summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile3
-rw-r--r--drivers/acpi/acpica/exutils.c2
-rw-r--r--drivers/acpi/acpica/rsutils.c2
-rw-r--r--drivers/acpi/apei/Kconfig2
-rw-r--r--drivers/acpi/apei/erst-dbg.c2
-rw-r--r--drivers/acpi/apei/erst.c2
-rw-r--r--drivers/acpi/battery.c1
-rw-r--r--drivers/acpi/bus.c4
-rw-r--r--drivers/acpi/ec_sys.c1
-rw-r--r--drivers/acpi/event.c1
-rw-r--r--drivers/acpi/pci_root.c97
-rw-r--r--drivers/acpi/processor_perflib.c4
-rw-r--r--drivers/acpi/sysfs.c20
-rw-r--r--drivers/acpi/video_detect.c4
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/ahci.c3
-rw-r--r--drivers/ata/ata_piix.c4
-rw-r--r--drivers/ata/libahci.c2
-rw-r--r--drivers/ata/libata-core.c117
-rw-r--r--drivers/ata/libata-eh.c43
-rw-r--r--drivers/ata/libata-pmp.c18
-rw-r--r--drivers/ata/libata-scsi.c117
-rw-r--r--drivers/ata/libata-sff.c80
-rw-r--r--drivers/ata/libata-transport.c774
-rw-r--r--drivers/ata/libata-transport.h18
-rw-r--r--drivers/ata/libata.h7
-rw-r--r--drivers/ata/pata_artop.c3
-rw-r--r--drivers/ata/pata_bf54x.c2
-rw-r--r--drivers/ata/pata_via.c2
-rw-r--r--drivers/ata/sata_fsl.c8
-rw-r--r--drivers/ata/sata_mv.c27
-rw-r--r--drivers/ata/sata_nv.c57
-rw-r--r--drivers/atm/firestream.c4
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/base/bus.c22
-rw-r--r--drivers/base/class.c19
-rw-r--r--drivers/base/core.c196
-rw-r--r--drivers/base/platform.c39
-rw-r--r--drivers/base/power/generic_ops.c4
-rw-r--r--drivers/base/power/main.c1
-rw-r--r--drivers/block/DAC960.c14
-rw-r--r--drivers/block/amiflop.c19
-rw-r--r--drivers/block/aoe/aoeblk.c9
-rw-r--r--drivers/block/aoe/aoechr.c10
-rw-r--r--drivers/block/aoe/aoecmd.c8
-rw-r--r--drivers/block/ataflop.c15
-rw-r--r--drivers/block/brd.c8
-rw-r--r--drivers/block/cciss.c867
-rw-r--r--drivers/block/cpqarray.c15
-rw-r--r--drivers/block/drbd/drbd_main.c11
-rw-r--r--drivers/block/floppy.c16
-rw-r--r--drivers/block/loop.c132
-rw-r--r--drivers/block/mg_disk.c3
-rw-r--r--drivers/block/nbd.c7
-rw-r--r--drivers/block/osdblk.c5
-rw-r--r--drivers/block/paride/pcd.c15
-rw-r--r--drivers/block/paride/pd.c15
-rw-r--r--drivers/block/paride/pf.c17
-rw-r--r--drivers/block/paride/pg.c8
-rw-r--r--drivers/block/paride/pt.c20
-rw-r--r--drivers/block/pktcdvd.c18
-rw-r--r--drivers/block/ps3disk.c2
-rw-r--r--drivers/block/swim.c15
-rw-r--r--drivers/block/swim3.c15
-rw-r--r--drivers/block/ub.c15
-rw-r--r--drivers/block/viodasd.c11
-rw-r--r--drivers/block/virtio_blk.c44
-rw-r--r--drivers/block/xd.c7
-rw-r--r--drivers/block/xen-blkfront.c58
-rw-r--r--drivers/block/xsysace.c11
-rw-r--r--drivers/block/z2ram.c15
-rw-r--r--drivers/bluetooth/btmrvl_debugfs.c10
-rw-r--r--drivers/bluetooth/hci_vhci.c1
-rw-r--r--drivers/cdrom/gdrom.c15
-rw-r--r--drivers/cdrom/viocd.c15
-rw-r--r--drivers/char/Kconfig15
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/amd64-agp.c4
-rw-r--r--drivers/char/agp/generic.c4
-rw-r--r--drivers/char/agp/intel-agp.c16
-rw-r--r--drivers/char/agp/intel-agp.h22
-rw-r--r--drivers/char/agp/intel-gtt.c66
-rw-r--r--drivers/char/apm-emulation.c12
-rw-r--r--drivers/char/applicom.c9
-rw-r--r--drivers/char/bfin-otp.c1
-rw-r--r--drivers/char/briq_panel.c1
-rw-r--r--drivers/char/bsr.c1
-rw-r--r--drivers/char/cs5535_gpio.c3
-rw-r--r--drivers/char/ds1302.c16
-rw-r--r--drivers/char/ds1620.c9
-rw-r--r--drivers/char/dsp56k.c28
-rw-r--r--drivers/char/dtlk.c9
-rw-r--r--drivers/char/generic_nvram.c7
-rw-r--r--drivers/char/genrtc.c14
-rw-r--r--drivers/char/hw_random/core.c1
-rw-r--r--drivers/char/hw_random/n2-drv.c2
-rw-r--r--drivers/char/i8k.c7
-rw-r--r--drivers/char/ip2/ip2main.c9
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c15
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c9
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/keyboard.c68
-rw-r--r--drivers/char/lp.c16
-rw-r--r--drivers/char/mbcs.c8
-rw-r--r--drivers/char/mem.c3
-rw-r--r--drivers/char/misc.c1
-rw-r--r--drivers/char/mmtimer.c8
-rw-r--r--drivers/char/mspec.c9
-rw-r--r--drivers/char/mwave/mwavedd.c47
-rw-r--r--drivers/char/mxser.c47
-rw-r--r--drivers/char/nvram.c11
-rw-r--r--drivers/char/nwbutton.c1
-rw-r--r--drivers/char/nwflash.c12
-rw-r--r--drivers/char/pc8736x_gpio.c1
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c12
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c8
-rw-r--r--drivers/char/ppdev.c8
-rw-r--r--drivers/char/pty.c4
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/rio/rio_linux.c8
-rw-r--r--drivers/char/scx200_gpio.c1
-rw-r--r--drivers/char/snsc.c10
-rw-r--r--drivers/char/stallion.c1
-rw-r--r--drivers/char/sx.c1
-rw-r--r--drivers/char/sysrq.c1
-rw-r--r--drivers/char/tb0219.c1
-rw-r--r--drivers/char/tlclk.c1
-rw-r--r--drivers/char/toshiba.c10
-rw-r--r--drivers/char/tty_io.c58
-rw-r--r--drivers/char/ttyprintk.c225
-rw-r--r--drivers/char/uv_mmtimer.c1
-rw-r--r--drivers/char/viotape.c12
-rw-r--r--drivers/char/virtio_console.c240
-rw-r--r--drivers/char/vt.c15
-rw-r--r--drivers/char/vt_ioctl.c16
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c7
-rw-r--r--drivers/clocksource/sh_cmt.c15
-rw-r--r--drivers/clocksource/sh_mtu2.c3
-rw-r--r--drivers/clocksource/sh_tmu.c3
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/cpuidle/governors/menu.c2
-rw-r--r--drivers/crypto/Kconfig9
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/omap-aes.c948
-rw-r--r--drivers/crypto/omap-sham.c6
-rw-r--r--drivers/dma/Kconfig8
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/amba-pl08x.c2025
-rw-r--r--drivers/dma/coh901318.c1
-rw-r--r--drivers/dma/shdma.c3
-rw-r--r--drivers/firewire/net.c13
-rw-r--r--drivers/firewire/nosy.c1
-rw-r--r--drivers/firewire/ohci.c1
-rw-r--r--drivers/gpio/stmpe-gpio.c7
-rw-r--r--drivers/gpio/sx150x.c26
-rw-r--r--drivers/gpio/wm8994-gpio.c1
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c24
-rw-r--r--drivers/gpu/drm/drm_drv.c3
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c5
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c1
-rw-r--r--drivers/gpu/drm/i810/i810_drv.c1
-rw-r--r--drivers/gpu/drm/i830/i830_dma.c1
-rw-r--r--drivers/gpu/drm/i830/i830_drv.c1
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c51
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c36
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c66
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h27
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c11
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c73
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h9
-rw-r--r--drivers/gpu/drm/i915/intel_display.c269
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c58
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h10
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c2
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c8
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c69
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c9
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c7
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c46
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c49
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c2
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c1
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c167
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c48
-rw-r--r--drivers/gpu/drm/radeon/r600.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon.h8
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c58
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c78
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c50
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h14
-rw-r--r--drivers/gpu/drm/radeon/rv770.c61
-rw-r--r--drivers/gpu/drm/savage/savage_drv.c1
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c1
-rw-r--r--drivers/gpu/drm/tdfx/tdfx_drv.c1
-rw-r--r--drivers/gpu/drm/via/via_drv.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c1
-rw-r--r--drivers/gpu/vga/vgaarb.c1
-rw-r--r--drivers/hid/Kconfig79
-rw-r--r--drivers/hid/Makefile3
-rw-r--r--drivers/hid/hid-apple.c7
-rw-r--r--drivers/hid/hid-cherry.c7
-rw-r--r--drivers/hid/hid-core.c26
-rw-r--r--drivers/hid/hid-cypress.c9
-rw-r--r--drivers/hid/hid-debug.c3
-rw-r--r--drivers/hid/hid-elecom.c7
-rw-r--r--drivers/hid/hid-ids.h18
-rw-r--r--drivers/hid/hid-input.c107
-rw-r--r--drivers/hid/hid-kye.c7
-rw-r--r--drivers/hid/hid-lg.c9
-rw-r--r--drivers/hid/hid-magicmouse.c250
-rw-r--r--drivers/hid/hid-microsoft.c7
-rw-r--r--drivers/hid/hid-monterey.c7
-rw-r--r--drivers/hid/hid-mosart.c1
-rw-r--r--drivers/hid/hid-ntrig.c69
-rw-r--r--drivers/hid/hid-ortek.c7
-rw-r--r--drivers/hid/hid-petalynx.c7
-rw-r--r--drivers/hid/hid-prodikeys.c7
-rw-r--r--drivers/hid/hid-roccat-pyra.c968
-rw-r--r--drivers/hid/hid-roccat-pyra.h186
-rw-r--r--drivers/hid/hid-roccat.c1
-rw-r--r--drivers/hid/hid-samsung.c20
-rw-r--r--drivers/hid/hid-sony.c35
-rw-r--r--drivers/hid/hid-sunplus.c7
-rw-r--r--drivers/hid/hid-topseed.c1
-rw-r--r--drivers/hid/hid-uclogic.c623
-rw-r--r--drivers/hid/hid-waltop.c891
-rw-r--r--drivers/hid/hid-zydacron.c7
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/usbhid/hid-core.c8
-rw-r--r--drivers/hid/usbhid/hid-quirks.c8
-rw-r--r--drivers/hid/usbhid/hiddev.c3
-rw-r--r--drivers/hid/usbhid/usbhid.h1
-rw-r--r--drivers/hwmon/asus_atk0110.c1
-rw-r--r--drivers/hwmon/f75375s.c6
-rw-r--r--drivers/hwmon/fschmd.c6
-rw-r--r--drivers/hwmon/hp_accel.c2
-rw-r--r--drivers/hwmon/k8temp.c51
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c4
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c4
-rw-r--r--drivers/hwmon/lm75.c51
-rw-r--r--drivers/hwmon/lm90.c76
-rw-r--r--drivers/hwmon/s3c-hwmon.c8
-rw-r--r--drivers/hwmon/w83793.c6
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c23
-rw-r--r--drivers/i2c/i2c-core.c36
-rw-r--r--drivers/i2c/i2c-dev.c13
-rw-r--r--drivers/ide/ide-cd.c14
-rw-r--r--drivers/ide/ide-disk.c16
-rw-r--r--drivers/ide/ide-disk_ioctl.c7
-rw-r--r--drivers/ide/ide-floppy_ioctl.c7
-rw-r--r--drivers/ide/ide-gd.c10
-rw-r--r--drivers/ide/ide-io.c13
-rw-r--r--drivers/ide/ide-tape.c20
-rw-r--r--drivers/idle/i7300_idle.c1
-rw-r--r--drivers/ieee1394/eth1394.c16
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h2
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c2
-rw-r--r--drivers/infiniband/hw/cxgb4/cq.c4
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c1
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c2
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c3
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c18
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c14
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h1
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c4
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c12
-rw-r--r--drivers/infiniband/hw/qib/qib_diag.c4
-rw-r--r--drivers/infiniband/hw/qib/qib_file_ops.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c1
-rw-r--r--drivers/input/evdev.c105
-rw-r--r--drivers/input/input.c208
-rw-r--r--drivers/input/joydev.c1
-rw-r--r--drivers/input/keyboard/Kconfig9
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/omap4-keypad.c287
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/ab8500-ponkey.c157
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c7
-rw-r--r--drivers/input/misc/twl4030-vibra.c4
-rw-r--r--drivers/input/misc/uinput.c1
-rw-r--r--drivers/input/mouse/bcm5974.c12
-rw-r--r--drivers/input/mousedev.c1
-rw-r--r--drivers/input/serio/i8042.c2
-rw-r--r--drivers/input/serio/serio.c1
-rw-r--r--drivers/input/serio/serio_raw.c1
-rw-r--r--drivers/input/serio/serport.c1
-rw-r--r--drivers/input/sparse-keymap.c81
-rw-r--r--drivers/input/tablet/Kconfig11
-rw-r--r--drivers/input/tablet/Makefile1
-rw-r--r--drivers/input/tablet/hanwang.c394
-rw-r--r--drivers/input/tablet/wacom.h1
-rw-r--r--drivers/input/tablet/wacom_sys.c68
-rw-r--r--drivers/input/tablet/wacom_wac.c217
-rw-r--r--drivers/input/tablet/wacom_wac.h15
-rw-r--r--drivers/input/touchscreen/Kconfig22
-rw-r--r--drivers/input/touchscreen/Makefile2
-rw-r--r--drivers/input/touchscreen/cy8ctmg110_ts.c4
-rw-r--r--drivers/input/touchscreen/intel-mid-touch.c687
-rw-r--r--drivers/input/touchscreen/lpc32xx_ts.c411
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c2
-rw-r--r--drivers/input/touchscreen/stmpe-ts.c11
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c3
-rw-r--r--drivers/input/touchscreen/tsc2007.c2
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c185
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c18
-rw-r--r--drivers/isdn/capi/capidrv.c17
-rw-r--r--drivers/isdn/capi/capifs.c10
-rw-r--r--drivers/isdn/divert/isdn_divert.c6
-rw-r--r--drivers/isdn/hisax/hfc_sx.c13
-rw-r--r--drivers/isdn/i4l/isdn_tty.c4
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c1
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c2
-rw-r--r--drivers/isdn/mISDN/timerdev.c1
-rw-r--r--drivers/lguest/lguest_user.c1
-rw-r--r--drivers/macintosh/adb.c10
-rw-r--r--drivers/macintosh/ans-lcd.c1
-rw-r--r--drivers/macintosh/smu.c6
-rw-r--r--drivers/macintosh/via-pmu-led.c4
-rw-r--r--drivers/macintosh/via-pmu.c12
-rw-r--r--drivers/md/.gitignore4
-rw-r--r--drivers/md/bitmap.c3
-rw-r--r--drivers/md/dm-crypt.c2
-rw-r--r--drivers/md/dm-io.c20
-rw-r--r--drivers/md/dm-ioctl.c1
-rw-r--r--drivers/md/dm-log.c2
-rw-r--r--drivers/md/dm-raid1.c8
-rw-r--r--drivers/md/dm-region-hash.c16
-rw-r--r--drivers/md/dm-snap-persistent.c2
-rw-r--r--drivers/md/dm-snap.c6
-rw-r--r--drivers/md/dm-stripe.c2
-rw-r--r--drivers/md/dm.c408
-rw-r--r--drivers/md/linear.c4
-rw-r--r--drivers/md/md.c161
-rw-r--r--drivers/md/md.h25
-rw-r--r--drivers/md/multipath.c4
-rw-r--r--drivers/md/raid0.c4
-rw-r--r--drivers/md/raid1.c176
-rw-r--r--drivers/md/raid1.h2
-rw-r--r--drivers/md/raid10.c7
-rw-r--r--drivers/md/raid5.c43
-rw-r--r--drivers/md/raid5.h1
-rw-r--r--drivers/media/IR/Kconfig12
-rw-r--r--drivers/media/IR/Makefile1
-rw-r--r--drivers/media/IR/imon.c6
-rw-r--r--drivers/media/IR/ir-core-priv.h6
-rw-r--r--drivers/media/IR/ir-keytable.c402
-rw-r--r--drivers/media/IR/ir-lirc-codec.c3
-rw-r--r--drivers/media/IR/ir-raw-event.c4
-rw-r--r--drivers/media/IR/ir-rc5-sz-decoder.c153
-rw-r--r--drivers/media/IR/ir-sysfs.c1
-rw-r--r--drivers/media/IR/keymaps/Makefile2
-rw-r--r--drivers/media/IR/keymaps/rc-lme2510.c68
-rw-r--r--drivers/media/IR/keymaps/rc-rc6-mce.c3
-rw-r--r--drivers/media/IR/keymaps/rc-streamzap.c82
-rw-r--r--drivers/media/IR/lirc_dev.c3
-rw-r--r--drivers/media/IR/mceusb.c4
-rw-r--r--drivers/media/IR/streamzap.c358
-rw-r--r--drivers/media/common/tuners/Kconfig7
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/tda18218.c334
-rw-r--r--drivers/media/common/tuners/tda18218.h45
-rw-r--r--drivers/media/common/tuners/tda18218_priv.h106
-rw-r--r--drivers/media/common/tuners/xc5000.c2
-rw-r--r--drivers/media/common/tuners/xc5000.h4
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c3
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig12
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c33
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c3
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c56
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c936
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.h187
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c4
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c1
-rw-r--r--drivers/media/dvb/frontends/Kconfig7
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/af9013.c14
-rw-r--r--drivers/media/dvb/frontends/af9013_priv.h5
-rw-r--r--drivers/media/dvb/frontends/cx24110.c2
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c8
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h5
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/ix2505v.c323
-rw-r--r--drivers/media/dvb/frontends/ix2505v.h64
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c2
-rw-r--r--drivers/media/dvb/frontends/mt352.c2
-rw-r--r--drivers/media/dvb/frontends/mt352.h2
-rw-r--r--drivers/media/dvb/frontends/si21xx.c2
-rw-r--r--drivers/media/dvb/frontends/stb6100.c2
-rw-r--r--drivers/media/dvb/frontends/stb6100.h4
-rw-r--r--drivers/media/dvb/frontends/stv0288.c4
-rw-r--r--drivers/media/dvb/frontends/stv0299.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.h2
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c2
-rw-r--r--drivers/media/dvb/frontends/zl10353.c2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c34
-rw-r--r--drivers/media/dvb/ttpci/av7110.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c1
-rw-r--r--drivers/media/video/cafe_ccic.c87
-rw-r--r--drivers/media/video/cx18/cx18-driver.h19
-rw-r--r--drivers/media/video/cx231xx/Makefile1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c3
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c3
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c18
-rw-r--r--drivers/media/video/cx88/cx88-cards.c6
-rw-r--r--drivers/media/video/cx88/cx88-core.c28
-rw-r--r--drivers/media/video/cx88/cx88-dsp.c11
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c118
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c4
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c6
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c43
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c2
-rw-r--r--drivers/media/video/cx88/cx88-video.c33
-rw-r--r--drivers/media/video/cx88/cx88.h52
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c36
-rw-r--r--drivers/media/video/davinci/vpif_capture.c3
-rw-r--r--drivers/media/video/davinci/vpif_display.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c3
-rw-r--r--drivers/media/video/gspca/Kconfig18
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/cpia1.c4
-rw-r--r--drivers/media/video/gspca/gspca.c1
-rw-r--r--drivers/media/video/gspca/konica.c653
-rw-r--r--drivers/media/video/gspca/mr97310a.c4
-rw-r--r--drivers/media/video/gspca/pac207.c4
-rw-r--r--drivers/media/video/gspca/stv0680.c4
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c3260
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h14
-rw-r--r--drivers/media/video/mt9m001.c26
-rw-r--r--drivers/media/video/mt9m111.c20
-rw-r--r--drivers/media/video/mt9t031.c24
-rw-r--r--drivers/media/video/mt9t112.c14
-rw-r--r--drivers/media/video/mt9v022.c26
-rw-r--r--drivers/media/video/ov7670.c76
-rw-r--r--drivers/media/video/ov772x.c18
-rw-r--r--drivers/media/video/ov9640.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c6
-rw-r--r--drivers/media/video/rj54n1cb0c.c26
-rw-r--r--drivers/media/video/s2255drv.c2
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c3
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c10
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c5
-rw-r--r--drivers/media/video/soc_camera.c2
-rw-r--r--drivers/media/video/tvp514x.c67
-rw-r--r--drivers/media/video/tvp7002.c126
-rw-r--r--drivers/media/video/tw9910.c20
-rw-r--r--drivers/media/video/usbvideo/Kconfig10
-rw-r--r--drivers/media/video/zoran/videocodec.h2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c2
-rw-r--r--drivers/media/video/zr364xx.c2
-rw-r--r--drivers/memstick/core/mspro_block.c11
-rw-r--r--drivers/message/fusion/mptbase.c4
-rw-r--r--drivers/message/fusion/mptctl.c15
-rw-r--r--drivers/message/i2o/i2o_block.c15
-rw-r--r--drivers/message/i2o/i2o_config.c23
-rw-r--r--drivers/mfd/88pm860x-core.c51
-rw-r--r--drivers/mfd/Kconfig41
-rw-r--r--drivers/mfd/Makefile4
-rw-r--r--drivers/mfd/ab3100-core.c144
-rw-r--r--drivers/mfd/ab8500-core.c306
-rw-r--r--drivers/mfd/ab8500-debugfs.c652
-rw-r--r--drivers/mfd/ab8500-i2c.c105
-rw-r--r--drivers/mfd/ab8500-spi.c2
-rw-r--r--drivers/mfd/da903x.c8
-rw-r--r--drivers/mfd/ezx-pcap.c10
-rw-r--r--drivers/mfd/htc-pasic3.c7
-rw-r--r--drivers/mfd/max8925-core.c13
-rw-r--r--drivers/mfd/max8998-irq.c255
-rw-r--r--drivers/mfd/max8998.c83
-rw-r--r--drivers/mfd/pcf50633-core.c7
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c19
-rw-r--r--drivers/mfd/tps6586x.c21
-rw-r--r--drivers/mfd/twl-core.c27
-rw-r--r--drivers/mfd/twl4030-codec.c8
-rw-r--r--drivers/mfd/twl4030-power.c30
-rw-r--r--drivers/mfd/wm831x-irq.c9
-rw-r--r--drivers/misc/Kconfig14
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/bh1780gli.c1
-rw-r--r--drivers/misc/hpilo.c1
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c4
-rw-r--r--drivers/misc/iwmc3200top/debugfs.c3
-rw-r--r--drivers/misc/lkdtm.c9
-rw-r--r--drivers/misc/pch_phub.c717
-rw-r--r--drivers/misc/phantom.c12
-rw-r--r--drivers/misc/sgi-gru/grufile.c1
-rw-r--r--drivers/mmc/card/block.c13
-rw-r--r--drivers/mmc/card/mmc_test.c183
-rw-r--r--drivers/mmc/card/queue.c11
-rw-r--r--drivers/mmc/core/debugfs.c1
-rw-r--r--drivers/mmc/core/host.c3
-rw-r--r--drivers/mmc/core/sdio.c5
-rw-r--r--drivers/mmc/host/Kconfig26
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/at91_mci.c12
-rw-r--r--drivers/mmc/host/atmel-mci.c5
-rw-r--r--drivers/mmc/host/au1xmmc.c4
-rw-r--r--drivers/mmc/host/bfin_sdh.c2
-rw-r--r--drivers/mmc/host/davinci_mmc.c8
-rw-r--r--drivers/mmc/host/imxmmc.c6
-rw-r--r--drivers/mmc/host/jz4740_mmc.c3
-rw-r--r--drivers/mmc/host/mmc_spi.c3
-rw-r--r--drivers/mmc/host/mmci.c30
-rw-r--r--drivers/mmc/host/mmci.h7
-rw-r--r--drivers/mmc/host/msm_sdcc.c3
-rw-r--r--drivers/mmc/host/mvsdio.c3
-rw-r--r--drivers/mmc/host/mxcmmc.c3
-rw-r--r--drivers/mmc/host/omap.c3
-rw-r--r--drivers/mmc/host/omap_hsmmc.c6
-rw-r--r--drivers/mmc/host/pxamci.c2
-rw-r--r--drivers/mmc/host/s3cmci.c5
-rw-r--r--drivers/mmc/host/sdhci-mv.c242
-rw-r--r--drivers/mmc/host/sdhci.c43
-rw-r--r--drivers/mmc/host/sdhci.h6
-rw-r--r--drivers/mmc/host/sh_mmcif.c15
-rw-r--r--drivers/mmc/host/tifm_sd.c3
-rw-r--r--drivers/mmc/host/tmio_mmc.c37
-rw-r--r--drivers/mmc/host/tmio_mmc.h13
-rw-r--r--drivers/mmc/host/ushc.c566
-rw-r--r--drivers/mmc/host/via-sdmmc.c3
-rw-r--r--drivers/mmc/host/wbsd.c3
-rw-r--r--drivers/mtd/mtd_blkdevs.c14
-rw-r--r--drivers/mtd/mtdchar.c15
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c9
-rw-r--r--drivers/mtd/nand/davinci_nand.c61
-rw-r--r--drivers/mtd/nand/mxc_nand.c47
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c6
-rw-r--r--drivers/mtd/onenand/samsung.c16
-rw-r--r--drivers/mtd/ubi/Kconfig.debug2
-rw-r--r--drivers/mtd/ubi/cdev.c13
-rw-r--r--drivers/mtd/ubi/scan.c2
-rw-r--r--drivers/mtd/ubi/wl.c3
-rw-r--r--drivers/net/3c503.c8
-rw-r--r--drivers/net/3c515.c2
-rw-r--r--drivers/net/3c59x.c17
-rw-r--r--drivers/net/8139cp.c2
-rw-r--r--drivers/net/Kconfig60
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/acenic.c2
-rw-r--r--drivers/net/amd8111e.c18
-rw-r--r--drivers/net/amd8111e.h1
-rw-r--r--drivers/net/arm/am79c961a.c35
-rw-r--r--drivers/net/arm/am79c961a.h1
-rw-r--r--drivers/net/arm/ep93xx_eth.c39
-rw-r--r--drivers/net/arm/ether1.c34
-rw-r--r--drivers/net/arm/ether1.h1
-rw-r--r--drivers/net/arm/ether3.c33
-rw-r--r--drivers/net/arm/ether3.h1
-rw-r--r--drivers/net/atl1c/atl1c.h1
-rw-r--r--drivers/net/atl1c/atl1c_hw.c2
-rw-r--r--drivers/net/atl1c/atl1c_main.c8
-rw-r--r--drivers/net/atl1e/atl1e_main.c4
-rw-r--r--drivers/net/atlx/atl1.c4
-rw-r--r--drivers/net/atlx/atl2.c10
-rw-r--r--drivers/net/atp.c2
-rw-r--r--drivers/net/au1000_eth.c313
-rw-r--r--drivers/net/au1000_eth.h42
-rw-r--r--drivers/net/b44.c11
-rw-r--r--drivers/net/bcm63xx_enet.c62
-rw-r--r--drivers/net/bcm63xx_enet.h1
-rw-r--r--drivers/net/benet/be.h15
-rw-r--r--drivers/net/benet/be_cmds.c8
-rw-r--r--drivers/net/benet/be_cmds.h2
-rw-r--r--drivers/net/benet/be_ethtool.c4
-rw-r--r--drivers/net/benet/be_hw.h7
-rw-r--r--drivers/net/benet/be_main.c109
-rw-r--r--drivers/net/bfin_mac.c10
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/bna/Makefile11
-rw-r--r--drivers/net/bna/bfa_cee.c291
-rw-r--r--drivers/net/bna/bfa_cee.h64
-rw-r--r--drivers/net/bna/bfa_defs.h243
-rw-r--r--drivers/net/bna/bfa_defs_cna.h223
-rw-r--r--drivers/net/bna/bfa_defs_mfg_comm.h244
-rw-r--r--drivers/net/bna/bfa_defs_status.h216
-rw-r--r--drivers/net/bna/bfa_ioc.c1738
-rw-r--r--drivers/net/bna/bfa_ioc.h301
-rw-r--r--drivers/net/bna/bfa_ioc_ct.c392
-rw-r--r--drivers/net/bna/bfa_sm.h88
-rw-r--r--drivers/net/bna/bfa_wc.h69
-rw-r--r--drivers/net/bna/bfi.h392
-rw-r--r--drivers/net/bna/bfi_cna.h199
-rw-r--r--drivers/net/bna/bfi_ctreg.h637
-rw-r--r--drivers/net/bna/bfi_ll.h438
-rw-r--r--drivers/net/bna/bna.h654
-rw-r--r--drivers/net/bna/bna_ctrl.c3624
-rw-r--r--drivers/net/bna/bna_hw.h1491
-rw-r--r--drivers/net/bna/bna_txrx.c4209
-rw-r--r--drivers/net/bna/bna_types.h1128
-rw-r--r--drivers/net/bna/bnad.c3267
-rw-r--r--drivers/net/bna/bnad.h333
-rw-r--r--drivers/net/bna/bnad_ethtool.c1277
-rw-r--r--drivers/net/bna/cna.h81
-rw-r--r--drivers/net/bna/cna_fwimg.c64
-rw-r--r--drivers/net/bnx2.c46
-rw-r--r--drivers/net/bnx2x/bnx2x.h15
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c42
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h12
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c233
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h130
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c8585
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h238
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c757
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h53
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c7
-rw-r--r--drivers/net/bonding/bond_3ad.c3
-rw-r--r--drivers/net/bonding/bond_alb.c3
-rw-r--r--drivers/net/bonding/bond_main.c56
-rw-r--r--drivers/net/caif/caif_spi.c6
-rw-r--r--drivers/net/can/mscan/mpc5xxx_can.c8
-rw-r--r--drivers/net/cassini.c2
-rw-r--r--drivers/net/chelsio/sge.c2
-rw-r--r--drivers/net/chelsio/subr.c2
-rw-r--r--drivers/net/cnic.c2
-rw-r--r--drivers/net/cpmac.c39
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c24
-rw-r--r--drivers/net/cxgb3/regs.h4
-rw-r--r--drivers/net/cxgb3/sge.c2
-rw-r--r--drivers/net/cxgb3/t3_hw.c7
-rw-r--r--drivers/net/cxgb4/cxgb4.h2
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c95
-rw-r--r--drivers/net/cxgb4/sge.c19
-rw-r--r--drivers/net/cxgb4/t4_hw.h1
-rw-r--r--drivers/net/cxgb4/t4fw_api.h5
-rw-r--r--drivers/net/cxgb4vf/sge.c3
-rw-r--r--drivers/net/davinci_cpdma.c837
-rw-r--r--drivers/net/davinci_cpdma.h105
-rw-r--r--drivers/net/davinci_emac.c1325
-rw-r--r--drivers/net/davinci_mdio.c386
-rw-r--r--drivers/net/declance.c2
-rw-r--r--drivers/net/depca.c2
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/dm9000.c2
-rw-r--r--drivers/net/e1000/e1000_main.c171
-rw-r--r--drivers/net/e1000e/netdev.c36
-rw-r--r--drivers/net/eepro.c8
-rw-r--r--drivers/net/ehea/ehea_main.c10
-rw-r--r--drivers/net/enic/enic.h2
-rw-r--r--drivers/net/enic/enic_main.c19
-rw-r--r--drivers/net/enic/vnic_dev.c25
-rw-r--r--drivers/net/enic/vnic_devcmd.h12
-rw-r--r--drivers/net/enic/vnic_enet.h2
-rw-r--r--drivers/net/enic/vnic_resource.h13
-rw-r--r--drivers/net/enic/vnic_rq.c6
-rw-r--r--drivers/net/enic/vnic_vic.c7
-rw-r--r--drivers/net/enic/vnic_wq.c6
-rw-r--r--drivers/net/epic100.c2
-rw-r--r--drivers/net/ethoc.c6
-rw-r--r--drivers/net/fealnx.c4
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/forcedeth.c6
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c3
-rw-r--r--drivers/net/gianfar.c19
-rw-r--r--drivers/net/greth.c6
-rw-r--r--drivers/net/hamachi.c2
-rw-r--r--drivers/net/hamradio/scc.c3
-rw-r--r--drivers/net/hp.c8
-rw-r--r--drivers/net/hydra.c13
-rw-r--r--drivers/net/ibmlana.c2
-rw-r--r--drivers/net/ibmveth.c953
-rw-r--r--drivers/net/ibmveth.h59
-rw-r--r--drivers/net/igb/igb.h2
-rw-r--r--drivers/net/igb/igb_main.c19
-rw-r--r--drivers/net/igbvf/netdev.c2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/ipg.c6
-rw-r--r--drivers/net/irda/irda-usb.c9
-rw-r--r--drivers/net/irda/mcs7780.c2
-rw-r--r--drivers/net/irda/via-ircc.c3
-rw-r--r--drivers/net/iseries_veth.c2
-rw-r--r--drivers/net/ixgb/ixgb_main.c6
-rw-r--r--drivers/net/ixgbe/ixgbe.h30
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c385
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c7
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1715
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h2
-rw-r--r--drivers/net/ixgbevf/ixgbevf.h1
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c30
-rw-r--r--drivers/net/ixgbevf/vf.h2
-rw-r--r--drivers/net/jme.c100
-rw-r--r--drivers/net/jme.h3
-rw-r--r--drivers/net/ks8851.c39
-rw-r--r--drivers/net/ll_temac_main.c3
-rw-r--r--drivers/net/ll_temac_mdio.c1
-rw-r--r--drivers/net/mac8390.c48
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/macvtap.c99
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/alloc.c17
-rw-r--r--drivers/net/mlx4/en_ethtool.c173
-rw-r--r--drivers/net/mlx4/en_main.c24
-rw-r--r--drivers/net/mlx4/en_netdev.c28
-rw-r--r--drivers/net/mlx4/en_port.c32
-rw-r--r--drivers/net/mlx4/en_port.h14
-rw-r--r--drivers/net/mlx4/en_rx.c104
-rw-r--r--drivers/net/mlx4/en_selftest.c179
-rw-r--r--drivers/net/mlx4/en_tx.c20
-rw-r--r--drivers/net/mlx4/eq.c44
-rw-r--r--drivers/net/mlx4/fw.c15
-rw-r--r--drivers/net/mlx4/fw.h6
-rw-r--r--drivers/net/mlx4/main.c6
-rw-r--r--drivers/net/mlx4/mlx4_en.h39
-rw-r--r--drivers/net/mlx4/profile.c2
-rw-r--r--drivers/net/myri10ge/myri10ge.c4
-rw-r--r--drivers/net/natsemi.c2
-rw-r--r--drivers/net/niu.c22
-rw-r--r--drivers/net/ns83820.c53
-rw-r--r--drivers/net/pasemi_mac.c2
-rw-r--r--drivers/net/pasemi_mac_ethtool.c16
-rw-r--r--drivers/net/pci-skeleton.c2
-rw-r--r--drivers/net/pcmcia/3c574_cs.c88
-rw-r--r--drivers/net/pcmcia/3c589_cs.c15
-rw-r--r--drivers/net/pcmcia/axnet_cs.c187
-rw-r--r--drivers/net/pcmcia/com20020_cs.c32
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c60
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c26
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c54
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c117
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c103
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c104
-rw-r--r--drivers/net/phy/mdio_bus.c4
-rw-r--r--drivers/net/plip.c1
-rw-r--r--drivers/net/ppp_generic.c12
-rw-r--r--drivers/net/pptp.c726
-rw-r--r--drivers/net/ps3_gelic_net.c8
-rw-r--r--drivers/net/pxa168_eth.c5
-rw-r--r--drivers/net/qla3xxx.c4
-rw-r--r--drivers/net/qlcnic/qlcnic.h107
-rw-r--r--drivers/net/qlcnic/qlcnic_ctx.c267
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c75
-rw-r--r--drivers/net/qlcnic/qlcnic_hdr.h23
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c77
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c271
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c1112
-rw-r--r--drivers/net/qlge/qlge_main.c34
-rw-r--r--drivers/net/r6040.c67
-rw-r--r--drivers/net/r8169.c18
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/s2io.c37
-rw-r--r--drivers/net/s2io.h9
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/sc92031.c11
-rw-r--r--drivers/net/sfc/efx.c302
-rw-r--r--drivers/net/sfc/efx.h22
-rw-r--r--drivers/net/sfc/ethtool.c53
-rw-r--r--drivers/net/sfc/falcon.c14
-rw-r--r--drivers/net/sfc/net_driver.h103
-rw-r--r--drivers/net/sfc/nic.c182
-rw-r--r--drivers/net/sfc/rx.c73
-rw-r--r--drivers/net/sfc/selftest.c7
-rw-r--r--drivers/net/sfc/siena.c2
-rw-r--r--drivers/net/sfc/tx.c78
-rw-r--r--drivers/net/sh_eth.c4
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/skfp/hwt.c2
-rw-r--r--drivers/net/skfp/skfddi.c86
-rw-r--r--drivers/net/skge.c5
-rw-r--r--drivers/net/slip.c91
-rw-r--r--drivers/net/slip.h9
-rw-r--r--drivers/net/smsc911x.c2
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/starfire.c10
-rw-r--r--drivers/net/stmmac/Kconfig5
-rw-r--r--drivers/net/stmmac/common.h50
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c20
-rw-r--r--drivers/net/stmmac/dwmac1000_dma.c8
-rw-r--r--drivers/net/stmmac/dwmac100_core.c22
-rw-r--r--drivers/net/stmmac/dwmac100_dma.c8
-rw-r--r--drivers/net/stmmac/dwmac_dma.h16
-rw-r--r--drivers/net/stmmac/dwmac_lib.c22
-rw-r--r--drivers/net/stmmac/enh_desc.c2
-rw-r--r--drivers/net/stmmac/norm_desc.c2
-rw-r--r--drivers/net/stmmac/stmmac.h4
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c21
-rw-r--r--drivers/net/stmmac/stmmac_main.c142
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c21
-rw-r--r--drivers/net/sunbmac.c2
-rw-r--r--drivers/net/sundance.c50
-rw-r--r--drivers/net/sungem.c211
-rw-r--r--drivers/net/sungem_phy.c3
-rw-r--r--drivers/net/sunhme.c8
-rw-r--r--drivers/net/sunlance.c2
-rw-r--r--drivers/net/sunvnet.c50
-rw-r--r--drivers/net/tehuti.c34
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/net/tlan.c8
-rw-r--r--drivers/net/tokenring/tms380tr.c6
-rw-r--r--drivers/net/tulip/de4x5.c18
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/interrupt.c77
-rw-r--r--drivers/net/tulip/pnic2.c2
-rw-r--r--drivers/net/tulip/tulip.h3
-rw-r--r--drivers/net/tulip/tulip_core.c10
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c2
-rw-r--r--drivers/net/tulip/xircom_cb.c15
-rw-r--r--drivers/net/typhoon.c48
-rw-r--r--drivers/net/usb/Kconfig8
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cx82310_eth.c346
-rw-r--r--drivers/net/usb/hso.c9
-rw-r--r--drivers/net/usb/ipheth.c7
-rw-r--r--drivers/net/usb/kaweth.c9
-rw-r--r--drivers/net/vbus-enet.c1560
-rw-r--r--drivers/net/via-velocity.c4
-rw-r--r--drivers/net/virtio_net.c14
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c4
-rw-r--r--drivers/net/vxge/vxge-main.c34
-rw-r--r--drivers/net/vxge/vxge-main.h1
-rw-r--r--drivers/net/wan/c101.c2
-rw-r--r--drivers/net/wan/cycx_drv.c14
-rw-r--r--drivers/net/wan/cycx_main.c6
-rw-r--r--drivers/net/wan/lapbether.c2
-rw-r--r--drivers/net/wan/lmc/lmc_main.c2
-rw-r--r--drivers/net/wan/n2.c2
-rw-r--r--drivers/net/wan/pc300_drv.c2
-rw-r--r--drivers/net/wan/pci200syn.c2
-rw-r--r--drivers/net/wan/z85230.c4
-rw-r--r--drivers/net/wd.c8
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c2
-rw-r--r--drivers/net/wireless/airo.c37
-rw-r--r--drivers/net/wireless/at76c50x-usb.c7
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile1
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c31
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h7
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c8
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c98
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c12
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c36
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c21
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c30
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h67
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c109
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c78
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c29
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h42
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c134
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h48
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c31
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c567
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c63
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c74
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c18
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig41
-rw-r--r--drivers/net/wireless/ath/carl9170/Makefile4
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h626
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c188
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h158
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c908
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.h134
-rw-r--r--drivers/net/wireless/ath/carl9170/eeprom.h216
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c395
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h268
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h237
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h736
-rw-r--r--drivers/net/wireless/ath/carl9170/led.c190
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c604
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c1855
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c1805
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h567
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c909
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c1373
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c1137
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h412
-rw-r--r--drivers/net/wireless/ath/debug.h2
-rw-r--r--drivers/net/wireless/ath/regd.h1
-rw-r--r--drivers/net/wireless/b43/debugfs.c1
-rw-r--r--drivers/net/wireless/b43/main.c30
-rw-r--r--drivers/net/wireless/b43/phy_n.c64
-rw-r--r--drivers/net/wireless/b43legacy/debugfs.c1
-rw-r--r--drivers/net/wireless/b43legacy/main.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c10
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c12
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c163
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c147
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c561
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c335
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c704
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.h129
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c153
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c87
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c724
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h518
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c945
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h96
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c159
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h194
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c638
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c442
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c224
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c339
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c4
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c7
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c1
-rw-r--r--drivers/net/wireless/libertas/cfg.c62
-rw-r--r--drivers/net/wireless/libertas/debugfs.c2
-rw-r--r--drivers/net/wireless/libertas/decl.h13
-rw-r--r--drivers/net/wireless/libertas/if_cs.c130
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c163
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h4
-rw-r--r--drivers/net/wireless/libertas/if_spi.c150
-rw-r--r--drivers/net/wireless/libertas/if_spi.h5
-rw-r--r--drivers/net/wireless/libertas/if_usb.c60
-rw-r--r--drivers/net/wireless/libertas/if_usb.h1
-rw-r--r--drivers/net/wireless/libertas/main.c105
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c57
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c20
-rw-r--r--drivers/net/wireless/orinoco/hw.c9
-rw-r--r--drivers/net/wireless/orinoco/wext.c11
-rw-r--r--drivers/net/wireless/p54/Kconfig18
-rw-r--r--drivers/net/wireless/p54/eeprom.c21
-rw-r--r--drivers/net/wireless/p54/fwio.c6
-rw-r--r--drivers/net/wireless/p54/main.c9
-rw-r--r--drivers/net/wireless/p54/p54spi.c9
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h2
-rw-r--r--drivers/net/wireless/p54/p54usb.c2
-rw-r--r--drivers/net/wireless/p54/txrx.c27
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/ray_cs.c46
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c147
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c154
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c71
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h50
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c457
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c259
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c159
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h34
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c21
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c71
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c82
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h56
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c298
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c118
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c88
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c143
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c9
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.h10
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_event.c33
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_event.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c55
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_reg.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.c26
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c39
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c4
-rw-r--r--drivers/net/wireless/wl3501_cs.c11
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c5
-rw-r--r--drivers/net/xen-netfront.c8
-rw-r--r--drivers/net/xilinx_emaclite.c15
-rw-r--r--drivers/net/yellowfin.c2
-rw-r--r--drivers/oprofile/buffer_sync.c27
-rw-r--r--drivers/oprofile/cpu_buffer.c2
-rw-r--r--drivers/oprofile/oprof.c11
-rw-r--r--drivers/oprofile/oprofile_files.c8
-rw-r--r--drivers/oprofile/oprofilefs.c3
-rw-r--r--drivers/parport/parport_pc.c2
-rw-r--r--drivers/pci/dmar.c6
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c6
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c13
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c4
-rw-r--r--drivers/pci/hotplug/pciehp.h16
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c4
-rw-r--r--drivers/pci/hotplug/pciehp_core.c4
-rw-r--r--drivers/pci/iov.c2
-rw-r--r--drivers/pci/pci.c2
-rw-r--r--drivers/pci/pci.h7
-rw-r--r--drivers/pci/pcie/Makefile3
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c1
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c36
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c16
-rw-r--r--drivers/pci/pcie/pme.c (renamed from drivers/pci/pcie/pme/pcie_pme.c)66
-rw-r--r--drivers/pci/pcie/pme/Makefile8
-rw-r--r--drivers/pci/pcie/pme/pcie_pme.h28
-rw-r--r--drivers/pci/pcie/pme/pcie_pme_acpi.c54
-rw-r--r--drivers/pci/pcie/portdrv.h22
-rw-r--r--drivers/pci/pcie/portdrv_acpi.c77
-rw-r--r--drivers/pci/pcie/portdrv_core.c53
-rw-r--r--drivers/pci/pcie/portdrv_pci.c38
-rw-r--r--drivers/pci/slot.c2
-rw-r--r--drivers/platform/x86/Kconfig5
-rw-r--r--drivers/platform/x86/dell-wmi.c256
-rw-r--r--drivers/platform/x86/hp-wmi.c172
-rw-r--r--drivers/platform/x86/panasonic-laptop.c172
-rw-r--r--drivers/platform/x86/sony-laptop.c1
-rw-r--r--drivers/platform/x86/topstar-laptop.c161
-rw-r--r--drivers/platform/x86/toshiba_acpi.c191
-rw-r--r--drivers/power/Kconfig14
-rw-r--r--drivers/power/Makefile2
-rw-r--r--drivers/power/bq20z75.c385
-rw-r--r--drivers/power/isp1704_charger.c369
-rw-r--r--drivers/power/wm831x_power.c1
-rw-r--r--drivers/regulator/88pm8607.c4
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/ab3100.c5
-rw-r--r--drivers/regulator/ab8500.c95
-rw-r--r--drivers/regulator/ad5398.c13
-rw-r--r--drivers/regulator/isl6271a-regulator.c4
-rw-r--r--drivers/regulator/max1586.c12
-rw-r--r--drivers/regulator/max8952.c360
-rw-r--r--drivers/regulator/max8998.c25
-rw-r--r--drivers/regulator/tps6507x-regulator.c6
-rw-r--r--drivers/regulator/tps6586x-regulator.c4
-rw-r--r--drivers/regulator/wm831x-ldo.c7
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ab8500.c103
-rw-r--r--drivers/rtc/rtc-bfin.c15
-rw-r--r--drivers/rtc/rtc-ds3232.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c16
-rw-r--r--drivers/rtc/rtc-max8998.c300
-rw-r--r--drivers/rtc/rtc-nuc900.c2
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/s390/block/dasd.c1
-rw-r--r--drivers/s390/block/dasd_3990_erp.c5
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--drivers/s390/char/monreader.c1
-rw-r--r--drivers/s390/char/monwriter.c1
-rw-r--r--drivers/s390/char/tape_3590.c6
-rw-r--r--drivers/s390/char/tape_block.c16
-rw-r--r--drivers/s390/char/tape_char.c1
-rw-r--r--drivers/s390/char/tape_core.c16
-rw-r--r--drivers/s390/char/vmcp.c1
-rw-r--r--drivers/s390/char/vmlogrdr.c1
-rw-r--r--drivers/s390/char/vmwatchdog.c1
-rw-r--r--drivers/s390/char/zcore.c2
-rw-r--r--drivers/s390/cio/blacklist.c10
-rw-r--r--drivers/s390/cio/chsc_sch.c1
-rw-r--r--drivers/s390/cio/css.c1
-rw-r--r--drivers/s390/cio/qdio.h29
-rw-r--r--drivers/s390/cio/qdio_debug.c33
-rw-r--r--drivers/s390/cio/qdio_main.c138
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c66
-rw-r--r--drivers/s390/crypto/zcrypt_api.c3
-rw-r--r--drivers/s390/kvm/kvm_virtio.c66
-rw-r--r--drivers/s390/net/Kconfig2
-rw-r--r--drivers/s390/net/qeth_core.h17
-rw-r--r--drivers/s390/net/qeth_core_main.c26
-rw-r--r--drivers/s390/net/qeth_l2_main.c173
-rw-r--r--drivers/s390/net/qeth_l3_main.c189
-rw-r--r--drivers/s390/scsi/zfcp_aux.c3
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c3
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c6
-rw-r--r--drivers/sbus/char/display7seg.c1
-rw-r--r--drivers/sbus/char/envctrl.c1
-rw-r--r--drivers/sbus/char/jsflash.c24
-rw-r--r--drivers/scsi/3w-9xxx.c10
-rw-r--r--drivers/scsi/3w-sas.c10
-rw-r--r--drivers/scsi/3w-xxxx.c12
-rw-r--r--drivers/scsi/Kconfig5
-rw-r--r--drivers/scsi/Makefile3
-rw-r--r--drivers/scsi/aacraid/linit.c16
-rw-r--r--drivers/scsi/aic7xxx_old.c21
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c4
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c5
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c2
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c63
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c62
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c15
-rw-r--r--drivers/scsi/ch.c9
-rw-r--r--drivers/scsi/constants.c6
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h161
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c773
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h312
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c132
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c1018
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c1944
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h243
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c495
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.h59
-rw-r--r--drivers/scsi/cxgbi/Kconfig2
-rw-r--r--drivers/scsi/cxgbi/Makefile2
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/Kbuild (renamed from drivers/scsi/cxgb3i/Kbuild)1
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/Kconfig (renamed from drivers/scsi/cxgb3i/Kconfig)4
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/cxgb3i.c1432
-rw-r--r--drivers/scsi/cxgbi/cxgb3i/cxgb3i.h51
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/Kbuild3
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/Kconfig7
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/cxgb4i.c1600
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/cxgb4i.h38
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c2610
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.h753
-rw-r--r--drivers/scsi/dpt_i2o.c19
-rw-r--r--drivers/scsi/fnic/fnic_main.c14
-rw-r--r--drivers/scsi/gdth.c12
-rw-r--r--drivers/scsi/hosts.c2
-rw-r--r--drivers/scsi/hpsa.c6
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c10
-rw-r--r--drivers/scsi/ipr.c106
-rw-r--r--drivers/scsi/ipr.h8
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c10
-rw-r--r--drivers/scsi/megaraid.c9
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c9
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c3
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c12
-rw-r--r--drivers/scsi/osd/osd_initiator.c2
-rw-r--r--drivers/scsi/osd/osd_uld.c1
-rw-r--r--drivers/scsi/osst.c15
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c6
-rw-r--r--drivers/scsi/pmcraid.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c62
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h28
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h15
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c148
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c15
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c73
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c68
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c428
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c187
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/scsi_debug.c100
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsi_scan.c2
-rw-r--r--drivers/scsi/scsi_tgt_if.c3
-rw-r--r--drivers/scsi/scsi_transport_fc.c49
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c2
-rw-r--r--drivers/scsi/sd.c30
-rw-r--r--drivers/scsi/sd.h1
-rw-r--r--drivers/scsi/sg.c12
-rw-r--r--drivers/scsi/sr.c14
-rw-r--r--drivers/scsi/st.c12
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c10
-rw-r--r--drivers/serial/68328serial.h5
-rw-r--r--drivers/serial/Kconfig7
-rw-r--r--drivers/serial/amba-pl010.c9
-rw-r--r--drivers/serial/bfin_sport_uart.c2
-rw-r--r--drivers/serial/kgdboc.c13
-rw-r--r--drivers/serial/mfd.c25
-rw-r--r--drivers/serial/mpc52xx_uart.c1
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/serial_core.c14
-rw-r--r--drivers/serial/serial_cs.c8
-rw-r--r--drivers/serial/sh-sci.h17
-rw-r--r--drivers/serial/uartlite.c26
-rw-r--r--drivers/sh/clk.c9
-rw-r--r--drivers/spi/amba-pl022.c16
-rw-r--r--drivers/spi/dw_spi.c25
-rw-r--r--drivers/spi/spi.c9
-rw-r--r--drivers/spi/spi_s3c64xx.c37
-rw-r--r--drivers/spi/spidev.c1
-rw-r--r--drivers/staging/Kconfig18
-rw-r--r--drivers/staging/Makefile9
-rw-r--r--drivers/staging/adis16255/adis16255.c4
-rw-r--r--drivers/staging/ath6kl/Kconfig163
-rw-r--r--drivers/staging/ath6kl/Makefile159
-rw-r--r--drivers/staging/ath6kl/TODO8
-rw-r--r--drivers/staging/ath6kl/bmi/include/bmi_internal.h55
-rw-r--r--drivers/staging/ath6kl/bmi/src/bmi.c1010
-rw-r--r--drivers/staging/ath6kl/hif/common/hif_sdio_common.h87
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h134
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c1298
-rw-r--r--drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c393
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.c1471
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k.h398
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c784
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c756
-rw-r--r--drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c1280
-rw-r--r--drivers/staging/ath6kl/htc2/htc.c579
-rw-r--r--drivers/staging/ath6kl/htc2/htc_debug.h38
-rw-r--r--drivers/staging/ath6kl/htc2/htc_internal.h220
-rw-r--r--drivers/staging/ath6kl/htc2/htc_recv.c1578
-rw-r--r--drivers/staging/ath6kl/htc2/htc_send.c1023
-rw-r--r--drivers/staging/ath6kl/htc2/htc_services.c450
-rw-r--r--drivers/staging/ath6kl/include/a_config.h53
-rw-r--r--drivers/staging/ath6kl/include/a_debug.h224
-rw-r--r--drivers/staging/ath6kl/include/a_drv.h54
-rw-r--r--drivers/staging/ath6kl/include/a_drv_api.h232
-rw-r--r--drivers/staging/ath6kl/include/a_osapi.h61
-rw-r--r--drivers/staging/ath6kl/include/a_types.h58
-rw-r--r--drivers/staging/ath6kl/include/aggr_recv_api.h140
-rw-r--r--drivers/staging/ath6kl/include/ar3kconfig.h65
-rw-r--r--drivers/staging/ath6kl/include/ar6000_api.h54
-rw-r--r--drivers/staging/ath6kl/include/ar6000_diag.h48
-rw-r--r--drivers/staging/ath6kl/include/ar6kap_common.h44
-rw-r--r--drivers/staging/ath6kl/include/athbtfilter.h135
-rw-r--r--drivers/staging/ath6kl/include/athendpack.h52
-rw-r--r--drivers/staging/ath6kl/include/athstartpack.h55
-rw-r--r--drivers/staging/ath6kl/include/bmi.h135
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h60
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h52
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/addrs.h90
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h64
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h1932
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h13
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h977
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h386
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h481
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h1163
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h186
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h327
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h76
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h3291
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h3674
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h37
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h40
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h48
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h7076
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h108
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h1253
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h1094
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h605
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h3065
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h37
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h560
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h522
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h638
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h564
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h975
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h2065
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h209
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h260
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h37
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h322
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h167
-rw-r--r--drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h195
-rw-r--r--drivers/staging/ath6kl/include/common/a_hci.h682
-rw-r--r--drivers/staging/ath6kl/include/common/athdefs.h84
-rw-r--r--drivers/staging/ath6kl/include/common/bmi_msg.h241
-rw-r--r--drivers/staging/ath6kl/include/common/btcoexGpio.h86
-rw-r--r--drivers/staging/ath6kl/include/common/cnxmgmt.h36
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog.h134
-rw-r--r--drivers/staging/ath6kl/include/common/dbglog_id.h558
-rw-r--r--drivers/staging/ath6kl/include/common/discovery.h75
-rw-r--r--drivers/staging/ath6kl/include/common/dset_internal.h63
-rw-r--r--drivers/staging/ath6kl/include/common/dsetid.h134
-rw-r--r--drivers/staging/ath6kl/include/common/epping_test.h120
-rw-r--r--drivers/staging/ath6kl/include/common/gmboxif.h78
-rw-r--r--drivers/staging/ath6kl/include/common/gpio.h45
-rw-r--r--drivers/staging/ath6kl/include/common/htc.h236
-rw-r--r--drivers/staging/ath6kl/include/common/htc_services.h52
-rw-r--r--drivers/staging/ath6kl/include/common/ini_dset.h82
-rw-r--r--drivers/staging/ath6kl/include/common/pkt_log.h45
-rw-r--r--drivers/staging/ath6kl/include/common/regDb.h29
-rw-r--r--drivers/staging/ath6kl/include/common/regdump.h59
-rw-r--r--drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h237
-rw-r--r--drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h504
-rw-r--r--drivers/staging/ath6kl/include/common/roaming.h41
-rw-r--r--drivers/staging/ath6kl/include/common/targaddrs.h245
-rw-r--r--drivers/staging/ath6kl/include/common/testcmd.h185
-rw-r--r--drivers/staging/ath6kl/include/common/tlpm.h38
-rw-r--r--drivers/staging/ath6kl/include/common/wlan_defs.h79
-rw-r--r--drivers/staging/ath6kl/include/common/wlan_dset.h33
-rw-r--r--drivers/staging/ath6kl/include/common/wmi.h3119
-rw-r--r--drivers/staging/ath6kl/include/common/wmi_thin.h347
-rw-r--r--drivers/staging/ath6kl/include/common/wmix.h279
-rw-r--r--drivers/staging/ath6kl/include/common_drv.h108
-rw-r--r--drivers/staging/ath6kl/include/dbglog_api.h52
-rw-r--r--drivers/staging/ath6kl/include/dl_list.h153
-rw-r--r--drivers/staging/ath6kl/include/dset_api.h65
-rw-r--r--drivers/staging/ath6kl/include/gpio_api.h59
-rw-r--r--drivers/staging/ath6kl/include/hci_transport_api.h259
-rw-r--r--drivers/staging/ath6kl/include/hif.h458
-rw-r--r--drivers/staging/ath6kl/include/host_version.h52
-rw-r--r--drivers/staging/ath6kl/include/htc_api.h575
-rw-r--r--drivers/staging/ath6kl/include/htc_packet.h227
-rw-r--r--drivers/staging/ath6kl/include/target_reg_table.h244
-rw-r--r--drivers/staging/ath6kl/include/wlan_api.h128
-rw-r--r--drivers/staging/ath6kl/include/wmi_api.h441
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kconfig.c566
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c572
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h79
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c969
-rw-r--r--drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h127
-rw-r--r--drivers/staging/ath6kl/miscdrv/common_drv.c1027
-rw-r--r--drivers/staging/ath6kl/miscdrv/credit_dist.c418
-rw-r--r--drivers/staging/ath6kl/miscdrv/miscdrv.h42
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_android.c413
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_drv.c6453
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_pm.c731
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6000_raw_if.c455
-rw-r--r--drivers/staging/ath6kl/os/linux/ar6k_pal.c481
-rw-r--r--drivers/staging/ath6kl/os/linux/cfg80211.c1478
-rw-r--r--drivers/staging/ath6kl/os/linux/eeprom.c574
-rw-r--r--drivers/staging/ath6kl/os/linux/export_hci_transport.c125
-rw-r--r--drivers/staging/ath6kl/os/linux/hci_bridge.c1144
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6000_drv.h770
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6k_pal.h36
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h197
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athdrv_linux.h1219
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athendpack_linux.h0
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h0
-rw-r--r--drivers/staging/ath6kl/os/linux/include/athtypes_linux.h53
-rw-r--r--drivers/staging/ath6kl/os/linux/include/cfg80211.h50
-rw-r--r--drivers/staging/ath6kl/os/linux/include/config_linux.h60
-rw-r--r--drivers/staging/ath6kl/os/linux/include/debug_linux.h50
-rw-r--r--drivers/staging/ath6kl/os/linux/include/export_hci_transport.h76
-rw-r--r--drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h179
-rw-r--r--drivers/staging/ath6kl/os/linux/include/osapi_linux.h387
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wlan_config.h111
-rw-r--r--drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h293
-rw-r--r--drivers/staging/ath6kl/os/linux/ioctl.c4733
-rw-r--r--drivers/staging/ath6kl/os/linux/netbuf.c236
-rw-r--r--drivers/staging/ath6kl/os/linux/wireless_ext.c2725
-rw-r--r--drivers/staging/ath6kl/reorder/aggr_rx_internal.h116
-rw-r--r--drivers/staging/ath6kl/reorder/rcv_aggr.c666
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211.h401
-rw-r--r--drivers/staging/ath6kl/wlan/include/ieee80211_node.h93
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_node.c636
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c200
-rw-r--r--drivers/staging/ath6kl/wlan/src/wlan_utils.c61
-rw-r--r--drivers/staging/ath6kl/wmi/wmi.c6672
-rw-r--r--drivers/staging/ath6kl/wmi/wmi_host.h102
-rw-r--r--drivers/staging/batman-adv/CHANGELOG63
-rw-r--r--drivers/staging/batman-adv/Makefile2
-rw-r--r--drivers/staging/batman-adv/README45
-rw-r--r--drivers/staging/batman-adv/TODO8
-rw-r--r--drivers/staging/batman-adv/aggregation.c57
-rw-r--r--drivers/staging/batman-adv/bat_debugfs.c1
-rw-r--r--drivers/staging/batman-adv/bat_sysfs.c106
-rw-r--r--drivers/staging/batman-adv/bitarray.c22
-rw-r--r--drivers/staging/batman-adv/bitarray.h7
-rw-r--r--drivers/staging/batman-adv/hard-interface.c237
-rw-r--r--drivers/staging/batman-adv/hard-interface.h6
-rw-r--r--drivers/staging/batman-adv/hash.c6
-rw-r--r--drivers/staging/batman-adv/hash.h4
-rw-r--r--drivers/staging/batman-adv/icmp_socket.c71
-rw-r--r--drivers/staging/batman-adv/main.c141
-rw-r--r--drivers/staging/batman-adv/main.h28
-rw-r--r--drivers/staging/batman-adv/originator.c166
-rw-r--r--drivers/staging/batman-adv/originator.h8
-rw-r--r--drivers/staging/batman-adv/packet.h26
-rw-r--r--drivers/staging/batman-adv/routing.c444
-rw-r--r--drivers/staging/batman-adv/routing.h16
-rw-r--r--drivers/staging/batman-adv/send.c174
-rw-r--r--drivers/staging/batman-adv/send.h7
-rw-r--r--drivers/staging/batman-adv/soft-interface.c241
-rw-r--r--drivers/staging/batman-adv/soft-interface.h13
-rw-r--r--drivers/staging/batman-adv/translation-table.c266
-rw-r--r--drivers/staging/batman-adv/translation-table.h30
-rw-r--r--drivers/staging/batman-adv/types.h95
-rw-r--r--drivers/staging/batman-adv/unicast.c269
-rw-r--r--drivers/staging/batman-adv/unicast.h39
-rw-r--r--drivers/staging/batman-adv/vis.c500
-rw-r--r--drivers/staging/batman-adv/vis.h27
-rw-r--r--drivers/staging/bcm/Adapter.h714
-rw-r--r--drivers/staging/bcm/Arp.c94
-rw-r--r--drivers/staging/bcm/Bcmchar.c2420
-rw-r--r--drivers/staging/bcm/Bcmnet.c266
-rw-r--r--drivers/staging/bcm/CmHost.c2443
-rw-r--r--drivers/staging/bcm/CmHost.h166
-rw-r--r--drivers/staging/bcm/DDRInit.c1302
-rw-r--r--drivers/staging/bcm/DDRInit.h9
-rw-r--r--drivers/staging/bcm/Debug.c40
-rw-r--r--drivers/staging/bcm/Debug.h297
-rw-r--r--drivers/staging/bcm/HandleControlPacket.c247
-rw-r--r--drivers/staging/bcm/HostMIBSInterface.h230
-rw-r--r--drivers/staging/bcm/HostMibs.h7
-rw-r--r--drivers/staging/bcm/IPv6Protocol.c400
-rw-r--r--drivers/staging/bcm/IPv6ProtocolHdr.h119
-rw-r--r--drivers/staging/bcm/InterfaceAdapter.h97
-rw-r--r--drivers/staging/bcm/InterfaceDld.c509
-rw-r--r--drivers/staging/bcm/InterfaceIdleMode.c318
-rw-r--r--drivers/staging/bcm/InterfaceIdleMode.h16
-rw-r--r--drivers/staging/bcm/InterfaceInit.c868
-rw-r--r--drivers/staging/bcm/InterfaceInit.h51
-rw-r--r--drivers/staging/bcm/InterfaceIsr.c203
-rw-r--r--drivers/staging/bcm/InterfaceIsr.h15
-rw-r--r--drivers/staging/bcm/InterfaceMacros.h18
-rw-r--r--drivers/staging/bcm/InterfaceMisc.c290
-rw-r--r--drivers/staging/bcm/InterfaceMisc.h45
-rw-r--r--drivers/staging/bcm/InterfaceRx.c256
-rw-r--r--drivers/staging/bcm/InterfaceRx.h7
-rw-r--r--drivers/staging/bcm/InterfaceTx.c259
-rw-r--r--drivers/staging/bcm/InterfaceTx.h13
-rw-r--r--drivers/staging/bcm/Interfacemain.h10
-rw-r--r--drivers/staging/bcm/Ioctl.h360
-rw-r--r--drivers/staging/bcm/Kconfig7
-rw-r--r--drivers/staging/bcm/LeakyBucket.c399
-rw-r--r--drivers/staging/bcm/Macros.h399
-rw-r--r--drivers/staging/bcm/Makefile12
-rw-r--r--drivers/staging/bcm/Misc.c2239
-rw-r--r--drivers/staging/bcm/Osal_Misc.c27
-rw-r--r--drivers/staging/bcm/PHSDefines.h125
-rw-r--r--drivers/staging/bcm/PHSModule.c1641
-rw-r--r--drivers/staging/bcm/PHSModule.h95
-rw-r--r--drivers/staging/bcm/Protocol.h151
-rw-r--r--drivers/staging/bcm/Prototypes.h323
-rw-r--r--drivers/staging/bcm/Qos.c893
-rw-r--r--drivers/staging/bcm/Queue.h31
-rw-r--r--drivers/staging/bcm/TODO15
-rw-r--r--drivers/staging/bcm/Transmit.c553
-rw-r--r--drivers/staging/bcm/Typedefs.h47
-rw-r--r--drivers/staging/bcm/Version.h35
-rw-r--r--drivers/staging/bcm/cntrl_SignalingInterface.h677
-rw-r--r--drivers/staging/bcm/headers.h109
-rw-r--r--drivers/staging/bcm/hostmibs.c164
-rw-r--r--drivers/staging/bcm/led_control.c1006
-rw-r--r--drivers/staging/bcm/led_control.h106
-rw-r--r--drivers/staging/bcm/nvm.c5614
-rw-r--r--drivers/staging/bcm/nvm.h489
-rw-r--r--drivers/staging/bcm/osal_misc.h49
-rw-r--r--drivers/staging/bcm/sort.c63
-rw-r--r--drivers/staging/bcm/target_params.h81
-rw-r--r--drivers/staging/bcm/vendorspecificextn.c146
-rw-r--r--drivers/staging/bcm/vendorspecificextn.h18
-rw-r--r--drivers/staging/brcm80211/Kconfig14
-rw-r--r--drivers/staging/brcm80211/Makefile65
-rw-r--r--drivers/staging/brcm80211/Module.symvers0
-rw-r--r--drivers/staging/brcm80211/README94
-rw-r--r--drivers/staging/brcm80211/TODO47
-rw-r--r--drivers/staging/brcm80211/include/aidmp.h374
-rw-r--r--drivers/staging/brcm80211/include/bcm_rpc.h80
-rw-r--r--drivers/staging/brcm80211/include/bcm_rpc_tp.h137
-rw-r--r--drivers/staging/brcm80211/include/bcm_xdr.h60
-rw-r--r--drivers/staging/brcm80211/include/bcmdefs.h224
-rw-r--r--drivers/staging/brcm80211/include/bcmdevs.h187
-rw-r--r--drivers/staging/brcm80211/include/bcmendian.h305
-rw-r--r--drivers/staging/brcm80211/include/bcmnvram.h173
-rw-r--r--drivers/staging/brcm80211/include/bcmotp.h44
-rw-r--r--drivers/staging/brcm80211/include/bcmsdbus.h113
-rw-r--r--drivers/staging/brcm80211/include/bcmsdh.h198
-rw-r--r--drivers/staging/brcm80211/include/bcmsdh_sdmmc.h108
-rw-r--r--drivers/staging/brcm80211/include/bcmsdpcm.h255
-rw-r--r--drivers/staging/brcm80211/include/bcmsrom.h34
-rw-r--r--drivers/staging/brcm80211/include/bcmsrom_fmt.h367
-rw-r--r--drivers/staging/brcm80211/include/bcmsrom_tbl.h583
-rw-r--r--drivers/staging/brcm80211/include/bcmutils.h606
-rw-r--r--drivers/staging/brcm80211/include/bcmwifi.h207
-rw-r--r--drivers/staging/brcm80211/include/bcmwpa.h86
-rw-r--r--drivers/staging/brcm80211/include/bitfuncs.h86
-rw-r--r--drivers/staging/brcm80211/include/d11.h1778
-rw-r--r--drivers/staging/brcm80211/include/dbus.h355
-rw-r--r--drivers/staging/brcm80211/include/epivers.h44
-rw-r--r--drivers/staging/brcm80211/include/hnddma.h243
-rw-r--r--drivers/staging/brcm80211/include/hndpmu.h71
-rw-r--r--drivers/staging/brcm80211/include/hndsoc.h199
-rw-r--r--drivers/staging/brcm80211/include/hndtcam.h48
-rw-r--r--drivers/staging/brcm80211/include/linux_osl.h385
-rw-r--r--drivers/staging/brcm80211/include/linuxver.h109
-rw-r--r--drivers/staging/brcm80211/include/nicpci.h79
-rw-r--r--drivers/staging/brcm80211/include/osl.h59
-rw-r--r--drivers/staging/brcm80211/include/packed_section_end.h32
-rw-r--r--drivers/staging/brcm80211/include/packed_section_start.h36
-rw-r--r--drivers/staging/brcm80211/include/pci_core.h122
-rw-r--r--drivers/staging/brcm80211/include/pcicfg.h524
-rw-r--r--drivers/staging/brcm80211/include/pcie_core.h299
-rw-r--r--drivers/staging/brcm80211/include/proto/802.11.h1436
-rw-r--r--drivers/staging/brcm80211/include/proto/802.11e.h110
-rw-r--r--drivers/staging/brcm80211/include/proto/802.1d.h37
-rw-r--r--drivers/staging/brcm80211/include/proto/bcmevent.h214
-rw-r--r--drivers/staging/brcm80211/include/proto/ethernet.h113
-rw-r--r--drivers/staging/brcm80211/include/proto/wpa.h128
-rw-r--r--drivers/staging/brcm80211/include/qmath.h80
-rw-r--r--drivers/staging/brcm80211/include/rpc_osl.h33
-rw-r--r--drivers/staging/brcm80211/include/sbchipc.h1588
-rw-r--r--drivers/staging/brcm80211/include/sbconfig.h272
-rw-r--r--drivers/staging/brcm80211/include/sbhnddma.h315
-rw-r--r--drivers/staging/brcm80211/include/sbhndpio.h52
-rw-r--r--drivers/staging/brcm80211/include/sbpcmcia.h217
-rw-r--r--drivers/staging/brcm80211/include/sbsdio.h152
-rw-r--r--drivers/staging/brcm80211/include/sbsdpcmdev.h281
-rw-r--r--drivers/staging/brcm80211/include/sbsocram.h175
-rw-r--r--drivers/staging/brcm80211/include/sdio.h552
-rw-r--r--drivers/staging/brcm80211/include/sdioh.h63
-rw-r--r--drivers/staging/brcm80211/include/sdiovar.h46
-rw-r--r--drivers/staging/brcm80211/include/siutils.h455
-rw-r--r--drivers/staging/brcm80211/include/spid.h155
-rw-r--r--drivers/staging/brcm80211/include/typedefs.h214
-rw-r--r--drivers/staging/brcm80211/include/wlioctl.h2007
-rw-r--r--drivers/staging/brcm80211/phy/phy_version.h36
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_cmn.c3454
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_hal.h263
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_int.h1229
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_lcn.c5329
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_lcn.h121
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_n.c29231
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phy_radio.h1533
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phyreg_n.h167
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c3639
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h49
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phytbl_n.c10631
-rw-r--r--drivers/staging/brcm80211/phy/wlc_phytbl_n.h39
-rw-r--r--drivers/staging/brcm80211/sys/d11ucode_ext.h35
-rw-r--r--drivers/staging/brcm80211/sys/wl_dbg.h82
-rw-r--r--drivers/staging/brcm80211/sys/wl_export.h63
-rw-r--r--drivers/staging/brcm80211/sys/wl_mac80211.c2552
-rw-r--r--drivers/staging/brcm80211/sys/wl_mac80211.h171
-rw-r--r--drivers/staging/brcm80211/sys/wl_ucode.h38
-rw-r--r--drivers/staging/brcm80211/sys/wl_ucode_loader.c89
-rw-r--r--drivers/staging/brcm80211/sys/wlc_alloc.c394
-rw-r--r--drivers/staging/brcm80211/sys/wlc_alloc.h25
-rw-r--r--drivers/staging/brcm80211/sys/wlc_ampdu.c1421
-rw-r--r--drivers/staging/brcm80211/sys/wlc_ampdu.h40
-rw-r--r--drivers/staging/brcm80211/sys/wlc_antsel.c329
-rw-r--r--drivers/staging/brcm80211/sys/wlc_antsel.h28
-rw-r--r--drivers/staging/brcm80211/sys/wlc_bmac.c4211
-rw-r--r--drivers/staging/brcm80211/sys/wlc_bmac.h277
-rw-r--r--drivers/staging/brcm80211/sys/wlc_bsscfg.h152
-rw-r--r--drivers/staging/brcm80211/sys/wlc_cfg.h310
-rw-r--r--drivers/staging/brcm80211/sys/wlc_channel.c1599
-rw-r--r--drivers/staging/brcm80211/sys/wlc_channel.h159
-rw-r--r--drivers/staging/brcm80211/sys/wlc_event.c229
-rw-r--r--drivers/staging/brcm80211/sys/wlc_event.h51
-rw-r--r--drivers/staging/brcm80211/sys/wlc_key.h143
-rw-r--r--drivers/staging/brcm80211/sys/wlc_mac80211.c9143
-rw-r--r--drivers/staging/brcm80211/sys/wlc_mac80211.h1039
-rw-r--r--drivers/staging/brcm80211/sys/wlc_phy_shim.c251
-rw-r--r--drivers/staging/brcm80211/sys/wlc_phy_shim.h115
-rw-r--r--drivers/staging/brcm80211/sys/wlc_pub.h714
-rw-r--r--drivers/staging/brcm80211/sys/wlc_rate.c498
-rw-r--r--drivers/staging/brcm80211/sys/wlc_rate.h170
-rw-r--r--drivers/staging/brcm80211/sys/wlc_rpc.h527
-rw-r--r--drivers/staging/brcm80211/sys/wlc_rpctx.h71
-rw-r--r--drivers/staging/brcm80211/sys/wlc_scb.h211
-rw-r--r--drivers/staging/brcm80211/sys/wlc_stf.c593
-rw-r--r--drivers/staging/brcm80211/sys/wlc_stf.h42
-rw-r--r--drivers/staging/brcm80211/sys/wlc_types.h52
-rw-r--r--drivers/staging/brcm80211/util/aiutils.c796
-rw-r--r--drivers/staging/brcm80211/util/bcmotp.c963
-rw-r--r--drivers/staging/brcm80211/util/bcmsrom.c2092
-rw-r--r--drivers/staging/brcm80211/util/bcmutils.c1789
-rw-r--r--drivers/staging/brcm80211/util/bcmwifi.c318
-rw-r--r--drivers/staging/brcm80211/util/bcmwpa.c52
-rw-r--r--drivers/staging/brcm80211/util/hnddma.c2699
-rw-r--r--drivers/staging/brcm80211/util/hndpmu.c2683
-rw-r--r--drivers/staging/brcm80211/util/linux_osl.c519
-rw-r--r--drivers/staging/brcm80211/util/nicpci.c883
-rw-r--r--drivers/staging/brcm80211/util/nvram/nvram_ro.c211
-rw-r--r--drivers/staging/brcm80211/util/qmath.c680
-rw-r--r--drivers/staging/brcm80211/util/siutils.c2961
-rw-r--r--drivers/staging/brcm80211/util/siutils_priv.h32
-rw-r--r--drivers/staging/comedi/comedi_fops.c4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c5
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c202
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c7
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c13
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c5
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c29
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c6
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c6
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c19
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c60
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c15
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c9
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c6
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c1
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c14
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c17
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c2
-rw-r--r--drivers/staging/comedi/drivers/me4000.c29
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c6
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c7
-rw-r--r--drivers/staging/comedi/drivers/skel.c7
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.c2
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c15
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h16
-rw-r--r--drivers/staging/cx25821/cx25821-core.c13
-rw-r--r--drivers/staging/cx25821/cx25821-video.c4
-rw-r--r--drivers/staging/cxt1e1/Kconfig2
-rw-r--r--drivers/staging/cxt1e1/functions.c4
-rw-r--r--drivers/staging/dream/camera/msm_camera.c3
-rw-r--r--drivers/staging/dream/pmem.c4
-rw-r--r--drivers/staging/dream/qdsp5/adsp_driver.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_aac.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_amrnb.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_evrc.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_in.c2
-rw-r--r--drivers/staging/dream/qdsp5/audio_mp3.c1
-rw-r--r--drivers/staging/dream/qdsp5/audio_out.c2
-rw-r--r--drivers/staging/dream/qdsp5/audio_qcelp.c1
-rw-r--r--drivers/staging/dream/qdsp5/evlog.h1
-rw-r--r--drivers/staging/dream/qdsp5/snd.c1
-rw-r--r--drivers/staging/et131x/et131x_initpci.c2
-rw-r--r--drivers/staging/frontier/alphatrack.c3
-rw-r--r--drivers/staging/frontier/tranzport.c3
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c19
-rw-r--r--drivers/staging/go7007/s2250-board.c7
-rw-r--r--drivers/staging/hv/TODO2
-rw-r--r--drivers/staging/hv/blkvsc_drv.c11
-rw-r--r--drivers/staging/hv/channel_interface.c29
-rw-r--r--drivers/staging/hv/channel_interface.h2
-rw-r--r--drivers/staging/hv/netvsc_drv.c3
-rw-r--r--drivers/staging/hv/ring_buffer.c3
-rw-r--r--drivers/staging/hv/storvsc_api.h4
-rw-r--r--drivers/staging/hv/storvsc_drv.c11
-rw-r--r--drivers/staging/hv/vmbus.c9
-rw-r--r--drivers/staging/hv/vmbus_api.h4
-rw-r--r--drivers/staging/hv/vmbus_drv.c4
-rw-r--r--drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c4
-rw-r--r--drivers/staging/iio/Documentation/overview.txt17
-rw-r--r--drivers/staging/iio/Documentation/ring.txt6
-rw-r--r--drivers/staging/iio/Documentation/sysfs-bus-iio (renamed from drivers/staging/iio/Documentation/sysfs-class-iio)72
-rw-r--r--drivers/staging/iio/Documentation/userspace.txt56
-rw-r--r--drivers/staging/iio/accel/accel.h42
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c34
-rw-r--r--drivers/staging/iio/accel/adis16209_ring.c49
-rw-r--r--drivers/staging/iio/accel/adis16209_trigger.c2
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c14
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c27
-rw-r--r--drivers/staging/iio/accel/adis16240_ring.c41
-rw-r--r--drivers/staging/iio/accel/adis16240_trigger.c2
-rw-r--r--drivers/staging/iio/accel/inclinometer.h2
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c2
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c65
-rw-r--r--drivers/staging/iio/accel/sca3000.h2
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c4
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c34
-rw-r--r--drivers/staging/iio/adc/adc.h7
-rw-r--r--drivers/staging/iio/adc/max1363_core.c1
-rw-r--r--drivers/staging/iio/adc/max1363_ring.c18
-rw-r--r--drivers/staging/iio/chrdev.h2
-rw-r--r--drivers/staging/iio/gyro/adis16260_core.c22
-rw-r--r--drivers/staging/iio/gyro/adis16260_ring.c39
-rw-r--r--drivers/staging/iio/gyro/adis16260_trigger.c2
-rw-r--r--drivers/staging/iio/gyro/gyro.h46
-rw-r--r--drivers/staging/iio/iio.h106
-rw-r--r--drivers/staging/iio/imu/adis16300_core.c36
-rw-r--r--drivers/staging/iio/imu/adis16300_ring.c51
-rw-r--r--drivers/staging/iio/imu/adis16300_trigger.c2
-rw-r--r--drivers/staging/iio/imu/adis16350_core.c45
-rw-r--r--drivers/staging/iio/imu/adis16350_ring.c55
-rw-r--r--drivers/staging/iio/imu/adis16350_trigger.c2
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c51
-rw-r--r--drivers/staging/iio/imu/adis16400_ring.c57
-rw-r--r--drivers/staging/iio/imu/adis16400_trigger.c2
-rw-r--r--drivers/staging/iio/industrialio-core.c89
-rw-r--r--drivers/staging/iio/industrialio-ring.c58
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig10
-rw-r--r--drivers/staging/iio/magnetometer/Makefile1
-rw-r--r--drivers/staging/iio/magnetometer/ak8975.c558
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c61
-rw-r--r--drivers/staging/iio/magnetometer/magnet.h12
-rw-r--r--drivers/staging/iio/ring_generic.h181
-rw-r--r--drivers/staging/iio/ring_sw.c79
-rw-r--r--drivers/staging/iio/ring_sw.h12
-rw-r--r--drivers/staging/iio/sysfs.h100
-rw-r--r--drivers/staging/iio/trigger.h6
-rw-r--r--drivers/staging/iio/trigger/iio-trig-gpio.c2
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c12
-rw-r--r--drivers/staging/keucr/Kconfig13
-rw-r--r--drivers/staging/keucr/Makefile16
-rw-r--r--drivers/staging/keucr/Module.symvers0
-rw-r--r--drivers/staging/keucr/TODO11
-rw-r--r--drivers/staging/keucr/common.h26
-rw-r--r--drivers/staging/keucr/init.c541
-rw-r--r--drivers/staging/keucr/init.h2066
-rw-r--r--drivers/staging/keucr/ms.c956
-rw-r--r--drivers/staging/keucr/ms.h381
-rw-r--r--drivers/staging/keucr/msscsi.c320
-rw-r--r--drivers/staging/keucr/scsiglue.c448
-rw-r--r--drivers/staging/keucr/scsiglue.h10
-rw-r--r--drivers/staging/keucr/sdscsi.c210
-rw-r--r--drivers/staging/keucr/smcommon.h33
-rw-r--r--drivers/staging/keucr/smil.h290
-rw-r--r--drivers/staging/keucr/smilecc.c201
-rw-r--r--drivers/staging/keucr/smilmain.c1852
-rw-r--r--drivers/staging/keucr/smilsub.c1661
-rw-r--r--drivers/staging/keucr/smscsi.c189
-rw-r--r--drivers/staging/keucr/transport.c788
-rw-r--r--drivers/staging/keucr/transport.h144
-rw-r--r--drivers/staging/keucr/usb.c701
-rw-r--r--drivers/staging/keucr/usb.h238
-rw-r--r--drivers/staging/line6/Kconfig67
-rw-r--r--drivers/staging/line6/audio.c16
-rw-r--r--drivers/staging/line6/audio.h7
-rw-r--r--drivers/staging/line6/capture.c231
-rw-r--r--drivers/staging/line6/capture.h25
-rw-r--r--drivers/staging/line6/control.c46
-rw-r--r--drivers/staging/line6/control.h190
-rw-r--r--drivers/staging/line6/driver.c569
-rw-r--r--drivers/staging/line6/driver.h57
-rw-r--r--drivers/staging/line6/dumprequest.c60
-rw-r--r--drivers/staging/line6/dumprequest.h28
-rw-r--r--drivers/staging/line6/midi.c96
-rw-r--r--drivers/staging/line6/midi.h9
-rw-r--r--drivers/staging/line6/midibuf.c90
-rw-r--r--drivers/staging/line6/midibuf.h31
-rw-r--r--drivers/staging/line6/pcm.c320
-rw-r--r--drivers/staging/line6/pcm.h144
-rw-r--r--drivers/staging/line6/playback.c313
-rw-r--r--drivers/staging/line6/playback.h28
-rw-r--r--drivers/staging/line6/pod.c758
-rw-r--r--drivers/staging/line6/pod.h127
-rw-r--r--drivers/staging/line6/revision.h2
-rw-r--r--drivers/staging/line6/toneport.c276
-rw-r--r--drivers/staging/line6/toneport.h33
-rw-r--r--drivers/staging/line6/usbdefs.h42
-rw-r--r--drivers/staging/line6/variax.c356
-rw-r--r--drivers/staging/line6/variax.h84
-rw-r--r--drivers/staging/lirc/lirc_imon.c19
-rw-r--r--drivers/staging/lirc/lirc_it87.c1
-rw-r--r--drivers/staging/lirc/lirc_sasem.c16
-rw-r--r--drivers/staging/lirc/lirc_serial.c1
-rw-r--r--drivers/staging/lirc/lirc_sir.c1
-rw-r--r--drivers/staging/lirc/lirc_zilog.c10
-rw-r--r--drivers/staging/memrar/memrar_handler.c1
-rw-r--r--drivers/staging/mrst-touchscreen/Kconfig7
-rw-r--r--drivers/staging/mrst-touchscreen/Makefile3
-rw-r--r--drivers/staging/mrst-touchscreen/TODO2
-rw-r--r--drivers/staging/mrst-touchscreen/intel-mid-touch.c864
-rw-r--r--drivers/staging/msm/mddihost.c2
-rw-r--r--drivers/staging/msm/mdp.c10
-rw-r--r--drivers/staging/msm/msm_fb.c2
-rw-r--r--drivers/staging/octeon/Kconfig2
-rw-r--r--drivers/staging/octeon/cvmx-fpa.c2
-rw-r--r--drivers/staging/octeon/cvmx-fpa.h2
-rw-r--r--drivers/staging/otus/80211core/ratectrl.c26
-rw-r--r--drivers/staging/otus/wwrap.c4
-rw-r--r--drivers/staging/panel/panel.c1
-rw-r--r--drivers/staging/pohmelfs/config.c34
-rw-r--r--drivers/staging/quatech_usb2/quatech_usb2.c2
-rw-r--r--drivers/staging/quickstart/quickstart.c7
-rw-r--r--drivers/staging/rt2860/ap.h20
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c8
-rw-r--r--drivers/staging/rt2860/eeprom.h4
-rw-r--r--drivers/staging/rt2860/iface/rtmp_pci.h42
-rw-r--r--drivers/staging/rt2860/iface/rtmp_usb.h110
-rw-r--r--drivers/staging/rt2860/oid.h2
-rw-r--r--drivers/staging/rt2860/rt_linux.c3
-rw-r--r--drivers/staging/rt2860/rtmp.h18
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c41
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h1
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c4
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c10
-rw-r--r--drivers/staging/rtl8192e/ieee80211.h213
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_module.c71
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c18
-rw-r--r--drivers/staging/rtl8192e/r8180_93cx6.c8
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.c2
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.h12
-rw-r--r--drivers/staging/rtl8192e/r8192E.h7
-rw-r--r--drivers/staging/rtl8192e/r8192E_core.c162
-rw-r--r--drivers/staging/rtl8192e/r8192E_dm.c480
-rw-r--r--drivers/staging/rtl8192e/r8192E_dm.h2
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.c38
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.h2
-rw-r--r--drivers/staging/rtl8192e/r8192_pm.c6
-rw-r--r--drivers/staging/rtl8192e/r819xE_cmdpkt.c310
-rw-r--r--drivers/staging/rtl8192e/r819xE_cmdpkt.h2
-rw-r--r--drivers/staging/rtl8192e/r819xE_firmware.c40
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.c39
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.h50
-rw-r--r--drivers/staging/rtl8192su/Kconfig9
-rw-r--r--drivers/staging/rtl8192su/Makefile39
-rw-r--r--drivers/staging/rtl8192su/TODO21
-rw-r--r--drivers/staging/rtl8192su/authors1
-rw-r--r--drivers/staging/rtl8192su/ieee80211/Makefile30
-rw-r--r--drivers/staging/rtl8192su/ieee80211/dot11d.c224
-rw-r--r--drivers/staging/rtl8192su/ieee80211/dot11d.h111
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211.h1934
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c242
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h86
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c471
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c776
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c294
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_module.c301
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h449
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c2580
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c3291
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c625
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c916
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c772
-rw-r--r--drivers/staging/rtl8192su/ieee80211/readme162
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_BA.h79
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c745
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h530
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c1725
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h540
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_TS.h71
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c631
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.c647
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.h60
-rw-r--r--drivers/staging/rtl8192su/r8192SU_led.c2338
-rw-r--r--drivers/staging/rtl8192su/r8192SU_led.h93
-rw-r--r--drivers/staging/rtl8192su/r8192S_Efuse.c2199
-rw-r--r--drivers/staging/rtl8192su/r8192S_Efuse.h79
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.c481
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.h210
-rw-r--r--drivers/staging/rtl8192su/r8192S_hw.h1445
-rw-r--r--drivers/staging/rtl8192su/r8192S_phy.c3634
-rw-r--r--drivers/staging/rtl8192su/r8192S_phy.h135
-rw-r--r--drivers/staging/rtl8192su/r8192S_phyreg.h1033
-rw-r--r--drivers/staging/rtl8192su/r8192S_rtl6052.c842
-rw-r--r--drivers/staging/rtl8192su/r8192S_rtl6052.h87
-rw-r--r--drivers/staging/rtl8192su/r8192S_rtl8225.c292
-rw-r--r--drivers/staging/rtl8192su/r8192S_rtl8225.h30
-rw-r--r--drivers/staging/rtl8192su/r8192U.h1519
-rw-r--r--drivers/staging/rtl8192su/r8192U_core.c7712
-rw-r--r--drivers/staging/rtl8192su/r8192U_dm.c3982
-rw-r--r--drivers/staging/rtl8192su/r8192U_dm.h254
-rw-r--r--drivers/staging/rtl8192su/r8192U_pm.c72
-rw-r--r--drivers/staging/rtl8192su/r8192U_pm.h25
-rw-r--r--drivers/staging/rtl8192su/r8192U_wx.c1296
-rw-r--r--drivers/staging/rtl8192su/r8192U_wx.h22
-rw-r--r--drivers/staging/rtl8192su/r819xU_HTGen.h22
-rw-r--r--drivers/staging/rtl8192su/r819xU_HTType.h383
-rw-r--r--drivers/staging/rtl8192su/r819xU_cmdpkt.c512
-rw-r--r--drivers/staging/rtl8192su/r819xU_cmdpkt.h192
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c2
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c25
-rw-r--r--drivers/staging/rtl8192u/r819xU_firmware.c2
-rw-r--r--drivers/staging/rtl8712/Kconfig18
-rw-r--r--drivers/staging/rtl8712/Makefile34
-rw-r--r--drivers/staging/rtl8712/TODO16
-rw-r--r--drivers/staging/rtl8712/basic_types.h23
-rw-r--r--drivers/staging/rtl8712/big_endian.h69
-rw-r--r--drivers/staging/rtl8712/drv_types.h165
-rw-r--r--drivers/staging/rtl8712/ethernet.h23
-rw-r--r--drivers/staging/rtl8712/farray.h10197
-rw-r--r--drivers/staging/rtl8712/generic.h153
-rw-r--r--drivers/staging/rtl8712/hal_init.c358
-rw-r--r--drivers/staging/rtl8712/ieee80211.c454
-rw-r--r--drivers/staging/rtl8712/ieee80211.h770
-rw-r--r--drivers/staging/rtl8712/if_ether.h116
-rw-r--r--drivers/staging/rtl8712/ip.h137
-rw-r--r--drivers/staging/rtl8712/little_endian.h69
-rw-r--r--drivers/staging/rtl8712/mlme_linux.c170
-rw-r--r--drivers/staging/rtl8712/mlme_osdep.h18
-rw-r--r--drivers/staging/rtl8712/mp_custom_oid.h274
-rw-r--r--drivers/staging/rtl8712/os_intfs.c464
-rw-r--r--drivers/staging/rtl8712/osdep_intf.h19
-rw-r--r--drivers/staging/rtl8712/osdep_service.h260
-rw-r--r--drivers/staging/rtl8712/recv_linux.c169
-rw-r--r--drivers/staging/rtl8712/recv_osdep.h27
-rw-r--r--drivers/staging/rtl8712/rtl8712_bitdef.h19
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.c465
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.h157
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h89
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h15
-rw-r--r--drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h36
-rw-r--r--drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h28
-rw-r--r--drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h52
-rw-r--r--drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h18
-rw-r--r--drivers/staging/rtl8712/rtl8712_efuse.c568
-rw-r--r--drivers/staging/rtl8712/rtl8712_efuse.h43
-rw-r--r--drivers/staging/rtl8712/rtl8712_event.h73
-rw-r--r--drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h126
-rw-r--r--drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h57
-rw-r--r--drivers/staging/rtl8712/rtl8712_gp_bitdef.h54
-rw-r--r--drivers/staging/rtl8712/rtl8712_gp_regdef.h17
-rw-r--r--drivers/staging/rtl8712/rtl8712_hal.h124
-rw-r--r--drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h39
-rw-r--r--drivers/staging/rtl8712/rtl8712_io.c151
-rw-r--r--drivers/staging/rtl8712/rtl8712_led.c1815
-rw-r--r--drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h28
-rw-r--r--drivers/staging/rtl8712/rtl8712_macsetting_regdef.h16
-rw-r--r--drivers/staging/rtl8712/rtl8712_powersave_bitdef.h33
-rw-r--r--drivers/staging/rtl8712/rtl8712_powersave_regdef.h20
-rw-r--r--drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h30
-rw-r--r--drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h31
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.c1131
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.h128
-rw-r--r--drivers/staging/rtl8712/rtl8712_regdef.h19
-rw-r--r--drivers/staging/rtl8712/rtl8712_security_bitdef.h29
-rw-r--r--drivers/staging/rtl8712/rtl8712_spec.h110
-rw-r--r--drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h145
-rw-r--r--drivers/staging/rtl8712/rtl8712_syscfg_regdef.h31
-rw-r--r--drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h44
-rw-r--r--drivers/staging/rtl8712/rtl8712_timectrl_regdef.h20
-rw-r--r--drivers/staging/rtl8712/rtl8712_wmac_bitdef.h37
-rw-r--r--drivers/staging/rtl8712/rtl8712_wmac_regdef.h24
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.c509
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.h95
-rw-r--r--drivers/staging/rtl8712/rtl871x_byteorder.h13
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.c926
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.h719
-rw-r--r--drivers/staging/rtl8712/rtl871x_debug.h142
-rw-r--r--drivers/staging/rtl8712/rtl871x_eeprom.c233
-rw-r--r--drivers/staging/rtl8712/rtl871x_eeprom.h82
-rw-r--r--drivers/staging/rtl8712/rtl871x_event.h95
-rw-r--r--drivers/staging/rtl8712/rtl871x_ht.h19
-rw-r--r--drivers/staging/rtl8712/rtl871x_io.c163
-rw-r--r--drivers/staging/rtl8712/rtl871x_io.h233
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl.h97
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c2247
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_rtl.c535
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_rtl.h96
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_set.c379
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_set.h24
-rw-r--r--drivers/staging/rtl8712/rtl871x_led.h99
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c1840
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.h208
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp.c736
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp.h318
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.c1475
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.h457
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h1025
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.c250
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.h127
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.c693
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.h330
-rw-r--r--drivers/staging/rtl8712/rtl871x_rf.h43
-rw-r--r--drivers/staging/rtl8712/rtl871x_security.c1389
-rw-r--r--drivers/staging/rtl8712/rtl871x_security.h196
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c299
-rw-r--r--drivers/staging/rtl8712/rtl871x_wlan_sme.h22
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c1052
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.h260
-rw-r--r--drivers/staging/rtl8712/sta_info.h125
-rw-r--r--drivers/staging/rtl8712/swab.h106
-rw-r--r--drivers/staging/rtl8712/usb_halinit.c317
-rw-r--r--drivers/staging/rtl8712/usb_intf.c571
-rw-r--r--drivers/staging/rtl8712/usb_ops.c201
-rw-r--r--drivers/staging/rtl8712/usb_ops.h25
-rw-r--r--drivers/staging/rtl8712/usb_ops_linux.c529
-rw-r--r--drivers/staging/rtl8712/usb_osintf.h24
-rw-r--r--drivers/staging/rtl8712/usb_vendor_req.h33
-rw-r--r--drivers/staging/rtl8712/wifi.h622
-rw-r--r--drivers/staging/rtl8712/wlan_bssdef.h242
-rw-r--r--drivers/staging/rtl8712/xmit_linux.c182
-rw-r--r--drivers/staging/rtl8712/xmit_osdep.h38
-rw-r--r--drivers/staging/sbe-2t3e3/2t3e3.h894
-rw-r--r--drivers/staging/sbe-2t3e3/Kconfig13
-rw-r--r--drivers/staging/sbe-2t3e3/Makefile4
-rw-r--r--drivers/staging/sbe-2t3e3/TODO6
-rw-r--r--drivers/staging/sbe-2t3e3/cpld.c366
-rw-r--r--drivers/staging/sbe-2t3e3/ctrl.c362
-rw-r--r--drivers/staging/sbe-2t3e3/ctrl.h131
-rw-r--r--drivers/staging/sbe-2t3e3/dc.c502
-rw-r--r--drivers/staging/sbe-2t3e3/exar7250.c217
-rw-r--r--drivers/staging/sbe-2t3e3/exar7300.c182
-rw-r--r--drivers/staging/sbe-2t3e3/intr.c635
-rw-r--r--drivers/staging/sbe-2t3e3/io.c352
-rw-r--r--drivers/staging/sbe-2t3e3/main.c171
-rw-r--r--drivers/staging/sbe-2t3e3/maps.c104
-rw-r--r--drivers/staging/sbe-2t3e3/module.c210
-rw-r--r--drivers/staging/sbe-2t3e3/netdev.c142
-rw-r--r--drivers/staging/slicoss/slic.h8
-rw-r--r--drivers/staging/slicoss/slicoss.c42
-rw-r--r--drivers/staging/sm7xx/smtcfb.c13
-rw-r--r--drivers/staging/solo6x10/solo6010-core.c40
-rw-r--r--drivers/staging/solo6x10/solo6010-g723.c2
-rw-r--r--drivers/staging/solo6x10/solo6010-i2c.c2
-rw-r--r--drivers/staging/solo6x10/solo6010-p2m.c2
-rw-r--r--drivers/staging/spectra/Kconfig3
-rw-r--r--drivers/staging/spectra/ffsport.c8
-rw-r--r--drivers/staging/spectra/flash.h2
-rw-r--r--drivers/staging/spectra/lld_nand.c7
-rw-r--r--drivers/staging/ti-st/st.h1
-rw-r--r--drivers/staging/ti-st/st_core.c14
-rw-r--r--drivers/staging/ti-st/st_core.h2
-rw-r--r--drivers/staging/ti-st/st_kim.c22
-rw-r--r--drivers/staging/tidspbridge/Makefile4
-rw-r--r--drivers/staging/tidspbridge/core/chnl_sm.c1
-rw-r--r--drivers/staging/tidspbridge/core/dsp-clock.c1
-rw-r--r--drivers/staging/tidspbridge/core/io_sm.c1
-rw-r--r--drivers/staging/tidspbridge/core/sync.c (renamed from drivers/staging/tidspbridge/services/sync.c)17
-rw-r--r--drivers/staging/tidspbridge/core/tiomap3430.c1
-rw-r--r--drivers/staging/tidspbridge/core/tiomap3430_pwr.c4
-rw-r--r--drivers/staging/tidspbridge/core/tiomap_io.c1
-rw-r--r--drivers/staging/tidspbridge/gen/gb.c1
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/cfg.h222
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/drv.h2
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/mgr.h2
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/services.h50
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/wdt.h2
-rw-r--r--drivers/staging/tidspbridge/pmgr/chnl.c1
-rw-r--r--drivers/staging/tidspbridge/pmgr/cmm.c1
-rw-r--r--drivers/staging/tidspbridge/pmgr/dbll.c2
-rw-r--r--drivers/staging/tidspbridge/pmgr/dev.c69
-rw-r--r--drivers/staging/tidspbridge/pmgr/dspapi.c18
-rw-r--r--drivers/staging/tidspbridge/pmgr/io.c3
-rw-r--r--drivers/staging/tidspbridge/rmgr/dbdcd.c8
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c59
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c15
-rw-r--r--drivers/staging/tidspbridge/rmgr/dspdrv.c12
-rw-r--r--drivers/staging/tidspbridge/rmgr/mgr.c52
-rw-r--r--drivers/staging/tidspbridge/rmgr/node.c1
-rw-r--r--drivers/staging/tidspbridge/rmgr/proc.c48
-rw-r--r--drivers/staging/tidspbridge/rmgr/strm.c1
-rw-r--r--drivers/staging/tidspbridge/services/cfg.c253
-rw-r--r--drivers/staging/tidspbridge/services/ntfy.c31
-rw-r--r--drivers/staging/tidspbridge/services/services.c70
-rw-r--r--drivers/staging/tm6000/Kconfig2
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c7
-rw-r--r--drivers/staging/tm6000/tm6000-core.c6
-rw-r--r--drivers/staging/tm6000/tm6000-input.c2
-rw-r--r--drivers/staging/udlfb/udlfb.c987
-rw-r--r--drivers/staging/udlfb/udlfb.h39
-rw-r--r--drivers/staging/udlfb/udlfb.txt144
-rw-r--r--drivers/staging/usbip/stub_dev.c2
-rw-r--r--drivers/staging/vme/devices/vme_user.c2
-rw-r--r--drivers/staging/vt6655/device_main.c3
-rw-r--r--drivers/staging/vt6655/iwctl.c2
-rw-r--r--drivers/staging/vt6655/wpactl.c11
-rw-r--r--drivers/staging/vt6656/80211mgr.h10
-rw-r--r--drivers/staging/vt6656/baseband.c2
-rw-r--r--drivers/staging/vt6656/bssdb.c14
-rw-r--r--drivers/staging/vt6656/channel.c3
-rw-r--r--drivers/staging/vt6656/device.h19
-rw-r--r--drivers/staging/vt6656/dpc.c17
-rw-r--r--drivers/staging/vt6656/firmware.c4
-rw-r--r--drivers/staging/vt6656/ioctl.c2
-rw-r--r--drivers/staging/vt6656/iwctl.c20
-rw-r--r--drivers/staging/vt6656/iwctl.h3
-rw-r--r--drivers/staging/vt6656/key.c2
-rw-r--r--drivers/staging/vt6656/main_usb.c29
-rw-r--r--drivers/staging/vt6656/power.c6
-rw-r--r--drivers/staging/vt6656/rxtx.c26
-rw-r--r--drivers/staging/vt6656/tether.h34
-rw-r--r--drivers/staging/vt6656/usbpipe.c52
-rw-r--r--drivers/staging/vt6656/wcmd.c4
-rw-r--r--drivers/staging/vt6656/wmgr.c19
-rw-r--r--drivers/staging/vt6656/wmgr.h2
-rw-r--r--drivers/staging/vt6656/wpa.c8
-rw-r--r--drivers/staging/vt6656/wpactl.c6
-rw-r--r--drivers/staging/westbridge/Kconfig53
-rw-r--r--drivers/staging/westbridge/TODO7
-rw-r--r--drivers/staging/westbridge/astoria/Kconfig9
-rw-r--r--drivers/staging/westbridge/astoria/Makefile11
-rw-r--r--drivers/staging/westbridge/astoria/api/Makefile14
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasdma.c1107
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasintr.c143
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c358
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c1264
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasmisc.c3474
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasmtp.c1128
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasstorage.c4104
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasusb.c3718
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c2450
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h55
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h319
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h558
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h72
-rw-r--r--drivers/staging/westbridge/astoria/block/Kconfig9
-rw-r--r--drivers/staging/westbridge/astoria/block/Makefile11
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_block.c1628
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c417
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h64
-rw-r--r--drivers/staging/westbridge/astoria/device/Kconfig9
-rw-r--r--drivers/staging/westbridge/astoria/device/Makefile23
-rw-r--r--drivers/staging/westbridge/astoria/device/cyandevice_export.h132
-rw-r--r--drivers/staging/westbridge/astoria/device/cyasdevice.c394
-rw-r--r--drivers/staging/westbridge/astoria/gadget/Kconfig9
-rw-r--r--drivers/staging/westbridge/astoria/gadget/Makefile11
-rw-r--r--drivers/staging/westbridge/astoria/gadget/cyasgadget.c2177
-rw-r--r--drivers/staging/westbridge/astoria/gadget/cyasgadget.h193
-rw-r--r--drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h99
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h418
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h59
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h614
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h180
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h30
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h419
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h35
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h31
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h619
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h11
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h11
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h35
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h1057
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h375
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h1094
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h108
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h44
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h800
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h104
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h36
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h366
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h54
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h1549
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h53
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h646
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h3838
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h201
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h2759
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h309
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h36
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h30
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h71
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h1862
-rw-r--r--drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h224
-rw-r--r--drivers/staging/wlags49_h2/mdd.h2
-rw-r--r--drivers/staging/wlags49_h2/wl_main.c2
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c3
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c2
-rw-r--r--drivers/staging/xgifb/XGI_accel.h3
-rw-r--r--drivers/staging/xgifb/XGI_main.h30
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c3876
-rw-r--r--drivers/staging/xgifb/vb_ext.c1737
-rw-r--r--drivers/staging/xgifb/vb_init.c5022
-rw-r--r--drivers/staging/xgifb/vb_setmode.c17041
-rw-r--r--drivers/staging/xgifb/vb_table.h620
-rw-r--r--drivers/staging/xgifb/vb_util.c192
-rw-r--r--drivers/staging/zram/Kconfig12
-rw-r--r--drivers/staging/zram/Makefile2
-rw-r--r--drivers/staging/zram/zram.txt58
-rw-r--r--drivers/staging/zram/zram_drv.c222
-rw-r--r--drivers/staging/zram/zram_drv.h57
-rw-r--r--drivers/staging/zram/zram_ioctl.h41
-rw-r--r--drivers/staging/zram/zram_sysfs.c224
-rw-r--r--drivers/telephony/ixj.c10
-rw-r--r--drivers/telephony/phonedev.c1
-rw-r--r--drivers/uio/uio.c1
-rw-r--r--drivers/uio/uio_pci_generic.c13
-rw-r--r--drivers/usb/atm/cxacru.c42
-rw-r--r--drivers/usb/class/cdc-acm.c23
-rw-r--r--drivers/usb/class/cdc-wdm.c3
-rw-r--r--drivers/usb/class/usblp.c1
-rw-r--r--drivers/usb/class/usbtmc.c1
-rw-r--r--drivers/usb/core/file.c1
-rw-r--r--drivers/usb/core/hcd.c1
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/core/message.c22
-rw-r--r--drivers/usb/core/urb.c5
-rw-r--r--drivers/usb/gadget/Kconfig10
-rw-r--r--drivers/usb/gadget/amd5536udc.c11
-rw-r--r--drivers/usb/gadget/at91_udc.c12
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c7
-rw-r--r--drivers/usb/gadget/audio.c10
-rw-r--r--drivers/usb/gadget/cdc2.c10
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c18
-rw-r--r--drivers/usb/gadget/composite.c136
-rw-r--r--drivers/usb/gadget/dbgp.c19
-rw-r--r--drivers/usb/gadget/dummy_hcd.c10
-rw-r--r--drivers/usb/gadget/ether.c16
-rw-r--r--drivers/usb/gadget/f_audio.c2
-rw-r--r--drivers/usb/gadget/f_hid.c5
-rw-r--r--drivers/usb/gadget/f_loopback.c7
-rw-r--r--drivers/usb/gadget/f_mass_storage.c16
-rw-r--r--drivers/usb/gadget/f_sourcesink.c5
-rw-r--r--drivers/usb/gadget/file_storage.c54
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c12
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c16
-rw-r--r--drivers/usb/gadget/g_ffs.c91
-rw-r--r--drivers/usb/gadget/gmidi.c5
-rw-r--r--drivers/usb/gadget/goku_udc.c9
-rw-r--r--drivers/usb/gadget/hid.c10
-rw-r--r--drivers/usb/gadget/imx_udc.c9
-rw-r--r--drivers/usb/gadget/inode.c18
-rw-r--r--drivers/usb/gadget/langwell_udc.c1047
-rw-r--r--drivers/usb/gadget/langwell_udc.h15
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c10
-rw-r--r--drivers/usb/gadget/m66592-udc.c9
-rw-r--r--drivers/usb/gadget/mass_storage.c82
-rw-r--r--drivers/usb/gadget/multi.c36
-rw-r--r--drivers/usb/gadget/net2280.c10
-rw-r--r--drivers/usb/gadget/nokia.c11
-rw-r--r--drivers/usb/gadget/omap_udc.c10
-rw-r--r--drivers/usb/gadget/printer.c10
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c9
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c14
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c9
-rw-r--r--drivers/usb/gadget/rndis.c498
-rw-r--r--drivers/usb/gadget/rndis.h2
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c11
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c17
-rw-r--r--drivers/usb/gadget/serial.c11
-rw-r--r--drivers/usb/gadget/storage_common.c3
-rw-r--r--drivers/usb/gadget/webcam.c11
-rw-r--r--drivers/usb/gadget/zero.c5
-rw-r--r--drivers/usb/host/ehci-dbg.c4
-rw-r--r--drivers/usb/host/ehci-fsl.c6
-rw-r--r--drivers/usb/host/ehci-fsl.h1
-rw-r--r--drivers/usb/host/ehci-hcd.c16
-rw-r--r--drivers/usb/host/ehci-mxc.c13
-rw-r--r--drivers/usb/host/ehci-pci.c5
-rw-r--r--drivers/usb/host/ehci-ppc-of.c12
-rw-r--r--drivers/usb/host/imx21-hcd.c4
-rw-r--r--drivers/usb/host/ohci-dbg.c3
-rw-r--r--drivers/usb/host/ohci-hcd.c1
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c9
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/u132-hcd.c8
-rw-r--r--drivers/usb/image/mdc800.c1
-rw-r--r--drivers/usb/image/microtek.c9
-rw-r--r--drivers/usb/misc/adutux.c1
-rw-r--r--drivers/usb/misc/ftdi-elan.c4
-rw-r--r--drivers/usb/misc/idmouse.c1
-rw-r--r--drivers/usb/misc/iowarrior.c1
-rw-r--r--drivers/usb/misc/ldusb.c1
-rw-r--r--drivers/usb/misc/rio500.c1
-rw-r--r--drivers/usb/misc/usblcd.c1
-rw-r--r--drivers/usb/mon/mon_main.c2
-rw-r--r--drivers/usb/musb/musb_debugfs.c5
-rw-r--r--drivers/usb/musb/musb_gadget.c10
-rw-r--r--drivers/usb/otg/Kconfig14
-rw-r--r--drivers/usb/otg/Makefile1
-rw-r--r--drivers/usb/otg/langwell_otg.c2408
-rw-r--r--drivers/usb/otg/twl4030-usb.c91
-rw-r--r--drivers/usb/serial/Kconfig9
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/cp210x.c11
-rw-r--r--drivers/usb/serial/cypress_m8.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c9
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h12
-rw-r--r--drivers/usb/serial/garmin_gps.c1
-rw-r--r--drivers/usb/serial/io_edgeport.c11
-rw-r--r--drivers/usb/serial/io_ti.c4
-rw-r--r--drivers/usb/serial/iuu_phoenix.c1
-rw-r--r--drivers/usb/serial/keyspan_pda.c1
-rw-r--r--drivers/usb/serial/mos7720.c6
-rw-r--r--drivers/usb/serial/mos7840.c39
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/option.c119
-rw-r--r--drivers/usb/serial/sam-ba.c206
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/serial/spcp8x5.c1
-rw-r--r--drivers/usb/serial/ssu100.c2
-rw-r--r--drivers/usb/serial/usb_wwan.c1
-rw-r--r--drivers/usb/serial/whiteheat.c6
-rw-r--r--drivers/usb/usb-skeleton.c1
-rw-r--r--drivers/uwb/address.c5
-rw-r--r--drivers/uwb/i1480/i1480u-wlp/lc.c16
-rw-r--r--drivers/uwb/wlp/messages.c40
-rw-r--r--drivers/uwb/wlp/sysfs.c46
-rw-r--r--drivers/uwb/wlp/wlp-lc.c12
-rw-r--r--drivers/uwb/wlp/wss-lc.c7
-rw-r--r--drivers/vbus/Kconfig25
-rw-r--r--drivers/vbus/Makefile6
-rw-r--r--drivers/vbus/bus-proxy.c248
-rw-r--r--drivers/vbus/pci-bridge.c1016
-rw-r--r--drivers/vhost/net.c17
-rw-r--r--drivers/vhost/vhost.c107
-rw-r--r--drivers/vhost/vhost.h10
-rw-r--r--drivers/video/Kconfig1
-rw-r--r--drivers/video/bf54x-lq043fb.c6
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c2
-rw-r--r--drivers/video/fbmem.c1
-rw-r--r--drivers/video/mbx/mbxdebugfs.c6
-rw-r--r--drivers/video/omap2/displays/Kconfig2
-rw-r--r--drivers/video/omap2/dss/dispc.c214
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c18
-rw-r--r--drivers/video/omap2/vram.c10
-rw-r--r--drivers/video/pxa168fb.c6
-rw-r--r--drivers/video/q40fb.c4
-rw-r--r--drivers/video/sh_mipi_dsi.c32
-rw-r--r--drivers/video/sh_mobile_hdmi.c657
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c211
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h38
-rw-r--r--drivers/video/vesafb.c2
-rw-r--r--drivers/video/via/dvi.c172
-rw-r--r--drivers/video/via/dvi.h4
-rw-r--r--drivers/video/via/hw.c456
-rw-r--r--drivers/video/via/hw.h16
-rw-r--r--drivers/video/via/ioctl.c2
-rw-r--r--drivers/video/via/lcd.c49
-rw-r--r--drivers/video/via/lcd.h6
-rw-r--r--drivers/video/via/lcdtbl.h591
-rw-r--r--drivers/video/via/viafbdev.c8
-rw-r--r--drivers/video/via/viafbdev.h3
-rw-r--r--drivers/watchdog/Kconfig6
-rw-r--r--drivers/watchdog/ar7_wdt.c1
-rw-r--r--drivers/watchdog/cpwd.c16
-rw-r--r--drivers/watchdog/ep93xx_wdt.c1
-rw-r--r--drivers/watchdog/omap_wdt.c1
-rw-r--r--drivers/watchdog/sb_wdog.c12
-rw-r--r--drivers/watchdog/ts72xx_wdt.c3
-rw-r--r--drivers/xen/evtchn.c1
-rw-r--r--drivers/xen/xenfs/super.c1
-rw-r--r--drivers/xen/xenfs/xenbus.c1
2385 files changed, 455738 insertions, 99684 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index ae473445ad6d..443c4eb48cae 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_EISA) += eisa/
obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
+obj-$(CONFIG_DMA_ENGINE) += dma/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-$(CONFIG_NEW_LEDS) += leds/
@@ -104,7 +105,6 @@ obj-$(CONFIG_ARCH_SHMOBILE) += sh/
ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
obj-y += clocksource/
endif
-obj-$(CONFIG_DMA_ENGINE) += dma/
obj-$(CONFIG_DCA) += dca/
obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
@@ -115,3 +115,4 @@ obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_STAGING) += staging/
obj-y += platform/
obj-y += ieee802154/
+obj-y += vbus/
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 74c24d517f81..4093522eed45 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void)
*
* DESCRIPTION: Reacquire the interpreter execution region from within the
* interpreter code. Failure to enter the interpreter region is a
- * fatal system error. Used in conjuction with
+ * fatal system error. Used in conjunction with
* relinquish_interpreter
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c
index 22cfcfbd9fff..491191e6cf69 100644
--- a/drivers/acpi/acpica/rsutils.c
+++ b/drivers/acpi/acpica/rsutils.c
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
/*
* 16-, 32-, and 64-bit cases must use the move macros that perform
- * endian conversion and/or accomodate hardware that cannot perform
+ * endian conversion and/or accommodate hardware that cannot perform
* misaligned memory transfers
*/
case ACPI_RSC_MOVE16:
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 907e350f1c7d..fca34ccfd294 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG
depends on ACPI_APEI
help
ERST is a way provided by APEI to save and retrieve hardware
- error infomation to and from a persistent store. Enable this
+ error information to and from a persistent store. Enable this
if you want to debugging and testing the ERST kernel support
and firmware implementation.
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c
index 5281ddda2777..98ffa2991ebc 100644
--- a/drivers/acpi/apei/erst-dbg.c
+++ b/drivers/acpi/apei/erst-dbg.c
@@ -2,7 +2,7 @@
* APEI Error Record Serialization Table debug support
*
* ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store. This file provide the
+ * information to and from a persistent store. This file provide the
* debugging/testing support for ERST kernel support and firmware
* implementation.
*
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 18645f4e83cd..a4904f1680cf 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -2,7 +2,7 @@
* APEI Error Record Serialization Table support
*
* ERST is a way provided by APEI to save and retrieve hardware error
- * infomation to and from a persistent store.
+ * information to and from a persistent store.
*
* For more information about ERST, please refer to ACPI Specification
* version 4.0, section 17.4.
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index dc58402b0a17..98417201e9ce 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 5c221ab535d5..cc17b352d1c5 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir);
static int set_power_nocheck(const struct dmi_system_id *id)
{
printk(KERN_NOTICE PREFIX "%s detected - "
- "disable power check in power transistion\n", id->ident);
+ "disable power check in power transition\n", id->ident);
acpi_power_nocheck = 1;
return 0;
}
@@ -1027,7 +1027,7 @@ static int __init acpi_init(void)
/*
* If the laptop falls into the DMI check table, the power state check
- * will be disabled in the course of device power transistion.
+ * will be disabled in the course of device power transition.
*/
dmi_check_system(power_nocheck_dmi_table);
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index 0e869b3f81ca..cbc910617cda 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -101,6 +101,7 @@ static struct file_operations acpi_ec_io_ops = {
.open = acpi_ec_open_io,
.read = acpi_ec_read_io,
.write = acpi_ec_write_io,
+ .llseek = default_llseek,/* read accesses f_pos */
};
int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count)
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index d439314a75d8..0900ca193c38 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -110,6 +110,7 @@ static const struct file_operations acpi_system_event_ops = {
.read = acpi_system_read_event,
.release = acpi_system_close_event,
.poll = acpi_system_poll_event,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif /* CONFIG_ACPI_PROC_EVENT */
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 1f67057af2a5..3ba8d1f44a73 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -33,7 +33,6 @@
#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
-#include <linux/pci-aspm.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <acpi/acpi_bus.h>
@@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle,
return status;
}
-static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
+ u32 support,
+ u32 *control)
{
acpi_status status;
- u32 support_set, result, capbuf[3];
+ u32 result, capbuf[3];
+
+ support &= OSC_PCI_SUPPORT_MASKS;
+ support |= root->osc_support_set;
- /* do _OSC query for all possible controls */
- support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- capbuf[OSC_SUPPORT_TYPE] = support_set;
- capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
+ capbuf[OSC_SUPPORT_TYPE] = support;
+ if (control) {
+ *control &= OSC_PCI_CONTROL_MASKS;
+ capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
+ } else {
+ /* Run _OSC query for all possible controls. */
+ capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
+ }
status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
if (ACPI_SUCCESS(status)) {
- root->osc_support_set = support_set;
- root->osc_control_qry = result;
- root->osc_queried = 1;
+ root->osc_support_set = support;
+ if (control)
+ *control = result;
}
return status;
}
@@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
if (ACPI_FAILURE(status))
return status;
mutex_lock(&osc_lock);
- status = acpi_pci_query_osc(root, flags);
+ status = acpi_pci_query_osc(root, flags, NULL);
mutex_unlock(&osc_lock);
return status;
}
@@ -365,55 +373,70 @@ out:
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
/**
- * acpi_pci_osc_control_set - commit requested control to Firmware
- * @handle: acpi_handle for the target ACPI object
- * @flags: driver's requested control bits
+ * acpi_pci_osc_control_set - Request control of PCI root _OSC features.
+ * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
+ * @mask: Mask of _OSC bits to request control of, place to store control mask.
+ * @req: Mask of _OSC bits the control of is essential to the caller.
+ *
+ * Run _OSC query for @mask and if that is successful, compare the returned
+ * mask of control bits with @req. If all of the @req bits are set in the
+ * returned mask, run _OSC request for it.
*
- * Attempt to take control from Firmware on requested control bits.
+ * The variable at the @mask address may be modified regardless of whether or
+ * not the function returns success. On success it will contain the mask of
+ * _OSC bits the BIOS has granted control of, but its contents are meaningless
+ * on failure.
**/
-acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
+acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
{
+ struct acpi_pci_root *root;
acpi_status status;
- u32 control_req, result, capbuf[3];
+ u32 ctrl, capbuf[3];
acpi_handle tmp;
- struct acpi_pci_root *root;
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return status;
+ if (!mask)
+ return AE_BAD_PARAMETER;
- control_req = (flags & OSC_PCI_CONTROL_MASKS);
- if (!control_req)
+ ctrl = *mask & OSC_PCI_CONTROL_MASKS;
+ if ((ctrl & req) != req)
return AE_TYPE;
root = acpi_pci_find_root(handle);
if (!root)
return AE_NOT_EXIST;
+ status = acpi_get_handle(handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
mutex_lock(&osc_lock);
+
+ *mask = ctrl | root->osc_control_set;
/* No need to evaluate _OSC if the control was already granted. */
- if ((root->osc_control_set & control_req) == control_req)
+ if ((root->osc_control_set & ctrl) == ctrl)
goto out;
- /* Need to query controls first before requesting them */
- if (!root->osc_queried) {
- status = acpi_pci_query_osc(root, root->osc_support_set);
+ /* Need to check the available controls bits before requesting them. */
+ while (*mask) {
+ status = acpi_pci_query_osc(root, root->osc_support_set, mask);
if (ACPI_FAILURE(status))
goto out;
+ if (ctrl == *mask)
+ break;
+ ctrl = *mask;
}
- if ((root->osc_control_qry & control_req) != control_req) {
- printk(KERN_DEBUG
- "Firmware did not grant requested _OSC control\n");
+
+ if ((ctrl & req) != req) {
status = AE_SUPPORT;
goto out;
}
capbuf[OSC_QUERY_TYPE] = 0;
capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
- capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
- status = acpi_pci_run_osc(handle, capbuf, &result);
+ capbuf[OSC_CONTROL_TYPE] = ctrl;
+ status = acpi_pci_run_osc(handle, capbuf, mask);
if (ACPI_SUCCESS(status))
- root->osc_control_set = result;
+ root->osc_control_set = *mask;
out:
mutex_unlock(&osc_lock);
return status;
@@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
if (flags != base_flags)
acpi_pci_osc_support(root, flags);
- status = acpi_pci_osc_control_set(root->device->handle,
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
- pcie_no_aspm();
- }
-
pci_acpi_add_bus_pm_notifier(device, root->bus);
if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index ba1bd263d903..3a73a93596e8 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module)
if (!try_module_get(calling_module))
return -EINVAL;
- /* is_done is set to negative if an error occured,
- * and to postitive if _no_ error occured, but SMM
+ /* is_done is set to negative if an error occurred,
+ * and to postitive if _no_ error occurred, but SMM
* was already notified. This avoids double notification
* which might lead to unexpected results...
*/
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 68e2e4582fa2..f8588f81048a 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
};
-static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
+static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
return result;
}
-static int param_get_debug_level(char *buffer, struct kernel_param *kp)
+static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp)
return result;
}
-module_param_call(debug_layer, param_set_uint, param_get_debug_layer,
- &acpi_dbg_layer, 0644);
-module_param_call(debug_level, param_set_uint, param_get_debug_level,
- &acpi_dbg_level, 0644);
+static struct kernel_param_ops param_ops_debug_layer = {
+ .set = param_set_uint,
+ .get = param_get_debug_layer,
+};
+
+static struct kernel_param_ops param_ops_debug_level = {
+ .set = param_set_uint,
+ .get = param_get_debug_level,
+};
+
+module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644);
+module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644);
static char trace_method_name[6];
module_param_string(trace_method_name, trace_method_name, 6, 0644);
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index c5fef01b3c95..b83676126598 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
- printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
- "control misses _BQC function\n");
+ printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
+ "cannot determine initial brightness\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index d5df04a395ca..ccd461bb5ee4 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -99,7 +99,7 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
-libata-objs := libata-core.o libata-scsi.o libata-eh.o
+libata-objs := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 013727b20417..ff1c945fba98 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -253,6 +253,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
+ { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
+ { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */
+ { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 3971bc0a4838..d712675d0a96 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -302,6 +302,10 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (CPT) */
{ 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+ /* SATA Controller IDE (PBG) */
+ { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+ /* SATA Controller IDE (PBG) */
+ { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
{ } /* terminate list */
};
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 666850d31df2..68dc6785472f 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1326,7 +1326,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
/* issue the first D2H Register FIS */
msecs = 0;
now = jiffies;
- if (time_after(now, deadline))
+ if (time_after(deadline, now))
msecs = jiffies_to_msecs(deadline - now);
tf.ctl |= ATA_SRST;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c035b3d041ee..a83d8541a6b3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -68,7 +68,7 @@
#include <linux/ratelimit.h>
#include "libata.h"
-
+#include "libata-transport.h"
/* debounce timing parameters in msecs { interval, duration, timeout } */
const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
@@ -1017,7 +1017,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
return "<n/a>";
}
-static const char *sata_spd_string(unsigned int spd)
+const char *sata_spd_string(unsigned int spd)
{
static const char * const spd_str[] = {
"1.5 Gbps",
@@ -4939,17 +4939,7 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
dev->flags &= ~ATA_DFLAG_DUBIOUS_XFER;
}
-/**
- * ata_qc_complete - Complete an active ATA command
- * @qc: Command to complete
- *
- * Indicate to the mid and upper layers that an ATA
- * command has completed, with either an ok or not-ok status.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_qc_complete(struct ata_queued_cmd *qc)
+static void ata_qc_complete_raw(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
@@ -5028,6 +5018,27 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
}
/**
+ * ata_qc_complete - Complete an active ATA command
+ * @qc: Command to complete
+ *
+ * Indicate to the mid and upper layers that an ATA command has
+ * completed, with either an ok or not-ok status.
+ *
+ * Refrain from calling this function multiple times when
+ * successfully completing multiple NCQ commands.
+ * ata_qc_complete_multiple() should be used instead, which will
+ * properly update IRQ expect state.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_qc_complete(struct ata_queued_cmd *qc)
+{
+ unexpect_irq(qc->ap->irq_expect, false);
+ ata_qc_complete_raw(qc);
+}
+
+/**
* ata_qc_complete_multiple - Complete multiple qcs successfully
* @ap: port in question
* @qc_active: new qc_active mask
@@ -5037,6 +5048,10 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
* requests normally. ap->qc_active and @qc_active is compared
* and commands are completed accordingly.
*
+ * Always use this function when completing multiple NCQ commands
+ * from IRQ handlers instead of calling ata_qc_complete()
+ * multiple times to keep IRQ expect status properly in sync.
+ *
* LOCKING:
* spin_lock_irqsave(host lock)
*
@@ -5048,6 +5063,8 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active)
int nr_done = 0;
u32 done_mask;
+ unexpect_irq(ap->irq_expect, false);
+
done_mask = ap->qc_active ^ qc_active;
if (unlikely(done_mask & qc_active)) {
@@ -5062,12 +5079,15 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active)
qc = ata_qc_from_tag(ap, tag);
if (qc) {
- ata_qc_complete(qc);
+ ata_qc_complete_raw(qc);
nr_done++;
}
done_mask &= ~(1 << tag);
}
+ if (ap->qc_active)
+ expect_irq(ap->irq_expect);
+
return nr_done;
}
@@ -5137,6 +5157,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
qc->err_mask |= ap->ops->qc_issue(qc);
if (unlikely(qc->err_mask))
goto err;
+ expect_irq(ap->irq_expect);
return;
sys_err:
@@ -5418,6 +5439,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
*/
int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
{
+ unsigned int ehi_flags = ATA_EHI_QUIET;
int rc;
/*
@@ -5426,7 +5448,18 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
*/
ata_lpm_enable(host);
- rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
+ /*
+ * On some hardware, device fails to respond after spun down
+ * for suspend. As the device won't be used before being
+ * resumed, we don't need to touch the device. Ask EH to skip
+ * the usual stuff and proceed directly to suspend.
+ *
+ * http://thread.gmane.org/gmane.linux.ide/46764
+ */
+ if (mesg.event == PM_EVENT_SUSPEND)
+ ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
+
+ rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1);
if (rc == 0)
host->dev->power.power_state = mesg;
return rc;
@@ -5505,7 +5538,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
int i;
/* clear everything except for devices */
- memset(link, 0, offsetof(struct ata_link, device[0]));
+ memset((void *)link + ATA_LINK_CLEAR_BEGIN, 0,
+ ATA_LINK_CLEAR_END - ATA_LINK_CLEAR_BEGIN);
link->ap = ap;
link->pmp = pmp;
@@ -5579,7 +5613,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
if (!ap)
return NULL;
-
+
ap->pflags |= ATA_PFLAG_INITIALIZING;
ap->lock = &host->lock;
ap->print_id = -1;
@@ -6081,9 +6115,18 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
for (i = 0; i < host->n_ports; i++)
host->ports[i]->print_id = ata_print_id++;
+
+ /* Create associated sysfs transport objects */
+ for (i = 0; i < host->n_ports; i++) {
+ rc = ata_tport_add(host->dev,host->ports[i]);
+ if (rc) {
+ goto err_tadd;
+ }
+ }
+
rc = ata_scsi_add_hosts(host, sht);
if (rc)
- return rc;
+ goto err_tadd;
/* associate with ACPI nodes */
ata_acpi_associate(host);
@@ -6124,6 +6167,13 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
}
return 0;
+
+ err_tadd:
+ while (--i >= 0) {
+ ata_tport_delete(host->ports[i]);
+ }
+ return rc;
+
}
/**
@@ -6170,8 +6220,13 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
return rc;
- for (i = 0; i < host->n_ports; i++)
- ata_port_desc(host->ports[i], "irq %d", irq);
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!ata_port_is_dummy(ap))
+ ap->irq_expect = init_irq_expect(irq, host);
+ ata_port_desc(ap, "irq %d%s", irq, ap->irq_expect ? "+" : "");
+ }
rc = ata_host_register(host, sht);
/* if failed, just free the IRQ and leave ports alone */
@@ -6214,6 +6269,13 @@ static void ata_port_detach(struct ata_port *ap)
cancel_rearming_delayed_work(&ap->hotplug_task);
skip_eh:
+ if (ap->pmp_link) {
+ int i;
+ for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
+ ata_tlink_delete(&ap->pmp_link[i]);
+ }
+ ata_tport_delete(ap);
+
/* remove the associated SCSI host */
scsi_remove_host(ap->scsi_host);
}
@@ -6530,7 +6592,7 @@ static void __init ata_parse_force_param(void)
static int __init ata_init(void)
{
- int rc = -ENOMEM;
+ int rc;
ata_parse_force_param();
@@ -6540,12 +6602,25 @@ static int __init ata_init(void)
return rc;
}
+ libata_transport_init();
+ ata_scsi_transport_template = ata_attach_transport();
+ if (!ata_scsi_transport_template) {
+ ata_sff_exit();
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
return 0;
+
+err_out:
+ return rc;
}
static void __exit ata_exit(void)
{
+ ata_release_transport(ata_scsi_transport_template);
+ libata_transport_exit();
ata_sff_exit();
kfree(ata_force_tbl);
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index c9ae299b8342..4d11f079e85c 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -57,6 +57,7 @@ enum {
/* error flags */
ATA_EFLAG_IS_IO = (1 << 0),
ATA_EFLAG_DUBIOUS_XFER = (1 << 1),
+ ATA_EFLAG_OLD_ER = (1 << 31),
/* error categories */
ATA_ECAT_NONE = 0,
@@ -396,14 +397,9 @@ static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering)
return NULL;
}
-static void ata_ering_clear(struct ata_ering *ering)
-{
- memset(ering, 0, sizeof(*ering));
-}
-
-static int ata_ering_map(struct ata_ering *ering,
- int (*map_fn)(struct ata_ering_entry *, void *),
- void *arg)
+int ata_ering_map(struct ata_ering *ering,
+ int (*map_fn)(struct ata_ering_entry *, void *),
+ void *arg)
{
int idx, rc = 0;
struct ata_ering_entry *ent;
@@ -422,6 +418,17 @@ static int ata_ering_map(struct ata_ering *ering,
return rc;
}
+int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg)
+{
+ ent->eflags |= ATA_EFLAG_OLD_ER;
+ return 0;
+}
+
+static void ata_ering_clear(struct ata_ering *ering)
+{
+ ata_ering_map(ering, ata_ering_clear_cb, NULL);
+}
+
static unsigned int ata_eh_dev_action(struct ata_device *dev)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
@@ -572,19 +579,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;
@@ -619,8 +626,10 @@ void ata_scsi_error(struct Scsi_Host *host)
* handler doesn't diddle with those qcs. This must
* be done atomically w.r.t. setting QCFLAG_FAILED.
*/
- if (nr_timedout)
+ if (nr_timedout) {
+ unexpect_irq(ap->irq_expect, true);
__ata_port_freeze(ap);
+ }
spin_unlock_irqrestore(ap->lock, flags);
@@ -628,7 +637,7 @@ 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 ? */
@@ -1755,7 +1764,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
struct speed_down_verdict_arg *arg = void_arg;
int cat;
- if (ent->timestamp < arg->since)
+ if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since))
return -1;
cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,
@@ -3235,6 +3244,10 @@ static int ata_eh_skip_recovery(struct ata_link *link)
if (link->flags & ATA_LFLAG_DISABLED)
return 1;
+ /* skip if explicitly requested */
+ if (ehc->i.flags & ATA_EHI_NO_RECOVERY)
+ return 1;
+
/* thaw frozen port and recover failed devices */
if ((ap->pflags & ATA_PFLAG_FROZEN) || ata_link_nr_enabled(link))
return 0;
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 224faabd7b7e..505470237d79 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -11,6 +11,7 @@
#include <linux/libata.h>
#include <linux/slab.h>
#include "libata.h"
+#include "libata-transport.h"
const struct ata_port_operations sata_pmp_port_ops = {
.inherits = &sata_port_ops,
@@ -312,10 +313,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
return rc;
}
-static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
+static int sata_pmp_init_links (struct ata_port *ap, int nr_ports)
{
struct ata_link *pmp_link = ap->pmp_link;
- int i;
+ int i, err;
if (!pmp_link) {
pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS,
@@ -327,6 +328,13 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
ata_link_init(ap, &pmp_link[i], i);
ap->pmp_link = pmp_link;
+
+ for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
+ err = ata_tlink_add(&pmp_link[i]);
+ if (err) {
+ goto err_tlink;
+ }
+ }
}
for (i = 0; i < nr_ports; i++) {
@@ -339,6 +347,12 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
}
return 0;
+ err_tlink:
+ while (--i >= 0)
+ ata_tlink_delete(&pmp_link[i]);
+ kfree(pmp_link);
+ ap->pmp_link = NULL;
+ return err;
}
static void sata_pmp_quirks(struct ata_port *ap)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index a89172c100f5..f1c0118c6d4b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -51,8 +51,8 @@
#include <asm/unaligned.h>
#include "libata.h"
+#include "libata-transport.h"
-#define SECTOR_SIZE 512
#define ATA_SCSI_RBUF_SIZE 4096
static DEFINE_SPINLOCK(ata_scsi_rbuf_lock);
@@ -64,9 +64,6 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
static struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
-static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun);
-
#define RW_RECOVERY_MPAGE 0x1
#define RW_RECOVERY_MPAGE_LEN 12
@@ -106,17 +103,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
0, 30 /* extended self test time, see 05-359r1 */
};
-/*
- * libata transport template. libata doesn't do real transport stuff.
- * It just needs the eh_timed_out hook.
- */
-static struct scsi_transport_template ata_scsi_transport_template = {
- .eh_strategy_handler = ata_scsi_error,
- .eh_timed_out = ata_scsi_timed_out,
- .user_scan = ata_scsi_user_scan,
-};
-
-
static const struct {
enum link_pm value;
const char *name;
@@ -516,7 +502,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
memset(scsi_cmd, 0, sizeof(scsi_cmd));
if (args[3]) {
- argsize = SECTOR_SIZE * args[3];
+ argsize = ATA_SECT_SIZE * args[3];
argbuf = kmalloc(argsize, GFP_KERNEL);
if (argbuf == NULL) {
rc = -ENOMEM;
@@ -1150,8 +1136,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
} else {
/* ATA devices must be sector aligned */
+ sdev->sector_size = ata_id_logical_sector_size(dev->id);
blk_queue_update_dma_alignment(sdev->request_queue,
- ATA_SECT_SIZE - 1);
+ sdev->sector_size - 1);
sdev->manage_start_stop = 1;
}
@@ -1166,6 +1153,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
}
+ dev->sdev = sdev;
return 0;
}
@@ -1696,7 +1684,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
goto nothing_to_do;
qc->flags |= ATA_QCFLAG_IO;
- qc->nbytes = n_block * ATA_SECT_SIZE;
+ qc->nbytes = n_block * scmd->device->sector_size;
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
qc->tag);
@@ -2123,7 +2111,7 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
{
- u32 min_io_sectors;
+ u16 min_io_sectors;
rbuf[1] = 0xb0;
rbuf[3] = 0x3c; /* required VPD size with unmap support */
@@ -2135,10 +2123,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
* logical than physical sector size we need to figure out what the
* latter is.
*/
- if (ata_id_has_large_logical_sectors(args->id))
- min_io_sectors = ata_id_logical_per_physical_sectors(args->id);
- else
- min_io_sectors = 1;
+ min_io_sectors = 1 << ata_id_log2_per_physical_sector(args->id);
put_unaligned_be16(min_io_sectors, &rbuf[6]);
/*
@@ -2397,21 +2382,13 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
{
struct ata_device *dev = args->dev;
u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
- u8 log_per_phys = 0;
- u16 lowest_aligned = 0;
- u16 word_106 = dev->id[106];
- u16 word_209 = dev->id[209];
-
- if ((word_106 & 0xc000) == 0x4000) {
- /* Number and offset of logical sectors per physical sector */
- if (word_106 & (1 << 13))
- log_per_phys = word_106 & 0xf;
- if ((word_209 & 0xc000) == 0x4000) {
- u16 first = dev->id[209] & 0x3fff;
- if (first > 0)
- lowest_aligned = (1 << log_per_phys) - first;
- }
- }
+ u32 sector_size; /* physical sector size in bytes */
+ u8 log2_per_phys;
+ u16 lowest_aligned;
+
+ sector_size = ata_id_logical_sector_size(dev->id);
+ log2_per_phys = ata_id_log2_per_physical_sector(dev->id);
+ lowest_aligned = ata_id_logical_sector_offset(dev->id, log2_per_phys);
VPRINTK("ENTER\n");
@@ -2426,8 +2403,10 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
rbuf[3] = last_lba;
/* sector size */
- rbuf[6] = ATA_SECT_SIZE >> 8;
- rbuf[7] = ATA_SECT_SIZE & 0xff;
+ rbuf[4] = sector_size >> (8 * 3);
+ rbuf[5] = sector_size >> (8 * 2);
+ rbuf[6] = sector_size >> (8 * 1);
+ rbuf[7] = sector_size;
} else {
/* sector count, 64-bit */
rbuf[0] = last_lba >> (8 * 7);
@@ -2440,11 +2419,13 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
rbuf[7] = last_lba;
/* sector size */
- rbuf[10] = ATA_SECT_SIZE >> 8;
- rbuf[11] = ATA_SECT_SIZE & 0xff;
+ rbuf[ 8] = sector_size >> (8 * 3);
+ rbuf[ 9] = sector_size >> (8 * 2);
+ rbuf[10] = sector_size >> (8 * 1);
+ rbuf[11] = sector_size;
rbuf[12] = 0;
- rbuf[13] = log_per_phys;
+ rbuf[13] = log2_per_phys;
rbuf[14] = (lowest_aligned >> 8) & 0x3f;
rbuf[15] = lowest_aligned;
@@ -2888,9 +2869,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = dev->devno ?
tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
- /* READ/WRITE LONG use a non-standard sect_size */
- qc->sect_size = ATA_SECT_SIZE;
switch (tf->command) {
+ /* READ/WRITE LONG use a non-standard sect_size */
case ATA_CMD_READ_LONG:
case ATA_CMD_READ_LONG_ONCE:
case ATA_CMD_WRITE_LONG:
@@ -2898,6 +2878,45 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
goto invalid_fld;
qc->sect_size = scsi_bufflen(scmd);
+ break;
+
+ /* commands using reported Logical Block size (e.g. 512 or 4K) */
+ case ATA_CMD_CFA_WRITE_NE:
+ case ATA_CMD_CFA_TRANS_SECT:
+ case ATA_CMD_CFA_WRITE_MULT_NE:
+ /* XXX: case ATA_CMD_CFA_WRITE_SECTORS_WITHOUT_ERASE: */
+ case ATA_CMD_READ:
+ case ATA_CMD_READ_EXT:
+ case ATA_CMD_READ_QUEUED:
+ /* XXX: case ATA_CMD_READ_QUEUED_EXT: */
+ case ATA_CMD_FPDMA_READ:
+ case ATA_CMD_READ_MULTI:
+ case ATA_CMD_READ_MULTI_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
+ case ATA_CMD_READ_STREAM_DMA_EXT:
+ case ATA_CMD_READ_STREAM_EXT:
+ case ATA_CMD_VERIFY:
+ case ATA_CMD_VERIFY_EXT:
+ case ATA_CMD_WRITE:
+ case ATA_CMD_WRITE_EXT:
+ case ATA_CMD_WRITE_FUA_EXT:
+ case ATA_CMD_WRITE_QUEUED:
+ case ATA_CMD_WRITE_QUEUED_FUA_EXT:
+ case ATA_CMD_FPDMA_WRITE:
+ case ATA_CMD_WRITE_MULTI:
+ case ATA_CMD_WRITE_MULTI_EXT:
+ case ATA_CMD_WRITE_MULTI_FUA_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
+ case ATA_CMD_WRITE_STREAM_DMA_EXT:
+ case ATA_CMD_WRITE_STREAM_EXT:
+ qc->sect_size = scmd->device->sector_size;
+ break;
+
+ /* Everything else uses 512 byte "sectors" */
+ default:
+ qc->sect_size = ATA_SECT_SIZE;
}
/*
@@ -3334,7 +3353,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
*(struct ata_port **)&shost->hostdata[0] = ap;
ap->scsi_host = shost;
- shost->transportt = &ata_scsi_transport_template;
+ shost->transportt = ata_scsi_transport_template;
shost->unique_id = ap->print_id;
shost->max_id = 16;
shost->max_lun = 1;
@@ -3393,6 +3412,8 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
if (!IS_ERR(sdev)) {
dev->sdev = sdev;
scsi_device_put(sdev);
+ } else {
+ dev->sdev = NULL;
}
}
}
@@ -3616,8 +3637,8 @@ void ata_scsi_hotplug(struct work_struct *work)
* RETURNS:
* Zero.
*/
-static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun)
+int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
+ unsigned int id, unsigned int lun)
{
struct ata_port *ap = ata_shost_to_port(shost);
unsigned long flags;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 3b82d8ef76f0..ccd42c8313a1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -418,6 +418,7 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
if (ioaddr->ctl_addr)
iowrite8(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
+ ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
@@ -453,6 +454,8 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
iowrite8(tf->device, ioaddr->device_addr);
VPRINTK("device 0x%X\n", tf->device);
}
+
+ ata_wait_idle(ap);
}
EXPORT_SYMBOL_GPL(ata_sff_tf_load);
@@ -1042,7 +1045,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
u8 status, int in_wq)
{
- struct ata_eh_info *ehi = &ap->link.eh_info;
+ struct ata_link *link = qc->dev->link;
+ struct ata_eh_info *ehi = &link->eh_info;
unsigned long flags = 0;
int poll_next;
@@ -1298,8 +1302,14 @@ fsm_start:
}
EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
-void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay)
+void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay)
{
+ struct ata_port *ap = link->ap;
+
+ WARN_ON((ap->sff_pio_task_link != NULL) &&
+ (ap->sff_pio_task_link != link));
+ ap->sff_pio_task_link = link;
+
/* may fail if ata_sff_flush_pio_task() in progress */
queue_delayed_work(ata_sff_wq, &ap->sff_pio_task,
msecs_to_jiffies(delay));
@@ -1321,14 +1331,18 @@ static void ata_sff_pio_task(struct work_struct *work)
{
struct ata_port *ap =
container_of(work, struct ata_port, sff_pio_task.work);
+ struct ata_link *link = ap->sff_pio_task_link;
struct ata_queued_cmd *qc;
u8 status;
int poll_next;
+ BUG_ON(ap->sff_pio_task_link == NULL);
/* qc can be NULL if timeout occurred */
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (!qc)
+ qc = ata_qc_from_tag(ap, link->active_tag);
+ if (!qc) {
+ ap->sff_pio_task_link = NULL;
return;
+ }
fsm_start:
WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE);
@@ -1345,11 +1359,16 @@ fsm_start:
msleep(2);
status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
- ata_sff_queue_pio_task(ap, ATA_SHORT_PAUSE);
+ ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
return;
}
}
+ /*
+ * hsm_move() may trigger another command to be processed.
+ * clean the link beforehand.
+ */
+ ap->sff_pio_task_link = NULL;
/* move the HSM */
poll_next = ata_sff_hsm_move(ap, qc, status, 1);
@@ -1376,6 +1395,7 @@ fsm_start:
unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_link *link = qc->dev->link;
/* Use polling pio if the LLD doesn't handle
* interrupt driven pio and atapi CDB interrupt.
@@ -1396,7 +1416,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
ap->hsm_task_state = HSM_ST_LAST;
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
break;
@@ -1409,7 +1429,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
if (qc->tf.flags & ATA_TFLAG_WRITE) {
/* PIO data out protocol */
ap->hsm_task_state = HSM_ST_FIRST;
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
/* always send first data block using the
* ata_sff_pio_task() codepath.
@@ -1419,7 +1439,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
ap->hsm_task_state = HSM_ST;
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
/* if polling, ata_sff_pio_task() handles the
* rest. otherwise, interrupt handler takes
@@ -1441,7 +1461,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
(qc->tf.flags & ATA_TFLAG_POLLING))
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
break;
default:
@@ -2388,7 +2408,8 @@ int ata_pci_sff_activate_host(struct ata_host *host,
struct device *dev = host->dev;
struct pci_dev *pdev = to_pci_dev(dev);
const char *drv_name = dev_driver_string(host->dev);
- int legacy_mode = 0, rc;
+ struct ata_port *ap[2] = { host->ports[0], host->ports[1] };
+ int legacy_mode = 0, i, rc;
rc = ata_host_start(host);
if (rc)
@@ -2422,29 +2443,29 @@ int ata_pci_sff_activate_host(struct ata_host *host,
if (rc)
goto out;
- ata_port_desc(host->ports[0], "irq %d", pdev->irq);
- ata_port_desc(host->ports[1], "irq %d", pdev->irq);
+ for (i = 0; i < 2; i++) {
+ if (!ata_port_is_dummy(ap[i]))
+ ap[i]->irq_expect =
+ init_irq_expect(pdev->irq, host);
+ ata_port_desc(ap[i], "irq %d%s",
+ pdev->irq, ap[i]->irq_expect ? "+" : "");
+ }
} else if (legacy_mode) {
- if (!ata_port_is_dummy(host->ports[0])) {
- rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev),
- irq_handler, IRQF_SHARED,
- drv_name, host);
- if (rc)
- goto out;
+ unsigned int irqs[2] = { ATA_PRIMARY_IRQ(pdev),
+ ATA_SECONDARY_IRQ(pdev) };
- ata_port_desc(host->ports[0], "irq %d",
- ATA_PRIMARY_IRQ(pdev));
- }
+ for (i = 0; i < 2; i++) {
+ if (ata_port_is_dummy(ap[i]))
+ continue;
- if (!ata_port_is_dummy(host->ports[1])) {
- rc = devm_request_irq(dev, ATA_SECONDARY_IRQ(pdev),
- irq_handler, IRQF_SHARED,
- drv_name, host);
+ rc = devm_request_irq(dev, irqs[i], irq_handler,
+ IRQF_SHARED, drv_name, host);
if (rc)
goto out;
- ata_port_desc(host->ports[1], "irq %d",
- ATA_SECONDARY_IRQ(pdev));
+ ap[i]->irq_expect = init_irq_expect(irqs[i], host);
+ ata_port_desc(ap[i], "irq %d%s",
+ irqs[i], ap[i]->irq_expect ? "+" : "");
}
}
@@ -2734,6 +2755,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_link *link = qc->dev->link;
/* defer PIO handling to sff_qc_issue */
if (!ata_is_dma(qc->tf.protocol))
@@ -2762,7 +2784,7 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
break;
default:
@@ -3321,7 +3343,7 @@ int __init ata_sff_init(void)
return 0;
}
-void __exit ata_sff_exit(void)
+void ata_sff_exit(void)
{
destroy_workqueue(ata_sff_wq);
}
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
new file mode 100644
index 000000000000..ce9dc6207f37
--- /dev/null
+++ b/drivers/ata/libata-transport.c
@@ -0,0 +1,774 @@
+/*
+ * Copyright 2008 ioogle, Inc. All rights reserved.
+ * Released under GPL v2.
+ *
+ * Libata transport class.
+ *
+ * The ATA transport class contains common code to deal with ATA HBAs,
+ * an approximated representation of ATA topologies in the driver model,
+ * and various sysfs attributes to expose these topologies and management
+ * interfaces to user-space.
+ *
+ * There are 3 objects defined in in this class:
+ * - ata_port
+ * - ata_link
+ * - ata_device
+ * Each port has a link object. Each link can have up to two devices for PATA
+ * and generally one for SATA.
+ * If there is SATA port multiplier [PMP], 15 additional ata_link object are
+ * created.
+ *
+ * These objects are created when the ata host is initialized and when a PMP is
+ * found. They are removed only when the HBA is removed, cleaned before the
+ * error handler runs.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/blkdev.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <scsi/scsi_transport.h>
+#include <linux/libata.h>
+#include <linux/hdreg.h>
+#include <linux/uaccess.h>
+
+#include "libata.h"
+#include "libata-transport.h"
+
+#define ATA_PORT_ATTRS 2
+#define ATA_LINK_ATTRS 3
+#define ATA_DEV_ATTRS 9
+
+struct scsi_transport_template;
+struct scsi_transport_template *ata_scsi_transport_template;
+
+struct ata_internal {
+ struct scsi_transport_template t;
+
+ struct device_attribute private_port_attrs[ATA_PORT_ATTRS];
+ struct device_attribute private_link_attrs[ATA_LINK_ATTRS];
+ struct device_attribute private_dev_attrs[ATA_DEV_ATTRS];
+
+ struct transport_container link_attr_cont;
+ struct transport_container dev_attr_cont;
+
+ /*
+ * The array of null terminated pointers to attributes
+ * needed by scsi_sysfs.c
+ */
+ struct device_attribute *link_attrs[ATA_LINK_ATTRS + 1];
+ struct device_attribute *port_attrs[ATA_PORT_ATTRS + 1];
+ struct device_attribute *dev_attrs[ATA_DEV_ATTRS + 1];
+};
+#define to_ata_internal(tmpl) container_of(tmpl, struct ata_internal, t)
+
+
+#define tdev_to_device(d) \
+ container_of((d), struct ata_device, tdev)
+#define transport_class_to_dev(dev) \
+ tdev_to_device((dev)->parent)
+
+#define tdev_to_link(d) \
+ container_of((d), struct ata_link, tdev)
+#define transport_class_to_link(dev) \
+ tdev_to_link((dev)->parent)
+
+#define tdev_to_port(d) \
+ container_of((d), struct ata_port, tdev)
+#define transport_class_to_port(dev) \
+ tdev_to_port((dev)->parent)
+
+
+/* Device objects are always created whit link objects */
+static int ata_tdev_add(struct ata_device *dev);
+static void ata_tdev_delete(struct ata_device *dev);
+
+
+/*
+ * Hack to allow attributes of the same name in different objects.
+ */
+#define ATA_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
+ struct device_attribute device_attr_##_prefix##_##_name = \
+ __ATTR(_name,_mode,_show,_store)
+
+#define ata_bitfield_name_match(title, table) \
+static ssize_t \
+get_ata_##title##_names(u32 table_key, char *buf) \
+{ \
+ char *prefix = ""; \
+ ssize_t len = 0; \
+ int i; \
+ \
+ for (i = 0; i < ARRAY_SIZE(table); i++) { \
+ if (table[i].value & table_key) { \
+ len += sprintf(buf + len, "%s%s", \
+ prefix, table[i].name); \
+ prefix = ", "; \
+ } \
+ } \
+ len += sprintf(buf + len, "\n"); \
+ return len; \
+}
+
+#define ata_bitfield_name_search(title, table) \
+static ssize_t \
+get_ata_##title##_names(u32 table_key, char *buf) \
+{ \
+ ssize_t len = 0; \
+ int i; \
+ \
+ for (i = 0; i < ARRAY_SIZE(table); i++) { \
+ if (table[i].value == table_key) { \
+ len += sprintf(buf + len, "%s", \
+ table[i].name); \
+ break; \
+ } \
+ } \
+ len += sprintf(buf + len, "\n"); \
+ return len; \
+}
+
+static struct {
+ u32 value;
+ char *name;
+} ata_class_names[] = {
+ { ATA_DEV_UNKNOWN, "unknown" },
+ { ATA_DEV_ATA, "ata" },
+ { ATA_DEV_ATA_UNSUP, "ata" },
+ { ATA_DEV_ATAPI, "atapi" },
+ { ATA_DEV_ATAPI_UNSUP, "atapi" },
+ { ATA_DEV_PMP, "pmp" },
+ { ATA_DEV_PMP_UNSUP, "pmp" },
+ { ATA_DEV_SEMB, "semb" },
+ { ATA_DEV_SEMB_UNSUP, "semb" },
+ { ATA_DEV_NONE, "none" }
+};
+ata_bitfield_name_search(class, ata_class_names)
+
+
+static struct {
+ u32 value;
+ char *name;
+} ata_err_names[] = {
+ { AC_ERR_DEV, "DeviceError" },
+ { AC_ERR_HSM, "HostStateMachineError" },
+ { AC_ERR_TIMEOUT, "Timeout" },
+ { AC_ERR_MEDIA, "MediaError" },
+ { AC_ERR_ATA_BUS, "BusError" },
+ { AC_ERR_HOST_BUS, "HostBusError" },
+ { AC_ERR_SYSTEM, "SystemError" },
+ { AC_ERR_INVALID, "InvalidArg" },
+ { AC_ERR_OTHER, "Unknown" },
+ { AC_ERR_NODEV_HINT, "NoDeviceHint" },
+ { AC_ERR_NCQ, "NCQError" }
+};
+ata_bitfield_name_match(err, ata_err_names)
+
+static struct {
+ u32 value;
+ char *name;
+} ata_xfer_names[] = {
+ { XFER_UDMA_7, "XFER_UDMA_7" },
+ { XFER_UDMA_6, "XFER_UDMA_6" },
+ { XFER_UDMA_5, "XFER_UDMA_5" },
+ { XFER_UDMA_4, "XFER_UDMA_4" },
+ { XFER_UDMA_3, "XFER_UDMA_3" },
+ { XFER_UDMA_2, "XFER_UDMA_2" },
+ { XFER_UDMA_1, "XFER_UDMA_1" },
+ { XFER_UDMA_0, "XFER_UDMA_0" },
+ { XFER_MW_DMA_4, "XFER_MW_DMA_4" },
+ { XFER_MW_DMA_3, "XFER_MW_DMA_3" },
+ { XFER_MW_DMA_2, "XFER_MW_DMA_2" },
+ { XFER_MW_DMA_1, "XFER_MW_DMA_1" },
+ { XFER_MW_DMA_0, "XFER_MW_DMA_0" },
+ { XFER_SW_DMA_2, "XFER_SW_DMA_2" },
+ { XFER_SW_DMA_1, "XFER_SW_DMA_1" },
+ { XFER_SW_DMA_0, "XFER_SW_DMA_0" },
+ { XFER_PIO_6, "XFER_PIO_6" },
+ { XFER_PIO_5, "XFER_PIO_5" },
+ { XFER_PIO_4, "XFER_PIO_4" },
+ { XFER_PIO_3, "XFER_PIO_3" },
+ { XFER_PIO_2, "XFER_PIO_2" },
+ { XFER_PIO_1, "XFER_PIO_1" },
+ { XFER_PIO_0, "XFER_PIO_0" },
+ { XFER_PIO_SLOW, "XFER_PIO_SLOW" }
+};
+ata_bitfield_name_match(xfer,ata_xfer_names)
+
+/*
+ * ATA Port attributes
+ */
+#define ata_port_show_simple(field, name, format_string, cast) \
+static ssize_t \
+show_ata_port_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct ata_port *ap = transport_class_to_port(dev); \
+ \
+ return snprintf(buf, 20, format_string, cast ap->field); \
+}
+
+#define ata_port_simple_attr(field, name, format_string, type) \
+ ata_port_show_simple(field, name, format_string, (type)) \
+static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL)
+
+ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
+ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
+
+static DECLARE_TRANSPORT_CLASS(ata_port_class,
+ "ata_port", NULL, NULL, NULL);
+
+static void ata_tport_release(struct device *dev)
+{
+ put_device(dev->parent);
+}
+
+/**
+ * ata_is_port -- check if a struct device represents a ATA port
+ * @dev: device to check
+ *
+ * Returns:
+ * %1 if the device represents a ATA Port, %0 else
+ */
+int ata_is_port(const struct device *dev)
+{
+ return dev->release == ata_tport_release;
+}
+
+static int ata_tport_match(struct attribute_container *cont,
+ struct device *dev)
+{
+ if (!ata_is_port(dev))
+ return 0;
+ return &ata_scsi_transport_template->host_attrs.ac == cont;
+}
+
+/**
+ * ata_tport_delete -- remove ATA PORT
+ * @port: ATA PORT to remove
+ *
+ * Removes the specified ATA PORT. Remove the associated link as well.
+ */
+void ata_tport_delete(struct ata_port *ap)
+{
+ struct device *dev = &ap->tdev;
+
+ ata_tlink_delete(&ap->link);
+
+ transport_remove_device(dev);
+ device_del(dev);
+ transport_destroy_device(dev);
+ put_device(dev);
+}
+
+/** ata_tport_add - initialize a transport ATA port structure
+ *
+ * @parent: parent device
+ * @ap: existing ata_port structure
+ *
+ * Initialize a ATA port structure for sysfs. It will be added to the device
+ * tree below the device specified by @parent which could be a PCI device.
+ *
+ * Returns %0 on success
+ */
+int ata_tport_add(struct device *parent,
+ struct ata_port *ap)
+{
+ int error;
+ struct device *dev = &ap->tdev;
+
+ device_initialize(dev);
+
+ dev->parent = get_device(parent);
+ dev->release = ata_tport_release;
+ dev_set_name(dev, "ata%d", ap->print_id);
+ transport_setup_device(dev);
+ error = device_add(dev);
+ if (error) {
+ goto tport_err;
+ }
+
+ transport_add_device(dev);
+ transport_configure_device(dev);
+
+ error = ata_tlink_add(&ap->link);
+ if (error) {
+ goto tport_link_err;
+ }
+ return 0;
+
+ tport_link_err:
+ transport_remove_device(dev);
+ device_del(dev);
+
+ tport_err:
+ transport_destroy_device(dev);
+ put_device(dev);
+ return error;
+}
+
+
+/*
+ * ATA link attributes
+ */
+
+
+#define ata_link_show_linkspeed(field) \
+static ssize_t \
+show_ata_link_##field(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct ata_link *link = transport_class_to_link(dev); \
+ \
+ return sprintf(buf,"%s\n", sata_spd_string(fls(link->field))); \
+}
+
+#define ata_link_linkspeed_attr(field) \
+ ata_link_show_linkspeed(field) \
+static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
+
+ata_link_linkspeed_attr(hw_sata_spd_limit);
+ata_link_linkspeed_attr(sata_spd_limit);
+ata_link_linkspeed_attr(sata_spd);
+
+
+static DECLARE_TRANSPORT_CLASS(ata_link_class,
+ "ata_link", NULL, NULL, NULL);
+
+static void ata_tlink_release(struct device *dev)
+{
+ put_device(dev->parent);
+}
+
+/**
+ * ata_is_link -- check if a struct device represents a ATA link
+ * @dev: device to check
+ *
+ * Returns:
+ * %1 if the device represents a ATA link, %0 else
+ */
+int ata_is_link(const struct device *dev)
+{
+ return dev->release == ata_tlink_release;
+}
+
+static int ata_tlink_match(struct attribute_container *cont,
+ struct device *dev)
+{
+ struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
+ if (!ata_is_link(dev))
+ return 0;
+ return &i->link_attr_cont.ac == cont;
+}
+
+/**
+ * ata_tlink_delete -- remove ATA LINK
+ * @port: ATA LINK to remove
+ *
+ * Removes the specified ATA LINK. remove associated ATA device(s) as well.
+ */
+void ata_tlink_delete(struct ata_link *link)
+{
+ struct device *dev = &link->tdev;
+ struct ata_device *ata_dev;
+
+ ata_for_each_dev(ata_dev, link, ALL) {
+ ata_tdev_delete(ata_dev);
+ }
+
+ transport_remove_device(dev);
+ device_del(dev);
+ transport_destroy_device(dev);
+ put_device(dev);
+}
+
+/**
+ * ata_tlink_add -- initialize a transport ATA link structure
+ * @link: allocated ata_link structure.
+ *
+ * Initialize an ATA LINK structure for sysfs. It will be added in the
+ * device tree below the ATA PORT it belongs to.
+ *
+ * Returns %0 on success
+ */
+int ata_tlink_add(struct ata_link *link)
+{
+ struct device *dev = &link->tdev;
+ struct ata_port *ap = link->ap;
+ struct ata_device *ata_dev;
+ int error;
+
+ device_initialize(dev);
+ dev->parent = get_device(&ap->tdev);
+ dev->release = ata_tlink_release;
+ if (ata_is_host_link(link))
+ dev_set_name(dev, "link%d", ap->print_id);
+ else
+ dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
+
+ transport_setup_device(dev);
+
+ error = device_add(dev);
+ if (error) {
+ goto tlink_err;
+ }
+
+ transport_add_device(dev);
+ transport_configure_device(dev);
+
+ ata_for_each_dev(ata_dev, link, ALL) {
+ error = ata_tdev_add(ata_dev);
+ if (error) {
+ goto tlink_dev_err;
+ }
+ }
+ return 0;
+ tlink_dev_err:
+ while (--ata_dev >= link->device) {
+ ata_tdev_delete(ata_dev);
+ }
+ transport_remove_device(dev);
+ device_del(dev);
+ tlink_err:
+ transport_destroy_device(dev);
+ put_device(dev);
+ return error;
+}
+
+/*
+ * ATA device attributes
+ */
+
+#define ata_dev_show_class(title, field) \
+static ssize_t \
+show_ata_dev_##field(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct ata_device *ata_dev = transport_class_to_dev(dev); \
+ \
+ return get_ata_##title##_names(ata_dev->field, buf); \
+}
+
+#define ata_dev_attr(title, field) \
+ ata_dev_show_class(title, field) \
+static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
+
+ata_dev_attr(class, class);
+ata_dev_attr(xfer, pio_mode);
+ata_dev_attr(xfer, dma_mode);
+ata_dev_attr(xfer, xfer_mode);
+
+
+#define ata_dev_show_simple(field, format_string, cast) \
+static ssize_t \
+show_ata_dev_##field(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct ata_device *ata_dev = transport_class_to_dev(dev); \
+ \
+ return snprintf(buf, 20, format_string, cast ata_dev->field); \
+}
+
+#define ata_dev_simple_attr(field, format_string, type) \
+ ata_dev_show_simple(field, format_string, (type)) \
+static DEVICE_ATTR(field, S_IRUGO, \
+ show_ata_dev_##field, NULL)
+
+ata_dev_simple_attr(spdn_cnt, "%d\n", int);
+
+struct ata_show_ering_arg {
+ char* buf;
+ int written;
+};
+
+static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
+{
+ struct ata_show_ering_arg* arg = void_arg;
+ struct timespec time;
+
+ jiffies_to_timespec(ent->timestamp,&time);
+ arg->written += sprintf(arg->buf + arg->written,
+ "[%5lu.%06lu]",
+ time.tv_sec, time.tv_nsec);
+ arg->written += get_ata_err_names(ent->err_mask,
+ arg->buf + arg->written);
+ return 0;
+}
+
+static ssize_t
+show_ata_dev_ering(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ata_device *ata_dev = transport_class_to_dev(dev);
+ struct ata_show_ering_arg arg = { buf, 0 };
+
+ ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
+ return arg.written;
+}
+
+
+static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
+
+static ssize_t
+show_ata_dev_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ata_device *ata_dev = transport_class_to_dev(dev);
+ int written = 0, i = 0;
+
+ if (ata_dev->class == ATA_DEV_PMP)
+ return 0;
+ for(i=0;i<ATA_ID_WORDS;i++) {
+ written += snprintf(buf+written, 20, "%04x%c",
+ ata_dev->id[i],
+ ((i+1) & 7) ? ' ' : '\n');
+ }
+ return written;
+}
+
+static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
+
+static ssize_t
+show_ata_dev_gscr(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ata_device *ata_dev = transport_class_to_dev(dev);
+ int written = 0, i = 0;
+
+ if (ata_dev->class != ATA_DEV_PMP)
+ return 0;
+ for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
+ written += snprintf(buf+written, 20, "%08x%c",
+ ata_dev->gscr[i],
+ ((i+1) & 3) ? ' ' : '\n');
+ }
+ if (SATA_PMP_GSCR_DWORDS & 3)
+ buf[written-1] = '\n';
+ return written;
+}
+
+static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
+
+static DECLARE_TRANSPORT_CLASS(ata_dev_class,
+ "ata_device", NULL, NULL, NULL);
+
+static void ata_tdev_release(struct device *dev)
+{
+ put_device(dev->parent);
+}
+
+/**
+ * ata_is_ata_dev -- check if a struct device represents a ATA device
+ * @dev: device to check
+ *
+ * Returns:
+ * %1 if the device represents a ATA device, %0 else
+ */
+int ata_is_ata_dev(const struct device *dev)
+{
+ return dev->release == ata_tdev_release;
+}
+
+static int ata_tdev_match(struct attribute_container *cont,
+ struct device *dev)
+{
+ struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
+ if (!ata_is_ata_dev(dev))
+ return 0;
+ return &i->dev_attr_cont.ac == cont;
+}
+
+/**
+ * ata_tdev_free -- free a ATA LINK
+ * @dev: ATA PHY to free
+ *
+ * Frees the specified ATA PHY.
+ *
+ * Note:
+ * This function must only be called on a PHY that has not
+ * successfully been added using ata_tdev_add().
+ */
+static void ata_tdev_free(struct ata_device *dev)
+{
+ transport_destroy_device(&dev->tdev);
+ put_device(&dev->tdev);
+}
+
+/**
+ * ata_tdev_delete -- remove ATA device
+ * @port: ATA PORT to remove
+ *
+ * Removes the specified ATA device.
+ */
+static void ata_tdev_delete(struct ata_device *ata_dev)
+{
+ struct device *dev = &ata_dev->tdev;
+
+ transport_remove_device(dev);
+ device_del(dev);
+ ata_tdev_free(ata_dev);
+}
+
+
+/**
+ * ata_tdev_add -- initialize a transport ATA device structure.
+ * @ata_dev: ata_dev structure.
+ *
+ * Initialize an ATA device structure for sysfs. It will be added in the
+ * device tree below the ATA LINK device it belongs to.
+ *
+ * Returns %0 on success
+ */
+static int ata_tdev_add(struct ata_device *ata_dev)
+{
+ struct device *dev = &ata_dev->tdev;
+ struct ata_link *link = ata_dev->link;
+ struct ata_port *ap = link->ap;
+ int error;
+
+ device_initialize(dev);
+ dev->parent = get_device(&link->tdev);
+ dev->release = ata_tdev_release;
+ if (ata_is_host_link(link))
+ dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
+ else
+ dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
+
+ transport_setup_device(dev);
+ error = device_add(dev);
+ if (error) {
+ ata_tdev_free(ata_dev);
+ return error;
+ }
+
+ transport_add_device(dev);
+ transport_configure_device(dev);
+ return 0;
+}
+
+
+/*
+ * Setup / Teardown code
+ */
+
+#define SETUP_TEMPLATE(attrb, field, perm, test) \
+ i->private_##attrb[count] = dev_attr_##field; \
+ i->private_##attrb[count].attr.mode = perm; \
+ i->attrb[count] = &i->private_##attrb[count]; \
+ if (test) \
+ count++
+
+#define SETUP_LINK_ATTRIBUTE(field) \
+ SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
+
+#define SETUP_PORT_ATTRIBUTE(field) \
+ SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
+
+#define SETUP_DEV_ATTRIBUTE(field) \
+ SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
+
+/**
+ * ata_attach_transport -- instantiate ATA transport template
+ */
+struct scsi_transport_template *ata_attach_transport(void)
+{
+ struct ata_internal *i;
+ int count;
+
+ i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
+ if (!i)
+ return NULL;
+
+ i->t.eh_strategy_handler = ata_scsi_error;
+ i->t.eh_timed_out = ata_scsi_timed_out;
+ i->t.user_scan = ata_scsi_user_scan;
+
+ i->t.host_attrs.ac.attrs = &i->port_attrs[0];
+ i->t.host_attrs.ac.class = &ata_port_class.class;
+ i->t.host_attrs.ac.match = ata_tport_match;
+ transport_container_register(&i->t.host_attrs);
+
+ i->link_attr_cont.ac.class = &ata_link_class.class;
+ i->link_attr_cont.ac.attrs = &i->link_attrs[0];
+ i->link_attr_cont.ac.match = ata_tlink_match;
+ transport_container_register(&i->link_attr_cont);
+
+ i->dev_attr_cont.ac.class = &ata_dev_class.class;
+ i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
+ i->dev_attr_cont.ac.match = ata_tdev_match;
+ transport_container_register(&i->dev_attr_cont);
+
+ count = 0;
+ SETUP_PORT_ATTRIBUTE(nr_pmp_links);
+ SETUP_PORT_ATTRIBUTE(idle_irq);
+ BUG_ON(count > ATA_PORT_ATTRS);
+ i->port_attrs[count] = NULL;
+
+ count = 0;
+ SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
+ SETUP_LINK_ATTRIBUTE(sata_spd_limit);
+ SETUP_LINK_ATTRIBUTE(sata_spd);
+ BUG_ON(count > ATA_LINK_ATTRS);
+ i->link_attrs[count] = NULL;
+
+ count = 0;
+ SETUP_DEV_ATTRIBUTE(class);
+ SETUP_DEV_ATTRIBUTE(pio_mode);
+ SETUP_DEV_ATTRIBUTE(dma_mode);
+ SETUP_DEV_ATTRIBUTE(xfer_mode);
+ SETUP_DEV_ATTRIBUTE(spdn_cnt);
+ SETUP_DEV_ATTRIBUTE(ering);
+ SETUP_DEV_ATTRIBUTE(id);
+ SETUP_DEV_ATTRIBUTE(gscr);
+ BUG_ON(count > ATA_DEV_ATTRS);
+ i->dev_attrs[count] = NULL;
+
+ return &i->t;
+}
+
+/**
+ * ata_release_transport -- release ATA transport template instance
+ * @t: transport template instance
+ */
+void ata_release_transport(struct scsi_transport_template *t)
+{
+ struct ata_internal *i = to_ata_internal(t);
+
+ transport_container_unregister(&i->t.host_attrs);
+ transport_container_unregister(&i->link_attr_cont);
+ transport_container_unregister(&i->dev_attr_cont);
+
+ kfree(i);
+}
+
+__init int libata_transport_init(void)
+{
+ int error;
+
+ error = transport_class_register(&ata_link_class);
+ if (error)
+ goto out_unregister_transport;
+ error = transport_class_register(&ata_port_class);
+ if (error)
+ goto out_unregister_link;
+ error = transport_class_register(&ata_dev_class);
+ if (error)
+ goto out_unregister_port;
+ return 0;
+
+ out_unregister_port:
+ transport_class_unregister(&ata_port_class);
+ out_unregister_link:
+ transport_class_unregister(&ata_link_class);
+ out_unregister_transport:
+ return error;
+
+}
+
+void __exit libata_transport_exit(void)
+{
+ transport_class_unregister(&ata_link_class);
+ transport_class_unregister(&ata_port_class);
+ transport_class_unregister(&ata_dev_class);
+}
diff --git a/drivers/ata/libata-transport.h b/drivers/ata/libata-transport.h
new file mode 100644
index 000000000000..2820cf864f11
--- /dev/null
+++ b/drivers/ata/libata-transport.h
@@ -0,0 +1,18 @@
+#ifndef _LIBATA_TRANSPORT_H
+#define _LIBATA_TRANSPORT_H
+
+
+extern struct scsi_transport_template *ata_scsi_transport_template;
+
+int ata_tlink_add(struct ata_link *link);
+void ata_tlink_delete(struct ata_link *link);
+
+int ata_tport_add(struct device *parent, struct ata_port *ap);
+void ata_tport_delete(struct ata_port *ap);
+
+struct scsi_transport_template *ata_attach_transport(void);
+void ata_release_transport(struct scsi_transport_template *t);
+
+__init int libata_transport_init(void);
+void __exit libata_transport_exit(void);
+#endif
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 9ce1ecc63e39..142102b94df5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -102,6 +102,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct ata_port *ata_port_alloc(struct ata_host *host);
extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy);
extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
+extern const char *sata_spd_string(unsigned int spd);
/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
@@ -137,6 +138,9 @@ extern void ata_scsi_hotplug(struct work_struct *work);
extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap);
+extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
+ unsigned int id, unsigned int lun);
+
/* libata-eh.c */
extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
@@ -164,6 +168,9 @@ extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_postreset_fn_t postreset,
struct ata_link **r_failed_disk);
extern void ata_eh_finish(struct ata_port *ap);
+extern int ata_ering_map(struct ata_ering *ering,
+ int (*map_fn)(struct ata_ering_entry *, void *),
+ void *arg);
/* libata-pmp.c */
#ifdef CONFIG_SATA_PMP
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index ba43f0f8c880..2215632e4b31 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -74,7 +74,8 @@ static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
/* Odd numbered device ids are the units with enable bits (the -R cards) */
- if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
+ if ((pdev->device & 1) &&
+ !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
return ata_sff_prereset(link, deadline);
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 9cae65de750e..be7b1b21e777 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1588,7 +1588,7 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev)
host->ports[0]->ioaddr.ctl_addr = (void *)res->start;
if (peripheral_request_list(atapi_io_port, "atapi-io-port")) {
- dev_err(&pdev->dev, "Requesting Peripherals faild\n");
+ dev_err(&pdev->dev, "Requesting Peripherals failed\n");
return -EFAULT;
}
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 5e659885de16..ac8d7d97e408 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -417,6 +417,8 @@ static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
tf->lbam,
tf->lbah);
}
+
+ ata_wait_idle(ap);
}
static int via_port_start(struct ata_port *ap)
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 7325f77480dc..1440dc0af242 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1137,17 +1137,13 @@ static void sata_fsl_host_intr(struct ata_port *ap)
ioread32(hcr_base + CE));
for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
- if (done_mask & (1 << i)) {
- qc = ata_qc_from_tag(ap, i);
- if (qc) {
- ata_qc_complete(qc);
- }
+ if (done_mask & (1 << i))
DPRINTK
("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
i, ioread32(hcr_base + CC),
ioread32(hcr_base + CA));
- }
}
+ ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
return;
} else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) {
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 81982594a014..bf74a36d3cc3 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2284,7 +2284,7 @@ static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
}
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_sff_queue_pio_task(ap, 0);
+ ata_sff_queue_pio_task(link, 0);
return 0;
}
@@ -2743,18 +2743,11 @@ static void mv_err_intr(struct ata_port *ap)
}
}
-static void mv_process_crpb_response(struct ata_port *ap,
+static bool mv_process_crpb_response(struct ata_port *ap,
struct mv_crpb *response, unsigned int tag, int ncq_enabled)
{
u8 ata_status;
u16 edma_status = le16_to_cpu(response->flags);
- struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
-
- if (unlikely(!qc)) {
- ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
- __func__, tag);
- return;
- }
/*
* edma_status from a response queue entry:
@@ -2768,13 +2761,14 @@ static void mv_process_crpb_response(struct ata_port *ap,
* Error will be seen/handled by
* mv_err_intr(). So do nothing at all here.
*/
- return;
+ return false;
}
}
ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
if (!ac_err_mask(ata_status))
- ata_qc_complete(qc);
+ return true;
/* else: leave it for mv_err_intr() */
+ return false;
}
static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
@@ -2783,6 +2777,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
struct mv_host_priv *hpriv = ap->host->private_data;
u32 in_index;
bool work_done = false;
+ u32 done_mask = 0;
int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN);
/* Get the hardware queue position index */
@@ -2803,15 +2798,19 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
/* Gen II/IIE: get command tag from CRPB entry */
tag = le16_to_cpu(response->id) & 0x1f;
}
- mv_process_crpb_response(ap, response, tag, ncq_enabled);
+ if (mv_process_crpb_response(ap, response, tag, ncq_enabled))
+ done_mask |= 1 << tag;
work_done = true;
}
- /* Update the software queue position index in hardware */
- if (work_done)
+ if (work_done) {
+ ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
+
+ /* Update the software queue position index in hardware */
writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
(pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT),
port_mmio + EDMA_RSP_Q_OUT_PTR);
+ }
}
static void mv_port_intr(struct ata_port *ap, u32 port_cause)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index cb89ef8d99d9..7254e255fd78 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -873,29 +873,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
ata_port_freeze(ap);
else
ata_port_abort(ap);
- return 1;
+ return -1;
}
- if (likely(flags & NV_CPB_RESP_DONE)) {
- struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
- VPRINTK("CPB flags done, flags=0x%x\n", flags);
- if (likely(qc)) {
- DPRINTK("Completing qc from tag %d\n", cpb_num);
- ata_qc_complete(qc);
- } else {
- struct ata_eh_info *ehi = &ap->link.eh_info;
- /* Notifier bits set without a command may indicate the drive
- is misbehaving. Raise host state machine violation on this
- condition. */
- ata_port_printk(ap, KERN_ERR,
- "notifier for tag %d with no cmd?\n",
- cpb_num);
- ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_RESET;
- ata_port_freeze(ap);
- return 1;
- }
- }
+ if (likely(flags & NV_CPB_RESP_DONE))
+ return 1;
return 0;
}
@@ -1018,6 +1000,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
NV_ADMA_STAT_CPBERR |
NV_ADMA_STAT_CMD_COMPLETE)) {
u32 check_commands = notifier_clears[i];
+ u32 done_mask = 0;
int pos, rc;
if (status & NV_ADMA_STAT_CPBERR) {
@@ -1034,10 +1017,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
pos--;
rc = nv_adma_check_cpb(ap, pos,
notifier_error & (1 << pos));
- if (unlikely(rc))
+ if (rc > 0)
+ done_mask |= 1 << pos;
+ else if (unlikely(rc < 0))
check_commands = 0;
check_commands &= ~(1 << pos);
}
+ ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
}
}
@@ -2132,7 +2118,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
struct ata_eh_info *ehi = &ap->link.eh_info;
u32 sactive;
u32 done_mask;
- int i;
u8 host_stat;
u8 lack_dhfis = 0;
@@ -2152,27 +2137,11 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
sactive = readl(pp->sactive_block);
done_mask = pp->qc_active ^ sactive;
- if (unlikely(done_mask & sactive)) {
- ata_ehi_clear_desc(ehi);
- ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition"
- "(%08x->%08x)", pp->qc_active, sactive);
- ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_RESET;
- return -EINVAL;
- }
- for (i = 0; i < ATA_MAX_QUEUE; i++) {
- if (!(done_mask & (1 << i)))
- continue;
-
- qc = ata_qc_from_tag(ap, i);
- if (qc) {
- ata_qc_complete(qc);
- pp->qc_active &= ~(1 << i);
- pp->dhfis_bits &= ~(1 << i);
- pp->dmafis_bits &= ~(1 << i);
- pp->sdbfis_bits |= (1 << i);
- }
- }
+ pp->qc_active &= ~done_mask;
+ pp->dhfis_bits &= ~done_mask;
+ pp->dmafis_bits &= ~done_mask;
+ pp->sdbfis_bits |= done_mask;
+ ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
if (!ap->qc_active) {
DPRINTK("over\n");
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 8717809787fb..5d86bb803e94 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -444,8 +444,8 @@ static inline void fs_kfree_skb (struct sk_buff * skb)
#define ROUND_NEAREST 3
/********** make rate (not quite as much fun as Horizon) **********/
-static unsigned int make_rate (unsigned int rate, int r,
- u16 * bits, unsigned int * actual)
+static int make_rate(unsigned int rate, int r,
+ u16 *bits, unsigned int *actual)
{
unsigned char exp = -1; /* hush gcc */
unsigned int man = -1; /* hush gcc */
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index ee9ddeb53417..8b358d7d958f 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -220,7 +220,7 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
dev->ffL.tcq_rd += 2;
if (dev->ffL.tcq_rd > dev->ffL.tcq_ed)
- dev->ffL.tcq_rd = dev->ffL.tcq_st;
+ dev->ffL.tcq_rd = dev->ffL.tcq_st;
if (dev->ffL.tcq_rd == dev->host_tcq_wr)
return 0xFFFF;
desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index eb1b7fa20dce..33c270a64db7 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -440,22 +440,6 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev)
}
}
-#ifdef CONFIG_SYSFS_DEPRECATED
-static int make_deprecated_bus_links(struct device *dev)
-{
- return sysfs_create_link(&dev->kobj,
- &dev->bus->p->subsys.kobj, "bus");
-}
-
-static void remove_deprecated_bus_links(struct device *dev)
-{
- sysfs_remove_link(&dev->kobj, "bus");
-}
-#else
-static inline int make_deprecated_bus_links(struct device *dev) { return 0; }
-static inline void remove_deprecated_bus_links(struct device *dev) { }
-#endif
-
/**
* bus_add_device - add device to bus
* @dev: device being added
@@ -482,15 +466,10 @@ int bus_add_device(struct device *dev)
&dev->bus->p->subsys.kobj, "subsystem");
if (error)
goto out_subsys;
- error = make_deprecated_bus_links(dev);
- if (error)
- goto out_deprecated;
klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
}
return 0;
-out_deprecated:
- sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys:
sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id:
@@ -530,7 +509,6 @@ void bus_remove_device(struct device *dev)
{
if (dev->bus) {
sysfs_remove_link(&dev->kobj, "subsystem");
- remove_deprecated_bus_links(dev);
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8e231d05b400..1078969889fd 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -276,25 +276,6 @@ void class_destroy(struct class *cls)
class_unregister(cls);
}
-#ifdef CONFIG_SYSFS_DEPRECATED
-char *make_class_name(const char *name, struct kobject *kobj)
-{
- char *class_name;
- int size;
-
- size = strlen(name) + strlen(kobject_name(kobj)) + 2;
-
- class_name = kmalloc(size, GFP_KERNEL);
- if (!class_name)
- return NULL;
-
- strcpy(class_name, name);
- strcat(class_name, ":");
- strcat(class_name, kobject_name(kobj));
- return class_name;
-}
-#endif
-
/**
* class_dev_iter_init - initialize class device iterator
* @iter: class iterator to initialize
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d1b2c9adc271..8b311ab9250b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -203,37 +203,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->driver)
add_uevent_var(env, "DRIVER=%s", dev->driver->name);
-#ifdef CONFIG_SYSFS_DEPRECATED
- if (dev->class) {
- struct device *parent = dev->parent;
-
- /* find first bus device in parent chain */
- while (parent && !parent->bus)
- parent = parent->parent;
- if (parent && parent->bus) {
- const char *path;
-
- path = kobject_get_path(&parent->kobj, GFP_KERNEL);
- if (path) {
- add_uevent_var(env, "PHYSDEVPATH=%s", path);
- kfree(path);
- }
-
- add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
-
- if (parent->driver)
- add_uevent_var(env, "PHYSDEVDRIVER=%s",
- parent->driver->name);
- }
- } else if (dev->bus) {
- add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
-
- if (dev->driver)
- add_uevent_var(env, "PHYSDEVDRIVER=%s",
- dev->driver->name);
- }
-#endif
-
/* have the bus specific function add its stuff */
if (dev->bus && dev->bus->uevent) {
retval = dev->bus->uevent(dev, env);
@@ -251,7 +220,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
__func__, retval);
}
- /* have the device type specific fuction add its stuff */
+ /* have the device type specific function add its stuff */
if (dev->type && dev->type->uevent) {
retval = dev->type->uevent(dev, env);
if (retval)
@@ -578,24 +547,6 @@ void device_initialize(struct device *dev)
set_dev_node(dev, -1);
}
-#ifdef CONFIG_SYSFS_DEPRECATED
-static struct kobject *get_device_parent(struct device *dev,
- struct device *parent)
-{
- /* class devices without a parent live in /sys/class/<classname>/ */
- if (dev->class && (!parent || parent->class != dev->class))
- return &dev->class->p->class_subsys.kobj;
- /* all other devices keep their parent */
- else if (parent)
- return &parent->kobj;
-
- return NULL;
-}
-
-static inline void cleanup_device_parent(struct device *dev) {}
-static inline void cleanup_glue_dir(struct device *dev,
- struct kobject *glue_dir) {}
-#else
static struct kobject *virtual_device_parent(struct device *dev)
{
static struct kobject *virtual_dir = NULL;
@@ -666,6 +617,14 @@ static struct kobject *get_device_parent(struct device *dev,
struct kobject *parent_kobj;
struct kobject *k;
+#ifdef CONFIG_SYSFS_DEPRECATED
+ /* block disks show up in /sys/block */
+ if (dev->class == &block_class) {
+ if (parent && parent->class == &block_class)
+ return &parent->kobj;
+ return &block_class.p->class_subsys.kobj;
+ }
+#endif
/*
* If we have no parent, we live in "virtual".
* Class-devices with a non class-device as parent, live
@@ -719,7 +678,6 @@ static void cleanup_device_parent(struct device *dev)
{
cleanup_glue_dir(dev, dev->kobj.parent);
}
-#endif
static void setup_parent(struct device *dev, struct device *parent)
{
@@ -742,70 +700,29 @@ static int device_add_class_symlinks(struct device *dev)
if (error)
goto out;
-#ifdef CONFIG_SYSFS_DEPRECATED
- /* stacked class devices need a symlink in the class directory */
- if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
- device_is_not_partition(dev)) {
- error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
- &dev->kobj, dev_name(dev));
- if (error)
- goto out_subsys;
- }
-
if (dev->parent && device_is_not_partition(dev)) {
- struct device *parent = dev->parent;
- char *class_name;
-
- /*
- * stacked class devices have the 'device' link
- * pointing to the bus device instead of the parent
- */
- while (parent->class && !parent->bus && parent->parent)
- parent = parent->parent;
-
- error = sysfs_create_link(&dev->kobj,
- &parent->kobj,
+ error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
"device");
if (error)
- goto out_busid;
-
- class_name = make_class_name(dev->class->name,
- &dev->kobj);
- if (class_name)
- error = sysfs_create_link(&dev->parent->kobj,
- &dev->kobj, class_name);
- kfree(class_name);
- if (error)
- goto out_device;
+ goto out_subsys;
}
- return 0;
-out_device:
- if (dev->parent && device_is_not_partition(dev))
- sysfs_remove_link(&dev->kobj, "device");
-out_busid:
- if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
- device_is_not_partition(dev))
- sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
- dev_name(dev));
-#else
+#ifdef CONFIG_SYSFS_DEPRECATED
+ /* /sys/block has directories and does not need symlinks */
+ if (dev->class == &block_class)
+ return 0;
+#endif
+
/* link in the class directory pointing to the device */
error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, dev_name(dev));
if (error)
- goto out_subsys;
+ goto out_device;
- if (dev->parent && device_is_not_partition(dev)) {
- error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
- "device");
- if (error)
- goto out_busid;
- }
return 0;
-out_busid:
- sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
-#endif
+out_device:
+ sysfs_remove_link(&dev->kobj, "device");
out_subsys:
sysfs_remove_link(&dev->kobj, "subsystem");
@@ -818,30 +735,14 @@ static void device_remove_class_symlinks(struct device *dev)
if (!dev->class)
return;
-#ifdef CONFIG_SYSFS_DEPRECATED
- if (dev->parent && device_is_not_partition(dev)) {
- char *class_name;
-
- class_name = make_class_name(dev->class->name, &dev->kobj);
- if (class_name) {
- sysfs_remove_link(&dev->parent->kobj, class_name);
- kfree(class_name);
- }
- sysfs_remove_link(&dev->kobj, "device");
- }
-
- if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
- device_is_not_partition(dev))
- sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj,
- dev_name(dev));
-#else
if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device");
-
- sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
-#endif
-
sysfs_remove_link(&dev->kobj, "subsystem");
+#ifdef CONFIG_SYSFS_DEPRECATED
+ if (dev->class == &block_class)
+ return;
+#endif
+ sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev));
}
/**
@@ -1613,41 +1514,23 @@ int device_rename(struct device *dev, const char *new_name)
pr_debug("device: '%s': %s: renaming to '%s'\n", dev_name(dev),
__func__, new_name);
-#ifdef CONFIG_SYSFS_DEPRECATED
- if ((dev->class) && (dev->parent))
- old_class_name = make_class_name(dev->class->name, &dev->kobj);
-#endif
-
old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
-#ifndef CONFIG_SYSFS_DEPRECATED
if (dev->class) {
error = sysfs_rename_link(&dev->class->p->class_subsys.kobj,
&dev->kobj, old_device_name, new_name);
if (error)
goto out;
}
-#endif
+
error = kobject_rename(&dev->kobj, new_name);
if (error)
goto out;
-#ifdef CONFIG_SYSFS_DEPRECATED
- if (old_class_name) {
- new_class_name = make_class_name(dev->class->name, &dev->kobj);
- if (new_class_name) {
- error = sysfs_rename_link(&dev->parent->kobj,
- &dev->kobj,
- old_class_name,
- new_class_name);
- }
- }
-#endif
-
out:
put_device(dev);
@@ -1664,40 +1547,13 @@ static int device_move_class_links(struct device *dev,
struct device *new_parent)
{
int error = 0;
-#ifdef CONFIG_SYSFS_DEPRECATED
- char *class_name;
- class_name = make_class_name(dev->class->name, &dev->kobj);
- if (!class_name) {
- error = -ENOMEM;
- goto out;
- }
- if (old_parent) {
- sysfs_remove_link(&dev->kobj, "device");
- sysfs_remove_link(&old_parent->kobj, class_name);
- }
- if (new_parent) {
- error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
- "device");
- if (error)
- goto out;
- error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
- class_name);
- if (error)
- sysfs_remove_link(&dev->kobj, "device");
- } else
- error = 0;
-out:
- kfree(class_name);
- return error;
-#else
if (old_parent)
sysfs_remove_link(&dev->kobj, "device");
if (new_parent)
error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
"device");
return error;
-#endif
}
/**
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c6c933f58102..a01abf9ebf7b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -488,12 +488,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
* if the probe was successful, and make sure any forced probes of
* new devices fail.
*/
- spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
+ spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
drv->probe = NULL;
if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
retval = -ENODEV;
drv->driver.probe = platform_drv_probe_fail;
- spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
+ spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
if (code != retval)
platform_driver_unregister(drv);
@@ -976,6 +976,41 @@ struct bus_type platform_bus_type = {
};
EXPORT_SYMBOL_GPL(platform_bus_type);
+/**
+ * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
+ *
+ * This function can be used by platform code to get the current
+ * set of dev_pm_ops functions used by the platform_bus_type.
+ */
+const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
+{
+ return platform_bus_type.pm;
+}
+
+/**
+ * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
+ *
+ * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
+ *
+ * Platform code can override the dev_pm_ops methods of
+ * platform_bus_type by using this function. It is expected that
+ * platform code will first do a platform_bus_get_pm_ops(), then
+ * kmemdup it, then customize selected methods and pass a pointer to
+ * the new struct dev_pm_ops to this function.
+ *
+ * Since platform-specific code is customizing methods for *all*
+ * devices (not just platform-specific devices) it is expected that
+ * any custom overrides of these functions will keep existing behavior
+ * and simply extend it. For example, any customization of the
+ * runtime PM methods should continue to call the pm_generic_*
+ * functions as the default ones do in addition to the
+ * platform-specific behavior.
+ */
+void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
+{
+ platform_bus_type.pm = pm;
+}
+
int __init platform_bus_init(void)
{
int error;
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 4b29d4981253..81f2c84697f4 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -46,7 +46,7 @@ int pm_generic_runtime_suspend(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret;
- ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL;
+ ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
return ret;
}
@@ -65,7 +65,7 @@ int pm_generic_runtime_resume(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int ret;
- ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL;
+ ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
return ret;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 5419a49ff135..276d5a701dc3 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -59,6 +59,7 @@ void device_pm_init(struct device *dev)
{
dev->power.status = DPM_ON;
init_completion(&dev->power.completion);
+ complete_all(&dev->power.completion);
dev->power.wakeup_count = 0;
pm_runtime_init(dev);
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 4e2c367fec11..723c4c6983c4 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -36,7 +36,7 @@
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/reboot.h>
@@ -54,6 +54,7 @@
#define DAC960_GAM_MINOR 252
+static DEFINE_MUTEX(DAC960_mutex);
static DAC960_Controller_T *DAC960_Controllers[DAC960_MaxControllers];
static int DAC960_ControllerCount;
static struct proc_dir_entry *DAC960_ProcDirectoryEntry;
@@ -81,7 +82,7 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode)
int drive_nr = (long)disk->private_data;
int ret = -ENXIO;
- lock_kernel();
+ mutex_lock(&DAC960_mutex);
if (p->FirmwareType == DAC960_V1_Controller) {
if (p->V1.LogicalDriveInformation[drive_nr].
LogicalDriveState == DAC960_V1_LogicalDrive_Offline)
@@ -99,7 +100,7 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode)
goto out;
ret = 0;
out:
- unlock_kernel();
+ mutex_unlock(&DAC960_mutex);
return ret;
}
@@ -6625,7 +6626,7 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
long ErrorCode = 0;
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
- lock_kernel();
+ mutex_lock(&DAC960_mutex);
switch (Request)
{
case DAC960_IOCTL_GET_CONTROLLER_COUNT:
@@ -7056,13 +7057,14 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
default:
ErrorCode = -ENOTTY;
}
- unlock_kernel();
+ mutex_unlock(&DAC960_mutex);
return ErrorCode;
}
static const struct file_operations DAC960_gam_fops = {
.owner = THIS_MODULE,
- .unlocked_ioctl = DAC960_gam_ioctl
+ .unlocked_ioctl = DAC960_gam_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice DAC960_gam_dev = {
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 76f114f0bba3..4b852c962266 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -60,7 +60,7 @@
#include <linux/hdreg.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/amifdreg.h>
#include <linux/amifd.h>
#include <linux/buffer_head.h>
@@ -109,6 +109,7 @@
#define FD_HD_3 0x55555555 /* high-density 3.5" (1760K) drive */
#define FD_DD_5 0xaaaaaaaa /* double-density 5.25" (440K) drive */
+static DEFINE_MUTEX(amiflop_mutex);
static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it doesn't identify */
module_param(fd_def_df0, ulong, 0);
@@ -1506,9 +1507,9 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&amiflop_mutex);
ret = fd_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&amiflop_mutex);
return ret;
}
@@ -1555,11 +1556,11 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
int old_dev;
unsigned long flags;
- lock_kernel();
+ mutex_lock(&amiflop_mutex);
old_dev = fd_device[drive];
if (fd_ref[drive] && old_dev != system) {
- unlock_kernel();
+ mutex_unlock(&amiflop_mutex);
return -EBUSY;
}
@@ -1575,7 +1576,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
rel_fdc();
if (wrprot) {
- unlock_kernel();
+ mutex_unlock(&amiflop_mutex);
return -EROFS;
}
}
@@ -1594,7 +1595,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
unit[drive].type->name, data_types[system].name);
- unlock_kernel();
+ mutex_unlock(&amiflop_mutex);
return 0;
}
@@ -1603,7 +1604,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
struct amiga_floppy_struct *p = disk->private_data;
int drive = p - unit;
- lock_kernel();
+ mutex_lock(&amiflop_mutex);
if (unit[drive].dirty == 1) {
del_timer (flush_track_timer + drive);
non_int_flush_track (drive);
@@ -1617,7 +1618,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
/* the mod_use counter is handled this way */
floppy_off (drive | 0x40000000);
#endif
- unlock_kernel();
+ mutex_unlock(&amiflop_mutex);
return 0;
}
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index a946929735a5..f21c237a9e5e 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -12,9 +12,10 @@
#include <linux/slab.h>
#include <linux/genhd.h>
#include <linux/netdevice.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include "aoe.h"
+static DEFINE_MUTEX(aoeblk_mutex);
static struct kmem_cache *buf_pool_cache;
static ssize_t aoedisk_show_state(struct device *dev,
@@ -125,16 +126,16 @@ aoeblk_open(struct block_device *bdev, fmode_t mode)
struct aoedev *d = bdev->bd_disk->private_data;
ulong flags;
- lock_kernel();
+ mutex_lock(&aoeblk_mutex);
spin_lock_irqsave(&d->lock, flags);
if (d->flags & DEVFL_UP) {
d->nopen++;
spin_unlock_irqrestore(&d->lock, flags);
- unlock_kernel();
+ mutex_unlock(&aoeblk_mutex);
return 0;
}
spin_unlock_irqrestore(&d->lock, flags);
- unlock_kernel();
+ mutex_unlock(&aoeblk_mutex);
return -ENODEV;
}
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 4a1b9e7464aa..3af9f7e83e67 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -9,7 +9,7 @@
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/skbuff.h>
#include "aoe.h"
@@ -37,6 +37,7 @@ struct ErrMsg {
char *msg;
};
+static DEFINE_MUTEX(aoechr_mutex);
static struct ErrMsg emsgs[NMSG];
static int emsgs_head_idx, emsgs_tail_idx;
static struct completion emsgs_comp;
@@ -183,16 +184,16 @@ aoechr_open(struct inode *inode, struct file *filp)
{
int n, i;
- lock_kernel();
+ mutex_lock(&aoechr_mutex);
n = iminor(inode);
filp->private_data = (void *) (unsigned long) n;
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
if (chardevs[i].minor == n) {
- unlock_kernel();
+ mutex_unlock(&aoechr_mutex);
return 0;
}
- unlock_kernel();
+ mutex_unlock(&aoechr_mutex);
return -EINVAL;
}
@@ -265,6 +266,7 @@ static const struct file_operations aoe_fops = {
.open = aoechr_open,
.release = aoechr_rel,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static char *aoe_devnode(struct device *dev, mode_t *mode)
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 5674bd01d96d..b1e5c624b110 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -987,8 +987,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
}
sysminor = SYSMINOR(aoemajor, h->minor);
- if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
- printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
+ if (h->minor >= NPERSHELF) {
+ printk(KERN_INFO "aoe: e%ld.%d: AoE minor address too large\n",
+ aoemajor, (int) h->minor);
+ return;
+ } else if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
+ printk(KERN_INFO "aoe: e%ld.%d: AoE major address too large\n",
aoemajor, (int) h->minor);
return;
}
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index aceb96476524..8c021bb7a991 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -67,7 +67,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/atafd.h>
#include <asm/atafdreg.h>
@@ -79,6 +79,7 @@
#undef DEBUG
+static DEFINE_MUTEX(ataflop_mutex);
static struct request_queue *floppy_queue;
static struct request *fd_request;
@@ -1671,9 +1672,9 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&ataflop_mutex);
ret = fd_locked_ioctl(bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ataflop_mutex);
return ret;
}
@@ -1854,9 +1855,9 @@ static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&ataflop_mutex);
ret = floppy_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&ataflop_mutex);
return ret;
}
@@ -1864,14 +1865,14 @@ static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
static int floppy_release(struct gendisk *disk, fmode_t mode)
{
struct atari_floppy_struct *p = disk->private_data;
- lock_kernel();
+ mutex_lock(&ataflop_mutex);
if (p->ref < 0)
p->ref = 0;
else if (!p->ref--) {
printk(KERN_ERR "floppy_release with fd_ref == 0");
p->ref = 0;
}
- unlock_kernel();
+ mutex_unlock(&ataflop_mutex);
return 0;
}
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 1c7f63792ff8..b7f51e4594f8 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -15,7 +15,7 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/buffer_head.h> /* invalidate_bh_lrus() */
#include <linux/slab.h>
@@ -55,6 +55,7 @@ struct brd_device {
/*
* Look up and return a brd's page for a given sector.
*/
+static DEFINE_MUTEX(brd_mutex);
static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector)
{
pgoff_t idx;
@@ -402,7 +403,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
* ram device BLKFLSBUF has special semantics, we want to actually
* release and destroy the ramdisk data.
*/
- lock_kernel();
+ mutex_lock(&brd_mutex);
mutex_lock(&bdev->bd_mutex);
error = -EBUSY;
if (bdev->bd_openers <= 1) {
@@ -419,7 +420,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
error = 0;
}
mutex_unlock(&bdev->bd_mutex);
- unlock_kernel();
+ mutex_unlock(&brd_mutex);
return error;
}
@@ -482,7 +483,6 @@ static struct brd_device *brd_alloc(int i)
if (!brd->brd_queue)
goto out_free_dev;
blk_queue_make_request(brd->brd_queue, brd_make_request);
- blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG);
blk_queue_max_hw_sectors(brd->brd_queue, 1024);
blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 31064df1370a..fe90778f8680 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -26,7 +26,6 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -66,6 +65,7 @@ MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
MODULE_VERSION("3.6.26");
MODULE_LICENSE("GPL");
+static DEFINE_MUTEX(cciss_mutex);
static int cciss_allow_hpsa;
module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cciss_allow_hpsa,
@@ -297,6 +297,8 @@ static void enqueue_cmd_and_start_io(ctlr_info_t *h,
spin_lock_irqsave(&h->lock, flags);
addQ(&h->reqQ, c);
h->Qdepth++;
+ if (h->Qdepth > h->maxQsinceinit)
+ h->maxQsinceinit = h->Qdepth;
start_io(h);
spin_unlock_irqrestore(&h->lock, flags);
}
@@ -1057,9 +1059,9 @@ static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&cciss_mutex);
ret = cciss_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&cciss_mutex);
return ret;
}
@@ -1072,13 +1074,13 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
ctlr_info_t *h;
drive_info_struct *drv;
- lock_kernel();
+ mutex_lock(&cciss_mutex);
h = get_host(disk);
drv = get_drv(disk);
dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name);
drv->usage_count--;
h->usage_count--;
- unlock_kernel();
+ mutex_unlock(&cciss_mutex);
return 0;
}
@@ -1086,9 +1088,9 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&cciss_mutex);
ret = cciss_ioctl(bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&cciss_mutex);
return ret;
}
@@ -1230,470 +1232,452 @@ static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c)
c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
(void)check_for_unit_attention(h, c);
}
-/*
- * ioctl
- */
-static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
+
+static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
{
- struct gendisk *disk = bdev->bd_disk;
- ctlr_info_t *h = get_host(disk);
- drive_info_struct *drv = get_drv(disk);
- void __user *argp = (void __user *)arg;
+ cciss_pci_info_struct pciinfo;
- dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
- cmd, arg);
- switch (cmd) {
- case CCISS_GETPCIINFO:
- {
- cciss_pci_info_struct pciinfo;
-
- if (!arg)
- return -EINVAL;
- pciinfo.domain = pci_domain_nr(h->pdev->bus);
- pciinfo.bus = h->pdev->bus->number;
- pciinfo.dev_fn = h->pdev->devfn;
- pciinfo.board_id = h->board_id;
- if (copy_to_user
- (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETINTINFO:
- {
- cciss_coalint_struct intinfo;
- if (!arg)
- return -EINVAL;
- intinfo.delay =
- readl(&h->cfgtable->HostWrite.CoalIntDelay);
- intinfo.count =
- readl(&h->cfgtable->HostWrite.CoalIntCount);
- if (copy_to_user
- (argp, &intinfo, sizeof(cciss_coalint_struct)))
- return -EFAULT;
- return 0;
- }
- case CCISS_SETINTINFO:
- {
- cciss_coalint_struct intinfo;
- unsigned long flags;
- int i;
-
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (copy_from_user
- (&intinfo, argp, sizeof(cciss_coalint_struct)))
- return -EFAULT;
- if ((intinfo.delay == 0) && (intinfo.count == 0))
- return -EINVAL;
- spin_lock_irqsave(&h->lock, flags);
- /* Update the field, and then ring the doorbell */
- writel(intinfo.delay,
- &(h->cfgtable->HostWrite.CoalIntDelay));
- writel(intinfo.count,
- &(h->cfgtable->HostWrite.CoalIntCount));
- writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
-
- for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
- if (!(readl(h->vaddr + SA5_DOORBELL)
- & CFGTBL_ChangeReq))
- break;
- /* delay and try again */
- udelay(1000);
- }
- spin_unlock_irqrestore(&h->lock, flags);
- if (i >= MAX_IOCTL_CONFIG_WAIT)
- return -EAGAIN;
- return 0;
- }
- case CCISS_GETNODENAME:
- {
- NodeName_type NodeName;
- int i;
-
- if (!arg)
- return -EINVAL;
- for (i = 0; i < 16; i++)
- NodeName[i] =
- readb(&h->cfgtable->ServerName[i]);
- if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_SETNODENAME:
- {
- NodeName_type NodeName;
- unsigned long flags;
- int i;
+ if (!argp)
+ return -EINVAL;
+ pciinfo.domain = pci_domain_nr(h->pdev->bus);
+ pciinfo.bus = h->pdev->bus->number;
+ pciinfo.dev_fn = h->pdev->devfn;
+ pciinfo.board_id = h->board_id;
+ if (copy_to_user(argp, &pciinfo, sizeof(cciss_pci_info_struct)))
+ return -EFAULT;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
+{
+ cciss_coalint_struct intinfo;
- if (copy_from_user
- (NodeName, argp, sizeof(NodeName_type)))
- return -EFAULT;
+ if (!argp)
+ return -EINVAL;
+ intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
+ intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+ if (copy_to_user
+ (argp, &intinfo, sizeof(cciss_coalint_struct)))
+ return -EFAULT;
+ return 0;
+}
- spin_lock_irqsave(&h->lock, flags);
+static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
+{
+ cciss_coalint_struct intinfo;
+ unsigned long flags;
+ int i;
- /* Update the field, and then ring the doorbell */
- for (i = 0; i < 16; i++)
- writeb(NodeName[i],
- &h->cfgtable->ServerName[i]);
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&intinfo, argp, sizeof(intinfo)))
+ return -EFAULT;
+ if ((intinfo.delay == 0) && (intinfo.count == 0))
+ return -EINVAL;
+ spin_lock_irqsave(&h->lock, flags);
+ /* Update the field, and then ring the doorbell */
+ writel(intinfo.delay, &(h->cfgtable->HostWrite.CoalIntDelay));
+ writel(intinfo.count, &(h->cfgtable->HostWrite.CoalIntCount));
+ writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
- writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+ for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+ if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+ break;
+ udelay(1000); /* delay and try again */
+ }
+ spin_unlock_irqrestore(&h->lock, flags);
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ return -EAGAIN;
+ return 0;
+}
- for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
- if (!(readl(h->vaddr + SA5_DOORBELL)
- & CFGTBL_ChangeReq))
- break;
- /* delay and try again */
- udelay(1000);
- }
- spin_unlock_irqrestore(&h->lock, flags);
- if (i >= MAX_IOCTL_CONFIG_WAIT)
- return -EAGAIN;
- return 0;
- }
+static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
+{
+ NodeName_type NodeName;
+ int i;
- case CCISS_GETHEARTBEAT:
- {
- Heartbeat_type heartbeat;
-
- if (!arg)
- return -EINVAL;
- heartbeat = readl(&h->cfgtable->HeartBeat);
- if (copy_to_user
- (argp, &heartbeat, sizeof(Heartbeat_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETBUSTYPES:
- {
- BusTypes_type BusTypes;
-
- if (!arg)
- return -EINVAL;
- BusTypes = readl(&h->cfgtable->BusTypes);
- if (copy_to_user
- (argp, &BusTypes, sizeof(BusTypes_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETFIRMVER:
- {
- FirmwareVer_type firmware;
+ if (!argp)
+ return -EINVAL;
+ for (i = 0; i < 16; i++)
+ NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+ if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
+ return -EFAULT;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
- memcpy(firmware, h->firm_ver, 4);
+static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
+{
+ NodeName_type NodeName;
+ unsigned long flags;
+ int i;
- if (copy_to_user
- (argp, firmware, sizeof(FirmwareVer_type)))
- return -EFAULT;
- return 0;
- }
- case CCISS_GETDRIVVER:
- {
- DriverVer_type DriverVer = DRIVER_VERSION;
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(NodeName, argp, sizeof(NodeName_type)))
+ return -EFAULT;
+ spin_lock_irqsave(&h->lock, flags);
+ /* Update the field, and then ring the doorbell */
+ for (i = 0; i < 16; i++)
+ writeb(NodeName[i], &h->cfgtable->ServerName[i]);
+ writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+ for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+ if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+ break;
+ udelay(1000); /* delay and try again */
+ }
+ spin_unlock_irqrestore(&h->lock, flags);
+ if (i >= MAX_IOCTL_CONFIG_WAIT)
+ return -EAGAIN;
+ return 0;
+}
- if (!arg)
- return -EINVAL;
+static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
+{
+ Heartbeat_type heartbeat;
- if (copy_to_user
- (argp, &DriverVer, sizeof(DriverVer_type)))
- return -EFAULT;
- return 0;
- }
+ if (!argp)
+ return -EINVAL;
+ heartbeat = readl(&h->cfgtable->HeartBeat);
+ if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
+ return -EFAULT;
+ return 0;
+}
- case CCISS_DEREGDISK:
- case CCISS_REGNEWD:
- case CCISS_REVALIDVOLS:
- return rebuild_lun_table(h, 0, 1);
+static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
+{
+ BusTypes_type BusTypes;
+
+ if (!argp)
+ return -EINVAL;
+ BusTypes = readl(&h->cfgtable->BusTypes);
+ if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
+ return -EFAULT;
+ return 0;
+}
- case CCISS_GETLUNINFO:{
- LogvolInfo_struct luninfo;
+static int cciss_getfirmver(ctlr_info_t *h, void __user *argp)
+{
+ FirmwareVer_type firmware;
- memcpy(&luninfo.LunID, drv->LunID,
- sizeof(luninfo.LunID));
- luninfo.num_opens = drv->usage_count;
- luninfo.num_parts = 0;
- if (copy_to_user(argp, &luninfo,
- sizeof(LogvolInfo_struct)))
- return -EFAULT;
- return 0;
+ if (!argp)
+ return -EINVAL;
+ memcpy(firmware, h->firm_ver, 4);
+
+ if (copy_to_user
+ (argp, firmware, sizeof(FirmwareVer_type)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_getdrivver(ctlr_info_t *h, void __user *argp)
+{
+ DriverVer_type DriverVer = DRIVER_VERSION;
+
+ if (!argp)
+ return -EINVAL;
+ if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_getluninfo(ctlr_info_t *h,
+ struct gendisk *disk, void __user *argp)
+{
+ LogvolInfo_struct luninfo;
+ drive_info_struct *drv = get_drv(disk);
+
+ if (!argp)
+ return -EINVAL;
+ memcpy(&luninfo.LunID, drv->LunID, sizeof(luninfo.LunID));
+ luninfo.num_opens = drv->usage_count;
+ luninfo.num_parts = 0;
+ if (copy_to_user(argp, &luninfo, sizeof(LogvolInfo_struct)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cciss_passthru(ctlr_info_t *h, void __user *argp)
+{
+ IOCTL_Command_struct iocommand;
+ CommandList_struct *c;
+ char *buff = NULL;
+ u64bit temp64;
+ DECLARE_COMPLETION_ONSTACK(wait);
+
+ if (!argp)
+ return -EINVAL;
+
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ if (copy_from_user
+ (&iocommand, argp, sizeof(IOCTL_Command_struct)))
+ return -EFAULT;
+ if ((iocommand.buf_size < 1) &&
+ (iocommand.Request.Type.Direction != XFER_NONE)) {
+ return -EINVAL;
+ }
+ if (iocommand.buf_size > 0) {
+ buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+ if (buff == NULL)
+ return -EFAULT;
+ }
+ if (iocommand.Request.Type.Direction == XFER_WRITE) {
+ /* Copy the data into the buffer we created */
+ if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
+ kfree(buff);
+ return -EFAULT;
}
- case CCISS_PASSTHRU:
- {
- IOCTL_Command_struct iocommand;
- CommandList_struct *c;
- char *buff = NULL;
- u64bit temp64;
- DECLARE_COMPLETION_ONSTACK(wait);
-
- if (!arg)
- return -EINVAL;
-
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
-
- if (copy_from_user
- (&iocommand, argp, sizeof(IOCTL_Command_struct)))
- return -EFAULT;
- if ((iocommand.buf_size < 1) &&
- (iocommand.Request.Type.Direction != XFER_NONE)) {
- return -EINVAL;
- }
-#if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
- /* Check kmalloc limits */
- if (iocommand.buf_size > 128000)
- return -EINVAL;
-#endif
- if (iocommand.buf_size > 0) {
- buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
- if (buff == NULL)
- return -EFAULT;
- }
- if (iocommand.Request.Type.Direction == XFER_WRITE) {
- /* Copy the data into the buffer we created */
- if (copy_from_user
- (buff, iocommand.buf, iocommand.buf_size)) {
- kfree(buff);
- return -EFAULT;
- }
- } else {
- memset(buff, 0, iocommand.buf_size);
- }
- c = cmd_special_alloc(h);
- if (!c) {
- kfree(buff);
- return -ENOMEM;
- }
- /* Fill in the command type */
- c->cmd_type = CMD_IOCTL_PEND;
- /* Fill in Command Header */
- c->Header.ReplyQueue = 0; /* unused in simple mode */
- if (iocommand.buf_size > 0) /* buffer to fill */
- {
- c->Header.SGList = 1;
- c->Header.SGTotal = 1;
- } else /* no buffers to fill */
- {
- c->Header.SGList = 0;
- c->Header.SGTotal = 0;
- }
- c->Header.LUN = iocommand.LUN_info;
- /* use the kernel address the cmd block for tag */
- c->Header.Tag.lower = c->busaddr;
-
- /* Fill in Request block */
- c->Request = iocommand.Request;
-
- /* Fill in the scatter gather information */
- if (iocommand.buf_size > 0) {
- temp64.val = pci_map_single(h->pdev, buff,
- iocommand.buf_size,
- PCI_DMA_BIDIRECTIONAL);
- c->SG[0].Addr.lower = temp64.val32.lower;
- c->SG[0].Addr.upper = temp64.val32.upper;
- c->SG[0].Len = iocommand.buf_size;
- c->SG[0].Ext = 0; /* we are not chaining */
- }
- c->waiting = &wait;
+ } else {
+ memset(buff, 0, iocommand.buf_size);
+ }
+ c = cmd_special_alloc(h);
+ if (!c) {
+ kfree(buff);
+ return -ENOMEM;
+ }
+ /* Fill in the command type */
+ c->cmd_type = CMD_IOCTL_PEND;
+ /* Fill in Command Header */
+ c->Header.ReplyQueue = 0; /* unused in simple mode */
+ if (iocommand.buf_size > 0) { /* buffer to fill */
+ c->Header.SGList = 1;
+ c->Header.SGTotal = 1;
+ } else { /* no buffers to fill */
+ c->Header.SGList = 0;
+ c->Header.SGTotal = 0;
+ }
+ c->Header.LUN = iocommand.LUN_info;
+ /* use the kernel address the cmd block for tag */
+ c->Header.Tag.lower = c->busaddr;
- enqueue_cmd_and_start_io(h, c);
- wait_for_completion(&wait);
+ /* Fill in Request block */
+ c->Request = iocommand.Request;
- /* unlock the buffers from DMA */
- temp64.val32.lower = c->SG[0].Addr.lower;
- temp64.val32.upper = c->SG[0].Addr.upper;
- pci_unmap_single(h->pdev, (dma_addr_t) temp64.val,
- iocommand.buf_size,
- PCI_DMA_BIDIRECTIONAL);
+ /* Fill in the scatter gather information */
+ if (iocommand.buf_size > 0) {
+ temp64.val = pci_map_single(h->pdev, buff,
+ iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
+ c->SG[0].Addr.lower = temp64.val32.lower;
+ c->SG[0].Addr.upper = temp64.val32.upper;
+ c->SG[0].Len = iocommand.buf_size;
+ c->SG[0].Ext = 0; /* we are not chaining */
+ }
+ c->waiting = &wait;
- check_ioctl_unit_attention(h, c);
+ enqueue_cmd_and_start_io(h, c);
+ wait_for_completion(&wait);
- /* Copy the error information out */
- iocommand.error_info = *(c->err_info);
- if (copy_to_user
- (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
- kfree(buff);
- cmd_special_free(h, c);
- return -EFAULT;
- }
+ /* unlock the buffers from DMA */
+ temp64.val32.lower = c->SG[0].Addr.lower;
+ temp64.val32.upper = c->SG[0].Addr.upper;
+ pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size,
+ PCI_DMA_BIDIRECTIONAL);
+ check_ioctl_unit_attention(h, c);
+
+ /* Copy the error information out */
+ iocommand.error_info = *(c->err_info);
+ if (copy_to_user(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
+ kfree(buff);
+ cmd_special_free(h, c);
+ return -EFAULT;
+ }
- if (iocommand.Request.Type.Direction == XFER_READ) {
- /* Copy the data out of the buffer we created */
- if (copy_to_user
- (iocommand.buf, buff, iocommand.buf_size)) {
- kfree(buff);
- cmd_special_free(h, c);
- return -EFAULT;
- }
- }
+ if (iocommand.Request.Type.Direction == XFER_READ) {
+ /* Copy the data out of the buffer we created */
+ if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
kfree(buff);
cmd_special_free(h, c);
- return 0;
+ return -EFAULT;
}
- case CCISS_BIG_PASSTHRU:{
- BIG_IOCTL_Command_struct *ioc;
- CommandList_struct *c;
- unsigned char **buff = NULL;
- int *buff_size = NULL;
- u64bit temp64;
- BYTE sg_used = 0;
- int status = 0;
- int i;
- DECLARE_COMPLETION_ONSTACK(wait);
- __u32 left;
- __u32 sz;
- BYTE __user *data_ptr;
-
- if (!arg)
- return -EINVAL;
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- ioc = (BIG_IOCTL_Command_struct *)
- kmalloc(sizeof(*ioc), GFP_KERNEL);
- if (!ioc) {
- status = -ENOMEM;
- goto cleanup1;
- }
- if (copy_from_user(ioc, argp, sizeof(*ioc))) {
+ }
+ kfree(buff);
+ cmd_special_free(h, c);
+ return 0;
+}
+
+static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp)
+{
+ BIG_IOCTL_Command_struct *ioc;
+ CommandList_struct *c;
+ unsigned char **buff = NULL;
+ int *buff_size = NULL;
+ u64bit temp64;
+ BYTE sg_used = 0;
+ int status = 0;
+ int i;
+ DECLARE_COMPLETION_ONSTACK(wait);
+ __u32 left;
+ __u32 sz;
+ BYTE __user *data_ptr;
+
+ if (!argp)
+ return -EINVAL;
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+ ioc = (BIG_IOCTL_Command_struct *)
+ kmalloc(sizeof(*ioc), GFP_KERNEL);
+ if (!ioc) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ if (copy_from_user(ioc, argp, sizeof(*ioc))) {
+ status = -EFAULT;
+ goto cleanup1;
+ }
+ if ((ioc->buf_size < 1) &&
+ (ioc->Request.Type.Direction != XFER_NONE)) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ /* Check kmalloc limits using all SGs */
+ if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
+ status = -EINVAL;
+ goto cleanup1;
+ }
+ buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
+ if (!buff) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
+ if (!buff_size) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ left = ioc->buf_size;
+ data_ptr = ioc->buf;
+ while (left) {
+ sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
+ buff_size[sg_used] = sz;
+ buff[sg_used] = kmalloc(sz, GFP_KERNEL);
+ if (buff[sg_used] == NULL) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ if (ioc->Request.Type.Direction == XFER_WRITE) {
+ if (copy_from_user(buff[sg_used], data_ptr, sz)) {
status = -EFAULT;
goto cleanup1;
}
- if ((ioc->buf_size < 1) &&
- (ioc->Request.Type.Direction != XFER_NONE)) {
- status = -EINVAL;
- goto cleanup1;
- }
- /* Check kmalloc limits using all SGs */
- if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
- status = -EINVAL;
- goto cleanup1;
- }
- if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
- status = -EINVAL;
- goto cleanup1;
- }
- buff =
- kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
- if (!buff) {
- status = -ENOMEM;
- goto cleanup1;
- }
- buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
- GFP_KERNEL);
- if (!buff_size) {
- status = -ENOMEM;
- goto cleanup1;
- }
- left = ioc->buf_size;
- data_ptr = ioc->buf;
- while (left) {
- sz = (left >
- ioc->malloc_size) ? ioc->
- malloc_size : left;
- buff_size[sg_used] = sz;
- buff[sg_used] = kmalloc(sz, GFP_KERNEL);
- if (buff[sg_used] == NULL) {
- status = -ENOMEM;
- goto cleanup1;
- }
- if (ioc->Request.Type.Direction == XFER_WRITE) {
- if (copy_from_user
- (buff[sg_used], data_ptr, sz)) {
- status = -EFAULT;
- goto cleanup1;
- }
- } else {
- memset(buff[sg_used], 0, sz);
- }
- left -= sz;
- data_ptr += sz;
- sg_used++;
- }
- c = cmd_special_alloc(h);
- if (!c) {
- status = -ENOMEM;
- goto cleanup1;
- }
- c->cmd_type = CMD_IOCTL_PEND;
- c->Header.ReplyQueue = 0;
+ } else {
+ memset(buff[sg_used], 0, sz);
+ }
+ left -= sz;
+ data_ptr += sz;
+ sg_used++;
+ }
+ c = cmd_special_alloc(h);
+ if (!c) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ c->cmd_type = CMD_IOCTL_PEND;
+ c->Header.ReplyQueue = 0;
+ c->Header.SGList = sg_used;
+ c->Header.SGTotal = sg_used;
+ c->Header.LUN = ioc->LUN_info;
+ c->Header.Tag.lower = c->busaddr;
- if (ioc->buf_size > 0) {
- c->Header.SGList = sg_used;
- c->Header.SGTotal = sg_used;
- } else {
- c->Header.SGList = 0;
- c->Header.SGTotal = 0;
- }
- c->Header.LUN = ioc->LUN_info;
- c->Header.Tag.lower = c->busaddr;
-
- c->Request = ioc->Request;
- if (ioc->buf_size > 0) {
- for (i = 0; i < sg_used; i++) {
- temp64.val =
- pci_map_single(h->pdev, buff[i],
- buff_size[i],
- PCI_DMA_BIDIRECTIONAL);
- c->SG[i].Addr.lower =
- temp64.val32.lower;
- c->SG[i].Addr.upper =
- temp64.val32.upper;
- c->SG[i].Len = buff_size[i];
- c->SG[i].Ext = 0; /* we are not chaining */
- }
- }
- c->waiting = &wait;
- enqueue_cmd_and_start_io(h, c);
- wait_for_completion(&wait);
- /* unlock the buffers from DMA */
- for (i = 0; i < sg_used; i++) {
- temp64.val32.lower = c->SG[i].Addr.lower;
- temp64.val32.upper = c->SG[i].Addr.upper;
- pci_unmap_single(h->pdev,
- (dma_addr_t) temp64.val, buff_size[i],
- PCI_DMA_BIDIRECTIONAL);
- }
- check_ioctl_unit_attention(h, c);
- /* Copy the error information out */
- ioc->error_info = *(c->err_info);
- if (copy_to_user(argp, ioc, sizeof(*ioc))) {
+ c->Request = ioc->Request;
+ for (i = 0; i < sg_used; i++) {
+ temp64.val = pci_map_single(h->pdev, buff[i], buff_size[i],
+ PCI_DMA_BIDIRECTIONAL);
+ c->SG[i].Addr.lower = temp64.val32.lower;
+ c->SG[i].Addr.upper = temp64.val32.upper;
+ c->SG[i].Len = buff_size[i];
+ c->SG[i].Ext = 0; /* we are not chaining */
+ }
+ c->waiting = &wait;
+ enqueue_cmd_and_start_io(h, c);
+ wait_for_completion(&wait);
+ /* unlock the buffers from DMA */
+ for (i = 0; i < sg_used; i++) {
+ temp64.val32.lower = c->SG[i].Addr.lower;
+ temp64.val32.upper = c->SG[i].Addr.upper;
+ pci_unmap_single(h->pdev,
+ (dma_addr_t) temp64.val, buff_size[i],
+ PCI_DMA_BIDIRECTIONAL);
+ }
+ check_ioctl_unit_attention(h, c);
+ /* Copy the error information out */
+ ioc->error_info = *(c->err_info);
+ if (copy_to_user(argp, ioc, sizeof(*ioc))) {
+ cmd_special_free(h, c);
+ status = -EFAULT;
+ goto cleanup1;
+ }
+ if (ioc->Request.Type.Direction == XFER_READ) {
+ /* Copy the data out of the buffer we created */
+ BYTE __user *ptr = ioc->buf;
+ for (i = 0; i < sg_used; i++) {
+ if (copy_to_user(ptr, buff[i], buff_size[i])) {
cmd_special_free(h, c);
status = -EFAULT;
goto cleanup1;
}
- if (ioc->Request.Type.Direction == XFER_READ) {
- /* Copy the data out of the buffer we created */
- BYTE __user *ptr = ioc->buf;
- for (i = 0; i < sg_used; i++) {
- if (copy_to_user
- (ptr, buff[i], buff_size[i])) {
- cmd_special_free(h, c);
- status = -EFAULT;
- goto cleanup1;
- }
- ptr += buff_size[i];
- }
- }
- cmd_special_free(h, c);
- status = 0;
- cleanup1:
- if (buff) {
- for (i = 0; i < sg_used; i++)
- kfree(buff[i]);
- kfree(buff);
- }
- kfree(buff_size);
- kfree(ioc);
- return status;
+ ptr += buff_size[i];
}
+ }
+ cmd_special_free(h, c);
+ status = 0;
+cleanup1:
+ if (buff) {
+ for (i = 0; i < sg_used; i++)
+ kfree(buff[i]);
+ kfree(buff);
+ }
+ kfree(buff_size);
+ kfree(ioc);
+ return status;
+}
+
+static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ struct gendisk *disk = bdev->bd_disk;
+ ctlr_info_t *h = get_host(disk);
+ void __user *argp = (void __user *)arg;
+
+ dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
+ cmd, arg);
+ switch (cmd) {
+ case CCISS_GETPCIINFO:
+ return cciss_getpciinfo(h, argp);
+ case CCISS_GETINTINFO:
+ return cciss_getintinfo(h, argp);
+ case CCISS_SETINTINFO:
+ return cciss_setintinfo(h, argp);
+ case CCISS_GETNODENAME:
+ return cciss_getnodename(h, argp);
+ case CCISS_SETNODENAME:
+ return cciss_setnodename(h, argp);
+ case CCISS_GETHEARTBEAT:
+ return cciss_getheartbeat(h, argp);
+ case CCISS_GETBUSTYPES:
+ return cciss_getbustypes(h, argp);
+ case CCISS_GETFIRMVER:
+ return cciss_getfirmver(h, argp);
+ case CCISS_GETDRIVVER:
+ return cciss_getdrivver(h, argp);
+ case CCISS_DEREGDISK:
+ case CCISS_REGNEWD:
+ case CCISS_REVALIDVOLS:
+ return rebuild_lun_table(h, 0, 1);
+ case CCISS_GETLUNINFO:
+ return cciss_getluninfo(h, disk, argp);
+ case CCISS_PASSTHRU:
+ return cciss_passthru(h, argp);
+ case CCISS_BIG_PASSTHRU:
+ return cciss_bigpassthru(h, argp);
/* scsi_cmd_ioctl handles these, below, though some are not */
/* very meaningful for cciss. SG_IO is the main one people want. */
@@ -4519,6 +4503,12 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
misc_fw_support = readl(&cfgtable->misc_fw_support);
use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+ /* The doorbell reset seems to cause lockups on some Smart
+ * Arrays (e.g. P410, P410i, maybe others). Until this is
+ * fixed or at least isolated, avoid the doorbell reset.
+ */
+ use_doorbell = 0;
+
rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
if (rc)
goto unmap_cfgtable;
@@ -4712,6 +4702,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
h->scatter_list = kmalloc(h->max_commands *
sizeof(struct scatterlist *),
GFP_KERNEL);
+ if (!h->scatter_list)
+ goto clean4;
+
for (k = 0; k < h->nr_cmds; k++) {
h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
h->maxsgentries,
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index d53b0291c44b..946dad4caef3 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -35,7 +35,7 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/hdreg.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
@@ -68,6 +68,7 @@ MODULE_LICENSE("GPL");
#define CPQARRAY_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
+static DEFINE_MUTEX(cpqarray_mutex);
static int nr_ctlr;
static ctlr_info_t *hba[MAX_CTLR];
@@ -845,9 +846,9 @@ static int ida_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&cpqarray_mutex);
ret = ida_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&cpqarray_mutex);
return ret;
}
@@ -859,10 +860,10 @@ static int ida_release(struct gendisk *disk, fmode_t mode)
{
ctlr_info_t *host;
- lock_kernel();
+ mutex_lock(&cpqarray_mutex);
host = get_host(disk);
host->usage_count--;
- unlock_kernel();
+ mutex_unlock(&cpqarray_mutex);
return 0;
}
@@ -1217,9 +1218,9 @@ static int ida_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&cpqarray_mutex);
ret = ida_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&cpqarray_mutex);
return ret;
}
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index fa650dd85b90..e4b56119866e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -32,7 +32,7 @@
#include <asm/types.h>
#include <net/sock.h>
#include <linux/ctype.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/proc_fs.h>
@@ -64,6 +64,7 @@ struct after_state_chg_work {
struct completion *done;
};
+static DEFINE_MUTEX(drbd_main_mutex);
int drbdd_init(struct drbd_thread *);
int drbd_worker(struct drbd_thread *);
int drbd_asender(struct drbd_thread *);
@@ -2536,7 +2537,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
unsigned long flags;
int rv = 0;
- lock_kernel();
+ mutex_lock(&drbd_main_mutex);
spin_lock_irqsave(&mdev->req_lock, flags);
/* to have a stable mdev->state.role
* and no race with updating open_cnt */
@@ -2551,7 +2552,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
if (!rv)
mdev->open_cnt++;
spin_unlock_irqrestore(&mdev->req_lock, flags);
- unlock_kernel();
+ mutex_unlock(&drbd_main_mutex);
return rv;
}
@@ -2559,9 +2560,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
static int drbd_release(struct gendisk *gd, fmode_t mode)
{
struct drbd_conf *mdev = gd->private_data;
- lock_kernel();
+ mutex_lock(&drbd_main_mutex);
mdev->open_cnt--;
- unlock_kernel();
+ mutex_unlock(&drbd_main_mutex);
return 0;
}
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index cf04c1b234ed..3b57459bb745 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -178,7 +178,6 @@ static int print_unex = 1;
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/bio.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/fcntl.h>
@@ -199,6 +198,7 @@ static int print_unex = 1;
* It's been recommended that take about 1/4 of the default speed
* in some more extreme cases.
*/
+static DEFINE_MUTEX(floppy_mutex);
static int slow_floppy;
#include <asm/dma.h>
@@ -3553,9 +3553,9 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&floppy_mutex);
ret = fd_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&floppy_mutex);
return ret;
}
@@ -3616,7 +3616,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
{
int drive = (long)disk->private_data;
- lock_kernel();
+ mutex_lock(&floppy_mutex);
mutex_lock(&open_lock);
if (UDRS->fd_ref < 0)
UDRS->fd_ref = 0;
@@ -3627,7 +3627,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
if (!UDRS->fd_ref)
opened_bdev[drive] = NULL;
mutex_unlock(&open_lock);
- unlock_kernel();
+ mutex_unlock(&floppy_mutex);
return 0;
}
@@ -3645,7 +3645,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
int res = -EBUSY;
char *tmp;
- lock_kernel();
+ mutex_lock(&floppy_mutex);
mutex_lock(&open_lock);
old_dev = UDRS->fd_device;
if (opened_bdev[drive] && opened_bdev[drive] != bdev)
@@ -3722,7 +3722,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
goto out;
}
mutex_unlock(&open_lock);
- unlock_kernel();
+ mutex_unlock(&floppy_mutex);
return 0;
out:
if (UDRS->fd_ref < 0)
@@ -3733,7 +3733,7 @@ out:
opened_bdev[drive] = NULL;
out2:
mutex_unlock(&open_lock);
- unlock_kernel();
+ mutex_unlock(&floppy_mutex);
return res;
}
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f3c636d23718..6c48b3545f84 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -67,16 +67,18 @@
#include <linux/compat.h>
#include <linux/suspend.h>
#include <linux/freezer.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> /* for invalidate_bdev() */
#include <linux/completion.h>
#include <linux/highmem.h>
#include <linux/kthread.h>
#include <linux/splice.h>
+#include <linux/sysfs.h>
#include <asm/uaccess.h>
+static DEFINE_MUTEX(loop_mutex);
static LIST_HEAD(loop_devices);
static DEFINE_MUTEX(loop_devices_mutex);
@@ -477,17 +479,17 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
if (bio_rw(bio) == WRITE) {
- bool barrier = (bio->bi_rw & REQ_HARDBARRIER);
struct file *file = lo->lo_backing_file;
- if (barrier) {
- if (unlikely(!file->f_op->fsync)) {
- ret = -EOPNOTSUPP;
- goto out;
- }
+ /* REQ_HARDBARRIER is deprecated */
+ if (bio->bi_rw & REQ_HARDBARRIER) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+ if (bio->bi_rw & REQ_FLUSH) {
ret = vfs_fsync(file, 0);
- if (unlikely(ret)) {
+ if (unlikely(ret && ret != -EINVAL)) {
ret = -EIO;
goto out;
}
@@ -495,9 +497,9 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
ret = lo_send(lo, bio, pos);
- if (barrier && !ret) {
+ if ((bio->bi_rw & REQ_FUA) && !ret) {
ret = vfs_fsync(file, 0);
- if (unlikely(ret))
+ if (unlikely(ret && ret != -EINVAL))
ret = -EIO;
}
} else
@@ -737,6 +739,103 @@ static inline int is_loop_device(struct file *file)
return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
}
+/* loop sysfs attributes */
+
+static ssize_t loop_attr_show(struct device *dev, char *page,
+ ssize_t (*callback)(struct loop_device *, char *))
+{
+ struct loop_device *l, *lo = NULL;
+
+ mutex_lock(&loop_devices_mutex);
+ list_for_each_entry(l, &loop_devices, lo_list)
+ if (disk_to_dev(l->lo_disk) == dev) {
+ lo = l;
+ break;
+ }
+ mutex_unlock(&loop_devices_mutex);
+
+ return lo ? callback(lo, page) : -EIO;
+}
+
+#define LOOP_ATTR_RO(_name) \
+static ssize_t loop_attr_##_name##_show(struct loop_device *, char *); \
+static ssize_t loop_attr_do_show_##_name(struct device *d, \
+ struct device_attribute *attr, char *b) \
+{ \
+ return loop_attr_show(d, b, loop_attr_##_name##_show); \
+} \
+static struct device_attribute loop_attr_##_name = \
+ __ATTR(_name, S_IRUGO, loop_attr_do_show_##_name, NULL);
+
+static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf)
+{
+ ssize_t ret;
+ char *p = NULL;
+
+ mutex_lock(&lo->lo_ctl_mutex);
+ if (lo->lo_backing_file)
+ p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1);
+ mutex_unlock(&lo->lo_ctl_mutex);
+
+ if (IS_ERR_OR_NULL(p))
+ ret = PTR_ERR(p);
+ else {
+ ret = strlen(p);
+ memmove(buf, p, ret);
+ buf[ret++] = '\n';
+ buf[ret] = 0;
+ }
+
+ return ret;
+}
+
+static ssize_t loop_attr_offset_show(struct loop_device *lo, char *buf)
+{
+ return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_offset);
+}
+
+static ssize_t loop_attr_sizelimit_show(struct loop_device *lo, char *buf)
+{
+ return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit);
+}
+
+static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
+{
+ int autoclear = (lo->lo_flags & LO_FLAGS_AUTOCLEAR);
+
+ return sprintf(buf, "%s\n", autoclear ? "1" : "0");
+}
+
+LOOP_ATTR_RO(backing_file);
+LOOP_ATTR_RO(offset);
+LOOP_ATTR_RO(sizelimit);
+LOOP_ATTR_RO(autoclear);
+
+static struct attribute *loop_attrs[] = {
+ &loop_attr_backing_file.attr,
+ &loop_attr_offset.attr,
+ &loop_attr_sizelimit.attr,
+ &loop_attr_autoclear.attr,
+ NULL,
+};
+
+static struct attribute_group loop_attribute_group = {
+ .name = "loop",
+ .attrs= loop_attrs,
+};
+
+static int loop_sysfs_init(struct loop_device *lo)
+{
+ return sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj,
+ &loop_attribute_group);
+}
+
+static void loop_sysfs_exit(struct loop_device *lo)
+{
+ sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj,
+ &loop_attribute_group);
+}
+
static int loop_set_fd(struct loop_device *lo, fmode_t mode,
struct block_device *bdev, unsigned int arg)
{
@@ -832,10 +931,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
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);
+ blk_queue_flush(lo->lo_queue, REQ_FLUSH);
set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);
+ loop_sysfs_init(lo);
/* let user-space know about the new size */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
@@ -854,6 +954,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
return 0;
out_clr:
+ loop_sysfs_exit(lo);
lo->lo_thread = NULL;
lo->lo_device = NULL;
lo->lo_backing_file = NULL;
@@ -950,6 +1051,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
set_capacity(lo->lo_disk, 0);
if (bdev) {
bd_set_size(bdev, 0);
+ loop_sysfs_exit(lo);
/* let user-space know about this change */
kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
}
@@ -1409,11 +1511,11 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
{
struct loop_device *lo = bdev->bd_disk->private_data;
- lock_kernel();
+ mutex_lock(&loop_mutex);
mutex_lock(&lo->lo_ctl_mutex);
lo->lo_refcnt++;
mutex_unlock(&lo->lo_ctl_mutex);
- unlock_kernel();
+ mutex_unlock(&loop_mutex);
return 0;
}
@@ -1423,7 +1525,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
struct loop_device *lo = disk->private_data;
int err;
- lock_kernel();
+ mutex_lock(&loop_mutex);
mutex_lock(&lo->lo_ctl_mutex);
if (--lo->lo_refcnt)
@@ -1448,7 +1550,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
out:
mutex_unlock(&lo->lo_ctl_mutex);
out_unlocked:
- lock_kernel();
+ mutex_unlock(&loop_mutex);
return 0;
}
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index b82c5ce5e9df..76fa3deaee84 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -974,8 +974,7 @@ static int mg_probe(struct platform_device *plat_dev)
host->breq->queuedata = host;
/* mflash is random device, thanx for the noop */
- elevator_exit(host->breq->elevator);
- err = elevator_init(host->breq, "noop");
+ err = elevator_change(host->breq, "noop");
if (err) {
printk(KERN_ERR "%s:%d (elevator_init) fail\n",
__func__, __LINE__);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 0daa422aa281..a32fb41246f8 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -24,7 +24,7 @@
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/ioctl.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -53,6 +53,7 @@
#define DBG_BLKDEV 0x0100
#define DBG_RX 0x0200
#define DBG_TX 0x0400
+static DEFINE_MUTEX(nbd_mutex);
static unsigned int debugflags;
#endif /* NDEBUG */
@@ -717,11 +718,11 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
- lock_kernel();
+ mutex_lock(&nbd_mutex);
mutex_lock(&lo->tx_lock);
error = __nbd_ioctl(bdev, lo, cmd, arg);
mutex_unlock(&lo->tx_lock);
- unlock_kernel();
+ mutex_unlock(&nbd_mutex);
return error;
}
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index 2284b4f05c62..87311ebac0db 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -310,8 +310,7 @@ static void osdblk_rq_fn(struct request_queue *q)
break;
/* filter out block requests we don't understand */
- if (rq->cmd_type != REQ_TYPE_FS &&
- !(rq->cmd_flags & REQ_HARDBARRIER)) {
+ if (rq->cmd_type != REQ_TYPE_FS) {
blk_end_request_all(rq, 0);
continue;
}
@@ -439,7 +438,7 @@ static int osdblk_init_disk(struct osdblk_device *osdev)
blk_queue_stack_limits(q, osd_request_queue(osdev->osd));
blk_queue_prep_rq(q, blk_queue_start_tag);
- blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH);
+ blk_queue_flush(q, REQ_FLUSH);
disk->queue = q;
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 76f8565e1e8d..62cec6afd7ad 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -138,9 +138,10 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/cdrom.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
+static DEFINE_MUTEX(pcd_mutex);
static DEFINE_SPINLOCK(pcd_lock);
module_param(verbose, bool, 0644);
@@ -227,9 +228,9 @@ static int pcd_block_open(struct block_device *bdev, fmode_t mode)
struct pcd_unit *cd = bdev->bd_disk->private_data;
int ret;
- lock_kernel();
+ mutex_lock(&pcd_mutex);
ret = cdrom_open(&cd->info, bdev, mode);
- unlock_kernel();
+ mutex_unlock(&pcd_mutex);
return ret;
}
@@ -237,9 +238,9 @@ static int pcd_block_open(struct block_device *bdev, fmode_t mode)
static int pcd_block_release(struct gendisk *disk, fmode_t mode)
{
struct pcd_unit *cd = disk->private_data;
- lock_kernel();
+ mutex_lock(&pcd_mutex);
cdrom_release(&cd->info, mode);
- unlock_kernel();
+ mutex_unlock(&pcd_mutex);
return 0;
}
@@ -249,9 +250,9 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
struct pcd_unit *cd = bdev->bd_disk->private_data;
int ret;
- lock_kernel();
+ mutex_lock(&pcd_mutex);
ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pcd_mutex);
return ret;
}
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 985f0d4f1d1e..c0ee1558b9bb 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -153,10 +153,11 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/workqueue.h>
+static DEFINE_MUTEX(pd_mutex);
static DEFINE_SPINLOCK(pd_lock);
module_param(verbose, bool, 0);
@@ -736,14 +737,14 @@ static int pd_open(struct block_device *bdev, fmode_t mode)
{
struct pd_unit *disk = bdev->bd_disk->private_data;
- lock_kernel();
+ mutex_lock(&pd_mutex);
disk->access++;
if (disk->removable) {
pd_special_command(disk, pd_media_check);
pd_special_command(disk, pd_door_lock);
}
- unlock_kernel();
+ mutex_unlock(&pd_mutex);
return 0;
}
@@ -771,10 +772,10 @@ static int pd_ioctl(struct block_device *bdev, fmode_t mode,
switch (cmd) {
case CDROMEJECT:
- lock_kernel();
+ mutex_lock(&pd_mutex);
if (disk->access == 1)
pd_special_command(disk, pd_eject);
- unlock_kernel();
+ mutex_unlock(&pd_mutex);
return 0;
default:
return -EINVAL;
@@ -785,10 +786,10 @@ static int pd_release(struct gendisk *p, fmode_t mode)
{
struct pd_unit *disk = p->private_data;
- lock_kernel();
+ mutex_lock(&pd_mutex);
if (!--disk->access && disk->removable)
pd_special_command(disk, pd_door_unlock);
- unlock_kernel();
+ mutex_unlock(&pd_mutex);
return 0;
}
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 4457b494882a..635f25dd9e10 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -152,9 +152,10 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
+static DEFINE_MUTEX(pf_mutex);
static DEFINE_SPINLOCK(pf_spin_lock);
module_param(verbose, bool, 0644);
@@ -302,7 +303,7 @@ static int pf_open(struct block_device *bdev, fmode_t mode)
struct pf_unit *pf = bdev->bd_disk->private_data;
int ret;
- lock_kernel();
+ mutex_lock(&pf_mutex);
pf_identify(pf);
ret = -ENODEV;
@@ -318,7 +319,7 @@ static int pf_open(struct block_device *bdev, fmode_t mode)
if (pf->removable)
pf_lock(pf, 1);
out:
- unlock_kernel();
+ mutex_unlock(&pf_mutex);
return ret;
}
@@ -349,9 +350,9 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
if (pf->access != 1)
return -EBUSY;
- lock_kernel();
+ mutex_lock(&pf_mutex);
pf_eject(pf);
- unlock_kernel();
+ mutex_unlock(&pf_mutex);
return 0;
}
@@ -360,9 +361,9 @@ static int pf_release(struct gendisk *disk, fmode_t mode)
{
struct pf_unit *pf = disk->private_data;
- lock_kernel();
+ mutex_lock(&pf_mutex);
if (pf->access <= 0) {
- unlock_kernel();
+ mutex_unlock(&pf_mutex);
return -EINVAL;
}
@@ -371,7 +372,7 @@ static int pf_release(struct gendisk *disk, fmode_t mode)
if (!pf->access && pf->removable)
pf_lock(pf, 0);
- unlock_kernel();
+ mutex_unlock(&pf_mutex);
return 0;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index c397b3ddba9b..eb4cab743e00 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -162,7 +162,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/pg.h>
#include <linux/device.h>
#include <linux/sched.h> /* current, TASK_* */
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
@@ -193,6 +193,7 @@ module_param_array(drive3, int, NULL, 0);
#define ATAPI_IDENTIFY 0x12
+static DEFINE_MUTEX(pg_mutex);
static int pg_open(struct inode *inode, struct file *file);
static int pg_release(struct inode *inode, struct file *file);
static ssize_t pg_read(struct file *filp, char __user *buf,
@@ -234,6 +235,7 @@ static const struct file_operations pg_fops = {
.write = pg_write,
.open = pg_open,
.release = pg_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static void pg_init_units(void)
@@ -518,7 +520,7 @@ static int pg_open(struct inode *inode, struct file *file)
struct pg *dev = &devices[unit];
int ret = 0;
- lock_kernel();
+ mutex_lock(&pg_mutex);
if ((unit >= PG_UNITS) || (!dev->present)) {
ret = -ENODEV;
goto out;
@@ -547,7 +549,7 @@ static int pg_open(struct inode *inode, struct file *file)
file->private_data = dev;
out:
- unlock_kernel();
+ mutex_unlock(&pg_mutex);
return ret;
}
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index bc5825fdeaab..b0de773aa453 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -146,7 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
#include <linux/mtio.h>
#include <linux/device.h>
#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
@@ -189,6 +189,7 @@ module_param_array(drive3, int, NULL, 0);
#define ATAPI_MODE_SENSE 0x1a
#define ATAPI_LOG_SENSE 0x4d
+static DEFINE_MUTEX(pt_mutex);
static int pt_open(struct inode *inode, struct file *file);
static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int pt_release(struct inode *inode, struct file *file);
@@ -239,6 +240,7 @@ static const struct file_operations pt_fops = {
.unlocked_ioctl = pt_ioctl,
.open = pt_open,
.release = pt_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/* sysfs class support */
@@ -650,9 +652,9 @@ static int pt_open(struct inode *inode, struct file *file)
struct pt_unit *tape = pt + unit;
int err;
- lock_kernel();
+ mutex_lock(&pt_mutex);
if (unit >= PT_UNITS || (!tape->present)) {
- unlock_kernel();
+ mutex_unlock(&pt_mutex);
return -ENODEV;
}
@@ -681,12 +683,12 @@ static int pt_open(struct inode *inode, struct file *file)
}
file->private_data = tape;
- unlock_kernel();
+ mutex_unlock(&pt_mutex);
return 0;
out:
atomic_inc(&tape->available);
- unlock_kernel();
+ mutex_unlock(&pt_mutex);
return err;
}
@@ -704,15 +706,15 @@ static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
switch (mtop.mt_op) {
case MTREW:
- lock_kernel();
+ mutex_lock(&pt_mutex);
pt_rewind(tape);
- unlock_kernel();
+ mutex_unlock(&pt_mutex);
return 0;
case MTWEOF:
- lock_kernel();
+ mutex_lock(&pt_mutex);
pt_write_fm(tape);
- unlock_kernel();
+ mutex_unlock(&pt_mutex);
return 0;
default:
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index b1cbeb59bb76..3b39c060dfd9 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -57,7 +57,6 @@
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/freezer.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <scsi/scsi_cmnd.h>
@@ -86,6 +85,7 @@
#define ZONE(sector, pd) (((sector) + (pd)->offset) & ~((pd)->settings.size - 1))
+static DEFINE_MUTEX(pktcdvd_mutex);
static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
static struct proc_dir_entry *pkt_proc;
static int pktdev_major;
@@ -753,7 +753,6 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
rq->timeout = 60*HZ;
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->cmd_flags |= REQ_HARDBARRIER;
if (cgc->quiet)
rq->cmd_flags |= REQ_QUIET;
@@ -2383,7 +2382,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode)
VPRINTK(DRIVER_NAME": entering open\n");
- lock_kernel();
+ mutex_lock(&pktcdvd_mutex);
mutex_lock(&ctl_mutex);
pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev));
if (!pd) {
@@ -2411,7 +2410,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode)
}
mutex_unlock(&ctl_mutex);
- unlock_kernel();
+ mutex_unlock(&pktcdvd_mutex);
return 0;
out_dec:
@@ -2419,7 +2418,7 @@ out_dec:
out:
VPRINTK(DRIVER_NAME": failed open (%d)\n", ret);
mutex_unlock(&ctl_mutex);
- unlock_kernel();
+ mutex_unlock(&pktcdvd_mutex);
return ret;
}
@@ -2428,7 +2427,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)
struct pktcdvd_device *pd = disk->private_data;
int ret = 0;
- lock_kernel();
+ mutex_lock(&pktcdvd_mutex);
mutex_lock(&ctl_mutex);
pd->refcnt--;
BUG_ON(pd->refcnt < 0);
@@ -2437,7 +2436,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)
pkt_release_dev(pd, flush);
}
mutex_unlock(&ctl_mutex);
- unlock_kernel();
+ mutex_unlock(&pktcdvd_mutex);
return ret;
}
@@ -2773,7 +2772,7 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd,
MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
- lock_kernel();
+ mutex_lock(&pktcdvd_mutex);
switch (cmd) {
case CDROMEJECT:
/*
@@ -2798,7 +2797,7 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
ret = -ENOTTY;
}
- unlock_kernel();
+ mutex_unlock(&pktcdvd_mutex);
return ret;
}
@@ -3046,6 +3045,7 @@ static const struct file_operations pkt_ctl_fops = {
.compat_ioctl = pkt_ctl_compat_ioctl,
#endif
.owner = THIS_MODULE,
+ .llseek = no_llseek,/* nonseekable */
};
static struct miscdevice pkt_misc = {
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index e9da874d0419..4911f9e57bc7 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -468,7 +468,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
blk_queue_dma_alignment(queue, dev->blk_size-1);
blk_queue_logical_block_size(queue, dev->blk_size);
- blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH);
+ blk_queue_flush(queue, REQ_FLUSH);
blk_queue_max_segments(queue, -1);
blk_queue_max_segment_size(queue, dev->bounce_size);
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 2e46815876df..75333d0a3327 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -20,7 +20,7 @@
#include <linux/fd.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/hdreg.h>
#include <linux/kernel.h>
#include <linux/delay.h>
@@ -222,6 +222,7 @@ extern int swim_read_sector_header(struct swim __iomem *base,
extern int swim_read_sector_data(struct swim __iomem *base,
unsigned char *data);
+static DEFINE_MUTEX(swim_mutex);
static inline void set_swim_mode(struct swim __iomem *base, int enable)
{
struct iwm __iomem *iwm_base;
@@ -666,9 +667,9 @@ static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&swim_mutex);
ret = floppy_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&swim_mutex);
return ret;
}
@@ -678,7 +679,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
struct floppy_state *fs = disk->private_data;
struct swim __iomem *base = fs->swd->base;
- lock_kernel();
+ mutex_lock(&swim_mutex);
if (fs->ref_count < 0)
fs->ref_count = 0;
else if (fs->ref_count > 0)
@@ -686,7 +687,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
if (fs->ref_count == 0)
swim_motor(base, OFF);
- unlock_kernel();
+ mutex_unlock(&swim_mutex);
return 0;
}
@@ -704,9 +705,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
case FDEJECT:
if (fs->ref_count != 1)
return -EBUSY;
- lock_kernel();
+ mutex_lock(&swim_mutex);
err = floppy_eject(fs);
- unlock_kernel();
+ mutex_unlock(&swim_mutex);
return err;
case FDGETPRM:
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index cc6a3864822c..bf3a5b859299 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -25,7 +25,7 @@
#include <linux/ioctl.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/io.h>
@@ -36,6 +36,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
+static DEFINE_MUTEX(swim3_mutex);
static struct request_queue *swim3_queue;
static struct gendisk *disks[2];
static struct request *fd_req;
@@ -873,9 +874,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&swim3_mutex);
ret = floppy_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&swim3_mutex);
return ret;
}
@@ -953,9 +954,9 @@ static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&swim3_mutex);
ret = floppy_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&swim3_mutex);
return ret;
}
@@ -964,13 +965,13 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
{
struct floppy_state *fs = disk->private_data;
struct swim3 __iomem *sw = fs->swim3;
- lock_kernel();
+ mutex_lock(&swim3_mutex);
if (fs->ref_count > 0 && --fs->ref_count == 0) {
swim3_action(fs, MOTOR_OFF);
out_8(&sw->control_bic, 0xff);
swim3_select(fs, RELAX);
}
- unlock_kernel();
+ mutex_unlock(&swim3_mutex);
return 0;
}
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c48e14878582..b5690a045a01 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -28,7 +28,7 @@
#include <linux/timer.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <scsi/scsi.h>
#define DRV_NAME "ub"
@@ -248,6 +248,7 @@ struct ub_completion {
spinlock_t lock;
};
+static DEFINE_MUTEX(ub_mutex);
static inline void ub_init_completion(struct ub_completion *x)
{
x->done = 0;
@@ -1715,9 +1716,9 @@ static int ub_bd_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&ub_mutex);
ret = ub_bd_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&ub_mutex);
return ret;
}
@@ -1730,9 +1731,9 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)
struct ub_lun *lun = disk->private_data;
struct ub_dev *sc = lun->udev;
- lock_kernel();
+ mutex_lock(&ub_mutex);
ub_put(sc);
- unlock_kernel();
+ mutex_unlock(&ub_mutex);
return 0;
}
@@ -1747,9 +1748,9 @@ static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
void __user *usermem = (void __user *) arg;
int ret;
- lock_kernel();
+ mutex_lock(&ub_mutex);
ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
- unlock_kernel();
+ mutex_unlock(&ub_mutex);
return ret;
}
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index f651e51a3319..e2ff697697c2 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -41,7 +41,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/dma-mapping.h>
#include <linux/completion.h>
#include <linux/device.h>
@@ -73,6 +73,7 @@ enum {
MAX_DISK_NAME = FIELD_SIZEOF(struct gendisk, disk_name)
};
+static DEFINE_MUTEX(viodasd_mutex);
static DEFINE_SPINLOCK(viodasd_spinlock);
#define VIOMAXREQ 16
@@ -180,9 +181,9 @@ static int viodasd_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&viodasd_mutex);
ret = viodasd_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&viodasd_mutex);
return ret;
}
@@ -196,7 +197,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)
struct viodasd_device *d = disk->private_data;
HvLpEvent_Rc hvrc;
- lock_kernel();
+ mutex_lock(&viodasd_mutex);
/* Send the event to OS/400. We DON'T expect a response */
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo,
@@ -210,7 +211,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)
if (hvrc != 0)
pr_warning("HV close call failed %d\n", (int)hvrc);
- unlock_kernel();
+ mutex_unlock(&viodasd_mutex);
return 0;
}
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 2aafafca2b13..5c590b850f39 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -2,7 +2,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/hdreg.h>
#include <linux/virtio.h>
#include <linux/virtio_blk.h>
@@ -10,6 +10,7 @@
#define PART_BITS 4
+static DEFINE_MUTEX(virtio_blk_mutex);
static int major, index;
struct virtio_blk
@@ -128,9 +129,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
}
}
- if (vbr->req->cmd_flags & REQ_HARDBARRIER)
- vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
-
sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr));
/*
@@ -239,9 +237,9 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&virtio_blk_mutex);
ret = virtblk_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&virtio_blk_mutex);
return ret;
}
@@ -388,31 +386,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
vblk->disk->driverfs_dev = &vdev->dev;
index++;
- if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) {
- /*
- * If the FLUSH feature is supported we do have support for
- * flushing a volatile write cache on the host. Use that
- * to implement write barrier support.
- */
- blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH);
- } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) {
- /*
- * If the BARRIER feature is supported the host expects us
- * to order request by tags. This implies there is not
- * volatile write cache on the host, and that the host
- * never re-orders outstanding I/O. This feature is not
- * useful for real life scenarious and deprecated.
- */
- blk_queue_ordered(q, QUEUE_ORDERED_TAG);
- } else {
- /*
- * If the FLUSH feature is not supported we must assume that
- * the host does not perform any kind of volatile write
- * caching. We still need to drain the queue to provider
- * proper barrier semantics.
- */
- blk_queue_ordered(q, QUEUE_ORDERED_DRAIN);
- }
+ /* configure queue flush support */
+ if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
+ blk_queue_flush(q, REQ_FLUSH);
/* If disk is read-only in the host, the guest should obey */
if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
@@ -531,9 +507,9 @@ static const struct virtio_device_id id_table[] = {
};
static unsigned int features[] = {
- VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
- VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
- VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY
+ VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
+ VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_SCSI,
+ VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY
};
/*
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index d5a3cd750561..4abd2bcd20fb 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -46,7 +46,7 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -58,6 +58,7 @@
#include "xd.h"
+static DEFINE_MUTEX(xd_mutex);
static void __init do_xd_setup (int *integers);
#ifdef MODULE
static int xd[5] = { -1,-1,-1,-1, };
@@ -381,9 +382,9 @@ static int xd_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&xd_mutex);
ret = xd_locked_ioctl(bdev, mode, cmd, param);
- unlock_kernel();
+ mutex_unlock(&xd_mutex);
return ret;
}
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index ab735a605cf3..5377317f033d 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -41,7 +41,7 @@
#include <linux/cdrom.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <xen/xen.h>
@@ -69,6 +69,7 @@ struct blk_shadow {
unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
+static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
@@ -95,7 +96,7 @@ struct blkfront_info
struct gnttab_free_callback callback;
struct blk_shadow shadow[BLK_RING_SIZE];
unsigned long shadow_free;
- int feature_barrier;
+ unsigned int feature_flush;
int is_ready;
};
@@ -418,26 +419,12 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
}
-static int xlvbd_barrier(struct blkfront_info *info)
+static void xlvbd_flush(struct blkfront_info *info)
{
- int err;
- const char *barrier;
-
- switch (info->feature_barrier) {
- case QUEUE_ORDERED_DRAIN: barrier = "enabled (drain)"; break;
- case QUEUE_ORDERED_TAG: barrier = "enabled (tag)"; break;
- case QUEUE_ORDERED_NONE: barrier = "disabled"; break;
- default: return -EINVAL;
- }
-
- err = blk_queue_ordered(info->rq, info->feature_barrier);
-
- if (err)
- return err;
-
+ blk_queue_flush(info->rq, info->feature_flush);
printk(KERN_INFO "blkfront: %s: barriers %s\n",
- info->gd->disk_name, barrier);
- return 0;
+ info->gd->disk_name,
+ info->feature_flush ? "enabled" : "disabled");
}
@@ -516,7 +503,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
info->rq = gd->queue;
info->gd = gd;
- xlvbd_barrier(info);
+ xlvbd_flush(info);
if (vdisk_info & VDISK_READONLY)
set_disk_ro(gd, 1);
@@ -662,8 +649,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name);
error = -EOPNOTSUPP;
- info->feature_barrier = QUEUE_ORDERED_NONE;
- xlvbd_barrier(info);
+ info->feature_flush = 0;
+ xlvbd_flush(info);
}
/* fall through */
case BLKIF_OP_READ:
@@ -1076,20 +1063,13 @@ static void blkfront_connect(struct blkfront_info *info)
/*
* If there's no "feature-barrier" defined, then it means
* we're dealing with a very old backend which writes
- * synchronously; draining will do what needs to get done.
+ * synchronously; nothing to do.
*
- * If there are barriers, then we can do full queued writes
- * with tagged barriers.
- *
- * If barriers are not supported, then there's no much we can
- * do, so just set ordering to NONE.
+ * If there are barriers, then we use flush.
*/
- if (err)
- info->feature_barrier = QUEUE_ORDERED_DRAIN;
- else if (barrier)
- info->feature_barrier = QUEUE_ORDERED_TAG;
- else
- info->feature_barrier = QUEUE_ORDERED_NONE;
+ info->feature_flush = 0;
+ if (!err && barrier)
+ info->feature_flush = REQ_FLUSH;
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
if (err) {
@@ -1201,7 +1181,7 @@ static int blkif_open(struct block_device *bdev, fmode_t mode)
struct blkfront_info *info;
int err = 0;
- lock_kernel();
+ mutex_lock(&blkfront_mutex);
info = disk->private_data;
if (!info) {
@@ -1219,7 +1199,7 @@ static int blkif_open(struct block_device *bdev, fmode_t mode)
mutex_unlock(&info->mutex);
out:
- unlock_kernel();
+ mutex_unlock(&blkfront_mutex);
return err;
}
@@ -1229,7 +1209,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
struct block_device *bdev;
struct xenbus_device *xbdev;
- lock_kernel();
+ mutex_lock(&blkfront_mutex);
bdev = bdget_disk(disk, 0);
bdput(bdev);
@@ -1263,7 +1243,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
}
out:
- unlock_kernel();
+ mutex_unlock(&blkfront_mutex);
return 0;
}
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 057413bb16e2..6e968cd4893c 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,7 +89,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/platform_device.h>
@@ -214,6 +214,7 @@ struct ace_device {
u16 cf_id[ATA_ID_WORDS];
};
+static DEFINE_MUTEX(xsysace_mutex);
static int ace_major;
/* ---------------------------------------------------------------------
@@ -903,13 +904,13 @@ static int ace_open(struct block_device *bdev, fmode_t mode)
dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1);
- lock_kernel();
+ mutex_lock(&xsysace_mutex);
spin_lock_irqsave(&ace->lock, flags);
ace->users++;
spin_unlock_irqrestore(&ace->lock, flags);
check_disk_change(bdev);
- unlock_kernel();
+ mutex_unlock(&xsysace_mutex);
return 0;
}
@@ -922,7 +923,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1);
- lock_kernel();
+ mutex_lock(&xsysace_mutex);
spin_lock_irqsave(&ace->lock, flags);
ace->users--;
if (ace->users == 0) {
@@ -930,7 +931,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ);
}
spin_unlock_irqrestore(&ace->lock, flags);
- unlock_kernel();
+ mutex_unlock(&xsysace_mutex);
return 0;
}
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index d75b2bb601ad..dcd4cfcf4126 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -33,7 +33,7 @@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/bitops.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/setup.h>
@@ -57,6 +57,7 @@ extern struct mem_info m68k_memory[NUM_MEMINFO];
#define Z2RAM_CHUNK1024 ( Z2RAM_CHUNKSIZE >> 10 )
+static DEFINE_MUTEX(z2ram_mutex);
static u_long *z2ram_map = NULL;
static u_long z2ram_size = 0;
static int z2_count = 0;
@@ -154,7 +155,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode)
device = MINOR(bdev->bd_dev);
- lock_kernel();
+ mutex_lock(&z2ram_mutex);
if ( current_device != -1 && current_device != device )
{
rc = -EBUSY;
@@ -296,25 +297,25 @@ static int z2_open(struct block_device *bdev, fmode_t mode)
set_capacity(z2ram_gendisk, z2ram_size >> 9);
}
- unlock_kernel();
+ mutex_unlock(&z2ram_mutex);
return 0;
err_out_kfree:
kfree(z2ram_map);
err_out:
- unlock_kernel();
+ mutex_unlock(&z2ram_mutex);
return rc;
}
static int
z2_release(struct gendisk *disk, fmode_t mode)
{
- lock_kernel();
+ mutex_lock(&z2ram_mutex);
if ( current_device == -1 ) {
- unlock_kernel();
+ mutex_unlock(&z2ram_mutex);
return 0;
}
- unlock_kernel();
+ mutex_unlock(&z2ram_mutex);
/*
* FIXME: unmap memory
*/
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c
index 54739b08c308..c25df43a11d5 100644
--- a/drivers/bluetooth/btmrvl_debugfs.c
+++ b/drivers/bluetooth/btmrvl_debugfs.c
@@ -92,6 +92,7 @@ static const struct file_operations btmrvl_hscfgcmd_fops = {
.read = btmrvl_hscfgcmd_read,
.write = btmrvl_hscfgcmd_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
@@ -130,6 +131,7 @@ static const struct file_operations btmrvl_psmode_fops = {
.read = btmrvl_psmode_read,
.write = btmrvl_psmode_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
@@ -173,6 +175,7 @@ static const struct file_operations btmrvl_pscmd_fops = {
.read = btmrvl_pscmd_read,
.write = btmrvl_pscmd_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
@@ -211,6 +214,7 @@ static const struct file_operations btmrvl_gpiogap_fops = {
.read = btmrvl_gpiogap_read,
.write = btmrvl_gpiogap_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
@@ -252,6 +256,7 @@ static const struct file_operations btmrvl_hscmd_fops = {
.read = btmrvl_hscmd_read,
.write = btmrvl_hscmd_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
@@ -289,6 +294,7 @@ static const struct file_operations btmrvl_hsmode_fops = {
.read = btmrvl_hsmode_read,
.write = btmrvl_hsmode_write,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
@@ -306,6 +312,7 @@ static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_curpsmode_fops = {
.read = btmrvl_curpsmode_read,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
@@ -323,6 +330,7 @@ static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
static const struct file_operations btmrvl_psstate_fops = {
.read = btmrvl_psstate_read,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
@@ -340,6 +348,7 @@ static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hsstate_fops = {
.read = btmrvl_hsstate_read,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
@@ -358,6 +367,7 @@ static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_txdnldready_fops = {
.read = btmrvl_txdnldready_read,
.open = btmrvl_open_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
void btmrvl_debugfs_init(struct hci_dev *hdev)
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 3aa7b2a54b6f..f82c64068a44 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -282,6 +282,7 @@ static const struct file_operations vhci_fops = {
.poll = vhci_poll,
.open = vhci_open,
.release = vhci_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice vhci_miscdev= {
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 261107d1457c..3af6516919b7 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -34,7 +34,7 @@
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/device.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
@@ -81,6 +81,7 @@
#define GDROM_DEFAULT_TIMEOUT (HZ * 7)
+static DEFINE_MUTEX(gdrom_mutex);
static const struct {
int sense_key;
const char * const text;
@@ -494,17 +495,17 @@ static struct cdrom_device_ops gdrom_ops = {
static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&gdrom_mutex);
ret = cdrom_open(gd.cd_info, bdev, mode);
- unlock_kernel();
+ mutex_unlock(&gdrom_mutex);
return ret;
}
static int gdrom_bdops_release(struct gendisk *disk, fmode_t mode)
{
- lock_kernel();
+ mutex_lock(&gdrom_mutex);
cdrom_release(gd.cd_info, mode);
- unlock_kernel();
+ mutex_unlock(&gdrom_mutex);
return 0;
}
@@ -518,9 +519,9 @@ static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&gdrom_mutex);
ret = cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&gdrom_mutex);
return ret;
}
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 56bf9f44700c..be73a9b493a6 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -42,7 +42,7 @@
#include <linux/module.h>
#include <linux/completion.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
@@ -61,6 +61,7 @@
*/
#define VIOCD_MAX_CD HVMAXARCHITECTEDVIRTUALCDROMS
+static DEFINE_MUTEX(viocd_mutex);
static const struct vio_error_entry viocd_err_table[] = {
{0x0201, EINVAL, "Invalid Range"},
{0x0202, EINVAL, "Invalid Token"},
@@ -156,9 +157,9 @@ static int viocd_blk_open(struct block_device *bdev, fmode_t mode)
struct disk_info *di = bdev->bd_disk->private_data;
int ret;
- lock_kernel();
+ mutex_lock(&viocd_mutex);
ret = cdrom_open(&di->viocd_info, bdev, mode);
- unlock_kernel();
+ mutex_unlock(&viocd_mutex);
return ret;
}
@@ -166,9 +167,9 @@ static int viocd_blk_open(struct block_device *bdev, fmode_t mode)
static int viocd_blk_release(struct gendisk *disk, fmode_t mode)
{
struct disk_info *di = disk->private_data;
- lock_kernel();
+ mutex_lock(&viocd_mutex);
cdrom_release(&di->viocd_info, mode);
- unlock_kernel();
+ mutex_unlock(&viocd_mutex);
return 0;
}
@@ -178,9 +179,9 @@ static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode,
struct disk_info *di = bdev->bd_disk->private_data;
int ret;
- lock_kernel();
+ mutex_lock(&viocd_mutex);
ret = cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&viocd_mutex);
return ret;
}
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 3d44ec724c17..43d3395325c5 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -493,6 +493,21 @@ config LEGACY_PTY_COUNT
When not in use, each legacy PTY occupies 12 bytes on 32-bit
architectures and 24 bytes on 64-bit architectures.
+config TTY_PRINTK
+ bool "TTY driver to output user messages via printk"
+ depends on EMBEDDED
+ default n
+ ---help---
+ If you say Y here, the support for writing user messages (i.e.
+ console messages) via printk is available.
+
+ The feature is useful to inline user messages with kernel
+ messages.
+ In order to use this feature, you should output user messages
+ to /dev/ttyprintk or redirect console to this TTY.
+
+ If unsure, say N.
+
config BRIQ_PANEL
tristate 'Total Impact briQ front panel driver'
depends on PPC_CHRP
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index dc9641660605..3a9c01416839 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -12,6 +12,7 @@ obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o t
obj-y += tty_mutex.o
obj-$(CONFIG_LEGACY_PTYS) += pty.o
obj-$(CONFIG_UNIX98_PTYS) += pty.o
+obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
obj-y += misc.o
obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o selection.o keyboard.o
obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 70312da4c968..564808a5c3c0 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -199,7 +199,7 @@ static void amd64_cleanup(void)
struct pci_dev *dev = k8_northbridges[i];
/* disable gart translation */
pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &tmp);
- tmp &= ~AMD64_GARTEN;
+ tmp &= ~GARTEN;
pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, tmp);
}
}
@@ -313,7 +313,7 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order))
return -1;
- pci_write_config_dword(nb, AMD64_GARTAPERTURECTL, order << 1);
+ gart_set_size_and_enable(nb, order);
pci_write_config_dword(nb, AMD64_GARTAPERTUREBASE, aper >> 25);
return 0;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index d2abf5143983..64255cef8a7d 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -984,7 +984,9 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
bridge->driver->cache_flush();
#ifdef CONFIG_X86
- set_memory_uc((unsigned long)table, 1 << page_order);
+ if (set_memory_uc((unsigned long)table, 1 << page_order))
+ printk(KERN_WARNING "Could not set GATT table memory to UC!");
+
bridge->gatt_table = (void *)table;
#else
bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 710af89b176d..eab58db5f91c 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -12,6 +12,7 @@
#include <asm/smp.h>
#include "agp.h"
#include "intel-agp.h"
+#include <linux/intel-gtt.h>
#include "intel-gtt.c"
@@ -815,11 +816,19 @@ static const struct intel_driver_description {
"HD Graphics", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
"HD Graphics", NULL, &intel_i965_driver },
- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG,
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG,
"Sandybridge", NULL, &intel_gen6_driver },
- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG,
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG,
"Sandybridge", NULL, &intel_gen6_driver },
- { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG,
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG,
+ "Sandybridge", NULL, &intel_gen6_driver },
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG,
+ "Sandybridge", NULL, &intel_gen6_driver },
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG,
+ "Sandybridge", NULL, &intel_gen6_driver },
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG,
+ "Sandybridge", NULL, &intel_gen6_driver },
+ { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG,
"Sandybridge", NULL, &intel_gen6_driver },
{ 0, 0, NULL, NULL, NULL }
};
@@ -1044,6 +1053,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
+ ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
{ }
};
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h
index 08d47532e605..ee189c74d345 100644
--- a/drivers/char/agp/intel-agp.h
+++ b/drivers/char/agp/intel-agp.h
@@ -1,6 +1,8 @@
/*
* Common Intel AGPGART and GTT definitions.
*/
+#ifndef _INTEL_AGP_H
+#define _INTEL_AGP_H
/* Intel registers */
#define INTEL_APSIZE 0xb4
@@ -200,11 +202,16 @@
#define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
#define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a
#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106
-#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG 0x0126
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 /* Desktop */
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG 0x0102
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG 0x0112
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG 0x0122
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 /* Mobile */
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG 0x0106
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG 0x0116
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */
+#define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A
/* cover 915 and 945 variants */
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@@ -231,7 +238,8 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB)
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
@@ -244,3 +252,5 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \
IS_SNB)
+
+#endif
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index d22ffb811bf2..75e0a3497888 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -49,6 +49,26 @@ static struct gatt_mask intel_i810_masks[] =
.type = INTEL_AGP_CACHED_MEMORY}
};
+#define INTEL_AGP_UNCACHED_MEMORY 0
+#define INTEL_AGP_CACHED_MEMORY_LLC 1
+#define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2
+#define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3
+#define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4
+
+static struct gatt_mask intel_gen6_masks[] =
+{
+ {.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED,
+ .type = INTEL_AGP_UNCACHED_MEMORY },
+ {.mask = I810_PTE_VALID | GEN6_PTE_LLC,
+ .type = INTEL_AGP_CACHED_MEMORY_LLC },
+ {.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT,
+ .type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT },
+ {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC,
+ .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC },
+ {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT,
+ .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT },
+};
+
static struct _intel_private {
struct pci_dev *pcidev; /* device one */
u8 __iomem *registers;
@@ -178,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
off_t pg_start, int mask_type)
{
int i, j;
- u32 cache_bits = 0;
-
- if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
- {
- cache_bits = GEN6_PTE_LLC_MLC;
- }
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
@@ -317,6 +330,23 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge,
return 0;
}
+static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge,
+ int type)
+{
+ unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT;
+ unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT;
+
+ if (type_mask == AGP_USER_UNCACHED_MEMORY)
+ return INTEL_AGP_UNCACHED_MEMORY;
+ else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
+ return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT :
+ INTEL_AGP_CACHED_MEMORY_LLC_MLC;
+ else /* set 'normal'/'cached' to LLC by default */
+ return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT :
+ INTEL_AGP_CACHED_MEMORY_LLC;
+}
+
+
static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
int type)
{
@@ -588,8 +618,7 @@ static void intel_i830_init_gtt_entries(void)
gtt_entries = 0;
break;
}
- } else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) {
+ } else if (IS_SNB) {
/*
* SandyBridge has new memory control reg at 0x50.w
*/
@@ -1068,11 +1097,11 @@ static void intel_i9xx_setup_flush(void)
intel_i915_setup_chipset_flush();
}
- if (intel_private.ifp_resource.start) {
+ if (intel_private.ifp_resource.start)
intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE);
- if (!intel_private.i9xx_flush_page)
- dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing");
- }
+ if (!intel_private.i9xx_flush_page)
+ dev_err(&intel_private.pcidev->dev,
+ "can't ioremap flush page - no chipset flushing\n");
}
static int intel_i9xx_configure(void)
@@ -1163,7 +1192,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
- if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
+ if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY &&
mask_type != INTEL_AGP_CACHED_MEMORY)
goto out_err;
@@ -1333,8 +1362,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
dma_addr_t addr, int type)
{
- /* Shift high bits down */
- addr |= (addr >> 28) & 0xff;
+ /* gen6 has bit11-4 for physical addr bit39-32 */
+ addr |= (addr >> 28) & 0xff0;
/* Type checking must be done elsewhere */
return addr | bridge->driver->masks[type].mask;
@@ -1359,6 +1388,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
break;
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
+ case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB:
*gtt_offset = MB(2);
pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
@@ -1563,7 +1593,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
.fetch_size = intel_i9xx_fetch_size,
.cleanup = intel_i915_cleanup,
.mask_memory = intel_gen6_mask_memory,
- .masks = intel_i810_masks,
+ .masks = intel_gen6_masks,
.agp_enable = intel_i810_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = intel_i965_create_gatt_table,
@@ -1576,7 +1606,7 @@ static const struct agp_bridge_driver intel_gen6_driver = {
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
.agp_destroy_pages = agp_generic_destroy_pages,
- .agp_type_to_mask_type = intel_i830_type_to_mask_type,
+ .agp_type_to_mask_type = intel_gen6_type_to_mask_type,
.chipset_flush = intel_i915_chipset_flush,
#ifdef USE_PCI_DMA_API
.agp_map_page = intel_agp_map_page,
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index 033e1505fca9..39df1b608c40 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
@@ -126,6 +126,7 @@ struct apm_user {
/*
* Local variables
*/
+static DEFINE_MUTEX(apm_mutex);
static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
static int apm_disabled;
@@ -274,7 +275,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
if (!as->suser || !as->writer)
return -EPERM;
- lock_kernel();
+ mutex_lock(&apm_mutex);
switch (cmd) {
case APM_IOC_SUSPEND:
mutex_lock(&state_lock);
@@ -335,7 +336,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg)
mutex_unlock(&state_lock);
break;
}
- unlock_kernel();
+ mutex_unlock(&apm_mutex);
return err;
}
@@ -370,7 +371,7 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
- lock_kernel();
+ mutex_lock(&apm_mutex);
as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
@@ -390,7 +391,7 @@ static int apm_open(struct inode * inode, struct file * filp)
filp->private_data = as;
}
- unlock_kernel();
+ mutex_unlock(&apm_mutex);
return as ? 0 : -ENOMEM;
}
@@ -402,6 +403,7 @@ static const struct file_operations apm_bios_fops = {
.unlocked_ioctl = apm_ioctl,
.open = apm_open,
.release = apm_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice apm_device = {
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index f4ae0e0fb631..e7ba774beda6 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -26,7 +26,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <linux/wait.h>
@@ -60,6 +60,7 @@
#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
#endif
+static DEFINE_MUTEX(ac_mutex);
static char *applicom_pci_devnames[] = {
"PCI board",
"PCI2000IBS / PCI2000CAN",
@@ -707,7 +708,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (IS_ERR(adgl))
return PTR_ERR(adgl);
- lock_kernel();
+ mutex_lock(&ac_mutex);
IndexCard = adgl->num_card-1;
if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
@@ -717,7 +718,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
warncount--;
}
kfree(adgl);
- unlock_kernel();
+ mutex_unlock(&ac_mutex);
return -EINVAL;
}
@@ -835,7 +836,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
Dummy = readb(apbs[IndexCard].RamIO + VERS);
kfree(adgl);
- unlock_kernel();
+ mutex_unlock(&ac_mutex);
return 0;
}
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c
index 836d4f0a876f..53e55c40eebe 100644
--- a/drivers/char/bfin-otp.c
+++ b/drivers/char/bfin-otp.c
@@ -222,6 +222,7 @@ static const struct file_operations bfin_otp_fops = {
.unlocked_ioctl = bfin_otp_ioctl,
.read = bfin_otp_read,
.write = bfin_otp_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct miscdevice bfin_otp_misc_device = {
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index d5fa113afe37..ffd008de362a 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -186,6 +186,7 @@ static const struct file_operations briq_panel_fops = {
.write = briq_panel_write,
.open = briq_panel_open,
.release = briq_panel_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct miscdevice briq_panel_miscdev = {
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index 91917133ae0a..84cc95a7da5a 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -155,6 +155,7 @@ static const struct file_operations bsr_fops = {
.owner = THIS_MODULE,
.mmap = bsr_mmap,
.open = bsr_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static void bsr_cleanup_devs(void)
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 4d830dc482ef..b16c97782e2c 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -169,7 +169,8 @@ static const struct file_operations cs5535_gpio_fops = {
.owner = THIS_MODULE,
.write = cs5535_gpio_write,
.read = cs5535_gpio_read,
- .open = cs5535_gpio_open
+ .open = cs5535_gpio_open,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int __init cs5535_gpio_init(void)
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c
index 170693c93c73..06591818fc0c 100644
--- a/drivers/char/ds1302.c
+++ b/drivers/char/ds1302.c
@@ -20,7 +20,7 @@
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/bcd.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/io.h>
@@ -32,6 +32,7 @@
#define RTC_MAJOR_NR 121 /* local major, change later */
+static DEFINE_MUTEX(rtc_mutex);
static const char ds1302_name[] = "ds1302";
/* Send 8 bits. */
@@ -164,9 +165,9 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct rtc_time rtc_tm;
memset(&rtc_tm, 0, sizeof (struct rtc_time));
- lock_kernel();
+ mutex_lock(&rtc_mutex);
get_rtc_time(&rtc_tm);
- unlock_kernel();
+ mutex_unlock(&rtc_mutex);
if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
return -EFAULT;
return 0;
@@ -218,7 +219,7 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mon = bin2bcd(mon);
yrs = bin2bcd(yrs);
- lock_kernel();
+ mutex_lock(&rtc_mutex);
local_irq_save(flags);
CMOS_WRITE(yrs, RTC_YEAR);
CMOS_WRITE(mon, RTC_MONTH);
@@ -227,7 +228,7 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
CMOS_WRITE(min, RTC_MINUTES);
CMOS_WRITE(sec, RTC_SECONDS);
local_irq_restore(flags);
- unlock_kernel();
+ mutex_unlock(&rtc_mutex);
/* Notice that at this point, the RTC is updated but
* the kernel is still running with the old time.
@@ -247,10 +248,10 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
return -EFAULT;
- lock_kernel();
+ mutex_lock(&rtc_mutex);
tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
- unlock_kernel();
+ mutex_unlock(&rtc_mutex);
return 0;
}
default:
@@ -288,6 +289,7 @@ get_rtc_status(char *buf)
static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = rtc_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* Probe for the chip by writing something to its RAM and try reading it back. */
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index dbee8688f75c..290019cabd1f 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -8,7 +8,7 @@
#include <linux/proc_fs.h>
#include <linux/capability.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -34,6 +34,7 @@
#define CFG_CPU 2
#define CFG_1SHOT 1
+static DEFINE_MUTEX(ds1620_mutex);
static const char *fan_state[] = { "off", "on", "on (hardwired)" };
/*
@@ -210,7 +211,6 @@ static void ds1620_read_state(struct therm *therm)
static int ds1620_open(struct inode *inode, struct file *file)
{
- cycle_kernel_lock();
return nonseekable_open(inode, file);
}
@@ -321,9 +321,9 @@ ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&ds1620_mutex);
ret = ds1620_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ds1620_mutex);
return ret;
}
@@ -357,6 +357,7 @@ static const struct file_operations ds1620_fops = {
.open = ds1620_open,
.read = ds1620_read,
.unlocked_ioctl = ds1620_unlocked_ioctl,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice ds1620_miscdev = {
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 8a1b28a10ef0..30cd3b80ea69 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -32,7 +32,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/device.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h> /* For put_user and get_user */
@@ -94,6 +94,7 @@
} \
}
+static DEFINE_MUTEX(dsp56k_mutex);
static struct dsp56k_device {
unsigned long in_use;
long maxio, timeout;
@@ -330,9 +331,9 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd,
if (len > DSP56K_MAX_BINARY_LENGTH) {
return -EINVAL;
}
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
r = dsp56k_upload(bin, len);
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
if (r < 0) {
return r;
}
@@ -342,16 +343,16 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd,
case DSP56K_SET_TX_WSIZE:
if (arg > 4 || arg < 1)
return -EINVAL;
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
dsp56k.tx_wsize = (int) arg;
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
break;
case DSP56K_SET_RX_WSIZE:
if (arg > 4 || arg < 1)
return -EINVAL;
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
dsp56k.rx_wsize = (int) arg;
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
break;
case DSP56K_HOST_FLAGS:
{
@@ -363,7 +364,7 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd,
if(get_user(out, &hf->out) < 0)
return -EFAULT;
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
if ((dir & 0x1) && (out & 0x1))
dsp56k_host_interface.icr |= DSP56K_ICR_HF0;
else if (dir & 0x1)
@@ -378,16 +379,16 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd,
if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2;
if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4;
if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8;
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
return put_user(status, &hf->status);
}
case DSP56K_HOST_CMD:
if (arg > 31 || arg < 0)
return -EINVAL;
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) |
DSP56K_CVR_HC);
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
break;
default:
return -EINVAL;
@@ -427,7 +428,7 @@ static int dsp56k_open(struct inode *inode, struct file *file)
int dev = iminor(inode) & 0x0f;
int ret = 0;
- lock_kernel();
+ mutex_lock(&dsp56k_mutex);
switch(dev)
{
case DSP56K_DEV_56001:
@@ -454,7 +455,7 @@ static int dsp56k_open(struct inode *inode, struct file *file)
ret = -ENODEV;
}
out:
- unlock_kernel();
+ mutex_unlock(&dsp56k_mutex);
return ret;
}
@@ -482,6 +483,7 @@ static const struct file_operations dsp56k_fops = {
.unlocked_ioctl = dsp56k_ioctl,
.open = dsp56k_open,
.release = dsp56k_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index e3859d4eaead..9fff6a61086c 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -57,7 +57,7 @@
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
#include <linux/sched.h>
-#include <linux/smp_lock.h> /* cycle_kernel_lock() */
+#include <linux/mutex.h>
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
#include <linux/wait.h> /* for wait_queue */
@@ -73,6 +73,7 @@
#define TRACE_RET ((void) 0)
#endif /* TRACING */
+static DEFINE_MUTEX(dtlk_mutex);
static void dtlk_timer_tick(unsigned long data);
static int dtlk_major;
@@ -105,6 +106,7 @@ static const struct file_operations dtlk_fops =
.unlocked_ioctl = dtlk_ioctl,
.open = dtlk_open,
.release = dtlk_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/* local prototypes */
@@ -275,9 +277,9 @@ static long dtlk_ioctl(struct file *file,
switch (cmd) {
case DTLK_INTERROGATE:
- lock_kernel();
+ mutex_lock(&dtlk_mutex);
sp = dtlk_interrogate();
- unlock_kernel();
+ mutex_unlock(&dtlk_mutex);
if (copy_to_user(argp, sp, sizeof(struct dtlk_settings)))
return -EINVAL;
return 0;
@@ -296,7 +298,6 @@ static int dtlk_open(struct inode *inode, struct file *file)
{
TRACE_TEXT("(dtlk_open");
- cycle_kernel_lock();
nonseekable_open(inode, file);
switch (iminor(inode)) {
case DTLK_MINOR:
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index 82b5a88a82d7..0e941b57482e 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -19,7 +19,7 @@
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/nvram.h>
#ifdef CONFIG_PPC_PMAC
@@ -28,6 +28,7 @@
#define NVRAM_SIZE 8192
+static DEFINE_MUTEX(nvram_mutex);
static ssize_t nvram_len;
static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
@@ -120,9 +121,9 @@ static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned l
{
int ret;
- lock_kernel();
+ mutex_lock(&nvram_mutex);
ret = nvram_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&nvram_mutex);
return ret;
}
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index b6c2cc167c11..592853f6f645 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -52,7 +52,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <asm/uaccess.h>
@@ -66,6 +66,7 @@
* ioctls.
*/
+static DEFINE_MUTEX(gen_rtc_mutex);
static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait);
/*
@@ -337,9 +338,9 @@ static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd,
{
int ret;
- lock_kernel();
+ mutex_lock(&gen_rtc_mutex);
ret = gen_rtc_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&gen_rtc_mutex);
return ret;
}
@@ -352,16 +353,16 @@ static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd,
static int gen_rtc_open(struct inode *inode, struct file *file)
{
- lock_kernel();
+ mutex_lock(&gen_rtc_mutex);
if (gen_rtc_status & RTC_IS_OPEN) {
- unlock_kernel();
+ mutex_unlock(&gen_rtc_mutex);
return -EBUSY;
}
gen_rtc_status |= RTC_IS_OPEN;
gen_rtc_irq_data = 0;
irq_active = 0;
- unlock_kernel();
+ mutex_unlock(&gen_rtc_mutex);
return 0;
}
@@ -497,6 +498,7 @@ static const struct file_operations gen_rtc_fops = {
.unlocked_ioctl = gen_rtc_unlocked_ioctl,
.open = gen_rtc_open,
.release = gen_rtc_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice rtc_gen_dev =
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 3d9c61e5acbf..46918bd27de1 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -170,6 +170,7 @@ static const struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
.read = rng_dev_read,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice rng_miscdev = {
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 1acdb2509511..a3f5e381e746 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -387,7 +387,7 @@ static int n2rng_init_control(struct n2rng *np)
static int n2rng_data_read(struct hwrng *rng, u32 *data)
{
- struct n2rng *np = rng->priv;
+ struct n2rng *np = (struct n2rng *) rng->priv;
unsigned long ra = __pa(&np->test_data);
int len;
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 4cd8b227c11f..3bc0eef88717 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -23,7 +23,7 @@
#include <linux/seq_file.h>
#include <linux/dmi.h>
#include <linux/capability.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -56,6 +56,7 @@
#define I8K_TEMPERATURE_BUG 1
+static DEFINE_MUTEX(i8k_mutex);
static char bios_version[4];
MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
@@ -399,9 +400,9 @@ static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&i8k_mutex);
ret = i8k_ioctl_unlocked(fp, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&i8k_mutex);
return ret;
}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index d4b71e8d0d23..f6d980d055f0 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -98,7 +98,7 @@
#include <linux/major.h>
#include <linux/wait.h>
#include <linux/device.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
@@ -138,6 +138,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+static DEFINE_MUTEX(ip2_mutex);
static const struct file_operations ip2mem_proc_fops;
static const struct file_operations ip2_proc_fops;
@@ -236,6 +237,7 @@ static const struct file_operations ip2_ipl = {
.write = ip2_ipl_write,
.unlocked_ioctl = ip2_ipl_ioctl,
.open = ip2_ipl_open,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static unsigned long irq_counter;
@@ -2897,7 +2899,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
#endif
- lock_kernel();
+ mutex_lock(&ip2_mutex);
switch ( iplminor ) {
case 0: // IPL device
@@ -2961,7 +2963,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
rc = -ENODEV;
break;
}
- unlock_kernel();
+ mutex_unlock(&ip2_mutex);
return rc;
}
@@ -2982,7 +2984,6 @@ ip2_ipl_open( struct inode *pInode, struct file *pFile )
#ifdef IP2DEBUG_IPL
printk (KERN_DEBUG "IP2IPL: open\n" );
#endif
- cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index d8ec92a38980..65720485320e 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -44,7 +44,6 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/compat.h>
-#include <linux/smp_lock.h>
struct ipmi_file_private
{
@@ -59,6 +58,7 @@ struct ipmi_file_private
unsigned int default_retry_time_ms;
};
+static DEFINE_MUTEX(ipmi_mutex);
static void file_receive_handler(struct ipmi_recv_msg *msg,
void *handler_data)
{
@@ -102,9 +102,9 @@ static int ipmi_fasync(int fd, struct file *file, int on)
struct ipmi_file_private *priv = file->private_data;
int result;
- lock_kernel(); /* could race against open() otherwise */
+ mutex_lock(&ipmi_mutex); /* could race against open() otherwise */
result = fasync_helper(fd, file, on, &priv->fasync_queue);
- unlock_kernel();
+ mutex_unlock(&ipmi_mutex);
return (result);
}
@@ -125,7 +125,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
if (!priv)
return -ENOMEM;
- lock_kernel();
+ mutex_lock(&ipmi_mutex);
priv->file = file;
rv = ipmi_create_user(if_num,
@@ -150,7 +150,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
priv->default_retry_time_ms = 0;
out:
- unlock_kernel();
+ mutex_unlock(&ipmi_mutex);
return rv;
}
@@ -639,9 +639,9 @@ static long ipmi_unlocked_ioctl(struct file *file,
{
int ret;
- lock_kernel();
+ mutex_lock(&ipmi_mutex);
ret = ipmi_ioctl(file, cmd, data);
- unlock_kernel();
+ mutex_unlock(&ipmi_mutex);
return ret;
}
@@ -850,6 +850,7 @@ static const struct file_operations ipmi_fops = {
.release = ipmi_release,
.fasync = ipmi_fasync,
.poll = ipmi_poll,
+ .llseek = noop_llseek,/* no read or write fn */
};
#define DEVICE_NAME "ipmidev"
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 654d566ca57c..b8dd54589319 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -35,7 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/watchdog.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
@@ -149,6 +149,7 @@
#define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int)
#endif
+static DEFINE_MUTEX(ipmi_watchdog_mutex);
static int nowayout = WATCHDOG_NOWAYOUT;
static ipmi_user_t watchdog_user;
@@ -748,9 +749,9 @@ static long ipmi_unlocked_ioctl(struct file *file,
{
int ret;
- lock_kernel();
+ mutex_lock(&ipmi_watchdog_mutex);
ret = ipmi_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ipmi_watchdog_mutex);
return ret;
}
@@ -844,7 +845,6 @@ static int ipmi_open(struct inode *ino, struct file *filep)
if (test_and_set_bit(0, &ipmi_wdog_open))
return -EBUSY;
- cycle_kernel_lock();
/*
* Don't start the timer now, let it start on the
@@ -909,6 +909,7 @@ static const struct file_operations ipmi_wdog_fops = {
.open = ipmi_open,
.release = ipmi_close,
.fasync = ipmi_fasync,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice ipmi_wdog_miscdev = {
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index be28391adb79..d25b0856021e 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -704,6 +704,7 @@ static const struct file_operations stli_fsiomem = {
.read = stli_memread,
.write = stli_memwrite,
.unlocked_ioctl = stli_memioctl,
+ .llseek = default_llseek,/* read accesses f_pos */
};
/*****************************************************************************/
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index a7ca75212bfe..c24ea8993278 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -175,8 +175,7 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
*/
struct getset_keycode_data {
- unsigned int scancode;
- unsigned int keycode;
+ struct input_keymap_entry ke;
int error;
};
@@ -184,32 +183,50 @@ static int getkeycode_helper(struct input_handle *handle, void *data)
{
struct getset_keycode_data *d = data;
- d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode);
+ d->error = input_get_keycode(handle->dev, &d->ke);
return d->error == 0; /* stop as soon as we successfully get one */
}
int getkeycode(unsigned int scancode)
{
- struct getset_keycode_data d = { scancode, 0, -ENODEV };
+ struct getset_keycode_data d = {
+ .ke = {
+ .flags = 0,
+ .len = sizeof(scancode),
+ .keycode = 0,
+ },
+ .error = -ENODEV,
+ };
+
+ memcpy(d.ke.scancode, &scancode, sizeof(scancode));
input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
- return d.error ?: d.keycode;
+ return d.error ?: d.ke.keycode;
}
static int setkeycode_helper(struct input_handle *handle, void *data)
{
struct getset_keycode_data *d = data;
- d->error = input_set_keycode(handle->dev, d->scancode, d->keycode);
+ d->error = input_set_keycode(handle->dev, &d->ke);
return d->error == 0; /* stop as soon as we successfully set one */
}
int setkeycode(unsigned int scancode, unsigned int keycode)
{
- struct getset_keycode_data d = { scancode, keycode, -ENODEV };
+ struct getset_keycode_data d = {
+ .ke = {
+ .flags = 0,
+ .len = sizeof(scancode),
+ .keycode = keycode,
+ },
+ .error = -ENODEV,
+ };
+
+ memcpy(d.ke.scancode, &scancode, sizeof(scancode));
input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
@@ -363,6 +380,43 @@ static void to_utf8(struct vc_data *vc, uint c)
}
}
+#ifdef CONFIG_KDB_KEYBOARD
+static int kbd_clear_keys_helper(struct input_handle *handle, void *data)
+{
+ unsigned int *keycode = data;
+ input_inject_event(handle, EV_KEY, *keycode, 0);
+ return 0;
+}
+
+static void kbd_clear_keys_callback(struct work_struct *dummy)
+{
+ unsigned int i, j, k;
+
+ for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+ if (!key_down[i])
+ continue;
+
+ k = i * BITS_PER_LONG;
+
+ for (j = 0; j < BITS_PER_LONG; j++, k++) {
+ if (!test_bit(k, key_down))
+ continue;
+ input_handler_for_each_handle(&kbd_handler, &k,
+ kbd_clear_keys_helper);
+ }
+ }
+}
+
+static DECLARE_WORK(kbd_clear_keys_work, kbd_clear_keys_callback);
+
+/* Called to clear any key presses after resuming the kernel. */
+void kbd_dbg_clear_keys(void)
+{
+ schedule_work(&kbd_clear_keys_work);
+}
+EXPORT_SYMBOL_GPL(kbd_dbg_clear_keys);
+#endif /* CONFIG_KDB_KEYBOARD */
+
/*
* Called after returning from RAW mode or when changing consoles - recompute
* shift_down[] and shift_state from key_down[] maybe called when keymap is
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 938a3a273886..fa01df1c4cb5 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -126,7 +126,7 @@
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compat.h>
#include <linux/parport.h>
@@ -140,6 +140,7 @@
/* if you have more than 8 printers, remember to increase LP_NO */
#define LP_NO 8
+static DEFINE_MUTEX(lp_mutex);
static struct lp_struct lp_table[LP_NO];
static unsigned int lp_count = 0;
@@ -493,7 +494,7 @@ static int lp_open(struct inode * inode, struct file * file)
unsigned int minor = iminor(inode);
int ret = 0;
- lock_kernel();
+ mutex_lock(&lp_mutex);
if (minor >= LP_NO) {
ret = -ENXIO;
goto out;
@@ -554,7 +555,7 @@ static int lp_open(struct inode * inode, struct file * file)
lp_release_parport (&lp_table[minor]);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
out:
- unlock_kernel();
+ mutex_unlock(&lp_mutex);
return ret;
}
@@ -680,7 +681,7 @@ static long lp_ioctl(struct file *file, unsigned int cmd,
int ret;
minor = iminor(file->f_path.dentry->d_inode);
- lock_kernel();
+ mutex_lock(&lp_mutex);
switch (cmd) {
case LPSETTIMEOUT:
if (copy_from_user(&par_timeout, (void __user *)arg,
@@ -694,7 +695,7 @@ static long lp_ioctl(struct file *file, unsigned int cmd,
ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg);
break;
}
- unlock_kernel();
+ mutex_unlock(&lp_mutex);
return ret;
}
@@ -709,7 +710,7 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd,
int ret;
minor = iminor(file->f_path.dentry->d_inode);
- lock_kernel();
+ mutex_lock(&lp_mutex);
switch (cmd) {
case LPSETTIMEOUT:
tc = compat_ptr(arg);
@@ -730,7 +731,7 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd,
ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg));
break;
}
- unlock_kernel();
+ mutex_unlock(&lp_mutex);
return ret;
}
@@ -748,6 +749,7 @@ static const struct file_operations lp_fops = {
#ifdef CONFIG_PARPORT_1284
.read = lp_read,
#endif
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/* --- support for console on the line printer ----------------- */
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 83bef4efe376..1aeaaba680d2 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/uio.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -42,6 +41,7 @@
#else
#define DBG(fmt...)
#endif
+static DEFINE_MUTEX(mbcs_mutex);
static int mbcs_major;
static LIST_HEAD(soft_list);
@@ -385,19 +385,19 @@ static int mbcs_open(struct inode *ip, struct file *fp)
struct mbcs_soft *soft;
int minor;
- lock_kernel();
+ mutex_lock(&mbcs_mutex);
minor = iminor(ip);
/* Nothing protects access to this list... */
list_for_each_entry(soft, &soft_list, list) {
if (soft->nasid == minor) {
fp->private_data = soft->cxdev;
- unlock_kernel();
+ mutex_unlock(&mbcs_mutex);
return 0;
}
}
- unlock_kernel();
+ mutex_unlock(&mbcs_mutex);
return -ENODEV;
}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index a398ecdbd758..3a7ad8b01d47 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -804,6 +804,7 @@ static const struct file_operations full_fops = {
static const struct file_operations oldmem_fops = {
.read = read_oldmem,
.open = open_oldmem,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif
@@ -830,6 +831,7 @@ static ssize_t kmsg_write(struct file *file, const char __user *buf,
static const struct file_operations kmsg_fops = {
.write = kmsg_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static const struct memdev {
@@ -881,6 +883,7 @@ static int memory_open(struct inode *inode, struct file *filp)
static const struct file_operations memory_fops = {
.open = memory_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static char *mem_devnode(struct device *dev, mode_t *mode)
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index abdafd488980..c75196d1888a 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -162,6 +162,7 @@ static struct class *misc_class;
static const struct file_operations misc_fops = {
.owner = THIS_MODULE,
.open = misc_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
/**
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index ea7c99fa978f..f11bf22c53f3 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -32,7 +32,7 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/math64.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -59,6 +59,7 @@ extern unsigned long sn_rtc_cycles_per_second;
#define rtc_time() (*RTC_COUNTER_ADDR)
+static DEFINE_MUTEX(mmtimer_mutex);
static long mmtimer_ioctl(struct file *file, unsigned int cmd,
unsigned long arg);
static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma);
@@ -72,6 +73,7 @@ static const struct file_operations mmtimer_fops = {
.owner = THIS_MODULE,
.mmap = mmtimer_mmap,
.unlocked_ioctl = mmtimer_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
@@ -371,7 +373,7 @@ static long mmtimer_ioctl(struct file *file, unsigned int cmd,
{
int ret = 0;
- lock_kernel();
+ mutex_lock(&mmtimer_mutex);
switch (cmd) {
case MMTIMER_GETOFFSET: /* offset of the counter */
@@ -414,7 +416,7 @@ static long mmtimer_ioctl(struct file *file, unsigned int cmd,
ret = -ENOTTY;
break;
}
- unlock_kernel();
+ mutex_unlock(&mmtimer_mutex);
return ret;
}
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index ecb89d798e35..2168bf2faa72 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -316,7 +316,8 @@ uncached_mmap(struct file *file, struct vm_area_struct *vma)
static const struct file_operations fetchop_fops = {
.owner = THIS_MODULE,
- .mmap = fetchop_mmap
+ .mmap = fetchop_mmap,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice fetchop_miscdev = {
@@ -327,7 +328,8 @@ static struct miscdevice fetchop_miscdev = {
static const struct file_operations cached_fops = {
.owner = THIS_MODULE,
- .mmap = cached_mmap
+ .mmap = cached_mmap,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice cached_miscdev = {
@@ -338,7 +340,8 @@ static struct miscdevice cached_miscdev = {
static const struct file_operations uncached_fops = {
.owner = THIS_MODULE,
- .mmap = uncached_mmap
+ .mmap = uncached_mmap,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice uncached_miscdev = {
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index a4ec50c95072..4de7fd07565f 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -56,7 +56,7 @@
#include <linux/serial.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/serial_8250.h>
#include "smapi.h"
@@ -73,6 +73,7 @@ MODULE_LICENSE("GPL");
* checks are made against other devices (ie. superio) for conflicts.
* We'll depend on users using the tpctl utility to do that for now
*/
+static DEFINE_MUTEX(mwave_mutex);
int mwave_debug = 0;
int mwave_3780i_irq = 0;
int mwave_3780i_io = 0;
@@ -101,7 +102,6 @@ static int mwave_open(struct inode *inode, struct file *file)
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_open, exit return retval %x\n", retval);
- cycle_kernel_lock();
return retval;
}
@@ -136,9 +136,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
PRINTK_1(TRACE_MWAVE,
"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
" calling tp3780I_ResetDSP\n");
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_ResetDSP(&pDrvData->rBDData);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
" retval %x from tp3780I_ResetDSP\n",
@@ -149,9 +149,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
PRINTK_1(TRACE_MWAVE,
"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
" calling tp3780I_StartDSP\n");
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_StartDSP(&pDrvData->rBDData);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
" retval %x from tp3780I_StartDSP\n",
@@ -165,10 +165,10 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
"mwavedd::mwave_ioctl,"
" IOCTL_MW_DSP_ABILITIES calling"
" tp3780I_QueryAbilities\n");
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
&rAbilities);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
" retval %x from tp3780I_QueryAbilities\n",
@@ -199,13 +199,13 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
" size %lx, ioarg %lx pusBuffer %p\n",
rReadData.ulDataLength, ioarg, pusBuffer);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
iocmd,
pusBuffer,
rReadData.ulDataLength,
rReadData.usDspAddress);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -223,12 +223,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
" size %lx, ioarg %lx pusBuffer %p\n",
rReadData.ulDataLength / 2, ioarg,
pusBuffer);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
iocmd, pusBuffer,
rReadData.ulDataLength / 2,
rReadData.usDspAddress);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -246,12 +246,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
" size %lx, ioarg %lx pusBuffer %p\n",
rWriteData.ulDataLength, ioarg,
pusBuffer);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
iocmd, pusBuffer,
rWriteData.ulDataLength,
rWriteData.usDspAddress);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -269,12 +269,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
" size %lx, ioarg %lx pusBuffer %p\n",
rWriteData.ulDataLength, ioarg,
pusBuffer);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
iocmd, pusBuffer,
rWriteData.ulDataLength,
rWriteData.usDspAddress);
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -295,10 +295,10 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
ipcnum,
pDrvData->IPCs[ipcnum].usIntCount);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
pDrvData->IPCs[ipcnum].bIsHere = FALSE;
pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
@@ -323,7 +323,7 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
ipcnum,
pDrvData->IPCs[ipcnum].usIntCount);
- lock_kernel();
+ mutex_lock(&mwave_mutex);
if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
DECLARE_WAITQUEUE(wait, current);
@@ -364,7 +364,7 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
" processing\n",
ipcnum);
}
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -383,14 +383,14 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd,
ipcnum);
return -EINVAL;
}
- lock_kernel();
+ mutex_lock(&mwave_mutex);
if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
pDrvData->IPCs[ipcnum].bIsEnabled = FALSE;
if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) {
wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
}
}
- unlock_kernel();
+ mutex_unlock(&mwave_mutex);
}
break;
@@ -479,7 +479,8 @@ static const struct file_operations mwave_fops = {
.write = mwave_write,
.unlocked_ioctl = mwave_ioctl,
.open = mwave_open,
- .release = mwave_close
+ .release = mwave_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 3fc89da856ae..9d243de795df 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -2339,20 +2339,11 @@ struct tty_port_operations mxser_port_ops = {
* The MOXA Smartio/Industio serial driver boot-time initialization code!
*/
-static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
- unsigned int irq)
+static void mxser_release_ISA_res(struct mxser_board *brd)
{
- if (irq)
- free_irq(brd->irq, brd);
- if (pdev != NULL) { /* PCI */
-#ifdef CONFIG_PCI
- pci_release_region(pdev, 2);
- pci_release_region(pdev, 3);
-#endif
- } else {
- release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
- release_region(brd->vector, 1);
- }
+ free_irq(brd->irq, brd);
+ release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
+ release_region(brd->vector, 1);
}
static int __devinit mxser_initbrd(struct mxser_board *brd,
@@ -2397,13 +2388,11 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
brd);
- if (retval) {
+ if (retval)
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
"conflict with another device.\n",
brd->info->name, brd->irq);
- /* We hold resources, we need to release them. */
- mxser_release_res(brd, pdev, 0);
- }
+
return retval;
}
@@ -2555,7 +2544,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
ioaddress = pci_resource_start(pdev, 2);
retval = pci_request_region(pdev, 2, "mxser(IO)");
if (retval)
- goto err;
+ goto err_dis;
brd->info = &mxser_cards[ent->driver_data];
for (i = 0; i < brd->info->nports; i++)
@@ -2565,7 +2554,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
ioaddress = pci_resource_start(pdev, 3);
retval = pci_request_region(pdev, 3, "mxser(vector)");
if (retval)
- goto err_relio;
+ goto err_zero;
brd->vector = ioaddress;
/* irq */
@@ -2608,7 +2597,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
/* mxser_initbrd will hook ISR. */
retval = mxser_initbrd(brd, pdev);
if (retval)
- goto err_null;
+ goto err_rel3;
for (i = 0; i < brd->info->nports; i++)
tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev);
@@ -2616,10 +2605,13 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, brd);
return 0;
-err_relio:
- pci_release_region(pdev, 2);
-err_null:
+err_rel3:
+ pci_release_region(pdev, 3);
+err_zero:
brd->info = NULL;
+ pci_release_region(pdev, 2);
+err_dis:
+ pci_disable_device(pdev);
err:
return retval;
#else
@@ -2629,14 +2621,19 @@ err:
static void __devexit mxser_remove(struct pci_dev *pdev)
{
+#ifdef CONFIG_PCI
struct mxser_board *brd = pci_get_drvdata(pdev);
unsigned int i;
for (i = 0; i < brd->info->nports; i++)
tty_unregister_device(mxvar_sdriver, brd->idx + i);
- mxser_release_res(brd, pdev, 1);
+ free_irq(pdev->irq, brd);
+ pci_release_region(pdev, 2);
+ pci_release_region(pdev, 3);
+ pci_disable_device(pdev);
brd->info = NULL;
+#endif
}
static struct pci_driver mxser_driver = {
@@ -2741,7 +2738,7 @@ static void __exit mxser_module_exit(void)
for (i = 0; i < MXSER_BOARDS; i++)
if (mxser_boards[i].info != NULL)
- mxser_release_res(&mxser_boards[i], NULL, 1);
+ mxser_release_ISA_res(&mxser_boards[i]);
}
module_init(mxser_module_init);
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 66d2917b003f..166f1e7aaa7e 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -109,10 +109,11 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/uaccess.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/system.h>
+static DEFINE_MUTEX(nvram_mutex);
static DEFINE_SPINLOCK(nvram_state_lock);
static int nvram_open_cnt; /* #times opened */
static int nvram_open_mode; /* special open modes */
@@ -308,7 +309,7 @@ static long nvram_ioctl(struct file *file, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- lock_kernel();
+ mutex_lock(&nvram_mutex);
spin_lock_irq(&rtc_lock);
for (i = 0; i < NVRAM_BYTES; ++i)
@@ -316,7 +317,7 @@ static long nvram_ioctl(struct file *file, unsigned int cmd,
__nvram_set_checksum();
spin_unlock_irq(&rtc_lock);
- unlock_kernel();
+ mutex_unlock(&nvram_mutex);
return 0;
case NVRAM_SETCKS:
@@ -325,11 +326,11 @@ static long nvram_ioctl(struct file *file, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- lock_kernel();
+ mutex_lock(&nvram_mutex);
spin_lock_irq(&rtc_lock);
__nvram_set_checksum();
spin_unlock_irq(&rtc_lock);
- unlock_kernel();
+ mutex_unlock(&nvram_mutex);
return 0;
default:
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 2604246501e4..fcf7c21306ff 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -182,6 +182,7 @@ static int button_read (struct file *filp, char __user *buffer,
static const struct file_operations button_fops = {
.owner = THIS_MODULE,
.read = button_read,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
/*
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index 043a1c7b86be..a12f52400dbc 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -25,7 +25,6 @@
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
@@ -41,6 +40,7 @@
#define NWFLASH_VERSION "6.4"
+static DEFINE_MUTEX(flash_mutex);
static void kick_open(void);
static int get_flash_id(void);
static int erase_block(int nBlock);
@@ -96,7 +96,7 @@ static int get_flash_id(void)
static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
- lock_kernel();
+ mutex_lock(&flash_mutex);
switch (cmd) {
case CMD_WRITE_DISABLE:
gbWriteBase64Enable = 0;
@@ -114,10 +114,10 @@ static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
default:
gbWriteBase64Enable = 0;
gbWriteEnable = 0;
- unlock_kernel();
+ mutex_unlock(&flash_mutex);
return -EINVAL;
}
- unlock_kernel();
+ mutex_unlock(&flash_mutex);
return 0;
}
@@ -282,7 +282,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
{
loff_t ret;
- lock_kernel();
+ mutex_lock(&flash_mutex);
if (flashdebug)
printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
(unsigned int) offset, orig);
@@ -317,7 +317,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
default:
ret = -EINVAL;
}
- unlock_kernel();
+ mutex_unlock(&flash_mutex);
return ret;
}
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index 8ecbcc174c15..a93a0f783970 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -234,6 +234,7 @@ static const struct file_operations pc8736x_gpio_fileops = {
.open = pc8736x_gpio_open,
.write = nsc_gpio_write,
.read = nsc_gpio_read,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static void __init pc8736x_init_shadow(void)
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index ec73d9f6d9ed..252aaf465d49 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -30,7 +30,7 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/bitrev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/io.h>
@@ -55,6 +55,7 @@
__func__ , ## args); \
} while (0)
+static DEFINE_MUTEX(cmm_mutex);
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
#define T_1SEC (HZ)
@@ -1418,7 +1419,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
#endif
- lock_kernel();
+ mutex_lock(&cmm_mutex);
rc = -ENODEV;
link = dev_table[iminor(inode)];
if (!pcmcia_dev_present(link)) {
@@ -1626,7 +1627,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
rc = -ENOTTY;
}
out:
- unlock_kernel();
+ mutex_unlock(&cmm_mutex);
return rc;
}
@@ -1640,7 +1641,7 @@ static int cmm_open(struct inode *inode, struct file *filp)
if (minor >= CM4000_MAX_DEV)
return -ENODEV;
- lock_kernel();
+ mutex_lock(&cmm_mutex);
link = dev_table[minor];
if (link == NULL || !pcmcia_dev_present(link)) {
ret = -ENODEV;
@@ -1685,7 +1686,7 @@ static int cmm_open(struct inode *inode, struct file *filp)
DEBUGP(2, dev, "<- cmm_open\n");
ret = nonseekable_open(inode, filp);
out:
- unlock_kernel();
+ mutex_unlock(&cmm_mutex);
return ret;
}
@@ -1880,6 +1881,7 @@ static const struct file_operations cm4000_fops = {
.unlocked_ioctl = cmm_ioctl,
.open = cmm_open,
.release= cmm_close,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct pcmcia_device_id cm4000_ids[] = {
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 815cde1d0570..67957a23cb7c 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -24,7 +24,7 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -49,6 +49,7 @@
__func__ , ## args); \
} while (0)
+static DEFINE_MUTEX(cm4040_mutex);
static char *version =
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
@@ -444,7 +445,7 @@ static int cm4040_open(struct inode *inode, struct file *filp)
if (minor >= CM_MAX_DEV)
return -ENODEV;
- lock_kernel();
+ mutex_lock(&cm4040_mutex);
link = dev_table[minor];
if (link == NULL || !pcmcia_dev_present(link)) {
ret = -ENODEV;
@@ -473,7 +474,7 @@ static int cm4040_open(struct inode *inode, struct file *filp)
DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
ret = nonseekable_open(inode, filp);
out:
- unlock_kernel();
+ mutex_unlock(&cm4040_mutex);
return ret;
}
@@ -650,6 +651,7 @@ static const struct file_operations reader_fops = {
.open = cm4040_open,
.release = cm4040_close,
.poll = cm4040_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct pcmcia_device_id cm4040_ids[] = {
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 02abfddce45a..723152d978a9 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -67,7 +67,7 @@
#include <linux/slab.h>
#include <linux/major.h>
#include <linux/ppdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/uaccess.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -97,6 +97,7 @@ struct pp_struct {
/* ROUND_UP macro from fs/select.c */
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+static DEFINE_MUTEX(pp_do_mutex);
static inline void pp_enable_irq (struct pp_struct *pp)
{
struct parport *port = pp->pdev->port;
@@ -630,9 +631,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&pp_do_mutex);
ret = pp_do_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pp_do_mutex);
return ret;
}
@@ -641,7 +642,6 @@ static int pp_open (struct inode * inode, struct file * file)
unsigned int minor = iminor(inode);
struct pp_struct *pp;
- cycle_kernel_lock();
if (minor >= PARPORT_MAX)
return -ENXIO;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index c350d01716bd..923a48585501 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -676,7 +676,9 @@ static int ptmx_open(struct inode *inode, struct file *filp)
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
- tty_add_file(tty, filp);
+ retval = tty_add_file(tty, filp);
+ if (retval)
+ goto out;
retval = devpts_pty_new(inode, tty->link);
if (retval)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index caef35a46890..3dbd4f25831d 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1165,6 +1165,7 @@ const struct file_operations random_fops = {
.poll = random_poll,
.unlocked_ioctl = random_ioctl,
.fasync = random_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
const struct file_operations urandom_fops = {
@@ -1172,6 +1173,7 @@ const struct file_operations urandom_fops = {
.write = random_write,
.unlocked_ioctl = random_ioctl,
.fasync = random_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/***************************************************************
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 24b2b9160aa6..bfe25ea9766b 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -292,6 +292,7 @@ static const struct file_operations raw_fops = {
.open = raw_open,
.release = raw_release,
.unlocked_ioctl = raw_ioctl,
+ .llseek = default_llseek,
.owner = THIS_MODULE,
};
@@ -302,6 +303,7 @@ static const struct file_operations raw_ctl_fops = {
#endif
.open = raw_open,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,
};
static struct cdev raw_cdev;
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index d58c2eb07f07..4253e187669b 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -44,7 +44,7 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
@@ -122,6 +122,7 @@ more than 512 ports.... */
/* These constants are derived from SCO Source */
+static DEFINE_MUTEX(rio_fw_mutex);
static struct Conf
RIOConf = {
/* locator */ "RIO Config here",
@@ -241,6 +242,7 @@ static struct real_driver rio_real_driver = {
static const struct file_operations rio_fw_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = rio_fw_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice rio_fw_device = {
@@ -566,9 +568,9 @@ static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
func_enter();
/* The "dev" argument isn't used. */
- lock_kernel();
+ mutex_lock(&rio_fw_mutex);
rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN));
- unlock_kernel();
+ mutex_unlock(&rio_fw_mutex);
func_exit();
return rc;
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 99e5272e3c53..9574028ba7a6 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -67,6 +67,7 @@ static const struct file_operations scx200_gpio_fileops = {
.read = nsc_gpio_read,
.open = scx200_gpio_open,
.release = scx200_gpio_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 32b74de18f5f..24fd32b6fedf 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -21,7 +21,7 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/module.h>
@@ -34,6 +34,7 @@
#define SCDRV_BUFSZ 2048
#define SCDRV_TIMEOUT 1000
+static DEFINE_MUTEX(scdrv_mutex);
static irqreturn_t
scdrv_interrupt(int irq, void *subch_data)
{
@@ -105,7 +106,7 @@ scdrv_open(struct inode *inode, struct file *file)
file->private_data = sd;
/* hook this subchannel up to the system controller interrupt */
- lock_kernel();
+ mutex_lock(&scdrv_mutex);
rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
IRQF_SHARED | IRQF_DISABLED,
SYSCTL_BASENAME, sd);
@@ -113,10 +114,10 @@ scdrv_open(struct inode *inode, struct file *file)
ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
kfree(sd);
printk("%s: irq request failed (%d)\n", __func__, rv);
- unlock_kernel();
+ mutex_unlock(&scdrv_mutex);
return -EBUSY;
}
- unlock_kernel();
+ mutex_unlock(&scdrv_mutex);
return 0;
}
@@ -357,6 +358,7 @@ static const struct file_operations scdrv_fops = {
.poll = scdrv_poll,
.open = scdrv_open,
.release = scdrv_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct class *snsc_class;
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index f2167f8e5aab..f0cd08bbeb46 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -608,6 +608,7 @@ static unsigned int sc26198_baudtable[] = {
static const struct file_operations stl_fsiomem = {
.owner = THIS_MODULE,
.unlocked_ioctl = stl_memioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct class *stallion_class;
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 5b24db4ff7f1..a172543c6c93 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -397,6 +397,7 @@ static struct real_driver sx_real_driver = {
static const struct file_operations sx_fw_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = sx_fw_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice sx_fw_device = {
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ef31bb81e843..a2ab2180b784 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -772,6 +772,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
static const struct file_operations proc_sysrq_trigger_operations = {
.write = write_sysrq_trigger,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static void sysrq_init_procfs(void)
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index cad4eb65f13d..789e9dfdb20e 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -261,6 +261,7 @@ static const struct file_operations tb0219_fops = {
.write = tanbac_tb0219_write,
.open = tanbac_tb0219_open,
.release = tanbac_tb0219_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static void tb0219_restart(char *command)
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index e32cbf0c9a0b..253698dca5d5 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -268,6 +268,7 @@ static const struct file_operations tlclk_fops = {
.open = tlclk_open,
.release = tlclk_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice tlclk_miscdev = {
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index f8bc79f6de34..c3fd9bd170bb 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -68,7 +68,7 @@
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/toshiba.h>
#define TOSH_MINOR_DEV 181
@@ -78,6 +78,7 @@ MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
MODULE_DESCRIPTION("Toshiba laptop SMM driver");
MODULE_SUPPORTED_DEVICE("toshiba");
+static DEFINE_MUTEX(tosh_mutex);
static int tosh_fn;
module_param_named(fn, tosh_fn, int, 0);
MODULE_PARM_DESC(fn, "User specified Fn key detection port");
@@ -95,6 +96,7 @@ static long tosh_ioctl(struct file *, unsigned int,
static const struct file_operations tosh_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tosh_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice tosh_device = {
@@ -274,16 +276,16 @@ static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
return -EINVAL;
/* do we need to emulate the fan ? */
- lock_kernel();
+ mutex_lock(&tosh_mutex);
if (tosh_fan==1) {
if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) {
err = tosh_emulate_fan(&regs);
- unlock_kernel();
+ mutex_unlock(&tosh_mutex);
break;
}
}
err = tosh_smm(&regs);
- unlock_kernel();
+ mutex_unlock(&tosh_mutex);
break;
default:
return -EINVAL;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 949067a0bd47..e185db36f8ad 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -183,6 +183,8 @@ struct tty_struct *alloc_tty_struct(void)
void free_tty_struct(struct tty_struct *tty)
{
+ if (tty->dev)
+ put_device(tty->dev);
kfree(tty->write_buf);
tty_buffer_free_all(tty);
kfree(tty);
@@ -194,12 +196,13 @@ static inline struct tty_struct *file_tty(struct file *file)
}
/* Associate a new file with the tty structure */
-void tty_add_file(struct tty_struct *tty, struct file *file)
+int tty_add_file(struct tty_struct *tty, struct file *file)
{
struct tty_file_private *priv;
- /* XXX: must implement proper error handling in callers */
- priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
+ priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
priv->tty = tty;
priv->file = file;
@@ -208,6 +211,8 @@ void tty_add_file(struct tty_struct *tty, struct file *file)
spin_lock(&tty_files_lock);
list_add(&priv->list, &tty->tty_files);
spin_unlock(&tty_files_lock);
+
+ return 0;
}
/* Delete file from its tty */
@@ -355,7 +360,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
if (*stp == '\0')
stp = NULL;
- if (tty_line >= 0 && tty_line <= p->num && p->ops &&
+ if (tty_line >= 0 && tty_line < p->num && p->ops &&
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
res = tty_driver_kref_get(p);
*line = tty_line;
@@ -1875,7 +1880,11 @@ got_driver:
return PTR_ERR(tty);
}
- tty_add_file(tty, filp);
+ retval = tty_add_file(tty, filp);
+ if (retval) {
+ tty_unlock();
+ return retval;
+ }
check_tty_count(tty, "tty_open");
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -2783,6 +2792,20 @@ void do_SAK(struct tty_struct *tty)
EXPORT_SYMBOL(do_SAK);
+static int dev_match_devt(struct device *dev, void *data)
+{
+ dev_t *devt = data;
+ return dev->devt == *devt;
+}
+
+/* Must put_device() after it's unused! */
+static struct device *tty_get_device(struct tty_struct *tty)
+{
+ dev_t devt = tty_devnum(tty);
+ return class_find_device(tty_class, NULL, &devt, dev_match_devt);
+}
+
+
/**
* initialize_tty_struct
* @tty: tty to initialize
@@ -2823,6 +2846,7 @@ void initialize_tty_struct(struct tty_struct *tty,
tty->ops = driver->ops;
tty->index = idx;
tty_line_name(driver, idx, tty->name);
+ tty->dev = tty_get_device(tty);
}
/**
@@ -2980,6 +3004,7 @@ int tty_register_driver(struct tty_driver *driver)
int i;
dev_t dev;
void **p = NULL;
+ struct device *d;
if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
@@ -3027,12 +3052,31 @@ int tty_register_driver(struct tty_driver *driver)
mutex_unlock(&tty_mutex);
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
- for (i = 0; i < driver->num; i++)
- tty_register_device(driver, i, NULL);
+ for (i = 0; i < driver->num; i++) {
+ d = tty_register_device(driver, i, NULL);
+ if (IS_ERR(d)) {
+ error = PTR_ERR(d);
+ goto err;
+ }
+ }
}
proc_tty_register_driver(driver);
driver->flags |= TTY_DRIVER_INSTALLED;
return 0;
+
+err:
+ for (i--; i >= 0; i--)
+ tty_unregister_device(driver, i);
+
+ mutex_lock(&tty_mutex);
+ list_del(&driver->tty_drivers);
+ mutex_unlock(&tty_mutex);
+
+ unregister_chrdev_region(dev, driver->num);
+ driver->ttys = NULL;
+ driver->termios = NULL;
+ kfree(p);
+ return error;
}
EXPORT_SYMBOL(tty_register_driver);
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
new file mode 100644
index 000000000000..c40c1612c8a7
--- /dev/null
+++ b/drivers/char/ttyprintk.c
@@ -0,0 +1,225 @@
+/*
+ * linux/drivers/char/ttyprintk.c
+ *
+ * Copyright (C) 2010 Samo Pogacnik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the smems of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+/*
+ * This pseudo device allows user to make printk messages. It is possible
+ * to store "console" messages inline with kernel messages for better analyses
+ * of the boot process, for example.
+ */
+
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+
+struct ttyprintk_port {
+ struct tty_port port;
+ struct mutex port_write_mutex;
+};
+
+static struct ttyprintk_port tpk_port;
+
+/*
+ * Our simple preformatting supports transparent output of (time-stamped)
+ * printk messages (also suitable for logging service):
+ * - any cr is replaced by nl
+ * - adds a ttyprintk source tag in front of each line
+ * - too long message is fragmeted, with '\'nl between fragments
+ * - TPK_STR_SIZE isn't really the write_room limiting factor, bcause
+ * it is emptied on the fly during preformatting.
+ */
+#define TPK_STR_SIZE 508 /* should be bigger then max expected line length */
+#define TPK_MAX_ROOM 4096 /* we could assume 4K for instance */
+static const char *tpk_tag = "[U] "; /* U for User */
+static int tpk_curr;
+
+static int tpk_printk(const unsigned char *buf, int count)
+{
+ static char tmp[TPK_STR_SIZE + 4];
+ int i = tpk_curr;
+
+ if (buf == NULL) {
+ /* flush tmp[] */
+ if (tpk_curr > 0) {
+ /* non nl or cr terminated message - add nl */
+ tmp[tpk_curr + 0] = '\n';
+ tmp[tpk_curr + 1] = '\0';
+ printk(KERN_INFO "%s%s", tpk_tag, tmp);
+ tpk_curr = 0;
+ }
+ return i;
+ }
+
+ for (i = 0; i < count; i++) {
+ tmp[tpk_curr] = buf[i];
+ if (tpk_curr < TPK_STR_SIZE) {
+ switch (buf[i]) {
+ case '\r':
+ /* replace cr with nl */
+ tmp[tpk_curr + 0] = '\n';
+ tmp[tpk_curr + 1] = '\0';
+ printk(KERN_INFO "%s%s", tpk_tag, tmp);
+ tpk_curr = 0;
+ if (buf[i + 1] == '\n')
+ i++;
+ break;
+ case '\n':
+ tmp[tpk_curr + 1] = '\0';
+ printk(KERN_INFO "%s%s", tpk_tag, tmp);
+ tpk_curr = 0;
+ break;
+ default:
+ tpk_curr++;
+ }
+ } else {
+ /* end of tmp buffer reached: cut the message in two */
+ tmp[tpk_curr + 1] = '\\';
+ tmp[tpk_curr + 2] = '\n';
+ tmp[tpk_curr + 3] = '\0';
+ printk(KERN_INFO "%s%s", tpk_tag, tmp);
+ tpk_curr = 0;
+ }
+ }
+
+ return count;
+}
+
+/*
+ * TTY operations open function.
+ */
+static int tpk_open(struct tty_struct *tty, struct file *filp)
+{
+ tty->driver_data = &tpk_port;
+
+ return tty_port_open(&tpk_port.port, tty, filp);
+}
+
+/*
+ * TTY operations close function.
+ */
+static void tpk_close(struct tty_struct *tty, struct file *filp)
+{
+ struct ttyprintk_port *tpkp = tty->driver_data;
+
+ mutex_lock(&tpkp->port_write_mutex);
+ /* flush tpk_printk buffer */
+ tpk_printk(NULL, 0);
+ mutex_unlock(&tpkp->port_write_mutex);
+
+ tty_port_close(&tpkp->port, tty, filp);
+}
+
+/*
+ * TTY operations write function.
+ */
+static int tpk_write(struct tty_struct *tty,
+ const unsigned char *buf, int count)
+{
+ struct ttyprintk_port *tpkp = tty->driver_data;
+ int ret;
+
+
+ /* exclusive use of tpk_printk within this tty */
+ mutex_lock(&tpkp->port_write_mutex);
+ ret = tpk_printk(buf, count);
+ mutex_unlock(&tpkp->port_write_mutex);
+
+ return ret;
+}
+
+/*
+ * TTY operations write_room function.
+ */
+static int tpk_write_room(struct tty_struct *tty)
+{
+ return TPK_MAX_ROOM;
+}
+
+/*
+ * TTY operations ioctl function.
+ */
+static int tpk_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct ttyprintk_port *tpkp = tty->driver_data;
+
+ if (!tpkp)
+ return -EINVAL;
+
+ switch (cmd) {
+ /* Stop TIOCCONS */
+ case TIOCCONS:
+ return -EOPNOTSUPP;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+static const struct tty_operations ttyprintk_ops = {
+ .open = tpk_open,
+ .close = tpk_close,
+ .write = tpk_write,
+ .write_room = tpk_write_room,
+ .ioctl = tpk_ioctl,
+};
+
+struct tty_port_operations null_ops = { };
+
+static struct tty_driver *ttyprintk_driver;
+
+static int __init ttyprintk_init(void)
+{
+ int ret = -ENOMEM;
+ void *rp;
+
+ ttyprintk_driver = alloc_tty_driver(1);
+ if (!ttyprintk_driver)
+ return ret;
+
+ ttyprintk_driver->owner = THIS_MODULE;
+ ttyprintk_driver->driver_name = "ttyprintk";
+ ttyprintk_driver->name = "ttyprintk";
+ ttyprintk_driver->major = TTYAUX_MAJOR;
+ ttyprintk_driver->minor_start = 3;
+ ttyprintk_driver->num = 1;
+ ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+ ttyprintk_driver->init_termios = tty_std_termios;
+ ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
+ ttyprintk_driver->flags = TTY_DRIVER_RESET_TERMIOS |
+ TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ tty_set_operations(ttyprintk_driver, &ttyprintk_ops);
+
+ ret = tty_register_driver(ttyprintk_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "Couldn't register ttyprintk driver\n");
+ goto error;
+ }
+
+ /* create our unnumbered device */
+ rp = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 3), NULL,
+ ttyprintk_driver->name);
+ if (IS_ERR(rp)) {
+ printk(KERN_ERR "Couldn't create ttyprintk device\n");
+ ret = PTR_ERR(rp);
+ goto error;
+ }
+
+ tty_port_init(&tpk_port.port);
+ tpk_port.port.ops = &null_ops;
+ mutex_init(&tpk_port.port_write_mutex);
+
+ return 0;
+
+error:
+ put_tty_driver(ttyprintk_driver);
+ ttyprintk_driver = NULL;
+ return ret;
+}
+module_init(ttyprintk_init);
diff --git a/drivers/char/uv_mmtimer.c b/drivers/char/uv_mmtimer.c
index c7072ba14f48..9aef403c4628 100644
--- a/drivers/char/uv_mmtimer.c
+++ b/drivers/char/uv_mmtimer.c
@@ -52,6 +52,7 @@ static const struct file_operations uv_mmtimer_fops = {
.owner = THIS_MODULE,
.mmap = uv_mmtimer_mmap,
.unlocked_ioctl = uv_mmtimer_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
/**
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 42f7fa442ff8..ad6e64a2912d 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -46,7 +46,7 @@
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -64,6 +64,7 @@
#define VIOTAPE_KERN_WARN KERN_WARNING "viotape: "
#define VIOTAPE_KERN_INFO KERN_INFO "viotape: "
+static DEFINE_MUTEX(proc_viotape_mutex);
static int viotape_numdev;
/*
@@ -684,9 +685,9 @@ static long viotap_unlocked_ioctl(struct file *file,
{
long rc;
- lock_kernel();
+ mutex_lock(&proc_viotape_mutex);
rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&proc_viotape_mutex);
return rc;
}
@@ -700,7 +701,7 @@ static int viotap_open(struct inode *inode, struct file *file)
if (op == NULL)
return -ENOMEM;
- lock_kernel();
+ mutex_lock(&proc_viotape_mutex);
get_dev_info(file->f_path.dentry->d_inode, &devi);
/* Note: We currently only support one mode! */
@@ -731,7 +732,7 @@ static int viotap_open(struct inode *inode, struct file *file)
free_op:
free_op_struct(op);
- unlock_kernel();
+ mutex_unlock(&proc_viotape_mutex);
return ret;
}
@@ -804,6 +805,7 @@ const struct file_operations viotap_fops = {
.unlocked_ioctl = viotap_unlocked_ioctl,
.open = viotap_open,
.release = viotap_release,
+ .llseek = noop_llseek,
};
/* Handle interrupt events for tape */
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 942a9826bd23..247f215d4819 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -48,6 +48,9 @@ struct ports_driver_data {
/* Used for exporting per-port information to debugfs */
struct dentry *debugfs_dir;
+ /* List of all the devices we're handling */
+ struct list_head portdevs;
+
/* Number of devices this driver is handling */
unsigned int index;
@@ -108,6 +111,9 @@ struct port_buffer {
* ports for that device (vdev->priv).
*/
struct ports_device {
+ /* Next portdev in the list, head is in the pdrvdata struct */
+ struct list_head list;
+
/*
* Workqueue handlers where we process deferred work after
* notification
@@ -178,15 +184,21 @@ struct port {
struct console cons;
/* Each port associates with a separate char device */
- struct cdev cdev;
+ struct cdev *cdev;
struct device *dev;
+ /* Reference-counting to handle port hot-unplugs and file operations */
+ struct kref kref;
+
/* A waitqueue for poll() or blocking read operations */
wait_queue_head_t waitqueue;
/* The 'name' of the port that we expose via sysfs properties */
char *name;
+ /* We can notify apps of host connect / disconnect events via SIGIO */
+ struct fasync_struct *async_queue;
+
/* The 'id' to identify the port with the Host */
u32 id;
@@ -221,6 +233,41 @@ out:
return port;
}
+static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev,
+ dev_t dev)
+{
+ struct port *port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&portdev->ports_lock, flags);
+ list_for_each_entry(port, &portdev->ports, list)
+ if (port->cdev->dev == dev)
+ goto out;
+ port = NULL;
+out:
+ spin_unlock_irqrestore(&portdev->ports_lock, flags);
+
+ return port;
+}
+
+static struct port *find_port_by_devt(dev_t dev)
+{
+ struct ports_device *portdev;
+ struct port *port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdrvdata_lock, flags);
+ list_for_each_entry(portdev, &pdrvdata.portdevs, list) {
+ port = find_port_by_devt_in_portdev(portdev, dev);
+ if (port)
+ goto out;
+ }
+ port = NULL;
+out:
+ spin_unlock_irqrestore(&pdrvdata_lock, flags);
+ return port;
+}
+
static struct port *find_port_by_id(struct ports_device *portdev, u32 id)
{
struct port *port;
@@ -410,7 +457,10 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
static ssize_t send_control_msg(struct port *port, unsigned int event,
unsigned int value)
{
- return __send_control_msg(port->portdev, port->id, event, value);
+ /* Did the port get unplugged before userspace closed it? */
+ if (port->portdev)
+ return __send_control_msg(port->portdev, port->id, event, value);
+ return 0;
}
/* Callers must take the port->outvq_lock */
@@ -522,6 +572,10 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
/* The condition that must be true for polling to end */
static bool will_read_block(struct port *port)
{
+ if (!port->guest_connected) {
+ /* Port got hot-unplugged. Let's exit. */
+ return false;
+ }
return !port_has_data(port) && port->host_connected;
}
@@ -572,6 +626,9 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
if (ret < 0)
return ret;
}
+ /* Port got hot-unplugged. */
+ if (!port->guest_connected)
+ return -ENODEV;
/*
* We could've received a disconnection message while we were
* waiting for more data.
@@ -609,6 +666,9 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
if (ret < 0)
return ret;
}
+ /* Port got hot-unplugged. */
+ if (!port->guest_connected)
+ return -ENODEV;
count = min((size_t)(32 * 1024), count);
@@ -641,6 +701,10 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
port = filp->private_data;
poll_wait(filp, &port->waitqueue, wait);
+ if (!port->guest_connected) {
+ /* Port got unplugged */
+ return POLLHUP;
+ }
ret = 0;
if (port->inbuf)
ret |= POLLIN | POLLRDNORM;
@@ -652,6 +716,8 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
return ret;
}
+static void remove_port(struct kref *kref);
+
static int port_fops_release(struct inode *inode, struct file *filp)
{
struct port *port;
@@ -672,6 +738,16 @@ static int port_fops_release(struct inode *inode, struct file *filp)
reclaim_consumed_buffers(port);
spin_unlock_irq(&port->outvq_lock);
+ /*
+ * Locks aren't necessary here as a port can't be opened after
+ * unplug, and if a port isn't unplugged, a kref would already
+ * exist for the port. Plus, taking ports_lock here would
+ * create a dependency on other locks taken by functions
+ * inside remove_port if we're the last holder of the port,
+ * creating many problems.
+ */
+ kref_put(&port->kref, remove_port);
+
return 0;
}
@@ -679,22 +755,31 @@ static int port_fops_open(struct inode *inode, struct file *filp)
{
struct cdev *cdev = inode->i_cdev;
struct port *port;
+ int ret;
- port = container_of(cdev, struct port, cdev);
+ port = find_port_by_devt(cdev->dev);
filp->private_data = port;
+ /* Prevent against a port getting hot-unplugged at the same time */
+ spin_lock_irq(&port->portdev->ports_lock);
+ kref_get(&port->kref);
+ spin_unlock_irq(&port->portdev->ports_lock);
+
/*
* Don't allow opening of console port devices -- that's done
* via /dev/hvc
*/
- if (is_console_port(port))
- return -ENXIO;
+ if (is_console_port(port)) {
+ ret = -ENXIO;
+ goto out;
+ }
/* Allow only one process to open a particular port at a time */
spin_lock_irq(&port->inbuf_lock);
if (port->guest_connected) {
spin_unlock_irq(&port->inbuf_lock);
- return -EMFILE;
+ ret = -EMFILE;
+ goto out;
}
port->guest_connected = true;
@@ -713,6 +798,17 @@ static int port_fops_open(struct inode *inode, struct file *filp)
send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1);
return 0;
+out:
+ kref_put(&port->kref, remove_port);
+ return ret;
+}
+
+static int port_fops_fasync(int fd, struct file *filp, int mode)
+{
+ struct port *port;
+
+ port = filp->private_data;
+ return fasync_helper(fd, filp, mode, &port->async_queue);
}
/*
@@ -728,6 +824,8 @@ static const struct file_operations port_fops = {
.write = port_fops_write,
.poll = port_fops_poll,
.release = port_fops_release,
+ .fasync = port_fops_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/*
@@ -949,6 +1047,7 @@ static const struct file_operations port_debugfs_ops = {
.owner = THIS_MODULE,
.open = debugfs_open,
.read = debugfs_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void set_console_size(struct port *port, u16 rows, u16 cols)
@@ -986,6 +1085,12 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
return nr_added_bufs;
}
+static void send_sigio_to_port(struct port *port)
+{
+ if (port->async_queue && port->guest_connected)
+ kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
+}
+
static int add_port(struct ports_device *portdev, u32 id)
{
char debugfs_name[16];
@@ -1000,6 +1105,7 @@ static int add_port(struct ports_device *portdev, u32 id)
err = -ENOMEM;
goto fail;
}
+ kref_init(&port->kref);
port->portdev = portdev;
port->id = id;
@@ -1007,6 +1113,7 @@ static int add_port(struct ports_device *portdev, u32 id)
port->name = NULL;
port->inbuf = NULL;
port->cons.hvc = NULL;
+ port->async_queue = NULL;
port->cons.ws.ws_row = port->cons.ws.ws_col = 0;
@@ -1017,14 +1124,20 @@ static int add_port(struct ports_device *portdev, u32 id)
port->in_vq = portdev->in_vqs[port->id];
port->out_vq = portdev->out_vqs[port->id];
- cdev_init(&port->cdev, &port_fops);
+ port->cdev = cdev_alloc();
+ if (!port->cdev) {
+ dev_err(&port->portdev->vdev->dev, "Error allocating cdev\n");
+ err = -ENOMEM;
+ goto free_port;
+ }
+ port->cdev->ops = &port_fops;
devt = MKDEV(portdev->chr_major, id);
- err = cdev_add(&port->cdev, devt, 1);
+ err = cdev_add(port->cdev, devt, 1);
if (err < 0) {
dev_err(&port->portdev->vdev->dev,
"Error %d adding cdev for port %u\n", err, id);
- goto free_port;
+ goto free_cdev;
}
port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
devt, port, "vport%up%u",
@@ -1089,7 +1202,7 @@ free_inbufs:
free_device:
device_destroy(pdrvdata.class, port->dev->devt);
free_cdev:
- cdev_del(&port->cdev);
+ cdev_del(port->cdev);
free_port:
kfree(port);
fail:
@@ -1098,21 +1211,45 @@ fail:
return err;
}
-/* Remove all port-specific data. */
-static int remove_port(struct port *port)
+/* No users remain, remove all port-specific data. */
+static void remove_port(struct kref *kref)
+{
+ struct port *port;
+
+ port = container_of(kref, struct port, kref);
+
+ sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
+ device_destroy(pdrvdata.class, port->dev->devt);
+ cdev_del(port->cdev);
+
+ kfree(port->name);
+
+ debugfs_remove(port->debugfs_file);
+
+ kfree(port);
+}
+
+/*
+ * Port got unplugged. Remove port from portdev's list and drop the
+ * kref reference. If no userspace has this port opened, it will
+ * result in immediate removal the port.
+ */
+static void unplug_port(struct port *port)
{
struct port_buffer *buf;
+ spin_lock_irq(&port->portdev->ports_lock);
+ list_del(&port->list);
+ spin_unlock_irq(&port->portdev->ports_lock);
+
if (port->guest_connected) {
port->guest_connected = false;
port->host_connected = false;
wake_up_interruptible(&port->waitqueue);
- send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
- }
- spin_lock_irq(&port->portdev->ports_lock);
- list_del(&port->list);
- spin_unlock_irq(&port->portdev->ports_lock);
+ /* Let the app know the port is going down. */
+ send_sigio_to_port(port);
+ }
if (is_console_port(port)) {
spin_lock_irq(&pdrvdata_lock);
@@ -1131,9 +1268,6 @@ static int remove_port(struct port *port)
hvc_remove(port->cons.hvc);
#endif
}
- sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
- device_destroy(pdrvdata.class, port->dev->devt);
- cdev_del(&port->cdev);
/* Remove unused data this port might have received. */
discard_port_data(port);
@@ -1144,12 +1278,19 @@ static int remove_port(struct port *port)
while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
free_buf(buf);
- kfree(port->name);
-
- debugfs_remove(port->debugfs_file);
+ /*
+ * We should just assume the device itself has gone off --
+ * else a close on an open port later will try to send out a
+ * control message.
+ */
+ port->portdev = NULL;
- kfree(port);
- return 0;
+ /*
+ * Locks around here are not necessary - a port can't be
+ * opened after we removed the port struct from ports_list
+ * above.
+ */
+ kref_put(&port->kref, remove_port);
}
/* Any private messages that the Host and Guest want to share */
@@ -1188,7 +1329,7 @@ static void handle_control_message(struct ports_device *portdev,
add_port(portdev, cpkt->id);
break;
case VIRTIO_CONSOLE_PORT_REMOVE:
- remove_port(port);
+ unplug_port(port);
break;
case VIRTIO_CONSOLE_CONSOLE_PORT:
if (!cpkt->value)
@@ -1230,6 +1371,12 @@ static void handle_control_message(struct ports_device *portdev,
spin_lock_irq(&port->outvq_lock);
reclaim_consumed_buffers(port);
spin_unlock_irq(&port->outvq_lock);
+
+ /*
+ * If the guest is connected, it'll be interested in
+ * knowing the host connection state changed.
+ */
+ send_sigio_to_port(port);
break;
case VIRTIO_CONSOLE_PORT_NAME:
/*
@@ -1326,6 +1473,9 @@ static void in_intr(struct virtqueue *vq)
wake_up_interruptible(&port->waitqueue);
+ /* Send a SIGIO indicating new data in case the process asked for it */
+ send_sigio_to_port(port);
+
if (is_console_port(port) && hvc_poll(port->cons.hvc))
hvc_kick();
}
@@ -1477,6 +1627,7 @@ fail:
static const struct file_operations portdev_fops = {
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
@@ -1562,6 +1713,10 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
add_port(portdev, 0);
}
+ spin_lock_irq(&pdrvdata_lock);
+ list_add_tail(&portdev->list, &pdrvdata.portdevs);
+ spin_unlock_irq(&pdrvdata_lock);
+
__send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
VIRTIO_CONSOLE_DEVICE_READY, 1);
return 0;
@@ -1585,23 +1740,41 @@ static void virtcons_remove(struct virtio_device *vdev)
{
struct ports_device *portdev;
struct port *port, *port2;
- struct port_buffer *buf;
- unsigned int len;
portdev = vdev->priv;
+ spin_lock_irq(&pdrvdata_lock);
+ list_del(&portdev->list);
+ spin_unlock_irq(&pdrvdata_lock);
+
+ /* Disable interrupts for vqs */
+ vdev->config->reset(vdev);
+ /* Finish up work that's lined up */
cancel_work_sync(&portdev->control_work);
list_for_each_entry_safe(port, port2, &portdev->ports, list)
- remove_port(port);
+ unplug_port(port);
unregister_chrdev(portdev->chr_major, "virtio-portsdev");
- while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
- free_buf(buf);
+ /*
+ * When yanking out a device, we immediately lose the
+ * (device-side) queues. So there's no point in keeping the
+ * guest side around till we drop our final reference. This
+ * also means that any ports which are in an open state will
+ * have to just stop using the port, as the vqs are going
+ * away.
+ */
+ if (use_multiport(portdev)) {
+ struct port_buffer *buf;
+ unsigned int len;
- while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
- free_buf(buf);
+ while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
+ free_buf(buf);
+
+ while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
+ free_buf(buf);
+ }
vdev->config->del_vqs(vdev);
kfree(portdev->in_vqs);
@@ -1648,6 +1821,7 @@ static int __init init(void)
PTR_ERR(pdrvdata.debugfs_dir));
}
INIT_LIST_HEAD(&pdrvdata.consoles);
+ INIT_LIST_HEAD(&pdrvdata.portdevs);
return register_virtio_driver(&virtio_console);
}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 50590c7f2c01..281aada7b4a1 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -906,22 +906,16 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
* bottom of buffer
*/
old_origin += (old_rows - new_rows) * old_row_size;
- end = vc->vc_scr_end;
} else {
/*
* Cursor is in no man's land, copy 1/2 screenful
* from the top and bottom of cursor position
*/
old_origin += (vc->vc_y - new_rows/2) * old_row_size;
- end = old_origin + (old_row_size * new_rows);
}
- } else
- /*
- * Cursor near the top, copy contents from the top of buffer
- */
- end = (old_rows > new_rows) ? old_origin +
- (old_row_size * new_rows) :
- vc->vc_scr_end;
+ }
+
+ end = old_origin + old_row_size * min(old_rows, new_rows);
update_attr(vc);
@@ -3075,8 +3069,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
old_was_color = vc->vc_can_do_color;
vc->vc_sw->con_deinit(vc);
- if (!vc->vc_origin)
- vc->vc_origin = (unsigned long)vc->vc_screenbuf;
+ vc->vc_origin = (unsigned long)vc->vc_screenbuf;
visual_init(vc, i, 0);
set_origin(vc);
update_attr(vc);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 2bbeaaea46e9..38df8c19e74c 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -533,11 +533,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KIOCSOUND:
if (!perm)
goto eperm;
- /* FIXME: This is an old broken API but we need to keep it
- supported and somehow separate the historic advertised
- tick rate from any real one */
+ /*
+ * The use of PIT_TICK_RATE is historic, it used to be
+ * the platform-dependent CLOCK_TICK_RATE between 2.6.12
+ * and 2.6.36, which was a minor but unfortunate ABI
+ * change.
+ */
if (arg)
- arg = CLOCK_TICK_RATE / arg;
+ arg = PIT_TICK_RATE / arg;
kd_mksound(arg, 0);
break;
@@ -553,11 +556,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
- /* FIXME: This is an old broken API but we need to keep it
- supported and somehow separate the historic advertised
- tick rate from any real one */
if (count)
- count = CLOCK_TICK_RATE / count;
+ count = PIT_TICK_RATE / count;
kd_mksound(count, ticks);
break;
}
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index b663d573aad9..dd960cab1ac5 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -81,7 +81,6 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/sysctl.h>
#include <linux/fs.h>
#include <linux/cdev.h>
@@ -112,6 +111,7 @@
#define HWICAP_DEVICES 1
/* An array, which is set to true when the device is registered. */
+static DEFINE_MUTEX(hwicap_mutex);
static bool probed_devices[HWICAP_DEVICES];
static struct mutex icap_sem;
@@ -502,7 +502,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
struct hwicap_drvdata *drvdata;
int status;
- lock_kernel();
+ mutex_lock(&hwicap_mutex);
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
status = mutex_lock_interruptible(&drvdata->sem);
@@ -528,7 +528,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
error:
mutex_unlock(&drvdata->sem);
out:
- unlock_kernel();
+ mutex_unlock(&hwicap_mutex);
return status;
}
@@ -567,6 +567,7 @@ static const struct file_operations hwicap_fops = {
.read = hwicap_read,
.open = hwicap_open,
.release = hwicap_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int __devinit hwicap_setup(struct device *dev, int id,
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 717305d30444..0a9701b1e13f 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -308,7 +308,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
* isr before we end up here.
*/
if (p->flags & FLAG_CLOCKSOURCE)
- p->total_cycles += p->match_value;
+ p->total_cycles += p->match_value + 1;
if (!(p->flags & FLAG_REPROGRAM))
p->next_match_value = p->max_match_value;
@@ -403,7 +403,7 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
raw = sh_cmt_get_counter(p, &has_wrapped);
if (unlikely(has_wrapped))
- raw += p->match_value;
+ raw += p->match_value + 1;
spin_unlock_irqrestore(&p->lock, flags);
return value + raw;
@@ -445,7 +445,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
/* clk_get_rate() needs an enabled clock */
clk_enable(p->clk);
- p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8;
+ p->rate = clk_get_rate(p->clk) / ((p->width == 16) ? 512 : 8);
clk_disable(p->clk);
/* TODO: calculate good shift from rate and counter bit width */
@@ -478,7 +478,7 @@ static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
if (periodic)
- sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+ sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1);
else
sh_cmt_set_next(p, p->max_match_value);
}
@@ -523,9 +523,9 @@ static int sh_cmt_clock_event_next(unsigned long delta,
BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
if (likely(p->flags & FLAG_IRQCONTEXT))
- p->next_match_value = delta;
+ p->next_match_value = delta - 1;
else
- sh_cmt_set_next(p, delta);
+ sh_cmt_set_next(p, delta - 1);
return 0;
}
@@ -610,8 +610,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
p->irqaction.name = dev_name(&p->pdev->dev);
p->irqaction.handler = sh_cmt_interrupt;
p->irqaction.dev_id = p;
- p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
- IRQF_IRQPOLL | IRQF_NOBALANCING;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_NOBALANCING;
/* get hold of clock */
p->clk = clk_get(&p->pdev->dev, "cmt_fck");
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index ef7a5be8a09f..9fe3507a453d 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -281,8 +281,7 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
p->irqaction.handler = sh_mtu2_interrupt;
p->irqaction.dev_id = p;
p->irqaction.irq = irq;
- p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
- IRQF_IRQPOLL | IRQF_NOBALANCING;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_NOBALANCING;
/* get hold of clock */
p->clk = clk_get(&p->pdev->dev, "mtu2_fck");
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index de715901b82a..75967f8e028e 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -387,8 +387,7 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
p->irqaction.handler = sh_tmu_interrupt;
p->irqaction.dev_id = p;
p->irqaction.irq = irq;
- p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
- IRQF_IRQPOLL | IRQF_NOBALANCING;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_NOBALANCING;
/* get hold of clock */
p->clk = clk_get(&p->pdev->dev, "tmu_fck");
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 199dcb9f0b83..c63a43823744 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -918,8 +918,8 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
spin_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus) {
- if (!cpu_online(j))
- continue;
+ if (!cpu_online(j))
+ continue;
per_cpu(cpufreq_cpu_data, j) = policy;
per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
}
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index c2408bbe9c2e..f508690eb958 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -80,7 +80,7 @@
* Limiting Performance Impact
* ---------------------------
* C states, especially those with large exit latencies, can have a real
- * noticable impact on workloads, which is not acceptable for most sysadmins,
+ * noticeable impact on workloads, which is not acceptable for most sysadmins,
* and in addition, less performance has a power price of its own.
*
* As a general rule of thumb, menu assumes that the following heuristic
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index ea0b3863ad0f..eab2cf7a0269 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -172,6 +172,7 @@ config CRYPTO_DEV_MV_CESA
config CRYPTO_DEV_NIAGARA2
tristate "Niagara2 Stream Processing Unit driver"
+ select CRYPTO_DES
select CRYPTO_ALGAPI
depends on SPARC64
help
@@ -243,4 +244,12 @@ config CRYPTO_DEV_OMAP_SHAM
OMAP processors have SHA1/MD5 hw accelerator. Select this if you
want to use the OMAP module for SHA1/MD5 algorithms.
+config CRYPTO_DEV_OMAP_AES
+ tristate "Support for OMAP AES hw engine"
+ depends on ARCH_OMAP2 || ARCH_OMAP3
+ select CRYPTO_AES
+ help
+ OMAP processors have AES module accelerator. Select this if you
+ want to use the OMAP module for AES algorithms.
+
endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 6dbbe00c4524..64289c678e98 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -9,4 +9,5 @@ obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
+obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
new file mode 100644
index 000000000000..799ca517c121
--- /dev/null
+++ b/drivers/crypto/omap-aes.c
@@ -0,0 +1,948 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for OMAP AES HW acceleration.
+ *
+ * Copyright (c) 2010 Nokia Corporation
+ * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/aes.h>
+
+#include <plat/cpu.h>
+#include <plat/dma.h>
+
+/* OMAP TRM gives bitfields as start:end, where start is the higher bit
+ number. For example 7:0 */
+#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+
+#define AES_REG_KEY(x) (0x1C - ((x ^ 0x01) * 0x04))
+#define AES_REG_IV(x) (0x20 + ((x) * 0x04))
+
+#define AES_REG_CTRL 0x30
+#define AES_REG_CTRL_CTR_WIDTH (1 << 7)
+#define AES_REG_CTRL_CTR (1 << 6)
+#define AES_REG_CTRL_CBC (1 << 5)
+#define AES_REG_CTRL_KEY_SIZE (3 << 3)
+#define AES_REG_CTRL_DIRECTION (1 << 2)
+#define AES_REG_CTRL_INPUT_READY (1 << 1)
+#define AES_REG_CTRL_OUTPUT_READY (1 << 0)
+
+#define AES_REG_DATA 0x34
+#define AES_REG_DATA_N(x) (0x34 + ((x) * 0x04))
+
+#define AES_REG_REV 0x44
+#define AES_REG_REV_MAJOR 0xF0
+#define AES_REG_REV_MINOR 0x0F
+
+#define AES_REG_MASK 0x48
+#define AES_REG_MASK_SIDLE (1 << 6)
+#define AES_REG_MASK_START (1 << 5)
+#define AES_REG_MASK_DMA_OUT_EN (1 << 3)
+#define AES_REG_MASK_DMA_IN_EN (1 << 2)
+#define AES_REG_MASK_SOFTRESET (1 << 1)
+#define AES_REG_AUTOIDLE (1 << 0)
+
+#define AES_REG_SYSSTATUS 0x4C
+#define AES_REG_SYSSTATUS_RESETDONE (1 << 0)
+
+#define DEFAULT_TIMEOUT (5*HZ)
+
+#define FLAGS_MODE_MASK 0x000f
+#define FLAGS_ENCRYPT BIT(0)
+#define FLAGS_CBC BIT(1)
+#define FLAGS_GIV BIT(2)
+
+#define FLAGS_NEW_KEY BIT(4)
+#define FLAGS_NEW_IV BIT(5)
+#define FLAGS_INIT BIT(6)
+#define FLAGS_FAST BIT(7)
+#define FLAGS_BUSY 8
+
+struct omap_aes_ctx {
+ struct omap_aes_dev *dd;
+
+ int keylen;
+ u32 key[AES_KEYSIZE_256 / sizeof(u32)];
+ unsigned long flags;
+};
+
+struct omap_aes_reqctx {
+ unsigned long mode;
+};
+
+#define OMAP_AES_QUEUE_LENGTH 1
+#define OMAP_AES_CACHE_SIZE 0
+
+struct omap_aes_dev {
+ struct list_head list;
+ unsigned long phys_base;
+ void __iomem *io_base;
+ struct clk *iclk;
+ struct omap_aes_ctx *ctx;
+ struct device *dev;
+ unsigned long flags;
+
+ u32 *iv;
+ u32 ctrl;
+
+ spinlock_t lock;
+ struct crypto_queue queue;
+
+ struct tasklet_struct task;
+
+ struct ablkcipher_request *req;
+ size_t total;
+ struct scatterlist *in_sg;
+ size_t in_offset;
+ struct scatterlist *out_sg;
+ size_t out_offset;
+
+ size_t buflen;
+ void *buf_in;
+ size_t dma_size;
+ int dma_in;
+ int dma_lch_in;
+ dma_addr_t dma_addr_in;
+ void *buf_out;
+ int dma_out;
+ int dma_lch_out;
+ dma_addr_t dma_addr_out;
+};
+
+/* keep registered devices data here */
+static LIST_HEAD(dev_list);
+static DEFINE_SPINLOCK(list_lock);
+
+static inline u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset)
+{
+ return __raw_readl(dd->io_base + offset);
+}
+
+static inline void omap_aes_write(struct omap_aes_dev *dd, u32 offset,
+ u32 value)
+{
+ __raw_writel(value, dd->io_base + offset);
+}
+
+static inline void omap_aes_write_mask(struct omap_aes_dev *dd, u32 offset,
+ u32 value, u32 mask)
+{
+ u32 val;
+
+ val = omap_aes_read(dd, offset);
+ val &= ~mask;
+ val |= value;
+ omap_aes_write(dd, offset, val);
+}
+
+static void omap_aes_write_n(struct omap_aes_dev *dd, u32 offset,
+ u32 *value, int count)
+{
+ for (; count--; value++, offset += 4)
+ omap_aes_write(dd, offset, *value);
+}
+
+static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)
+{
+ unsigned long timeout = jiffies + DEFAULT_TIMEOUT;
+
+ while (!(omap_aes_read(dd, offset) & bit)) {
+ if (time_is_before_jiffies(timeout)) {
+ dev_err(dd->dev, "omap-aes timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+ return 0;
+}
+
+static int omap_aes_hw_init(struct omap_aes_dev *dd)
+{
+ int err = 0;
+
+ clk_enable(dd->iclk);
+ if (!(dd->flags & FLAGS_INIT)) {
+ /* is it necessary to reset before every operation? */
+ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
+ AES_REG_MASK_SOFTRESET);
+ /*
+ * prevent OCP bus error (SRESP) in case an access to the module
+ * is performed while the module is coming out of soft reset
+ */
+ __asm__ __volatile__("nop");
+ __asm__ __volatile__("nop");
+
+ err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
+ AES_REG_SYSSTATUS_RESETDONE);
+ if (!err)
+ dd->flags |= FLAGS_INIT;
+ }
+
+ return err;
+}
+
+static void omap_aes_hw_cleanup(struct omap_aes_dev *dd)
+{
+ clk_disable(dd->iclk);
+}
+
+static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
+{
+ unsigned int key32;
+ int i;
+ u32 val, mask;
+
+ val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
+ if (dd->flags & FLAGS_CBC)
+ val |= AES_REG_CTRL_CBC;
+ if (dd->flags & FLAGS_ENCRYPT)
+ val |= AES_REG_CTRL_DIRECTION;
+
+ if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) &&
+ !(dd->ctx->flags & FLAGS_NEW_KEY))
+ goto out;
+
+ /* only need to write control registers for new settings */
+
+ dd->ctrl = val;
+
+ val = 0;
+ if (dd->dma_lch_out >= 0)
+ val |= AES_REG_MASK_DMA_OUT_EN;
+ if (dd->dma_lch_in >= 0)
+ val |= AES_REG_MASK_DMA_IN_EN;
+
+ mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN;
+
+ omap_aes_write_mask(dd, AES_REG_MASK, val, mask);
+
+ pr_debug("Set key\n");
+ key32 = dd->ctx->keylen / sizeof(u32);
+ /* set a key */
+ for (i = 0; i < key32; i++) {
+ omap_aes_write(dd, AES_REG_KEY(i),
+ __le32_to_cpu(dd->ctx->key[i]));
+ }
+ dd->ctx->flags &= ~FLAGS_NEW_KEY;
+
+ if (dd->flags & FLAGS_NEW_IV) {
+ pr_debug("Set IV\n");
+ omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4);
+ dd->flags &= ~FLAGS_NEW_IV;
+ }
+
+ mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
+ AES_REG_CTRL_KEY_SIZE;
+
+ omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask);
+
+out:
+ /* start DMA or disable idle mode */
+ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
+ AES_REG_MASK_START);
+}
+
+static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
+{
+ struct omap_aes_dev *dd = NULL, *tmp;
+
+ spin_lock_bh(&list_lock);
+ if (!ctx->dd) {
+ list_for_each_entry(tmp, &dev_list, list) {
+ /* FIXME: take fist available aes core */
+ dd = tmp;
+ break;
+ }
+ ctx->dd = dd;
+ } else {
+ /* already found before */
+ dd = ctx->dd;
+ }
+ spin_unlock_bh(&list_lock);
+
+ return dd;
+}
+
+static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
+{
+ struct omap_aes_dev *dd = data;
+
+ if (lch == dd->dma_lch_out)
+ tasklet_schedule(&dd->task);
+}
+
+static int omap_aes_dma_init(struct omap_aes_dev *dd)
+{
+ int err = -ENOMEM;
+
+ dd->dma_lch_out = -1;
+ dd->dma_lch_in = -1;
+
+ dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
+ dd->buf_out = (void *)__get_free_pages(GFP_KERNEL, OMAP_AES_CACHE_SIZE);
+ dd->buflen = PAGE_SIZE << OMAP_AES_CACHE_SIZE;
+ dd->buflen &= ~(AES_BLOCK_SIZE - 1);
+
+ if (!dd->buf_in || !dd->buf_out) {
+ dev_err(dd->dev, "unable to alloc pages.\n");
+ goto err_alloc;
+ }
+
+ /* MAP here */
+ dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, dd->buflen,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dd->dev, dd->dma_addr_in)) {
+ dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
+ err = -EINVAL;
+ goto err_map_in;
+ }
+
+ dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, dd->buflen,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(dd->dev, dd->dma_addr_out)) {
+ dev_err(dd->dev, "dma %d bytes error\n", dd->buflen);
+ err = -EINVAL;
+ goto err_map_out;
+ }
+
+ err = omap_request_dma(dd->dma_in, "omap-aes-rx",
+ omap_aes_dma_callback, dd, &dd->dma_lch_in);
+ if (err) {
+ dev_err(dd->dev, "Unable to request DMA channel\n");
+ goto err_dma_in;
+ }
+ err = omap_request_dma(dd->dma_out, "omap-aes-tx",
+ omap_aes_dma_callback, dd, &dd->dma_lch_out);
+ if (err) {
+ dev_err(dd->dev, "Unable to request DMA channel\n");
+ goto err_dma_out;
+ }
+
+ omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+
+ omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+
+ return 0;
+
+err_dma_out:
+ omap_free_dma(dd->dma_lch_in);
+err_dma_in:
+ dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
+ DMA_FROM_DEVICE);
+err_map_out:
+ dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
+err_map_in:
+ free_pages((unsigned long)dd->buf_out, OMAP_AES_CACHE_SIZE);
+ free_pages((unsigned long)dd->buf_in, OMAP_AES_CACHE_SIZE);
+err_alloc:
+ if (err)
+ pr_err("error: %d\n", err);
+ return err;
+}
+
+static void omap_aes_dma_cleanup(struct omap_aes_dev *dd)
+{
+ omap_free_dma(dd->dma_lch_out);
+ omap_free_dma(dd->dma_lch_in);
+ dma_unmap_single(dd->dev, dd->dma_addr_out, dd->buflen,
+ DMA_FROM_DEVICE);
+ dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE);
+ free_pages((unsigned long)dd->buf_out, OMAP_AES_CACHE_SIZE);
+ free_pages((unsigned long)dd->buf_in, OMAP_AES_CACHE_SIZE);
+}
+
+static void sg_copy_buf(void *buf, struct scatterlist *sg,
+ unsigned int start, unsigned int nbytes, int out)
+{
+ struct scatter_walk walk;
+
+ if (!nbytes)
+ return;
+
+ scatterwalk_start(&walk, sg);
+ scatterwalk_advance(&walk, start);
+ scatterwalk_copychunks(buf, &walk, nbytes, out);
+ scatterwalk_done(&walk, out, 0);
+}
+
+static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
+ size_t buflen, size_t total, int out)
+{
+ unsigned int count, off = 0;
+
+ while (buflen && total) {
+ count = min((*sg)->length - *offset, total);
+ count = min(count, buflen);
+
+ if (!count)
+ return off;
+
+ sg_copy_buf(buf + off, *sg, *offset, count, out);
+
+ off += count;
+ buflen -= count;
+ *offset += count;
+ total -= count;
+
+ if (*offset == (*sg)->length) {
+ *sg = sg_next(*sg);
+ if (*sg)
+ *offset = 0;
+ else
+ total = 0;
+ }
+ }
+
+ return off;
+}
+
+static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
+ dma_addr_t dma_addr_out, int length)
+{
+ struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct omap_aes_dev *dd = ctx->dd;
+ int len32;
+
+ pr_debug("len: %d\n", length);
+
+ dd->dma_size = length;
+
+ if (!(dd->flags & FLAGS_FAST))
+ dma_sync_single_for_device(dd->dev, dma_addr_in, length,
+ DMA_TO_DEVICE);
+
+ len32 = DIV_ROUND_UP(length, sizeof(u32));
+
+ /* IN */
+ omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32,
+ len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in,
+ OMAP_DMA_DST_SYNC);
+
+ omap_set_dma_src_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_addr_in, 0, 0);
+
+ /* OUT */
+ omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32,
+ len32, 1, OMAP_DMA_SYNC_PACKET,
+ dd->dma_out, OMAP_DMA_SRC_SYNC);
+
+ omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_addr_out, 0, 0);
+
+ omap_start_dma(dd->dma_lch_in);
+ omap_start_dma(dd->dma_lch_out);
+
+ omap_aes_write_ctrl(dd);
+
+ return 0;
+}
+
+static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
+{
+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(
+ crypto_ablkcipher_reqtfm(dd->req));
+ int err, fast = 0, in, out;
+ size_t count;
+ dma_addr_t addr_in, addr_out;
+
+ pr_debug("total: %d\n", dd->total);
+
+ if (sg_is_last(dd->in_sg) && sg_is_last(dd->out_sg)) {
+ /* check for alignment */
+ in = IS_ALIGNED((u32)dd->in_sg->offset, sizeof(u32));
+ out = IS_ALIGNED((u32)dd->out_sg->offset, sizeof(u32));
+
+ fast = in && out;
+ }
+
+ if (fast) {
+ count = min(dd->total, sg_dma_len(dd->in_sg));
+ count = min(count, sg_dma_len(dd->out_sg));
+
+ if (count != dd->total)
+ return -EINVAL;
+
+ pr_debug("fast\n");
+
+ err = dma_map_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ if (!err) {
+ dev_err(dd->dev, "dma_map_sg() error\n");
+ return -EINVAL;
+ }
+
+ err = dma_map_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
+ if (!err) {
+ dev_err(dd->dev, "dma_map_sg() error\n");
+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ return -EINVAL;
+ }
+
+ addr_in = sg_dma_address(dd->in_sg);
+ addr_out = sg_dma_address(dd->out_sg);
+
+ dd->flags |= FLAGS_FAST;
+
+ } else {
+ /* use cache buffers */
+ count = sg_copy(&dd->in_sg, &dd->in_offset, dd->buf_in,
+ dd->buflen, dd->total, 0);
+
+ addr_in = dd->dma_addr_in;
+ addr_out = dd->dma_addr_out;
+
+ dd->flags &= ~FLAGS_FAST;
+
+ }
+
+ dd->total -= count;
+
+ err = omap_aes_hw_init(dd);
+
+ err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count);
+
+ return err;
+}
+
+static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
+{
+ struct omap_aes_ctx *ctx;
+
+ pr_debug("err: %d\n", err);
+
+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req));
+
+ if (!dd->total)
+ dd->req->base.complete(&dd->req->base, err);
+}
+
+static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
+{
+ int err = 0;
+ size_t count;
+
+ pr_debug("total: %d\n", dd->total);
+
+ omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);
+
+ omap_aes_hw_cleanup(dd);
+
+ omap_stop_dma(dd->dma_lch_in);
+ omap_stop_dma(dd->dma_lch_out);
+
+ if (dd->flags & FLAGS_FAST) {
+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ } else {
+ dma_sync_single_for_device(dd->dev, dd->dma_addr_out,
+ dd->dma_size, DMA_FROM_DEVICE);
+
+ /* copy data */
+ count = sg_copy(&dd->out_sg, &dd->out_offset, dd->buf_out,
+ dd->buflen, dd->dma_size, 1);
+ if (count != dd->dma_size) {
+ err = -EINVAL;
+ pr_err("not all data converted: %u\n", count);
+ }
+ }
+
+ if (err || !dd->total)
+ omap_aes_finish_req(dd, err);
+
+ return err;
+}
+
+static int omap_aes_handle_req(struct omap_aes_dev *dd)
+{
+ struct crypto_async_request *async_req, *backlog;
+ struct omap_aes_ctx *ctx;
+ struct omap_aes_reqctx *rctx;
+ struct ablkcipher_request *req;
+ unsigned long flags;
+
+ if (dd->total)
+ goto start;
+
+ spin_lock_irqsave(&dd->lock, flags);
+ backlog = crypto_get_backlog(&dd->queue);
+ async_req = crypto_dequeue_request(&dd->queue);
+ if (!async_req)
+ clear_bit(FLAGS_BUSY, &dd->flags);
+ spin_unlock_irqrestore(&dd->lock, flags);
+
+ if (!async_req)
+ return 0;
+
+ if (backlog)
+ backlog->complete(backlog, -EINPROGRESS);
+
+ req = ablkcipher_request_cast(async_req);
+
+ pr_debug("get new req\n");
+
+ /* assign new request to device */
+ dd->req = req;
+ dd->total = req->nbytes;
+ dd->in_offset = 0;
+ dd->in_sg = req->src;
+ dd->out_offset = 0;
+ dd->out_sg = req->dst;
+
+ rctx = ablkcipher_request_ctx(req);
+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
+ rctx->mode &= FLAGS_MODE_MASK;
+ dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
+
+ dd->iv = req->info;
+ if ((dd->flags & FLAGS_CBC) && dd->iv)
+ dd->flags |= FLAGS_NEW_IV;
+ else
+ dd->flags &= ~FLAGS_NEW_IV;
+
+ ctx->dd = dd;
+ if (dd->ctx != ctx) {
+ /* assign new context to device */
+ dd->ctx = ctx;
+ ctx->flags |= FLAGS_NEW_KEY;
+ }
+
+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
+ pr_err("request size is not exact amount of AES blocks\n");
+
+start:
+ return omap_aes_crypt_dma_start(dd);
+}
+
+static void omap_aes_task(unsigned long data)
+{
+ struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
+ int err;
+
+ pr_debug("enter\n");
+
+ err = omap_aes_crypt_dma_stop(dd);
+
+ err = omap_aes_handle_req(dd);
+
+ pr_debug("exit\n");
+}
+
+static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
+{
+ struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct omap_aes_dev *dd;
+ unsigned long flags;
+ int err;
+
+ pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
+ !!(mode & FLAGS_ENCRYPT),
+ !!(mode & FLAGS_CBC));
+
+ dd = omap_aes_find_dev(ctx);
+ if (!dd)
+ return -ENODEV;
+
+ rctx->mode = mode;
+
+ spin_lock_irqsave(&dd->lock, flags);
+ err = ablkcipher_enqueue_request(&dd->queue, req);
+ spin_unlock_irqrestore(&dd->lock, flags);
+
+ if (!test_and_set_bit(FLAGS_BUSY, &dd->flags))
+ omap_aes_handle_req(dd);
+
+ pr_debug("exit\n");
+
+ return err;
+}
+
+/* ********************** ALG API ************************************ */
+
+static int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
+ keylen != AES_KEYSIZE_256)
+ return -EINVAL;
+
+ pr_debug("enter, keylen: %d\n", keylen);
+
+ memcpy(ctx->key, key, keylen);
+ ctx->keylen = keylen;
+ ctx->flags |= FLAGS_NEW_KEY;
+
+ return 0;
+}
+
+static int omap_aes_ecb_encrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, FLAGS_ENCRYPT);
+}
+
+static int omap_aes_ecb_decrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, 0);
+}
+
+static int omap_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
+}
+
+static int omap_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+ return omap_aes_crypt(req, FLAGS_CBC);
+}
+
+static int omap_aes_cra_init(struct crypto_tfm *tfm)
+{
+ pr_debug("enter\n");
+
+ tfm->crt_ablkcipher.reqsize = sizeof(struct omap_aes_reqctx);
+
+ return 0;
+}
+
+static void omap_aes_cra_exit(struct crypto_tfm *tfm)
+{
+ pr_debug("enter\n");
+}
+
+/* ********************** ALGS ************************************ */
+
+static struct crypto_alg algs[] = {
+{
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-omap",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct omap_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = omap_aes_cra_init,
+ .cra_exit = omap_aes_cra_exit,
+ .cra_u.ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = omap_aes_setkey,
+ .encrypt = omap_aes_ecb_encrypt,
+ .decrypt = omap_aes_ecb_decrypt,
+ }
+},
+{
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-omap",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct omap_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = omap_aes_cra_init,
+ .cra_exit = omap_aes_cra_exit,
+ .cra_u.ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = omap_aes_setkey,
+ .encrypt = omap_aes_cbc_encrypt,
+ .decrypt = omap_aes_cbc_decrypt,
+ }
+}
+};
+
+static int omap_aes_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct omap_aes_dev *dd;
+ struct resource *res;
+ int err = -ENOMEM, i, j;
+ u32 reg;
+
+ dd = kzalloc(sizeof(struct omap_aes_dev), GFP_KERNEL);
+ if (dd == NULL) {
+ dev_err(dev, "unable to alloc data struct.\n");
+ goto err_data;
+ }
+ dd->dev = dev;
+ platform_set_drvdata(pdev, dd);
+
+ spin_lock_init(&dd->lock);
+ crypto_init_queue(&dd->queue, OMAP_AES_QUEUE_LENGTH);
+
+ /* Get the base address */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "invalid resource type\n");
+ err = -ENODEV;
+ goto err_res;
+ }
+ dd->phys_base = res->start;
+
+ /* Get the DMA */
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!res)
+ dev_info(dev, "no DMA info\n");
+ else
+ dd->dma_out = res->start;
+
+ /* Get the DMA */
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (!res)
+ dev_info(dev, "no DMA info\n");
+ else
+ dd->dma_in = res->start;
+
+ /* Initializing the clock */
+ dd->iclk = clk_get(dev, "ick");
+ if (!dd->iclk) {
+ dev_err(dev, "clock intialization failed.\n");
+ err = -ENODEV;
+ goto err_res;
+ }
+
+ dd->io_base = ioremap(dd->phys_base, SZ_4K);
+ if (!dd->io_base) {
+ dev_err(dev, "can't ioremap\n");
+ err = -ENOMEM;
+ goto err_io;
+ }
+
+ clk_enable(dd->iclk);
+ reg = omap_aes_read(dd, AES_REG_REV);
+ dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
+ (reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
+ clk_disable(dd->iclk);
+
+ tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd);
+
+ err = omap_aes_dma_init(dd);
+ if (err)
+ goto err_dma;
+
+ INIT_LIST_HEAD(&dd->list);
+ spin_lock(&list_lock);
+ list_add_tail(&dd->list, &dev_list);
+ spin_unlock(&list_lock);
+
+ for (i = 0; i < ARRAY_SIZE(algs); i++) {
+ pr_debug("i: %d\n", i);
+ INIT_LIST_HEAD(&algs[i].cra_list);
+ err = crypto_register_alg(&algs[i]);
+ if (err)
+ goto err_algs;
+ }
+
+ pr_info("probe() done\n");
+
+ return 0;
+err_algs:
+ for (j = 0; j < i; j++)
+ crypto_unregister_alg(&algs[j]);
+ omap_aes_dma_cleanup(dd);
+err_dma:
+ tasklet_kill(&dd->task);
+ iounmap(dd->io_base);
+err_io:
+ clk_put(dd->iclk);
+err_res:
+ kfree(dd);
+ dd = NULL;
+err_data:
+ dev_err(dev, "initialization failed.\n");
+ return err;
+}
+
+static int omap_aes_remove(struct platform_device *pdev)
+{
+ struct omap_aes_dev *dd = platform_get_drvdata(pdev);
+ int i;
+
+ if (!dd)
+ return -ENODEV;
+
+ spin_lock(&list_lock);
+ list_del(&dd->list);
+ spin_unlock(&list_lock);
+
+ for (i = 0; i < ARRAY_SIZE(algs); i++)
+ crypto_unregister_alg(&algs[i]);
+
+ tasklet_kill(&dd->task);
+ omap_aes_dma_cleanup(dd);
+ iounmap(dd->io_base);
+ clk_put(dd->iclk);
+ kfree(dd);
+ dd = NULL;
+
+ return 0;
+}
+
+static struct platform_driver omap_aes_driver = {
+ .probe = omap_aes_probe,
+ .remove = omap_aes_remove,
+ .driver = {
+ .name = "omap-aes",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init omap_aes_mod_init(void)
+{
+ pr_info("loading %s driver\n", "omap-aes");
+
+ if (!cpu_class_is_omap2() || omap_type() != OMAP2_DEVICE_TYPE_SEC) {
+ pr_err("Unsupported cpu\n");
+ return -ENODEV;
+ }
+
+ return platform_driver_register(&omap_aes_driver);
+}
+
+static void __exit omap_aes_mod_exit(void)
+{
+ platform_driver_unregister(&omap_aes_driver);
+}
+
+module_init(omap_aes_mod_init);
+module_exit(omap_aes_mod_exit);
+
+MODULE_DESCRIPTION("OMAP AES hw acceleration support.");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Dmitry Kasatkin");
+
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 7d1485676886..a081c7c7d03f 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -311,7 +311,8 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
len32 = DIV_ROUND_UP(length, sizeof(u32));
omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32,
- 1, OMAP_DMA_SYNC_PACKET, dd->dma, OMAP_DMA_DST_SYNC);
+ 1, OMAP_DMA_SYNC_PACKET, dd->dma,
+ OMAP_DMA_DST_SYNC_PREFETCH);
omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC,
dma_addr, 0, 0);
@@ -1072,6 +1073,9 @@ static int omap_sham_dma_init(struct omap_sham_dev *dd)
omap_set_dma_dest_burst_mode(dd->dma_lch,
OMAP_DMA_DATA_BURST_16);
+ omap_set_dma_src_burst_mode(dd->dma_lch,
+ OMAP_DMA_DATA_BURST_4);
+
return 0;
}
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9520cf02edc8..f82ef10a8361 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -49,6 +49,14 @@ config INTEL_MID_DMAC
config ASYNC_TX_DISABLE_CHANNEL_SWITCH
bool
+config AMBA_PL08X
+ bool "ARM PrimeCell PL080 or PL081 support"
+ depends on ARM_AMBA && EXPERIMENTAL
+ select DMA_ENGINE
+ help
+ Platform has a PL08x DMAC device
+ which can provide DMA engine support
+
config INTEL_IOATDMA
tristate "Intel I/OAT DMA support"
depends on PCI && X86
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 72bd70384d8a..0b690e7e4384 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_TIMB_DMA) += timb_dma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
obj-$(CONFIG_PL330_DMA) += pl330.o
obj-$(CONFIG_PCH_DMA) += pch_dma.o
+obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
new file mode 100644
index 000000000000..fc5aaebacdfe
--- /dev/null
+++ b/drivers/dma/amba-pl08x.c
@@ -0,0 +1,2025 @@
+/*
+ * Copyright (c) 2006 ARM Ltd.
+ * Copyright (c) 2010 ST-Ericsson SA
+ *
+ * Author: Peter Pearse <peter.pearse@arm.com>
+ * Author: Linus Walleij <linus.walleij@stericsson.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.
+ *
+ * The full GNU General Public License is iin this distribution in the
+ * file called COPYING.
+ *
+ * Documentation: ARM DDI 0196G == PL080
+ * Documentation: ARM DDI 0218E == PL081
+ *
+ * PL080 & PL081 both have 16 sets of DMA signals that can be routed to
+ * any channel.
+ *
+ * The PL080 has 8 channels available for simultaneous use, and the PL081
+ * has only two channels. So on these DMA controllers the number of channels
+ * and the number of incoming DMA signals are two totally different things.
+ * It is usually not possible to theoretically handle all physical signals,
+ * so a multiplexing scheme with possible denial of use is necessary.
+ *
+ * The PL080 has a dual bus master, PL081 has a single master.
+ *
+ * Memory to peripheral transfer may be visualized as
+ * Get data from memory to DMAC
+ * Until no data left
+ * On burst request from peripheral
+ * Destination burst from DMAC to peripheral
+ * Clear burst request
+ * Raise terminal count interrupt
+ *
+ * For peripherals with a FIFO:
+ * Source burst size == half the depth of the peripheral FIFO
+ * Destination burst size == the depth of the peripheral FIFO
+ *
+ * (Bursts are irrelevant for mem to mem transfers - there are no burst
+ * signals, the DMA controller will simply facilitate its AHB master.)
+ *
+ * ASSUMES default (little) endianness for DMA transfers
+ *
+ * Only DMAC flow control is implemented
+ *
+ * Global TODO:
+ * - Break out common code from arch/arm/mach-s3c64xx and share
+ */
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/dmapool.h>
+#include <linux/amba/bus.h>
+#include <linux/dmaengine.h>
+#include <linux/amba/pl08x.h>
+#include <linux/clk.h>
+
+#include <asm/hardware/pl080.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+#include <asm/atomic.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+
+#define DRIVER_NAME "pl08xdmac"
+
+/**
+ * struct vendor_data - vendor-specific config parameters
+ * for PL08x derivates
+ * @name: the name of this specific variant
+ * @channels: the number of channels available in this variant
+ * @dualmaster: whether this version supports dual AHB masters
+ * or not.
+ */
+struct vendor_data {
+ char *name;
+ u8 channels;
+ bool dualmaster;
+};
+
+/*
+ * PL08X private data structures
+ * An LLI struct - see pl08x TRM
+ * Note that next uses bit[0] as a bus bit,
+ * start & end do not - their bus bit info
+ * is in cctl
+ */
+struct lli {
+ dma_addr_t src;
+ dma_addr_t dst;
+ dma_addr_t next;
+ u32 cctl;
+};
+
+/**
+ * struct pl08x_driver_data - the local state holder for the PL08x
+ * @base: virtual memory base (remapped) for the PL08x
+ * @adev: the corresponding AMBA (PrimeCell) bus entry
+ * @vd: vendor data for this PL08x variant
+ * @pd: platform data passed in from the platform/machine
+ * @clk: a clock to be enabled for this device to run
+ * @phy_chans: array of data for the physical channels
+ * @pool: a pool for the LLI descriptors
+ * @pool_ctr: counter of LLIs in the pool
+ * @lock: a spinlock for this struct
+ */
+struct pl08x_driver_data {
+ void __iomem *base;
+ struct amba_device *adev;
+ struct vendor_data *vd;
+ struct pl08x_platform_data *pd;
+ struct clk *clk;
+ struct pl08x_phy_chan *phy_chans;
+ struct dma_pool *pool;
+ int pool_ctr;
+ spinlock_t lock;
+};
+
+#ifdef MODULE
+
+# error "AMBA PL08X DMA CANNOT BE COMPILED AS A LOADABLE MODULE AT PRESENT"
+
+/*
+ a) Some devices might make use of DMA during boot
+ (esp true for DMAENGINE implementation)
+ b) Memory allocation will need much more attention
+ before load/unload can be supported
+ */
+#endif
+
+/*
+ * PL08X specific defines
+ */
+
+/*
+ * Memory boundaries: the manual for PL08x says that the controller
+ * cannot read past a 1KiB boundary, so these defines are used to
+ * create transfer LLIs that do not cross such boundaries.
+ */
+#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */
+#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT)
+
+/* Minimum period between work queue runs */
+#define PL08X_WQ_PERIODMIN 20
+
+/* Size (bytes) of each LLI buffer allocated for one transfer */
+# define PL08X_LLI_TSFR_SIZE 0x2000
+
+/* Maximimum times we call dma_pool_alloc on this pool without freeing */
+#define PL08X_MAX_ALLOCS 0x40
+#define MAX_NUM_TSFR_LLIS (PL08X_LLI_TSFR_SIZE/sizeof(struct lli))
+#define PL08X_ALIGN 8
+
+static inline struct pl08x_dma_chan *to_pl08x_chan(struct dma_chan *chan)
+{
+ return container_of(chan, struct pl08x_dma_chan, chan);
+}
+
+/*
+ * Physical channel handling
+ */
+
+/* Whether a certain channel is busy or not */
+static int pl08x_phy_channel_busy(struct pl08x_phy_chan *ch)
+{
+ unsigned int val;
+
+ val = readl(ch->base + PL080_CH_CONFIG);
+ return val & PL080_CONFIG_ACTIVE;
+}
+
+/*
+ * Set the initial DMA register values i.e. those for the first LLI
+ * The next lli pointer and the configuration interrupt bit have
+ * been set when the LLIs were constructed
+ */
+static void pl08x_set_cregs(struct pl08x_driver_data *pl08x,
+ struct pl08x_phy_chan *ch)
+{
+ /* Wait for channel inactive */
+ while (pl08x_phy_channel_busy(ch))
+ ;
+
+ dev_vdbg(&pl08x->adev->dev,
+ "WRITE channel %d: csrc=%08x, cdst=%08x, "
+ "cctl=%08x, clli=%08x, ccfg=%08x\n",
+ ch->id,
+ ch->csrc,
+ ch->cdst,
+ ch->cctl,
+ ch->clli,
+ ch->ccfg);
+
+ writel(ch->csrc, ch->base + PL080_CH_SRC_ADDR);
+ writel(ch->cdst, ch->base + PL080_CH_DST_ADDR);
+ writel(ch->clli, ch->base + PL080_CH_LLI);
+ writel(ch->cctl, ch->base + PL080_CH_CONTROL);
+ writel(ch->ccfg, ch->base + PL080_CH_CONFIG);
+}
+
+static inline void pl08x_config_phychan_for_txd(struct pl08x_dma_chan *plchan)
+{
+ struct pl08x_channel_data *cd = plchan->cd;
+ struct pl08x_phy_chan *phychan = plchan->phychan;
+ struct pl08x_txd *txd = plchan->at;
+
+ /* Copy the basic control register calculated at transfer config */
+ phychan->csrc = txd->csrc;
+ phychan->cdst = txd->cdst;
+ phychan->clli = txd->clli;
+ phychan->cctl = txd->cctl;
+
+ /* Assign the signal to the proper control registers */
+ phychan->ccfg = cd->ccfg;
+ phychan->ccfg &= ~PL080_CONFIG_SRC_SEL_MASK;
+ phychan->ccfg &= ~PL080_CONFIG_DST_SEL_MASK;
+ /* If it wasn't set from AMBA, ignore it */
+ if (txd->direction == DMA_TO_DEVICE)
+ /* Select signal as destination */
+ phychan->ccfg |=
+ (phychan->signal << PL080_CONFIG_DST_SEL_SHIFT);
+ else if (txd->direction == DMA_FROM_DEVICE)
+ /* Select signal as source */
+ phychan->ccfg |=
+ (phychan->signal << PL080_CONFIG_SRC_SEL_SHIFT);
+ /* Always enable error interrupts */
+ phychan->ccfg |= PL080_CONFIG_ERR_IRQ_MASK;
+ /* Always enable terminal interrupts */
+ phychan->ccfg |= PL080_CONFIG_TC_IRQ_MASK;
+}
+
+/*
+ * Enable the DMA channel
+ * Assumes all other configuration bits have been set
+ * as desired before this code is called
+ */
+static void pl08x_enable_phy_chan(struct pl08x_driver_data *pl08x,
+ struct pl08x_phy_chan *ch)
+{
+ u32 val;
+
+ /*
+ * Do not access config register until channel shows as disabled
+ */
+ while (readl(pl08x->base + PL080_EN_CHAN) & (1 << ch->id))
+ ;
+
+ /*
+ * Do not access config register until channel shows as inactive
+ */
+ val = readl(ch->base + PL080_CH_CONFIG);
+ while ((val & PL080_CONFIG_ACTIVE) || (val & PL080_CONFIG_ENABLE))
+ val = readl(ch->base + PL080_CH_CONFIG);
+
+ writel(val | PL080_CONFIG_ENABLE, ch->base + PL080_CH_CONFIG);
+}
+
+/*
+ * Overall DMAC remains enabled always.
+ *
+ * Disabling individual channels could lose data.
+ *
+ * Disable the peripheral DMA after disabling the DMAC
+ * in order to allow the DMAC FIFO to drain, and
+ * hence allow the channel to show inactive
+ *
+ */
+static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch)
+{
+ u32 val;
+
+ /* Set the HALT bit and wait for the FIFO to drain */
+ val = readl(ch->base + PL080_CH_CONFIG);
+ val |= PL080_CONFIG_HALT;
+ writel(val, ch->base + PL080_CH_CONFIG);
+
+ /* Wait for channel inactive */
+ while (pl08x_phy_channel_busy(ch))
+ ;
+}
+
+static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch)
+{
+ u32 val;
+
+ /* Clear the HALT bit */
+ val = readl(ch->base + PL080_CH_CONFIG);
+ val &= ~PL080_CONFIG_HALT;
+ writel(val, ch->base + PL080_CH_CONFIG);
+}
+
+
+/* Stops the channel */
+static void pl08x_stop_phy_chan(struct pl08x_phy_chan *ch)
+{
+ u32 val;
+
+ pl08x_pause_phy_chan(ch);
+
+ /* Disable channel */
+ val = readl(ch->base + PL080_CH_CONFIG);
+ val &= ~PL080_CONFIG_ENABLE;
+ writel(val, ch->base + PL080_CH_CONFIG);
+}
+
+static inline u32 get_bytes_in_cctl(u32 cctl)
+{
+ /* The source width defines the number of bytes */
+ u32 bytes = cctl & PL080_CONTROL_TRANSFER_SIZE_MASK;
+
+ switch (cctl >> PL080_CONTROL_SWIDTH_SHIFT) {
+ case PL080_WIDTH_8BIT:
+ break;
+ case PL080_WIDTH_16BIT:
+ bytes *= 2;
+ break;
+ case PL080_WIDTH_32BIT:
+ bytes *= 4;
+ break;
+ }
+ return bytes;
+}
+
+/* The channel should be paused when calling this */
+static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
+{
+ struct pl08x_phy_chan *ch;
+ struct pl08x_txd *txdi = NULL;
+ struct pl08x_txd *txd;
+ unsigned long flags;
+ u32 bytes = 0;
+
+ spin_lock_irqsave(&plchan->lock, flags);
+
+ ch = plchan->phychan;
+ txd = plchan->at;
+
+ /*
+ * Next follow the LLIs to get the number of pending bytes in the
+ * currently active transaction.
+ */
+ if (ch && txd) {
+ struct lli *llis_va = txd->llis_va;
+ struct lli *llis_bus = (struct lli *) txd->llis_bus;
+ u32 clli = readl(ch->base + PL080_CH_LLI);
+
+ /* First get the bytes in the current active LLI */
+ bytes = get_bytes_in_cctl(readl(ch->base + PL080_CH_CONTROL));
+
+ if (clli) {
+ int i = 0;
+
+ /* Forward to the LLI pointed to by clli */
+ while ((clli != (u32) &(llis_bus[i])) &&
+ (i < MAX_NUM_TSFR_LLIS))
+ i++;
+
+ while (clli) {
+ bytes += get_bytes_in_cctl(llis_va[i].cctl);
+ /*
+ * A clli of 0x00000000 will terminate the
+ * LLI list
+ */
+ clli = llis_va[i].next;
+ i++;
+ }
+ }
+ }
+
+ /* Sum up all queued transactions */
+ if (!list_empty(&plchan->desc_list)) {
+ list_for_each_entry(txdi, &plchan->desc_list, node) {
+ bytes += txdi->len;
+ }
+
+ }
+
+ spin_unlock_irqrestore(&plchan->lock, flags);
+
+ return bytes;
+}
+
+/*
+ * Allocate a physical channel for a virtual channel
+ */
+static struct pl08x_phy_chan *
+pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
+ struct pl08x_dma_chan *virt_chan)
+{
+ struct pl08x_phy_chan *ch = NULL;
+ unsigned long flags;
+ int i;
+
+ /*
+ * Try to locate a physical channel to be used for
+ * this transfer. If all are taken return NULL and
+ * the requester will have to cope by using some fallback
+ * PIO mode or retrying later.
+ */
+ for (i = 0; i < pl08x->vd->channels; i++) {
+ ch = &pl08x->phy_chans[i];
+
+ spin_lock_irqsave(&ch->lock, flags);
+
+ if (!ch->serving) {
+ ch->serving = virt_chan;
+ ch->signal = -1;
+ spin_unlock_irqrestore(&ch->lock, flags);
+ break;
+ }
+
+ spin_unlock_irqrestore(&ch->lock, flags);
+ }
+
+ if (i == pl08x->vd->channels) {
+ /* No physical channel available, cope with it */
+ return NULL;
+ }
+
+ return ch;
+}
+
+static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x,
+ struct pl08x_phy_chan *ch)
+{
+ unsigned long flags;
+
+ /* Stop the channel and clear its interrupts */
+ pl08x_stop_phy_chan(ch);
+ writel((1 << ch->id), pl08x->base + PL080_ERR_CLEAR);
+ writel((1 << ch->id), pl08x->base + PL080_TC_CLEAR);
+
+ /* Mark it as free */
+ spin_lock_irqsave(&ch->lock, flags);
+ ch->serving = NULL;
+ ch->signal = -1;
+ spin_unlock_irqrestore(&ch->lock, flags);
+}
+
+/*
+ * LLI handling
+ */
+
+static inline unsigned int pl08x_get_bytes_for_cctl(unsigned int coded)
+{
+ switch (coded) {
+ case PL080_WIDTH_8BIT:
+ return 1;
+ case PL080_WIDTH_16BIT:
+ return 2;
+ case PL080_WIDTH_32BIT:
+ return 4;
+ default:
+ break;
+ }
+ BUG();
+ return 0;
+}
+
+static inline u32 pl08x_cctl_bits(u32 cctl, u8 srcwidth, u8 dstwidth,
+ u32 tsize)
+{
+ u32 retbits = cctl;
+
+ /* Remove all src, dst and transfersize bits */
+ retbits &= ~PL080_CONTROL_DWIDTH_MASK;
+ retbits &= ~PL080_CONTROL_SWIDTH_MASK;
+ retbits &= ~PL080_CONTROL_TRANSFER_SIZE_MASK;
+
+ /* Then set the bits according to the parameters */
+ switch (srcwidth) {
+ case 1:
+ retbits |= PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT;
+ break;
+ case 2:
+ retbits |= PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT;
+ break;
+ case 4:
+ retbits |= PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ switch (dstwidth) {
+ case 1:
+ retbits |= PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT;
+ break;
+ case 2:
+ retbits |= PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT;
+ break;
+ case 4:
+ retbits |= PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ retbits |= tsize << PL080_CONTROL_TRANSFER_SIZE_SHIFT;
+ return retbits;
+}
+
+/*
+ * Autoselect a master bus to use for the transfer
+ * this prefers the destination bus if both available
+ * if fixed address on one bus the other will be chosen
+ */
+void pl08x_choose_master_bus(struct pl08x_bus_data *src_bus,
+ struct pl08x_bus_data *dst_bus, struct pl08x_bus_data **mbus,
+ struct pl08x_bus_data **sbus, u32 cctl)
+{
+ if (!(cctl & PL080_CONTROL_DST_INCR)) {
+ *mbus = src_bus;
+ *sbus = dst_bus;
+ } else if (!(cctl & PL080_CONTROL_SRC_INCR)) {
+ *mbus = dst_bus;
+ *sbus = src_bus;
+ } else {
+ if (dst_bus->buswidth == 4) {
+ *mbus = dst_bus;
+ *sbus = src_bus;
+ } else if (src_bus->buswidth == 4) {
+ *mbus = src_bus;
+ *sbus = dst_bus;
+ } else if (dst_bus->buswidth == 2) {
+ *mbus = dst_bus;
+ *sbus = src_bus;
+ } else if (src_bus->buswidth == 2) {
+ *mbus = src_bus;
+ *sbus = dst_bus;
+ } else {
+ /* src_bus->buswidth == 1 */
+ *mbus = dst_bus;
+ *sbus = src_bus;
+ }
+ }
+}
+
+/*
+ * Fills in one LLI for a certain transfer descriptor
+ * and advance the counter
+ */
+int pl08x_fill_lli_for_desc(struct pl08x_driver_data *pl08x,
+ struct pl08x_txd *txd, int num_llis, int len,
+ u32 cctl, u32 *remainder)
+{
+ struct lli *llis_va = txd->llis_va;
+ struct lli *llis_bus = (struct lli *) txd->llis_bus;
+
+ BUG_ON(num_llis >= MAX_NUM_TSFR_LLIS);
+
+ llis_va[num_llis].cctl = cctl;
+ llis_va[num_llis].src = txd->srcbus.addr;
+ llis_va[num_llis].dst = txd->dstbus.addr;
+
+ /*
+ * On versions with dual masters, you can optionally AND on
+ * PL080_LLI_LM_AHB2 to the LLI to tell the hardware to read
+ * in new LLIs with that controller, but we always try to
+ * choose AHB1 to point into memory. The idea is to have AHB2
+ * fixed on the peripheral and AHB1 messing around in the
+ * memory. So we don't manipulate this bit currently.
+ */
+
+ llis_va[num_llis].next =
+ (dma_addr_t)((u32) &(llis_bus[num_llis + 1]));
+
+ if (cctl & PL080_CONTROL_SRC_INCR)
+ txd->srcbus.addr += len;
+ if (cctl & PL080_CONTROL_DST_INCR)
+ txd->dstbus.addr += len;
+
+ *remainder -= len;
+
+ return num_llis + 1;
+}
+
+/*
+ * Return number of bytes to fill to boundary, or len
+ */
+static inline u32 pl08x_pre_boundary(u32 addr, u32 len)
+{
+ u32 boundary;
+
+ boundary = ((addr >> PL08X_BOUNDARY_SHIFT) + 1)
+ << PL08X_BOUNDARY_SHIFT;
+
+ if (boundary < addr + len)
+ return boundary - addr;
+ else
+ return len;
+}
+
+/*
+ * This fills in the table of LLIs for the transfer descriptor
+ * Note that we assume we never have to change the burst sizes
+ * Return 0 for error
+ */
+static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
+ struct pl08x_txd *txd)
+{
+ struct pl08x_channel_data *cd = txd->cd;
+ struct pl08x_bus_data *mbus, *sbus;
+ u32 remainder;
+ int num_llis = 0;
+ u32 cctl;
+ int max_bytes_per_lli;
+ int total_bytes = 0;
+ struct lli *llis_va;
+ struct lli *llis_bus;
+
+ if (!txd) {
+ dev_err(&pl08x->adev->dev, "%s no descriptor\n", __func__);
+ return 0;
+ }
+
+ txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_KERNEL,
+ &txd->llis_bus);
+ if (!txd->llis_va) {
+ dev_err(&pl08x->adev->dev, "%s no memory for llis\n", __func__);
+ return 0;
+ }
+
+ pl08x->pool_ctr++;
+
+ /*
+ * Initialize bus values for this transfer
+ * from the passed optimal values
+ */
+ if (!cd) {
+ dev_err(&pl08x->adev->dev, "%s no channel data\n", __func__);
+ return 0;
+ }
+
+ /* Get the default CCTL from the platform data */
+ cctl = cd->cctl;
+
+ /*
+ * On the PL080 we have two bus masters and we
+ * should select one for source and one for
+ * destination. We try to use AHB2 for the
+ * bus which does not increment (typically the
+ * peripheral) else we just choose something.
+ */
+ cctl &= ~(PL080_CONTROL_DST_AHB2 | PL080_CONTROL_SRC_AHB2);
+ if (pl08x->vd->dualmaster) {
+ if (cctl & PL080_CONTROL_SRC_INCR)
+ /* Source increments, use AHB2 for destination */
+ cctl |= PL080_CONTROL_DST_AHB2;
+ else if (cctl & PL080_CONTROL_DST_INCR)
+ /* Destination increments, use AHB2 for source */
+ cctl |= PL080_CONTROL_SRC_AHB2;
+ else
+ /* Just pick something, source AHB1 dest AHB2 */
+ cctl |= PL080_CONTROL_DST_AHB2;
+ }
+
+ /* Find maximum width of the source bus */
+ txd->srcbus.maxwidth =
+ pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_SWIDTH_MASK) >>
+ PL080_CONTROL_SWIDTH_SHIFT);
+
+ /* Find maximum width of the destination bus */
+ txd->dstbus.maxwidth =
+ pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_DWIDTH_MASK) >>
+ PL080_CONTROL_DWIDTH_SHIFT);
+
+ /* Set up the bus widths to the maximum */
+ txd->srcbus.buswidth = txd->srcbus.maxwidth;
+ txd->dstbus.buswidth = txd->dstbus.maxwidth;
+ dev_vdbg(&pl08x->adev->dev,
+ "%s source bus is %d bytes wide, dest bus is %d bytes wide\n",
+ __func__, txd->srcbus.buswidth, txd->dstbus.buswidth);
+
+
+ /*
+ * Bytes transferred == tsize * MIN(buswidths), not max(buswidths)
+ */
+ max_bytes_per_lli = min(txd->srcbus.buswidth, txd->dstbus.buswidth) *
+ PL080_CONTROL_TRANSFER_SIZE_MASK;
+ dev_vdbg(&pl08x->adev->dev,
+ "%s max bytes per lli = %d\n",
+ __func__, max_bytes_per_lli);
+
+ /* We need to count this down to zero */
+ remainder = txd->len;
+ dev_vdbg(&pl08x->adev->dev,
+ "%s remainder = %d\n",
+ __func__, remainder);
+
+ /*
+ * Choose bus to align to
+ * - prefers destination bus if both available
+ * - if fixed address on one bus chooses other
+ * - modifies cctl to choose an apropriate master
+ */
+ pl08x_choose_master_bus(&txd->srcbus, &txd->dstbus,
+ &mbus, &sbus, cctl);
+
+
+ /*
+ * The lowest bit of the LLI register
+ * is also used to indicate which master to
+ * use for reading the LLIs.
+ */
+
+ if (txd->len < mbus->buswidth) {
+ /*
+ * Less than a bus width available
+ * - send as single bytes
+ */
+ while (remainder) {
+ dev_vdbg(&pl08x->adev->dev,
+ "%s single byte LLIs for a transfer of "
+ "less than a bus width (remain %08x)\n",
+ __func__, remainder);
+ cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
+ num_llis =
+ pl08x_fill_lli_for_desc(pl08x, txd, num_llis, 1,
+ cctl, &remainder);
+ total_bytes++;
+ }
+ } else {
+ /*
+ * Make one byte LLIs until master bus is aligned
+ * - slave will then be aligned also
+ */
+ while ((mbus->addr) % (mbus->buswidth)) {
+ dev_vdbg(&pl08x->adev->dev,
+ "%s adjustment lli for less than bus width "
+ "(remain %08x)\n",
+ __func__, remainder);
+ cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
+ num_llis = pl08x_fill_lli_for_desc
+ (pl08x, txd, num_llis, 1, cctl, &remainder);
+ total_bytes++;
+ }
+
+ /*
+ * Master now aligned
+ * - if slave is not then we must set its width down
+ */
+ if (sbus->addr % sbus->buswidth) {
+ dev_dbg(&pl08x->adev->dev,
+ "%s set down bus width to one byte\n",
+ __func__);
+
+ sbus->buswidth = 1;
+ }
+
+ /*
+ * Make largest possible LLIs until less than one bus
+ * width left
+ */
+ while (remainder > (mbus->buswidth - 1)) {
+ int lli_len, target_len;
+ int tsize;
+ int odd_bytes;
+
+ /*
+ * If enough left try to send max possible,
+ * otherwise try to send the remainder
+ */
+ target_len = remainder;
+ if (remainder > max_bytes_per_lli)
+ target_len = max_bytes_per_lli;
+
+ /*
+ * Set bus lengths for incrementing busses
+ * to number of bytes which fill to next memory
+ * boundary
+ */
+ if (cctl & PL080_CONTROL_SRC_INCR)
+ txd->srcbus.fill_bytes =
+ pl08x_pre_boundary(
+ txd->srcbus.addr,
+ remainder);
+ else
+ txd->srcbus.fill_bytes =
+ max_bytes_per_lli;
+
+ if (cctl & PL080_CONTROL_DST_INCR)
+ txd->dstbus.fill_bytes =
+ pl08x_pre_boundary(
+ txd->dstbus.addr,
+ remainder);
+ else
+ txd->dstbus.fill_bytes =
+ max_bytes_per_lli;
+
+ /*
+ * Find the nearest
+ */
+ lli_len = min(txd->srcbus.fill_bytes,
+ txd->dstbus.fill_bytes);
+
+ BUG_ON(lli_len > remainder);
+
+ if (lli_len <= 0) {
+ dev_err(&pl08x->adev->dev,
+ "%s lli_len is %d, <= 0\n",
+ __func__, lli_len);
+ return 0;
+ }
+
+ if (lli_len == target_len) {
+ /*
+ * Can send what we wanted
+ */
+ /*
+ * Maintain alignment
+ */
+ lli_len = (lli_len/mbus->buswidth) *
+ mbus->buswidth;
+ odd_bytes = 0;
+ } else {
+ /*
+ * So now we know how many bytes to transfer
+ * to get to the nearest boundary
+ * The next lli will past the boundary
+ * - however we may be working to a boundary
+ * on the slave bus
+ * We need to ensure the master stays aligned
+ */
+ odd_bytes = lli_len % mbus->buswidth;
+ /*
+ * - and that we are working in multiples
+ * of the bus widths
+ */
+ lli_len -= odd_bytes;
+
+ }
+
+ if (lli_len) {
+ /*
+ * Check against minimum bus alignment:
+ * Calculate actual transfer size in relation
+ * to bus width an get a maximum remainder of
+ * the smallest bus width - 1
+ */
+ /* FIXME: use round_down()? */
+ tsize = lli_len / min(mbus->buswidth,
+ sbus->buswidth);
+ lli_len = tsize * min(mbus->buswidth,
+ sbus->buswidth);
+
+ if (target_len != lli_len) {
+ dev_vdbg(&pl08x->adev->dev,
+ "%s can't send what we want. Desired %08x, lli of %08x bytes in txd of %08x\n",
+ __func__, target_len, lli_len, txd->len);
+ }
+
+ cctl = pl08x_cctl_bits(cctl,
+ txd->srcbus.buswidth,
+ txd->dstbus.buswidth,
+ tsize);
+
+ dev_vdbg(&pl08x->adev->dev,
+ "%s fill lli with single lli chunk of size %08x (remainder %08x)\n",
+ __func__, lli_len, remainder);
+ num_llis = pl08x_fill_lli_for_desc(pl08x, txd,
+ num_llis, lli_len, cctl,
+ &remainder);
+ total_bytes += lli_len;
+ }
+
+
+ if (odd_bytes) {
+ /*
+ * Creep past the boundary,
+ * maintaining master alignment
+ */
+ int j;
+ for (j = 0; (j < mbus->buswidth)
+ && (remainder); j++) {
+ cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
+ dev_vdbg(&pl08x->adev->dev,
+ "%s align with boundardy, single byte (remain %08x)\n",
+ __func__, remainder);
+ num_llis =
+ pl08x_fill_lli_for_desc(pl08x,
+ txd, num_llis, 1,
+ cctl, &remainder);
+ total_bytes++;
+ }
+ }
+ }
+
+ /*
+ * Send any odd bytes
+ */
+ if (remainder < 0) {
+ dev_err(&pl08x->adev->dev, "%s remainder not fitted 0x%08x bytes\n",
+ __func__, remainder);
+ return 0;
+ }
+
+ while (remainder) {
+ cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
+ dev_vdbg(&pl08x->adev->dev,
+ "%s align with boundardy, single odd byte (remain %d)\n",
+ __func__, remainder);
+ num_llis = pl08x_fill_lli_for_desc(pl08x, txd, num_llis,
+ 1, cctl, &remainder);
+ total_bytes++;
+ }
+ }
+ if (total_bytes != txd->len) {
+ dev_err(&pl08x->adev->dev,
+ "%s size of encoded lli:s don't match total txd, transferred 0x%08x from size 0x%08x\n",
+ __func__, total_bytes, txd->len);
+ return 0;
+ }
+
+ if (num_llis >= MAX_NUM_TSFR_LLIS) {
+ dev_err(&pl08x->adev->dev,
+ "%s need to increase MAX_NUM_TSFR_LLIS from 0x%08x\n",
+ __func__, (u32) MAX_NUM_TSFR_LLIS);
+ return 0;
+ }
+ /*
+ * Decide whether this is a loop or a terminated transfer
+ */
+ llis_va = txd->llis_va;
+ llis_bus = (struct lli *) txd->llis_bus;
+
+ if (cd->circular_buffer) {
+ /*
+ * Loop the circular buffer so that the next element
+ * points back to the beginning of the LLI.
+ */
+ llis_va[num_llis - 1].next =
+ (dma_addr_t)((unsigned int)&(llis_bus[0]));
+ } else {
+ /*
+ * On non-circular buffers, the final LLI terminates
+ * the LLI.
+ */
+ llis_va[num_llis - 1].next = 0;
+ /*
+ * The final LLI element shall also fire an interrupt
+ */
+ llis_va[num_llis - 1].cctl |= PL080_CONTROL_TC_IRQ_EN;
+ }
+
+ /* Now store the channel register values */
+ txd->csrc = llis_va[0].src;
+ txd->cdst = llis_va[0].dst;
+ if (num_llis > 1)
+ txd->clli = llis_va[0].next;
+ else
+ txd->clli = 0;
+
+ txd->cctl = llis_va[0].cctl;
+ /* ccfg will be set at physical channel allocation time */
+
+#ifdef VERBOSE_DEBUG
+ {
+ int i;
+
+ for (i = 0; i < num_llis; i++) {
+ dev_vdbg(&pl08x->adev->dev,
+ "lli %d @%p: csrc=%08x, cdst=%08x, cctl=%08x, clli=%08x\n",
+ i,
+ &llis_va[i],
+ llis_va[i].src,
+ llis_va[i].dst,
+ llis_va[i].cctl,
+ llis_va[i].next
+ );
+ }
+ }
+#endif
+
+ return num_llis;
+}
+
+/* You should call this with the struct pl08x lock held */
+static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
+ struct pl08x_txd *txd)
+{
+ if (!txd)
+ dev_err(&pl08x->adev->dev,
+ "%s no descriptor to free\n",
+ __func__);
+
+ /* Free the LLI */
+ dma_pool_free(pl08x->pool, txd->llis_va,
+ txd->llis_bus);
+
+ pl08x->pool_ctr--;
+
+ kfree(txd);
+}
+
+static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
+ struct pl08x_dma_chan *plchan)
+{
+ struct pl08x_txd *txdi = NULL;
+ struct pl08x_txd *next;
+
+ if (!list_empty(&plchan->desc_list)) {
+ list_for_each_entry_safe(txdi,
+ next, &plchan->desc_list, node) {
+ list_del(&txdi->node);
+ pl08x_free_txd(pl08x, txdi);
+ }
+
+ }
+}
+
+static void pl08x_tasklet(unsigned long data)
+{
+ struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
+ struct pl08x_phy_chan *phychan = plchan->phychan;
+ struct pl08x_driver_data *pl08x = plchan->host;
+ unsigned long flags;
+
+ if (!plchan)
+ BUG();
+
+ spin_lock_irqsave(&plchan->lock, flags);
+
+ if (plchan->at) {
+ dma_async_tx_callback callback =
+ plchan->at->tx.callback;
+ void *callback_param =
+ plchan->at->tx.callback_param;
+
+ /*
+ * Update last completed
+ */
+ plchan->lc =
+ (plchan->at->tx.cookie);
+
+ /*
+ * Callback to signal completion
+ */
+ if (callback)
+ callback(callback_param);
+
+ /*
+ * Device callbacks should NOT clear
+ * the current transaction on the channel
+ * Linus: sometimes they should?
+ */
+ if (!plchan->at)
+ BUG();
+
+ /*
+ * Free the descriptor if it's not for a device
+ * using a circular buffer
+ */
+ if (!plchan->at->cd->circular_buffer) {
+ pl08x_free_txd(pl08x, plchan->at);
+ plchan->at = NULL;
+ }
+ /*
+ * else descriptor for circular
+ * buffers only freed when
+ * client has disabled dma
+ */
+ }
+ /*
+ * If a new descriptor is queued, set it up
+ * plchan->at is NULL here
+ */
+ if (!list_empty(&plchan->desc_list)) {
+ struct pl08x_txd *next;
+
+ next = list_first_entry(&plchan->desc_list,
+ struct pl08x_txd,
+ node);
+ list_del(&next->node);
+ plchan->at = next;
+ /* Configure the physical channel for the next txd */
+ pl08x_config_phychan_for_txd(plchan);
+ pl08x_set_cregs(pl08x, plchan->phychan);
+ pl08x_enable_phy_chan(pl08x, plchan->phychan);
+ } else {
+ /*
+ * No more jobs, so free up the physical channel
+ * Free any allocated signal on slave transfers too
+ */
+ if ((phychan->signal >= 0) && pl08x->pd->put_signal)
+ pl08x->pd->put_signal(plchan);
+ pl08x_put_phy_channel(pl08x, phychan);
+ plchan->phychan = NULL;
+ }
+
+ spin_unlock_irqrestore(&plchan->lock, flags);
+}
+
+static irqreturn_t pl08x_irq(int irq, void *dev)
+{
+ struct pl08x_driver_data *pl08x = dev;
+ u32 mask = 0;
+ u32 val;
+ int i;
+
+ val = readl(pl08x->base + PL080_ERR_STATUS);
+ if (val) {
+ /*
+ * An error interrupt (on one or more channels)
+ */
+ dev_err(&pl08x->adev->dev,
+ "%s error interrupt, register value 0x%08x\n",
+ __func__, val);
+ /*
+ * Simply clear ALL PL08X error interrupts,
+ * regardless of channel and cause
+ * FIXME: should be 0x00000003 on PL081 really.
+ */
+ writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR);
+ }
+ val = readl(pl08x->base + PL080_INT_STATUS);
+ for (i = 0; i < pl08x->vd->channels; i++) {
+ if ((1 << i) & val) {
+ /* Locate physical channel */
+ struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
+ struct pl08x_dma_chan *plchan = phychan->serving;
+
+ /* Schedule tasklet on this channel */
+ tasklet_schedule(&plchan->tasklet);
+
+ mask |= (1 << i);
+ }
+ }
+ /*
+ * Clear only the terminal interrupts on channels we processed
+ */
+ writel(mask, pl08x->base + PL080_TC_CLEAR);
+
+ return mask ? IRQ_HANDLED : IRQ_NONE;
+}
+
+
+/*
+ * The DMA ENGINE API
+ */
+static int pl08x_alloc_chan_resources(struct dma_chan *chan)
+{
+ return 0;
+}
+
+static void pl08x_free_chan_resources(struct dma_chan *chan)
+{
+}
+
+/*
+ * This should be called with the channel plchan->lock held
+ */
+static int prep_phy_channel(struct pl08x_dma_chan *plchan,
+ struct pl08x_txd *txd)
+{
+ struct pl08x_driver_data *pl08x = plchan->host;
+ struct pl08x_phy_chan *ch;
+ int ret;
+
+ /* Check if we already have a channel */
+ if (plchan->phychan)
+ return 0;
+
+ ch = pl08x_get_phy_channel(pl08x, plchan);
+ if (!ch) {
+ /* No physical channel available, cope with it */
+ dev_dbg(&pl08x->adev->dev, "no physical channel available for xfer on %s\n", plchan->name);
+ return -EBUSY;
+ }
+
+ /*
+ * OK we have a physical channel: for memcpy() this is all we
+ * need, but for slaves the physical siglals may be muxed!
+ * Can the platform allow us to use this channel?
+ */
+ if ((txd->direction == DMA_FROM_DEVICE ||
+ txd->direction == DMA_TO_DEVICE) &&
+ pl08x->pd->get_signal) {
+ ret = pl08x->pd->get_signal(plchan);
+ if (ret < 0) {
+ dev_dbg(&pl08x->adev->dev,
+ "unable to use physical channel %d for transfer on %s due to platform restrictions\n",
+ ch->id, plchan->name);
+ /* Release physical channel & return */
+ pl08x_put_phy_channel(pl08x, ch);
+ return -EBUSY;
+ }
+ ch->signal = ret;
+ }
+
+ dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n",
+ ch->id,
+ ch->signal,
+ plchan->name);
+
+ plchan->phychan = ch;
+
+ return 0;
+}
+
+/*
+ * First make the LLIs (could/should we do this earlier??)
+ * slave (m/p) - no queued transactions allowed at present
+ * TODO allow queued transactions for non circular buffers
+ * Set up the channel active txd as inactive
+ * m2m - transactions may be queued
+ * If no active txd on channel
+ * set it up as inactive
+ * - issue_pending() will set active & start
+ * else
+ * queue it
+ * Lock channel since there may be (at least for m2m) multiple calls
+ *
+ * Return < 0 for error
+ */
+
+static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ int num_llis;
+ unsigned long flags;
+ struct pl08x_txd *txd = container_of(tx, struct pl08x_txd, tx);
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ int ret;
+
+ num_llis = pl08x_fill_llis_for_desc(pl08x, txd);
+
+ if (!num_llis)
+ return -EINVAL;
+
+ spin_lock_irqsave(&plchan->lock, flags);
+
+ atomic_inc(&plchan->last_issued);
+ tx->cookie = atomic_read(&plchan->last_issued);
+
+ /*
+ * If this device is not using a circular buffer then
+ * queue this new descriptor for transfer.
+ * The descriptor for a circular buffer continues
+ * to be used until the channel is freed.
+ */
+ if (txd->cd->circular_buffer)
+ dev_err(&pl08x->adev->dev,
+ "%s attempting to queue a circular buffer\n",
+ __func__);
+ else
+ list_add_tail(&txd->node,
+ &plchan->desc_list);
+
+ /*
+ * See if we already have a physical channel allocated,
+ * else this is the time to try to get one.
+ */
+ ret = prep_phy_channel(plchan, txd);
+ if (ret) {
+ /* No physical channel available, cope with it */
+ spin_unlock_irqrestore(&plchan->lock, flags);
+ return -EBUSY;
+ }
+
+ spin_unlock_irqrestore(&plchan->lock, flags);
+
+ return tx->cookie;
+}
+
+static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
+ struct dma_chan *chan, unsigned long flags)
+{
+ struct dma_async_tx_descriptor *retval = NULL;
+
+ return retval;
+}
+
+/*
+ * Code accessing dma_async_is_complete() in a tight loop
+ * may give problems - could schedule where indicated.
+ * If slaves are relying on interrupts to signal completion this
+ * function must not be called with interrupts disabled
+ */
+static enum dma_status
+pl08x_dma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+ enum dma_status ret;
+ u32 bytesleft = 0;
+
+ last_used = atomic_read(&plchan->last_issued);
+ last_complete = plchan->lc;
+
+ ret = dma_async_is_complete(cookie, last_complete, last_used);
+ if (ret == DMA_SUCCESS) {
+ dma_set_tx_state(txstate, last_complete, last_used, 0);
+ return ret;
+ }
+
+ /*
+ * schedule(); could be inserted here
+ */
+
+ /*
+ * This cookie not complete yet
+ */
+ last_used = atomic_read(&plchan->last_issued);
+ last_complete = plchan->lc;
+
+ /* Get number of bytes left in the active transactions and queue */
+ bytesleft = pl08x_getbytes_chan(plchan);
+
+ dma_set_tx_state(txstate, last_complete, last_used,
+ bytesleft);
+
+ if (plchan->paused)
+ return DMA_PAUSED;
+
+ return DMA_IN_PROGRESS;
+}
+
+/* PrimeCell DMA extension */
+struct burst_table {
+ int burstwords;
+ u32 reg;
+};
+
+static const struct burst_table burst_sizes[] = {
+ {
+ .burstwords = 256,
+ .reg = (PL080_BSIZE_256 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_256 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 128,
+ .reg = (PL080_BSIZE_128 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_128 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 64,
+ .reg = (PL080_BSIZE_64 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_64 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 32,
+ .reg = (PL080_BSIZE_32 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_32 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 16,
+ .reg = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 8,
+ .reg = (PL080_BSIZE_8 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_8 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 4,
+ .reg = (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+ {
+ .burstwords = 1,
+ .reg = (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT),
+ },
+};
+
+static void dma_set_runtime_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ struct pl08x_channel_data *cd = plchan->cd;
+ enum dma_slave_buswidth addr_width;
+ u32 maxburst;
+ u32 cctl = 0;
+ /* Mask out all except src and dst channel */
+ u32 ccfg = cd->ccfg & 0x000003DEU;
+ int i = 0;
+
+ /* Transfer direction */
+ plchan->runtime_direction = config->direction;
+ if (config->direction == DMA_TO_DEVICE) {
+ plchan->runtime_addr = config->dst_addr;
+ cctl |= PL080_CONTROL_SRC_INCR;
+ ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ addr_width = config->dst_addr_width;
+ maxburst = config->dst_maxburst;
+ } else if (config->direction == DMA_FROM_DEVICE) {
+ plchan->runtime_addr = config->src_addr;
+ cctl |= PL080_CONTROL_DST_INCR;
+ ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ addr_width = config->src_addr_width;
+ maxburst = config->src_maxburst;
+ } else {
+ dev_err(&pl08x->adev->dev,
+ "bad runtime_config: alien transfer direction\n");
+ return;
+ }
+
+ switch (addr_width) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ cctl |= (PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT) |
+ (PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT);
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ cctl |= (PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT) |
+ (PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT);
+ break;
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ cctl |= (PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT) |
+ (PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT);
+ break;
+ default:
+ dev_err(&pl08x->adev->dev,
+ "bad runtime_config: alien address width\n");
+ return;
+ }
+
+ /*
+ * Now decide on a maxburst:
+ * If this channel will only request single transfers, set
+ * this down to ONE element.
+ */
+ if (plchan->cd->single) {
+ cctl |= (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) |
+ (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT);
+ } else {
+ while (i < ARRAY_SIZE(burst_sizes)) {
+ if (burst_sizes[i].burstwords <= maxburst)
+ break;
+ i++;
+ }
+ cctl |= burst_sizes[i].reg;
+ }
+
+ /* Access the cell in privileged mode, non-bufferable, non-cacheable */
+ cctl &= ~PL080_CONTROL_PROT_MASK;
+ cctl |= PL080_CONTROL_PROT_SYS;
+
+ /* Modify the default channel data to fit PrimeCell request */
+ cd->cctl = cctl;
+ cd->ccfg = ccfg;
+
+ dev_dbg(&pl08x->adev->dev,
+ "configured channel %s (%s) for %s, data width %d, "
+ "maxburst %d words, LE, CCTL=%08x, CCFG=%08x\n",
+ dma_chan_name(chan), plchan->name,
+ (config->direction == DMA_FROM_DEVICE) ? "RX" : "TX",
+ addr_width,
+ maxburst,
+ cctl, ccfg);
+}
+
+/*
+ * Slave transactions callback to the slave device to allow
+ * synchronization of slave DMA signals with the DMAC enable
+ */
+static void pl08x_issue_pending(struct dma_chan *chan)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ unsigned long flags;
+
+
+ spin_lock_irqsave(&plchan->lock, flags);
+ /* Something is already active */
+ if (plchan->at) {
+ spin_unlock_irqrestore(&plchan->lock, flags);
+ return;
+ }
+
+ /* Take the first element in the queue and execute it */
+ if (!list_empty(&plchan->desc_list)) {
+ struct pl08x_txd *next;
+
+ next = list_first_entry(&plchan->desc_list,
+ struct pl08x_txd,
+ node);
+ list_del(&next->node);
+ plchan->at = next;
+
+ /* Configure the physical channel for the active txd */
+ pl08x_config_phychan_for_txd(plchan);
+ pl08x_set_cregs(pl08x, plchan->phychan);
+ pl08x_enable_phy_chan(pl08x, plchan->phychan);
+ }
+
+ spin_unlock_irqrestore(&plchan->lock, flags);
+}
+
+/*
+ * Initialize a descriptor to be used by memcpy submit
+ */
+static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
+ struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+ size_t len, unsigned long flags)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ struct pl08x_txd *txd;
+
+ txd = kzalloc(sizeof(struct pl08x_txd), GFP_KERNEL);
+ if (!txd) {
+ dev_err(&pl08x->adev->dev,
+ "%s no memory for descriptor\n", __func__);
+ return NULL;
+ }
+
+ dma_async_tx_descriptor_init(&txd->tx, chan);
+ txd->direction = DMA_NONE;
+ txd->srcbus.addr = src;
+ txd->dstbus.addr = dest;
+
+ /* Set platform data for m2m */
+ txd->cd = &pl08x->pd->memcpy_channel;
+ /* Both to be incremented or the code will break */
+ txd->cd->cctl |= PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR;
+ txd->tx.tx_submit = pl08x_tx_submit;
+ txd->tx.callback = NULL;
+ txd->tx.callback_param = NULL;
+ txd->len = len;
+
+ INIT_LIST_HEAD(&txd->node);
+
+ return &txd->tx;
+}
+
+struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_data_direction direction,
+ unsigned long flags)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ struct pl08x_txd *txd;
+
+ /*
+ * Current implementation ASSUMES only one sg
+ */
+ if (sg_len != 1) {
+ dev_err(&pl08x->adev->dev, "%s prepared too long sglist\n",
+ __func__);
+ BUG();
+ }
+
+ dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n",
+ __func__, sgl->length, plchan->name);
+
+ txd = kzalloc(sizeof(struct pl08x_txd), GFP_KERNEL);
+ if (!txd) {
+ dev_err(&pl08x->adev->dev, "%s no txd\n", __func__);
+ return NULL;
+ }
+
+ dma_async_tx_descriptor_init(&txd->tx, chan);
+
+ if (direction != plchan->runtime_direction)
+ dev_err(&pl08x->adev->dev, "%s DMA setup does not match "
+ "the direction configured for the PrimeCell\n",
+ __func__);
+
+ /*
+ * Set up addresses, the PrimeCell configured address
+ * will take precedence since this may configure the
+ * channel target address dynamically at runtime.
+ */
+ txd->direction = direction;
+ if (direction == DMA_TO_DEVICE) {
+ txd->srcbus.addr = sgl->dma_address;
+ if (plchan->runtime_addr)
+ txd->dstbus.addr = plchan->runtime_addr;
+ else
+ txd->dstbus.addr = plchan->cd->addr;
+ } else if (direction == DMA_FROM_DEVICE) {
+ if (plchan->runtime_addr)
+ txd->srcbus.addr = plchan->runtime_addr;
+ else
+ txd->srcbus.addr = plchan->cd->addr;
+ txd->dstbus.addr = sgl->dma_address;
+ } else {
+ dev_err(&pl08x->adev->dev,
+ "%s direction unsupported\n", __func__);
+ return NULL;
+ }
+ txd->cd = plchan->cd;
+ txd->tx.tx_submit = pl08x_tx_submit;
+ txd->tx.callback = NULL;
+ txd->tx.callback_param = NULL;
+ txd->len = sgl->length;
+ INIT_LIST_HEAD(&txd->node);
+
+ return &txd->tx;
+}
+
+static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+ unsigned long flags;
+ int ret = 0;
+
+ /* Controls applicable to inactive channels */
+ if (cmd == DMA_SLAVE_CONFIG) {
+ dma_set_runtime_config(chan,
+ (struct dma_slave_config *)
+ arg);
+ return 0;
+ }
+
+ /*
+ * Anything succeeds on channels with no physical allocation and
+ * no queued transfers.
+ */
+ spin_lock_irqsave(&plchan->lock, flags);
+ if (!plchan->phychan && !plchan->at) {
+ spin_unlock_irqrestore(&plchan->lock, flags);
+ return 0;
+ }
+
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ plchan->paused = false;
+
+ if (plchan->phychan) {
+ pl08x_stop_phy_chan(plchan->phychan);
+
+ /*
+ * Mark physical channel as free and free any slave
+ * signal
+ */
+ if ((plchan->phychan->signal >= 0) &&
+ pl08x->pd->put_signal)
+ pl08x->pd->put_signal(plchan);
+ pl08x_put_phy_channel(pl08x, plchan->phychan);
+ plchan->phychan = NULL;
+ }
+
+ /* Dequeue jobs and free LLIs */
+ if (plchan->at) {
+ pl08x_free_txd(pl08x, plchan->at);
+ pl08x_free_txd_list(pl08x, plchan);
+ plchan->at = NULL;
+ }
+ break;
+ case DMA_PAUSE:
+ pl08x_pause_phy_chan(plchan->phychan);
+ plchan->paused = true;
+ break;
+ case DMA_RESUME:
+ pl08x_resume_phy_chan(plchan->phychan);
+ plchan->paused = false;
+ break;
+ default:
+ /* Unknown command */
+ ret = -ENXIO;
+ break;
+ }
+
+ spin_unlock_irqrestore(&plchan->lock, flags);
+
+ return ret;
+}
+
+bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ char *name = chan_id;
+
+ /* Check that the channel is not taken! */
+ if (!strcmp(plchan->name, name))
+ return true;
+
+ return false;
+}
+
+static struct dma_device dmac_memcpy = {
+ .device_alloc_chan_resources = pl08x_alloc_chan_resources,
+ .device_free_chan_resources = pl08x_free_chan_resources,
+ .device_prep_dma_memcpy = pl08x_prep_dma_memcpy,
+ .device_prep_dma_xor = NULL,
+ .device_prep_dma_memset = NULL,
+ .device_prep_dma_interrupt = pl08x_prep_dma_interrupt,
+ .device_tx_status = pl08x_dma_tx_status,
+ .device_issue_pending = pl08x_issue_pending,
+ .device_control = pl08x_control,
+ /*
+ * Align to 4-byte boundary
+ * This makes the DMAtests fail with grace on PB1176
+ * broken DMA hardware instead of locking everything
+ * up.
+ */
+ /* .copy_align = 2, */
+};
+
+static struct dma_device dmac_slave = {
+ .device_alloc_chan_resources = pl08x_alloc_chan_resources,
+ .device_free_chan_resources = pl08x_free_chan_resources,
+ .device_prep_dma_xor = NULL,
+ .device_prep_dma_memset = NULL,
+ .device_prep_dma_interrupt = pl08x_prep_dma_interrupt,
+ .device_tx_status = pl08x_dma_tx_status,
+ .device_issue_pending = pl08x_issue_pending,
+ .device_prep_slave_sg = pl08x_prep_slave_sg,
+ .device_control = pl08x_control,
+};
+
+
+/*
+ * Just check that the device is there and active
+ * TODO: turn this bit on/off depending on the number of
+ * physical channels actually used, if it is zero... well
+ * shut it off. That will save some power. Cut the clock
+ * at the same time.
+ */
+static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
+{
+ u32 val;
+
+ val = readl(pl08x->base + PL080_CONFIG);
+ val &= ~(PL080_CONFIG_M2_BE | PL080_CONFIG_M1_BE | PL080_CONFIG_ENABLE);
+ /* We implictly clear bit 1 and that means little-endian mode */
+ val |= PL080_CONFIG_ENABLE;
+ writel(val, pl08x->base + PL080_CONFIG);
+}
+
+/*
+ * Initialise the DMAC memcpy/slave channels.
+ * Make a local wrapper to hold required data
+ */
+static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
+ struct dma_device *dmadev,
+ unsigned int channels,
+ bool slave)
+{
+ struct pl08x_dma_chan *chan;
+ int i;
+
+ INIT_LIST_HEAD(&dmadev->channels);
+ /*
+ * Register as many many memcpy as we have physical channels,
+ * we won't always be able to use all but the code will have
+ * to cope with that situation.
+ */
+ for (i = 0; i < channels; i++) {
+ chan = kzalloc(sizeof(struct pl08x_dma_chan), GFP_KERNEL);
+ if (!chan) {
+ dev_err(&pl08x->adev->dev,
+ "%s no memory for channel\n", __func__);
+ return -ENOMEM;
+ }
+
+ chan->host = pl08x;
+
+ if (slave) {
+ chan->name = pl08x->pd->slave_channels[i].bus_id;
+ chan->cd = &pl08x->pd->slave_channels[i];
+ } else {
+ chan->cd = &pl08x->pd->memcpy_channel;
+ chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i);
+ if (!chan->name) {
+ kfree(chan);
+ return -ENOMEM;
+ }
+ }
+ dev_info(&pl08x->adev->dev,
+ "initialize virtual channel \"%s\"\n",
+ chan->name);
+
+ chan->chan.device = dmadev;
+ atomic_set(&chan->last_issued, 0);
+ chan->lc = atomic_read(&chan->last_issued);
+
+ spin_lock_init(&chan->lock);
+ INIT_LIST_HEAD(&chan->desc_list);
+ tasklet_init(&chan->tasklet, pl08x_tasklet,
+ (unsigned long) chan);
+
+ list_add_tail(&chan->chan.device_node, &dmadev->channels);
+ }
+ dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n",
+ i, slave ? "slave" : "memcpy");
+ return i;
+}
+
+static int pl08x_probe(struct amba_device *adev, struct amba_id *id)
+{
+ struct pl08x_driver_data *pl08x;
+ struct vendor_data *vd = id->data;
+ int ret = 0;
+ int i;
+
+ ret = amba_request_regions(adev, NULL);
+ if (ret)
+ return ret;
+
+ /* Create the driver state holder */
+ pl08x = kzalloc(sizeof(struct pl08x_driver_data), GFP_KERNEL);
+ if (!pl08x) {
+ ret = -ENOMEM;
+ goto out_no_pl08x;
+ }
+
+ /* Assign useful pointers to the driver state */
+ pl08x->adev = adev;
+ pl08x->vd = vd;
+
+ pl08x->clk = clk_get(&adev->dev, NULL);
+ if (IS_ERR(pl08x->clk)) {
+ ret = PTR_ERR(pl08x->clk);
+ if (ret == -ENOENT) {
+ dev_info(&adev->dev, "no clock supplied, assume always on\n");
+ pl08x->clk = NULL;
+ } else
+ goto out_no_clk;
+ }
+ /* Constantly enabled for now, we can control this dynamically */
+ if (pl08x->clk)
+ clk_enable(pl08x->clk);
+
+ /* A DMA memory pool for LLIs, align on 1-byte boundary */
+ pl08x->pool = dma_pool_create(DRIVER_NAME, &pl08x->adev->dev,
+ PL08X_LLI_TSFR_SIZE, PL08X_ALIGN, 0);
+ if (!pl08x->pool) {
+ ret = -ENOMEM;
+ goto out_no_lli_pool;
+ }
+
+ spin_lock_init(&pl08x->lock);
+
+ pl08x->base = ioremap(adev->res.start, resource_size(&adev->res));
+ if (!pl08x->base) {
+ ret = -ENOMEM;
+ goto out_no_ioremap;
+ }
+
+ /* Turn on the PL08x */
+ pl08x_ensure_on(pl08x);
+
+ /*
+ * Attach the interrupt handler
+ */
+ writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR);
+ writel(0x000000FF, pl08x->base + PL080_TC_CLEAR);
+
+ ret = request_irq(adev->irq[0], pl08x_irq, IRQF_DISABLED,
+ vd->name, pl08x);
+ if (ret) {
+ dev_err(&adev->dev, "%s failed to request interrupt %d\n",
+ __func__, adev->irq[0]);
+ goto out_no_irq;
+ }
+
+ /* Initialize physical channels */
+ pl08x->phy_chans = kmalloc((vd->channels * sizeof(struct pl08x_phy_chan)),
+ GFP_KERNEL);
+ if (!pl08x->phy_chans) {
+ dev_err(&adev->dev, "%s failed to allocate "
+ "physical channel holders\n",
+ __func__);
+ goto out_no_phychans;
+ }
+
+ for (i = 0; i < vd->channels; i++) {
+ struct pl08x_phy_chan *ch = &pl08x->phy_chans[i];
+
+ ch->id = i;
+ ch->base = pl08x->base + PL080_Cx_BASE(i);
+ spin_lock_init(&ch->lock);
+ ch->serving = NULL;
+ ch->signal = -1;
+ dev_info(&adev->dev,
+ "physical channel %d is %s\n", i,
+ pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
+ }
+
+ /* Get the platform data */
+ pl08x->pd = dev_get_platdata(&adev->dev);
+
+ /* Set caps */
+ dma_cap_set(DMA_MEMCPY, dmac_memcpy.cap_mask);
+ dma_cap_set(DMA_SLAVE, dmac_slave.cap_mask);
+ dmac_memcpy.dev = &adev->dev;
+ dmac_slave.dev = &adev->dev;
+
+ /* Register as many memcpy channels as there are physical channels */
+ ret = pl08x_dma_init_virtual_channels(pl08x, &dmac_memcpy,
+ pl08x->vd->channels, false);
+ if (ret <= 0) {
+ dev_warn(&pl08x->adev->dev,
+ "%s failed to enumerate memcpy channels - %d\n",
+ __func__, ret);
+ goto out_no_memcpy;
+ }
+ dmac_memcpy.chancnt = ret;
+
+ /* Register slave channels */
+ ret = pl08x_dma_init_virtual_channels(pl08x, &dmac_slave,
+ pl08x->pd->num_slave_channels,
+ true);
+ if (ret <= 0) {
+ dev_warn(&pl08x->adev->dev,
+ "%s failed to enumerate slave channels - %d\n",
+ __func__, ret);
+ goto out_no_slave;
+ }
+ dmac_slave.chancnt = ret;
+
+ ret = dma_async_device_register(&dmac_memcpy);
+ if (ret) {
+ dev_warn(&pl08x->adev->dev,
+ "%s failed to register memcpy as an async device - %d\n",
+ __func__, ret);
+ goto out_no_memcpy_reg;
+ }
+
+ ret = dma_async_device_register(&dmac_slave);
+ if (ret) {
+ dev_warn(&pl08x->adev->dev,
+ "%s failed to register slave as an async device - %d\n",
+ __func__, ret);
+ goto out_no_slave_reg;
+ }
+
+ amba_set_drvdata(adev, pl08x);
+ dev_info(&pl08x->adev->dev, "ARM(R) %s DMA block initialized @%08x\n",
+ vd->name, adev->res.start);
+ return 0;
+
+out_no_slave_reg:
+ dma_async_device_unregister(&dmac_memcpy);
+out_no_memcpy_reg:
+ /* FIXME: free slave channels */
+out_no_slave:
+ /* FIXME: free memcpy channels */
+out_no_memcpy:
+ kfree(pl08x->phy_chans);
+out_no_phychans:
+ free_irq(adev->irq[0], pl08x);
+out_no_irq:
+ iounmap(pl08x->base);
+out_no_ioremap:
+ dma_pool_destroy(pl08x->pool);
+out_no_lli_pool:
+ clk_put(pl08x->clk);
+out_no_clk:
+ kfree(pl08x);
+out_no_pl08x:
+ amba_release_regions(adev);
+ return ret;
+}
+
+/* PL080 has 8 channels and the PL080 have just 2 */
+static struct vendor_data vendor_pl080 = {
+ .name = "PL080",
+ .channels = 8,
+ .dualmaster = true,
+};
+
+static struct vendor_data vendor_pl081 = {
+ .name = "PL081",
+ .channels = 2,
+ .dualmaster = false,
+};
+
+static struct amba_id pl08x_ids[] = {
+ /* PL080 */
+ {
+ .id = 0x00041080,
+ .mask = 0x000fffff,
+ .data = &vendor_pl080,
+ },
+ /* PL081 */
+ {
+ .id = 0x00041081,
+ .mask = 0x000fffff,
+ .data = &vendor_pl081,
+ },
+ /* Nomadik 8815 PL080 variant */
+ {
+ .id = 0x00280880,
+ .mask = 0x00ffffff,
+ .data = &vendor_pl080,
+ },
+ { 0, 0 },
+};
+
+static struct amba_driver pl08x_amba_driver = {
+ .drv.name = DRIVER_NAME,
+ .id_table = pl08x_ids,
+ .probe = pl08x_probe,
+};
+
+static int __init pl08x_init(void)
+{
+ int retval;
+ retval = amba_driver_register(&pl08x_amba_driver);
+ if (retval)
+ printk(KERN_WARNING DRIVER_NAME
+ "failed to register as an amba device (%d)\n",
+ retval);
+ return retval;
+}
+subsys_initcall(pl08x_init);
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 557e2272e5b3..be80c43bffbe 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -157,6 +157,7 @@ static const struct file_operations coh901318_debugfs_status_operations = {
.owner = THIS_MODULE,
.open = coh901318_debugfs_open,
.read = coh901318_debugfs_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index fb64cf36ba61..eb6b54dbb806 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
sh_chan = to_sh_chan(chan);
param = chan->private;
- slave_addr = param->config->addr;
/* Someone calling slave DMA on a public channel? */
if (!param || !sg_len) {
@@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
return NULL;
}
+ slave_addr = param->config->addr;
+
/*
* if (param != NULL), this is a successfully requested slave channel,
* therefore param->config != NULL too.
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 33f8421c71cc..18fdd9703b48 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -8,7 +8,6 @@
#include <linux/bug.h>
#include <linux/device.h>
-#include <linux/ethtool.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/highmem.h>
@@ -1361,17 +1360,6 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu)
return 0;
}
-static void fwnet_get_drvinfo(struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, KBUILD_MODNAME);
- strcpy(info->bus_info, "ieee1394");
-}
-
-static const struct ethtool_ops fwnet_ethtool_ops = {
- .get_drvinfo = fwnet_get_drvinfo,
-};
-
static const struct net_device_ops fwnet_netdev_ops = {
.ndo_open = fwnet_open,
.ndo_stop = fwnet_stop,
@@ -1390,7 +1378,6 @@ static void fwnet_init_dev(struct net_device *net)
net->hard_header_len = FWNET_HLEN;
net->type = ARPHRD_IEEE1394;
net->tx_queue_len = 10;
- SET_ETHTOOL_OPS(net, &fwnet_ethtool_ops);
}
/* caller must hold fwnet_device_mutex */
diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c
index 8528b10763ed..8b693c43a572 100644
--- a/drivers/firewire/nosy.c
+++ b/drivers/firewire/nosy.c
@@ -405,6 +405,7 @@ static const struct file_operations nosy_ops = {
.poll = nosy_poll,
.open = nosy_open,
.release = nosy_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
#define PHY_PACKET_SIZE 12 /* 1 payload, 1 inverse, 1 ack = 3 quadlets */
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index be29b0bb2471..1b05896648bc 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -263,6 +263,7 @@ static const struct {
{PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
{PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
{PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
+ {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER},
{PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
};
diff --git a/drivers/gpio/stmpe-gpio.c b/drivers/gpio/stmpe-gpio.c
index 4e1f1b9d5e67..932759db1ac2 100644
--- a/drivers/gpio/stmpe-gpio.c
+++ b/drivers/gpio/stmpe-gpio.c
@@ -30,6 +30,7 @@ struct stmpe_gpio {
struct mutex irq_lock;
int irq_base;
+ unsigned norequest_mask;
/* Caches of interrupt control registers for bus_lock */
u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
@@ -103,6 +104,9 @@ static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset)
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip);
struct stmpe *stmpe = stmpe_gpio->stmpe;
+ if (stmpe_gpio->norequest_mask & (1 << offset))
+ return -EINVAL;
+
return stmpe_set_altfunc(stmpe, 1 << offset, STMPE_BLOCK_GPIO);
}
@@ -287,8 +291,6 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
int irq;
pdata = stmpe->pdata->gpio;
- if (!pdata)
- return -ENODEV;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
@@ -302,6 +304,7 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
stmpe_gpio->dev = &pdev->dev;
stmpe_gpio->stmpe = stmpe;
+ stmpe_gpio->norequest_mask = pdata ? pdata->norequest_mask : 0;
stmpe_gpio->chip = template_chip;
stmpe_gpio->chip.ngpio = stmpe->num_gpios;
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/sx150x.c
index b42f42ca70c3..823559ab0e24 100644
--- a/drivers/gpio/sx150x.c
+++ b/drivers/gpio/sx150x.c
@@ -459,17 +459,33 @@ static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg)
return err;
}
-static int sx150x_init_hw(struct sx150x_chip *chip,
- struct sx150x_platform_data *pdata)
+static int sx150x_reset(struct sx150x_chip *chip)
{
- int err = 0;
+ int err;
- err = i2c_smbus_write_word_data(chip->client,
+ err = i2c_smbus_write_byte_data(chip->client,
chip->dev_cfg->reg_reset,
- 0x3412);
+ 0x12);
if (err < 0)
return err;
+ err = i2c_smbus_write_byte_data(chip->client,
+ chip->dev_cfg->reg_reset,
+ 0x34);
+ return err;
+}
+
+static int sx150x_init_hw(struct sx150x_chip *chip,
+ struct sx150x_platform_data *pdata)
+{
+ int err = 0;
+
+ if (pdata->reset_during_probe) {
+ err = sx150x_reset(chip);
+ if (err < 0)
+ return err;
+ }
+
err = sx150x_i2c_write(chip->client,
chip->dev_cfg->reg_misc,
0x01);
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
index 2ac9a16d3daa..618398e4ed8e 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -140,6 +140,7 @@ static struct gpio_chip template_chip = {
.get = wm8994_gpio_get,
.direction_output = wm8994_gpio_direction_out,
.set = wm8994_gpio_set,
+ .to_irq = wm8994_gpio_to_irq,
.dbg_show = wm8994_gpio_dbg_show,
.can_sleep = 1,
};
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 7e31d4348340..d2ab01e90a96 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -34,6 +34,9 @@
#include "drm_crtc_helper.h"
#include "drm_fb_helper.h"
+static bool drm_kms_helper_poll = true;
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
+
static void drm_mode_validate_flag(struct drm_connector *connector,
int flags)
{
@@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
connector->status = connector_status_disconnected;
if (connector->funcs->force)
connector->funcs->force(connector);
- } else
+ } else {
connector->status = connector->funcs->detect(connector);
+ drm_helper_hpd_irq_event(dev);
+ }
if (connector->status == connector_status_disconnected) {
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
@@ -110,11 +115,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
}
count = (*connector_funcs->get_modes)(connector);
- if (!count) {
+ if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
- if (!count)
- return 0;
- }
+ if (count == 0)
+ goto prune;
drm_mode_connector_list_update(connector);
@@ -840,6 +844,9 @@ static void output_poll_execute(struct work_struct *work)
enum drm_connector_status old_status, status;
bool repoll = false, changed = false;
+ if (!drm_kms_helper_poll)
+ return;
+
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -890,6 +897,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
bool poll = false;
struct drm_connector *connector;
+ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
+ return;
+
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->polled)
poll = true;
@@ -919,8 +929,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
{
if (!dev->mode_config.poll_enabled)
return;
+
/* kill timer and schedule immediate execution, this doesn't block */
cancel_delayed_work(&dev->mode_config.output_poll_work);
- queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
+ if (drm_kms_helper_poll)
+ queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
}
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 84da748555bc..17b666e6398a 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -284,7 +284,8 @@ EXPORT_SYMBOL(drm_exit);
/** File operations structure */
static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
- .open = drm_stub_open
+ .open = drm_stub_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int __init drm_core_init(void)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 6a5e403f9aa1..625a2d551d6a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -263,7 +263,8 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
funcs->mode_set_base_atomic(mode_set->crtc,
mode_set->fb,
mode_set->x,
- mode_set->y);
+ mode_set->y,
+ 1);
}
}
@@ -309,7 +310,7 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
}
funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
- crtc->y);
+ crtc->y, 0);
}
return 0;
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 61b4caf220fa..73828f037cd2 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -119,6 +119,7 @@ static const struct file_operations i810_buffer_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = i810_mmap_buffers,
.fasync = drm_fasync,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index b4250b2cac1f..fe69914ce507 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -63,6 +63,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c
index 671aa18415ac..72d2f2413cee 100644
--- a/drivers/gpu/drm/i830/i830_dma.c
+++ b/drivers/gpu/drm/i830/i830_dma.c
@@ -121,6 +121,7 @@ static const struct file_operations i830_buffer_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = i830_mmap_buffers,
.fasync = drm_fasync,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int i830_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c
index a5c66aa82f0c..5b6298b24e24 100644
--- a/drivers/gpu/drm/i830/i830_drv.c
+++ b/drivers/gpu/drm/i830/i830_drv.c
@@ -74,6 +74,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 92d5605a34d1..ed0cf9c46e93 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -31,6 +31,7 @@
#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
+#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
@@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
return 0;
}
+static int i915_gem_pageflip_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ unsigned long flags;
+ struct intel_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ const char *pipe = crtc->pipe ? "B" : "A";
+ const char *plane = crtc->plane ? "B" : "A";
+ struct intel_unpin_work *work;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = crtc->unpin_work;
+ if (work == NULL) {
+ seq_printf(m, "No flip due on pipe %s (plane %s)\n",
+ pipe, plane);
+ } else {
+ if (!work->pending) {
+ seq_printf(m, "Flip queued on pipe %s (plane %s)\n",
+ pipe, plane);
+ } else {
+ seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n",
+ pipe, plane);
+ }
+ if (work->enable_stall_check)
+ seq_printf(m, "Stall check enabled, ");
+ else
+ seq_printf(m, "Stall check waiting for page flip ioctl, ");
+ seq_printf(m, "%d prepares\n", work->pending);
+
+ if (work->old_fb_obj) {
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj);
+ if(obj_priv)
+ seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
+ }
+ if (work->pending_flip_obj) {
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj);
+ if(obj_priv)
+ seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
+ }
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+
+ return 0;
+}
+
static int i915_gem_request_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -733,6 +782,7 @@ static const struct file_operations i915_wedged_fops = {
.open = i915_wedged_open,
.read = i915_wedged_read,
.write = i915_wedged_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
/* As the drm_debugfs_init() routines are called before dev->dev_private is
@@ -777,6 +827,7 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
+ {"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
{"i915_gem_seqno", i915_gem_seqno_info, 0},
{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a7ec93e62f81..9d67b4853030 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -620,8 +620,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
ret = copy_from_user(cliprects, batch->cliprects,
batch->num_cliprects *
sizeof(struct drm_clip_rect));
- if (ret != 0)
+ if (ret != 0) {
+ ret = -EFAULT;
goto fail_free;
+ }
}
mutex_lock(&dev->struct_mutex);
@@ -662,8 +664,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
return -ENOMEM;
ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
- if (ret != 0)
+ if (ret != 0) {
+ ret = -EFAULT;
goto fail_batch_free;
+ }
if (cmdbuf->num_cliprects) {
cliprects = kcalloc(cmdbuf->num_cliprects,
@@ -676,8 +680,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
ret = copy_from_user(cliprects, cmdbuf->cliprects,
cmdbuf->num_cliprects *
sizeof(struct drm_clip_rect));
- if (ret != 0)
+ if (ret != 0) {
+ ret = -EFAULT;
goto fail_clip_free;
+ }
}
mutex_lock(&dev->struct_mutex);
@@ -885,7 +891,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
u32 temp_lo, temp_hi = 0;
u64 mchbar_addr;
- int ret = 0;
+ int ret;
if (IS_I965G(dev))
pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
@@ -895,22 +901,23 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
/* If ACPI doesn't have it, assume we need to allocate it ourselves */
#ifdef CONFIG_PNP
if (mchbar_addr &&
- pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
- ret = 0;
- goto out;
- }
+ pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
+ return 0;
#endif
/* Get some space for it */
- ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
+ dev_priv->mch_res.name = "i915 MCHBAR";
+ dev_priv->mch_res.flags = IORESOURCE_MEM;
+ ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus,
+ &dev_priv->mch_res,
MCHBAR_SIZE, MCHBAR_SIZE,
PCIBIOS_MIN_MEM,
- 0, pcibios_align_resource,
+ 0, pcibios_align_resource,
dev_priv->bridge_dev);
if (ret) {
DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
dev_priv->mch_res.start = 0;
- goto out;
+ return ret;
}
if (IS_I965G(dev))
@@ -919,8 +926,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
pci_write_config_dword(dev_priv->bridge_dev, reg,
lower_32_bits(dev_priv->mch_res.start));
-out:
- return ret;
+ return 0;
}
/* Setup MCHBAR if possible, return true if we should disable it again */
@@ -2082,6 +2088,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
+ /* overlay on gen2 is broken and can't address above 1G */
+ if (IS_GEN2(dev))
+ dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
+
dev_priv->regs = ioremap(base, size);
if (!dev_priv->regs) {
DRM_ERROR("failed to map registers\n");
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 00befce8fbb7..a6fdb481500c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -61,91 +61,86 @@ extern int intel_agp_enabled;
.driver_data = (unsigned long) info }
static const struct intel_device_info intel_i830_info = {
- .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+ .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
};
static const struct intel_device_info intel_845g_info = {
- .is_i8xx = 1,
+ .gen = 2, .is_i8xx = 1,
};
static const struct intel_device_info intel_i85x_info = {
- .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
+ .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
.cursor_needs_physical = 1,
};
static const struct intel_device_info intel_i865g_info = {
- .is_i8xx = 1,
+ .gen = 2, .is_i8xx = 1,
};
static const struct intel_device_info intel_i915g_info = {
- .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
+ .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
};
static const struct intel_device_info intel_i915gm_info = {
- .is_i9xx = 1, .is_mobile = 1,
+ .gen = 3, .is_i9xx = 1, .is_mobile = 1,
.cursor_needs_physical = 1,
};
static const struct intel_device_info intel_i945g_info = {
- .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
+ .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
};
static const struct intel_device_info intel_i945gm_info = {
- .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
+ .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
.has_hotplug = 1, .cursor_needs_physical = 1,
};
static const struct intel_device_info intel_i965g_info = {
- .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
+ .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1,
+ .has_hotplug = 1,
};
static const struct intel_device_info intel_i965gm_info = {
- .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
- .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
- .has_hotplug = 1,
+ .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1,
+ .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_g33_info = {
- .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_hotplug = 1,
+ .gen = 3, .is_g33 = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_g45_info = {
- .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_pipe_cxsr = 1,
- .has_hotplug = 1,
+ .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
+ .has_pipe_cxsr = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_gm45_info = {
- .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1,
+ .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1,
.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
- .has_pipe_cxsr = 1,
- .has_hotplug = 1,
+ .has_pipe_cxsr = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_pineview_info = {
- .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
- .need_gfx_hws = 1,
- .has_hotplug = 1,
+ .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_ironlake_d_info = {
- .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_pipe_cxsr = 1,
- .has_hotplug = 1,
+ .gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_ironlake_m_info = {
- .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
- .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
- .has_hotplug = 1,
+ .gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_sandybridge_d_info = {
- .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_hotplug = 1, .is_gen6 = 1,
+ .gen = 6, .is_i965g = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_hotplug = 1,
};
static const struct intel_device_info intel_sandybridge_m_info = {
- .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
- .has_hotplug = 1, .is_gen6 = 1,
+ .gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1,
+ .need_gfx_hws = 1, .has_hotplug = 1,
};
static const struct pci_device_id pciidlist[] = { /* aka */
@@ -180,8 +175,12 @@ static const struct pci_device_id pciidlist[] = { /* aka */
INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
+ INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
+ INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
+ INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
+ INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
{0, 0, 0}
};
@@ -548,6 +547,7 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = i915_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 047cd7ce7e1b..af4a263cf257 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -191,6 +191,7 @@ struct drm_i915_display_funcs {
};
struct intel_device_info {
+ u8 gen;
u8 is_mobile : 1;
u8 is_i8xx : 1;
u8 is_i85x : 1;
@@ -206,7 +207,6 @@ struct intel_device_info {
u8 is_broadwater : 1;
u8 is_crestline : 1;
u8 is_ironlake : 1;
- u8 is_gen6 : 1;
u8 has_fbc : 1;
u8 has_rc6 : 1;
u8 has_pipe_cxsr : 1;
@@ -1162,7 +1162,6 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
#define IS_845G(dev) ((dev)->pci_device == 0x2562)
#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
-#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx)
#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
@@ -1181,27 +1180,13 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove
#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
#define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake)
#define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx)
-#define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6)
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
-#define IS_GEN3(dev) (IS_I915G(dev) || \
- IS_I915GM(dev) || \
- IS_I945G(dev) || \
- IS_I945GM(dev) || \
- IS_G33(dev) || \
- IS_PINEVIEW(dev))
-#define IS_GEN4(dev) ((dev)->pci_device == 0x2972 || \
- (dev)->pci_device == 0x2982 || \
- (dev)->pci_device == 0x2992 || \
- (dev)->pci_device == 0x29A2 || \
- (dev)->pci_device == 0x2A02 || \
- (dev)->pci_device == 0x2A12 || \
- (dev)->pci_device == 0x2E02 || \
- (dev)->pci_device == 0x2E12 || \
- (dev)->pci_device == 0x2E22 || \
- (dev)->pci_device == 0x2E32 || \
- (dev)->pci_device == 0x2A42 || \
- (dev)->pci_device == 0x2E42)
+#define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2)
+#define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3)
+#define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4)
+#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5)
+#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6)
#define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev))
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index df5a7135c261..16fca1d1799a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/pci.h>
+#include <linux/intel-gtt.h>
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
@@ -135,12 +136,15 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
return -ENOMEM;
ret = drm_gem_handle_create(file_priv, obj, &handle);
- drm_gem_object_unreference_unlocked(obj);
- if (ret)
+ if (ret) {
+ drm_gem_object_unreference_unlocked(obj);
return ret;
+ }
- args->handle = handle;
+ /* Sink the floating reference from kref_init(handlecount) */
+ drm_gem_object_handle_unreference_unlocked(obj);
+ args->handle = handle;
return 0;
}
@@ -3585,6 +3589,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
if (ret != 0) {
DRM_ERROR("copy %d cliprects failed: %d\n",
args->num_cliprects, ret);
+ ret = -EFAULT;
goto pre_mutex_err;
}
}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 16861b800fee..744225ebb4b2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -887,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
queue_work(dev_priv->wq, &dev_priv->error_work);
}
+static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_i915_gem_object *obj_priv;
+ struct intel_unpin_work *work;
+ unsigned long flags;
+ bool stall_detected;
+
+ /* Ignore early vblank irqs */
+ if (intel_crtc == NULL)
+ return;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = intel_crtc->unpin_work;
+
+ if (work == NULL || work->pending || !work->enable_stall_check) {
+ /* Either the pending flip IRQ arrived, or we're too early. Don't check */
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ return;
+ }
+
+ /* Potential stall - if we see that the flip has happened, assume a missed interrupt */
+ obj_priv = to_intel_bo(work->pending_flip_obj);
+ if(IS_I965G(dev)) {
+ int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF;
+ stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset;
+ } else {
+ int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR;
+ stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset +
+ crtc->y * crtc->fb->pitch +
+ crtc->x * crtc->fb->bits_per_pixel/8);
+ }
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ if (stall_detected) {
+ DRM_DEBUG_DRIVER("Pageflip stall detected\n");
+ intel_prepare_page_flip(dev, intel_crtc->plane);
+ }
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -1004,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
if (pipea_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 0);
- if (!dev_priv->flip_pending_is_done)
+ if (!dev_priv->flip_pending_is_done) {
+ i915_pageflip_stall_check(dev, 0);
intel_finish_page_flip(dev, 0);
+ }
}
if (pipeb_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 1);
- if (!dev_priv->flip_pending_is_done)
+ if (!dev_priv->flip_pending_is_done) {
+ i915_pageflip_stall_check(dev, 1);
intel_finish_page_flip(dev, 1);
+ }
}
if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
@@ -1303,17 +1350,25 @@ void i915_hangcheck_elapsed(unsigned long data)
i915_seqno_passed(i915_get_gem_seqno(dev,
&dev_priv->render_ring),
i915_get_tail_request(dev)->seqno)) {
+ bool missed_wakeup = false;
+
dev_priv->hangcheck_count = 0;
/* Issue a wake-up to catch stuck h/w. */
- if (dev_priv->render_ring.waiting_gem_seqno |
- dev_priv->bsd_ring.waiting_gem_seqno) {
- DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n");
- if (dev_priv->render_ring.waiting_gem_seqno)
- DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
- if (dev_priv->bsd_ring.waiting_gem_seqno)
- DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
+ if (dev_priv->render_ring.waiting_gem_seqno &&
+ waitqueue_active(&dev_priv->render_ring.irq_queue)) {
+ DRM_WAKEUP(&dev_priv->render_ring.irq_queue);
+ missed_wakeup = true;
}
+
+ if (dev_priv->bsd_ring.waiting_gem_seqno &&
+ waitqueue_active(&dev_priv->bsd_ring.irq_queue)) {
+ DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
+ missed_wakeup = true;
+ }
+
+ if (missed_wakeup)
+ DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n");
return;
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67e3ec1a6af9..4f5e15577e89 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -319,6 +319,7 @@
#define MI_MODE 0x0209c
# define VS_TIMER_DISPATCH (1 << 6)
+# define MI_FLUSH_ENABLE (1 << 11)
#define SCPD0 0x0209c /* 915+ only */
#define IER 0x020a0
@@ -2205,9 +2206,17 @@
#define WM1_LP_SR_EN (1<<31)
#define WM1_LP_LATENCY_SHIFT 24
#define WM1_LP_LATENCY_MASK (0x7f<<24)
+#define WM1_LP_FBC_LP1_MASK (0xf<<20)
+#define WM1_LP_FBC_LP1_SHIFT 20
#define WM1_LP_SR_MASK (0x1ff<<8)
#define WM1_LP_SR_SHIFT 8
#define WM1_LP_CURSOR_MASK (0x3f)
+#define WM2_LP_ILK 0x4510c
+#define WM2_LP_EN (1<<31)
+#define WM3_LP_ILK 0x45110
+#define WM3_LP_EN (1<<31)
+#define WM1S_LP_ILK 0x45120
+#define WM1S_LP_EN (1<<31)
/* Memory latency timer register */
#define MLTR_ILK 0x11222
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 11a3394f5fe1..6db698bb2c4c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -990,6 +990,22 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
struct drm_i915_private *dev_priv = dev->dev_private;
int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
+ /* Clear existing vblank status. Note this will clear any other
+ * sticky status fields as well.
+ *
+ * This races with i915_driver_irq_handler() with the result
+ * that either function could miss a vblank event. Here it is not
+ * fatal, as we will either wait upon the next vblank interrupt or
+ * timeout. Generally speaking intel_wait_for_vblank() is only
+ * called during modeset at which time the GPU should be idle and
+ * should *not* be performing page flips and thus not waiting on
+ * vblanks...
+ * Currently, the result of us stealing a vblank from the irq
+ * handler is that a single frame will be skipped during swapbuffers.
+ */
+ I915_WRITE(pipestat_reg,
+ I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS);
+
/* Wait for vblank interrupt bit to set */
if (wait_for((I915_READ(pipestat_reg) &
PIPE_VBLANK_INTERRUPT_STATUS),
@@ -1428,7 +1444,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
/* Assume fb object is pinned & idle & fenced and just update base pointers */
static int
intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
- int x, int y)
+ int x, int y, int enter)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1486,7 +1502,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
dspcntr &= ~DISPPLANE_TILED;
}
- if (IS_IRONLAKE(dev))
+ if (HAS_PCH_SPLIT(dev))
/* must disable */
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
@@ -1495,20 +1511,19 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
Start = obj_priv->gtt_offset;
Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
+ Start, Offset, x, y, fb->pitch);
I915_WRITE(dspstride, fb->pitch);
if (IS_I965G(dev)) {
- I915_WRITE(dspbase, Offset);
- I915_READ(dspbase);
I915_WRITE(dspsurf, Start);
- I915_READ(dspsurf);
I915_WRITE(dsptileoff, (y << 16) | x);
+ I915_WRITE(dspbase, Offset);
} else {
I915_WRITE(dspbase, Start + Offset);
- I915_READ(dspbase);
}
+ POSTING_READ(dspbase);
- if ((IS_I965G(dev) || plane == 0))
+ if (IS_I965G(dev) || plane == 0)
intel_update_fbc(crtc, &crtc->mode);
intel_wait_for_vblank(dev, intel_crtc->pipe);
@@ -1522,7 +1537,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_framebuffer *intel_fb;
@@ -1530,13 +1544,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_gem_object *obj;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- unsigned long Start, Offset;
- int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
- int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
- int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
- int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
- int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
- u32 dspcntr;
int ret;
/* no fb bound */
@@ -1572,71 +1579,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
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;
- break;
- case 16:
- if (crtc->fb->depth == 15)
- dspcntr |= DISPPLANE_15_16BPP;
- else
- dspcntr |= DISPPLANE_16BPP;
- break;
- case 24:
- case 32:
- if (crtc->fb->depth == 30)
- dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA;
- else
- dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
- break;
- default:
- DRM_ERROR("Unknown color depth\n");
+ ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, 0);
+ if (ret) {
i915_gem_object_unpin(obj);
mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
- if (IS_I965G(dev)) {
- if (obj_priv->tiling_mode != I915_TILING_NONE)
- dspcntr |= DISPPLANE_TILED;
- else
- dspcntr &= ~DISPPLANE_TILED;
- }
-
- if (HAS_PCH_SPLIT(dev))
- /* must disable */
- dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
-
- I915_WRITE(dspcntr_reg, dspcntr);
-
- Start = obj_priv->gtt_offset;
- Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
-
- DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
- Start, Offset, x, y, crtc->fb->pitch);
- I915_WRITE(dspstride, crtc->fb->pitch);
- if (IS_I965G(dev)) {
- I915_WRITE(dspsurf, Start);
- I915_WRITE(dsptileoff, (y << 16) | x);
- I915_WRITE(dspbase, Offset);
- } else {
- I915_WRITE(dspbase, Start + Offset);
+ return ret;
}
- POSTING_READ(dspbase);
-
- if ((IS_I965G(dev) || plane == 0))
- intel_update_fbc(crtc, &crtc->mode);
-
- intel_wait_for_vblank(dev, pipe);
if (old_fb) {
intel_fb = to_intel_framebuffer(old_fb);
obj_priv = to_intel_bo(intel_fb->obj);
i915_gem_object_unpin(intel_fb->obj);
}
- intel_increase_pllclock(crtc, true);
mutex_unlock(&dev->struct_mutex);
@@ -1911,9 +1865,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL;
int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL;
int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
- int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
- int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
- int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS;
int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
@@ -1982,15 +1933,19 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
}
/* Enable panel fitting for LVDS */
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
- || HAS_eDP || intel_pch_has_edp(crtc)) {
- if (dev_priv->pch_pf_size) {
- temp = I915_READ(pf_ctl_reg);
- I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3);
- I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos);
- I915_WRITE(pf_win_size, dev_priv->pch_pf_size);
- } else
- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
+ if (dev_priv->pch_pf_size &&
+ (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
+ || HAS_eDP || intel_pch_has_edp(crtc))) {
+ /* Force use of hard-coded filter coefficients
+ * as some pre-programmed values are broken,
+ * e.g. x201.
+ */
+ I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1,
+ PF_ENABLE | PF_FILTER_MED_3x3);
+ I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS,
+ dev_priv->pch_pf_pos);
+ I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ,
+ dev_priv->pch_pf_size);
}
/* Enable CPU pipe */
@@ -2115,7 +2070,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_WRITE(transconf_reg, temp | TRANS_ENABLE);
I915_READ(transconf_reg);
- if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0))
+ if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1))
DRM_ERROR("failed to enable transcoder\n");
}
@@ -2155,14 +2110,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
udelay(100);
/* Disable PF */
- temp = I915_READ(pf_ctl_reg);
- if ((temp & PF_ENABLE) != 0) {
- I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
- I915_READ(pf_ctl_reg);
- }
- I915_WRITE(pf_win_size, 0);
- POSTING_READ(pf_win_size);
-
+ I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0);
+ I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0);
/* disable CPU FDI tx and PCH FDI rx */
temp = I915_READ(fdi_tx_reg);
@@ -2421,6 +2370,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
int pipe = intel_crtc->pipe;
bool enabled;
+ if (intel_crtc->dpms_mode == mode)
+ return;
+
intel_crtc->dpms_mode = mode;
intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON;
@@ -2815,14 +2767,8 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
/* Don't promote wm_size to unsigned... */
if (wm_size > (long)wm->max_wm)
wm_size = wm->max_wm;
- if (wm_size <= 0) {
+ if (wm_size <= 0)
wm_size = wm->default_wm;
- DRM_ERROR("Insufficient FIFO for plane, expect flickering:"
- " entries required = %ld, available = %lu.\n",
- entries_required + wm->guard_size,
- wm->fifo_size);
- }
-
return wm_size;
}
@@ -3436,8 +3382,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock,
reg_value = I915_READ(WM1_LP_ILK);
reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK |
WM1_LP_CURSOR_MASK);
- reg_value |= WM1_LP_SR_EN |
- (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) |
+ reg_value |= (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) |
(sr_wm << WM1_LP_SR_SHIFT) | cursor_wm;
I915_WRITE(WM1_LP_ILK, reg_value);
@@ -3554,10 +3499,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
- bool is_edp = false;
+ struct intel_encoder *has_edp_encoder = NULL;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_encoder *encoder;
- struct intel_encoder *intel_encoder = NULL;
const intel_limit_t *limit;
int ret;
struct fdi_m_n m_n = {0};
@@ -3578,12 +3522,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
drm_vblank_pre_modeset(dev, pipe);
list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+ struct intel_encoder *intel_encoder;
- if (!encoder || encoder->crtc != crtc)
+ if (encoder->crtc != crtc)
continue;
intel_encoder = enc_to_intel_encoder(encoder);
-
switch (intel_encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
@@ -3607,7 +3551,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
is_dp = true;
break;
case INTEL_OUTPUT_EDP:
- is_edp = true;
+ has_edp_encoder = intel_encoder;
break;
}
@@ -3685,10 +3629,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
int lane = 0, link_bw, bpp;
/* eDP doesn't require FDI link, so just set DP M/N
according to current link config */
- if (is_edp) {
+ if (has_edp_encoder) {
target_clock = mode->clock;
- intel_edp_link_config(intel_encoder,
- &lane, &link_bw);
+ intel_edp_link_config(has_edp_encoder,
+ &lane, &link_bw);
} else {
/* DP over FDI requires target mode clock
instead of link clock */
@@ -3709,7 +3653,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
temp |= PIPE_8BPC;
else
temp |= PIPE_6BPC;
- } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) {
+ } else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) {
switch (dev_priv->edp_bpp/3) {
case 8:
temp |= PIPE_8BPC;
@@ -3782,7 +3726,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
udelay(200);
- if (is_edp) {
+ if (has_edp_encoder) {
if (dev_priv->lvds_use_ssc) {
temp |= DREF_SSC1_ENABLE;
I915_WRITE(PCH_DREF_CONTROL, temp);
@@ -3931,7 +3875,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
dpll_reg = pch_dpll_reg;
}
- if (!is_edp) {
+ if (!has_edp_encoder) {
I915_WRITE(fp_reg, fp);
I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
I915_READ(dpll_reg);
@@ -4026,7 +3970,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
}
}
- if (!is_edp) {
+ if (!has_edp_encoder) {
I915_WRITE(fp_reg, fp);
I915_WRITE(dpll_reg, dpll);
I915_READ(dpll_reg);
@@ -4105,7 +4049,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(link_m1_reg, m_n.link_m);
I915_WRITE(link_n1_reg, m_n.link_n);
- if (is_edp) {
+ if (has_edp_encoder) {
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
} else {
/* enable FDI RX PLL too */
@@ -4911,15 +4855,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
kfree(intel_crtc);
}
-struct intel_unpin_work {
- struct work_struct work;
- struct drm_device *dev;
- struct drm_gem_object *old_fb_obj;
- struct drm_gem_object *pending_flip_obj;
- struct drm_pending_vblank_event *event;
- int pending;
-};
-
static void intel_unpin_work_fn(struct work_struct *__work)
{
struct intel_unpin_work *work =
@@ -5007,7 +4942,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
spin_lock_irqsave(&dev->event_lock, flags);
if (intel_crtc->unpin_work) {
- intel_crtc->unpin_work->pending = 1;
+ if ((++intel_crtc->unpin_work->pending) > 1)
+ DRM_ERROR("Prepared flip multiple times\n");
} else {
DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
}
@@ -5026,9 +4962,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
unsigned long flags, offset;
- int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
- int ret, pipesrc;
- u32 flip_mask;
+ int pipe = intel_crtc->pipe;
+ u32 pf, pipesrc;
+ int ret;
work = kzalloc(sizeof *work, GFP_KERNEL);
if (work == NULL)
@@ -5077,42 +5013,73 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
atomic_inc(&obj_priv->pending_flip);
work->pending_flip_obj = obj;
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-
if (IS_GEN3(dev) || IS_GEN2(dev)) {
+ u32 flip_mask;
+
+ if (intel_crtc->plane)
+ flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+ else
+ flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+
BEGIN_LP_RING(2);
OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
OUT_RING(0);
ADVANCE_LP_RING();
}
+ work->enable_stall_check = true;
+
/* Offset into the new buffer for cases of shared fbs between CRTCs */
- offset = obj_priv->gtt_offset;
- offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
+ offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
BEGIN_LP_RING(4);
- if (IS_I965G(dev)) {
+ switch(INTEL_INFO(dev)->gen) {
+ case 2:
OUT_RING(MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
OUT_RING(fb->pitch);
- OUT_RING(offset | obj_priv->tiling_mode);
- pipesrc = I915_READ(pipesrc_reg);
- OUT_RING(pipesrc & 0x0fff0fff);
- } else if (IS_GEN3(dev)) {
+ OUT_RING(obj_priv->gtt_offset + offset);
+ OUT_RING(MI_NOOP);
+ break;
+
+ case 3:
OUT_RING(MI_DISPLAY_FLIP_I915 |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
OUT_RING(fb->pitch);
- OUT_RING(offset);
+ OUT_RING(obj_priv->gtt_offset + offset);
OUT_RING(MI_NOOP);
- } else {
+ break;
+
+ case 4:
+ case 5:
+ /* i965+ uses the linear or tiled offsets from the
+ * Display Registers (which do not change across a page-flip)
+ * so we need only reprogram the base address.
+ */
OUT_RING(MI_DISPLAY_FLIP |
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
OUT_RING(fb->pitch);
- OUT_RING(offset);
- OUT_RING(MI_NOOP);
+ OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
+
+ /* XXX Enabling the panel-fitter across page-flip is so far
+ * untested on non-native modes, so ignore it for now.
+ * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
+ */
+ pf = 0;
+ pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff;
+ OUT_RING(pf | pipesrc);
+ break;
+
+ case 6:
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch | obj_priv->tiling_mode);
+ OUT_RING(obj_priv->gtt_offset);
+
+ pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
+ pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff;
+ OUT_RING(pf | pipesrc);
+ break;
}
ADVANCE_LP_RING();
@@ -5193,7 +5160,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
intel_crtc->cursor_addr = 0;
- intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
+ intel_crtc->dpms_mode = -1;
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
intel_crtc->busy = false;
@@ -5701,6 +5668,9 @@ void intel_init_clock_gating(struct drm_device *dev)
I915_WRITE(DISP_ARB_CTL,
(I915_READ(DISP_ARB_CTL) |
DISP_FBC_WM_DIS));
+ I915_WRITE(WM3_LP_ILK, 0);
+ I915_WRITE(WM2_LP_ILK, 0);
+ I915_WRITE(WM1_LP_ILK, 0);
}
/*
* Based on the document from hardware guys the following bits
@@ -5722,8 +5692,7 @@ void intel_init_clock_gating(struct drm_device *dev)
ILK_DPFC_DIS2 |
ILK_CLK_FBC);
}
- if (IS_GEN6(dev))
- return;
+ return;
} else if (IS_G4X(dev)) {
uint32_t dspclk_gate;
I915_WRITE(RENCLK_GATE_D1, 0);
@@ -5784,11 +5753,9 @@ void intel_init_clock_gating(struct drm_device *dev)
OUT_RING(MI_FLUSH);
ADVANCE_LP_RING();
}
- } else {
+ } else
DRM_DEBUG_KMS("Failed to allocate render context."
- "Disable RC6\n");
- return;
- }
+ "Disable RC6\n");
}
if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9caccd03dccb..51d142939a26 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -239,7 +239,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
uint32_t ch_data = ch_ctl + 4;
int i;
int recv_bytes;
- uint32_t ctl;
uint32_t status;
uint32_t aux_clock_divider;
int try, precharge;
@@ -263,41 +262,43 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
else
precharge = 5;
+ if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
+ DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
+ I915_READ(ch_ctl));
+ return -EBUSY;
+ }
+
/* Must try at least 3 times according to DP spec */
for (try = 0; try < 5; try++) {
/* Load the send data into the aux channel data registers */
- for (i = 0; i < send_bytes; i += 4) {
- uint32_t d = pack_aux(send + i, send_bytes - i);
-
- I915_WRITE(ch_data + i, d);
- }
-
- ctl = (DP_AUX_CH_CTL_SEND_BUSY |
- DP_AUX_CH_CTL_TIME_OUT_400us |
- (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
- (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
- (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
- DP_AUX_CH_CTL_DONE |
- DP_AUX_CH_CTL_TIME_OUT_ERROR |
- DP_AUX_CH_CTL_RECEIVE_ERROR);
+ for (i = 0; i < send_bytes; i += 4)
+ I915_WRITE(ch_data + i,
+ pack_aux(send + i, send_bytes - i));
/* Send the command and wait for it to complete */
- I915_WRITE(ch_ctl, ctl);
- (void) I915_READ(ch_ctl);
+ I915_WRITE(ch_ctl,
+ DP_AUX_CH_CTL_SEND_BUSY |
+ DP_AUX_CH_CTL_TIME_OUT_400us |
+ (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+ (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
+ (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
+ DP_AUX_CH_CTL_DONE |
+ DP_AUX_CH_CTL_TIME_OUT_ERROR |
+ DP_AUX_CH_CTL_RECEIVE_ERROR);
for (;;) {
- udelay(100);
status = I915_READ(ch_ctl);
if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
break;
+ udelay(100);
}
/* Clear done status and any errors */
- I915_WRITE(ch_ctl, (status |
- DP_AUX_CH_CTL_DONE |
- DP_AUX_CH_CTL_TIME_OUT_ERROR |
- DP_AUX_CH_CTL_RECEIVE_ERROR));
- (void) I915_READ(ch_ctl);
- if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0)
+ I915_WRITE(ch_ctl,
+ status |
+ DP_AUX_CH_CTL_DONE |
+ DP_AUX_CH_CTL_TIME_OUT_ERROR |
+ DP_AUX_CH_CTL_RECEIVE_ERROR);
+ if (status & DP_AUX_CH_CTL_DONE)
break;
}
@@ -324,15 +325,12 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
/* Unload any bytes sent back from the other side */
recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
-
if (recv_bytes > recv_size)
recv_bytes = recv_size;
- for (i = 0; i < recv_bytes; i += 4) {
- uint32_t d = I915_READ(ch_data + i);
-
- unpack_aux(d, recv + i, recv_bytes - i);
- }
+ for (i = 0; i < recv_bytes; i += 4)
+ unpack_aux(I915_READ(ch_data + i),
+ recv + i, recv_bytes - i);
return recv_bytes;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0e92aa07b382..ad312ca6b3e5 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -176,6 +176,16 @@ struct intel_crtc {
#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+struct intel_unpin_work {
+ struct work_struct work;
+ struct drm_device *dev;
+ struct drm_gem_object *old_fb_obj;
+ struct drm_gem_object *pending_flip_obj;
+ struct drm_pending_vblank_event *event;
+ int pending;
+ bool enable_stall_check;
+};
+
struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
const char *name);
void intel_i2c_destroy(struct i2c_adapter *adapter);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index b819c1081147..4fbb0165b26f 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -875,8 +875,6 @@ void intel_lvds_init(struct drm_device *dev)
intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
intel_encoder->crtc_mask = (1 << 1);
- if (IS_I965G(dev))
- intel_encoder->crtc_mask |= (1 << 0);
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 4f00390d7c61..1d306a458be6 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -25,6 +25,8 @@
*
* Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
*/
+
+#include <linux/seq_file.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 51e9c9e718c4..cb3508f78bc3 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -220,9 +220,13 @@ static int init_render_ring(struct drm_device *dev,
{
drm_i915_private_t *dev_priv = dev->dev_private;
int ret = init_ring_common(dev, ring);
+ int mode;
+
if (IS_I9XX(dev) && !IS_GEN3(dev)) {
- I915_WRITE(MI_MODE,
- (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+ mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
+ if (IS_GEN6(dev))
+ mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
+ I915_WRITE(MI_MODE, mode);
}
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 093e914e8a41..e3b7a7ee39cb 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1061,8 +1061,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
return false;
- if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
- return false;
+ (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo,
+ mode,
+ adjusted_mode);
} else if (intel_sdvo->is_lvds) {
drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0);
@@ -1070,8 +1071,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
intel_sdvo->sdvo_lvds_fixed_mode))
return false;
- if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode))
- return false;
+ (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo,
+ mode,
+ adjusted_mode);
}
/* Make the CRTC code factor in the SDVO pixel multiplier. The
@@ -1108,10 +1110,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
in_out.in0 = intel_sdvo->attached_output;
in_out.in1 = 0;
- if (!intel_sdvo_set_value(intel_sdvo,
- SDVO_CMD_SET_IN_OUT_MAP,
- &in_out, sizeof(in_out)))
- return;
+ intel_sdvo_set_value(intel_sdvo,
+ SDVO_CMD_SET_IN_OUT_MAP,
+ &in_out, sizeof(in_out));
if (intel_sdvo->is_hdmi) {
if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode))
@@ -1122,11 +1123,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
/* We have tried to get input timing in mode_fixup, and filled into
adjusted_mode */
- if (intel_sdvo->is_tv || intel_sdvo->is_lvds) {
- intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+ intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+ if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags;
- } else
- 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.
@@ -1137,8 +1136,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo->attached_output))
return;
- if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd))
- return;
+ (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd);
}
/* Set the input timing to the screen. Assume always input 0. */
@@ -1165,8 +1163,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo_set_input_timing(encoder, &input_dtd);
}
#else
- if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
- return;
+ (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);
#endif
sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
@@ -1932,6 +1929,41 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
.destroy = intel_sdvo_enc_destroy,
};
+static void
+intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
+{
+ 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 (sdvo->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 &= sdvo->caps.output_flags;
+ num_bits = hweight16(mask);
+ /* If more than 3 outputs, default to DDC bus 3 for now. */
+ if (num_bits > 3)
+ num_bits = 3;
+
+ /* Corresponds to SDVO_CONTROL_BUS_DDCx */
+ sdvo->ddc_bus = 1 << num_bits;
+}
/**
* Choose the appropriate DDC bus for control bus switch command for this
@@ -1951,7 +1983,10 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
else
mapping = &(dev_priv->sdvo_mappings[1]);
- sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
+ if (mapping->initialized)
+ sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
+ else
+ intel_sdvo_guess_ddc_bus(sdvo);
}
static bool
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index d2029efee982..c671f60ce80b 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1231,7 +1231,6 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
struct drm_encoder *encoder = &intel_tv->base.enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
unsigned long irqflags;
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
@@ -1268,11 +1267,15 @@ intel_tv_detect_type (struct intel_tv *intel_tv)
DAC_C_0_7_V);
I915_WRITE(TV_CTL, tv_ctl);
I915_WRITE(TV_DAC, tv_dac);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ POSTING_READ(TV_DAC);
+ msleep(20);
+
tv_dac = I915_READ(TV_DAC);
I915_WRITE(TV_DAC, save_tv_dac);
I915_WRITE(TV_CTL, save_tv_ctl);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ POSTING_READ(TV_CTL);
+ msleep(20);
+
/*
* A B C
* 0 1 1 Composite
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 26d0d8ced80d..ac64f0b0392e 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -75,6 +75,7 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = mga_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 1de5eb53e016..eb15345162a0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -393,6 +393,7 @@ static struct drm_driver driver = {
#if defined(CONFIG_COMPAT)
.compat_ioctl = nouveau_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index dbd30b2e43fd..02a4d1fd4845 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -104,6 +104,8 @@ static struct fb_ops nouveau_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static struct fb_ops nv04_fbcon_ops = {
@@ -117,6 +119,8 @@ static struct fb_ops nv04_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static struct fb_ops nv50_fbcon_ops = {
@@ -130,6 +134,8 @@ static struct fb_ops nv50_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 6b208ffafa8d..87ac21ec23d2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
struct nouveau_fence *fence;
uint32_t sequence;
+ spin_lock(&chan->fence.lock);
+
if (USE_REFCNT)
sequence = nvchan_rd32(chan, 0x48);
else
sequence = atomic_read(&chan->fence.last_sequence_irq);
if (chan->fence.sequence_ack == sequence)
- return;
+ goto out;
chan->fence.sequence_ack = sequence;
- spin_lock(&chan->fence.lock);
list_for_each_safe(entry, tmp, &chan->fence.pending) {
fence = list_entry(entry, struct nouveau_fence, entry);
@@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
if (sequence == chan->fence.sequence_ack)
break;
}
+out:
spin_unlock(&chan->fence.lock);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 581c67cd7b24..ead7b8fc53fc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -245,7 +245,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence)
list_del(&nvbo->entry);
nvbo->reserved_by = NULL;
ttm_bo_unreserve(&nvbo->bo);
- drm_gem_object_unreference(nvbo->gem);
+ drm_gem_object_unreference_unlocked(nvbo->gem);
}
}
@@ -300,7 +300,7 @@ retry:
validate_fini(op, NULL);
if (ret == -EAGAIN)
ret = ttm_bo_wait_unreserved(&nvbo->bo, false);
- drm_gem_object_unreference(gem);
+ drm_gem_object_unreference_unlocked(gem);
if (ret) {
NV_ERROR(dev, "fail reserve\n");
return ret;
@@ -616,8 +616,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
return PTR_ERR(bo);
}
- mutex_lock(&dev->struct_mutex);
-
/* Mark push buffers as being used on PFIFO, the validation code
* will then make sure that if the pushbuf bo moves, that they
* happen on the kernel channel, which will in turn cause a sync
@@ -731,7 +729,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
out:
validate_fini(&op, fence);
nouveau_fence_unref((void**)&fence);
- mutex_unlock(&dev->struct_mutex);
kfree(bo);
kfree(push);
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 497df8765f28..fb669dd39c3c 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -768,8 +768,9 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
}
static int
-nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *passed_fb,
+ int x, int y, bool atomic)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -780,13 +781,26 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
int arb_burst, arb_lwm;
int ret;
- ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
+ /* If atomic, we want to switch to the fb we were passed, so
+ * now we update pointers to do that. (We don't pin; just
+ * assume we're already pinned and update the base address.)
+ */
+ if (atomic) {
+ drm_fb = passed_fb;
+ fb = nouveau_framebuffer(passed_fb);
+ }
+ else {
+ /* If not atomic, we can go ahead and pin, and unpin the
+ * old fb we were passed.
+ */
+ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+ if (ret)
+ return ret;
- if (old_fb) {
- struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
- nouveau_bo_unpin(ofb->nvbo);
+ if (passed_fb) {
+ struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+ nouveau_bo_unpin(ofb->nvbo);
+ }
}
nv_crtc->fb.offset = fb->nvbo->bo.offset;
@@ -834,6 +848,21 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
+}
+
+static int
+nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter)
+{
+ return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
+}
+
static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
struct nouveau_bo *dst)
{
@@ -962,6 +991,7 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
.mode_fixup = nv_crtc_mode_fixup,
.mode_set = nv_crtc_mode_set,
.mode_set_base = nv04_crtc_mode_set_base,
+ .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
.load_lut = nv_crtc_gamma_load,
};
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index bfd4ca2fe7ef..727a7a12fed9 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -491,8 +491,9 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
}
static int
-nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb, bool update)
+nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *passed_fb,
+ int x, int y, bool update, bool atomic)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
@@ -504,6 +505,28 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ /* If atomic, we want to switch to the fb we were passed, so
+ * now we update pointers to do that. (We don't pin; just
+ * assume we're already pinned and update the base address.)
+ */
+ if (atomic) {
+ drm_fb = passed_fb;
+ fb = nouveau_framebuffer(passed_fb);
+ }
+ else {
+ /* If not atomic, we can go ahead and pin, and unpin the
+ * old fb we were passed.
+ */
+ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+ if (ret)
+ return ret;
+
+ if (passed_fb) {
+ struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+ nouveau_bo_unpin(ofb->nvbo);
+ }
+ }
+
switch (drm_fb->depth) {
case 8:
format = NV50_EVO_CRTC_FB_DEPTH_8;
@@ -526,15 +549,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
return -EINVAL;
}
- ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
-
- if (old_fb) {
- struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
- nouveau_bo_unpin(ofb->nvbo);
- }
-
nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@ -685,14 +699,22 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false);
}
static int
nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false);
+}
+
+static int
+nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter)
+{
+ return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true);
}
static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
@@ -702,6 +724,7 @@ static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
.mode_fixup = nv50_crtc_mode_fixup,
.mode_set = nv50_crtc_mode_set,
.mode_set_base = nv50_crtc_mode_set_base,
+ .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
.load_lut = nv50_crtc_lut_load,
};
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index c95bf9b681dd..91ef93cf1f35 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -139,6 +139,8 @@ nv50_instmem_init(struct drm_device *dev)
chan->file_priv = (struct drm_file *)-2;
dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
+ INIT_LIST_HEAD(&chan->ramht_refs);
+
/* Channel's PRAMIN object + heap */
ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0,
NULL, &chan->ramin);
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 1e2971f13aa1..d42c76c23714 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -71,6 +71,7 @@ static struct drm_driver driver = {
#ifdef CONFIG_COMPAT
.compat_ioctl = r128_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 577239a24fd5..ca867d50a2b1 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
args.usV_SyncWidth =
cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start);
+ args.ucOverscanRight = radeon_crtc->h_border;
+ args.ucOverscanLeft = radeon_crtc->h_border;
+ args.ucOverscanBottom = radeon_crtc->v_border;
+ args.ucOverscanTop = radeon_crtc->v_border;
+
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
misc |= ATOM_VSYNC_POLARITY;
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
@@ -534,6 +539,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
pll->algo = PLL_ALGO_LEGACY;
pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
}
+ /* There is some evidence (often anecdotal) that RV515 LVDS
+ * (on some boards at least) prefers the legacy algo. I'm not
+ * sure whether this should handled generically or on a
+ * case-by-case quirk basis. Both algos should work fine in the
+ * majority of cases.
+ */
+ if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ (rdev->family == CHIP_RV515)) {
+ /* allow the user to overrride just in case */
+ if (radeon_new_pll == 1)
+ pll->algo = PLL_ALGO_NEW;
+ else
+ pll->algo = PLL_ALGO_LEGACY;
+ }
} else {
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -834,13 +853,15 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
}
-static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int atomic)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_framebuffer *radeon_fb;
+ struct drm_framebuffer *target_fb;
struct drm_gem_object *obj;
struct radeon_bo *rbo;
uint64_t fb_location;
@@ -848,28 +869,43 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
int r;
/* no fb bound */
- if (!crtc->fb) {
+ if (!atomic && !crtc->fb) {
DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
- radeon_fb = to_radeon_framebuffer(crtc->fb);
+ if (atomic) {
+ radeon_fb = to_radeon_framebuffer(fb);
+ target_fb = fb;
+ }
+ else {
+ radeon_fb = to_radeon_framebuffer(crtc->fb);
+ target_fb = crtc->fb;
+ }
- /* Pin framebuffer & get tilling informations */
+ /* If atomic, assume fb object is pinned & idle & fenced and
+ * just update base pointers
+ */
obj = radeon_fb->obj;
rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
- r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
- if (unlikely(r != 0)) {
- radeon_bo_unreserve(rbo);
- return -EINVAL;
+
+ if (atomic)
+ fb_location = radeon_bo_gpu_offset(rbo);
+ else {
+ r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
+ if (unlikely(r != 0)) {
+ radeon_bo_unreserve(rbo);
+ return -EINVAL;
+ }
}
+
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
- switch (crtc->fb->bits_per_pixel) {
+ switch (target_fb->bits_per_pixel) {
case 8:
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
@@ -889,7 +925,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
break;
default:
DRM_ERROR("Unsupported screen depth %d\n",
- crtc->fb->bits_per_pixel);
+ target_fb->bits_per_pixel);
return -EINVAL;
}
@@ -935,10 +971,10 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
- WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
- WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
+ WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
+ WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
- fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
+ fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8);
WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
@@ -957,8 +993,8 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
else
WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
- if (old_fb && old_fb != crtc->fb) {
- radeon_fb = to_radeon_framebuffer(old_fb);
+ if (!atomic && fb && fb != crtc->fb) {
+ radeon_fb = to_radeon_framebuffer(fb);
rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
@@ -973,8 +1009,9 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int atomic)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -982,33 +1019,48 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj;
struct radeon_bo *rbo;
+ struct drm_framebuffer *target_fb;
uint64_t fb_location;
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
int r;
/* no fb bound */
- if (!crtc->fb) {
+ if (!atomic && !crtc->fb) {
DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
- radeon_fb = to_radeon_framebuffer(crtc->fb);
+ if (atomic) {
+ radeon_fb = to_radeon_framebuffer(fb);
+ target_fb = fb;
+ }
+ else {
+ radeon_fb = to_radeon_framebuffer(crtc->fb);
+ target_fb = crtc->fb;
+ }
- /* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj;
rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
- r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
- if (unlikely(r != 0)) {
- radeon_bo_unreserve(rbo);
- return -EINVAL;
+
+ /* If atomic, assume fb object is pinned & idle & fenced and
+ * just update base pointers
+ */
+ if (atomic)
+ fb_location = radeon_bo_gpu_offset(rbo);
+ else {
+ r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
+ if (unlikely(r != 0)) {
+ radeon_bo_unreserve(rbo);
+ return -EINVAL;
+ }
}
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
- switch (crtc->fb->bits_per_pixel) {
+ switch (target_fb->bits_per_pixel) {
case 8:
fb_format =
AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
@@ -1032,7 +1084,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
break;
default:
DRM_ERROR("Unsupported screen depth %d\n",
- crtc->fb->bits_per_pixel);
+ target_fb->bits_per_pixel);
return -EINVAL;
}
@@ -1056,11 +1108,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
if (rdev->family >= CHIP_RV770) {
if (radeon_crtc->crtc_id) {
- WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
- WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+ WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
+ WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
} else {
- WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0);
- WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0);
+ WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
+ WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location));
}
}
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
@@ -1073,10 +1125,10 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
- WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
- WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
+ WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width);
+ WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height);
- fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
+ fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8);
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
@@ -1095,8 +1147,8 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
else
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
- if (old_fb && old_fb != crtc->fb) {
- radeon_fb = to_radeon_framebuffer(old_fb);
+ if (!atomic && fb && fb != crtc->fb) {
+ radeon_fb = to_radeon_framebuffer(fb);
rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
@@ -1118,11 +1170,26 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct radeon_device *rdev = dev->dev_private;
if (ASIC_IS_DCE4(rdev))
- return evergreen_crtc_set_base(crtc, x, y, old_fb);
+ return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0);
+ else if (ASIC_IS_AVIVO(rdev))
+ return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
+ else
+ return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
+}
+
+int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter)
+{
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (ASIC_IS_DCE4(rdev))
+ return evergreen_crtc_do_set_base(crtc, fb, x, y, 1);
else if (ASIC_IS_AVIVO(rdev))
- return avivo_crtc_set_base(crtc, x, y, old_fb);
+ return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
else
- return radeon_crtc_set_base(crtc, x, y, old_fb);
+ return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
}
/* properly set additional regs when using atombios */
@@ -1197,8 +1264,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ struct drm_encoder *encoder;
+ bool is_tvcv = false;
- /* TODO color tiling */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ /* find tv std */
+ if (encoder->crtc == crtc) {
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ if (radeon_encoder->active_device &
+ (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+ is_tvcv = true;
+ }
+ }
atombios_disable_ss(crtc);
/* always set DCPLL */
@@ -1207,9 +1284,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
atombios_crtc_set_pll(crtc, adjusted_mode);
atombios_enable_ss(crtc);
- if (ASIC_IS_AVIVO(rdev))
+ if (ASIC_IS_DCE4(rdev))
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
- else {
+ else if (ASIC_IS_AVIVO(rdev)) {
+ if (is_tvcv)
+ atombios_crtc_set_timing(crtc, adjusted_mode);
+ else
+ atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
+ } else {
atombios_crtc_set_timing(crtc, adjusted_mode);
if (radeon_crtc->crtc_id == 0)
atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
@@ -1276,6 +1358,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
.mode_fixup = atombios_crtc_mode_fixup,
.mode_set = atombios_crtc_mode_set,
.mode_set_base = atombios_crtc_set_base,
+ .mode_set_base_atomic = atombios_crtc_set_base_atomic,
.prepare = atombios_crtc_prepare,
.commit = atombios_crtc_commit,
.load_lut = radeon_crtc_load_lut,
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 957d5067ad9c..b8b7f010b25f 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -675,6 +675,43 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev)
return 0;
}
+static int evergreen_cp_start(struct radeon_device *rdev)
+{
+ int r;
+ uint32_t cp_me;
+
+ r = radeon_ring_lock(rdev, 7);
+ if (r) {
+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+ return r;
+ }
+ radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
+ radeon_ring_write(rdev, 0x1);
+ radeon_ring_write(rdev, 0x0);
+ radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1);
+ radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
+ radeon_ring_write(rdev, 0);
+ radeon_ring_write(rdev, 0);
+ radeon_ring_unlock_commit(rdev);
+
+ cp_me = 0xff;
+ WREG32(CP_ME_CNTL, cp_me);
+
+ r = radeon_ring_lock(rdev, 4);
+ if (r) {
+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+ return r;
+ }
+ /* init some VGT regs */
+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+ radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2);
+ radeon_ring_write(rdev, 0xe);
+ radeon_ring_write(rdev, 0x10);
+ radeon_ring_unlock_commit(rdev);
+
+ return 0;
+}
+
int evergreen_cp_resume(struct radeon_device *rdev)
{
u32 tmp;
@@ -719,7 +756,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)
rdev->cp.rptr = RREG32(CP_RB_RPTR);
rdev->cp.wptr = RREG32(CP_RB_WPTR);
- r600_cp_start(rdev);
+ evergreen_cp_start(rdev);
rdev->cp.ready = true;
r = radeon_ring_test(rdev);
if (r) {
@@ -2054,11 +2091,6 @@ int evergreen_resume(struct radeon_device *rdev)
*/
/* post card */
atom_asic_init(rdev->mode_info.atom_context);
- /* Initialize clocks */
- r = radeon_clocks_init(rdev);
- if (r) {
- return r;
- }
r = evergreen_startup(rdev);
if (r) {
@@ -2164,9 +2196,6 @@ int evergreen_init(struct radeon_device *rdev)
radeon_surface_init(rdev);
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
- r = radeon_clocks_init(rdev);
- if (r)
- return r;
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
@@ -2236,7 +2265,6 @@ void evergreen_fini(struct radeon_device *rdev)
evergreen_pcie_gart_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
- radeon_clocks_fini(rdev);
radeon_agp_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d0ebae9dde25..afc18d87fdca 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2119,10 +2119,7 @@ int r600_cp_start(struct radeon_device *rdev)
}
radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
radeon_ring_write(rdev, 0x1);
- if (rdev->family >= CHIP_CEDAR) {
- radeon_ring_write(rdev, 0x0);
- radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1);
- } else if (rdev->family >= CHIP_RV770) {
+ if (rdev->family >= CHIP_RV770) {
radeon_ring_write(rdev, 0x0);
radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
} else {
@@ -2489,11 +2486,6 @@ int r600_resume(struct radeon_device *rdev)
*/
/* post card */
atom_asic_init(rdev->mode_info.atom_context);
- /* Initialize clocks */
- r = radeon_clocks_init(rdev);
- if (r) {
- return r;
- }
r = r600_startup(rdev);
if (r) {
@@ -2586,9 +2578,6 @@ int r600_init(struct radeon_device *rdev)
radeon_surface_init(rdev);
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
- r = radeon_clocks_init(rdev);
- if (r)
- return r;
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
@@ -2663,7 +2652,6 @@ void r600_fini(struct radeon_device *rdev)
radeon_agp_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
- radeon_clocks_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
kfree(rdev->bios);
@@ -3541,7 +3529,7 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
*/
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
- void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+ void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
u32 tmp;
WREG32(HDP_DEBUG1, 0);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 3dfcfa3ca425..a168d644bf9e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1013,6 +1013,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
+/* VRAM scratch page for HDP bug */
+struct r700_vram_scratch {
+ struct radeon_bo *robj;
+ volatile uint32_t *ptr;
+};
/*
* Core structure, functions and helpers.
@@ -1079,6 +1084,7 @@ struct radeon_device {
const struct firmware *pfp_fw; /* r6/700 PFP firmware */
const struct firmware *rlc_fw; /* r6/700 RLC firmware */
struct r600_blit r600_blit;
+ struct r700_vram_scratch vram_scratch;
int msi_enabled; /* msi enabled */
struct r600_ih ih; /* r6/700 interrupt ring */
struct workqueue_struct *wq;
@@ -1333,8 +1339,6 @@ extern bool radeon_card_posted(struct radeon_device *rdev);
extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
extern void radeon_update_display_priority(struct radeon_device *rdev);
extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
-extern int radeon_clocks_init(struct radeon_device *rdev);
-extern void radeon_clocks_fini(struct radeon_device *rdev);
extern void radeon_scratch_init(struct radeon_device *rdev);
extern void radeon_surface_init(struct radeon_device *rdev);
extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index a21bf88e8c2d..25e1dd197791 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -858,21 +858,3 @@ int radeon_asic_init(struct radeon_device *rdev)
return 0;
}
-/*
- * Wrapper around modesetting bits. Move to radeon_clocks.c?
- */
-int radeon_clocks_init(struct radeon_device *rdev)
-{
- int r;
-
- r = radeon_static_clocks_init(rdev->ddev);
- if (r) {
- return r;
- }
- DRM_INFO("Clocks initialized !\n");
- return 0;
-}
-
-void radeon_clocks_fini(struct radeon_device *rdev)
-{
-}
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 61141981880d..ebae14c4b768 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -85,6 +85,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
for (i = 0; i < num_indices; i++) {
gpio = &i2c_info->asGPIO_Info[i];
+ /* some evergreen boards have bad data for this entry */
+ if (ASIC_IS_DCE4(rdev)) {
+ if ((i == 7) &&
+ (gpio->usClkMaskRegisterIndex == 0x1936) &&
+ (gpio->sucI2cId.ucAccess == 0)) {
+ gpio->sucI2cId.ucAccess = 0x97;
+ gpio->ucDataMaskShift = 8;
+ gpio->ucDataEnShift = 8;
+ gpio->ucDataY_Shift = 8;
+ gpio->ucDataA_Shift = 8;
+ }
+ }
+
if (gpio->sucI2cId.ucAccess == id) {
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
@@ -147,6 +160,20 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
for (i = 0; i < num_indices; i++) {
gpio = &i2c_info->asGPIO_Info[i];
i2c.valid = false;
+
+ /* some evergreen boards have bad data for this entry */
+ if (ASIC_IS_DCE4(rdev)) {
+ if ((i == 7) &&
+ (gpio->usClkMaskRegisterIndex == 0x1936) &&
+ (gpio->sucI2cId.ucAccess == 0)) {
+ gpio->sucI2cId.ucAccess = 0x97;
+ gpio->ucDataMaskShift = 8;
+ gpio->ucDataEnShift = 8;
+ gpio->ucDataY_Shift = 8;
+ gpio->ucDataA_Shift = 8;
+ }
+ }
+
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index 14448a740ba6..5249af8931e6 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -327,6 +327,14 @@ void radeon_get_clock_info(struct drm_device *dev)
mpll->max_feedback_div = 0xff;
mpll->best_vco = 0;
+ if (!rdev->clock.default_sclk)
+ rdev->clock.default_sclk = radeon_get_engine_clock(rdev);
+ if ((!rdev->clock.default_mclk) && rdev->asic->get_memory_clock)
+ rdev->clock.default_mclk = radeon_get_memory_clock(rdev);
+
+ rdev->pm.current_sclk = rdev->clock.default_sclk;
+ rdev->pm.current_mclk = rdev->clock.default_mclk;
+
}
/* 10 khz */
@@ -897,53 +905,3 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
}
}
-static void radeon_apply_clock_quirks(struct radeon_device *rdev)
-{
- uint32_t tmp;
-
- /* XXX make sure engine is idle */
-
- if (rdev->family < CHIP_RS600) {
- tmp = RREG32_PLL(RADEON_SCLK_CNTL);
- if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev))
- tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP;
- if ((rdev->family == CHIP_RV250)
- || (rdev->family == CHIP_RV280))
- tmp |=
- RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2;
- if ((rdev->family == CHIP_RV350)
- || (rdev->family == CHIP_RV380))
- tmp |= R300_SCLK_FORCE_VAP;
- if (rdev->family == CHIP_R420)
- tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX;
- WREG32_PLL(RADEON_SCLK_CNTL, tmp);
- } else if (rdev->family < CHIP_R600) {
- tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL);
- tmp |= AVIVO_CP_FORCEON;
- WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp);
-
- tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL);
- tmp |= AVIVO_E2_FORCEON;
- WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp);
-
- tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL);
- tmp |= AVIVO_IDCT_FORCEON;
- WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp);
- }
-}
-
-int radeon_static_clocks_init(struct drm_device *dev)
-{
- struct radeon_device *rdev = dev->dev_private;
-
- /* XXX make sure engine is idle */
-
- if (radeon_dynclks != -1) {
- if (radeon_dynclks) {
- if (rdev->asic->set_clock_gating)
- radeon_set_clock_gating(rdev, 1);
- }
- }
- radeon_apply_clock_quirks(rdev);
- return 0;
-}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 1a5ee392e9c7..a9dd7847d96e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1051,10 +1051,16 @@ radeon_add_atom_connector(struct drm_device *dev,
uint32_t subpixel_order = SubPixelNone;
bool shared_ddc = false;
- /* fixme - tv/cv/din */
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
return;
+ /* if the user selected tv=0 don't try and add the connector */
+ if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
+ (connector_type == DRM_MODE_CONNECTOR_Composite) ||
+ (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
+ (radeon_tv == 0))
+ return;
+
/* see if we already added it */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
radeon_connector = to_radeon_connector(connector);
@@ -1209,19 +1215,17 @@ radeon_add_atom_connector(struct drm_device *dev,
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_9PinDIN:
- if (radeon_tv == 1) {
- drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
- drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
- radeon_connector->dac_load_detect = true;
- drm_connector_attach_property(&radeon_connector->base,
- rdev->mode_info.load_detect_property,
- 1);
- drm_connector_attach_property(&radeon_connector->base,
- rdev->mode_info.tv_std_property,
- radeon_atombios_get_tv_info(rdev));
- /* no HPD on analog connectors */
- radeon_connector->hpd.hpd = RADEON_HPD_NONE;
- }
+ drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
+ drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
+ radeon_connector->dac_load_detect = true;
+ drm_connector_attach_property(&radeon_connector->base,
+ rdev->mode_info.load_detect_property,
+ 1);
+ drm_connector_attach_property(&radeon_connector->base,
+ rdev->mode_info.tv_std_property,
+ radeon_atombios_get_tv_info(rdev));
+ /* no HPD on analog connectors */
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
break;
case DRM_MODE_CONNECTOR_LVDS:
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -1272,10 +1276,16 @@ radeon_add_legacy_connector(struct drm_device *dev,
struct radeon_connector *radeon_connector;
uint32_t subpixel_order = SubPixelNone;
- /* fixme - tv/cv/din */
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
return;
+ /* if the user selected tv=0 don't try and add the connector */
+ if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
+ (connector_type == DRM_MODE_CONNECTOR_Composite) ||
+ (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
+ (radeon_tv == 0))
+ return;
+
/* see if we already added it */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
radeon_connector = to_radeon_connector(connector);
@@ -1347,26 +1357,24 @@ radeon_add_legacy_connector(struct drm_device *dev,
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
case DRM_MODE_CONNECTOR_9PinDIN:
- if (radeon_tv == 1) {
- drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
- drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
- radeon_connector->dac_load_detect = true;
- /* RS400,RC410,RS480 chipset seems to report a lot
- * of false positive on load detect, we haven't yet
- * found a way to make load detect reliable on those
- * chipset, thus just disable it for TV.
- */
- if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
- radeon_connector->dac_load_detect = false;
- drm_connector_attach_property(&radeon_connector->base,
- rdev->mode_info.load_detect_property,
- radeon_connector->dac_load_detect);
- drm_connector_attach_property(&radeon_connector->base,
- rdev->mode_info.tv_std_property,
- radeon_combios_get_tv_info(rdev));
- /* no HPD on analog connectors */
- radeon_connector->hpd.hpd = RADEON_HPD_NONE;
- }
+ drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
+ drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
+ radeon_connector->dac_load_detect = true;
+ /* RS400,RC410,RS480 chipset seems to report a lot
+ * of false positive on load detect, we haven't yet
+ * found a way to make load detect reliable on those
+ * chipset, thus just disable it for TV.
+ */
+ if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
+ radeon_connector->dac_load_detect = false;
+ drm_connector_attach_property(&radeon_connector->base,
+ rdev->mode_info.load_detect_property,
+ radeon_connector->dac_load_detect);
+ drm_connector_attach_property(&radeon_connector->base,
+ rdev->mode_info.tv_std_property,
+ radeon_combios_get_tv_info(rdev));
+ /* no HPD on analog connectors */
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
break;
case DRM_MODE_CONNECTOR_LVDS:
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index fcc79b5d22d1..6d64a2705f12 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -268,7 +268,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
}
r = radeon_ib_schedule(rdev, parser.ib);
if (r) {
- DRM_ERROR("Faild to schedule IB !\n");
+ DRM_ERROR("Failed to schedule IB !\n");
}
radeon_cs_parser_fini(&parser, r);
mutex_unlock(&rdev->cs_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 69b3c2291e92..256d204a6d24 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -293,30 +293,20 @@ bool radeon_card_posted(struct radeon_device *rdev)
void radeon_update_bandwidth_info(struct radeon_device *rdev)
{
fixed20_12 a;
- u32 sclk, mclk;
+ u32 sclk = rdev->pm.current_sclk;
+ u32 mclk = rdev->pm.current_mclk;
- if (rdev->flags & RADEON_IS_IGP) {
- sclk = radeon_get_engine_clock(rdev);
- mclk = rdev->clock.default_mclk;
-
- a.full = dfixed_const(100);
- rdev->pm.sclk.full = dfixed_const(sclk);
- rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
- rdev->pm.mclk.full = dfixed_const(mclk);
- rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
+ /* sclk/mclk in Mhz */
+ a.full = dfixed_const(100);
+ rdev->pm.sclk.full = dfixed_const(sclk);
+ rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
+ rdev->pm.mclk.full = dfixed_const(mclk);
+ rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
+ if (rdev->flags & RADEON_IS_IGP) {
a.full = dfixed_const(16);
/* core_bandwidth = sclk(Mhz) * 16 */
rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a);
- } else {
- sclk = radeon_get_engine_clock(rdev);
- mclk = radeon_get_memory_clock(rdev);
-
- a.full = dfixed_const(100);
- rdev->pm.sclk.full = dfixed_const(sclk);
- rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a);
- rdev->pm.mclk.full = dfixed_const(mclk);
- rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a);
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 6dd434ad2429..8d88a18cafc1 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -138,6 +138,38 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
legacy_crtc_load_lut(crtc);
}
+void radeon_crtc_save_lut(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ int i;
+
+ if (!crtc->enabled)
+ return;
+
+ for (i = 0; i < 256; i++) {
+ radeon_crtc->lut_r_copy[i] = radeon_crtc->lut_r[i];
+ radeon_crtc->lut_g_copy[i] = radeon_crtc->lut_g[i];
+ radeon_crtc->lut_b_copy[i] = radeon_crtc->lut_b[i];
+ }
+}
+
+void radeon_crtc_restore_lut(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ int i;
+
+ if (!crtc->enabled)
+ return;
+
+ for (i = 0; i < 256; i++) {
+ radeon_crtc->lut_r[i] = radeon_crtc->lut_r_copy[i];
+ radeon_crtc->lut_g[i] = radeon_crtc->lut_g_copy[i];
+ radeon_crtc->lut_b[i] = radeon_crtc->lut_b_copy[i];
+ }
+
+ radeon_crtc_load_lut(crtc);
+}
+
/** Sets the color ramps on behalf of fbcon */
void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 795403b0e2cd..29c1237c2e7b 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -219,6 +219,7 @@ static struct drm_driver driver_old = {
#ifdef CONFIG_COMPAT
.compat_ioctl = radeon_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index c74a8b20d941..fc3c408ed0b5 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -59,6 +59,8 @@ static struct fb_ops radeonfb_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 0416804d8f30..6a13ee38a5b9 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -213,7 +213,7 @@ static void post_xfer(struct i2c_adapter *i2c_adap)
static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
{
- u32 sclk = radeon_get_engine_clock(rdev);
+ u32 sclk = rdev->pm.current_sclk;
u32 prescale = 0;
u32 nm;
u8 n, m, loop;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 305049afde15..42954785247f 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -348,10 +348,30 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
+ return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
+}
+
+int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter)
+{
+ if (enter)
+ radeon_crtc_save_lut(crtc);
+ else
+ radeon_crtc_restore_lut(crtc);
+
+ return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
+}
+
+int radeon_crtc_do_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int atomic)
+{
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_framebuffer *radeon_fb;
+ struct drm_framebuffer *target_fb;
struct drm_gem_object *obj;
struct radeon_bo *rbo;
uint64_t base;
@@ -364,14 +384,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
DRM_DEBUG_KMS("\n");
/* no fb bound */
- if (!crtc->fb) {
+ if (!atomic && !crtc->fb) {
DRM_DEBUG_KMS("No FB bound\n");
return 0;
}
- radeon_fb = to_radeon_framebuffer(crtc->fb);
+ if (atomic) {
+ radeon_fb = to_radeon_framebuffer(fb);
+ target_fb = fb;
+ }
+ else {
+ radeon_fb = to_radeon_framebuffer(crtc->fb);
+ target_fb = crtc->fb;
+ }
- switch (crtc->fb->bits_per_pixel) {
+ switch (target_fb->bits_per_pixel) {
case 8:
format = 2;
break;
@@ -415,10 +442,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
crtc_offset_cntl = 0;
- pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
- crtc_pitch = (((pitch_pixels * crtc->fb->bits_per_pixel) +
- ((crtc->fb->bits_per_pixel * 8) - 1)) /
- (crtc->fb->bits_per_pixel * 8));
+ pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8);
+ crtc_pitch = (((pitch_pixels * target_fb->bits_per_pixel) +
+ ((target_fb->bits_per_pixel * 8) - 1)) /
+ (target_fb->bits_per_pixel * 8));
crtc_pitch |= crtc_pitch << 16;
@@ -443,14 +470,14 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
crtc_tile_x0_y0 = x | (y << 16);
base &= ~0x7ff;
} else {
- int byteshift = crtc->fb->bits_per_pixel >> 4;
+ int byteshift = target_fb->bits_per_pixel >> 4;
int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11;
base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
crtc_offset_cntl |= (y % 16);
}
} else {
int offset = y * pitch_pixels + x;
- switch (crtc->fb->bits_per_pixel) {
+ switch (target_fb->bits_per_pixel) {
case 8:
offset *= 1;
break;
@@ -496,8 +523,8 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
- if (old_fb && old_fb != crtc->fb) {
- radeon_fb = to_radeon_framebuffer(old_fb);
+ if (!atomic && fb && fb != crtc->fb) {
+ radeon_fb = to_radeon_framebuffer(fb);
rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
@@ -1040,6 +1067,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.mode_fixup = radeon_crtc_mode_fixup,
.mode_set = radeon_crtc_mode_set,
.mode_set_base = radeon_crtc_set_base,
+ .mode_set_base_atomic = radeon_crtc_set_base_atomic,
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
.load_lut = radeon_crtc_load_lut,
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 8f93e2b4b0c8..1abc91b4b14f 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -266,6 +266,7 @@ struct radeon_crtc {
struct drm_crtc base;
int crtc_id;
u16 lut_r[256], lut_g[256], lut_b[256];
+ u16 lut_r_copy[256], lut_g_copy[256], lut_b_copy[256];
bool enabled;
bool can_tile;
uint32_t crtc_offset;
@@ -511,8 +512,13 @@ extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
+extern void radeon_crtc_save_lut(struct drm_crtc *crtc);
+extern void radeon_crtc_restore_lut(struct drm_crtc *crtc);
extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);
+extern int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter);
extern int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -522,7 +528,12 @@ extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode);
extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);
-
+extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int enter);
+extern int radeon_crtc_do_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y, int atomic);
extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,
@@ -600,7 +611,6 @@ extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct d
void radeon_enc_destroy(struct drm_encoder *encoder);
void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
void radeon_combios_asic_init(struct drm_device *dev);
-extern int radeon_static_clocks_init(struct drm_device *dev);
bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index f1c796810117..bfa59db374d2 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -905,6 +905,54 @@ static void rv770_gpu_init(struct radeon_device *rdev)
}
+static int rv770_vram_scratch_init(struct radeon_device *rdev)
+{
+ int r;
+ u64 gpu_addr;
+
+ if (rdev->vram_scratch.robj == NULL) {
+ r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
+ true, RADEON_GEM_DOMAIN_VRAM,
+ &rdev->vram_scratch.robj);
+ if (r) {
+ return r;
+ }
+ }
+
+ r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+ if (unlikely(r != 0))
+ return r;
+ r = radeon_bo_pin(rdev->vram_scratch.robj,
+ RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
+ if (r) {
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+ return r;
+ }
+ r = radeon_bo_kmap(rdev->vram_scratch.robj,
+ (void **)&rdev->vram_scratch.ptr);
+ if (r)
+ radeon_bo_unpin(rdev->vram_scratch.robj);
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+
+ return r;
+}
+
+static void rv770_vram_scratch_fini(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->vram_scratch.robj == NULL) {
+ return;
+ }
+ r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+ if (likely(r == 0)) {
+ radeon_bo_kunmap(rdev->vram_scratch.robj);
+ radeon_bo_unpin(rdev->vram_scratch.robj);
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+ }
+ radeon_bo_unref(&rdev->vram_scratch.robj);
+}
+
int rv770_mc_init(struct radeon_device *rdev)
{
u32 tmp;
@@ -970,6 +1018,9 @@ static int rv770_startup(struct radeon_device *rdev)
if (r)
return r;
}
+ r = rv770_vram_scratch_init(rdev);
+ if (r)
+ return r;
rv770_gpu_init(rdev);
r = r600_blit_init(rdev);
if (r) {
@@ -1023,11 +1074,6 @@ int rv770_resume(struct radeon_device *rdev)
*/
/* post card */
atom_asic_init(rdev->mode_info.atom_context);
- /* Initialize clocks */
- r = radeon_clocks_init(rdev);
- if (r) {
- return r;
- }
r = rv770_startup(rdev);
if (r) {
@@ -1118,9 +1164,6 @@ int rv770_init(struct radeon_device *rdev)
radeon_surface_init(rdev);
/* Initialize clocks */
radeon_get_clock_info(rdev->ddev);
- r = radeon_clocks_init(rdev);
- if (r)
- return r;
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
@@ -1195,9 +1238,9 @@ void rv770_fini(struct radeon_device *rdev)
r600_irq_fini(rdev);
radeon_irq_kms_fini(rdev);
rv770_pcie_gart_fini(rdev);
+ rv770_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
- radeon_clocks_fini(rdev);
radeon_agp_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
index 021de44c15ab..2a2830f5a840 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -54,6 +54,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 776bf9e9ea1a..4bb10ef6676a 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -83,6 +83,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index ec5a43e65722..640567ef713d 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -52,6 +52,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 7a1b210401e0..b8984a5ae521 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -62,6 +62,7 @@ static struct drm_driver driver = {
.mmap = drm_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 72ec2e2b6e97..d237190b888a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -745,6 +745,7 @@ static struct drm_driver driver = {
#if defined(CONFIG_COMPAT)
.compat_ioctl = drm_compat_ioctl,
#endif
+ .llseek = noop_llseek,
},
.pci_driver = {
.name = VMWGFX_DRIVER_NAME,
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index b87569e96b16..329f4df6e014 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -1211,6 +1211,7 @@ static const struct file_operations vga_arb_device_fops = {
.poll = vga_arb_fpoll,
.open = vga_arb_open,
.release = vga_arb_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct miscdevice vga_arb_device = {
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 6369ba7f96f8..01fdb1717295 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -56,20 +56,20 @@ menu "Special HID drivers"
depends on HID
config HID_3M_PCT
- tristate "3M PCT"
+ tristate "3M PCT touchscreen"
depends on USB_HID
---help---
Support for 3M PCT touch screens.
config HID_A4TECH
- tristate "A4 tech" if EMBEDDED
+ tristate "A4 tech mice" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for A4 tech X5 and WOP-35 / Trust 450L mice.
config HID_ACRUX_FF
- tristate "ACRUX force feedback support"
+ tristate "ACRUX force feedback"
depends on USB_HID
select INPUT_FF_MEMLESS
---help---
@@ -77,7 +77,7 @@ config HID_ACRUX_FF
game controllers.
config HID_APPLE
- tristate "Apple" if EMBEDDED
+ tristate "Apple {i,Power,Mac}Books" if EMBEDDED
depends on (USB_HID || BT_HIDP)
default !EMBEDDED
---help---
@@ -88,7 +88,7 @@ config HID_APPLE
MacBooks, MacBook Pros and Apple Aluminum.
config HID_BELKIN
- tristate "Belkin" if EMBEDDED
+ tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
@@ -101,14 +101,14 @@ config HID_CANDO
Support for Cando dual touch panel.
config HID_CHERRY
- tristate "Cherry" if EMBEDDED
+ tristate "Cherry Cymotion keyboard" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Cherry Cymotion keyboard.
config HID_CHICONY
- tristate "Chicony" if EMBEDDED
+ tristate "Chicony Tactical pad" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
@@ -130,20 +130,20 @@ config HID_PRODIKEYS
and some additional multimedia keys.
config HID_CYPRESS
- tristate "Cypress" if EMBEDDED
+ tristate "Cypress mouse and barcode readers" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for cypress mouse and barcode readers.
config HID_DRAGONRISE
- tristate "DragonRise Inc. support"
+ tristate "DragonRise Inc. game controller"
depends on USB_HID
---help---
Say Y here if you have DragonRise Inc.game controllers.
config DRAGONRISE_FF
- bool "DragonRise Inc. force feedback support"
+ bool "DragonRise Inc. force feedback"
depends on HID_DRAGONRISE
select INPUT_FF_MEMLESS
---help---
@@ -157,46 +157,58 @@ config HID_EGALAX
Support for the eGalax dual-touch panel.
config HID_ELECOM
- tristate "ELECOM"
+ tristate "ELECOM BM084 bluetooth mouse"
depends on BT_HIDP
---help---
Support for the ELECOM BM084 (bluetooth mouse).
config HID_EZKEY
- tristate "Ezkey" if EMBEDDED
+ tristate "Ezkey BTC 8193 keyboard" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Ezkey BTC 8193 keyboard.
config HID_KYE
- tristate "Kye" if EMBEDDED
+ tristate "Kye/Genius Ergo Mouse" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Kye/Genius Ergo Mouse.
+config HID_UCLOGIC
+ tristate "UC-Logic"
+ depends on USB_HID
+ ---help---
+ Support for UC-Logic tablets.
+
+config HID_WALTOP
+ tristate "Waltop"
+ depends on USB_HID
+ ---help---
+ Support for Waltop tablets.
+
config HID_GYRATION
- tristate "Gyration"
+ tristate "Gyration remote control"
depends on USB_HID
---help---
Support for Gyration remote control.
config HID_TWINHAN
- tristate "Twinhan"
+ tristate "Twinhan IR remote control"
depends on USB_HID
---help---
Support for Twinhan IR remote control.
config HID_KENSINGTON
- tristate "Kensington" if EMBEDDED
+ tristate "Kensington Slimblade Trackball" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Kensington Slimblade Trackball.
config HID_LOGITECH
- tristate "Logitech" if EMBEDDED
+ tristate "Logitech devices" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
@@ -245,39 +257,39 @@ config HID_MAGICMOUSE
Apple Wireless "Magic" Mouse.
config HID_MICROSOFT
- tristate "Microsoft" if EMBEDDED
+ tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Microsoft devices that are not fully compliant with HID standard.
config HID_MOSART
- tristate "MosArt"
+ tristate "MosArt dual-touch panels"
depends on USB_HID
---help---
Support for MosArt dual-touch panels.
config HID_MONTEREY
- tristate "Monterey" if EMBEDDED
+ tristate "Monterey Genius KB29E keyboard" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Monterey Genius KB29E.
config HID_NTRIG
- tristate "NTrig"
+ tristate "N-Trig touch screen"
depends on USB_HID
---help---
Support for N-Trig touch screen.
config HID_ORTEK
- tristate "Ortek"
+ tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad"
depends on USB_HID
---help---
Support for Ortek WKB-2000 wireless keyboard + mouse trackpad.
config HID_PANTHERLORD
- tristate "Pantherlord support"
+ tristate "Pantherlord/GreenAsia game controller"
depends on USB_HID
---help---
Say Y here if you have a PantherLord/GreenAsia based game controller
@@ -292,7 +304,7 @@ config PANTHERLORD_FF
or adapter and want to enable force feedback support for it.
config HID_PETALYNX
- tristate "Petalynx"
+ tristate "Petalynx Maxter remote control"
depends on USB_HID
---help---
Support for Petalynx Maxter remote control.
@@ -356,7 +368,7 @@ config HID_PICOLCD_LEDS
Provide access to PicoLCD's GPO pins via leds class.
config HID_QUANTA
- tristate "Quanta Optical Touch"
+ tristate "Quanta Optical Touch panels"
depends on USB_HID
---help---
Support for Quanta Optical Touch dual-touch panels.
@@ -376,32 +388,39 @@ config HID_ROCCAT_KONE
---help---
Support for Roccat Kone mouse.
+config HID_ROCCAT_PYRA
+ tristate "Roccat Pyra mouse support"
+ depends on USB_HID
+ select HID_ROCCAT
+ ---help---
+ Support for Roccat Pyra mouse.
+
config HID_SAMSUNG
- tristate "Samsung"
+ tristate "Samsung InfraRed remote control or keyboards"
depends on USB_HID
---help---
Support for Samsung InfraRed remote control or keyboards.
config HID_SONY
- tristate "Sony"
+ tristate "Sony PS3 controller"
depends on USB_HID
---help---
Support for Sony PS3 controller.
config HID_STANTUM
- tristate "Stantum"
+ tristate "Stantum multitouch panel"
depends on USB_HID
---help---
Support for Stantum multitouch panel.
config HID_SUNPLUS
- tristate "Sunplus"
+ tristate "Sunplus wireless desktop"
depends on USB_HID
---help---
Support for Sunplus wireless desktop.
config HID_GREENASIA
- tristate "GreenAsia (Product ID 0x12) support"
+ tristate "GreenAsia (Product ID 0x12) game controller support"
depends on USB_HID
---help---
Say Y here if you have a GreenAsia (Product ID 0x12) based game
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 46f037f3df80..8baef4cd90af 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
+obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
obj-$(CONFIG_HID_SONY) += hid-sony.o
@@ -61,9 +62,11 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
+obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
obj-$(CONFIG_HID_WACOM) += hid-wacom.o
+obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
obj-$(CONFIG_USB_HID) += usbhid/
obj-$(CONFIG_USB_MOUSE) += usbhid/
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index bba05d0a8980..eaeca564a8d3 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -246,17 +246,18 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
/*
* MacBook JIS keyboard has wrong logical maximum
*/
-static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
- if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 &&
+ if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
rdesc[53] == 0x65 && rdesc[59] == 0x65) {
dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
"descriptor\n");
rdesc[53] = rdesc[59] = 0xe7;
}
+ return rdesc;
}
static void apple_setup_input(struct input_dev *input)
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index 24663a8717b1..e880086c2311 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -26,15 +26,16 @@
* Cherry Cymotion keyboard have an invalid HID report descriptor,
* that needs fixing before we can parse it.
*/
-static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
+ if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
"descriptor\n");
rdesc[11] = rdesc[16] = 0xff;
rdesc[12] = rdesc[17] = 0x03;
}
+ return rdesc;
}
#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0c52899be964..3fe1dcd67f2f 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -388,12 +388,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
__u32 data;
unsigned n;
- /* Local delimiter could have value 0, which allows size to be 0 */
- if (item->size == 0 && item->tag != HID_LOCAL_ITEM_TAG_DELIMITER) {
- dbg_hid("item data expected for local item\n");
- return -1;
- }
-
data = item_udata(item);
switch (item->tag) {
@@ -651,7 +645,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
};
if (device->driver->report_fixup)
- device->driver->report_fixup(device, start, size);
+ start = device->driver->report_fixup(device, start, &size);
device->rdesc = kmemdup(start, size, GFP_KERNEL);
if (device->rdesc == NULL)
@@ -1248,6 +1242,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
@@ -1285,8 +1280,11 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
@@ -1367,6 +1365,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
@@ -1384,8 +1383,15 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
@@ -1578,7 +1584,6 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) },
{ HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)},
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)},
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)},
{ HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
@@ -1767,6 +1772,11 @@ static bool hid_ignore(struct hid_device *hdev)
hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
return true;
break;
+ case USB_VENDOR_ID_HANWANG:
+ if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST &&
+ hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
+ return true;
+ break;
}
if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 998b6f443d7d..4cd0e2345991 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -31,16 +31,16 @@
* Some USB barcode readers from cypress have usage min and usage max in
* the wrong order
*/
-static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
unsigned int i;
if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
- return;
+ return rdesc;
- for (i = 0; i < rsize - 4; i++)
+ for (i = 0; i < *rsize - 4; i++)
if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
__u8 tmp;
@@ -50,6 +50,7 @@ static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[i + 3] = rdesc[i + 1];
rdesc[i + 1] = tmp;
}
+ return rdesc;
}
static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 850d02a7a925..fd5b390fff56 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -570,6 +570,8 @@ void hid_debug_event(struct hid_device *hdev, char *buf)
buf[i];
list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
}
+
+ wake_up_interruptible(&hdev->debug_wait);
}
EXPORT_SYMBOL_GPL(hid_debug_event);
@@ -1051,6 +1053,7 @@ static const struct file_operations hid_debug_events_fops = {
.read = hid_debug_events_read,
.poll = hid_debug_events_poll,
.release = hid_debug_events_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 7a40878f46b4..6e31f305397d 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -20,14 +20,15 @@
#include "hid-ids.h"
-static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
+ if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
dev_info(&hdev->dev, "Fixing up Elecom BM084 "
"report descriptor.\n");
rdesc[47] = 0x00;
}
+ return rdesc;
}
static const struct hid_device_id elecom_devices[] = {
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 85c6d13c9ffa..fe6cd8eeca34 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -63,6 +63,7 @@
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
@@ -105,6 +106,7 @@
#define USB_VENDOR_ID_ASUS 0x0486
#define USB_DEVICE_ID_ASUS_T91MT 0x0185
+#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186
#define USB_VENDOR_ID_ASUSTEK 0x0b05
#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726
@@ -128,6 +130,7 @@
#define USB_VENDOR_ID_BTC 0x046e
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
+#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
#define USB_VENDOR_ID_CANDO 0x2087
#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
@@ -149,6 +152,7 @@
#define USB_VENDOR_ID_CHICONY 0x04f2
#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
+#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
#define USB_VENDOR_ID_CIDC 0x1677
@@ -292,6 +296,10 @@
#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
+#define USB_VENDOR_ID_HANWANG 0x0b57
+#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
+#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
+
#define USB_VENDOR_ID_HAPP 0x078b
#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
#define USB_DEVICE_ID_UGCI_FLYING 0x0020
@@ -459,6 +467,8 @@
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
+#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
+#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
@@ -507,6 +517,9 @@
#define USB_VENDOR_ID_UCLOGIC 0x5543
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
+#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
#define USB_VENDOR_ID_VERNIER 0x08f7
#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
@@ -518,6 +531,11 @@
#define USB_VENDOR_ID_WACOM 0x056a
#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
+#define USB_VENDOR_ID_WALTOP 0x172f
+#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032
+#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501
+#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500
+
#define USB_VENDOR_ID_WISEGROUP 0x0925
#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6c03dcc5760a..243d5c532bf7 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -68,39 +68,49 @@ static const struct {
#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
&max, EV_KEY, (c))
-static inline int match_scancode(unsigned int code, unsigned int scancode)
+static bool match_scancode(struct hid_usage *usage,
+ unsigned int cur_idx, unsigned int scancode)
{
- if (scancode == 0)
- return 1;
-
- return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
+ return (usage->hid & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
}
-static inline int match_keycode(unsigned int code, unsigned int keycode)
+static bool match_keycode(struct hid_usage *usage,
+ unsigned int cur_idx, unsigned int keycode)
{
- if (keycode == 0)
- return 1;
+ return usage->code == keycode;
+}
- return code == keycode;
+static bool match_index(struct hid_usage *usage,
+ unsigned int cur_idx, unsigned int idx)
+{
+ return cur_idx == idx;
}
+typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
+ unsigned int cur_idx, unsigned int val);
+
static struct hid_usage *hidinput_find_key(struct hid_device *hid,
- unsigned int scancode,
- unsigned int keycode)
+ hid_usage_cmp_t match,
+ unsigned int value,
+ unsigned int *usage_idx)
{
- int i, j, k;
+ unsigned int i, j, k, cur_idx = 0;
struct hid_report *report;
struct hid_usage *usage;
for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
for (i = 0; i < report->maxfield; i++) {
- for ( j = 0; j < report->field[i]->maxusage; j++) {
+ for (j = 0; j < report->field[i]->maxusage; j++) {
usage = report->field[i]->usage + j;
- if (usage->type == EV_KEY &&
- match_scancode(usage->hid, scancode) &&
- match_keycode(usage->code, keycode))
- return usage;
+ if (usage->type == EV_KEY) {
+ if (match(usage, cur_idx, value)) {
+ if (usage_idx)
+ *usage_idx = cur_idx;
+ return usage;
+ }
+ cur_idx++;
+ }
}
}
}
@@ -108,39 +118,66 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
return NULL;
}
+static struct hid_usage *hidinput_locate_usage(struct hid_device *hid,
+ const struct input_keymap_entry *ke,
+ unsigned int *index)
+{
+ struct hid_usage *usage;
+ unsigned int scancode;
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX)
+ usage = hidinput_find_key(hid, match_index, ke->index, index);
+ else if (input_scancode_to_scalar(ke, &scancode) == 0)
+ usage = hidinput_find_key(hid, match_scancode, scancode, index);
+ else
+ usage = NULL;
+
+ return usage;
+}
+
static int hidinput_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
+ struct input_keymap_entry *ke)
{
struct hid_device *hid = input_get_drvdata(dev);
struct hid_usage *usage;
+ unsigned int scancode, index;
- usage = hidinput_find_key(hid, scancode, 0);
+ usage = hidinput_locate_usage(hid, ke, &index);
if (usage) {
- *keycode = usage->code;
+ ke->keycode = usage->code;
+ ke->index = index;
+ scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
+ ke->len = sizeof(scancode);
+ memcpy(ke->scancode, &scancode, sizeof(scancode));
return 0;
}
+
return -EINVAL;
}
static int hidinput_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
{
struct hid_device *hid = input_get_drvdata(dev);
struct hid_usage *usage;
- int old_keycode;
- usage = hidinput_find_key(hid, scancode, 0);
+ usage = hidinput_locate_usage(hid, ke, NULL);
if (usage) {
- old_keycode = usage->code;
- usage->code = keycode;
+ *old_keycode = usage->code;
+ usage->code = ke->keycode;
- clear_bit(old_keycode, dev->keybit);
+ clear_bit(*old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
- dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
- /* Set the keybit for the old keycode if the old keycode is used
- * by another key */
- if (hidinput_find_key (hid, 0, old_keycode))
- set_bit(old_keycode, dev->keybit);
+ dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
+ usage->code, usage->hid);
+
+ /*
+ * Set the keybit for the old keycode if the old keycode is used
+ * by another key
+ */
+ if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL))
+ set_bit(*old_keycode, dev->keybit);
return 0;
}
@@ -336,6 +373,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
map_key_clear(BTN_STYLUS);
break;
+ case 0x46: /* TabletPick */
+ map_key_clear(BTN_STYLUS2);
+ break;
+
default: goto unknown;
}
break;
@@ -748,8 +789,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
hid->ll_driver->hidinput_input_event;
input_dev->open = hidinput_open;
input_dev->close = hidinput_close;
- input_dev->setkeycode = hidinput_setkeycode;
- input_dev->getkeycode = hidinput_getkeycode;
+ input_dev->setkeycode_new = hidinput_setkeycode;
+ input_dev->getkeycode_new = hidinput_getkeycode;
input_dev->name = hid->name;
input_dev->phys = hid->phys;
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index f8871712b7b5..817247ee006c 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -23,10 +23,10 @@
* - report size 8 count 1 must be size 1 count 8 for button bitfield
* - change the button usage range to 4-7 for the extra buttons
*/
-static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 74 &&
+ if (*rsize >= 74 &&
rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
@@ -40,6 +40,7 @@ static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[72] = 0x01;
rdesc[74] = 0x08;
}
+ return rdesc;
}
static const struct hid_device_id kye_devices[] = {
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index f6433d8050a9..68c0b68856c7 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -41,25 +41,26 @@
* above the logical maximum described in descriptor. This extends
* the original value of 0x28c of logical maximum to 0x104d
*/
-static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 &&
+ if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
rdesc[84] == 0x8c && rdesc[85] == 0x02) {
dev_info(&hdev->dev, "fixing up Logitech keyboard report "
"descriptor\n");
rdesc[84] = rdesc[89] = 0x4d;
rdesc[85] = rdesc[90] = 0x10;
}
- if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
+ if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
rdesc[49] == 0x81 && rdesc[50] == 0x06) {
dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
"report descriptor\n");
rdesc[33] = rdesc[50] = 0x02;
}
+ return rdesc;
}
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 319b0e57ee41..8791a084693e 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -2,6 +2,7 @@
* Apple "Magic" Wireless Mouse driver
*
* Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
+ * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
*/
/*
@@ -53,7 +54,9 @@ static bool report_undeciphered;
module_param(report_undeciphered, bool, 0644);
MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
-#define TOUCH_REPORT_ID 0x29
+#define TRACKPAD_REPORT_ID 0x28
+#define MOUSE_REPORT_ID 0x29
+#define DOUBLE_REPORT_ID 0xf7
/* These definitions are not precise, but they're close enough. (Bits
* 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
* to be some kind of bit mask -- 0x20 may be a near-field reading,
@@ -67,15 +70,19 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define SCROLL_ACCEL_DEFAULT 7
+/* Single touch emulation should only begin when no touches are currently down.
+ * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
+ * are down and the touch providing for single touch emulation is lifted,
+ * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
+ * occuring, single_touch_id corresponds with the tracking id of the touch used.
+ */
+#define NO_TOUCHES -1
+#define SINGLE_TOUCH_UP -2
+
/**
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
* @input: Input device through which we report events.
* @quirks: Currently unused.
- * @last_timestamp: Timestamp from most recent (18-bit) touch report
- * (units of milliseconds over short windows, but seems to
- * increase faster when there are no touches).
- * @delta_time: 18-bit difference between the two most recent touch
- * reports from the mouse.
* @ntouches: Number of touches in most recent touch report.
* @scroll_accel: Number of consecutive scroll motions.
* @scroll_jiffies: Time of last scroll motion.
@@ -86,8 +93,6 @@ struct magicmouse_sc {
struct input_dev *input;
unsigned long quirks;
- int last_timestamp;
- int delta_time;
int ntouches;
int scroll_accel;
unsigned long scroll_jiffies;
@@ -98,9 +103,9 @@ struct magicmouse_sc {
short scroll_x;
short scroll_y;
u8 size;
- u8 down;
} touches[16];
int tracking_ids[16];
+ int single_touch_id;
};
static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -166,18 +171,35 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
{
struct input_dev *input = msc->input;
- __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24;
- int misc = tdata[5] | tdata[6] << 8;
- int id = (misc >> 6) & 15;
- int x = x_y << 12 >> 20;
- int y = -(x_y >> 20);
- int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE;
+ int id, x, y, size, orientation, touch_major, touch_minor, state, down;
+
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+ id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
+ x = (tdata[1] << 28 | tdata[0] << 20) >> 20;
+ y = -((tdata[2] << 24 | tdata[1] << 16) >> 20);
+ size = tdata[5] & 0x3f;
+ orientation = (tdata[6] >> 2) - 32;
+ touch_major = tdata[3];
+ touch_minor = tdata[4];
+ state = tdata[7] & TOUCH_STATE_MASK;
+ down = state != TOUCH_STATE_NONE;
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
+ x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
+ y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
+ size = tdata[6] & 0x3f;
+ orientation = (tdata[7] >> 2) - 32;
+ touch_major = tdata[4];
+ touch_minor = tdata[5];
+ state = tdata[8] & TOUCH_STATE_MASK;
+ down = state != TOUCH_STATE_NONE;
+ }
/* Store tracking ID and other fields. */
msc->tracking_ids[raw_id] = id;
msc->touches[id].x = x;
msc->touches[id].y = y;
- msc->touches[id].size = misc & 63;
+ msc->touches[id].size = size;
/* If requested, emulate a scroll wheel by detecting small
* vertical touch motions.
@@ -188,7 +210,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
int step_y = msc->touches[id].scroll_y - y;
/* Calculate and apply the scroll motion. */
- switch (tdata[7] & TOUCH_STATE_MASK) {
+ switch (state) {
case TOUCH_STATE_START:
msc->touches[id].scroll_x = x;
msc->touches[id].scroll_y = y;
@@ -222,21 +244,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
}
}
+ if (down) {
+ msc->ntouches++;
+ if (msc->single_touch_id == NO_TOUCHES)
+ msc->single_touch_id = id;
+ } else if (msc->single_touch_id == id)
+ msc->single_touch_id = SINGLE_TOUCH_UP;
+
/* Generate the input events for this touch. */
if (report_touches && down) {
- int orientation = (misc >> 10) - 32;
-
- msc->touches[id].down = 1;
-
input_report_abs(input, ABS_MT_TRACKING_ID, id);
- input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
- input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major);
+ input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor);
input_report_abs(input, ABS_MT_ORIENTATION, orientation);
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
- if (report_undeciphered)
- input_event(input, EV_MSC, MSC_RAW, tdata[7]);
+ if (report_undeciphered) {
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
+ input_event(input, EV_MSC, MSC_RAW, tdata[7]);
+ else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ input_event(input, EV_MSC, MSC_RAW, tdata[8]);
+ }
input_mt_sync(input);
}
@@ -247,7 +276,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
struct input_dev *input = msc->input;
- int x, y, ts, ii, clicks, last_up;
+ int x = 0, y = 0, ii, clicks = 0, npoints;
switch (data[0]) {
case 0x10:
@@ -257,29 +286,40 @@ static int magicmouse_raw_event(struct hid_device *hdev,
y = (__s16)(data[4] | data[5] << 8);
clicks = data[1];
break;
- case TOUCH_REPORT_ID:
+ case TRACKPAD_REPORT_ID:
+ /* Expect four bytes of prefix, and N*9 bytes of touch data. */
+ if (size < 4 || ((size - 4) % 9) != 0)
+ return 0;
+ npoints = (size - 4) / 9;
+ msc->ntouches = 0;
+ for (ii = 0; ii < npoints; ii++)
+ magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
+
+ /* We don't need an MT sync here because trackpad emits a
+ * BTN_TOUCH event in a new frame when all touches are released.
+ */
+ if (msc->ntouches == 0)
+ msc->single_touch_id = NO_TOUCHES;
+
+ clicks = data[1];
+
+ /* The following bits provide a device specific timestamp. They
+ * are unused here.
+ *
+ * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
+ */
+ break;
+ case MOUSE_REPORT_ID:
/* Expect six bytes of prefix, and N*8 bytes of touch data. */
if (size < 6 || ((size - 6) % 8) != 0)
return 0;
- ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
- msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff;
- msc->last_timestamp = ts;
- msc->ntouches = (size - 6) / 8;
- for (ii = 0; ii < msc->ntouches; ii++)
+ npoints = (size - 6) / 8;
+ msc->ntouches = 0;
+ for (ii = 0; ii < npoints; ii++)
magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
- if (report_touches) {
- last_up = 1;
- for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) {
- if (msc->touches[ii].down) {
- last_up = 0;
- msc->touches[ii].down = 0;
- }
- }
- if (last_up) {
- input_mt_sync(input);
- }
- }
+ if (report_touches && msc->ntouches == 0)
+ input_mt_sync(input);
/* When emulating three-button mode, it is important
* to have the current touch information before
@@ -288,6 +328,20 @@ static int magicmouse_raw_event(struct hid_device *hdev,
x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
clicks = data[3];
+
+ /* The following bits provide a device specific timestamp. They
+ * are unused here.
+ *
+ * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
+ */
+ break;
+ case DOUBLE_REPORT_ID:
+ /* Sometimes the trackpad sends two touch reports in one
+ * packet.
+ */
+ magicmouse_raw_event(hdev, report, data + 2, data[1]);
+ magicmouse_raw_event(hdev, report, data + 2 + data[1],
+ size - 2 - data[1]);
break;
case 0x20: /* Theoretically battery status (0-100), but I have
* never seen it -- maybe it is only upon request.
@@ -300,9 +354,25 @@ static int magicmouse_raw_event(struct hid_device *hdev,
return 0;
}
- magicmouse_emit_buttons(msc, clicks & 3);
- input_report_rel(input, REL_X, x);
- input_report_rel(input, REL_Y, y);
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+ magicmouse_emit_buttons(msc, clicks & 3);
+ input_report_rel(input, REL_X, x);
+ input_report_rel(input, REL_Y, y);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ input_report_key(input, BTN_MOUSE, clicks & 1);
+ input_report_key(input, BTN_TOUCH, msc->ntouches > 0);
+ input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
+ input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
+ input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
+ input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
+ if (msc->single_touch_id >= 0) {
+ input_report_abs(input, ABS_X,
+ msc->touches[msc->single_touch_id].x);
+ input_report_abs(input, ABS_Y,
+ msc->touches[msc->single_touch_id].y);
+ }
+ }
+
input_sync(input);
return 1;
}
@@ -338,18 +408,27 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
input->dev.parent = hdev->dev.parent;
__set_bit(EV_KEY, input->evbit);
- __set_bit(BTN_LEFT, input->keybit);
- __set_bit(BTN_RIGHT, input->keybit);
- if (emulate_3button)
- __set_bit(BTN_MIDDLE, input->keybit);
- __set_bit(BTN_TOOL_FINGER, input->keybit);
-
- __set_bit(EV_REL, input->evbit);
- __set_bit(REL_X, input->relbit);
- __set_bit(REL_Y, input->relbit);
- if (emulate_scroll_wheel) {
- __set_bit(REL_WHEEL, input->relbit);
- __set_bit(REL_HWHEEL, input->relbit);
+
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+ __set_bit(BTN_LEFT, input->keybit);
+ __set_bit(BTN_RIGHT, input->keybit);
+ if (emulate_3button)
+ __set_bit(BTN_MIDDLE, input->keybit);
+
+ __set_bit(EV_REL, input->evbit);
+ __set_bit(REL_X, input->relbit);
+ __set_bit(REL_Y, input->relbit);
+ if (emulate_scroll_wheel) {
+ __set_bit(REL_WHEEL, input->relbit);
+ __set_bit(REL_HWHEEL, input->relbit);
+ }
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ __set_bit(BTN_MOUSE, input->keybit);
+ __set_bit(BTN_TOOL_FINGER, input->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
+ __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
+ __set_bit(BTN_TOOL_QUADTAP, input->keybit);
+ __set_bit(BTN_TOUCH, input->keybit);
}
if (report_touches) {
@@ -359,16 +438,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0);
- input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358,
- 4, 0);
+
/* Note: Touch Y position from the device is inverted relative
* to how pointer motion is reported (and relative to how USB
* HID recommends the coordinates work). This driver keeps
* the origin at the same position, and just uses the additive
* inverse of the reported Y.
*/
- input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047,
- 4, 0);
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+ input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
+ 1358, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
+ 2047, 4, 0);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
+ input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
+ 3167, 4, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
+ 2565, 4, 0);
+ }
}
if (report_undeciphered) {
@@ -380,8 +469,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
static int magicmouse_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
- __u8 feature_1[] = { 0xd7, 0x01 };
- __u8 feature_2[] = { 0xf8, 0x01, 0x32 };
+ __u8 feature[] = { 0xd7, 0x01 };
struct input_dev *input;
struct magicmouse_sc *msc;
struct hid_report *report;
@@ -398,6 +486,8 @@ static int magicmouse_probe(struct hid_device *hdev,
msc->quirks = id->driver_data;
hid_set_drvdata(hdev, msc);
+ msc->single_touch_id = NO_TOUCHES;
+
ret = hid_parse(hdev);
if (ret) {
dev_err(&hdev->dev, "magicmouse hid parse failed\n");
@@ -413,7 +503,16 @@ static int magicmouse_probe(struct hid_device *hdev,
/* we are handling the input ourselves */
hidinput_disconnect(hdev);
- report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID);
+ if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ MOUSE_REPORT_ID);
+ else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ TRACKPAD_REPORT_ID);
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ DOUBLE_REPORT_ID);
+ }
+
if (!report) {
dev_err(&hdev->dev, "unable to register touch report\n");
ret = -ENOMEM;
@@ -421,17 +520,10 @@ static int magicmouse_probe(struct hid_device *hdev,
}
report->size = 6;
- ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1),
+ ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
HID_FEATURE_REPORT);
- if (ret != sizeof(feature_1)) {
- dev_err(&hdev->dev, "unable to request touch data (1:%d)\n",
- ret);
- goto err_stop_hw;
- }
- ret = hdev->hid_output_raw_report(hdev, feature_2,
- sizeof(feature_2), HID_FEATURE_REPORT);
- if (ret != sizeof(feature_2)) {
- dev_err(&hdev->dev, "unable to request touch data (2:%d)\n",
+ if (ret != sizeof(feature)) {
+ dev_err(&hdev->dev, "unable to request touch data (%d)\n",
ret);
goto err_stop_hw;
}
@@ -471,8 +563,10 @@ static void magicmouse_remove(struct hid_device *hdev)
}
static const struct hid_device_id magic_mice[] = {
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE),
- .driver_data = 0 },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
{ }
};
MODULE_DEVICE_TABLE(hid, magic_mice);
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 359cc447c6c6..dc618c33d0a2 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -33,18 +33,19 @@
* 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,
- unsigned int rsize)
+static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if ((quirks & MS_RDESC) && rsize == 571 && 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[557] = 0x35;
rdesc[559] = 0x45;
}
+ return rdesc;
}
#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index 2cd05aa244b9..c95c31e2d869 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -22,14 +22,15 @@
#include "hid-ids.h"
-static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
+ if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
dev_info(&hdev->dev, "fixing up button/consumer in HID report "
"descriptor\n");
rdesc[30] = 0x0c;
}
+ return rdesc;
}
#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c
index e91437c18906..ac5421d568f1 100644
--- a/drivers/hid/hid-mosart.c
+++ b/drivers/hid/hid-mosart.c
@@ -239,6 +239,7 @@ static void mosart_remove(struct hid_device *hdev)
static const struct hid_device_id mosart_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
{ }
};
MODULE_DEVICE_TABLE(hid, mosart_devices);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index fb69b8c4953f..69169efa1e16 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -90,6 +90,55 @@ struct ntrig_data {
};
+/*
+ * This function converts the 4 byte raw firmware code into
+ * a string containing 5 comma separated numbers.
+ */
+static int ntrig_version_string(unsigned char *raw, char *buf)
+{
+ __u8 a = (raw[1] & 0x0e) >> 1;
+ __u8 b = (raw[0] & 0x3c) >> 2;
+ __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5);
+ __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5);
+ __u8 e = raw[2] & 0x07;
+
+ /*
+ * As yet unmapped bits:
+ * 0b11000000 0b11110001 0b00011000 0b00011000
+ */
+
+ return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
+}
+
+static void ntrig_report_version(struct hid_device *hdev)
+{
+ int ret;
+ char buf[20];
+ struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+ unsigned char *data = kmalloc(8, GFP_KERNEL);
+
+ if (!data)
+ goto err_free;
+
+ ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+ USB_DIR_IN,
+ 0x30c, 1, data, 8,
+ USB_CTRL_SET_TIMEOUT);
+
+ if (ret == 8) {
+ ret = ntrig_version_string(&data[2], buf);
+
+ dev_info(&hdev->dev,
+ "Firmware version: %s (%02x%02x %02x%02x)\n",
+ buf, data[2], data[3], data[4], data[5]);
+ }
+
+err_free:
+ kfree(data);
+}
+
static ssize_t show_phys_width(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -377,8 +426,8 @@ static struct attribute_group ntrig_attribute_group = {
*/
static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
{
struct ntrig_data *nd = hid_get_drvdata(hdev);
@@ -448,13 +497,13 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
/* width/height mapped on TouchMajor/TouchMinor/Orientation */
case HID_DG_WIDTH:
hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MAJOR);
+ EV_ABS, ABS_MT_TOUCH_MAJOR);
return 1;
case HID_DG_HEIGHT:
hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TOUCH_MINOR);
+ EV_ABS, ABS_MT_TOUCH_MINOR);
input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
- 0, 1, 0, 0);
+ 0, 1, 0, 0);
return 1;
}
return 0;
@@ -468,8 +517,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
}
static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
{
/* No special mappings needed for the pen and single touch */
if (field->physical)
@@ -489,7 +538,7 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
* and call input_mt_sync after each point if necessary
*/
static int ntrig_event (struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
+ struct hid_usage *usage, __s32 value)
{
struct input_dev *input = field->hidinput->input;
struct ntrig_data *nd = hid_get_drvdata(hid);
@@ -848,6 +897,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (report)
usbhid_submit_report(hdev, report, USB_DIR_OUT);
+ ntrig_report_version(hdev);
+
ret = sysfs_create_group(&hdev->dev.kobj,
&ntrig_attribute_group);
@@ -860,7 +911,7 @@ err_free:
static void ntrig_remove(struct hid_device *hdev)
{
sysfs_remove_group(&hdev->dev.kobj,
- &ntrig_attribute_group);
+ &ntrig_attribute_group);
hid_hw_stop(hdev);
kfree(hid_get_drvdata(hdev));
}
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c
index aa9a960f73a4..2e79716dca31 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -19,14 +19,15 @@
#include "hid-ids.h"
-static void ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
+ if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 "
"report descriptor.\n");
rdesc[55] = 0x92;
}
+ return rdesc;
}
static const struct hid_device_id ortek_devices[] = {
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 500fbd0652dc..308d6ae48a3e 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -23,10 +23,10 @@
#include "hid-ids.h"
/* Petalynx Maxter Remote has maximum for consumer page set too low */
-static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
+ if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report "
@@ -34,6 +34,7 @@ static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[60] = 0xfa;
rdesc[40] = 0xfa;
}
+ return rdesc;
}
#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 845f428b8090..48eab84f53b5 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -740,10 +740,10 @@ int pcmidi_snd_terminate(struct pcmidi_snd *pm)
/*
* PC-MIDI report descriptor for report id is wrong.
*/
-static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize == 178 &&
+ if (*rsize == 178 &&
rdesc[111] == 0x06 && rdesc[112] == 0x00 &&
rdesc[113] == 0xff) {
dev_info(&hdev->dev, "fixing up pc-midi keyboard report "
@@ -751,6 +751,7 @@ static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[144] = 0x18; /* report 4: was 0x10 report count */
}
+ return rdesc;
}
static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
new file mode 100644
index 000000000000..9bf23047892a
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -0,0 +1,968 @@
+/*
+ * Roccat Pyra driver for Linux
+ *
+ * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/*
+ * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
+ * variant. Wireless variant is not tested.
+ * Userland tools can be found at http://sourceforge.net/projects/roccat
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/usb.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "hid-ids.h"
+#include "hid-roccat.h"
+#include "hid-roccat-pyra.h"
+
+static void profile_activated(struct pyra_device *pyra,
+ unsigned int new_profile)
+{
+ pyra->actual_profile = new_profile;
+ pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
+}
+
+static int pyra_send_control(struct usb_device *usb_dev, int value,
+ enum pyra_control_requests request)
+{
+ int len;
+ struct pyra_control control;
+
+ if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
+ request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
+ (value < 0 || value > 4))
+ return -EINVAL;
+
+ control.command = PYRA_COMMAND_CONTROL;
+ control.value = value;
+ control.request = request;
+
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
+ sizeof(struct pyra_control),
+ USB_CTRL_SET_TIMEOUT);
+
+ if (len != sizeof(struct pyra_control))
+ return len;
+
+ return 0;
+}
+
+static int pyra_receive_control_status(struct usb_device *usb_dev)
+{
+ int len;
+ struct pyra_control control;
+
+ do {
+ msleep(10);
+
+ len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+ USB_DIR_IN,
+ PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
+ sizeof(struct pyra_control),
+ USB_CTRL_SET_TIMEOUT);
+
+ /* requested too early, try again */
+ } while (len == -EPROTO);
+
+ if (len == sizeof(struct pyra_control) &&
+ control.command == PYRA_COMMAND_CONTROL &&
+ control.request == PYRA_CONTROL_REQUEST_STATUS &&
+ control.value == 1)
+ return 0;
+ else {
+ dev_err(&usb_dev->dev, "receive control status: "
+ "unknown response 0x%x 0x%x\n",
+ control.request, control.value);
+ return -EINVAL;
+ }
+}
+
+static int pyra_get_profile_settings(struct usb_device *usb_dev,
+ struct pyra_profile_settings *buf, int number)
+{
+ int retval;
+
+ retval = pyra_send_control(usb_dev, number,
+ PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
+
+ if (retval)
+ return retval;
+
+ retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
+ sizeof(struct pyra_profile_settings),
+ USB_CTRL_SET_TIMEOUT);
+
+ if (retval != sizeof(struct pyra_profile_settings))
+ return retval;
+
+ return 0;
+}
+
+static int pyra_get_profile_buttons(struct usb_device *usb_dev,
+ struct pyra_profile_buttons *buf, int number)
+{
+ int retval;
+
+ retval = pyra_send_control(usb_dev, number,
+ PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
+
+ if (retval)
+ return retval;
+
+ retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
+ sizeof(struct pyra_profile_buttons),
+ USB_CTRL_SET_TIMEOUT);
+
+ if (retval != sizeof(struct pyra_profile_buttons))
+ return retval;
+
+ return 0;
+}
+
+static int pyra_get_settings(struct usb_device *usb_dev,
+ struct pyra_settings *buf)
+{
+ int len;
+ len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ PYRA_USB_COMMAND_SETTINGS, 0, buf,
+ sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
+ if (len != sizeof(struct pyra_settings))
+ return -EIO;
+ return 0;
+}
+
+static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
+{
+ int len;
+ len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+ PYRA_USB_COMMAND_INFO, 0, buf,
+ sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT);
+ if (len != sizeof(struct pyra_info))
+ return -EIO;
+ return 0;
+}
+
+static int pyra_set_profile_settings(struct usb_device *usb_dev,
+ struct pyra_profile_settings const *settings)
+{
+ int len;
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
+ sizeof(struct pyra_profile_settings),
+ USB_CTRL_SET_TIMEOUT);
+ if (len != sizeof(struct pyra_profile_settings))
+ return -EIO;
+ if (pyra_receive_control_status(usb_dev))
+ return -EIO;
+ return 0;
+}
+
+static int pyra_set_profile_buttons(struct usb_device *usb_dev,
+ struct pyra_profile_buttons const *buttons)
+{
+ int len;
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
+ sizeof(struct pyra_profile_buttons),
+ USB_CTRL_SET_TIMEOUT);
+ if (len != sizeof(struct pyra_profile_buttons))
+ return -EIO;
+ if (pyra_receive_control_status(usb_dev))
+ return -EIO;
+ return 0;
+}
+
+static int pyra_set_settings(struct usb_device *usb_dev,
+ struct pyra_settings const *settings)
+{
+ int len;
+ len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings,
+ sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
+ if (len != sizeof(struct pyra_settings))
+ return -EIO;
+ if (pyra_receive_control_status(usb_dev))
+ return -EIO;
+ return 0;
+}
+
+static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count, int number)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+
+ if (off >= sizeof(struct pyra_profile_settings))
+ return 0;
+
+ if (off + count > sizeof(struct pyra_profile_settings))
+ count = sizeof(struct pyra_profile_settings) - off;
+
+ mutex_lock(&pyra->pyra_lock);
+ memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off,
+ count);
+ mutex_unlock(&pyra->pyra_lock);
+
+ return count;
+}
+
+static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_settings(fp, kobj,
+ attr, buf, off, count, 0);
+}
+
+static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_settings(fp, kobj,
+ attr, buf, off, count, 1);
+}
+
+static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_settings(fp, kobj,
+ attr, buf, off, count, 2);
+}
+
+static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_settings(fp, kobj,
+ attr, buf, off, count, 3);
+}
+
+static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_settings(fp, kobj,
+ attr, buf, off, count, 4);
+}
+
+static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count, int number)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+
+ if (off >= sizeof(struct pyra_profile_buttons))
+ return 0;
+
+ if (off + count > sizeof(struct pyra_profile_buttons))
+ count = sizeof(struct pyra_profile_buttons) - off;
+
+ mutex_lock(&pyra->pyra_lock);
+ memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off,
+ count);
+ mutex_unlock(&pyra->pyra_lock);
+
+ return count;
+}
+
+static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_buttons(fp, kobj,
+ attr, buf, off, count, 0);
+}
+
+static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_buttons(fp, kobj,
+ attr, buf, off, count, 1);
+}
+
+static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_buttons(fp, kobj,
+ attr, buf, off, count, 2);
+}
+
+static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_buttons(fp, kobj,
+ attr, buf, off, count, 3);
+}
+
+static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ return pyra_sysfs_read_profilex_buttons(fp, kobj,
+ attr, buf, off, count, 4);
+}
+
+static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval = 0;
+ int difference;
+ int profile_number;
+ struct pyra_profile_settings *profile_settings;
+
+ if (off != 0 || count != sizeof(struct pyra_profile_settings))
+ return -EINVAL;
+
+ profile_number = ((struct pyra_profile_settings const *)buf)->number;
+ profile_settings = &pyra->profile_settings[profile_number];
+
+ mutex_lock(&pyra->pyra_lock);
+ difference = memcmp(buf, profile_settings,
+ sizeof(struct pyra_profile_settings));
+ if (difference) {
+ retval = pyra_set_profile_settings(usb_dev,
+ (struct pyra_profile_settings const *)buf);
+ if (!retval)
+ memcpy(profile_settings, buf,
+ sizeof(struct pyra_profile_settings));
+ }
+ mutex_unlock(&pyra->pyra_lock);
+
+ if (retval)
+ return retval;
+
+ return sizeof(struct pyra_profile_settings);
+}
+
+static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval = 0;
+ int difference;
+ int profile_number;
+ struct pyra_profile_buttons *profile_buttons;
+
+ if (off != 0 || count != sizeof(struct pyra_profile_buttons))
+ return -EINVAL;
+
+ profile_number = ((struct pyra_profile_buttons const *)buf)->number;
+ profile_buttons = &pyra->profile_buttons[profile_number];
+
+ mutex_lock(&pyra->pyra_lock);
+ difference = memcmp(buf, profile_buttons,
+ sizeof(struct pyra_profile_buttons));
+ if (difference) {
+ retval = pyra_set_profile_buttons(usb_dev,
+ (struct pyra_profile_buttons const *)buf);
+ if (!retval)
+ memcpy(profile_buttons, buf,
+ sizeof(struct pyra_profile_buttons));
+ }
+ mutex_unlock(&pyra->pyra_lock);
+
+ if (retval)
+ return retval;
+
+ return sizeof(struct pyra_profile_buttons);
+}
+
+static ssize_t pyra_sysfs_read_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+
+ if (off >= sizeof(struct pyra_settings))
+ return 0;
+
+ if (off + count > sizeof(struct pyra_settings))
+ count = sizeof(struct pyra_settings) - off;
+
+ mutex_lock(&pyra->pyra_lock);
+ memcpy(buf, ((char const *)&pyra->settings) + off, count);
+ mutex_unlock(&pyra->pyra_lock);
+
+ return count;
+}
+
+static ssize_t pyra_sysfs_write_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+ int retval = 0;
+ int difference;
+
+ if (off != 0 || count != sizeof(struct pyra_settings))
+ return -EINVAL;
+
+ mutex_lock(&pyra->pyra_lock);
+ difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
+ if (difference) {
+ retval = pyra_set_settings(usb_dev,
+ (struct pyra_settings const *)buf);
+ if (!retval)
+ memcpy(&pyra->settings, buf,
+ sizeof(struct pyra_settings));
+ }
+ mutex_unlock(&pyra->pyra_lock);
+
+ if (retval)
+ return retval;
+
+ profile_activated(pyra, pyra->settings.startup_profile);
+
+ return sizeof(struct pyra_settings);
+}
+
+
+static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
+}
+
+static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
+}
+
+static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
+}
+
+static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+ return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
+}
+
+static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
+
+static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
+
+static DEVICE_ATTR(firmware_version, 0440,
+ pyra_sysfs_show_firmware_version, NULL);
+
+static DEVICE_ATTR(startup_profile, 0440,
+ pyra_sysfs_show_startup_profile, NULL);
+
+static struct attribute *pyra_attributes[] = {
+ &dev_attr_actual_cpi.attr,
+ &dev_attr_actual_profile.attr,
+ &dev_attr_firmware_version.attr,
+ &dev_attr_startup_profile.attr,
+ NULL
+};
+
+static struct attribute_group pyra_attribute_group = {
+ .attrs = pyra_attributes
+};
+
+static struct bin_attribute pyra_profile_settings_attr = {
+ .attr = { .name = "profile_settings", .mode = 0220 },
+ .size = sizeof(struct pyra_profile_settings),
+ .write = pyra_sysfs_write_profile_settings
+};
+
+static struct bin_attribute pyra_profile1_settings_attr = {
+ .attr = { .name = "profile1_settings", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_settings),
+ .read = pyra_sysfs_read_profile1_settings
+};
+
+static struct bin_attribute pyra_profile2_settings_attr = {
+ .attr = { .name = "profile2_settings", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_settings),
+ .read = pyra_sysfs_read_profile2_settings
+};
+
+static struct bin_attribute pyra_profile3_settings_attr = {
+ .attr = { .name = "profile3_settings", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_settings),
+ .read = pyra_sysfs_read_profile3_settings
+};
+
+static struct bin_attribute pyra_profile4_settings_attr = {
+ .attr = { .name = "profile4_settings", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_settings),
+ .read = pyra_sysfs_read_profile4_settings
+};
+
+static struct bin_attribute pyra_profile5_settings_attr = {
+ .attr = { .name = "profile5_settings", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_settings),
+ .read = pyra_sysfs_read_profile5_settings
+};
+
+static struct bin_attribute pyra_profile_buttons_attr = {
+ .attr = { .name = "profile_buttons", .mode = 0220 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .write = pyra_sysfs_write_profile_buttons
+};
+
+static struct bin_attribute pyra_profile1_buttons_attr = {
+ .attr = { .name = "profile1_buttons", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .read = pyra_sysfs_read_profile1_buttons
+};
+
+static struct bin_attribute pyra_profile2_buttons_attr = {
+ .attr = { .name = "profile2_buttons", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .read = pyra_sysfs_read_profile2_buttons
+};
+
+static struct bin_attribute pyra_profile3_buttons_attr = {
+ .attr = { .name = "profile3_buttons", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .read = pyra_sysfs_read_profile3_buttons
+};
+
+static struct bin_attribute pyra_profile4_buttons_attr = {
+ .attr = { .name = "profile4_buttons", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .read = pyra_sysfs_read_profile4_buttons
+};
+
+static struct bin_attribute pyra_profile5_buttons_attr = {
+ .attr = { .name = "profile5_buttons", .mode = 0440 },
+ .size = sizeof(struct pyra_profile_buttons),
+ .read = pyra_sysfs_read_profile5_buttons
+};
+
+static struct bin_attribute pyra_settings_attr = {
+ .attr = { .name = "settings", .mode = 0660 },
+ .size = sizeof(struct pyra_settings),
+ .read = pyra_sysfs_read_settings,
+ .write = pyra_sysfs_write_settings
+};
+
+static int pyra_create_sysfs_attributes(struct usb_interface *intf)
+{
+ int retval;
+
+ retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
+ if (retval)
+ goto exit_1;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile_settings_attr);
+ if (retval)
+ goto exit_2;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile1_settings_attr);
+ if (retval)
+ goto exit_3;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile2_settings_attr);
+ if (retval)
+ goto exit_4;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile3_settings_attr);
+ if (retval)
+ goto exit_5;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile4_settings_attr);
+ if (retval)
+ goto exit_6;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile5_settings_attr);
+ if (retval)
+ goto exit_7;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile_buttons_attr);
+ if (retval)
+ goto exit_8;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile1_buttons_attr);
+ if (retval)
+ goto exit_9;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile2_buttons_attr);
+ if (retval)
+ goto exit_10;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile3_buttons_attr);
+ if (retval)
+ goto exit_11;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile4_buttons_attr);
+ if (retval)
+ goto exit_12;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_profile5_buttons_attr);
+ if (retval)
+ goto exit_13;
+
+ retval = sysfs_create_bin_file(&intf->dev.kobj,
+ &pyra_settings_attr);
+ if (retval)
+ goto exit_14;
+
+ return 0;
+
+exit_14:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
+exit_13:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
+exit_12:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
+exit_11:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
+exit_10:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
+exit_9:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
+exit_8:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
+exit_7:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
+exit_6:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
+exit_5:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
+exit_4:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
+exit_3:
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
+exit_2:
+ sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
+exit_1:
+ return retval;
+}
+
+static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
+{
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
+ sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
+ sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
+}
+
+static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
+ struct pyra_device *pyra)
+{
+ struct pyra_info *info;
+ int retval, i;
+
+ mutex_init(&pyra->pyra_lock);
+
+ info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ retval = pyra_get_info(usb_dev, info);
+ if (retval) {
+ kfree(info);
+ return retval;
+ }
+ pyra->firmware_version = info->firmware_version;
+ kfree(info);
+
+ retval = pyra_get_settings(usb_dev, &pyra->settings);
+ if (retval)
+ return retval;
+
+ for (i = 0; i < 5; ++i) {
+ retval = pyra_get_profile_settings(usb_dev,
+ &pyra->profile_settings[i], i);
+ if (retval)
+ return retval;
+
+ retval = pyra_get_profile_buttons(usb_dev,
+ &pyra->profile_buttons[i], i);
+ if (retval)
+ return retval;
+ }
+
+ profile_activated(pyra, pyra->settings.startup_profile);
+
+ return 0;
+}
+
+static int pyra_init_specials(struct hid_device *hdev)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct pyra_device *pyra;
+ int retval;
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ == USB_INTERFACE_PROTOCOL_MOUSE) {
+
+ pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
+ if (!pyra) {
+ dev_err(&hdev->dev, "can't alloc device descriptor\n");
+ return -ENOMEM;
+ }
+ hid_set_drvdata(hdev, pyra);
+
+ retval = pyra_init_pyra_device_struct(usb_dev, pyra);
+ if (retval) {
+ dev_err(&hdev->dev,
+ "couldn't init struct pyra_device\n");
+ goto exit_free;
+ }
+
+ retval = roccat_connect(hdev);
+ if (retval < 0) {
+ dev_err(&hdev->dev, "couldn't init char dev\n");
+ } else {
+ pyra->chrdev_minor = retval;
+ pyra->roccat_claimed = 1;
+ }
+
+ retval = pyra_create_sysfs_attributes(intf);
+ if (retval) {
+ dev_err(&hdev->dev, "cannot create sysfs files\n");
+ goto exit_free;
+ }
+ } else {
+ hid_set_drvdata(hdev, NULL);
+ }
+
+ return 0;
+exit_free:
+ kfree(pyra);
+ return retval;
+}
+
+static void pyra_remove_specials(struct hid_device *hdev)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct pyra_device *pyra;
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ == USB_INTERFACE_PROTOCOL_MOUSE) {
+ pyra_remove_sysfs_attributes(intf);
+ pyra = hid_get_drvdata(hdev);
+ if (pyra->roccat_claimed)
+ roccat_disconnect(pyra->chrdev_minor);
+ kfree(hid_get_drvdata(hdev));
+ }
+}
+
+static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int retval;
+
+ retval = hid_parse(hdev);
+ if (retval) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto exit;
+ }
+
+ retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (retval) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto exit;
+ }
+
+ retval = pyra_init_specials(hdev);
+ if (retval) {
+ dev_err(&hdev->dev, "couldn't install mouse\n");
+ goto exit_stop;
+ }
+ return 0;
+
+exit_stop:
+ hid_hw_stop(hdev);
+exit:
+ return retval;
+}
+
+static void pyra_remove(struct hid_device *hdev)
+{
+ pyra_remove_specials(hdev);
+ hid_hw_stop(hdev);
+}
+
+static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
+ u8 const *data)
+{
+ struct pyra_mouse_event_button const *button_event;
+
+ switch (data[0]) {
+ case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
+ button_event = (struct pyra_mouse_event_button const *)data;
+ switch (button_event->type) {
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
+ profile_activated(pyra, button_event->data1 - 1);
+ break;
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
+ pyra->actual_cpi = button_event->data1;
+ break;
+ }
+ break;
+ }
+}
+
+static void pyra_report_to_chrdev(struct pyra_device const *pyra,
+ u8 const *data)
+{
+ struct pyra_roccat_report roccat_report;
+ struct pyra_mouse_event_button const *button_event;
+
+ if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
+ return;
+
+ button_event = (struct pyra_mouse_event_button const *)data;
+
+ switch (button_event->type) {
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
+ roccat_report.type = button_event->type;
+ roccat_report.value = button_event->data1;
+ roccat_report.key = 0;
+ roccat_report_event(pyra->chrdev_minor,
+ (uint8_t const *)&roccat_report,
+ sizeof(struct pyra_roccat_report));
+ break;
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
+ case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
+ if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
+ roccat_report.type = button_event->type;
+ roccat_report.key = button_event->data1;
+ /*
+ * pyra reports profile numbers with range 1-5.
+ * Keeping this behaviour.
+ */
+ roccat_report.value = pyra->actual_profile + 1;
+ roccat_report_event(pyra->chrdev_minor,
+ (uint8_t const *)&roccat_report,
+ sizeof(struct pyra_roccat_report));
+ }
+ break;
+ }
+}
+
+static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
+ u8 *data, int size)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct pyra_device *pyra = hid_get_drvdata(hdev);
+
+ if (intf->cur_altsetting->desc.bInterfaceProtocol
+ != USB_INTERFACE_PROTOCOL_MOUSE)
+ return 0;
+
+ pyra_keep_values_up_to_date(pyra, data);
+
+ if (pyra->roccat_claimed)
+ pyra_report_to_chrdev(pyra, data);
+
+ return 0;
+}
+
+static const struct hid_device_id pyra_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
+ USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
+ /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */
+ { }
+};
+
+MODULE_DEVICE_TABLE(hid, pyra_devices);
+
+static struct hid_driver pyra_driver = {
+ .name = "pyra",
+ .id_table = pyra_devices,
+ .probe = pyra_probe,
+ .remove = pyra_remove,
+ .raw_event = pyra_raw_event
+};
+
+static int __init pyra_init(void)
+{
+ return hid_register_driver(&pyra_driver);
+}
+
+static void __exit pyra_exit(void)
+{
+ hid_unregister_driver(&pyra_driver);
+}
+
+module_init(pyra_init);
+module_exit(pyra_exit);
+
+MODULE_AUTHOR("Stefan Achatz");
+MODULE_DESCRIPTION("USB Roccat Pyra driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
new file mode 100644
index 000000000000..22f80a8f26f9
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -0,0 +1,186 @@
+#ifndef __HID_ROCCAT_PYRA_H
+#define __HID_ROCCAT_PYRA_H
+
+/*
+ * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/types.h>
+
+#pragma pack(push)
+#pragma pack(1)
+
+struct pyra_b {
+ uint8_t command; /* PYRA_COMMAND_B */
+ uint8_t size; /* always 3 */
+ uint8_t unknown; /* 1 */
+};
+
+struct pyra_control {
+ uint8_t command; /* PYRA_COMMAND_CONTROL */
+ /*
+ * value is profile number for request_settings and request_buttons
+ * 1 if status ok for request_status
+ */
+ uint8_t value; /* Range 0-4 */
+ uint8_t request;
+};
+
+enum pyra_control_requests {
+ PYRA_CONTROL_REQUEST_STATUS = 0x00,
+ PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
+ PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
+};
+
+struct pyra_settings {
+ uint8_t command; /* PYRA_COMMAND_SETTINGS */
+ uint8_t size; /* always 3 */
+ uint8_t startup_profile; /* Range 0-4! */
+};
+
+struct pyra_profile_settings {
+ uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
+ uint8_t size; /* always 0xd */
+ uint8_t number; /* Range 0-4 */
+ uint8_t xysync;
+ uint8_t x_sensitivity; /* 0x1-0xa */
+ uint8_t y_sensitivity;
+ uint8_t x_cpi; /* unused */
+ uint8_t y_cpi; /* this value is for x and y */
+ uint8_t lightswitch; /* 0 = off, 1 = on */
+ uint8_t light_effect;
+ uint8_t handedness;
+ uint16_t checksum; /* byte sum */
+};
+
+struct pyra_profile_buttons {
+ uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
+ uint8_t size; /* always 0x13 */
+ uint8_t number; /* Range 0-4 */
+ uint8_t buttons[14];
+ uint16_t checksum; /* byte sum */
+};
+
+struct pyra_info {
+ uint8_t command; /* PYRA_COMMAND_INFO */
+ uint8_t size; /* always 6 */
+ uint8_t firmware_version;
+ uint8_t unknown1; /* always 0 */
+ uint8_t unknown2; /* always 1 */
+ uint8_t unknown3; /* always 0 */
+};
+
+enum pyra_commands {
+ PYRA_COMMAND_CONTROL = 0x4,
+ PYRA_COMMAND_SETTINGS = 0x5,
+ PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
+ PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
+ PYRA_COMMAND_INFO = 0x9,
+ PYRA_COMMAND_B = 0xb
+};
+
+enum pyra_usb_commands {
+ PYRA_USB_COMMAND_CONTROL = 0x304,
+ PYRA_USB_COMMAND_SETTINGS = 0x305,
+ PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306,
+ PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307,
+ PYRA_USB_COMMAND_INFO = 0x309,
+ PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */
+};
+
+enum pyra_mouse_report_numbers {
+ PYRA_MOUSE_REPORT_NUMBER_HID = 1,
+ PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
+ PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3,
+};
+
+struct pyra_mouse_event_button {
+ uint8_t report_number; /* always 3 */
+ uint8_t unknown; /* always 0 */
+ uint8_t type;
+ uint8_t data1;
+ uint8_t data2;
+};
+
+struct pyra_mouse_event_audio {
+ uint8_t report_number; /* always 2 */
+ uint8_t type;
+ uint8_t unused; /* always 0 */
+};
+
+/* hid audio controls */
+enum pyra_mouse_event_audio_types {
+ PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2,
+ PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9,
+ PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea,
+};
+
+enum pyra_mouse_event_button_types {
+ /*
+ * Mouse sends tilt events on report_number 1 and 3
+ * Tilt events are sent repeatedly with 0.94s between first and second
+ * event and 0.22s on subsequent
+ */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10,
+
+ /*
+ * These are sent sequentially
+ * data1 contains new profile number in range 1-5
+ */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20,
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30,
+
+ /*
+ * data1 = button_number (rmp index)
+ * data2 = pressed/released
+ */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40,
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50,
+
+ /*
+ * data1 = button_number (rmp index)
+ */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
+
+ /* data1 = new cpi */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0,
+
+ /* data1 and data2 = new sensitivity */
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0,
+
+ PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
+};
+
+enum {
+ PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
+ PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
+};
+
+struct pyra_roccat_report {
+ uint8_t type;
+ uint8_t value;
+ uint8_t key;
+};
+
+#pragma pack(pop)
+
+struct pyra_device {
+ int actual_profile;
+ int actual_cpi;
+ int firmware_version;
+ int roccat_claimed;
+ int chrdev_minor;
+ struct mutex pyra_lock;
+ struct pyra_settings settings;
+ struct pyra_profile_settings profile_settings[5];
+ struct pyra_profile_buttons profile_buttons[5];
+};
+
+#endif
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index f6e80c7ca61e..96c46e31a62e 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -384,6 +384,7 @@ static const struct file_operations roccat_ops = {
.poll = roccat_poll,
.open = roccat_open,
.release = roccat_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static int __init roccat_init(void)
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index bda0fd60c98d..35894444e000 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -61,10 +61,10 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev,
"descriptor\n", rsize);
}
-static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
+ if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
rdesc[182] == 0x40) {
@@ -74,24 +74,25 @@ static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[180] = 0x06;
rdesc[182] = 0x42;
} else
- if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
+ if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
rdesc[194] == 0x25 && rdesc[195] == 0x12) {
samsung_irda_dev_trace(hdev, 203);
rdesc[193] = 0x1;
rdesc[195] = 0xf;
} else
- if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
+ if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
rdesc[126] == 0x25 && rdesc[127] == 0x11) {
samsung_irda_dev_trace(hdev, 135);
rdesc[125] = 0x1;
rdesc[127] = 0xe;
} else
- if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
+ if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
rdesc[162] == 0x25 && rdesc[163] == 0x01) {
samsung_irda_dev_trace(hdev, 171);
rdesc[161] = 0x1;
rdesc[163] = 0x3;
}
+ return rdesc;
}
#define samsung_kbd_mouse_map_key_clear(c) \
@@ -130,11 +131,12 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
return 1;
}
-static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
- samsung_irda_report_fixup(hdev, rdesc, rsize);
+ rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
+ return rdesc;
}
static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 402d5574b574..e25af4b112df 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -24,24 +24,27 @@
#include "hid-ids.h"
-#define VAIO_RDESC_CONSTANT 0x0001
+#define VAIO_RDESC_CONSTANT (1 << 0)
+#define SIXAXIS_CONTROLLER_USB (1 << 1)
+#define SIXAXIS_CONTROLLER_BT (1 << 2)
struct sony_sc {
unsigned long quirks;
};
/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
-static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
struct sony_sc *sc = hid_get_drvdata(hdev);
if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
- rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
+ *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report "
"descriptor\n");
rdesc[55] = 0x06;
}
+ return rdesc;
}
/*
@@ -49,7 +52,7 @@ static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
* to "operational". Without this, the ps3 controller will not report any
* events.
*/
-static int sony_set_operational_usb(struct hid_device *hdev)
+static int sixaxis_set_operational_usb(struct hid_device *hdev)
{
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
struct usb_device *dev = interface_to_usbdev(intf);
@@ -74,7 +77,7 @@ static int sony_set_operational_usb(struct hid_device *hdev)
return ret;
}
-static int sony_set_operational_bt(struct hid_device *hdev)
+static int sixaxis_set_operational_bt(struct hid_device *hdev)
{
unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
@@ -108,16 +111,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_free;
}
- switch (hdev->bus) {
- case BUS_USB:
- ret = sony_set_operational_usb(hdev);
- break;
- case BUS_BLUETOOTH:
- ret = sony_set_operational_bt(hdev);
- break;
- default:
+ if (sc->quirks & SIXAXIS_CONTROLLER_USB)
+ ret = sixaxis_set_operational_usb(hdev);
+ else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
+ ret = sixaxis_set_operational_bt(hdev);
+ else
ret = 0;
- }
if (ret < 0)
goto err_stop;
@@ -137,8 +136,10 @@ static void sony_remove(struct hid_device *hdev)
}
static const struct hid_device_id sony_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
+ .driver_data = SIXAXIS_CONTROLLER_USB },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
+ .driver_data = SIXAXIS_CONTROLLER_BT },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
.driver_data = VAIO_RDESC_CONSTANT },
{ }
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 438107d9f1b2..164ed568f6cf 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -22,16 +22,17 @@
#include "hid-ids.h"
-static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
+ if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
rdesc[106] == 0x03) {
dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop "
"report descriptor\n");
rdesc[105] = rdesc[110] = 0x03;
rdesc[106] = rdesc[111] = 0x21;
}
+ return rdesc;
}
#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 5771f851f856..956ed9ac19d4 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -64,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
static const struct hid_device_id ts_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ }
};
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
new file mode 100644
index 000000000000..05fdc85a76e5
--- /dev/null
+++ b/drivers/hid/hid-uclogic.c
@@ -0,0 +1,623 @@
+/*
+ * HID driver for UC-Logic devices not fully compliant with HID standard
+ *
+ * Copyright (c) 2010 Nikolai Kondrashov
+ */
+
+/*
+ * 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/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/*
+ * The original descriptors of WPXXXXU tablets have three report IDs, of
+ * which only two are used (8 and 9), and the remaining (7) seems to have
+ * the originally intended pen description which was abandoned for some
+ * reason. From this unused description it is possible to extract the
+ * actual physical extents and resolution. All the models use the same
+ * descriptor with different extents for the unused report ID.
+ *
+ * Here it is:
+ *
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Pen), ; Pen (02h, application collection)
+ * Collection (Application),
+ * Report ID (7),
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (Tip Switch), ; Tip switch (42h, momentary control)
+ * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
+ * Usage (Eraser), ; Eraser (45h, momentary control)
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (3),
+ * Input (Variable),
+ * Report Count (3),
+ * Input (Constant, Variable),
+ * Usage (In Range), ; In range (32h, momentary control)
+ * Report Count (1),
+ * Input (Variable),
+ * Report Count (1),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Report Size (16),
+ * Report Count (1),
+ * Push,
+ * Unit Exponent (13),
+ * Unit (Inch^3),
+ * Physical Minimum (0),
+ * Physical Maximum (Xpm),
+ * Logical Maximum (Xlm),
+ * Input (Variable),
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Physical Maximum (Ypm),
+ * Logical Maximum (Ylm),
+ * Input (Variable),
+ * Pop,
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
+ * Logical Maximum (1023),
+ * Input (Variable),
+ * Report Size (16),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Mouse), ; Mouse (02h, application collection)
+ * Collection (Application),
+ * Report ID (8),
+ * Usage (Pointer), ; Pointer (01h, physical collection)
+ * Collection (Physical),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (03h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Count (3),
+ * Report Size (1),
+ * Input (Variable),
+ * Report Count (5),
+ * Input (Constant),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Usage (Wheel), ; Wheel (38h, dynamic value)
+ * Usage (00h),
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (4),
+ * Input (Variable, Relative),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Mouse), ; Mouse (02h, application collection)
+ * Collection (Application),
+ * Report ID (9),
+ * Usage (Pointer), ; Pointer (01h, physical collection)
+ * Collection (Physical),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (03h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Count (3),
+ * Report Size (1),
+ * Input (Variable),
+ * Report Count (5),
+ * Input (Constant),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Logical Minimum (0),
+ * Logical Maximum (32767),
+ * Physical Minimum (0),
+ * Physical Maximum (32767),
+ * Report Count (2),
+ * Report Size (16),
+ * Input (Variable),
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
+ * Logical Maximum (1023),
+ * Report Count (1),
+ * Report Size (16),
+ * Input (Variable),
+ * End Collection,
+ * End Collection
+ *
+ * Here are the extents values for the WPXXXXU models:
+ *
+ * Xpm Xlm Ypm Ylm
+ * WP4030U 4000 8000 3000 6000
+ * WP5540U 5500 11000 4000 8000
+ * WP8060U 8000 16000 6000 12000
+ *
+ * This suggests that all of them have 2000 LPI resolution, as advertised.
+ */
+
+/* Size of the original descriptor of WPXXXXU tablets */
+#define WPXXXXU_RDESC_ORIG_SIZE 212
+
+/*
+ * Fixed WP4030U report descriptor.
+ * Although the hardware might actually support it, the mouse description
+ * has been removed, since there seems to be no devices having one and it
+ * wouldn't make much sense because of the working area size.
+ */
+static __u8 wp4030u_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x09, /* Report ID (9), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/* Fixed WP5540U report descriptor */
+static __u8 wp5540u_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x09, /* Report ID (9), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x02, /* Usage (Mouse), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x08, /* Report ID (8), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x03, /* Usage Maximum (03h), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x15, 0x81, /* Logical Minimum (-127), */
+ 0x25, 0x7F, /* Logical Maximum (127), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x09, 0x38, /* Usage (Wheel), */
+ 0x15, 0xFF, /* Logical Minimum (-1), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/* Fixed WP8060U report descriptor */
+static __u8 wp8060u_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x09, /* Report ID (9), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x02, /* Usage (Mouse), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x08, /* Report ID (8), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x03, /* Usage Maximum (03h), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x15, 0x81, /* Logical Minimum (-127), */
+ 0x25, 0x7F, /* Logical Maximum (127), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x09, 0x38, /* Usage (Wheel), */
+ 0x15, 0xFF, /* Logical Minimum (-1), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/*
+ * Original PF1209 report descriptor.
+ *
+ * The descriptor is similar to WPXXXXU descriptors, with an addition of a
+ * feature report (ID 4) of unknown purpose.
+ *
+ * Although the advertised resolution is 4000 LPI the unused report ID
+ * (taken from WPXXXXU, it seems) states 2000 LPI, but it is probably
+ * incorrect and is a result of blind copying without understanding. Anyway
+ * the real logical extents are always scaled to 0..32767, which IMHO spoils
+ * the precision.
+ *
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Pen), ; Pen (02h, application collection)
+ * Collection (Application),
+ * Report ID (7),
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (Tip Switch), ; Tip switch (42h, momentary control)
+ * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
+ * Usage (Eraser), ; Eraser (45h, momentary control)
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (3),
+ * Input (Variable),
+ * Report Count (3),
+ * Input (Constant, Variable),
+ * Usage (In Range), ; In range (32h, momentary control)
+ * Report Count (1),
+ * Input (Variable),
+ * Report Count (1),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Report Size (16),
+ * Report Count (1),
+ * Push,
+ * Unit Exponent (13),
+ * Unit (Inch^3),
+ * Physical Minimum (0),
+ * Physical Maximum (12000),
+ * Logical Maximum (24000),
+ * Input (Variable),
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Physical Maximum (9000),
+ * Logical Maximum (18000),
+ * Input (Variable),
+ * Pop,
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
+ * Logical Maximum (1023),
+ * Input (Variable),
+ * Report Size (16),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Mouse), ; Mouse (02h, application collection)
+ * Collection (Application),
+ * Report ID (8),
+ * Usage (Pointer), ; Pointer (01h, physical collection)
+ * Collection (Physical),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (03h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Count (3),
+ * Report Size (1),
+ * Input (Variable),
+ * Report Count (5),
+ * Input (Constant),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Usage (Wheel), ; Wheel (38h, dynamic value)
+ * Usage (00h),
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (4),
+ * Input (Variable, Relative),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Mouse), ; Mouse (02h, application collection)
+ * Collection (Application),
+ * Report ID (9),
+ * Usage (Pointer), ; Pointer (01h, physical collection)
+ * Collection (Physical),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (03h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Count (3),
+ * Report Size (1),
+ * Input (Variable),
+ * Report Count (5),
+ * Input (Constant),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Logical Minimum (0),
+ * Logical Maximum (32767),
+ * Physical Minimum (0),
+ * Physical Maximum (32767),
+ * Report Count (2),
+ * Report Size (16),
+ * Input (Variable),
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
+ * Logical Maximum (1023),
+ * Report Count (1),
+ * Report Size (16),
+ * Input (Variable),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (00h),
+ * Collection (Application),
+ * Report ID (4),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Usage (00h),
+ * Report Size (8),
+ * Report Count (3),
+ * Feature (Variable),
+ * End Collection
+ */
+
+/* Size of the original descriptor of PF1209 tablet */
+#define PF1209_RDESC_ORIG_SIZE 234
+
+/*
+ * Fixed PF1209 report descriptor
+ *
+ * The descriptor is fixed similarly to WP5540U and WP8060U, plus the
+ * feature report is removed, because its purpose is unknown and it is of no
+ * use to the generic HID driver anyway for now.
+ */
+static __u8 pf1209_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x09, /* Report ID (9), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
+ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x02, /* Usage (Mouse), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x08, /* Report ID (8), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x03, /* Usage Maximum (03h), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x05, /* Report Count (5), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x15, 0x81, /* Logical Minimum (-127), */
+ 0x25, 0x7F, /* Logical Maximum (127), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x09, 0x38, /* Usage (Wheel), */
+ 0x15, 0xFF, /* Logical Minimum (-1), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ switch (hdev->product) {
+ case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209:
+ if (*rsize == PF1209_RDESC_ORIG_SIZE) {
+ rdesc = pf1209_rdesc_fixed;
+ *rsize = sizeof(pf1209_rdesc_fixed);
+ }
+ break;
+ case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U:
+ if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
+ rdesc = wp4030u_rdesc_fixed;
+ *rsize = sizeof(wp4030u_rdesc_fixed);
+ }
+ break;
+ case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U:
+ if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
+ rdesc = wp5540u_rdesc_fixed;
+ *rsize = sizeof(wp5540u_rdesc_fixed);
+ }
+ break;
+ case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U:
+ if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
+ rdesc = wp8060u_rdesc_fixed;
+ *rsize = sizeof(wp8060u_rdesc_fixed);
+ }
+ break;
+ }
+
+ return rdesc;
+}
+
+static const struct hid_device_id uclogic_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
+ USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
+ USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
+ USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
+ USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, uclogic_devices);
+
+static struct hid_driver uclogic_driver = {
+ .name = "uclogic",
+ .id_table = uclogic_devices,
+ .report_fixup = uclogic_report_fixup,
+};
+
+static int __init uclogic_init(void)
+{
+ return hid_register_driver(&uclogic_driver);
+}
+
+static void __exit uclogic_exit(void)
+{
+ hid_unregister_driver(&uclogic_driver);
+}
+
+module_init(uclogic_init);
+module_exit(uclogic_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c
new file mode 100644
index 000000000000..6ef9ed6a57d6
--- /dev/null
+++ b/drivers/hid/hid-waltop.c
@@ -0,0 +1,891 @@
+/*
+ * HID driver for Waltop devices not fully compliant with HID standard
+ *
+ * Copyright (c) 2010 Nikolai Kondrashov
+ */
+
+/*
+ * 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/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/*
+ * There exists an official driver on the manufacturer's website, which
+ * wasn't submitted to the kernel, for some reason. The official driver
+ * doesn't seem to support extra features of some tablets, like wheels.
+ *
+ * It shows that the feature report ID 2 could be used to control any waltop
+ * tablet input mode, switching it between "default", "tablet" and "ink".
+ *
+ * This driver only uses "default" mode for all the supported tablets. This
+ * mode tries to be HID-compatible (not very successfully), but cripples the
+ * resolution of some tablets.
+ *
+ * The "tablet" mode uses some proprietary, yet decipherable protocol, which
+ * represents the correct resolution, but is possibly HID-incompatible (i.e.
+ * indescribable by a report descriptor).
+ *
+ * The purpose of the "ink" mode is unknown.
+ *
+ * The feature reports needed for switching to each mode are these:
+ *
+ * 02 16 00 default
+ * 02 16 01 tablet
+ * 02 16 02 ink
+ */
+
+/*
+ * Original Slim Tablet 5.8 inch report descriptor.
+ *
+ * All the reports except the report with ID 16 (the stylus) are unused,
+ * possibly because the tablet is not configured to, or because they were
+ * just copied from a more capable model. The full purpose of features
+ * described for report ID 2 is unknown.
+ *
+ * The stylus buttons are described as three bit fields, whereas actually
+ * it's an "array", i.e. they're reported as button numbers (1, 2 and 3).
+ * The "eraser" field is not used. There is also a "push" without a "pop" in
+ * the stylus description.
+ *
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Mouse), ; Mouse (02h, application collection)
+ * Collection (Application),
+ * Report ID (1),
+ * Usage (Pointer), ; Pointer (01h, physical collection)
+ * Collection (Physical),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (05h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Size (3),
+ * Report Count (1),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Usage (Wheel), ; Wheel (38h, dynamic value)
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (3),
+ * Input (Variable, Relative),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Pen), ; Pen (02h, application collection)
+ * Collection (Application),
+ * Report ID (2),
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * Usage (Azimuth), ; Azimuth (3Fh, dynamic value)
+ * Usage (Altitude), ; Altitude (40h, dynamic value)
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (2),
+ * Feature (Variable),
+ * End Collection,
+ * Report ID (5),
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (10),
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (3),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (16),
+ * Usage (Stylus), ; Stylus (20h, logical collection)
+ * Collection (Physical),
+ * Usage (Tip Switch), ; Tip switch (42h, momentary control)
+ * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
+ * Usage (Invert), ; Invert (3Ch, momentary control)
+ * Usage (Eraser), ; Eraser (45h, momentary control)
+ * Usage (In Range), ; In range (32h, momentary control)
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Count (3),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (X), ; X (30h, dynamic value)
+ * Report Size (16),
+ * Report Count (1),
+ * Push,
+ * Unit Exponent (13),
+ * Unit (Inch^3),
+ * Logical Minimum (0),
+ * Logical Maximum (10000),
+ * Physical Minimum (0),
+ * Physical Maximum (10000),
+ * Input (Variable),
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Logical Maximum (6000),
+ * Physical Maximum (6000),
+ * Input (Variable),
+ * Usage Page (Digitizer), ; Digitizer (0Dh)
+ * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
+ * Logical Minimum (0),
+ * Logical Maximum (1023),
+ * Physical Minimum (0),
+ * Physical Maximum (1023),
+ * Input (Variable),
+ * End Collection,
+ * End Collection
+ */
+
+/* Size of the original report descriptor of Slim Tablet 5.8 inch */
+#define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE 222
+
+/*
+ * Fixed Slim Tablet 5.8 inch descriptor.
+ *
+ * All the reports except the stylus report (ID 16) were removed as unused.
+ * The stylus buttons description was fixed.
+ */
+static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x10, /* Report ID (16), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x15, 0x01, /* Logical Minimum (1), */
+ 0x25, 0x03, /* Logical Maximum (3), */
+ 0x75, 0x04, /* Report Size (4), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x80, /* Input, */
+ 0x09, 0x32, /* Usage (In Range), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
+ 0x26, 0x10, 0x27, /* Logical Maximum (10000), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
+ 0x26, 0x70, 0x17, /* Logical Maximum (6000), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/*
+ * Original Media Tablet 10.6 inch report descriptor.
+ *
+ * There are at least two versions of this model in the wild. They are
+ * represented by Genius G-Pen M609 (older version) and Genius G-Pen M609X
+ * (newer version).
+ *
+ * Both versions have the usual pen with two barrel buttons and two
+ * identical wheels with center buttons in the top corners of the tablet
+ * base. They also have buttons on the top, between the wheels, for
+ * selecting the wheels' functions and wide/standard mode. In the wide mode
+ * the whole working surface is sensed, in the standard mode a narrower area
+ * is sensed, but the logical report extents remain the same. These modes
+ * correspond roughly to 16:9 and 4:3 aspect ratios respectively.
+ *
+ * The older version has three wheel function buttons ("scroll", "zoom" and
+ * "volume") and two separate buttons for wide and standard mode. The newer
+ * version has four wheel function buttons (plus "brush") and only one
+ * button is used for selecting wide/standard mode. So, the total number of
+ * buttons remains the same, but one of the mode buttons is repurposed as a
+ * wheels' function button in the newer version.
+ *
+ * The wheel functions are:
+ * scroll - the wheels act as scroll wheels, the center buttons switch
+ * between vertical and horizontal scrolling;
+ * zoom - the wheels zoom in/out, the buttons supposedly reset to 100%;
+ * volume - the wheels control the sound volume, the buttons mute;
+ * brush - the wheels are supposed to control brush width in a graphics
+ * editor, the buttons do nothing.
+ *
+ * Below is the newer version's report descriptor. It may very well be that
+ * the older version's descriptor is different and thus it won't be
+ * supported.
+ *
+ * The mouse report (ID 1) only uses the wheel field for reporting the tablet
+ * wheels' scroll mode. The keyboard report (ID 13) is used to report the
+ * wheels' zoom and brush control functions as key presses. The report ID 12
+ * is used to report the wheels' volume control functions. The stylus report
+ * (ID 16) has the same problems as the Slim Tablet 5.8 inch report has.
+ *
+ * The rest of the reports are unused, at least in the default configuration.
+ * The purpose of the features is unknown.
+ *
+ * Usage Page (Desktop),
+ * Usage (Mouse),
+ * Collection (Application),
+ * Report ID (1),
+ * Usage (Pointer),
+ * Collection (Physical),
+ * Usage Page (Button),
+ * Usage Minimum (01h),
+ * Usage Maximum (05h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Size (3),
+ * Report Count (1),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop),
+ * Usage (X),
+ * Usage (Y),
+ * Usage (Wheel),
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (3),
+ * Input (Variable, Relative),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Digitizer),
+ * Usage (Pen),
+ * Collection (Application),
+ * Report ID (2),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * Usage (Azimuth),
+ * Usage (Altitude),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (2),
+ * Feature (Variable),
+ * End Collection,
+ * Report ID (5),
+ * Usage Page (Digitizer),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (10),
+ * Usage Page (Digitizer),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (16),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (Tip Switch),
+ * Usage (Barrel Switch),
+ * Usage (Invert),
+ * Usage (Eraser),
+ * Usage (In Range),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Count (3),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop),
+ * Usage (X),
+ * Report Size (16),
+ * Report Count (1),
+ * Push,
+ * Unit Exponent (13),
+ * Unit (Inch^3),
+ * Logical Minimum (0),
+ * Logical Maximum (18000),
+ * Physical Minimum (0),
+ * Physical Maximum (18000),
+ * Input (Variable),
+ * Usage (Y),
+ * Logical Maximum (11000),
+ * Physical Maximum (11000),
+ * Input (Variable),
+ * Usage Page (Digitizer),
+ * Usage (Tip Pressure),
+ * Logical Minimum (0),
+ * Logical Maximum (1023),
+ * Physical Minimum (0),
+ * Physical Maximum (1023),
+ * Input (Variable),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop),
+ * Usage (Keyboard),
+ * Collection (Application),
+ * Report ID (13),
+ * Usage Page (Keyboard),
+ * Usage Minimum (KB Leftcontrol),
+ * Usage Maximum (KB Right GUI),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (8),
+ * Input (Variable),
+ * Report Size (8),
+ * Report Count (1),
+ * Input (Constant),
+ * Usage Page (Keyboard),
+ * Usage Minimum (None),
+ * Usage Maximum (KB Application),
+ * Logical Minimum (0),
+ * Logical Maximum (101),
+ * Report Size (8),
+ * Report Count (5),
+ * Input,
+ * End Collection,
+ * Usage Page (Consumer),
+ * Usage (Consumer Control),
+ * Collection (Application),
+ * Report ID (12),
+ * Usage (Volume Inc),
+ * Usage (Volume Dec),
+ * Usage (Mute),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (3),
+ * Input (Variable, Relative),
+ * Report Size (5),
+ * Report Count (1),
+ * Input (Constant, Variable, Relative),
+ * End Collection
+ */
+
+/* Size of the original report descriptor of Media Tablet 10.6 inch */
+#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300
+
+/*
+ * Fixed Media Tablet 10.6 inch descriptor.
+ *
+ * The descriptions of reports unused in the default configuration are
+ * removed. The stylus report (ID 16) is fixed similarly to Slim Tablet 5.8
+ * inch. The unused mouse report (ID 1) fields are replaced with constant
+ * padding.
+ *
+ * The keyboard report (ID 13) is hacked to instead have an "array" field
+ * reporting consumer page controls, and all the unused bits are masked out
+ * with constant padding. The "brush" wheels' function is represented as "Scan
+ * Previous/Next Track" controls due to the lack of brush controls in the
+ * usage tables specification.
+ */
+static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x10, /* Report ID (16), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x15, 0x01, /* Logical Minimum (1), */
+ 0x25, 0x03, /* Logical Maximum (3), */
+ 0x75, 0x04, /* Report Size (4), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x80, /* Input, */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x32, /* Usage (In Range), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
+ 0x26, 0x50, 0x46, /* Logical Maximum (18000), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
+ 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x02, /* Usage (Mouse), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x01, /* Report ID (1), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x15, 0xFF, /* Logical Minimum (-1), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x09, 0x38, /* Usage (Wheel), */
+ 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
+ 0x0C, 0x00,
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x0C, /* Usage Page (Consumer), */
+ 0x09, 0x01, /* Usage (Consumer Control), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x0D, /* Report ID (13), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
+ 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
+ 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
+ 0x09, 0xB6, /* Usage (Scan Previous Track), */
+ 0x09, 0xB5, /* Usage (Scan Next Track), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
+ 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
+ 0x15, 0x0C, /* Logical Minimum (12), */
+ 0x25, 0x17, /* Logical Maximum (23), */
+ 0x75, 0x05, /* Report Size (5), */
+ 0x80, /* Input, */
+ 0x75, 0x03, /* Report Size (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x20, /* Report Size (32), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0xC0, /* End Collection, */
+ 0x09, 0x01, /* Usage (Consumer Control), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x0C, /* Report ID (12), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0xE9, /* Usage (Volume Inc), */
+ 0x09, 0xEA, /* Usage (Volume Dec), */
+ 0x09, 0xE2, /* Usage (Mute), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x95, 0x35, /* Report Count (53), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0xC0 /* End Collection */
+};
+
+/*
+ * Original Media Tablet 14.1 inch report descriptor.
+ *
+ * There are at least two versions of this model in the wild. They are
+ * represented by Genius G-Pen M712 (older version) and Genius G-Pen M712X
+ * (newer version). The hardware difference between these versions is the same
+ * as between older and newer versions of Media Tablet 10.6 inch. The report
+ * descriptors are identical for both versions.
+ *
+ * The function, behavior and report descriptor of this tablet is similar to
+ * that of Media Tablet 10.6 inch. However, there is one more field (with
+ * Consumer AC Pan usage) in the mouse description. Then the tablet X and Y
+ * logical extents both get scaled to 0..16383 range (a hardware limit?),
+ * which kind of defeats the advertised 4000 LPI resolution, considering the
+ * physical extents of 12x7.25 inches. Plus, reports 5, 10 and 255 are used
+ * sometimes (while moving the pen) with unknown purpose. Also, the key codes
+ * generated for zoom in/out are different.
+ *
+ * Usage Page (Desktop),
+ * Usage (Mouse),
+ * Collection (Application),
+ * Report ID (1),
+ * Usage (Pointer),
+ * Collection (Physical),
+ * Usage Page (Button),
+ * Usage Minimum (01h),
+ * Usage Maximum (05h),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Size (3),
+ * Report Count (1),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop),
+ * Usage (X),
+ * Usage (Y),
+ * Usage (Wheel),
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (3),
+ * Input (Variable, Relative),
+ * Usage Page (Consumer),
+ * Logical Minimum (-127),
+ * Logical Maximum (127),
+ * Report Size (8),
+ * Report Count (1),
+ * Usage (AC Pan),
+ * Input (Variable, Relative),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Digitizer),
+ * Usage (Pen),
+ * Collection (Application),
+ * Report ID (2),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * Usage (Azimuth),
+ * Usage (Altitude),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (2),
+ * Feature (Variable),
+ * End Collection,
+ * Report ID (5),
+ * Usage Page (Digitizer),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (10),
+ * Usage Page (Digitizer),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (00h),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Report Size (8),
+ * Report Count (7),
+ * Input (Variable),
+ * End Collection,
+ * Report ID (16),
+ * Usage (Stylus),
+ * Collection (Physical),
+ * Usage (Tip Switch),
+ * Usage (Barrel Switch),
+ * Usage (Invert),
+ * Usage (Eraser),
+ * Usage (In Range),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (5),
+ * Input (Variable),
+ * Report Count (3),
+ * Input (Constant, Variable),
+ * Usage Page (Desktop),
+ * Usage (X),
+ * Report Size (16),
+ * Report Count (1),
+ * Push,
+ * Unit Exponent (13),
+ * Unit (Inch^3),
+ * Logical Minimum (0),
+ * Logical Maximum (16383),
+ * Physical Minimum (0),
+ * Physical Maximum (16383),
+ * Input (Variable),
+ * Usage (Y),
+ * Input (Variable),
+ * Usage Page (Digitizer),
+ * Usage (Tip Pressure),
+ * Logical Minimum (0),
+ * Logical Maximum (1023),
+ * Physical Minimum (0),
+ * Physical Maximum (1023),
+ * Input (Variable),
+ * End Collection,
+ * End Collection,
+ * Usage Page (Desktop),
+ * Usage (Keyboard),
+ * Collection (Application),
+ * Report ID (13),
+ * Usage Page (Keyboard),
+ * Usage Minimum (KB Leftcontrol),
+ * Usage Maximum (KB Right GUI),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (8),
+ * Input (Variable),
+ * Report Size (8),
+ * Report Count (1),
+ * Input (Constant),
+ * Usage Page (Keyboard),
+ * Usage Minimum (None),
+ * Usage Maximum (KB Application),
+ * Logical Minimum (0),
+ * Logical Maximum (101),
+ * Report Size (8),
+ * Report Count (5),
+ * Input,
+ * End Collection,
+ * Usage Page (Consumer),
+ * Usage (Consumer Control),
+ * Collection (Application),
+ * Report ID (12),
+ * Usage (Volume Inc),
+ * Usage (Volume Dec),
+ * Usage (Mute),
+ * Logical Minimum (0),
+ * Logical Maximum (1),
+ * Report Size (1),
+ * Report Count (3),
+ * Input (Variable, Relative),
+ * Report Size (5),
+ * Report Count (1),
+ * Input (Constant, Variable, Relative),
+ * End Collection
+ */
+
+/* Size of the original report descriptor of Media Tablet 14.1 inch */
+#define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE 309
+
+/*
+ * Fixed Media Tablet 14.1 inch descriptor.
+ * It is fixed similarly to the Media Tablet 10.6 inch descriptor.
+ */
+static __u8 media_tablet_14_1_inch_rdesc_fixed[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x10, /* Report ID (16), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x15, 0x01, /* Logical Minimum (1), */
+ 0x25, 0x03, /* Logical Maximum (3), */
+ 0x75, 0x04, /* Report Size (4), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x80, /* Input, */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x32, /* Usage (In Range), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x14, /* Logical Minimum (0), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
+ 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x46, 0x52, 0x1C, /* Physical Maximum (7250), */
+ 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x02, /* Usage (Mouse), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x01, /* Report ID (1), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA0, /* Collection (Physical), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x15, 0xFF, /* Logical Minimum (-1), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x09, 0x38, /* Usage (Wheel), */
+ 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
+ 0x0C, 0x00,
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0xC0, /* End Collection, */
+ 0xC0, /* End Collection, */
+ 0x05, 0x0C, /* Usage Page (Consumer), */
+ 0x09, 0x01, /* Usage (Consumer Control), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x0D, /* Report ID (13), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
+ 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
+ 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
+ 0x09, 0xB6, /* Usage (Scan Previous Track), */
+ 0x09, 0xB5, /* Usage (Scan Next Track), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x08, /* Usage (00h), */
+ 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
+ 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
+ 0x15, 0x0C, /* Logical Minimum (12), */
+ 0x25, 0x17, /* Logical Maximum (23), */
+ 0x75, 0x05, /* Report Size (5), */
+ 0x80, /* Input, */
+ 0x75, 0x03, /* Report Size (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x20, /* Report Size (32), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0xC0, /* End Collection, */
+ 0x09, 0x01, /* Usage (Consumer Control), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x0C, /* Report ID (12), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0xE9, /* Usage (Volume Inc), */
+ 0x09, 0xEA, /* Usage (Volume Dec), */
+ 0x09, 0xE2, /* Usage (Mute), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x06, /* Input (Variable, Relative), */
+ 0x75, 0x05, /* Report Size (5), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0xC0 /* End Collection */
+};
+
+static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ switch (hdev->product) {
+ case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
+ if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
+ rdesc = slim_tablet_5_8_inch_rdesc_fixed;
+ *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
+ }
+ break;
+ case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
+ if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
+ rdesc = media_tablet_10_6_inch_rdesc_fixed;
+ *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
+ }
+ break;
+ case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:
+ if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {
+ rdesc = media_tablet_14_1_inch_rdesc_fixed;
+ *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);
+ }
+ break;
+ }
+ return rdesc;
+}
+
+static const struct hid_device_id waltop_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
+ USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
+ USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
+ USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, waltop_devices);
+
+static struct hid_driver waltop_driver = {
+ .name = "waltop",
+ .id_table = waltop_devices,
+ .report_fixup = waltop_report_fixup,
+};
+
+static int __init waltop_init(void)
+{
+ return hid_register_driver(&waltop_driver);
+}
+
+static void __exit waltop_exit(void)
+{
+ hid_unregister_driver(&waltop_driver);
+}
+
+module_init(waltop_init);
+module_exit(waltop_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index 9e8d35a203e4..aac1f9273149 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -27,10 +27,10 @@ struct zc_device {
* Zydacron remote control has an invalid HID report descriptor,
* that needs fixing before we can parse it.
*/
-static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int rsize)
+static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
- if (rsize >= 253 &&
+ if (*rsize >= 253 &&
rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
@@ -40,6 +40,7 @@ static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
}
+ return rdesc;
}
#define zc_map_key_clear(c) \
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 47d70c523d93..0615e2cfea79 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -329,6 +329,7 @@ static const struct file_operations hidraw_ops = {
.open = hidraw_open,
.release = hidraw_release,
.unlocked_ioctl = hidraw_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b729c0286679..599041a7f670 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -828,6 +828,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
}
} else {
int skipped_report_id = 0;
+ int report_id = buf[0];
if (buf[0] == 0x0) {
/* Don't send the Report ID */
buf++;
@@ -837,7 +838,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_REPORT,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ((report_type + 1) << 8) | *buf,
+ ((report_type + 1) << 8) | report_id,
interface->desc.bInterfaceNumber, buf, count,
USB_CTRL_SET_TIMEOUT);
/* count also the report id, if this was a numbered report. */
@@ -1445,6 +1446,11 @@ static const struct hid_device_id hid_usb_table[] = {
{ }
};
+struct usb_interface *usbhid_find_interface(int minor)
+{
+ return usb_find_interface(&hid_driver, minor);
+}
+
static struct hid_driver hid_usb_driver = {
.name = "generic-usb",
.id_table = hid_usb_table,
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 2643d3147621..bd25ebfbb1a3 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -33,6 +33,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -68,7 +69,12 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -77,6 +83,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
+ { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
+
{ 0, 0 }
};
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 0a29c51114aa..d4c73efc8da1 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -270,7 +270,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
struct hiddev *hiddev;
int res;
- intf = usb_find_interface(&hiddev_driver, iminor(inode));
+ intf = usbhid_find_interface(iminor(inode));
if (!intf)
return -ENODEV;
hid = usb_get_intfdata(intf);
@@ -847,6 +847,7 @@ static const struct file_operations hiddev_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = hiddev_compat_ioctl,
#endif
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static char *hiddev_devnode(struct device *dev, mode_t *mode)
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 693fd3e720df..89d2e847dcc6 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -42,6 +42,7 @@ void usbhid_submit_report
(struct hid_device *hid, struct hid_report *report, unsigned char dir);
int usbhid_get_power(struct hid_device *hid);
void usbhid_put_power(struct hid_device *hid);
+struct usb_interface *usbhid_find_interface(int minor);
/* iofl flags */
#define HID_CTRL_RUNNING 1
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 653db1bda934..ef82ed29aca4 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -762,6 +762,7 @@ static const struct file_operations atk_debugfs_ggrp_fops = {
.read = atk_debugfs_ggrp_read,
.open = atk_debugfs_ggrp_open,
.release = atk_debugfs_ggrp_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static void atk_debugfs_init(struct atk_data *data)
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 0f58ecc5334d..9638d58f99fd 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -79,7 +79,7 @@ enum chips { f75373, f75375 };
#define F75375_REG_PWM2_DROP_DUTY 0x6C
#define FAN_CTRL_LINEAR(nr) (4 + nr)
-#define FAN_CTRL_MODE(nr) (5 + ((nr) * 2))
+#define FAN_CTRL_MODE(nr) (4 + ((nr) * 2))
/*
* Data structures and manipulation thereof
@@ -298,7 +298,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
return -EINVAL;
fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
- fanmode = ~(3 << FAN_CTRL_MODE(nr));
+ fanmode &= ~(3 << FAN_CTRL_MODE(nr));
switch (val) {
case 0: /* Full speed */
@@ -350,7 +350,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->update_lock);
conf = f75375_read8(client, F75375_REG_CONFIG1);
- conf = ~(1 << FAN_CTRL_LINEAR(nr));
+ conf &= ~(1 << FAN_CTRL_LINEAR(nr));
if (val == 0)
conf |= (1 << FAN_CTRL_LINEAR(nr)) ;
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index b7ca2a9676cf..d4d4ca65d371 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -38,7 +38,6 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/smp_lock.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
@@ -50,6 +49,7 @@
#include <linux/kref.h>
/* Addresses to scan */
+static DEFINE_MUTEX(watchdog_mutex);
static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
/* Insmod parameters */
@@ -858,7 +858,7 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar
int i, ret = 0;
struct fschmd_data *data = filp->private_data;
- lock_kernel();
+ mutex_lock(&watchdog_mutex);
switch (cmd) {
case WDIOC_GETSUPPORT:
ident.firmware_version = data->revision;
@@ -915,7 +915,7 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long ar
default:
ret = -ENOTTY;
}
- unlock_kernel();
+ mutex_unlock(&watchdog_mutex);
return ret;
}
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 7580f55e67e3..36e957532230 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -221,6 +221,8 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left),
AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
+ AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted),
+ AXIS_DMI_MATCH("Mini5102", "HP Mini 5102", xy_rotated_left_usd),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index 39ead2a4d3c5..418496f13020 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -191,38 +191,31 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
model = boot_cpu_data.x86_model;
stepping = boot_cpu_data.x86_mask;
- switch (boot_cpu_data.x86) {
- case 0xf:
- /* feature available since SH-C0, exclude older revisions */
- if (((model == 4) && (stepping == 0)) ||
- ((model == 5) && (stepping <= 1))) {
- err = -ENODEV;
- goto exit_free;
- }
-
- /*
- * AMD NPT family 0fh, i.e. RevF and RevG:
- * meaning of SEL_CORE bit is inverted
- */
- if (model >= 0x40) {
- data->swap_core_select = 1;
- dev_warn(&pdev->dev, "Temperature readouts might be "
- "wrong - check erratum #141\n");
- }
-
- if (is_rev_g_desktop(model)) {
- /*
- * RevG desktop CPUs (i.e. no socket S1G1 or
- * ASB1 parts) need additional offset,
- * otherwise reported temperature is below
- * ambient temperature
- */
- data->temp_offset = 21000;
- }
+ /* feature available since SH-C0, exclude older revisions */
+ if (((model == 4) && (stepping == 0)) ||
+ ((model == 5) && (stepping <= 1))) {
+ err = -ENODEV;
+ goto exit_free;
+ }
- break;
+ /*
+ * AMD NPT family 0fh, i.e. RevF and RevG:
+ * meaning of SEL_CORE bit is inverted
+ */
+ if (model >= 0x40) {
+ data->swap_core_select = 1;
+ dev_warn(&pdev->dev, "Temperature readouts might be wrong - "
+ "check erratum #141\n");
}
+ /*
+ * RevG desktop CPUs (i.e. no socket S1G1 or ASB1 parts) need
+ * additional offset, otherwise reported temperature is below
+ * ambient temperature
+ */
+ if (is_rev_g_desktop(model))
+ data->temp_offset = 21000;
+
pci_read_config_byte(pdev, REG_TEMP, &scfg);
scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */
pci_write_config_byte(pdev, REG_TEMP, scfg);
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index dc1f5402c1d7..8e5933b72d19 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -121,7 +121,7 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct lis3lv02d *lis3 = i2c_get_clientdata(client);
- if (!lis3->pdata->wakeup_flags)
+ if (!lis3->pdata || !lis3->pdata->wakeup_flags)
lis3lv02d_poweroff(lis3);
return 0;
}
@@ -130,7 +130,7 @@ static int lis3lv02d_i2c_resume(struct i2c_client *client)
{
struct lis3lv02d *lis3 = i2c_get_clientdata(client);
- if (!lis3->pdata->wakeup_flags)
+ if (!lis3->pdata || !lis3->pdata->wakeup_flags)
lis3lv02d_poweron(lis3);
return 0;
}
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index 82b16808a274..b9be5e3a22b3 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -92,7 +92,7 @@ static int lis3lv02d_spi_suspend(struct spi_device *spi, pm_message_t mesg)
{
struct lis3lv02d *lis3 = spi_get_drvdata(spi);
- if (!lis3->pdata->wakeup_flags)
+ if (!lis3->pdata || !lis3->pdata->wakeup_flags)
lis3lv02d_poweroff(&lis3_dev);
return 0;
@@ -102,7 +102,7 @@ static int lis3lv02d_spi_resume(struct spi_device *spi)
{
struct lis3lv02d *lis3 = spi_get_drvdata(spi);
- if (!lis3->pdata->wakeup_flags)
+ if (!lis3->pdata || !lis3->pdata->wakeup_flags)
lis3lv02d_poweron(lis3);
return 0;
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index ab5b87a81677..f36eb80d227f 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -1,22 +1,22 @@
/*
- lm75.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
+ * lm75.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring
+ * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
+ *
+ * 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/module.h>
#include <linux/init.h>
@@ -103,7 +103,12 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
struct i2c_client *client = to_i2c_client(dev);
struct lm75_data *data = i2c_get_clientdata(client);
int nr = attr->index;
- long temp = simple_strtol(buf, NULL, 10);
+ long temp;
+ int error;
+
+ error = strict_strtol(buf, 10, &temp);
+ if (error)
+ return error;
mutex_lock(&data->update_lock);
data->temp[nr] = LM75_TEMP_TO_REG(temp);
@@ -335,9 +340,11 @@ static struct i2c_driver lm75_driver = {
/* register access */
-/* All registers are word-sized, except for the configuration register.
- LM75 uses a high-byte first convention, which is exactly opposite to
- the SMBus standard. */
+/*
+ * All registers are word-sized, except for the configuration register.
+ * LM75 uses a high-byte first convention, which is exactly opposite to
+ * the SMBus standard.
+ */
static int lm75_read_value(struct i2c_client *client, u8 reg)
{
int value;
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 760ef72eea56..aafed2898d95 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -387,8 +387,13 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct lm90_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
+ long val;
+ int err;
+
+ err = strict_strtol(buf, 10, &val);
+ if (err < 0)
+ return err;
/* +16 degrees offset for temp2 for the LM99 */
if (data->kind == lm99 && attr->index == 3)
@@ -442,8 +447,13 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct lm90_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
+ long val;
+ int err;
+
+ err = strict_strtol(buf, 10, &val);
+ if (err < 0)
+ return err;
/* +16 degrees offset for temp2 for the LM99 */
if (data->kind == lm99 && attr->index <= 2)
@@ -469,7 +479,8 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
return count;
}
-static ssize_t show_temphyst(struct device *dev, struct device_attribute *devattr,
+static ssize_t show_temphyst(struct device *dev,
+ struct device_attribute *devattr,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
@@ -495,9 +506,14 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm90_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
+ long val;
+ int err;
int temp;
+ err = strict_strtol(buf, 10, &val);
+ if (err < 0)
+ return err;
+
mutex_lock(&data->update_lock);
if (data->kind == adt7461)
temp = temp_from_u8_adt7461(data, data->temp8[2]);
@@ -600,7 +616,12 @@ static ssize_t set_pec(struct device *dev, struct device_attribute *dummy,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
- long val = simple_strtol(buf, NULL, 10);
+ long val;
+ int err;
+
+ err = strict_strtol(buf, 10, &val);
+ if (err < 0)
+ return err;
switch (val) {
case 0:
@@ -622,8 +643,10 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
* Real code
*/
-/* The ADM1032 supports PEC but not on write byte transactions, so we need
- to explicitly ask for a transaction without PEC. */
+/*
+ * The ADM1032 supports PEC but not on write byte transactions, so we need
+ * to explicitly ask for a transaction without PEC.
+ */
static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
{
return i2c_smbus_xfer(client->adapter, client->addr,
@@ -631,20 +654,22 @@ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
}
-/* It is assumed that client->update_lock is held (unless we are in
- detection or initialization steps). This matters when PEC is enabled,
- because we don't want the address pointer to change between the write
- byte and the read byte transactions. */
-static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
+/*
+ * It is assumed that client->update_lock is held (unless we are in
+ * detection or initialization steps). This matters when PEC is enabled,
+ * because we don't want the address pointer to change between the write
+ * byte and the read byte transactions.
+ */
+static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value)
{
int err;
- if (client->flags & I2C_CLIENT_PEC) {
- err = adm1032_write_byte(client, reg);
- if (err >= 0)
- err = i2c_smbus_read_byte(client);
- } else
- err = i2c_smbus_read_byte_data(client, reg);
+ if (client->flags & I2C_CLIENT_PEC) {
+ err = adm1032_write_byte(client, reg);
+ if (err >= 0)
+ err = i2c_smbus_read_byte(client);
+ } else
+ err = i2c_smbus_read_byte_data(client, reg);
if (err < 0) {
dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
@@ -826,16 +851,18 @@ static int lm90_probe(struct i2c_client *new_client,
lm90_init_client(new_client);
/* Register sysfs hooks */
- if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group)))
+ err = sysfs_create_group(&new_client->dev.kobj, &lm90_group);
+ if (err)
goto exit_free;
if (new_client->flags & I2C_CLIENT_PEC) {
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_pec)))
+ err = device_create_file(&new_client->dev, &dev_attr_pec);
+ if (err)
goto exit_remove_files;
}
if (data->kind != max6657 && data->kind != max6646) {
- if ((err = device_create_file(&new_client->dev,
- &sensor_dev_attr_temp2_offset.dev_attr)))
+ err = device_create_file(&new_client->dev,
+ &sensor_dev_attr_temp2_offset.dev_attr);
+ if (err)
goto exit_remove_files;
}
@@ -883,9 +910,8 @@ static void lm90_init_client(struct i2c_client *client)
* 0.125 degree resolution) and range (0x08, extend range
* to -64 degree) mode for the remote temperature sensor.
*/
- if (data->kind == max6680) {
+ if (data->kind == max6680)
config |= 0x18;
- }
config &= 0xBF; /* run */
if (config != data->config_orig) /* Only write if changed */
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index 3f3f9a47acfd..05248f2d7581 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -51,7 +51,7 @@ struct s3c_hwmon_attr {
* @attr: The holders for the channel attributes.
*/
struct s3c_hwmon {
- struct semaphore lock;
+ struct mutex lock;
struct s3c_adc_client *client;
struct device *hwmon_dev;
@@ -73,14 +73,14 @@ static int s3c_hwmon_read_ch(struct device *dev,
{
int ret;
- ret = down_interruptible(&hwmon->lock);
+ ret = mutex_lock_interruptible(&hwmon->lock);
if (ret < 0)
return ret;
dev_dbg(dev, "reading channel %d\n", channel);
ret = s3c_adc_read(hwmon->client, channel);
- up(&hwmon->lock);
+ mutex_unlock(&hwmon->lock);
return ret;
}
@@ -296,7 +296,7 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev)
platform_set_drvdata(dev, hwmon);
- init_MUTEX(&hwmon->lock);
+ mutex_init(&hwmon->lock);
/* Register with the core ADC driver. */
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 697202e27891..8e540ada47d2 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -35,7 +35,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
-#include <linux/smp_lock.h>
#include <linux/hwmon-vid.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
@@ -52,6 +51,7 @@
#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
/* Addresses to scan */
+static DEFINE_MUTEX(watchdog_mutex);
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
I2C_CLIENT_END };
@@ -1333,7 +1333,7 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd,
int val, ret = 0;
struct w83793_data *data = filp->private_data;
- lock_kernel();
+ mutex_lock(&watchdog_mutex);
switch (cmd) {
case WDIOC_GETSUPPORT:
if (!nowayout)
@@ -1387,7 +1387,7 @@ static long watchdog_ioctl(struct file *filp, unsigned int cmd,
default:
ret = -ENOTTY;
}
- unlock_kernel();
+ mutex_unlock(&watchdog_mutex);
return ret;
}
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 598c49acaeb5..2707f5e17158 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -538,15 +538,17 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
{
struct resource *res;
int ret = -ENXIO;
- int q, m;
- int k = 0;
- int n = 0;
+ int n, k = 0;
while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
for (n = res->start; hook && n <= res->end; n++) {
if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED,
- dev_name(&dev->dev), dev))
+ dev_name(&dev->dev), dev)) {
+ for (n--; n >= res->start; n--)
+ free_irq(n, dev);
+
goto rollback;
+ }
}
k++;
}
@@ -554,16 +556,17 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
if (hook)
return k > 0 ? 0 : -ENOENT;
- k--;
ret = 0;
rollback:
- for (q = k; k >= 0; k--) {
- for (m = n; m >= res->start; m--)
- free_irq(m, dev);
+ k--;
+
+ while (k >= 0) {
+ res = platform_get_resource(dev, IORESOURCE_IRQ, k);
+ for (n = res->start; n <= res->end; n++)
+ free_irq(n, dev);
- res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1);
- m = res->end;
+ k--;
}
return ret;
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 6649176de940..0b5784e753a7 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -216,12 +216,6 @@ static int i2c_device_pm_resume(struct device *dev)
else
ret = i2c_legacy_resume(dev);
- if (!ret) {
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
- }
-
return ret;
}
@@ -428,14 +422,14 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp)
/* walk up mux tree */
static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
{
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result;
result = device_for_each_child(&adapter->dev, &addr,
__i2c_check_addr_busy);
- if (!result && i2c_parent_is_i2c_adapter(adapter))
- result = i2c_check_mux_parents(
- to_i2c_adapter(adapter->dev.parent), addr);
+ if (!result && parent)
+ result = i2c_check_mux_parents(parent, addr);
return result;
}
@@ -456,11 +450,11 @@ static int i2c_check_mux_children(struct device *dev, void *addrp)
static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
{
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result = 0;
- if (i2c_parent_is_i2c_adapter(adapter))
- result = i2c_check_mux_parents(
- to_i2c_adapter(adapter->dev.parent), addr);
+ if (parent)
+ result = i2c_check_mux_parents(parent, addr);
if (!result)
result = device_for_each_child(&adapter->dev, &addr,
@@ -475,8 +469,10 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
*/
void i2c_lock_adapter(struct i2c_adapter *adapter)
{
- if (i2c_parent_is_i2c_adapter(adapter))
- i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent));
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+ if (parent)
+ i2c_lock_adapter(parent);
else
rt_mutex_lock(&adapter->bus_lock);
}
@@ -488,8 +484,10 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter);
*/
static int i2c_trylock_adapter(struct i2c_adapter *adapter)
{
- if (i2c_parent_is_i2c_adapter(adapter))
- return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent));
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+ if (parent)
+ return i2c_trylock_adapter(parent);
else
return rt_mutex_trylock(&adapter->bus_lock);
}
@@ -500,8 +498,10 @@ static int i2c_trylock_adapter(struct i2c_adapter *adapter)
*/
void i2c_unlock_adapter(struct i2c_adapter *adapter)
{
- if (i2c_parent_is_i2c_adapter(adapter))
- i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent));
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+
+ if (parent)
+ i2c_unlock_adapter(parent);
else
rt_mutex_unlock(&adapter->bus_lock);
}
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 5f3a52d517c3..cec0f3ba97f8 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -192,13 +192,12 @@ static int i2cdev_check(struct device *dev, void *addrp)
/* walk up mux tree */
static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)
{
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result;
result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);
-
- if (!result && i2c_parent_is_i2c_adapter(adapter))
- result = i2cdev_check_mux_parents(
- to_i2c_adapter(adapter->dev.parent), addr);
+ if (!result && parent)
+ result = i2cdev_check_mux_parents(parent, addr);
return result;
}
@@ -222,11 +221,11 @@ static int i2cdev_check_mux_children(struct device *dev, void *addrp)
driver bound to it, as NOT busy. */
static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
{
+ struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result = 0;
- if (i2c_parent_is_i2c_adapter(adapter))
- result = i2cdev_check_mux_parents(
- to_i2c_adapter(adapter->dev.parent), addr);
+ if (parent)
+ result = i2cdev_check_mux_parents(parent, addr);
if (!result)
result = device_for_each_child(&adapter->dev, &addr,
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 31fc76960a8f..0c73fe39a236 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -31,7 +31,6 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
@@ -52,6 +51,7 @@
#include "ide-cd.h"
+static DEFINE_MUTEX(ide_cd_mutex);
static DEFINE_MUTEX(idecd_ref_mutex);
static void ide_cd_release(struct device *);
@@ -1602,7 +1602,7 @@ static int idecd_open(struct block_device *bdev, fmode_t mode)
struct cdrom_info *info;
int rc = -ENXIO;
- lock_kernel();
+ mutex_lock(&ide_cd_mutex);
info = ide_cd_get(bdev->bd_disk);
if (!info)
goto out;
@@ -1611,7 +1611,7 @@ static int idecd_open(struct block_device *bdev, fmode_t mode)
if (rc < 0)
ide_cd_put(info);
out:
- unlock_kernel();
+ mutex_unlock(&ide_cd_mutex);
return rc;
}
@@ -1619,11 +1619,11 @@ static int idecd_release(struct gendisk *disk, fmode_t mode)
{
struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
- lock_kernel();
+ mutex_lock(&ide_cd_mutex);
cdrom_release(&info->devinfo, mode);
ide_cd_put(info);
- unlock_kernel();
+ mutex_unlock(&ide_cd_mutex);
return 0;
}
@@ -1694,9 +1694,9 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
{
int ret;
- lock_kernel();
+ mutex_lock(&ide_cd_mutex);
ret = idecd_locked_ioctl(bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ide_cd_mutex);
return ret;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 7433e07de30e..274798068a54 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -435,12 +435,11 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
if (!(rq->cmd_flags & REQ_FLUSH))
return BLKPREP_OK;
- cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
+ cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
/* FIXME: map struct ide_taskfile on rq->cmd[] */
BUG_ON(cmd == NULL);
- memset(cmd, 0, sizeof(*cmd));
if (ata_id_flush_ext_enabled(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
cmd->tf.command = ATA_CMD_FLUSH_EXT;
@@ -516,10 +515,10 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
return ide_no_data_taskfile(drive, &cmd);
}
-static void update_ordered(ide_drive_t *drive)
+static void update_flush(ide_drive_t *drive)
{
u16 *id = drive->id;
- unsigned ordered = QUEUE_ORDERED_NONE;
+ unsigned flush = 0;
if (drive->dev_flags & IDE_DFLAG_WCACHE) {
unsigned long long capacity;
@@ -543,13 +542,12 @@ static void update_ordered(ide_drive_t *drive)
drive->name, barrier ? "" : "not ");
if (barrier) {
- ordered = QUEUE_ORDERED_DRAIN_FLUSH;
+ flush = REQ_FLUSH;
blk_queue_prep_rq(drive->queue, idedisk_prep_fn);
}
- } else
- ordered = QUEUE_ORDERED_DRAIN;
+ }
- blk_queue_ordered(drive->queue, ordered);
+ blk_queue_flush(drive->queue, flush);
}
ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE);
@@ -572,7 +570,7 @@ static int set_wcache(ide_drive_t *drive, int arg)
}
}
- update_ordered(drive);
+ update_flush(drive);
return err;
}
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c
index ec94c66918f6..da36f729ff32 100644
--- a/drivers/ide/ide-disk_ioctl.c
+++ b/drivers/ide/ide-disk_ioctl.c
@@ -1,10 +1,11 @@
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/hdreg.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include "ide-disk.h"
+static DEFINE_MUTEX(ide_disk_ioctl_mutex);
static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address },
{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount },
@@ -19,13 +20,13 @@ int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode,
{
int err;
- lock_kernel();
+ mutex_lock(&ide_disk_ioctl_mutex);
err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
if (err != -EOPNOTSUPP)
goto out;
err = generic_ide_ioctl(drive, bdev, cmd, arg);
out:
- unlock_kernel();
+ mutex_unlock(&ide_disk_ioctl_mutex);
return err;
}
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index fd3d05ab3417..d267b7affad6 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -5,7 +5,7 @@
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/cdrom.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/unaligned.h>
@@ -32,6 +32,7 @@
* On exit we set nformats to the number of records we've actually initialized.
*/
+static DEFINE_MUTEX(ide_floppy_ioctl_mutex);
static int ide_floppy_get_format_capacities(ide_drive_t *drive,
struct ide_atapi_pc *pc,
int __user *arg)
@@ -276,7 +277,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
void __user *argp = (void __user *)arg;
int err;
- lock_kernel();
+ mutex_lock(&ide_floppy_ioctl_mutex);
if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) {
err = ide_floppy_lockdoor(drive, &pc, arg, cmd);
goto out;
@@ -298,6 +299,6 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
err = generic_ide_ioctl(drive, bdev, cmd, arg);
out:
- unlock_kernel();
+ mutex_unlock(&ide_floppy_ioctl_mutex);
return err;
}
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 70aeeb18833e..35c4b43585e3 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -1,4 +1,3 @@
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -23,6 +22,7 @@
#define IDE_GD_VERSION "1.18"
/* module parameters */
+static DEFINE_MUTEX(ide_gd_mutex);
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -242,9 +242,9 @@ static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&ide_gd_mutex);
ret = ide_gd_open(bdev, mode);
- unlock_kernel();
+ mutex_unlock(&ide_gd_mutex);
return ret;
}
@@ -257,7 +257,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
ide_debug_log(IDE_DBG_FUNC, "enter");
- lock_kernel();
+ mutex_lock(&ide_gd_mutex);
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
@@ -269,7 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
idkp->openers--;
ide_disk_put(idkp);
- unlock_kernel();
+ mutex_unlock(&ide_gd_mutex);
return 0;
}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index a381be814070..999dac054bcc 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -441,19 +441,6 @@ void do_ide_request(struct request_queue *q)
struct request *rq = NULL;
ide_startstop_t startstop;
- /*
- * drive is doing pre-flush, ordered write, post-flush sequence. even
- * though that is 3 requests, it must be seen as a single transaction.
- * we must not preempt this drive until that is complete
- */
- if (blk_queue_flushing(q))
- /*
- * small race where queue could get replugged during
- * the 3-request flush cycle, just yank the plug since
- * we want it to finish asap
- */
- blk_remove_plug(q);
-
spin_unlock_irq(q->queue_lock);
/* HLD do_request() callback might sleep, make sure it's okay */
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 6d622cb5ac81..31c6775c0de8 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -32,11 +32,9 @@
#include <linux/errno.h>
#include <linux/genhd.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/ide.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
@@ -220,6 +218,7 @@ typedef struct ide_tape_obj {
char write_prot;
} idetape_tape_t;
+static DEFINE_MUTEX(ide_tape_mutex);
static DEFINE_MUTEX(idetape_ref_mutex);
static DEFINE_MUTEX(idetape_chrdev_mutex);
@@ -1426,9 +1425,9 @@ static long idetape_chrdev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&ide_tape_mutex);
ret = do_idetape_chrdev_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ide_tape_mutex);
return ret;
}
@@ -1903,15 +1902,16 @@ static const struct file_operations idetape_fops = {
.unlocked_ioctl = idetape_chrdev_ioctl,
.open = idetape_chrdev_open,
.release = idetape_chrdev_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int idetape_open(struct block_device *bdev, fmode_t mode)
{
struct ide_tape_obj *tape;
- lock_kernel();
+ mutex_lock(&ide_tape_mutex);
tape = ide_tape_get(bdev->bd_disk, false, 0);
- unlock_kernel();
+ mutex_unlock(&ide_tape_mutex);
if (!tape)
return -ENXIO;
@@ -1923,9 +1923,9 @@ static int idetape_release(struct gendisk *disk, fmode_t mode)
{
struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj);
- lock_kernel();
+ mutex_lock(&ide_tape_mutex);
ide_tape_put(tape);
- unlock_kernel();
+ mutex_unlock(&ide_tape_mutex);
return 0;
}
@@ -1937,11 +1937,11 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
ide_drive_t *drive = tape->drive;
int err;
- lock_kernel();
+ mutex_lock(&ide_tape_mutex);
err = generic_ide_ioctl(drive, bdev, cmd, arg);
if (err == -EINVAL)
err = idetape_blkdev_ioctl(drive, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ide_tape_mutex);
return err;
}
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index 15341fc1c68b..bc599304c3cf 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -536,6 +536,7 @@ static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
static const struct file_operations idle_fops = {
.open = stats_open_generic,
.read = stats_read_ul,
+ .llseek = default_llseek,/* read accesses f_pos */
};
struct debugfs_file_info {
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index bc289e367e30..63403822330e 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -58,7 +58,6 @@
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>
-#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/unaligned.h>
@@ -173,8 +172,6 @@ static netdev_tx_t ether1394_tx(struct sk_buff *skb,
struct net_device *dev);
static void ether1394_iso(struct hpsb_iso *iso);
-static const struct ethtool_ops ethtool_ops;
-
static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
quadlet_t *data, u64 addr, size_t len, u16 flags);
static void ether1394_add_host(struct hpsb_host *host);
@@ -525,8 +522,6 @@ static void ether1394_init_dev(struct net_device *dev)
dev->header_ops = &ether1394_header_ops;
dev->netdev_ops = &ether1394_netdev_ops;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
-
dev->watchdog_timeo = ETHER1394_TIMEOUT;
dev->flags = IFF_BROADCAST | IFF_MULTICAST;
dev->features = NETIF_F_HIGHDMA;
@@ -1695,17 +1690,6 @@ fail:
return NETDEV_TX_OK;
}
-static void ether1394_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, driver_name);
- strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */
-}
-
-static const struct ethtool_ops ethtool_ops = {
- .get_drvinfo = ether1394_get_drvinfo
-};
-
static int __init ether1394_init_module(void)
{
int err;
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 8f0caf7d4482..78fbe9ffe7f0 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -53,7 +53,7 @@
#define T3_MAX_PBL_SIZE 256
#define T3_MAX_RQ_SIZE 1024
#define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1)
-#define T3_MAX_CQ_DEPTH 262144
+#define T3_MAX_CQ_DEPTH 65536
#define T3_MAX_NUM_STAG (1<<15)
#define T3_MAX_MR_SIZE 0x100000000ULL
#define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 32d352a88d50..ea54c6ae23bf 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -2323,7 +2323,7 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
switch (rpl->type) {
case 1:
ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);
- wr_waitp = (__force struct c4iw_wr_wait *)rpl->data[1];
+ wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];
PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);
if (wr_waitp) {
wr_waitp->ret = ret;
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index b3daf39eed4a..af684fca4a82 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -55,7 +55,7 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
V_FW_RI_RES_WR_NRES(1) |
FW_WR_COMPL(1));
res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16));
- res_wr->cookie = (u64)&wr_wait;
+ res_wr->cookie = (unsigned long) &wr_wait;
res = res_wr->res;
res->u.cq.restype = FW_RI_RES_TYPE_CQ;
res->u.cq.op = FW_RI_RES_OP_RESET;
@@ -132,7 +132,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
V_FW_RI_RES_WR_NRES(1) |
FW_WR_COMPL(1));
res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16));
- res_wr->cookie = (u64)&wr_wait;
+ res_wr->cookie = (unsigned long) &wr_wait;
res = res_wr->res;
res->u.cq.restype = FW_RI_RES_TYPE_CQ;
res->u.cq.op = FW_RI_RES_OP_WRITE;
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 9bbf491d5d9e..308498cc3789 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -186,6 +186,7 @@ static const struct file_operations qp_debugfs_fops = {
.open = qp_open,
.release = qp_release,
.read = qp_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int setup_debugfs(struct c4iw_dev *devp)
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 269373a62f22..f61562cc7413 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -71,7 +71,7 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len,
if (i == (num_wqe-1)) {
req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) |
FW_WR_COMPL(1));
- req->wr.wr_lo = (__force __be64)&wr_wait;
+ req->wr.wr_lo = (__force __be64)(unsigned long) &wr_wait;
} else
req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR));
req->wr.wr_mid = cpu_to_be32(
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 93f6e5bf0ec5..5d11f8601599 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -144,7 +144,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
V_FW_RI_RES_WR_NRES(2) |
FW_WR_COMPL(1));
res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16));
- res_wr->cookie = (u64)&wr_wait;
+ res_wr->cookie = (unsigned long) &wr_wait;
res = res_wr->res;
res->u.sqrq.restype = FW_RI_RES_TYPE_SQ;
res->u.sqrq.op = FW_RI_RES_OP_WRITE;
@@ -985,7 +985,7 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
wqe->flowid_len16 = cpu_to_be32(
FW_WR_FLOWID(ep->hwtid) |
FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16)));
- wqe->cookie = (u64)&wr_wait;
+ wqe->cookie = (unsigned long) &wr_wait;
wqe->u.fini.type = FW_RI_TYPE_FINI;
c4iw_init_wr_wait(&wr_wait);
@@ -1060,7 +1060,7 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
FW_WR_FLOWID(qhp->ep->hwtid) |
FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16)));
- wqe->cookie = (u64)&wr_wait;
+ wqe->cookie = (unsigned long) &wr_wait;
wqe->u.init.type = FW_RI_TYPE_INIT;
wqe->u.init.mpareqbit_p2ptype =
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index d4ce8b63e19e..ad76f68b53c7 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -65,7 +65,8 @@ static const struct file_operations diag_file_ops = {
.write = ipath_diag_write,
.read = ipath_diag_read,
.open = ipath_diag_open,
- .release = ipath_diag_release
+ .release = ipath_diag_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t ipath_diagpkt_write(struct file *fp,
@@ -75,6 +76,7 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
static const struct file_operations diagpkt_file_ops = {
.owner = THIS_MODULE,
.write = ipath_diagpkt_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static atomic_t diagpkt_count = ATOMIC_INIT(0);
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 65eb8929db22..69c1dccec3d9 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -63,7 +63,8 @@ static const struct file_operations ipath_file_ops = {
.open = ipath_open,
.release = ipath_close,
.poll = ipath_poll,
- .mmap = ipath_mmap
+ .mmap = ipath_mmap,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
/*
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 2fca70836dae..3ce1f68e12bd 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -103,6 +103,7 @@ static ssize_t atomic_stats_read(struct file *file, char __user *buf,
static const struct file_operations atomic_stats_ops = {
.read = atomic_stats_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t atomic_counters_read(struct file *file, char __user *buf,
@@ -120,6 +121,7 @@ static ssize_t atomic_counters_read(struct file *file, char __user *buf,
static const struct file_operations atomic_counters_ops = {
.read = atomic_counters_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t flash_read(struct file *file, char __user *buf,
@@ -224,6 +226,7 @@ bail:
static const struct file_operations flash_ops = {
.read = flash_read,
.write = flash_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int create_device_files(struct super_block *sb,
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 443cea55daac..61e0efd4ccfb 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -502,7 +502,9 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
static void nes_retrans_expired(struct nes_cm_node *cm_node)
{
struct iw_cm_id *cm_id = cm_node->cm_id;
- switch (cm_node->state) {
+ enum nes_cm_node_state state = cm_node->state;
+ cm_node->state = NES_CM_STATE_CLOSED;
+ switch (state) {
case NES_CM_STATE_SYN_RCVD:
case NES_CM_STATE_CLOSING:
rem_ref_cm_node(cm_node->cm_core, cm_node);
@@ -511,7 +513,6 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node)
case NES_CM_STATE_FIN_WAIT1:
if (cm_node->cm_id)
cm_id->rem_ref(cm_id);
- cm_node->state = NES_CM_STATE_CLOSED;
send_reset(cm_node, NULL);
break;
default:
@@ -1439,9 +1440,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
break;
case NES_CM_STATE_MPAREQ_RCVD:
passive_state = atomic_add_return(1, &cm_node->passive_state);
- if (passive_state == NES_SEND_RESET_EVENT)
- create_event(cm_node, NES_CM_EVENT_RESET);
- cm_node->state = NES_CM_STATE_CLOSED;
dev_kfree_skb_any(skb);
break;
case NES_CM_STATE_ESTABLISHED:
@@ -1456,6 +1454,7 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
case NES_CM_STATE_CLOSED:
drop_packet(skb);
break;
+ case NES_CM_STATE_FIN_WAIT2:
case NES_CM_STATE_FIN_WAIT1:
case NES_CM_STATE_LAST_ACK:
cm_node->cm_id->rem_ref(cm_node->cm_id);
@@ -2777,6 +2776,12 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
return -EINVAL;
}
+ passive_state = atomic_add_return(1, &cm_node->passive_state);
+ if (passive_state == NES_SEND_RESET_EVENT) {
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ return -ECONNRESET;
+ }
+
/* associate the node with the QP */
nesqp->cm_node = (void *)cm_node;
cm_node->nesqp = nesqp;
@@ -2979,9 +2984,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
"ret=%d\n", __func__, __LINE__, ret);
- passive_state = atomic_add_return(1, &cm_node->passive_state);
- if (passive_state == NES_SEND_RESET_EVENT)
- create_event(cm_node, NES_CM_EVENT_RESET);
return 0;
}
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index f8233c851c69..1980a461c499 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -3468,6 +3468,19 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
return; /* Ignore it, wait for close complete */
if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
+ if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) &&
+ (nesqp->ibqp_state == IB_QPS_RTS) &&
+ ((nesadapter->eeprom_version >> 16) != NES_A0)) {
+ spin_lock_irqsave(&nesqp->lock, flags);
+ nesqp->hw_iwarp_state = iwarp_state;
+ nesqp->hw_tcp_state = tcp_state;
+ nesqp->last_aeq = async_event_id;
+ next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
+ nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
+ spin_unlock_irqrestore(&nesqp->lock, flags);
+ nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
+ nes_cm_disconn(nesqp);
+ }
nesqp->cm_id->add_ref(nesqp->cm_id);
schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
NES_TIMER_TYPE_CLOSE, 1, 0);
@@ -3477,7 +3490,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
async_event_id, nesqp->last_aeq, tcp_state);
}
-
break;
case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
if (nesqp->term_flags) {
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index aa9183db32b1..1204c3432b63 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -45,6 +45,7 @@
#define NES_PHY_TYPE_KR 9
#define NES_MULTICAST_PF_MAX 8
+#define NES_A0 3
enum pci_regs {
NES_INT_STAT = 0x0000,
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 6dfdd49cdbcf..10560c796fd6 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1446,14 +1446,14 @@ static int nes_netdev_set_pauseparam(struct net_device *netdev,
NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200));
u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
nes_write_indexed(nesdev,
- NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp);
+ NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200), u32temp);
nesdev->disable_tx_flow_control = 0;
} else if ((et_pauseparam->tx_pause == 0) && (nesdev->disable_tx_flow_control == 0)) {
u32temp = nes_read_indexed(nesdev,
NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200));
u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
nes_write_indexed(nesdev,
- NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp);
+ NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200), u32temp);
nesdev->disable_tx_flow_control = 1;
}
if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control == 1)) {
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 9046e6675686..b89972c6a357 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -476,9 +476,9 @@ static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list(
}
nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, "
"ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, "
- "pbl.paddr= %p\n", pnesfrpl, &pnesfrpl->ibfrpl,
+ "pbl.paddr = %llx\n", pnesfrpl, &pnesfrpl->ibfrpl,
pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva,
- (void *)pnesfrpl->nes_wqe_pbl.paddr);
+ (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr);
return pifrpl;
}
@@ -3483,13 +3483,13 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++)
dst_page_list[i] = cpu_to_le64(src_page_list[i]);
- nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %p, "
- "length: %d, rkey: %0x, pgl_paddr: %p, "
+ nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %llx, "
+ "length: %d, rkey: %0x, pgl_paddr: %llx, "
"page_list_len: %u, wqe_misc: %x\n",
- (void *)ib_wr->wr.fast_reg.iova_start,
+ (unsigned long long) ib_wr->wr.fast_reg.iova_start,
ib_wr->wr.fast_reg.length,
ib_wr->wr.fast_reg.rkey,
- (void *)pnesfrpl->nes_wqe_pbl.paddr,
+ (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr,
ib_wr->wr.fast_reg.page_list_len,
wqe_misc);
break;
diff --git a/drivers/infiniband/hw/qib/qib_diag.c b/drivers/infiniband/hw/qib/qib_diag.c
index 05dcf0d9a7d3..edd941d2e9ed 100644
--- a/drivers/infiniband/hw/qib/qib_diag.c
+++ b/drivers/infiniband/hw/qib/qib_diag.c
@@ -136,7 +136,8 @@ static const struct file_operations diag_file_ops = {
.write = qib_diag_write,
.read = qib_diag_read,
.open = qib_diag_open,
- .release = qib_diag_release
+ .release = qib_diag_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static atomic_t diagpkt_count = ATOMIC_INIT(0);
@@ -149,6 +150,7 @@ static ssize_t qib_diagpkt_write(struct file *fp, const char __user *data,
static const struct file_operations diagpkt_file_ops = {
.owner = THIS_MODULE,
.write = qib_diagpkt_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
int qib_diag_add(struct qib_devdata *dd)
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index 6b11645edf35..cfc8281292be 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -63,7 +63,8 @@ static const struct file_operations qib_file_ops = {
.open = qib_open,
.release = qib_close,
.poll = qib_poll,
- .mmap = qib_mmapf
+ .mmap = qib_mmapf,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
/*
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index 9f989c0ba9d3..c11f205bd699 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -367,6 +367,7 @@ bail:
static const struct file_operations flash_ops = {
.read = flash_read,
.write = flash_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int add_cntr_files(struct super_block *sb, struct qib_devdata *dd)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index c908c5f83645..90d0a88fa7c3 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -28,7 +28,7 @@ struct evdev {
int minor;
struct input_handle handle;
wait_queue_head_t wait;
- struct evdev_client *grab;
+ struct evdev_client __rcu *grab;
struct list_head client_list;
spinlock_t client_lock; /* protects client_list */
struct mutex mutex;
@@ -534,6 +534,80 @@ static int handle_eviocgbit(struct input_dev *dev,
}
#undef OLD_KEY_MAX
+static int evdev_handle_get_keycode(struct input_dev *dev,
+ void __user *p, size_t size)
+{
+ struct input_keymap_entry ke;
+ int error;
+
+ memset(&ke, 0, sizeof(ke));
+
+ if (size == sizeof(unsigned int[2])) {
+ /* legacy case */
+ int __user *ip = (int __user *)p;
+
+ if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+ return -EFAULT;
+
+ ke.len = sizeof(unsigned int);
+ ke.flags = 0;
+
+ error = input_get_keycode(dev, &ke);
+ if (error)
+ return error;
+
+ if (put_user(ke.keycode, ip + 1))
+ return -EFAULT;
+
+ } else {
+ size = min(size, sizeof(ke));
+
+ if (copy_from_user(&ke, p, size))
+ return -EFAULT;
+
+ error = input_get_keycode(dev, &ke);
+ if (error)
+ return error;
+
+ if (copy_to_user(p, &ke, size))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int evdev_handle_set_keycode(struct input_dev *dev,
+ void __user *p, size_t size)
+{
+ struct input_keymap_entry ke;
+
+ memset(&ke, 0, sizeof(ke));
+
+ if (size == sizeof(unsigned int[2])) {
+ /* legacy case */
+ int __user *ip = (int __user *)p;
+
+ if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+ return -EFAULT;
+
+ if (get_user(ke.keycode, ip + 1))
+ return -EFAULT;
+
+ ke.len = sizeof(unsigned int);
+ ke.flags = 0;
+
+ } else {
+ size = min(size, sizeof(ke));
+
+ if (copy_from_user(&ke, p, size))
+ return -EFAULT;
+
+ if (ke.len > sizeof(ke.scancode))
+ return -EINVAL;
+ }
+
+ return input_set_keycode(dev, &ke);
+}
+
static long evdev_do_ioctl(struct file *file, unsigned int cmd,
void __user *p, int compat_mode)
{
@@ -580,25 +654,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return 0;
- case EVIOCGKEYCODE:
- if (get_user(t, ip))
- return -EFAULT;
-
- error = input_get_keycode(dev, t, &v);
- if (error)
- return error;
-
- if (put_user(v, ip + 1))
- return -EFAULT;
-
- return 0;
-
- case EVIOCSKEYCODE:
- if (get_user(t, ip) || get_user(v, ip + 1))
- return -EFAULT;
-
- return input_set_keycode(dev, t, v);
-
case EVIOCRMFF:
return input_ff_erase(dev, (int)(unsigned long) p, file);
@@ -620,7 +675,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
/* Now check variable-length commands */
#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
-
switch (EVIOC_MASK_SIZE(cmd)) {
case EVIOCGKEY(0):
@@ -654,6 +708,12 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
return error;
+
+ case EVIOC_MASK_SIZE(EVIOCGKEYCODE):
+ return evdev_handle_get_keycode(dev, p, size);
+
+ case EVIOC_MASK_SIZE(EVIOCSKEYCODE):
+ return evdev_handle_set_keycode(dev, p, size);
}
/* Multi-number variable-length handlers */
@@ -761,7 +821,8 @@ static const struct file_operations evdev_fops = {
.compat_ioctl = evdev_ioctl_compat,
#endif
.fasync = evdev_fasync,
- .flush = evdev_flush
+ .flush = evdev_flush,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int evdev_install_chrdev(struct evdev *evdev)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a9b025f4147a..22917f41b5cc 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -171,7 +171,7 @@ static int input_handle_abs_event(struct input_dev *dev,
if (code == ABS_MT_SLOT) {
/*
* "Stage" the event; we'll flush it later, when we
- * get actiual touch data.
+ * get actual touch data.
*/
if (*pval >= 0 && *pval < dev->mtsize)
dev->slot = *pval;
@@ -188,7 +188,7 @@ static int input_handle_abs_event(struct input_dev *dev,
pold = &mtslot->abs[code - ABS_MT_FIRST];
} else {
/*
- * Bypass filtering for multitouch events when
+ * Bypass filtering for multi-touch events when
* not employing slots.
*/
pold = NULL;
@@ -634,78 +634,141 @@ static void input_disconnect_device(struct input_dev *dev)
spin_unlock_irq(&dev->event_lock);
}
-static int input_fetch_keycode(struct input_dev *dev, int scancode)
+/**
+ * input_scancode_to_scalar() - converts scancode in &struct input_keymap_entry
+ * @ke: keymap entry containing scancode to be converted.
+ * @scancode: pointer to the location where converted scancode should
+ * be stored.
+ *
+ * This function is used to convert scancode stored in &struct keymap_entry
+ * into scalar form understood by legacy keymap handling methods. These
+ * methods expect scancodes to be represented as 'unsigned int'.
+ */
+int input_scancode_to_scalar(const struct input_keymap_entry *ke,
+ unsigned int *scancode)
+{
+ switch (ke->len) {
+ case 1:
+ *scancode = *((u8 *)ke->scancode);
+ break;
+
+ case 2:
+ *scancode = *((u16 *)ke->scancode);
+ break;
+
+ case 4:
+ *scancode = *((u32 *)ke->scancode);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(input_scancode_to_scalar);
+
+/*
+ * Those routines handle the default case where no [gs]etkeycode() is
+ * defined. In this case, an array indexed by the scancode is used.
+ */
+
+static unsigned int input_fetch_keycode(struct input_dev *dev,
+ unsigned int index)
{
switch (dev->keycodesize) {
- case 1:
- return ((u8 *)dev->keycode)[scancode];
+ case 1:
+ return ((u8 *)dev->keycode)[index];
- case 2:
- return ((u16 *)dev->keycode)[scancode];
+ case 2:
+ return ((u16 *)dev->keycode)[index];
- default:
- return ((u32 *)dev->keycode)[scancode];
+ default:
+ return ((u32 *)dev->keycode)[index];
}
}
static int input_default_getkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int *keycode)
+ struct input_keymap_entry *ke)
{
+ unsigned int index;
+ int error;
+
if (!dev->keycodesize)
return -EINVAL;
- if (scancode >= dev->keycodemax)
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX)
+ index = ke->index;
+ else {
+ error = input_scancode_to_scalar(ke, &index);
+ if (error)
+ return error;
+ }
+
+ if (index >= dev->keycodemax)
return -EINVAL;
- *keycode = input_fetch_keycode(dev, scancode);
+ ke->keycode = input_fetch_keycode(dev, index);
+ ke->index = index;
+ ke->len = sizeof(index);
+ memcpy(ke->scancode, &index, sizeof(index));
return 0;
}
static int input_default_setkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int keycode)
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
{
- int old_keycode;
+ unsigned int index;
+ int error;
int i;
- if (scancode >= dev->keycodemax)
+ if (!dev->keycodesize)
return -EINVAL;
- if (!dev->keycodesize)
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ } else {
+ error = input_scancode_to_scalar(ke, &index);
+ if (error)
+ return error;
+ }
+
+ if (index >= dev->keycodemax)
return -EINVAL;
- if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
+ if (dev->keycodesize < sizeof(dev->keycode) &&
+ (ke->keycode >> (dev->keycodesize * 8)))
return -EINVAL;
switch (dev->keycodesize) {
case 1: {
u8 *k = (u8 *)dev->keycode;
- old_keycode = k[scancode];
- k[scancode] = keycode;
+ *old_keycode = k[index];
+ k[index] = ke->keycode;
break;
}
case 2: {
u16 *k = (u16 *)dev->keycode;
- old_keycode = k[scancode];
- k[scancode] = keycode;
+ *old_keycode = k[index];
+ k[index] = ke->keycode;
break;
}
default: {
u32 *k = (u32 *)dev->keycode;
- old_keycode = k[scancode];
- k[scancode] = keycode;
+ *old_keycode = k[index];
+ k[index] = ke->keycode;
break;
}
}
- __clear_bit(old_keycode, dev->keybit);
- __set_bit(keycode, dev->keybit);
+ __clear_bit(*old_keycode, dev->keybit);
+ __set_bit(ke->keycode, dev->keybit);
for (i = 0; i < dev->keycodemax; i++) {
- if (input_fetch_keycode(dev, i) == old_keycode) {
- __set_bit(old_keycode, dev->keybit);
+ if (input_fetch_keycode(dev, i) == *old_keycode) {
+ __set_bit(*old_keycode, dev->keybit);
break; /* Setting the bit twice is useless, so break */
}
}
@@ -716,53 +779,86 @@ static int input_default_setkeycode(struct input_dev *dev,
/**
* input_get_keycode - retrieve keycode currently mapped to a given scancode
* @dev: input device which keymap is being queried
- * @scancode: scancode (or its equivalent for device in question) for which
- * keycode is needed
- * @keycode: result
+ * @ke: keymap entry
*
* This function should be called by anyone interested in retrieving current
- * keymap. Presently keyboard and evdev handlers use it.
+ * keymap. Presently evdev handlers use it.
*/
-int input_get_keycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
+int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke)
{
unsigned long flags;
int retval;
spin_lock_irqsave(&dev->event_lock, flags);
- retval = dev->getkeycode(dev, scancode, keycode);
- spin_unlock_irqrestore(&dev->event_lock, flags);
+ if (dev->getkeycode) {
+ /*
+ * Support for legacy drivers, that don't implement the new
+ * ioctls
+ */
+ u32 scancode = ke->index;
+
+ memcpy(ke->scancode, &scancode, sizeof(scancode));
+ ke->len = sizeof(scancode);
+ retval = dev->getkeycode(dev, scancode, &ke->keycode);
+ } else {
+ retval = dev->getkeycode_new(dev, ke);
+ }
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
return retval;
}
EXPORT_SYMBOL(input_get_keycode);
/**
- * input_get_keycode - assign new keycode to a given scancode
+ * input_set_keycode - attribute a keycode to a given scancode
* @dev: input device which keymap is being updated
- * @scancode: scancode (or its equivalent for device in question)
- * @keycode: new keycode to be assigned to the scancode
+ * @ke: new keymap entry
*
* This function should be called by anyone needing to update current
* keymap. Presently keyboard and evdev handlers use it.
*/
int input_set_keycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
+ const struct input_keymap_entry *ke)
{
unsigned long flags;
unsigned int old_keycode;
int retval;
- if (keycode > KEY_MAX)
+ if (ke->keycode > KEY_MAX)
return -EINVAL;
spin_lock_irqsave(&dev->event_lock, flags);
- retval = dev->getkeycode(dev, scancode, &old_keycode);
- if (retval)
- goto out;
+ if (dev->setkeycode) {
+ /*
+ * Support for legacy drivers, that don't implement the new
+ * ioctls
+ */
+ unsigned int scancode;
+
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ /*
+ * We need to know the old scancode, in order to generate a
+ * keyup effect, if the set operation happens successfully
+ */
+ if (!dev->getkeycode) {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ retval = dev->getkeycode(dev, scancode, &old_keycode);
+ if (retval)
+ goto out;
+
+ retval = dev->setkeycode(dev, scancode, ke->keycode);
+ } else {
+ retval = dev->setkeycode_new(dev, ke, &old_keycode);
+ }
- retval = dev->setkeycode(dev, scancode, keycode);
if (retval)
goto out;
@@ -1599,11 +1695,14 @@ EXPORT_SYMBOL(input_free_device);
* @dev: input device supporting MT events and finger tracking
* @num_slots: number of slots used by the device
*
- * This function allocates all necessary memory for MT slot handling
- * in the input device, and adds ABS_MT_SLOT to the device capabilities.
+ * This function allocates all necessary memory for MT slot handling in the
+ * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
+ * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
*/
int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
{
+ int i;
+
if (!num_slots)
return 0;
@@ -1614,6 +1713,10 @@ int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
dev->mtsize = num_slots;
input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+ /* Mark slots as 'unused' */
+ for (i = 0; i < num_slots; i++)
+ dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1;
+
return 0;
}
EXPORT_SYMBOL(input_mt_create_slots);
@@ -1752,11 +1855,11 @@ int input_register_device(struct input_dev *dev)
dev->rep[REP_PERIOD] = 33;
}
- if (!dev->getkeycode)
- dev->getkeycode = input_default_getkeycode;
+ if (!dev->getkeycode && !dev->getkeycode_new)
+ dev->getkeycode_new = input_default_getkeycode;
- if (!dev->setkeycode)
- dev->setkeycode = input_default_setkeycode;
+ if (!dev->setkeycode && !dev->setkeycode_new)
+ dev->setkeycode_new = input_default_setkeycode;
dev_set_name(&dev->dev, "input%ld",
(unsigned long) atomic_inc_return(&input_no) - 1);
@@ -2040,6 +2143,7 @@ out:
static const struct file_operations input_fops = {
.owner = THIS_MODULE,
.open = input_open_file,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int __init input_init(void)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index d85bd8a7967d..9ea20725d5e3 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -736,6 +736,7 @@ static const struct file_operations joydev_fops = {
.compat_ioctl = joydev_compat_ioctl,
#endif
.fasync = joydev_fasync,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int joydev_install_chrdev(struct joydev *joydev)
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9cc488d21490..4f300488e1f3 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -424,6 +424,15 @@ config KEYBOARD_OMAP
To compile this driver as a module, choose M here: the
module will be called omap-keypad.
+config KEYBOARD_OMAP4
+ tristate "TI OMAP4 keypad support"
+ depends on ARCH_OMAP4
+ help
+ Say Y here if you want to use the OMAP4 keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called omap4-keypad.
+
config KEYBOARD_TWL4030
tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 504b591be0cd..8ac01fb642c1 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o
obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
new file mode 100644
index 000000000000..975f8bbcc69b
--- /dev/null
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -0,0 +1,287 @@
+/*
+ * OMAP4 Keypad Driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * Author: Abraham Arce <x0066660@ti.com>
+ * Initial Code: Syed Rafiuddin <rafiuddin.syed@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+
+#include <plat/omap4-keypad.h>
+
+/* OMAP4 registers */
+#define OMAP4_KBD_REVISION 0x00
+#define OMAP4_KBD_SYSCONFIG 0x10
+#define OMAP4_KBD_SYSSTATUS 0x14
+#define OMAP4_KBD_IRQSTATUS 0x18
+#define OMAP4_KBD_IRQENABLE 0x1C
+#define OMAP4_KBD_WAKEUPENABLE 0x20
+#define OMAP4_KBD_PENDING 0x24
+#define OMAP4_KBD_CTRL 0x28
+#define OMAP4_KBD_DEBOUNCINGTIME 0x2C
+#define OMAP4_KBD_LONGKEYTIME 0x30
+#define OMAP4_KBD_TIMEOUT 0x34
+#define OMAP4_KBD_STATEMACHINE 0x38
+#define OMAP4_KBD_ROWINPUTS 0x3C
+#define OMAP4_KBD_COLUMNOUTPUTS 0x40
+#define OMAP4_KBD_FULLCODE31_0 0x44
+#define OMAP4_KBD_FULLCODE63_32 0x48
+
+/* OMAP4 bit definitions */
+#define OMAP4_DEF_SYSCONFIG_SOFTRST (1 << 1)
+#define OMAP4_DEF_SYSCONFIG_ENAWKUP (1 << 2)
+#define OMAP4_DEF_IRQENABLE_EVENTEN (1 << 0)
+#define OMAP4_DEF_IRQENABLE_LONGKEY (1 << 1)
+#define OMAP4_DEF_IRQENABLE_TIMEOUTEN (1 << 2)
+#define OMAP4_DEF_CTRL_NOSOFTMODE (1 << 1)
+#define OMAP4_DEF_CTRLPTVVALUE (1 << 2)
+#define OMAP4_DEF_CTRLPTV (1 << 1)
+#define OMAP4_DEF_IRQDISABLE 0x00
+
+/* OMAP4 values */
+#define OMAP4_VAL_DEBOUNCINGTIME 0x07
+#define OMAP4_VAL_FUNCTIONALCFG 0x1E
+
+#define OMAP4_MASK_IRQSTATUSDISABLE 0xFFFF
+
+struct omap4_keypad {
+ struct input_dev *input;
+
+ void __iomem *base;
+ int irq;
+
+ unsigned int rows;
+ unsigned int cols;
+ unsigned int row_shift;
+ unsigned char key_state[8];
+ unsigned short keymap[];
+};
+
+static void __devinit omap4_keypad_config(struct omap4_keypad *keypad_data)
+{
+ __raw_writel(OMAP4_DEF_SYSCONFIG_SOFTRST | OMAP4_DEF_SYSCONFIG_ENAWKUP,
+ keypad_data->base + OMAP4_KBD_SYSCONFIG);
+ __raw_writel(OMAP4_VAL_FUNCTIONALCFG,
+ keypad_data->base + OMAP4_KBD_CTRL);
+ __raw_writel(OMAP4_VAL_DEBOUNCINGTIME,
+ keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME);
+ __raw_writel(OMAP4_DEF_IRQDISABLE,
+ keypad_data->base + OMAP4_KBD_IRQSTATUS);
+ __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
+ keypad_data->base + OMAP4_KBD_IRQENABLE);
+}
+
+/* Interrupt handler */
+static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id)
+{
+ struct omap4_keypad *keypad_data = dev_id;
+ struct input_dev *input_dev = keypad_data->input;
+ unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)];
+ unsigned int col, row, code, changed;
+ u32 *new_state = (u32 *) key_state;
+
+ /* Disable interrupts */
+ __raw_writel(OMAP4_DEF_IRQDISABLE,
+ keypad_data->base + OMAP4_KBD_IRQENABLE);
+
+ *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0);
+ *(new_state + 1) = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE63_32);
+
+ for (row = 0; row < keypad_data->rows; row++) {
+ changed = key_state[row] ^ keypad_data->key_state[row];
+ if (!changed)
+ continue;
+
+ for (col = 0; col < keypad_data->cols; col++) {
+ if (changed & (1 << col)) {
+ code = MATRIX_SCAN_CODE(row, col,
+ keypad_data->row_shift);
+ input_event(input_dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(input_dev,
+ keypad_data->keymap[code],
+ key_state[row] & (1 << col));
+ }
+ }
+ }
+
+ input_sync(input_dev);
+
+ memcpy(keypad_data->key_state, key_state,
+ sizeof(keypad_data->key_state));
+
+ /* clear pending interrupts */
+ __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS),
+ keypad_data->base + OMAP4_KBD_IRQSTATUS);
+
+ /* enable interrupts */
+ __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY,
+ keypad_data->base + OMAP4_KBD_IRQENABLE);
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit omap4_keypad_probe(struct platform_device *pdev)
+{
+ const struct omap4_keypad_platform_data *pdata;
+ struct omap4_keypad *keypad_data;
+ struct input_dev *input_dev;
+ unsigned int row_shift, max_keys;
+ int error;
+
+ /* platform data */
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data defined\n");
+ return -EINVAL;
+ }
+
+ if (!pdata->base) {
+ dev_err(&pdev->dev, "no base address specified\n");
+ return -EINVAL;
+ }
+
+ if (!pdata->irq) {
+ dev_err(&pdev->dev, "no keyboard irq assigned\n");
+ return -EINVAL;
+ }
+
+ if (!pdata->keymap_data) {
+ dev_err(&pdev->dev, "no keymap data defined\n");
+ return -EINVAL;
+ }
+
+ row_shift = get_count_order(pdata->cols);
+ max_keys = pdata->rows << row_shift;
+
+ keypad_data = kzalloc(sizeof(struct omap4_keypad) +
+ max_keys * sizeof(keypad_data->keymap[0]),
+ GFP_KERNEL);
+ if (!keypad_data) {
+ dev_err(&pdev->dev, "keypad_data memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+ keypad_data->base = pdata->base;
+ keypad_data->irq = pdata->irq;
+
+ keypad_data->row_shift = row_shift;
+ keypad_data->rows = pdata->rows;
+ keypad_data->cols = pdata->cols;
+
+ /* input device allocation */
+ keypad_data->input = input_dev = input_allocate_device();
+ if (!input_dev) {
+ error = -ENOMEM;
+ goto err_free_keypad;
+ }
+
+ input_dev->name = pdev->name;
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0001;
+
+ input_dev->keycode = keypad_data->keymap;
+ input_dev->keycodesize = sizeof(keypad_data->keymap[0]);
+ input_dev->keycodemax = max_keys;
+
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_REP, input_dev->evbit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ input_set_drvdata(input_dev, keypad_data);
+
+ matrix_keypad_build_keymap(pdata->keymap_data, row_shift,
+ input_dev->keycode, input_dev->keybit);
+
+ omap4_keypad_config(keypad_data);
+
+ error = request_irq(keypad_data->irq, omap4_keypad_interrupt,
+ IRQF_TRIGGER_FALLING,
+ "omap4-keypad", keypad_data);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register interrupt\n");
+ goto err_free_input;
+ }
+
+ error = input_register_device(keypad_data->input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ goto err_free_irq;
+ }
+
+
+ platform_set_drvdata(pdev, keypad_data);
+ return 0;
+
+err_free_irq:
+ free_irq(keypad_data->irq, keypad_data);
+err_free_input:
+ input_free_device(input_dev);
+err_free_keypad:
+ kfree(keypad_data);
+ return error;
+}
+
+static int __devexit omap4_keypad_remove(struct platform_device *pdev)
+{
+ struct omap4_keypad *keypad_data = platform_get_drvdata(pdev);
+
+ free_irq(keypad_data->irq, keypad_data);
+ input_unregister_device(keypad_data->input);
+ kfree(keypad_data);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver omap4_keypad_driver = {
+ .probe = omap4_keypad_probe,
+ .remove = __devexit_p(omap4_keypad_remove),
+ .driver = {
+ .name = "omap4-keypad",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init omap4_keypad_init(void)
+{
+ return platform_driver_register(&omap4_keypad_driver);
+}
+module_init(omap4_keypad_init);
+
+static void __exit omap4_keypad_exit(void)
+{
+ platform_driver_unregister(&omap4_keypad_driver);
+}
+module_exit(omap4_keypad_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("OMAP4 Keypad Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap4-keypad");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index b49e23379723..b99b8cbde02f 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -22,6 +22,16 @@ config INPUT_88PM860X_ONKEY
To compile this driver as a module, choose M here: the module
will be called 88pm860x_onkey.
+config INPUT_AB8500_PONKEY
+ tristate "AB8500 Pon (PowerOn) Key"
+ depends on AB8500_CORE
+ help
+ Say Y here to use the PowerOn Key for ST-Ericsson's AB8500
+ Mix-Sig PMIC.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ab8500-ponkey.
+
config INPUT_AD714X
tristate "Analog Devices AD714x Capacitance Touch Sensor"
help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 19ccca78fa76..1fe1f6c8b737 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -5,6 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
+obj-$(CONFIG_INPUT_AB8500_PONKEY) += ab8500-ponkey.o
obj-$(CONFIG_INPUT_AD714X) += ad714x.o
obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o
obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c
new file mode 100644
index 000000000000..98f8ede504b8
--- /dev/null
+++ b/drivers/input/misc/ab8500-ponkey.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
+ *
+ * AB8500 Power-On Key handler
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/ab8500.h>
+#include <linux/slab.h>
+
+/**
+ * struct ab8500_ponkey - ab8500 ponkey information
+ * @input_dev: pointer to input device
+ * @ab8500: ab8500 parent
+ * @irq_dbf: irq number for falling transition
+ * @irq_dbr: irq number for rising transition
+ */
+struct ab8500_ponkey {
+ struct input_dev *idev;
+ struct ab8500 *ab8500;
+ int irq_dbf;
+ int irq_dbr;
+};
+
+/* AB8500 gives us an interrupt when ONKEY is held */
+static irqreturn_t ab8500_ponkey_handler(int irq, void *data)
+{
+ struct ab8500_ponkey *ponkey = data;
+
+ if (irq == ponkey->irq_dbf)
+ input_report_key(ponkey->idev, KEY_POWER, true);
+ else if (irq == ponkey->irq_dbr)
+ input_report_key(ponkey->idev, KEY_POWER, false);
+
+ input_sync(ponkey->idev);
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit ab8500_ponkey_probe(struct platform_device *pdev)
+{
+ struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
+ struct ab8500_ponkey *ponkey;
+ struct input_dev *input;
+ int irq_dbf, irq_dbr;
+ int error;
+
+ irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF");
+ if (irq_dbf < 0) {
+ dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf);
+ return irq_dbf;
+ }
+
+ irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR");
+ if (irq_dbr < 0) {
+ dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr);
+ return irq_dbr;
+ }
+
+ ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!ponkey || !input) {
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ ponkey->idev = input;
+ ponkey->ab8500 = ab8500;
+ ponkey->irq_dbf = irq_dbf;
+ ponkey->irq_dbr = irq_dbr;
+
+ input->name = "AB8500 POn(PowerOn) Key";
+ input->dev.parent = &pdev->dev;
+
+ input_set_capability(input, EV_KEY, KEY_POWER);
+
+ error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler,
+ 0, "ab8500-ponkey-dbf", ponkey);
+ if (error < 0) {
+ dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n",
+ ponkey->irq_dbf, error);
+ goto err_free_mem;
+ }
+
+ error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler,
+ 0, "ab8500-ponkey-dbr", ponkey);
+ if (error < 0) {
+ dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n",
+ ponkey->irq_dbr, error);
+ goto err_free_dbf_irq;
+ }
+
+ error = input_register_device(ponkey->idev);
+ if (error) {
+ dev_err(ab8500->dev, "Can't register input device: %d\n", error);
+ goto err_free_dbr_irq;
+ }
+
+ platform_set_drvdata(pdev, ponkey);
+ return 0;
+
+err_free_dbr_irq:
+ free_irq(ponkey->irq_dbf, ponkey);
+err_free_dbf_irq:
+ free_irq(ponkey->irq_dbf, ponkey);
+err_free_mem:
+ input_free_device(input);
+ kfree(ponkey);
+
+ return error;
+}
+
+static int __devexit ab8500_ponkey_remove(struct platform_device *pdev)
+{
+ struct ab8500_ponkey *ponkey = platform_get_drvdata(pdev);
+
+ free_irq(ponkey->irq_dbf, ponkey);
+ free_irq(ponkey->irq_dbr, ponkey);
+ input_unregister_device(ponkey->idev);
+ kfree(ponkey);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ab8500_ponkey_driver = {
+ .driver = {
+ .name = "ab8500-poweron-key",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab8500_ponkey_probe,
+ .remove = __devexit_p(ab8500_ponkey_remove),
+};
+
+static int __init ab8500_ponkey_init(void)
+{
+ return platform_driver_register(&ab8500_ponkey_driver);
+}
+module_init(ab8500_ponkey_init);
+
+static void __exit ab8500_ponkey_exit(void)
+{
+ platform_driver_unregister(&ab8500_ponkey_driver);
+}
+module_exit(ab8500_ponkey_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
+MODULE_DESCRIPTION("ST-Ericsson AB8500 Power-ON(Pon) Key driver");
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index c19066479057..07337061b2eb 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -43,7 +43,7 @@
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/rtc.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/semaphore.h>
MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
@@ -52,6 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL");
#define RTC_VERSION "1.10d"
+static DEFINE_MUTEX(hp_sdc_rtc_mutex);
static unsigned long epoch = 2000;
static struct semaphore i8042tregs;
@@ -665,9 +666,9 @@ static long hp_sdc_rtc_unlocked_ioctl(struct file *file,
{
int ret;
- lock_kernel();
+ mutex_lock(&hp_sdc_rtc_mutex);
ret = hp_sdc_rtc_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&hp_sdc_rtc_mutex);
return ret;
}
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index 4f9b2afc24e8..014dd4ad0d4f 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -271,7 +271,7 @@ static struct platform_driver twl4030_vibra_driver = {
.probe = twl4030_vibra_probe,
.remove = __devexit_p(twl4030_vibra_remove),
.driver = {
- .name = "twl4030_codec_vibra",
+ .name = "twl4030-vibra",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &twl4030_vibra_pm_ops,
@@ -291,7 +291,7 @@ static void __exit twl4030_vibra_exit(void)
}
module_exit(twl4030_vibra_exit);
-MODULE_ALIAS("platform:twl4030_codec_vibra");
+MODULE_ALIAS("platform:twl4030-vibra");
MODULE_DESCRIPTION("TWL4030 Vibra driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 0d4266a533a5..5afdf2f42a3e 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -804,6 +804,7 @@ static const struct file_operations uinput_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = uinput_compat_ioctl,
#endif
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice uinput_misc = {
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index ea67c49146a3..b95231763911 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -337,10 +337,14 @@ static void report_finger_data(struct input_dev *input,
const struct bcm5974_config *cfg,
const struct tp_finger *f)
{
- input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major));
- input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor));
- input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major));
- input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor));
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR,
+ raw2int(f->force_major) << 1);
+ input_report_abs(input, ABS_MT_TOUCH_MINOR,
+ raw2int(f->force_minor) << 1);
+ input_report_abs(input, ABS_MT_WIDTH_MAJOR,
+ raw2int(f->size_major) << 1);
+ input_report_abs(input, ABS_MT_WIDTH_MINOR,
+ raw2int(f->size_minor) << 1);
input_report_abs(input, ABS_MT_ORIENTATION,
MAX_FINGER_ORIENTATION - raw2int(f->orientation));
input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index d528a2dba064..830d99728383 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -792,6 +792,7 @@ static const struct file_operations mousedev_fops = {
.open = mousedev_open,
.release = mousedev_release,
.fasync = mousedev_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int mousedev_install_chrdev(struct mousedev *mousedev)
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 46e4ba0b9246..f58513160480 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1485,8 +1485,8 @@ static int __init i8042_init(void)
static void __exit i8042_exit(void)
{
- platform_driver_unregister(&i8042_driver);
platform_device_unregister(i8042_platform_device);
+ platform_driver_unregister(&i8042_driver);
i8042_platform_exit();
panic_blink = NULL;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index c3b626e9eae7..8a426375fcb3 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -37,7 +37,6 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
-#include <linux/freezer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 998664854440..c14fd5380a24 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -243,6 +243,7 @@ static const struct file_operations serio_raw_fops = {
.write = serio_raw_write,
.poll = serio_raw_poll,
.fasync = serio_raw_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 6d345112bcb7..6e362de3f412 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -165,6 +165,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
serio->open = serport_serio_open;
serio->close = serport_serio_close;
serio->port_data = serport;
+ serio->dev.parent = tty->dev;
serio_register_port(serport->serio);
printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c
index 014248344763..a29a7812bd46 100644
--- a/drivers/input/sparse-keymap.c
+++ b/drivers/input/sparse-keymap.c
@@ -22,6 +22,37 @@ MODULE_DESCRIPTION("Generic support for sparse keymaps");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");
+static unsigned int sparse_keymap_get_key_index(struct input_dev *dev,
+ const struct key_entry *k)
+{
+ struct key_entry *key;
+ unsigned int idx = 0;
+
+ for (key = dev->keycode; key->type != KE_END; key++) {
+ if (key->type == KE_KEY) {
+ if (key == k)
+ break;
+ idx++;
+ }
+ }
+
+ return idx;
+}
+
+static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev,
+ unsigned int index)
+{
+ struct key_entry *key;
+ unsigned int key_cnt = 0;
+
+ for (key = dev->keycode; key->type != KE_END; key++)
+ if (key->type == KE_KEY)
+ if (key_cnt++ == index)
+ return key;
+
+ return NULL;
+}
+
/**
* sparse_keymap_entry_from_scancode - perform sparse keymap lookup
* @dev: Input device using sparse keymap
@@ -64,16 +95,36 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
}
EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
+static struct key_entry *sparse_keymap_locate(struct input_dev *dev,
+ const struct input_keymap_entry *ke)
+{
+ struct key_entry *key;
+ unsigned int scancode;
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX)
+ key = sparse_keymap_entry_by_index(dev, ke->index);
+ else if (input_scancode_to_scalar(ke, &scancode) == 0)
+ key = sparse_keymap_entry_from_scancode(dev, scancode);
+ else
+ key = NULL;
+
+ return key;
+}
+
static int sparse_keymap_getkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int *keycode)
+ struct input_keymap_entry *ke)
{
const struct key_entry *key;
if (dev->keycode) {
- key = sparse_keymap_entry_from_scancode(dev, scancode);
+ key = sparse_keymap_locate(dev, ke);
if (key && key->type == KE_KEY) {
- *keycode = key->keycode;
+ ke->keycode = key->keycode;
+ if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
+ ke->index =
+ sparse_keymap_get_key_index(dev, key);
+ ke->len = sizeof(key->code);
+ memcpy(ke->scancode, &key->code, sizeof(key->code));
return 0;
}
}
@@ -82,20 +133,19 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
}
static int sparse_keymap_setkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int keycode)
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
{
struct key_entry *key;
- int old_keycode;
if (dev->keycode) {
- key = sparse_keymap_entry_from_scancode(dev, scancode);
+ key = sparse_keymap_locate(dev, ke);
if (key && key->type == KE_KEY) {
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
- clear_bit(old_keycode, dev->keybit);
+ *old_keycode = key->keycode;
+ key->keycode = ke->keycode;
+ set_bit(ke->keycode, dev->keybit);
+ if (!sparse_keymap_entry_from_keycode(dev, *old_keycode))
+ clear_bit(*old_keycode, dev->keybit);
return 0;
}
}
@@ -159,15 +209,14 @@ int sparse_keymap_setup(struct input_dev *dev,
dev->keycode = map;
dev->keycodemax = map_size;
- dev->getkeycode = sparse_keymap_getkeycode;
- dev->setkeycode = sparse_keymap_setkeycode;
+ dev->getkeycode_new = sparse_keymap_getkeycode;
+ dev->setkeycode_new = sparse_keymap_setkeycode;
return 0;
err_out:
kfree(map);
return error;
-
}
EXPORT_SYMBOL(sparse_keymap_setup);
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig
index effb49ea24aa..58a87755b936 100644
--- a/drivers/input/tablet/Kconfig
+++ b/drivers/input/tablet/Kconfig
@@ -49,6 +49,17 @@ config TABLET_USB_GTCO
To compile this driver as a module, choose M here: the
module will be called gtco.
+config TABLET_USB_HANWANG
+ tristate "Hanwang Art Master III tablet support (USB)"
+ depends on USB_ARCH_HAS_HCD
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Hanwang Art
+ Master III tablet.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hanwang.
+
config TABLET_USB_KBTAB
tristate "KB Gear JamStudio tablet support (USB)"
depends on USB_ARCH_HAS_HCD
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile
index ce8b9a9cfa40..3f6c25220638 100644
--- a/drivers/input/tablet/Makefile
+++ b/drivers/input/tablet/Makefile
@@ -8,5 +8,6 @@ wacom-objs := wacom_wac.o wacom_sys.o
obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o
obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o
obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o
+obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o
obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o
obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c
new file mode 100644
index 000000000000..0701d948cdf3
--- /dev/null
+++ b/drivers/input/tablet/hanwang.c
@@ -0,0 +1,394 @@
+/*
+ * USB Hanwang tablet support
+ *
+ * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn>
+ *
+ */
+
+/*
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb/input.h>
+
+#define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>"
+#define DRIVER_DESC "USB Hanwang tablet driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+#define USB_VENDOR_ID_HANWANG 0x0b57
+#define HANWANG_TABLET_INT_CLASS 0x0003
+#define HANWANG_TABLET_INT_SUB_CLASS 0x0001
+#define HANWANG_TABLET_INT_PROTOCOL 0x0002
+
+#define ART_MASTERIII_PKGLEN_MAX 10
+
+/* device IDs */
+#define STYLUS_DEVICE_ID 0x02
+#define TOUCH_DEVICE_ID 0x03
+#define CURSOR_DEVICE_ID 0x06
+#define ERASER_DEVICE_ID 0x0A
+#define PAD_DEVICE_ID 0x0F
+
+/* match vendor and interface info */
+#define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR \
+ | USB_DEVICE_ID_MATCH_INT_INFO, \
+ .idVendor = (vend), \
+ .bInterfaceClass = (cl), \
+ .bInterfaceSubClass = (sc), \
+ .bInterfaceProtocol = (pr)
+
+struct hanwang {
+ unsigned char *data;
+ dma_addr_t data_dma;
+ struct input_dev *dev;
+ struct usb_device *usbdev;
+ struct urb *irq;
+ const struct hanwang_features *features;
+ unsigned int current_tool;
+ unsigned int current_id;
+ char name[64];
+ char phys[32];
+};
+
+struct hanwang_features {
+ unsigned short pid;
+ char *name;
+ int pkg_len;
+ int max_x;
+ int max_y;
+ int max_tilt_x;
+ int max_tilt_y;
+ int max_pressure;
+};
+
+static const struct hanwang_features features_array[] = {
+ { 0x8528, "Hanwang Art Master III 0906",
+ ART_MASTERIII_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 },
+ { 0x8529, "Hanwang Art Master III 0604",
+ ART_MASTERIII_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 },
+ { 0x852a, "Hanwang Art Master III 1308",
+ ART_MASTERIII_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 },
+};
+
+static const int hw_eventtypes[] = {
+ EV_KEY, EV_ABS, EV_MSC,
+};
+
+static const int hw_absevents[] = {
+ ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL,
+ ABS_PRESSURE, ABS_MISC,
+};
+
+static const int hw_btnevents[] = {
+ BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER,
+ BTN_TOOL_MOUSE, BTN_TOOL_FINGER,
+ BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8,
+};
+
+static const int hw_mscevents[] = {
+ MSC_SERIAL,
+};
+
+static void hanwang_parse_packet(struct hanwang *hanwang)
+{
+ unsigned char *data = hanwang->data;
+ struct input_dev *input_dev = hanwang->dev;
+ struct usb_device *dev = hanwang->usbdev;
+ int i;
+
+ switch (data[0]) {
+ case 0x02: /* data packet */
+ switch (data[1]) {
+ case 0x80: /* tool prox out */
+ hanwang->current_id = 0;
+ input_report_key(input_dev, hanwang->current_tool, 0);
+ break;
+
+ case 0xc2: /* first time tool prox in */
+ switch (data[3] & 0xf0) {
+ case 0x20:
+ hanwang->current_id = STYLUS_DEVICE_ID;
+ hanwang->current_tool = BTN_TOOL_PEN;
+ input_report_key(input_dev, BTN_TOOL_PEN, 1);
+ break;
+ case 0xa0:
+ hanwang->current_id = ERASER_DEVICE_ID;
+ hanwang->current_tool = BTN_TOOL_RUBBER;
+ input_report_key(input_dev, BTN_TOOL_RUBBER, 1);
+ break;
+ default:
+ hanwang->current_id = 0;
+ dev_dbg(&dev->dev,
+ "unknown tablet tool %02x ", data[0]);
+ break;
+ }
+ break;
+
+ default: /* tool data packet */
+ input_report_abs(input_dev, ABS_X,
+ (data[2] << 8) | data[3]);
+ input_report_abs(input_dev, ABS_Y,
+ (data[4] << 8) | data[5]);
+ input_report_abs(input_dev, ABS_PRESSURE,
+ (data[6] << 3) |
+ ((data[7] & 0xc0) >> 5) |
+ (data[1] & 0x01));
+ input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f);
+ input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f);
+ input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02);
+ input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
+ break;
+ }
+ input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
+ input_event(input_dev, EV_MSC, MSC_SERIAL,
+ hanwang->features->pid);
+ break;
+
+ case 0x0c:
+ /* roll wheel */
+ hanwang->current_id = PAD_DEVICE_ID;
+ input_report_key(input_dev, BTN_TOOL_FINGER, data[1] ||
+ data[2] || data[3]);
+ input_report_abs(input_dev, ABS_WHEEL, data[1]);
+ input_report_key(input_dev, BTN_0, data[2]);
+ for (i = 0; i < 8; i++)
+ input_report_key(input_dev,
+ BTN_1 + i, data[3] & (1 << i));
+ input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
+ input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff);
+ break;
+
+ default:
+ dev_dbg(&dev->dev, "error packet %02x ", data[0]);
+ break;
+ }
+
+ input_sync(input_dev);
+}
+
+static void hanwang_irq(struct urb *urb)
+{
+ struct hanwang *hanwang = urb->context;
+ struct usb_device *dev = hanwang->usbdev;
+ int retval;
+
+ switch (urb->status) {
+ case 0:
+ /* success */;
+ hanwang_parse_packet(hanwang);
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dev_err(&dev->dev, "%s - urb shutting down with status: %d",
+ __func__, urb->status);
+ return;
+ default:
+ dev_err(&dev->dev, "%s - nonzero urb status received: %d",
+ __func__, urb->status);
+ break;
+ }
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d",
+ __func__, retval);
+}
+
+static int hanwang_open(struct input_dev *dev)
+{
+ struct hanwang *hanwang = input_get_drvdata(dev);
+
+ hanwang->irq->dev = hanwang->usbdev;
+ if (usb_submit_urb(hanwang->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void hanwang_close(struct input_dev *dev)
+{
+ struct hanwang *hanwang = input_get_drvdata(dev);
+
+ usb_kill_urb(hanwang->irq);
+}
+
+static bool get_features(struct usb_device *dev, struct hanwang *hanwang)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(features_array); i++) {
+ if (le16_to_cpu(dev->descriptor.idProduct) ==
+ features_array[i].pid) {
+ hanwang->features = &features_array[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_endpoint_descriptor *endpoint;
+ struct hanwang *hanwang;
+ struct input_dev *input_dev;
+ int error;
+ int i;
+
+ hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!hanwang || !input_dev) {
+ error = -ENOMEM;
+ goto fail1;
+ }
+
+ if (!get_features(dev, hanwang)) {
+ error = -ENXIO;
+ goto fail1;
+ }
+
+ hanwang->data = usb_alloc_coherent(dev, hanwang->features->pkg_len,
+ GFP_KERNEL, &hanwang->data_dma);
+ if (!hanwang->data) {
+ error = -ENOMEM;
+ goto fail1;
+ }
+
+ hanwang->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!hanwang->irq) {
+ error = -ENOMEM;
+ goto fail2;
+ }
+
+ hanwang->usbdev = dev;
+ hanwang->dev = input_dev;
+
+ usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys));
+ strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys));
+
+ strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name));
+ input_dev->name = hanwang->name;
+ input_dev->phys = hanwang->phys;
+ usb_to_input_id(dev, &input_dev->id);
+ input_dev->dev.parent = &intf->dev;
+
+ input_set_drvdata(input_dev, hanwang);
+
+ input_dev->open = hanwang_open;
+ input_dev->close = hanwang_close;
+
+ for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i)
+ __set_bit(hw_eventtypes[i], input_dev->evbit);
+
+ for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i)
+ __set_bit(hw_absevents[i], input_dev->absbit);
+
+ for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i)
+ __set_bit(hw_btnevents[i], input_dev->keybit);
+
+ for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i)
+ __set_bit(hw_mscevents[i], input_dev->mscbit);
+
+ input_set_abs_params(input_dev, ABS_X,
+ 0, hanwang->features->max_x, 4, 0);
+ input_set_abs_params(input_dev, ABS_Y,
+ 0, hanwang->features->max_y, 4, 0);
+ input_set_abs_params(input_dev, ABS_TILT_X,
+ 0, hanwang->features->max_tilt_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_TILT_Y,
+ 0, hanwang->features->max_tilt_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE,
+ 0, hanwang->features->max_pressure, 0, 0);
+
+ endpoint = &intf->cur_altsetting->endpoint[0].desc;
+ usb_fill_int_urb(hanwang->irq, dev,
+ usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+ hanwang->data, hanwang->features->pkg_len,
+ hanwang_irq, hanwang, endpoint->bInterval);
+ hanwang->irq->transfer_dma = hanwang->data_dma;
+ hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ error = input_register_device(hanwang->dev);
+ if (error)
+ goto fail3;
+
+ usb_set_intfdata(intf, hanwang);
+
+ return 0;
+
+ fail3: usb_free_urb(hanwang->irq);
+ fail2: usb_free_coherent(dev, hanwang->features->pkg_len,
+ hanwang->data, hanwang->data_dma);
+ fail1: input_free_device(input_dev);
+ kfree(hanwang);
+ return error;
+
+}
+
+static void hanwang_disconnect(struct usb_interface *intf)
+{
+ struct hanwang *hanwang = usb_get_intfdata(intf);
+
+ input_unregister_device(hanwang->dev);
+ usb_free_urb(hanwang->irq);
+ usb_free_coherent(interface_to_usbdev(intf),
+ hanwang->features->pkg_len, hanwang->data,
+ hanwang->data_dma);
+ kfree(hanwang);
+ usb_set_intfdata(intf, NULL);
+}
+
+static const struct usb_device_id hanwang_ids[] = {
+ { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS,
+ HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) },
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, hanwang_ids);
+
+static struct usb_driver hanwang_driver = {
+ .name = "hanwang",
+ .probe = hanwang_probe,
+ .disconnect = hanwang_disconnect,
+ .id_table = hanwang_ids,
+};
+
+static int __init hanwang_init(void)
+{
+ return usb_register(&hanwang_driver);
+}
+
+static void __exit hanwang_exit(void)
+{
+ usb_deregister(&hanwang_driver);
+}
+
+module_init(hanwang_init);
+module_exit(hanwang_exit);
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 284dfaab6b8c..de5adb109030 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -118,6 +118,7 @@ struct wacom {
extern const struct usb_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
+void wacom_setup_device_quirks(struct wacom_features *features);
void wacom_setup_input_capabilities(struct input_dev *input_dev,
struct wacom_wac *wacom_wac);
#endif
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 42ba3691d908..1e3af299a1c2 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -195,17 +195,30 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
features->pktlen = WACOM_PKGLEN_TPC2FG;
features->device_type = BTN_TOOL_TRIPLETAP;
}
- features->x_max =
- get_unaligned_le16(&report[i + 3]);
- features->x_phy =
- get_unaligned_le16(&report[i + 6]);
- features->unit = report[i + 9];
- features->unitExpo = report[i + 11];
- i += 12;
+ if (features->type == BAMBOO_PT) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ features->device_type = BTN_TOOL_TRIPLETAP;
+ features->x_phy =
+ get_unaligned_le16(&report[i + 5]);
+ features->x_max =
+ get_unaligned_le16(&report[i + 8]);
+ i += 15;
+ } else {
+ features->x_max =
+ get_unaligned_le16(&report[i + 3]);
+ features->x_phy =
+ get_unaligned_le16(&report[i + 6]);
+ features->unit = report[i + 9];
+ features->unitExpo = report[i + 11];
+ i += 12;
+ }
} else if (pen) {
/* penabled only accepts exact bytes of data */
if (features->type == TABLETPC2FG)
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ if (features->type == BAMBOO_PT)
+ features->pktlen = WACOM_PKGLEN_BBFUN;
features->device_type = BTN_TOOL_PEN;
features->x_max =
get_unaligned_le16(&report[i + 3]);
@@ -234,6 +247,15 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
+ } else if (features->type == BAMBOO_PT) {
+ /* need to reset back */
+ features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ features->device_type = BTN_TOOL_TRIPLETAP;
+ features->y_phy =
+ get_unaligned_le16(&report[i + 3]);
+ features->y_max =
+ get_unaligned_le16(&report[i + 6]);
+ i += 12;
} else {
features->y_max =
features->x_max;
@@ -245,6 +267,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
/* penabled only accepts exact bytes of data */
if (features->type == TABLETPC2FG)
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ if (features->type == BAMBOO_PT)
+ features->pktlen = WACOM_PKGLEN_BBFUN;
features->device_type = BTN_TOOL_PEN;
features->y_max =
get_unaligned_le16(&report[i + 3]);
@@ -295,8 +319,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
if (!rep_data)
return error;
- /* ask to report tablet data if it is 2FGT or not a Tablet PC */
- if (features->device_type == BTN_TOOL_TRIPLETAP) {
+ /* ask to report tablet data if it is 2FGT Tablet PC or
+ * not a Tablet PC */
+ if (features->type == TABLETPC2FG) {
do {
rep_data[0] = 3;
rep_data[1] = 4;
@@ -308,7 +333,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
WAC_HID_FEATURE_REPORT, report_id,
rep_data, 3);
} while ((error < 0 || rep_data[1] != 4) && limit++ < 5);
- } else if (features->type != TABLETPC && features->type != TABLETPC2FG) {
+ } else if (features->type != TABLETPC) {
do {
rep_data[0] = 2;
rep_data[1] = 2;
@@ -333,11 +358,16 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
struct usb_host_interface *interface = intf->cur_altsetting;
struct hid_descriptor *hid_desc;
- /* default device to penabled */
+ /* default features */
features->device_type = BTN_TOOL_PEN;
-
- /* only Tablet PCs need to retrieve the info */
- if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+ features->x_fuzz = 4;
+ features->y_fuzz = 4;
+ features->pressure_fuzz = 0;
+ features->distance_fuzz = 0;
+
+ /* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
+ (features->type != BAMBOO_PT))
goto out;
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -352,12 +382,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
if (error)
goto out;
- /* touch device found but size is not defined. use default */
- if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
- features->x_max = 1023;
- features->y_max = 1023;
- }
-
out:
return error;
}
@@ -493,9 +517,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail2;
+ wacom_setup_device_quirks(features);
+
strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
- if (features->type == TABLETPC || features->type == TABLETPC2FG) {
+ if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
/* Append the device type to the name */
strlcat(wacom_wac->name,
features->device_type == BTN_TOOL_PEN ?
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 40d77ba8fdc1..e1b65ba84438 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -243,10 +243,10 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
if (features->type == WACOM_G4 ||
features->type == WACOM_MO) {
input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);
- rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
+ rw = (data[7] & 0x04) - (data[7] & 0x03);
} else {
input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);
- rw = -(signed)data[6];
+ rw = -(signed char)data[6];
}
input_report_rel(input, REL_WHEEL, rw);
}
@@ -855,6 +855,134 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
return retval;
}
+static int wacom_bpt_touch(struct wacom_wac *wacom)
+{
+ struct wacom_features *features = &wacom->features;
+ struct input_dev *input = wacom->input;
+ unsigned char *data = wacom->data;
+ int sp = 0, sx = 0, sy = 0, count = 0;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ int p = data[9 * i + 2];
+ input_mt_slot(input, i);
+ /*
+ * Touch events need to be disabled while stylus is
+ * in proximity because user's hand is resting on touchpad
+ * and sending unwanted events. User expects tablet buttons
+ * to continue working though.
+ */
+ if (p && !wacom->shared->stylus_in_proximity) {
+ int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
+ int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
+ if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
+ x <<= 5;
+ y <<= 5;
+ }
+ input_report_abs(input, ABS_MT_PRESSURE, p);
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ if (wacom->id[i] < 0)
+ wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
+ if (!count++)
+ sp = p, sx = x, sy = y;
+ } else {
+ wacom->id[i] = -1;
+ }
+ input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
+ }
+
+ input_report_key(input, BTN_TOUCH, count > 0);
+ input_report_key(input, BTN_TOOL_FINGER, count == 1);
+ input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
+
+ input_report_abs(input, ABS_PRESSURE, sp);
+ input_report_abs(input, ABS_X, sx);
+ input_report_abs(input, ABS_Y, sy);
+
+ input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
+ input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
+ input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
+ input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
+
+ input_sync(input);
+
+ return 0;
+}
+
+static int wacom_bpt_pen(struct wacom_wac *wacom)
+{
+ struct input_dev *input = wacom->input;
+ unsigned char *data = wacom->data;
+ int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
+
+ /*
+ * Similar to Graphire protocol, data[1] & 0x20 is proximity and
+ * data[1] & 0x18 is tool ID. 0x30 is safety check to ignore
+ * 2 unused tool ID's.
+ */
+ prox = (data[1] & 0x30) == 0x30;
+
+ /*
+ * All reports shared between PEN and RUBBER tool must be
+ * forced to a known starting value (zero) when transitioning to
+ * out-of-prox.
+ *
+ * If not reset then, to userspace, it will look like lost events
+ * if new tool comes in-prox with same values as previous tool sent.
+ *
+ * Hardware does report zero in most out-of-prox cases but not all.
+ */
+ if (prox) {
+ if (!wacom->shared->stylus_in_proximity) {
+ if (data[1] & 0x08) {
+ wacom->tool[0] = BTN_TOOL_RUBBER;
+ wacom->id[0] = ERASER_DEVICE_ID;
+ } else {
+ wacom->tool[0] = BTN_TOOL_PEN;
+ wacom->id[0] = STYLUS_DEVICE_ID;
+ }
+ wacom->shared->stylus_in_proximity = true;
+ }
+ x = le16_to_cpup((__le16 *)&data[2]);
+ y = le16_to_cpup((__le16 *)&data[4]);
+ p = le16_to_cpup((__le16 *)&data[6]);
+ d = data[8];
+ pen = data[1] & 0x01;
+ btn1 = data[1] & 0x02;
+ btn2 = data[1] & 0x04;
+ }
+
+ input_report_key(input, BTN_TOUCH, pen);
+ input_report_key(input, BTN_STYLUS, btn1);
+ input_report_key(input, BTN_STYLUS2, btn2);
+
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ input_report_abs(input, ABS_PRESSURE, p);
+ input_report_abs(input, ABS_DISTANCE, d);
+
+ if (!prox) {
+ wacom->id[0] = 0;
+ wacom->shared->stylus_in_proximity = false;
+ }
+
+ input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
+ input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
+
+ return 1;
+}
+
+static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+{
+ if (len == WACOM_PKGLEN_BBTOUCH)
+ return wacom_bpt_touch(wacom);
+ else if (len == WACOM_PKGLEN_BBFUN)
+ return wacom_bpt_pen(wacom);
+
+ return 0;
+}
+
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
{
bool sync;
@@ -900,6 +1028,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync = wacom_tpc_irq(wacom_wac, len);
break;
+ case BAMBOO_PT:
+ sync = wacom_bpt_irq(wacom_wac, len);
+ break;
+
default:
sync = false;
break;
@@ -941,6 +1073,34 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
}
+
+void wacom_setup_device_quirks(struct wacom_features *features)
+{
+
+ /* touch device found but size is not defined. use default */
+ if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+ features->x_max = 1023;
+ features->y_max = 1023;
+ }
+
+ /* these device have multiple inputs */
+ if (features->type == TABLETPC || features->type == TABLETPC2FG ||
+ features->type == BAMBOO_PT)
+ features->quirks |= WACOM_QUIRK_MULTI_INPUT;
+
+ /* quirks for bamboo touch */
+ if (features->type == BAMBOO_PT &&
+ features->device_type == BTN_TOOL_TRIPLETAP) {
+ features->x_max <<= 5;
+ features->y_max <<= 5;
+ features->x_fuzz <<= 5;
+ features->y_fuzz <<= 5;
+ features->pressure_max = 256;
+ features->pressure_fuzz = 16;
+ features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
+ }
+}
+
void wacom_setup_input_capabilities(struct input_dev *input_dev,
struct wacom_wac *wacom_wac)
{
@@ -951,9 +1111,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOUCH, input_dev->keybit);
- input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, features->x_max,
+ features->x_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, features->y_max,
+ features->y_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max,
+ features->pressure_fuzz, 0);
__set_bit(ABS_MISC, input_dev->absbit);
@@ -1076,6 +1239,38 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
case PENPARTNER:
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
break;
+
+ case BAMBOO_PT:
+ __clear_bit(ABS_MISC, input_dev->absbit);
+
+ if (features->device_type == BTN_TOOL_TRIPLETAP) {
+ __set_bit(BTN_LEFT, input_dev->keybit);
+ __set_bit(BTN_FORWARD, input_dev->keybit);
+ __set_bit(BTN_BACK, input_dev->keybit);
+ __set_bit(BTN_RIGHT, input_dev->keybit);
+
+ __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+ __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+
+ input_mt_create_slots(input_dev, 2);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+ 0, features->x_max,
+ features->x_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+ 0, features->y_max,
+ features->y_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE,
+ 0, features->pressure_max,
+ features->pressure_fuzz, 0);
+ input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
+ MAX_TRACKING_ID, 0, 0);
+ } else if (features->device_type == BTN_TOOL_PEN) {
+ __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
+ __set_bit(BTN_TOOL_PEN, input_dev->keybit);
+ __set_bit(BTN_STYLUS, input_dev->keybit);
+ __set_bit(BTN_STYLUS2, input_dev->keybit);
+ }
+ break;
}
}
@@ -1213,6 +1408,14 @@ static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG };
static const struct wacom_features wacom_features_0x47 =
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS };
+static struct wacom_features wacom_features_0xD0 =
+ { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD1 =
+ { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD2 =
+ { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD3 =
+ { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
#define USB_DEVICE_WACOM(prod) \
USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \
@@ -1277,6 +1480,10 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xC6) },
{ USB_DEVICE_WACOM(0xC7) },
{ USB_DEVICE_WACOM(0xCE) },
+ { USB_DEVICE_WACOM(0xD0) },
+ { USB_DEVICE_WACOM(0xD1) },
+ { USB_DEVICE_WACOM(0xD2) },
+ { USB_DEVICE_WACOM(0xD3) },
{ USB_DEVICE_WACOM(0xF0) },
{ USB_DEVICE_WACOM(0xCC) },
{ USB_DEVICE_WACOM(0x90) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 99e1a54cd305..00ca01541d89 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -21,6 +21,7 @@
#define WACOM_PKGLEN_INTUOS 10
#define WACOM_PKGLEN_TPC1FG 5
#define WACOM_PKGLEN_TPC2FG 14
+#define WACOM_PKGLEN_BBTOUCH 20
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -37,6 +38,13 @@
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
+/* device quirks */
+#define WACOM_QUIRK_MULTI_INPUT 0x0001
+#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
+
+/* largest reported tracking id */
+#define MAX_TRACKING_ID 0xfff
+
enum {
PENPARTNER = 0,
GRAPHIRE,
@@ -44,6 +52,7 @@ enum {
PTU,
PL,
DTU,
+ BAMBOO_PT,
INTUOS,
INTUOS3S,
INTUOS3,
@@ -73,6 +82,11 @@ struct wacom_features {
int y_phy;
unsigned char unit;
unsigned char unitExpo;
+ int x_fuzz;
+ int y_fuzz;
+ int pressure_fuzz;
+ int distance_fuzz;
+ unsigned quirks;
};
struct wacom_shared {
@@ -86,6 +100,7 @@ struct wacom_wac {
int id[3];
__u32 serial[2];
int last_finger;
+ int trk_id;
struct wacom_features features;
struct wacom_shared *shared;
struct input_dev *input;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 0069d9703fda..d59feb7b90f6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -214,6 +214,16 @@ config TOUCHSCREEN_WACOM_W8001
To compile this driver as a module, choose M here: the
module will be called wacom_w8001.
+config TOUCHSCREEN_LPC32XX
+ tristate "LPC32XX touchscreen controller"
+ depends on ARCH_LPC32XX
+ help
+ Say Y here if you have a LPC32XX device and want
+ to support the built-in touchscreen.
+
+ To compile this driver as a module, choose M here: the
+ module will be called lpc32xx_ts.
+
config TOUCHSCREEN_MCS5000
tristate "MELFAS MCS-5000 touchscreen"
depends on I2C
@@ -250,6 +260,18 @@ config TOUCHSCREEN_INEXIO
To compile this driver as a module, choose M here: the
module will be called inexio.
+config TOUCHSCREEN_INTEL_MID
+ tristate "Intel MID platform resistive touchscreen"
+ depends on INTEL_SCU_IPC
+ help
+ Say Y here if you have a Intel MID based touchscreen in
+ your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called intel_mid_touch.
+
config TOUCHSCREEN_MK712
tristate "ICS MicroClock MK712 touchscreen"
help
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 28217e1dcafd..f1bc8a416824 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -23,6 +23,8 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
+obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o
obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o
obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c
index 5ec0946938fe..d0c3a7229adf 100644
--- a/drivers/input/touchscreen/cy8ctmg110_ts.c
+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c
@@ -206,9 +206,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client,
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X,
- CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0);
+ CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0);
input_set_abs_params(input_dev, ABS_Y,
- CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0);
+ CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0);
if (ts->reset_pin) {
err = gpio_request(ts->reset_pin, NULL);
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c
new file mode 100644
index 000000000000..c0307b22d86f
--- /dev/null
+++ b/drivers/input/touchscreen/intel-mid-touch.c
@@ -0,0 +1,687 @@
+/*
+ * Intel MID Resistive Touch Screen Driver
+ *
+ * Copyright (C) 2008 Intel Corp
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
+ * Ramesh Agarwal (ramesh.agarwal@intel.com)
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * TODO:
+ * review conversion of r/m/w sequences
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/param.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <asm/intel_scu_ipc.h>
+
+/* PMIC Interrupt registers */
+#define PMIC_REG_ID1 0x00 /* PMIC ID1 register */
+
+/* PMIC Interrupt registers */
+#define PMIC_REG_INT 0x04 /* PMIC interrupt register */
+#define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */
+
+/* ADC Interrupt registers */
+#define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */
+#define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */
+
+/* ADC Control registers */
+#define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */
+
+/* ADC Channel Selection registers */
+#define PMICADDR0 0xA4
+#define END_OF_CHANNEL 0x1F
+
+/* ADC Result register */
+#define PMIC_REG_ADCSNS0H 0x64
+
+/* ADC channels for touch screen */
+#define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */
+#define MRST_TS_CHAN11 0xB /* Touch screen X- connection */
+#define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */
+#define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */
+
+/* Touch screen channel BIAS constants */
+#define MRST_XBIAS 0x20
+#define MRST_YBIAS 0x40
+#define MRST_ZBIAS 0x80
+
+/* Touch screen coordinates */
+#define MRST_X_MIN 10
+#define MRST_X_MAX 1024
+#define MRST_X_FUZZ 5
+#define MRST_Y_MIN 10
+#define MRST_Y_MAX 1024
+#define MRST_Y_FUZZ 5
+#define MRST_PRESSURE_MIN 0
+#define MRST_PRESSURE_NOMINAL 50
+#define MRST_PRESSURE_MAX 100
+
+#define WAIT_ADC_COMPLETION 10 /* msec */
+
+/* PMIC ADC round robin delays */
+#define ADC_LOOP_DELAY0 0x0 /* Continuous loop */
+#define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */
+
+/* PMIC Vendor Identifiers */
+#define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */
+#define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */
+#define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */
+#define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */
+
+/* Touch screen device structure */
+struct mrstouch_dev {
+ struct device *dev; /* device associated with touch screen */
+ struct input_dev *input;
+ char phys[32];
+ u16 asr; /* Address selection register */
+ int irq;
+ unsigned int vendor; /* PMIC vendor */
+ unsigned int rev; /* PMIC revision */
+
+ int (*read_prepare)(struct mrstouch_dev *tsdev);
+ int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z);
+ int (*read_finish)(struct mrstouch_dev *tsdev);
+};
+
+
+/*************************** NEC and Maxim Interface ************************/
+
+static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev)
+{
+ return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20);
+}
+
+/*
+ * Enables PENDET interrupt.
+ */
+static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev)
+{
+ int err;
+
+ err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20);
+ if (!err)
+ err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05);
+
+ return err;
+}
+
+/*
+ * Reads PMIC ADC touch screen result
+ * Reads ADC storage registers for higher 7 and lower 3 bits and
+ * converts the two readings into a single value and turns off gain bit
+ */
+static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm)
+{
+ int err;
+ u16 result;
+ u32 res;
+
+ result = PMIC_REG_ADCSNS0H + offset;
+
+ if (chan == MRST_TS_CHAN12)
+ result += 4;
+
+ err = intel_scu_ipc_ioread32(result, &res);
+ if (err)
+ return err;
+
+ /* Mash the bits up */
+
+ *vp = (res & 0xFF) << 3; /* Highest 7 bits */
+ *vp |= (res >> 8) & 0x07; /* Lower 3 bits */
+ *vp &= 0x3FF;
+
+ res >>= 16;
+
+ *vm = (res & 0xFF) << 3; /* Highest 7 bits */
+ *vm |= (res >> 8) & 0x07; /* Lower 3 bits */
+ *vm &= 0x3FF;
+
+ return 0;
+}
+
+/*
+ * Enables X, Y and Z bias values
+ * Enables YPYM for X channels and XPXM for Y channels
+ */
+static int mrstouch_ts_bias_set(uint offset, uint bias)
+{
+ int count;
+ u16 chan, start;
+ u16 reg[4];
+ u8 data[4];
+
+ chan = PMICADDR0 + offset;
+ start = MRST_TS_CHAN10;
+
+ for (count = 0; count <= 3; count++) {
+ reg[count] = chan++;
+ data[count] = bias | (start + count);
+ }
+
+ return intel_scu_ipc_writev(reg, data, 4);
+}
+
+/* To read touch screen channel values */
+static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev,
+ u16 *x, u16 *y, u16 *z)
+{
+ int err;
+ u16 xm, ym, zm;
+
+ /* configure Y bias for X channels */
+ err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ /* read x+ and x- channels */
+ err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm);
+ if (err)
+ goto ipc_error;
+
+ /* configure x bias for y channels */
+ err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ /* read y+ and y- channels */
+ err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym);
+ if (err)
+ goto ipc_error;
+
+ /* configure z bias for x and y channels */
+ err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ /* read z+ and z- channels */
+ err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm);
+ if (err)
+ goto ipc_error;
+
+ return 0;
+
+ipc_error:
+ dev_err(tsdev->dev, "ipc error during adc read\n");
+ return err;
+}
+
+
+/*************************** Freescale Interface ************************/
+
+static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev)
+{
+ int err, count;
+ u16 chan;
+ u16 reg[5];
+ u8 data[5];
+
+ /* Stop the ADC */
+ err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02);
+ if (err)
+ goto ipc_error;
+
+ chan = PMICADDR0 + tsdev->asr;
+
+ /* Set X BIAS */
+ for (count = 0; count <= 3; count++) {
+ reg[count] = chan++;
+ data[count] = 0x2A;
+ }
+ reg[count] = chan++; /* Dummy */
+ data[count] = 0;
+
+ err = intel_scu_ipc_writev(reg, data, 5);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ /* Set Y BIAS */
+ for (count = 0; count <= 3; count++) {
+ reg[count] = chan++;
+ data[count] = 0x4A;
+ }
+ reg[count] = chan++; /* Dummy */
+ data[count] = 0;
+
+ err = intel_scu_ipc_writev(reg, data, 5);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ /* Set Z BIAS */
+ err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A);
+ if (err)
+ goto ipc_error;
+
+ msleep(WAIT_ADC_COMPLETION);
+
+ return 0;
+
+ipc_error:
+ dev_err(tsdev->dev, "ipc error during %s\n", __func__);
+ return err;
+}
+
+static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev,
+ u16 *x, u16 *y, u16 *z)
+{
+ int err;
+ u16 result;
+ u16 reg[4];
+ u8 data[4];
+
+ result = PMIC_REG_ADCSNS0H + tsdev->asr;
+
+ reg[0] = result + 4;
+ reg[1] = result + 5;
+ reg[2] = result + 16;
+ reg[3] = result + 17;
+
+ err = intel_scu_ipc_readv(reg, data, 4);
+ if (err)
+ goto ipc_error;
+
+ *x = data[0] << 3; /* Higher 7 bits */
+ *x |= data[1] & 0x7; /* Lower 3 bits */
+ *x &= 0x3FF;
+
+ *y = data[2] << 3; /* Higher 7 bits */
+ *y |= data[3] & 0x7; /* Lower 3 bits */
+ *y &= 0x3FF;
+
+ /* Read Z value */
+ reg[0] = result + 28;
+ reg[1] = result + 29;
+
+ err = intel_scu_ipc_readv(reg, data, 4);
+ if (err)
+ goto ipc_error;
+
+ *z = data[0] << 3; /* Higher 7 bits */
+ *z |= data[1] & 0x7; /* Lower 3 bits */
+ *z &= 0x3FF;
+
+ return 0;
+
+ipc_error:
+ dev_err(tsdev->dev, "ipc error during %s\n", __func__);
+ return err;
+}
+
+static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev)
+{
+ int err, count;
+ u16 chan;
+ u16 reg[5];
+ u8 data[5];
+
+ /* Clear all TS channels */
+ chan = PMICADDR0 + tsdev->asr;
+ for (count = 0; count <= 4; count++) {
+ reg[count] = chan++;
+ data[count] = 0;
+ }
+ err = intel_scu_ipc_writev(reg, data, 5);
+ if (err)
+ goto ipc_error;
+
+ for (count = 0; count <= 4; count++) {
+ reg[count] = chan++;
+ data[count] = 0;
+ }
+ err = intel_scu_ipc_writev(reg, data, 5);
+ if (err)
+ goto ipc_error;
+
+ err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000);
+ if (err)
+ goto ipc_error;
+
+ /* Start ADC */
+ err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02);
+ if (err)
+ goto ipc_error;
+
+ return 0;
+
+ipc_error:
+ dev_err(tsdev->dev, "ipc error during %s\n", __func__);
+ return err;
+}
+
+static void mrstouch_report_event(struct input_dev *input,
+ unsigned int x, unsigned int y, unsigned int z)
+{
+ if (z > MRST_PRESSURE_NOMINAL) {
+ /* Pen touched, report button touch and coordinates */
+ input_report_key(input, BTN_TOUCH, 1);
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ } else {
+ input_report_key(input, BTN_TOUCH, 0);
+ }
+
+ input_report_abs(input, ABS_PRESSURE, z);
+ input_sync(input);
+}
+
+/* PENDET interrupt handler */
+static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id)
+{
+ struct mrstouch_dev *tsdev = dev_id;
+ u16 x, y, z;
+
+ /*
+ * Should we lower thread priority? Probably not, since we are
+ * not spinning but sleeping...
+ */
+
+ if (tsdev->read_prepare(tsdev))
+ goto out;
+
+ do {
+ if (tsdev->read(tsdev, &x, &y, &z))
+ break;
+
+ mrstouch_report_event(tsdev->input, x, y, z);
+ } while (z > MRST_PRESSURE_NOMINAL);
+
+ tsdev->read_finish(tsdev);
+
+out:
+ return IRQ_HANDLED;
+}
+
+/* Utility to read PMIC ID */
+static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev)
+{
+ int err;
+ u8 r;
+
+ err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r);
+ if (err)
+ return err;
+
+ *vendor = r & 0x7;
+ *rev = (r >> 3) & 0x7;
+
+ return 0;
+}
+
+/*
+ * Parse ADC channels to find end of the channel configured by other ADC user
+ * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
+ */
+static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev)
+{
+ int err, i, found;
+ u8 r8;
+
+ found = -1;
+
+ for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) {
+ if (found >= 0)
+ break;
+
+ err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8);
+ if (err)
+ return err;
+
+ if (r8 == END_OF_CHANNEL) {
+ found = i;
+ break;
+ }
+ }
+ if (found < 0)
+ return 0;
+
+ if (tsdev->vendor == PMIC_VENDOR_FS) {
+ if (found && found > (MRSTOUCH_MAX_CHANNELS - 18))
+ return -ENOSPC;
+ } else {
+ if (found && found > (MRSTOUCH_MAX_CHANNELS - 4))
+ return -ENOSPC;
+ }
+ return found;
+}
+
+
+/*
+ * Writes touch screen channels to ADC address selection registers
+ */
+static int __devinit mrstouch_ts_chan_set(uint offset)
+{
+ u16 chan;
+
+ int ret, count;
+
+ chan = PMICADDR0 + offset;
+ for (count = 0; count <= 3; count++) {
+ ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count);
+ if (ret)
+ return ret;
+ }
+ return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL);
+}
+
+/* Initialize ADC */
+static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev)
+{
+ int err, start;
+ u8 ra, rm;
+
+ err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev);
+ if (err) {
+ dev_err(tsdev->dev, "Unable to read PMIC id\n");
+ return err;
+ }
+
+ switch (tsdev->vendor) {
+ case PMIC_VENDOR_NEC:
+ case PMIC_VENDOR_MAXIM:
+ tsdev->read_prepare = mrstouch_nec_adc_read_prepare;
+ tsdev->read = mrstouch_nec_adc_read;
+ tsdev->read_finish = mrstouch_nec_adc_read_finish;
+ break;
+
+ case PMIC_VENDOR_FS:
+ tsdev->read_prepare = mrstouch_fs_adc_read_prepare;
+ tsdev->read = mrstouch_fs_adc_read;
+ tsdev->read_finish = mrstouch_fs_adc_read_finish;
+ break;
+
+ default:
+ dev_err(tsdev->dev,
+ "Unsupported touchscreen: %d\n", tsdev->vendor);
+ return -ENXIO;
+ }
+
+ start = mrstouch_chan_parse(tsdev);
+ if (start < 0) {
+ dev_err(tsdev->dev, "Unable to parse channels\n");
+ return start;
+ }
+
+ tsdev->asr = start;
+
+ /*
+ * ADC power on, start, enable PENDET and set loop delay
+ * ADC loop delay is set to 4.5 ms approximately
+ * Loop delay more than this results in jitter in adc readings
+ * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
+ * interrupt generation sometimes.
+ */
+
+ if (tsdev->vendor == PMIC_VENDOR_FS) {
+ ra = 0xE0 | ADC_LOOP_DELAY0;
+ rm = 0x5;
+ } else {
+ /* NEC and MAXIm not consistent with loop delay 0 */
+ ra = 0xE0 | ADC_LOOP_DELAY1;
+ rm = 0x0;
+
+ /* configure touch screen channels */
+ err = mrstouch_ts_chan_set(tsdev->asr);
+ if (err)
+ return err;
+ }
+
+ err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7);
+ if (err)
+ return err;
+
+ err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+
+/* Probe function for touch screen driver */
+static int __devinit mrstouch_probe(struct platform_device *pdev)
+{
+ struct mrstouch_dev *tsdev;
+ struct input_dev *input;
+ int err;
+ int irq;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no interrupt assigned\n");
+ return -EINVAL;
+ }
+
+ tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!tsdev || !input) {
+ dev_err(&pdev->dev, "unable to allocate memory\n");
+ err = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ tsdev->dev = &pdev->dev;
+ tsdev->input = input;
+ tsdev->irq = irq;
+
+ snprintf(tsdev->phys, sizeof(tsdev->phys),
+ "%s/input0", dev_name(tsdev->dev));
+
+ err = mrstouch_adc_init(tsdev);
+ if (err) {
+ dev_err(&pdev->dev, "ADC initialization failed\n");
+ goto err_free_mem;
+ }
+
+ input->name = "mrst_touchscreen";
+ input->phys = tsdev->phys;
+ input->dev.parent = tsdev->dev;
+
+ input->id.vendor = tsdev->vendor;
+ input->id.version = tsdev->rev;
+
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+ input_set_abs_params(tsdev->input, ABS_X,
+ MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0);
+ input_set_abs_params(tsdev->input, ABS_Y,
+ MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0);
+ input_set_abs_params(tsdev->input, ABS_PRESSURE,
+ MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0);
+
+ err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq,
+ 0, "mrstouch", tsdev);
+ if (err) {
+ dev_err(tsdev->dev, "unable to allocate irq\n");
+ goto err_free_mem;
+ }
+
+ err = input_register_device(tsdev->input);
+ if (err) {
+ dev_err(tsdev->dev, "unable to register input device\n");
+ goto err_free_irq;
+ }
+
+ platform_set_drvdata(pdev, tsdev);
+ return 0;
+
+err_free_irq:
+ free_irq(tsdev->irq, tsdev);
+err_free_mem:
+ input_free_device(input);
+ kfree(tsdev);
+ return err;
+}
+
+static int __devexit mrstouch_remove(struct platform_device *pdev)
+{
+ struct mrstouch_dev *tsdev = platform_get_drvdata(pdev);
+
+ free_irq(tsdev->irq, tsdev);
+ input_unregister_device(tsdev->input);
+ kfree(tsdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver mrstouch_driver = {
+ .driver = {
+ .name = "pmic_touch",
+ .owner = THIS_MODULE,
+ },
+ .probe = mrstouch_probe,
+ .remove = __devexit_p(mrstouch_remove),
+};
+
+static int __init mrstouch_init(void)
+{
+ return platform_driver_register(&mrstouch_driver);
+}
+module_init(mrstouch_init);
+
+static void __exit mrstouch_exit(void)
+{
+ platform_driver_unregister(&mrstouch_driver);
+}
+module_exit(mrstouch_exit);
+
+MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
+MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c
new file mode 100644
index 000000000000..dcf803f5a1f7
--- /dev/null
+++ b/drivers/input/touchscreen/lpc32xx_ts.c
@@ -0,0 +1,411 @@
+/*
+ * LPC32xx built-in touchscreen driver
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+/*
+ * Touchscreen controller register offsets
+ */
+#define LPC32XX_TSC_STAT 0x00
+#define LPC32XX_TSC_SEL 0x04
+#define LPC32XX_TSC_CON 0x08
+#define LPC32XX_TSC_FIFO 0x0C
+#define LPC32XX_TSC_DTR 0x10
+#define LPC32XX_TSC_RTR 0x14
+#define LPC32XX_TSC_UTR 0x18
+#define LPC32XX_TSC_TTR 0x1C
+#define LPC32XX_TSC_DXP 0x20
+#define LPC32XX_TSC_MIN_X 0x24
+#define LPC32XX_TSC_MAX_X 0x28
+#define LPC32XX_TSC_MIN_Y 0x2C
+#define LPC32XX_TSC_MAX_Y 0x30
+#define LPC32XX_TSC_AUX_UTR 0x34
+#define LPC32XX_TSC_AUX_MIN 0x38
+#define LPC32XX_TSC_AUX_MAX 0x3C
+
+#define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8)
+#define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7)
+
+#define LPC32XX_TSC_SEL_DEFVAL 0x0284
+
+#define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11)
+#define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7)
+#define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4)
+#define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2)
+#define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0)
+
+#define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31)
+#define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16)
+#define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF)
+
+#define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF
+
+#define LPC32XX_TSC_MIN_XY_VAL 0x0
+#define LPC32XX_TSC_MAX_XY_VAL 0x3FF
+
+#define MOD_NAME "ts-lpc32xx"
+
+#define tsc_readl(dev, reg) \
+ __raw_readl((dev)->tsc_base + (reg))
+#define tsc_writel(dev, reg, val) \
+ __raw_writel((val), (dev)->tsc_base + (reg))
+
+struct lpc32xx_tsc {
+ struct input_dev *dev;
+ void __iomem *tsc_base;
+ int irq;
+ struct clk *clk;
+};
+
+static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc)
+{
+ while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) &
+ LPC32XX_TSC_STAT_FIFO_EMPTY))
+ tsc_readl(tsc, LPC32XX_TSC_FIFO);
+}
+
+static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id)
+{
+ u32 tmp, rv[4], xs[4], ys[4];
+ int idx;
+ struct lpc32xx_tsc *tsc = dev_id;
+ struct input_dev *input = tsc->dev;
+
+ tmp = tsc_readl(tsc, LPC32XX_TSC_STAT);
+
+ if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) {
+ /* FIFO overflow - throw away samples */
+ lpc32xx_fifo_clear(tsc);
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Gather and normalize 4 samples. Pen-up events may have less
+ * than 4 samples, but its ok to pop 4 and let the last sample
+ * pen status check drop the samples.
+ */
+ idx = 0;
+ while (idx < 4 &&
+ !(tsc_readl(tsc, LPC32XX_TSC_STAT) &
+ LPC32XX_TSC_STAT_FIFO_EMPTY)) {
+ tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO);
+ xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
+ LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp);
+ ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK -
+ LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp);
+ rv[idx] = tmp;
+ idx++;
+ }
+
+ /* Data is only valid if pen is still down in last sample */
+ if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) {
+ /* Use average of 2nd and 3rd sample for position */
+ input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2);
+ input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2);
+ input_report_key(input, BTN_TOUCH, 1);
+ } else {
+ input_report_key(input, BTN_TOUCH, 0);
+ }
+
+ input_sync(input);
+
+ return IRQ_HANDLED;
+}
+
+static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc)
+{
+ /* Disable auto mode */
+ tsc_writel(tsc, LPC32XX_TSC_CON,
+ tsc_readl(tsc, LPC32XX_TSC_CON) &
+ ~LPC32XX_TSC_ADCCON_AUTO_EN);
+
+ clk_disable(tsc->clk);
+}
+
+static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc)
+{
+ u32 tmp;
+
+ clk_enable(tsc->clk);
+
+ tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP;
+
+ /* Set the TSC FIFO depth to 4 samples @ 10-bits per sample (max) */
+ tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 |
+ LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) |
+ LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10);
+ tsc_writel(tsc, LPC32XX_TSC_CON, tmp);
+
+ /* These values are all preset */
+ tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL);
+ tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL);
+ tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL);
+ tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL);
+ tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL);
+
+ /* Aux support is not used */
+ tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0);
+ tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0);
+ tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0);
+
+ /*
+ * Set sample rate to about 240Hz per X/Y pair. A single measurement
+ * consists of 4 pairs which gives about a 60Hz sample rate based on
+ * a stable 32768Hz clock source. Values are in clocks.
+ * Rate is (32768 / (RTR + XCONV + RTR + YCONV + DXP + TTR + UTR) / 4
+ */
+ tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2);
+ tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2);
+ tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10);
+ tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4);
+ tsc_writel(tsc, LPC32XX_TSC_UTR, 88);
+
+ lpc32xx_fifo_clear(tsc);
+
+ /* Enable automatic ts event capture */
+ tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN);
+}
+
+static int lpc32xx_ts_open(struct input_dev *dev)
+{
+ struct lpc32xx_tsc *tsc = input_get_drvdata(dev);
+
+ lpc32xx_setup_tsc(tsc);
+
+ return 0;
+}
+
+static void lpc32xx_ts_close(struct input_dev *dev)
+{
+ struct lpc32xx_tsc *tsc = input_get_drvdata(dev);
+
+ lpc32xx_stop_tsc(tsc);
+}
+
+static int __devinit lpc32xx_ts_probe(struct platform_device *pdev)
+{
+ struct lpc32xx_tsc *tsc;
+ struct input_dev *input;
+ struct resource *res;
+ resource_size_t size;
+ int irq;
+ int error;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Can't get memory resource\n");
+ return -ENOENT;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "Can't get interrupt resource\n");
+ return irq;
+ }
+
+ tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!tsc || !input) {
+ dev_err(&pdev->dev, "failed allocating memory\n");
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ tsc->dev = input;
+ tsc->irq = irq;
+
+ size = resource_size(res);
+
+ if (!request_mem_region(res->start, size, pdev->name)) {
+ dev_err(&pdev->dev, "TSC registers are not free\n");
+ error = -EBUSY;
+ goto err_free_mem;
+ }
+
+ tsc->tsc_base = ioremap(res->start, size);
+ if (!tsc->tsc_base) {
+ dev_err(&pdev->dev, "Can't map memory\n");
+ error = -ENOMEM;
+ goto err_release_mem;
+ }
+
+ tsc->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(tsc->clk)) {
+ dev_err(&pdev->dev, "failed getting clock\n");
+ error = PTR_ERR(tsc->clk);
+ goto err_unmap;
+ }
+
+ input->name = MOD_NAME;
+ input->phys = "lpc32xx/input0";
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0002;
+ input->id.version = 0x0100;
+ input->dev.parent = &pdev->dev;
+ input->open = lpc32xx_ts_open;
+ input->close = lpc32xx_ts_close;
+
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL,
+ LPC32XX_TSC_MAX_XY_VAL, 0, 0);
+ input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL,
+ LPC32XX_TSC_MAX_XY_VAL, 0, 0);
+
+ input_set_drvdata(input, tsc);
+
+ error = request_irq(tsc->irq, lpc32xx_ts_interrupt,
+ IRQF_DISABLED, pdev->name, tsc);
+ if (error) {
+ dev_err(&pdev->dev, "failed requesting interrupt\n");
+ goto err_put_clock;
+ }
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(&pdev->dev, "failed registering input device\n");
+ goto err_free_irq;
+ }
+
+ platform_set_drvdata(pdev, tsc);
+ device_init_wakeup(&pdev->dev, 1);
+
+ return 0;
+
+err_free_irq:
+ free_irq(tsc->irq, tsc);
+err_put_clock:
+ clk_put(tsc->clk);
+err_unmap:
+ iounmap(tsc->tsc_base);
+err_release_mem:
+ release_mem_region(res->start, size);
+err_free_mem:
+ input_free_device(input);
+ kfree(tsc);
+
+ return error;
+}
+
+static int __devexit lpc32xx_ts_remove(struct platform_device *pdev)
+{
+ struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ device_init_wakeup(&pdev->dev, 0);
+ free_irq(tsc->irq, tsc);
+
+ input_unregister_device(tsc->dev);
+
+ clk_put(tsc->clk);
+
+ iounmap(tsc->tsc_base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ kfree(tsc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_ts_suspend(struct device *dev)
+{
+ struct lpc32xx_tsc *tsc = dev_get_drvdata(dev);
+ struct input_dev *input = tsc->dev;
+
+ /*
+ * Suspend and resume can be called when the device hasn't been
+ * enabled. If there are no users that have the device open, then
+ * avoid calling the TSC stop and start functions as the TSC
+ * isn't yet clocked.
+ */
+ mutex_lock(&input->mutex);
+
+ if (input->users) {
+ if (device_may_wakeup(dev))
+ enable_irq_wake(tsc->irq);
+ else
+ lpc32xx_stop_tsc(tsc);
+ }
+
+ mutex_unlock(&input->mutex);
+
+ return 0;
+}
+
+static int lpc32xx_ts_resume(struct device *dev)
+{
+ struct lpc32xx_tsc *tsc = dev_get_drvdata(dev);
+ struct input_dev *input = tsc->dev;
+
+ mutex_lock(&input->mutex);
+
+ if (input->users) {
+ if (device_may_wakeup(dev))
+ disable_irq_wake(tsc->irq);
+ else
+ lpc32xx_setup_tsc(tsc);
+ }
+
+ mutex_unlock(&input->mutex);
+
+ return 0;
+}
+
+static const struct dev_pm_ops lpc32xx_ts_pm_ops = {
+ .suspend = lpc32xx_ts_suspend,
+ .resume = lpc32xx_ts_resume,
+};
+#define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops)
+#else
+#define LPC32XX_TS_PM_OPS NULL
+#endif
+
+static struct platform_driver lpc32xx_ts_driver = {
+ .probe = lpc32xx_ts_probe,
+ .remove = __devexit_p(lpc32xx_ts_remove),
+ .driver = {
+ .name = MOD_NAME,
+ .owner = THIS_MODULE,
+ .pm = LPC32XX_TS_PM_OPS,
+ },
+};
+
+static int __init lpc32xx_ts_init(void)
+{
+ return platform_driver_register(&lpc32xx_ts_driver);
+}
+module_init(lpc32xx_ts_init);
+
+static void __exit lpc32xx_ts_exit(void)
+{
+ platform_driver_unregister(&lpc32xx_ts_driver);
+}
+module_exit(lpc32xx_ts_exit);
+
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com");
+MODULE_DESCRIPTION("LPC32XX TSC Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lpc32xx_ts");
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index 6085d12fd561..8feb7f3c8be1 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -350,7 +350,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
err_tcirq:
free_irq(ts.irq_tc, ts.input);
err_inputdev:
- input_unregister_device(ts.input);
+ input_free_device(ts.input);
err_iomap:
iounmap(ts.io);
err_clk:
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c
index 656148ec0027..ae88e13c99ff 100644
--- a/drivers/input/touchscreen/stmpe-ts.c
+++ b/drivers/input/touchscreen/stmpe-ts.c
@@ -268,7 +268,7 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev)
struct stmpe_touch *ts;
struct input_dev *idev;
struct stmpe_ts_platform_data *ts_pdata = NULL;
- int ret = 0;
+ int ret;
int ts_irq;
ts_irq = platform_get_irq_byname(pdev, "FIFO_TH");
@@ -276,12 +276,16 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev)
return ts_irq;
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
- if (!ts)
+ if (!ts) {
+ ret = -ENOMEM;
goto err_out;
+ }
idev = input_allocate_device();
- if (!idev)
+ if (!idev) {
+ ret = -ENOMEM;
goto err_free_ts;
+ }
platform_set_drvdata(pdev, ts);
ts->stmpe = stmpe;
@@ -361,7 +365,6 @@ static int __devexit stmpe_ts_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
input_unregister_device(ts->idev);
- input_free_device(ts->idev);
kfree(ts);
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index a644d18c04dc..c8c136cf7bbc 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -335,6 +335,7 @@ static int tps6507x_ts_probe(struct platform_device *pdev)
dev_err(tsc->dev, "schedule failed");
goto err2;
}
+ platform_set_drvdata(pdev, tps6507x_dev);
return 0;
@@ -358,7 +359,7 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
cancel_delayed_work_sync(&tsc->work);
destroy_workqueue(tsc->wq);
- input_free_device(input_dev);
+ input_unregister_device(input_dev);
tps6507x_dev->ts = NULL;
kfree(tsc);
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index be23780e8a3e..80467f262331 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -265,7 +265,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tsc2007 *ts;
- struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
+ struct tsc2007_platform_data *pdata = client->dev.platform_data;
struct input_dev *input_dev;
int err;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 56dc35c94bb1..9ae4c7b16ba7 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -2,6 +2,7 @@
* Wacom W8001 penabled serial touchscreen driver
*
* Copyright (c) 2008 Jaya Kumar
+ * Copyright (c) 2010 Red Hat, Inc.
*
* 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
@@ -30,11 +31,24 @@ MODULE_LICENSE("GPL");
#define W8001_LEAD_BYTE 0x80
#define W8001_TAB_MASK 0x40
#define W8001_TAB_BYTE 0x40
+/* set in first byte of touch data packets */
+#define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK)
+#define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE)
#define W8001_QUERY_PACKET 0x20
#define W8001_CMD_START '1'
#define W8001_CMD_QUERY '*'
+#define W8001_CMD_TOUCHQUERY '%'
+
+/* length of data packets in bytes, depends on device. */
+#define W8001_PKTLEN_TOUCH93 5
+#define W8001_PKTLEN_TOUCH9A 7
+#define W8001_PKTLEN_TPCPEN 9
+#define W8001_PKTLEN_TPCCTL 11 /* control packet */
+#define W8001_PKTLEN_TOUCH2FG 13
+
+#define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */
struct w8001_coord {
u8 rdy;
@@ -48,6 +62,15 @@ struct w8001_coord {
u8 tilt_y;
};
+/* touch query reply packet */
+struct w8001_touch_query {
+ u8 panel_res;
+ u8 capacity_res;
+ u8 sensor_id;
+ u16 x;
+ u16 y;
+};
+
/*
* Per-touchscreen data.
*/
@@ -62,6 +85,9 @@ struct w8001 {
unsigned char response[W8001_MAX_LENGTH];
unsigned char data[W8001_MAX_LENGTH];
char phys[32];
+ int type;
+ unsigned int pktlen;
+ int trkid[2];
};
static void parse_data(u8 *data, struct w8001_coord *coord)
@@ -88,11 +114,98 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
coord->tilt_y = data[8] & 0x7F;
}
+static void parse_touch(struct w8001 *w8001)
+{
+ static int trkid;
+ struct input_dev *dev = w8001->dev;
+ unsigned char *data = w8001->data;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ input_mt_slot(dev, i);
+
+ if (data[0] & (1 << i)) {
+ int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]);
+ int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]);
+ /* data[5,6] and [11,12] is finger capacity */
+
+ input_report_abs(dev, ABS_MT_POSITION_X, x);
+ input_report_abs(dev, ABS_MT_POSITION_Y, y);
+ input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
+ if (w8001->trkid[i] < 0)
+ w8001->trkid[i] = trkid++ & MAX_TRACKING_ID;
+ } else {
+ w8001->trkid[i] = -1;
+ }
+ input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]);
+ }
+
+ input_sync(dev);
+}
+
+static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
+{
+ memset(query, 0, sizeof(*query));
+
+ query->panel_res = data[1];
+ query->sensor_id = data[2] & 0x7;
+ query->capacity_res = data[7];
+
+ query->x = data[3] << 9;
+ query->x |= data[4] << 2;
+ query->x |= (data[2] >> 5) & 0x3;
+
+ query->y = data[5] << 9;
+ query->y |= data[6] << 2;
+ query->y |= (data[2] >> 3) & 0x3;
+}
+
+static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
+{
+ struct input_dev *dev = w8001->dev;
+
+ /*
+ * We have 1 bit for proximity (rdy) and 3 bits for tip, side,
+ * side2/eraser. If rdy && f2 are set, this can be either pen + side2,
+ * or eraser. assume
+ * - if dev is already in proximity and f2 is toggled → pen + side2
+ * - if dev comes into proximity with f2 set → eraser
+ * If f2 disappears after assuming eraser, fake proximity out for
+ * eraser and in for pen.
+ */
+
+ if (!w8001->type) {
+ w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+ } else if (w8001->type == BTN_TOOL_RUBBER) {
+ if (!coord->f2) {
+ input_report_abs(dev, ABS_PRESSURE, 0);
+ input_report_key(dev, BTN_TOUCH, 0);
+ input_report_key(dev, BTN_STYLUS, 0);
+ input_report_key(dev, BTN_STYLUS2, 0);
+ input_report_key(dev, BTN_TOOL_RUBBER, 0);
+ input_sync(dev);
+ w8001->type = BTN_TOOL_PEN;
+ }
+ } else {
+ input_report_key(dev, BTN_STYLUS2, coord->f2);
+ }
+
+ input_report_abs(dev, ABS_X, coord->x);
+ input_report_abs(dev, ABS_Y, coord->y);
+ input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure);
+ input_report_key(dev, BTN_TOUCH, coord->tsw);
+ input_report_key(dev, BTN_STYLUS, coord->f1);
+ input_report_key(dev, w8001->type, coord->rdy);
+ input_sync(dev);
+
+ if (!coord->rdy)
+ w8001->type = 0;
+}
+
static irqreturn_t w8001_interrupt(struct serio *serio,
unsigned char data, unsigned int flags)
{
struct w8001 *w8001 = serio_get_drvdata(serio);
- struct input_dev *dev = w8001->dev;
struct w8001_coord coord;
unsigned char tmp;
@@ -105,26 +218,45 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
}
break;
- case 8:
+ case W8001_PKTLEN_TOUCH93 - 1:
+ case W8001_PKTLEN_TOUCH9A - 1:
+ /* ignore one-finger touch packet. */
+ if (w8001->pktlen == w8001->idx)
+ w8001->idx = 0;
+ break;
+
+ /* Pen coordinates packet */
+ case W8001_PKTLEN_TPCPEN - 1:
tmp = w8001->data[0] & W8001_TAB_MASK;
if (unlikely(tmp == W8001_TAB_BYTE))
break;
+ tmp = (w8001->data[0] & W8001_TOUCH_BYTE);
+ if (tmp == W8001_TOUCH_BYTE)
+ break;
+
w8001->idx = 0;
parse_data(w8001->data, &coord);
- input_report_abs(dev, ABS_X, coord.x);
- input_report_abs(dev, ABS_Y, coord.y);
- input_report_abs(dev, ABS_PRESSURE, coord.pen_pressure);
- input_report_key(dev, BTN_TOUCH, coord.tsw);
- input_sync(dev);
+ report_pen_events(w8001, &coord);
break;
- case 10:
+ /* control packet */
+ case W8001_PKTLEN_TPCCTL - 1:
+ tmp = (w8001->data[0] & W8001_TOUCH_MASK);
+ if (tmp == W8001_TOUCH_BYTE)
+ break;
+
w8001->idx = 0;
memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH);
w8001->response_type = W8001_QUERY_PACKET;
complete(&w8001->cmd_done);
break;
+
+ /* 2 finger touch packet */
+ case W8001_PKTLEN_TOUCH2FG - 1:
+ w8001->idx = 0;
+ parse_touch(w8001);
+ break;
}
return IRQ_HANDLED;
@@ -167,6 +299,38 @@ static int w8001_setup(struct w8001 *w8001)
input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
+ error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true);
+ if (!error) {
+ struct w8001_touch_query touch;
+
+ parse_touchquery(w8001->response, &touch);
+
+ switch (touch.sensor_id) {
+ case 0:
+ case 2:
+ w8001->pktlen = W8001_PKTLEN_TOUCH93;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ w8001->pktlen = W8001_PKTLEN_TOUCH9A;
+ break;
+ case 5:
+ w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
+
+ input_mt_create_slots(dev, 2);
+ input_set_abs_params(dev, ABS_MT_TRACKING_ID,
+ 0, MAX_TRACKING_ID, 0, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_X,
+ 0, touch.x, 0, 0);
+ input_set_abs_params(dev, ABS_MT_POSITION_Y,
+ 0, touch.y, 0, 0);
+ input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
+ 0, 0, 0, 0);
+ break;
+ }
+ }
+
return w8001_command(w8001, W8001_CMD_START, false);
}
@@ -208,6 +372,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
w8001->serio = serio;
w8001->id = serio->id.id;
w8001->dev = input_dev;
+ w8001->trkid[0] = w8001->trkid[1] = -1;
init_completion(&w8001->cmd_done);
snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
@@ -221,6 +386,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN);
+ input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER);
+ input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS);
+ input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2);
serio_set_drvdata(serio, w8001);
err = serio_open(serio, drv);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index cbfef1ea7e30..6b75c9f660ae 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -125,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
{
int power_adc = 0, auxval;
u16 power = 0;
+ int rc = 0;
+ int timeout = 0;
/* get codec */
mutex_lock(&wm->codec_mutex);
@@ -143,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
/* Turn polling mode on to read AUX ADC */
wm->pen_probably_down = 1;
- wm->codec->poll_sample(wm, adcsel, &auxval);
+
+ while (rc != RC_VALID && timeout++ < 5)
+ rc = wm->codec->poll_sample(wm, adcsel, &auxval);
if (power_adc)
wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
@@ -152,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
wm->pen_probably_down = 0;
+ if (timeout >= 5) {
+ dev_err(wm->dev,
+ "timeout reading auxadc %d, disabling digitiser\n",
+ adcsel);
+ wm->codec->dig_enable(wm, false);
+ }
+
mutex_unlock(&wm->codec_mutex);
- return auxval & 0xfff;
+ return (rc == RC_VALID ? auxval & 0xfff : -EBUSY);
}
EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
@@ -684,8 +695,7 @@ static int wm97xx_probe(struct device *dev)
touch_reg_err:
platform_device_put(wm->touch_dev);
touch_err:
- platform_device_unregister(wm->battery_dev);
- wm->battery_dev = NULL;
+ platform_device_del(wm->battery_dev);
batt_reg_err:
platform_device_put(wm->battery_dev);
batt_err:
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 2978bdaa6b88..e54e79d4e2c1 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -1515,8 +1515,13 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
while (*s) {
int digit1 = 0;
int digit2 = 0;
- if (!isdigit(*s)) return -3;
- while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; }
+ char *endp;
+
+ digit1 = simple_strtoul(s, &endp, 10);
+ if (s == endp)
+ return -3;
+ s = endp;
+
if (digit1 <= 0 || digit1 > 30) return -4;
if (*s == 0 || *s == ',' || *s == ' ') {
bmask |= (1 << digit1);
@@ -1526,8 +1531,12 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
}
if (*s != '-') return -5;
s++;
- if (!isdigit(*s)) return -3;
- while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; }
+
+ digit2 = simple_strtoul(s, &endp, 10);
+ if (s == endp)
+ return -3;
+ s = endp;
+
if (digit2 <= 0 || digit2 > 30) return -4;
if (*s == 0 || *s == ',' || *s == ' ') {
if (digit1 > digit2)
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 2b83850997c3..c559b5265410 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/sched.h> /* current */
+#include <linux/smp_lock.h> /* For lock_kernel() */
#include "capifs.h"
@@ -99,6 +100,8 @@ capifs_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * inode;
+ lock_kernel();
+
s->s_blocksize = 1024;
s->s_blocksize_bits = 10;
s->s_magic = CAPIFS_SUPER_MAGIC;
@@ -116,12 +119,15 @@ capifs_fill_super(struct super_block *s, void *data, int silent)
inode->i_nlink = 2;
s->s_root = d_alloc_root(inode);
- if (s->s_root)
+ if (s->s_root) {
+ unlock_kernel();
return 0;
-
+ }
+
printk("capifs: get root dentry failed\n");
iput(inode);
fail:
+ unlock_kernel();
return -ENOMEM;
}
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 70cf6bac7a5a..48e6d220f62c 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -77,7 +77,7 @@ static void deflect_timer_expire(ulong arg)
case DEFLECT_ALERT:
cs->ics.command = ISDN_CMD_REDIR; /* protocol */
- strcpy(cs->ics.parm.setup.phone,cs->deflect_dest);
+ strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone));
strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed");
divert_if.ll_cmd(&cs->ics);
spin_lock_irqsave(&divert_lock, flags);
@@ -251,7 +251,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
case 2: /* redir */
del_timer(&cs->timer);
- strcpy(cs->ics.parm.setup.phone, to_nr);
+ strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone));
strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
ic.command = ISDN_CMD_REDIR;
if ((i = divert_if.ll_cmd(&ic)))
@@ -480,7 +480,7 @@ static int isdn_divert_icall(isdn_ctrl *ic)
if (!cs->timer.expires)
{ strcpy(ic->parm.setup.eazmsn,"Testtext direct");
ic->parm.setup.screen = dv->rule.screen;
- strcpy(ic->parm.setup.phone,dv->rule.to_nr);
+ strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
retval = 5;
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index be5faf4aa868..5aa138eb0b3c 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -234,13 +234,14 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
count++;
if (count > trans_max)
count = trans_max; /* limit length */
- if ((skb = dev_alloc_skb(count))) {
- dst = skb_put(skb, count);
- while (count--)
+ skb = dev_alloc_skb(count);
+ if (skb) {
+ dst = skb_put(skb, count);
+ while (count--)
*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
- return(skb);
- }
- else return(NULL); /* no memory */
+ return skb;
+ } else
+ return NULL; /* no memory */
}
do {
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 981f7abe008c..c463162843ba 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -3516,7 +3516,7 @@ isdn_tty_parse_at(modem_info * info)
{
atemu *m = &info->emu;
char *p;
- char ds[40];
+ char ds[ISDN_MSNLEN];
#ifdef ISDN_DEBUG_AT
printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd);
@@ -3595,7 +3595,7 @@ isdn_tty_parse_at(modem_info * info)
break;
case '3':
p++;
- sprintf(ds, "\r\n%d", info->emu.charge);
+ snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge);
isdn_tty_at_cout(ds, info);
break;
default:;
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 713ef2b805a2..76d9e673b4e1 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1237,6 +1237,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
if (dsp->cmx_delay)
dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
& CMX_BUFF_MASK;
+ else
dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1))
& CMX_BUFF_MASK;
} else {
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 22f38e48ac4e..5b59796ed250 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -972,7 +972,7 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
if (debug & DEBUG_L1OIP_SOCKET)
printk(KERN_DEBUG "%s: got new ip address from user "
"space.\n", __func__);
- l1oip_socket_open(hc);
+ l1oip_socket_open(hc);
break;
case MISDN_CTRL_UNSETPEER:
if (debug & DEBUG_L1OIP_SOCKET)
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index de43c8c70ad0..502a5fb7febc 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -267,6 +267,7 @@ static const struct file_operations mISDN_fops = {
.unlocked_ioctl = mISDN_ioctl,
.open = mISDN_open,
.release = mISDN_close,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice mISDNtimer = {
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 85b714df8eae..8d71d43cab64 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -514,6 +514,7 @@ static const struct file_operations lguest_fops = {
.release = close,
.write = write,
.read = read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
/*
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 1c4ee6e77937..e75e3be50811 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -24,7 +24,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
@@ -55,6 +54,7 @@ extern struct adb_driver adb_iop_driver;
extern struct adb_driver via_pmu_driver;
extern struct adb_driver macio_adb_driver;
+static DEFINE_MUTEX(adb_mutex);
static struct adb_driver *adb_driver_list[] = {
#ifdef CONFIG_ADB_MACII
&via_macii_driver,
@@ -647,7 +647,7 @@ static int adb_open(struct inode *inode, struct file *file)
struct adbdev_state *state;
int ret = 0;
- lock_kernel();
+ mutex_lock(&adb_mutex);
if (iminor(inode) > 0 || adb_controller == NULL) {
ret = -ENXIO;
goto out;
@@ -665,7 +665,7 @@ static int adb_open(struct inode *inode, struct file *file)
state->inuse = 1;
out:
- unlock_kernel();
+ mutex_unlock(&adb_mutex);
return ret;
}
@@ -674,7 +674,7 @@ static int adb_release(struct inode *inode, struct file *file)
struct adbdev_state *state = file->private_data;
unsigned long flags;
- lock_kernel();
+ mutex_lock(&adb_mutex);
if (state) {
file->private_data = NULL;
spin_lock_irqsave(&state->lock, flags);
@@ -687,7 +687,7 @@ static int adb_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&state->lock, flags);
}
}
- unlock_kernel();
+ mutex_unlock(&adb_mutex);
return 0;
}
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index a3d25da2f275..d4559e0e8b9a 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -137,6 +137,7 @@ const struct file_operations anslcd_fops = {
.write = anslcd_write,
.unlocked_ioctl = anslcd_ioctl,
.open = anslcd_open,
+ .llseek = default_llseek,/* write accesses f_pos */
};
static struct miscdevice anslcd_dev = {
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index e58c3d33e035..290cb325a94c 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -19,7 +19,6 @@
* the userland interface
*/
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
@@ -97,6 +96,7 @@ struct smu_device {
* I don't think there will ever be more than one SMU, so
* for now, just hard code that
*/
+static DEFINE_MUTEX(smu_mutex);
static struct smu_device *smu;
static DEFINE_MUTEX(smu_part_access);
static int smu_irq_inited;
@@ -1095,12 +1095,12 @@ static int smu_open(struct inode *inode, struct file *file)
pp->mode = smu_file_commands;
init_waitqueue_head(&pp->wait);
- lock_kernel();
+ mutex_lock(&smu_mutex);
spin_lock_irqsave(&smu_clist_lock, flags);
list_add(&pp->list, &smu_clist);
spin_unlock_irqrestore(&smu_clist_lock, flags);
file->private_data = pp;
- unlock_kernel();
+ mutex_unlock(&smu_mutex);
return 0;
}
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index d242976bcfe7..19c371809d77 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -92,8 +92,10 @@ static int __init via_pmu_led_init(void)
if (dt == NULL)
return -ENODEV;
model = of_get_property(dt, "model", NULL);
- if (model == NULL)
+ if (model == NULL) {
+ of_node_put(dt);
return -ENODEV;
+ }
if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
strncmp(model, "iBook", strlen("iBook")) != 0 &&
strcmp(model, "PowerMac7,2") != 0 &&
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 2d17e76066bd..3fcee6121803 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -18,7 +18,7 @@
*
*/
#include <stdarg.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -73,6 +73,7 @@
/* How many iterations between battery polls */
#define BATTERY_POLLING_COUNT 2
+static DEFINE_MUTEX(pmu_info_proc_mutex);
static volatile unsigned char __iomem *via;
/* VIA registers - spaced 0x200 bytes apart */
@@ -2078,7 +2079,7 @@ pmu_open(struct inode *inode, struct file *file)
pp->rb_get = pp->rb_put = 0;
spin_lock_init(&pp->lock);
init_waitqueue_head(&pp->wait);
- lock_kernel();
+ mutex_lock(&pmu_info_proc_mutex);
spin_lock_irqsave(&all_pvt_lock, flags);
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
pp->backlight_locker = 0;
@@ -2086,7 +2087,7 @@ pmu_open(struct inode *inode, struct file *file)
list_add(&pp->list, &all_pmu_pvt);
spin_unlock_irqrestore(&all_pvt_lock, flags);
file->private_data = pp;
- unlock_kernel();
+ mutex_unlock(&pmu_info_proc_mutex);
return 0;
}
@@ -2343,9 +2344,9 @@ static long pmu_unlocked_ioctl(struct file *filp,
{
int ret;
- lock_kernel();
+ mutex_lock(&pmu_info_proc_mutex);
ret = pmu_ioctl(filp, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&pmu_info_proc_mutex);
return ret;
}
@@ -2398,6 +2399,7 @@ static const struct file_operations pmu_device_fops = {
#endif
.open = pmu_open,
.release = pmu_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct miscdevice pmu_device = {
diff --git a/drivers/md/.gitignore b/drivers/md/.gitignore
deleted file mode 100644
index a7afec6b19c6..000000000000
--- a/drivers/md/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-mktables
-raid6altivec*.c
-raid6int*.c
-raid6tables.c
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 1ba1e122e948..ed4900ade93a 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1542,8 +1542,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
atomic_read(&bitmap->mddev->recovery_active) == 0);
bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
- if (bitmap->mddev->persistent)
- set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
+ set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
s = 0;
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 368e8e98f705..d5b0e4c0e702 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1278,7 +1278,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
struct dm_crypt_io *io;
struct crypt_config *cc;
- if (unlikely(bio_empty_barrier(bio))) {
+ if (bio->bi_rw & REQ_FLUSH) {
cc = ti->private;
bio->bi_bdev = cc->dev->bdev;
return DM_MAPIO_REMAPPED;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 0590c75b0ab6..136d4f71a116 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -31,7 +31,6 @@ struct dm_io_client {
*/
struct io {
unsigned long error_bits;
- unsigned long eopnotsupp_bits;
atomic_t count;
struct task_struct *sleeper;
struct dm_io_client *client;
@@ -130,11 +129,8 @@ static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io,
*---------------------------------------------------------------*/
static void dec_count(struct io *io, unsigned int region, int error)
{
- if (error) {
+ if (error)
set_bit(region, &io->error_bits);
- if (error == -EOPNOTSUPP)
- set_bit(region, &io->eopnotsupp_bits);
- }
if (atomic_dec_and_test(&io->count)) {
if (io->sleeper)
@@ -310,8 +306,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
sector_t remaining = where->count;
/*
- * where->count may be zero if rw holds a write barrier and we
- * need to send a zero-sized barrier.
+ * where->count may be zero if rw holds a flush and we need to
+ * send a zero-sized flush.
*/
do {
/*
@@ -364,7 +360,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
*/
for (i = 0; i < num_regions; i++) {
*dp = old_pages;
- if (where[i].count || (rw & REQ_HARDBARRIER))
+ if (where[i].count || (rw & REQ_FLUSH))
do_region(rw, i, where + i, dp, io);
}
@@ -393,9 +389,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
return -EIO;
}
-retry:
io->error_bits = 0;
- io->eopnotsupp_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
io->sleeper = current;
io->client = client;
@@ -412,11 +406,6 @@ retry:
}
set_current_state(TASK_RUNNING);
- if (io->eopnotsupp_bits && (rw & REQ_HARDBARRIER)) {
- rw &= ~REQ_HARDBARRIER;
- goto retry;
- }
-
if (error_bits)
*error_bits = io->error_bits;
@@ -437,7 +426,6 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,
io = mempool_alloc(client->pool, GFP_NOIO);
io->error_bits = 0;
- io->eopnotsupp_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
io->sleeper = NULL;
io->client = client;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 3e39193e5036..04001e80188c 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1596,6 +1596,7 @@ static const struct file_operations _ctl_fops = {
.unlocked_ioctl = dm_ctl_ioctl,
.compat_ioctl = dm_compat_ctl_ioctl,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice _dm_misc = {
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 5a08be0222db..33420e68d153 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -300,7 +300,7 @@ static int flush_header(struct log_c *lc)
.count = 0,
};
- lc->io_req.bi_rw = WRITE_BARRIER;
+ lc->io_req.bi_rw = WRITE_FLUSH;
return dm_io(&lc->io_req, 1, &null_location, NULL);
}
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 7c081bcbc3cf..19a59b041c27 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -259,7 +259,7 @@ static int mirror_flush(struct dm_target *ti)
struct dm_io_region io[ms->nr_mirrors];
struct mirror *m;
struct dm_io_request io_req = {
- .bi_rw = WRITE_BARRIER,
+ .bi_rw = WRITE_FLUSH,
.mem.type = DM_IO_KMEM,
.mem.ptr.bvec = NULL,
.client = ms->io_client,
@@ -629,7 +629,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
struct dm_io_region io[ms->nr_mirrors], *dest = io;
struct mirror *m;
struct dm_io_request io_req = {
- .bi_rw = WRITE | (bio->bi_rw & WRITE_BARRIER),
+ .bi_rw = WRITE | (bio->bi_rw & WRITE_FLUSH_FUA),
.mem.type = DM_IO_BVEC,
.mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx,
.notify.fn = write_callback,
@@ -670,7 +670,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- if (unlikely(bio_empty_barrier(bio))) {
+ if (bio->bi_rw & REQ_FLUSH) {
bio_list_add(&sync, bio);
continue;
}
@@ -1203,7 +1203,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
* We need to dec pending if this was a write.
*/
if (rw == WRITE) {
- if (likely(!bio_empty_barrier(bio)))
+ if (!(bio->bi_rw & REQ_FLUSH))
dm_rh_dec(ms->rh, map_context->ll);
return error;
}
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index bd5c58b28868..dad011aed0c9 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -81,9 +81,9 @@ struct dm_region_hash {
struct list_head failed_recovered_regions;
/*
- * If there was a barrier failure no regions can be marked clean.
+ * If there was a flush failure no regions can be marked clean.
*/
- int barrier_failure;
+ int flush_failure;
void *context;
sector_t target_begin;
@@ -217,7 +217,7 @@ struct dm_region_hash *dm_region_hash_create(
INIT_LIST_HEAD(&rh->quiesced_regions);
INIT_LIST_HEAD(&rh->recovered_regions);
INIT_LIST_HEAD(&rh->failed_recovered_regions);
- rh->barrier_failure = 0;
+ rh->flush_failure = 0;
rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
sizeof(struct dm_region));
@@ -399,8 +399,8 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
region_t region = dm_rh_bio_to_region(rh, bio);
int recovering = 0;
- if (bio_empty_barrier(bio)) {
- rh->barrier_failure = 1;
+ if (bio->bi_rw & REQ_FLUSH) {
+ rh->flush_failure = 1;
return;
}
@@ -524,7 +524,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
struct bio *bio;
for (bio = bios->head; bio; bio = bio->bi_next) {
- if (bio_empty_barrier(bio))
+ if (bio->bi_rw & REQ_FLUSH)
continue;
rh_inc(rh, dm_rh_bio_to_region(rh, bio));
}
@@ -555,9 +555,9 @@ void dm_rh_dec(struct dm_region_hash *rh, region_t region)
*/
/* do nothing for DM_RH_NOSYNC */
- if (unlikely(rh->barrier_failure)) {
+ if (unlikely(rh->flush_failure)) {
/*
- * If a write barrier failed some time ago, we
+ * If a write flush failed some time ago, we
* don't know whether or not this write made it
* to the disk, so we must resync the device.
*/
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index cc2bdb83f9ad..0b61792a2780 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -687,7 +687,7 @@ static void persistent_commit_exception(struct dm_exception_store *store,
/*
* Commit exceptions to disk.
*/
- if (ps->valid && area_io(ps, WRITE_BARRIER))
+ if (ps->valid && area_io(ps, WRITE_FLUSH_FUA))
ps->valid = 0;
/*
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 5974d3094d97..eed210152b75 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1587,7 +1587,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
chunk_t chunk;
struct dm_snap_pending_exception *pe = NULL;
- if (unlikely(bio_empty_barrier(bio))) {
+ if (bio->bi_rw & REQ_FLUSH) {
bio->bi_bdev = s->cow->bdev;
return DM_MAPIO_REMAPPED;
}
@@ -1691,7 +1691,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio,
int r = DM_MAPIO_REMAPPED;
chunk_t chunk;
- if (unlikely(bio_empty_barrier(bio))) {
+ if (bio->bi_rw & REQ_FLUSH) {
if (!map_context->target_request_nr)
bio->bi_bdev = s->origin->bdev;
else
@@ -2135,7 +2135,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
struct dm_dev *dev = ti->private;
bio->bi_bdev = dev->bdev;
- if (unlikely(bio_empty_barrier(bio)))
+ if (bio->bi_rw & REQ_FLUSH)
return DM_MAPIO_REMAPPED;
/* Only tell snapshots if this is a write */
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index c297f6da91ea..f0371b4c4fbf 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -271,7 +271,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio,
uint32_t stripe;
unsigned target_request_nr;
- if (unlikely(bio_empty_barrier(bio))) {
+ if (bio->bi_rw & REQ_FLUSH) {
target_request_nr = map_context->target_request_nr;
BUG_ON(target_request_nr >= sc->stripes);
bio->bi_bdev = sc->stripe[target_request_nr].dev->bdev;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ac384b2a6a33..7cb1352f7e7a 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -15,7 +15,6 @@
#include <linux/blkpg.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include <linux/idr.h>
@@ -33,6 +32,7 @@
#define DM_COOKIE_ENV_VAR_NAME "DM_COOKIE"
#define DM_COOKIE_LENGTH 24
+static DEFINE_MUTEX(dm_mutex);
static const char *_name = DM_NAME;
static unsigned int major = 0;
@@ -110,7 +110,6 @@ EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo);
#define DMF_FREEING 3
#define DMF_DELETING 4
#define DMF_NOFLUSH_SUSPENDING 5
-#define DMF_QUEUE_IO_TO_THREAD 6
/*
* Work processed by per-device workqueue.
@@ -144,24 +143,9 @@ struct mapped_device {
spinlock_t deferred_lock;
/*
- * An error from the barrier request currently being processed.
- */
- int barrier_error;
-
- /*
- * Protect barrier_error from concurrent endio processing
- * in request-based dm.
- */
- spinlock_t barrier_error_lock;
-
- /*
- * Processing queue (flush/barriers)
+ * Processing queue (flush)
*/
struct workqueue_struct *wq;
- struct work_struct barrier_work;
-
- /* A pointer to the currently processing pre/post flush request */
- struct request *flush_request;
/*
* The current mapping.
@@ -200,8 +184,8 @@ struct mapped_device {
/* sysfs handle */
struct kobject kobj;
- /* zero-length barrier that will be cloned and submitted to targets */
- struct bio barrier_bio;
+ /* zero-length flush that will be cloned and submitted to targets */
+ struct bio flush_bio;
};
/*
@@ -344,7 +328,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode)
{
struct mapped_device *md;
- lock_kernel();
+ mutex_lock(&dm_mutex);
spin_lock(&_minor_lock);
md = bdev->bd_disk->private_data;
@@ -362,7 +346,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode)
out:
spin_unlock(&_minor_lock);
- unlock_kernel();
+ mutex_unlock(&dm_mutex);
return md ? 0 : -ENXIO;
}
@@ -371,10 +355,10 @@ static int dm_blk_close(struct gendisk *disk, fmode_t mode)
{
struct mapped_device *md = disk->private_data;
- lock_kernel();
+ mutex_lock(&dm_mutex);
atomic_dec(&md->open_count);
dm_put(md);
- unlock_kernel();
+ mutex_unlock(&dm_mutex);
return 0;
}
@@ -512,7 +496,7 @@ static void end_io_acct(struct dm_io *io)
/*
* After this is decremented the bio must not be touched if it is
- * a barrier.
+ * a flush.
*/
dm_disk(md)->part0.in_flight[rw] = pending =
atomic_dec_return(&md->pending[rw]);
@@ -528,16 +512,12 @@ static void end_io_acct(struct dm_io *io)
*/
static void queue_io(struct mapped_device *md, struct bio *bio)
{
- down_write(&md->io_lock);
+ unsigned long flags;
- spin_lock_irq(&md->deferred_lock);
+ spin_lock_irqsave(&md->deferred_lock, flags);
bio_list_add(&md->deferred, bio);
- spin_unlock_irq(&md->deferred_lock);
-
- if (!test_and_set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags))
- queue_work(md->wq, &md->work);
-
- up_write(&md->io_lock);
+ spin_unlock_irqrestore(&md->deferred_lock, flags);
+ queue_work(md->wq, &md->work);
}
/*
@@ -625,11 +605,9 @@ static void dec_pending(struct dm_io *io, int error)
* Target requested pushing back the I/O.
*/
spin_lock_irqsave(&md->deferred_lock, flags);
- if (__noflush_suspending(md)) {
- if (!(io->bio->bi_rw & REQ_HARDBARRIER))
- bio_list_add_head(&md->deferred,
- io->bio);
- } else
+ if (__noflush_suspending(md))
+ bio_list_add_head(&md->deferred, io->bio);
+ else
/* noflush suspend was interrupted. */
io->error = -EIO;
spin_unlock_irqrestore(&md->deferred_lock, flags);
@@ -637,32 +615,23 @@ static void dec_pending(struct dm_io *io, int error)
io_error = io->error;
bio = io->bio;
+ end_io_acct(io);
+ free_io(md, io);
+
+ if (io_error == DM_ENDIO_REQUEUE)
+ return;
- if (bio->bi_rw & REQ_HARDBARRIER) {
+ if ((bio->bi_rw & REQ_FLUSH) && bio->bi_size) {
/*
- * There can be just one barrier request so we use
- * a per-device variable for error reporting.
- * Note that you can't touch the bio after end_io_acct
- *
- * We ignore -EOPNOTSUPP for empty flush reported by
- * underlying devices. We assume that if the device
- * doesn't support empty barriers, it doesn't need
- * cache flushing commands.
+ * Preflush done for flush with data, reissue
+ * without REQ_FLUSH.
*/
- if (!md->barrier_error &&
- !(bio_empty_barrier(bio) && io_error == -EOPNOTSUPP))
- md->barrier_error = io_error;
- end_io_acct(io);
- free_io(md, io);
+ bio->bi_rw &= ~REQ_FLUSH;
+ queue_io(md, bio);
} else {
- end_io_acct(io);
- free_io(md, io);
-
- if (io_error != DM_ENDIO_REQUEUE) {
- trace_block_bio_complete(md->queue, bio);
-
- bio_endio(bio, io_error);
- }
+ /* done with normal IO or empty flush */
+ trace_block_bio_complete(md->queue, bio);
+ bio_endio(bio, io_error);
}
}
}
@@ -755,23 +724,6 @@ static void end_clone_bio(struct bio *clone, int error)
blk_update_request(tio->orig, 0, nr_bytes);
}
-static void store_barrier_error(struct mapped_device *md, int error)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&md->barrier_error_lock, flags);
- /*
- * Basically, the first error is taken, but:
- * -EOPNOTSUPP supersedes any I/O error.
- * Requeue request supersedes any I/O error but -EOPNOTSUPP.
- */
- if (!md->barrier_error || error == -EOPNOTSUPP ||
- (md->barrier_error != -EOPNOTSUPP &&
- error == DM_ENDIO_REQUEUE))
- md->barrier_error = error;
- spin_unlock_irqrestore(&md->barrier_error_lock, flags);
-}
-
/*
* Don't touch any member of the md after calling this function because
* the md may be freed in dm_put() at the end of this function.
@@ -809,13 +761,11 @@ static void free_rq_clone(struct request *clone)
static void dm_end_request(struct request *clone, int error)
{
int rw = rq_data_dir(clone);
- int run_queue = 1;
- bool is_barrier = clone->cmd_flags & REQ_HARDBARRIER;
struct dm_rq_target_io *tio = clone->end_io_data;
struct mapped_device *md = tio->md;
struct request *rq = tio->orig;
- if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !is_barrier) {
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
rq->errors = clone->errors;
rq->resid_len = clone->resid_len;
@@ -829,15 +779,8 @@ static void dm_end_request(struct request *clone, int error)
}
free_rq_clone(clone);
-
- if (unlikely(is_barrier)) {
- if (unlikely(error))
- store_barrier_error(md, error);
- run_queue = 0;
- } else
- blk_end_request_all(rq, error);
-
- rq_completed(md, rw, run_queue);
+ blk_end_request_all(rq, error);
+ rq_completed(md, rw, true);
}
static void dm_unprep_request(struct request *rq)
@@ -862,16 +805,6 @@ void dm_requeue_unmapped_request(struct request *clone)
struct request_queue *q = rq->q;
unsigned long flags;
- if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) {
- /*
- * Barrier clones share an original request.
- * Leave it to dm_end_request(), which handles this special
- * case.
- */
- dm_end_request(clone, DM_ENDIO_REQUEUE);
- return;
- }
-
dm_unprep_request(rq);
spin_lock_irqsave(q->queue_lock, flags);
@@ -961,19 +894,6 @@ static void dm_complete_request(struct request *clone, int error)
struct dm_rq_target_io *tio = clone->end_io_data;
struct request *rq = tio->orig;
- if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) {
- /*
- * Barrier clones share an original request. So can't use
- * softirq_done with the original.
- * Pass the clone to dm_done() directly in this special case.
- * It is safe (even if clone->q->queue_lock is held here)
- * because there is no I/O dispatching during the completion
- * of barrier clone.
- */
- dm_done(clone, error, true);
- return;
- }
-
tio->error = error;
rq->completion_data = clone;
blk_complete_request(rq);
@@ -990,17 +910,6 @@ void dm_kill_unmapped_request(struct request *clone, int error)
struct dm_rq_target_io *tio = clone->end_io_data;
struct request *rq = tio->orig;
- if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) {
- /*
- * Barrier clones share an original request.
- * Leave it to dm_end_request(), which handles this special
- * case.
- */
- BUG_ON(error > 0);
- dm_end_request(clone, error);
- return;
- }
-
rq->cmd_flags |= REQ_FAILED;
dm_complete_request(clone, error);
}
@@ -1119,7 +1028,7 @@ static void dm_bio_destructor(struct bio *bio)
}
/*
- * Creates a little bio that is just does part of a bvec.
+ * Creates a little bio that just does part of a bvec.
*/
static struct bio *split_bvec(struct bio *bio, sector_t sector,
unsigned short idx, unsigned int offset,
@@ -1134,7 +1043,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
clone->bi_sector = sector;
clone->bi_bdev = bio->bi_bdev;
- clone->bi_rw = bio->bi_rw & ~REQ_HARDBARRIER;
+ clone->bi_rw = bio->bi_rw;
clone->bi_vcnt = 1;
clone->bi_size = to_bytes(len);
clone->bi_io_vec->bv_offset = offset;
@@ -1161,7 +1070,6 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
__bio_clone(clone, bio);
- clone->bi_rw &= ~REQ_HARDBARRIER;
clone->bi_destructor = dm_bio_destructor;
clone->bi_sector = sector;
clone->bi_idx = idx;
@@ -1225,16 +1133,15 @@ static void __issue_target_requests(struct clone_info *ci, struct dm_target *ti,
__issue_target_request(ci, ti, request_nr, len);
}
-static int __clone_and_map_empty_barrier(struct clone_info *ci)
+static int __clone_and_map_empty_flush(struct clone_info *ci)
{
unsigned target_nr = 0;
struct dm_target *ti;
+ BUG_ON(bio_has_data(ci->bio));
while ((ti = dm_table_get_target(ci->map, target_nr++)))
__issue_target_requests(ci, ti, ti->num_flush_requests, 0);
- ci->sector_count = 0;
-
return 0;
}
@@ -1289,9 +1196,6 @@ static int __clone_and_map(struct clone_info *ci)
sector_t len = 0, max;
struct dm_target_io *tio;
- if (unlikely(bio_empty_barrier(bio)))
- return __clone_and_map_empty_barrier(ci);
-
if (unlikely(bio->bi_rw & REQ_DISCARD))
return __clone_and_map_discard(ci);
@@ -1383,16 +1287,11 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
ci.map = dm_get_live_table(md);
if (unlikely(!ci.map)) {
- if (!(bio->bi_rw & REQ_HARDBARRIER))
- bio_io_error(bio);
- else
- if (!md->barrier_error)
- md->barrier_error = -EIO;
+ bio_io_error(bio);
return;
}
ci.md = md;
- ci.bio = bio;
ci.io = alloc_io(md);
ci.io->error = 0;
atomic_set(&ci.io->io_count, 1);
@@ -1400,14 +1299,20 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
ci.io->md = md;
spin_lock_init(&ci.io->endio_lock);
ci.sector = bio->bi_sector;
- ci.sector_count = bio_sectors(bio);
- if (unlikely(bio_empty_barrier(bio)))
- ci.sector_count = 1;
ci.idx = bio->bi_idx;
start_io_acct(ci.io);
- while (ci.sector_count && !error)
- error = __clone_and_map(&ci);
+ if (bio->bi_rw & REQ_FLUSH) {
+ ci.bio = &ci.md->flush_bio;
+ ci.sector_count = 0;
+ error = __clone_and_map_empty_flush(&ci);
+ /* dec_pending submits any data associated with flush */
+ } else {
+ ci.bio = bio;
+ ci.sector_count = bio_sectors(bio);
+ while (ci.sector_count && !error)
+ error = __clone_and_map(&ci);
+ }
/* drop the extra reference count */
dec_pending(ci.io, error);
@@ -1491,22 +1396,14 @@ static int _dm_request(struct request_queue *q, struct bio *bio)
part_stat_add(cpu, &dm_disk(md)->part0, sectors[rw], bio_sectors(bio));
part_stat_unlock();
- /*
- * If we're suspended or the thread is processing barriers
- * we have to queue this io for later.
- */
- if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) ||
- unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
+ /* if we're suspended, we have to queue this io for later */
+ if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
up_read(&md->io_lock);
- if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) &&
- bio_rw(bio) == READA) {
+ if (bio_rw(bio) != READA)
+ queue_io(md, bio);
+ else
bio_io_error(bio);
- return 0;
- }
-
- queue_io(md, bio);
-
return 0;
}
@@ -1537,14 +1434,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
return _dm_request(q, bio);
}
-static bool dm_rq_is_flush_request(struct request *rq)
-{
- if (rq->cmd_flags & REQ_FLUSH)
- return true;
- else
- return false;
-}
-
void dm_dispatch_request(struct request *rq)
{
int r;
@@ -1592,22 +1481,15 @@ static int setup_clone(struct request *clone, struct request *rq,
{
int r;
- if (dm_rq_is_flush_request(rq)) {
- blk_rq_init(NULL, clone);
- clone->cmd_type = REQ_TYPE_FS;
- clone->cmd_flags |= (REQ_HARDBARRIER | WRITE);
- } else {
- r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC,
- dm_rq_bio_constructor, tio);
- if (r)
- return r;
-
- clone->cmd = rq->cmd;
- clone->cmd_len = rq->cmd_len;
- clone->sense = rq->sense;
- clone->buffer = rq->buffer;
- }
+ r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC,
+ dm_rq_bio_constructor, tio);
+ if (r)
+ return r;
+ clone->cmd = rq->cmd;
+ clone->cmd_len = rq->cmd_len;
+ clone->sense = rq->sense;
+ clone->buffer = rq->buffer;
clone->end_io = end_clone_request;
clone->end_io_data = tio;
@@ -1648,9 +1530,6 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq)
struct mapped_device *md = q->queuedata;
struct request *clone;
- if (unlikely(dm_rq_is_flush_request(rq)))
- return BLKPREP_OK;
-
if (unlikely(rq->special)) {
DMWARN("Already has something in rq->special.");
return BLKPREP_KILL;
@@ -1727,6 +1606,7 @@ static void dm_request_fn(struct request_queue *q)
struct dm_table *map = dm_get_live_table(md);
struct dm_target *ti;
struct request *rq, *clone;
+ sector_t pos;
/*
* For suspend, check blk_queue_stopped() and increment
@@ -1739,15 +1619,14 @@ static void dm_request_fn(struct request_queue *q)
if (!rq)
goto plug_and_out;
- if (unlikely(dm_rq_is_flush_request(rq))) {
- BUG_ON(md->flush_request);
- md->flush_request = rq;
- blk_start_request(rq);
- queue_work(md->wq, &md->barrier_work);
- goto out;
- }
+ /* always use block 0 to find the target for flushes for now */
+ pos = 0;
+ if (!(rq->cmd_flags & REQ_FLUSH))
+ pos = blk_rq_pos(rq);
+
+ ti = dm_table_find_target(map, pos);
+ BUG_ON(!dm_target_is_valid(ti));
- ti = dm_table_find_target(map, blk_rq_pos(rq));
if (ti->type->busy && ti->type->busy(ti))
goto plug_and_out;
@@ -1918,7 +1797,6 @@ out:
static const struct block_device_operations dm_blk_dops;
static void dm_wq_work(struct work_struct *work);
-static void dm_rq_barrier_work(struct work_struct *work);
static void dm_init_md_queue(struct mapped_device *md)
{
@@ -1940,6 +1818,7 @@ static void dm_init_md_queue(struct mapped_device *md)
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
md->queue->unplug_fn = dm_unplug_all;
blk_queue_merge_bvec(md->queue, dm_merge_bvec);
+ blk_queue_flush(md->queue, REQ_FLUSH | REQ_FUA);
}
/*
@@ -1972,7 +1851,6 @@ static struct mapped_device *alloc_dev(int minor)
mutex_init(&md->suspend_lock);
mutex_init(&md->type_lock);
spin_lock_init(&md->deferred_lock);
- spin_lock_init(&md->barrier_error_lock);
rwlock_init(&md->map_lock);
atomic_set(&md->holders, 1);
atomic_set(&md->open_count, 0);
@@ -1995,7 +1873,6 @@ static struct mapped_device *alloc_dev(int minor)
atomic_set(&md->pending[1], 0);
init_waitqueue_head(&md->wait);
INIT_WORK(&md->work, dm_wq_work);
- INIT_WORK(&md->barrier_work, dm_rq_barrier_work);
init_waitqueue_head(&md->eventq);
md->disk->major = _major;
@@ -2015,6 +1892,10 @@ static struct mapped_device *alloc_dev(int minor)
if (!md->bdev)
goto bad_bdev;
+ bio_init(&md->flush_bio);
+ md->flush_bio.bi_bdev = md->bdev;
+ md->flush_bio.bi_rw = WRITE_FLUSH;
+
/* Populate the mapping, nobody knows we exist yet */
spin_lock(&_minor_lock);
old_md = idr_replace(&_minor_idr, md, minor);
@@ -2245,7 +2126,6 @@ static int dm_init_request_based_queue(struct mapped_device *md)
blk_queue_softirq_done(md->queue, dm_softirq_done);
blk_queue_prep_rq(md->queue, dm_prep_fn);
blk_queue_lld_busy(md->queue, dm_lld_busy);
- blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN_FLUSH);
elv_register_queue(md->queue);
@@ -2406,43 +2286,6 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
return r;
}
-static void dm_flush(struct mapped_device *md)
-{
- dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
-
- bio_init(&md->barrier_bio);
- md->barrier_bio.bi_bdev = md->bdev;
- md->barrier_bio.bi_rw = WRITE_BARRIER;
- __split_and_process_bio(md, &md->barrier_bio);
-
- dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
-}
-
-static void process_barrier(struct mapped_device *md, struct bio *bio)
-{
- md->barrier_error = 0;
-
- dm_flush(md);
-
- if (!bio_empty_barrier(bio)) {
- __split_and_process_bio(md, bio);
- /*
- * If the request isn't supported, don't waste time with
- * the second flush.
- */
- if (md->barrier_error != -EOPNOTSUPP)
- dm_flush(md);
- }
-
- if (md->barrier_error != DM_ENDIO_REQUEUE)
- bio_endio(bio, md->barrier_error);
- else {
- spin_lock_irq(&md->deferred_lock);
- bio_list_add_head(&md->deferred, bio);
- spin_unlock_irq(&md->deferred_lock);
- }
-}
-
/*
* Process the deferred bios
*/
@@ -2452,33 +2295,27 @@ static void dm_wq_work(struct work_struct *work)
work);
struct bio *c;
- down_write(&md->io_lock);
+ down_read(&md->io_lock);
while (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
spin_lock_irq(&md->deferred_lock);
c = bio_list_pop(&md->deferred);
spin_unlock_irq(&md->deferred_lock);
- if (!c) {
- clear_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
+ if (!c)
break;
- }
- up_write(&md->io_lock);
+ up_read(&md->io_lock);
if (dm_request_based(md))
generic_make_request(c);
- else {
- if (c->bi_rw & REQ_HARDBARRIER)
- process_barrier(md, c);
- else
- __split_and_process_bio(md, c);
- }
+ else
+ __split_and_process_bio(md, c);
- down_write(&md->io_lock);
+ down_read(&md->io_lock);
}
- up_write(&md->io_lock);
+ up_read(&md->io_lock);
}
static void dm_queue_flush(struct mapped_device *md)
@@ -2488,73 +2325,6 @@ static void dm_queue_flush(struct mapped_device *md)
queue_work(md->wq, &md->work);
}
-static void dm_rq_set_target_request_nr(struct request *clone, unsigned request_nr)
-{
- struct dm_rq_target_io *tio = clone->end_io_data;
-
- tio->info.target_request_nr = request_nr;
-}
-
-/* Issue barrier requests to targets and wait for their completion. */
-static int dm_rq_barrier(struct mapped_device *md)
-{
- int i, j;
- struct dm_table *map = dm_get_live_table(md);
- unsigned num_targets = dm_table_get_num_targets(map);
- struct dm_target *ti;
- struct request *clone;
-
- md->barrier_error = 0;
-
- for (i = 0; i < num_targets; i++) {
- ti = dm_table_get_target(map, i);
- for (j = 0; j < ti->num_flush_requests; j++) {
- clone = clone_rq(md->flush_request, md, GFP_NOIO);
- dm_rq_set_target_request_nr(clone, j);
- atomic_inc(&md->pending[rq_data_dir(clone)]);
- map_request(ti, clone, md);
- }
- }
-
- dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
- dm_table_put(map);
-
- return md->barrier_error;
-}
-
-static void dm_rq_barrier_work(struct work_struct *work)
-{
- int error;
- struct mapped_device *md = container_of(work, struct mapped_device,
- barrier_work);
- struct request_queue *q = md->queue;
- struct request *rq;
- unsigned long flags;
-
- /*
- * Hold the md reference here and leave it at the last part so that
- * the md can't be deleted by device opener when the barrier request
- * completes.
- */
- dm_get(md);
-
- error = dm_rq_barrier(md);
-
- rq = md->flush_request;
- md->flush_request = NULL;
-
- if (error == DM_ENDIO_REQUEUE) {
- spin_lock_irqsave(q->queue_lock, flags);
- blk_requeue_request(q, rq);
- spin_unlock_irqrestore(q->queue_lock, flags);
- } else
- blk_end_request_all(rq, error);
-
- blk_run_queue(q);
-
- dm_put(md);
-}
-
/*
* Swap in a new table, returning the old one for the caller to destroy.
*/
@@ -2677,23 +2447,17 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
*
* To get all processes out of __split_and_process_bio in dm_request,
* we take the write lock. To prevent any process from reentering
- * __split_and_process_bio from dm_request, we set
- * DMF_QUEUE_IO_TO_THREAD.
- *
- * To quiesce the thread (dm_wq_work), we set DMF_BLOCK_IO_FOR_SUSPEND
- * and call flush_workqueue(md->wq). flush_workqueue will wait until
- * dm_wq_work exits and DMF_BLOCK_IO_FOR_SUSPEND will prevent any
- * further calls to __split_and_process_bio from dm_wq_work.
+ * __split_and_process_bio from dm_request and quiesce the thread
+ * (dm_wq_work), we set BMF_BLOCK_IO_FOR_SUSPEND and call
+ * flush_workqueue(md->wq).
*/
down_write(&md->io_lock);
set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
- set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
up_write(&md->io_lock);
/*
- * Request-based dm uses md->wq for barrier (dm_rq_barrier_work) which
- * can be kicked until md->queue is stopped. So stop md->queue before
- * flushing md->wq.
+ * Stop md->queue before flushing md->wq in case request-based
+ * dm defers requests to md->wq from md->queue.
*/
if (dm_request_based(md))
stop_queue(md->queue);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index ba19060bcf3f..8a2f767f26d8 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -294,8 +294,8 @@ static int linear_make_request (mddev_t *mddev, struct bio *bio)
dev_info_t *tmp_dev;
sector_t start_sector;
- if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
- md_barrier_request(mddev, bio);
+ if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ md_flush_request(mddev, bio);
return 0;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c148b6302154..225815197a3d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -36,7 +36,7 @@
#include <linux/blkdev.h>
#include <linux/sysctl.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h>
#include <linux/ctype.h>
@@ -57,6 +57,7 @@
#define DEBUG 0
#define dprintk(x...) ((void)(DEBUG && printk(x)))
+static DEFINE_MUTEX(md_mutex);
#ifndef MODULE
static void autostart_arrays(int part);
@@ -226,12 +227,12 @@ static int md_make_request(struct request_queue *q, struct bio *bio)
return 0;
}
rcu_read_lock();
- if (mddev->suspended || mddev->barrier) {
+ if (mddev->suspended) {
DEFINE_WAIT(__wait);
for (;;) {
prepare_to_wait(&mddev->sb_wait, &__wait,
TASK_UNINTERRUPTIBLE);
- if (!mddev->suspended && !mddev->barrier)
+ if (!mddev->suspended)
break;
rcu_read_unlock();
schedule();
@@ -282,40 +283,29 @@ EXPORT_SYMBOL_GPL(mddev_resume);
int mddev_congested(mddev_t *mddev, int bits)
{
- if (mddev->barrier)
- return 1;
return mddev->suspended;
}
EXPORT_SYMBOL(mddev_congested);
/*
- * Generic barrier handling for md
+ * Generic flush handling for md
*/
-#define POST_REQUEST_BARRIER ((void*)1)
-
-static void md_end_barrier(struct bio *bio, int err)
+static void md_end_flush(struct bio *bio, int err)
{
mdk_rdev_t *rdev = bio->bi_private;
mddev_t *mddev = rdev->mddev;
- if (err == -EOPNOTSUPP && mddev->barrier != POST_REQUEST_BARRIER)
- set_bit(BIO_EOPNOTSUPP, &mddev->barrier->bi_flags);
rdev_dec_pending(rdev, mddev);
if (atomic_dec_and_test(&mddev->flush_pending)) {
- if (mddev->barrier == POST_REQUEST_BARRIER) {
- /* This was a post-request barrier */
- mddev->barrier = NULL;
- wake_up(&mddev->sb_wait);
- } else
- /* The pre-request barrier has finished */
- schedule_work(&mddev->barrier_work);
+ /* The pre-request flush has finished */
+ schedule_work(&mddev->flush_work);
}
bio_put(bio);
}
-static void submit_barriers(mddev_t *mddev)
+static void submit_flushes(mddev_t *mddev)
{
mdk_rdev_t *rdev;
@@ -332,60 +322,56 @@ static void submit_barriers(mddev_t *mddev)
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
bi = bio_alloc(GFP_KERNEL, 0);
- bi->bi_end_io = md_end_barrier;
+ bi->bi_end_io = md_end_flush;
bi->bi_private = rdev;
bi->bi_bdev = rdev->bdev;
atomic_inc(&mddev->flush_pending);
- submit_bio(WRITE_BARRIER, bi);
+ submit_bio(WRITE_FLUSH, bi);
rcu_read_lock();
rdev_dec_pending(rdev, mddev);
}
rcu_read_unlock();
}
-static void md_submit_barrier(struct work_struct *ws)
+static void md_submit_flush_data(struct work_struct *ws)
{
- mddev_t *mddev = container_of(ws, mddev_t, barrier_work);
- struct bio *bio = mddev->barrier;
+ mddev_t *mddev = container_of(ws, mddev_t, flush_work);
+ struct bio *bio = mddev->flush_bio;
atomic_set(&mddev->flush_pending, 1);
- if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags))
- bio_endio(bio, -EOPNOTSUPP);
- else if (bio->bi_size == 0)
+ if (bio->bi_size == 0)
/* an empty barrier - all done */
bio_endio(bio, 0);
else {
- bio->bi_rw &= ~REQ_HARDBARRIER;
+ bio->bi_rw &= ~REQ_FLUSH;
if (mddev->pers->make_request(mddev, bio))
generic_make_request(bio);
- mddev->barrier = POST_REQUEST_BARRIER;
- submit_barriers(mddev);
}
if (atomic_dec_and_test(&mddev->flush_pending)) {
- mddev->barrier = NULL;
+ mddev->flush_bio = NULL;
wake_up(&mddev->sb_wait);
}
}
-void md_barrier_request(mddev_t *mddev, struct bio *bio)
+void md_flush_request(mddev_t *mddev, struct bio *bio)
{
spin_lock_irq(&mddev->write_lock);
wait_event_lock_irq(mddev->sb_wait,
- !mddev->barrier,
+ !mddev->flush_bio,
mddev->write_lock, /*nothing*/);
- mddev->barrier = bio;
+ mddev->flush_bio = bio;
spin_unlock_irq(&mddev->write_lock);
atomic_set(&mddev->flush_pending, 1);
- INIT_WORK(&mddev->barrier_work, md_submit_barrier);
+ INIT_WORK(&mddev->flush_work, md_submit_flush_data);
- submit_barriers(mddev);
+ submit_flushes(mddev);
if (atomic_dec_and_test(&mddev->flush_pending))
- schedule_work(&mddev->barrier_work);
+ schedule_work(&mddev->flush_work);
}
-EXPORT_SYMBOL(md_barrier_request);
+EXPORT_SYMBOL(md_flush_request);
/* Support for plugging.
* This mirrors the plugging support in request_queue, but does not
@@ -696,31 +682,6 @@ static void super_written(struct bio *bio, int error)
bio_put(bio);
}
-static void super_written_barrier(struct bio *bio, int error)
-{
- struct bio *bio2 = bio->bi_private;
- mdk_rdev_t *rdev = bio2->bi_private;
- mddev_t *mddev = rdev->mddev;
-
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
- error == -EOPNOTSUPP) {
- unsigned long flags;
- /* barriers don't appear to be supported :-( */
- set_bit(BarriersNotsupp, &rdev->flags);
- mddev->barriers_work = 0;
- spin_lock_irqsave(&mddev->write_lock, flags);
- bio2->bi_next = mddev->biolist;
- mddev->biolist = bio2;
- spin_unlock_irqrestore(&mddev->write_lock, flags);
- wake_up(&mddev->sb_wait);
- bio_put(bio);
- } else {
- bio_put(bio2);
- bio->bi_private = rdev;
- super_written(bio, error);
- }
-}
-
void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page)
{
@@ -729,51 +690,28 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
* and decrement it on completion, waking up sb_wait
* if zero is reached.
* If an error occurred, call md_error
- *
- * As we might need to resubmit the request if REQ_HARDBARRIER
- * causes ENOTSUPP, we allocate a spare bio...
*/
struct bio *bio = bio_alloc(GFP_NOIO, 1);
- int rw = REQ_WRITE | REQ_SYNC | REQ_UNPLUG;
bio->bi_bdev = rdev->bdev;
bio->bi_sector = sector;
bio_add_page(bio, page, size, 0);
bio->bi_private = rdev;
bio->bi_end_io = super_written;
- bio->bi_rw = rw;
atomic_inc(&mddev->pending_writes);
- if (!test_bit(BarriersNotsupp, &rdev->flags)) {
- struct bio *rbio;
- rw |= REQ_HARDBARRIER;
- rbio = bio_clone(bio, GFP_NOIO);
- rbio->bi_private = bio;
- rbio->bi_end_io = super_written_barrier;
- submit_bio(rw, rbio);
- } else
- submit_bio(rw, bio);
+ submit_bio(REQ_WRITE | REQ_SYNC | REQ_UNPLUG | REQ_FLUSH | REQ_FUA,
+ bio);
}
void md_super_wait(mddev_t *mddev)
{
- /* wait for all superblock writes that were scheduled to complete.
- * if any had to be retried (due to BARRIER problems), retry them
- */
+ /* wait for all superblock writes that were scheduled to complete */
DEFINE_WAIT(wq);
for(;;) {
prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
if (atomic_read(&mddev->pending_writes)==0)
break;
- while (mddev->biolist) {
- struct bio *bio;
- spin_lock_irq(&mddev->write_lock);
- bio = mddev->biolist;
- mddev->biolist = bio->bi_next ;
- bio->bi_next = NULL;
- spin_unlock_irq(&mddev->write_lock);
- submit_bio(bio->bi_rw, bio);
- }
schedule();
}
finish_wait(&mddev->sb_wait, &wq);
@@ -1070,7 +1008,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
clear_bit(Faulty, &rdev->flags);
clear_bit(In_sync, &rdev->flags);
clear_bit(WriteMostly, &rdev->flags);
- clear_bit(BarriersNotsupp, &rdev->flags);
if (mddev->raid_disks == 0) {
mddev->major_version = 0;
@@ -1485,7 +1422,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
clear_bit(Faulty, &rdev->flags);
clear_bit(In_sync, &rdev->flags);
clear_bit(WriteMostly, &rdev->flags);
- clear_bit(BarriersNotsupp, &rdev->flags);
if (mddev->raid_disks == 0) {
mddev->major_version = 1;
@@ -1643,7 +1579,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1;
if (rdev->sb_size & bmask)
rdev->sb_size = (rdev->sb_size | bmask) + 1;
- }
+ } else
+ max_dev = le32_to_cpu(sb->max_dev);
+
for (i=0; i<max_dev;i++)
sb->dev_roles[i] = cpu_to_le16(0xfffe);
@@ -2167,9 +2105,9 @@ repeat:
rdev->recovery_offset = mddev->curr_resync_completed;
}
- if (mddev->external || !mddev->persistent) {
- clear_bit(MD_CHANGE_DEVS, &mddev->flags);
+ if (!mddev->persistent) {
clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ clear_bit(MD_CHANGE_DEVS, &mddev->flags);
wake_up(&mddev->sb_wait);
return;
}
@@ -2178,7 +2116,6 @@ repeat:
mddev->utime = get_seconds();
- set_bit(MD_CHANGE_PENDING, &mddev->flags);
if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags))
force_change = 1;
if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags))
@@ -3371,7 +3308,7 @@ array_state_show(mddev_t *mddev, char *page)
case 0:
if (mddev->in_sync)
st = clean;
- else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
+ else if (test_bit(MD_CHANGE_PENDING, &mddev->flags))
st = write_pending;
else if (mddev->safemode)
st = active_idle;
@@ -3452,9 +3389,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
mddev->in_sync = 1;
if (mddev->safemode == 1)
mddev->safemode = 0;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN,
- &mddev->flags);
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
}
err = 0;
} else
@@ -3466,8 +3401,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
case active:
if (mddev->pers) {
restart_array(mddev);
- if (mddev->external)
- clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ clear_bit(MD_CHANGE_PENDING, &mddev->flags);
wake_up(&mddev->sb_wait);
err = 0;
} else {
@@ -4506,7 +4440,6 @@ int md_run(mddev_t *mddev)
/* may be over-ridden by personality */
mddev->resync_max_sectors = mddev->dev_sectors;
- mddev->barriers_work = 1;
mddev->ok_start_degraded = start_dirty_degraded;
if (start_readonly && mddev->ro == 0)
@@ -4685,7 +4618,6 @@ static void md_clean(mddev_t *mddev)
mddev->recovery = 0;
mddev->in_sync = 0;
mddev->degraded = 0;
- mddev->barriers_work = 0;
mddev->safemode = 0;
mddev->bitmap_info.offset = 0;
mddev->bitmap_info.default_offset = 0;
@@ -5953,7 +5885,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
mddev_t *mddev = mddev_find(bdev->bd_dev);
int err;
- lock_kernel();
+ mutex_lock(&md_mutex);
if (mddev->gendisk != bdev->bd_disk) {
/* we are racing with mddev_put which is discarding this
* bd_disk.
@@ -5962,7 +5894,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
/* Wait until bdev->bd_disk is definitely gone */
flush_scheduled_work();
/* Then retry the open from the top */
- unlock_kernel();
+ mutex_unlock(&md_mutex);
return -ERESTARTSYS;
}
BUG_ON(mddev != bdev->bd_disk->private_data);
@@ -5976,7 +5908,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
check_disk_size_change(mddev->gendisk, bdev);
out:
- unlock_kernel();
+ mutex_unlock(&md_mutex);
return err;
}
@@ -5985,10 +5917,10 @@ static int md_release(struct gendisk *disk, fmode_t mode)
mddev_t *mddev = disk->private_data;
BUG_ON(!mddev);
- lock_kernel();
+ mutex_lock(&md_mutex);
atomic_dec(&mddev->openers);
mddev_put(mddev);
- unlock_kernel();
+ mutex_unlock(&md_mutex);
return 0;
}
@@ -6572,6 +6504,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
if (mddev->in_sync) {
mddev->in_sync = 0;
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ set_bit(MD_CHANGE_PENDING, &mddev->flags);
md_wakeup_thread(mddev->thread);
did_change = 1;
}
@@ -6580,7 +6513,6 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
if (did_change)
sysfs_notify_dirent_safe(mddev->sysfs_state);
wait_event(mddev->sb_wait,
- !test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
!test_bit(MD_CHANGE_PENDING, &mddev->flags));
}
@@ -6616,6 +6548,7 @@ int md_allow_write(mddev_t *mddev)
if (mddev->in_sync) {
mddev->in_sync = 0;
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ set_bit(MD_CHANGE_PENDING, &mddev->flags);
if (mddev->safemode_delay &&
mddev->safemode == 0)
mddev->safemode = 1;
@@ -6625,7 +6558,7 @@ int md_allow_write(mddev_t *mddev)
} else
spin_unlock_irq(&mddev->write_lock);
- if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
+ if (test_bit(MD_CHANGE_PENDING, &mddev->flags))
return -EAGAIN;
else
return 0;
@@ -6823,8 +6756,7 @@ void md_do_sync(mddev_t *mddev)
atomic_read(&mddev->recovery_active) == 0);
mddev->curr_resync_completed =
mddev->curr_resync;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
sysfs_notify(&mddev->kobj, NULL, "sync_completed");
}
@@ -7073,7 +7005,7 @@ void md_check_recovery(mddev_t *mddev)
if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
return;
if ( ! (
- (mddev->flags && !mddev->external) ||
+ (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
(mddev->external == 0 && mddev->safemode == 1) ||
@@ -7103,8 +7035,7 @@ void md_check_recovery(mddev_t *mddev)
mddev->recovery_cp == MaxSector) {
mddev->in_sync = 1;
did_change = 1;
- if (mddev->persistent)
- set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
}
if (mddev->safemode == 1)
mddev->safemode = 0;
diff --git a/drivers/md/md.h b/drivers/md/md.h
index a953fe2808ae..112a2c32db0c 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -87,7 +87,6 @@ struct mdk_rdev_s
#define Faulty 1 /* device is known to have a fault */
#define In_sync 2 /* device is in_sync with rest of array */
#define WriteMostly 4 /* Avoid reading if at all possible */
-#define BarriersNotsupp 5 /* REQ_HARDBARRIER is not supported */
#define AllReserved 6 /* If whole device is reserved for
* one array */
#define AutoDetected 7 /* added by auto-detect */
@@ -140,7 +139,7 @@ struct mddev_s
unsigned long flags;
#define MD_CHANGE_DEVS 0 /* Some device status has changed */
#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
-#define MD_CHANGE_PENDING 2 /* superblock update in progress */
+#define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */
int suspended;
atomic_t active_io;
@@ -273,13 +272,6 @@ struct mddev_s
int degraded; /* whether md should consider
* adding a spare
*/
- int barriers_work; /* initialised to true, cleared as soon
- * as a barrier request to slave
- * fails. Only supported
- */
- struct bio *biolist; /* bios that need to be retried
- * because REQ_HARDBARRIER is not supported
- */
atomic_t recovery_active; /* blocks scheduled, but not written */
wait_queue_head_t recovery_wait;
@@ -339,16 +331,13 @@ struct mddev_s
struct attribute_group *to_remove;
struct plug_handle *plug; /* if used by personality */
- /* Generic barrier handling.
- * If there is a pending barrier request, all other
- * writes are blocked while the devices are flushed.
- * The last to finish a flush schedules a worker to
- * submit the barrier request (without the barrier flag),
- * then submit more flush requests.
+ /* Generic flush handling.
+ * The last to finish preflush schedules a worker to submit
+ * the rest of the request (without the REQ_FLUSH flag).
*/
- struct bio *barrier;
+ struct bio *flush_bio;
atomic_t flush_pending;
- struct work_struct barrier_work;
+ struct work_struct flush_work;
struct work_struct event_work; /* used by dm to report failure event */
};
@@ -502,7 +491,7 @@ extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
extern int mddev_congested(mddev_t *mddev, int bits);
-extern void md_barrier_request(mddev_t *mddev, struct bio *bio);
+extern void md_flush_request(mddev_t *mddev, struct bio *bio);
extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page);
extern void md_super_wait(mddev_t *mddev);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 0307d217e7a4..6d7ddf32ef2e 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -142,8 +142,8 @@ static int multipath_make_request(mddev_t *mddev, struct bio * bio)
struct multipath_bh * mp_bh;
struct multipath_info *multipath;
- if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
- md_barrier_request(mddev, bio);
+ if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ md_flush_request(mddev, bio);
return 0;
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 6f7af46d623c..a39f4c355e55 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -483,8 +483,8 @@ static int raid0_make_request(mddev_t *mddev, struct bio *bio)
struct strip_zone *zone;
mdk_rdev_t *tmp_dev;
- if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
- md_barrier_request(mddev, bio);
+ if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ md_flush_request(mddev, bio);
return 0;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ad83a4dcadc3..886a9d865488 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -319,83 +319,74 @@ static void raid1_end_write_request(struct bio *bio, int error)
if (r1_bio->bios[mirror] == bio)
break;
- if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
- set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
- set_bit(R1BIO_BarrierRetry, &r1_bio->state);
- r1_bio->mddev->barriers_work = 0;
- /* Don't rdev_dec_pending in this branch - keep it for the retry */
- } else {
+ /*
+ * 'one mirror IO has finished' event handler:
+ */
+ r1_bio->bios[mirror] = NULL;
+ to_put = bio;
+ if (!uptodate) {
+ md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
+ /* an I/O failed, we can't clear the bitmap */
+ set_bit(R1BIO_Degraded, &r1_bio->state);
+ } else
/*
- * this branch is our 'one mirror IO has finished' event handler:
+ * Set R1BIO_Uptodate in our master bio, so that we
+ * will return a good error code for to the higher
+ * levels even if IO on some other mirrored buffer
+ * fails.
+ *
+ * The 'master' represents the composite IO operation
+ * to user-side. So if something waits for IO, then it
+ * will wait for the 'master' bio.
*/
- r1_bio->bios[mirror] = NULL;
- to_put = bio;
- if (!uptodate) {
- md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
- /* an I/O failed, we can't clear the bitmap */
- set_bit(R1BIO_Degraded, &r1_bio->state);
- } else
- /*
- * Set R1BIO_Uptodate in our master bio, so that
- * we will return a good error code for to the higher
- * levels even if IO on some other mirrored buffer fails.
- *
- * The 'master' represents the composite IO operation to
- * user-side. So if something waits for IO, then it will
- * wait for the 'master' bio.
- */
- set_bit(R1BIO_Uptodate, &r1_bio->state);
-
- update_head_pos(mirror, r1_bio);
-
- if (behind) {
- if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
- atomic_dec(&r1_bio->behind_remaining);
-
- /* In behind mode, we ACK the master bio once the I/O has safely
- * reached all non-writemostly disks. Setting the Returned bit
- * ensures that this gets done only once -- we don't ever want to
- * return -EIO here, instead we'll wait */
-
- if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
- test_bit(R1BIO_Uptodate, &r1_bio->state)) {
- /* Maybe we can return now */
- if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
- struct bio *mbio = r1_bio->master_bio;
- PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
- (unsigned long long) mbio->bi_sector,
- (unsigned long long) mbio->bi_sector +
- (mbio->bi_size >> 9) - 1);
- bio_endio(mbio, 0);
- }
+ set_bit(R1BIO_Uptodate, &r1_bio->state);
+
+ update_head_pos(mirror, r1_bio);
+
+ if (behind) {
+ if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
+ atomic_dec(&r1_bio->behind_remaining);
+
+ /*
+ * In behind mode, we ACK the master bio once the I/O
+ * has safely reached all non-writemostly
+ * disks. Setting the Returned bit ensures that this
+ * gets done only once -- we don't ever want to return
+ * -EIO here, instead we'll wait
+ */
+ if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
+ test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+ /* Maybe we can return now */
+ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
+ struct bio *mbio = r1_bio->master_bio;
+ PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
+ (unsigned long long) mbio->bi_sector,
+ (unsigned long long) mbio->bi_sector +
+ (mbio->bi_size >> 9) - 1);
+ bio_endio(mbio, 0);
}
}
- rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
}
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
+
/*
- *
* Let's see if all mirrored write operations have finished
* already.
*/
if (atomic_dec_and_test(&r1_bio->remaining)) {
- if (test_bit(R1BIO_BarrierRetry, &r1_bio->state))
- reschedule_retry(r1_bio);
- else {
- /* it really is the end of this request */
- if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
- /* free extra copy of the data pages */
- int i = bio->bi_vcnt;
- while (i--)
- safe_put_page(bio->bi_io_vec[i].bv_page);
- }
- /* clear the bitmap if all writes complete successfully */
- bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
- r1_bio->sectors,
- !test_bit(R1BIO_Degraded, &r1_bio->state),
- behind);
- md_write_end(r1_bio->mddev);
- raid_end_bio_io(r1_bio);
+ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
+ /* free extra copy of the data pages */
+ int i = bio->bi_vcnt;
+ while (i--)
+ safe_put_page(bio->bi_io_vec[i].bv_page);
}
+ /* clear the bitmap if all writes complete successfully */
+ bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
+ r1_bio->sectors,
+ !test_bit(R1BIO_Degraded, &r1_bio->state),
+ behind);
+ md_write_end(r1_bio->mddev);
+ raid_end_bio_io(r1_bio);
}
if (to_put)
@@ -788,16 +779,13 @@ static int make_request(mddev_t *mddev, struct bio * bio)
struct page **behind_pages = NULL;
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
- unsigned long do_barriers;
+ const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
mdk_rdev_t *blocked_rdev;
/*
* Register the new request and wait if the reconstruction
* thread has put up a bar for new requests.
* Continue immediately if no resync is active currently.
- * We test barriers_work *after* md_write_start as md_write_start
- * may cause the first superblock write, and that will check out
- * if barriers work.
*/
md_write_start(mddev, bio); /* wait on superblock update early */
@@ -821,13 +809,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
}
finish_wait(&conf->wait_barrier, &w);
}
- if (unlikely(!mddev->barriers_work &&
- (bio->bi_rw & REQ_HARDBARRIER))) {
- if (rw == WRITE)
- md_write_end(mddev);
- bio_endio(bio, -EOPNOTSUPP);
- return 0;
- }
wait_barrier(conf);
@@ -959,10 +940,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
atomic_set(&r1_bio->remaining, 0);
atomic_set(&r1_bio->behind_remaining, 0);
- do_barriers = bio->bi_rw & REQ_HARDBARRIER;
- if (do_barriers)
- set_bit(R1BIO_Barrier, &r1_bio->state);
-
bio_list_init(&bl);
for (i = 0; i < disks; i++) {
struct bio *mbio;
@@ -975,7 +952,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_rw = WRITE | do_barriers | do_sync;
+ mbio->bi_rw = WRITE | do_flush_fua | do_sync;
mbio->bi_private = r1_bio;
if (behind_pages) {
@@ -1634,41 +1611,6 @@ static void raid1d(mddev_t *mddev)
if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
sync_request_write(mddev, r1_bio);
unplug = 1;
- } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
- /* some requests in the r1bio were REQ_HARDBARRIER
- * requests which failed with -EOPNOTSUPP. Hohumm..
- * Better resubmit without the barrier.
- * We know which devices to resubmit for, because
- * all others have had their bios[] entry cleared.
- * We already have a nr_pending reference on these rdevs.
- */
- int i;
- const unsigned long do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC);
- clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
- clear_bit(R1BIO_Barrier, &r1_bio->state);
- for (i=0; i < conf->raid_disks; i++)
- if (r1_bio->bios[i])
- atomic_inc(&r1_bio->remaining);
- for (i=0; i < conf->raid_disks; i++)
- if (r1_bio->bios[i]) {
- struct bio_vec *bvec;
- int j;
-
- bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
- /* copy pages from the failed bio, as
- * this might be a write-behind device */
- __bio_for_each_segment(bvec, bio, j, 0)
- bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
- bio_put(r1_bio->bios[i]);
- bio->bi_sector = r1_bio->sector +
- conf->mirrors[i].rdev->data_offset;
- bio->bi_bdev = conf->mirrors[i].rdev->bdev;
- bio->bi_end_io = raid1_end_write_request;
- bio->bi_rw = WRITE | do_sync;
- bio->bi_private = r1_bio;
- r1_bio->bios[i] = bio;
- generic_make_request(bio);
- }
} else {
int disk;
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h
index 5f2d443ae28a..adf8cfd73313 100644
--- a/drivers/md/raid1.h
+++ b/drivers/md/raid1.h
@@ -117,8 +117,6 @@ struct r1bio_s {
#define R1BIO_IsSync 1
#define R1BIO_Degraded 2
#define R1BIO_BehindIO 3
-#define R1BIO_Barrier 4
-#define R1BIO_BarrierRetry 5
/* For write-behind requests, we call bi_end_io when
* the last non-write-behind device completes, providing
* any write was successful. Otherwise we call when
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 84718383124d..f0d082f749be 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -800,12 +800,13 @@ static int make_request(mddev_t *mddev, struct bio * bio)
int chunk_sects = conf->chunk_mask + 1;
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
+ const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
struct bio_list bl;
unsigned long flags;
mdk_rdev_t *blocked_rdev;
- if (unlikely(bio->bi_rw & REQ_HARDBARRIER)) {
- md_barrier_request(mddev, bio);
+ if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ md_flush_request(mddev, bio);
return 0;
}
@@ -965,7 +966,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
conf->mirrors[d].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync;
+ mbio->bi_rw = WRITE | do_sync | do_fua;
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 69b0a169e43d..31140d1259dc 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -506,9 +506,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
int rw;
struct bio *bi;
mdk_rdev_t *rdev;
- if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
- rw = WRITE;
- else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
+ if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags)) {
+ if (test_and_clear_bit(R5_WantFUA, &sh->dev[i].flags))
+ rw = WRITE_FUA;
+ else
+ rw = WRITE;
+ } else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
rw = READ;
else
continue;
@@ -1031,6 +1034,8 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
while (wbi && wbi->bi_sector <
dev->sector + STRIPE_SECTORS) {
+ if (wbi->bi_rw & REQ_FUA)
+ set_bit(R5_WantFUA, &dev->flags);
tx = async_copy_data(1, wbi, dev->page,
dev->sector, tx);
wbi = r5_next_bio(wbi, dev->sector);
@@ -1048,15 +1053,22 @@ static void ops_complete_reconstruct(void *stripe_head_ref)
int pd_idx = sh->pd_idx;
int qd_idx = sh->qd_idx;
int i;
+ bool fua = false;
pr_debug("%s: stripe %llu\n", __func__,
(unsigned long long)sh->sector);
+ for (i = disks; i--; )
+ fua |= test_bit(R5_WantFUA, &sh->dev[i].flags);
+
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
- if (dev->written || i == pd_idx || i == qd_idx)
+ if (dev->written || i == pd_idx || i == qd_idx) {
set_bit(R5_UPTODATE, &dev->flags);
+ if (fua)
+ set_bit(R5_WantFUA, &dev->flags);
+ }
}
if (sh->reconstruct_state == reconstruct_state_drain_run)
@@ -3281,7 +3293,7 @@ static void handle_stripe5(struct stripe_head *sh)
if (dec_preread_active) {
/* We delay this until after ops_run_io so that if make_request
- * is waiting on a barrier, it won't continue until the writes
+ * is waiting on a flush, it won't continue until the writes
* have actually been submitted.
*/
atomic_dec(&conf->preread_active_stripes);
@@ -3583,7 +3595,7 @@ static void handle_stripe6(struct stripe_head *sh)
if (dec_preread_active) {
/* We delay this until after ops_run_io so that if make_request
- * is waiting on a barrier, it won't continue until the writes
+ * is waiting on a flush, it won't continue until the writes
* have actually been submitted.
*/
atomic_dec(&conf->preread_active_stripes);
@@ -3978,14 +3990,8 @@ static int make_request(mddev_t *mddev, struct bio * bi)
const int rw = bio_data_dir(bi);
int remaining;
- if (unlikely(bi->bi_rw & REQ_HARDBARRIER)) {
- /* Drain all pending writes. We only really need
- * to ensure they have been submitted, but this is
- * easier.
- */
- mddev->pers->quiesce(mddev, 1);
- mddev->pers->quiesce(mddev, 0);
- md_barrier_request(mddev, bi);
+ if (unlikely(bi->bi_rw & REQ_FLUSH)) {
+ md_flush_request(mddev, bi);
return 0;
}
@@ -4103,7 +4109,7 @@ static int make_request(mddev_t *mddev, struct bio * bi)
finish_wait(&conf->wait_for_overlap, &w);
set_bit(STRIPE_HANDLE, &sh->state);
clear_bit(STRIPE_DELAYED, &sh->state);
- if (mddev->barrier &&
+ if ((bi->bi_rw & REQ_SYNC) &&
!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
atomic_inc(&conf->preread_active_stripes);
release_stripe(sh);
@@ -4126,13 +4132,6 @@ static int make_request(mddev_t *mddev, struct bio * bi)
bio_endio(bi, 0);
}
- if (mddev->barrier) {
- /* We need to wait for the stripes to all be handled.
- * So: wait for preread_active_stripes to drop to 0.
- */
- wait_event(mddev->thread->wqueue,
- atomic_read(&conf->preread_active_stripes) == 0);
- }
return 0;
}
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 36eaed5dfd6e..2ace0582b409 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -275,6 +275,7 @@ struct r6_state {
* filling
*/
#define R5_Wantdrain 13 /* dev->towrite needs to be drained */
+#define R5_WantFUA 14 /* Write should be FUA */
/*
* Write method
*/
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index 490c57cc4cfe..152000db3526 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -79,6 +79,18 @@ config IR_SONY_DECODER
Enable this option if you have an infrared remote control which
uses the Sony protocol, and you need software decoding support.
+config IR_RC5_SZ_DECODER
+ tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
+ depends on IR_CORE
+ select BITREVERSE
+ default y
+
+ ---help---
+ Enable this option if you have IR with RC-5 (streamzap) protocol,
+ and if the IR is decoded in software. (The Streamzap PC Remote
+ uses an IR protocol that is almost standard RC-5, but not quite,
+ as it uses an additional bit).
+
config IR_LIRC_CODEC
tristate "Enable IR to LIRC bridge"
depends on IR_CORE
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 53676838fe97..953c6c44330a 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
+obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
# stand-alone IR receivers/transmitters
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
index c185422ef28c..0fb2de2ca47d 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/IR/imon.c
@@ -151,7 +151,8 @@ static const struct file_operations vfd_fops = {
.owner = THIS_MODULE,
.open = &display_open,
.write = &vfd_write,
- .release = &display_close
+ .release = &display_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* lcd character device file operations */
@@ -159,7 +160,8 @@ static const struct file_operations lcd_fops = {
.owner = THIS_MODULE,
.open = &display_open,
.write = &lcd_write,
- .release = &display_close
+ .release = &display_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
enum {
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index a85a8c7c905a..0ad8ea39b39e 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -76,6 +76,12 @@ struct ir_raw_event_ctrl {
bool first;
bool toggle;
} jvc;
+ struct rc5_sz_dec {
+ int state;
+ u32 bits;
+ unsigned count;
+ unsigned wanted_bits;
+ } rc5_sz;
struct lirc_codec {
struct ir_input_dev *ir_dev;
struct lirc_driver *drv;
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index 7e82a9df726b..c06b4d50a3dc 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -25,14 +25,56 @@
#define IR_KEYPRESS_TIMEOUT 250
/**
+ * ir_create_table() - initializes a scancode table
+ * @rc_tab: the ir_scancode_table to initialize
+ * @name: name to assign to the table
+ * @ir_type: ir type to assign to the new table
+ * @size: initial size of the table
+ * @return: zero on success or a negative error code
+ *
+ * This routine will initialize the ir_scancode_table and will allocate
+ * memory to hold at least the specified number elements.
+ */
+static int ir_create_table(struct ir_scancode_table *rc_tab,
+ const char *name, u64 ir_type, size_t size)
+{
+ rc_tab->name = name;
+ rc_tab->ir_type = ir_type;
+ rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode));
+ rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
+ rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL);
+ if (!rc_tab->scan)
+ return -ENOMEM;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_tab->size, rc_tab->alloc);
+ return 0;
+}
+
+/**
+ * ir_free_table() - frees memory allocated by a scancode table
+ * @rc_tab: the table whose mappings need to be freed
+ *
+ * This routine will free memory alloctaed for key mappings used by given
+ * scancode table.
+ */
+static void ir_free_table(struct ir_scancode_table *rc_tab)
+{
+ rc_tab->size = 0;
+ kfree(rc_tab->scan);
+ rc_tab->scan = NULL;
+}
+
+/**
* ir_resize_table() - resizes a scancode table if necessary
* @rc_tab: the ir_scancode_table to resize
+ * @gfp_flags: gfp flags to use when allocating memory
* @return: zero on success or a negative error code
*
* This routine will shrink the ir_scancode_table if it has lots of
* unused entries and grow it if it is full.
*/
-static int ir_resize_table(struct ir_scancode_table *rc_tab)
+static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags)
{
unsigned int oldalloc = rc_tab->alloc;
unsigned int newalloc = oldalloc;
@@ -57,7 +99,7 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab)
if (newalloc == oldalloc)
return 0;
- newscan = kmalloc(newalloc, GFP_ATOMIC);
+ newscan = kmalloc(newalloc, gfp_flags);
if (!newscan) {
IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
return -ENOMEM;
@@ -72,26 +114,78 @@ static int ir_resize_table(struct ir_scancode_table *rc_tab)
}
/**
- * ir_do_setkeycode() - internal function to set a keycode in the
- * scancode->keycode table
+ * ir_update_mapping() - set a keycode in the scancode->keycode table
* @dev: the struct input_dev device descriptor
- * @rc_tab: the struct ir_scancode_table to set the keycode in
- * @scancode: the scancode for the ir command
- * @keycode: the keycode for the ir command
- * @resize: whether the keytable may be shrunk
- * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
+ * @rc_tab: scancode table to be adjusted
+ * @index: index of the mapping that needs to be updated
+ * @keycode: the desired keycode
+ * @return: previous keycode assigned to the mapping
+ *
+ * This routine is used to update scancode->keycopde mapping at given
+ * position.
+ */
+static unsigned int ir_update_mapping(struct input_dev *dev,
+ struct ir_scancode_table *rc_tab,
+ unsigned int index,
+ unsigned int new_keycode)
+{
+ int old_keycode = rc_tab->scan[index].keycode;
+ int i;
+
+ /* Did the user wish to remove the mapping? */
+ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
+ IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
+ index, rc_tab->scan[index].scancode);
+ rc_tab->len--;
+ memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1],
+ (rc_tab->len - index) * sizeof(struct ir_scancode));
+ } else {
+ IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
+ index,
+ old_keycode == KEY_RESERVED ? "New" : "Replacing",
+ rc_tab->scan[index].scancode, new_keycode);
+ rc_tab->scan[index].keycode = new_keycode;
+ __set_bit(new_keycode, dev->keybit);
+ }
+
+ if (old_keycode != KEY_RESERVED) {
+ /* A previous mapping was updated... */
+ __clear_bit(old_keycode, dev->keybit);
+ /* ... but another scancode might use the same keycode */
+ for (i = 0; i < rc_tab->len; i++) {
+ if (rc_tab->scan[i].keycode == old_keycode) {
+ __set_bit(old_keycode, dev->keybit);
+ break;
+ }
+ }
+
+ /* Possibly shrink the keytable, failure is not a problem */
+ ir_resize_table(rc_tab, GFP_ATOMIC);
+ }
+
+ return old_keycode;
+}
+
+/**
+ * ir_locate_scancode() - set a keycode in the scancode->keycode table
+ * @ir_dev: the struct ir_input_dev device descriptor
+ * @rc_tab: scancode table to be searched
+ * @scancode: the desired scancode
+ * @resize: controls whether we allowed to resize the table to
+ * accomodate not yet present scancodes
+ * @return: index of the mapping containing scancode in question
+ * or -1U in case of failure.
*
- * This routine is used internally to manipulate the scancode->keycode table.
- * The caller has to hold @rc_tab->lock.
+ * This routine is used to locate given scancode in ir_scancode_table.
+ * If scancode is not yet present the routine will allocate a new slot
+ * for it.
*/
-static int ir_do_setkeycode(struct input_dev *dev,
- struct ir_scancode_table *rc_tab,
- unsigned scancode, unsigned keycode,
- bool resize)
+static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
+ struct ir_scancode_table *rc_tab,
+ unsigned int scancode,
+ bool resize)
{
unsigned int i;
- int old_keycode = KEY_RESERVED;
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
/*
* Unfortunately, some hardware-based IR decoders don't provide
@@ -100,65 +194,34 @@ static int ir_do_setkeycode(struct input_dev *dev,
* the provided IR with another one, it is needed to allow loading
* IR tables from other remotes. So,
*/
- if (ir_dev->props && ir_dev->props->scanmask) {
+ if (ir_dev->props && ir_dev->props->scanmask)
scancode &= ir_dev->props->scanmask;
- }
/* First check if we already have a mapping for this ir command */
for (i = 0; i < rc_tab->len; i++) {
+ if (rc_tab->scan[i].scancode == scancode)
+ return i;
+
/* Keytable is sorted from lowest to highest scancode */
- if (rc_tab->scan[i].scancode > scancode)
+ if (rc_tab->scan[i].scancode >= scancode)
break;
- else if (rc_tab->scan[i].scancode < scancode)
- continue;
-
- old_keycode = rc_tab->scan[i].keycode;
- rc_tab->scan[i].keycode = keycode;
-
- /* Did the user wish to remove the mapping? */
- if (keycode == KEY_RESERVED || keycode == KEY_UNKNOWN) {
- IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
- i, scancode);
- rc_tab->len--;
- memmove(&rc_tab->scan[i], &rc_tab->scan[i + 1],
- (rc_tab->len - i) * sizeof(struct ir_scancode));
- }
-
- /* Possibly shrink the keytable, failure is not a problem */
- ir_resize_table(rc_tab);
- break;
}
- if (old_keycode == KEY_RESERVED && keycode != KEY_RESERVED) {
- /* No previous mapping found, we might need to grow the table */
- if (resize && ir_resize_table(rc_tab))
- return -ENOMEM;
-
- IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
- i, scancode, keycode);
+ /* No previous mapping found, we might need to grow the table */
+ if (rc_tab->size == rc_tab->len) {
+ if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC))
+ return -1U;
+ }
- /* i is the proper index to insert our new keycode */
+ /* i is the proper index to insert our new keycode */
+ if (i < rc_tab->len)
memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
(rc_tab->len - i) * sizeof(struct ir_scancode));
- rc_tab->scan[i].scancode = scancode;
- rc_tab->scan[i].keycode = keycode;
- rc_tab->len++;
- set_bit(keycode, dev->keybit);
- } else {
- IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
- i, scancode, keycode);
- /* A previous mapping was updated... */
- clear_bit(old_keycode, dev->keybit);
- /* ...but another scancode might use the same keycode */
- for (i = 0; i < rc_tab->len; i++) {
- if (rc_tab->scan[i].keycode == old_keycode) {
- set_bit(old_keycode, dev->keybit);
- break;
- }
- }
- }
+ rc_tab->scan[i].scancode = scancode;
+ rc_tab->scan[i].keycode = KEY_RESERVED;
+ rc_tab->len++;
- return 0;
+ return i;
}
/**
@@ -171,17 +234,41 @@ static int ir_do_setkeycode(struct input_dev *dev,
* This routine is used to handle evdev EVIOCSKEY ioctl.
*/
static int ir_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
{
- int rc;
- unsigned long flags;
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ unsigned int index;
+ unsigned int scancode;
+ int retval;
+ unsigned long flags;
spin_lock_irqsave(&rc_tab->lock, flags);
- rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode, true);
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ if (index >= rc_tab->len) {
+ retval = -EINVAL;
+ goto out;
+ }
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_establish_scancode(ir_dev, rc_tab, scancode, true);
+ if (index >= rc_tab->len) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ }
+
+ *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode);
+
+out:
spin_unlock_irqrestore(&rc_tab->lock, flags);
- return rc;
+ return retval;
}
/**
@@ -189,32 +276,73 @@ static int ir_setkeycode(struct input_dev *dev,
* @dev: the struct input_dev device descriptor
* @to: the struct ir_scancode_table to copy entries to
* @from: the struct ir_scancode_table to copy entries from
- * @return: -EINVAL if all keycodes could not be inserted, otherwise zero.
+ * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*
* This routine is used to handle table initialization.
*/
-static int ir_setkeytable(struct input_dev *dev,
- struct ir_scancode_table *to,
+static int ir_setkeytable(struct ir_input_dev *ir_dev,
const struct ir_scancode_table *from)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned long flags;
- unsigned int i;
- int rc = 0;
+ unsigned int i, index;
+ int rc;
+
+ rc = ir_create_table(&ir_dev->rc_tab,
+ from->name, from->ir_type, from->size);
+ if (rc)
+ return rc;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_tab->size, rc_tab->alloc);
- spin_lock_irqsave(&rc_tab->lock, flags);
for (i = 0; i < from->size; i++) {
- rc = ir_do_setkeycode(dev, to, from->scan[i].scancode,
- from->scan[i].keycode, false);
- if (rc)
+ index = ir_establish_scancode(ir_dev, rc_tab,
+ from->scan[i].scancode, false);
+ if (index >= rc_tab->len) {
+ rc = -ENOMEM;
break;
+ }
+
+ ir_update_mapping(ir_dev->input_dev, rc_tab, index,
+ from->scan[i].keycode);
}
- spin_unlock_irqrestore(&rc_tab->lock, flags);
+
+ if (rc)
+ ir_free_table(rc_tab);
+
return rc;
}
/**
+ * ir_lookup_by_scancode() - locate mapping by scancode
+ * @rc_tab: the &struct ir_scancode_table to search
+ * @scancode: scancode to look for in the table
+ * @return: index in the table, -1U if not found
+ *
+ * This routine performs binary search in RC keykeymap table for
+ * given scancode.
+ */
+static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab,
+ unsigned int scancode)
+{
+ unsigned int start = 0;
+ unsigned int end = rc_tab->len - 1;
+ unsigned int mid;
+
+ while (start <= end) {
+ mid = (start + end) / 2;
+ if (rc_tab->scan[mid].scancode < scancode)
+ start = mid + 1;
+ else if (rc_tab->scan[mid].scancode > scancode)
+ end = mid - 1;
+ else
+ return mid;
+ }
+
+ return -1U;
+}
+
+/**
* ir_getkeycode() - get a keycode from the scancode->keycode table
* @dev: the struct input_dev device descriptor
* @scancode: the desired scancode
@@ -224,36 +352,46 @@ static int ir_setkeytable(struct input_dev *dev,
* This routine is used to handle evdev EVIOCGKEY ioctl.
*/
static int ir_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
+ struct input_keymap_entry *ke)
{
- int start, end, mid;
- unsigned long flags;
- int key = KEY_RESERVED;
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode *entry;
+ unsigned long flags;
+ unsigned int index;
+ unsigned int scancode;
+ int retval;
spin_lock_irqsave(&rc_tab->lock, flags);
- start = 0;
- end = rc_tab->len - 1;
- while (start <= end) {
- mid = (start + end) / 2;
- if (rc_tab->scan[mid].scancode < scancode)
- start = mid + 1;
- else if (rc_tab->scan[mid].scancode > scancode)
- end = mid - 1;
- else {
- key = rc_tab->scan[mid].keycode;
- break;
- }
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_lookup_by_scancode(rc_tab, scancode);
}
- spin_unlock_irqrestore(&rc_tab->lock, flags);
- if (key == KEY_RESERVED)
- IR_dprintk(1, "unknown key for scancode 0x%04x\n",
- scancode);
+ if (index >= rc_tab->len) {
+ if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
+ IR_dprintk(1, "unknown key for scancode 0x%04x\n",
+ scancode);
+ retval = -EINVAL;
+ goto out;
+ }
- *keycode = key;
- return 0;
+ entry = &rc_tab->scan[index];
+
+ ke->index = index;
+ ke->keycode = entry->keycode;
+ ke->len = sizeof(entry->scancode);
+ memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
+
+out:
+ spin_unlock_irqrestore(&rc_tab->lock, flags);
+ return retval;
}
/**
@@ -268,12 +406,24 @@ static int ir_getkeycode(struct input_dev *dev,
*/
u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
{
- int keycode;
+ struct ir_input_dev *ir_dev = input_get_drvdata(dev);
+ struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ unsigned int keycode;
+ unsigned int index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rc_tab->lock, flags);
+
+ index = ir_lookup_by_scancode(rc_tab, scancode);
+ keycode = index < rc_tab->len ?
+ rc_tab->scan[index].keycode : KEY_RESERVED;
+
+ spin_unlock_irqrestore(&rc_tab->lock, flags);
- ir_getkeycode(dev, scancode, &keycode);
if (keycode != KEY_RESERVED)
IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
dev->name, scancode, keycode);
+
return keycode;
}
EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
@@ -319,7 +469,7 @@ static void ir_timer_keyup(unsigned long cookie)
* a keyup event might follow immediately after the keydown.
*/
spin_lock_irqsave(&ir->keylock, flags);
- if (time_is_after_eq_jiffies(ir->keyup_jiffies))
+ if (time_is_before_eq_jiffies(ir->keyup_jiffies))
ir_keyup(ir);
spin_unlock_irqrestore(&ir->keylock, flags);
}
@@ -453,8 +603,8 @@ int __ir_input_register(struct input_dev *input_dev,
goto out_dev;
}
- input_dev->getkeycode = ir_getkeycode;
- input_dev->setkeycode = ir_setkeycode;
+ input_dev->getkeycode_new = ir_getkeycode;
+ input_dev->setkeycode_new = ir_setkeycode;
input_set_drvdata(input_dev, ir_dev);
ir_dev->input_dev = input_dev;
@@ -462,12 +612,6 @@ int __ir_input_register(struct input_dev *input_dev,
spin_lock_init(&ir_dev->keylock);
setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
- ir_dev->rc_tab.name = rc_tab->name;
- ir_dev->rc_tab.ir_type = rc_tab->ir_type;
- ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size *
- sizeof(struct ir_scancode));
- ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL);
- ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode);
if (props) {
ir_dev->props = props;
if (props->open)
@@ -476,23 +620,14 @@ int __ir_input_register(struct input_dev *input_dev,
input_dev->close = ir_close;
}
- if (!ir_dev->rc_tab.scan) {
- rc = -ENOMEM;
- goto out_name;
- }
-
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- ir_dev->rc_tab.size, ir_dev->rc_tab.alloc);
-
set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_REP, input_dev->evbit);
set_bit(EV_MSC, input_dev->evbit);
set_bit(MSC_SCAN, input_dev->mscbit);
- if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) {
- rc = -ENOMEM;
- goto out_table;
- }
+ rc = ir_setkeytable(ir_dev, rc_tab);
+ if (rc)
+ goto out_name;
rc = ir_register_class(input_dev);
if (rc < 0)
@@ -510,12 +645,19 @@ int __ir_input_register(struct input_dev *input_dev,
(ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
" in raw mode" : "");
+ /*
+ * Default delay of 250ms is too short for some protocols, expecially
+ * since the timeout is currently set to 250ms. Increase it to 500ms,
+ * to avoid wrong repetition of the keycodes.
+ */
+ input_dev->rep[REP_DELAY] = 500;
+
return 0;
out_event:
ir_unregister_class(input_dev);
out_table:
- kfree(ir_dev->rc_tab.scan);
+ ir_free_table(&ir_dev->rc_tab);
out_name:
kfree(ir_dev->driver_name);
out_dev:
@@ -533,7 +675,6 @@ EXPORT_SYMBOL_GPL(__ir_input_register);
void ir_input_unregister(struct input_dev *input_dev)
{
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct ir_scancode_table *rc_tab;
if (!ir_dev)
return;
@@ -545,10 +686,7 @@ void ir_input_unregister(struct input_dev *input_dev)
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(input_dev);
- rc_tab = &ir_dev->rc_tab;
- rc_tab->size = 0;
- kfree(rc_tab->scan);
- rc_tab->scan = NULL;
+ ir_free_table(&ir_dev->rc_tab);
ir_unregister_class(input_dev);
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
index 77b5946413c0..1983cd3f3994 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/IR/ir-lirc-codec.c
@@ -235,6 +235,7 @@ static struct file_operations lirc_fops = {
.poll = lirc_dev_fop_poll,
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
+ .llseek = no_llseek,
};
static int ir_lirc_register(struct input_dev *input_dev)
@@ -267,7 +268,7 @@ static int ir_lirc_register(struct input_dev *input_dev)
features |= LIRC_CAN_SET_SEND_CARRIER;
if (ir_dev->props->s_tx_duty_cycle)
- features |= LIRC_CAN_SET_REC_DUTY_CYCLE;
+ features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
}
if (ir_dev->props->s_rx_carrier_range)
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 43094e7eccfa..8e0e1b1f8c87 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev)
"rc%u", (unsigned int)ir->devno);
if (IS_ERR(ir->raw->thread)) {
+ int ret = PTR_ERR(ir->raw->thread);
+
kfree(ir->raw);
ir->raw = NULL;
- return PTR_ERR(ir->raw->thread);
+ return ret;
}
mutex_lock(&ir_raw_handler_lock);
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/IR/ir-rc5-sz-decoder.c
new file mode 100644
index 000000000000..68f11d6acd5b
--- /dev/null
+++ b/drivers/media/IR/ir-rc5-sz-decoder.c
@@ -0,0 +1,153 @@
+/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
+ *
+ * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation 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.
+ */
+
+/*
+ * This code handles the 15 bit RC5-ish protocol used by the Streamzap
+ * PC Remote.
+ * It considers a carrier of 36 kHz, with a total of 15 bits, where
+ * the first two bits are start bits, and a third one is a filing bit
+ */
+
+#include "ir-core-priv.h"
+
+#define RC5_SZ_NBITS 15
+#define RC5_UNIT 888888 /* ns */
+#define RC5_BIT_START (1 * RC5_UNIT)
+#define RC5_BIT_END (1 * RC5_UNIT)
+
+enum rc5_sz_state {
+ STATE_INACTIVE,
+ STATE_BIT_START,
+ STATE_BIT_END,
+ STATE_FINISHED,
+};
+
+/**
+ * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
+ * @input_dev: the struct input_dev descriptor of the device
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+{
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
+ u8 toggle, command, system;
+ u32 scancode;
+
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
+ return 0;
+
+ if (IS_RESET(ev)) {
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+
+ if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
+ goto out;
+
+again:
+ IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
+ data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+
+ if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
+ return 0;
+
+ switch (data->state) {
+
+ case STATE_INACTIVE:
+ if (!ev.pulse)
+ break;
+
+ data->state = STATE_BIT_START;
+ data->count = 1;
+ data->wanted_bits = RC5_SZ_NBITS;
+ decrease_duration(&ev, RC5_BIT_START);
+ goto again;
+
+ case STATE_BIT_START:
+ if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
+ break;
+
+ data->bits <<= 1;
+ if (!ev.pulse)
+ data->bits |= 1;
+ data->count++;
+ data->state = STATE_BIT_END;
+ return 0;
+
+ case STATE_BIT_END:
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ break;
+
+ if (data->count == data->wanted_bits)
+ data->state = STATE_FINISHED;
+ else
+ data->state = STATE_BIT_START;
+
+ decrease_duration(&ev, RC5_BIT_END);
+ goto again;
+
+ case STATE_FINISHED:
+ if (ev.pulse)
+ break;
+
+ /* RC5-sz */
+ command = (data->bits & 0x0003F) >> 0;
+ system = (data->bits & 0x02FC0) >> 6;
+ toggle = (data->bits & 0x01000) ? 1 : 0;
+ scancode = system << 6 | command;
+
+ IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
+ scancode, toggle);
+
+ ir_keydown(input_dev, scancode, toggle);
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+
+out:
+ IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
+ data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+}
+
+static struct ir_raw_handler rc5_sz_handler = {
+ .protocols = IR_TYPE_RC5_SZ,
+ .decode = ir_rc5_sz_decode,
+};
+
+static int __init ir_rc5_sz_decode_init(void)
+{
+ ir_raw_handler_register(&rc5_sz_handler);
+
+ printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
+ return 0;
+}
+
+static void __exit ir_rc5_sz_decode_exit(void)
+{
+ ir_raw_handler_unregister(&rc5_sz_handler);
+}
+
+module_init(ir_rc5_sz_decode_init);
+module_exit(ir_rc5_sz_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
+MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index 96dafc425c8e..72403cdf427e 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -43,6 +43,7 @@ static struct {
{ IR_TYPE_RC6, "rc-6" },
{ IR_TYPE_JVC, "jvc" },
{ IR_TYPE_SONY, "sony" },
+ { IR_TYPE_RC5_SZ, "rc-5-sz" },
{ IR_TYPE_LIRC, "lirc" },
};
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
index 950e5d953c6f..2017273f8c86 100644
--- a/drivers/media/IR/keymaps/Makefile
+++ b/drivers/media/IR/keymaps/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-kworld-315u.o \
rc-kworld-plus-tv-analog.o \
rc-lirc.o \
+ rc-lme2510.o \
rc-manli.o \
rc-msi-tvanywhere.o \
rc-msi-tvanywhere-plus.o \
@@ -62,6 +63,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-rc5-tv.o \
rc-rc6-mce.o \
rc-real-audio-220-32-keys.o \
+ rc-streamzap.o \
rc-tbs-nec.o \
rc-terratec-cinergy-xs.o \
rc-tevii-nec.o \
diff --git a/drivers/media/IR/keymaps/rc-lme2510.c b/drivers/media/IR/keymaps/rc-lme2510.c
new file mode 100644
index 000000000000..40dcf0b4e21a
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-lme2510.c
@@ -0,0 +1,68 @@
+/* LME2510 remote control
+ *
+ *
+ * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+
+static struct ir_scancode lme2510_rc[] = {
+ { 0xba45, KEY_0 },
+ { 0xa05f, KEY_1 },
+ { 0xaf50, KEY_2 },
+ { 0xa25d, KEY_3 },
+ { 0xbe41, KEY_4 },
+ { 0xf50a, KEY_5 },
+ { 0xbd42, KEY_6 },
+ { 0xb847, KEY_7 },
+ { 0xb649, KEY_8 },
+ { 0xfa05, KEY_9 },
+ { 0xbc43, KEY_POWER },
+ { 0xb946, KEY_SUBTITLE },
+ { 0xf906, KEY_PAUSE },
+ { 0xfc03, KEY_MEDIA_REPEAT},
+ { 0xfd02, KEY_PAUSE },
+ { 0xa15e, KEY_VOLUMEUP },
+ { 0xa35c, KEY_VOLUMEDOWN },
+ { 0xf609, KEY_CHANNELUP },
+ { 0xe51a, KEY_CHANNELDOWN },
+ { 0xe11e, KEY_PLAY },
+ { 0xe41b, KEY_ZOOM },
+ { 0xa659, KEY_MUTE },
+ { 0xa55a, KEY_TV },
+ { 0xe718, KEY_RECORD },
+ { 0xf807, KEY_EPG },
+ { 0xfe01, KEY_STOP },
+
+};
+
+static struct rc_keymap lme2510_map = {
+ .map = {
+ .scan = lme2510_rc,
+ .size = ARRAY_SIZE(lme2510_rc),
+ .ir_type = IR_TYPE_UNKNOWN,
+ .name = RC_MAP_LME2510,
+ }
+};
+
+static int __init init_rc_lme2510_map(void)
+{
+ return ir_register_map(&lme2510_map);
+}
+
+static void __exit exit_rc_lme2510_map(void)
+{
+ ir_unregister_map(&lme2510_map);
+}
+
+module_init(init_rc_lme2510_map)
+module_exit(exit_rc_lme2510_map)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
index 64264f7f838f..39557ad401b6 100644
--- a/drivers/media/IR/keymaps/rc-rc6-mce.c
+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
@@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0416, KEY_PLAY },
{ 0x800f0418, KEY_PAUSE },
+ { 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f0419, KEY_STOP },
{ 0x800f0417, KEY_RECORD },
@@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0411, KEY_VOLUMEDOWN },
{ 0x800f0412, KEY_CHANNELUP },
{ 0x800f0413, KEY_CHANNELDOWN },
+ { 0x800f043a, KEY_BRIGHTNESSUP },
+ { 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0401, KEY_NUMERIC_1 },
{ 0x800f0402, KEY_NUMERIC_2 },
diff --git a/drivers/media/IR/keymaps/rc-streamzap.c b/drivers/media/IR/keymaps/rc-streamzap.c
new file mode 100644
index 000000000000..df32013a321c
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-streamzap.c
@@ -0,0 +1,82 @@
+/* rc-streamzap.c - Keytable for Streamzap PC Remote, for use
+ * with the Streamzap PC Remote IR Receiver.
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct ir_scancode streamzap[] = {
+/*
+ * The Streamzap remote is almost, but not quite, RC-5, as it has an extra
+ * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
+ * an additional RC-5-sz decoder is being deployed to support it, but it
+ * may be possible to merge it back with the standard RC-5 decoder.
+ */
+ { 0x28c0, KEY_NUMERIC_0 },
+ { 0x28c1, KEY_NUMERIC_1 },
+ { 0x28c2, KEY_NUMERIC_2 },
+ { 0x28c3, KEY_NUMERIC_3 },
+ { 0x28c4, KEY_NUMERIC_4 },
+ { 0x28c5, KEY_NUMERIC_5 },
+ { 0x28c6, KEY_NUMERIC_6 },
+ { 0x28c7, KEY_NUMERIC_7 },
+ { 0x28c8, KEY_NUMERIC_8 },
+ { 0x28c9, KEY_NUMERIC_9 },
+ { 0x28ca, KEY_POWER },
+ { 0x28cb, KEY_MUTE },
+ { 0x28cc, KEY_CHANNELUP },
+ { 0x28cd, KEY_VOLUMEUP },
+ { 0x28ce, KEY_CHANNELDOWN },
+ { 0x28cf, KEY_VOLUMEDOWN },
+ { 0x28d0, KEY_UP },
+ { 0x28d1, KEY_LEFT },
+ { 0x28d2, KEY_OK },
+ { 0x28d3, KEY_RIGHT },
+ { 0x28d4, KEY_DOWN },
+ { 0x28d5, KEY_MENU },
+ { 0x28d6, KEY_EXIT },
+ { 0x28d7, KEY_PLAY },
+ { 0x28d8, KEY_PAUSE },
+ { 0x28d9, KEY_STOP },
+ { 0x28da, KEY_BACK },
+ { 0x28db, KEY_FORWARD },
+ { 0x28dc, KEY_RECORD },
+ { 0x28dd, KEY_REWIND },
+ { 0x28de, KEY_FASTFORWARD },
+ { 0x28e0, KEY_RED },
+ { 0x28e1, KEY_GREEN },
+ { 0x28e2, KEY_YELLOW },
+ { 0x28e3, KEY_BLUE },
+
+};
+
+static struct rc_keymap streamzap_map = {
+ .map = {
+ .scan = streamzap,
+ .size = ARRAY_SIZE(streamzap),
+ .ir_type = IR_TYPE_RC5_SZ,
+ .name = RC_MAP_STREAMZAP,
+ }
+};
+
+static int __init init_rc_map_streamzap(void)
+{
+ return ir_register_map(&streamzap_map);
+}
+
+static void __exit exit_rc_map_streamzap(void)
+{
+ ir_unregister_map(&streamzap_map);
+}
+
+module_init(init_rc_map_streamzap)
+module_exit(exit_rc_map_streamzap)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
index 899891bec352..f6d571f067d3 100644
--- a/drivers/media/IR/lirc_dev.c
+++ b/drivers/media/IR/lirc_dev.c
@@ -163,6 +163,7 @@ static struct file_operations fops = {
.unlocked_ioctl = lirc_dev_fop_ioctl,
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int lirc_cdev_add(struct irctl *ir)
@@ -460,6 +461,8 @@ error:
mutex_unlock(&lirc_dev_lock);
+ nonseekable_open(inode, file);
+
return retval;
}
EXPORT_SYMBOL(lirc_dev_fop_open);
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
index ac6bb2c01a48..bc620e10ef77 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/IR/mceusb.c
@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
/* Philips eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
+ /* Philips/Spinel plus IR transceiver for ASUS */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x206c) },
+ /* Philips/Spinel plus IR transceiver for ASUS */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x2088) },
/* Realtek MCE IR Receiver */
{ USB_DEVICE(VENDOR_REALTEK, 0x0161) },
/* SMK/Toshiba G83C0004D410 */
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c
index 058e29fd478c..2cf57e64a80b 100644
--- a/drivers/media/IR/streamzap.c
+++ b/drivers/media/IR/streamzap.c
@@ -38,7 +38,7 @@
#include <linux/input.h>
#include <media/ir-core.h>
-#define DRIVER_VERSION "1.60"
+#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
#define DRIVER_DESC "Streamzap Remote Control driver"
@@ -69,6 +69,13 @@ MODULE_DEVICE_TABLE(usb, streamzap_table);
/* number of samples buffered */
#define SZ_BUF_LEN 128
+/* from ir-rc5-sz-decoder.c */
+#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
+#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
+#else
+#define load_rc5_sz_decode() 0
+#endif
+
enum StreamzapDecoderState {
PulseSpace,
FullPulse,
@@ -81,7 +88,6 @@ struct streamzap_ir {
/* ir-core */
struct ir_dev_props *props;
- struct ir_raw_event rawir;
/* core device info */
struct device *dev;
@@ -98,17 +104,6 @@ struct streamzap_ir {
dma_addr_t dma_in;
unsigned int buf_in_len;
- /* timer used to support delay buffering */
- struct timer_list delay_timer;
- bool timer_running;
- spinlock_t timer_lock;
- struct timer_list flush_timer;
- bool flush;
-
- /* delay buffer */
- struct kfifo fifo;
- bool fifo_initialized;
-
/* track what state we're in */
enum StreamzapDecoderState decoder_state;
/* tracks whether we are currently receiving some signal */
@@ -118,7 +113,7 @@ struct streamzap_ir {
/* start time of signal; necessary for gap tracking */
struct timeval signal_last;
struct timeval signal_start;
- /* bool timeout_enabled; */
+ bool timeout_enabled;
char name[128];
char phys[64];
@@ -143,122 +138,16 @@ static struct usb_driver streamzap_driver = {
.id_table = streamzap_table,
};
-static void streamzap_stop_timer(struct streamzap_ir *sz)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sz->timer_lock, flags);
- if (sz->timer_running) {
- sz->timer_running = false;
- spin_unlock_irqrestore(&sz->timer_lock, flags);
- del_timer_sync(&sz->delay_timer);
- } else {
- spin_unlock_irqrestore(&sz->timer_lock, flags);
- }
-}
-
-static void streamzap_flush_timeout(unsigned long arg)
-{
- struct streamzap_ir *sz = (struct streamzap_ir *)arg;
-
- dev_info(sz->dev, "%s: callback firing\n", __func__);
-
- /* finally start accepting data */
- sz->flush = false;
-}
-
-static void streamzap_delay_timeout(unsigned long arg)
-{
- struct streamzap_ir *sz = (struct streamzap_ir *)arg;
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- unsigned long flags;
- int len, ret;
- static unsigned long delay;
- bool wake = false;
-
- /* deliver data every 10 ms */
- delay = msecs_to_jiffies(10);
-
- spin_lock_irqsave(&sz->timer_lock, flags);
-
- if (kfifo_len(&sz->fifo) > 0) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- }
-
- len = kfifo_len(&sz->fifo);
- if (len > 0) {
- while ((len < SZ_BUF_LEN / 2) &&
- (len < SZ_BUF_LEN * sizeof(int))) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- len = kfifo_len(&sz->fifo);
- }
- if (sz->timer_running)
- mod_timer(&sz->delay_timer, jiffies + delay);
-
- } else {
- sz->timer_running = false;
- }
-
- if (wake)
- ir_raw_event_handle(sz->idev);
-
- spin_unlock_irqrestore(&sz->timer_lock, flags);
-}
-
-static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
+static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- bool wake = false;
- int ret;
-
- while (kfifo_len(&sz->fifo) > 0) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- wake = true;
- }
-
- if (wake)
- ir_raw_event_handle(sz->idev);
-}
-
-static void sz_push(struct streamzap_ir *sz)
-{
- struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&sz->timer_lock, flags);
- if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
- ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
- if (ret != sizeof(rawir))
- dev_err(sz->dev, "Problem w/kfifo_out...\n");
- ir_raw_event_store(sz->idev, &rawir);
- }
-
- kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
-
- if (!sz->timer_running) {
- sz->delay_timer.expires = jiffies + (HZ / 10);
- add_timer(&sz->delay_timer);
- sz->timer_running = true;
- }
-
- spin_unlock_irqrestore(&sz->timer_lock, flags);
+ ir_raw_event_store(sz->idev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
unsigned char value)
{
+ struct ir_raw_event rawir;
+
if (sz->idle) {
long deltv;
@@ -266,33 +155,33 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
do_gettimeofday(&sz->signal_start);
deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
- sz->rawir.pulse = false;
+ rawir.pulse = false;
if (deltv > 15) {
/* really long time */
- sz->rawir.duration = IR_MAX_DURATION;
+ rawir.duration = IR_MAX_DURATION;
} else {
- sz->rawir.duration = (int)(deltv * 1000000 +
+ rawir.duration = (int)(deltv * 1000000 +
sz->signal_start.tv_usec -
sz->signal_last.tv_usec);
- sz->rawir.duration -= sz->sum;
- sz->rawir.duration *= 1000;
- sz->rawir.duration &= IR_MAX_DURATION;
+ rawir.duration -= sz->sum;
+ rawir.duration *= 1000;
+ rawir.duration &= IR_MAX_DURATION;
}
- dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
- sz_push(sz);
+ dev_dbg(sz->dev, "ls %u\n", rawir.duration);
+ sz_push(sz, rawir);
- sz->idle = 0;
+ sz->idle = false;
sz->sum = 0;
}
- sz->rawir.pulse = true;
- sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
- sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
- sz->sum += sz->rawir.duration;
- sz->rawir.duration *= 1000;
- sz->rawir.duration &= IR_MAX_DURATION;
- dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
- sz_push(sz);
+ rawir.pulse = true;
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
+ sz->sum += rawir.duration;
+ rawir.duration *= 1000;
+ rawir.duration &= IR_MAX_DURATION;
+ dev_dbg(sz->dev, "p %u\n", rawir.duration);
+ sz_push(sz, rawir);
}
static void sz_push_half_pulse(struct streamzap_ir *sz,
@@ -304,13 +193,15 @@ static void sz_push_half_pulse(struct streamzap_ir *sz,
static void sz_push_full_space(struct streamzap_ir *sz,
unsigned char value)
{
- sz->rawir.pulse = false;
- sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
- sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
- sz->sum += sz->rawir.duration;
- sz->rawir.duration *= 1000;
- dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
- sz_push(sz);
+ struct ir_raw_event rawir;
+
+ rawir.pulse = false;
+ rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
+ rawir.duration += STREAMZAP_RESOLUTION / 2;
+ sz->sum += rawir.duration;
+ rawir.duration *= 1000;
+ dev_dbg(sz->dev, "s %u\n", rawir.duration);
+ sz_push(sz, rawir);
}
static void sz_push_half_space(struct streamzap_ir *sz,
@@ -330,10 +221,8 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz;
unsigned int i;
int len;
- #if 0
static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
IR_MAX_DURATION) | 0x03000000);
- #endif
if (!urb)
return;
@@ -356,57 +245,53 @@ static void streamzap_callback(struct urb *urb)
}
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
- if (!sz->flush) {
- for (i = 0; i < urb->actual_length; i++) {
- dev_dbg(sz->dev, "%d: %x\n", i,
- (unsigned char)sz->buf_in[i]);
- switch (sz->decoder_state) {
- case PulseSpace:
- if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
- STREAMZAP_PULSE_MASK) {
- sz->decoder_state = FullPulse;
- continue;
- } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
- == STREAMZAP_SPACE_MASK) {
- sz_push_half_pulse(sz, sz->buf_in[i]);
- sz->decoder_state = FullSpace;
- continue;
- } else {
- sz_push_half_pulse(sz, sz->buf_in[i]);
- sz_push_half_space(sz, sz->buf_in[i]);
- }
- break;
- case FullPulse:
- sz_push_full_pulse(sz, sz->buf_in[i]);
- sz->decoder_state = IgnorePulse;
- break;
- case FullSpace:
- if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
- sz->idle = 1;
- streamzap_stop_timer(sz);
- #if 0
- if (sz->timeout_enabled) {
- sz->rawir.pulse = false;
- sz->rawir.duration = timeout;
- sz->rawir.duration *= 1000;
- sz_push(sz);
- }
- #endif
- streamzap_flush_delay_buffer(sz);
- } else
- sz_push_full_space(sz, sz->buf_in[i]);
- sz->decoder_state = PulseSpace;
- break;
- case IgnorePulse:
- if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
- STREAMZAP_SPACE_MASK) {
- sz->decoder_state = FullSpace;
- continue;
- }
+ for (i = 0; i < len; i++) {
+ dev_dbg(sz->dev, "sz idx %d: %x\n",
+ i, (unsigned char)sz->buf_in[i]);
+ switch (sz->decoder_state) {
+ case PulseSpace:
+ if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
+ STREAMZAP_PULSE_MASK) {
+ sz->decoder_state = FullPulse;
+ continue;
+ } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
+ == STREAMZAP_SPACE_MASK) {
+ sz_push_half_pulse(sz, sz->buf_in[i]);
+ sz->decoder_state = FullSpace;
+ continue;
+ } else {
+ sz_push_half_pulse(sz, sz->buf_in[i]);
sz_push_half_space(sz, sz->buf_in[i]);
- sz->decoder_state = PulseSpace;
- break;
}
+ break;
+ case FullPulse:
+ sz_push_full_pulse(sz, sz->buf_in[i]);
+ sz->decoder_state = IgnorePulse;
+ break;
+ case FullSpace:
+ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
+ struct ir_raw_event rawir;
+
+ rawir.pulse = false;
+ rawir.duration = timeout * 1000;
+ sz->idle = true;
+ if (sz->timeout_enabled)
+ sz_push(sz, rawir);
+ ir_raw_event_handle(sz->idev);
+ } else {
+ sz_push_full_space(sz, sz->buf_in[i]);
+ }
+ sz->decoder_state = PulseSpace;
+ break;
+ case IgnorePulse:
+ if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK) ==
+ STREAMZAP_SPACE_MASK) {
+ sz->decoder_state = FullSpace;
+ continue;
+ }
+ sz_push_half_space(sz, sz->buf_in[i]);
+ sz->decoder_state = PulseSpace;
+ break;
}
}
@@ -446,12 +331,11 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
props->priv = sz;
props->driver_type = RC_DRIVER_IR_RAW;
- /* FIXME: not sure about supported protocols, check on this */
- props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
+ props->allowed_protos = IR_TYPE_ALL;
sz->props = props;
- ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
+ ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
goto irdev_failed;
@@ -467,29 +351,6 @@ idev_alloc_failed:
return NULL;
}
-static int streamzap_delay_buf_init(struct streamzap_ir *sz)
-{
- int ret;
-
- ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
- GFP_KERNEL);
- if (ret == 0)
- sz->fifo_initialized = 1;
-
- return ret;
-}
-
-static void streamzap_start_flush_timer(struct streamzap_ir *sz)
-{
- sz->flush_timer.expires = jiffies + HZ;
- sz->flush = true;
- add_timer(&sz->flush_timer);
-
- sz->urb_in->dev = sz->usbdev;
- if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
- dev_err(sz->dev, "urb submit failed\n");
-}
-
/**
* streamzap_probe
*
@@ -575,35 +436,21 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- retval = streamzap_delay_buf_init(sz);
- if (retval) {
- dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
- goto free_urb_in;
- }
-
sz->idev = streamzap_init_input_dev(sz);
if (!sz->idev)
goto input_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
+ /* FIXME: don't yet have a way to set this */
+ sz->timeout_enabled = true;
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
- sz->timeout_enabled = false;
sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
#endif
- init_timer(&sz->delay_timer);
- sz->delay_timer.function = streamzap_delay_timeout;
- sz->delay_timer.data = (unsigned long)sz;
- spin_lock_init(&sz->timer_lock);
-
- init_timer(&sz->flush_timer);
- sz->flush_timer.function = streamzap_flush_timeout;
- sz->flush_timer.data = (unsigned long)sz;
-
do_gettimeofday(&sz->signal_start);
/* Complete final initialisations */
@@ -615,16 +462,18 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
usb_set_intfdata(intf, sz);
- streamzap_start_flush_timer(sz);
+ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
+ dev_err(sz->dev, "urb submit failed\n");
dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
usbdev->bus->busnum, usbdev->devnum);
+ /* Load the streamzap not-quite-rc5 decoder too */
+ load_rc5_sz_decode();
+
return 0;
input_dev_fail:
- kfifo_free(&sz->fifo);
-free_urb_in:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@@ -654,13 +503,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
if (!sz)
return;
- if (sz->flush) {
- sz->flush = false;
- del_timer_sync(&sz->flush_timer);
- }
-
- streamzap_stop_timer(sz);
-
sz->usbdev = NULL;
ir_input_unregister(sz->idev);
usb_kill_urb(sz->urb_in);
@@ -674,13 +516,6 @@ static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
- if (sz->flush) {
- sz->flush = false;
- del_timer_sync(&sz->flush_timer);
- }
-
- streamzap_stop_timer(sz);
-
usb_kill_urb(sz->urb_in);
return 0;
@@ -690,13 +525,6 @@ static int streamzap_resume(struct usb_interface *intf)
{
struct streamzap_ir *sz = usb_get_intfdata(intf);
- if (sz->fifo_initialized)
- kfifo_reset(&sz->fifo);
-
- sz->flush_timer.expires = jiffies + HZ;
- sz->flush = true;
- add_timer(&sz->flush_timer);
-
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
dev_err(sz->dev, "Error sumbiting urb\n");
return -EIO;
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index b3ed5daaacf2..2385e6cca635 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -179,4 +179,11 @@ config MEDIA_TUNER_MAX2165
help
A driver for the silicon tuner MAX2165 from Maxim.
+config MEDIA_TUNER_TDA18218
+ tristate "NXP TDA18218 silicon tuner"
+ depends on VIDEO_MEDIA && I2C
+ default m if MEDIA_TUNER_CUSTOMISE
+ help
+ NXP TDA18218 silicon tuner driver.
+
endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index a5438523f30d..96da03d349ca 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c
new file mode 100644
index 000000000000..8da1fdeddaa7
--- /dev/null
+++ b/drivers/media/common/tuners/tda18218.c
@@ -0,0 +1,334 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@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 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 "tda18218.h"
+#include "tda18218_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+/* write multiple registers */
+static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
+{
+ int ret;
+ u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
+ struct i2c_msg msg[1] = {
+ {
+ .addr = priv->cfg->i2c_address,
+ .flags = 0,
+ .buf = buf,
+ }
+ };
+
+ msg_len_max = priv->cfg->i2c_wr_max - 1;
+ quotient = len / msg_len_max;
+ remainder = len % msg_len_max;
+ msg_len = msg_len_max;
+ for (i = 0; (i <= quotient && remainder); i++) {
+ if (i == quotient) /* set len of the last msg */
+ msg_len = remainder;
+
+ msg[0].len = msg_len + 1;
+ buf[0] = reg + i * msg_len_max;
+ memcpy(&buf[1], &val[i * msg_len_max], msg_len);
+
+ ret = i2c_transfer(priv->i2c, msg, 1);
+ if (ret != 1)
+ break;
+ }
+
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+/* read multiple registers */
+static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
+{
+ int ret;
+ u8 buf[reg+len]; /* we must start read always from reg 0x00 */
+ struct i2c_msg msg[2] = {
+ {
+ .addr = priv->cfg->i2c_address,
+ .flags = 0,
+ .len = 1,
+ .buf = "\x00",
+ }, {
+ .addr = priv->cfg->i2c_address,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ ret = i2c_transfer(priv->i2c, msg, 2);
+ if (ret == 2) {
+ memcpy(val, &buf[reg], len);
+ ret = 0;
+ } else {
+ warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+/* write single register */
+static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
+{
+ return tda18218_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+
+static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
+{
+ return tda18218_rd_regs(priv, reg, val, 1);
+}
+
+static int tda18218_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct tda18218_priv *priv = fe->tuner_priv;
+ int ret;
+ u8 buf[3], i, BP_Filter, LP_Fc;
+ u32 LO_Frac;
+ /* TODO: find out correct AGC algorithm */
+ u8 agc[][2] = {
+ { R20_AGC11, 0x60 },
+ { R23_AGC21, 0x02 },
+ { R20_AGC11, 0xa0 },
+ { R23_AGC21, 0x09 },
+ { R20_AGC11, 0xe0 },
+ { R23_AGC21, 0x0c },
+ { R20_AGC11, 0x40 },
+ { R23_AGC21, 0x01 },
+ { R20_AGC11, 0x80 },
+ { R23_AGC21, 0x08 },
+ { R20_AGC11, 0xc0 },
+ { R23_AGC21, 0x0b },
+ { R24_AGC22, 0x1c },
+ { R24_AGC22, 0x0c },
+ };
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+ /* low-pass filter cut-off frequency */
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ LP_Fc = 0;
+ LO_Frac = params->frequency + 4000000;
+ break;
+ case BANDWIDTH_7_MHZ:
+ LP_Fc = 1;
+ LO_Frac = params->frequency + 3500000;
+ break;
+ case BANDWIDTH_8_MHZ:
+ default:
+ LP_Fc = 2;
+ LO_Frac = params->frequency + 4000000;
+ break;
+ }
+
+ /* band-pass filter */
+ if (LO_Frac < 188000000)
+ BP_Filter = 3;
+ else if (LO_Frac < 253000000)
+ BP_Filter = 4;
+ else if (LO_Frac < 343000000)
+ BP_Filter = 5;
+ else
+ BP_Filter = 6;
+
+ buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
+ buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
+ buf[2] = priv->regs[R1C_AGC2B];
+ ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
+ if (ret)
+ goto error;
+
+ buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
+ buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
+ buf[2] = (LO_Frac / 1000) << 4 |
+ (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
+ ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
+ if (ret)
+ goto error;
+
+ buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
+ ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
+ if (ret)
+ goto error;
+
+ buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
+ ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
+ if (ret)
+ goto error;
+
+ /* trigger AGC */
+ for (i = 0; i < ARRAY_SIZE(agc); i++) {
+ ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
+ if (ret)
+ goto error;
+ }
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+ if (ret)
+ dbg("%s: failed ret:%d", __func__, ret);
+
+ return ret;
+}
+
+static int tda18218_sleep(struct dvb_frontend *fe)
+{
+ struct tda18218_priv *priv = fe->tuner_priv;
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+ /* standby */
+ ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+ if (ret)
+ dbg("%s: failed ret:%d", __func__, ret);
+
+ return ret;
+}
+
+static int tda18218_init(struct dvb_frontend *fe)
+{
+ struct tda18218_priv *priv = fe->tuner_priv;
+ int ret;
+
+ /* TODO: calibrations */
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+ ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+ if (ret)
+ dbg("%s: failed ret:%d", __func__, ret);
+
+ return ret;
+}
+
+static int tda18218_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static const struct dvb_tuner_ops tda18218_tuner_ops = {
+ .info = {
+ .name = "NXP TDA18218",
+
+ .frequency_min = 174000000,
+ .frequency_max = 864000000,
+ .frequency_step = 1000,
+ },
+
+ .release = tda18218_release,
+ .init = tda18218_init,
+ .sleep = tda18218_sleep,
+
+ .set_params = tda18218_set_params,
+};
+
+struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct tda18218_config *cfg)
+{
+ struct tda18218_priv *priv = NULL;
+ u8 val;
+ int ret;
+ /* chip default registers values */
+ static u8 def_regs[] = {
+ 0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
+ 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
+ 0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
+ 0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
+ 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
+ 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
+ };
+
+ priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+ fe->tuner_priv = priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+ /* check if the tuner is there */
+ ret = tda18218_rd_reg(priv, R00_ID, &val);
+ dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
+ if (ret || val != def_regs[R00_ID]) {
+ kfree(priv);
+ return NULL;
+ }
+
+ info("NXP TDA18218HN successfully identified.");
+
+ memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ memcpy(priv->regs, def_regs, sizeof(def_regs));
+
+ /* loop-through enabled chip default register values */
+ if (priv->cfg->loop_through) {
+ priv->regs[R17_PD1] = 0xb0;
+ priv->regs[R18_PD2] = 0x59;
+ }
+
+ /* standby */
+ ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
+ if (ret)
+ dbg("%s: failed ret:%d", __func__, ret);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+ return fe;
+}
+EXPORT_SYMBOL(tda18218_attach);
+
+MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tda18218.h b/drivers/media/common/tuners/tda18218.h
new file mode 100644
index 000000000000..b4180d180029
--- /dev/null
+++ b/drivers/media/common/tuners/tda18218.h
@@ -0,0 +1,45 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@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 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 TDA18218_H
+#define TDA18218_H
+
+#include "dvb_frontend.h"
+
+struct tda18218_config {
+ u8 i2c_address;
+ u8 i2c_wr_max;
+ u8 loop_through:1;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
+ (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct tda18218_config *cfg);
+#else
+static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct tda18218_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h
new file mode 100644
index 000000000000..904e5365c78c
--- /dev/null
+++ b/drivers/media/common/tuners/tda18218_priv.h
@@ -0,0 +1,106 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@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 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 TDA18218_PRIV_H
+#define TDA18218_PRIV_H
+
+#define LOG_PREFIX "tda18218"
+
+#undef dbg
+#define dbg(f, arg...) \
+ if (debug) \
+ printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#define R00_ID 0x00 /* ID byte */
+#define R01_R1 0x01 /* Read byte 1 */
+#define R02_R2 0x02 /* Read byte 2 */
+#define R03_R3 0x03 /* Read byte 3 */
+#define R04_R4 0x04 /* Read byte 4 */
+#define R05_R5 0x05 /* Read byte 5 */
+#define R06_R6 0x06 /* Read byte 6 */
+#define R07_MD1 0x07 /* Main divider byte 1 */
+#define R08_PSM1 0x08 /* PSM byte 1 */
+#define R09_MD2 0x09 /* Main divider byte 2 */
+#define R0A_MD3 0x0a /* Main divider byte 1 */
+#define R0B_MD4 0x0b /* Main divider byte 4 */
+#define R0C_MD5 0x0c /* Main divider byte 5 */
+#define R0D_MD6 0x0d /* Main divider byte 6 */
+#define R0E_MD7 0x0e /* Main divider byte 7 */
+#define R0F_MD8 0x0f /* Main divider byte 8 */
+#define R10_CD1 0x10 /* Call divider byte 1 */
+#define R11_CD2 0x11 /* Call divider byte 2 */
+#define R12_CD3 0x12 /* Call divider byte 3 */
+#define R13_CD4 0x13 /* Call divider byte 4 */
+#define R14_CD5 0x14 /* Call divider byte 5 */
+#define R15_CD6 0x15 /* Call divider byte 6 */
+#define R16_CD7 0x16 /* Call divider byte 7 */
+#define R17_PD1 0x17 /* Power-down byte 1 */
+#define R18_PD2 0x18 /* Power-down byte 2 */
+#define R19_XTOUT 0x19 /* XTOUT byte */
+#define R1A_IF1 0x1a /* IF byte 1 */
+#define R1B_IF2 0x1b /* IF byte 2 */
+#define R1C_AGC2B 0x1c /* AGC2b byte */
+#define R1D_PSM2 0x1d /* PSM byte 2 */
+#define R1E_PSM3 0x1e /* PSM byte 3 */
+#define R1F_PSM4 0x1f /* PSM byte 4 */
+#define R20_AGC11 0x20 /* AGC1 byte 1 */
+#define R21_AGC12 0x21 /* AGC1 byte 2 */
+#define R22_AGC13 0x22 /* AGC1 byte 3 */
+#define R23_AGC21 0x23 /* AGC2 byte 1 */
+#define R24_AGC22 0x24 /* AGC2 byte 2 */
+#define R25_AAGC 0x25 /* Analog AGC byte */
+#define R26_RC 0x26 /* RC byte */
+#define R27_RSSI 0x27 /* RSSI byte */
+#define R28_IRCAL1 0x28 /* IR CAL byte 1 */
+#define R29_IRCAL2 0x29 /* IR CAL byte 2 */
+#define R2A_IRCAL3 0x2a /* IR CAL byte 3 */
+#define R2B_IRCAL4 0x2b /* IR CAL byte 4 */
+#define R2C_RFCAL1 0x2c /* RF CAL byte 1 */
+#define R2D_RFCAL2 0x2d /* RF CAL byte 2 */
+#define R2E_RFCAL3 0x2e /* RF CAL byte 3 */
+#define R2F_RFCAL4 0x2f /* RF CAL byte 4 */
+#define R30_RFCAL5 0x30 /* RF CAL byte 5 */
+#define R31_RFCAL6 0x31 /* RF CAL byte 6 */
+#define R32_RFCAL7 0x32 /* RF CAL byte 7 */
+#define R33_RFCAL8 0x33 /* RF CAL byte 8 */
+#define R34_RFCAL9 0x34 /* RF CAL byte 9 */
+#define R35_RFCAL10 0x35 /* RF CAL byte 10 */
+#define R36_RFCALRAM1 0x36 /* RF CAL RAM byte 1 */
+#define R37_RFCALRAM2 0x37 /* RF CAL RAM byte 2 */
+#define R38_MARGIN 0x38 /* Margin byte */
+#define R39_FMAX1 0x39 /* Fmax byte 1 */
+#define R3A_FMAX2 0x3a /* Fmax byte 2 */
+
+#define TDA18218_NUM_REGS 59
+
+struct tda18218_priv {
+ struct tda18218_config *cfg;
+ struct i2c_adapter *i2c;
+
+ u8 regs[TDA18218_NUM_REGS];
+};
+
+#endif
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index d2b2c12a5561..76ac5cd84af7 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -1042,7 +1042,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
+ const struct xc5000_config *cfg)
{
struct xc5000_priv *priv = NULL;
int instance;
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index e6d7236c9ea1..3756e73649be 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -53,11 +53,11 @@ struct xc5000_config {
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
- struct xc5000_config *cfg);
+ const struct xc5000_config *cfg);
#else
static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
+ const struct xc5000_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index d75788b4e22e..1285100806ff 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -695,7 +695,8 @@ static const struct file_operations dst_ca_fops = {
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
- .write = dst_ca_write
+ .write = dst_ca_write,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct dvb_device dvbdev_ca = {
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 2de13b04b09d..a655666be54d 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -1143,6 +1143,7 @@ static const struct file_operations dvb_demux_fops = {
.open = dvb_demux_open,
.release = dvb_demux_release,
.poll = dvb_demux_poll,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct dvb_device dvbdev_demux = {
@@ -1212,6 +1213,7 @@ static const struct file_operations dvb_dvr_fops = {
.open = dvb_dvr_open,
.release = dvb_dvr_release,
.poll = dvb_dvr_poll,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct dvb_device dvbdev_dvr = {
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 1723a984a522..1a8b8336b2c3 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1622,6 +1622,7 @@ static const struct file_operations dvb_ca_fops = {
.open = dvb_ca_en50221_io_open,
.release = dvb_ca_en50221_io_release,
.poll = dvb_ca_en50221_io_poll,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct dvb_device dvbdev_ca = {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 4d45b7d6b3fb..a2e3d33328f2 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -2034,7 +2034,8 @@ static const struct file_operations dvb_frontend_fops = {
.unlocked_ioctl = dvb_generic_ioctl,
.poll = dvb_frontend_poll,
.open = dvb_frontend_open,
- .release = dvb_frontend_release
+ .release = dvb_frontend_release,
+ .llseek = noop_llseek,/* no read or write fn */
};
int dvb_register_frontend(struct dvb_adapter* dvb,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index bf0e6bed28dd..f9f19be77181 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -260,7 +260,7 @@ struct dvb_frontend_ops {
int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe);
- int (*write)(struct dvb_frontend* fe, u8* buf, int len);
+ int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
/* if this is set, it overrides the default swzigzag */
int (*tune)(struct dvb_frontend* fe,
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index a08032284cbf..27417d2a90ea 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1468,6 +1468,7 @@ static const struct file_operations dvb_net_fops = {
.unlocked_ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
.release = dvb_net_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct dvb_device dvbdev_net = {
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 28f486edcaf0..7f77a926b6de 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -105,6 +105,7 @@ static const struct file_operations dvb_device_fops =
{
.owner = THIS_MODULE,
.open = dvb_device_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct cdev dvb_device_cdev;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index fdc19bba2128..4734ec073e01 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -314,6 +314,7 @@ config DVB_USB_AF9015
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
@@ -346,3 +347,14 @@ config DVB_USB_AZ6027
select DVB_STB6100 if !DVB_FE_CUSTOMISE
help
Say Y here to support the AZ6027 device
+
+config DVB_USB_LME2510
+ tristate "LME DM04/QQBOX DVB-S USB2.0 support"
+ depends on DVB_USB
+ select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+ select DVB_TDA826X if !DVB_FE_CUSTOMISE
+ select DVB_STV0288 if !DVB_FE_CUSTOMISE
+ select DVB_IX2505V if !DVB_FE_CUSTOMISE
+ depends on IR_CORE
+ help
+ Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 1a192453b0e7..5b1d12f2d591 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -88,6 +88,9 @@ obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
dvb-usb-az6027-objs = az6027.o
obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
+dvb-usb-lmedm04-objs = lmedm04.o
+obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index ea1ed3b4592a..55a12df9a2f9 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -31,6 +31,7 @@
#include "tda18271.h"
#include "mxl5005s.h"
#include "mc44s803.h"
+#include "tda18218.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -992,6 +993,7 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MT2060_2:
case AF9013_TUNER_TDA18271:
case AF9013_TUNER_QT1010A:
+ case AF9013_TUNER_TDA18218:
af9015_af9013_config[i].rf_spec_inv = 1;
break;
case AF9013_TUNER_MXL5003D:
@@ -1003,9 +1005,6 @@ static int af9015_read_config(struct usb_device *udev)
af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
af9015_af9013_config[i].rf_spec_inv = 1;
break;
- case AF9013_TUNER_TDA18218:
- warn("tuner NXP TDA18218 not supported yet");
- return -ENODEV;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1208,6 +1207,11 @@ static struct mc44s803_config af9015_mc44s803_config = {
.dig_out = 1,
};
+static struct tda18218_config af9015_tda18218_config = {
+ .i2c_address = 0xc0,
+ .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
@@ -1238,6 +1242,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
&af9015_tda18271_config) == NULL ? -ENODEV : 0;
break;
+ case AF9013_TUNER_TDA18218:
+ ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap,
+ &af9015_tda18218_config) == NULL ? -ENODEV : 0;
+ break;
case AF9013_TUNER_MXL5003D:
ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
&af9015_mxl5003_config) == NULL ? -ENODEV : 0;
@@ -1300,6 +1308,7 @@ static struct usb_device_id af9015_usb_table[] = {
/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
+ {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1629,6 +1638,24 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.cold_ids = {&af9015_usb_table[32], NULL},
.warm_ids = {NULL},
},
+ },
+
+ .identify_state = af9015_identify_state,
+
+ .rc.legacy = {
+ .rc_query = af9015_rc_query,
+ .rc_interval = 150,
+ },
+
+ .i2c_algo = &af9015_i2c_algo,
+
+ .num_device_descs = 1, /* max 9 */
+ .devices = {
+ {
+ .name = "TerraTec Cinergy T Stick RC",
+ .cold_ids = {&af9015_usb_table[33], NULL},
+ .warm_ids = {NULL},
+ },
}
},
};
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index fe818348b8a3..48397f103d32 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf,
else
dev->props.rc.core.bulk_mode = false;
- /* Need a higher delay, to avoid wrong repeat */
- dev->rc_input_dev->rep[REP_DELAY] = 500;
-
dib0700_rc_setup(dev);
return 0;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index f634d2e784b2..e06acd1fecb6 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0;
}
+/* STK7770P */
+static struct dib7000p_config dib7770p_dib7000p_config = {
+ .output_mpeg2_in_188_bytes = 1,
+
+ .agc_config_count = 1,
+ .agc = &dib7070_agc_config,
+ .bw = &dib7070_bw_config_12_mhz,
+ .tuner_is_baseband = 1,
+ .spur_protect = 1,
+
+ .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+ .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+ .hostbus_diversity = 1,
+ .enable_current_mirror = 1,
+ .disable_sample_and_hold = 0,
+};
+
+static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+ if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
+ p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ else
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+ dib0700_ctrl_clock(adap->dev, 72, 1);
+
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(10);
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &dib7770p_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+ &dib7770p_dib7000p_config);
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
/* DIB807x generic */
static struct dibx000_agc_config dib807x_agc_config[2] = {
{
@@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
- { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
+ { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
@@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.pid_filter_count = 32,
.pid_filter = stk70x0p_pid_filter,
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
- .frontend_attach = stk7070p_frontend_attach,
+ .frontend_attach = stk7770p_frontend_attach,
.tuner_attach = dib7770p_tuner_attach,
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 1a774d58d664..dc6a0f194e5b 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -133,6 +133,7 @@
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
+#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
#define USB_PID_TWINHAN_VP7020_COLD 0x3203
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
index 93c21ddd0b77..015b4e8af1a5 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -75,7 +75,7 @@ static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
return 0;
}
-static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
+static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
struct jdvbt90502_state *state = fe->demodulator_priv;
int err, i;
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
new file mode 100644
index 000000000000..d5374ac075d3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -0,0 +1,936 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
+ * LME2510 + LGTDQT-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MV001F (LME2510 +LGTDQY-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ * For firmware see Documentation/dvb/lmedm04.txt
+ *
+ * I2C addresses:
+ * 0xd0 - STV0288 - Demodulator
+ * 0xc0 - Sharp IX2505V - Tuner
+ * --or--
+ * 0x1c - TDA10086 - Demodulator
+ * 0xc0 - TDA8263 - Tuner
+ *
+ * ***Please Note***
+ * There are other variants of the DM04
+ * ***NOT SUPPORTED***
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ * MV0194 (LME2510+SHARP0194)
+ * MVB0194 (LME2510C+SHARP0194)
+ *
+ *
+ * VID = 3344 PID LME2510=1122 LME2510C=1120
+ *
+ * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
+ * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ * Known Issues :
+ * LME2510: Non Intel USB chipsets fail to maintain High Speed on
+ * Boot or Hot Plug.
+ *
+ * DiSEqC functions are not fully supported in this driver. The main
+ * reason is the frontend is cut off during streaming. Allowing frontend
+ * access will stall the driver. Applications that attempt to this, the
+ * commands are ignored.
+ *
+ * PID functions have been removed from this driver version due to
+ * problems with different firmware and application versions.
+ */
+#define DVB_USB_LOG_PREFIX "LME2510(C)"
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/ir-core.h>
+
+#include "dvb-usb.h"
+#include "lmedm04.h"
+#include "tda826x.h"
+#include "tda10086.h"
+#include "stv0288.h"
+#include "ix2505v.h"
+
+
+
+/* debug */
+static int dvb_usb_lme2510_debug;
+#define l_dprintk(var, level, args...) do { \
+ if ((var >= level)) \
+ printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
+} while (0)
+
+#define deb_info(level, args...) l_dprintk(dvb_usb_lme2510_debug, level, args)
+#define debug_data_snipet(level, name, p) \
+ deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
+ *p, *(p+1), *(p+2), *(p+3), *(p+4), \
+ *(p+5), *(p+6), *(p+7));
+
+
+module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
+ DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+#define TUNER_LG 0x1
+#define TUNER_S7395 0x2
+
+struct lme2510_state {
+ u8 id;
+ u8 tuner_config;
+ u8 signal_lock;
+ u8 signal_level;
+ u8 signal_sn;
+ u8 time_key;
+ u8 i2c_talk_onoff;
+ u8 i2c_gate;
+ u8 i2c_tuner_gate_w;
+ u8 i2c_tuner_gate_r;
+ u8 i2c_tuner_addr;
+ void *buffer;
+ struct urb *lme_urb;
+ void *usb_buffer;
+
+};
+
+static int lme2510_bulk_write(struct usb_device *dev,
+ u8 *snd, int len, u8 pipe)
+{
+ int ret, actual_l;
+ ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
+ snd, len , &actual_l, 500);
+ return ret;
+}
+
+static int lme2510_bulk_read(struct usb_device *dev,
+ u8 *rev, int len, u8 pipe)
+{
+ int ret, actual_l;
+
+ ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
+ rev, len , &actual_l, 500);
+ return ret;
+}
+
+static int lme2510_usb_talk(struct dvb_usb_device *d,
+ u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ struct lme2510_state *st = d->priv;
+ u8 *buff;
+ int ret = 0;
+
+ if (st->usb_buffer == NULL) {
+ st->usb_buffer = kmalloc(512, GFP_KERNEL);
+ if (st->usb_buffer == NULL) {
+ info("MEM Error no memory");
+ return -ENOMEM;
+ }
+ }
+ buff = st->usb_buffer;
+
+ /* the read/write capped at 512 */
+ memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
+
+
+ ret = mutex_lock_interruptible(&d->usb_mutex);
+
+ if (ret < 0)
+ return -EAGAIN;
+
+ ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
+ msleep(5);
+ ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x1);
+
+ msleep(5);
+ ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x1));
+
+ msleep(5);
+ ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ?
+ 512 : rlen , 0x1);
+
+ if (rlen > 0)
+ memcpy(rbuf, buff, rlen);
+
+ mutex_unlock(&d->usb_mutex);
+
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
+{
+ struct dvb_usb_device *d = adap->dev;
+
+ deb_info(1, "INT Key Keypress =%04x", keypress);
+
+ if (keypress > 0)
+ ir_keydown(d->rc_input_dev, keypress, 0);
+
+ return 0;
+}
+
+static void lme2510_int_response(struct urb *lme_urb)
+{
+ struct dvb_usb_adapter *adap = lme_urb->context;
+ struct lme2510_state *st = adap->dev->priv;
+ static u8 *ibuf, *rbuf;
+ int i = 0, offset;
+
+ switch (lme_urb->status) {
+ case 0:
+ case -ETIMEDOUT:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default:
+ info("Error %x", lme_urb->status);
+ break;
+ }
+
+ rbuf = (u8 *) lme_urb->transfer_buffer;
+
+ offset = ((lme_urb->actual_length/8) > 4)
+ ? 4 : (lme_urb->actual_length/8) ;
+
+
+ for (i = 0; i < offset; ++i) {
+ ibuf = (u8 *)&rbuf[i*8];
+ deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
+ offset, i, ibuf[0], ibuf[1]);
+
+ switch (ibuf[0]) {
+ case 0xaa:
+ debug_data_snipet(1, "INT Remote data snipet in", ibuf);
+ lme2510_remote_keypress(adap,
+ (u16)(ibuf[4]<<8)+ibuf[5]);
+ break;
+ case 0xbb:
+ switch (st->tuner_config) {
+ case TUNER_LG:
+ st->signal_lock = ibuf[2];
+ st->signal_level = ibuf[4];
+ st->signal_sn = ibuf[3];
+ st->time_key = ibuf[7];
+ break;
+ case TUNER_S7395:
+ /* Tweak for earlier firmware*/
+ if (ibuf[1] == 0x03) {
+ st->signal_level = ibuf[3];
+ st->signal_sn = ibuf[2];
+ } else {
+ st->signal_level = ibuf[4];
+ st->signal_sn = ibuf[5];
+ }
+ break;
+ default:
+ break;
+ }
+ debug_data_snipet(5, "INT Remote data snipet in", ibuf);
+ break;
+ case 0xcc:
+ debug_data_snipet(1, "INT Control data snipet", ibuf);
+ break;
+ default:
+ debug_data_snipet(1, "INT Unknown data snipet", ibuf);
+ break;
+ }
+ }
+ usb_submit_urb(lme_urb, GFP_ATOMIC);
+}
+
+static int lme2510_int_read(struct dvb_usb_adapter *adap)
+{
+ struct lme2510_state *lme_int = adap->dev->priv;
+
+ lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (lme_int->lme_urb == NULL)
+ return -ENOMEM;
+
+ lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 5000, GFP_ATOMIC,
+ &lme_int->lme_urb->transfer_dma);
+
+ if (lme_int->buffer == NULL)
+ return -ENOMEM;
+
+ usb_fill_int_urb(lme_int->lme_urb,
+ adap->dev->udev,
+ usb_rcvintpipe(adap->dev->udev, 0xa),
+ lme_int->buffer,
+ 4096,
+ lme2510_int_response,
+ adap,
+ 11);
+
+ lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
+ info("INT Interupt Service Started");
+
+ return 0;
+}
+
+static int lme2510_return_status(struct usb_device *dev)
+{
+ int ret = 0;
+ u8 data[10] = {0};
+ ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
+ info("Firmware Status: %x (%x)", ret , data[2]);
+
+ return (ret < 0) ? -ENODEV : data[2];
+}
+
+static int lme2510_msg(struct dvb_usb_device *d,
+ u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ int ret = 0;
+ struct lme2510_state *st = d->priv;
+
+ if (st->i2c_talk_onoff == 1) {
+ if ((wbuf[2] == 0x1c) & (wbuf[3] == 0x0e))
+ msleep(80); /*take your time when waiting for tune*/
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+
+ mutex_unlock(&d->i2c_mutex);
+ switch (st->tuner_config) {
+ case TUNER_S7395:
+ if (wbuf[3] == 0x24)
+ st->signal_lock = rbuf[1];
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (st->tuner_config) {
+ case TUNER_LG:
+ switch (wbuf[3]) {
+ case 0x0e:
+ rbuf[0] = 0x55;
+ rbuf[1] = st->signal_lock;
+ break;
+ case 0x43:
+ rbuf[0] = 0x55;
+ rbuf[1] = st->signal_level;
+ break;
+ case 0x1c:
+ rbuf[0] = 0x55;
+ rbuf[1] = st->signal_sn;
+ break;
+ default:
+ break;
+ }
+ break;
+ case TUNER_S7395:
+ switch (wbuf[3]) {
+ case 0x10:
+ rbuf[0] = 0x55;
+ rbuf[1] = (st->signal_level & 0x80)
+ ? 0 : (st->signal_level * 2);
+ break;
+ case 0x2d:
+ rbuf[0] = 0x55;
+ rbuf[1] = st->signal_sn;
+ break;
+ case 0x24:
+ rbuf[0] = 0x55;
+ rbuf[1] = (st->signal_level & 0x80)
+ ? 0 : st->signal_lock;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+
+ }
+
+ deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
+ wbuf[3], rbuf[1]);
+
+ }
+
+ return ret;
+}
+
+
+static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ struct lme2510_state *st = d->priv;
+ static u8 obuf[64], ibuf[512];
+ int i, read, read_o;
+ u16 len;
+ u8 gate = st->i2c_gate;
+
+ if (gate == 0)
+ gate = 5;
+
+ if (num > 2)
+ warn("more than 2 i2c messages"
+ "at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+ read_o = 1 & (msg[i].flags & I2C_M_RD);
+ read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+ read |= read_o;
+ gate = (msg[i].addr == st->i2c_tuner_addr)
+ ? (read) ? st->i2c_tuner_gate_r
+ : st->i2c_tuner_gate_w
+ : st->i2c_gate;
+ obuf[0] = gate | (read << 7);
+
+ if (gate == 5)
+ obuf[1] = (read) ? 2 : msg[i].len + 1;
+ else
+ obuf[1] = msg[i].len + read + 1;
+
+ obuf[2] = msg[i].addr;
+ if (read) {
+ if (read_o)
+ len = 3;
+ else {
+ memcpy(&obuf[3], msg[i].buf, msg[i].len);
+ obuf[msg[i].len+3] = msg[i+1].len;
+ len = msg[i].len+4;
+ }
+ } else {
+ memcpy(&obuf[3], msg[i].buf, msg[i].len);
+ len = msg[i].len+3;
+ }
+
+ if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) {
+ deb_info(1, "i2c transfer failed.");
+ return -EAGAIN;
+ }
+
+ if (read) {
+ if (read_o)
+ memcpy(msg[i].buf, &ibuf[1], msg[i].len);
+ else {
+ memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
+ i++;
+ }
+ }
+ }
+ return i;
+}
+
+static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm lme2510_i2c_algo = {
+ .master_xfer = lme2510_i2c_xfer,
+ .functionality = lme2510_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int lme2510_identify_state(struct usb_device *udev,
+ struct dvb_usb_device_properties *props,
+ struct dvb_usb_device_description **desc,
+ int *cold)
+{
+ if (lme2510_return_status(udev) == 0x44)
+ *cold = 1;
+ else
+ *cold = 0;
+ return 0;
+}
+
+static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ struct lme2510_state *st = adap->dev->priv;
+ static u8 reset[] = LME_RESET;
+ static u8 stream_on[] = LME_ST_ON_W;
+ static u8 clear_reg_3[] = LME_CLEAR_PID;
+ static u8 rbuf[1];
+ int ret = 0, len = 2, rlen = sizeof(rbuf);
+
+ deb_info(1, "STM (%02x)", onoff);
+
+ if (onoff == 1) {
+ st->i2c_talk_onoff = 0;
+ msleep(400); /* give enough time for i2c to stop */
+ ret |= lme2510_usb_talk(adap->dev,
+ stream_on, len, rbuf, rlen);
+ } else {
+ deb_info(1, "STM Steam Off");
+ if (st->tuner_config == TUNER_LG)
+ ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
+ sizeof(clear_reg_3), rbuf, rlen);
+ else
+ ret |= lme2510_usb_talk(adap->dev,
+ reset, sizeof(reset), rbuf, rlen);
+
+ msleep(400);
+ st->i2c_talk_onoff = 1;
+ }
+
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static int lme2510_int_service(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap->dev;
+ struct input_dev *input_dev;
+ char *ir_codes = RC_MAP_LME2510;
+ int ret = 0;
+
+ info("STA Configuring Remote");
+
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "LME2510 Remote Control";
+ input_dev->phys = d->rc_phys;
+
+ usb_to_input_id(d->udev, &input_dev->id);
+
+ ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
+
+ if (ret) {
+ input_free_device(input_dev);
+ return ret;
+ }
+
+ d->rc_input_dev = input_dev;
+ /* Start the Interupt */
+ ret = lme2510_int_read(adap);
+
+ if (ret < 0) {
+ ir_input_unregister(input_dev);
+ input_free_device(input_dev);
+ }
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static u8 check_sum(u8 *p, u8 len)
+{
+ u8 sum = 0;
+ while (len--)
+ sum += *p++;
+ return sum;
+}
+
+static int lme2510_download_firmware(struct usb_device *dev,
+ const struct firmware *fw)
+{
+ int ret = 0;
+ u8 data[512] = {0};
+ u16 j, wlen, len_in, start, end;
+ u8 packet_size, dlen, i;
+ u8 *fw_data;
+
+ packet_size = 0x31;
+ len_in = 1;
+
+
+ info("FRM Starting Firmware Download");
+
+ for (i = 1; i < 3; i++) {
+ start = (i == 1) ? 0 : 512;
+ end = (i == 1) ? 512 : fw->size;
+ for (j = start; j < end; j += (packet_size+1)) {
+ fw_data = (u8 *)(fw->data + j);
+ if ((end - j) > packet_size) {
+ data[0] = i;
+ dlen = packet_size;
+ } else {
+ data[0] = i | 0x80;
+ dlen = (u8)(end - j)-1;
+ }
+ data[1] = dlen;
+ memcpy(&data[2], fw_data, dlen+1);
+ wlen = (u8) dlen + 4;
+ data[wlen-1] = check_sum(fw_data, dlen+1);
+ deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
+ data[dlen+2], data[dlen+3]);
+ ret |= lme2510_bulk_write(dev, data, wlen, 1);
+ ret |= lme2510_bulk_read(dev, data, len_in , 1);
+ ret |= (data[0] == 0x88) ? 0 : -1;
+ }
+ }
+ usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ 0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
+
+
+ data[0] = 0x8a;
+ len_in = 1;
+ msleep(2000);
+ ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Resetting*/
+ ret |= lme2510_bulk_read(dev, data, len_in, 1);
+ msleep(400);
+
+ if (ret < 0)
+ info("FRM Firmware Download Failed (%04x)" , ret);
+ else
+ info("FRM Firmware Download Completed - Resetting Device");
+
+
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+
+static int lme2510_kill_urb(struct usb_data_stream *stream)
+{
+ int i;
+ for (i = 0; i < stream->urbs_submitted; i++) {
+ deb_info(3, "killing URB no. %d.", i);
+
+ /* stop the URB */
+ usb_kill_urb(stream->urb_list[i]);
+ }
+ stream->urbs_submitted = 0;
+ return 0;
+}
+
+static struct tda10086_config tda10086_config = {
+ .demod_address = 0x1c,
+ .invert = 0,
+ .diseqc_tone = 1,
+ .xtal_freq = TDA10086_XTAL_16M,
+};
+
+static struct stv0288_config lme_config = {
+ .demod_address = 0xd0,
+ .min_delay_ms = 15,
+ .inittab = s7395_inittab,
+};
+
+static struct ix2505v_config lme_tuner = {
+ .tuner_address = 0xc0,
+ .min_delay_ms = 100,
+ .tuner_gain = 0x0,
+ .tuner_chargepump = 0x3,
+};
+
+
+static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct lme2510_state *st = adap->dev->priv;
+ static u8 voltage_low[] = LME_VOLTAGE_L;
+ static u8 voltage_high[] = LME_VOLTAGE_H;
+ static u8 reset[] = LME_RESET;
+ static u8 clear_reg_3[] = LME_CLEAR_PID;
+ static u8 rbuf[1];
+ int ret = 0, len = 3, rlen = 1;
+
+ msleep(100);
+
+ if (st->tuner_config == TUNER_LG)
+ ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
+ sizeof(clear_reg_3), rbuf, rlen);
+ else
+ ret |= lme2510_usb_talk(adap->dev,
+ reset, sizeof(reset), rbuf, rlen);
+
+ /*always check & stop streaming*/
+ lme2510_kill_urb(&adap->stream);
+ adap->feedcount = 0;
+
+ switch (voltage) {
+
+ case SEC_VOLTAGE_18:
+ ret |= lme2510_usb_talk(adap->dev,
+ voltage_high, len, rbuf, rlen);
+ break;
+
+ case SEC_VOLTAGE_OFF:
+ case SEC_VOLTAGE_13:
+ default:
+ ret |= lme2510_usb_talk(adap->dev,
+ voltage_low, len, rbuf, rlen);
+ break;
+
+
+ };
+ st->i2c_talk_onoff = 1;
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ int ret = 0;
+ struct lme2510_state *st = adap->dev->priv;
+
+ /* Interupt Start */
+ ret = lme2510_int_service(adap);
+ if (ret < 0) {
+ info("INT Unable to start Interupt Service");
+ return -ENODEV;
+ }
+
+ st->i2c_talk_onoff = 1;
+ st->i2c_gate = 4;
+
+ adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
+ &adap->dev->i2c_adap);
+
+ if (adap->fe) {
+ info("TUN Found Frontend TDA10086");
+ memcpy(&adap->fe->ops.info.name,
+ &"DM04_LG_TDQY-P001F DVB-S", 24);
+ adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
+ st->i2c_tuner_gate_w = 4;
+ st->i2c_tuner_gate_r = 4;
+ st->i2c_tuner_addr = 0xc0;
+ if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
+ &adap->dev->i2c_adap, 1)) {
+ info("TUN TDA8263 Found");
+ st->tuner_config = TUNER_LG;
+ return 0;
+ }
+ kfree(adap->fe);
+ adap->fe = NULL;
+ }
+ st->i2c_gate = 5;
+ adap->fe = dvb_attach(stv0288_attach, &lme_config,
+ &adap->dev->i2c_adap);
+
+ if (adap->fe) {
+ info("FE Found Stv0288");
+ memcpy(&adap->fe->ops.info.name,
+ &"DM04_SHARP:BS2F7HZ7395", 22);
+ adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
+ st->i2c_tuner_gate_w = 4;
+ st->i2c_tuner_gate_r = 5;
+ st->i2c_tuner_addr = 0xc0;
+ if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
+ &adap->dev->i2c_adap)) {
+ st->tuner_config = TUNER_S7395;
+ info("TUN Sharp IX2505V silicon tuner");
+ return 0;
+ }
+ kfree(adap->fe);
+ adap->fe = NULL;
+ }
+
+ info("DM04 Not Supported");
+ return -ENODEV;
+}
+
+static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
+{
+ struct lme2510_state *st = d->priv;
+ st->i2c_talk_onoff = 1;
+ return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties lme2510_properties;
+static struct dvb_usb_device_properties lme2510c_properties;
+
+static int lme2510_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int ret = 0;
+
+ usb_reset_configuration(udev);
+
+ usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
+
+ if (udev->speed != USB_SPEED_HIGH) {
+ ret = usb_reset_device(udev);
+ info("DEV Failed to connect in HIGH SPEED mode");
+ return -ENODEV;
+ }
+
+ if (0 == dvb_usb_device_init(intf, &lme2510_properties,
+ THIS_MODULE, NULL, adapter_nr)) {
+ info("DEV registering device driver");
+ return 0;
+ }
+ if (0 == dvb_usb_device_init(intf, &lme2510c_properties,
+ THIS_MODULE, NULL, adapter_nr)) {
+ info("DEV registering device driver");
+ return 0;
+ }
+
+ info("DEV lme2510 Error");
+ return -ENODEV;
+
+}
+
+static struct usb_device_id lme2510_table[] = {
+ { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
+ { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, lme2510_table);
+
+static struct dvb_usb_device_properties lme2510_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .download_firmware = lme2510_download_firmware,
+ .firmware = "dvb-usb-lme2510-lg.fw",
+
+ .size_of_priv = sizeof(struct lme2510_state),
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .streaming_ctrl = lme2510_streaming_ctrl,
+ .frontend_attach = dm04_lme2510_frontend_attach,
+ /* parameter for the MPEG2-data transfer */
+ .stream = {
+ .type = USB_BULK,
+ .count = 10,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+
+ }
+ }
+ }
+ }
+ },
+ .power_ctrl = lme2510_powerup,
+ .identify_state = lme2510_identify_state,
+ .i2c_algo = &lme2510_i2c_algo,
+ .generic_bulk_ctrl_endpoint = 0,
+ .num_device_descs = 1,
+ .devices = {
+ { "DM04 LME2510 DVB-S USB 2.0",
+ { &lme2510_table[0], NULL },
+ },
+
+ }
+};
+
+static struct dvb_usb_device_properties lme2510c_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .download_firmware = lme2510_download_firmware,
+ .firmware = "dvb-usb-lme2510c-s7395.fw",
+ .size_of_priv = sizeof(struct lme2510_state),
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .streaming_ctrl = lme2510_streaming_ctrl,
+ .frontend_attach = dm04_lme2510_frontend_attach,
+ /* parameter for the MPEG2-data transfer */
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x8,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+
+ }
+ }
+ }
+ }
+ },
+ .power_ctrl = lme2510_powerup,
+ .identify_state = lme2510_identify_state,
+ .i2c_algo = &lme2510_i2c_algo,
+ .generic_bulk_ctrl_endpoint = 0,
+ .num_device_descs = 1,
+ .devices = {
+ { "DM04 LME2510C USB2.0",
+ { &lme2510_table[1], NULL },
+ },
+ }
+};
+
+void lme2510_exit_int(struct dvb_usb_device *d)
+{
+ struct lme2510_state *st = d->priv;
+ if (st->lme_urb != NULL) {
+ st->i2c_talk_onoff = 0;
+ st->signal_lock = 0;
+ st->signal_level = 0;
+ st->signal_sn = 0;
+ kfree(st->usb_buffer);
+ usb_kill_urb(st->lme_urb);
+ usb_free_coherent(d->udev, 5000, st->buffer,
+ st->lme_urb->transfer_dma);
+ info("Interupt Service Stopped");
+ ir_input_unregister(d->rc_input_dev);
+ info("Remote Stopped");
+ }
+ return;
+}
+
+void lme2510_exit(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ if (d != NULL) {
+ d->adapter[0].feedcount = 0;
+ lme2510_exit_int(d);
+ dvb_usb_device_exit(intf);
+ }
+
+}
+
+static struct usb_driver lme2510_driver = {
+ .name = "LME2510C_DVBS",
+ .probe = lme2510_probe,
+ .disconnect = lme2510_exit,
+ .id_table = lme2510_table,
+};
+
+/* module stuff */
+static int __init lme2510_module_init(void)
+{
+ int result = usb_register(&lme2510_driver);
+ if (result) {
+ err("usb_register failed. Error number %d", result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit lme2510_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&lme2510_driver);
+}
+
+module_init(lme2510_module_init);
+module_exit(lme2510_module_exit);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
+MODULE_VERSION("1.4");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
new file mode 100644
index 000000000000..5a66c7ec4511
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.h
@@ -0,0 +1,187 @@
+/* DVB USB compliant linux driver for
+ *
+ * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
+ * LME2510C + LGTDQT-P001F
+ *
+ * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
+ * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
+ *
+ * MVB0001F (LME2510C+LGTDQT-P001F)
+ * LG TDQY - P001F =(TDA8263 + TDA10086H)
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ * *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_LME2510_H_
+#define _DVB_USB_LME2510_H_
+
+/* Streamer & PID
+ *
+ * Note: These commands do not actually stop the streaming
+ * but form some kind of packet filtering/stream count
+ * or tuning related functions.
+ * 06 XX
+ * offset 1 = 00 Enable Streaming
+ *
+ *
+ * PID
+ * 03 XX XX ----> reg number ---> setting....20 XX
+ * offset 1 = length
+ * offset 2 = start of data
+ * end byte -1 = 20
+ * end byte = clear pid always a0, other wise 9c, 9a ??
+ *
+ * RESET (also clears PID filter)
+ * 3a 01 00
+*/
+#define LME_ST_ON_W {0x06, 0x00}
+#define LME_RESET {0x3a, 0x01, 0x00}
+#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
+
+
+/* LME Power Control
+ * 07 XX XX
+ * offset 1 = 01 Power? my device cannot be powered down
+ * offset 2 = 00=Voltage low 01=Voltage high
+ */
+
+#define LME_VOLTAGE_L {0x07, 0x01, 0x00}
+#define LME_VOLTAGE_H {0x07, 0x01, 0x01}
+
+
+/* Initial stv0288 settings for 7395 Frontend */
+static u8 s7395_inittab[] = {
+ 0x00, 0x11,
+ 0x01, 0x15,
+ 0x02, 0x20,
+ 0x03, 0x8e,
+ 0x04, 0x8e,
+ 0x05, 0x12,
+ 0x06, 0xff,
+ 0x07, 0x20,
+ 0x08, 0x00,
+ 0x09, 0x00,
+ 0x0a, 0x04,
+ 0x0b, 0x00,
+ 0x0c, 0x00,
+ 0x0d, 0x00,
+ 0x0e, 0xc1,
+ 0x0f, 0x54,
+ 0x10, 0x40,
+ 0x11, 0x7a,
+ 0x12, 0x03,
+ 0x13, 0x48,
+ 0x14, 0x84,
+ 0x15, 0xc5,
+ 0x16, 0xb8,
+ 0x17, 0x9c,
+ 0x18, 0x00,
+ 0x19, 0xa6,
+ 0x1a, 0x88,
+ 0x1b, 0x8f,
+ 0x1c, 0xf0,
+ 0x1e, 0x80,
+ 0x20, 0x0b,
+ 0x21, 0x54,
+ 0x22, 0xff,
+ 0x23, 0x01,
+ 0x24, 0x9a,
+ 0x25, 0x7f,
+ 0x26, 0x00,
+ 0x27, 0x00,
+ 0x28, 0x46,
+ 0x29, 0x66,
+ 0x2a, 0x90,
+ 0x2b, 0xfa,
+ 0x2c, 0xd9,
+ 0x2d, 0x02,
+ 0x2e, 0xb1,
+ 0x2f, 0x00,
+ 0x30, 0x0,
+ 0x31, 0x1e,
+ 0x32, 0x14,
+ 0x33, 0x0f,
+ 0x34, 0x09,
+ 0x35, 0x0c,
+ 0x36, 0x05,
+ 0x37, 0x2f,
+ 0x38, 0x16,
+ 0x39, 0xbd,
+ 0x3a, 0x0,
+ 0x3b, 0x13,
+ 0x3c, 0x11,
+ 0x3d, 0x30,
+ 0x3e, 0x00,
+ 0x3f, 0x00,
+ 0x40, 0x63,
+ 0x41, 0x04,
+ 0x42, 0x60,
+ 0x43, 0x00,
+ 0x44, 0x00,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x47, 0x00,
+ 0x4a, 0x00,
+ 0x4b, 0xd1,
+ 0x4c, 0x33,
+ 0x50, 0x12,
+ 0x51, 0x36,
+ 0x52, 0x21,
+ 0x53, 0x94,
+ 0x54, 0xb2,
+ 0x55, 0x29,
+ 0x56, 0x64,
+ 0x57, 0x2b,
+ 0x58, 0x54,
+ 0x59, 0x86,
+ 0x5a, 0x00,
+ 0x5b, 0x9b,
+ 0x5c, 0x08,
+ 0x5d, 0x7f,
+ 0x5e, 0xff,
+ 0x5f, 0x8d,
+ 0x70, 0x0,
+ 0x71, 0x0,
+ 0x72, 0x0,
+ 0x74, 0x0,
+ 0x75, 0x0,
+ 0x76, 0x0,
+ 0x81, 0x0,
+ 0x82, 0x3f,
+ 0x83, 0x3f,
+ 0x84, 0x0,
+ 0x85, 0x0,
+ 0x88, 0x0,
+ 0x89, 0x0,
+ 0x8a, 0x0,
+ 0x8b, 0x0,
+ 0x8c, 0x0,
+ 0x90, 0x0,
+ 0x91, 0x0,
+ 0x92, 0x0,
+ 0x93, 0x0,
+ 0x94, 0x1c,
+ 0x97, 0x0,
+ 0xa0, 0x48,
+ 0xa1, 0x0,
+ 0xb0, 0xb8,
+ 0xb1, 0x3a,
+ 0xb2, 0x10,
+ 0xb3, 0x82,
+ 0xb4, 0x80,
+ 0xb5, 0x82,
+ 0xb6, 0x82,
+ 0xb7, 0x82,
+ 0xb8, 0x20,
+ 0xb9, 0x0,
+ 0xf0, 0x0,
+ 0xf1, 0x0,
+ 0xf2, 0xc0,
+ 0xff, 0xff,
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 6b22ec64ab0c..f896337b4535 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev,
}
}
kfree(p);
- if (fw) {
- release_firmware(fw);
- }
+ release_firmware(fw);
return ret;
}
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
index d3c2cf60de76..02e487be43f8 100644
--- a/drivers/media/dvb/firewire/firedtv-ci.c
+++ b/drivers/media/dvb/firewire/firedtv-ci.c
@@ -220,6 +220,7 @@ static const struct file_operations fdtv_ca_fops = {
.open = dvb_generic_open,
.release = dvb_generic_release,
.poll = fdtv_ca_io_poll,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct dvb_device fdtv_ca = {
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b5f6a04f9c12..d83632c06872 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -607,6 +607,13 @@ config DVB_TDA665x
Currently supported tuners:
* Panasonic ENV57H12D5 (ET-50DT)
+config DVB_IX2505V
+ tristate "Sharp IX2505V silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
comment "Tools to develop new frontends"
config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 874e8ada4d1d..9b59e411d5b4 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -82,3 +82,4 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o
obj-$(CONFIG_DVB_EC100) += ec100.o
obj-$(CONFIG_DVB_DS3000) += ds3000.o
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index dac917f7bb7f..a780c32ebce4 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -486,6 +486,19 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
if_sample_freq = 4300000; /* 4.3 MHz */
break;
}
+ } else if (state->config.tuner == AF9013_TUNER_TDA18218) {
+ switch (bw) {
+ case BANDWIDTH_6_MHZ:
+ if_sample_freq = 3000000; /* 3 MHz */
+ break;
+ case BANDWIDTH_7_MHZ:
+ if_sample_freq = 3500000; /* 3.5 MHz */
+ break;
+ case BANDWIDTH_8_MHZ:
+ default:
+ if_sample_freq = 4000000; /* 4 MHz */
+ break;
+ }
}
while (if_sample_freq > (adc_freq / 2))
@@ -1393,6 +1406,7 @@ static int af9013_init(struct dvb_frontend *fe)
init = tuner_init_mt2060_2;
break;
case AF9013_TUNER_TDA18271:
+ case AF9013_TUNER_TDA18218:
len = ARRAY_SIZE(tuner_init_tda18271);
init = tuner_init_tda18271;
break;
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h
index 0fd42b7e248e..0dcca60f0668 100644
--- a/drivers/media/dvb/frontends/af9013_priv.h
+++ b/drivers/media/dvb/frontends/af9013_priv.h
@@ -791,8 +791,9 @@ static struct regdesc tuner_init_unknown[] = {
{ 0x9bd9, 0, 8, 0x08 },
};
-/* NXP TDA18271 tuner init
- AF9013_TUNER_TDA18271 = 156 */
+/* NXP TDA18271 & TDA18218 tuner init
+ AF9013_TUNER_TDA18271 = 156
+ AF9013_TUNER_TDA18218 = 179 */
static struct regdesc tuner_init_tda18271[] = {
{ 0x9bd5, 0, 8, 0x01 },
{ 0x9bd6, 0, 8, 0x04 },
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 00a4e8f03304..7a1a5bc337d8 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -310,7 +310,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
}
-static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len)
+static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len)
{
struct cx24110_state *state = fe->demodulator_priv;
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 2e28b973dfd3..3aed0d433921 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
+ reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
+ reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
+
dib7000p_write_word(state, 908, reg_908);
dib7000p_write_word(state, 909, reg_909);
}
@@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
default:
case GUARD_INTERVAL_1_32: value *= 1; break;
}
- state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
+ if (state->cfg.diversity_delay == 0)
+ state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
+ else
+ state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo
/* deactive the possibility of diversity reception if extended interleaver */
state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 805dd13a97ee..da17345bf5bd 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -33,6 +33,11 @@ struct dib7000p_config {
int (*agc_control) (struct dvb_frontend *, u8 before);
u8 output_mode;
+ u8 disable_sample_and_hold : 1;
+
+ u8 enable_current_mirror : 1;
+ u8 diversity_delay;
+
};
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index f74cca6dc26b..a05007c80985 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -232,7 +232,7 @@ static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
exit_rc:
read_unlock(&fw[s->chip_rev].lock);
- return 0;
+ return rc;
}
/* Function is not endian safe, use the RD16 wrapper below */
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
new file mode 100644
index 000000000000..55f2eba7bc96
--- /dev/null
+++ b/drivers/media/dvb/frontends/ix2505v.c
@@ -0,0 +1,323 @@
+/**
+ * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
+ *
+ * Copyright (C) 2010 Malcolm Priestley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "ix2505v.h"
+
+static int ix2505v_debug;
+#define dprintk(level, args...) do { \
+ if (ix2505v_debug & level) \
+ printk(KERN_DEBUG "ix2505v: " args); \
+} while (0)
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_i2c(args...) dprintk(0x02, args)
+
+struct ix2505v_state {
+ struct i2c_adapter *i2c;
+ const struct ix2505v_config *config;
+ u32 frequency;
+};
+
+/**
+ * Data read format of the Sharp IX2505V B0017
+ *
+ * byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1
+ * byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X
+ *
+ * byte1 = address
+ * byte2;
+ * POR = Power on Reset (VCC H=<2.2v L=>2.2v)
+ * FL = Phase Lock (H=lock L=unlock)
+ * RD0-2 = Reserved internal operations
+ *
+ * Only POR can be used to check the tuner is present
+ *
+ * Caution: after byte2 the I2C reverts to write mode continuing to read
+ * may corrupt tuning data.
+ *
+ */
+
+static int ix2505v_read_status_reg(struct ix2505v_state *state)
+{
+ u8 addr = state->config->tuner_address;
+ u8 b2[] = {0};
+ int ret;
+
+ struct i2c_msg msg[1] = {
+ { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+ deb_i2c("Read %s ", __func__);
+
+ return (ret = 1) ? (int) b2[0] : -1;
+}
+
+static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
+{
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = 0,
+ .buf = buf, .len = count },
+ };
+
+ int ret;
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+
+ if (ret != 1) {
+ deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ix2505v_release(struct dvb_frontend *fe)
+{
+ struct ix2505v_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+
+ return 0;
+}
+
+/**
+ * Data write format of the Sharp IX2505V B0017
+ *
+ * byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0
+ * byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4
+ * byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1
+ * byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF)
+ * byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0
+ *
+ * byte1 = address
+ *
+ * Write order
+ * 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
+ * 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
+ * 3) byte1 -> byte2 -> byte3 -> byte4
+ * 4) byte1 -> byte4 -> byte5 -> byte2
+ * 5) byte1 -> byte2 -> byte3
+ * 6) byte1 -> byte4 -> byte5
+ * 7) byte1 -> byte2
+ * 8) byte1 -> byte4
+ *
+ * Recommended Setup
+ * 1 -> 8 -> 6
+ */
+
+static int ix2505v_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct ix2505v_state *state = fe->tuner_priv;
+ u32 frequency = params->frequency;
+ u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
+ u32 div_factor, N , A, x;
+ int ret = 0, len;
+ u8 gain, cc, ref, psc, local_osc, lpf;
+ u8 data[4] = {0};
+
+ if ((frequency < fe->ops.info.frequency_min)
+ || (frequency > fe->ops.info.frequency_max))
+ return -EINVAL;
+
+ if (state->config->tuner_gain)
+ gain = (state->config->tuner_gain < 4)
+ ? state->config->tuner_gain : 0;
+ else
+ gain = 0x0;
+
+ if (state->config->tuner_chargepump)
+ cc = state->config->tuner_chargepump;
+ else
+ cc = 0x3;
+
+ ref = 8; /* REF =1 */
+ psc = 32; /* PSC = 0 */
+
+ div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
+ x = div_factor / psc;
+ N = x/100;
+ A = ((x - (N * 100)) * psc) / 100;
+
+ data[0] = ((gain & 0x3) << 5) | (N >> 3);
+ data[1] = (N << 5) | (A & 0x1f);
+ data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
+
+ deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
+
+ if (frequency <= 1065000)
+ local_osc = (6 << 5) | 2;
+ else if (frequency <= 1170000)
+ local_osc = (7 << 5) | 2;
+ else if (frequency <= 1300000)
+ local_osc = (1 << 5);
+ else if (frequency <= 1445000)
+ local_osc = (2 << 5);
+ else if (frequency <= 1607000)
+ local_osc = (3 << 5);
+ else if (frequency <= 1778000)
+ local_osc = (4 << 5);
+ else if (frequency <= 1942000)
+ local_osc = (5 << 5);
+ else /*frequency up to 2150000*/
+ local_osc = (6 << 5);
+
+ data[3] = local_osc; /* all other bits set 0 */
+
+ if (b_w <= 10000)
+ lpf = 0xc;
+ else if (b_w <= 12000)
+ lpf = 0x2;
+ else if (b_w <= 14000)
+ lpf = 0xa;
+ else if (b_w <= 16000)
+ lpf = 0x6;
+ else if (b_w <= 18000)
+ lpf = 0xe;
+ else if (b_w <= 20000)
+ lpf = 0x1;
+ else if (b_w <= 22000)
+ lpf = 0x9;
+ else if (b_w <= 24000)
+ lpf = 0x5;
+ else if (b_w <= 26000)
+ lpf = 0xd;
+ else if (b_w <= 28000)
+ lpf = 0x3;
+ else
+ lpf = 0xb;
+
+ deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
+ deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ len = sizeof(data);
+
+ ret |= ix2505v_write(state, data, len);
+
+ data[2] |= 0x4; /* set TM = 1 other bits same */
+
+ len = 1;
+ ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
+
+ msleep(10);
+
+ data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
+ data[3] |= (lpf & 0x3) << 2;
+
+ deb_info("Data 2=[%x%x]\n", data[2], data[3]);
+
+ len = 2;
+ ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (state->config->min_delay_ms)
+ msleep(state->config->min_delay_ms);
+
+ state->frequency = frequency;
+
+ return ret;
+}
+
+static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct ix2505v_state *state = fe->tuner_priv;
+
+ *frequency = state->frequency;
+
+ return 0;
+}
+
+static struct dvb_tuner_ops ix2505v_tuner_ops = {
+ .info = {
+ .name = "Sharp IX2505V (B0017)",
+ .frequency_min = 950000,
+ .frequency_max = 2175000
+ },
+ .release = ix2505v_release,
+ .set_params = ix2505v_set_params,
+ .get_frequency = ix2505v_get_frequency,
+};
+
+struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+ const struct ix2505v_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct ix2505v_state *state = NULL;
+ int ret;
+
+ if (NULL == config) {
+ deb_i2c("%s: no config ", __func__);
+ goto error;
+ }
+
+ state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL);
+ if (NULL == state)
+ return NULL;
+
+ state->config = config;
+ state->i2c = i2c;
+
+ if (state->config->tuner_write_only) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = ix2505v_read_status_reg(state);
+
+ if (ret & 0x80) {
+ deb_i2c("%s: No IX2505V found\n", __func__);
+ goto error;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ fe->tuner_priv = state;
+
+ memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
+ __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+ return fe;
+
+error:
+ ix2505v_release(fe);
+ return NULL;
+}
+EXPORT_SYMBOL(ix2505v_attach);
+
+module_param_named(debug, ix2505v_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB IX2505V tuner driver");
+MODULE_AUTHOR("Malcolm Priestley");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb/frontends/ix2505v.h
new file mode 100644
index 000000000000..67e89d616d50
--- /dev/null
+++ b/drivers/media/dvb/frontends/ix2505v.h
@@ -0,0 +1,64 @@
+/**
+ * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
+ *
+ * Copyright (C) 2010 Malcolm Priestley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_IX2505V_H
+#define DVB_IX2505V_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a ix2505v tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config ix2505v_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct ix2505v_config {
+ u8 tuner_address;
+
+ /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
+ u8 tuner_gain;
+
+ /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
+ u8 tuner_chargepump;
+
+ /* delay after tune */
+ int min_delay_ms;
+
+ /* disables reads*/
+ u8 tuner_write_only;
+
+};
+
+#if defined(CONFIG_DVB_IX2505V) || \
+ (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
+extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+ const struct ix2505v_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
+ const struct ix2505v_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* DVB_IX2505V_H */
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index 5ea28ae2ba8f..0fcddc4569d2 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -662,7 +662,7 @@ static void lgs8gxx_release(struct dvb_frontend *fe)
}
-static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len)
+static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
struct lgs8gxx_state *priv = fe->demodulator_priv;
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index beba5aa0db50..319672f8e1a7 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -69,7 +69,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
return 0;
}
-static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
+static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
{
int err,i;
for (i=0; i < ilen-1; i++)
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index 595092f9f0c4..ca2562d6f289 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -63,7 +63,7 @@ static inline struct dvb_frontend* mt352_attach(const struct mt352_config* confi
}
#endif // CONFIG_DVB_MT352
-static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) {
+static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) {
int r = 0;
if (fe->ops.write)
r = fe->ops.write(fe, buf, len);
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
index d21a327db629..4b0c99a08a85 100644
--- a/drivers/media/dvb/frontends/si21xx.c
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -268,7 +268,7 @@ static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0;
}
-static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
+static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
struct si21xx_state *state = fe->demodulator_priv;
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index f73c13323e90..80a9e4cba631 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -506,7 +506,7 @@ static struct dvb_tuner_ops stb6100_ops = {
};
struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
- struct stb6100_config *config,
+ const struct stb6100_config *config,
struct i2c_adapter *i2c)
{
struct stb6100_state *state = NULL;
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h
index 395d056599a6..2ab096614b3f 100644
--- a/drivers/media/dvb/frontends/stb6100.h
+++ b/drivers/media/dvb/frontends/stb6100.h
@@ -97,13 +97,13 @@ struct stb6100_state {
#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
- struct stb6100_config *config,
+ const struct stb6100_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
- struct stb6100_config *config,
+ const struct stb6100_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
index 2930a5d6768a..89e8db6ed841 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -78,7 +78,7 @@ static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0;
}
-static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
+static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
struct stv0288_state *state = fe->demodulator_priv;
@@ -486,7 +486,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe,
tda[2] = 0x0; /* CFRL */
for (tm = -6; tm < 7;) {
/* Viterbi status */
- if (stv0288_readreg(state, 0x24) & 0x80)
+ if (stv0288_readreg(state, 0x24) & 0x8)
break;
tda[2] += 40;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 968874469726..4e3db3a42e06 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0;
}
-static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len)
+static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
{
struct stv0299_state* state = fe->demodulator_priv;
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 0fd96e22b650..ba219b767a69 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -65,7 +65,7 @@ struct stv0299_config
* First of each pair is the register, second is the value.
* List should be terminated with an 0xff, 0xff pair.
*/
- u8* inittab;
+ const u8* inittab;
/* master clock to use */
u32 mclk;
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index f2a8abe0a243..ea485d923550 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -598,7 +598,7 @@ static int tda1004x_decode_fec(int tdafec)
return -1;
}
-static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len)
+static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len)
{
struct tda1004x_state* state = fe->demodulator_priv;
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 8c612719adfc..adbbf6d3d044 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -64,7 +64,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
return 0;
}
-static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen)
+static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen)
{
int err, i;
for (i = 0; i < ilen - 1; i++)
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index d93468cd3a85..135e45bd00c7 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
*
* @return pointer to descriptor on success, NULL on error.
*/
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+
+struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
{
struct smscore_buffer_t *cb = NULL;
unsigned long flags;
- DEFINE_WAIT(wait);
-
spin_lock_irqsave(&coredev->bufferslock, flags);
-
- /* This function must return a valid buffer, since the buffer list is
- * finite, we check that there is an available buffer, if not, we wait
- * until such buffer become available.
- */
-
- prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
- if (list_empty(&coredev->buffers)) {
- spin_unlock_irqrestore(&coredev->bufferslock, flags);
- schedule();
- spin_lock_irqsave(&coredev->bufferslock, flags);
+ if (!list_empty(&coredev->buffers)) {
+ cb = (struct smscore_buffer_t *) coredev->buffers.next;
+ list_del(&cb->entry);
}
+ spin_unlock_irqrestore(&coredev->bufferslock, flags);
+ return cb;
+}
- finish_wait(&coredev->buffer_mng_waitq, &wait);
-
- cb = (struct smscore_buffer_t *) coredev->buffers.next;
- list_del(&cb->entry);
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+{
+ struct smscore_buffer_t *cb = NULL;
- spin_unlock_irqrestore(&coredev->bufferslock, flags);
+ wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
return cb;
}
@@ -1511,8 +1504,7 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
u32 msgData[3]; /* keep it 3 ! */
} *pMsg;
- if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
- (PinNum > MAX_GPIO_PIN_NUMBER))
+ if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
return -EINVAL;
totalLen = sizeof(struct SmsMsgHdr_ST) +
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index a6be529eec5c..98b2b5896bcd 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -730,6 +730,7 @@ static const struct file_operations dvb_osd_fops = {
.unlocked_ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
.release = dvb_generic_release,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct dvb_device dvbdev_osd = {
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 13efba942dac..e45904da79bb 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1521,6 +1521,7 @@ static const struct file_operations dvb_video_fops = {
.open = dvb_video_open,
.release = dvb_video_release,
.poll = dvb_video_poll,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static struct dvb_device dvbdev_video = {
@@ -1539,6 +1540,7 @@ static const struct file_operations dvb_audio_fops = {
.open = dvb_audio_open,
.release = dvb_audio_release,
.poll = dvb_audio_poll,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static struct dvb_device dvbdev_audio = {
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 4eba35a018e3..2612c60e3b4f 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -353,6 +353,7 @@ static const struct file_operations dvb_ca_fops = {
.open = dvb_ca_open,
.release = dvb_generic_release,
.poll = dvb_ca_poll,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct dvb_device dvbdev_ca = {
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index b070e88d8c6b..7cafbc37628a 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -312,6 +312,7 @@ static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer
static const struct file_operations av7110_ir_proc_fops = {
.owner = THIS_MODULE,
.write = av7110_ir_proc_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
/* interrupt handler */
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index be35e6965829..2ffb6df955b3 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -180,6 +180,7 @@ struct cafe_camera
/* Current operating parameters */
u32 sensor_type; /* Currently ov7670 only */
struct v4l2_pix_format pix_format;
+ enum v4l2_mbus_pixelcode mbus_code;
/* Locks */
struct mutex s_mutex; /* Access to this structure */
@@ -207,6 +208,49 @@ static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
return container_of(dev, struct cafe_camera, v4l2_dev);
}
+static struct cafe_format_struct {
+ __u8 *desc;
+ __u32 pixelformat;
+ int bpp; /* Bytes per pixel */
+ enum v4l2_mbus_pixelcode mbus_code;
+} cafe_formats[] = {
+ {
+ .desc = "YUYV 4:2:2",
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
+ .bpp = 2,
+ },
+ {
+ .desc = "RGB 444",
+ .pixelformat = V4L2_PIX_FMT_RGB444,
+ .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
+ .bpp = 2,
+ },
+ {
+ .desc = "RGB 565",
+ .pixelformat = V4L2_PIX_FMT_RGB565,
+ .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
+ .bpp = 2,
+ },
+ {
+ .desc = "Raw RGB Bayer",
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
+ .bpp = 1
+ },
+};
+#define N_CAFE_FMTS ARRAY_SIZE(cafe_formats)
+
+static struct cafe_format_struct *cafe_find_format(u32 pixelformat)
+{
+ unsigned i;
+
+ for (i = 0; i < N_CAFE_FMTS; i++)
+ if (cafe_formats[i].pixelformat == pixelformat)
+ return cafe_formats + i;
+ /* Not found? Then return the first format. */
+ return cafe_formats;
+}
/*
* Start over with DMA buffers - dev_lock needed.
@@ -812,15 +856,15 @@ static int cafe_cam_set_flip(struct cafe_camera *cam)
static int cafe_cam_configure(struct cafe_camera *cam)
{
- struct v4l2_format fmt;
+ struct v4l2_mbus_framefmt mbus_fmt;
int ret;
if (cam->state != S_IDLE)
return -EINVAL;
- fmt.fmt.pix = cam->pix_format;
+ v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
ret = sensor_call(cam, core, init, 0);
if (ret == 0)
- ret = sensor_call(cam, video, s_fmt, &fmt);
+ ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
/*
* OV7670 does weird things if flip is set *before* format...
*/
@@ -1481,7 +1525,7 @@ static int cafe_vidioc_querycap(struct file *file, void *priv,
/*
* The default format we use until somebody says otherwise.
*/
-static struct v4l2_pix_format cafe_def_pix_format = {
+static const struct v4l2_pix_format cafe_def_pix_format = {
.width = VGA_WIDTH,
.height = VGA_HEIGHT,
.pixelformat = V4L2_PIX_FMT_YUYV,
@@ -1490,28 +1534,38 @@ static struct v4l2_pix_format cafe_def_pix_format = {
.sizeimage = VGA_WIDTH*VGA_HEIGHT*2,
};
+static const enum v4l2_mbus_pixelcode cafe_def_mbus_code =
+ V4L2_MBUS_FMT_YUYV8_2X8;
+
static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_fmtdesc *fmt)
{
- struct cafe_camera *cam = priv;
- int ret;
-
- mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, enum_fmt, fmt);
- mutex_unlock(&cam->s_mutex);
- return ret;
+ if (fmt->index >= N_CAFE_FMTS)
+ return -EINVAL;
+ strlcpy(fmt->description, cafe_formats[fmt->index].desc,
+ sizeof(fmt->description));
+ fmt->pixelformat = cafe_formats[fmt->index].pixelformat;
+ return 0;
}
-
static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *fmt)
{
struct cafe_camera *cam = priv;
+ struct cafe_format_struct *f;
+ struct v4l2_pix_format *pix = &fmt->fmt.pix;
+ struct v4l2_mbus_framefmt mbus_fmt;
int ret;
+ f = cafe_find_format(pix->pixelformat);
+ pix->pixelformat = f->pixelformat;
+ v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code);
mutex_lock(&cam->s_mutex);
- ret = sensor_call(cam, video, try_fmt, fmt);
+ ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
mutex_unlock(&cam->s_mutex);
+ v4l2_fill_pix_format(pix, &mbus_fmt);
+ pix->bytesperline = pix->width * f->bpp;
+ pix->sizeimage = pix->height * pix->bytesperline;
return ret;
}
@@ -1519,6 +1573,7 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *fmt)
{
struct cafe_camera *cam = priv;
+ struct cafe_format_struct *f;
int ret;
/*
@@ -1527,6 +1582,9 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
*/
if (cam->state != S_IDLE || cam->n_sbufs > 0)
return -EBUSY;
+
+ f = cafe_find_format(fmt->fmt.pix.pixelformat);
+
/*
* See if the formatting works in principle.
*/
@@ -1539,6 +1597,8 @@ static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
*/
mutex_lock(&cam->s_mutex);
cam->pix_format = fmt->fmt.pix;
+ cam->mbus_code = f->mbus_code;
+
/*
* Make sure we have appropriate DMA buffers.
*/
@@ -1915,6 +1975,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
init_waitqueue_head(&cam->iowait);
cam->pdev = pdev;
cam->pix_format = cafe_def_pix_format;
+ cam->mbus_code = cafe_def_mbus_code;
INIT_LIST_HEAD(&cam->dev_list);
INIT_LIST_HEAD(&cam->sb_avail);
INIT_LIST_HEAD(&cam->sb_full);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 9bc51a99376b..77be58c1096b 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -674,18 +674,25 @@ static inline int cx18_raw_vbi(const struct cx18 *cx)
/* Call the specified callback for all subdevs with a grp_id bit matching the
* mask in hw (if 0, then match them all). Ignore any errors. */
-#define cx18_call_hw(cx, hw, o, f, args...) \
- __v4l2_device_call_subdevs(&(cx)->v4l2_dev, \
- !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+#define cx18_call_hw(cx, hw, o, f, args...) \
+ do { \
+ struct v4l2_subdev *__sd; \
+ __v4l2_device_call_subdevs_p(&(cx)->v4l2_dev, __sd, \
+ !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
+ } while (0)
#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
/* Call the specified callback for all subdevs with a grp_id bit matching the
* mask in hw (if 0, then match them all). If the callback returns an error
* other than 0 or -ENOIOCTLCMD, then return with that error code. */
-#define cx18_call_hw_err(cx, hw, o, f, args...) \
- __v4l2_device_call_subdevs_until_err( \
- &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+#define cx18_call_hw_err(cx, hw, o, f, args...) \
+({ \
+ struct v4l2_subdev *__sd; \
+ __v4l2_device_call_subdevs_until_err_p(&(cx)->v4l2_dev, \
+ __sd, !(hw) || (__sd->grp_id & (hw)), o, f, \
+ ##args); \
+})
#define cx18_call_all_err(cx, o, f, args...) \
cx18_call_hw_err(cx, 0, o, f , ##args)
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile
index 755dd0ce65ff..6f2b57384488 100644
--- a/drivers/media/video/cx231xx/Makefile
+++ b/drivers/media/video/cx231xx/Makefile
@@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/common/tuners
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 6bdc0ef18119..5b7c9a948a0a 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -32,6 +32,7 @@
#include <media/v4l2-chip-ident.h>
#include <media/cx25840.h>
+#include "dvb-usb-ids.h"
#include "xc5000.h"
#include "cx231xx.h"
@@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_CNXT_RDE_250},
{USB_DEVICE(0x0572, 0x58A1),
.driver_info = CX231XX_BOARD_CNXT_RDU_250},
+ {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
+ .driver_info = CX231XX_BOARD_UNKNOWN},
{},
};
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index da66e5f8d91d..5aadc1d1956e 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1165,9 +1165,10 @@ static int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, iname[INPUT(n)->type]);
if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
- (CX23885_VMUX_CABLE == INPUT(n)->type))
+ (CX23885_VMUX_CABLE == INPUT(n)->type)) {
i->type = V4L2_INPUT_TYPE_TUNER;
i->std = CX23885_NORMS;
+ }
return 0;
}
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 99dbae117591..0fa85cbefbb1 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -17,7 +17,7 @@ config VIDEO_CX88
config VIDEO_CX88_ALSA
tristate "Conexant 2388x DMA audio support"
- depends on VIDEO_CX88 && SND && EXPERIMENTAL
+ depends on VIDEO_CX88 && SND
select SND_PCM
---help---
This is a video4linux driver for direct (DMA) audio on
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 4f383cdf5296..54b7fcd469a8 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -94,7 +94,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
****************************************************************************/
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(enable, bool, NULL, 0444);
@@ -131,7 +131,7 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
{
struct cx88_audio_buffer *buf = chip->buf;
struct cx88_core *core=chip->core;
- struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
+ const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
/* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
cx_clear(MO_AUD_DMACNTRL, 0x11);
@@ -197,7 +197,7 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
/*
* BOARD Specific: IRQ dma bits
*/
-static char *cx88_aud_irqs[32] = {
+static const char *cx88_aud_irqs[32] = {
"dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
NULL, /* reserved */
"dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
@@ -308,7 +308,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
* Digital hardware definition
*/
#define DEFAULT_FIFO_SIZE 4096
-static struct snd_pcm_hardware snd_cx88_digital_hw = {
+static const struct snd_pcm_hardware snd_cx88_digital_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -533,7 +533,7 @@ static struct snd_pcm_ops snd_cx88_pcm_ops = {
/*
* create a PCM device
*/
-static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
+static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, const char *name)
{
int err;
struct snd_pcm *pcm;
@@ -614,7 +614,7 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
-static struct snd_kcontrol_new snd_cx88_volume = {
+static const struct snd_kcontrol_new snd_cx88_volume = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -656,7 +656,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
return ret;
}
-static struct snd_kcontrol_new snd_cx88_dac_switch = {
+static const struct snd_kcontrol_new snd_cx88_dac_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Playback Switch",
.info = snd_ctl_boolean_mono_info,
@@ -665,7 +665,7 @@ static struct snd_kcontrol_new snd_cx88_dac_switch = {
.private_value = (1<<8),
};
-static struct snd_kcontrol_new snd_cx88_source_switch = {
+static const struct snd_kcontrol_new snd_cx88_source_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Switch",
.info = snd_ctl_boolean_mono_info,
@@ -683,7 +683,7 @@ static struct snd_kcontrol_new snd_cx88_source_switch = {
* Only boards with eeprom and byte 1 at eeprom=1 have it
*/
-static struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = {
+static const struct pci_device_id const cx88_audio_pci_tbl[] __devinitdata = {
{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0, }
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index e8416b76da67..97672cb49b51 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -2673,10 +2673,10 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
/* ----------------------------------------------------------------------- */
/* some GDI (was: Modular Technology) specific stuff */
-static struct {
+static const struct {
int id;
int fm;
- char *name;
+ const char *name;
} gdi_tuner[] = {
[ 0x01 ] = { .id = TUNER_ABSENT,
.name = "NTSC_M" },
@@ -2710,7 +2710,7 @@ static struct {
static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
{
- char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
+ const char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
? gdi_tuner[eeprom_data[0x0d]].name : NULL;
info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown");
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 85eb266fb351..e46dd7ed63ce 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -253,7 +253,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
* 0x0c00 - FIFOs
*/
-struct sram_channel cx88_sram_channels[] = {
+const struct sram_channel const cx88_sram_channels[] = {
[SRAM_CH21] = {
.name = "video y / packed",
.cmds_start = 0x180040,
@@ -353,7 +353,7 @@ struct sram_channel cx88_sram_channels[] = {
};
int cx88_sram_channel_setup(struct cx88_core *core,
- struct sram_channel *ch,
+ const struct sram_channel *ch,
unsigned int bpl, u32 risc)
{
unsigned int i,lines;
@@ -394,7 +394,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
static int cx88_risc_decode(u32 risc)
{
- static char *instr[16] = {
+ static const char * const instr[16] = {
[ RISC_SYNC >> 28 ] = "sync",
[ RISC_WRITE >> 28 ] = "write",
[ RISC_WRITEC >> 28 ] = "writec",
@@ -406,14 +406,14 @@ static int cx88_risc_decode(u32 risc)
[ RISC_WRITECM >> 28 ] = "writecm",
[ RISC_WRITECR >> 28 ] = "writecr",
};
- static int incr[16] = {
+ static int const incr[16] = {
[ RISC_WRITE >> 28 ] = 2,
[ RISC_JUMP >> 28 ] = 2,
[ RISC_WRITERM >> 28 ] = 3,
[ RISC_WRITECM >> 28 ] = 3,
[ RISC_WRITECR >> 28 ] = 4,
};
- static char *bits[] = {
+ static const char * const bits[] = {
"12", "13", "14", "resync",
"cnt0", "cnt1", "18", "19",
"20", "21", "22", "23",
@@ -432,9 +432,9 @@ static int cx88_risc_decode(u32 risc)
void cx88_sram_channel_dump(struct cx88_core *core,
- struct sram_channel *ch)
+ const struct sram_channel *ch)
{
- static char *name[] = {
+ static const char * const name[] = {
"initial risc",
"cdt base",
"cdt size",
@@ -489,14 +489,14 @@ void cx88_sram_channel_dump(struct cx88_core *core,
core->name,cx_read(ch->cnt2_reg));
}
-static char *cx88_pci_irqs[32] = {
+static const char *cx88_pci_irqs[32] = {
"vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
"src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
"i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
};
-void cx88_print_irqbits(char *name, char *tag, char **strings,
+void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],
int len, u32 bits, u32 mask)
{
unsigned int i;
@@ -770,7 +770,7 @@ static const u32 xtal = 28636363;
static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
{
- static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
+ static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
u64 pll;
u32 reg;
int i;
@@ -879,7 +879,7 @@ static int set_tvaudio(struct cx88_core *core)
} else {
printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
core->name, v4l2_norm_to_name(core->tvnorm));
- core->tvaudio = 0;
+ core->tvaudio = WW_NONE;
return 0;
}
@@ -1020,15 +1020,15 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
struct video_device *cx88_vdev_init(struct cx88_core *core,
struct pci_dev *pci,
- struct video_device *template,
- char *type)
+ const struct video_device *template_,
+ const char *type)
{
struct video_device *vfd;
vfd = video_device_alloc();
if (NULL == vfd)
return NULL;
- *vfd = *template;
+ *vfd = *template_;
vfd->v4l2_dev = &core->v4l2_dev;
vfd->parent = &pci->dev;
vfd->release = video_device_release;
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c
index a94e00a4ac5d..a9907265ff66 100644
--- a/drivers/media/video/cx88/cx88-dsp.c
+++ b/drivers/media/video/cx88/cx88-dsp.c
@@ -230,7 +230,7 @@ static s32 detect_btsc(struct cx88_core *core, s16 x[], u32 N)
static s16 *read_rds_samples(struct cx88_core *core, u32 *N)
{
- struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
+ const struct sram_channel *srch = &cx88_sram_channels[SRAM_CH27];
s16 *samples;
unsigned int i;
@@ -292,11 +292,20 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core)
switch (core->tvaudio) {
case WW_BG:
case WW_DK:
+ case WW_EIAJ:
+ case WW_M:
ret = detect_a2_a2m_eiaj(core, samples, N);
break;
case WW_BTSC:
ret = detect_btsc(core, samples, N);
break;
+ case WW_NONE:
+ case WW_I:
+ case WW_L:
+ case WW_I2SPT:
+ case WW_FM:
+ case WW_I2SADC:
+ break;
}
kfree(samples);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index faa8e8163a4a..e24fd8d711d8 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -105,7 +105,7 @@ static void dvb_buf_release(struct videobuf_queue *q,
cx88_free_buffer(q, (struct cx88_buffer*)vb);
}
-static struct videobuf_queue_ops dvb_qops = {
+static const struct videobuf_queue_ops dvb_qops = {
.buf_setup = dvb_buf_setup,
.buf_prepare = dvb_buf_prepare,
.buf_queue = dvb_buf_queue,
@@ -167,12 +167,12 @@ static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
- static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+ static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
+ static const u8 reset [] = { RESET, 0x80 };
+ static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+ static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
+ static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+ static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(200);
@@ -187,12 +187,12 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
static int dvico_dual_demod_init(struct dvb_frontend *fe)
{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
- static u8 reset [] = { RESET, 0x80 };
- static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
- static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
- static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
- static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+ static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
+ static const u8 reset [] = { RESET, 0x80 };
+ static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+ static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
+ static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+ static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(200);
@@ -208,13 +208,13 @@ static int dvico_dual_demod_init(struct dvb_frontend *fe)
static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
{
- static u8 clock_config [] = { 0x89, 0x38, 0x39 };
- static u8 reset [] = { 0x50, 0x80 };
- static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
+ static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
+ static const u8 reset [] = { 0x50, 0x80 };
+ static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+ static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
0x00, 0xFF, 0x00, 0x40, 0x40 };
- static u8 dntv_extra[] = { 0xB5, 0x7A };
- static u8 capt_range_cfg[] = { 0x75, 0x32 };
+ static const u8 dntv_extra[] = { 0xB5, 0x7A };
+ static const u8 capt_range_cfg[] = { 0x75, 0x32 };
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(2000);
@@ -229,22 +229,22 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
return 0;
}
-static struct mt352_config dvico_fusionhdtv = {
+static const struct mt352_config dvico_fusionhdtv = {
.demod_address = 0x0f,
.demod_init = dvico_fusionhdtv_demod_init,
};
-static struct mt352_config dntv_live_dvbt_config = {
+static const struct mt352_config dntv_live_dvbt_config = {
.demod_address = 0x0f,
.demod_init = dntv_live_dvbt_demod_init,
};
-static struct mt352_config dvico_fusionhdtv_dual = {
+static const struct mt352_config dvico_fusionhdtv_dual = {
.demod_address = 0x0f,
.demod_init = dvico_dual_demod_init,
};
-static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
+static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
.if2 = 45600,
@@ -253,13 +253,13 @@ static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
{
- static u8 clock_config [] = { 0x89, 0x38, 0x38 };
- static u8 reset [] = { 0x50, 0x80 };
- static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
+ static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
+ static const u8 reset [] = { 0x50, 0x80 };
+ static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+ static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
0x00, 0xFF, 0x00, 0x40, 0x40 };
- static u8 dntv_extra[] = { 0xB5, 0x7A };
- static u8 capt_range_cfg[] = { 0x75, 0x32 };
+ static const u8 dntv_extra[] = { 0xB5, 0x7A };
+ static const u8 capt_range_cfg[] = { 0x75, 0x32 };
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(2000);
@@ -274,41 +274,41 @@ static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
return 0;
}
-static struct mt352_config dntv_live_dvbt_pro_config = {
+static const struct mt352_config dntv_live_dvbt_pro_config = {
.demod_address = 0x0f,
.no_tuner = 1,
.demod_init = dntv_live_dvbt_pro_demod_init,
};
#endif
-static struct zl10353_config dvico_fusionhdtv_hybrid = {
+static const struct zl10353_config dvico_fusionhdtv_hybrid = {
.demod_address = 0x0f,
.no_tuner = 1,
};
-static struct zl10353_config dvico_fusionhdtv_xc3028 = {
+static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
.demod_address = 0x0f,
.if2 = 45600,
.no_tuner = 1,
};
-static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
+static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
.demod_address = 0x0f,
.if2 = 4560,
.no_tuner = 1,
.demod_init = dvico_fusionhdtv_demod_init,
};
-static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
+static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
.demod_address = 0x0f,
};
-static struct cx22702_config connexant_refboard_config = {
+static const struct cx22702_config connexant_refboard_config = {
.demod_address = 0x43,
.output_mode = CX22702_SERIAL_OUTPUT,
};
-static struct cx22702_config hauppauge_hvr_config = {
+static const struct cx22702_config hauppauge_hvr_config = {
.demod_address = 0x63,
.output_mode = CX22702_SERIAL_OUTPUT,
};
@@ -320,7 +320,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
return 0;
}
-static struct or51132_config pchdtv_hd3000 = {
+static const struct or51132_config pchdtv_hd3000 = {
.demod_address = 0x15,
.set_ts_params = or51132_set_ts_param,
};
@@ -355,14 +355,14 @@ static struct lgdt330x_config fusionhdtv_3_gold = {
.set_ts_params = lgdt330x_set_ts_param,
};
-static struct lgdt330x_config fusionhdtv_5_gold = {
+static const struct lgdt330x_config fusionhdtv_5_gold = {
.demod_address = 0x0e,
.demod_chip = LGDT3303,
.serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
.set_ts_params = lgdt330x_set_ts_param,
};
-static struct lgdt330x_config pchdtv_hd5500 = {
+static const struct lgdt330x_config pchdtv_hd5500 = {
.demod_address = 0x59,
.demod_chip = LGDT3303,
.serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
@@ -376,7 +376,7 @@ static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
return 0;
}
-static struct nxt200x_config ati_hdtvwonder = {
+static const struct nxt200x_config ati_hdtvwonder = {
.demod_address = 0x0a,
.set_ts_params = nxt200x_set_ts_param,
};
@@ -445,23 +445,23 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
return 0;
}
-static struct cx24123_config geniatech_dvbs_config = {
+static const struct cx24123_config geniatech_dvbs_config = {
.demod_address = 0x55,
.set_ts_params = cx24123_set_ts_param,
};
-static struct cx24123_config hauppauge_novas_config = {
+static const struct cx24123_config hauppauge_novas_config = {
.demod_address = 0x55,
.set_ts_params = cx24123_set_ts_param,
};
-static struct cx24123_config kworld_dvbs_100_config = {
+static const struct cx24123_config kworld_dvbs_100_config = {
.demod_address = 0x15,
.set_ts_params = cx24123_set_ts_param,
.lnb_polarity = 1,
};
-static struct s5h1409_config pinnacle_pctv_hd_800i_config = {
+static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
.demod_address = 0x32 >> 1,
.output_mode = S5H1409_PARALLEL_OUTPUT,
.gpio = S5H1409_GPIO_ON,
@@ -471,7 +471,7 @@ static struct s5h1409_config pinnacle_pctv_hd_800i_config = {
.mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
};
-static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
+static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
.demod_address = 0x32 >> 1,
.output_mode = S5H1409_SERIAL_OUTPUT,
.gpio = S5H1409_GPIO_OFF,
@@ -480,7 +480,7 @@ static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};
-static struct s5h1409_config kworld_atsc_120_config = {
+static const struct s5h1409_config kworld_atsc_120_config = {
.demod_address = 0x32 >> 1,
.output_mode = S5H1409_SERIAL_OUTPUT,
.gpio = S5H1409_GPIO_OFF,
@@ -489,24 +489,24 @@ static struct s5h1409_config kworld_atsc_120_config = {
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};
-static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
+static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
.i2c_address = 0x64,
.if_khz = 5380,
};
-static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
+static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
.if2 = 45600,
};
-static struct zl10353_config cx88_geniatech_x8000_mt = {
+static const struct zl10353_config cx88_geniatech_x8000_mt = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
.disable_i2c_gate_ctrl = 1,
};
-static struct s5h1411_config dvico_fusionhdtv7_config = {
+static const struct s5h1411_config dvico_fusionhdtv7_config = {
.output_mode = S5H1411_SERIAL_OUTPUT,
.gpio = S5H1411_GPIO_ON,
.mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
@@ -516,7 +516,7 @@ static struct s5h1411_config dvico_fusionhdtv7_config = {
.status_mode = S5H1411_DEMODLOCKING
};
-static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
+static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
.i2c_address = 0xc2 >> 1,
.if_khz = 5380,
};
@@ -601,19 +601,19 @@ static int cx24116_reset_device(struct dvb_frontend *fe)
return 0;
}
-static struct cx24116_config hauppauge_hvr4000_config = {
+static const struct cx24116_config hauppauge_hvr4000_config = {
.demod_address = 0x05,
.set_ts_params = cx24116_set_ts_param,
.reset_device = cx24116_reset_device,
};
-static struct cx24116_config tevii_s460_config = {
+static const struct cx24116_config tevii_s460_config = {
.demod_address = 0x55,
.set_ts_params = cx24116_set_ts_param,
.reset_device = cx24116_reset_device,
};
-static struct stv0900_config prof_7301_stv0900_config = {
+static const struct stv0900_config prof_7301_stv0900_config = {
.demod_address = 0x6a,
/* demod_mode = 0,*/
.xtal = 27000000,
@@ -625,12 +625,12 @@ static struct stv0900_config prof_7301_stv0900_config = {
.set_ts_params = stv0900_set_ts_param,
};
-static struct stb6100_config prof_7301_stb6100_config = {
+static const struct stb6100_config prof_7301_stb6100_config = {
.tuner_address = 0x60,
.refclock = 27000000,
};
-static struct stv0299_config tevii_tuner_sharp_config = {
+static const struct stv0299_config tevii_tuner_sharp_config = {
.demod_address = 0x68,
.inittab = sharp_z0194a_inittab,
.mclk = 88000000UL,
@@ -643,7 +643,7 @@ static struct stv0299_config tevii_tuner_sharp_config = {
.set_ts_params = cx24116_set_ts_param,
};
-static struct stv0288_config tevii_tuner_earda_config = {
+static const struct stv0288_config tevii_tuner_earda_config = {
.demod_address = 0x68,
.min_delay_ms = 100,
.set_ts_params = cx24116_set_ts_param,
@@ -676,7 +676,7 @@ static int cx8802_alloc_frontends(struct cx8802_dev *dev)
-static u8 samsung_smt_7020_inittab[] = {
+static const u8 samsung_smt_7020_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x03, 0x00,
@@ -850,7 +850,7 @@ static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
}
-static struct stv0299_config samsung_stv0299_config = {
+static const struct stv0299_config samsung_stv0299_config = {
.demod_address = 0x68,
.inittab = samsung_smt_7020_inittab,
.mclk = 88000000UL,
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 82db555b22dd..9d25d4f49268 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -108,7 +108,7 @@ static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
/* ----------------------------------------------------------------------- */
-static char *i2c_devs[128] = {
+static const char * const i2c_devs[128] = {
[ 0x1c >> 1 ] = "lgdt330x",
[ 0x86 >> 1 ] = "tda9887/cx22702",
[ 0xa0 >> 1 ] = "eeprom",
@@ -117,7 +117,7 @@ static char *i2c_devs[128] = {
[ 0xc8 >> 1 ] = "xc5000",
};
-static void do_i2c_scan(char *name, struct i2c_client *c)
+static void do_i2c_scan(const char *name, struct i2c_client *c)
{
unsigned char buf;
int i,rc;
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 499f8d512ad6..f7d71acbb078 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -313,7 +313,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
/* ----------------------------------------------------------- */
-static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
+static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart)
{
struct cx88_dmaqueue *q = &dev->mpegq;
struct cx88_buffer *buf;
@@ -358,7 +358,7 @@ static void cx8802_timeout(unsigned long data)
do_cancel_buffers(dev,"timeout",1);
}
-static char *cx88_mpeg_irqs[32] = {
+static const char * cx88_mpeg_irqs[32] = {
"ts_risci1", NULL, NULL, NULL,
"ts_risci2", NULL, NULL, NULL,
"ts_oflow", NULL, NULL, NULL,
@@ -849,7 +849,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
kfree(dev);
}
-static struct pci_device_id cx8802_pci_tbl[] = {
+static const struct pci_device_id cx8802_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8802,
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 239631568f3b..08220de3d74d 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -70,7 +70,7 @@ MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, "
/* ----------------------------------------------------------- */
-static char *aud_ctl_names[64] = {
+static const char * const aud_ctl_names[64] = {
[EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
[EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
[EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
@@ -360,7 +360,15 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
set_audio_registers(core, nicam_bgdki_common);
set_audio_registers(core, nicam_i);
break;
- default:
+ case WW_NONE:
+ case WW_BTSC:
+ case WW_BG:
+ case WW_DK:
+ case WW_EIAJ:
+ case WW_I2SPT:
+ case WW_FM:
+ case WW_I2SADC:
+ case WW_M:
dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__);
set_audio_registers(core, nicam_bgdki_common);
set_audio_registers(core, nicam_default);
@@ -621,7 +629,13 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
dprintk("%s AM-L (status: devel)\n", __func__);
set_audio_registers(core, am_l);
break;
- default:
+ case WW_NONE:
+ case WW_BTSC:
+ case WW_EIAJ:
+ case WW_I2SPT:
+ case WW_FM:
+ case WW_I2SADC:
+ case WW_M:
dprintk("%s Warning: wrong value\n", __func__);
return;
break;
@@ -779,7 +793,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
set_audio_finish(core, EN_I2SIN_ENABLE);
break;
case WW_NONE:
- default:
+ case WW_I2SPT:
printk("%s/0: unknown tv audio mode [%d]\n",
core->name, core->tvaudio);
break;
@@ -795,8 +809,8 @@ void cx88_newstation(struct cx88_core *core)
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
{
- static char *m[] = { "stereo", "dual mono", "mono", "sap" };
- static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
+ static const char * const m[] = { "stereo", "dual mono", "mono", "sap" };
+ static const char * const p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
u32 reg, mode, pilot;
reg = cx_read(AUD_STATUS);
@@ -840,7 +854,12 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
break;
}
break;
- default:
+ case WW_NONE:
+ case WW_I:
+ case WW_L:
+ case WW_I2SPT:
+ case WW_FM:
+ case WW_I2SADC:
/* nothing */
break;
}
@@ -945,6 +964,9 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
}
break;
case WW_I2SADC:
+ case WW_NONE:
+ case WW_EIAJ:
+ case WW_I2SPT:
/* DO NOTHING */
break;
}
@@ -1000,7 +1022,12 @@ int cx88_audio_thread(void *data)
/* automatically switch to best available mode */
cx88_set_stereo(core, mode, 0);
break;
- default:
+ case WW_NONE:
+ case WW_BTSC:
+ case WW_EIAJ:
+ case WW_I2SPT:
+ case WW_FM:
+ case WW_I2SADC:
hw_autodetect:
/* stereo autodetection is supported by hardware so
we don't need to do it manually. Do nothing. */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index d9445b0e7ab2..f8f8389c0362 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -230,7 +230,7 @@ static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
cx88_free_buffer(q,buf);
}
-struct videobuf_queue_ops cx8800_vbi_qops = {
+const struct videobuf_queue_ops cx8800_vbi_qops = {
.buf_setup = vbi_setup,
.buf_prepare = vbi_prepare,
.buf_queue = vbi_queue,
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 0fab65c3ab39..b755bf100a2b 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
/* ------------------------------------------------------------------- */
/* static data */
-static struct cx8800_fmt formats[] = {
+static const struct cx8800_fmt formats[] = {
{
.name = "8 bpp, gray",
.fourcc = V4L2_PIX_FMT_GREY,
@@ -142,7 +142,7 @@ static struct cx8800_fmt formats[] = {
},
};
-static struct cx8800_fmt* format_by_fourcc(unsigned int fourcc)
+static const struct cx8800_fmt* format_by_fourcc(unsigned int fourcc)
{
unsigned int i;
@@ -159,7 +159,7 @@ static const struct v4l2_queryctrl no_ctl = {
.flags = V4L2_CTRL_FLAG_DISABLED,
};
-static struct cx88_ctrl cx8800_ctls[] = {
+static const struct cx88_ctrl cx8800_ctls[] = {
/* --- video --- */
{
.v = {
@@ -288,7 +288,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
.shift = 0,
}
};
-static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
+enum { CX8800_CTLS = ARRAY_SIZE(cx8800_ctls) };
/* Must be sorted from low to high control ID! */
const u32 cx88_user_ctrls[] = {
@@ -306,7 +306,7 @@ const u32 cx88_user_ctrls[] = {
};
EXPORT_SYMBOL(cx88_user_ctrls);
-static const u32 *ctrl_classes[] = {
+static const u32 * const ctrl_classes[] = {
cx88_user_ctrls,
NULL
};
@@ -710,7 +710,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
cx88_free_buffer(q,buf);
}
-static struct videobuf_queue_ops cx8800_video_qops = {
+static const struct videobuf_queue_ops cx8800_video_qops = {
.buf_setup = buffer_setup,
.buf_prepare = buffer_prepare,
.buf_queue = buffer_queue,
@@ -944,7 +944,7 @@ video_mmap(struct file *file, struct vm_area_struct * vma)
int cx88_get_control (struct cx88_core *core, struct v4l2_control *ctl)
{
- struct cx88_ctrl *c = NULL;
+ const struct cx88_ctrl *c = NULL;
u32 value;
int i;
@@ -976,7 +976,7 @@ EXPORT_SYMBOL(cx88_get_control);
int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
{
- struct cx88_ctrl *c = NULL;
+ const struct cx88_ctrl *c = NULL;
u32 value,mask;
int i;
@@ -1072,7 +1072,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
- struct cx8800_fmt *fmt;
+ const struct cx8800_fmt *fmt;
enum v4l2_field field;
unsigned int maxw, maxh;
@@ -1247,7 +1247,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *tvnorms)
/* only one input in this sample driver */
int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
{
- static const char *iname[] = {
+ static const char * const iname[] = {
[ CX88_VMUX_COMPOSITE1 ] = "Composite1",
[ CX88_VMUX_COMPOSITE2 ] = "Composite2",
[ CX88_VMUX_COMPOSITE3 ] = "Composite3",
@@ -1267,9 +1267,10 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name,iname[INPUT(n).type]);
if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
- (CX88_VMUX_CABLE == INPUT(n).type))
+ (CX88_VMUX_CABLE == INPUT(n).type)) {
i->type = V4L2_INPUT_TYPE_TUNER;
i->std = CX88_NORMS;
+ }
return 0;
}
EXPORT_SYMBOL(cx88_enum_input);
@@ -1578,7 +1579,7 @@ static void cx8800_vid_timeout(unsigned long data)
spin_unlock_irqrestore(&dev->slock,flags);
}
-static char *cx88_vid_irqs[32] = {
+static const char *cx88_vid_irqs[32] = {
"y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
"y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
"y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
@@ -1723,7 +1724,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static struct video_device cx8800_vbi_template;
-static struct video_device cx8800_video_template = {
+static const struct video_device cx8800_video_template = {
.name = "cx8800-video",
.fops = &video_fops,
.ioctl_ops = &video_ioctl_ops,
@@ -1758,7 +1759,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
#endif
};
-static struct video_device cx8800_radio_template = {
+static const struct video_device cx8800_radio_template = {
.name = "cx8800-radio",
.fops = &radio_fops,
.ioctl_ops = &radio_ioctl_ops,
@@ -1885,7 +1886,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
switch (core->boardnr) {
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
- static struct i2c_board_info rtc_info = {
+ static const struct i2c_board_info rtc_info = {
I2C_BOARD_INFO("isl1208", 0x6f)
};
@@ -2082,7 +2083,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
/* ----------------------------------------------------------- */
-static struct pci_device_id cx8800_pci_tbl[] = {
+static const struct pci_device_id cx8800_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8800,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 33d161a11725..bda9e3ee425e 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -108,7 +108,7 @@ static unsigned int inline norm_maxh(v4l2_std_id norm)
/* static data */
struct cx8800_fmt {
- char *name;
+ const char *name;
u32 fourcc; /* v4l2 format id */
int depth;
int flags;
@@ -138,7 +138,7 @@ struct cx88_ctrl {
/* more */
struct sram_channel {
- char *name;
+ const char *name;
u32 cmds_start;
u32 ctrl_start;
u32 cdt;
@@ -149,7 +149,7 @@ struct sram_channel {
u32 cnt1_reg;
u32 cnt2_reg;
};
-extern struct sram_channel cx88_sram_channels[];
+extern const struct sram_channel const cx88_sram_channels[];
/* ----------------------------------------------------------- */
/* card configuration */
@@ -262,7 +262,7 @@ struct cx88_input {
};
struct cx88_board {
- char *name;
+ const char *name;
unsigned int tuner_type;
unsigned int radio_type;
unsigned char tuner_addr;
@@ -281,6 +281,20 @@ struct cx88_subid {
u32 card;
};
+enum cx88_tvaudio {
+ WW_NONE = 1,
+ WW_BTSC,
+ WW_BG,
+ WW_DK,
+ WW_I,
+ WW_L,
+ WW_EIAJ,
+ WW_I2SPT,
+ WW_FM,
+ WW_I2SADC,
+ WW_M
+};
+
#define INPUT(nr) (core->board.input[nr])
/* ----------------------------------------------------------- */
@@ -300,7 +314,7 @@ struct cx88_buffer {
/* cx88 specific */
unsigned int bpl;
struct btcx_riscmem risc;
- struct cx8800_fmt *fmt;
+ const struct cx8800_fmt *fmt;
u32 count;
};
@@ -352,7 +366,7 @@ struct cx88_core {
/* state info */
struct task_struct *kthread;
v4l2_std_id tvnorm;
- u32 tvaudio;
+ enum cx88_tvaudio tvaudio;
u32 audiomode_manual;
u32 audiomode_current;
u32 input;
@@ -410,7 +424,7 @@ struct cx8800_fh {
unsigned int nclips;
/* video capture */
- struct cx8800_fmt *fmt;
+ const struct cx8800_fmt *fmt;
unsigned int width,height;
struct videobuf_queue vidq;
@@ -565,7 +579,7 @@ struct cx8802_dev {
/* ----------------------------------------------------------- */
/* cx88-core.c */
-extern void cx88_print_irqbits(char *name, char *tag, char **strings,
+extern void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],
int len, u32 bits, u32 mask);
extern int cx88_core_irq(struct cx88_core *core, u32 status);
@@ -592,10 +606,10 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf);
extern void cx88_risc_disasm(struct cx88_core *core,
struct btcx_riscmem *risc);
extern int cx88_sram_channel_setup(struct cx88_core *core,
- struct sram_channel *ch,
+ const struct sram_channel *ch,
unsigned int bpl, u32 risc);
extern void cx88_sram_channel_dump(struct cx88_core *core,
- struct sram_channel *ch);
+ const struct sram_channel *ch);
extern int cx88_set_scale(struct cx88_core *core, unsigned int width,
unsigned int height, enum v4l2_field field);
@@ -603,8 +617,8 @@ extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm);
extern struct video_device *cx88_vdev_init(struct cx88_core *core,
struct pci_dev *pci,
- struct video_device *template,
- char *type);
+ const struct video_device *template_,
+ const char *type);
extern struct cx88_core* cx88_core_get(struct pci_dev *pci);
extern void cx88_core_put(struct cx88_core *core,
struct pci_dev *pci);
@@ -630,7 +644,7 @@ int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q);
void cx8800_vbi_timeout(unsigned long data);
-extern struct videobuf_queue_ops cx8800_vbi_qops;
+extern const struct videobuf_queue_ops cx8800_vbi_qops;
/* ----------------------------------------------------------- */
/* cx88-i2c.c */
@@ -651,18 +665,6 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
/* ----------------------------------------------------------- */
/* cx88-tvaudio.c */
-#define WW_NONE 1
-#define WW_BTSC 2
-#define WW_BG 3
-#define WW_DK 4
-#define WW_I 5
-#define WW_L 6
-#define WW_EIAJ 7
-#define WW_I2SPT 8
-#define WW_FM 9
-#define WW_I2SADC 10
-#define WW_M 11
-
void cx88_set_tvaudio(struct cx88_core *core);
void cx88_newstation(struct cx88_core *core);
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 1c2588247289..b39112517dfb 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -370,7 +370,7 @@ static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
* For a given standard, this functions sets up the default
* pix format & crop values in the vpfe device and ccdc. It first
* starts with defaults based values from the standard table.
- * It then checks if sub device support g_fmt and then override the
+ * It then checks if sub device support g_mbus_fmt and then override the
* values based on that.Sets crop values to match with scan resolution
* starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
* values in ccdc
@@ -379,6 +379,8 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
const v4l2_std_id *std_id)
{
struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
+ struct v4l2_mbus_framefmt mbus_fmt;
+ struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix;
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
@@ -403,29 +405,36 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
vpfe_dev->crop.left = 0;
vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
- vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width;
- vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height;
+ pix->width = vpfe_dev->crop.width;
+ pix->height = vpfe_dev->crop.height;
/* first field and frame format based on standard frame format */
if (vpfe_dev->std_info.frame_format) {
- vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+ pix->field = V4L2_FIELD_INTERLACED;
/* assume V4L2_PIX_FMT_UYVY as default */
- vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ pix->pixelformat = V4L2_PIX_FMT_UYVY;
+ v4l2_fill_mbus_format(&mbus_fmt, pix,
+ V4L2_MBUS_FMT_YUYV10_2X10);
} else {
- vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+ pix->field = V4L2_FIELD_NONE;
/* assume V4L2_PIX_FMT_SBGGR8 */
- vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+ pix->pixelformat = V4L2_PIX_FMT_SBGGR8;
+ v4l2_fill_mbus_format(&mbus_fmt, pix,
+ V4L2_MBUS_FMT_SBGGR8_1X8);
}
- /* if sub device supports g_fmt, override the defaults */
+ /* if sub device supports g_mbus_fmt, override the defaults */
ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
- sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt);
+ sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt);
if (ret && ret != -ENOIOCTLCMD) {
v4l2_err(&vpfe_dev->v4l2_dev,
- "error in getting g_fmt from sub device\n");
+ "error in getting g_mbus_fmt from sub device\n");
return ret;
}
+ v4l2_fill_pix_format(pix, &mbus_fmt);
+ pix->bytesperline = pix->width * 2;
+ pix->sizeimage = pix->bytesperline * pix->height;
/* Sets the values in CCDC */
ret = vpfe_config_ccdc_image_format(vpfe_dev);
@@ -434,11 +443,8 @@ static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
/* Update the values of sizeimage and bytesperline */
if (!ret) {
- vpfe_dev->fmt.fmt.pix.bytesperline =
- ccdc_dev->hw_ops.get_line_length();
- vpfe_dev->fmt.fmt.pix.sizeimage =
- vpfe_dev->fmt.fmt.pix.bytesperline *
- vpfe_dev->fmt.fmt.pix.height;
+ pix->bytesperline = ccdc_dev->hw_ops.get_line_length();
+ pix->sizeimage = pix->bytesperline * pix->height;
}
return ret;
}
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index a7f48b53d3fc..2b424731f133 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -1030,9 +1030,10 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
goto qbuf_exit;
if ((VIDEOBUF_NEEDS_INIT != buf1->state)
- && (buf1->baddr != tbuf.m.userptr))
+ && (buf1->baddr != tbuf.m.userptr)) {
vpif_buffer_release(&common->buffer_queue, buf1);
buf1->baddr = tbuf.m.userptr;
+ }
break;
default:
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index da07607cbc55..4770fda3a199 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -935,9 +935,10 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
goto qbuf_exit;
if ((VIDEOBUF_NEEDS_INIT != buf1->state)
- && (buf1->baddr != tbuf.m.userptr))
+ && (buf1->baddr != tbuf.m.userptr)) {
vpif_buffer_release(&common->buffer_queue, buf1);
buf1->baddr = tbuf.m.userptr;
+ }
break;
default:
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 7b9ec6e493e4..95a4b60a1eda 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -277,12 +277,13 @@ static void em28xx_copy_vbi(struct em28xx *dev,
{
void *startwrite, *startread;
int offset;
- int bytesperline = dev->vbi_width;
+ int bytesperline;
if (dev == NULL) {
em28xx_isocdbg("dev is null\n");
return;
}
+ bytesperline = dev->vbi_width;
if (dma_q == NULL) {
em28xx_isocdbg("dma_q is null\n");
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 23db0c29f68c..dda56ff834f4 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -77,6 +77,15 @@ config USB_GSPCA_JEILINJ
To compile this driver as a module, choose M here: the
module will be called gspca_jeilinj.
+config USB_GSPCA_KONICA
+ tristate "Konica USB Camera V4L2 driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the Konica chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_konica.
+
config USB_GSPCA_MARS
tristate "Mars USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -337,6 +346,15 @@ config USB_GSPCA_VC032X
To compile this driver as a module, choose M here: the
module will be called gspca_vc032x.
+config USB_GSPCA_XIRLINK_CIT
+ tristate "Xirlink C-It USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for Xirlink C-It bases cameras.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_xirlink_cit.
+
config USB_GSPCA_ZC3XX
tristate "ZC3XX USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index f6616db0b7f8..24e695b8b077 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o
obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
+obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
@@ -33,6 +34,7 @@ obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o
obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
gspca_main-objs := gspca.o
@@ -42,6 +44,7 @@ gspca_cpia1-objs := cpia1.o
gspca_etoms-objs := etoms.o
gspca_finepix-objs := finepix.o
gspca_jeilinj-objs := jeilinj.o
+gspca_konica-objs := konica.o
gspca_mars-objs := mars.o
gspca_mr97310a-objs := mr97310a.o
gspca_ov519-objs := ov519.o
@@ -70,6 +73,7 @@ gspca_sunplus-objs := sunplus.o
gspca_t613-objs := t613.o
gspca_tv8532-objs := tv8532.o
gspca_vc032x-objs := vc032x.o
+gspca_xirlink_cit-objs := xirlink_cit.o
gspca_zc3xx-objs := zc3xx.o
obj-$(CONFIG_USB_M5602) += m5602/
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 3747a1dcff54..b278186ea6d1 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1,7 +1,7 @@
/*
* cpia CPiA (1) gspca driver
*
- * Copyright (C) 2010 Hans de Goede <hdgoede@redhat.com>
+ * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
*
* This module is adapted from the in kernel v4l1 cpia driver which is :
*
@@ -30,7 +30,7 @@
#include "gspca.h"
-MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Vision CPiA");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index b9846106913e..78abc1c1f9d5 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
usb_rcvintpipe(dev, ep->bEndpointAddress),
buffer, buffer_len,
int_irq, (void *)gspca_dev, interval);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
gspca_dev->int_urb = urb;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) {
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c
new file mode 100644
index 000000000000..3de67ee5c230
--- /dev/null
+++ b/drivers/media/video/gspca/konica.c
@@ -0,0 +1,653 @@
+/*
+ * Driver for USB webcams based on Konica chipset. This
+ * chipset is used in Intel YC76 camera.
+ *
+ * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Based on the usbvideo v4l1 konicawc driver which is:
+ *
+ * Copyright (C) 2002 Simon Evans <spse@secret.org.uk>
+ *
+ * The code for making gspca work with a webcam with 2 isoc endpoints was
+ * taken from the benq gspca subdriver which is:
+ *
+ * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
+ *
+ * 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
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "konica"
+
+#include <linux/input.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_DESCRIPTION("Konica chipset USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+#define WHITEBAL_REG 0x01
+#define BRIGHTNESS_REG 0x02
+#define SHARPNESS_REG 0x03
+#define CONTRAST_REG 0x04
+#define SATURATION_REG 0x05
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ struct urb *last_data_urb;
+ u8 snapshot_pressed;
+ u8 brightness;
+ u8 contrast;
+ u8 saturation;
+ u8 whitebal;
+ u8 sharpness;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
+static const struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 9,
+ .step = 1,
+#define BRIGHTNESS_DEFAULT 4
+ .default_value = BRIGHTNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "contrast",
+ .minimum = 0,
+ .maximum = 9,
+ .step = 4,
+#define CONTRAST_DEFAULT 10
+ .default_value = CONTRAST_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_SATURATION 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 9,
+ .step = 1,
+#define SATURATION_DEFAULT 4
+ .default_value = SATURATION_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setsaturation,
+ .get = sd_getsaturation,
+ },
+#define SD_WHITEBAL 3
+ {
+ {
+ .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Whitebalance ",
+ .minimum = 0,
+ .maximum = 33,
+ .step = 1,
+#define WHITEBAL_DEFAULT 25
+ .default_value = WHITEBAL_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setwhitebal,
+ .get = sd_getwhitebal,
+ },
+#define SD_SHARPNESS 4
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 9,
+ .step = 1,
+#define SHARPNESS_DEFAULT 4
+ .default_value = SHARPNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
+};
+
+/* .priv is what goes to register 8 for this mode, known working values:
+ 0x00 -> 176x144, cropped
+ 0x01 -> 176x144, cropped
+ 0x02 -> 176x144, cropped
+ 0x03 -> 176x144, cropped
+ 0x04 -> 176x144, binned
+ 0x05 -> 320x240
+ 0x06 -> 320x240
+ 0x07 -> 160x120, cropped
+ 0x08 -> 160x120, cropped
+ 0x09 -> 160x120, binned (note has 136 lines)
+ 0x0a -> 160x120, binned (note has 136 lines)
+ 0x0b -> 160x120, cropped
+*/
+static const struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 136 * 3 / 2 + 960,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0x0a},
+ {176, 144, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 2 + 960,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0x04},
+ {320, 240, V4L2_PIX_FMT_KONICA420, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 2 + 960,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0x05},
+};
+
+static void sd_isoc_irq(struct urb *urb);
+
+static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x02,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ NULL,
+ 0,
+ 1000);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ 0x03,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ gspca_dev->usb_buf,
+ 2,
+ 1000);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void konica_stream_on(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 1, 0x0b);
+}
+
+static void konica_stream_off(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0, 0x0b);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ gspca_dev->cam.cam_mode = vga_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
+ gspca_dev->cam.no_urb_create = 1;
+ /* The highest alt setting has an isoc packetsize of 0, so we
+ don't want to use it */
+ gspca_dev->nbalt--;
+
+ sd->brightness = BRIGHTNESS_DEFAULT;
+ sd->contrast = CONTRAST_DEFAULT;
+ sd->saturation = SATURATION_DEFAULT;
+ sd->whitebal = WHITEBAL_DEFAULT;
+ sd->sharpness = SHARPNESS_DEFAULT;
+
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ /* HDG not sure if these 2 reads are needed */
+ reg_r(gspca_dev, 0, 0x10);
+ PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ reg_r(gspca_dev, 0, 0x10);
+ PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ reg_w(gspca_dev, 0, 0x0d);
+
+ return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct urb *urb;
+ int i, n, packet_size;
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
+
+ intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+ if (!alt) {
+ PDEBUG(D_ERR, "Couldn't get altsetting");
+ return -EIO;
+ }
+
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+
+ reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
+ reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG);
+ reg_w(gspca_dev, sd->contrast, CONTRAST_REG);
+ reg_w(gspca_dev, sd->saturation, SATURATION_REG);
+ reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG);
+
+ n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+ reg_w(gspca_dev, n, 0x08);
+
+ konica_stream_on(gspca_dev);
+
+ if (gspca_dev->usb_err)
+ return gspca_dev->usb_err;
+
+ /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
+#if MAX_NURBS < 4
+#error "Not enough URBs in the gspca table"
+#endif
+#define SD_NPKT 32
+ for (n = 0; n < 4; n++) {
+ i = n & 1 ? 0 : 1;
+ packet_size =
+ le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize);
+ urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
+ if (!urb) {
+ err("usb_alloc_urb failed");
+ return -ENOMEM;
+ }
+ gspca_dev->urb[n] = urb;
+ urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
+ packet_size * SD_NPKT,
+ GFP_KERNEL,
+ &urb->transfer_dma);
+ if (urb->transfer_buffer == NULL) {
+ err("usb_buffer_alloc failed");
+ return -ENOMEM;
+ }
+
+ urb->dev = gspca_dev->dev;
+ urb->context = gspca_dev;
+ urb->transfer_buffer_length = packet_size * SD_NPKT;
+ urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
+ n & 1 ? 0x81 : 0x82);
+ urb->transfer_flags = URB_ISO_ASAP
+ | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = 1;
+ urb->complete = sd_isoc_irq;
+ urb->number_of_packets = SD_NPKT;
+ for (i = 0; i < SD_NPKT; i++) {
+ urb->iso_frame_desc[i].length = packet_size;
+ urb->iso_frame_desc[i].offset = packet_size * i;
+ }
+ }
+
+ return 0;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ konica_stream_off(gspca_dev);
+#ifdef CONFIG_INPUT
+ /* Don't keep the button in the pressed state "forever" if it was
+ pressed when streaming is stopped */
+ if (sd->snapshot_pressed) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+ input_sync(gspca_dev->input_dev);
+ sd->snapshot_pressed = 0;
+ }
+#endif
+}
+
+/* reception of an URB */
+static void sd_isoc_irq(struct urb *urb)
+{
+ struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct urb *data_urb, *status_urb;
+ u8 *data;
+ int i, st;
+
+ PDEBUG(D_PACK, "sd isoc irq");
+ if (!gspca_dev->streaming)
+ return;
+
+ if (urb->status != 0) {
+ if (urb->status == -ESHUTDOWN)
+ return; /* disconnection */
+#ifdef CONFIG_PM
+ if (gspca_dev->frozen)
+ return;
+#endif
+ PDEBUG(D_ERR, "urb status: %d", urb->status);
+ st = usb_submit_urb(urb, GFP_ATOMIC);
+ if (st < 0)
+ PDEBUG(D_ERR|D_PACK, "resubmit urb error %d", st);
+ return;
+ }
+
+ /* if this is a data URB (ep 0x82), wait */
+ if (urb->transfer_buffer_length > 32) {
+ sd->last_data_urb = urb;
+ return;
+ }
+
+ status_urb = urb;
+ data_urb = sd->last_data_urb;
+ sd->last_data_urb = NULL;
+
+ if (!data_urb || data_urb->start_frame != status_urb->start_frame) {
+ PDEBUG(D_ERR|D_PACK, "lost sync on frames");
+ goto resubmit;
+ }
+
+ if (data_urb->number_of_packets != status_urb->number_of_packets) {
+ PDEBUG(D_ERR|D_PACK,
+ "no packets does not match, data: %d, status: %d",
+ data_urb->number_of_packets,
+ status_urb->number_of_packets);
+ goto resubmit;
+ }
+
+ for (i = 0; i < status_urb->number_of_packets; i++) {
+ if (data_urb->iso_frame_desc[i].status ||
+ status_urb->iso_frame_desc[i].status) {
+ PDEBUG(D_ERR|D_PACK,
+ "pkt %d data-status %d, status-status %d", i,
+ data_urb->iso_frame_desc[i].status,
+ status_urb->iso_frame_desc[i].status);
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ continue;
+ }
+
+ if (status_urb->iso_frame_desc[i].actual_length != 1) {
+ PDEBUG(D_ERR|D_PACK,
+ "bad status packet length %d",
+ status_urb->iso_frame_desc[i].actual_length);
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ continue;
+ }
+
+ st = *((u8 *)status_urb->transfer_buffer
+ + status_urb->iso_frame_desc[i].offset);
+
+ data = (u8 *)data_urb->transfer_buffer
+ + data_urb->iso_frame_desc[i].offset;
+
+ /* st: 0x80-0xff: frame start with frame number (ie 0-7f)
+ * otherwise:
+ * bit 0 0: keep packet
+ * 1: drop packet (padding data)
+ *
+ * bit 4 0 button not clicked
+ * 1 button clicked
+ * button is used to `take a picture' (in software)
+ */
+ if (st & 0x80) {
+ gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
+ } else {
+#ifdef CONFIG_INPUT
+ u8 button_state = st & 0x40 ? 1 : 0;
+ if (sd->snapshot_pressed != button_state) {
+ input_report_key(gspca_dev->input_dev,
+ KEY_CAMERA,
+ button_state);
+ input_sync(gspca_dev->input_dev);
+ sd->snapshot_pressed = button_state;
+ }
+#endif
+ if (st & 0x01)
+ continue;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, data,
+ data_urb->iso_frame_desc[i].actual_length);
+ }
+
+resubmit:
+ if (data_urb) {
+ st = usb_submit_urb(data_urb, GFP_ATOMIC);
+ if (st < 0)
+ PDEBUG(D_ERR|D_PACK,
+ "usb_submit_urb(data_urb) ret %d", st);
+ }
+ st = usb_submit_urb(status_urb, GFP_ATOMIC);
+ if (st < 0)
+ PDEBUG(D_ERR|D_PACK, "usb_submit_urb(status_urb) ret %d", st);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
+ konica_stream_on(gspca_dev);
+ }
+
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming) {
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, sd->contrast, CONTRAST_REG);
+ konica_stream_on(gspca_dev);
+ }
+
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+
+ return 0;
+}
+
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->saturation = val;
+ if (gspca_dev->streaming) {
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, sd->saturation, SATURATION_REG);
+ konica_stream_on(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->saturation;
+
+ return 0;
+}
+
+static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->whitebal = val;
+ if (gspca_dev->streaming) {
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG);
+ konica_stream_on(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->whitebal;
+
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG);
+ konica_stream_on(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+#ifdef CONFIG_INPUT
+ .other_input = 1,
+#endif
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ info("registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 33744e724eaa..ccedf23300d4 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -9,14 +9,14 @@
* is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
*
* Support for the control settings for the CIF cameras is
- * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com> and
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and
* Thomas Kaiser <thomas@kaiser-linux.li>
*
* Support for the control settings for the VGA cameras is
* Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
*
* Several previously unsupported cameras are owned and have been tested by
- * Hans de Goede <hdgoede@redhat.com> and
+ * Hans de Goede <hdegoede@redhat.com> and
* Thomas Kaiser <thomas@kaiser-linux.li> and
* Theodore Kilgore <kilgota@auburn.edu> and
* Edmond Rodriguez <erodrig_97@yahoo.com> and
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index a40f8893310d..25671a6f3eec 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -1,7 +1,7 @@
/*
* Pixart PAC207BCA library
*
- * Copyright (C) 2008 Hans de Goede <hdgoede@redhat.com>
+ * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com>
* Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
* Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
*
@@ -28,7 +28,7 @@
#include <linux/input.h>
#include "gspca.h"
-MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Pixart PAC207");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c
index e50dd7693f74..8a363d5e1436 100644
--- a/drivers/media/video/gspca/stv0680.c
+++ b/drivers/media/video/gspca/stv0680.c
@@ -1,7 +1,7 @@
/*
* STV0680 USB Camera Driver
*
- * Copyright (C) 2009 Hans de Goede <hdgoede@redhat.com>
+ * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
*
* This module is adapted from the in kernel v4l1 stv680 driver:
*
@@ -31,7 +31,7 @@
#include "gspca.h"
-MODULE_AUTHOR("Hans de Goede <hdgoede@redhat.com>");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("STV0680 USB Camera Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
new file mode 100644
index 000000000000..e4424c6f7a69
--- /dev/null
+++ b/drivers/media/video/gspca/xirlink_cit.c
@@ -0,0 +1,3260 @@
+/*
+ * USB IBM C-It Video Camera driver
+ *
+ * Supports Xirlink C-It Video Camera, IBM PC Camera,
+ * IBM NetCamera and Veo Stingray.
+ *
+ * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This driver is based on earlier work of:
+ *
+ * (C) Copyright 1999 Johannes Erdfelt
+ * (C) Copyright 1999 Randy Dunlap
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define MODULE_NAME "xirlink-cit"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_DESCRIPTION("Xirlink C-IT");
+MODULE_LICENSE("GPL");
+
+/* FIXME we should autodetect this */
+static int ibm_netcam_pro;
+module_param(ibm_netcam_pro, int, 0);
+MODULE_PARM_DESC(ibm_netcam_pro,
+ "Use IBM Netcamera Pro init sequences for Model 3 cams");
+
+/* FIXME this should be handled through the V4L2 input selection API */
+static int rca_input;
+module_param(rca_input, int, 0644);
+MODULE_PARM_DESC(rca_input,
+ "Use rca input instead of ccd sensor on Model 3 cams");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ u8 model;
+#define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
+#define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
+#define CIT_MODEL2 2 /* ibmcam driver */
+#define CIT_MODEL3 3
+#define CIT_MODEL4 4
+#define CIT_IBM_NETCAM_PRO 5
+ u8 input_index;
+ u8 stop_on_control_change;
+ u8 sof_read;
+ u8 sof_len;
+ u8 contrast;
+ u8 brightness;
+ u8 hue;
+ u8 sharpness;
+ u8 lighting;
+ u8 hflip;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
+static void sd_stop0(struct gspca_dev *gspca_dev);
+
+static const struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+#define BRIGHTNESS_DEFAULT 32
+ .default_value = BRIGHTNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "contrast",
+ .minimum = 0,
+ .maximum = 20,
+ .step = 1,
+#define CONTRAST_DEFAULT 10
+ .default_value = CONTRAST_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_HUE 2
+ {
+ {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+#define HUE_DEFAULT 63
+ .default_value = HUE_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_sethue,
+ .get = sd_gethue,
+ },
+#define SD_SHARPNESS 3
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 6,
+ .step = 1,
+#define SHARPNESS_DEFAULT 3
+ .default_value = SHARPNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
+#define SD_LIGHTING 4
+ {
+ {
+ .id = V4L2_CID_BACKLIGHT_COMPENSATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Lighting",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+#define LIGHTING_DEFAULT 1
+ .default_value = LIGHTING_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setlighting,
+ .get = sd_getlighting,
+ },
+#define SD_HFLIP 5
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define HFLIP_DEFAULT 0
+ .default_value = HFLIP_DEFAULT,
+ },
+ .set = sd_sethflip,
+ .get = sd_gethflip,
+ },
+};
+
+static const struct v4l2_pix_format cif_yuv_mode[] = {
+ {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+};
+
+static const struct v4l2_pix_format vga_yuv_mode[] = {
+ {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+};
+
+static const struct v4l2_pix_format model0_mode[] = {
+ {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+};
+
+static const struct v4l2_pix_format model2_mode[] = {
+ {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+ {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB},
+};
+
+/*
+ * 01.01.08 - Added for RCA video in support -LO
+ * This struct is used to init the Model3 cam to use the RCA video in port
+ * instead of the CCD sensor.
+ */
+static const u16 rca_initdata[][3] = {
+ {0, 0x0000, 0x010c},
+ {0, 0x0006, 0x012c},
+ {0, 0x0078, 0x012d},
+ {0, 0x0046, 0x012f},
+ {0, 0xd141, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfea8, 0x0124},
+ {1, 0x0000, 0x0116},
+ {0, 0x0064, 0x0116},
+ {1, 0x0000, 0x0115},
+ {0, 0x0003, 0x0115},
+ {0, 0x0008, 0x0123},
+ {0, 0x0000, 0x0117},
+ {0, 0x0000, 0x0112},
+ {0, 0x0080, 0x0100},
+ {0, 0x0000, 0x0100},
+ {1, 0x0000, 0x0116},
+ {0, 0x0060, 0x0116},
+ {0, 0x0002, 0x0112},
+ {0, 0x0000, 0x0123},
+ {0, 0x0001, 0x0117},
+ {0, 0x0040, 0x0108},
+ {0, 0x0019, 0x012c},
+ {0, 0x0040, 0x0116},
+ {0, 0x000a, 0x0115},
+ {0, 0x000b, 0x0115},
+ {0, 0x0078, 0x012d},
+ {0, 0x0046, 0x012f},
+ {0, 0xd141, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfea8, 0x0124},
+ {0, 0x0064, 0x0116},
+ {0, 0x0000, 0x0115},
+ {0, 0x0001, 0x0115},
+ {0, 0xffff, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00aa, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xffff, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00f2, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x000f, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xffff, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00f8, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00fc, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xffff, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00f9, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x003c, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xffff, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0027, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0019, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0021, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0006, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0045, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002a, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x000e, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002b, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00f4, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002c, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0004, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002d, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0014, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002e, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0003, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x002f, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0003, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0014, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0053, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0x0000, 0x0101},
+ {0, 0x00a0, 0x0103},
+ {0, 0x0078, 0x0105},
+ {0, 0x0000, 0x010a},
+ {0, 0x0024, 0x010b},
+ {0, 0x0028, 0x0119},
+ {0, 0x0088, 0x011b},
+ {0, 0x0002, 0x011d},
+ {0, 0x0003, 0x011e},
+ {0, 0x0000, 0x0129},
+ {0, 0x00fc, 0x012b},
+ {0, 0x0008, 0x0102},
+ {0, 0x0000, 0x0104},
+ {0, 0x0008, 0x011a},
+ {0, 0x0028, 0x011c},
+ {0, 0x0021, 0x012a},
+ {0, 0x0000, 0x0118},
+ {0, 0x0000, 0x0132},
+ {0, 0x0000, 0x0109},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0031, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x00dc, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0032, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0020, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0001, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0040, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0037, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0030, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0xfff9, 0x0124},
+ {0, 0x0086, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0038, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0008, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0x0000, 0x0127},
+ {0, 0xfff8, 0x0124},
+ {0, 0xfffd, 0x0124},
+ {0, 0xfffa, 0x0124},
+ {0, 0x0003, 0x0111},
+};
+
+/* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
+ do the same for now (testing needed to see if this is really necessary) */
+static const int cit_model1_ntries = 5;
+static const int cit_model1_ntries2 = 2;
+
+static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int err;
+
+ err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
+ value, index, NULL, 0, 1000);
+ if (err < 0)
+ PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
+ " value 0x%02X, error %d)", index, value, err);
+
+ return 0;
+}
+
+static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ __u8 *buf = gspca_dev->usb_buf;
+ int res;
+
+ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
+ 0x00, index, buf, 8, 1000);
+ if (res < 0) {
+ PDEBUG(D_ERR,
+ "Failed to read a register (index 0x%04X, error %d)",
+ index, res);
+ return res;
+ }
+
+ PDEBUG(D_PROBE,
+ "Register %04x value: %02x %02x %02x %02x %02x %02x %02x %02x",
+ index,
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+
+ return 0;
+}
+
+/*
+ * cit_send_FF_04_02()
+ *
+ * This procedure sends magic 3-command prefix to the camera.
+ * The purpose of this prefix is not known.
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
+{
+ cit_write_reg(gspca_dev, 0x00FF, 0x0127);
+ cit_write_reg(gspca_dev, 0x0004, 0x0124);
+ cit_write_reg(gspca_dev, 0x0002, 0x0124);
+}
+
+static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
+{
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0x0004, 0x0124);
+ cit_write_reg(gspca_dev, 0x0006, 0x0124);
+}
+
+static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
+{
+ cit_write_reg(gspca_dev, x, 0x0127);
+ cit_write_reg(gspca_dev, 0x0000, 0x0124);
+}
+
+static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
+{
+ cit_send_x_00(gspca_dev, x);
+ cit_write_reg(gspca_dev, 0x0005, 0x0124);
+}
+
+static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
+{
+ cit_write_reg(gspca_dev, x, 0x0127);
+ cit_write_reg(gspca_dev, 0x0000, 0x0124);
+ cit_write_reg(gspca_dev, 0x0005, 0x0124);
+ cit_write_reg(gspca_dev, 0x0002, 0x0124);
+}
+
+static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
+{
+ cit_write_reg(gspca_dev, x, 0x0127);
+ cit_write_reg(gspca_dev, 0x0001, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0124);
+ cit_write_reg(gspca_dev, 0x0005, 0x0124);
+}
+
+static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
+{
+ cit_write_reg(gspca_dev, x, 0x0127);
+ cit_write_reg(gspca_dev, 0x0000, 0x0124);
+ cit_write_reg(gspca_dev, 0x0005, 0x0124);
+ cit_write_reg(gspca_dev, 0x0002, 0x0124);
+ cit_write_reg(gspca_dev, 0x0001, 0x0124);
+}
+
+static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
+{
+ cit_write_reg(gspca_dev, x, 0x0127);
+ cit_write_reg(gspca_dev, 0x0000, 0x0124);
+ cit_write_reg(gspca_dev, 0x0005, 0x0124);
+ cit_write_reg(gspca_dev, 0x0002, 0x0124);
+ cit_write_reg(gspca_dev, 0x0008, 0x0124);
+ cit_write_reg(gspca_dev, 0x0001, 0x0124);
+}
+
+static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
+{
+ cit_send_x_01_00_05(gspca_dev, 0x0088);
+ cit_send_x_00_05(gspca_dev, fkey);
+ cit_send_x_00_05_02_08_01(gspca_dev, val);
+ cit_send_x_00_05(gspca_dev, 0x0088);
+ cit_send_x_00_05_02_01(gspca_dev, fkey);
+ cit_send_x_00_05(gspca_dev, 0x0089);
+ cit_send_x_00(gspca_dev, fkey);
+ cit_send_00_04_06(gspca_dev);
+ cit_read_reg(gspca_dev, 0x0126);
+ cit_send_FF_04_02(gspca_dev);
+}
+
+static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
+{
+ cit_send_x_01_00_05(gspca_dev, 0x0088);
+ cit_send_x_00_05(gspca_dev, fkey);
+ cit_send_x_00_05_02(gspca_dev, val);
+}
+
+static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
+{
+ cit_write_reg(gspca_dev, 0x00ff, 0x012d);
+ cit_write_reg(gspca_dev, 0xfea3, 0x0124);
+}
+
+static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
+{
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x00ff, 0x012e);
+ cit_write_reg(gspca_dev, v1, 0x012f);
+ cit_write_reg(gspca_dev, 0x00ff, 0x0130);
+ cit_write_reg(gspca_dev, 0xc719, 0x0124);
+ cit_write_reg(gspca_dev, v2, 0x0127);
+
+ cit_model2_Packet2(gspca_dev);
+}
+
+/*
+ * cit_model3_Packet1()
+ *
+ * 00_0078_012d
+ * 00_0097_012f
+ * 00_d141_0124
+ * 00_0096_0127
+ * 00_fea8_0124
+*/
+static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
+{
+ cit_write_reg(gspca_dev, 0x0078, 0x012d);
+ cit_write_reg(gspca_dev, v1, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, v2, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+}
+
+static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
+{
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, v1, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, v2, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+}
+
+static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
+{
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0026, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, val, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0038, 0x012d);
+ cit_write_reg(gspca_dev, 0x0004, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ sd->model = id->driver_info;
+ if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
+ sd->model = CIT_IBM_NETCAM_PRO;
+
+ cam = &gspca_dev->cam;
+ switch (sd->model) {
+ case CIT_MODEL0:
+ cam->cam_mode = model0_mode;
+ cam->nmodes = ARRAY_SIZE(model0_mode);
+ cam->reverse_alts = 1;
+ gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP));
+ sd->sof_len = 4;
+ break;
+ case CIT_MODEL1:
+ cam->cam_mode = cif_yuv_mode;
+ cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
+ cam->reverse_alts = 1;
+ gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP);
+ sd->sof_len = 4;
+ break;
+ case CIT_MODEL2:
+ cam->cam_mode = model2_mode + 1; /* no 160x120 */
+ cam->nmodes = 3;
+ gspca_dev->ctrl_dis = (1 << SD_CONTRAST) |
+ (1 << SD_SHARPNESS) |
+ (1 << SD_HFLIP);
+ break;
+ case CIT_MODEL3:
+ cam->cam_mode = vga_yuv_mode;
+ cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
+ gspca_dev->ctrl_dis = (1 << SD_HUE) |
+ (1 << SD_LIGHTING) |
+ (1 << SD_HFLIP);
+ sd->stop_on_control_change = 1;
+ sd->sof_len = 4;
+ break;
+ case CIT_MODEL4:
+ cam->cam_mode = model2_mode;
+ cam->nmodes = ARRAY_SIZE(model2_mode);
+ gspca_dev->ctrl_dis = (1 << SD_CONTRAST) |
+ (1 << SD_SHARPNESS) |
+ (1 << SD_LIGHTING) |
+ (1 << SD_HFLIP);
+ break;
+ case CIT_IBM_NETCAM_PRO:
+ cam->cam_mode = vga_yuv_mode;
+ cam->nmodes = 2; /* no 640 x 480 */
+ cam->input_flags = V4L2_IN_ST_VFLIP;
+ gspca_dev->ctrl_dis = ~(1 << SD_CONTRAST);
+ sd->stop_on_control_change = 1;
+ sd->sof_len = 4;
+ break;
+ }
+
+ sd->brightness = BRIGHTNESS_DEFAULT;
+ sd->contrast = CONTRAST_DEFAULT;
+ sd->hue = HUE_DEFAULT;
+ sd->sharpness = SHARPNESS_DEFAULT;
+ sd->lighting = LIGHTING_DEFAULT;
+ sd->hflip = HFLIP_DEFAULT;
+
+ return 0;
+}
+
+static int cit_init_model0(struct gspca_dev *gspca_dev)
+{
+ cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
+ cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
+ cit_write_reg(gspca_dev, 0x0000, 0x0400);
+ cit_write_reg(gspca_dev, 0x0001, 0x0400);
+ cit_write_reg(gspca_dev, 0x0000, 0x0420);
+ cit_write_reg(gspca_dev, 0x0001, 0x0420);
+ cit_write_reg(gspca_dev, 0x000d, 0x0409);
+ cit_write_reg(gspca_dev, 0x0002, 0x040a);
+ cit_write_reg(gspca_dev, 0x0018, 0x0405);
+ cit_write_reg(gspca_dev, 0x0008, 0x0435);
+ cit_write_reg(gspca_dev, 0x0026, 0x040b);
+ cit_write_reg(gspca_dev, 0x0007, 0x0437);
+ cit_write_reg(gspca_dev, 0x0015, 0x042f);
+ cit_write_reg(gspca_dev, 0x002b, 0x0439);
+ cit_write_reg(gspca_dev, 0x0026, 0x043a);
+ cit_write_reg(gspca_dev, 0x0008, 0x0438);
+ cit_write_reg(gspca_dev, 0x001e, 0x042b);
+ cit_write_reg(gspca_dev, 0x0041, 0x042c);
+
+ return 0;
+}
+
+static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
+{
+ cit_read_reg(gspca_dev, 0x128);
+ cit_write_reg(gspca_dev, 0x0003, 0x0133);
+ cit_write_reg(gspca_dev, 0x0000, 0x0117);
+ cit_write_reg(gspca_dev, 0x0008, 0x0123);
+ cit_write_reg(gspca_dev, 0x0000, 0x0100);
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ cit_write_reg(gspca_dev, 0x0002, 0x0112);
+ cit_write_reg(gspca_dev, 0x0000, 0x0133);
+ cit_write_reg(gspca_dev, 0x0000, 0x0123);
+ cit_write_reg(gspca_dev, 0x0001, 0x0117);
+ cit_write_reg(gspca_dev, 0x0040, 0x0108);
+ cit_write_reg(gspca_dev, 0x0019, 0x012c);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ cit_write_reg(gspca_dev, 0x0002, 0x0115);
+ cit_write_reg(gspca_dev, 0x000b, 0x0115);
+
+ cit_write_reg(gspca_dev, 0x0078, 0x012d);
+ cit_write_reg(gspca_dev, 0x0001, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0079, 0x012d);
+ cit_write_reg(gspca_dev, 0x00ff, 0x0130);
+ cit_write_reg(gspca_dev, 0xcd41, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_read_reg(gspca_dev, 0x0126);
+
+ cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
+ cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
+ cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
+ cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
+ cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
+ cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
+ cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
+ cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
+ cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
+ cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
+ cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
+ cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
+ cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
+ cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
+ cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
+ cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
+ cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
+ cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
+ cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
+ cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
+ cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
+ cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
+ cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
+ cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
+ cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
+ cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
+ cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
+ cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
+ cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
+ cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
+ cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
+ cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
+ cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
+ cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
+ cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
+ cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
+ cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
+ cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
+ cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
+ cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
+ cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
+ cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
+ cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
+ cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
+ cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
+ cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
+ cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
+ cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
+ cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
+
+ cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
+ cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
+ cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
+ cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
+ cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
+ cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
+ cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
+ cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
+ cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
+ cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
+ cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
+ cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
+ cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
+ cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
+
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ cit_init_model0(gspca_dev);
+ sd_stop0(gspca_dev);
+ break;
+ case CIT_MODEL1:
+ case CIT_MODEL2:
+ case CIT_MODEL3:
+ case CIT_MODEL4:
+ break; /* All is done in sd_start */
+ case CIT_IBM_NETCAM_PRO:
+ cit_init_ibm_netcam_pro(gspca_dev);
+ sd_stop0(gspca_dev);
+ break;
+ }
+ return 0;
+}
+
+static int cit_set_brightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_IBM_NETCAM_PRO:
+ /* No (known) brightness control for these */
+ break;
+ case CIT_MODEL1:
+ /* Model 1: Brightness range 0 - 63 */
+ cit_Packet_Format1(gspca_dev, 0x0031, sd->brightness);
+ cit_Packet_Format1(gspca_dev, 0x0032, sd->brightness);
+ cit_Packet_Format1(gspca_dev, 0x0033, sd->brightness);
+ break;
+ case CIT_MODEL2:
+ /* Model 2: Brightness range 0x60 - 0xee */
+ /* Scale 0 - 63 to 0x60 - 0xee */
+ i = 0x60 + sd->brightness * 2254 / 1000;
+ cit_model2_Packet1(gspca_dev, 0x001a, i);
+ break;
+ case CIT_MODEL3:
+ /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
+ i = sd->brightness;
+ if (i < 0x0c)
+ i = 0x0c;
+ cit_model3_Packet1(gspca_dev, 0x0036, i);
+ break;
+ case CIT_MODEL4:
+ /* Model 4: Brightness range 'i' in [0x04..0xb4] */
+ /* Scale 0 - 63 to 0x04 - 0xb4 */
+ i = 0x04 + sd->brightness * 2794 / 1000;
+ cit_model4_BrightnessPacket(gspca_dev, i);
+ break;
+ }
+
+ return 0;
+}
+
+static int cit_set_contrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0: {
+ int i;
+ /* gain 0-15, 0-20 -> 0-15 */
+ i = sd->contrast * 1000 / 1333;
+ cit_write_reg(gspca_dev, i, 0x0422);
+ /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
+ i = sd->contrast * 2000 / 1333;
+ cit_write_reg(gspca_dev, i, 0x0423);
+ /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */
+ i = sd->contrast * 4000 / 1333;
+ cit_write_reg(gspca_dev, i, 0x0424);
+ /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
+ i = sd->contrast * 8000 / 1333;
+ cit_write_reg(gspca_dev, i, 0x0425);
+ break;
+ }
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ /* These models do not have this control. */
+ break;
+ case CIT_MODEL1:
+ {
+ /* Scale 0 - 20 to 15 - 0 */
+ int i, new_contrast = (20 - sd->contrast) * 1000 / 1333;
+ for (i = 0; i < cit_model1_ntries; i++) {
+ cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
+ cit_send_FF_04_02(gspca_dev);
+ }
+ break;
+ }
+ case CIT_MODEL3:
+ { /* Preset hardware values */
+ static const struct {
+ unsigned short cv1;
+ unsigned short cv2;
+ unsigned short cv3;
+ } cv[7] = {
+ { 0x05, 0x05, 0x0f }, /* Minimum */
+ { 0x04, 0x04, 0x16 },
+ { 0x02, 0x03, 0x16 },
+ { 0x02, 0x08, 0x16 },
+ { 0x01, 0x0c, 0x16 },
+ { 0x01, 0x0e, 0x16 },
+ { 0x01, 0x10, 0x16 } /* Maximum */
+ };
+ int i = sd->contrast / 3;
+ cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
+ cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
+ cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
+ break;
+ }
+ case CIT_IBM_NETCAM_PRO:
+ cit_model3_Packet1(gspca_dev, 0x005b, sd->contrast + 1);
+ break;
+ }
+ return 0;
+}
+
+static int cit_set_hue(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_MODEL1:
+ case CIT_IBM_NETCAM_PRO:
+ /* No hue control for these models */
+ break;
+ case CIT_MODEL2:
+ cit_model2_Packet1(gspca_dev, 0x0024, sd->hue);
+ /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
+ break;
+ case CIT_MODEL3: {
+ /* Model 3: Brightness range 'i' in [0x05..0x37] */
+ /* TESTME according to the ibmcam driver this does not work */
+ if (0) {
+ /* Scale 0 - 127 to 0x05 - 0x37 */
+ int i = 0x05 + sd->hue * 1000 / 2540;
+ cit_model3_Packet1(gspca_dev, 0x007e, i);
+ }
+ break;
+ }
+ case CIT_MODEL4:
+ /* HDG: taken from ibmcam, setting the color gains does not
+ * really belong here.
+ *
+ * I am not sure r/g/b_gain variables exactly control gain
+ * of those channels. Most likely they subtly change some
+ * very internal image processing settings in the camera.
+ * In any case, here is what they do, and feel free to tweak:
+ *
+ * r_gain: seriously affects red gain
+ * g_gain: seriously affects green gain
+ * b_gain: seriously affects blue gain
+ * hue: changes average color from violet (0) to red (0xFF)
+ */
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 160, 0x0127); /* Green gain */
+ cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */
+ cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, sd->hue, 0x012d); /* Hue */
+ cit_write_reg(gspca_dev, 0xf545, 0x0124);
+ break;
+ }
+ return 0;
+}
+
+static int cit_set_sharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ case CIT_IBM_NETCAM_PRO:
+ /* These models do not have this control */
+ break;
+ case CIT_MODEL1: {
+ int i;
+ const unsigned short sa[] = {
+ 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
+
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_PacketFormat2(gspca_dev, 0x0013, sa[sd->sharpness]);
+ break;
+ }
+ case CIT_MODEL3:
+ { /*
+ * "Use a table of magic numbers.
+ * This setting doesn't really change much.
+ * But that's how Windows does it."
+ */
+ static const struct {
+ unsigned short sv1;
+ unsigned short sv2;
+ unsigned short sv3;
+ unsigned short sv4;
+ } sv[7] = {
+ { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
+ { 0x01, 0x04, 0x05, 0x14 },
+ { 0x02, 0x04, 0x05, 0x14 },
+ { 0x03, 0x04, 0x05, 0x14 },
+ { 0x03, 0x05, 0x05, 0x14 },
+ { 0x03, 0x06, 0x05, 0x14 },
+ { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
+ };
+ cit_model3_Packet1(gspca_dev, 0x0060, sv[sd->sharpness].sv1);
+ cit_model3_Packet1(gspca_dev, 0x0061, sv[sd->sharpness].sv2);
+ cit_model3_Packet1(gspca_dev, 0x0062, sv[sd->sharpness].sv3);
+ cit_model3_Packet1(gspca_dev, 0x0063, sv[sd->sharpness].sv4);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * cit_set_lighting()
+ *
+ * Camera model 1:
+ * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
+ *
+ * Camera model 2:
+ * We have 16 levels of lighting, 0 for bright light and up to 15 for
+ * low light. But values above 5 or so are useless because camera is
+ * not really capable to produce anything worth viewing at such light.
+ * This setting may be altered only in certain camera state.
+ *
+ * Low lighting forces slower FPS.
+ *
+ * History:
+ * 1/5/00 Created.
+ * 2/20/00 Added support for Model 2 cameras.
+ */
+static void cit_set_lighting(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_MODEL2:
+ case CIT_MODEL3:
+ case CIT_MODEL4:
+ case CIT_IBM_NETCAM_PRO:
+ break;
+ case CIT_MODEL1: {
+ int i;
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting);
+ break;
+ }
+ }
+}
+
+static void cit_set_hflip(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ if (sd->hflip)
+ cit_write_reg(gspca_dev, 0x0020, 0x0115);
+ else
+ cit_write_reg(gspca_dev, 0x0040, 0x0115);
+ break;
+ case CIT_MODEL1:
+ case CIT_MODEL2:
+ case CIT_MODEL3:
+ case CIT_MODEL4:
+ case CIT_IBM_NETCAM_PRO:
+ break;
+ }
+}
+
+static int cit_restart_stream(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_MODEL1:
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ cit_write_reg(gspca_dev, 0x0001, 0x0114);
+ /* Fall through */
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
+ /* This happens repeatedly while streaming with the ibm netcam
+ pro and the ibmcam driver did it for model3 after changing
+ settings, but it does not seem to have any effect. */
+ /* cit_write_reg(gspca_dev, 0x0001, 0x0113); */
+ break;
+ }
+
+ sd->sof_read = 0;
+
+ return 0;
+}
+
+static int cit_get_packet_size(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
+
+ intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
+ alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
+ if (!alt) {
+ PDEBUG(D_ERR, "Couldn't get altsetting");
+ return -EIO;
+ }
+
+ return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+}
+
+/* Calculate the clockdiv giving us max fps given the available bandwidth */
+static int cit_get_clock_div(struct gspca_dev *gspca_dev)
+{
+ int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
+ int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
+ int packet_size;
+
+ packet_size = cit_get_packet_size(gspca_dev);
+ if (packet_size < 0)
+ return packet_size;
+
+ while (clock_div > 3 &&
+ 1000 * packet_size >
+ gspca_dev->width * gspca_dev->height *
+ fps[clock_div - 1] * 3 / 2)
+ clock_div--;
+
+ PDEBUG(D_PROBE,
+ "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)",
+ packet_size, gspca_dev->width, gspca_dev->height, clock_div,
+ fps[clock_div]);
+
+ return clock_div;
+}
+
+static int cit_start_model0(struct gspca_dev *gspca_dev)
+{
+ const unsigned short compression = 0; /* 0=none, 7=best frame rate */
+ int clock_div;
+
+ clock_div = cit_get_clock_div(gspca_dev);
+ if (clock_div < 0)
+ return clock_div;
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
+ cit_write_reg(gspca_dev, 0x0003, 0x0438);
+ cit_write_reg(gspca_dev, 0x001e, 0x042b);
+ cit_write_reg(gspca_dev, 0x0041, 0x042c);
+ cit_write_reg(gspca_dev, 0x0008, 0x0436);
+ cit_write_reg(gspca_dev, 0x0024, 0x0403);
+ cit_write_reg(gspca_dev, 0x002c, 0x0404);
+ cit_write_reg(gspca_dev, 0x0002, 0x0426);
+ cit_write_reg(gspca_dev, 0x0014, 0x0427);
+
+ switch (gspca_dev->width) {
+ case 160: /* 160x120 */
+ cit_write_reg(gspca_dev, 0x0004, 0x010b);
+ cit_write_reg(gspca_dev, 0x0001, 0x010a);
+ cit_write_reg(gspca_dev, 0x0010, 0x0102);
+ cit_write_reg(gspca_dev, 0x00a0, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x0078, 0x0105);
+ break;
+
+ case 176: /* 176x144 */
+ cit_write_reg(gspca_dev, 0x0006, 0x010b);
+ cit_write_reg(gspca_dev, 0x0000, 0x010a);
+ cit_write_reg(gspca_dev, 0x0005, 0x0102);
+ cit_write_reg(gspca_dev, 0x00b0, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x0090, 0x0105);
+ break;
+
+ case 320: /* 320x240 */
+ cit_write_reg(gspca_dev, 0x0008, 0x010b);
+ cit_write_reg(gspca_dev, 0x0004, 0x010a);
+ cit_write_reg(gspca_dev, 0x0005, 0x0102);
+ cit_write_reg(gspca_dev, 0x00a0, 0x0103);
+ cit_write_reg(gspca_dev, 0x0010, 0x0104);
+ cit_write_reg(gspca_dev, 0x0078, 0x0105);
+ break;
+ }
+
+ cit_write_reg(gspca_dev, compression, 0x0109);
+ cit_write_reg(gspca_dev, clock_div, 0x0111);
+
+ return 0;
+}
+
+static int cit_start_model1(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, clock_div;
+
+ clock_div = cit_get_clock_div(gspca_dev);
+ if (clock_div < 0)
+ return clock_div;
+
+ cit_read_reg(gspca_dev, 0x0128);
+ cit_read_reg(gspca_dev, 0x0100);
+ cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
+ cit_read_reg(gspca_dev, 0x0100);
+ cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
+ cit_read_reg(gspca_dev, 0x0100);
+ cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
+ cit_write_reg(gspca_dev, 0x01, 0x0108);
+
+ cit_write_reg(gspca_dev, 0x03, 0x0112);
+ cit_read_reg(gspca_dev, 0x0115);
+ cit_write_reg(gspca_dev, 0x06, 0x0115);
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x44, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x40, 0x0116);
+ cit_read_reg(gspca_dev, 0x0115);
+ cit_write_reg(gspca_dev, 0x0e, 0x0115);
+ cit_write_reg(gspca_dev, 0x19, 0x012c);
+
+ cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
+ cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
+ cit_Packet_Format1(gspca_dev, 0x39, 0x09);
+ cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
+ cit_Packet_Format1(gspca_dev, 0x28, 0x22);
+ cit_Packet_Format1(gspca_dev, 0x27, 0x00);
+ cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
+ cit_Packet_Format1(gspca_dev, 0x39, 0x08);
+
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
+
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x30, 0x14);
+
+ cit_PacketFormat2(gspca_dev, 0x39, 0x02);
+ cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
+ cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
+ cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
+ cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
+ cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
+ cit_PacketFormat2(gspca_dev, 0x39, 0x00);
+
+ cit_PacketFormat2(gspca_dev, 0x39, 0x02);
+ cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
+ cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
+ cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
+ cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
+ cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
+ cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
+ cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
+ cit_PacketFormat2(gspca_dev, 0x11, 0xba);
+ cit_PacketFormat2(gspca_dev, 0x12, 0x53);
+ cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
+ cit_PacketFormat2(gspca_dev, 0x39, 0x00);
+
+ cit_PacketFormat2(gspca_dev, 0x39, 0x02);
+ cit_PacketFormat2(gspca_dev, 0x16, 0x00);
+ cit_PacketFormat2(gspca_dev, 0x17, 0x28);
+ cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
+ cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
+ cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
+ cit_PacketFormat2(gspca_dev, 0x39, 0x00);
+
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x00, 0x18);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x13, 0x18);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x14, 0x06);
+
+ /* TESTME These are handled through controls
+ KEEP until someone can test leaving this out is ok */
+ if (0) {
+ /* This is default brightness */
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x31, 0x37);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x32, 0x46);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x33, 0x55);
+ }
+
+ cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x29, 0x80);
+ cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
+ cit_Packet_Format1(gspca_dev, 0x30, 0x17);
+ cit_Packet_Format1(gspca_dev, 0x39, 0x08);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x34, 0x00);
+
+ cit_write_reg(gspca_dev, 0x00, 0x0101);
+ cit_write_reg(gspca_dev, 0x00, 0x010a);
+
+ switch (gspca_dev->width) {
+ case 128: /* 128x96 */
+ cit_write_reg(gspca_dev, 0x80, 0x0103);
+ cit_write_reg(gspca_dev, 0x60, 0x0105);
+ cit_write_reg(gspca_dev, 0x0c, 0x010b);
+ cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x0b, 0x011d);
+ cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x00, 0x0129);
+ break;
+ case 176: /* 176x144 */
+ cit_write_reg(gspca_dev, 0xb0, 0x0103);
+ cit_write_reg(gspca_dev, 0x8f, 0x0105);
+ cit_write_reg(gspca_dev, 0x06, 0x010b);
+ cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x0d, 0x011d);
+ cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x03, 0x0129);
+ break;
+ case 352: /* 352x288 */
+ cit_write_reg(gspca_dev, 0xb0, 0x0103);
+ cit_write_reg(gspca_dev, 0x90, 0x0105);
+ cit_write_reg(gspca_dev, 0x02, 0x010b);
+ cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x05, 0x011d);
+ cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x00, 0x0129);
+ break;
+ }
+
+ cit_write_reg(gspca_dev, 0xff, 0x012b);
+
+ /* TESTME These are handled through controls
+ KEEP until someone can test leaving this out is ok */
+ if (0) {
+ /* This is another brightness - don't know why */
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
+
+ /* Default contrast */
+ for (i = 0; i < cit_model1_ntries; i++)
+ cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
+
+ /* Default sharpness */
+ for (i = 0; i < cit_model1_ntries2; i++)
+ cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
+
+ /* Default lighting conditions */
+ cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting);
+ }
+
+ /* Assorted init */
+ switch (gspca_dev->width) {
+ case 128: /* 128x96 */
+ cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
+ cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x36, 0x0102);
+ cit_write_reg(gspca_dev, 0x1a, 0x0104);
+ cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x2b, 0x011c);
+ cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
+ break;
+ case 176: /* 176x144 */
+ cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
+ cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x04, 0x0102);
+ cit_write_reg(gspca_dev, 0x02, 0x0104);
+ cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x2b, 0x011c);
+ cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
+ break;
+ case 352: /* 352x288 */
+ cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
+ cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x08, 0x0102);
+ cit_write_reg(gspca_dev, 0x01, 0x0104);
+ cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
+ cit_write_reg(gspca_dev, 0x2f, 0x011c);
+ cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
+ break;
+ }
+
+ cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
+ cit_write_reg(gspca_dev, clock_div, 0x0111);
+
+ return 0;
+}
+
+static int cit_start_model2(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int clock_div = 0;
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ cit_write_reg(gspca_dev, 0x0002, 0x0112);
+ cit_write_reg(gspca_dev, 0x00bc, 0x012c);
+ cit_write_reg(gspca_dev, 0x0008, 0x012b);
+ cit_write_reg(gspca_dev, 0x0000, 0x0108);
+ cit_write_reg(gspca_dev, 0x0001, 0x0133);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ switch (gspca_dev->width) {
+ case 176: /* 176x144 */
+ cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
+ cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
+ cit_write_reg(gspca_dev, 0x00b9, 0x010a); /* Unique to this mode */
+ cit_write_reg(gspca_dev, 0x0038, 0x0119); /* Unique to this mode */
+ /* TESTME HDG: this does not seem right
+ (it is 2 for all other resolutions) */
+ sd->sof_len = 10;
+ break;
+ case 320: /* 320x240 */
+ cit_write_reg(gspca_dev, 0x0028, 0x0103); /* Unique to this mode */
+ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
+ cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
+ cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
+ sd->sof_len = 2;
+ break;
+ /* case VIDEOSIZE_352x240: */
+ cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
+ cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
+ cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
+ sd->sof_len = 2;
+ break;
+ case 352: /* 352x288 */
+ cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
+ cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
+ cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
+ sd->sof_len = 2;
+ break;
+ }
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
+
+ switch (gspca_dev->width) {
+ case 176: /* 176x144 */
+ cit_write_reg(gspca_dev, 0x0050, 0x0111);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0111);
+ break;
+ case 320: /* 320x240 */
+ case 352: /* 352x288 */
+ cit_write_reg(gspca_dev, 0x0040, 0x0111);
+ cit_write_reg(gspca_dev, 0x00c0, 0x0111);
+ break;
+ }
+ cit_write_reg(gspca_dev, 0x009b, 0x010f);
+ cit_write_reg(gspca_dev, 0x00bb, 0x010f);
+
+ /*
+ * Hardware settings, may affect CMOS sensor; not user controls!
+ * -------------------------------------------------------------
+ * 0x0004: no effect
+ * 0x0006: hardware effect
+ * 0x0008: no effect
+ * 0x000a: stops video stream, probably important h/w setting
+ * 0x000c: changes color in hardware manner (not user setting)
+ * 0x0012: changes number of colors (does not affect speed)
+ * 0x002a: no effect
+ * 0x002c: hardware setting (related to scan lines)
+ * 0x002e: stops video stream, probably important h/w setting
+ */
+ cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
+ cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
+ cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
+ cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
+ cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
+ cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
+ cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
+ cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
+ cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
+
+ /*
+ * Function 0x0030 pops up all over the place. Apparently
+ * it is a hardware control register, with every bit assigned to
+ * do something.
+ */
+ cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
+
+ /*
+ * Magic control of CMOS sensor. Only lower values like
+ * 0-3 work, and picture shifts left or right. Don't change.
+ */
+ switch (gspca_dev->width) {
+ case 176: /* 176x144 */
+ cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
+ cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
+ cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
+ clock_div = 6;
+ break;
+ case 320: /* 320x240 */
+ cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
+ cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
+ cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
+ clock_div = 8;
+ break;
+ /* case VIDEOSIZE_352x240: */
+ /* This mode doesn't work as Windows programs it; changed to work */
+ cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
+ cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
+ cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
+ clock_div = 10;
+ break;
+ case 352: /* 352x288 */
+ cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
+ cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
+ cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
+ clock_div = 16;
+ break;
+ }
+
+ /* TESTME These are handled through controls
+ KEEP until someone can test leaving this out is ok */
+ if (0)
+ cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
+
+ /*
+ * We have our own frame rate setting varying from 0 (slowest) to 6
+ * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
+ # where 0 is also the slowest setting. However for all practical
+ # reasons high settings make no sense because USB is not fast enough
+ # to support high FPS. Be aware that the picture datastream will be
+ # severely disrupted if you ask for frame rate faster than allowed
+ # for the video size - see below:
+ *
+ * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
+ * -----------------------------------------------------------------
+ * 176x144: [6..31]
+ * 320x240: [8..31]
+ * 352x240: [10..31]
+ * 352x288: [16..31] I have to raise lower threshold for stability...
+ *
+ * As usual, slower FPS provides better sensitivity.
+ */
+ cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
+
+ /*
+ * This setting does not visibly affect pictures; left it here
+ * because it was present in Windows USB data stream. This function
+ * does not allow arbitrary values and apparently is a bit mask, to
+ * be activated only at appropriate time. Don't change it randomly!
+ */
+ switch (gspca_dev->width) {
+ case 176: /* 176x144 */
+ cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
+ break;
+ case 320: /* 320x240 */
+ cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
+ break;
+ /* case VIDEOSIZE_352x240: */
+ cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
+ break;
+ case 352: /* 352x288 */
+ cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
+ break;
+ }
+
+ /* FIXME this cannot be changed while streaming, so we
+ should report a grabbed flag for this control. */
+ cit_model2_Packet1(gspca_dev, 0x0028, sd->lighting);
+ /* color balance rg2 */
+ cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
+ /* saturation */
+ cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
+ /* color balance yb */
+ cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
+
+ /* Hardware control command */
+ cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
+
+ return 0;
+}
+
+static int cit_start_model3(struct gspca_dev *gspca_dev)
+{
+ const unsigned short compression = 0; /* 0=none, 7=best frame rate */
+ int i, clock_div = 0;
+
+ /* HDG not in ibmcam driver, added to see if it helps with
+ auto-detecting between model3 and ibm netcamera pro */
+ cit_read_reg(gspca_dev, 0x128);
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0100);
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ cit_write_reg(gspca_dev, 0x0002, 0x0112);
+ cit_write_reg(gspca_dev, 0x0000, 0x0123);
+ cit_write_reg(gspca_dev, 0x0001, 0x0117);
+ cit_write_reg(gspca_dev, 0x0040, 0x0108);
+ cit_write_reg(gspca_dev, 0x0019, 0x012c);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ cit_write_reg(gspca_dev, 0x0002, 0x0115);
+ cit_write_reg(gspca_dev, 0x0003, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115);
+ cit_write_reg(gspca_dev, 0x000b, 0x0115);
+
+ /* TESTME HDG not in ibmcam driver, added to see if it helps with
+ auto-detecting between model3 and ibm netcamera pro */
+ if (0) {
+ cit_write_reg(gspca_dev, 0x0078, 0x012d);
+ cit_write_reg(gspca_dev, 0x0001, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0079, 0x012d);
+ cit_write_reg(gspca_dev, 0x00ff, 0x0130);
+ cit_write_reg(gspca_dev, 0xcd41, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_read_reg(gspca_dev, 0x0126);
+ }
+
+ cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
+ cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
+ cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
+ cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
+ cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
+ cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
+ cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
+ cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
+ cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
+ cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
+ cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
+ cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
+ cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
+ cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
+ cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
+ cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
+ cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
+ cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
+ cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
+ cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
+ cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
+ cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
+ cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
+ cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
+ cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
+ cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
+ cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
+ cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
+ cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
+ cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
+ cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
+
+ switch (gspca_dev->width) {
+ case 160:
+ cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
+ cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
+ cit_write_reg(gspca_dev, 0x00a9, 0x0119);
+ cit_write_reg(gspca_dev, 0x0016, 0x011b);
+ cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
+ cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
+ cit_write_reg(gspca_dev, 0x0018, 0x0102);
+ cit_write_reg(gspca_dev, 0x0004, 0x0104);
+ cit_write_reg(gspca_dev, 0x0004, 0x011a);
+ cit_write_reg(gspca_dev, 0x0028, 0x011c);
+ cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
+ cit_write_reg(gspca_dev, 0x0000, 0x0118);
+ cit_write_reg(gspca_dev, 0x0000, 0x0132);
+ cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
+ cit_write_reg(gspca_dev, compression, 0x0109);
+ clock_div = 3;
+ break;
+ case 320:
+ cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
+ cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
+ cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
+ cit_write_reg(gspca_dev, 0x0000, 0x011e);
+ cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
+ cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
+ /* 4 commands from 160x120 skipped */
+ cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
+ cit_write_reg(gspca_dev, compression, 0x0109);
+ cit_write_reg(gspca_dev, 0x00d9, 0x0119);
+ cit_write_reg(gspca_dev, 0x0006, 0x011b);
+ cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x0010, 0x0104);
+ cit_write_reg(gspca_dev, 0x0004, 0x011a);
+ cit_write_reg(gspca_dev, 0x003f, 0x011c);
+ cit_write_reg(gspca_dev, 0x001c, 0x0118);
+ cit_write_reg(gspca_dev, 0x0000, 0x0132);
+ clock_div = 5;
+ break;
+ case 640:
+ cit_write_reg(gspca_dev, 0x00f0, 0x0105);
+ cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
+ cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
+ cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
+ cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
+ cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
+ cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
+ cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
+ cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
+ cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
+ cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
+ cit_write_reg(gspca_dev, compression, 0x0109);
+ cit_write_reg(gspca_dev, 0x0040, 0x0101);
+ cit_write_reg(gspca_dev, 0x0040, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
+ clock_div = 7;
+ break;
+ }
+
+ cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); /* Hue */
+ cit_model3_Packet1(gspca_dev, 0x0036, 0x0011); /* Brightness */
+ cit_model3_Packet1(gspca_dev, 0x0060, 0x0002); /* Sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0061, 0x0004); /* Sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); /* Sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0063, 0x0014); /* Sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0067, 0x0001); /* Contrast */
+ cit_model3_Packet1(gspca_dev, 0x005b, 0x000c); /* Contrast */
+ cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); /* Contrast */
+ cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
+ cit_model3_Packet1(gspca_dev, 0x002c, 0x0003); /* Was 1, broke 640x480 */
+ cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
+ cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
+ cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
+ cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
+ cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
+ cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
+ cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
+ cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
+ cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
+ cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
+ cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
+ cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
+ cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
+ cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
+ cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
+ cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
+ cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
+ cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
+
+ /* FIXME we should probably use cit_get_clock_div() here (in
+ combination with isoc negotiation using the programmable isoc size)
+ like with the IBM netcam pro). */
+ cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
+
+ switch (gspca_dev->width) {
+ case 160:
+ cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
+ cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
+ break;
+ case 320:
+ cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
+ cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
+ break;
+ case 640:
+ cit_model3_Packet1(gspca_dev, 0x001f, 0x0002); /* !Same */
+ cit_model3_Packet1(gspca_dev, 0x0039, 0x003e); /* !Same */
+ cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
+ cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
+ break;
+ }
+
+/* if (sd->input_index) { */
+ if (rca_input) {
+ for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
+ if (rca_initdata[i][0])
+ cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ else
+ cit_write_reg(gspca_dev, rca_initdata[i][1],
+ rca_initdata[i][2]);
+ }
+ }
+
+ return 0;
+}
+
+static int cit_start_model4(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0100);
+ cit_write_reg(gspca_dev, 0x00c0, 0x0111);
+ cit_write_reg(gspca_dev, 0x00bc, 0x012c);
+ cit_write_reg(gspca_dev, 0x0080, 0x012b);
+ cit_write_reg(gspca_dev, 0x0000, 0x0108);
+ cit_write_reg(gspca_dev, 0x0001, 0x0133);
+ cit_write_reg(gspca_dev, 0x009b, 0x010f);
+ cit_write_reg(gspca_dev, 0x00bb, 0x010f);
+ cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
+ cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
+
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0004, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0x00fb, 0x012e);
+ cit_write_reg(gspca_dev, 0x0000, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x000c, 0x0127);
+ cit_write_reg(gspca_dev, 0x0009, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0012, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0008, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x002a, 0x012d);
+ cit_write_reg(gspca_dev, 0x0000, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
+
+ switch (gspca_dev->width) {
+ case 128: /* 128x96 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0111);
+ cit_write_reg(gspca_dev, 0x0039, 0x010a);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ cit_write_reg(gspca_dev, 0x0028, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x001e, 0x0105);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0016, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x000a, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0014, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012e);
+ cit_write_reg(gspca_dev, 0x001a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
+ cit_write_reg(gspca_dev, 0x005a, 0x012d);
+ cit_write_reg(gspca_dev, 0x9545, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0127);
+ cit_write_reg(gspca_dev, 0x0018, 0x012e);
+ cit_write_reg(gspca_dev, 0x0043, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x001c, 0x0127);
+ cit_write_reg(gspca_dev, 0x00eb, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0032, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0036, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0017, 0x0127);
+ cit_write_reg(gspca_dev, 0x0013, 0x012e);
+ cit_write_reg(gspca_dev, 0x0031, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x0017, 0x012d);
+ cit_write_reg(gspca_dev, 0x0078, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+ sd->sof_len = 2;
+ break;
+ case 160: /* 160x120 */
+ cit_write_reg(gspca_dev, 0x0038, 0x0119);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0111);
+ cit_write_reg(gspca_dev, 0x00b9, 0x010a);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ cit_write_reg(gspca_dev, 0x0028, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x001e, 0x0105);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0016, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x000b, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0014, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012e);
+ cit_write_reg(gspca_dev, 0x001a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
+ cit_write_reg(gspca_dev, 0x005a, 0x012d);
+ cit_write_reg(gspca_dev, 0x9545, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0127);
+ cit_write_reg(gspca_dev, 0x0018, 0x012e);
+ cit_write_reg(gspca_dev, 0x0043, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x001c, 0x0127);
+ cit_write_reg(gspca_dev, 0x00c7, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0032, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0025, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0036, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0048, 0x0127);
+ cit_write_reg(gspca_dev, 0x0035, 0x012e);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x0048, 0x012d);
+ cit_write_reg(gspca_dev, 0x0090, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x0001, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+ sd->sof_len = 2;
+ break;
+ case 176: /* 176x144 */
+ cit_write_reg(gspca_dev, 0x0038, 0x0119);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0111);
+ cit_write_reg(gspca_dev, 0x00b9, 0x010a);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ cit_write_reg(gspca_dev, 0x002c, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x0024, 0x0105);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0016, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0007, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0014, 0x012d);
+ cit_write_reg(gspca_dev, 0x0001, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012e);
+ cit_write_reg(gspca_dev, 0x001a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
+ cit_write_reg(gspca_dev, 0x005e, 0x012d);
+ cit_write_reg(gspca_dev, 0x9545, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0127);
+ cit_write_reg(gspca_dev, 0x0018, 0x012e);
+ cit_write_reg(gspca_dev, 0x0049, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x001c, 0x0127);
+ cit_write_reg(gspca_dev, 0x00c7, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0032, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0028, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0036, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0010, 0x0127);
+ cit_write_reg(gspca_dev, 0x0013, 0x012e);
+ cit_write_reg(gspca_dev, 0x002a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x0010, 0x012d);
+ cit_write_reg(gspca_dev, 0x006d, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x0001, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+ /* TESTME HDG: this does not seem right
+ (it is 2 for all other resolutions) */
+ sd->sof_len = 10;
+ break;
+ case 320: /* 320x240 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119);
+ cit_write_reg(gspca_dev, 0x00d0, 0x0111);
+ cit_write_reg(gspca_dev, 0x0039, 0x010a);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ cit_write_reg(gspca_dev, 0x0028, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x001e, 0x0105);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0016, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x000a, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0014, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012e);
+ cit_write_reg(gspca_dev, 0x001a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
+ cit_write_reg(gspca_dev, 0x005a, 0x012d);
+ cit_write_reg(gspca_dev, 0x9545, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0127);
+ cit_write_reg(gspca_dev, 0x0018, 0x012e);
+ cit_write_reg(gspca_dev, 0x0043, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x001c, 0x0127);
+ cit_write_reg(gspca_dev, 0x00eb, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0032, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0036, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0017, 0x0127);
+ cit_write_reg(gspca_dev, 0x0013, 0x012e);
+ cit_write_reg(gspca_dev, 0x0031, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x0017, 0x012d);
+ cit_write_reg(gspca_dev, 0x0078, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+ sd->sof_len = 2;
+ break;
+ case 352: /* 352x288 */
+ cit_write_reg(gspca_dev, 0x0070, 0x0119);
+ cit_write_reg(gspca_dev, 0x00c0, 0x0111);
+ cit_write_reg(gspca_dev, 0x0039, 0x010a);
+ cit_write_reg(gspca_dev, 0x0001, 0x0102);
+ cit_write_reg(gspca_dev, 0x002c, 0x0103);
+ cit_write_reg(gspca_dev, 0x0000, 0x0104);
+ cit_write_reg(gspca_dev, 0x0024, 0x0105);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0016, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0006, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0014, 0x012d);
+ cit_write_reg(gspca_dev, 0x0002, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012e);
+ cit_write_reg(gspca_dev, 0x001a, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
+ cit_write_reg(gspca_dev, 0x005e, 0x012d);
+ cit_write_reg(gspca_dev, 0x9545, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0127);
+ cit_write_reg(gspca_dev, 0x0018, 0x012e);
+ cit_write_reg(gspca_dev, 0x0049, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012f);
+ cit_write_reg(gspca_dev, 0xd055, 0x0124);
+ cit_write_reg(gspca_dev, 0x001c, 0x0127);
+ cit_write_reg(gspca_dev, 0x00cf, 0x012e);
+ cit_write_reg(gspca_dev, 0xaa28, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x0032, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0x00aa, 0x0130);
+ cit_write_reg(gspca_dev, 0x82a8, 0x0124);
+ cit_write_reg(gspca_dev, 0x0036, 0x012d);
+ cit_write_reg(gspca_dev, 0x0008, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0xfffa, 0x0124);
+ cit_write_reg(gspca_dev, 0x00aa, 0x012d);
+ cit_write_reg(gspca_dev, 0x001e, 0x012f);
+ cit_write_reg(gspca_dev, 0xd141, 0x0124);
+ cit_write_reg(gspca_dev, 0x0010, 0x0127);
+ cit_write_reg(gspca_dev, 0x0013, 0x012e);
+ cit_write_reg(gspca_dev, 0x0025, 0x0130);
+ cit_write_reg(gspca_dev, 0x8a28, 0x0124);
+ cit_write_reg(gspca_dev, 0x0010, 0x012d);
+ cit_write_reg(gspca_dev, 0x0048, 0x012f);
+ cit_write_reg(gspca_dev, 0xd145, 0x0124);
+ cit_write_reg(gspca_dev, 0x0000, 0x0127);
+ cit_write_reg(gspca_dev, 0xfea8, 0x0124);
+ sd->sof_len = 2;
+ break;
+ }
+
+ cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
+
+ return 0;
+}
+
+static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
+{
+ const unsigned short compression = 0; /* 0=none, 7=best frame rate */
+ int i, clock_div;
+
+ clock_div = cit_get_clock_div(gspca_dev);
+ if (clock_div < 0)
+ return clock_div;
+
+ cit_write_reg(gspca_dev, 0x0003, 0x0133);
+ cit_write_reg(gspca_dev, 0x0000, 0x0117);
+ cit_write_reg(gspca_dev, 0x0008, 0x0123);
+ cit_write_reg(gspca_dev, 0x0000, 0x0100);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ /* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0133);
+ cit_write_reg(gspca_dev, 0x0000, 0x0123);
+ cit_write_reg(gspca_dev, 0x0001, 0x0117);
+ cit_write_reg(gspca_dev, 0x0040, 0x0108);
+ cit_write_reg(gspca_dev, 0x0019, 0x012c);
+ cit_write_reg(gspca_dev, 0x0060, 0x0116);
+ /* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
+
+ cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
+
+ cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
+ cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
+ cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
+ cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
+ cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
+ cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
+
+ switch (gspca_dev->width) {
+ case 160: /* 160x120 */
+ cit_write_reg(gspca_dev, 0x0024, 0x010b);
+ cit_write_reg(gspca_dev, 0x0089, 0x0119);
+ cit_write_reg(gspca_dev, 0x000a, 0x011b);
+ cit_write_reg(gspca_dev, 0x0003, 0x011e);
+ cit_write_reg(gspca_dev, 0x0007, 0x0104);
+ cit_write_reg(gspca_dev, 0x0009, 0x011a);
+ cit_write_reg(gspca_dev, 0x008b, 0x011c);
+ cit_write_reg(gspca_dev, 0x0008, 0x0118);
+ cit_write_reg(gspca_dev, 0x0000, 0x0132);
+ break;
+ case 320: /* 320x240 */
+ cit_write_reg(gspca_dev, 0x0028, 0x010b);
+ cit_write_reg(gspca_dev, 0x00d9, 0x0119);
+ cit_write_reg(gspca_dev, 0x0006, 0x011b);
+ cit_write_reg(gspca_dev, 0x0000, 0x011e);
+ cit_write_reg(gspca_dev, 0x000e, 0x0104);
+ cit_write_reg(gspca_dev, 0x0004, 0x011a);
+ cit_write_reg(gspca_dev, 0x003f, 0x011c);
+ cit_write_reg(gspca_dev, 0x000c, 0x0118);
+ cit_write_reg(gspca_dev, 0x0000, 0x0132);
+ break;
+ }
+
+ cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
+ cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
+ cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
+ cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
+ cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
+ cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
+ cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
+ cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
+
+ cit_write_reg(gspca_dev, compression, 0x0109);
+ cit_write_reg(gspca_dev, clock_div, 0x0111);
+
+/* if (sd->input_index) { */
+ if (rca_input) {
+ for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
+ if (rca_initdata[i][0])
+ cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ else
+ cit_write_reg(gspca_dev, rca_initdata[i][1],
+ rca_initdata[i][2]);
+ }
+ }
+
+ return 0;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int packet_size;
+
+ packet_size = cit_get_packet_size(gspca_dev);
+ if (packet_size < 0)
+ return packet_size;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ cit_start_model0(gspca_dev);
+ break;
+ case CIT_MODEL1:
+ cit_start_model1(gspca_dev);
+ break;
+ case CIT_MODEL2:
+ cit_start_model2(gspca_dev);
+ break;
+ case CIT_MODEL3:
+ cit_start_model3(gspca_dev);
+ break;
+ case CIT_MODEL4:
+ cit_start_model4(gspca_dev);
+ break;
+ case CIT_IBM_NETCAM_PRO:
+ cit_start_ibm_netcam_pro(gspca_dev);
+ break;
+ }
+
+ cit_set_brightness(gspca_dev);
+ cit_set_contrast(gspca_dev);
+ cit_set_hue(gspca_dev);
+ cit_set_sharpness(gspca_dev);
+ cit_set_lighting(gspca_dev);
+ cit_set_hflip(gspca_dev);
+
+ /* Program max isoc packet size */
+ cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
+ cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
+
+ cit_restart_stream(gspca_dev);
+
+ return 0;
+}
+
+static int sd_isoc_nego(struct gspca_dev *gspca_dev)
+{
+ int ret, packet_size;
+ struct usb_host_interface *alt;
+
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+ packet_size -= 100;
+ if (packet_size < 300)
+ return -EIO;
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
+
+ ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret);
+
+ return ret;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ cit_write_reg(gspca_dev, 0x0000, 0x010c);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_host_interface *alt;
+
+ /* We cannot use gspca_dev->present here as that is not set when
+ sd_init gets called and we get called from sd_init */
+ if (!gspca_dev->dev)
+ return;
+
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ /* HDG windows does this, but it causes the cams autogain to
+ restart from a gain of 0, which does not look good when
+ changing resolutions. */
+ /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
+ cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
+ break;
+ case CIT_MODEL1:
+ cit_send_FF_04_02(gspca_dev);
+ cit_read_reg(gspca_dev, 0x0100);
+ cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
+ break;
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
+
+ cit_write_reg(gspca_dev, 0x0080, 0x0100); /* LED Off */
+ cit_write_reg(gspca_dev, 0x0020, 0x0111);
+ cit_write_reg(gspca_dev, 0x00a0, 0x0111);
+
+ cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
+
+ cit_write_reg(gspca_dev, 0x0020, 0x0111);
+ cit_write_reg(gspca_dev, 0x0000, 0x0112);
+ break;
+ case CIT_MODEL3:
+ cit_write_reg(gspca_dev, 0x0006, 0x012c);
+ cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
+ cit_read_reg(gspca_dev, 0x0116);
+ cit_write_reg(gspca_dev, 0x0064, 0x0116);
+ cit_read_reg(gspca_dev, 0x0115);
+ cit_write_reg(gspca_dev, 0x0003, 0x0115);
+ cit_write_reg(gspca_dev, 0x0008, 0x0123);
+ cit_write_reg(gspca_dev, 0x0000, 0x0117);
+ cit_write_reg(gspca_dev, 0x0000, 0x0112);
+ cit_write_reg(gspca_dev, 0x0080, 0x0100);
+ break;
+ case CIT_IBM_NETCAM_PRO:
+ cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
+ cit_write_reg(gspca_dev, 0x0006, 0x012c);
+ cit_write_reg(gspca_dev, 0x0000, 0x0116);
+ /* HDG windows does this, but I cannot get the camera
+ to restart with this without redoing the entire init
+ sequence which makes switching modes really slow */
+ /* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
+ cit_write_reg(gspca_dev, 0x0008, 0x0123);
+ cit_write_reg(gspca_dev, 0x0000, 0x0117);
+ cit_write_reg(gspca_dev, 0x0003, 0x0133);
+ cit_write_reg(gspca_dev, 0x0000, 0x0111);
+ /* HDG windows does this, but I get a green picture when
+ restarting the stream after this */
+ /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
+ cit_write_reg(gspca_dev, 0x00c0, 0x0100);
+
+ /* Start isoc bandwidth "negotiation" at max isoc bandwith
+ next stream start */
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022);
+ break;
+ }
+}
+
+static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 byte3 = 0, byte4 = 0;
+ int i;
+
+ switch (sd->model) {
+ case CIT_MODEL0:
+ case CIT_MODEL1:
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ switch (gspca_dev->width) {
+ case 160: /* 160x120 */
+ byte3 = 0x02;
+ byte4 = 0x0a;
+ break;
+ case 176: /* 176x144 */
+ byte3 = 0x02;
+ byte4 = 0x0e;
+ break;
+ case 320: /* 320x240 */
+ byte3 = 0x02;
+ byte4 = 0x08;
+ break;
+ case 352: /* 352x288 */
+ byte3 = 0x02;
+ byte4 = 0x00;
+ break;
+ case 640:
+ byte3 = 0x03;
+ byte4 = 0x08;
+ break;
+ }
+
+ /* These have a different byte3 */
+ if (sd->model <= CIT_MODEL1)
+ byte3 = 0x00;
+
+ for (i = 0; i < len; i++) {
+ /* For this model the SOF always starts at offset 0
+ so no need to search the entire frame */
+ if (sd->model == CIT_MODEL0 && sd->sof_read != i)
+ break;
+
+ switch (sd->sof_read) {
+ case 0:
+ if (data[i] == 0x00)
+ sd->sof_read++;
+ break;
+ case 1:
+ if (data[i] == 0xff)
+ sd->sof_read++;
+ else if (data[i] == 0x00)
+ sd->sof_read = 1;
+ else
+ sd->sof_read = 0;
+ break;
+ case 2:
+ if (data[i] == byte3)
+ sd->sof_read++;
+ else if (data[i] == 0x00)
+ sd->sof_read = 1;
+ else
+ sd->sof_read = 0;
+ break;
+ case 3:
+ if (data[i] == byte4) {
+ sd->sof_read = 0;
+ return data + i + (sd->sof_len - 3);
+ }
+ if (byte3 == 0x00 && data[i] == 0xff)
+ sd->sof_read = 2;
+ else if (data[i] == 0x00)
+ sd->sof_read = 1;
+ else
+ sd->sof_read = 0;
+ break;
+ }
+ }
+ break;
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ /* TESTME we need to find a longer sof signature to avoid
+ false positives */
+ for (i = 0; i < len; i++) {
+ switch (sd->sof_read) {
+ case 0:
+ if (data[i] == 0x00)
+ sd->sof_read++;
+ break;
+ case 1:
+ sd->sof_read = 0;
+ if (data[i] == 0xff) {
+ if (i >= 4)
+ PDEBUG(D_FRAM,
+ "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n",
+ i - 1,
+ data[i - 4],
+ data[i - 3],
+ data[i],
+ data[i + 1],
+ data[i + 2]);
+ else
+ PDEBUG(D_FRAM,
+ "header found at offset: %d: 00 %02x %02x %02x\n",
+ i - 1,
+ data[i],
+ data[i + 1],
+ data[i + 2]);
+ return data + i + (sd->sof_len - 1);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ return NULL;
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ u8 *data, int len)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned char *sof;
+
+ sof = cit_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sd->sof_len)
+ n -= sd->sof_len;
+ else
+ n = 0;
+ gspca_frame_add(gspca_dev, LAST_PACKET,
+ data, n);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
+ len -= sof - data;
+ data = sof;
+ }
+
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_brightness(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_contrast(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+
+ return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hue = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_hue(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->hue;
+
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_sharpness(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+
+ return 0;
+}
+
+static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->lighting = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_lighting(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->lighting;
+
+ return 0;
+}
+
+static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hflip = val;
+ if (gspca_dev->streaming) {
+ if (sd->stop_on_control_change)
+ sd_stopN(gspca_dev);
+ cit_set_hflip(gspca_dev);
+ if (sd->stop_on_control_change)
+ cit_restart_stream(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->hflip;
+
+ return 0;
+}
+
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .pkt_scan = sd_pkt_scan,
+};
+
+static const struct sd_desc sd_desc_isoc_nego = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .isoc_nego = sd_isoc_nego,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
+ { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
+ { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
+ { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
+ { USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
+ { USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
+ { USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ const struct sd_desc *desc = &sd_desc;
+
+ switch (id->driver_info) {
+ case CIT_MODEL0:
+ case CIT_MODEL1:
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
+ return -ENODEV;
+ break;
+ case CIT_MODEL2:
+ case CIT_MODEL4:
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ return -ENODEV;
+ break;
+ case CIT_MODEL3:
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ return -ENODEV;
+ /* FIXME this likely applies to all model3 cams and probably
+ to other models too. */
+ if (ibm_netcam_pro)
+ desc = &sd_desc_isoc_nego;
+ break;
+ }
+
+ return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 75803141481e..04bacdbd10bb 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -811,15 +811,23 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). Ignore any errors. */
#define ivtv_call_hw(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ do { \
+ struct v4l2_subdev *__sd; \
+ __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \
+ !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
+ } while (0)
#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). If the callback returns an error other than 0 or
-ENOIOCTLCMD, then return with that error code. */
-#define ivtv_call_hw_err(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+#define ivtv_call_hw_err(itv, hw, o, f, args...) \
+({ \
+ struct v4l2_subdev *__sd; \
+ __v4l2_device_call_subdevs_until_err_p(&(itv)->v4l2_dev, __sd, \
+ !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
+})
#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 79f096ddcf5d..fcb4cd941853 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -157,7 +157,7 @@ static int mt9m001_init(struct i2c_client *client)
static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
/* Switch to master "normal" mode or stop sensor readout */
if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
@@ -206,7 +206,7 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_rect rect = a->c;
struct soc_camera_device *icd = client->dev.platform_data;
@@ -271,7 +271,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
a->c = mt9m001->rect;
@@ -297,7 +297,7 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int mt9m001_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
mf->width = mt9m001->rect.width;
@@ -312,7 +312,7 @@ static int mt9m001_g_fmt(struct v4l2_subdev *sd,
static int mt9m001_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_crop a = {
.c = {
@@ -340,7 +340,7 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd,
static int mt9m001_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
const struct mt9m001_datafmt *fmt;
@@ -367,7 +367,7 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd,
static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
@@ -386,7 +386,7 @@ static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
static int mt9m001_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -406,7 +406,7 @@ static int mt9m001_g_register(struct v4l2_subdev *sd,
static int mt9m001_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -468,7 +468,7 @@ static struct soc_camera_ops mt9m001_ops = {
static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
int data;
@@ -494,7 +494,7 @@ static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct soc_camera_device *icd = client->dev.platform_data;
const struct v4l2_queryctrl *qctrl;
@@ -683,7 +683,7 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
*lines = mt9m001->y_skip_top;
@@ -704,7 +704,7 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
if (index >= mt9m001->num_fmts)
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 758a4db27d65..2f170ea1ddef 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -440,7 +440,7 @@ static int mt9m111_make_rect(struct i2c_client *client,
static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct v4l2_rect rect = a->c;
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
int ret;
@@ -455,7 +455,7 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
a->c = mt9m111->rect;
@@ -481,7 +481,7 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int mt9m111_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
mf->width = mt9m111->rect.width;
@@ -543,7 +543,7 @@ static int mt9m111_set_pixfmt(struct i2c_client *client,
static int mt9m111_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
const struct mt9m111_datafmt *fmt;
struct mt9m111 *mt9m111 = to_mt9m111(client);
struct v4l2_rect rect = {
@@ -578,7 +578,7 @@ static int mt9m111_s_fmt(struct v4l2_subdev *sd,
static int mt9m111_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
const struct mt9m111_datafmt *fmt;
bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
@@ -618,7 +618,7 @@ static int mt9m111_try_fmt(struct v4l2_subdev *sd,
static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
@@ -637,7 +637,7 @@ static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
static int mt9m111_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int val;
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
@@ -658,7 +658,7 @@ static int mt9m111_g_register(struct v4l2_subdev *sd,
static int mt9m111_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
return -EINVAL;
@@ -806,7 +806,7 @@ static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
int data;
@@ -849,7 +849,7 @@ static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m111 *mt9m111 = to_mt9m111(client);
const struct v4l2_queryctrl *qctrl;
int ret;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index a9a28b214235..9bd44a816ea1 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -163,7 +163,7 @@ static int mt9t031_disable(struct i2c_client *client)
static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
if (enable)
@@ -393,7 +393,7 @@ static int mt9t031_set_params(struct i2c_client *client,
static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct v4l2_rect rect = a->c;
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
rect.width = ALIGN(rect.width, 2);
@@ -410,7 +410,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
a->c = mt9t031->rect;
@@ -436,7 +436,7 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int mt9t031_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
mf->width = mt9t031->rect.width / mt9t031->xskip;
@@ -451,7 +451,7 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd,
static int mt9t031_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
u16 xskip, yskip;
struct v4l2_rect rect = mt9t031->rect;
@@ -490,7 +490,7 @@ static int mt9t031_try_fmt(struct v4l2_subdev *sd,
static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
@@ -509,7 +509,7 @@ static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
static int mt9t031_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -528,7 +528,7 @@ static int mt9t031_g_register(struct v4l2_subdev *sd,
static int mt9t031_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -545,7 +545,7 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
int data;
@@ -577,7 +577,7 @@ static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
const struct v4l2_queryctrl *qctrl;
int data;
@@ -703,7 +703,7 @@ static int mt9t031_runtime_resume(struct device *dev)
struct soc_camera_device *icd = container_of(vdev->parent,
struct soc_camera_device, dev);
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
int ret;
@@ -780,7 +780,7 @@ static int mt9t031_video_probe(struct i2c_client *client)
static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t031 *mt9t031 = to_mt9t031(client);
*lines = mt9t031->y_skip_top;
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index 8ec47e42d4d0..bffa9ee10968 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -804,7 +804,7 @@ static struct soc_camera_ops mt9t112_ops = {
static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
id->ident = priv->model;
@@ -817,7 +817,7 @@ static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
static int mt9t112_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
reg->size = 2;
@@ -831,7 +831,7 @@ static int mt9t112_g_register(struct v4l2_subdev *sd,
static int mt9t112_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
mt9t112_reg_write(ret, client, reg->reg, reg->val);
@@ -858,7 +858,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
************************************************************************/
static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
int ret = 0;
@@ -968,7 +968,7 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct v4l2_rect *rect = &a->c;
return mt9t112_set_params(client, rect->width, rect->height,
@@ -978,7 +978,7 @@ static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9t112_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
if (!priv->format) {
@@ -1000,7 +1000,7 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd,
static int mt9t112_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
/* TODO: set colorspace */
return mt9t112_set_params(client, mf->width, mf->height, mf->code);
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index e7cd23cd6394..1a02f67764ee 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -184,7 +184,7 @@ static int mt9v022_init(struct i2c_client *client)
static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
if (enable)
@@ -273,7 +273,7 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
struct v4l2_rect rect = a->c;
int ret;
@@ -334,7 +334,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
a->c = mt9v022->rect;
@@ -360,7 +360,7 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int mt9v022_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
mf->width = mt9v022->rect.width;
@@ -375,7 +375,7 @@ static int mt9v022_g_fmt(struct v4l2_subdev *sd,
static int mt9v022_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
struct v4l2_crop a = {
.c = {
@@ -425,7 +425,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
static int mt9v022_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
const struct mt9v022_datafmt *fmt;
int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
@@ -451,7 +451,7 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd,
static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
@@ -470,7 +470,7 @@ static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
static int mt9v022_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -490,7 +490,7 @@ static int mt9v022_g_register(struct v4l2_subdev *sd,
static int mt9v022_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
return -EINVAL;
@@ -568,7 +568,7 @@ static struct soc_camera_ops mt9v022_ops = {
static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
const struct v4l2_queryctrl *qctrl;
unsigned long range;
int data;
@@ -625,7 +625,7 @@ static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
int data;
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
const struct v4l2_queryctrl *qctrl;
qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
@@ -820,7 +820,7 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
*lines = mt9v022->y_skip_top;
@@ -841,7 +841,7 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
if (index >= mt9v022->num_fmts)
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 91c886ab15c6..c141d2e604e3 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -18,6 +18,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-mediabus.h>
#include <media/v4l2-i2c-drv.h>
@@ -572,42 +573,37 @@ static int ov7670_detect(struct v4l2_subdev *sd)
/*
* Store information about the video data format. The color matrix
* is deeply tied into the format, so keep the relevant values here.
- * The magic matrix nubmers come from OmniVision.
+ * The magic matrix numbers come from OmniVision.
*/
static struct ov7670_format_struct {
- __u8 *desc;
- __u32 pixelformat;
+ enum v4l2_mbus_pixelcode mbus_code;
+ enum v4l2_colorspace colorspace;
struct regval_list *regs;
int cmatrix[CMATRIX_LEN];
- int bpp; /* Bytes per pixel */
} ov7670_formats[] = {
{
- .desc = "YUYV 4:2:2",
- .pixelformat = V4L2_PIX_FMT_YUYV,
+ .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
+ .colorspace = V4L2_COLORSPACE_JPEG,
.regs = ov7670_fmt_yuv422,
.cmatrix = { 128, -128, 0, -34, -94, 128 },
- .bpp = 2,
},
{
- .desc = "RGB 444",
- .pixelformat = V4L2_PIX_FMT_RGB444,
+ .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.regs = ov7670_fmt_rgb444,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
- .bpp = 2,
},
{
- .desc = "RGB 565",
- .pixelformat = V4L2_PIX_FMT_RGB565,
+ .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.regs = ov7670_fmt_rgb565,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
- .bpp = 2,
},
{
- .desc = "Raw RGB Bayer",
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.regs = ov7670_fmt_raw,
.cmatrix = { 0, 0, 0, 0, 0, 0 },
- .bpp = 1
},
};
#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
@@ -734,51 +730,45 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
}
-static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
+static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
+ enum v4l2_mbus_pixelcode *code)
{
- struct ov7670_format_struct *ofmt;
-
- if (fmt->index >= N_OV7670_FMTS)
+ if (index >= N_OV7670_FMTS)
return -EINVAL;
- ofmt = ov7670_formats + fmt->index;
- fmt->flags = 0;
- strcpy(fmt->description, ofmt->desc);
- fmt->pixelformat = ofmt->pixelformat;
+ *code = ov7670_formats[index].mbus_code;
return 0;
}
-
static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
- struct v4l2_format *fmt,
+ struct v4l2_mbus_framefmt *fmt,
struct ov7670_format_struct **ret_fmt,
struct ov7670_win_size **ret_wsize)
{
int index;
struct ov7670_win_size *wsize;
- struct v4l2_pix_format *pix = &fmt->fmt.pix;
for (index = 0; index < N_OV7670_FMTS; index++)
- if (ov7670_formats[index].pixelformat == pix->pixelformat)
+ if (ov7670_formats[index].mbus_code == fmt->code)
break;
if (index >= N_OV7670_FMTS) {
/* default to first format */
index = 0;
- pix->pixelformat = ov7670_formats[0].pixelformat;
+ fmt->code = ov7670_formats[0].mbus_code;
}
if (ret_fmt != NULL)
*ret_fmt = ov7670_formats + index;
/*
* Fields: the OV devices claim to be progressive.
*/
- pix->field = V4L2_FIELD_NONE;
+ fmt->field = V4L2_FIELD_NONE;
/*
* Round requested image size down to the nearest
* we support, but not below the smallest.
*/
for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
wsize++)
- if (pix->width >= wsize->width && pix->height >= wsize->height)
+ if (fmt->width >= wsize->width && fmt->height >= wsize->height)
break;
if (wsize >= ov7670_win_sizes + N_WIN_SIZES)
wsize--; /* Take the smallest one */
@@ -787,14 +777,14 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
/*
* Note the size we'll actually handle.
*/
- pix->width = wsize->width;
- pix->height = wsize->height;
- pix->bytesperline = pix->width*ov7670_formats[index].bpp;
- pix->sizeimage = pix->height*pix->bytesperline;
+ fmt->width = wsize->width;
+ fmt->height = wsize->height;
+ fmt->colorspace = ov7670_formats[index].colorspace;
return 0;
}
-static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+static int ov7670_try_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
{
return ov7670_try_fmt_internal(sd, fmt, NULL, NULL);
}
@@ -802,15 +792,17 @@ static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
/*
* Set a format.
*/
-static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
{
- int ret;
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
struct ov7670_info *info = to_state(sd);
unsigned char com7;
+ int ret;
ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
+
if (ret)
return ret;
/*
@@ -845,7 +837,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
*/
if (ret == 0)
ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
- return ret;
+ return 0;
}
/*
@@ -1442,9 +1434,9 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = {
};
static const struct v4l2_subdev_video_ops ov7670_video_ops = {
- .enum_fmt = ov7670_enum_fmt,
- .try_fmt = ov7670_try_fmt,
- .s_fmt = ov7670_s_fmt,
+ .enum_mbus_fmt = ov7670_enum_mbus_fmt,
+ .try_mbus_fmt = ov7670_try_mbus_fmt,
+ .s_mbus_fmt = ov7670_s_mbus_fmt,
.s_parm = ov7670_s_parm,
.g_parm = ov7670_g_parm,
};
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 25eb5d637eea..a84b770352f9 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -599,7 +599,7 @@ static int ov772x_reset(struct i2c_client *client)
static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
if (!enable) {
@@ -645,7 +645,7 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
switch (ctrl->id) {
@@ -664,7 +664,7 @@ static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
int ret = 0;
u8 val;
@@ -715,7 +715,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
id->ident = priv->model;
@@ -728,7 +728,7 @@ static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
static int ov772x_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
reg->size = 1;
@@ -747,7 +747,7 @@ static int ov772x_g_register(struct v4l2_subdev *sd,
static int ov772x_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->reg > 0xff ||
reg->val > 0xff)
@@ -954,7 +954,7 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int ov772x_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
if (!priv->win || !priv->cfmt) {
@@ -977,7 +977,7 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd,
static int ov772x_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
int ret = ov772x_set_params(client, &mf->width, &mf->height,
mf->code);
@@ -991,7 +991,7 @@ static int ov772x_s_fmt(struct v4l2_subdev *sd,
static int ov772x_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = to_ov772x(client);
const struct ov772x_win_size *win;
int i;
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 40cdfab74ccc..99e9e1d3c83b 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -308,7 +308,7 @@ static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
/* Get status of additional camera capabilities */
static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
struct ov9640_priv, subdev);
@@ -326,7 +326,7 @@ static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
/* Set status of additional camera capabilities */
static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
struct ov9640_priv, subdev);
@@ -360,7 +360,7 @@ static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov9640_priv *priv = container_of(i2c_get_clientdata(client),
struct ov9640_priv, subdev);
@@ -374,7 +374,7 @@ static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
static int ov9640_get_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
u8 val;
@@ -395,7 +395,7 @@ static int ov9640_get_register(struct v4l2_subdev *sd,
static int ov9640_set_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->reg & ~0xff || reg->val & ~0xff)
return -EINVAL;
@@ -558,7 +558,7 @@ static int ov9640_prog_dflt(struct i2c_client *client)
static int ov9640_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov9640_reg_alt alts = {0};
enum v4l2_colorspace cspace;
enum v4l2_mbus_pixelcode code = mf->code;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 1b992b847198..55ea914c7fcd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
if (ret >= 0) {
ret = pvr2_ctrl_range_check(cptr,*valptr);
}
- if (maskptr) *maskptr = ~0;
+ *maskptr = ~0;
} else if (cptr->info->type == pvr2_ctl_bool) {
ret = parse_token(ptr,len,valptr,boolNames,
ARRAY_SIZE(boolNames));
@@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
} else if (ret == 0) {
*valptr = (*valptr & 1) ? !0 : 0;
}
- if (maskptr) *maskptr = 1;
+ *maskptr = 1;
} else if (cptr->info->type == pvr2_ctl_enum) {
ret = parse_token(
ptr,len,valptr,
@@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
if (ret >= 0) {
ret = pvr2_ctrl_range_check(cptr,*valptr);
}
- if (maskptr) *maskptr = ~0;
+ *maskptr = ~0;
} else if (cptr->info->type == pvr2_ctl_bitmask) {
ret = parse_tlist(
ptr,len,maskptr,valptr,
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index ce78fff23425..d2fa2d43ff19 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -493,7 +493,7 @@ static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
/* Switch between preview and still shot modes */
return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
@@ -503,7 +503,7 @@ static int rj54n1_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
/* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
if (flags & SOCAM_PCLK_SAMPLE_RISING)
@@ -560,7 +560,7 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
struct v4l2_rect *rect = &a->c;
int dummy = 0, output_w, output_h,
@@ -595,7 +595,7 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
a->c = rj54n1->rect;
@@ -621,7 +621,7 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int rj54n1_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
mf->code = rj54n1->fmt->code;
@@ -641,7 +641,7 @@ static int rj54n1_g_fmt(struct v4l2_subdev *sd,
static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
s32 *out_w, s32 *out_h)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
output_w = *out_w, output_h = *out_h;
@@ -983,7 +983,7 @@ static int rj54n1_reg_init(struct i2c_client *client)
static int rj54n1_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
const struct rj54n1_datafmt *fmt;
int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 ||
@@ -1014,7 +1014,7 @@ static int rj54n1_try_fmt(struct v4l2_subdev *sd,
static int rj54n1_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
const struct rj54n1_datafmt *fmt;
int output_w, output_h, max_w, max_h,
@@ -1145,7 +1145,7 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd,
static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
return -EINVAL;
@@ -1163,7 +1163,7 @@ static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
static int rj54n1_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
reg->reg < 0x400 || reg->reg > 0x1fff)
@@ -1185,7 +1185,7 @@ static int rj54n1_g_register(struct v4l2_subdev *sd,
static int rj54n1_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
reg->reg < 0x400 || reg->reg > 0x1fff)
@@ -1248,7 +1248,7 @@ static struct soc_camera_ops rj54n1_ops = {
static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
int data;
@@ -1283,7 +1283,7 @@ static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
int data;
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
const struct v4l2_queryctrl *qctrl;
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 8ec7c9a45a17..8f7434182bc3 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -600,7 +600,7 @@ static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
unlock:
spin_unlock_irqrestore(&dev->slock, flags);
- return 0;
+ return rc;
}
static const struct s2255_fmt *format_by_fourcc(int fourcc)
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index b151c7be8a50..1beb2263d18c 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -822,7 +822,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
} else {
v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
"Wrong buffer/video queue type (%d)\n", f->type);
- return -EINVAL;
+ ret = -EINVAL;
+ goto s_fmt_out;
}
pix = &f->fmt.pix;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index ec697fcd406e..bb8d83d8ddaf 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = {
},
[SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
/* Beholder Intl. Ltd. 2008 */
- /*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV Columbus TVFM",
+ /* Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV Columbus TV/FM",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_ALPS_TSBE5_PAL,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = 0xc2 >> 1,
+ .radio_addr = 0xc0 >> 1,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x000A8004,
.inputs = {{
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 45f0ac8f3c0f..645224cfd887 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1825,7 +1825,7 @@ static int saa7134_querycap(struct file *file, void *priv,
if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
cap->capabilities &= ~V4L2_CAP_TUNER;
- return 0;
+ return 0;
}
int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id)
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index 5713f3a4b76c..ddd25d32723d 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -136,10 +136,11 @@ ret:
int saa7164_buffer_dealloc(struct saa7164_tsport *port,
struct saa7164_buffer *buf)
{
- struct saa7164_dev *dev = port->dev;
+ struct saa7164_dev *dev;
- if ((buf == 0) || (port == 0))
+ if (!buf || !port)
return SAA_ERR_BAD_PARAMETER;
+ dev = port->dev;
dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a499cacec1f3..a55d6dc4c6bd 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -902,7 +902,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
if (!subdev)
goto ei2cnd;
- client = subdev->priv;
+ client = v4l2_get_subdevdata(subdev);
/* Use to_i2c_client(dev) to recover the i2c client */
dev_set_drvdata(&icd->dev, &client->dev);
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 71c73fa0d68c..45bcf0358a1d 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -35,6 +35,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-mediabus.h>
#include <media/v4l2-chip-ident.h>
#include <media/tvp514x.h>
@@ -929,69 +930,51 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
}
/**
- * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt
+ * tvp514x_enum_mbus_fmt() - V4L2 decoder interface handler for enum_mbus_fmt
* @sd: pointer to standard V4L2 sub-device structure
- * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
+ * @index: index of pixelcode to retrieve
+ * @code: receives the pixelcode
*
- * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
+ * Enumerates supported mediabus formats
*/
static int
-tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
+tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
+ enum v4l2_mbus_pixelcode *code)
{
- if (fmt == NULL || fmt->index)
+ if (index)
return -EINVAL;
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- /* only capture is supported */
- return -EINVAL;
-
- /* only one format */
- fmt->flags = 0;
- strlcpy(fmt->description, "8-bit UYVY 4:2:2 Format",
- sizeof(fmt->description));
- fmt->pixelformat = V4L2_PIX_FMT_UYVY;
+ *code = V4L2_MBUS_FMT_YUYV10_2X10;
return 0;
}
/**
- * tvp514x_fmt_cap() - V4L2 decoder interface handler for try/s/g_fmt
+ * tvp514x_mbus_fmt_cap() - V4L2 decoder interface handler for try/s/g_mbus_fmt
* @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
+ * @f: pointer to the mediabus format structure
*
- * Implement the VIDIOC_TRY/S/G_FMT ioctl for the CAPTURE buffer type. This
- * ioctl is used to negotiate the image capture size and pixel format.
+ * Negotiates the image capture size and mediabus format.
*/
static int
-tvp514x_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
+tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
{
struct tvp514x_decoder *decoder = to_decoder(sd);
- struct v4l2_pix_format *pix;
enum tvp514x_std current_std;
if (f == NULL)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pix = &f->fmt.pix;
-
/* Calculate height and width based on current standard */
current_std = decoder->current_std;
- pix->pixelformat = V4L2_PIX_FMT_UYVY;
- pix->width = decoder->std_list[current_std].width;
- pix->height = decoder->std_list[current_std].height;
- pix->field = V4L2_FIELD_INTERLACED;
- pix->bytesperline = pix->width * 2;
- pix->sizeimage = pix->bytesperline * pix->height;
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pix->priv = 0;
-
- v4l2_dbg(1, debug, sd, "FMT: bytesperline - %d"
- "Width - %d, Height - %d\n",
- pix->bytesperline,
- pix->width, pix->height);
+ f->code = V4L2_MBUS_FMT_YUYV10_2X10;
+ f->width = decoder->std_list[current_std].width;
+ f->height = decoder->std_list[current_std].height;
+ f->field = V4L2_FIELD_INTERLACED;
+ f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+ v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n",
+ f->width, f->height);
return 0;
}
@@ -1131,10 +1114,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
.s_routing = tvp514x_s_routing,
.querystd = tvp514x_querystd,
- .enum_fmt = tvp514x_enum_fmt_cap,
- .g_fmt = tvp514x_fmt_cap,
- .try_fmt = tvp514x_fmt_cap,
- .s_fmt = tvp514x_fmt_cap,
+ .enum_mbus_fmt = tvp514x_enum_mbus_fmt,
+ .g_mbus_fmt = tvp514x_mbus_fmt,
+ .try_mbus_fmt = tvp514x_mbus_fmt,
+ .s_mbus_fmt = tvp514x_mbus_fmt,
.g_parm = tvp514x_g_parm,
.s_parm = tvp514x_s_parm,
.s_stream = tvp514x_s_stream,
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index 48f5c76ab521..e63b40f5a706 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -330,19 +330,6 @@ static const struct i2c_reg_value tvp7002_parms_720P50[] = {
{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
};
-/* Struct list for available formats */
-static const struct v4l2_fmtdesc tvp7002_fmt_list[] = {
- {
- .index = 0,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .flags = 0,
- .description = "8-bit UYVY 4:2:2 Format",
- .pixelformat = V4L2_PIX_FMT_UYVY,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(tvp7002_fmt_list)
-
/* Preset definition for handling device operation */
struct tvp7002_preset_definition {
u32 preset;
@@ -439,7 +426,6 @@ struct tvp7002 {
int ver;
int streaming;
- struct v4l2_pix_format pix;
const struct tvp7002_preset_definition *current_preset;
u8 gain;
};
@@ -695,81 +681,33 @@ static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
}
/*
- * tvp7002_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
+ * tvp7002_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt
* @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
+ * @f: pointer to mediabus format structure
*
- * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
- * ioctl is used to negotiate the image capture size and pixel format
- * without actually making it take effect.
+ * Negotiate the image capture size and mediabus format.
+ * There is only one possible format, so this single function works for
+ * get, set and try.
*/
-static int tvp7002_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
+static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
{
struct tvp7002 *device = to_tvp7002(sd);
struct v4l2_dv_enum_preset e_preset;
- struct v4l2_pix_format *pix;
- int error = 0;
-
- pix = &f->fmt.pix;
+ int error;
/* Calculate height and width based on current standard */
error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
if (error)
- return -EINVAL;
-
- pix->width = e_preset.width;
- pix->height = e_preset.height;
- pix->pixelformat = V4L2_PIX_FMT_UYVY;
- pix->field = device->current_preset->scanmode;
- pix->bytesperline = pix->width * 2;
- pix->sizeimage = pix->bytesperline * pix->height;
- pix->colorspace = device->current_preset->color_space;
- pix->priv = 0;
-
- v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
- "Width - %d, Height - %d", "8-bit UYVY 4:2:2 Format",
- pix->bytesperline, pix->width, pix->height);
- return error;
-}
-
-/*
- * tvp7002_s_fmt() - V4L2 decoder interface handler for s_fmt
- * @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
- *
- * If the requested format is supported, configures the HW to use that
- * format, returns error code if format not supported or HW can't be
- * correctly configured.
- */
-static int tvp7002_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
-{
- struct tvp7002 *decoder = to_tvp7002(sd);
- int rval;
-
- rval = tvp7002_try_fmt_cap(sd, f);
- if (!rval)
- decoder->pix = f->fmt.pix;
- return rval;
-}
-
-/*
- * tvp7002_g_fmt() - V4L2 decoder interface handler for tvp7002_g_fmt
- * @sd: pointer to standard V4L2 sub-device structure
- * @f: pointer to standard V4L2 v4l2_format structure
- *
- * Returns the decoder's current pixel format in the v4l2_format
- * parameter.
- */
-static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
-{
- struct tvp7002 *decoder = to_tvp7002(sd);
+ return error;
- f->fmt.pix = decoder->pix;
+ f->width = e_preset.width;
+ f->height = e_preset.height;
+ f->code = V4L2_MBUS_FMT_YUYV10_1X20;
+ f->field = device->current_preset->scanmode;
+ f->colorspace = device->current_preset->color_space;
- v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
- "Width - %d, Height - %d",
- decoder->pix.bytesperline,
- decoder->pix.width, decoder->pix.height);
+ v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d",
+ f->width, f->height);
return 0;
}
@@ -894,21 +832,21 @@ static int tvp7002_s_register(struct v4l2_subdev *sd,
#endif
/*
- * tvp7002_enum_fmt() - Enum supported formats
+ * tvp7002_enum_mbus_fmt() - Enum supported mediabus formats
* @sd: pointer to standard V4L2 sub-device structure
- * @fmtdesc: pointer to format struct
+ * @index: format index
+ * @code: pointer to mediabus format
*
- * Enumerate supported formats.
+ * Enumerate supported mediabus formats.
*/
-static int tvp7002_enum_fmt(struct v4l2_subdev *sd,
- struct v4l2_fmtdesc *fmtdesc)
+static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
+ enum v4l2_mbus_pixelcode *code)
{
/* Check requested format index is within range */
- if (fmtdesc->index < 0 || fmtdesc->index >= NUM_FORMATS)
+ if (index)
return -EINVAL;
- *fmtdesc = tvp7002_fmt_list[fmtdesc->index];
-
+ *code = V4L2_MBUS_FMT_YUYV10_1X20;
return 0;
}
@@ -1027,9 +965,10 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
.s_dv_preset = tvp7002_s_dv_preset,
.query_dv_preset = tvp7002_query_dv_preset,
.s_stream = tvp7002_s_stream,
- .g_fmt = tvp7002_g_fmt,
- .s_fmt = tvp7002_s_fmt,
- .enum_fmt = tvp7002_enum_fmt,
+ .g_mbus_fmt = tvp7002_mbus_fmt,
+ .try_mbus_fmt = tvp7002_mbus_fmt,
+ .s_mbus_fmt = tvp7002_mbus_fmt,
+ .enum_mbus_fmt = tvp7002_enum_mbus_fmt,
};
/* V4L2 top level operation handlers */
@@ -1040,17 +979,6 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
static struct tvp7002 tvp7002_dev = {
.streaming = 0,
-
- .pix = {
- .width = 1280,
- .height = 720,
- .pixelformat = V4L2_PIX_FMT_UYVY,
- .field = V4L2_FIELD_NONE,
- .bytesperline = 1280 * 2,
- .sizeimage = 1280 * 2 * 720,
- .colorspace = V4L2_COLORSPACE_REC709,
- },
-
.current_preset = tvp7002_presets,
.gain = 0,
};
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index a727962781a3..0347bbe36459 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -469,7 +469,7 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
*/
static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
u8 val;
int ret;
@@ -511,7 +511,7 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 val = VSSL_VVALID | HSSL_DVALID;
/*
@@ -565,7 +565,7 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
id->ident = V4L2_IDENT_TW9910;
@@ -578,7 +578,7 @@ static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
static int tw9910_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
if (reg->reg > 0xff)
@@ -600,7 +600,7 @@ static int tw9910_g_register(struct v4l2_subdev *sd,
static int tw9910_s_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
if (reg->reg > 0xff ||
reg->val > 0xff)
@@ -613,7 +613,7 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct v4l2_rect *rect = &a->c;
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
struct soc_camera_device *icd = client->dev.platform_data;
int ret = -EINVAL;
@@ -701,7 +701,7 @@ tw9910_set_fmt_error:
static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
if (!priv->scale) {
@@ -748,7 +748,7 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int tw9910_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
if (!priv->scale) {
@@ -778,7 +778,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
static int tw9910_s_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
/* See tw9910_s_crop() - no proper cropping support */
struct v4l2_crop a = {
@@ -813,7 +813,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
static int tw9910_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = sd->priv;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_device *icd = client->dev.platform_data;
const struct tw9910_scale_ctrl *scale;
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
index d6e16959f78b..dfa7fc68a657 100644
--- a/drivers/media/video/usbvideo/Kconfig
+++ b/drivers/media/video/usbvideo/Kconfig
@@ -12,10 +12,13 @@ config USB_VICAM
module will be called vicam.
config USB_IBMCAM
- tristate "USB IBM (Xirlink) C-it Camera support"
+ tristate "USB IBM (Xirlink) C-it Camera support (DEPRECATED)"
depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
+ This driver is DEPRECATED please use the gspca xirlink_cit module
+ instead.
+
Say Y here if you want to connect a IBM "C-It" camera, also known as
"Xirlink PC Camera" to your computer's USB port.
@@ -27,10 +30,13 @@ config USB_IBMCAM
<file:Documentation/video4linux/ibmcam.txt> to learn more.
config USB_KONICAWC
- tristate "USB Konica Webcam support"
+ tristate "USB Konica Webcam support (DEPRECATED)"
depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
+ This driver is DEPRECATED (and known to crash) please use the
+ gspca konica module instead.
+
Say Y here if you want support for webcams based on a Konica
chipset. This is known to work with the Intel YC76 webcam.
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h
index 5c27b251354e..b654bfff8740 100644
--- a/drivers/media/video/zoran/videocodec.h
+++ b/drivers/media/video/zoran/videocodec.h
@@ -56,7 +56,7 @@
the slave is bound to it). Otherwise it doesn't need this functions and
therfor they may not be initialized.
- The other fuctions are just for convenience, as they are for sure used by
+ The other functions are just for convenience, as they are for sure used by
most/all of the codecs. The last ones may be ommited, too.
See the structure declaration below for more information and which data has
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 6f89d0a096ea..c155ddfb1332 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -3322,7 +3322,7 @@ zoran_mmap (struct file *file,
mmap_unlock_and_return:
mutex_unlock(&zr->resource_lock);
- return 0;
+ return res;
}
static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index a82b5bd18d26..616c61fb3493 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -572,7 +572,7 @@ static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize)
DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
unlock:
spin_unlock_irqrestore(&cam->slock, flags);
- return 0;
+ return rc;
}
/* this function moves the usb stream read pipe data
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index d3f1a087eced..02362eccc588 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -18,11 +18,12 @@
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/memstick.h>
#define DRIVER_NAME "mspro_block"
+static DEFINE_MUTEX(mspro_block_mutex);
static int major;
module_param(major, int, 0644);
@@ -180,7 +181,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode)
struct mspro_block_data *msb = disk->private_data;
int rc = -ENXIO;
- lock_kernel();
+ mutex_lock(&mspro_block_mutex);
mutex_lock(&mspro_block_disk_lock);
if (msb && msb->card) {
@@ -192,7 +193,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode)
}
mutex_unlock(&mspro_block_disk_lock);
- unlock_kernel();
+ mutex_unlock(&mspro_block_mutex);
return rc;
}
@@ -225,9 +226,9 @@ static int mspro_block_disk_release(struct gendisk *disk)
static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode)
{
int ret;
- lock_kernel();
+ mutex_lock(&mspro_block_mutex);
ret = mspro_block_disk_release(disk);
- unlock_kernel();
+ mutex_unlock(&mspro_block_mutex);
return ret;
}
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 6837a8ef9371..3e57b61ca446 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -5945,8 +5945,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
goto out;
mem = kmalloc(iocpage2sz, GFP_KERNEL);
- if (!mem)
+ if (!mem) {
+ rc = -ENOMEM;
goto out;
+ }
memcpy(mem, (u8 *)pIoc2, iocpage2sz);
ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index d8ddfdf8be14..a3856ed90aef 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -54,7 +54,7 @@
#include <linux/pci.h>
#include <linux/delay.h> /* for mdelay */
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compat.h>
#include <asm/io.h>
@@ -83,6 +83,7 @@ MODULE_VERSION(my_VERSION);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static DEFINE_MUTEX(mpctl_mutex);
static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
@@ -601,12 +602,12 @@ mptctl_fasync(int fd, struct file *filep, int mode)
MPT_ADAPTER *ioc;
int ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
list_for_each_entry(ioc, &ioc_list, list)
ioc->aen_event_read_flag=0;
ret = fasync_helper(fd, filep, mode, &async_queue);
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
@@ -698,9 +699,9 @@ static long
mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
ret = __mptctl_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
@@ -2926,7 +2927,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
switch (cmd) {
case MPTIOCINFO:
case MPTIOCINFO1:
@@ -2951,7 +2952,7 @@ static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long a
ret = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index f0f1e667000f..f87a9d405a5e 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -53,7 +53,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2o.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/mempool.h>
@@ -69,6 +69,7 @@
#define OSM_VERSION "1.325"
#define OSM_DESCRIPTION "I2O Block Device OSM"
+static DEFINE_MUTEX(i2o_block_mutex);
static struct i2o_driver i2o_block_driver;
/* global Block OSM request mempool */
@@ -578,7 +579,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode)
if (!dev->i2o_dev)
return -ENODEV;
- lock_kernel();
+ mutex_lock(&i2o_block_mutex);
if (dev->power > 0x1f)
i2o_block_device_power(dev, 0x02);
@@ -587,7 +588,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode)
i2o_block_device_lock(dev->i2o_dev, -1);
osm_debug("Ready.\n");
- unlock_kernel();
+ mutex_unlock(&i2o_block_mutex);
return 0;
};
@@ -618,7 +619,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode)
if (!dev->i2o_dev)
return 0;
- lock_kernel();
+ mutex_lock(&i2o_block_mutex);
i2o_block_device_flush(dev->i2o_dev);
i2o_block_device_unlock(dev->i2o_dev, -1);
@@ -629,7 +630,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode)
operation = 0x24;
i2o_block_device_power(dev, operation);
- unlock_kernel();
+ mutex_unlock(&i2o_block_mutex);
return 0;
}
@@ -664,7 +665,7 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- lock_kernel();
+ mutex_lock(&i2o_block_mutex);
switch (cmd) {
case BLKI2OGRSTRAT:
ret = put_user(dev->rcache, (int __user *)arg);
@@ -688,7 +689,7 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
ret = 0;
break;
}
- unlock_kernel();
+ mutex_unlock(&i2o_block_mutex);
return ret;
};
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 068ba0785bb4..7d3cc575c361 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -31,7 +31,7 @@
*/
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compat.h>
#include <linux/slab.h>
@@ -41,6 +41,7 @@
#define SG_TABLESIZE 30
+static DEFINE_MUTEX(i2o_cfg_mutex);
static long i2o_cfg_ioctl(struct file *, unsigned int, unsigned long);
static spinlock_t i2o_config_lock;
@@ -741,7 +742,7 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&i2o_cfg_mutex);
switch (cmd) {
case I2OGETIOPS:
ret = i2o_cfg_ioctl(file, cmd, arg);
@@ -753,7 +754,7 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
ret = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
+ mutex_unlock(&i2o_cfg_mutex);
return ret;
}
@@ -981,7 +982,7 @@ static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&i2o_cfg_mutex);
switch (cmd) {
case I2OGETIOPS:
ret = i2o_cfg_getiops(arg);
@@ -1037,7 +1038,7 @@ static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
osm_debug("unknown ioctl called!\n");
ret = -EINVAL;
}
- unlock_kernel();
+ mutex_unlock(&i2o_cfg_mutex);
return ret;
}
@@ -1051,7 +1052,7 @@ static int cfg_open(struct inode *inode, struct file *file)
if (!tmp)
return -ENOMEM;
- lock_kernel();
+ mutex_lock(&i2o_cfg_mutex);
file->private_data = (void *)(i2o_cfg_info_id++);
tmp->fp = file;
tmp->fasync = NULL;
@@ -1065,7 +1066,7 @@ static int cfg_open(struct inode *inode, struct file *file)
spin_lock_irqsave(&i2o_config_lock, flags);
open_files = tmp;
spin_unlock_irqrestore(&i2o_config_lock, flags);
- unlock_kernel();
+ mutex_unlock(&i2o_cfg_mutex);
return 0;
}
@@ -1076,14 +1077,14 @@ static int cfg_fasync(int fd, struct file *fp, int on)
struct i2o_cfg_info *p;
int ret = -EBADF;
- lock_kernel();
+ mutex_lock(&i2o_cfg_mutex);
for (p = open_files; p; p = p->next)
if (p->q_id == id)
break;
if (p)
ret = fasync_helper(fd, fp, on, &p->fasync);
- unlock_kernel();
+ mutex_unlock(&i2o_cfg_mutex);
return ret;
}
@@ -1093,7 +1094,7 @@ static int cfg_release(struct inode *inode, struct file *file)
struct i2o_cfg_info *p, **q;
unsigned long flags;
- lock_kernel();
+ mutex_lock(&i2o_cfg_mutex);
spin_lock_irqsave(&i2o_config_lock, flags);
for (q = &open_files; (p = *q) != NULL; q = &p->next) {
if (p->q_id == id) {
@@ -1103,7 +1104,7 @@ static int cfg_release(struct inode *inode, struct file *file)
}
}
spin_unlock_irqrestore(&i2o_config_lock, flags);
- unlock_kernel();
+ mutex_unlock(&i2o_cfg_mutex);
return 0;
}
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 07933f3f7e4c..20895e7a99c9 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -158,6 +158,43 @@ static struct mfd_cell onkey_devs[] = {
},
};
+static struct resource codec_resources[] = {
+ {
+ /* Headset microphone insertion or removal */
+ .name = "micin",
+ .start = PM8607_IRQ_MICIN,
+ .end = PM8607_IRQ_MICIN,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* Hook-switch press or release */
+ .name = "hook",
+ .start = PM8607_IRQ_HOOK,
+ .end = PM8607_IRQ_HOOK,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* Headset insertion or removal */
+ .name = "headset",
+ .start = PM8607_IRQ_HEADSET,
+ .end = PM8607_IRQ_HEADSET,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* Audio short */
+ .name = "audio-short",
+ .start = PM8607_IRQ_AUDIO_SHORT,
+ .end = PM8607_IRQ_AUDIO_SHORT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell codec_devs[] = {
+ {
+ .name = "88pm860x-codec",
+ .num_resources = ARRAY_SIZE(codec_resources),
+ .resources = &codec_resources[0],
+ .id = -1,
+ },
+};
+
static struct resource regulator_resources[] = {
PM8607_REG_RESOURCE(BUCK1, BUCK1),
PM8607_REG_RESOURCE(BUCK2, BUCK2),
@@ -608,10 +645,13 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
goto out;
}
- if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION)
+ switch (ret & PM8607_VERSION_MASK) {
+ case 0x40:
+ case 0x50:
dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
ret);
- else {
+ break;
+ default:
dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
"Chip ID: %02x\n", ret);
goto out;
@@ -687,6 +727,13 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
goto out_dev;
}
+ ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
+ ARRAY_SIZE(codec_devs),
+ &codec_resources[0], 0);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add codec subdev\n");
+ goto out_dev;
+ }
return;
out_dev:
mfd_remove_devices(chip->dev);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index db51ea1c6082..fbfe14af24f2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -294,14 +294,15 @@ config MFD_MAX8925
to use the functionality of the device.
config MFD_MAX8998
- bool "Maxim Semiconductor MAX8998 PMIC Support"
- depends on I2C=y
+ bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support"
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
help
- Say yes here to support for Maxim Semiconductor MAX8998. This is
- a Power Management IC. This driver provies common support for
- accessing the device, additional drivers must be enabled in order
- to use the functionality of the device.
+ Say yes here to support for Maxim Semiconductor MAX8998 and
+ National Semiconductor LP3974. This is a Power Management IC.
+ This driver provies common support for accessing the device,
+ additional drivers must be enabled in order to use the functionality
+ of the device.
config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400"
@@ -433,7 +434,7 @@ config PCF50633_GPIO
config ABX500_CORE
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
- default y if ARCH_U300
+ default y if ARCH_U300 || ARCH_U8500
help
Say yes here if you have the ABX500 Mixed Signal IC family
chips. This core driver expose register access functions.
@@ -444,6 +445,7 @@ config ABX500_CORE
config AB3100_CORE
bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
depends on I2C=y && ABX500_CORE
+ select MFD_CORE
default y if ARCH_U300
help
Select this to enable the AB3100 Mixed Signal IC core
@@ -473,14 +475,33 @@ config EZX_PCAP
config AB8500_CORE
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
- depends on SPI=y && GENERIC_HARDIRQS
+ depends on GENERIC_HARDIRQS && ABX500_CORE
select MFD_CORE
help
Select this option to enable access to AB8500 power management
- chip. This connects to U8500 on the SSP/SPI bus and exports
- read/write functions for the devices to get access to this chip.
+ chip. This connects to U8500 either on the SSP/SPI bus
+ or the I2C bus via PRCMU. It also adds the irq_chip
+ parts for handling the Mixed Signal chip events.
This chip embeds various other multimedia funtionalities as well.
+config AB8500_I2C_CORE
+ bool "AB8500 register access via PRCMU I2C"
+ depends on AB8500_CORE && UX500_SOC_DB8500
+ default y
+ help
+ This enables register access to the AB8500 chip via PRCMU I2C.
+ The AB8500 chip can be accessed via SPI or I2C. On DB8500 hardware
+ the I2C bus is connected to the Power Reset
+ and Mangagement Unit, PRCMU.
+
+config AB8500_DEBUG
+ bool "Enable debug info via debugfs"
+ depends on AB8500_CORE && DEBUG_FS
+ default y if DEBUG_FS
+ help
+ Select this option if you want debug information using the debug
+ filesystem, debugfs.
+
config AB3550_CORE
bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index feaeeaeeddb7..d5968cd93048 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -58,7 +58,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o
max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o
-obj-$(CONFIG_MFD_MAX8998) += max8998.o
+obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o
pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
@@ -69,6 +69,8 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o
+obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
+obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
obj-$(CONFIG_LPC_SCH) += lpc_sch.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 66379b413906..94bf107b6aac 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -19,6 +19,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
+#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
/* These are the only registers inside AB3100 used in this main file */
@@ -146,7 +147,7 @@ static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100,
}
static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
- u8 reg, u8 *regval)
+ u8 reg, u8 *regval)
{
int err;
@@ -202,7 +203,7 @@ static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
}
static int get_register_interruptible(struct device *dev, u8 bank, u8 reg,
- u8 *value)
+ u8 *value)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
@@ -583,6 +584,7 @@ static ssize_t ab3100_get_set_reg(struct file *file,
static const struct file_operations ab3100_get_set_reg_fops = {
.open = ab3100_get_set_reg_open_file,
.write = ab3100_get_set_reg,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static struct dentry *ab3100_dir;
@@ -665,7 +667,7 @@ struct ab3100_init_setting {
u8 setting;
};
-static const struct ab3100_init_setting __initconst
+static const struct ab3100_init_setting __devinitconst
ab3100_init_settings[] = {
{
.abreg = AB3100_MCA,
@@ -712,7 +714,7 @@ ab3100_init_settings[] = {
},
};
-static int __init ab3100_setup(struct ab3100 *ab3100)
+static int __devinit ab3100_setup(struct ab3100 *ab3100)
{
int err = 0;
int i;
@@ -742,52 +744,64 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
return err;
}
-/*
- * Here we define all the platform devices that appear
- * as children of the AB3100. These are regular platform
- * devices with the IORESOURCE_IO .start and .end set
- * to correspond to the internal AB3100 register range
- * mapping to the corresponding subdevice.
- */
-
-#define AB3100_DEVICE(devname, devid) \
-static struct platform_device ab3100_##devname##_device = { \
- .name = devid, \
- .id = -1, \
-}
-
-/* This lists all the subdevices */
-AB3100_DEVICE(dac, "ab3100-dac");
-AB3100_DEVICE(leds, "ab3100-leds");
-AB3100_DEVICE(power, "ab3100-power");
-AB3100_DEVICE(regulators, "ab3100-regulators");
-AB3100_DEVICE(sim, "ab3100-sim");
-AB3100_DEVICE(uart, "ab3100-uart");
-AB3100_DEVICE(rtc, "ab3100-rtc");
-AB3100_DEVICE(charger, "ab3100-charger");
-AB3100_DEVICE(boost, "ab3100-boost");
-AB3100_DEVICE(adc, "ab3100-adc");
-AB3100_DEVICE(fuelgauge, "ab3100-fuelgauge");
-AB3100_DEVICE(vibrator, "ab3100-vibrator");
-AB3100_DEVICE(otp, "ab3100-otp");
-AB3100_DEVICE(codec, "ab3100-codec");
-
-static struct platform_device *
-ab3100_platform_devs[] = {
- &ab3100_dac_device,
- &ab3100_leds_device,
- &ab3100_power_device,
- &ab3100_regulators_device,
- &ab3100_sim_device,
- &ab3100_uart_device,
- &ab3100_rtc_device,
- &ab3100_charger_device,
- &ab3100_boost_device,
- &ab3100_adc_device,
- &ab3100_fuelgauge_device,
- &ab3100_vibrator_device,
- &ab3100_otp_device,
- &ab3100_codec_device,
+/* The subdevices of the AB3100 */
+static struct mfd_cell ab3100_devs[] = {
+ {
+ .name = "ab3100-dac",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-leds",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-power",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-regulators",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-sim",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-uart",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-rtc",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-charger",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-boost",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-adc",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-fuelgauge",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-vibrator",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-otp",
+ .id = -1,
+ },
+ {
+ .name = "ab3100-codec",
+ .id = -1,
+ },
};
struct ab_family_id {
@@ -795,7 +809,7 @@ struct ab_family_id {
char *name;
};
-static const struct ab_family_id ids[] __initdata = {
+static const struct ab_family_id ids[] __devinitdata = {
/* AB3100 */
{
.id = 0xc0,
@@ -849,8 +863,8 @@ static const struct ab_family_id ids[] __initdata = {
},
};
-static int __init ab3100_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int __devinit ab3100_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct ab3100 *ab3100;
struct ab3100_platform_data *ab3100_plf_data =
@@ -934,18 +948,14 @@ static int __init ab3100_probe(struct i2c_client *client,
if (err)
goto exit_no_ops;
- /* Set parent and a pointer back to the container in device data */
- for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) {
- ab3100_platform_devs[i]->dev.parent =
- &client->dev;
- ab3100_platform_devs[i]->dev.platform_data =
- ab3100_plf_data;
- platform_set_drvdata(ab3100_platform_devs[i], ab3100);
+ /* Set up and register the platform devices. */
+ for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) {
+ ab3100_devs[i].platform_data = ab3100_plf_data;
+ ab3100_devs[i].data_size = sizeof(struct ab3100_platform_data);
}
- /* Register the platform devices */
- platform_add_devices(ab3100_platform_devs,
- ARRAY_SIZE(ab3100_platform_devs));
+ err = mfd_add_devices(&client->dev, 0, ab3100_devs,
+ ARRAY_SIZE(ab3100_devs), NULL, 0);
ab3100_setup_debugfs(ab3100);
@@ -961,14 +971,12 @@ static int __init ab3100_probe(struct i2c_client *client,
return err;
}
-static int __exit ab3100_remove(struct i2c_client *client)
+static int __devexit ab3100_remove(struct i2c_client *client)
{
struct ab3100 *ab3100 = i2c_get_clientdata(client);
- int i;
/* Unregister subdevices */
- for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++)
- platform_device_unregister(ab3100_platform_devs[i]);
+ mfd_remove_devices(&client->dev);
ab3100_remove_debugfs();
i2c_unregister_device(ab3100->testreg_client);
@@ -995,7 +1003,7 @@ static struct i2c_driver ab3100_driver = {
},
.id_table = ab3100_id,
.probe = ab3100_probe,
- .remove = __exit_p(ab3100_remove),
+ .remove = __devexit_p(ab3100_remove),
};
static int __init ab3100_i2c_init(void)
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index defa786dee34..d21362bf6b0e 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -4,6 +4,7 @@
* License Terms: GNU General Public License v2
* Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
* Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * Changes: Mattias Wallin <mattias.wallin@stericsson.com>
*/
#include <linux/kernel.h>
@@ -15,6 +16,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
+#include <linux/mfd/abx500.h>
#include <linux/mfd/ab8500.h>
#include <linux/regulator/ab8500.h>
@@ -22,71 +24,71 @@
* Interrupt register offsets
* Bank : 0x0E
*/
-#define AB8500_IT_SOURCE1_REG 0x0E00
-#define AB8500_IT_SOURCE2_REG 0x0E01
-#define AB8500_IT_SOURCE3_REG 0x0E02
-#define AB8500_IT_SOURCE4_REG 0x0E03
-#define AB8500_IT_SOURCE5_REG 0x0E04
-#define AB8500_IT_SOURCE6_REG 0x0E05
-#define AB8500_IT_SOURCE7_REG 0x0E06
-#define AB8500_IT_SOURCE8_REG 0x0E07
-#define AB8500_IT_SOURCE19_REG 0x0E12
-#define AB8500_IT_SOURCE20_REG 0x0E13
-#define AB8500_IT_SOURCE21_REG 0x0E14
-#define AB8500_IT_SOURCE22_REG 0x0E15
-#define AB8500_IT_SOURCE23_REG 0x0E16
-#define AB8500_IT_SOURCE24_REG 0x0E17
+#define AB8500_IT_SOURCE1_REG 0x00
+#define AB8500_IT_SOURCE2_REG 0x01
+#define AB8500_IT_SOURCE3_REG 0x02
+#define AB8500_IT_SOURCE4_REG 0x03
+#define AB8500_IT_SOURCE5_REG 0x04
+#define AB8500_IT_SOURCE6_REG 0x05
+#define AB8500_IT_SOURCE7_REG 0x06
+#define AB8500_IT_SOURCE8_REG 0x07
+#define AB8500_IT_SOURCE19_REG 0x12
+#define AB8500_IT_SOURCE20_REG 0x13
+#define AB8500_IT_SOURCE21_REG 0x14
+#define AB8500_IT_SOURCE22_REG 0x15
+#define AB8500_IT_SOURCE23_REG 0x16
+#define AB8500_IT_SOURCE24_REG 0x17
/*
* latch registers
*/
-#define AB8500_IT_LATCH1_REG 0x0E20
-#define AB8500_IT_LATCH2_REG 0x0E21
-#define AB8500_IT_LATCH3_REG 0x0E22
-#define AB8500_IT_LATCH4_REG 0x0E23
-#define AB8500_IT_LATCH5_REG 0x0E24
-#define AB8500_IT_LATCH6_REG 0x0E25
-#define AB8500_IT_LATCH7_REG 0x0E26
-#define AB8500_IT_LATCH8_REG 0x0E27
-#define AB8500_IT_LATCH9_REG 0x0E28
-#define AB8500_IT_LATCH10_REG 0x0E29
-#define AB8500_IT_LATCH19_REG 0x0E32
-#define AB8500_IT_LATCH20_REG 0x0E33
-#define AB8500_IT_LATCH21_REG 0x0E34
-#define AB8500_IT_LATCH22_REG 0x0E35
-#define AB8500_IT_LATCH23_REG 0x0E36
-#define AB8500_IT_LATCH24_REG 0x0E37
+#define AB8500_IT_LATCH1_REG 0x20
+#define AB8500_IT_LATCH2_REG 0x21
+#define AB8500_IT_LATCH3_REG 0x22
+#define AB8500_IT_LATCH4_REG 0x23
+#define AB8500_IT_LATCH5_REG 0x24
+#define AB8500_IT_LATCH6_REG 0x25
+#define AB8500_IT_LATCH7_REG 0x26
+#define AB8500_IT_LATCH8_REG 0x27
+#define AB8500_IT_LATCH9_REG 0x28
+#define AB8500_IT_LATCH10_REG 0x29
+#define AB8500_IT_LATCH19_REG 0x32
+#define AB8500_IT_LATCH20_REG 0x33
+#define AB8500_IT_LATCH21_REG 0x34
+#define AB8500_IT_LATCH22_REG 0x35
+#define AB8500_IT_LATCH23_REG 0x36
+#define AB8500_IT_LATCH24_REG 0x37
/*
* mask registers
*/
-#define AB8500_IT_MASK1_REG 0x0E40
-#define AB8500_IT_MASK2_REG 0x0E41
-#define AB8500_IT_MASK3_REG 0x0E42
-#define AB8500_IT_MASK4_REG 0x0E43
-#define AB8500_IT_MASK5_REG 0x0E44
-#define AB8500_IT_MASK6_REG 0x0E45
-#define AB8500_IT_MASK7_REG 0x0E46
-#define AB8500_IT_MASK8_REG 0x0E47
-#define AB8500_IT_MASK9_REG 0x0E48
-#define AB8500_IT_MASK10_REG 0x0E49
-#define AB8500_IT_MASK11_REG 0x0E4A
-#define AB8500_IT_MASK12_REG 0x0E4B
-#define AB8500_IT_MASK13_REG 0x0E4C
-#define AB8500_IT_MASK14_REG 0x0E4D
-#define AB8500_IT_MASK15_REG 0x0E4E
-#define AB8500_IT_MASK16_REG 0x0E4F
-#define AB8500_IT_MASK17_REG 0x0E50
-#define AB8500_IT_MASK18_REG 0x0E51
-#define AB8500_IT_MASK19_REG 0x0E52
-#define AB8500_IT_MASK20_REG 0x0E53
-#define AB8500_IT_MASK21_REG 0x0E54
-#define AB8500_IT_MASK22_REG 0x0E55
-#define AB8500_IT_MASK23_REG 0x0E56
-#define AB8500_IT_MASK24_REG 0x0E57
-
-#define AB8500_REV_REG 0x1080
+#define AB8500_IT_MASK1_REG 0x40
+#define AB8500_IT_MASK2_REG 0x41
+#define AB8500_IT_MASK3_REG 0x42
+#define AB8500_IT_MASK4_REG 0x43
+#define AB8500_IT_MASK5_REG 0x44
+#define AB8500_IT_MASK6_REG 0x45
+#define AB8500_IT_MASK7_REG 0x46
+#define AB8500_IT_MASK8_REG 0x47
+#define AB8500_IT_MASK9_REG 0x48
+#define AB8500_IT_MASK10_REG 0x49
+#define AB8500_IT_MASK11_REG 0x4A
+#define AB8500_IT_MASK12_REG 0x4B
+#define AB8500_IT_MASK13_REG 0x4C
+#define AB8500_IT_MASK14_REG 0x4D
+#define AB8500_IT_MASK15_REG 0x4E
+#define AB8500_IT_MASK16_REG 0x4F
+#define AB8500_IT_MASK17_REG 0x50
+#define AB8500_IT_MASK18_REG 0x51
+#define AB8500_IT_MASK19_REG 0x52
+#define AB8500_IT_MASK20_REG 0x53
+#define AB8500_IT_MASK21_REG 0x54
+#define AB8500_IT_MASK22_REG 0x55
+#define AB8500_IT_MASK23_REG 0x56
+#define AB8500_IT_MASK24_REG 0x57
+
+#define AB8500_REV_REG 0x80
/*
* Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
@@ -99,96 +101,132 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21,
};
-static int __ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data)
+static int ab8500_get_chip_id(struct device *dev)
+{
+ struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
+ return (int)ab8500->chip_id;
+}
+
+static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
+ u8 reg, u8 data)
{
int ret;
+ /*
+ * Put the u8 bank and u8 register together into a an u16.
+ * The bank on higher 8 bits and register in lower 8 bits.
+ * */
+ u16 addr = ((u16)bank) << 8 | reg;
dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
+ ret = mutex_lock_interruptible(&ab8500->lock);
+ if (ret)
+ return ret;
+
ret = ab8500->write(ab8500, addr, data);
if (ret < 0)
dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
addr, ret);
+ mutex_unlock(&ab8500->lock);
return ret;
}
-/**
- * ab8500_write() - write an AB8500 register
- * @ab8500: device to write to
- * @addr: address of the register
- * @data: value to write
- */
-int ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data)
+static int ab8500_set_register(struct device *dev, u8 bank,
+ u8 reg, u8 value)
{
- int ret;
-
- mutex_lock(&ab8500->lock);
- ret = __ab8500_write(ab8500, addr, data);
- mutex_unlock(&ab8500->lock);
+ struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
- return ret;
+ return set_register_interruptible(ab8500, bank, reg, value);
}
-EXPORT_SYMBOL_GPL(ab8500_write);
-static int __ab8500_read(struct ab8500 *ab8500, u16 addr)
+static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
+ u8 reg, u8 *value)
{
int ret;
+ /* put the u8 bank and u8 reg together into a an u16.
+ * bank on higher 8 bits and reg in lower */
+ u16 addr = ((u16)bank) << 8 | reg;
+
+ ret = mutex_lock_interruptible(&ab8500->lock);
+ if (ret)
+ return ret;
ret = ab8500->read(ab8500, addr);
if (ret < 0)
dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
addr, ret);
+ else
+ *value = ret;
+ mutex_unlock(&ab8500->lock);
dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret);
return ret;
}
-/**
- * ab8500_read() - read an AB8500 register
- * @ab8500: device to read from
- * @addr: address of the register
- */
-int ab8500_read(struct ab8500 *ab8500, u16 addr)
+static int ab8500_get_register(struct device *dev, u8 bank,
+ u8 reg, u8 *value)
{
- int ret;
+ struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
- mutex_lock(&ab8500->lock);
- ret = __ab8500_read(ab8500, addr);
- mutex_unlock(&ab8500->lock);
-
- return ret;
+ return get_register_interruptible(ab8500, bank, reg, value);
}
-EXPORT_SYMBOL_GPL(ab8500_read);
-
-/**
- * ab8500_set_bits() - set a bitfield in an AB8500 register
- * @ab8500: device to read from
- * @addr: address of the register
- * @mask: mask of the bitfield to modify
- * @data: value to set to the bitfield
- */
-int ab8500_set_bits(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data)
+
+static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
+ u8 reg, u8 bitmask, u8 bitvalues)
{
int ret;
+ u8 data;
+ /* put the u8 bank and u8 reg together into a an u16.
+ * bank on higher 8 bits and reg in lower */
+ u16 addr = ((u16)bank) << 8 | reg;
- mutex_lock(&ab8500->lock);
+ ret = mutex_lock_interruptible(&ab8500->lock);
+ if (ret)
+ return ret;
- ret = __ab8500_read(ab8500, addr);
- if (ret < 0)
+ ret = ab8500->read(ab8500, addr);
+ if (ret < 0) {
+ dev_err(ab8500->dev, "failed to read reg %#x: %d\n",
+ addr, ret);
goto out;
+ }
- ret &= ~mask;
- ret |= data;
+ data = (u8)ret;
+ data = (~bitmask & data) | (bitmask & bitvalues);
- ret = __ab8500_write(ab8500, addr, ret);
+ ret = ab8500->write(ab8500, addr, data);
+ if (ret < 0)
+ dev_err(ab8500->dev, "failed to write reg %#x: %d\n",
+ addr, ret);
+ dev_vdbg(ab8500->dev, "mask: addr %#x => data %#x\n", addr, data);
out:
mutex_unlock(&ab8500->lock);
return ret;
}
-EXPORT_SYMBOL_GPL(ab8500_set_bits);
+
+static int ab8500_mask_and_set_register(struct device *dev,
+ u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
+{
+ struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
+
+ return mask_and_set_register_interruptible(ab8500, bank, reg,
+ bitmask, bitvalues);
+
+}
+
+static struct abx500_ops ab8500_ops = {
+ .get_chip_id = ab8500_get_chip_id,
+ .get_register = ab8500_get_register,
+ .set_register = ab8500_set_register,
+ .get_register_page = NULL,
+ .set_register_page = NULL,
+ .mask_and_set_register = ab8500_mask_and_set_register,
+ .event_registers_startup_state_get = NULL,
+ .startup_irq_enabled = NULL,
+};
static void ab8500_irq_lock(unsigned int irq)
{
@@ -213,7 +251,7 @@ static void ab8500_irq_sync_unlock(unsigned int irq)
ab8500->oldmask[i] = new;
reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i];
- ab8500_write(ab8500, reg, new);
+ set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
}
mutex_unlock(&ab8500->irq_lock);
@@ -257,9 +295,11 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
int regoffset = ab8500_irq_regoffset[i];
int status;
+ u8 value;
- status = ab8500_read(ab8500, AB8500_IT_LATCH1_REG + regoffset);
- if (status <= 0)
+ status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
+ AB8500_IT_LATCH1_REG + regoffset, &value);
+ if (status < 0 || value == 0)
continue;
do {
@@ -267,8 +307,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
int line = i * 8 + bit;
handle_nested_irq(ab8500->irq_base + line);
- status &= ~(1 << bit);
- } while (status);
+ value &= ~(1 << bit);
+ } while (value);
}
return IRQ_HANDLED;
@@ -338,7 +378,27 @@ static struct resource ab8500_rtc_resources[] = {
},
};
+static struct resource ab8500_poweronkey_db_resources[] = {
+ {
+ .name = "ONKEY_DBF",
+ .start = AB8500_INT_PON_KEY1DB_F,
+ .end = AB8500_INT_PON_KEY1DB_F,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "ONKEY_DBR",
+ .start = AB8500_INT_PON_KEY1DB_R,
+ .end = AB8500_INT_PON_KEY1DB_R,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct mfd_cell ab8500_devs[] = {
+#ifdef CONFIG_DEBUG_FS
+ {
+ .name = "ab8500-debug",
+ },
+#endif
{
.name = "ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
@@ -354,6 +414,11 @@ static struct mfd_cell ab8500_devs[] = {
{ .name = "ab8500-usb", },
{ .name = "ab8500-pwm", },
{ .name = "ab8500-regulator", },
+ {
+ .name = "ab8500-poweron-key",
+ .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
+ .resources = ab8500_poweronkey_db_resources,
+ },
};
int __devinit ab8500_init(struct ab8500 *ab8500)
@@ -361,6 +426,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev);
int ret;
int i;
+ u8 value;
if (plat)
ab8500->irq_base = plat->irq_base;
@@ -368,7 +434,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
mutex_init(&ab8500->lock);
mutex_init(&ab8500->irq_lock);
- ret = ab8500_read(ab8500, AB8500_REV_REG);
+ ret = get_register_interruptible(ab8500, AB8500_MISC,
+ AB8500_REV_REG, &value);
if (ret < 0)
return ret;
@@ -377,28 +444,37 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
* 0x10 - Cut 1.0
* 0x11 - Cut 1.1
*/
- if (ret == 0x0 || ret == 0x10 || ret == 0x11) {
- ab8500->revision = ret;
- dev_info(ab8500->dev, "detected chip, revision: %#x\n", ret);
+ if (value == 0x0 || value == 0x10 || value == 0x11) {
+ ab8500->revision = value;
+ dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
} else {
- dev_err(ab8500->dev, "unknown chip, revision: %#x\n", ret);
+ dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
return -EINVAL;
}
+ ab8500->chip_id = value;
if (plat && plat->init)
plat->init(ab8500);
/* Clear and mask all interrupts */
for (i = 0; i < 10; i++) {
- ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i);
- ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff);
+ get_register_interruptible(ab8500, AB8500_INTERRUPT,
+ AB8500_IT_LATCH1_REG + i, &value);
+ set_register_interruptible(ab8500, AB8500_INTERRUPT,
+ AB8500_IT_MASK1_REG + i, 0xff);
}
for (i = 18; i < 24; i++) {
- ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i);
- ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff);
+ get_register_interruptible(ab8500, AB8500_INTERRUPT,
+ AB8500_IT_LATCH1_REG + i, &value);
+ set_register_interruptible(ab8500, AB8500_INTERRUPT,
+ AB8500_IT_MASK1_REG + i, 0xff);
}
+ ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
+ if (ret)
+ return ret;
+
for (i = 0; i < AB8500_NUM_IRQ_REGS; i++)
ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
new file mode 100644
index 000000000000..8d1e05a39815
--- /dev/null
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
+ * License Terms: GNU General Public License v2
+ */
+
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab8500.h>
+
+static u32 debug_bank;
+static u32 debug_address;
+
+/**
+ * struct ab8500_reg_range
+ * @first: the first address of the range
+ * @last: the last address of the range
+ * @perm: access permissions for the range
+ */
+struct ab8500_reg_range {
+ u8 first;
+ u8 last;
+ u8 perm;
+};
+
+/**
+ * struct ab8500_i2c_ranges
+ * @num_ranges: the number of ranges in the list
+ * @bankid: bank identifier
+ * @range: the list of register ranges
+ */
+struct ab8500_i2c_ranges {
+ u8 num_ranges;
+ u8 bankid;
+ const struct ab8500_reg_range *range;
+};
+
+#define AB8500_NAME_STRING "ab8500"
+#define AB8500_NUM_BANKS 22
+
+#define AB8500_REV_REG 0x80
+
+static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = {
+ [0x0] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [AB8500_SYS_CTRL1_BLOCK] = {
+ .num_ranges = 3,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x02,
+ },
+ {
+ .first = 0x42,
+ .last = 0x42,
+ },
+ {
+ .first = 0x80,
+ .last = 0x81,
+ },
+ },
+ },
+ [AB8500_SYS_CTRL2_BLOCK] = {
+ .num_ranges = 4,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x0D,
+ },
+ {
+ .first = 0x0F,
+ .last = 0x17,
+ },
+ {
+ .first = 0x30,
+ .last = 0x30,
+ },
+ {
+ .first = 0x32,
+ .last = 0x33,
+ },
+ },
+ },
+ [AB8500_REGU_CTRL1] = {
+ .num_ranges = 3,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x00,
+ },
+ {
+ .first = 0x03,
+ .last = 0x10,
+ },
+ {
+ .first = 0x80,
+ .last = 0x84,
+ },
+ },
+ },
+ [AB8500_REGU_CTRL2] = {
+ .num_ranges = 5,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x15,
+ },
+ {
+ .first = 0x17,
+ .last = 0x19,
+ },
+ {
+ .first = 0x1B,
+ .last = 0x1D,
+ },
+ {
+ .first = 0x1F,
+ .last = 0x22,
+ },
+ {
+ .first = 0x40,
+ .last = 0x44,
+ },
+ /* 0x80-0x8B is SIM registers and should
+ * not be accessed from here */
+ },
+ },
+ [AB8500_USB] = {
+ .num_ranges = 2,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x80,
+ .last = 0x83,
+ },
+ {
+ .first = 0x87,
+ .last = 0x8A,
+ },
+ },
+ },
+ [AB8500_TVOUT] = {
+ .num_ranges = 9,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x12,
+ },
+ {
+ .first = 0x15,
+ .last = 0x17,
+ },
+ {
+ .first = 0x19,
+ .last = 0x21,
+ },
+ {
+ .first = 0x27,
+ .last = 0x2C,
+ },
+ {
+ .first = 0x41,
+ .last = 0x41,
+ },
+ {
+ .first = 0x45,
+ .last = 0x5B,
+ },
+ {
+ .first = 0x5D,
+ .last = 0x5D,
+ },
+ {
+ .first = 0x69,
+ .last = 0x69,
+ },
+ {
+ .first = 0x80,
+ .last = 0x81,
+ },
+ },
+ },
+ [AB8500_DBI] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [AB8500_ECI_AV_ACC] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x80,
+ .last = 0x82,
+ },
+ },
+ },
+ [0x9] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [AB8500_GPADC] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x08,
+ },
+ },
+ },
+ [AB8500_CHARGER] = {
+ .num_ranges = 8,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x03,
+ },
+ {
+ .first = 0x05,
+ .last = 0x05,
+ },
+ {
+ .first = 0x40,
+ .last = 0x40,
+ },
+ {
+ .first = 0x42,
+ .last = 0x42,
+ },
+ {
+ .first = 0x44,
+ .last = 0x44,
+ },
+ {
+ .first = 0x50,
+ .last = 0x55,
+ },
+ {
+ .first = 0x80,
+ .last = 0x82,
+ },
+ {
+ .first = 0xC0,
+ .last = 0xC2,
+ },
+ },
+ },
+ [AB8500_GAS_GAUGE] = {
+ .num_ranges = 3,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x00,
+ },
+ {
+ .first = 0x07,
+ .last = 0x0A,
+ },
+ {
+ .first = 0x10,
+ .last = 0x14,
+ },
+ },
+ },
+ [AB8500_AUDIO] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x6F,
+ },
+ },
+ },
+ [AB8500_INTERRUPT] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [AB8500_RTC] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x0F,
+ },
+ },
+ },
+ [AB8500_MISC] = {
+ .num_ranges = 8,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x05,
+ },
+ {
+ .first = 0x10,
+ .last = 0x15,
+ },
+ {
+ .first = 0x20,
+ .last = 0x25,
+ },
+ {
+ .first = 0x30,
+ .last = 0x35,
+ },
+ {
+ .first = 0x40,
+ .last = 0x45,
+ },
+ {
+ .first = 0x50,
+ .last = 0x50,
+ },
+ {
+ .first = 0x60,
+ .last = 0x67,
+ },
+ {
+ .first = 0x80,
+ .last = 0x80,
+ },
+ },
+ },
+ [0x11] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [0x12] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [0x13] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [0x14] = {
+ .num_ranges = 0,
+ .range = 0,
+ },
+ [AB8500_OTP_EMUL] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x01,
+ .last = 0x0F,
+ },
+ },
+ },
+};
+
+static int ab8500_registers_print(struct seq_file *s, void *p)
+{
+ struct device *dev = s->private;
+ unsigned int i;
+ u32 bank = debug_bank;
+
+ seq_printf(s, AB8500_NAME_STRING " register values:\n");
+
+ seq_printf(s, " bank %u:\n", bank);
+ for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
+ u32 reg;
+
+ for (reg = debug_ranges[bank].range[i].first;
+ reg <= debug_ranges[bank].range[i].last;
+ reg++) {
+ u8 value;
+ int err;
+
+ err = abx500_get_register_interruptible(dev,
+ (u8)bank, (u8)reg, &value);
+ if (err < 0) {
+ dev_err(dev, "ab->read fail %d\n", err);
+ return err;
+ }
+
+ err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank,
+ reg, value);
+ if (err < 0) {
+ dev_err(dev, "seq_printf overflow\n");
+ /* Error is not returned here since
+ * the output is wanted in any case */
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+static int ab8500_registers_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_registers_print, inode->i_private);
+}
+
+static const struct file_operations ab8500_registers_fops = {
+ .open = ab8500_registers_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int ab8500_bank_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "%d\n", debug_bank);
+}
+
+static int ab8500_bank_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_bank_print, inode->i_private);
+}
+
+static ssize_t ab8500_bank_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_bank;
+ int err;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_bank);
+ if (err)
+ return -EINVAL;
+
+ if (user_bank >= AB8500_NUM_BANKS) {
+ dev_err(dev, "debugfs error input > number of banks\n");
+ return -EINVAL;
+ }
+
+ debug_bank = user_bank;
+
+ return buf_size;
+}
+
+static int ab8500_address_print(struct seq_file *s, void *p)
+{
+ return seq_printf(s, "0x%02X\n", debug_address);
+}
+
+static int ab8500_address_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_address_print, inode->i_private);
+}
+
+static ssize_t ab8500_address_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_address;
+ int err;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_address);
+ if (err)
+ return -EINVAL;
+ if (user_address > 0xff) {
+ dev_err(dev, "debugfs error input > 0xff\n");
+ return -EINVAL;
+ }
+ debug_address = user_address;
+ return buf_size;
+}
+
+static int ab8500_val_print(struct seq_file *s, void *p)
+{
+ struct device *dev = s->private;
+ int ret;
+ u8 regvalue;
+
+ ret = abx500_get_register_interruptible(dev,
+ (u8)debug_bank, (u8)debug_address, &regvalue);
+ if (ret < 0) {
+ dev_err(dev, "abx500_get_reg fail %d, %d\n",
+ ret, __LINE__);
+ return -EINVAL;
+ }
+ seq_printf(s, "0x%02X\n", regvalue);
+
+ return 0;
+}
+
+static int ab8500_val_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ab8500_val_print, inode->i_private);
+}
+
+static ssize_t ab8500_val_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct device *dev = ((struct seq_file *)(file->private_data))->private;
+ char buf[32];
+ int buf_size;
+ unsigned long user_val;
+ int err;
+
+ /* Get userspace string and assure termination */
+ buf_size = min(count, (sizeof(buf)-1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ buf[buf_size] = 0;
+
+ err = strict_strtoul(buf, 0, &user_val);
+ if (err)
+ return -EINVAL;
+ if (user_val > 0xff) {
+ dev_err(dev, "debugfs error input > 0xff\n");
+ return -EINVAL;
+ }
+ err = abx500_set_register_interruptible(dev,
+ (u8)debug_bank, debug_address, (u8)user_val);
+ if (err < 0) {
+ printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__);
+ return -EINVAL;
+ }
+
+ return buf_size;
+}
+
+static const struct file_operations ab8500_bank_fops = {
+ .open = ab8500_bank_open,
+ .write = ab8500_bank_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static const struct file_operations ab8500_address_fops = {
+ .open = ab8500_address_open,
+ .write = ab8500_address_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static const struct file_operations ab8500_val_fops = {
+ .open = ab8500_val_open,
+ .write = ab8500_val_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static struct dentry *ab8500_dir;
+static struct dentry *ab8500_reg_file;
+static struct dentry *ab8500_bank_file;
+static struct dentry *ab8500_address_file;
+static struct dentry *ab8500_val_file;
+
+static int __devinit ab8500_debug_probe(struct platform_device *plf)
+{
+ debug_bank = AB8500_MISC;
+ debug_address = AB8500_REV_REG & 0x00FF;
+
+ ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
+ if (!ab8500_dir)
+ goto exit_no_debugfs;
+
+ ab8500_reg_file = debugfs_create_file("all-bank-registers",
+ S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops);
+ if (!ab8500_reg_file)
+ goto exit_destroy_dir;
+
+ ab8500_bank_file = debugfs_create_file("register-bank",
+ (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops);
+ if (!ab8500_bank_file)
+ goto exit_destroy_reg;
+
+ ab8500_address_file = debugfs_create_file("register-address",
+ (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev,
+ &ab8500_address_fops);
+ if (!ab8500_address_file)
+ goto exit_destroy_bank;
+
+ ab8500_val_file = debugfs_create_file("register-value",
+ (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops);
+ if (!ab8500_val_file)
+ goto exit_destroy_address;
+
+ return 0;
+
+exit_destroy_address:
+ debugfs_remove(ab8500_address_file);
+exit_destroy_bank:
+ debugfs_remove(ab8500_bank_file);
+exit_destroy_reg:
+ debugfs_remove(ab8500_reg_file);
+exit_destroy_dir:
+ debugfs_remove(ab8500_dir);
+exit_no_debugfs:
+ dev_err(&plf->dev, "failed to create debugfs entries.\n");
+ return -ENOMEM;
+}
+
+static int __devexit ab8500_debug_remove(struct platform_device *plf)
+{
+ debugfs_remove(ab8500_val_file);
+ debugfs_remove(ab8500_address_file);
+ debugfs_remove(ab8500_bank_file);
+ debugfs_remove(ab8500_reg_file);
+ debugfs_remove(ab8500_dir);
+
+ return 0;
+}
+
+static struct platform_driver ab8500_debug_driver = {
+ .driver = {
+ .name = "ab8500-debug",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab8500_debug_probe,
+ .remove = __devexit_p(ab8500_debug_remove)
+};
+
+static int __init ab8500_debug_init(void)
+{
+ return platform_driver_register(&ab8500_debug_driver);
+}
+
+static void __exit ab8500_debug_exit(void)
+{
+ platform_driver_unregister(&ab8500_debug_driver);
+}
+subsys_initcall(ab8500_debug_init);
+module_exit(ab8500_debug_exit);
+
+MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
+MODULE_DESCRIPTION("AB8500 DEBUG");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
new file mode 100644
index 000000000000..6820327adf4a
--- /dev/null
+++ b/drivers/mfd/ab8500-i2c.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
+ * License Terms: GNU General Public License v2
+ * This file was based on drivers/mfd/ab8500-spi.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ab8500.h>
+
+#include <mach/prcmu.h>
+
+static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
+{
+ int ret;
+
+ ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
+ if (ret < 0)
+ dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
+ return ret;
+}
+
+static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
+{
+ int ret;
+ u8 data;
+
+ ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
+ if (ret < 0) {
+ dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
+ return ret;
+ }
+ return (int)data;
+}
+
+static int __devinit ab8500_i2c_probe(struct platform_device *plf)
+{
+ struct ab8500 *ab8500;
+ struct resource *resource;
+ int ret;
+
+ ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL);
+ if (!ab8500)
+ return -ENOMEM;
+
+ ab8500->dev = &plf->dev;
+
+ resource = platform_get_resource(plf, IORESOURCE_IRQ, 0);
+ if (!resource) {
+ kfree(ab8500);
+ return -ENODEV;
+ }
+
+ ab8500->irq = resource->start;
+
+ ab8500->read = ab8500_i2c_read;
+ ab8500->write = ab8500_i2c_write;
+
+ platform_set_drvdata(plf, ab8500);
+
+ ret = ab8500_init(ab8500);
+ if (ret)
+ kfree(ab8500);
+
+ return ret;
+}
+
+static int __devexit ab8500_i2c_remove(struct platform_device *plf)
+{
+ struct ab8500 *ab8500 = platform_get_drvdata(plf);
+
+ ab8500_exit(ab8500);
+ kfree(ab8500);
+
+ return 0;
+}
+
+static struct platform_driver ab8500_i2c_driver = {
+ .driver = {
+ .name = "ab8500-i2c",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab8500_i2c_probe,
+ .remove = __devexit_p(ab8500_i2c_remove)
+};
+
+static int __init ab8500_i2c_init(void)
+{
+ return platform_driver_register(&ab8500_i2c_driver);
+}
+
+static void __exit ab8500_i2c_exit(void)
+{
+ platform_driver_unregister(&ab8500_i2c_driver);
+}
+subsys_initcall(ab8500_i2c_init);
+module_exit(ab8500_i2c_exit);
+
+MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
+MODULE_DESCRIPTION("AB8500 Core access via PRCMU I2C");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ab8500-spi.c b/drivers/mfd/ab8500-spi.c
index e1c8b62b086d..9181db531502 100644
--- a/drivers/mfd/ab8500-spi.c
+++ b/drivers/mfd/ab8500-spi.c
@@ -114,7 +114,7 @@ static int __devexit ab8500_spi_remove(struct spi_device *spi)
static struct spi_driver ab8500_spi_driver = {
.driver = {
- .name = "ab8500",
+ .name = "ab8500-spi",
.owner = THIS_MODULE,
},
.probe = ab8500_spi_probe,
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index c07aece900fb..2fadbaeb1cb1 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -470,13 +470,19 @@ static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
subdev = &pdata->subdevs[i];
pdev = platform_device_alloc(subdev->name, subdev->id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto failed;
+ }
pdev->dev.parent = chip->dev;
pdev->dev.platform_data = subdev->platform_data;
ret = platform_device_add(pdev);
- if (ret)
+ if (ret) {
+ platform_device_put(pdev);
goto failed;
+ }
}
return 0;
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index 134c69aa4790..d283d77937b9 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -384,12 +384,20 @@ static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
struct pcap_subdev *subdev)
{
struct platform_device *pdev;
+ int ret;
pdev = platform_device_alloc(subdev->name, subdev->id);
+ if (!pdev)
+ return -ENOMEM;
+
pdev->dev.parent = &pcap->spi->dev;
pdev->dev.platform_data = subdev->platform_data;
- return platform_device_add(pdev);
+ ret = platform_device_add(pdev);
+ if (ret)
+ platform_device_put(pdev);
+
+ return ret;
}
static int __devexit ezx_pcap_remove(struct spi_device *spi)
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index f04300e05fd6..7bc752272dc1 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -138,13 +138,6 @@ static int __init pasic3_probe(struct platform_device *pdev)
irq = r->start;
}
- r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (r) {
- ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
- (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
- irq = r->start;
- }
-
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENXIO;
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index 04028a9ee082..428377a5a6f5 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq)
irq_tsc = cache_tsc;
for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
irq_data = &max8925_irqs[i];
+ /* 1 -- disable, 0 -- enable */
switch (irq_data->mask_reg) {
case MAX8925_CHG_IRQ1_MASK:
- irq_chg[0] &= irq_data->enable;
+ irq_chg[0] &= ~irq_data->enable;
break;
case MAX8925_CHG_IRQ2_MASK:
- irq_chg[1] &= irq_data->enable;
+ irq_chg[1] &= ~irq_data->enable;
break;
case MAX8925_ON_OFF_IRQ1_MASK:
- irq_on[0] &= irq_data->enable;
+ irq_on[0] &= ~irq_data->enable;
break;
case MAX8925_ON_OFF_IRQ2_MASK:
- irq_on[1] &= irq_data->enable;
+ irq_on[1] &= ~irq_data->enable;
break;
case MAX8925_RTC_IRQ_MASK:
- irq_rtc &= irq_data->enable;
+ irq_rtc &= ~irq_data->enable;
break;
case MAX8925_TSC_IRQ_MASK:
- irq_tsc &= irq_data->enable;
+ irq_tsc &= ~irq_data->enable;
break;
default:
dev_err(chip->dev, "wrong IRQ\n");
diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c
new file mode 100644
index 000000000000..346fd296cf7d
--- /dev/null
+++ b/drivers/mfd/max8998-irq.c
@@ -0,0 +1,255 @@
+/*
+ * Interrupt controller support for MAX8998
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.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/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/max8998-private.h>
+
+struct max8998_irq_data {
+ int reg;
+ int mask;
+};
+
+static struct max8998_irq_data max8998_irqs[] = {
+ [MAX8998_IRQ_DCINF] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_DCINF_MASK,
+ },
+ [MAX8998_IRQ_DCINR] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_DCINR_MASK,
+ },
+ [MAX8998_IRQ_JIGF] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_JIGF_MASK,
+ },
+ [MAX8998_IRQ_JIGR] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_JIGR_MASK,
+ },
+ [MAX8998_IRQ_PWRONF] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_PWRONF_MASK,
+ },
+ [MAX8998_IRQ_PWRONR] = {
+ .reg = 1,
+ .mask = MAX8998_IRQ_PWRONR_MASK,
+ },
+ [MAX8998_IRQ_WTSREVNT] = {
+ .reg = 2,
+ .mask = MAX8998_IRQ_WTSREVNT_MASK,
+ },
+ [MAX8998_IRQ_SMPLEVNT] = {
+ .reg = 2,
+ .mask = MAX8998_IRQ_SMPLEVNT_MASK,
+ },
+ [MAX8998_IRQ_ALARM1] = {
+ .reg = 2,
+ .mask = MAX8998_IRQ_ALARM1_MASK,
+ },
+ [MAX8998_IRQ_ALARM0] = {
+ .reg = 2,
+ .mask = MAX8998_IRQ_ALARM0_MASK,
+ },
+ [MAX8998_IRQ_ONKEY1S] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_ONKEY1S_MASK,
+ },
+ [MAX8998_IRQ_TOPOFFR] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_TOPOFFR_MASK,
+ },
+ [MAX8998_IRQ_DCINOVPR] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_DCINOVPR_MASK,
+ },
+ [MAX8998_IRQ_CHGRSTF] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_CHGRSTF_MASK,
+ },
+ [MAX8998_IRQ_DONER] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_DONER_MASK,
+ },
+ [MAX8998_IRQ_CHGFAULT] = {
+ .reg = 3,
+ .mask = MAX8998_IRQ_CHGFAULT_MASK,
+ },
+ [MAX8998_IRQ_LOBAT1] = {
+ .reg = 4,
+ .mask = MAX8998_IRQ_LOBAT1_MASK,
+ },
+ [MAX8998_IRQ_LOBAT2] = {
+ .reg = 4,
+ .mask = MAX8998_IRQ_LOBAT2_MASK,
+ },
+};
+
+static inline struct max8998_irq_data *
+irq_to_max8998_irq(struct max8998_dev *max8998, int irq)
+{
+ return &max8998_irqs[irq - max8998->irq_base];
+}
+
+static void max8998_irq_lock(unsigned int irq)
+{
+ struct max8998_dev *max8998 = get_irq_chip_data(irq);
+
+ mutex_lock(&max8998->irqlock);
+}
+
+static void max8998_irq_sync_unlock(unsigned int irq)
+{
+ struct max8998_dev *max8998 = get_irq_chip_data(irq);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) {
+ /*
+ * If there's been a change in the mask write it back
+ * to the hardware.
+ */
+ if (max8998->irq_masks_cur[i] != max8998->irq_masks_cache[i]) {
+ max8998->irq_masks_cache[i] = max8998->irq_masks_cur[i];
+ max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i,
+ max8998->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&max8998->irqlock);
+}
+
+static void max8998_irq_unmask(unsigned int irq)
+{
+ struct max8998_dev *max8998 = get_irq_chip_data(irq);
+ struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq);
+
+ max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void max8998_irq_mask(unsigned int irq)
+{
+ struct max8998_dev *max8998 = get_irq_chip_data(irq);
+ struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq);
+
+ max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip max8998_irq_chip = {
+ .name = "max8998",
+ .bus_lock = max8998_irq_lock,
+ .bus_sync_unlock = max8998_irq_sync_unlock,
+ .mask = max8998_irq_mask,
+ .unmask = max8998_irq_unmask,
+};
+
+static irqreturn_t max8998_irq_thread(int irq, void *data)
+{
+ struct max8998_dev *max8998 = data;
+ u8 irq_reg[MAX8998_NUM_IRQ_REGS];
+ int ret;
+ int i;
+
+ ret = max8998_bulk_read(max8998->i2c, MAX8998_REG_IRQ1,
+ MAX8998_NUM_IRQ_REGS, irq_reg);
+ if (ret < 0) {
+ dev_err(max8998->dev, "Failed to read interrupt register: %d\n",
+ ret);
+ return IRQ_NONE;
+ }
+
+ /* Apply masking */
+ for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++)
+ irq_reg[i] &= ~max8998->irq_masks_cur[i];
+
+ /* Report */
+ for (i = 0; i < MAX8998_IRQ_NR; i++) {
+ if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask)
+ handle_nested_irq(max8998->irq_base + i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+int max8998_irq_init(struct max8998_dev *max8998)
+{
+ int i;
+ int cur_irq;
+ int ret;
+
+ if (!max8998->irq) {
+ dev_warn(max8998->dev,
+ "No interrupt specified, no interrupts\n");
+ max8998->irq_base = 0;
+ return 0;
+ }
+
+ if (!max8998->irq_base) {
+ dev_err(max8998->dev,
+ "No interrupt base specified, no interrupts\n");
+ return 0;
+ }
+
+ mutex_init(&max8998->irqlock);
+
+ /* Mask the individual interrupt sources */
+ for (i = 0; i < MAX8998_NUM_IRQ_REGS; i++) {
+ max8998->irq_masks_cur[i] = 0xff;
+ max8998->irq_masks_cache[i] = 0xff;
+ max8998_write_reg(max8998->i2c, MAX8998_REG_IRQM1 + i, 0xff);
+ }
+
+ max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff);
+ max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff);
+
+ /* register with genirq */
+ for (i = 0; i < MAX8998_IRQ_NR; i++) {
+ cur_irq = i + max8998->irq_base;
+ set_irq_chip_data(cur_irq, max8998);
+ set_irq_chip_and_handler(cur_irq, &max8998_irq_chip,
+ handle_edge_irq);
+ set_irq_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ set_irq_noprobe(cur_irq);
+#endif
+ }
+
+ ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "max8998-irq", max8998);
+ if (ret) {
+ dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
+ max8998->irq, ret);
+ return ret;
+ }
+
+ if (!max8998->ono)
+ return 0;
+
+ ret = request_threaded_irq(max8998->ono, NULL, max8998_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "max8998-ono", max8998);
+ if (ret)
+ dev_err(max8998->dev, "Failed to request IRQ %d: %d\n",
+ max8998->ono, ret);
+
+ return 0;
+}
+
+void max8998_irq_exit(struct max8998_dev *max8998)
+{
+ if (max8998->irq)
+ free_irq(max8998->irq, max8998);
+}
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index 73e6f5c4efc9..310fd8054f35 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -1,5 +1,5 @@
/*
- * max8698.c - mfd core driver for the Maxim 8998
+ * max8998.c - mfd core driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
@@ -30,19 +30,23 @@
#include <linux/mfd/max8998.h>
#include <linux/mfd/max8998-private.h>
+#define RTC_I2C_ADDR (0x0c >> 1)
+
static struct mfd_cell max8998_devs[] = {
{
.name = "max8998-pmic",
- }
+ }, {
+ .name = "max8998-rtc",
+ },
};
-static int max8998_i2c_device_read(struct max8998_dev *max8998, u8 reg, u8 *dest)
+int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
{
- struct i2c_client *client = max8998->i2c_client;
+ struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
int ret;
mutex_lock(&max8998->iolock);
- ret = i2c_smbus_read_byte_data(client, reg);
+ ret = i2c_smbus_read_byte_data(i2c, reg);
mutex_unlock(&max8998->iolock);
if (ret < 0)
return ret;
@@ -51,40 +55,73 @@ static int max8998_i2c_device_read(struct max8998_dev *max8998, u8 reg, u8 *dest
*dest = ret;
return 0;
}
+EXPORT_SYMBOL(max8998_read_reg);
-static int max8998_i2c_device_write(struct max8998_dev *max8998, u8 reg, u8 value)
+int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
{
- struct i2c_client *client = max8998->i2c_client;
+ struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&max8998->iolock);
+ ret = i2c_smbus_read_i2c_block_data(i2c, reg, count, buf);
+ mutex_unlock(&max8998->iolock);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL(max8998_bulk_read);
+
+int max8998_write_reg(struct i2c_client *i2c, u8 reg, u8 value)
+{
+ struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
int ret;
mutex_lock(&max8998->iolock);
- ret = i2c_smbus_write_byte_data(client, reg, value);
+ ret = i2c_smbus_write_byte_data(i2c, reg, value);
mutex_unlock(&max8998->iolock);
return ret;
}
+EXPORT_SYMBOL(max8998_write_reg);
-static int max8998_i2c_device_update(struct max8998_dev *max8998, u8 reg,
- u8 val, u8 mask)
+int max8998_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
{
- struct i2c_client *client = max8998->i2c_client;
+ struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
+ int ret;
+
+ mutex_lock(&max8998->iolock);
+ ret = i2c_smbus_write_i2c_block_data(i2c, reg, count, buf);
+ mutex_unlock(&max8998->iolock);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL(max8998_bulk_write);
+
+int max8998_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
+{
+ struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
int ret;
mutex_lock(&max8998->iolock);
- ret = i2c_smbus_read_byte_data(client, reg);
+ ret = i2c_smbus_read_byte_data(i2c, reg);
if (ret >= 0) {
u8 old_val = ret & 0xff;
u8 new_val = (val & mask) | (old_val & (~mask));
- ret = i2c_smbus_write_byte_data(client, reg, new_val);
+ ret = i2c_smbus_write_byte_data(i2c, reg, new_val);
if (ret >= 0)
ret = 0;
}
mutex_unlock(&max8998->iolock);
return ret;
}
+EXPORT_SYMBOL(max8998_update_reg);
static int max8998_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
+ struct max8998_platform_data *pdata = i2c->dev.platform_data;
struct max8998_dev *max8998;
int ret = 0;
@@ -94,12 +131,19 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, max8998);
max8998->dev = &i2c->dev;
- max8998->i2c_client = i2c;
- max8998->dev_read = max8998_i2c_device_read;
- max8998->dev_write = max8998_i2c_device_write;
- max8998->dev_update = max8998_i2c_device_update;
+ max8998->i2c = i2c;
+ max8998->irq = i2c->irq;
+ if (pdata) {
+ max8998->ono = pdata->ono;
+ max8998->irq_base = pdata->irq_base;
+ }
mutex_init(&max8998->iolock);
+ max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+ i2c_set_clientdata(max8998->rtc, max8998);
+
+ max8998_irq_init(max8998);
+
ret = mfd_add_devices(max8998->dev, -1,
max8998_devs, ARRAY_SIZE(max8998_devs),
NULL, 0);
@@ -125,8 +169,9 @@ static int max8998_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id max8998_i2c_id[] = {
- { "max8998", 0 },
- { }
+ { "max8998", 0 },
+ { "lp3974", 0 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 23e585527285..6d4233f0d0d3 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -25,13 +25,6 @@
#include <linux/mfd/pcf50633/core.h>
-int pcf50633_irq_init(struct pcf50633 *pcf, int irq);
-void pcf50633_irq_free(struct pcf50633 *pcf);
-#ifdef CONFIG_PM
-int pcf50633_irq_suspend(struct pcf50633 *pcf);
-int pcf50633_irq_resume(struct pcf50633 *pcf);
-#endif
-
static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
{
int ret;
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index cd164595f08a..9d43316312ab 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -65,6 +65,17 @@ static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
p->set_pwr(pdev, state);
}
+static int sh_mobile_sdhi_get_cd(struct platform_device *tmio)
+{
+ struct platform_device *pdev = to_platform_device(tmio->dev.parent);
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+
+ if (p && p->get_cd)
+ return p->get_cd(pdev);
+ else
+ return -ENOSYS;
+}
+
static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
{
struct sh_mobile_sdhi *priv;
@@ -106,12 +117,20 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
mmc_data->hclk = clk_get_rate(priv->clk);
mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+ mmc_data->get_cd = sh_mobile_sdhi_get_cd;
mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
if (p) {
mmc_data->flags = p->tmio_flags;
mmc_data->ocr_mask = p->tmio_ocr_mask;
+ mmc_data->capabilities |= p->tmio_caps;
}
+ /*
+ * All SDHI blocks support 2-byte and larger block sizes in 4-bit
+ * bus width mode.
+ */
+ mmc_data->flags |= TMIO_MMC_BLKSZ_2BYTES;
+
if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
priv->param_tx.slave_id = p->dma_slave_tx;
priv->param_rx.slave_id = p->dma_slave_rx;
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 4cde31e6a252..2f9336c3710c 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -273,13 +273,19 @@ static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
subdev = &pdata->subdevs[i];
pdev = platform_device_alloc(subdev->name, subdev->id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto failed;
+ }
pdev->dev.parent = tps6586x->dev;
pdev->dev.platform_data = subdev->platform_data;
ret = platform_device_add(pdev);
- if (ret)
+ if (ret) {
+ platform_device_put(pdev);
goto failed;
+ }
}
return 0;
@@ -338,6 +344,19 @@ err_add_devs:
static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
{
+ struct tps6586x *tps6586x = i2c_get_clientdata(client);
+ struct tps6586x_platform_data *pdata = client->dev.platform_data;
+ int ret;
+
+ if (pdata->gpio_base) {
+ ret = gpiochip_remove(&tps6586x->gpio);
+ if (ret)
+ dev_err(&client->dev, "Can't remove gpio chip: %d\n",
+ ret);
+ }
+
+ tps6586x_remove_subdevs(tps6586x);
+ kfree(tps6586x);
return 0;
}
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 720e099e506d..b0f2c0004efe 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -202,12 +202,6 @@
/* Few power values */
#define R_CFG_BOOT 0x05
-#define R_PROTECT_KEY 0x0E
-
-/* access control values for R_PROTECT_KEY */
-#define KEY_UNLOCK1 0xce
-#define KEY_UNLOCK2 0xec
-#define KEY_LOCK 0x00
/* some fields in R_CFG_BOOT */
#define HFCLK_FREQ_19p2_MHZ (1 << 0)
@@ -698,17 +692,17 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
if (twl_has_codec() && pdata->codec && twl_class_is_4030()) {
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
- child = add_child(sub_chip_id, "twl4030_codec",
+ child = add_child(sub_chip_id, "twl4030-audio",
pdata->codec, sizeof(*pdata->codec),
false, 0, 0);
if (IS_ERR(child))
return PTR_ERR(child);
}
- /* Phoenix*/
+ /* Phoenix codec driver is probed directly atm */
if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
- child = add_child(sub_chip_id, "twl6040_codec",
+ child = add_child(sub_chip_id, "twl6040-codec",
pdata->codec, sizeof(*pdata->codec),
false, 0, 0);
if (IS_ERR(child))
@@ -846,8 +840,8 @@ static inline int __init protect_pm_master(void)
{
int e = 0;
- e = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_LOCK,
- R_PROTECT_KEY);
+ e = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
return e;
}
@@ -855,10 +849,13 @@ static inline int __init unprotect_pm_master(void)
{
int e = 0;
- e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK1,
- R_PROTECT_KEY);
- e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK2,
- R_PROTECT_KEY);
+ e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG1,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+ e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG2,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+
return e;
}
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index add6f67d8032..9a4b196d6deb 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -207,14 +207,14 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
if (pdata->audio) {
cell = &codec->cells[childs];
- cell->name = "twl4030_codec_audio";
+ cell->name = "twl4030-codec";
cell->platform_data = pdata->audio;
cell->data_size = sizeof(*pdata->audio);
childs++;
}
if (pdata->vibra) {
cell = &codec->cells[childs];
- cell->name = "twl4030_codec_vibra";
+ cell->name = "twl4030-vibra";
cell->platform_data = pdata->vibra;
cell->data_size = sizeof(*pdata->vibra);
childs++;
@@ -249,14 +249,14 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
return 0;
}
-MODULE_ALIAS("platform:twl4030_codec");
+MODULE_ALIAS("platform:twl4030-audio");
static struct platform_driver twl4030_codec_driver = {
.probe = twl4030_codec_probe,
.remove = __devexit_p(twl4030_codec_remove),
.driver = {
.owner = THIS_MODULE,
- .name = "twl4030_codec",
+ .name = "twl4030-audio",
},
};
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 7efa8789a3a2..16422de0823a 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -63,10 +63,6 @@ static u8 twl4030_start_script_address = 0x2b;
#define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59)
#define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a)
-#define R_PROTECT_KEY 0x0E
-#define R_KEY_1 0xC0
-#define R_KEY_2 0x0C
-
/* resource configuration registers
<RESOURCE>_DEV_GRP at address 'n+0'
<RESOURCE>_TYPE at address 'n+1'
@@ -465,15 +461,17 @@ int twl4030_remove_script(u8 flags)
{
int err = 0;
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
- R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG1,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err) {
pr_err("twl4030: unable to unlock PROTECT_KEY\n");
return err;
}
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
- R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG2,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err) {
pr_err("twl4030: unable to unlock PROTECT_KEY\n");
return err;
@@ -504,7 +502,8 @@ int twl4030_remove_script(u8 flags)
return err;
}
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err)
pr_err("TWL4030 Unable to relock registers\n");
@@ -518,13 +517,15 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
struct twl4030_resconfig *resconfig;
u8 address = twl4030_start_script_address;
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
- R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG1,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err)
goto unlock;
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
- R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG2,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err)
goto unlock;
@@ -546,7 +547,8 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
}
}
- err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
if (err)
pr_err("TWL4030 Unable to relock registers\n");
return;
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 7dabe4dbd373..294183b6260b 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
irq = irq - wm831x->irq_base;
- if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11)
- return -EINVAL;
+ if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {
+ /* Ignore internal-only IRQs */
+ if (irq >= 0 && irq < WM831X_NUM_IRQS)
+ return 0;
+ else
+ return -EINVAL;
+ }
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b591b658243..2c38d4e69767 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -385,11 +385,23 @@ config BMP085
depends on I2C && SYSFS
help
If you say yes here you get support for the Bosch Sensortec
- BMP086 digital pressure sensor.
+ BMP085 digital pressure sensor.
To compile this driver as a module, choose M here: the
module will be called bmp085.
+config PCH_PHUB
+ tristate "PCH Packet Hub of Intel Topcliff"
+ depends on PCI
+ help
+ This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
+ Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded
+ processor. The Topcliff has MAC address and Option ROM data in SROM.
+ This driver can access MAC address and Option ROM data in SROM.
+
+ To compile this driver as a module, choose M here: the module will
+ be called pch_phub.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 255a80dc9d73..21b47612c48e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -35,3 +35,4 @@ obj-y += eeprom/
obj-y += cb710/
obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
+obj-$(CONFIG_PCH_PHUB) += pch_phub.o
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index 714c6b487313..d5f3a3fd2319 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -190,7 +190,6 @@ static int __devexit bh1780_remove(struct i2c_client *client)
ddata = i2c_get_clientdata(client);
sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group);
- i2c_set_clientdata(client, NULL);
kfree(ddata);
return 0;
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 557a8c2a7336..c74e71ecf654 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -640,6 +640,7 @@ static const struct file_operations ilo_fops = {
.poll = ilo_poll,
.open = ilo_open,
.release = ilo_close,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static irqreturn_t ilo_isr(int irq, void *data)
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 8844a3f45381..af2497ae5fe3 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -584,6 +584,7 @@ static const struct file_operations command_fops = {
.release = command_file_close,
.read = command_file_read,
.write = command_file_write,
+ .llseek = generic_file_llseek,
};
static const struct file_operations event_fops = {
@@ -591,6 +592,7 @@ static const struct file_operations event_fops = {
.release = event_file_close,
.read = event_file_read,
.write = event_file_write,
+ .llseek = generic_file_llseek,
};
static const struct file_operations r_heartbeat_fops = {
@@ -598,6 +600,7 @@ static const struct file_operations r_heartbeat_fops = {
.release = r_heartbeat_file_close,
.read = r_heartbeat_file_read,
.write = r_heartbeat_file_write,
+ .llseek = generic_file_llseek,
};
static const struct file_operations remote_settings_fops = {
@@ -605,6 +608,7 @@ static const struct file_operations remote_settings_fops = {
.release = remote_settings_file_close,
.read = remote_settings_file_read,
.write = remote_settings_file_write,
+ .llseek = generic_file_llseek,
};
diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
index e9eda471f6e0..62fbaec48207 100644
--- a/drivers/misc/iwmc3200top/debugfs.c
+++ b/drivers/misc/iwmc3200top/debugfs.c
@@ -71,6 +71,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file, \
static const struct file_operations iwmct_dbgfs_##name##_ops = { \
.read = iwmct_dbgfs_##name##_read, \
.open = iwmct_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_WRITE_FILE_OPS(name) \
@@ -78,6 +79,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file, \
static const struct file_operations iwmct_dbgfs_##name##_ops = { \
.write = iwmct_dbgfs_##name##_write, \
.open = iwmct_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
@@ -87,6 +89,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file, \
.write = iwmct_dbgfs_##name##_write, \
.read = iwmct_dbgfs_##name##_read, \
.open = iwmct_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index ef34de7a8026..343b5d8ea697 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -575,30 +575,39 @@ struct crash_entry {
static const struct crash_entry crash_entries[] = {
{"DIRECT", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = direct_entry} },
{"INT_HARDWARE_ENTRY", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = int_hardware_entry} },
{"INT_HW_IRQ_EN", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = int_hw_irq_en} },
{"INT_TASKLET_ENTRY", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = int_tasklet_entry} },
{"FS_DEVRW", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = fs_devrw_entry} },
{"MEM_SWAPOUT", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = mem_swapout_entry} },
{"TIMERADD", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = timeradd_entry} },
{"SCSI_DISPATCH_CMD", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = scsi_dispatch_cmd_entry} },
{"IDE_CORE_CP", {.read = lkdtm_debugfs_read,
+ .llseek = generic_file_llseek,
.open = lkdtm_debugfs_open,
.write = ide_core_cp_entry} },
};
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
new file mode 100644
index 000000000000..744b804aca15
--- /dev/null
+++ b/drivers/misc/pch_phub.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., 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; 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/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/if_ether.h>
+#include <linux/ctype.h>
+
+#define PHUB_STATUS 0x00 /* Status Register offset */
+#define PHUB_CONTROL 0x04 /* Control Register offset */
+#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
+#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
+#define PCH_PHUB_ROM_START_ADDR 0x14 /* ROM data area start address offset */
+
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
+#define PCI_DEVICE_ID_PCH1_PHUB 0x8801
+#define PCH_MINOR_NOS 1
+#define CLKCFG_CAN_50MHZ 0x12000000
+#define CLKCFG_CANCLK_MASK 0xFF000000
+
+/* SROM ACCESS Macro */
+#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
+
+/* Registers address offset */
+#define PCH_PHUB_ID_REG 0x0000
+#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004
+#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008
+#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C
+#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010
+#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014
+#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C
+#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040
+#define CLKCFG_REG_OFFSET 0x500
+
+#define PCH_PHUB_OROM_SIZE 15360
+
+/**
+ * struct pch_phub_reg - PHUB register structure
+ * @phub_id_reg: PHUB_ID register val
+ * @q_pri_val_reg: QUEUE_PRI_VAL register val
+ * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
+ * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
+ * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
+ * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
+ * @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val
+ * @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val
+ * @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val
+ * @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val
+ * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val
+ * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
+ * @clkcfg_reg: CLK CFG register val
+ * @pch_phub_base_address: Register base address
+ * @pch_phub_extrom_base_address: external rom base address
+ */
+struct pch_phub_reg {
+ u32 phub_id_reg;
+ u32 q_pri_val_reg;
+ u32 rc_q_maxsize_reg;
+ u32 bri_q_maxsize_reg;
+ u32 comp_resp_timeout_reg;
+ u32 bus_slave_control_reg;
+ u32 deadlock_avoid_type_reg;
+ u32 intpin_reg_wpermit_reg0;
+ u32 intpin_reg_wpermit_reg1;
+ u32 intpin_reg_wpermit_reg2;
+ u32 intpin_reg_wpermit_reg3;
+ u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
+ u32 clkcfg_reg;
+ void __iomem *pch_phub_base_address;
+ void __iomem *pch_phub_extrom_base_address;
+};
+
+/* SROM SPEC for MAC address assignment offset */
+static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
+
+static DEFINE_MUTEX(pch_phub_mutex);
+
+/**
+ * pch_phub_read_modify_write_reg() - Reading modifying and writing register
+ * @reg_addr_offset: Register offset address value.
+ * @data: Writing value.
+ * @mask: Mask value.
+ */
+static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
+ unsigned int reg_addr_offset,
+ unsigned int data, unsigned int mask)
+{
+ void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
+ iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
+}
+
+/* pch_phub_save_reg_conf - saves register configuration */
+static void pch_phub_save_reg_conf(struct pci_dev *pdev)
+{
+ unsigned int i;
+ struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+
+ void __iomem *p = chip->pch_phub_base_address;
+
+ chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
+ chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+ chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+ chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+ chip->comp_resp_timeout_reg =
+ ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+ chip->bus_slave_control_reg =
+ ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+ chip->deadlock_avoid_type_reg =
+ ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+ chip->intpin_reg_wpermit_reg0 =
+ ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+ chip->intpin_reg_wpermit_reg1 =
+ ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+ chip->intpin_reg_wpermit_reg2 =
+ ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+ chip->intpin_reg_wpermit_reg3 =
+ ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+ dev_dbg(&pdev->dev, "%s : "
+ "chip->phub_id_reg=%x, "
+ "chip->q_pri_val_reg=%x, "
+ "chip->rc_q_maxsize_reg=%x, "
+ "chip->bri_q_maxsize_reg=%x, "
+ "chip->comp_resp_timeout_reg=%x, "
+ "chip->bus_slave_control_reg=%x, "
+ "chip->deadlock_avoid_type_reg=%x, "
+ "chip->intpin_reg_wpermit_reg0=%x, "
+ "chip->intpin_reg_wpermit_reg1=%x, "
+ "chip->intpin_reg_wpermit_reg2=%x, "
+ "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
+ chip->phub_id_reg,
+ chip->q_pri_val_reg,
+ chip->rc_q_maxsize_reg,
+ chip->bri_q_maxsize_reg,
+ chip->comp_resp_timeout_reg,
+ chip->bus_slave_control_reg,
+ chip->deadlock_avoid_type_reg,
+ chip->intpin_reg_wpermit_reg0,
+ chip->intpin_reg_wpermit_reg1,
+ chip->intpin_reg_wpermit_reg2,
+ chip->intpin_reg_wpermit_reg3);
+ for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+ chip->int_reduce_control_reg[i] =
+ ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+ dev_dbg(&pdev->dev, "%s : "
+ "chip->int_reduce_control_reg[%d]=%x\n",
+ __func__, i, chip->int_reduce_control_reg[i]);
+ }
+ chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
+}
+
+/* pch_phub_restore_reg_conf - restore register configuration */
+static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
+{
+ unsigned int i;
+ struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+ void __iomem *p;
+ p = chip->pch_phub_base_address;
+
+ iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
+ iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+ iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+ iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+ iowrite32(chip->comp_resp_timeout_reg,
+ p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+ iowrite32(chip->bus_slave_control_reg,
+ p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+ iowrite32(chip->deadlock_avoid_type_reg,
+ p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+ iowrite32(chip->intpin_reg_wpermit_reg0,
+ p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+ iowrite32(chip->intpin_reg_wpermit_reg1,
+ p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+ iowrite32(chip->intpin_reg_wpermit_reg2,
+ p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+ iowrite32(chip->intpin_reg_wpermit_reg3,
+ p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+ dev_dbg(&pdev->dev, "%s : "
+ "chip->phub_id_reg=%x, "
+ "chip->q_pri_val_reg=%x, "
+ "chip->rc_q_maxsize_reg=%x, "
+ "chip->bri_q_maxsize_reg=%x, "
+ "chip->comp_resp_timeout_reg=%x, "
+ "chip->bus_slave_control_reg=%x, "
+ "chip->deadlock_avoid_type_reg=%x, "
+ "chip->intpin_reg_wpermit_reg0=%x, "
+ "chip->intpin_reg_wpermit_reg1=%x, "
+ "chip->intpin_reg_wpermit_reg2=%x, "
+ "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
+ chip->phub_id_reg,
+ chip->q_pri_val_reg,
+ chip->rc_q_maxsize_reg,
+ chip->bri_q_maxsize_reg,
+ chip->comp_resp_timeout_reg,
+ chip->bus_slave_control_reg,
+ chip->deadlock_avoid_type_reg,
+ chip->intpin_reg_wpermit_reg0,
+ chip->intpin_reg_wpermit_reg1,
+ chip->intpin_reg_wpermit_reg2,
+ chip->intpin_reg_wpermit_reg3);
+ for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+ iowrite32(chip->int_reduce_control_reg[i],
+ p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+ dev_dbg(&pdev->dev, "%s : "
+ "chip->int_reduce_control_reg[%d]=%x\n",
+ __func__, i, chip->int_reduce_control_reg[i]);
+ }
+
+ iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
+}
+
+/**
+ * pch_phub_read_serial_rom() - Reading Serial ROM
+ * @offset_address: Serial ROM offset address to read.
+ * @data: Read buffer for specified Serial ROM value.
+ */
+static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
+ unsigned int offset_address, u8 *data)
+{
+ void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
+ offset_address;
+
+ *data = ioread8(mem_addr);
+}
+
+/**
+ * pch_phub_write_serial_rom() - Writing Serial ROM
+ * @offset_address: Serial ROM offset address.
+ * @data: Serial ROM value to write.
+ */
+static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
+ unsigned int offset_address, u8 data)
+{
+ void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
+ (offset_address & PCH_WORD_ADDR_MASK);
+ int i;
+ unsigned int word_data;
+ unsigned int pos;
+ unsigned int mask;
+ pos = (offset_address % 4) * 8;
+ mask = ~(0xFF << pos);
+
+ iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
+ chip->pch_phub_extrom_base_address + PHUB_CONTROL);
+
+ word_data = ioread32(mem_addr);
+ iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
+
+ i = 0;
+ while (ioread8(chip->pch_phub_extrom_base_address +
+ PHUB_STATUS) != 0x00) {
+ msleep(1);
+ if (i == PHUB_TIMEOUT)
+ return -ETIMEDOUT;
+ i++;
+ }
+
+ iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
+ chip->pch_phub_extrom_base_address + PHUB_CONTROL);
+
+ return 0;
+}
+
+/**
+ * pch_phub_read_serial_rom_val() - Read Serial ROM value
+ * @offset_address: Serial ROM address offset value.
+ * @data: Serial ROM value to read.
+ */
+static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
+ unsigned int offset_address, u8 *data)
+{
+ unsigned int mem_addr;
+
+ mem_addr = PCH_PHUB_ROM_START_ADDR +
+ pch_phub_mac_offset[offset_address];
+
+ pch_phub_read_serial_rom(chip, mem_addr, data);
+}
+
+/**
+ * pch_phub_write_serial_rom_val() - writing Serial ROM value
+ * @offset_address: Serial ROM address offset value.
+ * @data: Serial ROM value.
+ */
+static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
+ unsigned int offset_address, u8 data)
+{
+ int retval;
+ unsigned int mem_addr;
+
+ mem_addr = PCH_PHUB_ROM_START_ADDR +
+ pch_phub_mac_offset[offset_address];
+
+ retval = pch_phub_write_serial_rom(chip, mem_addr, data);
+
+ return retval;
+}
+
+/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
+ * for Gigabit Ethernet MAC address
+ */
+static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
+{
+ int retval;
+
+ retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
+ retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
+ retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
+ retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
+
+ retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
+ retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
+ retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
+ retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
+
+ retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
+ retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
+ retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
+ retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
+
+ retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
+ retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
+ retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
+ retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
+
+ retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
+ retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
+ retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
+ retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
+
+ retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
+ retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
+ retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
+ retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
+
+ return retval;
+}
+
+/**
+ * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
+ * @offset_address: Gigabit Ethernet MAC address offset value.
+ * @data: Buffer of the Gigabit Ethernet MAC address value.
+ */
+static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
+{
+ int i;
+ for (i = 0; i < ETH_ALEN; i++)
+ pch_phub_read_serial_rom_val(chip, i, &data[i]);
+}
+
+/**
+ * pch_phub_write_gbe_mac_addr() - Write MAC address
+ * @offset_address: Gigabit Ethernet MAC address offset value.
+ * @data: Gigabit Ethernet MAC address value.
+ */
+static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
+{
+ int retval;
+ int i;
+
+ retval = pch_phub_gbe_serial_rom_conf(chip);
+ if (retval)
+ return retval;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
+ if (retval)
+ return retval;
+ }
+
+ return retval;
+}
+
+static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+{
+ unsigned int rom_signature;
+ unsigned char rom_length;
+ unsigned int tmp;
+ unsigned int addr_offset;
+ unsigned int orom_size;
+ int ret;
+ int err;
+
+ struct pch_phub_reg *chip =
+ dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+ ret = mutex_lock_interruptible(&pch_phub_mutex);
+ if (ret) {
+ err = -ERESTARTSYS;
+ goto return_err_nomutex;
+ }
+
+ /* Get Rom signature */
+ pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
+ rom_signature &= 0xff;
+ pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
+ rom_signature |= (tmp & 0xff) << 8;
+ if (rom_signature == 0xAA55) {
+ pch_phub_read_serial_rom(chip, 0x82, &rom_length);
+ orom_size = rom_length * 512;
+ if (orom_size < off) {
+ addr_offset = 0;
+ goto return_ok;
+ }
+ if (orom_size < count) {
+ addr_offset = 0;
+ goto return_ok;
+ }
+
+ for (addr_offset = 0; addr_offset < count; addr_offset++) {
+ pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
+ &buf[addr_offset]);
+ }
+ } else {
+ err = -ENODATA;
+ goto return_err;
+ }
+return_ok:
+ mutex_unlock(&pch_phub_mutex);
+ return addr_offset;
+
+return_err:
+ mutex_unlock(&pch_phub_mutex);
+return_err_nomutex:
+ return err;
+}
+
+static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ int err;
+ unsigned int addr_offset;
+ int ret;
+ struct pch_phub_reg *chip =
+ dev_get_drvdata(container_of(kobj, struct device, kobj));
+
+ ret = mutex_lock_interruptible(&pch_phub_mutex);
+ if (ret)
+ return -ERESTARTSYS;
+
+ if (off > PCH_PHUB_OROM_SIZE) {
+ addr_offset = 0;
+ goto return_ok;
+ }
+ if (count > PCH_PHUB_OROM_SIZE) {
+ addr_offset = 0;
+ goto return_ok;
+ }
+
+ for (addr_offset = 0; addr_offset < count; addr_offset++) {
+ if (PCH_PHUB_OROM_SIZE < off + addr_offset)
+ goto return_ok;
+
+ ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
+ buf[addr_offset]);
+ if (ret) {
+ err = ret;
+ goto return_err;
+ }
+ }
+
+return_ok:
+ mutex_unlock(&pch_phub_mutex);
+ return addr_offset;
+
+return_err:
+ mutex_unlock(&pch_phub_mutex);
+ return err;
+}
+
+static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ u8 mac[8];
+ struct pch_phub_reg *chip = dev_get_drvdata(dev);
+
+ pch_phub_read_gbe_mac_addr(chip, mac);
+
+ return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u8 mac[6];
+ struct pch_phub_reg *chip = dev_get_drvdata(dev);
+
+ if (count != 18)
+ return -EINVAL;
+
+ sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+ (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
+ (u32 *)&mac[4], (u32 *)&mac[5]);
+
+ pch_phub_write_gbe_mac_addr(chip, mac);
+
+ return count;
+}
+
+static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
+
+static struct bin_attribute pch_bin_attr = {
+ .attr = {
+ .name = "pch_firmware",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .size = PCH_PHUB_OROM_SIZE + 1,
+ .read = pch_phub_bin_read,
+ .write = pch_phub_bin_write,
+};
+
+static int __devinit pch_phub_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int retval;
+
+ int ret;
+ ssize_t rom_size;
+ struct pch_phub_reg *chip;
+
+ chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
+ goto err_pci_enable_dev;
+ }
+ dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
+ ret);
+
+ ret = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
+ goto err_req_regions;
+ }
+ dev_dbg(&pdev->dev, "%s : "
+ "pci_request_regions returns %d\n", __func__, ret);
+
+ chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
+
+
+ if (chip->pch_phub_base_address == 0) {
+ dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
+ ret = -ENOMEM;
+ goto err_pci_iomap;
+ }
+ dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
+ "in pch_phub_base_address variable is %p\n", __func__,
+ chip->pch_phub_base_address);
+ chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
+
+ if (chip->pch_phub_extrom_base_address == 0) {
+ dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
+ ret = -ENOMEM;
+ goto err_pci_map;
+ }
+ dev_dbg(&pdev->dev, "%s : "
+ "pci_map_rom SUCCESS and value in "
+ "pch_phub_extrom_base_address variable is %p\n", __func__,
+ chip->pch_phub_extrom_base_address);
+
+ pci_set_drvdata(pdev, chip);
+
+ retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+ if (retval)
+ goto err_sysfs_create;
+
+ retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+ if (retval)
+ goto exit_bin_attr;
+
+ pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET,
+ CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
+
+ /* set the prefech value */
+ iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
+ /* set the interrupt delay value */
+ iowrite32(0x25, chip->pch_phub_base_address + 0x44);
+
+ return 0;
+exit_bin_attr:
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+
+err_sysfs_create:
+ pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
+err_pci_map:
+ pci_iounmap(pdev, chip->pch_phub_base_address);
+err_pci_iomap:
+ pci_release_regions(pdev);
+err_req_regions:
+ pci_disable_device(pdev);
+err_pci_enable_dev:
+ kfree(chip);
+ dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
+ return ret;
+}
+
+static void __devexit pch_phub_remove(struct pci_dev *pdev)
+{
+ struct pch_phub_reg *chip = pci_get_drvdata(pdev);
+
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
+ sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+ pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
+ pci_iounmap(pdev, chip->pch_phub_base_address);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ kfree(chip);
+}
+
+#ifdef CONFIG_PM
+
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ int ret;
+
+ pch_phub_save_reg_conf(pdev);
+ ret = pci_save_state(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ " %s -pci_save_state returns %d\n", __func__, ret);
+ return ret;
+ }
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int pch_phub_resume(struct pci_dev *pdev)
+{
+ int ret;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s-pci_enable_device failed(ret=%d) ", __func__, ret);
+ return ret;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pch_phub_restore_reg_conf(pdev);
+
+ return 0;
+}
+#else
+#define pch_phub_suspend NULL
+#define pch_phub_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_device_id pch_phub_pcidev_id[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
+ {0,}
+};
+
+static struct pci_driver pch_phub_driver = {
+ .name = "pch_phub",
+ .id_table = pch_phub_pcidev_id,
+ .probe = pch_phub_probe,
+ .remove = __devexit_p(pch_phub_remove),
+ .suspend = pch_phub_suspend,
+ .resume = pch_phub_resume
+};
+
+static int __init pch_phub_pci_init(void)
+{
+ return pci_register_driver(&pch_phub_driver);
+}
+
+static void __exit pch_phub_pci_exit(void)
+{
+ pci_unregister_driver(&pch_phub_driver);
+}
+
+module_init(pch_phub_pci_init);
+module_exit(pch_phub_pci_exit);
+
+MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 75ee0d3f6f45..4337ed781103 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/phantom.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -38,6 +38,7 @@
#define PHB_RUNNING 1
#define PHB_NOT_OH 2
+static DEFINE_MUTEX(phantom_mutex);
static struct class *phantom_class;
static int phantom_major;
@@ -215,17 +216,17 @@ static int phantom_open(struct inode *inode, struct file *file)
struct phantom_device *dev = container_of(inode->i_cdev,
struct phantom_device, cdev);
- lock_kernel();
+ mutex_lock(&phantom_mutex);
nonseekable_open(inode, file);
if (mutex_lock_interruptible(&dev->open_lock)) {
- unlock_kernel();
+ mutex_unlock(&phantom_mutex);
return -ERESTARTSYS;
}
if (dev->opened) {
mutex_unlock(&dev->open_lock);
- unlock_kernel();
+ mutex_unlock(&phantom_mutex);
return -EINVAL;
}
@@ -236,7 +237,7 @@ static int phantom_open(struct inode *inode, struct file *file)
atomic_set(&dev->counter, 0);
dev->opened++;
mutex_unlock(&dev->open_lock);
- unlock_kernel();
+ mutex_unlock(&phantom_mutex);
return 0;
}
@@ -279,6 +280,7 @@ static const struct file_operations phantom_file_ops = {
.unlocked_ioctl = phantom_ioctl,
.compat_ioctl = phantom_compat_ioctl,
.poll = phantom_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static irqreturn_t phantom_isr(int irq, void *data)
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index cb3b4d228475..d84450eecd21 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -587,6 +587,7 @@ static const struct file_operations gru_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = gru_file_unlocked_ioctl,
.mmap = gru_file_mmap,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice gru_miscdev = {
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index d545f79f6000..759a105cb216 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -29,7 +29,6 @@
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/scatterlist.h>
#include <linux/string_helpers.h>
@@ -51,6 +50,7 @@ MODULE_ALIAS("mmc:block");
#define MMC_SHIFT 3
#define MMC_NUM_MINORS (256 >> MMC_SHIFT)
+static DEFINE_MUTEX(block_mutex);
static DECLARE_BITMAP(dev_use, MMC_NUM_MINORS);
/*
@@ -108,7 +108,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
int ret = -ENXIO;
- lock_kernel();
+ mutex_lock(&block_mutex);
if (md) {
if (md->usage == 2)
check_disk_change(bdev);
@@ -119,7 +119,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
ret = -EROFS;
}
}
- unlock_kernel();
+ mutex_unlock(&block_mutex);
return ret;
}
@@ -128,9 +128,9 @@ static int mmc_blk_release(struct gendisk *disk, fmode_t mode)
{
struct mmc_blk_data *md = disk->private_data;
- lock_kernel();
+ mutex_lock(&block_mutex);
mmc_blk_put(md);
- unlock_kernel();
+ mutex_unlock(&block_mutex);
return 0;
}
@@ -620,7 +620,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
* messages to tell when the card is present.
*/
- sprintf(md->disk->disk_name, "mmcblk%d", devidx);
+ snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
+ "mmcblk%d", devidx);
blk_queue_logical_block_size(md->queue.queue, 512);
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 5dd8576b5c18..b7ac30ac71aa 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -56,7 +56,9 @@ struct mmc_test_mem {
* struct mmc_test_area - information for performance tests.
* @max_sz: test area size (in bytes)
* @dev_addr: address on card at which to do performance tests
- * @max_segs: maximum segments in scatterlist @sg
+ * @max_tfr: maximum transfer size allowed by driver (in bytes)
+ * @max_segs: maximum segments allowed by driver in scatterlist @sg
+ * @max_seg_sz: maximum segment size allowed by driver
* @blocks: number of (512 byte) blocks currently mapped by @sg
* @sg_len: length of currently mapped scatterlist @sg
* @mem: allocated memory
@@ -65,7 +67,9 @@ struct mmc_test_mem {
struct mmc_test_area {
unsigned long max_sz;
unsigned int dev_addr;
+ unsigned int max_tfr;
unsigned int max_segs;
+ unsigned int max_seg_sz;
unsigned int blocks;
unsigned int sg_len;
struct mmc_test_mem *mem;
@@ -245,13 +249,18 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem)
/*
* Allocate a lot of memory, preferrably max_sz but at least min_sz. In case
- * there isn't much memory do not exceed 1/16th total lowmem pages.
+ * there isn't much memory do not exceed 1/16th total lowmem pages. Also do
+ * not exceed a maximum number of segments and try not to make segments much
+ * bigger than maximum segment size.
*/
static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
- unsigned long max_sz)
+ unsigned long max_sz,
+ unsigned int max_segs,
+ unsigned int max_seg_sz)
{
unsigned long max_page_cnt = DIV_ROUND_UP(max_sz, PAGE_SIZE);
unsigned long min_page_cnt = DIV_ROUND_UP(min_sz, PAGE_SIZE);
+ unsigned long max_seg_page_cnt = DIV_ROUND_UP(max_seg_sz, PAGE_SIZE);
unsigned long page_cnt = 0;
unsigned long limit = nr_free_buffer_pages() >> 4;
struct mmc_test_mem *mem;
@@ -261,11 +270,17 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
if (max_page_cnt < min_page_cnt)
max_page_cnt = min_page_cnt;
+ if (max_seg_page_cnt > max_page_cnt)
+ max_seg_page_cnt = max_page_cnt;
+
+ if (max_segs > max_page_cnt)
+ max_segs = max_page_cnt;
+
mem = kzalloc(sizeof(struct mmc_test_mem), GFP_KERNEL);
if (!mem)
return NULL;
- mem->arr = kzalloc(sizeof(struct mmc_test_pages) * max_page_cnt,
+ mem->arr = kzalloc(sizeof(struct mmc_test_pages) * max_segs,
GFP_KERNEL);
if (!mem->arr)
goto out_free;
@@ -276,7 +291,7 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
gfp_t flags = GFP_KERNEL | GFP_DMA | __GFP_NOWARN |
__GFP_NORETRY;
- order = get_order(max_page_cnt << PAGE_SHIFT);
+ order = get_order(max_seg_page_cnt << PAGE_SHIFT);
while (1) {
page = alloc_pages(flags, order);
if (page || !order)
@@ -293,6 +308,11 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
mem->cnt += 1;
if (max_page_cnt <= (1UL << order))
break;
+ if (mem->cnt >= max_segs) {
+ if (page_cnt < min_page_cnt)
+ goto out_free;
+ break;
+ }
max_page_cnt -= 1UL << order;
page_cnt += 1UL << order;
}
@@ -310,7 +330,8 @@ out_free:
*/
static int mmc_test_map_sg(struct mmc_test_mem *mem, unsigned long sz,
struct scatterlist *sglist, int repeat,
- unsigned int max_segs, unsigned int *sg_len)
+ unsigned int max_segs, unsigned int max_seg_sz,
+ unsigned int *sg_len)
{
struct scatterlist *sg = NULL;
unsigned int i;
@@ -322,8 +343,10 @@ static int mmc_test_map_sg(struct mmc_test_mem *mem, unsigned long sz,
for (i = 0; i < mem->cnt; i++) {
unsigned long len = PAGE_SIZE << mem->arr[i].order;
- if (sz < len)
+ if (len > sz)
len = sz;
+ if (len > max_seg_sz)
+ len = max_seg_sz;
if (sg)
sg = sg_next(sg);
else
@@ -355,6 +378,7 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
unsigned long sz,
struct scatterlist *sglist,
unsigned int max_segs,
+ unsigned int max_seg_sz,
unsigned int *sg_len)
{
struct scatterlist *sg = NULL;
@@ -365,7 +389,7 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
sg_init_table(sglist, max_segs);
*sg_len = 0;
- while (sz && i) {
+ while (sz) {
base = page_address(mem->arr[--i].page);
cnt = 1 << mem->arr[i].order;
while (sz && cnt) {
@@ -374,7 +398,9 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
continue;
last_addr = addr;
len = PAGE_SIZE;
- if (sz < len)
+ if (len > max_seg_sz)
+ len = max_seg_sz;
+ if (len > sz)
len = sz;
if (sg)
sg = sg_next(sg);
@@ -386,6 +412,8 @@ static int mmc_test_map_sg_max_scatter(struct mmc_test_mem *mem,
sz -= len;
*sg_len += 1;
}
+ if (i == 0)
+ i = mem->cnt;
}
if (sg)
@@ -1215,16 +1243,22 @@ static int mmc_test_area_map(struct mmc_test_card *test, unsigned long sz,
int max_scatter)
{
struct mmc_test_area *t = &test->area;
+ int err;
t->blocks = sz >> 9;
if (max_scatter) {
- return mmc_test_map_sg_max_scatter(t->mem, sz, t->sg,
- t->max_segs, &t->sg_len);
- } else {
- return mmc_test_map_sg(t->mem, sz, t->sg, 1, t->max_segs,
+ err = mmc_test_map_sg_max_scatter(t->mem, sz, t->sg,
+ t->max_segs, t->max_seg_sz,
&t->sg_len);
+ } else {
+ err = mmc_test_map_sg(t->mem, sz, t->sg, 1, t->max_segs,
+ t->max_seg_sz, &t->sg_len);
}
+ if (err)
+ printk(KERN_INFO "%s: Failed to map sg list\n",
+ mmc_hostname(test->card->host));
+ return err;
}
/*
@@ -1249,6 +1283,22 @@ static int mmc_test_area_io(struct mmc_test_card *test, unsigned long sz,
struct timespec ts1, ts2;
int ret;
+ /*
+ * In the case of a maximally scattered transfer, the maximum transfer
+ * size is further limited by using PAGE_SIZE segments.
+ */
+ if (max_scatter) {
+ struct mmc_test_area *t = &test->area;
+ unsigned long max_tfr;
+
+ if (t->max_seg_sz >= PAGE_SIZE)
+ max_tfr = t->max_segs * PAGE_SIZE;
+ else
+ max_tfr = t->max_segs * t->max_seg_sz;
+ if (sz > max_tfr)
+ sz = max_tfr;
+ }
+
ret = mmc_test_area_map(test, sz, max_scatter);
if (ret)
return ret;
@@ -1274,7 +1324,7 @@ static int mmc_test_area_io(struct mmc_test_card *test, unsigned long sz,
*/
static int mmc_test_area_fill(struct mmc_test_card *test)
{
- return mmc_test_area_io(test, test->area.max_sz, test->area.dev_addr,
+ return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
1, 0, 0);
}
@@ -1328,16 +1378,29 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill)
t->max_sz = TEST_AREA_MAX_SIZE;
else
t->max_sz = (unsigned long)test->card->pref_erase << 9;
+
+ t->max_segs = test->card->host->max_segs;
+ t->max_seg_sz = test->card->host->max_seg_size;
+
+ t->max_tfr = t->max_sz;
+ if (t->max_tfr >> 9 > test->card->host->max_blk_count)
+ t->max_tfr = test->card->host->max_blk_count << 9;
+ if (t->max_tfr > test->card->host->max_req_size)
+ t->max_tfr = test->card->host->max_req_size;
+ if (t->max_tfr / t->max_seg_sz > t->max_segs)
+ t->max_tfr = t->max_segs * t->max_seg_sz;
+
/*
* Try to allocate enough memory for the whole area. Less is OK
* because the same memory can be mapped into the scatterlist more than
- * once.
+ * once. Also, take into account the limits imposed on scatterlist
+ * segments by the host driver.
*/
- t->mem = mmc_test_alloc_mem(min_sz, t->max_sz);
+ t->mem = mmc_test_alloc_mem(min_sz, t->max_sz, t->max_segs,
+ t->max_seg_sz);
if (!t->mem)
return -ENOMEM;
- t->max_segs = DIV_ROUND_UP(t->max_sz, PAGE_SIZE);
t->sg = kmalloc(sizeof(struct scatterlist) * t->max_segs, GFP_KERNEL);
if (!t->sg) {
ret = -ENOMEM;
@@ -1401,7 +1464,7 @@ static int mmc_test_area_prepare_fill(struct mmc_test_card *test)
static int mmc_test_best_performance(struct mmc_test_card *test, int write,
int max_scatter)
{
- return mmc_test_area_io(test, test->area.max_sz, test->area.dev_addr,
+ return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
write, max_scatter, 1);
}
@@ -1446,12 +1509,13 @@ static int mmc_test_profile_read_perf(struct mmc_test_card *test)
unsigned int dev_addr;
int ret;
- for (sz = 512; sz < test->area.max_sz; sz <<= 1) {
+ for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
dev_addr = test->area.dev_addr + (sz >> 9);
ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
if (ret)
return ret;
}
+ sz = test->area.max_tfr;
dev_addr = test->area.dev_addr;
return mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
}
@@ -1468,7 +1532,7 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
ret = mmc_test_area_erase(test);
if (ret)
return ret;
- for (sz = 512; sz < test->area.max_sz; sz <<= 1) {
+ for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
dev_addr = test->area.dev_addr + (sz >> 9);
ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
if (ret)
@@ -1477,6 +1541,7 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
ret = mmc_test_area_erase(test);
if (ret)
return ret;
+ sz = test->area.max_tfr;
dev_addr = test->area.dev_addr;
return mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
}
@@ -1516,29 +1581,63 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
return 0;
}
+static int mmc_test_seq_read_perf(struct mmc_test_card *test, unsigned long sz)
+{
+ unsigned int dev_addr, i, cnt;
+ struct timespec ts1, ts2;
+ int ret;
+
+ cnt = test->area.max_sz / sz;
+ dev_addr = test->area.dev_addr;
+ getnstimeofday(&ts1);
+ for (i = 0; i < cnt; i++) {
+ ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0);
+ if (ret)
+ return ret;
+ dev_addr += (sz >> 9);
+ }
+ getnstimeofday(&ts2);
+ mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
+ return 0;
+}
+
/*
* Consecutive read performance by transfer size.
*/
static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
{
unsigned long sz;
+ int ret;
+
+ for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
+ ret = mmc_test_seq_read_perf(test, sz);
+ if (ret)
+ return ret;
+ }
+ sz = test->area.max_tfr;
+ return mmc_test_seq_read_perf(test, sz);
+}
+
+static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
+{
unsigned int dev_addr, i, cnt;
struct timespec ts1, ts2;
int ret;
- for (sz = 512; sz <= test->area.max_sz; sz <<= 1) {
- cnt = test->area.max_sz / sz;
- dev_addr = test->area.dev_addr;
- getnstimeofday(&ts1);
- for (i = 0; i < cnt; i++) {
- ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0);
- if (ret)
- return ret;
- dev_addr += (sz >> 9);
- }
- getnstimeofday(&ts2);
- mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
+ ret = mmc_test_area_erase(test);
+ if (ret)
+ return ret;
+ cnt = test->area.max_sz / sz;
+ dev_addr = test->area.dev_addr;
+ getnstimeofday(&ts1);
+ for (i = 0; i < cnt; i++) {
+ ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
+ if (ret)
+ return ret;
+ dev_addr += (sz >> 9);
}
+ getnstimeofday(&ts2);
+ mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
return 0;
}
@@ -1548,27 +1647,15 @@ static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
{
unsigned long sz;
- unsigned int dev_addr, i, cnt;
- struct timespec ts1, ts2;
int ret;
- for (sz = 512; sz <= test->area.max_sz; sz <<= 1) {
- ret = mmc_test_area_erase(test);
+ for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
+ ret = mmc_test_seq_write_perf(test, sz);
if (ret)
return ret;
- cnt = test->area.max_sz / sz;
- dev_addr = test->area.dev_addr;
- getnstimeofday(&ts1);
- for (i = 0; i < cnt; i++) {
- ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
- if (ret)
- return ret;
- dev_addr += (sz >> 9);
- }
- getnstimeofday(&ts2);
- mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
}
- return 0;
+ sz = test->area.max_tfr;
+ return mmc_test_seq_write_perf(test, sz);
}
/*
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index e876678176be..91c99e76c8cc 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -128,7 +128,6 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
mq->req = NULL;
blk_queue_prep_rq(mq->queue, mmc_prep_request);
- blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN);
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
if (mmc_can_erase(card)) {
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mq->queue);
@@ -147,7 +146,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
}
#ifdef CONFIG_MMC_BLOCK_BOUNCE
- if (host->max_hw_segs == 1) {
+ if (host->max_segs == 1) {
unsigned int bouncesz;
bouncesz = MMC_QUEUE_BOUNCESZ;
@@ -197,19 +196,19 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
blk_queue_bounce_limit(mq->queue, limit);
blk_queue_max_hw_sectors(mq->queue,
min(host->max_blk_count, host->max_req_size / 512));
- blk_queue_max_segments(mq->queue, host->max_hw_segs);
+ blk_queue_max_segments(mq->queue, host->max_segs);
blk_queue_max_segment_size(mq->queue, host->max_seg_size);
mq->sg = kmalloc(sizeof(struct scatterlist) *
- host->max_phys_segs, GFP_KERNEL);
+ host->max_segs, GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
goto cleanup_queue;
}
- sg_init_table(mq->sg, host->max_phys_segs);
+ sg_init_table(mq->sg, host->max_segs);
}
- init_MUTEX(&mq->thread_sem);
+ sema_init(&mq->thread_sem, 1);
mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");
if (IS_ERR(mq->thread)) {
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 53cb380c0987..21f8b466e5fa 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -245,6 +245,7 @@ static const struct file_operations mmc_dbg_ext_csd_fops = {
.open = mmc_ext_csd_open,
.read = mmc_ext_csd_read,
.release = mmc_ext_csd_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
void mmc_add_card_debugfs(struct mmc_card *card)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index d80cfdc8edd2..10b8af27e03a 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -94,8 +94,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
* By default, hosts do not support SGIO or large requests.
* They have to set these according to their abilities.
*/
- host->max_hw_segs = 1;
- host->max_phys_segs = 1;
+ host->max_segs = 1;
host->max_seg_size = PAGE_CACHE_SIZE;
host->max_req_size = PAGE_CACHE_SIZE;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index bd2755e8d9a3..f332c52968b7 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -362,9 +362,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
goto err;
}
- err = mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid);
-
- if (!err) {
+ if (ocr & R4_MEMORY_PRESENT
+ && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) {
card->type = MMC_TYPE_SD_COMBO;
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 68d12794cfd9..ce099c4ba0f0 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,18 @@ config MMC_SDHCI_CNS3XXX
If unsure, say N.
+config MMC_SDHCI_MV
+ tristate "SDHCI support on Marvell's SoC"
+ depends on MMC_SDHCI
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the Secure Digital Host Controller Interface in
+ Marvell's SoC controllers.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
config MMC_SDHCI_S3C
tristate "SDHCI support on Samsung S3C SoC"
depends on MMC_SDHCI && PLAT_SAMSUNG
@@ -451,3 +463,17 @@ config MMC_JZ4740
SoCs.
If you have a board based on such a SoC and with a SD/MMC slot,
say Y or M here.
+
+config MMC_USHC
+ tristate "USB SD Host Controller (USHC) support"
+ depends on USB
+ help
+ This selects support for USB SD Host Controllers based on
+ the Cypress Astoria chip with firmware compliant with CSR's
+ USB SD Host Controller specification (CS-118793-SP).
+
+ CSR boards with this device include: USB<>SDIO (M1985v2),
+ and Ultrasira.
+
+ Note: These controllers only support SDIO cards and do not
+ support MMC or SD memory cards.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 840bcb52d82f..697bbfe759ed 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -11,6 +11,7 @@ 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_MV) += sdhci-mv.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
@@ -36,6 +37,7 @@ obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
+obj-$(CONFIG_MMC_USHC) += ushc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-platform.o
sdhci-platform-y := sdhci-pltfm.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 5f3a599ead07..591ab540b407 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -66,6 +66,7 @@
#include <linux/clk.h>
#include <linux/atmel_pdc.h>
#include <linux/gfp.h>
+#include <linux/highmem.h>
#include <linux/mmc/host.h>
@@ -927,7 +928,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
if (!res)
return -ENXIO;
- if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))
+ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME))
return -EBUSY;
mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
@@ -946,8 +947,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->max_blk_size = MCI_MAXBLKSIZE;
mmc->max_blk_count = MCI_BLKATONCE;
mmc->max_req_size = MCI_BUFSIZE;
- mmc->max_phys_segs = MCI_BLKATONCE;
- mmc->max_hw_segs = MCI_BLKATONCE;
+ mmc->max_segs = MCI_BLKATONCE;
mmc->max_seg_size = MCI_BUFSIZE;
host = mmc_priv(mmc);
@@ -1016,7 +1016,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
/*
* Map I/O region
*/
- host->baseaddr = ioremap(res->start, res->end - res->start + 1);
+ host->baseaddr = ioremap(res->start, resource_size(res));
if (!host->baseaddr) {
ret = -ENOMEM;
goto fail1;
@@ -1092,7 +1092,7 @@ fail4b:
fail5:
mmc_free_host(mmc);
fail6:
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
dev_err(&pdev->dev, "probe failed, err %d\n", ret);
return ret;
}
@@ -1137,7 +1137,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
iounmap(host->baseaddr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
mmc_free_host(mmc);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 95ef864ad8f9..301351a5d838 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1618,8 +1618,7 @@ static int __init atmci_init_slot(struct atmel_mci *host,
if (slot_data->bus_width >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- mmc->max_hw_segs = 64;
- mmc->max_phys_segs = 64;
+ mmc->max_segs = 64;
mmc->max_req_size = 32768 * 512;
mmc->max_blk_size = 32768;
mmc->max_blk_count = 512;
@@ -1777,7 +1776,7 @@ static int __init atmci_probe(struct platform_device *pdev)
}
ret = -ENOMEM;
- host->regs = ioremap(regs->start, regs->end - regs->start + 1);
+ host->regs = ioremap(regs->start, resource_size(regs));
if (!host->regs)
goto err_ioremap;
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index c8da5d30a861..41e5a60493ad 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -964,7 +964,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
goto out1;
}
- host->ioarea = request_mem_region(r->start, r->end - r->start + 1,
+ host->ioarea = request_mem_region(r->start, resource_size(r),
pdev->name);
if (!host->ioarea) {
dev_err(&pdev->dev, "mmio already in use\n");
@@ -998,7 +998,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
mmc->f_max = 24000000;
mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
- mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
+ mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
mmc->max_blk_size = 2048;
mmc->max_blk_count = 512;
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 4b0e677d7295..bac7d62866b7 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -469,7 +469,7 @@ static int __devinit sdh_probe(struct platform_device *pdev)
}
mmc->ops = &sdh_ops;
- mmc->max_phys_segs = 32;
+ mmc->max_segs = 32;
mmc->max_seg_size = 1 << 16;
mmc->max_blk_size = 1 << 11;
mmc->max_blk_count = 1 << 11;
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 33d9f1b00862..e15547cf701f 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -138,7 +138,7 @@
/*
* One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units,
* and we handle up to MAX_NR_SG segments. MMC_BLOCK_BOUNCE kicks in only
- * for drivers with max_hw_segs == 1, making the segments bigger (64KB)
+ * for drivers with max_segs == 1, making the segments bigger (64KB)
* than the page or two that's otherwise typical. nr_sg (passed from
* platform data) == 16 gives at least the same throughput boost, using
* EDMA transfer linkage instead of spending CPU time copying pages.
@@ -1239,8 +1239,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
* Each hw_seg uses one EDMA parameter RAM slot, always one
* channel and then usually some linked slots.
*/
- mmc->max_hw_segs = 1 + host->n_link;
- mmc->max_phys_segs = mmc->max_hw_segs;
+ mmc->max_segs = 1 + host->n_link;
/* EDMA limit per hw segment (one or two MBytes) */
mmc->max_seg_size = MAX_CCNT * rw_threshold;
@@ -1250,8 +1249,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
mmc->max_blk_count = 65535; /* NBLK is 16 bits */
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
- dev_dbg(mmc_dev(host->mmc), "max_phys_segs=%d\n", mmc->max_phys_segs);
- dev_dbg(mmc_dev(host->mmc), "max_hw_segs=%d\n", mmc->max_hw_segs);
+ dev_dbg(mmc_dev(host->mmc), "max_segs=%d\n", mmc->max_segs);
dev_dbg(mmc_dev(host->mmc), "max_blk_size=%d\n", mmc->max_blk_size);
dev_dbg(mmc_dev(host->mmc), "max_req_size=%d\n", mmc->max_req_size);
dev_dbg(mmc_dev(host->mmc), "max_seg_size=%d\n", mmc->max_seg_size);
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 9a68ff4353a2..881f7ba545ae 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -148,11 +148,12 @@ static int imxmci_start_clock(struct imxmci_host *host)
while (delay--) {
reg = readw(host->base + MMC_REG_STATUS);
- if (reg & STATUS_CARD_BUS_CLK_RUN)
+ if (reg & STATUS_CARD_BUS_CLK_RUN) {
/* Check twice before cut */
reg = readw(host->base + MMC_REG_STATUS);
if (reg & STATUS_CARD_BUS_CLK_RUN)
return 0;
+ }
if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events))
return 0;
@@ -965,8 +966,7 @@ static int __init imxmci_probe(struct platform_device *pdev)
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_segs = 64;
mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */
mmc->max_req_size = 64*512; /* default PAGE_CACHE_SIZE */
mmc->max_blk_size = 2048;
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index ad4f9870e3ca..b3a0ab0e4c2b 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -876,8 +876,7 @@ static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
mmc->max_blk_count = (1 << 15) - 1;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
- mmc->max_phys_segs = 128;
- mmc->max_hw_segs = 128;
+ mmc->max_segs = 128;
mmc->max_seg_size = mmc->max_req_size;
host->mmc = mmc;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 62a35822003e..5b0b50636ec4 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1345,8 +1345,7 @@ static int mmc_spi_probe(struct spi_device *spi)
mmc->ops = &mmc_spi_ops;
mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
- mmc->max_hw_segs = MMC_SPI_BLOCKSATONCE;
- mmc->max_phys_segs = MMC_SPI_BLOCKSATONCE;
+ mmc->max_segs = MMC_SPI_BLOCKSATONCE;
mmc->max_req_size = MMC_SPI_BLOCKSATONCE * MMC_SPI_BLOCKSIZE;
mmc->max_blk_count = MMC_SPI_BLOCKSATONCE;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 840b301b5671..bf4f1c896675 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -41,23 +41,35 @@ static unsigned int fmax = 515633;
* @clkreg: default value for MCICLOCK register
* @clkreg_enable: enable value for MMCICLOCK register
* @datalength_bits: number of bits in the MMCIDATALENGTH register
+ * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
+ * is asserted (likewise for RX)
+ * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
+ * is asserted (likewise for RX)
*/
struct variant_data {
unsigned int clkreg;
unsigned int clkreg_enable;
unsigned int datalength_bits;
+ unsigned int fifosize;
+ unsigned int fifohalfsize;
};
static struct variant_data variant_arm = {
+ .fifosize = 16 * 4,
+ .fifohalfsize = 8 * 4,
.datalength_bits = 16,
};
static struct variant_data variant_u300 = {
+ .fifosize = 16 * 4,
+ .fifohalfsize = 8 * 4,
.clkreg_enable = 1 << 13, /* HWFCEN */
.datalength_bits = 16,
};
static struct variant_data variant_ux500 = {
+ .fifosize = 30 * 4,
+ .fifohalfsize = 8 * 4,
.clkreg = MCI_CLK_ENABLE,
.clkreg_enable = 1 << 14, /* HWFCEN */
.datalength_bits = 24,
@@ -138,6 +150,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
+ struct variant_data *variant = host->variant;
unsigned int datactrl, timeout, irqmask;
unsigned long long clks;
void __iomem *base;
@@ -173,7 +186,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
* If we have less than a FIFOSIZE of bytes to transfer,
* trigger a PIO interrupt as soon as any data is available.
*/
- if (host->size < MCI_FIFOSIZE)
+ if (host->size < variant->fifosize)
irqmask |= MCI_RXDATAAVLBLMASK;
} else {
/*
@@ -332,13 +345,15 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
{
+ struct variant_data *variant = host->variant;
void __iomem *base = host->base;
char *ptr = buffer;
do {
unsigned int count, maxcnt;
- maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : MCI_FIFOHALFSIZE;
+ maxcnt = status & MCI_TXFIFOEMPTY ?
+ variant->fifosize : variant->fifohalfsize;
count = min(remain, maxcnt);
writesl(base + MMCIFIFO, ptr, count >> 2);
@@ -362,6 +377,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
{
struct mmci_host *host = dev_id;
struct sg_mapping_iter *sg_miter = &host->sg_miter;
+ struct variant_data *variant = host->variant;
void __iomem *base = host->base;
unsigned long flags;
u32 status;
@@ -420,7 +436,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
* If we're nearing the end of the read, switch to
* "any data available" mode.
*/
- if (status & MCI_RXACTIVE && host->size < MCI_FIFOSIZE)
+ if (status & MCI_RXACTIVE && host->size < variant->fifosize)
writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1);
/*
@@ -570,12 +586,13 @@ static int mmci_get_ro(struct mmc_host *mmc)
static int mmci_get_cd(struct mmc_host *mmc)
{
struct mmci_host *host = mmc_priv(mmc);
+ struct mmci_platform_data *plat = host->plat;
unsigned int status;
if (host->gpio_cd == -ENOSYS)
- status = host->plat->status(mmc_dev(host->mmc));
+ status = plat->status(mmc_dev(host->mmc));
else
- status = !gpio_get_value(host->gpio_cd);
+ status = !!gpio_get_value(host->gpio_cd) ^ plat->cd_invert;
/*
* Use positive logic throughout - status is zero for no card,
@@ -704,8 +721,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
/*
* We can do SGIO
*/
- mmc->max_hw_segs = 16;
- mmc->max_phys_segs = NR_SG;
+ mmc->max_segs = NR_SG;
/*
* Since only a certain number of bits are valid in the data length
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 68970cfb81e1..4e18f5403f48 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -133,13 +133,6 @@
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
-/*
- * The size of the FIFO in bytes.
- */
-#define MCI_FIFOSIZE (16*4)
-
-#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
-
#define NR_SG 16
struct clk;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index ff7752348b11..1290d14c5839 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1164,8 +1164,7 @@ msmsdcc_probe(struct platform_device *pdev)
mmc->caps |= MMC_CAP_SDIO_IRQ;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
- mmc->max_phys_segs = NR_SG;
- mmc->max_hw_segs = NR_SG;
+ mmc->max_segs = NR_SG;
mmc->max_blk_size = 4096; /* MCI_DATA_CTL BLOCKSIZE up to 4096 */
mmc->max_blk_count = 65536;
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 366eefa77c5a..a5bf60e01af4 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -742,8 +742,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
mmc->max_blk_size = 2048;
mmc->max_blk_count = 65535;
- mmc->max_hw_segs = 1;
- mmc->max_phys_segs = 1;
+ mmc->max_segs = 1;
mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 350f78e86245..bdd2cbb87cba 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -790,8 +790,7 @@ static int mxcmci_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
/* MMC core transfer sizes tunable parameters */
- mmc->max_hw_segs = 64;
- mmc->max_phys_segs = 64;
+ mmc->max_segs = 64;
mmc->max_blk_size = 2048;
mmc->max_blk_count = 65535;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index d98ddcfac5e5..0c7e37f496ef 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1335,8 +1335,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
* NOTE max_seg_size assumption that small blocks aren't
* normally used (except e.g. for reading SD registers).
*/
- mmc->max_phys_segs = 32;
- mmc->max_hw_segs = 32;
+ mmc->max_segs = 32;
mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */
mmc->max_blk_count = 2048; /* NBLK is 11 bits (+1) */
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4a8776f8afdd..03c26e026506 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2105,8 +2105,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
/* Since we do only SG emulation, we can have as many segs
* as we want. */
- mmc->max_phys_segs = 1024;
- mmc->max_hw_segs = 1024;
+ mmc->max_segs = 1024;
mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
@@ -2305,7 +2304,6 @@ static int omap_hsmmc_suspend(struct device *dev)
int ret = 0;
struct platform_device *pdev = to_platform_device(dev);
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
- pm_message_t state = PMSG_SUSPEND; /* unused by MMC core */
if (host && host->suspended)
return 0;
@@ -2324,8 +2322,8 @@ static int omap_hsmmc_suspend(struct device *dev)
}
}
cancel_work_sync(&host->mmc_carddetect_work);
- mmc_host_enable(host->mmc);
ret = mmc_suspend_host(host->mmc);
+ mmc_host_enable(host->mmc);
if (ret == 0) {
omap_hsmmc_disable_irq(host);
OMAP_HSMMC_WRITE(host->base, HCTL,
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 0a4e43f37140..b7dfcac31e8a 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -576,7 +576,7 @@ static int pxamci_probe(struct platform_device *pdev)
* We can do SG-DMA, but we don't because we never know how much
* data we successfully wrote to the card.
*/
- mmc->max_phys_segs = NR_SG;
+ mmc->max_segs = NR_SG;
/*
* Our hardware DMA can handle a maximum of one page per SG entry.
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 2e16e0a90a5e..1ccd4b256cee 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1600,7 +1600,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
host->pio_active = XFER_NONE;
#ifdef CONFIG_MMC_S3C_PIODMA
- host->dodma = host->pdata->dma;
+ host->dodma = host->pdata->use_dma;
#endif
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1736,8 +1736,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
mmc->max_req_size = 4095 * 512;
mmc->max_seg_size = mmc->max_req_size;
- mmc->max_phys_segs = 128;
- mmc->max_hw_segs = 128;
+ mmc->max_segs = 128;
dbg(host, dbg_debug,
"probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",
diff --git a/drivers/mmc/host/sdhci-mv.c b/drivers/mmc/host/sdhci-mv.c
new file mode 100644
index 000000000000..8b8a8fe3fb5e
--- /dev/null
+++ b/drivers/mmc/host/sdhci-mv.c
@@ -0,0 +1,242 @@
+/*
+ * sdhci-mv.c Support for SDHCI platform devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform devices found on Marvell SoC's
+ *
+ * Based on sdhci-pltfm.c
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_mv_host {
+#if defined(CONFIG_HAVE_CLK)
+ struct clk *clk;
+#endif
+};
+
+/*****************************************************************************\
+ * *
+ * SDHCI core callbacks *
+ * *
+\*****************************************************************************/
+static u16 mv_readw(struct sdhci_host *host, int reg)
+{
+ u16 ret;
+
+ switch (reg) {
+ case SDHCI_HOST_VERSION:
+ case SDHCI_SLOT_INT_STATUS:
+ /* those registers don't exist */
+ return 0;
+ default:
+ ret = readw(host->ioaddr + reg);
+ }
+ return ret;
+}
+
+static u32 mv_readl(struct sdhci_host *host, int reg)
+{
+ u32 ret;
+
+ switch (reg) {
+ case SDHCI_CAPABILITIES:
+ ret = readl(host->ioaddr + reg);
+ /* Mask the support for 3.0V */
+ ret &= ~SDHCI_CAN_VDD_300;
+ break;
+ default:
+ ret = readl(host->ioaddr + reg);
+ }
+ return ret;
+}
+
+static struct sdhci_ops sdhci_mv_ops = {
+ .read_w = mv_readw,
+ .read_l = mv_readl,
+};
+
+/*****************************************************************************\
+ * *
+ * Device probing/removal *
+ * *
+\*****************************************************************************/
+
+static int __devinit sdhci_mv_probe(struct platform_device *pdev)
+{
+ struct sdhci_host *host;
+ struct sdhci_mv_host *mv_host;
+ struct resource *iomem;
+ int ret;
+
+ BUG_ON(pdev == NULL);
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iomem) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (resource_size(iomem) != 0x100)
+ dev_err(&pdev->dev, "Invalid iomem size. You may "
+ "experience problems.\n");
+
+ if (pdev->dev.parent)
+ host = sdhci_alloc_host(pdev->dev.parent, sizeof(*mv_host));
+ else
+ host = sdhci_alloc_host(&pdev->dev, sizeof(*mv_host));
+
+ if (IS_ERR(host)) {
+ ret = PTR_ERR(host);
+ goto err;
+ }
+
+ mv_host = sdhci_priv(host);
+ host->hw_name = "marvell-sdhci";
+ host->ops = &sdhci_mv_ops;
+ host->irq = platform_get_irq(pdev, 0);
+ host->quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
+ SDHCI_QUIRK_NO_BUSY_IRQ |
+ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+ SDHCI_QUIRK_FORCE_DMA;
+
+ if (!devm_request_mem_region(&pdev->dev, iomem->start,
+ resource_size(iomem),
+ mmc_hostname(host->mmc))) {
+ dev_err(&pdev->dev, "cannot request region\n");
+ ret = -EBUSY;
+ goto err_request;
+ }
+
+ host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
+ resource_size(iomem));
+ if (!host->ioaddr) {
+ dev_err(&pdev->dev, "failed to remap registers\n");
+ ret = -ENOMEM;
+ goto err_request;
+ }
+
+#if defined(CONFIG_HAVE_CLK)
+ mv_host->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(mv_host->clk))
+ dev_notice(&pdev->dev, "cannot get clkdev\n");
+ else
+ clk_enable(mv_host->clk);
+#endif
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_request;
+
+ platform_set_drvdata(pdev, host);
+
+ return 0;
+
+err_request:
+ sdhci_free_host(host);
+err:
+ printk(KERN_ERR"Probing of sdhci-mv failed: %d\n", ret);
+ return ret;
+}
+
+static int __devexit sdhci_mv_remove(struct platform_device *pdev)
+{
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+#if defined(CONFIG_HAVE_CLK)
+ struct sdhci_mv_host *mv_host = sdhci_priv(host);
+ struct clk *clk = mv_host->clk;
+#endif
+ int dead;
+ u32 scratch;
+
+ dead = 0;
+ scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+ if (scratch == (u32)-1)
+ dead = 1;
+
+ sdhci_remove_host(host, dead);
+ sdhci_free_host(host);
+ platform_set_drvdata(pdev, NULL);
+#if defined(CONFIG_HAVE_CLK)
+ if (!IS_ERR(clk)) {
+ clk_disable(clk);
+ clk_put(clk);
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sdhci_mv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+ return sdhci_suspend_host(host, state);
+}
+
+static int sdhci_mv_resume(struct platform_device *pdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&pdev->dev);
+
+ return sdhci_resume_host(host);
+}
+#else
+#define sdhci_mv_suspend NULL
+#define sdhci_mv_resume NULL
+#endif
+
+static struct platform_driver sdhci_mv_driver = {
+ .driver = {
+ .name = "sdhci-mv",
+ .owner = THIS_MODULE,
+ },
+ .probe = sdhci_mv_probe,
+ .remove = __devexit_p(sdhci_mv_remove),
+ .suspend = sdhci_mv_suspend,
+ .resume = sdhci_mv_resume,
+};
+
+/*****************************************************************************\
+ * *
+ * Driver init/exit *
+ * *
+\*****************************************************************************/
+
+static int __init sdhci_mv_init(void)
+{
+ return platform_driver_register(&sdhci_mv_driver);
+}
+
+static void __exit sdhci_mv_exit(void)
+{
+ platform_driver_unregister(&sdhci_mv_driver);
+}
+
+module_init(sdhci_mv_init);
+module_exit(sdhci_mv_exit);
+
+MODULE_DESCRIPTION("Marvell SDHCI platform driver");
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sdhci-mv");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 401527d273b5..ac8b12b18fa4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1001,13 +1001,28 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
if (clock == 0)
goto out;
- for (div = 1;div < 256;div *= 2) {
- if ((host->max_clk / div) <= clock)
- break;
+ if (host->version >= SDHCI_SPEC_300) {
+ /* Version 3.00 divisors must be a multiple of 2. */
+ if (host->max_clk <= clock)
+ div = 1;
+ else {
+ for (div = 2; div < 2046; div += 2) {
+ if ((host->max_clk / div) <= clock)
+ break;
+ }
+ }
+ } else {
+ /* Version 2.00 divisors must be a power of 2. */
+ for (div = 1; div < 256; div *= 2) {
+ if ((host->max_clk / div) <= clock)
+ break;
+ }
}
div >>= 1;
- clk = div << SDHCI_DIVIDER_SHIFT;
+ clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
+ clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
+ << SDHCI_DIVIDER_HI_SHIFT;
clk |= SDHCI_CLOCK_INT_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
@@ -1427,7 +1442,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
sdhci_finish_command(host);
}
-#ifdef DEBUG
+#ifdef CONFIG_MMC_DEBUG
static void sdhci_show_adma_error(struct sdhci_host *host)
{
const char *name = mmc_hostname(host->mmc);
@@ -1708,7 +1723,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (host->version & SDHCI_SPEC_VER_MASK)
>> SDHCI_SPEC_VER_SHIFT;
- if (host->version > SDHCI_SPEC_200) {
+ if (host->version > SDHCI_SPEC_300) {
printk(KERN_ERR "%s: Unknown controller version (%d). "
"You may experience problems.\n", mmc_hostname(mmc),
host->version);
@@ -1779,8 +1794,13 @@ int sdhci_add_host(struct sdhci_host *host)
mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
}
- host->max_clk =
- (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+ if (host->version >= SDHCI_SPEC_300)
+ host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK)
+ >> SDHCI_CLOCK_BASE_SHIFT;
+ else
+ host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK)
+ >> SDHCI_CLOCK_BASE_SHIFT;
+
host->max_clk *= 1000000;
if (host->max_clk == 0 || host->quirks &
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
@@ -1850,12 +1870,11 @@ int sdhci_add_host(struct sdhci_host *host)
* can do scatter/gather or not.
*/
if (host->flags & SDHCI_USE_ADMA)
- mmc->max_hw_segs = 128;
+ mmc->max_segs = 128;
else if (host->flags & SDHCI_USE_SDMA)
- mmc->max_hw_segs = 1;
+ mmc->max_segs = 1;
else /* PIO */
- mmc->max_hw_segs = 128;
- mmc->max_phys_segs = 128;
+ mmc->max_segs = 128;
/*
* Maximum number of sectors in one transfer. Limited by DMA boundary
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index d316bc79b636..ae28a310a6a1 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -86,6 +86,10 @@
#define SDHCI_CLOCK_CONTROL 0x2C
#define SDHCI_DIVIDER_SHIFT 8
+#define SDHCI_DIVIDER_HI_SHIFT 6
+#define SDHCI_DIV_MASK 0xFF
+#define SDHCI_DIV_MASK_LEN 8
+#define SDHCI_DIV_HI_MASK 0x300
#define SDHCI_CLOCK_CARD_EN 0x0004
#define SDHCI_CLOCK_INT_STABLE 0x0002
#define SDHCI_CLOCK_INT_EN 0x0001
@@ -140,6 +144,7 @@
#define SDHCI_TIMEOUT_CLK_SHIFT 0
#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080
#define SDHCI_CLOCK_BASE_MASK 0x00003F00
+#define SDHCI_CLOCK_V3_BASE_MASK 0x0000FF00
#define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_MAX_BLOCK_MASK 0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16
@@ -178,6 +183,7 @@
#define SDHCI_SPEC_VER_SHIFT 0
#define SDHCI_SPEC_100 0
#define SDHCI_SPEC_200 1
+#define SDHCI_SPEC_300 2
struct sdhci_ops;
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 5d3f824bb5a3..ddd09840520b 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -710,9 +710,21 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->bus_width = ios->bus_width;
}
+static int sh_mmcif_get_cd(struct mmc_host *mmc)
+{
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+ struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+
+ if (!p->get_cd)
+ return -ENOSYS;
+ else
+ return p->get_cd(host->pd);
+}
+
static struct mmc_host_ops sh_mmcif_ops = {
.request = sh_mmcif_request,
.set_ios = sh_mmcif_set_ios,
+ .get_cd = sh_mmcif_get_cd,
};
static void sh_mmcif_detect(struct mmc_host *mmc)
@@ -846,8 +858,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_MMC_HIGHSPEED;
if (pd->caps)
mmc->caps |= pd->caps;
- mmc->max_phys_segs = 128;
- mmc->max_hw_segs = 128;
+ mmc->max_segs = 128;
mmc->max_blk_size = 512;
mmc->max_blk_count = 65535;
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index cec99958b652..457c26ea09de 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -978,11 +978,10 @@ static int tifm_sd_probe(struct tifm_dev *sock)
mmc->f_max = 24000000;
mmc->max_blk_count = 2048;
- mmc->max_hw_segs = mmc->max_blk_count;
+ mmc->max_segs = mmc->max_blk_count;
mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE);
mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
mmc->max_req_size = mmc->max_seg_size;
- mmc->max_phys_segs = mmc->max_hw_segs;
sock->card_event = tifm_sd_card_event;
sock->data_event = tifm_sd_data_event;
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index ee7d0a5a51c4..e7765a89593e 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -164,6 +164,7 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
{
struct mmc_data *data = host->data;
+ void *sg_virt;
unsigned short *buf;
unsigned int count;
unsigned long flags;
@@ -173,8 +174,8 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
return;
}
- buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) +
- host->sg_off);
+ sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags);
+ buf = (unsigned short *)(sg_virt + host->sg_off);
count = host->sg_ptr->length - host->sg_off;
if (count > data->blksz)
@@ -191,7 +192,7 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
host->sg_off += count;
- tmio_mmc_kunmap_atomic(host, &flags);
+ tmio_mmc_kunmap_atomic(sg_virt, &flags);
if (host->sg_off == host->sg_ptr->length)
tmio_mmc_next_sg(host);
@@ -657,14 +658,21 @@ static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
static int tmio_mmc_start_data(struct tmio_mmc_host *host,
struct mmc_data *data)
{
+ struct mfd_cell *cell = host->pdev->dev.platform_data;
+ struct tmio_mmc_data *pdata = cell->driver_data;
+
pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
data->blksz, data->blocks);
- /* Hardware cannot perform 1 and 2 byte requests in 4 bit mode */
- if (data->blksz < 4 && host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
- pr_err("%s: %d byte block unsupported in 4 bit mode\n",
- mmc_hostname(host->mmc), data->blksz);
- return -EINVAL;
+ /* Some hardware cannot perform 2 byte requests in 4 bit mode */
+ if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
+ int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;
+
+ if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
+ pr_err("%s: %d byte block unsupported in 4 bit mode\n",
+ mmc_hostname(host->mmc), data->blksz);
+ return -EINVAL;
+ }
}
tmio_mmc_init_sg(host, data);
@@ -755,10 +763,23 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1;
}
+static int tmio_mmc_get_cd(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct mfd_cell *cell = host->pdev->dev.platform_data;
+ struct tmio_mmc_data *pdata = cell->driver_data;
+
+ if (!pdata->get_cd)
+ return -ENOSYS;
+ else
+ return pdata->get_cd(host->pdev);
+}
+
static const struct mmc_host_ops tmio_mmc_ops = {
.request = tmio_mmc_request,
.set_ios = tmio_mmc_set_ios,
.get_ro = tmio_mmc_get_ro,
+ .get_cd = tmio_mmc_get_cd,
};
#ifdef CONFIG_PM
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 64f7d5dfc106..0fedc78e3ea5 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -82,10 +82,7 @@
#define ack_mmc_irqs(host, i) \
do { \
- u32 mask;\
- mask = sd_ctrl_read32((host), CTL_STATUS); \
- mask &= ~((i) & TMIO_MASK_IRQ); \
- sd_ctrl_write32((host), CTL_STATUS, mask); \
+ sd_ctrl_write32((host), CTL_STATUS, ~(i)); \
} while (0)
@@ -177,19 +174,17 @@ static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host)
return --host->sg_len;
}
-static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host,
+static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
unsigned long *flags)
{
- struct scatterlist *sg = host->sg_ptr;
-
local_irq_save(*flags);
return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
}
-static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host,
+static inline void tmio_mmc_kunmap_atomic(void *virt,
unsigned long *flags)
{
- kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ);
+ kunmap_atomic(virt, KM_BIO_SRC_IRQ);
local_irq_restore(*flags);
}
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c
new file mode 100644
index 000000000000..b4ead4a13c98
--- /dev/null
+++ b/drivers/mmc/host/ushc.c
@@ -0,0 +1,566 @@
+/*
+ * USB SD Host Controller (USHC) controller driver.
+ *
+ * Copyright (C) 2010 Cambridge Silicon Radio 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.
+ *
+ * Notes:
+ * - Only version 2 devices are supported.
+ * - Version 2 devices only support SDIO cards/devices (R2 response is
+ * unsupported).
+ *
+ * References:
+ * [USHC] USB SD Host Controller specification (CS-118793-SP)
+ */
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+
+enum ushc_request {
+ USHC_GET_CAPS = 0x00,
+ USHC_HOST_CTRL = 0x01,
+ USHC_PWR_CTRL = 0x02,
+ USHC_CLK_FREQ = 0x03,
+ USHC_EXEC_CMD = 0x04,
+ USHC_READ_RESP = 0x05,
+ USHC_RESET = 0x06,
+};
+
+enum ushc_request_type {
+ USHC_GET_CAPS_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_HOST_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_PWR_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_CLK_FREQ_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_EXEC_CMD_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_READ_RESP_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_RESET_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+};
+
+#define USHC_GET_CAPS_VERSION_MASK 0xff
+#define USHC_GET_CAPS_3V3 (1 << 8)
+#define USHC_GET_CAPS_3V0 (1 << 9)
+#define USHC_GET_CAPS_1V8 (1 << 10)
+#define USHC_GET_CAPS_HIGH_SPD (1 << 16)
+
+#define USHC_HOST_CTRL_4BIT (1 << 1)
+#define USHC_HOST_CTRL_HIGH_SPD (1 << 0)
+
+#define USHC_PWR_CTRL_OFF 0x00
+#define USHC_PWR_CTRL_3V3 0x01
+#define USHC_PWR_CTRL_3V0 0x02
+#define USHC_PWR_CTRL_1V8 0x03
+
+#define USHC_READ_RESP_BUSY (1 << 4)
+#define USHC_READ_RESP_ERR_TIMEOUT (1 << 3)
+#define USHC_READ_RESP_ERR_CRC (1 << 2)
+#define USHC_READ_RESP_ERR_DAT (1 << 1)
+#define USHC_READ_RESP_ERR_CMD (1 << 0)
+#define USHC_READ_RESP_ERR_MASK 0x0f
+
+struct ushc_cbw {
+ __u8 signature;
+ __u8 cmd_idx;
+ __le16 block_size;
+ __le32 arg;
+} __attribute__((packed));
+
+#define USHC_CBW_SIGNATURE 'C'
+
+struct ushc_csw {
+ __u8 signature;
+ __u8 status;
+ __le32 response;
+} __attribute__((packed));
+
+#define USHC_CSW_SIGNATURE 'S'
+
+struct ushc_int_data {
+ u8 status;
+ u8 reserved[3];
+};
+
+#define USHC_INT_STATUS_SDIO_INT (1 << 1)
+#define USHC_INT_STATUS_CARD_PRESENT (1 << 0)
+
+
+struct ushc_data {
+ struct usb_device *usb_dev;
+ struct mmc_host *mmc;
+
+ struct urb *int_urb;
+ struct ushc_int_data *int_data;
+
+ struct urb *cbw_urb;
+ struct ushc_cbw *cbw;
+
+ struct urb *data_urb;
+
+ struct urb *csw_urb;
+ struct ushc_csw *csw;
+
+ spinlock_t lock;
+ struct mmc_request *current_req;
+ u32 caps;
+ u16 host_ctrl;
+ unsigned long flags;
+ u8 last_status;
+ int clock_freq;
+};
+
+#define DISCONNECTED 0
+#define INT_EN 1
+#define IGNORE_NEXT_INT 2
+
+static void data_callback(struct urb *urb);
+
+static int ushc_hw_reset(struct ushc_data *ushc)
+{
+ return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_RESET, USHC_RESET_TYPE,
+ 0, 0, NULL, 0, 100);
+}
+
+static int ushc_hw_get_caps(struct ushc_data *ushc)
+{
+ int ret;
+ int version;
+
+ ret = usb_control_msg(ushc->usb_dev, usb_rcvctrlpipe(ushc->usb_dev, 0),
+ USHC_GET_CAPS, USHC_GET_CAPS_TYPE,
+ 0, 0, &ushc->caps, sizeof(ushc->caps), 100);
+ if (ret < 0)
+ return ret;
+
+ ushc->caps = le32_to_cpu(ushc->caps);
+
+ version = ushc->caps & USHC_GET_CAPS_VERSION_MASK;
+ if (version != 0x02) {
+ dev_err(&ushc->usb_dev->dev, "controller version %d is not supported\n", version);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ushc_hw_set_host_ctrl(struct ushc_data *ushc, u16 mask, u16 val)
+{
+ u16 host_ctrl;
+ int ret;
+
+ host_ctrl = (ushc->host_ctrl & ~mask) | val;
+ ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_HOST_CTRL, USHC_HOST_CTRL_TYPE,
+ host_ctrl, 0, NULL, 0, 100);
+ if (ret < 0)
+ return ret;
+ ushc->host_ctrl = host_ctrl;
+ return 0;
+}
+
+static void int_callback(struct urb *urb)
+{
+ struct ushc_data *ushc = urb->context;
+ u8 status, last_status;
+
+ if (urb->status < 0)
+ return;
+
+ status = ushc->int_data->status;
+ last_status = ushc->last_status;
+ ushc->last_status = status;
+
+ /*
+ * Ignore the card interrupt status on interrupt transfers that
+ * were submitted while card interrupts where disabled.
+ *
+ * This avoid occasional spurious interrupts when enabling
+ * interrupts immediately after clearing the source on the card.
+ */
+
+ if (!test_and_clear_bit(IGNORE_NEXT_INT, &ushc->flags)
+ && test_bit(INT_EN, &ushc->flags)
+ && status & USHC_INT_STATUS_SDIO_INT) {
+ mmc_signal_sdio_irq(ushc->mmc);
+ }
+
+ if ((status ^ last_status) & USHC_INT_STATUS_CARD_PRESENT)
+ mmc_detect_change(ushc->mmc, msecs_to_jiffies(100));
+
+ if (!test_bit(INT_EN, &ushc->flags))
+ set_bit(IGNORE_NEXT_INT, &ushc->flags);
+ usb_submit_urb(ushc->int_urb, GFP_ATOMIC);
+}
+
+static void cbw_callback(struct urb *urb)
+{
+ struct ushc_data *ushc = urb->context;
+
+ if (urb->status != 0) {
+ usb_unlink_urb(ushc->data_urb);
+ usb_unlink_urb(ushc->csw_urb);
+ }
+}
+
+static void data_callback(struct urb *urb)
+{
+ struct ushc_data *ushc = urb->context;
+
+ if (urb->status != 0)
+ usb_unlink_urb(ushc->csw_urb);
+}
+
+static void csw_callback(struct urb *urb)
+{
+ struct ushc_data *ushc = urb->context;
+ struct mmc_request *req = ushc->current_req;
+ int status;
+
+ status = ushc->csw->status;
+
+ if (urb->status != 0) {
+ req->cmd->error = urb->status;
+ } else if (status & USHC_READ_RESP_ERR_CMD) {
+ if (status & USHC_READ_RESP_ERR_CRC)
+ req->cmd->error = -EIO;
+ else
+ req->cmd->error = -ETIMEDOUT;
+ }
+ if (req->data) {
+ if (status & USHC_READ_RESP_ERR_DAT) {
+ if (status & USHC_READ_RESP_ERR_CRC)
+ req->data->error = -EIO;
+ else
+ req->data->error = -ETIMEDOUT;
+ req->data->bytes_xfered = 0;
+ } else {
+ req->data->bytes_xfered = req->data->blksz * req->data->blocks;
+ }
+ }
+
+ req->cmd->resp[0] = le32_to_cpu(ushc->csw->response);
+
+ mmc_request_done(ushc->mmc, req);
+}
+
+static void ushc_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct ushc_data *ushc = mmc_priv(mmc);
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ushc->lock, flags);
+
+ if (test_bit(DISCONNECTED, &ushc->flags)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Version 2 firmware doesn't support the R2 response format. */
+ if (req->cmd->flags & MMC_RSP_136) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* The Astoria's data FIFOs don't work with clock speeds < 5MHz so
+ limit commands with data to 6MHz or more. */
+ if (req->data && ushc->clock_freq < 6000000) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ushc->current_req = req;
+
+ /* Start cmd with CBW. */
+ ushc->cbw->cmd_idx = cpu_to_le16(req->cmd->opcode);
+ if (req->data)
+ ushc->cbw->block_size = cpu_to_le16(req->data->blksz);
+ else
+ ushc->cbw->block_size = 0;
+ ushc->cbw->arg = cpu_to_le32(req->cmd->arg);
+
+ ret = usb_submit_urb(ushc->cbw_urb, GFP_ATOMIC);
+ if (ret < 0)
+ goto out;
+
+ /* Submit data (if any). */
+ if (req->data) {
+ struct mmc_data *data = req->data;
+ int pipe;
+
+ if (data->flags & MMC_DATA_READ)
+ pipe = usb_rcvbulkpipe(ushc->usb_dev, 6);
+ else
+ pipe = usb_sndbulkpipe(ushc->usb_dev, 2);
+
+ usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe,
+ sg_virt(data->sg), data->sg->length,
+ data_callback, ushc);
+ ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC);
+ if (ret < 0)
+ goto out;
+ }
+
+ /* Submit CSW. */
+ ret = usb_submit_urb(ushc->csw_urb, GFP_ATOMIC);
+ if (ret < 0)
+ goto out;
+
+out:
+ spin_unlock_irqrestore(&ushc->lock, flags);
+ if (ret < 0) {
+ usb_unlink_urb(ushc->cbw_urb);
+ usb_unlink_urb(ushc->data_urb);
+ req->cmd->error = ret;
+ mmc_request_done(mmc, req);
+ }
+}
+
+static int ushc_set_power(struct ushc_data *ushc, unsigned char power_mode)
+{
+ u16 voltage;
+
+ switch (power_mode) {
+ case MMC_POWER_OFF:
+ voltage = USHC_PWR_CTRL_OFF;
+ break;
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ voltage = USHC_PWR_CTRL_3V3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_PWR_CTRL, USHC_PWR_CTRL_TYPE,
+ voltage, 0, NULL, 0, 100);
+}
+
+static int ushc_set_bus_width(struct ushc_data *ushc, int bus_width)
+{
+ return ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_4BIT,
+ bus_width == 4 ? USHC_HOST_CTRL_4BIT : 0);
+}
+
+static int ushc_set_bus_freq(struct ushc_data *ushc, int clk, bool enable_hs)
+{
+ int ret;
+
+ /* Hardware can't detect interrupts while the clock is off. */
+ if (clk == 0)
+ clk = 400000;
+
+ ret = ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_HIGH_SPD,
+ enable_hs ? USHC_HOST_CTRL_HIGH_SPD : 0);
+ if (ret < 0)
+ return ret;
+
+ ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_CLK_FREQ, USHC_CLK_FREQ_TYPE,
+ clk & 0xffff, (clk >> 16) & 0xffff, NULL, 0, 100);
+ if (ret < 0)
+ return ret;
+
+ ushc->clock_freq = clk;
+ return 0;
+}
+
+static void ushc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct ushc_data *ushc = mmc_priv(mmc);
+
+ ushc_set_power(ushc, ios->power_mode);
+ ushc_set_bus_width(ushc, 1 << ios->bus_width);
+ ushc_set_bus_freq(ushc, ios->clock, ios->timing == MMC_TIMING_SD_HS);
+}
+
+static int ushc_get_cd(struct mmc_host *mmc)
+{
+ struct ushc_data *ushc = mmc_priv(mmc);
+
+ return !!(ushc->last_status & USHC_INT_STATUS_CARD_PRESENT);
+}
+
+static void ushc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct ushc_data *ushc = mmc_priv(mmc);
+
+ if (enable)
+ set_bit(INT_EN, &ushc->flags);
+ else
+ clear_bit(INT_EN, &ushc->flags);
+}
+
+static void ushc_clean_up(struct ushc_data *ushc)
+{
+ usb_free_urb(ushc->int_urb);
+ usb_free_urb(ushc->csw_urb);
+ usb_free_urb(ushc->data_urb);
+ usb_free_urb(ushc->cbw_urb);
+
+ kfree(ushc->int_data);
+ kfree(ushc->cbw);
+ kfree(ushc->csw);
+
+ mmc_free_host(ushc->mmc);
+}
+
+static const struct mmc_host_ops ushc_ops = {
+ .request = ushc_request,
+ .set_ios = ushc_set_ios,
+ .get_cd = ushc_get_cd,
+ .enable_sdio_irq = ushc_enable_sdio_irq,
+};
+
+static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct mmc_host *mmc;
+ struct ushc_data *ushc;
+ int ret = -ENOMEM;
+
+ mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
+ if (mmc == NULL)
+ return -ENOMEM;
+ ushc = mmc_priv(mmc);
+ usb_set_intfdata(intf, ushc);
+
+ ushc->usb_dev = usb_dev;
+ ushc->mmc = mmc;
+
+ spin_lock_init(&ushc->lock);
+
+ ret = ushc_hw_reset(ushc);
+ if (ret < 0)
+ goto err;
+
+ /* Read capabilities. */
+ ret = ushc_hw_get_caps(ushc);
+ if (ret < 0)
+ goto err;
+
+ mmc->ops = &ushc_ops;
+
+ mmc->f_min = 400000;
+ mmc->f_max = 50000000;
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+ mmc->caps |= (ushc->caps & USHC_GET_CAPS_HIGH_SPD) ? MMC_CAP_SD_HIGHSPEED : 0;
+
+ mmc->max_seg_size = 512*511;
+ mmc->max_segs = 1;
+ mmc->max_req_size = 512*511;
+ mmc->max_blk_size = 512;
+ mmc->max_blk_count = 511;
+
+ ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->int_urb == NULL)
+ goto err;
+ ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
+ if (ushc->int_data == NULL)
+ goto err;
+ usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
+ usb_rcvintpipe(usb_dev,
+ intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
+ ushc->int_data, sizeof(struct ushc_int_data),
+ int_callback, ushc,
+ intf->cur_altsetting->endpoint[0].desc.bInterval);
+
+ ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->cbw_urb == NULL)
+ goto err;
+ ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
+ if (ushc->cbw == NULL)
+ goto err;
+ ushc->cbw->signature = USHC_CBW_SIGNATURE;
+
+ usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),
+ ushc->cbw, sizeof(struct ushc_cbw),
+ cbw_callback, ushc);
+
+ ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->data_urb == NULL)
+ goto err;
+
+ ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->csw_urb == NULL)
+ goto err;
+ ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
+ if (ushc->csw == NULL)
+ goto err;
+ usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
+ ushc->csw, sizeof(struct ushc_csw),
+ csw_callback, ushc);
+
+ ret = mmc_add_host(ushc->mmc);
+ if (ret)
+ goto err;
+
+ ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL);
+ if (ret < 0) {
+ mmc_remove_host(ushc->mmc);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ ushc_clean_up(ushc);
+ return ret;
+}
+
+static void ushc_disconnect(struct usb_interface *intf)
+{
+ struct ushc_data *ushc = usb_get_intfdata(intf);
+
+ spin_lock_irq(&ushc->lock);
+ set_bit(DISCONNECTED, &ushc->flags);
+ spin_unlock_irq(&ushc->lock);
+
+ usb_kill_urb(ushc->int_urb);
+ usb_kill_urb(ushc->cbw_urb);
+ usb_kill_urb(ushc->data_urb);
+ usb_kill_urb(ushc->csw_urb);
+
+ mmc_remove_host(ushc->mmc);
+
+ ushc_clean_up(ushc);
+}
+
+static struct usb_device_id ushc_id_table[] = {
+ /* CSR USB SD Host Controller */
+ { USB_DEVICE(0x0a12, 0x5d10) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, ushc_id_table);
+
+static struct usb_driver ushc_driver = {
+ .name = "ushc",
+ .id_table = ushc_id_table,
+ .probe = ushc_probe,
+ .disconnect = ushc_disconnect,
+};
+
+static int __init ushc_init(void)
+{
+ return usb_register(&ushc_driver);
+}
+module_init(ushc_init);
+
+static void __exit ushc_exit(void)
+{
+ usb_deregister(&ushc_driver);
+}
+module_exit(ushc_exit);
+
+MODULE_DESCRIPTION("USB SD Host Controller driver");
+MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 19f2d72dbca5..9ed84ddb4780 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1050,8 +1050,7 @@ static void via_init_mmc_host(struct via_crdr_mmc_host *host)
mmc->ops = &via_sdc_ops;
/*Hardware cannot do scatter lists*/
- mmc->max_hw_segs = 1;
- mmc->max_phys_segs = 1;
+ mmc->max_segs = 1;
mmc->max_blk_size = VIA_CRDR_MAX_BLOCK_LENGTH;
mmc->max_blk_count = VIA_CRDR_MAX_BLOCK_COUNT;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 0012f5d13d28..7fca0a386ba0 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1235,8 +1235,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
* Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512.
*/
- mmc->max_hw_segs = 128;
- mmc->max_phys_segs = 128;
+ mmc->max_segs = 128;
/*
* Maximum request size. Also limited by 64KiB buffer.
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 62e68707b07f..50ab431b24eb 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -29,7 +29,6 @@
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/hdreg.h>
#include <linux/init.h>
#include <linux/mutex.h>
@@ -38,6 +37,7 @@
#include "mtdcore.h"
+static DEFINE_MUTEX(mtd_blkdevs_mutex);
static LIST_HEAD(blktrans_majors);
static DEFINE_MUTEX(blktrans_ref_mutex);
@@ -181,7 +181,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
if (!dev)
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
- lock_kernel();
+ mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (!dev->mtd) {
@@ -198,7 +198,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
- unlock_kernel();
+ mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
@@ -210,7 +210,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
if (!dev)
return ret;
- lock_kernel();
+ mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
/* Release one reference, we sure its not the last one here*/
@@ -223,7 +223,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
- unlock_kernel();
+ mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
@@ -256,7 +256,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
if (!dev)
return ret;
- lock_kernel();
+ mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (!dev->mtd)
@@ -271,7 +271,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
}
unlock:
mutex_unlock(&dev->lock);
- unlock_kernel();
+ mutex_unlock(&mtd_blkdevs_mutex);
blktrans_dev_put(dev);
return ret;
}
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a825002123c8..5ef45487b65f 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -26,7 +26,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/backing-dev.h>
#include <linux/compat.h>
#include <linux/mount.h>
@@ -37,6 +37,7 @@
#include <asm/uaccess.h>
#define MTD_INODE_FS_MAGIC 0x11307854
+static DEFINE_MUTEX(mtd_mutex);
static struct vfsmount *mtd_inode_mnt __read_mostly;
/*
@@ -90,7 +91,7 @@ static int mtd_open(struct inode *inode, struct file *file)
if ((file->f_mode & FMODE_WRITE) && (minor & 1))
return -EACCES;
- lock_kernel();
+ mutex_lock(&mtd_mutex);
mtd = get_mtd_device(NULL, devnum);
if (IS_ERR(mtd)) {
@@ -138,7 +139,7 @@ static int mtd_open(struct inode *inode, struct file *file)
file->private_data = mfi;
out:
- unlock_kernel();
+ mutex_unlock(&mtd_mutex);
return ret;
} /* mtd_open */
@@ -866,9 +867,9 @@ static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&mtd_mutex);
ret = mtd_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&mtd_mutex);
return ret;
}
@@ -892,7 +893,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
void __user *argp = compat_ptr(arg);
int ret = 0;
- lock_kernel();
+ mutex_lock(&mtd_mutex);
switch (cmd) {
case MEMWRITEOOB32:
@@ -927,7 +928,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
ret = mtd_ioctl(file, cmd, (unsigned long)argp);
}
- unlock_kernel();
+ mutex_unlock(&mtd_mutex);
return ret;
}
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index a382e3dd0a5d..6fbeefa3a766 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -682,7 +682,6 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
{
struct bf5xx_nand_info *info = to_nand_info(pdev);
- struct mtd_info *mtd = NULL;
platform_set_drvdata(pdev, NULL);
@@ -690,11 +689,7 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
* and their partitions, then go through freeing the
* resources used
*/
- mtd = &info->mtd;
- if (mtd) {
- nand_release(mtd);
- kfree(mtd);
- }
+ nand_release(&info->mtd);
peripheral_free_list(bfin_nfc_pin_req);
bf5xx_nand_dma_remove(info);
@@ -710,7 +705,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd)
struct nand_chip *chip = mtd->priv;
int ret;
- ret = nand_scan_ident(mtd, 1);
+ ret = nand_scan_ident(mtd, 1, NULL);
if (ret)
return ret;
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 2ac7367afe77..8beb0d0233b5 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <mach/nand.h>
+#include <mach/aemif.h>
#include <asm/mach-types.h>
@@ -74,6 +75,8 @@ struct davinci_nand_info {
uint32_t mask_cle;
uint32_t core_chipsel;
+
+ struct davinci_aemif_timing *timing;
};
static DEFINE_SPINLOCK(davinci_nand_lock);
@@ -478,36 +481,6 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd)
return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
}
-static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
-{
- uint32_t regval, a1cr;
-
- /*
- * NAND FLASH timings @ PLL1 == 459 MHz
- * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
- * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
- */
- regval = 0
- | (0 << 31) /* selectStrobe */
- | (0 << 30) /* extWait (never with NAND) */
- | (1 << 26) /* writeSetup 10 ns */
- | (3 << 20) /* writeStrobe 40 ns */
- | (1 << 17) /* writeHold 10 ns */
- | (0 << 13) /* readSetup 10 ns */
- | (3 << 7) /* readStrobe 60 ns */
- | (0 << 4) /* readHold 10 ns */
- | (3 << 2) /* turnAround ?? ns */
- | (0 << 0) /* asyncSize 8-bit bus */
- ;
- a1cr = davinci_nand_readl(info, A1CR_OFFSET);
- if (a1cr != regval) {
- dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
- "reg to 0x%08x, was 0x%08x, should be done by " \
- "bootloader.\n", regval, a1cr);
- davinci_nand_writel(info, A1CR_OFFSET, regval);
- }
-}
-
/*----------------------------------------------------------------------*/
/* An ECC layout for using 4-bit ECC with small-page flash, storing
@@ -611,6 +584,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
info->chip.options = pdata->options;
info->chip.bbt_td = pdata->bbt_td;
info->chip.bbt_md = pdata->bbt_md;
+ info->timing = pdata->timing;
info->ioaddr = (uint32_t __force) vaddr;
@@ -688,15 +662,25 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
goto err_clk_enable;
}
- /* EMIF timings should normally be set by the boot loader,
- * especially after boot-from-NAND. The *only* reason to
- * have this special casing for the DM6446 EVM is to work
- * with boot-from-NOR ... with CS0 manually re-jumpered
- * (after startup) so it addresses the NAND flash, not NOR.
- * Even for dev boards, that's unusually rude...
+ /*
+ * Setup Async configuration register in case we did not boot from
+ * NAND and so bootloader did not bother to set it up.
*/
- if (machine_is_davinci_evm())
- nand_dm6446evm_flash_init(info);
+ val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4);
+
+ /* Extended Wait is not valid and Select Strobe mode is not used */
+ val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK);
+ if (info->chip.options & NAND_BUSWIDTH_16)
+ val |= 0x1;
+
+ davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val);
+
+ ret = davinci_aemif_setup_timing(info->timing, info->base,
+ info->core_chipsel);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
+ goto err_timing;
+ }
spin_lock_irq(&davinci_nand_lock);
@@ -809,6 +793,7 @@ syndrome_done:
return 0;
err_scan:
+err_timing:
clk_disable(info->clk);
err_clk_enable:
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index fcf8ceb277d4..b2828e84d243 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -67,7 +67,9 @@
#define NFC_V1_V2_CONFIG1_BIG (1 << 5)
#define NFC_V1_V2_CONFIG1_RST (1 << 6)
#define NFC_V1_V2_CONFIG1_CE (1 << 7)
-#define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8)
+#define NFC_V2_CONFIG1_ONE_CYCLE (1 << 8)
+#define NFC_V2_CONFIG1_PPB(x) (((x) & 0x3) << 9)
+#define NFC_V2_CONFIG1_FP_INT (1 << 11)
#define NFC_V1_V2_CONFIG2_INT (1 << 15)
@@ -402,16 +404,16 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
/* Wait for operation to complete */
wait_op_done(host, true);
+ memcpy(host->data_buf, host->main_area0, 16);
+
if (this->options & NAND_BUSWIDTH_16) {
- void __iomem *main_buf = host->main_area0;
/* compress the ID info */
- writeb(readb(main_buf + 2), main_buf + 1);
- writeb(readb(main_buf + 4), main_buf + 2);
- writeb(readb(main_buf + 6), main_buf + 3);
- writeb(readb(main_buf + 8), main_buf + 4);
- writeb(readb(main_buf + 10), main_buf + 5);
+ host->data_buf[1] = host->data_buf[2];
+ host->data_buf[2] = host->data_buf[4];
+ host->data_buf[3] = host->data_buf[6];
+ host->data_buf[4] = host->data_buf[8];
+ host->data_buf[5] = host->data_buf[10];
}
- memcpy(host->data_buf, host->main_area0, 16);
}
static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
@@ -729,27 +731,30 @@ static void preset_v1_v2(struct mtd_info *mtd)
{
struct nand_chip *nand_chip = mtd->priv;
struct mxc_nand_host *host = nand_chip->priv;
- uint16_t tmp;
-
- /* enable interrupt, disable spare enable */
- tmp = readw(NFC_V1_V2_CONFIG1);
- tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
- tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
- if (nand_chip->ecc.mode == NAND_ECC_HW) {
- tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
- } else {
- tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
- }
+ uint16_t config1 = 0;
+
+ if (nand_chip->ecc.mode == NAND_ECC_HW)
+ config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+
+ if (nfc_is_v21())
+ config1 |= NFC_V2_CONFIG1_FP_INT;
+
+ if (!cpu_is_mx21())
+ config1 |= NFC_V1_V2_CONFIG1_INT_MSK;
if (nfc_is_v21() && mtd->writesize) {
+ uint16_t pages_per_block = mtd->erasesize / mtd->writesize;
+
host->eccsize = get_eccsize(mtd);
if (host->eccsize == 4)
- tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
+ config1 |= NFC_V2_CONFIG1_ECC_MODE_4;
+
+ config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6);
} else {
host->eccsize = 1;
}
- writew(tmp, NFC_V1_V2_CONFIG1);
+ writew(config1, NFC_V1_V2_CONFIG1);
/* preset operation */
/* Unlock the internal RAM Buffer */
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 4d89f3780207..4d01cda68844 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1320,6 +1320,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
goto fail_free_irq;
}
+#ifdef CONFIG_MTD_PARTITIONS
if (mtd_has_cmdlinepart()) {
static const char *probes[] = { "cmdlinepart", NULL };
struct mtd_partition *parts;
@@ -1332,6 +1333,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
}
return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
+#else
+ return 0;
+#endif
fail_free_irq:
free_irq(irq, info);
@@ -1364,7 +1368,9 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
del_mtd_device(mtd);
+#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(mtd);
+#endif
irq = platform_get_irq(pdev, 0);
if (irq >= 0)
free_irq(irq, info);
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index cb443af3d45f..a460f1b748c2 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -554,14 +554,13 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
do {
status = readl(base + S5PC110_DMA_TRANS_STATUS);
+ if (status & S5PC110_DMA_TRANS_STATUS_TE) {
+ writel(S5PC110_DMA_TRANS_CMD_TEC,
+ base + S5PC110_DMA_TRANS_CMD);
+ return -EIO;
+ }
} while (!(status & S5PC110_DMA_TRANS_STATUS_TD));
- if (status & S5PC110_DMA_TRANS_STATUS_TE) {
- writel(S5PC110_DMA_TRANS_CMD_TEC, base + S5PC110_DMA_TRANS_CMD);
- writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
- return -EIO;
- }
-
writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
return 0;
@@ -571,13 +570,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
unsigned char *buffer, int offset, size_t count)
{
struct onenand_chip *this = mtd->priv;
- void __iomem *bufferram;
void __iomem *p;
void *buf = (void *) buffer;
dma_addr_t dma_src, dma_dst;
int err;
- p = bufferram = this->base + area;
+ p = this->base + area;
if (ONENAND_CURRENT_BUFFERRAM(this)) {
if (area == ONENAND_DATARAM)
p += this->writesize;
@@ -621,7 +619,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
normal:
if (count != mtd->writesize) {
/* Copy the bufferram to memory to prevent unaligned access */
- memcpy(this->page_buf, bufferram, mtd->writesize);
+ memcpy(this->page_buf, p, mtd->writesize);
p = this->page_buf + offset;
}
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug
index 2246f154e2f7..61f6e5e40458 100644
--- a/drivers/mtd/ubi/Kconfig.debug
+++ b/drivers/mtd/ubi/Kconfig.debug
@@ -6,7 +6,7 @@ config MTD_UBI_DEBUG
depends on SYSFS
depends on MTD_UBI
select DEBUG_FS
- select KALLSYMS_ALL
+ select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL
help
This option enables UBI debugging.
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 4dfa6b90c21c..0cbd4ed7c799 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -798,18 +798,18 @@ static int rename_volumes(struct ubi_device *ubi,
goto out_free;
}
- re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
- if (!re) {
+ re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL);
+ if (!re1) {
err = -ENOMEM;
ubi_close_volume(desc);
goto out_free;
}
- re->remove = 1;
- re->desc = desc;
- list_add(&re->list, &rename_list);
+ re1->remove = 1;
+ re1->desc = desc;
+ list_add(&re1->list, &rename_list);
dbg_msg("will remove volume %d, name \"%s\"",
- re->desc->vol->vol_id, re->desc->vol->name);
+ re1->desc->vol->vol_id, re1->desc->vol->name);
}
mutex_lock(&ubi->device_mutex);
@@ -1100,4 +1100,5 @@ const struct file_operations ubi_ctrl_cdev_operations = {
.owner = THIS_MODULE,
.unlocked_ioctl = ctrl_cdev_ioctl,
.compat_ioctl = ctrl_cdev_compat_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 372a15ac9995..69b52e9c9489 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -843,7 +843,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
case UBI_COMPAT_DELETE:
ubi_msg("\"delete\" compatible internal volume %d:%d"
" found, will remove it", vol_id, lnum);
- err = add_to_list(si, pnum, ec, &si->corr);
+ err = add_to_list(si, pnum, ec, &si->erase);
if (err)
return err;
return 0;
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index ee7b1d8fbb92..97a435672eaf 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1212,7 +1212,8 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum)
retry:
spin_lock(&ubi->wl_lock);
e = ubi->lookuptbl[pnum];
- if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub)) {
+ if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub) ||
+ in_wl_tree(e, &ubi->erroneous)) {
spin_unlock(&ubi->wl_lock);
return 0;
}
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index baac246561b9..4777a1cbcd8d 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -337,10 +337,10 @@ el2_probe1(struct net_device *dev, int ioaddr)
/* Finish setting the board's parameters. */
ei_status.stop_page = EL2_MB1_STOP_PG;
ei_status.word16 = wordlength;
- ei_status.reset_8390 = &el2_reset_8390;
- ei_status.get_8390_hdr = &el2_get_8390_hdr;
- ei_status.block_input = &el2_block_input;
- ei_status.block_output = &el2_block_output;
+ ei_status.reset_8390 = el2_reset_8390;
+ ei_status.get_8390_hdr = el2_get_8390_hdr;
+ ei_status.block_input = el2_block_input;
+ ei_status.block_output = el2_block_output;
if (dev->irq == 2)
dev->irq = 9;
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 3bba835f1a21..8a6eb0c44486 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -734,7 +734,7 @@ static int corkscrew_open(struct net_device *dev)
init_timer(&vp->timer);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
vp->timer.data = (unsigned long) dev;
- vp->timer.function = &corkscrew_timer; /* timer handler */
+ vp->timer.function = corkscrew_timer; /* timer handler */
add_timer(&vp->timer);
} else
dev->if_port = vp->default_media;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index c685a55fc2f4..e31a6d1919c6 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -647,7 +647,7 @@ struct vortex_private {
u16 io_size; /* Size of PCI region (for release_region) */
/* Serialises access to hardware other than MII and variables below.
- * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */
+ * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */
spinlock_t lock;
spinlock_t mii_lock; /* Serialises access to MII */
@@ -1739,7 +1739,7 @@ vortex_open(struct net_device *dev)
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
- &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
+ boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
goto err;
}
@@ -1994,10 +1994,9 @@ vortex_error(struct net_device *dev, int status)
}
}
- if (status & RxEarly) { /* Rx early is unused. */
- vortex_rx(dev);
+ if (status & RxEarly) /* Rx early is unused. */
iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
- }
+
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
if (vortex_debug > 4)
@@ -2298,7 +2297,12 @@ vortex_interrupt(int irq, void *dev_id)
if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
if (status == 0xffff)
break;
+ if (status & RxEarly)
+ vortex_rx(dev);
+ spin_unlock(&vp->window_lock);
vortex_error(dev, status);
+ spin_lock(&vp->window_lock);
+ window_set(vp, 7);
}
if (--work_done < 0) {
@@ -2984,7 +2988,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
int err;
struct vortex_private *vp = netdev_priv(dev);
- unsigned long flags;
pci_power_t state = 0;
if(VORTEX_PCI(vp))
@@ -2994,9 +2997,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if(state != 0)
pci_set_power_state(VORTEX_PCI(vp), PCI_D0);
- spin_lock_irqsave(&vp->lock, flags);
err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL);
- spin_unlock_irqrestore(&vp->lock, flags);
if(state != 0)
pci_set_power_state(VORTEX_PCI(vp), state);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 4a4f6b81e32d..237d4ea5a416 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -561,7 +561,7 @@ rx_status_loop:
if (cp_rx_csum_ok(status))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_put(skb, len);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2cc81a54cbf3..d8d472b965e0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -951,6 +951,8 @@ config NET_NETX
config TI_DAVINCI_EMAC
tristate "TI DaVinci EMAC Support"
depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+ select TI_DAVINCI_MDIO
+ select TI_DAVINCI_CPDMA
select PHYLIB
help
This driver supports TI's DaVinci Ethernet .
@@ -958,6 +960,25 @@ config TI_DAVINCI_EMAC
To compile this driver as a module, choose M here: the module
will be called davinci_emac_driver. This is recommended.
+config TI_DAVINCI_MDIO
+ tristate "TI DaVinci MDIO Support"
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+ select PHYLIB
+ help
+ This driver supports TI's DaVinci MDIO module.
+
+ To compile this driver as a module, choose M here: the module
+ will be called davinci_mdio. This is recommended.
+
+config TI_DAVINCI_CPDMA
+ tristate "TI DaVinci CPDMA Support"
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
+ help
+ This driver supports TI's DaVinci CPDMA dma engine.
+
+ To compile this driver as a module, choose M here: the module
+ will be called davinci_cpdma. This is recommended.
+
config DM9000
tristate "DM9000 support"
depends on ARM || BLACKFIN || MIPS
@@ -2869,6 +2890,20 @@ config QLGE
To compile this driver as a module, choose M here: the module
will be called qlge.
+config BNA
+ tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
+ depends on PCI
+ ---help---
+ This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
+ cards.
+ To compile this driver as a module, choose M here: the module
+ will be called bna.
+
+ For general information and support, go to the Brocade support
+ website at:
+
+ <http://support.brocade.com>
+
source "drivers/net/sfc/Kconfig"
source "drivers/net/benet/Kconfig"
@@ -3202,6 +3237,17 @@ config PPPOE
which contains instruction on how to use this driver (under
the heading "Kernel mode PPPoE").
+config PPTP
+ tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX
+ help
+ Support for PPP over IPv4.(Point-to-Point Tunneling Protocol)
+
+ This driver requires pppd plugin to work in client mode or
+ modified pptpd (poptop) to work in server mode.
+ See http://accel-pptp.sourceforge.net/ for information how to
+ utilize this module.
+
config PPPOATM
tristate "PPP over ATM"
depends on ATM && PPP
@@ -3346,4 +3392,18 @@ config VMXNET3
To compile this driver as a module, choose M here: the
module will be called vmxnet3.
+config VBUS_ENET
+ tristate "VBUS Ethernet Driver"
+ default n
+ depends on VBUS_PROXY
+ help
+ A virtualized 802.x network device based on the VBUS
+ "virtual-ethernet" interface. It can be used with any
+ hypervisor/kernel that supports the vbus+venet protocol.
+
+config VBUS_ENET_DEBUG
+ bool "Enable Debugging"
+ depends on VBUS_ENET
+ default n
+
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3e8f150c4b14..9ea91109a856 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
+obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
+obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
@@ -34,6 +36,7 @@ obj-$(CONFIG_ENIC) += enic/
obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_BE2NET) += benet/
obj-$(CONFIG_VMXNET3) += vmxnet3/
+obj-$(CONFIG_BNA) += bna/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
@@ -162,6 +165,7 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_PPPOL2TP) += pppox.o
+obj-$(CONFIG_PPTP) += pppox.o pptp.o
obj-$(CONFIG_SLIP) += slip.o
obj-$(CONFIG_SLHC) += slhc.o
@@ -290,6 +294,7 @@ obj-$(CONFIG_FS_ENET) += fs_enet/
obj-$(CONFIG_NETXEN_NIC) += netxen/
obj-$(CONFIG_NIU) += niu.o
obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
+obj-$(CONFIG_VBUS_ENET) += vbus-enet.o
obj-$(CONFIG_SFC) += sfc/
obj-$(CONFIG_WIMAX) += wimax/
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b9a591604e5b..41d9911202d0 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2033,7 +2033,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb->csum = htons(csum);
skb->ip_summed = CHECKSUM_COMPLETE;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
/* send it up */
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 585c25f4b60c..58a0ab4923ee 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -396,7 +396,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->rx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
writel(VAL0|STINTEN, mmio+INTEN0);
@@ -409,7 +409,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->tx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
@@ -903,18 +903,18 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER)
}
/*
-This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values.
-*/
-static struct net_device_stats *amd8111e_get_stats(struct net_device * dev)
+ * This function reads the mib registers and returns the hardware statistics.
+ * It updates previous internal driver statistics with new values.
+ */
+static struct net_device_stats *amd8111e_get_stats(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio;
unsigned long flags;
- /* struct net_device_stats *prev_stats = &lp->prev_stats; */
- struct net_device_stats* new_stats = &lp->stats;
+ struct net_device_stats *new_stats = &dev->stats;
- if(!lp->opened)
- return &lp->stats;
+ if (!lp->opened)
+ return new_stats;
spin_lock_irqsave (&lp->lock, flags);
/* stats.rx_packets */
diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
index ac36eb6981e3..b5926af03a7e 100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/amd8111e.h
@@ -787,7 +787,6 @@ struct amd8111e_priv{
struct vlan_group *vlgrp;
#endif
char opened;
- struct net_device_stats stats;
unsigned int drv_rx_errors;
struct amd8111e_coalesce_conf coal_conf;
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 8c496fb1ac9e..62f21106efec 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -300,8 +300,6 @@ am79c961_open(struct net_device *dev)
struct dev_priv *priv = netdev_priv(dev);
int ret;
- memset (&priv->stats, 0, sizeof (priv->stats));
-
ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
if (ret)
return ret;
@@ -347,8 +345,7 @@ am79c961_close(struct net_device *dev)
*/
static struct net_device_stats *am79c961_getstats (struct net_device *dev)
{
- struct dev_priv *priv = netdev_priv(dev);
- return &priv->stats;
+ return &dev->stats;
}
static void am79c961_mc_hash(char *addr, unsigned short *hash)
@@ -510,14 +507,14 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
am_writeword (dev, hdraddr + 2, RMD_OWN);
- priv->stats.rx_errors ++;
+ dev->stats.rx_errors++;
if (status & RMD_ERR) {
if (status & RMD_FRAM)
- priv->stats.rx_frame_errors ++;
+ dev->stats.rx_frame_errors++;
if (status & RMD_CRC)
- priv->stats.rx_crc_errors ++;
+ dev->stats.rx_crc_errors++;
} else if (status & RMD_STP)
- priv->stats.rx_length_errors ++;
+ dev->stats.rx_length_errors++;
continue;
}
@@ -531,12 +528,12 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
am_writeword(dev, hdraddr + 2, RMD_OWN);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- priv->stats.rx_bytes += len;
- priv->stats.rx_packets ++;
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
} else {
am_writeword (dev, hdraddr + 2, RMD_OWN);
printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
break;
}
} while (1);
@@ -565,7 +562,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
if (status & TMD_ERR) {
u_int status2;
- priv->stats.tx_errors ++;
+ dev->stats.tx_errors++;
status2 = am_readword (dev, hdraddr + 6);
@@ -575,18 +572,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
am_writeword (dev, hdraddr + 6, 0);
if (status2 & TST_RTRY)
- priv->stats.collisions += 16;
+ dev->stats.collisions += 16;
if (status2 & TST_LCOL)
- priv->stats.tx_window_errors ++;
+ dev->stats.tx_window_errors++;
if (status2 & TST_LCAR)
- priv->stats.tx_carrier_errors ++;
+ dev->stats.tx_carrier_errors++;
if (status2 & TST_UFLO)
- priv->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
continue;
}
- priv->stats.tx_packets ++;
+ dev->stats.tx_packets++;
len = am_readword (dev, hdraddr + 4);
- priv->stats.tx_bytes += -len;
+ dev->stats.tx_bytes += -len;
} while (priv->txtail != priv->txhead);
netif_wake_queue(dev);
@@ -616,7 +613,7 @@ am79c961_interrupt(int irq, void *dev_id)
}
if (status & CSR0_MISS) {
handled = 1;
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
}
if (status & CSR0_CERR) {
handled = 1;
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
index 483009fe6ec2..fd634d32756b 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/arm/am79c961a.h
@@ -130,7 +130,6 @@
#define ISALED0_LNKST 0x8000
struct dev_priv {
- struct net_device_stats stats;
unsigned long rxbuffer[RX_BUFFERS];
unsigned long txbuffer[TX_BUFFERS];
unsigned char txhead;
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 4a5ec9470aa1..5a77001b6d10 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -175,8 +175,6 @@ struct ep93xx_priv
struct net_device *dev;
struct napi_struct napi;
- struct net_device_stats stats;
-
struct mii_if_info mii;
u8 mdc_divisor;
};
@@ -230,12 +228,6 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d
pr_info("mdio write timed out\n");
}
-static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
-{
- struct ep93xx_priv *ep = netdev_priv(dev);
- return &(ep->stats);
-}
-
static int ep93xx_rx(struct net_device *dev, int processed, int budget)
{
struct ep93xx_priv *ep = netdev_priv(dev);
@@ -267,15 +259,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1);
if (!(rstat0 & RSTAT0_RWE)) {
- ep->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (rstat0 & RSTAT0_OE)
- ep->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
if (rstat0 & RSTAT0_FE)
- ep->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA))
- ep->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (rstat0 & RSTAT0_CRCE)
- ep->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
goto err;
}
@@ -300,10 +292,10 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
netif_receive_skb(skb);
- ep->stats.rx_packets++;
- ep->stats.rx_bytes += length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
} else {
- ep->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
err:
@@ -359,7 +351,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
int entry;
if (unlikely(skb->len > MAX_PKT_SIZE)) {
- ep->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -415,17 +407,17 @@ static void ep93xx_tx_complete(struct net_device *dev)
if (tstat0 & TSTAT0_TXWE) {
int length = ep->descs->tdesc[entry].tdesc1 & 0xfff;
- ep->stats.tx_packets++;
- ep->stats.tx_bytes += length;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += length;
} else {
- ep->stats.tx_errors++;
+ dev->stats.tx_errors++;
}
if (tstat0 & TSTAT0_OW)
- ep->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
if (tstat0 & TSTAT0_TXU)
- ep->stats.tx_fifo_errors++;
- ep->stats.collisions += (tstat0 >> 16) & 0x1f;
+ dev->stats.tx_fifo_errors++;
+ dev->stats.collisions += (tstat0 >> 16) & 0x1f;
ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1);
if (ep->tx_pending == TX_QUEUE_ENTRIES)
@@ -758,7 +750,6 @@ static const struct net_device_ops ep93xx_netdev_ops = {
.ndo_open = ep93xx_open,
.ndo_stop = ep93xx_close,
.ndo_start_xmit = ep93xx_xmit,
- .ndo_get_stats = ep93xx_get_stats,
.ndo_do_ioctl = ep93xx_ioctl,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index b17ab5153f51..b00781c02d5d 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -68,7 +68,6 @@ static int ether1_open(struct net_device *dev);
static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t ether1_interrupt(int irq, void *dev_id);
static int ether1_close(struct net_device *dev);
-static struct net_device_stats *ether1_getstats(struct net_device *dev);
static void ether1_setmulticastlist(struct net_device *dev);
static void ether1_timeout(struct net_device *dev);
@@ -649,8 +648,6 @@ ether1_open (struct net_device *dev)
if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev))
return -EAGAIN;
- memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats));
-
if (ether1_init_for_open (dev)) {
free_irq (dev->irq, dev);
return -EAGAIN;
@@ -673,7 +670,7 @@ ether1_timeout(struct net_device *dev)
if (ether1_init_for_open (dev))
printk (KERN_ERR "%s: unable to restart interface\n", dev->name);
- priv(dev)->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_wake_queue(dev);
}
@@ -802,21 +799,21 @@ again:
while (nop.nop_status & STAT_COMPLETE) {
if (nop.nop_status & STAT_OK) {
- priv(dev)->stats.tx_packets ++;
- priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
+ dev->stats.tx_packets++;
+ dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
} else {
- priv(dev)->stats.tx_errors ++;
+ dev->stats.tx_errors++;
if (nop.nop_status & STAT_COLLAFTERTX)
- priv(dev)->stats.collisions ++;
+ dev->stats.collisions++;
if (nop.nop_status & STAT_NOCARRIER)
- priv(dev)->stats.tx_carrier_errors ++;
+ dev->stats.tx_carrier_errors++;
if (nop.nop_status & STAT_TXLOSTCTS)
printk (KERN_WARNING "%s: cts lost\n", dev->name);
if (nop.nop_status & STAT_TXSLOWDMA)
- priv(dev)->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
if (nop.nop_status & STAT_COLLEXCESSIVE)
- priv(dev)->stats.collisions += 16;
+ dev->stats.collisions += 16;
}
if (nop.nop_link == caddr) {
@@ -879,13 +876,13 @@ ether1_recv_done (struct net_device *dev)
skb->protocol = eth_type_trans (skb, dev);
netif_rx (skb);
- priv(dev)->stats.rx_packets ++;
+ dev->stats.rx_packets++;
} else
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
} else {
printk(KERN_WARNING "%s: %s\n", dev->name,
(rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid");
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
}
nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS);
@@ -939,7 +936,7 @@ ether1_interrupt (int irq, void *dev_id)
printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name);
ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
writeb(CTRL_CA, REG_CONTROL);
- priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */
+ dev->stats.rx_dropped++; /* we suspended due to lack of buffer space */
} else
printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name,
ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS));
@@ -962,12 +959,6 @@ ether1_close (struct net_device *dev)
return 0;
}
-static struct net_device_stats *
-ether1_getstats (struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
/*
* Set or clear the multicast filter for this adaptor.
* num_addrs == -1 Promiscuous mode, receive all packets.
@@ -994,7 +985,6 @@ static const struct net_device_ops ether1_netdev_ops = {
.ndo_open = ether1_open,
.ndo_stop = ether1_close,
.ndo_start_xmit = ether1_sendpacket,
- .ndo_get_stats = ether1_getstats,
.ndo_set_multicast_list = ether1_setmulticastlist,
.ndo_tx_timeout = ether1_timeout,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h
index c8a4b2389d85..3a5830ab3dc7 100644
--- a/drivers/net/arm/ether1.h
+++ b/drivers/net/arm/ether1.h
@@ -38,7 +38,6 @@
struct ether1_priv {
void __iomem *base;
- struct net_device_stats stats;
unsigned int tx_link;
unsigned int tx_head;
volatile unsigned int tx_tail;
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 1361b7367c28..44a8746f4014 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -81,7 +81,6 @@ static int ether3_open (struct net_device *dev);
static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
static irqreturn_t ether3_interrupt (int irq, void *dev_id);
static int ether3_close (struct net_device *dev);
-static struct net_device_stats *ether3_getstats (struct net_device *dev);
static void ether3_setmulticastlist (struct net_device *dev);
static void ether3_timeout(struct net_device *dev);
@@ -323,8 +322,6 @@ ether3_init_for_open(struct net_device *dev)
{
int i;
- memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats));
-
/* Reset the chip */
ether3_outw(CFG2_RESET, REG_CONFIG2);
udelay(4);
@@ -442,15 +439,6 @@ ether3_close(struct net_device *dev)
}
/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *ether3_getstats(struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
-/*
* Set or clear promiscuous/multicast mode filter for this adaptor.
*
* We don't attempt any packet filtering. The card may have a SEEQ 8004
@@ -490,7 +478,7 @@ static void ether3_timeout(struct net_device *dev)
local_irq_restore(flags);
priv(dev)->regs.config2 |= CFG2_CTRLO;
- priv(dev)->stats.tx_errors += 1;
+ dev->stats.tx_errors += 1;
ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
priv(dev)->tx_head = priv(dev)->tx_tail = 0;
@@ -509,7 +497,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
if (priv(dev)->broken) {
dev_kfree_skb(skb);
- priv(dev)->stats.tx_dropped ++;
+ dev->stats.tx_dropped++;
netif_start_queue(dev);
return NETDEV_TX_OK;
}
@@ -673,7 +661,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
} else
goto dropping;
} else {
- struct net_device_stats *stats = &priv(dev)->stats;
+ struct net_device_stats *stats = &dev->stats;
ether3_outw(next_ptr >> 8, REG_RECVEND);
if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++;
if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++;
@@ -685,14 +673,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
while (-- maxcnt);
done:
- priv(dev)->stats.rx_packets += received;
+ dev->stats.rx_packets += received;
priv(dev)->rx_head = next_ptr;
/*
* If rx went off line, then that means that the buffer may be full. We
* have dropped at least one packet.
*/
if (!(ether3_inw(REG_STATUS) & STAT_RXON)) {
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
ether3_outw(next_ptr, REG_RECVPTR);
ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND);
}
@@ -710,7 +698,7 @@ dropping:{
last_warned = jiffies;
printk("%s: memory squeeze, dropping packet.\n", dev->name);
}
- priv(dev)->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
goto done;
}
}
@@ -743,13 +731,13 @@ static void ether3_tx(struct net_device *dev)
* Update errors
*/
if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS)))
- priv(dev)->stats.tx_packets++;
+ dev->stats.tx_packets++;
else {
- priv(dev)->stats.tx_errors ++;
+ dev->stats.tx_errors++;
if (status & TXSTAT_16COLLISIONS)
- priv(dev)->stats.collisions += 16;
+ dev->stats.collisions += 16;
if (status & TXSTAT_BABBLED)
- priv(dev)->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
}
tx_tail = (tx_tail + 1) & 15;
@@ -773,7 +761,6 @@ static const struct net_device_ops ether3_netdev_ops = {
.ndo_open = ether3_open,
.ndo_stop = ether3_close,
.ndo_start_xmit = ether3_sendpacket,
- .ndo_get_stats = ether3_getstats,
.ndo_set_multicast_list = ether3_setmulticastlist,
.ndo_tx_timeout = ether3_timeout,
.ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h
index 1921a3a07da7..2db63b08bdf3 100644
--- a/drivers/net/arm/ether3.h
+++ b/drivers/net/arm/ether3.h
@@ -164,7 +164,6 @@ struct dev_priv {
unsigned char tx_head; /* buffer nr to insert next packet */
unsigned char tx_tail; /* buffer nr of transmitting packet */
unsigned int rx_head; /* address to fetch next packet from */
- struct net_device_stats stats;
struct timer_list timer;
int broken; /* 0 = ok, 1 = something went wrong */
};
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
index 52abbbdf8a08..ef4115b897bf 100644
--- a/drivers/net/atl1c/atl1c.h
+++ b/drivers/net/atl1c/atl1c.h
@@ -559,7 +559,6 @@ struct atl1c_adapter {
struct napi_struct napi;
struct atl1c_hw hw;
struct atl1c_hw_stats hw_stats;
- struct net_device_stats net_stats;
struct mii_if_info mii; /* MII interface info */
u16 rx_buffer_len;
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
index d8501f060957..919080b2c3a5 100644
--- a/drivers/net/atl1c/atl1c_hw.c
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -480,7 +480,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw)
atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D);
}
if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2
- || hw->nic_type == athr_l2c || hw->nic_type == athr_l2c) {
+ || hw->nic_type == athr_l2c) {
atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
}
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index c7b8ef507ebd..553230eb365c 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -1562,7 +1562,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw_stats *hw_stats = &adapter->hw_stats;
- struct net_device_stats *net_stats = &adapter->net_stats;
+ struct net_device_stats *net_stats = &netdev->stats;
atl1c_update_hw_stats(adapter);
net_stats->rx_packets = hw_stats->rx_ok;
@@ -1590,7 +1590,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
net_stats->tx_window_errors = hw_stats->tx_late_col;
- return &adapter->net_stats;
+ return net_stats;
}
static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
@@ -1700,7 +1700,7 @@ static irqreturn_t atl1c_intr(int irq, void *data)
/* link event */
if (status & (ISR_GPHY | ISR_MANUAL)) {
- adapter->net_stats.tx_carrier_errors++;
+ netdev->stats.tx_carrier_errors++;
atl1c_link_chg_event(adapter);
break;
}
@@ -1719,7 +1719,7 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
* cannot figure out if the packet is fragmented or not,
* so we tell the KERNEL CHECKSUM_NONE
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 1acea5774e89..56ace3fbe40d 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1331,7 +1331,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
u16 pkt_flags;
u16 err_flags;
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
pkt_flags = prrs->pkt_flag;
err_flags = prrs->err_flag;
if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
@@ -2316,7 +2316,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl1e_phy_config;
+ adapter->phy_config_timer.function = atl1e_phy_config;
adapter->phy_config_timer.data = (unsigned long) adapter;
/* get user settings */
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 63b9ba0cc67e..e1e0171d6e62 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1805,7 +1805,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
* the higher layers and let it be sorted out there.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
@@ -3036,7 +3036,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- setup_timer(&adapter->phy_config_timer, &atl1_phy_config,
+ setup_timer(&adapter->phy_config_timer, atl1_phy_config,
(unsigned long)adapter);
adapter->phy_timer_pending = false;
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 8da87383fb39..29c0265ccc5d 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -51,10 +51,10 @@
#define ATL2_DRV_VERSION "2.2.3"
-static char atl2_driver_name[] = "atl2";
+static const char atl2_driver_name[] = "atl2";
static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver";
-static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
-static char atl2_driver_version[] = ATL2_DRV_VERSION;
+static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
+static const char atl2_driver_version[] = ATL2_DRV_VERSION;
MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>");
MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver");
@@ -1444,11 +1444,11 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
atl2_check_options(adapter);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &atl2_watchdog;
+ adapter->watchdog_timer.function = atl2_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl2_phy_config;
+ adapter->phy_config_timer.function = atl2_phy_config;
adapter->phy_config_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->reset_task, atl2_reset_task);
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index bd2f9d331dac..dfd96b20547f 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -445,7 +445,7 @@ static int net_open(struct net_device *dev)
init_timer(&lp->timer);
lp->timer.expires = jiffies + TIMED_CHECKER;
lp->timer.data = (unsigned long)dev;
- lp->timer.function = &atp_timed_checker; /* timer handler */
+ lp->timer.function = atp_timed_checker; /* timer handler */
add_timer(&lp->timer);
netif_start_queue(dev);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 15ae6df2ff00..43489f89c142 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -13,7 +13,7 @@
* converted to use linux-2.6.x's PHY framework
*
* Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
+ * ppopov@mvista.com or source@mvista.com
*
* ########################################################################
*
@@ -34,6 +34,8 @@
*
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/capability.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
@@ -56,11 +58,11 @@
#include <linux/crc32.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
-#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/irq.h>
-#include <asm/io.h>
#include <asm/processor.h>
#include <au1000.h>
@@ -152,11 +154,11 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
spin_lock_irqsave(&aup->lock, flags);
- if(force_reset || (!aup->mac_enabled)) {
- *aup->enable = MAC_EN_CLOCK_ENABLE;
+ if (force_reset || (!aup->mac_enabled)) {
+ writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
au_sync_delay(2);
- *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE);
+ writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+ | MAC_EN_CLOCK_ENABLE), &aup->enable);
au_sync_delay(2);
aup->mac_enabled = 1;
@@ -171,12 +173,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
u32 mii_control;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "read_MII busy timeout!!\n");
@@ -187,29 +189,29 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
mii_control = MAC_SET_MII_SELECT_REG(reg) |
MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
- *mii_control_reg = mii_control;
+ writel(mii_control, mii_control_reg);
timedout = 20;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "mdio_read busy timeout!!\n");
return -1;
}
}
- return (int)*mii_data_reg;
+ return readl(mii_data_reg);
}
static void au1000_mdio_write(struct net_device *dev, int phy_addr,
int reg, u16 value)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
u32 mii_control;
- while (*mii_control_reg & MAC_MII_BUSY) {
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
mdelay(1);
if (--timedout == 0) {
netdev_err(dev, "mdio_write busy timeout!!\n");
@@ -220,18 +222,22 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
mii_control = MAC_SET_MII_SELECT_REG(reg) |
MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
- *mii_data_reg = value;
- *mii_control_reg = mii_control;
+ writel(value, mii_data_reg);
+ writel(mii_control, mii_control_reg);
}
static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
{
/* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
- * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
+ * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus)
+ */
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
return au1000_mdio_read(dev, phy_addr, regnum);
}
@@ -240,8 +246,11 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
{
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
au1000_mdio_write(dev, phy_addr, regnum, value);
return 0;
}
@@ -250,28 +259,37 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
{
struct net_device *const dev = bus->priv;
- au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
return 0;
}
static void au1000_hard_stop(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
netif_dbg(aup, drv, dev, "hard stop\n");
- aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ reg = readl(&aup->mac->control);
+ reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
au_sync_delay(10);
}
static void au1000_enable_rx_tx(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
netif_dbg(aup, hw, dev, "enable_rx_tx\n");
- aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ reg = readl(&aup->mac->control);
+ reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
au_sync_delay(10);
}
@@ -281,6 +299,7 @@ au1000_adjust_link(struct net_device *dev)
struct au1000_private *aup = netdev_priv(dev);
struct phy_device *phydev = aup->phy_dev;
unsigned long flags;
+ u32 reg;
int status_change = 0;
@@ -312,14 +331,15 @@ au1000_adjust_link(struct net_device *dev)
/* switching duplex mode requires to disable rx and tx! */
au1000_hard_stop(dev);
- if (DUPLEX_FULL == phydev->duplex)
- aup->mac->control = ((aup->mac->control
- | MAC_FULL_DUPLEX)
- & ~MAC_DISABLE_RX_OWN);
- else
- aup->mac->control = ((aup->mac->control
- & ~MAC_FULL_DUPLEX)
- | MAC_DISABLE_RX_OWN);
+ reg = readl(&aup->mac->control);
+ if (DUPLEX_FULL == phydev->duplex) {
+ reg |= MAC_FULL_DUPLEX;
+ reg &= ~MAC_DISABLE_RX_OWN;
+ } else {
+ reg &= ~MAC_FULL_DUPLEX;
+ reg |= MAC_DISABLE_RX_OWN;
+ }
+ writel(reg, &aup->mac->control);
au_sync_delay(1);
au1000_enable_rx_tx(dev);
@@ -353,10 +373,11 @@ au1000_adjust_link(struct net_device *dev)
}
}
-static int au1000_mii_probe (struct net_device *dev)
+static int au1000_mii_probe(struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
struct phy_device *phydev = NULL;
+ int phy_addr;
if (aup->phy_static_config) {
BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
@@ -366,42 +387,46 @@ static int au1000_mii_probe (struct net_device *dev)
else
netdev_info(dev, "using PHY-less setup\n");
return 0;
- } else {
- int phy_addr;
-
- /* find the first (lowest address) PHY on the current MAC's MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
- if (aup->mii_bus->phy_map[phy_addr]) {
- phydev = aup->mii_bus->phy_map[phy_addr];
- if (!aup->phy_search_highest_addr)
- break; /* break out with first one found */
- }
-
- if (aup->phy1_search_mac0) {
- /* try harder to find a PHY */
- if (!phydev && (aup->mac_id == 1)) {
- /* no PHY found, maybe we have a dual PHY? */
- dev_info(&dev->dev, ": no PHY found on MAC1, "
- "let's see if it's attached to MAC0...\n");
-
- /* find the first (lowest address) non-attached PHY on
- * the MAC0 MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- struct phy_device *const tmp_phydev =
- aup->mii_bus->phy_map[phy_addr];
-
- if (aup->mac_id == 1)
- break;
-
- if (!tmp_phydev)
- continue; /* no PHY here... */
+ }
- if (tmp_phydev->attached_dev)
- continue; /* already claimed by MAC0 */
+ /* find the first (lowest address) PHY
+ * on the current MAC's MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+ if (aup->mii_bus->phy_map[phy_addr]) {
+ phydev = aup->mii_bus->phy_map[phy_addr];
+ if (!aup->phy_search_highest_addr)
+ /* break out with first one found */
+ break;
+ }
- phydev = tmp_phydev;
- break; /* found it */
- }
+ if (aup->phy1_search_mac0) {
+ /* try harder to find a PHY */
+ if (!phydev && (aup->mac_id == 1)) {
+ /* no PHY found, maybe we have a dual PHY? */
+ dev_info(&dev->dev, ": no PHY found on MAC1, "
+ "let's see if it's attached to MAC0...\n");
+
+ /* find the first (lowest address) non-attached
+ * PHY on the MAC0 MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ struct phy_device *const tmp_phydev =
+ aup->mii_bus->phy_map[phy_addr];
+
+ if (aup->mac_id == 1)
+ break;
+
+ /* no PHY here... */
+ if (!tmp_phydev)
+ continue;
+
+ /* already claimed by MAC0 */
+ if (tmp_phydev->attached_dev)
+ continue;
+
+ phydev = tmp_phydev;
+ break; /* found it */
}
}
}
@@ -452,20 +477,20 @@ static int au1000_mii_probe (struct net_device *dev)
* has the virtual and dma address of a buffer suitable for
* both, receive and transmit operations.
*/
-static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
+static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup)
{
- db_dest_t *pDB;
+ struct db_dest *pDB;
pDB = aup->pDBfree;
- if (pDB) {
+ if (pDB)
aup->pDBfree = pDB->pnext;
- }
+
return pDB;
}
-void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
+void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB)
{
- db_dest_t *pDBfree = aup->pDBfree;
+ struct db_dest *pDBfree = aup->pDBfree;
if (pDBfree)
pDBfree->pnext = pDB;
aup->pDBfree = pDB;
@@ -478,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
au1000_hard_stop(dev);
- *aup->enable = MAC_EN_CLOCK_ENABLE;
+ writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
au_sync_delay(2);
- *aup->enable = 0;
+ writel(0, &aup->enable);
au_sync_delay(2);
aup->tx_full = 0;
@@ -507,7 +532,7 @@ static void au1000_reset_mac(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- au1000_reset_mac_unlocked (dev);
+ au1000_reset_mac_unlocked(dev);
spin_unlock_irqrestore(&aup->lock, flags);
}
@@ -524,11 +549,13 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
for (i = 0; i < NUM_RX_DMA; i++) {
aup->rx_dma_ring[i] =
- (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
+ (struct rx_dma *)
+ (rx_base + sizeof(struct rx_dma)*i);
}
for (i = 0; i < NUM_TX_DMA; i++) {
aup->tx_dma_ring[i] =
- (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
+ (struct tx_dma *)
+ (tx_base + sizeof(struct tx_dma)*i);
}
}
@@ -616,18 +643,21 @@ static int au1000_init(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- aup->mac->control = 0;
+ writel(0, &aup->mac->control);
aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
aup->tx_tail = aup->tx_head;
aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
- aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
- aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
- dev->dev_addr[1]<<8 | dev->dev_addr[0];
+ writel(dev->dev_addr[5]<<8 | dev->dev_addr[4],
+ &aup->mac->mac_addr_high);
+ writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
+ dev->dev_addr[1]<<8 | dev->dev_addr[0],
+ &aup->mac->mac_addr_low);
- for (i = 0; i < NUM_RX_DMA; i++) {
+
+ for (i = 0; i < NUM_RX_DMA; i++)
aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
- }
+
au_sync();
control = MAC_RX_ENABLE | MAC_TX_ENABLE;
@@ -643,8 +673,8 @@ static int au1000_init(struct net_device *dev)
control |= MAC_FULL_DUPLEX;
}
- aup->mac->control = control;
- aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
+ writel(control, &aup->mac->control);
+ writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
au_sync();
spin_unlock_irqrestore(&aup->lock, flags);
@@ -681,9 +711,9 @@ static int au1000_rx(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
struct sk_buff *skb;
- volatile rx_dma_t *prxd;
+ struct rx_dma *prxd;
u32 buff_stat, status;
- db_dest_t *pDB;
+ struct db_dest *pDB;
u32 frmlen;
netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
@@ -713,24 +743,26 @@ static int au1000_rx(struct net_device *dev)
netif_rx(skb); /* pass the packet to upper layers */
} else {
if (au1000_debug > 4) {
+ pr_err("rx_error(s):");
if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
+ pr_cont(" miss");
if (status & RX_WDOG_TIMER)
- printk("rx wdog\n");
+ pr_cont(" wdog");
if (status & RX_RUNT)
- printk("rx runt\n");
+ pr_cont(" runt");
if (status & RX_OVERLEN)
- printk("rx overlen\n");
+ pr_cont(" overlen");
if (status & RX_COLL)
- printk("rx coll\n");
+ pr_cont(" coll");
if (status & RX_MII_ERROR)
- printk("rx mii error\n");
+ pr_cont(" mii error");
if (status & RX_CRC_ERROR)
- printk("rx crc error\n");
+ pr_cont(" crc error");
if (status & RX_LEN_ERROR)
- printk("rx len error\n");
+ pr_cont(" len error");
if (status & RX_U_CNTRL_FRAME)
- printk("rx u control frame\n");
+ pr_cont(" u control frame");
+ pr_cont("\n");
}
}
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
@@ -753,7 +785,8 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
/* any other tx errors are only valid
- * in half duplex mode */
+ * in half duplex mode
+ */
ps->tx_errors++;
ps->tx_aborted_errors++;
}
@@ -774,7 +807,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
static void au1000_tx_ack(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
- volatile tx_dma_t *ptxd;
+ struct tx_dma *ptxd;
ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -854,7 +887,7 @@ static int au1000_close(struct net_device *dev)
spin_lock_irqsave(&aup->lock, flags);
- au1000_reset_mac_unlocked (dev);
+ au1000_reset_mac_unlocked(dev);
/* stop the device */
netif_stop_queue(dev);
@@ -873,9 +906,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
struct net_device_stats *ps = &dev->stats;
- volatile tx_dma_t *ptxd;
+ struct tx_dma *ptxd;
u32 buff_stat;
- db_dest_t *pDB;
+ struct db_dest *pDB;
int i;
netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
@@ -902,9 +935,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
pDB = aup->tx_db_inuse[aup->tx_head];
skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
if (skb->len < ETH_ZLEN) {
- for (i = skb->len; i < ETH_ZLEN; i++) {
+ for (i = skb->len; i < ETH_ZLEN; i++)
((char *)pDB->vaddr)[i] = 0;
- }
+
ptxd->len = ETH_ZLEN;
} else
ptxd->len = skb->len;
@@ -935,15 +968,16 @@ static void au1000_tx_timeout(struct net_device *dev)
static void au1000_multicast_list(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
- netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags);
-
+ netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags);
+ reg = readl(&aup->mac->control);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- aup->mac->control |= MAC_PROMISCUOUS;
+ reg |= MAC_PROMISCUOUS;
} else if ((dev->flags & IFF_ALLMULTI) ||
netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
- aup->mac->control |= MAC_PASS_ALL_MULTI;
- aup->mac->control &= ~MAC_PROMISCUOUS;
+ reg |= MAC_PASS_ALL_MULTI;
+ reg &= ~MAC_PROMISCUOUS;
netdev_info(dev, "Pass all multicast\n");
} else {
struct netdev_hw_addr *ha;
@@ -953,11 +987,12 @@ static void au1000_multicast_list(struct net_device *dev)
netdev_for_each_mc_addr(ha, dev)
set_bit(ether_crc(ETH_ALEN, ha->addr)>>26,
(long *)mc_filter);
- aup->mac->multi_hash_high = mc_filter[1];
- aup->mac->multi_hash_low = mc_filter[0];
- aup->mac->control &= ~MAC_PROMISCUOUS;
- aup->mac->control |= MAC_HASH_MODE;
+ writel(mc_filter[1], &aup->mac->multi_hash_high);
+ writel(mc_filter[0], &aup->mac->multi_hash_low);
+ reg &= ~MAC_PROMISCUOUS;
+ reg |= MAC_HASH_MODE;
}
+ writel(reg, &aup->mac->control);
}
static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -991,7 +1026,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
struct au1000_private *aup = NULL;
struct au1000_eth_platform_data *pd;
struct net_device *dev = NULL;
- db_dest_t *pDB, *pDBfree;
+ struct db_dest *pDB, *pDBfree;
int irq, i, err = 0;
struct resource *base, *macen;
@@ -1016,13 +1051,15 @@ static int __devinit au1000_probe(struct platform_device *pdev)
goto out;
}
- if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
+ if (!request_mem_region(base->start, resource_size(base),
+ pdev->name)) {
dev_err(&pdev->dev, "failed to request memory region for base registers\n");
err = -ENXIO;
goto out;
}
- if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
+ if (!request_mem_region(macen->start, resource_size(macen),
+ pdev->name)) {
dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
err = -ENXIO;
goto err_request;
@@ -1040,10 +1077,12 @@ static int __devinit au1000_probe(struct platform_device *pdev)
aup = netdev_priv(dev);
spin_lock_init(&aup->lock);
- aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug);
+ aup->msg_enable = (au1000_debug < 4 ?
+ AU1000_DEF_MSG_ENABLE : au1000_debug);
- /* Allocate the data buffers */
- /* Snooping works fine with eth on all au1xxx */
+ /* Allocate the data buffers
+ * Snooping works fine with eth on all au1xxx
+ */
aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
(NUM_TX_BUFFS + NUM_RX_BUFFS),
&aup->dma_addr, 0);
@@ -1054,15 +1093,17 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
/* aup->mac is the base address of the MAC's registers */
- aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
+ aup->mac = (struct mac_reg *)
+ ioremap_nocache(base->start, resource_size(base));
if (!aup->mac) {
dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
err = -ENXIO;
goto err_remap1;
}
- /* Setup some variables for quick register address access */
- aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
+ /* Setup some variables for quick register address access */
+ aup->enable = (u32 *)ioremap_nocache(macen->start,
+ resource_size(macen));
if (!aup->enable) {
dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
err = -ENXIO;
@@ -1078,12 +1119,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
/* set a random MAC now in case platform_data doesn't provide one */
random_ether_addr(dev->dev_addr);
- *aup->enable = 0;
+ writel(0, &aup->enable);
aup->mac_enabled = 0;
pd = pdev->dev.platform_data;
if (!pd) {
- dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
+ dev_info(&pdev->dev, "no platform_data passed,"
+ " PHY search on MAC0\n");
aup->phy1_search_mac0 = 1;
} else {
if (is_valid_ether_addr(pd->mac))
@@ -1098,8 +1140,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
if (aup->phy_busid && aup->phy_busid > 0) {
- dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII"
- "bus not supported yet\n");
+ dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII bus not supported yet\n");
err = -ENODEV;
goto err_mdiobus_alloc;
}
@@ -1151,17 +1192,17 @@ static int __devinit au1000_probe(struct platform_device *pdev)
for (i = 0; i < NUM_RX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
- if (!pDB) {
+ if (!pDB)
goto err_out;
- }
+
aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
aup->rx_db_inuse[i] = pDB;
}
for (i = 0; i < NUM_TX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
- if (!pDB) {
+ if (!pDB)
goto err_out;
- }
+
aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
aup->tx_dma_ring[i]->len = 0;
aup->tx_db_inuse[i] = pDB;
@@ -1188,7 +1229,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
(unsigned long)base->start, irq);
if (version_printed++ == 0)
- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+ pr_info("%s version %s %s\n",
+ DRV_NAME, DRV_VERSION, DRV_AUTHOR);
return 0;
@@ -1197,7 +1239,8 @@ err_out:
mdiobus_unregister(aup->mii_bus);
/* here we should have a valid dev plus aup-> register addresses
- * so we can reset the mac properly.*/
+ * so we can reset the mac properly.
+ */
au1000_reset_mac(dev);
for (i = 0; i < NUM_RX_DMA; i++) {
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index d06ec008fbf1..6229c774552c 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -44,34 +44,34 @@
* Data Buffer Descriptor. Data buffers must be aligned on 32 byte
* boundary for both, receive and transmit.
*/
-typedef struct db_dest {
+struct db_dest {
struct db_dest *pnext;
- volatile u32 *vaddr;
+ u32 *vaddr;
dma_addr_t dma_addr;
-} db_dest_t;
+};
/*
* The transmit and receive descriptors are memory
* mapped registers.
*/
-typedef struct tx_dma {
+struct tx_dma {
u32 status;
u32 buff_stat;
u32 len;
u32 pad;
-} tx_dma_t;
+};
-typedef struct rx_dma {
+struct rx_dma {
u32 status;
u32 buff_stat;
u32 pad[2];
-} rx_dma_t;
+};
/*
* MAC control registers, memory mapped.
*/
-typedef struct mac_reg {
+struct mac_reg {
u32 control;
u32 mac_addr_high;
u32 mac_addr_low;
@@ -82,16 +82,16 @@ typedef struct mac_reg {
u32 flow_control;
u32 vlan1_tag;
u32 vlan2_tag;
-} mac_reg_t;
+};
struct au1000_private {
- db_dest_t *pDBfree;
- db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
- volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
- volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
- db_dest_t *rx_db_inuse[NUM_RX_DMA];
- db_dest_t *tx_db_inuse[NUM_TX_DMA];
+ struct db_dest *pDBfree;
+ struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS];
+ struct rx_dma *rx_dma_ring[NUM_RX_DMA];
+ struct tx_dma *tx_dma_ring[NUM_TX_DMA];
+ struct db_dest *rx_db_inuse[NUM_RX_DMA];
+ struct db_dest *tx_db_inuse[NUM_TX_DMA];
u32 rx_head;
u32 tx_head;
u32 tx_tail;
@@ -99,7 +99,9 @@ struct au1000_private {
int mac_id;
- int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */
+ int mac_enabled; /* whether MAC is currently enabled and running
+ * (req. for mdio)
+ */
int old_link; /* used by au1000_adjust_link */
int old_speed;
@@ -117,9 +119,11 @@ struct au1000_private {
int phy_busid;
int phy_irq;
- /* These variables are just for quick access to certain regs addresses. */
- volatile mac_reg_t *mac; /* mac registers */
- volatile u32 *enable; /* address of MAC Enable Register */
+ /* These variables are just for quick access
+ * to certain regs addresses.
+ */
+ struct mac_reg *mac; /* mac registers */
+ u32 *enable; /* address of MAC Enable Register */
u32 vaddr; /* virtual address of rx/tx buffers */
dma_addr_t dma_addr; /* dma address of rx/tx buffers */
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 37617abc1647..8e7c8a8e61c7 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -818,7 +818,7 @@ static int b44_rx(struct b44 *bp, int budget)
copy_skb->data, len);
skb = copy_skb;
}
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, bp->dev);
netif_receive_skb(skb);
received++;
@@ -848,6 +848,15 @@ static int b44_poll(struct napi_struct *napi, int budget)
b44_tx(bp);
/* spin_unlock(&bp->tx_lock); */
}
+ if (bp->istat & ISTAT_RFO) { /* fast recovery, in ~20msec */
+ bp->istat &= ~ISTAT_RFO;
+ b44_disable_ints(bp);
+ ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */
+ b44_init_rings(bp);
+ b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
+ netif_wake_queue(bp->dev);
+ }
+
spin_unlock_irqrestore(&bp->lock, flags);
work_done = 0;
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index 0d2c5da08937..ecfef240a303 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -293,22 +293,22 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
/* if the packet does not have start of packet _and_
* end of packet flag set, then just recycle it */
if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
continue;
}
/* recycle packet if it's marked as bad */
if (unlikely(len_stat & DMADESC_ERR_MASK)) {
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (len_stat & DMADESC_OVSIZE_MASK)
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (len_stat & DMADESC_CRC_MASK)
- priv->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (len_stat & DMADESC_UNDER_MASK)
- priv->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (len_stat & DMADESC_OV_MASK)
- priv->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
continue;
}
@@ -324,7 +324,7 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
nskb = netdev_alloc_skb_ip_align(dev, len);
if (!nskb) {
/* forget packet, just rearm desc */
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
continue;
}
@@ -342,8 +342,8 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget)
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
netif_receive_skb(skb);
} while (--budget > 0);
@@ -403,7 +403,7 @@ static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
spin_unlock(&priv->tx_lock);
if (desc->len_stat & DMADESC_UNDER_MASK)
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
released++;
@@ -563,8 +563,8 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!priv->tx_desc_count)
netif_stop_queue(dev);
- priv->stats.tx_bytes += skb->len;
- priv->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
ret = NETDEV_TX_OK;
out_unlock:
@@ -798,7 +798,7 @@ static int bcm_enet_open(struct net_device *dev)
snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
priv->mac_id ? "1" : "0", priv->phy_id);
- phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
+ phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0,
PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
@@ -1141,17 +1141,6 @@ static int bcm_enet_stop(struct net_device *dev)
}
/*
- * core request to return device rx/tx stats
- */
-static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev)
-{
- struct bcm_enet_priv *priv;
-
- priv = netdev_priv(dev);
- return &priv->stats;
-}
-
-/*
* ethtool callbacks
*/
struct bcm_enet_stats {
@@ -1163,16 +1152,18 @@ struct bcm_enet_stats {
#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \
offsetof(struct bcm_enet_priv, m)
+#define DEV_STAT(m) sizeof(((struct net_device_stats *)0)->m), \
+ offsetof(struct net_device_stats, m)
static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
- { "rx_packets", GEN_STAT(stats.rx_packets), -1 },
- { "tx_packets", GEN_STAT(stats.tx_packets), -1 },
- { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 },
- { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 },
- { "rx_errors", GEN_STAT(stats.rx_errors), -1 },
- { "tx_errors", GEN_STAT(stats.tx_errors), -1 },
- { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 },
- { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 },
+ { "rx_packets", DEV_STAT(rx_packets), -1 },
+ { "tx_packets", DEV_STAT(tx_packets), -1 },
+ { "rx_bytes", DEV_STAT(rx_bytes), -1 },
+ { "tx_bytes", DEV_STAT(tx_bytes), -1 },
+ { "rx_errors", DEV_STAT(rx_errors), -1 },
+ { "tx_errors", DEV_STAT(tx_errors), -1 },
+ { "rx_dropped", DEV_STAT(rx_dropped), -1 },
+ { "tx_dropped", DEV_STAT(tx_dropped), -1 },
{ "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
{ "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
@@ -1328,7 +1319,11 @@ static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
char *p;
s = &bcm_enet_gstrings_stats[i];
- p = (char *)priv + s->stat_offset;
+ if (s->mib_reg == -1)
+ p = (char *)&netdev->stats;
+ else
+ p = (char *)priv;
+ p += s->stat_offset;
data[i] = (s->sizeof_stat == sizeof(u64)) ?
*(u64 *)p : *(u32 *)p;
}
@@ -1605,7 +1600,6 @@ static const struct net_device_ops bcm_enet_ops = {
.ndo_open = bcm_enet_open,
.ndo_stop = bcm_enet_stop,
.ndo_start_xmit = bcm_enet_start_xmit,
- .ndo_get_stats = bcm_enet_get_stats,
.ndo_set_mac_address = bcm_enet_set_mac_address,
.ndo_set_multicast_list = bcm_enet_set_multicast_list,
.ndo_do_ioctl = bcm_enet_ioctl,
diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h
index bd3684d42d74..0e3048b788c2 100644
--- a/drivers/net/bcm63xx_enet.h
+++ b/drivers/net/bcm63xx_enet.h
@@ -274,7 +274,6 @@ struct bcm_enet_priv {
int pause_tx;
/* stats */
- struct net_device_stats stats;
struct bcm_enet_mib_counters mib;
/* after mib interrupt, mib registers update is done in this
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 99197bd54da5..4faf6961dcec 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -181,6 +181,7 @@ struct be_drvr_stats {
u64 be_rx_bytes_prev;
u64 be_rx_pkts;
u32 be_rx_rate;
+ u32 be_rx_mcast_pkt;
/* number of non ether type II frames dropped where
* frame len > length field of Mac Hdr */
u32 be_802_3_dropped_frames;
@@ -413,6 +414,20 @@ static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
adapter->is_virtfn = (data != 0xAA);
}
+static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
+{
+ u32 addr;
+
+ addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
+
+ mac[5] = (u8)(addr & 0xFF);
+ mac[4] = (u8)((addr >> 8) & 0xFF);
+ mac[3] = (u8)((addr >> 16) & 0xFF);
+ mac[2] = 0xC9;
+ mac[1] = 0x00;
+ mac[0] = 0x00;
+}
+
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 3d305494a606..34abcc9403d6 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -140,10 +140,8 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
while ((compl = be_mcc_compl_get(adapter))) {
if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
/* Interpret flags as an async trailer */
- BUG_ON(!is_link_state_evt(compl->flags));
-
- /* Interpret compl as a async link evt */
- be_async_link_state_process(adapter,
+ if (is_link_state_evt(compl->flags))
+ be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
@@ -207,7 +205,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
if (msecs > 4000) {
dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
- be_dump_ue(adapter);
+ be_detect_dump_ue(adapter);
return -1;
}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index bdc10a28cfda..ad1e6fac60c5 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -992,5 +992,5 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
extern int be_cmd_get_phy_info(struct be_adapter *adapter,
struct be_dma_mem *cmd);
extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
-extern void be_dump_ue(struct be_adapter *adapter);
+extern void be_detect_dump_ue(struct be_adapter *adapter);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index cd16243c7c36..d92063420c25 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -60,6 +60,7 @@ static const struct be_ethtool_stat et_stats[] = {
{DRVSTAT_INFO(be_rx_events)},
{DRVSTAT_INFO(be_tx_compl)},
{DRVSTAT_INFO(be_rx_compl)},
+ {DRVSTAT_INFO(be_rx_mcast_pkt)},
{DRVSTAT_INFO(be_ethrx_post_fail)},
{DRVSTAT_INFO(be_802_3_dropped_frames)},
{DRVSTAT_INFO(be_802_3_malformed_frames)},
@@ -90,6 +91,9 @@ static const struct be_ethtool_stat et_stats[] = {
{PORTSTAT_INFO(rx_non_rss_packets)},
{PORTSTAT_INFO(rx_ipv4_packets)},
{PORTSTAT_INFO(rx_ipv6_packets)},
+ {PORTSTAT_INFO(rx_switched_unicast_packets)},
+ {PORTSTAT_INFO(rx_switched_multicast_packets)},
+ {PORTSTAT_INFO(rx_switched_broadcast_packets)},
{PORTSTAT_INFO(tx_unicastframes)},
{PORTSTAT_INFO(tx_multicastframes)},
{PORTSTAT_INFO(tx_broadcastframes)},
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index 5d38046402b2..a2ec5df0d733 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -167,8 +167,11 @@
#define FLASH_FCoE_BIOS_START_g3 (13631488)
#define FLASH_REDBOOT_START_g3 (262144)
-
-
+/************* Rx Packet Type Encoding **************/
+#define BE_UNICAST_PACKET 0
+#define BE_MULTICAST_PACKET 1
+#define BE_BROADCAST_PACKET 2
+#define BE_RSVD_PACKET 3
/*
* BE descriptors: host memory data structures whose formats
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 74e146f470c6..43a3a574e2e0 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -247,6 +247,7 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts;
dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes;
dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes;
+ dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt;
/* bad pkts received */
dev_stats->rx_errors = port_stats->rx_crc_errors +
@@ -294,7 +295,6 @@ void netdev_stats_update(struct be_adapter *adapter)
/* no space available in linux */
dev_stats->tx_dropped = 0;
- dev_stats->multicast = port_stats->rx_multicast_frames;
dev_stats->collisions = 0;
/* detailed tx_errors */
@@ -365,11 +365,6 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
rx_eq->cur_eqd = eqd;
}
-static struct net_device_stats *be_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
static u32 be_calc_rate(u64 bytes, unsigned long ticks)
{
u64 rate = bytes;
@@ -848,7 +843,7 @@ static void be_rx_rate_update(struct be_adapter *adapter)
}
static void be_rx_stats_update(struct be_adapter *adapter,
- u32 pktsize, u16 numfrags)
+ u32 pktsize, u16 numfrags, u8 pkt_type)
{
struct be_drvr_stats *stats = drvr_stats(adapter);
@@ -856,6 +851,9 @@ static void be_rx_stats_update(struct be_adapter *adapter,
stats->be_rx_frags += numfrags;
stats->be_rx_bytes += pktsize;
stats->be_rx_pkts++;
+
+ if (pkt_type == BE_MULTICAST_PACKET)
+ stats->be_rx_mcast_pkt++;
}
static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
@@ -925,9 +923,11 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
u16 rxq_idx, i, j;
u32 pktsize, hdr_len, curr_frag_len, size;
u8 *start;
+ u8 pkt_type;
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
+ pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp);
page_info = get_rx_page_info(adapter, rxq_idx);
@@ -993,7 +993,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
BUG_ON(j > MAX_SKB_FRAGS);
done:
- be_rx_stats_update(adapter, pktsize, num_rcvd);
+ be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type);
}
/* Process the RX completion indicated by rxcp when GRO is disabled */
@@ -1021,7 +1021,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb_fill_rx_data(adapter, skb, rxcp, num_rcvd);
if (do_pkt_csum(rxcp, adapter->rx_csum))
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1060,6 +1060,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
u16 i, rxq_idx = 0, vid, j;
u8 vtm;
+ u8 pkt_type;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
/* Is it a flush compl that has no data */
@@ -1070,6 +1071,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+ pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp);
/* vlanf could be wrongly set in some cards.
* ignore if vtm is not set */
@@ -1125,7 +1127,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
}
- be_rx_stats_update(adapter, pkt_size, num_rcvd);
+ be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type);
}
static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
@@ -1743,26 +1745,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
return 1;
}
-static inline bool be_detect_ue(struct be_adapter *adapter)
-{
- u32 online0 = 0, online1 = 0;
-
- pci_read_config_dword(adapter->pdev, PCICFG_ONLINE0, &online0);
-
- pci_read_config_dword(adapter->pdev, PCICFG_ONLINE1, &online1);
-
- if (!online0 || !online1) {
- adapter->ue_detected = true;
- dev_err(&adapter->pdev->dev,
- "UE Detected!! online0=%d online1=%d\n",
- online0, online1);
- return true;
- }
-
- return false;
-}
-
-void be_dump_ue(struct be_adapter *adapter)
+void be_detect_dump_ue(struct be_adapter *adapter)
{
u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask;
u32 i;
@@ -1779,6 +1762,11 @@ void be_dump_ue(struct be_adapter *adapter)
ue_status_lo = (ue_status_lo & (~ue_status_lo_mask));
ue_status_hi = (ue_status_hi & (~ue_status_hi_mask));
+ if (ue_status_lo || ue_status_hi) {
+ adapter->ue_detected = true;
+ dev_err(&adapter->pdev->dev, "UE Detected!!\n");
+ }
+
if (ue_status_lo) {
for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) {
if (ue_status_lo & 1)
@@ -1814,10 +1802,8 @@ static void be_worker(struct work_struct *work)
adapter->rx_post_starved = false;
be_post_rx_frags(adapter);
}
- if (!adapter->ue_detected) {
- if (be_detect_ue(adapter))
- be_dump_ue(adapter);
- }
+ if (!adapter->ue_detected)
+ be_detect_dump_ue(adapter);
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
}
@@ -2093,6 +2079,47 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
return status;
}
+/*
+ * Generate a seed MAC address from the PF MAC Address using jhash.
+ * MAC Address for VFs are assigned incrementally starting from the seed.
+ * These addresses are programmed in the ASIC by the PF and the VF driver
+ * queries for the MAC address during its probe.
+ */
+static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
+{
+ u32 vf = 0;
+ int status;
+ u8 mac[ETH_ALEN];
+
+ be_vf_eth_addr_generate(adapter, mac);
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_pmac_add(adapter, mac,
+ adapter->vf_cfg[vf].vf_if_handle,
+ &adapter->vf_cfg[vf].vf_pmac_id);
+ if (status)
+ dev_err(&adapter->pdev->dev,
+ "Mac address add failed for VF %d\n", vf);
+ else
+ memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
+
+ mac[5] += 1;
+ }
+ return status;
+}
+
+static inline void be_vf_eth_addr_rem(struct be_adapter *adapter)
+{
+ u32 vf;
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
+ be_cmd_pmac_del(adapter,
+ adapter->vf_cfg[vf].vf_if_handle,
+ adapter->vf_cfg[vf].vf_pmac_id);
+ }
+}
+
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -2152,10 +2179,20 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto rx_qs_destroy;
+ if (be_physfn(adapter)) {
+ status = be_vf_eth_addr_config(adapter);
+ if (status)
+ goto mcc_q_destroy;
+ }
+
adapter->link_speed = -1;
return 0;
+mcc_q_destroy:
+ if (be_physfn(adapter))
+ be_vf_eth_addr_rem(adapter);
+ be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
@@ -2172,6 +2209,9 @@ do_none:
static int be_clear(struct be_adapter *adapter)
{
+ if (be_physfn(adapter))
+ be_vf_eth_addr_rem(adapter);
+
be_mcc_queues_destroy(adapter);
be_rx_queues_destroy(adapter);
be_tx_queues_destroy(adapter);
@@ -2399,7 +2439,6 @@ static struct net_device_ops be_netdev_ops = {
.ndo_open = be_open,
.ndo_stop = be_close,
.ndo_start_xmit = be_xmit,
- .ndo_get_stats = be_get_stats,
.ndo_set_rx_mode = be_set_multicast_list,
.ndo_set_mac_address = be_mac_addr_set,
.ndo_change_mtu = be_change_mtu,
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 012613fde3f4..7a0e4156fade 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -803,15 +803,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa
static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
{
struct bfin_mac_local *lp = netdev_priv(netdev);
- union skb_shared_tx *shtx = skb_tx(skb);
- if (shtx->hardware) {
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
int timeout_cnt = MAX_TIMEOUT_CNT;
/* When doing time stamping, keep the connection to the socket
* a while longer
*/
- shtx->in_progress = 1;
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
/*
* The timestamping is done at the EMAC module's MII/RMII interface
@@ -991,7 +990,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
struct bfin_mac_local *lp = netdev_priv(dev);
u16 *data;
u32 data_align = (unsigned long)(skb->data) & 0x3;
- union skb_shared_tx *shtx = skb_tx(skb);
current_tx_ptr->skb = skb;
@@ -1005,7 +1003,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
* of this field are the length of the packet payload in bytes and the higher
* 4 bits are the timestamping enable field.
*/
- if (shtx->hardware)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
*data |= 0x1000;
current_tx_ptr->desc_a.start_addr = (u32)data;
@@ -1015,7 +1013,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
} else {
*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
/* enable timestamping for the sent packet */
- if (shtx->hardware)
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
*((u16 *)(current_tx_ptr->packet)) |= 0x1000;
memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
skb->len);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 959add2410bf..9322699bb31c 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1233,15 +1233,8 @@ static void bmac_reset_and_enable(struct net_device *dev)
}
spin_unlock_irqrestore(&bp->lock, flags);
}
-static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct bmac_data *bp = netdev_priv(dev);
- strcpy(info->driver, "bmac");
- strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
-}
static const struct ethtool_ops bmac_ethtool_ops = {
- .get_drvinfo = bmac_get_drvinfo,
.get_link = ethtool_op_get_link,
};
diff --git a/drivers/net/bna/Makefile b/drivers/net/bna/Makefile
new file mode 100644
index 000000000000..a5d604de7fea
--- /dev/null
+++ b/drivers/net/bna/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+# All rights reserved.
+#
+
+obj-$(CONFIG_BNA) += bna.o
+
+bna-objs := bnad.o bnad_ethtool.o bna_ctrl.o bna_txrx.o
+bna-objs += bfa_ioc.o bfa_ioc_ct.o bfa_cee.o cna_fwimg.o
+
+EXTRA_CFLAGS := -Idrivers/net/bna
diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c
new file mode 100644
index 000000000000..f7b789a3b217
--- /dev/null
+++ b/drivers/net/bna/bfa_cee.c
@@ -0,0 +1,291 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_defs_cna.h"
+#include "cna.h"
+#include "bfa_cee.h"
+#include "bfi_cna.h"
+#include "bfa_ioc.h"
+
+#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
+#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
+
+static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg);
+static void bfa_cee_format_cee_cfg(void *buffer);
+
+static void
+bfa_cee_format_cee_cfg(void *buffer)
+{
+ struct bfa_cee_attr *cee_cfg = buffer;
+ bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
+}
+
+static void
+bfa_cee_stats_swap(struct bfa_cee_stats *stats)
+{
+ u32 *buffer = (u32 *)stats;
+ int i;
+
+ for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32));
+ i++) {
+ buffer[i] = ntohl(buffer[i]);
+ }
+}
+
+static void
+bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg)
+{
+ lldp_cfg->time_to_live =
+ ntohs(lldp_cfg->time_to_live);
+ lldp_cfg->enabled_system_cap =
+ ntohs(lldp_cfg->enabled_system_cap);
+}
+
+/**
+ * bfa_cee_attr_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE attributes
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_attr_meminfo(void)
+{
+ return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ);
+}
+/**
+ * bfa_cee_stats_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE stats
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+static u32
+bfa_cee_stats_meminfo(void)
+{
+ return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for get-attributes responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->get_attr_status = status;
+ if (status == BFA_STATUS_OK) {
+ memcpy(cee->attr, cee->attr_dma.kva,
+ sizeof(struct bfa_cee_attr));
+ bfa_cee_format_cee_cfg(cee->attr);
+ }
+ cee->get_attr_pending = false;
+ if (cee->cbfn.get_attr_cbfn)
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for get-stats responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->get_stats_status = status;
+ if (status == BFA_STATUS_OK) {
+ memcpy(cee->stats, cee->stats_dma.kva,
+ sizeof(struct bfa_cee_stats));
+ bfa_cee_stats_swap(cee->stats);
+ }
+ cee->get_stats_pending = false;
+ if (cee->cbfn.get_stats_cbfn)
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
+}
+
+/**
+ * bfa_cee_get_attr_isr()
+ *
+ * @brief CEE ISR for reset-stats responses from f/w
+ *
+ * @param[in] cee - Pointer to the CEE module
+ * status - Return status from the f/w
+ *
+ * @return void
+ */
+static void
+bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status)
+{
+ cee->reset_stats_status = status;
+ cee->reset_stats_pending = false;
+ if (cee->cbfn.reset_stats_cbfn)
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
+}
+/**
+ * bfa_nw_cee_meminfo()
+ *
+ * @brief Returns the size of the DMA memory needed by CEE module
+ *
+ * @param[in] void
+ *
+ * @return Size of DMA region
+ */
+u32
+bfa_nw_cee_meminfo(void)
+{
+ return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
+}
+
+/**
+ * bfa_nw_cee_mem_claim()
+ *
+ * @brief Initialized CEE DMA Memory
+ *
+ * @param[in] cee CEE module pointer
+ * dma_kva Kernel Virtual Address of CEE DMA Memory
+ * dma_pa Physical Address of CEE DMA Memory
+ *
+ * @return void
+ */
+void
+bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa)
+{
+ cee->attr_dma.kva = dma_kva;
+ cee->attr_dma.pa = dma_pa;
+ cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
+ cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
+ cee->attr = (struct bfa_cee_attr *) dma_kva;
+ cee->stats = (struct bfa_cee_stats *)
+ (dma_kva + bfa_cee_attr_meminfo());
+}
+
+/**
+ * bfa_cee_isrs()
+ *
+ * @brief Handles Mail-box interrupts for CEE module.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+static void
+bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
+{
+ union bfi_cee_i2h_msg_u *msg;
+ struct bfi_cee_get_rsp *get_rsp;
+ struct bfa_cee *cee = (struct bfa_cee *) cbarg;
+ msg = (union bfi_cee_i2h_msg_u *) m;
+ get_rsp = (struct bfi_cee_get_rsp *) m;
+ switch (msg->mh.msg_id) {
+ case BFI_CEE_I2H_GET_CFG_RSP:
+ bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_GET_STATS_RSP:
+ bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ case BFI_CEE_I2H_RESET_STATS_RSP:
+ bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
+ break;
+ default:
+ BUG_ON(1);
+ }
+}
+
+/**
+ * bfa_cee_hbfail()
+ *
+ * @brief CEE module heart-beat failure handler.
+ *
+ * @param[in] Pointer to the CEE module data structure.
+ *
+ * @return void
+ */
+
+static void
+bfa_cee_hbfail(void *arg)
+{
+ struct bfa_cee *cee;
+ cee = (struct bfa_cee *) arg;
+
+ if (cee->get_attr_pending == true) {
+ cee->get_attr_status = BFA_STATUS_FAILED;
+ cee->get_attr_pending = false;
+ if (cee->cbfn.get_attr_cbfn) {
+ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+ if (cee->get_stats_pending == true) {
+ cee->get_stats_status = BFA_STATUS_FAILED;
+ cee->get_stats_pending = false;
+ if (cee->cbfn.get_stats_cbfn) {
+ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+ if (cee->reset_stats_pending == true) {
+ cee->reset_stats_status = BFA_STATUS_FAILED;
+ cee->reset_stats_pending = false;
+ if (cee->cbfn.reset_stats_cbfn) {
+ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
+ BFA_STATUS_FAILED);
+ }
+ }
+}
+
+/**
+ * bfa_nw_cee_attach()
+ *
+ * @brief CEE module-attach API
+ *
+ * @param[in] cee - Pointer to the CEE module data structure
+ * ioc - Pointer to the ioc module data structure
+ * dev - Pointer to the device driver module data structure
+ * The device driver specific mbox ISR functions have
+ * this pointer as one of the parameters.
+ *
+ * @return void
+ */
+void
+bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
+ void *dev)
+{
+ BUG_ON(!(cee != NULL));
+ cee->dev = dev;
+ cee->ioc = ioc;
+
+ bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
+ bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
+ bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail);
+}
diff --git a/drivers/net/bna/bfa_cee.h b/drivers/net/bna/bfa_cee.h
new file mode 100644
index 000000000000..20543d15b64f
--- /dev/null
+++ b/drivers/net/bna/bfa_cee.h
@@ -0,0 +1,64 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_CEE_H__
+#define __BFA_CEE_H__
+
+#include "bfa_defs_cna.h"
+#include "bfa_ioc.h"
+
+typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status);
+typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status);
+
+struct bfa_cee_cbfn {
+ bfa_cee_get_attr_cbfn_t get_attr_cbfn;
+ void *get_attr_cbarg;
+ bfa_cee_get_stats_cbfn_t get_stats_cbfn;
+ void *get_stats_cbarg;
+ bfa_cee_reset_stats_cbfn_t reset_stats_cbfn;
+ void *reset_stats_cbarg;
+};
+
+struct bfa_cee {
+ void *dev;
+ bool get_attr_pending;
+ bool get_stats_pending;
+ bool reset_stats_pending;
+ enum bfa_status get_attr_status;
+ enum bfa_status get_stats_status;
+ enum bfa_status reset_stats_status;
+ struct bfa_cee_cbfn cbfn;
+ struct bfa_ioc_hbfail_notify hbfail;
+ struct bfa_cee_attr *attr;
+ struct bfa_cee_stats *stats;
+ struct bfa_dma attr_dma;
+ struct bfa_dma stats_dma;
+ struct bfa_ioc *ioc;
+ struct bfa_mbox_cmd get_cfg_mb;
+ struct bfa_mbox_cmd get_stats_mb;
+ struct bfa_mbox_cmd reset_stats_mb;
+};
+
+u32 bfa_nw_cee_meminfo(void);
+void bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva,
+ u64 dma_pa);
+void bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev);
+
+#endif /* __BFA_CEE_H__ */
diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h
new file mode 100644
index 000000000000..29c1b8de2c2d
--- /dev/null
+++ b/drivers/net/bna/bfa_defs.h
@@ -0,0 +1,243 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_DEFS_H__
+#define __BFA_DEFS_H__
+
+#include "cna.h"
+#include "bfa_defs_status.h"
+#include "bfa_defs_mfg_comm.h"
+
+#define BFA_STRING_32 32
+#define BFA_VERSION_LEN 64
+
+/**
+ * ---------------------- adapter definitions ------------
+ */
+
+/**
+ * BFA adapter level attributes.
+ */
+enum {
+ BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE),
+ /*
+ *!< adapter serial num length
+ */
+ BFA_ADAPTER_MODEL_NAME_LEN = 16, /*!< model name length */
+ BFA_ADAPTER_MODEL_DESCR_LEN = 128, /*!< model description length */
+ BFA_ADAPTER_MFG_NAME_LEN = 8, /*!< manufacturer name length */
+ BFA_ADAPTER_SYM_NAME_LEN = 64, /*!< adapter symbolic name length */
+ BFA_ADAPTER_OS_TYPE_LEN = 64, /*!< adapter os type length */
+};
+
+struct bfa_adapter_attr {
+ char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+ u32 card_type;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN];
+ char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
+ u64 pwwn;
+ char node_symname[FC_SYMNAME_MAX];
+ char hw_ver[BFA_VERSION_LEN];
+ char fw_ver[BFA_VERSION_LEN];
+ char optrom_ver[BFA_VERSION_LEN];
+ char os_type[BFA_ADAPTER_OS_TYPE_LEN];
+ struct bfa_mfg_vpd vpd;
+ struct mac mac;
+
+ u8 nports;
+ u8 max_speed;
+ u8 prototype;
+ char asic_rev;
+
+ u8 pcie_gen;
+ u8 pcie_lanes_orig;
+ u8 pcie_lanes;
+ u8 cna_capable;
+
+ u8 is_mezz;
+ u8 trunk_capable;
+};
+
+/**
+ * ---------------------- IOC definitions ------------
+ */
+
+enum {
+ BFA_IOC_DRIVER_LEN = 16,
+ BFA_IOC_CHIP_REV_LEN = 8,
+};
+
+/**
+ * Driver and firmware versions.
+ */
+struct bfa_ioc_driver_attr {
+ char driver[BFA_IOC_DRIVER_LEN]; /*!< driver name */
+ char driver_ver[BFA_VERSION_LEN]; /*!< driver version */
+ char fw_ver[BFA_VERSION_LEN]; /*!< firmware version */
+ char bios_ver[BFA_VERSION_LEN]; /*!< bios version */
+ char efi_ver[BFA_VERSION_LEN]; /*!< EFI version */
+ char ob_ver[BFA_VERSION_LEN]; /*!< openboot version */
+};
+
+/**
+ * IOC PCI device attributes
+ */
+struct bfa_ioc_pci_attr {
+ u16 vendor_id; /*!< PCI vendor ID */
+ u16 device_id; /*!< PCI device ID */
+ u16 ssid; /*!< subsystem ID */
+ u16 ssvid; /*!< subsystem vendor ID */
+ u32 pcifn; /*!< PCI device function */
+ u32 rsvd; /* padding */
+ char chip_rev[BFA_IOC_CHIP_REV_LEN]; /*!< chip revision */
+};
+
+/**
+ * IOC states
+ */
+enum bfa_ioc_state {
+ BFA_IOC_RESET = 1, /*!< IOC is in reset state */
+ BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */
+ BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */
+ BFA_IOC_GETATTR = 4, /*!< IOC is being configured */
+ BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */
+ BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */
+ BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */
+ BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */
+ BFA_IOC_DISABLED = 9, /*!< IOC is disabled */
+ BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */
+};
+
+/**
+ * IOC firmware stats
+ */
+struct bfa_fw_ioc_stats {
+ u32 enable_reqs;
+ u32 disable_reqs;
+ u32 get_attr_reqs;
+ u32 dbg_sync;
+ u32 dbg_dump;
+ u32 unknown_reqs;
+};
+
+/**
+ * IOC driver stats
+ */
+struct bfa_ioc_drv_stats {
+ u32 ioc_isrs;
+ u32 ioc_enables;
+ u32 ioc_disables;
+ u32 ioc_hbfails;
+ u32 ioc_boots;
+ u32 stats_tmos;
+ u32 hb_count;
+ u32 disable_reqs;
+ u32 enable_reqs;
+ u32 disable_replies;
+ u32 enable_replies;
+};
+
+/**
+ * IOC statistics
+ */
+struct bfa_ioc_stats {
+ struct bfa_ioc_drv_stats drv_stats; /*!< driver IOC stats */
+ struct bfa_fw_ioc_stats fw_stats; /*!< firmware IOC stats */
+};
+
+enum bfa_ioc_type {
+ BFA_IOC_TYPE_FC = 1,
+ BFA_IOC_TYPE_FCoE = 2,
+ BFA_IOC_TYPE_LL = 3,
+};
+
+/**
+ * IOC attributes returned in queries
+ */
+struct bfa_ioc_attr {
+ enum bfa_ioc_type ioc_type;
+ enum bfa_ioc_state state; /*!< IOC state */
+ struct bfa_adapter_attr adapter_attr; /*!< HBA attributes */
+ struct bfa_ioc_driver_attr driver_attr; /*!< driver attr */
+ struct bfa_ioc_pci_attr pci_attr;
+ u8 port_id; /*!< port number */
+ u8 rsvd[7]; /*!< 64bit align */
+};
+
+/**
+ * ---------------------- mfg definitions ------------
+ */
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE 16
+
+#define BFA_MFG_PARTNUM_SIZE 14
+#define BFA_MFG_SUPPLIER_ID_SIZE 10
+#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
+#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
+
+#pragma pack(1)
+
+/**
+ * @brief BFA adapter manufacturing block definition.
+ *
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_block {
+ u8 version; /*!< manufacturing block version */
+ u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */
+ u16 mfgsize; /*!< mfg block size */
+ u16 u16_chksum; /*!< old u16 checksum */
+ char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
+ char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)];
+ u8 mfg_day; /*!< manufacturing day */
+ u8 mfg_month; /*!< manufacturing month */
+ u16 mfg_year; /*!< manufacturing year */
+ u64 mfg_wwn; /*!< wwn base for this adapter */
+ u8 num_wwn; /*!< number of wwns assigned */
+ u8 mfg_speeds; /*!< speeds allowed for this adapter */
+ u8 rsv[2];
+ char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)];
+ char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)];
+ char
+ supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)];
+ char
+ supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)];
+ mac_t mfg_mac; /*!< mac address */
+ u8 num_mac; /*!< number of mac addresses */
+ u8 rsv2;
+ u32 mfg_type; /*!< card type */
+ u8 rsv3[108];
+ u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */
+};
+
+#pragma pack()
+
+/**
+ * ---------------------- pci definitions ------------
+ */
+
+#define bfa_asic_id_ct(devid) \
+ ((devid) == PCI_DEVICE_ID_BROCADE_CT || \
+ (devid) == PCI_DEVICE_ID_BROCADE_CT_FC)
+
+#endif /* __BFA_DEFS_H__ */
diff --git a/drivers/net/bna/bfa_defs_cna.h b/drivers/net/bna/bfa_defs_cna.h
new file mode 100644
index 000000000000..7e0a9187bdd5
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_cna.h
@@ -0,0 +1,223 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_DEFS_CNA_H__
+#define __BFA_DEFS_CNA_H__
+
+#include "bfa_defs.h"
+
+/**
+ * @brief
+ * FC physical port statistics.
+ */
+struct bfa_port_fc_stats {
+ u64 secs_reset; /*!< Seconds since stats is reset */
+ u64 tx_frames; /*!< Tx frames */
+ u64 tx_words; /*!< Tx words */
+ u64 tx_lip; /*!< Tx LIP */
+ u64 tx_nos; /*!< Tx NOS */
+ u64 tx_ols; /*!< Tx OLS */
+ u64 tx_lr; /*!< Tx LR */
+ u64 tx_lrr; /*!< Tx LRR */
+ u64 rx_frames; /*!< Rx frames */
+ u64 rx_words; /*!< Rx words */
+ u64 lip_count; /*!< Rx LIP */
+ u64 nos_count; /*!< Rx NOS */
+ u64 ols_count; /*!< Rx OLS */
+ u64 lr_count; /*!< Rx LR */
+ u64 lrr_count; /*!< Rx LRR */
+ u64 invalid_crcs; /*!< Rx CRC err frames */
+ u64 invalid_crc_gd_eof; /*!< Rx CRC err good EOF frames */
+ u64 undersized_frm; /*!< Rx undersized frames */
+ u64 oversized_frm; /*!< Rx oversized frames */
+ u64 bad_eof_frm; /*!< Rx frames with bad EOF */
+ u64 error_frames; /*!< Errored frames */
+ u64 dropped_frames; /*!< Dropped frames */
+ u64 link_failures; /*!< Link Failure (LF) count */
+ u64 loss_of_syncs; /*!< Loss of sync count */
+ u64 loss_of_signals; /*!< Loss of signal count */
+ u64 primseq_errs; /*!< Primitive sequence protocol err. */
+ u64 bad_os_count; /*!< Invalid ordered sets */
+ u64 err_enc_out; /*!< Encoding err nonframe_8b10b */
+ u64 err_enc; /*!< Encoding err frame_8b10b */
+};
+
+/**
+ * @brief
+ * Eth Physical Port statistics.
+ */
+struct bfa_port_eth_stats {
+ u64 secs_reset; /*!< Seconds since stats is reset */
+ u64 frame_64; /*!< Frames 64 bytes */
+ u64 frame_65_127; /*!< Frames 65-127 bytes */
+ u64 frame_128_255; /*!< Frames 128-255 bytes */
+ u64 frame_256_511; /*!< Frames 256-511 bytes */
+ u64 frame_512_1023; /*!< Frames 512-1023 bytes */
+ u64 frame_1024_1518; /*!< Frames 1024-1518 bytes */
+ u64 frame_1519_1522; /*!< Frames 1519-1522 bytes */
+ u64 tx_bytes; /*!< Tx bytes */
+ u64 tx_packets; /*!< Tx packets */
+ u64 tx_mcast_packets; /*!< Tx multicast packets */
+ u64 tx_bcast_packets; /*!< Tx broadcast packets */
+ u64 tx_control_frame; /*!< Tx control frame */
+ u64 tx_drop; /*!< Tx drops */
+ u64 tx_jabber; /*!< Tx jabber */
+ u64 tx_fcs_error; /*!< Tx FCS errors */
+ u64 tx_fragments; /*!< Tx fragments */
+ u64 rx_bytes; /*!< Rx bytes */
+ u64 rx_packets; /*!< Rx packets */
+ u64 rx_mcast_packets; /*!< Rx multicast packets */
+ u64 rx_bcast_packets; /*!< Rx broadcast packets */
+ u64 rx_control_frames; /*!< Rx control frames */
+ u64 rx_unknown_opcode; /*!< Rx unknown opcode */
+ u64 rx_drop; /*!< Rx drops */
+ u64 rx_jabber; /*!< Rx jabber */
+ u64 rx_fcs_error; /*!< Rx FCS errors */
+ u64 rx_alignment_error; /*!< Rx alignment errors */
+ u64 rx_frame_length_error; /*!< Rx frame len errors */
+ u64 rx_code_error; /*!< Rx code errors */
+ u64 rx_fragments; /*!< Rx fragments */
+ u64 rx_pause; /*!< Rx pause */
+ u64 rx_zero_pause; /*!< Rx zero pause */
+ u64 tx_pause; /*!< Tx pause */
+ u64 tx_zero_pause; /*!< Tx zero pause */
+ u64 rx_fcoe_pause; /*!< Rx FCoE pause */
+ u64 rx_fcoe_zero_pause; /*!< Rx FCoE zero pause */
+ u64 tx_fcoe_pause; /*!< Tx FCoE pause */
+ u64 tx_fcoe_zero_pause; /*!< Tx FCoE zero pause */
+};
+
+/**
+ * @brief
+ * Port statistics.
+ */
+union bfa_port_stats_u {
+ struct bfa_port_fc_stats fc;
+ struct bfa_port_eth_stats eth;
+};
+
+#pragma pack(1)
+
+#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
+#define BFA_CEE_DCBX_MAX_PRIORITY (8)
+#define BFA_CEE_DCBX_MAX_PGID (8)
+
+#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
+#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
+#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
+#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008
+#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010
+#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020
+#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040
+#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080
+#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100
+#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200
+#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400
+
+/* LLDP string type */
+struct bfa_cee_lldp_str {
+ u8 sub_type;
+ u8 len;
+ u8 rsvd[2];
+ u8 value[BFA_CEE_LLDP_MAX_STRING_LEN];
+};
+
+/* LLDP paramters */
+struct bfa_cee_lldp_cfg {
+ struct bfa_cee_lldp_str chassis_id;
+ struct bfa_cee_lldp_str port_id;
+ struct bfa_cee_lldp_str port_desc;
+ struct bfa_cee_lldp_str sys_name;
+ struct bfa_cee_lldp_str sys_desc;
+ struct bfa_cee_lldp_str mgmt_addr;
+ u16 time_to_live;
+ u16 enabled_system_cap;
+};
+
+enum bfa_cee_dcbx_version {
+ DCBX_PROTOCOL_PRECEE = 1,
+ DCBX_PROTOCOL_CEE = 2,
+};
+
+enum bfa_cee_lls {
+ /* LLS is down because the TLV not sent by the peer */
+ CEE_LLS_DOWN_NO_TLV = 0,
+ /* LLS is down as advertised by the peer */
+ CEE_LLS_DOWN = 1,
+ CEE_LLS_UP = 2,
+};
+
+/* CEE/DCBX parameters */
+struct bfa_cee_dcbx_cfg {
+ u8 pgid[BFA_CEE_DCBX_MAX_PRIORITY];
+ u8 pg_percentage[BFA_CEE_DCBX_MAX_PGID];
+ u8 pfc_primap; /* bitmap of priorties with PFC enabled */
+ u8 fcoe_primap; /* bitmap of priorities used for FcoE traffic */
+ u8 iscsi_primap; /* bitmap of priorities used for iSCSI traffic */
+ u8 dcbx_version; /* operating version:CEE or preCEE */
+ u8 lls_fcoe; /* FCoE Logical Link Status */
+ u8 lls_lan; /* LAN Logical Link Status */
+ u8 rsvd[2];
+};
+
+/* CEE status */
+/* Making this to tri-state for the benefit of port list command */
+enum bfa_cee_status {
+ CEE_UP = 0,
+ CEE_PHY_UP = 1,
+ CEE_LOOPBACK = 2,
+ CEE_PHY_DOWN = 3,
+};
+
+/* CEE Query */
+struct bfa_cee_attr {
+ u8 cee_status;
+ u8 error_reason;
+ struct bfa_cee_lldp_cfg lldp_remote;
+ struct bfa_cee_dcbx_cfg dcbx_remote;
+ mac_t src_mac;
+ u8 link_speed;
+ u8 nw_priority;
+ u8 filler[2];
+};
+
+/* LLDP/DCBX/CEE Statistics */
+struct bfa_cee_stats {
+ u32 lldp_tx_frames; /*!< LLDP Tx Frames */
+ u32 lldp_rx_frames; /*!< LLDP Rx Frames */
+ u32 lldp_rx_frames_invalid; /*!< LLDP Rx Frames invalid */
+ u32 lldp_rx_frames_new; /*!< LLDP Rx Frames new */
+ u32 lldp_tlvs_unrecognized; /*!< LLDP Rx unrecognized TLVs */
+ u32 lldp_rx_shutdown_tlvs; /*!< LLDP Rx shutdown TLVs */
+ u32 lldp_info_aged_out; /*!< LLDP remote info aged out */
+ u32 dcbx_phylink_ups; /*!< DCBX phy link ups */
+ u32 dcbx_phylink_downs; /*!< DCBX phy link downs */
+ u32 dcbx_rx_tlvs; /*!< DCBX Rx TLVs */
+ u32 dcbx_rx_tlvs_invalid; /*!< DCBX Rx TLVs invalid */
+ u32 dcbx_control_tlv_error; /*!< DCBX control TLV errors */
+ u32 dcbx_feature_tlv_error; /*!< DCBX feature TLV errors */
+ u32 dcbx_cee_cfg_new; /*!< DCBX new CEE cfg rcvd */
+ u32 cee_status_down; /*!< CEE status down */
+ u32 cee_status_up; /*!< CEE status up */
+ u32 cee_hw_cfg_changed; /*!< CEE hw cfg changed */
+ u32 cee_rx_invalid_cfg; /*!< CEE invalid cfg */
+};
+
+#pragma pack()
+
+#endif /* __BFA_DEFS_CNA_H__ */
diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h
new file mode 100644
index 000000000000..987978fcb3fe
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_mfg_comm.h
@@ -0,0 +1,244 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFA_DEFS_MFG_COMM_H__
+#define __BFA_DEFS_MFG_COMM_H__
+
+#include "cna.h"
+
+/**
+ * Manufacturing block version
+ */
+#define BFA_MFG_VERSION 2
+#define BFA_MFG_VERSION_UNINIT 0xFF
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER 2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN 128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN 4
+
+#define BFA_MFG_SERIALNUM_SIZE 11
+#define STRSZ(_n) (((_n) + 4) & ~3)
+
+/**
+ * Manufacturing card type
+ */
+enum {
+ BFA_MFG_TYPE_CB_MAX = 825, /*!< Crossbow card type max */
+ BFA_MFG_TYPE_FC8P2 = 825, /*!< 8G 2port FC card */
+ BFA_MFG_TYPE_FC8P1 = 815, /*!< 8G 1port FC card */
+ BFA_MFG_TYPE_FC4P2 = 425, /*!< 4G 2port FC card */
+ BFA_MFG_TYPE_FC4P1 = 415, /*!< 4G 1port FC card */
+ BFA_MFG_TYPE_CNA10P2 = 1020, /*!< 10G 2port CNA card */
+ BFA_MFG_TYPE_CNA10P1 = 1010, /*!< 10G 1port CNA card */
+ BFA_MFG_TYPE_JAYHAWK = 804, /*!< Jayhawk mezz card */
+ BFA_MFG_TYPE_WANCHESE = 1007, /*!< Wanchese mezz card */
+ BFA_MFG_TYPE_ASTRA = 807, /*!< Astra mezz card */
+ BFA_MFG_TYPE_LIGHTNING_P0 = 902, /*!< Lightning mezz card - old */
+ BFA_MFG_TYPE_LIGHTNING = 1741, /*!< Lightning mezz card */
+ BFA_MFG_TYPE_INVALID = 0, /*!< Invalid card type */
+};
+
+#pragma pack(1)
+
+/**
+ * Check if 1-port card
+ */
+#define bfa_mfg_is_1port(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P1))
+
+/**
+ * Check if Mezz card
+ */
+#define bfa_mfg_is_mezz(type) (( \
+ (type) == BFA_MFG_TYPE_JAYHAWK || \
+ (type) == BFA_MFG_TYPE_WANCHESE || \
+ (type) == BFA_MFG_TYPE_ASTRA || \
+ (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \
+ (type) == BFA_MFG_TYPE_LIGHTNING))
+
+/**
+ * Check if card type valid
+ */
+#define bfa_mfg_is_card_type_valid(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P2 || \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P2 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P2 || \
+ (type) == BFA_MFG_TYPE_CNA10P1 || \
+ bfa_mfg_is_mezz(type)))
+
+/**
+ * Check if the card having old wwn/mac handling
+ */
+#define bfa_mfg_is_old_wwn_mac_model(type) (( \
+ (type) == BFA_MFG_TYPE_FC8P2 || \
+ (type) == BFA_MFG_TYPE_FC8P1 || \
+ (type) == BFA_MFG_TYPE_FC4P2 || \
+ (type) == BFA_MFG_TYPE_FC4P1 || \
+ (type) == BFA_MFG_TYPE_CNA10P2 || \
+ (type) == BFA_MFG_TYPE_CNA10P1 || \
+ (type) == BFA_MFG_TYPE_JAYHAWK || \
+ (type) == BFA_MFG_TYPE_WANCHESE))
+
+#define bfa_mfg_increment_wwn_mac(m, i) \
+do { \
+ u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \
+ t += (i); \
+ (m)[0] = (t >> 16) & 0xFF; \
+ (m)[1] = (t >> 8) & 0xFF; \
+ (m)[2] = t & 0xFF; \
+} while (0)
+
+#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \
+do { \
+ switch ((card_type)) { \
+ case BFA_MFG_TYPE_FC8P2: \
+ case BFA_MFG_TYPE_JAYHAWK: \
+ case BFA_MFG_TYPE_ASTRA: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 8); \
+ break; \
+ case BFA_MFG_TYPE_FC8P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
+ BFI_ADAPTER_SETP(SPEED, 8); \
+ break; \
+ case BFA_MFG_TYPE_FC4P2: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \
+ BFI_ADAPTER_SETP(SPEED, 4); \
+ break; \
+ case BFA_MFG_TYPE_FC4P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \
+ BFI_ADAPTER_SETP(SPEED, 4); \
+ break; \
+ case BFA_MFG_TYPE_CNA10P2: \
+ case BFA_MFG_TYPE_WANCHESE: \
+ case BFA_MFG_TYPE_LIGHTNING_P0: \
+ case BFA_MFG_TYPE_LIGHTNING: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ break; \
+ case BFA_MFG_TYPE_CNA10P1: \
+ (prop) = BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \
+ break; \
+ default: \
+ (prop) = BFI_ADAPTER_UNSUPP; \
+ } \
+} while (0)
+
+enum {
+ CB_GPIO_TTV = (1), /*!< TTV debug capable cards */
+ CB_GPIO_FC8P2 = (2), /*!< 8G 2port FC card */
+ CB_GPIO_FC8P1 = (3), /*!< 8G 1port FC card */
+ CB_GPIO_FC4P2 = (4), /*!< 4G 2port FC card */
+ CB_GPIO_FC4P1 = (5), /*!< 4G 1port FC card */
+ CB_GPIO_DFLY = (6), /*!< 8G 2port FC mezzanine card */
+ CB_GPIO_PROTO = (1 << 7) /*!< 8G 2port FC prototypes */
+};
+
+#define bfa_mfg_adapter_prop_init_gpio(gpio, card_type, prop) \
+do { \
+ if ((gpio) & CB_GPIO_PROTO) { \
+ (prop) |= BFI_ADAPTER_PROTO; \
+ (gpio) &= ~CB_GPIO_PROTO; \
+ } \
+ switch ((gpio)) { \
+ case CB_GPIO_TTV: \
+ (prop) |= BFI_ADAPTER_TTV; \
+ case CB_GPIO_DFLY: \
+ case CB_GPIO_FC8P2: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \
+ (card_type) = BFA_MFG_TYPE_FC8P2; \
+ break; \
+ case CB_GPIO_FC8P1: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \
+ (card_type) = BFA_MFG_TYPE_FC8P1; \
+ break; \
+ case CB_GPIO_FC4P2: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \
+ (card_type) = BFA_MFG_TYPE_FC4P2; \
+ break; \
+ case CB_GPIO_FC4P1: \
+ (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \
+ (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \
+ (card_type) = BFA_MFG_TYPE_FC4P1; \
+ break; \
+ default: \
+ (prop) |= BFI_ADAPTER_UNSUPP; \
+ (card_type) = BFA_MFG_TYPE_INVALID; \
+ } \
+} while (0)
+
+/**
+ * VPD data length
+ */
+#define BFA_MFG_VPD_LEN 512
+#define BFA_MFG_VPD_LEN_INVALID 0
+
+#define BFA_MFG_VPD_PCI_HDR_OFF 137
+#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /*!< version mask 3 bits */
+#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /*!< vendor mask 5 bits */
+
+/**
+ * VPD vendor tag
+ */
+enum {
+ BFA_MFG_VPD_UNKNOWN = 0, /*!< vendor unknown */
+ BFA_MFG_VPD_IBM = 1, /*!< vendor IBM */
+ BFA_MFG_VPD_HP = 2, /*!< vendor HP */
+ BFA_MFG_VPD_DELL = 3, /*!< vendor DELL */
+ BFA_MFG_VPD_PCI_IBM = 0x08, /*!< PCI VPD IBM */
+ BFA_MFG_VPD_PCI_HP = 0x10, /*!< PCI VPD HP */
+ BFA_MFG_VPD_PCI_DELL = 0x20, /*!< PCI VPD DELL */
+ BFA_MFG_VPD_PCI_BRCD = 0xf8, /*!< PCI VPD Brocade */
+};
+
+/**
+ * @brief BFA adapter flash vpd data definition.
+ *
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_vpd {
+ u8 version; /*!< vpd data version */
+ u8 vpd_sig[3]; /*!< characters 'V', 'P', 'D' */
+ u8 chksum; /*!< u8 checksum */
+ u8 vendor; /*!< vendor */
+ u8 len; /*!< vpd data length excluding header */
+ u8 rsv;
+ u8 data[BFA_MFG_VPD_LEN]; /*!< vpd data */
+};
+
+#pragma pack()
+
+#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/net/bna/bfa_defs_status.h b/drivers/net/bna/bfa_defs_status.h
new file mode 100644
index 000000000000..af951126375c
--- /dev/null
+++ b/drivers/net/bna/bfa_defs_status.h
@@ -0,0 +1,216 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFA_DEFS_STATUS_H__
+#define __BFA_DEFS_STATUS_H__
+
+/**
+ * API status return values
+ *
+ * NOTE: The error msgs are auto generated from the comments. Only singe line
+ * comments are supported
+ */
+enum bfa_status {
+ BFA_STATUS_OK = 0,
+ BFA_STATUS_FAILED = 1,
+ BFA_STATUS_EINVAL = 2,
+ BFA_STATUS_ENOMEM = 3,
+ BFA_STATUS_ENOSYS = 4,
+ BFA_STATUS_ETIMER = 5,
+ BFA_STATUS_EPROTOCOL = 6,
+ BFA_STATUS_ENOFCPORTS = 7,
+ BFA_STATUS_NOFLASH = 8,
+ BFA_STATUS_BADFLASH = 9,
+ BFA_STATUS_SFP_UNSUPP = 10,
+ BFA_STATUS_UNKNOWN_VFID = 11,
+ BFA_STATUS_DATACORRUPTED = 12,
+ BFA_STATUS_DEVBUSY = 13,
+ BFA_STATUS_ABORTED = 14,
+ BFA_STATUS_NODEV = 15,
+ BFA_STATUS_HDMA_FAILED = 16,
+ BFA_STATUS_FLASH_BAD_LEN = 17,
+ BFA_STATUS_UNKNOWN_LWWN = 18,
+ BFA_STATUS_UNKNOWN_RWWN = 19,
+ BFA_STATUS_FCPT_LS_RJT = 20,
+ BFA_STATUS_VPORT_EXISTS = 21,
+ BFA_STATUS_VPORT_MAX = 22,
+ BFA_STATUS_UNSUPP_SPEED = 23,
+ BFA_STATUS_INVLD_DFSZ = 24,
+ BFA_STATUS_CNFG_FAILED = 25,
+ BFA_STATUS_CMD_NOTSUPP = 26,
+ BFA_STATUS_NO_ADAPTER = 27,
+ BFA_STATUS_LINKDOWN = 28,
+ BFA_STATUS_FABRIC_RJT = 29,
+ BFA_STATUS_UNKNOWN_VWWN = 30,
+ BFA_STATUS_NSLOGIN_FAILED = 31,
+ BFA_STATUS_NO_RPORTS = 32,
+ BFA_STATUS_NSQUERY_FAILED = 33,
+ BFA_STATUS_PORT_OFFLINE = 34,
+ BFA_STATUS_RPORT_OFFLINE = 35,
+ BFA_STATUS_TGTOPEN_FAILED = 36,
+ BFA_STATUS_BAD_LUNS = 37,
+ BFA_STATUS_IO_FAILURE = 38,
+ BFA_STATUS_NO_FABRIC = 39,
+ BFA_STATUS_EBADF = 40,
+ BFA_STATUS_EINTR = 41,
+ BFA_STATUS_EIO = 42,
+ BFA_STATUS_ENOTTY = 43,
+ BFA_STATUS_ENXIO = 44,
+ BFA_STATUS_EFOPEN = 45,
+ BFA_STATUS_VPORT_WWN_BP = 46,
+ BFA_STATUS_PORT_NOT_DISABLED = 47,
+ BFA_STATUS_BADFRMHDR = 48,
+ BFA_STATUS_BADFRMSZ = 49,
+ BFA_STATUS_MISSINGFRM = 50,
+ BFA_STATUS_LINKTIMEOUT = 51,
+ BFA_STATUS_NO_FCPIM_NEXUS = 52,
+ BFA_STATUS_CHECKSUM_FAIL = 53,
+ BFA_STATUS_GZME_FAILED = 54,
+ BFA_STATUS_SCSISTART_REQD = 55,
+ BFA_STATUS_IOC_FAILURE = 56,
+ BFA_STATUS_INVALID_WWN = 57,
+ BFA_STATUS_MISMATCH = 58,
+ BFA_STATUS_IOC_ENABLED = 59,
+ BFA_STATUS_ADAPTER_ENABLED = 60,
+ BFA_STATUS_IOC_NON_OP = 61,
+ BFA_STATUS_ADDR_MAP_FAILURE = 62,
+ BFA_STATUS_SAME_NAME = 63,
+ BFA_STATUS_PENDING = 64,
+ BFA_STATUS_8G_SPD = 65,
+ BFA_STATUS_4G_SPD = 66,
+ BFA_STATUS_AD_IS_ENABLE = 67,
+ BFA_STATUS_EINVAL_TOV = 68,
+ BFA_STATUS_EINVAL_QDEPTH = 69,
+ BFA_STATUS_VERSION_FAIL = 70,
+ BFA_STATUS_DIAG_BUSY = 71,
+ BFA_STATUS_BEACON_ON = 72,
+ BFA_STATUS_BEACON_OFF = 73,
+ BFA_STATUS_LBEACON_ON = 74,
+ BFA_STATUS_LBEACON_OFF = 75,
+ BFA_STATUS_PORT_NOT_INITED = 76,
+ BFA_STATUS_RPSC_ENABLED = 77,
+ BFA_STATUS_ENOFSAVE = 78,
+ BFA_STATUS_BAD_FILE = 79,
+ BFA_STATUS_RLIM_EN = 80,
+ BFA_STATUS_RLIM_DIS = 81,
+ BFA_STATUS_IOC_DISABLED = 82,
+ BFA_STATUS_ADAPTER_DISABLED = 83,
+ BFA_STATUS_BIOS_DISABLED = 84,
+ BFA_STATUS_AUTH_ENABLED = 85,
+ BFA_STATUS_AUTH_DISABLED = 86,
+ BFA_STATUS_ERROR_TRL_ENABLED = 87,
+ BFA_STATUS_ERROR_QOS_ENABLED = 88,
+ BFA_STATUS_NO_SFP_DEV = 89,
+ BFA_STATUS_MEMTEST_FAILED = 90,
+ BFA_STATUS_INVALID_DEVID = 91,
+ BFA_STATUS_QOS_ENABLED = 92,
+ BFA_STATUS_QOS_DISABLED = 93,
+ BFA_STATUS_INCORRECT_DRV_CONFIG = 94,
+ BFA_STATUS_REG_FAIL = 95,
+ BFA_STATUS_IM_INV_CODE = 96,
+ BFA_STATUS_IM_INV_VLAN = 97,
+ BFA_STATUS_IM_INV_ADAPT_NAME = 98,
+ BFA_STATUS_IM_LOW_RESOURCES = 99,
+ BFA_STATUS_IM_VLANID_IS_PVID = 100,
+ BFA_STATUS_IM_VLANID_EXISTS = 101,
+ BFA_STATUS_IM_FW_UPDATE_FAIL = 102,
+ BFA_STATUS_PORTLOG_ENABLED = 103,
+ BFA_STATUS_PORTLOG_DISABLED = 104,
+ BFA_STATUS_FILE_NOT_FOUND = 105,
+ BFA_STATUS_QOS_FC_ONLY = 106,
+ BFA_STATUS_RLIM_FC_ONLY = 107,
+ BFA_STATUS_CT_SPD = 108,
+ BFA_STATUS_LEDTEST_OP = 109,
+ BFA_STATUS_CEE_NOT_DN = 110,
+ BFA_STATUS_10G_SPD = 111,
+ BFA_STATUS_IM_INV_TEAM_NAME = 112,
+ BFA_STATUS_IM_DUP_TEAM_NAME = 113,
+ BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114,
+ BFA_STATUS_IM_ADAPT_HAS_VLANS = 115,
+ BFA_STATUS_IM_PVID_MISMATCH = 116,
+ BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117,
+ BFA_STATUS_IM_MTU_MISMATCH = 118,
+ BFA_STATUS_IM_RSS_MISMATCH = 119,
+ BFA_STATUS_IM_HDS_MISMATCH = 120,
+ BFA_STATUS_IM_OFFLOAD_MISMATCH = 121,
+ BFA_STATUS_IM_PORT_PARAMS = 122,
+ BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123,
+ BFA_STATUS_IM_CANNOT_REM_PRI = 124,
+ BFA_STATUS_IM_MAX_PORTS_REACHED = 125,
+ BFA_STATUS_IM_LAST_PORT_DELETE = 126,
+ BFA_STATUS_IM_NO_DRIVER = 127,
+ BFA_STATUS_IM_MAX_VLANS_REACHED = 128,
+ BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129,
+ BFA_STATUS_NO_MINPORT_DRIVER = 130,
+ BFA_STATUS_CARD_TYPE_MISMATCH = 131,
+ BFA_STATUS_BAD_ASICBLK = 132,
+ BFA_STATUS_NO_DRIVER = 133,
+ BFA_STATUS_INVALID_MAC = 134,
+ BFA_STATUS_IM_NO_VLAN = 135,
+ BFA_STATUS_IM_ETH_LB_FAILED = 136,
+ BFA_STATUS_IM_PVID_REMOVE = 137,
+ BFA_STATUS_IM_PVID_EDIT = 138,
+ BFA_STATUS_CNA_NO_BOOT = 139,
+ BFA_STATUS_IM_PVID_NON_ZERO = 140,
+ BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141,
+ BFA_STATUS_IM_GET_INETCFG_FAILED = 142,
+ BFA_STATUS_IM_NOT_BOUND = 143,
+ BFA_STATUS_INSUFFICIENT_PERMS = 144,
+ BFA_STATUS_IM_INV_VLAN_NAME = 145,
+ BFA_STATUS_CMD_NOTSUPP_CNA = 146,
+ BFA_STATUS_IM_PASSTHRU_EDIT = 147,
+ BFA_STATUS_IM_BIND_FAILED = 148,
+ BFA_STATUS_IM_UNBIND_FAILED = 149,
+ BFA_STATUS_IM_PORT_IN_TEAM = 150,
+ BFA_STATUS_IM_VLAN_NOT_FOUND = 151,
+ BFA_STATUS_IM_TEAM_NOT_FOUND = 152,
+ BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153,
+ BFA_STATUS_PBC = 154,
+ BFA_STATUS_DEVID_MISSING = 155,
+ BFA_STATUS_BAD_FWCFG = 156,
+ BFA_STATUS_CREATE_FILE = 157,
+ BFA_STATUS_INVALID_VENDOR = 158,
+ BFA_STATUS_SFP_NOT_READY = 159,
+ BFA_STATUS_FLASH_UNINIT = 160,
+ BFA_STATUS_FLASH_EMPTY = 161,
+ BFA_STATUS_FLASH_CKFAIL = 162,
+ BFA_STATUS_TRUNK_UNSUPP = 163,
+ BFA_STATUS_TRUNK_ENABLED = 164,
+ BFA_STATUS_TRUNK_DISABLED = 165,
+ BFA_STATUS_TRUNK_ERROR_TRL_ENABLED = 166,
+ BFA_STATUS_BOOT_CODE_UPDATED = 167,
+ BFA_STATUS_BOOT_VERSION = 168,
+ BFA_STATUS_CARDTYPE_MISSING = 169,
+ BFA_STATUS_INVALID_CARDTYPE = 170,
+ BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 171,
+ BFA_STATUS_IM_VLAN_OVER_TEAM_DELETE_FAILED = 172,
+ BFA_STATUS_ETHBOOT_ENABLED = 173,
+ BFA_STATUS_ETHBOOT_DISABLED = 174,
+ BFA_STATUS_IOPROFILE_OFF = 175,
+ BFA_STATUS_NO_PORT_INSTANCE = 176,
+ BFA_STATUS_BOOT_CODE_TIMEDOUT = 177,
+ BFA_STATUS_NO_VPORT_LOCK = 178,
+ BFA_STATUS_VPORT_NO_CNFG = 179,
+ BFA_STATUS_MAX_VAL
+};
+
+enum bfa_eproto_status {
+ BFA_EPROTO_BAD_ACCEPT = 0,
+ BFA_EPROTO_UNKNOWN_RSP = 1
+};
+
+#endif /* __BFA_DEFS_STATUS_H__ */
diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c
new file mode 100644
index 000000000000..caa45c2185e9
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc.c
@@ -0,0 +1,1738 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi.h"
+#include "bfi_ctreg.h"
+#include "bfa_defs.h"
+
+/**
+ * IOC local definitions
+ */
+
+#define bfa_ioc_timer_start(__ioc) \
+ mod_timer(&(__ioc)->ioc_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_TOV))
+#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer)
+
+#define bfa_ioc_recovery_timer_start(__ioc) \
+ mod_timer(&(__ioc)->ioc_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_TOV_RECOVER))
+
+#define bfa_sem_timer_start(__ioc) \
+ mod_timer(&(__ioc)->sem_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV))
+#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer)
+
+#define bfa_hb_timer_start(__ioc) \
+ mod_timer(&(__ioc)->hb_timer, jiffies + \
+ msecs_to_jiffies(BFA_IOC_HB_TOV))
+#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer)
+
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+#define bfa_ioc_is_optrom(__ioc) \
+ (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
+
+#define bfa_ioc_mbox_cmd_pending(__ioc) \
+ (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
+ readl((__ioc)->ioc_regs.hfn_mbox_cmd))
+
+bool bfa_nw_auto_recover = true;
+
+/*
+ * forward declarations
+ */
+static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
+static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
+static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_send_enable(struct bfa_ioc *ioc);
+static void bfa_ioc_send_disable(struct bfa_ioc *ioc);
+static void bfa_ioc_send_getattr(struct bfa_ioc *ioc);
+static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc);
+static void bfa_ioc_hb_stop(struct bfa_ioc *ioc);
+static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
+static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
+static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_recover(struct bfa_ioc *ioc);
+static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
+static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
+static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
+static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
+ u32 boot_param);
+static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
+static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr);
+static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
+ char *serial_num);
+static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc,
+ char *fw_ver);
+static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc,
+ char *chip_rev);
+static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc,
+ char *optrom_ver);
+static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc,
+ char *manufacturer);
+static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model);
+static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc);
+static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc);
+
+/**
+ * IOC state machine events
+ */
+enum ioc_event {
+ IOC_E_ENABLE = 1, /*!< IOC enable request */
+ IOC_E_DISABLE = 2, /*!< IOC disable request */
+ IOC_E_TIMEOUT = 3, /*!< f/w response timeout */
+ IOC_E_FWREADY = 4, /*!< f/w initialization done */
+ IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */
+ IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */
+ IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */
+ IOC_E_HBFAIL = 8, /*!< heartbeat failure */
+ IOC_E_HWERROR = 9, /*!< hardware error interrupt */
+ IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */
+ IOC_E_DETACH = 11, /*!< driver detach cleanup */
+};
+
+bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event);
+bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event);
+
+static struct bfa_sm_table ioc_sm_table[] = {
+ {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
+ {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
+ {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
+ {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
+ {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
+ {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
+ {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
+ {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
+ {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
+ {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
+};
+
+/**
+ * Reset entry actions -- initialize state machine
+ */
+static void
+bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc)
+{
+ ioc->retry_count = 0;
+ ioc->auto_recover = bfa_nw_auto_recover;
+}
+
+/**
+ * Beginning state. IOC is in reset state.
+ */
+static void
+bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ break;
+
+ case IOC_E_DETACH:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Semaphore should be acquired for version check.
+ */
+static void
+bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting h/w semaphore to continue with version check.
+ */
+static void
+bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ if (bfa_ioc_firmware_lock(ioc)) {
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ } else {
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
+ }
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /* fall through */
+
+ case IOC_E_DETACH:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Notify enable completion callback and generate mismatch AEN.
+ */
+static void
+bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc)
+{
+ /**
+ * Provide enable completion callback and AEN notification only once.
+ */
+ if (ioc->retry_count == 0)
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ ioc->retry_count++;
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * Awaiting firmware version match.
+ */
+static void
+bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_disable_comp(ioc);
+ /* fall through */
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * Request for semaphore.
+ */
+static void
+bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+/**
+ * Awaiting semaphore for h/w initialzation.
+ */
+static void
+bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_SEMLOCKED:
+ ioc->retry_count = 0;
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hw_sem_get_cancel(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, false);
+}
+
+/**
+ * @brief
+ * Hardware is being initialized. Interrupts are enabled.
+ * Holding hardware semaphore lock.
+ */
+static void
+bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWREADY:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_reset(ioc, true);
+ break;
+ }
+
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_enable(ioc);
+}
+
+/**
+ * Host IOC function is being enabled, awaiting response from firmware.
+ * Semaphore is acquired.
+ */
+static void
+bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_ENABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ ioc->retry_count++;
+ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
+ writel(BFI_IOC_UNINIT,
+ ioc->ioc_regs.ioc_fwstate);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
+ break;
+ }
+
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_nw_ioc_hw_sem_release(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_FWREADY:
+ bfa_ioc_send_enable(ioc);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_getattr(ioc);
+}
+
+/**
+ * @brief
+ * IOC configuration in progress. Timer is active.
+ */
+static void
+bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_GETATTR:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_check_attr_wwns(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /* fall through */
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_op_entry(struct bfa_ioc *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
+ bfa_ioc_hb_monitor(ioc);
+}
+
+static void
+bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ break;
+
+ case IOC_E_DISABLE:
+ bfa_ioc_hb_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
+ break;
+
+ case IOC_E_HWERROR:
+ case IOC_E_FWREADY:
+ /**
+ * Hard error or IOC recovery by other function.
+ * Treat it same as heartbeat failure.
+ */
+ bfa_ioc_hb_stop(ioc);
+ /* !!! fall through !!! */
+
+ case IOC_E_HBFAIL:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_timer_start(ioc);
+ bfa_ioc_send_disable(ioc);
+}
+
+/**
+ * IOC is being disabled
+ */
+static void
+bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_FWRSP_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_HWERROR:
+ bfa_ioc_timer_stop(ioc);
+ /*
+ * !!! fall through !!!
+ */
+
+ case IOC_E_TIMEOUT:
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * IOC disable completion entry.
+ */
+static void
+bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc)
+{
+ bfa_ioc_disable_comp(ioc);
+}
+
+static void
+bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_ENABLE:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_DISABLE:
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+ break;
+
+ case IOC_E_FWREADY:
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc)
+{
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ bfa_ioc_timer_start(ioc);
+}
+
+/**
+ * @brief
+ * Hardware initialization failed.
+ */
+static void
+bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+ case IOC_E_DISABLE:
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_DETACH:
+ bfa_ioc_timer_stop(ioc);
+ bfa_ioc_firmware_unlock(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+static void
+bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify *notify;
+
+ /**
+ * Mark IOC as failed in hardware and stop firmware.
+ */
+ bfa_ioc_lpu_stop(ioc);
+ writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+
+ /**
+ * Notify other functions on HB failure.
+ */
+ bfa_ioc_notify_hbfail(ioc);
+
+ /**
+ * Notify driver and common modules registered for notification.
+ */
+ ioc->cbfn->hbfail_cbfn(ioc->bfa);
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+
+ /**
+ * Flush any queued up mailbox requests.
+ */
+ bfa_ioc_mbox_hbfail(ioc);
+
+ /**
+ * Trigger auto-recovery after a delay.
+ */
+ if (ioc->auto_recover)
+ mod_timer(&ioc->ioc_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_TOV_RECOVER));
+}
+
+/**
+ * @brief
+ * IOC heartbeat failure.
+ */
+static void
+bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event)
+{
+ switch (event) {
+
+ case IOC_E_ENABLE:
+ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
+ break;
+
+ case IOC_E_DISABLE:
+ if (ioc->auto_recover)
+ bfa_ioc_timer_stop(ioc);
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+ break;
+
+ case IOC_E_TIMEOUT:
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
+ break;
+
+ case IOC_E_FWREADY:
+ /**
+ * Recovery is already initiated by other function.
+ */
+ break;
+
+ case IOC_E_HWERROR:
+ /*
+ * HB failure notification, ignore.
+ */
+ break;
+ default:
+ bfa_sm_fault(ioc, event);
+ }
+}
+
+/**
+ * BFA IOC private functions
+ */
+
+static void
+bfa_ioc_disable_comp(struct bfa_ioc *ioc)
+{
+ struct list_head *qe;
+ struct bfa_ioc_hbfail_notify *notify;
+
+ ioc->cbfn->disable_cbfn(ioc->bfa);
+
+ /**
+ * Notify common modules registered for notification.
+ */
+ list_for_each(qe, &ioc->hb_notify_q) {
+ notify = (struct bfa_ioc_hbfail_notify *) qe;
+ notify->cbfn(notify->cbarg);
+ }
+}
+
+void
+bfa_nw_ioc_sem_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_ioc_hw_sem_get(ioc);
+}
+
+bool
+bfa_nw_ioc_sem_get(void __iomem *sem_reg)
+{
+ u32 r32;
+ int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
+
+ r32 = readl(sem_reg);
+
+ while (r32 && (cnt < BFA_SEM_SPINCNT)) {
+ cnt++;
+ udelay(2);
+ r32 = readl(sem_reg);
+ }
+
+ if (r32 == 0)
+ return true;
+
+ BUG_ON(!(cnt < BFA_SEM_SPINCNT));
+ return false;
+}
+
+void
+bfa_nw_ioc_sem_release(void __iomem *sem_reg)
+{
+ writel(1, sem_reg);
+}
+
+static void
+bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
+{
+ u32 r32;
+
+ /**
+ * First read to the semaphore register will return 0, subsequent reads
+ * will return 1. Semaphore is released by writing 1 to the register
+ */
+ r32 = readl(ioc->ioc_regs.ioc_sem_reg);
+ if (r32 == 0) {
+ bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
+ return;
+ }
+
+ mod_timer(&ioc->sem_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HWSEM_TOV));
+}
+
+void
+bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc)
+{
+ writel(1, ioc->ioc_regs.ioc_sem_reg);
+}
+
+static void
+bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc)
+{
+ del_timer(&ioc->sem_timer);
+}
+
+/**
+ * @brief
+ * Initialize LPU local memory (aka secondary memory / SRAM)
+ */
+static void
+bfa_ioc_lmem_init(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+ int i;
+#define PSS_LMEM_INIT_TIME 10000
+
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LMEM_RESET;
+ pss_ctl |= __PSS_LMEM_INIT_EN;
+
+ /*
+ * i2c workaround 12.5khz clock
+ */
+ pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+
+ /**
+ * wait for memory initialization to be complete
+ */
+ i = 0;
+ do {
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ i++;
+ } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
+
+ /**
+ * If memory initialization is not successful, IOC timeout will catch
+ * such failures.
+ */
+ BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
+
+ pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+static void
+bfa_ioc_lpu_start(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Take processor out of reset.
+ */
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl &= ~__PSS_LPU0_RESET;
+
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+static void
+bfa_ioc_lpu_stop(struct bfa_ioc *ioc)
+{
+ u32 pss_ctl;
+
+ /**
+ * Put processors in reset.
+ */
+ pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
+ pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
+
+ writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
+}
+
+/**
+ * Get driver and firmware versions.
+ */
+void
+bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
+{
+ u32 pgnum, pgoff;
+ u32 loff = 0;
+ int i;
+ u32 *fwsig = (u32 *) fwhdr;
+
+ pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+ writel(pgnum, ioc->ioc_regs.host_page_num_fn);
+
+ for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32));
+ i++) {
+ fwsig[i] =
+ swab32(readl((loff) + (ioc->ioc_regs.smem_page_start)));
+ loff += sizeof(u32);
+ }
+}
+
+/**
+ * Returns TRUE if same.
+ */
+bool
+bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
+{
+ struct bfi_ioc_image_hdr *drv_fwhdr;
+ int i;
+
+ drv_fwhdr = (struct bfi_ioc_image_hdr *)
+ bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
+ for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
+ if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i])
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Return true if current running version is valid. Firmware signature and
+ * execution context (driver/bios) must match.
+ */
+static bool
+bfa_ioc_fwver_valid(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr;
+
+ /**
+ * If bios/efi boot (flash based) -- return true
+ */
+ if (bfa_ioc_is_optrom(ioc))
+ return true;
+
+ bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+ drv_fwhdr = (struct bfi_ioc_image_hdr *)
+ bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
+ if (fwhdr.signature != drv_fwhdr->signature)
+ return false;
+
+ if (fwhdr.exec != drv_fwhdr->exec)
+ return false;
+
+ return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr);
+}
+
+/**
+ * Conditionally flush any pending message from firmware at start.
+ */
+static void
+bfa_ioc_msgflush(struct bfa_ioc *ioc)
+{
+ u32 r32;
+
+ r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
+ if (r32)
+ writel(1, ioc->ioc_regs.lpu_mbox_cmd);
+}
+
+/**
+ * @img ioc_init_logic.jpg
+ */
+static void
+bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ bool fwvalid;
+
+ ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ if (force)
+ ioc_fwstate = BFI_IOC_UNINIT;
+
+ /**
+ * check if firmware is valid
+ */
+ fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
+ false : bfa_ioc_fwver_valid(ioc);
+
+ if (!fwvalid) {
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+ return;
+ }
+
+ /**
+ * If hardware initialization is in progress (initialized by other IOC),
+ * just wait for an initialization completion interrupt.
+ */
+ if (ioc_fwstate == BFI_IOC_INITING) {
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ return;
+ }
+
+ /**
+ * If IOC function is disabled and firmware version is same,
+ * just re-enable IOC.
+ *
+ * If option rom, IOC must not be in operational state. With
+ * convergence, IOC will be in operational state when 2nd driver
+ * is loaded.
+ */
+ if (ioc_fwstate == BFI_IOC_DISABLED ||
+ (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
+ /**
+ * When using MSI-X any pending firmware ready event should
+ * be flushed. Otherwise MSI-X interrupts are not delivered.
+ */
+ bfa_ioc_msgflush(ioc);
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ return;
+ }
+
+ /**
+ * Initialize the h/w for any other states.
+ */
+ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
+}
+
+void
+bfa_nw_ioc_timeout(void *ioc_arg)
+{
+ struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg;
+
+ bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
+}
+
+static void
+bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len)
+{
+ u32 *msgp = (u32 *) ioc_msg;
+ u32 i;
+
+ BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX));
+
+ /*
+ * first write msg to mailbox registers
+ */
+ for (i = 0; i < len / sizeof(u32); i++)
+ writel(cpu_to_le32(msgp[i]),
+ ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
+
+ for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
+ writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
+
+ /*
+ * write 1 to mailbox CMD to trigger LPU event
+ */
+ writel(1, ioc->ioc_regs.hfn_mbox_cmd);
+ (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
+}
+
+static void
+bfa_ioc_send_enable(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_ctrl_req enable_req;
+ struct timeval tv;
+
+ bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
+ bfa_ioc_portid(ioc));
+ enable_req.ioc_class = ioc->ioc_mc;
+ do_gettimeofday(&tv);
+ enable_req.tv_sec = ntohl(tv.tv_sec);
+ bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
+}
+
+static void
+bfa_ioc_send_disable(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_ctrl_req disable_req;
+
+ bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req));
+}
+
+static void
+bfa_ioc_send_getattr(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_getattr_req attr_req;
+
+ bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
+ bfa_ioc_portid(ioc));
+ bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
+ bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
+}
+
+void
+bfa_nw_ioc_hb_check(void *cbarg)
+{
+ struct bfa_ioc *ioc = cbarg;
+ u32 hb_count;
+
+ hb_count = readl(ioc->ioc_regs.heartbeat);
+ if (ioc->hb_count == hb_count) {
+ pr_crit("Firmware heartbeat failure at %d", hb_count);
+ bfa_ioc_recover(ioc);
+ return;
+ } else {
+ ioc->hb_count = hb_count;
+ }
+
+ bfa_ioc_mbox_poll(ioc);
+ mod_timer(&ioc->hb_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HB_TOV));
+}
+
+static void
+bfa_ioc_hb_monitor(struct bfa_ioc *ioc)
+{
+ ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
+ mod_timer(&ioc->hb_timer, jiffies +
+ msecs_to_jiffies(BFA_IOC_HB_TOV));
+}
+
+static void
+bfa_ioc_hb_stop(struct bfa_ioc *ioc)
+{
+ del_timer(&ioc->hb_timer);
+}
+
+/**
+ * @brief
+ * Initiate a full firmware download.
+ */
+static void
+bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
+ u32 boot_param)
+{
+ u32 *fwimg;
+ u32 pgnum, pgoff;
+ u32 loff = 0;
+ u32 chunkno = 0;
+ u32 i;
+
+ /**
+ * Initialize LMEM first before code download
+ */
+ bfa_ioc_lmem_init(ioc);
+
+ /**
+ * Flash based firmware boot
+ */
+ if (bfa_ioc_is_optrom(ioc))
+ boot_type = BFI_BOOT_TYPE_FLASH;
+ fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
+
+ pgnum = bfa_ioc_smem_pgnum(ioc, loff);
+ pgoff = bfa_ioc_smem_pgoff(ioc, loff);
+
+ writel(pgnum, ioc->ioc_regs.host_page_num_fn);
+
+ for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
+ if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+ chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
+ fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
+ BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
+ }
+
+ /**
+ * write smem
+ */
+ writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])),
+ ((ioc->ioc_regs.smem_page_start) + (loff)));
+
+ loff += sizeof(u32);
+
+ /**
+ * handle page offset wrap around
+ */
+ loff = PSS_SMEM_PGOFF(loff);
+ if (loff == 0) {
+ pgnum++;
+ writel(pgnum,
+ ioc->ioc_regs.host_page_num_fn);
+ }
+ }
+
+ writel(bfa_ioc_smem_pgnum(ioc, 0),
+ ioc->ioc_regs.host_page_num_fn);
+
+ /*
+ * Set boot type and boot param at the end.
+ */
+ writel((swab32(swab32(boot_type))), ((ioc->ioc_regs.smem_page_start)
+ + (BFI_BOOT_TYPE_OFF)));
+ writel((swab32(swab32(boot_param))), ((ioc->ioc_regs.smem_page_start)
+ + (BFI_BOOT_PARAM_OFF)));
+}
+
+static void
+bfa_ioc_reset(struct bfa_ioc *ioc, bool force)
+{
+ bfa_ioc_hwinit(ioc, force);
+}
+
+/**
+ * @brief
+ * Update BFA configuration from firmware configuration.
+ */
+static void
+bfa_ioc_getattr_reply(struct bfa_ioc *ioc)
+{
+ struct bfi_ioc_attr *attr = ioc->attr;
+
+ attr->adapter_prop = ntohl(attr->adapter_prop);
+ attr->card_type = ntohl(attr->card_type);
+ attr->maxfrsize = ntohs(attr->maxfrsize);
+
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
+}
+
+/**
+ * Attach time initialization of mbox logic.
+ */
+static void
+bfa_ioc_mbox_attach(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ int mc;
+
+ INIT_LIST_HEAD(&mod->cmd_q);
+ for (mc = 0; mc < BFI_MC_MAX; mc++) {
+ mod->mbhdlr[mc].cbfn = NULL;
+ mod->mbhdlr[mc].cbarg = ioc->bfa;
+ }
+}
+
+/**
+ * Mbox poll timer -- restarts any pending mailbox requests.
+ */
+static void
+bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd *cmd;
+ u32 stat;
+
+ /**
+ * If no command pending, do nothing
+ */
+ if (list_empty(&mod->cmd_q))
+ return;
+
+ /**
+ * If previous command is not yet fetched by firmware, do nothing
+ */
+ stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat)
+ return;
+
+ /**
+ * Enqueue command to firmware.
+ */
+ bfa_q_deq(&mod->cmd_q, &cmd);
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Cleanup any pending requests.
+ */
+static void
+bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfa_mbox_cmd *cmd;
+
+ while (!list_empty(&mod->cmd_q))
+ bfa_q_deq(&mod->cmd_q, &cmd);
+}
+
+/**
+ * IOC public
+ */
+static enum bfa_status
+bfa_ioc_pll_init(struct bfa_ioc *ioc)
+{
+ /*
+ * Hold semaphore so that nobody can access the chip during init.
+ */
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+ bfa_ioc_pll_init_asic(ioc);
+
+ ioc->pllinit = true;
+ /*
+ * release semaphore.
+ */
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+ return BFA_STATUS_OK;
+}
+
+/**
+ * Interface used by diag module to do firmware boot with memory test
+ * as the entry vector.
+ */
+static void
+bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param)
+{
+ void __iomem *rb;
+
+ bfa_ioc_stats(ioc, ioc_boots);
+
+ if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
+ return;
+
+ /**
+ * Initialize IOC state of all functions on a chip reset.
+ */
+ rb = ioc->pcidev.pci_bar_kva;
+ if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
+ writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG));
+ } else {
+ writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG));
+ }
+
+ bfa_ioc_msgflush(ioc);
+ bfa_ioc_download_fw(ioc, boot_type, boot_param);
+
+ /**
+ * Enable interrupts just before starting LPU
+ */
+ ioc->cbfn->reset_cbfn(ioc->bfa);
+ bfa_ioc_lpu_start(ioc);
+}
+
+/**
+ * Enable/disable IOC failure auto recovery.
+ */
+void
+bfa_nw_ioc_auto_recover(bool auto_recover)
+{
+ bfa_nw_auto_recover = auto_recover;
+}
+
+bool
+bfa_nw_ioc_is_operational(struct bfa_ioc *ioc)
+{
+ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
+}
+
+static void
+bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg)
+{
+ u32 *msgp = mbmsg;
+ u32 r32;
+ int i;
+
+ /**
+ * read the MBOX msg
+ */
+ for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
+ i++) {
+ r32 = readl(ioc->ioc_regs.lpu_mbox +
+ i * sizeof(u32));
+ msgp[i] = htonl(r32);
+ }
+
+ /**
+ * turn off mailbox interrupt by clearing mailbox status
+ */
+ writel(1, ioc->ioc_regs.lpu_mbox_cmd);
+ readl(ioc->ioc_regs.lpu_mbox_cmd);
+}
+
+static void
+bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m)
+{
+ union bfi_ioc_i2h_msg_u *msg;
+
+ msg = (union bfi_ioc_i2h_msg_u *) m;
+
+ bfa_ioc_stats(ioc, ioc_isrs);
+
+ switch (msg->mh.msg_id) {
+ case BFI_IOC_I2H_HBEAT:
+ break;
+
+ case BFI_IOC_I2H_READY_EVENT:
+ bfa_fsm_send_event(ioc, IOC_E_FWREADY);
+ break;
+
+ case BFI_IOC_I2H_ENABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
+ break;
+
+ case BFI_IOC_I2H_DISABLE_REPLY:
+ bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
+ break;
+
+ case BFI_IOC_I2H_GETATTR_REPLY:
+ bfa_ioc_getattr_reply(ioc);
+ break;
+
+ default:
+ BUG_ON(1);
+ }
+}
+
+/**
+ * IOC attach time initialization and setup.
+ *
+ * @param[in] ioc memory for IOC
+ * @param[in] bfa driver instance structure
+ */
+void
+bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
+{
+ ioc->bfa = bfa;
+ ioc->cbfn = cbfn;
+ ioc->fcmode = false;
+ ioc->pllinit = false;
+ ioc->dbg_fwsave_once = true;
+
+ bfa_ioc_mbox_attach(ioc);
+ INIT_LIST_HEAD(&ioc->hb_notify_q);
+
+ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
+}
+
+/**
+ * Driver detach time IOC cleanup.
+ */
+void
+bfa_nw_ioc_detach(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_DETACH);
+}
+
+/**
+ * Setup IOC PCI properties.
+ *
+ * @param[in] pcidev PCI device information for this IOC
+ */
+void
+bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
+ enum bfi_mclass mc)
+{
+ ioc->ioc_mc = mc;
+ ioc->pcidev = *pcidev;
+ ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id);
+ ioc->cna = ioc->ctdev && !ioc->fcmode;
+
+ bfa_nw_ioc_set_ct_hwif(ioc);
+
+ bfa_ioc_map_port(ioc);
+ bfa_ioc_reg_init(ioc);
+}
+
+/**
+ * Initialize IOC dma memory
+ *
+ * @param[in] dm_kva kernel virtual address of IOC dma memory
+ * @param[in] dm_pa physical address of IOC dma memory
+ */
+void
+bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa)
+{
+ /**
+ * dma memory for firmware attribute
+ */
+ ioc->attr_dma.kva = dm_kva;
+ ioc->attr_dma.pa = dm_pa;
+ ioc->attr = (struct bfi_ioc_attr *) dm_kva;
+}
+
+/**
+ * Return size of dma memory required.
+ */
+u32
+bfa_nw_ioc_meminfo(void)
+{
+ return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ);
+}
+
+void
+bfa_nw_ioc_enable(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_enables);
+ ioc->dbg_fwsave_once = true;
+
+ bfa_fsm_send_event(ioc, IOC_E_ENABLE);
+}
+
+void
+bfa_nw_ioc_disable(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_disables);
+ bfa_fsm_send_event(ioc, IOC_E_DISABLE);
+}
+
+static u32
+bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr)
+{
+ return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
+}
+
+static u32
+bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr)
+{
+ return PSS_SMEM_PGOFF(fmaddr);
+}
+
+/**
+ * Register mailbox message handler function, to be called by common modules
+ */
+void
+bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
+ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+
+ mod->mbhdlr[mc].cbfn = cbfn;
+ mod->mbhdlr[mc].cbarg = cbarg;
+}
+
+/**
+ * Queue a mailbox command request to firmware. Waits if mailbox is busy.
+ * Responsibility of caller to serialize
+ *
+ * @param[in] ioc IOC instance
+ * @param[i] cmd Mailbox command
+ */
+void
+bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ u32 stat;
+
+ /**
+ * If a previous command is pending, queue new command
+ */
+ if (!list_empty(&mod->cmd_q)) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * If mailbox is busy, queue command for poll timer
+ */
+ stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
+ if (stat) {
+ list_add_tail(&cmd->qe, &mod->cmd_q);
+ return;
+ }
+
+ /**
+ * mailbox is free -- queue command to firmware
+ */
+ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+}
+
+/**
+ * Handle mailbox interrupts
+ */
+void
+bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
+{
+ struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
+ struct bfi_mbmsg m;
+ int mc;
+
+ bfa_ioc_msgget(ioc, &m);
+
+ /**
+ * Treat IOC message class as special.
+ */
+ mc = m.mh.msg_class;
+ if (mc == BFI_MC_IOC) {
+ bfa_ioc_isr(ioc, &m);
+ return;
+ }
+
+ if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
+ return;
+
+ mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
+}
+
+void
+bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
+{
+ bfa_fsm_send_event(ioc, IOC_E_HWERROR);
+}
+
+/**
+ * Add to IOC heartbeat failure notification queue. To be used by common
+ * modules such as cee, port, diag.
+ */
+void
+bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
+ struct bfa_ioc_hbfail_notify *notify)
+{
+ list_add_tail(&notify->qe, &ioc->hb_notify_q);
+}
+
+#define BFA_MFG_NAME "Brocade"
+static void
+bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc,
+ struct bfa_adapter_attr *ad_attr)
+{
+ struct bfi_ioc_attr *ioc_attr;
+
+ ioc_attr = ioc->attr;
+
+ bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+ bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+ bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+ bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
+ memcpy(&ad_attr->vpd, &ioc_attr->vpd,
+ sizeof(struct bfa_mfg_vpd));
+
+ ad_attr->nports = bfa_ioc_get_nports(ioc);
+ ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
+
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+ /* For now, model descr uses same model string */
+ bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
+
+ ad_attr->card_type = ioc_attr->card_type;
+ ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
+
+ if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
+ ad_attr->prototype = 1;
+ else
+ ad_attr->prototype = 0;
+
+ ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
+ ad_attr->mac = bfa_nw_ioc_get_mac(ioc);
+
+ ad_attr->pcie_gen = ioc_attr->pcie_gen;
+ ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
+ ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
+ ad_attr->asic_rev = ioc_attr->asic_rev;
+
+ bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
+
+ ad_attr->cna_capable = ioc->cna;
+ ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
+}
+
+static enum bfa_ioc_type
+bfa_ioc_get_type(struct bfa_ioc *ioc)
+{
+ if (!ioc->ctdev || ioc->fcmode)
+ return BFA_IOC_TYPE_FC;
+ else if (ioc->ioc_mc == BFI_MC_IOCFC)
+ return BFA_IOC_TYPE_FCoE;
+ else if (ioc->ioc_mc == BFI_MC_LL)
+ return BFA_IOC_TYPE_LL;
+ else {
+ BUG_ON(!(ioc->ioc_mc == BFI_MC_LL));
+ return BFA_IOC_TYPE_LL;
+ }
+}
+
+static void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num)
+{
+ memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+ memcpy(serial_num,
+ (void *)ioc->attr->brcd_serialnum,
+ BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver)
+{
+ memset(fw_ver, 0, BFA_VERSION_LEN);
+ memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+static void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev)
+{
+ BUG_ON(!(chip_rev));
+
+ memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+ chip_rev[0] = 'R';
+ chip_rev[1] = 'e';
+ chip_rev[2] = 'v';
+ chip_rev[3] = '-';
+ chip_rev[4] = ioc->attr->asic_rev;
+ chip_rev[5] = '\0';
+}
+
+static void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver)
+{
+ memset(optrom_ver, 0, BFA_VERSION_LEN);
+ memcpy(optrom_ver, ioc->attr->optrom_version,
+ BFA_VERSION_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer)
+{
+ memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+ memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+static void
+bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model)
+{
+ struct bfi_ioc_attr *ioc_attr;
+
+ BUG_ON(!(model));
+ memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+ ioc_attr = ioc->attr;
+
+ /**
+ * model name
+ */
+ snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+ BFA_MFG_NAME, ioc_attr->card_type);
+}
+
+static enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc *ioc)
+{
+ return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
+void
+bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr)
+{
+ memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr));
+
+ ioc_attr->state = bfa_ioc_get_state(ioc);
+ ioc_attr->port_id = ioc->port_id;
+
+ ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
+
+ bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
+
+ ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
+ ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
+ bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
+}
+
+/**
+ * WWN public
+ */
+static u64
+bfa_ioc_get_pwwn(struct bfa_ioc *ioc)
+{
+ return ioc->attr->pwwn;
+}
+
+mac_t
+bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
+{
+ /*
+ * Currently mfg mac is used as FCoE enode mac (not configured by PBC)
+ */
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
+ return bfa_ioc_get_mfg_mac(ioc);
+ else
+ return ioc->attr->mac;
+}
+
+static mac_t
+bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc)
+{
+ mac_t m;
+
+ m = ioc->attr->mfg_mac;
+ if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
+ m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
+ else
+ bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
+ bfa_ioc_pcifn(ioc));
+
+ return m;
+}
+
+/**
+ * Firmware failure detected. Start recovery actions.
+ */
+static void
+bfa_ioc_recover(struct bfa_ioc *ioc)
+{
+ bfa_ioc_stats(ioc, ioc_hbfails);
+ bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
+}
+
+static void
+bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
+{
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
+ return;
+
+}
diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h
new file mode 100644
index 000000000000..7f0719e17efc
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc.h
@@ -0,0 +1,301 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFA_IOC_H__
+#define __BFA_IOC_H__
+
+#include "bfa_sm.h"
+#include "bfi.h"
+#include "cna.h"
+
+#define BFA_IOC_TOV 3000 /* msecs */
+#define BFA_IOC_HWSEM_TOV 500 /* msecs */
+#define BFA_IOC_HB_TOV 500 /* msecs */
+#define BFA_IOC_HWINIT_MAX 2
+#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
+
+/**
+ * Generic Scatter Gather Element used by driver
+ */
+struct bfa_sge {
+ u32 sg_len;
+ void *sg_addr;
+};
+
+/**
+ * PCI device information required by IOC
+ */
+struct bfa_pcidev {
+ int pci_slot;
+ u8 pci_func;
+ u16 device_id;
+ void __iomem *pci_bar_kva;
+};
+
+/**
+ * Structure used to remember the DMA-able memory block's KVA and Physical
+ * Address
+ */
+struct bfa_dma {
+ void *kva; /* ! Kernel virtual address */
+ u64 pa; /* ! Physical address */
+};
+
+#define BFA_DMA_ALIGN_SZ 256
+
+/**
+ * smem size for Crossbow and Catapult
+ */
+#define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */
+#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */
+
+/**
+ * @brief BFA dma address assignment macro
+ */
+#define bfa_dma_addr_set(dma_addr, pa) \
+ __bfa_dma_addr_set(&dma_addr, (u64)pa)
+
+static inline void
+__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
+{
+ dma_addr->a32.addr_lo = (u32) pa;
+ dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa));
+}
+
+/**
+ * @brief BFA dma address assignment macro. (big endian format)
+ */
+#define bfa_dma_be_addr_set(dma_addr, pa) \
+ __bfa_dma_be_addr_set(&dma_addr, (u64)pa)
+static inline void
+__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
+{
+ dma_addr->a32.addr_lo = (u32) htonl(pa);
+ dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa));
+}
+
+struct bfa_ioc_regs {
+ void __iomem *hfn_mbox_cmd;
+ void __iomem *hfn_mbox;
+ void __iomem *lpu_mbox_cmd;
+ void __iomem *lpu_mbox;
+ void __iomem *pss_ctl_reg;
+ void __iomem *pss_err_status_reg;
+ void __iomem *app_pll_fast_ctl_reg;
+ void __iomem *app_pll_slow_ctl_reg;
+ void __iomem *ioc_sem_reg;
+ void __iomem *ioc_usage_sem_reg;
+ void __iomem *ioc_init_sem_reg;
+ void __iomem *ioc_usage_reg;
+ void __iomem *host_page_num_fn;
+ void __iomem *heartbeat;
+ void __iomem *ioc_fwstate;
+ void __iomem *ll_halt;
+ void __iomem *err_set;
+ void __iomem *shirq_isr_next;
+ void __iomem *shirq_msk_next;
+ void __iomem *smem_page_start;
+ u32 smem_pg0;
+};
+
+/**
+ * IOC Mailbox structures
+ */
+struct bfa_mbox_cmd {
+ struct list_head qe;
+ u32 msg[BFI_IOC_MSGSZ];
+};
+
+/**
+ * IOC mailbox module
+ */
+typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg *m);
+struct bfa_ioc_mbox_mod {
+ struct list_head cmd_q; /*!< pending mbox queue */
+ int nmclass; /*!< number of handlers */
+ struct {
+ bfa_ioc_mbox_mcfunc_t cbfn; /*!< message handlers */
+ void *cbarg;
+ } mbhdlr[BFI_MC_MAX];
+};
+
+/**
+ * IOC callback function interfaces
+ */
+typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
+typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa);
+typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa);
+typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa);
+struct bfa_ioc_cbfn {
+ bfa_ioc_enable_cbfn_t enable_cbfn;
+ bfa_ioc_disable_cbfn_t disable_cbfn;
+ bfa_ioc_hbfail_cbfn_t hbfail_cbfn;
+ bfa_ioc_reset_cbfn_t reset_cbfn;
+};
+
+/**
+ * Heartbeat failure notification queue element.
+ */
+struct bfa_ioc_hbfail_notify {
+ struct list_head qe;
+ bfa_ioc_hbfail_cbfn_t cbfn;
+ void *cbarg;
+};
+
+/**
+ * Initialize a heartbeat failure notification structure
+ */
+#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \
+ (__notify)->cbfn = (__cbfn); \
+ (__notify)->cbarg = (__cbarg); \
+} while (0)
+
+struct bfa_ioc {
+ bfa_fsm_t fsm;
+ struct bfa *bfa;
+ struct bfa_pcidev pcidev;
+ struct bfa_timer_mod *timer_mod;
+ struct timer_list ioc_timer;
+ struct timer_list sem_timer;
+ struct timer_list hb_timer;
+ u32 hb_count;
+ u32 retry_count;
+ struct list_head hb_notify_q;
+ void *dbg_fwsave;
+ int dbg_fwsave_len;
+ bool dbg_fwsave_once;
+ enum bfi_mclass ioc_mc;
+ struct bfa_ioc_regs ioc_regs;
+ struct bfa_ioc_drv_stats stats;
+ bool auto_recover;
+ bool fcmode;
+ bool ctdev;
+ bool cna;
+ bool pllinit;
+ bool stats_busy; /*!< outstanding stats */
+ u8 port_id;
+
+ struct bfa_dma attr_dma;
+ struct bfi_ioc_attr *attr;
+ struct bfa_ioc_cbfn *cbfn;
+ struct bfa_ioc_mbox_mod mbox_mod;
+ struct bfa_ioc_hwif *ioc_hwif;
+};
+
+struct bfa_ioc_hwif {
+ enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode);
+ bool (*ioc_firmware_lock) (struct bfa_ioc *ioc);
+ void (*ioc_firmware_unlock) (struct bfa_ioc *ioc);
+ void (*ioc_reg_init) (struct bfa_ioc *ioc);
+ void (*ioc_map_port) (struct bfa_ioc *ioc);
+ void (*ioc_isr_mode_set) (struct bfa_ioc *ioc,
+ bool msix);
+ void (*ioc_notify_hbfail) (struct bfa_ioc *ioc);
+ void (*ioc_ownership_reset) (struct bfa_ioc *ioc);
+};
+
+#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func)
+#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id)
+#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva)
+#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
+#define bfa_ioc_fetch_stats(__ioc, __stats) \
+ (((__stats)->drv_stats) = (__ioc)->stats)
+#define bfa_ioc_clr_stats(__ioc) \
+ memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
+#define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize)
+#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
+#define bfa_ioc_speed_sup(__ioc) \
+ BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc) \
+ BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+#define BFA_IOC_FWIMG_TYPE(__ioc) \
+ (((__ioc)->ctdev) ? \
+ (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \
+ BFI_IMAGE_CB_FC)
+#define BFA_IOC_FW_SMEM_SIZE(__ioc) \
+ (((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE)
+#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
+
+/**
+ * IOC mailbox interface
+ */
+void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd);
+void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc);
+void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc,
+ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
+
+/**
+ * IOC interfaces
+ */
+
+#define bfa_ioc_pll_init_asic(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \
+ (__ioc)->fcmode))
+
+#define bfa_ioc_isr_mode_set(__ioc, __msix) \
+ ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc) \
+ ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa,
+ struct bfa_ioc_cbfn *cbfn);
+void bfa_nw_ioc_auto_recover(bool auto_recover);
+void bfa_nw_ioc_detach(struct bfa_ioc *ioc);
+void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev,
+ enum bfi_mclass mc);
+u32 bfa_nw_ioc_meminfo(void);
+void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa);
+void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
+void bfa_nw_ioc_disable(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
+bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc);
+
+void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
+void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
+ struct bfa_ioc_hbfail_notify *notify);
+bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
+void bfa_nw_ioc_sem_release(void __iomem *sem_reg);
+void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);
+void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc,
+ struct bfi_ioc_image_hdr *fwhdr);
+bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc,
+ struct bfi_ioc_image_hdr *fwhdr);
+mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc);
+
+/*
+ * Timeout APIs
+ */
+void bfa_nw_ioc_timeout(void *ioc);
+void bfa_nw_ioc_hb_check(void *ioc);
+void bfa_nw_ioc_sem_timeout(void *ioc);
+
+/*
+ * F/W Image Size & Chunk
+ */
+u32 *bfa_cb_image_get_chunk(int type, u32 off);
+u32 bfa_cb_image_get_size(int type);
+
+#endif /* __BFA_IOC_H__ */
diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c
new file mode 100644
index 000000000000..462857cbab9b
--- /dev/null
+++ b/drivers/net/bna/bfa_ioc_ct.c
@@ -0,0 +1,392 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi.h"
+#include "bfi_ctreg.h"
+#include "bfa_defs.h"
+
+/*
+ * forward declarations
+ */
+static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc);
+static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode);
+
+struct bfa_ioc_hwif nw_hwif_ct;
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
+{
+ nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
+ nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
+ nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
+ nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
+ nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
+ nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
+ nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+
+ ioc->ioc_hwif = &nw_hwif_ct;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bool
+bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
+{
+ enum bfi_ioc_state ioc_fwstate;
+ u32 usecnt;
+ struct bfi_ioc_image_hdr fwhdr;
+
+ /**
+ * Firmware match check is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return true;
+
+ /**
+ * If bios boot (flash based) -- do not increment usage count
+ */
+ if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+ BFA_IOC_FWIMG_MINSZ)
+ return true;
+
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
+
+ /**
+ * If usage count is 0, always return TRUE.
+ */
+ if (usecnt == 0) {
+ writel(1, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return true;
+ }
+
+ ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+ /**
+ * Use count cannot be non-zero and chip in uninitialized state.
+ */
+ BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT));
+
+ /**
+ * Check if another driver with a different firmware is active
+ */
+ bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+ if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) {
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return false;
+ }
+
+ /**
+ * Same firmware version. Increment the reference count.
+ */
+ usecnt++;
+ writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ return true;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
+{
+ u32 usecnt;
+
+ /**
+ * Firmware lock is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return;
+
+ /**
+ * If bios boot (flash based) -- do not decrement usage count
+ */
+ if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
+ BFA_IOC_FWIMG_MINSZ)
+ return;
+
+ /**
+ * decrement usage count
+ */
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
+ BUG_ON(!(usecnt > 0));
+
+ usecnt--;
+ writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
+
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc)
+{
+ if (ioc->cna) {
+ writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
+ /* Wait for halt to take effect */
+ readl(ioc->ioc_regs.ll_halt);
+ } else {
+ writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
+ readl(ioc->ioc_regs.err_set);
+ }
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+ { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+ { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+ { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+ { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+ { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+ { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+ { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+ { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+ { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
+{
+ void __iomem *rb;
+ int pcifn = bfa_ioc_pcifn(ioc);
+
+ rb = bfa_ioc_bar0(ioc);
+
+ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+ if (ioc->port_id == 0) {
+ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+ } else {
+ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+ }
+
+ /*
+ * PSS control registers
+ */
+ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+ ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+ /*
+ * IOC semaphore registers and serialization
+ */
+ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+ ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+ ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+ ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+ /**
+ * sram memory access
+ */
+ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+ /*
+ * err set reg : for notification of hb failure in fcmode
+ */
+ ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc *ioc)
+{
+ void __iomem *rb = ioc->pcidev.pci_bar_kva;
+ u32 r32;
+
+ /**
+ * For catapult, base port id on personality register and IOC type
+ */
+ r32 = readl(rb + FNC_PERS_REG);
+ r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+ ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
+{
+ void __iomem *rb = ioc->pcidev.pci_bar_kva;
+ u32 r32, mode;
+
+ r32 = readl(rb + FNC_PERS_REG);
+
+ mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+ __F0_INTX_STATUS;
+
+ /**
+ * If already in desired mode, do not change anything
+ */
+ if (!msix && mode)
+ return;
+
+ if (msix)
+ mode = __F0_INTX_STATUS_MSIX;
+ else
+ mode = __F0_INTX_STATUS_INTA;
+
+ r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+ r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+
+ writel(r32, rb + FNC_PERS_REG);
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
+{
+ if (ioc->cna) {
+ bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_usage_reg);
+ bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+ }
+
+ /*
+ * Read the hw sem reg to make sure that it is locked
+ * before we clear it. If it is not locked, writing 1
+ * will lock it instead of clearing it.
+ */
+ readl(ioc->ioc_regs.ioc_sem_reg);
+ bfa_nw_ioc_hw_sem_release(ioc);
+}
+
+static enum bfa_status
+bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
+{
+ u32 pll_sclk, pll_fclk, r32;
+
+ pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+ __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+ __APP_PLL_312_JITLMT0_1(3U) |
+ __APP_PLL_312_CNTLMT0_1(1U);
+ pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+ __APP_PLL_425_JITLMT0_1(3U) |
+ __APP_PLL_425_CNTLMT0_1(1U);
+ if (fcmode) {
+ writel(0, (rb + OP_MODE));
+ writel(__APP_EMS_CMLCKSEL |
+ __APP_EMS_REFCKBUFEN2 |
+ __APP_EMS_CHANNEL_SEL,
+ (rb + ETH_MAC_SER_REG));
+ } else {
+ writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
+ writel(__APP_EMS_REFCKBUFEN1,
+ (rb + ETH_MAC_SER_REG));
+ }
+ writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+ writel(pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET,
+ rb + APP_PLL_425_CTL_REG);
+ writel(pll_sclk |
+ __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE,
+ rb + APP_PLL_425_CTL_REG);
+ readl(rb + HOSTFN0_INT_MSK);
+ udelay(2000);
+ writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+ writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+ writel(pll_sclk |
+ __APP_PLL_312_ENABLE,
+ rb + APP_PLL_312_CTL_REG);
+ writel(pll_fclk |
+ __APP_PLL_425_ENABLE,
+ rb + APP_PLL_425_CTL_REG);
+ if (!fcmode) {
+ writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
+ writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
+ }
+ r32 = readl((rb + PSS_CTL_REG));
+ r32 &= ~__PSS_LMEM_RESET;
+ writel(r32, (rb + PSS_CTL_REG));
+ udelay(1000);
+ if (!fcmode) {
+ writel(0, (rb + PMM_1T_RESET_REG_P0));
+ writel(0, (rb + PMM_1T_RESET_REG_P1));
+ }
+
+ writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
+ udelay(1000);
+ r32 = readl((rb + MBIST_STAT_REG));
+ writel(0, (rb + MBIST_CTL_REG));
+ return BFA_STATUS_OK;
+}
diff --git a/drivers/net/bna/bfa_sm.h b/drivers/net/bna/bfa_sm.h
new file mode 100644
index 000000000000..1d3d975d6f68
--- /dev/null
+++ b/drivers/net/bna/bfa_sm.h
@@ -0,0 +1,88 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfasm.h State machine defines
+ */
+
+#ifndef __BFA_SM_H__
+#define __BFA_SM_H__
+
+#include "cna.h"
+
+typedef void (*bfa_sm_t)(void *sm, int event);
+
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_sm_state_decl(oc, st, otype, etype) \
+ static void oc ## _sm_ ## st(otype * fsm, etype event)
+
+#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state))
+#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))
+#define bfa_sm_get_state(_sm) ((_sm)->sm)
+#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state))
+
+/**
+ * For converting from state machine function to state encoding.
+ */
+struct bfa_sm_table {
+ bfa_sm_t sm; /*!< state machine function */
+ int state; /*!< state machine encoding */
+ char *name; /*!< state name for display */
+};
+#define BFA_SM(_sm) ((bfa_sm_t)(_sm))
+
+/**
+ * State machine with entry actions.
+ */
+typedef void (*bfa_fsm_t)(void *fsm, int event);
+
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_fsm_state_decl(oc, st, otype, etype) \
+ static void oc ## _sm_ ## st(otype * fsm, etype event); \
+ static void oc ## _sm_ ## st ## _entry(otype * fsm)
+
+#define bfa_fsm_set_state(_fsm, _state) do { \
+ (_fsm)->fsm = (bfa_fsm_t)(_state); \
+ _state ## _entry(_fsm); \
+} while (0)
+
+#define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event)))
+#define bfa_fsm_get_state(_fsm) ((_fsm)->fsm)
+#define bfa_fsm_cmp_state(_fsm, _state) \
+ ((_fsm)->fsm == (bfa_fsm_t)(_state))
+
+static inline int
+bfa_sm_to_state(struct bfa_sm_table *smt, bfa_sm_t sm)
+{
+ int i = 0;
+
+ while (smt[i].sm && smt[i].sm != sm)
+ i++;
+ return smt[i].state;
+}
+#endif
diff --git a/drivers/net/bna/bfa_wc.h b/drivers/net/bna/bfa_wc.h
new file mode 100644
index 000000000000..d0e4caee67b0
--- /dev/null
+++ b/drivers/net/bna/bfa_wc.h
@@ -0,0 +1,69 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/**
+ * @file bfa_wc.h Generic wait counter.
+ */
+
+#ifndef __BFA_WC_H__
+#define __BFA_WC_H__
+
+typedef void (*bfa_wc_resume_t) (void *cbarg);
+
+struct bfa_wc {
+ bfa_wc_resume_t wc_resume;
+ void *wc_cbarg;
+ int wc_count;
+};
+
+static inline void
+bfa_wc_up(struct bfa_wc *wc)
+{
+ wc->wc_count++;
+}
+
+static inline void
+bfa_wc_down(struct bfa_wc *wc)
+{
+ wc->wc_count--;
+ if (wc->wc_count == 0)
+ wc->wc_resume(wc->wc_cbarg);
+}
+
+/**
+ * Initialize a waiting counter.
+ */
+static inline void
+bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
+{
+ wc->wc_resume = wc_resume;
+ wc->wc_cbarg = wc_cbarg;
+ wc->wc_count = 0;
+ bfa_wc_up(wc);
+}
+
+/**
+ * Wait for counter to reach zero
+ */
+static inline void
+bfa_wc_wait(struct bfa_wc *wc)
+{
+ bfa_wc_down(wc);
+}
+
+#endif
diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h
new file mode 100644
index 000000000000..a97396811050
--- /dev/null
+++ b/drivers/net/bna/bfi.h
@@ -0,0 +1,392 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __BFI_H__
+#define __BFI_H__
+
+#include "bfa_defs.h"
+
+#pragma pack(1)
+
+/**
+ * BFI FW image type
+ */
+#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */
+#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
+enum {
+ BFI_IMAGE_CB_FC,
+ BFI_IMAGE_CT_FC,
+ BFI_IMAGE_CT_CNA,
+ BFI_IMAGE_MAX,
+};
+
+/**
+ * Msg header common to all msgs
+ */
+struct bfi_mhdr {
+ u8 msg_class; /*!< @ref enum bfi_mclass */
+ u8 msg_id; /*!< msg opcode with in the class */
+ union {
+ struct {
+ u8 rsvd;
+ u8 lpu_id; /*!< msg destination */
+ } h2i;
+ u16 i2htok; /*!< token in msgs to host */
+ } mtag;
+};
+
+#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \
+ (_mh).msg_class = (_mc); \
+ (_mh).msg_id = (_op); \
+ (_mh).mtag.h2i.lpu_id = (_lpuid); \
+} while (0)
+
+#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \
+ (_mh).msg_class = (_mc); \
+ (_mh).msg_id = (_op); \
+ (_mh).mtag.i2htok = (_i2htok); \
+} while (0)
+
+/*
+ * Message opcodes: 0-127 to firmware, 128-255 to host
+ */
+#define BFI_I2H_OPCODE_BASE 128
+#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE)
+
+/**
+ ****************************************************************************
+ *
+ * Scatter Gather Element and Page definition
+ *
+ ****************************************************************************
+ */
+
+#define BFI_SGE_INLINE 1
+#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1)
+
+/**
+ * SG Flags
+ */
+enum {
+ BFI_SGE_DATA = 0, /*!< data address, not last */
+ BFI_SGE_DATA_CPL = 1, /*!< data addr, last in current page */
+ BFI_SGE_DATA_LAST = 3, /*!< data address, last */
+ BFI_SGE_LINK = 2, /*!< link address */
+ BFI_SGE_PGDLEN = 2, /*!< cumulative data length for page */
+};
+
+/**
+ * DMA addresses
+ */
+union bfi_addr_u {
+ struct {
+ u32 addr_lo;
+ u32 addr_hi;
+ } a32;
+};
+
+/**
+ * Scatter Gather Element
+ */
+struct bfi_sge {
+#ifdef __BIGENDIAN
+ u32 flags:2,
+ rsvd:2,
+ sg_len:28;
+#else
+ u32 sg_len:28,
+ rsvd:2,
+ flags:2;
+#endif
+ union bfi_addr_u sga;
+};
+
+/**
+ * Scatter Gather Page
+ */
+#define BFI_SGPG_DATA_SGES 7
+#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1)
+#define BFI_SGPG_RSVD_WD_LEN 8
+struct bfi_sgpg {
+ struct bfi_sge sges[BFI_SGPG_SGES_MAX];
+ u32 rsvd[BFI_SGPG_RSVD_WD_LEN];
+};
+
+/*
+ * Large Message structure - 128 Bytes size Msgs
+ */
+#define BFI_LMSG_SZ 128
+#define BFI_LMSG_PL_WSZ \
+ ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr)) / 4)
+
+struct bfi_msg {
+ struct bfi_mhdr mhdr;
+ u32 pl[BFI_LMSG_PL_WSZ];
+};
+
+/**
+ * Mailbox message structure
+ */
+#define BFI_MBMSG_SZ 7
+struct bfi_mbmsg {
+ struct bfi_mhdr mh;
+ u32 pl[BFI_MBMSG_SZ];
+};
+
+/**
+ * Message Classes
+ */
+enum bfi_mclass {
+ BFI_MC_IOC = 1, /*!< IO Controller (IOC) */
+ BFI_MC_DIAG = 2, /*!< Diagnostic Msgs */
+ BFI_MC_FLASH = 3, /*!< Flash message class */
+ BFI_MC_CEE = 4, /*!< CEE */
+ BFI_MC_FCPORT = 5, /*!< FC port */
+ BFI_MC_IOCFC = 6, /*!< FC - IO Controller (IOC) */
+ BFI_MC_LL = 7, /*!< Link Layer */
+ BFI_MC_UF = 8, /*!< Unsolicited frame receive */
+ BFI_MC_FCXP = 9, /*!< FC Transport */
+ BFI_MC_LPS = 10, /*!< lport fc login services */
+ BFI_MC_RPORT = 11, /*!< Remote port */
+ BFI_MC_ITNIM = 12, /*!< I-T nexus (Initiator mode) */
+ BFI_MC_IOIM_READ = 13, /*!< read IO (Initiator mode) */
+ BFI_MC_IOIM_WRITE = 14, /*!< write IO (Initiator mode) */
+ BFI_MC_IOIM_IO = 15, /*!< IO (Initiator mode) */
+ BFI_MC_IOIM = 16, /*!< IO (Initiator mode) */
+ BFI_MC_IOIM_IOCOM = 17, /*!< good IO completion */
+ BFI_MC_TSKIM = 18, /*!< Initiator Task management */
+ BFI_MC_SBOOT = 19, /*!< SAN boot services */
+ BFI_MC_IPFC = 20, /*!< IP over FC Msgs */
+ BFI_MC_PORT = 21, /*!< Physical port */
+ BFI_MC_SFP = 22, /*!< SFP module */
+ BFI_MC_MSGQ = 23, /*!< MSGQ */
+ BFI_MC_ENET = 24, /*!< ENET commands/responses */
+ BFI_MC_MAX = 32
+};
+
+#define BFI_IOC_MAX_CQS 4
+#define BFI_IOC_MAX_CQS_ASIC 8
+#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */
+
+#define BFI_BOOT_TYPE_OFF 8
+#define BFI_BOOT_PARAM_OFF 12
+
+#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */
+#define BFI_BOOT_TYPE_FLASH 1
+#define BFI_BOOT_TYPE_MEMTEST 2
+
+#define BFI_BOOT_MEMTEST_RES_ADDR 0x900
+#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3
+
+/**
+ *----------------------------------------------------------------------
+ * IOC
+ *----------------------------------------------------------------------
+ */
+
+enum bfi_ioc_h2i_msgs {
+ BFI_IOC_H2I_ENABLE_REQ = 1,
+ BFI_IOC_H2I_DISABLE_REQ = 2,
+ BFI_IOC_H2I_GETATTR_REQ = 3,
+ BFI_IOC_H2I_DBG_SYNC = 4,
+ BFI_IOC_H2I_DBG_DUMP = 5,
+};
+
+enum bfi_ioc_i2h_msgs {
+ BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
+ BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
+ BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
+ BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
+ BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
+};
+
+/**
+ * BFI_IOC_H2I_GETATTR_REQ message
+ */
+struct bfi_ioc_getattr_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u attr_addr;
+};
+
+struct bfi_ioc_attr {
+ u64 mfg_pwwn; /*!< Mfg port wwn */
+ u64 mfg_nwwn; /*!< Mfg node wwn */
+ mac_t mfg_mac; /*!< Mfg mac */
+ u16 rsvd_a;
+ u64 pwwn;
+ u64 nwwn;
+ mac_t mac; /*!< PBC or Mfg mac */
+ u16 rsvd_b;
+ mac_t fcoe_mac;
+ u16 rsvd_c;
+ char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
+ u8 pcie_gen;
+ u8 pcie_lanes_orig;
+ u8 pcie_lanes;
+ u8 rx_bbcredit; /*!< receive buffer credits */
+ u32 adapter_prop; /*!< adapter properties */
+ u16 maxfrsize; /*!< max receive frame size */
+ char asic_rev;
+ u8 rsvd_d;
+ char fw_version[BFA_VERSION_LEN];
+ char optrom_version[BFA_VERSION_LEN];
+ struct bfa_mfg_vpd vpd;
+ u32 card_type; /*!< card type */
+};
+
+/**
+ * BFI_IOC_I2H_GETATTR_REPLY message
+ */
+struct bfi_ioc_getattr_reply {
+ struct bfi_mhdr mh; /*!< Common msg header */
+ u8 status; /*!< cfg reply status */
+ u8 rsvd[3];
+};
+
+/**
+ * Firmware memory page offsets
+ */
+#define BFI_IOC_SMEM_PG0_CB (0x40)
+#define BFI_IOC_SMEM_PG0_CT (0x180)
+
+/**
+ * Firmware statistic offset
+ */
+#define BFI_IOC_FWSTATS_OFF (0x6B40)
+#define BFI_IOC_FWSTATS_SZ (4096)
+
+/**
+ * Firmware trace offset
+ */
+#define BFI_IOC_TRC_OFF (0x4b00)
+#define BFI_IOC_TRC_ENTS 256
+
+#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
+#define BFI_IOC_MD5SUM_SZ 4
+struct bfi_ioc_image_hdr {
+ u32 signature; /*!< constant signature */
+ u32 rsvd_a;
+ u32 exec; /*!< exec vector */
+ u32 param; /*!< parameters */
+ u32 rsvd_b[4];
+ u32 md5sum[BFI_IOC_MD5SUM_SZ];
+};
+
+/**
+ * BFI_IOC_I2H_READY_EVENT message
+ */
+struct bfi_ioc_rdy_event {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 init_status; /*!< init event status */
+ u8 rsvd[3];
+};
+
+struct bfi_ioc_hbeat {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 hb_count; /*!< current heart beat count */
+};
+
+/**
+ * IOC hardware/firmware state
+ */
+enum bfi_ioc_state {
+ BFI_IOC_UNINIT = 0, /*!< not initialized */
+ BFI_IOC_INITING = 1, /*!< h/w is being initialized */
+ BFI_IOC_HWINIT = 2, /*!< h/w is initialized */
+ BFI_IOC_CFG = 3, /*!< IOC configuration in progress */
+ BFI_IOC_OP = 4, /*!< IOC is operational */
+ BFI_IOC_DISABLING = 5, /*!< IOC is being disabled */
+ BFI_IOC_DISABLED = 6, /*!< IOC is disabled */
+ BFI_IOC_CFG_DISABLED = 7, /*!< IOC is being disabled;transient */
+ BFI_IOC_FAIL = 8, /*!< IOC heart-beat failure */
+ BFI_IOC_MEMTEST = 9, /*!< IOC is doing memtest */
+};
+
+#define BFI_IOC_ENDIAN_SIG 0x12345678
+
+enum {
+ BFI_ADAPTER_TYPE_FC = 0x01, /*!< FC adapters */
+ BFI_ADAPTER_TYPE_MK = 0x0f0000, /*!< adapter type mask */
+ BFI_ADAPTER_TYPE_SH = 16, /*!< adapter type shift */
+ BFI_ADAPTER_NPORTS_MK = 0xff00, /*!< number of ports mask */
+ BFI_ADAPTER_NPORTS_SH = 8, /*!< number of ports shift */
+ BFI_ADAPTER_SPEED_MK = 0xff, /*!< adapter speed mask */
+ BFI_ADAPTER_SPEED_SH = 0, /*!< adapter speed shift */
+ BFI_ADAPTER_PROTO = 0x100000, /*!< prototype adapaters */
+ BFI_ADAPTER_TTV = 0x200000, /*!< TTV debug capable */
+ BFI_ADAPTER_UNSUPP = 0x400000, /*!< unknown adapter type */
+};
+
+#define BFI_ADAPTER_GETP(__prop, __adap_prop) \
+ (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \
+ BFI_ADAPTER_ ## __prop ## _SH)
+#define BFI_ADAPTER_SETP(__prop, __val) \
+ ((__val) << BFI_ADAPTER_ ## __prop ## _SH)
+#define BFI_ADAPTER_IS_PROTO(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_PROTO)
+#define BFI_ADAPTER_IS_TTV(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_TTV)
+#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \
+ ((__adap_type) & BFI_ADAPTER_UNSUPP)
+#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \
+ ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \
+ BFI_ADAPTER_UNSUPP))
+
+/**
+ * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages
+ */
+struct bfi_ioc_ctrl_req {
+ struct bfi_mhdr mh;
+ u8 ioc_class;
+ u8 rsvd[3];
+ u32 tv_sec;
+};
+
+/**
+ * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
+ */
+struct bfi_ioc_ctrl_reply {
+ struct bfi_mhdr mh; /*!< Common msg header */
+ u8 status; /*!< enable/disable status */
+ u8 rsvd[3];
+};
+
+#define BFI_IOC_MSGSZ 8
+/**
+ * H2I Messages
+ */
+union bfi_ioc_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_ioc_ctrl_req enable_req;
+ struct bfi_ioc_ctrl_req disable_req;
+ struct bfi_ioc_getattr_req getattr_req;
+ u32 mboxmsg[BFI_IOC_MSGSZ];
+};
+
+/**
+ * I2H Messages
+ */
+union bfi_ioc_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_ioc_rdy_event rdy_event;
+ u32 mboxmsg[BFI_IOC_MSGSZ];
+};
+
+#pragma pack()
+
+#endif /* __BFI_H__ */
diff --git a/drivers/net/bna/bfi_cna.h b/drivers/net/bna/bfi_cna.h
new file mode 100644
index 000000000000..4eecabea397b
--- /dev/null
+++ b/drivers/net/bna/bfi_cna.h
@@ -0,0 +1,199 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFI_CNA_H__
+#define __BFI_CNA_H__
+
+#include "bfi.h"
+#include "bfa_defs_cna.h"
+
+#pragma pack(1)
+
+enum bfi_port_h2i {
+ BFI_PORT_H2I_ENABLE_REQ = (1),
+ BFI_PORT_H2I_DISABLE_REQ = (2),
+ BFI_PORT_H2I_GET_STATS_REQ = (3),
+ BFI_PORT_H2I_CLEAR_STATS_REQ = (4),
+};
+
+enum bfi_port_i2h {
+ BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1),
+ BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2),
+ BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
+ BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
+};
+
+/**
+ * Generic REQ type
+ */
+struct bfi_port_generic_req {
+ struct bfi_mhdr mh; /*!< msg header */
+ u32 msgtag; /*!< msgtag for reply */
+ u32 rsvd;
+};
+
+/**
+ * Generic RSP type
+ */
+struct bfi_port_generic_rsp {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 status; /*!< port enable status */
+ u8 rsvd[3];
+ u32 msgtag; /*!< msgtag for reply */
+};
+
+/**
+ * @todo
+ * BFI_PORT_H2I_ENABLE_REQ
+ */
+
+/**
+ * @todo
+ * BFI_PORT_I2H_ENABLE_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_DISABLE_REQ
+ */
+
+/**
+ * BFI_PORT_I2H_DISABLE_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_GET_STATS_REQ
+ */
+struct bfi_port_get_stats_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ union bfi_addr_u dma_addr;
+};
+
+/**
+ * BFI_PORT_I2H_GET_STATS_RSP
+ */
+
+/**
+ * BFI_PORT_H2I_CLEAR_STATS_REQ
+ */
+
+/**
+ * BFI_PORT_I2H_CLEAR_STATS_RSP
+ */
+
+union bfi_port_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_port_generic_req enable_req;
+ struct bfi_port_generic_req disable_req;
+ struct bfi_port_get_stats_req getstats_req;
+ struct bfi_port_generic_req clearstats_req;
+};
+
+union bfi_port_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_port_generic_rsp enable_rsp;
+ struct bfi_port_generic_rsp disable_rsp;
+ struct bfi_port_generic_rsp getstats_rsp;
+ struct bfi_port_generic_rsp clearstats_rsp;
+};
+
+/* @brief Mailbox commands from host to (DCBX/LLDP) firmware */
+enum bfi_cee_h2i_msgs {
+ BFI_CEE_H2I_GET_CFG_REQ = 1,
+ BFI_CEE_H2I_RESET_STATS = 2,
+ BFI_CEE_H2I_GET_STATS_REQ = 3,
+};
+
+/* @brief Mailbox reply and AEN messages from DCBX/LLDP firmware to host */
+enum bfi_cee_i2h_msgs {
+ BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1),
+ BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2),
+ BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3),
+};
+
+/* Data structures */
+
+/*
+ * @brief H2I command structure for resetting the stats.
+ * BFI_CEE_H2I_RESET_STATS
+ */
+struct bfi_lldp_reset_stats {
+ struct bfi_mhdr mh;
+};
+
+/*
+ * @brief H2I command structure for resetting the stats.
+ * BFI_CEE_H2I_RESET_STATS
+ */
+struct bfi_cee_reset_stats {
+ struct bfi_mhdr mh;
+};
+
+/*
+ * @brief get configuration command from host
+ * BFI_CEE_H2I_GET_CFG_REQ
+ */
+struct bfi_cee_get_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u dma_addr;
+};
+
+/*
+ * @brief reply message from firmware
+ * BFI_CEE_I2H_GET_CFG_RSP
+ */
+struct bfi_cee_get_rsp {
+ struct bfi_mhdr mh;
+ u8 cmd_status;
+ u8 rsvd[3];
+};
+
+/*
+ * @brief get configuration command from host
+ * BFI_CEE_H2I_GET_STATS_REQ
+ */
+struct bfi_cee_stats_req {
+ struct bfi_mhdr mh;
+ union bfi_addr_u dma_addr;
+};
+
+/*
+ * @brief reply message from firmware
+ * BFI_CEE_I2H_GET_STATS_RSP
+ */
+struct bfi_cee_stats_rsp {
+ struct bfi_mhdr mh;
+ u8 cmd_status;
+ u8 rsvd[3];
+};
+
+/* @brief mailbox command structures from host to firmware */
+union bfi_cee_h2i_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_cee_get_req get_req;
+ struct bfi_cee_stats_req stats_req;
+};
+
+/* @brief mailbox message structures from firmware to host */
+union bfi_cee_i2h_msg_u {
+ struct bfi_mhdr mh;
+ struct bfi_cee_get_rsp get_rsp;
+ struct bfi_cee_stats_rsp stats_rsp;
+};
+
+#pragma pack()
+
+#endif /* __BFI_CNA_H__ */
diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h
new file mode 100644
index 000000000000..404ea351d4a1
--- /dev/null
+++ b/drivers/net/bna/bfi_ctreg.h
@@ -0,0 +1,637 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+/*
+ * bfi_ctreg.h catapult host block register definitions
+ *
+ * !!! Do not edit. Auto generated. !!!
+ */
+
+#ifndef __BFI_CTREG_H__
+#define __BFI_CTREG_H__
+
+#define HOSTFN0_LPU_MBOX0_0 0x00019200
+#define HOSTFN1_LPU_MBOX0_8 0x00019260
+#define LPU_HOSTFN0_MBOX0_0 0x00019280
+#define LPU_HOSTFN1_MBOX0_8 0x000192e0
+#define HOSTFN2_LPU_MBOX0_0 0x00019400
+#define HOSTFN3_LPU_MBOX0_8 0x00019460
+#define LPU_HOSTFN2_MBOX0_0 0x00019480
+#define LPU_HOSTFN3_MBOX0_8 0x000194e0
+#define HOSTFN0_INT_STATUS 0x00014000
+#define __HOSTFN0_HALT_OCCURRED 0x01000000
+#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN0_INT_STATUS_LVL_SH 20
+#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
+#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN0_INT_STATUS_P_SH 16
+#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH)
+#define __HOSTFN0_INT_STATUS_F 0x0000ffff
+#define HOSTFN0_INT_MSK 0x00014004
+#define HOST_PAGE_NUM_FN0 0x00014008
+#define __HOST_PAGE_NUM_FN 0x000001ff
+#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c
+#define __MSIX_ERR_INDEX_FN 0x000001ff
+#define HOSTFN1_INT_STATUS 0x00014100
+#define __HOSTFN1_HALT_OCCURRED 0x01000000
+#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN1_INT_STATUS_LVL_SH 20
+#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH)
+#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN1_INT_STATUS_P_SH 16
+#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH)
+#define __HOSTFN1_INT_STATUS_F 0x0000ffff
+#define HOSTFN1_INT_MSK 0x00014104
+#define HOST_PAGE_NUM_FN1 0x00014108
+#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c
+#define APP_PLL_425_CTL_REG 0x00014204
+#define __P_425_PLL_LOCK 0x80000000
+#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000
+#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000
+#define __APP_PLL_425_RESET_TIMER_SH 17
+#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH)
+#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000
+#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000
+#define __APP_PLL_425_CNTLMT0_1_SH 14
+#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH)
+#define __APP_PLL_425_JITLMT0_1_MK 0x00003000
+#define __APP_PLL_425_JITLMT0_1_SH 12
+#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH)
+#define __APP_PLL_425_HREF 0x00000800
+#define __APP_PLL_425_HDIV 0x00000400
+#define __APP_PLL_425_P0_1_MK 0x00000300
+#define __APP_PLL_425_P0_1_SH 8
+#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH)
+#define __APP_PLL_425_Z0_2_MK 0x000000e0
+#define __APP_PLL_425_Z0_2_SH 5
+#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH)
+#define __APP_PLL_425_RSEL200500 0x00000010
+#define __APP_PLL_425_ENARST 0x00000008
+#define __APP_PLL_425_BYPASS 0x00000004
+#define __APP_PLL_425_LRESETN 0x00000002
+#define __APP_PLL_425_ENABLE 0x00000001
+#define APP_PLL_312_CTL_REG 0x00014208
+#define __P_312_PLL_LOCK 0x80000000
+#define __ENABLE_MAC_AHB_1 0x00800000
+#define __ENABLE_MAC_AHB_0 0x00400000
+#define __ENABLE_MAC_1 0x00200000
+#define __ENABLE_MAC_0 0x00100000
+#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000
+#define __APP_PLL_312_RESET_TIMER_SH 17
+#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH)
+#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000
+#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000
+#define __APP_PLL_312_CNTLMT0_1_SH 14
+#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH)
+#define __APP_PLL_312_JITLMT0_1_MK 0x00003000
+#define __APP_PLL_312_JITLMT0_1_SH 12
+#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH)
+#define __APP_PLL_312_HREF 0x00000800
+#define __APP_PLL_312_HDIV 0x00000400
+#define __APP_PLL_312_P0_1_MK 0x00000300
+#define __APP_PLL_312_P0_1_SH 8
+#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH)
+#define __APP_PLL_312_Z0_2_MK 0x000000e0
+#define __APP_PLL_312_Z0_2_SH 5
+#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH)
+#define __APP_PLL_312_RSEL200500 0x00000010
+#define __APP_PLL_312_ENARST 0x00000008
+#define __APP_PLL_312_BYPASS 0x00000004
+#define __APP_PLL_312_LRESETN 0x00000002
+#define __APP_PLL_312_ENABLE 0x00000001
+#define MBIST_CTL_REG 0x00014220
+#define __EDRAM_BISTR_START 0x00000004
+#define __MBIST_RESET 0x00000002
+#define __MBIST_START 0x00000001
+#define MBIST_STAT_REG 0x00014224
+#define __EDRAM_BISTR_STATUS 0x00000008
+#define __EDRAM_BISTR_DONE 0x00000004
+#define __MEM_BIT_STATUS 0x00000002
+#define __MBIST_DONE 0x00000001
+#define HOST_SEM0_REG 0x00014230
+#define __HOST_SEMAPHORE 0x00000001
+#define HOST_SEM1_REG 0x00014234
+#define HOST_SEM2_REG 0x00014238
+#define HOST_SEM3_REG 0x0001423c
+#define HOST_SEM0_INFO_REG 0x00014240
+#define HOST_SEM1_INFO_REG 0x00014244
+#define HOST_SEM2_INFO_REG 0x00014248
+#define HOST_SEM3_INFO_REG 0x0001424c
+#define ETH_MAC_SER_REG 0x00014288
+#define __APP_EMS_CKBUFAMPIN 0x00000020
+#define __APP_EMS_REFCLKSEL 0x00000010
+#define __APP_EMS_CMLCKSEL 0x00000008
+#define __APP_EMS_REFCKBUFEN2 0x00000004
+#define __APP_EMS_REFCKBUFEN1 0x00000002
+#define __APP_EMS_CHANNEL_SEL 0x00000001
+#define HOSTFN2_INT_STATUS 0x00014300
+#define __HOSTFN2_HALT_OCCURRED 0x01000000
+#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN2_INT_STATUS_LVL_SH 20
+#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH)
+#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN2_INT_STATUS_P_SH 16
+#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH)
+#define __HOSTFN2_INT_STATUS_F 0x0000ffff
+#define HOSTFN2_INT_MSK 0x00014304
+#define HOST_PAGE_NUM_FN2 0x00014308
+#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c
+#define HOSTFN3_INT_STATUS 0x00014400
+#define __HALT_OCCURRED 0x01000000
+#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000
+#define __HOSTFN3_INT_STATUS_LVL_SH 20
+#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH)
+#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000
+#define __HOSTFN3_INT_STATUS_P_SH 16
+#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH)
+#define __HOSTFN3_INT_STATUS_F 0x0000ffff
+#define HOSTFN3_INT_MSK 0x00014404
+#define HOST_PAGE_NUM_FN3 0x00014408
+#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c
+#define FNC_ID_REG 0x00014600
+#define __FUNCTION_NUMBER 0x00000007
+#define FNC_PERS_REG 0x00014604
+#define __F3_FUNCTION_ACTIVE 0x80000000
+#define __F3_FUNCTION_MODE 0x40000000
+#define __F3_PORT_MAP_MK 0x30000000
+#define __F3_PORT_MAP_SH 28
+#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH)
+#define __F3_VM_MODE 0x08000000
+#define __F3_INTX_STATUS_MK 0x07000000
+#define __F3_INTX_STATUS_SH 24
+#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH)
+#define __F2_FUNCTION_ACTIVE 0x00800000
+#define __F2_FUNCTION_MODE 0x00400000
+#define __F2_PORT_MAP_MK 0x00300000
+#define __F2_PORT_MAP_SH 20
+#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH)
+#define __F2_VM_MODE 0x00080000
+#define __F2_INTX_STATUS_MK 0x00070000
+#define __F2_INTX_STATUS_SH 16
+#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH)
+#define __F1_FUNCTION_ACTIVE 0x00008000
+#define __F1_FUNCTION_MODE 0x00004000
+#define __F1_PORT_MAP_MK 0x00003000
+#define __F1_PORT_MAP_SH 12
+#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH)
+#define __F1_VM_MODE 0x00000800
+#define __F1_INTX_STATUS_MK 0x00000700
+#define __F1_INTX_STATUS_SH 8
+#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH)
+#define __F0_FUNCTION_ACTIVE 0x00000080
+#define __F0_FUNCTION_MODE 0x00000040
+#define __F0_PORT_MAP_MK 0x00000030
+#define __F0_PORT_MAP_SH 4
+#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH)
+#define __F0_VM_MODE 0x00000008
+#define __F0_INTX_STATUS 0x00000007
+enum {
+ __F0_INTX_STATUS_MSIX = 0x0,
+ __F0_INTX_STATUS_INTA = 0x1,
+ __F0_INTX_STATUS_INTB = 0x2,
+ __F0_INTX_STATUS_INTC = 0x3,
+ __F0_INTX_STATUS_INTD = 0x4,
+};
+#define OP_MODE 0x0001460c
+#define __APP_ETH_CLK_LOWSPEED 0x00000004
+#define __GLOBAL_CORECLK_HALFSPEED 0x00000002
+#define __GLOBAL_FCOE_MODE 0x00000001
+#define HOST_SEM4_REG 0x00014610
+#define HOST_SEM5_REG 0x00014614
+#define HOST_SEM6_REG 0x00014618
+#define HOST_SEM7_REG 0x0001461c
+#define HOST_SEM4_INFO_REG 0x00014620
+#define HOST_SEM5_INFO_REG 0x00014624
+#define HOST_SEM6_INFO_REG 0x00014628
+#define HOST_SEM7_INFO_REG 0x0001462c
+#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000
+#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004
+#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008
+#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c
+#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010
+#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014
+#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018
+#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c
+#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150
+#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154
+#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158
+#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c
+#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160
+#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1
+#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH)
+#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001
+#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164
+#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe
+#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1
+#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH)
+#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001
+#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168
+#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
+#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1
+#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH)
+#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
+#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c
+#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
+#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1
+#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH)
+#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
+#define FW_INIT_HALT_P0 0x000191ac
+#define __FW_INIT_HALT_P 0x00000001
+#define FW_INIT_HALT_P1 0x000191bc
+#define CPE_PI_PTR_Q0 0x00038000
+#define __CPE_PI_UNUSED_MK 0xffff0000
+#define __CPE_PI_UNUSED_SH 16
+#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH)
+#define __CPE_PI_PTR 0x0000ffff
+#define CPE_PI_PTR_Q1 0x00038040
+#define CPE_CI_PTR_Q0 0x00038004
+#define __CPE_CI_UNUSED_MK 0xffff0000
+#define __CPE_CI_UNUSED_SH 16
+#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH)
+#define __CPE_CI_PTR 0x0000ffff
+#define CPE_CI_PTR_Q1 0x00038044
+#define CPE_DEPTH_Q0 0x00038008
+#define __CPE_DEPTH_UNUSED_MK 0xf8000000
+#define __CPE_DEPTH_UNUSED_SH 27
+#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH)
+#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000
+#define __CPE_MSIX_VEC_INDEX_SH 16
+#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH)
+#define __CPE_DEPTH 0x0000ffff
+#define CPE_DEPTH_Q1 0x00038048
+#define CPE_QCTRL_Q0 0x0003800c
+#define __CPE_CTRL_UNUSED30_MK 0xfc000000
+#define __CPE_CTRL_UNUSED30_SH 26
+#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH)
+#define __CPE_FUNC_INT_CTRL_MK 0x03000000
+#define __CPE_FUNC_INT_CTRL_SH 24
+#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH)
+enum {
+ __CPE_FUNC_INT_CTRL_DISABLE = 0x0,
+ __CPE_FUNC_INT_CTRL_F2NF = 0x1,
+ __CPE_FUNC_INT_CTRL_3QUART = 0x2,
+ __CPE_FUNC_INT_CTRL_HALF = 0x3,
+};
+#define __CPE_CTRL_UNUSED20_MK 0x00f00000
+#define __CPE_CTRL_UNUSED20_SH 20
+#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH)
+#define __CPE_SCI_TH_MK 0x000f0000
+#define __CPE_SCI_TH_SH 16
+#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH)
+#define __CPE_CTRL_UNUSED10_MK 0x0000c000
+#define __CPE_CTRL_UNUSED10_SH 14
+#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH)
+#define __CPE_ACK_PENDING 0x00002000
+#define __CPE_CTRL_UNUSED40_MK 0x00001c00
+#define __CPE_CTRL_UNUSED40_SH 10
+#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH)
+#define __CPE_PCIEID_MK 0x00000300
+#define __CPE_PCIEID_SH 8
+#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH)
+#define __CPE_CTRL_UNUSED00_MK 0x000000fe
+#define __CPE_CTRL_UNUSED00_SH 1
+#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH)
+#define __CPE_ESIZE 0x00000001
+#define CPE_QCTRL_Q1 0x0003804c
+#define __CPE_CTRL_UNUSED31_MK 0xfc000000
+#define __CPE_CTRL_UNUSED31_SH 26
+#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH)
+#define __CPE_CTRL_UNUSED21_MK 0x00f00000
+#define __CPE_CTRL_UNUSED21_SH 20
+#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH)
+#define __CPE_CTRL_UNUSED11_MK 0x0000c000
+#define __CPE_CTRL_UNUSED11_SH 14
+#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH)
+#define __CPE_CTRL_UNUSED41_MK 0x00001c00
+#define __CPE_CTRL_UNUSED41_SH 10
+#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH)
+#define __CPE_CTRL_UNUSED01_MK 0x000000fe
+#define __CPE_CTRL_UNUSED01_SH 1
+#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH)
+#define RME_PI_PTR_Q0 0x00038020
+#define __LATENCY_TIME_STAMP_MK 0xffff0000
+#define __LATENCY_TIME_STAMP_SH 16
+#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH)
+#define __RME_PI_PTR 0x0000ffff
+#define RME_PI_PTR_Q1 0x00038060
+#define RME_CI_PTR_Q0 0x00038024
+#define __DELAY_TIME_STAMP_MK 0xffff0000
+#define __DELAY_TIME_STAMP_SH 16
+#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH)
+#define __RME_CI_PTR 0x0000ffff
+#define RME_CI_PTR_Q1 0x00038064
+#define RME_DEPTH_Q0 0x00038028
+#define __RME_DEPTH_UNUSED_MK 0xf8000000
+#define __RME_DEPTH_UNUSED_SH 27
+#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH)
+#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000
+#define __RME_MSIX_VEC_INDEX_SH 16
+#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH)
+#define __RME_DEPTH 0x0000ffff
+#define RME_DEPTH_Q1 0x00038068
+#define RME_QCTRL_Q0 0x0003802c
+#define __RME_INT_LATENCY_TIMER_MK 0xff000000
+#define __RME_INT_LATENCY_TIMER_SH 24
+#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH)
+#define __RME_INT_DELAY_TIMER_MK 0x00ff0000
+#define __RME_INT_DELAY_TIMER_SH 16
+#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH)
+#define __RME_INT_DELAY_DISABLE 0x00008000
+#define __RME_DLY_DELAY_DISABLE 0x00004000
+#define __RME_ACK_PENDING 0x00002000
+#define __RME_FULL_INTERRUPT_DISABLE 0x00001000
+#define __RME_CTRL_UNUSED10_MK 0x00000c00
+#define __RME_CTRL_UNUSED10_SH 10
+#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH)
+#define __RME_PCIEID_MK 0x00000300
+#define __RME_PCIEID_SH 8
+#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH)
+#define __RME_CTRL_UNUSED00_MK 0x000000fe
+#define __RME_CTRL_UNUSED00_SH 1
+#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH)
+#define __RME_ESIZE 0x00000001
+#define RME_QCTRL_Q1 0x0003806c
+#define __RME_CTRL_UNUSED11_MK 0x00000c00
+#define __RME_CTRL_UNUSED11_SH 10
+#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH)
+#define __RME_CTRL_UNUSED01_MK 0x000000fe
+#define __RME_CTRL_UNUSED01_SH 1
+#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH)
+#define PSS_CTL_REG 0x00018800
+#define __PSS_I2C_CLK_DIV_MK 0x007f0000
+#define __PSS_I2C_CLK_DIV_SH 16
+#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
+#define __PSS_LMEM_INIT_DONE 0x00001000
+#define __PSS_LMEM_RESET 0x00000200
+#define __PSS_LMEM_INIT_EN 0x00000100
+#define __PSS_LPU1_RESET 0x00000002
+#define __PSS_LPU0_RESET 0x00000001
+#define PSS_ERR_STATUS_REG 0x00018810
+#define __PSS_LPU1_TCM_READ_ERR 0x00200000
+#define __PSS_LPU0_TCM_READ_ERR 0x00100000
+#define __PSS_LMEM5_CORR_ERR 0x00080000
+#define __PSS_LMEM4_CORR_ERR 0x00040000
+#define __PSS_LMEM3_CORR_ERR 0x00020000
+#define __PSS_LMEM2_CORR_ERR 0x00010000
+#define __PSS_LMEM1_CORR_ERR 0x00008000
+#define __PSS_LMEM0_CORR_ERR 0x00004000
+#define __PSS_LMEM5_UNCORR_ERR 0x00002000
+#define __PSS_LMEM4_UNCORR_ERR 0x00001000
+#define __PSS_LMEM3_UNCORR_ERR 0x00000800
+#define __PSS_LMEM2_UNCORR_ERR 0x00000400
+#define __PSS_LMEM1_UNCORR_ERR 0x00000200
+#define __PSS_LMEM0_UNCORR_ERR 0x00000100
+#define __PSS_BAL_PERR 0x00000080
+#define __PSS_DIP_IF_ERR 0x00000040
+#define __PSS_IOH_IF_ERR 0x00000020
+#define __PSS_TDS_IF_ERR 0x00000010
+#define __PSS_RDS_IF_ERR 0x00000008
+#define __PSS_SGM_IF_ERR 0x00000004
+#define __PSS_LPU1_RAM_ERR 0x00000002
+#define __PSS_LPU0_RAM_ERR 0x00000001
+#define ERR_SET_REG 0x00018818
+#define __PSS_ERR_STATUS_SET 0x003fffff
+#define PMM_1T_RESET_REG_P0 0x0002381c
+#define __PMM_1T_RESET_P 0x00000001
+#define PMM_1T_RESET_REG_P1 0x00023c1c
+#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
+#define __RXQ0_ADD_VECTORS_P 0x80000000
+#define __RXQ0_STOP_P 0x40000000
+#define __RXQ0_PRD_PTR_P 0x0000ffff
+#define HQM_QSET1_RXQ_DRBL_P0 0x00038080
+#define __RXQ1_ADD_VECTORS_P 0x80000000
+#define __RXQ1_STOP_P 0x40000000
+#define __RXQ1_PRD_PTR_P 0x0000ffff
+#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000
+#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080
+#define HQM_QSET0_TXQ_DRBL_P0 0x00038020
+#define __TXQ0_ADD_VECTORS_P 0x80000000
+#define __TXQ0_STOP_P 0x40000000
+#define __TXQ0_PRD_PTR_P 0x0000ffff
+#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0
+#define __TXQ1_ADD_VECTORS_P 0x80000000
+#define __TXQ1_STOP_P 0x40000000
+#define __TXQ1_PRD_PTR_P 0x0000ffff
+#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020
+#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0
+#define HQM_QSET0_IB_DRBL_1_P0 0x00038040
+#define __IB1_0_ACK_P 0x80000000
+#define __IB1_0_DISABLE_P 0x40000000
+#define __IB1_0_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB1_0_COALESCING_CFG_P_SH 16
+#define __IB1_0_COALESCING_CFG_P(_v) ((_v) << __IB1_0_COALESCING_CFG_P_SH)
+#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0
+#define __IB1_1_ACK_P 0x80000000
+#define __IB1_1_DISABLE_P 0x40000000
+#define __IB1_1_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB1_1_COALESCING_CFG_P_SH 16
+#define __IB1_1_COALESCING_CFG_P(_v) ((_v) << __IB1_1_COALESCING_CFG_P_SH)
+#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040
+#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0
+#define HQM_QSET0_IB_DRBL_2_P0 0x00038060
+#define __IB2_0_ACK_P 0x80000000
+#define __IB2_0_DISABLE_P 0x40000000
+#define __IB2_0_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB2_0_COALESCING_CFG_P_SH 16
+#define __IB2_0_COALESCING_CFG_P(_v) ((_v) << __IB2_0_COALESCING_CFG_P_SH)
+#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0
+#define __IB2_1_ACK_P 0x80000000
+#define __IB2_1_DISABLE_P 0x40000000
+#define __IB2_1_COALESCING_CFG_P_MK 0x00ff0000
+#define __IB2_1_COALESCING_CFG_P_SH 16
+#define __IB2_1_COALESCING_CFG_P(_v) ((_v) << __IB2_1_COALESCING_CFG_P_SH)
+#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
+#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060
+#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0
+
+/*
+ * These definitions are either in error/missing in spec. Its auto-generated
+ * from hard coded values in regparse.pl.
+ */
+#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
+#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
+#define __EMPHPRE_AT_4G_FIX 0x00000003
+#define __SFP_TXRATE_EN_FIX 0x00000100
+#define __SFP_RXRATE_EN_FIX 0x00000080
+
+/*
+ * These register definitions are auto-generated from hard coded values
+ * in regparse.pl.
+ */
+
+/*
+ * These register mapping definitions are auto-generated from mapping tables
+ * in regparse.pl.
+ */
+#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
+#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
+#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
+#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
+#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
+
+#define CPE_DEPTH_Q(__n) \
+ (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
+#define CPE_QCTRL_Q(__n) \
+ (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0))
+#define CPE_PI_PTR_Q(__n) \
+ (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0))
+#define CPE_CI_PTR_Q(__n) \
+ (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0))
+#define RME_DEPTH_Q(__n) \
+ (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0))
+#define RME_QCTRL_Q(__n) \
+ (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0))
+#define RME_PI_PTR_Q(__n) \
+ (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
+#define RME_CI_PTR_Q(__n) \
+ (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
+#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \
+ * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0))
+#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \
+ * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0))
+#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \
+ * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0))
+#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \
+ * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0))
+#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \
+ * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1))
+#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \
+ * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1))
+#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \
+ * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1))
+#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \
+ * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1))
+
+#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
+#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
+#define CPE_Q_MASK(__q) ((__q) & 0x3)
+#define RME_Q_MASK(__q) ((__q) & 0x3)
+
+/*
+ * PCI MSI-X vector defines
+ */
+enum {
+ BFA_MSIX_CPE_Q0 = 0,
+ BFA_MSIX_CPE_Q1 = 1,
+ BFA_MSIX_CPE_Q2 = 2,
+ BFA_MSIX_CPE_Q3 = 3,
+ BFA_MSIX_RME_Q0 = 4,
+ BFA_MSIX_RME_Q1 = 5,
+ BFA_MSIX_RME_Q2 = 6,
+ BFA_MSIX_RME_Q3 = 7,
+ BFA_MSIX_LPU_ERR = 8,
+ BFA_MSIX_CT_MAX = 9,
+};
+
+/*
+ * And corresponding host interrupt status bit field defines
+ */
+#define __HFN_INT_CPE_Q0 0x00000001U
+#define __HFN_INT_CPE_Q1 0x00000002U
+#define __HFN_INT_CPE_Q2 0x00000004U
+#define __HFN_INT_CPE_Q3 0x00000008U
+#define __HFN_INT_CPE_Q4 0x00000010U
+#define __HFN_INT_CPE_Q5 0x00000020U
+#define __HFN_INT_CPE_Q6 0x00000040U
+#define __HFN_INT_CPE_Q7 0x00000080U
+#define __HFN_INT_RME_Q0 0x00000100U
+#define __HFN_INT_RME_Q1 0x00000200U
+#define __HFN_INT_RME_Q2 0x00000400U
+#define __HFN_INT_RME_Q3 0x00000800U
+#define __HFN_INT_RME_Q4 0x00001000U
+#define __HFN_INT_RME_Q5 0x00002000U
+#define __HFN_INT_RME_Q6 0x00004000U
+#define __HFN_INT_RME_Q7 0x00008000U
+#define __HFN_INT_ERR_EMC 0x00010000U
+#define __HFN_INT_ERR_LPU0 0x00020000U
+#define __HFN_INT_ERR_LPU1 0x00040000U
+#define __HFN_INT_ERR_PSS 0x00080000U
+#define __HFN_INT_MBOX_LPU0 0x00100000U
+#define __HFN_INT_MBOX_LPU1 0x00200000U
+#define __HFN_INT_MBOX1_LPU0 0x00400000U
+#define __HFN_INT_MBOX1_LPU1 0x00800000U
+#define __HFN_INT_LL_HALT 0x01000000U
+#define __HFN_INT_CPE_MASK 0x000000ffU
+#define __HFN_INT_RME_MASK 0x0000ff00U
+
+/*
+ * catapult memory map.
+ */
+#define LL_PGN_HQM0 0x0096
+#define LL_PGN_HQM1 0x0097
+#define PSS_SMEM_PAGE_START 0x8000
+#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
+#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
+
+/*
+ * End of catapult memory map
+ */
+
+#endif /* __BFI_CTREG_H__ */
diff --git a/drivers/net/bna/bfi_ll.h b/drivers/net/bna/bfi_ll.h
new file mode 100644
index 000000000000..bee4d054066a
--- /dev/null
+++ b/drivers/net/bna/bfi_ll.h
@@ -0,0 +1,438 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BFI_LL_H__
+#define __BFI_LL_H__
+
+#include "bfi.h"
+
+#pragma pack(1)
+
+/**
+ * @brief
+ * "enums" for all LL mailbox messages other than IOC
+ */
+enum {
+ BFI_LL_H2I_MAC_UCAST_SET_REQ = 1,
+ BFI_LL_H2I_MAC_UCAST_ADD_REQ = 2,
+ BFI_LL_H2I_MAC_UCAST_DEL_REQ = 3,
+
+ BFI_LL_H2I_MAC_MCAST_ADD_REQ = 4,
+ BFI_LL_H2I_MAC_MCAST_DEL_REQ = 5,
+ BFI_LL_H2I_MAC_MCAST_FILTER_REQ = 6,
+ BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ = 7,
+
+ BFI_LL_H2I_PORT_ADMIN_REQ = 8,
+ BFI_LL_H2I_STATS_GET_REQ = 9,
+ BFI_LL_H2I_STATS_CLEAR_REQ = 10,
+
+ BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ = 11,
+ BFI_LL_H2I_RXF_DEFAULT_SET_REQ = 12,
+
+ BFI_LL_H2I_TXQ_STOP_REQ = 13,
+ BFI_LL_H2I_RXQ_STOP_REQ = 14,
+
+ BFI_LL_H2I_DIAG_LOOPBACK_REQ = 15,
+
+ BFI_LL_H2I_SET_PAUSE_REQ = 16,
+ BFI_LL_H2I_MTU_INFO_REQ = 17,
+
+ BFI_LL_H2I_RX_REQ = 18,
+} ;
+
+enum {
+ BFI_LL_I2H_MAC_UCAST_SET_RSP = BFA_I2HM(1),
+ BFI_LL_I2H_MAC_UCAST_ADD_RSP = BFA_I2HM(2),
+ BFI_LL_I2H_MAC_UCAST_DEL_RSP = BFA_I2HM(3),
+
+ BFI_LL_I2H_MAC_MCAST_ADD_RSP = BFA_I2HM(4),
+ BFI_LL_I2H_MAC_MCAST_DEL_RSP = BFA_I2HM(5),
+ BFI_LL_I2H_MAC_MCAST_FILTER_RSP = BFA_I2HM(6),
+ BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP = BFA_I2HM(7),
+
+ BFI_LL_I2H_PORT_ADMIN_RSP = BFA_I2HM(8),
+ BFI_LL_I2H_STATS_GET_RSP = BFA_I2HM(9),
+ BFI_LL_I2H_STATS_CLEAR_RSP = BFA_I2HM(10),
+
+ BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP = BFA_I2HM(11),
+ BFI_LL_I2H_RXF_DEFAULT_SET_RSP = BFA_I2HM(12),
+
+ BFI_LL_I2H_TXQ_STOP_RSP = BFA_I2HM(13),
+ BFI_LL_I2H_RXQ_STOP_RSP = BFA_I2HM(14),
+
+ BFI_LL_I2H_DIAG_LOOPBACK_RSP = BFA_I2HM(15),
+
+ BFI_LL_I2H_SET_PAUSE_RSP = BFA_I2HM(16),
+
+ BFI_LL_I2H_MTU_INFO_RSP = BFA_I2HM(17),
+ BFI_LL_I2H_RX_RSP = BFA_I2HM(18),
+
+ BFI_LL_I2H_LINK_DOWN_AEN = BFA_I2HM(19),
+ BFI_LL_I2H_LINK_UP_AEN = BFA_I2HM(20),
+
+ BFI_LL_I2H_PORT_ENABLE_AEN = BFA_I2HM(21),
+ BFI_LL_I2H_PORT_DISABLE_AEN = BFA_I2HM(22),
+} ;
+
+/**
+ * @brief bfi_ll_mac_addr_req is used by:
+ * BFI_LL_H2I_MAC_UCAST_SET_REQ
+ * BFI_LL_H2I_MAC_UCAST_ADD_REQ
+ * BFI_LL_H2I_MAC_UCAST_DEL_REQ
+ * BFI_LL_H2I_MAC_MCAST_ADD_REQ
+ * BFI_LL_H2I_MAC_MCAST_DEL_REQ
+ */
+struct bfi_ll_mac_addr_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 rsvd1[3];
+ mac_t mac_addr;
+ u8 rsvd2[2];
+};
+
+/**
+ * @brief bfi_ll_mcast_filter_req is used by:
+ * BFI_LL_H2I_MAC_MCAST_FILTER_REQ
+ */
+struct bfi_ll_mcast_filter_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 enable;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_mcast_del_all is used by:
+ * BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ
+ */
+struct bfi_ll_mcast_del_all_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_q_stop_req is used by:
+ * BFI_LL_H2I_TXQ_STOP_REQ
+ * BFI_LL_H2I_RXQ_STOP_REQ
+ */
+struct bfi_ll_q_stop_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 q_id_mask[2]; /* !< bit-mask for queue ids */
+};
+
+/**
+ * @brief bfi_ll_stats_req is used by:
+ * BFI_LL_I2H_STATS_GET_REQ
+ * BFI_LL_I2H_STATS_CLEAR_REQ
+ */
+struct bfi_ll_stats_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u16 stats_mask; /* !< bit-mask for non-function statistics */
+ u8 rsvd[2];
+ u32 rxf_id_mask[2]; /* !< bit-mask for RxF Statistics */
+ u32 txf_id_mask[2]; /* !< bit-mask for TxF Statistics */
+ union bfi_addr_u host_buffer; /* !< where statistics are returned */
+};
+
+/**
+ * @brief defines for "stats_mask" above.
+ */
+#define BFI_LL_STATS_MAC (1 << 0) /* !< MAC Statistics */
+#define BFI_LL_STATS_BPC (1 << 1) /* !< Pause Stats from BPC */
+#define BFI_LL_STATS_RAD (1 << 2) /* !< Rx Admission Statistics */
+#define BFI_LL_STATS_RX_FC (1 << 3) /* !< Rx FC Stats from RxA */
+#define BFI_LL_STATS_TX_FC (1 << 4) /* !< Tx FC Stats from TxA */
+
+#define BFI_LL_STATS_ALL 0x1f
+
+/**
+ * @brief bfi_ll_port_admin_req
+ */
+struct bfi_ll_port_admin_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 up;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_rxf_req is used by:
+ * BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ
+ * BFI_LL_H2I_RXF_DEFAULT_SET_REQ
+ */
+struct bfi_ll_rxf_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 rxf_id;
+ u8 enable;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_rxf_multi_req is used by:
+ * BFI_LL_H2I_RX_REQ
+ */
+struct bfi_ll_rxf_multi_req {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 rxf_id_mask[2];
+ u8 enable;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief enum for Loopback opmodes
+ */
+enum {
+ BFI_LL_DIAG_LB_OPMODE_EXT = 0,
+ BFI_LL_DIAG_LB_OPMODE_CBL = 1,
+};
+
+/**
+ * @brief bfi_ll_set_pause_req is used by:
+ * BFI_LL_H2I_SET_PAUSE_REQ
+ */
+struct bfi_ll_set_pause_req {
+ struct bfi_mhdr mh;
+ u8 tx_pause; /* 1 = enable, 0 = disable */
+ u8 rx_pause; /* 1 = enable, 0 = disable */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief bfi_ll_mtu_info_req is used by:
+ * BFI_LL_H2I_MTU_INFO_REQ
+ */
+struct bfi_ll_mtu_info_req {
+ struct bfi_mhdr mh;
+ u16 mtu;
+ u8 rsvd[2];
+};
+
+/**
+ * @brief
+ * Response header format used by all responses
+ * For both responses and asynchronous notifications
+ */
+struct bfi_ll_rsp {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u8 error;
+ u8 rsvd[3];
+};
+
+/**
+ * @brief bfi_ll_cee_aen is used by:
+ * BFI_LL_I2H_LINK_DOWN_AEN
+ * BFI_LL_I2H_LINK_UP_AEN
+ */
+struct bfi_ll_aen {
+ struct bfi_mhdr mh; /*!< common msg header */
+ u32 reason;
+ u8 cee_linkup;
+ u8 prio_map; /*!< LL priority bit-map */
+ u8 rsvd[2];
+};
+
+/**
+ * @brief
+ * The following error codes can be returned
+ * by the mbox commands
+ */
+enum {
+ BFI_LL_CMD_OK = 0,
+ BFI_LL_CMD_FAIL = 1,
+ BFI_LL_CMD_DUP_ENTRY = 2, /* !< Duplicate entry in CAM */
+ BFI_LL_CMD_CAM_FULL = 3, /* !< CAM is full */
+ BFI_LL_CMD_NOT_OWNER = 4, /* !< Not permitted, b'cos not owner */
+ BFI_LL_CMD_NOT_EXEC = 5, /* !< Was not sent to f/w at all */
+ BFI_LL_CMD_WAITING = 6, /* !< Waiting for completion (VMware) */
+ BFI_LL_CMD_PORT_DISABLED = 7, /* !< port in disabled state */
+} ;
+
+/* Statistics */
+#define BFI_LL_TXF_ID_MAX 64
+#define BFI_LL_RXF_ID_MAX 64
+
+/* TxF Frame Statistics */
+struct bfi_ll_stats_txf {
+ u64 ucast_octets;
+ u64 ucast;
+ u64 ucast_vlan;
+
+ u64 mcast_octets;
+ u64 mcast;
+ u64 mcast_vlan;
+
+ u64 bcast_octets;
+ u64 bcast;
+ u64 bcast_vlan;
+
+ u64 errors;
+ u64 filter_vlan; /* frames filtered due to VLAN */
+ u64 filter_mac_sa; /* frames filtered due to SA check */
+};
+
+/* RxF Frame Statistics */
+struct bfi_ll_stats_rxf {
+ u64 ucast_octets;
+ u64 ucast;
+ u64 ucast_vlan;
+
+ u64 mcast_octets;
+ u64 mcast;
+ u64 mcast_vlan;
+
+ u64 bcast_octets;
+ u64 bcast;
+ u64 bcast_vlan;
+ u64 frame_drops;
+};
+
+/* FC Tx Frame Statistics */
+struct bfi_ll_stats_fc_tx {
+ u64 txf_ucast_octets;
+ u64 txf_ucast;
+ u64 txf_ucast_vlan;
+
+ u64 txf_mcast_octets;
+ u64 txf_mcast;
+ u64 txf_mcast_vlan;
+
+ u64 txf_bcast_octets;
+ u64 txf_bcast;
+ u64 txf_bcast_vlan;
+
+ u64 txf_parity_errors;
+ u64 txf_timeout;
+ u64 txf_fid_parity_errors;
+};
+
+/* FC Rx Frame Statistics */
+struct bfi_ll_stats_fc_rx {
+ u64 rxf_ucast_octets;
+ u64 rxf_ucast;
+ u64 rxf_ucast_vlan;
+
+ u64 rxf_mcast_octets;
+ u64 rxf_mcast;
+ u64 rxf_mcast_vlan;
+
+ u64 rxf_bcast_octets;
+ u64 rxf_bcast;
+ u64 rxf_bcast_vlan;
+};
+
+/* RAD Frame Statistics */
+struct bfi_ll_stats_rad {
+ u64 rx_frames;
+ u64 rx_octets;
+ u64 rx_vlan_frames;
+
+ u64 rx_ucast;
+ u64 rx_ucast_octets;
+ u64 rx_ucast_vlan;
+
+ u64 rx_mcast;
+ u64 rx_mcast_octets;
+ u64 rx_mcast_vlan;
+
+ u64 rx_bcast;
+ u64 rx_bcast_octets;
+ u64 rx_bcast_vlan;
+
+ u64 rx_drops;
+};
+
+/* BPC Tx Registers */
+struct bfi_ll_stats_bpc {
+ /* transmit stats */
+ u64 tx_pause[8];
+ u64 tx_zero_pause[8]; /*!< Pause cancellation */
+ /*!<Pause initiation rather than retention */
+ u64 tx_first_pause[8];
+
+ /* receive stats */
+ u64 rx_pause[8];
+ u64 rx_zero_pause[8]; /*!< Pause cancellation */
+ /*!<Pause initiation rather than retention */
+ u64 rx_first_pause[8];
+};
+
+/* MAC Rx Statistics */
+struct bfi_ll_stats_mac {
+ u64 frame_64; /* both rx and tx counter */
+ u64 frame_65_127; /* both rx and tx counter */
+ u64 frame_128_255; /* both rx and tx counter */
+ u64 frame_256_511; /* both rx and tx counter */
+ u64 frame_512_1023; /* both rx and tx counter */
+ u64 frame_1024_1518; /* both rx and tx counter */
+ u64 frame_1519_1522; /* both rx and tx counter */
+
+ /* receive stats */
+ u64 rx_bytes;
+ u64 rx_packets;
+ u64 rx_fcs_error;
+ u64 rx_multicast;
+ u64 rx_broadcast;
+ u64 rx_control_frames;
+ u64 rx_pause;
+ u64 rx_unknown_opcode;
+ u64 rx_alignment_error;
+ u64 rx_frame_length_error;
+ u64 rx_code_error;
+ u64 rx_carrier_sense_error;
+ u64 rx_undersize;
+ u64 rx_oversize;
+ u64 rx_fragments;
+ u64 rx_jabber;
+ u64 rx_drop;
+
+ /* transmit stats */
+ u64 tx_bytes;
+ u64 tx_packets;
+ u64 tx_multicast;
+ u64 tx_broadcast;
+ u64 tx_pause;
+ u64 tx_deferral;
+ u64 tx_excessive_deferral;
+ u64 tx_single_collision;
+ u64 tx_muliple_collision;
+ u64 tx_late_collision;
+ u64 tx_excessive_collision;
+ u64 tx_total_collision;
+ u64 tx_pause_honored;
+ u64 tx_drop;
+ u64 tx_jabber;
+ u64 tx_fcs_error;
+ u64 tx_control_frame;
+ u64 tx_oversize;
+ u64 tx_undersize;
+ u64 tx_fragments;
+};
+
+/* Complete statistics */
+struct bfi_ll_stats {
+ struct bfi_ll_stats_mac mac_stats;
+ struct bfi_ll_stats_bpc bpc_stats;
+ struct bfi_ll_stats_rad rad_stats;
+ struct bfi_ll_stats_fc_rx fc_rx_stats;
+ struct bfi_ll_stats_fc_tx fc_tx_stats;
+ struct bfi_ll_stats_rxf rxf_stats[BFI_LL_RXF_ID_MAX];
+ struct bfi_ll_stats_txf txf_stats[BFI_LL_TXF_ID_MAX];
+};
+
+#pragma pack()
+
+#endif /* __BFI_LL_H__ */
diff --git a/drivers/net/bna/bna.h b/drivers/net/bna/bna.h
new file mode 100644
index 000000000000..6a2b3291c190
--- /dev/null
+++ b/drivers/net/bna/bna.h
@@ -0,0 +1,654 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef __BNA_H__
+#define __BNA_H__
+
+#include "bfa_wc.h"
+#include "bfa_ioc.h"
+#include "cna.h"
+#include "bfi_ll.h"
+#include "bna_types.h"
+
+extern u32 bna_dim_vector[][BNA_BIAS_T_MAX];
+extern u32 bna_napi_dim_vector[][BNA_BIAS_T_MAX];
+
+/**
+ *
+ * Macros and constants
+ *
+ */
+
+#define BNA_IOC_TIMER_FREQ 200
+
+/* Log string size */
+#define BNA_MESSAGE_SIZE 256
+
+#define bna_device_timer(_dev) bfa_timer_beat(&((_dev)->timer_mod))
+
+/* MBOX API for PORT, TX, RX */
+#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \
+do { \
+ memcpy(&((_qe)->cmd.msg[0]), (_cmd), (_cmd_len)); \
+ (_qe)->cbfn = (_cbfn); \
+ (_qe)->cbarg = (_cbarg); \
+} while (0)
+
+#define bna_is_small_rxq(rcb) ((rcb)->id == 1)
+
+#define BNA_MAC_IS_EQUAL(_mac1, _mac2) \
+ (!memcmp((_mac1), (_mac2), sizeof(mac_t)))
+
+#define BNA_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)
+
+#define BNA_TO_POWER_OF_2(x) \
+do { \
+ int _shift = 0; \
+ while ((x) && (x) != 1) { \
+ (x) >>= 1; \
+ _shift++; \
+ } \
+ (x) <<= _shift; \
+} while (0)
+
+#define BNA_TO_POWER_OF_2_HIGH(x) \
+do { \
+ int n = 1; \
+ while (n < (x)) \
+ n <<= 1; \
+ (x) = n; \
+} while (0)
+
+/*
+ * input : _addr-> os dma addr in host endian format,
+ * output : _bna_dma_addr-> pointer to hw dma addr
+ */
+#define BNA_SET_DMA_ADDR(_addr, _bna_dma_addr) \
+do { \
+ u64 tmp_addr = \
+ cpu_to_be64((u64)(_addr)); \
+ (_bna_dma_addr)->msb = ((struct bna_dma_addr *)&tmp_addr)->msb; \
+ (_bna_dma_addr)->lsb = ((struct bna_dma_addr *)&tmp_addr)->lsb; \
+} while (0)
+
+/*
+ * input : _bna_dma_addr-> pointer to hw dma addr
+ * output : _addr-> os dma addr in host endian format
+ */
+#define BNA_GET_DMA_ADDR(_bna_dma_addr, _addr) \
+do { \
+ (_addr) = ((((u64)ntohl((_bna_dma_addr)->msb))) << 32) \
+ | ((ntohl((_bna_dma_addr)->lsb) & 0xffffffff)); \
+} while (0)
+
+#define containing_rec(addr, type, field) \
+ ((type *)((unsigned char *)(addr) - \
+ (unsigned char *)(&((type *)0)->field)))
+
+#define BNA_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2)
+
+/* TxQ element is 64 bytes */
+#define BNA_TXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 6)
+#define BNA_TXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 6)
+
+#define BNA_TXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> BNA_TXQ_PAGE_INDEX_MAX_SHIFT)];\
+ (_qe_ptr) = &((struct bna_txq_entry *)(page_addr))[page_index]; \
+}
+
+/* RxQ element is 8 bytes */
+#define BNA_RXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 3)
+#define BNA_RXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 3)
+
+#define BNA_RXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ page_index = (_qe_idx) & (BNA_RXQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_RXQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> \
+ BNA_RXQ_PAGE_INDEX_MAX_SHIFT)]; \
+ (_qe_ptr) = &((struct bna_rxq_entry *)(page_addr))[page_index]; \
+}
+
+/* CQ element is 16 bytes */
+#define BNA_CQ_PAGE_INDEX_MAX (PAGE_SIZE >> 4)
+#define BNA_CQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 4)
+
+#define BNA_CQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \
+{ \
+ unsigned int page_index; /* index within a page */ \
+ void *page_addr; \
+ \
+ page_index = (_qe_idx) & (BNA_CQ_PAGE_INDEX_MAX - 1); \
+ (_qe_ptr_range) = (BNA_CQ_PAGE_INDEX_MAX - page_index); \
+ page_addr = (_qpt_ptr)[((_qe_idx) >> \
+ BNA_CQ_PAGE_INDEX_MAX_SHIFT)]; \
+ (_qe_ptr) = &((struct bna_cq_entry *)(page_addr))[page_index];\
+}
+
+#define BNA_QE_INDX_2_PTR(_cast, _qe_idx, _q_base) \
+ (&((_cast *)(_q_base))[(_qe_idx)])
+
+#define BNA_QE_INDX_RANGE(_qe_idx, _q_depth) ((_q_depth) - (_qe_idx))
+
+#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \
+ ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1))
+
+#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \
+ (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1))
+
+#define BNA_QE_FREE_CNT(_q_ptr, _q_depth) \
+ (((_q_ptr)->consumer_index - (_q_ptr)->producer_index - 1) & \
+ ((_q_depth) - 1))
+
+#define BNA_QE_IN_USE_CNT(_q_ptr, _q_depth) \
+ ((((_q_ptr)->producer_index - (_q_ptr)->consumer_index)) & \
+ (_q_depth - 1))
+
+#define BNA_Q_GET_CI(_q_ptr) ((_q_ptr)->q.consumer_index)
+
+#define BNA_Q_GET_PI(_q_ptr) ((_q_ptr)->q.producer_index)
+
+#define BNA_Q_PI_ADD(_q_ptr, _num) \
+ (_q_ptr)->q.producer_index = \
+ (((_q_ptr)->q.producer_index + (_num)) & \
+ ((_q_ptr)->q.q_depth - 1))
+
+#define BNA_Q_CI_ADD(_q_ptr, _num) \
+ (_q_ptr)->q.consumer_index = \
+ (((_q_ptr)->q.consumer_index + (_num)) \
+ & ((_q_ptr)->q.q_depth - 1))
+
+#define BNA_Q_FREE_COUNT(_q_ptr) \
+ (BNA_QE_FREE_CNT(&((_q_ptr)->q), (_q_ptr)->q.q_depth))
+
+#define BNA_Q_IN_USE_COUNT(_q_ptr) \
+ (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth))
+
+/* These macros build the data portion of the TxQ/RxQ doorbell */
+#define BNA_DOORBELL_Q_PRD_IDX(_pi) (0x80000000 | (_pi))
+#define BNA_DOORBELL_Q_STOP (0x40000000)
+
+/* These macros build the data portion of the IB doorbell */
+#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
+ (0x80000000 | ((_timeout) << 16) | (_events))
+#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000)
+
+/* Set the coalescing timer for the given ib */
+#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer) \
+ ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0));
+
+/* Acks 'events' # of events for a given ib */
+#define bna_ib_ack(_i_dbell, _events) \
+ (writel(((_i_dbell)->doorbell_ack | (_events)), \
+ (_i_dbell)->doorbell_addr));
+
+#define bna_txq_prod_indx_doorbell(_tcb) \
+ (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \
+ (_tcb)->q_dbell));
+
+#define bna_rxq_prod_indx_doorbell(_rcb) \
+ (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \
+ (_rcb)->q_dbell));
+
+#define BNA_LARGE_PKT_SIZE 1000
+
+#define BNA_UPDATE_PKT_CNT(_pkt, _len) \
+do { \
+ if ((_len) > BNA_LARGE_PKT_SIZE) { \
+ (_pkt)->large_pkt_cnt++; \
+ } else { \
+ (_pkt)->small_pkt_cnt++; \
+ } \
+} while (0)
+
+#define call_rxf_stop_cbfn(rxf, status) \
+ if ((rxf)->stop_cbfn) { \
+ (*(rxf)->stop_cbfn)((rxf)->stop_cbarg, (status)); \
+ (rxf)->stop_cbfn = NULL; \
+ (rxf)->stop_cbarg = NULL; \
+ }
+
+#define call_rxf_start_cbfn(rxf, status) \
+ if ((rxf)->start_cbfn) { \
+ (*(rxf)->start_cbfn)((rxf)->start_cbarg, (status)); \
+ (rxf)->start_cbfn = NULL; \
+ (rxf)->start_cbarg = NULL; \
+ }
+
+#define call_rxf_cam_fltr_cbfn(rxf, status) \
+ if ((rxf)->cam_fltr_cbfn) { \
+ (*(rxf)->cam_fltr_cbfn)((rxf)->cam_fltr_cbarg, rxf->rx, \
+ (status)); \
+ (rxf)->cam_fltr_cbfn = NULL; \
+ (rxf)->cam_fltr_cbarg = NULL; \
+ }
+
+#define call_rxf_pause_cbfn(rxf, status) \
+ if ((rxf)->oper_state_cbfn) { \
+ (*(rxf)->oper_state_cbfn)((rxf)->oper_state_cbarg, rxf->rx,\
+ (status)); \
+ (rxf)->rxf_flags &= ~BNA_RXF_FL_OPERSTATE_CHANGED; \
+ (rxf)->oper_state_cbfn = NULL; \
+ (rxf)->oper_state_cbarg = NULL; \
+ }
+
+#define call_rxf_resume_cbfn(rxf, status) call_rxf_pause_cbfn(rxf, status)
+
+#define is_xxx_enable(mode, bitmask, xxx) ((bitmask & xxx) && (mode & xxx))
+
+#define is_xxx_disable(mode, bitmask, xxx) ((bitmask & xxx) && !(mode & xxx))
+
+#define xxx_enable(mode, bitmask, xxx) \
+do { \
+ bitmask |= xxx; \
+ mode |= xxx; \
+} while (0)
+
+#define xxx_disable(mode, bitmask, xxx) \
+do { \
+ bitmask |= xxx; \
+ mode &= ~xxx; \
+} while (0)
+
+#define xxx_inactive(mode, bitmask, xxx) \
+do { \
+ bitmask &= ~xxx; \
+ mode &= ~xxx; \
+} while (0)
+
+#define is_promisc_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define is_promisc_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define promisc_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_PROMISC)
+
+#define is_default_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define is_default_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define default_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_DEFAULT)
+
+#define is_allmulti_enable(mode, bitmask) \
+ is_xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define is_allmulti_disable(mode, bitmask) \
+ is_xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_enable(mode, bitmask) \
+ xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_disable(mode, bitmask) \
+ xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define allmulti_inactive(mode, bitmask) \
+ xxx_inactive(mode, bitmask, BNA_RXMODE_ALLMULTI)
+
+#define GET_RXQS(rxp, q0, q1) do { \
+ switch ((rxp)->type) { \
+ case BNA_RXP_SINGLE: \
+ (q0) = rxp->rxq.single.only; \
+ (q1) = NULL; \
+ break; \
+ case BNA_RXP_SLR: \
+ (q0) = rxp->rxq.slr.large; \
+ (q1) = rxp->rxq.slr.small; \
+ break; \
+ case BNA_RXP_HDS: \
+ (q0) = rxp->rxq.hds.data; \
+ (q1) = rxp->rxq.hds.hdr; \
+ break; \
+ } \
+} while (0)
+
+/**
+ *
+ * Function prototypes
+ *
+ */
+
+/**
+ * BNA
+ */
+
+/* Internal APIs */
+void bna_adv_res_req(struct bna_res_info *res_info);
+
+/* APIs for BNAD */
+void bna_res_req(struct bna_res_info *res_info);
+void bna_init(struct bna *bna, struct bnad *bnad,
+ struct bfa_pcidev *pcidev,
+ struct bna_res_info *res_info);
+void bna_uninit(struct bna *bna);
+void bna_stats_get(struct bna *bna);
+void bna_stats_clr(struct bna *bna);
+void bna_get_perm_mac(struct bna *bna, u8 *mac);
+
+/* APIs for Rx */
+int bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size);
+
+/* APIs for RxF */
+struct bna_mac *bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod);
+void bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod,
+ struct bna_mac *mac);
+struct bna_mac *bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod);
+void bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod,
+ struct bna_mac *mac);
+struct bna_rit_segment *
+bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size);
+void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
+ struct bna_rit_segment *seg);
+
+/**
+ * DEVICE
+ */
+
+/* Interanl APIs */
+void bna_adv_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info);
+
+/* APIs for BNA */
+void bna_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_device_uninit(struct bna_device *device);
+void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status);
+int bna_device_status_get(struct bna_device *device);
+int bna_device_state_get(struct bna_device *device);
+
+/* APIs for BNAD */
+void bna_device_enable(struct bna_device *device);
+void bna_device_disable(struct bna_device *device,
+ enum bna_cleanup_type type);
+
+/**
+ * MBOX
+ */
+
+/* APIs for DEVICE */
+void bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna);
+void bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod);
+void bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod);
+void bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod);
+
+/* APIs for PORT, TX, RX */
+void bna_mbox_handler(struct bna *bna, u32 intr_status);
+void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe);
+
+/**
+ * PORT
+ */
+
+/* APIs for BNA */
+void bna_port_init(struct bna_port *port, struct bna *bna);
+void bna_port_uninit(struct bna_port *port);
+int bna_port_state_get(struct bna_port *port);
+int bna_llport_state_get(struct bna_llport *llport);
+
+/* APIs for DEVICE */
+void bna_port_start(struct bna_port *port);
+void bna_port_stop(struct bna_port *port);
+void bna_port_fail(struct bna_port *port);
+
+/* API for RX */
+int bna_port_mtu_get(struct bna_port *port);
+void bna_llport_admin_up(struct bna_llport *llport);
+void bna_llport_admin_down(struct bna_llport *llport);
+
+/* API for BNAD */
+void bna_port_enable(struct bna_port *port);
+void bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
+ void (*cbfn)(void *, enum bna_cb_status));
+void bna_port_pause_config(struct bna_port *port,
+ struct bna_pause_config *pause_config,
+ void (*cbfn)(struct bnad *, enum bna_cb_status));
+void bna_port_mtu_set(struct bna_port *port, int mtu,
+ void (*cbfn)(struct bnad *, enum bna_cb_status));
+void bna_port_mac_get(struct bna_port *port, mac_t *mac);
+void bna_port_type_set(struct bna_port *port, enum bna_port_type type);
+void bna_port_linkcbfn_set(struct bna_port *port,
+ void (*linkcbfn)(struct bnad *,
+ enum bna_link_status));
+void bna_port_admin_up(struct bna_port *port);
+void bna_port_admin_down(struct bna_port *port);
+
+/* Callbacks for TX, RX */
+void bna_port_cb_tx_stopped(struct bna_port *port,
+ enum bna_cb_status status);
+void bna_port_cb_rx_stopped(struct bna_port *port,
+ enum bna_cb_status status);
+
+/* Callbacks for MBOX */
+void bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen,
+ int status);
+void bna_port_cb_link_down(struct bna_port *port, int status);
+
+/**
+ * IB
+ */
+
+/* APIs for BNA */
+void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod);
+
+/* APIs for TX, RX */
+struct bna_ib *bna_ib_get(struct bna_ib_mod *ib_mod,
+ enum bna_intr_type intr_type, int vector);
+void bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib);
+int bna_ib_reserve_idx(struct bna_ib *ib);
+void bna_ib_release_idx(struct bna_ib *ib, int idx);
+int bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config);
+void bna_ib_start(struct bna_ib *ib);
+void bna_ib_stop(struct bna_ib *ib);
+void bna_ib_fail(struct bna_ib *ib);
+void bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo);
+
+/**
+ * TX MODULE AND TX
+ */
+
+/* Internal APIs */
+void bna_tx_prio_changed(struct bna_tx *tx, int prio);
+
+/* APIs for BNA */
+void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_tx_mod_uninit(struct bna_tx_mod *tx_mod);
+int bna_tx_state_get(struct bna_tx *tx);
+
+/* APIs for PORT */
+void bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
+void bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type);
+void bna_tx_mod_fail(struct bna_tx_mod *tx_mod);
+void bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio);
+void bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link);
+
+/* APIs for BNAD */
+void bna_tx_res_req(int num_txq, int txq_depth,
+ struct bna_res_info *res_info);
+struct bna_tx *bna_tx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_tx_config *tx_cfg,
+ struct bna_tx_event_cbfn *tx_cbfn,
+ struct bna_res_info *res_info, void *priv);
+void bna_tx_destroy(struct bna_tx *tx);
+void bna_tx_enable(struct bna_tx *tx);
+void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_tx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_tx_prio_set(struct bna_tx *tx, int prio,
+ void (*cbfn)(struct bnad *, struct bna_tx *,
+ enum bna_cb_status));
+void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo);
+
+/**
+ * RX MODULE, RX, RXF
+ */
+
+/* Internal APIs */
+void rxf_cb_cam_fltr_mbox_cmd(void *arg, int status);
+void rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
+ const struct bna_mac *mac_addr);
+void __rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status);
+void bna_rxf_adv_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config);
+int rxf_process_packet_filter_ucast(struct bna_rxf *rxf);
+int rxf_process_packet_filter_promisc(struct bna_rxf *rxf);
+int rxf_process_packet_filter_default(struct bna_rxf *rxf);
+int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_ucast(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_promisc(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_default(struct bna_rxf *rxf);
+int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_ucast(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_promisc(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_default(struct bna_rxf *rxf);
+void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf);
+
+/* APIs for BNA */
+void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
+ struct bna_res_info *res_info);
+void bna_rx_mod_uninit(struct bna_rx_mod *rx_mod);
+int bna_rx_state_get(struct bna_rx *rx);
+int bna_rxf_state_get(struct bna_rxf *rxf);
+
+/* APIs for PORT */
+void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
+void bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type);
+void bna_rx_mod_fail(struct bna_rx_mod *rx_mod);
+
+/* APIs for BNAD */
+void bna_rx_res_req(struct bna_rx_config *rx_config,
+ struct bna_res_info *res_info);
+struct bna_rx *bna_rx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_rx_config *rx_cfg,
+ struct bna_rx_event_cbfn *rx_cbfn,
+ struct bna_res_info *res_info, void *priv);
+void bna_rx_destroy(struct bna_rx *rx);
+void bna_rx_enable(struct bna_rx *rx);
+void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo);
+void bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX]);
+void bna_rx_dim_update(struct bna_ccb *ccb);
+enum bna_cb_status
+bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_ucast_add(struct bna_rx *rx, u8* ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_ucast_del(struct bna_rx *rx, u8 *ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mcast_del(struct bna_rx *rx, u8 *mcmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_mcast_delall(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+enum bna_cb_status
+bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode,
+ enum bna_rxmode bitmask,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id);
+void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id);
+void bna_rx_vlanfilter_enable(struct bna_rx *rx);
+void bna_rx_vlanfilter_disable(struct bna_rx *rx);
+void bna_rx_rss_enable(struct bna_rx *rx);
+void bna_rx_rss_disable(struct bna_rx *rx);
+void bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config);
+void bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors,
+ int nvectors);
+void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_hds_disable(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_receive_pause(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+void bna_rx_receive_resume(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status));
+
+/* RxF APIs for RX */
+void bna_rxf_start(struct bna_rxf *rxf);
+void bna_rxf_stop(struct bna_rxf *rxf);
+void bna_rxf_fail(struct bna_rxf *rxf);
+void bna_rxf_init(struct bna_rxf *rxf, struct bna_rx *rx,
+ struct bna_rx_config *q_config);
+void bna_rxf_uninit(struct bna_rxf *rxf);
+
+/* Callback from RXF to RX */
+void bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status);
+void bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status);
+
+/**
+ * BNAD
+ */
+
+/* Callbacks for BNA */
+void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
+ struct bna_stats *stats);
+void bnad_cb_stats_clr(struct bnad *bnad);
+
+/* Callbacks for DEVICE */
+void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status);
+void bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status);
+void bnad_cb_device_enable_mbox_intr(struct bnad *bnad);
+void bnad_cb_device_disable_mbox_intr(struct bnad *bnad);
+
+/* Callbacks for port */
+void bnad_cb_port_link_status(struct bnad *bnad,
+ enum bna_link_status status);
+
+#endif /* __BNA_H__ */
diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c
new file mode 100644
index 000000000000..f3034d6bda58
--- /dev/null
+++ b/drivers/net/bna/bna_ctrl.c
@@ -0,0 +1,3624 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+#include "bfa_sm.h"
+#include "bfa_wc.h"
+
+/**
+ * MBOX
+ */
+static int
+bna_is_aen(u8 msg_id)
+{
+ return (msg_id == BFI_LL_I2H_LINK_DOWN_AEN ||
+ msg_id == BFI_LL_I2H_LINK_UP_AEN);
+}
+
+static void
+bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg)
+{
+ struct bfi_ll_aen *aen = (struct bfi_ll_aen *)(msg);
+
+ switch (aen->mh.msg_id) {
+ case BFI_LL_I2H_LINK_UP_AEN:
+ bna_port_cb_link_up(&bna->port, aen, aen->reason);
+ break;
+ case BFI_LL_I2H_LINK_DOWN_AEN:
+ bna_port_cb_link_down(&bna->port, aen->reason);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+bna_ll_isr(void *llarg, struct bfi_mbmsg *msg)
+{
+ struct bna *bna = (struct bna *)(llarg);
+ struct bfi_ll_rsp *mb_rsp = (struct bfi_ll_rsp *)(msg);
+ struct bfi_mhdr *cmd_h, *rsp_h;
+ struct bna_mbox_qe *mb_qe = NULL;
+ int to_post = 0;
+ u8 aen = 0;
+ char message[BNA_MESSAGE_SIZE];
+
+ aen = bna_is_aen(mb_rsp->mh.msg_id);
+
+ if (!aen) {
+ mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
+ cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
+ rsp_h = (struct bfi_mhdr *)(&mb_rsp->mh);
+
+ if ((BFA_I2HM(cmd_h->msg_id) == rsp_h->msg_id) &&
+ (cmd_h->mtag.i2htok == rsp_h->mtag.i2htok)) {
+ /* Remove the request from posted_q, update state */
+ list_del(&mb_qe->qe);
+ bna->mbox_mod.msg_pending--;
+ if (list_empty(&bna->mbox_mod.posted_q))
+ bna->mbox_mod.state = BNA_MBOX_FREE;
+ else
+ to_post = 1;
+
+ /* Dispatch the cbfn */
+ if (mb_qe->cbfn)
+ mb_qe->cbfn(mb_qe->cbarg, mb_rsp->error);
+
+ /* Post the next entry, if needed */
+ if (to_post) {
+ mb_qe = bfa_q_first(&bna->mbox_mod.posted_q);
+ bfa_nw_ioc_mbox_queue(&bna->device.ioc,
+ &mb_qe->cmd);
+ }
+ } else {
+ snprintf(message, BNA_MESSAGE_SIZE,
+ "No matching rsp for [%d:%d:%d]\n",
+ mb_rsp->mh.msg_class, mb_rsp->mh.msg_id,
+ mb_rsp->mh.mtag.i2htok);
+ pr_info("%s", message);
+ }
+
+ } else
+ bna_mbox_aen_callback(bna, msg);
+}
+
+void
+bna_err_handler(struct bna *bna, u32 intr_status)
+{
+ u32 init_halt;
+
+ if (intr_status & __HALT_STATUS_BITS) {
+ init_halt = readl(bna->device.ioc.ioc_regs.ll_halt);
+ init_halt &= ~__FW_INIT_HALT_P;
+ writel(init_halt, bna->device.ioc.ioc_regs.ll_halt);
+ }
+
+ bfa_nw_ioc_error_isr(&bna->device.ioc);
+}
+
+void
+bna_mbox_handler(struct bna *bna, u32 intr_status)
+{
+ if (BNA_IS_ERR_INTR(intr_status)) {
+ bna_err_handler(bna, intr_status);
+ return;
+ }
+ if (BNA_IS_MBOX_INTR(intr_status))
+ bfa_nw_ioc_mbox_isr(&bna->device.ioc);
+}
+
+void
+bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe)
+{
+ struct bfi_mhdr *mh;
+
+ mh = (struct bfi_mhdr *)(&mbox_qe->cmd.msg[0]);
+
+ mh->mtag.i2htok = htons(bna->mbox_mod.msg_ctr);
+ bna->mbox_mod.msg_ctr++;
+ bna->mbox_mod.msg_pending++;
+ if (bna->mbox_mod.state == BNA_MBOX_FREE) {
+ list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
+ bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd);
+ bna->mbox_mod.state = BNA_MBOX_POSTED;
+ } else {
+ list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q);
+ }
+}
+
+void
+bna_mbox_flush_q(struct bna *bna, struct list_head *q)
+{
+ struct bna_mbox_qe *mb_qe = NULL;
+ struct bfi_mhdr *cmd_h;
+ struct list_head *mb_q;
+ void (*cbfn)(void *arg, int status);
+ void *cbarg;
+
+ mb_q = &bna->mbox_mod.posted_q;
+
+ while (!list_empty(mb_q)) {
+ bfa_q_deq(mb_q, &mb_qe);
+ cbfn = mb_qe->cbfn;
+ cbarg = mb_qe->cbarg;
+ bfa_q_qe_init(mb_qe);
+ bna->mbox_mod.msg_pending--;
+
+ cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
+ if (cbfn)
+ cbfn(cbarg, BNA_CB_NOT_EXEC);
+ }
+
+ bna->mbox_mod.state = BNA_MBOX_FREE;
+}
+
+void
+bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod)
+{
+}
+
+void
+bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod)
+{
+ bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q);
+}
+
+void
+bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna)
+{
+ bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna);
+ mbox_mod->state = BNA_MBOX_FREE;
+ mbox_mod->msg_ctr = mbox_mod->msg_pending = 0;
+ INIT_LIST_HEAD(&mbox_mod->posted_q);
+ mbox_mod->bna = bna;
+}
+
+void
+bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod)
+{
+ mbox_mod->bna = NULL;
+}
+
+/**
+ * LLPORT
+ */
+#define call_llport_stop_cbfn(llport, status)\
+do {\
+ if ((llport)->stop_cbfn)\
+ (llport)->stop_cbfn(&(llport)->bna->port, status);\
+ (llport)->stop_cbfn = NULL;\
+} while (0)
+
+static void bna_fw_llport_up(struct bna_llport *llport);
+static void bna_fw_cb_llport_up(void *arg, int status);
+static void bna_fw_llport_down(struct bna_llport *llport);
+static void bna_fw_cb_llport_down(void *arg, int status);
+static void bna_llport_start(struct bna_llport *llport);
+static void bna_llport_stop(struct bna_llport *llport);
+static void bna_llport_fail(struct bna_llport *llport);
+
+enum bna_llport_event {
+ LLPORT_E_START = 1,
+ LLPORT_E_STOP = 2,
+ LLPORT_E_FAIL = 3,
+ LLPORT_E_UP = 4,
+ LLPORT_E_DOWN = 5,
+ LLPORT_E_FWRESP_UP = 6,
+ LLPORT_E_FWRESP_DOWN = 7
+};
+
+enum bna_llport_state {
+ BNA_LLPORT_STOPPED = 1,
+ BNA_LLPORT_DOWN = 2,
+ BNA_LLPORT_UP_RESP_WAIT = 3,
+ BNA_LLPORT_DOWN_RESP_WAIT = 4,
+ BNA_LLPORT_UP = 5,
+ BNA_LLPORT_LAST_RESP_WAIT = 6
+};
+
+bfa_fsm_state_decl(bna_llport, stopped, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, down, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, up_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, down_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, up, struct bna_llport,
+ enum bna_llport_event);
+bfa_fsm_state_decl(bna_llport, last_resp_wait, struct bna_llport,
+ enum bna_llport_event);
+
+static struct bfa_sm_table llport_sm_table[] = {
+ {BFA_SM(bna_llport_sm_stopped), BNA_LLPORT_STOPPED},
+ {BFA_SM(bna_llport_sm_down), BNA_LLPORT_DOWN},
+ {BFA_SM(bna_llport_sm_up_resp_wait), BNA_LLPORT_UP_RESP_WAIT},
+ {BFA_SM(bna_llport_sm_down_resp_wait), BNA_LLPORT_DOWN_RESP_WAIT},
+ {BFA_SM(bna_llport_sm_up), BNA_LLPORT_UP},
+ {BFA_SM(bna_llport_sm_last_resp_wait), BNA_LLPORT_LAST_RESP_WAIT}
+};
+
+static void
+bna_llport_sm_stopped_entry(struct bna_llport *llport)
+{
+ llport->bna->port.link_cbfn((llport)->bna->bnad, BNA_LINK_DOWN);
+ call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
+}
+
+static void
+bna_llport_sm_stopped(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_START:
+ bfa_fsm_set_state(llport, bna_llport_sm_down);
+ break;
+
+ case LLPORT_E_STOP:
+ call_llport_stop_cbfn(llport, BNA_CB_SUCCESS);
+ break;
+
+ case LLPORT_E_FAIL:
+ break;
+
+ case LLPORT_E_DOWN:
+ /* This event is received due to Rx objects failing */
+ /* No-op */
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ case LLPORT_E_FWRESP_DOWN:
+ /**
+ * These events are received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_down_entry(struct bna_llport *llport)
+{
+ bnad_cb_port_link_status((llport)->bna->bnad, BNA_LINK_DOWN);
+}
+
+static void
+bna_llport_sm_down(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
+ bna_fw_llport_up(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport)
+{
+ /**
+ * NOTE: Do not call bna_fw_llport_up() here. That will over step
+ * mbox due to down_resp_wait -> up_resp_wait transition on event
+ * LLPORT_E_UP
+ */
+}
+
+static void
+bna_llport_sm_up_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */
+ bna_fw_llport_up(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_down_resp_wait_entry(struct bna_llport *llport)
+{
+ /**
+ * NOTE: Do not call bna_fw_llport_down() here. That will over step
+ * mbox due to up_resp_wait -> down_resp_wait transition on event
+ * LLPORT_E_DOWN
+ */
+}
+
+static void
+bna_llport_sm_down_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_UP:
+ bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait);
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_up_entry(struct bna_llport *llport)
+{
+}
+
+static void
+bna_llport_sm_up(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_STOP:
+ bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait);
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait);
+ bna_fw_llport_down(llport);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_llport_sm_last_resp_wait_entry(struct bna_llport *llport)
+{
+}
+
+static void
+bna_llport_sm_last_resp_wait(struct bna_llport *llport,
+ enum bna_llport_event event)
+{
+ switch (event) {
+ case LLPORT_E_FAIL:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ case LLPORT_E_DOWN:
+ /**
+ * This event is received due to Rx objects stopping in
+ * parallel to llport
+ */
+ /* No-op */
+ break;
+
+ case LLPORT_E_FWRESP_UP:
+ /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */
+ bna_fw_llport_down(llport);
+ break;
+
+ case LLPORT_E_FWRESP_DOWN:
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(llport->bna, event);
+ }
+}
+
+static void
+bna_fw_llport_admin_up(struct bna_llport *llport)
+{
+ struct bfi_ll_port_admin_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.up = BNA_STATUS_T_ENABLED;
+
+ bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_llport_up, llport);
+
+ bna_mbox_send(llport->bna, &llport->mbox_qe);
+}
+
+static void
+bna_fw_llport_up(struct bna_llport *llport)
+{
+ if (llport->type == BNA_PORT_T_REGULAR)
+ bna_fw_llport_admin_up(llport);
+}
+
+static void
+bna_fw_cb_llport_up(void *arg, int status)
+{
+ struct bna_llport *llport = (struct bna_llport *)arg;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP);
+}
+
+static void
+bna_fw_llport_admin_down(struct bna_llport *llport)
+{
+ struct bfi_ll_port_admin_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.up = BNA_STATUS_T_DISABLED;
+
+ bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_llport_down, llport);
+
+ bna_mbox_send(llport->bna, &llport->mbox_qe);
+}
+
+static void
+bna_fw_llport_down(struct bna_llport *llport)
+{
+ if (llport->type == BNA_PORT_T_REGULAR)
+ bna_fw_llport_admin_down(llport);
+}
+
+static void
+bna_fw_cb_llport_down(void *arg, int status)
+{
+ struct bna_llport *llport = (struct bna_llport *)arg;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+ bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN);
+}
+
+void
+bna_port_cb_llport_stopped(struct bna_port *port,
+ enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+static void
+bna_llport_init(struct bna_llport *llport, struct bna *bna)
+{
+ llport->flags |= BNA_LLPORT_F_ENABLED;
+ llport->type = BNA_PORT_T_REGULAR;
+ llport->bna = bna;
+
+ llport->link_status = BNA_LINK_DOWN;
+
+ llport->admin_up_count = 0;
+
+ llport->stop_cbfn = NULL;
+
+ bfa_q_qe_init(&llport->mbox_qe.qe);
+
+ bfa_fsm_set_state(llport, bna_llport_sm_stopped);
+}
+
+static void
+bna_llport_uninit(struct bna_llport *llport)
+{
+ llport->flags &= ~BNA_LLPORT_F_ENABLED;
+
+ llport->bna = NULL;
+}
+
+static void
+bna_llport_start(struct bna_llport *llport)
+{
+ bfa_fsm_send_event(llport, LLPORT_E_START);
+}
+
+static void
+bna_llport_stop(struct bna_llport *llport)
+{
+ llport->stop_cbfn = bna_port_cb_llport_stopped;
+
+ bfa_fsm_send_event(llport, LLPORT_E_STOP);
+}
+
+static void
+bna_llport_fail(struct bna_llport *llport)
+{
+ bfa_fsm_send_event(llport, LLPORT_E_FAIL);
+}
+
+int
+bna_llport_state_get(struct bna_llport *llport)
+{
+ return bfa_sm_to_state(llport_sm_table, llport->fsm);
+}
+
+void
+bna_llport_admin_up(struct bna_llport *llport)
+{
+ llport->admin_up_count++;
+
+ if (llport->admin_up_count == 1) {
+ llport->flags |= BNA_LLPORT_F_RX_ENABLED;
+ if (llport->flags & BNA_LLPORT_F_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_UP);
+ }
+}
+
+void
+bna_llport_admin_down(struct bna_llport *llport)
+{
+ llport->admin_up_count--;
+
+ if (llport->admin_up_count == 0) {
+ llport->flags &= ~BNA_LLPORT_F_RX_ENABLED;
+ if (llport->flags & BNA_LLPORT_F_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_DOWN);
+ }
+}
+
+/**
+ * PORT
+ */
+#define bna_port_chld_start(port)\
+do {\
+ enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bna_llport_start(&(port)->llport);\
+ bna_tx_mod_start(&(port)->bna->tx_mod, tx_type);\
+ bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_chld_stop(port)\
+do {\
+ enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bna_llport_stop(&(port)->llport);\
+ bna_tx_mod_stop(&(port)->bna->tx_mod, tx_type);\
+ bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_chld_fail(port)\
+do {\
+ bna_llport_fail(&(port)->llport);\
+ bna_tx_mod_fail(&(port)->bna->tx_mod);\
+ bna_rx_mod_fail(&(port)->bna->rx_mod);\
+} while (0)
+
+#define bna_port_rx_start(port)\
+do {\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define bna_port_rx_stop(port)\
+do {\
+ enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\
+ BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\
+ bfa_wc_up(&(port)->chld_stop_wc);\
+ bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\
+} while (0)
+
+#define call_port_stop_cbfn(port, status)\
+do {\
+ if ((port)->stop_cbfn)\
+ (port)->stop_cbfn((port)->stop_cbarg, status);\
+ (port)->stop_cbfn = NULL;\
+ (port)->stop_cbarg = NULL;\
+} while (0)
+
+#define call_port_pause_cbfn(port, status)\
+do {\
+ if ((port)->pause_cbfn)\
+ (port)->pause_cbfn((port)->bna->bnad, status);\
+ (port)->pause_cbfn = NULL;\
+} while (0)
+
+#define call_port_mtu_cbfn(port, status)\
+do {\
+ if ((port)->mtu_cbfn)\
+ (port)->mtu_cbfn((port)->bna->bnad, status);\
+ (port)->mtu_cbfn = NULL;\
+} while (0)
+
+static void bna_fw_pause_set(struct bna_port *port);
+static void bna_fw_cb_pause_set(void *arg, int status);
+static void bna_fw_mtu_set(struct bna_port *port);
+static void bna_fw_cb_mtu_set(void *arg, int status);
+
+enum bna_port_event {
+ PORT_E_START = 1,
+ PORT_E_STOP = 2,
+ PORT_E_FAIL = 3,
+ PORT_E_PAUSE_CFG = 4,
+ PORT_E_MTU_CFG = 5,
+ PORT_E_CHLD_STOPPED = 6,
+ PORT_E_FWRESP_PAUSE = 7,
+ PORT_E_FWRESP_MTU = 8
+};
+
+enum bna_port_state {
+ BNA_PORT_STOPPED = 1,
+ BNA_PORT_MTU_INIT_WAIT = 2,
+ BNA_PORT_PAUSE_INIT_WAIT = 3,
+ BNA_PORT_LAST_RESP_WAIT = 4,
+ BNA_PORT_STARTED = 5,
+ BNA_PORT_PAUSE_CFG_WAIT = 6,
+ BNA_PORT_RX_STOP_WAIT = 7,
+ BNA_PORT_MTU_CFG_WAIT = 8,
+ BNA_PORT_CHLD_STOP_WAIT = 9
+};
+
+bfa_fsm_state_decl(bna_port, stopped, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, mtu_init_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, pause_init_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, last_resp_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, started, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, pause_cfg_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, rx_stop_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, mtu_cfg_wait, struct bna_port,
+ enum bna_port_event);
+bfa_fsm_state_decl(bna_port, chld_stop_wait, struct bna_port,
+ enum bna_port_event);
+
+static struct bfa_sm_table port_sm_table[] = {
+ {BFA_SM(bna_port_sm_stopped), BNA_PORT_STOPPED},
+ {BFA_SM(bna_port_sm_mtu_init_wait), BNA_PORT_MTU_INIT_WAIT},
+ {BFA_SM(bna_port_sm_pause_init_wait), BNA_PORT_PAUSE_INIT_WAIT},
+ {BFA_SM(bna_port_sm_last_resp_wait), BNA_PORT_LAST_RESP_WAIT},
+ {BFA_SM(bna_port_sm_started), BNA_PORT_STARTED},
+ {BFA_SM(bna_port_sm_pause_cfg_wait), BNA_PORT_PAUSE_CFG_WAIT},
+ {BFA_SM(bna_port_sm_rx_stop_wait), BNA_PORT_RX_STOP_WAIT},
+ {BFA_SM(bna_port_sm_mtu_cfg_wait), BNA_PORT_MTU_CFG_WAIT},
+ {BFA_SM(bna_port_sm_chld_stop_wait), BNA_PORT_CHLD_STOP_WAIT}
+};
+
+static void
+bna_port_sm_stopped_entry(struct bna_port *port)
+{
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+ call_port_stop_cbfn(port, BNA_CB_SUCCESS);
+}
+
+static void
+bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_START:
+ bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
+ break;
+
+ case PORT_E_STOP:
+ call_port_stop_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_FAIL:
+ /* No-op */
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_MTU_CFG:
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ /**
+ * This event is received due to LLPort, Tx and Rx objects
+ * failing
+ */
+ /* No-op */
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ case PORT_E_FWRESP_MTU:
+ /**
+ * These events are received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_mtu_init_wait_entry(struct bna_port *port)
+{
+ bna_fw_mtu_set(port);
+}
+
+static void
+bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ /* No-op */
+ break;
+
+ case PORT_E_MTU_CFG:
+ port->flags |= BNA_PORT_F_MTU_CHANGED;
+ break;
+
+ case PORT_E_FWRESP_MTU:
+ if (port->flags & BNA_PORT_F_MTU_CHANGED) {
+ port->flags &= ~BNA_PORT_F_MTU_CHANGED;
+ bna_fw_mtu_set(port);
+ } else {
+ bfa_fsm_set_state(port, bna_port_sm_pause_init_wait);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_pause_init_wait_entry(struct bna_port *port)
+{
+ bna_fw_pause_set(port);
+}
+
+static void
+bna_port_sm_pause_init_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_last_resp_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ port->flags |= BNA_PORT_F_PAUSE_CHANGED;
+ break;
+
+ case PORT_E_MTU_CFG:
+ port->flags |= BNA_PORT_F_MTU_CHANGED;
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ if (port->flags & BNA_PORT_F_PAUSE_CHANGED) {
+ port->flags &= ~BNA_PORT_F_PAUSE_CHANGED;
+ bna_fw_pause_set(port);
+ } else if (port->flags & BNA_PORT_F_MTU_CHANGED) {
+ port->flags &= ~BNA_PORT_F_MTU_CHANGED;
+ bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait);
+ } else {
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ bna_port_chld_start(port);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_last_resp_wait_entry(struct bna_port *port)
+{
+}
+
+static void
+bna_port_sm_last_resp_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ case PORT_E_FWRESP_PAUSE:
+ case PORT_E_FWRESP_MTU:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_started_entry(struct bna_port *port)
+{
+ /**
+ * NOTE: Do not call bna_port_chld_start() here, since it will be
+ * inadvertently called during pause_cfg_wait->started transition
+ * as well
+ */
+ call_port_pause_cbfn(port, BNA_CB_SUCCESS);
+ call_port_mtu_cbfn(port, BNA_CB_SUCCESS);
+}
+
+static void
+bna_port_sm_started(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_STOP:
+ bfa_fsm_set_state(port, bna_port_sm_chld_stop_wait);
+ break;
+
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_PAUSE_CFG:
+ bfa_fsm_set_state(port, bna_port_sm_pause_cfg_wait);
+ break;
+
+ case PORT_E_MTU_CFG:
+ bfa_fsm_set_state(port, bna_port_sm_rx_stop_wait);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_pause_cfg_wait_entry(struct bna_port *port)
+{
+ bna_fw_pause_set(port);
+}
+
+static void
+bna_port_sm_pause_cfg_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_FWRESP_PAUSE:
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_rx_stop_wait_entry(struct bna_port *port)
+{
+ bna_port_rx_stop(port);
+}
+
+static void
+bna_port_sm_rx_stop_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ bfa_fsm_set_state(port, bna_port_sm_mtu_cfg_wait);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_mtu_cfg_wait_entry(struct bna_port *port)
+{
+ bna_fw_mtu_set(port);
+}
+
+static void
+bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_FWRESP_MTU:
+ bfa_fsm_set_state(port, bna_port_sm_started);
+ bna_port_rx_start(port);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_port_sm_chld_stop_wait_entry(struct bna_port *port)
+{
+ bna_port_chld_stop(port);
+}
+
+static void
+bna_port_sm_chld_stop_wait(struct bna_port *port,
+ enum bna_port_event event)
+{
+ switch (event) {
+ case PORT_E_FAIL:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ bna_port_chld_fail(port);
+ break;
+
+ case PORT_E_CHLD_STOPPED:
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(port->bna, event);
+ }
+}
+
+static void
+bna_fw_pause_set(struct bna_port *port)
+{
+ struct bfi_ll_set_pause_req ll_req;
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_SET_PAUSE_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+
+ ll_req.tx_pause = port->pause_config.tx_pause;
+ ll_req.rx_pause = port->pause_config.rx_pause;
+
+ bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_pause_set, port);
+
+ bna_mbox_send(port->bna, &port->mbox_qe);
+}
+
+static void
+bna_fw_cb_pause_set(void *arg, int status)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+ bfa_fsm_send_event(port, PORT_E_FWRESP_PAUSE);
+}
+
+void
+bna_fw_mtu_set(struct bna_port *port)
+{
+ struct bfi_ll_mtu_info_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_MTU_INFO_REQ, 0);
+ ll_req.mtu = htons((u16)port->mtu);
+
+ bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_mtu_set, port);
+ bna_mbox_send(port->bna, &port->mbox_qe);
+}
+
+void
+bna_fw_cb_mtu_set(void *arg, int status)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+ bfa_fsm_send_event(port, PORT_E_FWRESP_MTU);
+}
+
+static void
+bna_port_cb_chld_stopped(void *arg)
+{
+ struct bna_port *port = (struct bna_port *)arg;
+
+ bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED);
+}
+
+void
+bna_port_init(struct bna_port *port, struct bna *bna)
+{
+ port->bna = bna;
+ port->flags = 0;
+ port->mtu = 0;
+ port->type = BNA_PORT_T_REGULAR;
+
+ port->link_cbfn = bnad_cb_port_link_status;
+
+ port->chld_stop_wc.wc_resume = bna_port_cb_chld_stopped;
+ port->chld_stop_wc.wc_cbarg = port;
+ port->chld_stop_wc.wc_count = 0;
+
+ port->stop_cbfn = NULL;
+ port->stop_cbarg = NULL;
+
+ port->pause_cbfn = NULL;
+
+ port->mtu_cbfn = NULL;
+
+ bfa_q_qe_init(&port->mbox_qe.qe);
+
+ bfa_fsm_set_state(port, bna_port_sm_stopped);
+
+ bna_llport_init(&port->llport, bna);
+}
+
+void
+bna_port_uninit(struct bna_port *port)
+{
+ bna_llport_uninit(&port->llport);
+
+ port->flags = 0;
+
+ port->bna = NULL;
+}
+
+int
+bna_port_state_get(struct bna_port *port)
+{
+ return bfa_sm_to_state(port_sm_table, port->fsm);
+}
+
+void
+bna_port_start(struct bna_port *port)
+{
+ port->flags |= BNA_PORT_F_DEVICE_READY;
+ if (port->flags & BNA_PORT_F_ENABLED)
+ bfa_fsm_send_event(port, PORT_E_START);
+}
+
+void
+bna_port_stop(struct bna_port *port)
+{
+ port->stop_cbfn = bna_device_cb_port_stopped;
+ port->stop_cbarg = &port->bna->device;
+
+ port->flags &= ~BNA_PORT_F_DEVICE_READY;
+ bfa_fsm_send_event(port, PORT_E_STOP);
+}
+
+void
+bna_port_fail(struct bna_port *port)
+{
+ port->flags &= ~BNA_PORT_F_DEVICE_READY;
+ bfa_fsm_send_event(port, PORT_E_FAIL);
+}
+
+void
+bna_port_cb_tx_stopped(struct bna_port *port, enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+void
+bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status)
+{
+ bfa_wc_down(&port->chld_stop_wc);
+}
+
+void
+bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen,
+ int status)
+{
+ int i;
+ u8 prio_map;
+
+ port->llport.link_status = BNA_LINK_UP;
+ if (aen->cee_linkup)
+ port->llport.link_status = BNA_CEE_UP;
+
+ /* Compute the priority */
+ prio_map = aen->prio_map;
+ if (prio_map) {
+ for (i = 0; i < 8; i++) {
+ if ((prio_map >> i) & 0x1)
+ break;
+ }
+ port->priority = i;
+ } else
+ port->priority = 0;
+
+ /* Dispatch events */
+ bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup);
+ bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority);
+ port->link_cbfn(port->bna->bnad, port->llport.link_status);
+}
+
+void
+bna_port_cb_link_down(struct bna_port *port, int status)
+{
+ port->llport.link_status = BNA_LINK_DOWN;
+
+ /* Dispatch events */
+ bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN);
+ port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN);
+}
+
+int
+bna_port_mtu_get(struct bna_port *port)
+{
+ return port->mtu;
+}
+
+void
+bna_port_enable(struct bna_port *port)
+{
+ if (port->fsm != (bfa_sm_t)bna_port_sm_stopped)
+ return;
+
+ port->flags |= BNA_PORT_F_ENABLED;
+
+ if (port->flags & BNA_PORT_F_DEVICE_READY)
+ bfa_fsm_send_event(port, PORT_E_START);
+}
+
+void
+bna_port_disable(struct bna_port *port, enum bna_cleanup_type type,
+ void (*cbfn)(void *, enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ (*cbfn)(port->bna->bnad, BNA_CB_SUCCESS);
+ return;
+ }
+
+ port->stop_cbfn = cbfn;
+ port->stop_cbarg = port->bna->bnad;
+
+ port->flags &= ~BNA_PORT_F_ENABLED;
+
+ bfa_fsm_send_event(port, PORT_E_STOP);
+}
+
+void
+bna_port_pause_config(struct bna_port *port,
+ struct bna_pause_config *pause_config,
+ void (*cbfn)(struct bnad *, enum bna_cb_status))
+{
+ port->pause_config = *pause_config;
+
+ port->pause_cbfn = cbfn;
+
+ bfa_fsm_send_event(port, PORT_E_PAUSE_CFG);
+}
+
+void
+bna_port_mtu_set(struct bna_port *port, int mtu,
+ void (*cbfn)(struct bnad *, enum bna_cb_status))
+{
+ port->mtu = mtu;
+
+ port->mtu_cbfn = cbfn;
+
+ bfa_fsm_send_event(port, PORT_E_MTU_CFG);
+}
+
+void
+bna_port_mac_get(struct bna_port *port, mac_t *mac)
+{
+ *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc);
+}
+
+/**
+ * Should be called only when port is disabled
+ */
+void
+bna_port_type_set(struct bna_port *port, enum bna_port_type type)
+{
+ port->type = type;
+ port->llport.type = type;
+}
+
+/**
+ * Should be called only when port is disabled
+ */
+void
+bna_port_linkcbfn_set(struct bna_port *port,
+ void (*linkcbfn)(struct bnad *, enum bna_link_status))
+{
+ port->link_cbfn = linkcbfn;
+}
+
+void
+bna_port_admin_up(struct bna_port *port)
+{
+ struct bna_llport *llport = &port->llport;
+
+ if (llport->flags & BNA_LLPORT_F_ENABLED)
+ return;
+
+ llport->flags |= BNA_LLPORT_F_ENABLED;
+
+ if (llport->flags & BNA_LLPORT_F_RX_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_UP);
+}
+
+void
+bna_port_admin_down(struct bna_port *port)
+{
+ struct bna_llport *llport = &port->llport;
+
+ if (!(llport->flags & BNA_LLPORT_F_ENABLED))
+ return;
+
+ llport->flags &= ~BNA_LLPORT_F_ENABLED;
+
+ if (llport->flags & BNA_LLPORT_F_RX_ENABLED)
+ bfa_fsm_send_event(llport, LLPORT_E_DOWN);
+}
+
+/**
+ * DEVICE
+ */
+#define enable_mbox_intr(_device)\
+do {\
+ u32 intr_status;\
+ bna_intr_status_get((_device)->bna, intr_status);\
+ bnad_cb_device_enable_mbox_intr((_device)->bna->bnad);\
+ bna_mbox_intr_enable((_device)->bna);\
+} while (0)
+
+#define disable_mbox_intr(_device)\
+do {\
+ bna_mbox_intr_disable((_device)->bna);\
+ bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\
+} while (0)
+
+const struct bna_chip_regs_offset reg_offset[] =
+{{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS,
+ HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0},
+{HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS,
+ HOSTFN1_INT_MASK, HOST_MSIX_ERR_INDEX_FN1},
+{HOST_PAGE_NUM_FN2, HOSTFN2_INT_STATUS,
+ HOSTFN2_INT_MASK, HOST_MSIX_ERR_INDEX_FN2},
+{HOST_PAGE_NUM_FN3, HOSTFN3_INT_STATUS,
+ HOSTFN3_INT_MASK, HOST_MSIX_ERR_INDEX_FN3},
+};
+
+enum bna_device_event {
+ DEVICE_E_ENABLE = 1,
+ DEVICE_E_DISABLE = 2,
+ DEVICE_E_IOC_READY = 3,
+ DEVICE_E_IOC_FAILED = 4,
+ DEVICE_E_IOC_DISABLED = 5,
+ DEVICE_E_IOC_RESET = 6,
+ DEVICE_E_PORT_STOPPED = 7,
+};
+
+enum bna_device_state {
+ BNA_DEVICE_STOPPED = 1,
+ BNA_DEVICE_IOC_READY_WAIT = 2,
+ BNA_DEVICE_READY = 3,
+ BNA_DEVICE_PORT_STOP_WAIT = 4,
+ BNA_DEVICE_IOC_DISABLE_WAIT = 5,
+ BNA_DEVICE_FAILED = 6
+};
+
+bfa_fsm_state_decl(bna_device, stopped, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ioc_ready_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ready, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, port_stop_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, ioc_disable_wait, struct bna_device,
+ enum bna_device_event);
+bfa_fsm_state_decl(bna_device, failed, struct bna_device,
+ enum bna_device_event);
+
+static struct bfa_sm_table device_sm_table[] = {
+ {BFA_SM(bna_device_sm_stopped), BNA_DEVICE_STOPPED},
+ {BFA_SM(bna_device_sm_ioc_ready_wait), BNA_DEVICE_IOC_READY_WAIT},
+ {BFA_SM(bna_device_sm_ready), BNA_DEVICE_READY},
+ {BFA_SM(bna_device_sm_port_stop_wait), BNA_DEVICE_PORT_STOP_WAIT},
+ {BFA_SM(bna_device_sm_ioc_disable_wait), BNA_DEVICE_IOC_DISABLE_WAIT},
+ {BFA_SM(bna_device_sm_failed), BNA_DEVICE_FAILED},
+};
+
+static void
+bna_device_sm_stopped_entry(struct bna_device *device)
+{
+ if (device->stop_cbfn)
+ device->stop_cbfn(device->stop_cbarg, BNA_CB_SUCCESS);
+
+ device->stop_cbfn = NULL;
+ device->stop_cbarg = NULL;
+}
+
+static void
+bna_device_sm_stopped(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_ENABLE:
+ if (device->intr_type == BNA_INTR_T_MSIX)
+ bna_mbox_msix_idx_set(device);
+ bfa_nw_ioc_enable(&device->ioc);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
+ break;
+
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ioc_ready_wait_entry(struct bna_device *device)
+{
+ /**
+ * Do not call bfa_ioc_enable() here. It must be called in the
+ * previous state due to failed -> ioc_ready_wait transition.
+ */
+}
+
+static void
+bna_device_sm_ioc_ready_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_INTERRUPT);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_READY:
+ bfa_fsm_set_state(device, bna_device_sm_ready);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ready_entry(struct bna_device *device)
+{
+ bna_mbox_mod_start(&device->bna->mbox_mod);
+ bna_port_start(&device->bna->port);
+
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_SUCCESS);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+}
+
+static void
+bna_device_sm_ready(struct bna_device *device, enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_port_stop_wait);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ bfa_fsm_set_state(device, bna_device_sm_failed);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_port_stop_wait_entry(struct bna_device *device)
+{
+ bna_port_stop(&device->bna->port);
+}
+
+static void
+bna_device_sm_port_stop_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_PORT_STOPPED:
+ bna_mbox_mod_stop(&device->bna->mbox_mod);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_FAILED:
+ disable_mbox_intr(device);
+ bna_port_fail(&device->bna->port);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_ioc_disable_wait_entry(struct bna_device *device)
+{
+ bfa_nw_ioc_disable(&device->ioc);
+}
+
+static void
+bna_device_sm_ioc_disable_wait(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_IOC_DISABLED:
+ disable_mbox_intr(device);
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+static void
+bna_device_sm_failed_entry(struct bna_device *device)
+{
+ disable_mbox_intr(device);
+ bna_port_fail(&device->bna->port);
+ bna_mbox_mod_stop(&device->bna->mbox_mod);
+
+ if (device->ready_cbfn)
+ device->ready_cbfn(device->ready_cbarg,
+ BNA_CB_FAIL);
+ device->ready_cbfn = NULL;
+ device->ready_cbarg = NULL;
+}
+
+static void
+bna_device_sm_failed(struct bna_device *device,
+ enum bna_device_event event)
+{
+ switch (event) {
+ case DEVICE_E_DISABLE:
+ bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait);
+ break;
+
+ case DEVICE_E_IOC_RESET:
+ enable_mbox_intr(device);
+ bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait);
+ break;
+
+ default:
+ bfa_sm_fault(device->bna, event);
+ }
+}
+
+/* IOC callback functions */
+
+static void
+bna_device_cb_iocll_ready(void *dev, enum bfa_status error)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ if (error)
+ bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
+ else
+ bfa_fsm_send_event(device, DEVICE_E_IOC_READY);
+}
+
+static void
+bna_device_cb_iocll_disabled(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_DISABLED);
+}
+
+static void
+bna_device_cb_iocll_failed(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED);
+}
+
+static void
+bna_device_cb_iocll_reset(void *dev)
+{
+ struct bna_device *device = (struct bna_device *)dev;
+
+ bfa_fsm_send_event(device, DEVICE_E_IOC_RESET);
+}
+
+static struct bfa_ioc_cbfn bfa_iocll_cbfn = {
+ bna_device_cb_iocll_ready,
+ bna_device_cb_iocll_disabled,
+ bna_device_cb_iocll_failed,
+ bna_device_cb_iocll_reset
+};
+
+void
+bna_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ u64 dma;
+
+ device->bna = bna;
+
+ /**
+ * Attach IOC and claim:
+ * 1. DMA memory for IOC attributes
+ * 2. Kernel memory for FW trace
+ */
+ bfa_nw_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn);
+ bfa_nw_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL);
+
+ BNA_GET_DMA_ADDR(
+ &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
+ bfa_nw_ioc_mem_claim(&device->ioc,
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva,
+ dma);
+
+ bna_adv_device_init(device, bna, res_info);
+ /*
+ * Initialize mbox_mod only after IOC, so that mbox handler
+ * registration goes through
+ */
+ device->intr_type =
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type;
+ device->vector =
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.idl[0].vector;
+ bna_mbox_mod_init(&bna->mbox_mod, bna);
+
+ device->ready_cbfn = device->stop_cbfn = NULL;
+ device->ready_cbarg = device->stop_cbarg = NULL;
+
+ bfa_fsm_set_state(device, bna_device_sm_stopped);
+}
+
+void
+bna_device_uninit(struct bna_device *device)
+{
+ bna_mbox_mod_uninit(&device->bna->mbox_mod);
+
+ bfa_nw_ioc_detach(&device->ioc);
+
+ device->bna = NULL;
+}
+
+void
+bna_device_cb_port_stopped(void *arg, enum bna_cb_status status)
+{
+ struct bna_device *device = (struct bna_device *)arg;
+
+ bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED);
+}
+
+int
+bna_device_status_get(struct bna_device *device)
+{
+ return (device->fsm == (bfa_fsm_t)bna_device_sm_ready);
+}
+
+void
+bna_device_enable(struct bna_device *device)
+{
+ if (device->fsm != (bfa_fsm_t)bna_device_sm_stopped) {
+ bnad_cb_device_enabled(device->bna->bnad, BNA_CB_BUSY);
+ return;
+ }
+
+ device->ready_cbfn = bnad_cb_device_enabled;
+ device->ready_cbarg = device->bna->bnad;
+
+ bfa_fsm_send_event(device, DEVICE_E_ENABLE);
+}
+
+void
+bna_device_disable(struct bna_device *device, enum bna_cleanup_type type)
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ bnad_cb_device_disabled(device->bna->bnad, BNA_CB_SUCCESS);
+ return;
+ }
+
+ device->stop_cbfn = bnad_cb_device_disabled;
+ device->stop_cbarg = device->bna->bnad;
+
+ bfa_fsm_send_event(device, DEVICE_E_DISABLE);
+}
+
+int
+bna_device_state_get(struct bna_device *device)
+{
+ return bfa_sm_to_state(device_sm_table, device->fsm);
+}
+
+u32 bna_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
+ {12, 20},
+ {10, 18},
+ {8, 16},
+ {6, 12},
+ {4, 8},
+ {3, 6},
+ {2, 4},
+ {1, 2},
+};
+
+u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
+ {12, 12},
+ {6, 10},
+ {5, 10},
+ {4, 8},
+ {3, 6},
+ {3, 6},
+ {2, 4},
+ {1, 2},
+};
+
+/* device */
+void
+bna_adv_device_init(struct bna_device *device, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ u8 *kva;
+ u64 dma;
+
+ device->bna = bna;
+
+ kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
+
+ /**
+ * Attach common modules (Diag, SFP, CEE, Port) and claim respective
+ * DMA memory.
+ */
+ BNA_GET_DMA_ADDR(
+ &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
+ kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
+
+ bfa_nw_cee_attach(&bna->cee, &device->ioc, bna);
+ bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
+ kva += bfa_nw_cee_meminfo();
+ dma += bfa_nw_cee_meminfo();
+
+}
+
+/* utils */
+
+void
+bna_adv_res_req(struct bna_res_info *res_info)
+{
+ /* DMA memory for COMMON_MODULE */
+ res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
+ bfa_nw_cee_meminfo(), PAGE_SIZE);
+
+ /* Virtual memory for retreiving fw_trc */
+ res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0;
+ res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0;
+
+ /* DMA memory for retreiving stats */
+ res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
+ ALIGN(BFI_HW_STATS_SIZE, PAGE_SIZE);
+
+ /* Virtual memory for soft stats */
+ res_info[BNA_RES_MEM_T_SWSTATS].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.len =
+ sizeof(struct bna_sw_stats);
+}
+
+static void
+bna_sw_stats_get(struct bna *bna, struct bna_sw_stats *sw_stats)
+{
+ struct bna_tx *tx;
+ struct bna_txq *txq;
+ struct bna_rx *rx;
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+ struct list_head *txq_qe;
+ struct list_head *rxp_qe;
+ struct list_head *mac_qe;
+ int i;
+
+ sw_stats->device_state = bna_device_state_get(&bna->device);
+ sw_stats->port_state = bna_port_state_get(&bna->port);
+ sw_stats->port_flags = bna->port.flags;
+ sw_stats->llport_state = bna_llport_state_get(&bna->port.llport);
+ sw_stats->priority = bna->port.priority;
+
+ i = 0;
+ list_for_each(qe, &bna->tx_mod.tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ sw_stats->tx_stats[i].tx_state = bna_tx_state_get(tx);
+ sw_stats->tx_stats[i].tx_flags = tx->flags;
+
+ sw_stats->tx_stats[i].num_txqs = 0;
+ sw_stats->tx_stats[i].txq_bmap[0] = 0;
+ sw_stats->tx_stats[i].txq_bmap[1] = 0;
+ list_for_each(txq_qe, &tx->txq_q) {
+ txq = (struct bna_txq *)txq_qe;
+ if (txq->txq_id < 32)
+ sw_stats->tx_stats[i].txq_bmap[0] |=
+ ((u32)1 << txq->txq_id);
+ else
+ sw_stats->tx_stats[i].txq_bmap[1] |=
+ ((u32)
+ 1 << (txq->txq_id - 32));
+ sw_stats->tx_stats[i].num_txqs++;
+ }
+
+ sw_stats->tx_stats[i].txf_id = tx->txf.txf_id;
+
+ i++;
+ }
+ sw_stats->num_active_tx = i;
+
+ i = 0;
+ list_for_each(qe, &bna->rx_mod.rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ sw_stats->rx_stats[i].rx_state = bna_rx_state_get(rx);
+ sw_stats->rx_stats[i].rx_flags = rx->rx_flags;
+
+ sw_stats->rx_stats[i].num_rxps = 0;
+ sw_stats->rx_stats[i].num_rxqs = 0;
+ sw_stats->rx_stats[i].rxq_bmap[0] = 0;
+ sw_stats->rx_stats[i].rxq_bmap[1] = 0;
+ sw_stats->rx_stats[i].cq_bmap[0] = 0;
+ sw_stats->rx_stats[i].cq_bmap[1] = 0;
+ list_for_each(rxp_qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)rxp_qe;
+
+ sw_stats->rx_stats[i].num_rxqs += 1;
+
+ if (rxp->type == BNA_RXP_SINGLE) {
+ if (rxp->rxq.single.only->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.single.only->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.single.only->rxq_id - 32));
+ }
+ } else {
+ if (rxp->rxq.slr.large->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.slr.large->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.slr.large->rxq_id - 32));
+ }
+
+ if (rxp->rxq.slr.small->rxq_id < 32) {
+ sw_stats->rx_stats[i].rxq_bmap[0] |=
+ ((u32)1 <<
+ rxp->rxq.slr.small->rxq_id);
+ } else {
+ sw_stats->rx_stats[i].rxq_bmap[1] |=
+ ((u32)1 <<
+ (rxp->rxq.slr.small->rxq_id - 32));
+ }
+ sw_stats->rx_stats[i].num_rxqs += 1;
+ }
+
+ if (rxp->cq.cq_id < 32)
+ sw_stats->rx_stats[i].cq_bmap[0] |=
+ (1 << rxp->cq.cq_id);
+ else
+ sw_stats->rx_stats[i].cq_bmap[1] |=
+ (1 << (rxp->cq.cq_id - 32));
+
+ sw_stats->rx_stats[i].num_rxps++;
+ }
+
+ sw_stats->rx_stats[i].rxf_id = rx->rxf.rxf_id;
+ sw_stats->rx_stats[i].rxf_state = bna_rxf_state_get(&rx->rxf);
+ sw_stats->rx_stats[i].rxf_oper_state = rx->rxf.rxf_oper_state;
+
+ sw_stats->rx_stats[i].num_active_ucast = 0;
+ if (rx->rxf.ucast_active_mac)
+ sw_stats->rx_stats[i].num_active_ucast++;
+ list_for_each(mac_qe, &rx->rxf.ucast_active_q)
+ sw_stats->rx_stats[i].num_active_ucast++;
+
+ sw_stats->rx_stats[i].num_active_mcast = 0;
+ list_for_each(mac_qe, &rx->rxf.mcast_active_q)
+ sw_stats->rx_stats[i].num_active_mcast++;
+
+ sw_stats->rx_stats[i].rxmode_active = rx->rxf.rxmode_active;
+ sw_stats->rx_stats[i].vlan_filter_status =
+ rx->rxf.vlan_filter_status;
+ memcpy(sw_stats->rx_stats[i].vlan_filter_table,
+ rx->rxf.vlan_filter_table,
+ sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32));
+
+ sw_stats->rx_stats[i].rss_status = rx->rxf.rss_status;
+ sw_stats->rx_stats[i].hds_status = rx->rxf.hds_status;
+
+ i++;
+ }
+ sw_stats->num_active_rx = i;
+}
+
+static void
+bna_fw_cb_stats_get(void *arg, int status)
+{
+ struct bna *bna = (struct bna *)arg;
+ u64 *p_stats;
+ int i, count;
+ int rxf_count, txf_count;
+ u64 rxf_bmap, txf_bmap;
+
+ bfa_q_qe_init(&bna->mbox_qe.qe);
+
+ if (status == 0) {
+ p_stats = (u64 *)bna->stats.hw_stats;
+ count = sizeof(struct bfi_ll_stats) / sizeof(u64);
+ for (i = 0; i < count; i++)
+ p_stats[i] = cpu_to_be64(p_stats[i]);
+
+ rxf_count = 0;
+ rxf_bmap = (u64)bna->stats.rxf_bmap[0] |
+ ((u64)bna->stats.rxf_bmap[1] << 32);
+ for (i = 0; i < BFI_LL_RXF_ID_MAX; i++)
+ if (rxf_bmap & ((u64)1 << i))
+ rxf_count++;
+
+ txf_count = 0;
+ txf_bmap = (u64)bna->stats.txf_bmap[0] |
+ ((u64)bna->stats.txf_bmap[1] << 32);
+ for (i = 0; i < BFI_LL_TXF_ID_MAX; i++)
+ if (txf_bmap & ((u64)1 << i))
+ txf_count++;
+
+ p_stats = (u64 *)&bna->stats.hw_stats->rxf_stats[0] +
+ ((rxf_count * sizeof(struct bfi_ll_stats_rxf) +
+ txf_count * sizeof(struct bfi_ll_stats_txf))/
+ sizeof(u64));
+
+ /* Populate the TXF stats from the firmware DMAed copy */
+ for (i = (BFI_LL_TXF_ID_MAX - 1); i >= 0; i--)
+ if (txf_bmap & ((u64)1 << i)) {
+ p_stats -= sizeof(struct bfi_ll_stats_txf)/
+ sizeof(u64);
+ memcpy(&bna->stats.hw_stats->txf_stats[i],
+ p_stats,
+ sizeof(struct bfi_ll_stats_txf));
+ }
+
+ /* Populate the RXF stats from the firmware DMAed copy */
+ for (i = (BFI_LL_RXF_ID_MAX - 1); i >= 0; i--)
+ if (rxf_bmap & ((u64)1 << i)) {
+ p_stats -= sizeof(struct bfi_ll_stats_rxf)/
+ sizeof(u64);
+ memcpy(&bna->stats.hw_stats->rxf_stats[i],
+ p_stats,
+ sizeof(struct bfi_ll_stats_rxf));
+ }
+
+ bna_sw_stats_get(bna, bna->stats.sw_stats);
+ bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
+ } else
+ bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
+}
+
+static void
+bna_fw_stats_get(struct bna *bna)
+{
+ struct bfi_ll_stats_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_GET_REQ, 0);
+ ll_req.stats_mask = htons(BFI_LL_STATS_ALL);
+
+ ll_req.rxf_id_mask[0] = htonl(bna->rx_mod.rxf_bmap[0]);
+ ll_req.rxf_id_mask[1] = htonl(bna->rx_mod.rxf_bmap[1]);
+ ll_req.txf_id_mask[0] = htonl(bna->tx_mod.txf_bmap[0]);
+ ll_req.txf_id_mask[1] = htonl(bna->tx_mod.txf_bmap[1]);
+
+ ll_req.host_buffer.a32.addr_hi = bna->hw_stats_dma.msb;
+ ll_req.host_buffer.a32.addr_lo = bna->hw_stats_dma.lsb;
+
+ bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_stats_get, bna);
+ bna_mbox_send(bna, &bna->mbox_qe);
+
+ bna->stats.rxf_bmap[0] = bna->rx_mod.rxf_bmap[0];
+ bna->stats.rxf_bmap[1] = bna->rx_mod.rxf_bmap[1];
+ bna->stats.txf_bmap[0] = bna->tx_mod.txf_bmap[0];
+ bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1];
+}
+
+static void
+bna_fw_cb_stats_clr(void *arg, int status)
+{
+ struct bna *bna = (struct bna *)arg;
+
+ bfa_q_qe_init(&bna->mbox_qe.qe);
+
+ memset(bna->stats.sw_stats, 0, sizeof(struct bna_sw_stats));
+ memset(bna->stats.hw_stats, 0, sizeof(struct bfi_ll_stats));
+
+ bnad_cb_stats_clr(bna->bnad);
+}
+
+static void
+bna_fw_stats_clr(struct bna *bna)
+{
+ struct bfi_ll_stats_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
+ ll_req.stats_mask = htons(BFI_LL_STATS_ALL);
+ ll_req.rxf_id_mask[0] = htonl(0xffffffff);
+ ll_req.rxf_id_mask[1] = htonl(0xffffffff);
+ ll_req.txf_id_mask[0] = htonl(0xffffffff);
+ ll_req.txf_id_mask[1] = htonl(0xffffffff);
+
+ bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_fw_cb_stats_clr, bna);
+ bna_mbox_send(bna, &bna->mbox_qe);
+}
+
+void
+bna_stats_get(struct bna *bna)
+{
+ if (bna_device_status_get(&bna->device))
+ bna_fw_stats_get(bna);
+ else
+ bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
+}
+
+void
+bna_stats_clr(struct bna *bna)
+{
+ if (bna_device_status_get(&bna->device))
+ bna_fw_stats_clr(bna);
+ else {
+ memset(&bna->stats.sw_stats, 0,
+ sizeof(struct bna_sw_stats));
+ memset(bna->stats.hw_stats, 0,
+ sizeof(struct bfi_ll_stats));
+ bnad_cb_stats_clr(bna->bnad);
+ }
+}
+
+/* IB */
+void
+bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo)
+{
+ ib->ib_config.coalescing_timeo = coalescing_timeo;
+
+ if (ib->start_count)
+ ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
+ (u32)ib->ib_config.coalescing_timeo, 0);
+}
+
+/* RxF */
+void
+bna_rxf_adv_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config)
+{
+ switch (q_config->rxp_type) {
+ case BNA_RXP_SINGLE:
+ /* No-op */
+ break;
+ case BNA_RXP_SLR:
+ rxf->ctrl_flags |= BNA_RXF_CF_SM_LG_RXQ;
+ break;
+ case BNA_RXP_HDS:
+ rxf->hds_cfg.hdr_type = q_config->hds_config.hdr_type;
+ rxf->hds_cfg.header_size =
+ q_config->hds_config.header_size;
+ rxf->forced_offset = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (q_config->rss_status == BNA_STATUS_T_ENABLED) {
+ rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
+ rxf->rss_cfg.hash_type = q_config->rss_config.hash_type;
+ rxf->rss_cfg.hash_mask = q_config->rss_config.hash_mask;
+ memcpy(&rxf->rss_cfg.toeplitz_hash_key[0],
+ &q_config->rss_config.toeplitz_hash_key[0],
+ sizeof(rxf->rss_cfg.toeplitz_hash_key));
+ }
+}
+
+static void
+rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status)
+{
+ struct bfi_ll_rxf_req req;
+
+ bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
+
+ req.rxf_id = rxf->rxf_id;
+ req.enable = status;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
+ rxf_cb_cam_fltr_mbox_cmd, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+void
+__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status)
+{
+ struct bna_rx_fndb_ram *rx_fndb_ram;
+ u32 ctrl_flags;
+ int i;
+
+ rx_fndb_ram = (struct bna_rx_fndb_ram *)
+ BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva,
+ RX_FNDB_RAM_BASE_OFFSET);
+
+ for (i = 0; i < BFI_MAX_RXF; i++) {
+ if (status == BNA_STATUS_T_ENABLED) {
+ if (i == rxf->rxf_id)
+ continue;
+
+ ctrl_flags =
+ readl(&rx_fndb_ram[i].control_flags);
+ ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
+ writel(ctrl_flags,
+ &rx_fndb_ram[i].control_flags);
+ } else {
+ ctrl_flags =
+ readl(&rx_fndb_ram[i].control_flags);
+ ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE;
+ writel(ctrl_flags,
+ &rx_fndb_ram[i].control_flags);
+ }
+ }
+}
+
+int
+rxf_process_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* Add additional MAC entries */
+ if (!list_empty(&rxf->ucast_pending_add_q)) {
+ bfa_q_deq(&rxf->ucast_pending_add_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_ADD_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->ucast_active_q);
+ return 1;
+ }
+
+ /* Delete MAC addresses previousely added */
+ if (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* Enable/disable promiscuous mode */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_PROMISC;
+
+ /* Disable VLAN filter to allow all VLANs */
+ __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* Enable/disable default mode */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_DEFAULT;
+
+ /* Disable VLAN filter to allow all VLANs */
+ __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED);
+ /* Redirect all other RxF vlan filtering to this one */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_process_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* Enable/disable allmulti mode */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active |= BNA_RXMODE_ALLMULTI;
+
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_ENABLED);
+ return 1;
+ } else if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* 1. delete pending ucast entries */
+ if (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ return 1;
+ }
+
+ /* 2. clear active ucast entries; move them to pending_add_q */
+ if (!list_empty(&rxf->ucast_active_q)) {
+ bfa_q_deq(&rxf->ucast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->ucast_pending_add_q);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 6. Execute pending promisc mode disable command */
+ if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move promisc configuration from pending -> active */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 7. Clear active promisc mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ /* move promisc configuration from active -> pending */
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 8. Execute pending default mode disable command */
+ if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move default configuration from pending -> active */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 9. Clear active default mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ /* move default configuration from active -> pending */
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+
+ /* Revert VLAN filter */
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ /* Stop RxF vlan filter table redirection */
+ __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED);
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* 10. Execute pending allmulti mode disable command */
+ if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* move allmulti configuration from pending -> active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ /* 11. Clear active allmulti mode; move it to pending enable */
+ if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ /* move allmulti configuration from active -> pending */
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ,
+ BNA_STATUS_T_DISABLED);
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+rxf_reset_packet_filter_ucast(struct bna_rxf *rxf)
+{
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* 1. Move active ucast entries to pending_add_q */
+ while (!list_empty(&rxf->ucast_active_q)) {
+ bfa_q_deq(&rxf->ucast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->ucast_pending_add_q);
+ }
+
+ /* 2. Throw away delete pending ucast entries */
+ while (!list_empty(&rxf->ucast_pending_del_q)) {
+ bfa_q_deq(&rxf->ucast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ }
+}
+
+void
+rxf_reset_packet_filter_promisc(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 6. Clear pending promisc mode disable */
+ if (is_promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+ }
+
+ /* 7. Move promisc mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
+ }
+
+}
+
+void
+rxf_reset_packet_filter_default(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+
+ /* 8. Clear pending default mode disable */
+ if (is_default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ bna->rxf_default_id = BFI_MAX_RXF;
+ }
+
+ /* 9. Move default mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT;
+ }
+}
+
+void
+rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf)
+{
+ /* 10. Clear pending allmulti mode disable */
+ if (is_allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ }
+
+ /* 11. Move allmulti mode config from active -> pending */
+ if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
+ }
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_promisc_enable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_PROMISC)) {
+ /* Schedule enable */
+ } else {
+ /* Promisc mode should not be active in the system */
+ promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ bna->rxf_promisc_id = rxf->rxf_id;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_promisc_disable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_promisc_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Promisc mode should not be active */
+ /* system promisc state should be pending */
+ promisc_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ /* Remove the promisc state from the system */
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
+ /* Promisc mode should be active in the system */
+ promisc_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+
+ /* Do nothing if already disabled */
+ } else {
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_default_enable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) {
+ /* Schedule enable */
+ } else {
+ /* Default mode should not be active in the system */
+ default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ bna->rxf_default_id = rxf->rxf_id;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_default_disable(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_default_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Promisc mode should not be active */
+ /* system default state should be pending */
+ default_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ /* Remove the default state from the system */
+ bna->rxf_default_id = BFI_MAX_RXF;
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) {
+ /* Default mode should be active in the system */
+ default_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+
+ /* Do nothing if already disabled */
+ } else {
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_allmulti_enable(struct bna_rxf *rxf)
+{
+ int ret = 0;
+
+ /* There can not be any pending disable command */
+
+ /* Do nothing if pending enable or already enabled */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask) ||
+ (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) {
+ /* Schedule enable */
+ } else {
+ allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/**
+ * Should only be called by bna_rxf_mode_set.
+ * Helps deciding if h/w configuration is needed or not.
+ * Returns:
+ * 0 = no h/w change
+ * 1 = need h/w change
+ */
+int
+rxf_allmulti_disable(struct bna_rxf *rxf)
+{
+ int ret = 0;
+
+ /* There can not be any pending disable */
+
+ /* Turn off pending enable command , if any */
+ if (is_allmulti_enable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask)) {
+ /* Allmulti mode should not be active */
+ allmulti_inactive(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+
+ /* Schedule disable */
+ } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
+ allmulti_disable(rxf->rxmode_pending,
+ rxf->rxmode_pending_bitmask);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/* RxF <- bnad */
+void
+bna_rx_mcast_delall(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+ int need_hw_config = 0;
+
+ /* Purge all entries from pending_add_q */
+ while (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+
+ /* Schedule all entries in active_q for deletion */
+ while (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
+ need_hw_config = 1;
+ }
+
+ if (need_hw_config) {
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ return;
+ }
+
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+}
+
+/* RxF <- Rx */
+void
+bna_rx_receive_resume(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) {
+ rxf->oper_state_cbfn = cbfn;
+ rxf->oper_state_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_RESUME);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+}
+
+void
+bna_rx_receive_pause(struct bna_rx *rx,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_RUNNING) {
+ rxf->oper_state_cbfn = cbfn;
+ rxf->oper_state_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_PAUSE);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+}
+
+/* RxF <- bnad */
+enum bna_cb_status
+bna_rx_ucast_add(struct bna_rx *rx, u8 *addr,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* Check if already added */
+ list_for_each(qe, &rxf->ucast_active_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ /* Check if pending addition */
+ list_for_each(qe, &rxf->ucast_pending_add_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ mac = bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
+ if (mac == NULL)
+ return BNA_CB_UCAST_CAM_FULL;
+ bfa_q_qe_init(&mac->qe);
+ memcpy(mac->addr, addr, ETH_ALEN);
+ list_add_tail(&mac->qe, &rxf->ucast_pending_add_q);
+
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+
+ return BNA_CB_SUCCESS;
+}
+
+/* RxF <- bnad */
+enum bna_cb_status
+bna_rx_ucast_del(struct bna_rx *rx, u8 *addr,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ list_for_each(qe, &rxf->ucast_pending_add_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ list_del(qe);
+ bfa_q_qe_init(qe);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ list_for_each(qe, &rxf->ucast_active_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ list_del(qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->ucast_pending_del_q);
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ return BNA_CB_INVALID_MAC;
+}
+
+/* RxF <- bnad */
+enum bna_cb_status
+bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
+ enum bna_rxmode bitmask,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int need_hw_config = 0;
+
+ /* Error checks */
+
+ if (is_promisc_enable(new_mode, bitmask)) {
+ /* If promisc mode is already enabled elsewhere in the system */
+ if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) &&
+ (rx->bna->rxf_promisc_id != rxf->rxf_id))
+ goto err_return;
+
+ /* If default mode is already enabled in the system */
+ if (rx->bna->rxf_default_id != BFI_MAX_RXF)
+ goto err_return;
+
+ /* Trying to enable promiscuous and default mode together */
+ if (is_default_enable(new_mode, bitmask))
+ goto err_return;
+ }
+
+ if (is_default_enable(new_mode, bitmask)) {
+ /* If default mode is already enabled elsewhere in the system */
+ if ((rx->bna->rxf_default_id != BFI_MAX_RXF) &&
+ (rx->bna->rxf_default_id != rxf->rxf_id)) {
+ goto err_return;
+ }
+
+ /* If promiscuous mode is already enabled in the system */
+ if (rx->bna->rxf_promisc_id != BFI_MAX_RXF)
+ goto err_return;
+ }
+
+ /* Process the commands */
+
+ if (is_promisc_enable(new_mode, bitmask)) {
+ if (rxf_promisc_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_promisc_disable(new_mode, bitmask)) {
+ if (rxf_promisc_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ if (is_default_enable(new_mode, bitmask)) {
+ if (rxf_default_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_default_disable(new_mode, bitmask)) {
+ if (rxf_default_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ if (is_allmulti_enable(new_mode, bitmask)) {
+ if (rxf_allmulti_enable(rxf))
+ need_hw_config = 1;
+ } else if (is_allmulti_disable(new_mode, bitmask)) {
+ if (rxf_allmulti_disable(rxf))
+ need_hw_config = 1;
+ }
+
+ /* Trigger h/w if needed */
+
+ if (need_hw_config) {
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+
+ return BNA_CB_SUCCESS;
+
+err_return:
+ return BNA_CB_FAIL;
+}
+
+/* RxF <- bnad */
+void
+bna_rx_rss_enable(struct bna_rx *rx)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
+ rxf->rss_status = BNA_STATUS_T_ENABLED;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+}
+
+/* RxF <- bnad */
+void
+bna_rx_rss_disable(struct bna_rx *rx)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
+ rxf->rss_status = BNA_STATUS_T_DISABLED;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+}
+
+/* RxF <- bnad */
+void
+bna_rx_rss_reconfig(struct bna_rx *rx, struct bna_rxf_rss *rss_config)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
+ rxf->rss_status = BNA_STATUS_T_ENABLED;
+ rxf->rss_cfg = *rss_config;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+}
+
+void
+/* RxF <- bnad */
+bna_rx_vlanfilter_enable(struct bna_rx *rx)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ rxf->vlan_filter_status = BNA_STATUS_T_ENABLED;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+/* RxF <- bnad */
+void
+bna_rx_vlanfilter_disable(struct bna_rx *rx)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+/* Rx */
+
+struct bna_rxp *
+bna_rx_get_rxp(struct bna_rx *rx, int vector)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ if (rxp->vector == vector)
+ return rxp;
+ }
+ return NULL;
+}
+
+/*
+ * bna_rx_rss_rit_set()
+ * Sets the Q ids for the specified msi-x vectors in the RIT.
+ * Maximum rit size supported is 64, which should be the max size of the
+ * vectors array.
+ */
+
+void
+bna_rx_rss_rit_set(struct bna_rx *rx, unsigned int *vectors, int nvectors)
+{
+ int i;
+ struct bna_rxp *rxp;
+ struct bna_rxq *q0 = NULL, *q1 = NULL;
+ struct bna *bna;
+ struct bna_rxf *rxf;
+
+ /* Build the RIT contents for this RX */
+ bna = rx->bna;
+
+ rxf = &rx->rxf;
+ for (i = 0; i < nvectors; i++) {
+ rxp = bna_rx_get_rxp(rx, vectors[i]);
+
+ GET_RXQS(rxp, q0, q1);
+ rxf->rit_segment->rit[i].large_rxq_id = q0->rxq_id;
+ rxf->rit_segment->rit[i].small_rxq_id = (q1 ? q1->rxq_id : 0);
+ }
+
+ rxf->rit_segment->rit_size = nvectors;
+
+ /* Subsequent call to enable/reconfig RSS will update the RIT in h/w */
+}
+
+/* Rx <- bnad */
+void
+bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo;
+ bna_ib_coalescing_timeo_set(rxp->cq.ib, coalescing_timeo);
+ }
+}
+
+/* Rx <- bnad */
+void
+bna_rx_dim_reconfig(struct bna *bna, u32 vector[][BNA_BIAS_T_MAX])
+{
+ int i, j;
+
+ for (i = 0; i < BNA_LOAD_T_MAX; i++)
+ for (j = 0; j < BNA_BIAS_T_MAX; j++)
+ bna->rx_mod.dim_vector[i][j] = vector[i][j];
+}
+
+/* Rx <- bnad */
+void
+bna_rx_dim_update(struct bna_ccb *ccb)
+{
+ struct bna *bna = ccb->cq->rx->bna;
+ u32 load, bias;
+ u32 pkt_rt, small_rt, large_rt;
+ u8 coalescing_timeo;
+
+ if ((ccb->pkt_rate.small_pkt_cnt == 0) &&
+ (ccb->pkt_rate.large_pkt_cnt == 0))
+ return;
+
+ /* Arrive at preconfigured coalescing timeo value based on pkt rate */
+
+ small_rt = ccb->pkt_rate.small_pkt_cnt;
+ large_rt = ccb->pkt_rate.large_pkt_cnt;
+
+ pkt_rt = small_rt + large_rt;
+
+ if (pkt_rt < BNA_PKT_RATE_10K)
+ load = BNA_LOAD_T_LOW_4;
+ else if (pkt_rt < BNA_PKT_RATE_20K)
+ load = BNA_LOAD_T_LOW_3;
+ else if (pkt_rt < BNA_PKT_RATE_30K)
+ load = BNA_LOAD_T_LOW_2;
+ else if (pkt_rt < BNA_PKT_RATE_40K)
+ load = BNA_LOAD_T_LOW_1;
+ else if (pkt_rt < BNA_PKT_RATE_50K)
+ load = BNA_LOAD_T_HIGH_1;
+ else if (pkt_rt < BNA_PKT_RATE_60K)
+ load = BNA_LOAD_T_HIGH_2;
+ else if (pkt_rt < BNA_PKT_RATE_80K)
+ load = BNA_LOAD_T_HIGH_3;
+ else
+ load = BNA_LOAD_T_HIGH_4;
+
+ if (small_rt > (large_rt << 1))
+ bias = 0;
+ else
+ bias = 1;
+
+ ccb->pkt_rate.small_pkt_cnt = 0;
+ ccb->pkt_rate.large_pkt_cnt = 0;
+
+ coalescing_timeo = bna->rx_mod.dim_vector[load][bias];
+ ccb->rx_coalescing_timeo = coalescing_timeo;
+
+ /* Set it to IB */
+ bna_ib_coalescing_timeo_set(ccb->cq->ib, coalescing_timeo);
+}
+
+/* Tx */
+/* TX <- bnad */
+enum bna_cb_status
+bna_tx_prio_set(struct bna_tx *tx, int prio,
+ void (*cbfn)(struct bnad *, struct bna_tx *,
+ enum bna_cb_status))
+{
+ if (tx->flags & BNA_TX_F_PRIO_LOCK)
+ return BNA_CB_FAIL;
+ else {
+ tx->prio_change_cbfn = cbfn;
+ bna_tx_prio_changed(tx, prio);
+ }
+
+ return BNA_CB_SUCCESS;
+}
+
+/* TX <- bnad */
+void
+bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_coalescing_timeo_set(txq->ib, coalescing_timeo);
+ }
+}
+
+/*
+ * Private data
+ */
+
+struct bna_ritseg_pool_cfg {
+ u32 pool_size;
+ u32 pool_entry_size;
+};
+init_ritseg_pool(ritseg_pool_cfg);
+
+/*
+ * Private functions
+ */
+static void
+bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ ucam_mod->ucmac = (struct bna_mac *)
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&ucam_mod->free_q);
+ for (i = 0; i < BFI_MAX_UCMAC; i++) {
+ bfa_q_qe_init(&ucam_mod->ucmac[i].qe);
+ list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
+ }
+
+ ucam_mod->bna = bna;
+}
+
+static void
+bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
+{
+ struct list_head *qe;
+ int i = 0;
+
+ list_for_each(qe, &ucam_mod->free_q)
+ i++;
+
+ ucam_mod->bna = NULL;
+}
+
+static void
+bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ mcam_mod->mcmac = (struct bna_mac *)
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&mcam_mod->free_q);
+ for (i = 0; i < BFI_MAX_MCMAC; i++) {
+ bfa_q_qe_init(&mcam_mod->mcmac[i].qe);
+ list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
+ }
+
+ mcam_mod->bna = bna;
+}
+
+static void
+bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
+{
+ struct list_head *qe;
+ int i = 0;
+
+ list_for_each(qe, &mcam_mod->free_q)
+ i++;
+
+ mcam_mod->bna = NULL;
+}
+
+static void
+bna_rit_mod_init(struct bna_rit_mod *rit_mod,
+ struct bna_res_info *res_info)
+{
+ int i;
+ int j;
+ int count;
+ int offset;
+
+ rit_mod->rit = (struct bna_rit_entry *)
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mdl[0].kva;
+ rit_mod->rit_segment = (struct bna_rit_segment *)
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mdl[0].kva;
+
+ count = 0;
+ offset = 0;
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ INIT_LIST_HEAD(&rit_mod->rit_seg_pool[i]);
+ for (j = 0; j < ritseg_pool_cfg[i].pool_size; j++) {
+ bfa_q_qe_init(&rit_mod->rit_segment[count].qe);
+ rit_mod->rit_segment[count].max_rit_size =
+ ritseg_pool_cfg[i].pool_entry_size;
+ rit_mod->rit_segment[count].rit_offset = offset;
+ rit_mod->rit_segment[count].rit =
+ &rit_mod->rit[offset];
+ list_add_tail(&rit_mod->rit_segment[count].qe,
+ &rit_mod->rit_seg_pool[i]);
+ count++;
+ offset += ritseg_pool_cfg[i].pool_entry_size;
+ }
+ }
+}
+
+static void
+bna_rit_mod_uninit(struct bna_rit_mod *rit_mod)
+{
+ struct bna_rit_segment *rit_segment;
+ struct list_head *qe;
+ int i;
+ int j;
+
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ j = 0;
+ list_for_each(qe, &rit_mod->rit_seg_pool[i]) {
+ rit_segment = (struct bna_rit_segment *)qe;
+ j++;
+ }
+ }
+}
+
+/*
+ * Public functions
+ */
+
+/* Called during probe(), before calling bna_init() */
+void
+bna_res_req(struct bna_res_info *res_info)
+{
+ bna_adv_res_req(res_info);
+
+ /* DMA memory for retrieving IOC attributes */
+ res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
+ ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
+
+ /* DMA memory for index segment of an IB */
+ res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.len =
+ BFI_IBIDX_SIZE * BFI_IBIDX_MAX_SEGSIZE;
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.num = BFI_MAX_IB;
+
+ /* Virtual memory for IB objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.len =
+ BFI_MAX_IB * sizeof(struct bna_ib);
+
+ /* Virtual memory for intr objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.len =
+ BFI_MAX_IB * sizeof(struct bna_intr);
+
+ /* Virtual memory for idx_seg objects - stored by IB module */
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.len =
+ BFI_IBIDX_TOTAL_SEGS * sizeof(struct bna_ibidx_seg);
+
+ /* Virtual memory for Tx objects - stored by Tx module */
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
+ BFI_MAX_TXQ * sizeof(struct bna_tx);
+
+ /* Virtual memory for TxQ - stored by Tx module */
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
+ BFI_MAX_TXQ * sizeof(struct bna_txq);
+
+ /* Virtual memory for Rx objects - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rx);
+
+ /* Virtual memory for RxPath - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rxp);
+
+ /* Virtual memory for RxQ - stored by Rx module */
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
+ BFI_MAX_RXQ * sizeof(struct bna_rxq);
+
+ /* Virtual memory for Unicast MAC address - stored by ucam module */
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
+ BFI_MAX_UCMAC * sizeof(struct bna_mac);
+
+ /* Virtual memory for Multicast MAC address - stored by mcam module */
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
+ BFI_MAX_MCMAC * sizeof(struct bna_mac);
+
+ /* Virtual memory for RIT entries */
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.len =
+ BFI_MAX_RIT_SIZE * sizeof(struct bna_rit_entry);
+
+ /* Virtual memory for RIT segment table */
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_type = BNA_RES_T_MEM;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mem_type =
+ BNA_MEM_T_KVA;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.num = 1;
+ res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.len =
+ BFI_RIT_TOTAL_SEGS * sizeof(struct bna_rit_segment);
+
+ /* Interrupt resource for mailbox interrupt */
+ res_info[BNA_RES_INTR_T_MBOX].res_type = BNA_RES_T_INTR;
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type =
+ BNA_INTR_T_MSIX;
+ res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.num = 1;
+}
+
+/* Called during probe() */
+void
+bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev,
+ struct bna_res_info *res_info)
+{
+ bna->bnad = bnad;
+ bna->pcidev = *pcidev;
+
+ bna->stats.hw_stats = (struct bfi_ll_stats *)
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
+ bna->hw_stats_dma.msb =
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
+ bna->hw_stats_dma.lsb =
+ res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
+ bna->stats.sw_stats = (struct bna_sw_stats *)
+ res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mdl[0].kva;
+
+ bna->regs.page_addr = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].page_addr;
+ bna->regs.fn_int_status = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].fn_int_status;
+ bna->regs.fn_int_mask = bna->pcidev.pci_bar_kva +
+ reg_offset[bna->pcidev.pci_func].fn_int_mask;
+
+ if (bna->pcidev.pci_func < 3)
+ bna->port_num = 0;
+ else
+ bna->port_num = 1;
+
+ /* Also initializes diag, cee, sfp, phy_port and mbox_mod */
+ bna_device_init(&bna->device, bna, res_info);
+
+ bna_port_init(&bna->port, bna);
+
+ bna_tx_mod_init(&bna->tx_mod, bna, res_info);
+
+ bna_rx_mod_init(&bna->rx_mod, bna, res_info);
+
+ bna_ib_mod_init(&bna->ib_mod, bna, res_info);
+
+ bna_rit_mod_init(&bna->rit_mod, res_info);
+
+ bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
+
+ bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
+
+ bna->rxf_default_id = BFI_MAX_RXF;
+ bna->rxf_promisc_id = BFI_MAX_RXF;
+
+ /* Mbox q element for posting stat request to f/w */
+ bfa_q_qe_init(&bna->mbox_qe.qe);
+}
+
+void
+bna_uninit(struct bna *bna)
+{
+ bna_mcam_mod_uninit(&bna->mcam_mod);
+
+ bna_ucam_mod_uninit(&bna->ucam_mod);
+
+ bna_rit_mod_uninit(&bna->rit_mod);
+
+ bna_ib_mod_uninit(&bna->ib_mod);
+
+ bna_rx_mod_uninit(&bna->rx_mod);
+
+ bna_tx_mod_uninit(&bna->tx_mod);
+
+ bna_port_uninit(&bna->port);
+
+ bna_device_uninit(&bna->device);
+
+ bna->bnad = NULL;
+}
+
+struct bna_mac *
+bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod)
+{
+ struct list_head *qe;
+
+ if (list_empty(&ucam_mod->free_q))
+ return NULL;
+
+ bfa_q_deq(&ucam_mod->free_q, &qe);
+
+ return (struct bna_mac *)qe;
+}
+
+void
+bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac)
+{
+ list_add_tail(&mac->qe, &ucam_mod->free_q);
+}
+
+struct bna_mac *
+bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod)
+{
+ struct list_head *qe;
+
+ if (list_empty(&mcam_mod->free_q))
+ return NULL;
+
+ bfa_q_deq(&mcam_mod->free_q, &qe);
+
+ return (struct bna_mac *)qe;
+}
+
+void
+bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac)
+{
+ list_add_tail(&mac->qe, &mcam_mod->free_q);
+}
+
+/**
+ * Note: This should be called in the same locking context as the call to
+ * bna_rit_mod_seg_get()
+ */
+int
+bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size)
+{
+ int i;
+
+ /* Select the pool for seg_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ if (i == BFI_RIT_SEG_TOTAL_POOLS)
+ return 0;
+
+ if (list_empty(&rit_mod->rit_seg_pool[i]))
+ return 0;
+
+ return 1;
+}
+
+struct bna_rit_segment *
+bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size)
+{
+ struct bna_rit_segment *seg;
+ struct list_head *qe;
+ int i;
+
+ /* Select the pool for seg_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg_size <= ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ if (i == BFI_RIT_SEG_TOTAL_POOLS)
+ return NULL;
+
+ if (list_empty(&rit_mod->rit_seg_pool[i]))
+ return NULL;
+
+ bfa_q_deq(&rit_mod->rit_seg_pool[i], &qe);
+ seg = (struct bna_rit_segment *)qe;
+ bfa_q_qe_init(&seg->qe);
+ seg->rit_size = seg_size;
+
+ return seg;
+}
+
+void
+bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod,
+ struct bna_rit_segment *seg)
+{
+ int i;
+
+ /* Select the pool for seg->max_rit_size */
+ for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
+ if (seg->max_rit_size == ritseg_pool_cfg[i].pool_entry_size)
+ break;
+ }
+
+ seg->rit_size = 0;
+ list_add_tail(&seg->qe, &rit_mod->rit_seg_pool[i]);
+}
diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h
new file mode 100644
index 000000000000..67eb376c5c7e
--- /dev/null
+++ b/drivers/net/bna/bna_hw.h
@@ -0,0 +1,1491 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * File for interrupt macros and functions
+ */
+
+#ifndef __BNA_HW_H__
+#define __BNA_HW_H__
+
+#include "bfi_ctreg.h"
+
+/**
+ *
+ * SW imposed limits
+ *
+ */
+
+#ifndef BNA_BIOS_BUILD
+
+#define BFI_MAX_TXQ 64
+#define BFI_MAX_RXQ 64
+#define BFI_MAX_RXF 64
+#define BFI_MAX_IB 128
+#define BFI_MAX_RIT_SIZE 256
+#define BFI_RSS_RIT_SIZE 64
+#define BFI_NONRSS_RIT_SIZE 1
+#define BFI_MAX_UCMAC 256
+#define BFI_MAX_MCMAC 512
+#define BFI_IBIDX_SIZE 4
+#define BFI_MAX_VLAN 4095
+
+/**
+ * There are 2 free IB index pools:
+ * pool1: 120 segments of 1 index each
+ * pool8: 1 segment of 8 indexes
+ */
+#define BFI_IBIDX_POOL1_SIZE 116
+#define BFI_IBIDX_POOL1_ENTRY_SIZE 1
+#define BFI_IBIDX_POOL2_SIZE 2
+#define BFI_IBIDX_POOL2_ENTRY_SIZE 2
+#define BFI_IBIDX_POOL8_SIZE 1
+#define BFI_IBIDX_POOL8_ENTRY_SIZE 8
+#define BFI_IBIDX_TOTAL_POOLS 3
+#define BFI_IBIDX_TOTAL_SEGS 119 /* (POOL1 + POOL2 + POOL8)_SIZE */
+#define BFI_IBIDX_MAX_SEGSIZE 8
+#define init_ibidx_pool(name) \
+static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \
+{ \
+ { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE }, \
+ { BFI_IBIDX_POOL2_SIZE, BFI_IBIDX_POOL2_ENTRY_SIZE }, \
+ { BFI_IBIDX_POOL8_SIZE, BFI_IBIDX_POOL8_ENTRY_SIZE } \
+}
+
+/**
+ * There are 2 free RIT segment pools:
+ * Pool1: 192 segments of 1 RIT entry each
+ * Pool2: 1 segment of 64 RIT entry
+ */
+#define BFI_RIT_SEG_POOL1_SIZE 192
+#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1
+#define BFI_RIT_SEG_POOLRSS_SIZE 1
+#define BFI_RIT_SEG_POOLRSS_ENTRY_SIZE 64
+#define BFI_RIT_SEG_TOTAL_POOLS 2
+#define BFI_RIT_TOTAL_SEGS 193 /* POOL1_SIZE + POOLRSS_SIZE */
+#define init_ritseg_pool(name) \
+static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
+{ \
+ { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE }, \
+ { BFI_RIT_SEG_POOLRSS_SIZE, BFI_RIT_SEG_POOLRSS_ENTRY_SIZE } \
+}
+
+#else /* BNA_BIOS_BUILD */
+
+#define BFI_MAX_TXQ 1
+#define BFI_MAX_RXQ 1
+#define BFI_MAX_RXF 1
+#define BFI_MAX_IB 2
+#define BFI_MAX_RIT_SIZE 2
+#define BFI_RSS_RIT_SIZE 64
+#define BFI_NONRSS_RIT_SIZE 1
+#define BFI_MAX_UCMAC 1
+#define BFI_MAX_MCMAC 8
+#define BFI_IBIDX_SIZE 4
+#define BFI_MAX_VLAN 4095
+/* There is one free pool: 2 segments of 1 index each */
+#define BFI_IBIDX_POOL1_SIZE 2
+#define BFI_IBIDX_POOL1_ENTRY_SIZE 1
+#define BFI_IBIDX_TOTAL_POOLS 1
+#define BFI_IBIDX_TOTAL_SEGS 2 /* POOL1_SIZE */
+#define BFI_IBIDX_MAX_SEGSIZE 1
+#define init_ibidx_pool(name) \
+static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \
+{ \
+ { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE } \
+}
+
+#define BFI_RIT_SEG_POOL1_SIZE 1
+#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1
+#define BFI_RIT_SEG_TOTAL_POOLS 1
+#define BFI_RIT_TOTAL_SEGS 1 /* POOL1_SIZE */
+#define init_ritseg_pool(name) \
+static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
+{ \
+ { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE } \
+}
+
+#endif /* BNA_BIOS_BUILD */
+
+#define BFI_RSS_HASH_KEY_LEN 10
+
+#define BFI_COALESCING_TIMER_UNIT 5 /* 5us */
+#define BFI_MAX_COALESCING_TIMEO 0xFF /* in 5us units */
+#define BFI_MAX_INTERPKT_COUNT 0xFF
+#define BFI_MAX_INTERPKT_TIMEO 0xF /* in 0.5us units */
+#define BFI_TX_COALESCING_TIMEO 20 /* 20 * 5 = 100us */
+#define BFI_TX_INTERPKT_COUNT 32
+#define BFI_RX_COALESCING_TIMEO 12 /* 12 * 5 = 60us */
+#define BFI_RX_INTERPKT_COUNT 6 /* Pkt Cnt = 6 */
+#define BFI_RX_INTERPKT_TIMEO 3 /* 3 * 0.5 = 1.5us */
+
+#define BFI_TXQ_WI_SIZE 64 /* bytes */
+#define BFI_RXQ_WI_SIZE 8 /* bytes */
+#define BFI_CQ_WI_SIZE 16 /* bytes */
+#define BFI_TX_MAX_WRR_QUOTA 0xFFF
+
+#define BFI_TX_MAX_VECTORS_PER_WI 4
+#define BFI_TX_MAX_VECTORS_PER_PKT 0xFF
+#define BFI_TX_MAX_DATA_PER_VECTOR 0xFFFF
+#define BFI_TX_MAX_DATA_PER_PKT 0xFFFFFF
+
+/* Small Q buffer size */
+#define BFI_SMALL_RXBUF_SIZE 128
+
+/* Defined separately since BFA_FLASH_DMA_BUF_SZ is in bfa_flash.c */
+#define BFI_FLASH_DMA_BUF_SZ 0x010000 /* 64K DMA */
+#define BFI_HW_STATS_SIZE 0x4000 /* 16K DMA */
+
+/**
+ *
+ * HW register offsets, macros
+ *
+ */
+
+/* DMA Block Register Host Window Start Address */
+#define DMA_BLK_REG_ADDR 0x00013000
+
+/* DMA Block Internal Registers */
+#define DMA_CTRL_REG0 (DMA_BLK_REG_ADDR + 0x000)
+#define DMA_CTRL_REG1 (DMA_BLK_REG_ADDR + 0x004)
+#define DMA_ERR_INT_STATUS (DMA_BLK_REG_ADDR + 0x008)
+#define DMA_ERR_INT_ENABLE (DMA_BLK_REG_ADDR + 0x00c)
+#define DMA_ERR_INT_STATUS_SET (DMA_BLK_REG_ADDR + 0x010)
+
+/* APP Block Register Address Offset from BAR0 */
+#define APP_BLK_REG_ADDR 0x00014000
+
+/* Host Function Interrupt Mask Registers */
+#define HOSTFN0_INT_MASK (APP_BLK_REG_ADDR + 0x004)
+#define HOSTFN1_INT_MASK (APP_BLK_REG_ADDR + 0x104)
+#define HOSTFN2_INT_MASK (APP_BLK_REG_ADDR + 0x304)
+#define HOSTFN3_INT_MASK (APP_BLK_REG_ADDR + 0x404)
+
+/**
+ * Host Function PCIe Error Registers
+ * Duplicates "Correctable" & "Uncorrectable"
+ * registers in PCIe Config space.
+ */
+#define FN0_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x014)
+#define FN1_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x114)
+#define FN2_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x314)
+#define FN3_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x414)
+
+/* Host Function Error Type Status Registers */
+#define FN0_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x018)
+#define FN1_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x118)
+#define FN2_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x318)
+#define FN3_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x418)
+
+/* Host Function Error Type Mask Registers */
+#define FN0_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x01c)
+#define FN1_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x11c)
+#define FN2_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x31c)
+#define FN3_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x41c)
+
+/* Catapult Host Semaphore Status Registers (App block) */
+#define HOST_SEM_STS0_REG (APP_BLK_REG_ADDR + 0x630)
+#define HOST_SEM_STS1_REG (APP_BLK_REG_ADDR + 0x634)
+#define HOST_SEM_STS2_REG (APP_BLK_REG_ADDR + 0x638)
+#define HOST_SEM_STS3_REG (APP_BLK_REG_ADDR + 0x63c)
+#define HOST_SEM_STS4_REG (APP_BLK_REG_ADDR + 0x640)
+#define HOST_SEM_STS5_REG (APP_BLK_REG_ADDR + 0x644)
+#define HOST_SEM_STS6_REG (APP_BLK_REG_ADDR + 0x648)
+#define HOST_SEM_STS7_REG (APP_BLK_REG_ADDR + 0x64c)
+
+/* PCIe Misc Register */
+#define PCIE_MISC_REG (APP_BLK_REG_ADDR + 0x200)
+
+/* Temp Sensor Control Registers */
+#define TEMPSENSE_CNTL_REG (APP_BLK_REG_ADDR + 0x250)
+#define TEMPSENSE_STAT_REG (APP_BLK_REG_ADDR + 0x254)
+
+/* APP Block local error registers */
+#define APP_LOCAL_ERR_STAT (APP_BLK_REG_ADDR + 0x258)
+#define APP_LOCAL_ERR_MSK (APP_BLK_REG_ADDR + 0x25c)
+
+/* PCIe Link Error registers */
+#define PCIE_LNK_ERR_STAT (APP_BLK_REG_ADDR + 0x260)
+#define PCIE_LNK_ERR_MSK (APP_BLK_REG_ADDR + 0x264)
+
+/**
+ * FCoE/FIP Ethertype Register
+ * 31:16 -- Chip wide value for FIP type
+ * 15:0 -- Chip wide value for FCoE type
+ */
+#define FCOE_FIP_ETH_TYPE (APP_BLK_REG_ADDR + 0x280)
+
+/**
+ * Reserved Ethertype Register
+ * 31:16 -- Reserved
+ * 15:0 -- Other ethertype
+ */
+#define RESV_ETH_TYPE (APP_BLK_REG_ADDR + 0x284)
+
+/**
+ * Host Command Status Registers
+ * Each set consists of 3 registers :
+ * clear, set, cmd
+ * 16 such register sets in all
+ * See catapult_spec.pdf for detailed functionality
+ * Put each type in a single macro accessed by _num ?
+ */
+#define HOST_CMDSTS0_CLR_REG (APP_BLK_REG_ADDR + 0x500)
+#define HOST_CMDSTS0_SET_REG (APP_BLK_REG_ADDR + 0x504)
+#define HOST_CMDSTS0_REG (APP_BLK_REG_ADDR + 0x508)
+#define HOST_CMDSTS1_CLR_REG (APP_BLK_REG_ADDR + 0x510)
+#define HOST_CMDSTS1_SET_REG (APP_BLK_REG_ADDR + 0x514)
+#define HOST_CMDSTS1_REG (APP_BLK_REG_ADDR + 0x518)
+#define HOST_CMDSTS2_CLR_REG (APP_BLK_REG_ADDR + 0x520)
+#define HOST_CMDSTS2_SET_REG (APP_BLK_REG_ADDR + 0x524)
+#define HOST_CMDSTS2_REG (APP_BLK_REG_ADDR + 0x528)
+#define HOST_CMDSTS3_CLR_REG (APP_BLK_REG_ADDR + 0x530)
+#define HOST_CMDSTS3_SET_REG (APP_BLK_REG_ADDR + 0x534)
+#define HOST_CMDSTS3_REG (APP_BLK_REG_ADDR + 0x538)
+#define HOST_CMDSTS4_CLR_REG (APP_BLK_REG_ADDR + 0x540)
+#define HOST_CMDSTS4_SET_REG (APP_BLK_REG_ADDR + 0x544)
+#define HOST_CMDSTS4_REG (APP_BLK_REG_ADDR + 0x548)
+#define HOST_CMDSTS5_CLR_REG (APP_BLK_REG_ADDR + 0x550)
+#define HOST_CMDSTS5_SET_REG (APP_BLK_REG_ADDR + 0x554)
+#define HOST_CMDSTS5_REG (APP_BLK_REG_ADDR + 0x558)
+#define HOST_CMDSTS6_CLR_REG (APP_BLK_REG_ADDR + 0x560)
+#define HOST_CMDSTS6_SET_REG (APP_BLK_REG_ADDR + 0x564)
+#define HOST_CMDSTS6_REG (APP_BLK_REG_ADDR + 0x568)
+#define HOST_CMDSTS7_CLR_REG (APP_BLK_REG_ADDR + 0x570)
+#define HOST_CMDSTS7_SET_REG (APP_BLK_REG_ADDR + 0x574)
+#define HOST_CMDSTS7_REG (APP_BLK_REG_ADDR + 0x578)
+#define HOST_CMDSTS8_CLR_REG (APP_BLK_REG_ADDR + 0x580)
+#define HOST_CMDSTS8_SET_REG (APP_BLK_REG_ADDR + 0x584)
+#define HOST_CMDSTS8_REG (APP_BLK_REG_ADDR + 0x588)
+#define HOST_CMDSTS9_CLR_REG (APP_BLK_REG_ADDR + 0x590)
+#define HOST_CMDSTS9_SET_REG (APP_BLK_REG_ADDR + 0x594)
+#define HOST_CMDSTS9_REG (APP_BLK_REG_ADDR + 0x598)
+#define HOST_CMDSTS10_CLR_REG (APP_BLK_REG_ADDR + 0x5A0)
+#define HOST_CMDSTS10_SET_REG (APP_BLK_REG_ADDR + 0x5A4)
+#define HOST_CMDSTS10_REG (APP_BLK_REG_ADDR + 0x5A8)
+#define HOST_CMDSTS11_CLR_REG (APP_BLK_REG_ADDR + 0x5B0)
+#define HOST_CMDSTS11_SET_REG (APP_BLK_REG_ADDR + 0x5B4)
+#define HOST_CMDSTS11_REG (APP_BLK_REG_ADDR + 0x5B8)
+#define HOST_CMDSTS12_CLR_REG (APP_BLK_REG_ADDR + 0x5C0)
+#define HOST_CMDSTS12_SET_REG (APP_BLK_REG_ADDR + 0x5C4)
+#define HOST_CMDSTS12_REG (APP_BLK_REG_ADDR + 0x5C8)
+#define HOST_CMDSTS13_CLR_REG (APP_BLK_REG_ADDR + 0x5D0)
+#define HOST_CMDSTS13_SET_REG (APP_BLK_REG_ADDR + 0x5D4)
+#define HOST_CMDSTS13_REG (APP_BLK_REG_ADDR + 0x5D8)
+#define HOST_CMDSTS14_CLR_REG (APP_BLK_REG_ADDR + 0x5E0)
+#define HOST_CMDSTS14_SET_REG (APP_BLK_REG_ADDR + 0x5E4)
+#define HOST_CMDSTS14_REG (APP_BLK_REG_ADDR + 0x5E8)
+#define HOST_CMDSTS15_CLR_REG (APP_BLK_REG_ADDR + 0x5F0)
+#define HOST_CMDSTS15_SET_REG (APP_BLK_REG_ADDR + 0x5F4)
+#define HOST_CMDSTS15_REG (APP_BLK_REG_ADDR + 0x5F8)
+
+/**
+ * LPU0 Block Register Address Offset from BAR0
+ * Range 0x18000 - 0x18033
+ */
+#define LPU0_BLK_REG_ADDR 0x00018000
+
+/**
+ * LPU0 Registers
+ * Should they be directly used from host,
+ * except for diagnostics ?
+ * CTL_REG : Control register
+ * CMD_REG : Triggers exec. of cmd. in
+ * Mailbox memory
+ */
+#define LPU0_MBOX_CTL_REG (LPU0_BLK_REG_ADDR + 0x000)
+#define LPU0_MBOX_CMD_REG (LPU0_BLK_REG_ADDR + 0x004)
+#define LPU0_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x008)
+#define LPU1_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x00c)
+#define LPU0_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x010)
+#define LPU1_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x014)
+#define LPU0_ERR_STATUS_REG (LPU0_BLK_REG_ADDR + 0x018)
+#define LPU0_ERR_SET_REG (LPU0_BLK_REG_ADDR + 0x020)
+
+/**
+ * LPU1 Block Register Address Offset from BAR0
+ * Range 0x18400 - 0x18433
+ */
+#define LPU1_BLK_REG_ADDR 0x00018400
+
+/**
+ * LPU1 Registers
+ * Same as LPU0 registers above
+ */
+#define LPU1_MBOX_CTL_REG (LPU1_BLK_REG_ADDR + 0x000)
+#define LPU1_MBOX_CMD_REG (LPU1_BLK_REG_ADDR + 0x004)
+#define LPU0_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x008)
+#define LPU1_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x00c)
+#define LPU0_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x010)
+#define LPU1_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x014)
+#define LPU1_ERR_STATUS_REG (LPU1_BLK_REG_ADDR + 0x018)
+#define LPU1_ERR_SET_REG (LPU1_BLK_REG_ADDR + 0x020)
+
+/**
+ * PSS Block Register Address Offset from BAR0
+ * Range 0x18800 - 0x188DB
+ */
+#define PSS_BLK_REG_ADDR 0x00018800
+
+/**
+ * PSS Registers
+ * For details, see catapult_spec.pdf
+ * ERR_STATUS_REG : Indicates error in PSS module
+ * RAM_ERR_STATUS_REG : Indicates RAM module that detected error
+ */
+#define ERR_STATUS_SET (PSS_BLK_REG_ADDR + 0x018)
+#define PSS_RAM_ERR_STATUS_REG (PSS_BLK_REG_ADDR + 0x01C)
+
+/**
+ * PSS Semaphore Lock Registers, total 16
+ * First read when unlocked returns 0,
+ * and is set to 1, atomically.
+ * Subsequent reads returns 1.
+ * To clear set the value to 0.
+ * Range : 0x20 to 0x5c
+ */
+#define PSS_SEM_LOCK_REG(_num) \
+ (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+/**
+ * PSS Semaphore Status Registers,
+ * corresponding to the lock registers above
+ */
+#define PSS_SEM_STATUS_REG(_num) \
+ (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2))
+
+/**
+ * Catapult CPQ Registers
+ * Defines for Mailbox Registers
+ * Used to send mailbox commands to firmware from
+ * host. The data part is written to the MBox
+ * memory, registers are used to indicate that
+ * a commnad is resident in memory.
+ *
+ * Note : LPU0<->LPU1 mailboxes are not listed here
+ */
+#define CPQ_BLK_REG_ADDR 0x00019000
+
+#define HOSTFN0_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x130)
+#define HOSTFN0_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x134)
+#define LPU0_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x138)
+#define LPU1_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x13C)
+
+#define HOSTFN1_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x140)
+#define HOSTFN1_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x144)
+#define LPU0_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x148)
+#define LPU1_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x14C)
+
+#define HOSTFN2_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x170)
+#define HOSTFN2_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x174)
+#define LPU0_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x178)
+#define LPU1_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x17C)
+
+#define HOSTFN3_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x180)
+#define HOSTFN3_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x184)
+#define LPU0_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x188)
+#define LPU1_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x18C)
+
+/* Host Function Force Parity Error Registers */
+#define HOSTFN0_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x120)
+#define HOSTFN1_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x124)
+#define HOSTFN2_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x128)
+#define HOSTFN3_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x12C)
+
+/* LL Port[0|1] Halt Mask Registers */
+#define LL_HALT_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1A0)
+#define LL_HALT_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1B0)
+
+/* LL Port[0|1] Error Mask Registers */
+#define LL_ERR_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1D0)
+#define LL_ERR_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1D4)
+
+/* EMC FLI (Flash Controller) Block Register Address Offset from BAR0 */
+#define FLI_BLK_REG_ADDR 0x0001D000
+
+/* EMC FLI Registers */
+#define FLI_CMD_REG (FLI_BLK_REG_ADDR + 0x000)
+#define FLI_ADDR_REG (FLI_BLK_REG_ADDR + 0x004)
+#define FLI_CTL_REG (FLI_BLK_REG_ADDR + 0x008)
+#define FLI_WRDATA_REG (FLI_BLK_REG_ADDR + 0x00C)
+#define FLI_RDDATA_REG (FLI_BLK_REG_ADDR + 0x010)
+#define FLI_DEV_STATUS_REG (FLI_BLK_REG_ADDR + 0x014)
+#define FLI_SIG_WD_REG (FLI_BLK_REG_ADDR + 0x018)
+
+/**
+ * RO register
+ * 31:16 -- Vendor Id
+ * 15:0 -- Device Id
+ */
+#define FLI_DEV_VENDOR_REG (FLI_BLK_REG_ADDR + 0x01C)
+#define FLI_ERR_STATUS_REG (FLI_BLK_REG_ADDR + 0x020)
+
+/**
+ * RAD (RxAdm) Block Register Address Offset from BAR0
+ * RAD0 Range : 0x20000 - 0x203FF
+ * RAD1 Range : 0x20400 - 0x207FF
+ */
+#define RAD0_BLK_REG_ADDR 0x00020000
+#define RAD1_BLK_REG_ADDR 0x00020400
+
+/* RAD0 Registers */
+#define RAD0_CTL_REG (RAD0_BLK_REG_ADDR + 0x000)
+#define RAD0_PE_PARM_REG (RAD0_BLK_REG_ADDR + 0x004)
+#define RAD0_BCN_REG (RAD0_BLK_REG_ADDR + 0x008)
+
+/* Default function ID register */
+#define RAD0_DEFAULT_REG (RAD0_BLK_REG_ADDR + 0x00C)
+
+/* Default promiscuous ID register */
+#define RAD0_PROMISC_REG (RAD0_BLK_REG_ADDR + 0x010)
+
+#define RAD0_BCNQ_REG (RAD0_BLK_REG_ADDR + 0x014)
+
+/*
+ * This register selects 1 of 8 PM Q's using
+ * VLAN pri, for non-BCN packets without a VLAN tag
+ */
+#define RAD0_DEFAULTQ_REG (RAD0_BLK_REG_ADDR + 0x018)
+
+#define RAD0_ERR_STS (RAD0_BLK_REG_ADDR + 0x01C)
+#define RAD0_SET_ERR_STS (RAD0_BLK_REG_ADDR + 0x020)
+#define RAD0_ERR_INT_EN (RAD0_BLK_REG_ADDR + 0x024)
+#define RAD0_FIRST_ERR (RAD0_BLK_REG_ADDR + 0x028)
+#define RAD0_FORCE_ERR (RAD0_BLK_REG_ADDR + 0x02C)
+
+#define RAD0_IF_RCVD (RAD0_BLK_REG_ADDR + 0x030)
+#define RAD0_IF_RCVD_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x034)
+#define RAD0_IF_RCVD_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x038)
+#define RAD0_IF_RCVD_VLAN (RAD0_BLK_REG_ADDR + 0x03C)
+#define RAD0_IF_RCVD_UCAST (RAD0_BLK_REG_ADDR + 0x040)
+#define RAD0_IF_RCVD_UCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x044)
+#define RAD0_IF_RCVD_UCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x048)
+#define RAD0_IF_RCVD_UCAST_VLAN (RAD0_BLK_REG_ADDR + 0x04C)
+#define RAD0_IF_RCVD_MCAST (RAD0_BLK_REG_ADDR + 0x050)
+#define RAD0_IF_RCVD_MCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x054)
+#define RAD0_IF_RCVD_MCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x058)
+#define RAD0_IF_RCVD_MCAST_VLAN (RAD0_BLK_REG_ADDR + 0x05C)
+#define RAD0_IF_RCVD_BCAST (RAD0_BLK_REG_ADDR + 0x060)
+#define RAD0_IF_RCVD_BCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x064)
+#define RAD0_IF_RCVD_BCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x068)
+#define RAD0_IF_RCVD_BCAST_VLAN (RAD0_BLK_REG_ADDR + 0x06C)
+#define RAD0_DROPPED_FRAMES (RAD0_BLK_REG_ADDR + 0x070)
+
+#define RAD0_MAC_MAN_1H (RAD0_BLK_REG_ADDR + 0x080)
+#define RAD0_MAC_MAN_1L (RAD0_BLK_REG_ADDR + 0x084)
+#define RAD0_MAC_MAN_2H (RAD0_BLK_REG_ADDR + 0x088)
+#define RAD0_MAC_MAN_2L (RAD0_BLK_REG_ADDR + 0x08C)
+#define RAD0_MAC_MAN_3H (RAD0_BLK_REG_ADDR + 0x090)
+#define RAD0_MAC_MAN_3L (RAD0_BLK_REG_ADDR + 0x094)
+#define RAD0_MAC_MAN_4H (RAD0_BLK_REG_ADDR + 0x098)
+#define RAD0_MAC_MAN_4L (RAD0_BLK_REG_ADDR + 0x09C)
+
+#define RAD0_LAST4_IP (RAD0_BLK_REG_ADDR + 0x100)
+
+/* RAD1 Registers */
+#define RAD1_CTL_REG (RAD1_BLK_REG_ADDR + 0x000)
+#define RAD1_PE_PARM_REG (RAD1_BLK_REG_ADDR + 0x004)
+#define RAD1_BCN_REG (RAD1_BLK_REG_ADDR + 0x008)
+
+/* Default function ID register */
+#define RAD1_DEFAULT_REG (RAD1_BLK_REG_ADDR + 0x00C)
+
+/* Promiscuous function ID register */
+#define RAD1_PROMISC_REG (RAD1_BLK_REG_ADDR + 0x010)
+
+#define RAD1_BCNQ_REG (RAD1_BLK_REG_ADDR + 0x014)
+
+/*
+ * This register selects 1 of 8 PM Q's using
+ * VLAN pri, for non-BCN packets without a VLAN tag
+ */
+#define RAD1_DEFAULTQ_REG (RAD1_BLK_REG_ADDR + 0x018)
+
+#define RAD1_ERR_STS (RAD1_BLK_REG_ADDR + 0x01C)
+#define RAD1_SET_ERR_STS (RAD1_BLK_REG_ADDR + 0x020)
+#define RAD1_ERR_INT_EN (RAD1_BLK_REG_ADDR + 0x024)
+
+/**
+ * TXA Block Register Address Offset from BAR0
+ * TXA0 Range : 0x21000 - 0x213FF
+ * TXA1 Range : 0x21400 - 0x217FF
+ */
+#define TXA0_BLK_REG_ADDR 0x00021000
+#define TXA1_BLK_REG_ADDR 0x00021400
+
+/* TXA Registers */
+#define TXA0_CTRL_REG (TXA0_BLK_REG_ADDR + 0x000)
+#define TXA1_CTRL_REG (TXA1_BLK_REG_ADDR + 0x000)
+
+/**
+ * TSO Sequence # Registers (RO)
+ * Total 8 (for 8 queues)
+ * Holds the last seq.# for TSO frames
+ * See catapult_spec.pdf for more details
+ */
+#define TXA0_TSO_TCP_SEQ_REG(_num) \
+ (TXA0_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+#define TXA1_TSO_TCP_SEQ_REG(_num) \
+ (TXA1_BLK_REG_ADDR + 0x020 + ((_num) << 2))
+
+/**
+ * TSO IP ID # Registers (RO)
+ * Total 8 (for 8 queues)
+ * Holds the last IP ID for TSO frames
+ * See catapult_spec.pdf for more details
+ */
+#define TXA0_TSO_IP_INFO_REG(_num) \
+ (TXA0_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+#define TXA1_TSO_IP_INFO_REG(_num) \
+ (TXA1_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+/**
+ * RXA Block Register Address Offset from BAR0
+ * RXA0 Range : 0x21800 - 0x21BFF
+ * RXA1 Range : 0x21C00 - 0x21FFF
+ */
+#define RXA0_BLK_REG_ADDR 0x00021800
+#define RXA1_BLK_REG_ADDR 0x00021C00
+
+/* RXA Registers */
+#define RXA0_CTL_REG (RXA0_BLK_REG_ADDR + 0x040)
+#define RXA1_CTL_REG (RXA1_BLK_REG_ADDR + 0x040)
+
+/**
+ * PPLB Block Register Address Offset from BAR0
+ * PPLB0 Range : 0x22000 - 0x223FF
+ * PPLB1 Range : 0x22400 - 0x227FF
+ */
+#define PLB0_BLK_REG_ADDR 0x00022000
+#define PLB1_BLK_REG_ADDR 0x00022400
+
+/**
+ * PLB Registers
+ * Holds RL timer used time stamps in RLT tagged frames
+ */
+#define PLB0_ECM_TIMER_REG (PLB0_BLK_REG_ADDR + 0x05C)
+#define PLB1_ECM_TIMER_REG (PLB1_BLK_REG_ADDR + 0x05C)
+
+/* Controls the rate-limiter on each of the priority class */
+#define PLB0_RL_CTL (PLB0_BLK_REG_ADDR + 0x060)
+#define PLB1_RL_CTL (PLB1_BLK_REG_ADDR + 0x060)
+
+/**
+ * Max byte register, total 8, 0-7
+ * see catapult_spec.pdf for details
+ */
+#define PLB0_RL_MAX_BC(_num) \
+ (PLB0_BLK_REG_ADDR + 0x064 + ((_num) << 2))
+#define PLB1_RL_MAX_BC(_num) \
+ (PLB1_BLK_REG_ADDR + 0x064 + ((_num) << 2))
+
+/**
+ * RL Time Unit Register for priority 0-7
+ * 4 bits per priority
+ * (2^rl_unit)*1us is the actual time period
+ */
+#define PLB0_RL_TU_PRIO (PLB0_BLK_REG_ADDR + 0x084)
+#define PLB1_RL_TU_PRIO (PLB1_BLK_REG_ADDR + 0x084)
+
+/**
+ * RL byte count register,
+ * bytes transmitted in (rl_unit*1)us time period
+ * 1 per priority, 8 in all, 0-7.
+ */
+#define PLB0_RL_BYTE_CNT(_num) \
+ (PLB0_BLK_REG_ADDR + 0x088 + ((_num) << 2))
+#define PLB1_RL_BYTE_CNT(_num) \
+ (PLB1_BLK_REG_ADDR + 0x088 + ((_num) << 2))
+
+/**
+ * RL Min factor register
+ * 2 bits per priority,
+ * 4 factors possible: 1, 0.5, 0.25, 0
+ * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
+ */
+#define PLB0_RL_MIN_REG (PLB0_BLK_REG_ADDR + 0x0A8)
+#define PLB1_RL_MIN_REG (PLB1_BLK_REG_ADDR + 0x0A8)
+
+/**
+ * RL Max factor register
+ * 2 bits per priority,
+ * 4 factors possible: 1, 0.5, 0.25, 0
+ * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1
+ */
+#define PLB0_RL_MAX_REG (PLB0_BLK_REG_ADDR + 0x0AC)
+#define PLB1_RL_MAX_REG (PLB1_BLK_REG_ADDR + 0x0AC)
+
+/* MAC SERDES Address Paging register */
+#define PLB0_EMS_ADD_REG (PLB0_BLK_REG_ADDR + 0xD0)
+#define PLB1_EMS_ADD_REG (PLB1_BLK_REG_ADDR + 0xD0)
+
+/* LL EMS Registers */
+#define LL_EMS0_BLK_REG_ADDR 0x00026800
+#define LL_EMS1_BLK_REG_ADDR 0x00026C00
+
+/**
+ * BPC Block Register Address Offset from BAR0
+ * BPC0 Range : 0x23000 - 0x233FF
+ * BPC1 Range : 0x23400 - 0x237FF
+ */
+#define BPC0_BLK_REG_ADDR 0x00023000
+#define BPC1_BLK_REG_ADDR 0x00023400
+
+/**
+ * PMM Block Register Address Offset from BAR0
+ * PMM0 Range : 0x23800 - 0x23BFF
+ * PMM1 Range : 0x23C00 - 0x23FFF
+ */
+#define PMM0_BLK_REG_ADDR 0x00023800
+#define PMM1_BLK_REG_ADDR 0x00023C00
+
+/**
+ * HQM Block Register Address Offset from BAR0
+ * HQM0 Range : 0x24000 - 0x243FF
+ * HQM1 Range : 0x24400 - 0x247FF
+ */
+#define HQM0_BLK_REG_ADDR 0x00024000
+#define HQM1_BLK_REG_ADDR 0x00024400
+
+/**
+ * HQM Control Register
+ * Controls some aspects of IB
+ * See catapult_spec.pdf for details
+ */
+#define HQM0_CTL_REG (HQM0_BLK_REG_ADDR + 0x000)
+#define HQM1_CTL_REG (HQM1_BLK_REG_ADDR + 0x000)
+
+/**
+ * HQM Stop Q Semaphore Registers.
+ * Only one Queue resource can be stopped at
+ * any given time. This register controls access
+ * to the single stop Q resource.
+ * See catapult_spec.pdf for details
+ */
+#define HQM0_RXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x028)
+#define HQM0_TXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x02C)
+#define HQM1_RXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x028)
+#define HQM1_TXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x02C)
+
+/**
+ * LUT Block Register Address Offset from BAR0
+ * LUT0 Range : 0x25800 - 0x25BFF
+ * LUT1 Range : 0x25C00 - 0x25FFF
+ */
+#define LUT0_BLK_REG_ADDR 0x00025800
+#define LUT1_BLK_REG_ADDR 0x00025C00
+
+/**
+ * LUT Registers
+ * See catapult_spec.pdf for details
+ */
+#define LUT0_ERR_STS (LUT0_BLK_REG_ADDR + 0x000)
+#define LUT1_ERR_STS (LUT1_BLK_REG_ADDR + 0x000)
+#define LUT0_SET_ERR_STS (LUT0_BLK_REG_ADDR + 0x004)
+#define LUT1_SET_ERR_STS (LUT1_BLK_REG_ADDR + 0x004)
+
+/**
+ * TRC (Debug/Trace) Register Offset from BAR0
+ * Range : 0x26000 -- 0x263FFF
+ */
+#define TRC_BLK_REG_ADDR 0x00026000
+
+/**
+ * TRC Registers
+ * See catapult_spec.pdf for details of each
+ */
+#define TRC_CTL_REG (TRC_BLK_REG_ADDR + 0x000)
+#define TRC_MODS_REG (TRC_BLK_REG_ADDR + 0x004)
+#define TRC_TRGC_REG (TRC_BLK_REG_ADDR + 0x008)
+#define TRC_CNT1_REG (TRC_BLK_REG_ADDR + 0x010)
+#define TRC_CNT2_REG (TRC_BLK_REG_ADDR + 0x014)
+#define TRC_NXTS_REG (TRC_BLK_REG_ADDR + 0x018)
+#define TRC_DIRR_REG (TRC_BLK_REG_ADDR + 0x01C)
+
+/**
+ * TRC Trigger match filters, total 10
+ * Determines the trigger condition
+ */
+#define TRC_TRGM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x040 + ((_num) << 2))
+
+/**
+ * TRC Next State filters, total 10
+ * Determines the next state conditions
+ */
+#define TRC_NXTM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x080 + ((_num) << 2))
+
+/**
+ * TRC Store Match filters, total 10
+ * Determines the store conditions
+ */
+#define TRC_STRM_REG(_num) \
+ (TRC_BLK_REG_ADDR + 0x0C0 + ((_num) << 2))
+
+/* DOORBELLS ACCESS */
+
+/**
+ * Catapult doorbells
+ * Each doorbell-queue set has
+ * 1 RxQ, 1 TxQ, 2 IBs in that order
+ * Size of each entry in 32 bytes, even though only 1 word
+ * is used. For Non-VM case each doorbell-q set is
+ * separated by 128 bytes, for VM case it is separated
+ * by 4K bytes
+ * Non VM case Range : 0x38000 - 0x39FFF
+ * VM case Range : 0x100000 - 0x11FFFF
+ * The range applies to both HQMs
+ */
+#define HQM_DOORBELL_BLK_BASE_ADDR 0x00038000
+#define HQM_DOORBELL_VM_BLK_BASE_ADDR 0x00100000
+
+/* MEMORY ACCESS */
+
+/**
+ * Catapult H/W Block Memory Access Address
+ * To the host a memory space of 32K (page) is visible
+ * at a time. The address range is from 0x08000 to 0x0FFFF
+ */
+#define HW_BLK_HOST_MEM_ADDR 0x08000
+
+/**
+ * Catapult LUT Memory Access Page Numbers
+ * Range : LUT0 0xa0-0xa1
+ * LUT1 0xa2-0xa3
+ */
+#define LUT0_MEM_BLK_BASE_PG_NUM 0x000000A0
+#define LUT1_MEM_BLK_BASE_PG_NUM 0x000000A2
+
+/**
+ * Catapult RxFn Database Memory Block Base Offset
+ *
+ * The Rx function database exists in LUT block.
+ * In PCIe space this is accessible as a 256x32
+ * bit block. Each entry in this database is 4
+ * (4 byte) words. Max. entries is 64.
+ * Address of an entry corresponding to a function
+ * = base_addr + (function_no. * 16)
+ */
+#define RX_FNDB_RAM_BASE_OFFSET 0x0000B400
+
+/**
+ * Catapult TxFn Database Memory Block Base Offset Address
+ *
+ * The Tx function database exists in LUT block.
+ * In PCIe space this is accessible as a 64x32
+ * bit block. Each entry in this database is 1
+ * (4 byte) word. Max. entries is 64.
+ * Address of an entry corresponding to a function
+ * = base_addr + (function_no. * 4)
+ */
+#define TX_FNDB_RAM_BASE_OFFSET 0x0000B800
+
+/**
+ * Catapult Unicast CAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x48 bits; mapped to PCIe space
+ * 512x32 bit blocks. For each address, bits
+ * are written in the order : [47:32] and then
+ * [31:0].
+ */
+#define UCAST_CAM_BASE_OFFSET 0x0000A800
+
+/**
+ * Catapult Unicast RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x9 bits.
+ */
+#define UCAST_RAM_BASE_OFFSET 0x0000B000
+
+/**
+ * Catapult Mulicast CAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Shared by both the LL & FCoE driver.
+ * Size is 256x48 bits; mapped to PCIe space
+ * 512x32 bit blocks. For each address, bits
+ * are written in the order : [47:32] and then
+ * [31:0].
+ */
+#define MCAST_CAM_BASE_OFFSET 0x0000A000
+
+/**
+ * Catapult VLAN RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 4096x66 bits; mapped to PCIe space as
+ * 8192x32 bit blocks.
+ * All the 4K entries are within the address range
+ * 0x0000 to 0x8000, so in the first LUT page.
+ */
+#define VLAN_RAM_BASE_OFFSET 0x00000000
+
+/**
+ * Catapult Tx Stats RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 1024x33 bits;
+ * Each Tx function has 64 bytes of space
+ */
+#define TX_STATS_RAM_BASE_OFFSET 0x00009000
+
+/**
+ * Catapult Rx Stats RAM Base Offset Address
+ *
+ * Exists in LUT memory space.
+ * Size is 1024x33 bits;
+ * Each Rx function has 64 bytes of space
+ */
+#define RX_STATS_RAM_BASE_OFFSET 0x00008000
+
+/* Catapult RXA Memory Access Page Numbers */
+#define RXA0_MEM_BLK_BASE_PG_NUM 0x0000008C
+#define RXA1_MEM_BLK_BASE_PG_NUM 0x0000008D
+
+/**
+ * Catapult Multicast Vector Table Base Offset Address
+ *
+ * Exists in RxA memory space.
+ * Organized as 512x65 bit block.
+ * However for each entry 16 bytes allocated (power of 2)
+ * Total size 512*16 bytes.
+ * There are two logical divisions, 256 entries each :
+ * a) Entries 0x00 to 0xff (256) -- Approx. MVT
+ * Offset 0x000 to 0xFFF
+ * b) Entries 0x100 to 0x1ff (256) -- Exact MVT
+ * Offsets 0x1000 to 0x1FFF
+ */
+#define MCAST_APPROX_MVT_BASE_OFFSET 0x00000000
+#define MCAST_EXACT_MVT_BASE_OFFSET 0x00001000
+
+/**
+ * Catapult RxQ Translate Table (RIT) Base Offset Address
+ *
+ * Exists in RxA memory space
+ * Total no. of entries 64
+ * Each entry is 1 (4 byte) word.
+ * 31:12 -- Reserved
+ * 11:0 -- Two 6 bit RxQ Ids
+ */
+#define FUNCTION_TO_RXQ_TRANSLATE 0x00002000
+
+/* Catapult RxAdm (RAD) Memory Access Page Numbers */
+#define RAD0_MEM_BLK_BASE_PG_NUM 0x00000086
+#define RAD1_MEM_BLK_BASE_PG_NUM 0x00000087
+
+/**
+ * Catapult RSS Table Base Offset Address
+ *
+ * Exists in RAD memory space.
+ * Each entry is 352 bits, but alligned on
+ * 64 byte (512 bit) boundary. Accessed
+ * 4 byte words, the whole entry can be
+ * broken into 11 word accesses.
+ */
+#define RSS_TABLE_BASE_OFFSET 0x00000800
+
+/**
+ * Catapult CPQ Block Page Number
+ * This value is written to the page number registers
+ * to access the memory associated with the mailboxes.
+ */
+#define CPQ_BLK_PG_NUM 0x00000005
+
+/**
+ * Clarification :
+ * LL functions are 2 & 3; can HostFn0/HostFn1
+ * <-> LPU0/LPU1 memories be used ?
+ */
+/**
+ * Catapult HostFn0/HostFn1 to LPU0/LPU1 Mbox memory
+ * Per catapult_spec.pdf, the offset of the mbox
+ * memory is in the register space at an offset of 0x200
+ */
+#define CPQ_BLK_REG_MBOX_ADDR (CPQ_BLK_REG_ADDR + 0x200)
+
+#define HOSTFN_LPU_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x000)
+
+/* Catapult LPU0/LPU1 to HostFn0/HostFn1 Mbox memory */
+#define LPU_HOSTFN_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x080)
+
+/**
+ * Catapult HQM Block Page Number
+ * This is written to the page number register for
+ * the appropriate function to access the memory
+ * associated with HQM
+ */
+#define HQM0_BLK_PG_NUM 0x00000096
+#define HQM1_BLK_PG_NUM 0x00000097
+
+/**
+ * Note that TxQ and RxQ entries are interlaced
+ * the HQM memory, i.e RXQ0, TXQ0, RXQ1, TXQ1.. etc.
+ */
+
+#define HQM_RXTX_Q_RAM_BASE_OFFSET 0x00004000
+
+/**
+ * CQ Memory
+ * Exists in HQM Memory space
+ * Each entry is 16 (4 byte) words of which
+ * only 12 words are used for configuration
+ * Total 64 entries per HQM memory space
+ */
+#define HQM_CQ_RAM_BASE_OFFSET 0x00006000
+
+/**
+ * Interrupt Block (IB) Memory
+ * Exists in HQM Memory space
+ * Each entry is 8 (4 byte) words of which
+ * only 5 words are used for configuration
+ * Total 128 entries per HQM memory space
+ */
+#define HQM_IB_RAM_BASE_OFFSET 0x00001000
+
+/**
+ * Index Table (IT) Memory
+ * Exists in HQM Memory space
+ * Each entry is 1 (4 byte) word which
+ * is used for configuration
+ * Total 128 entries per HQM memory space
+ */
+#define HQM_INDX_TBL_RAM_BASE_OFFSET 0x00002000
+
+/**
+ * PSS Block Memory Page Number
+ * This is written to the appropriate page number
+ * register to access the CPU memory.
+ * Also known as the PSS secondary memory (SMEM).
+ * Range : 0x180 to 0x1CF
+ * See catapult_spec.pdf for details
+ */
+#define PSS_BLK_PG_NUM 0x00000180
+
+/**
+ * Offsets of different instances of PSS SMEM
+ * 2.5M of continuous 1T memory space : 2 blocks
+ * of 1M each (32 pages each, page=32KB) and 4 smaller
+ * blocks of 128K each (4 pages each, page=32KB)
+ * PSS_LMEM_INST0 is used for firmware download
+ */
+#define PSS_LMEM_INST0 0x00000000
+#define PSS_LMEM_INST1 0x00100000
+#define PSS_LMEM_INST2 0x00200000
+#define PSS_LMEM_INST3 0x00220000
+#define PSS_LMEM_INST4 0x00240000
+#define PSS_LMEM_INST5 0x00260000
+
+#define BNA_PCI_REG_CT_ADDRSZ (0x40000)
+
+#define BNA_GET_PAGE_NUM(_base_page, _offset) \
+ ((_base_page) + ((_offset) >> 15))
+
+#define BNA_GET_PAGE_OFFSET(_offset) \
+ ((_offset) & 0x7fff)
+
+#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset) \
+ ((_bar0) + HW_BLK_HOST_MEM_ADDR \
+ + BNA_GET_PAGE_OFFSET((_base_offset)))
+
+#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\
+ (_bar0 + (HW_BLK_HOST_MEM_ADDR) \
+ + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET)) \
+ + (((_fn_id) & 0x3f) << 9) \
+ + (((_vlan_id) & 0xfe0) >> 3))
+
+/**
+ *
+ * Interrupt related bits, flags and macros
+ *
+ */
+
+#define __LPU02HOST_MBOX0_STATUS_BITS 0x00100000
+#define __LPU12HOST_MBOX0_STATUS_BITS 0x00200000
+#define __LPU02HOST_MBOX1_STATUS_BITS 0x00400000
+#define __LPU12HOST_MBOX1_STATUS_BITS 0x00800000
+
+#define __LPU02HOST_MBOX0_MASK_BITS 0x00100000
+#define __LPU12HOST_MBOX0_MASK_BITS 0x00200000
+#define __LPU02HOST_MBOX1_MASK_BITS 0x00400000
+#define __LPU12HOST_MBOX1_MASK_BITS 0x00800000
+
+#define __LPU2HOST_MBOX_MASK_BITS \
+ (__LPU02HOST_MBOX0_MASK_BITS | __LPU02HOST_MBOX1_MASK_BITS | \
+ __LPU12HOST_MBOX0_MASK_BITS | __LPU12HOST_MBOX1_MASK_BITS)
+
+#define __LPU2HOST_IB_STATUS_BITS 0x0000ffff
+
+#define BNA_IS_LPU0_MBOX_INTR(_intr_status) \
+ ((_intr_status) & (__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS))
+
+#define BNA_IS_LPU1_MBOX_INTR(_intr_status) \
+ ((_intr_status) & (__LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS))
+
+#define BNA_IS_MBOX_INTR(_intr_status) \
+ ((_intr_status) & \
+ (__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS | \
+ __LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS))
+
+#define __EMC_ERROR_STATUS_BITS 0x00010000
+#define __LPU0_ERROR_STATUS_BITS 0x00020000
+#define __LPU1_ERROR_STATUS_BITS 0x00040000
+#define __PSS_ERROR_STATUS_BITS 0x00080000
+
+#define __HALT_STATUS_BITS 0x01000000
+
+#define __EMC_ERROR_MASK_BITS 0x00010000
+#define __LPU0_ERROR_MASK_BITS 0x00020000
+#define __LPU1_ERROR_MASK_BITS 0x00040000
+#define __PSS_ERROR_MASK_BITS 0x00080000
+
+#define __HALT_MASK_BITS 0x01000000
+
+#define __ERROR_MASK_BITS \
+ (__EMC_ERROR_MASK_BITS | __LPU0_ERROR_MASK_BITS | \
+ __LPU1_ERROR_MASK_BITS | __PSS_ERROR_MASK_BITS | \
+ __HALT_MASK_BITS)
+
+#define BNA_IS_ERR_INTR(_intr_status) \
+ ((_intr_status) & \
+ (__EMC_ERROR_STATUS_BITS | \
+ __LPU0_ERROR_STATUS_BITS | \
+ __LPU1_ERROR_STATUS_BITS | \
+ __PSS_ERROR_STATUS_BITS | \
+ __HALT_STATUS_BITS))
+
+#define BNA_IS_MBOX_ERR_INTR(_intr_status) \
+ (BNA_IS_MBOX_INTR((_intr_status)) | \
+ BNA_IS_ERR_INTR((_intr_status)))
+
+#define BNA_IS_INTX_DATA_INTR(_intr_status) \
+ ((_intr_status) & __LPU2HOST_IB_STATUS_BITS)
+
+#define BNA_INTR_STATUS_MBOX_CLR(_intr_status) \
+do { \
+ (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS | \
+ __LPU02HOST_MBOX1_STATUS_BITS | \
+ __LPU12HOST_MBOX0_STATUS_BITS | \
+ __LPU12HOST_MBOX1_STATUS_BITS); \
+} while (0)
+
+#define BNA_INTR_STATUS_ERR_CLR(_intr_status) \
+do { \
+ (_intr_status) &= ~(__EMC_ERROR_STATUS_BITS | \
+ __LPU0_ERROR_STATUS_BITS | \
+ __LPU1_ERROR_STATUS_BITS | \
+ __PSS_ERROR_STATUS_BITS | \
+ __HALT_STATUS_BITS); \
+} while (0)
+
+#define bna_intx_disable(_bna, _cur_mask) \
+{ \
+ (_cur_mask) = readl((_bna)->regs.fn_int_mask);\
+ writel(0xffffffff, (_bna)->regs.fn_int_mask);\
+}
+
+#define bna_intx_enable(bna, new_mask) \
+ writel((new_mask), (bna)->regs.fn_int_mask)
+
+#define bna_mbox_intr_disable(bna) \
+ writel((readl((bna)->regs.fn_int_mask) | \
+ (__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_mbox_intr_enable(bna) \
+ writel((readl((bna)->regs.fn_int_mask) & \
+ ~(__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_intr_status_get(_bna, _status) \
+{ \
+ (_status) = readl((_bna)->regs.fn_int_status); \
+ if ((_status)) { \
+ writel((_status) & ~(__LPU02HOST_MBOX0_STATUS_BITS |\
+ __LPU02HOST_MBOX1_STATUS_BITS |\
+ __LPU12HOST_MBOX0_STATUS_BITS |\
+ __LPU12HOST_MBOX1_STATUS_BITS), \
+ (_bna)->regs.fn_int_status);\
+ } \
+}
+
+#define bna_intr_status_get_no_clr(_bna, _status) \
+ (_status) = readl((_bna)->regs.fn_int_status)
+
+#define bna_intr_mask_get(bna, mask) \
+ (*mask) = readl((bna)->regs.fn_int_mask)
+
+#define bna_intr_ack(bna, intr_bmap) \
+ writel((intr_bmap), (bna)->regs.fn_int_status)
+
+#define bna_ib_intx_disable(bna, ib_id) \
+ writel(readl((bna)->regs.fn_int_mask) | \
+ (1 << (ib_id)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_ib_intx_enable(bna, ib_id) \
+ writel(readl((bna)->regs.fn_int_mask) & \
+ ~(1 << (ib_id)), \
+ (bna)->regs.fn_int_mask)
+
+#define bna_mbox_msix_idx_set(_device) \
+do {\
+ writel(((_device)->vector & 0x000001FF), \
+ (_device)->bna->pcidev.pci_bar_kva + \
+ reg_offset[(_device)->bna->pcidev.pci_func].msix_idx);\
+} while (0)
+
+/**
+ *
+ * TxQ, RxQ, CQ related bits, offsets, macros
+ *
+ */
+
+#define BNA_Q_IDLE_STATE 0x00008001
+
+#define BNA_GET_DOORBELL_BASE_ADDR(_bar0) \
+ ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR)
+
+#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry) \
+ ((HQM_DOORBELL_BLK_BASE_ADDR) \
+ + (_entry << 7))
+
+#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
+ (0x80000000 | ((_timeout) << 16) | (_events))
+
+#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000)
+
+/* TxQ Entry Opcodes */
+#define BNA_TXQ_WI_SEND (0x402) /* Single Frame Transmission */
+#define BNA_TXQ_WI_SEND_LSO (0x403) /* Multi-Frame Transmission */
+#define BNA_TXQ_WI_EXTENSION (0x104) /* Extension WI */
+
+/* TxQ Entry Control Flags */
+#define BNA_TXQ_WI_CF_FCOE_CRC (1 << 8)
+#define BNA_TXQ_WI_CF_IPID_MODE (1 << 5)
+#define BNA_TXQ_WI_CF_INS_PRIO (1 << 4)
+#define BNA_TXQ_WI_CF_INS_VLAN (1 << 3)
+#define BNA_TXQ_WI_CF_UDP_CKSUM (1 << 2)
+#define BNA_TXQ_WI_CF_TCP_CKSUM (1 << 1)
+#define BNA_TXQ_WI_CF_IP_CKSUM (1 << 0)
+
+#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
+ (((_hdr_size) << 10) | ((_offset) & 0x3FF))
+
+/*
+ * Completion Q defines
+ */
+/* CQ Entry Flags */
+#define BNA_CQ_EF_MAC_ERROR (1 << 0)
+#define BNA_CQ_EF_FCS_ERROR (1 << 1)
+#define BNA_CQ_EF_TOO_LONG (1 << 2)
+#define BNA_CQ_EF_FC_CRC_OK (1 << 3)
+
+#define BNA_CQ_EF_RSVD1 (1 << 4)
+#define BNA_CQ_EF_L4_CKSUM_OK (1 << 5)
+#define BNA_CQ_EF_L3_CKSUM_OK (1 << 6)
+#define BNA_CQ_EF_HDS_HEADER (1 << 7)
+
+#define BNA_CQ_EF_UDP (1 << 8)
+#define BNA_CQ_EF_TCP (1 << 9)
+#define BNA_CQ_EF_IP_OPTIONS (1 << 10)
+#define BNA_CQ_EF_IPV6 (1 << 11)
+
+#define BNA_CQ_EF_IPV4 (1 << 12)
+#define BNA_CQ_EF_VLAN (1 << 13)
+#define BNA_CQ_EF_RSS (1 << 14)
+#define BNA_CQ_EF_RSVD2 (1 << 15)
+
+#define BNA_CQ_EF_MCAST_MATCH (1 << 16)
+#define BNA_CQ_EF_MCAST (1 << 17)
+#define BNA_CQ_EF_BCAST (1 << 18)
+#define BNA_CQ_EF_REMOTE (1 << 19)
+
+#define BNA_CQ_EF_LOCAL (1 << 20)
+
+/**
+ *
+ * Data structures
+ *
+ */
+
+enum txf_flags {
+ BFI_TXF_CF_ENABLE = 1 << 0,
+ BFI_TXF_CF_VLAN_FILTER = 1 << 8,
+ BFI_TXF_CF_VLAN_ADMIT = 1 << 9,
+ BFI_TXF_CF_VLAN_INSERT = 1 << 10,
+ BFI_TXF_CF_RSVD1 = 1 << 11,
+ BFI_TXF_CF_MAC_SA_CHECK = 1 << 12,
+ BFI_TXF_CF_VLAN_WI_BASED = 1 << 13,
+ BFI_TXF_CF_VSWITCH_MCAST = 1 << 14,
+ BFI_TXF_CF_VSWITCH_UCAST = 1 << 15,
+ BFI_TXF_CF_RSVD2 = 0x7F << 1
+};
+
+enum ib_flags {
+ BFI_IB_CF_MASTER_ENABLE = (1 << 0),
+ BFI_IB_CF_MSIX_MODE = (1 << 1),
+ BFI_IB_CF_COALESCING_MODE = (1 << 2),
+ BFI_IB_CF_INTER_PKT_ENABLE = (1 << 3),
+ BFI_IB_CF_INT_ENABLE = (1 << 4),
+ BFI_IB_CF_INTER_PKT_DMA = (1 << 5),
+ BFI_IB_CF_ACK_PENDING = (1 << 6),
+ BFI_IB_CF_RESERVED1 = (1 << 7)
+};
+
+enum rss_hash_type {
+ BFI_RSS_T_V4_TCP = (1 << 11),
+ BFI_RSS_T_V4_IP = (1 << 10),
+ BFI_RSS_T_V6_TCP = (1 << 9),
+ BFI_RSS_T_V6_IP = (1 << 8)
+};
+enum hds_header_type {
+ BNA_HDS_T_V4_TCP = (1 << 11),
+ BNA_HDS_T_V4_UDP = (1 << 10),
+ BNA_HDS_T_V6_TCP = (1 << 9),
+ BNA_HDS_T_V6_UDP = (1 << 8),
+ BNA_HDS_FORCED = (1 << 7),
+};
+enum rxf_flags {
+ BNA_RXF_CF_SM_LG_RXQ = (1 << 15),
+ BNA_RXF_CF_DEFAULT_VLAN = (1 << 14),
+ BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE = (1 << 13),
+ BNA_RXF_CF_VLAN_STRIP = (1 << 12),
+ BNA_RXF_CF_RSS_ENABLE = (1 << 8)
+};
+struct bna_chip_regs_offset {
+ u32 page_addr;
+ u32 fn_int_status;
+ u32 fn_int_mask;
+ u32 msix_idx;
+};
+extern const struct bna_chip_regs_offset reg_offset[];
+
+struct bna_chip_regs {
+ void __iomem *page_addr;
+ void __iomem *fn_int_status;
+ void __iomem *fn_int_mask;
+};
+
+struct bna_txq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */
+ /* 23:16->Int Blk Offset */
+ /* 15:0 ->consumer pointer(index?) */
+ u32 cns_ptr2_n_q_state; /* 31:16->cons. ptr 2; 15:0-> Q state */
+ u32 nxt_qid_n_fid_n_pri; /* 17:10->next */
+ /* QId;9:3->FID;2:0->Priority */
+ u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count; */
+ /* 23:12->Cfg Quota; */
+ /* 11:0 ->Run Quota */
+ u32 reserved3[4];
+};
+
+struct bna_rxq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 sg_n_cq_n_cns_ptr; /* 31:28->reserved; 27:24->sg count */
+ /* 23:16->CQ; */
+ /* 15:0->consumer pointer(index?) */
+ u32 buf_sz_n_q_state; /* 31:16->buffer size; 15:0-> Q state */
+ u32 next_qid; /* 17:10->next QId */
+ u32 reserved3;
+ u32 reserved4[4];
+};
+
+struct bna_rxtx_q_mem {
+ struct bna_rxq_mem rxq;
+ struct bna_txq_mem txq;
+};
+
+struct bna_cq_mem {
+ u32 pg_tbl_addr_lo;
+ u32 pg_tbl_addr_hi;
+ u32 cur_q_entry_lo;
+ u32 cur_q_entry_hi;
+
+ u32 reserved1;
+ u32 reserved2;
+ u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */
+ /* 15:0 ->producer pointer (index?) */
+ u32 entry_n_pg_size; /* 31:16->entry size */
+ /* 15:0 ->page size */
+ u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */
+ /* 23:16->Int Blk Offset */
+ /* 15:0 ->consumer pointer(index?) */
+ u32 q_state; /* 31:16->reserved; 15:0-> Q state */
+ u32 reserved3[2];
+ u32 reserved4[4];
+};
+
+struct bna_ib_blk_mem {
+ u32 host_addr_lo;
+ u32 host_addr_hi;
+ u32 clsc_n_ctrl_n_msix; /* 31:24->coalescing; */
+ /* 23:16->coalescing cfg; */
+ /* 15:8 ->control; */
+ /* 7:0 ->msix; */
+ u32 ipkt_n_ent_n_idxof;
+ u32 ipkt_cnt_cfg_n_unacked;
+
+ u32 reserved[3];
+};
+
+struct bna_idx_tbl_mem {
+ u32 idx; /* !< 31:16->res;15:0->idx; */
+};
+
+struct bna_doorbell_qset {
+ u32 rxq[0x20 >> 2];
+ u32 txq[0x20 >> 2];
+ u32 ib0[0x20 >> 2];
+ u32 ib1[0x20 >> 2];
+};
+
+struct bna_rx_fndb_ram {
+ u32 rss_prop;
+ u32 size_routing_props;
+ u32 rit_hds_mcastq;
+ u32 control_flags;
+};
+
+struct bna_tx_fndb_ram {
+ u32 vlan_n_ctrl_flags;
+};
+
+/**
+ * @brief
+ * Structure which maps to RxFn Indirection Table (RIT)
+ * Size : 1 word
+ * See catapult_spec.pdf, RxA for details
+ */
+struct bna_rit_mem {
+ u32 rxq_ids; /* !< 31:12->res;11:0->two 6 bit RxQ Ids */
+};
+
+/**
+ * @brief
+ * Structure which maps to RSS Table entry
+ * Size : 16 words
+ * See catapult_spec.pdf, RAD for details
+ */
+struct bna_rss_mem {
+ /*
+ * 31:12-> res
+ * 11:8 -> protocol type
+ * 7:0 -> hash index
+ */
+ u32 type_n_hash;
+ u32 hash_key[10]; /* !< 40 byte Toeplitz hash key */
+ u32 reserved[5];
+};
+
+/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */
+struct bna_dma_addr {
+ u32 msb;
+ u32 lsb;
+};
+
+struct bna_txq_wi_vector {
+ u16 reserved;
+ u16 length; /* Only 14 LSB are valid */
+ struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */
+};
+
+typedef u16 bna_txq_wi_opcode_t;
+
+typedef u16 bna_txq_wi_ctrl_flag_t;
+
+/**
+ * TxQ Entry Structure
+ *
+ * BEWARE: Load values into this structure with correct endianess.
+ */
+struct bna_txq_entry {
+ union {
+ struct {
+ u8 reserved;
+ u8 num_vectors; /* number of vectors present */
+ bna_txq_wi_opcode_t opcode; /* Either */
+ /* BNA_TXQ_WI_SEND or */
+ /* BNA_TXQ_WI_SEND_LSO */
+ bna_txq_wi_ctrl_flag_t flags; /* OR of all the flags */
+ u16 l4_hdr_size_n_offset;
+ u16 vlan_tag;
+ u16 lso_mss; /* Only 14 LSB are valid */
+ u32 frame_length; /* Only 24 LSB are valid */
+ } wi;
+
+ struct {
+ u16 reserved;
+ bna_txq_wi_opcode_t opcode; /* Must be */
+ /* BNA_TXQ_WI_EXTENSION */
+ u32 reserved2[3]; /* Place holder for */
+ /* removed vector (12 bytes) */
+ } wi_ext;
+ } hdr;
+ struct bna_txq_wi_vector vector[4];
+};
+#define wi_hdr hdr.wi
+#define wi_ext_hdr hdr.wi_ext
+
+/* RxQ Entry Structure */
+struct bna_rxq_entry { /* Rx-Buffer */
+ struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */
+};
+
+typedef u32 bna_cq_e_flag_t;
+
+/* CQ Entry Structure */
+struct bna_cq_entry {
+ bna_cq_e_flag_t flags;
+ u16 vlan_tag;
+ u16 length;
+ u32 rss_hash;
+ u8 valid;
+ u8 reserved1;
+ u8 reserved2;
+ u8 rxq_id;
+};
+
+#endif /* __BNA_HW_H__ */
diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c
new file mode 100644
index 000000000000..890846d55502
--- /dev/null
+++ b/drivers/net/bna/bna_txrx.c
@@ -0,0 +1,4209 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include "bna.h"
+#include "bfa_sm.h"
+#include "bfi.h"
+
+/**
+ * IB
+ */
+#define bna_ib_find_free_ibidx(_mask, _pos)\
+do {\
+ (_pos) = 0;\
+ while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\
+ ((1 << (_pos)) & (_mask)))\
+ (_pos)++;\
+} while (0)
+
+#define bna_ib_count_ibidx(_mask, _count)\
+do {\
+ int pos = 0;\
+ (_count) = 0;\
+ while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\
+ if ((1 << pos) & (_mask))\
+ (_count) = pos + 1;\
+ pos++;\
+ } \
+} while (0)
+
+#define bna_ib_select_segpool(_count, _q_idx)\
+do {\
+ int i;\
+ (_q_idx) = -1;\
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\
+ if ((_count <= ibidx_pool[i].pool_entry_size)) {\
+ (_q_idx) = i;\
+ break;\
+ } \
+ } \
+} while (0)
+
+struct bna_ibidx_pool {
+ int pool_size;
+ int pool_entry_size;
+};
+init_ibidx_pool(ibidx_pool);
+
+static struct bna_intr *
+bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type,
+ int vector)
+{
+ struct bna_intr *intr;
+ struct list_head *qe;
+
+ list_for_each(qe, &ib_mod->intr_active_q) {
+ intr = (struct bna_intr *)qe;
+
+ if ((intr->intr_type == intr_type) &&
+ (intr->vector == vector)) {
+ intr->ref_count++;
+ return intr;
+ }
+ }
+
+ if (list_empty(&ib_mod->intr_free_q))
+ return NULL;
+
+ bfa_q_deq(&ib_mod->intr_free_q, &intr);
+ bfa_q_qe_init(&intr->qe);
+
+ intr->ref_count = 1;
+ intr->intr_type = intr_type;
+ intr->vector = vector;
+
+ list_add_tail(&intr->qe, &ib_mod->intr_active_q);
+
+ return intr;
+}
+
+static void
+bna_intr_put(struct bna_ib_mod *ib_mod,
+ struct bna_intr *intr)
+{
+ intr->ref_count--;
+
+ if (intr->ref_count == 0) {
+ intr->ib = NULL;
+ list_del(&intr->qe);
+ bfa_q_qe_init(&intr->qe);
+ list_add_tail(&intr->qe, &ib_mod->intr_free_q);
+ }
+}
+
+void
+bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+ int j;
+ int count;
+ u8 offset;
+ struct bna_doorbell_qset *qset;
+ unsigned long off;
+
+ ib_mod->bna = bna;
+
+ ib_mod->ib = (struct bna_ib *)
+ res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva;
+ ib_mod->intr = (struct bna_intr *)
+ res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva;
+ ib_mod->idx_seg = (struct bna_ibidx_seg *)
+ res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&ib_mod->ib_free_q);
+ INIT_LIST_HEAD(&ib_mod->intr_free_q);
+ INIT_LIST_HEAD(&ib_mod->intr_active_q);
+
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++)
+ INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]);
+
+ for (i = 0; i < BFI_MAX_IB; i++) {
+ ib_mod->ib[i].ib_id = i;
+
+ ib_mod->ib[i].ib_seg_host_addr_kva =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
+ ib_mod->ib[i].ib_seg_host_addr.lsb =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
+ ib_mod->ib[i].ib_seg_host_addr.msb =
+ res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
+
+ qset = (struct bna_doorbell_qset *)0;
+ off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1)
+ * (0x20 >> 2)]);
+ ib_mod->ib[i].door_bell.doorbell_addr = off +
+ BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
+
+ bfa_q_qe_init(&ib_mod->ib[i].qe);
+ list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q);
+
+ bfa_q_qe_init(&ib_mod->intr[i].qe);
+ list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q);
+ }
+
+ count = 0;
+ offset = 0;
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
+ for (j = 0; j < ibidx_pool[i].pool_size; j++) {
+ bfa_q_qe_init(&ib_mod->idx_seg[count]);
+ ib_mod->idx_seg[count].ib_seg_size =
+ ibidx_pool[i].pool_entry_size;
+ ib_mod->idx_seg[count].ib_idx_tbl_offset = offset;
+ list_add_tail(&ib_mod->idx_seg[count].qe,
+ &ib_mod->ibidx_seg_pool[i]);
+ count++;
+ offset += ibidx_pool[i].pool_entry_size;
+ }
+ }
+}
+
+void
+bna_ib_mod_uninit(struct bna_ib_mod *ib_mod)
+{
+ int i;
+ int j;
+ struct list_head *qe;
+
+ i = 0;
+ list_for_each(qe, &ib_mod->ib_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &ib_mod->intr_free_q)
+ i++;
+
+ for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
+ j = 0;
+ list_for_each(qe, &ib_mod->ibidx_seg_pool[i])
+ j++;
+ }
+
+ ib_mod->bna = NULL;
+}
+
+struct bna_ib *
+bna_ib_get(struct bna_ib_mod *ib_mod,
+ enum bna_intr_type intr_type,
+ int vector)
+{
+ struct bna_ib *ib;
+ struct bna_intr *intr;
+
+ if (intr_type == BNA_INTR_T_INTX)
+ vector = (1 << vector);
+
+ intr = bna_intr_get(ib_mod, intr_type, vector);
+ if (intr == NULL)
+ return NULL;
+
+ if (intr->ib) {
+ if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) {
+ bna_intr_put(ib_mod, intr);
+ return NULL;
+ }
+ intr->ib->ref_count++;
+ return intr->ib;
+ }
+
+ if (list_empty(&ib_mod->ib_free_q)) {
+ bna_intr_put(ib_mod, intr);
+ return NULL;
+ }
+
+ bfa_q_deq(&ib_mod->ib_free_q, &ib);
+ bfa_q_qe_init(&ib->qe);
+
+ ib->ref_count = 1;
+ ib->start_count = 0;
+ ib->idx_mask = 0;
+
+ ib->intr = intr;
+ ib->idx_seg = NULL;
+ intr->ib = ib;
+
+ ib->bna = ib_mod->bna;
+
+ return ib;
+}
+
+void
+bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib)
+{
+ bna_intr_put(ib_mod, ib->intr);
+
+ ib->ref_count--;
+
+ if (ib->ref_count == 0) {
+ ib->intr = NULL;
+ ib->bna = NULL;
+ list_add_tail(&ib->qe, &ib_mod->ib_free_q);
+ }
+}
+
+/* Returns index offset - starting from 0 */
+int
+bna_ib_reserve_idx(struct bna_ib *ib)
+{
+ struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
+ struct bna_ibidx_seg *idx_seg;
+ int idx;
+ int num_idx;
+ int q_idx;
+
+ /* Find the first free index position */
+ bna_ib_find_free_ibidx(ib->idx_mask, idx);
+ if (idx == BFI_IBIDX_MAX_SEGSIZE)
+ return -1;
+
+ /*
+ * Calculate the total number of indexes held by this IB,
+ * including the index newly reserved above.
+ */
+ bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx);
+
+ /* See if there is a free space in the index segment held by this IB */
+ if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) {
+ ib->idx_mask |= (1 << idx);
+ return idx;
+ }
+
+ if (ib->start_count)
+ return -1;
+
+ /* Allocate a new segment */
+ bna_ib_select_segpool(num_idx, q_idx);
+ while (1) {
+ if (q_idx == BFI_IBIDX_TOTAL_POOLS)
+ return -1;
+ if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx]))
+ break;
+ q_idx++;
+ }
+ bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg);
+ bfa_q_qe_init(&idx_seg->qe);
+
+ /* Free the old segment */
+ if (ib->idx_seg) {
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx);
+ list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]);
+ }
+
+ ib->idx_seg = idx_seg;
+
+ ib->idx_mask |= (1 << idx);
+
+ return idx;
+}
+
+void
+bna_ib_release_idx(struct bna_ib *ib, int idx)
+{
+ struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
+ struct bna_ibidx_seg *idx_seg;
+ int num_idx;
+ int cur_q_idx;
+ int new_q_idx;
+
+ ib->idx_mask &= ~(1 << idx);
+
+ if (ib->start_count)
+ return;
+
+ bna_ib_count_ibidx(ib->idx_mask, num_idx);
+
+ /*
+ * Free the segment, if there are no more indexes in the segment
+ * held by this IB
+ */
+ if (!num_idx) {
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
+ list_add_tail(&ib->idx_seg->qe,
+ &ib_mod->ibidx_seg_pool[cur_q_idx]);
+ ib->idx_seg = NULL;
+ return;
+ }
+
+ /* See if we can move to a smaller segment */
+ bna_ib_select_segpool(num_idx, new_q_idx);
+ bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
+ while (new_q_idx < cur_q_idx) {
+ if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx]))
+ break;
+ new_q_idx++;
+ }
+ if (new_q_idx < cur_q_idx) {
+ /* Select the new smaller segment */
+ bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg);
+ bfa_q_qe_init(&idx_seg->qe);
+ /* Free the old segment */
+ list_add_tail(&ib->idx_seg->qe,
+ &ib_mod->ibidx_seg_pool[cur_q_idx]);
+ ib->idx_seg = idx_seg;
+ }
+}
+
+int
+bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config)
+{
+ if (ib->start_count)
+ return -1;
+
+ ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo;
+ ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo;
+ ib->ib_config.interpkt_count = ib_config->interpkt_count;
+ ib->ib_config.ctrl_flags = ib_config->ctrl_flags;
+
+ ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE;
+ if (ib->intr->intr_type == BNA_INTR_T_MSIX)
+ ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE;
+
+ return 0;
+}
+
+void
+bna_ib_start(struct bna_ib *ib)
+{
+ struct bna_ib_blk_mem ib_cfg;
+ struct bna_ib_blk_mem *ib_mem;
+ u32 pg_num;
+ u32 intx_mask;
+ int i;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ ib->start_count++;
+
+ if (ib->start_count > 1)
+ return;
+
+ ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb);
+ ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb);
+
+ ib_cfg.clsc_n_ctrl_n_msix = (((u32)
+ ib->ib_config.coalescing_timeo << 16) |
+ ((u32)ib->ib_config.ctrl_flags << 8) |
+ (ib->intr->vector));
+ ib_cfg.ipkt_n_ent_n_idxof =
+ ((u32)
+ (ib->ib_config.interpkt_timeo & 0xf) << 16) |
+ ((u32)ib->idx_seg->ib_seg_size << 8) |
+ (ib->idx_seg->ib_idx_tbl_offset);
+ ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32)
+ ib->ib_config.interpkt_count << 24);
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
+ HQM_IB_RAM_BASE_OFFSET);
+ writel(pg_num, ib->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
+ HQM_IB_RAM_BASE_OFFSET);
+
+ ib_mem = (struct bna_ib_blk_mem *)0;
+ off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo;
+ writel(htonl(ib_cfg.host_addr_lo), base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi;
+ writel(htonl(ib_cfg.host_addr_hi), base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix;
+ writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof;
+ writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off);
+
+ off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked;
+ writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off);
+
+ ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
+ (u32)ib->ib_config.coalescing_timeo, 0);
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
+ HQM_INDX_TBL_RAM_BASE_OFFSET);
+ writel(pg_num, ib->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
+ HQM_INDX_TBL_RAM_BASE_OFFSET);
+ for (i = 0; i < ib->idx_seg->ib_seg_size; i++) {
+ off = (unsigned long)
+ ((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE);
+ writel(0, base_addr + off);
+ }
+
+ if (ib->intr->intr_type == BNA_INTR_T_INTX) {
+ bna_intx_disable(ib->bna, intx_mask);
+ intx_mask &= ~(ib->intr->vector);
+ bna_intx_enable(ib->bna, intx_mask);
+ }
+}
+
+void
+bna_ib_stop(struct bna_ib *ib)
+{
+ u32 intx_mask;
+
+ ib->start_count--;
+
+ if (ib->start_count == 0) {
+ writel(BNA_DOORBELL_IB_INT_DISABLE,
+ ib->door_bell.doorbell_addr);
+ if (ib->intr->intr_type == BNA_INTR_T_INTX) {
+ bna_intx_disable(ib->bna, intx_mask);
+ intx_mask |= (ib->intr->vector);
+ bna_intx_enable(ib->bna, intx_mask);
+ }
+ }
+}
+
+void
+bna_ib_fail(struct bna_ib *ib)
+{
+ ib->start_count = 0;
+}
+
+/**
+ * RXF
+ */
+static void rxf_enable(struct bna_rxf *rxf);
+static void rxf_disable(struct bna_rxf *rxf);
+static void __rxf_config_set(struct bna_rxf *rxf);
+static void __rxf_rit_set(struct bna_rxf *rxf);
+static void __bna_rxf_stat_clr(struct bna_rxf *rxf);
+static int rxf_process_packet_filter(struct bna_rxf *rxf);
+static int rxf_clear_packet_filter(struct bna_rxf *rxf);
+static void rxf_reset_packet_filter(struct bna_rxf *rxf);
+static void rxf_cb_enabled(void *arg, int status);
+static void rxf_cb_disabled(void *arg, int status);
+static void bna_rxf_cb_stats_cleared(void *arg, int status);
+static void __rxf_enable(struct bna_rxf *rxf);
+static void __rxf_disable(struct bna_rxf *rxf);
+
+bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf,
+ enum bna_rxf_event);
+bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf,
+ enum bna_rxf_event);
+
+static struct bfa_sm_table rxf_sm_table[] = {
+ {BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED},
+ {BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT},
+ {BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT},
+ {BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED},
+ {BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT},
+ {BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT},
+ {BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT},
+ {BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT},
+ {BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT}
+};
+
+static void
+bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
+{
+ call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS);
+}
+
+static void
+bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_START:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait);
+ break;
+
+ case RXF_E_STOP:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_FAIL:
+ /* No-op */
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ case RXF_E_STARTED:
+ case RXF_E_STOPPED:
+ case RXF_E_CAM_FLTR_RESP:
+ /**
+ * These events are received due to flushing of mbox
+ * when device fails
+ */
+ /* No-op */
+ break;
+
+ case RXF_E_PAUSE:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ case RXF_E_RESUME:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf)
+{
+ __rxf_config_set(rxf);
+ __rxf_rit_set(rxf);
+ rxf_enable(rxf);
+}
+
+static void
+bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ /**
+ * STOP is originated from bnad. When this happens,
+ * it can not be waiting for filter update
+ */
+ call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
+ break;
+
+ case RXF_E_FAIL:
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ /* No-op */
+ break;
+
+ case RXF_E_STARTED:
+ /**
+ * Force rxf_process_filter() to go through initial
+ * config
+ */
+ if ((rxf->ucast_active_mac != NULL) &&
+ (rxf->ucast_pending_set == 0))
+ rxf->ucast_pending_set = 1;
+
+ if (rxf->rss_status == BNA_STATUS_T_ENABLED)
+ rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;
+
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ case RXF_E_RESUME:
+ rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf)
+{
+ if (!rxf_process_packet_filter(rxf)) {
+ /* No more pending CAM entries to update */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ /**
+ * STOP is originated from bnad. When this happens,
+ * it can not be waiting for filter update
+ */
+ call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
+ break;
+
+ case RXF_E_FAIL:
+ rxf_reset_packet_filter(rxf);
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ /* No-op */
+ break;
+
+ case RXF_E_CAM_FLTR_RESP:
+ if (!rxf_process_packet_filter(rxf)) {
+ /* No more pending CAM entries to update */
+ call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ }
+ break;
+
+ case RXF_E_PAUSE:
+ case RXF_E_RESUME:
+ rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_started_entry(struct bna_rxf *rxf)
+{
+ call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS);
+
+ if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) {
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_PAUSE);
+ else
+ bfa_fsm_send_event(rxf, RXF_E_RESUME);
+ }
+
+}
+
+static void
+bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_STOP:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
+ /* Hack to get FSM start clearing CAM entries */
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
+ break;
+
+ case RXF_E_FAIL:
+ rxf_reset_packet_filter(rxf);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_MOD:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait);
+ break;
+
+ case RXF_E_RESUME:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf)
+{
+ /**
+ * Note: Do not add rxf_clear_packet_filter here.
+ * It will overstep mbox when this transition happens:
+ * cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
+ */
+}
+
+static void
+bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ rxf_reset_packet_filter(rxf);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_CAM_FLTR_RESP:
+ if (!rxf_clear_packet_filter(rxf)) {
+ /* No more pending CAM entries to clear */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
+ rxf_disable(rxf);
+ }
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf)
+{
+ /**
+ * NOTE: Do not add rxf_disable here.
+ * It will overstep mbox when this transition happens:
+ * start_wait -> stop_wait on RXF_E_STOP event
+ */
+}
+
+static void
+bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STARTED:
+ /**
+ * This event is received due to abrupt transition from
+ * bna_rxf_sm_start_wait state on receiving
+ * RXF_E_STOP event
+ */
+ rxf_disable(rxf);
+ break;
+
+ case RXF_E_STOPPED:
+ /**
+ * FSM was in the process of stopping, initiated by
+ * bnad. When this happens, no one can be waiting for
+ * start or filter update
+ */
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait);
+ break;
+
+ case RXF_E_PAUSE:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ break;
+
+ case RXF_E_RESUME:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags &=
+ ~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED);
+ __rxf_disable(rxf);
+}
+
+static void
+bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of disabling rxf, initiated by
+ * bnad.
+ */
+ call_rxf_pause_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STOPPED:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
+ call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ break;
+
+ /*
+ * Since PAUSE/RESUME can only be sent by bnad, we don't expect
+ * any other event during these states
+ */
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED);
+ rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
+ __rxf_enable(rxf);
+}
+
+static void
+bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ /**
+ * FSM was in the process of disabling rxf, initiated by
+ * bnad.
+ */
+ call_rxf_resume_cbfn(rxf, BNA_CB_FAIL);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ case RXF_E_STARTED:
+ rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
+ call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(rxf, bna_rxf_sm_started);
+ break;
+
+ /*
+ * Since PAUSE/RESUME can only be sent by bnad, we don't expect
+ * any other event during these states
+ */
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf)
+{
+ __bna_rxf_stat_clr(rxf);
+}
+
+static void
+bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
+{
+ switch (event) {
+ case RXF_E_FAIL:
+ case RXF_E_STAT_CLEARED:
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(rxf->rx->bna, event);
+ }
+}
+
+static void
+__rxf_enable(struct bna_rxf *rxf)
+{
+ struct bfi_ll_rxf_multi_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+ ll_req.enable = 1;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ rxf_cb_enabled, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+__rxf_disable(struct bna_rxf *rxf)
+{
+ struct bfi_ll_rxf_multi_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+ ll_req.enable = 0;
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ rxf_cb_disabled, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+__rxf_config_set(struct bna_rxf *rxf)
+{
+ u32 i;
+ struct bna_rss_mem *rss_mem;
+ struct bna_rx_fndb_ram *rx_fndb_ram;
+ struct bna *bna = rxf->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ RSS_TABLE_BASE_OFFSET);
+
+ rss_mem = (struct bna_rss_mem *)0;
+
+ /* Configure RSS if required */
+ if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) {
+ /* configure RSS Table */
+ writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM +
+ bna->port_num, RSS_TABLE_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ /* temporarily disable RSS, while hash value is written */
+ off = (unsigned long)&rss_mem[0].type_n_hash;
+ writel(0, base_addr + off);
+
+ for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) {
+ off = (unsigned long)
+ &rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i];
+ writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]),
+ base_addr + off);
+ }
+
+ off = (unsigned long)&rss_mem[0].type_n_hash;
+ writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask,
+ base_addr + off);
+ }
+
+ /* Configure RxF */
+ writel(BNA_GET_PAGE_NUM(
+ LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2),
+ RX_FNDB_RAM_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ RX_FNDB_RAM_BASE_OFFSET);
+
+ rx_fndb_ram = (struct bna_rx_fndb_ram *)0;
+
+ /* We always use RSS table 0 */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop;
+ writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE,
+ base_addr + off);
+
+ /* small large buffer enable/disable */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props;
+ writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80,
+ base_addr + off);
+
+ /* RIT offset, HDS forced offset, multicast RxQ Id */
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq;
+ writel((rxf->rit_segment->rit_offset << 16) |
+ (rxf->forced_offset << 8) |
+ (rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id,
+ base_addr + off);
+
+ /*
+ * default vlan tag, default function enable, strip vlan bytes,
+ * HDS type, header size
+ */
+
+ off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags;
+ writel(((u32)rxf->default_vlan_tag << 16) |
+ (rxf->ctrl_flags &
+ (BNA_RXF_CF_DEFAULT_VLAN |
+ BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE |
+ BNA_RXF_CF_VLAN_STRIP)) |
+ (rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) |
+ rxf->hds_cfg.header_size,
+ base_addr + off);
+}
+
+void
+__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status)
+{
+ struct bna *bna = rxf->rx->bna;
+ int i;
+
+ writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (bna->port_num * 2), VLAN_RAM_BASE_OFFSET),
+ bna->regs.page_addr);
+
+ if (status == BNA_STATUS_T_ENABLED) {
+ /* enable VLAN filtering on this function */
+ for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
+ writel(rxf->vlan_filter_table[i],
+ BNA_GET_VLAN_MEM_ENTRY_ADDR
+ (bna->pcidev.pci_bar_kva, rxf->rxf_id,
+ i * 32));
+ }
+ } else {
+ /* disable VLAN filtering on this function */
+ for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
+ writel(0xffffffff,
+ BNA_GET_VLAN_MEM_ENTRY_ADDR
+ (bna->pcidev.pci_bar_kva, rxf->rxf_id,
+ i * 32));
+ }
+ }
+}
+
+static void
+__rxf_rit_set(struct bna_rxf *rxf)
+{
+ struct bna *bna = rxf->rx->bna;
+ struct bna_rit_mem *rit_mem;
+ int i;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ FUNCTION_TO_RXQ_TRANSLATE);
+
+ rit_mem = (struct bna_rit_mem *)0;
+
+ writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num,
+ FUNCTION_TO_RXQ_TRANSLATE),
+ bna->regs.page_addr);
+
+ for (i = 0; i < rxf->rit_segment->rit_size; i++) {
+ off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset];
+ writel(rxf->rit_segment->rit[i].large_rxq_id << 6 |
+ rxf->rit_segment->rit[i].small_rxq_id,
+ base_addr + off);
+ }
+}
+
+static void
+__bna_rxf_stat_clr(struct bna_rxf *rxf)
+{
+ struct bfi_ll_stats_req ll_req;
+ u32 bm[2] = {0, 0};
+
+ if (rxf->rxf_id < 32)
+ bm[0] = 1 << rxf->rxf_id;
+ else
+ bm[1] = 1 << (rxf->rxf_id - 32);
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
+ ll_req.stats_mask = 0;
+ ll_req.txf_id_mask[0] = 0;
+ ll_req.txf_id_mask[1] = 0;
+
+ ll_req.rxf_id_mask[0] = htonl(bm[0]);
+ ll_req.rxf_id_mask[1] = htonl(bm[1]);
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_rxf_cb_stats_cleared, rxf);
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static void
+rxf_enable(struct bna_rxf *rxf)
+{
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_STARTED);
+ else {
+ rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
+ __rxf_enable(rxf);
+ }
+}
+
+static void
+rxf_cb_enabled(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STARTED);
+}
+
+static void
+rxf_disable(struct bna_rxf *rxf)
+{
+ if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
+ bfa_fsm_send_event(rxf, RXF_E_STOPPED);
+ else
+ rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED;
+ __rxf_disable(rxf);
+}
+
+static void
+rxf_cb_disabled(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STOPPED);
+}
+
+void
+rxf_cb_cam_fltr_mbox_cmd(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
+}
+
+static void
+bna_rxf_cb_stats_cleared(void *arg, int status)
+{
+ struct bna_rxf *rxf = (struct bna_rxf *)arg;
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+ bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED);
+}
+
+void
+rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
+ const struct bna_mac *mac_addr)
+{
+ struct bfi_ll_mac_addr_req req;
+
+ bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);
+
+ req.rxf_id = rxf->rxf_id;
+ memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN);
+
+ bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
+ rxf_cb_cam_fltr_mbox_cmd, rxf);
+
+ bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
+}
+
+static int
+rxf_process_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* Add multicast entries */
+ if (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->mcast_active_q);
+ return 1;
+ }
+
+ /* Delete multicast entries previousely added */
+ if (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+rxf_process_packet_filter_vlan(struct bna_rxf *rxf)
+{
+ /* Apply the VLAN filter */
+ if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) {
+ rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) &&
+ !(rxf->rxmode_active & BNA_RXMODE_DEFAULT))
+ __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
+ }
+
+ /* Apply RSS configuration */
+ if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) {
+ rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING;
+ if (rxf->rss_status == BNA_STATUS_T_DISABLED) {
+ /* RSS is being disabled */
+ rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE;
+ __rxf_rit_set(rxf);
+ __rxf_config_set(rxf);
+ } else {
+ /* RSS is being enabled or reconfigured */
+ rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
+ __rxf_rit_set(rxf);
+ __rxf_config_set(rxf);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Processes pending ucast, mcast entry addition/deletion and issues mailbox
+ * command. Also processes pending filter configuration - promiscuous mode,
+ * default mode, allmutli mode and issues mailbox command or directly applies
+ * to h/w
+ */
+static int
+rxf_process_packet_filter(struct bna_rxf *rxf)
+{
+ /* Set the default MAC first */
+ if (rxf->ucast_pending_set > 0) {
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ,
+ rxf->ucast_active_mac);
+ rxf->ucast_pending_set--;
+ return 1;
+ }
+
+ if (rxf_process_packet_filter_ucast(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_mcast(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_promisc(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_default(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_allmulti(rxf))
+ return 1;
+
+ if (rxf_process_packet_filter_vlan(rxf))
+ return 1;
+
+ return 0;
+}
+
+static int
+rxf_clear_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac = NULL;
+ struct list_head *qe;
+
+ /* 3. delete pending mcast entries */
+ if (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ return 1;
+ }
+
+ /* 4. clear active mcast entries; move them to pending_add_q */
+ if (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * In the rxf stop path, processes pending ucast/mcast delete queue and issues
+ * the mailbox command. Moves the active ucast/mcast entries to pending add q,
+ * so that they are added to CAM again in the rxf start path. Moves the current
+ * filter settings - promiscuous, default, allmutli - to pending filter
+ * configuration
+ */
+static int
+rxf_clear_packet_filter(struct bna_rxf *rxf)
+{
+ if (rxf_clear_packet_filter_ucast(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_mcast(rxf))
+ return 1;
+
+ /* 5. clear active default MAC in the CAM */
+ if (rxf->ucast_pending_set > 0)
+ rxf->ucast_pending_set = 0;
+
+ if (rxf_clear_packet_filter_promisc(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_default(rxf))
+ return 1;
+
+ if (rxf_clear_packet_filter_allmulti(rxf))
+ return 1;
+
+ return 0;
+}
+
+static void
+rxf_reset_packet_filter_mcast(struct bna_rxf *rxf)
+{
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* 3. Move active mcast entries to pending_add_q */
+ while (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->mcast_pending_add_q);
+ }
+
+ /* 4. Throw away delete pending mcast entries */
+ while (!list_empty(&rxf->mcast_pending_del_q)) {
+ bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
+ bfa_q_qe_init(qe);
+ mac = (struct bna_mac *)qe;
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+}
+
+/**
+ * In the rxf fail path, throws away the ucast/mcast entries pending for
+ * deletion, moves all active ucast/mcast entries to pending queue so that
+ * they are added back to CAM in the rxf start path. Also moves the current
+ * filter configuration to pending filter configuration.
+ */
+static void
+rxf_reset_packet_filter(struct bna_rxf *rxf)
+{
+ rxf_reset_packet_filter_ucast(rxf);
+
+ rxf_reset_packet_filter_mcast(rxf);
+
+ /* 5. Turn off ucast set flag */
+ rxf->ucast_pending_set = 0;
+
+ rxf_reset_packet_filter_promisc(rxf);
+
+ rxf_reset_packet_filter_default(rxf);
+
+ rxf_reset_packet_filter_allmulti(rxf);
+}
+
+void
+bna_rxf_init(struct bna_rxf *rxf,
+ struct bna_rx *rx,
+ struct bna_rx_config *q_config)
+{
+ struct list_head *qe;
+ struct bna_rxp *rxp;
+
+ /* rxf_id is initialized during rx_mod init */
+ rxf->rx = rx;
+
+ INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
+ INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
+ rxf->ucast_pending_set = 0;
+ INIT_LIST_HEAD(&rxf->ucast_active_q);
+ rxf->ucast_active_mac = NULL;
+
+ INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
+ INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
+ INIT_LIST_HEAD(&rxf->mcast_active_q);
+
+ bfa_q_qe_init(&rxf->mbox_qe.qe);
+
+ if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED)
+ rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP;
+
+ rxf->rxf_oper_state = (q_config->paused) ?
+ BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING;
+
+ bna_rxf_adv_init(rxf, rx, q_config);
+
+ rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod,
+ q_config->num_paths);
+
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ if (q_config->rxp_type == BNA_RXP_SINGLE)
+ rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id;
+ else
+ rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id;
+ break;
+ }
+
+ rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
+ memset(rxf->vlan_filter_table, 0,
+ (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)));
+
+ bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
+}
+
+void
+bna_rxf_uninit(struct bna_rxf *rxf)
+{
+ struct bna_mac *mac;
+
+ bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment);
+ rxf->rit_segment = NULL;
+
+ rxf->ucast_pending_set = 0;
+
+ while (!list_empty(&rxf->ucast_pending_add_q)) {
+ bfa_q_deq(&rxf->ucast_pending_add_q, &mac);
+ bfa_q_qe_init(&mac->qe);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
+ }
+
+ if (rxf->ucast_active_mac) {
+ bfa_q_qe_init(&rxf->ucast_active_mac->qe);
+ bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod,
+ rxf->ucast_active_mac);
+ rxf->ucast_active_mac = NULL;
+ }
+
+ while (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &mac);
+ bfa_q_qe_init(&mac->qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+
+ rxf->rx = NULL;
+}
+
+void
+bna_rxf_start(struct bna_rxf *rxf)
+{
+ rxf->start_cbfn = bna_rx_cb_rxf_started;
+ rxf->start_cbarg = rxf->rx;
+ rxf->rxf_flags &= ~BNA_RXF_FL_FAILED;
+ bfa_fsm_send_event(rxf, RXF_E_START);
+}
+
+void
+bna_rxf_stop(struct bna_rxf *rxf)
+{
+ rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
+ rxf->stop_cbarg = rxf->rx;
+ bfa_fsm_send_event(rxf, RXF_E_STOP);
+}
+
+void
+bna_rxf_fail(struct bna_rxf *rxf)
+{
+ rxf->rxf_flags |= BNA_RXF_FL_FAILED;
+ bfa_fsm_send_event(rxf, RXF_E_FAIL);
+}
+
+int
+bna_rxf_state_get(struct bna_rxf *rxf)
+{
+ return bfa_sm_to_state(rxf_sm_table, rxf->fsm);
+}
+
+enum bna_cb_status
+bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+
+ if (rxf->ucast_active_mac == NULL) {
+ rxf->ucast_active_mac =
+ bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
+ if (rxf->ucast_active_mac == NULL)
+ return BNA_CB_UCAST_CAM_FULL;
+ bfa_q_qe_init(&rxf->ucast_active_mac->qe);
+ }
+
+ memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN);
+ rxf->ucast_pending_set++;
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+
+ return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_add(struct bna_rx *rx, u8 *addr,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ /* Check if already added */
+ list_for_each(qe, &rxf->mcast_active_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ /* Check if pending addition */
+ list_for_each(qe, &rxf->mcast_pending_add_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+ if (mac == NULL)
+ return BNA_CB_MCAST_LIST_FULL;
+ bfa_q_qe_init(&mac->qe);
+ memcpy(mac->addr, addr, ETH_ALEN);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+
+ return BNA_CB_SUCCESS;
+}
+
+enum bna_cb_status
+bna_rx_mcast_del(struct bna_rx *rx, u8 *addr,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head *qe;
+ struct bna_mac *mac;
+
+ list_for_each(qe, &rxf->mcast_pending_add_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ list_del(qe);
+ bfa_q_qe_init(qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ list_for_each(qe, &rxf->mcast_active_q) {
+ mac = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
+ list_del(qe);
+ bfa_q_qe_init(qe);
+ list_add_tail(qe, &rxf->mcast_pending_del_q);
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ return BNA_CB_SUCCESS;
+ }
+ }
+
+ return BNA_CB_INVALID_MAC;
+}
+
+enum bna_cb_status
+bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist,
+ void (*cbfn)(struct bnad *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ struct list_head list_head;
+ struct list_head *qe;
+ u8 *mcaddr;
+ struct bna_mac *mac;
+ struct bna_mac *mac1;
+ int skip;
+ int delete;
+ int need_hw_config = 0;
+ int i;
+
+ /* Allocate nodes */
+ INIT_LIST_HEAD(&list_head);
+ for (i = 0, mcaddr = mclist; i < count; i++) {
+ mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
+ if (mac == NULL)
+ goto err_return;
+ bfa_q_qe_init(&mac->qe);
+ memcpy(mac->addr, mcaddr, ETH_ALEN);
+ list_add_tail(&mac->qe, &list_head);
+
+ mcaddr += ETH_ALEN;
+ }
+
+ /* Schedule for addition */
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+
+ skip = 0;
+
+ /* Skip if already added */
+ list_for_each(qe, &rxf->mcast_active_q) {
+ mac1 = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
+ mac);
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip)
+ continue;
+
+ /* Skip if pending addition */
+ list_for_each(qe, &rxf->mcast_pending_add_q) {
+ mac1 = (struct bna_mac *)qe;
+ if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
+ mac);
+ skip = 1;
+ break;
+ }
+ }
+
+ if (skip)
+ continue;
+
+ need_hw_config = 1;
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ }
+
+ /**
+ * Delete the entries that are in the pending_add_q but not
+ * in the new list
+ */
+ while (!list_empty(&rxf->mcast_pending_add_q)) {
+ bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
+ if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
+ delete = 0;
+ break;
+ }
+ mcaddr += ETH_ALEN;
+ }
+ if (delete)
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ else
+ list_add_tail(&mac->qe, &list_head);
+ }
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
+ }
+
+ /**
+ * Schedule entries for deletion that are in the active_q but not
+ * in the new list
+ */
+ while (!list_empty(&rxf->mcast_active_q)) {
+ bfa_q_deq(&rxf->mcast_active_q, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
+ if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
+ delete = 0;
+ break;
+ }
+ mcaddr += ETH_ALEN;
+ }
+ if (delete) {
+ list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
+ need_hw_config = 1;
+ } else {
+ list_add_tail(&mac->qe, &list_head);
+ }
+ }
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ list_add_tail(&mac->qe, &rxf->mcast_active_q);
+ }
+
+ if (need_hw_config) {
+ rxf->cam_fltr_cbfn = cbfn;
+ rxf->cam_fltr_cbarg = rx->bna->bnad;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ } else if (cbfn)
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+
+ return BNA_CB_SUCCESS;
+
+err_return:
+ while (!list_empty(&list_head)) {
+ bfa_q_deq(&list_head, &qe);
+ mac = (struct bna_mac *)qe;
+ bfa_q_qe_init(&mac->qe);
+ bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
+ }
+
+ return BNA_CB_MCAST_LIST_FULL;
+}
+
+void
+bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int index = (vlan_id >> 5);
+ int bit = (1 << (vlan_id & 0x1F));
+
+ rxf->vlan_filter_table[index] |= bit;
+ if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+void
+bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
+{
+ struct bna_rxf *rxf = &rx->rxf;
+ int index = (vlan_id >> 5);
+ int bit = (1 << (vlan_id & 0x1F));
+
+ rxf->vlan_filter_table[index] &= ~bit;
+ if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
+ rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
+ bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
+ }
+}
+
+/**
+ * RX
+ */
+#define RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem) do { \
+ struct bna_doorbell_qset *_qset; \
+ unsigned long off; \
+ (q)->rcb->producer_index = (q)->rcb->consumer_index = 0; \
+ (q)->rcb->q_depth = (qdepth); \
+ (q)->rcb->unmap_q = unmapq_mem; \
+ (q)->rcb->rxq = (q); \
+ (q)->rcb->cq = &(rxp)->cq; \
+ (q)->rcb->bnad = (bna)->bnad; \
+ _qset = (struct bna_doorbell_qset *)0; \
+ off = (unsigned long)&_qset[(q)->rxq_id].rxq[0]; \
+ (q)->rcb->q_dbell = off + \
+ BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva); \
+ (q)->rcb->id = _id; \
+} while (0)
+
+#define BNA_GET_RXQS(qcfg) (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \
+ (qcfg)->num_paths : ((qcfg)->num_paths * 2))
+
+#define SIZE_TO_PAGES(size) (((size) >> PAGE_SHIFT) + ((((size) &\
+ (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
+
+#define call_rx_stop_callback(rx, status) \
+ if ((rx)->stop_cbfn) { \
+ (*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status)); \
+ (rx)->stop_cbfn = NULL; \
+ (rx)->stop_cbarg = NULL; \
+ }
+
+/*
+ * Since rx_enable is synchronous callback, there is no start_cbfn required.
+ * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers
+ * for each rxpath.
+ */
+
+#define call_rx_disable_cbfn(rx, status) \
+ if ((rx)->disable_cbfn) { \
+ (*(rx)->disable_cbfn)((rx)->disable_cbarg, \
+ status); \
+ (rx)->disable_cbfn = NULL; \
+ (rx)->disable_cbarg = NULL; \
+ } \
+
+#define rxqs_reqd(type, num_rxqs) \
+ (((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2))
+
+#define rx_ib_fail(rx) \
+do { \
+ struct bna_rxp *rxp; \
+ struct list_head *qe; \
+ list_for_each(qe, &(rx)->rxp_q) { \
+ rxp = (struct bna_rxp *)qe; \
+ bna_ib_fail(rxp->cq.ib); \
+ } \
+} while (0)
+
+static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *);
+static void __bna_rxq_start(struct bna_rxq *rxq);
+static void __bna_cq_start(struct bna_cq *cq);
+static void bna_rit_create(struct bna_rx *rx);
+static void bna_rx_cb_multi_rxq_stopped(void *arg, int status);
+static void bna_rx_cb_rxq_stopped_all(void *arg);
+
+bfa_fsm_state_decl(bna_rx, stopped,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_start_wait,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, started,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
+ struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, rxq_stop_wait,
+ struct bna_rx, enum bna_rx_event);
+
+static struct bfa_sm_table rx_sm_table[] = {
+ {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED},
+ {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT},
+ {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED},
+ {BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT},
+ {BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT},
+};
+
+static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb);
+ }
+
+ call_rx_stop_callback(rx, BNA_CB_SUCCESS);
+}
+
+static void bna_rx_sm_stopped(struct bna_rx *rx,
+ enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_START:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
+ break;
+ case RX_E_STOP:
+ call_rx_stop_callback(rx, BNA_CB_SUCCESS);
+ break;
+ case RX_E_FAIL:
+ /* no-op */
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+
+}
+
+static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+ struct bna_rxq *q0 = NULL, *q1 = NULL;
+
+ /* Setup the RIT */
+ bna_rit_create(rx);
+
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ bna_ib_start(rxp->cq.ib);
+ GET_RXQS(rxp, q0, q1);
+ q0->buffer_size = bna_port_mtu_get(&rx->bna->port);
+ __bna_rxq_start(q0);
+ rx->rx_post_cbfn(rx->bna->bnad, q0->rcb);
+ if (q1) {
+ __bna_rxq_start(q1);
+ rx->rx_post_cbfn(rx->bna->bnad, q1->rcb);
+ }
+ __bna_cq_start(&rxp->cq);
+ }
+
+ bna_rxf_start(&rx->rxf);
+}
+
+static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
+ enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_STOP:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+ break;
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ case RX_E_RXF_STARTED:
+ bfa_fsm_set_state(rx, bna_rx_sm_started);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+bna_rx_sm_started_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp;
+ struct list_head *qe_rxp;
+
+ /* Start IB */
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ bna_ib_ack(&rxp->cq.ib->door_bell, 0);
+ }
+
+ bna_llport_admin_up(&rx->bna->port.llport);
+}
+
+void
+bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_FAIL:
+ bna_llport_admin_down(&rx->bna->port.llport);
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ case RX_E_STOP:
+ bna_llport_admin_down(&rx->bna->port.llport);
+ bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
+{
+ bna_rxf_stop(&rx->rxf);
+}
+
+void
+bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_RXF_STOPPED:
+ bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait);
+ break;
+ case RX_E_RXF_STARTED:
+ /**
+ * RxF was in the process of starting up when
+ * RXF_E_STOP was issued. Ignore this event
+ */
+ break;
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ rx_ib_fail(rx);
+ bna_rxf_fail(&rx->rxf);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+
+}
+
+void
+bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx)
+{
+ struct bna_rxp *rxp = NULL;
+ struct bna_rxq *q0 = NULL;
+ struct bna_rxq *q1 = NULL;
+ struct list_head *qe;
+ u32 rxq_mask[2] = {0, 0};
+
+ /* Only one call to multi-rxq-stop for all RXPs in this RX */
+ bfa_wc_up(&rx->rxq_stop_wc);
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ GET_RXQS(rxp, q0, q1);
+ if (q0->rxq_id < 32)
+ rxq_mask[0] |= ((u32)1 << q0->rxq_id);
+ else
+ rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32));
+ if (q1) {
+ if (q1->rxq_id < 32)
+ rxq_mask[0] |= ((u32)1 << q1->rxq_id);
+ else
+ rxq_mask[1] |= ((u32)
+ 1 << (q1->rxq_id - 32));
+ }
+ }
+
+ __bna_multi_rxq_stop(rxp, rxq_mask);
+}
+
+void
+bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+ struct bna_rxp *rxp = NULL;
+ struct list_head *qe;
+
+ switch (event) {
+ case RX_E_RXQ_STOPPED:
+ list_for_each(qe, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe;
+ bna_ib_stop(rxp->cq.ib);
+ }
+ /* Fall through */
+ case RX_E_FAIL:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ break;
+ default:
+ bfa_sm_fault(rx->bna, event);
+ break;
+ }
+}
+
+void
+__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask)
+{
+ struct bfi_ll_q_stop_req ll_req;
+
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0);
+ ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]);
+ ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]);
+ bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_rx_cb_multi_rxq_stopped, rxp);
+ bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe);
+}
+
+void
+__bna_rxq_start(struct bna_rxq *rxq)
+{
+ struct bna_rxtx_q_mem *q_mem;
+ struct bna_rxq_mem rxq_cfg, *rxq_mem;
+ struct bna_dma_addr cur_q_addr;
+ /* struct bna_doorbell_qset *qset; */
+ struct bna_qpt *qpt;
+ u32 pg_num;
+ struct bna *bna = rxq->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ qpt = &rxq->qpt;
+ cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
+
+ rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
+ rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
+ rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ rxq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0;
+ rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) |
+ (qpt->page_size >> 2);
+ rxq_cfg.sg_n_cq_n_cns_ptr =
+ ((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0;
+ rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) |
+ BNA_Q_IDLE_STATE;
+ rxq_cfg.next_qid = 0x0 | (0x3 << 8);
+
+ /* Write the page number register */
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ writel(pg_num, bna->regs.page_addr);
+
+ /* Write to h/w */
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+
+ q_mem = (struct bna_rxtx_q_mem *)0;
+ rxq_mem = &q_mem[rxq->rxq_id].rxq;
+
+ off = (unsigned long)&rxq_mem->pg_tbl_addr_lo;
+ writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->pg_tbl_addr_hi;
+ writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->cur_q_entry_lo;
+ writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->cur_q_entry_hi;
+ writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr;
+ writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->entry_n_pg_size;
+ writel(rxq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr;
+ writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->buf_sz_n_q_state;
+ writel(rxq_cfg.buf_sz_n_q_state, base_addr + off);
+
+ off = (unsigned long)&rxq_mem->next_qid;
+ writel(rxq_cfg.next_qid, base_addr + off);
+
+ rxq->rcb->producer_index = 0;
+ rxq->rcb->consumer_index = 0;
+}
+
+void
+__bna_cq_start(struct bna_cq *cq)
+{
+ struct bna_cq_mem cq_cfg, *cq_mem;
+ const struct bna_qpt *qpt;
+ struct bna_dma_addr cur_q_addr;
+ u32 pg_num;
+ struct bna *bna = cq->rx->bna;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ qpt = &cq->qpt;
+ cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));
+
+ /*
+ * Fill out structure, to be subsequently written
+ * to hardware
+ */
+ cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
+ cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
+ cq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ cq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0;
+ cq_cfg.entry_n_pg_size =
+ ((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2);
+ cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) |
+ ((u32)(cq->ib->ib_id & 0xff) << 16) | 0x0);
+ cq_cfg.q_state = BNA_Q_IDLE_STATE;
+
+ /* Write the page number register */
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
+ HQM_CQ_RAM_BASE_OFFSET);
+
+ writel(pg_num, bna->regs.page_addr);
+
+ /* H/W write */
+ base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
+ HQM_CQ_RAM_BASE_OFFSET);
+
+ cq_mem = (struct bna_cq_mem *)0;
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo;
+ writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi;
+ writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo;
+ writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi;
+ writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr;
+ writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size;
+ writel(cq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr;
+ writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&cq_mem[cq->cq_id].q_state;
+ writel(cq_cfg.q_state, base_addr + off);
+
+ cq->ccb->producer_index = 0;
+ *(cq->ccb->hw_producer_index) = 0;
+}
+
+void
+bna_rit_create(struct bna_rx *rx)
+{
+ struct list_head *qe_rxp;
+ struct bna *bna;
+ struct bna_rxp *rxp;
+ struct bna_rxq *q0 = NULL;
+ struct bna_rxq *q1 = NULL;
+ int offset;
+
+ bna = rx->bna;
+
+ offset = 0;
+ list_for_each(qe_rxp, &rx->rxp_q) {
+ rxp = (struct bna_rxp *)qe_rxp;
+ GET_RXQS(rxp, q0, q1);
+ rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id;
+ rx->rxf.rit_segment->rit[offset].small_rxq_id =
+ (q1 ? q1->rxq_id : 0);
+ offset++;
+ }
+}
+
+int
+_rx_can_satisfy(struct bna_rx_mod *rx_mod,
+ struct bna_rx_config *rx_cfg)
+{
+ if ((rx_mod->rx_free_count == 0) ||
+ (rx_mod->rxp_free_count == 0) ||
+ (rx_mod->rxq_free_count == 0))
+ return 0;
+
+ if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
+ if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+ (rx_mod->rxq_free_count < rx_cfg->num_paths))
+ return 0;
+ } else {
+ if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
+ (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
+ return 0;
+ }
+
+ if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths))
+ return 0;
+
+ return 1;
+}
+
+struct bna_rxq *
+_get_free_rxq(struct bna_rx_mod *rx_mod)
+{
+ struct bna_rxq *rxq = NULL;
+ struct list_head *qe = NULL;
+
+ bfa_q_deq(&rx_mod->rxq_free_q, &qe);
+ if (qe) {
+ rx_mod->rxq_free_count--;
+ rxq = (struct bna_rxq *)qe;
+ }
+ return rxq;
+}
+
+void
+_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
+{
+ bfa_q_qe_init(&rxq->qe);
+ list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
+ rx_mod->rxq_free_count++;
+}
+
+struct bna_rxp *
+_get_free_rxp(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe = NULL;
+ struct bna_rxp *rxp = NULL;
+
+ bfa_q_deq(&rx_mod->rxp_free_q, &qe);
+ if (qe) {
+ rx_mod->rxp_free_count--;
+
+ rxp = (struct bna_rxp *)qe;
+ }
+
+ return rxp;
+}
+
+void
+_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
+{
+ bfa_q_qe_init(&rxp->qe);
+ list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
+ rx_mod->rxp_free_count++;
+}
+
+struct bna_rx *
+_get_free_rx(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe = NULL;
+ struct bna_rx *rx = NULL;
+
+ bfa_q_deq(&rx_mod->rx_free_q, &qe);
+ if (qe) {
+ rx_mod->rx_free_count--;
+
+ rx = (struct bna_rx *)qe;
+ bfa_q_qe_init(qe);
+ list_add_tail(&rx->qe, &rx_mod->rx_active_q);
+ }
+
+ return rx;
+}
+
+void
+_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
+{
+ bfa_q_qe_init(&rx->qe);
+ list_add_tail(&rx->qe, &rx_mod->rx_free_q);
+ rx_mod->rx_free_count++;
+}
+
+void
+_rx_init(struct bna_rx *rx, struct bna *bna)
+{
+ rx->bna = bna;
+ rx->rx_flags = 0;
+
+ INIT_LIST_HEAD(&rx->rxp_q);
+
+ rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all;
+ rx->rxq_stop_wc.wc_cbarg = rx;
+ rx->rxq_stop_wc.wc_count = 0;
+
+ rx->stop_cbfn = NULL;
+ rx->stop_cbarg = NULL;
+}
+
+void
+_rxp_add_rxqs(struct bna_rxp *rxp,
+ struct bna_rxq *q0,
+ struct bna_rxq *q1)
+{
+ switch (rxp->type) {
+ case BNA_RXP_SINGLE:
+ rxp->rxq.single.only = q0;
+ rxp->rxq.single.reserved = NULL;
+ break;
+ case BNA_RXP_SLR:
+ rxp->rxq.slr.large = q0;
+ rxp->rxq.slr.small = q1;
+ break;
+ case BNA_RXP_HDS:
+ rxp->rxq.hds.data = q0;
+ rxp->rxq.hds.hdr = q1;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+_rxq_qpt_init(struct bna_rxq *rxq,
+ struct bna_rxp *rxp,
+ u32 page_count,
+ u32 page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
+ rxq->qpt.page_count = page_count;
+ rxq->qpt.page_size = page_size;
+
+ rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < rxq->qpt.page_count; i++) {
+ rxq->rcb->sw_qpt[i] = page_mem[i].kva;
+ ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+void
+_rxp_cqpt_setup(struct bna_rxp *rxp,
+ u32 page_count,
+ u32 page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
+ rxp->cq.qpt.page_count = page_count;
+ rxp->cq.qpt.page_size = page_size;
+
+ rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < rxp->cq.qpt.page_count; i++) {
+ rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva;
+
+ ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+void
+_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp)
+{
+ list_add_tail(&rxp->qe, &rx->rxp_q);
+}
+
+void
+_init_rxmod_queues(struct bna_rx_mod *rx_mod)
+{
+ INIT_LIST_HEAD(&rx_mod->rx_free_q);
+ INIT_LIST_HEAD(&rx_mod->rxq_free_q);
+ INIT_LIST_HEAD(&rx_mod->rxp_free_q);
+ INIT_LIST_HEAD(&rx_mod->rx_active_q);
+
+ rx_mod->rx_free_count = 0;
+ rx_mod->rxq_free_count = 0;
+ rx_mod->rxp_free_count = 0;
+}
+
+void
+_rx_ctor(struct bna_rx *rx, int id)
+{
+ bfa_q_qe_init(&rx->qe);
+ INIT_LIST_HEAD(&rx->rxp_q);
+ rx->bna = NULL;
+
+ rx->rxf.rxf_id = id;
+
+ /* FIXME: mbox_qe ctor()?? */
+ bfa_q_qe_init(&rx->mbox_qe.qe);
+
+ rx->stop_cbfn = NULL;
+ rx->stop_cbarg = NULL;
+}
+
+void
+bna_rx_cb_multi_rxq_stopped(void *arg, int status)
+{
+ struct bna_rxp *rxp = (struct bna_rxp *)arg;
+
+ bfa_wc_down(&rxp->rx->rxq_stop_wc);
+}
+
+void
+bna_rx_cb_rxq_stopped_all(void *arg)
+{
+ struct bna_rx *rx = (struct bna_rx *)arg;
+
+ bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED);
+}
+
+void
+bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+ bfa_wc_down(&rx_mod->rx_stop_wc);
+}
+
+void
+bna_rx_mod_cb_rx_stopped_all(void *arg)
+{
+ struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
+
+ if (rx_mod->stop_cbfn)
+ rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
+ rx_mod->stop_cbfn = NULL;
+}
+
+void
+bna_rx_start(struct bna_rx *rx)
+{
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ if (rx->rx_flags & BNA_RX_F_ENABLE)
+ bfa_fsm_send_event(rx, RX_E_START);
+}
+
+void
+bna_rx_stop(struct bna_rx *rx)
+{
+ rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
+ if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped)
+ bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS);
+ else {
+ rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
+ rx->stop_cbarg = &rx->bna->rx_mod;
+ bfa_fsm_send_event(rx, RX_E_STOP);
+ }
+}
+
+void
+bna_rx_fail(struct bna_rx *rx)
+{
+ /* Indicate port is not enabled, and failed */
+ rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
+ rx->rx_flags |= BNA_RX_F_PORT_FAILED;
+ bfa_fsm_send_event(rx, RX_E_FAIL);
+}
+
+void
+bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status)
+{
+ bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
+ if (rx->rxf.rxf_id < 32)
+ rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id);
+ else
+ rx->bna->rx_mod.rxf_bmap[1] |= ((u32)
+ 1 << (rx->rxf.rxf_id - 32));
+}
+
+void
+bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status)
+{
+ bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
+ if (rx->rxf.rxf_id < 32)
+ rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id;
+ else
+ rx->bna->rx_mod.rxf_bmap[1] &= ~(u32)
+ 1 << (rx->rxf.rxf_id - 32);
+}
+
+void
+bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED;
+ if (type == BNA_RX_T_LOOPBACK)
+ rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bna_rx_start(rx);
+ }
+}
+
+void
+bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ rx_mod->stop_cbfn = bna_port_cb_rx_stopped;
+
+ /**
+ * Before calling bna_rx_stop(), increment rx_stop_wc as many times
+ * as we are going to call bna_rx_stop
+ */
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bfa_wc_up(&rx_mod->rx_stop_wc);
+ }
+
+ if (rx_mod->rx_stop_wc.wc_count == 0) {
+ rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
+ rx_mod->stop_cbfn = NULL;
+ return;
+ }
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ if (rx->type == type)
+ bna_rx_stop(rx);
+ }
+}
+
+void
+bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
+{
+ struct bna_rx *rx;
+ struct list_head *qe;
+
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
+ rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ rx = (struct bna_rx *)qe;
+ bna_rx_fail(rx);
+ }
+}
+
+void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int index;
+ struct bna_rx *rx_ptr;
+ struct bna_rxp *rxp_ptr;
+ struct bna_rxq *rxq_ptr;
+
+ rx_mod->bna = bna;
+ rx_mod->flags = 0;
+
+ rx_mod->rx = (struct bna_rx *)
+ res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
+ rx_mod->rxp = (struct bna_rxp *)
+ res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
+ rx_mod->rxq = (struct bna_rxq *)
+ res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ /* Initialize the queues */
+ _init_rxmod_queues(rx_mod);
+
+ /* Build RX queues */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rx_ptr = &rx_mod->rx[index];
+ _rx_ctor(rx_ptr, index);
+ list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
+ rx_mod->rx_free_count++;
+ }
+
+ /* build RX-path queue */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rxp_ptr = &rx_mod->rxp[index];
+ rxp_ptr->cq.cq_id = index;
+ bfa_q_qe_init(&rxp_ptr->qe);
+ list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
+ rx_mod->rxp_free_count++;
+ }
+
+ /* build RXQ queue */
+ for (index = 0; index < BFI_MAX_RXQ; index++) {
+ rxq_ptr = &rx_mod->rxq[index];
+ rxq_ptr->rxq_id = index;
+
+ bfa_q_qe_init(&rxq_ptr->qe);
+ list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
+ rx_mod->rxq_free_count++;
+ }
+
+ rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all;
+ rx_mod->rx_stop_wc.wc_cbarg = rx_mod;
+ rx_mod->rx_stop_wc.wc_count = 0;
+}
+
+void
+bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
+{
+ struct list_head *qe;
+ int i;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rx_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rxp_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &rx_mod->rxq_free_q)
+ i++;
+
+ rx_mod->bna = NULL;
+}
+
+int
+bna_rx_state_get(struct bna_rx *rx)
+{
+ return bfa_sm_to_state(rx_sm_table, rx->fsm);
+}
+
+void
+bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
+{
+ u32 cq_size, hq_size, dq_size;
+ u32 cpage_count, hpage_count, dpage_count;
+ struct bna_mem_info *mem_info;
+ u32 cq_depth;
+ u32 hq_depth;
+ u32 dq_depth;
+
+ dq_depth = q_cfg->q_depth;
+ hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth);
+ cq_depth = dq_depth + hq_depth;
+
+ BNA_TO_POWER_OF_2_HIGH(cq_depth);
+ cq_size = cq_depth * BFI_CQ_WI_SIZE;
+ cq_size = ALIGN(cq_size, PAGE_SIZE);
+ cpage_count = SIZE_TO_PAGES(cq_size);
+
+ BNA_TO_POWER_OF_2_HIGH(dq_depth);
+ dq_size = dq_depth * BFI_RXQ_WI_SIZE;
+ dq_size = ALIGN(dq_size, PAGE_SIZE);
+ dpage_count = SIZE_TO_PAGES(dq_size);
+
+ if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
+ BNA_TO_POWER_OF_2_HIGH(hq_depth);
+ hq_size = hq_depth * BFI_RXQ_WI_SIZE;
+ hq_size = ALIGN(hq_size, PAGE_SIZE);
+ hpage_count = SIZE_TO_PAGES(hq_size);
+ } else {
+ hpage_count = 0;
+ }
+
+ /* CCB structures */
+ res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_ccb);
+ mem_info->num = q_cfg->num_paths;
+
+ /* RCB structures */
+ res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_rcb);
+ mem_info->num = BNA_GET_RXQS(q_cfg);
+
+ /* Completion QPT */
+ res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Completion s/w QPT */
+ res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = cpage_count * sizeof(void *);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Completion QPT pages */
+ res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = cpage_count * q_cfg->num_paths;
+
+ /* Data QPTs */
+ res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Data s/w QPTs */
+ res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = dpage_count * sizeof(void *);
+ mem_info->num = q_cfg->num_paths;
+
+ /* Data QPT pages */
+ res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = dpage_count * q_cfg->num_paths;
+
+ /* Hdr QPTs */
+ res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
+ mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+ /* Hdr s/w QPTs */
+ res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = hpage_count * sizeof(void *);
+ mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
+
+ /* Hdr QPT pages */
+ res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = (hpage_count ? PAGE_SIZE : 0);
+ mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0);
+
+ /* RX Interrupts */
+ res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
+ res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
+ res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
+}
+
+struct bna_rx *
+bna_rx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_rx_config *rx_cfg,
+ struct bna_rx_event_cbfn *rx_cbfn,
+ struct bna_res_info *res_info,
+ void *priv)
+{
+ struct bna_rx_mod *rx_mod = &bna->rx_mod;
+ struct bna_rx *rx;
+ struct bna_rxp *rxp;
+ struct bna_rxq *q0;
+ struct bna_rxq *q1;
+ struct bna_intr_info *intr_info;
+ u32 page_count;
+ struct bna_mem_descr *ccb_mem;
+ struct bna_mem_descr *rcb_mem;
+ struct bna_mem_descr *unmapq_mem;
+ struct bna_mem_descr *cqpt_mem;
+ struct bna_mem_descr *cswqpt_mem;
+ struct bna_mem_descr *cpage_mem;
+ struct bna_mem_descr *hqpt_mem; /* Header/Small Q qpt */
+ struct bna_mem_descr *dqpt_mem; /* Data/Large Q qpt */
+ struct bna_mem_descr *hsqpt_mem; /* s/w qpt for hdr */
+ struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */
+ struct bna_mem_descr *hpage_mem; /* hdr page mem */
+ struct bna_mem_descr *dpage_mem; /* data page mem */
+ int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret;
+ int dpage_count, hpage_count, rcb_idx;
+ struct bna_ib_config ibcfg;
+ /* Fail if we don't have enough RXPs, RXQs */
+ if (!_rx_can_satisfy(rx_mod, rx_cfg))
+ return NULL;
+
+ /* Initialize resource pointers */
+ intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
+ ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
+ rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
+ unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0];
+ cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
+ cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
+ cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
+ hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
+ dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
+ hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
+ dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
+ hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
+ dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
+
+ /* Compute q depth & page count */
+ page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+
+ dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+
+ hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num /
+ rx_cfg->num_paths;
+ /* Get RX pointer */
+ rx = _get_free_rx(rx_mod);
+ _rx_init(rx, bna);
+ rx->priv = priv;
+ rx->type = rx_cfg->rx_type;
+
+ rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
+ rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
+ rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
+ rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
+ /* Following callbacks are mandatory */
+ rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
+ rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
+
+ if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) {
+ switch (rx->type) {
+ case BNA_RX_T_REGULAR:
+ if (!(rx->bna->rx_mod.flags &
+ BNA_RX_MOD_F_PORT_LOOPBACK))
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ break;
+ case BNA_RX_T_LOOPBACK:
+ if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK)
+ rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
+ break;
+ }
+ }
+
+ for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) {
+ rxp = _get_free_rxp(rx_mod);
+ rxp->type = rx_cfg->rxp_type;
+ rxp->rx = rx;
+ rxp->cq.rx = rx;
+
+ /* Get required RXQs, and queue them to rx-path */
+ q0 = _get_free_rxq(rx_mod);
+ if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
+ q1 = NULL;
+ else
+ q1 = _get_free_rxq(rx_mod);
+
+ /* Initialize IB */
+ if (1 == intr_info->num) {
+ rxp->cq.ib = bna_ib_get(&bna->ib_mod,
+ intr_info->intr_type,
+ intr_info->idl[0].vector);
+ rxp->vector = intr_info->idl[0].vector;
+ } else {
+ rxp->cq.ib = bna_ib_get(&bna->ib_mod,
+ intr_info->intr_type,
+ intr_info->idl[i].vector);
+
+ /* Map the MSI-x vector used for this RXP */
+ rxp->vector = intr_info->idl[i].vector;
+ }
+
+ rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib);
+
+ ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO;
+ ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT;
+ ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
+ ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;
+
+ ret = bna_ib_config(rxp->cq.ib, &ibcfg);
+
+ /* Link rxqs to rxp */
+ _rxp_add_rxqs(rxp, q0, q1);
+
+ /* Link rxp to rx */
+ _rx_add_rxp(rx, rxp);
+
+ q0->rx = rx;
+ q0->rxp = rxp;
+
+ /* Initialize RCB for the large / data q */
+ q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+ RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0,
+ (void *)unmapq_mem[rcb_idx].kva);
+ rcb_idx++;
+ (q0)->rx_packets = (q0)->rx_bytes = 0;
+ (q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0;
+
+ /* Initialize RXQs */
+ _rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE,
+ &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]);
+ q0->rcb->page_idx = dpage_idx;
+ q0->rcb->page_count = dpage_count;
+ dpage_idx += dpage_count;
+
+ /* Call bnad to complete rcb setup */
+ if (rx->rcb_setup_cbfn)
+ rx->rcb_setup_cbfn(bnad, q0->rcb);
+
+ if (q1) {
+ q1->rx = rx;
+ q1->rxp = rxp;
+
+ q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
+ RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1,
+ (void *)unmapq_mem[rcb_idx].kva);
+ rcb_idx++;
+ (q1)->buffer_size = (rx_cfg)->small_buff_size;
+ (q1)->rx_packets = (q1)->rx_bytes = 0;
+ (q1)->rx_packets_with_error =
+ (q1)->rxbuf_alloc_failed = 0;
+
+ _rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE,
+ &hqpt_mem[i], &hsqpt_mem[i],
+ &hpage_mem[hpage_idx]);
+ q1->rcb->page_idx = hpage_idx;
+ q1->rcb->page_count = hpage_count;
+ hpage_idx += hpage_count;
+
+ /* Call bnad to complete rcb setup */
+ if (rx->rcb_setup_cbfn)
+ rx->rcb_setup_cbfn(bnad, q1->rcb);
+ }
+ /* Setup RXP::CQ */
+ rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
+ _rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
+ &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]);
+ rxp->cq.ccb->page_idx = cpage_idx;
+ rxp->cq.ccb->page_count = page_count;
+ cpage_idx += page_count;
+
+ rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
+ rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;
+
+ rxp->cq.ccb->producer_index = 0;
+ rxp->cq.ccb->q_depth = rx_cfg->q_depth +
+ ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
+ 0 : rx_cfg->q_depth);
+ rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell;
+ rxp->cq.ccb->rcb[0] = q0->rcb;
+ if (q1)
+ rxp->cq.ccb->rcb[1] = q1->rcb;
+ rxp->cq.ccb->cq = &rxp->cq;
+ rxp->cq.ccb->bnad = bna->bnad;
+ rxp->cq.ccb->hw_producer_index =
+ ((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva +
+ (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE));
+ *(rxp->cq.ccb->hw_producer_index) = 0;
+ rxp->cq.ccb->intr_type = intr_info->intr_type;
+ rxp->cq.ccb->intr_vector = (intr_info->num == 1) ?
+ intr_info->idl[0].vector :
+ intr_info->idl[i].vector;
+ rxp->cq.ccb->rx_coalescing_timeo =
+ rxp->cq.ib->ib_config.coalescing_timeo;
+ rxp->cq.ccb->id = i;
+
+ /* Call bnad to complete CCB setup */
+ if (rx->ccb_setup_cbfn)
+ rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
+
+ } /* for each rx-path */
+
+ bna_rxf_init(&rx->rxf, rx, rx_cfg);
+
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+
+ return rx;
+}
+
+void
+bna_rx_destroy(struct bna_rx *rx)
+{
+ struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
+ struct bna_ib_mod *ib_mod = &rx->bna->ib_mod;
+ struct bna_rxq *q0 = NULL;
+ struct bna_rxq *q1 = NULL;
+ struct bna_rxp *rxp;
+ struct list_head *qe;
+
+ bna_rxf_uninit(&rx->rxf);
+
+ while (!list_empty(&rx->rxp_q)) {
+ bfa_q_deq(&rx->rxp_q, &rxp);
+ GET_RXQS(rxp, q0, q1);
+ /* Callback to bnad for destroying RCB */
+ if (rx->rcb_destroy_cbfn)
+ rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
+ q0->rcb = NULL;
+ q0->rxp = NULL;
+ q0->rx = NULL;
+ _put_free_rxq(rx_mod, q0);
+ if (q1) {
+ /* Callback to bnad for destroying RCB */
+ if (rx->rcb_destroy_cbfn)
+ rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
+ q1->rcb = NULL;
+ q1->rxp = NULL;
+ q1->rx = NULL;
+ _put_free_rxq(rx_mod, q1);
+ }
+ rxp->rxq.slr.large = NULL;
+ rxp->rxq.slr.small = NULL;
+ if (rxp->cq.ib) {
+ if (rxp->cq.ib_seg_offset != 0xff)
+ bna_ib_release_idx(rxp->cq.ib,
+ rxp->cq.ib_seg_offset);
+ bna_ib_put(ib_mod, rxp->cq.ib);
+ rxp->cq.ib = NULL;
+ }
+ /* Callback to bnad for destroying CCB */
+ if (rx->ccb_destroy_cbfn)
+ rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
+ rxp->cq.ccb = NULL;
+ rxp->rx = NULL;
+ _put_free_rxp(rx_mod, rxp);
+ }
+
+ list_for_each(qe, &rx_mod->rx_active_q) {
+ if (qe == &rx->qe) {
+ list_del(&rx->qe);
+ bfa_q_qe_init(&rx->qe);
+ break;
+ }
+ }
+
+ rx->bna = NULL;
+ rx->priv = NULL;
+ _put_free_rx(rx_mod, rx);
+}
+
+void
+bna_rx_enable(struct bna_rx *rx)
+{
+ if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped)
+ return;
+
+ rx->rx_flags |= BNA_RX_F_ENABLE;
+ if (rx->rx_flags & BNA_RX_F_PORT_ENABLED)
+ bfa_fsm_send_event(rx, RX_E_START);
+}
+
+void
+bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_rx *,
+ enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ /* h/w should not be accessed. Treat we're stopped */
+ (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
+ } else {
+ rx->stop_cbfn = cbfn;
+ rx->stop_cbarg = rx->bna->bnad;
+
+ rx->rx_flags &= ~BNA_RX_F_ENABLE;
+
+ bfa_fsm_send_event(rx, RX_E_STOP);
+ }
+}
+
+/**
+ * TX
+ */
+#define call_tx_stop_cbfn(tx, status)\
+do {\
+ if ((tx)->stop_cbfn)\
+ (tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\
+ (tx)->stop_cbfn = NULL;\
+ (tx)->stop_cbarg = NULL;\
+} while (0)
+
+#define call_tx_prio_change_cbfn(tx, status)\
+do {\
+ if ((tx)->prio_change_cbfn)\
+ (tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\
+ (tx)->prio_change_cbfn = NULL;\
+} while (0)
+
+static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx,
+ enum bna_cb_status status);
+static void bna_tx_cb_txq_stopped(void *arg, int status);
+static void bna_tx_cb_stats_cleared(void *arg, int status);
+static void __bna_tx_stop(struct bna_tx *tx);
+static void __bna_tx_start(struct bna_tx *tx);
+static void __bna_txf_stat_clr(struct bna_tx *tx);
+
+enum bna_tx_event {
+ TX_E_START = 1,
+ TX_E_STOP = 2,
+ TX_E_FAIL = 3,
+ TX_E_TXQ_STOPPED = 4,
+ TX_E_PRIO_CHANGE = 5,
+ TX_E_STAT_CLEARED = 6,
+};
+
+enum bna_tx_state {
+ BNA_TX_STOPPED = 1,
+ BNA_TX_STARTED = 2,
+ BNA_TX_TXQ_STOP_WAIT = 3,
+ BNA_TX_PRIO_STOP_WAIT = 4,
+ BNA_TX_STAT_CLR_WAIT = 5,
+};
+
+bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, started, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
+ enum bna_tx_event);
+bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx,
+ enum bna_tx_event);
+
+static struct bfa_sm_table tx_sm_table[] = {
+ {BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED},
+ {BFA_SM(bna_tx_sm_started), BNA_TX_STARTED},
+ {BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT},
+ {BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT},
+ {BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT},
+};
+
+static void
+bna_tx_sm_stopped_entry(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+
+ call_tx_stop_cbfn(tx, BNA_CB_SUCCESS);
+}
+
+static void
+bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
+{
+ switch (event) {
+ case TX_E_START:
+ bfa_fsm_set_state(tx, bna_tx_sm_started);
+ break;
+
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_FAIL:
+ /* No-op */
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ /**
+ * This event is received due to flushing of mbox when
+ * device fails
+ */
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_started_entry(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ __bna_tx_start(tx);
+
+ /* Start IB */
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_ack(&txq->ib->door_bell, 0);
+ }
+}
+
+static void
+bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
+ __bna_tx_stop(tx);
+ break;
+
+ case TX_E_FAIL:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_fail(txq->ib);
+ (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx)
+{
+}
+
+static void
+bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_FAIL:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_stop(txq->ib);
+ }
+ bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
+{
+ __bna_tx_stop(tx);
+}
+
+static void
+bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ switch (event) {
+ case TX_E_STOP:
+ bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
+ break;
+
+ case TX_E_FAIL:
+ call_tx_prio_change_cbfn(tx, BNA_CB_FAIL);
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ case TX_E_TXQ_STOPPED:
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_stop(txq->ib);
+ (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
+ bfa_fsm_set_state(tx, bna_tx_sm_started);
+ break;
+
+ case TX_E_PRIO_CHANGE:
+ /* No-op */
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx)
+{
+ __bna_txf_stat_clr(tx);
+}
+
+static void
+bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event)
+{
+ switch (event) {
+ case TX_E_FAIL:
+ case TX_E_STAT_CLEARED:
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+ break;
+
+ default:
+ bfa_sm_fault(tx->bna, event);
+ }
+}
+
+static void
+__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
+{
+ struct bna_rxtx_q_mem *q_mem;
+ struct bna_txq_mem txq_cfg;
+ struct bna_txq_mem *txq_mem;
+ struct bna_dma_addr cur_q_addr;
+ u32 pg_num;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ /* Fill out structure, to be subsequently written to hardware */
+ txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb;
+ txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb;
+ cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr));
+ txq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
+ txq_cfg.cur_q_entry_hi = cur_q_addr.msb;
+
+ txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0;
+
+ txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) |
+ (txq->qpt.page_size >> 2);
+ txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) |
+ ((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0);
+
+ txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
+ txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
+ (txq->priority & 0x3));
+ txq_cfg.wvc_n_cquota_n_rquota =
+ ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
+ (BFI_TX_MAX_WRR_QUOTA & 0xfff));
+
+ /* Setup the page and write to H/W */
+
+ pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ writel(pg_num, tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ HQM_RXTX_Q_RAM_BASE_OFFSET);
+ q_mem = (struct bna_rxtx_q_mem *)0;
+ txq_mem = &q_mem[txq->txq_id].txq;
+
+ /*
+ * The following 4 lines, is a hack b'cos the H/W needs to read
+ * these DMA addresses as little endian
+ */
+
+ off = (unsigned long)&txq_mem->pg_tbl_addr_lo;
+ writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off);
+
+ off = (unsigned long)&txq_mem->pg_tbl_addr_hi;
+ writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off);
+
+ off = (unsigned long)&txq_mem->cur_q_entry_lo;
+ writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off);
+
+ off = (unsigned long)&txq_mem->cur_q_entry_hi;
+ writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off);
+
+ off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr;
+ writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off);
+
+ off = (unsigned long)&txq_mem->entry_n_pg_size;
+ writel(txq_cfg.entry_n_pg_size, base_addr + off);
+
+ off = (unsigned long)&txq_mem->int_blk_n_cns_ptr;
+ writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off);
+
+ off = (unsigned long)&txq_mem->cns_ptr2_n_q_state;
+ writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off);
+
+ off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri;
+ writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off);
+
+ off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota;
+ writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off);
+
+ txq->tcb->producer_index = 0;
+ txq->tcb->consumer_index = 0;
+ *(txq->tcb->hw_consumer_index) = 0;
+
+}
+
+static void
+__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq)
+{
+ struct bfi_ll_q_stop_req ll_req;
+ u32 bit_mask[2] = {0, 0};
+ if (txq->txq_id < 32)
+ bit_mask[0] = (u32)1 << txq->txq_id;
+ else
+ bit_mask[1] = (u32)1 << (txq->txq_id - 32);
+
+ memset(&ll_req, 0, sizeof(ll_req));
+ ll_req.mh.msg_class = BFI_MC_LL;
+ ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ;
+ ll_req.mh.mtag.h2i.lpu_id = 0;
+ ll_req.q_id_mask[0] = htonl(bit_mask[0]);
+ ll_req.q_id_mask[1] = htonl(bit_mask[1]);
+
+ bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_tx_cb_txq_stopped, tx);
+
+ bna_mbox_send(tx->bna, &tx->mbox_qe);
+}
+
+static void
+__bna_txf_start(struct bna_tx *tx)
+{
+ struct bna_tx_fndb_ram *tx_fndb;
+ struct bna_txf *txf = &tx->txf;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET),
+ tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ TX_FNDB_RAM_BASE_OFFSET);
+
+ tx_fndb = (struct bna_tx_fndb_ram *)0;
+ off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
+
+ writel(((u32)txf->vlan << 16) | txf->ctrl_flags,
+ base_addr + off);
+
+ if (tx->txf.txf_id < 32)
+ tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id);
+ else
+ tx->bna->tx_mod.txf_bmap[1] |= ((u32)
+ 1 << (tx->txf.txf_id - 32));
+}
+
+static void
+__bna_txf_stop(struct bna_tx *tx)
+{
+ struct bna_tx_fndb_ram *tx_fndb;
+ u32 page_num;
+ u32 ctl_flags;
+ struct bna_txf *txf = &tx->txf;
+ void __iomem *base_addr;
+ unsigned long off;
+
+ /* retrieve the running txf_flags & turn off enable bit */
+ page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
+ (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET);
+ writel(page_num, tx->bna->regs.page_addr);
+
+ base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
+ TX_FNDB_RAM_BASE_OFFSET);
+ tx_fndb = (struct bna_tx_fndb_ram *)0;
+ off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;
+
+ ctl_flags = readl(base_addr + off);
+ ctl_flags &= ~BFI_TXF_CF_ENABLE;
+
+ writel(ctl_flags, base_addr + off);
+
+ if (tx->txf.txf_id < 32)
+ tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id);
+ else
+ tx->bna->tx_mod.txf_bmap[0] &= ~((u32)
+ 1 << (tx->txf.txf_id - 32));
+}
+
+static void
+__bna_txf_stat_clr(struct bna_tx *tx)
+{
+ struct bfi_ll_stats_req ll_req;
+ u32 txf_bmap[2] = {0, 0};
+ if (tx->txf.txf_id < 32)
+ txf_bmap[0] = ((u32)1 << tx->txf.txf_id);
+ else
+ txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32));
+ bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
+ ll_req.stats_mask = 0;
+ ll_req.rxf_id_mask[0] = 0;
+ ll_req.rxf_id_mask[1] = 0;
+ ll_req.txf_id_mask[0] = htonl(txf_bmap[0]);
+ ll_req.txf_id_mask[1] = htonl(txf_bmap[1]);
+
+ bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
+ bna_tx_cb_stats_cleared, tx);
+ bna_mbox_send(tx->bna, &tx->mbox_qe);
+}
+
+static void
+__bna_tx_start(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bna_ib_start(txq->ib);
+ __bna_txq_start(tx, txq);
+ }
+
+ __bna_txf_start(tx);
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->tcb->priority = txq->priority;
+ (tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+}
+
+static void
+__bna_tx_stop(struct bna_tx *tx)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+
+ __bna_txf_stop(tx);
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ bfa_wc_up(&tx->txq_stop_wc);
+ }
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ __bna_txq_stop(tx, txq);
+ }
+}
+
+static void
+bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
+ struct bna_mem_descr *qpt_mem,
+ struct bna_mem_descr *swqpt_mem,
+ struct bna_mem_descr *page_mem)
+{
+ int i;
+
+ txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
+ txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
+ txq->qpt.kv_qpt_ptr = qpt_mem->kva;
+ txq->qpt.page_count = page_count;
+ txq->qpt.page_size = page_size;
+
+ txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
+
+ for (i = 0; i < page_count; i++) {
+ txq->tcb->sw_qpt[i] = page_mem[i].kva;
+
+ ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
+ page_mem[i].dma.lsb;
+ ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
+ page_mem[i].dma.msb;
+
+ }
+}
+
+static void
+bna_tx_free(struct bna_tx *tx)
+{
+ struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
+ struct bna_txq *txq;
+ struct bna_ib_mod *ib_mod = &tx->bna->ib_mod;
+ struct list_head *qe;
+
+ while (!list_empty(&tx->txq_q)) {
+ bfa_q_deq(&tx->txq_q, &txq);
+ bfa_q_qe_init(&txq->qe);
+ if (txq->ib) {
+ if (txq->ib_seg_offset != -1)
+ bna_ib_release_idx(txq->ib,
+ txq->ib_seg_offset);
+ bna_ib_put(ib_mod, txq->ib);
+ txq->ib = NULL;
+ }
+ txq->tcb = NULL;
+ txq->tx = NULL;
+ list_add_tail(&txq->qe, &tx_mod->txq_free_q);
+ }
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ if (qe == &tx->qe) {
+ list_del(&tx->qe);
+ bfa_q_qe_init(&tx->qe);
+ break;
+ }
+ }
+
+ tx->bna = NULL;
+ tx->priv = NULL;
+ list_add_tail(&tx->qe, &tx_mod->tx_free_q);
+}
+
+static void
+bna_tx_cb_txq_stopped(void *arg, int status)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+ bfa_wc_down(&tx->txq_stop_wc);
+}
+
+static void
+bna_tx_cb_txq_stopped_all(void *arg)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED);
+}
+
+static void
+bna_tx_cb_stats_cleared(void *arg, int status)
+{
+ struct bna_tx *tx = (struct bna_tx *)arg;
+
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+
+ bfa_fsm_send_event(tx, TX_E_STAT_CLEARED);
+}
+
+static void
+bna_tx_start(struct bna_tx *tx)
+{
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ if (tx->flags & BNA_TX_F_ENABLED)
+ bfa_fsm_send_event(tx, TX_E_START);
+}
+
+static void
+bna_tx_stop(struct bna_tx *tx)
+{
+ tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
+ tx->stop_cbarg = &tx->bna->tx_mod;
+
+ tx->flags &= ~BNA_TX_F_PORT_STARTED;
+ bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+static void
+bna_tx_fail(struct bna_tx *tx)
+{
+ tx->flags &= ~BNA_TX_F_PORT_STARTED;
+ bfa_fsm_send_event(tx, TX_E_FAIL);
+}
+
+void
+bna_tx_prio_changed(struct bna_tx *tx, int prio)
+{
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->priority = prio;
+ }
+
+ bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE);
+}
+
+static void
+bna_tx_cee_link_status(struct bna_tx *tx, int cee_link)
+{
+ if (cee_link)
+ tx->flags |= BNA_TX_F_PRIO_LOCK;
+ else
+ tx->flags &= ~BNA_TX_F_PRIO_LOCK;
+}
+
+static void
+bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status)
+{
+ struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+ bfa_wc_down(&tx_mod->tx_stop_wc);
+}
+
+static void
+bna_tx_mod_cb_tx_stopped_all(void *arg)
+{
+ struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
+
+ if (tx_mod->stop_cbfn)
+ tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
+ tx_mod->stop_cbfn = NULL;
+}
+
+void
+bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
+{
+ u32 q_size;
+ u32 page_count;
+ struct bna_mem_info *mem_info;
+
+ res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = sizeof(struct bna_tcb);
+ mem_info->num = num_txq;
+
+ q_size = txq_depth * BFI_TXQ_WI_SIZE;
+ q_size = ALIGN(q_size, PAGE_SIZE);
+ page_count = q_size >> PAGE_SHIFT;
+
+ res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = page_count * sizeof(struct bna_dma_addr);
+ mem_info->num = num_txq;
+
+ res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_KVA;
+ mem_info->len = page_count * sizeof(void *);
+ mem_info->num = num_txq;
+
+ res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
+ mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
+ mem_info->mem_type = BNA_MEM_T_DMA;
+ mem_info->len = PAGE_SIZE;
+ mem_info->num = num_txq * page_count;
+
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
+ BNA_INTR_T_MSIX;
+ res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
+}
+
+struct bna_tx *
+bna_tx_create(struct bna *bna, struct bnad *bnad,
+ struct bna_tx_config *tx_cfg,
+ struct bna_tx_event_cbfn *tx_cbfn,
+ struct bna_res_info *res_info, void *priv)
+{
+ struct bna_intr_info *intr_info;
+ struct bna_tx_mod *tx_mod = &bna->tx_mod;
+ struct bna_tx *tx;
+ struct bna_txq *txq;
+ struct list_head *qe;
+ struct bna_ib_mod *ib_mod = &bna->ib_mod;
+ struct bna_doorbell_qset *qset;
+ struct bna_ib_config ib_config;
+ int page_count;
+ int page_size;
+ int page_idx;
+ int i;
+ unsigned long off;
+
+ intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
+ page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) /
+ tx_cfg->num_txq;
+ page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;
+
+ /**
+ * Get resources
+ */
+
+ if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
+ return NULL;
+
+ /* Tx */
+
+ if (list_empty(&tx_mod->tx_free_q))
+ return NULL;
+ bfa_q_deq(&tx_mod->tx_free_q, &tx);
+ bfa_q_qe_init(&tx->qe);
+
+ /* TxQs */
+
+ INIT_LIST_HEAD(&tx->txq_q);
+ for (i = 0; i < tx_cfg->num_txq; i++) {
+ if (list_empty(&tx_mod->txq_free_q))
+ goto err_return;
+
+ bfa_q_deq(&tx_mod->txq_free_q, &txq);
+ bfa_q_qe_init(&txq->qe);
+ list_add_tail(&txq->qe, &tx->txq_q);
+ txq->ib = NULL;
+ txq->ib_seg_offset = -1;
+ txq->tx = tx;
+ }
+
+ /* IBs */
+ i = 0;
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+
+ if (intr_info->num == 1)
+ txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
+ intr_info->idl[0].vector);
+ else
+ txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
+ intr_info->idl[i].vector);
+
+ if (txq->ib == NULL)
+ goto err_return;
+
+ txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib);
+ if (txq->ib_seg_offset == -1)
+ goto err_return;
+
+ i++;
+ }
+
+ /*
+ * Initialize
+ */
+
+ /* Tx */
+
+ tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
+ tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
+ /* Following callbacks are mandatory */
+ tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
+ tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
+ tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;
+
+ list_add_tail(&tx->qe, &tx_mod->tx_active_q);
+ tx->bna = bna;
+ tx->priv = priv;
+ tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all;
+ tx->txq_stop_wc.wc_cbarg = tx;
+ tx->txq_stop_wc.wc_count = 0;
+
+ tx->type = tx_cfg->tx_type;
+
+ tx->flags = 0;
+ if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) {
+ switch (tx->type) {
+ case BNA_TX_T_REGULAR:
+ if (!(tx->bna->tx_mod.flags &
+ BNA_TX_MOD_F_PORT_LOOPBACK))
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ break;
+ case BNA_TX_T_LOOPBACK:
+ if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK)
+ tx->flags |= BNA_TX_F_PORT_STARTED;
+ break;
+ }
+ }
+ if (tx->bna->tx_mod.cee_link)
+ tx->flags |= BNA_TX_F_PRIO_LOCK;
+
+ /* TxQ */
+
+ i = 0;
+ page_idx = 0;
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ txq->priority = tx_mod->priority;
+ txq->tcb = (struct bna_tcb *)
+ res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
+ txq->tx_packets = 0;
+ txq->tx_bytes = 0;
+
+ /* IB */
+
+ ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO;
+ ib_config.interpkt_timeo = 0; /* Not used */
+ ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT;
+ ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA |
+ BFI_IB_CF_INT_ENABLE |
+ BFI_IB_CF_COALESCING_MODE);
+ bna_ib_config(txq->ib, &ib_config);
+
+ /* TCB */
+
+ txq->tcb->producer_index = 0;
+ txq->tcb->consumer_index = 0;
+ txq->tcb->hw_consumer_index = (volatile u32 *)
+ ((volatile u8 *)txq->ib->ib_seg_host_addr_kva +
+ (txq->ib_seg_offset * BFI_IBIDX_SIZE));
+ *(txq->tcb->hw_consumer_index) = 0;
+ txq->tcb->q_depth = tx_cfg->txq_depth;
+ txq->tcb->unmap_q = (void *)
+ res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
+ qset = (struct bna_doorbell_qset *)0;
+ off = (unsigned long)&qset[txq->txq_id].txq[0];
+ txq->tcb->q_dbell = off +
+ BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
+ txq->tcb->i_dbell = &txq->ib->door_bell;
+ txq->tcb->intr_type = intr_info->intr_type;
+ txq->tcb->intr_vector = (intr_info->num == 1) ?
+ intr_info->idl[0].vector :
+ intr_info->idl[i].vector;
+ txq->tcb->txq = txq;
+ txq->tcb->bnad = bnad;
+ txq->tcb->id = i;
+
+ /* QPT, SWQPT, Pages */
+ bna_txq_qpt_setup(txq, page_count, page_size,
+ &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
+ &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
+ &res_info[BNA_TX_RES_MEM_T_PAGE].
+ res_u.mem_info.mdl[page_idx]);
+ txq->tcb->page_idx = page_idx;
+ txq->tcb->page_count = page_count;
+ page_idx += page_count;
+
+ /* Callback to bnad for setting up TCB */
+ if (tx->tcb_setup_cbfn)
+ (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);
+
+ i++;
+ }
+
+ /* TxF */
+
+ tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED;
+ tx->txf.vlan = 0;
+
+ /* Mbox element */
+ bfa_q_qe_init(&tx->mbox_qe.qe);
+
+ bfa_fsm_set_state(tx, bna_tx_sm_stopped);
+
+ return tx;
+
+err_return:
+ bna_tx_free(tx);
+ return NULL;
+}
+
+void
+bna_tx_destroy(struct bna_tx *tx)
+{
+ /* Callback to bnad for destroying TCB */
+ if (tx->tcb_destroy_cbfn) {
+ struct bna_txq *txq;
+ struct list_head *qe;
+
+ list_for_each(qe, &tx->txq_q) {
+ txq = (struct bna_txq *)qe;
+ (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
+ }
+ }
+
+ bna_tx_free(tx);
+}
+
+void
+bna_tx_enable(struct bna_tx *tx)
+{
+ if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped)
+ return;
+
+ tx->flags |= BNA_TX_F_ENABLED;
+
+ if (tx->flags & BNA_TX_F_PORT_STARTED)
+ bfa_fsm_send_event(tx, TX_E_START);
+}
+
+void
+bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
+ void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status))
+{
+ if (type == BNA_SOFT_CLEANUP) {
+ (*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS);
+ return;
+ }
+
+ tx->stop_cbfn = cbfn;
+ tx->stop_cbarg = tx->bna->bnad;
+
+ tx->flags &= ~BNA_TX_F_ENABLED;
+
+ bfa_fsm_send_event(tx, TX_E_STOP);
+}
+
+int
+bna_tx_state_get(struct bna_tx *tx)
+{
+ return bfa_sm_to_state(tx_sm_table, tx->fsm);
+}
+
+void
+bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
+ struct bna_res_info *res_info)
+{
+ int i;
+
+ tx_mod->bna = bna;
+ tx_mod->flags = 0;
+
+ tx_mod->tx = (struct bna_tx *)
+ res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
+ tx_mod->txq = (struct bna_txq *)
+ res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;
+
+ INIT_LIST_HEAD(&tx_mod->tx_free_q);
+ INIT_LIST_HEAD(&tx_mod->tx_active_q);
+
+ INIT_LIST_HEAD(&tx_mod->txq_free_q);
+
+ for (i = 0; i < BFI_MAX_TXQ; i++) {
+ tx_mod->tx[i].txf.txf_id = i;
+ bfa_q_qe_init(&tx_mod->tx[i].qe);
+ list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);
+
+ tx_mod->txq[i].txq_id = i;
+ bfa_q_qe_init(&tx_mod->txq[i].qe);
+ list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
+ }
+
+ tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all;
+ tx_mod->tx_stop_wc.wc_cbarg = tx_mod;
+ tx_mod->tx_stop_wc.wc_count = 0;
+}
+
+void
+bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
+{
+ struct list_head *qe;
+ int i;
+
+ i = 0;
+ list_for_each(qe, &tx_mod->tx_free_q)
+ i++;
+
+ i = 0;
+ list_for_each(qe, &tx_mod->txq_free_q)
+ i++;
+
+ tx_mod->bna = NULL;
+}
+
+void
+bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED;
+ if (type == BNA_TX_T_LOOPBACK)
+ tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bna_tx_start(tx);
+ }
+}
+
+void
+bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ tx_mod->stop_cbfn = bna_port_cb_tx_stopped;
+
+ /**
+ * Before calling bna_tx_stop(), increment tx_stop_wc as many times
+ * as we are going to call bna_tx_stop
+ */
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bfa_wc_up(&tx_mod->tx_stop_wc);
+ }
+
+ if (tx_mod->tx_stop_wc.wc_count == 0) {
+ tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
+ tx_mod->stop_cbfn = NULL;
+ return;
+ }
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ if (tx->type == type)
+ bna_tx_stop(tx);
+ }
+}
+
+void
+bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
+ tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_fail(tx);
+ }
+}
+
+void
+bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ if (prio != tx_mod->priority) {
+ tx_mod->priority = prio;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_prio_changed(tx, prio);
+ }
+ }
+}
+
+void
+bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link)
+{
+ struct bna_tx *tx;
+ struct list_head *qe;
+
+ tx_mod->cee_link = cee_link;
+
+ list_for_each(qe, &tx_mod->tx_active_q) {
+ tx = (struct bna_tx *)qe;
+ bna_tx_cee_link_status(tx, cee_link);
+ }
+}
diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h
new file mode 100644
index 000000000000..6877310f6ef4
--- /dev/null
+++ b/drivers/net/bna/bna_types.h
@@ -0,0 +1,1128 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BNA_TYPES_H__
+#define __BNA_TYPES_H__
+
+#include "cna.h"
+#include "bna_hw.h"
+#include "bfa_cee.h"
+
+/**
+ *
+ * Forward declarations
+ *
+ */
+
+struct bna_txq;
+struct bna_tx;
+struct bna_rxq;
+struct bna_cq;
+struct bna_rx;
+struct bna_rxf;
+struct bna_port;
+struct bna;
+struct bnad;
+
+/**
+ *
+ * Enums, primitive data types
+ *
+ */
+
+enum bna_status {
+ BNA_STATUS_T_DISABLED = 0,
+ BNA_STATUS_T_ENABLED = 1
+};
+
+enum bna_cleanup_type {
+ BNA_HARD_CLEANUP = 0,
+ BNA_SOFT_CLEANUP = 1
+};
+
+enum bna_cb_status {
+ BNA_CB_SUCCESS = 0,
+ BNA_CB_FAIL = 1,
+ BNA_CB_INTERRUPT = 2,
+ BNA_CB_BUSY = 3,
+ BNA_CB_INVALID_MAC = 4,
+ BNA_CB_MCAST_LIST_FULL = 5,
+ BNA_CB_UCAST_CAM_FULL = 6,
+ BNA_CB_WAITING = 7,
+ BNA_CB_NOT_EXEC = 8
+};
+
+enum bna_res_type {
+ BNA_RES_T_MEM = 1,
+ BNA_RES_T_INTR = 2
+};
+
+enum bna_mem_type {
+ BNA_MEM_T_KVA = 1,
+ BNA_MEM_T_DMA = 2
+};
+
+enum bna_intr_type {
+ BNA_INTR_T_INTX = 1,
+ BNA_INTR_T_MSIX = 2
+};
+
+enum bna_res_req_type {
+ BNA_RES_MEM_T_COM = 0,
+ BNA_RES_MEM_T_ATTR = 1,
+ BNA_RES_MEM_T_FWTRC = 2,
+ BNA_RES_MEM_T_STATS = 3,
+ BNA_RES_MEM_T_SWSTATS = 4,
+ BNA_RES_MEM_T_IBIDX = 5,
+ BNA_RES_MEM_T_IB_ARRAY = 6,
+ BNA_RES_MEM_T_INTR_ARRAY = 7,
+ BNA_RES_MEM_T_IDXSEG_ARRAY = 8,
+ BNA_RES_MEM_T_TX_ARRAY = 9,
+ BNA_RES_MEM_T_TXQ_ARRAY = 10,
+ BNA_RES_MEM_T_RX_ARRAY = 11,
+ BNA_RES_MEM_T_RXP_ARRAY = 12,
+ BNA_RES_MEM_T_RXQ_ARRAY = 13,
+ BNA_RES_MEM_T_UCMAC_ARRAY = 14,
+ BNA_RES_MEM_T_MCMAC_ARRAY = 15,
+ BNA_RES_MEM_T_RIT_ENTRY = 16,
+ BNA_RES_MEM_T_RIT_SEGMENT = 17,
+ BNA_RES_INTR_T_MBOX = 18,
+ BNA_RES_T_MAX
+};
+
+enum bna_tx_res_req_type {
+ BNA_TX_RES_MEM_T_TCB = 0,
+ BNA_TX_RES_MEM_T_UNMAPQ = 1,
+ BNA_TX_RES_MEM_T_QPT = 2,
+ BNA_TX_RES_MEM_T_SWQPT = 3,
+ BNA_TX_RES_MEM_T_PAGE = 4,
+ BNA_TX_RES_INTR_T_TXCMPL = 5,
+ BNA_TX_RES_T_MAX,
+};
+
+enum bna_rx_mem_type {
+ BNA_RX_RES_MEM_T_CCB = 0, /* CQ context */
+ BNA_RX_RES_MEM_T_RCB = 1, /* CQ context */
+ BNA_RX_RES_MEM_T_UNMAPQ = 2, /* UnmapQ for RxQs */
+ BNA_RX_RES_MEM_T_CQPT = 3, /* CQ QPT */
+ BNA_RX_RES_MEM_T_CSWQPT = 4, /* S/W QPT */
+ BNA_RX_RES_MEM_T_CQPT_PAGE = 5, /* CQPT page */
+ BNA_RX_RES_MEM_T_HQPT = 6, /* RX QPT */
+ BNA_RX_RES_MEM_T_DQPT = 7, /* RX QPT */
+ BNA_RX_RES_MEM_T_HSWQPT = 8, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_DSWQPT = 9, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_DPAGE = 10, /* RX s/w QPT */
+ BNA_RX_RES_MEM_T_HPAGE = 11, /* RX s/w QPT */
+ BNA_RX_RES_T_INTR = 12, /* Rx interrupts */
+ BNA_RX_RES_T_MAX = 13
+};
+
+enum bna_mbox_state {
+ BNA_MBOX_FREE = 0,
+ BNA_MBOX_POSTED = 1
+};
+
+enum bna_tx_type {
+ BNA_TX_T_REGULAR = 0,
+ BNA_TX_T_LOOPBACK = 1,
+};
+
+enum bna_tx_flags {
+ BNA_TX_F_PORT_STARTED = 1,
+ BNA_TX_F_ENABLED = 2,
+ BNA_TX_F_PRIO_LOCK = 4,
+};
+
+enum bna_tx_mod_flags {
+ BNA_TX_MOD_F_PORT_STARTED = 1,
+ BNA_TX_MOD_F_PORT_LOOPBACK = 2,
+};
+
+enum bna_rx_type {
+ BNA_RX_T_REGULAR = 0,
+ BNA_RX_T_LOOPBACK = 1,
+};
+
+enum bna_rxp_type {
+ BNA_RXP_SINGLE = 1,
+ BNA_RXP_SLR = 2,
+ BNA_RXP_HDS = 3
+};
+
+enum bna_rxmode {
+ BNA_RXMODE_PROMISC = 1,
+ BNA_RXMODE_DEFAULT = 2,
+ BNA_RXMODE_ALLMULTI = 4
+};
+
+enum bna_rx_event {
+ RX_E_START = 1,
+ RX_E_STOP = 2,
+ RX_E_FAIL = 3,
+ RX_E_RXF_STARTED = 4,
+ RX_E_RXF_STOPPED = 5,
+ RX_E_RXQ_STOPPED = 6,
+};
+
+enum bna_rx_state {
+ BNA_RX_STOPPED = 1,
+ BNA_RX_RXF_START_WAIT = 2,
+ BNA_RX_STARTED = 3,
+ BNA_RX_RXF_STOP_WAIT = 4,
+ BNA_RX_RXQ_STOP_WAIT = 5,
+};
+
+enum bna_rx_flags {
+ BNA_RX_F_ENABLE = 0x01, /* bnad enabled rxf */
+ BNA_RX_F_PORT_ENABLED = 0x02, /* Port object is enabled */
+ BNA_RX_F_PORT_FAILED = 0x04, /* Port in failed state */
+};
+
+enum bna_rx_mod_flags {
+ BNA_RX_MOD_F_PORT_STARTED = 1,
+ BNA_RX_MOD_F_PORT_LOOPBACK = 2,
+};
+
+enum bna_rxf_oper_state {
+ BNA_RXF_OPER_STATE_RUNNING = 0x01, /* rxf operational */
+ BNA_RXF_OPER_STATE_PAUSED = 0x02, /* rxf in PAUSED state */
+};
+
+enum bna_rxf_flags {
+ BNA_RXF_FL_STOP_PENDING = 0x01,
+ BNA_RXF_FL_FAILED = 0x02,
+ BNA_RXF_FL_RSS_CONFIG_PENDING = 0x04,
+ BNA_RXF_FL_OPERSTATE_CHANGED = 0x08,
+ BNA_RXF_FL_RXF_ENABLED = 0x10,
+ BNA_RXF_FL_VLAN_CONFIG_PENDING = 0x20,
+};
+
+enum bna_rxf_event {
+ RXF_E_START = 1,
+ RXF_E_STOP = 2,
+ RXF_E_FAIL = 3,
+ RXF_E_CAM_FLTR_MOD = 4,
+ RXF_E_STARTED = 5,
+ RXF_E_STOPPED = 6,
+ RXF_E_CAM_FLTR_RESP = 7,
+ RXF_E_PAUSE = 8,
+ RXF_E_RESUME = 9,
+ RXF_E_STAT_CLEARED = 10,
+};
+
+enum bna_rxf_state {
+ BNA_RXF_STOPPED = 1,
+ BNA_RXF_START_WAIT = 2,
+ BNA_RXF_CAM_FLTR_MOD_WAIT = 3,
+ BNA_RXF_STARTED = 4,
+ BNA_RXF_CAM_FLTR_CLR_WAIT = 5,
+ BNA_RXF_STOP_WAIT = 6,
+ BNA_RXF_PAUSE_WAIT = 7,
+ BNA_RXF_RESUME_WAIT = 8,
+ BNA_RXF_STAT_CLR_WAIT = 9,
+};
+
+enum bna_port_type {
+ BNA_PORT_T_REGULAR = 0,
+ BNA_PORT_T_LOOPBACK_INTERNAL = 1,
+ BNA_PORT_T_LOOPBACK_EXTERNAL = 2,
+};
+
+enum bna_link_status {
+ BNA_LINK_DOWN = 0,
+ BNA_LINK_UP = 1,
+ BNA_CEE_UP = 2
+};
+
+enum bna_llport_flags {
+ BNA_LLPORT_F_ENABLED = 1,
+ BNA_LLPORT_F_RX_ENABLED = 2
+};
+
+enum bna_port_flags {
+ BNA_PORT_F_DEVICE_READY = 1,
+ BNA_PORT_F_ENABLED = 2,
+ BNA_PORT_F_PAUSE_CHANGED = 4,
+ BNA_PORT_F_MTU_CHANGED = 8
+};
+
+enum bna_pkt_rates {
+ BNA_PKT_RATE_10K = 10000,
+ BNA_PKT_RATE_20K = 20000,
+ BNA_PKT_RATE_30K = 30000,
+ BNA_PKT_RATE_40K = 40000,
+ BNA_PKT_RATE_50K = 50000,
+ BNA_PKT_RATE_60K = 60000,
+ BNA_PKT_RATE_70K = 70000,
+ BNA_PKT_RATE_80K = 80000,
+};
+
+enum bna_dim_load_types {
+ BNA_LOAD_T_HIGH_4 = 0, /* 80K <= r */
+ BNA_LOAD_T_HIGH_3 = 1, /* 60K <= r < 80K */
+ BNA_LOAD_T_HIGH_2 = 2, /* 50K <= r < 60K */
+ BNA_LOAD_T_HIGH_1 = 3, /* 40K <= r < 50K */
+ BNA_LOAD_T_LOW_1 = 4, /* 30K <= r < 40K */
+ BNA_LOAD_T_LOW_2 = 5, /* 20K <= r < 30K */
+ BNA_LOAD_T_LOW_3 = 6, /* 10K <= r < 20K */
+ BNA_LOAD_T_LOW_4 = 7, /* r < 10K */
+ BNA_LOAD_T_MAX = 8
+};
+
+enum bna_dim_bias_types {
+ BNA_BIAS_T_SMALL = 0, /* small pkts > (large pkts * 2) */
+ BNA_BIAS_T_LARGE = 1, /* Not BNA_BIAS_T_SMALL */
+ BNA_BIAS_T_MAX = 2
+};
+
+struct bna_mac {
+ /* This should be the first one */
+ struct list_head qe;
+ u8 addr[ETH_ALEN];
+};
+
+struct bna_mem_descr {
+ u32 len;
+ void *kva;
+ struct bna_dma_addr dma;
+};
+
+struct bna_mem_info {
+ enum bna_mem_type mem_type;
+ u32 len;
+ u32 num;
+ u32 align_sz; /* 0/1 = no alignment */
+ struct bna_mem_descr *mdl;
+ void *cookie; /* For bnad to unmap dma later */
+};
+
+struct bna_intr_descr {
+ int vector;
+};
+
+struct bna_intr_info {
+ enum bna_intr_type intr_type;
+ int num;
+ struct bna_intr_descr *idl;
+};
+
+union bna_res_u {
+ struct bna_mem_info mem_info;
+ struct bna_intr_info intr_info;
+};
+
+struct bna_res_info {
+ enum bna_res_type res_type;
+ union bna_res_u res_u;
+};
+
+/* HW QPT */
+struct bna_qpt {
+ struct bna_dma_addr hw_qpt_ptr;
+ void *kv_qpt_ptr;
+ u32 page_count;
+ u32 page_size;
+};
+
+/**
+ *
+ * Device
+ *
+ */
+
+struct bna_device {
+ bfa_fsm_t fsm;
+ struct bfa_ioc ioc;
+
+ enum bna_intr_type intr_type;
+ int vector;
+
+ void (*ready_cbfn)(struct bnad *bnad, enum bna_cb_status status);
+ struct bnad *ready_cbarg;
+
+ void (*stop_cbfn)(struct bnad *bnad, enum bna_cb_status status);
+ struct bnad *stop_cbarg;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Mail box
+ *
+ */
+
+struct bna_mbox_qe {
+ /* This should be the first one */
+ struct list_head qe;
+
+ struct bfa_mbox_cmd cmd;
+ u32 cmd_len;
+ /* Callback for port, tx, rx, rxf */
+ void (*cbfn)(void *arg, int status);
+ void *cbarg;
+};
+
+struct bna_mbox_mod {
+ enum bna_mbox_state state;
+ struct list_head posted_q;
+ u32 msg_pending;
+ u32 msg_ctr;
+ struct bna *bna;
+};
+
+/**
+ *
+ * Port
+ *
+ */
+
+/* Pause configuration */
+struct bna_pause_config {
+ enum bna_status tx_pause;
+ enum bna_status rx_pause;
+};
+
+struct bna_llport {
+ bfa_fsm_t fsm;
+ enum bna_llport_flags flags;
+
+ enum bna_port_type type;
+
+ enum bna_link_status link_status;
+
+ int admin_up_count;
+
+ void (*stop_cbfn)(struct bna_port *, enum bna_cb_status);
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+};
+
+struct bna_port {
+ bfa_fsm_t fsm;
+ enum bna_port_flags flags;
+
+ enum bna_port_type type;
+
+ struct bna_llport llport;
+
+ struct bna_pause_config pause_config;
+ u8 priority;
+ int mtu;
+
+ /* Callback for bna_port_disable(), port_stop() */
+ void (*stop_cbfn)(void *, enum bna_cb_status);
+ void *stop_cbarg;
+
+ /* Callback for bna_port_pause_config() */
+ void (*pause_cbfn)(struct bnad *, enum bna_cb_status);
+
+ /* Callback for bna_port_mtu_set() */
+ void (*mtu_cbfn)(struct bnad *, enum bna_cb_status);
+
+ void (*link_cbfn)(struct bnad *, enum bna_link_status);
+
+ struct bfa_wc chld_stop_wc;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Interrupt Block
+ *
+ */
+
+/* IB index segment structure */
+struct bna_ibidx_seg {
+ /* This should be the first one */
+ struct list_head qe;
+
+ u8 ib_seg_size;
+ u8 ib_idx_tbl_offset;
+};
+
+/* Interrupt structure */
+struct bna_intr {
+ /* This should be the first one */
+ struct list_head qe;
+ int ref_count;
+
+ enum bna_intr_type intr_type;
+ int vector;
+
+ struct bna_ib *ib;
+};
+
+/* Doorbell structure */
+struct bna_ib_dbell {
+ void *__iomem doorbell_addr;
+ u32 doorbell_ack;
+};
+
+/* Interrupt timer configuration */
+struct bna_ib_config {
+ u8 coalescing_timeo; /* Unit is 5usec. */
+
+ int interpkt_count;
+ int interpkt_timeo;
+
+ enum ib_flags ctrl_flags;
+};
+
+/* IB structure */
+struct bna_ib {
+ /* This should be the first one */
+ struct list_head qe;
+
+ int ib_id;
+
+ int ref_count;
+ int start_count;
+
+ struct bna_dma_addr ib_seg_host_addr;
+ void *ib_seg_host_addr_kva;
+ u32 idx_mask; /* Size >= BNA_IBIDX_MAX_SEGSIZE */
+
+ struct bna_ibidx_seg *idx_seg;
+
+ struct bna_ib_dbell door_bell;
+
+ struct bna_intr *intr;
+
+ struct bna_ib_config ib_config;
+
+ struct bna *bna;
+};
+
+/* IB module - keeps track of IBs and interrupts */
+struct bna_ib_mod {
+ struct bna_ib *ib; /* BFI_MAX_IB entries */
+ struct bna_intr *intr; /* BFI_MAX_IB entries */
+ struct bna_ibidx_seg *idx_seg; /* BNA_IBIDX_TOTAL_SEGS */
+
+ struct list_head ib_free_q;
+
+ struct list_head ibidx_seg_pool[BFI_IBIDX_TOTAL_POOLS];
+
+ struct list_head intr_free_q;
+ struct list_head intr_active_q;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Tx object
+ *
+ */
+
+/* Tx datapath control structure */
+#define BNA_Q_NAME_SIZE 16
+struct bna_tcb {
+ /* Fast path */
+ void **sw_qpt;
+ void *unmap_q;
+ u32 producer_index;
+ u32 consumer_index;
+ volatile u32 *hw_consumer_index;
+ u32 q_depth;
+ void *__iomem q_dbell;
+ struct bna_ib_dbell *i_dbell;
+ int page_idx;
+ int page_count;
+ /* Control path */
+ struct bna_txq *txq;
+ struct bnad *bnad;
+ enum bna_intr_type intr_type;
+ int intr_vector;
+ u8 priority; /* Current priority */
+ unsigned long flags; /* Used by bnad as required */
+ int id;
+ char name[BNA_Q_NAME_SIZE];
+};
+
+/* TxQ QPT and configuration */
+struct bna_txq {
+ /* This should be the first one */
+ struct list_head qe;
+
+ int txq_id;
+
+ u8 priority;
+
+ struct bna_qpt qpt;
+ struct bna_tcb *tcb;
+ struct bna_ib *ib;
+ int ib_seg_offset;
+
+ struct bna_tx *tx;
+
+ u64 tx_packets;
+ u64 tx_bytes;
+};
+
+/* TxF structure (hardware Tx Function) */
+struct bna_txf {
+ int txf_id;
+ enum txf_flags ctrl_flags;
+ u16 vlan;
+};
+
+/* Tx object */
+struct bna_tx {
+ /* This should be the first one */
+ struct list_head qe;
+
+ bfa_fsm_t fsm;
+ enum bna_tx_flags flags;
+
+ enum bna_tx_type type;
+
+ struct list_head txq_q;
+ struct bna_txf txf;
+
+ /* Tx event handlers */
+ void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+
+ /* callback for bna_tx_disable(), bna_tx_stop() */
+ void (*stop_cbfn)(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status);
+ void *stop_cbarg;
+
+ /* callback for bna_tx_prio_set() */
+ void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx,
+ enum bna_cb_status status);
+
+ struct bfa_wc txq_stop_wc;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bna *bna;
+ void *priv; /* bnad's cookie */
+};
+
+struct bna_tx_config {
+ int num_txq;
+ int txq_depth;
+ enum bna_tx_type tx_type;
+};
+
+struct bna_tx_event_cbfn {
+ /* Optional */
+ void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *);
+ /* Mandatory */
+ void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *);
+ void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *);
+};
+
+/* Tx module - keeps track of free, active tx objects */
+struct bna_tx_mod {
+ struct bna_tx *tx; /* BFI_MAX_TXQ entries */
+ struct bna_txq *txq; /* BFI_MAX_TXQ entries */
+
+ struct list_head tx_free_q;
+ struct list_head tx_active_q;
+
+ struct list_head txq_free_q;
+
+ /* callback for bna_tx_mod_stop() */
+ void (*stop_cbfn)(struct bna_port *port,
+ enum bna_cb_status status);
+
+ struct bfa_wc tx_stop_wc;
+
+ enum bna_tx_mod_flags flags;
+
+ int priority;
+ int cee_link;
+
+ u32 txf_bmap[2];
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Receive Indirection Table
+ *
+ */
+
+/* One row of RIT table */
+struct bna_rit_entry {
+ u8 large_rxq_id; /* used for either large or data buffers */
+ u8 small_rxq_id; /* used for either small or header buffers */
+};
+
+/* RIT segment */
+struct bna_rit_segment {
+ struct list_head qe;
+
+ u32 rit_offset;
+ u32 rit_size;
+ /**
+ * max_rit_size: Varies per RIT segment depending on how RIT is
+ * partitioned
+ */
+ u32 max_rit_size;
+
+ struct bna_rit_entry *rit;
+};
+
+struct bna_rit_mod {
+ struct bna_rit_entry *rit;
+ struct bna_rit_segment *rit_segment;
+
+ struct list_head rit_seg_pool[BFI_RIT_SEG_TOTAL_POOLS];
+};
+
+/**
+ *
+ * Rx object
+ *
+ */
+
+/* Rx datapath control structure */
+struct bna_rcb {
+ /* Fast path */
+ void **sw_qpt;
+ void *unmap_q;
+ u32 producer_index;
+ u32 consumer_index;
+ u32 q_depth;
+ void *__iomem q_dbell;
+ int page_idx;
+ int page_count;
+ /* Control path */
+ struct bna_rxq *rxq;
+ struct bna_cq *cq;
+ struct bnad *bnad;
+ unsigned long flags;
+ int id;
+};
+
+/* RxQ structure - QPT, configuration */
+struct bna_rxq {
+ struct list_head qe;
+ int rxq_id;
+
+ int buffer_size;
+ int q_depth;
+
+ struct bna_qpt qpt;
+ struct bna_rcb *rcb;
+
+ struct bna_rxp *rxp;
+ struct bna_rx *rx;
+
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 rx_packets_with_error;
+ u64 rxbuf_alloc_failed;
+};
+
+/* RxQ pair */
+union bna_rxq_u {
+ struct {
+ struct bna_rxq *hdr;
+ struct bna_rxq *data;
+ } hds;
+ struct {
+ struct bna_rxq *small;
+ struct bna_rxq *large;
+ } slr;
+ struct {
+ struct bna_rxq *only;
+ struct bna_rxq *reserved;
+ } single;
+};
+
+/* Packet rate for Dynamic Interrupt Moderation */
+struct bna_pkt_rate {
+ u32 small_pkt_cnt;
+ u32 large_pkt_cnt;
+};
+
+/* Completion control structure */
+struct bna_ccb {
+ /* Fast path */
+ void **sw_qpt;
+ u32 producer_index;
+ volatile u32 *hw_producer_index;
+ u32 q_depth;
+ struct bna_ib_dbell *i_dbell;
+ struct bna_rcb *rcb[2];
+ void *ctrl; /* For bnad */
+ struct bna_pkt_rate pkt_rate;
+ int page_idx;
+ int page_count;
+
+ /* Control path */
+ struct bna_cq *cq;
+ struct bnad *bnad;
+ enum bna_intr_type intr_type;
+ int intr_vector;
+ u8 rx_coalescing_timeo; /* For NAPI */
+ int id;
+ char name[BNA_Q_NAME_SIZE];
+};
+
+/* CQ QPT, configuration */
+struct bna_cq {
+ int cq_id;
+
+ struct bna_qpt qpt;
+ struct bna_ccb *ccb;
+
+ struct bna_ib *ib;
+ u8 ib_seg_offset;
+
+ struct bna_rx *rx;
+};
+
+struct bna_rss_config {
+ enum rss_hash_type hash_type;
+ u8 hash_mask;
+ u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+};
+
+struct bna_hds_config {
+ enum hds_header_type hdr_type;
+ int header_size;
+};
+
+/* This structure is used during RX creation */
+struct bna_rx_config {
+ enum bna_rx_type rx_type;
+ int num_paths;
+ enum bna_rxp_type rxp_type;
+ int paused;
+ int q_depth;
+ /*
+ * Small/Large (or Header/Data) buffer size to be configured
+ * for SLR and HDS queue type. Large buffer size comes from
+ * port->mtu.
+ */
+ int small_buff_size;
+
+ enum bna_status rss_status;
+ struct bna_rss_config rss_config;
+
+ enum bna_status hds_status;
+ struct bna_hds_config hds_config;
+
+ enum bna_status vlan_strip_status;
+};
+
+/* Rx Path structure - one per MSIX vector/CPU */
+struct bna_rxp {
+ /* This should be the first one */
+ struct list_head qe;
+
+ enum bna_rxp_type type;
+ union bna_rxq_u rxq;
+ struct bna_cq cq;
+
+ struct bna_rx *rx;
+
+ /* MSI-x vector number for configuring RSS */
+ int vector;
+
+ struct bna_mbox_qe mbox_qe;
+};
+
+/* HDS configuration structure */
+struct bna_rxf_hds {
+ enum hds_header_type hdr_type;
+ int header_size;
+};
+
+/* RSS configuration structure */
+struct bna_rxf_rss {
+ enum rss_hash_type hash_type;
+ u8 hash_mask;
+ u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN];
+};
+
+/* RxF structure (hardware Rx Function) */
+struct bna_rxf {
+ bfa_fsm_t fsm;
+ int rxf_id;
+ enum rxf_flags ctrl_flags;
+ u16 default_vlan_tag;
+ enum bna_rxf_oper_state rxf_oper_state;
+ enum bna_status hds_status;
+ struct bna_rxf_hds hds_cfg;
+ enum bna_status rss_status;
+ struct bna_rxf_rss rss_cfg;
+ struct bna_rit_segment *rit_segment;
+ struct bna_rx *rx;
+ u32 forced_offset;
+ struct bna_mbox_qe mbox_qe;
+ int mcast_rxq_id;
+
+ /* callback for bna_rxf_start() */
+ void (*start_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+ struct bna_rx *start_cbarg;
+
+ /* callback for bna_rxf_stop() */
+ void (*stop_cbfn) (struct bna_rx *rx, enum bna_cb_status status);
+ struct bna_rx *stop_cbarg;
+
+ /* callback for bna_rxf_receive_enable() / bna_rxf_receive_disable() */
+ void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status);
+ struct bnad *oper_state_cbarg;
+
+ /**
+ * callback for:
+ * bna_rxf_ucast_set()
+ * bna_rxf_{ucast/mcast}_add(),
+ * bna_rxf_{ucast/mcast}_del(),
+ * bna_rxf_mode_set()
+ */
+ void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status);
+ struct bnad *cam_fltr_cbarg;
+
+ enum bna_rxf_flags rxf_flags;
+
+ /* List of unicast addresses yet to be applied to h/w */
+ struct list_head ucast_pending_add_q;
+ struct list_head ucast_pending_del_q;
+ int ucast_pending_set;
+ /* ucast addresses applied to the h/w */
+ struct list_head ucast_active_q;
+ struct bna_mac *ucast_active_mac;
+
+ /* List of multicast addresses yet to be applied to h/w */
+ struct list_head mcast_pending_add_q;
+ struct list_head mcast_pending_del_q;
+ /* multicast addresses applied to the h/w */
+ struct list_head mcast_active_q;
+
+ /* Rx modes yet to be applied to h/w */
+ enum bna_rxmode rxmode_pending;
+ enum bna_rxmode rxmode_pending_bitmask;
+ /* Rx modes applied to h/w */
+ enum bna_rxmode rxmode_active;
+
+ enum bna_status vlan_filter_status;
+ u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
+};
+
+/* Rx object */
+struct bna_rx {
+ /* This should be the first one */
+ struct list_head qe;
+
+ bfa_fsm_t fsm;
+
+ enum bna_rx_type type;
+
+ /* list-head for RX path objects */
+ struct list_head rxp_q;
+
+ struct bna_rxf rxf;
+
+ enum bna_rx_flags rx_flags;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bfa_wc rxq_stop_wc;
+
+ /* Rx event handlers */
+ void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+
+ /* callback for bna_rx_disable(), bna_rx_stop() */
+ void (*stop_cbfn)(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status);
+ void *stop_cbarg;
+
+ struct bna *bna;
+ void *priv; /* bnad's cookie */
+};
+
+struct bna_rx_event_cbfn {
+ /* Optional */
+ void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
+ void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
+ /* Mandatory */
+ void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *);
+ void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *);
+};
+
+/* Rx module - keeps track of free, active rx objects */
+struct bna_rx_mod {
+ struct bna *bna; /* back pointer to parent */
+ struct bna_rx *rx; /* BFI_MAX_RXQ entries */
+ struct bna_rxp *rxp; /* BFI_MAX_RXQ entries */
+ struct bna_rxq *rxq; /* BFI_MAX_RXQ entries */
+
+ struct list_head rx_free_q;
+ struct list_head rx_active_q;
+ int rx_free_count;
+
+ struct list_head rxp_free_q;
+ int rxp_free_count;
+
+ struct list_head rxq_free_q;
+ int rxq_free_count;
+
+ enum bna_rx_mod_flags flags;
+
+ /* callback for bna_rx_mod_stop() */
+ void (*stop_cbfn)(struct bna_port *port,
+ enum bna_cb_status status);
+
+ struct bfa_wc rx_stop_wc;
+ u32 dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX];
+ u32 rxf_bmap[2];
+};
+
+/**
+ *
+ * CAM
+ *
+ */
+
+struct bna_ucam_mod {
+ struct bna_mac *ucmac; /* BFI_MAX_UCMAC entries */
+ struct list_head free_q;
+
+ struct bna *bna;
+};
+
+struct bna_mcam_mod {
+ struct bna_mac *mcmac; /* BFI_MAX_MCMAC entries */
+ struct list_head free_q;
+
+ struct bna *bna;
+};
+
+/**
+ *
+ * Statistics
+ *
+ */
+
+struct bna_tx_stats {
+ int tx_state;
+ int tx_flags;
+ int num_txqs;
+ u32 txq_bmap[2];
+ int txf_id;
+};
+
+struct bna_rx_stats {
+ int rx_state;
+ int rx_flags;
+ int num_rxps;
+ int num_rxqs;
+ u32 rxq_bmap[2];
+ u32 cq_bmap[2];
+ int rxf_id;
+ int rxf_state;
+ int rxf_oper_state;
+ int num_active_ucast;
+ int num_active_mcast;
+ int rxmode_active;
+ int vlan_filter_status;
+ u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32];
+ int rss_status;
+ int hds_status;
+};
+
+struct bna_sw_stats {
+ int device_state;
+ int port_state;
+ int port_flags;
+ int llport_state;
+ int priority;
+ int num_active_tx;
+ int num_active_rx;
+ struct bna_tx_stats tx_stats[BFI_MAX_TXQ];
+ struct bna_rx_stats rx_stats[BFI_MAX_RXQ];
+};
+
+struct bna_stats {
+ u32 txf_bmap[2];
+ u32 rxf_bmap[2];
+ struct bfi_ll_stats *hw_stats;
+ struct bna_sw_stats *sw_stats;
+};
+
+/**
+ *
+ * BNA
+ *
+ */
+
+struct bna {
+ struct bfa_pcidev pcidev;
+
+ int port_num;
+
+ struct bna_chip_regs regs;
+
+ struct bna_dma_addr hw_stats_dma;
+ struct bna_stats stats;
+
+ struct bna_device device;
+ struct bfa_cee cee;
+
+ struct bna_mbox_mod mbox_mod;
+
+ struct bna_port port;
+
+ struct bna_tx_mod tx_mod;
+
+ struct bna_rx_mod rx_mod;
+
+ struct bna_ib_mod ib_mod;
+
+ struct bna_ucam_mod ucam_mod;
+ struct bna_mcam_mod mcam_mod;
+
+ struct bna_rit_mod rit_mod;
+
+ int rxf_default_id;
+ int rxf_promisc_id;
+
+ struct bna_mbox_qe mbox_qe;
+
+ struct bnad *bnad;
+};
+
+#endif /* __BNA_TYPES_H__ */
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
new file mode 100644
index 000000000000..e380c0e88f4f
--- /dev/null
+++ b/drivers/net/bna/bnad.c
@@ -0,0 +1,3267 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/in.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+
+#include "bnad.h"
+#include "bna.h"
+#include "cna.h"
+
+DEFINE_MUTEX(bnad_fwimg_mutex);
+
+/*
+ * Module params
+ */
+static uint bnad_msix_disable;
+module_param(bnad_msix_disable, uint, 0444);
+MODULE_PARM_DESC(bnad_msix_disable, "Disable MSIX mode");
+
+static uint bnad_ioc_auto_recover = 1;
+module_param(bnad_ioc_auto_recover, uint, 0444);
+MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery");
+
+/*
+ * Global variables
+ */
+u32 bnad_rxqs_per_cq = 2;
+
+const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+/*
+ * Local MACROS
+ */
+#define BNAD_TX_UNMAPQ_DEPTH (bnad->txq_depth * 2)
+
+#define BNAD_RX_UNMAPQ_DEPTH (bnad->rxq_depth)
+
+#define BNAD_GET_MBOX_IRQ(_bnad) \
+ (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \
+ ((_bnad)->msix_table[(_bnad)->msix_num - 1].vector) : \
+ ((_bnad)->pcidev->irq))
+
+#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth) \
+do { \
+ (_res_info)->res_type = BNA_RES_T_MEM; \
+ (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \
+ (_res_info)->res_u.mem_info.num = (_num); \
+ (_res_info)->res_u.mem_info.len = \
+ sizeof(struct bnad_unmap_q) + \
+ (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \
+} while (0)
+
+/*
+ * Reinitialize completions in CQ, once Rx is taken down
+ */
+static void
+bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bna_cq_entry *cmpl, *next_cmpl;
+ unsigned int wi_range, wis = 0, ccb_prod = 0;
+ int i;
+
+ BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, cmpl,
+ wi_range);
+
+ for (i = 0; i < ccb->q_depth; i++) {
+ wis++;
+ if (likely(--wi_range))
+ next_cmpl = cmpl + 1;
+ else {
+ BNA_QE_INDX_ADD(ccb_prod, wis, ccb->q_depth);
+ wis = 0;
+ BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt,
+ next_cmpl, wi_range);
+ }
+ cmpl->valid = 0;
+ cmpl = next_cmpl;
+ }
+}
+
+/*
+ * Frees all pending Tx Bufs
+ * At this point no activity is expected on the Q,
+ * so DMA unmap & freeing is fine.
+ */
+static void
+bnad_free_all_txbufs(struct bnad *bnad,
+ struct bna_tcb *tcb)
+{
+ u16 unmap_cons;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct sk_buff *skb = NULL;
+ int i;
+
+ unmap_array = unmap_q->unmap_array;
+
+ unmap_cons = 0;
+ while (unmap_cons < unmap_q->q_depth) {
+ skb = unmap_array[unmap_cons].skb;
+ if (!skb) {
+ unmap_cons++;
+ continue;
+ }
+ unmap_array[unmap_cons].skb = NULL;
+
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr), skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
+ unmap_cons++;
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ pci_unmap_page(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr),
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
+ 0);
+ unmap_cons++;
+ }
+ dev_kfree_skb_any(skb);
+ }
+}
+
+/* Data Path Handlers */
+
+/*
+ * bnad_free_txbufs : Frees the Tx bufs on Tx completion
+ * Can be called in a) Interrupt context
+ * b) Sending context
+ * c) Tasklet context
+ */
+static u32
+bnad_free_txbufs(struct bnad *bnad,
+ struct bna_tcb *tcb)
+{
+ u32 sent_packets = 0, sent_bytes = 0;
+ u16 wis, unmap_cons, updated_hw_cons;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct sk_buff *skb;
+ int i;
+
+ /*
+ * Just return if TX is stopped. This check is useful
+ * when bnad_free_txbufs() runs out of a tasklet scheduled
+ * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit
+ * but this routine runs actually after the cleanup has been
+ * executed.
+ */
+ if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
+ return 0;
+
+ updated_hw_cons = *(tcb->hw_consumer_index);
+
+ wis = BNA_Q_INDEX_CHANGE(tcb->consumer_index,
+ updated_hw_cons, tcb->q_depth);
+
+ BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth)));
+
+ unmap_array = unmap_q->unmap_array;
+ unmap_cons = unmap_q->consumer_index;
+
+ prefetch(&unmap_array[unmap_cons + 1]);
+ while (wis) {
+ skb = unmap_array[unmap_cons].skb;
+
+ unmap_array[unmap_cons].skb = NULL;
+
+ sent_packets++;
+ sent_bytes += skb->len;
+ wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags);
+
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr), skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0);
+ BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
+
+ prefetch(&unmap_array[unmap_cons + 1]);
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ prefetch(&unmap_array[unmap_cons + 1]);
+
+ pci_unmap_page(bnad->pcidev,
+ pci_unmap_addr(&unmap_array[unmap_cons],
+ dma_addr),
+ skb_shinfo(skb)->frags[i].size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
+ 0);
+ BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth);
+ }
+ dev_kfree_skb_any(skb);
+ }
+
+ /* Update consumer pointers. */
+ tcb->consumer_index = updated_hw_cons;
+ unmap_q->consumer_index = unmap_cons;
+
+ tcb->txq->tx_packets += sent_packets;
+ tcb->txq->tx_bytes += sent_bytes;
+
+ return sent_packets;
+}
+
+/* Tx Free Tasklet function */
+/* Frees for all the tcb's in all the Tx's */
+/*
+ * Scheduled from sending context, so that
+ * the fat Tx lock is not held for too long
+ * in the sending context.
+ */
+static void
+bnad_tx_free_tasklet(unsigned long bnad_ptr)
+{
+ struct bnad *bnad = (struct bnad *)bnad_ptr;
+ struct bna_tcb *tcb;
+ u32 acked;
+ int i, j;
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ tcb = bnad->tx_info[i].tcb[j];
+ if (!tcb)
+ continue;
+ if (((u16) (*tcb->hw_consumer_index) !=
+ tcb->consumer_index) &&
+ (!test_and_set_bit(BNAD_TXQ_FREE_SENT,
+ &tcb->flags))) {
+ acked = bnad_free_txbufs(bnad, tcb);
+ bna_ib_ack(tcb->i_dbell, acked);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+ }
+ }
+ }
+}
+
+static u32
+bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct net_device *netdev = bnad->netdev;
+ u32 sent;
+
+ if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ return 0;
+
+ sent = bnad_free_txbufs(bnad, tcb);
+ if (sent) {
+ if (netif_queue_stopped(netdev) &&
+ netif_carrier_ok(netdev) &&
+ BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
+ BNAD_NETIF_WAKE_THRESHOLD) {
+ netif_wake_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+ bna_ib_ack(tcb->i_dbell, sent);
+ } else
+ bna_ib_ack(tcb->i_dbell, 0);
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+
+ return sent;
+}
+
+/* MSIX Tx Completion Handler */
+static irqreturn_t
+bnad_msix_tx(int irq, void *data)
+{
+ struct bna_tcb *tcb = (struct bna_tcb *)data;
+ struct bnad *bnad = tcb->bnad;
+
+ bnad_tx(bnad, tcb);
+
+ return IRQ_HANDLED;
+}
+
+static void
+bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ rcb->producer_index = 0;
+ rcb->consumer_index = 0;
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+}
+
+static void
+bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q;
+ struct sk_buff *skb;
+
+ unmap_q = rcb->unmap_q;
+ while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) {
+ skb = unmap_q->unmap_array[unmap_q->consumer_index].skb;
+ BUG_ON(!(skb));
+ unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL;
+ pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q->
+ unmap_array[unmap_q->consumer_index],
+ dma_addr), rcb->rxq->buffer_size +
+ NET_IP_ALIGN, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skb);
+ BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth);
+ BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth);
+ }
+
+ bnad_reset_rcb(bnad, rcb);
+}
+
+static void
+bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ u16 to_alloc, alloced, unmap_prod, wi_range;
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+ struct bnad_skb_unmap *unmap_array;
+ struct bna_rxq_entry *rxent;
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+
+ alloced = 0;
+ to_alloc =
+ BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth);
+
+ unmap_array = unmap_q->unmap_array;
+ unmap_prod = unmap_q->producer_index;
+
+ BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range);
+
+ while (to_alloc--) {
+ if (!wi_range) {
+ BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent,
+ wi_range);
+ }
+ skb = alloc_skb(rcb->rxq->buffer_size + NET_IP_ALIGN,
+ GFP_ATOMIC);
+ if (unlikely(!skb)) {
+ BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed);
+ goto finishing;
+ }
+ skb->dev = bnad->netdev;
+ skb_reserve(skb, NET_IP_ALIGN);
+ unmap_array[unmap_prod].skb = skb;
+ dma_addr = pci_map_single(bnad->pcidev, skb->data,
+ rcb->rxq->buffer_size, PCI_DMA_FROMDEVICE);
+ pci_unmap_addr_set(&unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+ BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+
+ rxent++;
+ wi_range--;
+ alloced++;
+ }
+
+finishing:
+ if (likely(alloced)) {
+ unmap_q->producer_index = unmap_prod;
+ rcb->producer_index = unmap_prod;
+ smp_mb();
+ bna_rxq_prod_indx_doorbell(rcb);
+ }
+}
+
+/*
+ * Locking is required in the enable path
+ * because it is called from a napi poll
+ * context, where the bna_lock is not held
+ * unlike the IRQ context.
+ */
+static void
+bnad_enable_txrx_irqs(struct bnad *bnad)
+{
+ struct bna_tcb *tcb;
+ struct bna_ccb *ccb;
+ int i, j;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ tcb = bnad->tx_info[i].tcb[j];
+ bna_ib_coalescing_timer_set(tcb->i_dbell,
+ tcb->txq->ib->ib_config.coalescing_timeo);
+ bna_ib_ack(tcb->i_dbell, 0);
+ }
+ }
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ ccb = bnad->rx_info[i].rx_ctrl[j].ccb;
+ bnad_enable_rx_irq_unsafe(ccb);
+ }
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static inline void
+bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
+ if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
+ >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
+ bnad_alloc_n_post_rxbufs(bnad, rcb);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+ }
+}
+
+static u32
+bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
+{
+ struct bna_cq_entry *cmpl, *next_cmpl;
+ struct bna_rcb *rcb = NULL;
+ unsigned int wi_range, packets = 0, wis = 0;
+ struct bnad_unmap_q *unmap_q;
+ struct sk_buff *skb;
+ u32 flags;
+ u32 qid0 = ccb->rcb[0]->rxq->rxq_id;
+ struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
+
+ prefetch(bnad->netdev);
+ BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
+ wi_range);
+ BUG_ON(!(wi_range <= ccb->q_depth));
+ while (cmpl->valid && packets < budget) {
+ packets++;
+ BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length));
+
+ if (qid0 == cmpl->rxq_id)
+ rcb = ccb->rcb[0];
+ else
+ rcb = ccb->rcb[1];
+
+ unmap_q = rcb->unmap_q;
+
+ skb = unmap_q->unmap_array[unmap_q->consumer_index].skb;
+ BUG_ON(!(skb));
+ unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL;
+ pci_unmap_single(bnad->pcidev,
+ pci_unmap_addr(&unmap_q->
+ unmap_array[unmap_q->
+ consumer_index],
+ dma_addr),
+ rcb->rxq->buffer_size,
+ PCI_DMA_FROMDEVICE);
+ BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth);
+
+ /* Should be more efficient ? Performance ? */
+ BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth);
+
+ wis++;
+ if (likely(--wi_range))
+ next_cmpl = cmpl + 1;
+ else {
+ BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
+ wis = 0;
+ BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt,
+ next_cmpl, wi_range);
+ BUG_ON(!(wi_range <= ccb->q_depth));
+ }
+ prefetch(next_cmpl);
+
+ flags = ntohl(cmpl->flags);
+ if (unlikely
+ (flags &
+ (BNA_CQ_EF_MAC_ERROR | BNA_CQ_EF_FCS_ERROR |
+ BNA_CQ_EF_TOO_LONG))) {
+ dev_kfree_skb_any(skb);
+ rcb->rxq->rx_packets_with_error++;
+ goto next;
+ }
+
+ skb_put(skb, ntohs(cmpl->length));
+ if (likely
+ (bnad->rx_csum &&
+ (((flags & BNA_CQ_EF_IPV4) &&
+ (flags & BNA_CQ_EF_L3_CKSUM_OK)) ||
+ (flags & BNA_CQ_EF_IPV6)) &&
+ (flags & (BNA_CQ_EF_TCP | BNA_CQ_EF_UDP)) &&
+ (flags & BNA_CQ_EF_L4_CKSUM_OK)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb_checksum_none_assert(skb);
+
+ rcb->rxq->rx_packets++;
+ rcb->rxq->rx_bytes += skb->len;
+ skb->protocol = eth_type_trans(skb, bnad->netdev);
+
+ if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) {
+ struct bnad_rx_ctrl *rx_ctrl =
+ (struct bnad_rx_ctrl *)ccb->ctrl;
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp,
+ ntohs(cmpl->vlan_tag), skb);
+ else
+ vlan_hwaccel_receive_skb(skb,
+ bnad->vlan_grp,
+ ntohs(cmpl->vlan_tag));
+
+ } else { /* Not VLAN tagged/stripped */
+ struct bnad_rx_ctrl *rx_ctrl =
+ (struct bnad_rx_ctrl *)ccb->ctrl;
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY)
+ napi_gro_receive(&rx_ctrl->napi, skb);
+ else
+ netif_receive_skb(skb);
+ }
+
+next:
+ cmpl->valid = 0;
+ cmpl = next_cmpl;
+ }
+
+ BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
+
+ if (likely(ccb)) {
+ bna_ib_ack(ccb->i_dbell, packets);
+ bnad_refill_rxq(bnad, ccb->rcb[0]);
+ if (ccb->rcb[1])
+ bnad_refill_rxq(bnad, ccb->rcb[1]);
+ } else
+ bna_ib_ack(ccb->i_dbell, 0);
+
+ return packets;
+}
+
+static void
+bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ bna_ib_coalescing_timer_set(ccb->i_dbell, 0);
+ bna_ib_ack(ccb->i_dbell, 0);
+}
+
+static void
+bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ spin_lock_irq(&bnad->bna_lock); /* Because of polling context */
+ bnad_enable_rx_irq_unsafe(ccb);
+ spin_unlock_irq(&bnad->bna_lock);
+}
+
+static void
+bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
+ if (likely(napi_schedule_prep((&rx_ctrl->napi)))) {
+ bnad_disable_rx_irq(bnad, ccb);
+ __napi_schedule((&rx_ctrl->napi));
+ }
+ BNAD_UPDATE_CTR(bnad, netif_rx_schedule);
+}
+
+/* MSIX Rx Path Handler */
+static irqreturn_t
+bnad_msix_rx(int irq, void *data)
+{
+ struct bna_ccb *ccb = (struct bna_ccb *)data;
+ struct bnad *bnad = ccb->bnad;
+
+ bnad_netif_rx_schedule_poll(bnad, ccb);
+
+ return IRQ_HANDLED;
+}
+
+/* Interrupt handlers */
+
+/* Mbox Interrupt Handlers */
+static irqreturn_t
+bnad_msix_mbox_handler(int irq, void *data)
+{
+ u32 intr_status;
+ unsigned long flags;
+ struct net_device *netdev = data;
+ struct bnad *bnad;
+
+ bnad = netdev_priv(netdev);
+
+ /* BNA_ISR_GET(bnad); Inc Ref count */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bna_intr_status_get(&bnad->bna, intr_status);
+
+ if (BNA_IS_MBOX_ERR_INTR(intr_status))
+ bna_mbox_handler(&bnad->bna, intr_status);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* BNAD_ISR_PUT(bnad); Dec Ref count */
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+bnad_isr(int irq, void *data)
+{
+ int i, j;
+ u32 intr_status;
+ unsigned long flags;
+ struct net_device *netdev = data;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bna_intr_status_get(&bnad->bna, intr_status);
+ if (!intr_status) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return IRQ_NONE;
+ }
+
+ if (BNA_IS_MBOX_ERR_INTR(intr_status)) {
+ bna_mbox_handler(&bnad->bna, intr_status);
+ if (!BNA_IS_INTX_DATA_INTR(intr_status)) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ goto done;
+ }
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Process data interrupts */
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (rx_ctrl->ccb)
+ bnad_netif_rx_schedule_poll(bnad,
+ rx_ctrl->ccb);
+ }
+ }
+done:
+ return IRQ_HANDLED;
+}
+
+/*
+ * Called in interrupt / callback context
+ * with bna_lock held, so cfg_flags access is OK
+ */
+static void
+bnad_enable_mbox_irq(struct bnad *bnad)
+{
+ int irq = BNAD_GET_MBOX_IRQ(bnad);
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX))
+ return;
+
+ if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
+ enable_irq(irq);
+ BNAD_UPDATE_CTR(bnad, mbox_intr_enabled);
+}
+
+/*
+ * Called with bnad->bna_lock held b'cos of
+ * bnad->cfg_flags access.
+ */
+void
+bnad_disable_mbox_irq(struct bnad *bnad)
+{
+ int irq = BNAD_GET_MBOX_IRQ(bnad);
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX))
+ return;
+
+ if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))
+ disable_irq_nosync(irq);
+ BNAD_UPDATE_CTR(bnad, mbox_intr_disabled);
+}
+
+/* Control Path Handlers */
+
+/* Callbacks */
+void
+bnad_cb_device_enable_mbox_intr(struct bnad *bnad)
+{
+ bnad_enable_mbox_irq(bnad);
+}
+
+void
+bnad_cb_device_disable_mbox_intr(struct bnad *bnad)
+{
+ bnad_disable_mbox_irq(bnad);
+}
+
+void
+bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status)
+{
+ complete(&bnad->bnad_completions.ioc_comp);
+ bnad->bnad_completions.ioc_comp_status = status;
+}
+
+void
+bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status)
+{
+ complete(&bnad->bnad_completions.ioc_comp);
+ bnad->bnad_completions.ioc_comp_status = status;
+}
+
+static void
+bnad_cb_port_disabled(void *arg, enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.port_comp);
+
+ netif_carrier_off(bnad->netdev);
+}
+
+void
+bnad_cb_port_link_status(struct bnad *bnad,
+ enum bna_link_status link_status)
+{
+ bool link_up = 0;
+
+ link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP);
+
+ if (link_status == BNA_CEE_UP) {
+ set_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
+ BNAD_UPDATE_CTR(bnad, cee_up);
+ } else
+ clear_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags);
+
+ if (link_up) {
+ if (!netif_carrier_ok(bnad->netdev)) {
+ pr_warn("bna: %s link up\n",
+ bnad->netdev->name);
+ netif_carrier_on(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, link_toggle);
+ if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) {
+ /* Force an immediate Transmit Schedule */
+ pr_info("bna: %s TX_STARTED\n",
+ bnad->netdev->name);
+ netif_wake_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ } else {
+ netif_stop_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ }
+ }
+ } else {
+ if (netif_carrier_ok(bnad->netdev)) {
+ pr_warn("bna: %s link down\n",
+ bnad->netdev->name);
+ netif_carrier_off(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, link_toggle);
+ }
+ }
+}
+
+static void
+bnad_cb_tx_disabled(void *arg, struct bna_tx *tx,
+ enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.tx_comp);
+}
+
+static void
+bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+ struct bnad_unmap_q *unmap_q = tcb->unmap_q;
+
+ tx_info->tcb[tcb->id] = tcb;
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+ unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH;
+}
+
+static void
+bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+
+ tx_info->tcb[tcb->id] = NULL;
+}
+
+static void
+bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+ unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH;
+}
+
+static void
+bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_info *rx_info =
+ (struct bnad_rx_info *)ccb->cq->rx->priv;
+
+ rx_info->rx_ctrl[ccb->id].ccb = ccb;
+ ccb->ctrl = &rx_info->rx_ctrl[ccb->id];
+}
+
+static void
+bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb)
+{
+ struct bnad_rx_info *rx_info =
+ (struct bnad_rx_info *)ccb->cq->rx->priv;
+
+ rx_info->rx_ctrl[ccb->id].ccb = NULL;
+}
+
+static void
+bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_tx_info *tx_info =
+ (struct bnad_tx_info *)tcb->txq->tx->priv;
+
+ if (tx_info != &bnad->tx_info[0])
+ return;
+
+ clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags);
+ netif_stop_queue(bnad->netdev);
+ pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name);
+}
+
+static void
+bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))
+ return;
+
+ if (netif_carrier_ok(bnad->netdev)) {
+ pr_info("bna: %s TX_STARTED\n", bnad->netdev->name);
+ netif_wake_queue(bnad->netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+}
+
+static void
+bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
+{
+ struct bnad_unmap_q *unmap_q;
+
+ if (!tcb || (!tcb->unmap_q))
+ return;
+
+ unmap_q = tcb->unmap_q;
+ if (!unmap_q->unmap_array)
+ return;
+
+ if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
+ return;
+
+ bnad_free_all_txbufs(bnad, tcb);
+
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+}
+
+static void
+bnad_cb_rx_cleanup(struct bnad *bnad,
+ struct bna_ccb *ccb)
+{
+ bnad_cq_cmpl_init(bnad, ccb);
+
+ bnad_free_rxbufs(bnad, ccb->rcb[0]);
+ clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags);
+
+ if (ccb->rcb[1]) {
+ bnad_free_rxbufs(bnad, ccb->rcb[1]);
+ clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
+ }
+}
+
+static void
+bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_unmap_q *unmap_q = rcb->unmap_q;
+
+ set_bit(BNAD_RXQ_STARTED, &rcb->flags);
+
+ /* Now allocate & post buffers for this RCB */
+ /* !!Allocation in callback context */
+ if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
+ if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
+ >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
+ bnad_alloc_n_post_rxbufs(bnad, rcb);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
+ }
+}
+
+static void
+bnad_cb_rx_disabled(void *arg, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ struct bnad *bnad = (struct bnad *)arg;
+
+ complete(&bnad->bnad_completions.rx_comp);
+}
+
+static void
+bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx,
+ enum bna_cb_status status)
+{
+ bnad->bnad_completions.mcast_comp_status = status;
+ complete(&bnad->bnad_completions.mcast_comp);
+}
+
+void
+bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status,
+ struct bna_stats *stats)
+{
+ if (status == BNA_CB_SUCCESS)
+ BNAD_UPDATE_CTR(bnad, hw_stats_updates);
+
+ if (!netif_running(bnad->netdev) ||
+ !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ return;
+
+ mod_timer(&bnad->stats_timer,
+ jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ));
+}
+
+void
+bnad_cb_stats_clr(struct bnad *bnad)
+{
+}
+
+/* Resource allocation, free functions */
+
+static void
+bnad_mem_free(struct bnad *bnad,
+ struct bna_mem_info *mem_info)
+{
+ int i;
+ dma_addr_t dma_pa;
+
+ if (mem_info->mdl == NULL)
+ return;
+
+ for (i = 0; i < mem_info->num; i++) {
+ if (mem_info->mdl[i].kva != NULL) {
+ if (mem_info->mem_type == BNA_MEM_T_DMA) {
+ BNA_GET_DMA_ADDR(&(mem_info->mdl[i].dma),
+ dma_pa);
+ pci_free_consistent(bnad->pcidev,
+ mem_info->mdl[i].len,
+ mem_info->mdl[i].kva, dma_pa);
+ } else
+ kfree(mem_info->mdl[i].kva);
+ }
+ }
+ kfree(mem_info->mdl);
+ mem_info->mdl = NULL;
+}
+
+static int
+bnad_mem_alloc(struct bnad *bnad,
+ struct bna_mem_info *mem_info)
+{
+ int i;
+ dma_addr_t dma_pa;
+
+ if ((mem_info->num == 0) || (mem_info->len == 0)) {
+ mem_info->mdl = NULL;
+ return 0;
+ }
+
+ mem_info->mdl = kcalloc(mem_info->num, sizeof(struct bna_mem_descr),
+ GFP_KERNEL);
+ if (mem_info->mdl == NULL)
+ return -ENOMEM;
+
+ if (mem_info->mem_type == BNA_MEM_T_DMA) {
+ for (i = 0; i < mem_info->num; i++) {
+ mem_info->mdl[i].len = mem_info->len;
+ mem_info->mdl[i].kva =
+ pci_alloc_consistent(bnad->pcidev,
+ mem_info->len, &dma_pa);
+
+ if (mem_info->mdl[i].kva == NULL)
+ goto err_return;
+
+ BNA_SET_DMA_ADDR(dma_pa,
+ &(mem_info->mdl[i].dma));
+ }
+ } else {
+ for (i = 0; i < mem_info->num; i++) {
+ mem_info->mdl[i].len = mem_info->len;
+ mem_info->mdl[i].kva = kzalloc(mem_info->len,
+ GFP_KERNEL);
+ if (mem_info->mdl[i].kva == NULL)
+ goto err_return;
+ }
+ }
+
+ return 0;
+
+err_return:
+ bnad_mem_free(bnad, mem_info);
+ return -ENOMEM;
+}
+
+/* Free IRQ for Mailbox */
+static void
+bnad_mbox_irq_free(struct bnad *bnad,
+ struct bna_intr_info *intr_info)
+{
+ int irq;
+ unsigned long flags;
+
+ if (intr_info->idl == NULL)
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bnad_disable_mbox_irq(bnad);
+
+ irq = BNAD_GET_MBOX_IRQ(bnad);
+ free_irq(irq, bnad->netdev);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ kfree(intr_info->idl);
+}
+
+/*
+ * Allocates IRQ for Mailbox, but keep it disabled
+ * This will be enabled once we get the mbox enable callback
+ * from bna
+ */
+static int
+bnad_mbox_irq_alloc(struct bnad *bnad,
+ struct bna_intr_info *intr_info)
+{
+ int err;
+ unsigned long flags;
+ u32 irq;
+ irq_handler_t irq_handler;
+
+ /* Mbox should use only 1 vector */
+
+ intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX) {
+ irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
+ irq = bnad->msix_table[bnad->msix_num - 1].vector;
+ flags = 0;
+ intr_info->intr_type = BNA_INTR_T_MSIX;
+ intr_info->idl[0].vector = bnad->msix_num - 1;
+ } else {
+ irq_handler = (irq_handler_t)bnad_isr;
+ irq = bnad->pcidev->irq;
+ flags = IRQF_SHARED;
+ intr_info->intr_type = BNA_INTR_T_INTX;
+ /* intr_info->idl.vector = 0 ? */
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
+
+ err = request_irq(irq, irq_handler, flags,
+ bnad->mbox_irq_name, bnad->netdev);
+ if (err) {
+ kfree(intr_info->idl);
+ intr_info->idl = NULL;
+ return err;
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad_disable_mbox_irq(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return 0;
+}
+
+static void
+bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info)
+{
+ kfree(intr_info->idl);
+ intr_info->idl = NULL;
+}
+
+/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */
+static int
+bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
+ uint txrx_id, struct bna_intr_info *intr_info)
+{
+ int i, vector_start = 0;
+ u32 cfg_flags;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ cfg_flags = bnad->cfg_flags;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (cfg_flags & BNAD_CF_MSIX) {
+ intr_info->intr_type = BNA_INTR_T_MSIX;
+ intr_info->idl = kcalloc(intr_info->num,
+ sizeof(struct bna_intr_descr),
+ GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ switch (src) {
+ case BNAD_INTR_TX:
+ vector_start = txrx_id;
+ break;
+
+ case BNAD_INTR_RX:
+ vector_start = bnad->num_tx * bnad->num_txq_per_tx +
+ txrx_id;
+ break;
+
+ default:
+ BUG();
+ }
+
+ for (i = 0; i < intr_info->num; i++)
+ intr_info->idl[i].vector = vector_start + i;
+ } else {
+ intr_info->intr_type = BNA_INTR_T_INTX;
+ intr_info->num = 1;
+ intr_info->idl = kcalloc(intr_info->num,
+ sizeof(struct bna_intr_descr),
+ GFP_KERNEL);
+ if (!intr_info->idl)
+ return -ENOMEM;
+
+ switch (src) {
+ case BNAD_INTR_TX:
+ intr_info->idl[0].vector = 0x1; /* Bit mask : Tx IB */
+ break;
+
+ case BNAD_INTR_RX:
+ intr_info->idl[0].vector = 0x2; /* Bit mask : Rx IB */
+ break;
+ }
+ }
+ return 0;
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Unregisters Tx MSIX vector(s) from the kernel
+ */
+static void
+bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info,
+ int num_txqs)
+{
+ int i;
+ int vector_num;
+
+ for (i = 0; i < num_txqs; i++) {
+ if (tx_info->tcb[i] == NULL)
+ continue;
+
+ vector_num = tx_info->tcb[i]->intr_vector;
+ free_irq(bnad->msix_table[vector_num].vector, tx_info->tcb[i]);
+ }
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
+ */
+static int
+bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info,
+ uint tx_id, int num_txqs)
+{
+ int i;
+ int err;
+ int vector_num;
+
+ for (i = 0; i < num_txqs; i++) {
+ vector_num = tx_info->tcb[i]->intr_vector;
+ sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name,
+ tx_id + tx_info->tcb[i]->id);
+ err = request_irq(bnad->msix_table[vector_num].vector,
+ (irq_handler_t)bnad_msix_tx, 0,
+ tx_info->tcb[i]->name,
+ tx_info->tcb[i]);
+ if (err)
+ goto err_return;
+ }
+
+ return 0;
+
+err_return:
+ if (i > 0)
+ bnad_tx_msix_unregister(bnad, tx_info, (i - 1));
+ return -1;
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Unregisters Rx MSIX vector(s) from the kernel
+ */
+static void
+bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info,
+ int num_rxps)
+{
+ int i;
+ int vector_num;
+
+ for (i = 0; i < num_rxps; i++) {
+ if (rx_info->rx_ctrl[i].ccb == NULL)
+ continue;
+
+ vector_num = rx_info->rx_ctrl[i].ccb->intr_vector;
+ free_irq(bnad->msix_table[vector_num].vector,
+ rx_info->rx_ctrl[i].ccb);
+ }
+}
+
+/**
+ * NOTE: Should be called for MSIX only
+ * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel
+ */
+static int
+bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info,
+ uint rx_id, int num_rxps)
+{
+ int i;
+ int err;
+ int vector_num;
+
+ for (i = 0; i < num_rxps; i++) {
+ vector_num = rx_info->rx_ctrl[i].ccb->intr_vector;
+ sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d",
+ bnad->netdev->name,
+ rx_id + rx_info->rx_ctrl[i].ccb->id);
+ err = request_irq(bnad->msix_table[vector_num].vector,
+ (irq_handler_t)bnad_msix_rx, 0,
+ rx_info->rx_ctrl[i].ccb->name,
+ rx_info->rx_ctrl[i].ccb);
+ if (err)
+ goto err_return;
+ }
+
+ return 0;
+
+err_return:
+ if (i > 0)
+ bnad_rx_msix_unregister(bnad, rx_info, (i - 1));
+ return -1;
+}
+
+/* Free Tx object Resources */
+static void
+bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
+{
+ int i;
+
+ for (i = 0; i < BNA_TX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for Tx object */
+static int
+bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+ uint tx_id)
+{
+ int i, err = 0;
+
+ for (i = 0; i < BNA_TX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad,
+ &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_TX, tx_id,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_tx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Free Rx object Resources */
+static void
+bnad_rx_res_free(struct bnad *bnad, struct bna_res_info *res_info)
+{
+ int i;
+
+ for (i = 0; i < BNA_RX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for Rx object */
+static int
+bnad_rx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info,
+ uint rx_id)
+{
+ int i, err = 0;
+
+ /* All memory needs to be allocated before setup_ccbs */
+ for (i = 0; i < BNA_RX_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad,
+ &res_info[i].res_u.mem_info);
+ else if (res_info[i].res_type == BNA_RES_T_INTR)
+ err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_RX, rx_id,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_rx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Timer callbacks */
+/* a) IOC timer */
+static void
+bnad_ioc_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_timeout((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_ioc_hb_check(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_hb_check((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_ioc_sem_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * All timer routines use bnad->bna_lock to protect against
+ * the following race, which may occur in case of no locking:
+ * Time CPU m CPU n
+ * 0 1 = test_bit
+ * 1 clear_bit
+ * 2 del_timer_sync
+ * 3 mod_timer
+ */
+
+/* b) Dynamic Interrupt Moderation Timer */
+static void
+bnad_dim_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+ int i, j;
+ unsigned long flags;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (!rx_ctrl->ccb)
+ continue;
+ bna_rx_dim_update(rx_ctrl->ccb);
+ }
+ }
+
+ /* Check for BNAD_CF_DIM_ENABLED, does not eleminate a race */
+ if (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags))
+ mod_timer(&bnad->dim_timer,
+ jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ));
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/* c) Statistics Timer */
+static void
+bnad_stats_timeout(unsigned long data)
+{
+ struct bnad *bnad = (struct bnad *)data;
+ unsigned long flags;
+
+ if (!netif_running(bnad->netdev) ||
+ !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ return;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_stats_get(&bnad->bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * Set up timer for DIM
+ * Called with bnad->bna_lock held
+ */
+void
+bnad_dim_timer_start(struct bnad *bnad)
+{
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED &&
+ !test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) {
+ setup_timer(&bnad->dim_timer, bnad_dim_timeout,
+ (unsigned long)bnad);
+ set_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags);
+ mod_timer(&bnad->dim_timer,
+ jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ));
+ }
+}
+
+/*
+ * Set up timer for statistics
+ * Called with mutex_lock(&bnad->conf_mutex) held
+ */
+static void
+bnad_stats_timer_start(struct bnad *bnad)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!test_and_set_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) {
+ setup_timer(&bnad->stats_timer, bnad_stats_timeout,
+ (unsigned long)bnad);
+ mod_timer(&bnad->stats_timer,
+ jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ));
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+}
+
+/*
+ * Stops the stats timer
+ * Called with mutex_lock(&bnad->conf_mutex) held
+ */
+static void
+bnad_stats_timer_stop(struct bnad *bnad)
+{
+ int to_del = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (test_and_clear_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags))
+ to_del = 1;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (to_del)
+ del_timer_sync(&bnad->stats_timer);
+}
+
+/* Utilities */
+
+static void
+bnad_netdev_mc_list_get(struct net_device *netdev, u8 *mc_list)
+{
+ int i = 1; /* Index 0 has broadcast address */
+ struct netdev_hw_addr *mc_addr;
+
+ netdev_for_each_mc_addr(mc_addr, netdev) {
+ memcpy(&mc_list[i * ETH_ALEN], &mc_addr->addr[0],
+ ETH_ALEN);
+ i++;
+ }
+}
+
+static int
+bnad_napi_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct bnad_rx_ctrl *rx_ctrl =
+ container_of(napi, struct bnad_rx_ctrl, napi);
+ struct bna_ccb *ccb;
+ struct bnad *bnad;
+ int rcvd = 0;
+
+ ccb = rx_ctrl->ccb;
+
+ bnad = ccb->bnad;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ goto poll_exit;
+
+ rcvd = bnad_poll_cq(bnad, ccb, budget);
+ if (rcvd == budget)
+ return rcvd;
+
+poll_exit:
+ napi_complete((napi));
+
+ BNAD_UPDATE_CTR(bnad, netif_rx_complete);
+
+ bnad_enable_rx_irq(bnad, ccb);
+ return rcvd;
+}
+
+static int
+bnad_napi_poll_txrx(struct napi_struct *napi, int budget)
+{
+ struct bnad_rx_ctrl *rx_ctrl =
+ container_of(napi, struct bnad_rx_ctrl, napi);
+ struct bna_ccb *ccb;
+ struct bnad *bnad;
+ int rcvd = 0;
+ int i, j;
+
+ ccb = rx_ctrl->ccb;
+
+ bnad = ccb->bnad;
+
+ if (!netif_carrier_ok(bnad->netdev))
+ goto poll_exit;
+
+ /* Handle Tx Completions, if any */
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++)
+ bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ }
+
+ /* Handle Rx Completions */
+ rcvd = bnad_poll_cq(bnad, ccb, budget);
+ if (rcvd == budget)
+ return rcvd;
+poll_exit:
+ napi_complete((napi));
+
+ BNAD_UPDATE_CTR(bnad, netif_rx_complete);
+
+ bnad_enable_txrx_irqs(bnad);
+ return rcvd;
+}
+
+static void
+bnad_napi_enable(struct bnad *bnad, u32 rx_id)
+{
+ int (*napi_poll) (struct napi_struct *, int);
+ struct bnad_rx_ctrl *rx_ctrl;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ napi_poll = bnad_napi_poll_rx;
+ else
+ napi_poll = bnad_napi_poll_txrx;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Initialize & enable NAPI */
+ for (i = 0; i < bnad->num_rxp_per_rx; i++) {
+ rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
+ netif_napi_add(bnad->netdev, &rx_ctrl->napi,
+ napi_poll, 64);
+ napi_enable(&rx_ctrl->napi);
+ }
+}
+
+static void
+bnad_napi_disable(struct bnad *bnad, u32 rx_id)
+{
+ int i;
+
+ /* First disable and then clean up */
+ for (i = 0; i < bnad->num_rxp_per_rx; i++) {
+ napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+ netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+ }
+}
+
+/* Should be held with conf_lock held */
+void
+bnad_cleanup_tx(struct bnad *bnad, uint tx_id)
+{
+ struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
+ struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
+ unsigned long flags;
+
+ if (!tx_info->tx)
+ return;
+
+ init_completion(&bnad->bnad_completions.tx_comp);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_disable(tx_info->tx, BNA_HARD_CLEANUP, bnad_cb_tx_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ wait_for_completion(&bnad->bnad_completions.tx_comp);
+
+ if (tx_info->tcb[0]->intr_type == BNA_INTR_T_MSIX)
+ bnad_tx_msix_unregister(bnad, tx_info,
+ bnad->num_txq_per_tx);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_destroy(tx_info->tx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ tx_info->tx = NULL;
+
+ if (0 == tx_id)
+ tasklet_kill(&bnad->tx_free_tasklet);
+
+ bnad_tx_res_free(bnad, res_info);
+}
+
+/* Should be held with conf_lock held */
+int
+bnad_setup_tx(struct bnad *bnad, uint tx_id)
+{
+ int err;
+ struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
+ struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
+ struct bna_intr_info *intr_info =
+ &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
+ struct bna_tx_config *tx_config = &bnad->tx_config[tx_id];
+ struct bna_tx_event_cbfn tx_cbfn;
+ struct bna_tx *tx;
+ unsigned long flags;
+
+ /* Initialize the Tx object configuration */
+ tx_config->num_txq = bnad->num_txq_per_tx;
+ tx_config->txq_depth = bnad->txq_depth;
+ tx_config->tx_type = BNA_TX_T_REGULAR;
+
+ /* Initialize the tx event handlers */
+ tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup;
+ tx_cbfn.tcb_destroy_cbfn = bnad_cb_tcb_destroy;
+ tx_cbfn.tx_stall_cbfn = bnad_cb_tx_stall;
+ tx_cbfn.tx_resume_cbfn = bnad_cb_tx_resume;
+ tx_cbfn.tx_cleanup_cbfn = bnad_cb_tx_cleanup;
+
+ /* Get BNA's resource requirement for one tx object */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_res_req(bnad->num_txq_per_tx,
+ bnad->txq_depth, res_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Fill Unmap Q memory requirements */
+ BNAD_FILL_UNMAPQ_MEM_REQ(
+ &res_info[BNA_TX_RES_MEM_T_UNMAPQ],
+ bnad->num_txq_per_tx,
+ BNAD_TX_UNMAPQ_DEPTH);
+
+ /* Allocate resources */
+ err = bnad_tx_res_alloc(bnad, res_info, tx_id);
+ if (err)
+ return err;
+
+ /* Ask BNA to create one Tx object, supplying required resources */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ tx = bna_tx_create(&bnad->bna, bnad, tx_config, &tx_cbfn, res_info,
+ tx_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (!tx)
+ goto err_return;
+ tx_info->tx = tx;
+
+ /* Register ISR for the Tx object */
+ if (intr_info->intr_type == BNA_INTR_T_MSIX) {
+ err = bnad_tx_msix_register(bnad, tx_info,
+ tx_id, bnad->num_txq_per_tx);
+ if (err)
+ goto err_return;
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_enable(tx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return 0;
+
+err_return:
+ bnad_tx_res_free(bnad, res_info);
+ return err;
+}
+
+/* Setup the rx config for bna_rx_create */
+/* bnad decides the configuration */
+static void
+bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
+{
+ rx_config->rx_type = BNA_RX_T_REGULAR;
+ rx_config->num_paths = bnad->num_rxp_per_rx;
+
+ if (bnad->num_rxp_per_rx > 1) {
+ rx_config->rss_status = BNA_STATUS_T_ENABLED;
+ rx_config->rss_config.hash_type =
+ (BFI_RSS_T_V4_TCP |
+ BFI_RSS_T_V6_TCP |
+ BFI_RSS_T_V4_IP |
+ BFI_RSS_T_V6_IP);
+ rx_config->rss_config.hash_mask =
+ bnad->num_rxp_per_rx - 1;
+ get_random_bytes(rx_config->rss_config.toeplitz_hash_key,
+ sizeof(rx_config->rss_config.toeplitz_hash_key));
+ } else {
+ rx_config->rss_status = BNA_STATUS_T_DISABLED;
+ memset(&rx_config->rss_config, 0,
+ sizeof(rx_config->rss_config));
+ }
+ rx_config->rxp_type = BNA_RXP_SLR;
+ rx_config->q_depth = bnad->rxq_depth;
+
+ rx_config->small_buff_size = BFI_SMALL_RXBUF_SIZE;
+
+ rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED;
+}
+
+/* Called with mutex_lock(&bnad->conf_mutex) held */
+void
+bnad_cleanup_rx(struct bnad *bnad, uint rx_id)
+{
+ struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
+ struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
+ struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0];
+ unsigned long flags;
+ int dim_timer_del = 0;
+
+ if (!rx_info->rx)
+ return;
+
+ if (0 == rx_id) {
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ dim_timer_del = bnad_dim_timer_running(bnad);
+ if (dim_timer_del)
+ clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (dim_timer_del)
+ del_timer_sync(&bnad->dim_timer);
+ }
+
+ bnad_napi_disable(bnad, rx_id);
+
+ init_completion(&bnad->bnad_completions.rx_comp);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ wait_for_completion(&bnad->bnad_completions.rx_comp);
+
+ if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
+ bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_destroy(rx_info->rx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ rx_info->rx = NULL;
+
+ bnad_rx_res_free(bnad, res_info);
+}
+
+/* Called with mutex_lock(&bnad->conf_mutex) held */
+int
+bnad_setup_rx(struct bnad *bnad, uint rx_id)
+{
+ int err;
+ struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
+ struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0];
+ struct bna_intr_info *intr_info =
+ &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
+ struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
+ struct bna_rx_event_cbfn rx_cbfn;
+ struct bna_rx *rx;
+ unsigned long flags;
+
+ /* Initialize the Rx object configuration */
+ bnad_init_rx_config(bnad, rx_config);
+
+ /* Initialize the Rx event handlers */
+ rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup;
+ rx_cbfn.rcb_destroy_cbfn = NULL;
+ rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup;
+ rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy;
+ rx_cbfn.rx_cleanup_cbfn = bnad_cb_rx_cleanup;
+ rx_cbfn.rx_post_cbfn = bnad_cb_rx_post;
+
+ /* Get BNA's resource requirement for one Rx object */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_res_req(rx_config, res_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Fill Unmap Q memory requirements */
+ BNAD_FILL_UNMAPQ_MEM_REQ(
+ &res_info[BNA_RX_RES_MEM_T_UNMAPQ],
+ rx_config->num_paths +
+ ((rx_config->rxp_type == BNA_RXP_SINGLE) ? 0 :
+ rx_config->num_paths), BNAD_RX_UNMAPQ_DEPTH);
+
+ /* Allocate resource */
+ err = bnad_rx_res_alloc(bnad, res_info, rx_id);
+ if (err)
+ return err;
+
+ /* Ask BNA to create one Rx object, supplying required resources */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info,
+ rx_info);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ if (!rx)
+ goto err_return;
+ rx_info->rx = rx;
+
+ /* Register ISR for the Rx object */
+ if (intr_info->intr_type == BNA_INTR_T_MSIX) {
+ err = bnad_rx_msix_register(bnad, rx_info, rx_id,
+ rx_config->num_paths);
+ if (err)
+ goto err_return;
+ }
+
+ /* Enable NAPI */
+ bnad_napi_enable(bnad, rx_id);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (0 == rx_id) {
+ /* Set up Dynamic Interrupt Moderation Vector */
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED)
+ bna_rx_dim_reconfig(&bnad->bna, bna_napi_dim_vector);
+
+ /* Enable VLAN filtering only on the default Rx */
+ bna_rx_vlanfilter_enable(rx);
+
+ /* Start the DIM timer */
+ bnad_dim_timer_start(bnad);
+ }
+
+ bna_rx_enable(rx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return 0;
+
+err_return:
+ bnad_cleanup_rx(bnad, rx_id);
+ return err;
+}
+
+/* Called with conf_lock & bnad->bna_lock held */
+void
+bnad_tx_coalescing_timeo_set(struct bnad *bnad)
+{
+ struct bnad_tx_info *tx_info;
+
+ tx_info = &bnad->tx_info[0];
+ if (!tx_info->tx)
+ return;
+
+ bna_tx_coalescing_timeo_set(tx_info->tx, bnad->tx_coalescing_timeo);
+}
+
+/* Called with conf_lock & bnad->bna_lock held */
+void
+bnad_rx_coalescing_timeo_set(struct bnad *bnad)
+{
+ struct bnad_rx_info *rx_info;
+ int i;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ bna_rx_coalescing_timeo_set(rx_info->rx,
+ bnad->rx_coalescing_timeo);
+ }
+}
+
+/*
+ * Called with bnad->bna_lock held
+ */
+static int
+bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr)
+{
+ int ret;
+
+ if (!is_valid_ether_addr(mac_addr))
+ return -EADDRNOTAVAIL;
+
+ /* If datapath is down, pretend everything went through */
+ if (!bnad->rx_info[0].rx)
+ return 0;
+
+ ret = bna_rx_ucast_set(bnad->rx_info[0].rx, mac_addr, NULL);
+ if (ret != BNA_CB_SUCCESS)
+ return -EADDRNOTAVAIL;
+
+ return 0;
+}
+
+/* Should be called with conf_lock held */
+static int
+bnad_enable_default_bcast(struct bnad *bnad)
+{
+ struct bnad_rx_info *rx_info = &bnad->rx_info[0];
+ int ret;
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.mcast_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ ret = bna_rx_mcast_add(rx_info->rx, (u8 *)bnad_bcast_addr,
+ bnad_cb_rx_mcast_add);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (ret == BNA_CB_SUCCESS)
+ wait_for_completion(&bnad->bnad_completions.mcast_comp);
+ else
+ return -ENODEV;
+
+ if (bnad->bnad_completions.mcast_comp_status != BNA_CB_SUCCESS)
+ return -ENODEV;
+
+ return 0;
+}
+
+/* Statistics utilities */
+void
+bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
+{
+ int i, j;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ if (bnad->rx_info[i].rx_ctrl[j].ccb) {
+ stats->rx_packets += bnad->rx_info[i].
+ rx_ctrl[j].ccb->rcb[0]->rxq->rx_packets;
+ stats->rx_bytes += bnad->rx_info[i].
+ rx_ctrl[j].ccb->rcb[0]->rxq->rx_bytes;
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ stats->rx_packets +=
+ bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1]->rxq->rx_packets;
+ stats->rx_bytes +=
+ bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1]->rxq->rx_bytes;
+ }
+ }
+ }
+ }
+ for (i = 0; i < bnad->num_tx; i++) {
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ if (bnad->tx_info[i].tcb[j]) {
+ stats->tx_packets +=
+ bnad->tx_info[i].tcb[j]->txq->tx_packets;
+ stats->tx_bytes +=
+ bnad->tx_info[i].tcb[j]->txq->tx_bytes;
+ }
+ }
+ }
+}
+
+/*
+ * Must be called with the bna_lock held.
+ */
+void
+bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats)
+{
+ struct bfi_ll_stats_mac *mac_stats;
+ u64 bmap;
+ int i;
+
+ mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats;
+ stats->rx_errors =
+ mac_stats->rx_fcs_error + mac_stats->rx_alignment_error +
+ mac_stats->rx_frame_length_error + mac_stats->rx_code_error +
+ mac_stats->rx_undersize;
+ stats->tx_errors = mac_stats->tx_fcs_error +
+ mac_stats->tx_undersize;
+ stats->rx_dropped = mac_stats->rx_drop;
+ stats->tx_dropped = mac_stats->tx_drop;
+ stats->multicast = mac_stats->rx_multicast;
+ stats->collisions = mac_stats->tx_total_collision;
+
+ stats->rx_length_errors = mac_stats->rx_frame_length_error;
+
+ /* receive ring buffer overflow ?? */
+
+ stats->rx_crc_errors = mac_stats->rx_fcs_error;
+ stats->rx_frame_errors = mac_stats->rx_alignment_error;
+ /* recv'r fifo overrun */
+ bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] |
+ ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats->rx_fifo_errors +=
+ bnad->stats.bna_stats->
+ hw_stats->rxf_stats[i].frame_drops;
+ break;
+ }
+ bmap >>= 1;
+ }
+}
+
+static void
+bnad_mbox_irq_sync(struct bnad *bnad)
+{
+ u32 irq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ irq = bnad->msix_table[bnad->msix_num - 1].vector;
+ else
+ irq = bnad->pcidev->irq;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ synchronize_irq(irq);
+}
+
+/* Utility used by bnad_start_xmit, for doing TSO */
+static int
+bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
+{
+ int err;
+
+ /* SKB_GSO_TCPV4 and SKB_GSO_TCPV6 is defined since 2.6.18. */
+ BUG_ON(!(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4 ||
+ skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6));
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err) {
+ BNAD_UPDATE_CTR(bnad, tso_err);
+ return err;
+ }
+ }
+
+ /*
+ * For TSO, the TCP checksum field is seeded with pseudo-header sum
+ * excluding the length field.
+ */
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *iph = ip_hdr(skb);
+
+ /* Do we really need these? */
+ iph->tot_len = 0;
+ iph->check = 0;
+
+ tcp_hdr(skb)->check =
+ ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
+ IPPROTO_TCP, 0);
+ BNAD_UPDATE_CTR(bnad, tso4);
+ } else {
+ struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+
+ BUG_ON(!(skb->protocol == htons(ETH_P_IPV6)));
+ ipv6h->payload_len = 0;
+ tcp_hdr(skb)->check =
+ ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 0,
+ IPPROTO_TCP, 0);
+ BNAD_UPDATE_CTR(bnad, tso6);
+ }
+
+ return 0;
+}
+
+/*
+ * Initialize Q numbers depending on Rx Paths
+ * Called with bnad->bna_lock held, because of cfg_flags
+ * access.
+ */
+static void
+bnad_q_num_init(struct bnad *bnad)
+{
+ int rxps;
+
+ rxps = min((uint)num_online_cpus(),
+ (uint)(BNAD_MAX_RXS * BNAD_MAX_RXPS_PER_RX));
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX))
+ rxps = 1; /* INTx */
+
+ bnad->num_rx = 1;
+ bnad->num_tx = 1;
+ bnad->num_rxp_per_rx = rxps;
+ bnad->num_txq_per_tx = BNAD_TXQ_NUM;
+}
+
+/*
+ * Adjusts the Q numbers, given a number of msix vectors
+ * Give preference to RSS as opposed to Tx priority Queues,
+ * in such a case, just use 1 Tx Q
+ * Called with bnad->bna_lock held b'cos of cfg_flags access
+ */
+static void
+bnad_q_num_adjust(struct bnad *bnad, int msix_vectors)
+{
+ bnad->num_txq_per_tx = 1;
+ if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) +
+ bnad_rxqs_per_cq + BNAD_MAILBOX_MSIX_VECTORS) &&
+ (bnad->cfg_flags & BNAD_CF_MSIX)) {
+ bnad->num_rxp_per_rx = msix_vectors -
+ (bnad->num_tx * bnad->num_txq_per_tx) -
+ BNAD_MAILBOX_MSIX_VECTORS;
+ } else
+ bnad->num_rxp_per_rx = 1;
+}
+
+static void
+bnad_set_netdev_perm_addr(struct bnad *bnad)
+{
+ struct net_device *netdev = bnad->netdev;
+
+ memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len);
+ if (is_zero_ether_addr(netdev->dev_addr))
+ memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len);
+}
+
+/* Enable / disable device */
+static void
+bnad_device_disable(struct bnad *bnad)
+{
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.ioc_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_device_disable(&bnad->bna.device, BNA_HARD_CLEANUP);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.ioc_comp);
+
+}
+
+static int
+bnad_device_enable(struct bnad *bnad)
+{
+ int err = 0;
+ unsigned long flags;
+
+ init_completion(&bnad->bnad_completions.ioc_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_device_enable(&bnad->bna.device);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.ioc_comp);
+
+ if (bnad->bnad_completions.ioc_comp_status)
+ err = bnad->bnad_completions.ioc_comp_status;
+
+ return err;
+}
+
+/* Free BNA resources */
+static void
+bnad_res_free(struct bnad *bnad)
+{
+ int i;
+ struct bna_res_info *res_info = &bnad->res_info[0];
+
+ for (i = 0; i < BNA_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ bnad_mem_free(bnad, &res_info[i].res_u.mem_info);
+ else
+ bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info);
+ }
+}
+
+/* Allocates memory and interrupt resources for BNA */
+static int
+bnad_res_alloc(struct bnad *bnad)
+{
+ int i, err;
+ struct bna_res_info *res_info = &bnad->res_info[0];
+
+ for (i = 0; i < BNA_RES_T_MAX; i++) {
+ if (res_info[i].res_type == BNA_RES_T_MEM)
+ err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info);
+ else
+ err = bnad_mbox_irq_alloc(bnad,
+ &res_info[i].res_u.intr_info);
+ if (err)
+ goto err_return;
+ }
+ return 0;
+
+err_return:
+ bnad_res_free(bnad);
+ return err;
+}
+
+/* Interrupt enable / disable */
+static void
+bnad_enable_msix(struct bnad *bnad)
+{
+ int i, ret;
+ u32 tot_msix_num;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX)) {
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (bnad->msix_table)
+ return;
+
+ tot_msix_num = bnad->msix_num + bnad->msix_diag_num;
+
+ bnad->msix_table =
+ kcalloc(tot_msix_num, sizeof(struct msix_entry), GFP_KERNEL);
+
+ if (!bnad->msix_table)
+ goto intx_mode;
+
+ for (i = 0; i < tot_msix_num; i++)
+ bnad->msix_table[i].entry = i;
+
+ ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, tot_msix_num);
+ if (ret > 0) {
+ /* Not enough MSI-X vectors. */
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ /* ret = #of vectors that we got */
+ bnad_q_num_adjust(bnad, ret);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx)
+ + (bnad->num_rx
+ * bnad->num_rxp_per_rx) +
+ BNAD_MAILBOX_MSIX_VECTORS;
+ tot_msix_num = bnad->msix_num + bnad->msix_diag_num;
+
+ /* Try once more with adjusted numbers */
+ /* If this fails, fall back to INTx */
+ ret = pci_enable_msix(bnad->pcidev, bnad->msix_table,
+ tot_msix_num);
+ if (ret)
+ goto intx_mode;
+
+ } else if (ret < 0)
+ goto intx_mode;
+ return;
+
+intx_mode:
+
+ kfree(bnad->msix_table);
+ bnad->msix_table = NULL;
+ bnad->msix_num = 0;
+ bnad->msix_diag_num = 0;
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad->cfg_flags &= ~BNAD_CF_MSIX;
+ bnad_q_num_init(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+static void
+bnad_disable_msix(struct bnad *bnad)
+{
+ u32 cfg_flags;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ cfg_flags = bnad->cfg_flags;
+ if (bnad->cfg_flags & BNAD_CF_MSIX)
+ bnad->cfg_flags &= ~BNAD_CF_MSIX;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ if (cfg_flags & BNAD_CF_MSIX) {
+ pci_disable_msix(bnad->pcidev);
+ kfree(bnad->msix_table);
+ bnad->msix_table = NULL;
+ }
+}
+
+/* Netdev entry points */
+static int
+bnad_open(struct net_device *netdev)
+{
+ int err;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bna_pause_config pause_config;
+ int mtu;
+ unsigned long flags;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ /* Tx */
+ err = bnad_setup_tx(bnad, 0);
+ if (err)
+ goto err_return;
+
+ /* Rx */
+ err = bnad_setup_rx(bnad, 0);
+ if (err)
+ goto cleanup_tx;
+
+ /* Port */
+ pause_config.tx_pause = 0;
+ pause_config.rx_pause = 0;
+
+ mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
+ bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
+ bna_port_enable(&bnad->bna.port);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Enable broadcast */
+ bnad_enable_default_bcast(bnad);
+
+ /* Set the UCAST address */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bnad_mac_addr_set_locked(bnad, netdev->dev_addr);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ /* Start the stats timer */
+ bnad_stats_timer_start(bnad);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ return 0;
+
+cleanup_tx:
+ bnad_cleanup_tx(bnad, 0);
+
+err_return:
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static int
+bnad_stop(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ /* Stop the stats timer */
+ bnad_stats_timer_stop(bnad);
+
+ init_completion(&bnad->bnad_completions.port_comp);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_disable(&bnad->bna.port, BNA_HARD_CLEANUP,
+ bnad_cb_port_disabled);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ wait_for_completion(&bnad->bnad_completions.port_comp);
+
+ bnad_cleanup_tx(bnad, 0);
+ bnad_cleanup_rx(bnad, 0);
+
+ /* Synchronize mailbox IRQ */
+ bnad_mbox_irq_sync(bnad);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ return 0;
+}
+
+/* TX */
+/*
+ * bnad_start_xmit : Netdev entry point for Transmit
+ * Called under lock held by net_device
+ */
+static netdev_tx_t
+bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ u16 txq_prod, vlan_tag = 0;
+ u32 unmap_prod, wis, wis_used, wi_range;
+ u32 vectors, vect_id, i, acked;
+ u32 tx_id;
+ int err;
+
+ struct bnad_tx_info *tx_info;
+ struct bna_tcb *tcb;
+ struct bnad_unmap_q *unmap_q;
+ dma_addr_t dma_addr;
+ struct bna_txq_entry *txqent;
+ bna_txq_wi_ctrl_flag_t flags;
+
+ if (unlikely
+ (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /*
+ * Takes care of the Tx that is scheduled between clearing the flag
+ * and the netif_stop_queue() call.
+ */
+ if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tx_id = 0;
+
+ tx_info = &bnad->tx_info[tx_id];
+ tcb = tx_info->tcb[tx_id];
+ unmap_q = tcb->unmap_q;
+
+ vectors = 1 + skb_shinfo(skb)->nr_frags;
+ if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
+ acked = 0;
+ if (unlikely
+ (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+ vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+ if ((u16) (*tcb->hw_consumer_index) !=
+ tcb->consumer_index &&
+ !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
+ acked = bnad_free_txbufs(bnad, tcb);
+ bna_ib_ack(tcb->i_dbell, acked);
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+ } else {
+ netif_stop_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ }
+
+ smp_mb();
+ /*
+ * Check again to deal with race condition between
+ * netif_stop_queue here, and netif_wake_queue in
+ * interrupt handler which is not inside netif tx lock.
+ */
+ if (likely
+ (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
+ vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
+ BNAD_UPDATE_CTR(bnad, netif_queue_stop);
+ return NETDEV_TX_BUSY;
+ } else {
+ netif_wake_queue(netdev);
+ BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
+ }
+ }
+
+ unmap_prod = unmap_q->producer_index;
+ wis_used = 1;
+ vect_id = 0;
+ flags = 0;
+
+ txq_prod = tcb->producer_index;
+ BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, txqent, wi_range);
+ BUG_ON(!(wi_range <= tcb->q_depth));
+ txqent->hdr.wi.reserved = 0;
+ txqent->hdr.wi.num_vectors = vectors;
+ txqent->hdr.wi.opcode =
+ htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO :
+ BNA_TXQ_WI_SEND));
+
+ if (bnad->vlan_grp && vlan_tx_tag_present(skb)) {
+ vlan_tag = (u16) vlan_tx_tag_get(skb);
+ flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
+ }
+ if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) {
+ vlan_tag =
+ (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff);
+ flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
+ }
+
+ txqent->hdr.wi.vlan_tag = htons(vlan_tag);
+
+ if (skb_is_gso(skb)) {
+ err = bnad_tso_prepare(bnad, skb);
+ if (err) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb));
+ flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM);
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (tcp_hdrlen(skb) >> 2,
+ skb_transport_offset(skb)));
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ u8 proto = 0;
+
+ txqent->hdr.wi.lso_mss = 0;
+
+ if (skb->protocol == htons(ETH_P_IP))
+ proto = ip_hdr(skb)->protocol;
+ else if (skb->protocol == htons(ETH_P_IPV6)) {
+ /* nexthdr may not be TCP immediately. */
+ proto = ipv6_hdr(skb)->nexthdr;
+ }
+ if (proto == IPPROTO_TCP) {
+ flags |= BNA_TXQ_WI_CF_TCP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, tcpcsum_offload);
+
+ BUG_ON(!(skb_headlen(skb) >=
+ skb_transport_offset(skb) + tcp_hdrlen(skb)));
+
+ } else if (proto == IPPROTO_UDP) {
+ flags |= BNA_TXQ_WI_CF_UDP_CKSUM;
+ txqent->hdr.wi.l4_hdr_size_n_offset =
+ htons(BNA_TXQ_WI_L4_HDR_N_OFFSET
+ (0, skb_transport_offset(skb)));
+
+ BNAD_UPDATE_CTR(bnad, udpcsum_offload);
+
+ BUG_ON(!(skb_headlen(skb) >=
+ skb_transport_offset(skb) +
+ sizeof(struct udphdr)));
+ } else {
+ err = skb_checksum_help(skb);
+ BNAD_UPDATE_CTR(bnad, csum_help);
+ if (err) {
+ dev_kfree_skb(skb);
+ BNAD_UPDATE_CTR(bnad, csum_help_err);
+ return NETDEV_TX_OK;
+ }
+ }
+ } else {
+ txqent->hdr.wi.lso_mss = 0;
+ txqent->hdr.wi.l4_hdr_size_n_offset = 0;
+ }
+
+ txqent->hdr.wi.flags = htons(flags);
+
+ txqent->hdr.wi.frame_length = htonl(skb->len);
+
+ unmap_q->unmap_array[unmap_prod].skb = skb;
+ BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR));
+ txqent->vector[vect_id].length = htons(skb_headlen(skb));
+ dma_addr = pci_map_single(bnad->pcidev, skb->data, skb_headlen(skb),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+
+ BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+ u32 size = frag->size;
+
+ if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
+ vect_id = 0;
+ if (--wi_range)
+ txqent++;
+ else {
+ BNA_QE_INDX_ADD(txq_prod, wis_used,
+ tcb->q_depth);
+ wis_used = 0;
+ BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt,
+ txqent, wi_range);
+ BUG_ON(!(wi_range <= tcb->q_depth));
+ }
+ wis_used++;
+ txqent->hdr.wi_ext.opcode = htons(BNA_TXQ_WI_EXTENSION);
+ }
+
+ BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR));
+ txqent->vector[vect_id].length = htons(size);
+ dma_addr =
+ pci_map_page(bnad->pcidev, frag->page,
+ frag->page_offset, size,
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
+ dma_addr);
+ BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
+ BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
+ }
+
+ unmap_q->producer_index = unmap_prod;
+ BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth);
+ tcb->producer_index = txq_prod;
+
+ smp_mb();
+ bna_txq_prod_indx_doorbell(tcb);
+
+ if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
+ tasklet_schedule(&bnad->tx_free_tasklet);
+
+ return NETDEV_TX_OK;
+}
+
+/*
+ * Used spin_lock to synchronize reading of stats structures, which
+ * is written by BNA under the same lock.
+ */
+static struct rtnl_link_stats64 *
+bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ bnad_netdev_qstats_fill(bnad, stats);
+ bnad_netdev_hwstats_fill(bnad, stats);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return stats;
+}
+
+static void
+bnad_set_rx_mode(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ u32 new_mask, valid_mask;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ new_mask = valid_mask = 0;
+
+ if (netdev->flags & IFF_PROMISC) {
+ if (!(bnad->cfg_flags & BNAD_CF_PROMISC)) {
+ new_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ valid_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ bnad->cfg_flags |= BNAD_CF_PROMISC;
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_PROMISC) {
+ new_mask = ~BNAD_RXMODE_PROMISC_DEFAULT;
+ valid_mask = BNAD_RXMODE_PROMISC_DEFAULT;
+ bnad->cfg_flags &= ~BNAD_CF_PROMISC;
+ }
+ }
+
+ if (netdev->flags & IFF_ALLMULTI) {
+ if (!(bnad->cfg_flags & BNAD_CF_ALLMULTI)) {
+ new_mask |= BNA_RXMODE_ALLMULTI;
+ valid_mask |= BNA_RXMODE_ALLMULTI;
+ bnad->cfg_flags |= BNAD_CF_ALLMULTI;
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_ALLMULTI) {
+ new_mask &= ~BNA_RXMODE_ALLMULTI;
+ valid_mask |= BNA_RXMODE_ALLMULTI;
+ bnad->cfg_flags &= ~BNAD_CF_ALLMULTI;
+ }
+ }
+
+ bna_rx_mode_set(bnad->rx_info[0].rx, new_mask, valid_mask, NULL);
+
+ if (!netdev_mc_empty(netdev)) {
+ u8 *mcaddr_list;
+ int mc_count = netdev_mc_count(netdev);
+
+ /* Index 0 holds the broadcast address */
+ mcaddr_list =
+ kzalloc((mc_count + 1) * ETH_ALEN,
+ GFP_ATOMIC);
+ if (!mcaddr_list)
+ goto unlock;
+
+ memcpy(&mcaddr_list[0], &bnad_bcast_addr[0], ETH_ALEN);
+
+ /* Copy rest of the MC addresses */
+ bnad_netdev_mc_list_get(netdev, mcaddr_list);
+
+ bna_rx_mcast_listset(bnad->rx_info[0].rx, mc_count + 1,
+ mcaddr_list, NULL);
+
+ /* Should we enable BNAD_CF_ALLMULTI for err != 0 ? */
+ kfree(mcaddr_list);
+ }
+unlock:
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+/*
+ * bna_lock is used to sync writes to netdev->addr
+ * conf_lock cannot be used since this call may be made
+ * in a non-blocking context.
+ */
+static int
+bnad_set_mac_address(struct net_device *netdev, void *mac_addr)
+{
+ int err;
+ struct bnad *bnad = netdev_priv(netdev);
+ struct sockaddr *sa = (struct sockaddr *)mac_addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ err = bnad_mac_addr_set_locked(bnad, sa->sa_data);
+
+ if (!err)
+ memcpy(netdev->dev_addr, sa->sa_data, netdev->addr_len);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ return err;
+}
+
+static int
+bnad_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ int mtu, err = 0;
+ unsigned long flags;
+
+ struct bnad *bnad = netdev_priv(netdev);
+
+ if (new_mtu + ETH_HLEN < ETH_ZLEN || new_mtu > BNAD_JUMBO_MTU)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ netdev->mtu = new_mtu;
+
+ mtu = ETH_HLEN + new_mtu + ETH_FCS_LEN;
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mtu_set(&bnad->bna.port, mtu, NULL);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static void
+bnad_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *vlan_grp)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ bnad->vlan_grp = vlan_grp;
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static void
+bnad_vlan_rx_add_vid(struct net_device *netdev,
+ unsigned short vid)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ if (!bnad->rx_info[0].rx)
+ return;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_vlan_add(bnad->rx_info[0].rx, vid);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static void
+bnad_vlan_rx_kill_vid(struct net_device *netdev,
+ unsigned short vid)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ if (!bnad->rx_info[0].rx)
+ return;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_vlan_del(bnad->rx_info[0].rx, vid);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+bnad_netpoll(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bnad_rx_info *rx_info;
+ struct bnad_rx_ctrl *rx_ctrl;
+ u32 curr_mask;
+ int i, j;
+
+ if (!(bnad->cfg_flags & BNAD_CF_MSIX)) {
+ bna_intx_disable(&bnad->bna, curr_mask);
+ bnad_isr(bnad->pcidev->irq, netdev);
+ bna_intx_enable(&bnad->bna, curr_mask);
+ } else {
+ for (i = 0; i < bnad->num_rx; i++) {
+ rx_info = &bnad->rx_info[i];
+ if (!rx_info->rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ rx_ctrl = &rx_info->rx_ctrl[j];
+ if (rx_ctrl->ccb) {
+ bnad_disable_rx_irq(bnad,
+ rx_ctrl->ccb);
+ bnad_netif_rx_schedule_poll(bnad,
+ rx_ctrl->ccb);
+ }
+ }
+ }
+ }
+}
+#endif
+
+static const struct net_device_ops bnad_netdev_ops = {
+ .ndo_open = bnad_open,
+ .ndo_stop = bnad_stop,
+ .ndo_start_xmit = bnad_start_xmit,
+ .ndo_get_stats64 = bnad_get_stats64,
+ .ndo_set_rx_mode = bnad_set_rx_mode,
+ .ndo_set_multicast_list = bnad_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = bnad_set_mac_address,
+ .ndo_change_mtu = bnad_change_mtu,
+ .ndo_vlan_rx_register = bnad_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = bnad_netpoll
+#endif
+};
+
+static void
+bnad_netdev_init(struct bnad *bnad, bool using_dac)
+{
+ struct net_device *netdev = bnad->netdev;
+
+ netdev->features |= NETIF_F_IPV6_CSUM;
+ netdev->features |= NETIF_F_TSO;
+ netdev->features |= NETIF_F_TSO6;
+
+ netdev->features |= NETIF_F_GRO;
+ pr_warn("bna: GRO enabled, using kernel stack GRO\n");
+
+ netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+
+ if (using_dac)
+ netdev->features |= NETIF_F_HIGHDMA;
+
+ netdev->features |=
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
+
+ netdev->vlan_features = netdev->features;
+ netdev->mem_start = bnad->mmio_start;
+ netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1;
+
+ netdev->netdev_ops = &bnad_netdev_ops;
+ bnad_set_ethtool_ops(netdev);
+}
+
+/*
+ * 1. Initialize the bnad structure
+ * 2. Setup netdev pointer in pci_dev
+ * 3. Initialze Tx free tasklet
+ * 4. Initialize no. of TxQ & CQs & MSIX vectors
+ */
+static int
+bnad_init(struct bnad *bnad,
+ struct pci_dev *pdev, struct net_device *netdev)
+{
+ unsigned long flags;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ pci_set_drvdata(pdev, netdev);
+
+ bnad->netdev = netdev;
+ bnad->pcidev = pdev;
+ bnad->mmio_start = pci_resource_start(pdev, 0);
+ bnad->mmio_len = pci_resource_len(pdev, 0);
+ bnad->bar0 = ioremap_nocache(bnad->mmio_start, bnad->mmio_len);
+ if (!bnad->bar0) {
+ dev_err(&pdev->dev, "ioremap for bar0 failed\n");
+ pci_set_drvdata(pdev, NULL);
+ return -ENOMEM;
+ }
+ pr_info("bar0 mapped to %p, len %llu\n", bnad->bar0,
+ (unsigned long long) bnad->mmio_len);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (!bnad_msix_disable)
+ bnad->cfg_flags = BNAD_CF_MSIX;
+
+ bnad->cfg_flags |= BNAD_CF_DIM_ENABLED;
+
+ bnad_q_num_init(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) +
+ (bnad->num_rx * bnad->num_rxp_per_rx) +
+ BNAD_MAILBOX_MSIX_VECTORS;
+ bnad->msix_diag_num = 2; /* 1 for Tx, 1 for Rx */
+
+ bnad->txq_depth = BNAD_TXQ_DEPTH;
+ bnad->rxq_depth = BNAD_RXQ_DEPTH;
+ bnad->rx_csum = true;
+
+ bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
+ bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
+
+ tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet,
+ (unsigned long)bnad);
+
+ return 0;
+}
+
+/*
+ * Must be called after bnad_pci_uninit()
+ * so that iounmap() and pci_set_drvdata(NULL)
+ * happens only after PCI uninitialization.
+ */
+static void
+bnad_uninit(struct bnad *bnad)
+{
+ if (bnad->bar0)
+ iounmap(bnad->bar0);
+ pci_set_drvdata(bnad->pcidev, NULL);
+}
+
+/*
+ * Initialize locks
+ a) Per device mutes used for serializing configuration
+ changes from OS interface
+ b) spin lock used to protect bna state machine
+ */
+static void
+bnad_lock_init(struct bnad *bnad)
+{
+ spin_lock_init(&bnad->bna_lock);
+ mutex_init(&bnad->conf_mutex);
+}
+
+static void
+bnad_lock_uninit(struct bnad *bnad)
+{
+ mutex_destroy(&bnad->conf_mutex);
+}
+
+/* PCI Initialization */
+static int
+bnad_pci_init(struct bnad *bnad,
+ struct pci_dev *pdev, bool *using_dac)
+{
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+ err = pci_request_regions(pdev, BNAD_NAME);
+ if (err)
+ goto disable_device;
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ *using_dac = 1;
+ } else {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
+ err = pci_set_consistent_dma_mask(pdev,
+ DMA_BIT_MASK(32));
+ if (err)
+ goto release_regions;
+ }
+ *using_dac = 0;
+ }
+ pci_set_master(pdev);
+ return 0;
+
+release_regions:
+ pci_release_regions(pdev);
+disable_device:
+ pci_disable_device(pdev);
+
+ return err;
+}
+
+static void
+bnad_pci_uninit(struct pci_dev *pdev)
+{
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static int __devinit
+bnad_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pcidev_id)
+{
+ bool using_dac;
+ int err;
+ struct bnad *bnad;
+ struct bna *bna;
+ struct net_device *netdev;
+ struct bfa_pcidev pcidev_info;
+ unsigned long flags;
+
+ pr_info("bnad_pci_probe : (0x%p, 0x%p) PCI Func : (%d)\n",
+ pdev, pcidev_id, PCI_FUNC(pdev->devfn));
+
+ mutex_lock(&bnad_fwimg_mutex);
+ if (!cna_get_firmware_buf(pdev)) {
+ mutex_unlock(&bnad_fwimg_mutex);
+ pr_warn("Failed to load Firmware Image!\n");
+ return -ENODEV;
+ }
+ mutex_unlock(&bnad_fwimg_mutex);
+
+ /*
+ * Allocates sizeof(struct net_device + struct bnad)
+ * bnad = netdev->priv
+ */
+ netdev = alloc_etherdev(sizeof(struct bnad));
+ if (!netdev) {
+ dev_err(&pdev->dev, "alloc_etherdev failed\n");
+ err = -ENOMEM;
+ return err;
+ }
+ bnad = netdev_priv(netdev);
+
+ /*
+ * PCI initialization
+ * Output : using_dac = 1 for 64 bit DMA
+ * = 0 for 32 bit DMA
+ */
+ err = bnad_pci_init(bnad, pdev, &using_dac);
+ if (err)
+ goto free_netdev;
+
+ bnad_lock_init(bnad);
+ /*
+ * Initialize bnad structure
+ * Setup relation between pci_dev & netdev
+ * Init Tx free tasklet
+ */
+ err = bnad_init(bnad, pdev, netdev);
+ if (err)
+ goto pci_uninit;
+ /* Initialize netdev structure, set up ethtool ops */
+ bnad_netdev_init(bnad, using_dac);
+
+ bnad_enable_msix(bnad);
+
+ /* Get resource requirement form bna */
+ bna_res_req(&bnad->res_info[0]);
+
+ /* Allocate resources from bna */
+ err = bnad_res_alloc(bnad);
+ if (err)
+ goto free_netdev;
+
+ bna = &bnad->bna;
+
+ /* Setup pcidev_info for bna_init() */
+ pcidev_info.pci_slot = PCI_SLOT(bnad->pcidev->devfn);
+ pcidev_info.pci_func = PCI_FUNC(bnad->pcidev->devfn);
+ pcidev_info.device_id = bnad->pcidev->device;
+ pcidev_info.pci_bar_kva = bnad->bar0;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ bnad->stats.bna_stats = &bna->stats;
+
+ /* Set up timers */
+ setup_timer(&bnad->bna.device.ioc.ioc_timer, bnad_ioc_timeout,
+ ((unsigned long)bnad));
+ setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check,
+ ((unsigned long)bnad));
+ setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout,
+ ((unsigned long)bnad));
+
+ /* Now start the timer before calling IOC */
+ mod_timer(&bnad->bna.device.ioc.ioc_timer,
+ jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ));
+
+ /*
+ * Start the chip
+ * Don't care even if err != 0, bna state machine will
+ * deal with it
+ */
+ err = bnad_device_enable(bnad);
+
+ /* Get the burnt-in mac */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_mac_get(&bna->port, &bnad->perm_addr);
+ bnad_set_netdev_perm_addr(bnad);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+
+ /*
+ * Make sure the link appears down to the stack
+ */
+ netif_carrier_off(netdev);
+
+ /* Finally, reguister with net_device layer */
+ err = register_netdev(netdev);
+ if (err) {
+ pr_err("BNA : Registering with netdev failed\n");
+ goto disable_device;
+ }
+
+ return 0;
+
+disable_device:
+ mutex_lock(&bnad->conf_mutex);
+ bnad_device_disable(bnad);
+ del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
+ del_timer_sync(&bnad->bna.device.ioc.sem_timer);
+ del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_uninit(bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ mutex_unlock(&bnad->conf_mutex);
+
+ bnad_res_free(bnad);
+ bnad_disable_msix(bnad);
+pci_uninit:
+ bnad_pci_uninit(pdev);
+ bnad_lock_uninit(bnad);
+ bnad_uninit(bnad);
+free_netdev:
+ free_netdev(netdev);
+ return err;
+}
+
+static void __devexit
+bnad_pci_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct bnad *bnad;
+ struct bna *bna;
+ unsigned long flags;
+
+ if (!netdev)
+ return;
+
+ pr_info("%s bnad_pci_remove\n", netdev->name);
+ bnad = netdev_priv(netdev);
+ bna = &bnad->bna;
+
+ unregister_netdev(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ bnad_device_disable(bnad);
+ del_timer_sync(&bnad->bna.device.ioc.ioc_timer);
+ del_timer_sync(&bnad->bna.device.ioc.sem_timer);
+ del_timer_sync(&bnad->bna.device.ioc.hb_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_uninit(bna);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ mutex_unlock(&bnad->conf_mutex);
+
+ bnad_res_free(bnad);
+ bnad_disable_msix(bnad);
+ bnad_pci_uninit(pdev);
+ bnad_lock_uninit(bnad);
+ bnad_uninit(bnad);
+ free_netdev(netdev);
+}
+
+const struct pci_device_id bnad_pci_id_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_BROCADE,
+ PCI_DEVICE_ID_BROCADE_CT),
+ .class = PCI_CLASS_NETWORK_ETHERNET << 8,
+ .class_mask = 0xffff00
+ }, {0, }
+};
+
+MODULE_DEVICE_TABLE(pci, bnad_pci_id_table);
+
+static struct pci_driver bnad_pci_driver = {
+ .name = BNAD_NAME,
+ .id_table = bnad_pci_id_table,
+ .probe = bnad_pci_probe,
+ .remove = __devexit_p(bnad_pci_remove),
+};
+
+static int __init
+bnad_module_init(void)
+{
+ int err;
+
+ pr_info("Brocade 10G Ethernet driver\n");
+
+ bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover);
+
+ err = pci_register_driver(&bnad_pci_driver);
+ if (err < 0) {
+ pr_err("bna : PCI registration failed in module init "
+ "(%d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit
+bnad_module_exit(void)
+{
+ pci_unregister_driver(&bnad_pci_driver);
+
+ if (bfi_fw)
+ release_firmware(bfi_fw);
+}
+
+module_init(bnad_module_init);
+module_exit(bnad_module_exit);
+
+MODULE_AUTHOR("Brocade");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver");
+MODULE_VERSION(BNAD_VERSION);
+MODULE_FIRMWARE(CNA_FW_FILE_CT);
diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h
new file mode 100644
index 000000000000..ee377888b905
--- /dev/null
+++ b/drivers/net/bna/bnad.h
@@ -0,0 +1,333 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#ifndef __BNAD_H__
+#define __BNAD_H__
+
+#include <linux/rtnetlink.h>
+#include <linux/workqueue.h>
+#include <linux/ipv6.h>
+#include <linux/etherdevice.h>
+#include <linux/mutex.h>
+#include <linux/firmware.h>
+
+/* Fix for IA64 */
+#include <asm/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include <net/ip.h>
+#include <net/tcp.h>
+
+#include "bna.h"
+
+#define BNAD_TXQ_DEPTH 2048
+#define BNAD_RXQ_DEPTH 2048
+
+#define BNAD_MAX_TXS 1
+#define BNAD_MAX_TXQ_PER_TX 8 /* 8 priority queues */
+#define BNAD_TXQ_NUM 1
+
+#define BNAD_MAX_RXS 1
+#define BNAD_MAX_RXPS_PER_RX 16
+
+/*
+ * Control structure pointed to ccb->ctrl, which
+ * determines the NAPI / LRO behavior CCB
+ * There is 1:1 corres. between ccb & ctrl
+ */
+struct bnad_rx_ctrl {
+ struct bna_ccb *ccb;
+ struct napi_struct napi;
+};
+
+#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC
+
+#define BNAD_GET_TX_ID(_skb) (0)
+
+/*
+ * GLOBAL #defines (CONSTANTS)
+ */
+#define BNAD_NAME "bna"
+#define BNAD_NAME_LEN 64
+
+#define BNAD_VERSION "2.3.2.0"
+
+#define BNAD_MAILBOX_MSIX_VECTORS 1
+
+#define BNAD_STATS_TIMER_FREQ 1000 /* in msecs */
+#define BNAD_DIM_TIMER_FREQ 1000 /* in msecs */
+
+#define BNAD_MAX_Q_DEPTH 0x10000
+#define BNAD_MIN_Q_DEPTH 0x200
+
+#define BNAD_JUMBO_MTU 9000
+
+#define BNAD_NETIF_WAKE_THRESHOLD 8
+
+#define BNAD_RXQ_REFILL_THRESHOLD_SHIFT 3
+
+/* Bit positions for tcb->flags */
+#define BNAD_TXQ_FREE_SENT 0
+
+/* Bit positions for rcb->flags */
+#define BNAD_RXQ_REFILL 0
+#define BNAD_RXQ_STARTED 1
+
+/*
+ * DATA STRUCTURES
+ */
+
+/* enums */
+enum bnad_intr_source {
+ BNAD_INTR_TX = 1,
+ BNAD_INTR_RX = 2
+};
+
+enum bnad_link_state {
+ BNAD_LS_DOWN = 0,
+ BNAD_LS_UP = 1
+};
+
+struct bnad_completion {
+ struct completion ioc_comp;
+ struct completion ucast_comp;
+ struct completion mcast_comp;
+ struct completion tx_comp;
+ struct completion rx_comp;
+ struct completion stats_comp;
+ struct completion port_comp;
+
+ u8 ioc_comp_status;
+ u8 ucast_comp_status;
+ u8 mcast_comp_status;
+ u8 tx_comp_status;
+ u8 rx_comp_status;
+ u8 stats_comp_status;
+ u8 port_comp_status;
+};
+
+/* Tx Rx Control Stats */
+struct bnad_drv_stats {
+ u64 netif_queue_stop;
+ u64 netif_queue_wakeup;
+ u64 tso4;
+ u64 tso6;
+ u64 tso_err;
+ u64 tcpcsum_offload;
+ u64 udpcsum_offload;
+ u64 csum_help;
+ u64 csum_help_err;
+
+ u64 hw_stats_updates;
+ u64 netif_rx_schedule;
+ u64 netif_rx_complete;
+ u64 netif_rx_dropped;
+
+ u64 link_toggle;
+ u64 cee_up;
+
+ u64 rxp_info_alloc_failed;
+ u64 mbox_intr_disabled;
+ u64 mbox_intr_enabled;
+ u64 tx_unmap_q_alloc_failed;
+ u64 rx_unmap_q_alloc_failed;
+
+ u64 rxbuf_alloc_failed;
+};
+
+/* Complete driver stats */
+struct bnad_stats {
+ struct bnad_drv_stats drv_stats;
+ struct bna_stats *bna_stats;
+};
+
+/* Tx / Rx Resources */
+struct bnad_tx_res_info {
+ struct bna_res_info res_info[BNA_TX_RES_T_MAX];
+};
+
+struct bnad_rx_res_info {
+ struct bna_res_info res_info[BNA_RX_RES_T_MAX];
+};
+
+struct bnad_tx_info {
+ struct bna_tx *tx; /* 1:1 between tx_info & tx */
+ struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
+} ____cacheline_aligned;
+
+struct bnad_rx_info {
+ struct bna_rx *rx; /* 1:1 between rx_info & rx */
+
+ struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXPS_PER_RX];
+} ____cacheline_aligned;
+
+/* Unmap queues for Tx / Rx cleanup */
+struct bnad_skb_unmap {
+ struct sk_buff *skb;
+ DECLARE_PCI_UNMAP_ADDR(dma_addr)
+};
+
+struct bnad_unmap_q {
+ u32 producer_index;
+ u32 consumer_index;
+ u32 q_depth;
+ /* This should be the last one */
+ struct bnad_skb_unmap unmap_array[1];
+};
+
+/* Bit mask values for bnad->cfg_flags */
+#define BNAD_CF_DIM_ENABLED 0x01 /* DIM */
+#define BNAD_CF_PROMISC 0x02
+#define BNAD_CF_ALLMULTI 0x04
+#define BNAD_CF_MSIX 0x08 /* If in MSIx mode */
+
+/* Defines for run_flags bit-mask */
+/* Set, tested & cleared using xxx_bit() functions */
+/* Values indicated bit positions */
+#define BNAD_RF_CEE_RUNNING 1
+#define BNAD_RF_HW_ERROR 2
+#define BNAD_RF_MBOX_IRQ_DISABLED 3
+#define BNAD_RF_TX_STARTED 4
+#define BNAD_RF_RX_STARTED 5
+#define BNAD_RF_DIM_TIMER_RUNNING 6
+#define BNAD_RF_STATS_TIMER_RUNNING 7
+
+struct bnad {
+ struct net_device *netdev;
+
+ /* Data path */
+ struct bnad_tx_info tx_info[BNAD_MAX_TXS];
+ struct bnad_rx_info rx_info[BNAD_MAX_RXS];
+
+ struct vlan_group *vlan_grp;
+ /*
+ * These q numbers are global only because
+ * they are used to calculate MSIx vectors.
+ * Actually the exact # of queues are per Tx/Rx
+ * object.
+ */
+ u32 num_tx;
+ u32 num_rx;
+ u32 num_txq_per_tx;
+ u32 num_rxp_per_rx;
+
+ u32 txq_depth;
+ u32 rxq_depth;
+
+ u8 tx_coalescing_timeo;
+ u8 rx_coalescing_timeo;
+
+ struct bna_rx_config rx_config[BNAD_MAX_RXS];
+ struct bna_tx_config tx_config[BNAD_MAX_TXS];
+
+ u32 rx_csum;
+
+ void __iomem *bar0; /* BAR0 address */
+
+ struct bna bna;
+
+ u32 cfg_flags;
+ unsigned long run_flags;
+
+ struct pci_dev *pcidev;
+ u64 mmio_start;
+ u64 mmio_len;
+
+ u32 msix_num;
+ u32 msix_diag_num;
+ struct msix_entry *msix_table;
+
+ struct mutex conf_mutex;
+ spinlock_t bna_lock ____cacheline_aligned;
+
+ /* Timers */
+ struct timer_list ioc_timer;
+ struct timer_list dim_timer;
+ struct timer_list stats_timer;
+
+ /* Control path resources, memory & irq */
+ struct bna_res_info res_info[BNA_RES_T_MAX];
+ struct bnad_tx_res_info tx_res_info[BNAD_MAX_TXS];
+ struct bnad_rx_res_info rx_res_info[BNAD_MAX_RXS];
+
+ struct bnad_completion bnad_completions;
+
+ /* Burnt in MAC address */
+ mac_t perm_addr;
+
+ struct tasklet_struct tx_free_tasklet;
+
+ /* Statistics */
+ struct bnad_stats stats;
+
+ struct bnad_diag *diag;
+
+ char adapter_name[BNAD_NAME_LEN];
+ char port_name[BNAD_NAME_LEN];
+ char mbox_irq_name[BNAD_NAME_LEN];
+};
+
+/*
+ * EXTERN VARIABLES
+ */
+extern struct firmware *bfi_fw;
+extern u32 bnad_rxqs_per_cq;
+
+/*
+ * EXTERN PROTOTYPES
+ */
+extern u32 *cna_get_firmware_buf(struct pci_dev *pdev);
+/* Netdev entry point prototypes */
+extern void bnad_set_ethtool_ops(struct net_device *netdev);
+
+/* Configuration & setup */
+extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad);
+extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad);
+
+extern int bnad_setup_rx(struct bnad *bnad, uint rx_id);
+extern int bnad_setup_tx(struct bnad *bnad, uint tx_id);
+extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id);
+extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id);
+
+/* Timer start/stop protos */
+extern void bnad_dim_timer_start(struct bnad *bnad);
+
+/* Statistics */
+extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
+extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats);
+
+/**
+ * MACROS
+ */
+/* To set & get the stats counters */
+#define BNAD_UPDATE_CTR(_bnad, _ctr) \
+ (((_bnad)->stats.drv_stats._ctr)++)
+
+#define BNAD_GET_CTR(_bnad, _ctr) ((_bnad)->stats.drv_stats._ctr)
+
+#define bnad_enable_rx_irq_unsafe(_ccb) \
+{ \
+ bna_ib_coalescing_timer_set((_ccb)->i_dbell, \
+ (_ccb)->rx_coalescing_timeo); \
+ bna_ib_ack((_ccb)->i_dbell, 0); \
+}
+
+#define bnad_dim_timer_running(_bnad) \
+ (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) && \
+ (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags))))
+
+#endif /* __BNAD_H__ */
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
new file mode 100644
index 000000000000..11fa2ea842c1
--- /dev/null
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -0,0 +1,1277 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#include "cna.h"
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/rtnetlink.h>
+
+#include "bna.h"
+
+#include "bnad.h"
+
+#define BNAD_NUM_TXF_COUNTERS 12
+#define BNAD_NUM_RXF_COUNTERS 10
+#define BNAD_NUM_CQ_COUNTERS 3
+#define BNAD_NUM_RXQ_COUNTERS 6
+#define BNAD_NUM_TXQ_COUNTERS 5
+
+#define BNAD_ETHTOOL_STATS_NUM \
+ (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \
+ sizeof(struct bnad_drv_stats) / sizeof(u64) + \
+ offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64))
+
+static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
+ "rx_packets",
+ "tx_packets",
+ "rx_bytes",
+ "tx_bytes",
+ "rx_errors",
+ "tx_errors",
+ "rx_dropped",
+ "tx_dropped",
+ "multicast",
+ "collisions",
+
+ "rx_length_errors",
+ "rx_over_errors",
+ "rx_crc_errors",
+ "rx_frame_errors",
+ "rx_fifo_errors",
+ "rx_missed_errors",
+
+ "tx_aborted_errors",
+ "tx_carrier_errors",
+ "tx_fifo_errors",
+ "tx_heartbeat_errors",
+ "tx_window_errors",
+
+ "rx_compressed",
+ "tx_compressed",
+
+ "netif_queue_stop",
+ "netif_queue_wakeup",
+ "tso4",
+ "tso6",
+ "tso_err",
+ "tcpcsum_offload",
+ "udpcsum_offload",
+ "csum_help",
+ "csum_help_err",
+ "hw_stats_updates",
+ "netif_rx_schedule",
+ "netif_rx_complete",
+ "netif_rx_dropped",
+
+ "link_toggle",
+ "cee_up",
+
+ "rxp_info_alloc_failed",
+ "mbox_intr_disabled",
+ "mbox_intr_enabled",
+ "tx_unmap_q_alloc_failed",
+ "rx_unmap_q_alloc_failed",
+ "rxbuf_alloc_failed",
+
+ "mac_frame_64",
+ "mac_frame_65_127",
+ "mac_frame_128_255",
+ "mac_frame_256_511",
+ "mac_frame_512_1023",
+ "mac_frame_1024_1518",
+ "mac_frame_1518_1522",
+ "mac_rx_bytes",
+ "mac_rx_packets",
+ "mac_rx_fcs_error",
+ "mac_rx_multicast",
+ "mac_rx_broadcast",
+ "mac_rx_control_frames",
+ "mac_rx_pause",
+ "mac_rx_unknown_opcode",
+ "mac_rx_alignment_error",
+ "mac_rx_frame_length_error",
+ "mac_rx_code_error",
+ "mac_rx_carrier_sense_error",
+ "mac_rx_undersize",
+ "mac_rx_oversize",
+ "mac_rx_fragments",
+ "mac_rx_jabber",
+ "mac_rx_drop",
+
+ "mac_tx_bytes",
+ "mac_tx_packets",
+ "mac_tx_multicast",
+ "mac_tx_broadcast",
+ "mac_tx_pause",
+ "mac_tx_deferral",
+ "mac_tx_excessive_deferral",
+ "mac_tx_single_collision",
+ "mac_tx_muliple_collision",
+ "mac_tx_late_collision",
+ "mac_tx_excessive_collision",
+ "mac_tx_total_collision",
+ "mac_tx_pause_honored",
+ "mac_tx_drop",
+ "mac_tx_jabber",
+ "mac_tx_fcs_error",
+ "mac_tx_control_frame",
+ "mac_tx_oversize",
+ "mac_tx_undersize",
+ "mac_tx_fragments",
+
+ "bpc_tx_pause_0",
+ "bpc_tx_pause_1",
+ "bpc_tx_pause_2",
+ "bpc_tx_pause_3",
+ "bpc_tx_pause_4",
+ "bpc_tx_pause_5",
+ "bpc_tx_pause_6",
+ "bpc_tx_pause_7",
+ "bpc_tx_zero_pause_0",
+ "bpc_tx_zero_pause_1",
+ "bpc_tx_zero_pause_2",
+ "bpc_tx_zero_pause_3",
+ "bpc_tx_zero_pause_4",
+ "bpc_tx_zero_pause_5",
+ "bpc_tx_zero_pause_6",
+ "bpc_tx_zero_pause_7",
+ "bpc_tx_first_pause_0",
+ "bpc_tx_first_pause_1",
+ "bpc_tx_first_pause_2",
+ "bpc_tx_first_pause_3",
+ "bpc_tx_first_pause_4",
+ "bpc_tx_first_pause_5",
+ "bpc_tx_first_pause_6",
+ "bpc_tx_first_pause_7",
+
+ "bpc_rx_pause_0",
+ "bpc_rx_pause_1",
+ "bpc_rx_pause_2",
+ "bpc_rx_pause_3",
+ "bpc_rx_pause_4",
+ "bpc_rx_pause_5",
+ "bpc_rx_pause_6",
+ "bpc_rx_pause_7",
+ "bpc_rx_zero_pause_0",
+ "bpc_rx_zero_pause_1",
+ "bpc_rx_zero_pause_2",
+ "bpc_rx_zero_pause_3",
+ "bpc_rx_zero_pause_4",
+ "bpc_rx_zero_pause_5",
+ "bpc_rx_zero_pause_6",
+ "bpc_rx_zero_pause_7",
+ "bpc_rx_first_pause_0",
+ "bpc_rx_first_pause_1",
+ "bpc_rx_first_pause_2",
+ "bpc_rx_first_pause_3",
+ "bpc_rx_first_pause_4",
+ "bpc_rx_first_pause_5",
+ "bpc_rx_first_pause_6",
+ "bpc_rx_first_pause_7",
+
+ "rad_rx_frames",
+ "rad_rx_octets",
+ "rad_rx_vlan_frames",
+ "rad_rx_ucast",
+ "rad_rx_ucast_octets",
+ "rad_rx_ucast_vlan",
+ "rad_rx_mcast",
+ "rad_rx_mcast_octets",
+ "rad_rx_mcast_vlan",
+ "rad_rx_bcast",
+ "rad_rx_bcast_octets",
+ "rad_rx_bcast_vlan",
+ "rad_rx_drops",
+
+ "fc_rx_ucast_octets",
+ "fc_rx_ucast",
+ "fc_rx_ucast_vlan",
+ "fc_rx_mcast_octets",
+ "fc_rx_mcast",
+ "fc_rx_mcast_vlan",
+ "fc_rx_bcast_octets",
+ "fc_rx_bcast",
+ "fc_rx_bcast_vlan",
+
+ "fc_tx_ucast_octets",
+ "fc_tx_ucast",
+ "fc_tx_ucast_vlan",
+ "fc_tx_mcast_octets",
+ "fc_tx_mcast",
+ "fc_tx_mcast_vlan",
+ "fc_tx_bcast_octets",
+ "fc_tx_bcast",
+ "fc_tx_bcast_vlan",
+ "fc_tx_parity_errors",
+ "fc_tx_timeout",
+ "fc_tx_fid_parity_errors",
+};
+
+static int
+bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = SUPPORTED_10000baseT_Full;
+ cmd->advertising = ADVERTISED_10000baseT_Full;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+ cmd->port = PORT_FIBRE;
+ cmd->phy_address = 0;
+
+ if (netif_carrier_ok(netdev)) {
+ cmd->speed = SPEED_10000;
+ cmd->duplex = DUPLEX_FULL;
+ } else {
+ cmd->speed = -1;
+ cmd->duplex = -1;
+ }
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ return 0;
+}
+
+static int
+bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+ /* 10G full duplex setting supported only */
+ if (cmd->autoneg == AUTONEG_ENABLE)
+ return -EOPNOTSUPP; else {
+ if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL))
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static void
+bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bfa_ioc_attr *ioc_attr;
+ unsigned long flags;
+
+ strcpy(drvinfo->driver, BNAD_NAME);
+ strcpy(drvinfo->version, BNAD_VERSION);
+
+ ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL);
+ if (ioc_attr) {
+ memset(ioc_attr, 0, sizeof(*ioc_attr));
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver,
+ sizeof(drvinfo->fw_version) - 1);
+ kfree(ioc_attr);
+ }
+
+ strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN);
+}
+
+static int
+get_regs(struct bnad *bnad, u32 * regs)
+{
+ int num = 0, i;
+ u32 reg_addr;
+ unsigned long flags;
+
+#define BNAD_GET_REG(addr) \
+do { \
+ if (regs) \
+ regs[num++] = readl(bnad->bar0 + (addr)); \
+ else \
+ num++; \
+} while (0)
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+
+ /* DMA Block Internal Registers */
+ BNAD_GET_REG(DMA_CTRL_REG0);
+ BNAD_GET_REG(DMA_CTRL_REG1);
+ BNAD_GET_REG(DMA_ERR_INT_STATUS);
+ BNAD_GET_REG(DMA_ERR_INT_ENABLE);
+ BNAD_GET_REG(DMA_ERR_INT_STATUS_SET);
+
+ /* APP Block Register Address Offset from BAR0 */
+ BNAD_GET_REG(HOSTFN0_INT_STATUS);
+ BNAD_GET_REG(HOSTFN0_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN0);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN0);
+ BNAD_GET_REG(FN0_PCIE_ERR_REG);
+ BNAD_GET_REG(FN0_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN0_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(HOSTFN1_INT_STATUS);
+ BNAD_GET_REG(HOSTFN1_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN1);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN1);
+ BNAD_GET_REG(FN1_PCIE_ERR_REG);
+ BNAD_GET_REG(FN1_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN1_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(PCIE_MISC_REG);
+
+ BNAD_GET_REG(HOST_SEM0_REG);
+ BNAD_GET_REG(HOST_SEM1_REG);
+ BNAD_GET_REG(HOST_SEM2_REG);
+ BNAD_GET_REG(HOST_SEM3_REG);
+ BNAD_GET_REG(HOST_SEM0_INFO_REG);
+ BNAD_GET_REG(HOST_SEM1_INFO_REG);
+ BNAD_GET_REG(HOST_SEM2_INFO_REG);
+ BNAD_GET_REG(HOST_SEM3_INFO_REG);
+
+ BNAD_GET_REG(TEMPSENSE_CNTL_REG);
+ BNAD_GET_REG(TEMPSENSE_STAT_REG);
+
+ BNAD_GET_REG(APP_LOCAL_ERR_STAT);
+ BNAD_GET_REG(APP_LOCAL_ERR_MSK);
+
+ BNAD_GET_REG(PCIE_LNK_ERR_STAT);
+ BNAD_GET_REG(PCIE_LNK_ERR_MSK);
+
+ BNAD_GET_REG(FCOE_FIP_ETH_TYPE);
+ BNAD_GET_REG(RESV_ETH_TYPE);
+
+ BNAD_GET_REG(HOSTFN2_INT_STATUS);
+ BNAD_GET_REG(HOSTFN2_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN2);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN2);
+ BNAD_GET_REG(FN2_PCIE_ERR_REG);
+ BNAD_GET_REG(FN2_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN2_ERR_TYPE_MSK_STATUS_REG);
+
+ BNAD_GET_REG(HOSTFN3_INT_STATUS);
+ BNAD_GET_REG(HOSTFN3_INT_MASK);
+ BNAD_GET_REG(HOST_PAGE_NUM_FN3);
+ BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN3);
+ BNAD_GET_REG(FN3_PCIE_ERR_REG);
+ BNAD_GET_REG(FN3_ERR_TYPE_STATUS_REG);
+ BNAD_GET_REG(FN3_ERR_TYPE_MSK_STATUS_REG);
+
+ /* Host Command Status Registers */
+ reg_addr = HOST_CMDSTS0_CLR_REG;
+ for (i = 0; i < 16; i++) {
+ BNAD_GET_REG(reg_addr);
+ BNAD_GET_REG(reg_addr + 4);
+ BNAD_GET_REG(reg_addr + 8);
+ reg_addr += 0x10;
+ }
+
+ /* Function ID register */
+ BNAD_GET_REG(FNC_ID_REG);
+
+ /* Function personality register */
+ BNAD_GET_REG(FNC_PERS_REG);
+
+ /* Operation mode register */
+ BNAD_GET_REG(OP_MODE);
+
+ /* LPU0 Registers */
+ BNAD_GET_REG(LPU0_MBOX_CTL_REG);
+ BNAD_GET_REG(LPU0_MBOX_CMD_REG);
+ BNAD_GET_REG(LPU0_MBOX_LINK_0REG);
+ BNAD_GET_REG(LPU1_MBOX_LINK_0REG);
+ BNAD_GET_REG(LPU0_MBOX_STATUS_0REG);
+ BNAD_GET_REG(LPU1_MBOX_STATUS_0REG);
+ BNAD_GET_REG(LPU0_ERR_STATUS_REG);
+ BNAD_GET_REG(LPU0_ERR_SET_REG);
+
+ /* LPU1 Registers */
+ BNAD_GET_REG(LPU1_MBOX_CTL_REG);
+ BNAD_GET_REG(LPU1_MBOX_CMD_REG);
+ BNAD_GET_REG(LPU0_MBOX_LINK_1REG);
+ BNAD_GET_REG(LPU1_MBOX_LINK_1REG);
+ BNAD_GET_REG(LPU0_MBOX_STATUS_1REG);
+ BNAD_GET_REG(LPU1_MBOX_STATUS_1REG);
+ BNAD_GET_REG(LPU1_ERR_STATUS_REG);
+ BNAD_GET_REG(LPU1_ERR_SET_REG);
+
+ /* PSS Registers */
+ BNAD_GET_REG(PSS_CTL_REG);
+ BNAD_GET_REG(PSS_ERR_STATUS_REG);
+ BNAD_GET_REG(ERR_STATUS_SET);
+ BNAD_GET_REG(PSS_RAM_ERR_STATUS_REG);
+
+ /* Catapult CPQ Registers */
+ BNAD_GET_REG(HOSTFN0_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN0_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN0_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN0_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN0_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN0_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN1_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN1_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN1_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN1_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN1_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN1_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN2_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN2_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN2_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN2_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN2_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN2_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN2_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN2_MBOX1_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN3_LPU0_MBOX0_CMD_STAT);
+ BNAD_GET_REG(HOSTFN3_LPU1_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN3_MBOX0_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN3_MBOX0_CMD_STAT);
+
+ BNAD_GET_REG(HOSTFN3_LPU0_MBOX1_CMD_STAT);
+ BNAD_GET_REG(HOSTFN3_LPU1_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU0_HOSTFN3_MBOX1_CMD_STAT);
+ BNAD_GET_REG(LPU1_HOSTFN3_MBOX1_CMD_STAT);
+
+ /* Host Function Force Parity Error Registers */
+ BNAD_GET_REG(HOSTFN0_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN1_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN2_LPU_FORCE_PERR);
+ BNAD_GET_REG(HOSTFN3_LPU_FORCE_PERR);
+
+ /* LL Port[0|1] Halt Mask Registers */
+ BNAD_GET_REG(LL_HALT_MSK_P0);
+ BNAD_GET_REG(LL_HALT_MSK_P1);
+
+ /* LL Port[0|1] Error Mask Registers */
+ BNAD_GET_REG(LL_ERR_MSK_P0);
+ BNAD_GET_REG(LL_ERR_MSK_P1);
+
+ /* EMC FLI Registers */
+ BNAD_GET_REG(FLI_CMD_REG);
+ BNAD_GET_REG(FLI_ADDR_REG);
+ BNAD_GET_REG(FLI_CTL_REG);
+ BNAD_GET_REG(FLI_WRDATA_REG);
+ BNAD_GET_REG(FLI_RDDATA_REG);
+ BNAD_GET_REG(FLI_DEV_STATUS_REG);
+ BNAD_GET_REG(FLI_SIG_WD_REG);
+
+ BNAD_GET_REG(FLI_DEV_VENDOR_REG);
+ BNAD_GET_REG(FLI_ERR_STATUS_REG);
+
+ /* RxAdm 0 Registers */
+ BNAD_GET_REG(RAD0_CTL_REG);
+ BNAD_GET_REG(RAD0_PE_PARM_REG);
+ BNAD_GET_REG(RAD0_BCN_REG);
+ BNAD_GET_REG(RAD0_DEFAULT_REG);
+ BNAD_GET_REG(RAD0_PROMISC_REG);
+ BNAD_GET_REG(RAD0_BCNQ_REG);
+ BNAD_GET_REG(RAD0_DEFAULTQ_REG);
+
+ BNAD_GET_REG(RAD0_ERR_STS);
+ BNAD_GET_REG(RAD0_SET_ERR_STS);
+ BNAD_GET_REG(RAD0_ERR_INT_EN);
+ BNAD_GET_REG(RAD0_FIRST_ERR);
+ BNAD_GET_REG(RAD0_FORCE_ERR);
+
+ BNAD_GET_REG(RAD0_MAC_MAN_1H);
+ BNAD_GET_REG(RAD0_MAC_MAN_1L);
+ BNAD_GET_REG(RAD0_MAC_MAN_2H);
+ BNAD_GET_REG(RAD0_MAC_MAN_2L);
+ BNAD_GET_REG(RAD0_MAC_MAN_3H);
+ BNAD_GET_REG(RAD0_MAC_MAN_3L);
+ BNAD_GET_REG(RAD0_MAC_MAN_4H);
+ BNAD_GET_REG(RAD0_MAC_MAN_4L);
+
+ BNAD_GET_REG(RAD0_LAST4_IP);
+
+ /* RxAdm 1 Registers */
+ BNAD_GET_REG(RAD1_CTL_REG);
+ BNAD_GET_REG(RAD1_PE_PARM_REG);
+ BNAD_GET_REG(RAD1_BCN_REG);
+ BNAD_GET_REG(RAD1_DEFAULT_REG);
+ BNAD_GET_REG(RAD1_PROMISC_REG);
+ BNAD_GET_REG(RAD1_BCNQ_REG);
+ BNAD_GET_REG(RAD1_DEFAULTQ_REG);
+
+ BNAD_GET_REG(RAD1_ERR_STS);
+ BNAD_GET_REG(RAD1_SET_ERR_STS);
+ BNAD_GET_REG(RAD1_ERR_INT_EN);
+
+ /* TxA0 Registers */
+ BNAD_GET_REG(TXA0_CTRL_REG);
+ /* TxA0 TSO Sequence # Registers (RO) */
+ for (i = 0; i < 8; i++) {
+ BNAD_GET_REG(TXA0_TSO_TCP_SEQ_REG(i));
+ BNAD_GET_REG(TXA0_TSO_IP_INFO_REG(i));
+ }
+
+ /* TxA1 Registers */
+ BNAD_GET_REG(TXA1_CTRL_REG);
+ /* TxA1 TSO Sequence # Registers (RO) */
+ for (i = 0; i < 8; i++) {
+ BNAD_GET_REG(TXA1_TSO_TCP_SEQ_REG(i));
+ BNAD_GET_REG(TXA1_TSO_IP_INFO_REG(i));
+ }
+
+ /* RxA Registers */
+ BNAD_GET_REG(RXA0_CTL_REG);
+ BNAD_GET_REG(RXA1_CTL_REG);
+
+ /* PLB0 Registers */
+ BNAD_GET_REG(PLB0_ECM_TIMER_REG);
+ BNAD_GET_REG(PLB0_RL_CTL);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB0_RL_MAX_BC(i));
+ BNAD_GET_REG(PLB0_RL_TU_PRIO);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB0_RL_BYTE_CNT(i));
+ BNAD_GET_REG(PLB0_RL_MIN_REG);
+ BNAD_GET_REG(PLB0_RL_MAX_REG);
+ BNAD_GET_REG(PLB0_EMS_ADD_REG);
+
+ /* PLB1 Registers */
+ BNAD_GET_REG(PLB1_ECM_TIMER_REG);
+ BNAD_GET_REG(PLB1_RL_CTL);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB1_RL_MAX_BC(i));
+ BNAD_GET_REG(PLB1_RL_TU_PRIO);
+ for (i = 0; i < 8; i++)
+ BNAD_GET_REG(PLB1_RL_BYTE_CNT(i));
+ BNAD_GET_REG(PLB1_RL_MIN_REG);
+ BNAD_GET_REG(PLB1_RL_MAX_REG);
+ BNAD_GET_REG(PLB1_EMS_ADD_REG);
+
+ /* HQM Control Register */
+ BNAD_GET_REG(HQM0_CTL_REG);
+ BNAD_GET_REG(HQM0_RXQ_STOP_SEM);
+ BNAD_GET_REG(HQM0_TXQ_STOP_SEM);
+ BNAD_GET_REG(HQM1_CTL_REG);
+ BNAD_GET_REG(HQM1_RXQ_STOP_SEM);
+ BNAD_GET_REG(HQM1_TXQ_STOP_SEM);
+
+ /* LUT Registers */
+ BNAD_GET_REG(LUT0_ERR_STS);
+ BNAD_GET_REG(LUT0_SET_ERR_STS);
+ BNAD_GET_REG(LUT1_ERR_STS);
+ BNAD_GET_REG(LUT1_SET_ERR_STS);
+
+ /* TRC Registers */
+ BNAD_GET_REG(TRC_CTL_REG);
+ BNAD_GET_REG(TRC_MODS_REG);
+ BNAD_GET_REG(TRC_TRGC_REG);
+ BNAD_GET_REG(TRC_CNT1_REG);
+ BNAD_GET_REG(TRC_CNT2_REG);
+ BNAD_GET_REG(TRC_NXTS_REG);
+ BNAD_GET_REG(TRC_DIRR_REG);
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_TRGM_REG(i));
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_NXTM_REG(i));
+ for (i = 0; i < 10; i++)
+ BNAD_GET_REG(TRC_STRM_REG(i));
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+#undef BNAD_GET_REG
+ return num;
+}
+static int
+bnad_get_regs_len(struct net_device *netdev)
+{
+ int ret = get_regs(netdev_priv(netdev), NULL) * sizeof(u32);
+ return ret;
+}
+
+static void
+bnad_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+{
+ memset(buf, 0, bnad_get_regs_len(netdev));
+ get_regs(netdev_priv(netdev), buf);
+}
+
+static void
+bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
+{
+ wolinfo->supported = 0;
+ wolinfo->wolopts = 0;
+}
+
+static int
+bnad_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+
+ /* Lock rqd. to access bnad->bna_lock */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ coalesce->use_adaptive_rx_coalesce =
+ (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) ? true : false;
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ coalesce->rx_coalesce_usecs = bnad->rx_coalescing_timeo *
+ BFI_COALESCING_TIMER_UNIT;
+ coalesce->tx_coalesce_usecs = bnad->tx_coalescing_timeo *
+ BFI_COALESCING_TIMER_UNIT;
+ coalesce->tx_max_coalesced_frames = BFI_TX_INTERPKT_COUNT;
+
+ return 0;
+}
+
+static int
+bnad_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ unsigned long flags;
+ int dim_timer_del = 0;
+
+ if (coalesce->rx_coalesce_usecs == 0 ||
+ coalesce->rx_coalesce_usecs >
+ BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
+ return -EINVAL;
+
+ if (coalesce->tx_coalesce_usecs == 0 ||
+ coalesce->tx_coalesce_usecs >
+ BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+ /*
+ * Do not need to store rx_coalesce_usecs here
+ * Every time DIM is disabled, we can get it from the
+ * stack.
+ */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ if (coalesce->use_adaptive_rx_coalesce) {
+ if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) {
+ bnad->cfg_flags |= BNAD_CF_DIM_ENABLED;
+ bnad_dim_timer_start(bnad);
+ }
+ } else {
+ if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) {
+ bnad->cfg_flags &= ~BNAD_CF_DIM_ENABLED;
+ dim_timer_del = bnad_dim_timer_running(bnad);
+ if (dim_timer_del) {
+ clear_bit(BNAD_RF_DIM_TIMER_RUNNING,
+ &bnad->run_flags);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ del_timer_sync(&bnad->dim_timer);
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ }
+ bnad_rx_coalescing_timeo_set(bnad);
+ }
+ }
+ if (bnad->tx_coalescing_timeo != coalesce->tx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT) {
+ bnad->tx_coalescing_timeo = coalesce->tx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT;
+ bnad_tx_coalescing_timeo_set(bnad);
+ }
+
+ if (bnad->rx_coalescing_timeo != coalesce->rx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT) {
+ bnad->rx_coalescing_timeo = coalesce->rx_coalesce_usecs /
+ BFI_COALESCING_TIMER_UNIT;
+
+ if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED))
+ bnad_rx_coalescing_timeo_set(bnad);
+
+ }
+
+ /* Add Tx Inter-pkt DMA count? */
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static void
+bnad_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ringparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ ringparam->rx_max_pending = BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq;
+ ringparam->rx_mini_max_pending = 0;
+ ringparam->rx_jumbo_max_pending = 0;
+ ringparam->tx_max_pending = BNAD_MAX_Q_DEPTH;
+
+ ringparam->rx_pending = bnad->rxq_depth;
+ ringparam->rx_mini_max_pending = 0;
+ ringparam->rx_jumbo_max_pending = 0;
+ ringparam->tx_pending = bnad->txq_depth;
+}
+
+static int
+bnad_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ringparam)
+{
+ int i, current_err, err = 0;
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ if (ringparam->rx_pending == bnad->rxq_depth &&
+ ringparam->tx_pending == bnad->txq_depth) {
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+ }
+
+ if (ringparam->rx_pending < BNAD_MIN_Q_DEPTH ||
+ ringparam->rx_pending > BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq ||
+ !BNA_POWER_OF_2(ringparam->rx_pending)) {
+ mutex_unlock(&bnad->conf_mutex);
+ return -EINVAL;
+ }
+ if (ringparam->tx_pending < BNAD_MIN_Q_DEPTH ||
+ ringparam->tx_pending > BNAD_MAX_Q_DEPTH ||
+ !BNA_POWER_OF_2(ringparam->tx_pending)) {
+ mutex_unlock(&bnad->conf_mutex);
+ return -EINVAL;
+ }
+
+ if (ringparam->rx_pending != bnad->rxq_depth) {
+ bnad->rxq_depth = ringparam->rx_pending;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ bnad_cleanup_rx(bnad, i);
+ current_err = bnad_setup_rx(bnad, i);
+ if (current_err && !err)
+ err = current_err;
+ }
+ }
+ if (ringparam->tx_pending != bnad->txq_depth) {
+ bnad->txq_depth = ringparam->tx_pending;
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ bnad_cleanup_tx(bnad, i);
+ current_err = bnad_setup_tx(bnad, i);
+ if (current_err && !err)
+ err = current_err;
+ }
+ }
+
+ mutex_unlock(&bnad->conf_mutex);
+ return err;
+}
+
+static void
+bnad_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pauseparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ pauseparam->autoneg = 0;
+ pauseparam->rx_pause = bnad->bna.port.pause_config.rx_pause;
+ pauseparam->tx_pause = bnad->bna.port.pause_config.tx_pause;
+}
+
+static int
+bnad_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pauseparam)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ struct bna_pause_config pause_config;
+ unsigned long flags;
+
+ if (pauseparam->autoneg == AUTONEG_ENABLE)
+ return -EINVAL;
+
+ mutex_lock(&bnad->conf_mutex);
+ if (pauseparam->rx_pause != bnad->bna.port.pause_config.rx_pause ||
+ pauseparam->tx_pause != bnad->bna.port.pause_config.tx_pause) {
+ pause_config.rx_pause = pauseparam->rx_pause;
+ pause_config.tx_pause = pauseparam->tx_pause;
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_port_pause_config(&bnad->bna.port, &pause_config, NULL);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ }
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static u32
+bnad_get_rx_csum(struct net_device *netdev)
+{
+ u32 rx_csum;
+ struct bnad *bnad = netdev_priv(netdev);
+
+ rx_csum = bnad->rx_csum;
+ return rx_csum;
+}
+
+static int
+bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ bnad->rx_csum = rx_csum;
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static int
+bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ if (tx_csum) {
+ netdev->features |= NETIF_F_IP_CSUM;
+ netdev->features |= NETIF_F_IPV6_CSUM;
+ } else {
+ netdev->features &= ~NETIF_F_IP_CSUM;
+ netdev->features &= ~NETIF_F_IPV6_CSUM;
+ }
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static int
+bnad_set_tso(struct net_device *netdev, u32 tso)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+
+ mutex_lock(&bnad->conf_mutex);
+ if (tso) {
+ netdev->features |= NETIF_F_TSO;
+ netdev->features |= NETIF_F_TSO6;
+ } else {
+ netdev->features &= ~NETIF_F_TSO;
+ netdev->features &= ~NETIF_F_TSO6;
+ }
+ mutex_unlock(&bnad->conf_mutex);
+ return 0;
+}
+
+static void
+bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, q_num;
+ u64 bmap;
+
+ mutex_lock(&bnad->conf_mutex);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) {
+ BUG_ON(!(strlen(bnad_net_stats_strings[i]) <
+ ETH_GSTRING_LEN));
+ memcpy(string, bnad_net_stats_strings[i],
+ ETH_GSTRING_LEN);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ sprintf(string, "txf%d_ucast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_ucast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_ucast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_mcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_bcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_errors", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_filter_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txf%d_filter_mac_sa", i);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap >>= 1;
+ }
+
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ sprintf(string, "rxf%d_ucast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_ucast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_ucast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_mcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast_octets", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_bcast_vlan", i);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxf%d_frame_drops", i);
+ string += ETH_GSTRING_LEN;
+ }
+ bmap >>= 1;
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ sprintf(string, "cq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "cq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "cq%d_hw_producer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++) {
+ sprintf(string, "rxq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_packets_with_error",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_allocbuf_failed", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ sprintf(string, "rxq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string,
+ "rxq%d_packets_with_error", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_allocbuf_failed",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_producer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "rxq%d_consumer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+ }
+
+ q_num = 0;
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ for (j = 0; j < bnad->num_txq_per_tx; j++) {
+ sprintf(string, "txq%d_packets", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_bytes", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_producer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_consumer_index", q_num);
+ string += ETH_GSTRING_LEN;
+ sprintf(string, "txq%d_hw_consumer_index",
+ q_num);
+ string += ETH_GSTRING_LEN;
+ q_num++;
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static int
+bnad_get_stats_count_locked(struct net_device *netdev)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, count, rxf_active_num = 0, txf_active_num = 0;
+ u64 bmap;
+
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1)
+ txf_active_num++;
+ bmap >>= 1;
+ }
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1)
+ rxf_active_num++;
+ bmap >>= 1;
+ }
+ count = BNAD_ETHTOOL_STATS_NUM +
+ txf_active_num * BNAD_NUM_TXF_COUNTERS +
+ rxf_active_num * BNAD_NUM_RXF_COUNTERS;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ count += bnad->num_rxp_per_rx * BNAD_NUM_CQ_COUNTERS;
+ count += bnad->num_rxp_per_rx * BNAD_NUM_RXQ_COUNTERS;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1]->rxq)
+ count += BNAD_NUM_RXQ_COUNTERS;
+ }
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ count += bnad->num_txq_per_tx * BNAD_NUM_TXQ_COUNTERS;
+ }
+ return count;
+}
+
+static int
+bnad_per_q_stats_fill(struct bnad *bnad, u64 *buf, int bi)
+{
+ int i, j;
+ struct bna_rcb *rcb = NULL;
+ struct bna_tcb *tcb = NULL;
+
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0]->rxq) {
+ buf[bi++] = bnad->rx_info[i].rx_ctrl[j].
+ ccb->producer_index;
+ buf[bi++] = 0; /* ccb->consumer_index */
+ buf[bi++] = *(bnad->rx_info[i].rx_ctrl[j].
+ ccb->hw_producer_index);
+ }
+ }
+ for (i = 0; i < bnad->num_rx; i++) {
+ if (!bnad->rx_info[i].rx)
+ continue;
+ for (j = 0; j < bnad->num_rxp_per_rx; j++)
+ if (bnad->rx_info[i].rx_ctrl[j].ccb) {
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[0]->rxq) {
+ rcb = bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[0];
+ buf[bi++] = rcb->rxq->rx_packets;
+ buf[bi++] = rcb->rxq->rx_bytes;
+ buf[bi++] = rcb->rxq->
+ rx_packets_with_error;
+ buf[bi++] = rcb->rxq->
+ rxbuf_alloc_failed;
+ buf[bi++] = rcb->producer_index;
+ buf[bi++] = rcb->consumer_index;
+ }
+ if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
+ bnad->rx_info[i].rx_ctrl[j].ccb->
+ rcb[1]->rxq) {
+ rcb = bnad->rx_info[i].rx_ctrl[j].
+ ccb->rcb[1];
+ buf[bi++] = rcb->rxq->rx_packets;
+ buf[bi++] = rcb->rxq->rx_bytes;
+ buf[bi++] = rcb->rxq->
+ rx_packets_with_error;
+ buf[bi++] = rcb->rxq->
+ rxbuf_alloc_failed;
+ buf[bi++] = rcb->producer_index;
+ buf[bi++] = rcb->consumer_index;
+ }
+ }
+ }
+
+ for (i = 0; i < bnad->num_tx; i++) {
+ if (!bnad->tx_info[i].tx)
+ continue;
+ for (j = 0; j < bnad->num_txq_per_tx; j++)
+ if (bnad->tx_info[i].tcb[j] &&
+ bnad->tx_info[i].tcb[j]->txq) {
+ tcb = bnad->tx_info[i].tcb[j];
+ buf[bi++] = tcb->txq->tx_packets;
+ buf[bi++] = tcb->txq->tx_bytes;
+ buf[bi++] = tcb->producer_index;
+ buf[bi++] = tcb->consumer_index;
+ buf[bi++] = *(tcb->hw_consumer_index);
+ }
+ }
+
+ return bi;
+}
+
+static void
+bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
+ u64 *buf)
+{
+ struct bnad *bnad = netdev_priv(netdev);
+ int i, j, bi;
+ unsigned long flags;
+ struct rtnl_link_stats64 *net_stats64;
+ u64 *stats64;
+ u64 bmap;
+
+ mutex_lock(&bnad->conf_mutex);
+ if (bnad_get_stats_count_locked(netdev) != stats->n_stats) {
+ mutex_unlock(&bnad->conf_mutex);
+ return;
+ }
+
+ /*
+ * Used bna_lock to sync reads from bna_stats, which is written
+ * under the same lock
+ */
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bi = 0;
+ memset(buf, 0, stats->n_stats * sizeof(u64));
+
+ net_stats64 = (struct rtnl_link_stats64 *)buf;
+ bnad_netdev_qstats_fill(bnad, net_stats64);
+ bnad_netdev_hwstats_fill(bnad, net_stats64);
+
+ bi = sizeof(*net_stats64) / sizeof(u64);
+
+ /* Fill driver stats into ethtool buffers */
+ stats64 = (u64 *)&bnad->stats.drv_stats;
+ for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++)
+ buf[bi++] = stats64[i];
+
+ /* Fill hardware stats excluding the rxf/txf into ethtool bufs */
+ stats64 = (u64 *) bnad->stats.bna_stats->hw_stats;
+ for (i = 0;
+ i < offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64);
+ i++)
+ buf[bi++] = stats64[i];
+
+ /* Fill txf stats into ethtool buffers */
+ bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] |
+ ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats64 = (u64 *)&bnad->stats.bna_stats->
+ hw_stats->txf_stats[i];
+ for (j = 0; j < sizeof(struct bfi_ll_stats_txf) /
+ sizeof(u64); j++)
+ buf[bi++] = stats64[j];
+ }
+ bmap >>= 1;
+ }
+
+ /* Fill rxf stats into ethtool buffers */
+ bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] |
+ ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32);
+ for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) {
+ if (bmap & 1) {
+ stats64 = (u64 *)&bnad->stats.bna_stats->
+ hw_stats->rxf_stats[i];
+ for (j = 0; j < sizeof(struct bfi_ll_stats_rxf) /
+ sizeof(u64); j++)
+ buf[bi++] = stats64[j];
+ }
+ bmap >>= 1;
+ }
+
+ /* Fill per Q stats into ethtool buffers */
+ bi = bnad_per_q_stats_fill(bnad, buf, bi);
+
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+
+ mutex_unlock(&bnad->conf_mutex);
+}
+
+static int
+bnad_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return bnad_get_stats_count_locked(netdev);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static struct ethtool_ops bnad_ethtool_ops = {
+ .get_settings = bnad_get_settings,
+ .set_settings = bnad_set_settings,
+ .get_drvinfo = bnad_get_drvinfo,
+ .get_regs_len = bnad_get_regs_len,
+ .get_regs = bnad_get_regs,
+ .get_wol = bnad_get_wol,
+ .get_link = ethtool_op_get_link,
+ .get_coalesce = bnad_get_coalesce,
+ .set_coalesce = bnad_set_coalesce,
+ .get_ringparam = bnad_get_ringparam,
+ .set_ringparam = bnad_set_ringparam,
+ .get_pauseparam = bnad_get_pauseparam,
+ .set_pauseparam = bnad_set_pauseparam,
+ .get_rx_csum = bnad_get_rx_csum,
+ .set_rx_csum = bnad_set_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = bnad_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = bnad_set_tso,
+ .get_strings = bnad_get_strings,
+ .get_ethtool_stats = bnad_get_ethtool_stats,
+ .get_sset_count = bnad_get_sset_count
+};
+
+void
+bnad_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops);
+}
diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h
new file mode 100644
index 000000000000..bbd39dc65972
--- /dev/null
+++ b/drivers/net/bna/cna.h
@@ -0,0 +1,81 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2006-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+
+#ifndef __CNA_H__
+#define __CNA_H__
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include <linux/list.h>
+
+#define bfa_sm_fault(__mod, __event) do { \
+ pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \
+ __event); \
+} while (0)
+
+extern char bfa_version[];
+
+#define CNA_FW_FILE_CT "ctfw_cna.bin"
+#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */
+
+#pragma pack(1)
+
+#define MAC_ADDRLEN (6)
+typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t;
+
+#pragma pack()
+
+#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))
+#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)
+#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev)
+
+/*
+ * bfa_q_qe_init - to initialize a queue element
+ */
+#define bfa_q_qe_init(_qe) { \
+ bfa_q_next(_qe) = (struct list_head *) NULL; \
+ bfa_q_prev(_qe) = (struct list_head *) NULL; \
+}
+
+/*
+ * bfa_q_deq - dequeue an element from head of the queue
+ */
+#define bfa_q_deq(_q, _qe) { \
+ if (!list_empty(_q)) { \
+ (*((struct list_head **) (_qe))) = bfa_q_next(_q); \
+ bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
+ (struct list_head *) (_q); \
+ bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \
+ bfa_q_qe_init(*((struct list_head **) _qe)); \
+ } else { \
+ *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
+ } \
+}
+
+#endif /* __CNA_H__ */
diff --git a/drivers/net/bna/cna_fwimg.c b/drivers/net/bna/cna_fwimg.c
new file mode 100644
index 000000000000..0bd1d3790a27
--- /dev/null
+++ b/drivers/net/bna/cna_fwimg.c
@@ -0,0 +1,64 @@
+/*
+ * Linux network driver for Brocade Converged Network Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ */
+#include <linux/firmware.h>
+#include "cna.h"
+
+const struct firmware *bfi_fw;
+static u32 *bfi_image_ct_cna;
+static u32 bfi_image_ct_cna_size;
+
+u32 *
+cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
+ u32 *bfi_image_size, char *fw_name)
+{
+ const struct firmware *fw;
+
+ if (request_firmware(&fw, fw_name, &pdev->dev)) {
+ pr_alert("Can't locate firmware %s\n", fw_name);
+ goto error;
+ }
+
+ *bfi_image = (u32 *)fw->data;
+ *bfi_image_size = fw->size/sizeof(u32);
+ bfi_fw = fw;
+
+ return *bfi_image;
+error:
+ return NULL;
+}
+
+u32 *
+cna_get_firmware_buf(struct pci_dev *pdev)
+{
+ if (bfi_image_ct_cna_size == 0)
+ cna_read_firmware(pdev, &bfi_image_ct_cna,
+ &bfi_image_ct_cna_size, CNA_FW_FILE_CT);
+ return bfi_image_ct_cna;
+}
+
+u32 *
+bfa_cb_image_get_chunk(int type, u32 off)
+{
+ return (u32 *)(bfi_image_ct_cna + off);
+}
+
+u32
+bfa_cb_image_get_size(int type)
+{
+ return bfi_image_ct_cna_size;
+}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index e6a803f1c507..4ff76e38e788 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -49,6 +49,7 @@
#include <linux/cache.h>
#include <linux/firmware.h>
#include <linux/log2.h>
+#include <linux/aer.h>
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
@@ -3217,7 +3218,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (bp->rx_csum &&
(status & (L2_FHDR_STATUS_TCP_SEGMENT |
L2_FHDR_STATUS_UDP_DATAGRAM))) {
@@ -7890,6 +7891,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
int rc, i, j;
u32 reg;
u64 dma_mask, persist_dma_mask;
+ int err;
SET_NETDEV_DEV(dev, &pdev->dev);
bp = netdev_priv(dev);
@@ -7925,6 +7927,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
goto err_out_disable;
}
+ /* 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_save_state(pdev);
@@ -8246,6 +8256,7 @@ err_out_unmap:
}
err_out_release:
+ pci_disable_pcie_error_reporting(pdev);
pci_release_regions(pdev);
err_out_disable:
@@ -8436,6 +8447,9 @@ bnx2_remove_one(struct pci_dev *pdev)
kfree(bp->temp_stats_blk);
free_netdev(dev);
+
+ pci_disable_pcie_error_reporting(pdev);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
@@ -8527,25 +8541,35 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
+ pci_ers_result_t result;
+ int err;
rtnl_lock();
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset\n");
- rtnl_unlock();
- return PCI_ERS_RESULT_DISCONNECT;
+ result = PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+
+ if (netif_running(dev)) {
+ bnx2_set_power_state(bp, PCI_D0);
+ bnx2_init_nic(bp, 1);
+ }
+ result = PCI_ERS_RESULT_RECOVERED;
}
- pci_set_master(pdev);
- pci_restore_state(pdev);
- pci_save_state(pdev);
+ rtnl_unlock();
- if (netif_running(dev)) {
- bnx2_set_power_state(bp, PCI_D0);
- bnx2_init_nic(bp, 1);
+ err = pci_cleanup_aer_uncorrect_error_status(pdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n",
+ err); /* non-fatal, continue */
}
- rtnl_unlock();
- return PCI_ERS_RESULT_RECOVERED;
+ return result;
}
/**
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 0c2d96ed561c..64329c5fbdea 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -20,8 +20,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.52.53-4"
-#define DRV_MODULE_RELDATE "2010/16/08"
+#define DRV_MODULE_VERSION "1.52.53-7"
+#define DRV_MODULE_RELDATE "2010/09/12"
#define BNX2X_BC_VER 0x040200
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -369,6 +369,7 @@ struct bnx2x_fastpath {
#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
#define MAX_RX_BD (NUM_RX_BD - 1)
#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
+#define MIN_RX_AVAIL 128
#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
(MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
#define RX_BD(x) ((x) & MAX_RX_BD)
@@ -566,13 +567,13 @@ struct bnx2x_common {
struct bnx2x_port {
u32 pmf;
- u32 link_config;
+ u32 link_config[LINK_CONFIG_SIZE];
- u32 supported;
+ u32 supported[LINK_CONFIG_SIZE];
/* link settings - missing defines */
#define SUPPORTED_2500baseX_Full (1 << 15)
- u32 advertising;
+ u32 advertising[LINK_CONFIG_SIZE];
/* link settings - missing defines */
#define ADVERTISED_2500baseX_Full (1 << 15)
@@ -931,7 +932,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
-u32 bnx2x_fw_command(struct bnx2x *bp, u32 command);
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param);
void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
u32 addr, u32 len);
@@ -939,7 +940,7 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp);
int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
u32 data_hi, u32 data_lo, int common);
void bnx2x_update_coalesce(struct bnx2x *bp);
-
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
{
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 02bf710629a3..efc7be4aefb5 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -20,6 +20,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
+#include <linux/firmware.h>
#include "bnx2x_cmn.h"
#ifdef BCM_VLAN
@@ -622,7 +623,7 @@ reuse_rx:
/* Set Toeplitz hash for a none-LRO skb */
bnx2x_set_skb_rxhash(bp, cqe, skb);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (bp->rx_csum) {
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -780,6 +781,10 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
ETH_MAX_AGGREGATION_QUEUES_E1H;
u16 ring_prod, cqe_ring_prod;
int i, j;
+ int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
+ MAX_RX_AVAIL/bp->num_queues;
+
+ rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size);
bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN;
DP(NETIF_MSG_IFUP,
@@ -882,7 +887,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
/* Allocate BDs and initialize BD ring */
fp->rx_comp_cons = 0;
cqe_ring_prod = ring_prod = 0;
- for (i = 0; i < bp->rx_ring_size; i++) {
+ for (i = 0; i < rx_ring_size; i++) {
if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
BNX2X_ERR("was only able to allocate "
"%d rx skbs on queue[%d]\n", i, j);
@@ -1206,12 +1211,27 @@ static int bnx2x_set_num_queues(struct bnx2x *bp)
return rc;
}
+static void bnx2x_release_firmware(struct bnx2x *bp)
+{
+ kfree(bp->init_ops_offsets);
+ kfree(bp->init_ops);
+ kfree(bp->init_data);
+ release_firmware(bp->firmware);
+}
+
/* must be called with rtnl_lock */
int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
u32 load_code;
int i, rc;
+ /* Set init arrays */
+ rc = bnx2x_init_firmware(bp);
+ if (rc) {
+ BNX2X_ERR("Error loading firmware\n");
+ return rc;
+ }
+
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return -EPERM;
@@ -1267,7 +1287,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
common blocks should be initialized, otherwise - not
*/
if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
@@ -1306,9 +1326,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
goto load_error2;
}
@@ -1323,7 +1343,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/* Send LOAD_DONE command to MCP */
if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
@@ -1427,6 +1447,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
#endif
bnx2x_inc_load_cnt(bp);
+ bnx2x_release_firmware(bp);
+
return 0;
#ifdef BCM_CNIC
@@ -1437,8 +1459,8 @@ load_error4:
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);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
}
bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
@@ -1454,6 +1476,8 @@ load_error1:
netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
+ bnx2x_release_firmware(bp);
+
return rc;
}
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index d1979b1a7ed2..d1e6a8c977d1 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -49,10 +49,11 @@ void bnx2x_link_set(struct bnx2x *bp);
* Query link status
*
* @param bp
+ * @param is_serdes
*
* @return 0 - link is UP
*/
-u8 bnx2x_link_test(struct bnx2x *bp);
+u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
/**
* Handles link status change
@@ -115,6 +116,15 @@ void bnx2x_int_enable(struct bnx2x *bp);
void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
/**
+ * Loads device firmware
+ *
+ * @param bp
+ *
+ * @return int
+ */
+int bnx2x_init_firmware(struct bnx2x *bp);
+
+/**
* Init HW blocks according to current initialization stage:
* COMMON, PORT or FUNCTION.
*
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 8b75b05e34c5..d9748e97fad3 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -29,9 +29,12 @@
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
-
- cmd->supported = bp->port.supported;
- cmd->advertising = bp->port.advertising;
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ /* Dual Media boards present all available port types */
+ cmd->supported = bp->port.supported[cfg_idx] |
+ (bp->port.supported[cfg_idx ^ 1] &
+ (SUPPORTED_TP | SUPPORTED_FIBRE));
+ cmd->advertising = bp->port.advertising[cfg_idx];
if ((bp->state == BNX2X_STATE_OPEN) &&
!(bp->flags & MF_FUNC_DIS) &&
@@ -48,47 +51,21 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->speed = vn_max_rate;
}
} else {
- cmd->speed = -1;
- cmd->duplex = -1;
+ cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+ cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
- if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- cmd->port = PORT_FIBRE;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- cmd->port = PORT_TP;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
- }
- } else
+ if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
+ else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
+ cmd->port = PORT_FIBRE;
+ else
+ BNX2X_ERR("XGXS PHY Failure detected\n");
cmd->phy_address = bp->mdio.prtad;
cmd->transceiver = XCVR_INTERNAL;
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG)
cmd->autoneg = AUTONEG_ENABLE;
else
cmd->autoneg = AUTONEG_DISABLE;
@@ -110,7 +87,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
- u32 advertising;
+ u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config;
if (IS_E1HMF(bp))
return 0;
@@ -123,26 +100,81 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ old_multi_phy_config = bp->link_params.multi_phy_config;
+ switch (cmd->port) {
+ case PORT_TP:
+ if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
+ break; /* no port change */
+
+ if (!(bp->port.supported[0] & SUPPORTED_TP ||
+ bp->port.supported[1] & SUPPORTED_TP)) {
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ break;
+ case PORT_FIBRE:
+ if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE)
+ break; /* no port change */
+
+ if (!(bp->port.supported[0] & SUPPORTED_FIBRE ||
+ bp->port.supported[1] & SUPPORTED_FIBRE)) {
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ /* Save new config in case command complete successuly */
+ new_multi_phy_config = bp->link_params.multi_phy_config;
+ /* Get the new cfg_idx */
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ /* Restore old config in case command failed */
+ bp->link_params.multi_phy_config = old_multi_phy_config;
+ DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx);
+
if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
DP(NETIF_MSG_LINK, "Autoneg not supported\n");
return -EINVAL;
}
/* advertise the requested speed and duplex if supported */
- cmd->advertising &= bp->port.supported;
+ cmd->advertising &= bp->port.supported[cfg_idx];
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->link_params.req_duplex = DUPLEX_FULL;
- bp->port.advertising |= (ADVERTISED_Autoneg |
+ bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG;
+ bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL;
+ bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg |
cmd->advertising);
} else { /* forced speed */
/* advertise the requested speed and duplex if supported */
- switch (cmd->speed) {
+ u32 speed = cmd->speed;
+ speed |= (cmd->speed_hi << 16);
+ switch (speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_10baseT_Full)) {
DP(NETIF_MSG_LINK,
"10M full not supported\n");
@@ -152,7 +184,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_10baseT_Half)) {
DP(NETIF_MSG_LINK,
"10M half not supported\n");
@@ -166,7 +198,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case SPEED_100:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_100baseT_Full)) {
DP(NETIF_MSG_LINK,
"100M full not supported\n");
@@ -176,7 +208,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->port.supported &
+ if (!(bp->port.supported[cfg_idx] &
SUPPORTED_100baseT_Half)) {
DP(NETIF_MSG_LINK,
"100M half not supported\n");
@@ -194,7 +226,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_1000baseT_Full)) {
DP(NETIF_MSG_LINK, "1G full not supported\n");
return -EINVAL;
}
@@ -210,7 +243,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) {
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_2500baseX_Full)) {
DP(NETIF_MSG_LINK,
"2.5G full not supported\n");
return -EINVAL;
@@ -226,7 +260,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) {
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_10000baseT_Full)) {
DP(NETIF_MSG_LINK, "10G full not supported\n");
return -EINVAL;
}
@@ -236,20 +271,23 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
- DP(NETIF_MSG_LINK, "Unsupported speed\n");
+ DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
return -EINVAL;
}
- bp->link_params.req_line_speed = cmd->speed;
- bp->link_params.req_duplex = cmd->duplex;
- bp->port.advertising = advertising;
+ bp->link_params.req_line_speed[cfg_idx] = speed;
+ bp->link_params.req_duplex[cfg_idx] = cmd->duplex;
+ bp->port.advertising[cfg_idx] = advertising;
}
DP(NETIF_MSG_LINK, "req_line_speed %d\n"
DP_LEVEL " req_duplex %d advertising 0x%x\n",
- bp->link_params.req_line_speed, bp->link_params.req_duplex,
- bp->port.advertising);
+ bp->link_params.req_line_speed[cfg_idx],
+ bp->link_params.req_duplex[cfg_idx],
+ bp->port.advertising[cfg_idx]);
+ /* Set new config */
+ bp->link_params.multi_phy_config = new_multi_phy_config;
if (netif_running(dev)) {
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
bnx2x_link_set(bp);
@@ -811,7 +849,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int port = BP_PORT(bp);
int rc = 0;
-
+ u32 ext_phy_config;
if (!netif_running(dev))
return -EAGAIN;
@@ -827,6 +865,10 @@ static int bnx2x_set_eeprom(struct net_device *dev,
!bp->port.pmf)
return -EINVAL;
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+
if (eeprom->magic == 0x50485950) {
/* 'PHYP' (0x50485950): prepare phy for FW upgrade */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -834,7 +876,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
bnx2x_acquire_phy_lock(bp);
rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars, 0);
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101)
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_HIGH, port);
@@ -855,10 +897,8 @@ static int bnx2x_set_eeprom(struct net_device *dev,
}
} else if (eeprom->magic == 0x53985943) {
/* 'PHYC' (0x53985943): PHY FW upgrade completed */
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
/* DSP Remove Download Mode */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
@@ -866,7 +906,8 @@ static int bnx2x_set_eeprom(struct net_device *dev,
bnx2x_acquire_phy_lock(bp);
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
+ bnx2x_sfx7101_sp_sw_reset(bp,
+ &bp->link_params.phy[EXT_PHY1]);
/* wait 0.5 sec to allow it to run */
msleep(500);
@@ -920,7 +961,14 @@ static void bnx2x_get_ringparam(struct net_device *dev,
ering->rx_mini_max_pending = 0;
ering->rx_jumbo_max_pending = 0;
- ering->rx_pending = bp->rx_ring_size;
+ if (bp->rx_ring_size)
+ ering->rx_pending = bp->rx_ring_size;
+ else
+ if (bp->state == BNX2X_STATE_OPEN && bp->num_queues)
+ ering->rx_pending = MAX_RX_AVAIL/bp->num_queues;
+ else
+ ering->rx_pending = MAX_RX_AVAIL;
+
ering->rx_mini_pending = 0;
ering->rx_jumbo_pending = 0;
@@ -940,6 +988,7 @@ static int bnx2x_set_ringparam(struct net_device *dev,
}
if ((ering->rx_pending > MAX_RX_AVAIL) ||
+ (ering->rx_pending < MIN_RX_AVAIL) ||
(ering->tx_pending > MAX_TX_AVAIL) ||
(ering->tx_pending <= MAX_SKB_FRAGS + 4))
return -EINVAL;
@@ -959,10 +1008,9 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *epause)
{
struct bnx2x *bp = netdev_priv(dev);
-
- epause->autoneg = (bp->link_params.req_flow_ctrl ==
- BNX2X_FLOW_CTRL_AUTO) &&
- (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] ==
+ BNX2X_FLOW_CTRL_AUTO);
epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
BNX2X_FLOW_CTRL_RX);
@@ -978,7 +1026,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *epause)
{
struct bnx2x *bp = netdev_priv(dev);
-
+ u32 cfg_idx = bnx2x_get_link_cfg_idx(bp);
if (IS_E1HMF(bp))
return 0;
@@ -986,29 +1034,31 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO;
if (epause->rx_pause)
- bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX;
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX;
if (epause->tx_pause)
- bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX;
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX;
- if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO)
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE;
if (epause->autoneg) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
DP(NETIF_MSG_LINK, "autoneg not supported\n");
return -EINVAL;
}
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) {
+ bp->link_params.req_flow_ctrl[cfg_idx] =
+ BNX2X_FLOW_CTRL_AUTO;
+ }
}
DP(NETIF_MSG_LINK,
- "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
+ "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]);
if (netif_running(dev)) {
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -1272,12 +1322,12 @@ test_mem_exit:
return rc;
}
-static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
+static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes)
{
int cnt = 1000;
if (link_up)
- while (bnx2x_link_test(bp) && cnt--)
+ while (bnx2x_link_test(bp, is_serdes) && cnt--)
msleep(10);
}
@@ -1304,7 +1354,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
/* check the loopback mode */
switch (loopback_mode) {
case BNX2X_PHY_LOOPBACK:
- if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+ if (bp->link_params.loopback_mode != LOOPBACK_XGXS)
return -EINVAL;
break;
case BNX2X_MAC_LOOPBACK:
@@ -1549,7 +1599,7 @@ static void bnx2x_self_test(struct net_device *dev,
struct ethtool_test *etest, u64 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
-
+ u8 is_serdes;
if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
printk(KERN_ERR "Handling parity error recovery. Try again later\n");
etest->flags |= ETH_TEST_FL_FAILED;
@@ -1564,6 +1614,7 @@ static void bnx2x_self_test(struct net_device *dev,
/* offline tests are not supported in MF mode */
if (IS_E1HMF(bp))
etest->flags &= ~ETH_TEST_FL_OFFLINE;
+ is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int port = BP_PORT(bp);
@@ -1575,11 +1626,12 @@ static void bnx2x_self_test(struct net_device *dev,
/* disable input for TX port IF */
REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
- link_up = (bnx2x_link_test(bp) == 0);
+ link_up = bp->link_vars.link_up;
+
bnx2x_nic_unload(bp, UNLOAD_NORMAL);
bnx2x_nic_load(bp, LOAD_DIAG);
/* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
+ bnx2x_wait_for_link(bp, link_up, is_serdes);
if (bnx2x_test_registers(bp) != 0) {
buf[0] = 1;
@@ -1600,7 +1652,7 @@ static void bnx2x_self_test(struct net_device *dev,
bnx2x_nic_load(bp, LOAD_NORMAL);
/* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
+ bnx2x_wait_for_link(bp, link_up, is_serdes);
}
if (bnx2x_test_nvram(bp) != 0) {
buf[3] = 1;
@@ -1611,7 +1663,7 @@ static void bnx2x_self_test(struct net_device *dev,
etest->flags |= ETH_TEST_FL_FAILED;
}
if (bp->port.pmf)
- if (bnx2x_link_test(bp) != 0) {
+ if (bnx2x_link_test(bp, is_serdes) != 0) {
buf[5] = 1;
etest->flags |= ETH_TEST_FL_FAILED;
}
@@ -1910,10 +1962,11 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
for (i = 0; i < (data * 2); i++) {
if ((i % 2) == 0)
- bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
- SPEED_1000);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OPER, SPEED_1000);
else
- bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OFF, 0);
msleep_interruptible(500);
if (signal_pending(current))
@@ -1921,7 +1974,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
}
if (bp->link_vars.link_up)
- bnx2x_set_led(&bp->link_params, LED_MODE_OPER,
+ bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER,
bp->link_vars.line_speed);
return 0;
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index fd1f29e0317d..60d141cd9950 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -78,6 +78,8 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_LED_PHY11 0x000b0000
#define SHARED_HW_CFG_LED_MAC4 0x000c0000
#define SHARED_HW_CFG_LED_PHY8 0x000d0000
+#define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000
+
#define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000
#define SHARED_HW_CFG_AN_ENABLE_SHIFT 24
@@ -120,6 +122,23 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_FAN_FAILURE_DISABLED 0x00080000
#define SHARED_HW_CFG_FAN_FAILURE_ENABLED 0x00100000
+ /* Set the MDC/MDIO access for the first external phy */
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK 0x1C000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT 26
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE 0x00000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0 0x04000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1 0x08000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH 0x0c000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED 0x10000000
+
+ /* Set the MDC/MDIO access for the second external phy */
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK 0xE0000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT 29
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_PHY_TYPE 0x00000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC0 0x20000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC1 0x40000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_BOTH 0x60000000
+#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SWAPPED 0x80000000
u32 power_dissipated; /* 0x11c */
#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
#define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24
@@ -221,7 +240,88 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
u16 xgxs_config_tx[4]; /* 0x1A0 */
- u32 Reserved1[64]; /* 0x1A8 */
+ u32 Reserved1[57]; /* 0x1A8 */
+ u32 speed_capability_mask2; /* 0x28C */
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10M_FULL 0x00000001
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3__ 0x00000002
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3___ 0x00000004
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_100M_FULL 0x00000008
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_1G 0x00000010
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_2_DOT_5G 0x00000020
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10G 0x00000040
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12G 0x00000080
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12_DOT_5G 0x00000100
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_13G 0x00000200
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_15G 0x00000400
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_16G 0x00000800
+
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_MASK 0xFFFF0000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_SHIFT 16
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10M_FULL 0x00010000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0__ 0x00020000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0___ 0x00040000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_100M_FULL 0x00080000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_1G 0x00100000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_2_DOT_5G 0x00200000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10G 0x00400000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12G 0x00800000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12_DOT_5G 0x01000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_13G 0x02000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_15G 0x04000000
+#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_16G 0x08000000
+
+ /* In the case where two media types (e.g. copper and fiber) are
+ present and electrically active at the same time, PHY Selection
+ will determine which of the two PHYs will be designated as the
+ Active PHY and used for a connection to the network. */
+ u32 multi_phy_config; /* 0x290 */
+#define PORT_HW_CFG_PHY_SELECTION_MASK 0x00000007
+#define PORT_HW_CFG_PHY_SELECTION_SHIFT 0
+#define PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT 0x00000000
+#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY 0x00000001
+#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY 0x00000002
+#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY 0x00000003
+#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY 0x00000004
+
+ /* When enabled, all second phy nvram parameters will be swapped
+ with the first phy parameters */
+#define PORT_HW_CFG_PHY_SWAPPED_MASK 0x00000008
+#define PORT_HW_CFG_PHY_SWAPPED_SHIFT 3
+#define PORT_HW_CFG_PHY_SWAPPED_DISABLED 0x00000000
+#define PORT_HW_CFG_PHY_SWAPPED_ENABLED 0x00000008
+
+
+ /* Address of the second external phy */
+ u32 external_phy_config2; /* 0x294 */
+#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_MASK 0x000000FF
+#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_SHIFT 0
+
+ /* The second XGXS external PHY type */
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_MASK 0x0000FF00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SHIFT 8
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_DIRECT 0x00000000
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8071 0x00000100
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8072 0x00000200
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8073 0x00000300
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8705 0x00000400
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8706 0x00000500
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8726 0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8481 0x00000700
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SFX7101 0x00000800
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727 0x00000900
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727_NOC 0x00000a00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00
+#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00
+
+ /* 4 times 16 bits for all 4 lanes. For some external PHYs (such as
+ 8706, 8726 and 8727) not all 4 values are needed. */
+ u16 xgxs_config2_rx[4]; /* 0x296 */
+ u16 xgxs_config2_tx[4]; /* 0x2A0 */
u32 lane_config;
#define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff
@@ -515,10 +615,17 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400
/* The default for MCP link configuration,
- uses the same defines as link_config */
+ uses the same defines as link_config */
u32 mfw_wol_link_cfg;
+ /* The default for the driver of the second external phy,
+ uses the same defines as link_config */
+ u32 link_config2; /* 0x47C */
+
+ /* The default for MCP of the second external phy,
+ uses the same defines as link_config */
+ u32 mfw_wol_link_cfg2; /* 0x480 */
- u32 reserved[19];
+ u32 Reserved2[17]; /* 0x484 */
};
@@ -686,8 +793,14 @@ struct drv_func_mb {
* The optic module verification commands require bootcode
* v5.0.6 or later
*/
-#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000
-#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006
+#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000
+#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006
+ /*
+ * The specific optic module verification command requires bootcode
+ * v5.2.12 or later
+ */
+#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000
+#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
@@ -922,7 +1035,12 @@ struct shmem2_region {
#define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040
#define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080
#define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE
-
+ u32 ext_phy_fw_version2[PORT_MAX];
+ /*
+ * For backwards compatibility, if the mf_cfg_addr does not exist
+ * (the size filed is smaller than 0xc) the mf_cfg resides at the
+ * end of struct shmem_region
+ */
};
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 0383e3066313..a07a3a6abd40 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -168,50 +168,19 @@
/**********************************************************/
/* INTERFACE */
/**********************************************************/
-#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
+
+#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
+ bnx2x_cl45_write(_bp, _phy, \
+ (_phy)->def_md_devad, \
(_bank + (_addr & 0xf)), \
_val)
-#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
+#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
+ bnx2x_cl45_read(_bp, _phy, \
+ (_phy)->def_md_devad, \
(_bank + (_addr & 0xf)), \
_val)
-static void bnx2x_set_serdes_access(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- /* Set Clause 22 */
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
- udelay(500);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
- udelay(500);
- /* Set Clause 45 */
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
-}
-static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
-
- if (phy_flags & PHY_XGXS_FLAG) {
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
- params->port*0x18, 0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
- DEFAULT_PHY_DEV_ADDR);
- } else {
- bnx2x_set_serdes_access(params);
-
- REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
- params->port*0x10,
- DEFAULT_PHY_DEV_ADDR);
- }
-}
-
static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
{
u32 val = REG_RD(bp, reg);
@@ -527,162 +496,6 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
return 0;
}
-static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
- u32 val;
-
- if (phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
- val = XGXS_RESET_BITS;
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
- val = SERDES_RESET_BITS;
- }
-
- val = val << (params->port*16);
-
- /* reset and unreset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- val);
- udelay(500);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
- val);
- bnx2x_set_phy_mdio(params, phy_flags);
-}
-
-void bnx2x_link_status_update(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 link_10g;
- u8 port = params->port;
-
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
- vars->link_status = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[port].link_status));
-
- vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
-
- if (vars->link_up) {
- DP(NETIF_MSG_LINK, "phy link up\n");
-
- vars->phy_link_up = 1;
- vars->duplex = DUPLEX_FULL;
- switch (vars->link_status &
- LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
- case LINK_10THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_10TFD:
- vars->line_speed = SPEED_10;
- break;
-
- case LINK_100TXHD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_100T4:
- case LINK_100TXFD:
- vars->line_speed = SPEED_100;
- break;
-
- case LINK_1000THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_1000TFD:
- vars->line_speed = SPEED_1000;
- break;
-
- case LINK_2500THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_2500TFD:
- vars->line_speed = SPEED_2500;
- break;
-
- case LINK_10GTFD:
- vars->line_speed = SPEED_10000;
- break;
-
- case LINK_12GTFD:
- vars->line_speed = SPEED_12000;
- break;
-
- case LINK_12_5GTFD:
- vars->line_speed = SPEED_12500;
- break;
-
- case LINK_13GTFD:
- vars->line_speed = SPEED_13000;
- break;
-
- case LINK_15GTFD:
- vars->line_speed = SPEED_15000;
- break;
-
- case LINK_16GTFD:
- vars->line_speed = SPEED_16000;
- break;
-
- default:
- break;
- }
-
- if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
- else
- vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
-
- if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
- else
- vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (vars->line_speed &&
- ((vars->line_speed == SPEED_10) ||
- (vars->line_speed == SPEED_100))) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
- }
-
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
- if (link_10g)
- vars->mac_type = MAC_TYPE_BMAC;
- else
- vars->mac_type = MAC_TYPE_EMAC;
-
- } else { /* link down */
- DP(NETIF_MSG_LINK, "phy link down\n");
-
- vars->phy_link_up = 0;
-
- vars->line_speed = 0;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
-
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
- }
-
- DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
- vars->link_status, vars->phy_link_up);
- DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
- vars->line_speed, vars->duplex, vars->flow_ctrl);
-}
static void bnx2x_update_mng(struct link_params *params, u32 link_status)
{
@@ -800,62 +613,69 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
+static u32 bnx2x_get_emac_base(struct bnx2x *bp,
+ u32 mdc_mdio_access, u8 port)
{
- u32 emac_base;
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- /* All MDC/MDIO is directed through single EMAC */
+ u32 emac_base = 0;
+ switch (mdc_mdio_access) {
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
+ if (REG_RD(bp, NIG_REG_PORT_SWAP))
+ emac_base = GRCBASE_EMAC1;
+ else
+ emac_base = GRCBASE_EMAC0;
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
if (REG_RD(bp, NIG_REG_PORT_SWAP))
emac_base = GRCBASE_EMAC0;
else
emac_base = GRCBASE_EMAC1;
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
+ emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ break;
+ case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
break;
default:
- emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
break;
}
return emac_base;
}
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val)
+u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 val)
{
u32 tmp, saved_mode;
u8 i, rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT);
tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
(49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+ REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
udelay(40);
/* address */
- tmp = ((phy_addr << 21) | (devad << 16) | reg |
+ tmp = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, phy->mdio_ctrl +
+ EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -866,15 +686,15 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
rc = -EFAULT;
} else {
/* data */
- tmp = ((phy_addr << 21) | (devad << 16) | val |
+ tmp = ((phy->addr << 21) | (devad << 16) | val |
EMAC_MDIO_COMM_COMMAND_WRITE_45 |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, mdio_ctrl +
+ tmp = REG_RD(bp, phy->mdio_ctrl +
EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
@@ -888,42 +708,41 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
}
/* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
return rc;
}
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
+u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 *ret_val)
{
u32 val, saved_mode;
u16 i;
u8 rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
+ saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT));
val |= (EMAC_MDIO_MODE_CLAUSE_45 |
(49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+ REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
udelay(40);
/* address */
- val = ((phy_addr << 21) | (devad << 16) | reg |
+ val = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -937,15 +756,15 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
} else {
/* data */
- val = ((phy_addr << 21) | (devad << 16) |
+ val = ((phy->addr << 21) | (devad << 16) |
EMAC_MDIO_COMM_COMMAND_READ_45 |
EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, mdio_ctrl +
+ val = REG_RD(bp, phy->mdio_ctrl +
EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
@@ -961,13 +780,49 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
}
/* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+ REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
return rc;
}
+u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 *ret_val)
+{
+ u8 phy_index;
+ /**
+ * Probe for the phy according to the given phy_addr, and execute
+ * the read request on it
+ */
+ for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].addr == phy_addr) {
+ return bnx2x_cl45_read(params->bp,
+ &params->phy[phy_index], devad,
+ reg, ret_val);
+ }
+ }
+ return -EINVAL;
+}
+
+u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 val)
+{
+ u8 phy_index;
+ /**
+ * Probe for the phy according to the given phy_addr, and execute
+ * the write request on it
+ */
+ for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].addr == phy_addr) {
+ return bnx2x_cl45_write(params->bp,
+ &params->phy[phy_index], devad,
+ reg, val);
+ }
+ }
+ return -EINVAL;
+}
+
static void bnx2x_set_aer_mmd(struct link_params *params,
- struct link_vars *vars)
+ struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
u32 ser_lane;
@@ -977,16 +832,202 @@ static void bnx2x_set_aer_mmd(struct link_params *params,
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
- offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
- (params->phy_addr + ser_lane) : 0;
+ offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
+ (phy->addr + ser_lane) : 0;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_AER_BLOCK,
MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
}
-static void bnx2x_set_master_ln(struct link_params *params)
+/******************************************************************/
+/* Internal phy section */
+/******************************************************************/
+
+static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
+{
+ u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ /* Set Clause 22 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
+ udelay(500);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
+ udelay(500);
+ /* Set Clause 45 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
+}
+
+static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
+{
+ u32 val;
+
+ DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
+
+ val = SERDES_RESET_BITS << (port*16);
+
+ /* reset and unreset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
+ udelay(500);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
+
+ bnx2x_set_serdes_access(bp, port);
+
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
+ port*0x10,
+ DEFAULT_PHY_DEV_ADDR);
+}
+
+static void bnx2x_xgxs_deassert(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port;
+ u32 val;
+ DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
+ port = params->port;
+
+ val = XGXS_RESET_BITS << (port*16);
+
+ /* reset and unreset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
+ udelay(500);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
+
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+ port*0x18, 0);
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
+ params->phy[INT_PHY].def_md_devad);
+}
+
+
+void bnx2x_link_status_update(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_10g;
+ u8 port = params->port;
+
+ vars->link_status = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[port].link_status));
+
+ vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
+
+ if (vars->link_up) {
+ DP(NETIF_MSG_LINK, "phy link up\n");
+
+ vars->phy_link_up = 1;
+ vars->duplex = DUPLEX_FULL;
+ switch (vars->link_status &
+ LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
+ case LINK_10THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_10TFD:
+ vars->line_speed = SPEED_10;
+ break;
+
+ case LINK_100TXHD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_100T4:
+ case LINK_100TXFD:
+ vars->line_speed = SPEED_100;
+ break;
+
+ case LINK_1000THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_1000TFD:
+ vars->line_speed = SPEED_1000;
+ break;
+
+ case LINK_2500THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_2500TFD:
+ vars->line_speed = SPEED_2500;
+ break;
+
+ case LINK_10GTFD:
+ vars->line_speed = SPEED_10000;
+ break;
+
+ case LINK_12GTFD:
+ vars->line_speed = SPEED_12000;
+ break;
+
+ case LINK_12_5GTFD:
+ vars->line_speed = SPEED_12500;
+ break;
+
+ case LINK_13GTFD:
+ vars->line_speed = SPEED_13000;
+ break;
+
+ case LINK_15GTFD:
+ vars->line_speed = SPEED_15000;
+ break;
+
+ case LINK_16GTFD:
+ vars->line_speed = SPEED_16000;
+ break;
+
+ default:
+ break;
+ }
+ vars->flow_ctrl = 0;
+ if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
+
+ if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
+
+ if (!vars->flow_ctrl)
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ if (vars->line_speed &&
+ ((vars->line_speed == SPEED_10) ||
+ (vars->line_speed == SPEED_100))) {
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ } else {
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ }
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+ if (link_10g)
+ vars->mac_type = MAC_TYPE_BMAC;
+ else
+ vars->mac_type = MAC_TYPE_EMAC;
+
+ } else { /* link down */
+ DP(NETIF_MSG_LINK, "phy link down\n");
+
+ vars->phy_link_up = 0;
+
+ vars->line_speed = 0;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+ }
+
+ DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
+ vars->link_status, vars->phy_link_up);
+ DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
+ vars->line_speed, vars->duplex, vars->flow_ctrl);
+}
+
+
+static void bnx2x_set_master_ln(struct link_params *params,
+ struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
u16 new_master_ln, ser_lane;
@@ -995,47 +1036,44 @@ static void bnx2x_set_master_ln(struct link_params *params)
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
/* set the master_ln for AN */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
&new_master_ln);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2 ,
MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
(new_master_ln | ser_lane));
}
-static u8 bnx2x_reset_unicore(struct link_params *params)
+static u8 bnx2x_reset_unicore(struct link_params *params,
+ struct bnx2x_phy *phy,
+ u8 set_serdes)
{
struct bnx2x *bp = params->bp;
u16 mii_control;
u16 i;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
/* reset the unicore */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
(mii_control |
MDIO_COMBO_IEEO_MII_CONTROL_RESET));
- if (params->switch_cfg == SWITCH_CFG_1G)
- bnx2x_set_serdes_access(params);
+ if (set_serdes)
+ bnx2x_set_serdes_access(bp, params->port);
/* wait for the reset to self clear */
for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
udelay(5);
/* the reset erased the previous bank value */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
@@ -1051,7 +1089,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
}
-static void bnx2x_set_swap_lanes(struct link_params *params)
+static void bnx2x_set_swap_lanes(struct link_params *params,
+ struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
/* Each two bits represents a lane number:
@@ -1069,71 +1108,62 @@ static void bnx2x_set_swap_lanes(struct link_params *params)
PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
if (rx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_RX_LN_SWAP,
(rx_lane_swap |
MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
} else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
}
if (tx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TX_LN_SWAP,
(tx_lane_swap |
MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
} else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
}
}
-static void bnx2x_set_parallel_detection(struct link_params *params,
- u8 phy_flags)
+static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 control2;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
&control2);
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
else
control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
- DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
- params->speed_cap_mask, control2);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
+ phy->speed_cap_mask, control2);
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
control2);
- if ((phy_flags & PHY_XGXS_FLAG) &&
- (params->speed_cap_mask &
+ if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
DP(NETIF_MSG_LINK, "XGXS\n");
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
&control2);
@@ -1142,15 +1172,13 @@ static void bnx2x_set_parallel_detection(struct link_params *params,
control2 |=
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
control2);
/* Disable parallel detection of HiG */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_XGXS_BLOCK2,
MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
@@ -1158,7 +1186,8 @@ static void bnx2x_set_parallel_detection(struct link_params *params,
}
}
-static void bnx2x_set_autoneg(struct link_params *params,
+static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars,
u8 enable_cl73)
{
@@ -1166,9 +1195,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
u16 reg_val;
/* CL37 Autoneg */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
@@ -1179,15 +1206,13 @@ static void bnx2x_set_autoneg(struct link_params *params,
reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
/* Enable/Disable Autodetection */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
@@ -1198,14 +1223,12 @@ static void bnx2x_set_autoneg(struct link_params *params,
else
reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
/* Enable TetonII and BAM autoneg */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_BAM_NEXT_PAGE,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
&reg_val);
@@ -1218,23 +1241,20 @@ static void bnx2x_set_autoneg(struct link_params *params,
reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
}
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_BAM_NEXT_PAGE,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
reg_val);
if (enable_cl73) {
/* Enable Cl73 FSM status bits */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_UCTRL,
0xe);
/* Enable BAM Station Manager*/
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_BAM_CTRL1,
MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
@@ -1242,20 +1262,18 @@ static void bnx2x_set_autoneg(struct link_params *params,
MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
/* Advertise CL73 link speeds */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV2,
&reg_val);
- if (params->speed_cap_mask &
+ if (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- if (params->speed_cap_mask &
+ if (phy->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV2,
reg_val);
@@ -1266,38 +1284,35 @@ static void bnx2x_set_autoneg(struct link_params *params,
} else /* CL73 Autoneg Disabled */
reg_val = 0;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
}
/* program SerDes, forced speed */
-static void bnx2x_program_serdes(struct link_params *params,
+static void bnx2x_program_serdes(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 reg_val;
/* program duplex, disable autoneg and sgmii*/
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
- if (params->req_duplex == DUPLEX_FULL)
+ if (phy->req_duplex == DUPLEX_FULL)
reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
/* program speed
- needed only if the speed is greater than 1G (2.5G or 10G) */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_MISC1, &reg_val);
/* clearing the speed value before setting the right speed */
@@ -1320,14 +1335,14 @@ static void bnx2x_program_serdes(struct link_params *params,
MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
}
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_MISC1, reg_val);
}
-static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
+static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 val = 0;
@@ -1335,29 +1350,28 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
/* configure the 48 bits for BAM AN */
/* set extended capabilities */
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
val |= MDIO_OVER_1G_UP1_2_5G;
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
val |= MDIO_OVER_1G_UP1_10G;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_UP1, val);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_UP3, 0x400);
}
-static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
+static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
+ struct link_params *params, u16 *ieee_fc)
{
struct bnx2x *bp = params->bp;
*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
/* resolve pause mode and advertisement
* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
- switch (params->req_flow_ctrl) {
+ switch (phy->req_flow_ctrl) {
case BNX2X_FLOW_CTRL_AUTO:
if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
*ieee_fc |=
@@ -1385,30 +1399,30 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
}
-static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
+static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 ieee_fc)
{
struct bnx2x *bp = params->bp;
u16 val;
/* for AN, we are always publishing full duplex */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1, &val);
val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1, val);
}
-static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
+static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
+ struct link_params *params,
+ u8 enable_cl73)
{
struct bnx2x *bp = params->bp;
u16 mii_control;
@@ -1417,14 +1431,12 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
/* Enable and restart BAM/CL37 aneg */
if (enable_cl73) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
&mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
(mii_control |
@@ -1432,16 +1444,14 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
} else {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
DP(NETIF_MSG_LINK,
"bnx2x_restart_autoneg mii_control before = 0x%x\n",
mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
(mii_control |
@@ -1450,7 +1460,8 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
}
}
-static void bnx2x_initialize_sgmii_process(struct link_params *params,
+static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
+ struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
@@ -1458,8 +1469,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
/* in SGMII mode, the unicore is always slave */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
&control1);
@@ -1468,8 +1478,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
control1);
@@ -1479,8 +1488,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
/* set speed, disable autoneg */
u16 mii_control;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
&mii_control);
@@ -1508,18 +1516,17 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
}
/* setting the full duplex */
- if (params->req_duplex == DUPLEX_FULL)
+ if (phy->req_duplex == DUPLEX_FULL)
mii_control |=
MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL,
mii_control);
} else { /* AN mode */
/* enable and restart AN */
- bnx2x_restart_autoneg(params, 0);
+ bnx2x_restart_autoneg(phy, params, 0);
}
}
@@ -1549,91 +1556,24 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
default:
break;
}
+ if (pause_result & (1<<0))
+ vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
+ if (pause_result & (1<<1))
+ vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
}
-static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u16 ld_pause; /* local */
- u16 lp_pause; /* link partner */
- u16 an_complete; /* AN complete */
- u16 pause_result;
- u8 ret = 0;
- u32 ext_phy_type;
- u8 port = params->port;
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* read twice */
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
-
- if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
- ret = 1;
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &ld_pause);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
- pause_result = (ld_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
- pause_result |= (lp_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
- DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
- pause_result);
- bnx2x_pause_resolve(vars, pause_result);
- if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
- ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &ld_pause);
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP, &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
-
- bnx2x_pause_resolve(vars, pause_result);
- DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
- pause_result);
- }
- }
- return ret;
-}
-
-static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
+static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 pd_10g, status2_1000x;
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ if (phy->req_line_speed != SPEED_AUTO_NEG)
+ return 0;
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
&status2_1000x);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_SERDES_DIGITAL,
MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
&status2_1000x);
@@ -1643,8 +1583,7 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
return 1;
}
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_10G_PARALLEL_DETECT,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
&pd_10g);
@@ -1657,9 +1596,10 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
return 0;
}
-static void bnx2x_flow_ctrl_resolve(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status)
+static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
{
struct bnx2x *bp = params->bp;
u16 ld_pause; /* local driver */
@@ -1669,12 +1609,13 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
/* resolve from gp_status in case of AN complete and not sgmii */
- if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
- (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
- if (bnx2x_direct_parallel_detect_used(params)) {
+ if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+ vars->flow_ctrl = phy->req_flow_ctrl;
+ else if (phy->req_line_speed != SPEED_AUTO_NEG)
+ vars->flow_ctrl = params->req_fc_auto_adv;
+ else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
+ (!(vars->phy_flags & PHY_SGMII_FLAG))) {
+ if (bnx2x_direct_parallel_detect_used(phy, params)) {
vars->flow_ctrl = params->req_fc_auto_adv;
return;
}
@@ -1684,13 +1625,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_ADV1,
&ld_pause);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB1,
MDIO_CL73_IEEEB1_AN_LP_ADV1,
&lp_pause);
@@ -1703,14 +1642,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
pause_result);
} else {
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
&ld_pause);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
&lp_pause);
@@ -1722,26 +1658,18 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
pause_result);
}
bnx2x_pause_resolve(vars, pause_result);
- } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- (bnx2x_ext_phy_resolve_fc(params, vars))) {
- return;
- } else {
- if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
- vars->flow_ctrl = params->req_fc_auto_adv;
- else
- vars->flow_ctrl = params->req_flow_ctrl;
}
DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
}
-static void bnx2x_check_fallback_to_cl37(struct link_params *params)
+static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 rx_status, ustat_val, cl37_fsm_recieved;
DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
/* Step 1: Make sure signal is detected */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_RX0,
MDIO_RX0_RX_STATUS,
&rx_status);
@@ -1749,16 +1677,14 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
(MDIO_RX0_RX_STATUS_SIGDET)) {
DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
"rx_status(0x80b0) = 0x%x\n", rx_status);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
return;
}
/* Step 2: Check CL73 state machine */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_USERB0,
MDIO_CL73_USERB0_CL73_USTAT1,
&ustat_val);
@@ -1773,8 +1699,7 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
}
/* Step 3: Check CL37 Message Pages received to indicate LP
supports only CL37 */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_REMOTE_PHY,
MDIO_REMOTE_PHY_MISC_RX_STATUS,
&cl37_fsm_recieved);
@@ -1792,25 +1717,45 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
connected to a device which does not support cl73, but does support
cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
/* Disable CL73 */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
MDIO_REG_BANK_CL73_IEEEB0,
MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
0);
/* Restart CL37 autoneg */
- bnx2x_restart_autoneg(params, 0);
+ bnx2x_restart_autoneg(phy, params, 0);
DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
}
-static u8 bnx2x_link_settings_status(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status,
- u8 ext_phy_link_up)
+
+static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
+{
+ if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
+ vars->link_status |=
+ LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+
+ if (bnx2x_direct_parallel_detect_used(phy, params))
+ vars->link_status |=
+ LINK_STATUS_PARALLEL_DETECTION_USED;
+}
+
+static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u16 new_line_speed;
+ u16 new_line_speed , gp_status;
u8 rc = 0;
- vars->link_status = 0;
+ /* Read gp_status */
+ CL45_RD_OVER_CL22(bp, phy,
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+
+ if (phy->req_line_speed == SPEED_AUTO_NEG)
+ vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
gp_status);
@@ -1823,7 +1768,12 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
else
vars->duplex = DUPLEX_HALF;
- bnx2x_flow_ctrl_resolve(params, vars, gp_status);
+ if (SINGLE_MEDIA_DIRECT(params)) {
+ bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
+ if (phy->req_line_speed == SPEED_AUTO_NEG)
+ bnx2x_xgxs_an_resolve(phy, params, vars,
+ gp_status);
+ }
switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M:
@@ -1905,56 +1855,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
return -EINVAL;
}
- /* Upon link speed change set the NIG into drain mode.
- Comes to deals with possible FIFO glitch due to clk change
- when speed is decreased without link down indicator */
- if (new_line_speed != vars->line_speed) {
- if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
- ext_phy_link_up) {
- DP(NETIF_MSG_LINK, "Internal link speed %d is"
- " different than the external"
- " link speed %d\n", new_line_speed,
- vars->line_speed);
- vars->phy_link_up = 0;
- return 0;
- }
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
- + params->port*4, 0);
- msleep(1);
- }
vars->line_speed = new_line_speed;
- vars->link_status |= LINK_STATUS_SERDES_LINK;
-
- if ((params->req_line_speed == SPEED_AUTO_NEG) &&
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
- vars->autoneg = AUTO_NEG_ENABLED;
-
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- vars->autoneg |= AUTO_NEG_COMPLETE;
- vars->link_status |=
- LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
- }
-
- vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
- vars->link_status |=
- LINK_STATUS_PARALLEL_DETECTION_USED;
-
- }
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
- vars->link_status |=
- LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
-
- if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
- vars->link_status |=
- LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
} else { /* link_down */
DP(NETIF_MSG_LINK, "phy link down\n");
@@ -1963,38 +1864,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
- vars->autoneg = AUTO_NEG_DISABLED;
vars->mac_type = MAC_TYPE_NONE;
- if ((params->req_line_speed == SPEED_AUTO_NEG) &&
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
+ if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ SINGLE_MEDIA_DIRECT(params)) {
/* Check signal is detected */
- bnx2x_check_fallback_to_cl37(params);
+ bnx2x_check_fallback_to_cl37(phy, params);
}
}
DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n",
gp_status, vars->phy_link_up, vars->line_speed);
- DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
- " autoneg 0x%x\n",
- vars->duplex,
- vars->flow_ctrl, vars->autoneg);
- DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
-
+ DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
+ vars->duplex, vars->flow_ctrl, vars->link_status);
return rc;
}
static void bnx2x_set_gmii_tx_driver(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy = &params->phy[INT_PHY];
u16 lp_up2;
u16 tx_driver;
u16 bank;
/* read precomp */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_LP_UP2, &lp_up2);
@@ -2008,8 +1903,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_RD_OVER_CL22(bp, phy,
bank,
MDIO_TX0_TX_DRIVER, &tx_driver);
@@ -2018,8 +1912,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
(tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
tx_driver |= lp_up2;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
+ CL45_WR_OVER_CL22(bp, phy,
bank,
MDIO_TX0_TX_DRIVER, tx_driver);
}
@@ -2027,7 +1920,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
}
static u8 bnx2x_emac_program(struct link_params *params,
- u32 line_speed, u32 duplex)
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -2039,7 +1932,7 @@ static u8 bnx2x_emac_program(struct link_params *params,
(EMAC_MODE_25G_MODE |
EMAC_MODE_PORT_MII_10M |
EMAC_MODE_HALF_DUPLEX));
- switch (line_speed) {
+ switch (vars->line_speed) {
case SPEED_10:
mode |= EMAC_MODE_PORT_MII_10M;
break;
@@ -2058,371 +1951,1369 @@ static u8 bnx2x_emac_program(struct link_params *params,
default:
/* 10G not valid for EMAC */
- DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
+ DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
+ vars->line_speed);
return -EINVAL;
}
- if (duplex == DUPLEX_HALF)
+ if (vars->duplex == DUPLEX_HALF)
mode |= EMAC_MODE_HALF_DUPLEX;
bnx2x_bits_en(bp,
GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
mode);
- bnx2x_set_led(params, LED_MODE_OPER, line_speed);
+ bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
return 0;
}
-/*****************************************************************************/
-/* External Phy section */
-/*****************************************************************************/
-void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
+static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
+ struct link_params *params)
{
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- msleep(1);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
+
+ u16 bank, i = 0;
+ struct bnx2x *bp = params->bp;
+
+ for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
+ bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
+ CL45_WR_OVER_CL22(bp, phy,
+ bank,
+ MDIO_RX0_RX_EQ_BOOST,
+ phy->rx_preemphasis[i]);
+ }
+
+ for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
+ CL45_WR_OVER_CL22(bp, phy,
+ bank,
+ MDIO_TX0_TX_DRIVER,
+ phy->tx_preemphasis[i]);
+ }
}
-static void bnx2x_ext_phy_reset(struct link_params *params,
- struct link_vars *vars)
+static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+ u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
+ (params->loopback_mode == LOOPBACK_XGXS));
+ if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
+ if (SINGLE_MEDIA_DIRECT(params) &&
+ (params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
+ bnx2x_set_preemphasis(phy, params);
- DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* The PHY reset is controled by GPIO 1
- * Give it 1ms of reset pulse
- */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
+ /* forced speed requested? */
+ if (vars->line_speed != SPEED_AUTO_NEG ||
+ (SINGLE_MEDIA_DIRECT(params) &&
+ params->loopback_mode == LOOPBACK_EXT)) {
+ DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- break;
+ /* disable autoneg */
+ bnx2x_set_autoneg(phy, params, vars, 0);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+ /* program speed and duplex */
+ bnx2x_program_serdes(phy, params, vars);
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* AN_mode */
+ DP(NETIF_MSG_LINK, "not SGMII, AN\n");
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
+ /* AN enabled */
+ bnx2x_set_brcm_cl37_advertisment(phy, params);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0xa040);
- break;
+ /* program duplex & pause advertisement (for aneg) */
+ bnx2x_set_ieee_aneg_advertisment(phy, params,
+ vars->ieee_fc);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- break;
+ /* enable autoneg */
+ bnx2x_set_autoneg(phy, params, vars, enable_cl73);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* enable and restart AN */
+ bnx2x_restart_autoneg(phy, params, enable_cl73);
+ }
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* SGMII mode */
+ DP(NETIF_MSG_LINK, "SGMII\n");
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ bnx2x_initialize_sgmii_process(phy, params, vars);
+ }
+}
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
+static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc;
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ bnx2x_set_aer_mmd(params, phy);
+ rc = bnx2x_reset_unicore(params, phy, 1);
+ /* reset the SerDes and wait for reset bit return low */
+ if (rc != 0)
+ return rc;
+ bnx2x_set_aer_mmd(params, phy);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- DP(NETIF_MSG_LINK, "XGXS 8072\n");
+ return rc;
+}
- /* Unset Low Power Mode and SW reset */
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc;
+ vars->phy_flags = PHY_XGXS_FLAG;
+ if ((phy->req_line_speed &&
+ ((phy->req_line_speed == SPEED_100) ||
+ (phy->req_line_speed == SPEED_10))) ||
+ (!phy->req_line_speed &&
+ (phy->speed_cap_mask >=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+ (phy->speed_cap_mask <
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ ))
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ else
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ bnx2x_set_aer_mmd(params, phy);
+ bnx2x_set_master_ln(params, phy);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- DP(NETIF_MSG_LINK, "XGXS 8073\n");
+ rc = bnx2x_reset_unicore(params, phy, 0);
+ /* reset the SerDes and wait for reset bit return low */
+ if (rc != 0)
+ return rc;
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ bnx2x_set_aer_mmd(params, phy);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ /* setting the masterLn_def again after the reset */
+ bnx2x_set_master_ln(params, phy);
+ bnx2x_set_swap_lanes(params, phy);
+
+ return rc;
+}
+
+static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ u16 cnt, ctrl;
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
+ if (!(ctrl & (1<<15)))
break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+ return cnt;
+}
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
+static void bnx2x_link_int_enable(struct link_params *params)
+{
+ u8 port = params->port;
+ u32 mask;
+ struct bnx2x *bp = params->bp;
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ /* setting the status to report on link up
+ for either XGXS or SerDes */
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
- break;
+ if (params->switch_cfg == SWITCH_CFG_10G) {
+ mask = (NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_XGXS0_LINK_STATUS);
+ DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+ if (!(SINGLE_MEDIA_DIRECT(params)) &&
+ params->phy[INT_PHY].type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
+ } else { /* SerDes */
+ mask = NIG_MASK_SERDES0_LINK_STATUS;
+ DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+ if (!(SINGLE_MEDIA_DIRECT(params)) &&
+ params->phy[INT_PHY].type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
+ }
+ bnx2x_bits_en(bp,
+ NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ mask);
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, params->port);
+ DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
+ (params->switch_cfg == SWITCH_CFG_10G),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+ DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+}
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
- break;
+static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
+ u8 exp_mi_int)
+{
+ u32 latch_status = 0;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
+ /**
+ * Disable the MI INT ( external phy int ) by writing 1 to the
+ * status register. Link down indication is high-active-signal,
+ * so in this case we need to write the status to clear the XOR
+ */
+ /* Read Latched signals */
+ latch_status = REG_RD(bp,
+ NIG_REG_LATCH_STATUS_0 + port*8);
+ DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
+ /* Handle only those with latched-signal=up.*/
+ if (exp_mi_int)
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0
+ + port*4,
+ NIG_STATUS_EMAC0_MI_INT);
+ else
+ bnx2x_bits_dis(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0
+ + port*4,
+ NIG_STATUS_EMAC0_MI_INT);
+
+ if (latch_status & 1) {
+
+ /* For all latched-signal=up : Re-Arm Latch signals */
+ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
+ (latch_status & 0xfffe) | (latch_status & 1));
+ }
+ /* For all latched-signal=up,Write original_signal to status */
+}
+
+static void bnx2x_link_int_ack(struct link_params *params,
+ struct link_vars *vars, u8 is_10g)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+
+ /* first reset all status
+ * we assume only one line will be change at a time */
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+ if (vars->phy_link_up) {
+ if (is_10g) {
+ /* Disable the 10G link interrupt
+ * by writing 1 to the status register
+ */
+ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_XGXS0_LINK10G);
+
+ } else if (params->switch_cfg == SWITCH_CFG_10G) {
+ /* Disable the link interrupt
+ * by writing 1 to the relevant lane
+ * in the status register
+ */
+ u32 ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
+ vars->line_speed);
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ ((1 << ser_lane) <<
+ NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
+
+ } else { /* SerDes */
+ DP(NETIF_MSG_LINK, "SerDes phy link up\n");
+ /* Disable the link interrupt
+ * by writing 1 to the status register
+ */
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_SERDES0_LINK_STATUS);
}
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
+ }
+}
+
+static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
+{
+ u8 *str_ptr = str;
+ u32 mask = 0xf0000000;
+ u8 shift = 8*4;
+ u8 digit;
+ u8 remove_leading_zeros = 1;
+ if (*len < 10) {
+ /* Need more than 10chars for this format */
+ *str_ptr = '\0';
+ (*len)--;
+ return -EINVAL;
+ }
+ while (shift > 0) {
+
+ shift -= 4;
+ digit = ((num & mask) >> shift);
+ if (digit == 0 && remove_leading_zeros) {
+ mask = mask >> 4;
+ continue;
+ } else if (digit < 0xa)
+ *str_ptr = digit + '0';
+ else
+ *str_ptr = digit - 0xa + 'a';
+ remove_leading_zeros = 0;
+ str_ptr++;
+ (*len)--;
+ mask = mask >> 4;
+ if (shift == 4*4) {
+ *str_ptr = '.';
+ str_ptr++;
+ (*len)--;
+ remove_leading_zeros = 1;
+ }
+ }
+ return 0;
+}
+
+
+static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
+{
+ str[0] = '\0';
+ (*len)--;
+ return 0;
+}
+
+u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
+ u8 *version, u16 len)
+{
+ struct bnx2x *bp;
+ u32 spirom_ver = 0;
+ u8 status = 0;
+ u8 *ver_p = version;
+ u16 remain_len = len;
+ if (version == NULL || params == NULL)
+ return -EINVAL;
+ bp = params->bp;
+
+ /* Extract first external phy*/
+ version[0] = '\0';
+ spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
+
+ if (params->phy[EXT_PHY1].format_fw_ver) {
+ status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
+ ver_p,
+ &remain_len);
+ ver_p += (len - remain_len);
+ }
+ if ((params->num_phys == MAX_PHYS) &&
+ (params->phy[EXT_PHY2].ver_addr != 0)) {
+ spirom_ver = REG_RD(bp,
+ params->phy[EXT_PHY2].ver_addr);
+ if (params->phy[EXT_PHY2].format_fw_ver) {
+ *ver_p = '/';
+ ver_p++;
+ remain_len--;
+ status |= params->phy[EXT_PHY2].format_fw_ver(
+ spirom_ver,
+ ver_p,
+ &remain_len);
+ ver_p = version + (len - remain_len);
+ }
+ }
+ *ver_p = '\0';
+ return status;
+}
+
+static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ u8 port = params->port;
+ struct bnx2x *bp = params->bp;
+
+ if (phy->req_line_speed != SPEED_1000) {
+ u32 md_devad;
+
+ DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+
+ /* change the uni_phy_addr in the nig */
+ md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
+ port*0x18));
+
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+
+ bnx2x_cl45_write(bp, phy,
+ 5,
+ (MDIO_REG_BANK_AER_BLOCK +
+ (MDIO_AER_BLOCK_AER_REG & 0xf)),
+ 0x2800);
+
+ bnx2x_cl45_write(bp, phy,
+ 5,
+ (MDIO_REG_BANK_CL73_IEEEB0 +
+ (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
+ 0x6041);
+ msleep(200);
+ /* set aer mmd back */
+ bnx2x_set_aer_mmd(params, phy);
+
+ /* and md_devad */
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
+ md_devad);
+
+ } else {
+ u16 mii_ctrl;
+ DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+ bnx2x_cl45_read(bp, phy, 5,
+ (MDIO_REG_BANK_COMBO_IEEE0 +
+ (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
+ &mii_ctrl);
+ bnx2x_cl45_write(bp, phy, 5,
+ (MDIO_REG_BANK_COMBO_IEEE0 +
+ (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
+ mii_ctrl |
+ MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
+ }
+}
+
+/*
+ *------------------------------------------------------------------------
+ * bnx2x_override_led_value -
+ *
+ * Override the led value of the requested led
+ *
+ *------------------------------------------------------------------------
+ */
+u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
+ u32 led_idx, u32 value)
+{
+ u32 reg_val;
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_ext_phy_hw_reset(bp, params->port);
+ /* If port 0 then use EMAC0, else use EMAC1*/
+ u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() port %x led_idx %d value %d\n",
+ port, led_idx, value);
+
+ switch (led_idx) {
+ case 0: /* 10MB led */
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 10M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_10MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 1: /*100MB led */
+ /*Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 100M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_100MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 2: /* 1000MB led */
+ /* Read the current value of the LED register in the
+ EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
+ reset it. */
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 3: /* 2500MB led */
+ /* Read the current value of the LED register in the
+ EMAC block*/
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 4: /*10G led */
+ if (port == 0) {
+ REG_WR(bp, NIG_REG_LED_10G_P0,
+ value);
+ } else {
+ REG_WR(bp, NIG_REG_LED_10G_P1,
+ value);
+ }
+ break;
+ case 5: /* TRAFFIC led */
+ /* Find if the traffic control is via BMAC or EMAC */
+ if (port == 0)
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
+ else
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
+
+ /* Override the traffic led in the EMAC:*/
+ if (reg_val == 1) {
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base +
+ EMAC_REG_EMAC_LED);
+ /* Set the TRAFFIC_OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the TRAFFIC bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
+ (reg_val & ~EMAC_LED_TRAFFIC);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ } else { /* Override the traffic led in the BMAC: */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
+ value);
+ }
+ break;
+ default:
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() unknown led index %d "
+ "(should be 0-5)\n", led_idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+u8 bnx2x_set_led(struct link_params *params,
+ struct link_vars *vars, u8 mode, u32 speed)
+{
+ u8 port = params->port;
+ u16 hw_led_mode = params->hw_led_mode;
+ u8 rc = 0, phy_idx;
+ u32 tmp;
+ u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
+ DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
+ speed, hw_led_mode);
+ /* In case */
+ for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
+ if (params->phy[phy_idx].set_link_led) {
+ params->phy[phy_idx].set_link_led(
+ &params->phy[phy_idx], params, mode);
+ }
+ }
+
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ SHARED_HW_CFG_LED_MAC1);
+
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
+ break;
+
+ case LED_MODE_OPER:
+ /**
+ * For all other phys, OPER mode is same as ON, so in case
+ * link is down, do nothing
+ **/
+ if (!vars->link_up)
break;
+ case LED_MODE_ON:
+ if (SINGLE_MEDIA_DIRECT(params)) {
+ /**
+ * This is a work-around for HW issue found when link
+ * is up in CL73
+ */
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+ } else {
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ hw_led_mode);
+ }
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
+ port*4, 0);
+ /* Set blinking rate to ~15.9Hz */
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+ LED_BLINK_RATE_VAL);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
+ port*4, 1);
+ tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+ EMAC_WR(bp, EMAC_REG_EMAC_LED,
+ (tmp & (~EMAC_LED_OVERRIDE)));
+
+ if (CHIP_IS_E1(bp) &&
+ ((speed == SPEED_2500) ||
+ (speed == SPEED_1000) ||
+ (speed == SPEED_100) ||
+ (speed == SPEED_10))) {
+ /* On Everest 1 Ax chip versions for speeds less than
+ 10G LED scheme is different */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
+ port*4, 0);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
+ port*4, 1);
+ }
+ break;
+
+ default:
+ rc = -EINVAL;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
+ mode);
+ break;
+ }
+ return rc;
+
+}
+
+/**
+ * This function comes to reflect the actual link state read DIRECTLY from the
+ * HW
+ */
+u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
+ u8 is_serdes)
+{
+ struct bnx2x *bp = params->bp;
+ u16 gp_status = 0, phy_index = 0;
+ u8 ext_phy_link_up = 0, serdes_phy_type;
+ struct link_vars temp_vars;
+
+ CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+ /* link is up only if both local phy and external phy are up */
+ if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
+ return -ESRCH;
+
+ switch (params->num_phys) {
+ case 1:
+ /* No external PHY */
+ return 0;
+ case 2:
+ ext_phy_link_up = params->phy[EXT_PHY1].read_status(
+ &params->phy[EXT_PHY1],
+ params, &temp_vars);
+ break;
+ case 3: /* Dual Media */
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ serdes_phy_type = ((params->phy[phy_index].media_type ==
+ ETH_PHY_SFP_FIBER) ||
+ (params->phy[phy_index].media_type ==
+ ETH_PHY_XFP_FIBER));
+
+ if (is_serdes != serdes_phy_type)
+ continue;
+ if (params->phy[phy_index].read_status) {
+ ext_phy_link_up |=
+ params->phy[phy_index].read_status(
+ &params->phy[phy_index],
+ params, &temp_vars);
+ }
+ }
+ break;
+ }
+ if (ext_phy_link_up)
+ return 0;
+ return -ESRCH;
+}
+
+static u8 bnx2x_link_initialize(struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 rc = 0;
+ u8 phy_index, non_ext_phy;
+ struct bnx2x *bp = params->bp;
+ /**
+ * In case of external phy existence, the line speed would be the
+ * line speed linked up by the external phy. In case it is direct
+ * only, then the line_speed during initialization will be
+ * equal to the req_line_speed
+ */
+ vars->line_speed = params->phy[INT_PHY].req_line_speed;
+
+ /**
+ * Initialize the internal phy in case this is a direct board
+ * (no external phys), or this board has external phy which requires
+ * to first.
+ */
+
+ if (params->phy[INT_PHY].config_init)
+ params->phy[INT_PHY].config_init(
+ &params->phy[INT_PHY],
+ params, vars);
+
+ /* init ext phy and enable link state int */
+ non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
+ (params->loopback_mode == LOOPBACK_XGXS));
+
+ if (non_ext_phy ||
+ (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+ struct bnx2x_phy *phy = &params->phy[INT_PHY];
+ if (vars->line_speed == SPEED_AUTO_NEG)
+ bnx2x_set_parallel_detection(phy, params);
+ bnx2x_init_internal_phy(phy, params, vars);
+ }
+
+ /* Init external phy*/
+ if (!non_ext_phy)
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ /**
+ * No need to initialize second phy in case of first
+ * phy only selection. In case of second phy, we do
+ * need to initialize the first phy, since they are
+ * connected.
+ **/
+ if (phy_index == EXT_PHY2 &&
+ (bnx2x_phy_selection(params) ==
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
+ DP(NETIF_MSG_LINK, "Not initializing"
+ "second phy\n");
+ continue;
+ }
+ params->phy[phy_index].config_init(
+ &params->phy[phy_index],
+ params, vars);
+ }
+
+ /* Reset the interrupt indication after phy was initialized */
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
+ params->port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS |
+ NIG_MASK_MI_INT));
+ return rc;
+}
+
+static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ /* reset the SerDes/XGXS */
+ REG_WR(params->bp, GRCBASE_MISC +
+ MISC_REGISTERS_RESET_REG_3_CLEAR,
+ (0x1ff << (params->port*16)));
+}
+
+static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 gpio_port;
+ /* HW reset */
+ gpio_port = params->port;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+ DP(NETIF_MSG_LINK, "reset external PHY\n");
+}
+
+static u8 bnx2x_update_link_down(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+
+ DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
+ bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+
+ /* update shared memory */
+ vars->link_status = 0;
+ vars->line_speed = 0;
+ bnx2x_update_mng(params, vars->link_status);
+
+ /* activate nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
+ /* reset BigMac */
+ bnx2x_bmac_rx_disable(bp, params->port);
+ REG_WR(bp, GRCBASE_MISC +
+ MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ return 0;
+}
+
+static u8 bnx2x_update_link_up(struct link_params *params,
+ struct link_vars *vars,
+ u8 link_10g)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 rc = 0;
+
+ vars->link_status |= LINK_STATUS_LINK_UP;
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ vars->link_status |=
+ LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
+
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ vars->link_status |=
+ LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
+
+ if (link_10g) {
+ bnx2x_bmac_enable(params, vars, 0);
+ bnx2x_set_led(params, vars,
+ LED_MODE_OPER, SPEED_10000);
+ } else {
+ rc = bnx2x_emac_program(params, vars);
+
+ bnx2x_emac_enable(params, vars, 0);
+
+ /* AN complete? */
+ if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
+ && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
+ SINGLE_MEDIA_DIRECT(params))
+ bnx2x_set_gmii_tx_driver(params);
+ }
+
+ /* PBF - link up */
+ rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
+ vars->line_speed);
+
+ /* disable drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
+
+ /* update shared memory */
+ bnx2x_update_mng(params, vars->link_status);
+ msleep(20);
+ return rc;
+}
+/**
+ * The bnx2x_link_update function should be called upon link
+ * interrupt.
+ * Link is considered up as follows:
+ * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
+ * to be up
+ * - SINGLE_MEDIA - The link between the 577xx and the external
+ * phy (XGXS) need to up as well as the external link of the
+ * phy (PHY_EXT1)
+ * - DUAL_MEDIA - The link between the 577xx and the first
+ * external phy needs to be up, and at least one of the 2
+ * external phy link must be up.
+ */
+u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ struct link_vars phy_vars[MAX_PHYS];
+ u8 port = params->port;
+ u8 link_10g, phy_index;
+ u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
+ u8 is_mi_int = 0;
+ u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
+ u8 active_external_phy = INT_PHY;
+ vars->link_status = 0;
+ for (phy_index = INT_PHY; phy_index < params->num_phys;
+ phy_index++) {
+ phy_vars[phy_index].flow_ctrl = 0;
+ phy_vars[phy_index].link_status = 0;
+ phy_vars[phy_index].line_speed = 0;
+ phy_vars[phy_index].duplex = DUPLEX_FULL;
+ phy_vars[phy_index].phy_link_up = 0;
+ phy_vars[phy_index].link_up = 0;
+ }
+
+ DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
+ port, (vars->phy_flags & PHY_XGXS_FLAG),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+
+ is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
+ port*0x18) > 0);
+ DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ is_mi_int,
+ REG_RD(bp,
+ NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
+
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ /**
+ * Step 1:
+ * Check external link change only for external phys, and apply
+ * priority selection between them in case the link on both phys
+ * is up. Note that the instead of the common vars, a temporary
+ * vars argument is used since each phy may have different link/
+ * speed/duplex result
+ */
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ struct bnx2x_phy *phy = &params->phy[phy_index];
+ if (!phy->read_status)
+ continue;
+ /* Read link status and params of this ext phy */
+ cur_link_up = phy->read_status(phy, params,
+ &phy_vars[phy_index]);
+ if (cur_link_up) {
+ DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
+ phy_index);
+ } else {
+ DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
+ phy_index);
+ continue;
+ }
+
+ if (!ext_phy_link_up) {
+ ext_phy_link_up = 1;
+ active_external_phy = phy_index;
+ } else {
+ switch (bnx2x_phy_selection(params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ /**
+ * In this option, the first PHY makes sure to pass the
+ * traffic through itself only.
+ * Its not clear how to reset the link on the second phy
+ **/
+ active_external_phy = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ /**
+ * In this option, the first PHY makes sure to pass the
+ * traffic through the second PHY.
+ **/
+ active_external_phy = EXT_PHY2;
+ break;
+ default:
+ /**
+ * Link indication on both PHYs with the following cases
+ * is invalid:
+ * - FIRST_PHY means that second phy wasn't initialized,
+ * hence its link is expected to be down
+ * - SECOND_PHY means that first phy should not be able
+ * to link up by itself (using configuration)
+ * - DEFAULT should be overriden during initialiazation
+ **/
+ DP(NETIF_MSG_LINK, "Invalid link indication"
+ "mpc=0x%x. DISABLING LINK !!!\n",
+ params->multi_phy_config);
+ ext_phy_link_up = 0;
+ break;
+ }
+ }
+ }
+ prev_line_speed = vars->line_speed;
+ /**
+ * Step 2:
+ * Read the status of the internal phy. In case of
+ * DIRECT_SINGLE_MEDIA board, this link is the external link,
+ * otherwise this is the link between the 577xx and the first
+ * external phy
+ */
+ if (params->phy[INT_PHY].read_status)
+ params->phy[INT_PHY].read_status(
+ &params->phy[INT_PHY],
+ params, vars);
+ /**
+ * The INT_PHY flow control reside in the vars. This include the
+ * case where the speed or flow control are not set to AUTO.
+ * Otherwise, the active external phy flow control result is set
+ * to the vars. The ext_phy_line_speed is needed to check if the
+ * speed is different between the internal phy and external phy.
+ * This case may be result of intermediate link speed change.
+ */
+ if (active_external_phy > INT_PHY) {
+ vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
+ /**
+ * Link speed is taken from the XGXS. AN and FC result from
+ * the external phy.
+ */
+ vars->link_status |= phy_vars[active_external_phy].link_status;
+
+ /**
+ * if active_external_phy is first PHY and link is up - disable
+ * disable TX on second external PHY
+ */
+ if (active_external_phy == EXT_PHY1) {
+ if (params->phy[EXT_PHY2].phy_specific_func) {
+ DP(NETIF_MSG_LINK, "Disabling TX on"
+ " EXT_PHY2\n");
+ params->phy[EXT_PHY2].phy_specific_func(
+ &params->phy[EXT_PHY2],
+ params, DISABLE_TX);
+ }
+ }
+
+ ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
+ vars->duplex = phy_vars[active_external_phy].duplex;
+ if (params->phy[active_external_phy].supported &
+ SUPPORTED_FIBRE)
+ vars->link_status |= LINK_STATUS_SERDES_LINK;
+ DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
+ active_external_phy);
+ }
+
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ if (params->phy[phy_index].flags &
+ FLAGS_REARM_LATCH_SIGNAL) {
+ bnx2x_rearm_latch_signal(bp, port,
+ phy_index ==
+ active_external_phy);
break;
}
}
+ DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
+ " ext_phy_line_speed = %d\n", vars->flow_ctrl,
+ vars->link_status, ext_phy_line_speed);
+ /**
+ * Upon link speed change set the NIG into drain mode. Comes to
+ * deals with possible FIFO glitch due to clk change when speed
+ * is decreased without link down indicator
+ */
+
+ if (vars->phy_link_up) {
+ if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
+ (ext_phy_line_speed != vars->line_speed)) {
+ DP(NETIF_MSG_LINK, "Internal link speed %d is"
+ " different than the external"
+ " link speed %d\n", vars->line_speed,
+ ext_phy_line_speed);
+ vars->phy_link_up = 0;
+ } else if (prev_line_speed != vars->line_speed) {
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+ msleep(1);
+ }
+ }
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+
+ bnx2x_link_int_ack(params, vars, link_10g);
+
+ /**
+ * In case external phy link is up, and internal link is down
+ * (not initialized yet probably after link initialization, it
+ * needs to be initialized.
+ * Note that after link down-up as result of cable plug, the xgxs
+ * link would probably become up again without the need
+ * initialize it
+ */
+ if (!(SINGLE_MEDIA_DIRECT(params))) {
+ DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
+ " init_preceding = %d\n", ext_phy_link_up,
+ vars->phy_link_up,
+ params->phy[EXT_PHY1].flags &
+ FLAGS_INIT_XGXS_FIRST);
+ if (!(params->phy[EXT_PHY1].flags &
+ FLAGS_INIT_XGXS_FIRST)
+ && ext_phy_link_up && !vars->phy_link_up) {
+ vars->line_speed = ext_phy_line_speed;
+ if (vars->line_speed < SPEED_1000)
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ else
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ bnx2x_init_internal_phy(&params->phy[INT_PHY],
+ params,
+ vars);
+ }
+ }
+ /**
+ * Link is up only if both local phy and external phy (in case of
+ * non-direct board) are up
+ */
+ vars->link_up = (vars->phy_link_up &&
+ (ext_phy_link_up ||
+ SINGLE_MEDIA_DIRECT(params)));
+
+ if (vars->link_up)
+ rc = bnx2x_update_link_up(params, vars, link_10g);
+ else
+ rc = bnx2x_update_link_down(params, vars);
+
+ return rc;
+}
+
+
+/*****************************************************************************/
+/* External Phy section */
+/*****************************************************************************/
+void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
+{
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
}
static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
- u32 shmem_base, u32 spirom_ver)
+ u32 spirom_ver, u32 ver_addr)
{
DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
(u16)(spirom_ver>>16), (u16)spirom_ver, port);
- REG_WR(bp, shmem_base +
- offsetof(struct shmem_region,
- port_mb[port].ext_phy_fw_version),
- spirom_ver);
+
+ if (ver_addr)
+ REG_WR(bp, ver_addr, spirom_ver);
}
-static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
- u32 ext_phy_type, u8 ext_phy_addr,
- u32 shmem_base)
+static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port)
{
u16 fw_ver1, fw_ver2;
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- bnx2x_save_spirom_version(bp, port, shmem_base,
- (u32)(fw_ver1<<16 | fw_ver2));
+ bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
+ phy->ver_addr);
}
-
-static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr, u32 shmem_base)
+static void bnx2x_ext_phy_set_pause(struct link_params *params,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
{
- u16 val, fw_ver1, fw_ver2, cnt;
- /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
- /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA819, 0x0014);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81A,
- 0xc200);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81B,
- 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81C,
- 0x0300);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA817,
- 0x0009);
+ u16 val;
+ struct bnx2x *bp = params->bp;
+ /* read modify write pause advertizing */
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA818,
- &val);
- if (val & 1)
- break;
- udelay(5);
+ val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
+
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
+ val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
}
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
- bnx2x_save_spirom_version(bp, port,
- shmem_base, 0);
- return;
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
+ val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
}
+ DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
+}
+static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ u16 pause_result;
+ u8 ret = 0;
+ /* read twice */
- /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA819, 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA81A, 0xc200);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr, MDIO_PMA_DEVAD,
- 0xA817, 0x000A);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA818,
- &val);
- if (val & 1)
- break;
- udelay(5);
+ vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+
+ if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+ vars->flow_ctrl = phy->req_flow_ctrl;
+ else if (phy->req_line_speed != SPEED_AUTO_NEG)
+ vars->flow_ctrl = params->req_fc_auto_adv;
+ else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+ ret = 1;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
+ pause_result |= (lp_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
+ DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
+ pause_result);
+ bnx2x_pause_resolve(vars, pause_result);
}
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
- bnx2x_save_spirom_version(bp, port,
- shmem_base, 0);
+ return ret;
+}
+
+static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
+{
+ u16 val;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &val);
+ if (val & (1<<5))
+ vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+ if ((val & (1<<0)) == 0)
+ vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
+}
+
+/******************************************************************/
+/* common BCM8073/BCM8727 PHY SECTION */
+/******************************************************************/
+static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ if (phy->req_line_speed == SPEED_10 ||
+ phy->req_line_speed == SPEED_100) {
+ vars->flow_ctrl = phy->req_flow_ctrl;
return;
}
- /* lower 16 bits of the register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81B,
- &fw_ver1);
- /* upper 16 bits of register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xA81C,
- &fw_ver2);
+ if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
+ (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
+ u16 pause_result;
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LD, &ld_pause);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LP, &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
+ pause_result |= (lp_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
- bnx2x_save_spirom_version(bp, port,
- shmem_base, (fw_ver2<<16) | fw_ver1);
+ bnx2x_pause_resolve(vars, pause_result);
+ DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
+ pause_result);
+ }
}
-static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
+static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port)
{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* Boot port from external ROM */
+ /* EDC grst */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x0001);
- /* Need to wait 200ms after reset */
- msleep(200);
- /* Boot port from external ROM
- * Set ser_boot_ctl bit in the MISC_CTRL1 register
- */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ /* ucode reboot and rst */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x008c);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
/* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* set micro reset = 0 */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* wait for 100ms for code download via SPI port */
- msleep(100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+
+ /* Release srst bit */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 120ms for code download via SPI port */
+ msleep(120);
/* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- /* Wait 100ms */
- msleep(100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ bnx2x_save_bcm_spirom_ver(bp, phy, port);
+}
+
+static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ u16 val;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
+ if (val == 0) {
+ /* Mustn't set low power mode in 8073 A0 */
+ return;
+ }
+
+ /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
+ val &= ~(1<<13);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
+
+ /* PLL controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
+
+ /* Tx Controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
+
+ /* Rx Controls */
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
+
+ /* Enable PLL sequencer (use read-modify-write to set bit 13) */
+ bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
+ val |= (1<<13);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
}
-static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
+/******************************************************************/
+/* BCM8073 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
{
/* This is only required for 8073A1, version 102 only */
-
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val;
/* Read 8073 HW revision*/
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_CHIP_REV, &val);
@@ -2431,9 +3322,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
return 0;
}
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2, &val);
@@ -2444,15 +3333,11 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
return 1;
}
-static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
+static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val, cnt, cnt1 ;
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_CHIP_REV, &val);
@@ -2466,9 +3351,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
poll Dev1, Reg $C820: */
for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
&val);
@@ -2485,9 +3368,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
XAUI workaround has completed),
then continue on with system initialization.*/
for (cnt1 = 0; cnt1 < 1000; cnt1++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_XAUI_WA, &val);
if (val & (1<<15)) {
@@ -2505,143 +3386,385 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
return -EINVAL;
}
-static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 ext_phy_type,
- u32 shmem_base)
+static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
{
- /* Boot port from external ROM */
- /* EDC grst */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x0001);
+ /* Force KR or KX */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
+}
- /* ucode reboot and rst */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x008c);
+static void bnx2x_8073_set_pause_cl37(struct link_params *params,
+ struct bnx2x_phy *phy,
+ struct link_vars *vars)
+{
+ u16 cl37_val;
+ struct bnx2x *bp = params->bp;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
+ }
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ }
+ if ((vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
+ cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ }
+ DP(NETIF_MSG_LINK,
+ "Ext phy AN advertize cl37 0x%x\n", cl37_val);
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
+ msleep(500);
+}
- /* Release srst bit */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val = 0, tmp1;
+ u8 gpio_port;
+ DP(NETIF_MSG_LINK, "Init 8073\n");
- /* wait for 100ms for code download via SPI port */
- msleep(100);
+ gpio_port = params->port;
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
- /* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- shmem_base);
-}
+ /* enable LASI */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
-static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 shmem_base)
-{
- bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- shmem_base);
-}
+ bnx2x_8073_set_pause_cl37(params, phy, vars);
-static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- u32 shmem_base)
-{
- bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- shmem_base);
+ bnx2x_8073_set_xaui_low_power_mode(bp, phy);
-}
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
-static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
- /* Need to wait 100ms after reset */
- msleep(100);
+ DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
- /* Micro controller re-boot */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x018B);
+ /* Enable CL37 BAM */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8073_BAM, &val);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8073_BAM, val | 1);
- /* Set soft reset */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+ if (params->loopback_mode == LOOPBACK_EXT) {
+ bnx2x_807x_force_10G(bp, phy);
+ DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
+ return 0;
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
+ }
+ if (phy->req_line_speed != SPEED_AUTO_NEG) {
+ if (phy->req_line_speed == SPEED_10000) {
+ val = (1<<7);
+ } else if (phy->req_line_speed == SPEED_2500) {
+ val = (1<<5);
+ /* Note that 2.5G works only
+ when used with 1G advertisment */
+ } else
+ val = (1<<5);
+ } else {
+ val = 0;
+ if (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ val |= (1<<7);
+
+ /* Note that 2.5G works only when
+ used with 1G advertisment */
+ if (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
+ val |= (1<<5);
+ DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
+ }
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
+
+ if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
+ (phy->req_line_speed == SPEED_AUTO_NEG)) ||
+ (phy->req_line_speed == SPEED_2500)) {
+ u16 phy_ver;
+ /* Allow 2.5G for A1 and above */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
+ &phy_ver);
+ DP(NETIF_MSG_LINK, "Add 2.5G\n");
+ if (phy_ver > 0)
+ tmp1 |= 1;
+ else
+ tmp1 &= 0xfffe;
+ } else {
+ DP(NETIF_MSG_LINK, "Disable 2.5G\n");
+ tmp1 &= 0xfffe;
+ }
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
+ /* Add support for CL37 (passive mode) II */
- /* wait for 150ms for microcode load */
- msleep(150);
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
+ (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
+ 0x20 : 0x40)));
- /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ /* Add support for CL37 (passive mode) III */
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
- msleep(200);
- bnx2x_save_bcm_spirom_ver(bp, port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
+ /* The SNR will improve about 2db by changing
+ BW and FEE main tap. Rest commands are executed
+ after link is up*/
+ if (bnx2x_8073_is_snr_needed(bp, phy))
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
+ 0xFB0C);
+
+ /* Enable FEC (Forware Error Correction) Request in the AN */
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
+ tmp1 |= (1<<15);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+
+ /* Restart autoneg */
+ msleep(500);
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
+ ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
+ return 0;
+}
+
+static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_up = 0;
+ u16 val1, val2;
+ u16 link_status = 0;
+ u16 an1000_status = 0;
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+
+ DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
+
+ /* clear the interrupt LASI status register */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
+ /* Clear MSG-OUT */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
+
+ /* Check the LASI */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+
+ DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
+
+ /* Check the link status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ link_up = ((val1 & 4) == 4);
+ DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
+
+ if (link_up &&
+ ((phy->req_line_speed != SPEED_10000))) {
+ if (bnx2x_8073_xaui_wa(bp, phy) != 0)
+ return 0;
+ }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
+
+ /* Check the link status on 1.1.2 */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
+ "an_link_status=0x%x\n", val2, val1, an1000_status);
+
+ link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
+ if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
+ /* The SNR will improve about 2dbby
+ changing the BW and FEE main tap.*/
+ /* The 1st write to change FFE main
+ tap is set before restart AN */
+ /* Change PLL Bandwidth in EDC
+ register */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
+ 0x26BC);
+
+ /* Change CDR Bandwidth in EDC register */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
+ 0x0333);
+ }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &link_status);
+
+ /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
+ if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_10000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
+ params->port);
+ } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_2500;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
+ params->port);
+ } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_1000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
+ params->port);
+ } else {
+ link_up = 0;
+ DP(NETIF_MSG_LINK, "port %x: External link is down\n",
+ params->port);
+ }
+
+ if (link_up) {
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ bnx2x_8073_resolve_fc(phy, params, vars);
+ }
+ return link_up;
+}
+
+static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 gpio_port;
+ gpio_port = params->port;
+ DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
+ gpio_port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ gpio_port);
+}
+
+/******************************************************************/
+/* BCM8705 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "init 8705\n");
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
+ /* BCM8705 doesn't have microcode, hence the 0 */
+ bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
+ return 0;
+}
+
+static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ u8 link_up = 0;
+ u16 val1, rx_sd;
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "read status 8705\n");
+ bnx2x_cl45_read(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, 0xc809, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, 0xc809, &val1);
+
+ DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
+ link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
+ if (link_up) {
+ vars->line_speed = SPEED_10000;
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+ }
+ return link_up;
}
-static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
- u32 ext_phy_type, u8 ext_phy_addr,
- u8 tx_en)
+/******************************************************************/
+/* SFP+ module Section */
+/******************************************************************/
+static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 port,
+ u8 tx_en)
{
u16 val;
DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
tx_en, port);
/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
&val);
@@ -2651,58 +3774,42 @@ static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
else
val |= (1<<15);
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
val);
}
-static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
+static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 addr, u8 byte_cnt, u8 *o_buf)
{
struct bnx2x *bp = params->bp;
u16 val = 0;
u16 i;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK, "Reading from eeprom is"
" is limited to 0xf\n");
return -EINVAL;
}
/* Set the read command byte count */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
(byte_cnt | 0xa000));
/* Set the read command address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
addr);
/* Activate read command */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
0x2c0f);
/* Wait up to 500us for command complete status */
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2721,18 +3828,14 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
/* Read the buffer */
for (i = 0; i < byte_cnt; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
}
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2743,14 +3846,12 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
return -EINVAL;
}
-static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
+static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 addr, u8 byte_cnt, u8 *o_buf)
{
struct bnx2x *bp = params->bp;
u16 val, i;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK, "Reading from eeprom is"
@@ -2759,40 +3860,30 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
}
/* Need to read from 1.8000 to clear it */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
&val);
/* Set the read command byte count */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
((byte_cnt < 2) ? 2 : byte_cnt));
/* Set the read command address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
addr);
/* Set the destination address */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
0x8004,
MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
/* Activate read command */
- bnx2x_cl45_write(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
0x8002);
@@ -2802,9 +3893,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
/* Wait up to 500us for command complete status */
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2823,18 +3912,14 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
/* Read the buffer */
for (i = 0; i < byte_cnt; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
}
for (i = 0; i < 100; i++) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
@@ -2846,21 +3931,21 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
return -EINVAL;
}
-u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
- return bnx2x_8726_read_sfp_module_eeprom(params, addr,
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+ return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
byte_cnt, o_buf);
- else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
- return bnx2x_8727_read_sfp_module_eeprom(params, addr,
+ else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+ return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
byte_cnt, o_buf);
return -EINVAL;
}
-static u8 bnx2x_get_edc_mode(struct link_params *params,
+static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
+ struct link_params *params,
u16 *edc_mode)
{
struct bnx2x *bp = params->bp;
@@ -2868,10 +3953,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
*edc_mode = EDC_MODE_LIMITING;
/* First check for copper cable */
- if (bnx2x_read_sfp_module_eeprom(params,
- SFP_EEPROM_CON_TYPE_ADDR,
- 1,
- &val) != 0) {
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
+ SFP_EEPROM_CON_TYPE_ADDR,
+ 1,
+ &val) != 0) {
DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
return -EINVAL;
}
@@ -2883,7 +3969,8 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
/* Check if its active cable( includes SFP+ module)
of passive cable*/
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_FC_TX_TECH_ADDR,
1,
&copper_module_type) !=
@@ -2923,10 +4010,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
if (check_limiting_mode) {
u8 options[SFP_EEPROM_OPTIONS_SIZE];
- if (bnx2x_read_sfp_module_eeprom(params,
- SFP_EEPROM_OPTIONS_ADDR,
- SFP_EEPROM_OPTIONS_SIZE,
- options) != 0) {
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
+ SFP_EEPROM_OPTIONS_ADDR,
+ SFP_EEPROM_OPTIONS_SIZE,
+ options) != 0) {
DP(NETIF_MSG_LINK, "Failed to read Option"
" field from module EEPROM\n");
return -EINVAL;
@@ -2939,17 +4027,17 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
return 0;
}
-
/* This function read the relevant field from the module ( SFP+ ),
and verify it is compliant with this board */
-static u8 bnx2x_verify_sfp_module(struct link_params *params)
+static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
- u32 val;
- u32 fw_resp;
+ u32 val, cmd;
+ u32 fw_resp, fw_cmd_param;
char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
-
+ phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].config));
@@ -2959,29 +4047,43 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params)
return 0;
}
- /* Ask the FW to validate the module */
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
+ if (params->feature_config_flags &
+ FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
+ /* Use specific phy request */
+ cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
+ } else if (params->feature_config_flags &
+ FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
+ /* Use first phy request only in case of non-dual media*/
+ if (DUAL_MEDIA(params)) {
+ DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
+ "verification\n");
+ return -EINVAL;
+ }
+ cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
+ } else {
+ /* No support in OPT MDL detection */
DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
- "verification\n");
+ "verification\n");
return -EINVAL;
}
-
- fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
+ fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
+ fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
DP(NETIF_MSG_LINK, "Approved module\n");
return 0;
}
/* format the warning message */
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_VENDOR_NAME_ADDR,
SFP_EEPROM_VENDOR_NAME_SIZE,
(u8 *)vendor_name))
vendor_name[0] = '\0';
else
vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
- if (bnx2x_read_sfp_module_eeprom(params,
+ if (bnx2x_read_sfp_module_eeprom(phy,
+ params,
SFP_EEPROM_PART_NO_ADDR,
SFP_EEPROM_PART_NO_SIZE,
(u8 *)vendor_pn))
@@ -2989,22 +4091,78 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params)
else
vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
- netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n",
+ netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
+ " Port %d from %s part number %s\n",
params->port, vendor_name, vendor_pn);
+ phy->flags |= FLAGS_SFP_NOT_APPROVED;
return -EINVAL;
}
-static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
- u16 edc_mode)
+static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
+ struct link_params *params)
+
{
+ u8 val;
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+ u16 timeout;
+ /* Initialization time after hot-plug may take up to 300ms for some
+ phys type ( e.g. JDSU ) */
+ for (timeout = 0; timeout < 60; timeout++) {
+ if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
+ == 0) {
+ DP(NETIF_MSG_LINK, "SFP+ module initialization "
+ "took %d ms\n", timeout * 5);
+ return 0;
+ }
+ msleep(5);
+ }
+ return -EINVAL;
+}
+
+static void bnx2x_8727_power_module(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u8 is_power_up) {
+ /* Make sure GPIOs are not using for LED mode */
+ u16 val;
+ /*
+ * In the GPIO register, bit 4 is use to detemine if the GPIOs are
+ * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
+ * output
+ * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
+ * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
+ * where the 1st bit is the over-current(only input), and 2nd bit is
+ * for power( only output )
+ */
+
+ /*
+ * In case of NOC feature is disabled and power is up, set GPIO control
+ * as input to enable listening of over-current indication
+ */
+ if (phy->flags & FLAGS_NOC)
+ return;
+ if (!(phy->flags &
+ FLAGS_NOC) && is_power_up)
+ val = (1<<4);
+ else
+ /*
+ * Set GPIO control to OUTPUT, and set the power bit
+ * to according to the is_power_up
+ */
+ val = ((!(is_power_up)) << 1);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ val);
+}
+
+static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
+ u16 edc_mode)
+{
u16 cur_limiting_mode;
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
&cur_limiting_mode);
@@ -3014,12 +4172,10 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
if (edc_mode == EDC_MODE_LIMITING) {
DP(NETIF_MSG_LINK,
"Setting LIMITING MODE\n");
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2,
- EDC_MODE_LIMITING);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ EDC_MODE_LIMITING);
} else { /* LRM mode ( default )*/
DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
@@ -3030,27 +4186,19 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
if (cur_limiting_mode != EDC_MODE_LIMITING)
return 0;
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_LRM_MODE,
0);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
0x128);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_MISC_CTRL0,
0x4008);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_LRM_MODE,
0xaaaa);
@@ -3058,46 +4206,33 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
return 0;
}
-static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
+static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
+ struct bnx2x_phy *phy,
u16 edc_mode)
{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
u16 phy_identifier;
u16 rom_ver2_val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
&phy_identifier);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
(phy_identifier & ~(1<<9)));
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
&rom_ver2_val);
/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER2,
(rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
(phy_identifier | (1<<9)));
@@ -3105,72 +4240,34 @@ static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
return 0;
}
-
-static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
+static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
+ struct link_params *params,
+ u32 action)
{
- u8 val;
struct bnx2x *bp = params->bp;
- u16 timeout;
- /* Initialization time after hot-plug may take up to 300ms for some
- phys type ( e.g. JDSU ) */
- for (timeout = 0; timeout < 60; timeout++) {
- if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
- == 0) {
- DP(NETIF_MSG_LINK, "SFP+ module initialization "
- "took %d ms\n", timeout * 5);
- return 0;
- }
- msleep(5);
- }
- return -EINVAL;
-}
-static void bnx2x_8727_power_module(struct bnx2x *bp,
- struct link_params *params,
- u8 ext_phy_addr, u8 is_power_up) {
- /* Make sure GPIOs are not using for LED mode */
- u16 val;
- u8 port = params->port;
- /*
- * In the GPIO register, bit 4 is use to detemine if the GPIOs are
- * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
- * output
- * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
- * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
- * where the 1st bit is the over-current(only input), and 2nd bit is
- * for power( only output )
- */
-
- /*
- * In case of NOC feature is disabled and power is up, set GPIO control
- * as input to enable listening of over-current indication
- */
-
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
- val = (1<<4);
- else
- /*
- * Set GPIO control to OUTPUT, and set the power bit
- * to according to the is_power_up
- */
- val = ((!(is_power_up)) << 1);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_GPIO_CTRL,
- val);
+ switch (action) {
+ case DISABLE_TX:
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+ break;
+ case ENABLE_TX:
+ if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
+ action);
+ return;
+ }
}
-static u8 bnx2x_sfp_module_detection(struct link_params *params)
+static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 edc_mode;
u8 rc = 0;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].config));
@@ -3178,10 +4275,10 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
params->port);
- if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
+ if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
return -EINVAL;
- } else if (bnx2x_verify_sfp_module(params) !=
+ } else if (bnx2x_verify_sfp_module(phy, params) !=
0) {
/* check SFP+ module compatibility */
DP(NETIF_MSG_LINK, "Module verification failed!!\n");
@@ -3190,13 +4287,12 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_HIGH,
params->port);
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
+ if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
/* Shutdown SFP+ module */
DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
- bnx2x_8727_power_module(bp, params,
- ext_phy_addr, 0);
+ bnx2x_8727_power_module(bp, phy, 0);
return rc;
}
} else {
@@ -3208,15 +4304,15 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
}
/* power up the SFP module */
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
- bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+ bnx2x_8727_power_module(bp, phy, 1);
/* Check and set limiting mode / LRM mode on 8726.
On 8727 it is done automatically */
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
- bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+ bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
else
- bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
+ bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
/*
* Enable transmit for this module if the module is approved, or
* if unapproved modules should also enable the Tx laser
@@ -3224,11 +4320,9 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
if (rc == 0 ||
(val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 1);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
else
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
return rc;
}
@@ -3236,6 +4330,7 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
void bnx2x_handle_module_detect_int(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
u32 gpio_val;
u8 port = params->port;
@@ -3245,1349 +4340,587 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
params->port);
/* Get current gpio val refelecting module plugged in / out*/
- gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
+ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
/* Call the handling function in case module is detected */
if (gpio_val == 0) {
bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
- port);
+ MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
+ port);
- if (bnx2x_wait_for_sfp_module_initialized(params) ==
- 0)
- bnx2x_sfp_module_detection(params);
+ if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
+ bnx2x_sfp_module_detection(phy, params);
else
DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
} else {
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].
config));
bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
- port);
+ MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
+ port);
/* Module was plugged out. */
/* Disable transmit for this module */
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- ext_phy_type, ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
}
}
-static void bnx2x_bcm807x_force_10G(struct link_params *params)
+/******************************************************************/
+/* common BCM8706/BCM8726 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u8 link_up = 0;
+ u16 val1, val2, rx_sd, pcs_status;
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Force KR or KX */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 0x2040);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2,
- 0x000b);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x0000);
-}
-
-static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_CHIP_REV, &val);
-
- if (val == 0) {
- /* Mustn't set low power mode in 8073 A0 */
- return;
+ DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
+ /* Clear RX Alarm*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+ /* clear LASI indication*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
+
+ DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
+ " link_status 0x%x\n", rx_sd, pcs_status, val2);
+ /* link is up if both bit 0 of pmd_rx_sd and
+ * bit 0 of pcs_status are set, or if the autoneg bit
+ * 1 is set
+ */
+ link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+ if (link_up) {
+ if (val2 & (1<<1))
+ vars->line_speed = SPEED_1000;
+ else
+ vars->line_speed = SPEED_10000;
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
}
-
- /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val &= ~(1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
-
- /* PLL controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805E, 0x1077);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805D, 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805C, 0x030B);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805B, 0x1240);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805A, 0x2490);
-
- /* Tx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A7, 0x0C74);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A6, 0x9041);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A5, 0x4640);
-
- /* Rx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FE, 0x01C4);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FD, 0x9249);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FC, 0x2015);
-
- /* Enable PLL sequencer (use read-modify-write to set bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val |= (1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
+ return link_up;
}
-static void bnx2x_8073_set_pause_cl37(struct link_params *params,
- struct link_vars *vars)
+/******************************************************************/
+/* BCM8706 PHY SECTION */
+/******************************************************************/
+static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 cnt, val;
struct bnx2x *bp = params->bp;
- u16 cl37_val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &cl37_val);
-
- cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
+ bnx2x_wait_reset_complete(bp, phy);
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
+ /* Wait until fw is loaded */
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
+ if (val)
+ break;
+ msleep(10);
}
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ u8 i;
+ u16 reg;
+ for (i = 0; i < 4; i++) {
+ reg = MDIO_XS_8706_REG_BANK_RX0 +
+ i*(MDIO_XS_8706_REG_BANK_RX1 -
+ MDIO_XS_8706_REG_BANK_RX0);
+ bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
+ /* Clear first 3 bits of the control */
+ val &= ~0x7;
+ /* Set control bits according to configuration */
+ val |= (phy->rx_preemphasis[i] & 0x7);
+ DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
+ " reg 0x%x <-- val 0x%x\n", reg, val);
+ bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
+ }
}
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ /* Force speed */
+ if (phy->req_line_speed == SPEED_10000) {
+ DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
+ } else {
+ /* Force 1Gbps using autoneg with 1G advertisment */
+
+ /* Allow CL37 through CL73 */
+ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
+
+ /* Enable Full-Duplex advertisment on CL37 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
+ /* Enable CL37 AN */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
+ /* 1G support */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
+
+ /* Enable clause 73 AN */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x0400);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+ 0x0004);
}
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize cl37 0x%x\n", cl37_val);
+ bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
+ return 0;
+}
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, cl37_val);
- msleep(500);
+static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ return bnx2x_8706_8726_read_status(phy, params, vars);
}
-static void bnx2x_ext_phy_set_pause(struct link_params *params,
- struct link_vars *vars)
+/******************************************************************/
+/* BCM8726 PHY SECTION */
+/******************************************************************/
+static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
- u16 val;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* read modify write pause advertizing */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &val);
-
- val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
-
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
-
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
- }
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- val |=
- MDIO_AN_REG_ADV_PAUSE_PAUSE;
- }
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize 0x%x\n", val);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, val);
+ DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
}
-static void bnx2x_set_preemphasis(struct link_params *params)
+
+static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
+ struct link_params *params)
{
- u16 bank, i = 0;
struct bnx2x *bp = params->bp;
+ /* Need to wait 100ms after reset */
+ msleep(100);
- for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
- bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- bank,
- MDIO_RX0_RX_EQ_BOOST,
- params->xgxs_config_rx[i]);
- }
-
- for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
- bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- bank,
- MDIO_TX0_TX_DRIVER,
- params->xgxs_config_tx[i]);
- }
-}
+ /* Micro controller re-boot */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
+ /* Set soft reset */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
-static void bnx2x_8481_set_led4(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
-{
- struct bnx2x *bp = params->bp;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
- /* PHYC_CTL_LED_CTL */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* Unmask LED4 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
+ /* wait for 150ms for microcode load */
+ msleep(150);
+
+ /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
- /* 'Interrupt Mask' */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0xFFFB, 0xFFFD);
-}
-static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
-{
- struct bnx2x *bp = params->bp;
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
- /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_SHADOW,
- (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
+ msleep(200);
+ bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
}
-static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
- u32 ext_phy_type, u8 ext_phy_addr)
+static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 val1;
-
- /* LED1 (10G Link) */
- /* Enable continuse based on source 7(10G-link) */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL,
- &val1);
- /* Set bit 2 to 0, and bits [1:0] to 10 */
- val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/
- val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LINK_SIGNAL,
- val1);
-
- /* Unmask LED1 for 10G link */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED1_MASK,
- &val1);
- /* Set bit 2 to 0, and bits [1:0] to 10 */
- val1 |= (1<<7);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED1_MASK,
- val1);
-
- /* LED2 (1G/100/10G Link) */
- /* Mask LED2 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED2_MASK,
- 0);
-
- /* Unmask LED3 for 10G link */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED3_MASK,
- 0x6);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_LED3_BLINK,
- 0);
+ u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
+ if (link_up) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is disabled\n");
+ link_up = 0;
+ vars->line_speed = 0;
+ }
+ }
+ return link_up;
}
-static void bnx2x_init_internal_phy(struct link_params *params,
- struct link_vars *vars,
- u8 enable_cl73)
+static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
+ u32 val;
+ u32 swap_val, swap_override, aeu_gpio_mask, offset;
+ DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
- if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
- if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
- bnx2x_set_preemphasis(params);
-
- /* forced speed requested? */
- if (vars->line_speed != SPEED_AUTO_NEG ||
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- params->loopback_mode == LOOPBACK_EXT)) {
- DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
-
- /* disable autoneg */
- bnx2x_set_autoneg(params, vars, 0);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_8726_external_rom_boot(phy, params);
+
+ /* Need to call module detected on initialization since
+ the module detection triggered by actual module
+ insertion might occur before driver is loaded, and when
+ driver is loaded, it reset all registers, including the
+ transmitter */
+ bnx2x_sfp_module_detection(phy, params);
+
+ if (phy->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+ } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
+ DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
+ /* Set Flow control */
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
+ /* Enable RX-ALARM control to receive
+ interrupt for 1G speed change */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+
+ } else { /* Default 10G. Set only LASI control */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
+ }
- /* program speed and duplex */
- bnx2x_program_serdes(params, vars);
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+ "TX_CTRL2 0x%x\n",
+ phy->tx_preemphasis[0],
+ phy->tx_preemphasis[1]);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL1,
+ phy->tx_preemphasis[0]);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL2,
+ phy->tx_preemphasis[1]);
+ }
- } else { /* AN_mode */
- DP(NETIF_MSG_LINK, "not SGMII, AN\n");
+ /* Set GPIO3 to trigger SFP+ module insertion/removal */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
- /* AN enabled */
- bnx2x_set_brcm_cl37_advertisment(params);
+ /* The GPIO should be swapped if the swap register is set and active */
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- /* program duplex & pause advertisement (for aneg) */
- bnx2x_set_ieee_aneg_advertisment(params,
- vars->ieee_fc);
+ /* Select function upon port-swap configuration */
+ if (params->port == 0) {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
+ } else {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
+ }
+ val = REG_RD(bp, offset);
+ /* add GPIO3 to group */
+ val |= aeu_gpio_mask;
+ REG_WR(bp, offset, val);
+ return 0;
- /* enable autoneg */
- bnx2x_set_autoneg(params, vars, enable_cl73);
+}
- /* enable and restart AN */
- bnx2x_restart_autoneg(params, enable_cl73);
- }
+static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL, 0x0001);
+}
- } else { /* SGMII mode */
- DP(NETIF_MSG_LINK, "SGMII\n");
+/******************************************************************/
+/* BCM8727 PHY SECTION */
+/******************************************************************/
- bnx2x_initialize_sgmii_process(params, vars);
+static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ struct bnx2x *bp = params->bp;
+ u16 led_mode_bitmask = 0;
+ u16 gpio_pins_bitmask = 0;
+ u16 val;
+ /* Only NOC flavor requires to set the LED specifically */
+ if (!(phy->flags & FLAGS_NOC))
+ return;
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ led_mode_bitmask = 0;
+ gpio_pins_bitmask = 0x03;
+ break;
+ case LED_MODE_ON:
+ led_mode_bitmask = 0;
+ gpio_pins_bitmask = 0x02;
+ break;
+ case LED_MODE_OPER:
+ led_mode_bitmask = 0x60;
+ gpio_pins_bitmask = 0x11;
+ break;
}
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ &val);
+ val &= 0xff8f;
+ val |= led_mode_bitmask;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ &val);
+ val &= 0xffe0;
+ val |= gpio_pins_bitmask;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_GPIO_CTRL,
+ val);
+}
+static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params) {
+ u32 swap_val, swap_override;
+ u8 port;
+ /**
+ * The PHY reset is controlled by GPIO 1. Fake the port number
+ * to cancel the swap done in set_gpio()
+ */
+ struct bnx2x *bp = params->bp;
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+ port = (swap_val && swap_override) ^ 1;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
}
-static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
+static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 tmp1, val, mod_abs;
+ u16 rx_alarm_ctrl_val;
+ u16 lasi_ctrl_val;
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 cnt;
- u16 ctrl = 0;
- u16 val = 0;
- u8 rc = 0;
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* Make sure that the soft reset is off (expect for the 8072:
- * due to the lock, it will be done inside the specific
- * handling)
+ /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
+
+ bnx2x_wait_reset_complete(bp, phy);
+ rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
+ lasi_ctrl_val = 0x0004;
+
+ DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
+ /* enable LASI */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ rx_alarm_ctrl_val);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
+
+ /* Initially configure MOD_ABS to interrupt when
+ module is presence( bit 8) */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
+ /* Set EDC off by setting OPTXLOS signal input to low
+ (bit 9).
+ When the EDC is off it locks onto a reference clock and
+ avoids becoming 'lost'.*/
+ mod_abs &= ~(1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs &= ~(1<<9);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+
+
+ /* Make MOD_ABS give interrupt on change */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+ &val);
+ val |= (1<<12);
+ if (phy->flags & FLAGS_NOC)
+ val |= (3<<5);
+
+ /**
+ * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
+ * status which reflect SFP+ module over-current
+ */
+ if (!(phy->flags & FLAGS_NOC))
+ val &= 0xff8f; /* Reset bits 4-6 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
+
+ bnx2x_8727_power_module(bp, phy, 1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
+
+ /* Set option 1G speed */
+ if (phy->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
+ DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
+ /**
+ * Power down the XAUI until link is up in case of dual-media
+ * and 1G
*/
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
- /* Wait for soft reset to get cleared upto 1 sec */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, &ctrl);
- if (!(ctrl & (1<<15)))
- break;
- msleep(1);
- }
- DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
- ctrl, cnt);
- }
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL,
- 0x8288);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- 0x7fbf);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CMU_PLL_BYPASS,
- 0x0100);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_CNTL, 0x1);
-
- /* BCM8705 doesn't have microcode, hence the 0 */
- bnx2x_save_spirom_version(bp, params->port,
- params->shmem_base, 0);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- /* Wait until fw is loaded */
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- if (val)
- break;
- msleep(10);
- }
- DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
- "after %d ms\n", cnt);
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- u8 i;
- u16 reg;
- for (i = 0; i < 4; i++) {
- reg = MDIO_XS_8706_REG_BANK_RX0 +
- i*(MDIO_XS_8706_REG_BANK_RX1 -
- MDIO_XS_8706_REG_BANK_RX0);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- reg, &val);
- /* Clear first 3 bits of the control */
- val &= ~0x7;
- /* Set control bits according to
- configuation */
- val |= (params->xgxs_config_rx[i] &
- 0x7);
- DP(NETIF_MSG_LINK, "Setting RX"
- "Equalizer to BCM8706 reg 0x%x"
- " <-- val 0x%x\n", reg, val);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- reg, val);
- }
- }
- /* Force speed */
- if (params->req_line_speed == SPEED_10000) {
- DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_DIGITAL_CTRL,
- 0x400);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 1);
- } else {
- /* Force 1Gbps using autoneg with 1G
- advertisment */
-
- /* Allow CL37 through CL73 */
- DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_CL73,
- 0x040c);
-
- /* Enable Full-Duplex advertisment on CL37 */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP,
- 0x0020);
- /* Enable CL37 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN,
- 0x1000);
- /* 1G support */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, (1<<5));
-
- /* Enable clause 73 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x1200);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x0400);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x0004);
-
- }
- bnx2x_save_bcm_spirom_ver(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- params->shmem_base);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
- bnx2x_bcm8726_external_rom_boot(params);
-
- /* Need to call module detected on initialization since
- the module detection triggered by actual module
- insertion might occur before driver is loaded, and when
- driver is loaded, it reset all registers, including the
- transmitter */
- bnx2x_sfp_module_detection(params);
-
- /* Set Flow control */
- bnx2x_ext_phy_set_pause(params, vars);
- if (params->req_line_speed == SPEED_1000) {
- DP(NETIF_MSG_LINK, "Setting 1G force\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x40);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0xD);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x5);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x400);
- } else if ((params->req_line_speed ==
- SPEED_AUTO_NEG) &&
- ((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
- DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, 0x20);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_CL73, 0x040c);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, 0x0020);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1000);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x1200);
-
- /* Enable RX-ALARM control to receive
- interrupt for 1G speed change */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x4);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x400);
-
- } else { /* Default 10G. Set only LASI control */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 1);
- }
-
- /* Set TX PreEmphasis if needed */
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
- "TX_CTRL2 0x%x\n",
- params->xgxs_config_tx[0],
- params->xgxs_config_tx[1]);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8726_TX_CTRL1,
- params->xgxs_config_tx[0]);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8726_TX_CTRL2,
- params->xgxs_config_tx[1]);
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 tmp1;
- u16 rx_alarm_ctrl_val;
- u16 lasi_ctrl_val;
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- rx_alarm_ctrl_val = 0x400;
- lasi_ctrl_val = 0x0004;
- } else {
- rx_alarm_ctrl_val = (1<<2);
- lasi_ctrl_val = 0x0004;
- }
-
- /* enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- rx_alarm_ctrl_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL,
- lasi_ctrl_val);
-
- bnx2x_8073_set_pause_cl37(params, vars);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
- bnx2x_bcm8072_external_rom_boot(params);
- else
- /* In case of 8073 with long xaui lines,
- don't set the 8073 xaui low power*/
- bnx2x_bcm8073_set_xaui_low_power_mode(params);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &tmp1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &tmp1);
-
- DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
- "0x%x\n", tmp1);
-
- /* If this is forced speed, set to KR or KX
- * (all other are not supported)
- */
- if (params->loopback_mode == LOOPBACK_EXT) {
- bnx2x_bcm807x_force_10G(params);
- DP(NETIF_MSG_LINK,
- "Forced speed 10G on 807X\n");
- break;
- } else {
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0002);
- }
- if (params->req_line_speed != SPEED_AUTO_NEG) {
- if (params->req_line_speed == SPEED_10000) {
- val = (1<<7);
- } else if (params->req_line_speed ==
- SPEED_2500) {
- val = (1<<5);
- /* Note that 2.5G works only
- when used with 1G advertisment */
- } else
- val = (1<<5);
- } else {
-
- val = 0;
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
- val |= (1<<7);
-
- /* Note that 2.5G works only when
- used with 1G advertisment */
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- val |= (1<<5);
- DP(NETIF_MSG_LINK,
- "807x autoneg val = 0x%x\n", val);
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, val);
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8073_2_5G, &tmp1);
-
- if (((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
- (params->req_line_speed ==
- SPEED_AUTO_NEG)) ||
- (params->req_line_speed ==
- SPEED_2500)) {
- u16 phy_ver;
- /* Allow 2.5G for A1 and above */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
+ if (DUAL_MEDIA(params)) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, &val);
+ val |= (3<<10);
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
- DP(NETIF_MSG_LINK, "Add 2.5G\n");
- if (phy_ver > 0)
- tmp1 |= 1;
- else
- tmp1 &= 0xfffe;
- } else {
- DP(NETIF_MSG_LINK, "Disable 2.5G\n");
- tmp1 &= 0xfffe;
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8073_2_5G, tmp1);
- }
-
- /* Add support for CL37 (passive mode) II */
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD,
- &tmp1);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, (tmp1 |
- ((params->req_duplex == DUPLEX_FULL) ?
- 0x20 : 0x40)));
-
- /* Add support for CL37 (passive mode) III */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1000);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- /* The SNR will improve about 2db by changing
- BW and FEE main tap. Rest commands are executed
- after link is up*/
- /*Change FFE main cursor to 5 in EDC register*/
- if (bnx2x_8073_is_snr_needed(params))
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_EDC_FFE_MAIN,
- 0xFB0C);
-
- /* Enable FEC (Forware Error Correction)
- Request in the AN */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, &tmp1);
-
- tmp1 |= (1<<15);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, tmp1);
-
- }
-
- bnx2x_ext_phy_set_pause(params, vars);
-
- /* Restart autoneg */
- msleep(500);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x1200);
- DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
- "Advertise 1G=%x, 10G=%x\n",
- ((val & (1<<5)) > 0),
- ((val & (1<<7)) > 0));
- break;
- }
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
- u16 tmp1;
- u16 rx_alarm_ctrl_val;
- u16 lasi_ctrl_val;
-
- /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
-
- u16 mod_abs;
- rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
- lasi_ctrl_val = 0x0004;
-
- DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
- /* enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- rx_alarm_ctrl_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL,
- lasi_ctrl_val);
-
- /* Initially configure MOD_ABS to interrupt when
- module is presence( bit 8) */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
- /* Set EDC off by setting OPTXLOS signal input to low
- (bit 9).
- When the EDC is off it locks onto a reference clock and
- avoids becoming 'lost'.*/
- mod_abs &= ~((1<<8) | (1<<9));
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
-
- /* Make MOD_ABS give interrupt on change */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- &val);
- val |= (1<<12);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- val);
-
- /* Set 8727 GPIOs to input to allow reading from the
- 8727 GPIO0 status which reflect SFP+ module
- over-current */
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- &val);
- val &= 0xff8f; /* Reset bits 4-6 */
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_PCS_OPT_CTRL,
- val);
-
- bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
- bnx2x_bcm8073_set_xaui_low_power_mode(params);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &tmp1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &tmp1);
-
- /* Set option 1G speed */
- if (params->req_line_speed == SPEED_1000) {
-
- DP(NETIF_MSG_LINK, "Setting 1G force\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x40);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0xD);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, &tmp1);
- DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
-
- } else if ((params->req_line_speed ==
- SPEED_AUTO_NEG) &&
- ((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
-
- DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_PMA_REG_8727_MISC_CTRL, 0);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1300);
- } else {
- /* Since the 8727 has only single reset pin,
- need to set the 10G registers although it is
- default */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x0020);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_AN_DEVAD,
- 0x7, 0x0100);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x2040);
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2, 0x0008);
- }
-
- /* Set 2-wire transfer rate of SFP+ module EEPROM
- * to 100Khz since some DACs(direct attached cables) do
- * not work at 400Khz.
- */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
- 0xa001);
-
- /* Set TX PreEmphasis if needed */
- if ((params->feature_config_flags &
- FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
- DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
- "TX_CTRL2 0x%x\n",
- params->xgxs_config_tx[0],
- params->xgxs_config_tx[1]);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TX_CTRL1,
- params->xgxs_config_tx[0]);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_TX_CTRL2,
- params->xgxs_config_tx[1]);
- }
-
- break;
- }
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- {
- u16 fw_ver1, fw_ver2;
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LASI indication\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x1);
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LED to blink on traffic\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
-
- bnx2x_ext_phy_set_pause(params, vars);
- /* Restart autoneg */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, &val);
- val |= 0x200;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, val);
-
- /* Save spirom version */
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1, &fw_ver1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr, MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER2, &fw_ver2);
-
- bnx2x_save_spirom_version(params->bp, params->port,
- params->shmem_base,
- (u32)(fw_ver1<<16 | fw_ver2));
- break;
+ MDIO_PMA_REG_8727_PCS_GP, val);
}
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- /* This phy uses the NIG latch mechanism since link
- indication arrives through its LED4 and not via
- its LASI signal, so we get steady signal
- instead of clear on read */
- bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
- 1 << NIG_LATCH_BC_ENABLE_MI_INT);
-
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x0000);
-
- bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
- if (params->req_line_speed == SPEED_AUTO_NEG) {
-
- u16 autoneg_val, an_1000_val, an_10_100_val;
- /* set 1000 speed advertisement */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_1000T_CTRL,
- &an_1000_val);
-
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
- an_1000_val |= (1<<8);
- if (params->req_duplex == DUPLEX_FULL)
- an_1000_val |= (1<<9);
- DP(NETIF_MSG_LINK, "Advertising 1G\n");
- } else
- an_1000_val &= ~((1<<8) | (1<<9));
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_1000T_CTRL,
- an_1000_val);
-
- /* set 100 speed advertisement */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_AN_ADV,
- &an_10_100_val);
-
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
- an_10_100_val |= (1<<7);
- if (params->req_duplex == DUPLEX_FULL)
- an_10_100_val |= (1<<8);
- DP(NETIF_MSG_LINK,
- "Advertising 100M\n");
- } else
- an_10_100_val &= ~((1<<7) | (1<<8));
-
- /* set 10 speed advertisement */
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
- an_10_100_val |= (1<<5);
- if (params->req_duplex == DUPLEX_FULL)
- an_10_100_val |= (1<<6);
- DP(NETIF_MSG_LINK, "Advertising 10M\n");
- }
- else
- an_10_100_val &= ~((1<<5) | (1<<6));
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_AN_ADV,
- an_10_100_val);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- &autoneg_val);
-
- /* Disable forced speed */
- autoneg_val &= ~(1<<6|1<<13);
-
- /* Enable autoneg and restart autoneg
- for legacy speeds */
- autoneg_val |= (1<<9|1<<12);
-
- if (params->req_duplex == DUPLEX_FULL)
- autoneg_val |= (1<<8);
- else
- autoneg_val &= ~(1<<8);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- autoneg_val);
-
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
- DP(NETIF_MSG_LINK, "Advertising 10G\n");
- /* Restart autoneg for 10G*/
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x3200);
- }
- } else {
- /* Force speed */
- u16 autoneg_ctrl, pma_ctrl;
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- &autoneg_ctrl);
-
- /* Disable autoneg */
- autoneg_ctrl &= ~(1<<12);
-
- /* Set 1000 force */
- switch (params->req_line_speed) {
- case SPEED_10000:
- DP(NETIF_MSG_LINK,
- "Unable to set 10G force !\n");
- break;
- case SPEED_1000:
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- &pma_ctrl);
- autoneg_ctrl &= ~(1<<13);
- autoneg_ctrl |= (1<<6);
- pma_ctrl &= ~(1<<13);
- pma_ctrl |= (1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 1000M force\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- pma_ctrl);
- break;
- case SPEED_100:
- autoneg_ctrl |= (1<<13);
- autoneg_ctrl &= ~(1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 100M force\n");
- break;
- case SPEED_10:
- autoneg_ctrl &= ~(1<<13);
- autoneg_ctrl &= ~(1<<6);
- DP(NETIF_MSG_LINK,
- "Setting 10M force\n");
- break;
- }
-
- /* Duplex mode */
- if (params->req_duplex == DUPLEX_FULL) {
- autoneg_ctrl |= (1<<8);
- DP(NETIF_MSG_LINK,
- "Setting full duplex\n");
- } else
- autoneg_ctrl &= ~(1<<8);
-
- /* Update autoneg ctrl and pma ctrl */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_LEGACY_MII_CTRL,
- autoneg_ctrl);
- }
-
- /* Save spirom version */
- bnx2x_save_8481_spirom_version(bp, params->port,
- ext_phy_addr,
- params->shmem_base);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK,
- "XGXS PHY Failure detected 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- }
-
- } else { /* SerDes */
-
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- break;
+ } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
+ ((phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
+
+ DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
+ } else {
+ /**
+ * Since the 8727 has only single reset pin, need to set the 10G
+ * registers although it is default
+ */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
+ 0x0020);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
+ 0x0008);
+ }
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
- }
+ /* Set 2-wire transfer rate of SFP+ module EEPROM
+ * to 100Khz since some DACs(direct attached cables) do
+ * not work at 400Khz.
+ */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
+ 0xa001);
+
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
+ phy->tx_preemphasis[0],
+ phy->tx_preemphasis[1]);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
+ phy->tx_preemphasis[0]);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
+ phy->tx_preemphasis[1]);
}
- return rc;
+
+ return 0;
}
-static void bnx2x_8727_handle_mod_abs(struct link_params *params)
+static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
+ struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 mod_abs, rx_alarm_status;
- u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].
config));
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
if (mod_abs & (1<<8)) {
@@ -4602,18 +4935,16 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
(bit 9).
When the EDC is off it locks onto a reference clock and
avoids becoming 'lost'.*/
- mod_abs &= ~((1<<8)|(1<<9));
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ mod_abs &= ~(1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs &= ~(1<<9);
+ bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
/* Clear RX alarm since it stays up as long as
the mod_abs wasn't changed */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
@@ -4630,33 +4961,28 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
2. Restore the default polarity of the OPRXLOS signal and
this signal will then correctly indicate the presence or
absence of the Rx signal. (bit 9) */
- mod_abs |= ((1<<8)|(1<<9));
- bnx2x_cl45_write(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+ mod_abs |= (1<<8);
+ if (!(phy->flags & FLAGS_NOC))
+ mod_abs |= (1<<9);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
/* Clear RX alarm since it stays up as long as
the mod_abs wasn't changed. This is need to be done
before calling the module detection, otherwise it will clear
the link update alarm */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr, 0);
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
- if (bnx2x_wait_for_sfp_module_initialized(params)
- == 0)
- bnx2x_sfp_module_detection(params);
+ if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
+ bnx2x_sfp_module_detection(phy, params);
else
DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
}
@@ -4667,1298 +4993,1711 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params)
module plugged in/out */
}
+static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
-static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
- struct link_vars *vars,
- u8 is_mi_int)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 val1 = 0, val2;
- u16 rx_sd, pcs_status;
- u8 ext_phy_link_up = 0;
- u8 port = params->port;
+ u8 link_up = 0;
+ u16 link_status = 0;
+ u16 rx_alarm_status, lasi_ctrl, val1;
+
+ /* If PHY is not initialized, do not check link status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+ &lasi_ctrl);
+ if (!lasi_ctrl)
+ return 0;
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- ext_phy_link_up = 1;
- break;
+ /* Check the LASI */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+ &rx_alarm_status);
+ vars->line_speed = 0;
+ DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- 1,
- 0xc809, &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- 1,
- 0xc809, &val1);
-
- DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
- ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) &&
- ((val1 & (1<<8)) == 0));
- if (ext_phy_link_up)
- vars->line_speed = SPEED_10000;
- break;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
- /* Clear RX Alarm*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
- &val2);
- /* clear LASI indication*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
- &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
- &val2);
- DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
- "0x%x\n", val1, val2);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
- &rx_sd);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
- &pcs_status);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
- &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
- &val2);
-
- DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
- " pcs_status 0x%x 1Gbps link_status 0x%x\n",
- rx_sd, pcs_status, val2);
- /* link is up if both bit 0 of pmd_rx_sd and
- * bit 0 of pcs_status are set, or if the autoneg bit
- 1 is set
- */
- ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
- (val2 & (1<<1)));
- if (ext_phy_link_up) {
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
- /* If transmitter is disabled,
- ignore false link up indication */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- if (val1 & (1<<15)) {
- DP(NETIF_MSG_LINK, "Tx is "
- "disabled\n");
- ext_phy_link_up = 0;
- break;
- }
- }
- if (val2 & (1<<1))
- vars->line_speed = SPEED_1000;
- else
- vars->line_speed = SPEED_10000;
- }
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
- u16 link_status = 0;
- u16 rx_alarm_status;
- /* Check the LASI */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
-
- DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
- rx_alarm_status);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
- DP(NETIF_MSG_LINK,
- "8727 LASI status 0x%x\n",
- val1);
+ /* Clear MSG-OUT */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
- /* Clear MSG-OUT */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &val1);
+ /**
+ * If a module is present and there is need to check
+ * for over current
+ */
+ if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
+ /* Check over-current using 8727 GPIO0 input*/
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
+ &val1);
+
+ if ((val1 & (1<<8)) == 0) {
+ DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
+ " on port %d\n", params->port);
+ netdev_err(bp->dev, "Error: Power fault on Port %d has"
+ " been detected and the power to "
+ "that SFP+ module has been removed"
+ " to prevent failure of the card."
+ " Please remove the SFP+ module and"
+ " restart the system to clear this"
+ " error.\n",
+ params->port);
/*
- * If a module is present and there is need to check
- * for over current
+ * Disable all RX_ALARMs except for
+ * mod_abs
*/
- if (!(params->feature_config_flags &
- FEATURE_CONFIG_BCM8727_NOC) &&
- !(rx_alarm_status & (1<<5))) {
- /* Check over-current using 8727 GPIO0 input*/
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8727_GPIO_CTRL,
- &val1);
-
- if ((val1 & (1<<8)) == 0) {
- DP(NETIF_MSG_LINK, "8727 Power fault"
- " has been detected on "
- "port %d\n",
- params->port);
- netdev_err(bp->dev, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n",
- params->port);
- /*
- * Disable all RX_ALARMs except for
- * mod_abs
- */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- (1<<5));
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- /* Wait for module_absent_event */
- val1 |= (1<<8);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- val1);
- /* Clear RX alarm */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM,
- &rx_alarm_status);
- break;
- }
- } /* Over current check */
-
- /* When module absent bit is set, check module */
- if (rx_alarm_status & (1<<5)) {
- bnx2x_8727_handle_mod_abs(params);
- /* Enable all mod_abs and link detection bits */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- ((1<<5) | (1<<2)));
- }
-
- /* If transmitter is disabled,
- ignore false link up indication */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- &val1);
- if (val1 & (1<<15)) {
- DP(NETIF_MSG_LINK, "Tx is disabled\n");
- ext_phy_link_up = 0;
- break;
- }
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
- &link_status);
-
- /* Bits 0..2 --> speed detected,
- bits 13..15--> link is down */
- if ((link_status & (1<<2)) &&
- (!(link_status & (1<<15)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- } else if ((link_status & (1<<0)) &&
- (!(link_status & (1<<13)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else {
- ext_phy_link_up = 0;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " is down\n", params->port);
- }
- break;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
+ /* Wait for module_absent_event */
+ val1 |= (1<<8);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER, val1);
+ /* Clear RX alarm */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+ return 0;
}
+ } /* Over current check */
+
+ /* When module absent bit is set, check module */
+ if (rx_alarm_status & (1<<5)) {
+ bnx2x_8727_handle_mod_abs(phy, params);
+ /* Enable all mod_abs and link detection bits */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+ ((1<<5) | (1<<2)));
+ }
+ DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
+ bnx2x_8727_specific_func(phy, params, ENABLE_TX);
+ /* If transmitter is disabled, ignore false link up indication */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is disabled\n");
+ return 0;
+ }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 link_status = 0;
- u16 an1000_status = 0;
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val1);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val2);
- DP(NETIF_MSG_LINK,
- "870x LASI status 0x%x->0x%x\n",
- val1, val2);
- } else {
- /* In 8073, port1 is directed through emac0 and
- * port0 is directed through emac1
- */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
-
- DP(NETIF_MSG_LINK,
- "8703 LASI status 0x%x\n",
- val1);
- }
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
- /* clear the interrupt LASI status register */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
- val2, val1);
- /* Clear MSG-OUT */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_M8051_MSGOUT_REG,
- &val1);
-
- /* Check the LASI */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
-
- DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
-
- /* Check the link status */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
- if (ext_phy_link_up &&
- ((params->req_line_speed !=
- SPEED_10000))) {
- if (bnx2x_bcm8073_xaui_wa(params)
- != 0) {
- ext_phy_link_up = 0;
- break;
- }
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
-
- /* Check the link status on 1.1.2 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
- "an_link_status=0x%x\n",
- val2, val1, an1000_status);
-
- ext_phy_link_up = (((val1 & 4) == 4) ||
- (an1000_status & (1<<1)));
- if (ext_phy_link_up &&
- bnx2x_8073_is_snr_needed(params)) {
- /* The SNR will improve about 2dbby
- changing the BW and FEE main tap.*/
-
- /* The 1st write to change FFE main
- tap is set before restart AN */
- /* Change PLL Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PLL_BANDWIDTH,
- 0x26BC);
-
- /* Change CDR Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CDR_BANDWIDTH,
- 0x0333);
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
- &link_status);
-
- /* Bits 0..2 --> speed detected,
- bits 13..15--> link is down */
- if ((link_status & (1<<2)) &&
- (!(link_status & (1<<15)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- } else if ((link_status & (1<<1)) &&
- (!(link_status & (1<<14)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_2500;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 2.5G\n", params->port);
- } else if ((link_status & (1<<0)) &&
- (!(link_status & (1<<13)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else {
- ext_phy_link_up = 0;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " is down\n", params->port);
- }
- } else {
- /* See if 1G link is up for the 8072 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS,
- &an1000_status);
- if (an1000_status & (1<<1)) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else if (ext_phy_link_up) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- }
- }
+ /* Bits 0..2 --> speed detected,
+ bits 13..15--> link is down */
+ if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_10000;
+ } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
+ link_up = 1;
+ vars->line_speed = SPEED_1000;
+ DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
+ params->port);
+ } else {
+ link_up = 0;
+ DP(NETIF_MSG_LINK, "port %x: External link is down\n",
+ params->port);
+ }
+ if (link_up)
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+
+ if ((DUAL_MEDIA(params)) &&
+ (phy->req_line_speed == SPEED_1000)) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, &val1);
+ /**
+ * In case of dual-media board and 1G, power up the XAUI side,
+ * otherwise power it down. For 10G it is done automatically
+ */
+ if (link_up)
+ val1 &= ~(3<<10);
+ else
+ val1 |= (3<<10);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8727_PCS_GP, val1);
+ }
+ return link_up;
+}
+static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ /* Disable Transmitter */
+ bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+ /* Clear LASI */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T LASI status 0x%x->0x%x\n",
- val2, val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T PMA status 0x%x->0x%x\n",
- val2, val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- /* if link is up
- * print the AN outcome of the SFX7101 PHY
- */
- if (ext_phy_link_up) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_MASTER_STATUS,
- &val2);
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "SFX7101 AN status 0x%x->Master=%x\n",
- val2,
- (val2 & (1<<14)));
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- /* Check 10G-BaseT link status */
- /* Check PMD signal ok */
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0xFFFA,
- &val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_8481_PMD_SIGNAL,
- &val2);
- DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
-
- /* Check link 10G */
- if (val2 & (1<<11)) {
- vars->line_speed = SPEED_10000;
- ext_phy_link_up = 1;
- bnx2x_8481_set_10G_led_mode(params,
- ext_phy_type,
- ext_phy_addr);
- } else { /* Check Legacy speed link */
- u16 legacy_status, legacy_speed;
-
- /* Enable expansion register 0x42
- (Operation mode status) */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
- 0xf42);
-
- /* Get legacy speed operation status */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
- &legacy_status);
-
- DP(NETIF_MSG_LINK, "Legacy speed status"
- " = 0x%x\n", legacy_status);
- ext_phy_link_up = ((legacy_status & (1<<11))
- == (1<<11));
- if (ext_phy_link_up) {
- legacy_speed = (legacy_status & (3<<9));
- if (legacy_speed == (0<<9))
- vars->line_speed = SPEED_10;
- else if (legacy_speed == (1<<9))
- vars->line_speed =
- SPEED_100;
- else if (legacy_speed == (2<<9))
- vars->line_speed =
- SPEED_1000;
- else /* Should not happen */
- vars->line_speed = 0;
-
- if (legacy_status & (1<<8))
- vars->duplex = DUPLEX_FULL;
- else
- vars->duplex = DUPLEX_HALF;
-
- DP(NETIF_MSG_LINK, "Link is up "
- "in %dMbps, is_duplex_full"
- "= %d\n",
- vars->line_speed,
- (vars->duplex == DUPLEX_FULL));
- bnx2x_8481_set_legacy_led_mode(params,
- ext_phy_type,
- ext_phy_addr);
- }
- }
- break;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
- break;
- }
- /* Set SGMII mode for external phy */
- if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- if (vars->line_speed < SPEED_1000)
- vars->phy_flags |= PHY_SGMII_FLAG;
- else
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
+}
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- ext_phy_link_up = 1;
- break;
+/******************************************************************/
+/* BCM8481/BCM84823/BCM84833 PHY SECTION */
+/******************************************************************/
+static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ u16 val, fw_ver1, fw_ver2, cnt;
+ struct bnx2x *bp = params->bp;
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- ext_phy_link_up = 1;
+ /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
+ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
break;
+ udelay(5);
+ }
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
+ bnx2x_save_spirom_version(bp, params->port, 0,
+ phy->ver_addr);
+ return;
+ }
- default:
- DP(NETIF_MSG_LINK,
- "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
+
+ /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
break;
- }
+ udelay(5);
}
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
+ bnx2x_save_spirom_version(bp, params->port, 0,
+ phy->ver_addr);
+ return;
+ }
+
+ /* lower 16 bits of the register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
+ /* upper 16 bits of register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
- return ext_phy_link_up;
+ bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
+ phy->ver_addr);
}
-static void bnx2x_link_int_enable(struct link_params *params)
+static void bnx2x_848xx_set_led(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
{
- u8 port = params->port;
- u32 ext_phy_type;
- u32 mask;
- struct bnx2x *bp = params->bp;
+ u16 val;
- /* setting the status to report on link up
- for either XGXS or SerDes */
+ /* PHYC_CTL_LED_CTL */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
+ val &= 0xFE00;
+ val |= 0x0092;
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL, val);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x80);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x18);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0040);
- if (params->switch_cfg == SWITCH_CFG_10G) {
- mask = (NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_XGXS0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
+ /* 'Interrupt Mask' */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ 0xFFFB, 0xFFFD);
+}
- } else { /* SerDes */
- mask = NIG_MASK_SERDES0_LINK_STATUS;
- DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
+static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 autoneg_val, an_1000_val, an_10_100_val;
+ bnx2x_wait_reset_complete(bp, phy);
+ bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
+ 1 << NIG_LATCH_BC_ENABLE_MI_INT);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
+
+ bnx2x_848xx_set_led(bp, phy);
+
+ /* set 1000 speed advertisement */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
+ &an_1000_val);
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_AN_ADV,
+ &an_10_100_val);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+ &autoneg_val);
+ /* Disable forced speed */
+ autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
+ an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
+
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
+ (phy->req_line_speed == SPEED_1000)) {
+ an_1000_val |= (1<<8);
+ autoneg_val |= (1<<9 | 1<<12);
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_1000_val |= (1<<9);
+ DP(NETIF_MSG_LINK, "Advertising 1G\n");
+ } else
+ an_1000_val &= ~((1<<8) | (1<<9));
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
+ an_1000_val);
+
+ /* set 10 speed advertisement */
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
+ an_10_100_val |= (1<<7);
+ /* Enable autoneg and restart autoneg for legacy speeds */
+ autoneg_val |= (1<<9 | 1<<12);
+
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_10_100_val |= (1<<8);
+ DP(NETIF_MSG_LINK, "Advertising 100M\n");
+ }
+ /* set 10 speed advertisement */
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
+ an_10_100_val |= (1<<5);
+ autoneg_val |= (1<<9 | 1<<12);
+ if (phy->req_duplex == DUPLEX_FULL)
+ an_10_100_val |= (1<<6);
+ DP(NETIF_MSG_LINK, "Advertising 10M\n");
}
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- mask);
- DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
- (params->switch_cfg == SWITCH_CFG_10G),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
- DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-}
+ /* Only 10/100 are allowed to work in FORCE mode */
+ if (phy->req_line_speed == SPEED_100) {
+ autoneg_val |= (1<<13);
+ /* Enabled AUTO-MDIX when autoneg is disabled */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
+ (1<<15 | 1<<9 | 7<<0));
+ DP(NETIF_MSG_LINK, "Setting 100M force\n");
+ }
+ if (phy->req_line_speed == SPEED_10) {
+ /* Enabled AUTO-MDIX when autoneg is disabled */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
+ (1<<15 | 1<<9 | 7<<0));
+ DP(NETIF_MSG_LINK, "Setting 10M force\n");
+ }
-static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
- u8 is_mi_int)
-{
- u32 latch_status = 0, is_mi_int_status;
- /* Disable the MI INT ( external phy int )
- * by writing 1 to the status register. Link down indication
- * is high-active-signal, so in this case we need to write the
- * status to clear the XOR
- */
- /* Read Latched signals */
- latch_status = REG_RD(bp,
- NIG_REG_LATCH_STATUS_0 + port*8);
- is_mi_int_status = REG_RD(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
- DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
- "latch_status = 0x%x\n",
- is_mi_int, is_mi_int_status, latch_status);
- /* Handle only those with latched-signal=up.*/
- if (latch_status & 1) {
- /* For all latched-signal=up,Write original_signal to status */
- if (is_mi_int)
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0
- + port*4,
- NIG_STATUS_EMAC0_MI_INT);
- else
- bnx2x_bits_dis(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0
- + port*4,
- NIG_STATUS_EMAC0_MI_INT);
- /* For all latched-signal=up : Re-Arm Latch signals */
- REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
- (latch_status & 0xfffe) | (latch_status & 1));
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
+ an_10_100_val);
+
+ if (phy->req_duplex == DUPLEX_FULL)
+ autoneg_val |= (1<<8);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
+
+ if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ (phy->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
+ (phy->req_line_speed == SPEED_10000)) {
+ DP(NETIF_MSG_LINK, "Advertising 10G\n");
+ /* Restart autoneg for 10G*/
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
+ 0x3200);
+ } else if (phy->req_line_speed != SPEED_10 &&
+ phy->req_line_speed != SPEED_100) {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
+ 1);
}
+ /* Save spirom version */
+ bnx2x_save_848xx_spirom_version(phy, params);
+
+ return 0;
}
-/*
- * link management
- */
-static void bnx2x_link_int_ack(struct link_params *params,
- struct link_vars *vars, u8 is_10g,
- u8 is_mi_int)
+
+static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
- /* first reset all status
- * we assume only one line will be change at a time */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
- if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
- == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
- == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
- bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
- }
- if (vars->phy_link_up) {
- if (is_10g) {
- /* Disable the 10G link interrupt
- * by writing 1 to the status register
- */
- DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_XGXS0_LINK10G);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
- } else if (params->switch_cfg == SWITCH_CFG_10G) {
- /* Disable the link interrupt
- * by writing 1 to the relevant lane
- * in the status register
- */
- u32 ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
+ return bnx2x_848xx_cmn_config_init(phy, params, vars);
+}
- DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
- vars->line_speed);
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- ((1 << ser_lane) <<
- NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
+static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port, initialize = 1;
+ u16 val;
+ u16 temp;
+ u32 actual_phy_selection;
+ u8 rc = 0;
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes phy link up\n");
- /* Disable the link interrupt
- * by writing 1 to the status register
- */
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_SERDES0_LINK_STATUS);
- }
+ /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
- } else { /* link_down */
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ port);
+ msleep(200); /* 100 is not enough */
+
+ /* BCM84823 requires that XGXS links up first @ 10G for normal
+ behavior */
+ temp = vars->line_speed;
+ vars->line_speed = SPEED_10000;
+ bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
+ bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
+ vars->line_speed = temp;
+
+ /* Set dual-media configuration according to configuration */
+
+ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
+ MDIO_CTL_REG_84823_MEDIA, &val);
+ val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
+ MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
+ MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
+ MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
+ MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
+ val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
+ MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
+
+ actual_phy_selection = bnx2x_phy_selection(params);
+
+ switch (actual_phy_selection) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ /* Do nothing. Essentialy this is like the priority copper */
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ /* Do nothing here. The first PHY won't be initialized at all */
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
+ initialize = 0;
+ break;
}
+ if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
+ val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
+
+ bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+ MDIO_CTL_REG_84823_MEDIA, val);
+ DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
+ params->multi_phy_config, val);
+
+ if (initialize)
+ rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
+ else
+ bnx2x_save_848xx_spirom_version(phy, params);
+ return rc;
}
-static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
+static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
- u8 *str_ptr = str;
- u32 mask = 0xf0000000;
- u8 shift = 8*4;
- u8 digit;
- if (len < 10) {
- /* Need more than 10chars for this format */
- *str_ptr = '\0';
- return -EINVAL;
- }
- while (shift > 0) {
+ struct bnx2x *bp = params->bp;
+ u16 val, val1, val2;
+ u8 link_up = 0;
+
+ /* Check 10G-BaseT link status */
+ /* Check PMD signal ok */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, 0xFFFA, &val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
+ &val2);
+ DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
+
+ /* Check link 10G */
+ if (val2 & (1<<11)) {
+ vars->line_speed = SPEED_10000;
+ link_up = 1;
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ } else { /* Check Legacy speed link */
+ u16 legacy_status, legacy_speed;
+
+ /* Enable expansion register 0x42 (Operation mode status) */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
+
+ /* Get legacy speed operation status */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
+ &legacy_status);
+
+ DP(NETIF_MSG_LINK, "Legacy speed status"
+ " = 0x%x\n", legacy_status);
+ link_up = ((legacy_status & (1<<11)) == (1<<11));
+ if (link_up) {
+ legacy_speed = (legacy_status & (3<<9));
+ if (legacy_speed == (0<<9))
+ vars->line_speed = SPEED_10;
+ else if (legacy_speed == (1<<9))
+ vars->line_speed = SPEED_100;
+ else if (legacy_speed == (2<<9))
+ vars->line_speed = SPEED_1000;
+ else /* Should not happen */
+ vars->line_speed = 0;
- shift -= 4;
- digit = ((num & mask) >> shift);
- if (digit < 0xa)
- *str_ptr = digit + '0';
- else
- *str_ptr = digit - 0xa + 'a';
- str_ptr++;
- mask = mask >> 4;
- if (shift == 4*4) {
- *str_ptr = ':';
- str_ptr++;
+ if (legacy_status & (1<<8))
+ vars->duplex = DUPLEX_FULL;
+ else
+ vars->duplex = DUPLEX_HALF;
+
+ DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
+ " is_duplex_full= %d\n", vars->line_speed,
+ (vars->duplex == DUPLEX_FULL));
+ /* Check legacy speed AN resolution */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_MII_STATUS,
+ &val);
+ if (val & (1<<5))
+ vars->link_status |=
+ LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
+ &val);
+ if ((val & (1<<0)) == 0)
+ vars->link_status |=
+ LINK_STATUS_PARALLEL_DETECTION_USED;
}
}
- *str_ptr = '\0';
- return 0;
+ if (link_up) {
+ DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
+ vars->line_speed);
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
+ }
+
+ return link_up;
}
-u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
- u8 *version, u16 len)
+static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
{
- struct bnx2x *bp;
- u32 ext_phy_type = 0;
- u32 spirom_ver = 0;
- u8 status;
+ u8 status = 0;
+ u32 spirom_ver;
+ spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
+ status = bnx2x_format_ver(spirom_ver, str, len);
+ return status;
+}
- if (version == NULL || params == NULL)
- return -EINVAL;
- bp = params->bp;
+static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
+}
- spirom_ver = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[params->port].ext_phy_fw_version));
+static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ bnx2x_cl45_write(params->bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
+ bnx2x_cl45_write(params->bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
+}
- status = 0;
- /* reset the returned value to zero */
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ port);
+}
- if (len < 5)
- return -EINVAL;
+static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val;
- version[0] = (spirom_ver & 0xFF);
- version[1] = (spirom_ver & 0xFF00) >> 8;
- version[2] = (spirom_ver & 0xFF0000) >> 16;
- version[3] = (spirom_ver & 0xFF000000) >> 24;
- version[4] = '\0';
+ switch (mode) {
+ case LED_MODE_OFF:
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- status = bnx2x_format_ver(spirom_ver, version, len);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
- (spirom_ver & 0x7F);
- status = bnx2x_format_ver(spirom_ver, version, len);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- version[0] = '\0';
- break;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
- " type is FAILURE!\n");
- status = -EINVAL;
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x0);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+ }
break;
+ case LED_MODE_FRONT_PANEL_OFF:
- default:
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
+ params->port);
+
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x0);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x20);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
+ }
break;
- }
- return status;
-}
+ case LED_MODE_ON:
-static void bnx2x_set_xgxs_loopback(struct link_params *params,
- struct link_vars *vars,
- u8 is_10g)
-{
- u8 port = params->port;
- struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
- if (is_10g) {
- u32 md_devad;
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
+ /* Set control reg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ &val);
+ val &= 0x8000;
+ val |= 0x2492;
- DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ val);
- /* change the uni_phy_addr in the nig */
- md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
- port*0x18));
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x20);
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_AER_BLOCK +
- (MDIO_AER_BLOCK_AER_REG & 0xf)),
- 0x2800);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x20);
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_CL73_IEEEB0 +
- (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
- 0x6041);
- msleep(200);
- /* set aer mmd back */
- bnx2x_set_aer_mmd(params, vars);
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x0);
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x20);
+ }
+ break;
- /* and md_devad */
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
- md_devad);
+ case LED_MODE_OPER:
- } else {
- u16 mii_control;
+ DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
- DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+ if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
+ SHARED_HW_CFG_LED_EXTPHY1) {
- CL45_RD_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
+ /* Set control reg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ &val);
+
+ if (!((val &
+ MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
+ >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
+ DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LINK_SIGNAL,
+ 0xa492);
+ }
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
+ /* Set LED masks */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x10);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED2_MASK,
+ 0x80);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED3_MASK,
+ 0x98);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED5_MASK,
+ 0x40);
+
+ } else {
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8481_LED1_MASK,
+ 0x80);
+ }
+ break;
}
}
+/******************************************************************/
+/* SFX7101 PHY SECTION */
+/******************************************************************/
+static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
+ struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ /* SFX7101_XGXS_TEST1 */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
+}
-
-static void bnx2x_ext_phy_loopback(struct link_params *params)
+static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
{
+ u16 fw_ver1, fw_ver2, val;
struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u32 ext_phy_type;
+ DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
- if (params->switch_cfg == SWITCH_CFG_10G) {
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- /* CL37 Autoneg Enabled */
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: We should not get here\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 0x0001);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* SFX7101_XGXS_TEST1 */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_SFX7101_XGXS_TEST1,
- 0x100);
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: set ext phy loopback\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
+ /* HW reset */
+ bnx2x_ext_phy_hw_reset(bp, params->port);
+ bnx2x_wait_reset_complete(bp, phy);
+
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
+ DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
+
+ bnx2x_ext_phy_set_pause(params, phy, vars);
+ /* Restart autoneg */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
+ val |= 0x200;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
+
+ /* Save spirom version */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
+
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
+ bnx2x_save_spirom_version(bp, params->port,
+ (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
+ return 0;
+}
- break;
- } /* switch external PHY type */
- } else {
- /* serdes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = (params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
- >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
+static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
+ struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_up;
+ u16 val1, val2;
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
+ val2, val1);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
+ val2, val1);
+ link_up = ((val1 & 4) == 4);
+ /* if link is up
+ * print the AN outcome of the SFX7101 PHY
+ */
+ if (link_up) {
+ bnx2x_cl45_read(bp, phy,
+ MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
+ &val2);
+ vars->line_speed = SPEED_10000;
+ DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
+ val2, (val2 & (1<<14)));
+ bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
+ bnx2x_ext_phy_resolve_fc(phy, params, vars);
}
+ return link_up;
}
-/*
- *------------------------------------------------------------------------
- * bnx2x_override_led_value -
- *
- * Override the led value of the requsted led
- *
- *------------------------------------------------------------------------
- */
-u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
- u32 led_idx, u32 value)
+static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
{
- u32 reg_val;
+ if (*len < 5)
+ return -EINVAL;
+ str[0] = (spirom_ver & 0xFF);
+ str[1] = (spirom_ver & 0xFF00) >> 8;
+ str[2] = (spirom_ver & 0xFF0000) >> 16;
+ str[3] = (spirom_ver & 0xFF000000) >> 24;
+ str[4] = '\0';
+ *len -= 5;
+ return 0;
+}
- /* If port 0 then use EMAC0, else use EMAC1*/
- u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
+{
+ u16 val, cnt;
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() port %x led_idx %d value %d\n",
- port, led_idx, value);
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
- switch (led_idx) {
- case 0: /* 10MB led */
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 10M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_10MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 1: /*100MB led */
- /*Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 100M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_100MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ for (cnt = 0; cnt < 10; cnt++) {
+ msleep(50);
+ /* Writes a self-clearing reset */
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET,
+ (val | (1<<15)));
+ /* Wait for clear */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
+
+ if ((val & (1<<15)) == 0)
+ break;
+ }
+}
+
+static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
+ struct link_params *params) {
+ /* Low power mode is controlled by GPIO 2 */
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
+ /* The PHY reset is controlled by GPIO 1 */
+ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
+}
+
+static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode)
+{
+ u16 val = 0;
+ struct bnx2x *bp = params->bp;
+ switch (mode) {
+ case LED_MODE_FRONT_PANEL_OFF:
+ case LED_MODE_OFF:
+ val = 2;
break;
- case 2: /* 1000MB led */
- /* Read the current value of the LED register in the
- EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
- reset it. */
- reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ case LED_MODE_ON:
+ val = 1;
break;
- case 3: /* 2500MB led */
- /* Read the current value of the LED register in the
- EMAC block*/
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ case LED_MODE_OPER:
+ val = 0;
break;
- case 4: /*10G led */
- if (port == 0) {
- REG_WR(bp, NIG_REG_LED_10G_P0,
- value);
+ }
+ bnx2x_cl45_write(bp, phy,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7107_LINK_LED_CNTL,
+ val);
+}
+
+/******************************************************************/
+/* STATIC PHY DECLARATION */
+/******************************************************************/
+
+static struct bnx2x_phy phy_null = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
+ .addr = 0,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = 0,
+ .media_type = ETH_PHY_NOT_PRESENT,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)NULL,
+ .read_status = (read_status_t)NULL,
+ .link_reset = (link_reset_t)NULL,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_serdes = {
+ .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
+ .addr = 0xff,
+ .flags = 0,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_init_serdes,
+ .read_status = (read_status_t)bnx2x_link_settings_status,
+ .link_reset = (link_reset_t)bnx2x_int_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_xgxs = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
+ .addr = 0xff,
+ .flags = 0,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_init_xgxs,
+ .read_status = (read_status_t)bnx2x_link_settings_status,
+ .link_reset = (link_reset_t)bnx2x_int_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
+ .format_fw_ver = (format_fw_ver_t)NULL,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_7101 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_7101_config_init,
+ .read_status = (read_status_t)bnx2x_7101_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8073 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ .addr = 0xff,
+ .flags = FLAGS_HW_LOCK_REQUIRED,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_UNSPECIFIED,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8073_config_init,
+ .read_status = (read_status_t)bnx2x_8073_read_status,
+ .link_reset = (link_reset_t)bnx2x_8073_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8705 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
+ .addr = 0xff,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_XFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8705_config_init,
+ .read_status = (read_status_t)bnx2x_8705_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+static struct bnx2x_phy phy_8706 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
+ .addr = 0xff,
+ .flags = FLAGS_INIT_XGXS_FIRST,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8706_config_init,
+ .read_status = (read_status_t)bnx2x_8706_read_status,
+ .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_8726 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ .addr = 0xff,
+ .flags = (FLAGS_HW_LOCK_REQUIRED |
+ FLAGS_INIT_XGXS_FIRST),
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8726_config_init,
+ .read_status = (read_status_t)bnx2x_8726_read_status,
+ .link_reset = (link_reset_t)bnx2x_8726_link_reset,
+ .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)NULL,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_8727 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_SFP_FIBER,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8727_config_init,
+ .read_status = (read_status_t)bnx2x_8727_read_status,
+ .link_reset = (link_reset_t)bnx2x_8727_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
+};
+static struct bnx2x_phy phy_8481 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_8481_config_init,
+ .read_status = (read_status_t)bnx2x_848xx_read_status,
+ .link_reset = (link_reset_t)bnx2x_8481_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
+ .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
+ .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+static struct bnx2x_phy phy_84823 = {
+ .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
+ .addr = 0xff,
+ .flags = FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL,
+ .def_md_devad = 0,
+ .reserved = 0,
+ .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
+ .mdio_ctrl = 0,
+ .supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .media_type = ETH_PHY_BASE_T,
+ .ver_addr = 0,
+ .req_flow_ctrl = 0,
+ .req_line_speed = 0,
+ .speed_cap_mask = 0,
+ .req_duplex = 0,
+ .rsrv = 0,
+ .config_init = (config_init_t)bnx2x_848x3_config_init,
+ .read_status = (read_status_t)bnx2x_848xx_read_status,
+ .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
+ .config_loopback = (config_loopback_t)NULL,
+ .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
+ .hw_reset = (hw_reset_t)NULL,
+ .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
+ .phy_specific_func = (phy_specific_func_t)NULL
+};
+
+/*****************************************************************/
+/* */
+/* Populate the phy according. Main function: bnx2x_populate_phy */
+/* */
+/*****************************************************************/
+
+static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
+ struct bnx2x_phy *phy, u8 port,
+ u8 phy_index)
+{
+ /* Get the 4 lanes xgxs config rx and tx */
+ u32 rx = 0, tx = 0, i;
+ for (i = 0; i < 2; i++) {
+ /**
+ * INT_PHY and EXT_PHY1 share the same value location in the
+ * shmem. When num_phys is greater than 1, than this value
+ * applies only to EXT_PHY1
+ */
+ if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
+ rx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
+
+ tx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
} else {
- REG_WR(bp, NIG_REG_LED_10G_P1,
- value);
+ rx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
+
+ tx = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
}
+
+ phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
+ phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
+
+ phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
+ phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
+ }
+}
+
+static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
+ u8 phy_index, u8 port)
+{
+ u32 ext_phy_config = 0;
+ switch (phy_index) {
+ case EXT_PHY1:
+ ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config));
break;
- case 5: /* TRAFFIC led */
- /* Find if the traffic control is via BMAC or EMAC */
- if (port == 0)
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
- else
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
+ case EXT_PHY2:
+ ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config2));
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
+ return -EINVAL;
+ }
- /* Override the traffic led in the EMAC:*/
- if (reg_val == 1) {
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base +
- EMAC_REG_EMAC_LED);
- /* Set the TRAFFIC_OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the TRAFFIC bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
- (reg_val & ~EMAC_LED_TRAFFIC);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- } else { /* Override the traffic led in the BMAC: */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
- value);
- }
+ return ext_phy_config;
+}
+static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
+ struct bnx2x_phy *phy)
+{
+ u32 phy_addr;
+ u32 chip_id;
+ u32 switch_cfg = (REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_feature_config[port].link_config)) &
+ PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
+ switch (switch_cfg) {
+ case SWITCH_CFG_1G:
+ phy_addr = REG_RD(bp,
+ NIG_REG_SERDES0_CTRL_PHY_ADDR +
+ port * 0x10);
+ *phy = phy_serdes;
+ break;
+ case SWITCH_CFG_10G:
+ phy_addr = REG_RD(bp,
+ NIG_REG_XGXS0_CTRL_PHY_ADDR +
+ port * 0x18);
+ *phy = phy_xgxs;
break;
default:
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() unknown led index %d "
- "(should be 0-5)\n", led_idx);
+ DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
return -EINVAL;
}
+ phy->addr = (u8)phy_addr;
+ phy->mdio_ctrl = bnx2x_get_emac_base(bp,
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
+ port);
+ phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
+
+ DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
+ port, phy->addr, phy->mdio_ctrl);
+ bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
return 0;
}
-
-u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
+static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
+ u8 phy_index,
+ u32 shmem_base,
+ u32 shmem2_base,
+ u8 port,
+ struct bnx2x_phy *phy)
{
- u8 port = params->port;
- u16 hw_led_mode = params->hw_led_mode;
- u8 rc = 0;
- u32 tmp;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- struct bnx2x *bp = params->bp;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
- DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
- speed, hw_led_mode);
- switch (mode) {
- case LED_MODE_OFF:
- REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
- SHARED_HW_CFG_LED_MAC1);
-
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
+ u32 ext_phy_config, phy_type, config2;
+ u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
+ ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
+ phy_index, port);
+ phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+ /* Select the phy type */
+ switch (phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
+ *phy = phy_8073;
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ *phy = phy_8705;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ *phy = phy_8706;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8726;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
+ /* BCM8727_NOC => BCM8727 no over current */
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8727;
+ phy->flags |= FLAGS_NOC;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+ mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
+ *phy = phy_8727;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ *phy = phy_8481;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
+ *phy = phy_84823;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ *phy = phy_7101;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ *phy = phy_null;
+ return -EINVAL;
+ default:
+ *phy = phy_null;
+ return 0;
+ }
- case LED_MODE_OPER:
- if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
- REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
- } else {
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
- hw_led_mode);
- }
+ phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
+ bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
- port*4, 0);
- /* Set blinking rate to ~15.9Hz */
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
- port*4, 1);
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED,
- (tmp & (~EMAC_LED_OVERRIDE)));
+ /**
+ * The shmem address of the phy version is located on different
+ * structures. In case this structure is too old, do not set
+ * the address
+ */
+ config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
+ dev_info.shared_hw_config.config2));
+ if (phy_index == EXT_PHY1) {
+ phy->ver_addr = shmem_base + offsetof(struct shmem_region,
+ port_mb[port].ext_phy_fw_version);
+
+ /* Check specific mdc mdio settings */
+ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
+ mdc_mdio_access = config2 &
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
+ } else {
+ u32 size = REG_RD(bp, shmem2_base);
- if (CHIP_IS_E1(bp) &&
- ((speed == SPEED_2500) ||
- (speed == SPEED_1000) ||
- (speed == SPEED_100) ||
- (speed == SPEED_10))) {
- /* On Everest 1 Ax chip versions for speeds less than
- 10G LED scheme is different */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
- port*4, 0);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
- port*4, 1);
+ if (size >
+ offsetof(struct shmem2_region, ext_phy_fw_version2)) {
+ phy->ver_addr = shmem2_base +
+ offsetof(struct shmem2_region,
+ ext_phy_fw_version2[port]);
}
- break;
-
- default:
- rc = -EINVAL;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
- mode);
- break;
+ /* Check specific mdc mdio settings */
+ if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
+ mdc_mdio_access = (config2 &
+ SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
+ (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
+ SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
}
- return rc;
+ phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
+ /**
+ * In case mdc/mdio_access of the external phy is different than the
+ * mdc/mdio access of the XGXS, a HW lock must be taken in each access
+ * to prevent one port interfere with another port's CL45 operations.
+ */
+ if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
+ phy->flags |= FLAGS_HW_LOCK_REQUIRED;
+ DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
+ phy_type, port, phy_index);
+ DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
+ phy->addr, phy->mdio_ctrl);
+ return 0;
}
-u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
+static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
+ u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
{
- struct bnx2x *bp = params->bp;
- u16 gp_status = 0;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
- /* link is up only if both local phy and external phy are up */
- if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
- bnx2x_ext_phy_is_link_up(params, vars, 1))
- return 0;
-
- return -ESRCH;
+ u8 status = 0;
+ phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
+ if (phy_index == INT_PHY)
+ return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
+ status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, phy);
+ return status;
}
-static u8 bnx2x_link_initialize(struct link_params *params,
- struct link_vars *vars)
+static void bnx2x_phy_def_cfg(struct link_params *params,
+ struct bnx2x_phy *phy,
+ u8 phy_index)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
- u8 non_ext_phy;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Activate the external PHY */
- bnx2x_ext_phy_reset(params, vars);
-
- bnx2x_set_aer_mmd(params, vars);
+ u32 link_config;
+ /* Populate the default phy configuration for MF mode */
+ if (phy_index == EXT_PHY2) {
+ link_config = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_feature_config[params->port].link_config2));
+ phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_hw_config[params->port].speed_capability_mask2));
+ } else {
+ link_config = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_feature_config[params->port].link_config));
+ phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region, dev_info.
+ port_hw_config[params->port].speed_capability_mask));
+ }
+ DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
+ " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
+
+ phy->req_duplex = DUPLEX_FULL;
+ switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+ case PORT_FEATURE_LINK_SPEED_10M_HALF:
+ phy->req_duplex = DUPLEX_HALF;
+ case PORT_FEATURE_LINK_SPEED_10M_FULL:
+ phy->req_line_speed = SPEED_10;
+ break;
+ case PORT_FEATURE_LINK_SPEED_100M_HALF:
+ phy->req_duplex = DUPLEX_HALF;
+ case PORT_FEATURE_LINK_SPEED_100M_FULL:
+ phy->req_line_speed = SPEED_100;
+ break;
+ case PORT_FEATURE_LINK_SPEED_1G:
+ phy->req_line_speed = SPEED_1000;
+ break;
+ case PORT_FEATURE_LINK_SPEED_2_5G:
+ phy->req_line_speed = SPEED_2500;
+ break;
+ case PORT_FEATURE_LINK_SPEED_10G_CX4:
+ phy->req_line_speed = SPEED_10000;
+ break;
+ default:
+ phy->req_line_speed = SPEED_AUTO_NEG;
+ break;
+ }
- if (vars->phy_flags & PHY_XGXS_FLAG)
- bnx2x_set_master_ln(params);
+ switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
+ case PORT_FEATURE_FLOW_CONTROL_AUTO:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_TX:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_RX:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
+ break;
+ case PORT_FEATURE_FLOW_CONTROL_BOTH:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
+ break;
+ default:
+ phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ break;
+ }
+}
- rc = bnx2x_reset_unicore(params);
- /* reset the SerDes and wait for reset bit return low */
- if (rc != 0)
- return rc;
+u32 bnx2x_phy_selection(struct link_params *params)
+{
+ u32 phy_config_swapped, prio_cfg;
+ u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
+
+ phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+
+ prio_cfg = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SELECTION_MASK;
+
+ if (phy_config_swapped) {
+ switch (prio_cfg) {
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ break;
+ }
+ } else
+ return_cfg = prio_cfg;
- bnx2x_set_aer_mmd(params, vars);
+ return return_cfg;
+}
- /* setting the masterLn_def again after the reset */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- bnx2x_set_master_ln(params);
- bnx2x_set_swap_lanes(params);
- }
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if ((params->req_line_speed &&
- ((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) ||
- (!params->req_line_speed &&
- (params->speed_cap_mask >=
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
- (params->speed_cap_mask <
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
- )) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
+u8 bnx2x_phy_probe(struct link_params *params)
+{
+ u8 phy_index, actual_phy_idx, link_cfg_idx;
+ u32 phy_config_swapped;
+ struct bnx2x *bp = params->bp;
+ struct bnx2x_phy *phy;
+ params->num_phys = 0;
+ DP(NETIF_MSG_LINK, "Begin phy probe\n");
+ phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+
+ for (phy_index = INT_PHY; phy_index < MAX_PHYS;
+ phy_index++) {
+ link_cfg_idx = LINK_CONFIG_IDX(phy_index);
+ actual_phy_idx = phy_index;
+ if (phy_config_swapped) {
+ if (phy_index == EXT_PHY1)
+ actual_phy_idx = EXT_PHY2;
+ else if (phy_index == EXT_PHY2)
+ actual_phy_idx = EXT_PHY1;
}
+ DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
+ " actual_phy_idx %x\n", phy_config_swapped,
+ phy_index, actual_phy_idx);
+ phy = &params->phy[actual_phy_idx];
+ if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
+ params->shmem2_base, params->port,
+ phy) != 0) {
+ params->num_phys = 0;
+ DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
+ phy_index);
+ for (phy_index = INT_PHY;
+ phy_index < MAX_PHYS;
+ phy_index++)
+ *phy = phy_null;
+ return -EINVAL;
+ }
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
+ break;
+
+ bnx2x_phy_def_cfg(params, phy, phy_index);
+ params->num_phys++;
}
- /* In case of external phy existance, the line speed would be the
- line speed linked up by the external phy. In case it is direct only,
- then the line_speed during initialization will be equal to the
- req_line_speed*/
- vars->line_speed = params->req_line_speed;
- bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
+ DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
+ return 0;
+}
- /* init ext phy and enable link state int */
- non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (params->loopback_mode == LOOPBACK_XGXS_10));
+u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx)
+{
+ if (phy_idx < params->num_phys)
+ return params->phy[phy_idx].supported;
+ return 0;
+}
- if (non_ext_phy ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY)) {
- if (params->req_line_speed == SPEED_AUTO_NEG)
- bnx2x_set_parallel_detection(params, vars->phy_flags);
- bnx2x_init_internal_phy(params, vars, non_ext_phy);
- }
+static void set_phy_vars(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 actual_phy_idx, phy_index, link_cfg_idx;
+ u8 phy_config_swapped = params->multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED;
+ for (phy_index = INT_PHY; phy_index < params->num_phys;
+ phy_index++) {
+ link_cfg_idx = LINK_CONFIG_IDX(phy_index);
+ actual_phy_idx = phy_index;
+ if (phy_config_swapped) {
+ if (phy_index == EXT_PHY1)
+ actual_phy_idx = EXT_PHY2;
+ else if (phy_index == EXT_PHY2)
+ actual_phy_idx = EXT_PHY1;
+ }
+ params->phy[actual_phy_idx].req_flow_ctrl =
+ params->req_flow_ctrl[link_cfg_idx];
- if (!non_ext_phy)
- rc |= bnx2x_ext_phy_init(params, vars);
+ params->phy[actual_phy_idx].req_line_speed =
+ params->req_line_speed[link_cfg_idx];
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
+ params->phy[actual_phy_idx].speed_cap_mask =
+ params->speed_cap_mask[link_cfg_idx];
- return rc;
+ params->phy[actual_phy_idx].req_duplex =
+ params->req_duplex[link_cfg_idx];
+ DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
+ " speed_cap_mask %x\n",
+ params->phy[actual_phy_idx].req_flow_ctrl,
+ params->phy[actual_phy_idx].req_line_speed,
+ params->phy[actual_phy_idx].speed_cap_mask);
+ }
}
-
u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u32 val;
-
DP(NETIF_MSG_LINK, "Phy Initialization started\n");
- DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
- params->req_line_speed, params->req_flow_ctrl);
+ DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
+ params->req_line_speed[0], params->req_flow_ctrl[0]);
+ DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
+ params->req_line_speed[1], params->req_flow_ctrl[1]);
vars->link_status = 0;
vars->phy_link_up = 0;
vars->link_up = 0;
@@ -5966,11 +6705,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
vars->mac_type = MAC_TYPE_NONE;
-
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
+ vars->phy_flags = 0;
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
@@ -5981,6 +6716,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
bnx2x_emac_init(params, vars);
+ if (params->num_phys == 0) {
+ DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
+ return -EINVAL;
+ }
+ set_phy_vars(params);
+
+ DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
if (CHIP_REV_IS_FPGA(bp)) {
vars->link_up = 1;
@@ -6040,7 +6782,8 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->phy_flags = PHY_XGXS_FLAG;
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
+
/* set bmac loopback */
bnx2x_bmac_enable(params, vars, 1);
@@ -6057,80 +6800,66 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
vars->phy_flags = PHY_XGXS_FLAG;
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
/* set bmac loopback */
bnx2x_emac_enable(params, vars, 1);
- bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
+ bnx2x_emac_program(params, vars);
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
- } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
+ } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
(params->loopback_mode == LOOPBACK_EXT_PHY)) {
vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ vars->duplex = DUPLEX_FULL;
+ if (params->req_line_speed[0] == SPEED_1000) {
+ vars->line_speed = SPEED_1000;
+ vars->mac_type = MAC_TYPE_EMAC;
+ } else {
+ vars->line_speed = SPEED_10000;
+ vars->mac_type = MAC_TYPE_BMAC;
+ }
- vars->phy_flags = PHY_XGXS_FLAG;
-
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_xgxs_deassert(params);
bnx2x_link_initialize(params, vars);
- vars->mac_type = MAC_TYPE_BMAC;
-
+ if (params->req_line_speed[0] == SPEED_1000) {
+ bnx2x_emac_program(params, vars);
+ bnx2x_emac_enable(params, vars, 0);
+ } else
bnx2x_bmac_enable(params, vars, 0);
- if (params->loopback_mode == LOOPBACK_XGXS_10) {
+ if (params->loopback_mode == LOOPBACK_XGXS) {
/* set 10G XGXS loopback */
- bnx2x_set_xgxs_loopback(params, vars, 1);
+ params->phy[INT_PHY].config_loopback(
+ &params->phy[INT_PHY],
+ params);
+
} else {
/* set external phy loopback */
- bnx2x_ext_phy_loopback(params);
+ u8 phy_index;
+ for (phy_index = EXT_PHY1;
+ phy_index < params->num_phys; phy_index++) {
+ if (params->phy[phy_index].config_loopback)
+ params->phy[phy_index].config_loopback(
+ &params->phy[phy_index],
+ params);
+ }
}
+
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
- bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
+ bnx2x_set_led(params, vars,
+ LED_MODE_OPER, vars->line_speed);
} else
/* No loopback */
{
- bnx2x_phy_deassert(params, vars->phy_flags);
- switch (params->switch_cfg) {
- case SWITCH_CFG_1G:
- vars->phy_flags |= PHY_SERDES_FLAG;
- if ((params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- }
-
- val = REG_RD(bp,
- NIG_REG_SERDES0_CTRL_PHY_ADDR+
- params->port*0x10);
-
- params->phy_addr = (u8)val;
-
- break;
- case SWITCH_CFG_10G:
- vars->phy_flags |= PHY_XGXS_FLAG;
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- break;
- default:
- DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
- return -EINVAL;
- }
- DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
+ if (params->switch_cfg == SWITCH_CFG_10G)
+ bnx2x_xgxs_deassert(params);
+ else
+ bnx2x_serdes_deassert(bp, params->port);
bnx2x_link_initialize(params, vars);
msleep(30);
@@ -6138,29 +6867,11 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
}
return 0;
}
-
-static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
-{
- DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
-
- /* Set serial boot control for external load */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL, 0x0001);
-}
-
u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
u8 reset_ext_phy)
{
struct bnx2x *bp = params->bp;
- u32 ext_phy_config = params->ext_phy_config;
- u8 port = params->port;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
- u32 val = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region, dev_info.
- port_feature_config[params->port].
- config));
+ u8 phy_index, port = params->port;
DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
/* disable attentions */
vars->link_status = 0;
@@ -6189,73 +6900,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
* Hold it as vars low
*/
/* clear link led */
- bnx2x_set_led(params, LED_MODE_OFF, 0);
- if (reset_ext_phy) {
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- break;
+ bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- {
-
- /* Disable Transmitter */
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
- PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
- bnx2x_sfp_set_transmitter(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr, 0);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
- "low power mode\n",
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- /* Set soft reset */
- bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- {
- u8 ext_phy_addr =
- XGXS_EXT_PHY_ADDR(params->ext_phy_config);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x0000);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 1);
- break;
- }
- default:
- /* HW reset */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- DP(NETIF_MSG_LINK, "reset external PHY\n");
+ if (reset_ext_phy) {
+ for (phy_index = EXT_PHY1; phy_index < params->num_phys;
+ phy_index++) {
+ if (params->phy[phy_index].link_reset)
+ params->phy[phy_index].link_reset(
+ &params->phy[phy_index],
+ params);
}
}
- /* reset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- (0x1ff << (port*16)));
+ if (params->phy[INT_PHY].link_reset)
+ params->phy[INT_PHY].link_reset(
+ &params->phy[INT_PHY], params);
/* reset BigMac */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -6269,183 +6928,25 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
return 0;
}
-static u8 bnx2x_update_link_down(struct link_params *params,
- struct link_vars *vars)
+/****************************************************************************/
+/* Common function */
+/****************************************************************************/
+static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index)
{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
-
- DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
- bnx2x_set_led(params, LED_MODE_OFF, 0);
-
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
-
- /* update shared memory */
- vars->link_status = 0;
- vars->line_speed = 0;
- bnx2x_update_mng(params, vars->link_status);
-
- /* activate nig drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* disable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- msleep(10);
-
- /* reset BigMac */
- bnx2x_bmac_rx_disable(bp, params->port);
- REG_WR(bp, GRCBASE_MISC +
- MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- return 0;
-}
-
-static u8 bnx2x_update_link_up(struct link_params *params,
- struct link_vars *vars,
- u8 link_10g, u32 gp_status)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
-
- vars->link_status |= LINK_STATUS_LINK_UP;
- if (link_10g) {
- bnx2x_bmac_enable(params, vars, 0);
- bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
- } else {
- rc = bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
-
- bnx2x_emac_enable(params, vars, 0);
-
- /* AN complete? */
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- if (!(vars->phy_flags &
- PHY_SGMII_FLAG))
- bnx2x_set_gmii_tx_driver(params);
- }
- }
-
- /* PBF - link up */
- rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
- vars->line_speed);
-
- /* disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(params, vars->link_status);
- msleep(20);
- return rc;
-}
-/* This function should called upon link interrupt */
-/* In case vars->link_up, driver needs to
- 1. Update the pbf
- 2. Disable drain
- 3. Update the shared memory
- 4. Indicate link up
- 5. Set LEDs
- Otherwise,
- 1. Update shared memory
- 2. Reset BigMac
- 3. Report link down
- 4. Unset LEDs
-*/
-u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 gp_status;
- u8 link_10g;
- u8 ext_phy_link_up, rc = 0;
- u32 ext_phy_type;
- u8 is_mi_int = 0;
-
- DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
- port, (vars->phy_flags & PHY_XGXS_FLAG),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
- is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
- port*0x18) > 0);
- DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- is_mi_int,
- REG_RD(bp,
- NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
-
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-
- /* disable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Check external link change only for non-direct */
- ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
-
- /* Read gp_status */
- CL45_RD_OVER_CL22(bp, port, params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
-
- rc = bnx2x_link_settings_status(params, vars, gp_status,
- ext_phy_link_up);
- if (rc != 0)
- return rc;
-
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
-
- bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
-
- /* In case external phy link is up, and internal link is down
- ( not initialized yet probably after link initialization, it needs
- to be initialized.
- Note that after link down-up as result of cable plug,
- the xgxs link would probably become up again without the need to
- initialize it*/
-
- if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
- (ext_phy_link_up && !vars->phy_link_up))
- bnx2x_init_internal_phy(params, vars, 0);
-
- /* link is up only if both local phy and external phy are up */
- vars->link_up = (ext_phy_link_up && vars->phy_link_up);
-
- if (vars->link_up)
- rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
- else
- rc = bnx2x_update_link_down(params, vars);
-
- return rc;
-}
-
-static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- u8 ext_phy_addr[PORT_MAX];
+ struct bnx2x_phy phy[PORT_MAX];
+ struct bnx2x_phy *phy_blk[PORT_MAX];
u16 val;
s8 port;
/* PART1 - Reset both phys */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
/* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
-
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy[port]) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate_phy failed\n");
+ return -EINVAL;
+ }
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
(NIG_MASK_XGXS0_LINK_STATUS |
@@ -6453,17 +6954,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
-
/* Need to take the phy out of low power mode in order
to write to access its registers */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
/* Reset the phy */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, &phy[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
1<<15);
@@ -6472,15 +6969,22 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* Add delay of 150ms after reset */
msleep(150);
+ if (phy[PORT_0].addr & 0x1) {
+ phy_blk[PORT_0] = &(phy[PORT_1]);
+ phy_blk[PORT_1] = &(phy[PORT_0]);
+ } else {
+ phy_blk[PORT_0] = &(phy[PORT_0]);
+ phy_blk[PORT_1] = &(phy[PORT_1]);
+ }
+
/* PART2 - Download firmware to both phys */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
u16 fw_ver1;
- bnx2x_bcm8073_external_rom_boot(bp, port,
- ext_phy_addr[port], shmem_base);
+ bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+ port);
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
@@ -6492,16 +6996,12 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
}
/* Only set bit 10 = 1 (Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, &val);
/* Phase1 of TX_POWER_DOWN reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN,
(val | 1<<10));
@@ -6515,28 +7015,20 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
/* Phase2 of POWER_DOWN_RESET */
/* Release bit 10 (Release Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, &val);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
msleep(15);
/* Read modify write the SPI-ROM version select register */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_EDC_FFE_MAIN, &val);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
@@ -6545,33 +7037,74 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
}
return 0;
-
}
-static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base, u8 phy_index)
+{
+ u32 val;
+ s8 port;
+ struct bnx2x_phy phy;
+ /* Use port1 because of the static port-swap */
+ /* Enable the module detection interrupt */
+ val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
+ val |= ((1<<MISC_REGISTERS_GPIO_3)|
+ (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
+ REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
+
+ bnx2x_ext_phy_hw_reset(bp, 1);
+ msleep(5);
+ for (port = 0; port < PORT_MAX; port++) {
+ /* Extract the ext phy address for the port */
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return -EINVAL;
+ }
+
+ /* Reset phy*/
+ bnx2x_cl45_write(bp, &phy,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
+
+
+ /* Set fault module detected LED on */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ port);
+ }
+
+ return 0;
+}
+static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base, u8 phy_index)
{
- u8 ext_phy_addr[PORT_MAX];
- s8 port, first_port, i;
+ s8 port;
u32 swap_val, swap_override;
+ struct bnx2x_phy phy[PORT_MAX];
+ struct bnx2x_phy *phy_blk[PORT_MAX];
DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
- msleep(5);
+ port = 1;
- if (swap_val && swap_override)
- first_port = PORT_0;
- else
- first_port = PORT_1;
+ bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
+
+ /* Calculate the port based on port swap */
+ port ^= (swap_val && swap_override);
+
+ msleep(5);
/* PART1 - Reset both phys */
- for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
+ for (port = PORT_MAX - 1; port >= PORT_0; port--) {
/* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
-
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy[port]) !=
+ 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return -EINVAL;
+ }
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
(NIG_MASK_XGXS0_LINK_STATUS |
@@ -6579,12 +7112,9 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
/* Reset the phy */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr[port],
+ bnx2x_cl45_write(bp, &phy[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
1<<15);
@@ -6592,16 +7122,20 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* Add delay of 150ms after reset */
msleep(150);
-
+ if (phy[PORT_0].addr & 0x1) {
+ phy_blk[PORT_0] = &(phy[PORT_1]);
+ phy_blk[PORT_1] = &(phy[PORT_0]);
+ } else {
+ phy_blk[PORT_0] = &(phy[PORT_0]);
+ phy_blk[PORT_1] = &(phy[PORT_1]);
+ }
/* PART2 - Download firmware to both phys */
- for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
+ for (port = PORT_MAX - 1; port >= PORT_0; port--) {
u16 fw_ver1;
- bnx2x_bcm8727_external_rom_boot(bp, port,
- ext_phy_addr[port], shmem_base);
-
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
- ext_phy_addr[port],
+ bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
+ port);
+ bnx2x_cl45_read(bp, phy_blk[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
@@ -6616,82 +7150,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
return 0;
}
-
-static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- u8 ext_phy_addr;
- u32 val;
- s8 port;
-
- /* Use port1 because of the static port-swap */
- /* Enable the module detection interrupt */
- val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
- val |= ((1<<MISC_REGISTERS_GPIO_3)|
- (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
- REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
-
- bnx2x_ext_phy_hw_reset(bp, 1);
- msleep(5);
- for (port = 0; port < PORT_MAX; port++) {
- /* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
-
- ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
- DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
- ext_phy_addr);
-
- bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
-
- /* Set fault module detected LED on */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_HIGH,
- port);
- }
-
- return 0;
-}
-
-
-static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- /* HW reset */
- bnx2x_ext_phy_hw_reset(bp, 1);
- return 0;
-}
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base, u8 phy_index,
+ u32 ext_phy_type)
{
u8 rc = 0;
- u32 ext_phy_type;
-
- DP(NETIF_MSG_LINK, "Begin common phy init\n");
-
- /* Read the ext_phy_type for arbitrary port(0) */
- ext_phy_type = XGXS_EXT_PHY_TYPE(
- REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[0].external_phy_config)));
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- rc = bnx2x_8073_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8073_common_init_phy(bp, shmem_base,
+ shmem2_base, phy_index);
break;
- }
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
- rc = bnx2x_8727_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8727_common_init_phy(bp, shmem_base,
+ shmem2_base, phy_index);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
/* GPIO1 affects both ports, so there's need to pull
it for single port alone */
- rc = bnx2x_8726_common_init_phy(bp, shmem_base);
+ rc = bnx2x_8726_common_init_phy(bp, shmem_base,
+ shmem2_base, phy_index);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
- rc = bnx2x_84823_common_init_phy(bp, shmem_base);
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ rc = -EINVAL;
break;
default:
DP(NETIF_MSG_LINK,
@@ -6703,33 +7187,80 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
return rc;
}
-void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
+u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base)
{
- u16 val, cnt;
+ u8 rc = 0;
+ u8 phy_index;
+ u32 ext_phy_type, ext_phy_config;
+ DP(NETIF_MSG_LINK, "Begin common phy init\n");
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
+ if (CHIP_REV_IS_EMUL(bp))
+ return 0;
- for (cnt = 0; cnt < 10; cnt++) {
- msleep(50);
- /* Writes a self-clearing reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET,
- (val | (1<<15)));
- /* Wait for clear */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
+ /* Read the ext_phy_type for arbitrary port(0) */
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ ext_phy_config = bnx2x_get_ext_phy_config(bp,
+ shmem_base,
+ phy_index, 0);
+ ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+ rc |= bnx2x_ext_phy_common_init(bp, shmem_base,
+ shmem2_base,
+ phy_index, ext_phy_type);
+ }
+ return rc;
+}
- if ((val & (1<<15)) == 0)
- break;
+u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
+{
+ u8 phy_index;
+ struct bnx2x_phy phy;
+ for (phy_index = INT_PHY; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ 0, &phy) != 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return 0;
+ }
+
+ if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
+ return 1;
+ }
+ return 0;
+}
+
+u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
+ u32 shmem_base,
+ u32 shmem2_base,
+ u8 port)
+{
+ u8 phy_index, fan_failure_det_req = 0;
+ struct bnx2x_phy phy;
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
+ port, &phy)
+ != 0) {
+ DP(NETIF_MSG_LINK, "populate phy failed\n");
+ return 0;
+ }
+ fan_failure_det_req |= (phy.flags &
+ FLAGS_FAN_FAILURE_DET_REQ);
+ }
+ return fan_failure_det_req;
+}
+
+void bnx2x_hw_reset_phy(struct link_params *params)
+{
+ u8 phy_index;
+ for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+ phy_index++) {
+ if (params->phy[phy_index].hw_reset) {
+ params->phy[phy_index].hw_reset(
+ &params->phy[phy_index],
+ params);
+ params->phy[phy_index] = phy_null;
+ }
}
}
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h
index 40c2981de8ed..e98ea3d19471 100644
--- a/drivers/net/bnx2x/bnx2x_link.h
+++ b/drivers/net/bnx2x/bnx2x_link.h
@@ -1,4 +1,4 @@
-/* Copyright 2008-2009 Broadcom Corporation
+/* Copyright 2008-2010 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -46,9 +46,137 @@
#define SFP_EEPROM_PART_NO_ADDR 0x28
#define SFP_EEPROM_PART_NO_SIZE 16
#define PWR_FLT_ERR_MSG_LEN 250
+
+#define XGXS_EXT_PHY_TYPE(ext_phy_config) \
+ ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
+#define XGXS_EXT_PHY_ADDR(ext_phy_config) \
+ (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
+#define SERDES_EXT_PHY_TYPE(ext_phy_config) \
+ ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+
+/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */
+#define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1)
+/* Single Media board contains single external phy */
+#define SINGLE_MEDIA(params) (params->num_phys == 2)
+/* Dual Media board contains two external phy with different media */
+#define DUAL_MEDIA(params) (params->num_phys == 3)
+#define FW_PARAM_MDIO_CTRL_OFFSET 16
+#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
+ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET)
/***********************************************************/
/* Structs */
/***********************************************************/
+#define INT_PHY 0
+#define EXT_PHY1 1
+#define EXT_PHY2 2
+#define MAX_PHYS 3
+
+/* Same configuration is shared between the XGXS and the first external phy */
+#define LINK_CONFIG_SIZE (MAX_PHYS - 1)
+#define LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == INT_PHY) ? \
+ 0 : (_phy_idx - 1))
+/***********************************************************/
+/* bnx2x_phy struct */
+/* Defines the required arguments and function per phy */
+/***********************************************************/
+struct link_vars;
+struct link_params;
+struct bnx2x_phy;
+
+typedef u8 (*config_init_t)(struct bnx2x_phy *phy, struct link_params *params,
+ struct link_vars *vars);
+typedef u8 (*read_status_t)(struct bnx2x_phy *phy, struct link_params *params,
+ struct link_vars *vars);
+typedef void (*link_reset_t)(struct bnx2x_phy *phy,
+ struct link_params *params);
+typedef void (*config_loopback_t)(struct bnx2x_phy *phy,
+ struct link_params *params);
+typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len);
+typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params);
+typedef void (*set_link_led_t)(struct bnx2x_phy *phy,
+ struct link_params *params, u8 mode);
+typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy,
+ struct link_params *params, u32 action);
+
+struct bnx2x_phy {
+ u32 type;
+
+ /* Loaded during init */
+ u8 addr;
+
+ u8 flags;
+ /* Require HW lock */
+#define FLAGS_HW_LOCK_REQUIRED (1<<0)
+ /* No Over-Current detection */
+#define FLAGS_NOC (1<<1)
+ /* Fan failure detection required */
+#define FLAGS_FAN_FAILURE_DET_REQ (1<<2)
+ /* Initialize first the XGXS and only then the phy itself */
+#define FLAGS_INIT_XGXS_FIRST (1<<3)
+#define FLAGS_REARM_LATCH_SIGNAL (1<<6)
+#define FLAGS_SFP_NOT_APPROVED (1<<7)
+
+ u8 def_md_devad;
+ u8 reserved;
+ /* preemphasis values for the rx side */
+ u16 rx_preemphasis[4];
+
+ /* preemphasis values for the tx side */
+ u16 tx_preemphasis[4];
+
+ /* EMAC address for access MDIO */
+ u32 mdio_ctrl;
+
+ u32 supported;
+
+ u32 media_type;
+#define ETH_PHY_UNSPECIFIED 0x0
+#define ETH_PHY_SFP_FIBER 0x1
+#define ETH_PHY_XFP_FIBER 0x2
+#define ETH_PHY_DA_TWINAX 0x3
+#define ETH_PHY_BASE_T 0x4
+#define ETH_PHY_NOT_PRESENT 0xff
+
+ /* The address in which version is located*/
+ u32 ver_addr;
+
+ u16 req_flow_ctrl;
+
+ u16 req_line_speed;
+
+ u32 speed_cap_mask;
+
+ u16 req_duplex;
+ u16 rsrv;
+ /* Called per phy/port init, and it configures LASI, speed, autoneg,
+ duplex, flow control negotiation, etc. */
+ config_init_t config_init;
+
+ /* Called due to interrupt. It determines the link, speed */
+ read_status_t read_status;
+
+ /* Called when driver is unloading. Should reset the phy */
+ link_reset_t link_reset;
+
+ /* Set the loopback configuration for the phy */
+ config_loopback_t config_loopback;
+
+ /* Format the given raw number into str up to len */
+ format_fw_ver_t format_fw_ver;
+
+ /* Reset the phy (both ports) */
+ hw_reset_t hw_reset;
+
+ /* Set link led mode (on/off/oper)*/
+ set_link_led_t set_link_led;
+
+ /* PHY Specific tasks */
+ phy_specific_func_t phy_specific_func;
+#define DISABLE_TX 1
+#define ENABLE_TX 2
+};
+
/* Inputs parameters to the CLC */
struct link_params {
@@ -59,56 +187,50 @@ struct link_params {
#define LOOPBACK_NONE 0
#define LOOPBACK_EMAC 1
#define LOOPBACK_BMAC 2
-#define LOOPBACK_XGXS_10 3
+#define LOOPBACK_XGXS 3
#define LOOPBACK_EXT_PHY 4
#define LOOPBACK_EXT 5
- u16 req_duplex;
- u16 req_flow_ctrl;
- u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
- req_flow_ctrl is set to AUTO */
- u16 req_line_speed; /* Also determine AutoNeg */
-
/* Device parameters */
u8 mac_addr[6];
+ u16 req_duplex[LINK_CONFIG_SIZE];
+ u16 req_flow_ctrl[LINK_CONFIG_SIZE];
+
+ u16 req_line_speed[LINK_CONFIG_SIZE]; /* Also determine AutoNeg */
+
/* shmem parameters */
u32 shmem_base;
- u32 speed_cap_mask;
+ u32 shmem2_base;
+ u32 speed_cap_mask[LINK_CONFIG_SIZE];
u32 switch_cfg;
#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
- u16 hw_led_mode; /* part of the hw_config read from the shmem */
-
- /* phy_addr populated by the phy_init function */
- u8 phy_addr;
- /*u8 reserved1;*/
-
u32 lane_config;
- u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(ext_phy_config) \
- ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define XGXS_EXT_PHY_ADDR(ext_phy_config) \
- (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
-#define SERDES_EXT_PHY_TYPE(ext_phy_config) \
- ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
/* Phy register parameter */
u32 chip_id;
- u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
- u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
-
u32 feature_config_flags;
#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
-#define FEATURE_CONFIG_BCM8727_NOC (1<<3)
+#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
+ /* Will be populated during common init */
+ struct bnx2x_phy phy[MAX_PHYS];
+
+ /* Will be populated during common init */
+ u8 num_phys;
+
+ u8 rsrv;
+ u16 hw_led_mode; /* part of the hw_config read from the shmem */
+ u32 multi_phy_config;
/* Device pointer passed to all callback functions */
struct bnx2x *bp;
+ u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
+ req_flow_ctrl is set to AUTO */
};
/* Output parameters */
@@ -129,12 +251,6 @@ struct link_vars {
u16 flow_ctrl;
u16 ieee_fc;
- u32 autoneg;
-#define AUTO_NEG_DISABLED 0x0
-#define AUTO_NEG_ENABLED 0x1
-#define AUTO_NEG_COMPLETE 0x2
-#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3
-
/* The same definitions as the shmem parameter */
u32 link_status;
};
@@ -142,8 +258,6 @@ struct link_vars {
/***********************************************************/
/* Functions */
/***********************************************************/
-
-/* Initialize the phy */
u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
/* Reset the link. Should be called when driver or interface goes down
@@ -155,17 +269,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
/* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
-/* use the following cl45 functions to read/write from external_phy
+/* use the following phy functions to read/write from external_phy
In order to use it to read/write internal phy registers, use
DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as
- Use ext_phy_type of 0 in case of cl22 over cl45
the register */
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val);
+u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 *ret_val);
+
+u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
+ u8 devad, u16 reg, u16 val);
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val);
+u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 *ret_val);
+u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
+ u8 devad, u16 reg, u16 val);
/* Reads the link_status from the shmem,
and update the link vars accordingly */
void bnx2x_link_status_update(struct link_params *input,
@@ -178,9 +296,12 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
Basically, the CLC takes care of the led for the link, but in case one needs
to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to
blink the led, and LED_MODE_OFF to set the led off.*/
-u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed);
-#define LED_MODE_OFF 0
-#define LED_MODE_OPER 2
+u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars,
+ u8 mode, u32 speed);
+#define LED_MODE_OFF 0
+#define LED_MODE_ON 1
+#define LED_MODE_OPER 2
+#define LED_MODE_FRONT_PANEL_OFF 3
u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
@@ -190,17 +311,38 @@ void bnx2x_handle_module_detect_int(struct link_params *params);
/* Get the actual link status. In case it returns 0, link is up,
otherwise link is down*/
-u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
+u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars,
+ u8 is_serdes);
/* One-time initialization for external phy after power up */
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
+u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base);
/* Reset the external PHY using GPIO */
void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port);
-void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr);
+/* Reset the external of SFX7101 */
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy);
-u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
+ struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf);
+void bnx2x_hw_reset_phy(struct link_params *params);
+
+/* Checks if HW lock is required for this phy/board type */
+u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base);
+
+/* Returns the aggregative supported attributes of the phys on board */
+u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx);
+
+/* Check swap bit and adjust PHY order */
+u32 bnx2x_phy_selection(struct link_params *params);
+
+/* Probe the phys on board, and populate them in "params" */
+u8 bnx2x_phy_probe(struct link_params *params);
+/* Checks if fan failure detection is required on one of the phys on board */
+u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base,
+ u32 shmem2_base, u8 port);
+
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index f8c3f08e4ce7..67587fe9e358 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -781,7 +781,7 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource)
DP(NETIF_MSG_HW,
"resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
+ return false;
}
if (func <= 5)
@@ -1227,26 +1227,66 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
return 0;
}
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = 0;
+ if (bp->link_vars.link_up) {
+ sel_phy_idx = EXT_PHY1;
+ /* In case link is SERDES, check if the EXT_PHY2 is the one */
+ if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) &&
+ (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE))
+ sel_phy_idx = EXT_PHY2;
+ } else {
+
+ switch (bnx2x_phy_selection(&bp->link_params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY2;
+ break;
+ }
+ }
+ /*
+ * The selected actived PHY is always after swapping (in case PHY
+ * swapping is enabled). So when swapping is enabled, we need to reverse
+ * the configuration
+ */
+
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ if (sel_phy_idx == EXT_PHY1)
+ sel_phy_idx = EXT_PHY2;
+ else if (sel_phy_idx == EXT_PHY2)
+ sel_phy_idx = EXT_PHY1;
+ }
+ return LINK_CONFIG_IDX(sel_phy_idx);
+}
+
void bnx2x_calc_fc_adv(struct bnx2x *bp)
{
+ u8 cfg_idx = bnx2x_get_link_cfg_idx(bp);
switch (bp->link_vars.ieee_fc &
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) {
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
+ bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
- bp->port.advertising |= (ADVERTISED_Asym_Pause |
+ bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
- bp->port.advertising |= ADVERTISED_Asym_Pause;
+ bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause;
break;
default:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
+ bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
}
@@ -1257,7 +1297,8 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
{
if (!BP_NOMCP(bp)) {
u8 rc;
-
+ int cfx_idx = bnx2x_get_link_cfg_idx(bp);
+ u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx];
/* Initialize link parameters structure variables */
/* It is recommended to turn off RX FC for jumbo frames
for better performance */
@@ -1268,8 +1309,10 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
bnx2x_acquire_phy_lock(bp);
- if (load_mode == LOAD_DIAG)
- bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+ if (load_mode == LOAD_DIAG) {
+ bp->link_params.loopback_mode = LOOPBACK_XGXS;
+ bp->link_params.req_line_speed[cfx_idx] = SPEED_10000;
+ }
rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
@@ -1281,7 +1324,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
bnx2x_link_report(bp);
}
-
+ bp->link_params.req_line_speed[cfx_idx] = req_line_speed;
return rc;
}
BNX2X_ERR("Bootcode is missing - can not initialize link\n");
@@ -1292,6 +1335,7 @@ void bnx2x_link_set(struct bnx2x *bp)
{
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
+ bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
bnx2x_release_phy_lock(bp);
@@ -1310,13 +1354,14 @@ static void bnx2x__link_reset(struct bnx2x *bp)
BNX2X_ERR("Bootcode is missing - can not reset link\n");
}
-u8 bnx2x_link_test(struct bnx2x *bp)
+u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes)
{
u8 rc = 0;
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_test_link(&bp->link_params, &bp->link_vars);
+ rc = bnx2x_test_link(&bp->link_params, &bp->link_vars,
+ is_serdes);
bnx2x_release_phy_lock(bp);
} else
BNX2X_ERR("Bootcode is missing - can not test link\n");
@@ -1585,7 +1630,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
*/
/* send the MCP a request, block until there is a reply */
-u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
{
int func = BP_FUNC(bp);
u32 seq = ++bp->fw_seq;
@@ -1594,6 +1639,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
mutex_lock(&bp->fw_mb_mutex);
+ SHMEM_WR(bp, func_mb[func].drv_mb_param, param);
SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
@@ -1715,9 +1761,9 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
/* Report results to MCP */
if (dcc_event)
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0);
else
- bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0);
}
/* must be called under the spq lock */
@@ -1959,12 +2005,16 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
static inline void bnx2x_fan_failure(struct bnx2x *bp)
{
int port = BP_PORT(bp);
-
+ u32 ext_phy_config;
/* mark the failure */
- bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+
+ ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+ ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config,
- bp->link_params.ext_phy_config);
+ ext_phy_config);
/* log the failure */
netdev_err(bp->dev, "Fan Failure on Network Controller has caused"
@@ -1976,7 +2026,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
{
int port = BP_PORT(bp);
int reg_offset;
- u32 val, swap_val, swap_override;
+ u32 val;
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -1990,30 +2040,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
BNX2X_ERR("SPIO5 hw attention\n");
/* Fan failure attention */
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* Low power mode is controlled by GPIO 2 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- /* The PHY reset is controlled by GPIO 1 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- /* The PHY reset is controlled by GPIO 1 */
- /* fake the port number to cancel the swap done in
- set_gpio() */
- swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
- swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- port = (swap_val && swap_override) ^ 1;
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- break;
-
- default:
- break;
- }
+ bnx2x_hw_reset_phy(&bp->link_params);
bnx2x_fan_failure(bp);
}
@@ -3803,10 +3830,9 @@ static const struct {
static void enable_blocks_parity(struct bnx2x *bp)
{
- int i, mask_arr_len =
- sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0]));
+ int i;
- for (i = 0; i < mask_arr_len; i++)
+ for (i = 0; i < ARRAY_SIZE(bnx2x_parity_mask); i++)
REG_WR(bp, bnx2x_parity_mask[i].addr,
bnx2x_parity_mask[i].mask);
}
@@ -3862,17 +3888,12 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
*/
else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE)
for (port = PORT_0; port < PORT_MAX; port++) {
- u32 phy_type =
- SHMEM_RD(bp, dev_info.port_hw_config[port].
- external_phy_config) &
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
is_required |=
- ((phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) ||
- (phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
- (phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481));
+ bnx2x_fan_failure_det_req(
+ bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base,
+ port);
}
DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required);
@@ -4139,17 +4160,9 @@ static int bnx2x_init_common(struct bnx2x *bp)
return -EBUSY;
}
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- bp->port.need_hw_lock = 1;
- break;
-
- default:
- break;
- }
+ bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base);
bnx2x_setup_fan_failure_detection(bp);
@@ -4162,7 +4175,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
- bnx2x_common_init_phy(bp, bp->common.shmem_base);
+ bnx2x_common_init_phy(bp, bp->common.shmem_base,
+ bp->common.shmem2_base);
bnx2x_release_phy_lock(bp);
} else
BNX2X_ERR("Bootcode is missing - can not initialize link\n");
@@ -4297,60 +4311,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
bnx2x_init_block(bp, MCP_BLOCK, init_stage);
bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
-
- switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- {
- u32 swap_val, swap_override, aeu_gpio_mask, offset;
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
- MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
-
- /* The GPIO should be swapped if the swap register is
- set and active */
- swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
- swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
-
- /* Select function upon port-swap configuration */
- if (port == 0) {
- offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
- aeu_gpio_mask = (swap_val && swap_override) ?
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
- } else {
- offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
- aeu_gpio_mask = (swap_val && swap_override) ?
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
- AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
- }
- val = REG_RD(bp, offset);
- /* add GPIO3 to group */
- val |= aeu_gpio_mask;
- REG_WR(bp, offset, val);
- }
- bp->port.need_hw_lock = 1;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- bp->port.need_hw_lock = 1;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* add SPIO 5 to group 0 */
- {
+ bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
+ bp->common.shmem_base,
+ bp->common.shmem2_base);
+ if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base,
+ bp->common.shmem2_base, port)) {
u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
val = REG_RD(bp, reg_addr);
val |= AEU_INPUTS_ATTN_BITS_SPIO5;
REG_WR(bp, reg_addr, val);
- }
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- bp->port.need_hw_lock = 1;
- break;
- default:
- break;
}
-
bnx2x__link_reset(bp);
return 0;
@@ -4480,7 +4451,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
-
+ bnx2x_phy_probe(&bp->link_params);
return 0;
}
@@ -5302,7 +5273,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
unload_error:
if (!BP_NOMCP(bp))
- reset_code = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code, 0);
else {
DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
@@ -5327,7 +5298,7 @@ unload_error:
/* Report UNLOAD_DONE to MCP */
if (!BP_NOMCP(bp))
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
}
@@ -5892,13 +5863,14 @@ 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);
- reset_code = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code, 0);
/* if UNDI is loaded on the other port */
if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
/* send "DONE" for previous unload */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_UNLOAD_DONE, 0);
/* unload UNDI on port 1 */
bp->func = 1;
@@ -5907,7 +5879,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
DRV_MSG_SEQ_NUMBER_MASK);
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
- bnx2x_fw_command(bp, reset_code);
+ bnx2x_fw_command(bp, reset_code, 0);
}
/* now it's safe to release the lock */
@@ -5949,7 +5921,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
/* send unload done to the MCP */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
/* restore our func and fw_seq */
bp->func = func;
@@ -5997,6 +5969,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0);
bp->link_params.shmem_base = bp->common.shmem_base;
+ bp->link_params.shmem2_base = bp->common.shmem2_base;
BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n",
bp->common.shmem_base, bp->common.shmem2_base);
@@ -6039,8 +6012,11 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
"please upgrade BC\n", BNX2X_BC_VER, val);
}
bp->link_params.feature_config_flags |=
- (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ?
+ (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ?
FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
+ bp->link_params.feature_config_flags |=
+ (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ?
+ FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0;
if (BP_E1HVN(bp) == 0) {
pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
@@ -6064,194 +6040,55 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
u32 switch_cfg)
{
- int port = BP_PORT(bp);
- u32 ext_phy_type;
-
- switch (switch_cfg) {
- case SWITCH_CFG_1G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
-
- ext_phy_type =
- SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
+ int cfg_size = 0, idx, port = BP_PORT(bp);
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
+ /* Aggregation of supported attributes of all external phys */
+ bp->port.supported[0] = 0;
+ bp->port.supported[1] = 0;
+ switch (bp->link_params.num_phys) {
+ case 1:
+ bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported;
+ cfg_size = 1;
+ break;
+ case 2:
+ bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported;
+ cfg_size = 1;
+ break;
+ case 3:
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ bp->port.supported[1] =
+ bp->link_params.phy[EXT_PHY1].supported;
+ bp->port.supported[0] =
+ bp->link_params.phy[EXT_PHY2].supported;
+ } else {
+ bp->port.supported[0] =
+ bp->link_params.phy[EXT_PHY1].supported;
+ bp->port.supported[1] =
+ bp->link_params.phy[EXT_PHY2].supported;
+ }
+ cfg_size = 2;
+ break;
+ }
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD SerDes ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
+ if (!(bp->port.supported[0] || bp->port.supported[1])) {
+ BNX2X_ERR("NVRAM config error. BAD phy config."
+ "PHY1 config 0x%x, PHY2 config 0x%x\n",
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config),
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config2));
return;
}
+ switch (switch_cfg) {
+ case SWITCH_CFG_1G:
bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
port*0x10);
BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
break;
case SWITCH_CFG_10G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
-
- ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- return;
- }
-
bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
port*0x18);
BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
@@ -6260,164 +6097,183 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
default:
BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
- bp->port.link_config);
+ bp->port.link_config[0]);
return;
}
- bp->link_params.phy_addr = bp->port.phy_addr;
-
- /* mask what we support according to speed_cap_mask */
- if (!(bp->link_params.speed_cap_mask &
+ /* mask what we support according to speed_cap_mask per configuration */
+ for (idx = 0; idx < cfg_size; idx++) {
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
- bp->port.supported &= ~SUPPORTED_10baseT_Half;
+ bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
- bp->port.supported &= ~SUPPORTED_10baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
- bp->port.supported &= ~SUPPORTED_100baseT_Half;
+ bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
- bp->port.supported &= ~SUPPORTED_100baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
- bp->port.supported &= ~(SUPPORTED_1000baseT_Half |
+ bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->port.supported &= ~SUPPORTED_2500baseX_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full;
- if (!(bp->link_params.speed_cap_mask &
+ if (!(bp->link_params.speed_cap_mask[idx] &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
- bp->port.supported &= ~SUPPORTED_10000baseT_Full;
+ bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full;
+
+ }
- BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported);
+ BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0],
+ bp->port.supported[1]);
}
static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
{
- bp->link_params.req_duplex = DUPLEX_FULL;
-
- switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+ u32 link_config, idx, cfg_size = 0;
+ bp->port.advertising[0] = 0;
+ bp->port.advertising[1] = 0;
+ switch (bp->link_params.num_phys) {
+ case 1:
+ case 2:
+ cfg_size = 1;
+ break;
+ case 3:
+ cfg_size = 2;
+ break;
+ }
+ for (idx = 0; idx < cfg_size; idx++) {
+ bp->link_params.req_duplex[idx] = DUPLEX_FULL;
+ link_config = bp->port.link_config[idx];
+ switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
case PORT_FEATURE_LINK_SPEED_AUTO:
- if (bp->port.supported & SUPPORTED_Autoneg) {
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
+ if (bp->port.supported[idx] & SUPPORTED_Autoneg) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_AUTO_NEG;
+ bp->port.advertising[idx] |=
+ bp->port.supported[idx];
} else {
- 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_BCM8705) ||
- (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
- /* force 10G, no AN */
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising =
- (ADVERTISED_10000baseT_Full |
+ /* force 10G, no AN */
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
- break;
- }
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " Autoneg not supported\n",
- bp->port.link_config);
- return;
+ continue;
}
break;
case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->port.supported & SUPPORTED_10baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->port.advertising = (ADVERTISED_10baseT_Full |
+ if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->port.supported & SUPPORTED_10baseT_Half) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_10baseT_Half |
+ if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10;
+ bp->link_params.req_duplex[idx] =
+ DUPLEX_HALF;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10baseT_Half |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->port.supported & SUPPORTED_100baseT_Full) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->port.advertising = (ADVERTISED_100baseT_Full |
+ if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_100;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->port.supported & SUPPORTED_100baseT_Half) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_100baseT_Half |
+ if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) {
+ bp->link_params.req_line_speed[idx] = SPEED_100;
+ bp->link_params.req_duplex[idx] = DUPLEX_HALF;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_100baseT_Half |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->port.supported & SUPPORTED_1000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_1000;
- bp->port.advertising = (ADVERTISED_1000baseT_Full |
+ if (bp->port.supported[idx] &
+ SUPPORTED_1000baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_1000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_1000baseT_Full |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->port.supported & SUPPORTED_2500baseX_Full) {
- bp->link_params.req_line_speed = SPEED_2500;
- bp->port.advertising = (ADVERTISED_2500baseX_Full |
+ if (bp->port.supported[idx] &
+ SUPPORTED_2500baseX_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_2500;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
@@ -6425,16 +6281,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
case PORT_FEATURE_LINK_SPEED_10G_CX4:
case PORT_FEATURE_LINK_SPEED_10G_KX4:
case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (bp->port.supported & SUPPORTED_10000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising = (ADVERTISED_10000baseT_Full |
+ if (bp->port.supported[idx] &
+ SUPPORTED_10000baseT_Full) {
+ bp->link_params.req_line_speed[idx] =
+ SPEED_10000;
+ bp->port.advertising[idx] |=
+ (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
} else {
BNX2X_ERROR("NVRAM config error. "
"Invalid link_config 0x%x"
" speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
+ link_config,
+ bp->link_params.speed_cap_mask[idx]);
return;
}
break;
@@ -6442,23 +6301,28 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
default:
BNX2X_ERROR("NVRAM config error. "
"BAD link speed link_config 0x%x\n",
- bp->port.link_config);
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
+ link_config);
+ bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG;
+ bp->port.advertising[idx] = bp->port.supported[idx];
break;
}
- bp->link_params.req_flow_ctrl = (bp->port.link_config &
+ bp->link_params.req_flow_ctrl[idx] = (link_config &
PORT_FEATURE_FLOW_CONTROL_MASK);
- if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- !(bp->port.supported & SUPPORTED_Autoneg))
- bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
+ if ((bp->link_params.req_flow_ctrl[idx] ==
+ BNX2X_FLOW_CTRL_AUTO) &&
+ !(bp->port.supported[idx] & SUPPORTED_Autoneg)) {
+ bp->link_params.req_flow_ctrl[idx] =
+ BNX2X_FLOW_CTRL_NONE;
+ }
- BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x"
- " advertising 0x%x\n",
- bp->link_params.req_line_speed,
- bp->link_params.req_duplex,
- bp->link_params.req_flow_ctrl, bp->port.advertising);
+ BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl"
+ " 0x%x advertising 0x%x\n",
+ bp->link_params.req_line_speed[idx],
+ bp->link_params.req_duplex[idx],
+ bp->link_params.req_flow_ctrl[idx],
+ bp->port.advertising[idx]);
+ }
}
static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
@@ -6474,48 +6338,28 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
int port = BP_PORT(bp);
u32 val, val2;
u32 config;
- u16 i;
- u32 ext_phy_type;
+ u32 ext_phy_type, ext_phy_config;;
bp->link_params.bp = bp;
bp->link_params.port = port;
bp->link_params.lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
- bp->link_params.ext_phy_config =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].external_phy_config);
- /* BCM8727_NOC => BCM8727 no over current */
- if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) {
- bp->link_params.ext_phy_config &=
- ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->link_params.ext_phy_config |=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727;
- bp->link_params.feature_config_flags |=
- FEATURE_CONFIG_BCM8727_NOC;
- }
- bp->link_params.speed_cap_mask =
+ bp->link_params.speed_cap_mask[0] =
SHMEM_RD(bp,
dev_info.port_hw_config[port].speed_capability_mask);
-
- bp->port.link_config =
+ bp->link_params.speed_cap_mask[1] =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].speed_capability_mask2);
+ bp->port.link_config[0] =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- /* Get the 4 lanes xgxs config rx and tx */
- for (i = 0; i < 2; i++) {
- val = SHMEM_RD(bp,
- dev_info.port_hw_config[port].xgxs_config_rx[i<<1]);
- bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff);
- bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff);
-
- val = SHMEM_RD(bp,
- dev_info.port_hw_config[port].xgxs_config_tx[i<<1]);
- bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff);
- bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
- }
+ bp->port.link_config[1] =
+ SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2);
+ bp->link_params.multi_phy_config =
+ SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config);
/* If the device is capable of WoL, set the default state according
* to the HW
*/
@@ -6523,14 +6367,15 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
(config & PORT_FEATURE_WOL_ENABLED));
- BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x"
- " speed_cap_mask 0x%08x link_config 0x%08x\n",
+ BNX2X_DEV_INFO("lane_config 0x%08x"
+ "speed_cap_mask0 0x%08x link_config0 0x%08x\n",
bp->link_params.lane_config,
- bp->link_params.ext_phy_config,
- bp->link_params.speed_cap_mask, bp->port.link_config);
+ bp->link_params.speed_cap_mask[0],
+ bp->port.link_config[0]);
- bp->link_params.switch_cfg |= (bp->port.link_config &
+ bp->link_params.switch_cfg = (bp->port.link_config[0] &
PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ bnx2x_phy_probe(&bp->link_params);
bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
bnx2x_link_settings_requested(bp);
@@ -6539,14 +6384,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
* If connected directly, work with the internal PHY, otherwise, work
* with the external PHY
*/
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+ ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
- bp->mdio.prtad = bp->link_params.phy_addr;
+ bp->mdio.prtad = bp->port.phy_addr;
else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
(ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
bp->mdio.prtad =
- XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
+ XGXS_EXT_PHY_ADDR(ext_phy_config);
val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
@@ -6771,7 +6619,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->mrrs = mrrs;
bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_ring_size = MAX_RX_AVAIL;
bp->rx_csum = 1;
@@ -6982,23 +6829,15 @@ static int bnx2x_mdio_read(struct net_device *netdev, int prtad,
struct bnx2x *bp = netdev_priv(netdev);
u16 value;
int rc;
- u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n",
prtad, devad, addr);
- if (prtad != bp->mdio.prtad) {
- DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
- prtad, bp->mdio.prtad);
- return -EINVAL;
- }
-
/* The HW expects different devad if CL22 is used */
devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad,
- devad, addr, &value);
+ rc = bnx2x_phy_read(&bp->link_params, prtad, devad, addr, &value);
bnx2x_release_phy_lock(bp);
DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc);
@@ -7012,24 +6851,16 @@ static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad,
u16 addr, u16 value)
{
struct bnx2x *bp = netdev_priv(netdev);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
int rc;
DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x,"
" value 0x%x\n", prtad, devad, addr, value);
- if (prtad != bp->mdio.prtad) {
- DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
- prtad, bp->mdio.prtad);
- return -EINVAL;
- }
-
/* The HW expects different devad if CL22 is used */
devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad,
- devad, addr, value);
+ rc = bnx2x_phy_write(&bp->link_params, prtad, devad, addr, value);
bnx2x_release_phy_lock(bp);
return rc;
}
@@ -7259,7 +7090,7 @@ static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp,
*speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
}
-static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+static int bnx2x_check_firmware(struct bnx2x *bp)
{
const struct firmware *firmware = bp->firmware;
struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7370,7 +7201,7 @@ do { \
(u8 *)bp->arr, len); \
} while (0)
-static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+int bnx2x_init_firmware(struct bnx2x *bp)
{
const char *fw_file_name;
struct bnx2x_fw_file_hdr *fw_hdr;
@@ -7381,21 +7212,21 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
else if (CHIP_IS_E1H(bp))
fw_file_name = FW_FILE_NAME_E1H;
else {
- dev_err(dev, "Unsupported chip revision\n");
+ BNX2X_ERR("Unsupported chip revision\n");
return -EINVAL;
}
- dev_info(dev, "Loading %s\n", fw_file_name);
+ BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
- rc = request_firmware(&bp->firmware, fw_file_name, dev);
+ rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
if (rc) {
- dev_err(dev, "Can't load firmware file %s\n", fw_file_name);
+ BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
goto request_firmware_exit;
}
rc = bnx2x_check_firmware(bp);
if (rc) {
- dev_err(dev, "Corrupt firmware file %s\n", fw_file_name);
+ BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
goto request_firmware_exit;
}
@@ -7473,13 +7304,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (rc)
goto init_one_exit;
- /* Set init arrays */
- rc = bnx2x_init_firmware(bp, &pdev->dev);
- if (rc) {
- dev_err(&pdev->dev, "Error loading firmware\n");
- goto init_one_exit;
- }
-
rc = register_netdev(dev);
if (rc) {
dev_err(&pdev->dev, "Cannot register net device\n");
@@ -7530,11 +7354,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
/* Make sure RESET task is not scheduled before continuing */
cancel_delayed_work_sync(&bp->reset_task);
- kfree(bp->init_ops_offsets);
- kfree(bp->init_ops);
- kfree(bp->init_data);
- release_firmware(bp->firmware);
-
if (bp->regview)
iounmap(bp->regview);
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h
index a1f3bf0cd630..6be0d09ad3fd 100644
--- a/drivers/net/bnx2x/bnx2x_reg.h
+++ b/drivers/net/bnx2x/bnx2x_reg.h
@@ -4964,6 +4964,8 @@
#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001
#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SGMII 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_LINK 0x0002
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018
#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3
@@ -5135,28 +5137,35 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR 0x8005
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF 0x8007
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
-#define MDIO_PMA_REG_8727_MISC_CTRL 0x8309
#define MDIO_PMA_REG_8727_TX_CTRL1 0xca02
#define MDIO_PMA_REG_8727_TX_CTRL2 0xca05
#define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808
#define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e
+#define MDIO_PMA_REG_8727_PCS_GP 0xc842
+
+#define MDIO_AN_REG_8727_MISC_CTRL 0x8309
#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
#define MDIO_PMA_REG_8073_XAUI_WA 0xc841
+#define MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL 0xcd08
#define MDIO_PMA_REG_7101_RESET 0xc000
#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
+#define MDIO_PMA_REG_7107_LINK_LED_CNTL 0xc009
#define MDIO_PMA_REG_7101_VER1 0xc026
#define MDIO_PMA_REG_7101_VER2 0xc027
-#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811
-#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c
-#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f
-#define MDIO_PMA_REG_8481_LED3_MASK 0xa832
-#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834
-#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835
-#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b
+#define MDIO_PMA_REG_8481_PMD_SIGNAL 0xa811
+#define MDIO_PMA_REG_8481_LED1_MASK 0xa82c
+#define MDIO_PMA_REG_8481_LED2_MASK 0xa82f
+#define MDIO_PMA_REG_8481_LED3_MASK 0xa832
+#define MDIO_PMA_REG_8481_LED3_BLINK 0xa834
+#define MDIO_PMA_REG_8481_LED5_MASK 0xa838
+#define MDIO_PMA_REG_8481_SIGNAL_MASK 0xa835
+#define MDIO_PMA_REG_8481_LINK_SIGNAL 0xa83b
+#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK 0x800
+#define MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT 11
#define MDIO_WIS_DEVAD 0x2
@@ -5188,6 +5197,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
+#define MDIO_XS_REG_8073_RX_CTRL_PCIE 0x80FA
+
#define MDIO_AN_DEVAD 0x7
/*ieee*/
#define MDIO_AN_REG_CTRL 0x0000
@@ -5210,14 +5221,40 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_CL37_FC_LP 0xffe5
#define MDIO_AN_REG_8073_2_5G 0x8329
+#define MDIO_AN_REG_8073_BAM 0x8350
+#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020
#define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0
+#define MDIO_AN_REG_8481_LEGACY_MII_STATUS 0xffe1
#define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4
+#define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION 0xffe6
#define MDIO_AN_REG_8481_1000T_CTRL 0xffe9
#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5
#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7
+#define MDIO_AN_REG_8481_AUX_CTRL 0xfff8
#define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc
+/* BCM84823 only */
+#define MDIO_CTL_DEVAD 0x1e
+#define MDIO_CTL_REG_84823_MEDIA 0x401a
+#define MDIO_CTL_REG_84823_MEDIA_MAC_MASK 0x0018
+ /* These pins configure the BCM84823 interface to MAC after reset. */
+#define MDIO_CTL_REG_84823_CTRL_MAC_XFI 0x0008
+#define MDIO_CTL_REG_84823_MEDIA_MAC_XAUI_M 0x0010
+ /* These pins configure the BCM84823 interface to Line after reset. */
+#define MDIO_CTL_REG_84823_MEDIA_LINE_MASK 0x0060
+#define MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L 0x0020
+#define MDIO_CTL_REG_84823_MEDIA_LINE_XFI 0x0040
+ /* When this pin is active high during reset, 10GBASE-T core is power
+ * down, When it is active low the 10GBASE-T is power up
+ */
+#define MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN 0x0080
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK 0x0100
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000
+#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100
+#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000
+
+
#define IGU_FUNC_BASE 0x0400
#define IGU_ADDR_MSIX 0x0000
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index c74724461020..efa1403ebf82 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -969,6 +969,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
{
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
+ unsigned long tmp;
int i;
nstats->rx_packets =
@@ -985,10 +986,10 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = estats->mac_discard;
+ tmp = estats->mac_discard;
for_each_queue(bp, i)
- nstats->rx_dropped +=
- le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+ tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+ nstats->rx_dropped = tmp;
nstats->tx_dropped = 0;
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 822f586d72af..0ddf4c66afe2 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2466,6 +2466,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
if (!(dev->flags & IFF_MASTER))
goto out;
+ if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
+ goto out;
+
read_lock(&bond->lock);
slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev),
orig_dev);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index c746b331771d..26bb118c4533 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -362,6 +362,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
goto out;
}
+ if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
+ goto out;
+
if (skb->len < sizeof(struct arp_pkt)) {
pr_debug("Packet is too small to be an ARP\n");
goto out;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2cc4cfc31892..3b16f62d5606 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2797,9 +2797,15 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* so it can wait
*/
bond_for_each_slave(bond, slave, i) {
+ unsigned long trans_start = dev_trans_start(slave->dev);
+
if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies, dev_trans_start(slave->dev) + delta_in_ticks) &&
- time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) {
+ if (time_in_range(jiffies,
+ trans_start - delta_in_ticks,
+ trans_start + delta_in_ticks) &&
+ time_in_range(jiffies,
+ slave->dev->last_rx - delta_in_ticks,
+ slave->dev->last_rx + delta_in_ticks)) {
slave->link = BOND_LINK_UP;
slave->state = BOND_STATE_ACTIVE;
@@ -2827,8 +2833,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* when the source ip is 0, so don't take the link down
* if we don't know our ip yet
*/
- if (time_after_eq(jiffies, dev_trans_start(slave->dev) + 2*delta_in_ticks) ||
- (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) {
+ if (!time_in_range(jiffies,
+ trans_start - delta_in_ticks,
+ trans_start + 2 * delta_in_ticks) ||
+ !time_in_range(jiffies,
+ slave->dev->last_rx - delta_in_ticks,
+ slave->dev->last_rx + 2 * delta_in_ticks)) {
slave->link = BOND_LINK_DOWN;
slave->state = BOND_STATE_BACKUP;
@@ -2883,13 +2893,16 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
{
struct slave *slave;
int i, commit = 0;
+ unsigned long trans_start;
bond_for_each_slave(bond, slave, i) {
slave->new_link = BOND_LINK_NOCHANGE;
if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies, slave_last_rx(bond, slave) +
- delta_in_ticks)) {
+ if (time_in_range(jiffies,
+ slave_last_rx(bond, slave) - delta_in_ticks,
+ slave_last_rx(bond, slave) + delta_in_ticks)) {
+
slave->new_link = BOND_LINK_UP;
commit++;
}
@@ -2902,8 +2915,9 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* active. This avoids bouncing, as the last receive
* times need a full ARP monitor cycle to be updated.
*/
- if (!time_after_eq(jiffies, slave->jiffies +
- 2 * delta_in_ticks))
+ if (time_in_range(jiffies,
+ slave->jiffies - delta_in_ticks,
+ slave->jiffies + 2 * delta_in_ticks))
continue;
/*
@@ -2921,8 +2935,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
*/
if (slave->state == BOND_STATE_BACKUP &&
!bond->current_arp_slave &&
- time_after(jiffies, slave_last_rx(bond, slave) +
- 3 * delta_in_ticks)) {
+ !time_in_range(jiffies,
+ slave_last_rx(bond, slave) - delta_in_ticks,
+ slave_last_rx(bond, slave) + 3 * delta_in_ticks)) {
+
slave->new_link = BOND_LINK_DOWN;
commit++;
}
@@ -2933,11 +2949,15 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* - (more than 2*delta since receive AND
* the bond has an IP address)
*/
+ trans_start = dev_trans_start(slave->dev);
if ((slave->state == BOND_STATE_ACTIVE) &&
- (time_after_eq(jiffies, dev_trans_start(slave->dev) +
- 2 * delta_in_ticks) ||
- (time_after_eq(jiffies, slave_last_rx(bond, slave)
- + 2 * delta_in_ticks)))) {
+ (!time_in_range(jiffies,
+ trans_start - delta_in_ticks,
+ trans_start + 2 * delta_in_ticks) ||
+ !time_in_range(jiffies,
+ slave_last_rx(bond, slave) - delta_in_ticks,
+ slave_last_rx(bond, slave) + 2 * delta_in_ticks))) {
+
slave->new_link = BOND_LINK_DOWN;
commit++;
}
@@ -2956,6 +2976,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
{
struct slave *slave;
int i;
+ unsigned long trans_start;
bond_for_each_slave(bond, slave, i) {
switch (slave->new_link) {
@@ -2963,10 +2984,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
continue;
case BOND_LINK_UP:
+ trans_start = dev_trans_start(slave->dev);
if ((!bond->curr_active_slave &&
- time_before_eq(jiffies,
- dev_trans_start(slave->dev) +
- delta_in_ticks)) ||
+ time_in_range(jiffies,
+ trans_start - delta_in_ticks,
+ trans_start + delta_in_ticks)) ||
bond->curr_active_slave != slave) {
slave->link = BOND_LINK_UP;
bond->current_arp_slave = NULL;
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index f5058ff2b210..2da938734aa0 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -240,13 +240,15 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
static const struct file_operations dbgfs_state_fops = {
.open = dbgfs_open,
.read = dbgfs_state,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations dbgfs_frame_fops = {
.open = dbgfs_open,
.read = dbgfs_frame,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static inline void dev_debugfs_add(struct cfspi *cfspi)
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index b1bdc909090f..312b9c8f4f3b 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -143,12 +143,12 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
if (!np_clock) {
dev_err(&ofdev->dev, "couldn't find clock node\n");
- return -ENODEV;
+ return 0;
}
clockctl = of_iomap(np_clock, 0);
if (!clockctl) {
dev_err(&ofdev->dev, "couldn't map clock registers\n");
- return 0;
+ goto exit_put;
}
/* Determine the MSCAN device index from the physical address */
@@ -233,9 +233,9 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
exit_unmap:
- of_node_put(np_clock);
iounmap(clockctl);
-
+exit_put:
+ of_node_put(np_clock);
return freq;
}
#else /* !CONFIG_PPC_MPC512x */
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 28c88eeec757..32aaadc4734f 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2149,7 +2149,7 @@ end_copy_pkt:
skb->csum = csum_unfold(~csum);
skb->ip_summed = CHECKSUM_COMPLETE;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
return len;
}
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index f01cfdb995de..1950b9a20ecd 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1388,7 +1388,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
++st->rx_cso_good;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
st->vlan_xtract++;
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 599d178df62d..63ebf76d2390 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -314,14 +314,12 @@ static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
return 0;
}
-#if defined(CONFIG_CHELSIO_T1_1G)
static const struct mdio_ops mi1_mdio_ops = {
.init = mi1_mdio_init,
.read = mi1_mdio_read,
.write = mi1_mdio_write,
.mode_support = MDIO_SUPPORTS_C22
};
-#endif
#endif
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 09610323a948..2ab6a7c4ffc1 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -1022,7 +1022,7 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev)
if (blks > cp->ethdev->ctx_tbl_len)
return -ENOMEM;
- cp->ctx_arr = kzalloc(blks * sizeof(struct cnic_ctx), GFP_KERNEL);
+ cp->ctx_arr = kcalloc(blks, sizeof(struct cnic_ctx), GFP_KERNEL);
if (cp->ctx_arr == NULL)
return -ENOMEM;
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index e1f6156b3710..fec939f8f65f 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -38,7 +38,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
#include <asm/atomic.h>
MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
@@ -108,7 +108,7 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_RX_INT_CLEAR 0x019c
#define CPMAC_MAC_INT_ENABLE 0x01a8
#define CPMAC_MAC_INT_CLEAR 0x01ac
-#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4)
+#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4)
#define CPMAC_MAC_ADDR_MID 0x01d0
#define CPMAC_MAC_ADDR_HI 0x01d4
#define CPMAC_MAC_HASH_LO 0x01d8
@@ -227,7 +227,7 @@ static void cpmac_dump_regs(struct net_device *dev)
for (i = 0; i < CPMAC_REG_END; i += 4) {
if (i % 16 == 0) {
if (i)
- printk("\n");
+ pr_cont("\n");
printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
priv->regs + i);
}
@@ -262,7 +262,7 @@ static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
for (i = 0; i < skb->len; i++) {
if (i % 16 == 0) {
if (i)
- printk("\n");
+ pr_cont("\n");
printk(KERN_DEBUG "%s: data[%p]:", dev->name,
skb->data + i);
}
@@ -391,7 +391,7 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
if (likely(skb)) {
skb_put(desc->skb, desc->datalen);
desc->skb->protocol = eth_type_trans(desc->skb, priv->dev);
- desc->skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(desc->skb);
priv->dev->stats.rx_packets++;
priv->dev->stats.rx_bytes += desc->datalen;
result = desc->skb;
@@ -506,7 +506,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
"restart rx from a descriptor that's "
"not free: %p\n",
priv->dev->name, restart);
- goto fatal_error;
+ goto fatal_error;
}
cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping);
@@ -873,7 +873,8 @@ static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
-static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+static void cpmac_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
{
struct cpmac_priv *priv = netdev_priv(dev);
@@ -888,7 +889,8 @@ static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam
ring->tx_pending = 1;
}
-static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+static int cpmac_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
{
struct cpmac_priv *priv = netdev_priv(dev);
@@ -1012,8 +1014,8 @@ static int cpmac_open(struct net_device *dev)
priv->rx_head->prev->hw_next = (u32)0;
- if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED,
- dev->name, dev))) {
+ res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev);
+ if (res) {
if (netif_msg_drv(priv))
printk(KERN_ERR "%s: failed to obtain irq\n",
dev->name);
@@ -1133,7 +1135,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
}
if (phy_id == PHY_MAX_ADDR) {
- dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n");
+ dev_err(&pdev->dev, "no PHY present, falling back "
+ "to switch on MDIO bus 0\n");
strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1169,9 +1172,10 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr));
- snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+ snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
+ mdio_bus_id, phy_id);
- priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+ priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
@@ -1182,7 +1186,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
goto fail;
}
- if ((rc = register_netdev(dev))) {
+ rc = register_netdev(dev);
+ if (rc) {
printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
dev->name);
goto fail;
@@ -1248,11 +1253,13 @@ int __devinit cpmac_init(void)
cpmac_mii->reset(cpmac_mii);
- for (i = 0; i < 300; i++)
- if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE)))
+ for (i = 0; i < 300; i++) {
+ mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE);
+ if (mask)
break;
else
msleep(10);
+ }
mask &= 0x7fffffff;
if (mask & (mask - 1)) {
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index ad19585d960b..1ecf53dafe06 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1286,7 +1286,7 @@ irq_err:
/*
* Release resources when all the ports and offloading have been stopped.
*/
-static void cxgb_down(struct adapter *adapter)
+static void cxgb_down(struct adapter *adapter, int on_wq)
{
t3_sge_stop(adapter);
spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */
@@ -1296,7 +1296,8 @@ static void cxgb_down(struct adapter *adapter)
free_irq_resources(adapter);
quiesce_rx(adapter);
t3_sge_stop(adapter);
- flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
+ if (!on_wq)
+ flush_workqueue(cxgb3_wq);/* wait for external IRQ handler */
}
static void schedule_chk_task(struct adapter *adap)
@@ -1374,7 +1375,7 @@ static int offload_close(struct t3cdev *tdev)
clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map);
if (!adapter->open_device_map)
- cxgb_down(adapter);
+ cxgb_down(adapter, 0);
cxgb3_offload_deactivate(adapter);
return 0;
@@ -1409,7 +1410,7 @@ static int cxgb_open(struct net_device *dev)
return 0;
}
-static int cxgb_close(struct net_device *dev)
+static int __cxgb_close(struct net_device *dev, int on_wq)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
@@ -1436,12 +1437,17 @@ static int cxgb_close(struct net_device *dev)
cancel_delayed_work_sync(&adapter->adap_check_task);
if (!adapter->open_device_map)
- cxgb_down(adapter);
+ cxgb_down(adapter, on_wq);
cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_DOWN, pi->port_id);
return 0;
}
+static int cxgb_close(struct net_device *dev)
+{
+ return __cxgb_close(dev, 0);
+}
+
static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
{
struct port_info *pi = netdev_priv(dev);
@@ -2862,7 +2868,7 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
spin_unlock(&adapter->work_lock);
}
-static int t3_adapter_error(struct adapter *adapter, int reset)
+static int t3_adapter_error(struct adapter *adapter, int reset, int on_wq)
{
int i, ret = 0;
@@ -2877,7 +2883,7 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
struct net_device *netdev = adapter->port[i];
if (netif_running(netdev))
- cxgb_close(netdev);
+ __cxgb_close(netdev, on_wq);
}
/* Stop SGE timers */
@@ -2948,7 +2954,7 @@ static void fatal_error_task(struct work_struct *work)
int err = 0;
rtnl_lock();
- err = t3_adapter_error(adapter, 1);
+ err = t3_adapter_error(adapter, 1, 1);
if (!err)
err = t3_reenable_adapter(adapter);
if (!err)
@@ -2998,7 +3004,7 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
- ret = t3_adapter_error(adapter, 0);
+ ret = t3_adapter_error(adapter, 0, 0);
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index cb42353c9fdd..6990f6c65221 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1997,6 +1997,10 @@
#define A_PL_RST 0x6f0
+#define S_FATALPERREN 4
+#define V_FATALPERREN(x) ((x) << S_FATALPERREN)
+#define F_FATALPERREN V_FATALPERREN(1U)
+
#define S_CRSTWRM 1
#define V_CRSTWRM(x) ((x) << S_CRSTWRM)
#define F_CRSTWRM V_CRSTWRM(1U)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 8ff96c6f6de5..c5a142bea5e9 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2022,7 +2022,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
if (unlikely(p->vlan_valid)) {
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 427c451be1a7..421d5589cecd 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1408,6 +1408,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
fatal++;
CH_ALERT(adapter, "%s (0x%x)\n",
acts->msg, status & acts->mask);
+ status &= ~acts->mask;
} else if (acts->msg)
CH_WARN(adapter, "%s (0x%x)\n",
acts->msg, status & acts->mask);
@@ -1843,11 +1844,10 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
t3_os_link_fault_handler(adap, idx);
}
- t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
-
if (cause & XGM_INTR_FATAL)
t3_fatal_err(adap);
+ t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
return cause != 0;
}
@@ -3569,6 +3569,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
t3_write_reg(adapter, A_PM1_TX_MODE, 0);
chan_init_hw(adapter, adapter->params.chan_map);
t3_sge_init(adapter, &adapter->params.sge);
+ t3_set_reg_field(adapter, A_PL_RST, 0, F_FATALPERREN);
t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
@@ -3682,7 +3683,7 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7,
mc7->name = name;
mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
- mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
+ mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
mc7->width = G_WIDTH(cfg);
}
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 6e562c0dad7d..3ece9f5069fa 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -463,6 +463,8 @@ struct sge {
u8 counter_val[SGE_NCOUNTERS];
unsigned int starve_thres;
u8 idma_state[2];
+ unsigned int egr_start;
+ unsigned int ingr_start;
void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */
struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
DECLARE_BITMAP(starving_fl, MAX_EGRQ);
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index c327527fbbc8..e0fe7f7a0bdf 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -175,16 +175,26 @@ enum {
static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0xa000, 0), /* PE10K */
- CH_DEVICE(0x4001, 0),
- CH_DEVICE(0x4002, 0),
- CH_DEVICE(0x4003, 0),
- CH_DEVICE(0x4004, 0),
- CH_DEVICE(0x4005, 0),
- CH_DEVICE(0x4006, 0),
- CH_DEVICE(0x4007, 0),
- CH_DEVICE(0x4008, 0),
- CH_DEVICE(0x4009, 0),
- CH_DEVICE(0x400a, 0),
+ CH_DEVICE(0x4001, -1),
+ CH_DEVICE(0x4002, -1),
+ CH_DEVICE(0x4003, -1),
+ CH_DEVICE(0x4004, -1),
+ CH_DEVICE(0x4005, -1),
+ CH_DEVICE(0x4006, -1),
+ CH_DEVICE(0x4007, -1),
+ CH_DEVICE(0x4008, -1),
+ CH_DEVICE(0x4009, -1),
+ CH_DEVICE(0x400a, -1),
+ CH_DEVICE(0x4401, 4),
+ CH_DEVICE(0x4402, 4),
+ CH_DEVICE(0x4403, 4),
+ CH_DEVICE(0x4404, 4),
+ CH_DEVICE(0x4405, 4),
+ CH_DEVICE(0x4406, 4),
+ CH_DEVICE(0x4407, 4),
+ CH_DEVICE(0x4408, 4),
+ CH_DEVICE(0x4409, 4),
+ CH_DEVICE(0x440a, 4),
{ 0, }
};
@@ -423,10 +433,11 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
const struct cpl_sge_egr_update *p = (void *)rsp;
unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
- struct sge_txq *txq = q->adap->sge.egr_map[qid];
+ struct sge_txq *txq;
+ txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start];
txq->restarts++;
- if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) {
+ if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) {
struct sge_eth_txq *eq;
eq = container_of(txq, struct sge_eth_txq, q);
@@ -658,6 +669,15 @@ static int setup_rss(struct adapter *adap)
}
/*
+ * Return the channel of the ingress queue with the given qid.
+ */
+static unsigned int rxq_to_chan(const struct sge *p, unsigned int qid)
+{
+ qid -= p->ingr_start;
+ return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan;
+}
+
+/*
* Wait until all NAPI handlers are descheduled.
*/
static void quiesce_rx(struct adapter *adap)
@@ -1671,27 +1691,41 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
return 0;
}
-/*
- * Translate a physical EEPROM address to virtual. The first 1K is accessed
- * through virtual addresses starting at 31K, the rest is accessed through
- * virtual addresses starting at 0. This mapping is correct only for PF0.
+/**
+ * eeprom_ptov - translate a physical EEPROM address to virtual
+ * @phys_addr: the physical EEPROM address
+ * @fn: the PCI function number
+ * @sz: size of function-specific area
+ *
+ * Translate a physical EEPROM address to virtual. The first 1K is
+ * accessed through virtual addresses starting at 31K, the rest is
+ * accessed through virtual addresses starting at 0.
+ *
+ * The mapping is as follows:
+ * [0..1K) -> [31K..32K)
+ * [1K..1K+A) -> [31K-A..31K)
+ * [1K+A..ES) -> [0..ES-A-1K)
+ *
+ * where A = @fn * @sz, and ES = EEPROM size.
*/
-static int eeprom_ptov(unsigned int phys_addr)
+static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
{
+ fn *= sz;
if (phys_addr < 1024)
return phys_addr + (31 << 10);
+ if (phys_addr < 1024 + fn)
+ return 31744 - fn + phys_addr - 1024;
if (phys_addr < EEPROMSIZE)
- return phys_addr - 1024;
+ return phys_addr - 1024 - fn;
return -EINVAL;
}
/*
* The next two routines implement eeprom read/write from physical addresses.
- * The physical->virtual translation is correct only for PF0.
*/
static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
{
- int vaddr = eeprom_ptov(phys_addr);
+ int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE);
if (vaddr >= 0)
vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
@@ -1700,7 +1734,7 @@ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
{
- int vaddr = eeprom_ptov(phys_addr);
+ int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE);
if (vaddr >= 0)
vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);
@@ -1743,6 +1777,14 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
aligned_offset = eeprom->offset & ~3;
aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3;
+ if (adapter->fn > 0) {
+ u32 start = 1024 + adapter->fn * EEPROMPFSIZE;
+
+ if (aligned_offset < start ||
+ aligned_offset + aligned_len > start + EEPROMPFSIZE)
+ return -EPERM;
+ }
+
if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
/*
* RMW possibly needed for first or last words.
@@ -2026,6 +2068,7 @@ static const struct file_operations mem_debugfs_fops = {
.owner = THIS_MODULE,
.open = mem_open,
.read = mem_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void __devinit add_debugfs_mem(struct adapter *adap, const char *name,
@@ -2304,7 +2347,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
req->peer_port = htons(0);
req->local_ip = sip;
req->peer_ip = htonl(0);
- chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+ chan = rxq_to_chan(&adap->sge, queue);
req->opt0 = cpu_to_be64(TX_CHAN(chan));
req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
@@ -2346,7 +2389,7 @@ int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
req->peer_ip_hi = cpu_to_be64(0);
req->peer_ip_lo = cpu_to_be64(0);
- chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+ chan = rxq_to_chan(&adap->sge, queue);
req->opt0 = cpu_to_be64(TX_CHAN(chan));
req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
@@ -3061,12 +3104,16 @@ static int adap_init0(struct adapter *adap)
params[2] = FW_PARAM_PFVF(L2T_END);
params[3] = FW_PARAM_PFVF(FILTER_START);
params[4] = FW_PARAM_PFVF(FILTER_END);
- ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val);
+ params[5] = FW_PARAM_PFVF(IQFLINT_START);
+ params[6] = FW_PARAM_PFVF(EQ_START);
+ ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val);
if (ret < 0)
goto bye;
port_vec = val[0];
adap->tids.ftid_base = val[3];
adap->tids.nftids = val[4] - val[3] + 1;
+ adap->sge.ingr_start = val[5];
+ adap->sge.egr_start = val[6];
if (c.ofldcaps) {
/* query offload-related parameters */
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
index bf38cfc57565..9967f3debce7 100644
--- a/drivers/net/cxgb4/sge.c
+++ b/drivers/net/cxgb4/sge.c
@@ -557,7 +557,8 @@ out: cred = q->avail - cred;
if (unlikely(fl_starving(q))) {
smp_wmb();
- set_bit(q->cntxt_id, adap->sge.starving_fl);
+ set_bit(q->cntxt_id - adap->sge.egr_start,
+ adap->sge.starving_fl);
}
return cred;
@@ -974,7 +975,7 @@ out_free: dev_kfree_skb(skb);
}
cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) |
- TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0));
+ TXPKT_INTF(pi->tx_chan) | TXPKT_PF(adap->fn));
cpl->pack = htons(0);
cpl->len = htons(skb->len);
cpl->ctrl1 = cpu_to_be64(cntrl);
@@ -1213,7 +1214,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q)
{
q->mapping_err++;
q->q.stops++;
- set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr);
+ set_bit(q->q.cntxt_id - q->adap->sge.egr_start,
+ q->adap->sge.txq_maperr);
}
/**
@@ -1603,7 +1605,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
rxq->stats.rx_cso++;
}
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(pkt->vlan_ex)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -1835,6 +1837,7 @@ static unsigned int process_intrq(struct adapter *adap)
if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
unsigned int qid = ntohl(rc->pldbuflen_qid);
+ qid -= adap->sge.ingr_start;
napi_schedule(&adap->sge.ingr_map[qid]->napi);
}
@@ -2050,14 +2053,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
/* set offset to -1 to distinguish ingress queues without FL */
iq->offset = fl ? 0 : -1;
- adap->sge.ingr_map[iq->cntxt_id] = iq;
+ adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq;
if (fl) {
fl->cntxt_id = ntohs(c.fl0id);
fl->avail = fl->pend_cred = 0;
fl->pidx = fl->cidx = 0;
fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
- adap->sge.egr_map[fl->cntxt_id] = fl;
+ adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl;
refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
}
return 0;
@@ -2087,7 +2090,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
q->stops = q->restarts = 0;
q->stat = (void *)&q->desc[q->size];
q->cntxt_id = id;
- adap->sge.egr_map[id] = q;
+ adap->sge.egr_map[id - adap->sge.egr_start] = q;
}
int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
@@ -2259,7 +2262,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
{
unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
- adap->sge.ingr_map[rq->cntxt_id] = NULL;
+ adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL;
t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP,
rq->cntxt_id, fl_id, 0xffff);
dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h
index 10a055565776..c26b455f37de 100644
--- a/drivers/net/cxgb4/t4_hw.h
+++ b/drivers/net/cxgb4/t4_hw.h
@@ -42,6 +42,7 @@ enum {
MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */
EEPROMSIZE = 17408, /* Serial EEPROM physical size */
EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */
+ EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */
RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */
TCB_SIZE = 128, /* TCB size */
NMTUS = 16, /* size of MTU table */
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
index 0969f2fbc1b0..940584a8a640 100644
--- a/drivers/net/cxgb4/t4fw_api.h
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -487,6 +487,11 @@ enum fw_params_param_pfvf {
FW_PARAMS_PARAM_PFVF_CPMASK = 0x25,
FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26,
FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27,
+ FW_PARAMS_PARAM_PFVF_CONM_MAP = 0x28,
+ FW_PARAMS_PARAM_PFVF_IQFLINT_START = 0x29,
+ FW_PARAMS_PARAM_PFVF_IQFLINT_END = 0x2A,
+ FW_PARAMS_PARAM_PFVF_EQ_START = 0x2B,
+ FW_PARAMS_PARAM_PFVF_EQ_END = 0x2C,
};
/*
diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
index eb5a1c9cb2d3..f10864ddafbe 100644
--- a/drivers/net/cxgb4vf/sge.c
+++ b/drivers/net/cxgb4vf/sge.c
@@ -1520,7 +1520,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
__skb_pull(skb, PKTSHIFT);
skb->protocol = eth_type_trans(skb, rspq->netdev);
skb_record_rx_queue(skb, rspq->idx);
- skb->dev->last_rx = jiffies; /* XXX removed 2.6.29 */
pi = netdev_priv(skb->dev);
rxq->stats.pkts++;
@@ -1535,7 +1534,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
}
rxq->stats.rx_cso++;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(pkt->vlan_ex)) {
struct vlan_group *grp = pi->vlan_grp;
diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c
new file mode 100644
index 000000000000..ab7ecd762e77
--- /dev/null
+++ b/drivers/net/davinci_cpdma.c
@@ -0,0 +1,837 @@
+/*
+ * Texas Instruments CPDMA Driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include "davinci_cpdma.h"
+
+/* DMA Registers */
+#define CPDMA_TXIDVER 0x00
+#define CPDMA_TXCONTROL 0x04
+#define CPDMA_TXTEARDOWN 0x08
+#define CPDMA_RXIDVER 0x10
+#define CPDMA_RXCONTROL 0x14
+#define CPDMA_SOFTRESET 0x1c
+#define CPDMA_RXTEARDOWN 0x18
+#define CPDMA_TXINTSTATRAW 0x80
+#define CPDMA_TXINTSTATMASKED 0x84
+#define CPDMA_TXINTMASKSET 0x88
+#define CPDMA_TXINTMASKCLEAR 0x8c
+#define CPDMA_MACINVECTOR 0x90
+#define CPDMA_MACEOIVECTOR 0x94
+#define CPDMA_RXINTSTATRAW 0xa0
+#define CPDMA_RXINTSTATMASKED 0xa4
+#define CPDMA_RXINTMASKSET 0xa8
+#define CPDMA_RXINTMASKCLEAR 0xac
+#define CPDMA_DMAINTSTATRAW 0xb0
+#define CPDMA_DMAINTSTATMASKED 0xb4
+#define CPDMA_DMAINTMASKSET 0xb8
+#define CPDMA_DMAINTMASKCLEAR 0xbc
+#define CPDMA_DMAINT_HOSTERR BIT(1)
+
+/* the following exist only if has_ext_regs is set */
+#define CPDMA_DMACONTROL 0x20
+#define CPDMA_DMASTATUS 0x24
+#define CPDMA_RXBUFFOFS 0x28
+#define CPDMA_EM_CONTROL 0x2c
+
+/* Descriptor mode bits */
+#define CPDMA_DESC_SOP BIT(31)
+#define CPDMA_DESC_EOP BIT(30)
+#define CPDMA_DESC_OWNER BIT(29)
+#define CPDMA_DESC_EOQ BIT(28)
+#define CPDMA_DESC_TD_COMPLETE BIT(27)
+#define CPDMA_DESC_PASS_CRC BIT(26)
+
+#define CPDMA_TEARDOWN_VALUE 0xfffffffc
+
+struct cpdma_desc {
+ /* hardware fields */
+ u32 hw_next;
+ u32 hw_buffer;
+ u32 hw_len;
+ u32 hw_mode;
+ /* software fields */
+ void *sw_token;
+ u32 sw_buffer;
+ u32 sw_len;
+};
+
+struct cpdma_desc_pool {
+ u32 phys;
+ void __iomem *iomap; /* ioremap map */
+ void *cpumap; /* dma_alloc map */
+ int desc_size, mem_size;
+ int num_desc, used_desc;
+ unsigned long *bitmap;
+ struct device *dev;
+ spinlock_t lock;
+};
+
+enum cpdma_state {
+ CPDMA_STATE_IDLE,
+ CPDMA_STATE_ACTIVE,
+ CPDMA_STATE_TEARDOWN,
+};
+
+struct cpdma_ctlr {
+ enum cpdma_state state;
+ struct cpdma_params params;
+ struct device *dev;
+ struct cpdma_desc_pool *pool;
+ spinlock_t lock;
+ struct cpdma_chan *channels[2 * CPDMA_MAX_CHANNELS];
+};
+
+struct cpdma_chan {
+ enum cpdma_state state;
+ struct cpdma_ctlr *ctlr;
+ int chan_num;
+ spinlock_t lock;
+ struct cpdma_desc __iomem *head, *tail;
+ int count;
+ void __iomem *hdp, *cp, *rxfree;
+ u32 mask;
+ cpdma_handler_fn handler;
+ enum dma_data_direction dir;
+ struct cpdma_chan_stats stats;
+ /* offsets into dmaregs */
+ int int_set, int_clear, td;
+};
+
+/* The following make access to common cpdma_ctlr params more readable */
+#define dmaregs params.dmaregs
+#define num_chan params.num_chan
+
+/* various accessors */
+#define dma_reg_read(ctlr, ofs) __raw_readl((ctlr)->dmaregs + (ofs))
+#define chan_read(chan, fld) __raw_readl((chan)->fld)
+#define desc_read(desc, fld) __raw_readl(&(desc)->fld)
+#define dma_reg_write(ctlr, ofs, v) __raw_writel(v, (ctlr)->dmaregs + (ofs))
+#define chan_write(chan, fld, v) __raw_writel(v, (chan)->fld)
+#define desc_write(desc, fld, v) __raw_writel((u32)(v), &(desc)->fld)
+
+/*
+ * Utility constructs for a cpdma descriptor pool. Some devices (e.g. davinci
+ * emac) have dedicated on-chip memory for these descriptors. Some other
+ * devices (e.g. cpsw switches) use plain old memory. Descriptor pools
+ * abstract out these details
+ */
+static struct cpdma_desc_pool *
+cpdma_desc_pool_create(struct device *dev, u32 phys, int size, int align)
+{
+ int bitmap_size;
+ struct cpdma_desc_pool *pool;
+
+ pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+ if (!pool)
+ return NULL;
+
+ spin_lock_init(&pool->lock);
+
+ pool->dev = dev;
+ pool->mem_size = size;
+ pool->desc_size = ALIGN(sizeof(struct cpdma_desc), align);
+ pool->num_desc = size / pool->desc_size;
+
+ bitmap_size = (pool->num_desc / BITS_PER_LONG) * sizeof(long);
+ pool->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!pool->bitmap)
+ goto fail;
+
+ if (phys) {
+ pool->phys = phys;
+ pool->iomap = ioremap(phys, size);
+ } else {
+ pool->cpumap = dma_alloc_coherent(dev, size, &pool->phys,
+ GFP_KERNEL);
+ pool->iomap = (void __force __iomem *)pool->cpumap;
+ }
+
+ if (pool->iomap)
+ return pool;
+
+fail:
+ kfree(pool->bitmap);
+ kfree(pool);
+ return NULL;
+}
+
+static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
+{
+ unsigned long flags;
+
+ if (!pool)
+ return;
+
+ spin_lock_irqsave(&pool->lock, flags);
+ WARN_ON(pool->used_desc);
+ kfree(pool->bitmap);
+ if (pool->cpumap) {
+ dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
+ pool->phys);
+ } else {
+ iounmap(pool->iomap);
+ }
+ spin_unlock_irqrestore(&pool->lock, flags);
+ kfree(pool);
+}
+
+static inline dma_addr_t desc_phys(struct cpdma_desc_pool *pool,
+ struct cpdma_desc __iomem *desc)
+{
+ if (!desc)
+ return 0;
+ return pool->phys + (__force dma_addr_t)desc -
+ (__force dma_addr_t)pool->iomap;
+}
+
+static inline struct cpdma_desc __iomem *
+desc_from_phys(struct cpdma_desc_pool *pool, dma_addr_t dma)
+{
+ return dma ? pool->iomap + dma - pool->phys : NULL;
+}
+
+static struct cpdma_desc __iomem *
+cpdma_desc_alloc(struct cpdma_desc_pool *pool, int num_desc)
+{
+ unsigned long flags;
+ int index;
+ struct cpdma_desc __iomem *desc = NULL;
+
+ spin_lock_irqsave(&pool->lock, flags);
+
+ index = bitmap_find_next_zero_area(pool->bitmap, pool->num_desc, 0,
+ num_desc, 0);
+ if (index < pool->num_desc) {
+ bitmap_set(pool->bitmap, index, num_desc);
+ desc = pool->iomap + pool->desc_size * index;
+ pool->used_desc++;
+ }
+
+ spin_unlock_irqrestore(&pool->lock, flags);
+ return desc;
+}
+
+static void cpdma_desc_free(struct cpdma_desc_pool *pool,
+ struct cpdma_desc __iomem *desc, int num_desc)
+{
+ unsigned long flags, index;
+
+ index = ((unsigned long)desc - (unsigned long)pool->iomap) /
+ pool->desc_size;
+ spin_lock_irqsave(&pool->lock, flags);
+ bitmap_clear(pool->bitmap, index, num_desc);
+ pool->used_desc--;
+ spin_unlock_irqrestore(&pool->lock, flags);
+}
+
+struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params)
+{
+ struct cpdma_ctlr *ctlr;
+
+ ctlr = kzalloc(sizeof(*ctlr), GFP_KERNEL);
+ if (!ctlr)
+ return NULL;
+
+ ctlr->state = CPDMA_STATE_IDLE;
+ ctlr->params = *params;
+ ctlr->dev = params->dev;
+ spin_lock_init(&ctlr->lock);
+
+ ctlr->pool = cpdma_desc_pool_create(ctlr->dev,
+ ctlr->params.desc_mem_phys,
+ ctlr->params.desc_mem_size,
+ ctlr->params.desc_align);
+ if (!ctlr->pool) {
+ kfree(ctlr);
+ return NULL;
+ }
+
+ if (WARN_ON(ctlr->num_chan > CPDMA_MAX_CHANNELS))
+ ctlr->num_chan = CPDMA_MAX_CHANNELS;
+ return ctlr;
+}
+
+int cpdma_ctlr_start(struct cpdma_ctlr *ctlr)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ if (ctlr->state != CPDMA_STATE_IDLE) {
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return -EBUSY;
+ }
+
+ if (ctlr->params.has_soft_reset) {
+ unsigned long timeout = jiffies + HZ/10;
+
+ dma_reg_write(ctlr, CPDMA_SOFTRESET, 1);
+ while (time_before(jiffies, timeout)) {
+ if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0)
+ break;
+ }
+ WARN_ON(!time_before(jiffies, timeout));
+ }
+
+ for (i = 0; i < ctlr->num_chan; i++) {
+ __raw_writel(0, ctlr->params.txhdp + 4 * i);
+ __raw_writel(0, ctlr->params.rxhdp + 4 * i);
+ __raw_writel(0, ctlr->params.txcp + 4 * i);
+ __raw_writel(0, ctlr->params.rxcp + 4 * i);
+ }
+
+ dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff);
+ dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff);
+
+ dma_reg_write(ctlr, CPDMA_TXCONTROL, 1);
+ dma_reg_write(ctlr, CPDMA_RXCONTROL, 1);
+
+ ctlr->state = CPDMA_STATE_ACTIVE;
+
+ for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) {
+ if (ctlr->channels[i])
+ cpdma_chan_start(ctlr->channels[i]);
+ }
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return 0;
+}
+
+int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ if (ctlr->state != CPDMA_STATE_ACTIVE) {
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return -EINVAL;
+ }
+
+ ctlr->state = CPDMA_STATE_TEARDOWN;
+
+ for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) {
+ if (ctlr->channels[i])
+ cpdma_chan_stop(ctlr->channels[i]);
+ }
+
+ dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff);
+ dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff);
+
+ dma_reg_write(ctlr, CPDMA_TXCONTROL, 0);
+ dma_reg_write(ctlr, CPDMA_RXCONTROL, 0);
+
+ ctlr->state = CPDMA_STATE_IDLE;
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return 0;
+}
+
+int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
+{
+ unsigned long flags;
+ int ret = 0, i;
+
+ if (!ctlr)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ if (ctlr->state != CPDMA_STATE_IDLE)
+ cpdma_ctlr_stop(ctlr);
+
+ for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) {
+ if (ctlr->channels[i])
+ cpdma_chan_destroy(ctlr->channels[i]);
+ }
+
+ cpdma_desc_pool_destroy(ctlr->pool);
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ kfree(ctlr);
+ return ret;
+}
+
+int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable)
+{
+ unsigned long flags;
+ int i, reg;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ if (ctlr->state != CPDMA_STATE_ACTIVE) {
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return -EINVAL;
+ }
+
+ reg = enable ? CPDMA_DMAINTMASKSET : CPDMA_DMAINTMASKCLEAR;
+ dma_reg_write(ctlr, reg, CPDMA_DMAINT_HOSTERR);
+
+ for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) {
+ if (ctlr->channels[i])
+ cpdma_chan_int_ctrl(ctlr->channels[i], enable);
+ }
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return 0;
+}
+
+void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr)
+{
+ dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, 0);
+}
+
+struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,
+ cpdma_handler_fn handler)
+{
+ struct cpdma_chan *chan;
+ int ret, offset = (chan_num % CPDMA_MAX_CHANNELS) * 4;
+ unsigned long flags;
+
+ if (__chan_linear(chan_num) >= ctlr->num_chan)
+ return NULL;
+
+ ret = -ENOMEM;
+ chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+ if (!chan)
+ goto err_chan_alloc;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ ret = -EBUSY;
+ if (ctlr->channels[chan_num])
+ goto err_chan_busy;
+
+ chan->ctlr = ctlr;
+ chan->state = CPDMA_STATE_IDLE;
+ chan->chan_num = chan_num;
+ chan->handler = handler;
+
+ if (is_rx_chan(chan)) {
+ chan->hdp = ctlr->params.rxhdp + offset;
+ chan->cp = ctlr->params.rxcp + offset;
+ chan->rxfree = ctlr->params.rxfree + offset;
+ chan->int_set = CPDMA_RXINTMASKSET;
+ chan->int_clear = CPDMA_RXINTMASKCLEAR;
+ chan->td = CPDMA_RXTEARDOWN;
+ chan->dir = DMA_FROM_DEVICE;
+ } else {
+ chan->hdp = ctlr->params.txhdp + offset;
+ chan->cp = ctlr->params.txcp + offset;
+ chan->int_set = CPDMA_TXINTMASKSET;
+ chan->int_clear = CPDMA_TXINTMASKCLEAR;
+ chan->td = CPDMA_TXTEARDOWN;
+ chan->dir = DMA_TO_DEVICE;
+ }
+ chan->mask = BIT(chan_linear(chan));
+
+ spin_lock_init(&chan->lock);
+
+ ctlr->channels[chan_num] = chan;
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return chan;
+
+err_chan_busy:
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ kfree(chan);
+err_chan_alloc:
+ return ERR_PTR(ret);
+}
+
+int cpdma_chan_destroy(struct cpdma_chan *chan)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ unsigned long flags;
+
+ if (!chan)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+ if (chan->state != CPDMA_STATE_IDLE)
+ cpdma_chan_stop(chan);
+ ctlr->channels[chan->chan_num] = NULL;
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ kfree(chan);
+ return 0;
+}
+
+int cpdma_chan_get_stats(struct cpdma_chan *chan,
+ struct cpdma_chan_stats *stats)
+{
+ unsigned long flags;
+ if (!chan)
+ return -EINVAL;
+ spin_lock_irqsave(&chan->lock, flags);
+ memcpy(stats, &chan->stats, sizeof(*stats));
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return 0;
+}
+
+static void __cpdma_chan_submit(struct cpdma_chan *chan,
+ struct cpdma_desc __iomem *desc)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc __iomem *prev = chan->tail;
+ struct cpdma_desc_pool *pool = ctlr->pool;
+ dma_addr_t desc_dma;
+
+ desc_dma = desc_phys(pool, desc);
+
+ /* simple case - idle channel */
+ if (!chan->head) {
+ chan->stats.head_enqueue++;
+ chan->head = desc;
+ chan->tail = desc;
+ if (chan->state == CPDMA_STATE_ACTIVE)
+ chan_write(chan, hdp, desc_dma);
+ return;
+ }
+
+ /* first chain the descriptor at the tail of the list */
+ desc_write(prev, hw_next, desc_dma);
+ chan->tail = desc;
+ chan->stats.tail_enqueue++;
+
+ /* next check if EOQ has been triggered already */
+ if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ &&
+ chan->state == CPDMA_STATE_ACTIVE) {
+ chan_write(chan, hdp, desc_dma);
+ chan->stats.misqueued++;
+ }
+}
+
+int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
+ int len, gfp_t gfp_mask)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc __iomem *desc;
+ dma_addr_t buffer;
+ unsigned long flags;
+ u32 mode;
+ int ret = 0;
+
+ spin_lock_irqsave(&chan->lock, flags);
+
+ if (chan->state == CPDMA_STATE_TEARDOWN) {
+ ret = -EINVAL;
+ goto unlock_ret;
+ }
+
+ desc = cpdma_desc_alloc(ctlr->pool, 1);
+ if (!desc) {
+ chan->stats.desc_alloc_fail++;
+ ret = -ENOMEM;
+ goto unlock_ret;
+ }
+
+ if (len < ctlr->params.min_packet_size) {
+ len = ctlr->params.min_packet_size;
+ chan->stats.runt_transmit_buff++;
+ }
+
+ buffer = dma_map_single(ctlr->dev, data, len, chan->dir);
+ mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
+
+ desc_write(desc, hw_next, 0);
+ desc_write(desc, hw_buffer, buffer);
+ desc_write(desc, hw_len, len);
+ desc_write(desc, hw_mode, mode | len);
+ desc_write(desc, sw_token, token);
+ desc_write(desc, sw_buffer, buffer);
+ desc_write(desc, sw_len, len);
+
+ __cpdma_chan_submit(chan, desc);
+
+ if (chan->state == CPDMA_STATE_ACTIVE && chan->rxfree)
+ chan_write(chan, rxfree, 1);
+
+ chan->count++;
+
+unlock_ret:
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return ret;
+}
+
+static void __cpdma_chan_free(struct cpdma_chan *chan,
+ struct cpdma_desc __iomem *desc,
+ int outlen, int status)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc_pool *pool = ctlr->pool;
+ dma_addr_t buff_dma;
+ int origlen;
+ void *token;
+
+ token = (void *)desc_read(desc, sw_token);
+ buff_dma = desc_read(desc, sw_buffer);
+ origlen = desc_read(desc, sw_len);
+
+ dma_unmap_single(ctlr->dev, buff_dma, origlen, chan->dir);
+ cpdma_desc_free(pool, desc, 1);
+ (*chan->handler)(token, outlen, status);
+}
+
+static int __cpdma_chan_process(struct cpdma_chan *chan)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc __iomem *desc;
+ int status, outlen;
+ struct cpdma_desc_pool *pool = ctlr->pool;
+ dma_addr_t desc_dma;
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->lock, flags);
+
+ desc = chan->head;
+ if (!desc) {
+ chan->stats.empty_dequeue++;
+ status = -ENOENT;
+ goto unlock_ret;
+ }
+ desc_dma = desc_phys(pool, desc);
+
+ status = __raw_readl(&desc->hw_mode);
+ outlen = status & 0x7ff;
+ if (status & CPDMA_DESC_OWNER) {
+ chan->stats.busy_dequeue++;
+ status = -EBUSY;
+ goto unlock_ret;
+ }
+ status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE);
+
+ chan->head = desc_from_phys(pool, desc_read(desc, hw_next));
+ chan_write(chan, cp, desc_dma);
+ chan->count--;
+ chan->stats.good_dequeue++;
+
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ __cpdma_chan_free(chan, desc, outlen, status);
+ return status;
+
+unlock_ret:
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return status;
+}
+
+int cpdma_chan_process(struct cpdma_chan *chan, int quota)
+{
+ int used = 0, ret = 0;
+
+ if (chan->state != CPDMA_STATE_ACTIVE)
+ return -EINVAL;
+
+ while (used < quota) {
+ ret = __cpdma_chan_process(chan);
+ if (ret < 0)
+ break;
+ used++;
+ }
+ return used;
+}
+
+int cpdma_chan_start(struct cpdma_chan *chan)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc_pool *pool = ctlr->pool;
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->lock, flags);
+ if (chan->state != CPDMA_STATE_IDLE) {
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return -EBUSY;
+ }
+ if (ctlr->state != CPDMA_STATE_ACTIVE) {
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return -EINVAL;
+ }
+ dma_reg_write(ctlr, chan->int_set, chan->mask);
+ chan->state = CPDMA_STATE_ACTIVE;
+ if (chan->head) {
+ chan_write(chan, hdp, desc_phys(pool, chan->head));
+ if (chan->rxfree)
+ chan_write(chan, rxfree, chan->count);
+ }
+
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return 0;
+}
+
+int cpdma_chan_stop(struct cpdma_chan *chan)
+{
+ struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_desc_pool *pool = ctlr->pool;
+ unsigned long flags;
+ int ret;
+ unsigned long timeout;
+
+ spin_lock_irqsave(&chan->lock, flags);
+ if (chan->state != CPDMA_STATE_ACTIVE) {
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return -EINVAL;
+ }
+
+ chan->state = CPDMA_STATE_TEARDOWN;
+ dma_reg_write(ctlr, chan->int_clear, chan->mask);
+
+ /* trigger teardown */
+ dma_reg_write(ctlr, chan->td, chan->chan_num);
+
+ /* wait for teardown complete */
+ timeout = jiffies + HZ/10; /* 100 msec */
+ while (time_before(jiffies, timeout)) {
+ u32 cp = chan_read(chan, cp);
+ if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE)
+ break;
+ cpu_relax();
+ }
+ WARN_ON(!time_before(jiffies, timeout));
+ chan_write(chan, cp, CPDMA_TEARDOWN_VALUE);
+
+ /* handle completed packets */
+ do {
+ ret = __cpdma_chan_process(chan);
+ if (ret < 0)
+ break;
+ } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0);
+
+ /* remaining packets haven't been tx/rx'ed, clean them up */
+ while (chan->head) {
+ struct cpdma_desc __iomem *desc = chan->head;
+ dma_addr_t next_dma;
+
+ next_dma = desc_read(desc, hw_next);
+ chan->head = desc_from_phys(pool, next_dma);
+ chan->stats.teardown_dequeue++;
+
+ /* issue callback without locks held */
+ spin_unlock_irqrestore(&chan->lock, flags);
+ __cpdma_chan_free(chan, desc, 0, -ENOSYS);
+ spin_lock_irqsave(&chan->lock, flags);
+ }
+
+ chan->state = CPDMA_STATE_IDLE;
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return 0;
+}
+
+int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->lock, flags);
+ if (chan->state != CPDMA_STATE_ACTIVE) {
+ spin_unlock_irqrestore(&chan->lock, flags);
+ return -EINVAL;
+ }
+
+ dma_reg_write(chan->ctlr, enable ? chan->int_set : chan->int_clear,
+ chan->mask);
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ return 0;
+}
+
+struct cpdma_control_info {
+ u32 reg;
+ u32 shift, mask;
+ int access;
+#define ACCESS_RO BIT(0)
+#define ACCESS_WO BIT(1)
+#define ACCESS_RW (ACCESS_RO | ACCESS_WO)
+};
+
+struct cpdma_control_info controls[] = {
+ [CPDMA_CMD_IDLE] = {CPDMA_DMACONTROL, 3, 1, ACCESS_WO},
+ [CPDMA_COPY_ERROR_FRAMES] = {CPDMA_DMACONTROL, 4, 1, ACCESS_RW},
+ [CPDMA_RX_OFF_LEN_UPDATE] = {CPDMA_DMACONTROL, 2, 1, ACCESS_RW},
+ [CPDMA_RX_OWNERSHIP_FLIP] = {CPDMA_DMACONTROL, 1, 1, ACCESS_RW},
+ [CPDMA_TX_PRIO_FIXED] = {CPDMA_DMACONTROL, 0, 1, ACCESS_RW},
+ [CPDMA_STAT_IDLE] = {CPDMA_DMASTATUS, 31, 1, ACCESS_RO},
+ [CPDMA_STAT_TX_ERR_CODE] = {CPDMA_DMASTATUS, 20, 0xf, ACCESS_RW},
+ [CPDMA_STAT_TX_ERR_CHAN] = {CPDMA_DMASTATUS, 16, 0x7, ACCESS_RW},
+ [CPDMA_STAT_RX_ERR_CODE] = {CPDMA_DMASTATUS, 12, 0xf, ACCESS_RW},
+ [CPDMA_STAT_RX_ERR_CHAN] = {CPDMA_DMASTATUS, 8, 0x7, ACCESS_RW},
+ [CPDMA_RX_BUFFER_OFFSET] = {CPDMA_RXBUFFOFS, 0, 0xffff, ACCESS_RW},
+};
+
+int cpdma_control_get(struct cpdma_ctlr *ctlr, int control)
+{
+ unsigned long flags;
+ struct cpdma_control_info *info = &controls[control];
+ int ret;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ ret = -ENOTSUPP;
+ if (!ctlr->params.has_ext_regs)
+ goto unlock_ret;
+
+ ret = -EINVAL;
+ if (ctlr->state != CPDMA_STATE_ACTIVE)
+ goto unlock_ret;
+
+ ret = -ENOENT;
+ if (control < 0 || control >= ARRAY_SIZE(controls))
+ goto unlock_ret;
+
+ ret = -EPERM;
+ if ((info->access & ACCESS_RO) != ACCESS_RO)
+ goto unlock_ret;
+
+ ret = (dma_reg_read(ctlr, info->reg) >> info->shift) & info->mask;
+
+unlock_ret:
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return ret;
+}
+
+int cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value)
+{
+ unsigned long flags;
+ struct cpdma_control_info *info = &controls[control];
+ int ret;
+ u32 val;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ ret = -ENOTSUPP;
+ if (!ctlr->params.has_ext_regs)
+ goto unlock_ret;
+
+ ret = -EINVAL;
+ if (ctlr->state != CPDMA_STATE_ACTIVE)
+ goto unlock_ret;
+
+ ret = -ENOENT;
+ if (control < 0 || control >= ARRAY_SIZE(controls))
+ goto unlock_ret;
+
+ ret = -EPERM;
+ if ((info->access & ACCESS_WO) != ACCESS_WO)
+ goto unlock_ret;
+
+ val = dma_reg_read(ctlr, info->reg);
+ val &= ~(info->mask << info->shift);
+ val |= (value & info->mask) << info->shift;
+ dma_reg_write(ctlr, info->reg, val);
+ ret = 0;
+
+unlock_ret:
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+ return ret;
+}
diff --git a/drivers/net/davinci_cpdma.h b/drivers/net/davinci_cpdma.h
new file mode 100644
index 000000000000..d50ee35f3078
--- /dev/null
+++ b/drivers/net/davinci_cpdma.h
@@ -0,0 +1,105 @@
+/*
+ * Texas Instruments CPDMA Driver
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DAVINCI_CPDMA_H__
+#define __DAVINCI_CPDMA_H__
+
+#define CPDMA_MAX_CHANNELS BITS_PER_LONG
+
+#define tx_chan_num(chan) (chan)
+#define rx_chan_num(chan) ((chan) + CPDMA_MAX_CHANNELS)
+#define is_rx_chan(chan) ((chan)->chan_num >= CPDMA_MAX_CHANNELS)
+#define is_tx_chan(chan) (!is_rx_chan(chan))
+#define __chan_linear(chan_num) ((chan_num) & (CPDMA_MAX_CHANNELS - 1))
+#define chan_linear(chan) __chan_linear((chan)->chan_num)
+
+struct cpdma_params {
+ struct device *dev;
+ void __iomem *dmaregs;
+ void __iomem *txhdp, *rxhdp, *txcp, *rxcp;
+ void __iomem *rxthresh, *rxfree;
+ int num_chan;
+ bool has_soft_reset;
+ int min_packet_size;
+ u32 desc_mem_phys;
+ int desc_mem_size;
+ int desc_align;
+
+ /*
+ * Some instances of embedded cpdma controllers have extra control and
+ * status registers. The following flag enables access to these
+ * "extended" registers.
+ */
+ bool has_ext_regs;
+};
+
+struct cpdma_chan_stats {
+ u32 head_enqueue;
+ u32 tail_enqueue;
+ u32 pad_enqueue;
+ u32 misqueued;
+ u32 desc_alloc_fail;
+ u32 pad_alloc_fail;
+ u32 runt_receive_buff;
+ u32 runt_transmit_buff;
+ u32 empty_dequeue;
+ u32 busy_dequeue;
+ u32 good_dequeue;
+ u32 teardown_dequeue;
+};
+
+struct cpdma_ctlr;
+struct cpdma_chan;
+
+typedef void (*cpdma_handler_fn)(void *token, int len, int status);
+
+struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params);
+int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr);
+int cpdma_ctlr_start(struct cpdma_ctlr *ctlr);
+int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr);
+
+struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,
+ cpdma_handler_fn handler);
+int cpdma_chan_destroy(struct cpdma_chan *chan);
+int cpdma_chan_start(struct cpdma_chan *chan);
+int cpdma_chan_stop(struct cpdma_chan *chan);
+
+int cpdma_chan_get_stats(struct cpdma_chan *chan,
+ struct cpdma_chan_stats *stats);
+int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data,
+ int len, gfp_t gfp_mask);
+int cpdma_chan_process(struct cpdma_chan *chan, int quota);
+
+int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable);
+void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr);
+int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable);
+
+enum cpdma_control {
+ CPDMA_CMD_IDLE, /* write-only */
+ CPDMA_COPY_ERROR_FRAMES, /* read-write */
+ CPDMA_RX_OFF_LEN_UPDATE, /* read-write */
+ CPDMA_RX_OWNERSHIP_FLIP, /* read-write */
+ CPDMA_TX_PRIO_FIXED, /* read-write */
+ CPDMA_STAT_IDLE, /* read-only */
+ CPDMA_STAT_TX_ERR_CHAN, /* read-only */
+ CPDMA_STAT_TX_ERR_CODE, /* read-only */
+ CPDMA_STAT_RX_ERR_CHAN, /* read-only */
+ CPDMA_STAT_RX_ERR_CODE, /* read-only */
+ CPDMA_RX_BUFFER_OFFSET, /* read-write */
+};
+
+int cpdma_control_get(struct cpdma_ctlr *ctlr, int control);
+int cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value);
+
+#endif
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 7fbd052ddb0a..525b84ce131b 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -63,6 +63,8 @@
#include <asm/irq.h>
#include <asm/page.h>
+#include "davinci_cpdma.h"
+
static int debug_level;
module_param(debug_level, int, 0);
MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
@@ -113,7 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DEF_MAX_FRAME_SIZE (1500 + 14 + 4 + 4)
#define EMAC_DEF_TX_CH (0) /* Default 0th channel */
#define EMAC_DEF_RX_CH (0) /* Default 0th channel */
-#define EMAC_DEF_MDIO_TICK_MS (10) /* typically 1 tick=1 ms) */
+#define EMAC_DEF_RX_NUM_DESC (128)
#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */
#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */
#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */
@@ -125,7 +127,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
/* EMAC register related defines */
#define EMAC_ALL_MULTI_REG_VALUE (0xFFFFFFFF)
#define EMAC_NUM_MULTICAST_BITS (64)
-#define EMAC_TEARDOWN_VALUE (0xFFFFFFFC)
#define EMAC_TX_CONTROL_TX_ENABLE_VAL (0x1)
#define EMAC_RX_CONTROL_RX_ENABLE_VAL (0x1)
#define EMAC_MAC_HOST_ERR_INTMASK_VAL (0x2)
@@ -212,24 +213,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DEF_MAX_MULTICAST_ADDRESSES (64) /* Max mcast addr's */
/* EMAC Peripheral Device Register Memory Layout structure */
-#define EMAC_TXIDVER 0x0
-#define EMAC_TXCONTROL 0x4
-#define EMAC_TXTEARDOWN 0x8
-#define EMAC_RXIDVER 0x10
-#define EMAC_RXCONTROL 0x14
-#define EMAC_RXTEARDOWN 0x18
-#define EMAC_TXINTSTATRAW 0x80
-#define EMAC_TXINTSTATMASKED 0x84
-#define EMAC_TXINTMASKSET 0x88
-#define EMAC_TXINTMASKCLEAR 0x8C
#define EMAC_MACINVECTOR 0x90
#define EMAC_DM646X_MACEOIVECTOR 0x94
-#define EMAC_RXINTSTATRAW 0xA0
-#define EMAC_RXINTSTATMASKED 0xA4
-#define EMAC_RXINTMASKSET 0xA8
-#define EMAC_RXINTMASKCLEAR 0xAC
#define EMAC_MACINTSTATRAW 0xB0
#define EMAC_MACINTSTATMASKED 0xB4
#define EMAC_MACINTMASKSET 0xB8
@@ -256,12 +243,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_MACADDRHI 0x504
#define EMAC_MACINDEX 0x508
-/* EMAC HDP and Completion registors */
-#define EMAC_TXHDP(ch) (0x600 + (ch * 4))
-#define EMAC_RXHDP(ch) (0x620 + (ch * 4))
-#define EMAC_TXCP(ch) (0x640 + (ch * 4))
-#define EMAC_RXCP(ch) (0x660 + (ch * 4))
-
/* EMAC statistics registers */
#define EMAC_RXGOODFRAMES 0x200
#define EMAC_RXBCASTFRAMES 0x204
@@ -303,25 +284,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DM644X_INTMIN_INTVL 0x1
#define EMAC_DM644X_INTMAX_INTVL (EMAC_DM644X_EWINTCNT_MASK)
-/* EMAC MDIO related */
-/* Mask & Control defines */
-#define MDIO_CONTROL_CLKDIV (0xFF)
-#define MDIO_CONTROL_ENABLE BIT(30)
-#define MDIO_USERACCESS_GO BIT(31)
-#define MDIO_USERACCESS_WRITE BIT(30)
-#define MDIO_USERACCESS_READ (0)
-#define MDIO_USERACCESS_REGADR (0x1F << 21)
-#define MDIO_USERACCESS_PHYADR (0x1F << 16)
-#define MDIO_USERACCESS_DATA (0xFFFF)
-#define MDIO_USERPHYSEL_LINKSEL BIT(7)
-#define MDIO_VER_MODID (0xFFFF << 16)
-#define MDIO_VER_REVMAJ (0xFF << 8)
-#define MDIO_VER_REVMIN (0xFF)
-
-#define MDIO_USERACCESS(inst) (0x80 + (inst * 8))
-#define MDIO_USERPHYSEL(inst) (0x84 + (inst * 8))
-#define MDIO_CONTROL (0x04)
-
/* EMAC DM646X control module registers */
#define EMAC_DM646X_CMINTCTRL 0x0C
#define EMAC_DM646X_CMRXINTEN 0x14
@@ -345,120 +307,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
/* EMAC Stats Clear Mask */
#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
-/** net_buf_obj: EMAC network bufferdata structure
- *
- * EMAC network buffer data structure
- */
-struct emac_netbufobj {
- void *buf_token;
- char *data_ptr;
- int length;
-};
-
-/** net_pkt_obj: EMAC network packet data structure
- *
- * EMAC network packet data structure - supports buffer list (for future)
- */
-struct emac_netpktobj {
- void *pkt_token; /* data token may hold tx/rx chan id */
- struct emac_netbufobj *buf_list; /* array of network buffer objects */
- int num_bufs;
- int pkt_length;
-};
-
-/** emac_tx_bd: EMAC TX Buffer descriptor data structure
- *
- * EMAC TX Buffer descriptor data structure
- */
-struct emac_tx_bd {
- int h_next;
- int buff_ptr;
- int off_b_len;
- int mode; /* SOP, EOP, ownership, EOQ, teardown,Qstarv, length */
- struct emac_tx_bd __iomem *next;
- void *buf_token;
-};
-
-/** emac_txch: EMAC TX Channel data structure
- *
- * EMAC TX Channel data structure
- */
-struct emac_txch {
- /* Config related */
- u32 num_bd;
- u32 service_max;
-
- /* CPPI specific */
- u32 alloc_size;
- void __iomem *bd_mem;
- struct emac_tx_bd __iomem *bd_pool_head;
- struct emac_tx_bd __iomem *active_queue_head;
- struct emac_tx_bd __iomem *active_queue_tail;
- struct emac_tx_bd __iomem *last_hw_bdprocessed;
- u32 queue_active;
- u32 teardown_pending;
- u32 *tx_complete;
-
- /** statistics */
- u32 proc_count; /* TX: # of times emac_tx_bdproc is called */
- u32 mis_queued_packets;
- u32 queue_reinit;
- u32 end_of_queue_add;
- u32 out_of_tx_bd;
- u32 no_active_pkts; /* IRQ when there were no packets to process */
- u32 active_queue_count;
-};
-
-/** emac_rx_bd: EMAC RX Buffer descriptor data structure
- *
- * EMAC RX Buffer descriptor data structure
- */
-struct emac_rx_bd {
- int h_next;
- int buff_ptr;
- int off_b_len;
- int mode;
- struct emac_rx_bd __iomem *next;
- void *data_ptr;
- void *buf_token;
-};
-
-/** emac_rxch: EMAC RX Channel data structure
- *
- * EMAC RX Channel data structure
- */
-struct emac_rxch {
- /* configuration info */
- u32 num_bd;
- u32 service_max;
- u32 buf_size;
- char mac_addr[6];
-
- /** CPPI specific */
- u32 alloc_size;
- void __iomem *bd_mem;
- struct emac_rx_bd __iomem *bd_pool_head;
- struct emac_rx_bd __iomem *active_queue_head;
- struct emac_rx_bd __iomem *active_queue_tail;
- u32 queue_active;
- u32 teardown_pending;
-
- /* packet and buffer objects */
- struct emac_netpktobj pkt_queue;
- struct emac_netbufobj buf_queue;
-
- /** statistics */
- u32 proc_count; /* number of times emac_rx_bdproc is called */
- u32 processed_bd;
- u32 recycled_bd;
- u32 out_of_rx_bd;
- u32 out_of_rx_buffers;
- u32 queue_reinit;
- u32 end_of_queue_add;
- u32 end_of_queue;
- u32 mis_queued_packets;
-};
-
/* emac_priv: EMAC private data structure
*
* EMAC adapter private data structure
@@ -469,17 +317,13 @@ struct emac_priv {
struct platform_device *pdev;
struct napi_struct napi;
char mac_addr[6];
- spinlock_t tx_lock;
- spinlock_t rx_lock;
void __iomem *remap_addr;
u32 emac_base_phys;
void __iomem *emac_base;
void __iomem *ctrl_base;
- void __iomem *emac_ctrl_ram;
- u32 ctrl_ram_size;
- u32 hw_ram_addr;
- struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
- struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
+ struct cpdma_ctlr *dma;
+ struct cpdma_chan *txchan;
+ struct cpdma_chan *rxchan;
u32 link; /* 1=link on, 0=link off */
u32 speed; /* 0=Auto Neg, 1=No PHY, 10,100, 1000 - mbps */
u32 duplex; /* Link duplex: 0=Half, 1=Full */
@@ -493,13 +337,7 @@ struct emac_priv {
u32 mac_hash2;
u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
u32 rx_addr_type;
- /* periodic timer required for MDIO polling */
- struct timer_list periodic_timer;
- u32 periodic_ticks;
- u32 timer_active;
- u32 phy_mask;
- /* mii_bus,phy members */
- struct mii_bus *mii_bus;
+ const char *phy_id;
struct phy_device *phydev;
spinlock_t lock;
/*platform specific members*/
@@ -510,19 +348,6 @@ struct emac_priv {
/* clock frequency for EMAC */
static struct clk *emac_clk;
static unsigned long emac_bus_frequency;
-static unsigned long mdio_max_freq;
-
-#define emac_virt_to_phys(addr, priv) \
- (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \
- + priv->hw_ram_addr)
-
-/* Cache macros - Packet buffers would be from skb pool which is cached */
-#define EMAC_VIRT_NOCACHE(addr) (addr)
-
-/* DM644x does not have BD's in cached memory - so no cache functions */
-#define BD_CACHE_INVALIDATE(addr, size)
-#define BD_CACHE_WRITEBACK(addr, size)
-#define BD_CACHE_WRITEBACK_INVALIDATE(addr, size)
/* EMAC TX Host Error description strings */
static char *emac_txhost_errcodes[16] = {
@@ -548,9 +373,6 @@ static char *emac_rxhost_errcodes[16] = {
#define emac_ctrl_read(reg) ioread32((priv->ctrl_base + (reg)))
#define emac_ctrl_write(reg, val) iowrite32(val, (priv->ctrl_base + (reg)))
-#define emac_mdio_read(reg) ioread32(bus->priv + (reg))
-#define emac_mdio_write(reg, val) iowrite32(val, (bus->priv + (reg)))
-
/**
* emac_dump_regs: Dump important EMAC registers to debug terminal
* @priv: The DaVinci EMAC private adapter structure
@@ -569,20 +391,6 @@ static void emac_dump_regs(struct emac_priv *priv)
emac_ctrl_read(EMAC_CTRL_EWCTL),
emac_ctrl_read(EMAC_CTRL_EWINTTCNT));
}
- dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n",
- emac_read(EMAC_TXIDVER),
- ((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"),
- emac_read(EMAC_RXIDVER),
- ((emac_read(EMAC_RXCONTROL)) ? "enabled" : "disabled"));
- dev_info(emac_dev, "EMAC: TXIntRaw:%08X, TxIntMasked: %08X, "\
- "TxIntMasSet: %08X\n", emac_read(EMAC_TXINTSTATRAW),
- emac_read(EMAC_TXINTSTATMASKED), emac_read(EMAC_TXINTMASKSET));
- dev_info(emac_dev, "EMAC: RXIntRaw:%08X, RxIntMasked: %08X, "\
- "RxIntMasSet: %08X\n", emac_read(EMAC_RXINTSTATRAW),
- emac_read(EMAC_RXINTSTATMASKED), emac_read(EMAC_RXINTMASKSET));
- dev_info(emac_dev, "EMAC: MacIntRaw:%08X, MacIntMasked: %08X, "\
- "MacInVector=%08X\n", emac_read(EMAC_MACINTSTATRAW),
- emac_read(EMAC_MACINTSTATMASKED), emac_read(EMAC_MACINVECTOR));
dev_info(emac_dev, "EMAC: EmuControl:%08X, FifoControl: %08X\n",
emac_read(EMAC_EMCONTROL), emac_read(EMAC_FIFOCONTROL));
dev_info(emac_dev, "EMAC: MBPEnable:%08X, RXUnicastSet: %08X, "\
@@ -591,8 +399,6 @@ static void emac_dump_regs(struct emac_priv *priv)
dev_info(emac_dev, "EMAC: MacControl:%08X, MacStatus: %08X, "\
"MacConfig=%08X\n", emac_read(EMAC_MACCONTROL),
emac_read(EMAC_MACSTATUS), emac_read(EMAC_MACCONFIG));
- dev_info(emac_dev, "EMAC: TXHDP[0]:%08X, RXHDP[0]: %08X\n",
- emac_read(EMAC_TXHDP(0)), emac_read(EMAC_RXHDP(0)));
dev_info(emac_dev, "EMAC Statistics\n");
dev_info(emac_dev, "EMAC: rx_good_frames:%d\n",
emac_read(EMAC_RXGOODFRAMES));
@@ -656,9 +462,6 @@ static void emac_dump_regs(struct emac_priv *priv)
emac_read(EMAC_RXDMAOVERRUNS));
}
-/*************************************************************************
- * EMAC MDIO/Phy Functionality
- *************************************************************************/
/**
* emac_get_drvinfo: Get EMAC driver information
* @ndev: The DaVinci EMAC network adapter
@@ -686,7 +489,7 @@ static int emac_get_settings(struct net_device *ndev,
struct ethtool_cmd *ecmd)
{
struct emac_priv *priv = netdev_priv(ndev);
- if (priv->phy_mask)
+ if (priv->phydev)
return phy_ethtool_gset(priv->phydev, ecmd);
else
return -EOPNOTSUPP;
@@ -704,7 +507,7 @@ static int emac_get_settings(struct net_device *ndev,
static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
{
struct emac_priv *priv = netdev_priv(ndev);
- if (priv->phy_mask)
+ if (priv->phydev)
return phy_ethtool_sset(priv->phydev, ecmd);
else
return -EOPNOTSUPP;
@@ -841,7 +644,7 @@ static void emac_update_phystatus(struct emac_priv *priv)
mac_control = emac_read(EMAC_MACCONTROL);
cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ?
DUPLEX_FULL : DUPLEX_HALF;
- if (priv->phy_mask)
+ if (priv->phydev)
new_duplex = priv->phydev->duplex;
else
new_duplex = DUPLEX_FULL;
@@ -1184,371 +987,55 @@ static irqreturn_t emac_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/** EMAC on-chip buffer descriptor memory
- *
- * WARNING: Please note that the on chip memory is used for both TX and RX
- * buffer descriptor queues and is equally divided between TX and RX desc's
- * If the number of TX or RX descriptors change this memory pointers need
- * to be adjusted. If external memory is allocated then these pointers can
- * pointer to the memory
- *
- */
-#define EMAC_TX_BD_MEM(priv) ((priv)->emac_ctrl_ram)
-#define EMAC_RX_BD_MEM(priv) ((priv)->emac_ctrl_ram + \
- (((priv)->ctrl_ram_size) >> 1))
-
-/**
- * emac_init_txch: TX channel initialization
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number
- *
- * Called during device init to setup a TX channel (allocate buffer desc
- * create free pool and keep ready for transmission
- *
- * Returns success(0) or mem alloc failures error code
- */
-static int emac_init_txch(struct emac_priv *priv, u32 ch)
+static struct sk_buff *emac_rx_alloc(struct emac_priv *priv)
{
- struct device *emac_dev = &priv->ndev->dev;
- u32 cnt, bd_size;
- void __iomem *mem;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch = NULL;
-
- txch = kzalloc(sizeof(struct emac_txch), GFP_KERNEL);
- if (NULL == txch) {
- dev_err(emac_dev, "DaVinci EMAC: TX Ch mem alloc failed");
- return -ENOMEM;
- }
- priv->txch[ch] = txch;
- txch->service_max = EMAC_DEF_TX_MAX_SERVICE;
- txch->active_queue_head = NULL;
- txch->active_queue_tail = NULL;
- txch->queue_active = 0;
- txch->teardown_pending = 0;
-
- /* allocate memory for TX CPPI channel on a 4 byte boundry */
- txch->tx_complete = kzalloc(txch->service_max * sizeof(u32),
- GFP_KERNEL);
- if (NULL == txch->tx_complete) {
- dev_err(emac_dev, "DaVinci EMAC: Tx service mem alloc failed");
- kfree(txch);
- return -ENOMEM;
- }
-
- /* allocate buffer descriptor pool align every BD on four word
- * boundry for future requirements */
- bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF;
- txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
- txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF);
-
- /* alloc TX BD memory */
- txch->bd_mem = EMAC_TX_BD_MEM(priv);
- __memzero((void __force *)txch->bd_mem, txch->alloc_size);
-
- /* initialize the BD linked list */
- mem = (void __force __iomem *)
- (((u32 __force) txch->bd_mem + 0xF) & ~0xF);
- txch->bd_pool_head = NULL;
- for (cnt = 0; cnt < txch->num_bd; cnt++) {
- curr_bd = mem + (cnt * bd_size);
- curr_bd->next = txch->bd_pool_head;
- txch->bd_pool_head = curr_bd;
- }
-
- /* reset statistics counters */
- txch->out_of_tx_bd = 0;
- txch->no_active_pkts = 0;
- txch->active_queue_count = 0;
-
- return 0;
-}
-
-/**
- * emac_cleanup_txch: Book-keep function to clean TX channel resources
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: TX channel number
- *
- * Called to clean up TX channel resources
- *
- */
-static void emac_cleanup_txch(struct emac_priv *priv, u32 ch)
-{
- struct emac_txch *txch = priv->txch[ch];
-
- if (txch) {
- if (txch->bd_mem)
- txch->bd_mem = NULL;
- kfree(txch->tx_complete);
- kfree(txch);
- priv->txch[ch] = NULL;
- }
+ struct sk_buff *skb = dev_alloc_skb(priv->rx_buf_size);
+ if (WARN_ON(!skb))
+ return NULL;
+ skb->dev = priv->ndev;
+ skb_reserve(skb, NET_IP_ALIGN);
+ return skb;
}
-/**
- * emac_net_tx_complete: TX packet completion function
- * @priv: The DaVinci EMAC private adapter structure
- * @net_data_tokens: packet token - skb pointer
- * @num_tokens: number of skb's to free
- * @ch: TX channel number
- *
- * Frees the skb once packet is transmitted
- *
- */
-static int emac_net_tx_complete(struct emac_priv *priv,
- void **net_data_tokens,
- int num_tokens, u32 ch)
+static void emac_rx_handler(void *token, int len, int status)
{
- struct net_device *ndev = priv->ndev;
- u32 cnt;
-
- if (unlikely(num_tokens && netif_queue_stopped(ndev)))
- netif_start_queue(ndev);
- for (cnt = 0; cnt < num_tokens; cnt++) {
- struct sk_buff *skb = (struct sk_buff *)net_data_tokens[cnt];
- if (skb == NULL)
- continue;
- ndev->stats.tx_packets++;
- ndev->stats.tx_bytes += skb->len;
- dev_kfree_skb_any(skb);
- }
- return 0;
-}
+ struct sk_buff *skb = token;
+ struct net_device *ndev = skb->dev;
+ struct emac_priv *priv = netdev_priv(ndev);
+ int ret;
-/**
- * emac_txch_teardown: TX channel teardown
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: TX channel number
- *
- * Called to teardown TX channel
- *
- */
-static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
-{
- struct device *emac_dev = &priv->ndev->dev;
- u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
- struct emac_txch *txch = priv->txch[ch];
- struct emac_tx_bd __iomem *curr_bd;
-
- while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
- EMAC_TEARDOWN_VALUE) {
- /* wait till tx teardown complete */
- cpu_relax(); /* TODO: check if this helps ... */
- --teardown_cnt;
- if (0 == teardown_cnt) {
- dev_err(emac_dev, "EMAC: TX teardown aborted\n");
- break;
- }
+ if (status < 0) {
+ /* error */
+ goto recycle;
}
- emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE);
-
- /* process sent packets and return skb's to upper layer */
- if (1 == txch->queue_active) {
- curr_bd = txch->active_queue_head;
- while (curr_bd != NULL) {
- dma_unmap_single(emac_dev, curr_bd->buff_ptr,
- curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
- DMA_TO_DEVICE);
-
- emac_net_tx_complete(priv, (void __force *)
- &curr_bd->buf_token, 1, ch);
- if (curr_bd != txch->active_queue_tail)
- curr_bd = curr_bd->next;
- else
- break;
- }
- txch->bd_pool_head = txch->active_queue_head;
- txch->active_queue_head =
- txch->active_queue_tail = NULL;
- }
-}
-/**
- * emac_stop_txch: Stop TX channel operation
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: TX channel number
- *
- * Called to stop TX channel operation
- *
- */
-static void emac_stop_txch(struct emac_priv *priv, u32 ch)
-{
- struct emac_txch *txch = priv->txch[ch];
-
- if (txch) {
- txch->teardown_pending = 1;
- emac_write(EMAC_TXTEARDOWN, 0);
- emac_txch_teardown(priv, ch);
- txch->teardown_pending = 0;
- emac_write(EMAC_TXINTMASKCLEAR, BIT(ch));
- }
-}
+ skb_put(skb, len);
+ skb->protocol = eth_type_trans(skb, ndev);
+ netif_receive_skb(skb);
+ ndev->stats.rx_bytes += len;
+ ndev->stats.rx_packets++;
-/**
- * emac_tx_bdproc: TX buffer descriptor (packet) processing
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: TX channel number to process buffer descriptors for
- * @budget: number of packets allowed to process
- * @pending: indication to caller that packets are pending to process
- *
- * Processes TX buffer descriptors after packets are transmitted - checks
- * ownership bit on the TX * descriptor and requeues it to free pool & frees
- * the SKB buffer. Only "budget" number of packets are processed and
- * indication of pending packets provided to the caller
- *
- * Returns number of packets processed
- */
-static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
-{
- struct device *emac_dev = &priv->ndev->dev;
- unsigned long flags;
- u32 frame_status;
- u32 pkts_processed = 0;
- u32 tx_complete_cnt = 0;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch = priv->txch[ch];
- u32 *tx_complete_ptr = txch->tx_complete;
-
- if (unlikely(1 == txch->teardown_pending)) {
- if (netif_msg_tx_err(priv) && net_ratelimit()) {
- dev_err(emac_dev, "DaVinci EMAC:emac_tx_bdproc: "\
- "teardown pending\n");
- }
- return 0; /* dont handle any pkt completions */
- }
+ /* alloc a new packet for receive */
+ skb = emac_rx_alloc(priv);
- ++txch->proc_count;
- spin_lock_irqsave(&priv->tx_lock, flags);
- curr_bd = txch->active_queue_head;
- if (NULL == curr_bd) {
- emac_write(EMAC_TXCP(ch),
- emac_virt_to_phys(txch->last_hw_bdprocessed, priv));
- txch->no_active_pkts++;
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- return 0;
+recycle:
+ if (skb) {
+ ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
+ skb_tailroom(skb), GFP_KERNEL);
+ WARN_ON(ret < 0);
}
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- while ((curr_bd) &&
- ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
- (pkts_processed < budget)) {
- emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv));
- txch->active_queue_head = curr_bd->next;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- if (curr_bd->next) { /* misqueued packet */
- emac_write(EMAC_TXHDP(ch), curr_bd->h_next);
- ++txch->mis_queued_packets;
- } else {
- txch->queue_active = 0; /* end of queue */
- }
- }
-
- dma_unmap_single(emac_dev, curr_bd->buff_ptr,
- curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
- DMA_TO_DEVICE);
-
- *tx_complete_ptr = (u32) curr_bd->buf_token;
- ++tx_complete_ptr;
- ++tx_complete_cnt;
- curr_bd->next = txch->bd_pool_head;
- txch->bd_pool_head = curr_bd;
- --txch->active_queue_count;
- pkts_processed++;
- txch->last_hw_bdprocessed = curr_bd;
- curr_bd = txch->active_queue_head;
- if (curr_bd) {
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- }
- } /* end of pkt processing loop */
-
- emac_net_tx_complete(priv,
- (void *)&txch->tx_complete[0],
- tx_complete_cnt, ch);
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- return pkts_processed;
}
-#define EMAC_ERR_TX_OUT_OF_BD -1
-
-/**
- * emac_send: EMAC Transmit function (internal)
- * @priv: The DaVinci EMAC private adapter structure
- * @pkt: packet pointer (contains skb ptr)
- * @ch: TX channel number
- *
- * Called by the transmit function to queue the packet in EMAC hardware queue
- *
- * Returns success(0) or error code (typically out of desc's)
- */
-static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
+static void emac_tx_handler(void *token, int len, int status)
{
- unsigned long flags;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch;
- struct emac_netbufobj *buf_list;
-
- txch = priv->txch[ch];
- buf_list = pkt->buf_list; /* get handle to the buffer array */
-
- /* check packet size and pad if short */
- if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) {
- buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length);
- pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
- }
-
- spin_lock_irqsave(&priv->tx_lock, flags);
- curr_bd = txch->bd_pool_head;
- if (curr_bd == NULL) {
- txch->out_of_tx_bd++;
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- return EMAC_ERR_TX_OUT_OF_BD;
- }
+ struct sk_buff *skb = token;
+ struct net_device *ndev = skb->dev;
- txch->bd_pool_head = curr_bd->next;
- curr_bd->buf_token = buf_list->buf_token;
- curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr,
- buf_list->length, DMA_TO_DEVICE);
- curr_bd->off_b_len = buf_list->length;
- curr_bd->h_next = 0;
- curr_bd->next = NULL;
- curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT |
- EMAC_CPPI_EOP_BIT | pkt->pkt_length);
-
- /* flush the packet from cache if write back cache is present */
- BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
-
- /* send the packet */
- if (txch->active_queue_head == NULL) {
- txch->active_queue_head = curr_bd;
- txch->active_queue_tail = curr_bd;
- if (1 != txch->queue_active) {
- emac_write(EMAC_TXHDP(ch),
- emac_virt_to_phys(curr_bd, priv));
- txch->queue_active = 1;
- }
- ++txch->queue_reinit;
- } else {
- register struct emac_tx_bd __iomem *tail_bd;
- register u32 frame_status;
-
- tail_bd = txch->active_queue_tail;
- tail_bd->next = curr_bd;
- txch->active_queue_tail = curr_bd;
- tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv);
- frame_status = tail_bd->mode;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- emac_write(EMAC_TXHDP(ch),
- emac_virt_to_phys(curr_bd, priv));
- frame_status &= ~(EMAC_CPPI_EOQ_BIT);
- tail_bd->mode = frame_status;
- ++txch->end_of_queue_add;
- }
- }
- txch->active_queue_count++;
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- return 0;
+ if (unlikely(netif_queue_stopped(ndev)))
+ netif_start_queue(ndev);
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += len;
+ dev_kfree_skb_any(skb);
}
/**
@@ -1565,42 +1052,36 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct device *emac_dev = &ndev->dev;
int ret_code;
- struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */
- struct emac_netpktobj tx_packet; /* packet object */
struct emac_priv *priv = netdev_priv(ndev);
/* If no link, return */
if (unlikely(!priv->link)) {
if (netif_msg_tx_err(priv) && net_ratelimit())
dev_err(emac_dev, "DaVinci EMAC: No link to transmit");
- return NETDEV_TX_BUSY;
+ goto fail_tx;
+ }
+
+ ret_code = skb_padto(skb, EMAC_DEF_MIN_ETHPKTSIZE);
+ if (unlikely(ret_code < 0)) {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ dev_err(emac_dev, "DaVinci EMAC: packet pad failed");
+ goto fail_tx;
}
- /* Build the buffer and packet objects - Since only single fragment is
- * supported, need not set length and token in both packet & object.
- * Doing so for completeness sake & to show that this needs to be done
- * in multifragment case
- */
- tx_packet.buf_list = &tx_buf;
- tx_packet.num_bufs = 1; /* only single fragment supported */
- tx_packet.pkt_length = skb->len;
- tx_packet.pkt_token = (void *)skb;
- tx_buf.length = skb->len;
- tx_buf.buf_token = (void *)skb;
- tx_buf.data_ptr = skb->data;
- ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
+ ret_code = cpdma_chan_submit(priv->txchan, skb, skb->data, skb->len,
+ GFP_KERNEL);
if (unlikely(ret_code != 0)) {
- if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
- if (netif_msg_tx_err(priv) && net_ratelimit())
- dev_err(emac_dev, "DaVinci EMAC: xmit() fatal"\
- " err. Out of TX BD's");
- netif_stop_queue(priv->ndev);
- }
- ndev->stats.tx_dropped++;
- return NETDEV_TX_BUSY;
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ dev_err(emac_dev, "DaVinci EMAC: desc submit failed");
+ goto fail_tx;
}
return NETDEV_TX_OK;
+
+fail_tx:
+ ndev->stats.tx_dropped++;
+ netif_stop_queue(ndev);
+ return NETDEV_TX_BUSY;
}
/**
@@ -1623,216 +1104,12 @@ static void emac_dev_tx_timeout(struct net_device *ndev)
ndev->stats.tx_errors++;
emac_int_disable(priv);
- emac_stop_txch(priv, EMAC_DEF_TX_CH);
- emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
- emac_init_txch(priv, EMAC_DEF_TX_CH);
- emac_write(EMAC_TXHDP(0), 0);
- emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH));
+ cpdma_chan_stop(priv->txchan);
+ cpdma_chan_start(priv->txchan);
emac_int_enable(priv);
}
/**
- * emac_net_alloc_rx_buf: Allocate a skb for RX
- * @priv: The DaVinci EMAC private adapter structure
- * @buf_size: size of SKB data buffer to allocate
- * @data_token: data token returned (skb handle for storing in buffer desc)
- * @ch: RX channel number
- *
- * Called during RX channel setup - allocates skb buffer of required size
- * and provides the skb handle and allocated buffer data pointer to caller
- *
- * Returns skb data pointer or 0 on failure to alloc skb
- */
-static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
- void **data_token, u32 ch)
-{
- struct net_device *ndev = priv->ndev;
- struct device *emac_dev = &ndev->dev;
- struct sk_buff *p_skb;
-
- p_skb = dev_alloc_skb(buf_size);
- if (unlikely(NULL == p_skb)) {
- if (netif_msg_rx_err(priv) && net_ratelimit())
- dev_err(emac_dev, "DaVinci EMAC: failed to alloc skb");
- return NULL;
- }
-
- /* set device pointer in skb and reserve space for extra bytes */
- p_skb->dev = ndev;
- skb_reserve(p_skb, NET_IP_ALIGN);
- *data_token = (void *) p_skb;
- return p_skb->data;
-}
-
-/**
- * emac_init_rxch: RX channel initialization
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number
- * @param: mac address for RX channel
- *
- * Called during device init to setup a RX channel (allocate buffers and
- * buffer descriptors, create queue and keep ready for reception
- *
- * Returns success(0) or mem alloc failures error code
- */
-static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
-{
- struct device *emac_dev = &priv->ndev->dev;
- u32 cnt, bd_size;
- void __iomem *mem;
- struct emac_rx_bd __iomem *curr_bd;
- struct emac_rxch *rxch = NULL;
-
- rxch = kzalloc(sizeof(struct emac_rxch), GFP_KERNEL);
- if (NULL == rxch) {
- dev_err(emac_dev, "DaVinci EMAC: RX Ch mem alloc failed");
- return -ENOMEM;
- }
- priv->rxch[ch] = rxch;
- rxch->buf_size = priv->rx_buf_size;
- rxch->service_max = EMAC_DEF_RX_MAX_SERVICE;
- rxch->queue_active = 0;
- rxch->teardown_pending = 0;
-
- /* save mac address */
- for (cnt = 0; cnt < 6; cnt++)
- rxch->mac_addr[cnt] = param[cnt];
-
- /* allocate buffer descriptor pool align every BD on four word
- * boundry for future requirements */
- bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF;
- rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
- rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF);
- rxch->bd_mem = EMAC_RX_BD_MEM(priv);
- __memzero((void __force *)rxch->bd_mem, rxch->alloc_size);
- rxch->pkt_queue.buf_list = &rxch->buf_queue;
-
- /* allocate RX buffer and initialize the BD linked list */
- mem = (void __force __iomem *)
- (((u32 __force) rxch->bd_mem + 0xF) & ~0xF);
- rxch->active_queue_head = NULL;
- rxch->active_queue_tail = mem;
- for (cnt = 0; cnt < rxch->num_bd; cnt++) {
- curr_bd = mem + (cnt * bd_size);
- /* for future use the last parameter contains the BD ptr */
- curr_bd->data_ptr = emac_net_alloc_rx_buf(priv,
- rxch->buf_size,
- (void __force **)&curr_bd->buf_token,
- EMAC_DEF_RX_CH);
- if (curr_bd->data_ptr == NULL) {
- dev_err(emac_dev, "DaVinci EMAC: RX buf mem alloc " \
- "failed for ch %d\n", ch);
- kfree(rxch);
- return -ENOMEM;
- }
-
- /* populate the hardware descriptor */
- curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
- priv);
- curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr,
- rxch->buf_size, DMA_FROM_DEVICE);
- curr_bd->off_b_len = rxch->buf_size;
- curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
-
- /* write back to hardware memory */
- BD_CACHE_WRITEBACK_INVALIDATE((u32) curr_bd,
- EMAC_BD_LENGTH_FOR_CACHE);
- curr_bd->next = rxch->active_queue_head;
- rxch->active_queue_head = curr_bd;
- }
-
- /* At this point rxCppi->activeQueueHead points to the first
- RX BD ready to be given to RX HDP and rxch->active_queue_tail
- points to the last RX BD
- */
- return 0;
-}
-
-/**
- * emac_rxch_teardown: RX channel teardown
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number
- *
- * Called during device stop to teardown RX channel
- *
- */
-static void emac_rxch_teardown(struct emac_priv *priv, u32 ch)
-{
- struct device *emac_dev = &priv->ndev->dev;
- u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
-
- while ((emac_read(EMAC_RXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
- EMAC_TEARDOWN_VALUE) {
- /* wait till tx teardown complete */
- cpu_relax(); /* TODO: check if this helps ... */
- --teardown_cnt;
- if (0 == teardown_cnt) {
- dev_err(emac_dev, "EMAC: RX teardown aborted\n");
- break;
- }
- }
- emac_write(EMAC_RXCP(ch), EMAC_TEARDOWN_VALUE);
-}
-
-/**
- * emac_stop_rxch: Stop RX channel operation
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number
- *
- * Called during device stop to stop RX channel operation
- *
- */
-static void emac_stop_rxch(struct emac_priv *priv, u32 ch)
-{
- struct emac_rxch *rxch = priv->rxch[ch];
-
- if (rxch) {
- rxch->teardown_pending = 1;
- emac_write(EMAC_RXTEARDOWN, ch);
- /* wait for teardown complete */
- emac_rxch_teardown(priv, ch);
- rxch->teardown_pending = 0;
- emac_write(EMAC_RXINTMASKCLEAR, BIT(ch));
- }
-}
-
-/**
- * emac_cleanup_rxch: Book-keep function to clean RX channel resources
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number
- *
- * Called during device stop to clean up RX channel resources
- *
- */
-static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
-{
- struct emac_rxch *rxch = priv->rxch[ch];
- struct emac_rx_bd __iomem *curr_bd;
-
- if (rxch) {
- /* free the receive buffers previously allocated */
- curr_bd = rxch->active_queue_head;
- while (curr_bd) {
- if (curr_bd->buf_token) {
- dma_unmap_single(&priv->ndev->dev,
- curr_bd->buff_ptr,
- curr_bd->off_b_len
- & EMAC_RX_BD_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- dev_kfree_skb_any((struct sk_buff *)\
- curr_bd->buf_token);
- }
- curr_bd = curr_bd->next;
- }
- if (rxch->bd_mem)
- rxch->bd_mem = NULL;
- kfree(rxch);
- priv->rxch[ch] = NULL;
- }
-}
-
-/**
* emac_set_type0addr: Set EMAC Type0 mac address
* @priv: The DaVinci EMAC private adapter structure
* @ch: RX channel number
@@ -1948,7 +1225,6 @@ static void emac_setmac(struct emac_priv *priv, u32 ch, char *mac_addr)
static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
{
struct emac_priv *priv = netdev_priv(ndev);
- struct emac_rxch *rxch = priv->rxch[EMAC_DEF_RX_CH];
struct device *emac_dev = &priv->ndev->dev;
struct sockaddr *sa = addr;
@@ -1959,11 +1235,10 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
- /* If the interface is down - rxch is NULL. */
/* MAC address is configured only after the interface is enabled. */
if (netif_running(ndev)) {
- memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len);
- emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr);
+ memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
+ emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr);
}
if (netif_msg_drv(priv))
@@ -1974,194 +1249,6 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
}
/**
- * emac_addbd_to_rx_queue: Recycle RX buffer descriptor
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number to process buffer descriptors for
- * @curr_bd: current buffer descriptor
- * @buffer: buffer pointer for descriptor
- * @buf_token: buffer token (stores skb information)
- *
- * Prepares the recycled buffer descriptor and addes it to hardware
- * receive queue - if queue empty this descriptor becomes the head
- * else addes the descriptor to end of queue
- *
- */
-static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
- struct emac_rx_bd __iomem *curr_bd,
- char *buffer, void *buf_token)
-{
- struct emac_rxch *rxch = priv->rxch[ch];
-
- /* populate the hardware descriptor */
- curr_bd->h_next = 0;
- curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer,
- rxch->buf_size, DMA_FROM_DEVICE);
- curr_bd->off_b_len = rxch->buf_size;
- curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
- curr_bd->next = NULL;
- curr_bd->data_ptr = buffer;
- curr_bd->buf_token = buf_token;
-
- /* write back */
- BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- if (rxch->active_queue_head == NULL) {
- rxch->active_queue_head = curr_bd;
- rxch->active_queue_tail = curr_bd;
- if (0 != rxch->queue_active) {
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(rxch->active_queue_head, priv));
- rxch->queue_active = 1;
- }
- } else {
- struct emac_rx_bd __iomem *tail_bd;
- u32 frame_status;
-
- tail_bd = rxch->active_queue_tail;
- rxch->active_queue_tail = curr_bd;
- tail_bd->next = curr_bd;
- tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = emac_virt_to_phys(curr_bd, priv);
- frame_status = tail_bd->mode;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd, priv));
- frame_status &= ~(EMAC_CPPI_EOQ_BIT);
- tail_bd->mode = frame_status;
- ++rxch->end_of_queue_add;
- }
- }
- ++rxch->recycled_bd;
-}
-
-/**
- * emac_net_rx_cb: Prepares packet and sends to upper layer
- * @priv: The DaVinci EMAC private adapter structure
- * @net_pkt_list: Network packet list (received packets)
- *
- * Invalidates packet buffer memory and sends the received packet to upper
- * layer
- *
- * Returns success or appropriate error code (none as of now)
- */
-static int emac_net_rx_cb(struct emac_priv *priv,
- struct emac_netpktobj *net_pkt_list)
-{
- struct net_device *ndev = priv->ndev;
- struct sk_buff *p_skb = net_pkt_list->pkt_token;
- /* set length of packet */
- skb_put(p_skb, net_pkt_list->pkt_length);
- p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
- netif_receive_skb(p_skb);
- ndev->stats.rx_bytes += net_pkt_list->pkt_length;
- ndev->stats.rx_packets++;
- return 0;
-}
-
-/**
- * emac_rx_bdproc: RX buffer descriptor (packet) processing
- * @priv: The DaVinci EMAC private adapter structure
- * @ch: RX channel number to process buffer descriptors for
- * @budget: number of packets allowed to process
- * @pending: indication to caller that packets are pending to process
- *
- * Processes RX buffer descriptors - checks ownership bit on the RX buffer
- * descriptor, sends the receive packet to upper layer, allocates a new SKB
- * and recycles the buffer descriptor (requeues it in hardware RX queue).
- * Only "budget" number of packets are processed and indication of pending
- * packets provided to the caller.
- *
- * Returns number of packets processed (and indication of pending packets)
- */
-static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
-{
- unsigned long flags;
- u32 frame_status;
- u32 pkts_processed = 0;
- char *new_buffer;
- struct emac_rx_bd __iomem *curr_bd;
- struct emac_rx_bd __iomem *last_bd;
- struct emac_netpktobj *curr_pkt, pkt_obj;
- struct emac_netbufobj buf_obj;
- struct emac_netbufobj *rx_buf_obj;
- void *new_buf_token;
- struct emac_rxch *rxch = priv->rxch[ch];
-
- if (unlikely(1 == rxch->teardown_pending))
- return 0;
- ++rxch->proc_count;
- spin_lock_irqsave(&priv->rx_lock, flags);
- pkt_obj.buf_list = &buf_obj;
- curr_pkt = &pkt_obj;
- curr_bd = rxch->active_queue_head;
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
-
- while ((curr_bd) &&
- ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
- (pkts_processed < budget)) {
-
- new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size,
- &new_buf_token, EMAC_DEF_RX_CH);
- if (unlikely(NULL == new_buffer)) {
- ++rxch->out_of_rx_buffers;
- goto end_emac_rx_bdproc;
- }
-
- /* populate received packet data structure */
- rx_buf_obj = &curr_pkt->buf_list[0];
- rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
- rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
- rx_buf_obj->buf_token = curr_bd->buf_token;
-
- dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr,
- curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
- curr_pkt->num_bufs = 1;
- curr_pkt->pkt_length =
- (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
- emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv));
- ++rxch->processed_bd;
- last_bd = curr_bd;
- curr_bd = last_bd->next;
- rxch->active_queue_head = curr_bd;
-
- /* check if end of RX queue ? */
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- if (curr_bd) {
- ++rxch->mis_queued_packets;
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd, priv));
- } else {
- ++rxch->end_of_queue;
- rxch->queue_active = 0;
- }
- }
-
- /* recycle BD */
- emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer,
- new_buf_token);
-
- /* return the packet to the user - BD ptr passed in
- * last parameter for potential *future* use */
- spin_unlock_irqrestore(&priv->rx_lock, flags);
- emac_net_rx_cb(priv, curr_pkt);
- spin_lock_irqsave(&priv->rx_lock, flags);
- curr_bd = rxch->active_queue_head;
- if (curr_bd) {
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- }
- ++pkts_processed;
- }
-
-end_emac_rx_bdproc:
- spin_unlock_irqrestore(&priv->rx_lock, flags);
- return pkts_processed;
-}
-
-/**
* emac_hw_enable: Enable EMAC hardware for packet transmission/reception
* @priv: The DaVinci EMAC private adapter structure
*
@@ -2172,7 +1259,7 @@ end_emac_rx_bdproc:
*/
static int emac_hw_enable(struct emac_priv *priv)
{
- u32 ch, val, mbp_enable, mac_control;
+ u32 val, mbp_enable, mac_control;
/* Soft reset */
emac_write(EMAC_SOFTRESET, 1);
@@ -2215,26 +1302,9 @@ static int emac_hw_enable(struct emac_priv *priv)
emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL);
priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF;
- val = emac_read(EMAC_TXCONTROL);
- val |= EMAC_TX_CONTROL_TX_ENABLE_VAL;
- emac_write(EMAC_TXCONTROL, val);
- val = emac_read(EMAC_RXCONTROL);
- val |= EMAC_RX_CONTROL_RX_ENABLE_VAL;
- emac_write(EMAC_RXCONTROL, val);
emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL);
- for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) {
- emac_write(EMAC_TXHDP(ch), 0);
- emac_write(EMAC_TXINTMASKSET, BIT(ch));
- }
- for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) {
- struct emac_rxch *rxch = priv->rxch[ch];
- emac_setmac(priv, ch, rxch->mac_addr);
- emac_write(EMAC_RXINTMASKSET, BIT(ch));
- rxch->queue_active = 1;
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(rxch->active_queue_head, priv));
- }
+ emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr);
/* Enable MII */
val = emac_read(EMAC_MACCONTROL);
@@ -2279,8 +1349,8 @@ static int emac_poll(struct napi_struct *napi, int budget)
mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
if (status & mask) {
- num_tx_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
- EMAC_DEF_TX_MAX_SERVICE);
+ num_tx_pkts = cpdma_chan_process(priv->txchan,
+ EMAC_DEF_TX_MAX_SERVICE);
} /* TX processing */
mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
@@ -2289,7 +1359,7 @@ static int emac_poll(struct napi_struct *napi, int budget)
mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
if (status & mask) {
- num_rx_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget);
+ num_rx_pkts = cpdma_chan_process(priv->rxchan, budget);
} /* RX processing */
mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT;
@@ -2348,79 +1418,6 @@ void emac_poll_controller(struct net_device *ndev)
}
#endif
-/* PHY/MII bus related */
-
-/* Wait until mdio is ready for next command */
-#define MDIO_WAIT_FOR_USER_ACCESS\
- while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
- MDIO_USERACCESS_GO) != 0)
-
-static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg)
-{
- unsigned int phy_data = 0;
- unsigned int phy_control;
-
- /* Wait until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
-
- phy_control = (MDIO_USERACCESS_GO |
- MDIO_USERACCESS_READ |
- ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
- ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
- (phy_data & MDIO_USERACCESS_DATA));
- emac_mdio_write(MDIO_USERACCESS(0), phy_control);
-
- /* Wait until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
-
- return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA;
-
-}
-
-static int emac_mii_write(struct mii_bus *bus, int phy_id,
- int phy_reg, u16 phy_data)
-{
-
- unsigned int control;
-
- /* until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
-
- control = (MDIO_USERACCESS_GO |
- MDIO_USERACCESS_WRITE |
- ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
- ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
- (phy_data & MDIO_USERACCESS_DATA));
- emac_mdio_write(MDIO_USERACCESS(0), control);
-
- return 0;
-}
-
-static int emac_mii_reset(struct mii_bus *bus)
-{
- unsigned int clk_div;
- int mdio_bus_freq = emac_bus_frequency;
-
- if (mdio_max_freq && mdio_bus_freq)
- clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
- else
- clk_div = 0xFF;
-
- clk_div &= MDIO_CONTROL_CLKDIV;
-
- /* Set enable and clock divider in MDIOControl */
- emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE));
-
- return 0;
-
-}
-
-static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, PHY_POLL };
-
-/* emac_driver: EMAC MII bus structure */
-
-static struct mii_bus *emac_mii;
-
static void emac_adjust_link(struct net_device *ndev)
{
struct emac_priv *priv = netdev_priv(ndev);
@@ -2485,6 +1482,11 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
return -EOPNOTSUPP;
}
+static int match_first_device(struct device *dev, void *data)
+{
+ return 1;
+}
+
/**
* emac_dev_open: EMAC device open
* @ndev: The DaVinci EMAC network adapter
@@ -2498,10 +1500,9 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
static int emac_dev_open(struct net_device *ndev)
{
struct device *emac_dev = &ndev->dev;
- u32 rc, cnt, ch;
- int phy_addr;
+ u32 cnt;
struct resource *res;
- int q, m;
+ int q, m, ret;
int i = 0;
int k = 0;
struct emac_priv *priv = netdev_priv(ndev);
@@ -2513,29 +1514,21 @@ static int emac_dev_open(struct net_device *ndev)
/* Configuration items */
priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN;
- /* Clear basic hardware */
- for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
- emac_write(EMAC_TXHDP(ch), 0);
- emac_write(EMAC_RXHDP(ch), 0);
- emac_write(EMAC_RXHDP(ch), 0);
- emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
- emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
- }
priv->mac_hash1 = 0;
priv->mac_hash2 = 0;
emac_write(EMAC_MACHASH1, 0);
emac_write(EMAC_MACHASH2, 0);
- /* multi ch not supported - open 1 TX, 1RX ch by default */
- rc = emac_init_txch(priv, EMAC_DEF_TX_CH);
- if (0 != rc) {
- dev_err(emac_dev, "DaVinci EMAC: emac_init_txch() failed");
- return rc;
- }
- rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr);
- if (0 != rc) {
- dev_err(emac_dev, "DaVinci EMAC: emac_init_rxch() failed");
- return rc;
+ for (i = 0; i < EMAC_DEF_RX_NUM_DESC; i++) {
+ struct sk_buff *skb = emac_rx_alloc(priv);
+
+ if (!skb)
+ break;
+
+ ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
+ skb_tailroom(skb), GFP_KERNEL);
+ if (WARN_ON(ret < 0))
+ break;
}
/* Request IRQ */
@@ -2560,28 +1553,28 @@ static int emac_dev_open(struct net_device *ndev)
emac_set_coalesce(ndev, &coal);
}
- /* find the first phy */
+ cpdma_ctlr_start(priv->dma);
+
priv->phydev = NULL;
- if (priv->phy_mask) {
- emac_mii_reset(priv->mii_bus);
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- if (priv->mii_bus->phy_map[phy_addr]) {
- priv->phydev = priv->mii_bus->phy_map[phy_addr];
- break;
- }
- }
+ /* use the first phy on the bus if pdata did not give us a phy id */
+ if (!priv->phy_id) {
+ struct device *phy;
- if (!priv->phydev) {
- printk(KERN_ERR "%s: no PHY found\n", ndev->name);
- return -1;
- }
+ phy = bus_find_device(&mdio_bus_type, NULL, NULL,
+ match_first_device);
+ if (phy)
+ priv->phy_id = dev_name(phy);
+ }
- priv->phydev = phy_connect(ndev, dev_name(&priv->phydev->dev),
- &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+ if (priv->phy_id) {
+ priv->phydev = phy_connect(ndev, priv->phy_id,
+ &emac_adjust_link, 0,
+ PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n",
- ndev->name);
+ dev_err(emac_dev, "could not connect to phy %s\n",
+ priv->phy_id);
+ priv->phydev = NULL;
return PTR_ERR(priv->phydev);
}
@@ -2589,12 +1582,13 @@ static int emac_dev_open(struct net_device *ndev)
priv->speed = 0;
priv->duplex = ~0;
- printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, id=%x)\n", ndev->name,
+ dev_info(emac_dev, "attached PHY driver [%s] "
+ "(mii_bus:phy_addr=%s, id=%x)\n",
priv->phydev->drv->name, dev_name(&priv->phydev->dev),
priv->phydev->phy_id);
- } else{
+ } else {
/* No PHY , fix the link, speed and duplex settings */
+ dev_notice(emac_dev, "no phy, defaulting to 100/full\n");
priv->link = 1;
priv->speed = SPEED_100;
priv->duplex = DUPLEX_FULL;
@@ -2607,7 +1601,7 @@ static int emac_dev_open(struct net_device *ndev)
if (netif_msg_drv(priv))
dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name);
- if (priv->phy_mask)
+ if (priv->phydev)
phy_start(priv->phydev);
return 0;
@@ -2648,10 +1642,7 @@ static int emac_dev_stop(struct net_device *ndev)
netif_carrier_off(ndev);
emac_int_disable(priv);
- emac_stop_txch(priv, EMAC_DEF_TX_CH);
- emac_stop_rxch(priv, EMAC_DEF_RX_CH);
- emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
- emac_cleanup_rxch(priv, EMAC_DEF_RX_CH);
+ cpdma_ctlr_stop(priv->dma);
emac_write(EMAC_SOFTRESET, 1);
if (priv->phydev)
@@ -2756,9 +1747,10 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
struct resource *res;
struct net_device *ndev;
struct emac_priv *priv;
- unsigned long size;
+ unsigned long size, hw_ram_addr;
struct emac_platform_data *pdata;
struct device *emac_dev;
+ struct cpdma_params dma_params;
/* obtain emac clock from kernel */
emac_clk = clk_get(&pdev->dev, NULL);
@@ -2782,8 +1774,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
priv->ndev = ndev;
priv->msg_enable = netif_msg_init(debug_level, DAVINCI_EMAC_DEBUG);
- spin_lock_init(&priv->tx_lock);
- spin_lock_init(&priv->rx_lock);
spin_lock_init(&priv->lock);
pdata = pdev->dev.platform_data;
@@ -2794,7 +1784,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
/* MAC addr and PHY mask , RMII enable info from platform_data */
memcpy(priv->mac_addr, pdata->mac_addr, 6);
- priv->phy_mask = pdata->phy_mask;
+ priv->phy_id = pdata->phy_id;
priv->rmii_en = pdata->rmii_en;
priv->version = pdata->version;
priv->int_enable = pdata->interrupt_enable;
@@ -2831,14 +1821,41 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
ndev->base_addr = (unsigned long)priv->remap_addr;
priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset;
- priv->ctrl_ram_size = pdata->ctrl_ram_size;
- priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
- if (pdata->hw_ram_addr)
- priv->hw_ram_addr = pdata->hw_ram_addr;
- else
- priv->hw_ram_addr = (u32 __force)res->start +
- pdata->ctrl_ram_offset;
+ hw_ram_addr = pdata->hw_ram_addr;
+ if (!hw_ram_addr)
+ hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset;
+
+ memset(&dma_params, 0, sizeof(dma_params));
+ dma_params.dev = emac_dev;
+ dma_params.dmaregs = priv->emac_base;
+ dma_params.rxthresh = priv->emac_base + 0x120;
+ dma_params.rxfree = priv->emac_base + 0x140;
+ dma_params.txhdp = priv->emac_base + 0x600;
+ dma_params.rxhdp = priv->emac_base + 0x620;
+ dma_params.txcp = priv->emac_base + 0x640;
+ dma_params.rxcp = priv->emac_base + 0x660;
+ dma_params.num_chan = EMAC_MAX_TXRX_CHANNELS;
+ dma_params.min_packet_size = EMAC_DEF_MIN_ETHPKTSIZE;
+ dma_params.desc_mem_phys = hw_ram_addr;
+ dma_params.desc_mem_size = pdata->ctrl_ram_size;
+ dma_params.desc_align = 16;
+
+ priv->dma = cpdma_ctlr_create(&dma_params);
+ if (!priv->dma) {
+ dev_err(emac_dev, "DaVinci EMAC: Error initializing DMA\n");
+ rc = -ENOMEM;
+ goto no_dma;
+ }
+
+ priv->txchan = cpdma_chan_create(priv->dma, tx_chan_num(EMAC_DEF_TX_CH),
+ emac_tx_handler);
+ priv->rxchan = cpdma_chan_create(priv->dma, rx_chan_num(EMAC_DEF_RX_CH),
+ emac_rx_handler);
+ if (WARN_ON(!priv->txchan || !priv->rxchan)) {
+ rc = -ENOMEM;
+ goto no_irq_res;
+ }
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
@@ -2871,32 +1888,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
}
- /* MII/Phy intialisation, mdio bus registration */
- emac_mii = mdiobus_alloc();
- if (emac_mii == NULL) {
- dev_err(emac_dev, "DaVinci EMAC: Error allocating mii_bus\n");
- rc = -ENOMEM;
- goto mdio_alloc_err;
- }
-
- priv->mii_bus = emac_mii;
- emac_mii->name = "emac-mii",
- emac_mii->read = emac_mii_read,
- emac_mii->write = emac_mii_write,
- emac_mii->reset = emac_mii_reset,
- emac_mii->irq = mii_irqs,
- emac_mii->phy_mask = ~(priv->phy_mask);
- emac_mii->parent = &pdev->dev;
- emac_mii->priv = priv->remap_addr + pdata->mdio_reg_offset;
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", priv->pdev->id);
- mdio_max_freq = pdata->mdio_max_freq;
- emac_mii->reset(emac_mii);
-
- /* Register the MII bus */
- rc = mdiobus_register(emac_mii);
- if (rc)
- goto mdiobus_quit;
-
if (netif_msg_probe(priv)) {
dev_notice(emac_dev, "DaVinci EMAC Probe found device "\
"(regs: %p, irq: %d)\n",
@@ -2904,13 +1895,15 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
}
return 0;
-mdiobus_quit:
- mdiobus_free(emac_mii);
-
netdev_reg_err:
-mdio_alloc_err:
clk_disable(emac_clk);
no_irq_res:
+ if (priv->txchan)
+ cpdma_chan_destroy(priv->txchan);
+ if (priv->rxchan)
+ cpdma_chan_destroy(priv->rxchan);
+ cpdma_ctlr_destroy(priv->dma);
+no_dma:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1);
iounmap(priv->remap_addr);
@@ -2938,8 +1931,12 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mdiobus_unregister(priv->mii_bus);
- mdiobus_free(priv->mii_bus);
+
+ if (priv->txchan)
+ cpdma_chan_destroy(priv->txchan);
+ if (priv->rxchan)
+ cpdma_chan_destroy(priv->rxchan);
+ cpdma_ctlr_destroy(priv->dma);
release_mem_region(res->start, res->end - res->start + 1);
diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c
new file mode 100644
index 000000000000..d34a53ae5a81
--- /dev/null
+++ b/drivers/net/davinci_mdio.c
@@ -0,0 +1,386 @@
+/*
+ * DaVinci MDIO Module driver
+ *
+ * Copyright (C) 2010 Texas Instruments.
+ *
+ * Shamelessly ripped out of davinci_emac.c, original copyrights follow:
+ *
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/davinci_emac.h>
+
+#define PHY_REG_MASK 0x1f
+#define PHY_ID_MASK 0x1f
+
+#define DEF_OUT_FREQ 2200000 /* 2.2 MHz */
+
+struct davinci_mdio_regs {
+ u32 version;
+ u32 control;
+#define CONTROL_IDLE BIT(31)
+#define CONTROL_ENABLE BIT(30)
+#define CONTROL_MAX_DIV (0xff)
+
+ u32 alive;
+ u32 link;
+ u32 linkintraw;
+ u32 linkintmasked;
+ u32 __reserved_0[2];
+ u32 userintraw;
+ u32 userintmasked;
+ u32 userintmaskset;
+ u32 userintmaskclr;
+ u32 __reserved_1[20];
+
+ struct {
+ u32 access;
+#define USERACCESS_GO BIT(31)
+#define USERACCESS_WRITE BIT(30)
+#define USERACCESS_ACK BIT(29)
+#define USERACCESS_READ (0)
+#define USERACCESS_DATA (0xffff)
+
+ u32 physel;
+ } user[0];
+};
+
+struct mdio_platform_data default_pdata = {
+ .bus_freq = DEF_OUT_FREQ,
+};
+
+struct davinci_mdio_data {
+ struct mdio_platform_data pdata;
+ struct davinci_mdio_regs __iomem *regs;
+ spinlock_t lock;
+ struct clk *clk;
+ struct device *dev;
+ struct mii_bus *bus;
+ bool suspended;
+};
+
+/* wait until hardware is ready for another user access */
+static inline u32 wait_for_user_access(struct davinci_mdio_data *data)
+{
+ struct davinci_mdio_regs __iomem *regs = data->regs;
+ u32 reg;
+
+ while ((reg = __raw_readl(&regs->user[0].access)) & USERACCESS_GO)
+ ;
+
+ return reg;
+}
+
+/* wait until hardware state machine is idle */
+static inline void wait_for_idle(struct davinci_mdio_data *data)
+{
+ struct davinci_mdio_regs __iomem *regs = data->regs;
+
+ while ((__raw_readl(&regs->control) & CONTROL_IDLE) == 0)
+ ;
+}
+
+static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
+{
+ struct davinci_mdio_data *data = bus->priv;
+ u32 reg;
+
+ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+ return -EINVAL;
+
+ spin_lock(&data->lock);
+
+ if (data->suspended) {
+ spin_unlock(&data->lock);
+ return -ENODEV;
+ }
+
+ wait_for_user_access(data);
+ reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
+ (phy_id << 16));
+ __raw_writel(reg, &data->regs->user[0].access);
+ reg = wait_for_user_access(data);
+ spin_unlock(&data->lock);
+
+ return (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO;
+}
+
+static int davinci_mdio_write(struct mii_bus *bus, int phy_id,
+ int phy_reg, u16 phy_data)
+{
+ struct davinci_mdio_data *data = bus->priv;
+ u32 reg;
+
+ if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+ return -EINVAL;
+
+ spin_lock(&data->lock);
+
+ if (data->suspended) {
+ spin_unlock(&data->lock);
+ return -ENODEV;
+ }
+
+ wait_for_user_access(data);
+ reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
+ (phy_id << 16) | (phy_data & USERACCESS_DATA));
+ __raw_writel(reg, &data->regs->user[0].access);
+ wait_for_user_access(data);
+ spin_unlock(&data->lock);
+
+ return 0;
+}
+
+static int __devinit davinci_mdio_probe(struct platform_device *pdev)
+{
+ struct mdio_platform_data *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+ struct davinci_mdio_data *data;
+ struct resource *res;
+ u32 mdio_in_freq, mdio_out_freq, div, phy_mask, ver;
+ struct phy_device *phy;
+ int ret, addr;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ dev_err(dev, "failed to alloc device data\n");
+ return -ENOMEM;
+ }
+
+ data->pdata = pdata ? (*pdata) : default_pdata;
+
+ data->bus = mdiobus_alloc();
+ if (!data->bus) {
+ dev_err(dev, "failed to alloc mii bus\n");
+ ret = -ENOMEM;
+ goto bail_out;
+ }
+
+ data->bus->name = dev_name(dev);
+ data->bus->read = davinci_mdio_read,
+ data->bus->write = davinci_mdio_write,
+ data->bus->parent = dev;
+ data->bus->priv = data;
+ snprintf(data->bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
+
+ data->clk = clk_get(dev, NULL);
+ if (IS_ERR(data->clk)) {
+ data->clk = NULL;
+ dev_err(dev, "failed to get device clock\n");
+ ret = PTR_ERR(data->clk);
+ goto bail_out;
+ }
+
+ clk_enable(data->clk);
+
+ dev_set_drvdata(dev, data);
+ data->dev = dev;
+ spin_lock_init(&data->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "could not find register map resource\n");
+ ret = -ENOENT;
+ goto bail_out;
+ }
+
+ res = devm_request_mem_region(dev, res->start, resource_size(res),
+ dev_name(dev));
+ if (!res) {
+ dev_err(dev, "could not allocate register map resource\n");
+ ret = -ENXIO;
+ goto bail_out;
+ }
+
+ data->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+ if (!data->regs) {
+ dev_err(dev, "could not map mdio registers\n");
+ ret = -ENOMEM;
+ goto bail_out;
+ }
+
+ mdio_in_freq = clk_get_rate(data->clk);
+ div = (mdio_in_freq / data->pdata.bus_freq) - 1;
+ if (div > CONTROL_MAX_DIV)
+ div = CONTROL_MAX_DIV;
+ mdio_out_freq = mdio_in_freq / (div + 1);
+
+ /* set enable and clock divider */
+ __raw_writel(div | CONTROL_ENABLE, &data->regs->control);
+
+ /*
+ * wait for scan logic to settle:
+ * the scan time consists of (a) a large fixed component, and (b) a
+ * small component that varies with the mii bus frequency. These
+ * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
+ * silicon. Since the effect of (b) was found to be largely
+ * negligible, we keep things simple here.
+ */
+ mdelay(1);
+
+ /* dump hardware version info */
+ ver = __raw_readl(&data->regs->version);
+ dev_info(dev, "davinci mdio revision %d.%d\n",
+ (ver >> 8) & 0xff, ver & 0xff);
+
+ /* get phy mask from the alive register */
+ phy_mask = __raw_readl(&data->regs->alive);
+ if (phy_mask) {
+ /* restrict mdio bus to live phys only */
+ dev_info(dev, "detected phy mask %x\n", ~phy_mask);
+ phy_mask = ~phy_mask;
+ } else {
+ /* desperately scan all phys */
+ dev_warn(dev, "failed to detect live phys, scanning all\n");
+ phy_mask = 0;
+ }
+ data->bus->phy_mask = phy_mask;
+
+ /* register the mii bus */
+ ret = mdiobus_register(data->bus);
+ if (ret)
+ goto bail_out;
+
+ /* scan and dump the bus */
+ for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+ phy = data->bus->phy_map[addr];
+ if (phy) {
+ dev_info(dev, "phy[%d]: device %s, driver %s\n",
+ phy->addr, dev_name(&phy->dev),
+ phy->drv ? phy->drv->name : "unknown");
+ }
+ }
+
+ return 0;
+
+bail_out:
+ if (data->bus)
+ mdiobus_free(data->bus);
+
+ if (data->clk) {
+ clk_disable(data->clk);
+ clk_put(data->clk);
+ }
+
+ kfree(data);
+
+ return ret;
+}
+
+static int __devexit davinci_mdio_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct davinci_mdio_data *data = dev_get_drvdata(dev);
+
+ if (data->bus)
+ mdiobus_free(data->bus);
+
+ if (data->clk) {
+ clk_disable(data->clk);
+ clk_put(data->clk);
+ }
+
+ dev_set_drvdata(dev, NULL);
+
+ kfree(data);
+
+ return 0;
+}
+
+static int davinci_mdio_suspend(struct device *dev)
+{
+ struct davinci_mdio_data *data = dev_get_drvdata(dev);
+ u32 ctrl;
+
+ spin_lock(&data->lock);
+
+ /* shutdown the scan state machine */
+ ctrl = __raw_readl(&data->regs->control);
+ ctrl &= ~CONTROL_ENABLE;
+ __raw_writel(ctrl, &data->regs->control);
+ wait_for_idle(data);
+
+ if (data->clk)
+ clk_disable(data->clk);
+
+ data->suspended = true;
+ spin_unlock(&data->lock);
+
+ return 0;
+}
+
+static int davinci_mdio_resume(struct device *dev)
+{
+ struct davinci_mdio_data *data = dev_get_drvdata(dev);
+ u32 ctrl;
+
+ spin_lock(&data->lock);
+ if (data->clk)
+ clk_enable(data->clk);
+
+ /* restart the scan state machine */
+ ctrl = __raw_readl(&data->regs->control);
+ ctrl |= CONTROL_ENABLE;
+ __raw_writel(ctrl, &data->regs->control);
+
+ data->suspended = false;
+ spin_unlock(&data->lock);
+
+ return 0;
+}
+
+static const struct dev_pm_ops davinci_mdio_pm_ops = {
+ .suspend = davinci_mdio_suspend,
+ .resume = davinci_mdio_resume,
+};
+
+static struct platform_driver davinci_mdio_driver = {
+ .driver = {
+ .name = "davinci_mdio",
+ .owner = THIS_MODULE,
+ .pm = &davinci_mdio_pm_ops,
+ },
+ .probe = davinci_mdio_probe,
+ .remove = __devexit_p(davinci_mdio_remove),
+};
+
+static int __init davinci_mdio_init(void)
+{
+ return platform_driver_register(&davinci_mdio_driver);
+}
+device_initcall(davinci_mdio_init);
+
+static void __exit davinci_mdio_exit(void)
+{
+ platform_driver_unregister(&davinci_mdio_driver);
+}
+module_exit(davinci_mdio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DaVinci MDIO driver");
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index d7de376d7178..219eb5ad5c12 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1255,7 +1255,7 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type)
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
ret = register_netdev(dev);
if (ret) {
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 44c0694c1f4e..91b3846ffc8a 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1487,7 +1487,7 @@ static void __init depca_platform_probe (void)
if (!pldev->dev.driver) {
/* The driver was not bound to this device, there was
* no hardware at this address. Unregister it, as the
- * release fuction will take care of freeing the
+ * release function will take care of freeing the
* allocated structure */
depca_io_ports[i].device = NULL;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index a2f238d20caa..e1a8216ff692 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -465,7 +465,7 @@ rio_open (struct net_device *dev)
init_timer (&np->timer);
np->timer.expires = jiffies + 1*HZ;
np->timer.data = (unsigned long) dev;
- np->timer.function = &rio_timer;
+ np->timer.function = rio_timer;
add_timer (&np->timer);
/* Start Tx/Rx */
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 4fd6b2b4554b..9f6aeefa06bf 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1056,7 +1056,7 @@ dm9000_rx(struct net_device *dev)
if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
netif_rx(skb);
dev->stats.rx_packets++;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5cc39ed289c6..8d9269d12a67 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -790,6 +790,70 @@ static const struct net_device_ops e1000_netdev_ops = {
};
/**
+ * e1000_init_hw_struct - initialize members of hw struct
+ * @adapter: board private struct
+ * @hw: structure used by e1000_hw.c
+ *
+ * Factors out initialization of the e1000_hw struct to its own function
+ * that can be called very early at init (just after struct allocation).
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ * Returns negative error codes if MAC type setup fails.
+ */
+static int e1000_init_hw_struct(struct e1000_adapter *adapter,
+ struct e1000_hw *hw)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ /* PCI config space info */
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+ hw->revision_id = pdev->revision;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+ hw->max_frame_size = adapter->netdev->mtu +
+ ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+ hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+
+ /* identify the MAC */
+ if (e1000_set_mac_type(hw)) {
+ e_err(probe, "Unknown MAC Type\n");
+ return -EIO;
+ }
+
+ switch (hw->mac_type) {
+ default:
+ break;
+ case e1000_82541:
+ case e1000_82547:
+ case e1000_82541_rev_2:
+ case e1000_82547_rev_2:
+ hw->phy_init_script = 1;
+ break;
+ }
+
+ e1000_set_media_type(hw);
+ e1000_get_bus_info(hw);
+
+ hw->wait_autoneg_complete = false;
+ hw->tbi_compatibility_en = true;
+ hw->adaptive_ifs = true;
+
+ /* Copper options */
+
+ if (hw->media_type == e1000_media_type_copper) {
+ hw->mdix = AUTO_ALL_MODES;
+ hw->disable_polarity_correction = false;
+ hw->master_slave = E1000_MASTER_SLAVE;
+ }
+
+ return 0;
+}
+
+/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in e1000_pci_tbl
@@ -826,22 +890,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
return err;
- if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
- !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
- pci_using_dac = 1;
- } else {
- err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (err) {
- err = dma_set_coherent_mask(&pdev->dev,
- DMA_BIT_MASK(32));
- if (err) {
- pr_err("No usable DMA config, aborting\n");
- goto err_dma;
- }
- }
- pci_using_dac = 0;
- }
-
err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
if (err)
goto err_pci_reg;
@@ -885,6 +933,32 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
}
+ /* make ready for any if (hw->...) below */
+ err = e1000_init_hw_struct(adapter, hw);
+ if (err)
+ goto err_sw_init;
+
+ /*
+ * there is a workaround being applied below that limits
+ * 64-bit DMA addresses to 64-bit hardware. There are some
+ * 32-bit adapters that Tx hang when given 64-bit DMA addresses
+ */
+ pci_using_dac = 0;
+ if ((hw->bus_type == e1000_bus_type_pcix) &&
+ !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+ /*
+ * according to DMA-API-HOWTO, coherent calls will always
+ * succeed if the set call did
+ */
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+ pci_using_dac = 1;
+ } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ } else {
+ pr_err("No usable DMA config, aborting\n");
+ goto err_dma;
+ }
+
netdev->netdev_ops = &e1000_netdev_ops;
e1000_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;
@@ -959,18 +1033,16 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (!is_valid_ether_addr(netdev->perm_addr))
e_err(probe, "Invalid MAC Address\n");
- e1000_get_bus_info(hw);
-
init_timer(&adapter->tx_fifo_stall_timer);
- adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
+ adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall;
adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &e1000_watchdog;
+ adapter->watchdog_timer.function = e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.function = e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, e1000_reset_task);
@@ -1072,6 +1144,7 @@ err_eeprom:
iounmap(hw->flash_address);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+err_dma:
err_sw_init:
iounmap(hw->hw_addr);
err_ioremap:
@@ -1079,7 +1152,6 @@ err_ioremap:
err_alloc_etherdev:
pci_release_selected_regions(pdev, bars);
err_pci_reg:
-err_dma:
pci_disable_device(pdev);
return err;
}
@@ -1131,62 +1203,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
* @adapter: board private structure to initialize
*
* e1000_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
+ * e1000_init_hw_struct MUST be called before this function
**/
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
{
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
-
- /* PCI config space info */
-
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_id = pdev->subsystem_device;
- hw->revision_id = pdev->revision;
-
- pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
- hw->max_frame_size = netdev->mtu +
- ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
-
- /* identify the MAC */
-
- if (e1000_set_mac_type(hw)) {
- e_err(probe, "Unknown MAC Type\n");
- return -EIO;
- }
-
- switch (hw->mac_type) {
- default:
- break;
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- hw->phy_init_script = 1;
- break;
- }
-
- e1000_set_media_type(hw);
-
- hw->wait_autoneg_complete = false;
- hw->tbi_compatibility_en = true;
- hw->adaptive_ifs = true;
-
- /* Copper options */
-
- if (hw->media_type == e1000_media_type_copper) {
- hw->mdix = AUTO_ALL_MODES;
- hw->disable_polarity_correction = false;
- hw->master_slave = E1000_MASTER_SLAVE;
- }
adapter->num_tx_queues = 1;
adapter->num_rx_queues = 1;
@@ -3552,7 +3574,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
struct e1000_hw *hw = &adapter->hw;
u16 status = (u16)status_err;
u8 errors = (u8)(status_err >> 24);
- skb->ip_summed = CHECKSUM_NONE;
+
+ skb_checksum_none_assert(skb);
/* 82543 or newer only */
if (unlikely(hw->mac_type < e1000_82543)) return;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 2b8ef44bd2b1..e2c7e0d767b1 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -475,7 +475,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
{
u16 status = (u16)status_err;
u8 errors = (u8)(status_err >> 24);
- skb->ip_summed = CHECKSUM_NONE;
+
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set */
if (status & E1000_RXD_STAT_IXSM)
@@ -3411,22 +3412,16 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_MSI_TEST_FAILED) {
adapter->int_mode = E1000E_INT_MODE_LEGACY;
- err = -EIO;
- e_info("MSI interrupt test failed!\n");
- }
+ e_info("MSI interrupt test failed, using legacy interrupt.\n");
+ } else
+ e_dbg("MSI interrupt test succeeded!\n");
free_irq(adapter->pdev->irq, netdev);
pci_disable_msi(adapter->pdev);
- if (err == -EIO)
- goto msi_test_failed;
-
- /* okay so the test worked, restore settings */
- e_dbg("MSI interrupt test succeeded!\n");
msi_test_failed:
e1000e_set_interrupt_capability(adapter);
- e1000_request_irq(adapter);
- return err;
+ return e1000_request_irq(adapter);
}
/**
@@ -3458,21 +3453,6 @@ static int e1000_test_msi(struct e1000_adapter *adapter)
pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
}
- /* success ! */
- if (!err)
- return 0;
-
- /* EIO means MSI test failed */
- if (err != -EIO)
- return err;
-
- /* back to INTx mode */
- e_warn("MSI interrupt test failed, using legacy interrupt.\n");
-
- e1000_free_irq(adapter);
-
- err = e1000_request_irq(adapter);
-
return err;
}
@@ -5745,11 +5725,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &e1000_watchdog;
+ adapter->watchdog_timer.function = e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &e1000_update_phy_info;
+ adapter->phy_info_timer.function = e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->reset_task, e1000_reset_task);
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 8d97f168f018..7c826319ee5a 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1457,11 +1457,11 @@ hardware_send_packet(struct net_device *dev, void *buf, short length)
if (net_debug > 5)
printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
- /* determine how much of the transmit buffer space is available */
- if (lp->tx_end > lp->tx_start)
+ /* determine how much of the transmit buffer space is available */
+ if (lp->tx_end > lp->tx_start)
tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start);
- else if (lp->tx_end < lp->tx_start)
- tx_available = lp->tx_start - lp->tx_end;
+ else if (lp->tx_end < lp->tx_start)
+ tx_available = lp->tx_start - lp->tx_end;
else tx_available = lp->xmt_ram;
if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) {
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index a333b42111b8..043d99013056 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -180,7 +180,7 @@ static void ehea_update_firmware_handles(void)
num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
if (num_fw_handles) {
- arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+ arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL);
if (!arr)
goto out; /* Keep the existing array */
} else
@@ -265,7 +265,7 @@ static void ehea_update_bcmc_registrations(void)
}
if (num_registrations) {
- arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
+ arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC);
if (!arr)
goto out; /* Keep the existing array */
} else
@@ -3721,7 +3721,7 @@ int __init ehea_module_init(void)
if (ret)
ehea_info("failed registering memory remove notifier");
- ret = crash_shutdown_register(&ehea_crash_handler);
+ ret = crash_shutdown_register(ehea_crash_handler);
if (ret)
ehea_info("failed registering crash handler");
@@ -3746,7 +3746,7 @@ out3:
out2:
unregister_memory_notifier(&ehea_mem_nb);
unregister_reboot_notifier(&ehea_reboot_nb);
- crash_shutdown_unregister(&ehea_crash_handler);
+ crash_shutdown_unregister(ehea_crash_handler);
out:
return ret;
}
@@ -3759,7 +3759,7 @@ static void __exit ehea_module_exit(void)
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
- ret = crash_shutdown_unregister(&ehea_crash_handler);
+ ret = crash_shutdown_unregister(ehea_crash_handler);
if (ret)
ehea_info("failed unregistering crash handler");
unregister_memory_notifier(&ehea_mem_nb);
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index f239aa8c6f4c..75869ed7226f 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -32,7 +32,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.4.1.1"
+#define DRV_VERSION "1.4.1.2"
#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9aab85366d21..711077a2e345 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -911,7 +911,9 @@ static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p)
static int enic_set_mac_address(struct net_device *netdev, void *p)
{
- return -EOPNOTSUPP;
+ struct sockaddr *saddr = p;
+
+ return enic_set_mac_addr(netdev, (char *)saddr->sa_data);
}
static int enic_dev_packet_filter(struct enic *enic, int directed,
@@ -2152,17 +2154,6 @@ void enic_dev_deinit(struct enic *enic)
enic_clear_intr_mode(enic);
}
-static int enic_dev_stats_clear(struct enic *enic)
-{
- int err;
-
- spin_lock(&enic->devcmd_lock);
- err = vnic_dev_stats_clear(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
-
- return err;
-}
-
int enic_dev_init(struct enic *enic)
{
struct device *dev = enic_get_dev(enic);
@@ -2205,10 +2196,6 @@ int enic_dev_init(struct enic *enic)
enic_init_vnic_resources(enic);
- /* Clear LIF stats
- */
- enic_dev_stats_clear(enic);
-
err = enic_set_rq_alloc_buf(enic);
if (err) {
dev_err(dev, "Failed to set RQ buffer allocator, aborting\n");
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 6a5b578a69e1..08d5d42da260 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -74,6 +74,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
struct vnic_dev_bar *bar, unsigned int num_bars)
{
struct vnic_resource_header __iomem *rh;
+ struct mgmt_barmap_hdr __iomem *mrh;
struct vnic_resource __iomem *r;
u8 type;
@@ -85,22 +86,32 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
return -EINVAL;
}
- rh = bar->vaddr;
+ rh = bar->vaddr;
+ mrh = bar->vaddr;
if (!rh) {
pr_err("vNIC BAR0 res hdr not mem-mapped\n");
return -EINVAL;
}
- if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||
- ioread32(&rh->version) != VNIC_RES_VERSION) {
- pr_err("vNIC BAR0 res magic/version error "
- "exp (%lx/%lx) curr (%x/%x)\n",
+ /* Check for mgmt vnic in addition to normal vnic */
+ if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) ||
+ (ioread32(&rh->version) != VNIC_RES_VERSION)) {
+ if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) ||
+ (ioread32(&mrh->version) != MGMTVNIC_VERSION)) {
+ pr_err("vNIC BAR0 res magic/version error "
+ "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n",
VNIC_RES_MAGIC, VNIC_RES_VERSION,
+ MGMTVNIC_MAGIC, MGMTVNIC_VERSION,
ioread32(&rh->magic), ioread32(&rh->version));
- return -EINVAL;
+ return -EINVAL;
+ }
}
- r = (struct vnic_resource __iomem *)(rh + 1);
+ if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC)
+ r = (struct vnic_resource __iomem *)(mrh + 1);
+ else
+ r = (struct vnic_resource __iomem *)(rh + 1);
+
while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 20661755df6b..9abb3d51dea1 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -238,6 +238,18 @@ enum vnic_devcmd_cmd {
* out: (u32)a0=status of proxied cmd
* a1-a15=out args of proxied cmd */
CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42),
+
+ /*
+ * As for BY_BDF except a0 is index of hvnlink subordinate vnic
+ * or SR-IOV virtual vnic */
+ CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43),
+
+ /*
+ * in: (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in
+ * (u32)a1=length of buffer in a0
+ * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV
+ * (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */
+ CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
};
/* flags for CMD_OPEN */
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 3b3291248956..e8740e3704e4 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -30,7 +30,7 @@ struct vnic_enet_config {
u32 wq_desc_count;
u32 rq_desc_count;
u16 mtu;
- u16 intr_timer;
+ u16 intr_timer_deprecated;
u8 intr_timer_type;
u8 intr_mode;
char devname[16];
diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h
index 810287beff14..e0a73f1ca6f4 100644
--- a/drivers/net/enic/vnic_resource.h
+++ b/drivers/net/enic/vnic_resource.h
@@ -22,6 +22,11 @@
#define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */
#define VNIC_RES_VERSION 0x00000000L
+#define MGMTVNIC_MAGIC 0x544d474dL /* 'MGMT' */
+#define MGMTVNIC_VERSION 0x00000000L
+
+/* The MAC address assigned to the CFG vNIC is fixed. */
+#define MGMTVNIC_MAC { 0x02, 0x00, 0x54, 0x4d, 0x47, 0x4d }
/* vNIC resource types */
enum vnic_res_type {
@@ -52,6 +57,14 @@ struct vnic_resource_header {
u32 version;
};
+struct mgmt_barmap_hdr {
+ u32 magic; /* magic number */
+ u32 version; /* header format version */
+ u16 lif; /* loopback lif for mgmt frames */
+ u16 pci_slot; /* installed pci slot */
+ char serial[16]; /* card serial number */
+};
+
struct vnic_resource {
u8 type;
u8 bar;
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index dbb2aca258b9..b236d7cbc137 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -77,8 +77,10 @@ void vnic_rq_free(struct vnic_rq *rq)
vnic_dev_free_desc_ring(vdev, &rq->ring);
for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) {
- kfree(rq->bufs[i]);
- rq->bufs[i] = NULL;
+ if (rq->bufs[i]) {
+ kfree(rq->bufs[i]);
+ rq->bufs[i] = NULL;
+ }
}
rq->ctrl = NULL;
diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c
index 197c9d24af82..4725b79de0ef 100644
--- a/drivers/net/enic/vnic_vic.c
+++ b/drivers/net/enic/vnic_vic.c
@@ -54,8 +54,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
if (!vp || !value)
return -EINVAL;
- if (ntohl(vp->length) + sizeof(*tlv) + length >
- VIC_PROVINFO_MAX_TLV_DATA)
+ if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) +
+ length > VIC_PROVINFO_MAX_TLV_DATA)
return -ENOMEM;
tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
@@ -66,7 +66,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
memcpy(tlv->value, value, length);
vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
- vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length);
+ vp->length = htonl(ntohl(vp->length) +
+ offsetof(struct vic_provinfo_tlv, value) + length);
return 0;
}
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index 122e33bcc578..4b2a6c6a569b 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -77,8 +77,10 @@ void vnic_wq_free(struct vnic_wq *wq)
vnic_dev_free_desc_ring(vdev, &wq->ring);
for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) {
- kfree(wq->bufs[i]);
- wq->bufs[i] = NULL;
+ if (wq->bufs[i]) {
+ kfree(wq->bufs[i]);
+ wq->bufs[i] = NULL;
+ }
}
wq->ctrl = NULL;
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 57c8ac0ef3f1..32543a300b81 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -758,7 +758,7 @@ static int epic_open(struct net_device *dev)
init_timer(&ep->timer);
ep->timer.expires = jiffies + 3*HZ;
ep->timer.data = (unsigned long)dev;
- ep->timer.function = &epic_timer; /* timer handler */
+ ep->timer.function = epic_timer; /* timer handler */
add_timer(&ep->timer);
return 0;
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 6d653c459c1f..c5a2fe099a8d 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -806,11 +806,6 @@ static void ethoc_tx_timeout(struct net_device *dev)
ethoc_interrupt(dev->irq, dev);
}
-static struct net_device_stats *ethoc_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ethoc *priv = netdev_priv(dev);
@@ -863,7 +858,6 @@ static const struct net_device_ops ethoc_netdev_ops = {
.ndo_set_multicast_list = ethoc_set_multicast_list,
.ndo_change_mtu = ethoc_change_mtu,
.ndo_tx_timeout = ethoc_tx_timeout,
- .ndo_get_stats = ethoc_stats,
.ndo_start_xmit = ethoc_start_xmit,
};
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index d7e8f6b8f4cf..dd54abe2f710 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -915,14 +915,14 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = RUN_AT(3 * HZ);
np->timer.data = (unsigned long) dev;
- np->timer.function = &netdev_timer;
+ np->timer.function = netdev_timer;
/* timer handler */
add_timer(&np->timer);
init_timer(&np->reset_timer);
np->reset_timer.data = (unsigned long) dev;
- np->reset_timer.function = &reset_timer;
+ np->reset_timer.function = reset_timer;
np->reset_timer_armed = 0;
return 0;
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index e3e10b4add9c..e9f5d030bc26 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -771,11 +771,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
/* ethtool interface */
-static void mpc52xx_fec_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRIVER_NAME);
-}
static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
@@ -810,7 +805,6 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level)
}
static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {
- .get_drvinfo = mpc52xx_fec_get_drvinfo,
.get_settings = mpc52xx_fec_get_settings,
.set_settings = mpc52xx_fec_set_settings,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 4da05b1b445c..6a44fe411589 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5440,13 +5440,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
init_timer(&np->oom_kick);
np->oom_kick.data = (unsigned long) dev;
- np->oom_kick.function = &nv_do_rx_refill; /* timer handler */
+ np->oom_kick.function = nv_do_rx_refill; /* timer handler */
init_timer(&np->nic_poll);
np->nic_poll.data = (unsigned long) dev;
- np->nic_poll.function = &nv_do_nic_poll; /* timer handler */
+ np->nic_poll.function = nv_do_nic_poll; /* timer handler */
init_timer(&np->stats_poll);
np->stats_poll.data = (unsigned long) dev;
- np->stats_poll.function = &nv_do_stats_poll; /* timer handler */
+ np->stats_poll.function = nv_do_stats_poll; /* timer handler */
err = pci_enable_device(pci_dev);
if (err)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index d6e3111959ab..d684f187de57 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1036,7 +1036,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev,
ndev = alloc_etherdev(privsize);
if (!ndev) {
ret = -ENOMEM;
- goto out_free_fpi;
+ goto out_put;
}
SET_NETDEV_DEV(ndev, &ofdev->dev);
@@ -1099,6 +1099,7 @@ out_cleanup_data:
out_free_dev:
free_netdev(ndev);
dev_set_drvdata(&ofdev->dev, NULL);
+out_put:
of_node_put(fpi->phy_node);
out_free_fpi:
kfree(fpi);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 4f7c3f3ca234..f30adbf86bb2 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1859,7 +1859,7 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
printk(KERN_ERR "%s: Can't get IRQ %d\n",
dev->name, grp->interruptError);
- goto err_irq_fail;
+ goto err_irq_fail;
}
if ((err = request_irq(grp->interruptTransmit, gfar_transmit,
@@ -2048,7 +2048,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 bufaddr;
unsigned long flags;
unsigned int nr_frags, nr_txbds, length;
- union skb_shared_tx *shtx;
/*
* TOE=1 frames larger than 2500 bytes may see excess delays
@@ -2069,10 +2068,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txq = netdev_get_tx_queue(dev, rq);
base = tx_queue->tx_bd_base;
regs = tx_queue->grp->regs;
- shtx = skb_tx(skb);
/* check if time stamp should be generated */
- if (unlikely(shtx->hardware && priv->hwts_tx_en))
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+ priv->hwts_tx_en))
do_tstamp = 1;
/* make space for additional header when fcb is needed */
@@ -2174,7 +2173,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Setup tx hardware time stamping if requested */
if (unlikely(do_tstamp)) {
- shtx->in_progress = 1;
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
if (fcb == NULL)
fcb = gfar_add_fcb(skb);
fcb->ptp = 1;
@@ -2446,7 +2445,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
int howmany = 0;
u32 lstatus;
size_t buflen;
- union skb_shared_tx *shtx;
rx_queue = priv->rx_queue[tx_queue->qindex];
bdp = tx_queue->dirty_tx;
@@ -2461,8 +2459,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
* When time stamping, one additional TxBD must be freed.
* Also, we need to dma_unmap_single() the TxPAL.
*/
- shtx = skb_tx(skb);
- if (unlikely(shtx->in_progress))
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
nr_txbds = frags + 2;
else
nr_txbds = frags + 1;
@@ -2476,7 +2473,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
(lstatus & BD_LENGTH_MASK))
break;
- if (unlikely(shtx->in_progress)) {
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
next = next_txbd(bdp, base, tx_ring_size);
buflen = next->length + GMAC_FCB_LEN;
} else
@@ -2485,7 +2482,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
buflen, DMA_TO_DEVICE);
- if (unlikely(shtx->in_progress)) {
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
struct skb_shared_hwtstamps shhwtstamps;
u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7);
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
@@ -2657,7 +2654,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index f15c64f1cd38..27d6960ce09e 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -893,7 +893,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, dev);
dev->stats.rx_packets++;
@@ -1547,10 +1547,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev, const struct
dev->netdev_ops = &greth_netdev_ops;
dev->ethtool_ops = &greth_ethtool_ops;
- if (register_netdev(dev)) {
+ err = register_netdev(dev);
+ if (err) {
if (netif_msg_probe(greth))
dev_err(greth->dev, "netdevice registration failed.\n");
- err = -ENOMEM;
goto error5;
}
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 49aac7027fbb..9a6485892b3d 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1004,7 +1004,7 @@ static int hamachi_open(struct net_device *dev)
init_timer(&hmp->timer);
hmp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */
hmp->timer.data = (unsigned long)dev;
- hmp->timer.function = &hamachi_timer; /* timer handler */
+ hmp->timer.function = hamachi_timer; /* timer handler */
add_timer(&hmp->timer);
return 0;
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 9f64c8637208..33655814448e 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1069,7 +1069,8 @@ static void scc_tx_done(struct scc_channel *scc)
case KISS_DUPLEX_LINK:
scc->stat.tx_state = TXS_IDLE2;
if (scc->kiss.idletime != TIMER_OFF)
- scc_start_tx_timer(scc, t_idle, scc->kiss.idletime*100);
+ scc_start_tx_timer(scc, t_idle,
+ scc->kiss.idletime*100);
break;
case KISS_DUPLEX_OPTIMA:
scc_notify(scc, HWEV_ALL_SENT);
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 86ececd3c658..d15d2f2ba78e 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -204,10 +204,10 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
ei_status.rx_start_page = HP_START_PG + TX_PAGES;
ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;
- ei_status.reset_8390 = &hp_reset_8390;
- ei_status.get_8390_hdr = &hp_get_8390_hdr;
- ei_status.block_input = &hp_block_input;
- ei_status.block_output = &hp_block_output;
+ ei_status.reset_8390 = hp_reset_8390;
+ ei_status.get_8390_hdr = hp_get_8390_hdr;
+ ei_status.block_input = hp_block_input;
+ ei_status.block_output = hp_block_output;
hp_init_card(dev);
retval = register_netdev(dev);
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 07d8e5b634f3..c5ef62ceb840 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -155,10 +155,10 @@ static int __devinit hydra_init(struct zorro_dev *z)
ei_status.rx_start_page = start_page + TX_PAGES;
- ei_status.reset_8390 = &hydra_reset_8390;
- ei_status.block_input = &hydra_block_input;
- ei_status.block_output = &hydra_block_output;
- ei_status.get_8390_hdr = &hydra_get_8390_hdr;
+ ei_status.reset_8390 = hydra_reset_8390;
+ ei_status.block_input = hydra_block_input;
+ ei_status.block_output = hydra_block_output;
+ ei_status.get_8390_hdr = hydra_get_8390_hdr;
ei_status.reg_offset = hydra_offsets;
dev->netdev_ops = &hydra_netdev_ops;
@@ -173,9 +173,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
zorro_set_drvdata(z, dev);
- printk(KERN_INFO "%s: Hydra at 0x%08llx, address "
- "%pM (hydra.c " HYDRA_VERSION ")\n",
- dev->name, (unsigned long long)z->resource.start, dev->dev_addr);
+ pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n",
+ dev->name, &z->resource, dev->dev_addr);
return 0;
}
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index 294ccfb427cf..0037a696cd0a 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -602,7 +602,7 @@ static void irqrx_handler(struct net_device *dev)
/* set up skb fields */
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* bookkeeping */
dev->stats.rx_packets++;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 4734c939ad03..b3e157ed6776 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1,122 +1,84 @@
-/**************************************************************************/
-/* */
-/* IBM eServer i/pSeries Virtual Ethernet Device Driver */
-/* Copyright (C) 2003 IBM Corp. */
-/* Originally written by Dave Larson (larson1@us.ibm.com) */
-/* Maintained by Santiago Leon (santil@us.ibm.com) */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */
-/* USA */
-/* */
-/* This module contains the implementation of a virtual ethernet device */
-/* for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN */
-/* option of the RS/6000 Platform Architechture to interface with virtual */
-/* ethernet NICs that are presented to the partition by the hypervisor. */
-/* */
-/**************************************************************************/
/*
- TODO:
- - add support for sysfs
- - possibly remove procfs support
-*/
+ * IBM Power Virtual Ethernet Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2003, 2010
+ *
+ * Authors: Dave Larson <larson1@us.ibm.com>
+ * Santiago Leon <santil@linux.vnet.ibm.com>
+ * Brian King <brking@linux.vnet.ibm.com>
+ * Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Anton Blanchard <anton@au.ibm.com>
+ */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/ioport.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/ethtool.h>
-#include <linux/proc_fs.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/slab.h>
-#include <net/net_namespace.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
#include <asm/vio.h>
#include <asm/iommu.h>
-#include <asm/uaccess.h>
#include <asm/firmware.h>
-#include <linux/seq_file.h>
#include "ibmveth.h"
-#undef DEBUG
-
-#define ibmveth_printk(fmt, args...) \
- printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args)
-
-#define ibmveth_error_printk(fmt, args...) \
- printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
-
-#ifdef DEBUG
-#define ibmveth_debug_printk_no_adapter(fmt, args...) \
- printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args)
-#define ibmveth_debug_printk(fmt, args...) \
- printk(KERN_DEBUG "(%s:%3.3d ua:%x): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
-#define ibmveth_assert(expr) \
- if(!(expr)) { \
- printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \
- BUG(); \
- }
-#else
-#define ibmveth_debug_printk_no_adapter(fmt, args...)
-#define ibmveth_debug_printk(fmt, args...)
-#define ibmveth_assert(expr)
-#endif
-
-static int ibmveth_open(struct net_device *dev);
-static int ibmveth_close(struct net_device *dev);
-static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int ibmveth_poll(struct napi_struct *napi, int budget);
-static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void ibmveth_set_multicast_list(struct net_device *dev);
-static int ibmveth_change_mtu(struct net_device *dev, int new_mtu);
-static void ibmveth_proc_register_driver(void);
-static void ibmveth_proc_unregister_driver(void);
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance);
static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev);
-static struct kobj_type ktype_veth_pool;
+static struct kobj_type ktype_veth_pool;
-#ifdef CONFIG_PROC_FS
-#define IBMVETH_PROC_DIR "ibmveth"
-static struct proc_dir_entry *ibmveth_proc_dir;
-#endif
static const char ibmveth_driver_name[] = "ibmveth";
-static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver";
-#define ibmveth_driver_version "1.03"
+static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver";
+#define ibmveth_driver_version "1.04"
-MODULE_AUTHOR("Santiago Leon <santil@us.ibm.com>");
-MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver");
+MODULE_AUTHOR("Santiago Leon <santil@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(ibmveth_driver_version);
+static unsigned int tx_copybreak __read_mostly = 128;
+module_param(tx_copybreak, uint, 0644);
+MODULE_PARM_DESC(tx_copybreak,
+ "Maximum size of packet that is copied to a new buffer on transmit");
+
+static unsigned int rx_copybreak __read_mostly = 128;
+module_param(rx_copybreak, uint, 0644);
+MODULE_PARM_DESC(rx_copybreak,
+ "Maximum size of packet that is copied to a new buffer on receive");
+
+static unsigned int rx_flush __read_mostly = 0;
+module_param(rx_flush, uint, 0644);
+MODULE_PARM_DESC(rx_flush, "Flush receive buffers before use");
+
struct ibmveth_stat {
char name[ETH_GSTRING_LEN];
int offset;
@@ -128,12 +90,16 @@ struct ibmveth_stat {
struct ibmveth_stat ibmveth_stats[] = {
{ "replenish_task_cycles", IBMVETH_STAT_OFF(replenish_task_cycles) },
{ "replenish_no_mem", IBMVETH_STAT_OFF(replenish_no_mem) },
- { "replenish_add_buff_failure", IBMVETH_STAT_OFF(replenish_add_buff_failure) },
- { "replenish_add_buff_success", IBMVETH_STAT_OFF(replenish_add_buff_success) },
+ { "replenish_add_buff_failure",
+ IBMVETH_STAT_OFF(replenish_add_buff_failure) },
+ { "replenish_add_buff_success",
+ IBMVETH_STAT_OFF(replenish_add_buff_success) },
{ "rx_invalid_buffer", IBMVETH_STAT_OFF(rx_invalid_buffer) },
{ "rx_no_buffer", IBMVETH_STAT_OFF(rx_no_buffer) },
{ "tx_map_failed", IBMVETH_STAT_OFF(tx_map_failed) },
{ "tx_send_failed", IBMVETH_STAT_OFF(tx_send_failed) },
+ { "fw_enabled_ipv4_csum", IBMVETH_STAT_OFF(fw_ipv4_csum_support) },
+ { "fw_enabled_ipv6_csum", IBMVETH_STAT_OFF(fw_ipv6_csum_support) },
};
/* simple methods of getting data from the current rxq entry */
@@ -144,41 +110,44 @@ static inline u32 ibmveth_rxq_flags(struct ibmveth_adapter *adapter)
static inline int ibmveth_rxq_toggle(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> IBMVETH_RXQ_TOGGLE_SHIFT;
+ return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >>
+ IBMVETH_RXQ_TOGGLE_SHIFT;
}
static inline int ibmveth_rxq_pending_buffer(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle);
+ return ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle;
}
static inline int ibmveth_rxq_buffer_valid(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID;
}
static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK;
}
static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
{
- return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].length);
+ return adapter->rx_queue.queue_addr[adapter->rx_queue.index].length;
}
static inline int ibmveth_rxq_csum_good(struct ibmveth_adapter *adapter)
{
- return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD);
+ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD;
}
/* setup the initial settings for a buffer pool */
-static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_index, u32 pool_size, u32 buff_size, u32 pool_active)
+static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool,
+ u32 pool_index, u32 pool_size,
+ u32 buff_size, u32 pool_active)
{
pool->size = pool_size;
pool->index = pool_index;
pool->buff_size = buff_size;
- pool->threshold = pool_size / 2;
+ pool->threshold = pool_size * 7 / 8;
pool->active = pool_active;
}
@@ -189,12 +158,11 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
pool->free_map = kmalloc(sizeof(u16) * pool->size, GFP_KERNEL);
- if(!pool->free_map) {
+ if (!pool->free_map)
return -1;
- }
pool->dma_addr = kmalloc(sizeof(dma_addr_t) * pool->size, GFP_KERNEL);
- if(!pool->dma_addr) {
+ if (!pool->dma_addr) {
kfree(pool->free_map);
pool->free_map = NULL;
return -1;
@@ -202,7 +170,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
pool->skbuff = kcalloc(pool->size, sizeof(void *), GFP_KERNEL);
- if(!pool->skbuff) {
+ if (!pool->skbuff) {
kfree(pool->dma_addr);
pool->dma_addr = NULL;
@@ -213,9 +181,8 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
memset(pool->dma_addr, 0, sizeof(dma_addr_t) * pool->size);
- for(i = 0; i < pool->size; ++i) {
+ for (i = 0; i < pool->size; ++i)
pool->free_map[i] = i;
- }
atomic_set(&pool->available, 0);
pool->producer_index = 0;
@@ -224,10 +191,19 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
return 0;
}
+static inline void ibmveth_flush_buffer(void *addr, unsigned long length)
+{
+ unsigned long offset;
+
+ for (offset = 0; offset < length; offset += SMP_CACHE_BYTES)
+ asm("dcbfl %0,%1" :: "b" (addr), "r" (offset));
+}
+
/* replenish the buffers for a pool. note that we don't need to
* skb_reserve these since they are used for incoming...
*/
-static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool)
+static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter,
+ struct ibmveth_buff_pool *pool)
{
u32 i;
u32 count = pool->size - atomic_read(&pool->available);
@@ -240,23 +216,26 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
mb();
- for(i = 0; i < count; ++i) {
+ for (i = 0; i < count; ++i) {
union ibmveth_buf_desc desc;
- skb = alloc_skb(pool->buff_size, GFP_ATOMIC);
+ skb = netdev_alloc_skb(adapter->netdev, pool->buff_size);
- if(!skb) {
- ibmveth_debug_printk("replenish: unable to allocate skb\n");
+ if (!skb) {
+ netdev_dbg(adapter->netdev,
+ "replenish: unable to allocate skb\n");
adapter->replenish_no_mem++;
break;
}
free_index = pool->consumer_index;
- pool->consumer_index = (pool->consumer_index + 1) % pool->size;
+ pool->consumer_index++;
+ if (pool->consumer_index >= pool->size)
+ pool->consumer_index = 0;
index = pool->free_map[free_index];
- ibmveth_assert(index != IBM_VETH_INVALID_MAP);
- ibmveth_assert(pool->skbuff[index] == NULL);
+ BUG_ON(index == IBM_VETH_INVALID_MAP);
+ BUG_ON(pool->skbuff[index] != NULL);
dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
pool->buff_size, DMA_FROM_DEVICE);
@@ -269,16 +248,23 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
pool->skbuff[index] = skb;
correlator = ((u64)pool->index << 32) | index;
- *(u64*)skb->data = correlator;
+ *(u64 *)skb->data = correlator;
desc.fields.flags_len = IBMVETH_BUF_VALID | pool->buff_size;
desc.fields.address = dma_addr;
- lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
+ if (rx_flush) {
+ unsigned int len = min(pool->buff_size,
+ adapter->netdev->mtu +
+ IBMVETH_BUFF_OH);
+ ibmveth_flush_buffer(skb->data, len);
+ }
+ lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address,
+ desc.desc);
- if (lpar_rc != H_SUCCESS)
+ if (lpar_rc != H_SUCCESS) {
goto failure;
- else {
+ } else {
buffers_added++;
adapter->replenish_add_buff_success++;
}
@@ -313,26 +299,31 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter)
adapter->replenish_task_cycles++;
- for (i = (IbmVethNumBufferPools - 1); i >= 0; i--)
- if(adapter->rx_buff_pool[i].active)
- ibmveth_replenish_buffer_pool(adapter,
- &adapter->rx_buff_pool[i]);
+ for (i = (IBMVETH_NUM_BUFF_POOLS - 1); i >= 0; i--) {
+ struct ibmveth_buff_pool *pool = &adapter->rx_buff_pool[i];
- adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
+ if (pool->active &&
+ (atomic_read(&pool->available) < pool->threshold))
+ ibmveth_replenish_buffer_pool(adapter, pool);
+ }
+
+ adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) +
+ 4096 - 8);
}
/* empty and free ana buffer pool - also used to do cleanup in error paths */
-static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool)
+static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter,
+ struct ibmveth_buff_pool *pool)
{
int i;
kfree(pool->free_map);
pool->free_map = NULL;
- if(pool->skbuff && pool->dma_addr) {
- for(i = 0; i < pool->size; ++i) {
+ if (pool->skbuff && pool->dma_addr) {
+ for (i = 0; i < pool->size; ++i) {
struct sk_buff *skb = pool->skbuff[i];
- if(skb) {
+ if (skb) {
dma_unmap_single(&adapter->vdev->dev,
pool->dma_addr[i],
pool->buff_size,
@@ -343,31 +334,32 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
}
}
- if(pool->dma_addr) {
+ if (pool->dma_addr) {
kfree(pool->dma_addr);
pool->dma_addr = NULL;
}
- if(pool->skbuff) {
+ if (pool->skbuff) {
kfree(pool->skbuff);
pool->skbuff = NULL;
}
}
/* remove a buffer from a pool */
-static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 correlator)
+static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter,
+ u64 correlator)
{
unsigned int pool = correlator >> 32;
unsigned int index = correlator & 0xffffffffUL;
unsigned int free_index;
struct sk_buff *skb;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
skb = adapter->rx_buff_pool[pool].skbuff[index];
- ibmveth_assert(skb != NULL);
+ BUG_ON(skb == NULL);
adapter->rx_buff_pool[pool].skbuff[index] = NULL;
@@ -377,9 +369,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64
DMA_FROM_DEVICE);
free_index = adapter->rx_buff_pool[pool].producer_index;
- adapter->rx_buff_pool[pool].producer_index
- = (adapter->rx_buff_pool[pool].producer_index + 1)
- % adapter->rx_buff_pool[pool].size;
+ adapter->rx_buff_pool[pool].producer_index++;
+ if (adapter->rx_buff_pool[pool].producer_index >=
+ adapter->rx_buff_pool[pool].size)
+ adapter->rx_buff_pool[pool].producer_index = 0;
adapter->rx_buff_pool[pool].free_map[free_index] = index;
mb();
@@ -394,8 +387,8 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada
unsigned int pool = correlator >> 32;
unsigned int index = correlator & 0xffffffffUL;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
return adapter->rx_buff_pool[pool].skbuff[index];
}
@@ -410,10 +403,10 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
union ibmveth_buf_desc desc;
unsigned long lpar_rc;
- ibmveth_assert(pool < IbmVethNumBufferPools);
- ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
+ BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
+ BUG_ON(index >= adapter->rx_buff_pool[pool].size);
- if(!adapter->rx_buff_pool[pool].active) {
+ if (!adapter->rx_buff_pool[pool].active) {
ibmveth_rxq_harvest_buffer(adapter);
ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
return;
@@ -425,12 +418,13 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed "
+ "during recycle rc=%ld", lpar_rc);
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
}
- if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
+ if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
adapter->rx_queue.index = 0;
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
}
@@ -440,7 +434,7 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
{
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
- if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
+ if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
adapter->rx_queue.index = 0;
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
}
@@ -451,7 +445,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
int i;
struct device *dev = &adapter->vdev->dev;
- if(adapter->buffer_list_addr != NULL) {
+ if (adapter->buffer_list_addr != NULL) {
if (!dma_mapping_error(dev, adapter->buffer_list_dma)) {
dma_unmap_single(dev, adapter->buffer_list_dma, 4096,
DMA_BIDIRECTIONAL);
@@ -461,7 +455,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->buffer_list_addr = NULL;
}
- if(adapter->filter_list_addr != NULL) {
+ if (adapter->filter_list_addr != NULL) {
if (!dma_mapping_error(dev, adapter->filter_list_dma)) {
dma_unmap_single(dev, adapter->filter_list_dma, 4096,
DMA_BIDIRECTIONAL);
@@ -471,7 +465,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->filter_list_addr = NULL;
}
- if(adapter->rx_queue.queue_addr != NULL) {
+ if (adapter->rx_queue.queue_addr != NULL) {
if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) {
dma_unmap_single(dev,
adapter->rx_queue.queue_dma,
@@ -483,7 +477,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
adapter->rx_queue.queue_addr = NULL;
}
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
if (adapter->rx_buff_pool[i].active)
ibmveth_free_buffer_pool(adapter,
&adapter->rx_buff_pool[i]);
@@ -506,9 +500,11 @@ static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
{
int rc, try_again = 1;
- /* After a kexec the adapter will still be open, so our attempt to
- * open it will fail. So if we get a failure we free the adapter and
- * try again, but only once. */
+ /*
+ * After a kexec the adapter will still be open, so our attempt to
+ * open it will fail. So if we get a failure we free the adapter and
+ * try again, but only once.
+ */
retry:
rc = h_register_logical_lan(adapter->vdev->unit_address,
adapter->buffer_list_dma, rxq_desc.desc,
@@ -537,28 +533,31 @@ static int ibmveth_open(struct net_device *netdev)
int i;
struct device *dev;
- ibmveth_debug_printk("open starting\n");
+ netdev_dbg(netdev, "open starting\n");
napi_enable(&adapter->napi);
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for(i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
rxq_entries += adapter->rx_buff_pool[i].size;
adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
- if(!adapter->buffer_list_addr || !adapter->filter_list_addr) {
- ibmveth_error_printk("unable to allocate filter or buffer list pages\n");
+ if (!adapter->buffer_list_addr || !adapter->filter_list_addr) {
+ netdev_err(netdev, "unable to allocate filter or buffer list "
+ "pages\n");
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
return -ENOMEM;
}
- adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries;
- adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL);
+ adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *
+ rxq_entries;
+ adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len,
+ GFP_KERNEL);
- if(!adapter->rx_queue.queue_addr) {
- ibmveth_error_printk("unable to allocate rx queue pages\n");
+ if (!adapter->rx_queue.queue_addr) {
+ netdev_err(netdev, "unable to allocate rx queue pages\n");
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
return -ENOMEM;
@@ -577,7 +576,8 @@ static int ibmveth_open(struct net_device *netdev)
if ((dma_mapping_error(dev, adapter->buffer_list_dma)) ||
(dma_mapping_error(dev, adapter->filter_list_dma)) ||
(dma_mapping_error(dev, adapter->rx_queue.queue_dma))) {
- ibmveth_error_printk("unable to map filter or buffer list pages\n");
+ netdev_err(netdev, "unable to map filter or buffer list "
+ "pages\n");
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
return -ENOMEM;
@@ -590,20 +590,23 @@ static int ibmveth_open(struct net_device *netdev)
memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
mac_address = mac_address >> 16;
- rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len;
+ rxq_desc.fields.flags_len = IBMVETH_BUF_VALID |
+ adapter->rx_queue.queue_len;
rxq_desc.fields.address = adapter->rx_queue.queue_dma;
- ibmveth_debug_printk("buffer list @ 0x%p\n", adapter->buffer_list_addr);
- ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr);
- ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
+ netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr);
+ netdev_dbg(netdev, "filter list @ 0x%p\n", adapter->filter_list_addr);
+ netdev_dbg(netdev, "receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
- ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n",
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_register_logical_lan failed with %ld\n",
+ lpar_rc);
+ netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq "
+ "desc:0x%llx MAC:0x%llx\n",
adapter->buffer_list_dma,
adapter->filter_list_dma,
rxq_desc.desc,
@@ -613,11 +616,11 @@ static int ibmveth_open(struct net_device *netdev)
return -ENONET;
}
- for(i = 0; i<IbmVethNumBufferPools; i++) {
- if(!adapter->rx_buff_pool[i].active)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
+ if (!adapter->rx_buff_pool[i].active)
continue;
if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) {
- ibmveth_error_printk("unable to alloc pool\n");
+ netdev_err(netdev, "unable to alloc pool\n");
adapter->rx_buff_pool[i].active = 0;
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
@@ -625,9 +628,12 @@ static int ibmveth_open(struct net_device *netdev)
}
}
- ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq);
- if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) {
- ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc);
+ netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq);
+ rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name,
+ netdev);
+ if (rc != 0) {
+ netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
+ netdev->irq, rc);
do {
rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
@@ -640,7 +646,7 @@ static int ibmveth_open(struct net_device *netdev)
adapter->bounce_buffer =
kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL);
if (!adapter->bounce_buffer) {
- ibmveth_error_printk("unable to allocate bounce buffer\n");
+ netdev_err(netdev, "unable to allocate bounce buffer\n");
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
return -ENOMEM;
@@ -649,18 +655,18 @@ static int ibmveth_open(struct net_device *netdev)
dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer,
netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
- ibmveth_error_printk("unable to map bounce buffer\n");
+ netdev_err(netdev, "unable to map bounce buffer\n");
ibmveth_cleanup(adapter);
napi_disable(&adapter->napi);
return -ENOMEM;
}
- ibmveth_debug_printk("initial replenish cycle\n");
+ netdev_dbg(netdev, "initial replenish cycle\n");
ibmveth_interrupt(netdev->irq, netdev);
netif_start_queue(netdev);
- ibmveth_debug_printk("open complete\n");
+ netdev_dbg(netdev, "open complete\n");
return 0;
}
@@ -670,7 +676,7 @@ static int ibmveth_close(struct net_device *netdev)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
long lpar_rc;
- ibmveth_debug_printk("close starting\n");
+ netdev_dbg(netdev, "close starting\n");
napi_disable(&adapter->napi);
@@ -683,26 +689,29 @@ static int ibmveth_close(struct net_device *netdev)
lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
} while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
- if(lpar_rc != H_SUCCESS)
- {
- ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n",
- lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_free_logical_lan failed with %lx, "
+ "continuing with close\n", lpar_rc);
}
free_irq(netdev->irq, netdev);
- adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
+ adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) +
+ 4096 - 8);
ibmveth_cleanup(adapter);
- ibmveth_debug_printk("close complete\n");
+ netdev_dbg(netdev, "close complete\n");
return 0;
}
-static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) {
- cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE);
- cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE);
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE);
+ cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
+ ADVERTISED_FIBRE);
cmd->speed = SPEED_1000;
cmd->duplex = DUPLEX_FULL;
cmd->port = PORT_FIBRE;
@@ -714,12 +723,16 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return 0;
}
-static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) {
+static void netdev_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
strncpy(info->driver, ibmveth_driver_name, sizeof(info->driver) - 1);
- strncpy(info->version, ibmveth_driver_version, sizeof(info->version) - 1);
+ strncpy(info->version, ibmveth_driver_version,
+ sizeof(info->version) - 1);
}
-static u32 netdev_get_link(struct net_device *dev) {
+static u32 netdev_get_link(struct net_device *dev)
+{
return 1;
}
@@ -727,18 +740,20 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
- if (data)
+ if (data) {
adapter->rx_csum = 1;
- else {
+ } else {
/*
- * Since the ibmveth firmware interface does not have the concept of
- * separate tx/rx checksum offload enable, if rx checksum is disabled
- * we also have to disable tx checksum offload. Once we disable rx
- * checksum offload, we are no longer allowed to send tx buffers that
- * are not properly checksummed.
+ * Since the ibmveth firmware interface does not have the
+ * concept of separate tx/rx checksum offload enable, if rx
+ * checksum is disabled we also have to disable tx checksum
+ * offload. Once we disable rx checksum offload, we are no
+ * longer allowed to send tx buffers that are not properly
+ * checksummed.
*/
adapter->rx_csum = 0;
dev->features &= ~NETIF_F_IP_CSUM;
+ dev->features &= ~NETIF_F_IPV6_CSUM;
}
}
@@ -747,10 +762,15 @@ static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
struct ibmveth_adapter *adapter = netdev_priv(dev);
if (data) {
- dev->features |= NETIF_F_IP_CSUM;
+ if (adapter->fw_ipv4_csum_support)
+ dev->features |= NETIF_F_IP_CSUM;
+ if (adapter->fw_ipv6_csum_support)
+ dev->features |= NETIF_F_IPV6_CSUM;
adapter->rx_csum = 1;
- } else
+ } else {
dev->features &= ~NETIF_F_IP_CSUM;
+ dev->features &= ~NETIF_F_IPV6_CSUM;
+ }
}
static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
@@ -758,7 +778,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
unsigned long set_attr, clr_attr, ret_attr;
- long ret;
+ unsigned long set_attr6, clr_attr6;
+ long ret, ret6;
int rc1 = 0, rc2 = 0;
int restart = 0;
@@ -772,10 +793,13 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
set_attr = 0;
clr_attr = 0;
- if (data)
+ if (data) {
set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
- else
+ set_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM;
+ } else {
clr_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
+ clr_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM;
+ }
ret = h_illan_attributes(adapter->vdev->unit_address, 0, 0, &ret_attr);
@@ -786,18 +810,39 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
set_attr, &ret_attr);
if (ret != H_SUCCESS) {
- rc1 = -EIO;
- ibmveth_error_printk("unable to change checksum offload settings."
- " %d rc=%ld\n", data, ret);
+ netdev_err(dev, "unable to change IPv4 checksum "
+ "offload settings. %d rc=%ld\n",
+ data, ret);
ret = h_illan_attributes(adapter->vdev->unit_address,
set_attr, clr_attr, &ret_attr);
+ } else {
+ adapter->fw_ipv4_csum_support = data;
+ }
+
+ ret6 = h_illan_attributes(adapter->vdev->unit_address,
+ clr_attr6, set_attr6, &ret_attr);
+
+ if (ret6 != H_SUCCESS) {
+ netdev_err(dev, "unable to change IPv6 checksum "
+ "offload settings. %d rc=%ld\n",
+ data, ret);
+
+ ret = h_illan_attributes(adapter->vdev->unit_address,
+ set_attr6, clr_attr6,
+ &ret_attr);
} else
+ adapter->fw_ipv6_csum_support = data;
+
+ if (ret == H_SUCCESS || ret6 == H_SUCCESS)
done(dev, data);
+ else
+ rc1 = -EIO;
} else {
rc1 = -EIO;
- ibmveth_error_printk("unable to change checksum offload settings."
- " %d rc=%ld ret_attr=%lx\n", data, ret, ret_attr);
+ netdev_err(dev, "unable to change checksum offload settings."
+ " %d rc=%ld ret_attr=%lx\n", data, ret,
+ ret_attr);
}
if (restart)
@@ -821,13 +866,14 @@ static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
struct ibmveth_adapter *adapter = netdev_priv(dev);
int rc = 0;
- if (data && (dev->features & NETIF_F_IP_CSUM))
+ if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
return 0;
- if (!data && !(dev->features & NETIF_F_IP_CSUM))
+ if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
return 0;
if (data && !adapter->rx_csum)
- rc = ibmveth_set_csum_offload(dev, data, ibmveth_set_tx_csum_flags);
+ rc = ibmveth_set_csum_offload(dev, data,
+ ibmveth_set_tx_csum_flags);
else
ibmveth_set_tx_csum_flags(dev, data);
@@ -881,6 +927,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_strings = ibmveth_get_strings,
.get_sset_count = ibmveth_get_sset_count,
.get_ethtool_stats = ibmveth_get_ethtool_stats,
+ .set_sg = ethtool_op_set_sg,
};
static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -890,129 +937,216 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
#define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1))
-static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
+static int ibmveth_send(struct ibmveth_adapter *adapter,
+ union ibmveth_buf_desc *descs)
{
- struct ibmveth_adapter *adapter = netdev_priv(netdev);
- union ibmveth_buf_desc desc;
- unsigned long lpar_rc;
unsigned long correlator;
- unsigned long flags;
unsigned int retry_count;
- unsigned int tx_dropped = 0;
- unsigned int tx_bytes = 0;
- unsigned int tx_packets = 0;
- unsigned int tx_send_failed = 0;
- unsigned int tx_map_failed = 0;
- int used_bounce = 0;
- unsigned long data_dma_addr;
+ unsigned long ret;
+
+ /*
+ * The retry count sets a maximum for the number of broadcast and
+ * multicast destinations within the system.
+ */
+ retry_count = 1024;
+ correlator = 0;
+ do {
+ ret = h_send_logical_lan(adapter->vdev->unit_address,
+ descs[0].desc, descs[1].desc,
+ descs[2].desc, descs[3].desc,
+ descs[4].desc, descs[5].desc,
+ correlator, &correlator);
+ } while ((ret == H_BUSY) && (retry_count--));
+
+ if (ret != H_SUCCESS && ret != H_DROPPED) {
+ netdev_err(adapter->netdev, "tx: h_send_logical_lan failed "
+ "with rc=%ld\n", ret);
+ return 1;
+ }
+
+ return 0;
+}
- desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len;
+static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct ibmveth_adapter *adapter = netdev_priv(netdev);
+ unsigned int desc_flags;
+ union ibmveth_buf_desc descs[6];
+ int last, i;
+ int force_bounce = 0;
+
+ /*
+ * veth handles a maximum of 6 segments including the header, so
+ * we have to linearize the skb if there are more than this.
+ */
+ if (skb_shinfo(skb)->nr_frags > 5 && __skb_linearize(skb)) {
+ netdev->stats.tx_dropped++;
+ goto out;
+ }
+ /* veth can't checksum offload UDP */
if (skb->ip_summed == CHECKSUM_PARTIAL &&
- ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) {
- ibmveth_error_printk("tx: failed to checksum packet\n");
- tx_dropped++;
+ ((skb->protocol == htons(ETH_P_IP) &&
+ ip_hdr(skb)->protocol != IPPROTO_TCP) ||
+ (skb->protocol == htons(ETH_P_IPV6) &&
+ ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)) &&
+ skb_checksum_help(skb)) {
+
+ netdev_err(netdev, "tx: failed to checksum packet\n");
+ netdev->stats.tx_dropped++;
goto out;
}
+ desc_flags = IBMVETH_BUF_VALID;
+
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- unsigned char *buf = skb_transport_header(skb) + skb->csum_offset;
+ unsigned char *buf = skb_transport_header(skb) +
+ skb->csum_offset;
- desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD);
+ desc_flags |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD);
/* Need to zero out the checksum */
buf[0] = 0;
buf[1] = 0;
}
- data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
- if (!firmware_has_feature(FW_FEATURE_CMO))
- ibmveth_error_printk("tx: unable to map xmit buffer\n");
+retry_bounce:
+ memset(descs, 0, sizeof(descs));
+
+ /*
+ * If a linear packet is below the rx threshold then
+ * copy it into the static bounce buffer. This avoids the
+ * cost of a TCE insert and remove.
+ */
+ if (force_bounce || (!skb_is_nonlinear(skb) &&
+ (skb->len < tx_copybreak))) {
skb_copy_from_linear_data(skb, adapter->bounce_buffer,
skb->len);
- desc.fields.address = adapter->bounce_buffer_dma;
- tx_map_failed++;
- used_bounce = 1;
- wmb();
- } else
- desc.fields.address = data_dma_addr;
-
- /* send the frame. Arbitrarily set retrycount to 1024 */
- correlator = 0;
- retry_count = 1024;
- do {
- lpar_rc = h_send_logical_lan(adapter->vdev->unit_address,
- desc.desc, 0, 0, 0, 0, 0,
- correlator, &correlator);
- } while ((lpar_rc == H_BUSY) && (retry_count--));
-
- if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) {
- ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc);
- ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n",
- (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0,
- skb->len, desc.fields.address);
- tx_send_failed++;
- tx_dropped++;
- } else {
- tx_packets++;
- tx_bytes += skb->len;
- netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+
+ descs[0].fields.flags_len = desc_flags | skb->len;
+ descs[0].fields.address = adapter->bounce_buffer_dma;
+
+ if (ibmveth_send(adapter, descs)) {
+ adapter->tx_send_failed++;
+ netdev->stats.tx_dropped++;
+ } else {
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
+ }
+
+ goto out;
+ }
+
+ /* Map the header */
+ descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data,
+ skb_headlen(skb),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address))
+ goto map_failed;
+
+ descs[0].fields.flags_len = desc_flags | skb_headlen(skb);
+
+ /* Map the frags */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ unsigned long dma_addr;
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ dma_addr = dma_map_page(&adapter->vdev->dev, frag->page,
+ frag->page_offset, frag->size,
+ DMA_TO_DEVICE);
+
+ if (dma_mapping_error(&adapter->vdev->dev, dma_addr))
+ goto map_failed_frags;
+
+ descs[i+1].fields.flags_len = desc_flags | frag->size;
+ descs[i+1].fields.address = dma_addr;
}
- if (!used_bounce)
- dma_unmap_single(&adapter->vdev->dev, data_dma_addr,
- skb->len, DMA_TO_DEVICE);
+ if (ibmveth_send(adapter, descs)) {
+ adapter->tx_send_failed++;
+ netdev->stats.tx_dropped++;
+ } else {
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
+ }
-out: spin_lock_irqsave(&adapter->stats_lock, flags);
- netdev->stats.tx_dropped += tx_dropped;
- netdev->stats.tx_bytes += tx_bytes;
- netdev->stats.tx_packets += tx_packets;
- adapter->tx_send_failed += tx_send_failed;
- adapter->tx_map_failed += tx_map_failed;
- spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++)
+ dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
+ descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
+ DMA_TO_DEVICE);
+out:
dev_kfree_skb(skb);
return NETDEV_TX_OK;
+
+map_failed_frags:
+ last = i+1;
+ for (i = 0; i < last; i++)
+ dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
+ descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
+ DMA_TO_DEVICE);
+
+map_failed:
+ if (!firmware_has_feature(FW_FEATURE_CMO))
+ netdev_err(netdev, "tx: unable to map xmit buffer\n");
+ adapter->tx_map_failed++;
+ skb_linearize(skb);
+ force_bounce = 1;
+ goto retry_bounce;
}
static int ibmveth_poll(struct napi_struct *napi, int budget)
{
- struct ibmveth_adapter *adapter = container_of(napi, struct ibmveth_adapter, napi);
+ struct ibmveth_adapter *adapter =
+ container_of(napi, struct ibmveth_adapter, napi);
struct net_device *netdev = adapter->netdev;
int frames_processed = 0;
unsigned long lpar_rc;
- restart_poll:
+restart_poll:
do {
- struct sk_buff *skb;
-
if (!ibmveth_rxq_pending_buffer(adapter))
break;
- rmb();
+ smp_rmb();
if (!ibmveth_rxq_buffer_valid(adapter)) {
wmb(); /* suggested by larson1 */
adapter->rx_invalid_buffer++;
- ibmveth_debug_printk("recycling invalid buffer\n");
+ netdev_dbg(netdev, "recycling invalid buffer\n");
ibmveth_rxq_recycle_buffer(adapter);
} else {
+ struct sk_buff *skb, *new_skb;
int length = ibmveth_rxq_frame_length(adapter);
int offset = ibmveth_rxq_frame_offset(adapter);
int csum_good = ibmveth_rxq_csum_good(adapter);
skb = ibmveth_rxq_get_buffer(adapter);
- if (csum_good)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- ibmveth_rxq_harvest_buffer(adapter);
+ new_skb = NULL;
+ if (length < rx_copybreak)
+ new_skb = netdev_alloc_skb(netdev, length);
+
+ if (new_skb) {
+ skb_copy_to_linear_data(new_skb,
+ skb->data + offset,
+ length);
+ if (rx_flush)
+ ibmveth_flush_buffer(skb->data,
+ length + offset);
+ skb = new_skb;
+ ibmveth_rxq_recycle_buffer(adapter);
+ } else {
+ ibmveth_rxq_harvest_buffer(adapter);
+ skb_reserve(skb, offset);
+ }
- skb_reserve(skb, offset);
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, netdev);
+ if (csum_good)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
netif_receive_skb(skb); /* send it up */
netdev->stats.rx_packets++;
@@ -1030,7 +1164,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_ENABLE);
- ibmveth_assert(lpar_rc == H_SUCCESS);
+ BUG_ON(lpar_rc != H_SUCCESS);
napi_complete(napi);
@@ -1054,7 +1188,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
if (napi_schedule_prep(&adapter->napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
- ibmveth_assert(lpar_rc == H_SUCCESS);
+ BUG_ON(lpar_rc != H_SUCCESS);
__napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1071,8 +1205,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
IbmVethMcastEnableRecv |
IbmVethMcastDisableFiltering,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "entering promisc mode\n", lpar_rc);
}
} else {
struct netdev_hw_addr *ha;
@@ -1082,19 +1217,23 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
IbmVethMcastDisableFiltering |
IbmVethMcastClearFilterTable,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "attempting to clear filter table\n",
+ lpar_rc);
}
/* add the addresses to the filter table */
netdev_for_each_mc_addr(ha, netdev) {
- // add the multicast address to the filter table
+ /* add the multicast address to the filter table */
unsigned long mcast_addr = 0;
memcpy(((char *)&mcast_addr)+2, ha->addr, 6);
lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
IbmVethMcastAddFilter,
mcast_addr);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld "
+ "when adding an entry to the filter "
+ "table\n", lpar_rc);
}
}
@@ -1102,8 +1241,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
IbmVethMcastEnableFiltering,
0);
- if(lpar_rc != H_SUCCESS) {
- ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc);
+ if (lpar_rc != H_SUCCESS) {
+ netdev_err(netdev, "h_multicast_ctrl rc=%ld when "
+ "enabling filtering\n", lpar_rc);
}
}
}
@@ -1116,14 +1256,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
int i, rc;
int need_restart = 0;
- if (new_mtu < IBMVETH_MAX_MTU)
+ if (new_mtu < IBMVETH_MIN_MTU)
return -EINVAL;
- for (i = 0; i < IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size)
break;
- if (i == IbmVethNumBufferPools)
+ if (i == IBMVETH_NUM_BUFF_POOLS)
return -EINVAL;
/* Deactivate all the buffer pools so that the next loop can activate
@@ -1136,7 +1276,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
}
/* Look for an active buffer pool that can hold the new MTU */
- for(i = 0; i<IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
adapter->rx_buff_pool[i].active = 1;
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
@@ -1190,7 +1330,7 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
ret = IBMVETH_BUFF_LIST_SIZE + IBMVETH_FILT_LIST_SIZE;
ret += IOMMU_PAGE_ALIGN(netdev->mtu);
- for (i = 0; i < IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
/* add the size of the active receive buffers */
if (adapter->rx_buff_pool[i].active)
ret +=
@@ -1219,41 +1359,36 @@ static const struct net_device_ops ibmveth_netdev_ops = {
#endif
};
-static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
+static int __devinit ibmveth_probe(struct vio_dev *dev,
+ const struct vio_device_id *id)
{
int rc, i;
- long ret;
struct net_device *netdev;
struct ibmveth_adapter *adapter;
- unsigned long set_attr, ret_attr;
-
unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
+ dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n",
+ dev->unit_address);
- ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n",
- dev->unit_address);
-
- mac_addr_p = (unsigned char *) vio_get_attribute(dev,
- VETH_MAC_ADDR, NULL);
- if(!mac_addr_p) {
- printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR "
- "attribute\n", __FILE__, __LINE__);
- return 0;
+ mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR,
+ NULL);
+ if (!mac_addr_p) {
+ dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n");
+ return -EINVAL;
}
- mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev,
+ mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
VETH_MCAST_FILTER_SIZE, NULL);
- if(!mcastFilterSize_p) {
- printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find "
- "VETH_MCAST_FILTER_SIZE attribute\n",
- __FILE__, __LINE__);
- return 0;
+ if (!mcastFilterSize_p) {
+ dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE "
+ "attribute\n");
+ return -EINVAL;
}
netdev = alloc_etherdev(sizeof(struct ibmveth_adapter));
- if(!netdev)
+ if (!netdev)
return -ENOMEM;
adapter = netdev_priv(netdev);
@@ -1261,19 +1396,19 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
adapter->vdev = dev;
adapter->netdev = netdev;
- adapter->mcastFilterSize= *mcastFilterSize_p;
+ adapter->mcastFilterSize = *mcastFilterSize_p;
adapter->pool_config = 0;
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
- /* Some older boxes running PHYP non-natively have an OF that
- returns a 8-byte local-mac-address field (and the first
- 2 bytes have to be ignored) while newer boxes' OF return
- a 6-byte field. Note that IEEE 1275 specifies that
- local-mac-address must be a 6-byte field.
- The RPA doc specifies that the first byte must be 10b, so
- we'll just look for it to solve this 8 vs. 6 byte field issue */
-
+ /*
+ * Some older boxes running PHYP non-natively have an OF that returns
+ * a 8-byte local-mac-address field (and the first 2 bytes have to be
+ * ignored) while newer boxes' OF return a 6-byte field. Note that
+ * IEEE 1275 specifies that local-mac-address must be a 6-byte field.
+ * The RPA doc specifies that the first byte must be 10b, so we'll
+ * just look for it to solve this 8 vs. 6 byte field issue
+ */
if ((*mac_addr_p & 0x3) != 0x02)
mac_addr_p += 2;
@@ -1284,12 +1419,11 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
netdev->netdev_ops = &ibmveth_netdev_ops;
netdev->ethtool_ops = &netdev_ethtool_ops;
SET_NETDEV_DEV(netdev, &dev->dev);
- netdev->features |= NETIF_F_LLTX;
- spin_lock_init(&adapter->stats_lock);
+ netdev->features |= NETIF_F_SG;
memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
- for(i = 0; i<IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
int error;
@@ -1302,41 +1436,25 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
kobject_uevent(kobj, KOBJ_ADD);
}
- ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
+ netdev_dbg(netdev, "adapter @ 0x%p\n", adapter);
adapter->buffer_list_dma = DMA_ERROR_CODE;
adapter->filter_list_dma = DMA_ERROR_CODE;
adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
- ibmveth_debug_printk("registering netdev...\n");
-
- ret = h_illan_attributes(dev->unit_address, 0, 0, &ret_attr);
-
- if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) &&
- !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) &&
- (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) {
- set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
-
- ret = h_illan_attributes(dev->unit_address, 0, set_attr, &ret_attr);
+ netdev_dbg(netdev, "registering netdev...\n");
- if (ret == H_SUCCESS) {
- adapter->rx_csum = 1;
- netdev->features |= NETIF_F_IP_CSUM;
- } else
- ret = h_illan_attributes(dev->unit_address, set_attr, 0, &ret_attr);
- }
+ ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags);
rc = register_netdev(netdev);
- if(rc) {
- ibmveth_debug_printk("failed to register netdev rc=%d\n", rc);
+ if (rc) {
+ netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc);
free_netdev(netdev);
return rc;
}
- ibmveth_debug_printk("registered\n");
-
- ibmveth_proc_register_adapter(adapter);
+ netdev_dbg(netdev, "registered\n");
return 0;
}
@@ -1347,114 +1465,23 @@ static int __devexit ibmveth_remove(struct vio_dev *dev)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
int i;
- for(i = 0; i<IbmVethNumBufferPools; i++)
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++)
kobject_put(&adapter->rx_buff_pool[i].kobj);
unregister_netdev(netdev);
- ibmveth_proc_unregister_adapter(adapter);
-
free_netdev(netdev);
dev_set_drvdata(&dev->dev, NULL);
return 0;
}
-#ifdef CONFIG_PROC_FS
-static void ibmveth_proc_register_driver(void)
-{
- ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net);
- if (ibmveth_proc_dir) {
- }
-}
-
-static void ibmveth_proc_unregister_driver(void)
-{
- remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net);
-}
-
-static int ibmveth_show(struct seq_file *seq, void *v)
-{
- struct ibmveth_adapter *adapter = seq->private;
- char *current_mac = (char *) adapter->netdev->dev_addr;
- char *firmware_mac = (char *) &adapter->mac_addr;
-
- seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
-
- seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
- seq_printf(seq, "Current MAC: %pM\n", current_mac);
- seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac);
-
- seq_printf(seq, "\nAdapter Statistics:\n");
- seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed);
- seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed);
- seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles);
- seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem);
- seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure);
- seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer);
- seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer);
-
- return 0;
-}
-
-static int ibmveth_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ibmveth_show, PDE(inode)->data);
-}
-
-static const struct file_operations ibmveth_proc_fops = {
- .owner = THIS_MODULE,
- .open = ibmveth_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
-{
- struct proc_dir_entry *entry;
- if (ibmveth_proc_dir) {
- char u_addr[10];
- sprintf(u_addr, "%x", adapter->vdev->unit_address);
- entry = proc_create_data(u_addr, S_IFREG, ibmveth_proc_dir,
- &ibmveth_proc_fops, adapter);
- if (!entry)
- ibmveth_error_printk("Cannot create adapter proc entry");
- }
-}
-
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
-{
- if (ibmveth_proc_dir) {
- char u_addr[10];
- sprintf(u_addr, "%x", adapter->vdev->unit_address);
- remove_proc_entry(u_addr, ibmveth_proc_dir);
- }
-}
-
-#else /* CONFIG_PROC_FS */
-static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
-{
-}
-
-static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
-{
-}
-static void ibmveth_proc_register_driver(void)
-{
-}
-
-static void ibmveth_proc_unregister_driver(void)
-{
-}
-#endif /* CONFIG_PROC_FS */
-
static struct attribute veth_active_attr;
static struct attribute veth_num_attr;
static struct attribute veth_size_attr;
-static ssize_t veth_pool_show(struct kobject * kobj,
- struct attribute * attr, char * buf)
+static ssize_t veth_pool_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
{
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
@@ -1469,8 +1496,8 @@ static ssize_t veth_pool_show(struct kobject * kobj,
return 0;
}
-static ssize_t veth_pool_store(struct kobject * kobj, struct attribute * attr,
-const char * buf, size_t count)
+static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
{
struct ibmveth_buff_pool *pool = container_of(kobj,
struct ibmveth_buff_pool,
@@ -1484,8 +1511,9 @@ const char * buf, size_t count)
if (attr == &veth_active_attr) {
if (value && !pool->active) {
if (netif_running(netdev)) {
- if(ibmveth_alloc_buffer_pool(pool)) {
- ibmveth_error_printk("unable to alloc pool\n");
+ if (ibmveth_alloc_buffer_pool(pool)) {
+ netdev_err(netdev,
+ "unable to alloc pool\n");
return -ENOMEM;
}
pool->active = 1;
@@ -1494,14 +1522,15 @@ const char * buf, size_t count)
adapter->pool_config = 0;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->active = 1;
+ }
} else if (!value && pool->active) {
int mtu = netdev->mtu + IBMVETH_BUFF_OH;
int i;
/* Make sure there is a buffer pool with buffers that
can hold a packet of the size of the MTU */
- for (i = 0; i < IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
if (pool == &adapter->rx_buff_pool[i])
continue;
if (!adapter->rx_buff_pool[i].active)
@@ -1510,8 +1539,8 @@ const char * buf, size_t count)
break;
}
- if (i == IbmVethNumBufferPools) {
- ibmveth_error_printk("no active pool >= MTU\n");
+ if (i == IBMVETH_NUM_BUFF_POOLS) {
+ netdev_err(netdev, "no active pool >= MTU\n");
return -EPERM;
}
@@ -1526,9 +1555,9 @@ const char * buf, size_t count)
pool->active = 0;
}
} else if (attr == &veth_num_attr) {
- if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
+ if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
return -EINVAL;
- else {
+ } else {
if (netif_running(netdev)) {
adapter->pool_config = 1;
ibmveth_close(netdev);
@@ -1536,13 +1565,14 @@ const char * buf, size_t count)
pool->size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->size = value;
+ }
}
} else if (attr == &veth_size_attr) {
- if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE)
+ if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
return -EINVAL;
- else {
+ } else {
if (netif_running(netdev)) {
adapter->pool_config = 1;
ibmveth_close(netdev);
@@ -1550,8 +1580,9 @@ const char * buf, size_t count)
pool->buff_size = value;
if ((rc = ibmveth_open(netdev)))
return rc;
- } else
+ } else {
pool->buff_size = value;
+ }
}
}
@@ -1561,16 +1592,16 @@ const char * buf, size_t count)
}
-#define ATTR(_name, _mode) \
- struct attribute veth_##_name##_attr = { \
- .name = __stringify(_name), .mode = _mode, \
- };
+#define ATTR(_name, _mode) \
+ struct attribute veth_##_name##_attr = { \
+ .name = __stringify(_name), .mode = _mode, \
+ };
static ATTR(active, 0644);
static ATTR(num, 0644);
static ATTR(size, 0644);
-static struct attribute * veth_pool_attrs[] = {
+static struct attribute *veth_pool_attrs[] = {
&veth_active_attr,
&veth_num_attr,
&veth_size_attr,
@@ -1595,7 +1626,7 @@ static int ibmveth_resume(struct device *dev)
return 0;
}
-static struct vio_device_id ibmveth_device_table[] __devinitdata= {
+static struct vio_device_id ibmveth_device_table[] __devinitdata = {
{ "network", "IBM,l-lan"},
{ "", "" }
};
@@ -1619,9 +1650,8 @@ static struct vio_driver ibmveth_driver = {
static int __init ibmveth_module_init(void)
{
- ibmveth_printk("%s: %s %s\n", ibmveth_driver_name, ibmveth_driver_string, ibmveth_driver_version);
-
- ibmveth_proc_register_driver();
+ printk(KERN_DEBUG "%s: %s %s\n", ibmveth_driver_name,
+ ibmveth_driver_string, ibmveth_driver_version);
return vio_register_driver(&ibmveth_driver);
}
@@ -1629,7 +1659,6 @@ static int __init ibmveth_module_init(void)
static void __exit ibmveth_module_exit(void)
{
vio_unregister_driver(&ibmveth_driver);
- ibmveth_proc_unregister_driver();
}
module_init(ibmveth_module_init);
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index ec76ace66c6b..43a794fab9ff 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -1,26 +1,28 @@
-/**************************************************************************/
-/* */
-/* IBM eServer i/[Series Virtual Ethernet Device Driver */
-/* Copyright (C) 2003 IBM Corp. */
-/* Dave Larson (larson1@us.ibm.com) */
-/* Santiago Leon (santil@us.ibm.com) */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */
-/* USA */
-/* */
-/**************************************************************************/
+/*
+ * IBM Power Virtual Ethernet Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2003, 2010
+ *
+ * Authors: Dave Larson <larson1@us.ibm.com>
+ * Santiago Leon <santil@linux.vnet.ibm.com>
+ * Brian King <brking@linux.vnet.ibm.com>
+ * Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Anton Blanchard <anton@au.ibm.com>
+ */
#ifndef _IBMVETH_H
#define _IBMVETH_H
@@ -92,17 +94,17 @@ static inline long h_illan_attributes(unsigned long unit_address,
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
-#define IbmVethNumBufferPools 5
+#define IBMVETH_NUM_BUFF_POOLS 5
#define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */
#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
-#define IBMVETH_MAX_MTU 68
+#define IBMVETH_MIN_MTU 68
#define IBMVETH_MAX_POOL_COUNT 4096
#define IBMVETH_BUFF_LIST_SIZE 4096
#define IBMVETH_FILT_LIST_SIZE 4096
#define IBMVETH_MAX_BUF_SIZE (1024 * 128)
static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
-static int pool_count[] = { 256, 768, 256, 256, 256 };
+static int pool_count[] = { 256, 512, 256, 256, 256 };
static int pool_active[] = { 1, 1, 0, 0, 0};
#define IBM_VETH_INVALID_MAP ((u16)0xffff)
@@ -142,13 +144,15 @@ struct ibmveth_adapter {
void * filter_list_addr;
dma_addr_t buffer_list_dma;
dma_addr_t filter_list_dma;
- struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
+ struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS];
struct ibmveth_rx_q rx_queue;
int pool_config;
int rx_csum;
void *bounce_buffer;
dma_addr_t bounce_buffer_dma;
+ u64 fw_ipv6_csum_support;
+ u64 fw_ipv4_csum_support;
/* adapter specific stats */
u64 replenish_task_cycles;
u64 replenish_no_mem;
@@ -158,7 +162,6 @@ struct ibmveth_adapter {
u64 rx_no_buffer;
u64 tx_map_failed;
u64 tx_send_failed;
- spinlock_t stats_lock;
};
struct ibmveth_buf_desc_fields {
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 6e63d9a7fc75..44e0ff1494e0 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -143,7 +143,7 @@ struct igb_buffer {
u16 next_to_watch;
unsigned int bytecount;
u16 gso_segs;
- union skb_shared_tx shtx;
+ u8 tx_flags;
u8 mapped_as_page;
};
/* RX */
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 9b4e5895f5f9..3adef1e1c16e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1888,9 +1888,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
goto err_eeprom;
}
- setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+ setup_timer(&adapter->watchdog_timer, igb_watchdog,
(unsigned long) adapter);
- setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+ setup_timer(&adapter->phy_info_timer, igb_update_phy_info,
(unsigned long) adapter);
INIT_WORK(&adapter->reset_task, igb_reset_task);
@@ -3527,7 +3527,7 @@ enum latency_range {
* Stores a new ITR value based on strictly on packet size. This
* algorithm is less sophisticated than that used in igb_update_itr,
* due to the difficulty of synchronizing statistics across multiple
- * receive rings. The divisors and thresholds used by this fuction
+ * receive rings. The divisors and thresholds used by this function
* were determined based on theoretical maximum wire speed and testing
* data, in order to minimize response time while increasing bulk
* throughput.
@@ -3954,7 +3954,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
}
tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags;
+ tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags;
/* multiply data chunks by size of headers */
tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len;
tx_ring->buffer_info[i].gso_segs = gso_segs;
@@ -4088,7 +4088,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
u32 tx_flags = 0;
u16 first;
u8 hdr_len = 0;
- union skb_shared_tx *shtx = skb_tx(skb);
/* need: 1 descriptor per page,
* + 2 desc gap to keep tail from touching head,
@@ -4100,8 +4099,8 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- if (unlikely(shtx->hardware)) {
- shtx->in_progress = 1;
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= IGB_TX_FLAGS_TSTAMP;
}
@@ -5319,7 +5318,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu
u64 regval;
/* if skb does not support hw timestamp or TX stamp not valid exit */
- if (likely(!buffer_info->shtx.hardware) ||
+ if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) ||
!(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
return;
@@ -5456,7 +5455,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector,
static inline void igb_rx_checksum_adv(struct igb_ring *ring,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) ||
@@ -5500,7 +5499,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
* values must belong to this one here and therefore we don't need to
* compare any of the additional attributes stored for it.
*
- * If nothing went wrong, then it should have a skb_shared_tx that we
+ * If nothing went wrong, then it should have a shared tx_flags that we
* can turn into a skb_shared_hwtstamps.
*/
if (staterr & E1000_RXDADV_STAT_TSIP) {
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index c539f7c9c3e0..c7fab80d2490 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -103,7 +103,7 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
if ((status_err & E1000_RXD_STAT_IXSM) ||
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 0b3f6df5cff7..c8ee8d28767b 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -827,7 +827,7 @@ static void ioc3_mii_start(struct ioc3_private *ip)
{
ip->ioc3_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */
ip->ioc3_timer.data = (unsigned long) ip;
- ip->ioc3_timer.function = &ioc3_timer;
+ ip->ioc3_timer.function = ioc3_timer;
add_timer(&ip->ioc3_timer);
}
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 72e3d2da9e9f..dc0198092343 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1213,7 +1213,7 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
skb_put(skb, framelen);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_rx(skb);
sp->rx_buff[entry] = NULL;
}
@@ -1278,7 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
jumbo->skb->protocol =
eth_type_trans(jumbo->skb, dev);
- jumbo->skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(jumbo->skb);
netif_rx(jumbo->skb);
}
}
@@ -1476,7 +1476,7 @@ static int ipg_nic_rx(struct net_device *dev)
* IP/TCP/UDP frame was received. Let the
* upper layer decide.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Hand off frame for higher layer processing.
* The function netif_rx() releases the sk_buff
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 4441fa3389c2..e4e71f32746b 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1124,11 +1124,12 @@ static int stir421x_patch_device(struct irda_usb_cb *self)
* The actual image starts after the "STMP" keyword
* so forward to the firmware header tag
*/
- for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) &&
- (i < fw->size); i++) ;
+ for (i = 0; i < fw->size && fw->data[i] !=
+ STIR421X_PATCH_END_OF_HDR_TAG; i++)
+ ;
/* here we check for the out of buffer case */
- if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) &&
- (i < STIR421X_PATCH_CODE_OFFSET)) {
+ if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size &&
+ STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) {
if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG,
sizeof(STIR421X_PATCH_STMP_TAG) - 1)) {
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 5b1036ac38d7..74b20f179cea 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -734,7 +734,7 @@ static int mcs_net_open(struct net_device *netdev)
}
if (!mcs_setup_urbs(mcs))
- goto error3;
+ goto error3;
ret = mcs_receive_start(mcs);
if (ret)
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index b0a6cd815be1..67c0ad42d818 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -1182,12 +1182,13 @@ F01_E */
skb = dev_alloc_skb(len + 1 - 4);
/*
- * if frame size,data ptr,or skb ptr are wrong ,the get next
+ * if frame size, data ptr, or skb ptr are wrong, then get next
* entry.
*/
if ((skb == NULL) || (skb->data == NULL) ||
(self->rx_buff.data == NULL) || (len < 6)) {
self->netdev->stats.rx_dropped++;
+ kfree_skb(skb);
return TRUE;
}
skb_reserve(skb, 1);
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index ba1de5973fb2..8df645e78f2e 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1524,7 +1524,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
skb_put(skb, length);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_rx(skb); /* send it up */
dev->stats.rx_packets++;
dev->stats.rx_bytes += length;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 45fc89b9ba64..c2f6e71e1181 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -470,7 +470,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgb_watchdog;
+ adapter->watchdog_timer.function = ixgb_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
@@ -1905,7 +1905,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
*/
if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
(!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
return;
}
@@ -1913,7 +1913,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
/* now look at the TCP checksum error bit */
if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
/* let the stack verify checksum errors */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
adapter->hw_csum_rx_error++;
} else {
/* TCP checksum is good */
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 9e15eb93860e..5cebc3755b64 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -69,15 +69,20 @@
#define IXGBE_MAX_FCPAUSE 0xFFFF
/* Supported Rx Buffer Sizes */
-#define IXGBE_RXBUFFER_64 64 /* Used for packet split */
-#define IXGBE_RXBUFFER_128 128 /* Used for packet split */
-#define IXGBE_RXBUFFER_256 256 /* Used for packet split */
+#define IXGBE_RXBUFFER_512 512 /* Used for packet split */
#define IXGBE_RXBUFFER_2048 2048
#define IXGBE_RXBUFFER_4096 4096
#define IXGBE_RXBUFFER_8192 8192
#define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
-#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
+/*
+ * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we
+ * reserve 2 more, and skb_shared_info adds an additional 384 bytes more,
+ * this adds up to 512 bytes of extra data meaning the smallest allocation
+ * we could have is 1K.
+ * i.e. RXBUFFER_512 --> size-1024 slab
+ */
+#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512
#define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
@@ -251,11 +256,11 @@ struct ixgbe_q_vector {
(R)->next_to_clean - (R)->next_to_use - 1)
#define IXGBE_RX_DESC_ADV(R, i) \
- (&(((union ixgbe_adv_rx_desc *)((R).desc))[i]))
+ (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBE_TX_DESC_ADV(R, i) \
- (&(((union ixgbe_adv_tx_desc *)((R).desc))[i]))
+ (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i]))
#define IXGBE_TX_CTXTDESC_ADV(R, i) \
- (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
+ (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
#ifdef IXGBE_FCOE
@@ -448,9 +453,20 @@ extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
+extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
+extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *,
+ struct net_device *,
+ struct ixgbe_adapter *,
+ struct ixgbe_ring *);
+extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *,
+ struct ixgbe_tx_buffer *);
+extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ int cleaned_count);
extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
extern int ethtool_ioctl(struct ifreq *ifr);
extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index dcebc82c6f4d..25ef8b197373 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -820,16 +820,19 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
char firmware_version[32];
- strncpy(drvinfo->driver, ixgbe_driver_name, 32);
- strncpy(drvinfo->version, ixgbe_driver_version, 32);
-
- 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);
+ strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
+ strncpy(drvinfo->version, ixgbe_driver_version,
+ sizeof(drvinfo->version));
+
+ snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d",
+ (adapter->eeprom_version & 0xF000) >> 12,
+ (adapter->eeprom_version & 0x0FF0) >> 4,
+ adapter->eeprom_version & 0x000F);
+
+ strncpy(drvinfo->fw_version, firmware_version,
+ sizeof(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
drvinfo->n_stats = IXGBE_STATS_LEN;
drvinfo->testinfo_len = IXGBE_TEST_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
@@ -1435,9 +1438,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
struct ixgbe_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
u32 reg_ctl;
- int i;
/* shut down the DMA engines now so they can be reinitialized later */
@@ -1445,14 +1446,15 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
reg_ctl &= ~IXGBE_RXCTRL_RXEN;
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
- reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0));
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx));
reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl);
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl);
/* now Tx */
- reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0));
+ reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx));
reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl);
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl);
+
if (hw->mac.type == ixgbe_mac_82599EB) {
reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_ctl &= ~IXGBE_DMATXCTL_TE;
@@ -1461,221 +1463,57 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
ixgbe_reset(adapter);
- if (tx_ring->desc && tx_ring->tx_buffer_info) {
- for (i = 0; i < tx_ring->count; i++) {
- struct ixgbe_tx_buffer *buf =
- &(tx_ring->tx_buffer_info[i]);
- if (buf->dma)
- dma_unmap_single(&pdev->dev, buf->dma,
- buf->length, DMA_TO_DEVICE);
- if (buf->skb)
- dev_kfree_skb(buf->skb);
- }
- }
-
- if (rx_ring->desc && rx_ring->rx_buffer_info) {
- for (i = 0; i < rx_ring->count; i++) {
- struct ixgbe_rx_buffer *buf =
- &(rx_ring->rx_buffer_info[i]);
- if (buf->dma)
- dma_unmap_single(&pdev->dev, buf->dma,
- IXGBE_RXBUFFER_2048,
- DMA_FROM_DEVICE);
- if (buf->skb)
- dev_kfree_skb(buf->skb);
- }
- }
-
- if (tx_ring->desc) {
- dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
- tx_ring->dma);
- tx_ring->desc = NULL;
- }
- if (rx_ring->desc) {
- dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
- rx_ring->dma);
- rx_ring->desc = NULL;
- }
-
- kfree(tx_ring->tx_buffer_info);
- tx_ring->tx_buffer_info = NULL;
- kfree(rx_ring->rx_buffer_info);
- rx_ring->rx_buffer_info = NULL;
+ ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring);
+ ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring);
}
static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
{
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
u32 rctl, reg_data;
- int i, ret_val;
+ int ret_val;
+ int err;
/* Setup Tx descriptor ring and Tx buffers */
+ tx_ring->count = IXGBE_DEFAULT_TXD;
+ tx_ring->queue_index = 0;
+ tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx;
+ tx_ring->numa_node = adapter->node;
- if (!tx_ring->count)
- tx_ring->count = IXGBE_DEFAULT_TXD;
-
- tx_ring->tx_buffer_info = kcalloc(tx_ring->count,
- sizeof(struct ixgbe_tx_buffer),
- GFP_KERNEL);
- if (!(tx_ring->tx_buffer_info)) {
- ret_val = 1;
- goto err_nomem;
- }
-
- tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
- tx_ring->size = ALIGN(tx_ring->size, 4096);
- tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
- &tx_ring->dma, GFP_KERNEL);
- if (!(tx_ring->desc)) {
- ret_val = 2;
- goto err_nomem;
- }
- tx_ring->next_to_use = tx_ring->next_to_clean = 0;
-
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0),
- ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0),
- ((u64) tx_ring->dma >> 32));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0),
- tx_ring->count * sizeof(union ixgbe_adv_tx_desc));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
- reg_data |= IXGBE_HLREG0_TXPADEN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+ err = ixgbe_setup_tx_resources(adapter, tx_ring);
+ if (err)
+ return 1;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
reg_data |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
}
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0));
- reg_data |= IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data);
-
- for (i = 0; i < tx_ring->count; i++) {
- union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
- struct sk_buff *skb;
- unsigned int size = 1024;
-
- skb = alloc_skb(size, GFP_KERNEL);
- if (!skb) {
- ret_val = 3;
- goto err_nomem;
- }
- skb_put(skb, size);
- tx_ring->tx_buffer_info[i].skb = skb;
- tx_ring->tx_buffer_info[i].length = skb->len;
- tx_ring->tx_buffer_info[i].dma =
- dma_map_single(&pdev->dev, skb->data, skb->len,
- DMA_TO_DEVICE);
- desc->read.buffer_addr =
- cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
- desc->read.cmd_type_len = cpu_to_le32(skb->len);
- desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
- IXGBE_TXD_CMD_IFCS |
- IXGBE_TXD_CMD_RS);
- desc->read.olinfo_status = 0;
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
- desc->read.olinfo_status |=
- (skb->len << IXGBE_ADVTXD_PAYLEN_SHIFT);
- }
+ ixgbe_configure_tx_ring(adapter, tx_ring);
/* Setup Rx Descriptor ring and Rx buffers */
-
- if (!rx_ring->count)
- rx_ring->count = IXGBE_DEFAULT_RXD;
-
- rx_ring->rx_buffer_info = kcalloc(rx_ring->count,
- sizeof(struct ixgbe_rx_buffer),
- GFP_KERNEL);
- if (!(rx_ring->rx_buffer_info)) {
+ rx_ring->count = IXGBE_DEFAULT_RXD;
+ rx_ring->queue_index = 0;
+ rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx;
+ rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048;
+ rx_ring->numa_node = adapter->node;
+
+ err = ixgbe_setup_rx_resources(adapter, rx_ring);
+ if (err) {
ret_val = 4;
goto err_nomem;
}
- rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
- rx_ring->size = ALIGN(rx_ring->size, 4096);
- rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
- &rx_ring->dma, GFP_KERNEL);
- if (!(rx_ring->desc)) {
- ret_val = 5;
- goto err_nomem;
- }
- rx_ring->next_to_use = rx_ring->next_to_clean = 0;
-
rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0),
- ((u64)rx_ring->dma & 0xFFFFFFFF));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0),
- ((u64) rx_ring->dma >> 32));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
- reg_data &= ~IXGBE_HLREG0_LPBK;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL);
-#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum
- Threshold Size mask */
- reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL);
-#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */
- reg_data &= ~IXGBE_MCSTCTRL_MO_MASK;
- reg_data |= adapter->hw.mac.mc_filter_type;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data);
-
- reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0));
- reg_data |= IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- int j = adapter->rx_ring[0]->reg_idx;
- u32 k;
- for (k = 0; k < 10; k++) {
- if (IXGBE_READ_REG(&adapter->hw,
- IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
- break;
- else
- msleep(1);
- }
- }
+ ixgbe_configure_rx_ring(adapter, rx_ring);
rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
- for (i = 0; i < rx_ring->count; i++) {
- union ixgbe_adv_rx_desc *rx_desc =
- IXGBE_RX_DESC_ADV(*rx_ring, i);
- struct sk_buff *skb;
-
- skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
- if (!skb) {
- ret_val = 6;
- goto err_nomem;
- }
- skb_reserve(skb, NET_IP_ALIGN);
- rx_ring->rx_buffer_info[i].skb = skb;
- rx_ring->rx_buffer_info[i].dma =
- dma_map_single(&pdev->dev, skb->data,
- IXGBE_RXBUFFER_2048, DMA_FROM_DEVICE);
- rx_desc->read.pkt_addr =
- cpu_to_le64(rx_ring->rx_buffer_info[i].dma);
- memset(skb->data, 0x00, skb->len);
- }
-
return 0;
err_nomem:
@@ -1689,16 +1527,21 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
u32 reg_data;
/* right now we only support MAC loopback in the driver */
-
- /* Setup MAC loopback */
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+ /* Setup MAC loopback */
reg_data |= IXGBE_HLREG0_LPBK;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+ reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
+
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC);
reg_data &= ~IXGBE_AUTOC_LMS_MASK;
reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
+ IXGBE_WRITE_FLUSH(&adapter->hw);
+ msleep(10);
/* Disable Atlas Tx lanes; re-enabled in reset path */
if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -1756,15 +1599,81 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb,
return 13;
}
+static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ struct ixgbe_ring *tx_ring,
+ unsigned int size)
+{
+ union ixgbe_adv_rx_desc *rx_desc;
+ struct ixgbe_rx_buffer *rx_buffer_info;
+ struct ixgbe_tx_buffer *tx_buffer_info;
+ const int bufsz = rx_ring->rx_buf_len;
+ u32 staterr;
+ u16 rx_ntc, tx_ntc, count = 0;
+
+ /* initialize next to clean and descriptor values */
+ rx_ntc = rx_ring->next_to_clean;
+ tx_ntc = tx_ring->next_to_clean;
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+ while (staterr & IXGBE_RXD_STAT_DD) {
+ /* check Rx buffer */
+ rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc];
+
+ /* unmap Rx buffer, will be remapped by alloc_rx_buffers */
+ dma_unmap_single(&adapter->pdev->dev,
+ rx_buffer_info->dma,
+ bufsz,
+ DMA_FROM_DEVICE);
+ rx_buffer_info->dma = 0;
+
+ /* verify contents of skb */
+ if (!ixgbe_check_lbtest_frame(rx_buffer_info->skb, size))
+ count++;
+
+ /* unmap buffer on Tx side */
+ tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc];
+ ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
+
+ /* increment Rx/Tx next to clean counters */
+ rx_ntc++;
+ if (rx_ntc == rx_ring->count)
+ rx_ntc = 0;
+ tx_ntc++;
+ if (tx_ntc == tx_ring->count)
+ tx_ntc = 0;
+
+ /* fetch next descriptor */
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+ }
+
+ /* re-map buffers to ring, store next to clean values */
+ ixgbe_alloc_rx_buffers(adapter, rx_ring, count);
+ rx_ring->next_to_clean = rx_ntc;
+ tx_ring->next_to_clean = tx_ntc;
+
+ return count;
+}
+
static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
{
struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
- int i, j, k, l, lc, good_cnt, ret_val = 0;
- unsigned long time;
+ int i, j, lc, good_cnt, ret_val = 0;
+ unsigned int size = 1024;
+ netdev_tx_t tx_ret_val;
+ struct sk_buff *skb;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1);
+ /* allocate test skb */
+ skb = alloc_skb(size, GFP_KERNEL);
+ if (!skb)
+ return 11;
+
+ /* place data into test skb */
+ ixgbe_create_lbtest_frame(skb, size);
+ skb_put(skb, size);
/*
* Calculate the loop count based on the largest descriptor ring
@@ -1777,54 +1686,40 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
else
lc = ((rx_ring->count / 64) * 2) + 1;
- k = l = 0;
for (j = 0; j <= lc; j++) {
- for (i = 0; i < 64; i++) {
- ixgbe_create_lbtest_frame(
- tx_ring->tx_buffer_info[k].skb,
- 1024);
- dma_sync_single_for_device(&pdev->dev,
- tx_ring->tx_buffer_info[k].dma,
- tx_ring->tx_buffer_info[k].length,
- DMA_TO_DEVICE);
- if (unlikely(++k == tx_ring->count))
- k = 0;
- }
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k);
- msleep(200);
- /* set the start time for the receive */
- time = jiffies;
+ /* reset count of good packets */
good_cnt = 0;
- do {
- /* receive the sent packets */
- dma_sync_single_for_cpu(&pdev->dev,
- rx_ring->rx_buffer_info[l].dma,
- IXGBE_RXBUFFER_2048,
- DMA_FROM_DEVICE);
- ret_val = ixgbe_check_lbtest_frame(
- rx_ring->rx_buffer_info[l].skb, 1024);
- if (!ret_val)
+
+ /* place 64 packets on the transmit queue*/
+ for (i = 0; i < 64; i++) {
+ skb_get(skb);
+ tx_ret_val = ixgbe_xmit_frame_ring(skb,
+ adapter->netdev,
+ adapter,
+ tx_ring);
+ if (tx_ret_val == NETDEV_TX_OK)
good_cnt++;
- if (++l == rx_ring->count)
- l = 0;
- /*
- * time + 20 msecs (200 msecs on 2.4) is more than
- * enough time to complete the receives, if it's
- * exceeded, break and error off
- */
- } while (good_cnt < 64 && jiffies < (time + 20));
+ }
+
if (good_cnt != 64) {
- /* ret_val is the same as mis-compare */
- ret_val = 13;
+ ret_val = 12;
break;
}
- if (jiffies >= (time + 20)) {
- /* Error code for time out error */
- ret_val = 14;
+
+ /* allow 200 milliseconds for packets to go from Tx to Rx */
+ msleep(200);
+
+ good_cnt = ixgbe_clean_test_rings(adapter, rx_ring,
+ tx_ring, size);
+ if (good_cnt != 64) {
+ ret_val = 13;
break;
}
}
+ /* free the original skb */
+ kfree_skb(skb);
+
return ret_val;
}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 072327c5e41a..2f1de8b90f9e 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -304,12 +304,13 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
if (!ixgbe_rx_is_fcoe(rx_desc))
goto ddp_out;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
sterr = le32_to_cpu(rx_desc->wb.upper.status_error);
fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR);
fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE);
if (fcerr == IXGBE_FCERR_BADCRC)
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))
fh = (struct fc_frame_header *)(skb->data +
@@ -471,7 +472,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter,
/* write context desc */
i = tx_ring->next_to_use;
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof);
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e32af434cc9d..d03eef96c0ba 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -50,7 +50,7 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
- "Intel(R) 10 Gigabit PCI Express Network Driver";
+ "Intel(R) 10 Gigabit PCI Express Network Driver";
#define DRV_VERSION "2.0.84-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
@@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
- void *p);
+ void *p);
static struct notifier_block dca_notifier = {
.notifier_call = ixgbe_notify_dca,
.next = NULL,
@@ -131,8 +131,8 @@ static struct notifier_block dca_notifier = {
#ifdef CONFIG_PCI_IOV
static unsigned int max_vfs;
module_param(max_vfs, uint, 0);
-MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
- "per physical function");
+MODULE_PARM_DESC(max_vfs,
+ "Maximum number of virtual functions to allocate per physical function");
#endif /* CONFIG_PCI_IOV */
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -169,8 +169,8 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
/* take a breather then clean up driver data */
msleep(100);
- if (adapter->vfinfo)
- kfree(adapter->vfinfo);
+
+ kfree(adapter->vfinfo);
adapter->vfinfo = NULL;
adapter->num_vfs = 0;
@@ -282,17 +282,17 @@ static void ixgbe_regdump(struct ixgbe_hw *hw, struct ixgbe_reg_info *reginfo)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
break;
default:
- printk(KERN_INFO "%-15s %08x\n", reginfo->name,
+ pr_info("%-15s %08x\n", reginfo->name,
IXGBE_READ_REG(hw, reginfo->ofs));
return;
}
for (i = 0; i < 8; i++) {
snprintf(rname, 16, "%s[%d-%d]", reginfo->name, i*8, i*8+7);
- printk(KERN_ERR "%-15s ", rname);
+ pr_err("%-15s", rname);
for (j = 0; j < 8; j++)
- printk(KERN_CONT "%08x ", regs[i*8+j]);
- printk(KERN_CONT "\n");
+ pr_cont(" %08x", regs[i*8+j]);
+ pr_cont("\n");
}
}
@@ -322,18 +322,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Print netdevice Info */
if (netdev) {
dev_info(&adapter->pdev->dev, "Net device Info\n");
- printk(KERN_INFO "Device Name state "
+ pr_info("Device Name state "
"trans_start last_rx\n");
- printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
- netdev->name,
- netdev->state,
- netdev->trans_start,
- netdev->last_rx);
+ pr_info("%-15s %016lX %016lX %016lX\n",
+ netdev->name,
+ netdev->state,
+ netdev->trans_start,
+ netdev->last_rx);
}
/* Print Registers */
dev_info(&adapter->pdev->dev, "Register Dump\n");
- printk(KERN_INFO " Register Name Value\n");
+ pr_info(" Register Name Value\n");
for (reginfo = (struct ixgbe_reg_info *)ixgbe_reg_info_tbl;
reginfo->name; reginfo++) {
ixgbe_regdump(hw, reginfo);
@@ -344,13 +344,12 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
goto exit;
dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
- printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ] "
- "leng ntw timestamp\n");
+ pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n");
for (n = 0; n < adapter->num_tx_queues; n++) {
tx_ring = adapter->tx_ring[n];
tx_buffer_info =
&tx_ring->tx_buffer_info[tx_ring->next_to_clean];
- printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
+ pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
n, tx_ring->next_to_use, tx_ring->next_to_clean,
(u64)tx_buffer_info->dma,
tx_buffer_info->length,
@@ -377,18 +376,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
for (n = 0; n < adapter->num_tx_queues; n++) {
tx_ring = adapter->tx_ring[n];
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index);
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "T [desc] [address 63:0 ] "
+ pr_info("------------------------------------\n");
+ pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
+ pr_info("------------------------------------\n");
+ pr_info("T [desc] [address 63:0 ] "
"[PlPOIdStDDt Ln] [bi->dma ] "
"leng ntw timestamp bi->skb\n");
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
u0 = (struct my_u0 *)tx_desc;
- printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX"
+ pr_info("T [0x%03X] %016llX %016llX %016llX"
" %04X %3X %016llX %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
@@ -399,13 +398,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
tx_buffer_info->skb);
if (i == tx_ring->next_to_use &&
i == tx_ring->next_to_clean)
- printk(KERN_CONT " NTC/U\n");
+ pr_cont(" NTC/U\n");
else if (i == tx_ring->next_to_use)
- printk(KERN_CONT " NTU\n");
+ pr_cont(" NTU\n");
else if (i == tx_ring->next_to_clean)
- printk(KERN_CONT " NTC\n");
+ pr_cont(" NTC\n");
else
- printk(KERN_CONT "\n");
+ pr_cont("\n");
if (netif_msg_pktdata(adapter) &&
tx_buffer_info->dma != 0)
@@ -419,11 +418,11 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Print RX Rings Summary */
rx_ring_summary:
dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
- printk(KERN_INFO "Queue [NTU] [NTC]\n");
+ pr_info("Queue [NTU] [NTC]\n");
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
- printk(KERN_INFO "%5d %5X %5X\n", n,
- rx_ring->next_to_use, rx_ring->next_to_clean);
+ pr_info("%5d %5X %5X\n",
+ n, rx_ring->next_to_use, rx_ring->next_to_clean);
}
/* Print RX Rings */
@@ -454,30 +453,30 @@ rx_ring_summary:
*/
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index);
- printk(KERN_INFO "------------------------------------\n");
- printk(KERN_INFO "R [desc] [ PktBuf A0] "
+ pr_info("------------------------------------\n");
+ pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
+ pr_info("------------------------------------\n");
+ pr_info("R [desc] [ PktBuf A0] "
"[ HeadBuf DD] [bi->dma ] [bi->skb] "
"<-- Adv Rx Read format\n");
- printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] "
+ pr_info("RWB[desc] [PcsmIpSHl PtRs] "
"[vl er S cks ln] ---------------- [bi->skb] "
"<-- Adv Rx Write-Back format\n");
for (i = 0; i < rx_ring->count; i++) {
rx_buffer_info = &rx_ring->rx_buffer_info[i];
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
u0 = (struct my_u0 *)rx_desc;
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
if (staterr & IXGBE_RXD_STAT_DD) {
/* Descriptor Done */
- printk(KERN_INFO "RWB[0x%03X] %016llX "
+ pr_info("RWB[0x%03X] %016llX "
"%016llX ---------------- %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
rx_buffer_info->skb);
} else {
- printk(KERN_INFO "R [0x%03X] %016llX "
+ pr_info("R [0x%03X] %016llX "
"%016llX %016llX %p", i,
le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
@@ -503,11 +502,11 @@ rx_ring_summary:
}
if (i == rx_ring->next_to_use)
- printk(KERN_CONT " NTU\n");
+ pr_cont(" NTU\n");
else if (i == rx_ring->next_to_clean)
- printk(KERN_CONT " NTC\n");
+ pr_cont(" NTC\n");
else
- printk(KERN_CONT "\n");
+ pr_cont("\n");
}
}
@@ -523,7 +522,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware take over control of h/w */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
}
static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
@@ -533,7 +532,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware know the driver has taken over */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
/*
@@ -545,7 +544,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
*
*/
static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
- u8 queue, u8 msix_vector)
+ u8 queue, u8 msix_vector)
{
u32 ivar, index;
struct ixgbe_hw *hw = &adapter->hw;
@@ -586,7 +585,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
}
static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
- u64 qmask)
+ u64 qmask)
{
u32 mask;
@@ -601,9 +600,9 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
}
}
-static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
- struct ixgbe_tx_buffer
- *tx_buffer_info)
+void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
+ struct ixgbe_tx_buffer
+ *tx_buffer_info)
{
if (tx_buffer_info->dma) {
if (tx_buffer_info->mapped_as_page)
@@ -637,7 +636,7 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
* Returns : true if in xon state (currently not paused)
*/
static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txoff = IXGBE_TFCS_TXOFF;
@@ -682,8 +681,8 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
}
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- unsigned int eop)
+ struct ixgbe_ring *tx_ring,
+ unsigned int eop)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -695,7 +694,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
ixgbe_tx_xon_state(adapter, tx_ring)) {
/* detected Tx unit hang */
union ixgbe_adv_tx_desc *tx_desc;
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
e_err(drv, "Detected Tx Unit Hang\n"
" Tx Queue <%d>\n"
" TDH, TDT <%x>, <%x>\n"
@@ -732,7 +731,7 @@ static void ixgbe_tx_timeout(struct net_device *netdev);
* @tx_ring: tx ring to clean
**/
static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
struct net_device *netdev = adapter->netdev;
@@ -743,7 +742,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
i = tx_ring->next_to_clean;
eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
(count < tx_ring->work_limit)) {
@@ -751,7 +750,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
struct sk_buff *skb;
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
cleaned = (i == eop);
skb = tx_buffer_info->skb;
@@ -781,7 +780,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
}
ixgbe_unmap_and_free_tx_resource(adapter,
- tx_buffer_info);
+ tx_buffer_info);
tx_desc->wb.status = 0;
@@ -791,14 +790,14 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
}
eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop);
}
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
if (unlikely(count && netif_carrier_ok(netdev) &&
- (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
+ (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
@@ -832,7 +831,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
#ifdef CONFIG_IXGBE_DCA
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 rxctrl;
int cpu = get_cpu();
@@ -846,13 +845,13 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+ IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
}
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
rx_ring->cpu = cpu;
}
@@ -860,7 +859,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txctrl;
int cpu = get_cpu();
@@ -878,7 +877,7 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q));
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
- IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl);
}
@@ -946,16 +945,15 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_desc: rx descriptor
**/
static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
- struct sk_buff *skb, u8 status,
- struct ixgbe_ring *ring,
- union ixgbe_adv_rx_desc *rx_desc)
+ struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
+ union ixgbe_adv_rx_desc *rx_desc)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
struct napi_struct *napi = &q_vector->napi;
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- skb_record_rx_queue(skb, ring->queue_index);
if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
@@ -981,7 +979,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
{
u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Rx csum disabled */
if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
@@ -1017,7 +1015,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
}
static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
- struct ixgbe_ring *rx_ring, u32 val)
+ struct ixgbe_ring *rx_ring, u32 val)
{
/*
* Force memory writes to complete before letting h/w
@@ -1033,25 +1031,27 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
* ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int cleaned_count)
+void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring,
+ int cleaned_count)
{
+ struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
unsigned int i;
+ unsigned int bufsz = rx_ring->rx_buf_len;
i = rx_ring->next_to_use;
bi = &rx_ring->rx_buffer_info[i];
while (cleaned_count--) {
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
if (!bi->page_dma &&
(rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) {
if (!bi->page) {
- bi->page = alloc_page(GFP_ATOMIC);
+ bi->page = netdev_alloc_page(netdev);
if (!bi->page) {
adapter->alloc_rx_page_failed++;
goto no_buffers;
@@ -1063,29 +1063,28 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
}
bi->page_dma = dma_map_page(&pdev->dev, bi->page,
- bi->page_offset,
- (PAGE_SIZE / 2),
+ bi->page_offset,
+ (PAGE_SIZE / 2),
DMA_FROM_DEVICE);
}
if (!bi->skb) {
- struct sk_buff *skb;
- /* netdev_alloc_skb reserves 32 bytes up front!! */
- uint bufsz = rx_ring->rx_buf_len + SMP_CACHE_BYTES;
- skb = netdev_alloc_skb(adapter->netdev, bufsz);
+ struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev,
+ bufsz);
+ bi->skb = skb;
if (!skb) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
}
+ /* initialize queue mapping */
+ skb_record_rx_queue(skb, rx_ring->queue_index);
+ }
- /* advance the data pointer to the next cache line */
- skb_reserve(skb, (PTR_ALIGN(skb->data, SMP_CACHE_BYTES)
- - skb->data));
-
- bi->skb = skb;
- bi->dma = dma_map_single(&pdev->dev, skb->data,
- rx_ring->rx_buf_len,
+ if (!bi->dma) {
+ bi->dma = dma_map_single(&pdev->dev,
+ bi->skb->data,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
}
/* Refresh the desc even if buffer_addrs didn't change because
@@ -1095,6 +1094,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
} else {
rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
+ rx_desc->read.hdr_addr = 0;
}
i++;
@@ -1126,8 +1126,8 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
{
return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
- IXGBE_RXDADV_RSCCNT_MASK) >>
- IXGBE_RXDADV_RSCCNT_SHIFT;
+ IXGBE_RXDADV_RSCCNT_MASK) >>
+ IXGBE_RXDADV_RSCCNT_SHIFT;
}
/**
@@ -1140,7 +1140,7 @@ static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
* turns it into the frag list owner.
**/
static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb,
- u64 *count)
+ u64 *count)
{
unsigned int frag_list_size = 0;
@@ -1168,8 +1168,8 @@ struct ixgbe_rsc_cb {
#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
- struct ixgbe_ring *rx_ring,
- int *work_done, int work_to_do)
+ struct ixgbe_ring *rx_ring,
+ int *work_done, int work_to_do)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
struct net_device *netdev = adapter->netdev;
@@ -1188,7 +1188,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
i = rx_ring->next_to_clean;
- rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
rx_buffer_info = &rx_ring->rx_buffer_info[i];
@@ -1231,9 +1231,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
} else {
dma_unmap_single(&pdev->dev,
- rx_buffer_info->dma,
- rx_ring->rx_buf_len,
- DMA_FROM_DEVICE);
+ rx_buffer_info->dma,
+ rx_ring->rx_buf_len,
+ DMA_FROM_DEVICE);
}
rx_buffer_info->dma = 0;
skb_put(skb, len);
@@ -1244,9 +1244,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
PAGE_SIZE / 2, DMA_FROM_DEVICE);
rx_buffer_info->page_dma = 0;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
- rx_buffer_info->page,
- rx_buffer_info->page_offset,
- upper_len);
+ rx_buffer_info->page,
+ rx_buffer_info->page_offset,
+ upper_len);
if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
(page_count(rx_buffer_info->page) != 1))
@@ -1263,7 +1263,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (i == rx_ring->count)
i = 0;
- next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
+ next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i);
prefetch(next_rxd);
cleaned_count++;
@@ -1280,18 +1280,20 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (staterr & IXGBE_RXD_STAT_EOP) {
if (skb->prev)
- skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
+ skb = ixgbe_transform_rsc_queue(skb,
+ &(rx_ring->rsc_count));
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
if (IXGBE_RSC_CB(skb)->delay_unmap) {
dma_unmap_single(&pdev->dev,
IXGBE_RSC_CB(skb)->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
IXGBE_RSC_CB(skb)->dma = 0;
IXGBE_RSC_CB(skb)->delay_unmap = false;
}
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
- rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
+ rx_ring->rsc_count +=
+ skb_shinfo(skb)->nr_frags;
else
rx_ring->rsc_count++;
rx_ring->rsc_flush++;
@@ -1403,24 +1405,24 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vector = adapter->q_vector[v_idx];
/* XXX for_each_set_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
- adapter->num_rx_queues);
+ adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx]->reg_idx;
ixgbe_set_ivar(adapter, 0, j, v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
- adapter->num_rx_queues,
- r_idx + 1);
+ adapter->num_rx_queues,
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->txr_idx,
- adapter->num_tx_queues);
+ adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx]->reg_idx;
ixgbe_set_ivar(adapter, 1, j, v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
- adapter->num_tx_queues,
- r_idx + 1);
+ adapter->num_tx_queues,
+ r_idx + 1);
}
if (q_vector->txr_count && !q_vector->rxr_count)
@@ -1435,7 +1437,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
- v_idx);
+ v_idx);
else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
ixgbe_set_ivar(adapter, -1, 1, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
@@ -1477,8 +1479,8 @@ enum latency_range {
* parameter (see ixgbe_param.c)
**/
static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
- u32 eitr, u8 itr_setting,
- int packets, int bytes)
+ u32 eitr, u8 itr_setting,
+ int packets, int bytes)
{
unsigned int retval = itr_setting;
u32 timepassed_us;
@@ -1567,30 +1569,30 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = adapter->tx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->tx_itr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
- q_vector->tx_itr - 1 : ret_itr);
+ q_vector->tx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = adapter->rx_ring[r_idx];
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->rx_itr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
- q_vector->rx_itr - 1 : ret_itr);
+ q_vector->rx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
@@ -1627,39 +1629,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
static void ixgbe_check_overtemp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- check_overtemp_task);
+ struct ixgbe_adapter,
+ check_overtemp_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = adapter->interrupt_event;
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) {
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82599_T3_LOM: {
- u32 autoneg;
- bool link_up = false;
+ if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE))
+ return;
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82599_T3_LOM: {
+ u32 autoneg;
+ bool link_up = false;
- if (hw->mac.ops.check_link)
- hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
+ if (hw->mac.ops.check_link)
+ hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
- if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
- (eicr & IXGBE_EICR_LSC))
- /* Check if this is due to overtemp */
- if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
- break;
- }
+ if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
+ (eicr & IXGBE_EICR_LSC))
+ /* Check if this is due to overtemp */
+ if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
+ break;
+ return;
+ }
+ default:
+ if (!(eicr & IXGBE_EICR_GPI_SDP0))
return;
- default:
- if (!(eicr & IXGBE_EICR_GPI_SDP0))
- return;
- break;
- }
- e_crit(drv, "Network adapter has been stopped because it has "
- "over heated. Restart the computer. If the problem "
- "persists, power off the system and replace the "
- "adapter\n");
- /* write to clear the interrupt */
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+ break;
}
+ e_crit(drv,
+ "Network adapter has been stopped because it has over heated. "
+ "Restart the computer. If the problem persists, "
+ "power off the system and replace the adapter\n");
+ /* write to clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
}
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
@@ -1746,9 +1749,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
netif_tx_stop_all_queues(netdev);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring =
- adapter->tx_ring[i];
+ adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state))
+ &tx_ring->reinit_state))
schedule_work(&adapter->fdir_reinit_task);
}
}
@@ -1777,7 +1780,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
}
static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
- u64 qmask)
+ u64 qmask)
{
u32 mask;
@@ -1809,7 +1812,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* EIAM disabled interrupts (on this vector) for us */
@@ -1837,7 +1840,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
rx_ring->total_bytes = 0;
rx_ring->total_packets = 0;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
if (!q_vector->rxr_count)
@@ -1867,7 +1870,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
ring->total_bytes = 0;
ring->total_packets = 0;
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
@@ -1876,7 +1879,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
ring->total_bytes = 0;
ring->total_packets = 0;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* EIAM disabled interrupts (on this vector) for us */
@@ -1896,7 +1899,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *rx_ring = NULL;
int work_done = 0;
@@ -1918,7 +1921,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
- ((u64)1 << q_vector->v_idx));
+ ((u64)1 << q_vector->v_idx));
}
return work_done;
@@ -1935,7 +1938,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *ring = NULL;
int work_done = 0, i;
@@ -1951,7 +1954,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
#endif
tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
/* attempt to distribute budget to each queue fairly, but don't allow
@@ -1967,7 +1970,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
#endif
ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
@@ -1979,7 +1982,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
- ((u64)1 << q_vector->v_idx));
+ ((u64)1 << q_vector->v_idx));
return 0;
}
@@ -1997,7 +2000,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *tx_ring = NULL;
int work_done = 0;
@@ -2019,14 +2022,15 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
if (adapter->tx_itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
+ ixgbe_irq_enable_queues(adapter,
+ ((u64)1 << q_vector->v_idx));
}
return work_done;
}
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
@@ -2035,7 +2039,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int t_idx)
+ int t_idx)
{
struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
@@ -2055,7 +2059,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
* mapping configurations in here.
**/
static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int v_start = 0;
int rxr_idx = 0, txr_idx = 0;
@@ -2122,7 +2126,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev;
irqreturn_t (*handler)(int, void *);
int i, vector, q_vectors, err;
- int ri=0, ti=0;
+ int ri = 0, ti = 0;
/* Decrement for Other and TCP Timer vectors */
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -2133,26 +2137,24 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
goto out;
#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
- (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
- &ixgbe_msix_clean_many)
+ (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
+ &ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
handler = SET_HANDLER(adapter->q_vector[vector]);
- if(handler == &ixgbe_msix_clean_rx) {
+ if (handler == &ixgbe_msix_clean_rx) {
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "rx", ri++);
- }
- else if(handler == &ixgbe_msix_clean_tx) {
+ } else if (handler == &ixgbe_msix_clean_tx) {
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "tx", ti++);
- }
- else
+ } else
sprintf(adapter->name[vector], "%s-%s-%d",
netdev->name, "TxRx", vector);
err = request_irq(adapter->msix_entries[vector].vector,
- handler, 0, adapter->name[vector],
- adapter->q_vector[vector]);
+ handler, 0, adapter->name[vector],
+ adapter->q_vector[vector]);
if (err) {
e_err(probe, "request_irq failed for MSIX interrupt "
"Error: %d\n", err);
@@ -2162,7 +2164,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
sprintf(adapter->name[vector], "%s:lsc", netdev->name);
err = request_irq(adapter->msix_entries[vector].vector,
- ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+ ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
if (err) {
e_err(probe, "request_irq for msix_lsc failed: %d\n", err);
goto free_queue_irqs;
@@ -2173,7 +2175,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- adapter->q_vector[i]);
+ adapter->q_vector[i]);
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -2191,13 +2193,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
struct ixgbe_ring *tx_ring = adapter->tx_ring[0];
q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
- q_vector->tx_itr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr,
- q_vector->rx_itr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
@@ -2343,10 +2345,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
err = ixgbe_request_msix_irqs(adapter);
} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
err = request_irq(adapter->pdev->irq, ixgbe_intr, 0,
- netdev->name, netdev);
+ netdev->name, netdev);
} else {
err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED,
- netdev->name, netdev);
+ netdev->name, netdev);
}
if (err)
@@ -2370,7 +2372,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- adapter->q_vector[i]);
+ adapter->q_vector[i]);
}
ixgbe_reset_q_vectors(adapter);
@@ -2413,7 +2415,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
- EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));
+ EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));
ixgbe_set_ivar(adapter, 0, 0, 0);
ixgbe_set_ivar(adapter, 1, 0, 0);
@@ -2425,95 +2427,140 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset
+ * ixgbe_configure_tx_ring - Configure 8259x Tx ring after Reset
* @adapter: board private structure
+ * @ring: structure containing ring specific data
*
- * Configure the Tx unit of the MAC after a reset.
+ * Configure the Tx descriptor ring after a reset.
**/
-static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
+void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
{
- u64 tdba;
struct ixgbe_hw *hw = &adapter->hw;
- u32 i, j, tdlen, txctrl;
+ u64 tdba = ring->dma;
+ int wait_loop = 10;
+ u32 txdctl;
+ u16 reg_idx = ring->reg_idx;
- /* Setup the HW Tx Head and Tail descriptor pointers */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- struct ixgbe_ring *ring = adapter->tx_ring[i];
- j = ring->reg_idx;
- tdba = ring->dma;
- tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
- IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
- (tdba & DMA_BIT_MASK(32)));
- IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
- IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
- IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
- adapter->tx_ring[i]->head = IXGBE_TDH(j);
- adapter->tx_ring[i]->tail = IXGBE_TDT(j);
- /*
- * Disable Tx Head Writeback RO bit, since this hoses
- * bookkeeping if things aren't delivered in order.
- */
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
- break;
- case ixgbe_mac_82599EB:
- default:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
- break;
- }
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
- break;
- case ixgbe_mac_82599EB:
- default:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
- break;
- }
+ /* disable queue to avoid issues while updating state */
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
+ txdctl & ~IXGBE_TXDCTL_ENABLE);
+ IXGBE_WRITE_FLUSH(hw);
+
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx),
+ (tdba & DMA_BIT_MASK(32)));
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx),
+ ring->count * sizeof(union ixgbe_adv_tx_desc));
+ IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0);
+ ring->head = IXGBE_TDH(reg_idx);
+ ring->tail = IXGBE_TDT(reg_idx);
+
+ /* configure fetching thresholds */
+ if (adapter->rx_itr_setting == 0) {
+ /* cannot set wthresh when itr==0 */
+ txdctl &= ~0x007F0000;
+ } else {
+ /* enable WTHRESH=8 descriptors, to encourage burst writeback */
+ txdctl |= (8 << 16);
+ }
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ /* PThresh workaround for Tx hang with DFP enabled. */
+ txdctl |= 32;
}
- if (hw->mac.type == ixgbe_mac_82599EB) {
- u32 rttdcs;
- u32 mask;
+ /* reinitialize flowdirector state */
+ set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state);
- /* disable the arbiter while setting MTQC */
- rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
- rttdcs |= IXGBE_RTTDCS_ARBDIS;
- IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+ /* enable queue */
+ txdctl |= IXGBE_TXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl);
- /* set transmit pool layout */
- mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED);
- switch (adapter->flags & mask) {
+ /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ if (hw->mac.type == ixgbe_mac_82598EB &&
+ !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+ return;
- case (IXGBE_FLAG_SRIOV_ENABLED):
- IXGBE_WRITE_REG(hw, IXGBE_MTQC,
- (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF));
- break;
+ /* poll to verify queue is enabled */
+ do {
+ msleep(1);
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
+ } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
+ if (!wait_loop)
+ e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+}
- case (IXGBE_FLAG_DCB_ENABLED):
- /* We enable 8 traffic classes, DCB only */
- IXGBE_WRITE_REG(hw, IXGBE_MTQC,
- (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ));
- break;
+static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rttdcs;
+ u32 mask;
- default:
- IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
- break;
- }
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ /* disable the arbiter while setting MTQC */
+ rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ rttdcs |= IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+
+ /* set transmit pool layout */
+ mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED);
+ switch (adapter->flags & mask) {
+
+ case (IXGBE_FLAG_SRIOV_ENABLED):
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+ (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF));
+ break;
+
+ case (IXGBE_FLAG_DCB_ENABLED):
+ /* We enable 8 traffic classes, DCB only */
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC,
+ (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ));
+ break;
+
+ default:
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+ break;
+ }
+
+ /* re-enable the arbiter */
+ rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+}
+
+/**
+ * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 dmatxctl;
+ u32 i;
+
+ ixgbe_setup_mtqc(adapter);
- /* re-eable the arbiter */
- rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
- IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+ if (hw->mac.type != ixgbe_mac_82598EB) {
+ /* DMATXCTL.EN must be before Tx queues are enabled */
+ dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ dmatxctl |= IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
}
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]);
}
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 srrctl;
int index;
@@ -2529,6 +2576,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+ if (adapter->num_vfs)
+ srrctl |= IXGBE_SRRCTL_DROP_EN;
srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
IXGBE_SRRCTL_BSIZEHDR_MASK;
@@ -2549,20 +2598,46 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
-static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
+static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
{
- u32 mrqc = 0;
+ struct ixgbe_hw *hw = &adapter->hw;
+ static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
+ 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
+ 0x6A3E67EA, 0x14364D17, 0x3BED200D};
+ u32 mrqc = 0, reta = 0;
+ u32 rxcsum;
+ int i, j;
int mask;
- if (!(adapter->hw.mac.type == ixgbe_mac_82599EB))
- return mrqc;
+ /* Fill out hash function seeds */
+ for (i = 0; i < 10; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
+
+ /* Fill out redirection table */
+ for (i = 0, j = 0; i < 128; i++, j++) {
+ if (j == adapter->ring_feature[RING_F_RSS].indices)
+ j = 0;
+ /* reta = 4-byte sliding window of
+ * 0x00..(indices-1)(indices-1)00..etc. */
+ reta = (reta << 8) | (j * 0x11);
+ if ((i & 3) == 3)
+ IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
+ }
+
+ /* Disable indicating checksum in descriptor, enables RSS hash */
+ rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
+ rxcsum |= IXGBE_RXCSUM_PCSD;
+ IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
- mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ mask = adapter->flags & IXGBE_FLAG_RSS_ENABLED;
+ else
+ mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
#ifdef CONFIG_IXGBE_DCB
- | IXGBE_FLAG_DCB_ENABLED
+ | IXGBE_FLAG_DCB_ENABLED
#endif
- | IXGBE_FLAG_SRIOV_ENABLED
- );
+ | IXGBE_FLAG_SRIOV_ENABLED
+ );
switch (mask) {
case (IXGBE_FLAG_RSS_ENABLED):
@@ -2580,7 +2655,13 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
break;
}
- return mrqc;
+ /* Perform hash on these packet types */
+ mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
+ | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6
+ | IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
}
/**
@@ -2588,25 +2669,26 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
* @adapter: address of board private structure
* @index: index of ring to set
**/
-static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index)
+static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
{
- struct ixgbe_ring *rx_ring;
struct ixgbe_hw *hw = &adapter->hw;
- int j;
u32 rscctrl;
int rx_buf_len;
+ u16 reg_idx = ring->reg_idx;
- rx_ring = adapter->rx_ring[index];
- j = rx_ring->reg_idx;
- rx_buf_len = rx_ring->rx_buf_len;
- rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
+ if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
+ return;
+
+ rx_buf_len = ring->rx_buf_len;
+ rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx));
rscctrl |= IXGBE_RSCCTL_RSCEN;
/*
* we must limit the number of descriptors so that the
* total size of max desc * buf_len is not greater
* than 65535
*/
- if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
+ if (ring->flags & IXGBE_RING_RX_PS_ENABLED) {
#if (MAX_SKB_FRAGS > 16)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
#elif (MAX_SKB_FRAGS > 8)
@@ -2624,31 +2706,181 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index)
else
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
}
- IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
}
/**
- * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
- * @adapter: board private structure
+ * ixgbe_set_uta - Set unicast filter table address
+ * @adapter: board private structure
*
- * Configure the Rx unit of the MAC after a reset.
+ * The unicast table address is a register array of 32-bit registers.
+ * The table is meant to be used in a way similar to how the MTA is used
+ * however due to certain limitations in the hardware it is necessary to
+ * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
+ * enable bit to allow vlan tag stripping when promiscuous mode is enabled
**/
-static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
+static void ixgbe_set_uta(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ /* The UTA table only exists on 82599 hardware and newer */
+ if (hw->mac.type < ixgbe_mac_82599EB)
+ return;
+
+ /* we only need to do this if VMDq is enabled */
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return;
+
+ for (i = 0; i < 128; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0);
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int reg_idx = ring->reg_idx;
+ int wait_loop = IXGBE_MAX_RX_DESC_POLL;
+ u32 rxdctl;
+
+ /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ if (hw->mac.type == ixgbe_mac_82598EB &&
+ !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+ return;
+
+ do {
+ msleep(1);
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+ } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
+
+ if (!wait_loop) {
+ e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within "
+ "the polling period\n", reg_idx);
+ }
+}
+
+void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 rdba = ring->dma;
+ u32 rxdctl;
+ u16 reg_idx = ring->reg_idx;
+
+ /* disable queue to avoid issues while updating state */
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx),
+ rxdctl & ~IXGBE_RXDCTL_ENABLE);
+ IXGBE_WRITE_FLUSH(hw);
+
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32)));
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx),
+ ring->count * sizeof(union ixgbe_adv_rx_desc));
+ IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0);
+ ring->head = IXGBE_RDH(reg_idx);
+ ring->tail = IXGBE_RDT(reg_idx);
+
+ ixgbe_configure_srrctl(adapter, ring);
+ ixgbe_configure_rscctl(adapter, ring);
+
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * enable cache line friendly hardware writes:
+ * PTHRESH=32 descriptors (half the internal cache),
+ * this also removes ugly rx_no_buffer_count increment
+ * HTHRESH=4 descriptors (to minimize latency on fetch)
+ * WTHRESH=8 burst writeback up to two cache lines
+ */
+ rxdctl &= ~0x3FFFFF;
+ rxdctl |= 0x080420;
+ }
+
+ /* enable receive descriptor ring */
+ rxdctl |= IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
+
+ ixgbe_rx_desc_queue_enable(adapter, ring);
+ ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring));
+}
+
+static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int p;
+
+ /* PSRTYPE must be initialized in non 82598 adapters */
+ u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+ IXGBE_PSRTYPE_UDPHDR |
+ IXGBE_PSRTYPE_IPV4HDR |
+ IXGBE_PSRTYPE_L2HDR |
+ IXGBE_PSRTYPE_IPV6HDR;
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED)
+ psrtype |= (adapter->num_rx_queues_per_pool << 29);
+
+ for (p = 0; p < adapter->num_rx_pools; p++)
+ IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(adapter->num_vfs + p),
+ psrtype);
+}
+
+static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 gcr_ext;
+ u32 vt_reg_bits;
+ u32 reg_offset, vf_shift;
+ u32 vmdctl;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return;
+
+ vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
+ vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN | IXGBE_VT_CTL_REPLEN;
+ vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
+
+ vf_shift = adapter->num_vfs % 32;
+ reg_offset = (adapter->num_vfs > 32) ? 1 : 0;
+
+ /* Enable only the PF's pool for Tx/Rx */
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift));
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+
+ /* Map PF MAC address in RAR Entry 0 to first pool following VFs */
+ hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs);
+
+ /*
+ * Set up VF register offsets for selected VT Mode,
+ * i.e. 32 or 64 VFs for SR-IOV
+ */
+ gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
+ gcr_ext |= IXGBE_GCR_EXT_MSIX_EN;
+ gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64;
+ IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
+
+ /* enable Tx loopback for VF/PF communication */
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+}
+
+static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
{
- u64 rdba;
struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_ring *rx_ring;
struct net_device *netdev = adapter->netdev;
int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- int i, j;
- u32 rdlen, rxctrl, rxcsum;
- static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
- 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
- 0x6A3E67EA, 0x14364D17, 0x3BED200D};
- u32 fctrl, hlreg0;
- u32 reta = 0, mrqc = 0;
- u32 rdrxctl;
int rx_buf_len;
+ struct ixgbe_ring *rx_ring;
+ int i;
+ u32 mhadd, hlreg0;
/* Decide whether to use packet split mode or not */
/* Do not use packet split if we're in SR-IOV Mode */
@@ -2658,62 +2890,40 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
rx_buf_len = IXGBE_RX_HDR_SIZE;
- if (hw->mac.type == ixgbe_mac_82599EB) {
- /* PSRTYPE must be initialized in 82599 */
- u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
- IXGBE_PSRTYPE_UDPHDR |
- IXGBE_PSRTYPE_IPV4HDR |
- IXGBE_PSRTYPE_IPV6HDR |
- IXGBE_PSRTYPE_L2HDR;
- IXGBE_WRITE_REG(hw,
- IXGBE_PSRTYPE(adapter->num_vfs),
- psrtype);
- }
} else {
if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) &&
(netdev->mtu <= ETH_DATA_LEN))
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
- rx_buf_len = ALIGN(max_frame, 1024);
+ rx_buf_len = ALIGN(max_frame + VLAN_HLEN, 1024);
}
- fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- fctrl |= IXGBE_FCTRL_BAM;
- fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
- fctrl |= IXGBE_FCTRL_PMCF;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
+#ifdef IXGBE_FCOE
+ /* adjust max frame to be able to do baby jumbo for FCoE */
+ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+ (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
+ max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+
+#endif /* IXGBE_FCOE */
+ mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
+ if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
+ mhadd &= ~IXGBE_MHADD_MFS_MASK;
+ mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
+ }
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- if (adapter->netdev->mtu <= ETH_DATA_LEN)
- hlreg0 &= ~IXGBE_HLREG0_JUMBOEN;
- else
- hlreg0 |= IXGBE_HLREG0_JUMBOEN;
-#ifdef IXGBE_FCOE
- if (netdev->features & NETIF_F_FCOE_MTU)
- hlreg0 |= IXGBE_HLREG0_JUMBOEN;
-#endif
+ /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */
+ hlreg0 |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
- rdlen = adapter->rx_ring[0]->count * sizeof(union ixgbe_adv_rx_desc);
- /* disable receives while setting up the descriptors */
- rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
-
/*
* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring
*/
for (i = 0; i < adapter->num_rx_queues; i++) {
rx_ring = adapter->rx_ring[i];
- rdba = rx_ring->dma;
- j = rx_ring->reg_idx;
- IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
- IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
- IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
- rx_ring->head = IXGBE_RDH(j);
- rx_ring->tail = IXGBE_RDT(j);
rx_ring->rx_buf_len = rx_buf_len;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
@@ -2729,15 +2939,21 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)
rx_ring->rx_buf_len =
- IXGBE_FCOE_JUMBO_FRAME_SIZE;
+ IXGBE_FCOE_JUMBO_FRAME_SIZE;
}
}
-
#endif /* IXGBE_FCOE */
- ixgbe_configure_srrctl(adapter, rx_ring);
}
- if (hw->mac.type == ixgbe_mac_82598EB) {
+}
+
+static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
/*
* For VMDq support of different descriptor types or
* buffer sizes through the use of multiple SRRCTL
@@ -2748,110 +2964,66 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
* effects of setting this bit are only that SRRCTL must be
* fully programmed [0..15]
*/
- rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_MVMEN;
- IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+ break;
+ case ixgbe_mac_82599EB:
+ /* Disable RSC for ACK packets */
+ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
+ (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
+ rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
+ /* hardware requires some bits to be set by default */
+ rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX);
+ rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ break;
+ default:
+ /* We should do nothing since we don't know this hardware */
+ return;
}
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
- u32 vt_reg_bits;
- u32 reg_offset, vf_shift;
- u32 vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
- vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN
- | IXGBE_VT_CTL_REPLEN;
- vt_reg_bits |= (adapter->num_vfs <<
- IXGBE_VT_CTL_POOL_SHIFT);
- IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits);
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, 0);
-
- vf_shift = adapter->num_vfs % 32;
- reg_offset = adapter->num_vfs / 32;
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0);
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0);
- /* Enable only the PF's pool for Tx/Rx */
- IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift));
- IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift));
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
- ixgbe_set_vmolr(hw, adapter->num_vfs, true);
- }
-
- /* Program MRQC for the distribution of queues */
- mrqc = ixgbe_setup_mrqc(adapter);
-
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- /* Fill out redirection table */
- for (i = 0, j = 0; i < 128; i++, j++) {
- if (j == adapter->ring_feature[RING_F_RSS].indices)
- j = 0;
- /* reta = 4-byte sliding window of
- * 0x00..(indices-1)(indices-1)00..etc. */
- reta = (reta << 8) | (j * 0x11);
- if ((i & 3) == 3)
- IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
- }
-
- /* Fill out hash function seeds */
- for (i = 0; i < 10; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
-
- if (hw->mac.type == ixgbe_mac_82598EB)
- mrqc |= IXGBE_MRQC_RSSEN;
- /* Perform hash on these packet types */
- mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
- }
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+}
- if (adapter->num_vfs) {
- u32 reg;
+/**
+ * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+ u32 rxctrl;
- /* Map PF MAC address in RAR Entry 0 to first pool
- * following VFs */
- hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs);
+ /* disable receives while setting up the descriptors */
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
- /* Set up VF register offsets for selected VT Mode, i.e.
- * 64 VFs for SR-IOV */
- reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
- reg |= IXGBE_GCR_EXT_SRIOV;
- IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg);
- }
+ ixgbe_setup_psrtype(adapter);
+ ixgbe_setup_rdrxctl(adapter);
- rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
+ /* Program registers for the distribution of queues */
+ ixgbe_setup_mrqc(adapter);
- if (adapter->flags & IXGBE_FLAG_RSS_ENABLED ||
- adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) {
- /* Disable indicating checksum in descriptor, enables
- * RSS hash */
- rxcsum |= IXGBE_RXCSUM_PCSD;
- }
- if (!(rxcsum & IXGBE_RXCSUM_PCSD)) {
- /* Enable IPv4 payload checksum for UDP fragments
- * if PCSD is not set */
- rxcsum |= IXGBE_RXCSUM_IPPCSE;
- }
+ ixgbe_set_uta(adapter);
- IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
+ /* set_rx_buffer_len must be called before ring initialization */
+ ixgbe_set_rx_buffer_len(adapter);
- if (hw->mac.type == ixgbe_mac_82599EB) {
- rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
- rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
- rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
- IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
- }
+ /*
+ * Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]);
- if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
- /* Enable 82599 HW-RSC */
- for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_configure_rscctl(adapter, i);
+ /* disable drop enable for 82598 parts */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ rxctrl |= IXGBE_RXCTRL_DMBYPS;
- /* Disable RSC for ACK packets */
- IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
- (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
- }
+ /* enable all receives */
+ rxctrl |= IXGBE_RXCTRL_RXEN;
+ hw->mac.ops.enable_rx_dma(hw, rxctrl);
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -2955,7 +3127,7 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
}
static void ixgbe_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+ struct vlan_group *grp)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3052,6 +3224,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ /* set all bits that we expect to always be set */
+ fctrl |= IXGBE_FCTRL_BAM;
+ fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
+ fctrl |= IXGBE_FCTRL_PMCF;
+
/* clear the bits we are changing the status of */
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
@@ -3157,6 +3334,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
u32 txdctl;
int i, j;
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) {
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ netif_set_gso_max_size(adapter->netdev, 65536);
+ return;
+ }
+
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ netif_set_gso_max_size(adapter->netdev, 32768);
+
ixgbe_dcb_check_config(&adapter->dcb_cfg);
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG);
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG);
@@ -3188,17 +3374,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
ixgbe_restore_vlan(adapter);
#ifdef CONFIG_IXGBE_DCB
- if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
- if (hw->mac.type == ixgbe_mac_82598EB)
- netif_set_gso_max_size(netdev, 32768);
- else
- netif_set_gso_max_size(netdev, 65536);
- ixgbe_configure_dcb(adapter);
- } else {
- netif_set_gso_max_size(netdev, 65536);
- }
-#else
- netif_set_gso_max_size(netdev, 65536);
+ ixgbe_configure_dcb(adapter);
#endif
#ifdef IXGBE_FCOE
@@ -3209,17 +3385,15 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
for (i = 0; i < adapter->num_tx_queues; i++)
adapter->tx_ring[i]->atr_sample_rate =
- adapter->atr_sample_rate;
+ adapter->atr_sample_rate;
ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc);
} else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc);
}
+ ixgbe_configure_virtualization(adapter);
ixgbe_configure_tx(adapter);
ixgbe_configure_rx(adapter);
- for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i],
- (adapter->rx_ring[i]->count - 1));
}
static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
@@ -3290,7 +3464,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
goto link_cfg_out;
if (hw->mac.ops.get_link_capabilities)
- ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+ ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &negotiation);
if (ret)
goto link_cfg_out;
@@ -3300,62 +3475,15 @@ link_cfg_out:
return ret;
}
-#define IXGBE_MAX_RX_DESC_POLL 10
-static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
- int rxr)
-{
- int j = adapter->rx_ring[rxr]->reg_idx;
- int k;
-
- for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
- if (IXGBE_READ_REG(&adapter->hw,
- IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
- break;
- else
- msleep(1);
- }
- if (k >= IXGBE_MAX_RX_DESC_POLL) {
- e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within "
- "the polling period\n", rxr);
- }
- ixgbe_release_rx_desc(&adapter->hw, adapter->rx_ring[rxr],
- (adapter->rx_ring[rxr]->count - 1));
-}
-
-static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
+static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
{
- struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
- int i, j = 0;
- int num_rx_rings = adapter->num_rx_queues;
- int err;
- int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- u32 txdctl, rxdctl, mhadd;
- u32 dmatxctl;
- u32 gpie;
- u32 ctrl_ext;
-
- ixgbe_get_hw_control(adapter);
-
- if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) ||
- (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
- IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
- } else {
- /* MSI only */
- gpie = 0;
- }
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
- gpie &= ~IXGBE_GPIE_VTMODE_MASK;
- gpie |= IXGBE_GPIE_VTMODE_64;
- }
- /* XXX: to interrupt immediately for EICS writes, enable this */
- /* gpie |= IXGBE_GPIE_EIMEN; */
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
+ u32 gpie = 0;
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ gpie = IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT |
+ IXGBE_GPIE_OCD;
+ gpie |= IXGBE_GPIE_EIAME;
/*
* use EIAM to auto-mask when MSI-X interrupt is asserted
* this saves a register write for every interrupt
@@ -3376,98 +3504,33 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
}
- /* Enable Thermal over heat sensor interrupt */
- if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
- gpie |= IXGBE_SDP0_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ /* XXX: to interrupt immediately for EICS writes, enable this */
+ /* gpie |= IXGBE_GPIE_EIMEN; */
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ gpie &= ~IXGBE_GPIE_VTMODE_MASK;
+ gpie |= IXGBE_GPIE_VTMODE_64;
}
- /* Enable fan failure interrupt if media type is copper */
- if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ /* Enable fan failure interrupt */
+ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
gpie |= IXGBE_SDP1_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
- if (hw->mac.type == ixgbe_mac_82599EB) {
- gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ if (hw->mac.type == ixgbe_mac_82599EB)
gpie |= IXGBE_SDP1_GPIEN;
gpie |= IXGBE_SDP2_GPIEN;
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
- }
-
-#ifdef IXGBE_FCOE
- /* adjust max frame to be able to do baby jumbo for FCoE */
- if ((netdev->features & NETIF_F_FCOE_MTU) &&
- (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
- max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
-#endif /* IXGBE_FCOE */
- mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
- if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
- mhadd &= ~IXGBE_MHADD_MFS_MASK;
- mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT;
-
- IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
- }
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- if (adapter->rx_itr_setting == 0) {
- /* cannot set wthresh when itr==0 */
- txdctl &= ~0x007F0000;
- } else {
- /* enable WTHRESH=8 descriptors, to encourage burst writeback */
- txdctl |= (8 << 16);
- }
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
- }
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+}
- if (hw->mac.type == ixgbe_mac_82599EB) {
- /* DMATXCTL.EN must be set after all Tx queue config is done */
- dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
- dmatxctl |= IXGBE_DMATXCTL_TE;
- IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
- }
- for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i]->reg_idx;
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- txdctl |= IXGBE_TXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
- if (hw->mac.type == ixgbe_mac_82599EB) {
- int wait_loop = 10;
- /* poll for Tx Enable ready */
- do {
- msleep(1);
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
- } while (--wait_loop &&
- !(txdctl & IXGBE_TXDCTL_ENABLE));
- if (!wait_loop)
- e_err(drv, "Could not enable Tx Queue %d\n", j);
- }
- }
+static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int err;
+ u32 ctrl_ext;
- for (i = 0; i < num_rx_rings; i++) {
- j = adapter->rx_ring[i]->reg_idx;
- rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
- /* enable PTHRESH=32 descriptors (half the internal cache)
- * and HTHRESH=0 descriptors (to minimize latency on fetch),
- * this also removes a pesky rx_no_buffer_count increment */
- rxdctl |= 0x0020;
- rxdctl |= IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
- if (hw->mac.type == ixgbe_mac_82599EB)
- ixgbe_rx_desc_queue_enable(adapter, i);
- }
- /* enable all receives */
- rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- if (hw->mac.type == ixgbe_mac_82598EB)
- rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
- else
- rxdctl |= IXGBE_RXCTRL_RXEN;
- hw->mac.ops.enable_rx_dma(hw, rxdctl);
+ ixgbe_get_hw_control(adapter);
+ ixgbe_setup_gpie(adapter);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
ixgbe_configure_msix(adapter);
@@ -3483,7 +3546,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
-
ixgbe_irq_enable(adapter);
/*
@@ -3525,12 +3587,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
e_err(probe, "link_config FAILED %d\n", err);
}
- for (i = 0; i < adapter->num_tx_queues; i++)
- set_bit(__IXGBE_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->reinit_state));
-
/* enable transmits */
- netif_tx_start_all_queues(netdev);
+ netif_tx_start_all_queues(adapter->netdev);
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
@@ -3609,21 +3667,24 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
* @rx_ring: ring to free buffers from
**/
static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
unsigned int i;
- /* Free all the Rx ring sk_buffs */
+ /* ring already cleared, nothing to do */
+ if (!rx_ring->rx_buffer_info)
+ return;
+ /* Free all the Rx ring sk_buffs */
for (i = 0; i < rx_ring->count; i++) {
struct ixgbe_rx_buffer *rx_buffer_info;
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
dma_unmap_single(&pdev->dev, rx_buffer_info->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
rx_buffer_info->dma = 0;
}
@@ -3635,7 +3696,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
if (IXGBE_RSC_CB(this)->delay_unmap) {
dma_unmap_single(&pdev->dev,
IXGBE_RSC_CB(this)->dma,
- rx_ring->rx_buf_len,
+ rx_ring->rx_buf_len,
DMA_FROM_DEVICE);
IXGBE_RSC_CB(this)->dma = 0;
IXGBE_RSC_CB(skb)->delay_unmap = false;
@@ -3677,14 +3738,17 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
* @tx_ring: ring to be cleaned
**/
static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned long size;
unsigned int i;
- /* Free all the Tx ring sk_buffs */
+ /* ring already cleared, nothing to do */
+ if (!tx_ring->tx_buffer_info)
+ return;
+ /* Free all the Tx ring sk_buffs */
for (i = 0; i < tx_ring->count; i++) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info);
@@ -3786,13 +3850,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
j = adapter->tx_ring[i]->reg_idx;
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
- (txdctl & ~IXGBE_TXDCTL_ENABLE));
+ (txdctl & ~IXGBE_TXDCTL_ENABLE));
}
/* Disable the Tx DMA engine on 82599 */
if (hw->mac.type == ixgbe_mac_82599EB)
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
- (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
- ~IXGBE_DMATXCTL_TE));
+ (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
+ ~IXGBE_DMATXCTL_TE));
/* power down the optics */
if (hw->phy.multispeed_fiber)
@@ -3822,7 +3886,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
int tx_clean_complete, work_done = 0;
@@ -3932,7 +3996,7 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
* Rx load across CPUs using RSS.
*
**/
-static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
{
bool ret = false;
struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
@@ -4061,7 +4125,7 @@ done:
}
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int err, vector_threshold;
@@ -4080,7 +4144,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
*/
while (vectors >= vector_threshold) {
err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- vectors);
+ vectors);
if (!err) /* Success in acquiring all requested vectors. */
break;
else if (err < 0)
@@ -4107,7 +4171,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
* vectors we were allocated.
*/
adapter->num_msix_vectors = min(vectors,
- adapter->max_msix_q_vectors + NON_Q_VECTORS);
+ adapter->max_msix_q_vectors + NON_Q_VECTORS);
}
}
@@ -4178,12 +4242,12 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
}
for ( ; i < 5; i++) {
adapter->tx_ring[i]->reg_idx =
- ((i + 2) << 4);
+ ((i + 2) << 4);
adapter->rx_ring[i]->reg_idx = i << 4;
}
for ( ; i < dcb_i; i++) {
adapter->tx_ring[i]->reg_idx =
- ((i + 8) << 3);
+ ((i + 8) << 3);
adapter->rx_ring[i]->reg_idx = i << 4;
}
@@ -4226,7 +4290,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
* Cache the descriptor ring offsets for Flow Director to the assigned rings.
*
**/
-static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
{
int i;
bool ret = false;
@@ -4383,7 +4447,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!ring)
@@ -4407,7 +4471,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL,
- adapter->node);
+ adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!ring)
@@ -4453,7 +4517,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
* (roughly) the same number of vectors as there are CPU's.
*/
v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
- (int)num_online_cpus()) + NON_Q_VECTORS;
+ (int)num_online_cpus()) + NON_Q_VECTORS;
/*
* At the same time, hardware can only support a maximum of
@@ -4467,7 +4531,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
/* A failure in MSI-X entry allocation isn't fatal, but it does
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
- sizeof(struct msix_entry), GFP_KERNEL);
+ sizeof(struct msix_entry), GFP_KERNEL);
if (adapter->msix_entries) {
for (vector = 0; vector < v_budget; vector++)
adapter->msix_entries[vector].entry = vector;
@@ -4529,10 +4593,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
q_vector = kzalloc_node(sizeof(struct ixgbe_q_vector),
- GFP_KERNEL, adapter->node);
+ GFP_KERNEL, adapter->node);
if (!q_vector)
q_vector = kzalloc(sizeof(struct ixgbe_q_vector),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!q_vector)
goto err_out;
q_vector->adapter = adapter;
@@ -4693,8 +4757,8 @@ static void ixgbe_sfp_timer(unsigned long data)
static void ixgbe_sfp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_task);
+ struct ixgbe_adapter,
+ sfp_task);
struct ixgbe_hw *hw = &adapter->hw;
if ((hw->phy.type == ixgbe_phy_nl) &&
@@ -4719,7 +4783,7 @@ static void ixgbe_sfp_task(struct work_struct *work)
reschedule:
if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
+ round_jiffies(jiffies + (2 * HZ)));
}
/**
@@ -4775,7 +4839,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->atr_sample_rate = 20;
}
adapter->ring_feature[RING_F_FDIR].indices =
- IXGBE_MAX_FDIR_INDICES;
+ IXGBE_MAX_FDIR_INDICES;
adapter->fdir_pballoc = 0;
#ifdef IXGBE_FCOE
adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
@@ -4806,7 +4870,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->dcb_cfg.round_robin_enable = false;
adapter->dcb_set_bitmap = 0x00;
ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
- adapter->ring_feature[RING_F_DCB].indices);
+ adapter->ring_feature[RING_F_DCB].indices);
#endif
@@ -4861,7 +4925,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
* Return 0 on success, negative on failure
**/
int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -4928,7 +4992,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
* Returns 0 on success, negative on failure
**/
int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -5001,7 +5065,7 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
* Free all transmit software resources
**/
void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -5039,7 +5103,7 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
* Free all receive software resources
**/
void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -5333,6 +5397,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
u64 non_eop_descs = 0, restart_queue = 0;
+ struct ixgbe_hw_stats *hwstats = &adapter->stats;
if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state))
@@ -5343,7 +5408,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 rsc_flush = 0;
for (i = 0; i < 16; i++)
adapter->hw_rx_no_dma_resources +=
- IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
for (i = 0; i < adapter->num_rx_queues; i++) {
rsc_count += adapter->rx_ring[i]->rsc_count;
rsc_flush += adapter->rx_ring[i]->rsc_flush;
@@ -5361,119 +5426,118 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
non_eop_descs += adapter->rx_ring[i]->non_eop_descs;
adapter->non_eop_descs = non_eop_descs;
- adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
+ hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
for (i = 0; i < 8; i++) {
/* for packet buffers not used, the register should read 0 */
mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i));
missed_rx += mpc;
- adapter->stats.mpc[i] += mpc;
- total_mpc += adapter->stats.mpc[i];
+ hwstats->mpc[i] += mpc;
+ total_mpc += hwstats->mpc[i];
if (hw->mac.type == ixgbe_mac_82598EB)
- adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
- adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
- adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
+ hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
+ hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+ hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
+ hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
if (hw->mac.type == ixgbe_mac_82599EB) {
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXCNT(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXCNT(i));
- adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ hwstats->pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
+ hwstats->pxoffrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
+ hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
} else {
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXC(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXC(i));
+ hwstats->pxonrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+ hwstats->pxoffrxc[i] +=
+ IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
}
- adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONTXC(i));
- adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFTXC(i));
+ hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
+ hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
}
- adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
+ hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
/* work around hardware counting issue */
- adapter->stats.gprc -= missed_rx;
+ hwstats->gprc -= missed_rx;
/* 82598 hardware only has a 32 bit counter in the high register */
if (hw->mac.type == ixgbe_mac_82599EB) {
u64 tmp;
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
- adapter->stats.gorc += (tmp << 32);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
- tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
- adapter->stats.gotc += (tmp << 32);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
- IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
- adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
- adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+ hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
+ tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF;
+ /* 4 high bits of GORC */
+ hwstats->gorc += (tmp << 32);
+ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
+ tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF;
+ /* 4 high bits of GOTC */
+ hwstats->gotc += (tmp << 32);
+ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL);
+ IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+ hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+ hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
#ifdef IXGBE_FCOE
- adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
- adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
- adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
- adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
- adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
- adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
+ hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
+ hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
+ hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
+ hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
+ hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
+ hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
#endif /* IXGBE_FCOE */
} else {
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+ hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+ hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+ hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
}
bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
- adapter->stats.bprc += bprc;
- adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
+ hwstats->bprc += bprc;
+ hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
if (hw->mac.type == ixgbe_mac_82598EB)
- adapter->stats.mprc -= bprc;
- adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
- adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
- adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
- adapter->stats.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
- adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
- adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
- adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
- adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
+ hwstats->mprc -= bprc;
+ hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC);
+ hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
+ hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
+ hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255);
+ hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
+ hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
+ hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
+ hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
- adapter->stats.lxontxc += lxon;
+ hwstats->lxontxc += lxon;
lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
- adapter->stats.lxofftxc += lxoff;
- adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
- adapter->stats.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
- adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
+ hwstats->lxofftxc += lxoff;
+ hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
+ hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
+ hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
/*
* 82598 errata - tx of flow control packets is included in tx counters
*/
xon_off_tot = lxon + lxoff;
- adapter->stats.gptc -= xon_off_tot;
- adapter->stats.mptc -= xon_off_tot;
- adapter->stats.gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
- adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
- adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
- adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
- adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
- adapter->stats.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
- adapter->stats.ptc64 -= xon_off_tot;
- adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
- adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
- adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
- adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
- adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
- adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
+ hwstats->gptc -= xon_off_tot;
+ hwstats->mptc -= xon_off_tot;
+ hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
+ hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
+ hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
+ hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
+ hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
+ hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
+ hwstats->ptc64 -= xon_off_tot;
+ hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
+ hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
+ hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
+ hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
+ hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
+ hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
/* Fill out the OS statistics structure */
- netdev->stats.multicast = adapter->stats.mprc;
+ netdev->stats.multicast = hwstats->mprc;
/* Rx Errors */
- netdev->stats.rx_errors = adapter->stats.crcerrs +
- adapter->stats.rlec;
+ netdev->stats.rx_errors = hwstats->crcerrs + hwstats->rlec;
netdev->stats.rx_dropped = 0;
- netdev->stats.rx_length_errors = adapter->stats.rlec;
- netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
+ netdev->stats.rx_length_errors = hwstats->rlec;
+ netdev->stats.rx_crc_errors = hwstats->crcerrs;
netdev->stats.rx_missed_errors = total_mpc;
}
@@ -5532,8 +5596,8 @@ watchdog_short_circuit:
static void ixgbe_multispeed_fiber_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- multispeed_fiber_task);
+ struct ixgbe_adapter,
+ multispeed_fiber_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg;
bool negotiation;
@@ -5556,8 +5620,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)
static void ixgbe_sfp_config_module_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_config_module_task);
+ struct ixgbe_adapter,
+ sfp_config_module_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 err;
@@ -5590,15 +5654,15 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
static void ixgbe_fdir_reinit_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- fdir_reinit_task);
+ struct ixgbe_adapter,
+ fdir_reinit_task);
struct ixgbe_hw *hw = &adapter->hw;
int i;
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++)
set_bit(__IXGBE_FDIR_INIT_DONE,
- &(adapter->tx_ring[i]->reinit_state));
+ &(adapter->tx_ring[i]->reinit_state));
} else {
e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n");
@@ -5616,8 +5680,8 @@ static DEFINE_MUTEX(ixgbe_watchdog_lock);
static void ixgbe_watchdog_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- watchdog_task);
+ struct ixgbe_adapter,
+ watchdog_task);
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
u32 link_speed;
@@ -5648,7 +5712,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (link_up ||
time_after(jiffies, (adapter->link_check_timeout +
- IXGBE_TRY_LINK_TIMEOUT))) {
+ IXGBE_TRY_LINK_TIMEOUT))) {
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
}
@@ -5719,8 +5783,8 @@ static void ixgbe_watchdog_task(struct work_struct *work)
}
static int ixgbe_tso(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring, struct sk_buff *skb,
- u32 tx_flags, u8 *hdr_len)
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -5743,28 +5807,28 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
iph->tot_len = 0;
iph->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
+ iph->daddr, 0,
+ IPPROTO_TCP,
+ 0);
} else if (skb_is_gso_v6(skb)) {
ipv6_hdr(skb)->payload_len = 0;
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
}
i = tx_ring->next_to_use;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
/* VLAN MACLEN IPLEN */
if (tx_flags & IXGBE_TX_FLAGS_VLAN)
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= ((skb_network_offset(skb)) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
*hdr_len += skb_network_offset(skb);
vlan_macip_lens |=
(skb_transport_header(skb) - skb_network_header(skb));
@@ -5775,7 +5839,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->protocol == htons(ETH_P_IP))
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
@@ -5803,9 +5867,53 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
return false;
}
+static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb)
+{
+ u32 rtn = 0;
+ __be16 protocol;
+
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+ protocol = ((const struct vlan_ethhdr *)skb->data)->
+ h_vlan_encapsulated_proto;
+ else
+ protocol = skb->protocol;
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
+ rtn |= IXGBE_ADVTXD_TUCMD_IPV4;
+ switch (ip_hdr(skb)->protocol) {
+ case IPPROTO_TCP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case IPPROTO_SCTP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
+ break;
+ }
+ break;
+ case cpu_to_be16(ETH_P_IPV6):
+ /* XXX what about other V6 headers?? */
+ switch (ipv6_hdr(skb)->nexthdr) {
+ case IPPROTO_TCP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case IPPROTO_SCTP:
+ rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
+ break;
+ }
+ break;
+ default:
+ if (unlikely(net_ratelimit()))
+ e_warn(probe, "partial checksum but proto=%x!\n",
+ skb->protocol);
+ break;
+ }
+
+ return rtn;
+}
+
static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -5816,63 +5924,25 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
(tx_flags & IXGBE_TX_FLAGS_VLAN)) {
i = tx_ring->next_to_use;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+ context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
if (tx_flags & IXGBE_TX_FLAGS_VLAN)
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= (skb_network_offset(skb) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
if (skb->ip_summed == CHECKSUM_PARTIAL)
vlan_macip_lens |= (skb_transport_header(skb) -
- skb_network_header(skb));
+ skb_network_header(skb));
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = 0;
type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
-
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- __be16 protocol;
-
- if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
- const struct vlan_ethhdr *vhdr =
- (const struct vlan_ethhdr *)skb->data;
-
- protocol = vhdr->h_vlan_encapsulated_proto;
- } else {
- protocol = skb->protocol;
- }
+ IXGBE_ADVTXD_DTYP_CTXT);
- switch (protocol) {
- case cpu_to_be16(ETH_P_IP):
- type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
- if (ip_hdr(skb)->protocol == IPPROTO_TCP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
- else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_SCTP;
- break;
- case cpu_to_be16(ETH_P_IPV6):
- /* XXX what about other V6 headers?? */
- if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
- else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
- type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_SCTP;
- break;
- default:
- if (unlikely(net_ratelimit())) {
- e_warn(probe, "partial checksum "
- "but proto=%x!\n",
- skb->protocol);
- }
- break;
- }
- }
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ type_tucmd_mlhl |= ixgbe_psum(adapter, skb);
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
/* use index zero for tx checksum offload */
@@ -5893,9 +5963,9 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
}
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags,
- unsigned int first)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags,
+ unsigned int first)
{
struct pci_dev *pdev = adapter->pdev;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -5990,7 +6060,7 @@ dma_error:
/* clear timestamp and dma mappings for remaining portion of packet */
while (count--) {
- if (i==0)
+ if (i == 0)
i += tx_ring->count;
i--;
tx_buffer_info = &tx_ring->tx_buffer_info[i];
@@ -6001,8 +6071,8 @@ dma_error:
}
static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- int tx_flags, int count, u32 paylen, u8 hdr_len)
+ struct ixgbe_ring *tx_ring,
+ int tx_flags, int count, u32 paylen, u8 hdr_len)
{
union ixgbe_adv_tx_desc *tx_desc = NULL;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -6021,17 +6091,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
/* use index 1 context for tso */
olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
if (tx_flags & IXGBE_TX_FLAGS_IPV4)
olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
} else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
olinfo_status |= IXGBE_ADVTXD_CC;
@@ -6045,10 +6115,10 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
i = tx_ring->next_to_use;
while (count--) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
+ tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
tx_desc->read.cmd_type_len =
- cpu_to_le32(cmd_type_len | tx_buffer_info->length);
+ cpu_to_le32(cmd_type_len | tx_buffer_info->length);
tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
i++;
if (i == tx_ring->count)
@@ -6070,7 +6140,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
}
static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
- int queue, u32 tx_flags)
+ int queue, u32 tx_flags)
{
struct ixgbe_atr_input atr_input;
struct tcphdr *th;
@@ -6098,7 +6168,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >>
- IXGBE_TX_FLAGS_VLAN_SHIFT;
+ IXGBE_TX_FLAGS_VLAN_SHIFT;
src_ipv4_addr = iph->saddr;
dst_ipv4_addr = iph->daddr;
flex_bytes = eth->h_proto;
@@ -6117,7 +6187,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
}
static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
netif_stop_subqueue(netdev, tx_ring->queue_index);
/* Herbert's original patch had:
@@ -6137,7 +6207,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
}
static int ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
return 0;
@@ -6183,11 +6253,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
return skb_tx_hash(dev, skb);
}
-static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
- struct net_device *netdev)
+netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev,
+ struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_ring *tx_ring;
struct netdev_queue *txq;
unsigned int first;
unsigned int tx_flags = 0;
@@ -6211,8 +6280,6 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
- tx_ring = adapter->tx_ring[skb->queue_mapping];
-
#ifdef IXGBE_FCOE
/* for FCoE with DCB, we force the priority to what
* was specified by the switch */
@@ -6283,10 +6350,10 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
if (tx_ring->atr_sample_rate) {
++tx_ring->atr_count;
if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
- test_bit(__IXGBE_FDIR_INIT_DONE,
- &tx_ring->reinit_state)) {
+ test_bit(__IXGBE_FDIR_INIT_DONE,
+ &tx_ring->reinit_state)) {
ixgbe_atr(adapter, skb, tx_ring->queue_index,
- tx_flags);
+ tx_flags);
tx_ring->atr_count = 0;
}
}
@@ -6294,7 +6361,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
txq->tx_bytes += skb->len;
txq->tx_packets++;
ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
- hdr_len);
+ hdr_len);
ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
} else {
@@ -6306,6 +6373,15 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_ring *tx_ring;
+
+ tx_ring = adapter->tx_ring[skb->queue_mapping];
+ return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring);
+}
+
/**
* ixgbe_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
@@ -6437,7 +6513,7 @@ static void ixgbe_netpoll(struct net_device *netdev)
#endif
static const struct net_device_ops ixgbe_netdev_ops = {
- .ndo_open = ixgbe_open,
+ .ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
.ndo_select_queue = ixgbe_select_queue,
@@ -6532,7 +6608,7 @@ err_novfs:
* and a hardware reset occur.
**/
static int __devinit ixgbe_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
struct net_device *netdev;
struct ixgbe_adapter *adapter = NULL;
@@ -6577,7 +6653,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
}
err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM), ixgbe_driver_name);
+ IORESOURCE_MEM), ixgbe_driver_name);
if (err) {
dev_err(&pdev->dev,
"pci_request_selected_regions failed 0x%x\n", err);
@@ -6617,7 +6693,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
+ pci_resource_len(pdev, 0));
if (!hw->hw_addr) {
err = -EIO;
goto err_ioremap;
@@ -6661,7 +6737,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
* which might start the timer
*/
init_timer(&adapter->sfp_timer);
- adapter->sfp_timer.function = &ixgbe_sfp_timer;
+ adapter->sfp_timer.function = ixgbe_sfp_timer;
adapter->sfp_timer.data = (unsigned long) adapter;
INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
@@ -6671,7 +6747,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* a new SFP+ module arrival, called from GPI SDP2 context */
INIT_WORK(&adapter->sfp_config_module_task,
- ixgbe_sfp_config_module_task);
+ ixgbe_sfp_config_module_task);
ii->get_invariants(hw);
@@ -6723,10 +6799,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
ixgbe_probe_vf(adapter, ii);
netdev->features = NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ NETIF_F_IP_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
@@ -6793,7 +6869,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->mac.ops.disable_tx_laser(hw);
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgbe_watchdog;
+ adapter->watchdog_timer.function = ixgbe_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
@@ -6806,7 +6882,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
switch (pdev->device) {
case IXGBE_DEV_ID_82599_KX4:
adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
- IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+ IXGBE_WUFC_MC | IXGBE_WUFC_BC);
break;
default:
adapter->wol = 0;
@@ -6819,13 +6895,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* print bus type/speed/width info */
e_dev_info("(PCI Express:%s:%s) %pM\n",
- ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
- (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
- ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
- (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
- (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
- "Unknown"),
- netdev->dev_addr);
+ (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
+ hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
+ "Unknown"),
+ (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
+ hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
+ hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" :
+ "Unknown"),
+ netdev->dev_addr);
ixgbe_read_pba_num_generic(hw, &part_num);
if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
e_dev_info("MAC: %d, PHY: %d, SFP+: %d, "
@@ -6872,7 +6949,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
- INIT_WORK(&adapter->check_overtemp_task, ixgbe_check_overtemp_task);
+ INIT_WORK(&adapter->check_overtemp_task,
+ ixgbe_check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -6908,8 +6986,8 @@ err_eeprom:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM));
+ pci_release_selected_regions(pdev,
+ pci_select_bars(pdev, IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -6976,7 +7054,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
iounmap(adapter->hw.hw_addr);
pci_release_selected_regions(pdev, pci_select_bars(pdev,
- IORESOURCE_MEM));
+ IORESOURCE_MEM));
e_dev_info("complete\n");
@@ -6996,7 +7074,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
* this device has been detected.
*/
static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+ pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -7102,8 +7180,7 @@ static struct pci_driver ixgbe_driver = {
static int __init ixgbe_init_module(void)
{
int ret;
- pr_info("%s - version %s\n", ixgbe_driver_string,
- ixgbe_driver_version);
+ pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
pr_info("%s\n", ixgbe_copyright);
#ifdef CONFIG_IXGBE_DCA
@@ -7132,12 +7209,12 @@ static void __exit ixgbe_exit_module(void)
#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
- void *p)
+ void *p)
{
int ret_val;
ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
- __ixgbe_notify_dca);
+ __ixgbe_notify_dca);
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 9587d975d66c..d3cc6ce7c973 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -871,6 +871,8 @@
#define IXGBE_RDRXCTL_MVMEN 0x00000020
#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
+#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */
+#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */
/* RQTC Bit Masks and Shifts */
#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h
index f7015efbff05..da4033c6efa2 100644
--- a/drivers/net/ixgbevf/ixgbevf.h
+++ b/drivers/net/ixgbevf/ixgbevf.h
@@ -243,7 +243,6 @@ struct ixgbevf_adapter {
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
/* structs defined in ixgbe_vf.h */
struct ixgbe_hw hw;
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 918c00359b0a..3eda1bdbbb7a 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -308,8 +308,8 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
- adapter->net_stats.tx_bytes += total_bytes;
- adapter->net_stats.tx_packets += total_packets;
+ netdev->stats.tx_bytes += total_bytes;
+ netdev->stats.tx_packets += total_packets;
return (count < tx_ring->work_limit);
}
@@ -356,7 +356,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector,
static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Rx csum disabled */
if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
@@ -639,8 +639,8 @@ next_desc:
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
+ adapter->netdev->stats.rx_bytes += total_rx_bytes;
+ adapter->netdev->stats.rx_packets += total_rx_packets;
return cleaned;
}
@@ -2297,7 +2297,7 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter)
adapter->stats.vfmprc);
/* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.vfmprc -
+ adapter->netdev->stats.multicast = adapter->stats.vfmprc -
adapter->stats.base_vfmprc;
}
@@ -3181,21 +3181,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
/**
- * ixgbevf_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- **/
-static struct net_device_stats *ixgbevf_get_stats(struct net_device *netdev)
-{
- struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-
- /* only return the current stats */
- return &adapter->net_stats;
-}
-
-/**
* ixgbevf_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -3272,7 +3257,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = &ixgbevf_open,
.ndo_stop = &ixgbevf_close,
.ndo_start_xmit = &ixgbevf_xmit_frame,
- .ndo_get_stats = &ixgbevf_get_stats,
.ndo_set_rx_mode = &ixgbevf_set_rx_mode,
.ndo_set_multicast_list = &ixgbevf_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
@@ -3426,7 +3410,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
}
init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &ixgbevf_watchdog;
+ adapter->watchdog_timer.function = ixgbevf_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbevf_reset_task);
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 94b750b8874f..61f9dc831424 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -124,8 +124,6 @@ struct ixgbe_hw {
void *back;
u8 __iomem *hw_addr;
- u8 *flash_address;
- unsigned long io_base;
struct ixgbe_mac_info mac;
struct ixgbe_mbx_info mbx;
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 99f24f5cac53..c04c096bc6a9 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -21,6 +21,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -73,7 +75,7 @@ read_again:
}
if (i == 0) {
- jeprintk(jme->pdev, "phy(%d) read timeout : %d\n", phy, reg);
+ pr_err("phy(%d) read timeout : %d\n", phy, reg);
return 0;
}
@@ -102,7 +104,7 @@ jme_mdio_write(struct net_device *netdev,
}
if (i == 0)
- jeprintk(jme->pdev, "phy(%d) write timeout : %d\n", phy, reg);
+ pr_err("phy(%d) write timeout : %d\n", phy, reg);
}
static inline void
@@ -227,7 +229,7 @@ jme_reload_eeprom(struct jme_adapter *jme)
}
if (i == 0) {
- jeprintk(jme->pdev, "eeprom reload timeout\n");
+ pr_err("eeprom reload timeout\n");
return -EIO;
}
}
@@ -397,8 +399,7 @@ jme_check_link(struct net_device *netdev, int testonly)
phylink = jread32(jme, JME_PHY_LINK);
}
if (!cnt)
- jeprintk(jme->pdev,
- "Waiting speed resolve timeout.\n");
+ pr_err("Waiting speed resolve timeout\n");
strcat(linkmsg, "ANed: ");
}
@@ -480,13 +481,13 @@ jme_check_link(struct net_device *netdev, int testonly)
strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ?
"MDI-X" :
"MDI");
- netif_info(jme, link, jme->dev, "Link is up at %s.\n", linkmsg);
+ netif_info(jme, link, jme->dev, "Link is up at %s\n", linkmsg);
netif_carrier_on(netdev);
} else {
if (testonly)
goto out;
- netif_info(jme, link, jme->dev, "Link is down.\n");
+ netif_info(jme, link, jme->dev, "Link is down\n");
jme->phylink = 0;
netif_carrier_off(netdev);
}
@@ -648,7 +649,7 @@ jme_disable_tx_engine(struct jme_adapter *jme)
}
if (!i)
- jeprintk(jme->pdev, "Disable TX engine timeout.\n");
+ pr_err("Disable TX engine timeout\n");
}
static void
@@ -867,7 +868,7 @@ jme_disable_rx_engine(struct jme_adapter *jme)
}
if (!i)
- jeprintk(jme->pdev, "Disable RX engine timeout.\n");
+ pr_err("Disable RX engine timeout\n");
}
@@ -887,13 +888,13 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
== RXWBFLAG_UDPON)) {
if (flags & RXWBFLAG_IPV4)
- netif_err(jme, rx_err, jme->dev, "UDP Checksum error.\n");
+ netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n");
return false;
}
if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS))
== RXWBFLAG_IPV4)) {
- netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error.\n");
+ netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error\n");
return false;
}
@@ -936,7 +937,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) {
if (jme->vlgrp) {
@@ -1185,9 +1186,9 @@ jme_link_change_tasklet(unsigned long arg)
while (!atomic_dec_and_test(&jme->link_changing)) {
atomic_inc(&jme->link_changing);
- netif_info(jme, intr, jme->dev, "Get link change lock failed.\n");
+ netif_info(jme, intr, jme->dev, "Get link change lock failed\n");
while (atomic_read(&jme->link_changing) != 1)
- netif_info(jme, intr, jme->dev, "Waiting link change lock.\n");
+ netif_info(jme, intr, jme->dev, "Waiting link change lock\n");
}
if (jme_check_link(netdev, 1) && jme->old_mtu == netdev->mtu)
@@ -1221,15 +1222,13 @@ jme_link_change_tasklet(unsigned long arg)
if (netif_carrier_ok(netdev)) {
rc = jme_setup_rx_resources(jme);
if (rc) {
- jeprintk(jme->pdev, "Allocating resources for RX error"
- ", Device STOPPED!\n");
+ pr_err("Allocating resources for RX error, Device STOPPED!\n");
goto out_enable_tasklet;
}
rc = jme_setup_tx_resources(jme);
if (rc) {
- jeprintk(jme->pdev, "Allocating resources for TX error"
- ", Device STOPPED!\n");
+ pr_err("Allocating resources for TX error, Device STOPPED!\n");
goto err_out_free_rx_resources;
}
@@ -1324,7 +1323,7 @@ jme_wake_queue_if_stopped(struct jme_adapter *jme)
smp_wmb();
if (unlikely(netif_queue_stopped(jme->dev) &&
atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold))) {
- netif_info(jme, tx_done, jme->dev, "TX Queue Waked.\n");
+ netif_info(jme, tx_done, jme->dev, "TX Queue Waked\n");
netif_wake_queue(jme->dev);
}
@@ -1339,7 +1338,7 @@ jme_tx_clean_tasklet(unsigned long arg)
struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi;
int i, j, cnt = 0, max, err, mask;
- tx_dbg(jme, "Into txclean.\n");
+ tx_dbg(jme, "Into txclean\n");
if (unlikely(!atomic_dec_and_test(&jme->tx_cleaning)))
goto out;
@@ -1361,7 +1360,7 @@ jme_tx_clean_tasklet(unsigned long arg)
!(txdesc[i].descwb.flags & TXWBFLAG_OWN))) {
tx_dbg(jme, "txclean: %d+%d@%lu\n",
- i, ctxbi->nr_desc, jiffies);
+ i, ctxbi->nr_desc, jiffies);
err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR;
@@ -1402,7 +1401,7 @@ jme_tx_clean_tasklet(unsigned long arg)
ctxbi->nr_desc = 0;
}
- tx_dbg(jme, "txclean: done %d@%lu.\n", i, jiffies);
+ tx_dbg(jme, "txclean: done %d@%lu\n", i, jiffies);
atomic_set(&txring->next_to_clean, i);
atomic_add(cnt, &txring->nr_free);
@@ -1548,10 +1547,10 @@ jme_request_irq(struct jme_adapter *jme)
rc = request_irq(jme->pdev->irq, handler, irq_flags, netdev->name,
netdev);
if (rc) {
- jeprintk(jme->pdev,
- "Unable to request %s interrupt (return: %d)\n",
- test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx",
- rc);
+ netdev_err(netdev,
+ "Unable to request %s interrupt (return: %d)\n",
+ test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx",
+ rc);
if (test_bit(JME_FLAG_MSI, &jme->flags)) {
pci_disable_msi(jme->pdev);
@@ -1834,7 +1833,7 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags)
*flags |= TXFLAG_UDPCS;
break;
default:
- netif_err(jme, tx_err, jme->dev, "Error upper layer protocol.\n");
+ netif_err(jme, tx_err, jme->dev, "Error upper layer protocol\n");
break;
}
}
@@ -1909,12 +1908,12 @@ jme_stop_queue_if_full(struct jme_adapter *jme)
smp_wmb();
if (unlikely(atomic_read(&txring->nr_free) < (MAX_SKB_FRAGS+2))) {
netif_stop_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Paused.\n");
+ netif_info(jme, tx_queued, jme->dev, "TX Queue Paused\n");
smp_wmb();
if (atomic_read(&txring->nr_free)
>= (jme->tx_wake_threshold)) {
netif_wake_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked.\n");
+ netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked\n");
}
}
@@ -1922,7 +1921,8 @@ jme_stop_queue_if_full(struct jme_adapter *jme)
(jiffies - txbi->start_xmit) >= TX_TIMEOUT &&
txbi->skb)) {
netif_stop_queue(jme->dev);
- netif_info(jme, tx_queued, jme->dev, "TX Queue Stopped %d@%lu.\n", idx, jiffies);
+ netif_info(jme, tx_queued, jme->dev,
+ "TX Queue Stopped %d@%lu\n", idx, jiffies);
}
}
@@ -1945,7 +1945,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (unlikely(idx < 0)) {
netif_stop_queue(netdev);
- netif_err(jme, tx_err, jme->dev, "BUG! Tx ring full when queue awake!\n");
+ netif_err(jme, tx_err, jme->dev,
+ "BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -1957,9 +1958,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
TXCS_QUEUE0S |
TXCS_ENABLE);
- tx_dbg(jme, "xmit: %d+%d@%lu\n", idx,
- skb_shinfo(skb)->nr_frags + 2,
- jiffies);
+ tx_dbg(jme, "xmit: %d+%d@%lu\n",
+ idx, skb_shinfo(skb)->nr_frags + 2, jiffies);
jme_stop_queue_if_full(jme);
return NETDEV_TX_OK;
@@ -2501,7 +2501,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr)
val = jread32(jme, JME_SMBCSR);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return 0xFF;
}
@@ -2517,7 +2517,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr)
val = jread32(jme, JME_SMBINTF);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return 0xFF;
}
@@ -2537,7 +2537,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data)
val = jread32(jme, JME_SMBCSR);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return;
}
@@ -2554,7 +2554,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data)
val = jread32(jme, JME_SMBINTF);
}
if (!to) {
- netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n");
+ netif_err(jme, hw, jme->dev, "SMB Bus Busy\n");
return;
}
@@ -2699,26 +2699,26 @@ jme_init_one(struct pci_dev *pdev,
*/
rc = pci_enable_device(pdev);
if (rc) {
- jeprintk(pdev, "Cannot enable PCI device.\n");
+ pr_err("Cannot enable PCI device\n");
goto err_out;
}
using_dac = jme_pci_dma64(pdev);
if (using_dac < 0) {
- jeprintk(pdev, "Cannot set PCI DMA Mask.\n");
+ pr_err("Cannot set PCI DMA Mask\n");
rc = -EIO;
goto err_out_disable_pdev;
}
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- jeprintk(pdev, "No PCI resource region found.\n");
+ pr_err("No PCI resource region found\n");
rc = -ENOMEM;
goto err_out_disable_pdev;
}
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- jeprintk(pdev, "Cannot obtain PCI resource region.\n");
+ pr_err("Cannot obtain PCI resource region\n");
goto err_out_disable_pdev;
}
@@ -2729,7 +2729,7 @@ jme_init_one(struct pci_dev *pdev,
*/
netdev = alloc_etherdev(sizeof(*jme));
if (!netdev) {
- jeprintk(pdev, "Cannot allocate netdev structure.\n");
+ pr_err("Cannot allocate netdev structure\n");
rc = -ENOMEM;
goto err_out_release_regions;
}
@@ -2767,7 +2767,7 @@ jme_init_one(struct pci_dev *pdev,
jme->regs = ioremap(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (!(jme->regs)) {
- jeprintk(pdev, "Mapping PCI resource region error.\n");
+ pr_err("Mapping PCI resource region error\n");
rc = -ENOMEM;
goto err_out_free_netdev;
}
@@ -2855,8 +2855,8 @@ jme_init_one(struct pci_dev *pdev,
if (!jme->mii_if.phy_id) {
rc = -EIO;
- jeprintk(pdev, "Can not find phy_id.\n");
- goto err_out_unmap;
+ pr_err("Can not find phy_id\n");
+ goto err_out_unmap;
}
jme->reg_ghc |= GHC_LINK_POLL;
@@ -2883,8 +2883,7 @@ jme_init_one(struct pci_dev *pdev,
jme_reset_mac_processor(jme);
rc = jme_reload_eeprom(jme);
if (rc) {
- jeprintk(pdev,
- "Reload eeprom for reading MAC Address error.\n");
+ pr_err("Reload eeprom for reading MAC Address error\n");
goto err_out_unmap;
}
jme_load_macaddr(netdev);
@@ -2900,7 +2899,7 @@ jme_init_one(struct pci_dev *pdev,
*/
rc = register_netdev(netdev);
if (rc) {
- jeprintk(pdev, "Cannot register net device.\n");
+ pr_err("Cannot register net device\n");
goto err_out_unmap;
}
@@ -3042,8 +3041,7 @@ static struct pci_driver jme_driver = {
static int __init
jme_init_module(void)
{
- printk(KERN_INFO PFX "JMicron JMC2XX ethernet "
- "driver version %s\n", DRV_VERSION);
+ pr_info("JMicron JMC2XX ethernet driver version %s\n", DRV_VERSION);
return pci_register_driver(&jme_driver);
}
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 07ad3a457185..1360f68861b8 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -41,9 +41,6 @@
NETIF_MSG_TX_ERR | \
NETIF_MSG_HW)
-#define jeprintk(pdev, fmt, args...) \
- printk(KERN_ERR PFX fmt, ## args)
-
#ifdef TX_DEBUG
#define tx_dbg(priv, fmt, args...) \
printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args)
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index b4fb07a6f13f..51919fcd50c2 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -503,30 +503,33 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
ks8851_wrreg16(ks, KS_RXQCR,
ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE);
- if (rxlen > 0) {
- skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8);
- if (!skb) {
- /* todo - dump frame and move on */
- }
+ if (rxlen > 4) {
+ unsigned int rxalign;
+
+ rxlen -= 4;
+ rxalign = ALIGN(rxlen, 4);
+ skb = netdev_alloc_skb_ip_align(ks->netdev, rxalign);
+ if (skb) {
- /* two bytes to ensure ip is aligned, and four bytes
- * for the status header and 4 bytes of garbage */
- skb_reserve(skb, 2 + 4 + 4);
+ /* 4 bytes of status header + 4 bytes of
+ * garbage: we put them before ethernet
+ * header, so that they are copied,
+ * but ignored.
+ */
- rxpkt = skb_put(skb, rxlen - 4) - 8;
+ rxpkt = skb_put(skb, rxlen) - 8;
- /* align the packet length to 4 bytes, and add 4 bytes
- * as we're getting the rx status header as well */
- ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8);
+ ks8851_rdfifo(ks, rxpkt, rxalign + 8);
- if (netif_msg_pktdata(ks))
- ks8851_dbg_dumpkkt(ks, rxpkt);
+ if (netif_msg_pktdata(ks))
+ ks8851_dbg_dumpkkt(ks, rxpkt);
- skb->protocol = eth_type_trans(skb, ks->netdev);
- netif_rx(skb);
+ skb->protocol = eth_type_trans(skb, ks->netdev);
+ netif_rx(skb);
- ks->netdev->stats.rx_packets++;
- ks->netdev->stats.rx_bytes += rxlen - 4;
+ ks->netdev->stats.rx_packets++;
+ ks->netdev->stats.rx_bytes += rxlen;
+ }
}
ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index bdf2149e5296..87d5af361475 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -38,6 +38,7 @@
#include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
+#include <linux/of_address.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/tcp.h> /* needed for sizeof(tcphdr) */
@@ -760,7 +761,7 @@ static void ll_temac_recv(struct net_device *ndev)
skb_put(skb, length);
skb->dev = ndev;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* if we're doing rx csum offload, set it up */
if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
index 5ae28c975b38..8cf9d4f56bb2 100644
--- a/drivers/net/ll_temac_mdio.c
+++ b/drivers/net/ll_temac_mdio.c
@@ -10,6 +10,7 @@
#include <linux/phy.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/of_mdio.h>
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 3832fa4961dd..f84f5e6ededb 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -562,19 +562,19 @@ static int __init mac8390_initdev(struct net_device *dev,
case ACCESS_16:
/* 16 bit card, register map is reversed */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
break;
case ACCESS_32:
/* 32 bit card, register map is reversed */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &sane_block_input;
- ei_status.block_output = &sane_block_output;
- ei_status.get_8390_hdr = &sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = sane_block_input;
+ ei_status.block_output = sane_block_output;
+ ei_status.get_8390_hdr = sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
access_bitmode = 1;
break;
@@ -586,19 +586,19 @@ static int __init mac8390_initdev(struct net_device *dev,
* but overwrite system memory when run at 32 bit.
* so we run them all at 16 bit.
*/
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = back4_offsets;
break;
case MAC8390_CABLETRON:
/* 16 bit card, register map is short forward */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = fwrd2_offsets;
break;
@@ -606,19 +606,19 @@ static int __init mac8390_initdev(struct net_device *dev,
case MAC8390_KINETICS:
/* 16 bit memory, register map is forward */
/* dayna and similar */
- ei_status.reset_8390 = &mac8390_no_reset;
- ei_status.block_input = &dayna_block_input;
- ei_status.block_output = &dayna_block_output;
- ei_status.get_8390_hdr = &dayna_get_8390_hdr;
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = dayna_block_input;
+ ei_status.block_output = dayna_block_output;
+ ei_status.get_8390_hdr = dayna_get_8390_hdr;
ei_status.reg_offset = fwrd4_offsets;
break;
case MAC8390_INTERLAN:
/* 16 bit memory, register map is forward */
- ei_status.reset_8390 = &interlan_reset;
- ei_status.block_input = &slow_sane_block_input;
- ei_status.block_output = &slow_sane_block_output;
- ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reset_8390 = interlan_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
ei_status.reg_offset = fwrd4_offsets;
break;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index ff2f158ab0b9..4297f6e8c4bc 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
}
skb_reserve(skb, RX_OFFSET);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb_put(skb, len);
for (frag = first_frag; ; frag = NEXT_RX(frag)) {
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 3b1c54a9c6ef..42567279843e 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -84,26 +84,45 @@ static const struct proto_ops macvtap_socket_ops;
static DEFINE_SPINLOCK(macvtap_lock);
/*
- * Choose the next free queue, for now there is only one
+ * get_slot: return a [unused/occupied] slot in vlan->taps[]:
+ * - if 'q' is NULL, return the first empty slot;
+ * - otherwise, return the slot this pointer occupies.
*/
+static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q)
+{
+ int i;
+
+ for (i = 0; i < MAX_MACVTAP_QUEUES; i++) {
+ if (rcu_dereference(vlan->taps[i]) == q)
+ return i;
+ }
+
+ /* Should never happen */
+ BUG_ON(1);
+}
+
static int macvtap_set_queue(struct net_device *dev, struct file *file,
struct macvtap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ int index;
int err = -EBUSY;
spin_lock(&macvtap_lock);
- if (rcu_dereference(vlan->tap))
+ if (vlan->numvtaps == MAX_MACVTAP_QUEUES)
goto out;
err = 0;
+ index = get_slot(vlan, NULL);
rcu_assign_pointer(q->vlan, vlan);
- rcu_assign_pointer(vlan->tap, q);
+ rcu_assign_pointer(vlan->taps[index], q);
sock_hold(&q->sk);
q->file = file;
file->private_data = q;
+ vlan->numvtaps++;
+
out:
spin_unlock(&macvtap_lock);
return err;
@@ -124,9 +143,12 @@ static void macvtap_put_queue(struct macvtap_queue *q)
spin_lock(&macvtap_lock);
vlan = rcu_dereference(q->vlan);
if (vlan) {
- rcu_assign_pointer(vlan->tap, NULL);
+ int index = get_slot(vlan, q);
+
+ rcu_assign_pointer(vlan->taps[index], NULL);
rcu_assign_pointer(q->vlan, NULL);
sock_put(&q->sk);
+ --vlan->numvtaps;
}
spin_unlock(&macvtap_lock);
@@ -136,39 +158,82 @@ static void macvtap_put_queue(struct macvtap_queue *q)
}
/*
- * Since we only support one queue, just dereference the pointer.
+ * Select a queue based on the rxq of the device on which this packet
+ * arrived. If the incoming device is not mq, calculate a flow hash
+ * to select a queue. If all fails, find the first available queue.
+ * Cache vlan->numvtaps since it can become zero during the execution
+ * of this function.
*/
static struct macvtap_queue *macvtap_get_queue(struct net_device *dev,
struct sk_buff *skb)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ struct macvtap_queue *tap = NULL;
+ int numvtaps = vlan->numvtaps;
+ __u32 rxq;
+
+ if (!numvtaps)
+ goto out;
+
+ if (likely(skb_rx_queue_recorded(skb))) {
+ rxq = skb_get_rx_queue(skb);
+
+ while (unlikely(rxq >= numvtaps))
+ rxq -= numvtaps;
+
+ tap = rcu_dereference(vlan->taps[rxq]);
+ if (tap)
+ goto out;
+ }
+
+ /* Check if we can use flow to select a queue */
+ rxq = skb_get_rxhash(skb);
+ if (rxq) {
+ tap = rcu_dereference(vlan->taps[rxq % numvtaps]);
+ if (tap)
+ goto out;
+ }
- return rcu_dereference(vlan->tap);
+ /* Everything failed - find first available queue */
+ for (rxq = 0; rxq < MAX_MACVTAP_QUEUES; rxq++) {
+ tap = rcu_dereference(vlan->taps[rxq]);
+ if (tap)
+ break;
+ }
+
+out:
+ return tap;
}
/*
* The net_device is going away, give up the reference
- * that it holds on the queue (all the queues one day)
- * and safely set the pointer from the queues to NULL.
+ * that it holds on all queues and safely set the pointer
+ * from the queues to NULL.
*/
static void macvtap_del_queues(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvtap_queue *q;
+ struct macvtap_queue *q, *qlist[MAX_MACVTAP_QUEUES];
+ int i, j = 0;
+ /* macvtap_put_queue can free some slots, so go through all slots */
spin_lock(&macvtap_lock);
- q = rcu_dereference(vlan->tap);
- if (!q) {
- spin_unlock(&macvtap_lock);
- return;
+ for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) {
+ q = rcu_dereference(vlan->taps[i]);
+ if (q) {
+ qlist[j++] = q;
+ rcu_assign_pointer(vlan->taps[i], NULL);
+ rcu_assign_pointer(q->vlan, NULL);
+ vlan->numvtaps--;
+ }
}
-
- rcu_assign_pointer(vlan->tap, NULL);
- rcu_assign_pointer(q->vlan, NULL);
+ BUG_ON(vlan->numvtaps != 0);
spin_unlock(&macvtap_lock);
synchronize_rcu();
- sock_put(&q->sk);
+
+ for (--j; j >= 0; j--)
+ sock_put(&qlist[j]->sk);
}
/*
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index 1fd068e1d930..d1aa45a15854 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -6,4 +6,4 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
obj-$(CONFIG_MLX4_EN) += mlx4_en.o
mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
- en_resources.o en_netdev.o
+ en_resources.o en_netdev.o en_selftest.o
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index 8c8515619b8e..8f4bf1f07c11 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -74,7 +74,7 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
{
- u32 obj, i;
+ u32 obj;
if (likely(cnt == 1 && align == 1))
return mlx4_bitmap_alloc(bitmap);
@@ -91,8 +91,7 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
}
if (obj < bitmap->max) {
- for (i = 0; i < cnt; i++)
- set_bit(obj + i, bitmap->table);
+ bitmap_set(bitmap->table, obj, cnt);
if (obj == bitmap->last) {
bitmap->last = (obj + cnt);
if (bitmap->last >= bitmap->max)
@@ -109,13 +108,10 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
{
- u32 i;
-
obj &= bitmap->max + bitmap->reserved_top - 1;
spin_lock(&bitmap->lock);
- for (i = 0; i < cnt; i++)
- clear_bit(obj + i, bitmap->table);
+ bitmap_clear(bitmap->table, obj, cnt);
bitmap->last = min(bitmap->last, obj);
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
& bitmap->mask;
@@ -125,8 +121,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
u32 reserved_bot, u32 reserved_top)
{
- int i;
-
/* num must be a power of 2 */
if (num != roundup_pow_of_two(num))
return -EINVAL;
@@ -142,8 +136,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
if (!bitmap->table)
return -ENOMEM;
- for (i = 0; i < reserved_bot; ++i)
- set_bit(i, bitmap->table);
+ bitmap_set(bitmap->table, 0, reserved_bot);
return 0;
}
@@ -188,7 +181,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
buf->npages = buf->nbufs;
buf->page_shift = PAGE_SHIFT;
- buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list,
+ buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
GFP_KERNEL);
if (!buf->page_list)
return -ENOMEM;
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index b275238fe70d..056152b3ff58 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -39,21 +39,6 @@
#include "en_port.h"
-static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
-{
- int i;
-
- priv->port_stats.lro_aggregated = 0;
- priv->port_stats.lro_flushed = 0;
- priv->port_stats.lro_no_desc = 0;
-
- for (i = 0; i < priv->rx_ring_num; i++) {
- priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
- priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
- priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
- }
-}
-
static void
mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
{
@@ -112,7 +97,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
"tx_heartbeat_errors", "tx_window_errors",
/* port statistics */
- "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets",
+ "tso_packets",
"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
"rx_csum_good", "rx_csum_none", "tx_chksum_offload",
@@ -125,6 +110,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
#define NUM_MAIN_STATS 21
#define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
+static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= {
+ "Interupt Test",
+ "Link Test",
+ "Speed Test",
+ "Register Test",
+ "Loopback Test",
+};
+
static u32 mlx4_en_get_msglevel(struct net_device *dev)
{
return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
@@ -146,10 +139,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- if (sset != ETH_SS_STATS)
+ switch (sset) {
+ case ETH_SS_STATS:
+ return NUM_ALL_STATS +
+ (priv->tx_ring_num + priv->rx_ring_num) * 2;
+ case ETH_SS_TEST:
+ return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2;
+ default:
return -EOPNOTSUPP;
-
- return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
+ }
}
static void mlx4_en_get_ethtool_stats(struct net_device *dev,
@@ -161,8 +159,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
spin_lock_bh(&priv->stats_lock);
- mlx4_en_update_lro_stats(priv);
-
for (i = 0; i < NUM_MAIN_STATS; i++)
data[index++] = ((unsigned long *) &priv->stats)[i];
for (i = 0; i < NUM_PORT_STATS; i++)
@@ -181,6 +177,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
}
+static void mlx4_en_self_test(struct net_device *dev,
+ struct ethtool_test *etest, u64 *buf)
+{
+ mlx4_en_ex_selftest(dev, &etest->flags, buf);
+}
+
static void mlx4_en_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *data)
{
@@ -188,44 +190,76 @@ static void mlx4_en_get_strings(struct net_device *dev,
int index = 0;
int i;
- if (stringset != ETH_SS_STATS)
- return;
-
- /* Add main counters */
- for (i = 0; i < NUM_MAIN_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
- for (i = 0; i < NUM_PORT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
+ switch (stringset) {
+ case ETH_SS_TEST:
+ for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++)
+ strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
+ if (priv->mdev->dev->caps.loopback_support)
+ for (; i < MLX4_EN_NUM_SELF_TEST; i++)
+ strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]);
+ break;
+
+ case ETH_SS_STATS:
+ /* Add main counters */
+ for (i = 0; i < NUM_MAIN_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
+ for (i = 0; i< NUM_PORT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i + NUM_MAIN_STATS]);
- for (i = 0; i < priv->tx_ring_num; i++) {
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "tx%d_packets", i);
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "tx%d_bytes", i);
- }
- for (i = 0; i < priv->rx_ring_num; i++) {
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "rx%d_packets", i);
- sprintf(data + (index++) * ETH_GSTRING_LEN,
- "rx%d_bytes", i);
- }
- for (i = 0; i < NUM_PKT_STATS; i++)
- strcpy(data + (index++) * ETH_GSTRING_LEN,
+ for (i = 0; i < priv->tx_ring_num; i++) {
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "tx%d_packets", i);
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "tx%d_bytes", i);
+ }
+ for (i = 0; i < priv->rx_ring_num; i++) {
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "rx%d_packets", i);
+ sprintf(data + (index++) * ETH_GSTRING_LEN,
+ "rx%d_bytes", i);
+ }
+ for (i = 0; i< NUM_PKT_STATS; i++)
+ strcpy(data + (index++) * ETH_GSTRING_LEN,
main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
+ break;
+ }
}
static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ int trans_type;
+
cmd->autoneg = AUTONEG_DISABLE;
cmd->supported = SUPPORTED_10000baseT_Full;
- cmd->advertising = ADVERTISED_1000baseT_Full;
+ cmd->advertising = ADVERTISED_10000baseT_Full;
+
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+
+ trans_type = priv->port_state.transciver;
if (netif_carrier_ok(dev)) {
- cmd->speed = SPEED_10000;
+ cmd->speed = priv->port_state.link_speed;
cmd->duplex = DUPLEX_FULL;
} else {
cmd->speed = -1;
cmd->duplex = -1;
}
+
+ if (trans_type > 0 && trans_type <= 0xC) {
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->supported |= SUPPORTED_FIBRE;
+ cmd->advertising |= ADVERTISED_FIBRE;
+ } else if (trans_type == 0x80 || trans_type == 0) {
+ cmd->port = PORT_TP;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->supported |= SUPPORTED_TP;
+ cmd->advertising |= ADVERTISED_TP;
+ } else {
+ cmd->port = -1;
+ cmd->transceiver = -1;
+ }
return 0;
}
@@ -343,8 +377,9 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
- if (rx_size == priv->prof->rx_ring_size &&
- tx_size == priv->prof->tx_ring_size)
+ if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size :
+ priv->rx_ring[0].size) &&
+ tx_size == priv->tx_ring[0].size)
return 0;
mutex_lock(&mdev->state_lock);
@@ -378,49 +413,13 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *param)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
memset(param, 0, sizeof(*param));
param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
- param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size;
- param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
-}
-
-static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data)
-{
- struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
- int rc = 0;
- int changed = 0;
-
- if (data & ~ETH_FLAG_LRO)
- return -EOPNOTSUPP;
-
- if (data & ETH_FLAG_LRO) {
- if (mdev->profile.num_lro == 0)
- return -EOPNOTSUPP;
- if (!(dev->features & NETIF_F_LRO))
- changed = 1;
- } else if (dev->features & NETIF_F_LRO) {
- changed = 1;
- }
-
- if (changed) {
- if (netif_running(dev)) {
- mutex_lock(&mdev->state_lock);
- mlx4_en_stop_port(dev);
- }
- dev->features ^= NETIF_F_LRO;
- if (netif_running(dev)) {
- rc = mlx4_en_start_port(dev);
- if (rc)
- en_err(priv, "Failed to restart port\n");
- mutex_unlock(&mdev->state_lock);
- }
- }
-
- return rc;
+ param->rx_pending = priv->port_up ?
+ priv->rx_ring[0].actual_size : priv->rx_ring[0].size;
+ param->tx_pending = priv->tx_ring[0].size;
}
const struct ethtool_ops mlx4_en_ethtool_ops = {
@@ -441,6 +440,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_strings = mlx4_en_get_strings,
.get_sset_count = mlx4_en_get_sset_count,
.get_ethtool_stats = mlx4_en_get_ethtool_stats,
+ .self_test = mlx4_en_self_test,
.get_wol = mlx4_en_get_wol,
.get_msglevel = mlx4_en_get_msglevel,
.set_msglevel = mlx4_en_set_msglevel,
@@ -451,7 +451,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_ringparam = mlx4_en_get_ringparam,
.set_ringparam = mlx4_en_set_ringparam,
.get_flags = ethtool_op_get_flags,
- .set_flags = mlx4_ethtool_op_set_flags,
};
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 97934f1ec53a..143906417048 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -63,15 +63,12 @@ static const char mlx4_en_version[] =
*/
-/* Use a XOR rathern than Toeplitz hash function for RSS */
-MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
-
-/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
-MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
-
-/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
-MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
- "Number of LRO sessions per ring or disabled (0)");
+/* Enable RSS TCP traffic */
+MLX4_EN_PARM_INT(tcp_rss, 1,
+ "Enable RSS for incomming TCP traffic or disabled (0)");
+/* Enable RSS UDP traffic */
+MLX4_EN_PARM_INT(udp_rss, 1,
+ "Enable RSS for incomming UDP traffic or disabled (0)");
/* Priority pausing */
MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
@@ -107,9 +104,12 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
struct mlx4_en_profile *params = &mdev->profile;
int i;
- params->rss_xor = (rss_xor != 0);
- params->rss_mask = rss_mask & 0x1f;
- params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
+ params->tcp_rss = tcp_rss;
+ params->udp_rss = udp_rss;
+ if (params->udp_rss && !mdev->dev->caps.udp_rss) {
+ mlx4_warn(mdev, "UDP RSS is not supported on this device.\n");
+ params->udp_rss = 0;
+ }
for (i = 1; i <= MLX4_MAX_PORTS; i++) {
params->prof[i].rx_pause = 1;
params->prof[i].rx_ppp = pfcrx;
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index a0d8a26f5a02..411bda581c04 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -109,7 +109,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
mutex_unlock(&mdev->state_lock);
}
-static u64 mlx4_en_mac_to_u64(u8 *addr)
+u64 mlx4_en_mac_to_u64(u8 *addr)
{
u64 mac = 0;
int i;
@@ -513,6 +513,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
}
+ if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
+ queue_work(mdev->workqueue, &priv->mac_task);
+ mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
+ }
mutex_unlock(&mdev->state_lock);
}
@@ -528,10 +532,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
* report to system log */
if (priv->last_link_state != linkstate) {
if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
- en_dbg(LINK, priv, "Link Down\n");
+ en_info(priv, "Link Down\n");
netif_carrier_off(priv->dev);
} else {
- en_dbg(LINK, priv, "Link Up\n");
+ en_info(priv, "Link Up\n");
netif_carrier_on(priv->dev);
}
}
@@ -653,6 +657,7 @@ int mlx4_en_start_port(struct net_device *dev)
en_err(priv, "Failed setting port mac\n");
goto tx_err;
}
+ mdev->mac_removed[priv->port] = 0;
/* Init port */
en_dbg(HW, priv, "Initializing port\n");
@@ -704,12 +709,12 @@ void mlx4_en_stop_port(struct net_device *dev)
netif_tx_stop_all_queues(dev);
netif_tx_unlock_bh(dev);
- /* close port*/
+ /* Set port as not active */
priv->port_up = false;
- mlx4_CLOSE_PORT(mdev->dev, priv->port);
/* Unregister Mac address for the port */
mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+ mdev->mac_removed[priv->port] = 1;
/* Free TX Rings */
for (i = 0; i < priv->tx_ring_num; i++) {
@@ -731,6 +736,9 @@ void mlx4_en_stop_port(struct net_device *dev)
msleep(1);
mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
}
+
+ /* close port*/
+ mlx4_CLOSE_PORT(mdev->dev, priv->port);
}
static void mlx4_en_restart(struct work_struct *work)
@@ -1023,9 +1031,10 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
/* Set defualt MAC */
dev->addr_len = ETH_ALEN;
- for (i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[ETH_ALEN - 1 - i] =
- (u8) (priv->mac >> (8 * i));
+ for (i = 0; i < ETH_ALEN; i++) {
+ dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+ dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+ }
/*
* Set driver features
@@ -1038,8 +1047,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
dev->features |= NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
- if (mdev->profile.num_lro)
- dev->features |= NETIF_F_LRO;
+ dev->features |= NETIF_F_GRO;
if (mdev->LSO_support) {
dev->features |= NETIF_F_TSO;
dev->features |= NETIF_F_TSO6;
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index a29abe845d2e..aa3ef2aee5bf 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -142,6 +142,38 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
return err;
}
+int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port)
+{
+ struct mlx4_en_query_port_context *qport_context;
+ struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
+ struct mlx4_en_port_state *state = &priv->port_state;
+ struct mlx4_cmd_mailbox *mailbox;
+ int err;
+
+ mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
+ if (IS_ERR(mailbox))
+ return PTR_ERR(mailbox);
+ memset(mailbox->buf, 0, sizeof(*qport_context));
+ err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0,
+ MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B);
+ if (err)
+ goto out;
+ qport_context = mailbox->buf;
+
+ /* This command is always accessed from Ethtool context
+ * already synchronized, no need in locking */
+ state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK);
+ if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) ==
+ MLX4_EN_1G_SPEED)
+ state->link_speed = 1000;
+ else
+ state->link_speed = 10000;
+ state->transciver = qport_context->transceiver;
+
+out:
+ mlx4_free_cmd_mailbox(mdev->dev, mailbox);
+ return err;
+}
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
{
diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h
index e6477f12beb5..f6511aa2b7df 100644
--- a/drivers/net/mlx4/en_port.h
+++ b/drivers/net/mlx4/en_port.h
@@ -84,6 +84,20 @@ enum {
MLX4_MCAST_ENABLE = 2,
};
+struct mlx4_en_query_port_context {
+ u8 link_up;
+#define MLX4_EN_LINK_UP_MASK 0x80
+ u8 reserved;
+ __be16 mtu;
+ u8 reserved2;
+ u8 link_speed;
+#define MLX4_EN_SPEED_MASK 0x3
+#define MLX4_EN_1G_SPEED 0x2
+ u16 reserved3[5];
+ __be64 mac;
+ u8 transceiver;
+};
+
struct mlx4_en_stat_out_mbox {
/* Received frames with a length of 64 octets */
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 8e2fcb7103c3..570f2508fb30 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -42,18 +42,6 @@
#include "mlx4_en.h"
-static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr,
- u64 *hdr_flags, void *priv)
-{
- *mac_hdr = page_address(frags->page) + frags->page_offset;
- *ip_hdr = *mac_hdr + ETH_HLEN;
- *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr));
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- return 0;
-}
-
static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv,
struct mlx4_en_rx_desc *rx_desc,
struct skb_frag_struct *skb_frags,
@@ -251,7 +239,6 @@ reduce_rings:
ring->prod--;
mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
}
- ring->size_mask = ring->actual_size - 1;
}
return 0;
@@ -313,28 +300,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
}
ring->buf = ring->wqres.buf.direct.buf;
- /* Configure lro mngr */
- memset(&ring->lro, 0, sizeof(struct net_lro_mgr));
- ring->lro.dev = priv->dev;
- ring->lro.features = LRO_F_NAPI;
- ring->lro.frag_align_pad = NET_IP_ALIGN;
- ring->lro.ip_summed = CHECKSUM_UNNECESSARY;
- ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY;
- ring->lro.max_desc = mdev->profile.num_lro;
- ring->lro.max_aggr = MAX_SKB_FRAGS;
- ring->lro.lro_arr = kzalloc(mdev->profile.num_lro *
- sizeof(struct net_lro_desc),
- GFP_KERNEL);
- if (!ring->lro.lro_arr) {
- en_err(priv, "Failed to allocate lro array\n");
- goto err_map;
- }
- ring->lro.get_frag_header = mlx4_en_get_frag_header;
-
return 0;
-err_map:
- mlx4_en_unmap_buffer(&ring->wqres.buf);
err_hwq:
mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
err_ring:
@@ -389,6 +356,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
ring = &priv->rx_ring[ring_ind];
+ ring->size_mask = ring->actual_size - 1;
mlx4_en_update_rx_prod_db(ring);
}
@@ -412,7 +380,6 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
{
struct mlx4_en_dev *mdev = priv->mdev;
- kfree(ring->lro.lro_arr);
mlx4_en_unmap_buffer(&ring->wqres.buf);
mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
vfree(ring->rx_info);
@@ -459,7 +426,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
goto fail;
/* Unmap buffer */
- pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+ pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size,
PCI_DMA_FROMDEVICE);
}
/* Adjust size of last fragment to match actual length */
@@ -541,6 +508,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
return skb;
}
+static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb)
+{
+ int i;
+ int offset = ETH_HLEN;
+
+ for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) {
+ if (*(skb->data + offset) != (unsigned char) (i & 0xff))
+ goto out_loopback;
+ }
+ /* Loopback found */
+ priv->loopback_ok = 1;
+
+out_loopback:
+ dev_kfree_skb_any(skb);
+}
int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
{
@@ -548,7 +530,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
struct mlx4_cqe *cqe;
struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
struct skb_frag_struct *skb_frags;
- struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS];
struct mlx4_en_rx_desc *rx_desc;
struct sk_buff *skb;
int index;
@@ -608,37 +589,35 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
* - TCP/IP (v4)
* - without IP options
* - not an IP fragment */
- if (mlx4_en_can_lro(cqe->status) &&
- dev->features & NETIF_F_LRO) {
+ if (dev->features & NETIF_F_GRO) {
+ struct sk_buff *gro_skb = napi_get_frags(&cq->napi);
+ if (!gro_skb)
+ goto next;
nr = mlx4_en_complete_rx_desc(
priv, rx_desc,
- skb_frags, lro_frags,
+ skb_frags, skb_shinfo(gro_skb)->frags,
ring->page_alloc, length);
if (!nr)
goto next;
+ skb_shinfo(gro_skb)->nr_frags = nr;
+ gro_skb->len = length;
+ gro_skb->data_len = length;
+ gro_skb->truesize += length;
+ gro_skb->ip_summed = CHECKSUM_UNNECESSARY;
+
if (priv->vlgrp && (cqe->vlan_my_qpn &
- cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) {
- lro_vlan_hwaccel_receive_frags(
- &ring->lro, lro_frags,
- length, length,
- priv->vlgrp,
- be16_to_cpu(cqe->sl_vid),
- NULL, 0);
- } else
- lro_receive_frags(&ring->lro,
- lro_frags,
- length,
- length,
- NULL, 0);
+ cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK)))
+ vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid));
+ else
+ napi_gro_frags(&cq->napi);
goto next;
}
/* LRO not possible, complete processing here */
ip_summed = CHECKSUM_UNNECESSARY;
- INC_PERF_COUNTER(priv->pstats.lro_misses);
} else {
ip_summed = CHECKSUM_NONE;
priv->port_stats.rx_chksum_none++;
@@ -655,6 +634,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
goto next;
}
+ if (unlikely(priv->validate_loopback)) {
+ validate_loopback(priv, skb);
+ goto next;
+ }
+
skb->ip_summed = ip_summed;
skb->protocol = eth_type_trans(skb, dev);
skb_record_rx_queue(skb, cq->ring);
@@ -674,14 +658,10 @@ next:
if (++polled == budget) {
/* We are here because we reached the NAPI budget -
* flush only pending LRO sessions */
- lro_flush_all(&ring->lro);
goto out;
}
}
- /* If CQ is empty flush all LRO sessions unconditionally */
- lro_flush_all(&ring->lro);
-
out:
AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled);
mlx4_cq_set_ci(&cq->mcq);
@@ -816,7 +796,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
qp->event = mlx4_en_sqp_event;
memset(context, 0, sizeof *context);
- mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0,
+ mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0,
qpn, ring->cqn, context);
context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
@@ -839,8 +819,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
struct mlx4_qp_context context;
struct mlx4_en_rss_context *rss_context;
void *ptr;
- int rss_xor = mdev->profile.rss_xor;
- u8 rss_mask = mdev->profile.rss_mask;
+ u8 rss_mask = 0x3f;
int i, qpn;
int err = 0;
int good_qps = 0;
@@ -886,9 +865,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 |
(rss_map->base_qpn));
rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
- rss_context->hash_fn = rss_xor & 0x3;
- rss_context->flags = rss_mask << 2;
+ rss_context->flags = rss_mask;
+ if (priv->mdev->profile.udp_rss)
+ rss_context->base_qpn_udp = rss_context->default_qpn;
err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context,
&rss_map->indir_qp, &rss_map->indir_state);
if (err)
diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c
new file mode 100644
index 000000000000..43357d35616a
--- /dev/null
+++ b/drivers/net/mlx4/en_selftest.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/mlx4/driver.h>
+
+#include "mlx4_en.h"
+
+
+static int mlx4_en_test_registers(struct mlx4_en_priv *priv)
+{
+ return mlx4_cmd(priv->mdev->dev, 0, 0, 0, MLX4_CMD_HW_HEALTH_CHECK,
+ MLX4_CMD_TIME_CLASS_A);
+}
+
+static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv)
+{
+ struct sk_buff *skb;
+ struct ethhdr *ethh;
+ unsigned char *packet;
+ unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD;
+ unsigned int i;
+ int err;
+
+
+ /* build the pkt before xmit */
+ skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN);
+ if (!skb) {
+ en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr));
+ packet = (unsigned char *)skb_put(skb, packet_size);
+ memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN);
+ memset(ethh->h_source, 0, ETH_ALEN);
+ ethh->h_proto = htons(ETH_P_ARP);
+ skb_set_mac_header(skb, 0);
+ for (i = 0; i < packet_size; ++i) /* fill our packet */
+ packet[i] = (unsigned char)(i & 0xff);
+
+ /* xmit the pkt */
+ err = mlx4_en_xmit(skb, priv->dev);
+ return err;
+}
+
+static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
+{
+ u32 loopback_ok = 0;
+ int i;
+
+
+ priv->loopback_ok = 0;
+ priv->validate_loopback = 1;
+
+ /* xmit */
+ if (mlx4_en_test_loopback_xmit(priv)) {
+ en_err(priv, "Transmitting loopback packet failed\n");
+ goto mlx4_en_test_loopback_exit;
+ }
+
+ /* polling for result */
+ for (i = 0; i < MLX4_EN_LOOPBACK_RETRIES; ++i) {
+ msleep(MLX4_EN_LOOPBACK_TIMEOUT);
+ if (priv->loopback_ok) {
+ loopback_ok = 1;
+ break;
+ }
+ }
+ if (!loopback_ok)
+ en_err(priv, "Loopback packet didn't arrive\n");
+
+mlx4_en_test_loopback_exit:
+
+ priv->validate_loopback = 0;
+ return (!loopback_ok);
+}
+
+
+static int mlx4_en_test_link(struct mlx4_en_priv *priv)
+{
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+ if (priv->port_state.link_state == 1)
+ return 0;
+ else
+ return 1;
+}
+
+static int mlx4_en_test_speed(struct mlx4_en_priv *priv)
+{
+
+ if (mlx4_en_QUERY_PORT(priv->mdev, priv->port))
+ return -ENOMEM;
+
+ /* The device currently only supports 10G speed */
+ if (priv->port_state.link_speed != SPEED_10000)
+ return priv->port_state.link_speed;
+ return 0;
+}
+
+
+void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ struct mlx4_en_tx_ring *tx_ring;
+ int i, carrier_ok;
+
+ memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST);
+
+ if (*flags & ETH_TEST_FL_OFFLINE) {
+ /* disable the interface */
+ carrier_ok = netif_carrier_ok(dev);
+
+ netif_carrier_off(dev);
+retry_tx:
+ /* Wait untill all tx queues are empty.
+ * there should not be any additional incoming traffic
+ * since we turned the carrier off */
+ msleep(200);
+ for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) {
+ tx_ring = &priv->tx_ring[i];
+ if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb))
+ goto retry_tx;
+ }
+
+ if (priv->mdev->dev->caps.loopback_support){
+ buf[3] = mlx4_en_test_registers(priv);
+ buf[4] = mlx4_en_test_loopback(priv);
+ }
+
+ if (carrier_ok)
+ netif_carrier_on(dev);
+
+ }
+ buf[0] = mlx4_test_interrupts(mdev->dev);
+ buf[1] = mlx4_en_test_link(priv);
+ buf[2] = mlx4_en_test_speed(priv);
+
+ for (i = 0; i < MLX4_EN_NUM_SELF_TEST; i++) {
+ if (buf[i])
+ *flags |= ETH_TEST_FL_FAILED;
+ }
+}
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 580968f304eb..98dd620042a8 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -38,6 +38,7 @@
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/vmalloc.h>
+#include <linux/tcp.h>
#include "mlx4_en.h"
@@ -600,6 +601,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
struct mlx4_wqe_data_seg *data;
struct skb_frag_struct *frag;
struct mlx4_en_tx_info *tx_info;
+ struct ethhdr *ethh;
+ u64 mac;
+ u32 mac_l, mac_h;
int tx_ind = 0;
int nr_txbb;
int desc_size;
@@ -612,6 +616,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
int lso_header_size;
void *fragptr;
+ if (!priv->port_up)
+ goto tx_drop;
+
real_size = get_real_size(skb, dev, &lso_header_size);
if (unlikely(!real_size))
goto tx_drop;
@@ -676,6 +683,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
priv->port_stats.tx_chksum_offload++;
}
+ if (unlikely(priv->validate_loopback)) {
+ /* Copy dst mac address to wqe */
+ skb_reset_mac_header(skb);
+ ethh = eth_hdr(skb);
+ if (ethh && ethh->h_dest) {
+ mac = mlx4_en_mac_to_u64(ethh->h_dest);
+ mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16);
+ mac_l = (u32) (mac & 0xffffffff);
+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h);
+ tx_desc->ctrl.imm = cpu_to_be32(mac_l);
+ }
+ }
+
/* Handle LSO (TSO) packets */
if (lso_header_size) {
/* Mark opcode as LSO */
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 6d7b2bf210ce..552d0fce6f67 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
kfree(priv->eq_table.uar_map);
}
+
+/* A test that verifies that we can accept interrupts on all
+ * the irq vectors of the device.
+ * Interrupts are checked using the NOP command.
+ */
+int mlx4_test_interrupts(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int i;
+ int err;
+
+ err = mlx4_NOP(dev);
+ /* When not in MSI_X, there is only one irq to check */
+ if (!(dev->flags & MLX4_FLAG_MSI_X))
+ return err;
+
+ /* A loop over all completion vectors, for each vector we will check
+ * whether it works by mapping command completions to that vector
+ * and performing a NOP command
+ */
+ for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
+ /* Temporary use polling for command completions */
+ mlx4_cmd_use_polling(dev);
+
+ /* Map the new eq to handle all asyncronous events */
+ err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
+ priv->eq_table.eq[i].eqn);
+ if (err) {
+ mlx4_warn(dev, "Failed mapping eq for interrupt test\n");
+ mlx4_cmd_use_events(dev);
+ break;
+ }
+
+ /* Go back to using events */
+ mlx4_cmd_use_events(dev);
+ err = mlx4_NOP(dev);
+ }
+
+ /* Return to default */
+ mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
+ priv->eq_table.eq[dev->caps.num_comp_vectors].eqn);
+ return err;
+}
+EXPORT_SYMBOL(mlx4_test_interrupts);
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 04f42ae1eda0..b716e1a1b298 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -141,6 +141,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
struct mlx4_cmd_mailbox *mailbox;
u32 *outbox;
u8 field;
+ u32 field32;
u16 size;
u16 stat_rate;
int err;
@@ -178,6 +179,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b
#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
+#define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42
+#define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43
#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -268,6 +271,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->max_msg_sz = 1 << (field & 0x1f);
MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
dev_cap->stat_rate_support = stat_rate;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET);
+ dev_cap->udp_rss = field & 0x1;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET);
+ dev_cap->loopback_support = field & 0x1;
MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4;
@@ -365,6 +372,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a
#define QUERY_PORT_MAX_VL_OFFSET 0x0b
#define QUERY_PORT_MAC_OFFSET 0x10
+#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18
+#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c
+#define QUERY_PORT_TRANS_CODE_OFFSET 0x20
for (i = 1; i <= dev_cap->num_ports; ++i) {
err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
@@ -388,6 +398,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->log_max_vlans[i] = field >> 4;
MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET);
MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET);
+ MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET);
+ dev_cap->trans_type[i] = field32 >> 24;
+ dev_cap->vendor_oui[i] = field32 & 0xffffff;
+ MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET);
+ MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET);
}
}
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 526d7f30c041..65cc72eb899d 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -73,7 +73,13 @@ struct mlx4_dev_cap {
int max_pkeys[MLX4_MAX_PORTS + 1];
u64 def_mac[MLX4_MAX_PORTS + 1];
u16 eth_mtu[MLX4_MAX_PORTS + 1];
+ int trans_type[MLX4_MAX_PORTS + 1];
+ int vendor_oui[MLX4_MAX_PORTS + 1];
+ u16 wavelength[MLX4_MAX_PORTS + 1];
+ u64 trans_code[MLX4_MAX_PORTS + 1];
u16 stat_rate_support;
+ int udp_rss;
+ int loopback_support;
u32 flags;
int reserved_uars;
int uar_size;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 5102ab1ac561..569fa3df381f 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -184,6 +184,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i];
dev->caps.def_mac[i] = dev_cap->def_mac[i];
dev->caps.supported_type[i] = dev_cap->supported_port_types[i];
+ dev->caps.trans_type[i] = dev_cap->trans_type[i];
+ dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i];
+ dev->caps.wavelength[i] = dev_cap->wavelength[i];
+ dev->caps.trans_code[i] = dev_cap->trans_code[i];
}
dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE;
@@ -221,6 +225,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.bmme_flags = dev_cap->bmme_flags;
dev->caps.reserved_lkey = dev_cap->reserved_lkey;
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
+ dev->caps.udp_rss = dev_cap->udp_rss;
+ dev->caps.loopback_support = dev_cap->loopback_support;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
dev->caps.log_num_macs = log_num_mac;
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 449210994ee9..1fc16ab7ad2f 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -38,19 +38,19 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/qp.h>
#include <linux/mlx4/cq.h>
#include <linux/mlx4/srq.h>
#include <linux/mlx4/doorbell.h>
+#include <linux/mlx4/cmd.h>
#include "en_port.h"
#define DRV_NAME "mlx4_en"
-#define DRV_VERSION "1.4.1.1"
-#define DRV_RELDATE "June 2009"
+#define DRV_VERSION "1.5.1.6"
+#define DRV_RELDATE "August 2010"
#define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
@@ -61,7 +61,6 @@
#define MLX4_EN_PAGE_SHIFT 12
#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT)
-#define MAX_TX_RINGS 16
#define MAX_RX_RINGS 16
#define TXBB_SIZE 64
#define HEADROOM (2048 / TXBB_SIZE + 1)
@@ -107,6 +106,7 @@ enum {
#define MLX4_EN_SMALL_PKT_SIZE 64
#define MLX4_EN_NUM_TX_RINGS 8
#define MLX4_EN_NUM_PPP_RINGS 8
+#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
#define MLX4_EN_DEF_TX_RING_SIZE 512
#define MLX4_EN_DEF_RX_RING_SIZE 1024
@@ -139,10 +139,14 @@ enum {
#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN)
#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN)
+#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN)
#define MLX4_EN_MIN_MTU 46
#define ETH_BCAST 0xffffffffffffULL
+#define MLX4_EN_LOOPBACK_RETRIES 5
+#define MLX4_EN_LOOPBACK_TIMEOUT 100
+
#ifdef MLX4_EN_PERF_STAT
/* Number of samples to 'average' */
#define AVG_SIZE 128
@@ -249,7 +253,6 @@ struct mlx4_en_rx_desc {
struct mlx4_en_rx_ring {
struct mlx4_hwq_resources wqres;
struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
- struct net_lro_mgr lro;
u32 size ; /* number of Rx descs*/
u32 actual_size;
u32 size_mask;
@@ -313,7 +316,8 @@ struct mlx4_en_port_profile {
struct mlx4_en_profile {
int rss_xor;
- int num_lro;
+ int tcp_rss;
+ int udp_rss;
u8 rss_mask;
u32 active_ports;
u32 small_pkt_int;
@@ -337,6 +341,7 @@ struct mlx4_en_dev {
struct mlx4_mr mr;
u32 priv_pdn;
spinlock_t uar_lock;
+ u8 mac_removed[MLX4_MAX_PORTS + 1];
};
@@ -355,6 +360,13 @@ struct mlx4_en_rss_context {
u8 hash_fn;
u8 flags;
__be32 rss_key[10];
+ __be32 base_qpn_udp;
+};
+
+struct mlx4_en_port_state {
+ int link_state;
+ int link_speed;
+ int transciver;
};
struct mlx4_en_pkt_stats {
@@ -365,9 +377,6 @@ struct mlx4_en_pkt_stats {
};
struct mlx4_en_port_stats {
- unsigned long lro_aggregated;
- unsigned long lro_flushed;
- unsigned long lro_no_desc;
unsigned long tso_packets;
unsigned long queue_stopped;
unsigned long wake_queue;
@@ -376,7 +385,7 @@ struct mlx4_en_port_stats {
unsigned long rx_chksum_good;
unsigned long rx_chksum_none;
unsigned long tx_chksum_offload;
-#define NUM_PORT_STATS 11
+#define NUM_PORT_STATS 8
};
struct mlx4_en_perf_stats {
@@ -405,6 +414,7 @@ struct mlx4_en_priv {
struct vlan_group *vlgrp;
struct net_device_stats stats;
struct net_device_stats ret_stats;
+ struct mlx4_en_port_state port_state;
spinlock_t stats_lock;
unsigned long last_moder_packets;
@@ -423,6 +433,8 @@ struct mlx4_en_priv {
u16 sample_interval;
u16 adaptive_rx_coal;
u32 msg_enable;
+ u32 loopback_ok;
+ u32 validate_loopback;
struct mlx4_hwq_resources res;
int link_state;
@@ -531,6 +543,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
u8 promisc);
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
+int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port);
+
+#define MLX4_EN_NUM_SELF_TEST 5
+void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
+u64 mlx4_en_mac_to_u64(u8 *addr);
/*
* Globals
@@ -555,6 +572,8 @@ do { \
en_print(KERN_WARNING, priv, format, ##arg)
#define en_err(priv, format, arg...) \
en_print(KERN_ERR, priv, format, ##arg)
+#define en_info(priv, format, arg...) \
+ en_print(KERN_INFO, priv, format, ## arg)
#define mlx4_err(mdev, format, arg...) \
pr_err("%s %s: " format, DRV_NAME, \
diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c
index 5caf0115fa5b..e749f82865fe 100644
--- a/drivers/net/mlx4/profile.c
+++ b/drivers/net/mlx4/profile.c
@@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
struct mlx4_resource tmp;
int i, j;
- profile = kzalloc(MLX4_RES_NUM * sizeof *profile, GFP_KERNEL);
+ profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL);
if (!profile)
return -ENOMEM;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index fb2c0927d3cc..24ab8a43c777 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3753,8 +3753,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
* slices. We give up on MSI-X if we can only get a single
* vector. */
- mgp->msix_vectors = kzalloc(mgp->num_slices *
- sizeof(*mgp->msix_vectors), GFP_KERNEL);
+ mgp->msix_vectors = kcalloc(mgp->num_slices, sizeof(*mgp->msix_vectors),
+ GFP_KERNEL);
if (mgp->msix_vectors == NULL)
goto disable_msix;
for (i = 0; i < mgp->num_slices; i++) {
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a6033d48b5cc..2fd39630b1e5 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1570,7 +1570,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ);
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
return 0;
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index bc695d53cdcc..8e1859c801a4 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3484,7 +3484,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
RCR_ENTRY_ERROR)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else if (!(val & RCR_ENTRY_MULTI))
append_size = len - skb->len;
@@ -4504,7 +4504,7 @@ static int niu_alloc_channels(struct niu *np)
np->dev->real_num_tx_queues = np->num_tx_rings;
- np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info),
+ np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info),
GFP_KERNEL);
err = -ENOMEM;
if (!np->rx_rings)
@@ -4538,7 +4538,7 @@ static int niu_alloc_channels(struct niu *np)
return err;
}
- np->tx_rings = kzalloc(np->num_tx_rings * sizeof(struct tx_ring_info),
+ np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info),
GFP_KERNEL);
err = -ENOMEM;
if (!np->tx_rings)
@@ -7269,32 +7269,28 @@ static int niu_get_ethtool_tcam_all(struct niu *np,
struct niu_parent *parent = np->parent;
struct niu_tcam_entry *tp;
int i, idx, cnt;
- u16 n_entries;
unsigned long flags;
-
+ int ret = 0;
/* 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;
+ if (cnt == nfc->rule_cnt) {
+ ret = -EMSGSIZE;
+ break;
+ }
rule_locs[cnt] = i;
cnt++;
}
niu_unlock_parent(np, flags);
- if (n_entries != cnt) {
- /* print warning, this should not happen */
- netdev_info(np->dev, "niu%d: In %s(): n_entries[%d] != cnt[%d]!!!\n",
- np->parent->index, __func__, n_entries, cnt);
- }
-
- return 0;
+ return ret;
}
static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 5a3488f76b38..3bbd0aab17e8 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -923,7 +923,7 @@ static void rx_irq(struct net_device *ndev)
if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
skb->protocol = eth_type_trans(skb, ndev);
#ifdef NS83820_VLAN_ACCEL_SUPPORT
@@ -1246,7 +1246,6 @@ static int ns83820_get_settings(struct net_device *ndev,
{
struct ns83820 *dev = PRIV(ndev);
u32 cfg, tanar, tbicr;
- int have_optical = 0;
int fullduplex = 0;
/*
@@ -1267,25 +1266,25 @@ static int ns83820_get_settings(struct net_device *ndev,
tanar = readl(dev->base + TANAR);
tbicr = readl(dev->base + TBICR);
- if (dev->CFG_cache & CFG_TBI_EN) {
- /* we have an optical interface */
- have_optical = 1;
- fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
-
- } else {
- /* We have copper */
- fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
- }
+ fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0;
cmd->supported = SUPPORTED_Autoneg;
- /* we have optical interface */
if (dev->CFG_cache & CFG_TBI_EN) {
+ /* we have optical interface */
cmd->supported |= SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE;
cmd->port = PORT_FIBRE;
- } /* TODO: else copper related support */
+ } else {
+ /* we have copper */
+ cmd->supported |= SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_MII;
+ cmd->port = PORT_MII;
+ }
cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF;
switch (cfg / CFG_SPDSTS0 & 3) {
@@ -1299,7 +1298,8 @@ static int ns83820_get_settings(struct net_device *ndev,
cmd->speed = SPEED_10;
break;
}
- cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0;
+ cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE)
+ ? AUTONEG_ENABLE : AUTONEG_DISABLE;
return 0;
}
@@ -1405,6 +1405,13 @@ static const struct ethtool_ops ops = {
.get_link = ns83820_get_link
};
+static inline void ns83820_disable_interrupts(struct ns83820 *dev)
+{
+ writel(0, dev->base + IMR);
+ writel(0, dev->base + IER);
+ readl(dev->base + IER);
+}
+
/* this function is called in irq context from the ISR */
static void ns83820_mib_isr(struct ns83820 *dev)
{
@@ -1557,10 +1564,7 @@ static int ns83820_stop(struct net_device *ndev)
/* FIXME: protect against interrupt handler? */
del_timer_sync(&dev->tx_watchdog);
- /* disable interrupts */
- writel(0, dev->base + IMR);
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev);
dev->rx_info.up = 0;
synchronize_irq(dev->pci_dev->irq);
@@ -2023,10 +2027,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
dev->tx_descs, (long)dev->tx_phy_descs,
dev->rx_info.descs, (long)dev->rx_info.phy_descs);
- /* disable interrupts */
- writel(0, dev->base + IMR);
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev);
dev->IMR_cache = 0;
@@ -2250,9 +2251,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
return 0;
out_cleanup:
- writel(0, dev->base + IMR); /* paranoia */
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev); /* paranoia */
out_free_irq:
rtnl_unlock();
free_irq(pci_dev->irq, ndev);
@@ -2277,9 +2276,7 @@ static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
if (!ndev) /* paranoia */
return;
- writel(0, dev->base + IMR); /* paranoia */
- writel(0, dev->base + IER);
- readl(dev->base + IER);
+ ns83820_disable_interrupts(dev); /* paranoia */
unregister_netdev(ndev);
free_irq(dev->pci_dev->irq, ndev);
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 8ab6ae0a6107..828e97cacdbf 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -808,7 +808,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx,
skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
packets++;
tot_bytes += len;
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
index fefa79e34b95..4825959a0efe 100644
--- a/drivers/net/pasemi_mac_ethtool.c
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -90,21 +90,6 @@ pasemi_mac_ethtool_set_settings(struct net_device *netdev,
return phy_ethtool_sset(phydev, cmd);
}
-static void
-pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct pasemi_mac *mac;
- mac = netdev_priv(netdev);
-
- /* clear and fill out info */
- memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
- strncpy(drvinfo->driver, "pasemi_mac", 12);
- strcpy(drvinfo->version, "N/A");
- strcpy(drvinfo->fw_version, "N/A");
- strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32);
-}
-
static u32
pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
{
@@ -164,7 +149,6 @@ static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
const struct ethtool_ops pasemi_mac_ethtool_ops = {
.get_settings = pasemi_mac_ethtool_get_settings,
.set_settings = pasemi_mac_ethtool_set_settings,
- .get_drvinfo = pasemi_mac_ethtool_get_drvinfo,
.get_msglevel = pasemi_mac_ethtool_get_msglevel,
.set_msglevel = pasemi_mac_ethtool_set_msglevel,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 56f3fc45dbaa..8dd03439d994 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1125,7 +1125,7 @@ static int netdrv_open(struct net_device *dev)
init_timer(&tp->timer);
tp->timer.expires = jiffies + 3 * HZ;
tp->timer.data = (unsigned long) dev;
- tp->timer.function = &netdrv_timer;
+ tp->timer.function = netdrv_timer;
add_timer(&tp->timer);
DPRINTK("EXIT, returning 0\n");
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index c683f77c6f42..042f6777e6b9 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -69,6 +69,8 @@ earlier 3Com products.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -83,7 +85,6 @@ earlier 3Com products.
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
-#include <linux/ethtool.h>
#include <linux/bitops.h>
#include <linux/mii.h>
@@ -238,7 +239,6 @@ static int el3_rx(struct net_device *dev, int worklimit);
static int el3_close(struct net_device *dev);
static void el3_tx_timeout(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
@@ -285,7 +285,6 @@ static int tc574_probe(struct pcmcia_device *link)
link->conf.ConfigIndex = 1;
dev->netdev_ops = &el3_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->watchdog_timeo = TX_TIMEOUT;
return tc574_config(link);
@@ -376,8 +375,8 @@ static int tc574_config(struct pcmcia_device *link)
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
if (phys_addr[0] == htons(0x6060)) {
- printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx"
- "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
+ pr_notice("IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
goto failed;
}
}
@@ -391,7 +390,7 @@ static int tc574_config(struct pcmcia_device *link)
outw(2<<11, ioaddr + RunnerRdCtrl);
mcr = inb(ioaddr + 2);
outw(0<<11, ioaddr + RunnerRdCtrl);
- printk(KERN_INFO " ASIC rev %d,", mcr>>3);
+ pr_info(" ASIC rev %d,", mcr>>3);
EL3WINDOW(3);
config = inl(ioaddr + Wn3_Config);
lp->default_media = (config & Xcvr) >> Xcvr_shift;
@@ -428,7 +427,7 @@ static int tc574_config(struct pcmcia_device *link)
}
}
if (phy > 32) {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ pr_notice(" No MII transceivers found!\n");
goto failed;
}
i = mdio_read(ioaddr, lp->phys, 16) | 0x40;
@@ -444,18 +443,16 @@ static int tc574_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
- "hw_addr %pM.\n",
- dev->name, cardname, dev->base_addr, dev->irq,
- dev->dev_addr);
- printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
- 8 << config & Ram_size,
- ram_split[(config & Ram_split) >> Ram_split_shift],
- config & Autoselect ? "autoselect " : "");
+ netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",
+ cardname, dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
+ 8 << config & Ram_size,
+ ram_split[(config & Ram_split) >> Ram_split_shift],
+ config & Autoselect ? "autoselect " : "");
return 0;
@@ -502,14 +499,14 @@ static void dump_status(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
EL3WINDOW(1);
- printk(KERN_INFO " irq status %04x, rx status %04x, tx status "
- "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
- inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
- inw(ioaddr+TxFree));
+ netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x, tx free %04x\n",
+ inw(ioaddr+EL3_STATUS),
+ inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
+ inw(ioaddr+TxFree));
EL3WINDOW(4);
- printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x"
- " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
- inw(ioaddr+0x08), inw(ioaddr+0x0a));
+ netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n",
+ inw(ioaddr+0x04), inw(ioaddr+0x06),
+ inw(ioaddr+0x08), inw(ioaddr+0x0a));
EL3WINDOW(1);
}
@@ -523,7 +520,7 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd)
while (--i > 0)
if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
if (i == 0)
- printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd);
+ netdev_notice(dev, "command 0x%04x did not complete!\n", cmd);
}
/* Read a word from the EEPROM using the regular EEPROM access register.
@@ -710,7 +707,7 @@ static int el3_open(struct net_device *dev)
netif_start_queue(dev);
tc574_reset(dev);
- lp->media.function = &media_check;
+ lp->media.function = media_check;
lp->media.data = (unsigned long) dev;
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
@@ -725,7 +722,7 @@ static void el3_tx_timeout(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
+ netdev_notice(dev, "Transmit timed out!\n");
dump_status(dev);
dev->stats.tx_errors++;
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -848,8 +845,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
EL3WINDOW(4);
fifo_diag = inw(ioaddr + Wn4_FIFODiag);
EL3WINDOW(1);
- printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic"
- " register %04x.\n", dev->name, fifo_diag);
+ netdev_notice(dev, "adapter failure, FIFO diagnostic register %04x\n",
+ fifo_diag);
if (fifo_diag & 0x0400) {
/* Tx overrun */
tc574_wait_for_completion(dev, TxReset);
@@ -903,7 +900,7 @@ static void media_check(unsigned long arg)
this, we can limp along even if the interrupt is blocked */
if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
if (!lp->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
local_irq_save(flags);
el3_interrupt(dev->irq, dev);
@@ -926,23 +923,21 @@ static void media_check(unsigned long arg)
if (media != lp->media_status) {
if ((media ^ lp->media_status) & 0x0004)
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (lp->media_status & 0x0004) ? "lost" : "found");
+ netdev_info(dev, "%s link beat\n",
+ (lp->media_status & 0x0004) ? "lost" : "found");
if ((media ^ lp->media_status) & 0x0020) {
lp->partner = 0;
if (lp->media_status & 0x0020) {
- printk(KERN_INFO "%s: autonegotiation restarted\n",
- dev->name);
+ netdev_info(dev, "autonegotiation restarted\n");
} else if (partner) {
partner &= lp->advertising;
lp->partner = partner;
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((partner & 0x0180) ? "100" : "10"),
- ((partner & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%dbaseT-%cD selected\n",
+ (partner & 0x0180) ? 100 : 10,
+ (partner & 0x0140) ? 'F' : 'H');
} else {
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
EL3WINDOW(3);
@@ -952,10 +947,9 @@ static void media_check(unsigned long arg)
}
if (media & 0x0010)
- printk(KERN_INFO "%s: remote fault detected\n",
- dev->name);
+ netdev_info(dev, "remote fault detected\n");
if (media & 0x0002)
- printk(KERN_INFO "%s: jabber detected\n", dev->name);
+ netdev_info(dev, "jabber detected\n");
lp->media_status = media;
}
spin_unlock_irqrestore(&lp->window_lock, flags);
@@ -1065,16 +1059,6 @@ static int el3_rx(struct net_device *dev, int worklimit)
return worklimit;
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "3c574_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/* Provide ioctl() calls to examine the MII xcvr state. */
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 61f9cf2100ff..7f2baf5eae26 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -19,6 +19,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "3c589_cs"
#define DRV_VERSION "1.162-ac"
@@ -273,8 +275,7 @@ static int tc589_config(struct pcmcia_device *link)
phys_addr = (__be16 *)dev->dev_addr;
/* Is this a 3c562? */
if (link->manf_id != MANFID_3COM)
- printk(KERN_INFO "3c589_cs: hmmm, is this really a "
- "3Com card??\n");
+ dev_info(&link->dev, "hmmm, is this really a 3Com card??\n");
multi = (link->card_id == PRODID_3COM_3C562);
link->io_lines = 16;
@@ -315,8 +316,8 @@ static int tc589_config(struct pcmcia_device *link)
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
if (phys_addr[0] == htons(0x6060)) {
- printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx"
- "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
+ dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
goto failed;
}
}
@@ -330,12 +331,12 @@ static int tc589_config(struct pcmcia_device *link)
if ((if_port >= 0) && (if_port <= 3))
dev->if_port = if_port;
else
- printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
+ dev_err(&link->dev, "invalid if_port requested\n");
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
+ dev_err(&link->dev, "register_netdev() failed\n");
goto failed;
}
@@ -537,7 +538,7 @@ static int el3_open(struct net_device *dev)
tc589_reset(dev);
init_timer(&lp->media);
- lp->media.function = &media_check;
+ lp->media.function = media_check;
lp->media.data = (unsigned long) dev;
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 5f05ffb240cc..3f61fde70d73 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -24,6 +24,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -32,7 +34,6 @@
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
@@ -86,7 +87,6 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
static struct net_device_stats *get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void axnet_tx_timeout(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void axnet_reset_8390(struct net_device *dev);
@@ -171,7 +171,6 @@ static int axnet_probe(struct pcmcia_device *link)
dev->netdev_ops = &axnet_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->watchdog_timeo = TX_TIMEOUT;
return axnet_config(link);
@@ -347,8 +346,8 @@ static int axnet_config(struct pcmcia_device *link)
dev->base_addr = link->resource[0]->start;
if (!get_prom(link)) {
- printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
- printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
+ pr_notice("this is not an AX88190 card!\n");
+ pr_notice("use pcnet_cs instead.\n");
goto failed;
}
@@ -357,10 +356,10 @@ static int axnet_config(struct pcmcia_device *link)
ei_status.tx_start_page = AXNET_START_PG;
ei_status.rx_start_page = AXNET_START_PG + TX_PAGES;
ei_status.stop_page = AXNET_STOP_PG;
- ei_status.reset_8390 = &axnet_reset_8390;
- ei_status.get_8390_hdr = &get_8390_hdr;
- ei_status.block_input = &block_input;
- ei_status.block_output = &block_output;
+ ei_status.reset_8390 = axnet_reset_8390;
+ ei_status.get_8390_hdr = get_8390_hdr;
+ ei_status.block_input = block_input;
+ ei_status.block_output = block_output;
if (inb(dev->base_addr + AXNET_TEST) != 0)
info->flags |= IS_AX88790;
@@ -393,19 +392,18 @@ static int axnet_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
- dev->base_addr, dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n",
+ ((info->flags & IS_AX88790) ? 7 : 1),
+ dev->base_addr, dev->irq, dev->dev_addr);
if (info->phy_id != -1) {
- dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
+ netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
+ info->phy_id, j);
} else {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ netdev_notice(dev, " No MII transceivers found!\n");
}
return 0;
@@ -532,7 +530,7 @@ static int axnet_open(struct net_device *dev)
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -585,8 +583,7 @@ static void axnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: axnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "axnet_reset_8390() did not complete\n");
} /* axnet_reset_8390 */
@@ -613,7 +610,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -628,7 +625,7 @@ static void ei_watchdog(u_long arg)
goto reschedule;
link = mdio_read(mii_addr, info->phy_id, 1);
if (!link || (link == 0xffff)) {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->phy_id = -1;
goto reschedule;
}
@@ -636,18 +633,14 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link) {
info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00;
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- ((p & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n",
+ (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H');
else
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
AX88190_init(dev, 1);
}
info->link_status = link;
@@ -658,16 +651,6 @@ reschedule:
add_timer(&info->watchdog);
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "axnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/*====================================================================*/
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -855,9 +838,6 @@ module_exit(exit_axnet_cs);
*/
-static const char version_8390[] = KERN_INFO \
- "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
-
#include <linux/bitops.h>
#include <asm/irq.h>
#include <linux/fcntl.h>
@@ -1004,9 +984,11 @@ static void axnet_tx_timeout(struct net_device *dev)
isr = inb(e8390_base+EN0_ISR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
- dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
- (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
+ netdev_printk(KERN_DEBUG, dev,
+ "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
+ (txsr & ENTSR_ABT) ? "excess collisions." :
+ (isr) ? "lost interrupt?" : "cable problem?",
+ txsr, isr, tickssofar);
if (!isr && !dev->stats.tx_packets)
{
@@ -1076,22 +1058,28 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
output_page = ei_local->tx_start_page;
ei_local->tx1 = send_length;
if (ei_debug && ei_local->tx2 > 0)
- printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing);
+ netdev_printk(KERN_DEBUG, dev,
+ "idle transmitter tx2=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx2, ei_local->lasttx,
+ ei_local->txing);
}
else if (ei_local->tx2 == 0)
{
output_page = ei_local->tx_start_page + TX_PAGES/2;
ei_local->tx2 = send_length;
if (ei_debug && ei_local->tx1 > 0)
- printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing);
+ netdev_printk(KERN_DEBUG, dev,
+ "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx1, ei_local->lasttx,
+ ei_local->txing);
}
else
{ /* We should never get here. */
if (ei_debug)
- printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n",
- dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx);
+ netdev_printk(KERN_DEBUG, dev,
+ "No Tx buffers free! tx1=%d tx2=%d last=%d\n",
+ ei_local->tx1, ei_local->tx2,
+ ei_local->lasttx);
ei_local->irqlock = 0;
netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
@@ -1179,23 +1167,26 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&ei_local->page_lock, flags);
- if (ei_local->irqlock)
- {
+ if (ei_local->irqlock) {
#if 1 /* This might just be an interrupt for a PCI device sharing this line */
+ const char *msg;
/* The "irqlock" check is only for testing. */
- printk(ei_local->irqlock
- ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
- : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
- dev->name, inb_p(e8390_base + EN0_ISR),
- inb_p(e8390_base + EN0_IMR));
+ if (ei_local->irqlock)
+ msg = "Interrupted while interrupts are masked!";
+ else
+ msg = "Reentering the interrupt handler!";
+ netdev_info(dev, "%s, isr=%#2x imr=%#2x\n",
+ msg,
+ inb_p(e8390_base + EN0_ISR),
+ inb_p(e8390_base + EN0_IMR));
#endif
spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_NONE;
}
if (ei_debug > 3)
- printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name,
- inb_p(e8390_base + EN0_ISR));
+ netdev_printk(KERN_DEBUG, dev, "interrupt(isr=%#2.2x)\n",
+ inb_p(e8390_base + EN0_ISR));
outb_p(0x00, e8390_base + EN0_ISR);
ei_local->irqlock = 1;
@@ -1206,7 +1197,8 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
{
if (!netif_running(dev) || (interrupts == 0xff)) {
if (ei_debug > 1)
- printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
+ netdev_warn(dev,
+ "interrupt from stopped card\n");
outb_p(interrupts, e8390_base + EN0_ISR);
interrupts = 0;
break;
@@ -1249,11 +1241,12 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
{
/* 0xFF is valid for a card removal */
if(interrupts!=0xFF)
- printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
- dev->name, interrupts);
+ netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n",
+ interrupts);
outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
} else {
- printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts);
+ netdev_warn(dev, "unknown interrupt %#2x\n",
+ interrupts);
outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
}
}
@@ -1287,18 +1280,19 @@ static void ei_tx_err(struct net_device *dev)
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
#ifdef VERBOSE_ERROR_DUMP
- printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);
+ netdev_printk(KERN_DEBUG, dev,
+ "transmitter error (%#2x):", txsr);
if (txsr & ENTSR_ABT)
- printk("excess-collisions ");
+ pr_cont(" excess-collisions");
if (txsr & ENTSR_ND)
- printk("non-deferral ");
+ pr_cont(" non-deferral");
if (txsr & ENTSR_CRS)
- printk("lost-carrier ");
+ pr_cont(" lost-carrier");
if (txsr & ENTSR_FU)
- printk("FIFO-underrun ");
+ pr_cont(" FIFO-underrun");
if (txsr & ENTSR_CDH)
- printk("lost-heartbeat ");
- printk("\n");
+ pr_cont(" lost-heartbeat");
+ pr_cont("\n");
#endif
if (tx_was_aborted)
@@ -1335,8 +1329,9 @@ static void ei_tx_intr(struct net_device *dev)
if (ei_local->tx1 < 0)
{
if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
- printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx1);
+ netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx1);
ei_local->tx1 = 0;
if (ei_local->tx2 > 0)
{
@@ -1351,8 +1346,9 @@ static void ei_tx_intr(struct net_device *dev)
else if (ei_local->tx2 < 0)
{
if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
- printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx2);
+ netdev_info(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx2);
ei_local->tx2 = 0;
if (ei_local->tx1 > 0)
{
@@ -1365,8 +1361,9 @@ static void ei_tx_intr(struct net_device *dev)
else
ei_local->lasttx = 10, ei_local->txing = 0;
}
-// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
-// dev->name, ei_local->lasttx);
+// else
+// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n",
+// ei_local->lasttx);
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
@@ -1429,8 +1426,8 @@ static void ei_receive(struct net_device *dev)
is that some clones crash in roughly the same way.
*/
if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
- printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",
- dev->name, this_frame, ei_local->current_page);
+ netdev_err(dev, "mismatched read page pointers %2x vs %2x\n",
+ this_frame, ei_local->current_page);
if (this_frame == rxing_page) /* Read all the frames? */
break; /* Done for now */
@@ -1446,9 +1443,10 @@ static void ei_receive(struct net_device *dev)
if (pkt_len < 60 || pkt_len > 1518)
{
if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
- dev->name, rx_frame.count, rx_frame.status,
- rx_frame.next);
+ netdev_printk(KERN_DEBUG, dev,
+ "bogus packet size: %d, status=%#2x nxpg=%#2x\n",
+ rx_frame.count, rx_frame.status,
+ rx_frame.next);
dev->stats.rx_errors++;
dev->stats.rx_length_errors++;
}
@@ -1460,8 +1458,9 @@ static void ei_receive(struct net_device *dev)
if (skb == NULL)
{
if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
+ netdev_printk(KERN_DEBUG, dev,
+ "Couldn't allocate a sk_buff of size %d\n",
+ pkt_len);
dev->stats.rx_dropped++;
break;
}
@@ -1481,9 +1480,10 @@ static void ei_receive(struct net_device *dev)
else
{
if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
- dev->name, rx_frame.status, rx_frame.next,
- rx_frame.count);
+ netdev_printk(KERN_DEBUG, dev,
+ "bogus packet: status=%#2x nxpg=%#2x size=%d\n",
+ rx_frame.status, rx_frame.next,
+ rx_frame.count);
dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
@@ -1493,8 +1493,8 @@ static void ei_receive(struct net_device *dev)
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= ei_local->stop_page) {
- printk("%s: next frame inconsistency, %#2x\n", dev->name,
- next_frame);
+ netdev_info(dev, "next frame inconsistency, %#2x\n",
+ next_frame);
next_frame = ei_local->rx_start_page;
}
ei_local->current_page = next_frame;
@@ -1529,7 +1529,7 @@ static void ei_rx_overrun(struct net_device *dev)
outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
+ netdev_printk(KERN_DEBUG, dev, "Receiver overrun\n");
dev->stats.rx_over_errors++;
/*
@@ -1726,7 +1726,7 @@ static void AX88190_init(struct net_device *dev, int startp)
{
outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i));
if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i])
- printk(KERN_ERR "Hw. address read/write mismap %d\n",i);
+ netdev_err(dev, "Hw. address read/write mismap %d\n", i);
}
outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
@@ -1763,8 +1763,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
if (inb_p(e8390_base) & E8390_TRANS)
{
- printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",
- dev->name);
+ netdev_warn(dev, "trigger_send() called with the transmitter busy\n");
return;
}
outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 3c400cfa82ae..f065c35cd4b7 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -52,23 +52,23 @@
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
-#ifdef DEBUG
static void regdump(struct net_device *dev)
{
+#ifdef DEBUG
int ioaddr = dev->base_addr;
int count;
- printk("com20020 register dump:\n");
+ netdev_dbg(dev, "register dump:\n");
for (count = ioaddr; count < ioaddr + 16; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
- printk("%02X ", inb(count));
+ pr_cont("%04X:", count);
+ pr_cont(" %02X", inb(count));
}
- printk("\n");
+ pr_cont("\n");
- printk("buffer0 dump:\n");
+ netdev_dbg(dev, "buffer0 dump:\n");
/* set up the address register */
count = 0;
outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
@@ -77,19 +77,15 @@ static void regdump(struct net_device *dev)
for (count = 0; count < 256+32; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
+ pr_cont("%04X:", count);
/* copy the data */
- printk("%02X ", inb(_MEMDATA));
+ pr_cont(" %02X", inb(_MEMDATA));
}
- printk("\n");
+ pr_cont("\n");
+#endif
}
-#else
-
-static inline void regdump(struct net_device *dev) { }
-
-#endif
/*====================================================================*/
@@ -301,13 +297,13 @@ static int com20020_config(struct pcmcia_device *link)
i = com20020_found(dev, 0); /* calls register_netdev */
if (i != 0) {
- dev_printk(KERN_NOTICE, &link->dev,
- "com20020_cs: com20020_found() failed\n");
+ dev_notice(&link->dev,
+ "com20020_found() failed\n");
goto failed;
}
- dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
- dev->name, dev->base_addr, dev->irq);
+ netdev_dbg(dev, "port %#3lx, irq %d\n",
+ dev->base_addr, dev->irq);
return 0;
failed:
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 98fffb03ecd7..8f26d548d1bb 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -28,6 +28,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "fmvj18x_cs"
#define DRV_VERSION "2.9"
@@ -291,7 +293,7 @@ static int mfc_try_io_port(struct pcmcia_device *link)
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (link->resource[1]->start == 0) {
link->resource[1]->end = 0;
- printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
+ pr_notice("out of resource for serial\n");
}
ret = pcmcia_request_io(link);
if (ret == 0)
@@ -503,7 +505,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
case XXX10304:
/* Read MACID from Buggy CIS */
if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
- printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
+ pr_notice("unable to read hardware net address\n");
goto failed;
}
for (i = 0 ; i < 6; i++) {
@@ -524,15 +526,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
/* print current configuration */
- printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
- dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(dev, "%s, sram %s, port %#3lx, irq %d, hw_addr %pM\n",
+ card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2",
+ dev->base_addr, dev->irq, dev->dev_addr);
return 0;
@@ -606,7 +607,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
lp->base = ioremap(req.Base, req.Size);
if (lp->base == NULL) {
- printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n");
+ netdev_notice(dev, "ioremap failed\n");
return -1;
}
@@ -800,17 +801,16 @@ static void fjn_tx_timeout(struct net_device *dev)
struct local_info_t *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",
- dev->name, htons(inw(ioaddr + TX_STATUS)),
- inb(ioaddr + TX_STATUS) & F_TMT_RDY
- ? "IRQ conflict" : "network cable problem");
- printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "
- "%04x %04x %04x %04x %04x.\n",
- dev->name, htons(inw(ioaddr + 0)),
- htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
- htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
- htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
- htons(inw(ioaddr +14)));
+ netdev_notice(dev, "transmit timed out with status %04x, %s?\n",
+ htons(inw(ioaddr + TX_STATUS)),
+ inb(ioaddr + TX_STATUS) & F_TMT_RDY
+ ? "IRQ conflict" : "network cable problem");
+ netdev_notice(dev, "timeout registers: %04x %04x %04x "
+ "%04x %04x %04x %04x %04x.\n",
+ htons(inw(ioaddr + 0)), htons(inw(ioaddr + 2)),
+ htons(inw(ioaddr + 4)), htons(inw(ioaddr + 6)),
+ htons(inw(ioaddr + 8)), htons(inw(ioaddr + 10)),
+ htons(inw(ioaddr + 12)), htons(inw(ioaddr + 14)));
dev->stats.tx_errors++;
/* ToDo: We should try to restart the adaptor... */
local_irq_disable();
@@ -845,13 +845,13 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
unsigned char *buf = skb->data;
if (length > ETH_FRAME_LEN) {
- printk(KERN_NOTICE "%s: Attempting to send a large packet"
- " (%d bytes).\n", dev->name, length);
+ netdev_notice(dev, "Attempting to send a large packet (%d bytes)\n",
+ length);
return NETDEV_TX_BUSY;
}
- pr_debug("%s: Transmitting a packet of length %lu.\n",
- dev->name, (unsigned long)skb->len);
+ netdev_dbg(dev, "Transmitting a packet of length %lu\n",
+ (unsigned long)skb->len);
dev->stats.tx_bytes += skb->len;
/* Disable both interrupts. */
@@ -904,7 +904,7 @@ static void fjn_reset(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int i;
- pr_debug("fjn_reset(%s) called.\n",dev->name);
+ netdev_dbg(dev, "fjn_reset() called\n");
/* Reset controller */
if( sram_config == 0 )
@@ -988,8 +988,8 @@ static void fjn_rx(struct net_device *dev)
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
u_short status = inw(ioaddr + DATAPORT);
- pr_debug("%s: Rxing packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RX_MODE), status);
+ netdev_dbg(dev, "Rxing packet mode %02x status %04x.\n",
+ inb(ioaddr + RX_MODE), status);
#ifndef final_version
if (status == 0) {
outb(F_SKP_PKT, ioaddr + RX_SKIP);
@@ -1008,16 +1008,16 @@ static void fjn_rx(struct net_device *dev)
struct sk_buff *skb;
if (pkt_len > 1550) {
- printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
- "large packet, size %d.\n", dev->name, pkt_len);
+ netdev_notice(dev, "The FMV-18x claimed a very large packet, size %d\n",
+ pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
dev->stats.rx_errors++;
break;
}
skb = dev_alloc_skb(pkt_len+2);
if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping "
- "packet (len %d).\n", dev->name, pkt_len);
+ netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n",
+ pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
dev->stats.rx_dropped++;
break;
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b0d06a3d962f..dc85282193bf 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -45,6 +45,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
@@ -52,7 +54,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/module.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/trdevice.h>
#include <linux/ibmtr.h>
@@ -107,16 +108,6 @@ typedef struct ibmtr_dev_t {
struct tok_info *ti;
} ibmtr_dev_t;
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "ibmtr_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
ibmtr_dev_t *info = dev_id;
struct net_device *dev = info->dev;
@@ -159,8 +150,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
info->dev = dev;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-
return ibmtr_config(link);
} /* ibmtr_attach */
@@ -285,15 +274,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
i = ibmtr_probe_card(dev);
if (i != 0) {
- printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO
- "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
- dev->name, dev->base_addr, dev->irq,
- (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
- dev->dev_addr);
+ netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
+ dev->base_addr, dev->irq,
+ (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
+ dev->dev_addr);
return 0;
failed:
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 68f2deeb3ade..89cf63bb8c91 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -111,6 +111,8 @@ Log: nmclan_cs.c,v
---------------------------------------------------------------------------- */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "nmclan_cs"
#define DRV_VERSION "0.16"
@@ -563,7 +565,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
/* Wait for reset bit to be cleared automatically after <= 200ns */;
if(++ct > 500)
{
- printk(KERN_ERR "mace: reset failed, card removed ?\n");
+ pr_err("reset failed, card removed?\n");
return -1;
}
udelay(1);
@@ -610,7 +612,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
{
if(++ ct > 500)
{
- printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n");
+ pr_err("ADDRCHG timeout, card removed?\n");
return -1;
}
}
@@ -678,8 +680,8 @@ static int nmclan_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
sig[0], sig[1]);
} else {
- printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
- " be 0x40 0x?9\n", sig[0], sig[1]);
+ pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
+ sig[0], sig[1]);
return -ENODEV;
}
}
@@ -691,20 +693,18 @@ static int nmclan_config(struct pcmcia_device *link)
if (if_port <= 2)
dev->if_port = if_port;
else
- printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if (i != 0) {
- printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
- " hw_addr %pM\n",
- dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
- dev->dev_addr);
+ netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n",
+ dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr);
return 0;
failed:
@@ -798,8 +798,7 @@ static int mace_config(struct net_device *dev, struct ifmap *map)
if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
if (map->port <= 2) {
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n", dev->name,
- if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
} else
return -EINVAL;
}
@@ -878,12 +877,12 @@ static void mace_tx_timeout(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
+ netdev_notice(dev, "transmit timed out -- ");
#if RESET_ON_TIMEOUT
- printk("resetting card\n");
+ pr_cont("resetting card\n");
pcmcia_reset_card(link->socket);
#else /* #if RESET_ON_TIMEOUT */
- printk("NOT resetting card\n");
+ pr_cont("NOT resetting card\n");
#endif /* #if RESET_ON_TIMEOUT */
dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
@@ -965,22 +964,21 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
ioaddr = dev->base_addr;
if (lp->tx_irq_disabled) {
- printk(
- (lp->tx_irq_disabled?
- KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
- "[isr=%02X, imr=%02X]\n":
- KERN_NOTICE "%s: Re-entering the interrupt handler "
- "[isr=%02X, imr=%02X]\n"),
- dev->name,
- inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
- inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)
- );
+ const char *msg;
+ if (lp->tx_irq_disabled)
+ msg = "Interrupt with tx_irq_disabled";
+ else
+ msg = "Re-entering the interrupt handler";
+ netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n",
+ msg,
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IMR));
/* WARNING: MACE_IR has been read! */
return IRQ_NONE;
}
if (!netif_device_present(dev)) {
- pr_debug("%s: interrupt from dead card\n", dev->name);
+ netdev_dbg(dev, "interrupt from dead card\n");
return IRQ_NONE;
}
@@ -1378,8 +1376,8 @@ static void BuildLAF(int *ladrf, int *adr)
printk(KERN_DEBUG " adr =%pM\n", adr);
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
for (i = 0; i < 8; i++)
- printk(KERN_CONT " %02X", ladrf[i]);
- printk(KERN_CONT "\n");
+ pr_cont(" %02X", ladrf[i]);
+ pr_cont("\n");
#endif
} /* BuildLAF */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c3edfe4c2651..e180832c278f 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -28,6 +28,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -35,7 +37,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/log2.h>
#include <linux/etherdevice.h>
@@ -100,7 +101,6 @@ static void pcnet_release(struct pcmcia_device *link);
static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev);
@@ -434,8 +434,6 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link)
dev->dev_addr[i] = j & 0xff;
dev->dev_addr[i+1] = j >> 8;
}
- printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n");
- printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n");
return NULL;
}
@@ -570,15 +568,15 @@ static int pcnet_config(struct pcmcia_device *link)
if ((if_port == 1) || (if_port == 2))
dev->if_port = if_port;
else
- printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
} else {
dev->if_port = 0;
}
if ((link->conf.ConfigBase == 0x03c0) &&
(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");
+ pr_notice("this is an AX88190 card!\n");
+ pr_notice("use axnet_cs instead.\n");
goto failed;
}
@@ -593,8 +591,8 @@ static int pcnet_config(struct pcmcia_device *link)
local_hw_info = get_hwired(link);
if (local_hw_info == NULL) {
- printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
- " address for io base %#3lx\n", dev->base_addr);
+ pr_notice("unable to read hardware net address for io base %#3lx\n",
+ dev->base_addr);
goto failed;
}
@@ -626,9 +624,7 @@ static int pcnet_config(struct pcmcia_device *link)
ei_status.name = "NE2000";
ei_status.word16 = 1;
- ei_status.reset_8390 = &pcnet_reset_8390;
-
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ ei_status.reset_8390 = pcnet_reset_8390;
if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev);
@@ -636,25 +632,25 @@ static int pcnet_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto failed;
}
if (info->flags & (IS_DL10019|IS_DL10022)) {
u_char id = inb(dev->base_addr + 0x1a);
- printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
- dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
+ netdev_info(dev, "NE2000 (DL100%d rev %02x): ",
+ (info->flags & IS_DL10022) ? 22 : 19, id);
if (info->pna_phy)
- printk("PNA, ");
+ pr_cont("PNA, ");
} else {
- printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
+ netdev_info(dev, "NE2000 Compatible: ");
}
- printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
+ pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq);
if (info->flags & USE_SHMEM)
- printk (" mem %#5lx,", dev->mem_start);
+ pr_cont(" mem %#5lx,", dev->mem_start);
if (info->flags & HAS_MISC_REG)
- printk(" %s xcvr,", if_names[dev->if_port]);
- printk(" hw_addr %pM\n", dev->dev_addr);
+ pr_cont(" %s xcvr,", if_names[dev->if_port]);
+ pr_cont(" hw_addr %pM\n", dev->dev_addr);
return 0;
failed:
@@ -928,7 +924,7 @@ static void mii_phy_probe(struct net_device *dev)
phyid = tmp << 16;
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
phyid &= MII_PHYID_REV_MASK;
- pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+ netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid);
if (phyid == AM79C9XX_HOME_PHY) {
info->pna_phy = i;
} else if (phyid != AM79C9XX_ETH_PHY) {
@@ -961,7 +957,7 @@ static int pcnet_open(struct net_device *dev)
info->phy_id = info->eth_phy;
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -1014,8 +1010,8 @@ static void pcnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "pcnet_reset_8390() did not complete.\n");
+
set_misc_reg(dev);
} /* pcnet_reset_8390 */
@@ -1031,8 +1027,7 @@ static int set_config(struct net_device *dev, struct ifmap *map)
else if ((map->port < 1) || (map->port > 2))
return -EINVAL;
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
NS8390_init(dev, 1);
}
return 0;
@@ -1067,7 +1062,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -1087,7 +1082,7 @@ static void ei_watchdog(u_long arg)
if (info->eth_phy) {
info->phy_id = info->eth_phy = 0;
} else {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->flags &= ~HAS_MII;
}
goto reschedule;
@@ -1096,8 +1091,7 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link && (info->flags & IS_DL10022)) {
/* Disable collision detection on full duplex links */
outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
@@ -1108,13 +1102,12 @@ static void ei_watchdog(u_long arg)
if (link) {
if (info->phy_id == info->eth_phy) {
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
+ netdev_info(dev, "autonegotiation complete: "
+ "%sbaseT-%cD selected\n",
((p & 0x0180) ? "100" : "10"),
((p & 0x0140) ? 'F' : 'H'));
else
- printk(KERN_INFO "%s: link partner did not "
- "autonegotiate\n", dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
NS8390_init(dev, 1);
}
@@ -1127,7 +1120,7 @@ static void ei_watchdog(u_long arg)
/* isolate this MII and try flipping to the other one */
mdio_write(mii_addr, info->phy_id, 0, 0x0400);
info->phy_id ^= info->pna_phy ^ info->eth_phy;
- printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name,
+ netdev_info(dev, "switched to %s transceiver\n",
(info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
mdio_write(mii_addr, info->phy_id, 0,
(info->phy_id == info->eth_phy) ? 0x1000 : 0);
@@ -1143,18 +1136,6 @@ reschedule:
/*====================================================================*/
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "pcnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-/*====================================================================*/
-
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
@@ -1187,9 +1168,9 @@ static void dma_get_8390_hdr(struct net_device *dev,
unsigned int nic_base = dev->base_addr;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
+ netdev_notice(dev, "DMAing conflict in dma_block_input."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -1220,11 +1201,11 @@ static void dma_block_input(struct net_device *dev, int count,
char *buf = skb->data;
if ((ei_debug > 4) && (count != 4))
- pr_debug("%s: [bi=%d]\n", dev->name, count+4);
+ netdev_dbg(dev, "[bi=%d]\n", count+4);
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
+ netdev_notice(dev, "DMAing conflict in dma_block_input."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1254,9 +1235,9 @@ static void dma_block_input(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0)
- printk(KERN_NOTICE "%s: RX transfer address mismatch,"
+ netdev_notice(dev, "RX transfer address mismatch,"
"%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
+ ring_offset + xfer_count, addr);
}
#endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
@@ -1277,7 +1258,7 @@ static void dma_block_output(struct net_device *dev, int count,
#ifdef PCMCIA_DEBUG
if (ei_debug > 4)
- printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
+ netdev_dbg(dev, "[bo=%d]\n", count);
#endif
/* Round the count up for word writes. Do we need to do this?
@@ -1286,9 +1267,9 @@ static void dma_block_output(struct net_device *dev, int count,
if (count & 0x01)
count++;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
+ netdev_notice(dev, "DMAing conflict in dma_block_output."
"[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1325,9 +1306,9 @@ static void dma_block_output(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0) {
- printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
+ netdev_notice(dev, "Tx packet transfer address mismatch,"
"%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
+ (start_page << 8) + count, addr);
if (retries++ == 0)
goto retry;
}
@@ -1336,8 +1317,7 @@ static void dma_block_output(struct net_device *dev, int count,
while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
- printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
- dev->name);
+ netdev_notice(dev, "timeout waiting for Tx RDC.\n");
pcnet_reset_8390(dev);
NS8390_init(dev, 1);
break;
@@ -1361,9 +1341,9 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
ei_status.stop_page = stop_pg;
/* set up block i/o functions */
- ei_status.get_8390_hdr = &dma_get_8390_hdr;
- ei_status.block_input = &dma_block_input;
- ei_status.block_output = &dma_block_output;
+ ei_status.get_8390_hdr = dma_get_8390_hdr;
+ ei_status.block_input = dma_block_input;
+ ei_status.block_output = dma_block_output;
return 0;
}
@@ -1509,9 +1489,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
ei_status.stop_page = start_pg + ((req.Size - offset) >> 8);
/* set up block i/o functions */
- ei_status.get_8390_hdr = &shmem_get_8390_hdr;
- ei_status.block_input = &shmem_block_input;
- ei_status.block_output = &shmem_block_output;
+ ei_status.get_8390_hdr = shmem_get_8390_hdr;
+ ei_status.block_input = shmem_block_input;
+ ei_status.block_output = shmem_block_output;
info->flags |= USE_SHMEM;
return 0;
@@ -1637,6 +1617,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b),
PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0),
PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956),
+ PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616),
PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64),
PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5),
PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3),
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 377367d03b41..3d1c549b7038 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -25,6 +25,8 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -294,7 +296,7 @@ static const struct net_device_ops smc_netdev_ops = {
.ndo_tx_timeout = smc_tx_timeout,
.ndo_set_config = s9k_config,
.ndo_set_multicast_list = set_rx_mode,
- .ndo_do_ioctl = &smc_ioctl,
+ .ndo_do_ioctl = smc_ioctl,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -820,7 +822,7 @@ static int check_sig(struct pcmcia_device *link)
modconf_t mod = {
.Attributes = CONF_IO_CHANGE_WIDTH,
};
- printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
+ pr_info("using 8-bit IO window\n");
smc91c92_suspend(link);
pcmcia_modify_configuration(link, &mod);
@@ -881,7 +883,7 @@ static int smc91c92_config(struct pcmcia_device *link)
if ((if_port >= 0) && (if_port <= 2))
dev->if_port = if_port;
else
- printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n");
+ dev_notice(&link->dev, "invalid if_port requested\n");
switch (smc->manfid) {
case MANFID_OSITECH:
@@ -899,7 +901,7 @@ static int smc91c92_config(struct pcmcia_device *link)
}
if (i != 0) {
- printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
+ dev_notice(&link->dev, "Unable to find hardware address.\n");
goto config_failed;
}
@@ -952,30 +954,28 @@ static int smc91c92_config(struct pcmcia_device *link)
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
+ dev_err(&link->dev, "register_netdev() failed\n");
goto config_undo;
}
- printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
- "hw_addr %pM\n",
- dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "smc91c%s rev %d: io %#3lx, irq %d, hw_addr %pM\n",
+ name, (rev & 0x0f), dev->base_addr, dev->irq, dev->dev_addr);
if (rev > 0) {
if (mir & 0x3ff)
- printk(KERN_INFO " %lu byte", mir);
+ netdev_info(dev, " %lu byte", mir);
else
- printk(KERN_INFO " %lu kb", mir>>10);
- printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ?
- "MII" : if_names[dev->if_port]);
+ netdev_info(dev, " %lu kb", mir>>10);
+ pr_cont(" buffer, %s xcvr\n",
+ (smc->cfg & CFG_MII_SELECT) ? "MII" : if_names[dev->if_port]);
}
if (smc->cfg & CFG_MII_SELECT) {
if (smc->mii_if.phy_id != -1) {
- dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n",
- smc->mii_if.phy_id, j);
+ netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
+ smc->mii_if.phy_id, j);
} else {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ netdev_notice(dev, " No MII transceivers found!\n");
}
}
return 0;
@@ -1081,10 +1081,10 @@ static void smc_dump(struct net_device *dev)
save = inw(ioaddr + BANK_SELECT);
for (w = 0; w < 4; w++) {
SMC_SELECT_BANK(w);
- printk(KERN_DEBUG "bank %d: ", w);
+ netdev_printk(KERN_DEBUG, dev, "bank %d: ", w);
for (i = 0; i < 14; i += 2)
- printk(" %04x", inw(ioaddr + i));
- printk("\n");
+ pr_cont(" %04x", inw(ioaddr + i));
+ pr_cont("\n");
}
outw(save, ioaddr + BANK_SELECT);
}
@@ -1106,7 +1106,7 @@ static int smc_open(struct net_device *dev)
return -ENODEV;
/* Physical device present signature. */
if (check_sig(link) < 0) {
- printk("smc91c92_cs: Yikes! Bad chip signature!\n");
+ netdev_info(dev, "Yikes! Bad chip signature!\n");
return -ENODEV;
}
link->open++;
@@ -1117,7 +1117,7 @@ static int smc_open(struct net_device *dev)
smc_reset(dev);
init_timer(&smc->media);
- smc->media.function = &media_check;
+ smc->media.function = media_check;
smc->media.data = (u_long) dev;
smc->media.expires = jiffies + HZ;
add_timer(&smc->media);
@@ -1172,7 +1172,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
u_char packet_no;
if (!skb) {
- printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name);
+ netdev_err(dev, "In XMIT with no packet to send\n");
return;
}
@@ -1180,8 +1180,8 @@ static void smc_hardware_send_packet(struct net_device * dev)
packet_no = inw(ioaddr + PNR_ARR) >> 8;
if (packet_no & 0x80) {
/* If not, there is a hardware problem! Likely an ejected card. */
- printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation"
- " failed, status %#2.2x.\n", dev->name, packet_no);
+ netdev_warn(dev, "hardware Tx buffer allocation failed, status %#2.2x\n",
+ packet_no);
dev_kfree_skb_irq(skb);
smc->saved_skb = NULL;
netif_start_queue(dev);
@@ -1200,8 +1200,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
u_char *buf = skb->data;
u_int length = skb->len; /* The chip will pad to ethernet min. */
- pr_debug("%s: Trying to xmit packet of length %d.\n",
- dev->name, length);
+ netdev_dbg(dev, "Trying to xmit packet of length %d\n", length);
/* send the packet length: +6 for status word, length, and ctl */
outw(0, ioaddr + DATA_1);
@@ -1233,9 +1232,8 @@ static void smc_tx_timeout(struct net_device *dev)
struct smc_private *smc = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
- "Tx_status %2.2x status %4.4x.\n",
- dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
+ netdev_notice(dev, "transmit timed out, Tx_status %2.2x status %4.4x.\n",
+ inw(ioaddr)&0xff, inw(ioaddr + 2));
dev->stats.tx_errors++;
smc_reset(dev);
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -1254,14 +1252,14 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
netif_stop_queue(dev);
- pr_debug("%s: smc_start_xmit(length = %d) called,"
- " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
+ netdev_dbg(dev, "smc_start_xmit(length = %d) called, status %04x\n",
+ skb->len, inw(ioaddr + 2));
if (smc->saved_skb) {
/* THIS SHOULD NEVER HAPPEN. */
dev->stats.tx_aborted_errors++;
- printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
- dev->name);
+ netdev_printk(KERN_DEBUG, dev,
+ "Internal error -- sent packet while busy\n");
return NETDEV_TX_BUSY;
}
smc->saved_skb = skb;
@@ -1269,7 +1267,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
num_pages = skb->len >> 8;
if (num_pages > 7) {
- printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
+ netdev_err(dev, "Far too big packet error: %d pages\n", num_pages);
dev_kfree_skb (skb);
smc->saved_skb = NULL;
dev->stats.tx_dropped++;
@@ -1339,8 +1337,7 @@ static void smc_tx_err(struct net_device * dev)
}
if (tx_status & TS_SUCCESS) {
- printk(KERN_NOTICE "%s: Successful packet caused error "
- "interrupt?\n", dev->name);
+ netdev_notice(dev, "Successful packet caused error interrupt?\n");
}
/* re-enable transmit */
SMC_SELECT_BANK(0);
@@ -1530,8 +1527,7 @@ static void smc_rx(struct net_device *dev)
/* Assertion: we are in Window 2. */
if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) {
- printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n",
- dev->name);
+ netdev_err(dev, "smc_rx() with nothing on Rx FIFO\n");
return;
}
@@ -1646,8 +1642,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map)
else if (map->port > 2)
return -EINVAL;
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
smc_reset(dev);
}
return 0;
@@ -1798,7 +1793,7 @@ static void media_check(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (smc->watchdog++ && ((i>>8) & i)) {
if (!smc->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
local_irq_save(flags);
smc_interrupt(dev->irq, dev);
local_irq_restore(flags);
@@ -1822,7 +1817,7 @@ static void media_check(u_long arg)
SMC_SELECT_BANK(3);
link = mdio_read(dev, smc->mii_if.phy_id, 1);
if (!link || (link == 0xffff)) {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
smc->mii_if.phy_id = -1;
goto reschedule;
}
@@ -1830,15 +1825,13 @@ static void media_check(u_long arg)
link &= 0x0004;
if (link != smc->link_status) {
u_short p = mdio_read(dev, smc->mii_if.phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40))
? TCR_FDUPLX : 0);
if (link) {
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- (smc->duplex ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%dbaseT-%cD selected\n",
+ (p & 0x0180) ? 100 : 10, smc->duplex ? 'F' : 'H');
}
SMC_SELECT_BANK(0);
outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR);
@@ -1857,25 +1850,23 @@ static void media_check(u_long arg)
if (media != smc->media_status) {
if ((media & smc->media_status & 1) &&
((smc->media_status ^ media) & EPH_LINK_OK))
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (smc->media_status & EPH_LINK_OK ? "lost" : "found"));
+ netdev_info(dev, "%s link beat\n",
+ smc->media_status & EPH_LINK_OK ? "lost" : "found");
else if ((media & smc->media_status & 2) &&
((smc->media_status ^ media) & EPH_16COL))
- printk(KERN_INFO "%s: coax cable %s\n", dev->name,
- (media & EPH_16COL ? "problem" : "ok"));
+ netdev_info(dev, "coax cable %s\n",
+ media & EPH_16COL ? "problem" : "ok");
if (dev->if_port == 0) {
if (media & 1) {
if (media & EPH_LINK_OK)
- printk(KERN_INFO "%s: flipped to 10baseT\n",
- dev->name);
+ netdev_info(dev, "flipped to 10baseT\n");
else
smc_set_xcvr(dev, 2);
} else {
if (media & EPH_16COL)
smc_set_xcvr(dev, 1);
else
- printk(KERN_INFO "%s: flipped to 10base2\n",
- dev->name);
+ netdev_info(dev, "flipped to 10base2\n");
}
}
smc->media_status = media;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f5819526b5ee..d858b5e4c4a7 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -63,6 +63,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -210,13 +212,6 @@ enum xirc_cmd { /* Commands */
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
-
-#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
-#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
-#define KWRN_XIRC KERN_WARNING "xirc2ps_cs: "
-#define KNOT_XIRC KERN_NOTICE "xirc2ps_cs: "
-#define KINF_XIRC KERN_INFO "xirc2ps_cs: "
-
/* card types */
#define XIR_UNKNOWN 0 /* unknown: not supported */
#define XIR_CE 1 /* (prodid 1) different hardware: not supported */
@@ -350,26 +345,26 @@ PrintRegisters(struct net_device *dev)
if (pc_debug > 1) {
int i, page;
- printk(KDBG_XIRC "Register common: ");
+ printk(KERN_DEBUG pr_fmt("Register common: "));
for (i = 0; i < 8; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
for (page = 0; page <= 8; page++) {
- printk(KDBG_XIRC "Register page %2x: ", page);
+ printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
SelectPage(page);
for (i = 8; i < 16; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
}
for (page=0x40 ; page <= 0x5f; page++) {
if (page == 0x43 || (page >= 0x46 && page <= 0x4f) ||
(page >= 0x51 && page <=0x5e))
continue;
- printk(KDBG_XIRC "Register page %2x: ", page);
+ printk(KERN_DEBUG pr_fmt("Register page %2x: "), page);
SelectPage(page);
for (i = 8; i < 16; i++)
- printk(" %2.2x", GetByte(i));
- printk("\n");
+ pr_cont(" %2.2x", GetByte(i));
+ pr_cont("\n");
}
}
}
@@ -608,11 +603,11 @@ set_card_type(struct pcmcia_device *link)
local->modem = 0;
local->card_type = XIR_UNKNOWN;
if (!(prodid & 0x40)) {
- printk(KNOT_XIRC "Ooops: Not a creditcard\n");
+ pr_notice("Oops: Not a creditcard\n");
return 0;
}
if (!(mediaid & 0x01)) {
- printk(KNOT_XIRC "Not an Ethernet card\n");
+ pr_notice("Not an Ethernet card\n");
return 0;
}
if (mediaid & 0x10) {
@@ -643,12 +638,11 @@ set_card_type(struct pcmcia_device *link)
}
}
if (local->card_type == XIR_CE || local->card_type == XIR_CEM) {
- printk(KNOT_XIRC "Sorry, this is an old CE card\n");
+ pr_notice("Sorry, this is an old CE card\n");
return 0;
}
if (local->card_type == XIR_UNKNOWN)
- printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n",
- mediaid, prodid);
+ pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid);
return 1;
}
@@ -748,7 +742,7 @@ xirc2ps_config(struct pcmcia_device * link)
/* Is this a valid card */
if (link->has_manf_id == 0) {
- printk(KNOT_XIRC "manfid not found in CIS\n");
+ pr_notice("manfid not found in CIS\n");
goto failure;
}
@@ -770,14 +764,14 @@ xirc2ps_config(struct pcmcia_device * link)
local->manf_str = "Toshiba";
break;
default:
- printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
- (unsigned)link->manf_id);
+ pr_notice("Unknown Card Manufacturer ID: 0x%04x\n",
+ (unsigned)link->manf_id);
goto failure;
}
dev_dbg(&link->dev, "found %s card\n", local->manf_str);
if (!set_card_type(link)) {
- printk(KNOT_XIRC "this card is not supported\n");
+ pr_notice("this card is not supported\n");
goto failure;
}
@@ -803,7 +797,7 @@ xirc2ps_config(struct pcmcia_device * link)
err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
if (err) {
- printk(KNOT_XIRC "node-id not found in CIS\n");
+ pr_notice("node-id not found in CIS\n");
goto failure;
}
@@ -838,7 +832,7 @@ xirc2ps_config(struct pcmcia_device * link)
* try to configure as Ethernet only.
* .... */
}
- printk(KNOT_XIRC "no ports available\n");
+ pr_notice("no ports available\n");
} else {
link->resource[0]->end = 16;
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
@@ -911,24 +905,24 @@ xirc2ps_config(struct pcmcia_device * link)
#if 0
{
u_char tmp;
- printk(KERN_INFO "ECOR:");
+ pr_info("ECOR:");
for (i=0; i < 7; i++) {
tmp = readb(local->dingo_ccr + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
- printk(KERN_INFO "DCOR:");
+ pr_cont("\n");
+ pr_info("DCOR:");
for (i=0; i < 4; i++) {
tmp = readb(local->dingo_ccr + 0x20 + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
- printk(KERN_INFO "SCOR:");
+ pr_cont("\n");
+ pr_info("SCOR:");
for (i=0; i < 10; i++) {
tmp = readb(local->dingo_ccr + 0x40 + i*2);
- printk(" %02x", tmp);
+ pr_cont(" %02x", tmp);
}
- printk("\n");
+ pr_cont("\n");
}
#endif
@@ -947,7 +941,7 @@ xirc2ps_config(struct pcmcia_device * link)
(local->mohawk && if_port==4))
dev->if_port = if_port;
else
- printk(KNOT_XIRC "invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
/* we can now register the device with the net subsystem */
dev->irq = link->irq;
@@ -959,14 +953,14 @@ xirc2ps_config(struct pcmcia_device * link)
SET_NETDEV_DEV(dev, &link->dev);
if ((err=register_netdev(dev))) {
- printk(KNOT_XIRC "register_netdev() failed\n");
+ pr_notice("register_netdev() failed\n");
goto config_error;
}
/* give some infos about the hardware */
- printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n",
- dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq,
- dev->dev_addr);
+ netdev_info(dev, "%s: port %#3lx, irq %d, hwaddr %pM\n",
+ local->manf_str, (u_long)dev->base_addr, (int)dev->irq,
+ dev->dev_addr);
return 0;
@@ -1098,8 +1092,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
if (!skb) {
- printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
- pktlen);
+ pr_notice("low memory, packet dropped (size=%u)\n", pktlen);
dev->stats.rx_dropped++;
} else { /* okay get the packet */
skb_reserve(skb, 2);
@@ -1268,7 +1261,7 @@ xirc_tx_timeout(struct net_device *dev)
{
local_info_t *lp = netdev_priv(dev);
dev->stats.tx_errors++;
- printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
+ netdev_notice(dev, "transmit timed out\n");
schedule_work(&lp->tx_timeout_task);
}
@@ -1435,8 +1428,7 @@ do_config(struct net_device *dev, struct ifmap *map)
local->probe_port = 0;
dev->if_port = map->port;
}
- printk(KERN_INFO "%s: switching to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switching to %s port\n", if_names[dev->if_port]);
do_reset(dev,1); /* not the fine way :-) */
}
return 0;
@@ -1576,7 +1568,7 @@ do_reset(struct net_device *dev, int full)
{
SelectPage(0);
value = GetByte(XIRCREG_ESR); /* read the ESR */
- printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
+ pr_debug("%s: ESR is: %#02x\n", dev->name, value);
}
#endif
@@ -1626,13 +1618,12 @@ do_reset(struct net_device *dev, int full)
if (full && local->mohawk && init_mii(dev)) {
if (dev->if_port == 4 || local->dingo || local->new_mii) {
- printk(KERN_INFO "%s: MII selected\n", dev->name);
+ netdev_info(dev, "MII selected\n");
SelectPage(2);
PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);
msleep(20);
} else {
- printk(KERN_INFO "%s: MII detected; using 10mbs\n",
- dev->name);
+ netdev_info(dev, "MII detected; using 10mbs\n");
SelectPage(0x42);
if (dev->if_port == 2) /* enable 10Base2 */
PutByte(XIRCREG42_SWC1, 0xC0);
@@ -1677,8 +1668,8 @@ do_reset(struct net_device *dev, int full)
}
if (full)
- printk(KERN_INFO "%s: media %s, silicon revision %d\n",
- dev->name, if_names[dev->if_port], local->silicon);
+ netdev_info(dev, "media %s, silicon revision %d\n",
+ if_names[dev->if_port], local->silicon);
/* We should switch back to page 0 to avoid a bug in revision 0
* where regs with offset below 8 can't be read after an access
* to the MAC registers */
@@ -1720,8 +1711,7 @@ init_mii(struct net_device *dev)
control = mii_rd(ioaddr, 0, 0);
if (control & 0x0400) {
- printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n",
- dev->name);
+ netdev_notice(dev, "can't take PHY out of isolation mode\n");
local->probe_port = 0;
return 0;
}
@@ -1739,8 +1729,7 @@ init_mii(struct net_device *dev)
}
if (!(status & 0x0020)) {
- printk(KERN_INFO "%s: autonegotiation failed;"
- " using 10mbs\n", dev->name);
+ netdev_info(dev, "autonegotiation failed; using 10mbs\n");
if (!local->new_mii) {
control = 0x0000;
mii_wr(ioaddr, 0, 0, control, 16);
@@ -1750,8 +1739,7 @@ init_mii(struct net_device *dev)
}
} else {
linkpartner = mii_rd(ioaddr, 0, 5);
- printk(KERN_INFO "%s: MII link partner: %04x\n",
- dev->name, linkpartner);
+ netdev_info(dev, "MII link partner: %04x\n", linkpartner);
if (linkpartner & 0x0080) {
dev->if_port = 4;
} else
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6a6b8199a0d6..6c58da2b882c 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -308,7 +308,7 @@ static int mdio_bus_suspend(struct device *dev)
* may call phy routines that try to grab the same lock, and that may
* lead to a deadlock.
*/
- if (phydev->attached_dev)
+ if (phydev->attached_dev && phydev->adjust_link)
phy_stop_machine(phydev);
if (!mdio_bus_phy_may_suspend(phydev))
@@ -331,7 +331,7 @@ static int mdio_bus_resume(struct device *dev)
return ret;
no_resume:
- if (phydev->attached_dev)
+ if (phydev->attached_dev && phydev->adjust_link)
phy_start_machine(phydev, NULL);
return 0;
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index ec0349e84a8a..7e82a82422cf 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -1279,7 +1279,6 @@ static void plip_attach (struct parport *port)
if (!nl->pardev) {
printk(KERN_ERR "%s: parport_register failed\n", name);
goto err_free_dev;
- return;
}
plip_init_netdev(dev);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 6695a51e09e9..837aadc3b6aa 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -856,7 +856,8 @@ static const struct file_operations ppp_device_fops = {
.poll = ppp_poll,
.unlocked_ioctl = ppp_ioctl,
.open = ppp_open,
- .release = ppp_release
+ .release = ppp_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static __net_init int ppp_init_net(struct net *net)
@@ -1314,8 +1315,13 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
i = 0;
list_for_each_entry(pch, &ppp->channels, clist) {
- navail += pch->avail = (pch->chan != NULL);
- pch->speed = pch->chan->speed;
+ if (pch->chan) {
+ pch->avail = 1;
+ navail++;
+ pch->speed = pch->chan->speed;
+ } else {
+ pch->avail = 0;
+ }
if (pch->avail) {
if (skb_queue_empty(&pch->file.xq) ||
!pch->had_frag) {
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
new file mode 100644
index 000000000000..761f0eced724
--- /dev/null
+++ b/drivers/net/pptp.c
@@ -0,0 +1,726 @@
+/*
+ * Point-to-Point Tunneling Protocol for Linux
+ *
+ * Authors: Dmitry Kozlov <xeb@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/ppp_channel.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_pppox.h>
+#include <linux/if_ppp.h>
+#include <linux/notifier.h>
+#include <linux/file.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/version.h>
+#include <linux/rcupdate.h>
+#include <linux/spinlock.h>
+
+#include <net/sock.h>
+#include <net/protocol.h>
+#include <net/ip.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <net/gre.h>
+
+#include <linux/uaccess.h>
+
+#define PPTP_DRIVER_VERSION "0.8.5"
+
+#define MAX_CALLID 65535
+
+static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1);
+static struct pppox_sock **callid_sock;
+
+static DEFINE_SPINLOCK(chan_lock);
+
+static struct proto pptp_sk_proto __read_mostly;
+static struct ppp_channel_ops pptp_chan_ops;
+static const struct proto_ops pptp_ops;
+
+#define PPP_LCP_ECHOREQ 0x09
+#define PPP_LCP_ECHOREP 0x0A
+#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
+
+#define MISSING_WINDOW 20
+#define WRAPPED(curseq, lastseq)\
+ ((((curseq) & 0xffffff00) == 0) &&\
+ (((lastseq) & 0xffffff00) == 0xffffff00))
+
+#define PPTP_GRE_PROTO 0x880B
+#define PPTP_GRE_VER 0x1
+
+#define PPTP_GRE_FLAG_C 0x80
+#define PPTP_GRE_FLAG_R 0x40
+#define PPTP_GRE_FLAG_K 0x20
+#define PPTP_GRE_FLAG_S 0x10
+#define PPTP_GRE_FLAG_A 0x80
+
+#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C)
+#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R)
+#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K)
+#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S)
+#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A)
+
+#define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header))
+struct pptp_gre_header {
+ u8 flags;
+ u8 ver;
+ u16 protocol;
+ u16 payload_len;
+ u16 call_id;
+ u32 seq;
+ u32 ack;
+} __packed;
+
+static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+
+ rcu_read_lock();
+ sock = rcu_dereference(callid_sock[call_id]);
+ if (sock) {
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.sin_addr.s_addr != s_addr)
+ sock = NULL;
+ else
+ sock_hold(sk_pppox(sock));
+ }
+ rcu_read_unlock();
+
+ return sock;
+}
+
+static int lookup_chan_dst(u16 call_id, __be32 d_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+ int i;
+
+ rcu_read_lock();
+ for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID;
+ i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) {
+ sock = rcu_dereference(callid_sock[i]);
+ if (!sock)
+ continue;
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.call_id == call_id &&
+ opt->dst_addr.sin_addr.s_addr == d_addr)
+ break;
+ }
+ rcu_read_unlock();
+
+ return i < MAX_CALLID;
+}
+
+static int add_chan(struct pppox_sock *sock)
+{
+ static int call_id;
+
+ spin_lock(&chan_lock);
+ if (!sock->proto.pptp.src_addr.call_id) {
+ call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1);
+ if (call_id == MAX_CALLID) {
+ call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1);
+ if (call_id == MAX_CALLID)
+ goto out_err;
+ }
+ sock->proto.pptp.src_addr.call_id = call_id;
+ } else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap))
+ goto out_err;
+
+ set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock);
+ spin_unlock(&chan_lock);
+
+ return 0;
+
+out_err:
+ spin_unlock(&chan_lock);
+ return -1;
+}
+
+static void del_chan(struct pppox_sock *sock)
+{
+ spin_lock(&chan_lock);
+ clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL);
+ spin_unlock(&chan_lock);
+ synchronize_rcu();
+}
+
+static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct pptp_gre_header *hdr;
+ unsigned int header_len = sizeof(*hdr);
+ int err = 0;
+ int islcp;
+ int len;
+ unsigned char *data;
+ __u32 seq_recv;
+
+
+ struct rtable *rt;
+ struct net_device *tdev;
+ struct iphdr *iph;
+ int max_headroom;
+
+ if (sk_pppox(po)->sk_state & PPPOX_DEAD)
+ goto tx_error;
+
+ {
+ struct flowi fl = { .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_TOS(0) } },
+ .proto = IPPROTO_GRE };
+ err = ip_route_output_key(&init_net, &rt, &fl);
+ if (err)
+ goto tx_error;
+ }
+ tdev = rt->dst.dev;
+
+ max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2;
+
+ if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb) {
+ ip_rt_put(rt);
+ goto tx_error;
+ }
+ if (skb->sk)
+ skb_set_owner_w(new_skb, skb->sk);
+ kfree_skb(skb);
+ skb = new_skb;
+ }
+
+ data = skb->data;
+ islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7;
+
+ /* compress protocol field */
+ if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp)
+ skb_pull(skb, 1);
+
+ /* Put in the address/control bytes if necessary */
+ if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) {
+ data = skb_push(skb, 2);
+ data[0] = PPP_ALLSTATIONS;
+ data[1] = PPP_UI;
+ }
+
+ len = skb->len;
+
+ seq_recv = opt->seq_recv;
+
+ if (opt->ack_sent == seq_recv)
+ header_len -= sizeof(hdr->ack);
+
+ /* Push down and install GRE header */
+ skb_push(skb, header_len);
+ hdr = (struct pptp_gre_header *)(skb->data);
+
+ hdr->flags = PPTP_GRE_FLAG_K;
+ hdr->ver = PPTP_GRE_VER;
+ hdr->protocol = htons(PPTP_GRE_PROTO);
+ hdr->call_id = htons(opt->dst_addr.call_id);
+
+ hdr->flags |= PPTP_GRE_FLAG_S;
+ hdr->seq = htonl(++opt->seq_sent);
+ if (opt->ack_sent != seq_recv) {
+ /* send ack with this message */
+ hdr->ver |= PPTP_GRE_FLAG_A;
+ hdr->ack = htonl(seq_recv);
+ opt->ack_sent = seq_recv;
+ }
+ hdr->payload_len = htons(len);
+
+ /* Push down and install the IP header. */
+
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph));
+ skb_reset_network_header(skb);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
+
+ iph = ip_hdr(skb);
+ iph->version = 4;
+ iph->ihl = sizeof(struct iphdr) >> 2;
+ if (ip_dont_fragment(sk, &rt->dst))
+ iph->frag_off = htons(IP_DF);
+ else
+ iph->frag_off = 0;
+ iph->protocol = IPPROTO_GRE;
+ iph->tos = 0;
+ iph->daddr = rt->rt_dst;
+ iph->saddr = rt->rt_src;
+ iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT);
+ iph->tot_len = htons(skb->len);
+
+ skb_dst_drop(skb);
+ skb_dst_set(skb, &rt->dst);
+
+ nf_reset(skb);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ ip_select_ident(iph, &rt->dst, NULL);
+ ip_send_check(iph);
+
+ ip_local_out(skb);
+
+tx_error:
+ return 1;
+}
+
+static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
+{
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int headersize, payload_len, seq;
+ __u8 *payload;
+ struct pptp_gre_header *header;
+
+ if (!(sk->sk_state & PPPOX_CONNECTED)) {
+ if (sock_queue_rcv_skb(sk, skb))
+ goto drop;
+ return NET_RX_SUCCESS;
+ }
+
+ header = (struct pptp_gre_header *)(skb->data);
+
+ /* test if acknowledgement present */
+ if (PPTP_GRE_IS_A(header->ver)) {
+ __u32 ack = (PPTP_GRE_IS_S(header->flags)) ?
+ header->ack : header->seq; /* ack in different place if S = 0 */
+
+ ack = ntohl(ack);
+
+ if (ack > opt->ack_recv)
+ opt->ack_recv = ack;
+ /* also handle sequence number wrap-around */
+ if (WRAPPED(ack, opt->ack_recv))
+ opt->ack_recv = ack;
+ }
+
+ /* test if payload present */
+ if (!PPTP_GRE_IS_S(header->flags))
+ goto drop;
+
+ headersize = sizeof(*header);
+ payload_len = ntohs(header->payload_len);
+ seq = ntohl(header->seq);
+
+ /* no ack present? */
+ if (!PPTP_GRE_IS_A(header->ver))
+ headersize -= sizeof(header->ack);
+ /* check for incomplete packet (length smaller than expected) */
+ if (skb->len - headersize < payload_len)
+ goto drop;
+
+ payload = skb->data + headersize;
+ /* check for expected sequence number */
+ if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) {
+ if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) &&
+ (PPP_PROTOCOL(payload) == PPP_LCP) &&
+ ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP)))
+ goto allow_packet;
+ } else {
+ opt->seq_recv = seq;
+allow_packet:
+ skb_pull(skb, headersize);
+
+ if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) {
+ /* chop off address/control */
+ if (skb->len < 3)
+ goto drop;
+ skb_pull(skb, 2);
+ }
+
+ if ((*skb->data) & 1) {
+ /* protocol is compressed */
+ skb_push(skb, 1)[0] = 0;
+ }
+
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_set_network_header(skb, skb->head-skb->data);
+ ppp_input(&po->chan, skb);
+
+ return NET_RX_SUCCESS;
+ }
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_rcv(struct sk_buff *skb)
+{
+ struct pppox_sock *po;
+ struct pptp_gre_header *header;
+ struct iphdr *iph;
+
+ if (skb->pkt_type != PACKET_HOST)
+ goto drop;
+
+ if (!pskb_may_pull(skb, 12))
+ goto drop;
+
+ iph = ip_hdr(skb);
+
+ header = (struct pptp_gre_header *)skb->data;
+
+ if (ntohs(header->protocol) != PPTP_GRE_PROTO || /* PPTP-GRE protocol for PPTP */
+ PPTP_GRE_IS_C(header->flags) || /* flag C should be clear */
+ PPTP_GRE_IS_R(header->flags) || /* flag R should be clear */
+ !PPTP_GRE_IS_K(header->flags) || /* flag K should be set */
+ (header->flags&0xF) != 0) /* routing and recursion ctrl = 0 */
+ /* if invalid, discard this packet */
+ goto drop;
+
+ po = lookup_chan(htons(header->call_id), iph->saddr);
+ if (po) {
+ skb_dst_drop(skb);
+ nf_reset(skb);
+ return sk_receive_skb(sk_pppox(po), skb, 0);
+ }
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
+ int sockaddr_len)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int error = 0;
+
+ lock_sock(sk);
+
+ opt->src_addr = sp->sa_addr.pptp;
+ if (add_chan(po)) {
+ release_sock(sk);
+ error = -EBUSY;
+ }
+
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ int sockaddr_len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct rtable *rt;
+ int error = 0;
+
+ if (sp->sa_protocol != PX_PROTO_PPTP)
+ return -EINVAL;
+
+ if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr))
+ return -EALREADY;
+
+ lock_sock(sk);
+ /* Check for already bound sockets */
+ if (sk->sk_state & PPPOX_CONNECTED) {
+ error = -EBUSY;
+ goto end;
+ }
+
+ /* Check for already disconnected sockets, on attempts to disconnect */
+ if (sk->sk_state & PPPOX_DEAD) {
+ error = -EALREADY;
+ goto end;
+ }
+
+ if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr) {
+ error = -EINVAL;
+ goto end;
+ }
+
+ po->chan.private = sk;
+ po->chan.ops = &pptp_chan_ops;
+
+ {
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_CONN_FLAGS(sk) } },
+ .proto = IPPROTO_GRE };
+ security_sk_classify_flow(sk, &fl);
+ if (ip_route_output_key(&init_net, &rt, &fl)) {
+ error = -EHOSTUNREACH;
+ goto end;
+ }
+ sk_setup_caps(sk, &rt->dst);
+ }
+ po->chan.mtu = dst_mtu(&rt->dst);
+ if (!po->chan.mtu)
+ po->chan.mtu = PPP_MTU;
+ ip_rt_put(rt);
+ po->chan.mtu -= PPTP_HEADER_OVERHEAD;
+
+ po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
+ error = ppp_register_channel(&po->chan);
+ if (error) {
+ pr_err("PPTP: failed to register PPP channel (%d)\n", error);
+ goto end;
+ }
+
+ opt->dst_addr = sp->sa_addr.pptp;
+ sk->sk_state = PPPOX_CONNECTED;
+
+ end:
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
+ int *usockaddr_len, int peer)
+{
+ int len = sizeof(struct sockaddr_pppox);
+ struct sockaddr_pppox sp;
+
+ sp.sa_family = AF_PPPOX;
+ sp.sa_protocol = PX_PROTO_PPTP;
+ sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
+
+ memcpy(uaddr, &sp, len);
+
+ *usockaddr_len = len;
+
+ return 0;
+}
+
+static int pptp_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+ int error = 0;
+
+ if (!sk)
+ return 0;
+
+ lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD)) {
+ release_sock(sk);
+ return -EBADF;
+ }
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+ del_chan(po);
+
+ pppox_unbind_sock(sk);
+ sk->sk_state = PPPOX_DEAD;
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+
+ release_sock(sk);
+ sock_put(sk);
+
+ return error;
+}
+
+static void pptp_sock_destruct(struct sock *sk)
+{
+ if (!(sk->sk_state & PPPOX_DEAD)) {
+ del_chan(pppox_sk(sk));
+ pppox_unbind_sock(sk);
+ }
+ skb_queue_purge(&sk->sk_receive_queue);
+}
+
+static int pptp_create(struct net *net, struct socket *sock)
+{
+ int error = -ENOMEM;
+ struct sock *sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+
+ sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto);
+ if (!sk)
+ goto out;
+
+ sock_init_data(sock, sk);
+
+ sock->state = SS_UNCONNECTED;
+ sock->ops = &pptp_ops;
+
+ sk->sk_backlog_rcv = pptp_rcv_core;
+ sk->sk_state = PPPOX_NONE;
+ sk->sk_type = SOCK_STREAM;
+ sk->sk_family = PF_PPPOX;
+ sk->sk_protocol = PX_PROTO_PPTP;
+ sk->sk_destruct = pptp_sock_destruct;
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+
+ opt->seq_sent = 0; opt->seq_recv = 0;
+ opt->ack_recv = 0; opt->ack_sent = 0;
+
+ error = 0;
+out:
+ return error;
+}
+
+static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int err, val;
+
+ err = -EFAULT;
+ switch (cmd) {
+ case PPPIOCGFLAGS:
+ val = opt->ppp_flags;
+ if (put_user(val, p))
+ break;
+ err = 0;
+ break;
+ case PPPIOCSFLAGS:
+ if (get_user(val, p))
+ break;
+ opt->ppp_flags = val & ~SC_RCV_BITS;
+ err = 0;
+ break;
+ default:
+ err = -ENOTTY;
+ }
+
+ return err;
+}
+
+static struct ppp_channel_ops pptp_chan_ops = {
+ .start_xmit = pptp_xmit,
+ .ioctl = pptp_ppp_ioctl,
+};
+
+static struct proto pptp_sk_proto __read_mostly = {
+ .name = "PPTP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pppox_sock),
+};
+
+static const struct proto_ops pptp_ops = {
+ .family = AF_PPPOX,
+ .owner = THIS_MODULE,
+ .release = pptp_release,
+ .bind = pptp_bind,
+ .connect = pptp_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pptp_getname,
+ .poll = sock_no_poll,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .mmap = sock_no_mmap,
+ .ioctl = pppox_ioctl,
+};
+
+static struct pppox_proto pppox_pptp_proto = {
+ .create = pptp_create,
+ .owner = THIS_MODULE,
+};
+
+static struct gre_protocol gre_pptp_protocol = {
+ .handler = pptp_rcv,
+};
+
+static int __init pptp_init_module(void)
+{
+ int err = 0;
+ pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n");
+
+ callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *),
+ GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+ if (!callid_sock) {
+ pr_err("PPTP: cann't allocate memory\n");
+ return -ENOMEM;
+ }
+
+ err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ if (err) {
+ pr_err("PPTP: can't add gre protocol\n");
+ goto out_mem_free;
+ }
+
+ err = proto_register(&pptp_sk_proto, 0);
+ if (err) {
+ pr_err("PPTP: can't register sk_proto\n");
+ goto out_gre_del_protocol;
+ }
+
+ err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto);
+ if (err) {
+ pr_err("PPTP: can't register pppox_proto\n");
+ goto out_unregister_sk_proto;
+ }
+
+ return 0;
+
+out_unregister_sk_proto:
+ proto_unregister(&pptp_sk_proto);
+out_gre_del_protocol:
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+out_mem_free:
+ vfree(callid_sock);
+
+ return err;
+}
+
+static void __exit pptp_exit_module(void)
+{
+ unregister_pppox_proto(PX_PROTO_PPTP);
+ proto_unregister(&pptp_sk_proto);
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ vfree(callid_sock);
+}
+
+module_init(pptp_init_module);
+module_exit(pptp_exit_module);
+
+MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol");
+MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 87d6b8f36304..5ecfa4b1e758 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -642,7 +642,7 @@ static inline void gelic_card_disable_rxdmac(struct gelic_card *card)
status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
if (status)
dev_err(ctodev(card),
- "lv1_net_stop_rx_dma faild, %d\n", status);
+ "lv1_net_stop_rx_dma failed, %d\n", status);
}
/**
@@ -660,7 +660,7 @@ static inline void gelic_card_disable_txdmac(struct gelic_card *card)
status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
if (status)
dev_err(ctodev(card),
- "lv1_net_stop_tx_dma faild, status=%d\n", status);
+ "lv1_net_stop_tx_dma failed, status=%d\n", status);
}
/**
@@ -956,9 +956,9 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
(!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* update netdevice statistics */
netdev->stats.rx_packets++;
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index 410ea0a61371..75c2ff99d66d 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -42,8 +42,6 @@
#include <linux/types.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <linux/pxa168_eth.h>
@@ -850,7 +848,6 @@ static int rxq_process(struct net_device *dev, int budget)
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
}
- dev->last_rx = jiffies;
}
/* Fill RX ring with skb's */
rxq_refill(dev);
@@ -1606,6 +1603,8 @@ static int pxa168_eth_remove(struct platform_device *pdev)
iounmap(pep->base);
pep->base = NULL;
+ mdiobus_unregister(pep->smi_bus);
+ mdiobus_free(pep->smi_bus);
unregister_netdev(dev);
flush_scheduled_work();
free_netdev(dev);
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 6168a130f33f..7496ed2c34ab 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2029,7 +2029,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev,
dma_unmap_len(lrg_buf_cb2, maplen),
PCI_DMA_FROMDEVICE);
prefetch(skb->data);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, qdev->ndev);
netif_receive_skb(skb);
@@ -2076,7 +2076,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
PCI_DMA_FROMDEVICE);
prefetch(skb2->data);
- skb2->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb2);
if (qdev->device_id == QL3022_DEVICE_ID) {
/*
* Copy the ethhdr from first buffer to second. This
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 970389331bbc..cc8385a6727e 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -51,9 +51,11 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 7
-#define QLCNIC_LINUX_VERSIONID "5.0.7"
+#define _QLCNIC_LINUX_SUBVERSION 9
+#define QLCNIC_LINUX_VERSIONID "5.0.9"
#define QLCNIC_DRV_IDC_VER 0x01
+#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
+ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
#define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -148,6 +150,7 @@
#define DEFAULT_RCV_DESCRIPTORS_1G 2048
#define DEFAULT_RCV_DESCRIPTORS_10G 4096
+#define MAX_RDS_RINGS 2
#define get_next_index(index, length) \
(((index) + 1) & ((length) - 1))
@@ -172,7 +175,7 @@
((_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0))
#define qlcnic_set_tx_flags_opcode(_desc, _flags, _opcode) \
- ((_desc)->flags_opcode = \
+ ((_desc)->flags_opcode |= \
cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)))
#define qlcnic_set_tx_frags_len(_desc, _frags, _len) \
@@ -221,7 +224,8 @@ struct rcv_desc {
#define QLCNIC_LRO_DESC 0x12
/* for status field in status_desc */
-#define STATUS_CKSUM_OK (2)
+#define STATUS_CKSUM_LOOP 0
+#define STATUS_CKSUM_OK 2
/* owner bits of status_desc */
#define STATUS_OWNER_HOST (0x1ULL << 56)
@@ -555,6 +559,8 @@ struct qlcnic_recv_context {
#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026
#define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027
#define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028
+#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029
+#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a
#define QLCNIC_RCODE_SUCCESS 0
#define QLCNIC_RCODE_TIMEOUT 17
@@ -717,6 +723,8 @@ struct qlcnic_cardrsp_tx_ctx {
#define QLCNIC_MAC_NOOP 0
#define QLCNIC_MAC_ADD 1
#define QLCNIC_MAC_DEL 2
+#define QLCNIC_MAC_VLAN_ADD 3
+#define QLCNIC_MAC_VLAN_DEL 4
struct qlcnic_mac_list_s {
struct list_head list;
@@ -893,9 +901,14 @@ struct qlcnic_mac_req {
#define QLCNIC_MSI_ENABLED 0x02
#define QLCNIC_MSIX_ENABLED 0x04
#define QLCNIC_LRO_ENABLED 0x08
+#define QLCNIC_LRO_DISABLED 0x00
#define QLCNIC_BRIDGE_ENABLED 0X10
#define QLCNIC_DIAG_ENABLED 0x20
#define QLCNIC_ESWITCH_ENABLED 0x40
+#define QLCNIC_ADAPTER_INITIALIZED 0x80
+#define QLCNIC_TAGGING_ENABLED 0x100
+#define QLCNIC_MACSPOOF 0x200
+#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
@@ -916,6 +929,22 @@ struct qlcnic_mac_req {
#define QLCNIC_INTERRUPT_TEST 1
#define QLCNIC_LOOPBACK_TEST 2
+#define QLCNIC_FILTER_AGE 80
+#define QLCNIC_LB_MAX_FILTERS 64
+
+struct qlcnic_filter {
+ struct hlist_node fnode;
+ u8 faddr[ETH_ALEN];
+ u16 vlan_id;
+ unsigned long ftime;
+};
+
+struct qlcnic_filter_hash {
+ struct hlist_head *fhead;
+ u8 fnum;
+ u8 fmax;
+};
+
struct qlcnic_adapter {
struct qlcnic_hardware_context ahw;
@@ -924,6 +953,7 @@ struct qlcnic_adapter {
struct list_head mac_list;
spinlock_t tx_clean_lock;
+ spinlock_t mac_learn_lock;
u16 num_txd;
u16 num_rxd;
@@ -931,7 +961,6 @@ struct qlcnic_adapter {
u8 max_rds_rings;
u8 max_sds_rings;
- u8 driver_mismatch;
u8 msix_supported;
u8 rx_csum;
u8 portnum;
@@ -961,6 +990,7 @@ struct qlcnic_adapter {
u16 max_tx_ques;
u16 max_rx_ques;
u16 max_mtu;
+ u16 pvid;
u32 fw_hal_version;
u32 capabilities;
@@ -969,7 +999,7 @@ struct qlcnic_adapter {
u32 temp;
u32 int_vec_bit;
- u32 heartbit;
+ u32 heartbeat;
u8 max_mac_filters;
u8 dev_state;
@@ -1003,6 +1033,8 @@ struct qlcnic_adapter {
struct qlcnic_nic_intr_coalesce coal;
+ struct qlcnic_filter_hash fhash;
+
unsigned long state;
__le32 file_prd_off; /*File fw product offset*/
u32 fw_version;
@@ -1042,7 +1074,7 @@ struct qlcnic_pci_info {
};
struct qlcnic_npar_info {
- u16 vlan_id;
+ u16 pvid;
u16 min_bw;
u16 max_bw;
u8 phy_port;
@@ -1050,11 +1082,13 @@ struct qlcnic_npar_info {
u8 active;
u8 enable_pm;
u8 dest_npar;
- u8 host_vlan_tag;
- u8 promisc_mode;
u8 discard_tagged;
- u8 mac_learning;
+ u8 mac_override;
+ u8 mac_anti_spoof;
+ u8 promisc_mode;
+ u8 offload_flags;
};
+
struct qlcnic_eswitch {
u8 port;
u8 active_vports;
@@ -1086,7 +1120,6 @@ struct qlcnic_eswitch {
#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW)
#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES)
#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES)
-#define IS_VALID_MODE(mode) (mode == 0 || mode == 1)
struct qlcnic_pci_func_cfg {
u16 func_type;
@@ -1118,12 +1151,41 @@ struct qlcnic_pm_func_cfg {
struct qlcnic_esw_func_cfg {
u16 vlan_id;
+ u8 op_mode;
+ u8 op_type;
u8 pci_func;
u8 host_vlan_tag;
u8 promisc_mode;
u8 discard_tagged;
- u8 mac_learning;
- u8 reserved;
+ u8 mac_override;
+ u8 mac_anti_spoof;
+ u8 offload_flags;
+ u8 reserved[5];
+};
+
+#define QLCNIC_STATS_VERSION 1
+#define QLCNIC_STATS_PORT 1
+#define QLCNIC_STATS_ESWITCH 2
+#define QLCNIC_QUERY_RX_COUNTER 0
+#define QLCNIC_QUERY_TX_COUNTER 1
+struct __qlcnic_esw_statistics {
+ __le16 context_id;
+ __le16 version;
+ __le16 size;
+ __le16 unused;
+ __le64 unicast_frames;
+ __le64 multicast_frames;
+ __le64 broadcast_frames;
+ __le64 dropped_frames;
+ __le64 errors;
+ __le64 local_frames;
+ __le64 numbytes;
+ __le64 rsvd[3];
+};
+
+struct qlcnic_esw_statistics {
+ struct __qlcnic_esw_statistics rx;
+ struct __qlcnic_esw_statistics tx;
};
int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
@@ -1171,6 +1233,8 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);
int qlcnic_get_board_info(struct qlcnic_adapter *adapter);
int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
+void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter);
+void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
/* Functions from qlcnic_init.c */
int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
@@ -1199,7 +1263,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
-int qlcnic_init_firmware(struct qlcnic_adapter *adapter);
+int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
void qlcnic_watchdog_task(struct work_struct *work);
void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
struct qlcnic_host_rds_ring *rds_ring);
@@ -1220,7 +1284,6 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring);
-int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac);
void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter);
int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
@@ -1249,9 +1312,16 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8,
int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8,
struct qlcnic_eswitch *);
int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
-int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8,
- u8, u8, u16);
+int qlcnic_config_switch_port(struct qlcnic_adapter *,
+ struct qlcnic_esw_func_cfg *);
+int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
+ struct qlcnic_esw_func_cfg *);
int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
+int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
+ struct __qlcnic_esw_statistics *);
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8,
+ struct __qlcnic_esw_statistics *);
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
extern int qlcnic_config_tso;
/*
@@ -1280,6 +1350,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = {
"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
{0x1077, 0x8020, 0x1077, 0x20f,
"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
+ {0x1077, 0x8020, 0x103c, 0x3733,
+ "NC523SFP 10Gb 2-port Flex-10 Server Adapter"},
{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
};
@@ -1298,7 +1370,6 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
extern const struct ethtool_ops qlcnic_ethtool_ops;
struct qlcnic_nic_template {
- int (*get_mac_addr) (struct qlcnic_adapter *, u8*);
int (*config_bridged_mode) (struct qlcnic_adapter *, u32);
int (*config_led) (struct qlcnic_adapter *, u32, u32);
int (*start_firmware) (struct qlcnic_adapter *);
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index cc5d861d9a12..95a821e0b66f 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -813,9 +813,8 @@ int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port,
arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
eswitch->port = arg1 & 0xf;
- eswitch->active_vports = LSB(arg2);
- eswitch->max_ucast_filters = MSB(arg2);
- eswitch->max_active_vlans = LSB(MSW(arg2));
+ eswitch->max_ucast_filters = LSW(arg2);
+ eswitch->max_active_vlans = MSW(arg2) & 0xfff;
if (arg1 & BIT_6)
eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
if (arg1 & BIT_7)
@@ -943,43 +942,271 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
return err;
}
-/* Configure eSwitch port */
-int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
- int vlan_tagging, u8 discard_tagged, u8 promsc_mode,
- u8 mac_learn, u8 pci_func, u16 vlan_id)
+int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
+ const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+ size_t stats_size = sizeof(struct __qlcnic_esw_statistics);
+ struct __qlcnic_esw_statistics *stats;
+ dma_addr_t stats_dma_t;
+ void *stats_addr;
+ u32 arg1;
+ int err;
+
+ if (esw_stats == NULL)
+ return -ENOMEM;
+
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
+ func != adapter->ahw.pci_func) {
+ dev_err(&adapter->pdev->dev,
+ "Not privilege to query stats for func=%d", func);
+ return -EIO;
+ }
+
+ stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
+ &stats_dma_t);
+ if (!stats_addr) {
+ dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+ memset(stats_addr, 0, stats_size);
+
+ arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
+ arg1 |= rx_tx << 15 | stats_size << 16;
+
+ err = qlcnic_issue_cmd(adapter,
+ adapter->ahw.pci_func,
+ adapter->fw_hal_version,
+ arg1,
+ MSD(stats_dma_t),
+ LSD(stats_dma_t),
+ QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+ if (!err) {
+ stats = (struct __qlcnic_esw_statistics *)stats_addr;
+ esw_stats->context_id = le16_to_cpu(stats->context_id);
+ esw_stats->version = le16_to_cpu(stats->version);
+ esw_stats->size = le16_to_cpu(stats->size);
+ esw_stats->multicast_frames =
+ le64_to_cpu(stats->multicast_frames);
+ esw_stats->broadcast_frames =
+ le64_to_cpu(stats->broadcast_frames);
+ esw_stats->unicast_frames = le64_to_cpu(stats->unicast_frames);
+ esw_stats->dropped_frames = le64_to_cpu(stats->dropped_frames);
+ esw_stats->local_frames = le64_to_cpu(stats->local_frames);
+ esw_stats->errors = le64_to_cpu(stats->errors);
+ esw_stats->numbytes = le64_to_cpu(stats->numbytes);
+ }
+
+ pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+ stats_dma_t);
+ return err;
+}
+
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
+ const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+ struct __qlcnic_esw_statistics port_stats;
+ u8 i;
+ int ret = -EIO;
+
+ if (esw_stats == NULL)
+ return -ENOMEM;
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+ return -EIO;
+ if (adapter->npars == NULL)
+ return -EIO;
+
+ memset(esw_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+ esw_stats->context_id = eswitch;
+
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ if (adapter->npars[i].phy_port != eswitch)
+ continue;
+
+ memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+ if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
+ continue;
+
+ esw_stats->size = port_stats.size;
+ esw_stats->version = port_stats.version;
+ esw_stats->unicast_frames += port_stats.unicast_frames;
+ esw_stats->multicast_frames += port_stats.multicast_frames;
+ esw_stats->broadcast_frames += port_stats.broadcast_frames;
+ esw_stats->dropped_frames += port_stats.dropped_frames;
+ esw_stats->errors += port_stats.errors;
+ esw_stats->local_frames += port_stats.local_frames;
+ esw_stats->numbytes += port_stats.numbytes;
+
+ ret = 0;
+ }
+ return ret;
+}
+
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
+ const u8 port, const u8 rx_tx)
{
- int err = -EIO;
+
u32 arg1;
- struct qlcnic_eswitch *eswitch;
if (adapter->op_mode != QLCNIC_MGMT_FUNC)
- return err;
+ return -EIO;
- eswitch = &adapter->eswitch[id];
- if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE))
+ if (func_esw == QLCNIC_STATS_PORT) {
+ if (port >= QLCNIC_MAX_PCI_FUNC)
+ goto err_ret;
+ } else if (func_esw == QLCNIC_STATS_ESWITCH) {
+ if (port >= QLCNIC_NIU_MAX_XG_PORTS)
+ goto err_ret;
+ } else {
+ goto err_ret;
+ }
+
+ if (rx_tx > QLCNIC_QUERY_TX_COUNTER)
+ goto err_ret;
+
+ arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
+ arg1 |= BIT_14 | rx_tx << 15;
+
+ return qlcnic_issue_cmd(adapter,
+ adapter->ahw.pci_func,
+ adapter->fw_hal_version,
+ arg1,
+ 0,
+ 0,
+ QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+err_ret:
+ dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d"
+ "rx_ctx=%d\n", func_esw, port, rx_tx);
+ return -EIO;
+}
+
+static int
+__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
+ u32 *arg1, u32 *arg2)
+{
+ int err = -EIO;
+ u8 pci_func;
+ pci_func = (*arg1 >> 8);
+ err = qlcnic_issue_cmd(adapter,
+ adapter->ahw.pci_func,
+ adapter->fw_hal_version,
+ *arg1,
+ 0,
+ 0,
+ QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG);
+
+ if (err == QLCNIC_RCODE_SUCCESS) {
+ *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+ *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
+ dev_info(&adapter->pdev->dev,
+ "eSwitch port config for pci func %d\n", pci_func);
+ } else {
+ dev_err(&adapter->pdev->dev,
+ "Failed to get eswitch port config for pci func %d\n",
+ pci_func);
+ }
+ return err;
+}
+/* Configure eSwitch port
+op_mode = 0 for setting default port behavior
+op_mode = 1 for setting vlan id
+op_mode = 2 for deleting vlan id
+op_type = 0 for vlan_id
+op_type = 1 for port vlan_id
+*/
+int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ int err = -EIO;
+ u32 arg1, arg2 = 0;
+ u8 pci_func;
+
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return err;
+ pci_func = esw_cfg->pci_func;
+ arg1 = (adapter->npars[pci_func].phy_port & BIT_0);
+ arg1 |= (pci_func << 8);
- arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0);
- arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0);
- arg1 |= pci_func << 8;
- if (vlan_tagging)
- arg1 |= BIT_5 | (vlan_id << 16);
+ if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
+ return err;
+ arg1 &= ~(0x0ff << 8);
+ arg1 |= (pci_func << 8);
+ arg1 &= ~(BIT_2 | BIT_3);
+ switch (esw_cfg->op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ arg1 |= (BIT_4 | BIT_6 | BIT_7);
+ arg2 |= (BIT_0 | BIT_1);
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+ arg2 |= (BIT_2 | BIT_3);
+ if (!(esw_cfg->discard_tagged))
+ arg1 &= ~BIT_4;
+ if (!(esw_cfg->promisc_mode))
+ arg1 &= ~BIT_6;
+ if (!(esw_cfg->mac_override))
+ arg1 &= ~BIT_7;
+ if (!(esw_cfg->mac_anti_spoof))
+ arg2 &= ~BIT_0;
+ if (!(esw_cfg->offload_flags & BIT_0))
+ arg2 &= ~(BIT_1 | BIT_2 | BIT_3);
+ if (!(esw_cfg->offload_flags & BIT_1))
+ arg2 &= ~BIT_2;
+ if (!(esw_cfg->offload_flags & BIT_2))
+ arg2 &= ~BIT_3;
+ break;
+ case QLCNIC_ADD_VLAN:
+ arg1 |= (BIT_2 | BIT_5);
+ arg1 |= (esw_cfg->vlan_id << 16);
+ break;
+ case QLCNIC_DEL_VLAN:
+ arg1 |= (BIT_3 | BIT_5);
+ arg1 &= ~(0x0ffff << 16);
+ break;
+ default:
+ return err;
+ }
err = qlcnic_issue_cmd(adapter,
adapter->ahw.pci_func,
adapter->fw_hal_version,
arg1,
- 0,
+ arg2,
0,
QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
if (err != QLCNIC_RCODE_SUCCESS) {
dev_err(&adapter->pdev->dev,
- "Failed to configure eswitch port%d\n", eswitch->port);
+ "Failed to configure eswitch pci func %d\n", pci_func);
} else {
dev_info(&adapter->pdev->dev,
- "Configured eSwitch for port %d\n", eswitch->port);
+ "Configured eSwitch for pci func %d\n", pci_func);
}
return err;
}
+
+int
+qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ u32 arg1, arg2;
+ u8 phy_port;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ phy_port = adapter->npars[esw_cfg->pci_func].phy_port;
+ else
+ phy_port = adapter->physical_port;
+ arg1 = phy_port;
+ arg1 |= (esw_cfg->pci_func << 8);
+ if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2))
+ return -EIO;
+
+ esw_cfg->discard_tagged = !!(arg1 & BIT_4);
+ esw_cfg->host_vlan_tag = !!(arg1 & BIT_5);
+ esw_cfg->promisc_mode = !!(arg1 & BIT_6);
+ esw_cfg->mac_override = !!(arg1 & BIT_7);
+ esw_cfg->vlan_id = LSW(arg1 >> 16);
+ esw_cfg->mac_anti_spoof = (arg2 & 0x1);
+ esw_cfg->offload_flags = ((arg2 >> 1) & 0x7);
+
+ return 0;
+}
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 9328d59e21e0..cb9463bd6b1e 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -99,7 +99,7 @@ static const u32 diag_registers[] = {
CRB_XG_STATE_P3,
CRB_FW_CAPABILITIES_1,
ISR_INT_STATE_REG,
- QLCNIC_CRB_DEV_REF_COUNT,
+ QLCNIC_CRB_DRV_ACTIVE,
QLCNIC_CRB_DEV_STATE,
QLCNIC_CRB_DRV_STATE,
QLCNIC_CRB_DRV_SCRATCH,
@@ -115,9 +115,13 @@ static const u32 diag_registers[] = {
-1
};
+#define QLCNIC_MGMT_API_VERSION 2
+#define QLCNIC_DEV_INFO_SIZE 1
+#define QLCNIC_ETHTOOL_REGS_VER 2
static int qlcnic_get_regs_len(struct net_device *dev)
{
- return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN;
+ return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
+ QLCNIC_DEV_INFO_SIZE + 1;
}
static int qlcnic_get_eeprom_len(struct net_device *dev)
@@ -342,10 +346,13 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
int ring, i = 0;
memset(p, 0, qlcnic_get_regs_len(dev));
- regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
- (adapter->pdev)->device;
+ regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
+ (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
- for (i = 0; diag_registers[i] != -1; i++)
+ regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
+ regs_buff[1] = QLCNIC_MGMT_API_VERSION;
+
+ for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[i] != -1; i++)
regs_buff[i] = QLCRD32(adapter, diag_registers[i]);
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
@@ -747,6 +754,14 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
{
memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
+ data[0] = qlcnic_reg_test(dev);
+ if (data[0])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ data[1] = (u64) qlcnic_test_link(dev);
+ if (data[1])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
data[2] = qlcnic_irq_test(dev);
if (data[2])
@@ -757,15 +772,6 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
eth_test->flags |= ETH_TEST_FL_FAILED;
}
-
- data[0] = qlcnic_reg_test(dev);
- if (data[0])
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* link test */
- data[1] = (u64) qlcnic_test_link(dev);
- if (data[1])
- eth_test->flags |= ETH_TEST_FL_FAILED;
}
static void
@@ -805,6 +811,20 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
}
}
+static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+ if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return -EOPNOTSUPP;
+ if (data)
+ dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ else
+ dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+
+ return 0;
+
+}
static u32 qlcnic_get_tx_csum(struct net_device *dev)
{
return dev->features & NETIF_F_IP_CSUM;
@@ -819,7 +839,23 @@ static u32 qlcnic_get_rx_csum(struct net_device *dev)
static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
{
struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+ if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return -EOPNOTSUPP;
+ if (!!data) {
+ adapter->rx_csum = !!data;
+ return 0;
+ }
+
+ if (adapter->flags & QLCNIC_LRO_ENABLED) {
+ if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
+ return -EIO;
+
+ dev->features &= ~NETIF_F_LRO;
+ qlcnic_send_lro_cleanup(adapter);
+ }
adapter->rx_csum = !!data;
+ dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n");
return 0;
}
@@ -1002,6 +1038,15 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data)
if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
return -EINVAL;
+ if (!adapter->rx_csum) {
+ dev_info(&adapter->pdev->dev, "rx csum is off, "
+ "cannot toggle lro\n");
+ return -EINVAL;
+ }
+
+ if ((data & ETH_FLAG_LRO) && (adapter->flags & QLCNIC_LRO_ENABLED))
+ return 0;
+
if (data & ETH_FLAG_LRO) {
hw_lro = QLCNIC_LRO_ENABLED;
netdev->features |= NETIF_F_LRO;
@@ -1048,7 +1093,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
.get_pauseparam = qlcnic_get_pauseparam,
.set_pauseparam = qlcnic_set_pauseparam,
.get_tx_csum = qlcnic_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
+ .set_tx_csum = qlcnic_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.get_tso = qlcnic_get_tso,
.set_tso = qlcnic_set_tso,
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 15fc32070be3..716203e41dc7 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -698,7 +698,7 @@ enum {
#define QLCNIC_PEG_ALIVE_COUNTER (QLCNIC_CAM_RAM(0xb0))
#define QLCNIC_PEG_HALT_STATUS1 (QLCNIC_CAM_RAM(0xa8))
#define QLCNIC_PEG_HALT_STATUS2 (QLCNIC_CAM_RAM(0xac))
-#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138))
+#define QLCNIC_CRB_DRV_ACTIVE (QLCNIC_CAM_RAM(0x138))
#define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140))
#define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144))
@@ -718,8 +718,9 @@ enum {
#define QLCNIC_DEV_FAILED 0x6
#define QLCNIC_DEV_QUISCENT 0x7
-#define QLCNIC_DEV_NPAR_NOT_RDY 0
-#define QLCNIC_DEV_NPAR_RDY 1
+#define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */
+#define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */
+#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */
#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4)))
#define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4)))
@@ -744,6 +745,15 @@ enum {
#define FW_POLL_DELAY (1 * HZ)
#define FW_FAIL_THRESH 2
+#define QLCNIC_RESET_TIMEOUT_SECS 10
+#define QLCNIC_INIT_TIMEOUT_SECS 30
+#define QLCNIC_RCVPEG_CHECK_RETRY_COUNT 2000
+#define QLCNIC_RCVPEG_CHECK_DELAY 10
+#define QLCNIC_CMDPEG_CHECK_RETRY_COUNT 60
+#define QLCNIC_CMDPEG_CHECK_DELAY 500
+#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200
+#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45
+
#define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
@@ -770,6 +780,7 @@ struct qlcnic_legacy_intr_set {
#define QLCNIC_DRV_OP_MODE 0x1b2170
#define QLCNIC_MSIX_BASE 0x132110
#define QLCNIC_MAX_PCI_FUNC 8
+#define QLCNIC_MAX_VLAN_FILTERS 64
/* PCI function operational mode */
enum {
@@ -778,6 +789,12 @@ enum {
QLCNIC_NON_PRIV_FUNC = 2
};
+enum {
+ QLCNIC_PORT_DEFAULTS = 0,
+ QLCNIC_ADD_VLAN = 1,
+ QLCNIC_DEL_VLAN = 2
+};
+
#define QLC_DEV_DRV_DEFAULT 0x11111111
#define LSB(x) ((uint8_t)(x))
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index e08c8b0556a4..c198df90ff3c 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -297,8 +297,8 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
break;
if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
dev_err(&adapter->pdev->dev,
- "Failed to acquire sem=%d lock;reg_id=%d\n",
- sem, id_reg);
+ "Failed to acquire sem=%d lock; holdby=%d\n",
+ sem, id_reg ? QLCRD32(adapter, id_reg) : -1);
return -EIO;
}
msleep(1);
@@ -375,7 +375,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
static int
qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
- unsigned op)
+ u16 vlan_id, unsigned op)
{
struct qlcnic_nic_req req;
struct qlcnic_mac_req *mac_req;
@@ -391,6 +391,8 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
mac_req->op = op;
memcpy(mac_req->mac_addr, addr, 6);
+ req.words[1] = cpu_to_le64(vlan_id);
+
return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
}
@@ -415,7 +417,7 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
memcpy(cur->mac_addr, addr, ETH_ALEN);
if (qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_ADD)) {
+ cur->mac_addr, 0, QLCNIC_MAC_ADD)) {
kfree(cur);
return -EIO;
}
@@ -485,12 +487,63 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
while (!list_empty(head)) {
cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_DEL);
+ cur->mac_addr, 0, QLCNIC_MAC_DEL);
list_del(&cur->list);
kfree(cur);
}
}
+void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_filter *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ int i;
+
+ for (i = 0; i < adapter->fhash.fmax; i++) {
+ head = &(adapter->fhash.fhead[i]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode)
+ {
+ if (jiffies >
+ (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) {
+ qlcnic_sre_macaddr_change(adapter,
+ tmp_fil->faddr, tmp_fil->vlan_id,
+ tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL :
+ QLCNIC_MAC_DEL);
+ spin_lock_bh(&adapter->mac_learn_lock);
+ adapter->fhash.fnum--;
+ hlist_del(&tmp_fil->fnode);
+ spin_unlock_bh(&adapter->mac_learn_lock);
+ kfree(tmp_fil);
+ }
+ }
+ }
+}
+
+void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_filter *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ int i;
+
+ for (i = 0; i < adapter->fhash.fmax; i++) {
+ head = &(adapter->fhash.fhead[i]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
+ qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr,
+ tmp_fil->vlan_id, tmp_fil->vlan_id ?
+ QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL);
+ spin_lock_bh(&adapter->mac_learn_lock);
+ adapter->fhash.fnum--;
+ hlist_del(&tmp_fil->fnode);
+ spin_unlock_bh(&adapter->mac_learn_lock);
+ kfree(tmp_fil);
+ }
+ }
+}
+
#define QLCNIC_CONFIG_INTR_COALESCE 3
/*
@@ -715,19 +768,6 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
return rc;
}
-int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac)
-{
- u32 crbaddr;
- int pci_func = adapter->ahw.pci_func;
-
- crbaddr = CRB_MAC_BLOCK_START +
- (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
-
- qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac);
-
- return 0;
-}
-
/*
* Changes the CRB window to the specified window.
*/
@@ -1245,4 +1285,5 @@ void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter)
mode = VPORT_MISS_MODE_ACCEPT_MULTI;
qlcnic_nic_set_promisc(adapter, mode);
+ msleep(1000);
}
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 75ba744b173c..26a7d6bca5c7 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -25,6 +25,7 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/if_vlan.h>
#include "qlcnic.h"
struct crb_addr_pair {
@@ -45,6 +46,9 @@ static void
qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring);
+static int
+qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter);
+
static void crb_addr_transform_setup(void)
{
crb_addr_transform(XDMA);
@@ -136,8 +140,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- spin_lock(&rds_ring->lock);
-
INIT_LIST_HEAD(&rds_ring->free_list);
rx_buf = rds_ring->rx_buf_arr;
@@ -146,8 +148,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
&rds_ring->free_list);
rx_buf++;
}
-
- spin_unlock(&rds_ring->lock);
}
}
@@ -439,11 +439,14 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
u32 off;
struct pci_dev *pdev = adapter->pdev;
- /* resetall */
+ QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
+ QLCWR32(adapter, CRB_RCVPEG_STATE, 0);
+
qlcnic_rom_lock(adapter);
QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff);
qlcnic_rom_unlock(adapter);
+ /* Init HW CRB block */
if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) ||
qlcnic_rom_fast_read(adapter, 4, &n) != 0) {
dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n);
@@ -524,13 +527,10 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
}
kfree(buf);
- /* p2dn replyCount */
+ /* Initialize protocol process engine */
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e);
- /* disable_peg_cache 0 & 1*/
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8);
-
- /* peg_clr_all */
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0);
@@ -539,10 +539,88 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0);
QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
+ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0);
+ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0);
+ msleep(1);
+ QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
+ QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
+ return 0;
+}
+
+static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
+{
+ u32 val;
+ int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT;
+
+ do {
+ val = QLCRD32(adapter, CRB_CMDPEG_STATE);
+
+ switch (val) {
+ case PHAN_INITIALIZE_COMPLETE:
+ case PHAN_INITIALIZE_ACK:
+ return 0;
+ case PHAN_INITIALIZE_FAILED:
+ goto out_err;
+ default:
+ break;
+ }
+
+ msleep(QLCNIC_CMDPEG_CHECK_DELAY);
+
+ } while (--retries);
+
+ QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
+
+out_err:
+ dev_err(&adapter->pdev->dev, "Command Peg initialization not "
+ "complete, state: 0x%x.\n", val);
+ return -EIO;
+}
+
+static int
+qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
+{
+ u32 val;
+ int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT;
+
+ do {
+ val = QLCRD32(adapter, CRB_RCVPEG_STATE);
+
+ if (val == PHAN_PEG_RCV_INITIALIZED)
+ return 0;
+
+ msleep(QLCNIC_RCVPEG_CHECK_DELAY);
+
+ } while (--retries);
+
+ if (!retries) {
+ dev_err(&adapter->pdev->dev, "Receive Peg initialization not "
+ "complete, state: 0x%x.\n", val);
+ return -EIO;
+ }
+
return 0;
}
int
+qlcnic_check_fw_status(struct qlcnic_adapter *adapter)
+{
+ int err;
+
+ err = qlcnic_cmd_peg_ready(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_receive_peg_ready(adapter);
+ if (err)
+ return err;
+
+ QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+ return err;
+}
+
+int
qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
int timeo;
@@ -557,12 +635,12 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) {
}
adapter->physical_port = (val >> 2);
if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo))
- timeo = 30;
+ timeo = QLCNIC_INIT_TIMEOUT_SECS;
adapter->dev_init_timeo = timeo;
if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DRV_RESET_TIMEOUT, &timeo))
- timeo = 10;
+ timeo = QLCNIC_RESET_TIMEOUT_SECS;
adapter->reset_ack_timeo = timeo;
@@ -906,38 +984,45 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter)
return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24);
}
-int
-qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
+static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter)
{
- u32 count, old_count;
- u32 val, version, major, minor, build;
- int i, timeout;
-
- if (adapter->need_fw_reset)
- return 1;
+ if (qlcnic_pcie_sem_lock(adapter, 2, QLCNIC_ROM_LOCK_ID))
+ dev_info(&adapter->pdev->dev, "Resetting rom_lock\n");
- /* last attempt had failed */
- if (QLCRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
- return 1;
+ qlcnic_pcie_sem_unlock(adapter, 2);
+}
- old_count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+static int
+qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter)
+{
+ u32 heartbeat, ret = -EIO;
+ int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT;
- for (i = 0; i < 10; i++) {
+ adapter->heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- timeout = msleep_interruptible(200);
- if (timeout) {
- QLCWR32(adapter, CRB_CMDPEG_STATE,
- PHAN_INITIALIZE_FAILED);
- return -EINTR;
+ do {
+ msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS);
+ heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+ if (heartbeat != adapter->heartbeat) {
+ ret = QLCNIC_RCODE_SUCCESS;
+ break;
}
+ } while (--retries);
- count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- if (count != old_count)
- break;
+ return ret;
+}
+
+int
+qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
+{
+ u32 val, version, major, minor, build;
+
+ if (qlcnic_check_fw_hearbeat(adapter)) {
+ qlcnic_rom_lock_recovery(adapter);
+ return 1;
}
- /* firmware is dead */
- if (count == old_count)
+ if (adapter->need_fw_reset)
return 1;
/* check if we have got newer or different file firmware */
@@ -1162,78 +1247,6 @@ qlcnic_release_firmware(struct qlcnic_adapter *adapter)
adapter->fw = NULL;
}
-static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
-{
- u32 val;
- int retries = 60;
-
- do {
- val = QLCRD32(adapter, CRB_CMDPEG_STATE);
-
- switch (val) {
- case PHAN_INITIALIZE_COMPLETE:
- case PHAN_INITIALIZE_ACK:
- return 0;
- case PHAN_INITIALIZE_FAILED:
- goto out_err;
- default:
- break;
- }
-
- msleep(500);
-
- } while (--retries);
-
- QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
-
-out_err:
- dev_err(&adapter->pdev->dev, "Command Peg initialization not "
- "complete, state: 0x%x.\n", val);
- return -EIO;
-}
-
-static int
-qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter)
-{
- u32 val;
- int retries = 2000;
-
- do {
- val = QLCRD32(adapter, CRB_RCVPEG_STATE);
-
- if (val == PHAN_PEG_RCV_INITIALIZED)
- return 0;
-
- msleep(10);
-
- } while (--retries);
-
- if (!retries) {
- dev_err(&adapter->pdev->dev, "Receive Peg initialization not "
- "complete, state: 0x%x.\n", val);
- return -EIO;
- }
-
- return 0;
-}
-
-int qlcnic_init_firmware(struct qlcnic_adapter *adapter)
-{
- int err;
-
- err = qlcnic_cmd_peg_ready(adapter);
- if (err)
- return err;
-
- err = qlcnic_receive_peg_ready(adapter);
- if (err)
- return err;
-
- QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
- return err;
-}
-
static void
qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
struct qlcnic_fw_msg *msg)
@@ -1351,11 +1364,12 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
skb = buffer->skb;
- if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+ if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK ||
+ cksum == STATUS_CKSUM_LOOP))) {
adapter->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
skb->dev = adapter->netdev;
@@ -1365,6 +1379,27 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
return skb;
}
+static int
+qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb)
+{
+ u16 vlan_tag;
+ struct ethhdr *eth_hdr;
+
+ if (!__vlan_get_tag(skb, &vlan_tag)) {
+ if (vlan_tag == adapter->pvid) {
+ /* strip the tag from the packet and send it up */
+ eth_hdr = (struct ethhdr *) skb->data;
+ memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2);
+ skb_pull(skb, VLAN_HLEN);
+ return 0;
+ }
+ }
+ if (adapter->flags & QLCNIC_TAGGING_ENABLED)
+ return 0;
+
+ return -EIO;
+}
+
static struct qlcnic_rx_buffer *
qlcnic_process_rcv(struct qlcnic_adapter *adapter,
struct qlcnic_host_sds_ring *sds_ring,
@@ -1405,6 +1440,15 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
skb_pull(skb, pkt_offset);
skb->truesize = skb->len + sizeof(struct sk_buff);
+
+ if (unlikely(adapter->pvid)) {
+ if (qlcnic_check_rx_tagging(adapter, skb)) {
+ adapter->stats.rxdropped++;
+ dev_kfree_skb_any(skb);
+ return buffer;
+ }
+ }
+
skb->protocol = eth_type_trans(skb, netdev);
napi_gro_receive(&sds_ring->napi, skb);
@@ -1469,6 +1513,14 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
skb_pull(skb, l2_hdr_offset);
+
+ if (unlikely(adapter->pvid)) {
+ if (qlcnic_check_rx_tagging(adapter, skb)) {
+ adapter->stats.rxdropped++;
+ dev_kfree_skb_any(skb);
+ return buffer;
+ }
+ }
skb->protocol = eth_type_trans(skb, netdev);
iph = (struct iphdr *)skb->data;
@@ -1587,8 +1639,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
int producer, count = 0;
struct list_head *head;
- spin_lock(&rds_ring->lock);
-
producer = rds_ring->producer;
head = &rds_ring->free_list;
@@ -1618,7 +1668,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
writel((producer-1) & (rds_ring->num_desc-1),
rds_ring->crb_rcv_producer);
}
- spin_unlock(&rds_ring->lock);
}
static void
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 66eea5972020..5fd2abd1eb67 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -50,6 +50,10 @@ static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG;
/* Default to restricted 1G auto-neg mode */
static int wol_port_mode = 5;
+static int qlcnic_mac_learn;
+module_param(qlcnic_mac_learn, int, 0644);
+MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)");
+
static int use_msi = 1;
module_param(use_msi, int, 0644);
MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled");
@@ -94,7 +98,7 @@ static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding);
-static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter);
+static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8);
static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
@@ -106,10 +110,14 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev);
static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long);
static int qlcnic_start_firmware(struct qlcnic_adapter *);
+static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
+static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
+static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
+ struct qlcnic_esw_func_cfg *);
/* PCI Device ID Table */
#define ENTRY(device) \
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -320,7 +328,7 @@ qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
- if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0)
+ if (qlcnic_get_mac_address(adapter, mac_addr) != 0)
return -EIO;
memcpy(netdev->dev_addr, mac_addr, ETH_ALEN);
@@ -341,6 +349,9 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
+ if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED))
+ return -EOPNOTSUPP;
+
if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
@@ -376,14 +387,12 @@ static const struct net_device_ops qlcnic_netdev_ops = {
};
static struct qlcnic_nic_template qlcnic_ops = {
- .get_mac_addr = qlcnic_get_mac_address,
.config_bridged_mode = qlcnic_config_bridged_mode,
.config_led = qlcnic_config_led,
.start_firmware = qlcnic_start_firmware
};
static struct qlcnic_nic_template qlcnic_vf_ops = {
- .get_mac_addr = qlcnic_get_mac_address,
.config_bridged_mode = qlcnicvf_config_bridged_mode,
.config_led = qlcnicvf_config_led,
.start_firmware = qlcnicvf_start_firmware
@@ -474,7 +483,7 @@ static int
qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
{
struct qlcnic_pci_info *pci_info;
- int i, ret = 0, err;
+ int i, ret = 0;
u8 pfn;
pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
@@ -484,14 +493,14 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) *
QLCNIC_MAX_PCI_FUNC, GFP_KERNEL);
if (!adapter->npars) {
- err = -ENOMEM;
+ ret = -ENOMEM;
goto err_pci_info;
}
adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) *
QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL);
if (!adapter->eswitch) {
- err = -ENOMEM;
+ ret = -ENOMEM;
goto err_npars;
}
@@ -506,7 +515,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
adapter->npars[pfn].active = pci_info[i].active;
adapter->npars[pfn].type = pci_info[i].type;
adapter->npars[pfn].phy_port = pci_info[i].default_port;
- adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
}
@@ -539,12 +547,10 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
/* If other drivers are not in use set their privilege level */
- ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
ret = qlcnic_api_lock(adapter);
if (ret)
goto err_lock;
- if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func))
- goto err_npar;
if (qlcnic_config_npars) {
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
@@ -562,18 +568,16 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
adapter->ahw.pci_func));
}
writel(data, priv_op);
-err_npar:
qlcnic_api_unlock(adapter);
err_lock:
return ret;
}
-static u32
-qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
+static void
+qlcnic_check_vf(struct qlcnic_adapter *adapter)
{
void __iomem *msix_base_addr;
void __iomem *priv_op;
- struct qlcnic_info nic_info;
u32 func;
u32 msix_base;
u32 op_mode, priv_level;
@@ -588,20 +592,6 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
adapter->ahw.pci_func = func;
- if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) {
- adapter->capabilities = nic_info.capabilities;
-
- if (adapter->capabilities & BIT_6)
- adapter->flags |= QLCNIC_ESWITCH_ENABLED;
- else
- adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
- }
-
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
- adapter->nic_ops = &qlcnic_ops;
- return adapter->fw_hal_version;
- }
-
/* Determine function privilege level */
priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
op_mode = readl(priv_op);
@@ -610,37 +600,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter)
else
priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
- switch (priv_level) {
- case QLCNIC_MGMT_FUNC:
- adapter->op_mode = QLCNIC_MGMT_FUNC;
- adapter->nic_ops = &qlcnic_ops;
- qlcnic_init_pci_info(adapter);
- /* Set privilege level for other functions */
- qlcnic_set_function_modes(adapter);
- dev_info(&adapter->pdev->dev,
- "HAL Version: %d, Management function\n",
- adapter->fw_hal_version);
- break;
- case QLCNIC_PRIV_FUNC:
- adapter->op_mode = QLCNIC_PRIV_FUNC;
- dev_info(&adapter->pdev->dev,
- "HAL Version: %d, Privileged function\n",
- adapter->fw_hal_version);
- adapter->nic_ops = &qlcnic_ops;
- break;
- case QLCNIC_NON_PRIV_FUNC:
+ if (priv_level == QLCNIC_NON_PRIV_FUNC) {
adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
dev_info(&adapter->pdev->dev,
"HAL Version: %d Non Privileged function\n",
adapter->fw_hal_version);
adapter->nic_ops = &qlcnic_vf_ops;
- break;
- default:
- dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n",
- priv_level);
- return 0;
- }
- return adapter->fw_hal_version;
+ } else
+ adapter->nic_ops = &qlcnic_ops;
}
static int
@@ -673,10 +640,7 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter)
adapter->ahw.pci_base0 = mem_ptr0;
adapter->ahw.pci_len0 = pci_len0;
- if (!qlcnic_get_driver_mode(adapter)) {
- iounmap(adapter->ahw.pci_base0);
- return -EIO;
- }
+ qlcnic_check_vf(adapter);
adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter,
QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func)));
@@ -711,25 +675,7 @@ static void
qlcnic_check_options(struct qlcnic_adapter *adapter)
{
u32 fw_major, fw_minor, fw_build;
- char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
- char serial_num[32];
- int i, offset, val;
- int *ptr32;
struct pci_dev *pdev = adapter->pdev;
- struct qlcnic_info nic_info;
- adapter->driver_mismatch = 0;
-
- ptr32 = (int *)&serial_num;
- offset = QLCNIC_FW_SERIAL_NUM_OFFSET;
- for (i = 0; i < 8; i++) {
- if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) {
- dev_err(&pdev->dev, "error reading board info\n");
- adapter->driver_mismatch = 1;
- return;
- }
- ptr32[i] = cpu_to_le32(val);
- offset += sizeof(u32);
- }
fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
@@ -737,14 +683,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
- if (adapter->portnum == 0) {
- get_brd_name(adapter, brd_name);
-
- pr_info("%s: %s Board Chip rev 0x%x\n",
- module_name(THIS_MODULE),
- brd_name, adapter->ahw.revision_id);
- }
-
dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
fw_major, fw_minor, fw_build);
@@ -758,109 +696,333 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
}
- if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) {
- adapter->physical_port = nic_info.phys_port;
- adapter->switch_mode = nic_info.switch_mode;
- adapter->max_tx_ques = nic_info.max_tx_ques;
- adapter->max_rx_ques = nic_info.max_rx_ques;
- adapter->capabilities = nic_info.capabilities;
- adapter->max_mac_filters = nic_info.max_mac_filters;
- adapter->max_mtu = nic_info.max_mtu;
- }
-
adapter->msix_supported = !!use_msi_x;
adapter->rss_supported = !!use_msi_x;
adapter->num_txd = MAX_CMD_DESCRIPTORS;
- adapter->max_rds_rings = 2;
+ adapter->max_rds_rings = MAX_RDS_RINGS;
+}
+
+static int
+qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
+{
+ int err;
+ struct qlcnic_info nic_info;
+
+ err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func);
+ if (err)
+ return err;
+
+ adapter->physical_port = nic_info.phys_port;
+ adapter->switch_mode = nic_info.switch_mode;
+ adapter->max_tx_ques = nic_info.max_tx_ques;
+ adapter->max_rx_ques = nic_info.max_rx_ques;
+ adapter->capabilities = nic_info.capabilities;
+ adapter->max_mac_filters = nic_info.max_mac_filters;
+ adapter->max_mtu = nic_info.max_mtu;
+
+ if (adapter->capabilities & BIT_6)
+ adapter->flags |= QLCNIC_ESWITCH_ENABLED;
+ else
+ adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
+
+ return err;
+}
+
+static void
+qlcnic_set_vlan_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ if (esw_cfg->discard_tagged)
+ adapter->flags &= ~QLCNIC_TAGGING_ENABLED;
+ else
+ adapter->flags |= QLCNIC_TAGGING_ENABLED;
+
+ if (esw_cfg->vlan_id)
+ adapter->pvid = esw_cfg->vlan_id;
+ else
+ adapter->pvid = 0;
+}
+
+static void
+qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ adapter->flags &= ~QLCNIC_MACSPOOF;
+ adapter->flags &= ~QLCNIC_MAC_OVERRIDE_DISABLED;
+
+ if (esw_cfg->mac_anti_spoof)
+ adapter->flags |= QLCNIC_MACSPOOF;
+
+ if (!esw_cfg->mac_override)
+ adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED;
+
+ qlcnic_set_netdev_features(adapter, esw_cfg);
+}
+
+static int
+qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return 0;
+
+ esw_cfg.pci_func = adapter->ahw.pci_func;
+ if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg))
+ return -EIO;
+ qlcnic_set_vlan_config(adapter, &esw_cfg);
+ qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
+
+ return 0;
+}
+
+static void
+qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
+ struct qlcnic_esw_func_cfg *esw_cfg)
+{
+ struct net_device *netdev = adapter->netdev;
+ unsigned long features, vlan_features;
+
+ features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_GRO);
+ vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM);
+
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
+ features |= (NETIF_F_TSO | NETIF_F_TSO6);
+ vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
+ }
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+ features |= NETIF_F_LRO;
+
+ if (esw_cfg->offload_flags & BIT_0) {
+ netdev->features |= features;
+ adapter->rx_csum = 1;
+ if (!(esw_cfg->offload_flags & BIT_1))
+ netdev->features &= ~NETIF_F_TSO;
+ if (!(esw_cfg->offload_flags & BIT_2))
+ netdev->features &= ~NETIF_F_TSO6;
+ } else {
+ netdev->features &= ~features;
+ adapter->rx_csum = 0;
+ }
+
+ netdev->vlan_features = (features & vlan_features);
+}
+
+static int
+qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
+{
+ void __iomem *priv_op;
+ u32 op_mode, priv_level;
+ int err = 0;
+
+ err = qlcnic_initialize_nic(adapter);
+ if (err)
+ return err;
+
+ if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
+ return 0;
+
+ priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+ op_mode = readl(priv_op);
+ priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+
+ if (op_mode == QLC_DEV_DRV_DEFAULT)
+ priv_level = QLCNIC_MGMT_FUNC;
+ else
+ priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+
+ if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
+ if (priv_level == QLCNIC_MGMT_FUNC) {
+ adapter->op_mode = QLCNIC_MGMT_FUNC;
+ err = qlcnic_init_pci_info(adapter);
+ if (err)
+ return err;
+ /* Set privilege level for other functions */
+ qlcnic_set_function_modes(adapter);
+ dev_info(&adapter->pdev->dev,
+ "HAL Version: %d, Management function\n",
+ adapter->fw_hal_version);
+ } else if (priv_level == QLCNIC_PRIV_FUNC) {
+ adapter->op_mode = QLCNIC_PRIV_FUNC;
+ dev_info(&adapter->pdev->dev,
+ "HAL Version: %d, Privileged function\n",
+ adapter->fw_hal_version);
+ }
+ }
+
+ adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
+
+ return err;
+}
+
+static int
+qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+ struct qlcnic_npar_info *npar;
+ u8 i;
+
+ if (adapter->need_fw_reset)
+ return 0;
+
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
+ continue;
+ memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
+ esw_cfg.pci_func = i;
+ esw_cfg.offload_flags = BIT_0;
+ esw_cfg.mac_override = BIT_0;
+ if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+ esw_cfg.offload_flags |= (BIT_1 | BIT_2);
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+ npar = &adapter->npars[i];
+ npar->pvid = esw_cfg.vlan_id;
+ npar->mac_override = esw_cfg.mac_override;
+ npar->mac_anti_spoof = esw_cfg.mac_anti_spoof;
+ npar->discard_tagged = esw_cfg.discard_tagged;
+ npar->promisc_mode = esw_cfg.promisc_mode;
+ npar->offload_flags = esw_cfg.offload_flags;
+ }
+
+ return 0;
+}
+
+static int
+qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
+ struct qlcnic_npar_info *npar, int pci_func)
+{
+ struct qlcnic_esw_func_cfg esw_cfg;
+ esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS;
+ esw_cfg.pci_func = pci_func;
+ esw_cfg.vlan_id = npar->pvid;
+ esw_cfg.mac_override = npar->mac_override;
+ esw_cfg.discard_tagged = npar->discard_tagged;
+ esw_cfg.mac_anti_spoof = npar->mac_anti_spoof;
+ esw_cfg.offload_flags = npar->offload_flags;
+ esw_cfg.promisc_mode = npar->promisc_mode;
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+
+ esw_cfg.op_mode = QLCNIC_ADD_VLAN;
+ if (qlcnic_config_switch_port(adapter, &esw_cfg))
+ return -EIO;
+
+ return 0;
}
static int
qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
{
- int i, err = 0;
+ int i, err;
struct qlcnic_npar_info *npar;
struct qlcnic_info nic_info;
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- !adapter->need_fw_reset)
+ if (!adapter->need_fw_reset)
return 0;
- if (adapter->op_mode == QLCNIC_MGMT_FUNC) {
- /* Set the NPAR config data after FW reset */
- for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
- npar = &adapter->npars[i];
- if (npar->type != QLCNIC_TYPE_NIC)
- continue;
- err = qlcnic_get_nic_info(adapter, &nic_info, i);
- if (err)
- goto err_out;
- nic_info.min_tx_bw = npar->min_bw;
- nic_info.max_tx_bw = npar->max_bw;
- err = qlcnic_set_nic_info(adapter, &nic_info);
+ /* Set the NPAR config data after FW reset */
+ for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+ npar = &adapter->npars[i];
+ if (npar->type != QLCNIC_TYPE_NIC)
+ continue;
+ err = qlcnic_get_nic_info(adapter, &nic_info, i);
+ if (err)
+ return err;
+ nic_info.min_tx_bw = npar->min_bw;
+ nic_info.max_tx_bw = npar->max_bw;
+ err = qlcnic_set_nic_info(adapter, &nic_info);
+ if (err)
+ return err;
+
+ if (npar->enable_pm) {
+ err = qlcnic_config_port_mirroring(adapter,
+ npar->dest_npar, 1, i);
if (err)
- goto err_out;
+ return err;
+ }
+ err = qlcnic_reset_eswitch_config(adapter, npar, i);
+ if (err)
+ return err;
+ }
+ return 0;
+}
- if (npar->enable_pm) {
- err = qlcnic_config_port_mirroring(adapter,
- npar->dest_npar, 1, i);
- if (err)
- goto err_out;
+static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter)
+{
+ u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
+ u32 npar_state;
- }
- npar->mac_learning = DEFAULT_MAC_LEARN;
- npar->host_vlan_tag = 0;
- npar->promisc_mode = 0;
- npar->discard_tagged = 0;
- npar->vlan_id = 0;
- }
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ return 0;
+
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) {
+ msleep(1000);
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
}
-err_out:
+ if (!npar_opt_timeo) {
+ dev_err(&adapter->pdev->dev,
+ "Waiting for NPAR state to opertional timeout\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int
+qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter)
+{
+ int err;
+
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
+ adapter->op_mode != QLCNIC_MGMT_FUNC)
+ return 0;
+
+ err = qlcnic_set_default_offload_settings(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_reset_npar_config(adapter);
+ if (err)
+ return err;
+
+ qlcnic_dev_set_npar_ready(adapter);
+
return err;
}
static int
qlcnic_start_firmware(struct qlcnic_adapter *adapter)
{
- int val, err, first_boot;
+ int err;
err = qlcnic_can_start_firmware(adapter);
if (err < 0)
return err;
else if (!err)
- goto wait_init;
-
- first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc));
- if (first_boot == 0x55555555)
- /* This is the first boot after power up */
- QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC);
+ goto check_fw_status;
if (load_fw_file)
qlcnic_request_firmware(adapter);
else {
- if (qlcnic_check_flash_fw_ver(adapter))
+ err = qlcnic_check_flash_fw_ver(adapter);
+ if (err)
goto err_out;
adapter->fw_type = QLCNIC_FLASH_ROMIMAGE;
}
err = qlcnic_need_fw_reset(adapter);
- if (err < 0)
- goto err_out;
if (err == 0)
- goto wait_init;
-
- if (first_boot != 0x55555555) {
- QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
- QLCWR32(adapter, CRB_RCVPEG_STATE, 0);
- qlcnic_pinit_from_rom(adapter);
- msleep(1);
- }
-
- QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
- QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
+ goto check_fw_status;
+ err = qlcnic_pinit_from_rom(adapter);
+ if (err)
+ goto err_out;
qlcnic_set_port_mode(adapter);
err = qlcnic_load_firmware(adapter);
@@ -868,26 +1030,27 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
goto err_out;
qlcnic_release_firmware(adapter);
+ QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION);
- val = (_QLCNIC_LINUX_MAJOR << 16)
- | ((_QLCNIC_LINUX_MINOR << 8))
- | (_QLCNIC_LINUX_SUBVERSION);
- QLCWR32(adapter, CRB_DRIVER_VERSION, val);
-
-wait_init:
- /* Handshake with the card before we register the devices. */
- err = qlcnic_init_firmware(adapter);
+check_fw_status:
+ err = qlcnic_check_fw_status(adapter);
if (err)
goto err_out;
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
qlcnic_idc_debug_info(adapter, 1);
- qlcnic_check_options(adapter);
- if (qlcnic_reset_npar_config(adapter))
+ err = qlcnic_check_eswitch_mode(adapter);
+ if (err) {
+ dev_err(&adapter->pdev->dev,
+ "Memory allocation failed for eswitch\n");
+ goto err_out;
+ }
+ err = qlcnic_set_mgmt_operations(adapter);
+ if (err)
goto err_out;
- qlcnic_dev_set_npar_ready(adapter);
+ qlcnic_check_options(adapter);
adapter->need_fw_reset = 0;
qlcnic_release_firmware(adapter);
@@ -896,6 +1059,7 @@ wait_init:
err_out:
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
dev_err(&adapter->pdev->dev, "Device state set to failed\n");
+
qlcnic_release_firmware(adapter);
return err;
}
@@ -979,6 +1143,8 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
return 0;
+ if (qlcnic_set_eswitch_port_config(adapter))
+ return -EIO;
if (qlcnic_fw_create_ctx(adapter))
return -EIO;
@@ -998,7 +1164,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_config_intr_coalesce(adapter);
- if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+ if (netdev->features & NETIF_F_LRO)
qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
qlcnic_napi_enable(adapter);
@@ -1041,6 +1207,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_free_mac_list(adapter);
+ if (adapter->fhash.fnum)
+ qlcnic_delete_lb_filters(adapter);
+
qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE);
qlcnic_napi_disable(adapter);
@@ -1296,12 +1465,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
netdev->features |= NETIF_F_LRO;
-
netdev->irq = adapter->msix_entries[0].vector;
- if (qlcnic_read_mac_addr(adapter))
- dev_warn(&pdev->dev, "failed to read mac addr\n");
-
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -1338,6 +1503,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int err;
uint8_t revision_id;
uint8_t pci_using_dac;
+ char brd_name[QLCNIC_MAX_BOARD_NAME_LEN];
err = pci_enable_device(pdev);
if (err)
@@ -1395,10 +1561,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_iounmap;
}
- if (qlcnic_read_mac_addr(adapter))
- dev_warn(&pdev->dev, "failed to read mac addr\n");
-
- if (qlcnic_setup_idc_param(adapter))
+ err = qlcnic_setup_idc_param(adapter);
+ if (err)
goto err_out_iounmap;
err = adapter->nic_ops->start_firmware(adapter);
@@ -1407,6 +1571,17 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_decr_ref;
}
+ if (qlcnic_read_mac_addr(adapter))
+ dev_warn(&pdev->dev, "failed to read mac addr\n");
+
+ if (adapter->portnum == 0) {
+ get_brd_name(adapter, brd_name);
+
+ pr_info("%s: %s Board Chip rev 0x%x\n",
+ module_name(THIS_MODULE),
+ brd_name, adapter->ahw.revision_id);
+ }
+
qlcnic_clear_stats(adapter);
qlcnic_setup_intr(adapter);
@@ -1430,6 +1605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
+ qlcnic_alloc_lb_filters_mem(adapter);
qlcnic_create_diag_entries(adapter);
return 0;
@@ -1438,7 +1614,7 @@ err_out_disable_msi:
qlcnic_teardown_intr(adapter);
err_out_decr_ref:
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
err_out_iounmap:
qlcnic_cleanup_pci_map(adapter);
@@ -1477,10 +1653,12 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
if (adapter->eswitch != NULL)
kfree(adapter->eswitch);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ qlcnic_free_lb_filters_mem(adapter);
+
qlcnic_teardown_intr(adapter);
qlcnic_remove_diag_entries(adapter);
@@ -1509,7 +1687,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev)
if (netif_running(netdev))
qlcnic_down(adapter, netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
@@ -1587,9 +1765,6 @@ static int qlcnic_open(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int err;
- if (adapter->driver_mismatch)
- return -EIO;
-
err = qlcnic_attach(adapter);
if (err)
return err;
@@ -1619,6 +1794,119 @@ static int qlcnic_close(struct net_device *netdev)
}
static void
+qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter)
+{
+ void *head;
+ int i;
+
+ if (!qlcnic_mac_learn)
+ return;
+
+ spin_lock_init(&adapter->mac_learn_lock);
+
+ head = kcalloc(QLCNIC_LB_MAX_FILTERS, sizeof(struct hlist_head),
+ GFP_KERNEL);
+ if (!head)
+ return;
+
+ adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS;
+ adapter->fhash.fhead = (struct hlist_head *)head;
+
+ for (i = 0; i < adapter->fhash.fmax; i++)
+ INIT_HLIST_HEAD(&adapter->fhash.fhead[i]);
+}
+
+static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter)
+{
+ if (adapter->fhash.fmax && adapter->fhash.fhead)
+ kfree(adapter->fhash.fhead);
+
+ adapter->fhash.fhead = NULL;
+ adapter->fhash.fmax = 0;
+}
+
+static void qlcnic_change_filter(struct qlcnic_adapter *adapter,
+ u64 uaddr, u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring)
+{
+ struct cmd_desc_type0 *hwdesc;
+ struct qlcnic_nic_req *req;
+ struct qlcnic_mac_req *mac_req;
+ u32 producer;
+ u64 word;
+
+ producer = tx_ring->producer;
+ hwdesc = &tx_ring->desc_head[tx_ring->producer];
+
+ req = (struct qlcnic_nic_req *)hwdesc;
+ memset(req, 0, sizeof(struct qlcnic_nic_req));
+ req->qhdr = cpu_to_le64(QLCNIC_REQUEST << 23);
+
+ word = QLCNIC_MAC_EVENT | ((u64)(adapter->portnum) << 16);
+ req->req_hdr = cpu_to_le64(word);
+
+ mac_req = (struct qlcnic_mac_req *)&(req->words[0]);
+ mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD;
+ memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN);
+
+ req->words[1] = cpu_to_le64(vlan_id);
+
+ tx_ring->producer = get_next_index(producer, tx_ring->num_desc);
+}
+
+#define QLCNIC_MAC_HASH(MAC)\
+ ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25))
+
+static void
+qlcnic_send_filter(struct qlcnic_adapter *adapter,
+ struct qlcnic_host_tx_ring *tx_ring,
+ struct cmd_desc_type0 *first_desc,
+ struct sk_buff *skb)
+{
+ struct ethhdr *phdr = (struct ethhdr *)(skb->data);
+ struct qlcnic_filter *fil, *tmp_fil;
+ struct hlist_node *tmp_hnode, *n;
+ struct hlist_head *head;
+ u64 src_addr = 0;
+ u16 vlan_id = 0;
+ u8 hindex;
+
+ if (!compare_ether_addr(phdr->h_source, adapter->mac_addr))
+ return;
+
+ if (adapter->fhash.fnum >= adapter->fhash.fmax)
+ return;
+
+ /* Only NPAR capable devices support vlan based learning*/
+ if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
+ vlan_id = first_desc->vlan_TCI;
+ memcpy(&src_addr, phdr->h_source, ETH_ALEN);
+ hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1);
+ head = &(adapter->fhash.fhead[hindex]);
+
+ hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) {
+ if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) &&
+ tmp_fil->vlan_id == vlan_id) {
+ tmp_fil->ftime = jiffies;
+ return;
+ }
+ }
+
+ fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC);
+ if (!fil)
+ return;
+
+ qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring);
+
+ fil->ftime = jiffies;
+ fil->vlan_id = vlan_id;
+ memcpy(fil->faddr, &src_addr, ETH_ALEN);
+ spin_lock(&adapter->mac_learn_lock);
+ hlist_add_head(&(fil->fnode), head);
+ adapter->fhash.fnum++;
+ spin_unlock(&adapter->mac_learn_lock);
+}
+
+static void
qlcnic_tso_check(struct net_device *netdev,
struct qlcnic_host_tx_ring *tx_ring,
struct cmd_desc_type0 *first_desc,
@@ -1626,26 +1914,13 @@ qlcnic_tso_check(struct net_device *netdev,
{
u8 opcode = TX_ETHER_PKT;
__be16 protocol = skb->protocol;
- u16 flags = 0, vid = 0;
- int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
+ u16 flags = 0;
+ int copied, offset, copy_len, hdr_len = 0, tso = 0;
struct cmd_desc_type0 *hwdesc;
struct vlan_ethhdr *vh;
struct qlcnic_adapter *adapter = netdev_priv(netdev);
u32 producer = tx_ring->producer;
-
- if (protocol == cpu_to_be16(ETH_P_8021Q)) {
-
- vh = (struct vlan_ethhdr *)skb->data;
- protocol = vh->h_vlan_encapsulated_proto;
- flags = FLAGS_VLAN_TAGGED;
-
- } else if (vlan_tx_tag_present(skb)) {
-
- flags = FLAGS_VLAN_OOB;
- vid = vlan_tx_tag_get(skb);
- qlcnic_set_tx_vlan_tci(first_desc, vid);
- vlan_oob = 1;
- }
+ int vlan_oob = first_desc->flags_opcode & cpu_to_le16(FLAGS_VLAN_OOB);
if (*(skb->data) & BIT_0) {
flags |= BIT_0;
@@ -1716,7 +1991,7 @@ qlcnic_tso_check(struct net_device *netdev,
vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
skb_copy_from_linear_data(skb, vh, 12);
vh->h_vlan_proto = htons(ETH_P_8021Q);
- vh->h_vlan_TCI = htons(vid);
+ vh->h_vlan_TCI = htons(first_desc->vlan_TCI);
skb_copy_from_linear_data_offset(skb, 12,
(char *)vh + 16, copy_len - 16);
@@ -1796,11 +2071,47 @@ out_err:
return -ENOMEM;
}
+static int
+qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter,
+ struct sk_buff *skb,
+ struct cmd_desc_type0 *first_desc)
+{
+ u8 opcode = 0;
+ u16 flags = 0;
+ __be16 protocol = skb->protocol;
+ struct vlan_ethhdr *vh;
+
+ if (protocol == cpu_to_be16(ETH_P_8021Q)) {
+ vh = (struct vlan_ethhdr *)skb->data;
+ protocol = vh->h_vlan_encapsulated_proto;
+ flags = FLAGS_VLAN_TAGGED;
+ qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI));
+ } else if (vlan_tx_tag_present(skb)) {
+ flags = FLAGS_VLAN_OOB;
+ qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb));
+ }
+ if (unlikely(adapter->pvid)) {
+ if (first_desc->vlan_TCI &&
+ !(adapter->flags & QLCNIC_TAGGING_ENABLED))
+ return -EIO;
+ if (first_desc->vlan_TCI &&
+ (adapter->flags & QLCNIC_TAGGING_ENABLED))
+ goto set_flags;
+
+ flags = FLAGS_VLAN_OOB;
+ qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid);
+ }
+set_flags:
+ qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
+ return 0;
+}
+
static inline void
qlcnic_clear_cmddesc(u64 *desc)
{
desc[0] = 0ULL;
desc[2] = 0ULL;
+ desc[7] = 0ULL;
}
netdev_tx_t
@@ -1812,6 +2123,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct qlcnic_skb_frag *buffrag;
struct cmd_desc_type0 *hwdesc, *first_desc;
struct pci_dev *pdev;
+ struct ethhdr *phdr;
int i, k;
u32 producer;
@@ -1823,6 +2135,13 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
+ if (adapter->flags & QLCNIC_MACSPOOF) {
+ phdr = (struct ethhdr *)skb->data;
+ if (compare_ether_addr(phdr->h_source,
+ adapter->mac_addr))
+ goto drop_packet;
+ }
+
frag_count = skb_shinfo(skb)->nr_frags + 1;
/* 4 fragments per cmd des */
@@ -1844,6 +2163,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
pdev = adapter->pdev;
+ first_desc = hwdesc = &tx_ring->desc_head[producer];
+ qlcnic_clear_cmddesc((u64 *)hwdesc);
+
+ if (qlcnic_check_tx_tagging(adapter, skb, first_desc))
+ goto drop_packet;
+
if (qlcnic_map_tx_skb(pdev, skb, pbuf)) {
adapter->stats.tx_dma_map_error++;
goto drop_packet;
@@ -1852,9 +2177,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
pbuf->skb = skb;
pbuf->frag_count = frag_count;
- first_desc = hwdesc = &tx_ring->desc_head[producer];
- qlcnic_clear_cmddesc((u64 *)hwdesc);
-
qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len);
qlcnic_set_tx_port(first_desc, adapter->portnum);
@@ -1893,6 +2215,9 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
qlcnic_tso_check(netdev, tx_ring, first_desc, skb);
+ if (qlcnic_mac_learn)
+ qlcnic_send_filter(adapter, tx_ring, first_desc, skb);
+
qlcnic_update_cmd_producer(adapter, tx_ring);
adapter->stats.txbytes += skb->len;
@@ -1947,14 +2272,14 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
struct net_device *netdev = adapter->netdev;
if (adapter->ahw.linkup && !linkup) {
- dev_info(&netdev->dev, "NIC Link is down\n");
+ netdev_info(netdev, "NIC Link is down\n");
adapter->ahw.linkup = 0;
if (netif_running(netdev)) {
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
} else if (!adapter->ahw.linkup && linkup) {
- dev_info(&netdev->dev, "NIC Link is up\n");
+ netdev_info(netdev, "NIC Link is up\n");
adapter->ahw.linkup = 1;
if (netif_running(netdev)) {
netif_carrier_on(netdev);
@@ -2258,18 +2583,22 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter)
}
static void
-qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter)
+qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
{
u32 val;
if (qlcnic_api_lock(adapter))
goto err;
- val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
QLC_DEV_CLR_REF_CNT(val, adapter->portnum);
- QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+ QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val);
- if (!(val & 0x11111111))
+ if (failed) {
+ QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED);
+ dev_info(&adapter->pdev->dev,
+ "Device state set to Failed. Please Reboot\n");
+ } else if (!(val & 0x11111111))
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD);
val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
@@ -2290,7 +2619,7 @@ qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
int act, state;
state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
- act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
if (((state & 0x11111111) == (act & 0x11111111)) ||
((act & 0x11111111) == ((state >> 1) & 0x11111111)))
@@ -2325,10 +2654,10 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
if (qlcnic_api_lock(adapter))
return -1;
- val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
+ val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
if (!(val & (1 << (portnum * 4)))) {
QLC_DEV_SET_REF_CNT(val, portnum);
- QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
+ QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val);
}
prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
@@ -2403,7 +2732,7 @@ qlcnic_fwinit_work(struct work_struct *work)
{
struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work);
- u32 dev_state = 0xf, npar_state;
+ u32 dev_state = 0xf;
if (qlcnic_api_lock(adapter))
goto err_ret;
@@ -2417,16 +2746,8 @@ qlcnic_fwinit_work(struct work_struct *work)
}
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
- npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
- if (npar_state == QLCNIC_DEV_NPAR_RDY) {
- qlcnic_api_unlock(adapter);
- goto wait_npar;
- } else {
- qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
- FW_POLL_DELAY);
- qlcnic_api_unlock(adapter);
- return;
- }
+ qlcnic_api_unlock(adapter);
+ goto wait_npar;
}
if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
@@ -2463,6 +2784,7 @@ skip_ack_check:
if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+ adapter->fw_wait_cnt = 0;
return;
}
goto err_ret;
@@ -2475,27 +2797,25 @@ wait_npar:
QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
switch (dev_state) {
- case QLCNIC_DEV_QUISCENT:
- case QLCNIC_DEV_NEED_QUISCENT:
- case QLCNIC_DEV_NEED_RESET:
- qlcnic_schedule_work(adapter,
- qlcnic_fwinit_work, FW_POLL_DELAY);
- return;
- case QLCNIC_DEV_FAILED:
- break;
-
- default:
+ case QLCNIC_DEV_READY:
if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
+ adapter->fw_wait_cnt = 0;
return;
}
+ case QLCNIC_DEV_FAILED:
+ break;
+ default:
+ qlcnic_schedule_work(adapter,
+ qlcnic_fwinit_work, FW_POLL_DELAY);
+ return;
}
err_ret:
dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u "
"fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt);
netif_device_attach(adapter->netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 0);
}
static void
@@ -2531,8 +2851,23 @@ err_ret:
dev_err(&adapter->pdev->dev, "detach failed; status=%d temp=%d\n",
status, adapter->temp);
netif_device_attach(netdev);
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 1);
+}
+
+/*Transit NPAR state to NON Operational */
+static void
+qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
+{
+ u32 state;
+
+ state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ if (state == QLCNIC_DEV_NPAR_NON_OPER)
+ return;
+ if (qlcnic_api_lock(adapter))
+ return;
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+ qlcnic_api_unlock(adapter);
}
/*Transit to RESET state from READY state only */
@@ -2553,6 +2888,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
qlcnic_idc_debug_info(adapter, 0);
}
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
qlcnic_api_unlock(adapter);
}
@@ -2560,21 +2896,11 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
static void
qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
{
- u32 state;
-
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
- return;
if (qlcnic_api_lock(adapter))
return;
- state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-
- if (state != QLCNIC_DEV_NPAR_RDY) {
- QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
- QLCNIC_DEV_NPAR_RDY);
- QLCDB(adapter, DRV, "NPAR READY state set\n");
- }
+ QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER);
+ QLCDB(adapter, DRV, "NPAR operational state set\n");
qlcnic_api_unlock(adapter);
}
@@ -2605,7 +2931,21 @@ qlcnic_attach_work(struct work_struct *work)
struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work);
struct net_device *netdev = adapter->netdev;
+ u32 npar_state;
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC) {
+ npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+ if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO)
+ qlcnic_clr_all_drv_state(adapter, 0);
+ else if (npar_state != QLCNIC_DEV_NPAR_OPER)
+ qlcnic_schedule_work(adapter, qlcnic_attach_work,
+ FW_POLL_DELAY);
+ else
+ goto attach;
+ QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n");
+ return;
+ }
+attach:
if (netif_running(netdev)) {
if (qlcnic_up(adapter, netdev))
goto done;
@@ -2626,7 +2966,7 @@ done:
static int
qlcnic_check_health(struct qlcnic_adapter *adapter)
{
- u32 state = 0, heartbit;
+ u32 state = 0, heartbeat;
struct net_device *netdev = adapter->netdev;
if (qlcnic_check_temp(adapter))
@@ -2636,12 +2976,15 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
qlcnic_dev_request_reset(adapter);
state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
- if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT)
+ if (state == QLCNIC_DEV_NEED_RESET ||
+ state == QLCNIC_DEV_NEED_QUISCENT) {
+ qlcnic_set_npar_non_operational(adapter);
adapter->need_fw_reset = 1;
+ }
- heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
- if (heartbit != adapter->heartbit) {
- adapter->heartbit = heartbit;
+ heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
+ if (heartbeat != adapter->heartbeat) {
+ adapter->heartbeat = heartbeat;
adapter->fw_fail_cnt = 0;
if (adapter->need_fw_reset)
goto detach;
@@ -2692,6 +3035,9 @@ qlcnic_fw_poll_work(struct work_struct *work)
if (qlcnic_check_health(adapter))
return;
+ if (adapter->fhash.fnum)
+ qlcnic_prune_lb_filters(adapter);
+
reschedule:
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
}
@@ -2738,7 +3084,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
if (qlcnic_api_lock(adapter))
return -EINVAL;
- if (first_func) {
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
adapter->need_fw_reset = 1;
set_bit(__QLCNIC_START_FW, &adapter->state);
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
@@ -2756,7 +3102,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
if (netif_running(netdev)) {
err = qlcnic_attach(adapter);
if (err) {
- qlcnic_clr_all_drv_state(adapter);
+ qlcnic_clr_all_drv_state(adapter, 1);
clear_bit(__QLCNIC_AER, &adapter->state);
netif_device_attach(netdev);
return err;
@@ -2822,7 +3168,6 @@ static void qlcnic_io_resume(struct pci_dev *pdev)
FW_POLL_DELAY);
}
-
static int
qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
{
@@ -2832,8 +3177,20 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
if (err)
return err;
+ err = qlcnic_check_npar_opertional(adapter);
+ if (err)
+ return err;
+
+ err = qlcnic_initialize_nic(adapter);
+ if (err)
+ return err;
+
qlcnic_check_options(adapter);
+ err = qlcnic_set_eswitch_port_config(adapter);
+ if (err)
+ return err;
+
adapter->need_fw_reset = 0;
return err;
@@ -3093,9 +3450,6 @@ validate_pm_config(struct qlcnic_adapter *adapter,
if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
return QL_STATUS_INVALID_PARAM;
- if (!IS_VALID_MODE(pm_cfg[i].action))
- return QL_STATUS_INVALID_PARAM;
-
s_esw_id = adapter->npars[src_pci_func].phy_port;
d_esw_id = adapter->npars[dest_pci_func].phy_port;
@@ -3129,7 +3483,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
return ret;
for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func;
- action = pm_cfg[i].action;
+ action = !!pm_cfg[i].action;
id = adapter->npars[pci_func].phy_port;
ret = qlcnic_config_port_mirroring(adapter, id,
action, pci_func);
@@ -3140,7 +3494,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
for (i = 0; i < count; i++) {
pci_func = pm_cfg[i].pci_func;
id = adapter->npars[pci_func].phy_port;
- adapter->npars[pci_func].enable_pm = pm_cfg[i].action;
+ adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
adapter->npars[pci_func].dest_npar = id;
}
return size;
@@ -3172,30 +3526,45 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
static int
validate_esw_config(struct qlcnic_adapter *adapter,
- struct qlcnic_esw_func_cfg *esw_cfg, int count)
+ struct qlcnic_esw_func_cfg *esw_cfg, int count)
{
+ u32 op_mode;
u8 pci_func;
int i;
+ op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE);
+
for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func;
if (pci_func >= QLCNIC_MAX_PCI_FUNC)
return QL_STATUS_INVALID_PARAM;
- if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
- return QL_STATUS_INVALID_PARAM;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
+ return QL_STATUS_INVALID_PARAM;
- if (esw_cfg->host_vlan_tag == 1)
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ if (QLC_DEV_GET_DRV(op_mode, pci_func) !=
+ QLCNIC_NON_PRIV_FUNC) {
+ esw_cfg[i].mac_anti_spoof = 0;
+ esw_cfg[i].mac_override = 1;
+ }
+ break;
+ case QLCNIC_ADD_VLAN:
if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
return QL_STATUS_INVALID_PARAM;
-
- if (!IS_VALID_MODE(esw_cfg[i].promisc_mode)
- || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag)
- || !IS_VALID_MODE(esw_cfg[i].mac_learning)
- || !IS_VALID_MODE(esw_cfg[i].discard_tagged))
+ if (!esw_cfg[i].op_type)
+ return QL_STATUS_INVALID_PARAM;
+ break;
+ case QLCNIC_DEL_VLAN:
+ if (!esw_cfg[i].op_type)
+ return QL_STATUS_INVALID_PARAM;
+ break;
+ default:
return QL_STATUS_INVALID_PARAM;
+ }
}
-
return 0;
}
@@ -3206,8 +3575,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg *esw_cfg;
+ struct qlcnic_npar_info *npar;
int count, rem, i, ret;
- u8 id, pci_func;
+ u8 pci_func, op_mode = 0;
count = size / sizeof(struct qlcnic_esw_func_cfg);
rem = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3220,30 +3590,55 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
return ret;
for (i = 0; i < count; i++) {
- pci_func = esw_cfg[i].pci_func;
- id = adapter->npars[pci_func].phy_port;
- ret = qlcnic_config_switch_port(adapter, id,
- esw_cfg[i].host_vlan_tag,
- esw_cfg[i].discard_tagged,
- esw_cfg[i].promisc_mode,
- esw_cfg[i].mac_learning,
- esw_cfg[i].pci_func,
- esw_cfg[i].vlan_id);
- if (ret)
- return ret;
+ if (adapter->op_mode == QLCNIC_MGMT_FUNC)
+ if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
+ return QL_STATUS_INVALID_PARAM;
+
+ if (adapter->ahw.pci_func != esw_cfg[i].pci_func)
+ continue;
+
+ op_mode = esw_cfg[i].op_mode;
+ qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
+ esw_cfg[i].op_mode = op_mode;
+ esw_cfg[i].pci_func = adapter->ahw.pci_func;
+
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
+ break;
+ case QLCNIC_ADD_VLAN:
+ qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
+ break;
+ case QLCNIC_DEL_VLAN:
+ esw_cfg[i].vlan_id = 0;
+ qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
+ break;
+ }
}
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+ goto out;
+
for (i = 0; i < count; i++) {
pci_func = esw_cfg[i].pci_func;
- adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode;
- adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning;
- adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id;
- adapter->npars[pci_func].discard_tagged =
- esw_cfg[i].discard_tagged;
- adapter->npars[pci_func].host_vlan_tag =
- esw_cfg[i].host_vlan_tag;
+ npar = &adapter->npars[pci_func];
+ switch (esw_cfg[i].op_mode) {
+ case QLCNIC_PORT_DEFAULTS:
+ npar->promisc_mode = esw_cfg[i].promisc_mode;
+ npar->mac_override = esw_cfg[i].mac_override;
+ npar->offload_flags = esw_cfg[i].offload_flags;
+ npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
+ npar->discard_tagged = esw_cfg[i].discard_tagged;
+ break;
+ case QLCNIC_ADD_VLAN:
+ npar->pvid = esw_cfg[i].vlan_id;
+ break;
+ case QLCNIC_DEL_VLAN:
+ npar->pvid = 0;
+ break;
+ }
}
-
+out:
return size;
}
@@ -3254,7 +3649,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
struct device *dev = container_of(kobj, struct device, kobj);
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
- int i;
+ u8 i;
if (size != sizeof(esw_cfg))
return QL_STATUS_INVALID_PARAM;
@@ -3262,12 +3657,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
continue;
-
- esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag;
- esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode;
- esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged;
- esw_cfg[i].vlan_id = adapter->npars[i].vlan_id;
- esw_cfg[i].mac_learning = adapter->npars[i].mac_learning;
+ esw_cfg[i].pci_func = i;
+ if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
+ return QL_STATUS_INVALID_PARAM;
}
memcpy(buf, &esw_cfg, size);
@@ -3370,6 +3762,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
}
static ssize_t
+qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ struct qlcnic_esw_statistics port_stats;
+ int ret;
+
+ if (size != sizeof(struct qlcnic_esw_statistics))
+ return QL_STATUS_INVALID_PARAM;
+
+ if (offset >= QLCNIC_MAX_PCI_FUNC)
+ return QL_STATUS_INVALID_PARAM;
+
+ memset(&port_stats, 0, size);
+ ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+ &port_stats.rx);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+ &port_stats.tx);
+ if (ret)
+ return ret;
+
+ memcpy(buf, &port_stats, size);
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ struct qlcnic_esw_statistics esw_stats;
+ int ret;
+
+ if (size != sizeof(struct qlcnic_esw_statistics))
+ return QL_STATUS_INVALID_PARAM;
+
+ if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+ return QL_STATUS_INVALID_PARAM;
+
+ memset(&esw_stats, 0, size);
+ ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+ &esw_stats.rx);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+ &esw_stats.tx);
+ if (ret)
+ return ret;
+
+ memcpy(buf, &esw_stats, size);
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ int ret;
+
+ if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+ return QL_STATUS_INVALID_PARAM;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+ QLCNIC_QUERY_RX_COUNTER);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+ QLCNIC_QUERY_TX_COUNTER);
+ if (ret)
+ return ret;
+
+ return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ int ret;
+
+ if (offset >= QLCNIC_MAX_PCI_FUNC)
+ return QL_STATUS_INVALID_PARAM;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+ QLCNIC_QUERY_RX_COUNTER);
+ if (ret)
+ return ret;
+
+ ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+ QLCNIC_QUERY_TX_COUNTER);
+ if (ret)
+ return ret;
+
+ return size;
+}
+
+static ssize_t
qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj,
struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
{
@@ -3418,6 +3919,20 @@ static struct bin_attribute bin_attr_pci_config = {
.write = NULL,
};
+static struct bin_attribute bin_attr_port_stats = {
+ .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
+ .size = 0,
+ .read = qlcnic_sysfs_get_port_stats,
+ .write = qlcnic_sysfs_clear_port_stats,
+};
+
+static struct bin_attribute bin_attr_esw_stats = {
+ .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
+ .size = 0,
+ .read = qlcnic_sysfs_get_esw_stats,
+ .write = qlcnic_sysfs_clear_esw_stats,
+};
+
static struct bin_attribute bin_attr_esw_config = {
.attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
@@ -3457,6 +3972,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
+ if (device_create_bin_file(dev, &bin_attr_port_stats))
+ dev_info(dev, "failed to create port stats sysfs entry");
+
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
return;
if (device_create_file(dev, &dev_attr_diag_mode))
@@ -3465,18 +3983,20 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
dev_info(dev, "failed to create crb sysfs entry\n");
if (device_create_bin_file(dev, &bin_attr_mem))
dev_info(dev, "failed to create mem sysfs entry\n");
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode != QLCNIC_MGMT_FUNC)
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return;
+ if (device_create_bin_file(dev, &bin_attr_esw_config))
+ dev_info(dev, "failed to create esw config sysfs entry");
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return;
if (device_create_bin_file(dev, &bin_attr_pci_config))
dev_info(dev, "failed to create pci config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_npar_config))
dev_info(dev, "failed to create npar config sysfs entry");
- if (device_create_bin_file(dev, &bin_attr_esw_config))
- dev_info(dev, "failed to create esw config sysfs entry");
if (device_create_bin_file(dev, &bin_attr_pm_config))
dev_info(dev, "failed to create pm config sysfs entry");
-
+ if (device_create_bin_file(dev, &bin_attr_esw_stats))
+ dev_info(dev, "failed to create eswitch stats sysfs entry");
}
static void
@@ -3484,18 +4004,22 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
+ device_remove_bin_file(dev, &bin_attr_port_stats);
+
if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
return;
device_remove_file(dev, &dev_attr_diag_mode);
device_remove_bin_file(dev, &bin_attr_crb);
device_remove_bin_file(dev, &bin_attr_mem);
- if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
- adapter->op_mode != QLCNIC_MGMT_FUNC)
+ if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
+ return;
+ device_remove_bin_file(dev, &bin_attr_esw_config);
+ if (adapter->op_mode != QLCNIC_MGMT_FUNC)
return;
device_remove_bin_file(dev, &bin_attr_pci_config);
device_remove_bin_file(dev, &bin_attr_npar_config);
- device_remove_bin_file(dev, &bin_attr_esw_config);
device_remove_bin_file(dev, &bin_attr_pm_config);
+ device_remove_bin_file(dev, &bin_attr_esw_stats);
}
#ifdef CONFIG_INET
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 5f89e83501f4..4ffebe83d883 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
rx_ring->rx_packets++;
rx_ring->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (qdev->rx_csum &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
@@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
rx_ring->rx_packets++;
rx_ring->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* If rx checksum is on, and there are no
* csum or frame errors.
@@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
}
skb->protocol = eth_type_trans(skb, ndev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* If rx checksum is on, and there are no
* csum or frame errors.
@@ -2222,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
ql_update_cq(rx_ring);
prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
+ if (!net_rsp)
+ return 0;
ql_write_cq_idx(rx_ring);
tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
- if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
- net_rsp != NULL) {
+ if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) {
if (atomic_read(&tx_ring->queue_stopped) &&
(atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
/*
@@ -3888,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev)
return status;
}
-static int ql_adapter_down(struct ql_adapter *qdev)
+static void ql_cancel_all_work_sync(struct ql_adapter *qdev)
{
- int i, status = 0;
-
- ql_link_off(qdev);
/* Don't kill the reset worker thread if we
* are in the process of recovery.
@@ -3904,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->mpi_idc_work);
cancel_delayed_work_sync(&qdev->mpi_core_to_log);
cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+}
+
+static int ql_adapter_down(struct ql_adapter *qdev)
+{
+ int i, status = 0;
+
+ ql_link_off(qdev);
+
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
napi_disable(&qdev->rx_ring[i].napi);
@@ -4726,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
del_timer_sync(&qdev->timer);
+ ql_cancel_all_work_sync(qdev);
unregister_netdev(ndev);
ql_release_all(pdev);
pci_disable_device(pdev);
@@ -4745,13 +4753,7 @@ static void ql_eeh_close(struct net_device *ndev)
/* Disabling the timer */
del_timer_sync(&qdev->timer);
- if (test_bit(QL_ADAPTER_UP, &qdev->flags))
- cancel_delayed_work_sync(&qdev->asic_reset_work);
- cancel_delayed_work_sync(&qdev->mpi_reset_work);
- cancel_delayed_work_sync(&qdev->mpi_work);
- cancel_delayed_work_sync(&qdev->mpi_idc_work);
- cancel_delayed_work_sync(&qdev->mpi_core_to_log);
- cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
netif_napi_del(&qdev->rx_ring[i].napi);
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 142c381e1d73..63db065508f4 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -200,7 +200,7 @@ struct r6040_private {
int old_duplex;
};
-static char version[] __devinitdata = KERN_INFO DRV_NAME
+static char version[] __devinitdata = DRV_NAME
": RDC R6040 NAPI net driver,"
"version "DRV_VERSION " (" DRV_RELDATE ")";
@@ -224,7 +224,8 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg)
}
/* Write a word data from PHY Chip */
-static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
+static void r6040_phy_write(void __iomem *ioaddr,
+ int phy_addr, int reg, u16 val)
{
int limit = 2048;
u16 cmd;
@@ -348,8 +349,8 @@ static int r6040_alloc_rxbufs(struct net_device *dev)
}
desc->skb_ptr = skb;
desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
- desc->skb_ptr->data,
- MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+ desc->skb_ptr->data,
+ MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
desc->status = DSC_OWNER_MAC;
desc = desc->vndescp;
} while (desc != lp->rx_ring);
@@ -491,12 +492,14 @@ static int r6040_close(struct net_device *dev)
/* Free Descriptor memory */
if (lp->rx_ring) {
- pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
+ pci_free_consistent(pdev,
+ RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
lp->rx_ring = NULL;
}
if (lp->tx_ring) {
- pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
+ pci_free_consistent(pdev,
+ TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
lp->tx_ring = NULL;
}
@@ -547,7 +550,7 @@ static int r6040_rx(struct net_device *dev, int limit)
}
goto next_descr;
}
-
+
/* Packet successfully received */
new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
if (!new_skb) {
@@ -556,13 +559,13 @@ static int r6040_rx(struct net_device *dev, int limit)
}
skb_ptr = descptr->skb_ptr;
skb_ptr->dev = priv->dev;
-
+
/* Do not count the CRC */
skb_put(skb_ptr, descptr->len - 4);
pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
-
+
/* Send to upper layer */
netif_receive_skb(skb_ptr);
dev->stats.rx_packets++;
@@ -710,8 +713,10 @@ static int r6040_up(struct net_device *dev)
return ret;
/* improve performance (by RDC guys) */
- r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
- r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
+ r6040_phy_write(ioaddr, 30, 17,
+ (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
+ r6040_phy_write(ioaddr, 30, 17,
+ ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
r6040_phy_write(ioaddr, 0, 19, 0x0000);
r6040_phy_write(ioaddr, 0, 30, 0x01F0);
@@ -751,7 +756,7 @@ static int r6040_open(struct net_device *dev)
ret = request_irq(dev->irq, r6040_interrupt,
IRQF_SHARED, dev->name, dev);
if (ret)
- return ret;
+ goto out;
/* Set MAC address */
r6040_mac_address(dev);
@@ -759,30 +764,37 @@ static int r6040_open(struct net_device *dev)
/* Allocate Descriptor memory */
lp->rx_ring =
pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma);
- if (!lp->rx_ring)
- return -ENOMEM;
+ if (!lp->rx_ring) {
+ ret = -ENOMEM;
+ goto err_free_irq;
+ }
lp->tx_ring =
pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma);
if (!lp->tx_ring) {
- pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
- lp->rx_ring_dma);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_free_rx_ring;
}
ret = r6040_up(dev);
- if (ret) {
- pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
- lp->tx_ring_dma);
- pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
- lp->rx_ring_dma);
- return ret;
- }
+ if (ret)
+ goto err_free_tx_ring;
napi_enable(&lp->napi);
netif_start_queue(dev);
return 0;
+
+err_free_tx_ring:
+ pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
+ lp->tx_ring_dma);
+err_free_rx_ring:
+ pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
+ lp->rx_ring_dma);
+err_free_irq:
+ free_irq(dev->irq, dev);
+out:
+ return ret;
}
static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
@@ -946,7 +958,7 @@ static const struct net_device_ops r6040_netdev_ops = {
.ndo_set_multicast_list = r6040_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = r6040_ioctl,
.ndo_tx_timeout = r6040_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1039,7 +1051,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
u16 *adrp;
int i;
- printk("%s\n", version);
+ pr_info("%s\n", version);
err = pci_enable_device(pdev);
if (err)
@@ -1113,7 +1125,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
/* Some bootloader/BIOSes do not initialize
* MAC address, warn about that */
if (!(adrp[0] || adrp[1] || adrp[2])) {
- netdev_warn(dev, "MAC address not initialized, generating random\n");
+ netdev_warn(dev, "MAC address not initialized, "
+ "generating random\n");
random_ether_addr(dev->dev_addr);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 078bbf4e6f19..54900332f12d 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1076,7 +1076,12 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
int ret;
if (vlgrp && (opts2 & RxVlanTag)) {
- __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling);
+ u16 vtag = swab16(opts2 & 0xffff);
+
+ if (likely(polling))
+ vlan_gro_receive(&tp->napi, vlgrp, vtag, skb);
+ else
+ __vlan_hwaccel_rx(skb, vlgrp, vtag, polling);
ret = 0;
} else
ret = -1;
@@ -3186,6 +3191,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
+ dev->features |= NETIF_F_GRO;
tp->intr_mask = 0xffff;
tp->align = cfg->align;
@@ -4450,9 +4456,8 @@ static inline int rtl8169_fragmented_frame(u32 status)
return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
}
-static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
+static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
{
- u32 opts1 = le32_to_cpu(desc->opts1);
u32 status = opts1 & RxProtoMask;
if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
@@ -4460,7 +4465,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
((status == RxProtoIP) && !(opts1 & IPFail)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
@@ -4546,8 +4551,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
continue;
}
- rtl8169_rx_csum(skb, desc);
-
if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
pci_dma_sync_single_for_device(pdev, addr,
pkt_size, PCI_DMA_FROMDEVICE);
@@ -4558,12 +4561,13 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
tp->Rx_skbuff[entry] = NULL;
}
+ rtl8169_rx_csum(skb, status);
skb_put(skb, pkt_size);
skb->protocol = eth_type_trans(skb, dev);
if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
if (likely(polling))
- netif_receive_skb(skb);
+ napi_gro_receive(&tp->napi, skb);
else
netif_rx(skb);
}
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index e26e107f93e0..e68c941926f1 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1245,7 +1245,7 @@ static int rr_open(struct net_device *dev)
init_timer(&rrpriv->timer);
rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */
rrpriv->timer.data = (unsigned long)dev;
- rrpriv->timer.function = &rr_timer; /* timer handler */
+ rrpriv->timer.function = rr_timer; /* timer handler */
add_timer(&rrpriv->timer);
netif_start_queue(dev);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 18bc5b718bbb..c70ad515383a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -38,8 +38,6 @@
* Tx descriptors that can be associated with each corresponding FIFO.
* intr_type: This defines the type of interrupt. The values can be 0(INTA),
* 2(MSI_X). Default value is '2(MSI_X)'
- * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
- * Possible values '1' for enable '0' for disable. Default is '0'
* lro_max_pkts: This parameter defines maximum number of packets can be
* aggregated as a single large packet
* napi: This parameter used to enable/disable NAPI (polling Rx)
@@ -90,7 +88,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.26"
+#define DRV_VERSION "2.0.26.27"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -496,8 +494,6 @@ S2IO_PARM_INT(rxsync_frequency, 3);
/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
S2IO_PARM_INT(intr_type, 2);
/* Large receive offload feature */
-static unsigned int lro_enable = 1;
-module_param_named(lro, lro_enable, uint, 0);
/* Max pkts to be aggregated by LRO at one time. If not specified,
* aggregation happens until we hit max IP pkt size(64K)
@@ -5124,8 +5120,6 @@ static void s2io_set_multicast(struct net_device *dev)
/* Create the new Rx filter list and update the same in H/W. */
i = 0;
netdev_for_each_mc_addr(ha, dev) {
- memcpy(sp->usr_addrs[i].addr, ha->addr,
- ETH_ALEN);
mac_addr = 0;
for (j = 0; j < ETH_ALEN; j++) {
mac_addr |= ha->addr[j];
@@ -6735,13 +6729,10 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
return -EINVAL;
if (data & ETH_FLAG_LRO) {
- if (lro_enable) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- changed = 1;
- }
- } else
- rc = -EINVAL;
+ if (!(dev->features & NETIF_F_LRO)) {
+ dev->features |= NETIF_F_LRO;
+ changed = 1;
+ }
} else if (dev->features & NETIF_F_LRO) {
dev->features &= ~NETIF_F_LRO;
changed = 1;
@@ -6750,7 +6741,6 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
if (changed && netif_running(dev)) {
s2io_stop_all_tx_queue(sp);
s2io_card_down(sp);
- sp->lro = !!(dev->features & NETIF_F_LRO);
rc = s2io_card_up(sp);
if (rc)
s2io_reset(sp);
@@ -7307,7 +7297,7 @@ static int s2io_card_up(struct s2io_nic *sp)
struct ring_info *ring = &mac_control->rings[i];
ring->mtu = dev->mtu;
- ring->lro = sp->lro;
+ ring->lro = !!(dev->features & NETIF_F_LRO);
ret = fill_rx_buffers(sp, ring, 1);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
@@ -7341,7 +7331,7 @@ static int s2io_card_up(struct s2io_nic *sp)
/* Setting its receive mode */
s2io_set_multicast(dev);
- if (sp->lro) {
+ if (dev->features & NETIF_F_LRO) {
/* Initialize max aggregatable pkts per session based on MTU */
sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
/* Check if we can use (if specified) user provided value */
@@ -7613,10 +7603,10 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
* Packet with erroneous checksum, let the
* upper layers deal with it.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
swstats->mem_freed += skb->truesize;
send_up:
@@ -7911,7 +7901,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
else
sp->device_type = XFRAME_I_DEVICE;
- sp->lro = lro_enable;
/* Initialize some PCI/PCI-X fields of the NIC. */
s2io_init_pci(sp);
@@ -8047,8 +8036,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->netdev_ops = &s2io_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- if (lro_enable)
- dev->features |= NETIF_F_LRO;
+ dev->features |= NETIF_F_LRO;
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
if (sp->high_dma_flag == true)
dev->features |= NETIF_F_HIGHDMA;
@@ -8283,9 +8271,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->name);
}
- if (sp->lro)
- DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
- dev->name);
+ DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
+ dev->name);
if (ufo)
DBG_PRINT(ERR_DBG,
"%s: UDP Fragmentation Offload(UFO) enabled\n",
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 0af033533905..00b8614efe48 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -816,12 +816,6 @@ struct mac_info {
struct stat_block *stats_info; /* Logical address of the stat block */
};
-/* structure representing the user defined MAC addresses */
-struct usr_addr {
- char addr[ETH_ALEN];
- int usage_cnt;
-};
-
/* Default Tunable parameters of the NIC. */
#define DEFAULT_FIFO_0_LEN 4096
#define DEFAULT_FIFO_1_7_LEN 512
@@ -894,9 +888,7 @@ struct s2io_nic {
#define ALL_MULTI 2
#define MAX_ADDRS_SUPPORTED 64
- u16 usr_addr_count;
u16 mc_addr_count;
- struct usr_addr usr_addrs[256];
u16 m_cast_flg;
u16 all_multi_pos;
@@ -971,7 +963,6 @@ struct s2io_nic {
unsigned long clubbed_frms_cnt;
unsigned long sending_both;
- u8 lro;
u16 lro_max_aggr_per_sess;
volatile unsigned long state;
u64 general_int_mask;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 8e6bd45b9f31..d8249d7653c6 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -1170,7 +1170,7 @@ again:
sb->ip_summed = CHECKSUM_UNNECESSARY;
/* don't need to set sb->csum */
} else {
- sb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(sb);
}
}
prefetch(sb->data);
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 8c4067af32b0..31b92f5f32cb 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1251,16 +1251,6 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
return 0;
}
-static void sc92031_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct sc92031_priv *priv = netdev_priv(dev);
- struct pci_dev *pdev = priv->pdev;
-
- strcpy(drvinfo->driver, SC92031_NAME);
- strcpy(drvinfo->bus_info, pci_name(pdev));
-}
-
static void sc92031_ethtool_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wolinfo)
{
@@ -1382,7 +1372,6 @@ static void sc92031_ethtool_get_ethtool_stats(struct net_device *dev,
static const struct ethtool_ops sc92031_ethtool_ops = {
.get_settings = sc92031_ethtool_get_settings,
.set_settings = sc92031_ethtool_set_settings,
- .get_drvinfo = sc92031_ethtool_get_drvinfo,
.get_wol = sc92031_ethtool_get_wol,
.set_wol = sc92031_ethtool_set_wol,
.nway_reset = sc92031_ethtool_nway_reset,
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index ba674c5ca29e..f702f1fb63b6 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -114,7 +114,7 @@ static struct workqueue_struct *reset_workqueue;
* This is only used in MSI-X interrupt mode
*/
static unsigned int separate_tx_channels;
-module_param(separate_tx_channels, uint, 0644);
+module_param(separate_tx_channels, uint, 0444);
MODULE_PARM_DESC(separate_tx_channels,
"Use separate channels for TX and RX");
@@ -201,10 +201,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
* Utility functions and prototypes
*
*************************************************************************/
-static void efx_remove_channel(struct efx_channel *channel);
+
+static void efx_remove_channels(struct efx_nic *efx);
static void efx_remove_port(struct efx_nic *efx);
static void efx_fini_napi(struct efx_nic *efx);
-static void efx_fini_channels(struct efx_nic *efx);
+static void efx_fini_struct(struct efx_nic *efx);
+static void efx_start_all(struct efx_nic *efx);
+static void efx_stop_all(struct efx_nic *efx);
#define EFX_ASSERT_RESET_SERIALISED(efx) \
do { \
@@ -248,7 +251,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
efx_rx_strategy(channel);
- efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
+ efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
return spent;
}
@@ -334,6 +337,7 @@ void efx_process_channel_now(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ BUG_ON(channel->channel >= efx->n_channels);
BUG_ON(!channel->enabled);
/* Disable interrupts and wait for ISRs to complete */
@@ -347,7 +351,7 @@ void efx_process_channel_now(struct efx_channel *channel)
napi_disable(&channel->napi_str);
/* Poll the channel */
- efx_process_channel(channel, EFX_EVQ_SIZE);
+ efx_process_channel(channel, channel->eventq_mask + 1);
/* Ack the eventq. This may cause an interrupt to be generated
* when they are reenabled */
@@ -364,9 +368,18 @@ void efx_process_channel_now(struct efx_channel *channel)
*/
static int efx_probe_eventq(struct efx_channel *channel)
{
+ struct efx_nic *efx = channel->efx;
+ unsigned long entries;
+
netif_dbg(channel->efx, probe, channel->efx->net_dev,
"chan %d create event queue\n", channel->channel);
+ /* Build an event queue with room for one event per tx and rx buffer,
+ * plus some extra for link state events and MCDI completions. */
+ entries = roundup_pow_of_two(efx->rxq_entries + efx->txq_entries + 128);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_EVQ_SIZE);
+ channel->eventq_mask = max(entries, EFX_MIN_EVQ_SIZE) - 1;
+
return efx_nic_probe_eventq(channel);
}
@@ -403,6 +416,63 @@ static void efx_remove_eventq(struct efx_channel *channel)
*
*************************************************************************/
+/* Allocate and initialise a channel structure, optionally copying
+ * parameters (but not resources) from an old channel structure. */
+static struct efx_channel *
+efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
+{
+ struct efx_channel *channel;
+ struct efx_rx_queue *rx_queue;
+ struct efx_tx_queue *tx_queue;
+ int j;
+
+ if (old_channel) {
+ channel = kmalloc(sizeof(*channel), GFP_KERNEL);
+ if (!channel)
+ return NULL;
+
+ *channel = *old_channel;
+
+ memset(&channel->eventq, 0, sizeof(channel->eventq));
+
+ rx_queue = &channel->rx_queue;
+ rx_queue->buffer = NULL;
+ memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd));
+
+ for (j = 0; j < EFX_TXQ_TYPES; j++) {
+ tx_queue = &channel->tx_queue[j];
+ if (tx_queue->channel)
+ tx_queue->channel = channel;
+ tx_queue->buffer = NULL;
+ memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
+ }
+ } else {
+ channel = kzalloc(sizeof(*channel), GFP_KERNEL);
+ if (!channel)
+ return NULL;
+
+ channel->efx = efx;
+ channel->channel = i;
+
+ for (j = 0; j < EFX_TXQ_TYPES; j++) {
+ tx_queue = &channel->tx_queue[j];
+ tx_queue->efx = efx;
+ tx_queue->queue = i * EFX_TXQ_TYPES + j;
+ tx_queue->channel = channel;
+ }
+ }
+
+ spin_lock_init(&channel->tx_stop_lock);
+ atomic_set(&channel->tx_stop_count, 1);
+
+ rx_queue = &channel->rx_queue;
+ rx_queue->efx = efx;
+ setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
+ (unsigned long)rx_queue);
+
+ return channel;
+}
+
static int efx_probe_channel(struct efx_channel *channel)
{
struct efx_tx_queue *tx_queue;
@@ -459,11 +529,38 @@ static void efx_set_channel_names(struct efx_nic *efx)
number -= efx->n_rx_channels;
}
}
- snprintf(channel->name, sizeof(channel->name),
+ snprintf(efx->channel_name[channel->channel],
+ sizeof(efx->channel_name[0]),
"%s%s-%d", efx->name, type, number);
}
}
+static int efx_probe_channels(struct efx_nic *efx)
+{
+ struct efx_channel *channel;
+ int rc;
+
+ /* Restart special buffer allocation */
+ efx->next_buffer_table = 0;
+
+ efx_for_each_channel(channel, efx) {
+ rc = efx_probe_channel(channel);
+ if (rc) {
+ netif_err(efx, probe, efx->net_dev,
+ "failed to create channel %d\n",
+ channel->channel);
+ goto fail;
+ }
+ }
+ efx_set_channel_names(efx);
+
+ return 0;
+
+fail:
+ efx_remove_channels(efx);
+ return rc;
+}
+
/* Channels are shutdown and reinitialised whilst the NIC is running
* to propagate configuration changes (mtu, checksum offload), or
* to clear hardware error conditions
@@ -601,6 +698,75 @@ static void efx_remove_channel(struct efx_channel *channel)
efx_remove_eventq(channel);
}
+static void efx_remove_channels(struct efx_nic *efx)
+{
+ struct efx_channel *channel;
+
+ efx_for_each_channel(channel, efx)
+ efx_remove_channel(channel);
+}
+
+int
+efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
+{
+ struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel;
+ u32 old_rxq_entries, old_txq_entries;
+ unsigned i;
+ int rc;
+
+ efx_stop_all(efx);
+ efx_fini_channels(efx);
+
+ /* Clone channels */
+ memset(other_channel, 0, sizeof(other_channel));
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx_alloc_channel(efx, i, efx->channel[i]);
+ if (!channel) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ other_channel[i] = channel;
+ }
+
+ /* Swap entry counts and channel pointers */
+ old_rxq_entries = efx->rxq_entries;
+ old_txq_entries = efx->txq_entries;
+ efx->rxq_entries = rxq_entries;
+ efx->txq_entries = txq_entries;
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx->channel[i];
+ efx->channel[i] = other_channel[i];
+ other_channel[i] = channel;
+ }
+
+ rc = efx_probe_channels(efx);
+ if (rc)
+ goto rollback;
+
+ /* Destroy old channels */
+ for (i = 0; i < efx->n_channels; i++)
+ efx_remove_channel(other_channel[i]);
+out:
+ /* Free unused channel structures */
+ for (i = 0; i < efx->n_channels; i++)
+ kfree(other_channel[i]);
+
+ efx_init_channels(efx);
+ efx_start_all(efx);
+ return rc;
+
+rollback:
+ /* Swap back */
+ efx->rxq_entries = old_rxq_entries;
+ efx->txq_entries = old_txq_entries;
+ for (i = 0; i < efx->n_channels; i++) {
+ channel = efx->channel[i];
+ efx->channel[i] = other_channel[i];
+ other_channel[i] = channel;
+ }
+ goto out;
+}
+
void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
{
mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100));
@@ -761,7 +927,7 @@ static int efx_probe_port(struct efx_nic *efx)
/* Connect up MAC/PHY operations table */
rc = efx->type->probe_port(efx);
if (rc)
- goto err;
+ return rc;
/* Sanity check MAC address */
if (is_valid_ether_addr(efx->mac_address)) {
@@ -782,7 +948,7 @@ static int efx_probe_port(struct efx_nic *efx)
return 0;
err:
- efx_remove_port(efx);
+ efx->type->remove_port(efx);
return rc;
}
@@ -1050,7 +1216,8 @@ static void efx_probe_interrupts(struct efx_nic *efx)
efx->n_rx_channels = efx->n_channels;
}
for (i = 0; i < n_channels; i++)
- efx->channel[i].irq = xentries[i].vector;
+ efx_get_channel(efx, i)->irq =
+ xentries[i].vector;
} else {
/* Fall back to single channel MSI */
efx->interrupt_mode = EFX_INT_MODE_MSI;
@@ -1066,7 +1233,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)
efx->n_tx_channels = 1;
rc = pci_enable_msi(efx->pci_dev);
if (rc == 0) {
- efx->channel[0].irq = efx->pci_dev->irq;
+ efx_get_channel(efx, 0)->irq = efx->pci_dev->irq;
} else {
netif_err(efx, drv, efx->net_dev,
"could not enable MSI\n");
@@ -1097,26 +1264,32 @@ static void efx_remove_interrupts(struct efx_nic *efx)
efx->legacy_irq = 0;
}
+struct efx_tx_queue *
+efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
+{
+ unsigned tx_channel_offset =
+ separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+ EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels ||
+ type >= EFX_TXQ_TYPES);
+ return &efx->channel[tx_channel_offset + index]->tx_queue[type];
+}
+
static void efx_set_channels(struct efx_nic *efx)
{
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
unsigned tx_channel_offset =
separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+ /* Channel pointers were set in efx_init_struct() but we now
+ * need to clear them for TX queues in any RX-only channels. */
efx_for_each_channel(channel, efx) {
- if (channel->channel - tx_channel_offset < efx->n_tx_channels) {
- channel->tx_queue = &efx->tx_queue[
- (channel->channel - tx_channel_offset) *
- EFX_TXQ_TYPES];
+ if (channel->channel - tx_channel_offset >=
+ efx->n_tx_channels) {
efx_for_each_channel_tx_queue(tx_queue, channel)
- tx_queue->channel = channel;
+ tx_queue->channel = NULL;
}
}
-
- efx_for_each_rx_queue(rx_queue, efx)
- rx_queue->channel = &efx->channel[rx_queue->queue];
}
static int efx_probe_nic(struct efx_nic *efx)
@@ -1165,40 +1338,28 @@ static void efx_remove_nic(struct efx_nic *efx)
static int efx_probe_all(struct efx_nic *efx)
{
- struct efx_channel *channel;
int rc;
- /* Create NIC */
rc = efx_probe_nic(efx);
if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to create NIC\n");
goto fail1;
}
- /* Create port */
rc = efx_probe_port(efx);
if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to create port\n");
goto fail2;
}
- /* Create channels */
- efx_for_each_channel(channel, efx) {
- rc = efx_probe_channel(channel);
- if (rc) {
- netif_err(efx, probe, efx->net_dev,
- "failed to create channel %d\n",
- channel->channel);
- goto fail3;
- }
- }
- efx_set_channel_names(efx);
+ efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
+ rc = efx_probe_channels(efx);
+ if (rc)
+ goto fail3;
return 0;
fail3:
- efx_for_each_channel(channel, efx)
- efx_remove_channel(channel);
efx_remove_port(efx);
fail2:
efx_remove_nic(efx);
@@ -1328,10 +1489,7 @@ static void efx_stop_all(struct efx_nic *efx)
static void efx_remove_all(struct efx_nic *efx)
{
- struct efx_channel *channel;
-
- efx_for_each_channel(channel, efx)
- efx_remove_channel(channel);
+ efx_remove_channels(efx);
efx_remove_port(efx);
efx_remove_nic(efx);
}
@@ -1355,20 +1513,20 @@ static unsigned irq_mod_ticks(int usecs, int resolution)
void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
bool rx_adaptive)
{
- struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
+ struct efx_channel *channel;
unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION);
unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION);
EFX_ASSERT_RESET_SERIALISED(efx);
- efx_for_each_tx_queue(tx_queue, efx)
- tx_queue->channel->irq_moderation = tx_ticks;
-
efx->irq_rx_adaptive = rx_adaptive;
efx->irq_rx_moderation = rx_ticks;
- efx_for_each_rx_queue(rx_queue, efx)
- rx_queue->channel->irq_moderation = rx_ticks;
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_get_rx_queue(channel))
+ channel->irq_moderation = rx_ticks;
+ else if (efx_channel_get_tx_queue(channel, 0))
+ channel->irq_moderation = tx_ticks;
+ }
}
/**************************************************************************
@@ -1546,11 +1704,11 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc
stats->tx_packets = mac_stats->tx_packets;
stats->rx_bytes = mac_stats->rx_bytes;
stats->tx_bytes = mac_stats->tx_bytes;
+ stats->rx_dropped = efx->n_rx_nodesc_drop_cnt;
stats->multicast = mac_stats->rx_multicast;
stats->collisions = mac_stats->tx_collision;
stats->rx_length_errors = (mac_stats->rx_gtjumbo +
mac_stats->rx_length_error);
- stats->rx_over_errors = efx->n_rx_nodesc_drop_cnt;
stats->rx_crc_errors = mac_stats->rx_bad;
stats->rx_frame_errors = mac_stats->rx_align_error;
stats->rx_fifo_errors = mac_stats->rx_overflow;
@@ -1767,6 +1925,7 @@ fail_registered:
static void efx_unregister_netdev(struct efx_nic *efx)
{
+ struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
if (!efx->net_dev)
@@ -1777,8 +1936,10 @@ static void efx_unregister_netdev(struct efx_nic *efx)
/* Free up any skbs still remaining. This has to happen before
* we try to unregister the netdev as running their destructors
* may be needed to get the device ref. count to 0. */
- efx_for_each_tx_queue(tx_queue, efx)
- efx_release_tx_buffers(tx_queue);
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_release_tx_buffers(tx_queue);
+ }
if (efx_dev_registered(efx)) {
strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
@@ -2037,9 +2198,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
struct pci_dev *pci_dev, struct net_device *net_dev)
{
- struct efx_channel *channel;
- struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
int i;
/* Initialise common structures */
@@ -2068,36 +2226,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
INIT_WORK(&efx->mac_work, efx_mac_work);
for (i = 0; i < EFX_MAX_CHANNELS; i++) {
- channel = &efx->channel[i];
- channel->efx = efx;
- channel->channel = i;
- channel->work_pending = false;
- spin_lock_init(&channel->tx_stop_lock);
- atomic_set(&channel->tx_stop_count, 1);
- }
- for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
- tx_queue = &efx->tx_queue[i];
- tx_queue->efx = efx;
- tx_queue->queue = i;
- tx_queue->buffer = NULL;
- tx_queue->channel = &efx->channel[0]; /* for safety */
- tx_queue->tso_headers_free = NULL;
- }
- for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
- rx_queue = &efx->rx_queue[i];
- rx_queue->efx = efx;
- rx_queue->queue = i;
- rx_queue->channel = &efx->channel[0]; /* for safety */
- rx_queue->buffer = NULL;
- setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
- (unsigned long)rx_queue);
+ efx->channel[i] = efx_alloc_channel(efx, i, NULL);
+ if (!efx->channel[i])
+ goto fail;
}
efx->type = type;
- /* As close as we can get to guaranteeing that we don't overflow */
- BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE);
-
EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS);
/* Higher numbered interrupt modes are less capable! */
@@ -2109,13 +2244,22 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
pci_name(pci_dev));
efx->workqueue = create_singlethread_workqueue(efx->workqueue_name);
if (!efx->workqueue)
- return -ENOMEM;
+ goto fail;
return 0;
+
+fail:
+ efx_fini_struct(efx);
+ return -ENOMEM;
}
static void efx_fini_struct(struct efx_nic *efx)
{
+ int i;
+
+ for (i = 0; i < EFX_MAX_CHANNELS; i++)
+ kfree(efx->channel[i]);
+
if (efx->workqueue) {
destroy_workqueue(efx->workqueue);
efx->workqueue = NULL;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 060dc952a0fd..e783c0fedfd8 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -37,8 +37,6 @@ efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_stop_queue(struct efx_channel *channel);
extern void efx_wake_queue(struct efx_channel *channel);
-#define EFX_TXQ_SIZE 1024
-#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1)
/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
@@ -53,13 +51,23 @@ extern void __efx_rx_packet(struct efx_channel *channel,
extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard);
extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
-#define EFX_RXQ_SIZE 1024
-#define EFX_RXQ_MASK (EFX_RXQ_SIZE - 1)
+
+#define EFX_MAX_DMAQ_SIZE 4096UL
+#define EFX_DEFAULT_DMAQ_SIZE 1024UL
+#define EFX_MIN_DMAQ_SIZE 512UL
+
+#define EFX_MAX_EVQ_SIZE 16384UL
+#define EFX_MIN_EVQ_SIZE 512UL
+
+/* The smallest [rt]xq_entries that the driver supports. Callers of
+ * efx_wake_queue() assume that they can subsequently send at least one
+ * skb. Falcon/A1 may require up to three descriptors per skb_frag. */
+#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS))
/* Channels */
extern void efx_process_channel_now(struct efx_channel *channel);
-#define EFX_EVQ_SIZE 4096
-#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1)
+extern int
+efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
/* Ports */
extern int efx_reconfigure_port(struct efx_nic *efx);
@@ -81,8 +89,6 @@ extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
int rx_usecs, bool rx_adaptive);
-extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
-extern void efx_hex_dump(const u8 *, unsigned int, const char *);
/* Dummy PHY ops for PHY drivers */
extern int efx_port_dummy_op_int(struct efx_nic *efx);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index fd19d6ab97a2..7f735d804801 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -328,9 +328,10 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
unsigned int test_index,
struct ethtool_string *strings, u64 *data)
{
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
- efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
efx_fill_test(test_index++, strings, data,
&lb_tests->tx_sent[tx_queue->queue],
EFX_TX_QUEUE_NAME(tx_queue),
@@ -673,15 +674,15 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
struct efx_nic *efx = netdev_priv(net_dev);
- struct efx_tx_queue *tx_queue;
struct efx_channel *channel;
memset(coalesce, 0, sizeof(*coalesce));
/* Find lowest IRQ moderation across all used TX queues */
coalesce->tx_coalesce_usecs_irq = ~((u32) 0);
- efx_for_each_tx_queue(tx_queue, efx) {
- channel = tx_queue->channel;
+ efx_for_each_channel(channel, efx) {
+ if (!efx_channel_get_tx_queue(channel, 0))
+ continue;
if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) {
if (channel->channel < efx->n_rx_channels)
coalesce->tx_coalesce_usecs_irq =
@@ -708,7 +709,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
- struct efx_tx_queue *tx_queue;
unsigned tx_usecs, rx_usecs, adaptive;
if (coalesce->use_adaptive_tx_coalesce)
@@ -725,8 +725,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
adaptive = coalesce->use_adaptive_rx_coalesce;
/* If the channel is shared only allow RX parameters to be set */
- efx_for_each_tx_queue(tx_queue, efx) {
- if ((tx_queue->channel->channel < efx->n_rx_channels) &&
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_get_rx_queue(channel) &&
+ efx_channel_get_tx_queue(channel, 0) &&
tx_usecs) {
netif_err(efx, drv, efx->net_dev, "Channel is shared. "
"Only RX coalescing may be set\n");
@@ -741,6 +742,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
return 0;
}
+static void efx_ethtool_get_ringparam(struct net_device *net_dev,
+ struct ethtool_ringparam *ring)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
+ ring->tx_max_pending = EFX_MAX_DMAQ_SIZE;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = efx->rxq_entries;
+ ring->tx_pending = efx->txq_entries;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
+static int efx_ethtool_set_ringparam(struct net_device *net_dev,
+ struct ethtool_ringparam *ring)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+
+ if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
+ ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
+ ring->tx_pending > EFX_MAX_DMAQ_SIZE)
+ return -EINVAL;
+
+ if (ring->rx_pending < EFX_MIN_RING_SIZE ||
+ ring->tx_pending < EFX_MIN_RING_SIZE) {
+ netif_err(efx, drv, efx->net_dev,
+ "TX and RX queues cannot be smaller than %ld\n",
+ EFX_MIN_RING_SIZE);
+ return -EINVAL;
+ }
+
+ return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending);
+}
+
static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
@@ -971,6 +1008,8 @@ const struct ethtool_ops efx_ethtool_ops = {
.set_eeprom = efx_ethtool_set_eeprom,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
+ .get_ringparam = efx_ethtool_get_ringparam,
+ .set_ringparam = efx_ethtool_set_ringparam,
.get_pauseparam = efx_ethtool_get_pauseparam,
.set_pauseparam = efx_ethtool_set_pauseparam,
.get_rx_csum = efx_ethtool_get_rx_csum,
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 4f9d33f3cca1..b4d8efe67772 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -159,7 +159,6 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
{
struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr;
- struct efx_channel *channel;
int syserr;
int queues;
@@ -194,15 +193,10 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
wmb(); /* Ensure the vector is cleared before interrupt ack */
falcon_irq_ack_a1(efx);
- /* Schedule processing of any interrupting queues */
- channel = &efx->channel[0];
- while (queues) {
- if (queues & 0x01)
- efx_schedule_channel(channel);
- channel++;
- queues >>= 1;
- }
-
+ if (queues & 1)
+ efx_schedule_channel(efx_get_channel(efx, 0));
+ if (queues & 2)
+ efx_schedule_channel(efx_get_channel(efx, 1));
return IRQ_HANDLED;
}
/**************************************************************************
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 64e7caa4bbb5..152342dbff29 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -137,6 +137,7 @@ struct efx_tx_buffer {
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
+ * @ptr_mask: The size of the ring minus 1.
* @flushed: Used when handling queue flushing
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
@@ -170,6 +171,7 @@ struct efx_tx_queue {
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
struct efx_special_buffer txd;
+ unsigned int ptr_mask;
enum efx_flush_state flushed;
/* Members used mainly on the completion path */
@@ -225,10 +227,9 @@ struct efx_rx_page_state {
/**
* struct efx_rx_queue - An Efx RX queue
* @efx: The associated Efx NIC
- * @queue: DMA queue number
- * @channel: The associated channel
* @buffer: The software buffer ring
* @rxd: The hardware descriptor ring
+ * @ptr_mask: The size of the ring minus 1.
* @added_count: Number of buffers added to the receive queue.
* @notified_count: Number of buffers given to NIC (<= @added_count).
* @removed_count: Number of buffers removed from the receive queue.
@@ -240,9 +241,6 @@ struct efx_rx_page_state {
* @min_fill: RX descriptor minimum non-zero fill level.
* This records the minimum fill level observed when a ring
* refill was triggered.
- * @min_overfill: RX descriptor minimum overflow fill level.
- * This records the minimum fill level at which RX queue
- * overflow was observed. It should never be set.
* @alloc_page_count: RX allocation strategy counter.
* @alloc_skb_count: RX allocation strategy counter.
* @slow_fill: Timer used to defer efx_nic_generate_fill_event().
@@ -250,10 +248,9 @@ struct efx_rx_page_state {
*/
struct efx_rx_queue {
struct efx_nic *efx;
- int queue;
- struct efx_channel *channel;
struct efx_rx_buffer *buffer;
struct efx_special_buffer rxd;
+ unsigned int ptr_mask;
int added_count;
int notified_count;
@@ -302,7 +299,6 @@ enum efx_rx_alloc_method {
*
* @efx: Associated Efx NIC
* @channel: Channel instance number
- * @name: Name for channel and IRQ
* @enabled: Channel enabled indicator
* @irq: IRQ number (MSI and MSI-X only)
* @irq_moderation: IRQ moderation value (in hardware ticks)
@@ -311,6 +307,7 @@ enum efx_rx_alloc_method {
* @reset_work: Scheduled reset work thread
* @work_pending: Is work pending via NAPI?
* @eventq: Event queue buffer
+ * @eventq_mask: Event queue pointer mask
* @eventq_read_ptr: Event queue read pointer
* @last_eventq_read_ptr: Last event queue read pointer value.
* @magic_count: Event queue test event count
@@ -327,14 +324,14 @@ enum efx_rx_alloc_method {
* @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors
* @n_rx_overlength: Count of RX_OVERLENGTH errors
* @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun
- * @tx_queue: Pointer to first TX queue, or %NULL if not used for TX
+ * @rx_queue: RX queue for this channel
* @tx_stop_count: Core TX queue stop count
* @tx_stop_lock: Core TX queue stop lock
+ * @tx_queue: TX queues for this channel
*/
struct efx_channel {
struct efx_nic *efx;
int channel;
- char name[IFNAMSIZ + 6];
bool enabled;
int irq;
unsigned int irq_moderation;
@@ -342,6 +339,7 @@ struct efx_channel {
struct napi_struct napi_str;
bool work_pending;
struct efx_special_buffer eventq;
+ unsigned int eventq_mask;
unsigned int eventq_read_ptr;
unsigned int last_eventq_read_ptr;
unsigned int magic_count;
@@ -366,9 +364,12 @@ struct efx_channel {
struct efx_rx_buffer *rx_pkt;
bool rx_pkt_csummed;
- struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue rx_queue;
+
atomic_t tx_stop_count;
spinlock_t tx_stop_lock;
+
+ struct efx_tx_queue tx_queue[2];
};
enum efx_led_mode {
@@ -641,6 +642,9 @@ union efx_multicast_hash {
* @tx_queue: TX DMA queues
* @rx_queue: RX DMA queues
* @channel: Channels
+ * @channel_name: Names for channels and their IRQs
+ * @rxq_entries: Size of receive queues requested by user.
+ * @txq_entries: Size of transmit queues requested by user.
* @next_buffer_table: First available buffer table id
* @n_channels: Number of channels in use
* @n_rx_channels: Number of channels used for RX (= number of RX queues)
@@ -724,10 +728,11 @@ struct efx_nic {
enum nic_state state;
enum reset_type reset_pending;
- struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES];
- struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
- struct efx_channel channel[EFX_MAX_CHANNELS];
+ struct efx_channel *channel[EFX_MAX_CHANNELS];
+ char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6];
+ unsigned rxq_entries;
+ unsigned txq_entries;
unsigned next_buffer_table;
unsigned n_channels;
unsigned n_rx_channels;
@@ -909,39 +914,67 @@ struct efx_nic_type {
*
*************************************************************************/
+static inline struct efx_channel *
+efx_get_channel(struct efx_nic *efx, unsigned index)
+{
+ EFX_BUG_ON_PARANOID(index >= efx->n_channels);
+ return efx->channel[index];
+}
+
/* Iterate over all used channels */
#define efx_for_each_channel(_channel, _efx) \
- for (_channel = &((_efx)->channel[0]); \
- _channel < &((_efx)->channel[(efx)->n_channels]); \
- _channel++)
-
-/* Iterate over all used TX queues */
-#define efx_for_each_tx_queue(_tx_queue, _efx) \
- for (_tx_queue = &((_efx)->tx_queue[0]); \
- _tx_queue < &((_efx)->tx_queue[EFX_TXQ_TYPES * \
- (_efx)->n_tx_channels]); \
- _tx_queue++)
+ for (_channel = (_efx)->channel[0]; \
+ _channel; \
+ _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \
+ (_efx)->channel[_channel->channel + 1] : NULL)
+
+extern struct efx_tx_queue *
+efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type);
+
+static inline struct efx_tx_queue *
+efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
+{
+ struct efx_tx_queue *tx_queue = channel->tx_queue;
+ EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES);
+ return tx_queue->channel ? tx_queue + type : NULL;
+}
/* Iterate over all TX queues belonging to a channel */
#define efx_for_each_channel_tx_queue(_tx_queue, _channel) \
- for (_tx_queue = (_channel)->tx_queue; \
+ for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \
_tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \
_tx_queue++)
-/* Iterate over all used RX queues */
-#define efx_for_each_rx_queue(_rx_queue, _efx) \
- for (_rx_queue = &((_efx)->rx_queue[0]); \
- _rx_queue < &((_efx)->rx_queue[(_efx)->n_rx_channels]); \
- _rx_queue++)
+static inline struct efx_rx_queue *
+efx_get_rx_queue(struct efx_nic *efx, unsigned index)
+{
+ EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels);
+ return &efx->channel[index]->rx_queue;
+}
+
+static inline struct efx_rx_queue *
+efx_channel_get_rx_queue(struct efx_channel *channel)
+{
+ return channel->channel < channel->efx->n_rx_channels ?
+ &channel->rx_queue : NULL;
+}
/* Iterate over all RX queues belonging to a channel */
#define efx_for_each_channel_rx_queue(_rx_queue, _channel) \
- for (_rx_queue = &((_channel)->efx->rx_queue[(_channel)->channel]); \
+ for (_rx_queue = efx_channel_get_rx_queue(channel); \
_rx_queue; \
- _rx_queue = NULL) \
- if (_rx_queue->channel != (_channel)) \
- continue; \
- else
+ _rx_queue = NULL)
+
+static inline struct efx_channel *
+efx_rx_queue_channel(struct efx_rx_queue *rx_queue)
+{
+ return container_of(rx_queue, struct efx_channel, rx_queue);
+}
+
+static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue)
+{
+ return efx_rx_queue_channel(rx_queue)->channel;
+}
/* Returns a pointer to the specified receive buffer in the RX
* descriptor queue.
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index f595d920c7c4..6c5c0cefa9d8 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -263,8 +263,8 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
{
len = ALIGN(len, EFX_BUF_SIZE);
- buffer->addr = pci_alloc_consistent(efx->pci_dev, len,
- &buffer->dma_addr);
+ buffer->addr = dma_alloc_coherent(&efx->pci_dev->dev, len,
+ &buffer->dma_addr, GFP_KERNEL);
if (!buffer->addr)
return -ENOMEM;
buffer->len = len;
@@ -301,8 +301,8 @@ efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
(u64)buffer->dma_addr, buffer->len,
buffer->addr, (u64)virt_to_phys(buffer->addr));
- pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr,
- buffer->dma_addr);
+ dma_free_coherent(&efx->pci_dev->dev, buffer->len, buffer->addr,
+ buffer->dma_addr);
buffer->addr = NULL;
buffer->entries = 0;
}
@@ -356,7 +356,7 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue)
unsigned write_ptr;
efx_dword_t reg;
- write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr);
efx_writed_page(tx_queue->efx, &reg,
FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue);
@@ -377,7 +377,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
BUG_ON(tx_queue->write_count == tx_queue->insert_count);
do {
- write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+ write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[write_ptr];
txd = efx_tx_desc(tx_queue, write_ptr);
++tx_queue->write_count;
@@ -398,10 +398,11 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 ||
- EFX_TXQ_SIZE & EFX_TXQ_MASK);
+ unsigned entries;
+
+ entries = tx_queue->ptr_mask + 1;
return efx_alloc_special_buffer(efx, &tx_queue->txd,
- EFX_TXQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
@@ -526,30 +527,32 @@ efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index)
*/
void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
{
+ struct efx_nic *efx = rx_queue->efx;
efx_dword_t reg;
unsigned write_ptr;
while (rx_queue->notified_count != rx_queue->added_count) {
- efx_build_rx_desc(rx_queue,
- rx_queue->notified_count &
- EFX_RXQ_MASK);
+ efx_build_rx_desc(
+ rx_queue,
+ rx_queue->notified_count & rx_queue->ptr_mask);
++rx_queue->notified_count;
}
wmb();
- write_ptr = rx_queue->added_count & EFX_RXQ_MASK;
+ write_ptr = rx_queue->added_count & rx_queue->ptr_mask;
EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr);
- efx_writed_page(rx_queue->efx, &reg,
- FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue);
+ efx_writed_page(efx, &reg, FR_AZ_RX_DESC_UPD_DWORD_P0,
+ efx_rx_queue_index(rx_queue));
}
int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 ||
- EFX_RXQ_SIZE & EFX_RXQ_MASK);
+ unsigned entries;
+
+ entries = rx_queue->ptr_mask + 1;
return efx_alloc_special_buffer(efx, &rx_queue->rxd,
- EFX_RXQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
@@ -561,7 +564,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
netif_dbg(efx, hw, efx->net_dev,
"RX queue %d ring in special buffers %d-%d\n",
- rx_queue->queue, rx_queue->rxd.index,
+ efx_rx_queue_index(rx_queue), rx_queue->rxd.index,
rx_queue->rxd.index + rx_queue->rxd.entries - 1);
rx_queue->flushed = FLUSH_NONE;
@@ -575,9 +578,10 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en,
FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index,
FRF_AZ_RX_DESCQ_EVQ_ID,
- rx_queue->channel->channel,
+ efx_rx_queue_channel(rx_queue)->channel,
FRF_AZ_RX_DESCQ_OWNER_ID, 0,
- FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue,
+ FRF_AZ_RX_DESCQ_LABEL,
+ efx_rx_queue_index(rx_queue),
FRF_AZ_RX_DESCQ_SIZE,
__ffs(rx_queue->rxd.entries),
FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ ,
@@ -585,7 +589,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
FRF_AZ_RX_DESCQ_JUMBO, !is_b0,
FRF_AZ_RX_DESCQ_EN, 1);
efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
+ efx_rx_queue_index(rx_queue));
}
static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
@@ -598,7 +602,8 @@ static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
/* Post a flush command */
EFX_POPULATE_OWORD_2(rx_flush_descq,
FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
- FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue);
+ FRF_AZ_RX_FLUSH_DESCQ,
+ efx_rx_queue_index(rx_queue));
efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ);
}
@@ -613,7 +618,7 @@ void efx_nic_fini_rx(struct efx_rx_queue *rx_queue)
/* Remove RX descriptor ring from card */
EFX_ZERO_OWORD(rx_desc_ptr);
efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
+ efx_rx_queue_index(rx_queue));
/* Unpin RX descriptor ring */
efx_fini_special_buffer(efx, &rx_queue->rxd);
@@ -680,15 +685,17 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
/* Transmit completion */
tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
- tx_queue = &efx->tx_queue[tx_ev_q_label];
+ tx_queue = efx_channel_get_tx_queue(
+ channel, tx_ev_q_label % EFX_TXQ_TYPES);
tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) &
- EFX_TXQ_MASK);
+ tx_queue->ptr_mask);
channel->irq_mod_score += tx_packets;
efx_xmit_done(tx_queue, tx_ev_desc_ptr);
} else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
/* Rewrite the FIFO write pointer */
tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
- tx_queue = &efx->tx_queue[tx_ev_q_label];
+ tx_queue = efx_channel_get_tx_queue(
+ channel, tx_ev_q_label % EFX_TXQ_TYPES);
if (efx_dev_registered(efx))
netif_tx_lock(efx->net_dev);
@@ -714,6 +721,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
bool *rx_ev_pkt_ok,
bool *discard)
{
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
struct efx_nic *efx = rx_queue->efx;
bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
@@ -746,14 +754,14 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
/* Count errors that are not in MAC stats. Ignore expected
* checksum errors during self-test. */
if (rx_ev_frm_trunc)
- ++rx_queue->channel->n_rx_frm_trunc;
+ ++channel->n_rx_frm_trunc;
else if (rx_ev_tobe_disc)
- ++rx_queue->channel->n_rx_tobe_disc;
+ ++channel->n_rx_tobe_disc;
else if (!efx->loopback_selftest) {
if (rx_ev_ip_hdr_chksum_err)
- ++rx_queue->channel->n_rx_ip_hdr_chksum_err;
+ ++channel->n_rx_ip_hdr_chksum_err;
else if (rx_ev_tcp_udp_chksum_err)
- ++rx_queue->channel->n_rx_tcp_udp_chksum_err;
+ ++channel->n_rx_tcp_udp_chksum_err;
}
/* The frame must be discarded if any of these are true. */
@@ -769,7 +777,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
netif_dbg(efx, rx_err, efx->net_dev,
" RX queue %d unexpected RX event "
EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
- rx_queue->queue, EFX_QWORD_VAL(*event),
+ efx_rx_queue_index(rx_queue), EFX_QWORD_VAL(*event),
rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
rx_ev_ip_hdr_chksum_err ?
" [IP_HDR_CHKSUM_ERR]" : "",
@@ -791,8 +799,8 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index)
struct efx_nic *efx = rx_queue->efx;
unsigned expected, dropped;
- expected = rx_queue->removed_count & EFX_RXQ_MASK;
- dropped = (index - expected) & EFX_RXQ_MASK;
+ expected = rx_queue->removed_count & rx_queue->ptr_mask;
+ dropped = (index - expected) & rx_queue->ptr_mask;
netif_info(efx, rx_err, efx->net_dev,
"dropped %d events (index=%d expected=%d)\n",
dropped, index, expected);
@@ -827,10 +835,10 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) !=
channel->channel);
- rx_queue = &efx->rx_queue[channel->channel];
+ rx_queue = efx_channel_get_rx_queue(channel);
rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR);
- expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK;
+ expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask;
if (unlikely(rx_ev_desc_ptr != expected_ptr))
efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
@@ -879,7 +887,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
/* The queue must be empty, so we won't receive any rx
* events, so efx_process_channel() won't refill the
* queue. Refill it here */
- efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
+ efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
else
netif_dbg(efx, hw, efx->net_dev, "channel %d received "
"generated event "EFX_QWORD_FMT"\n",
@@ -997,6 +1005,7 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
int efx_nic_process_eventq(struct efx_channel *channel, int budget)
{
+ struct efx_nic *efx = channel->efx;
unsigned int read_ptr;
efx_qword_t event, *p_event;
int ev_code;
@@ -1021,7 +1030,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
EFX_SET_QWORD(*p_event);
/* Increment read pointer */
- read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+ read_ptr = (read_ptr + 1) & channel->eventq_mask;
ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE);
@@ -1033,7 +1042,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
break;
case FSE_AZ_EV_CODE_TX_EV:
tx_packets += efx_handle_tx_event(channel, &event);
- if (tx_packets >= EFX_TXQ_SIZE) {
+ if (tx_packets > efx->txq_entries) {
spent = budget;
goto out;
}
@@ -1068,10 +1077,11 @@ out:
int efx_nic_probe_eventq(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
- BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 ||
- EFX_EVQ_SIZE & EFX_EVQ_MASK);
+ unsigned entries;
+
+ entries = channel->eventq_mask + 1;
return efx_alloc_special_buffer(efx, &channel->eventq,
- EFX_EVQ_SIZE * sizeof(efx_qword_t));
+ entries * sizeof(efx_qword_t));
}
void efx_nic_init_eventq(struct efx_channel *channel)
@@ -1163,11 +1173,11 @@ void efx_nic_generate_fill_event(struct efx_channel *channel)
static void efx_poll_flush_events(struct efx_nic *efx)
{
- struct efx_channel *channel = &efx->channel[0];
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
unsigned int read_ptr = channel->eventq_read_ptr;
- unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK;
+ unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask;
do {
efx_qword_t *event = efx_event(channel, read_ptr);
@@ -1185,7 +1195,9 @@ static void efx_poll_flush_events(struct efx_nic *efx)
ev_queue = EFX_QWORD_FIELD(*event,
FSF_AZ_DRIVER_EV_SUBDATA);
if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) {
- tx_queue = efx->tx_queue + ev_queue;
+ tx_queue = efx_get_tx_queue(
+ efx, ev_queue / EFX_TXQ_TYPES,
+ ev_queue % EFX_TXQ_TYPES);
tx_queue->flushed = FLUSH_DONE;
}
} else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
@@ -1195,7 +1207,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
ev_failed = EFX_QWORD_FIELD(
*event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
if (ev_queue < efx->n_rx_channels) {
- rx_queue = efx->rx_queue + ev_queue;
+ rx_queue = efx_get_rx_queue(efx, ev_queue);
rx_queue->flushed =
ev_failed ? FLUSH_FAILED : FLUSH_DONE;
}
@@ -1205,7 +1217,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
* it's ok to throw away every non-flush event */
EFX_SET_QWORD(*event);
- read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+ read_ptr = (read_ptr + 1) & channel->eventq_mask;
} while (read_ptr != end_ptr);
channel->eventq_read_ptr = read_ptr;
@@ -1216,6 +1228,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
* serialise them */
int efx_nic_flush_queues(struct efx_nic *efx)
{
+ struct efx_channel *channel;
struct efx_rx_queue *rx_queue;
struct efx_tx_queue *tx_queue;
int i, tx_pending, rx_pending;
@@ -1224,29 +1237,35 @@ int efx_nic_flush_queues(struct efx_nic *efx)
efx->type->prepare_flush(efx);
/* Flush all tx queues in parallel */
- efx_for_each_tx_queue(tx_queue, efx)
- efx_flush_tx_queue(tx_queue);
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_flush_tx_queue(tx_queue);
+ }
/* The hardware supports four concurrent rx flushes, each of which may
* need to be retried if there is an outstanding descriptor fetch */
for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) {
rx_pending = tx_pending = 0;
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_queue->flushed == FLUSH_PENDING)
- ++rx_pending;
- }
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_pending == EFX_RX_FLUSH_COUNT)
- break;
- if (rx_queue->flushed == FLUSH_FAILED ||
- rx_queue->flushed == FLUSH_NONE) {
- efx_flush_rx_queue(rx_queue);
- ++rx_pending;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_queue->flushed == FLUSH_PENDING)
+ ++rx_pending;
}
}
- efx_for_each_tx_queue(tx_queue, efx) {
- if (tx_queue->flushed != FLUSH_DONE)
- ++tx_pending;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_pending == EFX_RX_FLUSH_COUNT)
+ break;
+ if (rx_queue->flushed == FLUSH_FAILED ||
+ rx_queue->flushed == FLUSH_NONE) {
+ efx_flush_rx_queue(rx_queue);
+ ++rx_pending;
+ }
+ }
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ if (tx_queue->flushed != FLUSH_DONE)
+ ++tx_pending;
+ }
}
if (rx_pending == 0 && tx_pending == 0)
@@ -1258,19 +1277,21 @@ int efx_nic_flush_queues(struct efx_nic *efx)
/* Mark the queues as all flushed. We're going to return failure
* leading to a reset, or fake up success anyway */
- efx_for_each_tx_queue(tx_queue, efx) {
- if (tx_queue->flushed != FLUSH_DONE)
- netif_err(efx, hw, efx->net_dev,
- "tx queue %d flush command timed out\n",
- tx_queue->queue);
- tx_queue->flushed = FLUSH_DONE;
- }
- efx_for_each_rx_queue(rx_queue, efx) {
- if (rx_queue->flushed != FLUSH_DONE)
- netif_err(efx, hw, efx->net_dev,
- "rx queue %d flush command timed out\n",
- rx_queue->queue);
- rx_queue->flushed = FLUSH_DONE;
+ efx_for_each_channel(channel, efx) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ if (tx_queue->flushed != FLUSH_DONE)
+ netif_err(efx, hw, efx->net_dev,
+ "tx queue %d flush command timed out\n",
+ tx_queue->queue);
+ tx_queue->flushed = FLUSH_DONE;
+ }
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ if (rx_queue->flushed != FLUSH_DONE)
+ netif_err(efx, hw, efx->net_dev,
+ "rx queue %d flush command timed out\n",
+ efx_rx_queue_index(rx_queue));
+ rx_queue->flushed = FLUSH_DONE;
+ }
}
return -ETIMEDOUT;
@@ -1457,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
*/
static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
{
- struct efx_channel *channel = dev_id;
+ struct efx_channel *channel = *(struct efx_channel **)dev_id;
struct efx_nic *efx = channel->efx;
efx_oword_t *int_ker = efx->irq_status.addr;
int syserr;
@@ -1532,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
rc = request_irq(channel->irq, efx_msi_interrupt,
IRQF_PROBE_SHARED, /* Not shared */
- channel->name, channel);
+ efx->channel_name[channel->channel],
+ &efx->channel[channel->channel]);
if (rc) {
netif_err(efx, drv, efx->net_dev,
"failed to hook IRQ %d\n", channel->irq);
@@ -1544,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
fail2:
efx_for_each_channel(channel, efx)
- free_irq(channel->irq, channel);
+ free_irq(channel->irq, &efx->channel[channel->channel]);
fail1:
return rc;
}
@@ -1557,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
/* Disable MSI/MSI-X interrupts */
efx_for_each_channel(channel, efx) {
if (channel->irq)
- free_irq(channel->irq, channel);
+ free_irq(channel->irq, &efx->channel[channel->channel]);
}
/* ACK legacy interrupt */
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 799c461ce7b8..6d0959b5158e 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -133,7 +133,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
unsigned index, count;
for (count = 0; count < EFX_RX_BATCH; ++count) {
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->skb = netdev_alloc_skb(net_dev, skb_len);
@@ -208,7 +208,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
dma_addr += sizeof(struct efx_rx_page_state);
split:
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->skb = NULL;
@@ -285,7 +285,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
* we'd like to insert an additional descriptor whilst leaving
* EFX_RXD_HEAD_ROOM for the non-recycle path */
fill_level = (rx_queue->added_count - rx_queue->removed_count + 2);
- if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) {
+ if (unlikely(fill_level > rx_queue->max_fill)) {
/* We could place "state" on a list, and drain the list in
* efx_fast_push_rx_descriptors(). For now, this will do. */
return;
@@ -294,7 +294,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
++state->refcnt;
get_page(rx_buf->page);
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
new_buf = efx_rx_buffer(rx_queue, index);
new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
new_buf->skb = NULL;
@@ -311,7 +311,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf)
{
struct efx_nic *efx = channel->efx;
- struct efx_rx_queue *rx_queue = &efx->rx_queue[channel->channel];
+ struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
struct efx_rx_buffer *new_buf;
unsigned index;
@@ -319,7 +319,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
page_count(rx_buf->page) == 1)
efx_resurrect_rx_buffer(rx_queue, rx_buf);
- index = rx_queue->added_count & EFX_RXQ_MASK;
+ index = rx_queue->added_count & rx_queue->ptr_mask;
new_buf = efx_rx_buffer(rx_queue, index);
memcpy(new_buf, rx_buf, sizeof(*new_buf));
@@ -341,13 +341,13 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
*/
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
{
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
unsigned fill_level;
int space, rc = 0;
/* Calculate current fill level, and exit if we don't need to fill */
fill_level = (rx_queue->added_count - rx_queue->removed_count);
- EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE);
+ EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries);
if (fill_level >= rx_queue->fast_fill_trigger)
goto out;
@@ -364,7 +364,8 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev,
"RX queue %d fast-filling descriptor ring from"
" level %d to level %d using %s allocation\n",
- rx_queue->queue, fill_level, rx_queue->fast_fill_limit,
+ efx_rx_queue_index(rx_queue), fill_level,
+ rx_queue->fast_fill_limit,
channel->rx_alloc_push_pages ? "page" : "skb");
do {
@@ -382,7 +383,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev,
"RX queue %d fast-filled descriptor ring "
- "to level %d\n", rx_queue->queue,
+ "to level %d\n", efx_rx_queue_index(rx_queue),
rx_queue->added_count - rx_queue->removed_count);
out:
@@ -393,7 +394,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
void efx_rx_slow_fill(unsigned long context)
{
struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context;
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
/* Post an event to cause NAPI to run and refill the queue */
efx_nic_generate_fill_event(channel);
@@ -421,7 +422,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
netif_err(efx, rx_err, efx->net_dev,
" RX queue %d seriously overlength "
"RX event (0x%x > 0x%x+0x%x). Leaking\n",
- rx_queue->queue, len, max_len,
+ efx_rx_queue_index(rx_queue), len, max_len,
efx->type->rx_buffer_padding);
/* If this buffer was skb-allocated, then the meta
* data at the end of the skb will be trashed. So
@@ -434,10 +435,10 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
netif_err(efx, rx_err, efx->net_dev,
" RX queue %d overlength RX event "
"(0x%x > 0x%x)\n",
- rx_queue->queue, len, max_len);
+ efx_rx_queue_index(rx_queue), len, max_len);
}
- rx_queue->channel->n_rx_overlength++;
+ efx_rx_queue_channel(rx_queue)->n_rx_overlength++;
}
/* Pass a received packet up through the generic LRO stack
@@ -507,7 +508,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard)
{
struct efx_nic *efx = rx_queue->efx;
- struct efx_channel *channel = rx_queue->channel;
+ struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
struct efx_rx_buffer *rx_buf;
bool leak_packet = false;
@@ -528,7 +529,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
netif_vdbg(efx, rx_status, efx->net_dev,
"RX queue %d received id %x at %llx+%x %s%s\n",
- rx_queue->queue, index,
+ efx_rx_queue_index(rx_queue), index,
(unsigned long long)rx_buf->dma_addr, len,
(checksummed ? " [SUMMED]" : ""),
(discard ? " [DISCARD]" : ""));
@@ -560,12 +561,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
*/
rx_buf->len = len;
out:
- if (rx_queue->channel->rx_pkt)
- __efx_rx_packet(rx_queue->channel,
- rx_queue->channel->rx_pkt,
- rx_queue->channel->rx_pkt_csummed);
- rx_queue->channel->rx_pkt = rx_buf;
- rx_queue->channel->rx_pkt_csummed = checksummed;
+ if (channel->rx_pkt)
+ __efx_rx_packet(channel,
+ channel->rx_pkt, channel->rx_pkt_csummed);
+ channel->rx_pkt = rx_buf;
+ channel->rx_pkt_csummed = checksummed;
}
/* Handle a received packet. Second half: Touches packet payload. */
@@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel,
EFX_BUG_ON_PARANOID(!skb);
/* Set the SKB flags */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
/* Pass the packet up */
netif_receive_skb(skb);
@@ -650,15 +650,22 @@ void efx_rx_strategy(struct efx_channel *channel)
int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- unsigned int rxq_size;
+ unsigned int entries;
int rc;
+ /* Create the smallest power-of-two aligned ring */
+ entries = max(roundup_pow_of_two(efx->rxq_entries), EFX_MIN_DMAQ_SIZE);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE);
+ rx_queue->ptr_mask = entries - 1;
+
netif_dbg(efx, probe, efx->net_dev,
- "creating RX queue %d\n", rx_queue->queue);
+ "creating RX queue %d size %#x mask %#x\n",
+ efx_rx_queue_index(rx_queue), efx->rxq_entries,
+ rx_queue->ptr_mask);
/* Allocate RX buffers */
- rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer);
- rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL);
+ rx_queue->buffer = kzalloc(entries * sizeof(*rx_queue->buffer),
+ GFP_KERNEL);
if (!rx_queue->buffer)
return -ENOMEM;
@@ -672,20 +679,20 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
{
+ struct efx_nic *efx = rx_queue->efx;
unsigned int max_fill, trigger, limit;
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "initialising RX queue %d\n", rx_queue->queue);
+ "initialising RX queue %d\n", efx_rx_queue_index(rx_queue));
/* Initialise ptr fields */
rx_queue->added_count = 0;
rx_queue->notified_count = 0;
rx_queue->removed_count = 0;
rx_queue->min_fill = -1U;
- rx_queue->min_overfill = -1U;
/* Initialise limit fields */
- max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM;
+ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM;
trigger = max_fill * min(rx_refill_threshold, 100U) / 100U;
limit = max_fill * min(rx_refill_limit, 100U) / 100U;
@@ -703,14 +710,14 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
struct efx_rx_buffer *rx_buf;
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "shutting down RX queue %d\n", rx_queue->queue);
+ "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
del_timer_sync(&rx_queue->slow_fill);
efx_nic_fini_rx(rx_queue);
/* Release RX buffers NB start at index 0 not current HW ptr */
if (rx_queue->buffer) {
- for (i = 0; i <= EFX_RXQ_MASK; i++) {
+ for (i = 0; i <= rx_queue->ptr_mask; i++) {
rx_buf = efx_rx_buffer(rx_queue, i);
efx_fini_rx_buffer(rx_queue, rx_buf);
}
@@ -720,7 +727,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue)
{
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
- "destroying RX queue %d\n", rx_queue->queue);
+ "destroying RX queue %d\n", efx_rx_queue_index(rx_queue));
efx_nic_remove_rx(rx_queue);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 85f015f005d5..da4473b71058 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -506,7 +506,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
for (i = 0; i < 3; i++) {
/* Determine how many packets to send */
- state->packet_count = EFX_TXQ_SIZE / 3;
+ state->packet_count = efx->txq_entries / 3;
state->packet_count = min(1 << (i << 2), state->packet_count);
state->skbs = kzalloc(sizeof(state->skbs[0]) *
state->packet_count, GFP_KERNEL);
@@ -567,7 +567,7 @@ static int efx_wait_for_link(struct efx_nic *efx)
efx->type->monitor(efx);
mutex_unlock(&efx->mac_lock);
} else {
- struct efx_channel *channel = &efx->channel[0];
+ struct efx_channel *channel = efx_get_channel(efx, 0);
if (channel->work_pending)
efx_process_channel_now(channel);
}
@@ -594,6 +594,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode mode;
struct efx_loopback_state *state;
+ struct efx_channel *channel = efx_get_channel(efx, 0);
struct efx_tx_queue *tx_queue;
int rc = 0;
@@ -634,7 +635,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
}
/* Test both types of TX queue */
- efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) {
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
state->offload_csum = (tx_queue->queue &
EFX_TXQ_TYPE_OFFLOAD);
rc = efx_test_loopback(tx_queue,
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c
index 3fab030f8ab5..9f5368049694 100644
--- a/drivers/net/sfc/siena.c
+++ b/drivers/net/sfc/siena.c
@@ -450,7 +450,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
mac_stats->rx_bad_bytes);
MAC_STAT(rx_packets, RX_PKTS);
MAC_STAT(rx_good, RX_GOOD_PKTS);
- mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good;
+ MAC_STAT(rx_bad, RX_BAD_FCS_PKTS);
MAC_STAT(rx_pause, RX_PAUSE_PKTS);
MAC_STAT(rx_control, RX_CONTROL_PKTS);
MAC_STAT(rx_unicast, RX_UNICAST_PKTS);
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index c6942da2c99a..11726989fe2d 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -28,7 +28,7 @@
* The tx_queue descriptor ring fill-level must fall below this value
* before we restart the netif queue
*/
-#define EFX_TXQ_THRESHOLD (EFX_TXQ_MASK / 2u)
+#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u)
/* We need to be able to nest calls to netif_tx_stop_queue(), partly
* because of the 2 hardware queues associated with each core queue,
@@ -37,8 +37,9 @@
void efx_stop_queue(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
- if (!channel->tx_queue)
+ if (!tx_queue)
return;
spin_lock_bh(&channel->tx_stop_lock);
@@ -46,9 +47,8 @@ void efx_stop_queue(struct efx_channel *channel)
atomic_inc(&channel->tx_stop_count);
netif_tx_stop_queue(
- netdev_get_tx_queue(
- efx->net_dev,
- channel->tx_queue->queue / EFX_TXQ_TYPES));
+ netdev_get_tx_queue(efx->net_dev,
+ tx_queue->queue / EFX_TXQ_TYPES));
spin_unlock_bh(&channel->tx_stop_lock);
}
@@ -57,8 +57,9 @@ void efx_stop_queue(struct efx_channel *channel)
void efx_wake_queue(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
+ struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0);
- if (!channel->tx_queue)
+ if (!tx_queue)
return;
local_bh_disable();
@@ -66,9 +67,8 @@ void efx_wake_queue(struct efx_channel *channel)
&channel->tx_stop_lock)) {
netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n");
netif_tx_wake_queue(
- netdev_get_tx_queue(
- efx->net_dev,
- channel->tx_queue->queue / EFX_TXQ_TYPES));
+ netdev_get_tx_queue(efx->net_dev,
+ tx_queue->queue / EFX_TXQ_TYPES));
spin_unlock(&channel->tx_stop_lock);
}
local_bh_enable();
@@ -207,7 +207,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
}
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
/* Map for DMA. Use pci_map_single rather than pci_map_page
* since this is more efficient on machines with sparse
@@ -244,14 +244,14 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
&tx_queue->read_count;
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
if (unlikely(q_space-- <= 0))
goto stop;
smp_mb();
--tx_queue->stopped;
}
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->tsoh);
@@ -320,7 +320,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
/* Work backwards until we hit the original insert pointer value */
while (tx_queue->insert_count != tx_queue->write_count) {
--tx_queue->insert_count;
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
efx_dequeue_buffer(tx_queue, buffer);
buffer->len = 0;
@@ -350,8 +350,8 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
struct efx_nic *efx = tx_queue->efx;
unsigned int stop_index, read_ptr;
- stop_index = (index + 1) & EFX_TXQ_MASK;
- read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
+ stop_index = (index + 1) & tx_queue->ptr_mask;
+ read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
while (read_ptr != stop_index) {
struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
@@ -368,7 +368,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
buffer->len = 0;
++tx_queue->read_count;
- read_ptr = tx_queue->read_count & EFX_TXQ_MASK;
+ read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
}
}
@@ -390,9 +390,9 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
if (unlikely(efx->port_inhibited))
return NETDEV_TX_BUSY;
- tx_queue = &efx->tx_queue[EFX_TXQ_TYPES * skb_get_queue_mapping(skb)];
- if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
- tx_queue += EFX_TXQ_TYPE_OFFLOAD;
+ tx_queue = efx_get_tx_queue(efx, skb_get_queue_mapping(skb),
+ skb->ip_summed == CHECKSUM_PARTIAL ?
+ EFX_TXQ_TYPE_OFFLOAD : 0);
return efx_enqueue_skb(tx_queue, skb);
}
@@ -402,7 +402,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
unsigned fill_level;
struct efx_nic *efx = tx_queue->efx;
- EFX_BUG_ON_PARANOID(index > EFX_TXQ_MASK);
+ EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask);
efx_dequeue_buffers(tx_queue, index);
@@ -412,7 +412,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
smp_mb();
if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
- if (fill_level < EFX_TXQ_THRESHOLD) {
+ if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
/* Do this under netif_tx_lock(), to avoid racing
@@ -430,18 +430,24 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
int efx_probe_tx_queue(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- unsigned int txq_size;
+ unsigned int entries;
int i, rc;
- netif_dbg(efx, probe, efx->net_dev, "creating TX queue %d\n",
- tx_queue->queue);
+ /* Create the smallest power-of-two aligned ring */
+ entries = max(roundup_pow_of_two(efx->txq_entries), EFX_MIN_DMAQ_SIZE);
+ EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE);
+ tx_queue->ptr_mask = entries - 1;
+
+ netif_dbg(efx, probe, efx->net_dev,
+ "creating TX queue %d size %#x mask %#x\n",
+ tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask);
/* Allocate software ring */
- txq_size = EFX_TXQ_SIZE * sizeof(*tx_queue->buffer);
- tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
+ tx_queue->buffer = kzalloc(entries * sizeof(*tx_queue->buffer),
+ GFP_KERNEL);
if (!tx_queue->buffer)
return -ENOMEM;
- for (i = 0; i <= EFX_TXQ_MASK; ++i)
+ for (i = 0; i <= tx_queue->ptr_mask; ++i)
tx_queue->buffer[i].continuation = true;
/* Allocate hardware ring */
@@ -481,7 +487,7 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
/* Free any buffers left in the ring */
while (tx_queue->read_count != tx_queue->write_count) {
- buffer = &tx_queue->buffer[tx_queue->read_count & EFX_TXQ_MASK];
+ buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask];
efx_dequeue_buffer(tx_queue, buffer);
buffer->continuation = true;
buffer->len = 0;
@@ -741,7 +747,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
/* -1 as there is no way to represent all descriptors used */
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
while (1) {
if (unlikely(q_space-- <= 0)) {
@@ -757,7 +763,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
*(volatile unsigned *)&tx_queue->read_count;
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
- q_space = EFX_TXQ_MASK - 1 - fill_level;
+ q_space = efx->txq_entries - 1 - fill_level;
if (unlikely(q_space-- <= 0)) {
*final_buffer = NULL;
return 1;
@@ -766,13 +772,13 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
--tx_queue->stopped;
}
- insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK;
+ insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
buffer = &tx_queue->buffer[insert_ptr];
++tx_queue->insert_count;
EFX_BUG_ON_PARANOID(tx_queue->insert_count -
- tx_queue->read_count >
- EFX_TXQ_MASK);
+ tx_queue->read_count >=
+ efx->txq_entries);
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->len);
@@ -813,7 +819,7 @@ static void efx_tso_put_header(struct efx_tx_queue *tx_queue,
{
struct efx_tx_buffer *buffer;
- buffer = &tx_queue->buffer[tx_queue->insert_count & EFX_TXQ_MASK];
+ buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->len);
EFX_BUG_ON_PARANOID(buffer->unmap_len);
@@ -838,7 +844,7 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
while (tx_queue->insert_count != tx_queue->write_count) {
--tx_queue->insert_count;
buffer = &tx_queue->buffer[tx_queue->insert_count &
- EFX_TXQ_MASK];
+ tx_queue->ptr_mask];
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->skb);
if (buffer->unmap_len) {
@@ -1168,7 +1174,7 @@ static void efx_fini_tso(struct efx_tx_queue *tx_queue)
unsigned i;
if (tx_queue->buffer) {
- for (i = 0; i <= EFX_TXQ_MASK; ++i)
+ for (i = 0; i <= tx_queue->ptr_mask; ++i)
efx_tsoh_free(tx_queue, &tx_queue->buffer[i]);
}
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 79fd02bc69fd..50259dfec583 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -798,7 +798,7 @@ static int sh_eth_rx(struct net_device *ndev)
skb->dev = ndev;
sh_eth_set_receive_align(skb);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
}
if (entry >= RX_RING_SIZE - 1)
@@ -1031,7 +1031,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
mdp->duplex = -1;
/* Try connect to PHY */
- phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link,
+ phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
dev_err(&ndev->dev, "phy_connect failed\n");
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index bbbded76ff14..ffdd8591d4bc 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1042,7 +1042,7 @@ sis900_open(struct net_device *net_dev)
init_timer(&sis_priv->timer);
sis_priv->timer.expires = jiffies + HZ;
sis_priv->timer.data = (unsigned long)net_dev;
- sis_priv->timer.function = &sis900_timer;
+ sis_priv->timer.function = sis900_timer;
add_timer(&sis_priv->timer);
return 0;
diff --git a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c
index 053151468f93..465565e53a68 100644
--- a/drivers/net/skfp/hwt.c
+++ b/drivers/net/skfp/hwt.c
@@ -221,7 +221,7 @@ u_long hwt_quick_read(struct s_smc *smc)
* para start start time
* duration time to wait
*
- * NOTE: The fuction will return immediately, if the timer is not
+ * NOTE: The function will return immediately, if the timer is not
* started
************************/
void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 31b2dabf094c..a3c434850c75 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -33,7 +33,7 @@
* The driver architecture is based on the DEC FDDI driver by
* Lawrence V. Stefani and several ethernet drivers.
* I also used an existing Windows NT miniport driver.
- * All hardware dependent fuctions are handled by the SysKonnect
+ * All hardware dependent functions are handled by the SysKonnect
* Hardware Module.
* The only headerfiles that are directly related to this source
* are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h.
@@ -209,7 +209,7 @@ static int skfp_init_one(struct pci_dev *pdev,
void __iomem *mem;
int err;
- pr_debug(KERN_INFO "entering skfp_init_one\n");
+ pr_debug("entering skfp_init_one\n");
if (num_boards == 0)
printk("%s\n", boot_msg);
@@ -385,7 +385,7 @@ static int skfp_driver_init(struct net_device *dev)
skfddi_priv *bp = &smc->os;
int err = -EIO;
- pr_debug(KERN_INFO "entering skfp_driver_init\n");
+ pr_debug("entering skfp_driver_init\n");
// set the io address in private structures
bp->base_addr = dev->base_addr;
@@ -405,7 +405,7 @@ static int skfp_driver_init(struct net_device *dev)
// Determine the required size of the 'shared' memory area.
bp->SharedMemSize = mac_drv_check_space();
- pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
+ pr_debug("Memory for HWM: %ld\n", bp->SharedMemSize);
if (bp->SharedMemSize > 0) {
bp->SharedMemSize += 16; // for descriptor alignment
@@ -429,13 +429,13 @@ static int skfp_driver_init(struct net_device *dev)
card_stop(smc); // Reset adapter.
- pr_debug(KERN_INFO "mac_drv_init()..\n");
+ pr_debug("mac_drv_init()..\n");
if (mac_drv_init(smc) != 0) {
- pr_debug(KERN_INFO "mac_drv_init() failed.\n");
+ pr_debug("mac_drv_init() failed\n");
goto fail;
}
read_address(smc, NULL);
- pr_debug(KERN_INFO "HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a);
+ pr_debug("HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a);
memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6);
smt_reset_defaults(smc, 0);
@@ -485,7 +485,7 @@ static int skfp_open(struct net_device *dev)
struct s_smc *smc = netdev_priv(dev);
int err;
- pr_debug(KERN_INFO "entering skfp_open\n");
+ pr_debug("entering skfp_open\n");
/* Register IRQ - support shared interrupts by passing device ptr */
err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED,
dev->name, dev);
@@ -856,12 +856,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
/* Enable promiscuous mode, if necessary */
if (dev->flags & IFF_PROMISC) {
mac_drv_rx_mode(smc, RX_ENABLE_PROMISC);
- pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
+ pr_debug("PROMISCUOUS MODE ENABLED\n");
}
/* Else, update multicast address table */
else {
mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
- pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
+ pr_debug("PROMISCUOUS MODE DISABLED\n");
// Reset all MC addresses
mac_clear_multicast(smc);
@@ -869,7 +869,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug("ENABLE ALL MC ADDRESSES\n");
} else if (!netdev_mc_empty(dev)) {
if (netdev_mc_count(dev) <= FPMAX_MULTICAST) {
/* use exact filtering */
@@ -880,18 +880,18 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
(struct fddi_addr *)ha->addr,
1);
- pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n",
- ha->addr);
+ pr_debug("ENABLE MC ADDRESS: %pMF\n",
+ ha->addr);
}
} else { // more MC addresses than HW supports
mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
- pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+ pr_debug("ENABLE ALL MC ADDRESSES\n");
}
} else { // no MC addresses
- pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
+ pr_debug("DISABLE ALL MC ADDRESSES\n");
}
/* Update adapter filters */
@@ -1045,7 +1045,7 @@ static netdev_tx_t skfp_send_pkt(struct sk_buff *skb,
struct s_smc *smc = netdev_priv(dev);
skfddi_priv *bp = &smc->os;
- pr_debug(KERN_INFO "skfp_send_pkt\n");
+ pr_debug("skfp_send_pkt\n");
/*
* Verify that incoming transmit request is OK
@@ -1114,13 +1114,13 @@ static void send_queued_packets(struct s_smc *smc)
int frame_status; // HWM tx frame status.
- pr_debug(KERN_INFO "send queued packets\n");
+ pr_debug("send queued packets\n");
for (;;) {
// send first buffer from queue
skb = skb_dequeue(&bp->SendSkbQueue);
if (!skb) {
- pr_debug(KERN_INFO "queue empty\n");
+ pr_debug("queue empty\n");
return;
} // queue empty !
@@ -1232,7 +1232,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr)
static void ResetAdapter(struct s_smc *smc)
{
- pr_debug(KERN_INFO "[fddi: ResetAdapter]\n");
+ pr_debug("[fddi: ResetAdapter]\n");
// Stop the adapter.
@@ -1278,7 +1278,7 @@ void llc_restart_tx(struct s_smc *smc)
{
skfddi_priv *bp = &smc->os;
- pr_debug(KERN_INFO "[llc_restart_tx]\n");
+ pr_debug("[llc_restart_tx]\n");
// Try to send queued packets
spin_unlock(&bp->DriverLock);
@@ -1308,7 +1308,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
{
void *virt;
- pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
+ pr_debug("mac_drv_get_space (%d bytes), ", size);
virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
@@ -1317,9 +1317,9 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
}
smc->os.SharedMemHeap += size; // Move heap pointer.
- pr_debug(KERN_INFO "mac_drv_get_space end\n");
- pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt);
- pr_debug(KERN_INFO "bus addr: %lx\n", (ulong)
+ pr_debug("mac_drv_get_space end\n");
+ pr_debug("virt addr: %lx\n", (ulong) virt);
+ pr_debug("bus addr: %lx\n", (ulong)
(smc->os.SharedMemDMA +
((char *) virt - (char *)smc->os.SharedMemAddr)));
return (virt);
@@ -1349,7 +1349,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
char *virt;
- pr_debug(KERN_INFO "mac_drv_get_desc_mem\n");
+ pr_debug("mac_drv_get_desc_mem\n");
// Descriptor memory must be aligned on 16-byte boundary.
@@ -1493,7 +1493,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
{
struct sk_buff *skb;
- pr_debug(KERN_INFO "entering mac_drv_tx_complete\n");
+ pr_debug("entering mac_drv_tx_complete\n");
// Check if this TxD points to a skb
if (!(skb = txd->txd_os.skb)) {
@@ -1513,7 +1513,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
// free the skb
dev_kfree_skb_irq(skb);
- pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n");
+ pr_debug("leaving mac_drv_tx_complete\n");
} // mac_drv_tx_complete
@@ -1580,7 +1580,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
unsigned short ri;
u_int RifLength;
- pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
+ pr_debug("entering mac_drv_rx_complete (len=%d)\n", len);
if (frag_count != 1) { // This is not allowed to happen.
printk("fddi: Multi-fragment receive!\n");
@@ -1589,7 +1589,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
}
skb = rxd->rxd_os.skb;
if (!skb) {
- pr_debug(KERN_INFO "No skb in rxd\n");
+ pr_debug("No skb in rxd\n");
smc->os.MacStat.gen.rx_errors++;
goto RequeueRxd;
}
@@ -1619,7 +1619,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
else {
int n;
// goos: RIF removal has still to be tested
- pr_debug(KERN_INFO "RIF found\n");
+ pr_debug("RIF found\n");
// Get RIF length from Routing Control (RC) field.
cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header.
@@ -1664,7 +1664,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
return;
RequeueRxd:
- pr_debug(KERN_INFO "Rx: re-queue RXD.\n");
+ pr_debug("Rx: re-queue RXD.\n");
mac_drv_requeue_rxd(smc, rxd, frag_count);
smc->os.MacStat.gen.rx_errors++; // Count receive packets
// not indicated.
@@ -1775,7 +1775,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
struct sk_buff *skb;
volatile struct s_smt_fp_rxd *rxd;
- pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n");
+ pr_debug("entering mac_drv_fill_rxd\n");
// Walk through the list of free receive buffers, passing receive
// buffers to the HWM as long as RXDs are available.
@@ -1783,7 +1783,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
MaxFrameSize = smc->os.MaxFrameSize;
// Check if there is any RXD left.
while (HWM_GET_RX_FREE(smc) > 0) {
- pr_debug(KERN_INFO ".\n");
+ pr_debug(".\n");
rxd = HWM_GET_CURR_RXD(smc);
skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
@@ -1814,7 +1814,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
FIRST_FRAG | LAST_FRAG);
}
- pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n");
+ pr_debug("leaving mac_drv_fill_rxd\n");
} // mac_drv_fill_rxd
@@ -2034,17 +2034,17 @@ void smt_stat_counter(struct s_smc *smc, int stat)
{
// BOOLEAN RingIsUp ;
- pr_debug(KERN_INFO "smt_stat_counter\n");
+ pr_debug("smt_stat_counter\n");
switch (stat) {
case 0:
- pr_debug(KERN_INFO "Ring operational change.\n");
+ pr_debug("Ring operational change.\n");
break;
case 1:
- pr_debug(KERN_INFO "Receive fifo overflow.\n");
+ pr_debug("Receive fifo overflow.\n");
smc->os.MacStat.gen.rx_errors++;
break;
default:
- pr_debug(KERN_INFO "Unknown status (%d).\n", stat);
+ pr_debug("Unknown status (%d).\n", stat);
break;
}
} // smt_stat_counter
@@ -2100,10 +2100,10 @@ void cfm_state_change(struct s_smc *smc, int c_state)
s = "SC11_C_WRAP_S";
break;
default:
- pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
+ pr_debug("cfm_state_change: unknown %d\n", c_state);
return;
}
- pr_debug(KERN_INFO "cfm_state_change: %s\n", s);
+ pr_debug("cfm_state_change: %s\n", s);
#endif // DRIVERDEBUG
} // cfm_state_change
@@ -2158,7 +2158,7 @@ void ecm_state_change(struct s_smc *smc, int e_state)
s = "unknown";
break;
}
- pr_debug(KERN_INFO "ecm_state_change: %s\n", s);
+ pr_debug("ecm_state_change: %s\n", s);
#endif //DRIVERDEBUG
} // ecm_state_change
@@ -2213,7 +2213,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
s = "unknown";
break;
}
- pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s);
+ pr_debug("[rmt_state_change: %s]\n", s);
#endif // DRIVERDEBUG
} // rmt_state_change
@@ -2233,7 +2233,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
************************/
void drv_reset_indication(struct s_smc *smc)
{
- pr_debug(KERN_INFO "entering drv_reset_indication\n");
+ pr_debug("entering drv_reset_indication\n");
smc->os.ResetRequested = TRUE; // Set flag.
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 40e5c46e7571..a8a63581d63d 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3178,8 +3178,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
skb = skge_rx_get(dev, e, control, rd->status, rd->csum2);
if (likely(skb)) {
- netif_receive_skb(skb);
-
+ napi_gro_receive(napi, skb);
++work_done;
}
}
@@ -3192,6 +3191,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
if (work_done < to_do) {
unsigned long flags;
+ napi_gro_flush(napi);
spin_lock_irqsave(&hw->hw_lock, flags);
__napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
@@ -3849,6 +3849,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
skge->rx_csum = 1;
}
+ dev->features |= NETIF_F_GRO;
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index fa434fb8fb7c..38547a8938fe 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -271,7 +271,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
memcpy(sl->xbuff, sl->xhead, sl->xleft);
} else {
sl->xleft = 0;
- sl->tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
sl->xhead = sl->xbuff;
@@ -281,7 +281,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
memcpy(sl->rbuff, rbuff, sl->rcount);
} else {
sl->rcount = 0;
- sl->rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -319,6 +319,7 @@ static inline void sl_unlock(struct slip *sl)
/* Send one completely decapsulated IP datagram to the IP layer. */
static void sl_bump(struct slip *sl)
{
+ struct net_device *dev = sl->dev;
struct sk_buff *skb;
int count;
@@ -329,13 +330,13 @@ static void sl_bump(struct slip *sl)
if (c & SL_TYPE_COMPRESSED_TCP) {
/* ignore compressed packets when CSLIP is off */
if (!(sl->mode & SL_MODE_CSLIP)) {
- printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name);
+ printk(KERN_WARNING "%s: compressed packet ignored\n", dev->name);
return;
}
/* make sure we've reserved enough space for uncompress
to use */
if (count + 80 > sl->buffsize) {
- sl->rx_over_errors++;
+ dev->stats.rx_over_errors++;
return;
}
count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
@@ -346,7 +347,7 @@ static void sl_bump(struct slip *sl)
/* turn on header compression */
sl->mode |= SL_MODE_CSLIP;
sl->mode &= ~SL_MODE_ADAPTIVE;
- printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name);
+ printk(KERN_INFO "%s: header compression turned on\n", dev->name);
}
sl->rbuff[0] &= 0x4f;
if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0)
@@ -355,20 +356,20 @@ static void sl_bump(struct slip *sl)
}
#endif /* SL_INCLUDE_CSLIP */
- sl->rx_bytes += count;
+ dev->stats.rx_bytes += count;
skb = dev_alloc_skb(count);
if (skb == NULL) {
- printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
- sl->rx_dropped++;
+ printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
+ dev->stats.rx_dropped++;
return;
}
- skb->dev = sl->dev;
+ skb->dev = dev;
memcpy(skb_put(skb, count), sl->rbuff, count);
skb_reset_mac_header(skb);
skb->protocol = htons(ETH_P_IP);
netif_rx(skb);
- sl->rx_packets++;
+ dev->stats.rx_packets++;
}
/* Encapsulate one IP datagram and stuff into a TTY queue. */
@@ -379,7 +380,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */
printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
- sl->tx_dropped++;
+ sl->dev->stats.tx_dropped++;
sl_unlock(sl);
return;
}
@@ -433,7 +434,7 @@ static void slip_write_wakeup(struct tty_struct *tty)
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
- sl->tx_packets++;
+ sl->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
sl_unlock(sl);
return;
@@ -496,7 +497,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
}
sl_lock(sl);
- sl->tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
sl_encaps(sl, skb->data, skb->len);
spin_unlock(&sl->lock);
@@ -558,39 +559,39 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu)
/* Netdevice get statistics request */
-static struct net_device_stats *
-sl_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *
+sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
- static struct net_device_stats stats;
- struct slip *sl = netdev_priv(dev);
+ struct net_device_stats *devstats = &dev->stats;
+ unsigned long c_rx_dropped = 0;
#ifdef SL_INCLUDE_CSLIP
- struct slcompress *comp;
-#endif
+ unsigned long c_rx_fifo_errors = 0;
+ unsigned long c_tx_fifo_errors = 0;
+ unsigned long c_collisions = 0;
+ struct slip *sl = netdev_priv(dev);
+ struct slcompress *comp = sl->slcomp;
- memset(&stats, 0, sizeof(struct net_device_stats));
-
- stats.rx_packets = sl->rx_packets;
- stats.tx_packets = sl->tx_packets;
- stats.rx_bytes = sl->rx_bytes;
- stats.tx_bytes = sl->tx_bytes;
- stats.rx_dropped = sl->rx_dropped;
- stats.tx_dropped = sl->tx_dropped;
- stats.tx_errors = sl->tx_errors;
- stats.rx_errors = sl->rx_errors;
- stats.rx_over_errors = sl->rx_over_errors;
-#ifdef SL_INCLUDE_CSLIP
- stats.rx_fifo_errors = sl->rx_compressed;
- stats.tx_fifo_errors = sl->tx_compressed;
- stats.collisions = sl->tx_misses;
- comp = sl->slcomp;
if (comp) {
- stats.rx_fifo_errors += comp->sls_i_compressed;
- stats.rx_dropped += comp->sls_i_tossed;
- stats.tx_fifo_errors += comp->sls_o_compressed;
- stats.collisions += comp->sls_o_misses;
+ c_rx_fifo_errors = comp->sls_i_compressed;
+ c_rx_dropped = comp->sls_i_tossed;
+ c_tx_fifo_errors = comp->sls_o_compressed;
+ c_collisions = comp->sls_o_misses;
}
-#endif /* CONFIG_INET */
- return (&stats);
+ stats->rx_fifo_errors = sl->rx_compressed + c_rx_fifo_errors;
+ stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors;
+ stats->collisions = sl->tx_misses + c_collisions;
+#endif
+ stats->rx_packets = devstats->rx_packets;
+ stats->tx_packets = devstats->tx_packets;
+ stats->rx_bytes = devstats->rx_bytes;
+ stats->tx_bytes = devstats->tx_bytes;
+ stats->rx_dropped = devstats->rx_dropped + c_rx_dropped;
+ stats->tx_dropped = devstats->tx_dropped;
+ stats->tx_errors = devstats->tx_errors;
+ stats->rx_errors = devstats->rx_errors;
+ stats->rx_over_errors = devstats->rx_over_errors;
+
+ return stats;
}
/* Netdevice register callback */
@@ -633,7 +634,7 @@ static const struct net_device_ops sl_netdev_ops = {
.ndo_open = sl_open,
.ndo_stop = sl_close,
.ndo_start_xmit = sl_xmit,
- .ndo_get_stats = sl_get_stats,
+ .ndo_get_stats64 = sl_get_stats64,
.ndo_change_mtu = sl_change_mtu,
.ndo_tx_timeout = sl_tx_timeout,
#ifdef CONFIG_SLIP_SMART
@@ -681,7 +682,7 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
while (count--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
- sl->rx_errors++;
+ sl->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -981,7 +982,7 @@ static void slip_unesc(struct slip *sl, unsigned char s)
sl->rbuff[sl->rcount++] = s;
return;
}
- sl->rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -1057,7 +1058,7 @@ static void slip_unesc6(struct slip *sl, unsigned char s)
sl->rbuff[sl->rcount++] = c;
return;
}
- sl->rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
diff --git a/drivers/net/slip.h b/drivers/net/slip.h
index 9ea5c11287d2..914e958abbfc 100644
--- a/drivers/net/slip.h
+++ b/drivers/net/slip.h
@@ -67,15 +67,6 @@ struct slip {
int xleft; /* bytes left in XMIT queue */
/* SLIP interface statistics. */
- unsigned long rx_packets; /* inbound frames counter */
- unsigned long tx_packets; /* outbound frames counter */
- unsigned long rx_bytes; /* inbound byte counte */
- unsigned long tx_bytes; /* outbound byte counter */
- unsigned long rx_errors; /* Parity, etc. errors */
- unsigned long tx_errors; /* Planned stuff */
- unsigned long rx_dropped; /* No memory for skb */
- unsigned long tx_dropped; /* When MTU change */
- unsigned long rx_over_errors; /* Frame bigger than SLIP buf. */
#ifdef SL_INCLUDE_CSLIP
unsigned long tx_compressed;
unsigned long rx_compressed;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 0909ae934ad0..13ddcd487200 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1048,7 +1048,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
pktwords);
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_receive_skb(skb);
/* Update counters */
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 1636a34d95dd..cb6bcca9d541 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1000,9 +1000,9 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
!(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
} else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (data_status & SPIDER_NET_VLAN_PACKET) {
/* further enhancements: HW-accel VLAN
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index a42b6873370b..4adf12422787 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, };
* This SUCKS.
* We need a much better method to determine if dma_addr_t is 64-bit.
*/
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
#define netdrv_addr_t __le64
@@ -302,7 +302,7 @@ enum chipset {
};
static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = {
- { 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 },
+ { PCI_VDEVICE(ADAPTEC, 0x6915), CH_6915 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, starfire_pci_tbl);
@@ -2078,11 +2078,7 @@ static int __init starfire_init (void)
printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
#endif
- /* we can do this test only at run-time... sigh */
- if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) {
- printk("This driver has dma_addr_t issues, please send email to maintainer\n");
- return -ENODEV;
- }
+ BUILD_BUG_ON(sizeof(dma_addr_t) != sizeof(netdrv_addr_t));
return pci_register_driver(&starfire_driver);
}
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index eb63d44748a7..3c2af7c6a39b 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -3,10 +3,10 @@ config STMMAC_ETH
select MII
select PHYLIB
select CRC32
- depends on NETDEVICES && CPU_SUBTYPE_ST40
+ depends on NETDEVICES
help
This is the driver for the Ethernet IPs are built around a
- Synopsys IP Core and fully tested on the STMicroelectronics
+ Synopsys IP Core and only tested on the STMicroelectronics
platforms.
if STMMAC_ETH
@@ -32,6 +32,7 @@ config STMMAC_DUAL_MAC
config STMMAC_TIMER
bool "STMMAC Timer optimisation"
default n
+ depends on RTC_HCTOSYS_DEVICE
help
Use an external timer for mitigating the number of network
interrupts. Currently, for SH architectures, it is possible
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 66b9da0260fe..e8cbcb5c206e 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -167,7 +167,7 @@ struct stmmac_desc_ops {
int (*get_tx_ls) (struct dma_desc *p);
/* Return the transmit status looking at the TDES1 */
int (*tx_status) (void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr);
+ struct dma_desc *p, void __iomem *ioaddr);
/* Get the buffer size from the descriptor */
int (*get_tx_len) (struct dma_desc *p);
/* Handle extra events on specific interrupts hw dependent */
@@ -182,44 +182,44 @@ struct stmmac_desc_ops {
struct stmmac_dma_ops {
/* DMA core initialization */
- int (*init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+ int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
/* Dump DMA registers */
- void (*dump_regs) (unsigned long ioaddr);
+ void (*dump_regs) (void __iomem *ioaddr);
/* Set tx/rx threshold in the csr6 register
* An invalid value enables the store-and-forward mode */
- void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
+ void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
/* To track extra statistic (if supported) */
void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
- unsigned long ioaddr);
- void (*enable_dma_transmission) (unsigned long ioaddr);
- void (*enable_dma_irq) (unsigned long ioaddr);
- void (*disable_dma_irq) (unsigned long ioaddr);
- void (*start_tx) (unsigned long ioaddr);
- void (*stop_tx) (unsigned long ioaddr);
- void (*start_rx) (unsigned long ioaddr);
- void (*stop_rx) (unsigned long ioaddr);
- int (*dma_interrupt) (unsigned long ioaddr,
+ void __iomem *ioaddr);
+ void (*enable_dma_transmission) (void __iomem *ioaddr);
+ void (*enable_dma_irq) (void __iomem *ioaddr);
+ void (*disable_dma_irq) (void __iomem *ioaddr);
+ void (*start_tx) (void __iomem *ioaddr);
+ void (*stop_tx) (void __iomem *ioaddr);
+ void (*start_rx) (void __iomem *ioaddr);
+ void (*stop_rx) (void __iomem *ioaddr);
+ int (*dma_interrupt) (void __iomem *ioaddr,
struct stmmac_extra_stats *x);
};
struct stmmac_ops {
/* MAC core initialization */
- void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
+ void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
/* Dump MAC registers */
- void (*dump_regs) (unsigned long ioaddr);
+ void (*dump_regs) (void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
- void (*host_irq_status) (unsigned long ioaddr);
+ void (*host_irq_status) (void __iomem *ioaddr);
/* Multicast filter setting */
void (*set_filter) (struct net_device *dev);
/* Flow control setting */
- void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
+ void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time);
/* Set power management mode (e.g. magic frame) */
- void (*pmt) (unsigned long ioaddr, unsigned long mode);
+ void (*pmt) (void __iomem *ioaddr, unsigned long mode);
/* Set/Get Unicast MAC addresses */
- void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
- void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
+ void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
};
@@ -243,11 +243,11 @@ struct mac_device_info {
struct mac_link link;
};
-struct mac_device_info *dwmac1000_setup(unsigned long addr);
-struct mac_device_info *dwmac100_setup(unsigned long addr);
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
-extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
unsigned int high, unsigned int low);
-extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int high, unsigned int low);
-extern void dwmac_dma_flush_tx_fifo(unsigned long ioaddr);
+extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 2b2f5c8caf1c..f1f426146f40 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -30,7 +30,7 @@
#include <linux/slab.h>
#include "dwmac1000.h"
-static void dwmac1000_core_init(unsigned long ioaddr)
+static void dwmac1000_core_init(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + GMAC_CONTROL);
value |= GMAC_CORE_INIT;
@@ -50,10 +50,10 @@ static void dwmac1000_core_init(unsigned long ioaddr)
#endif
}
-static void dwmac1000_dump_regs(unsigned long ioaddr)
+static void dwmac1000_dump_regs(void __iomem *ioaddr)
{
int i;
- pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr);
+ pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
for (i = 0; i < 55; i++) {
int offset = i * 4;
@@ -62,14 +62,14 @@ static void dwmac1000_dump_regs(unsigned long ioaddr)
}
}
-static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
GMAC_ADDR_LOW(reg_n));
}
-static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
@@ -78,7 +78,7 @@ static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
static void dwmac1000_set_filter(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = (void __iomem *) dev->base_addr;
unsigned int value = 0;
CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
@@ -139,7 +139,7 @@ static void dwmac1000_set_filter(struct net_device *dev)
readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
}
-static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
unsigned int flow = 0;
@@ -162,7 +162,7 @@ static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
writel(flow, ioaddr + GMAC_FLOW_CTRL);
}
-static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
+static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
{
unsigned int pmt = 0;
@@ -178,7 +178,7 @@ static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
}
-static void dwmac1000_irq_status(unsigned long ioaddr)
+static void dwmac1000_irq_status(void __iomem *ioaddr)
{
u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
@@ -211,7 +211,7 @@ struct stmmac_ops dwmac1000_ops = {
.get_umac_addr = dwmac1000_get_umac_addr,
};
-struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
{
struct mac_device_info *mac;
u32 uid = readl(ioaddr + GMAC_VERSION);
diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c
index 415805057cb0..2ef5a56370e9 100644
--- a/drivers/net/stmmac/dwmac1000_dma.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -29,7 +29,7 @@
#include "dwmac1000.h"
#include "dwmac_dma.h"
-static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
@@ -58,7 +58,7 @@ static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
return 0;
}
-static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
+static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
int rxmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -111,12 +111,12 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
/* Not yet implemented --- no RMON module */
static void dwmac1000_dma_diagnostic_fr(void *data,
- struct stmmac_extra_stats *x, unsigned long ioaddr)
+ struct stmmac_extra_stats *x, void __iomem *ioaddr)
{
return;
}
-static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
+static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
{
int i;
pr_info(" DMA registers\n");
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
index 2fb165fa2ba0..db06c04ce480 100644
--- a/drivers/net/stmmac/dwmac100_core.c
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -31,7 +31,7 @@
#include <linux/crc32.h>
#include "dwmac100.h"
-static void dwmac100_core_init(unsigned long ioaddr)
+static void dwmac100_core_init(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CONTROL);
@@ -42,12 +42,12 @@ static void dwmac100_core_init(unsigned long ioaddr)
#endif
}
-static void dwmac100_dump_mac_regs(unsigned long ioaddr)
+static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
{
pr_info("\t----------------------------------------------\n"
- "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
+ "\t DWMAC 100 CSR (base addr = 0x%p)\n"
"\t----------------------------------------------\n",
- (unsigned int)ioaddr);
+ ioaddr);
pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
readl(ioaddr + MAC_CONTROL));
pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
@@ -77,18 +77,18 @@ static void dwmac100_dump_mac_regs(unsigned long ioaddr)
MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
}
-static void dwmac100_irq_status(unsigned long ioaddr)
+static void dwmac100_irq_status(void __iomem *ioaddr)
{
return;
}
-static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
}
-static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
+static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n)
{
stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
@@ -96,7 +96,7 @@ static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
static void dwmac100_set_filter(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = (void __iomem *) dev->base_addr;
u32 value = readl(ioaddr + MAC_CONTROL);
if (dev->flags & IFF_PROMISC) {
@@ -145,7 +145,7 @@ static void dwmac100_set_filter(struct net_device *dev)
readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
}
-static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
+static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
unsigned int flow = MAC_FLOW_CTRL_ENABLE;
@@ -158,7 +158,7 @@ static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
/* No PMT module supported for this Ethernet Controller.
* Tested on ST platforms only.
*/
-static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
+static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
{
return;
}
@@ -174,7 +174,7 @@ struct stmmac_ops dwmac100_ops = {
.get_umac_addr = dwmac100_get_umac_addr,
};
-struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
{
struct mac_device_info *mac;
diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c
index 2fece7b72727..c7279d2b946b 100644
--- a/drivers/net/stmmac/dwmac100_dma.c
+++ b/drivers/net/stmmac/dwmac100_dma.c
@@ -31,7 +31,7 @@
#include "dwmac100.h"
#include "dwmac_dma.h"
-static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
+static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
@@ -58,7 +58,7 @@ static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
/* Store and Forward capability is not used at all..
* The transmit threshold can be programmed by
* setting the TTC bits in the DMA control register.*/
-static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
+static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
int rxmode)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
@@ -73,7 +73,7 @@ static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
writel(csr6, ioaddr + DMA_CONTROL);
}
-static void dwmac100_dump_dma_regs(unsigned long ioaddr)
+static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
{
int i;
@@ -91,7 +91,7 @@ static void dwmac100_dump_dma_regs(unsigned long ioaddr)
/* DMA controller has two counters to track the number of
* the receive missed frames. */
static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
- unsigned long ioaddr)
+ void __iomem *ioaddr)
{
struct net_device_stats *stats = (struct net_device_stats *)data;
u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h
index 7b815a1b7b8c..da3f5ccf83d3 100644
--- a/drivers/net/stmmac/dwmac_dma.h
+++ b/drivers/net/stmmac/dwmac_dma.h
@@ -97,12 +97,12 @@
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
-extern void dwmac_enable_dma_transmission(unsigned long ioaddr);
-extern void dwmac_enable_dma_irq(unsigned long ioaddr);
-extern void dwmac_disable_dma_irq(unsigned long ioaddr);
-extern void dwmac_dma_start_tx(unsigned long ioaddr);
-extern void dwmac_dma_stop_tx(unsigned long ioaddr);
-extern void dwmac_dma_start_rx(unsigned long ioaddr);
-extern void dwmac_dma_stop_rx(unsigned long ioaddr);
-extern int dwmac_dma_interrupt(unsigned long ioaddr,
+extern void dwmac_enable_dma_transmission(void __iomem *ioaddr);
+extern void dwmac_enable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_disable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_dma_start_tx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_tx(void __iomem *ioaddr);
+extern void dwmac_dma_start_rx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_rx(void __iomem *ioaddr);
+extern int dwmac_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x);
diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c
index a85415216ef4..d65fab1ba790 100644
--- a/drivers/net/stmmac/dwmac_lib.c
+++ b/drivers/net/stmmac/dwmac_lib.c
@@ -32,43 +32,43 @@
#endif
/* CSR1 enables the transmit DMA to check for new descriptor */
-void dwmac_enable_dma_transmission(unsigned long ioaddr)
+void dwmac_enable_dma_transmission(void __iomem *ioaddr)
{
writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
}
-void dwmac_enable_dma_irq(unsigned long ioaddr)
+void dwmac_enable_dma_irq(void __iomem *ioaddr)
{
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
}
-void dwmac_disable_dma_irq(unsigned long ioaddr)
+void dwmac_disable_dma_irq(void __iomem *ioaddr)
{
writel(0, ioaddr + DMA_INTR_ENA);
}
-void dwmac_dma_start_tx(unsigned long ioaddr)
+void dwmac_dma_start_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_stop_tx(unsigned long ioaddr)
+void dwmac_dma_stop_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_start_rx(unsigned long ioaddr)
+void dwmac_dma_start_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL);
}
-void dwmac_dma_stop_rx(unsigned long ioaddr)
+void dwmac_dma_stop_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_SR;
@@ -145,7 +145,7 @@ static void show_rx_process_state(unsigned int status)
}
#endif
-int dwmac_dma_interrupt(unsigned long ioaddr,
+int dwmac_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x)
{
int ret = 0;
@@ -219,7 +219,7 @@ int dwmac_dma_interrupt(unsigned long ioaddr,
return ret;
}
-void dwmac_dma_flush_tx_fifo(unsigned long ioaddr)
+void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
{
u32 csr6 = readl(ioaddr + DMA_CONTROL);
writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
@@ -227,7 +227,7 @@ void dwmac_dma_flush_tx_fifo(unsigned long ioaddr)
do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
}
-void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
+void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
unsigned int high, unsigned int low)
{
unsigned long data;
@@ -238,7 +238,7 @@ void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
writel(data, ioaddr + low);
}
-void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
+void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int high, unsigned int low)
{
unsigned int hi_addr, lo_addr;
diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c
index f612f986a7e1..77ff88c3958b 100644
--- a/drivers/net/stmmac/enh_desc.c
+++ b/drivers/net/stmmac/enh_desc.c
@@ -25,7 +25,7 @@
#include "common.h"
static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr)
+ struct dma_desc *p, void __iomem *ioaddr)
{
int ret = 0;
struct net_device_stats *stats = (struct net_device_stats *)data;
diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c
index 31ad53643792..51f4440ab98b 100644
--- a/drivers/net/stmmac/norm_desc.c
+++ b/drivers/net/stmmac/norm_desc.c
@@ -25,7 +25,7 @@
#include "common.h"
static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
- struct dma_desc *p, unsigned long ioaddr)
+ struct dma_desc *p, void __iomem *ioaddr)
{
int ret = 0;
struct net_device_stats *stats = (struct net_device_stats *)data;
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index ebebc644b1b8..d0ddab0d21c2 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -21,6 +21,7 @@
*******************************************************************************/
#define DRV_MODULE_VERSION "Apr_2010"
+#include <linux/platform_device.h>
#include <linux/stmmac.h>
#include "common.h"
@@ -54,6 +55,7 @@ struct stmmac_priv {
unsigned int dma_buf_sz;
struct device *device;
struct mac_device_info *hw;
+ void __iomem *ioaddr;
struct stmmac_extra_stats xstats;
struct napi_struct napi;
@@ -65,7 +67,7 @@ struct stmmac_priv {
int phy_mask;
int (*phy_reset) (void *priv);
void (*fix_mac_speed) (void *priv, unsigned int speed);
- void (*bus_setup)(unsigned long ioaddr);
+ void (*bus_setup)(void __iomem *ioaddr);
void *bsp_priv;
int phy_irq;
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index f080509923f0..63b68e61afce 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -177,21 +177,21 @@ void stmmac_ethtool_gregs(struct net_device *dev,
if (!priv->is_gmac) {
/* MAC registers */
for (i = 0; i < 12; i++)
- reg_space[i] = readl(dev->base_addr + (i * 4));
+ reg_space[i] = readl(priv->ioaddr + (i * 4));
/* DMA registers */
for (i = 0; i < 9; i++)
reg_space[i + 12] =
- readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
- reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR);
- reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR);
+ readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
+ reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
+ reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
} else {
/* MAC registers */
for (i = 0; i < 55; i++)
- reg_space[i] = readl(dev->base_addr + (i * 4));
+ reg_space[i] = readl(priv->ioaddr + (i * 4));
/* DMA registers */
for (i = 0; i < 22; i++)
reg_space[i + 55] =
- readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
+ readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
}
}
@@ -263,11 +263,9 @@ stmmac_set_pauseparam(struct net_device *netdev,
cmd.phy_address = phy->addr;
ret = phy_ethtool_sset(phy, &cmd);
}
- } else {
- unsigned long ioaddr = netdev->base_addr;
- priv->hw->mac->flow_ctrl(ioaddr, phy->duplex,
+ } else
+ priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
priv->flow_ctrl, priv->pause);
- }
spin_unlock(&priv->lock);
return ret;
}
@@ -276,12 +274,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *dummy, u64 *data)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int i;
/* Update HW stats if supported */
priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
- ioaddr);
+ priv->ioaddr);
for (i = 0; i < STMMAC_STATS_LEN; i++) {
char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index bbb7951b9c4c..03c160c6d75c 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -202,7 +202,6 @@ static void stmmac_adjust_link(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev;
- unsigned long ioaddr = dev->base_addr;
unsigned long flags;
int new_state = 0;
unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
@@ -215,7 +214,7 @@ static void stmmac_adjust_link(struct net_device *dev)
spin_lock_irqsave(&priv->lock, flags);
if (phydev->link) {
- u32 ctrl = readl(ioaddr + MAC_CTRL_REG);
+ u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
@@ -229,7 +228,7 @@ static void stmmac_adjust_link(struct net_device *dev)
}
/* Flow Control operation */
if (phydev->pause)
- priv->hw->mac->flow_ctrl(ioaddr, phydev->duplex,
+ priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
fc, pause_time);
if (phydev->speed != priv->speed) {
@@ -238,6 +237,9 @@ static void stmmac_adjust_link(struct net_device *dev)
case 1000:
if (likely(priv->is_gmac))
ctrl &= ~priv->hw->link.port;
+ if (likely(priv->fix_mac_speed))
+ priv->fix_mac_speed(priv->bsp_priv,
+ phydev->speed);
break;
case 100:
case 10:
@@ -265,7 +267,7 @@ static void stmmac_adjust_link(struct net_device *dev)
priv->speed = phydev->speed;
}
- writel(ctrl, ioaddr + MAC_CTRL_REG);
+ writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
if (!priv->oldlink) {
new_state = 1;
@@ -342,7 +344,7 @@ static int stmmac_init_phy(struct net_device *dev)
return 0;
}
-static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
+static inline void stmmac_mac_enable_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value |= MAC_RNABLE_RX;
@@ -350,7 +352,7 @@ static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
+static inline void stmmac_mac_enable_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value |= MAC_ENABLE_TX;
@@ -358,14 +360,14 @@ static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_disable_rx(unsigned long ioaddr)
+static inline void stmmac_mac_disable_rx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value &= ~MAC_RNABLE_RX;
writel(value, ioaddr + MAC_CTRL_REG);
}
-static inline void stmmac_mac_disable_tx(unsigned long ioaddr)
+static inline void stmmac_mac_disable_tx(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + MAC_CTRL_REG);
value &= ~MAC_ENABLE_TX;
@@ -574,17 +576,17 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
{
if (!priv->is_gmac) {
/* MAC 10/100 */
- priv->hw->dma->dma_mode(priv->dev->base_addr, tc, 0);
+ priv->hw->dma->dma_mode(priv->ioaddr, tc, 0);
priv->tx_coe = NO_HW_CSUM;
} else {
if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
- priv->hw->dma->dma_mode(priv->dev->base_addr,
+ priv->hw->dma->dma_mode(priv->ioaddr,
SF_DMA_MODE, SF_DMA_MODE);
tc = SF_DMA_MODE;
priv->tx_coe = HW_CSUM;
} else {
/* Checksum computation is performed in software. */
- priv->hw->dma->dma_mode(priv->dev->base_addr, tc,
+ priv->hw->dma->dma_mode(priv->ioaddr, tc,
SF_DMA_MODE);
priv->tx_coe = NO_HW_CSUM;
}
@@ -600,7 +602,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
static void stmmac_tx(struct stmmac_priv *priv)
{
unsigned int txsize = priv->dma_tx_size;
- unsigned long ioaddr = priv->dev->base_addr;
while (priv->dirty_tx != priv->cur_tx) {
int last;
@@ -618,7 +619,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
int tx_error =
priv->hw->desc->tx_status(&priv->dev->stats,
&priv->xstats, p,
- ioaddr);
+ priv->ioaddr);
if (likely(tx_error == 0)) {
priv->dev->stats.tx_packets++;
priv->xstats.tx_pkt_n++;
@@ -674,7 +675,7 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv)
priv->tm->timer_start(tmrate);
else
#endif
- priv->hw->dma->enable_dma_irq(priv->dev->base_addr);
+ priv->hw->dma->enable_dma_irq(priv->ioaddr);
}
static inline void stmmac_disable_irq(struct stmmac_priv *priv)
@@ -684,7 +685,7 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv)
priv->tm->timer_stop();
else
#endif
- priv->hw->dma->disable_dma_irq(priv->dev->base_addr);
+ priv->hw->dma->disable_dma_irq(priv->ioaddr);
}
static int stmmac_has_work(struct stmmac_priv *priv)
@@ -739,14 +740,15 @@ static void stmmac_no_timer_stopped(void)
*/
static void stmmac_tx_err(struct stmmac_priv *priv)
{
+
netif_stop_queue(priv->dev);
- priv->hw->dma->stop_tx(priv->dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
dma_free_tx_skbufs(priv);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
priv->dirty_tx = 0;
priv->cur_tx = 0;
- priv->hw->dma->start_tx(priv->dev->base_addr);
+ priv->hw->dma->start_tx(priv->ioaddr);
priv->dev->stats.tx_errors++;
netif_wake_queue(priv->dev);
@@ -755,11 +757,9 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
static void stmmac_dma_interrupt(struct stmmac_priv *priv)
{
- unsigned long ioaddr = priv->dev->base_addr;
int status;
- status = priv->hw->dma->dma_interrupt(priv->dev->base_addr,
- &priv->xstats);
+ status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
if (likely(status == handle_tx_rx))
_stmmac_schedule(priv);
@@ -767,7 +767,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
/* Try to bump up the dma threshold on this failure */
if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
tc += 64;
- priv->hw->dma->dma_mode(ioaddr, tc, SF_DMA_MODE);
+ priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
priv->xstats.threshold = tc;
}
stmmac_tx_err(priv);
@@ -787,7 +787,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
static int stmmac_open(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int ret;
/* Check that the MAC address is valid. If its not, refuse
@@ -843,7 +842,8 @@ static int stmmac_open(struct net_device *dev)
init_dma_desc_rings(dev);
/* DMA initialization and SW reset */
- if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy,
+ if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl,
+ priv->dma_tx_phy,
priv->dma_rx_phy) < 0)) {
pr_err("%s: DMA initialization failed\n", __func__);
@@ -851,22 +851,22 @@ static int stmmac_open(struct net_device *dev)
}
/* Copy the MAC addr into the HW */
- priv->hw->mac->set_umac_addr(ioaddr, dev->dev_addr, 0);
+ priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
/* If required, perform hw setup of the bus. */
if (priv->bus_setup)
- priv->bus_setup(ioaddr);
+ priv->bus_setup(priv->ioaddr);
/* Initialize the MAC Core */
- priv->hw->mac->core_init(ioaddr);
+ priv->hw->mac->core_init(priv->ioaddr);
priv->shutdown = 0;
/* Initialise the MMC (if present) to disable all interrupts. */
- writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK);
- writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK);
+ writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
+ writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
/* Enable the MAC Rx/Tx */
- stmmac_mac_enable_rx(ioaddr);
- stmmac_mac_enable_tx(ioaddr);
+ stmmac_mac_enable_rx(priv->ioaddr);
+ stmmac_mac_enable_tx(priv->ioaddr);
/* Set the HW DMA mode and the COE */
stmmac_dma_operation_mode(priv);
@@ -877,16 +877,16 @@ static int stmmac_open(struct net_device *dev)
/* Start the ball rolling... */
DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
- priv->hw->dma->start_tx(ioaddr);
- priv->hw->dma->start_rx(ioaddr);
+ priv->hw->dma->start_tx(priv->ioaddr);
+ priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_start(tmrate);
#endif
/* Dump DMA/MAC registers */
if (netif_msg_hw(priv)) {
- priv->hw->mac->dump_regs(ioaddr);
- priv->hw->dma->dump_regs(ioaddr);
+ priv->hw->mac->dump_regs(priv->ioaddr);
+ priv->hw->dma->dump_regs(priv->ioaddr);
}
if (priv->phydev)
@@ -930,15 +930,15 @@ static int stmmac_release(struct net_device *dev)
free_irq(dev->irq, dev);
/* Stop TX/RX DMA and clear the descriptors */
- priv->hw->dma->stop_tx(dev->base_addr);
- priv->hw->dma->stop_rx(dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
/* Release and free the Rx/Tx resources */
free_dma_desc_resources(priv);
/* Disable the MAC core */
- stmmac_mac_disable_tx(dev->base_addr);
- stmmac_mac_disable_rx(dev->base_addr);
+ stmmac_mac_disable_tx(priv->ioaddr);
+ stmmac_mac_disable_rx(priv->ioaddr);
netif_carrier_off(dev);
@@ -1140,7 +1140,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
- priv->hw->dma->enable_dma_transmission(dev->base_addr);
+ priv->hw->dma->enable_dma_transmission(priv->ioaddr);
return NETDEV_TX_OK;
}
@@ -1256,7 +1256,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
if (unlikely(status == csum_none)) {
/* always for the old mac 10/100 */
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
netif_receive_skb(skb);
} else {
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1405,11 +1405,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
- if (priv->is_gmac) {
- unsigned long ioaddr = dev->base_addr;
+ if (priv->is_gmac)
/* To handle GMAC own interrupts */
- priv->hw->mac->host_irq_status(ioaddr);
- }
+ priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
stmmac_dma_interrupt(priv);
@@ -1522,7 +1520,8 @@ static int stmmac_probe(struct net_device *dev)
netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
/* Get the MAC address */
- priv->hw->mac->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
+ priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
+ dev->dev_addr, 0);
if (!is_valid_ether_addr(dev->dev_addr))
pr_warning("\tno valid MAC address;"
@@ -1552,14 +1551,13 @@ static int stmmac_probe(struct net_device *dev)
static int stmmac_mac_device_setup(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
struct mac_device_info *device;
if (priv->is_gmac)
- device = dwmac1000_setup(ioaddr);
+ device = dwmac1000_setup(priv->ioaddr);
else
- device = dwmac100_setup(ioaddr);
+ device = dwmac100_setup(priv->ioaddr);
if (!device)
return -ENOMEM;
@@ -1653,7 +1651,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *res;
- unsigned int *addr = NULL;
+ void __iomem *addr = NULL;
struct net_device *ndev = NULL;
struct stmmac_priv *priv;
struct plat_stmmacenet_data *plat_dat;
@@ -1708,6 +1706,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
priv->pbl = plat_dat->pbl; /* TLI */
priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
priv->enh_desc = plat_dat->enh_desc;
+ priv->ioaddr = addr;
platform_set_drvdata(pdev, ndev);
@@ -1743,8 +1742,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
priv->bsp_priv = plat_dat->bsp_priv;
pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
- "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name,
- pdev->id, ndev->irq, (unsigned int)addr);
+ "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
+ pdev->id, ndev->irq, addr);
/* MDIO bus Registration */
pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
@@ -1779,11 +1778,11 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
pr_info("%s:\n\tremoving driver", __func__);
- priv->hw->dma->stop_rx(ndev->base_addr);
- priv->hw->dma->stop_tx(ndev->base_addr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
- stmmac_mac_disable_rx(ndev->base_addr);
- stmmac_mac_disable_tx(ndev->base_addr);
+ stmmac_mac_disable_rx(priv->ioaddr);
+ stmmac_mac_disable_tx(priv->ioaddr);
netif_carrier_off(ndev);
@@ -1792,7 +1791,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
- iounmap((void *)ndev->base_addr);
+ iounmap((void *)priv->ioaddr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
@@ -1827,22 +1826,21 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
napi_disable(&priv->napi);
/* Stop TX/RX DMA */
- priv->hw->dma->stop_tx(dev->base_addr);
- priv->hw->dma->stop_rx(dev->base_addr);
+ priv->hw->dma->stop_tx(priv->ioaddr);
+ priv->hw->dma->stop_rx(priv->ioaddr);
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
dis_ic);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
- stmmac_mac_disable_tx(dev->base_addr);
+ stmmac_mac_disable_tx(priv->ioaddr);
if (device_may_wakeup(&(pdev->dev))) {
/* Enable Power down mode by programming the PMT regs */
if (priv->wolenabled == PMT_SUPPORTED)
- priv->hw->mac->pmt(dev->base_addr,
- priv->wolopts);
+ priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
} else {
- stmmac_mac_disable_rx(dev->base_addr);
+ stmmac_mac_disable_rx(priv->ioaddr);
}
} else {
priv->shutdown = 1;
@@ -1860,20 +1858,19 @@ static int stmmac_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
if (!netif_running(dev))
return 0;
- spin_lock(&priv->lock);
-
if (priv->shutdown) {
/* Re-open the interface and re-init the MAC/DMA
- and the rings. */
+ and the rings (i.e. on hibernation stage) */
stmmac_open(dev);
- goto out_resume;
+ return 0;
}
+ spin_lock(&priv->lock);
+
/* Power Down bit, into the PM register, is cleared
* automatically as soon as a magic packet or a Wake-up frame
* is received. Anyway, it's better to manually clear
@@ -1881,15 +1878,15 @@ static int stmmac_resume(struct platform_device *pdev)
* from another devices (e.g. serial console). */
if (device_may_wakeup(&(pdev->dev)))
if (priv->wolenabled == PMT_SUPPORTED)
- priv->hw->mac->pmt(dev->base_addr, 0);
+ priv->hw->mac->pmt(priv->ioaddr, 0);
netif_device_attach(dev);
/* Enable the MAC and DMA */
- stmmac_mac_enable_rx(ioaddr);
- stmmac_mac_enable_tx(ioaddr);
- priv->hw->dma->start_tx(ioaddr);
- priv->hw->dma->start_rx(ioaddr);
+ stmmac_mac_enable_rx(priv->ioaddr);
+ stmmac_mac_enable_tx(priv->ioaddr);
+ priv->hw->dma->start_tx(priv->ioaddr);
+ priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_start(tmrate);
@@ -1901,7 +1898,6 @@ static int stmmac_resume(struct platform_device *pdev)
netif_start_queue(dev);
-out_resume:
spin_unlock(&priv->lock);
return 0;
}
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
index 40b2c7929719..03dea1401571 100644
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -47,7 +47,6 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
@@ -56,12 +55,12 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
((phyreg << 6) & (0x000007C0)));
regValue |= MII_BUSY; /* in case of GMAC */
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
- writel(regValue, ioaddr + mii_address);
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ writel(regValue, priv->ioaddr + mii_address);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
/* Read the data from the MII data register */
- data = (int)readl(ioaddr + mii_data);
+ data = (int)readl(priv->ioaddr + mii_data);
return data;
}
@@ -79,7 +78,6 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
@@ -90,14 +88,14 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
value |= MII_BUSY;
/* Wait until any existing MII operation is complete */
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
/* Set the MII address register to write */
- writel(phydata, ioaddr + mii_data);
- writel(value, ioaddr + mii_address);
+ writel(phydata, priv->ioaddr + mii_data);
+ writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */
- do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
+ do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
return 0;
}
@@ -111,7 +109,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned long ioaddr = ndev->base_addr;
unsigned int mii_address = priv->hw->mii.addr;
if (priv->phy_reset) {
@@ -123,7 +120,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
* It doesn't complete its reset until at least one clock cycle
* on MDC, so perform a dummy mdio read.
*/
- writel(0, ioaddr + mii_address);
+ writel(0, priv->ioaddr + mii_address);
return 0;
}
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 618643e3ca3e..0a6a5ced3c1c 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -617,7 +617,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp)
bp->timer_ticks = 0;
bp->bigmac_timer.expires = jiffies + (12 * HZ) / 10;
bp->bigmac_timer.data = (unsigned long) bp;
- bp->bigmac_timer.function = &bigmac_timer;
+ bp->bigmac_timer.function = bigmac_timer;
add_timer(&bp->bigmac_timer);
}
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 2678588ea4b2..7dfdbee878e8 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -874,7 +874,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = jiffies + 3*HZ;
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
/* Enable interrupts by setting the interrupt mask. */
@@ -1757,11 +1757,59 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev)
}
}
+#ifdef CONFIG_PM
+
+static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pci_dev);
+
+ if (!netif_running(dev))
+ return 0;
+
+ netdev_close(dev);
+ netif_device_detach(dev);
+
+ pci_save_state(pci_dev);
+ pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+ return 0;
+}
+
+static int sundance_resume(struct pci_dev *pci_dev)
+{
+ struct net_device *dev = pci_get_drvdata(pci_dev);
+ int err = 0;
+
+ if (!netif_running(dev))
+ return 0;
+
+ pci_set_power_state(pci_dev, PCI_D0);
+ pci_restore_state(pci_dev);
+
+ err = netdev_open(dev);
+ if (err) {
+ printk(KERN_ERR "%s: Can't resume interface!\n",
+ dev->name);
+ goto out;
+ }
+
+ netif_device_attach(dev);
+
+out:
+ return err;
+}
+
+#endif /* CONFIG_PM */
+
static struct pci_driver sundance_driver = {
.name = DRV_NAME,
.id_table = sundance_pci_tbl,
.probe = sundance_probe1,
.remove = __devexit_p(sundance_remove1),
+#ifdef CONFIG_PM
+ .suspend = sundance_suspend,
+ .resume = sundance_resume,
+#endif /* CONFIG_PM */
};
static int __init sundance_init(void)
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 434f9d735333..4ceb3cf6a9a9 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -31,6 +31,8 @@
* about when we can start taking interrupts or get xmit() called...
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -105,7 +107,6 @@ MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
MODULE_LICENSE("GPL");
#define GEM_MODULE_NAME "gem"
-#define PFX GEM_MODULE_NAME ": "
static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = {
{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM,
@@ -262,8 +263,7 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
gp->dev->name, pcs_istat);
if (!(pcs_istat & PCS_ISTAT_LSC)) {
- printk(KERN_ERR "%s: PCS irq but no link status change???\n",
- dev->name);
+ netdev_err(dev, "PCS irq but no link status change???\n");
return 0;
}
@@ -282,20 +282,16 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
* when autoneg has completed.
*/
if (pcs_miistat & PCS_MIISTAT_RF)
- printk(KERN_INFO "%s: PCS AutoNEG complete, "
- "RemoteFault\n", dev->name);
+ netdev_info(dev, "PCS AutoNEG complete, RemoteFault\n");
else
- printk(KERN_INFO "%s: PCS AutoNEG complete.\n",
- dev->name);
+ netdev_info(dev, "PCS AutoNEG complete\n");
}
if (pcs_miistat & PCS_MIISTAT_LS) {
- printk(KERN_INFO "%s: PCS link is now up.\n",
- dev->name);
+ netdev_info(dev, "PCS link is now up\n");
netif_carrier_on(gp->dev);
} else {
- printk(KERN_INFO "%s: PCS link is now down.\n",
- dev->name);
+ netdev_info(dev, "PCS link is now down\n");
netif_carrier_off(gp->dev);
/* If this happens and the link timer is not running,
* reset so we re-negotiate.
@@ -323,14 +319,12 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
return 0;
if (txmac_stat & MAC_TXSTAT_URUN) {
- printk(KERN_ERR "%s: TX MAC xmit underrun.\n",
- dev->name);
+ netdev_err(dev, "TX MAC xmit underrun\n");
gp->net_stats.tx_fifo_errors++;
}
if (txmac_stat & MAC_TXSTAT_MPE) {
- printk(KERN_ERR "%s: TX MAC max packet size error.\n",
- dev->name);
+ netdev_err(dev, "TX MAC max packet size error\n");
gp->net_stats.tx_errors++;
}
@@ -377,8 +371,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX MAC will not reset, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX MAC will not reset, resetting whole chip\n");
return 1;
}
@@ -390,8 +383,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX MAC will not disable, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX MAC will not disable, resetting whole chip\n");
return 1;
}
@@ -403,8 +395,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX DMA will not disable, resetting whole "
- "chip.\n", dev->name);
+ netdev_err(dev, "RX DMA will not disable, resetting whole chip\n");
return 1;
}
@@ -419,8 +410,7 @@ static int gem_rxmac_reset(struct gem *gp)
udelay(10);
}
if (limit == 5000) {
- printk(KERN_ERR "%s: RX reset command will not execute, resetting "
- "whole chip.\n", dev->name);
+ netdev_err(dev, "RX reset command will not execute, resetting whole chip\n");
return 1;
}
@@ -429,8 +419,7 @@ static int gem_rxmac_reset(struct gem *gp)
struct gem_rxd *rxd = &gp->init_block->rxd[i];
if (gp->rx_skbs[i] == NULL) {
- printk(KERN_ERR "%s: Parts of RX ring empty, resetting "
- "whole chip.\n", dev->name);
+ netdev_err(dev, "Parts of RX ring empty, resetting whole chip\n");
return 1;
}
@@ -479,8 +468,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s
if (rxmac_stat & MAC_RXSTAT_OFLW) {
u32 smac = readl(gp->regs + MAC_SMACHINE);
- printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n",
- dev->name, smac);
+ netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac);
gp->net_stats.rx_over_errors++;
gp->net_stats.rx_fifo_errors++;
@@ -542,19 +530,18 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
- printk(KERN_ERR "%s: PCI error [%04x] ",
- dev->name, pci_estat);
+ netdev_err(dev, "PCI error [%04x]", pci_estat);
if (pci_estat & GREG_PCIESTAT_BADACK)
- printk("<No ACK64# during ABS64 cycle> ");
+ pr_cont(" <No ACK64# during ABS64 cycle>");
if (pci_estat & GREG_PCIESTAT_DTRTO)
- printk("<Delayed transaction timeout> ");
+ pr_cont(" <Delayed transaction timeout>");
if (pci_estat & GREG_PCIESTAT_OTHER)
- printk("<other>");
- printk("\n");
+ pr_cont(" <other>");
+ pr_cont("\n");
} else {
pci_estat |= GREG_PCIESTAT_OTHER;
- printk(KERN_ERR "%s: PCI error\n", dev->name);
+ netdev_err(dev, "PCI error\n");
}
if (pci_estat & GREG_PCIESTAT_OTHER) {
@@ -565,26 +552,20 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
*/
pci_read_config_word(gp->pdev, PCI_STATUS,
&pci_cfg_stat);
- printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n",
- dev->name, pci_cfg_stat);
+ netdev_err(dev, "Read PCI cfg space status [%04x]\n",
+ pci_cfg_stat);
if (pci_cfg_stat & PCI_STATUS_PARITY)
- printk(KERN_ERR "%s: PCI parity error detected.\n",
- dev->name);
+ netdev_err(dev, "PCI parity error detected\n");
if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT)
- printk(KERN_ERR "%s: PCI target abort.\n",
- dev->name);
+ netdev_err(dev, "PCI target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT)
- printk(KERN_ERR "%s: PCI master acks target abort.\n",
- dev->name);
+ netdev_err(dev, "PCI master acks target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT)
- printk(KERN_ERR "%s: PCI master abort.\n",
- dev->name);
+ netdev_err(dev, "PCI master abort\n");
if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR)
- printk(KERN_ERR "%s: PCI system error SERR#.\n",
- dev->name);
+ netdev_err(dev, "PCI system error SERR#\n");
if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY)
- printk(KERN_ERR "%s: PCI parity error.\n",
- dev->name);
+ netdev_err(dev, "PCI parity error\n");
/* Write the error bits back to clear them. */
pci_cfg_stat &= (PCI_STATUS_PARITY |
@@ -874,8 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
gp->rx_new = entry;
if (drops)
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- gp->dev->name);
+ netdev_info(gp->dev, "Memory squeeze, deferring packet\n");
return work_done;
}
@@ -981,21 +961,19 @@ static void gem_tx_timeout(struct net_device *dev)
{
struct gem *gp = netdev_priv(dev);
- printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+ netdev_err(dev, "transmit timed out, resetting\n");
if (!gp->running) {
- printk("%s: hrm.. hw not running !\n", dev->name);
+ netdev_err(dev, "hrm.. hw not running !\n");
return;
}
- printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n",
- dev->name,
- readl(gp->regs + TXDMA_CFG),
- readl(gp->regs + MAC_TXSTAT),
- readl(gp->regs + MAC_TXCFG));
- printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n",
- dev->name,
- readl(gp->regs + RXDMA_CFG),
- readl(gp->regs + MAC_RXSTAT),
- readl(gp->regs + MAC_RXCFG));
+ netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n",
+ readl(gp->regs + TXDMA_CFG),
+ readl(gp->regs + MAC_TXSTAT),
+ readl(gp->regs + MAC_TXCFG));
+ netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n",
+ readl(gp->regs + RXDMA_CFG),
+ readl(gp->regs + MAC_RXSTAT),
+ readl(gp->regs + MAC_RXCFG));
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
@@ -1048,8 +1026,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&gp->tx_lock, flags);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
- dev->name);
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -1158,8 +1135,7 @@ static void gem_pcs_reset(struct gem *gp)
break;
}
if (limit < 0)
- printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
- gp->dev->name);
+ netdev_warn(gp->dev, "PCS reset bit would not clear\n");
}
static void gem_pcs_reinit_adv(struct gem *gp)
@@ -1230,7 +1206,7 @@ static void gem_reset(struct gem *gp)
} while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST));
if (limit < 0)
- printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
+ netdev_err(gp->dev, "SW reset is ghetto\n");
if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
gem_pcs_reinit_adv(gp);
@@ -1395,9 +1371,8 @@ static int gem_set_link_modes(struct gem *gp)
speed = SPEED_1000;
}
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n",
- gp->dev->name, speed, (full_duplex ? "full" : "half"));
+ netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n",
+ speed, (full_duplex ? "full" : "half"));
if (!gp->running)
return 0;
@@ -1451,15 +1426,13 @@ static int gem_set_link_modes(struct gem *gp)
if (netif_msg_link(gp)) {
if (pause) {
- printk(KERN_INFO "%s: Pause is enabled "
- "(rxfifo: %d off: %d on: %d)\n",
- gp->dev->name,
- gp->rx_fifo_sz,
- gp->rx_pause_off,
- gp->rx_pause_on);
+ netdev_info(gp->dev,
+ "Pause is enabled (rxfifo: %d off: %d on: %d)\n",
+ gp->rx_fifo_sz,
+ gp->rx_pause_off,
+ gp->rx_pause_on);
} else {
- printk(KERN_INFO "%s: Pause is disabled\n",
- gp->dev->name);
+ netdev_info(gp->dev, "Pause is disabled\n");
}
}
@@ -1484,9 +1457,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
{
switch (gp->lstate) {
case link_force_ret:
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Autoneg failed again, keeping"
- " forced mode\n", gp->dev->name);
+ netif_info(gp, link, gp->dev,
+ "Autoneg failed again, keeping forced mode\n");
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii,
gp->last_forced_speed, DUPLEX_HALF);
gp->timer_ticks = 5;
@@ -1499,9 +1471,7 @@ static int gem_mdio_link_not_up(struct gem *gp)
*/
if (gp->phy_mii.def->magic_aneg)
return 1;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: switching to forced 100bt\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev, "switching to forced 100bt\n");
/* Try forced modes. */
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100,
DUPLEX_HALF);
@@ -1517,9 +1487,8 @@ static int gem_mdio_link_not_up(struct gem *gp)
gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10,
DUPLEX_HALF);
gp->timer_ticks = 5;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: switching to forced 10bt\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev,
+ "switching to forced 10bt\n");
return 0;
} else
return 1;
@@ -1574,8 +1543,8 @@ static void gem_link_timer(unsigned long data)
gp->last_forced_speed = gp->phy_mii.speed;
gp->timer_ticks = 5;
if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Got link after fallback, retrying"
- " autoneg once...\n", gp->dev->name);
+ netdev_info(gp->dev,
+ "Got link after fallback, retrying autoneg once...\n");
gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising);
} else if (gp->lstate != link_up) {
gp->lstate = link_up;
@@ -1589,9 +1558,7 @@ static void gem_link_timer(unsigned long data)
*/
if (gp->lstate == link_up) {
gp->lstate = link_down;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Link down\n",
- gp->dev->name);
+ netif_info(gp, link, gp->dev, "Link down\n");
netif_carrier_off(gp->dev);
gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
@@ -1746,8 +1713,7 @@ static void gem_init_phy(struct gem *gp)
if (phy_read(gp, MII_BMCR) != 0xffff)
break;
if (i == 2)
- printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
- gp->dev->name);
+ netdev_warn(gp->dev, "GMAC PHY not responding !\n");
}
}
@@ -2038,7 +2004,7 @@ static int gem_check_invariants(struct gem *gp)
* as this chip has no gigabit PHY.
*/
if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) {
- printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n",
+ pr_err("RIO GEM lacks MII phy, mif_cfg[%08x]\n",
mif_cfg);
return -1;
}
@@ -2078,7 +2044,7 @@ static int gem_check_invariants(struct gem *gp)
}
if (i == 32) {
if (pdev->device != PCI_DEVICE_ID_SUN_GEM) {
- printk(KERN_ERR PFX "RIO MII phy will not respond.\n");
+ pr_err("RIO MII phy will not respond\n");
return -1;
}
gp->phy_type = phy_serdes;
@@ -2093,7 +2059,7 @@ static int gem_check_invariants(struct gem *gp)
if (pdev->device == PCI_DEVICE_ID_SUN_GEM) {
if (gp->tx_fifo_sz != (9 * 1024) ||
gp->rx_fifo_sz != (20 * 1024)) {
- printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ pr_err("GEM has bogus fifo sizes tx(%d) rx(%d)\n",
gp->tx_fifo_sz, gp->rx_fifo_sz);
return -1;
}
@@ -2101,7 +2067,7 @@ static int gem_check_invariants(struct gem *gp)
} else {
if (gp->tx_fifo_sz != (2 * 1024) ||
gp->rx_fifo_sz != (2 * 1024)) {
- printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
+ pr_err("RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n",
gp->tx_fifo_sz, gp->rx_fifo_sz);
return -1;
}
@@ -2239,7 +2205,7 @@ static int gem_do_start(struct net_device *dev)
if (request_irq(gp->pdev->irq, gem_interrupt,
IRQF_SHARED, dev->name, (void *)dev)) {
- printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
+ netdev_err(dev, "failed to request irq !\n");
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
@@ -2378,9 +2344,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
mutex_lock(&gp->pm_mutex);
- printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
- dev->name,
- (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
+ netdev_info(dev, "suspending, WakeOnLan %s\n",
+ (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
/* Keep the cell enabled during the entire operation */
spin_lock_irqsave(&gp->lock, flags);
@@ -2440,7 +2405,7 @@ static int gem_resume(struct pci_dev *pdev)
struct gem *gp = netdev_priv(dev);
unsigned long flags;
- printk(KERN_INFO "%s: resuming\n", dev->name);
+ netdev_info(dev, "resuming\n");
mutex_lock(&gp->pm_mutex);
@@ -2452,8 +2417,7 @@ static int gem_resume(struct pci_dev *pdev)
/* Make sure PCI access and bus master are enabled */
if (pci_enable_device(gp->pdev)) {
- printk(KERN_ERR "%s: Can't re-enable chip !\n",
- dev->name);
+ netdev_err(dev, "Can't re-enable chip !\n");
/* Put cell and forget it for now, it will be considered as
* still asleep, a new sleep cycle may bring it back
*/
@@ -2938,7 +2902,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
addr = idprom->id_ethaddr;
#else
printk("\n");
- printk(KERN_ERR "%s: can't get mac-address\n", dev->name);
+ pr_err("%s: can't get mac-address\n", dev->name);
return -1;
#endif
}
@@ -3009,14 +2973,12 @@ static const struct net_device_ops gem_netdev_ops = {
static int __devinit gem_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- static int gem_version_printed = 0;
unsigned long gemreg_base, gemreg_len;
struct net_device *dev;
struct gem *gp;
int err, pci_using_dac;
- if (gem_version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ printk_once(KERN_INFO "%s", version);
/* Apple gmac note: during probe, the chip is powered up by
* the arch code to allow the code below to work (and to let
@@ -3026,8 +2988,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
*/
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR PFX "Cannot enable MMIO operation, "
- "aborting.\n");
+ pr_err("Cannot enable MMIO operation, aborting\n");
return err;
}
pci_set_master(pdev);
@@ -3048,8 +3009,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
} else {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- printk(KERN_ERR PFX "No usable DMA configuration, "
- "aborting.\n");
+ pr_err("No usable DMA configuration, aborting\n");
goto err_disable_device;
}
pci_using_dac = 0;
@@ -3059,15 +3019,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gemreg_len = pci_resource_len(pdev, 0);
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
- printk(KERN_ERR PFX "Cannot find proper PCI device "
- "base address, aborting.\n");
+ pr_err("Cannot find proper PCI device base address, aborting\n");
err = -ENODEV;
goto err_disable_device;
}
dev = alloc_etherdev(sizeof(*gp));
if (!dev) {
- printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ pr_err("Etherdev alloc failed, aborting\n");
err = -ENOMEM;
goto err_disable_device;
}
@@ -3077,8 +3036,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
- printk(KERN_ERR PFX "Cannot obtain PCI resources, "
- "aborting.\n");
+ pr_err("Cannot obtain PCI resources, aborting\n");
goto err_out_free_netdev;
}
@@ -3104,8 +3062,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->regs = ioremap(gemreg_base, gemreg_len);
if (!gp->regs) {
- printk(KERN_ERR PFX "Cannot map device registers, "
- "aborting.\n");
+ pr_err("Cannot map device registers, aborting\n");
err = -EIO;
goto err_out_free_res;
}
@@ -3150,8 +3107,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
pci_alloc_consistent(pdev, sizeof(struct gem_init_block),
&gp->gblock_dvma);
if (!gp->init_block) {
- printk(KERN_ERR PFX "Cannot allocate init block, "
- "aborting.\n");
+ pr_err("Cannot allocate init block, aborting\n");
err = -ENOMEM;
goto err_out_iounmap;
}
@@ -3180,19 +3136,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
/* Register with kernel */
if (register_netdev(dev)) {
- printk(KERN_ERR PFX "Cannot register net device, "
- "aborting.\n");
+ pr_err("Cannot register net device, aborting\n");
err = -ENOMEM;
goto err_out_free_consistent;
}
- printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
- dev->name, dev->dev_addr);
+ netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
+ dev->dev_addr);
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1)
- printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
- gp->phy_mii.def ? gp->phy_mii.def->name : "no");
+ netdev_info(dev, "Found %s PHY\n",
+ gp->phy_mii.def ? gp->phy_mii.def->name : "no");
/* GEM can do it all... */
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 78f8cee5fd74..4a4fac630337 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -1175,7 +1175,8 @@ int mii_phy_probe(struct mii_phy *phy, int mii_id)
/* Read ID and find matching entry */
id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
- printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id);
+ printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n",
+ id, mii_id);
for (i=0; (def = mii_phy_table[i]) != NULL; i++)
if ((id & def->phy_id_mask) == def->phy_id)
break;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd0df1c14955..45f315ed1868 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1409,7 +1409,7 @@ force_link:
hp->timer_ticks = 0;
hp->happy_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */
hp->happy_timer.data = (unsigned long) hp;
- hp->happy_timer.function = &happy_meal_timer;
+ hp->happy_timer.function = happy_meal_timer;
add_timer(&hp->happy_timer);
}
@@ -2808,7 +2808,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
happy_meal_set_initial_advertisement(hp);
spin_unlock_irq(&hp->happy_lock);
- if (register_netdev(hp->dev)) {
+ err = register_netdev(hp->dev);
+ if (err) {
printk(KERN_ERR "happymeal: Cannot register net device, "
"aborting.\n");
goto err_out_free_coherent;
@@ -3130,7 +3131,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
happy_meal_set_initial_advertisement(hp);
spin_unlock_irq(&hp->happy_lock);
- if (register_netdev(hp->dev)) {
+ err = register_netdev(hp->dev);
+ if (err) {
printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
"aborting.\n");
goto err_out_iounmap;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 8dcb858f2168..2cf84e5968b2 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1483,7 +1483,7 @@ no_link_test:
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
if (register_netdev(dev)) {
printk(KERN_ERR "SunLance: Cannot register device.\n");
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index d281a7b34701..bf3c762de620 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -3,6 +3,8 @@
* Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -20,7 +22,6 @@
#include "sunvnet.h"
#define DRV_MODULE_NAME "sunvnet"
-#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.0"
#define DRV_MODULE_RELDATE "June 25, 2007"
@@ -45,9 +46,9 @@ static int vnet_handle_unknown(struct vnet_port *port, void *arg)
{
struct vio_msg_tag *pkt = arg;
- printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n",
+ pr_err("Received unknown msg [%02x:%02x:%04x:%08x]\n",
pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
- printk(KERN_ERR PFX "Resetting connection.\n");
+ pr_err("Resetting connection\n");
ldc_disconnect(port->vio.lp);
@@ -400,8 +401,8 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf)
if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA))
return 0;
if (unlikely(pkt->seq != dr->rcv_nxt)) {
- printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] "
- "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt);
+ pr_err("RX out of sequence seq[0x%llx] rcv_nxt[0x%llx]\n",
+ pkt->seq, dr->rcv_nxt);
return 0;
}
@@ -464,8 +465,7 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf)
struct vio_net_mcast_info *pkt = msgbuf;
if (pkt->tag.stype != VIO_SUBTYPE_ACK)
- printk(KERN_ERR PFX "%s: Got unexpected MCAST reply "
- "[%02x:%02x:%04x:%08x]\n",
+ pr_err("%s: Got unexpected MCAST reply [%02x:%02x:%04x:%08x]\n",
port->vp->dev->name,
pkt->tag.type,
pkt->tag.stype,
@@ -520,7 +520,7 @@ static void vnet_event(void *arg, int event)
}
if (unlikely(event != LDC_EVENT_DATA_READY)) {
- printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
+ pr_warning("Unexpected LDC event %d\n", event);
spin_unlock_irqrestore(&vio->lock, flags);
return;
}
@@ -662,8 +662,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
/* This is a hard error, log it. */
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
- "queue awake!\n", dev->name);
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
dev->stats.tx_errors++;
}
spin_unlock_irqrestore(&port->vio.lock, flags);
@@ -696,8 +695,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
err = __vnet_tx_trigger(port);
if (unlikely(err < 0)) {
- printk(KERN_INFO PFX "%s: TX trigger error %d\n",
- dev->name, err);
+ netdev_info(dev, "TX trigger error %d\n", err);
d->hdr.state = VIO_DESC_FREE;
dev->stats.tx_carrier_errors++;
goto out_dropped_unlock;
@@ -952,12 +950,12 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port)
err = -ENOMEM;
if (!buf) {
- printk(KERN_ERR "TX buffer allocation failure\n");
+ pr_err("TX buffer allocation failure\n");
goto err_out;
}
err = -EFAULT;
if ((unsigned long)buf & (8UL - 1)) {
- printk(KERN_ERR "TX buffer misaligned\n");
+ pr_err("TX buffer misaligned\n");
kfree(buf);
goto err_out;
}
@@ -1030,7 +1028,7 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
dev = alloc_etherdev(sizeof(*vp));
if (!dev) {
- printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ pr_err("Etherdev alloc failed, aborting\n");
return ERR_PTR(-ENOMEM);
}
@@ -1056,12 +1054,11 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR PFX "Cannot register net device, "
- "aborting.\n");
+ pr_err("Cannot register net device, aborting\n");
goto err_out_free_dev;
}
- printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr);
+ netdev_info(dev, "Sun LDOM vnet %pM\n", dev->dev_addr);
list_add(&vp->list, &vnet_list);
@@ -1133,10 +1130,7 @@ static struct vio_driver_ops vnet_vio_ops = {
static void __devinit print_version(void)
{
- static int version_printed;
-
- if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ printk_once(KERN_INFO "%s", version);
}
const char *remote_macaddr_prop = "remote-mac-address";
@@ -1157,7 +1151,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
vp = vnet_find_parent(hp, vdev->mp);
if (IS_ERR(vp)) {
- printk(KERN_ERR PFX "Cannot find port parent vnet.\n");
+ pr_err("Cannot find port parent vnet\n");
err = PTR_ERR(vp);
goto err_out_put_mdesc;
}
@@ -1165,15 +1159,14 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len);
err = -ENODEV;
if (!rmac) {
- printk(KERN_ERR PFX "Port lacks %s property.\n",
- remote_macaddr_prop);
+ pr_err("Port lacks %s property\n", remote_macaddr_prop);
goto err_out_put_mdesc;
}
port = kzalloc(sizeof(*port), GFP_KERNEL);
err = -ENOMEM;
if (!port) {
- printk(KERN_ERR PFX "Cannot allocate vnet_port.\n");
+ pr_err("Cannot allocate vnet_port\n");
goto err_out_put_mdesc;
}
@@ -1214,9 +1207,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
dev_set_drvdata(&vdev->dev, port);
- printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n",
- vp->dev->name, port->raddr,
- switch_port ? " switch-port" : "");
+ pr_info("%s: PORT ( remote-mac %pM%s )\n",
+ vp->dev->name, port->raddr, switch_port ? " switch-port" : "");
vio_port_up(&port->vio);
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 737df6032bbc..8b3dc1eb4015 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -92,7 +92,7 @@ static void bdx_rx_free(struct bdx_priv *priv);
static void bdx_tx_free(struct bdx_priv *priv);
/* Definitions needed by bdx_probe */
-static void bdx_ethtool_ops(struct net_device *netdev);
+static void bdx_set_ethtool_ops(struct net_device *netdev);
/*************************************************************************
* Print Info *
@@ -927,13 +927,6 @@ static void bdx_update_stats(struct bdx_priv *priv)
BDX_ASSERT((sizeof(struct bdx_stats) / sizeof(u64)) != i);
}
-static struct net_device_stats *bdx_get_stats(struct net_device *ndev)
-{
- struct bdx_priv *priv = netdev_priv(ndev);
- struct net_device_stats *net_stat = &priv->net_stats;
- return net_stat;
-}
-
static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len,
u16 rxd_vlan);
static void print_rxfd(struct rxf_desc *rxfd);
@@ -1220,6 +1213,7 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd)
static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
{
+ struct net_device *ndev = priv->ndev;
struct sk_buff *skb, *skb2;
struct rxd_desc *rxdd;
struct rx_map *dm;
@@ -1273,7 +1267,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
if (unlikely(GET_RXD_ERR(rxd_val1))) {
DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1));
- priv->net_stats.rx_errors++;
+ ndev->stats.rx_errors++;
bdx_recycle_skb(priv, rxdd);
continue;
}
@@ -1300,15 +1294,16 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
bdx_rxdb_free_elem(db, rxdd->va_lo);
}
- priv->net_stats.rx_bytes += len;
+ ndev->stats.rx_bytes += len;
skb_put(skb, len);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->protocol = eth_type_trans(skb, priv->ndev);
+ skb->protocol = eth_type_trans(skb, ndev);
/* Non-IP packets aren't checksum-offloaded */
if (GET_RXD_PKT_ID(rxd_val1) == 0)
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb);
@@ -1316,7 +1311,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
break;
}
- priv->net_stats.rx_packets += done;
+ ndev->stats.rx_packets += done;
/* FIXME: do smth to minimize pci accesses */
WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR);
@@ -1712,8 +1707,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
#ifdef BDX_LLTX
ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
#endif
- priv->net_stats.tx_packets++;
- priv->net_stats.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
if (priv->tx_level < BDX_MIN_TX_LEVEL) {
DBG("%s: %s: TX Q STOP level %d\n",
@@ -1888,7 +1883,6 @@ static const struct net_device_ops bdx_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bdx_ioctl,
.ndo_set_multicast_list = bdx_setmulti,
- .ndo_get_stats = bdx_get_stats,
.ndo_change_mtu = bdx_change_mtu,
.ndo_set_mac_address = bdx_set_mac,
.ndo_vlan_rx_register = bdx_vlan_rx_register,
@@ -2012,7 +2006,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ndev->netdev_ops = &bdx_netdev_ops;
ndev->tx_queue_len = BDX_NDEV_TXQ_LEN;
- bdx_ethtool_ops(ndev); /* ethtool interface */
+ bdx_set_ethtool_ops(ndev); /* ethtool interface */
/* these fields are used for info purposes only
* so we can have them same for all ports of the board */
@@ -2417,10 +2411,10 @@ static void bdx_get_ethtool_stats(struct net_device *netdev,
}
/*
- * bdx_ethtool_ops - ethtool interface implementation
+ * bdx_set_ethtool_ops - ethtool interface implementation
* @netdev
*/
-static void bdx_ethtool_ops(struct net_device *netdev)
+static void bdx_set_ethtool_ops(struct net_device *netdev)
{
static const struct ethtool_ops bdx_ethtool_ops = {
.get_settings = bdx_get_settings,
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index 67e3b71bf705..b6ba8601e2b5 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -269,7 +269,6 @@ struct bdx_priv {
u32 msg_enable;
int stats_flag;
struct bdx_stats hw_stats;
- struct net_device_stats net_stats;
struct pci_dev *pdev;
struct pci_nic *nic;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index bc3af78a869f..9f6ffffc8376 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4719,7 +4719,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
>> RXD_TCPCSUM_SHIFT) == 0xffff))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, tp->dev);
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index ccee3eddc5f4..0564ca05963d 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -393,7 +393,7 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
if (!in_irq())
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1453,7 +1453,7 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.data = (unsigned long) dev;
priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
priv->timerSetAt = jiffies;
@@ -1601,7 +1601,7 @@ drop_and_reuse:
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.data = (unsigned long) dev;
priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
priv->timerSetAt = jiffies;
@@ -1897,7 +1897,7 @@ static void TLan_Timer( unsigned long data )
TLan_DioWrite8( dev->base_addr,
TLAN_LED_REG, TLAN_LED_LINK );
} else {
- priv->timer.function = &TLan_Timer;
+ priv->timer.function = TLan_Timer;
priv->timer.expires = priv->timerSetAt
+ TLAN_TIMER_ACT_DELAY;
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 435ef7d5470f..08182fde3dcd 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1321,14 +1321,12 @@ static int tms380tr_reset_adapter(struct net_device *dev)
/* Clear CPHALT and start BUD */
SIFWRITEW(c, SIFACL);
- if (fw_entry)
- release_firmware(fw_entry);
+ release_firmware(fw_entry);
return (1);
}
} while(count == 0);
- if (fw_entry)
- release_firmware(fw_entry);
+ release_firmware(fw_entry);
printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name);
return (-1);
}
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 75a64c88cf7a..4f7503063446 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1448,7 +1448,7 @@ de4x5_sw_reset(struct net_device *dev)
status = -EIO;
}
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
lp->tx_old = lp->tx_new;
return status;
@@ -1506,7 +1506,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
lp->stats.tx_bytes += skb->len;
outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
if (TX_BUFFS_AVAIL) {
netif_start_queue(dev); /* Another pkt may be queued */
@@ -1657,7 +1657,7 @@ de4x5_rx(struct net_device *dev)
}
/* Change buffer ownership for this frame, back to the adapter */
- for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) {
+ for (;lp->rx_old!=entry;lp->rx_old=(lp->rx_old + 1)%lp->rxRingSize) {
lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN);
barrier();
}
@@ -1668,7 +1668,7 @@ de4x5_rx(struct net_device *dev)
/*
** Update entry information
*/
- lp->rx_new = (++lp->rx_new) % lp->rxRingSize;
+ lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize;
}
return 0;
@@ -1726,7 +1726,7 @@ de4x5_tx(struct net_device *dev)
}
/* Update all the pointers */
- lp->tx_old = (++lp->tx_old) % lp->txRingSize;
+ lp->tx_old = (lp->tx_old + 1) % lp->txRingSize;
}
/* Any resources available? */
@@ -1801,7 +1801,7 @@ de4x5_rx_ovfc(struct net_device *dev)
for (; (s32)le32_to_cpu(lp->rx_ring[lp->rx_new].status)>=0;) {
lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN);
- lp->rx_new = (++lp->rx_new % lp->rxRingSize);
+ lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize;
}
outl(omr, DE4X5_OMR);
@@ -1932,7 +1932,7 @@ set_multicast_list(struct net_device *dev)
load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
SETUP_FRAME_LEN, (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
dev->trans_start = jiffies; /* prevent tx timeout */
}
@@ -3568,7 +3568,7 @@ ping_media(struct net_device *dev, int msec)
lp->tmp = lp->tx_new; /* Remember the ring position */
load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD);
}
@@ -5417,7 +5417,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* Set up the descriptor and give ownership to the card */
load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
SETUP_FRAME_LEN, (struct sk_buff *)1);
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ lp->tx_new = (lp->tx_new + 1) % lp->txRingSize;
outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
netif_wake_queue(dev); /* Unlock the TX ring */
break;
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 0bc4f3030a80..a9f7d5d1a269 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -599,7 +599,7 @@ static int dmfe_open(struct DEVICE *dev)
init_timer(&db->timer);
db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
db->timer.data = (unsigned long)dev;
- db->timer.function = &dmfe_timer;
+ db->timer.function = dmfe_timer;
add_timer(&db->timer);
return 0;
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 1faf7a4d7202..0013642903ee 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -180,21 +180,24 @@ int tulip_poll(struct napi_struct *napi, int budget)
dev_warn(&dev->dev,
"Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
status);
- tp->stats.rx_length_errors++;
- }
+ dev->stats.rx_length_errors++;
+ }
} else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
dev->name, status);
- tp->stats.rx_errors++; /* end of a packet.*/
- if (pkt_len > 1518 ||
- (status & RxDescRunt))
- tp->stats.rx_length_errors++;
-
- if (status & 0x0004) tp->stats.rx_frame_errors++;
- if (status & 0x0002) tp->stats.rx_crc_errors++;
- if (status & 0x0001) tp->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++; /* end of a packet.*/
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ dev->stats.rx_length_errors++;
+
+ if (status & 0x0004)
+ dev->stats.rx_frame_errors++;
+ if (status & 0x0002)
+ dev->stats.rx_crc_errors++;
+ if (status & 0x0001)
+ dev->stats.rx_fifo_errors++;
}
} else {
struct sk_buff *skb;
@@ -244,8 +247,8 @@ int tulip_poll(struct napi_struct *napi, int budget)
netif_receive_skb(skb);
- tp->stats.rx_packets++;
- tp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
received++;
@@ -404,20 +407,23 @@ static int tulip_rx(struct net_device *dev)
dev_warn(&dev->dev,
"Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
status);
- tp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
}
} else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
dev->name, status);
- tp->stats.rx_errors++; /* end of a packet.*/
+ dev->stats.rx_errors++; /* end of a packet.*/
if (pkt_len > 1518 ||
(status & RxDescRunt))
- tp->stats.rx_length_errors++;
- if (status & 0x0004) tp->stats.rx_frame_errors++;
- if (status & 0x0002) tp->stats.rx_crc_errors++;
- if (status & 0x0001) tp->stats.rx_fifo_errors++;
+ dev->stats.rx_length_errors++;
+ if (status & 0x0004)
+ dev->stats.rx_frame_errors++;
+ if (status & 0x0002)
+ dev->stats.rx_crc_errors++;
+ if (status & 0x0001)
+ dev->stats.rx_fifo_errors++;
}
} else {
struct sk_buff *skb;
@@ -467,8 +473,8 @@ static int tulip_rx(struct net_device *dev)
netif_rx(skb);
- tp->stats.rx_packets++;
- tp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
received++;
entry = (++tp->cur_rx) % RX_RING_SIZE;
@@ -602,18 +608,22 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
dev->name, status);
#endif
- tp->stats.tx_errors++;
- if (status & 0x4104) tp->stats.tx_aborted_errors++;
- if (status & 0x0C00) tp->stats.tx_carrier_errors++;
- if (status & 0x0200) tp->stats.tx_window_errors++;
- if (status & 0x0002) tp->stats.tx_fifo_errors++;
+ dev->stats.tx_errors++;
+ if (status & 0x4104)
+ dev->stats.tx_aborted_errors++;
+ if (status & 0x0C00)
+ dev->stats.tx_carrier_errors++;
+ if (status & 0x0200)
+ dev->stats.tx_window_errors++;
+ if (status & 0x0002)
+ dev->stats.tx_fifo_errors++;
if ((status & 0x0080) && tp->full_duplex == 0)
- tp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
} else {
- tp->stats.tx_bytes +=
+ dev->stats.tx_bytes +=
tp->tx_buffers[entry].skb->len;
- tp->stats.collisions += (status >> 3) & 15;
- tp->stats.tx_packets++;
+ dev->stats.collisions += (status >> 3) & 15;
+ dev->stats.tx_packets++;
}
pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
@@ -655,7 +665,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */
if (csr5 == 0xffffffff)
break;
- if (csr5 & TxJabber) tp->stats.tx_errors++;
+ if (csr5 & TxJabber)
+ dev->stats.tx_errors++;
if (csr5 & TxFIFOUnderflow) {
if ((tp->csr6 & 0xC000) != 0xC000)
tp->csr6 += 0x4000; /* Bump up the Tx threshold */
@@ -672,8 +683,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
}
}
if (csr5 & RxDied) { /* Missed a Rx frame. */
- tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
- tp->stats.rx_errors++;
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+ dev->stats.rx_errors++;
tulip_start_rxtx(tp);
}
/*
@@ -789,7 +800,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
#endif /* CONFIG_TULIP_NAPI */
if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) {
- tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+ dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
}
if (tulip_debug > 4)
diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c
index b8197666021e..4690c8e69207 100644
--- a/drivers/net/tulip/pnic2.c
+++ b/drivers/net/tulip/pnic2.c
@@ -59,7 +59,7 @@
* Bit 14:12 - autonegotiation state (write 001 to start autonegotiate)
* Bit 3 - Autopolarity state
* Bit 2 - LS10B - link state of 10baseT 0 - good, 1 - failed
- * Bit 1 - LS100B - link state of 100baseT 0 - good, 1- faild
+ * Bit 1 - LS100B - link state of 100baseT 0 - good, 1 - failed
*
*
* Data Port Selection Info
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index e525875ed67d..ed66a16711dc 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -417,7 +417,6 @@ struct tulip_private {
int revision;
int flags;
struct napi_struct napi;
- struct net_device_stats stats;
struct timer_list timer; /* Media selection timer. */
struct timer_list oom_timer; /* Out of memory timer. */
u32 mc_filter[2];
@@ -570,7 +569,7 @@ static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __io
/* Trigger an immediate transmit demand. */
iowrite32(0, ioaddr + CSR1);
- tp->stats.tx_errors++;
+ tp->dev->stats.tx_errors++;
}
#endif /* __NET_TULIP_H__ */
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 3a8d7efa2acf..2c39f2591216 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -725,7 +725,7 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
int status = le32_to_cpu(tp->tx_ring[entry].status);
if (status < 0) {
- tp->stats.tx_errors++; /* It wasn't Txed */
+ tp->dev->stats.tx_errors++; /* It wasn't Txed */
tp->tx_ring[entry].status = 0;
}
@@ -781,8 +781,8 @@ static void tulip_down (struct net_device *dev)
/* release any unconsumed transmit buffers */
tulip_clean_tx_ring(tp);
- if (ioread32 (ioaddr + CSR6) != 0xffffffff)
- tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff;
+ if (ioread32(ioaddr + CSR6) != 0xffffffff)
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
spin_unlock_irqrestore (&tp->lock, flags);
@@ -864,12 +864,12 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev)
spin_lock_irqsave (&tp->lock, flags);
- tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+ dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
spin_unlock_irqrestore(&tp->lock, flags);
}
- return &tp->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 96de5829b940..1dc27a557275 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -480,7 +480,7 @@ static int uli526x_open(struct net_device *dev)
init_timer(&db->timer);
db->timer.expires = ULI526X_TIMER_WUT + HZ * 2;
db->timer.data = (unsigned long)dev;
- db->timer.function = &uli526x_timer;
+ db->timer.function = uli526x_timer;
add_timer(&db->timer);
return 0;
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 66d41cf8da29..f0b231035dee 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -662,7 +662,7 @@ static int netdev_open(struct net_device *dev)
init_timer(&np->timer);
np->timer.expires = jiffies + 1*HZ;
np->timer.data = (unsigned long)dev;
- np->timer.function = &netdev_timer; /* timer handler */
+ np->timer.function = netdev_timer; /* timer handler */
add_timer(&np->timer);
return 0;
out_err:
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index a439e93be22d..5a73752be2ca 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -29,7 +29,6 @@
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/ethtool.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
@@ -181,19 +180,6 @@ static void print_binary(unsigned int number)
}
#endif
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct xircom_private *private = netdev_priv(dev);
-
- strcpy(info->driver, "xircom_cb");
- strcpy(info->bus_info, pci_name(private->pdev));
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
static const struct net_device_ops netdev_ops = {
.ndo_open = xircom_open,
.ndo_stop = xircom_close,
@@ -279,7 +265,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
setup_descriptors(private);
dev->netdev_ops = &netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
pci_set_drvdata(pdev, dev);
if (register_netdev(dev)) {
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 2e50077ff450..5dfb39539b3e 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp)
* The extra status reported would be a good candidate for
* ethtool_ops->get_{strings,stats}()
*/
- stats->tx_packets = le32_to_cpu(s->txPackets);
- stats->tx_bytes = le64_to_cpu(s->txBytes);
- stats->tx_errors = le32_to_cpu(s->txCarrierLost);
- stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost);
- stats->collisions = le32_to_cpu(s->txMultipleCollisions);
- stats->rx_packets = le32_to_cpu(s->rxPacketsGood);
- stats->rx_bytes = le64_to_cpu(s->rxBytesGood);
- stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns);
+ stats->tx_packets = le32_to_cpu(s->txPackets) +
+ saved->tx_packets;
+ stats->tx_bytes = le64_to_cpu(s->txBytes) +
+ saved->tx_bytes;
+ stats->tx_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_errors;
+ stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_carrier_errors;
+ stats->collisions = le32_to_cpu(s->txMultipleCollisions) +
+ saved->collisions;
+ stats->rx_packets = le32_to_cpu(s->rxPacketsGood) +
+ saved->rx_packets;
+ stats->rx_bytes = le64_to_cpu(s->rxBytesGood) +
+ saved->rx_bytes;
+ stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) +
+ saved->rx_fifo_errors;
stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
- le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors);
- stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors);
- stats->rx_length_errors = le32_to_cpu(s->rxOversized);
+ le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_errors;
+ stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_crc_errors;
+ stats->rx_length_errors = le32_to_cpu(s->rxOversized) +
+ saved->rx_length_errors;
tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
SPEED_100 : SPEED_10;
tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
DUPLEX_FULL : DUPLEX_HALF;
- /* add in the saved statistics
- */
- stats->tx_packets += saved->tx_packets;
- stats->tx_bytes += saved->tx_bytes;
- stats->tx_errors += saved->tx_errors;
- stats->collisions += saved->collisions;
- stats->rx_packets += saved->rx_packets;
- stats->rx_bytes += saved->rx_bytes;
- stats->rx_fifo_errors += saved->rx_fifo_errors;
- stats->rx_errors += saved->rx_errors;
- stats->rx_crc_errors += saved->rx_crc_errors;
- stats->rx_length_errors += saved->rx_length_errors;
-
return 0;
}
@@ -1762,7 +1760,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
(TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
new_skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- new_skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(new_skb);
spin_lock(&tp->state_lock);
if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index d7b7018a1de1..52ffabe6db0e 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -358,6 +358,14 @@ config USB_NET_ZAURUS
really need this non-conformant variant of CDC Ethernet (or in
some cases CDC MDLM) protocol, not "g_ether".
+config USB_NET_CX82310_ETH
+ tristate "Conexant CX82310 USB ethernet port"
+ depends on USB_USBNET
+ help
+ Choose this option if you're using a Conexant CX82310-based ADSL
+ router with USB ethernet port. This driver is for routers only,
+ it will not work with ADSL modems (use cxacru driver instead).
+
config USB_HSO
tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index b13a279663ba..a19b0259ae16 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
+obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
new file mode 100644
index 000000000000..8969f124c18c
--- /dev/null
+++ b/drivers/net/usb/cx82310_eth.c
@@ -0,0 +1,346 @@
+/*
+ * Driver for USB ethernet port of Conexant CX82310-based ADSL routers
+ * Copyright (C) 2010 by Ondrej Zary
+ * some parts inspired by the cxacru driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
+
+enum cx82310_cmd {
+ CMD_START = 0x84, /* no effect? */
+ CMD_STOP = 0x85, /* no effect? */
+ CMD_GET_STATUS = 0x90, /* returns nothing? */
+ CMD_GET_MAC_ADDR = 0x91, /* read MAC address */
+ CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */
+ CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */
+};
+
+enum cx82310_status {
+ STATUS_UNDEFINED,
+ STATUS_SUCCESS,
+ STATUS_ERROR,
+ STATUS_UNSUPPORTED,
+ STATUS_UNIMPLEMENTED,
+ STATUS_PARAMETER_ERROR,
+ STATUS_DBG_LOOPBACK,
+};
+
+#define CMD_PACKET_SIZE 64
+/* first command after power on can take around 8 seconds */
+#define CMD_TIMEOUT 15000
+#define CMD_REPLY_RETRY 5
+
+#define CX82310_MTU 1514
+#define CMD_EP 0x01
+
+/*
+ * execute control command
+ * - optionally send some data (command parameters)
+ * - optionally wait for the reply
+ * - optionally read some data from the reply
+ */
+static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply,
+ u8 *wdata, int wlen, u8 *rdata, int rlen)
+{
+ int actual_len, retries, ret;
+ struct usb_device *udev = dev->udev;
+ u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ /* create command packet */
+ buf[0] = cmd;
+ if (wdata)
+ memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4));
+
+ /* send command packet */
+ ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf,
+ CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev, "send command %#x: error %d\n",
+ cmd, ret);
+ goto end;
+ }
+
+ if (reply) {
+ /* wait for reply, retry if it's empty */
+ for (retries = 0; retries < CMD_REPLY_RETRY; retries++) {
+ ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP),
+ buf, CMD_PACKET_SIZE, &actual_len,
+ CMD_TIMEOUT);
+ if (ret < 0) {
+ dev_err(&dev->udev->dev,
+ "reply receive error %d\n", ret);
+ goto end;
+ }
+ if (actual_len > 0)
+ break;
+ }
+ if (actual_len == 0) {
+ dev_err(&dev->udev->dev, "no reply to command %#x\n",
+ cmd);
+ ret = -EIO;
+ goto end;
+ }
+ if (buf[0] != cmd) {
+ dev_err(&dev->udev->dev,
+ "got reply to command %#x, expected: %#x\n",
+ buf[0], cmd);
+ ret = -EIO;
+ goto end;
+ }
+ if (buf[1] != STATUS_SUCCESS) {
+ dev_err(&dev->udev->dev, "command %#x failed: %#x\n",
+ cmd, buf[1]);
+ ret = -EIO;
+ goto end;
+ }
+ if (rdata)
+ memcpy(rdata, buf + 4,
+ min_t(int, rlen, CMD_PACKET_SIZE - 4));
+ }
+end:
+ kfree(buf);
+ return ret;
+}
+
+#define partial_len data[0] /* length of partial packet data */
+#define partial_rem data[1] /* remaining (missing) data length */
+#define partial_data data[2] /* partial packet data */
+
+static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+ char buf[15];
+ struct usb_device *udev = dev->udev;
+
+ /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
+ if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
+ && strcmp(buf, "USB NET CARD")) {
+ dev_info(&udev->dev, "ignoring: probably an ADSL modem\n");
+ return -ENODEV;
+ }
+
+ ret = usbnet_get_endpoints(dev, intf);
+ if (ret)
+ return ret;
+
+ /*
+ * this must not include ethernet header as the device can send partial
+ * packets with no header (and sometimes even empty URBs)
+ */
+ dev->net->hard_header_len = 0;
+ /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */
+ dev->hard_mtu = CX82310_MTU + 2;
+ /* we can receive URBs up to 4KB from the device */
+ dev->rx_urb_size = 4096;
+
+ dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL);
+ if (!dev->partial_data)
+ return -ENOMEM;
+
+ /* enable ethernet mode (?) */
+ ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
+ if (ret) {
+ dev_err(&udev->dev, "unable to enable ethernet mode: %d\n",
+ ret);
+ goto err;
+ }
+
+ /* get the MAC address */
+ ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0,
+ dev->net->dev_addr, ETH_ALEN);
+ if (ret) {
+ dev_err(&udev->dev, "unable to read MAC address: %d\n", ret);
+ goto err;
+ }
+
+ /* start (does not seem to have any effect?) */
+ ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ kfree((void *)dev->partial_data);
+ return ret;
+}
+
+static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ kfree((void *)dev->partial_data);
+}
+
+/*
+ * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte
+ * packet length at the beginning.
+ * The last packet might be incomplete (when it crosses the 4KB URB size),
+ * continuing in the next skb (without any headers).
+ * If a packet has odd length, there is one extra byte at the end (before next
+ * packet or at the end of the URB).
+ */
+static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int len;
+ struct sk_buff *skb2;
+
+ /*
+ * If the last skb ended with an incomplete packet, this skb contains
+ * end of that packet at the beginning.
+ */
+ if (dev->partial_rem) {
+ len = dev->partial_len + dev->partial_rem;
+ skb2 = alloc_skb(len, GFP_ATOMIC);
+ if (!skb2)
+ return 0;
+ skb_put(skb2, len);
+ memcpy(skb2->data, (void *)dev->partial_data,
+ dev->partial_len);
+ memcpy(skb2->data + dev->partial_len, skb->data,
+ dev->partial_rem);
+ usbnet_skb_return(dev, skb2);
+ skb_pull(skb, (dev->partial_rem + 1) & ~1);
+ dev->partial_rem = 0;
+ if (skb->len < 2)
+ return 1;
+ }
+
+ /* a skb can contain multiple packets */
+ while (skb->len > 1) {
+ /* first two bytes are packet length */
+ len = skb->data[0] | (skb->data[1] << 8);
+ skb_pull(skb, 2);
+
+ /* if last packet in the skb, let usbnet to process it */
+ if (len == skb->len || len + 1 == skb->len) {
+ skb_trim(skb, len);
+ break;
+ }
+
+ if (len > CX82310_MTU) {
+ dev_err(&dev->udev->dev, "RX packet too long: %d B\n",
+ len);
+ return 0;
+ }
+
+ /* incomplete packet, save it for the next skb */
+ if (len > skb->len) {
+ dev->partial_len = skb->len;
+ dev->partial_rem = len - skb->len;
+ memcpy((void *)dev->partial_data, skb->data,
+ dev->partial_len);
+ skb_pull(skb, skb->len);
+ break;
+ }
+
+ skb2 = alloc_skb(len, GFP_ATOMIC);
+ if (!skb2)
+ return 0;
+ skb_put(skb2, len);
+ memcpy(skb2->data, skb->data, len);
+ /* process the packet */
+ usbnet_skb_return(dev, skb2);
+
+ skb_pull(skb, (len + 1) & ~1);
+ }
+
+ /* let usbnet process the last packet */
+ return 1;
+}
+
+/* TX is easy, just add 2 bytes of length at the beginning */
+static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ int len = skb->len;
+
+ if (skb_headroom(skb) < 2) {
+ struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+ skb_push(skb, 2);
+
+ skb->data[0] = len;
+ skb->data[1] = len >> 8;
+
+ return skb;
+}
+
+
+static const struct driver_info cx82310_info = {
+ .description = "Conexant CX82310 USB ethernet",
+ .flags = FLAG_ETHER,
+ .bind = cx82310_bind,
+ .unbind = cx82310_unbind,
+ .rx_fixup = cx82310_rx_fixup,
+ .tx_fixup = cx82310_tx_fixup,
+};
+
+#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+ USB_DEVICE_ID_MATCH_DEV_INFO, \
+ .idVendor = (vend), \
+ .idProduct = (prod), \
+ .bDeviceClass = (cl), \
+ .bDeviceSubClass = (sc), \
+ .bDeviceProtocol = (pr)
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0),
+ .driver_info = (unsigned long) &cx82310_info
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver cx82310_driver = {
+ .name = "cx82310_eth",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init cx82310_init(void)
+{
+ return usb_register(&cx82310_driver);
+}
+module_init(cx82310_init);
+
+static void __exit cx82310_exit(void)
+{
+ usb_deregister(&cx82310_driver);
+}
+module_exit(cx82310_exit);
+
+MODULE_AUTHOR("Ondrej Zary");
+MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 6efca66b8766..4f123f869bdc 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -843,16 +843,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
-static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
-{
- struct hso_net *odev = netdev_priv(net);
-
- strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
- usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
-}
-
static const struct ethtool_ops ops = {
- .get_drvinfo = hso_get_drvinfo,
.get_link = ethtool_op_get_link
};
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 8ed30fa35d0a..b2bcf99e6f08 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -429,10 +429,6 @@ static const struct net_device_ops ipheth_netdev_ops = {
.ndo_get_stats = &ipheth_stats,
};
-static struct device_type ipheth_type = {
- .name = "wwan",
-};
-
static int ipheth_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -450,7 +446,7 @@ static int ipheth_probe(struct usb_interface *intf,
netdev->netdev_ops = &ipheth_netdev_ops;
netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
- strcpy(netdev->name, "wwan%d");
+ strcpy(netdev->name, "eth%d");
dev = netdev_priv(netdev);
dev->udev = udev;
@@ -500,7 +496,6 @@ static int ipheth_probe(struct usb_interface *intf,
SET_NETDEV_DEV(netdev, &intf->dev);
SET_ETHTOOL_OPS(netdev, &ops);
- SET_NETDEV_DEVTYPE(netdev, &ipheth_type);
retval = register_netdev(netdev);
if (retval) {
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 2b7b39cad1ce..5e98643a4a21 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -759,14 +759,6 @@ static int kaweth_close(struct net_device *net)
return 0;
}
-static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct kaweth_device *kaweth = netdev_priv(dev);
-
- strlcpy(info->driver, driver_name, sizeof(info->driver));
- usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info));
-}
-
static u32 kaweth_get_link(struct net_device *dev)
{
struct kaweth_device *kaweth = netdev_priv(dev);
@@ -775,7 +767,6 @@ static u32 kaweth_get_link(struct net_device *dev)
}
static const struct ethtool_ops ops = {
- .get_drvinfo = kaweth_get_drvinfo,
.get_link = kaweth_get_link
};
diff --git a/drivers/net/vbus-enet.c b/drivers/net/vbus-enet.c
new file mode 100644
index 000000000000..94b86d482cee
--- /dev/null
+++ b/drivers/net/vbus-enet.c
@@ -0,0 +1,1560 @@
+/*
+ * vbus_enet - A virtualized 802.x network device based on the VBUS interface
+ *
+ * Copyright (C) 2009 Novell, Gregory Haskins <ghaskins@novell.com>
+ *
+ * Derived from the SNULL example from the book "Linux Device Drivers" by
+ * Alessandro Rubini, Jonathan Corbet, and Greg Kroah-Hartman, published
+ * by O'Reilly & Associates.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/ioq.h>
+#include <linux/vbus_driver.h>
+
+#include <linux/in6.h>
+#include <asm/checksum.h>
+
+#include <linux/venet.h>
+
+MODULE_AUTHOR("Gregory Haskins");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("virtual-ethernet");
+MODULE_VERSION("1");
+
+static int rx_ringlen = 256;
+module_param(rx_ringlen, int, 0444);
+static int tx_ringlen = 256;
+module_param(tx_ringlen, int, 0444);
+static int sg_enabled = 1;
+module_param(sg_enabled, int, 0444);
+
+#define PDEBUG(_dev, fmt, args...) dev_dbg(&(_dev)->dev, fmt, ## args)
+
+#define SG_DESC_SIZE VSG_DESC_SIZE(MAX_SKB_FRAGS)
+
+struct vbus_enet_queue {
+ struct ioq *queue;
+ struct ioq_notifier notifier;
+ unsigned long count;
+};
+
+struct vbus_enet_priv {
+ spinlock_t lock;
+ struct net_device *dev;
+ struct vbus_device_proxy *vdev;
+ struct napi_struct napi;
+ struct vbus_enet_queue rxq;
+ struct {
+ struct vbus_enet_queue veq;
+ struct tasklet_struct task;
+ struct sk_buff_head outstanding;
+ } tx;
+ bool sg;
+ struct {
+ bool enabled;
+ char *pool;
+ } pmtd; /* pre-mapped transmit descriptors */
+ struct {
+ bool enabled;
+ bool linkstate;
+ bool txc;
+ unsigned long evsize;
+ struct vbus_enet_queue veq;
+ struct tasklet_struct task;
+ char *pool;
+ } evq;
+ struct {
+ bool available;
+ char *pool;
+ struct vbus_enet_queue pageq;
+ } l4ro;
+
+ struct sk_buff *(*import)(struct vbus_enet_priv *priv,
+ struct ioq_ring_desc *desc);
+};
+
+static void vbus_enet_tx_reap(struct vbus_enet_priv *priv);
+
+static struct vbus_enet_priv *
+napi_to_priv(struct napi_struct *napi)
+{
+ return container_of(napi, struct vbus_enet_priv, napi);
+}
+
+static int
+queue_init(struct vbus_enet_priv *priv,
+ struct vbus_enet_queue *q,
+ const char *name,
+ int qid,
+ size_t ringsize,
+ void (*func)(struct ioq_notifier *))
+{
+ struct vbus_device_proxy *dev = priv->vdev;
+ int ret;
+ char _name[64];
+
+ if (name)
+ snprintf(_name, sizeof(_name), "%s-%s", priv->dev->name, name);
+
+ ret = vbus_driver_ioq_alloc(dev, name ? _name : NULL, qid, 0,
+ ringsize, &q->queue);
+ if (ret < 0)
+ panic("ioq_alloc failed: %d\n", ret);
+
+ if (func) {
+ q->notifier.signal = func;
+ q->queue->notifier = &q->notifier;
+ }
+
+ q->count = ringsize;
+
+ return 0;
+}
+
+static int
+devcall(struct vbus_enet_priv *priv, u32 func, void *data, size_t len)
+{
+ struct vbus_device_proxy *dev = priv->vdev;
+
+ return dev->ops->call(dev, func, data, len, 0);
+}
+
+/*
+ * ---------------
+ * rx descriptors
+ * ---------------
+ */
+
+static void
+rxdesc_alloc(struct vbus_enet_priv *priv, struct ioq_ring_desc *desc, size_t len)
+{
+ struct net_device *dev = priv->dev;
+ struct sk_buff *skb;
+
+ len += ETH_HLEN;
+
+ skb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
+ BUG_ON(!skb);
+
+ skb_reserve(skb, NET_IP_ALIGN); /* align IP on 16B boundary */
+
+ if (priv->l4ro.available) {
+ /*
+ * We will populate an SG descriptor initially with one
+ * IOV filled with an MTU SKB. If the packet needs to be
+ * larger than MTU, the host will grab pages out of the
+ * page-queue and populate additional IOVs
+ */
+ struct venet_sg *vsg = (struct venet_sg *)(unsigned long)desc->cookie;
+ struct venet_iov *iov = &vsg->iov[0];
+
+ memset(vsg, 0, SG_DESC_SIZE);
+
+ vsg->cookie = (u64)(unsigned long)skb;
+ vsg->count = 1;
+
+ iov->ptr = (u64)__pa(skb->data);
+ iov->len = len;
+ } else {
+ desc->cookie = (u64)(unsigned long)skb;
+ desc->ptr = cpu_to_le64(__pa(skb->data));
+ desc->len = cpu_to_le64(len); /* total length */
+ }
+
+ desc->valid = 1;
+}
+
+static void
+rx_pageq_refill(struct vbus_enet_priv *priv, gfp_t gfp_mask)
+{
+ struct ioq *ioq = priv->l4ro.pageq.queue;
+ struct ioq_iterator iter;
+ int ret, added = 0;
+
+ if (ioq_full(ioq, ioq_idxtype_inuse))
+ /* nothing to do if the pageq is already fully populated */
+ return;
+
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_inuse, 0);
+ BUG_ON(ret < 0); /* will never fail unless seriously broken */
+
+ ret = ioq_iter_seek(&iter, ioq_seek_tail, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * Now populate each descriptor with an empty page
+ */
+ while (!iter.desc->sown) {
+ struct page *page = NULL;
+
+ page = alloc_page(gfp_mask);
+
+ if (!page)
+ break;
+
+ added = 1;
+ iter.desc->cookie = (u64)(unsigned long)page;
+ iter.desc->ptr = cpu_to_le64(__pa(page_address(page)));
+ iter.desc->len = cpu_to_le64(PAGE_SIZE);
+
+ ret = ioq_iter_push(&iter, 0);
+ BUG_ON(ret < 0);
+ }
+
+ if (added)
+ ioq_signal(ioq, 0);
+}
+
+static void
+rx_setup(struct vbus_enet_priv *priv)
+{
+ struct ioq *ioq = priv->rxq.queue;
+ struct ioq_iterator iter;
+ int ret;
+ int i = 0;
+
+ /*
+ * We want to iterate on the "valid" index. By default the iterator
+ * will not "autoupdate" which means it will not hypercall the host
+ * with our changes. This is good, because we are really just
+ * initializing stuff here anyway. Note that you can always manually
+ * signal the host with ioq_signal() if the autoupdate feature is not
+ * used.
+ */
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0); /* will never fail unless seriously broken */
+
+ /*
+ * Seek to the tail of the valid index (which should be our first
+ * item, since the queue is brand-new)
+ */
+ ret = ioq_iter_seek(&iter, ioq_seek_tail, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * Now populate each descriptor with an empty buffer and mark it valid
+ */
+ while (!iter.desc->valid) {
+ if (priv->l4ro.available) {
+ size_t offset = (i * SG_DESC_SIZE);
+ void *addr = &priv->l4ro.pool[offset];
+
+ iter.desc->ptr = cpu_to_le64(offset);
+ iter.desc->cookie = (u64)(unsigned long)addr;
+ iter.desc->len = cpu_to_le64(SG_DESC_SIZE);
+ }
+
+ rxdesc_alloc(priv, iter.desc, priv->dev->mtu);
+
+ /*
+ * This push operation will simultaneously advance the
+ * valid-head index and increment our position in the queue
+ * by one.
+ */
+ ret = ioq_iter_push(&iter, 0);
+ BUG_ON(ret < 0);
+
+ i++;
+ }
+
+ if (priv->l4ro.available)
+ rx_pageq_refill(priv, GFP_KERNEL);
+}
+
+static void
+rx_rxq_teardown(struct vbus_enet_priv *priv)
+{
+ struct ioq *ioq = priv->rxq.queue;
+ struct ioq_iterator iter;
+ int ret;
+
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * free each valid descriptor
+ */
+ while (iter.desc->valid) {
+ struct sk_buff *skb;
+
+ if (priv->l4ro.available) {
+ struct venet_sg *vsg;
+ int i;
+
+ vsg = (struct venet_sg *)(unsigned long)iter.desc->cookie;
+
+ /* skip i=0, since that is the skb->data IOV */
+ for (i = 1; i < vsg->count; i++) {
+ struct venet_iov *iov = &vsg->iov[i];
+ struct page *page = (struct page *)(unsigned long)iov->ptr;
+
+ put_page(page);
+ }
+
+ skb = (struct sk_buff *)(unsigned long)vsg->cookie;
+ } else
+ skb = (struct sk_buff *)(unsigned long)iter.desc->cookie;
+
+ iter.desc->valid = 0;
+ wmb();
+
+ iter.desc->ptr = 0;
+ iter.desc->cookie = 0;
+
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+
+ dev_kfree_skb(skb);
+ }
+}
+
+static void
+rx_l4ro_teardown(struct vbus_enet_priv *priv)
+{
+ struct ioq *ioq = priv->l4ro.pageq.queue;
+ struct ioq_iterator iter;
+ int ret;
+
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_inuse, 0);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * free each valid descriptor
+ */
+ while (iter.desc->sown) {
+ struct page *page = (struct page *)(unsigned long)iter.desc->cookie;
+
+ iter.desc->valid = 0;
+ wmb();
+
+ iter.desc->ptr = 0;
+ iter.desc->cookie = 0;
+
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+
+ put_page(page);
+ }
+
+ ioq_put(ioq);
+ kfree(priv->l4ro.pool);
+}
+
+static void
+rx_teardown(struct vbus_enet_priv *priv)
+{
+ rx_rxq_teardown(priv);
+
+ if (priv->l4ro.available)
+ rx_l4ro_teardown(priv);
+}
+
+static int
+tx_setup(struct vbus_enet_priv *priv)
+{
+ struct ioq *ioq = priv->tx.veq.queue;
+ struct ioq_iterator iter;
+ int i;
+ int ret;
+
+ if (!priv->sg)
+ /*
+ * There is nothing to do for a ring that is not using
+ * scatter-gather
+ */
+ return 0;
+
+ /* pre-allocate our descriptor pool if pmtd is enabled */
+ if (priv->pmtd.enabled) {
+ struct vbus_device_proxy *dev = priv->vdev;
+ size_t poollen = SG_DESC_SIZE * priv->tx.veq.count;
+ char *pool;
+ int shmid;
+
+ /* pmtdquery will return the shm-id to use for the pool */
+ ret = devcall(priv, VENET_FUNC_PMTDQUERY, NULL, 0);
+ BUG_ON(ret < 0);
+
+ shmid = ret;
+
+ pool = kzalloc(poollen, GFP_KERNEL | GFP_DMA);
+ if (!pool)
+ return -ENOMEM;
+
+ priv->pmtd.pool = pool;
+
+ ret = dev->ops->shm(dev, NULL, shmid, 0, pool, poollen,
+ NULL, NULL, 0);
+ BUG_ON(ret < 0);
+ }
+
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_set, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * Now populate each descriptor with an empty SG descriptor
+ */
+ for (i = 0; i < priv->tx.veq.count; i++) {
+ struct venet_sg *vsg;
+
+ if (priv->pmtd.enabled) {
+ size_t offset = (i * SG_DESC_SIZE);
+
+ vsg = (struct venet_sg *)&priv->pmtd.pool[offset];
+ iter.desc->ptr = cpu_to_le64(offset);
+ } else {
+ vsg = kzalloc(SG_DESC_SIZE, GFP_KERNEL);
+ if (!vsg)
+ return -ENOMEM;
+
+ iter.desc->ptr = cpu_to_le64(__pa(vsg));
+ }
+
+ iter.desc->cookie = (u64)(unsigned long)vsg;
+ iter.desc->len = cpu_to_le64(SG_DESC_SIZE);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_next, 0, 0);
+ BUG_ON(ret < 0);
+ }
+
+ return 0;
+}
+
+static void
+tx_teardown(struct vbus_enet_priv *priv)
+{
+ struct ioq *ioq = priv->tx.veq.queue;
+ struct ioq_iterator iter;
+ struct sk_buff *skb;
+ int ret;
+
+ /* forcefully free all outstanding transmissions */
+ while ((skb = __skb_dequeue(&priv->tx.outstanding)))
+ dev_kfree_skb(skb);
+
+ if (!priv->sg)
+ /*
+ * There is nothing else to do for a ring that is not using
+ * scatter-gather
+ */
+ return;
+
+ if (priv->pmtd.enabled) {
+ /*
+ * PMTD mode means we only need to free the pool
+ */
+ kfree(priv->pmtd.pool);
+ return;
+ }
+
+ ret = ioq_iter_init(ioq, &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0);
+
+ /* seek to position 0 */
+ ret = ioq_iter_seek(&iter, ioq_seek_set, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * free each valid descriptor
+ */
+ while (iter.desc->cookie) {
+ struct venet_sg *vsg = (struct venet_sg *)(unsigned long)iter.desc->cookie;
+
+ iter.desc->valid = 0;
+ wmb();
+
+ iter.desc->ptr = 0;
+ iter.desc->cookie = 0;
+
+ ret = ioq_iter_seek(&iter, ioq_seek_next, 0, 0);
+ BUG_ON(ret < 0);
+
+ kfree(vsg);
+ }
+}
+
+static void
+evq_teardown(struct vbus_enet_priv *priv)
+{
+ if (!priv->evq.enabled)
+ return;
+
+ ioq_put(priv->evq.veq.queue);
+ kfree(priv->evq.pool);
+}
+
+/*
+ * Open and close
+ */
+
+static int
+vbus_enet_open(struct net_device *dev)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+ int ret;
+
+ ret = devcall(priv, VENET_FUNC_LINKUP, NULL, 0);
+ BUG_ON(ret < 0);
+
+ napi_enable(&priv->napi);
+
+ return 0;
+}
+
+static int
+vbus_enet_stop(struct net_device *dev)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+ int ret;
+
+ napi_disable(&priv->napi);
+
+ ret = devcall(priv, VENET_FUNC_LINKDOWN, NULL, 0);
+ BUG_ON(ret < 0);
+
+ return 0;
+}
+
+/*
+ * Configuration changes (passed on by ifconfig)
+ */
+static int
+vbus_enet_config(struct net_device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP) /* can't act on a running interface */
+ return -EBUSY;
+
+ /* Don't allow changing the I/O address */
+ if (map->base_addr != dev->base_addr) {
+ dev_warn(&dev->dev, "Can't change I/O address\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* ignore other fields */
+ return 0;
+}
+
+static void
+vbus_enet_schedule_rx(struct vbus_enet_priv *priv)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (napi_schedule_prep(&priv->napi)) {
+ /* Disable further interrupts */
+ ioq_notify_disable(priv->rxq.queue, 0);
+ __napi_schedule(&priv->napi);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int
+vbus_enet_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+ int ret;
+
+ dev->mtu = new_mtu;
+
+ /*
+ * FLUSHRX will cause the device to flush any outstanding
+ * RX buffers. They will appear to come in as 0 length
+ * packets which we can simply discard and replace with new_mtu
+ * buffers for the future.
+ */
+ ret = devcall(priv, VENET_FUNC_FLUSHRX, NULL, 0);
+ BUG_ON(ret < 0);
+
+ vbus_enet_schedule_rx(priv);
+
+ return 0;
+}
+
+static struct sk_buff *
+vbus_enet_l4ro_import(struct vbus_enet_priv *priv, struct ioq_ring_desc *desc)
+{
+ struct venet_sg *vsg = (struct venet_sg *)(unsigned long)desc->cookie;
+ struct sk_buff *skb = (struct sk_buff *)(unsigned long)vsg->cookie;
+ struct skb_shared_info *sinfo = skb_shinfo(skb);
+ int i;
+
+ rx_pageq_refill(priv, GFP_ATOMIC);
+
+ if (!vsg->len)
+ /*
+ * the device may send a zero-length packet when its
+ * flushing references on the ring. We can just drop
+ * these on the floor
+ */
+ goto fail;
+
+ /* advance only by the linear portion in IOV[0] */
+ skb_put(skb, vsg->iov[0].len);
+
+ /* skip i=0, since that is the skb->data IOV */
+ for (i = 1; i < vsg->count; i++) {
+ struct venet_iov *iov = &vsg->iov[i];
+ struct page *page = (struct page *)(unsigned long)iov->ptr;
+ skb_frag_t *f = &sinfo->frags[i-1];
+
+ f->page = page;
+ f->page_offset = 0;
+ f->size = iov->len;
+
+ PDEBUG(priv->dev, "SG: Importing %d byte page[%i]\n",
+ f->size, i);
+
+ skb->data_len += f->size;
+ skb->len += f->size;
+ skb->truesize += f->size;
+ sinfo->nr_frags++;
+ }
+
+ if (vsg->flags & VENET_SG_FLAG_NEEDS_CSUM
+ && !skb_partial_csum_set(skb, vsg->csum.start,
+ vsg->csum.offset)) {
+ priv->dev->stats.rx_frame_errors++;
+ goto fail;
+ }
+
+ if (vsg->flags & VENET_SG_FLAG_GSO) {
+ PDEBUG(priv->dev, "L4RO packet detected\n");
+
+ switch (vsg->gso.type) {
+ case VENET_GSO_TYPE_TCPV4:
+ sinfo->gso_type = SKB_GSO_TCPV4;
+ break;
+ case VENET_GSO_TYPE_TCPV6:
+ sinfo->gso_type = SKB_GSO_TCPV6;
+ break;
+ case VENET_GSO_TYPE_UDP:
+ sinfo->gso_type = SKB_GSO_UDP;
+ break;
+ default:
+ PDEBUG(priv->dev, "Illegal L4RO type: %d\n",
+ vsg->gso.type);
+ priv->dev->stats.rx_frame_errors++;
+ goto fail;
+ }
+
+ if (vsg->flags & VENET_SG_FLAG_ECN)
+ sinfo->gso_type |= SKB_GSO_TCP_ECN;
+
+ sinfo->gso_size = vsg->gso.size;
+ if (sinfo->gso_size == 0) {
+ PDEBUG(priv->dev, "Illegal L4RO size: %d\n",
+ vsg->gso.size);
+ priv->dev->stats.rx_frame_errors++;
+ goto fail;
+ }
+
+ /*
+ * Header must be checked, and gso_segs
+ * computed.
+ */
+ sinfo->gso_type |= SKB_GSO_DODGY;
+ sinfo->gso_segs = 0;
+ }
+
+ return skb;
+
+fail:
+ dev_kfree_skb(skb);
+
+ return NULL;
+}
+
+static struct sk_buff *
+vbus_enet_flat_import(struct vbus_enet_priv *priv, struct ioq_ring_desc *desc)
+{
+ struct sk_buff *skb = (struct sk_buff *)(unsigned long)desc->cookie;
+
+ if (!desc->len) {
+ /*
+ * the device may send a zero-length packet when its
+ * flushing references on the ring. We can just drop
+ * these on the floor
+ */
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+
+ skb_put(skb, le64_to_cpu(desc->len));
+
+ return skb;
+}
+
+/*
+ * The poll implementation.
+ */
+static int
+vbus_enet_poll(struct napi_struct *napi, int budget)
+{
+ struct vbus_enet_priv *priv = napi_to_priv(napi);
+ int npackets = 0;
+ struct ioq_iterator iter;
+ int ret;
+
+ PDEBUG(priv->dev, "polling...\n");
+
+ /* We want to iterate on the head of the in-use index */
+ ret = ioq_iter_init(priv->rxq.queue, &iter, ioq_idxtype_inuse,
+ IOQ_ITER_AUTOUPDATE);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * We stop if we have met the quota or there are no more packets.
+ * The EOM is indicated by finding a packet that is still owned by
+ * the south side
+ */
+ while ((npackets < budget) && (!iter.desc->sown)) {
+ struct sk_buff *skb;
+
+ skb = priv->import(priv, iter.desc);
+ if (skb) {
+ /* Maintain stats */
+ npackets++;
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += skb->len;
+
+ /* Pass the buffer up to the stack */
+ skb->dev = priv->dev;
+ skb->protocol = eth_type_trans(skb, priv->dev);
+ netif_receive_skb(skb);
+
+ mb();
+ }
+
+ /* Grab a new buffer to put in the ring */
+ rxdesc_alloc(priv, iter.desc, priv->dev->mtu);
+
+ /* Advance the in-use tail */
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+ }
+
+ PDEBUG(priv->dev, "%d packets received\n", npackets);
+
+ /*
+ * If we processed all packets, we're done; tell the kernel and
+ * reenable ints
+ */
+ if (ioq_empty(priv->rxq.queue, ioq_idxtype_inuse)) {
+ napi_complete(napi);
+ ioq_notify_enable(priv->rxq.queue, 0);
+ ret = 0;
+ } else
+ /* We couldn't process everything. */
+ ret = 1;
+
+ return ret;
+}
+
+/*
+ * Transmit a packet (called by the kernel)
+ */
+static int
+vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+ struct ioq_iterator iter;
+ int ret;
+ unsigned long flags;
+
+ PDEBUG(priv->dev, "sending %d bytes\n", skb->len);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
+ /*
+ * We must flow-control the kernel by disabling the
+ * queue
+ */
+ spin_unlock_irqrestore(&priv->lock, flags);
+ netif_stop_queue(dev);
+ dev_err(&priv->dev->dev, "tx on full queue bug\n");
+ return 1;
+ }
+
+ /*
+ * We want to iterate on the tail of both the "inuse" and "valid" index
+ * so we specify the "both" index
+ */
+ ret = ioq_iter_init(priv->tx.veq.queue, &iter, ioq_idxtype_both,
+ IOQ_ITER_AUTOUPDATE);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_tail, 0, 0);
+ BUG_ON(ret < 0);
+ BUG_ON(iter.desc->sown);
+
+ if (priv->sg) {
+ struct venet_sg *vsg = (struct venet_sg *)(unsigned long)iter.desc->cookie;
+ struct scatterlist sgl[MAX_SKB_FRAGS+1];
+ struct scatterlist *sg;
+ int count, maxcount = ARRAY_SIZE(sgl);
+
+ sg_init_table(sgl, maxcount);
+
+ memset(vsg, 0, sizeof(*vsg));
+
+ vsg->cookie = (u64)(unsigned long)skb;
+ vsg->len = skb->len;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ vsg->flags |= VENET_SG_FLAG_NEEDS_CSUM;
+ vsg->csum.start = skb->csum_start - skb_headroom(skb);
+ vsg->csum.offset = skb->csum_offset;
+ }
+
+ if (skb_is_gso(skb)) {
+ struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+ vsg->flags |= VENET_SG_FLAG_GSO;
+
+ vsg->gso.hdrlen = skb_headlen(skb);
+ vsg->gso.size = sinfo->gso_size;
+ if (sinfo->gso_type & SKB_GSO_TCPV4)
+ vsg->gso.type = VENET_GSO_TYPE_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ vsg->gso.type = VENET_GSO_TYPE_TCPV6;
+ else if (sinfo->gso_type & SKB_GSO_UDP)
+ vsg->gso.type = VENET_GSO_TYPE_UDP;
+ else
+ panic("Virtual-Ethernet: unknown GSO type " \
+ "0x%x\n", sinfo->gso_type);
+
+ if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+ vsg->flags |= VENET_SG_FLAG_ECN;
+ }
+
+ count = skb_to_sgvec(skb, sgl, 0, skb->len);
+
+ BUG_ON(count > maxcount);
+
+ for (sg = &sgl[0]; sg; sg = sg_next(sg)) {
+ struct venet_iov *iov = &vsg->iov[vsg->count++];
+
+ iov->len = sg->length;
+ iov->ptr = (u64)sg_phys(sg);
+ }
+
+ iter.desc->len = cpu_to_le64(VSG_DESC_SIZE(vsg->count));
+
+ } else {
+ /*
+ * non scatter-gather mode: simply put the skb right onto the
+ * ring.
+ */
+ iter.desc->cookie = (u64)(unsigned long)skb;
+ iter.desc->len = cpu_to_le64(skb->len);
+ iter.desc->ptr = cpu_to_le64(__pa(skb->data));
+ }
+
+ iter.desc->valid = 1;
+
+ priv->dev->stats.tx_packets++;
+ priv->dev->stats.tx_bytes += skb->len;
+
+ skb_queue_tail(&priv->tx.outstanding, skb);
+
+ /*
+ * This advances both indexes together implicitly, and then
+ * signals the south side to consume the packet
+ */
+ ret = ioq_iter_push(&iter, 0);
+ BUG_ON(ret < 0);
+
+ dev->trans_start = jiffies; /* save the timestamp */
+
+ if (ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
+ /*
+ * If the queue is congested, we must flow-control the kernel
+ */
+ PDEBUG(priv->dev, "backpressure tx queue\n");
+ netif_stop_queue(dev);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+/* assumes priv->lock held */
+static void
+vbus_enet_skb_complete(struct vbus_enet_priv *priv, struct sk_buff *skb)
+{
+ PDEBUG(priv->dev, "completed sending %d bytes\n",
+ skb->len);
+
+ skb_unlink(skb, &priv->tx.outstanding);
+ dev_kfree_skb(skb);
+}
+
+/*
+ * reclaim any outstanding completed tx packets
+ *
+ * assumes priv->lock held
+ */
+static struct sk_buff *
+vbus_enet_tx_reap_one(struct vbus_enet_priv *priv)
+{
+ struct sk_buff *skb = NULL;
+ struct ioq_iterator iter;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /*
+ * We want to iterate on the head of the valid index, but we
+ * do not want the iter_pop (below) to flip the ownership, so
+ * we set the NOFLIPOWNER option
+ */
+ ret = ioq_iter_init(priv->tx.veq.queue, &iter, ioq_idxtype_valid,
+ IOQ_ITER_NOFLIPOWNER);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ if (iter.desc->valid && !iter.desc->sown) {
+
+ if (priv->sg) {
+ struct venet_sg *vsg;
+
+ vsg = (struct venet_sg *)(unsigned long)iter.desc->cookie;
+ skb = (struct sk_buff *)(unsigned long)vsg->cookie;
+ } else
+ skb = (struct sk_buff *)(unsigned long)iter.desc->cookie;
+
+ /* Reset the descriptor */
+ iter.desc->valid = 0;
+
+ /* Advance the valid-index head */
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+ }
+
+ /*
+ * If we were previously stopped due to flow control, restart the
+ * processing
+ */
+ if (netif_queue_stopped(priv->dev)
+ && !ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
+ PDEBUG(priv->dev, "re-enabling tx queue\n");
+ netif_wake_queue(priv->dev);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return skb;
+}
+
+static void
+vbus_enet_tx_reap(struct vbus_enet_priv *priv)
+{
+ struct sk_buff *skb;
+
+ while ((skb = vbus_enet_tx_reap_one(priv))) {
+ if (!priv->evq.txc)
+ /*
+ * We are responsible for freeing the packet upon
+ * reap if TXC is not enabled
+ */
+ vbus_enet_skb_complete(priv, skb);
+ }
+}
+
+static void
+vbus_enet_timeout(struct net_device *dev)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+
+ dev_dbg(&dev->dev, "Transmit timeout\n");
+
+ vbus_enet_tx_reap(priv);
+}
+
+static void
+rx_isr(struct ioq_notifier *notifier)
+{
+ struct vbus_enet_priv *priv;
+ struct net_device *dev;
+
+ priv = container_of(notifier, struct vbus_enet_priv, rxq.notifier);
+ dev = priv->dev;
+
+ if (!ioq_empty(priv->rxq.queue, ioq_idxtype_inuse))
+ vbus_enet_schedule_rx(priv);
+}
+
+static void
+deferred_tx_isr(unsigned long data)
+{
+ struct vbus_enet_priv *priv = (struct vbus_enet_priv *)data;
+
+ PDEBUG(priv->dev, "deferred_tx_isr\n");
+
+ vbus_enet_tx_reap(priv);
+
+ ioq_notify_enable(priv->tx.veq.queue, 0);
+}
+
+static void
+tx_isr(struct ioq_notifier *notifier)
+{
+ struct vbus_enet_priv *priv;
+
+ priv = container_of(notifier, struct vbus_enet_priv, tx.veq.notifier);
+
+ PDEBUG(priv->dev, "tx_isr\n");
+
+ ioq_notify_disable(priv->tx.veq.queue, 0);
+ tasklet_schedule(&priv->tx.task);
+}
+
+static void
+evq_linkstate_event(struct vbus_enet_priv *priv,
+ struct venet_event_header *header)
+{
+ struct venet_event_linkstate *event =
+ (struct venet_event_linkstate *)header;
+
+ switch (event->state) {
+ case 0:
+ netif_carrier_off(priv->dev);
+ break;
+ case 1:
+ netif_carrier_on(priv->dev);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+evq_txc_event(struct vbus_enet_priv *priv,
+ struct venet_event_header *header)
+{
+ struct venet_event_txc *event =
+ (struct venet_event_txc *)header;
+
+ vbus_enet_tx_reap(priv);
+
+ vbus_enet_skb_complete(priv, (struct sk_buff *)(unsigned long)event->cookie);
+}
+
+static void
+deferred_evq_isr(unsigned long data)
+{
+ struct vbus_enet_priv *priv = (struct vbus_enet_priv *)data;
+ int nevents = 0;
+ struct ioq_iterator iter;
+ int ret;
+
+ PDEBUG(priv->dev, "evq: polling...\n");
+
+ /* We want to iterate on the head of the in-use index */
+ ret = ioq_iter_init(priv->evq.veq.queue, &iter, ioq_idxtype_inuse,
+ IOQ_ITER_AUTOUPDATE);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * The EOM is indicated by finding a packet that is still owned by
+ * the south side
+ */
+ while (!iter.desc->sown) {
+ struct venet_event_header *header;
+
+ header = (struct venet_event_header *)(unsigned long)iter.desc->cookie;
+
+ switch (header->id) {
+ case VENET_EVENT_LINKSTATE:
+ evq_linkstate_event(priv, header);
+ break;
+ case VENET_EVENT_TXC:
+ evq_txc_event(priv, header);
+ break;
+ default:
+ panic("venet: unexpected event id:%d of size %d\n",
+ header->id, header->size);
+ break;
+ }
+
+ memset((void *)(unsigned long)iter.desc->cookie, 0, priv->evq.evsize);
+
+ /* Advance the in-use tail */
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+
+ nevents++;
+ }
+
+ PDEBUG(priv->dev, "%d events received\n", nevents);
+
+ ioq_notify_enable(priv->evq.veq.queue, 0);
+}
+
+static void
+evq_isr(struct ioq_notifier *notifier)
+{
+ struct vbus_enet_priv *priv;
+
+ priv = container_of(notifier, struct vbus_enet_priv, evq.veq.notifier);
+
+ PDEBUG(priv->dev, "evq_isr\n");
+
+ ioq_notify_disable(priv->evq.veq.queue, 0);
+ tasklet_schedule(&priv->evq.task);
+}
+
+static int
+vbus_enet_sg_negcap(struct vbus_enet_priv *priv)
+{
+ struct net_device *dev = priv->dev;
+ struct venet_capabilities caps;
+ int ret;
+
+ memset(&caps, 0, sizeof(caps));
+
+ if (sg_enabled) {
+ caps.gid = VENET_CAP_GROUP_SG;
+ caps.bits |= (VENET_CAP_SG|VENET_CAP_TSO4|VENET_CAP_TSO6
+ |VENET_CAP_ECN|VENET_CAP_PMTD);
+ /* note: exclude UFO for now due to stack bug */
+ }
+
+ ret = devcall(priv, VENET_FUNC_NEGCAP, &caps, sizeof(caps));
+ if (ret < 0)
+ return ret;
+
+ if (caps.bits & VENET_CAP_SG) {
+ priv->sg = true;
+
+ dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM|NETIF_F_FRAGLIST;
+
+ if (caps.bits & VENET_CAP_TSO4)
+ dev->features |= NETIF_F_TSO;
+ if (caps.bits & VENET_CAP_UFO)
+ dev->features |= NETIF_F_UFO;
+ if (caps.bits & VENET_CAP_TSO6)
+ dev->features |= NETIF_F_TSO6;
+ if (caps.bits & VENET_CAP_ECN)
+ dev->features |= NETIF_F_TSO_ECN;
+
+ if (caps.bits & VENET_CAP_PMTD)
+ priv->pmtd.enabled = true;
+ }
+
+ return 0;
+}
+
+static int
+vbus_enet_evq_negcap(struct vbus_enet_priv *priv, unsigned long count)
+{
+ struct venet_capabilities caps;
+ int ret;
+
+ memset(&caps, 0, sizeof(caps));
+
+ caps.gid = VENET_CAP_GROUP_EVENTQ;
+ caps.bits |= VENET_CAP_EVQ_LINKSTATE;
+ caps.bits |= VENET_CAP_EVQ_TXC;
+
+ ret = devcall(priv, VENET_FUNC_NEGCAP, &caps, sizeof(caps));
+ if (ret < 0)
+ return ret;
+
+ if (caps.bits) {
+ struct vbus_device_proxy *dev = priv->vdev;
+ struct venet_eventq_query query;
+ size_t poollen;
+ struct ioq_iterator iter;
+ char *pool;
+ int i;
+
+ priv->evq.enabled = true;
+
+ if (caps.bits & VENET_CAP_EVQ_LINKSTATE) {
+ /*
+ * We will assume there is no carrier until we get
+ * an event telling us otherwise
+ */
+ netif_carrier_off(priv->dev);
+ priv->evq.linkstate = true;
+ }
+
+ if (caps.bits & VENET_CAP_EVQ_TXC)
+ priv->evq.txc = true;
+
+ memset(&query, 0, sizeof(query));
+
+ ret = devcall(priv, VENET_FUNC_EVQQUERY, &query, sizeof(query));
+ if (ret < 0)
+ return ret;
+
+ priv->evq.evsize = query.evsize;
+ poollen = query.evsize * count;
+
+ pool = kzalloc(poollen, GFP_KERNEL | GFP_DMA);
+ if (!pool)
+ return -ENOMEM;
+
+ priv->evq.pool = pool;
+
+ ret = dev->ops->shm(dev, NULL, query.dpid, 0,
+ pool, poollen, NULL, NULL, 0);
+ if (ret < 0)
+ return ret;
+
+ queue_init(priv, &priv->evq.veq, "evq",
+ query.qid, count, evq_isr);
+
+ ret = ioq_iter_init(priv->evq.veq.queue,
+ &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_set, 0, 0);
+ BUG_ON(ret < 0);
+
+ /* Now populate each descriptor with an empty event */
+ for (i = 0; i < count; i++) {
+ size_t offset = (i * query.evsize);
+ void *addr = &priv->evq.pool[offset];
+
+ iter.desc->ptr = cpu_to_le64(offset);
+ iter.desc->cookie = (u64)(unsigned long)addr;
+ iter.desc->len = cpu_to_le64(query.evsize);
+
+ ret = ioq_iter_push(&iter, 0);
+ BUG_ON(ret < 0);
+ }
+
+ /* Finally, enable interrupts */
+ tasklet_init(&priv->evq.task, deferred_evq_isr,
+ (unsigned long)priv);
+ ioq_notify_enable(priv->evq.veq.queue, 0);
+ }
+
+ return 0;
+}
+
+static int
+vbus_enet_l4ro_negcap(struct vbus_enet_priv *priv, unsigned long count)
+{
+ struct venet_capabilities caps;
+ int ret;
+
+ memset(&caps, 0, sizeof(caps));
+
+ caps.gid = VENET_CAP_GROUP_L4RO;
+ caps.bits |= (VENET_CAP_SG|VENET_CAP_TSO4|VENET_CAP_TSO6
+ |VENET_CAP_ECN);
+
+ ret = devcall(priv, VENET_FUNC_NEGCAP, &caps, sizeof(caps));
+ if (ret < 0) {
+ printk(KERN_ERR "Error negotiating L4RO: %d\n", ret);
+ return ret;
+ }
+
+ if (caps.bits & VENET_CAP_SG) {
+ struct vbus_device_proxy *dev = priv->vdev;
+ size_t poollen = SG_DESC_SIZE * count;
+ struct venet_l4ro_query query;
+ char *pool;
+
+ memset(&query, 0, sizeof(query));
+
+ ret = devcall(priv, VENET_FUNC_L4ROQUERY, &query, sizeof(query));
+ if (ret < 0) {
+ printk(KERN_ERR "Error querying L4RO: %d\n", ret);
+ return ret;
+ }
+
+ pool = kzalloc(poollen, GFP_KERNEL | GFP_DMA);
+ if (!pool)
+ return -ENOMEM;
+
+ /*
+ * pre-mapped descriptor pool
+ */
+ ret = dev->ops->shm(dev, NULL, query.dpid, 0,
+ pool, poollen, NULL, NULL, 0);
+ if (ret < 0) {
+ printk(KERN_ERR "Error registering L4RO pool: %d\n",
+ ret);
+ kfree(pool);
+ return ret;
+ }
+
+ /*
+ * page-queue: contains a ring of arbitrary pages for
+ * consumption by the host for when the SG::IOV count exceeds
+ * one MTU frame. All we need to do is keep it populated
+ * with free pages.
+ */
+ queue_init(priv, &priv->l4ro.pageq, "pageq", query.pqid,
+ count, NULL);
+
+ priv->l4ro.pool = pool;
+ priv->l4ro.available = true;
+ }
+
+ return 0;
+}
+
+static int
+vbus_enet_negcap(struct vbus_enet_priv *priv)
+{
+ int ret;
+
+ ret = vbus_enet_sg_negcap(priv);
+ if (ret < 0)
+ return ret;
+
+ ret = vbus_enet_evq_negcap(priv, tx_ringlen);
+ if (ret < 0)
+ return ret;
+
+ ret = vbus_enet_l4ro_negcap(priv, rx_ringlen);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int vbus_enet_set_tx_csum(struct net_device *dev, u32 data)
+{
+ struct vbus_enet_priv *priv = netdev_priv(dev);
+
+ if (data && !priv->sg)
+ return -ENOSYS;
+
+ return ethtool_op_set_tx_hw_csum(dev, data);
+}
+
+static struct ethtool_ops vbus_enet_ethtool_ops = {
+ .set_tx_csum = vbus_enet_set_tx_csum,
+ .set_sg = ethtool_op_set_sg,
+ .set_tso = ethtool_op_set_tso,
+ .get_link = ethtool_op_get_link,
+};
+
+static const struct net_device_ops vbus_enet_netdev_ops = {
+ .ndo_open = vbus_enet_open,
+ .ndo_stop = vbus_enet_stop,
+ .ndo_set_config = vbus_enet_config,
+ .ndo_start_xmit = vbus_enet_tx_start,
+ .ndo_change_mtu = vbus_enet_change_mtu,
+ .ndo_tx_timeout = vbus_enet_timeout,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+/*
+ * This is called whenever a new vbus_device_proxy is added to the vbus
+ * with the matching VENET_ID
+ */
+static int
+vbus_enet_probe(struct vbus_device_proxy *vdev)
+{
+ struct net_device *dev;
+ struct vbus_enet_priv *priv;
+ int ret;
+
+ printk(KERN_INFO "VENET: Found new device at %lld\n", vdev->id);
+
+ ret = vdev->ops->open(vdev, VENET_VERSION, 0);
+ if (ret < 0)
+ return ret;
+
+ dev = alloc_etherdev(sizeof(struct vbus_enet_priv));
+ if (!dev)
+ return -ENOMEM;
+
+ /*
+ * establish our device-name early so we can incorporate it into
+ * the signal-path names, etc
+ */
+ rtnl_lock();
+
+ ret = dev_alloc_name(dev, dev->name);
+ if (ret < 0)
+ goto out_free;
+
+ priv = netdev_priv(dev);
+
+ spin_lock_init(&priv->lock);
+ priv->dev = dev;
+ priv->vdev = vdev;
+
+ ret = vbus_enet_negcap(priv);
+ if (ret < 0) {
+ printk(KERN_INFO "VENET: Error negotiating capabilities for " \
+ "%lld\n",
+ priv->vdev->id);
+ goto out_free;
+ }
+
+ if (priv->l4ro.available)
+ priv->import = &vbus_enet_l4ro_import;
+ else
+ priv->import = &vbus_enet_flat_import;
+
+ skb_queue_head_init(&priv->tx.outstanding);
+
+ queue_init(priv, &priv->rxq, "rx", VENET_QUEUE_RX, rx_ringlen,
+ rx_isr);
+ queue_init(priv, &priv->tx.veq, "tx", VENET_QUEUE_TX, tx_ringlen,
+ tx_isr);
+
+ rx_setup(priv);
+ tx_setup(priv);
+
+ ioq_notify_enable(priv->rxq.queue, 0); /* enable rx interrupts */
+
+ if (!priv->evq.txc) {
+ /*
+ * If the TXC feature is present, we will recieve our
+ * tx-complete notification via the event-channel. Therefore,
+ * we only enable txq interrupts if the TXC feature is not
+ * present.
+ */
+ tasklet_init(&priv->tx.task, deferred_tx_isr,
+ (unsigned long)priv);
+ ioq_notify_enable(priv->tx.veq.queue, 0);
+ }
+
+ dev->netdev_ops = &vbus_enet_netdev_ops;
+ dev->watchdog_timeo = 5 * HZ;
+ SET_ETHTOOL_OPS(dev, &vbus_enet_ethtool_ops);
+ SET_NETDEV_DEV(dev, &vdev->dev);
+
+ netif_napi_add(dev, &priv->napi, vbus_enet_poll, 128);
+
+ ret = devcall(priv, VENET_FUNC_MACQUERY, priv->dev->dev_addr, ETH_ALEN);
+ if (ret < 0) {
+ printk(KERN_INFO "VENET: Error obtaining MAC address for " \
+ "%lld\n",
+ priv->vdev->id);
+ goto out_free;
+ }
+
+ dev->features |= NETIF_F_HIGHDMA;
+
+ ret = register_netdevice(dev);
+ if (ret < 0) {
+ printk(KERN_INFO "VENET: error %i registering device \"%s\"\n",
+ ret, dev->name);
+ goto out_free;
+ }
+
+ rtnl_unlock();
+
+ vdev->priv = priv;
+
+ return 0;
+
+ out_free:
+ rtnl_unlock();
+
+ free_netdev(dev);
+
+ return ret;
+}
+
+static int
+vbus_enet_remove(struct vbus_device_proxy *vdev)
+{
+ struct vbus_enet_priv *priv = (struct vbus_enet_priv *)vdev->priv;
+ struct vbus_device_proxy *dev = priv->vdev;
+
+ unregister_netdev(priv->dev);
+ napi_disable(&priv->napi);
+
+ rx_teardown(priv);
+ ioq_put(priv->rxq.queue);
+
+ tx_teardown(priv);
+ ioq_put(priv->tx.veq.queue);
+
+ if (priv->evq.enabled)
+ evq_teardown(priv);
+
+ dev->ops->close(dev, 0);
+
+ free_netdev(priv->dev);
+
+ return 0;
+}
+
+/*
+ * Finally, the module stuff
+ */
+
+static struct vbus_driver_ops vbus_enet_driver_ops = {
+ .probe = vbus_enet_probe,
+ .remove = vbus_enet_remove,
+};
+
+static struct vbus_driver vbus_enet_driver = {
+ .type = VENET_TYPE,
+ .owner = THIS_MODULE,
+ .ops = &vbus_enet_driver_ops,
+};
+
+static __init int
+vbus_enet_init_module(void)
+{
+ printk(KERN_INFO "Virtual Ethernet: Copyright (C) 2009 Novell, Gregory Haskins\n");
+ printk(KERN_DEBUG "VENET: Using %d/%d queue depth\n",
+ rx_ringlen, tx_ringlen);
+ return vbus_driver_register(&vbus_enet_driver);
+}
+
+static __exit void
+vbus_enet_cleanup(void)
+{
+ vbus_driver_unregister(&vbus_enet_driver);
+}
+
+module_init(vbus_enet_init_module);
+module_exit(vbus_enet_cleanup);
+
+VBUS_DRIVER_AUTOPROBE(VENET_TYPE);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index fd69095ef6e3..6884813b809c 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1954,7 +1954,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
*/
static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
{
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (rd->rdesc1.CSM & CSM_IPKT) {
if (rd->rdesc1.CSM & CSM_IPOK) {
@@ -2824,7 +2824,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
- NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG;
+ NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
ret = register_netdev(dev);
if (ret < 0)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4598e9d2608f..bb6b67f6b0cc 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -705,19 +705,6 @@ static int virtnet_close(struct net_device *dev)
return 0;
}
-static void virtnet_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- struct virtnet_info *vi = netdev_priv(dev);
- struct virtio_device *vdev = vi->vdev;
-
- strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver));
- strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version));
- strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version));
- strncpy(drvinfo->bus_info, dev_name(&vdev->dev),
- ARRAY_SIZE(drvinfo->bus_info));
-}
-
static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -830,7 +817,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
}
static const struct ethtool_ops virtnet_ethtool_ops = {
- .get_drvinfo = virtnet_get_drvinfo,
.set_tx_csum = virtnet_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index abe0ff53daf3..198ce92af0c3 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1042,11 +1042,11 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
skb->csum = htons(gdesc->rcd.csum);
skb->ip_summed = CHECKSUM_PARTIAL;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
}
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
}
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index c7c5605b3728..5378b849f54f 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -501,7 +501,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
vxge_rx_complete(ring, skb, ext_info.vlan,
pkt_length, &ext_info);
@@ -2159,8 +2159,8 @@ start:
/* Alarm MSIX Vectors count */
vdev->intr_cnt++;
- vdev->entries = kzalloc(vdev->intr_cnt * sizeof(struct msix_entry),
- GFP_KERNEL);
+ vdev->entries = kcalloc(vdev->intr_cnt, sizeof(struct msix_entry),
+ GFP_KERNEL);
if (!vdev->entries) {
vxge_debug_init(VXGE_ERR,
"%s: memory allocation failed",
@@ -2169,9 +2169,9 @@ start:
goto alloc_entries_failed;
}
- vdev->vxge_entries =
- kzalloc(vdev->intr_cnt * sizeof(struct vxge_msix_entry),
- GFP_KERNEL);
+ vdev->vxge_entries = kcalloc(vdev->intr_cnt,
+ sizeof(struct vxge_msix_entry),
+ GFP_KERNEL);
if (!vdev->vxge_entries) {
vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
VXGE_DRIVER_NAME);
@@ -2914,26 +2914,18 @@ static int vxge_change_mtu(struct net_device *dev, int new_mtu)
}
/**
- * vxge_get_stats
+ * vxge_get_stats64
* @dev: pointer to the device structure
+ * @stats: pointer to struct rtnl_link_stats64
*
- * Updates the device statistics structure. This function updates the device
- * statistics structure in the net_device structure and returns a pointer
- * to the same.
*/
-static struct net_device_stats *
-vxge_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *
+vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
{
- struct vxgedev *vdev;
- struct net_device_stats *net_stats;
+ struct vxgedev *vdev = netdev_priv(dev);
int k;
- vdev = netdev_priv(dev);
-
- net_stats = &vdev->stats.net_stats;
-
- memset(net_stats, 0, sizeof(struct net_device_stats));
-
+ /* net_stats already zeroed by caller */
for (k = 0; k < vdev->no_of_vpath; k++) {
net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms;
net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
@@ -3102,7 +3094,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
static const struct net_device_ops vxge_netdev_ops = {
.ndo_open = vxge_open,
.ndo_stop = vxge_close,
- .ndo_get_stats = vxge_get_stats,
+ .ndo_get_stats64 = vxge_get_stats64,
.ndo_start_xmit = vxge_xmit,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = vxge_set_multicast,
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 2e3b064b8e4b..d4be07eaacd7 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -172,7 +172,6 @@ struct vxge_msix_entry {
struct vxge_sw_stats {
/* Network Stats (interface stats) */
- struct net_device_stats net_stats;
/* Tx */
u64 tx_frms;
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 0bd898c94759..4ac85a09c5a6 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -264,7 +264,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index a5ddc6c8963e..164c3624ba89 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -73,7 +73,7 @@ static int reset_cyc2x(void __iomem *addr);
static int detect_cyc2x(void __iomem *addr);
/* Miscellaneous functions */
-static int get_option_index(long *optlist, long optval);
+static int get_option_index(const long *optlist, long optval);
static u16 checksum(u8 *buf, u32 len);
#define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET)
@@ -81,23 +81,23 @@ static u16 checksum(u8 *buf, u32 len);
/* Global Data */
/* private data */
-static char modname[] = "cycx_drv";
-static char fullname[] = "Cyclom 2X Support Module";
-static char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
+static const char modname[] = "cycx_drv";
+static const char fullname[] = "Cyclom 2X Support Module";
+static const char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
"<acme@conectiva.com.br>";
/* Hardware configuration options.
* These are arrays of configuration options used by verification routines.
* The first element of each array is its size (i.e. number of options).
*/
-static long cyc2x_dpmbase_options[] = {
+static const long cyc2x_dpmbase_options[] = {
20,
0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000,
0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000,
0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000
};
-static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
+static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
/* Kernel Loadable Module Entry Points */
/* Module 'insert' entry point.
@@ -529,7 +529,7 @@ static int detect_cyc2x(void __iomem *addr)
/* Miscellaneous */
/* Get option's index into the options list.
* Return option's index (1 .. N) or zero if option is invalid. */
-static int get_option_index(long *optlist, long optval)
+static int get_option_index(const long *optlist, long optval)
{
int i = 1;
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index a0e8611ad8e8..859dba9b972e 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -81,9 +81,9 @@ static irqreturn_t cycx_isr(int irq, void *dev_id);
*/
/* private data */
-static char cycx_drvname[] = "cyclomx";
-static char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
-static char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
+static const char cycx_drvname[] = "cyclomx";
+static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
+static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
"<acme@conectiva.com.br>";
static int cycx_ncards = CONFIG_CYCX_CARDS;
static struct cycx_device *cycx_card_array; /* adapter data space */
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 4d4dc38c7290..7f5bb913c8b9 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -46,7 +46,7 @@
#include <net/x25device.h>
-static char bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* If this number is made larger, check that the temporary string buffer
* in lapbeth_new_device is large enough to store the probe device name.*/
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index e2c6f7f4f51c..43af85b8e45e 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1105,7 +1105,7 @@ static int lmc_open(struct net_device *dev)
init_timer (&sc->timer);
sc->timer.expires = jiffies + HZ;
sc->timer.data = (unsigned long) dev;
- sc->timer.function = &lmc_watchdog;
+ sc->timer.function = lmc_watchdog;
add_timer (&sc->timer);
lmc_trace(dev, "lmc_open out");
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 5394b51bdb2f..7a3720f09ce3 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -282,7 +282,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index c6aa66e5b52f..fbf1175a07f1 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -1,5 +1,5 @@
#define USE_PCI_CLOCK
-static char rcsid[] =
+static const char rcsid[] =
"Revision: 3.4.5 Date: 2002/03/07 ";
/*
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index e2cff64a446a..fd7375955e41 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -220,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
new_line.clock_type != CLOCK_TXFROMRX &&
new_line.clock_type != CLOCK_INT &&
new_line.clock_type != CLOCK_TXINT)
- return -EINVAL; /* No such clock setting */
+ return -EINVAL; /* No such clock setting */
if (new_line.loopback != 0 && new_line.loopback != 1)
return -EINVAL;
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index fbf5e843d48c..93956861ea21 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -766,7 +766,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id)
EXPORT_SYMBOL(z8530_interrupt);
-static char reg_init[16]=
+static const u8 reg_init[16]=
{
0,0,0,0,
0,0,0,0,
@@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(z8530_sync_txdma_close);
* it exists...
*/
-static char *z8530_type_name[]={
+static const char *z8530_type_name[]={
"Z8530",
"Z85C30",
"Z85230"
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index eb72c67699ab..f1549fff0edc 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -342,10 +342,10 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
model_name, dev->irq, dev->mem_start, dev->mem_end-1);
- ei_status.reset_8390 = &wd_reset_8390;
- ei_status.block_input = &wd_block_input;
- ei_status.block_output = &wd_block_output;
- ei_status.get_8390_hdr = &wd_get_8390_hdr;
+ ei_status.reset_8390 = wd_reset_8390;
+ ei_status.block_input = wd_block_input;
+ ei_status.block_output = wd_block_output;
+ ei_status.get_8390_hdr = wd_get_8390_hdr;
dev->netdev_ops = &wd_netdev_ops;
NS8390_init(dev, 0);
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index b1aec3e1892f..ac04c31a166b 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -119,6 +119,7 @@ const struct file_operations i2400m_rx_stats_fops = {
.open = i2400m_stats_open,
.read = i2400m_rx_stats_read,
.write = i2400m_rx_stats_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -171,6 +172,7 @@ const struct file_operations i2400m_tx_stats_fops = {
.open = i2400m_stats_open,
.read = i2400m_tx_stats_read,
.write = i2400m_tx_stats_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 1d05445d4ba3..51c1a89a1f42 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -105,7 +105,7 @@ static struct pci_driver airo_driver = {
of statistics in the /proc filesystem */
#define IGNLABEL(comment) NULL
-static char *statsLabels[] = {
+static const char *statsLabels[] = {
"RxOverrun",
IGNLABEL("RxPlcpCrcErr"),
IGNLABEL("RxPlcpFormatErr"),
@@ -932,7 +932,7 @@ typedef struct aironet_ioctl {
unsigned char __user *data; // d-data
} aironet_ioctl;
-static char swversion[] = "2.1";
+static const char swversion[] = "2.1";
#endif /* CISCO_EXT */
#define NUM_MODULES 2
@@ -1374,7 +1374,7 @@ static int micsetup(struct airo_info *ai) {
return SUCCESS;
}
-static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
+static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
/*===========================================================================
* Description: Mic a packet
@@ -2723,9 +2723,8 @@ static int airo_networks_allocate(struct airo_info *ai)
if (ai->networks)
return 0;
- ai->networks =
- kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
- GFP_KERNEL);
+ ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
+ GFP_KERNEL);
if (!ai->networks) {
airo_print_warn("", "Out of memory allocating beacons");
return -ENOMEM;
@@ -4430,21 +4429,24 @@ static const struct file_operations proc_statsdelta_ops = {
.owner = THIS_MODULE,
.read = proc_read,
.open = proc_statsdelta_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_stats_ops = {
.owner = THIS_MODULE,
.read = proc_read,
.open = proc_stats_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_status_ops = {
.owner = THIS_MODULE,
.read = proc_read,
.open = proc_status_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_SSID_ops = {
@@ -4452,7 +4454,8 @@ static const struct file_operations proc_SSID_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_SSID_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_BSSList_ops = {
@@ -4460,7 +4463,8 @@ static const struct file_operations proc_BSSList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_BSSList_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_APList_ops = {
@@ -4468,7 +4472,8 @@ static const struct file_operations proc_APList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_APList_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_config_ops = {
@@ -4476,7 +4481,8 @@ static const struct file_operations proc_config_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_config_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations proc_wepkey_ops = {
@@ -4484,7 +4490,8 @@ static const struct file_operations proc_wepkey_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_wepkey_open,
- .release = proc_close
+ .release = proc_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct proc_dir_entry *airo_entry;
@@ -5024,7 +5031,7 @@ static void proc_config_on_close(struct inode *inode, struct file *file)
airo_config_commit(dev, NULL, NULL, NULL);
}
-static char *get_rmode(__le16 mode)
+static const char *get_rmode(__le16 mode)
{
switch(mode & RXMODE_MASK) {
case RXMODE_RFMON: return "rfmon";
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 1128fa8c9ed5..91c5f73b5ba3 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -2061,11 +2061,12 @@ static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
int i;
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
+ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->cipher %d key->keyidx %d "
"key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ __func__, cmd, key->cipher, key->keyidx, key->keylen);
- if (key->alg != ALG_WEP)
+ if ((key->cipher != WLAN_CIPHER_SUITE_WEP40) &&
+ (key->cipher != WLAN_CIPHER_SUITE_WEP104))
return -EOPNOTSUPP;
key->hw_key_idx = key->keyidx;
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 0a75be027afa..92c216263ee9 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -25,5 +25,6 @@ config ATH_DEBUG
source "drivers/net/wireless/ath/ath5k/Kconfig"
source "drivers/net/wireless/ath/ath9k/Kconfig"
source "drivers/net/wireless/ath/ar9170/Kconfig"
+source "drivers/net/wireless/ath/carl9170/Kconfig"
endif
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 8113a5042afa..40fa1794d489 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K_HW) += ath9k/
obj-$(CONFIG_AR9170_USB) += ar9170/
+obj-$(CONFIG_CARL9170) += carl9170/
obj-$(CONFIG_ATH_COMMON) += ath.o
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index debfb0fbc7c5..32bf79e6a320 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1190,14 +1190,13 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
if (info->control.hw_key) {
icv = info->control.hw_key->icv_len;
- switch (info->control.hw_key->alg) {
- case ALG_WEP:
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
keytype = AR9170_TX_MAC_ENCR_RC4;
break;
- case ALG_TKIP:
- keytype = AR9170_TX_MAC_ENCR_RC4;
- break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
keytype = AR9170_TX_MAC_ENCR_AES;
break;
default:
@@ -1778,17 +1777,17 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if ((!ar->vif) || (ar->disable_offload))
return -EOPNOTSUPP;
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- ktype = AR9170_ENC_ALG_WEP64;
- else
- ktype = AR9170_ENC_ALG_WEP128;
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ ktype = AR9170_ENC_ALG_WEP64;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ ktype = AR9170_ENC_ALG_WEP128;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
ktype = AR9170_ENC_ALG_TKIP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
ktype = AR9170_ENC_ALG_AESCCMP;
break;
default:
@@ -1827,7 +1826,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (err)
goto out;
- if (key->alg == ALG_TKIP) {
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
ktype, 1, key->key + 16, 16);
if (err)
@@ -1864,7 +1863,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (err)
goto out;
- if (key->alg == ALG_TKIP) {
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
err = ar9170_upload_key(ar, key->hw_key_idx,
NULL,
AR9170_ENC_ALG_NONE, 1,
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index d32f2828b098..a706202fa67c 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -119,6 +119,7 @@ struct ath_common {
u32 keymax;
DECLARE_BITMAP(keymap, ATH_KEYMAX);
+ DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
u8 splitmic;
struct ath_regulatory regulatory;
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index 26dbe65fedb0..e4a5f046bba4 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -552,9 +552,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
return;
- /* if one of the errors triggered, we can get a superfluous second
- * interrupt, even though we have already reset the register. the
- * function detects that so we can return early */
+ /* If one of the errors triggered, we can get a superfluous second
+ * interrupt, even though we have already reset the register. The
+ * function detects that so we can return early. */
if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
return;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ea6362a8988d..f399c4dd8e69 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -175,7 +175,7 @@
#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
#define AR5K_TUNE_RADAR_ALERT false
#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
-#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
+#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
#define AR5K_TUNE_REGISTER_TIMEOUT 20000
/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
* be the max value. */
@@ -343,9 +343,6 @@ struct ath5k_srev_name {
#define AR5K_SREV_PHY_5413 0x61
#define AR5K_SREV_PHY_2425 0x70
-/* IEEE defs */
-#define IEEE80211_MAX_LEN 2500
-
/* TODO add support to mac80211 for vendor-specific rates and modes */
/*
@@ -1190,7 +1187,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
/* BSSID Functions */
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-void ath5k_hw_set_associd(struct ath5k_hw *ah);
+void ath5k_hw_set_bssid(struct ath5k_hw *ah);
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
/* Receive start/stop functions */
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index b32e28caeee2..aabad4f13e2a 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -139,12 +139,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
else
ah->ah_version = AR5K_AR5212;
- /*Fill the ath5k_hw struct with the needed functions*/
+ /* Fill the ath5k_hw struct with the needed functions */
ret = ath5k_hw_init_desc_functions(ah);
if (ret)
goto err_free;
- /* Bring device out of sleep and reset it's units */
+ /* Bring device out of sleep and reset its units */
ret = ath5k_hw_nic_wakeup(ah, 0, true);
if (ret)
goto err_free;
@@ -158,7 +158,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
CHANNEL_5GHZ);
ah->ah_phy = AR5K_PHY(0);
- /* Try to identify radio chip based on it's srev */
+ /* Try to identify radio chip based on its srev */
switch (ah->ah_radio_5ghz_revision & 0xf0) {
case AR5K_SREV_RAD_5111:
ah->ah_radio = AR5K_RF5111;
@@ -329,7 +329,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
ath5k_hw_set_opmode(ah, sc->opmode);
ath5k_hw_rfgain_opt_init(ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 373dcfec689c..116ac66c6e3e 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -612,7 +612,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
goto err_free;
}
- /*If we passed the test malloc a ath5k_hw struct*/
+ /* If we passed the test, malloc an ath5k_hw struct */
sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
if (!sc->ah) {
ret = -ENOMEM;
@@ -700,10 +700,10 @@ ath5k_pci_probe(struct pci_dev *pdev,
return 0;
err_ah:
ath5k_hw_detach(sc->ah);
-err_irq:
- free_irq(pdev->irq, sc);
err_free_ah:
kfree(sc->ah);
+err_irq:
+ free_irq(pdev->irq, sc);
err_free:
ieee80211_free_hw(hw);
err_map:
@@ -786,8 +786,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
/*
* Check if the MAC has multi-rate retry support.
* We do this by trying to setup a fake extended
- * descriptor. MAC's that don't have support will
- * return false w/o doing anything. MAC's that do
+ * descriptor. MACs that don't have support will
+ * return false w/o doing anything. MACs that do
* support it will return true w/o doing anything.
*/
ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
@@ -827,7 +827,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
/*
* Allocate hardware transmit queues: one queue for
* beacon frames and one data queue for each QoS
- * priority. Note that hw functions handle reseting
+ * priority. Note that hw functions handle resetting
* these queues at the needed time.
*/
ret = ath5k_beaconq_setup(ah);
@@ -909,7 +909,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
/*
* NB: the order of these is important:
* o call the 802.11 layer before detaching ath5k_hw to
- * insure callbacks into the driver to delete global
+ * ensure callbacks into the driver to delete global
* key cache entries can be handled
* o reclaim the tx queue data structures after calling
* the 802.11 layer as we'll get called back to reclaim
@@ -1327,6 +1327,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
PCI_DMA_TODEVICE);
rate = ieee80211_get_tx_rate(sc->hw, info);
+ if (!rate) {
+ ret = -EINVAL;
+ goto err_unmap;
+ }
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= AR5K_TXDESC_NOACK;
@@ -1514,7 +1518,7 @@ ath5k_txq_setup(struct ath5k_softc *sc,
/*
* Enable interrupts only for EOL and DESC conditions.
* We mark tx descriptors to receive a DESC interrupt
- * when a tx queue gets deep; otherwise waiting for the
+ * when a tx queue gets deep; otherwise we wait for the
* EOL to reap descriptors. Note that this is done to
* reduce interrupt load and this only defers reaping
* descriptors, never transmitting frames. Aside from
@@ -1709,7 +1713,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
struct ath5k_buf *bf;
int ret;
- common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
+ common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
common->cachelsz, common->rx_bufsize);
@@ -1859,7 +1863,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
}
/*
- * Compute padding position. skb must contains an IEEE 802.11 frame
+ * Compute padding position. skb must contain an IEEE 802.11 frame
*/
static int ath5k_common_padpos(struct sk_buff *skb)
{
@@ -1878,10 +1882,9 @@ static int ath5k_common_padpos(struct sk_buff *skb)
}
/*
- * This function expects a 802.11 frame and returns the number of
- * bytes added, or -1 if we don't have enought header room.
+ * This function expects an 802.11 frame and returns the number of
+ * bytes added, or -1 if we don't have enough header room.
*/
-
static int ath5k_add_padding(struct sk_buff *skb)
{
int padpos = ath5k_common_padpos(skb);
@@ -1901,10 +1904,18 @@ static int ath5k_add_padding(struct sk_buff *skb)
}
/*
- * This function expects a 802.11 frame and returns the number of
- * bytes removed
+ * The MAC header is padded to have 32-bit boundary if the
+ * packet payload is non-zero. The general calculation for
+ * padsize would take into account odd header lengths:
+ * padsize = 4 - (hdrlen & 3); however, since only
+ * even-length headers are used, padding can only be 0 or 2
+ * bytes and we can optimize this a bit. We must not try to
+ * remove padding from short control frames that do not have a
+ * payload.
+ *
+ * This function expects an 802.11 frame and returns the number of
+ * bytes removed.
*/
-
static int ath5k_remove_padding(struct sk_buff *skb)
{
int padpos = ath5k_common_padpos(skb);
@@ -1925,14 +1936,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
{
struct ieee80211_rx_status *rxs;
- /* The MAC header is padded to have 32-bit boundary if the
- * packet payload is non-zero. The general calculation for
- * padsize would take into account odd header lengths:
- * padsize = (4 - hdrlen % 4) % 4; However, since only
- * even-length headers are used, padding can only be 0 or 2
- * bytes and we can optimize this a bit. In addition, we must
- * not try to remove padding from short control frames that do
- * not have payload. */
ath5k_remove_padding(skb);
rxs = IEEE80211_SKB_RXCB(skb);
@@ -2036,9 +2039,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
return true;
}
- /* let crypto-error packets fall through in MNTR */
- if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
- sc->opmode != NL80211_IFTYPE_MONITOR)
+ /* reject any frames with non-crypto errors */
+ if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
return false;
}
@@ -2281,10 +2283,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
* default antenna which is supposed to be an omni.
*
* Note2: On sectored scenarios it's possible to have
- * multiple antennas (1omni -the default- and 14 sectors)
- * so if we choose to actually support this mode we need
- * to allow user to set how many antennas we have and tweak
- * the code below to send beacons on all of them.
+ * multiple antennas (1 omni -- the default -- and 14
+ * sectors), so if we choose to actually support this
+ * mode, we need to allow the user to set how many antennas
+ * we have and tweak the code below to send beacons
+ * on all of them.
*/
if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
antenna = sc->bsent & 4 ? 2 : 1;
@@ -2326,14 +2329,13 @@ ath5k_beacon_send(struct ath5k_softc *sc)
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
- if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
- sc->opmode == NL80211_IFTYPE_MONITOR)) {
+ if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) {
ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
return;
}
/*
* Check if the previous beacon has gone out. If
- * not don't don't try to post another, skip this
+ * not, don't don't try to post another: skip this
* period and wait for the next. Missed beacons
* indicate a problem and should not occur. If we
* miss too many consecutive beacons reset the device.
@@ -2901,12 +2903,9 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
ath5k_debug_dump_skb(sc, skb, "TX ", 1);
- if (sc->opmode == NL80211_IFTYPE_MONITOR)
- ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
-
/*
- * the hardware expects the header padded to 4 byte boundaries
- * if this is not the case we add the padding after the header
+ * The hardware expects the header padded to 4 byte boundaries.
+ * If this is not the case, we add the padding after the header.
*/
padsize = ath5k_add_padding(skb);
if (padsize < 0) {
@@ -3049,7 +3048,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_MONITOR:
sc->opmode = vif->type;
break;
default:
@@ -3233,9 +3231,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
rfilt |= AR5K_RX_FILTER_PHYERR;
/* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
- * and probes for any BSSID, this needs testing */
+ * and probes for any BSSID */
if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
- rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
+ rfilt |= AR5K_RX_FILTER_BEACON;
/* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
* set we should only pass on control frames for this
@@ -3251,7 +3249,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
switch (sc->opmode) {
case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_MONITOR:
rfilt |= AR5K_RX_FILTER_CONTROL |
AR5K_RX_FILTER_BEACON |
AR5K_RX_FILTER_PROBEREQ |
@@ -3274,7 +3271,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
/* Set multicast bits */
ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
- /* Set the cached hw filter flags, this will alter actually
+ /* Set the cached hw filter flags, this will later actually
* be set in HW */
sc->filter_flags = rfilt;
@@ -3297,11 +3294,12 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (sc->opmode == NL80211_IFTYPE_AP)
return -EOPNOTSUPP;
- switch (key->alg) {
- case ALG_WEP:
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (sc->ah->ah_aes_support)
break;
@@ -3475,7 +3473,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
/* Cache for later use during resets */
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
common->curaid = 0;
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
mmiowb();
}
@@ -3493,7 +3491,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
"Bss Info ASSOC %d, bssid: %pM\n",
bss_conf->aid, common->curbssid);
common->curaid = bss_conf->aid;
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
/* Once ANI is available you would start it here */
}
}
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4cccc29964f6..5aab7d93df6a 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -271,6 +271,7 @@ static const struct file_operations fops_beacon = {
.write = write_file_beacon,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -290,6 +291,7 @@ static const struct file_operations fops_reset = {
.write = write_file_reset,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
@@ -312,6 +314,7 @@ static const struct {
{ ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
{ ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
{ ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
+ { ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
{ ATH5K_DEBUG_ANY, "all", "show all debug levels" },
};
@@ -369,6 +372,7 @@ static const struct file_operations fops_debug = {
.write = write_file_debug,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -480,6 +484,7 @@ static const struct file_operations fops_antenna = {
.write = write_file_antenna,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -591,6 +596,7 @@ static const struct file_operations fops_frameerrors = {
.write = write_file_frameerrors,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -748,6 +754,7 @@ static const struct file_operations fops_ani = {
.write = write_file_ani,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -811,6 +818,7 @@ static const struct file_operations fops_queue = {
.write = write_file_queue,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -955,7 +963,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
struct ath5k_rx_status rs = {};
int status;
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
return;
printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
@@ -997,7 +1005,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ath5k_tx_status ts = {};
int done;
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+ if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
return;
done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 606ae94a9157..9b22722a95f0 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -95,6 +95,7 @@ struct ath5k_dbg_info {
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
* @ATH5K_DEBUG_DUMPBANDS: dump bands
* @ATH5K_DEBUG_TRACE: trace function calls
+ * @ATH5K_DEBUG_DESC: descriptor setup
* @ATH5K_DEBUG_ANY: show at any debug level
*
* The debug level is used to control the amount and type of debugging output
@@ -117,6 +118,7 @@ enum ath5k_debug_level {
ATH5K_DEBUG_DUMP_TX = 0x00000200,
ATH5K_DEBUG_DUMPBANDS = 0x00000400,
ATH5K_DEBUG_ANI = 0x00002000,
+ ATH5K_DEBUG_DESC = 0x00004000,
ATH5K_DEBUG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 484f31870ba8..58bb6c5dda7b 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -377,11 +377,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
*
* This function increases/decreases the tx trigger level for the tx fifo
* buffer (aka FIFO threshold) that is used to indicate when PCU flushes
- * the buffer and transmits it's data. Lowering this results sending small
+ * the buffer and transmits its data. Lowering this results sending small
* frames more quickly but can lead to tx underruns, raising it a lot can
* result other problems (i think bmiss is related). Right now we start with
* the lowest possible (64Bytes) and if we get tx underrun we increase it using
- * the increase flag. Returns -EIO if we have have reached maximum/minimum.
+ * the increase flag. Returns -EIO if we have reached maximum/minimum.
*
* XXX: Link this with tx DMA size ?
* XXX: Use it to save interrupts ?
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index ae316fec4a6a..39722dd73e43 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -661,7 +661,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
* (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
* steps that match with the power values we read from eeprom. On
* older eeprom versions (< 3.2) these steps are equaly spaced at
- * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * 10% of the pcdac curve -until the curve reaches its maximum-
* (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
* these 11 steps are spaced in a different way. This function returns
* the pcdac steps based on eeprom version and curve min/max so that we
@@ -1113,7 +1113,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
*/
/* For RF2413 power calibration data doesn't start on a fixed location and
- * if a mode is not supported, it's section is missing -not zeroed-.
+ * if a mode is not supported, its section is missing -not zeroed-.
* So we need to calculate the starting offset for each section by using
* these two functions */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 86fdb6ddfaaa..bb2e21553d1b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -137,11 +137,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
* ath5k_hw_set_ack_bitrate - set bitrate for ACKs
*
* @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmition rate
+ * @high: Flag to determine if we want to use high transmission rate
* for ACKs or not
*
* If high flag is set, we tell hw to use a set of control rates based on
- * the current transmition rate (check out control_rates array inside reset.c).
+ * the current transmission rate (check out control_rates array inside reset.c).
* If not hw just uses the lowest rate available for the current modulation
* scheme being used (1Mbit for CCK and 6Mbits for OFDM).
*/
@@ -308,27 +308,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
}
/**
- * ath5k_hw_set_associd - Set BSSID for association
+ * ath5k_hw_set_bssid - Set current BSSID on hw
*
* @ah: The &struct ath5k_hw
- * @bssid: BSSID
- * @assoc_id: Assoc id
*
- * Sets the BSSID which trigers the "SME Join" operation
+ * Sets the current BSSID and BSSID mask we have from the
+ * common struct into the hardware
*/
-void ath5k_hw_set_associd(struct ath5k_hw *ah)
+void ath5k_hw_set_bssid(struct ath5k_hw *ah)
{
struct ath_common *common = ath5k_hw_common(ah);
u16 tim_offset = 0;
/*
- * Set simple BSSID mask on 5212
+ * Set BSSID mask on 5212
*/
if (ah->ah_version == AR5K_AR5212)
ath_hw_setbssidmask(common);
/*
- * Set BSSID which triggers the "SME Join" operation
+ * Set BSSID
*/
ath5k_hw_reg_write(ah,
get_unaligned_le32(common->curbssid),
@@ -695,21 +694,18 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
static
int ath5k_keycache_type(const struct ieee80211_key_conf *key)
{
- switch (key->alg) {
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
return AR5K_KEYTABLE_TYPE_TKIP;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return AR5K_KEYTABLE_TYPE_CCM;
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- return AR5K_KEYTABLE_TYPE_40;
- else if (key->keylen == WLAN_KEY_LEN_WEP104)
- return AR5K_KEYTABLE_TYPE_104;
- return -EINVAL;
+ case WLAN_CIPHER_SUITE_WEP40:
+ return AR5K_KEYTABLE_TYPE_40;
+ case WLAN_CIPHER_SUITE_WEP104:
+ return AR5K_KEYTABLE_TYPE_104;
default:
return -EINVAL;
}
- return -EINVAL;
}
/*
@@ -728,7 +724,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
bool is_tkip;
const u8 *key_ptr;
- is_tkip = (key->alg == ALG_TKIP);
+ is_tkip = (key->cipher == WLAN_CIPHER_SUITE_TKIP);
/*
* key->keylen comes in from mac80211 in bytes.
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 6284c389ba18..4932bf2f35eb 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -115,7 +115,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
\**********************/
/*
- * This code is used to optimize rf gain on different environments
+ * This code is used to optimize RF gain on different environments
* (temperature mostly) based on feedback from a power detector.
*
* It's only used on RF5111 and RF5112, later RF chips seem to have
@@ -302,7 +302,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
}
/* Perform gain_F adjustment by choosing the right set
- * of parameters from rf gain optimization ladder */
+ * of parameters from RF gain optimization ladder */
static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
{
const struct ath5k_gain_opt *go;
@@ -367,7 +367,7 @@ done:
return ret;
}
-/* Main callback for thermal rf gain calibration engine
+/* Main callback for thermal RF gain calibration engine
* Check for a new gain reading and schedule an adjustment
* if needed.
*
@@ -433,7 +433,7 @@ done:
return ah->ah_gain.g_state;
}
-/* Write initial rf gain table to set the RF sensitivity
+/* Write initial RF gain table to set the RF sensitivity
* this one works on all RF chips and has nothing to do
* with gain_F calibration */
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
@@ -496,7 +496,7 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
/*
- * Setup RF registers by writing rf buffer on hw
+ * Setup RF registers by writing RF buffer on hw
*/
int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
unsigned int mode)
@@ -571,7 +571,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}
- /* If it's the first time we set rf buffer, allocate
+ /* If it's the first time we set RF buffer, allocate
* ah->ah_rf_banks based on ah->ah_rf_banks_size
* we set above */
if (ah->ah_rf_banks == NULL) {
@@ -1377,7 +1377,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
/* protect against divide by 0 and loss of sign bits */
if (i_coffd == 0 || q_coffd < 2)
- return -1;
+ return 0;
i_coff = (-iq_corr) / i_coffd;
i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
@@ -1582,7 +1582,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
else if (curr_sym_off >= 31 && curr_sym_off <= 46)
mag_mask[2] |=
plt_mag_map << (curr_sym_off - 31) * 2;
- else if (curr_sym_off >= 46 && curr_sym_off <= 53)
+ else if (curr_sym_off >= 47 && curr_sym_off <= 53)
mag_mask[3] |=
plt_mag_map << (curr_sym_off - 47) * 2;
@@ -2987,7 +2987,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
/*
- * Set transmition power
+ * Set transmission power
*/
int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
@@ -3035,9 +3035,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);
- /* FIXME: Tx power limit for this regdomain
- * XXX: Mac80211/CRDA will do that anyway ? */
-
/* FIXME: Antenna reduction stuff */
/* FIXME: Limit power on turbo modes */
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 55b4ac6d236f..05ef587ad2b4 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1911,7 +1911,7 @@
#define AR5K_PHY_TURBO 0x9804 /* Register Address */
#define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */
#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */
-#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */
+#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */
/*
* PHY agility command register
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 498aa28ea9e6..58912cd762d9 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -326,7 +326,7 @@ commit:
* register). After this MAC and Baseband are
* disabled and a full reset is needed to come
* back. This way we save as much power as possible
- * without puting the card on full sleep.
+ * without putting the card on full sleep.
*/
int ath5k_hw_on_hold(struct ath5k_hw *ah)
{
@@ -344,7 +344,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
/*
* Put chipset on warm reset...
*
- * Note: puting PCI core on warm reset on PCI-E cards
+ * Note: putting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
@@ -400,7 +400,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
/*
* Put chipset on warm reset...
*
- * Note: puting PCI core on warm reset on PCI-E cards
+ * Note: putting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
@@ -959,7 +959,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_QUEUE_DCU_SEQNUM(0));
}
- /* TSF accelerates on AR5211 durring reset
+ /* TSF accelerates on AR5211 during reset
* As a workaround save it here and restore
* it later so that it's back in time after
* reset. This way it'll get re-synced on the
@@ -1080,7 +1080,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return ret;
/* Spur info is available only from EEPROM versions
- * bigger than 5.3 but but the EEPOM routines will use
+ * greater than 5.3, but the EEPROM routines will use
* static values for older versions */
if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
ath5k_hw_set_spur_mitigation_filter(ah,
@@ -1160,7 +1160,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
/* Restore bssid and bssid mask */
- ath5k_hw_set_associd(ah);
+ ath5k_hw_set_bssid(ah);
/* Set PCU config */
ath5k_hw_set_opmode(ah, op_mode);
@@ -1173,11 +1173,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Set RSSI/BRSSI thresholds
*
* Note: If we decide to set this value
- * dynamicaly, have in mind that when AR5K_RSSI_THR
- * register is read it might return 0x40 if we haven't
- * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * dynamically, keep in mind that when AR5K_RSSI_THR
+ * register is read, it might return 0x40 if we haven't
+ * written anything to it. Also, BMISS RSSI threshold is zeroed.
* So doing a save/restore procedure here isn't the right
- * choice. Instead store it on ath5k_hw */
+ * choice. Instead, store it in ath5k_hw */
ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
AR5K_TUNE_BMISS_THRES <<
AR5K_RSSI_THR_BMISS_S),
@@ -1235,7 +1235,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Perform ADC test to see if baseband is ready
- * Set tx hold and check adc test register
+ * Set TX hold and check ADC test register
*/
phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
@@ -1254,15 +1254,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*
* This method is used to calibrate some static offsets
* used together with on-the fly I/Q calibration (the
- * one performed via ath5k_hw_phy_calibrate), that doesn't
+ * one performed via ath5k_hw_phy_calibrate), which doesn't
* interrupt rx path.
*
* While rx path is re-routed to the power detector we also
- * start a noise floor calibration, to measure the
+ * start a noise floor calibration to measure the
* card's noise floor (the noise we measure when we are not
- * transmiting or receiving anything).
+ * transmitting or receiving anything).
*
- * If we are in a noisy environment AGC calibration may time
+ * If we are in a noisy environment, AGC calibration may time
* out and/or noise floor calibration might timeout.
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index e50baff66175..3ac4cff4239d 100644
--- a/drivers/net/wireless/ath/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
@@ -25,10 +25,10 @@
*
* We don't write on those registers directly but
* we send a data packet on the chip, using a special register,
- * that holds all the settings we need. After we 've sent the
+ * that holds all the settings we need. After we've sent the
* data packet, we write on another special register to notify hw
* to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
+ * can be dynamically programmed during operation and the settings
* are applied faster on the hw.
*
* We call each data packet an "RF Bank" and all the data we write
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 973ae4f49f35..4555e9983903 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -46,6 +46,7 @@ ath9k_htc-y += htc_hst.o \
htc_drv_txrx.o \
htc_drv_main.o \
htc_drv_beacon.o \
- htc_drv_init.o
+ htc_drv_init.o \
+ htc_drv_gpio.o
obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index cc648b6ae31c..0496f965314f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/kernel.h>
#include "hw.h"
#include "hw-ops.h"
@@ -48,7 +49,7 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = {
{ 7, 8, 0 } /* lvl 9 */
};
#define ATH9K_ANI_OFDM_NUM_LEVEL \
- (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0]))
+ ARRAY_SIZE(ofdm_level_table)
#define ATH9K_ANI_OFDM_MAX_LEVEL \
(ATH9K_ANI_OFDM_NUM_LEVEL-1)
#define ATH9K_ANI_OFDM_DEF_LEVEL \
@@ -94,7 +95,7 @@ static const struct ani_cck_level_entry cck_level_table[] = {
};
#define ATH9K_ANI_CCK_NUM_LEVEL \
- (sizeof(cck_level_table)/sizeof(cck_level_table[0]))
+ ARRAY_SIZE(cck_level_table)
#define ATH9K_ANI_CCK_MAX_LEVEL \
(ATH9K_ANI_CCK_NUM_LEVEL-1)
#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 303c63da5ea3..94392daebaa0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -580,3 +580,53 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
else
ath9k_hw_attach_ani_ops_old(ah);
}
+
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ u32 modesIndex;
+ int i;
+
+ switch (chan->chanmode) {
+ case CHANNEL_A:
+ case CHANNEL_A_HT20:
+ modesIndex = 1;
+ break;
+ case CHANNEL_A_HT40PLUS:
+ case CHANNEL_A_HT40MINUS:
+ modesIndex = 2;
+ break;
+ case CHANNEL_G:
+ case CHANNEL_G_HT20:
+ case CHANNEL_B:
+ modesIndex = 4;
+ break;
+ case CHANNEL_G_HT40PLUS:
+ case CHANNEL_G_HT40MINUS:
+ modesIndex = 3;
+ break;
+
+ default:
+ return;
+ }
+
+ ENABLE_REGWRITE_BUFFER(ah);
+
+ for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
+ u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
+ u32 val_orig;
+
+ if (reg == AR_PHY_CCK_DETECT) {
+ val_orig = REG_READ(ah, reg);
+ val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+ val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
+
+ REG_WRITE(ah, reg, val|val_orig);
+ } else
+ REG_WRITE(ah, reg, val);
+ }
+
+ REGWRITE_BUFFER_FLUSH(ah);
+ DISABLE_REGWRITE_BUFFER(ah);
+
+}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index adbf031fbc5a..cd56c8692705 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -530,3 +530,38 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
ar9002_hw_set_nf_limits(ah);
}
+
+void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+ antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >>
+ AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S;
+ antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >>
+ AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
+ antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
+ AR_PHY_9285_FAST_DIV_BIAS_S;
+}
+EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
+
+void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf)
+{
+ u32 regval;
+
+ regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+ regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
+ AR_PHY_9285_ANT_DIV_ALT_LNACONF |
+ AR_PHY_9285_FAST_DIV_BIAS);
+ regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S)
+ & AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
+ regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S)
+ & AR_PHY_9285_ANT_DIV_ALT_LNACONF);
+ regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S)
+ & AR_PHY_9285_FAST_DIV_BIAS);
+
+ REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
+}
+EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index c5151a4dd10b..37663dbbcf57 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -302,6 +302,8 @@
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
+#define AR_PHY_9285_FAST_DIV_BIAS 0x00007E00
+#define AR_PHY_9285_FAST_DIV_BIAS_S 9
#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
#define AR_PHY_9285_ANT_DIV_CTL_S 24
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index b883b174385b..057fb69ddf7f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -797,7 +797,7 @@ static bool ar9300_uncompress_block(struct ath_hw *ah,
length = block[it+1];
length &= 0xff;
- if (length > 0 && spot >= 0 && spot+length < mdataSize) {
+ if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
ath_print(common, ATH_DBG_EEPROM,
"Restore at %d: spot=%d "
"offset=%d length=%d\n",
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 5b995bee70ae..3b424ca1ba84 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -185,7 +185,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
ath_print(common, ATH_DBG_INTERRUPT,
"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
- REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+ REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
}
@@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
} else if (rxsp->status11 & AR_MichaelErr) {
rxs->rs_status |= ATH9K_RXERR_MIC;
- }
+ } else if (rxsp->status11 & AR_KeyMiss)
+ rxs->rs_status |= ATH9K_RXERR_DECRYPT;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 07f26ee7a723..c8ff417f6c10 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -423,6 +423,7 @@ int ath_beaconq_config(struct ath_softc *sc);
#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
#define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */
#define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */
+#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */
#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
@@ -436,14 +437,6 @@ void ath_ani_calibrate(unsigned long data);
/* BTCOEX */
/**********/
-/* Defines the BT AR_BT_COEX_WGHT used */
-enum ath_stomp_type {
- ATH_BTCOEX_NO_STOMP,
- ATH_BTCOEX_STOMP_ALL,
- ATH_BTCOEX_STOMP_LOW,
- ATH_BTCOEX_STOMP_NONE
-};
-
struct ath_btcoex {
bool hw_timer_enabled;
spinlock_t btcoex_lock;
@@ -488,6 +481,60 @@ struct ath_led {
void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc);
+/* Antenna diversity/combining */
+#define ATH_ANT_RX_CURRENT_SHIFT 4
+#define ATH_ANT_RX_MAIN_SHIFT 2
+#define ATH_ANT_RX_MASK 0x3
+
+#define ATH_ANT_DIV_COMB_SHORT_SCAN_INTR 50
+#define ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT 0x100
+#define ATH_ANT_DIV_COMB_MAX_PKTCOUNT 0x200
+#define ATH_ANT_DIV_COMB_INIT_COUNT 95
+#define ATH_ANT_DIV_COMB_MAX_COUNT 100
+#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
+#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
+
+#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3
+#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
+#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
+#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
+#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2
+
+enum ath9k_ant_div_comb_lna_conf {
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
+ ATH_ANT_DIV_COMB_LNA2,
+ ATH_ANT_DIV_COMB_LNA1,
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2,
+};
+
+struct ath_ant_comb {
+ u16 count;
+ u16 total_pkt_count;
+ bool scan;
+ bool scan_not_start;
+ int main_total_rssi;
+ int alt_total_rssi;
+ int alt_recv_cnt;
+ int main_recv_cnt;
+ int rssi_lna1;
+ int rssi_lna2;
+ int rssi_add;
+ int rssi_sub;
+ int rssi_first;
+ int rssi_second;
+ int rssi_third;
+ bool alt_good;
+ int quick_scan_cnt;
+ int main_conf;
+ enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf;
+ enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf;
+ int first_bias;
+ int second_bias;
+ bool first_ratio;
+ bool second_ratio;
+ unsigned long scan_start_time;
+};
+
/********************/
/* Main driver core */
/********************/
@@ -604,6 +651,8 @@ struct ath_softc {
struct ath_btcoex btcoex;
struct ath_descdma txsdma;
+
+ struct ath_ant_comb ant_comb;
};
struct ath_wiphy {
@@ -670,7 +719,7 @@ static inline void ath_ahb_exit(void) {};
void ath9k_ps_wakeup(struct ath_softc *sc);
void ath9k_ps_restore(struct ath_softc *sc);
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int ath9k_wiphy_add(struct ath_softc *sc);
int ath9k_wiphy_del(struct ath_wiphy *aphy);
void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 4d4b22d52dfd..081192e78a46 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -359,11 +359,12 @@ void ath_beacon_tasklet(unsigned long data)
sc->beacon.bmisscnt++;
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"missed %u consecutive beacons\n",
sc->beacon.bmisscnt);
+ ath9k_hw_bstuck_nfcal(ah);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
ath_reset(sc, false);
@@ -373,7 +374,7 @@ void ath_beacon_tasklet(unsigned long data)
}
if (sc->beacon.bmisscnt != 0) {
- ath_print(common, ATH_DBG_BEACON,
+ ath_print(common, ATH_DBG_BSTUCK,
"resume beacon xmit after %u misses\n",
sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index fb4ac15f3b93..6a92e57fddf0 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -168,6 +168,7 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
{
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+ u32 val;
/*
* Program coex mode and weight registers to
@@ -177,6 +178,12 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
+ if (AR_SREV_9271(ah)) {
+ val = REG_READ(ah, 0x50040);
+ val &= 0xFFFFFEFF;
+ REG_WRITE(ah, 0x50040, val);
+ }
+
REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 45208690c0ec..67ee5d735cc1 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -19,8 +19,7 @@
/* Common calibration code */
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW -60
+#define ATH9K_NF_TOO_HIGH -60
static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
{
@@ -45,11 +44,39 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
return nfval;
}
-static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ath_nf_limits *limit;
+
+ if (!chan || IS_CHAN_2GHZ(chan))
+ limit = &ah->nf_2g;
+ else
+ limit = &ah->nf_5g;
+
+ return limit;
+}
+
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+}
+
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
+ struct ath9k_hw_cal_data *cal,
int16_t *nfarray)
{
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_nf_limits *limit;
+ struct ath9k_nfcal_hist *h;
+ bool high_nf_mid = false;
int i;
+ h = cal->nfCalHist;
+ limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
+
for (i = 0; i < NUM_NF_READINGS; i++) {
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
@@ -63,7 +90,39 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
h[i].privNF =
ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
}
+
+ if (!h[i].privNF)
+ continue;
+
+ if (h[i].privNF > limit->max) {
+ high_nf_mid = true;
+
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "NFmid[%d] (%d) > MAX (%d), %s\n",
+ i, h[i].privNF, limit->max,
+ (cal->nfcal_interference ?
+ "not corrected (due to interference)" :
+ "correcting to MAX"));
+
+ /*
+ * Normally we limit the average noise floor by the
+ * hardware specific maximum here. However if we have
+ * encountered stuck beacons because of interference,
+ * we bypass this limit here in order to better deal
+ * with our environment.
+ */
+ if (!cal->nfcal_interference)
+ h[i].privNF = limit->max;
+ }
}
+
+ /*
+ * If the noise floor seems normal for all chains, assume that
+ * there is no significant interference in the environment anymore.
+ * Re-enable the enforcement of the NF maximum again.
+ */
+ if (!high_nf_mid)
+ cal->nfcal_interference = false;
}
static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
@@ -104,19 +163,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
ah->cal_samples = 0;
}
-static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
- struct ath9k_channel *chan)
-{
- struct ath_nf_limits *limit;
-
- if (!chan || IS_CHAN_2GHZ(chan))
- limit = &ah->nf_2g;
- else
- limit = &ah->nf_5g;
-
- return limit->nominal;
-}
-
/* This is done for the currently configured channel */
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
@@ -277,10 +323,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
"NF calibrated [%s] [chain %d] is %d\n",
(i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
- if (nf[i] > limit->max) {
+ if (nf[i] > ATH9K_NF_TOO_HIGH) {
ath_print(common, ATH_DBG_CALIBRATE,
"NF[%d] (%d) > MAX (%d), correcting to MAX",
- i, nf[i], limit->max);
+ i, nf[i], ATH9K_NF_TOO_HIGH);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
ath_print(common, ATH_DBG_CALIBRATE,
@@ -326,7 +372,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
h = caldata->nfCalHist;
caldata->nfcal_pending = false;
- ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+ ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
caldata->rawNoiseFloor = h[0].privNF;
return true;
}
@@ -361,3 +407,28 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
return ah->caldata->rawNoiseFloor;
}
EXPORT_SYMBOL(ath9k_hw_getchan_noise);
+
+void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
+{
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+ if (unlikely(!caldata))
+ return;
+
+ /*
+ * If beacons are stuck, the most likely cause is interference.
+ * Triggering a noise floor calibration at this point helps the
+ * hardware adapt to a noisy environment much faster.
+ * To ensure that we recover from stuck beacons quickly, let
+ * the baseband update the internal NF value itself, similar to
+ * what is being done after a full reset.
+ */
+ if (!caldata->nfcal_pending)
+ ath9k_hw_start_nfcal(ah, true);
+ else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF))
+ ath9k_hw_getnf(ah, ah->curchan);
+
+ caldata->nfcal_interference = true;
+}
+EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal);
+
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 0a304b3eeeb6..5b053a6260b2 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -113,6 +113,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_channel *chan);
+void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index c86f7d3593ab..2dab64bb23a8 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -46,12 +46,17 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
+ switch (tx_info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
+ case WLAN_CIPHER_SUITE_TKIP:
return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
+ case WLAN_CIPHER_SUITE_CCMP:
return ATH9K_KEY_TYPE_AES;
+ default:
+ break;
+ }
}
return ATH9K_KEY_TYPE_CLEAR;
@@ -212,11 +217,11 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
}
static int ath_reserve_key_cache_slot(struct ath_common *common,
- enum ieee80211_key_alg alg)
+ u32 cipher)
{
int i;
- if (alg == ALG_TKIP)
+ if (cipher == WLAN_CIPHER_SUITE_TKIP)
return ath_reserve_key_cache_slot_tkip(common);
/* First, try to find slots that would not be available for TKIP. */
@@ -293,14 +298,15 @@ int ath9k_cmn_key_config(struct ath_common *common,
memset(&hk, 0, sizeof(hk));
- switch (key->alg) {
- case ALG_WEP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
hk.kv_type = ATH9K_CIPHER_WEP;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
hk.kv_type = ATH9K_CIPHER_TKIP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
hk.kv_type = ATH9K_CIPHER_AES_CCM;
break;
default:
@@ -316,7 +322,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
memcpy(gmac, vif->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
- idx = ath_reserve_key_cache_slot(common, key->alg);
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
break;
case NL80211_IFTYPE_ADHOC:
if (!sta) {
@@ -326,7 +332,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
memcpy(gmac, sta->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
- idx = ath_reserve_key_cache_slot(common, key->alg);
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
break;
default:
idx = key->keyidx;
@@ -348,13 +354,13 @@ int ath9k_cmn_key_config(struct ath_common *common,
return -EOPNOTSUPP;
mac = sta->addr;
- idx = ath_reserve_key_cache_slot(common, key->alg);
+ idx = ath_reserve_key_cache_slot(common, key->cipher);
}
if (idx < 0)
return -ENOSPC; /* no free key cache entries */
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
vif->type == NL80211_IFTYPE_AP);
else
@@ -364,11 +370,15 @@ int ath9k_cmn_key_config(struct ath_common *common,
return -EIO;
set_bit(idx, common->keymap);
- if (key->alg == ALG_TKIP) {
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
set_bit(idx + 64, common->keymap);
+ set_bit(idx, common->tkip_keymap);
+ set_bit(idx + 64, common->tkip_keymap);
if (common->splitmic) {
set_bit(idx + 32, common->keymap);
set_bit(idx + 64 + 32, common->keymap);
+ set_bit(idx + 32, common->tkip_keymap);
+ set_bit(idx + 64 + 32, common->tkip_keymap);
}
}
@@ -389,14 +399,21 @@ void ath9k_cmn_key_delete(struct ath_common *common,
return;
clear_bit(key->hw_key_idx, common->keymap);
- if (key->alg != ALG_TKIP)
+ if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
return;
clear_bit(key->hw_key_idx + 64, common->keymap);
+
+ clear_bit(key->hw_key_idx, common->tkip_keymap);
+ clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
+
if (common->splitmic) {
ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
clear_bit(key->hw_key_idx + 32, common->keymap);
clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
+
+ clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
+ clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
}
}
EXPORT_SYMBOL(ath9k_cmn_key_delete);
@@ -414,6 +431,37 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
}
EXPORT_SYMBOL(ath9k_cmn_count_streams);
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
+ enum ath_stomp_type stomp_type)
+{
+ struct ath_hw *ah = common->ah;
+
+ switch (stomp_type) {
+ case ATH_BTCOEX_STOMP_ALL:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_ALL_WLAN_WGHT);
+ break;
+ case ATH_BTCOEX_STOMP_LOW:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
+ break;
+ case ATH_BTCOEX_STOMP_NONE:
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_NONE_WLAN_WGHT);
+ break;
+ default:
+ ath_print(common, ATH_DBG_BTCOEX,
+ "Invalid Stomptype\n");
+ break;
+ }
+
+ ath9k_hw_btcoex_enable(ah);
+}
+EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
+
static int __init ath9k_cmn_init(void)
{
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 97809d39c73f..4aa4e7dbe4d2 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -52,6 +52,14 @@
#define ATH_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+ ATH_BTCOEX_NO_STOMP,
+ ATH_BTCOEX_STOMP_ALL,
+ ATH_BTCOEX_STOMP_LOW,
+ ATH_BTCOEX_STOMP_NONE
+};
+
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
@@ -65,3 +73,5 @@ int ath9k_cmn_key_config(struct ath_common *common,
void ath9k_cmn_key_delete(struct ath_common *common,
struct ieee80211_key_conf *key);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
+void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
+ enum ath_stomp_type stomp_type);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 54aae931424e..24765702a883 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -71,7 +71,8 @@ static const struct file_operations fops_debug = {
.read = read_file_debug,
.write = write_file_debug,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif
@@ -116,7 +117,8 @@ static const struct file_operations fops_tx_chainmask = {
.read = read_file_tx_chainmask,
.write = write_file_tx_chainmask,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -158,7 +160,8 @@ static const struct file_operations fops_rx_chainmask = {
.read = read_file_rx_chainmask,
.write = write_file_rx_chainmask,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -259,7 +262,8 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
static const struct file_operations fops_dma = {
.read = read_file_dma,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -375,7 +379,8 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
static const struct file_operations fops_interrupt = {
.read = read_file_interrupt,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
@@ -464,7 +469,8 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
static const struct file_operations fops_rcstat = {
.read = read_file_rcstat,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
@@ -623,7 +629,8 @@ static const struct file_operations fops_wiphy = {
.read = read_file_wiphy,
.write = write_file_wiphy,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#define PR(str, elem) \
@@ -702,7 +709,8 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
static const struct file_operations fops_xmit = {
.read = read_file_xmit,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t read_file_recv(struct file *file, char __user *user_buf,
@@ -814,7 +822,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
static const struct file_operations fops_recv = {
.read = read_file_recv,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
@@ -852,7 +861,8 @@ static const struct file_operations fops_regidx = {
.read = read_file_regidx,
.write = write_file_regidx,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t read_file_regval(struct file *file, char __user *user_buf,
@@ -894,7 +904,8 @@ static const struct file_operations fops_regval = {
.read = read_file_regval,
.write = write_file_regval,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
int ath9k_init_debug(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 7f48df1e2903..3216b703d01c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -62,7 +62,7 @@
#define SD_NO_CTL 0xE0
#define NO_CTL 0xff
-#define CTL_MODE_M 7
+#define CTL_MODE_M 0xf
#define CTL_11A 0
#define CTL_11B 1
#define CTL_11G 2
@@ -266,6 +266,8 @@ enum eeprom_param {
EEP_INTERNAL_REGULATOR,
EEP_SWREG,
EEP_PAPRD,
+ EEP_MODAL_VER,
+ EEP_ANT_DIV_CTL1,
};
enum ar5416_rates {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 9cccd12e8f21..2e1397b68a87 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -213,6 +213,10 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
return 0;
case EEP_PWR_TABLE_OFFSET:
return AR5416_PWR_TABLE_OFFSET_DB;
+ case EEP_MODAL_VER:
+ return pModal->version;
+ case EEP_ANT_DIV_CTL1:
+ return pModal->antdiv_ctl1;
default:
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 3a8ee999da5d..4a9a68bba324 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -251,36 +251,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
}
}
-/*
- * Configures appropriate weight based on stomp type.
- */
-static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
- enum ath_stomp_type stomp_type)
-{
- struct ath_hw *ah = sc->sc_ah;
-
- switch (stomp_type) {
- case ATH_BTCOEX_STOMP_ALL:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_ALL_WLAN_WGHT);
- break;
- case ATH_BTCOEX_STOMP_LOW:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_LOW_WLAN_WGHT);
- break;
- case ATH_BTCOEX_STOMP_NONE:
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_NONE_WLAN_WGHT);
- break;
- default:
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
- "Invalid Stomptype\n");
- break;
- }
-
- ath9k_hw_btcoex_enable(ah);
-}
-
static void ath9k_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
u32 timer_next,
@@ -319,6 +289,7 @@ static void ath_btcoex_period_timer(unsigned long data)
struct ath_softc *sc = (struct ath_softc *) data;
struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_common *common = ath9k_hw_common(ah);
u32 timer_period;
bool is_btscan;
@@ -328,7 +299,7 @@ static void ath_btcoex_period_timer(unsigned long data)
spin_lock_bh(&btcoex->btcoex_lock);
- ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
spin_unlock_bh(&btcoex->btcoex_lock);
@@ -359,17 +330,18 @@ static void ath_btcoex_no_stomp_timer(void *arg)
struct ath_softc *sc = (struct ath_softc *)arg;
struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_common *common = ath9k_hw_common(ah);
bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
- ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ ath_print(common, ATH_DBG_BTCOEX,
"no stomp timer running\n");
spin_lock_bh(&btcoex->btcoex_lock);
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
- ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
- ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
spin_unlock_bh(&btcoex->btcoex_lock);
}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 17e7a9a367e7..27f88a0a155b 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -92,10 +92,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
cmd->skb = skb;
cmd->hif_dev = hif_dev;
- usb_fill_int_urb(urb, hif_dev->udev,
- usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
+ usb_fill_bulk_urb(urb, hif_dev->udev,
+ usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE),
skb->data, skb->len,
- hif_usb_regout_cb, cmd, 1);
+ hif_usb_regout_cb, cmd);
usb_anchor_urb(urb, &hif_dev->regout_submitted);
ret = usb_submit_urb(urb, GFP_KERNEL);
@@ -822,7 +822,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
{
- int ret;
+ int ret, idx;
+ struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
+ struct usb_endpoint_descriptor *endp;
/* Request firmware */
ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
@@ -850,6 +852,22 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
goto err_fw_download;
}
+ /* On downloading the firmware to the target, the USB descriptor of EP4
+ * is 'patched' to change the type of the endpoint to Bulk. This will
+ * bring down CPU usage during the scan period.
+ */
+ for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) {
+ endp = &alt->endpoint[idx].desc;
+ if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+ == 0x04) &&
+ ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT)) {
+ endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK;
+ endp->bmAttributes |= USB_ENDPOINT_XFER_BULK;
+ endp->bInterval = 0;
+ }
+ }
+
return 0;
err_fw_download:
@@ -920,7 +938,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
}
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
- &hif_dev->udev->dev, hif_dev->device_id);
+ &hif_dev->udev->dev, hif_dev->device_id,
+ hif_dev->udev->product);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 43b9e21bc562..75ecf6a30d25 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -316,17 +316,32 @@ struct htc_beacon_config {
u8 dtim_count;
};
-#define OP_INVALID BIT(0)
-#define OP_SCANNING BIT(1)
-#define OP_FULL_RESET BIT(2)
-#define OP_LED_ASSOCIATED BIT(3)
-#define OP_LED_ON BIT(4)
-#define OP_PREAMBLE_SHORT BIT(5)
-#define OP_PROTECT_ENABLE BIT(6)
-#define OP_ASSOCIATED BIT(7)
-#define OP_ENABLE_BEACON BIT(8)
-#define OP_LED_DEINIT BIT(9)
-#define OP_UNPLUGGED BIT(10)
+struct ath_btcoex {
+ u32 bt_priority_cnt;
+ unsigned long bt_priority_time;
+ int bt_stomp_type; /* Types of BT stomping */
+ u32 btcoex_no_stomp;
+ u32 btcoex_period;
+ u32 btscan_no_stomp;
+};
+
+void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv);
+void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv);
+void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
+
+#define OP_INVALID BIT(0)
+#define OP_SCANNING BIT(1)
+#define OP_FULL_RESET BIT(2)
+#define OP_LED_ASSOCIATED BIT(3)
+#define OP_LED_ON BIT(4)
+#define OP_PREAMBLE_SHORT BIT(5)
+#define OP_PROTECT_ENABLE BIT(6)
+#define OP_ASSOCIATED BIT(7)
+#define OP_ENABLE_BEACON BIT(8)
+#define OP_LED_DEINIT BIT(9)
+#define OP_UNPLUGGED BIT(10)
+#define OP_BT_PRIORITY_DETECTED BIT(11)
+#define OP_BT_SCAN BIT(12)
struct ath9k_htc_priv {
struct device *dev;
@@ -391,6 +406,9 @@ struct ath9k_htc_priv {
int cabq;
int hwq_map[WME_NUM_AC];
+ struct ath_btcoex btcoex;
+ struct delayed_work coex_period_work;
+ struct delayed_work duty_cycle_work;
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
struct ath9k_debug debug;
#endif
@@ -443,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid);
+ u16 devid, char *product);
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
#ifdef CONFIG_PM
int ath9k_htc_resume(struct htc_target *htc_handle);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
new file mode 100644
index 000000000000..50eec9a3b88c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -0,0 +1,134 @@
+#include "htc.h"
+
+/******************/
+/* BTCOEX */
+/******************/
+
+/*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_hw *ah = priv->ah;
+
+ if (ath9k_hw_gpio_get(ah, ah->btcoex_hw.btpriority_gpio))
+ btcoex->bt_priority_cnt++;
+
+ if (time_after(jiffies, btcoex->bt_priority_time +
+ msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+ priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
+ /* Detect if colocated bt started scanning */
+ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT scan detected");
+ priv->op_flags |= (OP_BT_SCAN |
+ OP_BT_PRIORITY_DETECTED);
+ } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "BT priority traffic detected");
+ priv->op_flags |= OP_BT_PRIORITY_DETECTED;
+ }
+
+ btcoex->bt_priority_cnt = 0;
+ btcoex->bt_priority_time = jiffies;
+ }
+}
+
+/*
+ * This is the master bt coex work which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+static void ath_btcoex_period_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ coex_period_work.work);
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ u32 timer_period;
+ bool is_btscan;
+ int ret;
+ u8 cmd_rsp, aggr;
+
+ ath_detect_bt_priority(priv);
+
+ is_btscan = !!(priv->op_flags & OP_BT_SCAN);
+
+ aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
+
+ WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
+
+ ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+ btcoex->bt_stomp_type);
+
+ timer_period = is_btscan ? btcoex->btscan_no_stomp :
+ btcoex->btcoex_no_stomp;
+ ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work,
+ msecs_to_jiffies(timer_period));
+ ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work,
+ msecs_to_jiffies(btcoex->btcoex_period));
+}
+
+/*
+ * Work to time slice between wlan and bt traffic and
+ * configure weight registers
+ */
+static void ath_btcoex_duty_cycle_work(struct work_struct *work)
+{
+ struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
+ duty_cycle_work.work);
+ struct ath_hw *ah = priv->ah;
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_common *common = ath9k_hw_common(ah);
+ bool is_btscan = priv->op_flags & OP_BT_SCAN;
+
+ ath_print(common, ATH_DBG_BTCOEX,
+ "time slice work for bt and wlan\n");
+
+ if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+ else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+ ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+}
+
+void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+
+ btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
+ btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+ btcoex->btcoex_period / 100;
+ btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
+ btcoex->btcoex_period / 100;
+ INIT_DELAYED_WORK(&priv->coex_period_work, ath_btcoex_period_work);
+ INIT_DELAYED_WORK(&priv->duty_cycle_work, ath_btcoex_duty_cycle_work);
+}
+
+/*
+ * (Re)start btcoex work
+ */
+
+void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ struct ath_btcoex *btcoex = &priv->btcoex;
+ struct ath_hw *ah = priv->ah;
+
+ ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+ "Starting btcoex work");
+
+ btcoex->bt_priority_cnt = 0;
+ btcoex->bt_priority_time = jiffies;
+ priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
+ ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0);
+}
+
+
+/*
+ * Cancel btcoex and bt duty cycle work.
+ */
+void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
+{
+ cancel_delayed_work_sync(&priv->coex_period_work);
+ cancel_delayed_work_sync(&priv->duty_cycle_work);
+}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 2d4279191d7a..717f2b821f0d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -41,6 +41,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
.max_power = 20, \
}
+#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
+
static struct ieee80211_channel ath9k_2ghz_channels[] = {
CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */
@@ -599,13 +601,36 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
common->tx_chainmask = priv->ah->caps.tx_chainmask;
common->rx_chainmask = priv->ah->caps.rx_chainmask;
- if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
priv->ah->opmode = NL80211_IFTYPE_STATION;
}
-static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
+static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
+{
+ int qnum;
+
+ switch (priv->ah->btcoex_hw.scheme) {
+ case ATH_BTCOEX_CFG_NONE:
+ break;
+ case ATH_BTCOEX_CFG_3WIRE:
+ priv->ah->btcoex_hw.btactive_gpio = 7;
+ priv->ah->btcoex_hw.btpriority_gpio = 6;
+ priv->ah->btcoex_hw.wlanactive_gpio = 8;
+ priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+ ath9k_hw_btcoex_init_3wire(priv->ah);
+ ath_htc_init_btcoex_work(priv);
+ qnum = priv->hwq_map[WME_AC_BE];
+ ath9k_hw_init_btcoex_hw(priv->ah, qnum);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static int ath9k_init_priv(struct ath9k_htc_priv *priv,
+ u16 devid, char *product)
{
struct ath_hw *ah = NULL;
struct ath_common *common;
@@ -672,6 +697,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
ath9k_init_channels_rates(priv);
ath9k_init_misc(priv);
+ if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
+ ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
+ ath9k_init_btcoex(priv);
+ }
+
return 0;
err_queues:
@@ -734,7 +764,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
}
-static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
+static int ath9k_init_device(struct ath9k_htc_priv *priv,
+ u16 devid, char *product)
{
struct ieee80211_hw *hw = priv->hw;
struct ath_common *common;
@@ -743,7 +774,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
struct ath_regulatory *reg;
/* Bring up device */
- error = ath9k_init_priv(priv, devid);
+ error = ath9k_init_priv(priv, devid, product);
if (error != 0)
goto err_init;
@@ -801,7 +832,7 @@ err_init:
}
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
- u16 devid)
+ u16 devid, char *product)
{
struct ieee80211_hw *hw;
struct ath9k_htc_priv *priv;
@@ -835,7 +866,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
/* The device may have been unplugged earlier. */
priv->op_flags &= ~OP_UNPLUGGED;
- ret = ath9k_init_device(priv, devid);
+ ret = ath9k_init_device(priv, devid, product);
if (ret)
goto err_init;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 7d09b4b17bbd..0ed5b003c594 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -137,8 +137,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
if (priv->op_flags & OP_FULL_RESET)
fastcc = false;
- /* Fiddle around with fastcc later on, for now just use full reset */
- fastcc = false;
ath9k_htc_ps_wakeup(priv);
htc_stop(priv->htc);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -146,9 +144,10 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
WMI_CMD(WMI_STOP_RECV_CMDID);
ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
+ "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
priv->ah->curchan->channel,
- channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
+ channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
+ fastcc);
caldata = &priv->caldata[channel->hw_value];
ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
@@ -536,7 +535,8 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
static const struct file_operations fops_tgt_stats = {
.read = read_file_tgt_stats,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -584,7 +584,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
static const struct file_operations fops_xmit = {
.read = read_file_xmit,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t read_file_recv(struct file *file, char __user *user_buf,
@@ -613,7 +614,8 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
static const struct file_operations fops_recv = {
.read = read_file_recv,
.open = ath9k_debugfs_open,
- .owner = THIS_MODULE
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,/* read accesses f_pos */
};
int ath9k_htc_init_debug(struct ath_hw *ah)
@@ -1210,6 +1212,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(hw);
+ if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
+ ath9k_hw_btcoex_enable(ah);
+ ath_htc_resume_btcoex_work(priv);
+ }
mutex_unlock(&priv->mutex);
return ret;
@@ -1233,7 +1241,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Cancel all the running timers/work .. */
cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_ani_work);
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
ath9k_led_stop_brightness(priv);
@@ -1254,6 +1261,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
"Monitor interface removed\n");
}
+ if (ah->btcoex_hw.enabled) {
+ ath9k_hw_btcoex_disable(ah);
+ if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+ ath_htc_cancel_btcoex_work(priv);
+ }
+
ath9k_hw_phy_disable(ah);
ath9k_hw_disable(ah);
ath9k_hw_configpcipowersave(ah, 1, 1);
@@ -1585,9 +1598,10 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ if (priv->ah->sw_mgmt_crypto &&
+ key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
@@ -1774,7 +1788,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
priv->op_flags |= OP_SCANNING;
spin_unlock_bh(&priv->beacon_lock);
cancel_work_sync(&priv->ps_work);
- cancel_delayed_work_sync(&priv->ath9k_ani_work);
+ if (priv->op_flags & OP_ASSOCIATED)
+ cancel_delayed_work_sync(&priv->ath9k_ani_work);
mutex_unlock(&priv->mutex);
}
@@ -1788,9 +1803,10 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
priv->op_flags &= ~OP_SCANNING;
spin_unlock_bh(&priv->beacon_lock);
priv->op_flags |= OP_FULL_RESET;
- if (priv->op_flags & OP_ASSOCIATED)
+ if (priv->op_flags & OP_ASSOCIATED) {
ath9k_htc_beacon_config(priv, priv->vif);
- ath_start_ani(priv);
+ ath_start_ani(priv);
+ }
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 2a6e45a293a9..c99600aff76d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -415,8 +415,7 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath_hw_setbssidmask(common);
+ ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 705c0f342e1c..861ec9269309 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -462,9 +462,9 @@ void ath9k_htc_hw_free(struct htc_target *htc)
}
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid)
+ struct device *dev, u16 devid, char *product)
{
- if (ath9k_htc_probe_device(target, dev, devid)) {
+ if (ath9k_htc_probe_device(target, dev, devid, product)) {
printk(KERN_ERR "Failed to initialize the device\n");
return -ENODEV;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index faba6790328b..07b6509d5896 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -239,7 +239,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct device *dev);
void ath9k_htc_hw_free(struct htc_target *htc);
int ath9k_htc_hw_init(struct htc_target *target,
- struct device *dev, u16 devid);
+ struct device *dev, u16 devid, char *product);
void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 3384ca164562..40c6451602d3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1258,11 +1258,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
(chan->channel != ah->curchan->channel) &&
((chan->channelFlags & CHANNEL_ALL) ==
(ah->curchan->channelFlags & CHANNEL_ALL)) &&
- !AR_SREV_9280(ah)) {
+ (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) {
if (ath9k_hw_channel_change(ah, chan)) {
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah, true);
+ if (AR_SREV_9271(ah))
+ ar9002_hw_load_ani_reg(ah, chan);
return 0;
}
}
@@ -1572,12 +1574,6 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
keyType = AR_KEYTABLE_TYPE_AES;
break;
case ATH9K_CIPHER_AES_CCM:
- if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
- ath_print(common, ATH_DBG_ANY,
- "AES-CCM not supported by mac rev 0x%x\n",
- ah->hw_version.macRev);
- return false;
- }
keyType = AR_KEYTABLE_TYPE_CCM;
break;
case ATH9K_CIPHER_TKIP:
@@ -2056,6 +2052,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval;
+ u8 ant_div_ctl1;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
regulatory->current_rd = eeval;
@@ -2140,24 +2137,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->low_5ghz_chan = 4920;
pCap->high_5ghz_chan = 6100;
- pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
-
- pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
- pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
-
if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
- pCap->hw_caps |= ATH9K_HW_CAP_GTT;
- pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
- pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
- pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
-
if (capField & AR_EEPROM_EEPCAP_MAXQCU)
pCap->total_queues =
MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
@@ -2170,8 +2154,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->keycache_size = AR_KEYTABLE_SIZE;
- pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
else
@@ -2280,6 +2262,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah))
pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
+ if (AR_SREV_9285(ah))
+ if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) {
+ ant_div_ctl1 =
+ ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+ if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1))
+ pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+ }
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 399f7c1283cd..a3c2ce235123 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -181,29 +181,19 @@ enum wireless_mode {
};
enum ath9k_hw_caps {
- ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
- ATH9K_HW_CAP_MIC_CKIP = BIT(1),
- ATH9K_HW_CAP_MIC_TKIP = BIT(2),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(4),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(5),
- ATH9K_HW_CAP_VEOL = BIT(6),
- ATH9K_HW_CAP_BSSIDMASK = BIT(7),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8),
- ATH9K_HW_CAP_HT = BIT(9),
- ATH9K_HW_CAP_GTT = BIT(10),
- ATH9K_HW_CAP_FASTCC = BIT(11),
- ATH9K_HW_CAP_RFSILENT = BIT(12),
- ATH9K_HW_CAP_CST = BIT(13),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
- ATH9K_HW_CAP_EDMA = BIT(17),
- ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
- ATH9K_HW_CAP_LDPC = BIT(19),
- ATH9K_HW_CAP_FASTCLOCK = BIT(20),
- ATH9K_HW_CAP_SGI_20 = BIT(21),
- ATH9K_HW_CAP_PAPRD = BIT(22),
+ ATH9K_HW_CAP_HT = BIT(0),
+ ATH9K_HW_CAP_RFSILENT = BIT(1),
+ ATH9K_HW_CAP_CST = BIT(2),
+ ATH9K_HW_CAP_ENHANCEDPM = BIT(3),
+ ATH9K_HW_CAP_AUTOSLEEP = BIT(4),
+ ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5),
+ ATH9K_HW_CAP_EDMA = BIT(6),
+ ATH9K_HW_CAP_RAC_SUPPORTED = BIT(7),
+ ATH9K_HW_CAP_LDPC = BIT(8),
+ ATH9K_HW_CAP_FASTCLOCK = BIT(9),
+ ATH9K_HW_CAP_SGI_20 = BIT(10),
+ ATH9K_HW_CAP_PAPRD = BIT(11),
+ ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
};
struct ath9k_hw_capabilities {
@@ -355,6 +345,7 @@ struct ath9k_hw_cal_data {
int16_t rawNoiseFloor;
bool paprd_done;
bool nfcal_pending;
+ bool nfcal_interference;
u16 small_signal_gain[AR9300_MAX_CHAINS];
u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
@@ -494,6 +485,12 @@ struct ath_gen_timer_table {
} timer_mask;
};
+struct ath_hw_antcomb_conf {
+ u8 main_lna_conf;
+ u8 alt_lna_conf;
+ u8 fast_div_bias;
+};
+
/**
* struct ath_hw_private_ops - callbacks used internally by hardware code
*
@@ -887,6 +884,10 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
+void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+ struct ath_hw_antcomb_conf *antconf);
/* General Operation */
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
@@ -984,6 +985,7 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
void ar9002_hw_attach_ops(struct ath_hw *ah);
void ar9003_hw_attach_ops(struct ath_hw *ah);
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
/*
* ANI work can be shared between all families but a next
* generation implementation of ANI will be used only for AR9003 only
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 243c1775f343..5c77a9913e03 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -33,7 +33,7 @@ int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-int led_blink = 1;
+int led_blink;
module_param_named(blink, led_blink, int, 0444);
MODULE_PARM_DESC(blink, "Enable LED blink on activity");
@@ -522,8 +522,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
ath9k_hw_set_diversity(sc->sc_ah, true);
sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
sc->beacon.slottime = ATH9K_SLOT_TIME_9;
@@ -531,6 +530,9 @@ static void ath9k_init_misc(struct ath_softc *sc)
sc->beacon.bslot[i] = NULL;
sc->beacon.bslot_aphy[i] = NULL;
}
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
+ sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
}
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e955bb9d98cb..3efda8a8a3c1 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -711,8 +711,11 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_phyerr = phyerr;
} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if (ads.ds_rxstatus8 & AR_MichaelErr)
+ else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
+ rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
rs->rs_status |= ATH9K_RXERR_MIC;
+ else if (ads.ds_rxstatus8 & AR_KeyMiss)
+ rs->rs_status |= ATH9K_RXERR_DECRYPT;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3caa32316e7b..a2f7eb2a552b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -226,9 +226,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
caldata = &aphy->caldata;
ath_print(common, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
+ "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
sc->sc_ah->curchan->channel,
- channel->center_freq, conf_is_ht40(conf));
+ channel->center_freq, conf_is_ht40(conf),
+ fastcc);
spin_lock_bh(&sc->sc_resetlock);
@@ -395,7 +396,12 @@ void ath_ani_calibrate(unsigned long data)
bool shortcal = false;
bool aniflag = false;
unsigned int timestamp = jiffies_to_msecs(jiffies);
- u32 cal_interval, short_cal_interval;
+ u32 cal_interval, short_cal_interval, long_cal_interval;
+
+ if (ah->caldata && ah->caldata->nfcal_interference)
+ long_cal_interval = ATH_LONG_CALINTERVAL_INT;
+ else
+ long_cal_interval = ATH_LONG_CALINTERVAL;
short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
@@ -407,7 +413,7 @@ void ath_ani_calibrate(unsigned long data)
ath9k_ps_wakeup(sc);
/* Long calibration runs independently of short calibration. */
- if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+ if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
longcal = true;
ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
common->ani.longcal_timer = timestamp;
@@ -1150,8 +1156,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
else
ah->imask |= ATH9K_INT_RX;
- if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
- ah->imask |= ATH9K_INT_GTT;
+ ah->imask |= ATH9K_INT_GTT;
if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ah->imask |= ATH9K_INT_CST;
@@ -1373,12 +1378,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
- if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
- sc->nvifs > 0) {
- ret = -ENOBUFS;
- goto out;
- }
-
switch (vif->type) {
case NL80211_IFTYPE_STATION:
ic_opmode = NL80211_IFTYPE_STATION;
@@ -1408,8 +1407,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
sc->nvifs++;
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath9k_set_bssid_mask(hw);
+ ath9k_set_bssid_mask(hw, vif);
if (sc->nvifs > 1)
goto out; /* skip global settings for secondary vif */
@@ -1776,9 +1774,10 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ if (sc->sc_ah->sw_mgmt_crypto &&
+ key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index a3fc987ebab0..6fb3b4536045 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -19,6 +19,15 @@
#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))
+static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
+ int mindelta, int main_rssi_avg,
+ int alt_rssi_avg, int pkt_count)
+{
+ return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg + maxdelta)) ||
+ (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
+}
+
static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
{
return sc->ps_enabled &&
@@ -110,8 +119,7 @@ static void ath_opmode_init(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath_hw_setbssidmask(common);
+ ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
@@ -870,15 +878,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
*decrypt_error = true;
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
- if (ieee80211_is_ctl(fc))
- /*
- * Sometimes, we get invalid
- * MIC failures on valid control frames.
- * Remove these mic errors.
- */
- rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
- else
+ /*
+ * The MIC error bit is only valid if the frame
+ * is not a control frame or fragment, and it was
+ * decrypted using a valid TKIP key.
+ */
+ if (!ieee80211_is_ctl(fc) &&
+ !ieee80211_has_morefrags(fc) &&
+ !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
+ test_bit(rx_stats->rs_keyix, common->tkip_keymap))
rxs->flag |= RX_FLAG_MMIC_ERROR;
+ else
+ rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
}
/*
* Reject error frames with the exception of
@@ -1073,6 +1084,539 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
rxs->flag &= ~RX_FLAG_DECRYPTED;
}
+static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb,
+ struct ath_hw_antcomb_conf ant_conf,
+ int main_rssi_avg)
+{
+ antcomb->quick_scan_cnt = 0;
+
+ if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = main_rssi_avg;
+ else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = main_rssi_avg;
+
+ switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) {
+ case (0x10): /* LNA2 A-B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
+ break;
+ case (0x20): /* LNA1 A-B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case (0x13): /* LNA2 A+B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
+ break;
+ case (0x23): /* LNA1 A+B */
+ antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ antcomb->first_quick_scan_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
+ break;
+ default:
+ break;
+ }
+}
+
+static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
+ struct ath_hw_antcomb_conf *div_ant_conf,
+ int main_rssi_avg, int alt_rssi_avg,
+ int alt_ratio)
+{
+ /* alt_good */
+ switch (antcomb->quick_scan_cnt) {
+ case 0:
+ /* set alt to main, and alt to first conf */
+ div_ant_conf->main_lna_conf = antcomb->main_conf;
+ div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
+ break;
+ case 1:
+ /* set alt to main, and alt to first conf */
+ div_ant_conf->main_lna_conf = antcomb->main_conf;
+ div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
+ antcomb->rssi_first = main_rssi_avg;
+ antcomb->rssi_second = alt_rssi_avg;
+
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
+ /* main is LNA1 */
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ } else {
+ if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
+ (alt_rssi_avg > main_rssi_avg)) &&
+ (antcomb->total_pkt_count > 50))
+ antcomb->first_ratio = true;
+ else
+ antcomb->first_ratio = false;
+ }
+ break;
+ case 2:
+ antcomb->alt_good = false;
+ antcomb->scan_not_start = false;
+ antcomb->scan = false;
+ antcomb->rssi_first = main_rssi_avg;
+ antcomb->rssi_third = alt_rssi_avg;
+
+ if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = alt_rssi_avg;
+ else if (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = alt_rssi_avg;
+ else if (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) {
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)
+ antcomb->rssi_lna2 = main_rssi_avg;
+ else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1)
+ antcomb->rssi_lna1 = main_rssi_avg;
+ }
+
+ if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)
+ div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
+ else
+ div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
+
+ if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
+ if (ath_is_alt_ant_ratio_better(alt_ratio,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
+ ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
+ main_rssi_avg, alt_rssi_avg,
+ antcomb->total_pkt_count))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ } else {
+ if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
+ (alt_rssi_avg > main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
+ (alt_rssi_avg > main_rssi_avg)) &&
+ (antcomb->total_pkt_count > 50))
+ antcomb->second_ratio = true;
+ else
+ antcomb->second_ratio = false;
+ }
+
+ /* set alt to the conf with maximun ratio */
+ if (antcomb->first_ratio && antcomb->second_ratio) {
+ if (antcomb->rssi_second > antcomb->rssi_third) {
+ /* first alt*/
+ if ((antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2*/
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->first_quick_scan_conf;
+ } else if ((antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2)) {
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ } else {
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->second_quick_scan_conf;
+ }
+ } else if (antcomb->first_ratio) {
+ /* first alt */
+ if ((antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->first_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->first_quick_scan_conf;
+ } else if (antcomb->second_ratio) {
+ /* second alt */
+ if ((antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->second_quick_scan_conf ==
+ ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf =
+ antcomb->second_quick_scan_conf;
+ } else {
+ /* main is largest */
+ if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
+ (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
+ /* Set alt LNA1 or LNA2 */
+ if (div_ant_conf->main_lna_conf ==
+ ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else
+ div_ant_conf->alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ else
+ /* Set alt to A+B or A-B */
+ div_ant_conf->alt_lna_conf = antcomb->main_conf;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
+{
+ /* Adjust the fast_div_bias based on main and alt lna conf */
+ switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
+ case (0x01): /* A-B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x02): /* A-B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ case (0x03): /* A-B A+B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x10): /* LNA2 A-B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x12): /* LNA2 LNA1 */
+ ant_conf->fast_div_bias = 0x2;
+ break;
+ case (0x13): /* LNA2 A+B */
+ ant_conf->fast_div_bias = 0x7;
+ break;
+ case (0x20): /* LNA1 A-B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x21): /* LNA1 LNA2 */
+ ant_conf->fast_div_bias = 0x0;
+ break;
+ case (0x23): /* LNA1 A+B */
+ ant_conf->fast_div_bias = 0x6;
+ break;
+ case (0x30): /* A+B A-B */
+ ant_conf->fast_div_bias = 0x1;
+ break;
+ case (0x31): /* A+B LNA2 */
+ ant_conf->fast_div_bias = 0x3b;
+ break;
+ case (0x32): /* A+B LNA1 */
+ ant_conf->fast_div_bias = 0x3d;
+ break;
+ default:
+ break;
+ }
+}
+
+/* Antenna diversity and combining */
+static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
+{
+ struct ath_hw_antcomb_conf div_ant_conf;
+ struct ath_ant_comb *antcomb = &sc->ant_comb;
+ int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
+ int curr_main_set, curr_bias;
+ int main_rssi = rs->rs_rssi_ctl0;
+ int alt_rssi = rs->rs_rssi_ctl1;
+ int rx_ant_conf, main_ant_conf;
+ bool short_scan = false;
+
+ rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
+ ATH_ANT_RX_MASK;
+ main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
+ ATH_ANT_RX_MASK;
+
+ /* Record packet only when alt_rssi is positive */
+ if (alt_rssi > 0) {
+ antcomb->total_pkt_count++;
+ antcomb->main_total_rssi += main_rssi;
+ antcomb->alt_total_rssi += alt_rssi;
+ if (main_ant_conf == rx_ant_conf)
+ antcomb->main_recv_cnt++;
+ else
+ antcomb->alt_recv_cnt++;
+ }
+
+ /* Short scan check */
+ if (antcomb->scan && antcomb->alt_good) {
+ if (time_after(jiffies, antcomb->scan_start_time +
+ msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
+ short_scan = true;
+ else
+ if (antcomb->total_pkt_count ==
+ ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
+ alt_ratio = ((antcomb->alt_recv_cnt * 100) /
+ antcomb->total_pkt_count);
+ if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
+ short_scan = true;
+ }
+ }
+
+ if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
+ rs->rs_moreaggr) && !short_scan)
+ return;
+
+ if (antcomb->total_pkt_count) {
+ alt_ratio = ((antcomb->alt_recv_cnt * 100) /
+ antcomb->total_pkt_count);
+ main_rssi_avg = (antcomb->main_total_rssi /
+ antcomb->total_pkt_count);
+ alt_rssi_avg = (antcomb->alt_total_rssi /
+ antcomb->total_pkt_count);
+ }
+
+
+ ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
+ curr_alt_set = div_ant_conf.alt_lna_conf;
+ curr_main_set = div_ant_conf.main_lna_conf;
+ curr_bias = div_ant_conf.fast_div_bias;
+
+ antcomb->count++;
+
+ if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
+ main_rssi_avg);
+ antcomb->alt_good = true;
+ } else {
+ antcomb->alt_good = false;
+ }
+
+ antcomb->count = 0;
+ antcomb->scan = true;
+ antcomb->scan_not_start = true;
+ }
+
+ if (!antcomb->scan) {
+ if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+ if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
+ /* Switch main and alt LNA */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+
+ goto div_comb_done;
+ } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) &&
+ (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) {
+ /* Set alt to another LNA */
+ if (curr_main_set == ATH_ANT_DIV_COMB_LNA2)
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1)
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+
+ goto div_comb_done;
+ }
+
+ if ((alt_rssi_avg < (main_rssi_avg +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
+ goto div_comb_done;
+ }
+
+ if (!antcomb->scan_not_start) {
+ switch (curr_alt_set) {
+ case ATH_ANT_DIV_COMB_LNA2:
+ antcomb->rssi_lna2 = alt_rssi_avg;
+ antcomb->rssi_lna1 = main_rssi_avg;
+ antcomb->scan = true;
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1:
+ antcomb->rssi_lna1 = alt_rssi_avg;
+ antcomb->rssi_lna2 = main_rssi_avg;
+ antcomb->scan = true;
+ /* set to A+B */
+ div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
+ antcomb->rssi_add = alt_rssi_avg;
+ antcomb->scan = true;
+ /* set to A-B */
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ break;
+ case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2:
+ antcomb->rssi_sub = alt_rssi_avg;
+ antcomb->scan = false;
+ if (antcomb->rssi_lna2 >
+ (antcomb->rssi_lna1 +
+ ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
+ /* use LNA2 as main LNA */
+ if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
+ (antcomb->rssi_add > antcomb->rssi_sub)) {
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ } else if (antcomb->rssi_sub >
+ antcomb->rssi_lna1) {
+ /* set to A-B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ } else {
+ /* set to LNA1 */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ }
+ } else {
+ /* use LNA1 as main LNA */
+ if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
+ (antcomb->rssi_add > antcomb->rssi_sub)) {
+ /* set to A+B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
+ } else if (antcomb->rssi_sub >
+ antcomb->rssi_lna1) {
+ /* set to A-B */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
+ } else {
+ /* set to LNA2 */
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ if (!antcomb->alt_good) {
+ antcomb->scan_not_start = false;
+ /* Set alt to another LNA */
+ if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) {
+ div_ant_conf.main_lna_conf =
+ ATH_ANT_DIV_COMB_LNA1;
+ div_ant_conf.alt_lna_conf =
+ ATH_ANT_DIV_COMB_LNA2;
+ }
+ goto div_comb_done;
+ }
+ }
+
+ ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
+ main_rssi_avg, alt_rssi_avg,
+ alt_ratio);
+
+ antcomb->quick_scan_cnt++;
+
+div_comb_done:
+ ath_ant_div_conf_fast_divbias(&div_ant_conf);
+
+ ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
+
+ antcomb->scan_start_time = jiffies;
+ antcomb->total_pkt_count = 0;
+ antcomb->main_total_rssi = 0;
+ antcomb->alt_total_rssi = 0;
+ antcomb->main_recv_cnt = 0;
+ antcomb->alt_recv_cnt = 0;
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_buf *bf;
@@ -1210,6 +1754,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
PS_WAIT_FOR_PSPOLL_DATA))))
ath_rx_ps(sc, skb);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
+ ath_ant_comb_scan(sc, &rs);
+
ath_rx_send_to_mac80211(hw, sc, skb, rxs);
requeue:
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index fd20241f57d8..ec7cf5ee56bc 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -19,45 +19,36 @@
#include "ath9k.h"
struct ath9k_vif_iter_data {
- int count;
- u8 *addr;
+ const u8 *hw_macaddr;
+ u8 mask[ETH_ALEN];
};
static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
struct ath9k_vif_iter_data *iter_data = data;
- u8 *nbuf;
-
- nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
- GFP_ATOMIC);
- if (nbuf == NULL)
- return;
+ int i;
- memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
- iter_data->addr = nbuf;
- iter_data->count++;
+ for (i = 0; i < ETH_ALEN; i++)
+ iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
}
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_vif_iter_data iter_data;
- int i, j;
- u8 mask[ETH_ALEN];
+ int i;
/*
- * Add primary MAC address even if it is not in active use since it
- * will be configured to the hardware as the starting point and the
- * BSSID mask will need to be changed if another address is active.
+ * Use the hardware MAC address as reference, the hardware uses it
+ * together with the BSSID mask when matching addresses.
*/
- iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
- if (iter_data.addr) {
- memcpy(iter_data.addr, common->macaddr, ETH_ALEN);
- iter_data.count = 1;
- } else
- iter_data.count = 0;
+ iter_data.hw_macaddr = common->macaddr;
+ memset(&iter_data.mask, 0xff, ETH_ALEN);
+
+ if (vif)
+ ath9k_vif_iter(&iter_data, vif->addr, vif);
/* Get list of all active MAC addresses */
spin_lock_bh(&sc->wiphy_lock);
@@ -71,31 +62,7 @@ void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
}
spin_unlock_bh(&sc->wiphy_lock);
- /* Generate an address mask to cover all active addresses */
- memset(mask, 0, ETH_ALEN);
- for (i = 0; i < iter_data.count; i++) {
- u8 *a1 = iter_data.addr + i * ETH_ALEN;
- for (j = i + 1; j < iter_data.count; j++) {
- u8 *a2 = iter_data.addr + j * ETH_ALEN;
- mask[0] |= a1[0] ^ a2[0];
- mask[1] |= a1[1] ^ a2[1];
- mask[2] |= a1[2] ^ a2[2];
- mask[3] |= a1[3] ^ a2[3];
- mask[4] |= a1[4] ^ a2[4];
- mask[5] |= a1[5] ^ a2[5];
- }
- }
-
- kfree(iter_data.addr);
-
- /* Invert the mask and configure hardware */
- common->bssidmask[0] = ~mask[0];
- common->bssidmask[1] = ~mask[1];
- common->bssidmask[2] = ~mask[2];
- common->bssidmask[3] = ~mask[3];
- common->bssidmask[4] = ~mask[4];
- common->bssidmask[5] = ~mask[5];
-
+ memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
ath_hw_setbssidmask(common);
}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 6260faa658a2..93a8bda09c25 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -85,6 +85,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_TGT_DETACH_CMDID";
case WMI_TGT_TXQ_ENABLE_CMDID:
return "WMI_TGT_TXQ_ENABLE_CMDID";
+ case WMI_AGGR_LIMIT_CMD:
+ return "WMI_AGGR_LIMIT_CMD";
}
return "Bogus";
@@ -122,55 +124,11 @@ void ath9k_wmi_tasklet(unsigned long data)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ath_common *common = ath9k_hw_common(priv->ah);
- struct wmi_cmd_hdr *hdr;
- struct wmi_swba *swba_hdr;
- enum wmi_event_id event;
- struct sk_buff *skb;
- void *wmi_event;
- unsigned long flags;
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- __be32 txrate;
-#endif
- spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
- skb = priv->wmi->wmi_skb;
- spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
+ ath_print(common, ATH_DBG_WMI, "SWBA Event received\n");
- hdr = (struct wmi_cmd_hdr *) skb->data;
- event = be16_to_cpu(hdr->command_id);
- wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+ ath9k_htc_swba(priv, priv->wmi->beacon_pending);
- ath_print(common, ATH_DBG_WMI,
- "WMI Event: 0x%x\n", event);
-
- switch (event) {
- case WMI_TGT_RDY_EVENTID:
- break;
- case WMI_SWBA_EVENTID:
- swba_hdr = (struct wmi_swba *) wmi_event;
- ath9k_htc_swba(priv, swba_hdr->beacon_pending);
- break;
- case WMI_FATAL_EVENTID:
- break;
- case WMI_TXTO_EVENTID:
- break;
- case WMI_BMISS_EVENTID:
- break;
- case WMI_WLAN_TXCOMP_EVENTID:
- break;
- case WMI_DELBA_EVENTID:
- break;
- case WMI_TXRATE_EVENTID:
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
- txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
- priv->debug.txrate = be32_to_cpu(txrate);
-#endif
- break;
- default:
- break;
- }
-
- kfree_skb(skb);
}
static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
@@ -189,6 +147,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
struct wmi *wmi = (struct wmi *) priv;
struct wmi_cmd_hdr *hdr;
u16 cmd_id;
+ void *wmi_event;
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+ __be32 txrate;
+#endif
if (unlikely(wmi->stopped))
goto free_skb;
@@ -197,10 +159,22 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
cmd_id = be16_to_cpu(hdr->command_id);
if (cmd_id & 0x1000) {
- spin_lock(&wmi->wmi_lock);
- wmi->wmi_skb = skb;
- spin_unlock(&wmi->wmi_lock);
- tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
+ wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+ switch (cmd_id) {
+ case WMI_SWBA_EVENTID:
+ wmi->beacon_pending = *(u8 *)wmi_event;
+ tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
+ break;
+ case WMI_TXRATE_EVENTID:
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+ txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
+ wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
+#endif
+ break;
+ default:
+ break;
+ }
+ kfree_skb(skb);
return;
}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 765db5faa2d3..ac61074af8ac 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -31,10 +31,6 @@ struct wmi_cmd_hdr {
__be16 seq_no;
} __packed;
-struct wmi_swba {
- u8 beacon_pending;
-} __packed;
-
enum wmi_cmd_id {
WMI_ECHO_CMDID = 0x0001,
WMI_ACCESS_MEMORY_CMDID,
@@ -71,6 +67,7 @@ enum wmi_cmd_id {
WMI_TX_AGGR_ENABLE_CMDID,
WMI_TGT_DETACH_CMDID,
WMI_TGT_TXQ_ENABLE_CMDID,
+ WMI_AGGR_LIMIT_CMD = 0x0026,
};
enum wmi_event_id {
@@ -103,7 +100,7 @@ struct wmi {
u32 cmd_rsp_len;
bool stopped;
- struct sk_buff *wmi_skb;
+ u8 beacon_pending;
spinlock_t wmi_lock;
atomic_t mwrite_cnt;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4dda14e36227..457f07692ac7 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1407,22 +1407,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
- if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
- return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
- return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
- return ATH9K_KEY_TYPE_AES;
- }
-
- return ATH9K_KEY_TYPE_CLEAR;
-}
-
static void assign_aggr_tid_seqno(struct sk_buff *skb,
struct ath_buf *bf)
{
@@ -1661,7 +1645,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_state.bfs_paprd_timestamp = jiffies;
bf->bf_flags = setup_tx_flags(skb, use_ldpc);
- bf->bf_keytype = get_hw_crypto_keytype(skb);
+ bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
bf->bf_frmlen += tx_info->control.hw_key->icv_len;
bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
new file mode 100644
index 000000000000..c5d3a3f2e55b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/Kconfig
@@ -0,0 +1,41 @@
+config CARL9170
+ tristate "Linux Community AR9170 802.11n USB support"
+ depends on USB && MAC80211 && EXPERIMENTAL
+ select FW_LOADER
+ select CRC32
+ help
+ This is another driver for the Atheros "otus" 802.11n USB devices.
+
+ This driver provides more features than the original,
+ but it needs a special firmware (carl9170-1.fw) to do that.
+
+ The firmware can be downloaded from our wiki here:
+ http://wireless.kernel.org/en/users/Drivers/carl9170
+
+ If you choose to build a module, it'll be called carl9170.
+
+config CARL9170_LEDS
+ bool "SoftLED Support"
+ depends on CARL9170
+ select MAC80211_LEDS
+ select LEDS_CLASS
+ select NEW_LEDS
+ default y
+ help
+ This option is necessary, if you want your device' LEDs to blink
+
+ Say Y, unless you need the LEDs for firmware debugging.
+
+config CARL9170_DEBUGFS
+ bool "DebugFS Support"
+ depends on CARL9170 && DEBUG_FS && MAC80211_DEBUGFS
+ default n
+ help
+ Export several driver and device internals to user space.
+
+ Say N.
+
+config CARL9170_WPC
+ bool
+ depends on CARL9170 && (INPUT = y || INPUT = CARL9170)
+ default y
diff --git a/drivers/net/wireless/ath/carl9170/Makefile b/drivers/net/wireless/ath/carl9170/Makefile
new file mode 100644
index 000000000000..f64ed76af8ad
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/Makefile
@@ -0,0 +1,4 @@
+carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o
+carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o
+
+obj-$(CONFIG_CARL9170) += carl9170.o
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
new file mode 100644
index 000000000000..9f1d60359061
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -0,0 +1,626 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CARL9170_H
+#define __CARL9170_H
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <linux/usb.h>
+#ifdef CONFIG_CARL9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_CARL170_LEDS */
+#ifdef CONFIG_CARL9170_WPC
+#include <linux/input.h>
+#endif /* CONFIG_CARL9170_WPC */
+#include "eeprom.h"
+#include "wlan.h"
+#include "hw.h"
+#include "fwdesc.h"
+#include "fwcmd.h"
+#include "../regd.h"
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+#include "debug.h"
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+#define CARL9170FW_NAME "carl9170-1.fw"
+
+#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1)
+
+enum carl9170_rf_init_mode {
+ CARL9170_RFI_NONE,
+ CARL9170_RFI_WARM,
+ CARL9170_RFI_COLD,
+};
+
+#define CARL9170_MAX_RX_BUFFER_SIZE 8192
+
+enum carl9170_device_state {
+ CARL9170_UNKNOWN_STATE,
+ CARL9170_STOPPED,
+ CARL9170_IDLE,
+ CARL9170_STARTED,
+};
+
+#define CARL9170_NUM_TID 16
+#define WME_BA_BMP_SIZE 64
+#define CARL9170_TX_USER_RATE_TRIES 3
+
+#define WME_AC_BE 2
+#define WME_AC_BK 3
+#define WME_AC_VI 1
+#define WME_AC_VO 0
+
+#define TID_TO_WME_AC(_tid) \
+ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+ (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+ (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+ WME_AC_VO)
+
+#define SEQ_DIFF(_start, _seq) \
+ (((_start) - (_seq)) & 0x0fff)
+#define SEQ_PREV(_seq) \
+ (((_seq) - 1) & 0x0fff)
+#define SEQ_NEXT(_seq) \
+ (((_seq) + 1) & 0x0fff)
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+ ((((_seqno) - (_start)) & 0xfff) < (_bawsz))
+
+enum carl9170_tid_state {
+ CARL9170_TID_STATE_INVALID,
+ CARL9170_TID_STATE_KILLED,
+ CARL9170_TID_STATE_SHUTDOWN,
+ CARL9170_TID_STATE_SUSPEND,
+ CARL9170_TID_STATE_PROGRESS,
+ CARL9170_TID_STATE_IDLE,
+ CARL9170_TID_STATE_XMIT,
+};
+
+#define CARL9170_BAW_BITS (2 * WME_BA_BMP_SIZE)
+#define CARL9170_BAW_SIZE (BITS_TO_LONGS(CARL9170_BAW_BITS))
+#define CARL9170_BAW_LEN (DIV_ROUND_UP(CARL9170_BAW_BITS, BITS_PER_BYTE))
+
+struct carl9170_sta_tid {
+ /* must be the first entry! */
+ struct list_head list;
+
+ /* temporary list for RCU unlink procedure */
+ struct list_head tmp_list;
+
+ /* lock for the following data structures */
+ spinlock_t lock;
+
+ unsigned int counter;
+ enum carl9170_tid_state state;
+ u8 tid; /* TID number ( 0 - 15 ) */
+ u16 max; /* max. AMPDU size */
+
+ u16 snx; /* awaiting _next_ frame */
+ u16 hsn; /* highest _queued_ sequence */
+ u16 bsn; /* base of the tx/agg bitmap */
+ unsigned long bitmap[CARL9170_BAW_SIZE];
+
+ /* Preaggregation reorder queue */
+ struct sk_buff_head queue;
+};
+
+#define CARL9170_QUEUE_TIMEOUT 256
+#define CARL9170_BUMP_QUEUE 1000
+#define CARL9170_TX_TIMEOUT 2500
+#define CARL9170_JANITOR_DELAY 128
+#define CARL9170_QUEUE_STUCK_TIMEOUT 5500
+
+#define CARL9170_NUM_TX_AGG_MAX 30
+
+/*
+ * Tradeoff between stability/latency and speed.
+ *
+ * AR9170_TXQ_DEPTH is devised by dividing the amount of available
+ * tx buffers with the size of a full ethernet frame + overhead.
+ *
+ * Naturally: The higher the limit, the faster the device CAN send.
+ * However, even a slight over-commitment at the wrong time and the
+ * hardware is doomed to send all already-queued frames at suboptimal
+ * rates. This in turn leads to an enourmous amount of unsuccessful
+ * retries => Latency goes up, whereas the throughput goes down. CRASH!
+ */
+#define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2)
+#define CARL9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH)
+
+struct carl9170_tx_queue_stats {
+ unsigned int count;
+ unsigned int limit;
+ unsigned int len;
+};
+
+struct carl9170_vif {
+ unsigned int id;
+ struct ieee80211_vif *vif;
+};
+
+struct carl9170_vif_info {
+ struct list_head list;
+ bool active;
+ unsigned int id;
+ struct sk_buff *beacon;
+ bool enable_beacon;
+};
+
+#define AR9170_NUM_RX_URBS 16
+#define AR9170_NUM_RX_URBS_MUL 2
+#define AR9170_NUM_TX_URBS 8
+#define AR9170_NUM_RX_URBS_POOL (AR9170_NUM_RX_URBS_MUL * AR9170_NUM_RX_URBS)
+
+enum carl9170_device_features {
+ CARL9170_WPS_BUTTON = BIT(0),
+ CARL9170_ONE_LED = BIT(1),
+};
+
+#ifdef CONFIG_CARL9170_LEDS
+struct ar9170;
+
+struct carl9170_led {
+ struct ar9170 *ar;
+ struct led_classdev l;
+ char name[32];
+ unsigned int toggled;
+ bool last_state;
+ bool registered;
+};
+#endif /* CONFIG_CARL9170_LEDS */
+
+enum carl9170_restart_reasons {
+ CARL9170_RR_NO_REASON = 0,
+ CARL9170_RR_FATAL_FIRMWARE_ERROR,
+ CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
+ CARL9170_RR_WATCHDOG,
+ CARL9170_RR_STUCK_TX,
+ CARL9170_RR_SLOW_SYSTEM,
+ CARL9170_RR_COMMAND_TIMEOUT,
+ CARL9170_RR_TOO_MANY_PHY_ERRORS,
+ CARL9170_RR_LOST_RSP,
+ CARL9170_RR_INVALID_RSP,
+ CARL9170_RR_USER_REQUEST,
+
+ __CARL9170_RR_LAST,
+};
+
+enum carl9170_erp_modes {
+ CARL9170_ERP_INVALID,
+ CARL9170_ERP_AUTO,
+ CARL9170_ERP_MAC80211,
+ CARL9170_ERP_OFF,
+ CARL9170_ERP_CTS,
+ CARL9170_ERP_RTS,
+ __CARL9170_ERP_NUM,
+};
+
+struct ar9170 {
+ struct ath_common common;
+ struct ieee80211_hw *hw;
+ struct mutex mutex;
+ enum carl9170_device_state state;
+ spinlock_t state_lock;
+ enum carl9170_restart_reasons last_reason;
+ bool registered;
+
+ /* USB */
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct usb_anchor rx_anch;
+ struct usb_anchor rx_work;
+ struct usb_anchor rx_pool;
+ struct usb_anchor tx_wait;
+ struct usb_anchor tx_anch;
+ struct usb_anchor tx_cmd;
+ struct usb_anchor tx_err;
+ struct tasklet_struct usb_tasklet;
+ atomic_t tx_cmd_urbs;
+ atomic_t tx_anch_urbs;
+ atomic_t rx_anch_urbs;
+ atomic_t rx_work_urbs;
+ atomic_t rx_pool_urbs;
+ kernel_ulong_t features;
+
+ /* firmware settings */
+ struct completion fw_load_wait;
+ struct completion fw_boot_wait;
+ struct {
+ const struct carl9170fw_desc_head *desc;
+ const struct firmware *fw;
+ unsigned int offset;
+ unsigned int address;
+ unsigned int cmd_bufs;
+ unsigned int api_version;
+ unsigned int vif_num;
+ unsigned int err_counter;
+ unsigned int bug_counter;
+ u32 beacon_addr;
+ unsigned int beacon_max_len;
+ bool rx_stream;
+ bool tx_stream;
+ unsigned int mem_blocks;
+ unsigned int mem_block_size;
+ unsigned int rx_size;
+ } fw;
+
+ /* reset / stuck frames/queue detection */
+ struct work_struct restart_work;
+ unsigned int restart_counter;
+ unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
+ unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
+ bool needs_full_reset;
+ atomic_t pending_restarts;
+
+ /* interface mode settings */
+ struct list_head vif_list;
+ unsigned long vif_bitmap;
+ unsigned int vifs;
+ struct carl9170_vif vif_priv[AR9170_MAX_VIRTUAL_MAC];
+
+ /* beaconing */
+ spinlock_t beacon_lock;
+ unsigned int global_pretbtt;
+ unsigned int global_beacon_int;
+ struct carl9170_vif_info *beacon_iter;
+ unsigned int beacon_enabled;
+
+ /* cryptographic engine */
+ u64 usedkeys;
+ bool rx_software_decryption;
+ bool disable_offload;
+
+ /* filter settings */
+ u64 cur_mc_hash;
+ u32 cur_filter;
+ unsigned int filter_state;
+ bool sniffer_enabled;
+
+ /* MAC */
+ enum carl9170_erp_modes erp_mode;
+
+ /* PHY */
+ struct ieee80211_channel *channel;
+ int noise[6];
+ unsigned int chan_fail;
+ unsigned int total_chan_fail;
+ u8 heavy_clip;
+
+ /* power calibration data */
+ u8 power_5G_leg[4];
+ u8 power_2G_cck[4];
+ u8 power_2G_ofdm[4];
+ u8 power_5G_ht20[8];
+ u8 power_5G_ht40[8];
+ u8 power_2G_ht20[8];
+ u8 power_2G_ht40[8];
+
+#ifdef CONFIG_CARL9170_LEDS
+ /* LED */
+ struct delayed_work led_work;
+ struct carl9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_CARL9170_LEDS */
+
+ /* qos queue settings */
+ spinlock_t tx_stats_lock;
+ struct carl9170_tx_queue_stats tx_stats[__AR9170_NUM_TXQ];
+ struct ieee80211_tx_queue_params edcf[5];
+ struct completion tx_flush;
+
+ /* CMD */
+ int cmd_seq;
+ int readlen;
+ u8 *readbuf;
+ spinlock_t cmd_lock;
+ struct completion cmd_wait;
+ union {
+ __le32 cmd_buf[PAYLOAD_MAX + 1];
+ struct carl9170_cmd cmd;
+ struct carl9170_rsp rsp;
+ };
+
+ /* statistics */
+ unsigned int tx_dropped;
+ unsigned int tx_ack_failures;
+ unsigned int tx_fcs_errors;
+ unsigned int tx_ampdu_timeout;
+ unsigned int rx_dropped;
+
+ /* EEPROM */
+ struct ar9170_eeprom eeprom;
+
+ /* tx queuing */
+ struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
+ struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+ struct delayed_work tx_janitor;
+ unsigned long tx_janitor_last_run;
+ bool tx_schedule;
+
+ /* tx ampdu */
+ struct work_struct ampdu_work;
+ spinlock_t tx_ampdu_list_lock;
+ struct carl9170_sta_tid *tx_ampdu_iter;
+ struct list_head tx_ampdu_list;
+ atomic_t tx_ampdu_upload;
+ atomic_t tx_ampdu_scheduler;
+ atomic_t tx_total_pending;
+ atomic_t tx_total_queued;
+ unsigned int tx_ampdu_list_len;
+ int current_density;
+ int current_factor;
+ bool tx_ampdu_schedule;
+
+ /* internal memory management */
+ spinlock_t mem_lock;
+ unsigned long *mem_bitmap;
+ atomic_t mem_free_blocks;
+ atomic_t mem_allocs;
+
+ /* rxstream mpdu merge */
+ struct ar9170_rx_head rx_plcp;
+ bool rx_has_plcp;
+ struct sk_buff *rx_failover;
+ int rx_failover_missing;
+
+#ifdef CONFIG_CARL9170_WPC
+ struct {
+ bool pbc_state;
+ struct input_dev *pbc;
+ char name[32];
+ char phys[32];
+ } wps;
+#endif /* CONFIG_CARL9170_WPC */
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ struct carl9170_debug debug;
+ struct dentry *debug_dir;
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+ /* PSM */
+ struct work_struct ps_work;
+ struct {
+ unsigned int dtim_counter;
+ unsigned long last_beacon;
+ unsigned long last_action;
+ unsigned long last_slept;
+ unsigned int sleep_ms;
+ unsigned int off_override;
+ bool state;
+ } ps;
+};
+
+enum carl9170_ps_off_override_reasons {
+ PS_OFF_VIF = BIT(0),
+ PS_OFF_BCN = BIT(1),
+ PS_OFF_5GHZ = BIT(2),
+};
+
+struct carl9170_ba_stats {
+ u8 ampdu_len;
+ u8 ampdu_ack_len;
+ bool clear;
+};
+
+struct carl9170_sta_info {
+ bool ht_sta;
+ unsigned int ampdu_max_len;
+ struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
+ struct carl9170_ba_stats stats[CARL9170_NUM_TID];
+};
+
+struct carl9170_tx_info {
+ unsigned long timeout;
+ struct ar9170 *ar;
+ struct kref ref;
+};
+
+#define CHK_DEV_STATE(a, s) (((struct ar9170 *)a)->state >= (s))
+#define IS_INITIALIZED(a) (CHK_DEV_STATE(a, CARL9170_STOPPED))
+#define IS_ACCEPTING_CMD(a) (CHK_DEV_STATE(a, CARL9170_IDLE))
+#define IS_STARTED(a) (CHK_DEV_STATE(a, CARL9170_STARTED))
+
+static inline void __carl9170_set_state(struct ar9170 *ar,
+ enum carl9170_device_state newstate)
+{
+ ar->state = newstate;
+}
+
+static inline void carl9170_set_state(struct ar9170 *ar,
+ enum carl9170_device_state newstate)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->state_lock, flags);
+ __carl9170_set_state(ar, newstate);
+ spin_unlock_irqrestore(&ar->state_lock, flags);
+}
+
+static inline void carl9170_set_state_when(struct ar9170 *ar,
+ enum carl9170_device_state min, enum carl9170_device_state newstate)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->state_lock, flags);
+ if (CHK_DEV_STATE(ar, min))
+ __carl9170_set_state(ar, newstate);
+ spin_unlock_irqrestore(&ar->state_lock, flags);
+}
+
+/* exported interface */
+void *carl9170_alloc(size_t priv_size);
+int carl9170_register(struct ar9170 *ar);
+void carl9170_unregister(struct ar9170 *ar);
+void carl9170_free(struct ar9170 *ar);
+void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r);
+void carl9170_ps_check(struct ar9170 *ar);
+
+/* USB back-end */
+int carl9170_usb_open(struct ar9170 *ar);
+void carl9170_usb_stop(struct ar9170 *ar);
+void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_usb_handle_tx_err(struct ar9170 *ar);
+int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids,
+ u32 plen, void *payload, u32 rlen, void *resp);
+int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
+ const bool free_buf);
+int carl9170_usb_restart(struct ar9170 *ar);
+void carl9170_usb_reset(struct ar9170 *ar);
+
+/* MAC */
+int carl9170_init_mac(struct ar9170 *ar);
+int carl9170_set_qos(struct ar9170 *ar);
+int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
+int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
+ const u8 *mac);
+int carl9170_set_operating_mode(struct ar9170 *ar);
+int carl9170_set_beacon_timers(struct ar9170 *ar);
+int carl9170_set_dyn_sifs_ack(struct ar9170 *ar);
+int carl9170_set_rts_cts_rate(struct ar9170 *ar);
+int carl9170_set_ampdu_settings(struct ar9170 *ar);
+int carl9170_set_slot_time(struct ar9170 *ar);
+int carl9170_set_mac_rates(struct ar9170 *ar);
+int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
+int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
+ const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
+int carl9170_disable_key(struct ar9170 *ar, const u8 id);
+
+/* RX */
+void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
+void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
+
+/* TX */
+int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+void carl9170_tx_janitor(struct work_struct *work);
+void carl9170_tx_process_status(struct ar9170 *ar,
+ const struct carl9170_rsp *cmd);
+void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ const bool success);
+void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb);
+void carl9170_tx_scheduler(struct ar9170 *ar);
+void carl9170_tx_get_skb(struct sk_buff *skb);
+int carl9170_tx_put_skb(struct sk_buff *skb);
+
+/* LEDs */
+#ifdef CONFIG_CARL9170_LEDS
+int carl9170_led_register(struct ar9170 *ar);
+void carl9170_led_unregister(struct ar9170 *ar);
+#endif /* CONFIG_CARL9170_LEDS */
+int carl9170_led_init(struct ar9170 *ar);
+int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
+
+/* PHY / RF */
+int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi);
+int carl9170_get_noisefloor(struct ar9170 *ar);
+
+/* FW */
+int carl9170_parse_firmware(struct ar9170 *ar);
+int carl9170_fw_fix_eeprom(struct ar9170 *ar);
+
+extern struct ieee80211_rate __carl9170_ratetable[];
+extern int modparam_noht;
+
+static inline struct ar9170 *carl9170_get_priv(struct carl9170_vif *carl_vif)
+{
+ return container_of(carl_vif, struct ar9170,
+ vif_priv[carl_vif->id]);
+}
+
+static inline struct ieee80211_hdr *carl9170_get_hdr(struct sk_buff *skb)
+{
+ return (void *)((struct _carl9170_tx_superframe *)
+ skb->data)->frame_data;
+}
+
+static inline u16 get_seq_h(struct ieee80211_hdr *hdr)
+{
+ return le16_to_cpu(hdr->seq_ctrl) >> 4;
+}
+
+static inline u16 carl9170_get_seq(struct sk_buff *skb)
+{
+ return get_seq_h(carl9170_get_hdr(skb));
+}
+
+static inline u16 get_tid_h(struct ieee80211_hdr *hdr)
+{
+ return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 carl9170_get_tid(struct sk_buff *skb)
+{
+ return get_tid_h(carl9170_get_hdr(skb));
+}
+
+static inline struct ieee80211_vif *
+carl9170_get_vif(struct carl9170_vif_info *priv)
+{
+ return container_of((void *)priv, struct ieee80211_vif, drv_priv);
+}
+
+/* Protected by ar->mutex or RCU */
+static inline struct ieee80211_vif *carl9170_get_main_vif(struct ar9170 *ar)
+{
+ struct carl9170_vif_info *cvif;
+
+ list_for_each_entry_rcu(cvif, &ar->vif_list, list) {
+ if (cvif->active)
+ return carl9170_get_vif(cvif);
+ }
+
+ return NULL;
+}
+
+static inline bool is_main_vif(struct ar9170 *ar, struct ieee80211_vif *vif)
+{
+ bool ret;
+
+ rcu_read_lock();
+ ret = (carl9170_get_main_vif(ar) == vif);
+ rcu_read_unlock();
+ return ret;
+}
+
+#endif /* __CARL9170_H */
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
new file mode 100644
index 000000000000..c21f3364bfec
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -0,0 +1,188 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "carl9170.h"
+#include "cmd.h"
+
+int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+ __le32 buf[2] = {
+ cpu_to_le32(reg),
+ cpu_to_le32(val),
+ };
+ int err;
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
+ (u8 *) buf, 0, NULL);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "writing reg %#x "
+ "(val %#x) failed (%d)\n", reg, val, err);
+ }
+ }
+ return err;
+}
+
+int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
+ const u32 *regs, u32 *out)
+{
+ int i, err;
+ __le32 *offs, *res;
+
+ /* abuse "out" for the register offsets, must be same length */
+ offs = (__le32 *)out;
+ for (i = 0; i < nregs; i++)
+ offs[i] = cpu_to_le32(regs[i]);
+
+ /* also use the same buffer for the input */
+ res = (__le32 *)out;
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
+ 4 * nregs, (u8 *)offs,
+ 4 * nregs, (u8 *)res);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
+ err);
+ }
+ return err;
+ }
+
+ /* convert result to cpu endian */
+ for (i = 0; i < nregs; i++)
+ out[i] = le32_to_cpu(res[i]);
+
+ return 0;
+}
+
+int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+ return carl9170_read_mreg(ar, 1, &reg, val);
+}
+
+int carl9170_echo_test(struct ar9170 *ar, const u32 v)
+{
+ u32 echores;
+ int err;
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO,
+ 4, (u8 *)&v,
+ 4, (u8 *)&echores);
+ if (err)
+ return err;
+
+ if (v != echores) {
+ wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
+ const enum carl9170_cmd_oids cmd, const unsigned int len)
+{
+ struct carl9170_cmd *tmp;
+
+ tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC);
+ if (tmp) {
+ tmp->hdr.cmd = cmd;
+ tmp->hdr.len = len;
+ }
+
+ return tmp;
+}
+
+int carl9170_reboot(struct ar9170 *ar)
+{
+ struct carl9170_cmd *cmd;
+ int err;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
+ if (!cmd)
+ return -ENOMEM;
+
+ err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true);
+ return err;
+}
+
+int carl9170_mac_reset(struct ar9170 *ar)
+{
+ return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST,
+ 0, NULL, 0, NULL);
+}
+
+int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
+ const u32 mode, const u32 addr, const u32 len)
+{
+ struct carl9170_cmd *cmd;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC,
+ sizeof(struct carl9170_bcn_ctrl_cmd));
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id);
+ cmd->bcn_ctrl.mode = cpu_to_le32(mode);
+ cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr);
+ cmd->bcn_ctrl.bcn_len = cpu_to_le32(len);
+
+ return __carl9170_exec_cmd(ar, cmd, true);
+}
+
+int carl9170_powersave(struct ar9170 *ar, const bool ps)
+{
+ struct carl9170_cmd *cmd;
+ u32 state;
+
+ cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC,
+ sizeof(struct carl9170_psm));
+ if (!cmd)
+ return -ENOMEM;
+
+ if (ps) {
+ /* Sleep until next TBTT */
+ state = CARL9170_PSM_SLEEP | 1;
+ } else {
+ /* wake up immediately */
+ state = 1;
+ }
+
+ cmd->psm.state = cpu_to_le32(state);
+ return __carl9170_exec_cmd(ar, cmd, true);
+}
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
new file mode 100644
index 000000000000..0fc83d2336fd
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -0,0 +1,158 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CMD_H
+#define __CMD_H
+
+#include "carl9170.h"
+
+/* basic HW access */
+int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
+int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val);
+int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
+ const u32 *regs, u32 *out);
+int carl9170_echo_test(struct ar9170 *ar, u32 v);
+int carl9170_reboot(struct ar9170 *ar);
+int carl9170_mac_reset(struct ar9170 *ar);
+int carl9170_powersave(struct ar9170 *ar, const bool power_on);
+int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
+ const u32 mode, const u32 addr, const u32 len);
+
+static inline int carl9170_flush_cab(struct ar9170 *ar,
+ const unsigned int vif_id)
+{
+ return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0);
+}
+
+struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar,
+ const enum carl9170_cmd_oids cmd, const unsigned int len);
+
+/*
+ * Macros to facilitate writing multiple registers in a single
+ * write-combining USB command. Note that when the first group
+ * fails the whole thing will fail without any others attempted,
+ * but you won't know which write in the group failed.
+ */
+#define carl9170_regwrite_begin(ar) \
+do { \
+ int __nreg = 0, __err = 0; \
+ struct ar9170 *__ar = ar;
+
+#define carl9170_regwrite(r, v) do { \
+ __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \
+ __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \
+ __nreg++; \
+ if ((__nreg >= PAYLOAD_MAX/2)) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = carl9170_exec_cmd(__ar, \
+ CARL9170_CMD_WREG, 8 * __nreg, \
+ (u8 *) &__ar->cmd_buf[1], 0, NULL); \
+ else \
+ goto __regwrite_out; \
+ \
+ __nreg = 0; \
+ if (__err) \
+ goto __regwrite_out; \
+ } \
+} while (0)
+
+#define carl9170_regwrite_finish() \
+__regwrite_out : \
+ if (__err == 0 && __nreg) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = carl9170_exec_cmd(__ar, \
+ CARL9170_CMD_WREG, 8 * __nreg, \
+ (u8 *) &__ar->cmd_buf[1], 0, NULL); \
+ __nreg = 0; \
+ }
+
+#define carl9170_regwrite_result() \
+ __err; \
+} while (0);
+
+
+#define carl9170_async_get_buf() \
+do { \
+ __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \
+ CARL9170_MAX_CMD_PAYLOAD_LEN); \
+ if (__cmd == NULL) { \
+ __err = -ENOMEM; \
+ goto __async_regwrite_out; \
+ } \
+} while (0);
+
+#define carl9170_async_regwrite_begin(carl) \
+do { \
+ int __nreg = 0, __err = 0; \
+ struct ar9170 *__carl = carl; \
+ struct carl9170_cmd *__cmd; \
+ carl9170_async_get_buf(); \
+
+#define carl9170_async_regwrite(r, v) do { \
+ __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \
+ __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \
+ __nreg++; \
+ if ((__nreg >= PAYLOAD_MAX/2)) { \
+ if (IS_ACCEPTING_CMD(__carl)) { \
+ __cmd->hdr.len = 8 * __nreg; \
+ __err = __carl9170_exec_cmd(__carl, __cmd, true);\
+ __cmd = NULL; \
+ carl9170_async_get_buf(); \
+ } else { \
+ goto __async_regwrite_out; \
+ } \
+ __nreg = 0; \
+ if (__err) \
+ goto __async_regwrite_out; \
+ } \
+} while (0)
+
+#define carl9170_async_regwrite_finish() \
+__async_regwrite_out : \
+ if (__err == 0 && __nreg) { \
+ __cmd->hdr.len = 8 * __nreg; \
+ if (IS_ACCEPTING_CMD(__carl)) \
+ __err = __carl9170_exec_cmd(__carl, __cmd, true);\
+ __nreg = 0; \
+ }
+
+#define carl9170_async_regwrite_result() \
+ __err; \
+} while (0);
+
+#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
new file mode 100644
index 000000000000..3e9b0e8b2b8c
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -0,0 +1,908 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * debug(fs) probing
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2008-2009 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/vmalloc.h>
+#include "carl9170.h"
+#include "cmd.h"
+
+#define ADD(buf, off, max, fmt, args...) \
+ off += snprintf(&buf[off], max - off, fmt, ##args);
+
+static int carl9170_debugfs_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+struct carl9170_debugfs_fops {
+ unsigned int read_bufsize;
+ mode_t attr;
+ char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
+ ssize_t *len);
+ ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
+ const struct file_operations fops;
+
+ enum carl9170_device_state req_dev_state;
+};
+
+static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct carl9170_debugfs_fops *dfops;
+ struct ar9170 *ar;
+ char *buf = NULL, *res_buf = NULL;
+ ssize_t ret = 0;
+ int err = 0;
+
+ if (!count)
+ return 0;
+
+ ar = file->private_data;
+
+ if (!ar)
+ return -ENODEV;
+ dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
+
+ if (!dfops->read)
+ return -ENOSYS;
+
+ if (dfops->read_bufsize) {
+ buf = vmalloc(dfops->read_bufsize);
+ if (!buf)
+ return -ENOMEM;
+ }
+
+ mutex_lock(&ar->mutex);
+ if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
+ err = -ENODEV;
+ res_buf = buf;
+ goto out_free;
+ }
+
+ res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret);
+
+ if (ret > 0)
+ err = simple_read_from_buffer(userbuf, count, ppos,
+ res_buf, ret);
+ else
+ err = ret;
+
+ WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf));
+
+out_free:
+ vfree(res_buf);
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static ssize_t carl9170_debugfs_write(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct carl9170_debugfs_fops *dfops;
+ struct ar9170 *ar;
+ char *buf = NULL;
+ int err = 0;
+
+ if (!count)
+ return 0;
+
+ if (count > PAGE_SIZE)
+ return -E2BIG;
+
+ ar = file->private_data;
+
+ if (!ar)
+ return -ENODEV;
+ dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
+
+ if (!dfops->write)
+ return -ENOSYS;
+
+ buf = vmalloc(count);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, userbuf, count)) {
+ err = -EFAULT;
+ goto out_free;
+ }
+
+ if (mutex_trylock(&ar->mutex) == 0) {
+ err = -EAGAIN;
+ goto out_free;
+ }
+
+ if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
+
+ err = dfops->write(ar, buf, count);
+ if (err)
+ goto out_unlock;
+
+out_unlock:
+ mutex_unlock(&ar->mutex);
+
+out_free:
+ vfree(buf);
+ return err;
+}
+
+#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \
+ _attr, _dstate) \
+static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
+ .read_bufsize = _read_bufsize, \
+ .read = _read, \
+ .write = _write, \
+ .attr = _attr, \
+ .req_dev_state = _dstate, \
+ .fops = { \
+ .open = carl9170_debugfs_open, \
+ .read = carl9170_debugfs_read, \
+ .write = carl9170_debugfs_write, \
+ .owner = THIS_MODULE \
+ }, \
+}
+
+#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \
+ __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \
+ _attr, CARL9170_STARTED) \
+
+#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \
+ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ NULL, _read_bufsize, S_IRUSR)
+
+#define DEBUGFS_DECLARE_WO_FILE(name) \
+ DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
+ 0, S_IWUSR)
+
+#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \
+ DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ carl9170_debugfs_##name ##_write, \
+ _read_bufsize, S_IRUSR | S_IWUSR)
+
+#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \
+ __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
+ carl9170_debugfs_##name ##_write, \
+ _read_bufsize, S_IRUSR | S_IWUSR, _dstate)
+
+#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \
+static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \
+ char *buf, size_t buf_size,\
+ ssize_t *len) \
+{ \
+ ADD(buf, *len, buf_size, fmt "\n", ##value); \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
+
+static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "jar: [");
+
+ spin_lock_bh(&ar->mem_lock);
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ ar->mem_bitmap, ar->fw.mem_blocks);
+
+ ADD(buf, *len, bufsize, "]\n");
+
+ ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
+ bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
+ ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
+
+ ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
+ atomic_read(&ar->mem_free_blocks),
+ (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
+ (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
+
+ spin_unlock_bh(&ar->mem_lock);
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
+
+static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
+ "Software");
+
+ ADD(buf, *len, bufsize, "[ VO VI "
+ " BE BK ]\n");
+
+ spin_lock_bh(&ar->tx_stats_lock);
+ ADD(buf, *len, bufsize, "[length/limit length/limit "
+ "length/limit length/limit ]\n"
+ "[ %3d/%3d %3d/%3d "
+ " %3d/%3d %3d/%3d ]\n\n",
+ ar->tx_stats[0].len, ar->tx_stats[0].limit,
+ ar->tx_stats[1].len, ar->tx_stats[1].limit,
+ ar->tx_stats[2].len, ar->tx_stats[2].limit,
+ ar->tx_stats[3].len, ar->tx_stats[3].limit);
+
+ ADD(buf, *len, bufsize, "[ total total "
+ " total total ]\n"
+ "[%10d %10d %10d %10d ]\n\n",
+ ar->tx_stats[0].count, ar->tx_stats[1].count,
+ ar->tx_stats[2].count, ar->tx_stats[3].count);
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+
+ ADD(buf, *len, bufsize, "[ pend/waittx pend/waittx "
+ " pend/waittx pend/waittx]\n"
+ "[ %3d/%3d %3d/%3d "
+ " %3d/%3d %3d/%3d ]\n\n",
+ skb_queue_len(&ar->tx_pending[0]),
+ skb_queue_len(&ar->tx_status[0]),
+ skb_queue_len(&ar->tx_pending[1]),
+ skb_queue_len(&ar->tx_status[1]),
+ skb_queue_len(&ar->tx_pending[2]),
+ skb_queue_len(&ar->tx_status[2]),
+ skb_queue_len(&ar->tx_pending[3]),
+ skb_queue_len(&ar->tx_status[3]));
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
+
+static void carl9170_debugfs_format_frame(struct ar9170 *ar,
+ struct sk_buff *skb, const char *prefix, char *buf,
+ ssize_t *off, ssize_t bufsize)
+{
+ struct _carl9170_tx_superframe *txc = (void *) skb->data;
+ struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+ struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
+ struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+
+ ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
+ "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
+ ieee80211_get_DA(hdr), get_seq_h(hdr),
+ le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
+ jiffies_to_msecs(jiffies - arinfo->timeout));
+}
+
+
+static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ struct carl9170_sta_tid *iter;
+ struct sk_buff *skb;
+ int cnt = 0, fc;
+ int offset;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
+
+ spin_lock_bh(&iter->lock);
+ ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
+ "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
+ cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
+ iter->max, iter->state, iter->counter);
+
+ ADD(buf, *len, bufsize, "\tWindow: [");
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ iter->bitmap, CARL9170_BAW_BITS);
+
+#define BM_STR_OFF(offset) \
+ ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \
+ (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
+
+ ADD(buf, *len, bufsize, ",W]\n");
+
+ offset = BM_STR_OFF(0);
+ ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
+
+ offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
+ ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
+
+ offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
+ CARL9170_BAW_BITS);
+ ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
+
+ ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
+ " currently queued:%d\n", skb_queue_len(&iter->queue));
+
+ fc = 0;
+ skb_queue_walk(&iter->queue, skb) {
+ char prefix[32];
+
+ snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
+ carl9170_debugfs_format_frame(ar, skb, prefix, buf,
+ len, bufsize);
+
+ fc++;
+ }
+ spin_unlock_bh(&iter->lock);
+ cnt++;
+ }
+ rcu_read_unlock();
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
+
+static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
+ ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+ char prefix[16];
+ int fc = 0;
+
+ spin_lock_bh(&queue->lock);
+ skb_queue_walk(queue, skb) {
+ snprintf(prefix, sizeof(prefix), "%3d :", fc);
+ carl9170_debugfs_format_frame(ar, skb, prefix, buf,
+ len, bufsize);
+ fc++;
+ }
+ spin_unlock_bh(&queue->lock);
+}
+
+#define DEBUGFS_QUEUE_DUMP(q, qi) \
+static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar, \
+ char *buf, size_t bufsize, ssize_t *len) \
+{ \
+ carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
+
+static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
+ "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
+
+ ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
+ ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
+ jiffies_to_msecs(jiffies - ar->ps.last_action));
+ ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
+ jiffies_to_msecs(jiffies - ar->ps.last_slept));
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
+
+static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ int i;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
+ i, ieee80211_queue_stopped(ar->hw, i) ?
+ jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
+ jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
+
+ ar->max_queue_stop_timeout[i] = 0;
+ }
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
+
+static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ int err;
+
+ err = carl9170_get_noisefloor(ar);
+ if (err) {
+ *len = err;
+ return buf;
+ }
+
+ ADD(buf, *len, bufsize, "Chain 1: %10d dBm, ext. chan.:%10d dBm\n",
+ ar->noise[1], ar->noise[4]);
+ ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
+ ar->noise[2], ar->noise[5]);
+ ADD(buf, *len, bufsize, "Combined %10d dBm, ext. chan.:%10d dBm\n",
+ ar->noise[0], ar->noise[3]);
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
+
+static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *len)
+{
+ struct carl9170_vif_info *iter;
+ int i = 0;
+
+ ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
+ ar->vifs, ar->fw.vif_num);
+
+ ADD(buf, *len, bufsize, "VIF bitmap: [");
+
+ *len += bitmap_scnprintf(&buf[*len], bufsize - *len,
+ &ar->vif_bitmap, ar->fw.vif_num);
+
+ ADD(buf, *len, bufsize, "]\n");
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->vif_list, list) {
+ struct ieee80211_vif *vif = carl9170_get_vif(iter);
+ ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
+ " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
+ "Master" : " Slave"), iter->id, vif->type, vif->addr,
+ iter->enable_beacon ? "beaconing " : "");
+ i++;
+ }
+ rcu_read_unlock();
+
+ return buf;
+}
+DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
+
+#define UPDATE_COUNTER(ar, name) ({ \
+ u32 __tmp[ARRAY_SIZE(name##_regs)]; \
+ unsigned int __i, __err = -ENODEV; \
+ \
+ for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \
+ __tmp[__i] = name##_regs[__i].reg; \
+ ar->debug.stats.name##_counter[__i] = 0; \
+ } \
+ \
+ if (IS_STARTED(ar)) \
+ __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \
+ __tmp, ar->debug.stats.name##_counter); \
+ (__err); })
+
+#define TALLY_SUM_UP(ar, name) do { \
+ unsigned int __i; \
+ \
+ for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \
+ ar->debug.stats.name##_sum[__i] += \
+ ar->debug.stats.name##_counter[__i]; \
+ } \
+} while (0)
+
+#define DEBUGFS_HW_TALLY_FILE(name, f) \
+static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \
+ char *dum, size_t bufsize, ssize_t *ret) \
+{ \
+ char *buf; \
+ int i, max_len, err; \
+ \
+ max_len = ARRAY_SIZE(name##_regs) * 80; \
+ buf = vmalloc(max_len); \
+ if (!buf) \
+ return NULL; \
+ \
+ err = UPDATE_COUNTER(ar, name); \
+ if (err) { \
+ *ret = err; \
+ return buf; \
+ } \
+ \
+ TALLY_SUM_UP(ar, name); \
+ \
+ for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \
+ ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \
+ name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
+ ar->debug.stats.name ##_counter[i]); \
+ } \
+ \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, 0);
+
+#define DEBUGFS_HW_REG_FILE(name, f) \
+static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \
+ char *dum, size_t bufsize, ssize_t *ret) \
+{ \
+ char *buf; \
+ int i, max_len, err; \
+ \
+ max_len = ARRAY_SIZE(name##_regs) * 80; \
+ buf = vmalloc(max_len); \
+ if (!buf) \
+ return NULL; \
+ \
+ err = UPDATE_COUNTER(ar, name); \
+ if (err) { \
+ *ret = err; \
+ return buf; \
+ } \
+ \
+ for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \
+ ADD(buf, *ret, max_len, "%22s = %" f "\n", \
+ name##_regs[i].nreg, \
+ ar->debug.stats.name##_counter[i]); \
+ } \
+ \
+ return buf; \
+} \
+DEBUGFS_DECLARE_RO_FILE(name, 0);
+
+static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
+ const char *buf, size_t count)
+{
+ int err = 0, i, n = 0, max_len = 32, res;
+ unsigned int reg, tmp;
+
+ if (!count)
+ return 0;
+
+ if (count > max_len)
+ return -E2BIG;
+
+ res = sscanf(buf, "0x%X %d", &reg, &n);
+ if (res < 1) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (res == 1)
+ n = 1;
+
+ if (n > 15) {
+ err = -EMSGSIZE;
+ goto out;
+ }
+
+ if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
+
+ if (reg & 3) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < n; i++) {
+ err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
+ if (err)
+ goto out;
+
+ ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
+ ar->debug.ring[ar->debug.ring_tail].value = tmp;
+ ar->debug.ring_tail++;
+ ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
+ }
+
+out:
+ return err ? err : count;
+}
+
+static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ int i = 0;
+
+ while (ar->debug.ring_head != ar->debug.ring_tail) {
+ ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
+ ar->debug.ring[ar->debug.ring_head].reg,
+ ar->debug.ring[ar->debug.ring_head].value);
+
+ ar->debug.ring_head++;
+ ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
+
+ if (i++ == 64)
+ break;
+ }
+ ar->debug.ring_head = ar->debug.ring_tail;
+ return buf;
+}
+DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
+
+static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
+ size_t count)
+{
+ int err;
+
+ if (count < 1)
+ return -EINVAL;
+
+ switch (buf[0]) {
+ case 'F':
+ ar->needs_full_reset = true;
+ break;
+
+ case 'R':
+ if (!IS_STARTED(ar)) {
+ err = -EAGAIN;
+ goto out;
+ }
+
+ ar->needs_full_reset = false;
+ break;
+
+ case 'M':
+ err = carl9170_mac_reset(ar);
+ if (err < 0)
+ count = err;
+
+ goto out;
+
+ case 'P':
+ err = carl9170_set_channel(ar, ar->hw->conf.channel,
+ ar->hw->conf.channel_type, CARL9170_RFI_COLD);
+ if (err < 0)
+ count = err;
+
+ goto out;
+
+ default:
+ return -EINVAL;
+ }
+
+ carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
+
+out:
+ return count;
+}
+
+static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
+ "[M]ac reset\n");
+ ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
+ ar->restart_counter, ar->last_reason);
+ ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
+ ar->total_chan_fail, ar->chan_fail);
+ ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
+ ar->fw.err_counter);
+ ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
+ ar->fw.bug_counter);
+ ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
+ atomic_read(&ar->pending_restarts));
+ return buf;
+}
+__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
+
+static const char *erp_modes[] = {
+ [CARL9170_ERP_INVALID] = "INVALID",
+ [CARL9170_ERP_AUTO] = "Automatic",
+ [CARL9170_ERP_MAC80211] = "Set by MAC80211",
+ [CARL9170_ERP_OFF] = "Force Off",
+ [CARL9170_ERP_RTS] = "Force RTS",
+ [CARL9170_ERP_CTS] = "Force CTS"
+};
+
+static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
+ size_t bufsize, ssize_t *ret)
+{
+ ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
+ erp_modes[ar->erp_mode]);
+ return buf;
+}
+
+static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
+ size_t count)
+{
+ int res, val;
+
+ if (count < 1)
+ return -EINVAL;
+
+ res = sscanf(buf, "%d", &val);
+ if (res != 1)
+ return -EINVAL;
+
+ if (!((val > CARL9170_ERP_INVALID) &&
+ (val < __CARL9170_ERP_NUM)))
+ return -EINVAL;
+
+ ar->erp_mode = val;
+ return count;
+}
+
+DEBUGFS_DECLARE_RW_FILE(erp, 80);
+
+static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
+ const char *buf, size_t count)
+{
+ int err = 0, max_len = 22, res;
+ u32 reg, val;
+
+ if (!count)
+ return 0;
+
+ if (count > max_len)
+ return -E2BIG;
+
+ res = sscanf(buf, "0x%X 0x%X", &reg, &val);
+ if (res != 2) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (reg <= 0x100000 || reg >= 0x280000) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
+
+ if (reg & 3) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = carl9170_write_reg(ar, reg, val);
+ if (err)
+ goto out;
+
+out:
+ return err ? err : count;
+}
+DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
+
+DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
+DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
+DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
+DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
+DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
+DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
+DEBUGFS_QUEUE_DUMP(tx_status, 0);
+DEBUGFS_QUEUE_DUMP(tx_status, 1);
+DEBUGFS_QUEUE_DUMP(tx_status, 2);
+DEBUGFS_QUEUE_DUMP(tx_status, 3);
+DEBUGFS_QUEUE_DUMP(tx_pending, 0);
+DEBUGFS_QUEUE_DUMP(tx_pending, 1);
+DEBUGFS_QUEUE_DUMP(tx_pending, 2);
+DEBUGFS_QUEUE_DUMP(tx_pending, 3);
+DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
+ atomic_read(&ar->tx_anch_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
+ atomic_read(&ar->rx_anch_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
+ atomic_read(&ar->rx_work_urbs));
+DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
+ atomic_read(&ar->rx_pool_urbs));
+
+DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
+ atomic_read(&ar->tx_total_queued));
+DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
+ atomic_read(&ar->tx_ampdu_scheduler));
+DEBUGFS_READONLY_FILE(tx_ampdu_timeout, 20, "%d",
+ ar->tx_ampdu_timeout);
+
+DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
+ atomic_read(&ar->tx_total_pending));
+
+DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
+ ar->tx_ampdu_list_len);
+
+DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
+ atomic_read(&ar->tx_ampdu_upload));
+
+DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
+ jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
+
+DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
+
+DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
+
+DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
+DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
+ ar->rx_software_decryption);
+DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
+ ar->current_factor);
+DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
+ ar->current_density);
+
+DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
+DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
+
+void carl9170_debugfs_register(struct ar9170 *ar)
+{
+ ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
+ ar->hw->wiphy->debugfsdir);
+
+#define DEBUGFS_ADD(name) \
+ debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \
+ ar->debug_dir, ar, \
+ &carl_debugfs_##name ## _ops.fops);
+
+ DEBUGFS_ADD(usb_tx_anch_urbs);
+ DEBUGFS_ADD(usb_rx_pool_urbs);
+ DEBUGFS_ADD(usb_rx_anch_urbs);
+ DEBUGFS_ADD(usb_rx_work_urbs);
+
+ DEBUGFS_ADD(tx_total_queued);
+ DEBUGFS_ADD(tx_total_pending);
+ DEBUGFS_ADD(tx_dropped);
+ DEBUGFS_ADD(tx_stuck);
+ DEBUGFS_ADD(tx_ampdu_upload);
+ DEBUGFS_ADD(tx_ampdu_scheduler);
+ DEBUGFS_ADD(tx_ampdu_list_len);
+
+ DEBUGFS_ADD(rx_dropped);
+ DEBUGFS_ADD(sniffer_enabled);
+ DEBUGFS_ADD(rx_software_decryption);
+
+ DEBUGFS_ADD(mem_usage);
+ DEBUGFS_ADD(qos_stat);
+ DEBUGFS_ADD(sta_psm);
+ DEBUGFS_ADD(ampdu_state);
+
+ DEBUGFS_ADD(hw_tx_tally);
+ DEBUGFS_ADD(hw_rx_tally);
+ DEBUGFS_ADD(hw_phy_errors);
+ DEBUGFS_ADD(phy_noise);
+
+ DEBUGFS_ADD(hw_wlan_queue);
+ DEBUGFS_ADD(hw_pta_queue);
+ DEBUGFS_ADD(hw_ampdu_info);
+
+ DEBUGFS_ADD(ampdu_density);
+ DEBUGFS_ADD(ampdu_factor);
+
+ DEBUGFS_ADD(tx_ampdu_timeout);
+
+ DEBUGFS_ADD(tx_janitor_last_run);
+
+ DEBUGFS_ADD(tx_status_0);
+ DEBUGFS_ADD(tx_status_1);
+ DEBUGFS_ADD(tx_status_2);
+ DEBUGFS_ADD(tx_status_3);
+
+ DEBUGFS_ADD(tx_pending_0);
+ DEBUGFS_ADD(tx_pending_1);
+ DEBUGFS_ADD(tx_pending_2);
+ DEBUGFS_ADD(tx_pending_3);
+
+ DEBUGFS_ADD(hw_ioread32);
+ DEBUGFS_ADD(hw_iowrite32);
+ DEBUGFS_ADD(bug);
+
+ DEBUGFS_ADD(erp);
+
+ DEBUGFS_ADD(vif_dump);
+
+ DEBUGFS_ADD(beacon_int);
+ DEBUGFS_ADD(pretbtt);
+
+#undef DEBUGFS_ADD
+}
+
+void carl9170_debugfs_unregister(struct ar9170 *ar)
+{
+ debugfs_remove_recursive(ar->debug_dir);
+}
diff --git a/drivers/net/wireless/ath/carl9170/debug.h b/drivers/net/wireless/ath/carl9170/debug.h
new file mode 100644
index 000000000000..ea4b97524122
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/debug.h
@@ -0,0 +1,134 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * debug header
+ *
+ * Copyright 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#include "eeprom.h"
+#include "wlan.h"
+#include "hw.h"
+#include "fwdesc.h"
+#include "fwcmd.h"
+#include "../regd.h"
+
+struct hw_stat_reg_entry {
+ u32 reg;
+ char nreg[32];
+};
+
+#define STAT_MAC_REG(reg) \
+ { (AR9170_MAC_REG_##reg), #reg }
+
+#define STAT_PTA_REG(reg) \
+ { (AR9170_PTA_REG_##reg), #reg }
+
+#define STAT_USB_REG(reg) \
+ { (AR9170_USB_REG_##reg), #reg }
+
+static const struct hw_stat_reg_entry hw_rx_tally_regs[] = {
+ STAT_MAC_REG(RX_CRC32), STAT_MAC_REG(RX_CRC16),
+ STAT_MAC_REG(RX_TIMEOUT_COUNT), STAT_MAC_REG(RX_ERR_DECRYPTION_UNI),
+ STAT_MAC_REG(RX_ERR_DECRYPTION_MUL), STAT_MAC_REG(RX_MPDU),
+ STAT_MAC_REG(RX_DROPPED_MPDU), STAT_MAC_REG(RX_DEL_MPDU),
+};
+
+static const struct hw_stat_reg_entry hw_phy_errors_regs[] = {
+ STAT_MAC_REG(RX_PHY_MISC_ERROR), STAT_MAC_REG(RX_PHY_XR_ERROR),
+ STAT_MAC_REG(RX_PHY_OFDM_ERROR), STAT_MAC_REG(RX_PHY_CCK_ERROR),
+ STAT_MAC_REG(RX_PHY_HT_ERROR), STAT_MAC_REG(RX_PHY_TOTAL),
+};
+
+static const struct hw_stat_reg_entry hw_tx_tally_regs[] = {
+ STAT_MAC_REG(TX_TOTAL), STAT_MAC_REG(TX_UNDERRUN),
+ STAT_MAC_REG(TX_RETRY),
+};
+
+static const struct hw_stat_reg_entry hw_wlan_queue_regs[] = {
+ STAT_MAC_REG(DMA_STATUS), STAT_MAC_REG(DMA_TRIGGER),
+ STAT_MAC_REG(DMA_TXQ0_ADDR), STAT_MAC_REG(DMA_TXQ0_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ1_ADDR), STAT_MAC_REG(DMA_TXQ1_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ2_ADDR), STAT_MAC_REG(DMA_TXQ2_CURR_ADDR),
+ STAT_MAC_REG(DMA_TXQ3_ADDR), STAT_MAC_REG(DMA_TXQ3_CURR_ADDR),
+ STAT_MAC_REG(DMA_RXQ_ADDR), STAT_MAC_REG(DMA_RXQ_CURR_ADDR),
+};
+
+static const struct hw_stat_reg_entry hw_ampdu_info_regs[] = {
+ STAT_MAC_REG(AMPDU_DENSITY), STAT_MAC_REG(AMPDU_FACTOR),
+};
+
+static const struct hw_stat_reg_entry hw_pta_queue_regs[] = {
+ STAT_PTA_REG(DN_CURR_ADDRH), STAT_PTA_REG(DN_CURR_ADDRL),
+ STAT_PTA_REG(UP_CURR_ADDRH), STAT_PTA_REG(UP_CURR_ADDRL),
+ STAT_PTA_REG(DMA_STATUS), STAT_PTA_REG(DMA_MODE_CTRL),
+};
+
+#define DEFINE_TALLY(name) \
+ u32 name##_sum[ARRAY_SIZE(name##_regs)], \
+ name##_counter[ARRAY_SIZE(name##_regs)] \
+
+#define DEFINE_STAT(name) \
+ u32 name##_counter[ARRAY_SIZE(name##_regs)] \
+
+struct ath_stats {
+ DEFINE_TALLY(hw_tx_tally);
+ DEFINE_TALLY(hw_rx_tally);
+ DEFINE_TALLY(hw_phy_errors);
+ DEFINE_STAT(hw_wlan_queue);
+ DEFINE_STAT(hw_pta_queue);
+ DEFINE_STAT(hw_ampdu_info);
+};
+
+struct carl9170_debug_mem_rbe {
+ u32 reg;
+ u32 value;
+};
+
+#define CARL9170_DEBUG_RING_SIZE 64
+
+struct carl9170_debug {
+ struct ath_stats stats;
+ struct carl9170_debug_mem_rbe ring[CARL9170_DEBUG_RING_SIZE];
+ struct mutex ring_lock;
+ unsigned int ring_head, ring_tail;
+ struct delayed_work update_tally;
+};
+
+struct ar9170;
+
+void carl9170_debugfs_register(struct ar9170 *ar);
+void carl9170_debugfs_unregister(struct ar9170 *ar);
+#endif /* __DEBUG_H */
diff --git a/drivers/net/wireless/ath/carl9170/eeprom.h b/drivers/net/wireless/ath/carl9170/eeprom.h
new file mode 100644
index 000000000000..7cff40ac7759
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/eeprom.h
@@ -0,0 +1,216 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CARL9170_SHARED_EEPROM_H
+#define __CARL9170_SHARED_EEPROM_H
+
+#define AR9170_EEPROM_START 0x1600
+
+#define AR5416_MAX_CHAINS 2
+#define AR5416_MODAL_SPURS 5
+
+struct ar9170_eeprom_modal {
+ __le32 antCtrlChain[AR5416_MAX_CHAINS];
+ __le32 antCtrlCommon;
+ s8 antennaGainCh[AR5416_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+ s8 adcDesiredSize;
+ s8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ s8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ s8 iqCalICh[AR5416_MAX_CHAINS];
+ s8 iqCalQCh[AR5416_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob;
+ u8 db;
+ u8 xpaBiasLvl;
+ u8 pwrDecreaseFor2Chain;
+ u8 pwrDecreaseFor3Chain;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_MAX_CHAINS];
+ u8 bswMargin[AR5416_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 reserved[22];
+ struct spur_channel {
+ __le16 spurChan;
+ u8 spurRangeLow;
+ u8 spurRangeHigh;
+ } __packed spur_channels[AR5416_MODAL_SPURS];
+} __packed;
+
+#define AR5416_NUM_PD_GAINS 4
+#define AR5416_PD_GAIN_ICEPTS 5
+
+struct ar9170_calibration_data_per_freq {
+ u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+#define AR5416_NUM_5G_CAL_PIERS 8
+#define AR5416_NUM_2G_CAL_PIERS 4
+
+#define AR5416_NUM_5G_TARGET_PWRS 8
+#define AR5416_NUM_2G_CCK_TARGET_PWRS 3
+#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
+#define AR5416_MAX_NUM_TGT_PWRS 8
+
+struct ar9170_calibration_target_power_legacy {
+ u8 freq;
+ u8 power[4];
+} __packed;
+
+struct ar9170_calibration_target_power_ht {
+ u8 freq;
+ u8 power[8];
+} __packed;
+
+#define AR5416_NUM_CTLS 24
+
+struct ar9170_calctl_edges {
+ u8 channel;
+#define AR9170_CALCTL_EDGE_FLAGS 0xC0
+ u8 power_flags;
+} __packed;
+
+#define AR5416_NUM_BAND_EDGES 8
+
+struct ar9170_calctl_data {
+ struct ar9170_calctl_edges
+ control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct ar9170_eeprom {
+ __le16 length;
+ __le16 checksum;
+ __le16 version;
+ u8 operating_flags;
+#define AR9170_OPFLAG_5GHZ 1
+#define AR9170_OPFLAG_2GHZ 2
+ u8 misc;
+ __le16 reg_domain[2];
+ u8 mac_address[6];
+ u8 rx_mask;
+ u8 tx_mask;
+ __le16 rf_silent;
+ __le16 bluetooth_options;
+ __le16 device_capabilities;
+ __le32 build_number;
+ u8 deviceType;
+ u8 reserved[33];
+
+ u8 customer_data[64];
+
+ struct ar9170_eeprom_modal
+ modal_header[2];
+
+ u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
+ u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
+
+ struct ar9170_calibration_data_per_freq
+ cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
+ cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+
+ /* power calibration data */
+ struct ar9170_calibration_target_power_legacy
+ cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
+ struct ar9170_calibration_target_power_ht
+ cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
+ cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
+
+ struct ar9170_calibration_target_power_legacy
+ cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
+ cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+ struct ar9170_calibration_target_power_ht
+ cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
+ cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+
+ /* conformance testing limits */
+ u8 ctl_index[AR5416_NUM_CTLS];
+ struct ar9170_calctl_data
+ ctl_data[AR5416_NUM_CTLS];
+
+ u8 pad;
+ __le16 subsystem_id;
+} __packed;
+
+#define AR9170_LED_MODE_POWER_ON 0x0001
+#define AR9170_LED_MODE_RESERVED 0x0002
+#define AR9170_LED_MODE_DISABLE_STATE 0x0004
+#define AR9170_LED_MODE_OFF_IN_PSM 0x0008
+
+/* AR9170_LED_MODE BIT is set */
+#define AR9170_LED_MODE_FREQUENCY_S 4
+#define AR9170_LED_MODE_FREQUENCY 0x0030
+#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000
+#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010
+#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020
+#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030
+
+/* AR9170_LED_MODE BIT is not set */
+#define AR9170_LED_MODE_CONN_STATE_S 4
+#define AR9170_LED_MODE_CONN_STATE 0x0030
+#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000
+#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010
+/* Idle off / Active on */
+#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020
+/* Idle on / Active off */
+#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010
+
+#define AR9170_LED_MODE_MODE 0x0040
+#define AR9170_LED_MODE_RESERVED2 0x0080
+
+#define AR9170_LED_MODE_TON_SCAN_S 8
+#define AR9170_LED_MODE_TON_SCAN 0x0f00
+
+#define AR9170_LED_MODE_TOFF_SCAN_S 12
+#define AR9170_LED_MODE_TOFF_SCAN 0xf000
+
+struct ar9170_led_mode {
+ __le16 led;
+};
+
+#endif /* __CARL9170_SHARED_EEPROM_H */
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
new file mode 100644
index 000000000000..36615462b87a
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -0,0 +1,395 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * firmware parser
+ *
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/crc32.h>
+#include "carl9170.h"
+#include "fwcmd.h"
+#include "version.h"
+
+#define MAKE_STR(symbol) #symbol
+#define TO_STR(symbol) MAKE_STR(symbol)
+#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER)
+MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT);
+
+static const u8 otus_magic[4] = { OTUS_MAGIC };
+
+static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4],
+ const unsigned int len, const u8 compatible_revision)
+{
+ const struct carl9170fw_desc_head *iter;
+
+ carl9170fw_for_each_hdr(iter, ar->fw.desc) {
+ if (carl9170fw_desc_cmp(iter, descid, len,
+ compatible_revision))
+ return (void *)iter;
+ }
+
+ /* needed to find the LAST desc */
+ if (carl9170fw_desc_cmp(iter, descid, len,
+ compatible_revision))
+ return (void *)iter;
+
+ return NULL;
+}
+
+static int carl9170_fw_verify_descs(struct ar9170 *ar,
+ const struct carl9170fw_desc_head *head, unsigned int max_len)
+{
+ const struct carl9170fw_desc_head *pos;
+ unsigned long pos_addr, end_addr;
+ unsigned int pos_length;
+
+ if (max_len < sizeof(*pos))
+ return -ENODATA;
+
+ max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len);
+
+ pos = head;
+ pos_addr = (unsigned long) pos;
+ end_addr = pos_addr + max_len;
+
+ while (pos_addr < end_addr) {
+ if (pos_addr + sizeof(*head) > end_addr)
+ return -E2BIG;
+
+ pos_length = le16_to_cpu(pos->length);
+
+ if (pos_length < sizeof(*head))
+ return -EBADMSG;
+
+ if (pos_length > max_len)
+ return -EOVERFLOW;
+
+ if (pos_addr + pos_length > end_addr)
+ return -EMSGSIZE;
+
+ if (carl9170fw_desc_cmp(pos, LAST_MAGIC,
+ CARL9170FW_LAST_DESC_SIZE,
+ CARL9170FW_LAST_DESC_CUR_VER))
+ return 0;
+
+ pos_addr += pos_length;
+ pos = (void *)pos_addr;
+ max_len -= pos_length;
+ }
+ return -EINVAL;
+}
+
+static void carl9170_fw_info(struct ar9170 *ar)
+{
+ const struct carl9170fw_motd_desc *motd_desc;
+ unsigned int str_ver_len;
+ u32 fw_date;
+
+ dev_info(&ar->udev->dev, "driver API: %s 2%03d-%02d-%02d [%d-%d]\n",
+ CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR,
+ CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY,
+ CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER);
+
+ motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC,
+ sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER);
+
+ if (motd_desc) {
+ str_ver_len = strnlen(motd_desc->release,
+ CARL9170FW_MOTD_RELEASE_LEN);
+
+ fw_date = le32_to_cpu(motd_desc->fw_year_month_day);
+
+ dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n",
+ str_ver_len, motd_desc->release,
+ CARL9170FW_GET_YEAR(fw_date),
+ CARL9170FW_GET_MONTH(fw_date),
+ CARL9170FW_GET_DAY(fw_date));
+
+ strlcpy(ar->hw->wiphy->fw_version, motd_desc->release,
+ sizeof(ar->hw->wiphy->fw_version));
+ }
+}
+
+static bool valid_dma_addr(const u32 address)
+{
+ if (address >= AR9170_SRAM_OFFSET &&
+ address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE))
+ return true;
+
+ return false;
+}
+
+static bool valid_cpu_addr(const u32 address)
+{
+ if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET &&
+ address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE)))
+ return true;
+
+ return false;
+}
+
+static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
+{
+ const struct carl9170fw_otus_desc *otus_desc;
+ const struct carl9170fw_chk_desc *chk_desc;
+ const struct carl9170fw_last_desc *last_desc;
+
+ last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
+ sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
+ if (!last_desc)
+ return -EINVAL;
+
+ otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC,
+ sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER);
+ if (!otus_desc) {
+ dev_err(&ar->udev->dev, "failed to find compatible firmware "
+ "descriptor.\n");
+ return -ENODATA;
+ }
+
+ chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC,
+ sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER);
+
+ if (chk_desc) {
+ unsigned long fin, diff;
+ unsigned int dsc_len;
+ u32 crc32;
+
+ dsc_len = min_t(unsigned int, len,
+ (unsigned long)chk_desc - (unsigned long)otus_desc);
+
+ fin = (unsigned long) last_desc + sizeof(*last_desc);
+ diff = fin - (unsigned long) otus_desc;
+
+ if (diff < len)
+ len -= diff;
+
+ if (len < 256)
+ return -EIO;
+
+ crc32 = crc32_le(~0, data, len);
+ if (cpu_to_le32(crc32) != chk_desc->fw_crc32) {
+ dev_err(&ar->udev->dev, "fw checksum test failed.\n");
+ return -ENOEXEC;
+ }
+
+ crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len);
+ if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) {
+ dev_err(&ar->udev->dev, "descriptor check failed.\n");
+ return -EINVAL;
+ }
+ } else {
+ dev_warn(&ar->udev->dev, "Unprotected firmware image.\n");
+ }
+
+#define SUPP(feat) \
+ (carl9170fw_supports(otus_desc->feature_set, feat))
+
+ if (!SUPP(CARL9170FW_DUMMY_FEATURE)) {
+ dev_err(&ar->udev->dev, "invalid firmware descriptor "
+ "format detected.\n");
+ return -EINVAL;
+ }
+
+ ar->fw.api_version = otus_desc->api_ver;
+
+ if (ar->fw.api_version < CARL9170FW_API_MIN_VER ||
+ ar->fw.api_version > CARL9170FW_API_MAX_VER) {
+ dev_err(&ar->udev->dev, "unsupported firmware api version.\n");
+ return -EINVAL;
+ }
+
+ if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) ||
+ !SUPP(CARL9170FW_HANDLE_BACK_REQ)) {
+ dev_err(&ar->udev->dev, "firmware does support "
+ "mandatory features.\n");
+ return -ECANCELED;
+ }
+
+ if (ilog2(le32_to_cpu(otus_desc->feature_set)) >=
+ __CARL9170FW_FEATURE_NUM) {
+ dev_warn(&ar->udev->dev, "driver does not support all "
+ "firmware features.\n");
+ }
+
+ if (!SUPP(CARL9170FW_COMMAND_CAM)) {
+ dev_info(&ar->udev->dev, "crypto offloading is disabled "
+ "by firmware.\n");
+ ar->disable_offload = true;
+ }
+
+ if (SUPP(CARL9170FW_PSM))
+ ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS;
+
+ if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) {
+ dev_err(&ar->udev->dev, "firmware does not provide "
+ "mandatory interfaces.\n");
+ return -EINVAL;
+ }
+
+ if (SUPP(CARL9170FW_MINIBOOT))
+ ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size);
+ else
+ ar->fw.offset = 0;
+
+ if (SUPP(CARL9170FW_USB_DOWN_STREAM)) {
+ ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream);
+ ar->fw.tx_stream = true;
+ }
+
+ if (SUPP(CARL9170FW_USB_UP_STREAM))
+ ar->fw.rx_stream = true;
+
+ ar->fw.vif_num = otus_desc->vif_num;
+ ar->fw.cmd_bufs = otus_desc->cmd_bufs;
+ ar->fw.address = le32_to_cpu(otus_desc->fw_address);
+ ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len);
+ ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe);
+ atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks);
+ ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len);
+
+ if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num ||
+ ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs ||
+ ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 ||
+ ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 ||
+ !valid_cpu_addr(ar->fw.address)) {
+ dev_err(&ar->udev->dev, "firmware shows obvious signs of "
+ "malicious tampering.\n");
+ return -EINVAL;
+ }
+
+ ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr);
+ ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len);
+
+ if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >=
+ AR9170_MAC_BCN_LENGTH_MAX) {
+ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+
+ if (SUPP(CARL9170FW_WLANTX_CAB)) {
+ ar->hw->wiphy->interface_modes |=
+ BIT(NL80211_IFTYPE_AP);
+ }
+ }
+
+#undef SUPPORTED
+ return 0;
+}
+
+static struct carl9170fw_desc_head *
+carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len)
+
+{
+ int scan = 0, found = 0;
+
+ if (!carl9170fw_size_check(len)) {
+ dev_err(&ar->udev->dev, "firmware size is out of bound.\n");
+ return NULL;
+ }
+
+ while (scan < len - sizeof(struct carl9170fw_desc_head)) {
+ if (fw_data[scan++] == otus_magic[found])
+ found++;
+ else
+ found = 0;
+
+ if (scan >= len)
+ break;
+
+ if (found == sizeof(otus_magic))
+ break;
+ }
+
+ if (found != sizeof(otus_magic))
+ return NULL;
+
+ return (void *)&fw_data[scan - found];
+}
+
+int carl9170_fw_fix_eeprom(struct ar9170 *ar)
+{
+ const struct carl9170fw_fix_desc *fix_desc = NULL;
+ unsigned int i, n, off;
+ u32 *data = (void *)&ar->eeprom;
+
+ fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC,
+ sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER);
+
+ if (!fix_desc)
+ return 0;
+
+ n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) /
+ sizeof(struct carl9170fw_fix_entry);
+
+ for (i = 0; i < n; i++) {
+ off = le32_to_cpu(fix_desc->data[i].address) -
+ AR9170_EEPROM_START;
+
+ if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) {
+ dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i);
+ continue;
+ }
+
+ data[off / sizeof(*data)] &=
+ le32_to_cpu(fix_desc->data[i].mask);
+ data[off / sizeof(*data)] |=
+ le32_to_cpu(fix_desc->data[i].value);
+ }
+
+ return 0;
+}
+
+int carl9170_parse_firmware(struct ar9170 *ar)
+{
+ const struct carl9170fw_desc_head *fw_desc = NULL;
+ const struct firmware *fw = ar->fw.fw;
+ unsigned long header_offset = 0;
+ int err;
+
+ if (WARN_ON(!fw))
+ return -EINVAL;
+
+ fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size);
+
+ if (!fw_desc) {
+ dev_err(&ar->udev->dev, "unsupported firmware.\n");
+ return -ENODATA;
+ }
+
+ header_offset = (unsigned long)fw_desc - (unsigned long)fw->data;
+
+ err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset);
+ if (err) {
+ dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err);
+ return err;
+ }
+
+ ar->fw.desc = fw_desc;
+
+ carl9170_fw_info(ar);
+
+ err = carl9170_fw(ar, fw->data, fw->size);
+ if (err) {
+ dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n",
+ err);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
new file mode 100644
index 000000000000..d4a4e1dbef06
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -0,0 +1,268 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Firmware command interface definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CARL9170_SHARED_FWCMD_H
+#define __CARL9170_SHARED_FWCMD_H
+
+#define CARL9170_MAX_CMD_LEN 64
+#define CARL9170_MAX_CMD_PAYLOAD_LEN 60
+
+#define CARL9170FW_API_MIN_VER 1
+#define CARL9170FW_API_MAX_VER 1
+
+enum carl9170_cmd_oids {
+ CARL9170_CMD_RREG = 0x00,
+ CARL9170_CMD_WREG = 0x01,
+ CARL9170_CMD_ECHO = 0x02,
+ CARL9170_CMD_SWRST = 0x03,
+ CARL9170_CMD_REBOOT = 0x04,
+ CARL9170_CMD_BCN_CTRL = 0x05,
+ CARL9170_CMD_READ_TSF = 0x06,
+
+ /* CAM */
+ CARL9170_CMD_EKEY = 0x10,
+ CARL9170_CMD_DKEY = 0x11,
+
+ /* RF / PHY */
+ CARL9170_CMD_FREQUENCY = 0x20,
+ CARL9170_CMD_RF_INIT = 0x21,
+ CARL9170_CMD_SYNTH = 0x22,
+ CARL9170_CMD_FREQ_START = 0x23,
+ CARL9170_CMD_PSM = 0x24,
+
+ /* Asychronous command flag */
+ CARL9170_CMD_ASYNC_FLAG = 0x40,
+ CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL |
+ CARL9170_CMD_ASYNC_FLAG),
+ CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM |
+ CARL9170_CMD_ASYNC_FLAG),
+
+ /* responses and traps */
+ CARL9170_RSP_FLAG = 0xc0,
+ CARL9170_RSP_PRETBTT = 0xc0,
+ CARL9170_RSP_TXCOMP = 0xc1,
+ CARL9170_RSP_BEACON_CONFIG = 0xc2,
+ CARL9170_RSP_ATIM = 0xc3,
+ CARL9170_RSP_WATCHDOG = 0xc6,
+ CARL9170_RSP_TEXT = 0xca,
+ CARL9170_RSP_HEXDUMP = 0xcc,
+ CARL9170_RSP_RADAR = 0xcd,
+ CARL9170_RSP_GPIO = 0xce,
+ CARL9170_RSP_BOOT = 0xcf,
+};
+
+struct carl9170_set_key_cmd {
+ __le16 user;
+ __le16 keyId;
+ __le16 type;
+ u8 macAddr[6];
+ u32 key[4];
+} __packed;
+#define CARL9170_SET_KEY_CMD_SIZE 28
+
+struct carl9170_disable_key_cmd {
+ __le16 user;
+ __le16 padding;
+} __packed;
+#define CARL9170_DISABLE_KEY_CMD_SIZE 4
+
+struct carl9170_u32_list {
+ u32 vals[0];
+} __packed;
+
+struct carl9170_reg_list {
+ __le32 regs[0];
+} __packed;
+
+struct carl9170_write_reg {
+ struct {
+ __le32 addr;
+ __le32 val;
+ } regs[0] __packed;
+} __packed;
+
+#define CARL9170FW_PHY_HT_ENABLE 0x4
+#define CARL9170FW_PHY_HT_DYN2040 0x8
+#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3
+#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2
+
+struct carl9170_rf_init {
+ __le32 freq;
+ u8 ht_settings;
+ u8 padding2[3];
+ __le32 delta_slope_coeff_exp;
+ __le32 delta_slope_coeff_man;
+ __le32 delta_slope_coeff_exp_shgi;
+ __le32 delta_slope_coeff_man_shgi;
+ __le32 finiteLoopCount;
+} __packed;
+#define CARL9170_RF_INIT_SIZE 28
+
+struct carl9170_rf_init_result {
+ __le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */
+} __packed;
+#define CARL9170_RF_INIT_RESULT_SIZE 4
+
+#define CARL9170_PSM_SLEEP 0x1000
+#define CARL9170_PSM_SOFTWARE 0
+#define CARL9170_PSM_WAKE 0 /* internally used. */
+#define CARL9170_PSM_COUNTER 0xfff
+#define CARL9170_PSM_COUNTER_S 0
+
+struct carl9170_psm {
+ __le32 state;
+} __packed;
+#define CARL9170_PSM_SIZE 4
+
+struct carl9170_bcn_ctrl_cmd {
+ __le32 vif_id;
+ __le32 mode;
+ __le32 bcn_addr;
+ __le32 bcn_len;
+} __packed;
+#define CARL9170_BCN_CTRL_CMD_SIZE 16
+
+#define CARL9170_BCN_CTRL_DRAIN 0
+#define CARL9170_BCN_CTRL_CAB_TRIGGER 1
+
+struct carl9170_cmd_head {
+ union {
+ struct {
+ u8 len;
+ u8 cmd;
+ u8 seq;
+ u8 ext;
+ } __packed;
+
+ u32 hdr_data;
+ } __packed;
+} __packed;
+
+struct carl9170_cmd {
+ struct carl9170_cmd_head hdr;
+ union {
+ struct carl9170_set_key_cmd setkey;
+ struct carl9170_disable_key_cmd disablekey;
+ struct carl9170_u32_list echo;
+ struct carl9170_reg_list rreg;
+ struct carl9170_write_reg wreg;
+ struct carl9170_rf_init rf_init;
+ struct carl9170_psm psm;
+ struct carl9170_bcn_ctrl_cmd bcn_ctrl;
+ u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
+ } __packed;
+} __packed;
+
+#define CARL9170_TX_STATUS_QUEUE 3
+#define CARL9170_TX_STATUS_QUEUE_S 0
+#define CARL9170_TX_STATUS_RIX_S 2
+#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S)
+#define CARL9170_TX_STATUS_TRIES_S 4
+#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
+#define CARL9170_TX_STATUS_SUCCESS 0x80
+
+/*
+ * NOTE:
+ * Both structs [carl9170_tx_status and _carl9170_tx_status]
+ * need to be "bit for bit" in sync.
+ */
+struct carl9170_tx_status {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 cookie;
+ u8 queue:2;
+ u8 rix:2;
+ u8 tries:3;
+ u8 success:1;
+} __packed;
+struct _carl9170_tx_status {
+ /*
+ * This version should be immune to all alignment bugs.
+ */
+
+ u8 cookie;
+ u8 info;
+} __packed;
+#define CARL9170_TX_STATUS_SIZE 2
+
+#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \
+ sizeof(struct _carl9170_tx_status))
+
+#define CARL9170_TX_MAX_RATE_TRIES 7
+
+#define CARL9170_TX_MAX_RATES 4
+#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1)
+#define CARL9170_ERR_MAGIC "ERR:"
+#define CARL9170_BUG_MAGIC "BUG:"
+
+struct carl9170_gpio {
+ __le32 gpio;
+} __packed;
+#define CARL9170_GPIO_SIZE 4
+
+struct carl9170_tsf_rsp {
+ union {
+ __le32 tsf[2];
+ __le64 tsf_64;
+ } __packed;
+} __packed;
+#define CARL9170_TSF_RSP_SIZE 8
+
+struct carl9170_rsp {
+ struct carl9170_cmd_head hdr;
+
+ union {
+ struct carl9170_rf_init_result rf_init_res;
+ struct carl9170_u32_list rreg_res;
+ struct carl9170_u32_list echo;
+ struct carl9170_tx_status tx_status[0];
+ struct _carl9170_tx_status _tx_status[0];
+ struct carl9170_gpio gpio;
+ struct carl9170_tsf_rsp tsf;
+ struct carl9170_psm psm;
+ u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
+ } __packed;
+} __packed;
+
+#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
new file mode 100644
index 000000000000..7cd811708fe5
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -0,0 +1,237 @@
+/*
+ * Shared CARL9170 Header
+ *
+ * Firmware descriptor format
+ *
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ */
+
+#ifndef __CARL9170_SHARED_FWDESC_H
+#define __CARL9170_SHARED_FWDESC_H
+
+/* NOTE: Don't mess with the order of the flags! */
+enum carl9170fw_feature_list {
+ /* Always set */
+ CARL9170FW_DUMMY_FEATURE,
+
+ /*
+ * Indicates that this image has special boot block which prevents
+ * legacy drivers to drive the firmware.
+ */
+ CARL9170FW_MINIBOOT,
+
+ /* usb registers are initialized by the firmware */
+ CARL9170FW_USB_INIT_FIRMWARE,
+
+ /* command traps & notifications are send through EP2 */
+ CARL9170FW_USB_RESP_EP2,
+
+ /* usb download (app -> fw) stream */
+ CARL9170FW_USB_DOWN_STREAM,
+
+ /* usb upload (fw -> app) stream */
+ CARL9170FW_USB_UP_STREAM,
+
+ /* unusable - reserved to flag non-functional debug firmwares */
+ CARL9170FW_UNUSABLE,
+
+ /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */
+ CARL9170FW_COMMAND_PHY,
+
+ /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */
+ CARL9170FW_COMMAND_CAM,
+
+ /* Firmware has a software Content After Beacon Queueing mechanism */
+ CARL9170FW_WLANTX_CAB,
+
+ /* The firmware is capable of responding to incoming BAR frames */
+ CARL9170FW_HANDLE_BACK_REQ,
+
+ /* GPIO Interrupt | CARL9170_RSP_GPIO */
+ CARL9170FW_GPIO_INTERRUPT,
+
+ /* Firmware PSM support | CARL9170_CMD_PSM */
+ CARL9170FW_PSM,
+
+ /* KEEP LAST */
+ __CARL9170FW_FEATURE_NUM
+};
+
+#define OTUS_MAGIC "OTAR"
+#define MOTD_MAGIC "MOTD"
+#define FIX_MAGIC "FIX\0"
+#define DBG_MAGIC "DBG\0"
+#define CHK_MAGIC "CHK\0"
+#define LAST_MAGIC "LAST"
+
+#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31)
+#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31)
+#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372)
+
+#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1)
+#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1)
+#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10)
+
+struct carl9170fw_desc_head {
+ u8 magic[4];
+ __le16 length;
+ u8 min_ver;
+ u8 cur_ver;
+} __packed;
+#define CARL9170FW_DESC_HEAD_SIZE \
+ (sizeof(struct carl9170fw_desc_head))
+
+#define CARL9170FW_OTUS_DESC_MIN_VER 6
+#define CARL9170FW_OTUS_DESC_CUR_VER 6
+struct carl9170fw_otus_desc {
+ struct carl9170fw_desc_head head;
+ __le32 feature_set;
+ __le32 fw_address;
+ __le32 bcn_addr;
+ __le16 bcn_len;
+ __le16 miniboot_size;
+ __le16 tx_frag_len;
+ __le16 rx_max_frame_len;
+ u8 tx_descs;
+ u8 cmd_bufs;
+ u8 api_ver;
+ u8 vif_num;
+} __packed;
+#define CARL9170FW_OTUS_DESC_SIZE \
+ (sizeof(struct carl9170fw_otus_desc))
+
+#define CARL9170FW_MOTD_STRING_LEN 24
+#define CARL9170FW_MOTD_RELEASE_LEN 20
+#define CARL9170FW_MOTD_DESC_MIN_VER 1
+#define CARL9170FW_MOTD_DESC_CUR_VER 2
+struct carl9170fw_motd_desc {
+ struct carl9170fw_desc_head head;
+ __le32 fw_year_month_day;
+ char desc[CARL9170FW_MOTD_STRING_LEN];
+ char release[CARL9170FW_MOTD_RELEASE_LEN];
+} __packed;
+#define CARL9170FW_MOTD_DESC_SIZE \
+ (sizeof(struct carl9170fw_motd_desc))
+
+#define CARL9170FW_FIX_DESC_MIN_VER 1
+#define CARL9170FW_FIX_DESC_CUR_VER 2
+struct carl9170fw_fix_entry {
+ __le32 address;
+ __le32 mask;
+ __le32 value;
+} __packed;
+
+struct carl9170fw_fix_desc {
+ struct carl9170fw_desc_head head;
+ struct carl9170fw_fix_entry data[0];
+} __packed;
+#define CARL9170FW_FIX_DESC_SIZE \
+ (sizeof(struct carl9170fw_fix_desc))
+
+#define CARL9170FW_DBG_DESC_MIN_VER 1
+#define CARL9170FW_DBG_DESC_CUR_VER 2
+struct carl9170fw_dbg_desc {
+ struct carl9170fw_desc_head head;
+
+ __le32 bogoclock_addr;
+ __le32 counter_addr;
+ __le32 rx_total_addr;
+ __le32 rx_overrun_addr;
+
+ /* Put your debugging definitions here */
+} __packed;
+#define CARL9170FW_DBG_DESC_SIZE \
+ (sizeof(struct carl9170fw_dbg_desc))
+
+#define CARL9170FW_CHK_DESC_MIN_VER 1
+#define CARL9170FW_CHK_DESC_CUR_VER 2
+struct carl9170fw_chk_desc {
+ struct carl9170fw_desc_head head;
+ __le32 fw_crc32;
+ __le32 hdr_crc32;
+} __packed;
+#define CARL9170FW_CHK_DESC_SIZE \
+ (sizeof(struct carl9170fw_chk_desc))
+
+#define CARL9170FW_LAST_DESC_MIN_VER 1
+#define CARL9170FW_LAST_DESC_CUR_VER 2
+struct carl9170fw_last_desc {
+ struct carl9170fw_desc_head head;
+} __packed;
+#define CARL9170FW_LAST_DESC_SIZE \
+ (sizeof(struct carl9170fw_fix_desc))
+
+#define CARL9170FW_DESC_MAX_LENGTH 8192
+
+#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \
+ .head = { \
+ .magic = _magic, \
+ .length = cpu_to_le16(_length), \
+ .min_ver = _min_ver, \
+ .cur_ver = _cur_ver, \
+ }
+
+static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head,
+ u8 magic[4], __le16 length,
+ u8 min_ver, u8 cur_ver)
+{
+ head->magic[0] = magic[0];
+ head->magic[1] = magic[1];
+ head->magic[2] = magic[2];
+ head->magic[3] = magic[3];
+
+ head->length = length;
+ head->min_ver = min_ver;
+ head->cur_ver = cur_ver;
+}
+
+#define carl9170fw_for_each_hdr(desc, fw_desc) \
+ for (desc = fw_desc; \
+ memcmp(desc->magic, LAST_MAGIC, 4) && \
+ le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \
+ le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \
+ desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length)))
+
+#define CHECK_HDR_VERSION(head, _min_ver) \
+ (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \
+
+static inline bool carl9170fw_supports(__le32 list, u8 feature)
+{
+ return le32_to_cpu(list) & BIT(feature);
+}
+
+static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head,
+ const u8 descid[4], u16 min_len,
+ u8 compatible_revision)
+{
+ if (descid[0] == head->magic[0] && descid[1] == head->magic[1] &&
+ descid[2] == head->magic[2] && descid[3] == head->magic[3] &&
+ !CHECK_HDR_VERSION(head, compatible_revision) &&
+ (le16_to_cpu(head->length) >= min_len))
+ return true;
+
+ return false;
+}
+
+#define CARL9170FW_MIN_SIZE 32
+#define CARL9170FW_MAX_SIZE 16384
+
+static inline bool carl9170fw_size_check(unsigned int len)
+{
+ return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE);
+}
+
+#endif /* __CARL9170_SHARED_FWDESC_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
new file mode 100644
index 000000000000..b1292ac5b703
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -0,0 +1,736 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * Register map, hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CARL9170_SHARED_HW_H
+#define __CARL9170_SHARED_HW_H
+
+/* High Speed UART */
+#define AR9170_UART_REG_BASE 0x1c0000
+
+/* Definitions of interrupt registers */
+#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000)
+#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004)
+#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010)
+#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02
+#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04
+
+#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014)
+#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018)
+#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01
+#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02
+#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10
+#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20
+#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40
+
+#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c)
+#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01
+#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02
+#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10
+#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20
+#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40
+
+#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020)
+#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01
+#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02
+#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08
+#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10
+#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20
+#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80
+
+#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024)
+#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028)
+#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c)
+#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034)
+#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038)
+#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c)
+#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c)
+
+/* Timer */
+#define AR9170_TIMER_REG_BASE 0x1c1000
+
+#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000)
+#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010)
+#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014)
+#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018)
+#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c)
+#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020)
+#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024)
+#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100
+
+#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028)
+#define AR9170_TIMER_INT_TIMER0 0x001
+#define AR9170_TIMER_INT_TIMER1 0x002
+#define AR9170_TIMER_INT_TIMER2 0x004
+#define AR9170_TIMER_INT_TIMER3 0x008
+#define AR9170_TIMER_INT_TIMER4 0x010
+#define AR9170_TIMER_INT_TICK_TIMER 0x100
+
+#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030)
+#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040)
+#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044)
+
+#define AR9170_MAC_REG_BASE 0x1c3000
+
+#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500)
+#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20
+
+#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c)
+
+#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510)
+#define AR9170_MAC_INT_TXC BIT(0)
+#define AR9170_MAC_INT_RXC BIT(1)
+#define AR9170_MAC_INT_RETRY_FAIL BIT(2)
+#define AR9170_MAC_INT_WAKEUP BIT(3)
+#define AR9170_MAC_INT_ATIM BIT(4)
+#define AR9170_MAC_INT_DTIM BIT(5)
+#define AR9170_MAC_INT_CFG_BCN BIT(6)
+#define AR9170_MAC_INT_ABORT BIT(7)
+#define AR9170_MAC_INT_QOS BIT(8)
+#define AR9170_MAC_INT_MIMO_PS BIT(9)
+#define AR9170_MAC_INT_KEY_GEN BIT(10)
+#define AR9170_MAC_INT_DECRY_NOUSER BIT(11)
+#define AR9170_MAC_INT_RADAR BIT(12)
+#define AR9170_MAC_INT_QUIET_FRAME BIT(13)
+#define AR9170_MAC_INT_PRETBTT BIT(14)
+
+#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514)
+#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518)
+
+#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51c)
+#define AR9170_MAC_ATIM_PERIOD_S 0
+#define AR9170_MAC_ATIM_PERIOD 0x0000ffff
+
+#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_BCN_PERIOD_S 0
+#define AR9170_MAC_BCN_PERIOD 0x0000ffff
+#define AR9170_MAC_BCN_DTIM_S 16
+#define AR9170_MAC_BCN_DTIM 0x00ff0000
+#define AR9170_MAC_BCN_AP_MODE BIT(24)
+#define AR9170_MAC_BCN_IBSS_MODE BIT(25)
+#define AR9170_MAC_BCN_PWR_MGT BIT(26)
+#define AR9170_MAC_BCN_STA_PS BIT(27)
+
+#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
+#define AR9170_MAC_PRETBTT_S 0
+#define AR9170_MAC_PRETBTT 0x0000ffff
+#define AR9170_MAC_PRETBTT2_S 16
+#define AR9170_MAC_PRETBTT2 0xffff0000
+
+#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610)
+#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614)
+#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618)
+#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c)
+
+#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624)
+#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628)
+
+#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62c)
+
+#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630)
+#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634)
+#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638)
+#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c)
+#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640)
+#define AR9170_MAC_REG_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648)
+#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64c)
+
+#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658)
+#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674)
+#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0)
+#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000
+#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
+#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3)
+#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70
+
+#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684)
+#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688)
+
+#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c)
+#define AR9170_MAC_FTF_ASSOC_REQ BIT(0)
+#define AR9170_MAC_FTF_ASSOC_RESP BIT(1)
+#define AR9170_MAC_FTF_REASSOC_REQ BIT(2)
+#define AR9170_MAC_FTF_REASSOC_RESP BIT(3)
+#define AR9170_MAC_FTF_PRB_REQ BIT(4)
+#define AR9170_MAC_FTF_PRB_RESP BIT(5)
+#define AR9170_MAC_FTF_BIT6 BIT(6)
+#define AR9170_MAC_FTF_BIT7 BIT(7)
+#define AR9170_MAC_FTF_BEACON BIT(8)
+#define AR9170_MAC_FTF_ATIM BIT(9)
+#define AR9170_MAC_FTF_DEASSOC BIT(10)
+#define AR9170_MAC_FTF_AUTH BIT(11)
+#define AR9170_MAC_FTF_DEAUTH BIT(12)
+#define AR9170_MAC_FTF_BIT13 BIT(13)
+#define AR9170_MAC_FTF_BIT14 BIT(14)
+#define AR9170_MAC_FTF_BIT15 BIT(15)
+#define AR9170_MAC_FTF_BAR BIT(24)
+#define AR9170_MAC_FTF_BA BIT(25)
+#define AR9170_MAC_FTF_PSPOLL BIT(26)
+#define AR9170_MAC_FTF_RTS BIT(27)
+#define AR9170_MAC_FTF_CTS BIT(28)
+#define AR9170_MAC_FTF_ACK BIT(29)
+#define AR9170_MAC_FTF_CFE BIT(30)
+#define AR9170_MAC_FTF_CFE_ACK BIT(31)
+#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff
+#define AR9170_MAC_FTF_MONITOR 0xff00ffff
+
+#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694)
+#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
+#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c)
+#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6a0)
+#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6a4)
+#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6a8)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6ac)
+#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6b0)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6bc)
+#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0)
+#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4)
+#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8)
+#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc)
+
+#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4)
+
+#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8)
+#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec)
+
+#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0)
+#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4)
+#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8)
+
+#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700)
+#define AR9170_MAC_CAM_IBSS 0xe0
+#define AR9170_MAC_CAM_AP 0xa1
+#define AR9170_MAC_CAM_STA 0x2
+#define AR9170_MAC_CAM_AP_WDS 0x3
+#define AR9170_MAC_CAM_DEFAULTS (0xf << 24)
+#define AR9170_MAC_CAM_HOST_PENDING 0x80000000
+
+#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c)
+#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000
+#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720)
+#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724)
+#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728)
+#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c)
+
+#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730)
+#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734)
+#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738)
+#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c)
+#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000
+#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000
+
+#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740)
+#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750)
+
+#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760)
+#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770)
+#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780)
+#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790)
+
+#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xb00)
+#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xb04)
+#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xb08)
+#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xb0c)
+#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xb10)
+#define AR9170_MAC_REG_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14)
+#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18)
+#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c)
+#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20)
+#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24)
+#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28)
+#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c)
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30)
+#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34)
+#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38)
+#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c)
+#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40)
+#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15)
+#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16)
+#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17)
+#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18)
+#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19)
+#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000)
+
+#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xb44)
+#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xb48)
+
+#define AR9170_MAC_REG_AMPDU_COUNT (AR9170_MAC_REG_BASE + 0xb88)
+#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c)
+
+#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c)
+#define AR9170_MAC_AMPDU_FACTOR 0x7f0000
+#define AR9170_MAC_AMPDU_FACTOR_S 16
+#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0)
+#define AR9170_MAC_AMPDU_DENSITY 0x7
+#define AR9170_MAC_AMPDU_DENSITY_S 0
+
+#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xbb0)
+#define AR9170_MAC_FCS_SWFCS 0x1
+#define AR9170_MAC_FCS_FIFO_PROT 0x4
+
+#define AR9170_MAC_REG_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4)
+#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8)
+
+#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00)
+#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40)
+#define AR9170_MAC_RX_CTRL_DEAGG 0x1
+#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2
+#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20
+#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28)
+#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30)
+
+#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44)
+
+#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50)
+
+#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0)
+#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4)
+#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8)
+#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac)
+#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0)
+#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4)
+#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8)
+#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc)
+#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0)
+
+#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00)
+#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04)
+#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00)
+#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04)
+#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08)
+#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c)
+#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10)
+#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14)
+#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18)
+#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c)
+#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20)
+#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24)
+#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28)
+#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c)
+
+#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30)
+#define AR9170_DMA_TRIGGER_TXQ0 BIT(0)
+#define AR9170_DMA_TRIGGER_TXQ1 BIT(1)
+#define AR9170_DMA_TRIGGER_TXQ2 BIT(2)
+#define AR9170_DMA_TRIGGER_TXQ3 BIT(3)
+#define AR9170_DMA_TRIGGER_TXQ4 BIT(4)
+#define AR9170_DMA_TRIGGER_RXQ BIT(8)
+
+#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38)
+#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c)
+
+#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c)
+#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
+#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0
+#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
+#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000
+
+#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84)
+#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88)
+#define AR9170_MAC_BCN_LENGTH_MAX 256
+
+#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c)
+
+#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90)
+#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94)
+#define AR9170_BCN_CTRL_READY 0x01
+#define AR9170_BCN_CTRL_LOCK 0x02
+
+#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98)
+#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c)
+
+
+#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0)
+#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4)
+
+#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0)
+
+/* Random number generator */
+#define AR9170_RAND_REG_BASE 0x1d0000
+
+#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000)
+#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004)
+#define AR9170_RAND_MODE_MANUAL 0x000
+#define AR9170_RAND_MODE_FREE 0x001
+
+/* GPIO */
+#define AR9170_GPIO_REG_BASE 0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000)
+#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004)
+#define AR9170_GPIO_PORT_LED_0 1
+#define AR9170_GPIO_PORT_LED_1 2
+/* WPS Button GPIO for TP-Link TL-WN821N */
+#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4
+
+/* Memory Controller */
+#define AR9170_MC_REG_BASE 0x1d1000
+
+#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000)
+#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400)
+#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404)
+#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408)
+
+/* Interrupt Controller */
+#define AR9170_MAX_INT_SRC 9
+#define AR9170_INT_REG_BASE 0x1d2000
+
+#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000)
+#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004)
+#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008)
+/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */
+#define AR9170_INT_FLAG_WLAN 0x001
+#define AR9170_INT_FLAG_PTAB_BIT 0x002
+#define AR9170_INT_FLAG_SE_BIT 0x004
+#define AR9170_INT_FLAG_UART_BIT 0x008
+#define AR9170_INT_FLAG_TIMER_BIT 0x010
+#define AR9170_INT_FLAG_EXT_BIT 0x020
+#define AR9170_INT_FLAG_SW_BIT 0x040
+#define AR9170_INT_FLAG_USB_BIT 0x080
+#define AR9170_INT_FLAG_ETHERNET_BIT 0x100
+
+#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c)
+#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010)
+#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014)
+#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018)
+#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c)
+#define AR9170_INT_SW_INT_ENABLE 0x1
+
+#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020)
+#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024)
+
+/* Power Management */
+#define AR9170_PWR_REG_BASE 0x1d4000
+
+#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000)
+
+#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004)
+#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0)
+#define AR9170_PWR_RESET_WLAN_MASK BIT(1)
+#define AR9170_PWR_RESET_DMA_MASK BIT(2)
+#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3)
+#define AR9170_PWR_RESET_AHB_MASK BIT(9)
+#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10)
+#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11)
+#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12)
+#define AR9170_PWR_RESET_PLL BIT(13)
+#define AR9170_PWR_RESET_USB_PLL BIT(14)
+
+#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008)
+#define AR9170_PWR_CLK_AHB_40MHZ 0
+#define AR9170_PWR_CLK_AHB_20_22MHZ 1
+#define AR9170_PWR_CLK_AHB_40_44MHZ 2
+#define AR9170_PWR_CLK_AHB_80_88MHZ 3
+#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70
+
+#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010)
+#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014)
+#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020)
+
+/* Faraday USB Controller */
+#define AR9170_USB_REG_BASE 0x1e1000
+
+#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000)
+#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0)
+#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2)
+#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6)
+
+#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001)
+#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7)
+
+#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002)
+#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008)
+#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b)
+#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c)
+#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c)
+#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d)
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011)
+#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012)
+#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013)
+#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014)
+#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015)
+#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6))
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016)
+#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017)
+#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6)
+
+#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018)
+
+#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020)
+
+#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021)
+#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022)
+#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023)
+#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024)
+#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025)
+#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026)
+#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027)
+#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028)
+
+#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030)
+#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030)
+#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031)
+#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032)
+#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033)
+#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034)
+#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035)
+#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036)
+#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037)
+#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038)
+#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039)
+
+#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f)
+#define AR9170_USB_EP_IN_TOGGLE 0x10
+
+#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e)
+
+#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f)
+#define AR9170_USB_EP_OUT_TOGGLE 0x10
+
+#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e)
+
+#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae)
+#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be)
+#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af)
+#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf)
+
+#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080)
+#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080)
+#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081)
+#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082)
+#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083)
+#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084)
+#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085)
+#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086)
+#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087)
+#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088)
+#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089)
+
+#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090)
+#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090)
+#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091)
+#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092)
+#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093)
+#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094)
+#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095)
+#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096)
+#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097)
+#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098)
+#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099)
+
+#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8)
+#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc)
+
+#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100)
+#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
+#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0)
+#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1)
+#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2)
+#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3)
+#define AR9170_USB_DMA_CTL_UP_STREAM_S 4
+#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5))
+#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0)
+#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4)
+#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5)
+#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5))
+#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6)
+
+#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c)
+#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8)
+#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16)
+
+#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110)
+#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114)
+#define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0)
+#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1))
+
+/* PCI/USB to AHB Bridge */
+#define AR9170_PTA_REG_BASE 0x1e2000
+
+#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000)
+#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004)
+#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008)
+#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c)
+#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010)
+#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014)
+#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018)
+#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c)
+#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020)
+#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024)
+#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028)
+#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030)
+#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034)
+#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038)
+#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c)
+
+#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124)
+
+/*
+ * PCI to AHB Bridge
+ */
+
+#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100)
+#define AR9170_PTA_INT_FLAG_DN 0x01
+#define AR9170_PTA_INT_FLAG_UP 0x02
+#define AR9170_PTA_INT_FLAG_CMD 0x04
+
+#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104)
+#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108)
+#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c)
+#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110)
+#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114)
+#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118)
+#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c)
+#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120)
+#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00
+#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01
+#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02
+#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10
+
+#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124)
+#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128)
+#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c)
+#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130)
+#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134)
+#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138)
+#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c)
+#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140)
+#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144)
+#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148)
+#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0)
+#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1)
+
+/* Protocol Controller Module */
+#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00)
+
+
+#define AR9170_NUM_LEDS 2
+
+/* CAM */
+#define AR9170_CAM_MAX_USER 64
+#define AR9170_CAM_MAX_KEY_LENGTH 16
+
+#define AR9170_SRAM_OFFSET 0x100000
+#define AR9170_SRAM_SIZE 0x18000
+
+#define AR9170_PRAM_OFFSET 0x200000
+#define AR9170_PRAM_SIZE 0x8000
+
+enum cpu_clock {
+ AHB_STATIC_40MHZ = 0,
+ AHB_GMODE_22MHZ = 1,
+ AHB_AMODE_20MHZ = 1,
+ AHB_GMODE_44MHZ = 2,
+ AHB_AMODE_40MHZ = 2,
+ AHB_GMODE_88MHZ = 3,
+ AHB_AMODE_80MHZ = 3
+};
+
+/* USB endpoints */
+enum ar9170_usb_ep {
+ /*
+ * Control EP is always EP 0 (USB SPEC)
+ *
+ * The weird thing is: the original firmware has a few
+ * comments that suggest that the actual EP numbers
+ * are in the 1 to 10 range?!
+ */
+ AR9170_USB_EP_CTRL = 0,
+
+ AR9170_USB_EP_TX,
+ AR9170_USB_EP_RX,
+ AR9170_USB_EP_IRQ,
+ AR9170_USB_EP_CMD,
+ AR9170_USB_NUM_EXTRA_EP = 4,
+
+ __AR9170_USB_NUM_EP,
+
+ __AR9170_USB_NUM_MAX_EP = 10
+};
+
+enum ar9170_usb_fifo {
+ __AR9170_USB_NUM_MAX_FIFO = 10
+};
+
+enum ar9170_tx_queues {
+ AR9170_TXQ0 = 0,
+ AR9170_TXQ1,
+ AR9170_TXQ2,
+ AR9170_TXQ3,
+ AR9170_TXQ_SPECIAL,
+
+ /* keep last */
+ __AR9170_NUM_TX_QUEUES = 5
+};
+
+#define AR9170_TX_STREAM_TAG 0x697e
+#define AR9170_RX_STREAM_TAG 0x4e00
+#define AR9170_RX_STREAM_MAX_SIZE 0xffff
+
+struct ar9170_stream {
+ __le16 length;
+ __le16 tag;
+
+ u8 payload[0];
+};
+
+#define AR9170_MAX_ACKTABLE_ENTRIES 8
+#define AR9170_MAX_VIRTUAL_MAC 7
+
+#define AR9170_USB_EP_CTRL_MAX 64
+#define AR9170_USB_EP_TX_MAX 512
+#define AR9170_USB_EP_RX_MAX 512
+#define AR9170_USB_EP_IRQ_MAX 64
+#define AR9170_USB_EP_CMD_MAX 64
+
+/* Trigger PRETBTT interrupt 6 Kus earlier */
+#define CARL9170_PRETBTT_KUS 6
+
+#define AR5416_MAX_RATE_POWER 63
+
+#define SET_VAL(reg, value, newvalue) \
+ (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+
+#define MOD_VAL(reg, value, newvalue) \
+ (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c
new file mode 100644
index 000000000000..4bb2cbd8bd9b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/led.c
@@ -0,0 +1,190 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparer <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "carl9170.h"
+#include "cmd.h"
+
+int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state)
+{
+ return carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_DATA, led_state);
+}
+
+int carl9170_led_init(struct ar9170 *ar)
+{
+ int err;
+
+ /* disable LEDs */
+ /* GPIO [0/1 mode: output, 2/3: input] */
+ err = carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+ if (err)
+ goto out;
+
+ /* GPIO 0/1 value: off */
+ err = carl9170_led_set_state(ar, 0);
+
+out:
+ return err;
+}
+
+#ifdef CONFIG_CARL9170_LEDS
+static void carl9170_led_update(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+ int i, tmp = 300, blink_delay = 1000;
+ u32 led_val = 0;
+ bool rerun = false;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ for (i = 0; i < AR9170_NUM_LEDS; i++) {
+ if (ar->leds[i].registered) {
+ if (ar->leds[i].last_state ||
+ ar->leds[i].toggled) {
+
+ if (ar->leds[i].toggled)
+ tmp = 70 + 200 / (ar->leds[i].toggled);
+
+ if (tmp < blink_delay)
+ blink_delay = tmp;
+
+ led_val |= 1 << i;
+ ar->leds[i].toggled = 0;
+ rerun = true;
+ }
+ }
+ }
+
+ carl9170_led_set_state(ar, led_val);
+ mutex_unlock(&ar->mutex);
+
+ if (!rerun)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw,
+ &ar->led_work,
+ msecs_to_jiffies(blink_delay));
+}
+
+static void carl9170_led_set_brightness(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ struct carl9170_led *arl = container_of(led, struct carl9170_led, l);
+ struct ar9170 *ar = arl->ar;
+
+ if (!arl->registered)
+ return;
+
+ if (arl->last_state != !!brightness) {
+ arl->toggled++;
+ arl->last_state = !!brightness;
+ }
+
+ if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
+ ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
+}
+
+static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name,
+ char *trigger)
+{
+ int err;
+
+ snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+ "carl9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
+
+ ar->leds[i].ar = ar;
+ ar->leds[i].l.name = ar->leds[i].name;
+ ar->leds[i].l.brightness_set = carl9170_led_set_brightness;
+ ar->leds[i].l.brightness = 0;
+ ar->leds[i].l.default_trigger = trigger;
+
+ err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
+ &ar->leds[i].l);
+ if (err) {
+ wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
+ ar->leds[i].name, err);
+ } else {
+ ar->leds[i].registered = true;
+ }
+
+ return err;
+}
+
+void carl9170_led_unregister(struct ar9170 *ar)
+{
+ int i;
+
+ for (i = 0; i < AR9170_NUM_LEDS; i++)
+ if (ar->leds[i].registered) {
+ led_classdev_unregister(&ar->leds[i].l);
+ ar->leds[i].registered = false;
+ ar->leds[i].toggled = 0;
+ }
+
+ cancel_delayed_work_sync(&ar->led_work);
+}
+
+int carl9170_led_register(struct ar9170 *ar)
+{
+ int err;
+
+ INIT_DELAYED_WORK(&ar->led_work, carl9170_led_update);
+
+ err = carl9170_led_register_led(ar, 0, "tx",
+ ieee80211_get_tx_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ if (ar->features & CARL9170_ONE_LED)
+ return 0;
+
+ err = carl9170_led_register_led(ar, 1, "assoc",
+ ieee80211_get_assoc_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ return 0;
+
+fail:
+ carl9170_led_unregister(ar);
+ return err;
+}
+
+#endif /* CONFIG_CARL9170_LEDS */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
new file mode 100644
index 000000000000..2305bc27151c
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -0,0 +1,604 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * MAC programming
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <asm/unaligned.h>
+
+#include "carl9170.h"
+#include "cmd.h"
+
+int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
+{
+ u32 val;
+
+ if (conf_is_ht40(&ar->hw->conf))
+ val = 0x010a;
+ else {
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ val = 0x105;
+ else
+ val = 0x104;
+ }
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
+}
+
+int carl9170_set_rts_cts_rate(struct ar9170 *ar)
+{
+ u32 rts_rate, cts_rate;
+
+ if (conf_is_ht(&ar->hw->conf)) {
+ /* 12 mbit OFDM */
+ rts_rate = 0x1da;
+ cts_rate = 0x10a;
+ } else {
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ /* 11 mbit CCK */
+ rts_rate = 033;
+ cts_rate = 003;
+ } else {
+ /* 6 mbit OFDM */
+ rts_rate = 0x1bb;
+ cts_rate = 0x10b;
+ }
+ }
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
+ rts_rate | (cts_rate) << 16);
+}
+
+int carl9170_set_slot_time(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 slottime = 20;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+ if (!vif) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+ vif->bss_conf.use_short_slot)
+ slottime = 9;
+
+ rcu_read_unlock();
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
+ slottime << 10);
+}
+
+int carl9170_set_mac_rates(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 basic, mandatory;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (!vif) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ basic = (vif->bss_conf.basic_rates & 0xf);
+ basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
+ rcu_read_unlock();
+
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
+ else
+ mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
+ carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_set_qos(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+ (ar->edcf[0].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+ (ar->edcf[1].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+ (ar->edcf[2].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+ (ar->edcf[3].cw_max << 16));
+ carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+ (ar->edcf[4].cw_max << 16));
+
+ carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
+ ((ar->edcf[0].aifs * 9 + 10)) |
+ ((ar->edcf[1].aifs * 9 + 10) << 12) |
+ ((ar->edcf[2].aifs * 9 + 10) << 24));
+ carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
+ ((ar->edcf[2].aifs * 9 + 10) >> 8) |
+ ((ar->edcf[3].aifs * 9 + 10) << 4) |
+ ((ar->edcf[4].aifs * 9 + 10) << 16));
+
+ carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+ ar->edcf[0].txop | ar->edcf[1].txop << 16);
+ carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+ ar->edcf[2].txop | ar->edcf[3].txop << 16 |
+ ar->edcf[4].txop << 24);
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_init_mac(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ /* switch MAC to OTUS interface */
+ carl9170_regwrite(0x1c3600, 0x3);
+
+ carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+ carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
+
+ carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+ AR9170_MAC_FTF_MONITOR);
+
+ /* enable MMIC */
+ carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
+ AR9170_MAC_SNIFFER_DEFAULTS);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+ carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+ carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+ /* CF-END & CF-ACK rate => 24M OFDM */
+ carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
+
+ /* NAV protects ACK only (in TXOP) */
+ carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
+
+ /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+ /* OTUS set AM to 0x1 */
+ carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+ carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+ /* Aggregation MAX number and timeout */
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);
+
+ carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+ AR9170_MAC_FTF_DEFAULTS);
+
+ carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
+ AR9170_MAC_RX_CTRL_DEAGG |
+ AR9170_MAC_RX_CTRL_SHORT_FILTER);
+
+ /* rate sets */
+ carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+ carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+ carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
+
+ /* MIMO response control */
+ carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
+
+ carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+ /* set PHY register read timeout (??) */
+ carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+ /* Disable Rx TimeOut, workaround for BB. */
+ carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+ /* Set WLAN DMA interrupt mode: generate int per packet */
+ carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+ carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+ AR9170_MAC_FCS_FIFO_PROT);
+
+ /* Disables the CF_END frame, undocumented register */
+ carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+ 0x141e0f48);
+
+ /* reset group hash table */
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
+
+ /* disable PRETBTT interrupt */
+ carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
+ carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+static int carl9170_set_mac_reg(struct ar9170 *ar,
+ const u32 reg, const u8 *mac)
+{
+ static const u8 zero[ETH_ALEN] = { 0 };
+
+ if (!mac)
+ mac = zero;
+
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(reg, get_unaligned_le32(mac));
+ carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
+
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
+ const u8 *mac)
+{
+ if (WARN_ON(id >= ar->fw.vif_num))
+ return -EINVAL;
+
+ return carl9170_set_mac_reg(ar,
+ AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
+}
+
+int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
+{
+ int err;
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
+ carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ ar->cur_mc_hash = mc_hash;
+ return 0;
+}
+
+int carl9170_set_operating_mode(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ struct ath_common *common = &ar->common;
+ u8 *mac_addr, *bssid;
+ u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
+ u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS;
+ u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
+ AR9170_MAC_RX_CTRL_SHORT_FILTER;
+ u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
+ int err = 0;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (vif) {
+ mac_addr = common->macaddr;
+ bssid = common->curbssid;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ cam_mode |= AR9170_MAC_CAM_IBSS;
+ break;
+ case NL80211_IFTYPE_AP:
+ cam_mode |= AR9170_MAC_CAM_AP;
+
+ /* iwlagn 802.11n STA Workaround */
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ case NL80211_IFTYPE_WDS:
+ cam_mode |= AR9170_MAC_CAM_AP_WDS;
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ case NL80211_IFTYPE_STATION:
+ cam_mode |= AR9170_MAC_CAM_STA;
+ rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
+ break;
+ default:
+ WARN(1, "Unsupported operation mode %x\n", vif->type);
+ err = -EOPNOTSUPP;
+ break;
+ }
+ } else {
+ mac_addr = NULL;
+ bssid = NULL;
+ }
+ rcu_read_unlock();
+
+ if (err)
+ return err;
+
+ if (ar->rx_software_decryption)
+ enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
+
+ if (ar->sniffer_enabled) {
+ rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
+ sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
+ enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
+ }
+
+ err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+ if (err)
+ return err;
+
+ err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+ if (err)
+ return err;
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+ carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
+ carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
+ carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
+{
+ u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+ return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int carl9170_set_beacon_timers(struct ar9170 *ar)
+{
+ struct ieee80211_vif *vif;
+ u32 v = 0;
+ u32 pretbtt = 0;
+
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (vif) {
+ struct carl9170_vif_info *mvif;
+ mvif = (void *) vif->drv_priv;
+
+ if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
+ ar->global_beacon_int = vif->bss_conf.beacon_int /
+ ar->beacon_enabled;
+
+ SET_VAL(AR9170_MAC_BCN_DTIM, v,
+ vif->bss_conf.dtim_period);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ v |= AR9170_MAC_BCN_IBSS_MODE;
+ break;
+ case NL80211_IFTYPE_AP:
+ v |= AR9170_MAC_BCN_AP_MODE;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ } else if (vif->type == NL80211_IFTYPE_STATION) {
+ ar->global_beacon_int = vif->bss_conf.beacon_int;
+
+ SET_VAL(AR9170_MAC_BCN_DTIM, v,
+ ar->hw->conf.ps_dtim_period);
+
+ v |= AR9170_MAC_BCN_STA_PS |
+ AR9170_MAC_BCN_PWR_MGT;
+ }
+
+ if (ar->global_beacon_int) {
+ if (ar->global_beacon_int < 15) {
+ rcu_read_unlock();
+ return -ERANGE;
+ }
+
+ ar->global_pretbtt = ar->global_beacon_int -
+ CARL9170_PRETBTT_KUS;
+ } else {
+ ar->global_pretbtt = 0;
+ }
+ } else {
+ ar->global_beacon_int = 0;
+ ar->global_pretbtt = 0;
+ }
+
+ rcu_read_unlock();
+
+ SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
+ SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
+ SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
+
+ carl9170_regwrite_begin(ar);
+ carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+ carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
+{
+ struct sk_buff *skb;
+ struct carl9170_vif_info *cvif;
+ __le32 *data, *old = NULL;
+ u32 word, off, addr, len;
+ int i = 0, err = 0;
+
+ rcu_read_lock();
+ cvif = rcu_dereference(ar->beacon_iter);
+retry:
+ if (ar->vifs == 0 || !cvif)
+ goto out_unlock;
+
+ list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
+ if (cvif->active && cvif->enable_beacon)
+ goto found;
+ }
+
+ if (!ar->beacon_enabled || i++)
+ goto out_unlock;
+
+ goto retry;
+
+found:
+ rcu_assign_pointer(ar->beacon_iter, cvif);
+
+ skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
+ NULL, NULL);
+
+ if (!skb) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ spin_lock_bh(&ar->beacon_lock);
+ data = (__le32 *)skb->data;
+ if (cvif->beacon)
+ old = (__le32 *)cvif->beacon->data;
+
+ off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
+ addr = ar->fw.beacon_addr + off;
+ len = roundup(skb->len + FCS_LEN, 4);
+
+ if ((off + len) > ar->fw.beacon_max_len) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "beacon does not "
+ "fit into device memory!\n");
+ }
+
+ spin_unlock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(skb);
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (len > AR9170_MAC_BCN_LENGTH_MAX) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "no support for beacons "
+ "bigger than %d (yours:%d).\n",
+ AR9170_MAC_BCN_LENGTH_MAX, len);
+ }
+
+ spin_unlock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(skb);
+ err = -EMSGSIZE;
+ goto out_unlock;
+ }
+
+ carl9170_async_regwrite_begin(ar);
+
+ /* XXX: use skb->cb info */
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
+ } else {
+ carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + FCS_LEN) << 16) + 0x001b);
+ }
+
+ for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+ /*
+ * XXX: This accesses beyond skb data for up
+ * to the last 3 bytes!!
+ */
+
+ if (old && (data[i] == old[i]))
+ continue;
+
+ word = le32_to_cpu(data[i]);
+ carl9170_async_regwrite(addr + 4 * i, word);
+ }
+ carl9170_async_regwrite_finish();
+
+ dev_kfree_skb_any(cvif->beacon);
+ cvif->beacon = NULL;
+
+ err = carl9170_async_regwrite_result();
+ if (!err)
+ cvif->beacon = skb;
+ spin_unlock_bh(&ar->beacon_lock);
+ if (err)
+ goto out_unlock;
+
+ if (submit) {
+ err = carl9170_bcn_ctrl(ar, cvif->id,
+ CARL9170_BCN_CTRL_CAB_TRIGGER,
+ addr, skb->len + FCS_LEN);
+
+ if (err)
+ goto out_unlock;
+ }
+out_unlock:
+ rcu_read_unlock();
+ return err;
+}
+
+int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
+ const u8 ktype, const u8 keyidx, const u8 *keydata,
+ const int keylen)
+{
+ struct carl9170_set_key_cmd key = { };
+ static const u8 bcast[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ mac = mac ? : bcast;
+
+ key.user = cpu_to_le16(id);
+ key.keyId = cpu_to_le16(keyidx);
+ key.type = cpu_to_le16(ktype);
+ memcpy(&key.macAddr, mac, ETH_ALEN);
+ if (keydata)
+ memcpy(&key.key, keydata, keylen);
+
+ return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
+ sizeof(key), (u8 *)&key, 0, NULL);
+}
+
+int carl9170_disable_key(struct ar9170 *ar, const u8 id)
+{
+ struct carl9170_disable_key_cmd key = { };
+
+ key.user = cpu_to_le16(id);
+
+ return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
+ sizeof(key), (u8 *)&key, 0, NULL);
+}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
new file mode 100644
index 000000000000..ea49d54ce03b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -0,0 +1,1855 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <net/mac80211.h>
+#include <net/cfg80211.h>
+#include "hw.h"
+#include "carl9170.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload.");
+
+int modparam_noht;
+module_param_named(noht, modparam_noht, int, S_IRUGO);
+MODULE_PARM_DESC(noht, "Disable MPDU aggregation.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
+ .bitrate = (_bitrate), \
+ .flags = (_flags), \
+ .hw_value = (_hw_rate) | (_txpidx) << 4, \
+}
+
+struct ieee80211_rate __carl9170_ratetable[] = {
+ RATE(10, 0, 0, 0),
+ RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(60, 0xb, 0, 0),
+ RATE(90, 0xf, 0, 0),
+ RATE(120, 0xa, 0, 0),
+ RATE(180, 0xe, 0, 0),
+ RATE(240, 0x9, 0, 0),
+ RATE(360, 0xd, 1, 0),
+ RATE(480, 0x8, 2, 0),
+ RATE(540, 0xc, 3, 0),
+};
+#undef RATE
+
+#define carl9170_g_ratetable (__carl9170_ratetable + 0)
+#define carl9170_g_ratetable_size 12
+#define carl9170_a_ratetable (__carl9170_ratetable + 4)
+#define carl9170_a_ratetable_size 8
+
+/*
+ * NB: The hw_value is used as an index into the carl9170_phy_freq_params
+ * array in phy.c so that we don't have to do frequency lookups!
+ */
+#define CHAN(_freq, _idx) { \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 18, /* XXX */ \
+}
+
+static struct ieee80211_channel carl9170_2ghz_chantable[] = {
+ CHAN(2412, 0),
+ CHAN(2417, 1),
+ CHAN(2422, 2),
+ CHAN(2427, 3),
+ CHAN(2432, 4),
+ CHAN(2437, 5),
+ CHAN(2442, 6),
+ CHAN(2447, 7),
+ CHAN(2452, 8),
+ CHAN(2457, 9),
+ CHAN(2462, 10),
+ CHAN(2467, 11),
+ CHAN(2472, 12),
+ CHAN(2484, 13),
+};
+
+static struct ieee80211_channel carl9170_5ghz_chantable[] = {
+ CHAN(4920, 14),
+ CHAN(4940, 15),
+ CHAN(4960, 16),
+ CHAN(4980, 17),
+ CHAN(5040, 18),
+ CHAN(5060, 19),
+ CHAN(5080, 20),
+ CHAN(5180, 21),
+ CHAN(5200, 22),
+ CHAN(5220, 23),
+ CHAN(5240, 24),
+ CHAN(5260, 25),
+ CHAN(5280, 26),
+ CHAN(5300, 27),
+ CHAN(5320, 28),
+ CHAN(5500, 29),
+ CHAN(5520, 30),
+ CHAN(5540, 31),
+ CHAN(5560, 32),
+ CHAN(5580, 33),
+ CHAN(5600, 34),
+ CHAN(5620, 35),
+ CHAN(5640, 36),
+ CHAN(5660, 37),
+ CHAN(5680, 38),
+ CHAN(5700, 39),
+ CHAN(5745, 40),
+ CHAN(5765, 41),
+ CHAN(5785, 42),
+ CHAN(5805, 43),
+ CHAN(5825, 44),
+ CHAN(5170, 45),
+ CHAN(5190, 46),
+ CHAN(5210, 47),
+ CHAN(5230, 48),
+};
+#undef CHAN
+
+#define CARL9170_HT_CAP \
+{ \
+ .ht_supported = true, \
+ .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
+ IEEE80211_HT_CAP_SGI_40 | \
+ IEEE80211_HT_CAP_DSSSCCK40 | \
+ IEEE80211_HT_CAP_SM_PS, \
+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
+ .mcs = { \
+ .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
+ .rx_highest = cpu_to_le16(300), \
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
+ }, \
+}
+
+static struct ieee80211_supported_band carl9170_band_2GHz = {
+ .channels = carl9170_2ghz_chantable,
+ .n_channels = ARRAY_SIZE(carl9170_2ghz_chantable),
+ .bitrates = carl9170_g_ratetable,
+ .n_bitrates = carl9170_g_ratetable_size,
+ .ht_cap = CARL9170_HT_CAP,
+};
+
+static struct ieee80211_supported_band carl9170_band_5GHz = {
+ .channels = carl9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(carl9170_5ghz_chantable),
+ .bitrates = carl9170_a_ratetable,
+ .n_bitrates = carl9170_a_ratetable_size,
+ .ht_cap = CARL9170_HT_CAP,
+};
+
+static void carl9170_ampdu_gc(struct ar9170 *ar)
+{
+ struct carl9170_sta_tid *tid_info;
+ LIST_HEAD(tid_gc);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state == CARL9170_TID_STATE_SHUTDOWN) {
+ tid_info->state = CARL9170_TID_STATE_KILLED;
+ list_del_rcu(&tid_info->list);
+ ar->tx_ampdu_list_len--;
+ list_add_tail(&tid_info->tmp_list, &tid_gc);
+ }
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+
+ }
+ rcu_assign_pointer(ar->tx_ampdu_iter, tid_info);
+ rcu_read_unlock();
+
+ synchronize_rcu();
+
+ while (!list_empty(&tid_gc)) {
+ struct sk_buff *skb;
+ tid_info = list_first_entry(&tid_gc, struct carl9170_sta_tid,
+ tmp_list);
+
+ while ((skb = __skb_dequeue(&tid_info->queue)))
+ carl9170_tx_status(ar, skb, false);
+
+ list_del_init(&tid_info->tmp_list);
+ kfree(tid_info);
+ }
+}
+
+static void carl9170_flush(struct ar9170 *ar, bool drop_queued)
+{
+ if (drop_queued) {
+ int i;
+
+ /*
+ * We can only drop frames which have not been uploaded
+ * to the device yet.
+ */
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&ar->tx_pending[i])))
+ carl9170_tx_status(ar, skb, false);
+ }
+ }
+
+ /* Wait for all other outstanding frames to timeout. */
+ if (atomic_read(&ar->tx_total_queued))
+ WARN_ON(wait_for_completion_timeout(&ar->tx_flush, HZ) == 0);
+}
+
+static void carl9170_flush_ba(struct ar9170 *ar)
+{
+ struct sk_buff_head free;
+ struct carl9170_sta_tid *tid_info;
+ struct sk_buff *skb;
+
+ __skb_queue_head_init(&free);
+
+ rcu_read_lock();
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ if (tid_info->state > CARL9170_TID_STATE_SUSPEND) {
+ tid_info->state = CARL9170_TID_STATE_SUSPEND;
+
+ spin_lock(&tid_info->lock);
+ while ((skb = __skb_dequeue(&tid_info->queue)))
+ __skb_queue_tail(&free, skb);
+ spin_unlock(&tid_info->lock);
+ }
+ }
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ rcu_read_unlock();
+
+ while ((skb = __skb_dequeue(&free)))
+ carl9170_tx_status(ar, skb, false);
+}
+
+static void carl9170_zap_queues(struct ar9170 *ar)
+{
+ struct carl9170_vif_info *cvif;
+ unsigned int i;
+
+ carl9170_ampdu_gc(ar);
+
+ carl9170_flush_ba(ar);
+ carl9170_flush(ar, true);
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ spin_lock_bh(&ar->tx_status[i].lock);
+ while (!skb_queue_empty(&ar->tx_status[i])) {
+ struct sk_buff *skb;
+
+ skb = skb_peek(&ar->tx_status[i]);
+ carl9170_tx_get_skb(skb);
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ carl9170_tx_drop(ar, skb);
+ spin_lock_bh(&ar->tx_status[i].lock);
+ carl9170_tx_put_skb(skb);
+ }
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ }
+
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_SOFT < 1);
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD < CARL9170_NUM_TX_LIMIT_SOFT);
+ BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD >= CARL9170_BAW_BITS);
+
+ /* reinitialize queues statistics */
+ memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+ for (i = 0; i < ar->hw->queues; i++)
+ ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD;
+
+ for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++)
+ ar->mem_bitmap[i] = 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(cvif, &ar->vif_list, list) {
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(cvif->beacon);
+ cvif->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+ }
+ rcu_read_unlock();
+
+ atomic_set(&ar->tx_ampdu_upload, 0);
+ atomic_set(&ar->tx_ampdu_scheduler, 0);
+ atomic_set(&ar->tx_total_pending, 0);
+ atomic_set(&ar->tx_total_queued, 0);
+ atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks);
+}
+
+#define CARL9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
+do { \
+ queue.aifs = ai_fs; \
+ queue.cw_min = cwmin; \
+ queue.cw_max = cwmax; \
+ queue.txop = _txop; \
+} while (0)
+
+static int carl9170_op_start(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ int err, i;
+
+ mutex_lock(&ar->mutex);
+
+ carl9170_zap_queues(ar);
+
+ /* reset QoS defaults */
+ CARL9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT */
+ CARL9170_FILL_QUEUE(ar->edcf[1], 2, 7, 15, 94); /* VIDEO */
+ CARL9170_FILL_QUEUE(ar->edcf[2], 2, 3, 7, 47); /* VOICE */
+ CARL9170_FILL_QUEUE(ar->edcf[3], 7, 15, 1023, 0); /* BACKGROUND */
+ CARL9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
+
+ ar->current_factor = ar->current_density = -1;
+ /* "The first key is unique." */
+ ar->usedkeys = 1;
+ ar->filter_state = 0;
+ ar->ps.last_action = jiffies;
+ ar->ps.last_slept = jiffies;
+ ar->erp_mode = CARL9170_ERP_AUTO;
+ ar->rx_software_decryption = false;
+ ar->disable_offload = false;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ ar->queue_stop_timeout[i] = jiffies;
+ ar->max_queue_stop_timeout[i] = 0;
+ }
+
+ atomic_set(&ar->mem_allocs, 0);
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_init_mac(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_qos(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER,
+ AR9170_DMA_TRIGGER_RXQ);
+ if (err)
+ goto out;
+
+ /* Clear key-cache */
+ for (i = 0; i < AR9170_CAM_MAX_USER + 4; i++) {
+ err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE,
+ 0, NULL, 0);
+ if (err)
+ goto out;
+
+ err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE,
+ 1, NULL, 0);
+ if (err)
+ goto out;
+
+ if (i < AR9170_CAM_MAX_USER) {
+ err = carl9170_disable_key(ar, i);
+ if (err)
+ goto out;
+ }
+ }
+
+ carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED);
+
+ ieee80211_wake_queues(ar->hw);
+ err = 0;
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static void carl9170_cancel_worker(struct ar9170 *ar)
+{
+ cancel_delayed_work_sync(&ar->tx_janitor);
+#ifdef CONFIG_CARL9170_LEDS
+ cancel_delayed_work_sync(&ar->led_work);
+#endif /* CONFIG_CARL9170_LEDS */
+ cancel_work_sync(&ar->ps_work);
+ cancel_work_sync(&ar->ampdu_work);
+}
+
+static void carl9170_op_stop(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+
+ carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE);
+
+ ieee80211_stop_queues(ar->hw);
+
+ mutex_lock(&ar->mutex);
+ if (IS_ACCEPTING_CMD(ar)) {
+ rcu_assign_pointer(ar->beacon_iter, NULL);
+
+ carl9170_led_set_state(ar, 0);
+
+ /* stop DMA */
+ carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 0);
+ carl9170_usb_stop(ar);
+ }
+
+ carl9170_zap_queues(ar);
+ mutex_unlock(&ar->mutex);
+
+ carl9170_cancel_worker(ar);
+}
+
+static void carl9170_restart_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ restart_work);
+ int err;
+
+ ar->usedkeys = 0;
+ ar->filter_state = 0;
+ carl9170_cancel_worker(ar);
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_usb_restart(ar);
+ if (net_ratelimit()) {
+ if (err) {
+ dev_err(&ar->udev->dev, "Failed to restart device "
+ " (%d).\n", err);
+ } else {
+ dev_info(&ar->udev->dev, "device restarted "
+ "successfully.\n");
+ }
+ }
+
+ carl9170_zap_queues(ar);
+ mutex_unlock(&ar->mutex);
+ if (!err) {
+ ar->restart_counter++;
+ atomic_set(&ar->pending_restarts, 0);
+
+ ieee80211_restart_hw(ar->hw);
+ } else {
+ /*
+ * The reset was unsuccessful and the device seems to
+ * be dead. But there's still one option: a low-level
+ * usb subsystem reset...
+ */
+
+ carl9170_usb_reset(ar);
+ }
+}
+
+void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
+{
+ carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE);
+
+ /*
+ * Sometimes, an error can trigger several different reset events.
+ * By ignoring these *surplus* reset events, the device won't be
+ * killed again, right after it has recovered.
+ */
+ if (atomic_inc_return(&ar->pending_restarts) > 1) {
+ dev_dbg(&ar->udev->dev, "ignoring restart (%d)\n", r);
+ return;
+ }
+
+ ieee80211_stop_queues(ar->hw);
+
+ dev_err(&ar->udev->dev, "restart device (%d)\n", r);
+
+ if (!WARN_ON(r == CARL9170_RR_NO_REASON) ||
+ !WARN_ON(r >= __CARL9170_RR_LAST))
+ ar->last_reason = r;
+
+ if (!ar->registered)
+ return;
+
+ if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset)
+ ieee80211_queue_work(ar->hw, &ar->restart_work);
+ else
+ carl9170_usb_reset(ar);
+
+ /*
+ * At this point, the device instance might have vanished/disabled.
+ * So, don't put any code which access the ar9170 struct
+ * without proper protection.
+ */
+}
+
+static int carl9170_init_interface(struct ar9170 *ar,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = &ar->common;
+ int err;
+
+ if (!vif) {
+ WARN_ON_ONCE(IS_STARTED(ar));
+ return 0;
+ }
+
+ memcpy(common->macaddr, vif->addr, ETH_ALEN);
+
+ if (modparam_nohwcrypt ||
+ ((vif->type != NL80211_IFTYPE_STATION) &&
+ (vif->type != NL80211_IFTYPE_AP))) {
+ ar->rx_software_decryption = true;
+ ar->disable_offload = true;
+ }
+
+ err = carl9170_set_operating_mode(ar);
+ return err;
+}
+
+static int carl9170_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv;
+ struct ieee80211_vif *main_vif;
+ struct ar9170 *ar = hw->priv;
+ int vif_id = -1, err = 0;
+
+ mutex_lock(&ar->mutex);
+ rcu_read_lock();
+ if (vif_priv->active) {
+ /*
+ * Skip the interface structure initialization,
+ * if the vif survived the _restart call.
+ */
+ vif_id = vif_priv->id;
+ vif_priv->enable_beacon = false;
+
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(vif_priv->beacon);
+ vif_priv->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+
+ goto init;
+ }
+
+ main_vif = carl9170_get_main_vif(ar);
+
+ if (main_vif) {
+ switch (main_vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (vif->type == NL80211_IFTYPE_STATION)
+ break;
+
+ err = -EBUSY;
+ rcu_read_unlock();
+
+ goto unlock;
+
+ case NL80211_IFTYPE_AP:
+ if ((vif->type == NL80211_IFTYPE_STATION) ||
+ (vif->type == NL80211_IFTYPE_WDS) ||
+ (vif->type == NL80211_IFTYPE_AP))
+ break;
+
+ err = -EBUSY;
+ rcu_read_unlock();
+ goto unlock;
+
+ default:
+ rcu_read_unlock();
+ goto unlock;
+ }
+ }
+
+ vif_id = bitmap_find_free_region(&ar->vif_bitmap, ar->fw.vif_num, 0);
+
+ if (vif_id < 0) {
+ rcu_read_unlock();
+
+ err = -ENOSPC;
+ goto unlock;
+ }
+
+ BUG_ON(ar->vif_priv[vif_id].id != vif_id);
+
+ vif_priv->active = true;
+ vif_priv->id = vif_id;
+ vif_priv->enable_beacon = false;
+ ar->vifs++;
+ list_add_tail_rcu(&vif_priv->list, &ar->vif_list);
+ rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif);
+
+init:
+ if (carl9170_get_main_vif(ar) == vif) {
+ rcu_assign_pointer(ar->beacon_iter, vif_priv);
+ rcu_read_unlock();
+
+ err = carl9170_init_interface(ar, vif);
+ if (err)
+ goto unlock;
+ } else {
+ err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr);
+ rcu_read_unlock();
+
+ if (err)
+ goto unlock;
+ }
+
+unlock:
+ if (err && (vif_id != -1)) {
+ vif_priv->active = false;
+ bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
+ ar->vifs--;
+ rcu_assign_pointer(ar->vif_priv[vif_id].vif, NULL);
+ list_del_rcu(&vif_priv->list);
+ mutex_unlock(&ar->mutex);
+ synchronize_rcu();
+ } else {
+ if (ar->vifs > 1)
+ ar->ps.off_override |= PS_OFF_VIF;
+
+ mutex_unlock(&ar->mutex);
+ }
+
+ return err;
+}
+
+static void carl9170_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv;
+ struct ieee80211_vif *main_vif;
+ struct ar9170 *ar = hw->priv;
+ unsigned int id;
+
+ mutex_lock(&ar->mutex);
+
+ if (WARN_ON_ONCE(!vif_priv->active))
+ goto unlock;
+
+ ar->vifs--;
+
+ rcu_read_lock();
+ main_vif = carl9170_get_main_vif(ar);
+
+ id = vif_priv->id;
+
+ vif_priv->active = false;
+ WARN_ON(vif_priv->enable_beacon);
+ vif_priv->enable_beacon = false;
+ list_del_rcu(&vif_priv->list);
+ rcu_assign_pointer(ar->vif_priv[id].vif, NULL);
+
+ if (vif == main_vif) {
+ rcu_read_unlock();
+
+ if (ar->vifs) {
+ WARN_ON(carl9170_init_interface(ar,
+ carl9170_get_main_vif(ar)));
+ } else {
+ carl9170_set_operating_mode(ar);
+ }
+ } else {
+ rcu_read_unlock();
+
+ WARN_ON(carl9170_mod_virtual_mac(ar, id, NULL));
+ }
+
+ carl9170_update_beacon(ar, false);
+ carl9170_flush_cab(ar, id);
+
+ spin_lock_bh(&ar->beacon_lock);
+ dev_kfree_skb_any(vif_priv->beacon);
+ vif_priv->beacon = NULL;
+ spin_unlock_bh(&ar->beacon_lock);
+
+ bitmap_release_region(&ar->vif_bitmap, id, 0);
+
+ carl9170_set_beacon_timers(ar);
+
+ if (ar->vifs == 1)
+ ar->ps.off_override &= ~PS_OFF_VIF;
+
+unlock:
+ mutex_unlock(&ar->mutex);
+
+ synchronize_rcu();
+}
+
+void carl9170_ps_check(struct ar9170 *ar)
+{
+ ieee80211_queue_work(ar->hw, &ar->ps_work);
+}
+
+/* caller must hold ar->mutex */
+static int carl9170_ps_update(struct ar9170 *ar)
+{
+ bool ps = false;
+ int err = 0;
+
+ if (!ar->ps.off_override)
+ ps = (ar->hw->conf.flags & IEEE80211_CONF_PS);
+
+ if (ps != ar->ps.state) {
+ err = carl9170_powersave(ar, ps);
+ if (err)
+ return err;
+
+ if (ar->ps.state && !ps) {
+ ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
+ ar->ps.last_action);
+ }
+
+ if (ps)
+ ar->ps.last_slept = jiffies;
+
+ ar->ps.last_action = jiffies;
+ ar->ps.state = ps;
+ }
+
+ return 0;
+}
+
+static void carl9170_ps_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ ps_work);
+ mutex_lock(&ar->mutex);
+ if (IS_STARTED(ar))
+ WARN_ON_ONCE(carl9170_ps_update(ar) != 0);
+ mutex_unlock(&ar->mutex);
+}
+
+
+static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0;
+
+ mutex_lock(&ar->mutex);
+ if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ err = carl9170_ps_update(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_SMPS) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ /* adjust slot time for 5 GHz */
+ err = carl9170_set_slot_time(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_channel(ar, hw->conf.channel,
+ hw->conf.channel_type, CARL9170_RFI_NONE);
+ if (err)
+ goto out;
+
+ err = carl9170_set_dyn_sifs_ack(ar);
+ if (err)
+ goto out;
+
+ err = carl9170_set_rts_cts_rate(ar);
+ if (err)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct netdev_hw_addr *ha;
+ u64 mchash;
+
+ /* always get broadcast frames */
+ mchash = 1ULL << (0xff >> 2);
+
+ netdev_hw_addr_list_for_each(ha, mc_list)
+ mchash |= 1ULL << (ha->addr[5] >> 2);
+
+ return mchash;
+}
+
+static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *new_flags,
+ u64 multicast)
+{
+ struct ar9170 *ar = hw->priv;
+
+ /* mask supported flags */
+ *new_flags &= FIF_ALLMULTI | FIF_FCSFAIL | FIF_PLCPFAIL |
+ FIF_OTHER_BSS | FIF_PROMISC_IN_BSS;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+
+ ar->filter_state = *new_flags;
+ /*
+ * We can support more by setting the sniffer bit and
+ * then checking the error flags, later.
+ */
+
+ if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
+ multicast = ~0ULL;
+
+ if (multicast != ar->cur_mc_hash)
+ WARN_ON(carl9170_update_multicast(ar, multicast));
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+ ar->sniffer_enabled = !!(*new_flags &
+ (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS));
+
+ WARN_ON(carl9170_set_operating_mode(ar));
+ }
+
+ mutex_unlock(&ar->mutex);
+}
+
+
+static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ath_common *common = &ar->common;
+ int err = 0;
+ struct carl9170_vif_info *vif_priv;
+ struct ieee80211_vif *main_vif;
+
+ mutex_lock(&ar->mutex);
+ vif_priv = (void *) vif->drv_priv;
+ main_vif = carl9170_get_main_vif(ar);
+ if (WARN_ON(!main_vif))
+ goto out;
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ struct carl9170_vif_info *iter;
+ int i = 0;
+
+ vif_priv->enable_beacon = bss_conf->enable_beacon;
+ rcu_read_lock();
+ list_for_each_entry_rcu(iter, &ar->vif_list, list) {
+ if (iter->active && iter->enable_beacon)
+ i++;
+
+ }
+ rcu_read_unlock();
+
+ ar->beacon_enabled = i;
+ }
+
+ if (changed & BSS_CHANGED_BEACON) {
+ err = carl9170_update_beacon(ar, false);
+ if (err)
+ goto out;
+ }
+
+ if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
+ BSS_CHANGED_BEACON_INT)) {
+
+ if (main_vif != vif) {
+ bss_conf->beacon_int = main_vif->bss_conf.beacon_int;
+ bss_conf->dtim_period = main_vif->bss_conf.dtim_period;
+ }
+
+ /*
+ * Therefore a hard limit for the broadcast traffic should
+ * prevent false alarms.
+ */
+ if (vif->type != NL80211_IFTYPE_STATION &&
+ (bss_conf->beacon_int * bss_conf->dtim_period >=
+ (CARL9170_QUEUE_STUCK_TIMEOUT / 2))) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = carl9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ /* TODO */
+ err = 0;
+ if (err)
+ goto out;
+ }
+
+ if (main_vif != vif)
+ goto out;
+
+ /*
+ * The following settings can only be changed by the
+ * master interface.
+ */
+
+ if (changed & BSS_CHANGED_BSSID) {
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+ err = carl9170_set_operating_mode(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ ar->common.curaid = bss_conf->aid;
+ err = carl9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ err = carl9170_set_slot_time(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ err = carl9170_set_mac_rates(ar);
+ if (err)
+ goto out;
+ }
+
+out:
+ WARN_ON_ONCE(err && IS_STARTED(ar));
+ mutex_unlock(&ar->mutex);
+}
+
+static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_tsf_rsp tsf;
+ int err;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_READ_TSF,
+ 0, NULL, sizeof(tsf), &tsf);
+ mutex_unlock(&ar->mutex);
+ if (WARN_ON(err))
+ return 0;
+
+ return le64_to_cpu(tsf.tsf_64);
+}
+
+static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0, i;
+ u8 ktype;
+
+ if (ar->disable_offload || !vif)
+ return -EOPNOTSUPP;
+
+ /*
+ * We have to fall back to software encryption, whenever
+ * the user choose to participates in an IBSS or is connected
+ * to more than one network.
+ *
+ * This is very unfortunate, because some machines cannot handle
+ * the high througput speed in 802.11n networks.
+ */
+
+ if (!is_main_vif(ar, vif))
+ goto err_softw;
+
+ /*
+ * While the hardware supports *catch-all* key, for offloading
+ * group-key en-/de-cryption. The way of how the hardware
+ * decides which keyId maps to which key, remains a mystery...
+ */
+ if ((vif->type != NL80211_IFTYPE_STATION &&
+ vif->type != NL80211_IFTYPE_ADHOC) &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ return -EOPNOTSUPP;
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ ktype = AR9170_ENC_ALG_WEP64;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ ktype = AR9170_ENC_ALG_WEP128;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ ktype = AR9170_ENC_ALG_TKIP;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ ktype = AR9170_ENC_ALG_AESCCMP;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&ar->mutex);
+ if (cmd == SET_KEY) {
+ if (!IS_STARTED(ar)) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ sta = NULL;
+
+ i = 64 + key->keyidx;
+ } else {
+ for (i = 0; i < 64; i++)
+ if (!(ar->usedkeys & BIT(i)))
+ break;
+ if (i == 64)
+ goto err_softw;
+ }
+
+ key->hw_key_idx = i;
+
+ err = carl9170_upload_key(ar, i, sta ? sta->addr : NULL,
+ ktype, 0, key->key,
+ min_t(u8, 16, key->keylen));
+ if (err)
+ goto out;
+
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ err = carl9170_upload_key(ar, i, sta ? sta->addr :
+ NULL, ktype, 1,
+ key->key + 16, 16);
+ if (err)
+ goto out;
+
+ /*
+ * hardware is not capable generating MMIC
+ * of fragmented frames!
+ */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ }
+
+ if (i < 64)
+ ar->usedkeys |= BIT(i);
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ } else {
+ if (!IS_STARTED(ar)) {
+ /* The device is gone... together with the key ;-) */
+ err = 0;
+ goto out;
+ }
+
+ if (key->hw_key_idx < 64) {
+ ar->usedkeys &= ~BIT(key->hw_key_idx);
+ } else {
+ err = carl9170_upload_key(ar, key->hw_key_idx, NULL,
+ AR9170_ENC_ALG_NONE, 0,
+ NULL, 0);
+ if (err)
+ goto out;
+
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ err = carl9170_upload_key(ar, key->hw_key_idx,
+ NULL,
+ AR9170_ENC_ALG_NONE,
+ 1, NULL, 0);
+ if (err)
+ goto out;
+ }
+
+ }
+
+ err = carl9170_disable_key(ar, key->hw_key_idx);
+ if (err)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+
+err_softw:
+ if (!ar->rx_software_decryption) {
+ ar->rx_software_decryption = true;
+ carl9170_set_operating_mode(ar);
+ }
+ mutex_unlock(&ar->mutex);
+ return -ENOSPC;
+}
+
+static int carl9170_op_sta_add(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ unsigned int i;
+
+ if (sta->ht_cap.ht_supported) {
+ if (sta->ht_cap.ampdu_density > 6) {
+ /*
+ * HW does support 16us AMPDU density.
+ * No HT-Xmit for station.
+ */
+
+ return 0;
+ }
+
+ for (i = 0; i < CARL9170_NUM_TID; i++)
+ rcu_assign_pointer(sta_info->agg[i], NULL);
+
+ sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
+ sta_info->ht_sta = true;
+ }
+
+ return 0;
+}
+
+static int carl9170_op_sta_remove(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ unsigned int i;
+ bool cleanup = false;
+
+ if (sta->ht_cap.ht_supported) {
+
+ sta_info->ht_sta = false;
+
+ rcu_read_lock();
+ for (i = 0; i < CARL9170_NUM_TID; i++) {
+ struct carl9170_sta_tid *tid_info;
+
+ tid_info = rcu_dereference(sta_info->agg[i]);
+ rcu_assign_pointer(sta_info->agg[i], NULL);
+
+ if (!tid_info)
+ continue;
+
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN)
+ tid_info->state = CARL9170_TID_STATE_SHUTDOWN;
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ cleanup = true;
+ }
+ rcu_read_unlock();
+
+ if (cleanup)
+ carl9170_ampdu_gc(ar);
+ }
+
+ return 0;
+}
+
+static int carl9170_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *param)
+{
+ struct ar9170 *ar = hw->priv;
+ int ret;
+
+ mutex_lock(&ar->mutex);
+ if (queue < ar->hw->queues) {
+ memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
+ ret = carl9170_set_qos(ar);
+ } else {
+ ret = -EINVAL;
+ }
+
+ mutex_unlock(&ar->mutex);
+ return ret;
+}
+
+static void carl9170_ampdu_work(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ ampdu_work);
+
+ if (!IS_STARTED(ar))
+ return;
+
+ mutex_lock(&ar->mutex);
+ carl9170_ampdu_gc(ar);
+ mutex_unlock(&ar->mutex);
+}
+
+static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ struct carl9170_sta_tid *tid_info;
+
+ if (modparam_noht)
+ return -EOPNOTSUPP;
+
+ switch (action) {
+ case IEEE80211_AMPDU_TX_START:
+ if (WARN_ON_ONCE(!sta_info->ht_sta))
+ return -EOPNOTSUPP;
+
+ rcu_read_lock();
+ if (rcu_dereference(sta_info->agg[tid])) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+
+ tid_info = kzalloc(sizeof(struct carl9170_sta_tid),
+ GFP_ATOMIC);
+ if (!tid_info) {
+ rcu_read_unlock();
+ return -ENOMEM;
+ }
+
+ tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn);
+ tid_info->state = CARL9170_TID_STATE_PROGRESS;
+ tid_info->tid = tid;
+ tid_info->max = sta_info->ampdu_max_len;
+
+ INIT_LIST_HEAD(&tid_info->list);
+ INIT_LIST_HEAD(&tid_info->tmp_list);
+ skb_queue_head_init(&tid_info->queue);
+ spin_lock_init(&tid_info->lock);
+
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ ar->tx_ampdu_list_len++;
+ list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list);
+ rcu_assign_pointer(sta_info->agg[tid], tid_info);
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ rcu_read_unlock();
+
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
+
+ case IEEE80211_AMPDU_TX_STOP:
+ rcu_read_lock();
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+ if (tid_info) {
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN)
+ tid_info->state = CARL9170_TID_STATE_SHUTDOWN;
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+ }
+
+ rcu_assign_pointer(sta_info->agg[tid], NULL);
+ rcu_read_unlock();
+
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ ieee80211_queue_work(ar->hw, &ar->ampdu_work);
+ break;
+
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ rcu_read_lock();
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+
+ sta_info->stats[tid].clear = true;
+
+ if (tid_info) {
+ bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE);
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+ }
+ rcu_read_unlock();
+
+ if (WARN_ON_ONCE(!tid_info))
+ return -EFAULT;
+
+ break;
+
+ case IEEE80211_AMPDU_RX_START:
+ case IEEE80211_AMPDU_RX_STOP:
+ /* Handled by hardware */
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_CARL9170_WPC
+static int carl9170_register_wps_button(struct ar9170 *ar)
+{
+ struct input_dev *input;
+ int err;
+
+ if (!(ar->features & CARL9170_WPS_BUTTON))
+ return 0;
+
+ input = input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+
+ snprintf(ar->wps.name, sizeof(ar->wps.name), "%s WPS Button",
+ wiphy_name(ar->hw->wiphy));
+
+ snprintf(ar->wps.phys, sizeof(ar->wps.phys),
+ "ieee80211/%s/input0", wiphy_name(ar->hw->wiphy));
+
+ input->name = ar->wps.name;
+ input->phys = ar->wps.phys;
+ input->id.bustype = BUS_USB;
+ input->dev.parent = &ar->hw->wiphy->dev;
+
+ input_set_capability(input, EV_KEY, KEY_WPS_BUTTON);
+
+ err = input_register_device(input);
+ if (err) {
+ input_free_device(input);
+ return err;
+ }
+
+ ar->wps.pbc = input;
+ return 0;
+}
+#endif /* CONFIG_CARL9170_WPC */
+
+static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx,
+ struct survey_info *survey)
+{
+ struct ar9170 *ar = hw->priv;
+ int err;
+
+ if (idx != 0)
+ return -ENOENT;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_get_noisefloor(ar);
+ mutex_unlock(&ar->mutex);
+ if (err)
+ return err;
+
+ survey->channel = ar->channel;
+ survey->filled = SURVEY_INFO_NOISE_DBM;
+ survey->noise = ar->noise[0];
+ return 0;
+}
+
+static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct ar9170 *ar = hw->priv;
+ unsigned int vid;
+
+ mutex_lock(&ar->mutex);
+ for_each_set_bit(vid, &ar->vif_bitmap, ar->fw.vif_num)
+ carl9170_flush_cab(ar, vid);
+
+ carl9170_flush(ar, drop);
+ mutex_unlock(&ar->mutex);
+}
+
+static int carl9170_op_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct ar9170 *ar = hw->priv;
+
+ memset(stats, 0, sizeof(*stats));
+ stats->dot11ACKFailureCount = ar->tx_ack_failures;
+ stats->dot11FCSErrorCount = ar->tx_fcs_errors;
+ return 0;
+}
+
+static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct ar9170 *ar = hw->priv;
+ struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+ struct sk_buff *skb;
+ struct sk_buff_head free;
+ int i;
+
+ switch (cmd) {
+ case STA_NOTIFY_SLEEP:
+ /*
+ * Since the peer is no longer listening, we have to return
+ * as many SKBs as possible back to the mac80211 stack.
+ * It will deal with the retry procedure, once the peer
+ * has become available again.
+ *
+ * NB: Ideally, the driver should return the all frames in
+ * the correct, ascending order. However, I think that this
+ * functionality should be implemented in the stack and not
+ * here...
+ */
+
+ __skb_queue_head_init(&free);
+
+ if (sta->ht_cap.ht_supported) {
+ rcu_read_lock();
+ for (i = 0; i < CARL9170_NUM_TID; i++) {
+ struct carl9170_sta_tid *tid_info;
+
+ tid_info = rcu_dereference(sta_info->agg[i]);
+
+ if (!tid_info)
+ continue;
+
+ spin_lock_bh(&ar->tx_ampdu_list_lock);
+ if (tid_info->state >
+ CARL9170_TID_STATE_SUSPEND)
+ tid_info->state =
+ CARL9170_TID_STATE_SUSPEND;
+ spin_unlock_bh(&ar->tx_ampdu_list_lock);
+
+ spin_lock_bh(&tid_info->lock);
+ while ((skb = __skb_dequeue(&tid_info->queue)))
+ __skb_queue_tail(&free, skb);
+ spin_unlock_bh(&tid_info->lock);
+
+ ieee80211_stop_tx_ba_session(sta,
+ tid_info->tid);
+ }
+ rcu_read_unlock();
+ }
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ spin_lock_bh(&ar->tx_pending[i].lock);
+ skb_queue_walk(&ar->tx_pending[i], skb) {
+ struct _carl9170_tx_superframe *super;
+ struct ieee80211_hdr *hdr;
+
+ super = (void *) skb->data;
+ hdr = (void *) super->frame_data;
+
+ if (compare_ether_addr(hdr->addr1, sta->addr))
+ continue;
+
+ __skb_unlink(skb, &ar->tx_pending[i]);
+ carl9170_tx_status(ar, skb, false);
+ }
+ spin_unlock_bh(&ar->tx_pending[i].lock);
+ }
+
+ while ((skb = __skb_dequeue(&free)))
+ carl9170_tx_status(ar, skb, false);
+
+ break;
+
+ case STA_NOTIFY_AWAKE:
+ if (!sta->ht_cap.ht_supported)
+ return;
+
+ rcu_read_lock();
+ for (i = 0; i < CARL9170_NUM_TID; i++) {
+ struct carl9170_sta_tid *tid_info;
+
+ tid_info = rcu_dereference(sta_info->agg[i]);
+
+ if (!tid_info)
+ continue;
+
+ if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+ }
+ rcu_read_unlock();
+ break;
+ }
+}
+
+static const struct ieee80211_ops carl9170_ops = {
+ .start = carl9170_op_start,
+ .stop = carl9170_op_stop,
+ .tx = carl9170_op_tx,
+ .flush = carl9170_op_flush,
+ .add_interface = carl9170_op_add_interface,
+ .remove_interface = carl9170_op_remove_interface,
+ .config = carl9170_op_config,
+ .prepare_multicast = carl9170_op_prepare_multicast,
+ .configure_filter = carl9170_op_configure_filter,
+ .conf_tx = carl9170_op_conf_tx,
+ .bss_info_changed = carl9170_op_bss_info_changed,
+ .get_tsf = carl9170_op_get_tsf,
+ .set_key = carl9170_op_set_key,
+ .sta_add = carl9170_op_sta_add,
+ .sta_remove = carl9170_op_sta_remove,
+ .sta_notify = carl9170_op_sta_notify,
+ .get_survey = carl9170_op_get_survey,
+ .get_stats = carl9170_op_get_stats,
+ .ampdu_action = carl9170_op_ampdu_action,
+};
+
+void *carl9170_alloc(size_t priv_size)
+{
+ struct ieee80211_hw *hw;
+ struct ar9170 *ar;
+ struct sk_buff *skb;
+ int i;
+
+ /*
+ * this buffer is used for rx stream reconstruction.
+ * Under heavy load this device (or the transport layer?)
+ * tends to split the streams into separate rx descriptors.
+ */
+
+ skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
+ if (!skb)
+ goto err_nomem;
+
+ hw = ieee80211_alloc_hw(priv_size, &carl9170_ops);
+ if (!hw)
+ goto err_nomem;
+
+ ar = hw->priv;
+ ar->hw = hw;
+ ar->rx_failover = skb;
+
+ memset(&ar->rx_plcp, 0, sizeof(struct ar9170_rx_head));
+ ar->rx_has_plcp = false;
+
+ /*
+ * Here's a hidden pitfall!
+ *
+ * All 4 AC queues work perfectly well under _legacy_ operation.
+ * However as soon as aggregation is enabled, the traffic flow
+ * gets very bumpy. Therefore we have to _switch_ to a
+ * software AC with a single HW queue.
+ */
+ hw->queues = __AR9170_NUM_TXQ;
+
+ mutex_init(&ar->mutex);
+ spin_lock_init(&ar->beacon_lock);
+ spin_lock_init(&ar->cmd_lock);
+ spin_lock_init(&ar->tx_stats_lock);
+ spin_lock_init(&ar->tx_ampdu_list_lock);
+ spin_lock_init(&ar->mem_lock);
+ spin_lock_init(&ar->state_lock);
+ atomic_set(&ar->pending_restarts, 0);
+ ar->vifs = 0;
+ for (i = 0; i < ar->hw->queues; i++) {
+ skb_queue_head_init(&ar->tx_status[i]);
+ skb_queue_head_init(&ar->tx_pending[i]);
+ }
+ INIT_WORK(&ar->ps_work, carl9170_ps_work);
+ INIT_WORK(&ar->restart_work, carl9170_restart_work);
+ INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
+ INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
+ INIT_LIST_HEAD(&ar->tx_ampdu_list);
+ rcu_assign_pointer(ar->tx_ampdu_iter,
+ (struct carl9170_sta_tid *) &ar->tx_ampdu_list);
+
+ bitmap_zero(&ar->vif_bitmap, ar->fw.vif_num);
+ INIT_LIST_HEAD(&ar->vif_list);
+ init_completion(&ar->tx_flush);
+
+ /*
+ * Note:
+ * IBSS/ADHOC and AP mode are only enabled, if the firmware
+ * supports these modes. The code which will add the
+ * additional interface_modes is in fw.c.
+ */
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+ hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_SIGNAL_DBM;
+
+ if (!modparam_noht) {
+ /*
+ * see the comment above, why we allow the user
+ * to disable HT by a module parameter.
+ */
+ hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+ }
+
+ hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe);
+ hw->sta_data_size = sizeof(struct carl9170_sta_info);
+ hw->vif_data_size = sizeof(struct carl9170_vif_info);
+
+ hw->max_rates = CARL9170_TX_MAX_RATES;
+ hw->max_rate_tries = CARL9170_TX_USER_RATE_TRIES;
+
+ for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+ ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ return ar;
+
+err_nomem:
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
+}
+
+static int carl9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW 8 /* number of words to read at once */
+#define RB (sizeof(u32) * RW)
+ u8 *eeprom = (void *)&ar->eeprom;
+ __le32 offsets[RW];
+ int i, j, err;
+
+ BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+ BUILD_BUG_ON(RB > CARL9170_MAX_CMD_LEN - 4);
+#ifndef __CHECKER__
+ /* don't want to handle trailing remains */
+ BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
+#endif
+
+ for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+ for (j = 0; j < RW; j++)
+ offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
+ RB * i + 4 * j);
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
+ RB, (u8 *) &offsets,
+ RB, eeprom + RB * i);
+ if (err)
+ return err;
+ }
+
+#undef RW
+#undef RB
+ return 0;
+}
+
+static int carl9170_parse_eeprom(struct ar9170 *ar)
+{
+ struct ath_regulatory *regulatory = &ar->common.regulatory;
+ unsigned int rx_streams, tx_streams, tx_params = 0;
+ int bands = 0;
+
+ if (ar->eeprom.length == cpu_to_le16(0xffff))
+ return -ENODATA;
+
+ rx_streams = hweight8(ar->eeprom.rx_mask);
+ tx_streams = hweight8(ar->eeprom.tx_mask);
+
+ if (rx_streams != tx_streams) {
+ tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
+
+ WARN_ON(!(tx_streams >= 1 && tx_streams <=
+ IEEE80211_HT_MCS_TX_MAX_STREAMS));
+
+ tx_params = (tx_streams - 1) <<
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+
+ carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
+ carl9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
+ }
+
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &carl9170_band_2GHz;
+ bands++;
+ }
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &carl9170_band_5GHz;
+ bands++;
+ }
+
+ /*
+ * I measured this, a bandswitch takes roughly
+ * 135 ms and a frequency switch about 80.
+ *
+ * FIXME: measure these values again once EEPROM settings
+ * are used, that will influence them!
+ */
+ if (bands == 2)
+ ar->hw->channel_change_time = 135 * 1000;
+ else
+ ar->hw->channel_change_time = 80 * 1000;
+
+ regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+ regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
+ /* second part of wiphy init */
+ SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address);
+
+ return bands ? 0 : -EINVAL;
+}
+
+static int carl9170_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ar9170 *ar = hw->priv;
+
+ return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
+}
+
+int carl9170_register(struct ar9170 *ar)
+{
+ struct ath_regulatory *regulatory = &ar->common.regulatory;
+ int err = 0, i;
+
+ if (WARN_ON(ar->mem_bitmap))
+ return -EINVAL;
+
+ ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) *
+ sizeof(unsigned long), GFP_KERNEL);
+
+ if (!ar->mem_bitmap)
+ return -ENOMEM;
+
+ /* try to read EEPROM, init MAC addr */
+ err = carl9170_read_eeprom(ar);
+ if (err)
+ return err;
+
+ err = carl9170_fw_fix_eeprom(ar);
+ if (err)
+ return err;
+
+ err = carl9170_parse_eeprom(ar);
+ if (err)
+ return err;
+
+ err = ath_regd_init(regulatory, ar->hw->wiphy,
+ carl9170_reg_notifier);
+ if (err)
+ return err;
+
+ if (modparam_noht) {
+ carl9170_band_2GHz.ht_cap.ht_supported = false;
+ carl9170_band_5GHz.ht_cap.ht_supported = false;
+ }
+
+ for (i = 0; i < ar->fw.vif_num; i++) {
+ ar->vif_priv[i].id = i;
+ ar->vif_priv[i].vif = NULL;
+ }
+
+ err = ieee80211_register_hw(ar->hw);
+ if (err)
+ return err;
+
+ /* mac80211 interface is now registered */
+ ar->registered = true;
+
+ if (!ath_is_world_regd(regulatory))
+ regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ carl9170_debugfs_register(ar);
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+ err = carl9170_led_init(ar);
+ if (err)
+ goto err_unreg;
+
+#ifdef CONFIG_CARL9170_LEDS
+ err = carl9170_led_register(ar);
+ if (err)
+ goto err_unreg;
+#endif /* CONFIG_CAR9L170_LEDS */
+
+#ifdef CONFIG_CARL9170_WPC
+ err = carl9170_register_wps_button(ar);
+ if (err)
+ goto err_unreg;
+#endif /* CONFIG_CARL9170_WPC */
+
+ dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n",
+ wiphy_name(ar->hw->wiphy));
+
+ return 0;
+
+err_unreg:
+ carl9170_unregister(ar);
+ return err;
+}
+
+void carl9170_unregister(struct ar9170 *ar)
+{
+ if (!ar->registered)
+ return;
+
+ ar->registered = false;
+
+#ifdef CONFIG_CARL9170_LEDS
+ carl9170_led_unregister(ar);
+#endif /* CONFIG_CARL9170_LEDS */
+
+#ifdef CONFIG_CARL9170_DEBUGFS
+ carl9170_debugfs_unregister(ar);
+#endif /* CONFIG_CARL9170_DEBUGFS */
+
+#ifdef CONFIG_CARL9170_WPC
+ if (ar->wps.pbc) {
+ input_unregister_device(ar->wps.pbc);
+ ar->wps.pbc = NULL;
+ }
+#endif /* CONFIG_CARL9170_WPC */
+
+ carl9170_cancel_worker(ar);
+ cancel_work_sync(&ar->restart_work);
+
+ ieee80211_unregister_hw(ar->hw);
+}
+
+void carl9170_free(struct ar9170 *ar)
+{
+ WARN_ON(ar->registered);
+ WARN_ON(IS_INITIALIZED(ar));
+
+ kfree_skb(ar->rx_failover);
+ ar->rx_failover = NULL;
+
+ kfree(ar->mem_bitmap);
+ ar->mem_bitmap = NULL;
+
+ mutex_destroy(&ar->mutex);
+
+ ieee80211_free_hw(ar->hw);
+}
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
new file mode 100644
index 000000000000..47709c13d964
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -0,0 +1,1805 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * PHY and RF code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/bitrev.h>
+#include "carl9170.h"
+#include "cmd.h"
+#include "phy.h"
+
+static int carl9170_init_power_cal(struct ar9170 *ar)
+{
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f);
+ carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f);
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+struct carl9170_phy_init {
+ u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct carl9170_phy_init ar5416_phy_init[] = {
+ { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
+ { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
+ { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
+ { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
+ { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
+ { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
+ { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+ { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
+ { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+ { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+ { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
+ { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
+ { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
+ { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
+ { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
+ { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
+ { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+ { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+ { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
+ { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+ { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
+ { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
+ { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
+ { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
+ { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
+ { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
+ { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
+ { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+ { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
+ { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
+ { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
+ { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
+ { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
+ { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
+ { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
+ { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
+ { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
+ { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
+ { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
+ { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
+ { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+ { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+ { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
+ { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
+ { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
+ { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
+ { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
+ { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
+ { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
+ { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
+ { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
+ { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
+ { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
+ { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
+ { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
+ { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
+ { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
+ { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
+ { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
+ { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+ { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
+ { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
+ { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
+ { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
+ { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
+ { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
+ { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
+ { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
+ { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
+ { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
+ { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
+ { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
+ { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
+ { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
+ { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
+ { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
+ { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
+ { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
+ { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
+ { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
+ { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
+ { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
+ { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
+ { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
+ { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
+ { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
+ { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
+ { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
+ { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
+ { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
+ { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
+ { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+ { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
+ { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
+ { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
+ { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
+ { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
+ { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
+ { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
+ { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+ { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
+ { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
+ { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
+ { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
+ { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
+ { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
+ { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
+ { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+ { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
+ { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
+ { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
+ { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
+ { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
+ { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
+ { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
+ { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
+ { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
+ { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+ { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
+ { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
+ { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
+ { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
+ { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
+ { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
+ { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
+ { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
+ { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
+ { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
+ { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+ { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+ { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
+ { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
+ { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
+ { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
+ { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
+ { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
+ { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
+ { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
+ { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
+ { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
+ { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
+ { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
+ { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
+ { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
+ { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
+ { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+ { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
+ { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
+ { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
+ { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
+ { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+ { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
+ { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
+ { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
+ { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
+ { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
+ { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
+ { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
+ { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
+ { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
+ { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
+ { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
+ { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
+ { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
+ { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
+ { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
+ { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
+ { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
+ { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
+ { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+ { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+ { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+ { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+ { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+ { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
+ { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+ { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
+ { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
+ { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+ { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
+ { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
+ { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
+ { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
+ { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
+ { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
+ { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
+ { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
+ { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
+ { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
+ { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
+ { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
+};
+
+/*
+ * look up a certain register in ar5416_phy_init[] and return the init. value
+ * for the band and bandwidth given. Return 0 if register address not found.
+ */
+static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz)
+{
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+ if (ar5416_phy_init[i].reg != reg)
+ continue;
+
+ if (is_2ghz) {
+ if (is_40mhz)
+ return ar5416_phy_init[i]._2ghz_40;
+ else
+ return ar5416_phy_init[i]._2ghz_20;
+ } else {
+ if (is_40mhz)
+ return ar5416_phy_init[i]._5ghz_40;
+ else
+ return ar5416_phy_init[i]._5ghz_20;
+ }
+ }
+ return 0;
+}
+
+/*
+ * initialize some phy regs from eeprom values in modal_header[]
+ * acc. to band and bandwith
+ */
+static int carl9170_init_phy_from_eeprom(struct ar9170 *ar,
+ bool is_2ghz, bool is_40mhz)
+{
+ static const u8 xpd2pd[16] = {
+ 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
+ 0x2, 0x3, 0x7, 0x2, 0xb, 0x2, 0x2, 0x2
+ };
+ /* pointer to the modal_header acc. to band */
+ struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
+ u32 val;
+
+ carl9170_regwrite_begin(ar);
+
+ /* ant common control (index 0) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM,
+ le32_to_cpu(m->antCtrlCommon));
+
+ /* ant control chain 0 (index 1) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0,
+ le32_to_cpu(m->antCtrlChain[0]));
+
+ /* ant control chain 2 (index 2) */
+ carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2,
+ le32_to_cpu(m->antCtrlChain[1]));
+
+ /* SwSettle (index 3) */
+ if (!is_40mhz) {
+ val = carl9170_def_val(AR9170_PHY_REG_SETTLING,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling);
+ carl9170_regwrite(AR9170_PHY_REG_SETTLING, val);
+ }
+
+ /* adcDesired, pdaDesired (index 4) */
+ val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize);
+ SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize);
+ carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val);
+
+ /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
+ val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff);
+ SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff);
+ SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn);
+ SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn);
+ carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val);
+
+ /* TxEndToRxOn (index 6) */
+ val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn);
+ carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val);
+
+ /* thresh62 (index 7) */
+ val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz);
+ val = (val & ~0x7f000) | (m->thresh62 << 12);
+ carl9170_regwrite(0x1c8864, val);
+
+ /* tx/rx attenuation chain 0 (index 8) */
+ val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]);
+ carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val);
+
+ /* tx/rx attenuation chain 2 (index 9) */
+ val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val);
+
+ /* tx/rx margin chain 0 (index 10) */
+ val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]);
+ /* bsw margin chain 0 for 5GHz only */
+ if (!is_2ghz)
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]);
+ carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val);
+
+ /* tx/rx margin chain 2 (index 11) */
+ val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2,
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val);
+
+ /* iqCall, iqCallq chain 0 (index 12) */
+ val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0),
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]);
+ carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val);
+
+ /* iqCall, iqCallq chain 2 (index 13) */
+ val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2),
+ is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]);
+ SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]);
+ carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val);
+
+ /* xpd gain mask (index 14) */
+ val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz);
+ SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val,
+ xpd2pd[m->xpdGain & 0xf] & 3);
+ SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val,
+ xpd2pd[m->xpdGain & 0xf] >> 2);
+ carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val);
+ carl9170_regwrite_finish();
+
+ return carl9170_regwrite_result();
+}
+
+static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
+{
+ int i, err;
+ u32 val;
+ bool is_2ghz = band == IEEE80211_BAND_2GHZ;
+ bool is_40mhz = conf_is_ht40(&ar->hw->conf);
+
+ carl9170_regwrite_begin(ar);
+
+ for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+ if (is_40mhz) {
+ if (is_2ghz)
+ val = ar5416_phy_init[i]._2ghz_40;
+ else
+ val = ar5416_phy_init[i]._5ghz_40;
+ } else {
+ if (is_2ghz)
+ val = ar5416_phy_init[i]._2ghz_20;
+ else
+ val = ar5416_phy_init[i]._5ghz_20;
+ }
+
+ carl9170_regwrite(ar5416_phy_init[i].reg, val);
+ }
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
+ if (err)
+ return err;
+
+ err = carl9170_init_power_cal(ar);
+ if (err)
+ return err;
+
+ /* XXX: remove magic! */
+ if (is_2ghz)
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5163);
+ else
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5143);
+
+ return err;
+}
+
+struct carl9170_rf_initvals {
+ u32 reg, _5ghz, _2ghz;
+};
+
+static struct carl9170_rf_initvals carl9170_rf_initval[] = {
+ /* bank 0 */
+ { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
+ { 0x1c58e0, 0x02008020, 0x02008020},
+ /* bank 1 */
+ { 0x1c58b0, 0x02108421, 0x02108421},
+ { 0x1c58ec, 0x00000008, 0x00000008},
+ /* bank 2 */
+ { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
+ { 0x1c58e0, 0x00000420, 0x00000420},
+ /* bank 3 */
+ { 0x1c58f0, 0x01400018, 0x01c00018},
+ /* bank 4 */
+ { 0x1c58b0, 0x000001a1, 0x000001a1},
+ { 0x1c58e8, 0x00000001, 0x00000001},
+ /* bank 5 */
+ { 0x1c58b0, 0x00000013, 0x00000013},
+ { 0x1c58e4, 0x00000002, 0x00000002},
+ /* bank 6 */
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00002c00, 0x00002c00},
+ { 0x1c58b0, 0x00004800, 0x00004800},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00006000, 0x00006000},
+ { 0x1c58b0, 0x00001000, 0x00001000},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00087c00, 0x00087c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00005400, 0x00005400},
+ { 0x1c58b0, 0x00000c00, 0x00000c00},
+ { 0x1c58b0, 0x00001800, 0x00001800},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00002c00, 0x00002c00},
+ { 0x1c58b0, 0x00003c00, 0x00003c00},
+ { 0x1c58b0, 0x00003800, 0x00003800},
+ { 0x1c58b0, 0x00001c00, 0x00001c00},
+ { 0x1c58b0, 0x00000800, 0x00000800},
+ { 0x1c58b0, 0x00000408, 0x00000408},
+ { 0x1c58b0, 0x00004c15, 0x00004c15},
+ { 0x1c58b0, 0x00004188, 0x00004188},
+ { 0x1c58b0, 0x0000201e, 0x0000201e},
+ { 0x1c58b0, 0x00010408, 0x00010408},
+ { 0x1c58b0, 0x00000801, 0x00000801},
+ { 0x1c58b0, 0x00000c08, 0x00000c08},
+ { 0x1c58b0, 0x0000181e, 0x0000181e},
+ { 0x1c58b0, 0x00001016, 0x00001016},
+ { 0x1c58b0, 0x00002800, 0x00002800},
+ { 0x1c58b0, 0x00004010, 0x00004010},
+ { 0x1c58b0, 0x0000081c, 0x0000081c},
+ { 0x1c58b0, 0x00000115, 0x00000115},
+ { 0x1c58b0, 0x00000015, 0x00000015},
+ { 0x1c58b0, 0x00000066, 0x00000066},
+ { 0x1c58b0, 0x0000001c, 0x0000001c},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000004, 0x00000004},
+ { 0x1c58b0, 0x00000015, 0x00000015},
+ { 0x1c58b0, 0x0000001f, 0x0000001f},
+ { 0x1c58e0, 0x00000000, 0x00000400},
+ /* bank 7 */
+ { 0x1c58b0, 0x000000a0, 0x000000a0},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000040, 0x00000040},
+ { 0x1c58f0, 0x0000001c, 0x0000001c},
+};
+
+static int carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+ int err, i;
+
+ carl9170_regwrite_begin(ar);
+
+ for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++)
+ carl9170_regwrite(carl9170_rf_initval[i].reg,
+ band5ghz ? carl9170_rf_initval[i]._5ghz
+ : carl9170_rf_initval[i]._2ghz);
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ wiphy_err(ar->hw->wiphy, "rf init failed\n");
+
+ return err;
+}
+
+struct carl9170_phy_freq_params {
+ u8 coeff_exp;
+ u16 coeff_man;
+ u8 coeff_exp_shgi;
+ u16 coeff_man_shgi;
+};
+
+enum carl9170_bw {
+ CARL9170_BW_20,
+ CARL9170_BW_40_BELOW,
+ CARL9170_BW_40_ABOVE,
+
+ __CARL9170_NUM_BW,
+};
+
+struct carl9170_phy_freq_entry {
+ u16 freq;
+ struct carl9170_phy_freq_params params[__CARL9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct carl9170_phy_freq_entry carl9170_phy_freq_params[] = {
+/*
+ * freq,
+ * 20MHz,
+ * 40MHz (below),
+ * 40Mhz (above),
+ */
+ { 2412, {
+ { 3, 21737, 3, 19563, },
+ { 3, 21827, 3, 19644, },
+ { 3, 21647, 3, 19482, },
+ } },
+ { 2417, {
+ { 3, 21692, 3, 19523, },
+ { 3, 21782, 3, 19604, },
+ { 3, 21602, 3, 19442, },
+ } },
+ { 2422, {
+ { 3, 21647, 3, 19482, },
+ { 3, 21737, 3, 19563, },
+ { 3, 21558, 3, 19402, },
+ } },
+ { 2427, {
+ { 3, 21602, 3, 19442, },
+ { 3, 21692, 3, 19523, },
+ { 3, 21514, 3, 19362, },
+ } },
+ { 2432, {
+ { 3, 21558, 3, 19402, },
+ { 3, 21647, 3, 19482, },
+ { 3, 21470, 3, 19323, },
+ } },
+ { 2437, {
+ { 3, 21514, 3, 19362, },
+ { 3, 21602, 3, 19442, },
+ { 3, 21426, 3, 19283, },
+ } },
+ { 2442, {
+ { 3, 21470, 3, 19323, },
+ { 3, 21558, 3, 19402, },
+ { 3, 21382, 3, 19244, },
+ } },
+ { 2447, {
+ { 3, 21426, 3, 19283, },
+ { 3, 21514, 3, 19362, },
+ { 3, 21339, 3, 19205, },
+ } },
+ { 2452, {
+ { 3, 21382, 3, 19244, },
+ { 3, 21470, 3, 19323, },
+ { 3, 21295, 3, 19166, },
+ } },
+ { 2457, {
+ { 3, 21339, 3, 19205, },
+ { 3, 21426, 3, 19283, },
+ { 3, 21252, 3, 19127, },
+ } },
+ { 2462, {
+ { 3, 21295, 3, 19166, },
+ { 3, 21382, 3, 19244, },
+ { 3, 21209, 3, 19088, },
+ } },
+ { 2467, {
+ { 3, 21252, 3, 19127, },
+ { 3, 21339, 3, 19205, },
+ { 3, 21166, 3, 19050, },
+ } },
+ { 2472, {
+ { 3, 21209, 3, 19088, },
+ { 3, 21295, 3, 19166, },
+ { 3, 21124, 3, 19011, },
+ } },
+ { 2484, {
+ { 3, 21107, 3, 18996, },
+ { 3, 21192, 3, 19073, },
+ { 3, 21022, 3, 18920, },
+ } },
+ { 4920, {
+ { 4, 21313, 4, 19181, },
+ { 4, 21356, 4, 19220, },
+ { 4, 21269, 4, 19142, },
+ } },
+ { 4940, {
+ { 4, 21226, 4, 19104, },
+ { 4, 21269, 4, 19142, },
+ { 4, 21183, 4, 19065, },
+ } },
+ { 4960, {
+ { 4, 21141, 4, 19027, },
+ { 4, 21183, 4, 19065, },
+ { 4, 21098, 4, 18988, },
+ } },
+ { 4980, {
+ { 4, 21056, 4, 18950, },
+ { 4, 21098, 4, 18988, },
+ { 4, 21014, 4, 18912, },
+ } },
+ { 5040, {
+ { 4, 20805, 4, 18725, },
+ { 4, 20846, 4, 18762, },
+ { 4, 20764, 4, 18687, },
+ } },
+ { 5060, {
+ { 4, 20723, 4, 18651, },
+ { 4, 20764, 4, 18687, },
+ { 4, 20682, 4, 18614, },
+ } },
+ { 5080, {
+ { 4, 20641, 4, 18577, },
+ { 4, 20682, 4, 18614, },
+ { 4, 20601, 4, 18541, },
+ } },
+ { 5180, {
+ { 4, 20243, 4, 18219, },
+ { 4, 20282, 4, 18254, },
+ { 4, 20204, 4, 18183, },
+ } },
+ { 5200, {
+ { 4, 20165, 4, 18148, },
+ { 4, 20204, 4, 18183, },
+ { 4, 20126, 4, 18114, },
+ } },
+ { 5220, {
+ { 4, 20088, 4, 18079, },
+ { 4, 20126, 4, 18114, },
+ { 4, 20049, 4, 18044, },
+ } },
+ { 5240, {
+ { 4, 20011, 4, 18010, },
+ { 4, 20049, 4, 18044, },
+ { 4, 19973, 4, 17976, },
+ } },
+ { 5260, {
+ { 4, 19935, 4, 17941, },
+ { 4, 19973, 4, 17976, },
+ { 4, 19897, 4, 17907, },
+ } },
+ { 5280, {
+ { 4, 19859, 4, 17873, },
+ { 4, 19897, 4, 17907, },
+ { 4, 19822, 4, 17840, },
+ } },
+ { 5300, {
+ { 4, 19784, 4, 17806, },
+ { 4, 19822, 4, 17840, },
+ { 4, 19747, 4, 17772, },
+ } },
+ { 5320, {
+ { 4, 19710, 4, 17739, },
+ { 4, 19747, 4, 17772, },
+ { 4, 19673, 4, 17706, },
+ } },
+ { 5500, {
+ { 4, 19065, 4, 17159, },
+ { 4, 19100, 4, 17190, },
+ { 4, 19030, 4, 17127, },
+ } },
+ { 5520, {
+ { 4, 18996, 4, 17096, },
+ { 4, 19030, 4, 17127, },
+ { 4, 18962, 4, 17065, },
+ } },
+ { 5540, {
+ { 4, 18927, 4, 17035, },
+ { 4, 18962, 4, 17065, },
+ { 4, 18893, 4, 17004, },
+ } },
+ { 5560, {
+ { 4, 18859, 4, 16973, },
+ { 4, 18893, 4, 17004, },
+ { 4, 18825, 4, 16943, },
+ } },
+ { 5580, {
+ { 4, 18792, 4, 16913, },
+ { 4, 18825, 4, 16943, },
+ { 4, 18758, 4, 16882, },
+ } },
+ { 5600, {
+ { 4, 18725, 4, 16852, },
+ { 4, 18758, 4, 16882, },
+ { 4, 18691, 4, 16822, },
+ } },
+ { 5620, {
+ { 4, 18658, 4, 16792, },
+ { 4, 18691, 4, 16822, },
+ { 4, 18625, 4, 16762, },
+ } },
+ { 5640, {
+ { 4, 18592, 4, 16733, },
+ { 4, 18625, 4, 16762, },
+ { 4, 18559, 4, 16703, },
+ } },
+ { 5660, {
+ { 4, 18526, 4, 16673, },
+ { 4, 18559, 4, 16703, },
+ { 4, 18493, 4, 16644, },
+ } },
+ { 5680, {
+ { 4, 18461, 4, 16615, },
+ { 4, 18493, 4, 16644, },
+ { 4, 18428, 4, 16586, },
+ } },
+ { 5700, {
+ { 4, 18396, 4, 16556, },
+ { 4, 18428, 4, 16586, },
+ { 4, 18364, 4, 16527, },
+ } },
+ { 5745, {
+ { 4, 18252, 4, 16427, },
+ { 4, 18284, 4, 16455, },
+ { 4, 18220, 4, 16398, },
+ } },
+ { 5765, {
+ { 4, 18189, 5, 32740, },
+ { 4, 18220, 4, 16398, },
+ { 4, 18157, 5, 32683, },
+ } },
+ { 5785, {
+ { 4, 18126, 5, 32626, },
+ { 4, 18157, 5, 32683, },
+ { 4, 18094, 5, 32570, },
+ } },
+ { 5805, {
+ { 4, 18063, 5, 32514, },
+ { 4, 18094, 5, 32570, },
+ { 4, 18032, 5, 32458, },
+ } },
+ { 5825, {
+ { 4, 18001, 5, 32402, },
+ { 4, 18032, 5, 32458, },
+ { 4, 17970, 5, 32347, },
+ } },
+ { 5170, {
+ { 4, 20282, 4, 18254, },
+ { 4, 20321, 4, 18289, },
+ { 4, 20243, 4, 18219, },
+ } },
+ { 5190, {
+ { 4, 20204, 4, 18183, },
+ { 4, 20243, 4, 18219, },
+ { 4, 20165, 4, 18148, },
+ } },
+ { 5210, {
+ { 4, 20126, 4, 18114, },
+ { 4, 20165, 4, 18148, },
+ { 4, 20088, 4, 18079, },
+ } },
+ { 5230, {
+ { 4, 20049, 4, 18044, },
+ { 4, 20088, 4, 18079, },
+ { 4, 20011, 4, 18010, },
+ } },
+};
+
+static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+ u32 freq, enum carl9170_bw bw)
+{
+ int err;
+ u32 d0, d1, td0, td1, fd0, fd1;
+ u8 chansel;
+ u8 refsel0 = 1, refsel1 = 0;
+ u8 lf_synth = 0;
+
+ switch (bw) {
+ case CARL9170_BW_40_ABOVE:
+ freq += 10;
+ break;
+ case CARL9170_BW_40_BELOW:
+ freq -= 10;
+ break;
+ case CARL9170_BW_20:
+ break;
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ if (band5ghz) {
+ if (freq % 10) {
+ chansel = (freq - 4800) / 5;
+ } else {
+ chansel = ((freq - 4800) / 10) * 2;
+ refsel0 = 0;
+ refsel1 = 1;
+ }
+ chansel = byte_rev_table[chansel];
+ } else {
+ if (freq == 2484) {
+ chansel = 10 + (freq - 2274) / 5;
+ lf_synth = 1;
+ } else
+ chansel = 16 + (freq - 2272) / 5;
+ chansel *= 4;
+ chansel = byte_rev_table[chansel];
+ }
+
+ d1 = chansel;
+ d0 = 0x21 |
+ refsel0 << 3 |
+ refsel1 << 2 |
+ lf_synth << 1;
+ td0 = d0 & 0x1f;
+ td1 = d1 & 0x1f;
+ fd0 = td1 << 5 | td0;
+
+ td0 = (d0 >> 5) & 0x7;
+ td1 = (d1 >> 5) & 0x7;
+ fd1 = td1 << 5 | td0;
+
+ carl9170_regwrite_begin(ar);
+
+ carl9170_regwrite(0x1c58b0, fd0);
+ carl9170_regwrite(0x1c58e8, fd1);
+
+ carl9170_regwrite_finish();
+ err = carl9170_regwrite_result();
+ if (err)
+ return err;
+
+ msleep(20);
+
+ return 0;
+}
+
+static const struct carl9170_phy_freq_params *
+carl9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+ enum carl9170_bw bw)
+{
+ unsigned int chanidx = 0;
+ u16 freq = 2412;
+
+ if (channel) {
+ chanidx = channel->hw_value;
+ freq = channel->center_freq;
+ }
+
+ BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params));
+
+ BUILD_BUG_ON(__CARL9170_NUM_BW != 3);
+
+ WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq);
+
+ return &carl9170_phy_freq_params[chanidx].params[bw];
+}
+
+static int carl9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
+{
+ int idx = nfreqs - 2;
+
+ while (idx >= 0) {
+ if (f >= freqs[idx])
+ return idx;
+ idx--;
+ }
+
+ return 0;
+}
+
+static s32 carl9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
+{
+ /* nothing to interpolate, it's horizontal */
+ if (y2 == y1)
+ return y1;
+
+ /* check if we hit one of the edges */
+ if (x == x1)
+ return y1;
+ if (x == x2)
+ return y2;
+
+ /* x1 == x2 is bad, hopefully == x */
+ if (x2 == x1)
+ return y1;
+
+ return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
+}
+
+static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT 8
+ s32 y;
+
+ y = carl9170_interpolate_s32(x << SHIFT, x1 << SHIFT,
+ y1 << SHIFT, x2 << SHIFT, y2 << SHIFT);
+
+ /*
+ * XXX: unwrap this expression
+ * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
+ * Can we rely on the compiler to optimise away the div?
+ */
+ return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+#undef SHIFT
+}
+
+static u8 carl9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (x <= x_array[i + 1])
+ break;
+ }
+
+ return carl9170_interpolate_u8(x, x_array[i], y_array[i],
+ x_array[i + 1], y_array[i + 1]);
+}
+
+static int carl9170_set_freq_cal_data(struct ar9170 *ar,
+ struct ieee80211_channel *channel)
+{
+ u8 *cal_freq_pier;
+ u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
+ u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
+ int chain, idx, i;
+ u32 phy_data = 0;
+ u8 f, tmp;
+
+ switch (channel->band) {
+ case IEEE80211_BAND_2GHZ:
+ f = channel->center_freq - 2300;
+ cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
+ i = AR5416_NUM_2G_CAL_PIERS - 1;
+ break;
+
+ case IEEE80211_BAND_5GHZ:
+ f = (channel->center_freq - 4800) / 5;
+ cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
+ i = AR5416_NUM_5G_CAL_PIERS - 1;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ for (; i >= 0; i--) {
+ if (cal_freq_pier[i] != 0xff)
+ break;
+ }
+ if (i < 0)
+ return -EINVAL;
+
+ idx = carl9170_find_freq_idx(i, cal_freq_pier, f);
+
+ carl9170_regwrite_begin(ar);
+
+ for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
+ for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
+ struct ar9170_calibration_data_per_freq *cal_pier_data;
+ int j;
+
+ switch (channel->band) {
+ case IEEE80211_BAND_2GHZ:
+ cal_pier_data = &ar->eeprom.
+ cal_pier_data_2G[chain][idx];
+ break;
+
+ case IEEE80211_BAND_5GHZ:
+ cal_pier_data = &ar->eeprom.
+ cal_pier_data_5G[chain][idx];
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ for (j = 0; j < 2; j++) {
+ vpds[j][i] = carl9170_interpolate_u8(f,
+ cal_freq_pier[idx],
+ cal_pier_data->vpd_pdg[j][i],
+ cal_freq_pier[idx + 1],
+ cal_pier_data[1].vpd_pdg[j][i]);
+
+ pwrs[j][i] = carl9170_interpolate_u8(f,
+ cal_freq_pier[idx],
+ cal_pier_data->pwr_pdg[j][i],
+ cal_freq_pier[idx + 1],
+ cal_pier_data[1].pwr_pdg[j][i]) / 2;
+ }
+ }
+
+ for (i = 0; i < 76; i++) {
+ if (i < 25) {
+ tmp = carl9170_interpolate_val(i, &pwrs[0][0],
+ &vpds[0][0]);
+ } else {
+ tmp = carl9170_interpolate_val(i - 12,
+ &pwrs[1][0],
+ &vpds[1][0]);
+ }
+
+ phy_data |= tmp << ((i & 3) << 3);
+ if ((i & 3) == 3) {
+ carl9170_regwrite(0x1c6280 + chain * 0x1000 +
+ (i & ~3), phy_data);
+ phy_data = 0;
+ }
+ }
+
+ for (i = 19; i < 32; i++)
+ carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
+ 0x0);
+ }
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+static u8 carl9170_get_max_edge_power(struct ar9170 *ar,
+ u32 freq, struct ar9170_calctl_edges edges[])
+{
+ int i;
+ u8 rc = AR5416_MAX_RATE_POWER;
+ u8 f;
+ if (freq < 3000)
+ f = freq - 2300;
+ else
+ f = (freq - 4800) / 5;
+
+ for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
+ if (edges[i].channel == 0xff)
+ break;
+ if (f == edges[i].channel) {
+ /* exact freq match */
+ rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
+ break;
+ }
+ if (i > 0 && f < edges[i].channel) {
+ if (f > edges[i - 1].channel &&
+ edges[i - 1].power_flags &
+ AR9170_CALCTL_EDGE_FLAGS) {
+ /* lower channel has the inband flag set */
+ rc = edges[i - 1].power_flags &
+ ~AR9170_CALCTL_EDGE_FLAGS;
+ }
+ break;
+ }
+ }
+
+ if (i == AR5416_NUM_BAND_EDGES) {
+ if (f > edges[i - 1].channel &&
+ edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
+ /* lower channel has the inband flag set */
+ rc = edges[i - 1].power_flags &
+ ~AR9170_CALCTL_EDGE_FLAGS;
+ }
+ }
+ return rc;
+}
+
+static u8 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq,
+ enum carl9170_bw bw, struct ar9170_calctl_edges edges[])
+{
+ u8 f;
+ int i;
+ u8 rc = 0;
+
+ if (freq < 3000)
+ f = freq - 2300;
+ else
+ f = (freq - 4800) / 5;
+
+ if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_BW_40_ABOVE)
+ rc |= 0xf0;
+
+ for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
+ if (edges[i].channel == 0xff)
+ break;
+ if (f == edges[i].channel) {
+ if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
+ rc |= 0x0f;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * calculate the conformance test limits and the heavy clip parameter
+ * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706)
+ */
+static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
+{
+ u8 ctl_grp; /* CTL group */
+ u8 ctl_idx; /* CTL index */
+ int i, j;
+ struct ctl_modes {
+ u8 ctl_mode;
+ u8 max_power;
+ u8 *pwr_cal_data;
+ int pwr_cal_len;
+ } *modes;
+
+ /*
+ * order is relevant in the mode_list_*: we fall back to the
+ * lower indices if any mode is missed in the EEPROM.
+ */
+ struct ctl_modes mode_list_2ghz[] = {
+ { CTL_11B, 0, ar->power_2G_cck, 4 },
+ { CTL_11G, 0, ar->power_2G_ofdm, 4 },
+ { CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
+ { CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
+ };
+ struct ctl_modes mode_list_5ghz[] = {
+ { CTL_11A, 0, ar->power_5G_leg, 4 },
+ { CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
+ { CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
+ };
+ int nr_modes;
+
+#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
+
+ ar->heavy_clip = 0;
+
+ /*
+ * TODO: investigate the differences between OTUS'
+ * hpreg.c::zfHpGetRegulatoryDomain() and
+ * ath/regd.c::ath_regd_get_band_ctl() -
+ * e.g. for FCC3_WORLD the OTUS procedure
+ * always returns CTL_FCC, while the one in ath/ delivers
+ * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
+ */
+ ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
+ ar->hw->conf.channel->band);
+
+ /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
+ if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
+ ctl_grp = CTL_FCC;
+
+ if (ctl_grp != CTL_FCC)
+ /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
+ return;
+
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+ modes = mode_list_2ghz;
+ nr_modes = ARRAY_SIZE(mode_list_2ghz);
+ } else {
+ modes = mode_list_5ghz;
+ nr_modes = ARRAY_SIZE(mode_list_5ghz);
+ }
+
+ for (i = 0; i < nr_modes; i++) {
+ u8 c = ctl_grp | modes[i].ctl_mode;
+ for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
+ if (c == ar->eeprom.ctl_index[ctl_idx])
+ break;
+ if (ctl_idx < AR5416_NUM_CTLS) {
+ int f_off = 0;
+
+ /*
+ * determine heavy clip parameter
+ * from the 11G edges array
+ */
+ if (modes[i].ctl_mode == CTL_11G) {
+ ar->heavy_clip =
+ carl9170_get_heavy_clip(ar,
+ freq, bw, EDGES(ctl_idx, 1));
+ }
+
+ /* adjust freq for 40MHz */
+ if (modes[i].ctl_mode == CTL_2GHT40 ||
+ modes[i].ctl_mode == CTL_5GHT40) {
+ if (bw == CARL9170_BW_40_BELOW)
+ f_off = -10;
+ else
+ f_off = 10;
+ }
+
+ modes[i].max_power =
+ carl9170_get_max_edge_power(ar,
+ freq+f_off, EDGES(ctl_idx, 1));
+
+ /*
+ * TODO: check if the regulatory max. power is
+ * controlled by cfg80211 for DFS.
+ * (hpmain applies it to max_power itself for DFS freq)
+ */
+
+ } else {
+ /*
+ * Workaround in otus driver, hpmain.c, line 3906:
+ * if no data for 5GHT20 are found, take the
+ * legacy 5G value. We extend this here to fallback
+ * from any other HT* or 11G, too.
+ */
+ int k = i;
+
+ modes[i].max_power = AR5416_MAX_RATE_POWER;
+ while (k-- > 0) {
+ if (modes[k].max_power !=
+ AR5416_MAX_RATE_POWER) {
+ modes[i].max_power = modes[k].max_power;
+ break;
+ }
+ }
+ }
+
+ /* apply max power to pwr_cal_data (ar->power_*) */
+ for (j = 0; j < modes[i].pwr_cal_len; j++) {
+ modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
+ modes[i].max_power);
+ }
+ }
+
+ if (ar->heavy_clip & 0xf0) {
+ ar->power_2G_ht40[0]--;
+ ar->power_2G_ht40[1]--;
+ ar->power_2G_ht40[2]--;
+ }
+ if (ar->heavy_clip & 0xf) {
+ ar->power_2G_ht20[0]++;
+ ar->power_2G_ht20[1]++;
+ ar->power_2G_ht20[2]++;
+ }
+
+#undef EDGES
+}
+
+static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
+ enum carl9170_bw bw)
+{
+ struct ar9170_calibration_target_power_legacy *ctpl;
+ struct ar9170_calibration_target_power_ht *ctph;
+ u8 *ctpres;
+ int ntargets;
+ int idx, i, n;
+ u8 ackpower, ackchains, f;
+ u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
+
+ if (freq < 3000)
+ f = freq - 2300;
+ else
+ f = (freq - 4800)/5;
+
+ /*
+ * cycle through the various modes
+ *
+ * legacy modes first: 5G, 2G CCK, 2G OFDM
+ */
+ for (i = 0; i < 3; i++) {
+ switch (i) {
+ case 0: /* 5 GHz legacy */
+ ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_leg;
+ break;
+ case 1: /* 2.4 GHz CCK */
+ ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
+ ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
+ ctpres = ar->power_2G_cck;
+ break;
+ case 2: /* 2.4 GHz OFDM */
+ ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ofdm;
+ break;
+ default:
+ BUG();
+ }
+
+ for (n = 0; n < ntargets; n++) {
+ if (ctpl[n].freq == 0xff)
+ break;
+ pwr_freqs[n] = ctpl[n].freq;
+ }
+ ntargets = n;
+ idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 4; n++)
+ ctpres[n] = carl9170_interpolate_u8(f,
+ ctpl[idx + 0].freq, ctpl[idx + 0].power[n],
+ ctpl[idx + 1].freq, ctpl[idx + 1].power[n]);
+ }
+
+ /* HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 */
+ for (i = 0; i < 4; i++) {
+ switch (i) {
+ case 0: /* 5 GHz HT 20 */
+ ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_ht20;
+ break;
+ case 1: /* 5 GHz HT 40 */
+ ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_ht40;
+ break;
+ case 2: /* 2.4 GHz HT 20 */
+ ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ht20;
+ break;
+ case 3: /* 2.4 GHz HT 40 */
+ ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ht40;
+ break;
+ default:
+ BUG();
+ }
+
+ for (n = 0; n < ntargets; n++) {
+ if (ctph[n].freq == 0xff)
+ break;
+ pwr_freqs[n] = ctph[n].freq;
+ }
+ ntargets = n;
+ idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 8; n++)
+ ctpres[n] = carl9170_interpolate_u8(f,
+ ctph[idx + 0].freq, ctph[idx + 0].power[n],
+ ctph[idx + 1].freq, ctph[idx + 1].power[n]);
+ }
+
+ /* calc. conformance test limits and apply to ar->power*[] */
+ carl9170_calc_ctl(ar, freq, bw);
+
+ /* set ACK/CTS TX power */
+ carl9170_regwrite_begin(ar);
+
+ if (ar->eeprom.tx_mask != 1)
+ ackchains = AR9170_TX_PHY_TXCHAIN_2;
+ else
+ ackchains = AR9170_TX_PHY_TXCHAIN_1;
+
+ if (freq < 3000)
+ ackpower = ar->power_2G_ofdm[0] & 0x3f;
+ else
+ ackpower = ar->power_5G_leg[0] & 0x3f;
+
+ carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
+ 0x3c1e | ackpower << 20 | ackchains << 26);
+ carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
+ ackpower << 5 | ackchains << 11 |
+ ackpower << 21 | ackchains << 27);
+
+ carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
+ ackpower << 5 | ackchains << 11 |
+ ackpower << 21 | ackchains << 27);
+
+ carl9170_regwrite_finish();
+ return carl9170_regwrite_result();
+}
+
+/* TODO: replace this with sign_extend32(noise, 8) */
+static int carl9170_calc_noise_dbm(u32 raw_noise)
+{
+ if (raw_noise & 0x100)
+ return ~((raw_noise & 0x0ff) >> 1);
+ else
+ return (raw_noise & 0xff) >> 1;
+}
+
+int carl9170_get_noisefloor(struct ar9170 *ar)
+{
+ static const u32 phy_regs[] = {
+ AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH1_CCA,
+ AR9170_PHY_REG_CH2_CCA, AR9170_PHY_REG_EXT_CCA,
+ AR9170_PHY_REG_CH1_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA };
+ u32 phy_res[ARRAY_SIZE(phy_regs)];
+ int err, i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise));
+
+ err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res);
+ if (err)
+ return err;
+
+ for (i = 0; i < 3; i++) {
+ ar->noise[i] = carl9170_calc_noise_dbm(
+ (phy_res[i] >> 19) & 0x1ff);
+
+ ar->noise[i + 3] = carl9170_calc_noise_dbm(
+ (phy_res[i + 3] >> 23) & 0x1ff);
+ }
+
+ return 0;
+}
+
+static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
+{
+ switch (type) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ return CARL9170_BW_20;
+ case NL80211_CHAN_HT40MINUS:
+ return CARL9170_BW_40_BELOW;
+ case NL80211_CHAN_HT40PLUS:
+ return CARL9170_BW_40_ABOVE;
+ default:
+ BUG();
+ }
+}
+
+int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum nl80211_channel_type _bw,
+ enum carl9170_rf_init_mode rfi)
+{
+ const struct carl9170_phy_freq_params *freqpar;
+ struct carl9170_rf_init_result rf_res;
+ struct carl9170_rf_init rf;
+ u32 cmd, tmp, offs = 0;
+ int err;
+ enum carl9170_bw bw;
+ bool warm_reset;
+ struct ieee80211_channel *old_channel = NULL;
+
+ bw = nl80211_to_carl(_bw);
+
+ /* may be NULL at first setup */
+ if (ar->channel) {
+ old_channel = ar->channel;
+ warm_reset = (old_channel->band != channel->band) ||
+ (old_channel->center_freq ==
+ channel->center_freq);
+
+ ar->channel = NULL;
+ } else {
+ warm_reset = true;
+ }
+
+ /* HW workaround */
+ if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+ channel->center_freq <= 2417)
+ warm_reset = true;
+
+ if (rfi != CARL9170_RFI_NONE || warm_reset) {
+ u32 val;
+
+ if (rfi == CARL9170_RFI_COLD)
+ val = AR9170_PWR_RESET_BB_COLD_RESET;
+ else
+ val = AR9170_PWR_RESET_BB_WARM_RESET;
+
+ /* warm/cold reset BB/ADDA */
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val);
+ if (err)
+ return err;
+
+ err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
+ if (err)
+ return err;
+
+ err = carl9170_init_phy(ar, channel->band);
+ if (err)
+ return err;
+
+ err = carl9170_init_rf_banks_0_7(ar,
+ channel->band == IEEE80211_BAND_5GHZ);
+ if (err)
+ return err;
+
+ cmd = CARL9170_CMD_RF_INIT;
+
+ msleep(100);
+
+ err = carl9170_echo_test(ar, 0xaabbccdd);
+ if (err)
+ return err;
+ } else {
+ cmd = CARL9170_CMD_FREQUENCY;
+ }
+
+ err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+ if (err)
+ return err;
+
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
+ 0x200);
+
+ err = carl9170_init_rf_bank4_pwr(ar,
+ channel->band == IEEE80211_BAND_5GHZ,
+ channel->center_freq, bw);
+ if (err)
+ return err;
+
+ tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 |
+ AR9170_PHY_TURBO_FC_HT_EN;
+
+ switch (bw) {
+ case CARL9170_BW_20:
+ break;
+ case CARL9170_BW_40_BELOW:
+ tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
+ AR9170_PHY_TURBO_FC_SHORT_GI_40;
+ offs = 3;
+ break;
+ case CARL9170_BW_40_ABOVE:
+ tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN |
+ AR9170_PHY_TURBO_FC_SHORT_GI_40 |
+ AR9170_PHY_TURBO_FC_DYN2040_PRI_CH;
+ offs = 1;
+ break;
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ if (ar->eeprom.tx_mask != 1)
+ tmp |= AR9170_PHY_TURBO_FC_WALSH;
+
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp);
+ if (err)
+ return err;
+
+ err = carl9170_set_freq_cal_data(ar, channel);
+ if (err)
+ return err;
+
+ err = carl9170_set_power_cal(ar, channel->center_freq, bw);
+ if (err)
+ return err;
+
+ freqpar = carl9170_get_hw_dyn_params(channel, bw);
+
+ rf.ht_settings = 0;
+ if (conf_is_ht(&ar->hw->conf)) {
+ rf.ht_settings |= CARL9170FW_PHY_HT_ENABLE;
+
+ if (conf_is_ht40(&ar->hw->conf)) {
+ rf.ht_settings |= CARL9170FW_PHY_HT_DYN2040;
+ SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF,
+ rf.ht_settings, offs);
+ }
+ }
+
+ rf.freq = cpu_to_le32(channel->center_freq * 1000);
+ rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp);
+ rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
+ rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
+ rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
+
+ if (rfi != CARL9170_RFI_NONE)
+ rf.finiteLoopCount = cpu_to_le32(2000);
+ else
+ rf.finiteLoopCount = cpu_to_le32(1000);
+
+ err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf,
+ sizeof(rf_res), &rf_res);
+ if (err)
+ return err;
+
+ err = le32_to_cpu(rf_res.ret);
+ if (err != 0) {
+ ar->chan_fail++;
+ ar->total_chan_fail++;
+
+ wiphy_err(ar->hw->wiphy, "channel change: %d -> %d "
+ "failed (%d).\n", old_channel ?
+ old_channel->center_freq : -1, channel->center_freq,
+ err);
+
+ if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) {
+ /*
+ * We have tried very hard to change to _another_
+ * channel and we've failed to do so!
+ * Chances are that the PHY/RF is no longer
+ * operable (due to corruptions/fatal events/bugs?)
+ * and we need to reset at a higher level.
+ */
+ carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS);
+ return 0;
+ }
+
+ err = carl9170_set_channel(ar, channel, _bw,
+ CARL9170_RFI_COLD);
+ if (err)
+ return err;
+ } else {
+ ar->chan_fail = 0;
+ }
+
+ err = carl9170_get_noisefloor(ar);
+ if (err)
+ return err;
+
+ if (ar->heavy_clip) {
+ err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
+ 0x200 | ar->heavy_clip);
+ if (err) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "failed to set "
+ "heavy clip\n");
+ }
+
+ return err;
+ }
+ }
+
+ /* FIXME: PSM does not work in 5GHz Band */
+ if (channel->band == IEEE80211_BAND_5GHZ)
+ ar->ps.off_override |= PS_OFF_5GHZ;
+ else
+ ar->ps.off_override &= ~PS_OFF_5GHZ;
+
+ ar->channel = channel;
+ return 0;
+}
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
new file mode 100644
index 000000000000..53c18d34ffcc
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -0,0 +1,567 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * PHY register map
+ *
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CARL9170_SHARED_PHY_H
+#define __CARL9170_SHARED_PHY_H
+
+#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800)
+#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \
+ ((_n) << 2))
+
+#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000)
+#define AR9170_PHY_TEST_AGC_CLR 0x10000000
+#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000
+
+#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004)
+#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001
+#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002
+#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004
+#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008
+#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010
+/* For 25 MHz channel spacing -- not used but supported by hw */
+#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020
+#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040
+#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080
+#define AR9170_PHY_TURBO_FC_WALSH 0x00000100
+#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200
+#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800
+
+#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008)
+
+#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010)
+#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000
+#define AR9170_PHY_TIMING2_FORCE 0x00000fff
+#define AR9170_PHY_TIMING2_FORCE_S 0
+
+#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014)
+#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000
+#define AR9170_PHY_TIMING3_DSC_EXP_S 13
+#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000
+#define AR9170_PHY_TIMING3_DSC_MAN_S 17
+
+#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018)
+#define AR9170_PHY_CHIP_ID_REV_0 0x80
+#define AR9170_PHY_CHIP_ID_REV_1 0x81
+#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0
+
+#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c)
+#define AR9170_PHY_ACTIVE_EN 0x00000001
+#define AR9170_PHY_ACTIVE_DIS 0x00000000
+
+#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024)
+#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff
+#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0
+#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00
+#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8
+
+#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028)
+#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000
+#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16
+
+#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c)
+#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
+#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
+#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
+#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
+#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000
+#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
+#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16
+
+#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030)
+#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000
+#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001
+
+#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034)
+#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000
+#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
+#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000
+#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
+#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00
+#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
+#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff
+#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
+
+#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c)
+
+#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044)
+#define AR9170_PHY_SETTLING_SWITCH 0x00003f80
+#define AR9170_PHY_SETTLING_SWITCH_S 7
+
+#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048)
+#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048)
+#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000
+#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12
+#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000
+#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18
+
+#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050)
+#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff
+#define AR9170_PHY_DESIRED_SZ_ADC_S 0
+#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00
+#define AR9170_PHY_DESIRED_SZ_PGA_S 8
+#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000
+#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20
+
+#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058)
+#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000
+#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000
+#define AR9170_PHY_FIND_SIG_FIRPWR_S 18
+
+#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c)
+#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80
+#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7
+#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000
+#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15
+
+#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060)
+#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001
+#define AR9170_PHY_AGC_CONTROL_NF 0x00000002
+#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
+#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
+#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
+
+#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
+#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CCA_MINCCA_PWR_S 19
+#define AR9170_PHY_CCA_THRESH62 0x0007f000
+#define AR9170_PHY_CCA_THRESH62_S 12
+
+#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068)
+#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f
+#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0
+#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000
+#define AR9170_PHY_SFCORR_M1_THRESH_S 17
+#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000
+#define AR9170_PHY_SFCORR_M2_THRESH_S 24
+
+#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c)
+#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
+#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00
+#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
+#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000
+#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
+#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000
+#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
+
+#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070)
+#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074)
+#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078)
+
+#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c)
+#define AR9170_PHY_PLL_CTL_40 0xaa
+#define AR9170_PHY_PLL_CTL_40_5413 0x04
+#define AR9170_PHY_PLL_CTL_44 0xab
+#define AR9170_PHY_PLL_CTL_44_2133 0xeb
+#define AR9170_PHY_PLL_CTL_40_2133 0xea
+
+#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100)
+#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104)
+#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108)
+#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c)
+
+/* analogue power on time (100ns) */
+#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114)
+#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118)
+#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff
+
+#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \
+ (0x0120 + ((_i) << 12)))
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
+#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
+#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000
+#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
+#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
+#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
+
+#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124)
+#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe
+#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1
+
+#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134)
+#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138)
+#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c)
+#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144)
+#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038
+#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3
+
+#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
+#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
+#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9)
+#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
+#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
+#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f
+#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
+
+#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140)
+#define AR9170_PHY_RADAR_EXT_ENA 0x00004000
+
+#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154)
+#define AR9170_PHY_RADAR_0_ENA 0x00000001
+#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000
+/* inband pulse threshold */
+#define AR9170_PHY_RADAR_0_INBAND 0x0000003e
+#define AR9170_PHY_RADAR_0_INBAND_S 1
+/* pulse RSSI threshold */
+#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0
+#define AR9170_PHY_RADAR_0_PRSSI_S 6
+/* pulse height threshold */
+#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000
+#define AR9170_PHY_RADAR_0_HEIGHT_S 12
+/* radar RSSI threshold */
+#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000
+#define AR9170_PHY_RADAR_0_RRSSI_S 18
+/* radar firepower threshold */
+#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000
+#define AR9170_PHY_RADAR_0_FIRPWR_S 24
+
+#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158)
+#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000
+#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000
+#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000
+#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16
+#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000
+#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000
+#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
+#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00
+#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff
+#define AR9170_PHY_RADAR_1_MAXLEN_S 0
+
+#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160)
+#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160)
+
+#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164)
+
+#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168)
+
+#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c)
+#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
+#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8
+#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3
+#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00
+#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8
+#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
+#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170)
+#define AR9170_PHY_RESTART_DIV_GC 0x001c0000
+#define AR9170_PHY_RESTART_DIV_GC_S 18
+
+#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c)
+#define AR9170_PHY_RFBUS_REQ_EN 0x00000001
+
+#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180)
+#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184)
+#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff
+#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0
+
+#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188)
+#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c)
+#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190)
+#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194)
+#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff
+#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0
+
+#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198)
+#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c)
+#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff
+#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0
+
+#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0)
+#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff
+#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
+#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000
+#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20
+#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
+#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
+
+#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4)
+#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \
+ 0x01b4 + ((_i) << 12))
+#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+
+#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac)
+#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
+#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000
+#define AR9170_PHY_9285_ANT_DIV_CTL_S 24
+#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
+#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
+#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
+#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
+#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
+#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
+#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
+#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
+#define AR9170_PHY_9285_ANT_DIV_LNA1 2
+#define AR9170_PHY_9285_ANT_DIV_LNA2 1
+#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
+#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
+#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0
+#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1
+
+#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8)
+#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff
+#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0
+
+#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc)
+#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00
+#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
+#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
+#define AR9170_PHY_EXT_CCA_THRESH62_S 16
+#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_EXT_MINCCA_PWR_S 23
+
+#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000
+#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000
+#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
+
+#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0)
+#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0
+#define AR9170_PHY_HALFGI_DSC_MAN_S 4
+#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f
+#define AR9170_PHY_HALFGI_DSC_EXP_S 0
+
+#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4)
+#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8)
+
+#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc)
+#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
+
+#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0)
+#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec)
+#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000
+
+#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0)
+#define AR9170_PHY_CALMODE_IQ 0x00000000
+#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001
+#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002
+#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003
+
+#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4)
+#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8)
+
+
+#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \
+ 0x0410 + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \
+ 0x0414 \ + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \
+ 0x0418 + ((_i) << 12))
+#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \
+ 0x041c + ((_i) << 12))
+
+#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c)
+
+#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420)
+#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001
+
+#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4)
+#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc)
+
+#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00)
+#define AR9170_PHY_MODE_ASYNCFIFO 0x80
+#define AR9170_PHY_MODE_AR2133 0x08
+#define AR9170_PHY_MODE_AR5111 0x00
+#define AR9170_PHY_MODE_AR5112 0x08
+#define AR9170_PHY_MODE_DYNAMIC 0x04
+#define AR9170_PHY_MODE_RF2GHZ 0x02
+#define AR9170_PHY_MODE_RF5GHZ 0x00
+#define AR9170_PHY_MODE_CCK 0x01
+#define AR9170_PHY_MODE_OFDM 0x00
+#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100
+
+#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04)
+#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c
+#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
+
+#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08)
+#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f
+#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
+/* [12:6] settling time for antenna switch */
+#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0
+#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
+#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
+#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
+
+#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c)
+#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c)
+#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000
+#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
+#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00
+#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
+#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f
+#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0
+#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f
+#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
+
+#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c)
+#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000
+#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28)
+#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
+#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00
+#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10
+
+#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c)
+#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
+
+#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34)
+#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38)
+
+#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c)
+#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40)
+#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44)
+#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54)
+
+#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58)
+#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
+#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14
+#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000
+#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16
+#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000
+#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18
+#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000
+#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20
+#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
+#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64)
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe
+#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
+
+#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68)
+#define AR9170_PHY_ANALOG_SWAP_AB 0x0001
+#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040
+
+#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c)
+#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f
+#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000
+#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
+
+#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70)
+#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70)
+#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
+#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
+
+#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74)
+#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000
+#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+
+#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c)
+#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00
+#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10
+#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
+#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
+
+#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00)
+#define AR9170_PHY_TX_GAIN 0x0007f000
+#define AR9170_PHY_TX_GAIN_S 12
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58)
+#define AR9170_PHY_CL_CAL_ENABLE 0x00000002
+#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001
+
+#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c)
+#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90)
+
+#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98)
+#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98)
+#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00
+#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
+#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c)
+#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0)
+#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4)
+#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8)
+#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac)
+#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0)
+#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4)
+#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8)
+#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc)
+#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0)
+#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4)
+#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8)
+#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc)
+#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0)
+#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4)
+#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8)
+#define AR9170_PHY_FORCE_XPA_CFG 0x000000001
+#define AR9170_PHY_FORCE_XPA_CFG_S 0
+
+#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
+#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CH1_MINCCA_PWR_S 19
+
+#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
+#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000
+#define AR9170_PHY_CH2_MINCCA_PWR_S 19
+
+#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
+#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23
+
+#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
+#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000
+#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23
+
+#define REDUCE_CHAIN_0 0x00000050
+#define REDUCE_CHAIN_1 0x00000051
+
+#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
new file mode 100644
index 000000000000..671dbc429547
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -0,0 +1,909 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * 802.11 & command trap routines
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/crc32.h>
+#include <net/mac80211.h>
+#include "carl9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len)
+{
+ bool restart = false;
+ enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON;
+
+ if (len > 3) {
+ if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) {
+ ar->fw.err_counter++;
+ if (ar->fw.err_counter > 3) {
+ restart = true;
+ reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS;
+ }
+ }
+
+ if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) {
+ ar->fw.bug_counter++;
+ restart = true;
+ reason = CARL9170_RR_FATAL_FIRMWARE_ERROR;
+ }
+ }
+
+ wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf);
+
+ if (restart)
+ carl9170_restart(ar, reason);
+}
+
+static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp)
+{
+ u32 ps;
+ bool new_ps;
+
+ ps = le32_to_cpu(rsp->psm.state);
+
+ new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE;
+ if (ar->ps.state != new_ps) {
+ if (!new_ps) {
+ ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
+ ar->ps.last_action);
+ }
+
+ ar->ps.last_action = jiffies;
+
+ ar->ps.state = new_ps;
+ }
+}
+
+static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq)
+{
+ if (ar->cmd_seq < -1)
+ return 0;
+
+ /*
+ * Initialize Counter
+ */
+ if (ar->cmd_seq < 0)
+ ar->cmd_seq = seq;
+
+ /*
+ * The sequence is strictly monotonic increasing and it never skips!
+ *
+ * Therefore we can safely assume that whenever we received an
+ * unexpected sequence we have lost some valuable data.
+ */
+ if (seq != ar->cmd_seq) {
+ int count;
+
+ count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs;
+
+ wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! "
+ "w:%d g:%d\n", count, ar->cmd_seq, seq);
+
+ carl9170_restart(ar, CARL9170_RR_LOST_RSP);
+ return -EIO;
+ }
+
+ ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs;
+ return 0;
+}
+
+static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
+{
+ /*
+ * Some commands may have a variable response length
+ * and we cannot predict the correct length in advance.
+ * So we only check if we provided enough space for the data.
+ */
+ if (unlikely(ar->readlen != (len - 4))) {
+ dev_warn(&ar->udev->dev, "received invalid command response:"
+ "got %d, instead of %d\n", len - 4, ar->readlen);
+ print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET,
+ ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f);
+ print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET,
+ buffer, len);
+ /*
+ * Do not complete. The command times out,
+ * and we get a stack trace from there.
+ */
+ carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
+ }
+
+ spin_lock(&ar->cmd_lock);
+ if (ar->readbuf) {
+ if (len >= 4)
+ memcpy(ar->readbuf, buffer + 4, len - 4);
+
+ ar->readbuf = NULL;
+ }
+ complete(&ar->cmd_wait);
+ spin_unlock(&ar->cmd_lock);
+}
+
+void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
+{
+ struct carl9170_rsp *cmd = (void *) buf;
+ struct ieee80211_vif *vif;
+
+ if (carl9170_check_sequence(ar, cmd->hdr.seq))
+ return;
+
+ if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) {
+ if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG))
+ carl9170_cmd_callback(ar, len, buf);
+
+ return;
+ }
+
+ if (unlikely(cmd->hdr.len != (len - 4))) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "FW: received over-/under"
+ "sized event %x (%d, but should be %d).\n",
+ cmd->hdr.cmd, cmd->hdr.len, len - 4);
+
+ print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE,
+ buf, len);
+ }
+
+ return;
+ }
+
+ /* hardware event handlers */
+ switch (cmd->hdr.cmd) {
+ case CARL9170_RSP_PRETBTT:
+ /* pre-TBTT event */
+ rcu_read_lock();
+ vif = carl9170_get_main_vif(ar);
+
+ if (!vif) {
+ rcu_read_unlock();
+ break;
+ }
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ carl9170_handle_ps(ar, cmd);
+ break;
+
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_ADHOC:
+ carl9170_update_beacon(ar, true);
+ break;
+
+ default:
+ break;
+ }
+ rcu_read_unlock();
+
+ break;
+
+
+ case CARL9170_RSP_TXCOMP:
+ /* TX status notification */
+ carl9170_tx_process_status(ar, cmd);
+ break;
+
+ case CARL9170_RSP_BEACON_CONFIG:
+ /*
+ * (IBSS) beacon send notification
+ * bytes: 04 c2 XX YY B4 B3 B2 B1
+ *
+ * XX always 80
+ * YY always 00
+ * B1-B4 "should" be the number of send out beacons.
+ */
+ break;
+
+ case CARL9170_RSP_ATIM:
+ /* End of Atim Window */
+ break;
+
+ case CARL9170_RSP_WATCHDOG:
+ /* Watchdog Interrupt */
+ carl9170_restart(ar, CARL9170_RR_WATCHDOG);
+ break;
+
+ case CARL9170_RSP_TEXT:
+ /* firmware debug */
+ carl9170_dbg_message(ar, (char *)buf + 4, len - 4);
+ break;
+
+ case CARL9170_RSP_HEXDUMP:
+ wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4);
+ print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE,
+ (char *)buf + 4, len - 4);
+ break;
+
+ case CARL9170_RSP_RADAR:
+ if (!net_ratelimit())
+ break;
+
+ wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this "
+ "incident to linux-wireless@vger.kernel.org !\n");
+ break;
+
+ case CARL9170_RSP_GPIO:
+#ifdef CONFIG_CARL9170_WPC
+ if (ar->wps.pbc) {
+ bool state = !!(cmd->gpio.gpio & cpu_to_le32(
+ AR9170_GPIO_PORT_WPS_BUTTON_PRESSED));
+
+ if (state != ar->wps.pbc_state) {
+ ar->wps.pbc_state = state;
+ input_report_key(ar->wps.pbc, KEY_WPS_BUTTON,
+ state);
+ input_sync(ar->wps.pbc);
+ }
+ }
+#endif /* CONFIG_CARL9170_WPC */
+ break;
+
+ case CARL9170_RSP_BOOT:
+ complete(&ar->fw_boot_wait);
+ break;
+
+ default:
+ wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n",
+ cmd->hdr.cmd);
+ print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+ break;
+ }
+}
+
+static int carl9170_rx_mac_status(struct ar9170 *ar,
+ struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac,
+ struct ieee80211_rx_status *status)
+{
+ struct ieee80211_channel *chan;
+ u8 error, decrypt;
+
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
+
+ error = mac->error;
+
+ if (error & AR9170_RX_ERROR_WRONG_RA) {
+ if (!ar->sniffer_enabled)
+ return -EINVAL;
+ }
+
+ if (error & AR9170_RX_ERROR_PLCP) {
+ if (!(ar->filter_state & FIF_PLCPFAIL))
+ return -EINVAL;
+
+ status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+ }
+
+ if (error & AR9170_RX_ERROR_FCS) {
+ ar->tx_fcs_errors++;
+
+ if (!(ar->filter_state & FIF_FCSFAIL))
+ return -EINVAL;
+
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+
+ decrypt = ar9170_get_decrypt_type(mac);
+ if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+ decrypt != AR9170_ENC_ALG_NONE) {
+ if ((decrypt == AR9170_ENC_ALG_TKIP) &&
+ (error & AR9170_RX_ERROR_MMIC))
+ status->flag |= RX_FLAG_MMIC_ERROR;
+
+ status->flag |= RX_FLAG_DECRYPTED;
+ }
+
+ if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled)
+ return -ENODATA;
+
+ error &= ~(AR9170_RX_ERROR_MMIC |
+ AR9170_RX_ERROR_FCS |
+ AR9170_RX_ERROR_WRONG_RA |
+ AR9170_RX_ERROR_DECRYPT |
+ AR9170_RX_ERROR_PLCP);
+
+ /* drop any other error frames */
+ if (unlikely(error)) {
+ /* TODO: update netdevice's RX dropped/errors statistics */
+
+ if (net_ratelimit())
+ wiphy_dbg(ar->hw->wiphy, "received frame with "
+ "suspicious error code (%#x).\n", error);
+
+ return -EINVAL;
+ }
+
+ chan = ar->channel;
+ if (chan) {
+ status->band = chan->band;
+ status->freq = chan->center_freq;
+ }
+
+ switch (mac->status & AR9170_RX_STATUS_MODULATION) {
+ case AR9170_RX_STATUS_MODULATION_CCK:
+ if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+ status->flag |= RX_FLAG_SHORTPRE;
+ switch (head->plcp[0]) {
+ case AR9170_RX_PHY_RATE_CCK_1M:
+ status->rate_idx = 0;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_2M:
+ status->rate_idx = 1;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_5M:
+ status->rate_idx = 2;
+ break;
+ case AR9170_RX_PHY_RATE_CCK_11M:
+ status->rate_idx = 3;
+ break;
+ default:
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "invalid plcp cck "
+ "rate (%x).\n", head->plcp[0]);
+ }
+
+ return -EINVAL;
+ }
+ break;
+
+ case AR9170_RX_STATUS_MODULATION_DUPOFDM:
+ case AR9170_RX_STATUS_MODULATION_OFDM:
+ switch (head->plcp[0] & 0xf) {
+ case AR9170_TXRX_PHY_RATE_OFDM_6M:
+ status->rate_idx = 0;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_9M:
+ status->rate_idx = 1;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_12M:
+ status->rate_idx = 2;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_18M:
+ status->rate_idx = 3;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_24M:
+ status->rate_idx = 4;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_36M:
+ status->rate_idx = 5;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_48M:
+ status->rate_idx = 6;
+ break;
+ case AR9170_TXRX_PHY_RATE_OFDM_54M:
+ status->rate_idx = 7;
+ break;
+ default:
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "invalid plcp ofdm "
+ "rate (%x).\n", head->plcp[0]);
+ }
+
+ return -EINVAL;
+ }
+ if (status->band == IEEE80211_BAND_2GHZ)
+ status->rate_idx += 4;
+ break;
+
+ case AR9170_RX_STATUS_MODULATION_HT:
+ if (head->plcp[3] & 0x80)
+ status->flag |= RX_FLAG_40MHZ;
+ if (head->plcp[6] & 0x80)
+ status->flag |= RX_FLAG_SHORT_GI;
+
+ status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f);
+ status->flag |= RX_FLAG_HT;
+ break;
+
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ return 0;
+}
+
+static void carl9170_rx_phy_status(struct ar9170 *ar,
+ struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status)
+{
+ int i;
+
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
+
+ for (i = 0; i < 3; i++)
+ if (phy->rssi[i] != 0x80)
+ status->antenna |= BIT(i);
+
+ /* post-process RSSI */
+ for (i = 0; i < 7; i++)
+ if (phy->rssi[i] & 0x80)
+ phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
+
+ /* TODO: we could do something with phy_errors */
+ status->signal = ar->noise[0] + phy->rssi_combined;
+}
+
+static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len)
+{
+ struct sk_buff *skb;
+ int reserved = 0;
+ struct ieee80211_hdr *hdr = (void *) buf;
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ reserved += NET_IP_ALIGN;
+
+ if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+ reserved += NET_IP_ALIGN;
+ }
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ reserved += NET_IP_ALIGN;
+
+ reserved = 32 + (reserved & NET_IP_ALIGN);
+
+ skb = dev_alloc_skb(len + reserved);
+ if (likely(skb)) {
+ skb_reserve(skb, reserved);
+ memcpy(skb_put(skb, len), buf, len);
+ }
+
+ return skb;
+}
+
+static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+ return NULL;
+}
+
+/*
+ * NOTE:
+ *
+ * The firmware is in charge of waking up the device just before
+ * the AP is expected to transmit the next beacon.
+ *
+ * This leaves the driver with the important task of deciding when
+ * to set the PHY back to bed again.
+ */
+static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
+{
+ struct ieee80211_hdr *hdr = (void *) data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool cam;
+
+ if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (compare_ether_addr(hdr->addr3, ar->common.curbssid) ||
+ !ar->common.curaid)
+ return;
+
+ ar->ps.last_beacon = jiffies;
+
+ tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+ if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period))
+ ar->ps.dtim_counter = (tim_ie->dtim_count - 1) %
+ ar->hw->conf.ps_dtim_period;
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ cam = !!(tim_ie->bitmap_ctrl & 0x01);
+
+ if (!cam) {
+ /* back to low-power land. */
+ ar->ps.off_override &= ~PS_OFF_BCN;
+ carl9170_ps_check(ar);
+ } else {
+ /* force CAM */
+ ar->ps.off_override |= PS_OFF_BCN;
+ }
+}
+
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we could
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
+
+static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+ struct ar9170_rx_head *head;
+ struct ar9170_rx_macstatus *mac;
+ struct ar9170_rx_phystatus *phy = NULL;
+ struct ieee80211_rx_status status;
+ struct sk_buff *skb;
+ int mpdu_len;
+
+ if (!IS_STARTED(ar))
+ return;
+
+ if (unlikely(len < sizeof(*mac))) {
+ ar->rx_dropped++;
+ return;
+ }
+
+ mpdu_len = len - sizeof(*mac);
+
+ mac = (void *)(buf + mpdu_len);
+ if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
+ ar->rx_dropped++;
+ return;
+ }
+
+ switch (mac->status & AR9170_RX_STATUS_MPDU) {
+ case AR9170_RX_STATUS_MPDU_FIRST:
+ /* Aggregated MPDUs start with an PLCP header */
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
+ head = (void *) buf;
+
+ /*
+ * The PLCP header needs to be cached for the
+ * following MIDDLE + LAST A-MPDU packets.
+ *
+ * So, if you are wondering why all frames seem
+ * to share a common RX status information,
+ * then you have the answer right here...
+ */
+ memcpy(&ar->rx_plcp, (void *) buf,
+ sizeof(struct ar9170_rx_head));
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ buf += sizeof(struct ar9170_rx_head);
+
+ ar->rx_has_plcp = true;
+ } else {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "plcp info "
+ "is clipped.\n");
+ }
+
+ ar->rx_dropped++;
+ return;
+ }
+ break;
+
+ case AR9170_RX_STATUS_MPDU_LAST:
+ /*
+ * The last frame of an A-MPDU has an extra tail
+ * which does contain the phy status of the whole
+ * aggregate.
+ */
+
+ if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+ phy = (void *)(buf + mpdu_len);
+ } else {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "frame tail "
+ "is clipped.\n");
+ }
+
+ ar->rx_dropped++;
+ return;
+ }
+
+ case AR9170_RX_STATUS_MPDU_MIDDLE:
+ /* These are just data + mac status */
+ if (unlikely(!ar->rx_has_plcp)) {
+ if (!net_ratelimit())
+ return;
+
+ wiphy_err(ar->hw->wiphy, "rx stream does not start "
+ "with a first_mpdu frame tag.\n");
+
+ ar->rx_dropped++;
+ return;
+ }
+
+ head = &ar->rx_plcp;
+ break;
+
+ case AR9170_RX_STATUS_MPDU_SINGLE:
+ /* single mpdu has both: plcp (head) and phy status (tail) */
+ head = (void *) buf;
+
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+
+ buf += sizeof(struct ar9170_rx_head);
+ phy = (void *)(buf + mpdu_len);
+ break;
+
+ default:
+ BUG_ON(1);
+ break;
+ }
+
+ /* FC + DU + RA + FCS */
+ if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) {
+ ar->rx_dropped++;
+ return;
+ }
+
+ memset(&status, 0, sizeof(status));
+ if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) {
+ ar->rx_dropped++;
+ return;
+ }
+
+ if (phy)
+ carl9170_rx_phy_status(ar, phy, &status);
+
+ carl9170_ps_beacon(ar, buf, mpdu_len);
+
+ skb = carl9170_rx_copy_data(buf, mpdu_len);
+ if (likely(skb)) {
+ memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+ ieee80211_rx(ar->hw, skb);
+ } else {
+ ar->rx_dropped++;
+ }
+}
+
+static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
+ const unsigned int resplen)
+{
+ struct carl9170_rsp *cmd;
+ int i = 0;
+
+ while (i < resplen) {
+ cmd = (void *) &respbuf[i];
+
+ i += cmd->hdr.len + 4;
+ if (unlikely(i > resplen))
+ break;
+
+ carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4);
+ }
+
+ if (unlikely(i != resplen)) {
+ if (!net_ratelimit())
+ return;
+
+ wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n");
+ print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET,
+ respbuf, resplen);
+ }
+}
+
+static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
+{
+ unsigned int i = 0;
+
+ /* weird thing, but this is the same in the original driver */
+ while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) {
+ i += 2;
+ len -= 2;
+ buf += 2;
+ }
+
+ if (unlikely(len < 4))
+ return;
+
+ /* found the 6 * 0xffff marker? */
+ if (i == 12)
+ carl9170_rx_untie_cmds(ar, buf, len);
+ else
+ carl9170_handle_mpdu(ar, buf, len);
+}
+
+static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
+{
+ unsigned int tlen, wlen = 0, clen = 0;
+ struct ar9170_stream *rx_stream;
+ u8 *tbuf;
+
+ tbuf = buf;
+ tlen = len;
+
+ while (tlen >= 4) {
+ rx_stream = (void *) tbuf;
+ clen = le16_to_cpu(rx_stream->length);
+ wlen = ALIGN(clen, 4);
+
+ /* check if this is stream has a valid tag.*/
+ if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) {
+ /*
+ * TODO: handle the highly unlikely event that the
+ * corrupted stream has the TAG at the right position.
+ */
+
+ /* check if the frame can be repaired. */
+ if (!ar->rx_failover_missing) {
+
+ /* this is not "short read". */
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy,
+ "missing tag!\n");
+ }
+
+ __carl9170_rx(ar, tbuf, tlen);
+ return;
+ }
+
+ if (ar->rx_failover_missing > tlen) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy,
+ "possible multi "
+ "stream corruption!\n");
+ goto err_telluser;
+ } else {
+ goto err_silent;
+ }
+ }
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing -= tlen;
+
+ if (ar->rx_failover_missing <= 0) {
+ /*
+ * nested carl9170_rx_stream call!
+ *
+ * termination is guranteed, even when the
+ * combined frame also have an element with
+ * a bad tag.
+ */
+
+ ar->rx_failover_missing = 0;
+ carl9170_rx_stream(ar, ar->rx_failover->data,
+ ar->rx_failover->len);
+
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ }
+
+ return;
+ }
+
+ /* check if stream is clipped */
+ if (wlen > tlen - 4) {
+ if (ar->rx_failover_missing) {
+ /* TODO: handle double stream corruption. */
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "double rx "
+ "stream corruption!\n");
+ goto err_telluser;
+ } else {
+ goto err_silent;
+ }
+ }
+
+ /*
+ * save incomplete data set.
+ * the firmware will resend the missing bits when
+ * the rx - descriptor comes round again.
+ */
+
+ memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+ ar->rx_failover_missing = clen - tlen;
+ return;
+ }
+ __carl9170_rx(ar, rx_stream->payload, clen);
+
+ tbuf += wlen + 4;
+ tlen -= wlen + 4;
+ }
+
+ if (tlen) {
+ if (net_ratelimit()) {
+ wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed "
+ "data left in rx stream!\n", tlen);
+ }
+
+ goto err_telluser;
+ }
+
+ return;
+
+err_telluser:
+ wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, "
+ "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen,
+ ar->rx_failover_missing);
+
+ if (ar->rx_failover_missing)
+ print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
+ ar->rx_failover->data,
+ ar->rx_failover->len);
+
+ print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
+ buf, len);
+
+ wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if "
+ "you see this message frequently.\n");
+
+err_silent:
+ if (ar->rx_failover_missing) {
+ skb_reset_tail_pointer(ar->rx_failover);
+ skb_trim(ar->rx_failover, 0);
+ ar->rx_failover_missing = 0;
+ }
+}
+
+void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len)
+{
+ if (ar->fw.rx_stream)
+ carl9170_rx_stream(ar, buf, len);
+ else
+ __carl9170_rx(ar, buf, len);
+}
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
new file mode 100644
index 000000000000..e0d2374e0c77
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -0,0 +1,1373 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * 802.11 xmit & status routines
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "carl9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static inline unsigned int __carl9170_get_queue(struct ar9170 *ar,
+ unsigned int queue)
+{
+ if (unlikely(modparam_noht)) {
+ return queue;
+ } else {
+ /*
+ * This is just another workaround, until
+ * someone figures out how to get QoS and
+ * AMPDU to play nicely together.
+ */
+
+ return 2; /* AC_BE */
+ }
+}
+
+static inline unsigned int carl9170_get_queue(struct ar9170 *ar,
+ struct sk_buff *skb)
+{
+ return __carl9170_get_queue(ar, skb_get_queue_mapping(skb));
+}
+
+static bool is_mem_full(struct ar9170 *ar)
+{
+ return (DIV_ROUND_UP(IEEE80211_MAX_FRAME_LEN, ar->fw.mem_block_size) >
+ atomic_read(&ar->mem_free_blocks));
+}
+
+static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
+{
+ int queue, i;
+ bool mem_full;
+
+ atomic_inc(&ar->tx_total_queued);
+
+ queue = skb_get_queue_mapping(skb);
+ spin_lock_bh(&ar->tx_stats_lock);
+
+ /*
+ * The driver has to accept the frame, regardless if the queue is
+ * full to the brim, or not. We have to do the queuing internally,
+ * since mac80211 assumes that a driver which can operate with
+ * aggregated frames does not reject frames for this reason.
+ */
+ ar->tx_stats[queue].len++;
+ ar->tx_stats[queue].count++;
+
+ mem_full = is_mem_full(ar);
+ for (i = 0; i < ar->hw->queues; i++) {
+ if (mem_full || ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
+ ieee80211_stop_queue(ar->hw, i);
+ ar->queue_stop_timeout[i] = jiffies;
+ }
+ }
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+}
+
+static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *txinfo;
+ int queue;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ queue = skb_get_queue_mapping(skb);
+
+ spin_lock_bh(&ar->tx_stats_lock);
+
+ ar->tx_stats[queue].len--;
+
+ if (!is_mem_full(ar)) {
+ unsigned int i;
+ for (i = 0; i < ar->hw->queues; i++) {
+ if (ar->tx_stats[i].len >= CARL9170_NUM_TX_LIMIT_SOFT)
+ continue;
+
+ if (ieee80211_queue_stopped(ar->hw, i)) {
+ unsigned long tmp;
+
+ tmp = jiffies - ar->queue_stop_timeout[i];
+ if (tmp > ar->max_queue_stop_timeout[i])
+ ar->max_queue_stop_timeout[i] = tmp;
+ }
+
+ ieee80211_wake_queue(ar->hw, i);
+ }
+ }
+
+ spin_unlock_bh(&ar->tx_stats_lock);
+ if (atomic_dec_and_test(&ar->tx_total_queued))
+ complete(&ar->tx_flush);
+}
+
+static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ unsigned int chunks;
+ int cookie = -1;
+
+ atomic_inc(&ar->mem_allocs);
+
+ chunks = DIV_ROUND_UP(skb->len, ar->fw.mem_block_size);
+ if (unlikely(atomic_sub_return(chunks, &ar->mem_free_blocks) < 0)) {
+ atomic_add(chunks, &ar->mem_free_blocks);
+ return -ENOSPC;
+ }
+
+ spin_lock_bh(&ar->mem_lock);
+ cookie = bitmap_find_free_region(ar->mem_bitmap, ar->fw.mem_blocks, 0);
+ spin_unlock_bh(&ar->mem_lock);
+
+ if (unlikely(cookie < 0)) {
+ atomic_add(chunks, &ar->mem_free_blocks);
+ return -ENOSPC;
+ }
+
+ super = (void *) skb->data;
+
+ /*
+ * Cookie #0 serves two special purposes:
+ * 1. The firmware might use it generate BlockACK frames
+ * in responds of an incoming BlockAckReqs.
+ *
+ * 2. Prevent double-free bugs.
+ */
+ super->s.cookie = (u8) cookie + 1;
+ return 0;
+}
+
+static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ int cookie;
+
+ /* make a local copy of the cookie */
+ cookie = super->s.cookie;
+ /* invalidate cookie */
+ super->s.cookie = 0;
+
+ /*
+ * Do a out-of-bounds check on the cookie:
+ *
+ * * cookie "0" is reserved and won't be assigned to any
+ * out-going frame. Internally however, it is used to
+ * mark no longer/un-accounted frames and serves as a
+ * cheap way of preventing frames from being freed
+ * twice by _accident_. NB: There is a tiny race...
+ *
+ * * obviously, cookie number is limited by the amount
+ * of available memory blocks, so the number can
+ * never execeed the mem_blocks count.
+ */
+ if (unlikely(WARN_ON_ONCE(cookie == 0) ||
+ WARN_ON_ONCE(cookie > ar->fw.mem_blocks)))
+ return;
+
+ atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size),
+ &ar->mem_free_blocks);
+
+ spin_lock_bh(&ar->mem_lock);
+ bitmap_release_region(ar->mem_bitmap, cookie - 1, 0);
+ spin_unlock_bh(&ar->mem_lock);
+}
+
+/* Called from any context */
+static void carl9170_tx_release(struct kref *ref)
+{
+ struct ar9170 *ar;
+ struct carl9170_tx_info *arinfo;
+ struct ieee80211_tx_info *txinfo;
+ struct sk_buff *skb;
+
+ arinfo = container_of(ref, struct carl9170_tx_info, ref);
+ txinfo = container_of((void *) arinfo, struct ieee80211_tx_info,
+ rate_driver_data);
+ skb = container_of((void *) txinfo, struct sk_buff, cb);
+
+ ar = arinfo->ar;
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ BUILD_BUG_ON(
+ offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23);
+
+ memset(&txinfo->status.ampdu_ack_len, 0,
+ sizeof(struct ieee80211_tx_info) -
+ offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
+
+ if (atomic_read(&ar->tx_total_queued))
+ ar->tx_schedule = true;
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (!atomic_read(&ar->tx_ampdu_upload))
+ ar->tx_ampdu_schedule = true;
+
+ if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
+ txinfo->status.ampdu_len = txinfo->pad[0];
+ txinfo->status.ampdu_ack_len = txinfo->pad[1];
+ txinfo->pad[0] = txinfo->pad[1] = 0;
+ } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
+ /*
+ * drop redundant tx_status reports:
+ *
+ * 1. ampdu_ack_len of the final tx_status does
+ * include the feedback of this particular frame.
+ *
+ * 2. tx_status_irqsafe only queues up to 128
+ * tx feedback reports and discards the rest.
+ *
+ * 3. minstrel_ht is picky, it only accepts
+ * reports of frames with the TX_STATUS_AMPDU flag.
+ */
+
+ dev_kfree_skb_any(skb);
+ return;
+ } else {
+ /*
+ * Frame has failed, but we want to keep it in
+ * case it was lost due to a power-state
+ * transition.
+ */
+ }
+ }
+
+ skb_pull(skb, sizeof(struct _carl9170_tx_superframe));
+ ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+void carl9170_tx_get_skb(struct sk_buff *skb)
+{
+ struct carl9170_tx_info *arinfo = (void *)
+ (IEEE80211_SKB_CB(skb))->rate_driver_data;
+ kref_get(&arinfo->ref);
+}
+
+int carl9170_tx_put_skb(struct sk_buff *skb)
+{
+ struct carl9170_tx_info *arinfo = (void *)
+ (IEEE80211_SKB_CB(skb))->rate_driver_data;
+
+ return kref_put(&arinfo->ref, carl9170_tx_release);
+}
+
+/* Caller must hold the tid_info->lock & rcu_read_lock */
+static void carl9170_tx_shift_bm(struct ar9170 *ar,
+ struct carl9170_sta_tid *tid_info, u16 seq)
+{
+ u16 off;
+
+ off = SEQ_DIFF(seq, tid_info->bsn);
+
+ if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS))
+ return;
+
+ /*
+ * Sanity check. For each MPDU we set the bit in bitmap and
+ * clear it once we received the tx_status.
+ * But if the bit is already cleared then we've been bitten
+ * by a bug.
+ */
+ WARN_ON_ONCE(!test_and_clear_bit(off, tid_info->bitmap));
+
+ off = SEQ_DIFF(tid_info->snx, tid_info->bsn);
+ if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS))
+ return;
+
+ if (!bitmap_empty(tid_info->bitmap, off))
+ off = find_first_bit(tid_info->bitmap, off);
+
+ tid_info->bsn += off;
+ tid_info->bsn &= 0x0fff;
+
+ bitmap_shift_right(tid_info->bitmap, tid_info->bitmap,
+ off, CARL9170_BAW_BITS);
+}
+
+static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
+ struct sk_buff *skb, struct ieee80211_tx_info *txinfo)
+{
+ struct _carl9170_tx_superframe *super = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *) super->frame_data;
+ struct ieee80211_tx_info *tx_info;
+ struct carl9170_tx_info *ar_info;
+ struct carl9170_sta_info *sta_info;
+ struct ieee80211_sta *sta;
+ struct carl9170_sta_tid *tid_info;
+ struct ieee80211_vif *vif;
+ unsigned int vif_id;
+ u8 tid;
+
+ if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
+ txinfo->flags & IEEE80211_TX_CTL_INJECTED)
+ return;
+
+ tx_info = IEEE80211_SKB_CB(skb);
+ ar_info = (void *) tx_info->rate_driver_data;
+
+ vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+ if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+ return;
+
+ rcu_read_lock();
+ vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+ if (unlikely(!vif))
+ goto out_rcu;
+
+ /*
+ * Normally we should use wrappers like ieee80211_get_DA to get
+ * the correct peer ieee80211_sta.
+ *
+ * But there is a problem with indirect traffic (broadcasts, or
+ * data which is designated for other stations) in station mode.
+ * The frame will be directed to the AP for distribution and not
+ * to the actual destination.
+ */
+ sta = ieee80211_find_sta(vif, hdr->addr1);
+ if (unlikely(!sta))
+ goto out_rcu;
+
+ tid = get_tid_h(hdr);
+
+ sta_info = (void *) sta->drv_priv;
+ tid_info = rcu_dereference(sta_info->agg[tid]);
+ if (!tid_info)
+ goto out_rcu;
+
+ spin_lock_bh(&tid_info->lock);
+ if (likely(tid_info->state >= CARL9170_TID_STATE_IDLE))
+ carl9170_tx_shift_bm(ar, tid_info, get_seq_h(hdr));
+
+ if (sta_info->stats[tid].clear) {
+ sta_info->stats[tid].clear = false;
+ sta_info->stats[tid].ampdu_len = 0;
+ sta_info->stats[tid].ampdu_ack_len = 0;
+ }
+
+ sta_info->stats[tid].ampdu_len++;
+ if (txinfo->status.rates[0].count == 1)
+ sta_info->stats[tid].ampdu_ack_len++;
+
+ if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
+ txinfo->pad[0] = sta_info->stats[tid].ampdu_len;
+ txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len;
+ txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
+ sta_info->stats[tid].clear = true;
+ }
+ spin_unlock_bh(&tid_info->lock);
+
+out_rcu:
+ rcu_read_unlock();
+}
+
+void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ const bool success)
+{
+ struct ieee80211_tx_info *txinfo;
+
+ carl9170_tx_accounting_free(ar, skb);
+
+ txinfo = IEEE80211_SKB_CB(skb);
+
+ if (success)
+ txinfo->flags |= IEEE80211_TX_STAT_ACK;
+ else
+ ar->tx_ack_failures++;
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
+ carl9170_tx_status_process_ampdu(ar, skb, txinfo);
+
+ carl9170_tx_put_skb(skb);
+}
+
+/* This function may be called form any context */
+void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+
+ atomic_dec(&ar->tx_total_pending);
+
+ if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
+ atomic_dec(&ar->tx_ampdu_upload);
+
+ if (carl9170_tx_put_skb(skb))
+ tasklet_hi_schedule(&ar->usb_tasklet);
+}
+
+static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie,
+ struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+
+ spin_lock_bh(&queue->lock);
+ skb_queue_walk(queue, skb) {
+ struct _carl9170_tx_superframe *txc = (void *) skb->data;
+
+ if (txc->s.cookie != cookie)
+ continue;
+
+ __skb_unlink(skb, queue);
+ spin_unlock_bh(&queue->lock);
+
+ carl9170_release_dev_space(ar, skb);
+ return skb;
+ }
+ spin_unlock_bh(&queue->lock);
+
+ return NULL;
+}
+
+static void carl9170_tx_fill_rateinfo(struct ar9170 *ar, unsigned int rix,
+ unsigned int tries, struct ieee80211_tx_info *txinfo)
+{
+ unsigned int i;
+
+ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+ if (txinfo->status.rates[i].idx < 0)
+ break;
+
+ if (i == rix) {
+ txinfo->status.rates[i].count = tries;
+ i++;
+ break;
+ }
+ }
+
+ for (; i < IEEE80211_TX_MAX_RATES; i++) {
+ txinfo->status.rates[i].idx = -1;
+ txinfo->status.rates[i].count = 0;
+ }
+}
+
+static void carl9170_check_queue_stop_timeout(struct ar9170 *ar)
+{
+ int i;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ bool restart = false;
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ spin_lock_bh(&ar->tx_status[i].lock);
+
+ skb = skb_peek(&ar->tx_status[i]);
+
+ if (!skb)
+ goto next;
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (time_is_before_jiffies(arinfo->timeout +
+ msecs_to_jiffies(CARL9170_QUEUE_STUCK_TIMEOUT)) == true)
+ restart = true;
+
+next:
+ spin_unlock_bh(&ar->tx_status[i].lock);
+ }
+
+ if (restart) {
+ /*
+ * At least one queue has been stuck for long enough.
+ * Give the device a kick and hope it gets back to
+ * work.
+ *
+ * possible reasons may include:
+ * - frames got lost/corrupted (bad connection to the device)
+ * - stalled rx processing/usb controller hiccups
+ * - firmware errors/bugs
+ * - every bug you can think of.
+ * - all bugs you can't...
+ * - ...
+ */
+ carl9170_restart(ar, CARL9170_RR_STUCK_TX);
+ }
+}
+
+void carl9170_tx_janitor(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ tx_janitor.work);
+ if (!IS_STARTED(ar))
+ return;
+
+ ar->tx_janitor_last_run = jiffies;
+
+ carl9170_check_queue_stop_timeout(ar);
+
+ if (!atomic_read(&ar->tx_total_queued))
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor,
+ msecs_to_jiffies(CARL9170_TX_TIMEOUT));
+}
+
+static void __carl9170_tx_process_status(struct ar9170 *ar,
+ const uint8_t cookie, const uint8_t info)
+{
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+ unsigned int r, t, q;
+ bool success = true;
+
+ q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE];
+
+ skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]);
+ if (!skb) {
+ /*
+ * We have lost the race to another thread.
+ */
+
+ return ;
+ }
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (!(info & CARL9170_TX_STATUS_SUCCESS))
+ success = false;
+
+ r = (info & CARL9170_TX_STATUS_RIX) >> CARL9170_TX_STATUS_RIX_S;
+ t = (info & CARL9170_TX_STATUS_TRIES) >> CARL9170_TX_STATUS_TRIES_S;
+
+ carl9170_tx_fill_rateinfo(ar, r, t, txinfo);
+ carl9170_tx_status(ar, skb, success);
+}
+
+void carl9170_tx_process_status(struct ar9170 *ar,
+ const struct carl9170_rsp *cmd)
+{
+ unsigned int i;
+
+ for (i = 0; i < cmd->hdr.ext; i++) {
+ if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) {
+ print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE,
+ (void *) cmd, cmd->hdr.len + 4);
+ break;
+ }
+
+ __carl9170_tx_process_status(ar, cmd->_tx_status[i].cookie,
+ cmd->_tx_status[i].info);
+ }
+}
+
+static __le32 carl9170_tx_physet(struct ar9170 *ar,
+ struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate)
+{
+ struct ieee80211_rate *rate = NULL;
+ u32 power, chains;
+ __le32 tmp;
+
+ tmp = cpu_to_le32(0);
+
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ <<
+ AR9170_TX_PHY_BW_S);
+ /* this works because 40 MHz is 2 and dup is 3 */
+ if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP <<
+ AR9170_TX_PHY_BW_S);
+
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+ if (txrate->flags & IEEE80211_TX_RC_MCS) {
+ u32 r = txrate->idx;
+ u8 *txpower;
+
+ /* heavy clip control */
+ tmp |= cpu_to_le32((r & 0x7) <<
+ AR9170_TX_PHY_TX_HEAVY_CLIP_S);
+
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+ if (info->band == IEEE80211_BAND_5GHZ)
+ txpower = ar->power_5G_ht40;
+ else
+ txpower = ar->power_2G_ht40;
+ } else {
+ if (info->band == IEEE80211_BAND_5GHZ)
+ txpower = ar->power_5G_ht20;
+ else
+ txpower = ar->power_2G_ht20;
+ }
+
+ power = txpower[r & 7];
+
+ /* +1 dBm for HT40 */
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ power += 2;
+
+ r <<= AR9170_TX_PHY_MCS_S;
+ BUG_ON(r & ~AR9170_TX_PHY_MCS);
+
+ tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS);
+ tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+ /*
+ * green field preamble does not work.
+ *
+ * if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+ */
+ } else {
+ u8 *txpower;
+ u32 mod;
+ u32 phyrate;
+ u8 idx = txrate->idx;
+
+ if (info->band != IEEE80211_BAND_2GHZ) {
+ idx += 4;
+ txpower = ar->power_5G_leg;
+ mod = AR9170_TX_PHY_MOD_OFDM;
+ } else {
+ if (idx < 4) {
+ txpower = ar->power_2G_cck;
+ mod = AR9170_TX_PHY_MOD_CCK;
+ } else {
+ mod = AR9170_TX_PHY_MOD_OFDM;
+ txpower = ar->power_2G_ofdm;
+ }
+ }
+
+ rate = &__carl9170_ratetable[idx];
+
+ phyrate = rate->hw_value & 0xF;
+ power = txpower[(rate->hw_value & 0x30) >> 4];
+ phyrate <<= AR9170_TX_PHY_MCS_S;
+
+ tmp |= cpu_to_le32(mod);
+ tmp |= cpu_to_le32(phyrate);
+
+ /*
+ * short preamble seems to be broken too.
+ *
+ * if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+ */
+ }
+ power <<= AR9170_TX_PHY_TX_PWR_S;
+ power &= AR9170_TX_PHY_TX_PWR;
+ tmp |= cpu_to_le32(power);
+
+ /* set TX chains */
+ if (ar->eeprom.tx_mask == 1) {
+ chains = AR9170_TX_PHY_TXCHAIN_1;
+ } else {
+ chains = AR9170_TX_PHY_TXCHAIN_2;
+
+ /* >= 36M legacy OFDM - use only one chain */
+ if (rate && rate->bitrate >= 360 &&
+ !(txrate->flags & IEEE80211_TX_RC_MCS))
+ chains = AR9170_TX_PHY_TXCHAIN_1;
+ }
+ tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S);
+
+ return tmp;
+}
+
+static bool carl9170_tx_rts_check(struct ar9170 *ar,
+ struct ieee80211_tx_rate *rate,
+ bool ampdu, bool multi)
+{
+ switch (ar->erp_mode) {
+ case CARL9170_ERP_AUTO:
+ if (ampdu)
+ break;
+
+ case CARL9170_ERP_MAC80211:
+ if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS))
+ break;
+
+ case CARL9170_ERP_RTS:
+ if (likely(!multi))
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static bool carl9170_tx_cts_check(struct ar9170 *ar,
+ struct ieee80211_tx_rate *rate)
+{
+ switch (ar->erp_mode) {
+ case CARL9170_ERP_AUTO:
+ case CARL9170_ERP_MAC80211:
+ if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
+ break;
+
+ case CARL9170_ERP_CTS:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ struct _carl9170_tx_superframe *txc;
+ struct carl9170_vif_info *cvif;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_tx_rate *txrate;
+ struct ieee80211_sta *sta;
+ struct carl9170_tx_info *arinfo;
+ unsigned int hw_queue;
+ int i;
+ u16 keytype = 0;
+ u16 len, icv = 0;
+ bool ampdu, no_ack;
+
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+ BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) !=
+ CARL9170_TX_SUPERDESC_LEN);
+
+ BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) !=
+ AR9170_TX_HWDESC_LEN);
+
+ BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES);
+
+ hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)];
+
+ hdr = (void *)skb->data;
+ info = IEEE80211_SKB_CB(skb);
+ len = skb->len;
+
+ /*
+ * Note: If the frame was sent through a monitor interface,
+ * the ieee80211_vif pointer can be NULL.
+ */
+ if (likely(info->control.vif))
+ cvif = (void *) info->control.vif->drv_priv;
+ else
+ cvif = NULL;
+
+ sta = info->control.sta;
+
+ txc = (void *)skb_push(skb, sizeof(*txc));
+ memset(txc, 0, sizeof(*txc));
+
+ ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU);
+ no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
+
+ if (info->control.hw_key) {
+ icv = info->control.hw_key->icv_len;
+
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ keytype = AR9170_TX_MAC_ENCR_RC4;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ keytype = AR9170_TX_MAC_ENCR_AES;
+ break;
+ default:
+ WARN_ON(1);
+ goto err_out;
+ }
+ }
+
+ BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC >
+ ((CARL9170_TX_SUPER_MISC_VIF_ID >>
+ CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1));
+
+ txc->s.len = cpu_to_le16(len + sizeof(*txc));
+ txc->f.length = cpu_to_le16(len + icv + 4);
+ SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc,
+ cvif ? cvif->id : 0);
+
+ txc->f.mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+ AR9170_TX_MAC_BACKOFF);
+
+ SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue);
+
+ txc->f.mac_control |= cpu_to_le16(hw_queue << AR9170_TX_MAC_QOS_S);
+ txc->f.mac_control |= cpu_to_le16(keytype);
+ txc->f.phy_control = cpu_to_le32(0);
+
+ if (no_ack)
+ txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+ txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB;
+
+ txrate = &info->control.rates[0];
+ if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+ txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+ else if (carl9170_tx_cts_check(ar, txrate))
+ txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+
+ SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count);
+ txc->f.phy_control |= carl9170_tx_physet(ar, info, txrate);
+
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ for (i = 1; i < CARL9170_TX_MAX_RATES; i++) {
+ txrate = &info->control.rates[i];
+ if (txrate->idx >= 0)
+ continue;
+
+ txrate->idx = 0;
+ txrate->count = ar->hw->max_rate_tries;
+ }
+ }
+
+ /*
+ * NOTE: For the first rate, the ERP & AMPDU flags are directly
+ * taken from mac_control. For all fallback rate, the firmware
+ * updates the mac_control flags from the rate info field.
+ */
+ for (i = 1; i < CARL9170_TX_MAX_RATES; i++) {
+ txrate = &info->control.rates[i];
+ if (txrate->idx < 0)
+ break;
+
+ SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
+ txrate->count);
+
+ if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+ txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS <<
+ CARL9170_TX_SUPER_RI_ERP_PROT_S);
+ else if (carl9170_tx_cts_check(ar, txrate))
+ txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
+ CARL9170_TX_SUPER_RI_ERP_PROT_S);
+
+ /*
+ * unaggregated fallback, in case aggregation
+ * proves to be unsuccessful and unreliable.
+ */
+ if (ampdu && i < 3)
+ txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
+
+ txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate);
+ }
+
+ if (ieee80211_is_probe_resp(hdr->frame_control))
+ txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF;
+
+ if (ampdu) {
+ unsigned int density, factor;
+
+ if (unlikely(!sta || !cvif))
+ goto err_out;
+
+ density = info->control.sta->ht_cap.ampdu_density;
+ factor = info->control.sta->ht_cap.ampdu_factor;
+
+ if (density) {
+ /*
+ * Watch out!
+ *
+ * Otus uses slightly different density values than
+ * those from the 802.11n spec.
+ */
+
+ density = max_t(unsigned int, density + 1, 7u);
+ }
+
+ factor = min_t(unsigned int, 1u, factor);
+
+ SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY,
+ txc->s.ampdu_settings, density);
+
+ SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR,
+ txc->s.ampdu_settings, factor);
+
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
+ txc->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+ } else {
+ /*
+ * Not sure if it's even possible to aggregate
+ * non-ht rates with this HW.
+ */
+ WARN_ON_ONCE(1);
+ }
+ }
+
+ arinfo = (void *)info->rate_driver_data;
+ arinfo->timeout = jiffies;
+ arinfo->ar = ar;
+ kref_init(&arinfo->ref);
+ return 0;
+
+err_out:
+ skb_pull(skb, sizeof(*txc));
+ return -EINVAL;
+}
+
+static void carl9170_set_immba(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+
+ super = (void *) skb->data;
+ super->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_BA);
+}
+
+static void carl9170_set_ampdu_params(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+ int tmp;
+
+ super = (void *) skb->data;
+
+ tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_DENSITY) <<
+ CARL9170_TX_SUPER_AMPDU_DENSITY_S;
+
+ /*
+ * If you haven't noticed carl9170_tx_prepare has already filled
+ * in all ampdu spacing & factor parameters.
+ * Now it's the time to check whenever the settings have to be
+ * updated by the firmware, or if everything is still the same.
+ *
+ * There's no sane way to handle different density values with
+ * this hardware, so we may as well just do the compare in the
+ * driver.
+ */
+
+ if (tmp != ar->current_density) {
+ ar->current_density = tmp;
+ super->s.ampdu_settings |=
+ CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY;
+ }
+
+ tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_FACTOR) <<
+ CARL9170_TX_SUPER_AMPDU_FACTOR_S;
+
+ if (tmp != ar->current_factor) {
+ ar->current_factor = tmp;
+ super->s.ampdu_settings |=
+ CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR;
+ }
+}
+
+static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest,
+ struct sk_buff *_src)
+{
+ struct _carl9170_tx_superframe *dest, *src;
+
+ dest = (void *) _dest->data;
+ src = (void *) _src->data;
+
+ /*
+ * The mac80211 rate control algorithm expects that all MPDUs in
+ * an AMPDU share the same tx vectors.
+ * This is not really obvious right now, because the hardware
+ * does the AMPDU setup according to its own rulebook.
+ * Our nicely assembled, strictly monotonic increasing mpdu
+ * chains will be broken up, mashed back together...
+ */
+
+ return (dest->f.phy_control == src->f.phy_control);
+}
+
+static void carl9170_tx_ampdu(struct ar9170 *ar)
+{
+ struct sk_buff_head agg;
+ struct carl9170_sta_tid *tid_info;
+ struct sk_buff *skb, *first;
+ unsigned int i = 0, done_ampdus = 0;
+ u16 seq, queue, tmpssn;
+
+ atomic_inc(&ar->tx_ampdu_scheduler);
+ ar->tx_ampdu_schedule = false;
+
+ if (atomic_read(&ar->tx_ampdu_upload))
+ return;
+
+ if (!ar->tx_ampdu_list_len)
+ return;
+
+ __skb_queue_head_init(&agg);
+
+ rcu_read_lock();
+ tid_info = rcu_dereference(ar->tx_ampdu_iter);
+ if (WARN_ON_ONCE(!tid_info)) {
+ rcu_read_unlock();
+ return;
+ }
+
+retry:
+ list_for_each_entry_continue_rcu(tid_info, &ar->tx_ampdu_list, list) {
+ i++;
+
+ if (tid_info->state < CARL9170_TID_STATE_PROGRESS)
+ continue;
+
+ queue = TID_TO_WME_AC(tid_info->tid);
+
+ spin_lock_bh(&tid_info->lock);
+ if (tid_info->state != CARL9170_TID_STATE_XMIT) {
+ first = skb_peek(&tid_info->queue);
+ if (first) {
+ struct ieee80211_tx_info *txinfo;
+ struct carl9170_tx_info *arinfo;
+
+ txinfo = IEEE80211_SKB_CB(first);
+ arinfo = (void *) txinfo->rate_driver_data;
+
+ if (time_is_after_jiffies(arinfo->timeout +
+ msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))
+ == true)
+ goto processed;
+
+ /*
+ * We've been waiting for the frame which
+ * matches "snx" (start sequence of the
+ * next aggregate) for some time now.
+ *
+ * But it never arrived. Therefore
+ * jump to the next available frame
+ * and kick-start the transmission.
+ *
+ * Note: This might induce odd latency
+ * spikes because the receiver will be
+ * waiting for the lost frame too.
+ */
+ ar->tx_ampdu_timeout++;
+
+ tid_info->snx = carl9170_get_seq(first);
+ tid_info->state = CARL9170_TID_STATE_XMIT;
+ } else {
+ goto processed;
+ }
+ }
+
+ tid_info->counter++;
+ first = skb_peek(&tid_info->queue);
+ tmpssn = carl9170_get_seq(first);
+ seq = tid_info->snx;
+
+ if (unlikely(tmpssn != seq)) {
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+
+ goto processed;
+ }
+
+ while ((skb = skb_peek(&tid_info->queue))) {
+ /* strict 0, 1, ..., n - 1, n frame sequence order */
+ if (unlikely(carl9170_get_seq(skb) != seq))
+ break;
+
+ /* don't upload more than AMPDU FACTOR allows. */
+ if (unlikely(SEQ_DIFF(tid_info->snx, tid_info->bsn) >=
+ (tid_info->max - 1)))
+ break;
+
+ if (!carl9170_tx_rate_check(ar, skb, first))
+ break;
+
+ atomic_inc(&ar->tx_ampdu_upload);
+ tid_info->snx = seq = SEQ_NEXT(seq);
+ __skb_unlink(skb, &tid_info->queue);
+
+ __skb_queue_tail(&agg, skb);
+
+ if (skb_queue_len(&agg) >= CARL9170_NUM_TX_AGG_MAX)
+ break;
+ }
+
+ if (skb_queue_empty(&tid_info->queue) ||
+ carl9170_get_seq(skb_peek(&tid_info->queue)) !=
+ tid_info->snx) {
+ /*
+ * stop TID, if A-MPDU frames are still missing,
+ * or whenever the queue is empty.
+ */
+
+ tid_info->state = CARL9170_TID_STATE_IDLE;
+ }
+ done_ampdus++;
+
+processed:
+ spin_unlock_bh(&tid_info->lock);
+
+ if (skb_queue_empty(&agg))
+ continue;
+
+ /* apply ampdu spacing & factor settings */
+ carl9170_set_ampdu_params(ar, skb_peek(&agg));
+
+ /* set aggregation push bit */
+ carl9170_set_immba(ar, skb_peek_tail(&agg));
+
+ spin_lock_bh(&ar->tx_pending[queue].lock);
+ skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
+ spin_unlock_bh(&ar->tx_pending[queue].lock);
+ ar->tx_schedule = true;
+ }
+ if ((done_ampdus++ == 0) && (i++ == 0))
+ goto retry;
+
+ rcu_assign_pointer(ar->tx_ampdu_iter, tid_info);
+ rcu_read_unlock();
+}
+
+static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
+ struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ struct carl9170_tx_info *arinfo;
+
+ BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+
+ spin_lock_bh(&queue->lock);
+ skb = skb_peek(queue);
+ if (unlikely(!skb))
+ goto err_unlock;
+
+ if (carl9170_alloc_dev_space(ar, skb))
+ goto err_unlock;
+
+ __skb_unlink(skb, queue);
+ spin_unlock_bh(&queue->lock);
+
+ info = IEEE80211_SKB_CB(skb);
+ arinfo = (void *) info->rate_driver_data;
+
+ arinfo->timeout = jiffies;
+
+ /*
+ * increase ref count to "2".
+ * Ref counting is the easiest way to solve the race between
+ * the the urb's completion routine: carl9170_tx_callback and
+ * wlan tx status functions: carl9170_tx_status/janitor.
+ */
+ carl9170_tx_get_skb(skb);
+
+ return skb;
+
+err_unlock:
+ spin_unlock_bh(&queue->lock);
+ return NULL;
+}
+
+void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct _carl9170_tx_superframe *super;
+ uint8_t q = 0;
+
+ ar->tx_dropped++;
+
+ super = (void *)skb->data;
+ SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q,
+ ar9170_qmap[carl9170_get_queue(ar, skb)]);
+ __carl9170_tx_process_status(ar, super->s.cookie, q);
+}
+
+static void carl9170_tx(struct ar9170 *ar)
+{
+ struct sk_buff *skb;
+ unsigned int i, q;
+ bool schedule_garbagecollector = false;
+
+ ar->tx_schedule = false;
+
+ if (unlikely(!IS_STARTED(ar)))
+ return;
+
+ carl9170_usb_handle_tx_err(ar);
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ while (!skb_queue_empty(&ar->tx_pending[i])) {
+ skb = carl9170_tx_pick_skb(ar, &ar->tx_pending[i]);
+ if (unlikely(!skb))
+ break;
+
+ atomic_inc(&ar->tx_total_pending);
+
+ q = __carl9170_get_queue(ar, i);
+ /*
+ * NB: tx_status[i] vs. tx_status[q],
+ * TODO: Move into pick_skb or alloc_dev_space.
+ */
+ skb_queue_tail(&ar->tx_status[q], skb);
+
+ carl9170_usb_tx(ar, skb);
+ schedule_garbagecollector = true;
+ }
+ }
+
+ if (!schedule_garbagecollector)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor,
+ msecs_to_jiffies(CARL9170_TX_TIMEOUT));
+}
+
+static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
+ struct ieee80211_sta *sta, struct sk_buff *skb)
+{
+ struct carl9170_sta_info *sta_info;
+ struct carl9170_sta_tid *agg;
+ struct sk_buff *iter;
+ unsigned int max;
+ u16 tid, seq, qseq, off;
+ bool run = false;
+
+ tid = carl9170_get_tid(skb);
+ seq = carl9170_get_seq(skb);
+ sta_info = (void *) sta->drv_priv;
+
+ rcu_read_lock();
+ agg = rcu_dereference(sta_info->agg[tid]);
+ max = sta_info->ampdu_max_len;
+
+ if (!agg)
+ goto err_unlock_rcu;
+
+ spin_lock_bh(&agg->lock);
+ if (unlikely(agg->state < CARL9170_TID_STATE_IDLE))
+ goto err_unlock;
+
+ /* check if sequence is within the BA window */
+ if (unlikely(!BAW_WITHIN(agg->bsn, CARL9170_BAW_BITS, seq)))
+ goto err_unlock;
+
+ if (WARN_ON_ONCE(!BAW_WITHIN(agg->snx, CARL9170_BAW_BITS, seq)))
+ goto err_unlock;
+
+ off = SEQ_DIFF(seq, agg->bsn);
+ if (WARN_ON_ONCE(test_and_set_bit(off, agg->bitmap)))
+ goto err_unlock;
+
+ if (likely(BAW_WITHIN(agg->hsn, CARL9170_BAW_BITS, seq))) {
+ __skb_queue_tail(&agg->queue, skb);
+ agg->hsn = seq;
+ goto queued;
+ }
+
+ skb_queue_reverse_walk(&agg->queue, iter) {
+ qseq = carl9170_get_seq(iter);
+
+ if (BAW_WITHIN(qseq, CARL9170_BAW_BITS, seq)) {
+ __skb_queue_after(&agg->queue, iter, skb);
+ goto queued;
+ }
+ }
+
+ __skb_queue_head(&agg->queue, skb);
+queued:
+
+ if (unlikely(agg->state != CARL9170_TID_STATE_XMIT)) {
+ if (agg->snx == carl9170_get_seq(skb_peek(&agg->queue))) {
+ agg->state = CARL9170_TID_STATE_XMIT;
+ run = true;
+ }
+ }
+
+ spin_unlock_bh(&agg->lock);
+ rcu_read_unlock();
+
+ return run;
+
+err_unlock:
+ spin_unlock_bh(&agg->lock);
+
+err_unlock_rcu:
+ rcu_read_unlock();
+ carl9170_tx_status(ar, skb, false);
+ ar->tx_dropped++;
+ return false;
+}
+
+int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_sta *sta;
+ bool run;
+
+ if (unlikely(!IS_STARTED(ar)))
+ goto err_free;
+
+ info = IEEE80211_SKB_CB(skb);
+ sta = info->control.sta;
+
+ if (unlikely(carl9170_tx_prepare(ar, skb)))
+ goto err_free;
+
+ carl9170_tx_accounting(ar, skb);
+ /*
+ * from now on, one has to use carl9170_tx_status to free
+ * all ressouces which are associated with the frame.
+ */
+
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (WARN_ON_ONCE(!sta))
+ goto err_free;
+
+ run = carl9170_tx_ampdu_queue(ar, sta, skb);
+ if (run)
+ carl9170_tx_ampdu(ar);
+
+ } else {
+ unsigned int queue = skb_get_queue_mapping(skb);
+
+ skb_queue_tail(&ar->tx_pending[queue], skb);
+ }
+
+ carl9170_tx(ar);
+ return NETDEV_TX_OK;
+
+err_free:
+ ar->tx_dropped++;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+void carl9170_tx_scheduler(struct ar9170 *ar)
+{
+
+ if (ar->tx_ampdu_schedule)
+ carl9170_tx_ampdu(ar);
+
+ if (ar->tx_schedule)
+ carl9170_tx(ar);
+}
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
new file mode 100644
index 000000000000..fde918d0120b
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -0,0 +1,1137 @@
+/*
+ * Atheros CARL9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include "carl9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "fwcmd.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@googlemail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE(CARL9170FW_NAME);
+MODULE_ALIAS("ar9170usb");
+MODULE_ALIAS("arusb_lnx");
+
+/*
+ * Note:
+ *
+ * Always update our wiki's device list (located at:
+ * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ),
+ * whenever you add a new device.
+ */
+static struct usb_device_id carl9170_usb_ids[] = {
+ /* Atheros 9170 */
+ { USB_DEVICE(0x0cf3, 0x9170) },
+ /* Atheros TG121N */
+ { USB_DEVICE(0x0cf3, 0x1001) },
+ /* TP-Link TL-WN821N v2 */
+ { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON |
+ CARL9170_ONE_LED },
+ /* 3Com Dual Band 802.11n USB Adapter */
+ { USB_DEVICE(0x0cf3, 0x1010) },
+ /* H3C Dual Band 802.11n USB Adapter */
+ { USB_DEVICE(0x0cf3, 0x1011) },
+ /* Cace Airpcap NX */
+ { USB_DEVICE(0xcace, 0x0300) },
+ /* D-Link DWA 160 A1 */
+ { USB_DEVICE(0x07d1, 0x3c10) },
+ /* D-Link DWA 160 A2 */
+ { USB_DEVICE(0x07d1, 0x3a09) },
+ /* Netgear WNA1000 */
+ { USB_DEVICE(0x0846, 0x9040) },
+ /* Netgear WNDA3100 */
+ { USB_DEVICE(0x0846, 0x9010) },
+ /* Netgear WN111 v2 */
+ { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED },
+ /* Zydas ZD1221 */
+ { USB_DEVICE(0x0ace, 0x1221) },
+ /* Proxim ORiNOCO 802.11n USB */
+ { USB_DEVICE(0x1435, 0x0804) },
+ /* WNC Generic 11n USB Dongle */
+ { USB_DEVICE(0x1435, 0x0326) },
+ /* ZyXEL NWD271N */
+ { USB_DEVICE(0x0586, 0x3417) },
+ /* Z-Com UB81 BG */
+ { USB_DEVICE(0x0cde, 0x0023) },
+ /* Z-Com UB82 ABG */
+ { USB_DEVICE(0x0cde, 0x0026) },
+ /* Sphairon Homelink 1202 */
+ { USB_DEVICE(0x0cde, 0x0027) },
+ /* Arcadyan WN7512 */
+ { USB_DEVICE(0x083a, 0xf522) },
+ /* Planex GWUS300 */
+ { USB_DEVICE(0x2019, 0x5304) },
+ /* IO-Data WNGDNUS2 */
+ { USB_DEVICE(0x04bb, 0x093f) },
+ /* NEC WL300NU-G */
+ { USB_DEVICE(0x0409, 0x0249) },
+ /* AVM FRITZ!WLAN USB Stick N */
+ { USB_DEVICE(0x057c, 0x8401) },
+ /* AVM FRITZ!WLAN USB Stick N 2.4 */
+ { USB_DEVICE(0x057c, 0x8402) },
+ /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
+ { USB_DEVICE(0x1668, 0x1200) },
+
+ /* terminate */
+ {}
+};
+MODULE_DEVICE_TABLE(usb, carl9170_usb_ids);
+
+static void carl9170_usb_submit_data_urb(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int err;
+
+ if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS)
+ goto err_acc;
+
+ urb = usb_get_from_anchor(&ar->tx_wait);
+ if (!urb)
+ goto err_acc;
+
+ usb_anchor_urb(urb, &ar->tx_anch);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ if (net_ratelimit()) {
+ dev_err(&ar->udev->dev, "tx submit failed (%d)\n",
+ urb->status);
+ }
+
+ usb_unanchor_urb(urb);
+ usb_anchor_urb(urb, &ar->tx_err);
+ }
+
+ usb_free_urb(urb);
+
+ if (likely(err == 0))
+ return;
+
+err_acc:
+ atomic_dec(&ar->tx_anch_urbs);
+}
+
+static void carl9170_usb_tx_data_complete(struct urb *urb)
+{
+ struct ar9170 *ar = (struct ar9170 *)
+ usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+ if (WARN_ON_ONCE(!ar)) {
+ dev_kfree_skb_irq(urb->context);
+ return;
+ }
+
+ atomic_dec(&ar->tx_anch_urbs);
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ carl9170_tx_callback(ar, (void *)urb->context);
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ /*
+ * Defer the frame clean-up to the tasklet worker.
+ * This is necessary, because carl9170_tx_drop
+ * does not work in an irqsave context.
+ */
+ usb_anchor_urb(urb, &ar->tx_err);
+ return;
+
+ /* a random transmission error has occurred? */
+ default:
+ if (net_ratelimit()) {
+ dev_err(&ar->udev->dev, "tx failed (%d)\n",
+ urb->status);
+ }
+
+ usb_anchor_urb(urb, &ar->tx_err);
+ break;
+ }
+
+ if (likely(IS_STARTED(ar)))
+ carl9170_usb_submit_data_urb(ar);
+}
+
+static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int err;
+
+ if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) {
+ atomic_dec(&ar->tx_cmd_urbs);
+ return 0;
+ }
+
+ urb = usb_get_from_anchor(&ar->tx_cmd);
+ if (!urb) {
+ atomic_dec(&ar->tx_cmd_urbs);
+ return 0;
+ }
+
+ usb_anchor_urb(urb, &ar->tx_anch);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ usb_unanchor_urb(urb);
+ atomic_dec(&ar->tx_cmd_urbs);
+ }
+ usb_free_urb(urb);
+
+ return err;
+}
+
+static void carl9170_usb_cmd_complete(struct urb *urb)
+{
+ struct ar9170 *ar = urb->context;
+ int err = 0;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ atomic_dec(&ar->tx_cmd_urbs);
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ err = urb->status;
+ break;
+ }
+
+ if (!IS_INITIALIZED(ar))
+ return;
+
+ if (err)
+ dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err);
+
+ err = carl9170_usb_submit_cmd_urb(ar);
+ if (err)
+ dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err);
+}
+
+static void carl9170_usb_rx_irq_complete(struct urb *urb)
+{
+ struct ar9170 *ar = urb->context;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ goto resubmit;
+ }
+
+ carl9170_handle_command_response(ar, urb->transfer_buffer,
+ urb->actual_length);
+
+resubmit:
+ usb_anchor_urb(urb, &ar->rx_anch);
+ if (unlikely(usb_submit_urb(urb, GFP_ATOMIC)))
+ usb_unanchor_urb(urb);
+}
+
+static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp)
+{
+ struct urb *urb;
+ int err = 0, runs = 0;
+
+ while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) &&
+ (runs++ < AR9170_NUM_RX_URBS)) {
+ err = -ENOSPC;
+ urb = usb_get_from_anchor(&ar->rx_pool);
+ if (urb) {
+ usb_anchor_urb(urb, &ar->rx_anch);
+ err = usb_submit_urb(urb, gfp);
+ if (unlikely(err)) {
+ usb_unanchor_urb(urb);
+ usb_anchor_urb(urb, &ar->rx_pool);
+ } else {
+ atomic_dec(&ar->rx_pool_urbs);
+ atomic_inc(&ar->rx_anch_urbs);
+ }
+ usb_free_urb(urb);
+ }
+ }
+
+ return err;
+}
+
+static void carl9170_usb_rx_work(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int i;
+
+ for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) {
+ urb = usb_get_from_anchor(&ar->rx_work);
+ if (!urb)
+ break;
+
+ atomic_dec(&ar->rx_work_urbs);
+ if (IS_INITIALIZED(ar)) {
+ carl9170_rx(ar, urb->transfer_buffer,
+ urb->actual_length);
+ }
+
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+
+ usb_free_urb(urb);
+
+ carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC);
+ }
+}
+
+void carl9170_usb_handle_tx_err(struct ar9170 *ar)
+{
+ struct urb *urb;
+
+ while ((urb = usb_get_from_anchor(&ar->tx_err))) {
+ struct sk_buff *skb = (void *)urb->context;
+
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+ usb_free_urb(urb);
+ }
+}
+
+static void carl9170_usb_tasklet(unsigned long data)
+{
+ struct ar9170 *ar = (struct ar9170 *) data;
+
+ carl9170_usb_rx_work(ar);
+
+ /*
+ * Strictly speaking: The tx scheduler is not part of the USB system.
+ * But the rx worker returns frames back to the mac80211-stack and
+ * this is the _perfect_ place to generate the next transmissions.
+ */
+ if (IS_STARTED(ar))
+ carl9170_tx_scheduler(ar);
+}
+
+static void carl9170_usb_rx_complete(struct urb *urb)
+{
+ struct ar9170 *ar = (struct ar9170 *)urb->context;
+ int err;
+
+ if (WARN_ON_ONCE(!ar))
+ return;
+
+ atomic_dec(&ar->rx_anch_urbs);
+
+ switch (urb->status) {
+ case 0:
+ /* rx path */
+ usb_anchor_urb(urb, &ar->rx_work);
+ atomic_inc(&ar->rx_work_urbs);
+ break;
+
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ /* handle disconnect events*/
+ return;
+
+ default:
+ /* handle all other errors */
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+ break;
+ }
+
+ err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC);
+ if (unlikely(err)) {
+ /*
+ * usb_submit_rx_urb reported a problem.
+ * In case this is due to a rx buffer shortage,
+ * elevate the tasklet worker priority to
+ * the highest available level.
+ */
+ tasklet_hi_schedule(&ar->usb_tasklet);
+
+ if (atomic_read(&ar->rx_anch_urbs) == 0) {
+ /*
+ * The system is too slow to cope with
+ * the enormous workload. We have simply
+ * run out of active rx urbs and this
+ * unfortunatly leads to an unpredictable
+ * device.
+ */
+
+ carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+ }
+ } else {
+ /*
+ * Using anything less than _high_ priority absolutely
+ * kills the rx performance my UP-System...
+ */
+ tasklet_hi_schedule(&ar->usb_tasklet);
+ }
+}
+
+static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp)
+{
+ struct urb *urb;
+ void *buf;
+
+ buf = kmalloc(ar->fw.rx_size, gfp);
+ if (!buf)
+ return NULL;
+
+ urb = usb_alloc_urb(0, gfp);
+ if (!urb) {
+ kfree(buf);
+ return NULL;
+ }
+
+ usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev,
+ AR9170_USB_EP_RX), buf, ar->fw.rx_size,
+ carl9170_usb_rx_complete, ar);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ return urb;
+}
+
+static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar)
+{
+ struct urb *urb = NULL;
+ void *ibuf;
+ int err = -ENOMEM;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto out;
+
+ ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL);
+ if (!ibuf)
+ goto out;
+
+ usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev,
+ AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX,
+ carl9170_usb_rx_irq_complete, ar, 1);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &ar->rx_anch);
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err)
+ usb_unanchor_urb(urb);
+
+out:
+ usb_free_urb(urb);
+ return err;
+}
+
+static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int i, err = -EINVAL;
+
+ /*
+ * The driver actively maintains a second shadow
+ * pool for inactive, but fully-prepared rx urbs.
+ *
+ * The pool should help the driver to master huge
+ * workload spikes without running the risk of
+ * undersupplying the hardware or wasting time by
+ * processing rx data (streams) inside the urb
+ * completion (hardirq context).
+ */
+ for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) {
+ urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL);
+ if (!urb) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ usb_anchor_urb(urb, &ar->rx_pool);
+ atomic_inc(&ar->rx_pool_urbs);
+ usb_free_urb(urb);
+ }
+
+ err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL);
+ if (err)
+ goto err_out;
+
+ /* the device now waiting for the firmware. */
+ carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE);
+ return 0;
+
+err_out:
+
+ usb_scuttle_anchored_urbs(&ar->rx_pool);
+ usb_scuttle_anchored_urbs(&ar->rx_work);
+ usb_kill_anchored_urbs(&ar->rx_anch);
+ return err;
+}
+
+static int carl9170_usb_flush(struct ar9170 *ar)
+{
+ struct urb *urb;
+ int ret, err = 0;
+
+ while ((urb = usb_get_from_anchor(&ar->tx_wait))) {
+ struct sk_buff *skb = (void *)urb->context;
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+ usb_free_urb(urb);
+ }
+
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+
+ /* lets wait a while until the tx - queues are dried out */
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+
+ usb_kill_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+
+ return err;
+}
+
+static void carl9170_usb_cancel_urbs(struct ar9170 *ar)
+{
+ int err;
+
+ carl9170_set_state(ar, CARL9170_UNKNOWN_STATE);
+
+ err = carl9170_usb_flush(ar);
+ if (err)
+ dev_err(&ar->udev->dev, "stuck tx urbs!\n");
+
+ usb_poison_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+ usb_poison_anchored_urbs(&ar->rx_anch);
+
+ tasklet_kill(&ar->usb_tasklet);
+
+ usb_scuttle_anchored_urbs(&ar->rx_work);
+ usb_scuttle_anchored_urbs(&ar->rx_pool);
+ usb_scuttle_anchored_urbs(&ar->tx_cmd);
+}
+
+int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd,
+ const bool free_buf)
+{
+ struct urb *urb;
+
+ if (!IS_INITIALIZED(ar))
+ return -EPERM;
+
+ if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4))
+ return -EINVAL;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev,
+ AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4,
+ carl9170_usb_cmd_complete, ar, 1);
+
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ if (free_buf)
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &ar->tx_cmd);
+ usb_free_urb(urb);
+
+ return carl9170_usb_submit_cmd_urb(ar);
+}
+
+int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd,
+ unsigned int plen, void *payload, unsigned int outlen, void *out)
+{
+ int err = -ENOMEM;
+
+ if (!IS_ACCEPTING_CMD(ar))
+ return -EIO;
+
+ if (!(cmd & CARL9170_CMD_ASYNC_FLAG))
+ might_sleep();
+
+ ar->cmd.hdr.len = plen;
+ ar->cmd.hdr.cmd = cmd;
+ /* writing multiple regs fills this buffer already */
+ if (plen && payload != (u8 *)(ar->cmd.data))
+ memcpy(ar->cmd.data, payload, plen);
+
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readbuf = (u8 *)out;
+ ar->readlen = outlen;
+ spin_unlock_bh(&ar->cmd_lock);
+
+ err = __carl9170_exec_cmd(ar, &ar->cmd, false);
+
+ if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) {
+ err = wait_for_completion_timeout(&ar->cmd_wait, HZ);
+ if (err == 0) {
+ err = -ETIMEDOUT;
+ goto err_unbuf;
+ }
+
+ if (ar->readlen != outlen) {
+ err = -EMSGSIZE;
+ goto err_unbuf;
+ }
+ }
+
+ return 0;
+
+err_unbuf:
+ /* Maybe the device was removed in the moment we were waiting? */
+ if (IS_STARTED(ar)) {
+ dev_err(&ar->udev->dev, "no command feedback "
+ "received (%d).\n", err);
+
+ /* provide some maybe useful debug information */
+ print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE,
+ &ar->cmd, plen + 4);
+
+ carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT);
+ }
+
+ /* invalidate to avoid completing the next command prematurely */
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readbuf = NULL;
+ ar->readlen = 0;
+ spin_unlock_bh(&ar->cmd_lock);
+
+ return err;
+}
+
+void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct urb *urb;
+ struct ar9170_stream *tx_stream;
+ void *data;
+ unsigned int len;
+
+ if (!IS_STARTED(ar))
+ goto err_drop;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ goto err_drop;
+
+ if (ar->fw.tx_stream) {
+ tx_stream = (void *) (skb->data - sizeof(*tx_stream));
+
+ len = skb->len + sizeof(*tx_stream);
+ tx_stream->length = cpu_to_le16(len);
+ tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG);
+ data = tx_stream;
+ } else {
+ data = skb->data;
+ len = skb->len;
+ }
+
+ usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev,
+ AR9170_USB_EP_TX), data, len,
+ carl9170_usb_tx_data_complete, skb);
+
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ usb_anchor_urb(urb, &ar->tx_wait);
+
+ usb_free_urb(urb);
+
+ carl9170_usb_submit_data_urb(ar);
+ return;
+
+err_drop:
+ carl9170_tx_drop(ar, skb);
+ carl9170_tx_callback(ar, skb);
+}
+
+static void carl9170_release_firmware(struct ar9170 *ar)
+{
+ if (ar->fw.fw) {
+ release_firmware(ar->fw.fw);
+ memset(&ar->fw, 0, sizeof(ar->fw));
+ }
+}
+
+void carl9170_usb_stop(struct ar9170 *ar)
+{
+ int ret;
+
+ carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED);
+
+ ret = carl9170_usb_flush(ar);
+ if (ret)
+ dev_err(&ar->udev->dev, "kill pending tx urbs.\n");
+
+ usb_poison_anchored_urbs(&ar->tx_anch);
+ carl9170_usb_handle_tx_err(ar);
+
+ /* kill any pending command */
+ spin_lock_bh(&ar->cmd_lock);
+ ar->readlen = 0;
+ spin_unlock_bh(&ar->cmd_lock);
+ complete_all(&ar->cmd_wait);
+
+ /* This is required to prevent an early completion on _start */
+ INIT_COMPLETION(ar->cmd_wait);
+
+ /*
+ * Note:
+ * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
+ * Else we would end up with a unresponsive device...
+ */
+}
+
+int carl9170_usb_open(struct ar9170 *ar)
+{
+ usb_unpoison_anchored_urbs(&ar->tx_anch);
+
+ carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE);
+ return 0;
+}
+
+static int carl9170_usb_load_firmware(struct ar9170 *ar)
+{
+ const u8 *data;
+ u8 *buf;
+ unsigned int transfer;
+ size_t len;
+ u32 addr;
+ int err = 0;
+
+ buf = kmalloc(4096, GFP_KERNEL);
+ if (!buf) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ data = ar->fw.fw->data;
+ len = ar->fw.fw->size;
+ addr = ar->fw.address;
+
+ /* this removes the miniboot image */
+ data += ar->fw.offset;
+ len -= ar->fw.offset;
+
+ while (len) {
+ transfer = min_t(unsigned int, len, 4096u);
+ memcpy(buf, data, transfer);
+
+ err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0),
+ 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+ addr >> 8, 0, buf, transfer, 100);
+
+ if (err < 0) {
+ kfree(buf);
+ goto err_out;
+ }
+
+ len -= transfer;
+ data += transfer;
+ addr += transfer;
+ }
+ kfree(buf);
+
+ err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0),
+ 0x31 /* FW DL COMPLETE */,
+ 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200);
+
+ if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) {
+ err = -ETIMEDOUT;
+ goto err_out;
+ }
+
+ err = carl9170_echo_test(ar, 0x4a110123);
+ if (err)
+ goto err_out;
+
+ /* firmware restarts cmd counter */
+ ar->cmd_seq = -1;
+
+ return 0;
+
+err_out:
+ dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err);
+ return err;
+}
+
+int carl9170_usb_restart(struct ar9170 *ar)
+{
+ int err = 0;
+
+ if (ar->intf->condition != USB_INTERFACE_BOUND)
+ return 0;
+
+ /* Disable command response sequence counter. */
+ ar->cmd_seq = -2;
+
+ err = carl9170_reboot(ar);
+
+ carl9170_usb_stop(ar);
+
+ carl9170_set_state(ar, CARL9170_UNKNOWN_STATE);
+
+ if (err)
+ goto err_out;
+
+ tasklet_schedule(&ar->usb_tasklet);
+
+ /* The reboot procedure can take quite a while to complete. */
+ msleep(1100);
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_out;
+
+ err = carl9170_usb_load_firmware(ar);
+ if (err)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ carl9170_usb_cancel_urbs(ar);
+ return err;
+}
+
+void carl9170_usb_reset(struct ar9170 *ar)
+{
+ /*
+ * This is the last resort to get the device going again
+ * without any *user replugging action*.
+ *
+ * But there is a catch: usb_reset really is like a physical
+ * *reconnect*. The mac80211 state will be lost in the process.
+ * Therefore a userspace application, which is monitoring
+ * the link must step in.
+ */
+ carl9170_usb_cancel_urbs(ar);
+
+ carl9170_usb_stop(ar);
+
+ usb_queue_reset_device(ar->intf);
+}
+
+static int carl9170_usb_init_device(struct ar9170 *ar)
+{
+ int err;
+
+ err = carl9170_usb_send_rx_irq_urb(ar);
+ if (err)
+ goto err_out;
+
+ err = carl9170_usb_init_rx_bulk_urbs(ar);
+ if (err)
+ goto err_unrx;
+
+ mutex_lock(&ar->mutex);
+ err = carl9170_usb_load_firmware(ar);
+ mutex_unlock(&ar->mutex);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+err_out:
+ return err;
+}
+
+static void carl9170_usb_firmware_failed(struct ar9170 *ar)
+{
+ struct device *parent = ar->udev->dev.parent;
+ struct usb_device *udev;
+
+ /*
+ * Store a copy of the usb_device pointer locally.
+ * This is because device_release_driver initiates
+ * carl9170_usb_disconnect, which in turn frees our
+ * driver context (ar).
+ */
+ udev = ar->udev;
+
+ complete(&ar->fw_load_wait);
+
+ /* unbind anything failed */
+ if (parent)
+ device_lock(parent);
+
+ device_release_driver(&udev->dev);
+ if (parent)
+ device_unlock(parent);
+
+ usb_put_dev(udev);
+}
+
+static void carl9170_usb_firmware_finish(struct ar9170 *ar)
+{
+ int err;
+
+ err = carl9170_parse_firmware(ar);
+ if (err)
+ goto err_freefw;
+
+ err = carl9170_usb_init_device(ar);
+ if (err)
+ goto err_freefw;
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
+ err = carl9170_register(ar);
+
+ carl9170_usb_stop(ar);
+ if (err)
+ goto err_unrx;
+
+ complete(&ar->fw_load_wait);
+ usb_put_dev(ar->udev);
+ return;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+err_freefw:
+ carl9170_release_firmware(ar);
+ carl9170_usb_firmware_failed(ar);
+}
+
+static void carl9170_usb_firmware_step2(const struct firmware *fw,
+ void *context)
+{
+ struct ar9170 *ar = context;
+
+ if (fw) {
+ ar->fw.fw = fw;
+ carl9170_usb_firmware_finish(ar);
+ return;
+ }
+
+ dev_err(&ar->udev->dev, "firmware not found.\n");
+ carl9170_usb_firmware_failed(ar);
+}
+
+static int carl9170_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct ar9170 *ar;
+ struct usb_device *udev;
+ int err;
+
+ err = usb_reset_device(interface_to_usbdev(intf));
+ if (err)
+ return err;
+
+ ar = carl9170_alloc(sizeof(*ar));
+ if (IS_ERR(ar))
+ return PTR_ERR(ar);
+
+ udev = interface_to_usbdev(intf);
+ usb_get_dev(udev);
+ ar->udev = udev;
+ ar->intf = intf;
+ ar->features = id->driver_info;
+
+ usb_set_intfdata(intf, ar);
+ SET_IEEE80211_DEV(ar->hw, &intf->dev);
+
+ init_usb_anchor(&ar->rx_anch);
+ init_usb_anchor(&ar->rx_pool);
+ init_usb_anchor(&ar->rx_work);
+ init_usb_anchor(&ar->tx_wait);
+ init_usb_anchor(&ar->tx_anch);
+ init_usb_anchor(&ar->tx_cmd);
+ init_usb_anchor(&ar->tx_err);
+ init_completion(&ar->cmd_wait);
+ init_completion(&ar->fw_boot_wait);
+ init_completion(&ar->fw_load_wait);
+ tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet,
+ (unsigned long)ar);
+
+ atomic_set(&ar->tx_cmd_urbs, 0);
+ atomic_set(&ar->tx_anch_urbs, 0);
+ atomic_set(&ar->rx_work_urbs, 0);
+ atomic_set(&ar->rx_anch_urbs, 0);
+ atomic_set(&ar->rx_pool_urbs, 0);
+ ar->cmd_seq = -2;
+
+ usb_get_dev(ar->udev);
+
+ carl9170_set_state(ar, CARL9170_STOPPED);
+
+ return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME,
+ &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2);
+}
+
+static void carl9170_usb_disconnect(struct usb_interface *intf)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+ struct usb_device *udev;
+
+ if (WARN_ON(!ar))
+ return;
+
+ udev = ar->udev;
+ wait_for_completion(&ar->fw_load_wait);
+
+ if (IS_INITIALIZED(ar)) {
+ carl9170_reboot(ar);
+ carl9170_usb_stop(ar);
+ }
+
+ carl9170_usb_cancel_urbs(ar);
+ carl9170_unregister(ar);
+
+ usb_set_intfdata(intf, NULL);
+
+ carl9170_release_firmware(ar);
+ carl9170_free(ar);
+ usb_put_dev(udev);
+}
+
+#ifdef CONFIG_PM
+static int carl9170_usb_suspend(struct usb_interface *intf,
+ pm_message_t message)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+
+ if (!ar)
+ return -ENODEV;
+
+ carl9170_usb_cancel_urbs(ar);
+
+ /*
+ * firmware automatically reboots for usb suspend.
+ */
+
+ return 0;
+}
+
+static int carl9170_usb_resume(struct usb_interface *intf)
+{
+ struct ar9170 *ar = usb_get_intfdata(intf);
+ int err;
+
+ if (!ar)
+ return -ENODEV;
+
+ usb_unpoison_anchored_urbs(&ar->rx_anch);
+
+ err = carl9170_usb_init_device(ar);
+ if (err)
+ goto err_unrx;
+
+ err = carl9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ carl9170_usb_cancel_urbs(ar);
+
+ return err;
+}
+#endif /* CONFIG_PM */
+
+static struct usb_driver carl9170_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = carl9170_usb_probe,
+ .disconnect = carl9170_usb_disconnect,
+ .id_table = carl9170_usb_ids,
+ .soft_unbind = 1,
+#ifdef CONFIG_PM
+ .suspend = carl9170_usb_suspend,
+ .resume = carl9170_usb_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init carl9170_usb_init(void)
+{
+ return usb_register(&carl9170_driver);
+}
+
+static void __exit carl9170_usb_exit(void)
+{
+ usb_deregister(&carl9170_driver);
+}
+
+module_init(carl9170_usb_init);
+module_exit(carl9170_usb_exit);
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
new file mode 100644
index 000000000000..0e917f80eab4
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -0,0 +1,7 @@
+#ifndef __CARL9170_SHARED_VERSION_H
+#define __CARL9170_SHARED_VERSION_H
+#define CARL9170FW_VERSION_YEAR 10
+#define CARL9170FW_VERSION_MONTH 8
+#define CARL9170FW_VERSION_DAY 30
+#define CARL9170FW_VERSION_GIT "1.8.8.1"
+#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h
new file mode 100644
index 000000000000..48ead2268f50
--- /dev/null
+++ b/drivers/net/wireless/ath/carl9170/wlan.h
@@ -0,0 +1,412 @@
+/*
+ * Shared Atheros AR9170 Header
+ *
+ * RX/TX meta descriptor format
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CARL9170_SHARED_WLAN_H
+#define __CARL9170_SHARED_WLAN_H
+
+#include "fwcmd.h"
+
+#define AR9170_RX_PHY_RATE_CCK_1M 0x0a
+#define AR9170_RX_PHY_RATE_CCK_2M 0x14
+#define AR9170_RX_PHY_RATE_CCK_5M 0x37
+#define AR9170_RX_PHY_RATE_CCK_11M 0x6e
+
+#define AR9170_ENC_ALG_NONE 0x0
+#define AR9170_ENC_ALG_WEP64 0x1
+#define AR9170_ENC_ALG_TKIP 0x2
+#define AR9170_ENC_ALG_AESCCMP 0x4
+#define AR9170_ENC_ALG_WEP128 0x5
+#define AR9170_ENC_ALG_WEP256 0x6
+#define AR9170_ENC_ALG_CENC 0x7
+
+#define AR9170_RX_ENC_SOFTWARE 0x8
+
+#define AR9170_RX_STATUS_MODULATION 0x03
+#define AR9170_RX_STATUS_MODULATION_S 0
+#define AR9170_RX_STATUS_MODULATION_CCK 0x00
+#define AR9170_RX_STATUS_MODULATION_OFDM 0x01
+#define AR9170_RX_STATUS_MODULATION_HT 0x02
+#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03
+
+/* depends on modulation */
+#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08
+#define AR9170_RX_STATUS_GREENFIELD 0x08
+
+#define AR9170_RX_STATUS_MPDU 0x30
+#define AR9170_RX_STATUS_MPDU_S 4
+#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
+#define AR9170_RX_STATUS_MPDU_FIRST 0x20
+#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
+#define AR9170_RX_STATUS_MPDU_LAST 0x10
+
+#define AR9170_RX_ERROR_RXTO 0x01
+#define AR9170_RX_ERROR_OVERRUN 0x02
+#define AR9170_RX_ERROR_DECRYPT 0x04
+#define AR9170_RX_ERROR_FCS 0x08
+#define AR9170_RX_ERROR_WRONG_RA 0x10
+#define AR9170_RX_ERROR_PLCP 0x20
+#define AR9170_RX_ERROR_MMIC 0x40
+#define AR9170_RX_ERROR_FATAL 0x80
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS 0x0001
+#define AR9170_TX_MAC_PROT_CTS 0x0002
+#define AR9170_TX_MAC_PROT 0x0003
+
+#define AR9170_TX_MAC_NO_ACK 0x0004
+/* if unset, MAC will only do SIFS space before frame */
+#define AR9170_TX_MAC_BACKOFF 0x0008
+#define AR9170_TX_MAC_BURST 0x0010
+#define AR9170_TX_MAC_AGGR 0x0020
+
+/* encryption is a two-bit field */
+#define AR9170_TX_MAC_ENCR_NONE 0x0000
+#define AR9170_TX_MAC_ENCR_RC4 0x0040
+#define AR9170_TX_MAC_ENCR_CENC 0x0080
+#define AR9170_TX_MAC_ENCR_AES 0x00c0
+
+#define AR9170_TX_MAC_MMIC 0x0100
+#define AR9170_TX_MAC_HW_DURATION 0x0200
+#define AR9170_TX_MAC_QOS_S 10
+#define AR9170_TX_MAC_QOS 0x0c00
+#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
+#define AR9170_TX_MAC_TXOP_RIFS 0x2000
+#define AR9170_TX_MAC_IMM_BA 0x4000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK 0x00000000
+#define AR9170_TX_PHY_MOD_OFDM 0x00000001
+#define AR9170_TX_PHY_MOD_HT 0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
+#define AR9170_TX_PHY_GREENFIELD 0x00000004
+
+#define AR9170_TX_PHY_BW_S 3
+#define AR9170_TX_PHY_BW (3 << AR9170_TX_PHY_BW_SHIFT)
+#define AR9170_TX_PHY_BW_20MHZ 0
+#define AR9170_TX_PHY_BW_40MHZ 2
+#define AR9170_TX_PHY_BW_40MHZ_DUP 3
+
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_S 6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \
+ AR9170_TX_PHY_TX_HEAVY_CLIP_S)
+
+#define AR9170_TX_PHY_TX_PWR_S 9
+#define AR9170_TX_PHY_TX_PWR (0x3f << \
+ AR9170_TX_PHY_TX_PWR_S)
+
+#define AR9170_TX_PHY_TXCHAIN_S 15
+#define AR9170_TX_PHY_TXCHAIN (7 << \
+ AR9170_TX_PHY_TXCHAIN_S)
+#define AR9170_TX_PHY_TXCHAIN_1 1
+/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
+#define AR9170_TX_PHY_TXCHAIN_2 5
+
+#define AR9170_TX_PHY_MCS_S 18
+#define AR9170_TX_PHY_MCS (0x7f << \
+ AR9170_TX_PHY_MCS_S)
+
+#define AR9170_TX_PHY_RATE_CCK_1M 0x0
+#define AR9170_TX_PHY_RATE_CCK_2M 0x1
+#define AR9170_TX_PHY_RATE_CCK_5M 0x2
+#define AR9170_TX_PHY_RATE_CCK_11M 0x3
+
+/* same as AR9170_RX_PHY_RATE */
+#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb
+#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf
+#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa
+#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe
+#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9
+#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd
+#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8
+#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc
+
+#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0
+#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1
+#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2
+#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3
+#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4
+#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5
+#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6
+#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7
+#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8
+#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9
+#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa
+#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb
+#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc
+#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd
+#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe
+#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf
+
+#define AR9170_TX_PHY_SHORT_GI 0x80000000
+
+#ifdef __CARL9170FW__
+struct ar9170_tx_hw_mac_control {
+ union {
+ struct {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 erp_prot:2;
+ u8 no_ack:1;
+ u8 backoff:1;
+ u8 burst:1;
+ u8 ampdu:1;
+
+ u8 enc_mode:2;
+
+ u8 hw_mmic:1;
+ u8 hw_duration:1;
+
+ u8 qos_queue:2;
+
+ u8 disable_txop:1;
+ u8 txop_rifs:1;
+
+ u8 ba_end:1;
+ u8 probe:1;
+ } __packed;
+
+ __le16 set;
+ } __packed;
+} __packed;
+
+struct ar9170_tx_hw_phy_control {
+ union {
+ struct {
+ /*
+ * Beware of compiler bugs in all gcc pre 4.4!
+ */
+
+ u8 modulation:2;
+ u8 preamble:1;
+ u8 bandwidth:2;
+ u8:1;
+ u8 heavy_clip:3;
+ u8 tx_power:6;
+ u8 chains:3;
+ u8 mcs:7;
+ u8:6;
+ u8 short_gi:1;
+ } __packed;
+
+ __le32 set;
+ } __packed;
+} __packed;
+
+struct ar9170_tx_rate_info {
+ u8 tries:3;
+ u8 erp_prot:2;
+ u8 ampdu:1;
+ u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */
+} __packed;
+
+struct carl9170_tx_superdesc {
+ __le16 len;
+ u8 rix;
+ u8 cnt;
+ u8 cookie;
+ u8 ampdu_density:3;
+ u8 ampdu_factor:2;
+ u8 ampdu_commit_density:1;
+ u8 ampdu_commit_factor:1;
+ u8 ampdu_unused_bit:1;
+ u8 queue:2;
+ u8 reserved:1;
+ u8 vif_id:3;
+ u8 fill_in_tsf:1;
+ u8 cab:1;
+ u8 padding2;
+ struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES];
+ struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES];
+} __packed;
+
+struct ar9170_tx_hwdesc {
+ __le16 length;
+ struct ar9170_tx_hw_mac_control mac;
+ struct ar9170_tx_hw_phy_control phy;
+} __packed;
+
+struct ar9170_tx_frame {
+ struct ar9170_tx_hwdesc hdr;
+
+ union {
+ struct ieee80211_hdr i3e;
+ u8 payload[0];
+ } data;
+} __packed;
+
+struct carl9170_tx_superframe {
+ struct carl9170_tx_superdesc s;
+ struct ar9170_tx_frame f;
+} __packed;
+
+#endif /* __CARL9170FW__ */
+
+struct _ar9170_tx_hwdesc {
+ __le16 length;
+ __le16 mac_control;
+ __le32 phy_control;
+} __packed;
+
+#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0
+#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7
+#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18
+#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40
+#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6
+
+#define CARL9170_TX_SUPER_MISC_QUEUE 0x3
+#define CARL9170_TX_SUPER_MISC_QUEUE_S 0
+#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38
+#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3
+#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40
+#define CARL9170_TX_SUPER_MISC_CAB 0x80
+
+#define CARL9170_TX_SUPER_RI_TRIES 0x7
+#define CARL9170_TX_SUPER_RI_TRIES_S 0
+#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18
+#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3
+#define CARL9170_TX_SUPER_RI_AMPDU 0x20
+#define CARL9170_TX_SUPER_RI_AMPDU_S 5
+
+struct _carl9170_tx_superdesc {
+ __le16 len;
+ u8 rix;
+ u8 cnt;
+ u8 cookie;
+ u8 ampdu_settings;
+ u8 misc;
+ u8 padding;
+ u8 ri[CARL9170_TX_MAX_RATES];
+ __le32 rr[CARL9170_TX_MAX_RETRY_RATES];
+} __packed;
+
+struct _carl9170_tx_superframe {
+ struct _carl9170_tx_superdesc s;
+ struct _ar9170_tx_hwdesc f;
+ u8 frame_data[0];
+} __packed;
+
+#define CARL9170_TX_SUPERDESC_LEN 24
+#define AR9170_TX_HWDESC_LEN 8
+#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \
+ AR9170_TX_SUPERDESC_LEN)
+
+struct ar9170_rx_head {
+ u8 plcp[12];
+} __packed;
+
+struct ar9170_rx_phystatus {
+ union {
+ struct {
+ u8 rssi_ant0, rssi_ant1, rssi_ant2,
+ rssi_ant0x, rssi_ant1x, rssi_ant2x,
+ rssi_combined;
+ } __packed;
+ u8 rssi[7];
+ } __packed;
+
+ u8 evm_stream0[6], evm_stream1[6];
+ u8 phy_err;
+} __packed;
+
+struct ar9170_rx_macstatus {
+ u8 SAidx, DAidx;
+ u8 error;
+ u8 status;
+} __packed;
+
+struct ar9170_rx_frame_single {
+ struct ar9170_rx_head phy_head;
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_phystatus phy_tail;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_head {
+ struct ar9170_rx_head phy_head;
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_middle {
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame_tail {
+ struct ieee80211_hdr i3e;
+ struct ar9170_rx_phystatus phy_tail;
+ struct ar9170_rx_macstatus macstatus;
+} __packed;
+
+struct ar9170_rx_frame {
+ union {
+ struct ar9170_rx_frame_single single;
+ struct ar9170_rx_frame_head head;
+ struct ar9170_rx_frame_middle middle;
+ struct ar9170_rx_frame_tail tail;
+ } __packed;
+} __packed;
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
+{
+ return (t->SAidx & 0xc0) >> 4 |
+ (t->DAidx & 0xc0) >> 6;
+}
+
+enum ar9170_txq {
+ AR9170_TXQ_BE,
+
+ AR9170_TXQ_VI,
+ AR9170_TXQ_VO,
+ AR9170_TXQ_BK,
+
+ __AR9170_NUM_TXQ,
+};
+
+static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 };
+
+#define AR9170_TXQ_DEPTH 32
+
+#endif /* __CARL9170_SHARED_WLAN_H */
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 873bf526e11f..fd3a020682dc 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -36,6 +36,7 @@
* @ATH_DBG_PS: power save processing
* @ATH_DBG_HWTIMER: hardware timer handling
* @ATH_DBG_BTCOEX: bluetooth coexistance
+ * @ATH_DBG_BSTUCK: stuck beacons
* @ATH_DBG_ANY: enable all debugging
*
* The debug level is used to control the amount and type of debugging output
@@ -60,6 +61,7 @@ enum ATH_DEBUG {
ATH_DBG_HWTIMER = 0x00001000,
ATH_DBG_BTCOEX = 0x00002000,
ATH_DBG_WMI = 0x00004000,
+ ATH_DBG_BSTUCK = 0x00008000,
ATH_DBG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index a1c39526161a..345dd9721b41 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -31,7 +31,6 @@ enum ctl_group {
#define NO_CTL 0xff
#define SD_NO_CTL 0xE0
#define NO_CTL 0xff
-#define CTL_MODE_M 7
#define CTL_11A 0
#define CTL_11B 1
#define CTL_11G 2
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 80b19a44a407..59f59fa40334 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -627,6 +627,7 @@ out_unlock:
.open = b43_debugfs_open, \
.read = b43_debugfs_read, \
.write = b43_debugfs_write, \
+ .llseek = generic_file_llseek, \
}, \
.file_struct_offset = offsetof(struct b43_dfsentry, \
file_##name), \
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 20631ae2ddd7..a1186525c70d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2280,6 +2280,7 @@ out:
static int b43_upload_microcode(struct b43_wldev *dev)
{
+ struct wiphy *wiphy = dev->wl->hw->wiphy;
const size_t hdr_len = sizeof(struct b43_fw_header);
const __be32 *data;
unsigned int i, len;
@@ -2405,6 +2406,10 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}
}
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
+ dev->fw.rev, dev->fw.patch);
+ wiphy->hw_version = dev->dev->id.coreid;
+
if (b43_is_old_txhdr_format(dev)) {
/* We're over the deadline, but we keep support for old fw
* until it turns out to be in major conflict with something new. */
@@ -3754,17 +3759,17 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
err = -EINVAL;
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- algorithm = B43_SEC_ALGO_WEP40;
- else
- algorithm = B43_SEC_ALGO_WEP104;
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ algorithm = B43_SEC_ALGO_WEP40;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ algorithm = B43_SEC_ALGO_WEP104;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
algorithm = B43_SEC_ALGO_TKIP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
algorithm = B43_SEC_ALGO_AES;
break;
default:
@@ -4250,6 +4255,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
return;
+
+ /* Unregister HW RNG driver */
+ b43_rng_exit(dev->wl);
+
b43_set_status(dev, B43_STAT_UNINIT);
/* Stop the microcode PSM. */
@@ -4379,6 +4388,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_set_status(dev, B43_STAT_INITIALIZED);
+ /* Register HW RNG driver */
+ b43_rng_init(dev->wl);
+
out:
return err;
@@ -4984,7 +4996,6 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
if (err)
goto err_one_core_detach;
b43_leds_register(wl->current_dev);
- b43_rng_init(wl);
}
out:
@@ -5020,7 +5031,6 @@ static void b43_remove(struct ssb_device *dev)
b43_one_core_detach(dev);
if (list_empty(&wl->devlist)) {
- b43_rng_exit(wl);
b43_leds_unregister(wl);
/* Last core on the chip unregistered.
* We can destroy common struct b43_wl.
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5a725703770c..2466c0a52e5d 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -893,7 +893,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
-static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
+static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
u8 i, j;
@@ -1094,11 +1094,12 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
- b43_nphy_gain_crtl_workarounds(dev);
+ b43_nphy_gain_ctrl_workarounds(dev);
if (dev->phy.rev < 2) {
if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
- ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
+ b43_hf_write(dev, b43_hf_read(dev) |
+ B43_HF_MLADVW);
} else if (dev->phy.rev == 2) {
b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
@@ -1182,7 +1183,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
len = bw << 1;
}
- samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
+ samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL);
if (!samples) {
b43err(dev->wl, "allocation for samples generation failed\n");
return 0;
@@ -3073,6 +3074,57 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
+static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
+{
+ u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
+ if (on)
+ tmslow |= SSB_TMSLOW_PHYCLK;
+ else
+ tmslow &= ~SSB_TMSLOW_PHYCLK;
+ ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
+static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
+{
+ struct b43_phy *phy = &dev->phy;
+ struct b43_phy_n *nphy = phy->n;
+ u16 buf[16];
+
+ nphy->phyrxchain = mask;
+
+ if (0 /* FIXME clk */)
+ return;
+
+ b43_mac_suspend(dev);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, true);
+
+ b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
+ (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT);
+
+ if ((mask & 0x3) != 0x3) {
+ b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1);
+ if (dev->phy.rev >= 3) {
+ /* TODO */
+ }
+ } else {
+ b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E);
+ if (dev->phy.rev >= 3) {
+ /* TODO */
+ }
+ }
+
+ b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, false);
+
+ b43_mac_enable(dev);
+}
+
/*
* Init N-PHY
* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
@@ -3173,7 +3225,7 @@ int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
b43_nphy_bmac_clock_fgc(dev, 0);
- /* TODO N PHY MAC PHY Clock Set with argument 1 */
+ b43_nphy_mac_phy_clock_set(dev, true);
b43_nphy_pa_override(dev, false);
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
@@ -3199,7 +3251,7 @@ int b43_phy_initn(struct b43_wldev *dev)
}
if (nphy->phyrxchain != 3)
- ;/* TODO N PHY RX Core Set State with phyrxchain as argument */
+ b43_nphy_set_rx_core_state(dev, nphy->phyrxchain);
if (nphy->mphase_cal_phase_id > 0)
;/* TODO PHY Periodic Calibration Multi-Phase Restart */
diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
index 1f85ac569fec..f232618f2cd1 100644
--- a/drivers/net/wireless/b43legacy/debugfs.c
+++ b/drivers/net/wireless/b43legacy/debugfs.c
@@ -334,6 +334,7 @@ out_unlock:
.open = b43legacy_debugfs_open, \
.read = b43legacy_debugfs_read, \
.write = b43legacy_debugfs_write, \
+ .llseek = generic_file_llseek, \
}, \
.file_struct_offset = offsetof(struct b43legacy_dfsentry, \
file_##name), \
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1713f5f7a58b..67f18ecdb3bf 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1623,6 +1623,7 @@ error:
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
{
+ struct wiphy *wiphy = dev->wl->hw->wiphy;
const size_t hdr_len = sizeof(struct b43legacy_fw_header);
const __be32 *data;
unsigned int i;
@@ -1732,6 +1733,10 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
+ dev->fw.rev, dev->fw.patch);
+ wiphy->hw_version = dev->dev->id.coreid;
+
return 0;
error:
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index a85e43a8d758..6038633ef361 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1696,7 +1696,7 @@ static int prism2_request_scan(struct net_device *dev)
hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
HFA384X_ROAMING_FIRMWARE);
- return 0;
+ return ret;
}
#else /* !PRISM2_NO_STATION_MODES */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 996e9d7d7586..61915f371416 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1921,9 +1921,9 @@ static int ipw2100_net_init(struct net_device *dev)
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ bg_band->channels = kcalloc(geo->bg_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
if (!bg_band->channels) {
ipw2100_down(priv);
return -ENOMEM;
@@ -3056,9 +3056,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
packet = list_entry(element, struct ipw2100_tx_packet, list);
- IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
+ IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n",
&txq->drv[txq->next],
- (void *)(txq->nic + txq->next *
+ (u32) (txq->nic + txq->next *
sizeof(struct ipw2100_bd)));
packet->index = txq->next;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index cb2552a6777c..0f2508384c75 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11467,9 +11467,9 @@ static int ipw_net_init(struct net_device *dev)
bg_band->band = IEEE80211_BAND_2GHZ;
bg_band->n_channels = geo->bg_channels;
- bg_band->channels =
- kzalloc(geo->bg_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ bg_band->channels = kcalloc(geo->bg_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
/* translate geo->bg to bg_band.channels */
for (i = 0; i < geo->bg_channels; i++) {
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
@@ -11502,9 +11502,9 @@ static int ipw_net_init(struct net_device *dev)
a_band->band = IEEE80211_BAND_5GHZ;
a_band->n_channels = geo->a_channels;
- a_band->channels =
- kzalloc(geo->a_channels *
- sizeof(struct ieee80211_channel), GFP_KERNEL);
+ a_band->channels = kcalloc(geo->a_channels,
+ sizeof(struct ieee80211_channel),
+ GFP_KERNEL);
/* translate geo->bg to a_band.channels */
for (i = 0; i < geo->a_channels; i++) {
a_band->channels[i].band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index a51e4da1bdfc..b82364258dc5 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -3,6 +3,9 @@ config IWLWIFI
depends on PCI && MAC80211
select FW_LOADER
+menu "Debugging Options"
+ depends on IWLWIFI
+
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwlagn and iwl3945 drivers"
depends on IWLWIFI
@@ -36,6 +39,12 @@ config IWLWIFI_DEBUGFS
is a low-impact option that allows getting insight into the
driver's state at runtime.
+config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+ bool "Experimental uCode support"
+ depends on IWLWIFI && IWLWIFI_DEBUG
+ ---help---
+ Enable use of experimental ucode for testing and debugging.
+
config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing"
depends on IWLWIFI
@@ -53,6 +62,7 @@ config IWLWIFI_DEVICE_TRACING
If unsure, say Y so we can help you better when problems
occur.
+endmenu
config IWLAGN
tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 728bb858ba97..493163925a45 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
+iwlagn-objs += iwl-agn-tt.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 0b779a41a142..674fb93ae17f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -130,7 +130,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -217,7 +217,7 @@ static struct iwl_lib_ops iwl1000_lib = {
.set_ct_kill = iwl1000_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -229,6 +229,11 @@ static struct iwl_lib_ops iwl1000_lib = {
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
+ .tt_ops = {
+ .lower_power_detection = iwl_tt_is_low_power_state,
+ .tt_power_mode = iwl_tt_current_power_mode,
+ .ct_kill_check = iwl_check_for_ct_kill,
+ }
};
static const struct iwl_ops iwl1000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 7c731a793632..65b5834da28c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-3945-hw.h) only for hardware-related definitions.
- * Please use iwl-3945-commands.h for uCode API definitions.
+ * Please use iwl-commands.h for uCode API definitions.
* Please use iwl-3945.h for driver implementation definitions.
*/
@@ -226,6 +226,7 @@ struct iwl3945_eeprom {
/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
#define IWL39_NUM_QUEUES 5
+#define IWL39_CMD_QUEUE_NUM 4
#define IWL_DEFAULT_TX_RETRY 15
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 8e84a08ff951..600c4bbd34b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -343,7 +343,7 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s
int i;
IWL_DEBUG_INFO(priv, "enter\n");
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
goto out;
psta = (struct iwl3945_sta_priv *) sta->drv_priv;
@@ -873,6 +873,7 @@ static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = iwl3945_sta_dbgfs_stats_table_read,
.open = iwl3945_open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void iwl3945_add_debugfs(void *priv, void *priv_sta,
@@ -932,7 +933,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock();
- sta = ieee80211_find_sta(priv->vif,
+ sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif,
priv->stations[sta_id].sta.sta.addr);
if (!sta) {
IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
@@ -949,7 +950,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
switch (priv->band) {
case IEEE80211_BAND_2GHZ:
/* TODO: this always does G, not a regression */
- if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
+ if (priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+ RXON_FLG_TGG_PROTECT_MSK) {
rs_sta->tgg = 1;
rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
} else
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ccfcd08218d..5d09686c3389 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -245,7 +245,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
break;
case IEEE80211_BAND_2GHZ:
if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl_is_associated(priv)) {
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
if (rate == IWL_RATE_11M_INDEX)
next_rate = IWL_RATE_5M_INDEX;
}
@@ -273,7 +273,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
struct iwl_queue *q = &txq->q;
struct iwl_tx_info *tx_info;
- BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
+ BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM);
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
@@ -285,7 +285,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
}
if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
- (txq_id != IWL_CMD_QUEUE_NUM) &&
+ (txq_id != IWL39_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
iwl_wake_queue(priv, txq_id);
}
@@ -760,7 +760,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
data_retry_limit = IWL_DEFAULT_TX_RETRY;
tx_cmd->data_retry_limit = data_retry_limit;
- if (tx_id >= IWL_CMD_QUEUE_NUM)
+ if (tx_id >= IWL39_CMD_QUEUE_NUM)
rts_retry_limit = 3;
else
rts_retry_limit = 7;
@@ -909,7 +909,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
/* Tx queue(s) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+ slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
@@ -1072,7 +1072,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
if (priv->txq)
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
txq_id++)
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == IWL39_CMD_QUEUE_NUM)
iwl_cmd_queue_free(priv);
else
iwl_tx_queue_free(priv, txq_id);
@@ -1439,17 +1439,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
int rate_idx, i;
const struct iwl_channel_info *ch_info = NULL;
struct iwl3945_txpowertable_cmd txpower = {
- .channel = priv->active_rxon.channel,
+ .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel,
};
+ u16 chan;
+
+ chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ ch_info = iwl_get_channel_info(priv, priv->band, chan);
if (!ch_info) {
IWL_ERR(priv,
"Failed to get channel info for channel %d [%d]\n",
- le16_to_cpu(priv->active_rxon.channel), priv->band);
+ chan, priv->band);
return -EINVAL;
}
@@ -1710,7 +1711,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
return 0;
}
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int rc = 0;
struct iwl_rx_packet *pkt;
@@ -1721,8 +1723,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1732,10 +1734,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
rxon_assoc.reserved = 0;
rc = iwl_send_cmd_sync(priv, &cmd);
@@ -1761,14 +1763,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
+static int iwl3945_commit_rxon(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
/* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
- struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
+ struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
+ struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
int rc = 0;
- bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -1;
@@ -1781,7 +1783,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
- rc = iwl_check_rxon_cmd(priv);
+ rc = iwl_check_rxon_cmd(priv, ctx);
if (rc) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -1790,8 +1792,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl3945_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- rc = iwl_send_rxon_assoc(priv);
+ if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) {
+ rc = iwl_send_rxon_assoc(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
if (rc) {
IWL_ERR(priv, "Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
@@ -1807,7 +1810,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -1819,7 +1822,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
active_rxon->reserved5 = 0;
rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
+ &priv->contexts[IWL_RXON_CTX_BSS].active);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
@@ -1829,8 +1832,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"configuration (%d).\n", rc);
return rc;
}
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
+ iwl_clear_ucode_stations(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
+ iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
}
IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1848,7 +1852,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
staging_rxon->reserved4 = 0;
staging_rxon->reserved5 = 0;
- iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);
/* Apply the new configuration */
rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -1862,8 +1866,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
if (!new_assoc) {
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
+ iwl_clear_ucode_stations(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
+ iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
}
/* If we issue a new RXON command which required a tune then we must
@@ -2302,8 +2307,10 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
int ret;
if (add) {
- ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
- &vif_priv->ibss_bssid_sta_id);
+ ret = iwl_add_bssid_station(
+ priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ vif->bss_conf.bssid, false,
+ &vif_priv->ibss_bssid_sta_id);
if (ret)
return ret;
@@ -2366,7 +2373,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
* 1M CCK rates */
if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl_is_associated(priv)) {
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
index = IWL_FIRST_CCK_RATE;
for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2421,7 +2428,9 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
priv->hw_params.max_stations = IWL3945_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID;
+
+ priv->sta_key_max_num = STA_KEY_MAX_NUM;
priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
@@ -2439,7 +2448,8 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id =
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bb2aeebf3652..98509c5e708d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -295,7 +295,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
/* scanning */
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
/* Requires full declaration of iwl_priv before including */
#include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d92b72909233..1d6a46d4db59 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
- iwl_is_associated(priv)) {
+ iwl_is_any_associated(priv)) {
struct iwl_calib_diff_gain_cmd cmd;
/* clear data for chain noise calibration algorithm */
@@ -576,7 +576,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
/* Activate all Tx DMA/FIFO channels */
priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6));
- iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+ iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0);
/* make sure all queue are not stopped */
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
@@ -587,6 +587,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
priv->txq_ctx_active_msk = 0;
/* Map each Tx/cmd queue to its corresponding fifo */
BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
+
for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
int ac = default_queue_to_tx_fifo[i];
@@ -656,7 +657,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
@@ -1374,6 +1375,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
u8 band = 0;
bool is_ht40 = false;
u8 ctrl_chan_high = 0;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (test_bit(STATUS_SCANNING, &priv->status)) {
/* If this gets hit a lot, switch it to a BUG() and catch
@@ -1385,17 +1387,16 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
band = priv->band == IEEE80211_BAND_2GHZ;
- is_ht40 = is_ht40_channel(priv->active_rxon.flags);
+ is_ht40 = is_ht40_channel(ctx->active.flags);
- if (is_ht40 &&
- (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
- cmd.channel = priv->active_rxon.channel;
+ cmd.channel = ctx->active.channel;
ret = iwl4965_fill_txpower_tbl(priv, band,
- le16_to_cpu(priv->active_rxon.channel),
+ le16_to_cpu(ctx->active.channel),
is_ht40, ctrl_chan_high, &cmd.tx_power);
if (ret)
goto out;
@@ -1406,12 +1407,13 @@ out:
return ret;
}
-static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int ret = 0;
struct iwl4965_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1426,16 +1428,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
rxon_assoc.reserved = 0;
rxon_assoc.ofdm_ht_single_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
sizeof(rxon_assoc), &rxon_assoc, NULL);
@@ -1448,6 +1450,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int rc;
u8 band = 0;
bool is_ht40 = false;
@@ -1458,22 +1461,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
band = priv->band == IEEE80211_BAND_2GHZ;
- is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
+ is_ht40 = is_ht40_channel(ctx->staging.flags);
if (is_ht40 &&
- (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
cmd.expect_beacon = 0;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -1508,7 +1511,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
@@ -2007,7 +2010,7 @@ static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return priv->hw_params.bcast_sta_id;
+ return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
for (i = start; i < priv->hw_params.max_stations; i++)
@@ -2280,7 +2283,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.set_ct_kill = iwl4965_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 146e6431ae95..3975e45e7500 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-5000-hw.h) only for hardware-related definitions.
- * Use iwl-5000-commands.h for uCode API definitions.
+ * Use iwl-commands.h for uCode API definitions.
*/
#ifndef __iwl_5000_hw_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 48bdcd8d2e94..1dbb1246c083 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -180,7 +180,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -227,7 +227,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -275,14 +275,19 @@ static void iwl5150_temperature(struct iwl_priv *priv)
static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl5000_channel_switch_cmd cmd;
const struct iwl_channel_info *ch_info;
u32 switch_time_in_usec, ucode_switch_time;
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
@@ -291,12 +296,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
};
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -331,7 +336,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
priv->switch_rxon.channel = cmd.channel;
@@ -393,7 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.set_ct_kill = iwl5000_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -405,6 +410,11 @@ static struct iwl_lib_ops iwl5000_lib = {
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
+ .tt_ops = {
+ .lower_power_detection = iwl_tt_is_low_power_state,
+ .tt_power_mode = iwl_tt_current_power_mode,
+ .ct_kill_check = iwl_check_for_ct_kill,
+ }
};
static struct iwl_lib_ops iwl5150_lib = {
@@ -459,7 +469,7 @@ static struct iwl_lib_ops iwl5150_lib = {
.set_ct_kill = iwl5150_set_ct_threshold,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -470,6 +480,11 @@ static struct iwl_lib_ops iwl5150_lib = {
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
+ .tt_ops = {
+ .lower_power_detection = iwl_tt_is_low_power_state,
+ .tt_power_mode = iwl_tt_current_power_mode,
+ .ct_kill_check = iwl_check_for_ct_kill,
+ }
};
static const struct iwl_ops iwl5000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index ddba39999997..47891e16a758 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
- * Use iwl-5000-commands.h for uCode API definitions.
+ * Use iwl-commands.h for uCode API definitions.
*/
#ifndef __iwl_6000_hw_h__
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index cee06b968de8..2fdba088bd27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -52,7 +52,7 @@
/* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 4
#define IWL6050_UCODE_API_MAX 4
-#define IWL6000G2_UCODE_API_MAX 4
+#define IWL6000G2_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL6000_UCODE_API_MIN 4
@@ -161,7 +161,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
sizeof(struct iwlagn_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
- priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
@@ -198,14 +198,19 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
struct ieee80211_channel_switch *ch_switch)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl6000_channel_switch_cmd cmd;
const struct iwl_channel_info *ch_info;
u32 switch_time_in_usec, ucode_switch_time;
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
- struct ieee80211_vif *vif = priv->vif;
+ u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
+ struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
@@ -214,12 +219,12 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
};
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
- ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
+ ch = ch_switch->channel->hw_value;
IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = priv->staging_rxon.flags;
- cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
+ cmd.rxon_flags = ctx->staging.flags;
+ cmd.rxon_filter_flags = ctx->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -254,7 +259,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
cmd.expect_beacon = is_channel_radar(ch_info);
else {
IWL_ERR(priv, "invalid channel switch from %u to %u\n",
- priv->active_rxon.channel, ch);
+ ctx->active.channel, ch);
return -EFAULT;
}
priv->switch_rxon.channel = cmd.channel;
@@ -318,7 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = {
.set_calib_version = iwl6000_set_calib_version,
},
.manage_ibss_station = iwlagn_manage_ibss_station,
- .update_bcast_station = iwl_update_bcast_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -330,6 +335,86 @@ static struct iwl_lib_ops iwl6000_lib = {
.check_ack_health = iwl_good_ack_health,
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
+ .tt_ops = {
+ .lower_power_detection = iwl_tt_is_low_power_state,
+ .tt_power_mode = iwl_tt_current_power_mode,
+ .ct_kill_check = iwl_check_for_ct_kill,
+ }
+};
+
+static struct iwl_lib_ops iwl6000g2b_lib = {
+ .set_hw_params = iwl6000_hw_set_hw_params,
+ .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
+ .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
+ .txq_set_sched = iwlagn_txq_set_sched,
+ .txq_agg_enable = iwlagn_txq_agg_enable,
+ .txq_agg_disable = iwlagn_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
+ .rx_handler_setup = iwlagn_bt_rx_handler_setup,
+ .setup_deferred_work = iwlagn_bt_setup_deferred_work,
+ .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
+ .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
+ .load_ucode = iwlagn_load_ucode,
+ .dump_nic_event_log = iwl_dump_nic_event_log,
+ .dump_nic_error_log = iwl_dump_nic_error_log,
+ .dump_csr = iwl_dump_csr,
+ .dump_fh = iwl_dump_fh,
+ .init_alive_start = iwlagn_init_alive_start,
+ .alive_notify = iwlagn_alive_notify,
+ .send_tx_power = iwlagn_send_tx_power,
+ .update_chain_flags = iwl_update_chain_flags,
+ .set_channel_switch = iwl6000_hw_channel_switch,
+ .apm_ops = {
+ .init = iwl_apm_init,
+ .stop = iwl_apm_stop,
+ .config = iwl6000_nic_config,
+ .set_pwr_src = iwl_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REG_BAND_1_CHANNELS,
+ EEPROM_REG_BAND_2_CHANNELS,
+ EEPROM_REG_BAND_3_CHANNELS,
+ EEPROM_REG_BAND_4_CHANNELS,
+ EEPROM_REG_BAND_5_CHANNELS,
+ EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
+ EEPROM_REG_BAND_52_HT40_CHANNELS
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+ .release_semaphore = iwlcore_eeprom_release_semaphore,
+ .calib_version = iwlagn_eeprom_calib_version,
+ .query_addr = iwlagn_eeprom_query_addr,
+ .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
+ },
+ .post_associate = iwl_post_associate,
+ .isr = iwl_isr_ict,
+ .config_ap = iwl_config_ap,
+ .temp_ops = {
+ .temperature = iwlagn_temperature,
+ .set_ct_kill = iwl6000_set_ct_threshold,
+ .set_calib_version = iwl6000_set_calib_version,
+ },
+ .manage_ibss_station = iwlagn_manage_ibss_station,
+ .update_bcast_stations = iwl_update_bcast_stations,
+ .debugfs_ops = {
+ .rx_stats_read = iwl_ucode_rx_stats_read,
+ .tx_stats_read = iwl_ucode_tx_stats_read,
+ .general_stats_read = iwl_ucode_general_stats_read,
+ .bt_stats_read = iwl_ucode_bt_stats_read,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ .check_plcp_health = iwl_good_plcp_health,
+ .check_ack_health = iwl_good_ack_health,
+ .txfifo_flush = iwlagn_txfifo_flush,
+ .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
+ .tt_ops = {
+ .lower_power_detection = iwl_tt_is_low_power_state,
+ .tt_power_mode = iwl_tt_current_power_mode,
+ .ct_kill_check = iwl_check_for_ct_kill,
+ }
};
static const struct iwl_ops iwl6000_ops = {
@@ -339,21 +424,9 @@ static const struct iwl_ops iwl6000_ops = {
.led = &iwlagn_led_ops,
};
-static void do_not_send_bt_config(struct iwl_priv *priv)
-{
-}
-
-static struct iwl_hcmd_ops iwl6000g2b_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
- .commit_rxon = iwl_commit_rxon,
- .set_rxon_chain = iwl_set_rxon_chain,
- .set_tx_ant = iwlagn_send_tx_ant_config,
- .send_bt_config = do_not_send_bt_config,
-};
-
static const struct iwl_ops iwl6000g2b_ops = {
- .lib = &iwl6000_lib,
- .hcmd = &iwl6000g2b_hcmd,
+ .lib = &iwl6000g2b_lib,
+ .hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
};
@@ -494,7 +567,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -502,6 +575,11 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -530,7 +608,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -538,6 +616,11 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -568,7 +651,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -576,6 +659,11 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -604,7 +692,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -612,6 +700,11 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -642,7 +735,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -650,6 +743,11 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -678,7 +776,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
.supports_idle = true,
.adv_thermal_throttle = true,
.support_ct_kill_exit = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_LONG_MONITORING_PERIOD,
.max_event_log_size = 512,
@@ -686,6 +784,11 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
.chain_noise_calib_by_driver = true,
.need_dc_calib = true,
.bt_statistics = true,
+ /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+ .advanced_bt_coexist = true,
+ .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+ .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
};
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index c4c5691032a6..84ad62958535 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -625,7 +625,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
data = &(priv->sensitivity_data);
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_any_associated(priv)) {
IWL_DEBUG_CALIB(priv, "<< - not associated\n");
return;
}
@@ -763,6 +763,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
unsigned long flags;
struct statistics_rx_non_phy *rx_info;
u8 first_chain;
+ /*
+ * MULTI-FIXME:
+ * When we support multiple interfaces on different channels,
+ * this must be modified/fixed.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (priv->disable_chain_noise_cal)
return;
@@ -793,8 +799,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
return;
}
- rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
- rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
+ rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
+ rxon_chnum = le16_to_cpu(ctx->staging.channel);
if (priv->cfg->bt_statistics) {
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
stat_resp)->flag &
@@ -914,7 +920,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
* To be safe, simply mask out any chains that we know
* are not on the device.
*/
- active_chains &= priv->hw_params.valid_rx_ant;
+ if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ active_chains &= first_antenna(priv->hw_params.valid_rx_ant);
+ } else
+ active_chains &= priv->hw_params.valid_rx_ant;
num_tx_chains = 0;
for (i = 0; i < NUM_RX_CHAINS; i++) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 75b901b3eb1e..d86902b83630 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,12 +37,13 @@
#include "iwl-io.h"
#include "iwl-agn.h"
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
+int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int ret = 0;
struct iwl5000_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
@@ -60,23 +61,23 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
rxon_assoc.reserved1 = 0;
rxon_assoc.reserved2 = 0;
rxon_assoc.reserved3 = 0;
rxon_assoc.ofdm_ht_single_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
rxon_assoc.ofdm_ht_triple_stream_basic_rates =
- priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
- rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
+ ctx->staging.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
- ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
+ ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
sizeof(rxon_assoc), &rxon_assoc, NULL);
if (ret)
return ret;
@@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
int ret;
if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
- iwl_is_associated(priv)) {
+ iwl_is_any_associated(priv)) {
struct iwl_calib_chain_noise_reset_cmd cmd;
/* clear data for chain noise calibration algorithm */
@@ -235,13 +236,13 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
/* data from PHY/DSP regarding signal strength, etc.,
* contents are always there, not configurable by host
*/
- struct iwl5000_non_cfg_phy *ncphy =
- (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
+ struct iwlagn_non_cfg_phy *ncphy =
+ (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
u8 agc;
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
- agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]);
+ agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS;
/* Find max rssi among 3 possible receivers.
* These values are measured by the digital signal processor (DSP).
@@ -249,11 +250,14 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
* if the radio's automatic gain control (AGC) is working right.
* AGC value (see below) will provide the "interesting" info.
*/
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
- rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
- rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
- val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
- rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]);
+ rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >>
+ IWLAGN_OFDM_RSSI_A_BIT_POS;
+ rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >>
+ IWLAGN_OFDM_RSSI_B_BIT_POS;
+ val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]);
+ rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >>
+ IWLAGN_OFDM_RSSI_C_BIT_POS;
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
@@ -266,12 +270,109 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
return max_rssi - agc - IWLAGN_RSSI_OFFSET;
}
+static int iwlagn_set_pan_params(struct iwl_priv *priv)
+{
+ struct iwl_wipan_params_cmd cmd;
+ struct iwl_rxon_context *ctx_bss, *ctx_pan;
+ int slot0 = 300, slot1 = 0;
+ int ret;
+
+ if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
+ return 0;
+
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+ lockdep_assert_held(&priv->mutex);
+
+ ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
+ ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
+
+ /*
+ * If the PAN context is inactive, then we don't need
+ * to update the PAN parameters, the last thing we'll
+ * have done before it goes inactive is making the PAN
+ * parameters be WLAN-only.
+ */
+ if (!ctx_pan->is_active)
+ return 0;
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ /* only 2 slots are currently allowed */
+ cmd.num_slots = 2;
+
+ cmd.slots[0].type = 0; /* BSS */
+ cmd.slots[1].type = 1; /* PAN */
+
+ if (ctx_bss->vif && ctx_pan->vif) {
+ int bcnint = ctx_pan->vif->bss_conf.beacon_int;
+
+ /* should be set, but seems unused?? */
+ cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
+
+ if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
+ bcnint &&
+ bcnint != ctx_bss->vif->bss_conf.beacon_int) {
+ IWL_ERR(priv,
+ "beacon intervals don't match (%d, %d)\n",
+ ctx_bss->vif->bss_conf.beacon_int,
+ ctx_pan->vif->bss_conf.beacon_int);
+ } else
+ bcnint = max_t(int, bcnint,
+ ctx_bss->vif->bss_conf.beacon_int);
+ if (!bcnint)
+ bcnint = DEFAULT_BEACON_INTERVAL;
+ slot0 = bcnint / 2;
+ slot1 = bcnint - slot0;
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status) ||
+ (!ctx_bss->vif->bss_conf.idle &&
+ !ctx_bss->vif->bss_conf.assoc)) {
+ slot0 = bcnint * 3 - 20;
+ slot1 = 20;
+ } else if (!ctx_pan->vif->bss_conf.idle &&
+ !ctx_pan->vif->bss_conf.assoc) {
+ slot1 = bcnint * 3 - 20;
+ slot0 = 20;
+ }
+ } else if (ctx_pan->vif) {
+ slot0 = 0;
+ slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
+ ctx_pan->vif->bss_conf.beacon_int;
+ slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ slot0 = slot1 * 3 - 20;
+ slot1 = 20;
+ }
+ }
+
+ cmd.slots[0].width = cpu_to_le16(slot0);
+ cmd.slots[1].width = cpu_to_le16(slot1);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
+
+ return ret;
+}
+
struct iwl_hcmd_ops iwlagn_hcmd = {
.rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwl_commit_rxon,
.set_rxon_chain = iwl_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
.send_bt_config = iwl_send_bt_config,
+ .set_pan_params = iwlagn_set_pan_params,
+};
+
+struct iwl_hcmd_ops iwlagn_bt_hcmd = {
+ .rxon_assoc = iwlagn_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
+ .set_tx_ant = iwlagn_send_tx_ant_config,
+ .send_bt_config = iwlagn_send_advance_bt_config,
+ .set_pan_params = iwlagn_set_pan_params,
};
struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 9dd9e64c2b0b..12170cfcff4e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -46,6 +46,28 @@ static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
tx_resp->frame_count) & MAX_SN;
}
+static void iwlagn_set_tx_status(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ struct iwl5000_tx_resp *tx_resp,
+ int txq_id, bool is_agg)
+{
+ u16 status = le16_to_cpu(tx_resp->status.status);
+
+ info->status.rates[0].count = tx_resp->failure_frame + 1;
+ if (is_agg)
+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+ info->flags |= iwl_tx_status_to_mac80211(status);
+ iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n",
+ txq_id,
+ iwl_get_tx_fail_reason(status), status,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+}
+
static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
struct iwl5000_tx_resp *tx_resp,
@@ -53,9 +75,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
{
u16 status;
struct agg_tx_status *frame_status = &tx_resp->status;
- struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
- u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
@@ -64,31 +84,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
- agg->rate_n_flags = rate_n_flags;
+ agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
agg->bitmap = 0;
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
- status = le16_to_cpu(frame_status[0].status);
idx = start_idx;
- /* FIXME: code repetition */
IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
-
- info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb);
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags &= ~IEEE80211_TX_CTL_AMPDU;
- info->flags |= iwl_tx_status_to_mac80211(status);
- iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
-
- /* FIXME: code repetition end */
-
- IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
- status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
-
+ iwlagn_set_tx_status(priv,
+ IEEE80211_SKB_CB(
+ priv->txq[txq_id].txb[idx].skb),
+ tx_resp, txq_id, true);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
@@ -247,7 +256,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg;
agg = &priv->stations[sta_id].tid[tid].agg;
-
+ /*
+ * If the BT kill count is non-zero, we'll get this
+ * notification again.
+ */
+ if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
+ priv->cfg->advanced_bt_coexist) {
+ IWL_WARN(priv, "receive reply tx with bt_kill\n");
+ }
iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
/* check if BAR is needed */
@@ -274,20 +290,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
}
} else {
BUG_ON(txq_id != txq->swq_id);
-
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags |= iwl_tx_status_to_mac80211(status);
- iwlagn_hwrate_to_tx_control(priv,
- le32_to_cpu(tx_resp->rate_n_flags),
- info);
-
- IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
- "0x%x retries %d\n",
- txq_id,
- iwl_get_tx_fail_reason(status), status,
- le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
+ iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
@@ -1098,7 +1101,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
if (chan->band != band)
continue;
- channel = ieee80211_frequency_to_channel(chan->center_freq);
+ channel = chan->hw_value;
scan_ch->channel = cpu_to_le16(channel);
ch_info = iwl_get_channel_info(priv, band, channel);
@@ -1147,7 +1150,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -1155,7 +1158,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
.flags = CMD_SIZE_HUGE,
};
struct iwl_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u32 rate_flags = 0;
u16 cmd_len;
u16 rx_chain = 0;
@@ -1167,48 +1170,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
int chan_mod;
u8 active_chains;
u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
+ int ret;
- conf = ieee80211_get_hw_conf(priv->hw);
-
- cancel_delayed_work(&priv->scan_check);
-
- if (!iwl_is_ready(priv)) {
- IWL_WARN(priv, "request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't canceled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
- goto done;
- }
+ lockdep_assert_held(&priv->mutex);
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
- goto done;
- }
+ if (vif)
+ ctx = iwl_rxon_ctx_from_vif(vif);
if (!priv->scan_cmd) {
priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
@@ -1216,7 +1183,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv,
"fail to allocate memory for scan\n");
- goto done;
+ return -ENOMEM;
}
}
scan = priv->scan_cmd;
@@ -1225,7 +1192,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
@@ -1276,13 +1243,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.sta_id = ctx->bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
switch (priv->scan_band) {
case IEEE80211_BAND_2GHZ:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
+ chan_mod = le32_to_cpu(
+ priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+ RXON_FLG_CHANNEL_MODE_MSK)
>> RXON_FLG_CHANNEL_MODE_POS;
if (chan_mod == CHANNEL_MODE_PURE_40) {
rate = IWL_RATE_6M_PLCP;
@@ -1290,6 +1259,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
rate = IWL_RATE_1M_PLCP;
rate_flags = RATE_MCS_CCK_MSK;
}
+ /*
+ * Internal scans are passive, so we can indiscriminately set
+ * the BT ignore flag on 2.4 GHz since it applies to TX only.
+ */
+ if (priv->cfg->advanced_bt_coexist)
+ scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
break;
case IEEE80211_BAND_5GHZ:
@@ -1315,8 +1290,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_GOOD_CRC_TH_NEVER;
break;
default:
- IWL_WARN(priv, "Invalid scan band count\n");
- goto done;
+ IWL_WARN(priv, "Invalid scan band\n");
+ return -EIO;
}
band = priv->scan_band;
@@ -1327,6 +1302,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (priv->cfg->scan_tx_antennas[band])
scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
+ if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ scan_tx_antennas =
+ first_antenna(priv->cfg->scan_tx_antennas[band]);
+ }
+
priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
scan_tx_antennas);
rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
@@ -1345,6 +1326,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
rx_ant = first_antenna(active_chains);
}
+ if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ rx_ant = first_antenna(rx_ant);
+ }
+
/* MIMO is not used here, but value is required */
rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -1385,7 +1371,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
}
if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
- goto done;
+ return -EIO;
}
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -1393,25 +1379,21 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
cmd.data = scan;
scan->len = cpu_to_le16(cmd.len);
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
+
set_bit(STATUS_SCAN_HW, &priv->status);
- if (iwl_send_cmd_sync(priv, &cmd))
- goto done;
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret) {
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
+ }
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
-
- return;
-
- done:
- /* Cannot perform scan. Make sure we clear scanning
- * bits from status so next scan request can be performed.
- * If we don't clear scanning status bit here all next scan
- * will fail
- */
- clear_bit(STATUS_SCAN_HW, &priv->status);
- clear_bit(STATUS_SCANNING, &priv->status);
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ return ret;
}
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
@@ -1420,7 +1402,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
if (add)
- return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true,
+ return iwl_add_bssid_station(priv, vif_priv->ctx,
+ vif->bss_conf.bssid, true,
&vif_priv->ibss_bssid_sta_id);
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
@@ -1453,7 +1436,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
/* waiting for all the tx frames complete might take a while */
for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
- if (cnt == IWL_CMD_QUEUE_NUM)
+ if (cnt == priv->cmd_queue)
continue;
txq = &priv->txq[cnt];
q = &txq->q;
@@ -1518,3 +1501,377 @@ done:
ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex);
}
+
+/*
+ * BT coex
+ */
+/*
+ * Macros to access the lookup table.
+ *
+ * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
+* wifi_prio, wifi_txrx and wifi_sh_ant_req.
+ *
+ * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
+ *
+ * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
+ * one after another in 32-bit registers, and "registers" 0 through 7 contain
+ * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
+ *
+ * These macros encode that format.
+ */
+#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
+ wifi_txrx, wifi_sh_ant_req) \
+ (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
+ (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
+
+#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
+ lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
+#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))))
+#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))
+#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req) \
+ LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
+ bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))
+
+#define LUT_WLAN_KILL_OP(lut, op, val) \
+ lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
+#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
+#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+
+#define LUT_ANT_SWITCH_OP(lut, op, val) \
+ lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
+#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, \
+ wifi_sh_ant_req))))
+#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
+ wifi_prio, wifi_txrx, wifi_sh_ant_req) \
+ LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
+ wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
+
+static const __le32 iwlagn_def_3w_lookup[12] = {
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaeaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xcc00ff28),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xcc00aaaa),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0x00004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0004000),
+};
+
+static const __le32 iwlagn_concurrent_lookup[12] = {
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+};
+
+void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
+{
+ struct iwlagn_bt_cmd bt_cmd = {
+ .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT,
+ .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT,
+ .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
+ .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
+ };
+
+ BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
+ sizeof(bt_cmd.bt3_lookup_table));
+
+ bt_cmd.prio_boost = priv->cfg->bt_prio_boost;
+ bt_cmd.kill_ack_mask = priv->kill_ack_mask;
+ bt_cmd.kill_cts_mask = priv->kill_cts_mask;
+ bt_cmd.valid = priv->bt_valid;
+
+ /*
+ * Configure BT coex mode to "no coexistence" when the
+ * user disabled BT coexistence, we have no interface
+ * (might be in monitor mode), or the interface is in
+ * IBSS mode (no proper uCode support for coex then).
+ */
+ if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
+ bt_cmd.flags = 0;
+ } else {
+ bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
+ IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
+ if (priv->bt_ch_announce)
+ bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
+ IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
+ }
+ if (priv->bt_full_concurrent)
+ memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
+ sizeof(iwlagn_concurrent_lookup));
+ else
+ memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup,
+ sizeof(iwlagn_def_3w_lookup));
+
+ IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n",
+ bt_cmd.flags ? "active" : "disabled",
+ priv->bt_full_concurrent ?
+ "full concurrency" : "3-wire");
+
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd))
+ IWL_ERR(priv, "failed to send BT Coex Config\n");
+
+ /*
+ * When we are doing a restart, need to also reconfigure BT
+ * SCO to the device. If not doing a restart, bt_sco_active
+ * will always be false, so there's no need to have an extra
+ * variable to check for it.
+ */
+ if (priv->bt_sco_active) {
+ struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
+
+ if (priv->bt_sco_active)
+ sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO,
+ sizeof(sco_cmd), &sco_cmd))
+ IWL_ERR(priv, "failed to send BT SCO command\n");
+ }
+}
+
+static void iwlagn_bt_traffic_change_work(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_traffic_change_work);
+ struct iwl_rxon_context *ctx;
+ int smps_request = -1;
+
+ IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
+ priv->bt_traffic_load);
+
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ smps_request = IEEE80211_SMPS_AUTOMATIC;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ smps_request = IEEE80211_SMPS_DYNAMIC;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ smps_request = IEEE80211_SMPS_STATIC;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT traffic load: %d\n",
+ priv->bt_traffic_load);
+ break;
+ }
+
+ mutex_lock(&priv->mutex);
+
+ if (priv->cfg->ops->lib->update_chain_flags)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+
+ if (smps_request != -1) {
+ for_each_context(priv, ctx) {
+ if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
+ ieee80211_request_smps(ctx->vif, smps_request);
+ }
+ }
+
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwlagn_print_uartmsg(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
+{
+ IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
+ "Update Req = 0x%X",
+ (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1MSGTYPE_POS,
+ (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1SSN_POS,
+ (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
+ BT_UART_MSG_FRAME1UPDATEREQ_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
+ "Chl_SeqN = 0x%X, In band = 0x%X",
+ (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
+ (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
+ (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2CHLSEQN_POS,
+ (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
+ BT_UART_MSG_FRAME2INBAND_POS);
+
+ IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
+ "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
+ (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3SCOESCO_POS,
+ (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3SNIFF_POS,
+ (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3A2DP_POS,
+ (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3ACL_POS,
+ (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3MASTER_POS,
+ (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
+ BT_UART_MSG_FRAME3OBEX_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X",
+ (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
+ BT_UART_MSG_FRAME4IDLEDURATION_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
+ "eSCO Retransmissions = 0x%X",
+ (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5TXACTIVITY_POS,
+ (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5RXACTIVITY_POS,
+ (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
+ BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
+ (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
+ BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
+ (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
+ BT_UART_MSG_FRAME6DISCOVERABLE_POS);
+
+ IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = "
+ "0x%X, Connectable = 0x%X",
+ (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
+ (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS,
+ (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
+ BT_UART_MSG_FRAME7CONNECTABLE_POS);
+}
+
+static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
+ struct iwl_bt_uart_msg *uart_msg)
+{
+ u8 kill_ack_msk;
+ __le32 bt_kill_ack_msg[2] = {
+ cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
+
+ kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
+ BT_UART_MSG_FRAME3SNIFF_MSK |
+ BT_UART_MSG_FRAME3SCOESCO_MSK) &
+ uart_msg->frame3) == 0) ? 1 : 0;
+ if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
+ priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
+ priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
+ /* schedule to send runtime bt_config */
+ queue_work(priv->workqueue, &priv->bt_runtime_config);
+ }
+
+}
+
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ unsigned long flags;
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
+ struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
+ struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
+ u8 last_traffic_load;
+
+ IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
+ IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
+ IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);
+ IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n",
+ coex->bt_ci_compliance);
+ iwlagn_print_uartmsg(priv, uart_msg);
+
+ last_traffic_load = priv->notif_bt_traffic_load;
+ priv->notif_bt_traffic_load = coex->bt_traffic_load;
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+ if (priv->bt_status != coex->bt_status ||
+ last_traffic_load != coex->bt_traffic_load) {
+ if (coex->bt_status) {
+ /* BT on */
+ if (!priv->bt_ch_announce)
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ else
+ priv->bt_traffic_load =
+ coex->bt_traffic_load;
+ } else {
+ /* BT off */
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE;
+ }
+ priv->bt_status = coex->bt_status;
+ queue_work(priv->workqueue,
+ &priv->bt_traffic_change_work);
+ }
+ if (priv->bt_sco_active !=
+ (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
+ priv->bt_sco_active = uart_msg->frame3 &
+ BT_UART_MSG_FRAME3SCOESCO_MSK;
+ if (priv->bt_sco_active)
+ sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
+ iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO,
+ sizeof(sco_cmd), &sco_cmd, NULL);
+ }
+ }
+
+ iwlagn_set_kill_ack_msk(priv, uart_msg);
+
+ /* FIXME: based on notification, adjust the prio_boost */
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->bt_ci_compliance = coex->bt_ci_compliance;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
+{
+ iwlagn_rx_handler_setup(priv);
+ priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
+ iwlagn_bt_coex_profile_notif;
+}
+
+void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
+{
+ iwlagn_setup_deferred_work(priv);
+
+ INIT_WORK(&priv->bt_traffic_change_work,
+ iwlagn_bt_traffic_change_work);
+}
+
+void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
+{
+ cancel_work_sync(&priv->bt_traffic_change_work);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 23e5c42e7d7e..4af0ef54a950 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -82,6 +82,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
+static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
#ifdef CONFIG_MAC80211_DEBUGFS
@@ -300,7 +301,19 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
int ret = -EAGAIN;
- u32 load = rs_tl_get_load(lq_data, tid);
+ u32 load;
+
+ /*
+ * Don't create TX aggregation sessions when in high
+ * BT traffic, as they would just be disrupted by BT.
+ */
+ if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {
+ IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n",
+ priv->bt_traffic_load);
+ return ret;
+ }
+
+ load = rs_tl_get_load(lq_data, tid);
if (load > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
@@ -502,6 +515,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
u8 mcs;
+ memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));
*rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
if (*rate_idx == IWL_RATE_INVALID) {
@@ -588,11 +602,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
* Green-field mode is valid if the station supports it and
* there are no non-GF stations present in the BSS.
*/
-static inline u8 rs_use_green(struct ieee80211_sta *sta,
- struct iwl_ht_config *ht_conf)
+static bool rs_use_green(struct ieee80211_sta *sta)
{
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+
return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
- !(ht_conf->non_GF_STA_present);
+ !(ctx->ht.non_gf_sta_present);
}
/**
@@ -744,6 +760,32 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
(a->is_SGI == b->is_SGI);
}
+static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct iwl_lq_sta *lq_sta)
+{
+ struct iwl_scale_tbl_info *tbl;
+ bool full_concurrent;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
+ full_concurrent = true;
+ else
+ full_concurrent = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (priv->bt_full_concurrent != full_concurrent) {
+ priv->bt_full_concurrent = full_concurrent;
+
+ /* Update uCode's rate table. */
+ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
+
+ queue_work(priv->workqueue, &priv->bt_full_concurrency);
+ }
+}
+
/*
* mac80211 sends us Tx status
*/
@@ -763,6 +805,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
u32 tx_rate;
struct iwl_scale_tbl_info tbl_type;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -829,7 +873,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->missed_rate_counter++;
if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
lq_sta->missed_rate_counter = 0;
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
}
/* Regardless, ignore this status info for outdated rate */
return;
@@ -848,7 +892,20 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
} else {
IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
- return;
+ tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+ IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n",
+ tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
+ tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
+ IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n",
+ tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
+ IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n",
+ tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI);
+ /*
+ * no matching table found, let's by-pass the data collection
+ * and continue to perform rate scale to find the rate table
+ */
+ rs_stay_in_table(lq_sta, true);
+ goto done;
}
/*
@@ -909,10 +966,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
}
/* The last TX rate is cached in lq_sta; it's set in if/else above */
lq_sta->last_rate_n_flags = tx_rate;
-
+done:
/* See if there's a better rate or modulation mode to try. */
if (sta && sta->supp_rates[sband->band])
rs_rate_scale_perform(priv, skb, sta, lq_sta);
+
+ /* Is there a need to switch between full concurrency and 3-wire? */
+ if (priv->bt_ant_couple_ok)
+ rs_bt_update_lq(priv, ctx, lq_sta);
}
/*
@@ -1106,6 +1167,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1126,7 +1189,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1160,6 +1223,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1180,7 +1245,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
rate_mask = lq_sta->active_mimo3_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1215,6 +1280,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1227,7 +1294,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->max_search = IWL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate;
- if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1265,18 +1332,52 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
struct iwl_rate_scale_data *window = &(tbl->win[index]);
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0;
u8 update_search_tbl_counter = 0;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
+ tbl->action != IWL_LEGACY_SWITCH_SISO)
+ tbl->action = IWL_LEGACY_SWITCH_SISO;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if (!iwl_ht_enabled(priv))
/* stay in Legacy */
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
tbl->action > IWL_LEGACY_SWITCH_SISO)
tbl->action = IWL_LEGACY_SWITCH_SISO;
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent) {
+ if (!iwl_ht_enabled(priv))
+ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+ else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_LEGACY_SWITCH_SISO;
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
+ start_action = tbl->action;
for (; ;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1291,7 +1392,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
break;
/* Don't change antenna if success has been great */
- if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+ !priv->bt_full_concurrent &&
+ priv->bt_traffic_load ==
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break;
/* Set up search table to try other antenna */
@@ -1403,31 +1507,64 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
/* stay in SISO */
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent) {
+ valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
+ if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
+ tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+ }
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2:
IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
-
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
- tx_chains_num <= 1) ||
+ tx_chains_num <= 1) ||
(tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
- tx_chains_num <= 2))
+ tx_chains_num <= 2))
break;
- if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+ if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+ !priv->bt_full_concurrent &&
+ priv->bt_traffic_load ==
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE)
break;
memcpy(search_tbl, tbl, sz);
@@ -1541,18 +1678,47 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
u8 update_search_tbl_counter = 0;
int ret;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO2_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
(tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO2_SWITCH_SISO_A;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent &&
+ (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
+ tbl->action > IWL_MIMO2_SWITCH_SISO_C))
+ tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1682,18 +1848,47 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
- u8 start_action = tbl->action;
+ u8 start_action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret;
u8 update_search_tbl_counter = 0;
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ /* nothing */
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ /* avoid antenna B and MIMO */
+ if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ /* avoid antenna B unless MIMO */
+ if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
+ tbl->action == IWL_MIMO3_SWITCH_SISO_C)
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+ break;
+ default:
+ IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
+ break;
+ }
+
if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
(tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO3_SWITCH_SISO_A;
}
+
+ /* configure as 1x1 if bt full concurrency */
+ if (priv->bt_full_concurrent &&
+ (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
+ tbl->action > IWL_MIMO3_SWITCH_SISO_C))
+ tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+
+ start_action = tbl->action;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
@@ -1820,7 +2015,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
* 2) # times calling this function
* 3) elapsed time in this mode (not used, for now)
*/
-static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
+static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
{
struct iwl_scale_tbl_info *tbl;
int i;
@@ -1851,7 +2046,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* allow a new search. Also (below) reset all bitmaps and
* stats in active history.
*/
- if ((lq_sta->total_failed > lq_sta->max_failure_limit) ||
+ if (force_search ||
+ (lq_sta->total_failed > lq_sta->max_failure_limit) ||
(lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) {
@@ -1900,6 +2096,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* return rate_n_flags as used in the table
*/
static u32 rs_update_rate_tbl(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct iwl_lq_sta *lq_sta,
struct iwl_scale_tbl_info *tbl,
int index, u8 is_green)
@@ -1909,7 +2106,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
/* Update uCode's rate table. */
rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
rs_fill_link_cmd(priv, lq_sta, rate);
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
return rate;
}
@@ -1948,6 +2145,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
s32 sr;
u8 tid = MAX_TID_COUNT;
struct iwl_tid_data *tid_data;
+ struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
@@ -1986,7 +2185,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (is_legacy(tbl->lq_type))
lq_sta->is_green = 0;
else
- lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
+ lq_sta->is_green = rs_use_green(sta);
is_green = lq_sta->is_green;
/* current tx rate */
@@ -2025,7 +2224,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
/* get "active" rate info */
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
- rate = rs_update_rate_tbl(priv, lq_sta,
+ rate = rs_update_rate_tbl(priv, ctx, lq_sta,
tbl, index, is_green);
}
return;
@@ -2067,7 +2266,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Should we stay with this modulation mode,
* or search for a new one? */
- rs_stay_in_table(lq_sta);
+ rs_stay_in_table(lq_sta, false);
goto out;
}
@@ -2215,6 +2414,28 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
scale_action = -1;
+
+ if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+ (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+ if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
+ /*
+ * don't set scale_action, don't want to scale up if
+ * the rate scale doesn't otherwise think that is a
+ * good idea.
+ */
+ } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
+ scale_action = -1;
+ }
+ }
+ lq_sta->last_bt_traffic = priv->bt_traffic_load;
+
+ if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+ (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+ /* search for a new modulation */
+ rs_stay_in_table(lq_sta, true);
+ goto lq_update;
+ }
+
switch (scale_action) {
case -1:
/* Decrease starting rate, update uCode's rate table */
@@ -2245,13 +2466,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq)
- rate = rs_update_rate_tbl(priv, lq_sta,
+ rate = rs_update_rate_tbl(priv, ctx, lq_sta,
tbl, index, is_green);
if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
/* Should we stay with this modulation mode,
* or search for a new one? */
- rs_stay_in_table(lq_sta);
+ rs_stay_in_table(lq_sta, false);
}
/*
* Search for new modulation mode if we're:
@@ -2287,7 +2508,7 @@ lq_update:
IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
} else
done_search = 1;
}
@@ -2357,12 +2578,17 @@ static void rs_initialize_lq(struct iwl_priv *priv,
int rate_idx;
int i;
u32 rate;
- u8 use_green = rs_use_green(sta, &priv->current_ht_config);
+ u8 use_green = rs_use_green(sta);
u8 active_tbl = 0;
u8 valid_tx_ant;
+ struct iwl_station_priv *sta_priv;
+ struct iwl_rxon_context *ctx;
if (!sta || !lq_sta)
- goto out;
+ return;
+
+ sta_priv = (void *)sta->drv_priv;
+ ctx = sta_priv->common.ctx;
i = lq_sta->last_txrate_idx;
@@ -2394,9 +2620,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_link_cmd(NULL, lq_sta, rate);
priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true);
- out:
- return;
+ iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true);
}
static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
@@ -2524,7 +2748,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
lq_sta->is_dup = 0;
lq_sta->max_rate_idx = -1;
lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
- lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
+ lq_sta->is_green = rs_use_green(sta);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->band = priv->band;
/*
@@ -2594,10 +2818,15 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
/* Interpret new_rate (rate_n_flags) */
- memset(&tbl_type, 0, sizeof(tbl_type));
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
&tbl_type, &rate_idx);
+ if (priv && priv->bt_full_concurrent) {
+ /* 1x1 only */
+ tbl_type.ant_type =
+ first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
/* How many times should we repeat the initial rate? */
if (is_legacy(tbl_type.lq_type)) {
ant_toggle_cnt = 1;
@@ -2622,9 +2851,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
index++;
repeat_rate--;
-
- if (priv)
- valid_tx_ant = priv->hw_params.valid_tx_ant;
+ if (priv) {
+ if (priv->bt_full_concurrent)
+ valid_tx_ant = ANT_A;
+ else
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
+ }
/* Fill rest of rate table */
while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2639,7 +2871,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_toggle_antenna(valid_tx_ant,
&new_rate, &tbl_type))
ant_toggle_cnt = 1;
-}
+ }
/* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2654,6 +2886,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
&rate_idx);
+ if (priv && priv->bt_full_concurrent) {
+ /* 1x1 only */
+ tbl_type.ant_type =
+ first_antenna(priv->hw_params.valid_tx_ant);
+ }
+
/* Indicate to uCode which entries might be MIMO.
* If initial rate was MIMO, this will finally end up
* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
@@ -2694,8 +2932,18 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+
lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+ /*
+ * overwrite if needed, pass aggregation time limit
+ * to uCode in uSec
+ */
+ if (priv && priv->cfg->agg_time_limit &&
+ priv->cfg->agg_time_limit >= LINK_QUAL_AGG_TIME_LIMIT_MIN &&
+ priv->cfg->agg_time_limit <= LINK_QUAL_AGG_TIME_LIMIT_MAX)
+ lq_cmd->agg_params.agg_time_limit =
+ cpu_to_le16(priv->cfg->agg_time_limit);
}
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2760,6 +3008,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
char buf[64];
int buf_size;
u32 parsed_rate;
+ struct iwl_station_priv *sta_priv =
+ container_of(lq_sta, struct iwl_station_priv, lq_sta);
+ struct iwl_rxon_context *ctx = sta_priv->common.ctx;
priv = lq_sta->drv;
memset(buf, 0, sizeof(buf));
@@ -2782,7 +3033,8 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
if (lq_sta->dbg_fixed_rate) {
rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
- iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
+ iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
+ false);
}
return count;
@@ -2873,6 +3125,7 @@ static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
.write = rs_sta_dbgfs_scale_table_write,
.read = rs_sta_dbgfs_scale_table_read,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
@@ -2915,6 +3168,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = rs_sta_dbgfs_stats_table_read,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
@@ -2946,6 +3200,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
.read = rs_sta_dbgfs_rate_scale_data_read,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void rs_add_debugfs(void *priv, void *priv_sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 8292f6d48ec6..357cdb26f16d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -432,6 +432,8 @@ struct iwl_lq_sta {
u32 last_rate_n_flags;
/* packets destined for this STA are aggregated */
u8 is_agg;
+ /* BT traffic this sta was last updated in */
+ u8 last_bt_traffic;
};
static inline u8 num_of_ant(u8 mask)
@@ -451,15 +453,6 @@ static inline u8 first_antenna(u8 mask)
}
-static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
{
u8 rate = iwl3945_rates[rate_index].prev_ieee;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
new file mode 100644
index 000000000000..07b2c6cadf51
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -0,0 +1,704 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-commands.h"
+#include "iwl-debug.h"
+#include "iwl-agn-tt.h"
+
+/* default Thermal Throttling transaction table
+ * Current state | Throttling Down | Throttling Up
+ *=============================================================================
+ * Condition Nxt State Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
+ * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
+ * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
+ * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
+ *=============================================================================
+ */
+static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
+ {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
+ {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
+ {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
+ {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
+ {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
+ {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+
+/* Advance Thermal Throttling default restriction table */
+static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
+ {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
+ {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
+ {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
+ {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
+};
+
+bool iwl_tt_is_low_power_state(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (tt->state >= IWL_TI_1)
+ return true;
+ return false;
+}
+
+u8 iwl_tt_current_power_mode(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ return tt->tt_power_mode;
+}
+
+bool iwl_ht_enabled(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return true;
+ restriction = tt->restriction + tt->state;
+ return restriction->is_ht;
+}
+
+static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
+{
+ s32 temp = priv->temperature; /* degrees CELSIUS except specified */
+ bool within_margin = false;
+
+ if (priv->cfg->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+ if (!priv->thermal_throttle.advanced_tt)
+ within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+ CT_KILL_THRESHOLD_LEGACY) ? true : false;
+ else
+ within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
+ CT_KILL_THRESHOLD) ? true : false;
+ return within_margin;
+}
+
+bool iwl_check_for_ct_kill(struct iwl_priv *priv)
+{
+ bool is_ct_kill = false;
+
+ if (iwl_within_ct_kill_margin(priv)) {
+ iwl_tt_enter_ct_kill(priv);
+ is_ct_kill = true;
+ }
+ return is_ct_kill;
+}
+
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return IWL_ANT_OK_MULTI;
+ restriction = tt->restriction + tt->state;
+ return restriction->tx_stream;
+}
+
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ struct iwl_tt_restriction *restriction;
+
+ if (!priv->thermal_throttle.advanced_tt)
+ return IWL_ANT_OK_MULTI;
+ restriction = tt->restriction + tt->state;
+ return restriction->rx_stream;
+}
+
+#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
+#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */
+
+/*
+ * toggle the bit to wake up uCode and check the temperature
+ * if the temperature is below CT, uCode will stay awake and send card
+ * state notification with CT_KILL bit clear to inform Thermal Throttling
+ * Management to change state. Otherwise, uCode will go back to sleep
+ * without doing anything, driver should continue the 5 seconds timer
+ * to wake up uCode for temperature check until temperature drop below CT
+ */
+static void iwl_tt_check_exit_ct_kill(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ unsigned long flags;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (tt->state == IWL_TI_CT_KILL) {
+ if (priv->thermal_throttle.ct_kill_toggle) {
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ priv->thermal_throttle.ct_kill_toggle = false;
+ } else {
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ priv->thermal_throttle.ct_kill_toggle = true;
+ }
+ iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ if (!iwl_grab_nic_access(priv))
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ /* Reschedule the ct_kill timer to occur in
+ * CT_KILL_EXIT_DURATION seconds to ensure we get a
+ * thermal update */
+ IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
+ mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
+ jiffies + CT_KILL_EXIT_DURATION * HZ);
+ }
+}
+
+static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
+ bool stop)
+{
+ if (stop) {
+ IWL_DEBUG_POWER(priv, "Stop all queues\n");
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
+ IWL_DEBUG_POWER(priv,
+ "Schedule 5 seconds CT_KILL Timer\n");
+ mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
+ jiffies + CT_KILL_EXIT_DURATION * HZ);
+ } else {
+ IWL_DEBUG_POWER(priv, "Wake all queues\n");
+ if (priv->mac80211_registered)
+ ieee80211_wake_queues(priv->hw);
+ }
+}
+
+static void iwl_tt_ready_for_ct_kill(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* temperature timer expired, ready to go into CT_KILL state */
+ if (tt->state != IWL_TI_CT_KILL) {
+ IWL_DEBUG_POWER(priv, "entering CT_KILL state when "
+ "temperature timer expired\n");
+ tt->state = IWL_TI_CT_KILL;
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ }
+}
+
+static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
+{
+ IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
+ /* make request to retrieve statistics information */
+ iwl_send_statistics_request(priv, CMD_SYNC, false);
+ /* Reschedule the ct_kill wait timer */
+ mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
+ jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
+}
+
+#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
+
+/*
+ * Legacy thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ * Chip will identify dangerously high temperatures that can
+ * harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ * Throttle early enough to lower the power consumption before
+ * drastic steps are needed
+ */
+static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ enum iwl_tt_state old_state;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if ((tt->tt_previous_temp) &&
+ (temp > tt->tt_previous_temp) &&
+ ((temp - tt->tt_previous_temp) >
+ IWL_TT_INCREASE_MARGIN)) {
+ IWL_DEBUG_POWER(priv,
+ "Temperature increase %d degree Celsius\n",
+ (temp - tt->tt_previous_temp));
+ }
+#endif
+ old_state = tt->state;
+ /* in Celsius */
+ if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
+ tt->state = IWL_TI_CT_KILL;
+ else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
+ tt->state = IWL_TI_2;
+ else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
+ tt->state = IWL_TI_1;
+ else
+ tt->state = IWL_TI_0;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ tt->tt_previous_temp = temp;
+#endif
+ /* stop ct_kill_waiting_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ if (tt->state != old_state) {
+ switch (tt->state) {
+ case IWL_TI_0:
+ /*
+ * When the system is ready to go back to IWL_TI_0
+ * we only have to call iwl_power_update_mode() to
+ * do so.
+ */
+ break;
+ case IWL_TI_1:
+ tt->tt_power_mode = IWL_POWER_INDEX_3;
+ break;
+ case IWL_TI_2:
+ tt->tt_power_mode = IWL_POWER_INDEX_4;
+ break;
+ default:
+ tt->tt_power_mode = IWL_POWER_INDEX_5;
+ break;
+ }
+ mutex_lock(&priv->mutex);
+ if (old_state == IWL_TI_CT_KILL)
+ clear_bit(STATUS_CT_KILL, &priv->status);
+ if (tt->state != IWL_TI_CT_KILL &&
+ iwl_power_update_mode(priv, true)) {
+ /* TT state not updated
+ * try again during next temperature read
+ */
+ if (old_state == IWL_TI_CT_KILL)
+ set_bit(STATUS_CT_KILL, &priv->status);
+ tt->state = old_state;
+ IWL_ERR(priv, "Cannot update power mode, "
+ "TT state not updated\n");
+ } else {
+ if (tt->state == IWL_TI_CT_KILL) {
+ if (force) {
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ } else {
+ iwl_prepare_ct_kill_task(priv);
+ tt->state = old_state;
+ }
+ } else if (old_state == IWL_TI_CT_KILL &&
+ tt->state != IWL_TI_CT_KILL)
+ iwl_perform_ct_kill_task(priv, false);
+ IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
+ tt->state);
+ IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
+ tt->tt_power_mode);
+ }
+ mutex_unlock(&priv->mutex);
+ }
+}
+
+/*
+ * Advance thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ * Chip will identify dangerously high temperatures that can
+ * harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ * Throttle early enough to lower the power consumption before
+ * drastic steps are needed
+ * Actions include relaxing the power down sleep thresholds and
+ * decreasing the number of TX streams
+ * 3) Avoid throughput performance impact as much as possible
+ *
+ *=============================================================================
+ * Condition Nxt State Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
+ * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
+ * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
+ * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
+ *=============================================================================
+ */
+static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ int i;
+ bool changed = false;
+ enum iwl_tt_state old_state;
+ struct iwl_tt_trans *transaction;
+
+ old_state = tt->state;
+ for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
+ /* based on the current TT state,
+ * find the curresponding transaction table
+ * each table has (IWL_TI_STATE_MAX - 1) entries
+ * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
+ * will advance to the correct table.
+ * then based on the current temperature
+ * find the next state need to transaction to
+ * go through all the possible (IWL_TI_STATE_MAX - 1) entries
+ * in the current table to see if transaction is needed
+ */
+ transaction = tt->transaction +
+ ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
+ if (temp >= transaction->tt_low &&
+ temp <= transaction->tt_high) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if ((tt->tt_previous_temp) &&
+ (temp > tt->tt_previous_temp) &&
+ ((temp - tt->tt_previous_temp) >
+ IWL_TT_INCREASE_MARGIN)) {
+ IWL_DEBUG_POWER(priv,
+ "Temperature increase %d "
+ "degree Celsius\n",
+ (temp - tt->tt_previous_temp));
+ }
+ tt->tt_previous_temp = temp;
+#endif
+ if (old_state !=
+ transaction->next_state) {
+ changed = true;
+ tt->state =
+ transaction->next_state;
+ }
+ break;
+ }
+ }
+ /* stop ct_kill_waiting_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ if (changed) {
+ if (tt->state >= IWL_TI_1) {
+ /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
+ tt->tt_power_mode = IWL_POWER_INDEX_5;
+
+ if (!iwl_ht_enabled(priv)) {
+ struct iwl_rxon_context *ctx;
+
+ for_each_context(priv, ctx) {
+ struct iwl_rxon_cmd *rxon;
+
+ rxon = &ctx->staging;
+
+ /* disable HT */
+ rxon->flags &= ~(
+ RXON_FLG_CHANNEL_MODE_MSK |
+ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
+ RXON_FLG_HT40_PROT_MSK |
+ RXON_FLG_HT_PROT_MSK);
+ }
+ } else {
+ /* check HT capability and set
+ * according to the system HT capability
+ * in case get disabled before */
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+
+ } else {
+ /*
+ * restore system power setting -- it will be
+ * recalculated automatically.
+ */
+
+ /* check HT capability and set
+ * according to the system HT capability
+ * in case get disabled before */
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ }
+ mutex_lock(&priv->mutex);
+ if (old_state == IWL_TI_CT_KILL)
+ clear_bit(STATUS_CT_KILL, &priv->status);
+ if (tt->state != IWL_TI_CT_KILL &&
+ iwl_power_update_mode(priv, true)) {
+ /* TT state not updated
+ * try again during next temperature read
+ */
+ IWL_ERR(priv, "Cannot update power mode, "
+ "TT state not updated\n");
+ if (old_state == IWL_TI_CT_KILL)
+ set_bit(STATUS_CT_KILL, &priv->status);
+ tt->state = old_state;
+ } else {
+ IWL_DEBUG_POWER(priv,
+ "Thermal Throttling to new state: %u\n",
+ tt->state);
+ if (old_state != IWL_TI_CT_KILL &&
+ tt->state == IWL_TI_CT_KILL) {
+ if (force) {
+ IWL_DEBUG_POWER(priv,
+ "Enter IWL_TI_CT_KILL\n");
+ set_bit(STATUS_CT_KILL, &priv->status);
+ iwl_perform_ct_kill_task(priv, true);
+ } else {
+ iwl_prepare_ct_kill_task(priv);
+ tt->state = old_state;
+ }
+ } else if (old_state == IWL_TI_CT_KILL &&
+ tt->state != IWL_TI_CT_KILL) {
+ IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
+ iwl_perform_ct_kill_task(priv, false);
+ }
+ }
+ mutex_unlock(&priv->mutex);
+ }
+}
+
+/* Card State Notification indicated reach critical temperature
+ * if PSP not enable, no Thermal Throttling function will be performed
+ * just set the GP1 bit to acknowledge the event
+ * otherwise, go into IWL_TI_CT_KILL state
+ * since Card State Notification will not provide any temperature reading
+ * for Legacy mode
+ * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
+ * for advance mode
+ * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
+ */
+static void iwl_bg_ct_enter(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ if (tt->state != IWL_TI_CT_KILL) {
+ IWL_ERR(priv, "Device reached critical temperature "
+ "- ucode going to sleep!\n");
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv,
+ IWL_MINIMAL_POWER_THRESHOLD,
+ true);
+ else
+ iwl_advance_tt_handler(priv,
+ CT_KILL_THRESHOLD + 1, true);
+ }
+}
+
+/* Card State Notification indicated out of critical temperature
+ * since Card State Notification will not provide any temperature reading
+ * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
+ * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
+ */
+static void iwl_bg_ct_exit(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ /* stop ct_kill_exit_tm timer */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+
+ if (tt->state == IWL_TI_CT_KILL) {
+ IWL_ERR(priv,
+ "Device temperature below critical"
+ "- ucode awake!\n");
+ /*
+ * exit from CT_KILL state
+ * reset the current temperature reading
+ */
+ priv->temperature = 0;
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv,
+ IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
+ true);
+ else
+ iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
+ true);
+ }
+}
+
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
+ queue_work(priv->workqueue, &priv->ct_enter);
+}
+EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
+
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
+ queue_work(priv->workqueue, &priv->ct_exit);
+}
+EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
+
+static void iwl_bg_tt_work(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
+ s32 temp = priv->temperature; /* degrees CELSIUS except specified */
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ if (priv->cfg->temperature_kelvin)
+ temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+ if (!priv->thermal_throttle.advanced_tt)
+ iwl_legacy_tt_handler(priv, temp, false);
+ else
+ iwl_advance_tt_handler(priv, temp, false);
+}
+
+void iwl_tt_handler(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
+ queue_work(priv->workqueue, &priv->tt_work);
+}
+EXPORT_SYMBOL(iwl_tt_handler);
+
+/* Thermal throttling initialization
+ * For advance thermal throttling:
+ * Initialize Thermal Index and temperature threshold table
+ * Initialize thermal throttling restriction table
+ */
+void iwl_tt_initialize(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+ int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
+ struct iwl_tt_trans *transaction;
+
+ IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
+
+ memset(tt, 0, sizeof(struct iwl_tt_mgmt));
+
+ tt->state = IWL_TI_0;
+ init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
+ priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
+ priv->thermal_throttle.ct_kill_exit_tm.function =
+ iwl_tt_check_exit_ct_kill;
+ init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
+ priv->thermal_throttle.ct_kill_waiting_tm.data =
+ (unsigned long)priv;
+ priv->thermal_throttle.ct_kill_waiting_tm.function =
+ iwl_tt_ready_for_ct_kill;
+ /* setup deferred ct kill work */
+ INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
+ INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
+ INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
+
+ if (priv->cfg->adv_thermal_throttle) {
+ IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
+ tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
+ IWL_TI_STATE_MAX, GFP_KERNEL);
+ tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
+ IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
+ GFP_KERNEL);
+ if (!tt->restriction || !tt->transaction) {
+ IWL_ERR(priv, "Fallback to Legacy Throttling\n");
+ priv->thermal_throttle.advanced_tt = false;
+ kfree(tt->restriction);
+ tt->restriction = NULL;
+ kfree(tt->transaction);
+ tt->transaction = NULL;
+ } else {
+ transaction = tt->transaction +
+ (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_0[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_1[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_2[0], size);
+ transaction = tt->transaction +
+ (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
+ memcpy(transaction, &tt_range_3[0], size);
+ size = sizeof(struct iwl_tt_restriction) *
+ IWL_TI_STATE_MAX;
+ memcpy(tt->restriction,
+ &restriction_range[0], size);
+ priv->thermal_throttle.advanced_tt = true;
+ }
+ } else {
+ IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
+ priv->thermal_throttle.advanced_tt = false;
+ }
+}
+EXPORT_SYMBOL(iwl_tt_initialize);
+
+/* cleanup thermal throttling management related memory and timer */
+void iwl_tt_exit(struct iwl_priv *priv)
+{
+ struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+ /* stop ct_kill_exit_tm timer if activated */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+ /* stop ct_kill_waiting_tm timer if activated */
+ del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
+ cancel_work_sync(&priv->tt_work);
+ cancel_work_sync(&priv->ct_enter);
+ cancel_work_sync(&priv->ct_exit);
+
+ if (priv->thermal_throttle.advanced_tt) {
+ /* free advance thermal throttling memory */
+ kfree(tt->restriction);
+ tt->restriction = NULL;
+ kfree(tt->transaction);
+ tt->transaction = NULL;
+ }
+}
+EXPORT_SYMBOL(iwl_tt_exit);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
new file mode 100644
index 000000000000..d55060427cac
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+#ifndef __iwl_tt_setting_h__
+#define __iwl_tt_setting_h__
+
+#include "iwl-commands.h"
+
+#define IWL_ABSOLUTE_ZERO 0
+#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
+#define IWL_TT_INCREASE_MARGIN 5
+#define IWL_TT_CT_KILL_MARGIN 3
+
+enum iwl_antenna_ok {
+ IWL_ANT_OK_NONE,
+ IWL_ANT_OK_SINGLE,
+ IWL_ANT_OK_MULTI,
+};
+
+/* Thermal Throttling State Machine states */
+enum iwl_tt_state {
+ IWL_TI_0, /* normal temperature, system power state */
+ IWL_TI_1, /* high temperature detect, low power state */
+ IWL_TI_2, /* higher temperature detected, lower power state */
+ IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
+ IWL_TI_STATE_MAX
+};
+
+/**
+ * struct iwl_tt_restriction - Thermal Throttling restriction table
+ * @tx_stream: number of tx stream allowed
+ * @is_ht: ht enable/disable
+ * @rx_stream: number of rx stream allowed
+ *
+ * This table is used by advance thermal throttling management
+ * based on the current thermal throttling state, and determines
+ * the number of tx/rx streams and the status of HT operation.
+ */
+struct iwl_tt_restriction {
+ enum iwl_antenna_ok tx_stream;
+ enum iwl_antenna_ok rx_stream;
+ bool is_ht;
+};
+
+/**
+ * struct iwl_tt_trans - Thermal Throttling transaction table
+ * @next_state: next thermal throttling mode
+ * @tt_low: low temperature threshold to change state
+ * @tt_high: high temperature threshold to change state
+ *
+ * This is used by the advanced thermal throttling algorithm
+ * to determine the next thermal state to go based on the
+ * current temperature.
+ */
+struct iwl_tt_trans {
+ enum iwl_tt_state next_state;
+ u32 tt_low;
+ u32 tt_high;
+};
+
+/**
+ * struct iwl_tt_mgnt - Thermal Throttling Management structure
+ * @advanced_tt: advanced thermal throttle required
+ * @state: current Thermal Throttling state
+ * @tt_power_mode: Thermal Throttling power mode index
+ * being used to set power level when
+ * when thermal throttling state != IWL_TI_0
+ * the tt_power_mode should set to different
+ * power mode based on the current tt state
+ * @tt_previous_temperature: last measured temperature
+ * @iwl_tt_restriction: ptr to restriction tbl, used by advance
+ * thermal throttling to determine how many tx/rx streams
+ * should be used in tt state; and can HT be enabled or not
+ * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
+ * state transaction
+ * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature
+ * @ct_kill_exit_tm: timer to exit thermal kill
+ */
+struct iwl_tt_mgmt {
+ enum iwl_tt_state state;
+ bool advanced_tt;
+ u8 tt_power_mode;
+ bool ct_kill_toggle;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ s32 tt_previous_temp;
+#endif
+ struct iwl_tt_restriction *restriction;
+ struct iwl_tt_trans *transaction;
+ struct timer_list ct_kill_exit_tm;
+ struct timer_list ct_kill_waiting_tm;
+};
+
+u8 iwl_tt_current_power_mode(struct iwl_priv *priv);
+bool iwl_tt_is_low_power_state(struct iwl_priv *priv);
+bool iwl_ht_enabled(struct iwl_priv *priv);
+bool iwl_check_for_ct_kill(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
+void iwl_tt_handler(struct iwl_priv *priv);
+void iwl_tt_initialize(struct iwl_priv *priv);
+void iwl_tt_exit(struct iwl_priv *priv);
+
+#endif /* __iwl_tt_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 69155aa448fb..5950184d9860 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
2, 3, 3, 2, 1, 1, 0, 0
};
-static const u8 ac_to_fifo[] = {
- IWL_TX_FIFO_VO,
- IWL_TX_FIFO_VI,
- IWL_TX_FIFO_BE,
- IWL_TX_FIFO_BK,
-};
-
-static inline int get_fifo_from_ac(u8 ac)
-{
- return ac_to_fifo[ac];
-}
-
static inline int get_ac_from_tid(u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
@@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
return -EINVAL;
}
-static inline int get_fifo_from_tid(u16 tid)
+static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
{
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
- return get_fifo_from_ac(tid_to_ac[tid]);
+ return ctx->ac_to_fifo[tid_to_ac[tid]];
/* no support for TIDs 8-15 yet */
return -EINVAL;
@@ -118,7 +106,7 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != IWL_CMD_QUEUE_NUM) {
+ if (txq_id != priv->cmd_queue) {
sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
@@ -155,7 +143,7 @@ void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
- if (txq_id != IWL_CMD_QUEUE_NUM)
+ if (txq_id != priv->cmd_queue)
sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
bc_ent = cpu_to_le16(1 | (sta_id << 12));
@@ -333,19 +321,15 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
}
-static inline int get_queue_from_ac(u16 ac)
-{
- return ac;
-}
-
/*
* handle build REPLY_TX command notification.
*/
static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
- struct iwl_tx_cmd *tx_cmd,
- struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- u8 std_id)
+ struct sk_buff *skb,
+ struct iwl_tx_cmd *tx_cmd,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_hdr *hdr,
+ u8 std_id)
{
__le16 fc = hdr->frame_control;
__le32 tx_flags = tx_cmd->tx_flags;
@@ -365,6 +349,12 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
if (ieee80211_is_back_req(fc))
tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
+ else if (info->band == IEEE80211_BAND_2GHZ &&
+ priv->cfg->advanced_bt_coexist &&
+ (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
+ ieee80211_is_reassoc_req(fc) ||
+ skb->protocol == cpu_to_be16(ETH_P_PAE)))
+ tx_flags |= TX_CMD_FLG_IGNORE_BT;
tx_cmd->sta_id = std_id;
@@ -454,7 +444,12 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
rate_flags |= RATE_MCS_CCK_MSK;
/* Set up antennas */
- priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
+ if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
+ /* operated as 1x1 in full concurrency mode */
+ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
+ first_antenna(priv->hw_params.valid_tx_ant));
+ } else
+ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
priv->hw_params.valid_tx_ant);
rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
@@ -470,8 +465,8 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
{
struct ieee80211_key_conf *keyconf = info->control.hw_key;
- switch (keyconf->alg) {
- case ALG_CCMP:
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
@@ -479,20 +474,20 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
ieee80211_get_tkip_key(keyconf, skb_frag,
IEEE80211_TKIP_P2_KEY, tx_cmd->key);
IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
+ /* fall through */
+ case WLAN_CIPHER_SUITE_WEP40:
tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
(keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
- if (keyconf->keylen == WEP_KEY_LEN_128)
- tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
-
memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
@@ -500,7 +495,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
break;
default:
- IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
+ IWL_ERR(priv, "Unknown encode cipher %x\n", keyconf->cipher);
break;
}
}
@@ -519,6 +514,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
struct iwl_tx_cmd *tx_cmd;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int swq_id, txq_id;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
@@ -533,6 +529,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u8 *qc = NULL;
unsigned long flags;
+ if (info->control.vif)
+ ctx = iwl_rxon_ctx_from_vif(info->control.vif);
+
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
@@ -553,7 +552,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -565,8 +564,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (sta)
sta_priv = (void *)sta->drv_priv;
- if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
- sta_priv->asleep) {
+ if (sta_priv && sta_priv->asleep) {
WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
/*
* This sends an asynchronous command to the device,
@@ -580,7 +578,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
}
- txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
+ /*
+ * Send this frame after DTIM -- there's a special queue
+ * reserved for this for contexts that support AP mode.
+ */
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+ txq_id = ctx->mcast_queue;
+ /*
+ * The microcode will clear the more data
+ * bit in the last frame it transmits.
+ */
+ hdr->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ } else
+ txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
/* irqs already disabled/saved above when locking priv->lock */
spin_lock(&priv->sta_lock);
@@ -625,6 +636,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb = skb;
+ txq->txb[q->write_ptr].ctx = ctx;
/* Set up first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[q->write_ptr];
@@ -655,7 +667,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
/* TODO need this for burst mode later on */
- iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+ iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
iwl_dbg_log_tx_data_frame(priv, len, hdr);
iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
@@ -813,7 +825,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
/* Tx queues */
if (priv->txq) {
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
iwl_cmd_queue_free(priv);
else
iwl_tx_queue_free(priv, txq_id);
@@ -870,9 +882,9 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- /* Alloc and init all Tx queues, including the command queue (#4) */
+ /* Alloc and init all Tx queues, including the command queue (#4/#9) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+ slots_num = (txq_id == priv->cmd_queue) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
@@ -910,7 +922,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
/* Alloc and init all Tx queues, including the command queue (#4) */
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+ slots_num = txq_id == priv->cmd_queue ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
}
@@ -968,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
unsigned long flags;
struct iwl_tid_data *tid_data;
- tx_fifo = get_fifo_from_tid(tid);
+ tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo < 0))
return tx_fifo;
@@ -1024,12 +1036,12 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid)
{
- int tx_fifo_id, txq_id, sta_id, ssn = -1;
+ int tx_fifo_id, txq_id, sta_id, ssn;
struct iwl_tid_data *tid_data;
int write_ptr, read_ptr;
unsigned long flags;
- tx_fifo_id = get_fifo_from_tid(tid);
+ tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;
@@ -1042,21 +1054,26 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
spin_lock_irqsave(&priv->sta_lock, flags);
- if (priv->stations[sta_id].tid[tid].agg.state ==
- IWL_EMPTYING_HW_QUEUE_ADDBA) {
- IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
- priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
- }
-
- if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
-
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
txq_id = tid_data->agg.txq_id;
+
+ switch (priv->stations[sta_id].tid[tid].agg.state) {
+ case IWL_EMPTYING_HW_QUEUE_ADDBA:
+ /*
+ * This can happen if the peer stops aggregation
+ * again before we've had a chance to drain the
+ * queue we selected previously, i.e. before the
+ * session was really started completely.
+ */
+ IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
+ goto turn_off;
+ case IWL_AGG_ON:
+ break;
+ default:
+ IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
+ }
+
write_ptr = priv->txq[txq_id].q.write_ptr;
read_ptr = priv->txq[txq_id].q.read_ptr;
@@ -1070,6 +1087,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
}
IWL_DEBUG_HT(priv, "HW queue is empty\n");
+ turn_off:
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
/* do not restore/save irqs */
@@ -1098,6 +1116,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
struct iwl_queue *q = &priv->txq[txq_id].q;
u8 *addr = priv->stations[sta_id].sta.sta.addr;
struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
+ struct iwl_rxon_context *ctx;
+
+ ctx = &priv->contexts[priv->stations[sta_id].ctxid];
lockdep_assert_held(&priv->sta_lock);
@@ -1108,12 +1129,12 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if ((txq_id == tid_data->agg.txq_id) &&
(q->read_ptr == q->write_ptr)) {
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
- int tx_fifo = get_fifo_from_tid(tid);
+ int tx_fifo = get_fifo_from_tid(ctx, tid);
IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF;
- ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
break;
case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1121,7 +1142,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
}
break;
}
@@ -1129,14 +1150,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
return 0;
}
-static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
+static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
struct ieee80211_sta *sta;
struct iwl_station_priv *sta_priv;
rcu_read_lock();
- sta = ieee80211_find_sta(priv->vif, hdr->addr1);
+ sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
@@ -1146,7 +1167,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
}
rcu_read_unlock();
- ieee80211_tx_status_irqsafe(priv->hw, skb);
+ ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
}
int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
@@ -1169,7 +1190,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr];
- iwlagn_tx_status(priv, tx_info->skb);
+ iwlagn_tx_status(priv, tx_info);
hdr = (struct ieee80211_hdr *)tx_info->skb->data;
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 6f77441cb65a..8bfb0495a76b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -52,6 +52,19 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_UNUSED,
};
+static const s8 iwlagn_ipan_queue_to_tx_fifo[] = {
+ IWL_TX_FIFO_VO,
+ IWL_TX_FIFO_VI,
+ IWL_TX_FIFO_BE,
+ IWL_TX_FIFO_BK,
+ IWL_TX_FIFO_BK_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWL_TX_FIFO_VI_IPAN,
+ IWL_TX_FIFO_VO_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWLAGN_CMD_FIFO_NUM,
+};
+
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
0, COEX_UNASSOC_IDLE_FLAGS},
@@ -294,6 +307,17 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
goto restart;
}
+ if (priv->cfg->advanced_bt_coexist) {
+ /*
+ * Tell uCode we are ready to perform calibration
+ * need to perform this before any calibration
+ * no need to close the envlope since we are going
+ * to load the runtime uCode later.
+ */
+ iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+
+ }
iwlagn_send_calib_cfg(priv);
return;
@@ -329,8 +353,54 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
sizeof(coex_cmd), &coex_cmd);
}
+static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
+ (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+void iwlagn_send_prio_tbl(struct iwl_priv *priv)
+{
+ struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
+
+ memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl,
+ sizeof(iwlagn_bt_prio_tbl));
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE,
+ sizeof(prio_tbl_cmd), &prio_tbl_cmd))
+ IWL_ERR(priv, "failed to send BT prio tbl command\n");
+}
+
+void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
+{
+ struct iwl_bt_coex_prot_env_cmd env_cmd;
+
+ env_cmd.action = action;
+ env_cmd.type = type;
+ if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+ sizeof(env_cmd), &env_cmd))
+ IWL_ERR(priv, "failed to send BT env command\n");
+}
+
+
int iwlagn_alive_notify(struct iwl_priv *priv)
{
+ const s8 *queues;
u32 a;
unsigned long flags;
int i, chan;
@@ -365,7 +435,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
- IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
+ IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv));
iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
/* initiate the queues */
@@ -391,7 +461,13 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* Activate all Tx DMA/FIFO channels */
priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
- iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+ /* map queues to FIFOs */
+ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+ queues = iwlagn_ipan_queue_to_tx_fifo;
+ else
+ queues = iwlagn_default_queue_to_tx_fifo;
+
+ iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
/* make sure all queue are not stopped */
memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
@@ -400,11 +476,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
/* reset to 0 to enable all the queue first */
priv->txq_ctx_active_msk = 0;
- /* map qos queues to fifos one-to-one */
+
BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
+ BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
- for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) {
- int ac = iwlagn_default_queue_to_tx_fifo[i];
+ for (i = 0; i < 10; i++) {
+ int ac = queues[i];
iwl_txq_ctx_activate(priv, i);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 10d7b9b7f064..646864a26eaf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -86,6 +87,9 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
MODULE_ALIAS("iwl4965");
+static int iwlagn_ant_coupling;
+static bool iwlagn_bt_ch_announce = 1;
+
/**
* iwl_commit_rxon - commit staging_rxon to hardware
*
@@ -94,21 +98,25 @@ MODULE_ALIAS("iwl4965");
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-int iwl_commit_rxon(struct iwl_priv *priv)
+int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
/* cast away the const for active_rxon in this function */
- struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
int ret;
bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+ !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -EBUSY;
+ if (!ctx->is_active)
+ return 0;
+
/* always get timestamp with Rx frame */
- priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
- ret = iwl_check_rxon_cmd(priv);
+ ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -119,7 +127,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
* abort any previous channel switch if still in process
*/
if (priv->switch_rxon.switch_in_progress &&
- (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
+ (priv->switch_rxon.channel != ctx->staging.channel)) {
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
le16_to_cpu(priv->switch_rxon.channel));
iwl_chswitch_done(priv, false);
@@ -128,15 +136,15 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- ret = iwl_send_rxon_assoc(priv);
+ if (!iwl_full_rxon_required(priv, ctx)) {
+ ret = iwl_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
- iwl_print_rx_config_cmd(priv);
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
@@ -144,13 +152,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl_is_associated(priv) && new_assoc) {
+ if (iwl_is_associated_ctx(ctx) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd),
- &priv->active_rxon);
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd),
+ active_rxon);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
@@ -159,9 +167,9 @@ int iwl_commit_rxon(struct iwl_priv *priv)
IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
- ret = iwl_restore_default_wep_keys(priv);
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
if (ret) {
IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
return ret;
@@ -173,47 +181,65 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"* channel = %d\n"
"* bssid = %pM\n",
(new_assoc ? "" : "out"),
- le16_to_cpu(priv->staging_rxon.channel),
- priv->staging_rxon.bssid_addr);
+ le16_to_cpu(ctx->staging.channel),
+ ctx->staging.bssid_addr);
- iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+
+ if (!old_assoc) {
+ /*
+ * First of all, before setting associated, we need to
+ * send RXON timing so the device knows about the DTIM
+ * period and other timing values
+ */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Error setting RXON timing!\n");
+ return ret;
+ }
+ }
+
+ if (priv->cfg->ops->hcmd->set_pan_params) {
+ ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+ if (ret)
+ return ret;
+ }
/* Apply the new configuration
* RXON unassoc clears the station table in uCode so restoration of
* stations is needed after it (the RXON command) completes
*/
if (!new_assoc) {
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
if (ret) {
IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
- iwl_clear_ucode_stations(priv);
- iwl_restore_stations(priv);
- ret = iwl_restore_default_wep_keys(priv);
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
if (ret) {
IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
return ret;
}
}
-
- priv->start_calib = 0;
if (new_assoc) {
+ priv->start_calib = 0;
/* Apply the new configuration
* RXON assoc doesn't clear the station table in uCode,
*/
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
if (ret) {
IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
}
- iwl_print_rx_config_cmd(priv);
+ iwl_print_rx_config_cmd(priv, ctx);
iwl_init_sensitivity(priv);
@@ -230,10 +256,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
void iwl_update_chain_flags(struct iwl_priv *priv)
{
+ struct iwl_rxon_context *ctx;
- if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
- iwlcore_commit_rxon(priv);
+ if (priv->cfg->ops->hcmd->set_rxon_chain) {
+ for_each_context(priv, ctx) {
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ iwlcore_commit_rxon(priv, ctx);
+ }
+ }
}
static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -337,6 +367,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
* beacon contents.
*/
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
+ return 0;
+ }
+
/* Initialize memory */
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
@@ -349,7 +386,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
/* Set up TX command fields */
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
- tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
@@ -359,7 +396,7 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
frame_size);
/* Set up packet rate and flags */
- rate = iwl_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
priv->hw_params.valid_tx_ant);
rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
@@ -592,23 +629,84 @@ static void iwl_bg_beacon_update(struct work_struct *work)
container_of(work, struct iwl_priv, beacon_update);
struct sk_buff *beacon;
- /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+ mutex_lock(&priv->mutex);
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "updating beacon w/o beacon context!\n");
+ goto out;
+ }
+
+ if (priv->beacon_ctx->vif->type != NL80211_IFTYPE_AP) {
+ /*
+ * The ucode will send beacon notifications even in
+ * IBSS mode, but we don't want to process them. But
+ * we need to defer the type check to here due to
+ * requiring locking around the beacon_ctx access.
+ */
+ goto out;
+ }
+ /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
+ beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
if (!beacon) {
IWL_ERR(priv, "update beacon failed\n");
- return;
+ goto out;
}
- mutex_lock(&priv->mutex);
/* new beacon skb is allocated every time; dispose previous.*/
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
priv->ibss_beacon = beacon;
- mutex_unlock(&priv->mutex);
iwl_send_beacon_cmd(priv);
+ out:
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwl_bg_bt_runtime_config(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_runtime_config);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* dont send host command if rf-kill is on */
+ if (!iwl_is_ready_rf(priv))
+ return;
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+}
+
+static void iwl_bg_bt_full_concurrency(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, bt_full_concurrency);
+ struct iwl_rxon_context *ctx;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ /* dont send host command if rf-kill is on */
+ if (!iwl_is_ready_rf(priv))
+ return;
+
+ IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
+ priv->bt_full_concurrent ?
+ "full concurrency" : "3-wire");
+
+ /*
+ * LQ & RXON updated cmds must be sent before BT Config cmd
+ * to avoid 3-wire collisions
+ */
+ mutex_lock(&priv->mutex);
+ for_each_context(priv, ctx) {
+ if (priv->cfg->ops->hcmd->set_rxon_chain)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+ iwlcore_commit_rxon(priv, ctx);
+ }
+ mutex_unlock(&priv->mutex);
+
+ priv->cfg->ops->hcmd->send_bt_config(priv);
}
/**
@@ -763,10 +861,10 @@ static void iwl_bg_ucode_trace(unsigned long data)
static void iwl_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl4965_beacon_notif *beacon =
(struct iwl4965_beacon_notif *)pkt->u.raw;
+#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
@@ -778,8 +876,9 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate);
#endif
- if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
- (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
+ priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
queue_work(priv->workqueue, &priv->beacon_update);
}
@@ -1181,7 +1280,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1362,7 +1460,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1650,30 +1747,44 @@ static void iwl_nic_start(struct iwl_priv *priv)
struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
+ bool pan;
};
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
static int iwl_mac_setup_register(struct iwl_priv *priv,
struct iwlagn_ucode_capabilities *capa);
+#define UCODE_EXPERIMENTAL_INDEX 100
+#define UCODE_EXPERIMENTAL_TAG "exp"
+
static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
{
const char *name_pre = priv->cfg->fw_name_pre;
+ char tag[8];
- if (first)
+ if (first) {
+#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+ priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+ strcpy(tag, UCODE_EXPERIMENTAL_TAG);
+ } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+#endif
priv->fw_index = priv->cfg->ucode_api_max;
- else
+ sprintf(tag, "%d", priv->fw_index);
+ } else {
priv->fw_index--;
+ sprintf(tag, "%d", priv->fw_index);
+ }
if (priv->fw_index < priv->cfg->ucode_api_min) {
IWL_ERR(priv, "no suitable firmware found!\n");
return -ENOENT;
}
- sprintf(priv->firmware_name, "%s%d%s",
- name_pre, priv->fw_index, ".ucode");
+ sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
- IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
+ IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
+ (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+ ? "EXPERIMENTAL " : "",
priv->firmware_name);
return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
@@ -1874,6 +1985,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
capa->max_probe_length =
le32_to_cpup((__le32 *)tlv_data);
break;
+ case IWL_UCODE_TLV_PAN:
+ if (tlv_len)
+ goto invalid_tlv_len;
+ capa->pan = true;
+ break;
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
if (tlv_len != sizeof(u32))
goto invalid_tlv_len;
@@ -1968,8 +2084,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
memset(&pieces, 0, sizeof(pieces));
if (!ucode_raw) {
- IWL_ERR(priv, "request for firmware file '%s' failed.\n",
- priv->firmware_name);
+ if (priv->fw_index <= priv->cfg->ucode_api_max)
+ IWL_ERR(priv,
+ "request for firmware file '%s' failed.\n",
+ priv->firmware_name);
goto try_again;
}
@@ -2016,7 +2134,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
api_max, api_ver);
if (build)
- sprintf(buildstr, " build %u", build);
+ sprintf(buildstr, " build %u%s", build,
+ (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+ ? " (EXP)" : "");
else
buildstr[0] = '\0';
@@ -2145,6 +2265,12 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
+ if (ucode_capa.pan) {
+ priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
+ priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
+ } else
+ priv->sta_key_max_num = STA_KEY_MAX_NUM;
+
/* Copy images into buffers for card's bus-master reads ... */
/* Runtime instructions (first block of data in file) */
@@ -2341,6 +2467,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
}
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+ priv->isr_stats.err_code = desc;
pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
@@ -2543,6 +2670,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
+ /* enable/disable bt channel announcement */
+ priv->bt_ch_announce = iwlagn_bt_ch_announce;
+
#ifdef CONFIG_IWLWIFI_DEBUG
if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log)
size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
@@ -2589,6 +2719,52 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
return pos;
}
+static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
+{
+ struct iwl_ct_kill_config cmd;
+ struct iwl_ct_kill_throttling_config adv_cmd;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ priv->thermal_throttle.ct_kill_toggle = false;
+
+ if (priv->cfg->support_ct_kill_exit) {
+ adv_cmd.critical_temperature_enter =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);
+ adv_cmd.critical_temperature_exit =
+ cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(adv_cmd), &adv_cmd);
+ if (ret)
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+ "succeeded, "
+ "critical temperature enter is %d,"
+ "exit is %d\n",
+ priv->hw_params.ct_kill_threshold,
+ priv->hw_params.ct_kill_exit_threshold);
+ } else {
+ cmd.critical_temperature_R =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+ "succeeded, "
+ "critical temperature is %d\n",
+ priv->hw_params.ct_kill_threshold);
+ }
+}
+
/**
* iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -2597,6 +2773,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
static void iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
@@ -2637,6 +2814,22 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (iwl_is_rfkill(priv))
return;
+ if (priv->cfg->advanced_bt_coexist) {
+ /* Configure Bluetooth device coexistence support */
+ priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
+ priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
+ priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+ priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
+ if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC)
+ iwlagn_send_prio_tbl(priv);
+
+ /* FIXME: w/a to force change uCode BT state machine */
+ iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+ }
ieee80211_wake_queues(priv->hw);
priv->active_rate = IWL_RATES_MASK;
@@ -2645,27 +2838,31 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_tx_ant)
priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated_ctx(ctx)) {
struct iwl_rxon_cmd *active_rxon =
- (struct iwl_rxon_cmd *)&priv->active_rxon;
+ (struct iwl_rxon_cmd *)&ctx->active;
/* apply any changes in staging */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
+ struct iwl_rxon_context *tmp;
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, NULL);
+ for_each_context(priv, tmp)
+ iwl_connection_init_rx_config(priv, tmp);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
- /* Configure Bluetooth device coexistence support */
- priv->cfg->ops->hcmd->send_bt_config(priv);
+ if (!priv->cfg->advanced_bt_coexist) {
+ /* Configure Bluetooth device coexistence support */
+ priv->cfg->ops->hcmd->send_bt_config(priv);
+ }
iwl_reset_run_time_calib(priv);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
/* At this point, the NIC is initialized and operational */
iwl_rf_kill_ct_config(priv);
@@ -2695,13 +2892,26 @@ static void __iwl_down(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
- if (!exit_pending)
- set_bit(STATUS_EXIT_PENDING, &priv->status);
+ iwl_scan_cancel_timeout(priv, 200);
- iwl_clear_ucode_stations(priv);
- iwl_dealloc_bcast_station(priv);
+ exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
+
+ /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
+ * to prevent rearm timer */
+ if (priv->cfg->ops->lib->recover_from_tx_stall)
+ del_timer_sync(&priv->monitor_recover);
+
+ iwl_clear_ucode_stations(priv, NULL);
+ iwl_dealloc_bcast_stations(priv);
iwl_clear_driver_stations(priv);
+ /* reset BT coex data */
+ priv->bt_status = 0;
+ priv->bt_traffic_load = priv->cfg->bt_init_traffic_load;
+ priv->bt_sco_active = false;
+ priv->bt_full_concurrent = false;
+ priv->bt_ci_compliance = 0;
+
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2834,6 +3044,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
static int __iwl_up(struct iwl_priv *priv)
{
+ struct iwl_rxon_context *ctx;
int i;
int ret;
@@ -2847,9 +3058,13 @@ static int __iwl_up(struct iwl_priv *priv)
return -EIO;
}
- ret = iwl_alloc_bcast_station(priv, true);
- if (ret)
- return ret;
+ for_each_context(priv, ctx) {
+ ret = iwl_alloc_bcast_station(priv, ctx, true);
+ if (ret) {
+ iwl_dealloc_bcast_stations(priv);
+ return ret;
+ }
+ }
iwl_prepare_card_hw(priv);
@@ -2874,6 +3089,12 @@ static int __iwl_up(struct iwl_priv *priv)
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ /* must be initialised before iwl_hw_nic_init */
+ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+ priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+ else
+ priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+
ret = iwlagn_hw_nic_init(priv);
if (ret) {
IWL_ERR(priv, "Unable to init nic\n");
@@ -3004,11 +3225,42 @@ static void iwl_bg_restart(struct work_struct *data)
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ struct iwl_rxon_context *ctx;
+ bool bt_sco, bt_full_concurrent;
+ u8 bt_ci_compliance;
+ u8 bt_load;
+ u8 bt_status;
+
mutex_lock(&priv->mutex);
- priv->vif = NULL;
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
priv->is_open = 0;
+
+ /*
+ * __iwl_down() will clear the BT status variables,
+ * which is correct, but when we restart we really
+ * want to keep them so restore them afterwards.
+ *
+ * The restart process will later pick them up and
+ * re-configure the hw when we reconfigure the BT
+ * command.
+ */
+ bt_sco = priv->bt_sco_active;
+ bt_full_concurrent = priv->bt_full_concurrent;
+ bt_ci_compliance = priv->bt_ci_compliance;
+ bt_load = priv->bt_traffic_load;
+ bt_status = priv->bt_status;
+
+ __iwl_down(priv);
+
+ priv->bt_sco_active = bt_sco;
+ priv->bt_full_concurrent = bt_full_concurrent;
+ priv->bt_ci_compliance = bt_ci_compliance;
+ priv->bt_traffic_load = bt_load;
+ priv->bt_status = bt_status;
+
mutex_unlock(&priv->mutex);
- iwl_down(priv);
+ iwl_cancel_deferred_work(priv);
ieee80211_restart_hw(priv->hw);
} else {
iwl_down(priv);
@@ -3039,12 +3291,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx;
struct ieee80211_conf *conf = NULL;
int ret = 0;
if (!vif || !priv->is_open)
return;
+ ctx = iwl_rxon_ctx_from_vif(vif);
+
if (vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
@@ -3057,44 +3312,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
conf = ieee80211_get_hw_conf(priv->hw);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
- iwl_setup_rxon_timing(priv, vif);
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ ret = iwl_send_rxon_timing(priv, ctx);
if (ret)
- IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "RXON timing - "
"Attempting to continue.\n");
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl_set_rxon_ht(priv, &priv->current_ht_config);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
vif->bss_conf.aid, vif->bss_conf.beacon_int);
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, ctx->active.bssid_addr);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -3137,11 +3390,14 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
{
int ret;
struct ieee80211_hw *hw = priv->hw;
+ struct iwl_rxon_context *ctx;
+
hw->rate_control_algorithm = "iwl-agn-rs";
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_NEED_DTIM_PERIOD |
IEEE80211_HW_SPECTRUM_MGMT;
if (!priv->cfg->broken_powersave)
@@ -3155,9 +3411,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
hw->sta_data_size = sizeof(struct iwl_station_priv);
hw->vif_data_size = sizeof(struct iwl_vif_priv);
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ for_each_context(priv, ctx) {
+ hw->wiphy->interface_modes |= ctx->interface_modes;
+ hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
+ }
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -3247,15 +3504,6 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
- if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
- /* stop mac, cancel any scan request and clear
- * RXON_FILTER_ASSOC_MSK BIT
- */
- mutex_lock(&priv->mutex);
- iwl_scan_cancel_timeout(priv, 100);
- mutex_unlock(&priv->mutex);
- }
-
iwl_down(priv);
flush_workqueue(priv->workqueue);
@@ -3285,24 +3533,25 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
int ret = 0;
+ lockdep_assert_held(&priv->mutex);
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_associated_ctx(ctx)) {
/* RXON - unassoc (to set timing command) */
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
/* RXON Timing */
- iwl_setup_rxon_timing(priv, vif);
- ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ ret = iwl_send_rxon_timing(priv, ctx);
if (ret)
- IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "RXON timing failed - "
"Attempting to continue.\n");
/* AP has all antennas */
@@ -3310,28 +3559,30 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
priv->hw_params.valid_rx_ant;
iwl_set_rxon_ht(priv, &priv->current_ht_config);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- priv->staging_rxon.assoc_id = 0;
+ ctx->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
+ /* need to send beacon cmd before committing assoc RXON! */
+ iwl_send_beacon_cmd(priv);
/* restore RXON assoc */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
}
iwl_send_beacon_cmd(priv);
@@ -3348,9 +3599,11 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+
IWL_DEBUG_MAC80211(priv, "enter\n");
- iwl_update_tkip_key(priv, keyconf, sta,
+ iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta,
iv32, phase1key);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3362,6 +3615,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+ struct iwl_rxon_context *ctx = vif_priv->ctx;
int ret;
u8 sta_id;
bool is_default_wep_key = false;
@@ -3373,7 +3628,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta);
if (sta_id == IWL_INVALID_STATION)
return -EINVAL;
@@ -3386,9 +3641,11 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* in 1X mode.
* In legacy wep mode, we use another host command to the uCode.
*/
- if (key->alg == ALG_WEP && !sta && vif->type != NL80211_IFTYPE_AP) {
+ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+ !sta) {
if (cmd == SET_KEY)
- is_default_wep_key = !priv->key_mapping_key;
+ is_default_wep_key = !ctx->key_mapping_keys;
else
is_default_wep_key =
(key->hw_key_idx == HW_KEY_DEFAULT);
@@ -3397,17 +3654,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
if (is_default_wep_key)
- ret = iwl_set_default_wep_key(priv, key);
+ ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key);
else
- ret = iwl_set_dynamic_key(priv, key, sta_id);
+ ret = iwl_set_dynamic_key(priv, vif_priv->ctx,
+ key, sta_id);
IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
if (is_default_wep_key)
- ret = iwl_remove_default_wep_key(priv, key);
+ ret = iwl_remove_default_wep_key(priv, ctx, key);
else
- ret = iwl_remove_dynamic_key(priv, key, sta_id);
+ ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id);
IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
@@ -3476,8 +3734,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
sta_priv->lq_sta.lq.general_params.flags &=
~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
- iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
- CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
+ &sta_priv->lq_sta.lq, CMD_ASYNC, false);
}
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
@@ -3492,8 +3750,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
sta_priv->lq_sta.lq.general_params.flags |=
LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
- iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
- CMD_ASYNC, false);
+ iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
+ &sta_priv->lq_sta.lq, CMD_ASYNC, false);
}
ret = 0;
break;
@@ -3539,6 +3797,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
int ret;
u8 sta_id;
@@ -3554,8 +3813,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP)
sta_priv->client = true;
- ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
- &sta_id);
+ ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr,
+ is_ap, sta, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
sta->addr, ret);
@@ -3581,7 +3840,17 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = ch_switch->channel;
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ /*
+ * MULTI-FIXME
+ * When we add support for multiple interfaces, we need to
+ * revisit this. The channel switch command in the device
+ * only affects the BSS context, but what does that really
+ * mean? And what if we get a CSA on the second interface?
+ * This needs a lot of work.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u16 ch;
unsigned long flags = 0;
@@ -3594,7 +3863,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
test_bit(STATUS_SCANNING, &priv->status))
goto out_exit;
- if (!iwl_is_associated(priv))
+ if (!iwl_is_associated_ctx(ctx))
goto out_exit;
/* channel switch in progress */
@@ -3604,11 +3873,10 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {
- ch = ieee80211_frequency_to_channel(
- ch_switch->channel->center_freq);
- if (le16_to_cpu(priv->active_rxon.channel) != ch) {
+ ch = channel->hw_value;
+ if (le16_to_cpu(ctx->active.channel) != ch) {
ch_info = iwl_get_channel_info(priv,
- conf->channel->band,
+ channel->band,
ch);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_MAC80211(priv, "invalid channel\n");
@@ -3619,34 +3887,31 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
priv->current_ht_config.smps = conf->smps_mode;
/* Configure HT40 channels */
- ht_conf->is_ht = conf_is_ht(conf);
- if (ht_conf->is_ht) {
+ ctx->ht.enabled = conf_is_ht(conf);
+ if (ctx->ht.enabled) {
if (conf_is_ht40_minus(conf)) {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ht_conf->is_40mhz = true;
+ ctx->ht.is_40mhz = true;
} else if (conf_is_ht40_plus(conf)) {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ht_conf->is_40mhz = true;
+ ctx->ht.is_40mhz = true;
} else {
- ht_conf->extension_chan_offset =
+ ctx->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ht_conf->is_40mhz = false;
+ ctx->ht.is_40mhz = false;
}
} else
- ht_conf->is_40mhz = false;
+ ctx->ht.is_40mhz = false;
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
- iwl_set_rxon_channel(priv, conf->channel);
+ iwl_set_rxon_channel(priv, channel, ctx);
iwl_set_rxon_ht(priv, ht_conf);
- iwl_set_flags_for_band(priv, conf->channel->band,
- priv->vif);
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_set_rate(priv);
@@ -3663,7 +3928,7 @@ out:
mutex_unlock(&priv->mutex);
out_exit:
if (!priv->switch_rxon.switch_in_progress)
- ieee80211_chswitch_done(priv->vif, false);
+ ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
}
@@ -3674,6 +3939,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
+ struct iwl_rxon_context *ctx;
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
@@ -3693,10 +3959,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
-
- iwlcore_commit_rxon(priv);
+ for_each_context(priv, ctx) {
+ ctx->staging.filter_flags &= ~filter_nand;
+ ctx->staging.filter_flags |= filter_or;
+ iwlcore_commit_rxon(priv, ctx);
+ }
mutex_unlock(&priv->mutex);
@@ -3765,6 +4032,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
+ INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
+ INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
@@ -3802,15 +4071,17 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
priv->cfg->ops->lib->cancel_deferred_work(priv);
cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->scan_check);
- cancel_work_sync(&priv->start_internal_scan);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->run_time_calib_work);
cancel_work_sync(&priv->beacon_update);
+
+ iwl_cancel_scan_deferred_work(priv);
+
+ cancel_work_sync(&priv->bt_full_concurrency);
+ cancel_work_sync(&priv->bt_runtime_config);
+
del_timer_sync(&priv->statistics_periodic);
del_timer_sync(&priv->ucode_trace);
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
}
static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3865,10 +4136,22 @@ static int iwl_init_drv(struct iwl_priv *priv)
/* Choose which receivers/antennas to use */
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
iwl_init_scan_params(priv);
+ /* init bt coex */
+ if (priv->cfg->advanced_bt_coexist) {
+ priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
+ priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
+ priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
+ priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
+ priv->bt_duration = BT_DURATION_LIMIT_DEF;
+ priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
+ priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF;
+ }
+
/* Set the tx_power_user_lmt to the lowest power level
* this value will get overwritten by channel max power avg
* from eeprom */
@@ -3923,11 +4206,60 @@ static struct ieee80211_ops iwl_hw_ops = {
.sta_remove = iwl_mac_sta_remove,
.channel_switch = iwl_mac_channel_switch,
.flush = iwl_mac_flush,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
+};
+
+static void iwl_hw_detect(struct iwl_priv *priv)
+{
+ priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
+ priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
+}
+
+static int iwl_set_hw_params(struct iwl_priv *priv)
+{
+ priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+ priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+ if (priv->cfg->mod_params->amsdu_size_8K)
+ priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
+ else
+ priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
+
+ priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
+
+ if (priv->cfg->mod_params->disable_11n)
+ priv->cfg->sku &= ~IWL_SKU_N;
+
+ /* Device-specific setup */
+ return priv->cfg->ops->lib->set_hw_params(priv);
+}
+
+static const u8 iwlagn_bss_ac_to_fifo[] = {
+ IWL_TX_FIFO_VO,
+ IWL_TX_FIFO_VI,
+ IWL_TX_FIFO_BE,
+ IWL_TX_FIFO_BK,
+};
+
+static const u8 iwlagn_bss_ac_to_queue[] = {
+ 0, 1, 2, 3,
+};
+
+static const u8 iwlagn_pan_ac_to_fifo[] = {
+ IWL_TX_FIFO_VO_IPAN,
+ IWL_TX_FIFO_VI_IPAN,
+ IWL_TX_FIFO_BE_IPAN,
+ IWL_TX_FIFO_BK_IPAN,
+};
+
+static const u8 iwlagn_pan_ac_to_queue[] = {
+ 7, 6, 5, 4,
};
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int err = 0;
+ int err = 0, i;
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3955,6 +4287,53 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv = hw->priv;
/* At this point both hw and priv are allocated. */
+ /*
+ * The default context is always valid,
+ * more may be discovered when firmware
+ * is loaded.
+ */
+ priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
+
+ for (i = 0; i < NUM_IWL_RXON_CTX; i++)
+ priv->contexts[i].ctxid = i;
+
+ priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
+ priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo;
+ priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue;
+ priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
+ BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
+ BIT(NL80211_IFTYPE_STATION);
+ priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
+ priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
+ priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
+
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
+ priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
+ priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
+ priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo;
+ priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue;
+ priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
+ priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
+ priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
+ priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
+ priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
+
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
SET_IEEE80211_DEV(hw, &pdev->dev);
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
@@ -3962,12 +4341,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
priv->pci_dev = pdev;
priv->inta_mask = CSR_INI_SET_MASK;
+ /* is antenna coupling more than 35dB ? */
+ priv->bt_ant_couple_ok =
+ (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
+ true : false;
+
+ /* enable/disable bt channel announcement */
+ priv->bt_ch_announce = iwlagn_bt_ch_announce;
+
if (iwl_alloc_traffic_mem(priv))
IWL_ERR(priv, "Not enough memory to generate traffic log\n");
/**************************
* 2. Initializing PCI bus
**************************/
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
if (pci_enable_device(pdev)) {
err = -ENODEV;
goto out_ieee80211_free_hw;
@@ -4492,3 +4882,11 @@ module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
S_IRUGO);
MODULE_PARM_DESC(ucode_alternative,
"specify ucode alternative to use from ucode file");
+
+module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO);
+MODULE_PARM_DESC(antenna_coupling,
+ "specify antenna coupling in dB (defualt: 0 dB)");
+
+module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO);
+MODULE_PARM_DESC(bt_ch_announce,
+ "Enable BT channel announcement mode (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index cc6464dc72e5..e1f85ae9da59 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -95,6 +95,7 @@ extern struct iwl_cfg iwl1000_bg_cfg;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd;
+extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
int iwl_reset_ict(struct iwl_priv *priv);
@@ -133,6 +134,8 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
void iwlagn_init_alive_start(struct iwl_priv *priv);
int iwlagn_alive_notify(struct iwl_priv *priv);
int iwl_verify_ucode(struct iwl_priv *priv);
+void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+void iwlagn_send_prio_tbl(struct iwl_priv *priv);
/* lib */
void iwl_check_abort_status(struct iwl_priv *priv,
@@ -216,14 +219,23 @@ void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
/* scan */
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
/* station mgmt */
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
/* hcmd */
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv);
+int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
+/* bt coex */
+void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
+void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
+void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
+void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
+
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 60725a5c1b69..3e4ba31b5d59 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -62,7 +62,7 @@
*****************************************************************************/
/*
* Please use this file (iwl-commands.h) only for uCode API definitions.
- * Please use iwl-4965-hw.h for hardware-related definitions.
+ * Please use iwl-xxxx-hw.h for hardware-related definitions.
* Please use iwl-dev.h for driver implementation definitions.
*/
@@ -173,6 +173,23 @@ enum {
REPLY_RX_MPDU_CMD = 0xc1,
REPLY_RX = 0xc3,
REPLY_COMPRESSED_BA = 0xc5,
+
+ /* BT Coex */
+ REPLY_BT_COEX_PRIO_TABLE = 0xcc,
+ REPLY_BT_COEX_PROT_ENV = 0xcd,
+ REPLY_BT_COEX_PROFILE_NOTIF = 0xce,
+ REPLY_BT_COEX_SCO = 0xcf,
+
+ /* PAN commands */
+ REPLY_WIPAN_PARAMS = 0xb2,
+ REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */
+ REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */
+ REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */
+ REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */
+ REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */
+ REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9,
+ REPLY_WIPAN_NOA_NOTIFICATION = 0xbc,
+
REPLY_MAX = 0xff
};
@@ -600,6 +617,9 @@ enum {
RXON_DEV_TYPE_ESS = 3,
RXON_DEV_TYPE_IBSS = 4,
RXON_DEV_TYPE_SNIFFER = 6,
+ RXON_DEV_TYPE_CP = 7,
+ RXON_DEV_TYPE_2STA = 8,
+ RXON_DEV_TYPE_P2P = 9,
};
@@ -816,7 +836,8 @@ struct iwl_rxon_time_cmd {
__le16 atim_window;
__le32 beacon_init_val;
__le16 listen_interval;
- __le16 reserved;
+ u8 dtim_period;
+ u8 delta_cp_bss_tbtts;
} __packed;
/*
@@ -953,11 +974,13 @@ struct iwl_qosparam_cmd {
/* Special, dedicated locations within device's station table */
#define IWL_AP_ID 0
+#define IWL_AP_ID_PAN 1
#define IWL_STA_ID 2
#define IWL3945_BROADCAST_ID 24
#define IWL3945_STATION_COUNT 25
#define IWL4965_BROADCAST_ID 31
#define IWL4965_STATION_COUNT 32
+#define IWLAGN_PAN_BCAST_ID 14
#define IWLAGN_BROADCAST_ID 15
#define IWLAGN_STATION_COUNT 16
@@ -966,6 +989,7 @@ struct iwl_qosparam_cmd {
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
+#define STA_FLG_PAN_STATION cpu_to_le32(1 << 13)
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
#define STA_FLG_MAX_AGG_SIZE_POS (19)
@@ -994,6 +1018,7 @@ struct iwl_qosparam_cmd {
#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
#define STA_KEY_MAX_NUM 8
+#define STA_KEY_MAX_NUM_PAN 16
/* Flags indicate whether to modify vs. don't change various station params */
#define STA_MODIFY_KEY_MASK 0x01
@@ -1056,7 +1081,8 @@ struct sta_id_modify {
*
* The device contains an internal table of per-station information,
* with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
+ * initial Tx attempt and any retries (agn devices uses
+ * REPLY_TX_LINK_QUALITY_CMD,
* 3945 uses REPLY_RATE_SCALE to set up rate tables).
*
* REPLY_ADD_STA sets up the table entry for one station, either creating
@@ -1367,21 +1393,24 @@ struct iwl4965_rx_non_cfg_phy {
} __packed;
-#define IWL50_RX_RES_PHY_CNT 8
-#define IWL50_RX_RES_AGC_IDX 1
-#define IWL50_RX_RES_RSSI_AB_IDX 2
-#define IWL50_RX_RES_RSSI_C_IDX 3
-#define IWL50_OFDM_AGC_MSK 0xfe00
-#define IWL50_OFDM_AGC_BIT_POS 9
-#define IWL50_OFDM_RSSI_A_MSK 0x00ff
-#define IWL50_OFDM_RSSI_A_BIT_POS 0
-#define IWL50_OFDM_RSSI_B_MSK 0xff0000
-#define IWL50_OFDM_RSSI_B_BIT_POS 16
-#define IWL50_OFDM_RSSI_C_MSK 0x00ff
-#define IWL50_OFDM_RSSI_C_BIT_POS 0
+#define IWLAGN_RX_RES_PHY_CNT 8
+#define IWLAGN_RX_RES_AGC_IDX 1
+#define IWLAGN_RX_RES_RSSI_AB_IDX 2
+#define IWLAGN_RX_RES_RSSI_C_IDX 3
+#define IWLAGN_OFDM_AGC_MSK 0xfe00
+#define IWLAGN_OFDM_AGC_BIT_POS 9
+#define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff
+#define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00
+#define IWLAGN_OFDM_RSSI_A_BIT_POS 0
+#define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000
+#define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000
+#define IWLAGN_OFDM_RSSI_B_BIT_POS 16
+#define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff
+#define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00
+#define IWLAGN_OFDM_RSSI_C_BIT_POS 0
-struct iwl5000_non_cfg_phy {
- __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* up to 8 phy entries */
+struct iwlagn_non_cfg_phy {
+ __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */
} __packed;
@@ -1401,7 +1430,7 @@ struct iwl_rx_phy_res {
u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
__le32 rate_n_flags; /* RATE_MCS_* */
__le16 byte_count; /* frame's byte-count */
- __le16 reserved3;
+ __le16 frame_time; /* frame's time on the air */
} __packed;
struct iwl_rx_mpdu_res_start {
@@ -1424,12 +1453,12 @@ struct iwl_rx_mpdu_res_start {
* uCode handles all timing and protocol related to control frames
* (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler
* handle reception of block-acks; uCode updates the host driver via
- * REPLY_COMPRESSED_BA (4965).
+ * REPLY_COMPRESSED_BA.
*
* uCode handles retrying Tx when an ACK is expected but not received.
* This includes trying lower data rates than the one requested in the Tx
* command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
+ * REPLY_TX_LINK_QUALITY_CMD (agn).
*
* Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
* This command must be executed after every RXON command, before Tx can occur.
@@ -1465,7 +1494,7 @@ struct iwl_rx_mpdu_res_start {
* Set this for unicast frames, but not broadcast/multicast. */
#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-/* For 4965:
+/* For agn devices:
* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
* Tx command's initial_rate_index indicates first rate to try;
* uCode walks through table for additional Tx attempts.
@@ -1484,7 +1513,7 @@ struct iwl_rx_mpdu_res_start {
*/
#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
+/* Tx antenna selection field; used only for 3945, reserved (0) for agn devices.
* Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
@@ -1867,9 +1896,10 @@ enum {
* frame in this new agg block failed in previous agg block(s).
*
* Note that, for aggregation, ACK (block-ack) status is not delivered here;
- * block-ack has not been received by the time the 4965 records this status.
+ * block-ack has not been received by the time the agn device records
+ * this status.
* This status relates to reasons the tx might have been blocked or aborted
- * within the sending station (this 4965), rather than whether it was
+ * within the sending station (this agn device), rather than whether it was
* received successfully by the destination station.
*/
struct agg_tx_status {
@@ -2092,8 +2122,8 @@ struct iwl_link_qual_general_params {
} __packed;
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
-#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)
-#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)
+#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
+#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
@@ -2110,8 +2140,10 @@ struct iwl_link_qual_general_params {
*/
struct iwl_link_qual_agg_params {
- /* Maximum number of uSec in aggregation.
- * Driver should set this to 4000 (4 milliseconds). */
+ /*
+ *Maximum number of uSec in aggregation.
+ * default set to 4000 (4 milliseconds) if not configured in .cfg
+ */
__le16 agg_time_limit;
/*
@@ -2135,14 +2167,16 @@ struct iwl_link_qual_agg_params {
/*
* REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response)
*
- * For 4965 only; 3945 uses REPLY_RATE_SCALE.
+ * For agn devices only; 3945 uses REPLY_RATE_SCALE.
*
- * Each station in the 4965's internal station table has its own table of 16
+ * Each station in the agn device's internal station table has its own table
+ * of 16
* Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when
* an ACK is not received. This command replaces the entire table for
* one station.
*
- * NOTE: Station must already be in 4965's station table. Use REPLY_ADD_STA.
+ * NOTE: Station must already be in agn device's station table.
+ * Use REPLY_ADD_STA.
*
* The rate scaling procedures described below work well. Of course, other
* procedures are possible, and may work better for particular environments.
@@ -2179,12 +2213,12 @@ struct iwl_link_qual_agg_params {
*
* ACCUMULATING HISTORY
*
- * The rate scaling algorithm for 4965, as implemented in Linux driver, uses
- * two sets of frame Tx success history: One for the current/active modulation
- * mode, and one for a speculative/search mode that is being attempted. If the
- * speculative mode turns out to be more effective (i.e. actual transfer
- * rate is better), then the driver continues to use the speculative mode
- * as the new current active mode.
+ * The rate scaling algorithm for agn devices, as implemented in Linux driver,
+ * uses two sets of frame Tx success history: One for the current/active
+ * modulation mode, and one for a speculative/search mode that is being
+ * attempted. If the speculative mode turns out to be more effective (i.e.
+ * actual transfer rate is better), then the driver continues to use the
+ * speculative mode as the new current active mode.
*
* Each history set contains, separately for each possible rate, data for a
* sliding window of the 62 most recent tx attempts at that rate. The data
@@ -2195,12 +2229,12 @@ struct iwl_link_qual_agg_params {
* The driver uses the bit map to remove successes from the success sum, as
* the oldest tx attempts fall out of the window.
*
- * When the 4965 makes multiple tx attempts for a given frame, each attempt
- * might be at a different rate, and have different modulation characteristics
- * (e.g. antenna, fat channel, short guard interval), as set up in the rate
- * scaling table in the Link Quality command. The driver must determine
- * which rate table entry was used for each tx attempt, to determine which
- * rate-specific history to update, and record only those attempts that
+ * When the agn device makes multiple tx attempts for a given frame, each
+ * attempt might be at a different rate, and have different modulation
+ * characteristics (e.g. antenna, fat channel, short guard interval), as set
+ * up in the rate scaling table in the Link Quality command. The driver must
+ * determine which rate table entry was used for each tx attempt, to determine
+ * which rate-specific history to update, and record only those attempts that
* match the modulation characteristics of the history set.
*
* When using block-ack (aggregation), all frames are transmitted at the same
@@ -2330,7 +2364,7 @@ struct iwl_link_quality_cmd {
/*
* Rate info; when using rate-scaling, Tx command's initial_rate_index
* specifies 1st Tx rate attempted, via index into this table.
- * 4965 works its way through table when retrying Tx.
+ * agn devices works its way through table when retrying Tx.
*/
struct {
__le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */
@@ -2363,10 +2397,26 @@ struct iwl_link_quality_cmd {
#define BT_MAX_KILL_DEF (0x5)
#define BT_MAX_KILL_MAX (0xFF)
+#define BT_DURATION_LIMIT_DEF 625
+#define BT_DURATION_LIMIT_MAX 1250
+#define BT_DURATION_LIMIT_MIN 625
+
+#define BT_ON_THRESHOLD_DEF 4
+#define BT_ON_THRESHOLD_MAX 1000
+#define BT_ON_THRESHOLD_MIN 1
+
+#define BT_FRAG_THRESHOLD_DEF 0
+#define BT_FRAG_THRESHOLD_MAX 0
+#define BT_FRAG_THRESHOLD_MIN 0
+
+#define BT_AGG_THRESHOLD_DEF 0
+#define BT_AGG_THRESHOLD_MAX 0
+#define BT_AGG_THRESHOLD_MIN 0
+
/*
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
*
- * 3945 and 4965 support hardware handshake with Bluetooth device on
+ * 3945 and agn devices support hardware handshake with Bluetooth device on
* same platform. Bluetooth device alerts wireless device when it will Tx;
* wireless device can delay or kill its own Tx to accommodate.
*/
@@ -2379,6 +2429,74 @@ struct iwl_bt_cmd {
__le32 kill_cts_mask;
} __packed;
+#define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0)
+
+#define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5))
+#define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3
+#define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0
+#define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1
+#define IWLAGN_BT_FLAG_COEX_MODE_3W 2
+#define IWLAGN_BT_FLAG_COEX_MODE_4W 3
+
+#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6)
+#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7)
+
+#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF
+#define IWLAGN_BT_PRIO_BOOST_MIN 0x00
+#define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0
+
+#define IWLAGN_BT_MAX_KILL_DEFAULT 5
+
+#define IWLAGN_BT3_T7_DEFAULT 1
+
+#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff)
+#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff)
+
+#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
+
+#define IWLAGN_BT3_T2_DEFAULT 0xc
+
+#define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0))
+#define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1))
+#define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2))
+#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3))
+#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4))
+#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5))
+#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6))
+#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7))
+
+#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \
+ IWLAGN_BT_VALID_BOOST | \
+ IWLAGN_BT_VALID_MAX_KILL | \
+ IWLAGN_BT_VALID_3W_TIMERS | \
+ IWLAGN_BT_VALID_KILL_ACK_MASK | \
+ IWLAGN_BT_VALID_KILL_CTS_MASK | \
+ IWLAGN_BT_VALID_BT4_TIMES | \
+ IWLAGN_BT_VALID_3W_LUT)
+
+struct iwlagn_bt_cmd {
+ u8 flags;
+ u8 ledtime; /* unused */
+ u8 max_kill;
+ u8 bt3_timer_t7_value;
+ __le32 kill_ack_mask;
+ __le32 kill_cts_mask;
+ u8 bt3_prio_sample_time;
+ u8 bt3_timer_t2_value;
+ __le16 bt4_reaction_time; /* unused */
+ __le32 bt3_lookup_table[12];
+ __le16 bt4_decision_time; /* unused */
+ __le16 valid;
+ u8 prio_boost;
+ u8 reserved[3];
+};
+
+#define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0))
+
+struct iwlagn_bt_sco_cmd {
+ __le32 flags;
+};
+
/******************************************************************************
* (6)
* Spectrum Management (802.11h) Commands, Responses, Notifications:
@@ -2567,7 +2685,7 @@ struct iwl_powertable_cmd {
/*
* PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
+ * all devices identical.
*/
struct iwl_sleep_notification {
u8 pm_sleep_mode;
@@ -2578,7 +2696,7 @@ struct iwl_sleep_notification {
__le32 bcon_timer;
} __packed;
-/* Sleep states. 3945 and 4965 identical. */
+/* Sleep states. all devices identical. */
enum {
IWL_PM_NO_SLEEP = 0,
IWL_PM_SLP_MAC = 1,
@@ -2887,6 +3005,12 @@ struct iwl_scanstart_notification {
#define SCAN_OWNER_STATUS 0x1;
#define MEASURE_OWNER_STATUS 0x2;
+#define IWL_PROBE_STATUS_OK 0
+#define IWL_PROBE_STATUS_TX_FAILED BIT(0)
+/* error statuses combined with TX_FAILED */
+#define IWL_PROBE_STATUS_FAIL_TTL BIT(1)
+#define IWL_PROBE_STATUS_FAIL_BT BIT(2)
+
#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
/*
* SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
@@ -2894,7 +3018,8 @@ struct iwl_scanstart_notification {
struct iwl_scanresults_notification {
u8 channel;
u8 band;
- u8 reserved[2];
+ u8 probe_status;
+ u8 num_probe_not_sent; /* not enough time to send */
__le32 tsf_low;
__le32 tsf_high;
__le32 statistics[NUMBER_OF_STATISTICS];
@@ -2906,7 +3031,7 @@ struct iwl_scanresults_notification {
struct iwl_scancomplete_notification {
u8 scanned_channels;
u8 status;
- u8 reserved;
+ u8 bt_status; /* BT On/Off status */
u8 last_channel;
__le32 tsf_low;
__le32 tsf_high;
@@ -2919,6 +3044,11 @@ struct iwl_scancomplete_notification {
*
*****************************************************************************/
+enum iwl_ibss_manager {
+ IWL_NOT_IBSS_MANAGER = 0,
+ IWL_IBSS_MANAGER = 1,
+};
+
/*
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
@@ -3260,7 +3390,7 @@ struct statistics_general_bt {
/*
* REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
+ * all devices identical.
*
* This command triggers an immediate response containing uCode statistics.
* The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
@@ -3598,7 +3728,7 @@ struct iwl_enhance_sensitivity_cmd {
/**
* REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
*
- * This command sets the relative gains of 4965's 3 radio receiver chains.
+ * This command sets the relative gains of agn device's 3 radio receiver chains.
*
* After the first association, driver should accumulate signal and noise
* statistics from the STATISTICS_NOTIFICATIONs that follow the first 20
@@ -3955,6 +4085,201 @@ struct iwl_coex_event_resp {
/******************************************************************************
+ * Bluetooth Coexistence commands
+ *
+ *****************************************************************************/
+
+/*
+ * BT Status notification
+ * REPLY_BT_COEX_PROFILE_NOTIF = 0xce
+ */
+enum iwl_bt_coex_profile_traffic_load {
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
+ IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
+ IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
+/*
+ * There are no more even though below is a u8, the
+ * indication from the BT device only has two bits.
+ */
+};
+
+#define BT_UART_MSG_FRAME1MSGTYPE_POS (0)
+#define BT_UART_MSG_FRAME1MSGTYPE_MSK \
+ (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS)
+#define BT_UART_MSG_FRAME1SSN_POS (3)
+#define BT_UART_MSG_FRAME1SSN_MSK \
+ (0x3 << BT_UART_MSG_FRAME1SSN_POS)
+#define BT_UART_MSG_FRAME1UPDATEREQ_POS (5)
+#define BT_UART_MSG_FRAME1UPDATEREQ_MSK \
+ (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS)
+#define BT_UART_MSG_FRAME1RESERVED_POS (6)
+#define BT_UART_MSG_FRAME1RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME1RESERVED_POS)
+
+#define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0)
+#define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \
+ (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS)
+#define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2)
+#define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \
+ (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS)
+#define BT_UART_MSG_FRAME2CHLSEQN_POS (4)
+#define BT_UART_MSG_FRAME2CHLSEQN_MSK \
+ (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS)
+#define BT_UART_MSG_FRAME2INBAND_POS (5)
+#define BT_UART_MSG_FRAME2INBAND_MSK \
+ (0x1 << BT_UART_MSG_FRAME2INBAND_POS)
+#define BT_UART_MSG_FRAME2RESERVED_POS (6)
+#define BT_UART_MSG_FRAME2RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME2RESERVED_POS)
+
+#define BT_UART_MSG_FRAME3SCOESCO_POS (0)
+#define BT_UART_MSG_FRAME3SCOESCO_MSK \
+ (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS)
+#define BT_UART_MSG_FRAME3SNIFF_POS (1)
+#define BT_UART_MSG_FRAME3SNIFF_MSK \
+ (0x1 << BT_UART_MSG_FRAME3SNIFF_POS)
+#define BT_UART_MSG_FRAME3A2DP_POS (2)
+#define BT_UART_MSG_FRAME3A2DP_MSK \
+ (0x1 << BT_UART_MSG_FRAME3A2DP_POS)
+#define BT_UART_MSG_FRAME3ACL_POS (3)
+#define BT_UART_MSG_FRAME3ACL_MSK \
+ (0x1 << BT_UART_MSG_FRAME3ACL_POS)
+#define BT_UART_MSG_FRAME3MASTER_POS (4)
+#define BT_UART_MSG_FRAME3MASTER_MSK \
+ (0x1 << BT_UART_MSG_FRAME3MASTER_POS)
+#define BT_UART_MSG_FRAME3OBEX_POS (5)
+#define BT_UART_MSG_FRAME3OBEX_MSK \
+ (0x1 << BT_UART_MSG_FRAME3OBEX_POS)
+#define BT_UART_MSG_FRAME3RESERVED_POS (6)
+#define BT_UART_MSG_FRAME3RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME3RESERVED_POS)
+
+#define BT_UART_MSG_FRAME4IDLEDURATION_POS (0)
+#define BT_UART_MSG_FRAME4IDLEDURATION_MSK \
+ (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS)
+#define BT_UART_MSG_FRAME4RESERVED_POS (6)
+#define BT_UART_MSG_FRAME4RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME4RESERVED_POS)
+
+#define BT_UART_MSG_FRAME5TXACTIVITY_POS (0)
+#define BT_UART_MSG_FRAME5TXACTIVITY_MSK \
+ (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS)
+#define BT_UART_MSG_FRAME5RXACTIVITY_POS (2)
+#define BT_UART_MSG_FRAME5RXACTIVITY_MSK \
+ (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS)
+#define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4)
+#define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \
+ (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS)
+#define BT_UART_MSG_FRAME5RESERVED_POS (6)
+#define BT_UART_MSG_FRAME5RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME5RESERVED_POS)
+
+#define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0)
+#define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \
+ (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS)
+#define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5)
+#define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \
+ (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS)
+#define BT_UART_MSG_FRAME6RESERVED_POS (6)
+#define BT_UART_MSG_FRAME6RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME6RESERVED_POS)
+
+#define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0)
+#define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \
+ (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS)
+#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS (3)
+#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK \
+ (0x3 << BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS)
+#define BT_UART_MSG_FRAME7CONNECTABLE_POS (5)
+#define BT_UART_MSG_FRAME7CONNECTABLE_MSK \
+ (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS)
+#define BT_UART_MSG_FRAME7RESERVED_POS (6)
+#define BT_UART_MSG_FRAME7RESERVED_MSK \
+ (0x3 << BT_UART_MSG_FRAME7RESERVED_POS)
+
+
+struct iwl_bt_uart_msg {
+ u8 header;
+ u8 frame1;
+ u8 frame2;
+ u8 frame3;
+ u8 frame4;
+ u8 frame5;
+ u8 frame6;
+ u8 frame7;
+} __attribute__((packed));
+
+struct iwl_bt_coex_profile_notif {
+ struct iwl_bt_uart_msg last_bt_uart_msg;
+ u8 bt_status; /* 0 - off, 1 - on */
+ u8 bt_traffic_load; /* 0 .. 3? */
+ u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */
+ u8 reserved;
+} __attribute__((packed));
+
+#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0
+#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1
+#define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1
+#define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e
+#define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4
+#define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0
+#define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1
+
+/*
+ * BT Coexistence Priority table
+ * REPLY_BT_COEX_PRIO_TABLE = 0xcc
+ */
+enum bt_coex_prio_table_events {
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
+ BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,
+ BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,
+ BT_COEX_PRIO_TBL_EVT_DTIM = 6,
+ BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,
+ BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,
+ BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9,
+ BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10,
+ BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11,
+ BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12,
+ BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13,
+ BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14,
+ BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15,
+ /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */
+ BT_COEX_PRIO_TBL_EVT_MAX,
+};
+
+enum bt_coex_prio_table_priorities {
+ BT_COEX_PRIO_TBL_DISABLED = 0,
+ BT_COEX_PRIO_TBL_PRIO_LOW = 1,
+ BT_COEX_PRIO_TBL_PRIO_HIGH = 2,
+ BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,
+ BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,
+ BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,
+ BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6,
+ BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7,
+ BT_COEX_PRIO_TBL_MAX,
+};
+
+struct iwl_bt_coex_prio_table_cmd {
+ u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
+} __attribute__((packed));
+
+#define IWL_BT_COEX_ENV_CLOSE 0
+#define IWL_BT_COEX_ENV_OPEN 1
+/*
+ * BT Protection Envelope
+ * REPLY_BT_COEX_PROT_ENV = 0xcd
+ */
+struct iwl_bt_coex_prot_env_cmd {
+ u8 action; /* 0 = closed, 1 = open */
+ u8 type; /* 0 .. 15 */
+ u8 reserved[2];
+} __attribute__((packed));
+
+/******************************************************************************
* (13)
* Union of all expected notifications/responses:
*
@@ -3993,6 +4318,7 @@ struct iwl_rx_packet {
struct iwl_missed_beacon_notif missed_beacon;
struct iwl_coex_medium_notification coex_medium_notif;
struct iwl_coex_event_resp coex_event;
+ struct iwl_bt_coex_profile_notif bt_coex_profile_notif;
__le32 status;
u8 raw[0];
} u;
@@ -4000,4 +4326,94 @@ struct iwl_rx_packet {
int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
+/*
+ * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
+ */
+
+/**
+ * struct iwl_wipan_slot
+ * @width: Time in TU
+ * @type:
+ * 0 - BSS
+ * 1 - PAN
+ */
+struct iwl_wipan_slot {
+ __le16 width;
+ u8 type;
+ u8 reserved;
+} __packed;
+
+#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */
+#define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4)
+#define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5)
+
+/**
+ * struct iwl_wipan_params_cmd
+ * @flags:
+ * bit0: reserved
+ * bit1: CP leave channel with CTS
+ * bit2: CP leave channel qith Quiet
+ * bit3: slotted mode
+ * 1 - work in slotted mode
+ * 0 - work in non slotted mode
+ * bit4: filter beacon notification
+ * bit5: full tx slotted mode. if this flag is set,
+ * uCode will perform leaving channel methods in context switch
+ * also when working in same channel mode
+ * @num_slots: 1 - 10
+ */
+struct iwl_wipan_params_cmd {
+ __le16 flags;
+ u8 reserved;
+ u8 num_slots;
+ struct iwl_wipan_slot slots[10];
+} __packed;
+
+/*
+ * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9
+ *
+ * TODO: Figure out what this is used for,
+ * it can only switch between 2.4 GHz
+ * channels!!
+ */
+
+struct iwl_wipan_p2p_channel_switch_cmd {
+ __le16 channel;
+ __le16 reserved;
+};
+
+/*
+ * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc
+ *
+ * This is used by the device to notify us of the
+ * NoA schedule it determined so we can forward it
+ * to userspace for inclusion in probe responses.
+ *
+ * In beacons, the NoA schedule is simply appended
+ * to the frame we give the device.
+ */
+
+struct iwl_wipan_noa_descriptor {
+ u8 count;
+ __le32 duration;
+ __le32 interval;
+ __le32 starttime;
+} __packed;
+
+struct iwl_wipan_noa_attribute {
+ u8 id;
+ __le16 length;
+ u8 index;
+ u8 ct_window;
+ struct iwl_wipan_noa_descriptor descr0, descr1;
+ u8 reserved;
+} __packed;
+
+struct iwl_wipan_noa_notification {
+ u32 noa_active;
+ struct iwl_wipan_noa_attribute noa_attribute;
+} __packed;
+
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 07dbc2796448..393f02d94c4e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -64,7 +64,8 @@ MODULE_LICENSE("GPL");
*
* default: bt_coex_active = true (BT_COEX_ENABLE)
*/
-static bool bt_coex_active = true;
+bool bt_coex_active = true;
+EXPORT_SYMBOL_GPL(bt_coex_active);
module_param(bt_coex_active, bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
@@ -146,6 +147,10 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
int i;
u8 ind = ant;
+ if (priv->band == IEEE80211_BAND_2GHZ &&
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
+ return 0;
+
for (i = 0; i < RATE_ANT_NUM - 1; i++) {
ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
if (valid & BIT(ind))
@@ -183,38 +188,33 @@ out:
}
EXPORT_SYMBOL(iwl_alloc_all);
-void iwl_hw_detect(struct iwl_priv *priv)
-{
- priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
- priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
- pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
-}
-EXPORT_SYMBOL(iwl_hw_detect);
-
/*
* QoS support
*/
-static void iwl_update_qos(struct iwl_priv *priv)
+static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- priv->qos_data.def_qos_parm.qos_flags = 0;
+ if (!ctx->is_active)
+ return;
+
+ ctx->qos_data.def_qos_parm.qos_flags = 0;
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
+ if (ctx->qos_data.qos_active)
+ ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
- if (priv->current_ht_config.is_ht)
- priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+ if (ctx->ht.enabled)
+ ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- priv->qos_data.qos_active,
- priv->qos_data.def_qos_parm.qos_flags);
+ ctx->qos_data.qos_active,
+ ctx->qos_data.def_qos_parm.qos_flags);
- iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
- &priv->qos_data.def_qos_parm, NULL);
+ &ctx->qos_data.def_qos_parm, NULL);
}
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
@@ -247,7 +247,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
+ if (priv->cfg->ampdu_factor)
+ ht_info->ampdu_factor = priv->cfg->ampdu_factor;
ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
+ if (priv->cfg->ampdu_density)
+ ht_info->ampdu_density = priv->cfg->ampdu_density;
ht_info->mcs.rx_mask[0] = 0xFF;
if (rx_chains_num >= 2)
@@ -440,15 +444,15 @@ static bool is_single_rx_stream(struct iwl_priv *priv)
priv->current_ht_config.single_chain_sufficient;
}
-static u8 iwl_is_channel_extension(struct iwl_priv *priv,
- enum ieee80211_band band,
- u16 channel, u8 extension_chan_offset)
+static bool iwl_is_channel_extension(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u16 channel, u8 extension_chan_offset)
{
const struct iwl_channel_info *ch_info;
ch_info = iwl_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info))
- return 0;
+ return false;
if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
return !(ch_info->ht40_extension_channel &
@@ -457,38 +461,59 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
return !(ch_info->ht40_extension_channel &
IEEE80211_CHAN_NO_HT40MINUS);
- return 0;
+ return false;
}
-u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_sta_ht_cap *sta_ht_inf)
+bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_sta_ht_cap *ht_cap)
{
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
-
- if (!ht_conf->is_ht || !ht_conf->is_40mhz)
- return 0;
+ if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
+ return false;
- /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ /*
+ * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
* the bit will not set if it is pure 40MHz case
*/
- if (sta_ht_inf) {
- if (!sta_ht_inf->ht_supported)
- return 0;
- }
+ if (ht_cap && !ht_cap->ht_supported)
+ return false;
+
#ifdef CONFIG_IWLWIFI_DEBUGFS
if (priv->disable_ht40)
- return 0;
+ return false;
#endif
+
return iwl_is_channel_extension(priv, priv->band,
- le16_to_cpu(priv->staging_rxon.channel),
- ht_conf->extension_chan_offset);
+ le16_to_cpu(ctx->staging.channel),
+ ctx->ht.extension_chan_offset);
}
EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
- u16 new_val = 0;
- u16 beacon_factor = 0;
+ u16 new_val;
+ u16 beacon_factor;
+
+ /*
+ * If mac80211 hasn't given us a beacon interval, program
+ * the default into the device (not checking this here
+ * would cause the adjustment below to return the maximum
+ * value, which may break PAN.)
+ */
+ if (!beacon_val)
+ return DEFAULT_BEACON_INTERVAL;
+
+ /*
+ * If the beacon interval we obtained from the peer
+ * is too large, we'll have to wake up more often
+ * (and in IBSS case, we'll beacon too much)
+ *
+ * For example, if max_beacon_val is 4096, and the
+ * requested beacon interval is 7000, we'll have to
+ * use 3500 to be able to wake up on the beacons.
+ *
+ * This could badly influence beacon detection stats.
+ */
beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
new_val = beacon_val / beacon_factor;
@@ -499,51 +524,76 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
return new_val;
}
-void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
u64 tsf;
s32 interval_tm, rem;
- unsigned long flags;
struct ieee80211_conf *conf = NULL;
u16 beacon_int;
+ struct ieee80211_vif *vif = ctx->vif;
conf = ieee80211_get_hw_conf(priv->hw);
- spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
- priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
+ lockdep_assert_held(&priv->mutex);
- beacon_int = vif->bss_conf.beacon_int;
+ memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
- if (vif->type == NL80211_IFTYPE_ADHOC) {
- /* TODO: we need to get atim_window from upper stack
- * for now we set to 0 */
- priv->rxon_timing.atim_window = 0;
- } else {
- priv->rxon_timing.atim_window = 0;
- }
+ ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
+ ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
- beacon_int = iwl_adjust_beacon_interval(beacon_int,
+ beacon_int = vif ? vif->bss_conf.beacon_int : 0;
+
+ /*
+ * TODO: For IBSS we need to get atim_window from mac80211,
+ * for now just always use 0
+ */
+ ctx->timing.atim_window = 0;
+
+ if (ctx->ctxid == IWL_RXON_CTX_PAN &&
+ (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&
+ iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif &&
+ priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {
+ ctx->timing.beacon_interval =
+ priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
+ beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
+ } else if (ctx->ctxid == IWL_RXON_CTX_BSS &&
+ iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif &&
+ priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&
+ (!iwl_is_associated_ctx(ctx) || !ctx->vif ||
+ !ctx->vif->bss_conf.beacon_int)) {
+ ctx->timing.beacon_interval =
+ priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;
+ beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
+ } else {
+ beacon_int = iwl_adjust_beacon_interval(beacon_int,
priv->hw_params.max_beacon_itrvl * TIME_UNIT);
- priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
+ ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
+ }
tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
interval_tm = beacon_int * TIME_UNIT;
rem = do_div(tsf, interval_tm);
- priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+ ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+
+ ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;
- spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_ASSOC(priv,
"beacon interval %d beacon timer %d beacon tim %d\n",
- le16_to_cpu(priv->rxon_timing.beacon_interval),
- le32_to_cpu(priv->rxon_timing.beacon_init_val),
- le16_to_cpu(priv->rxon_timing.atim_window));
+ le16_to_cpu(ctx->timing.beacon_interval),
+ le32_to_cpu(ctx->timing.beacon_init_val),
+ le16_to_cpu(ctx->timing.atim_window));
+
+ return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
+ sizeof(ctx->timing), &ctx->timing);
}
-EXPORT_SYMBOL(iwl_setup_rxon_timing);
+EXPORT_SYMBOL(iwl_send_rxon_timing);
-void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ int hw_decrypt)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
if (hw_decrypt)
rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -560,11 +610,11 @@ EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
* 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 iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
int error = 0;
int counter = 1;
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
error |= le32_to_cpu(rxon->flags &
@@ -636,66 +686,83 @@ EXPORT_SYMBOL(iwl_check_rxon_cmd);
* or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
* a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
*/
-int iwl_full_rxon_required(struct iwl_priv *priv)
+int iwl_full_rxon_required(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
+ const struct iwl_rxon_cmd *staging = &ctx->staging;
+ const struct iwl_rxon_cmd *active = &ctx->active;
+
+#define CHK(cond) \
+ if ((cond)) { \
+ IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \
+ return 1; \
+ }
+
+#define CHK_NEQ(c1, c2) \
+ if ((c1) != (c2)) { \
+ IWL_DEBUG_INFO(priv, "need full RXON - " \
+ #c1 " != " #c2 " - %d != %d\n", \
+ (c1), (c2)); \
+ return 1; \
+ }
/* These items are only settable from the full RXON command */
- if (!(iwl_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
+ CHK(!iwl_is_associated_ctx(ctx));
+ CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
+ CHK(compare_ether_addr(staging->node_addr, active->node_addr));
+ CHK(compare_ether_addr(staging->wlap_bssid_addr,
+ active->wlap_bssid_addr));
+ CHK_NEQ(staging->dev_type, active->dev_type);
+ CHK_NEQ(staging->channel, active->channel);
+ CHK_NEQ(staging->air_propagation, active->air_propagation);
+ CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,
+ active->ofdm_ht_single_stream_basic_rates);
+ CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,
+ active->ofdm_ht_dual_stream_basic_rates);
+ CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,
+ active->ofdm_ht_triple_stream_basic_rates);
+ CHK_NEQ(staging->assoc_id, active->assoc_id);
/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
* be updated with the RXON_ASSOC command -- however only some
* flag transitions are allowed using RXON_ASSOC */
/* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
+ CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
+ active->flags & RXON_FLG_BAND_24G_MSK);
/* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
+ CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
+ active->filter_flags & RXON_FILTER_ASSOC_MSK);
+
+#undef CHK
+#undef CHK_NEQ
return 0;
}
EXPORT_SYMBOL(iwl_full_rxon_required);
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
/*
* Assign the lowest rate -- should really get this from
* the beacon skb from mac80211.
*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
return IWL_RATE_1M_PLCP;
else
return IWL_RATE_6M_PLCP;
}
EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
-void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
+static void _iwl_set_rxon_ht(struct iwl_priv *priv,
+ struct iwl_ht_config *ht_conf,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
- if (!ht_conf->is_ht) {
+ if (!ctx->ht.enabled) {
rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
RXON_FLG_HT40_PROT_MSK |
@@ -703,22 +770,22 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
return;
}
- /* FIXME: if the definition of ht_protection changed, the "translation"
+ /* FIXME: if the definition of ht.protection changed, the "translation"
* will be needed for rxon->flags
*/
- rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
+ rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
/* Set up channel bandwidth:
* 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
/* clear the HT channel mode before set the mode */
rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
- if (iwl_is_ht40_tx_allowed(priv, NULL)) {
+ if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
/* pure ht40 */
- if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+ if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
/* Note: control channel is opposite of extension channel */
- switch (ht_conf->extension_chan_offset) {
+ switch (ctx->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
break;
@@ -728,7 +795,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
}
} else {
/* Note: control channel is opposite of extension channel */
- switch (ht_conf->extension_chan_offset) {
+ switch (ctx->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
@@ -749,12 +816,20 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
}
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
"extension channel offset 0x%x\n",
- le32_to_cpu(rxon->flags), ht_conf->ht_protection,
- ht_conf->extension_chan_offset);
+ le32_to_cpu(rxon->flags), ctx->ht.protection,
+ ctx->ht.extension_chan_offset);
+}
+
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
+{
+ struct iwl_rxon_context *ctx;
+
+ for_each_context(priv, ctx)
+ _iwl_set_rxon_ht(priv, ht_conf, ctx);
}
EXPORT_SYMBOL(iwl_set_rxon_ht);
@@ -775,6 +850,14 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
*/
static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
{
+ if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+ /*
+ * only use chain 'A' in bt high traffic load or
+ * full concurrency mode
+ */
+ return IWL_NUM_RX_CHAINS_SINGLE;
+ }
/* # of Rx chains to use when expecting MIMO. */
if (is_single_rx_stream(priv))
return IWL_NUM_RX_CHAINS_SINGLE;
@@ -819,7 +902,7 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
* Selects how many and which Rx receivers/antennas/chains to use.
* This should not be used for scan command ... it puts data in wrong place.
*/
-void iwl_set_rxon_chain(struct iwl_priv *priv)
+void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
bool is_single = is_single_rx_stream(priv);
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
@@ -831,11 +914,20 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
* Before first association, we assume all antennas are connected.
* Just after first association, iwl_chain_noise_calibration()
* checks which antennas actually *are* connected. */
- if (priv->chain_noise_data.active_chains)
+ if (priv->chain_noise_data.active_chains)
active_chains = priv->chain_noise_data.active_chains;
else
active_chains = priv->hw_params.valid_rx_ant;
+ if (priv->cfg->advanced_bt_coexist && (priv->bt_full_concurrent ||
+ priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
+ /*
+ * only use chain 'A' in bt high traffic load or
+ * full concurrency mode
+ */
+ active_chains = first_antenna(active_chains);
+ }
+
rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
/* How many receivers should we use? */
@@ -856,15 +948,15 @@ 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;
- priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
+ ctx->staging.rx_chain = cpu_to_le16(rx_chain);
if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
- priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
else
- priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
- priv->staging_rxon.rx_chain,
+ ctx->staging.rx_chain,
active_rx_cnt, idle_rx_cnt);
WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
@@ -872,39 +964,41 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_set_rxon_chain);
-/* Return valid channel */
+/* Return valid, unused, channel for a passive scan to reset the RF */
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
- enum ieee80211_band band)
+ enum ieee80211_band band)
{
const struct iwl_channel_info *ch_info;
int i;
u8 channel = 0;
+ u8 min, max;
+ struct iwl_rxon_context *ctx;
- /* only scan single channel, good enough to reset the RF */
- /* pick the first valid not in-use channel */
if (band == IEEE80211_BAND_5GHZ) {
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel !=
- le16_to_cpu(priv->staging_rxon.channel)) {
- channel = priv->channel_info[i].channel;
- ch_info = iwl_get_channel_info(priv,
- band, channel);
- if (is_channel_valid(ch_info))
- break;
- }
- }
+ min = 14;
+ max = priv->channel_count;
} else {
- for (i = 0; i < 14; i++) {
- if (priv->channel_info[i].channel !=
- le16_to_cpu(priv->staging_rxon.channel)) {
- channel =
- priv->channel_info[i].channel;
- ch_info = iwl_get_channel_info(priv,
- band, channel);
- if (is_channel_valid(ch_info))
- break;
- }
+ min = 0;
+ max = 14;
+ }
+
+ for (i = min; i < max; i++) {
+ bool busy = false;
+
+ for_each_context(priv, ctx) {
+ busy = priv->channel_info[i].channel ==
+ le16_to_cpu(ctx->staging.channel);
+ if (busy)
+ break;
}
+
+ if (busy)
+ continue;
+
+ channel = priv->channel_info[i].channel;
+ ch_info = iwl_get_channel_info(priv, band, channel);
+ if (is_channel_valid(ch_info))
+ break;
}
return channel;
@@ -912,35 +1006,27 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_get_single_channel_number);
/**
- * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
- * @channel: Any channel valid for the requested phymode
+ * iwl_set_rxon_channel - Set the band and channel values in staging RXON
+ * @ch: requested channel as a pointer to struct ieee80211_channel
- * In addition to setting the staging RXON, priv->phymode is also set.
- *
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the phymode
+ * in the staging RXON flag structure based on the ch->band
*/
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+ struct iwl_rxon_context *ctx)
{
enum ieee80211_band band = ch->band;
- u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
-
- if (!iwl_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n",
- channel, band);
- return -EINVAL;
- }
+ u16 channel = ch->hw_value;
- if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
+ if ((le16_to_cpu(ctx->staging.channel) == channel) &&
(priv->band == band))
return 0;
- priv->staging_rxon.channel = cpu_to_le16(channel);
+ ctx->staging.channel = cpu_to_le16(channel);
if (band == IEEE80211_BAND_5GHZ)
- priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
priv->band = band;
@@ -951,24 +1037,25 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
EXPORT_SYMBOL(iwl_set_rxon_channel);
void iwl_set_flags_for_band(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
| RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from iwl_post_associate() */
if (vif && vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+ ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
+ ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
}
}
EXPORT_SYMBOL(iwl_set_flags_for_band);
@@ -977,35 +1064,34 @@ EXPORT_SYMBOL(iwl_set_flags_for_band);
* initialize rxon structure with default values from eeprom
*/
void iwl_connection_init_rx_config(struct iwl_priv *priv,
- struct ieee80211_vif *vif)
+ struct iwl_rxon_context *ctx)
{
const struct iwl_channel_info *ch_info;
- enum nl80211_iftype type = NL80211_IFTYPE_STATION;
-
- if (vif)
- type = vif->type;
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
+ memset(&ctx->staging, 0, sizeof(ctx->staging));
- switch (type) {
+ if (!ctx->vif) {
+ ctx->staging.dev_type = ctx->unused_devtype;
+ } else switch (ctx->vif->type) {
case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+ ctx->staging.dev_type = ctx->ap_devtype;
break;
case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ ctx->staging.dev_type = ctx->station_devtype;
+ ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
break;
case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+ ctx->staging.dev_type = ctx->ibss_devtype;
+ ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
RXON_FILTER_ACCEPT_GRP_MSK;
break;
default:
- IWL_ERR(priv, "Unsupported interface type %d\n", type);
+ IWL_ERR(priv, "Unsupported interface type %d\n",
+ ctx->vif->type);
break;
}
@@ -1013,37 +1099,36 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
/* TODO: Figure out when short_preamble would be set and cache from
* that */
if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif
ch_info = iwl_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ le16_to_cpu(ctx->active.channel));
if (!ch_info)
ch_info = &priv->channel_info[0];
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+ ctx->staging.channel = cpu_to_le16(ch_info->channel);
priv->band = ch_info->band;
- iwl_set_flags_for_band(priv, priv->band, vif);
+ iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
+ ctx->staging.cck_basic_rates =
(IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
/* clear both MIX and PURE40 mode flag */
- priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
+ ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
RXON_FLG_CHANNEL_MODE_PURE_40);
+ if (ctx->vif)
+ memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
- if (vif)
- memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN);
-
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
- priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
+ ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
}
EXPORT_SYMBOL(iwl_connection_init_rx_config);
@@ -1051,6 +1136,7 @@ void iwl_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
+ struct iwl_rxon_context *ctx;
int i;
hw = iwl_get_hw_mode(priv, priv->band);
@@ -1069,21 +1155,29 @@ void iwl_set_rate(struct iwl_priv *priv)
IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+ for_each_context(priv, ctx) {
+ ctx->staging.cck_basic_rates =
+ (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ ctx->staging.ofdm_basic_rates =
+ (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ }
}
EXPORT_SYMBOL(iwl_set_rate);
void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
if (priv->switch_rxon.switch_in_progress) {
- ieee80211_chswitch_done(priv->vif, is_success);
+ ieee80211_chswitch_done(ctx->vif, is_success);
mutex_lock(&priv->mutex);
priv->switch_rxon.switch_in_progress = false;
mutex_unlock(&priv->mutex);
@@ -1094,14 +1188,19 @@ EXPORT_SYMBOL(iwl_chswitch_done);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+ /*
+ * MULTI-FIXME
+ * See iwl_mac_channel_switch.
+ */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+ struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
if (priv->switch_rxon.switch_in_progress) {
if (!le32_to_cpu(csa->status) &&
(csa->channel == priv->switch_rxon.channel)) {
rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
+ ctx->staging.channel = csa->channel;
IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
le16_to_cpu(csa->channel));
iwl_chswitch_done(priv, true);
@@ -1115,9 +1214,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
EXPORT_SYMBOL(iwl_rx_csa);
#ifdef CONFIG_IWLWIFI_DEBUG
-void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &ctx->staging;
IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -1157,7 +1257,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
- iwl_print_rx_config_cmd(priv);
+ iwl_print_rx_config_cmd(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
#endif
wake_up_interruptible(&priv->wait_command_queue);
@@ -1328,25 +1429,6 @@ out:
EXPORT_SYMBOL(iwl_apm_init);
-int iwl_set_hw_params(struct iwl_priv *priv)
-{
- priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
- priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
- if (priv->cfg->mod_params->amsdu_size_8K)
- priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
- else
- priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
-
- priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
-
- if (priv->cfg->mod_params->disable_11n)
- priv->cfg->sku &= ~IWL_SKU_N;
-
- /* Device-specific setup */
- return priv->cfg->ops->lib->set_hw_params(priv);
-}
-EXPORT_SYMBOL(iwl_set_hw_params);
-
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
@@ -1496,76 +1578,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
}
EXPORT_SYMBOL(iwl_send_statistics_request);
-void iwl_rf_kill_ct_config(struct iwl_priv *priv)
-{
- struct iwl_ct_kill_config cmd;
- struct iwl_ct_kill_throttling_config adv_cmd;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- spin_unlock_irqrestore(&priv->lock, flags);
- priv->thermal_throttle.ct_kill_toggle = false;
-
- if (priv->cfg->support_ct_kill_exit) {
- adv_cmd.critical_temperature_enter =
- cpu_to_le32(priv->hw_params.ct_kill_threshold);
- adv_cmd.critical_temperature_exit =
- cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
-
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(adv_cmd), &adv_cmd);
- if (ret)
- IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
- "succeeded, "
- "critical temperature enter is %d,"
- "exit is %d\n",
- priv->hw_params.ct_kill_threshold,
- priv->hw_params.ct_kill_exit_threshold);
- } else {
- cmd.critical_temperature_R =
- cpu_to_le32(priv->hw_params.ct_kill_threshold);
-
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
- "succeeded, "
- "critical temperature is %d\n",
- priv->hw_params.ct_kill_threshold);
- }
-}
-EXPORT_SYMBOL(iwl_rf_kill_ct_config);
-
-
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .flags = meta_flag,
- };
-
- return iwl_send_cmd(priv, &cmd);
-}
-
void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -1614,6 +1626,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx;
unsigned long flags;
int q;
@@ -1633,13 +1646,21 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
+ /*
+ * MULTI-FIXME
+ * This may need to be done per interface in nl80211/cfg80211/mac80211.
+ */
+ for_each_context(priv, ctx) {
+ ctx->qos_data.def_qos_parm.ac[q].cw_min =
+ cpu_to_le16(params->cw_min);
+ ctx->qos_data.def_qos_parm.ac[q].cw_max =
+ cpu_to_le16(params->cw_max);
+ ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+ ctx->qos_data.def_qos_parm.ac[q].edca_txop =
+ cpu_to_le16((params->txop * 32));
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ }
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1648,21 +1669,30 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
}
EXPORT_SYMBOL(iwl_mac_conf_tx);
+int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
+{
+ struct iwl_priv *priv = hw->priv;
+
+ return priv->ibss_manager == IWL_IBSS_MANAGER;
+}
+EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
+
static void iwl_ht_conf(struct iwl_priv *priv,
struct ieee80211_vif *vif)
{
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
IWL_DEBUG_MAC80211(priv, "enter:\n");
- if (!ht_conf->is_ht)
+ if (!ctx->ht.enabled)
return;
- ht_conf->ht_protection =
+ ctx->ht.protection =
bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- ht_conf->non_GF_STA_present =
+ ctx->ht.non_gf_sta_present =
!!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
ht_conf->single_chain_sufficient = false;
@@ -1706,18 +1736,20 @@ static void iwl_ht_conf(struct iwl_priv *priv,
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static inline void iwl_set_no_assoc(struct iwl_priv *priv)
+static inline void iwl_set_no_assoc(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
iwl_led_disassociate(priv);
/*
* inform the ucode that there is no longer an
* association and that no more packets should be
* sent
*/
- priv->staging_rxon.filter_flags &=
- ~RXON_FILTER_ASSOC_MSK;
- priv->staging_rxon.assoc_id = 0;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ ctx->staging.assoc_id = 0;
+ iwlcore_commit_rxon(priv, ctx);
}
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -1728,6 +1760,14 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211(priv, "enter\n");
+ lockdep_assert_held(&priv->mutex);
+
+ if (!priv->beacon_ctx) {
+ IWL_ERR(priv, "update beacon but no beacon context!\n");
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
@@ -1746,7 +1786,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
- priv->cfg->ops->lib->post_associate(priv, priv->vif);
+ priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
return 0;
}
@@ -1757,6 +1797,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
int ret;
IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
@@ -1770,19 +1811,30 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = bss_conf->qos;
- iwl_update_qos(priv);
+ ctx->qos_data.qos_active = bss_conf->qos;
+ iwl_update_qos(priv, ctx);
spin_unlock_irqrestore(&priv->lock, flags);
}
+ if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ /*
+ * the add_interface code must make sure we only ever
+ * have a single interface that could be beaconing at
+ * any time.
+ */
+ if (vif->bss_conf.enable_beacon)
+ priv->beacon_ctx = ctx;
+ else
+ priv->beacon_ctx = NULL;
+ }
+
if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
dev_kfree_skb(priv->ibss_beacon);
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
- if (changes & BSS_CHANGED_BEACON_INT) {
- /* TODO: in AP mode, do something to make this take effect */
- }
+ if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
+ iwl_send_rxon_timing(priv, ctx);
if (changes & BSS_CHANGED_BSSID) {
IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
@@ -1801,13 +1853,13 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
/* mac80211 only sets assoc when in STATION mode */
if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
- memcpy(priv->staging_rxon.bssid_addr,
+ memcpy(ctx->staging.bssid_addr,
bss_conf->bssid, ETH_ALEN);
/* currently needed in a few places */
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
} else {
- priv->staging_rxon.filter_flags &=
+ ctx->staging.filter_flags &=
~RXON_FILTER_ASSOC_MSK;
}
@@ -1830,21 +1882,21 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
if (bss_conf->use_cts_prot)
- priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+ ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+ ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
}
if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -1854,12 +1906,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
* like this here:
*
if (A-band)
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
bss_conf->basic_rates;
else
- priv->staging_rxon.ofdm_basic_rates =
+ ctx->staging.ofdm_basic_rates =
bss_conf->basic_rates >> 4;
- priv->staging_rxon.cck_basic_rates =
+ ctx->staging.cck_basic_rates =
bss_conf->basic_rates & 0xF;
*/
}
@@ -1868,7 +1920,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
iwl_ht_conf(priv, vif);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
if (changes & BSS_CHANGED_ASSOC) {
@@ -1881,29 +1933,29 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
if (!iwl_is_rfkill(priv))
priv->cfg->ops->lib->post_associate(priv, vif);
} else
- iwl_set_no_assoc(priv);
+ iwl_set_no_assoc(priv, vif);
}
- if (changes && iwl_is_associated(priv) && bss_conf->aid) {
+ if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
changes);
- ret = iwl_send_rxon_assoc(priv);
+ ret = iwl_send_rxon_assoc(priv, ctx);
if (!ret) {
/* Sync active_rxon with latest change. */
- memcpy((void *)&priv->active_rxon,
- &priv->staging_rxon,
+ memcpy((void *)&ctx->active,
+ &ctx->staging,
sizeof(struct iwl_rxon_cmd));
}
}
if (changes & BSS_CHANGED_BEACON_ENABLED) {
if (vif->bss_conf.enable_beacon) {
- memcpy(priv->staging_rxon.bssid_addr,
+ memcpy(ctx->staging.bssid_addr,
bss_conf->bssid, ETH_ALEN);
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
iwlcore_config_ap(priv, vif);
} else
- iwl_set_no_assoc(priv);
+ iwl_set_no_assoc(priv, vif);
}
if (changes & BSS_CHANGED_IBSS) {
@@ -1915,6 +1967,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->bssid);
}
+ if (changes & BSS_CHANGED_IDLE &&
+ priv->cfg->ops->hcmd->set_pan_params) {
+ if (priv->cfg->ops->hcmd->set_pan_params(priv))
+ IWL_ERR(priv, "failed to update PAN params\n");
+ }
+
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1923,17 +1981,21 @@ EXPORT_SYMBOL(iwl_bss_info_changed);
static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
- iwl_connection_init_rx_config(priv, vif);
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+
+ iwl_connection_init_rx_config(priv, ctx);
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
- return iwlcore_commit_rxon(priv);
+ return iwlcore_commit_rxon(priv, ctx);
}
int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+ struct iwl_rxon_context *tmp, *ctx = NULL;
int err = 0;
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
@@ -1946,23 +2008,65 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;
}
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
+ for_each_context(priv, tmp) {
+ u32 possible_modes =
+ tmp->interface_modes | tmp->exclusive_interface_modes;
+
+ if (tmp->vif) {
+ /* check if this busy context is exclusive */
+ if (tmp->exclusive_interface_modes &
+ BIT(tmp->vif->type)) {
+ err = -EINVAL;
+ goto out;
+ }
+ continue;
+ }
+
+ if (!(possible_modes & BIT(vif->type)))
+ continue;
+
+ /* have maybe usable context w/o interface */
+ ctx = tmp;
+ break;
+ }
+
+ if (!ctx) {
err = -EOPNOTSUPP;
goto out;
}
- priv->vif = vif;
+ vif_priv->ctx = ctx;
+ ctx->vif = vif;
+ /*
+ * This variable will be correct only when there's just
+ * a single context, but all code using it is for hardware
+ * that supports only one context.
+ */
priv->iw_mode = vif->type;
+ ctx->is_active = true;
+
err = iwl_set_mode(priv, vif);
- if (err)
+ if (err) {
+ if (!ctx->always_active)
+ ctx->is_active = false;
goto out_err;
+ }
+
+ if (priv->cfg->advanced_bt_coexist &&
+ vif->type == NL80211_IFTYPE_ADHOC) {
+ /*
+ * pretend to have high BT traffic as long as we
+ * are operating in IBSS mode, as this will cause
+ * the rate scaling etc. to behave as intended.
+ */
+ priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ }
goto out;
out_err:
- priv->vif = NULL;
+ ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION;
out:
mutex_unlock(&priv->mutex);
@@ -1976,30 +2080,36 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
- bool scan_completed = false;
+ struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
- }
- if (priv->vif == vif) {
- priv->vif = NULL;
- if (priv->scan_vif == vif) {
- scan_completed = true;
- priv->scan_vif = NULL;
- priv->scan_request = NULL;
- }
- memset(priv->bssid, 0, ETH_ALEN);
+ WARN_ON(ctx->vif != vif);
+ ctx->vif = NULL;
+
+ if (priv->scan_vif == vif) {
+ iwl_scan_cancel_timeout(priv, 200);
+ iwl_force_scan_end(priv);
}
- mutex_unlock(&priv->mutex);
+ iwl_set_mode(priv, vif);
+
+ if (!ctx->always_active)
+ ctx->is_active = false;
+
+ /*
+ * When removing the IBSS interface, overwrite the
+ * BT traffic load with the stored one from the last
+ * notification, if any. If this is a device that
+ * doesn't implement this, this has no effect since
+ * both values are the same and zero.
+ */
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ priv->bt_traffic_load = priv->notif_bt_traffic_load;
- if (scan_completed)
- ieee80211_scan_completed(priv->hw, true);
+ memset(priv->bssid, 0, ETH_ALEN);
+ mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2014,7 +2124,9 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
+ struct ieee80211_channel *channel = conf->channel;
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+ struct iwl_rxon_context *ctx;
unsigned long flags = 0;
int ret = 0;
u16 ch;
@@ -2023,7 +2135,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
- conf->channel->hw_value, changed);
+ channel->hw_value, changed);
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
@@ -2044,7 +2156,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
* configured.
*/
if (priv->cfg->ops->hcmd->set_rxon_chain)
- priv->cfg->ops->hcmd->set_rxon_chain(priv);
+ for_each_context(priv, ctx)
+ priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
}
/* during scanning mac80211 will delay channel setting until
@@ -2054,8 +2167,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (scan_active)
goto set_ch_out;
- ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+ ch = channel->hw_value;
+ ch_info = iwl_get_channel_info(priv, channel->band, ch);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
ret = -EINVAL;
@@ -2064,42 +2177,49 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&priv->lock, flags);
- /* Configure HT40 channels */
- ht_conf->is_ht = conf_is_ht(conf);
- if (ht_conf->is_ht) {
- if (conf_is_ht40_minus(conf)) {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ht_conf->is_40mhz = true;
- } else if (conf_is_ht40_plus(conf)) {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ht_conf->is_40mhz = true;
- } else {
- ht_conf->extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ht_conf->is_40mhz = false;
- }
- } else
- ht_conf->is_40mhz = false;
- /* Default to no protection. Protection mode will later be set
- * from BSS config in iwl_ht_conf */
- ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+ for_each_context(priv, ctx) {
+ /* Configure HT40 channels */
+ ctx->ht.enabled = conf_is_ht(conf);
+ if (ctx->ht.enabled) {
+ if (conf_is_ht40_minus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ ctx->ht.is_40mhz = true;
+ } else if (conf_is_ht40_plus(conf)) {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ ctx->ht.is_40mhz = true;
+ } else {
+ ctx->ht.extension_chan_offset =
+ IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ ctx->ht.is_40mhz = false;
+ }
+ } else
+ ctx->ht.is_40mhz = false;
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
- priv->staging_rxon.flags = 0;
+ /*
+ * Default to no protection. Protection mode will
+ * later be set from BSS config in iwl_ht_conf
+ */
+ ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(ctx->staging.channel) != ch))
+ ctx->staging.flags = 0;
- iwl_set_rxon_channel(priv, conf->channel);
- iwl_set_rxon_ht(priv, ht_conf);
+ iwl_set_rxon_channel(priv, channel, ctx);
+ iwl_set_rxon_ht(priv, ht_conf);
+
+ iwl_set_flags_for_band(priv, ctx, channel->band,
+ ctx->vif);
+ }
- iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
spin_unlock_irqrestore(&priv->lock, flags);
- if (priv->cfg->ops->lib->update_bcast_station)
- ret = priv->cfg->ops->lib->update_bcast_station(priv);
+ if (priv->cfg->ops->lib->update_bcast_stations)
+ ret = priv->cfg->ops->lib->update_bcast_stations(priv);
set_ch_out:
/* The list of supported rates and rate mask can be different
@@ -2130,12 +2250,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (scan_active)
goto out;
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwlcore_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n");
-
+ for_each_context(priv, ctx) {
+ if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
+ iwlcore_commit_rxon(priv, ctx);
+ else
+ IWL_DEBUG_INFO(priv,
+ "Not re-sending same RXON configuration.\n");
+ }
out:
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2148,6 +2269,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ /* IBSS can only be the IWL_RXON_CTX_BSS context */
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -2168,6 +2291,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_scan_cancel_timeout(priv, 100);
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
@@ -2177,9 +2301,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
/* we are restarting association process
* clear RXON_FILTER_ASSOC_MSK bit
*/
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
iwl_set_rate(priv);
@@ -2588,7 +2711,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (!iwl_is_associated(priv)) {
+ if (!iwl_is_any_associated(priv)) {
IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
return;
}
@@ -2714,10 +2837,14 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
"queue %d, not read %d time\n",
q->id,
q->repeat_same_read_ptr);
- mod_timer(&priv->monitor_recover, jiffies +
- msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
+ if (!priv->cfg->advanced_bt_coexist) {
+ mod_timer(&priv->monitor_recover,
+ jiffies + msecs_to_jiffies(
+ IWL_ONE_HUNDRED_MSECS));
+ return 1;
+ }
}
- return 1;
+ return 0;
} else {
q->last_read_ptr = q->read_ptr;
q->repeat_same_read_ptr = 0;
@@ -2735,25 +2862,27 @@ void iwl_bg_monitor_recover(unsigned long data)
return;
/* monitor and check for stuck cmd queue */
- if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
+ if (iwl_check_stuck_queue(priv, priv->cmd_queue))
return;
/* monitor and check for other stuck queues */
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
/* skip as we already checked the command queue */
- if (cnt == IWL_CMD_QUEUE_NUM)
+ if (cnt == priv->cmd_queue)
continue;
if (iwl_check_stuck_queue(priv, cnt))
return;
}
}
- /*
- * Reschedule the timer to occur in
- * priv->cfg->monitor_recover_period
- */
- mod_timer(&priv->monitor_recover,
- jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
+ if (priv->cfg->monitor_recover_period) {
+ /*
+ * Reschedule the timer to occur in
+ * priv->cfg->monitor_recover_period
+ */
+ mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
+ priv->cfg->monitor_recover_period));
+ }
}
EXPORT_SYMBOL(iwl_bg_monitor_recover);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5e6ee3da6bbf..f1d40c6173c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -88,11 +88,13 @@ struct iwl_cmd;
#define IWL_CMD(x) case x: return #x
struct iwl_hcmd_ops {
- int (*rxon_assoc)(struct iwl_priv *priv);
- int (*commit_rxon)(struct iwl_priv *priv);
- void (*set_rxon_chain)(struct iwl_priv *priv);
+ int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+ int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+ void (*set_rxon_chain)(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
void (*send_bt_config)(struct iwl_priv *priv);
+ int (*set_pan_params)(struct iwl_priv *priv);
};
struct iwl_hcmd_utils_ops {
@@ -109,7 +111,7 @@ struct iwl_hcmd_utils_ops {
__le16 fc, __le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
- void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+ int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
};
struct iwl_apm_ops {
@@ -136,6 +138,12 @@ struct iwl_temp_ops {
void (*set_calib_version)(struct iwl_priv *priv);
};
+struct iwl_tt_ops {
+ bool (*lower_power_detection)(struct iwl_priv *priv);
+ u8 (*tt_power_mode)(struct iwl_priv *priv);
+ bool (*ct_kill_check)(struct iwl_priv *priv);
+};
+
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
@@ -199,7 +207,7 @@ struct iwl_lib_ops {
/* station management */
int (*manage_ibss_station)(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
- int (*update_bcast_station)(struct iwl_priv *priv);
+ int (*update_bcast_stations)(struct iwl_priv *priv);
/* recover from tx queue stall */
void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
@@ -212,6 +220,9 @@ struct iwl_lib_ops {
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
struct iwl_debugfs_ops debugfs_ops;
+
+ /* thermal throttling */
+ struct iwl_tt_ops tt_ops;
};
struct iwl_led_ops {
@@ -269,6 +280,14 @@ struct iwl_mod_params {
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
* @scan_antennas: available antenna for scan operation
+ * @advanced_bt_coexist: support advanced bt coexist
+ * @bt_init_traffic_load: specify initial bt traffic load
+ * @bt_prio_boost: default bt priority boost value
+ * @need_dc_calib: need to perform init dc calibration
+ * @bt_statistics: use BT version of statistics notification
+ * @agg_time_limit: maximum number of uSec in aggregation
+ * @ampdu_factor: Maximum A-MPDU length factor
+ * @ampdu_density: Minimum A-MPDU spacing
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -337,8 +356,14 @@ struct iwl_cfg {
const bool chain_noise_calib_by_driver;
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
+ bool advanced_bt_coexist;
+ u8 bt_init_traffic_load;
+ u8 bt_prio_boost;
const bool need_dc_calib;
const bool bt_statistics;
+ u16 agg_time_limit;
+ u8 ampdu_factor;
+ u8 ampdu_density;
};
/***************************
@@ -347,38 +372,41 @@ struct iwl_cfg {
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
-void iwl_hw_detect(struct iwl_priv *priv);
void iwl_activate_qos(struct iwl_priv *priv);
int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
-void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
-int iwl_check_rxon_cmd(struct iwl_priv *priv);
-int iwl_full_rxon_required(struct iwl_priv *priv);
-void iwl_set_rxon_chain(struct iwl_priv *priv);
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
+int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+ struct iwl_rxon_context *ctx);
void iwl_set_flags_for_band(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
enum ieee80211_band band,
struct ieee80211_vif *vif);
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
enum ieee80211_band band);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
-u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_sta_ht_cap *sta_ht_inf);
+bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_sta_ht_cap *ht_cap);
void iwl_connection_init_rx_config(struct iwl_priv *priv,
- struct ieee80211_vif *vif);
+ struct iwl_rxon_context *ctx);
void iwl_set_rate(struct iwl_priv *priv);
int iwl_set_decrypted_flag(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
void iwl_irq_handle_error(struct iwl_priv *priv);
-int iwl_set_hw_params(struct iwl_priv *priv);
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-int iwl_commit_rxon(struct iwl_priv *priv);
+int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -496,7 +524,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
@@ -524,10 +553,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
+void iwl_force_scan_end(struct iwl_priv *priv);
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
-void iwl_bg_start_internal_scan(struct work_struct *work);
void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
@@ -539,10 +568,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_vif *vif);
-void iwl_bg_scan_check(struct work_struct *data);
-void iwl_bg_abort_scan(struct work_struct *work);
-void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
/* For faster active scanning, scan will move to the next channel if fewer than
* PLCP_QUIET_THRESH packets are heard on this channel within
@@ -580,8 +607,6 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
- u8 meta_flag);
/*****************************************************
* PCI *
@@ -616,9 +641,11 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv,
void iwl_dump_csr(struct iwl_priv *priv);
int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
#ifdef CONFIG_IWLWIFI_DEBUG
-void iwl_print_rx_config_cmd(struct iwl_priv *priv);
+void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
#else
-static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
}
#endif
@@ -695,23 +722,24 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}
-extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern void iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv,
u8 flags, bool clear);
-extern int iwl_send_lq_cmd(struct iwl_priv *priv,
+extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init);
void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);
-void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
-static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
+int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- return priv->cfg->ops->hcmd->rxon_assoc(priv);
+ return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
}
-static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
+static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
- return priv->cfg->ops->hcmd->commit_rxon(priv);
+ return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
}
static inline void iwlcore_config_ap(struct iwl_priv *priv,
struct ieee80211_vif *vif)
@@ -723,4 +751,8 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
{
return priv->hw->wiphy->bands[band];
}
+
+extern bool bt_coex_active;
+extern bool bt_siso_mode;
+
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index e96a1bb12783..143d6706aaf6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -87,6 +87,7 @@ static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.read = iwl_dbgfs_##name##_read, \
.open = iwl_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_WRITE_FILE_OPS(name) \
@@ -94,6 +95,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
.open = iwl_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
@@ -104,6 +106,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = iwl_dbgfs_##name##_write, \
.read = iwl_dbgfs_##name##_read, \
.open = iwl_dbgfs_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
@@ -467,8 +470,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
"%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
+ channels[i].hw_value,
channels[i].max_power,
channels[i].flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
@@ -491,8 +493,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
for (i = 0; i < supp_band->n_channels; i++)
pos += scnprintf(buf + pos, bufsz - pos,
"%d: %ddBm: BSS%s%s, %s.\n",
- ieee80211_frequency_to_channel(
- channels[i].center_freq),
+ channels[i].hw_value,
channels[i].max_power,
channels[i].flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
@@ -577,10 +578,10 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
priv->isr_stats.hw);
pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
priv->isr_stats.sw);
- if (priv->isr_stats.sw > 0) {
+ if (priv->isr_stats.sw || priv->isr_stats.hw) {
pos += scnprintf(buf + pos, bufsz - pos,
"\tLast Restarting Code: 0x%X\n",
- priv->isr_stats.sw_err);
+ priv->isr_stats.err_code);
}
#ifdef CONFIG_IWLWIFI_DEBUG
pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
@@ -645,19 +646,25 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
+ struct iwl_rxon_context *ctx;
int pos = 0, i;
- char buf[256];
+ char buf[256 * NUM_IWL_RXON_CTX];
const size_t bufsz = sizeof(buf);
- for (i = 0; i < AC_NUM; i++) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tcw_min\tcw_max\taifsn\ttxop\n");
- pos += scnprintf(buf + pos, bufsz - pos,
+ for_each_context(priv, ctx) {
+ pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
+ ctx->ctxid);
+ for (i = 0; i < AC_NUM; i++) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tcw_min\tcw_max\taifsn\ttxop\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
"AC[%d]\t%u\t%u\t%u\t%u\n", i,
- priv->qos_data.def_qos_parm.ac[i].cw_min,
- priv->qos_data.def_qos_parm.ac[i].cw_max,
- priv->qos_data.def_qos_parm.ac[i].aifsn,
- priv->qos_data.def_qos_parm.ac[i].edca_txop);
+ ctx->qos_data.def_qos_parm.ac[i].cw_min,
+ ctx->qos_data.def_qos_parm.ac[i].cw_max,
+ ctx->qos_data.def_qos_parm.ac[i].aifsn,
+ ctx->qos_data.def_qos_parm.ac[i].edca_txop);
+ }
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -732,7 +739,7 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
return -EFAULT;
if (sscanf(buf, "%d", &ht40) != 1)
return -EFAULT;
- if (!iwl_is_associated(priv))
+ if (!iwl_is_any_associated(priv))
priv->disable_ht40 = ht40 ? true : false;
else {
IWL_ERR(priv, "Sta associated with AP - "
@@ -1321,7 +1328,8 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
int len = 0;
char buf[20];
- len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
+ len = sprintf(buf, "0x%04X\n",
+ le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1334,7 +1342,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
char buf[20];
len = sprintf(buf, "0x%04X\n",
- le32_to_cpu(priv->active_rxon.filter_flags));
+ le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1529,6 +1537,114 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
user_buf, count, ppos);
}
+static ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ int period;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &period) != 1)
+ return -EINVAL;
+ if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
+ priv->cfg->monitor_recover_period = IWL_DEF_MONITORING_PERIOD;
+ else
+ priv->cfg->monitor_recover_period = period;
+
+ if (priv->cfg->monitor_recover_period)
+ mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
+ priv->cfg->monitor_recover_period));
+ else
+ del_timer_sync(&priv->monitor_recover);
+ return count;
+}
+
+static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char buf[200];
+ const size_t bufsz = sizeof(buf);
+ ssize_t ret;
+
+ pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
+ priv->bt_full_concurrent ? "full concurrency" : "3-wire");
+ pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
+ "last traffic notif: %d\n",
+ priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load);
+ pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
+ "sco_active: %d, kill_ack_mask: %x, "
+ "kill_cts_mask: %x\n",
+ priv->bt_ch_announce, priv->bt_sco_active,
+ priv->kill_ack_mask, priv->kill_cts_mask);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: ");
+ switch (priv->bt_traffic_load) {
+ case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+ pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+ pos += scnprintf(buf + pos, bufsz - pos, "High\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+ pos += scnprintf(buf + pos, bufsz - pos, "Low\n");
+ break;
+ case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+ default:
+ pos += scnprintf(buf + pos, bufsz - pos, "None\n");
+ break;
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+
+ int pos = 0;
+ char buf[40];
+ const size_t bufsz = sizeof(buf);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n",
+ (priv->cfg->use_rts_for_aggregation) ? "rts/cts" :
+ "cts-to-self");
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ int rts;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &rts) != 1)
+ return -EINVAL;
+ if (rts)
+ priv->cfg->use_rts_for_aggregation = true;
+ else
+ priv->cfg->use_rts_for_aggregation = false;
+ return count;
+}
+
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1552,6 +1668,9 @@ DEBUGFS_READ_FILE_OPS(rxon_flags);
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
+DEBUGFS_WRITE_FILE_OPS(monitor_period);
+DEBUGFS_READ_FILE_OPS(bt_traffic);
+DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
/*
* Create the debugfs files and directories
@@ -1612,6 +1731,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
if (priv->cfg->ops->lib->dev_txfifo_flush)
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
+ DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
if (priv->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
@@ -1623,6 +1743,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
+ DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
+ if (priv->cfg->advanced_bt_coexist)
+ DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
if (priv->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
&priv->disable_sens_cal);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2e97cd2fa98a..4e3a69271e34 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -47,6 +47,7 @@
#include "iwl-led.h"
#include "iwl-power.h"
#include "iwl-agn-rs.h"
+#include "iwl-agn-tt.h"
struct iwl_tx_queue;
@@ -143,6 +144,7 @@ struct iwl_queue {
/* One for each TFD */
struct iwl_tx_info {
struct sk_buff *skb;
+ struct iwl_rxon_context *ctx;
};
/**
@@ -252,10 +254,14 @@ struct iwl_channel_info {
struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};
-#define IWL_TX_FIFO_BK 0
+#define IWL_TX_FIFO_BK 0 /* shared */
#define IWL_TX_FIFO_BE 1
-#define IWL_TX_FIFO_VI 2
+#define IWL_TX_FIFO_VI 2 /* shared */
#define IWL_TX_FIFO_VO 3
+#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK
+#define IWL_TX_FIFO_BE_IPAN 4
+#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI
+#define IWL_TX_FIFO_VO_IPAN 5
#define IWL_TX_FIFO_UNUSED -1
/* Minimum number of queues. MAX_NUM is defined in hw specific files.
@@ -264,11 +270,17 @@ struct iwl_channel_info {
#define IWL_MIN_NUM_QUEUES 10
/*
- * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00,
- * the driver maps it into the appropriate device FIFO for the
- * uCode.
+ * Command queue depends on iPAN support.
*/
-#define IWL_CMD_QUEUE_NUM 4
+#define IWL_DEFAULT_CMD_QUEUE_NUM 4
+#define IWL_IPAN_CMD_QUEUE_NUM 9
+
+/*
+ * This queue number is required for proper operation
+ * because the ucode will stop/start the scheduler as
+ * required.
+ */
+#define IWL_IPAN_MCAST_QUEUE 8
/* Power management (not Tx power) structures */
@@ -420,7 +432,7 @@ struct iwl_tid_data {
};
struct iwl_hw_key {
- enum ieee80211_key_alg alg;
+ u32 cipher;
int keylen;
u8 keyidx;
u8 key[32];
@@ -434,7 +446,13 @@ union iwl_ht_rate_supp {
};
};
-#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3)
+#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0)
+#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1)
+#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2)
+#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3)
+#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K
+#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K
+#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K
/*
* Maximal MPDU density for TX aggregation
@@ -443,19 +461,17 @@ union iwl_ht_rate_supp {
* 6 - 8us density
* 7 - 16us density
*/
+#define CFG_HT_MPDU_DENSITY_2USEC (0x4)
#define CFG_HT_MPDU_DENSITY_4USEC (0x5)
+#define CFG_HT_MPDU_DENSITY_8USEC (0x6)
+#define CFG_HT_MPDU_DENSITY_16USEC (0x7)
#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
+#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC
+#define CFG_HT_MPDU_DENSITY_MIN (0x1)
struct iwl_ht_config {
- /* self configuration data */
- bool is_ht;
- bool is_40mhz;
bool single_chain_sufficient;
enum ieee80211_smps_mode smps; /* current smps mode */
- /* BSS related data */
- u8 extension_chan_offset;
- u8 ht_protection;
- u8 non_GF_STA_present;
};
/* QoS structures */
@@ -473,12 +489,13 @@ struct iwl_qos_info {
struct iwl_station_entry {
struct iwl_addsta_cmd sta;
struct iwl_tid_data tid[MAX_TID_COUNT];
- u8 used;
+ u8 used, ctxid;
struct iwl_hw_key keyinfo;
struct iwl_link_quality_cmd *lq;
};
struct iwl_station_priv_common {
+ struct iwl_rxon_context *ctx;
u8 sta_id;
};
@@ -507,6 +524,7 @@ struct iwl_station_priv {
* space for us to put data into.
*/
struct iwl_vif_priv {
+ struct iwl_rxon_context *ctx;
u8 ibss_bssid_sta_id;
};
@@ -564,6 +582,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INIT_DATA = 4,
IWL_UCODE_TLV_BOOT = 5,
IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
+ IWL_UCODE_TLV_PAN = 7,
IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
@@ -658,7 +677,6 @@ struct iwl_sensitivity_ranges {
* @rx_page_order: Rx buffer page order
* @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
- * @bcast_sta_id:
* @ht40_channel: is 40MHz width possible in band 2.4
* BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ)
* @sw_crypto: 0 for hw, 1 for sw
@@ -682,7 +700,6 @@ struct iwl_hw_params {
u32 rx_page_order;
u32 rx_wrt_ptr_reg;
u8 max_stations;
- u8 bcast_sta_id;
u8 ht40_channel;
u8 max_beacon_itrvl; /* in 1024 ms */
u32 max_inst_size;
@@ -928,7 +945,7 @@ enum iwl_pa_type {
struct isr_statistics {
u32 hw;
u32 sw;
- u32 sw_err;
+ u32 err_code;
u32 sch;
u32 alive;
u32 rfkill;
@@ -1052,7 +1069,10 @@ struct iwl_event_log {
#define IWL_DEF_MONITORING_PERIOD (1000)
#define IWL_LONG_MONITORING_PERIOD (5000)
#define IWL_ONE_HUNDRED_MSECS (100)
-#define IWL_SIXTY_SECS (60000)
+#define IWL_MAX_MONITORING_PERIOD (60000)
+
+/* BT Antenna Coupling Threshold (dB) */
+#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
enum iwl_reset {
IWL_RF_RESET = 0,
@@ -1082,6 +1102,64 @@ struct iwl_force_reset {
*/
#define IWLAGN_EXT_BEACON_TIME_POS 22
+enum iwl_rxon_context_id {
+ IWL_RXON_CTX_BSS,
+ IWL_RXON_CTX_PAN,
+
+ NUM_IWL_RXON_CTX
+};
+
+struct iwl_rxon_context {
+ struct ieee80211_vif *vif;
+
+ const u8 *ac_to_fifo;
+ const u8 *ac_to_queue;
+ u8 mcast_queue;
+
+ /*
+ * We could use the vif to indicate active, but we
+ * also need it to be active during disabling when
+ * we already removed the vif for type setting.
+ */
+ bool always_active, is_active;
+
+ enum iwl_rxon_context_id ctxid;
+
+ u32 interface_modes, exclusive_interface_modes;
+ u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
+
+ /*
+ * We declare this const so it can only be
+ * changed via explicit cast within the
+ * routines that actually update the physical
+ * hardware.
+ */
+ const struct iwl_rxon_cmd active;
+ struct iwl_rxon_cmd staging;
+
+ struct iwl_rxon_time_cmd timing;
+
+ struct iwl_qos_info qos_data;
+
+ u8 bcast_sta_id, ap_sta_id;
+
+ u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
+ u8 qos_cmd;
+ u8 wep_key_cmd;
+
+ struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
+ u8 key_mapping_keys;
+
+ __le32 station_flags;
+
+ struct {
+ bool non_gf_sta_present;
+ u8 protection;
+ bool enabled, is_40mhz;
+ u8 extension_chan_offset;
+ } ht;
+};
+
struct iwl_priv {
/* ieee device used by generic ieee processing code */
@@ -1110,6 +1188,9 @@ struct iwl_priv {
u32 ucode_beacon_time;
int missed_beacon_threshold;
+ /* track IBSS manager (last beacon) status */
+ u32 ibss_manager;
+
/* storing the jiffies when the plcp error rate is received */
unsigned long plcp_jiffies;
@@ -1155,6 +1236,15 @@ struct iwl_priv {
u32 hw_wa_rev;
u8 rev_id;
+ /* microcode/device supports multiple contexts */
+ u8 valid_contexts;
+
+ /* command queue number */
+ u8 cmd_queue;
+
+ /* max number of station keys */
+ u8 sta_key_max_num;
+
/* EEPROM MAC addresses */
struct mac_address addresses[2];
@@ -1172,15 +1262,7 @@ struct iwl_priv {
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
-
- struct iwl_rxon_time_cmd rxon_timing;
-
- /* We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware */
- const struct iwl_rxon_cmd active_rxon;
- struct iwl_rxon_cmd staging_rxon;
+ struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
struct iwl_switch_rxon switch_rxon;
@@ -1242,8 +1324,6 @@ struct iwl_priv {
spinlock_t sta_lock;
int num_stations;
struct iwl_station_entry stations[IWL_STATION_COUNT];
- struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
- u8 key_mapping_key;
unsigned long ucode_key_table;
/* queue refcounts */
@@ -1268,7 +1348,6 @@ struct iwl_priv {
/* Last Rx'd beacon timestamp */
u64 timestamp;
- struct ieee80211_vif *vif;
union {
#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
@@ -1348,12 +1427,27 @@ struct iwl_priv {
#endif
};
+ /* bt coex */
+ u8 bt_status;
+ u8 bt_traffic_load, notif_bt_traffic_load;
+ bool bt_ch_announce;
+ bool bt_sco_active;
+ bool bt_full_concurrent;
+ bool bt_ant_couple_ok;
+ __le32 kill_ack_mask;
+ __le32 kill_cts_mask;
+ __le16 bt_valid;
+ u16 bt_on_thresh;
+ u16 bt_duration;
+ u16 dynamic_frag_thresh;
+ u16 dynamic_agg_thresh;
+ u8 bt_ci_compliance;
+ struct work_struct bt_traffic_change_work;
+
struct iwl_hw_params hw_params;
u32 inta_mask;
- struct iwl_qos_info qos_data;
-
struct workqueue_struct *workqueue;
struct work_struct restart;
@@ -1361,11 +1455,15 @@ struct iwl_priv {
struct work_struct rx_replenish;
struct work_struct abort_scan;
struct work_struct beacon_update;
+ struct iwl_rxon_context *beacon_ctx;
+
struct work_struct tt_work;
struct work_struct ct_enter;
struct work_struct ct_exit;
struct work_struct start_internal_scan;
struct work_struct tx_flush;
+ struct work_struct bt_full_concurrency;
+ struct work_struct bt_runtime_config;
struct tasklet_struct irq_tasklet;
@@ -1453,10 +1551,34 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
return NULL;
}
+static inline struct iwl_rxon_context *
+iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
+{
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+
+ return vif_priv->ctx;
+}
+
+#define for_each_context(priv, ctx) \
+ for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \
+ ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
+ if (priv->valid_contexts & BIT(ctx->ctxid))
+
+static inline int iwl_is_associated(struct iwl_priv *priv,
+ enum iwl_rxon_context_id ctxid)
+{
+ return (priv->contexts[ctxid].active.filter_flags &
+ RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+}
+
+static inline int iwl_is_any_associated(struct iwl_priv *priv)
+{
+ return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
+}
-static inline int iwl_is_associated(struct iwl_priv *priv)
+static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
{
- return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 258d059ef41f..c373b53babea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -97,6 +97,17 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_TX_POWER_DBM_CMD);
IWL_CMD(TEMPERATURE_NOTIFICATION);
IWL_CMD(TX_ANT_CONFIGURATION_CMD);
+ IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
+ IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
+ IWL_CMD(REPLY_BT_COEX_PROT_ENV);
+ IWL_CMD(REPLY_WIPAN_PARAMS);
+ IWL_CMD(REPLY_WIPAN_RXON);
+ IWL_CMD(REPLY_WIPAN_RXON_TIMING);
+ IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
+ IWL_CMD(REPLY_WIPAN_QOS_PARAM);
+ IWL_CMD(REPLY_WIPAN_WEPKEY);
+ IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
+ IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
default:
return "UNKNOWN";
@@ -229,7 +240,7 @@ cancel:
* in later, it will possibly set an invalid
* address (cmd->meta.source).
*/
- priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &=
+ priv->txq[priv->cmd_queue].meta[cmd_idx].flags &=
~CMD_WANT_SKB;
}
fail:
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index cda6a94d6cc9..63c0ab46261f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -192,47 +192,6 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
}
-/* default Thermal Throttling transaction table
- * Current state | Throttling Down | Throttling Up
- *=============================================================================
- * Condition Nxt State Condition Nxt State Condition Nxt State
- *-----------------------------------------------------------------------------
- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
- * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
- * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
- * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
- *=============================================================================
- */
-static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
- {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
- {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX},
- {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}
-};
-static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
- {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
- {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
- {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
-};
-
-/* Advance Thermal Throttling default restriction table */
-static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
- {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
- {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
- {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
- {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
-};
-
-
static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
struct iwl_powertable_cmd *cmd)
{
@@ -308,7 +267,6 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
int iwl_power_update_mode(struct iwl_priv *priv, bool force)
{
int ret = 0;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
bool update_chains;
struct iwl_powertable_cmd cmd;
@@ -325,9 +283,13 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
else if (priv->cfg->supports_idle &&
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
- else if (tt->state >= IWL_TI_1)
- iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
- else if (!enabled)
+ else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
+ priv->cfg->ops->lib->tt_ops.tt_power_mode &&
+ priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
+ /* in thermal throttling low power state */
+ iwl_static_sleep_cmd(priv, &cmd,
+ priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
+ } else if (!enabled)
iwl_power_sleep_cam_cmd(priv, &cmd);
else if (priv->power_data.debug_sleep_level_override >= 0)
iwl_static_sleep_cmd(priv, &cmd,
@@ -367,592 +329,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
}
EXPORT_SYMBOL(iwl_power_update_mode);
-bool iwl_ht_enabled(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return true;
- restriction = tt->restriction + tt->state;
- return restriction->is_ht;
-}
-EXPORT_SYMBOL(iwl_ht_enabled);
-
-bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
-{
- s32 temp = priv->temperature; /* degrees CELSIUS except specified */
- bool within_margin = false;
-
- if (priv->cfg->temperature_kelvin)
- temp = KELVIN_TO_CELSIUS(priv->temperature);
-
- if (!priv->thermal_throttle.advanced_tt)
- within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
- CT_KILL_THRESHOLD_LEGACY) ? true : false;
- else
- within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
- CT_KILL_THRESHOLD) ? true : false;
- return within_margin;
-}
-
-enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return IWL_ANT_OK_MULTI;
- restriction = tt->restriction + tt->state;
- return restriction->tx_stream;
-}
-EXPORT_SYMBOL(iwl_tx_ant_restriction);
-
-enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- struct iwl_tt_restriction *restriction;
-
- if (!priv->thermal_throttle.advanced_tt)
- return IWL_ANT_OK_MULTI;
- restriction = tt->restriction + tt->state;
- return restriction->rx_stream;
-}
-
-#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
-#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */
-
-/*
- * toggle the bit to wake up uCode and check the temperature
- * if the temperature is below CT, uCode will stay awake and send card
- * state notification with CT_KILL bit clear to inform Thermal Throttling
- * Management to change state. Otherwise, uCode will go back to sleep
- * without doing anything, driver should continue the 5 seconds timer
- * to wake up uCode for temperature check until temperature drop below CT
- */
-static void iwl_tt_check_exit_ct_kill(unsigned long data)
-{
- struct iwl_priv *priv = (struct iwl_priv *)data;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- unsigned long flags;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (tt->state == IWL_TI_CT_KILL) {
- if (priv->thermal_throttle.ct_kill_toggle) {
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- priv->thermal_throttle.ct_kill_toggle = false;
- } else {
- iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- priv->thermal_throttle.ct_kill_toggle = true;
- }
- iwl_read32(priv, CSR_UCODE_DRV_GP1);
- spin_lock_irqsave(&priv->reg_lock, flags);
- if (!iwl_grab_nic_access(priv))
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->reg_lock, flags);
-
- /* Reschedule the ct_kill timer to occur in
- * CT_KILL_EXIT_DURATION seconds to ensure we get a
- * thermal update */
- IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
- mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
- CT_KILL_EXIT_DURATION * HZ);
- }
-}
-
-static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
- bool stop)
-{
- if (stop) {
- IWL_DEBUG_POWER(priv, "Stop all queues\n");
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
- IWL_DEBUG_POWER(priv,
- "Schedule 5 seconds CT_KILL Timer\n");
- mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
- CT_KILL_EXIT_DURATION * HZ);
- } else {
- IWL_DEBUG_POWER(priv, "Wake all queues\n");
- if (priv->mac80211_registered)
- ieee80211_wake_queues(priv->hw);
- }
-}
-
-static void iwl_tt_ready_for_ct_kill(unsigned long data)
-{
- struct iwl_priv *priv = (struct iwl_priv *)data;
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- /* temperature timer expired, ready to go into CT_KILL state */
- if (tt->state != IWL_TI_CT_KILL) {
- IWL_DEBUG_POWER(priv, "entering CT_KILL state when temperature timer expired\n");
- tt->state = IWL_TI_CT_KILL;
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- }
-}
-
-static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
-{
- IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
- /* make request to retrieve statistics information */
- iwl_send_statistics_request(priv, CMD_SYNC, false);
- /* Reschedule the ct_kill wait timer */
- mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
- jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
-}
-
-#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
-#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
-#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
-
-/*
- * Legacy thermal throttling
- * 1) Avoid NIC destruction due to high temperatures
- * Chip will identify dangerously high temperatures that can
- * harm the device and will power down
- * 2) Avoid the NIC power down due to high temperature
- * Throttle early enough to lower the power consumption before
- * drastic steps are needed
- */
-static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- enum iwl_tt_state old_state;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if ((tt->tt_previous_temp) &&
- (temp > tt->tt_previous_temp) &&
- ((temp - tt->tt_previous_temp) >
- IWL_TT_INCREASE_MARGIN)) {
- IWL_DEBUG_POWER(priv,
- "Temperature increase %d degree Celsius\n",
- (temp - tt->tt_previous_temp));
- }
-#endif
- old_state = tt->state;
- /* in Celsius */
- if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
- tt->state = IWL_TI_CT_KILL;
- else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
- tt->state = IWL_TI_2;
- else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
- tt->state = IWL_TI_1;
- else
- tt->state = IWL_TI_0;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- tt->tt_previous_temp = temp;
-#endif
- /* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- if (tt->state != old_state) {
- switch (tt->state) {
- case IWL_TI_0:
- /*
- * When the system is ready to go back to IWL_TI_0
- * we only have to call iwl_power_update_mode() to
- * do so.
- */
- break;
- case IWL_TI_1:
- tt->tt_power_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_TI_2:
- tt->tt_power_mode = IWL_POWER_INDEX_4;
- break;
- default:
- tt->tt_power_mode = IWL_POWER_INDEX_5;
- break;
- }
- mutex_lock(&priv->mutex);
- if (old_state == IWL_TI_CT_KILL)
- clear_bit(STATUS_CT_KILL, &priv->status);
- if (tt->state != IWL_TI_CT_KILL &&
- iwl_power_update_mode(priv, true)) {
- /* TT state not updated
- * try again during next temperature read
- */
- if (old_state == IWL_TI_CT_KILL)
- set_bit(STATUS_CT_KILL, &priv->status);
- tt->state = old_state;
- IWL_ERR(priv, "Cannot update power mode, "
- "TT state not updated\n");
- } else {
- if (tt->state == IWL_TI_CT_KILL) {
- if (force) {
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- } else {
- iwl_prepare_ct_kill_task(priv);
- tt->state = old_state;
- }
- } else if (old_state == IWL_TI_CT_KILL &&
- tt->state != IWL_TI_CT_KILL)
- iwl_perform_ct_kill_task(priv, false);
- IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
- tt->state);
- IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
- tt->tt_power_mode);
- }
- mutex_unlock(&priv->mutex);
- }
-}
-
-/*
- * Advance thermal throttling
- * 1) Avoid NIC destruction due to high temperatures
- * Chip will identify dangerously high temperatures that can
- * harm the device and will power down
- * 2) Avoid the NIC power down due to high temperature
- * Throttle early enough to lower the power consumption before
- * drastic steps are needed
- * Actions include relaxing the power down sleep thresholds and
- * decreasing the number of TX streams
- * 3) Avoid throughput performance impact as much as possible
- *
- *=============================================================================
- * Condition Nxt State Condition Nxt State Condition Nxt State
- *-----------------------------------------------------------------------------
- * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
- * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
- * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
- * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
- *=============================================================================
- */
-static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- int i;
- bool changed = false;
- enum iwl_tt_state old_state;
- struct iwl_tt_trans *transaction;
-
- old_state = tt->state;
- for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
- /* based on the current TT state,
- * find the curresponding transaction table
- * each table has (IWL_TI_STATE_MAX - 1) entries
- * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
- * will advance to the correct table.
- * then based on the current temperature
- * find the next state need to transaction to
- * go through all the possible (IWL_TI_STATE_MAX - 1) entries
- * in the current table to see if transaction is needed
- */
- transaction = tt->transaction +
- ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
- if (temp >= transaction->tt_low &&
- temp <= transaction->tt_high) {
-#ifdef CONFIG_IWLWIFI_DEBUG
- if ((tt->tt_previous_temp) &&
- (temp > tt->tt_previous_temp) &&
- ((temp - tt->tt_previous_temp) >
- IWL_TT_INCREASE_MARGIN)) {
- IWL_DEBUG_POWER(priv,
- "Temperature increase %d "
- "degree Celsius\n",
- (temp - tt->tt_previous_temp));
- }
- tt->tt_previous_temp = temp;
-#endif
- if (old_state !=
- transaction->next_state) {
- changed = true;
- tt->state =
- transaction->next_state;
- }
- break;
- }
- }
- /* stop ct_kill_waiting_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- if (changed) {
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (tt->state >= IWL_TI_1) {
- /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
- tt->tt_power_mode = IWL_POWER_INDEX_5;
- if (!iwl_ht_enabled(priv))
- /* disable HT */
- rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
- RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
- RXON_FLG_HT40_PROT_MSK |
- RXON_FLG_HT_PROT_MSK);
- else {
- /* check HT capability and set
- * according to the system HT capability
- * in case get disabled before */
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- }
-
- } else {
- /*
- * restore system power setting -- it will be
- * recalculated automatically.
- */
-
- /* check HT capability and set
- * according to the system HT capability
- * in case get disabled before */
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
- }
- mutex_lock(&priv->mutex);
- if (old_state == IWL_TI_CT_KILL)
- clear_bit(STATUS_CT_KILL, &priv->status);
- if (tt->state != IWL_TI_CT_KILL &&
- iwl_power_update_mode(priv, true)) {
- /* TT state not updated
- * try again during next temperature read
- */
- IWL_ERR(priv, "Cannot update power mode, "
- "TT state not updated\n");
- if (old_state == IWL_TI_CT_KILL)
- set_bit(STATUS_CT_KILL, &priv->status);
- tt->state = old_state;
- } else {
- IWL_DEBUG_POWER(priv,
- "Thermal Throttling to new state: %u\n",
- tt->state);
- if (old_state != IWL_TI_CT_KILL &&
- tt->state == IWL_TI_CT_KILL) {
- if (force) {
- IWL_DEBUG_POWER(priv,
- "Enter IWL_TI_CT_KILL\n");
- set_bit(STATUS_CT_KILL, &priv->status);
- iwl_perform_ct_kill_task(priv, true);
- } else {
- iwl_prepare_ct_kill_task(priv);
- tt->state = old_state;
- }
- } else if (old_state == IWL_TI_CT_KILL &&
- tt->state != IWL_TI_CT_KILL) {
- IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
- iwl_perform_ct_kill_task(priv, false);
- }
- }
- mutex_unlock(&priv->mutex);
- }
-}
-
-/* Card State Notification indicated reach critical temperature
- * if PSP not enable, no Thermal Throttling function will be performed
- * just set the GP1 bit to acknowledge the event
- * otherwise, go into IWL_TI_CT_KILL state
- * since Card State Notification will not provide any temperature reading
- * for Legacy mode
- * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
- * for advance mode
- * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
- */
-static void iwl_bg_ct_enter(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!iwl_is_ready(priv))
- return;
-
- if (tt->state != IWL_TI_CT_KILL) {
- IWL_ERR(priv, "Device reached critical temperature "
- "- ucode going to sleep!\n");
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv,
- IWL_MINIMAL_POWER_THRESHOLD,
- true);
- else
- iwl_advance_tt_handler(priv,
- CT_KILL_THRESHOLD + 1, true);
- }
-}
-
-/* Card State Notification indicated out of critical temperature
- * since Card State Notification will not provide any temperature reading
- * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
- * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
- */
-static void iwl_bg_ct_exit(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (!iwl_is_ready(priv))
- return;
-
- /* stop ct_kill_exit_tm timer */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
-
- if (tt->state == IWL_TI_CT_KILL) {
- IWL_ERR(priv,
- "Device temperature below critical"
- "- ucode awake!\n");
- /*
- * exit from CT_KILL state
- * reset the current temperature reading
- */
- priv->temperature = 0;
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv,
- IWL_REDUCED_PERFORMANCE_THRESHOLD_2,
- true);
- else
- iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
- true);
- }
-}
-
-void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
- queue_work(priv->workqueue, &priv->ct_enter);
-}
-EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
-
-void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
- queue_work(priv->workqueue, &priv->ct_exit);
-}
-EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
-
-static void iwl_bg_tt_work(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
- s32 temp = priv->temperature; /* degrees CELSIUS except specified */
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (priv->cfg->temperature_kelvin)
- temp = KELVIN_TO_CELSIUS(priv->temperature);
-
- if (!priv->thermal_throttle.advanced_tt)
- iwl_legacy_tt_handler(priv, temp, false);
- else
- iwl_advance_tt_handler(priv, temp, false);
-}
-
-void iwl_tt_handler(struct iwl_priv *priv)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
- queue_work(priv->workqueue, &priv->tt_work);
-}
-EXPORT_SYMBOL(iwl_tt_handler);
-
-/* Thermal throttling initialization
- * For advance thermal throttling:
- * Initialize Thermal Index and temperature threshold table
- * Initialize thermal throttling restriction table
- */
-void iwl_tt_initialize(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
- int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
- struct iwl_tt_trans *transaction;
-
- IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
-
- memset(tt, 0, sizeof(struct iwl_tt_mgmt));
-
- tt->state = IWL_TI_0;
- init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
- priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
- priv->thermal_throttle.ct_kill_exit_tm.function =
- iwl_tt_check_exit_ct_kill;
- init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
- priv->thermal_throttle.ct_kill_waiting_tm.data = (unsigned long)priv;
- priv->thermal_throttle.ct_kill_waiting_tm.function =
- iwl_tt_ready_for_ct_kill;
- /* setup deferred ct kill work */
- INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
- INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
- INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
-
- if (priv->cfg->adv_thermal_throttle) {
- IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
- tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
- IWL_TI_STATE_MAX, GFP_KERNEL);
- tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
- IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
- GFP_KERNEL);
- if (!tt->restriction || !tt->transaction) {
- IWL_ERR(priv, "Fallback to Legacy Throttling\n");
- priv->thermal_throttle.advanced_tt = false;
- kfree(tt->restriction);
- tt->restriction = NULL;
- kfree(tt->transaction);
- tt->transaction = NULL;
- } else {
- transaction = tt->transaction +
- (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_0[0], size);
- transaction = tt->transaction +
- (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_1[0], size);
- transaction = tt->transaction +
- (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_2[0], size);
- transaction = tt->transaction +
- (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
- memcpy(transaction, &tt_range_3[0], size);
- size = sizeof(struct iwl_tt_restriction) *
- IWL_TI_STATE_MAX;
- memcpy(tt->restriction,
- &restriction_range[0], size);
- priv->thermal_throttle.advanced_tt = true;
- }
- } else {
- IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
- priv->thermal_throttle.advanced_tt = false;
- }
-}
-EXPORT_SYMBOL(iwl_tt_initialize);
-
-/* cleanup thermal throttling management related memory and timer */
-void iwl_tt_exit(struct iwl_priv *priv)
-{
- struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
-
- /* stop ct_kill_exit_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
- /* stop ct_kill_waiting_tm timer if activated */
- del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
- cancel_work_sync(&priv->tt_work);
- cancel_work_sync(&priv->ct_enter);
- cancel_work_sync(&priv->ct_exit);
-
- if (priv->thermal_throttle.advanced_tt) {
- /* free advance thermal throttling memory */
- kfree(tt->restriction);
- tt->restriction = NULL;
- kfree(tt->transaction);
- tt->transaction = NULL;
- }
-}
-EXPORT_SYMBOL(iwl_tt_exit);
-
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 5db91c10dcc8..df81565a7cc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -30,90 +30,6 @@
#include "iwl-commands.h"
-#define IWL_ABSOLUTE_ZERO 0
-#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
-#define IWL_TT_INCREASE_MARGIN 5
-#define IWL_TT_CT_KILL_MARGIN 3
-
-enum iwl_antenna_ok {
- IWL_ANT_OK_NONE,
- IWL_ANT_OK_SINGLE,
- IWL_ANT_OK_MULTI,
-};
-
-/* Thermal Throttling State Machine states */
-enum iwl_tt_state {
- IWL_TI_0, /* normal temperature, system power state */
- IWL_TI_1, /* high temperature detect, low power state */
- IWL_TI_2, /* higher temperature detected, lower power state */
- IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
- IWL_TI_STATE_MAX
-};
-
-/**
- * struct iwl_tt_restriction - Thermal Throttling restriction table
- * @tx_stream: number of tx stream allowed
- * @is_ht: ht enable/disable
- * @rx_stream: number of rx stream allowed
- *
- * This table is used by advance thermal throttling management
- * based on the current thermal throttling state, and determines
- * the number of tx/rx streams and the status of HT operation.
- */
-struct iwl_tt_restriction {
- enum iwl_antenna_ok tx_stream;
- enum iwl_antenna_ok rx_stream;
- bool is_ht;
-};
-
-/**
- * struct iwl_tt_trans - Thermal Throttling transaction table
- * @next_state: next thermal throttling mode
- * @tt_low: low temperature threshold to change state
- * @tt_high: high temperature threshold to change state
- *
- * This is used by the advanced thermal throttling algorithm
- * to determine the next thermal state to go based on the
- * current temperature.
- */
-struct iwl_tt_trans {
- enum iwl_tt_state next_state;
- u32 tt_low;
- u32 tt_high;
-};
-
-/**
- * struct iwl_tt_mgnt - Thermal Throttling Management structure
- * @advanced_tt: advanced thermal throttle required
- * @state: current Thermal Throttling state
- * @tt_power_mode: Thermal Throttling power mode index
- * being used to set power level when
- * when thermal throttling state != IWL_TI_0
- * the tt_power_mode should set to different
- * power mode based on the current tt state
- * @tt_previous_temperature: last measured temperature
- * @iwl_tt_restriction: ptr to restriction tbl, used by advance
- * thermal throttling to determine how many tx/rx streams
- * should be used in tt state; and can HT be enabled or not
- * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
- * state transaction
- * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature
- * @ct_kill_exit_tm: timer to exit thermal kill
- */
-struct iwl_tt_mgmt {
- enum iwl_tt_state state;
- bool advanced_tt;
- u8 tt_power_mode;
- bool ct_kill_toggle;
-#ifdef CONFIG_IWLWIFI_DEBUG
- s32 tt_previous_temp;
-#endif
- struct iwl_tt_restriction *restriction;
- struct iwl_tt_trans *transaction;
- struct timer_list ct_kill_exit_tm;
- struct timer_list ct_kill_waiting_tm;
-};
-
enum iwl_power_level {
IWL_POWER_INDEX_1,
IWL_POWER_INDEX_2,
@@ -130,15 +46,6 @@ struct iwl_power_mgr {
};
int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-bool iwl_ht_enabled(struct iwl_priv *priv);
-bool iwl_within_ct_kill_margin(struct iwl_priv *priv);
-enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
-enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
-void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
-void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
-void iwl_tt_handler(struct iwl_priv *priv);
-void iwl_tt_initialize(struct iwl_priv *priv);
-void iwl_tt_exit(struct iwl_priv *priv);
void iwl_power_initialize(struct iwl_priv *priv);
extern bool no_sleep_autoadjust;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b1f101caf19d..5469655646ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -306,7 +306,7 @@
* at a time, until receiving ACK from receiving station, or reaching
* retry limit and giving up.
*
- * The command queue (#4) must use this mode!
+ * The command queue (#4/#9) must use this mode!
* This mode does not require use of the Byte Count table in host DRAM.
*
* Driver controls scheduler operation via 3 means:
@@ -322,7 +322,7 @@
* (1024 bytes for each queue).
*
* After receiving "Alive" response from uCode, driver must initialize
- * the scheduler (especially for queue #4, the command queue, otherwise
+ * the scheduler (especially for queue #4/#9, the command queue, otherwise
* the driver can't issue commands!):
*/
@@ -555,8 +555,9 @@
#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
-#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
- (~(1<<IWL_CMD_QUEUE_NUM)))
+#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv) \
+ (((1<<(priv)->hw_params.max_txq_num) - 1) &\
+ (~(1<<(priv)->cmd_queue)))
#define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 79773e353baa..10be197b0f22 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -228,7 +228,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_any_associated(priv)) {
if (priv->cfg->ops->lib->check_ack_health) {
if (!priv->cfg->ops->lib->check_ack_health(
priv, pkt)) {
@@ -266,7 +266,12 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
{
u16 fc = le16_to_cpu(hdr->frame_control);
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ /*
+ * All contexts have the same setting here due to it being
+ * a module parameter, so OK to check any context.
+ */
+ if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags &
+ RXON_FILTER_DIS_DECRYPT_MSK)
return 0;
if (!(fc & IEEE80211_FCTL_PROTECTED))
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index a4b3663a262f..599573f2b01f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -54,100 +54,134 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
+static int iwl_send_scan_abort(struct iwl_priv *priv)
+{
+ int ret;
+ struct iwl_rx_packet *pkt;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_ABORT_CMD,
+ .flags = CMD_WANT_SKB,
+ };
+ /* Exit instantly with error when device is not ready
+ * to receive scan abort command or it does not perform
+ * hardware scan currently */
+ if (!test_bit(STATUS_READY, &priv->status) ||
+ !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
+ !test_bit(STATUS_SCAN_HW, &priv->status) ||
+ test_bit(STATUS_FW_ERROR, &priv->status) ||
+ test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return -EIO;
-/**
- * iwl_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-int iwl_scan_cancel(struct iwl_priv *priv)
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ return ret;
+
+ pkt = (struct iwl_rx_packet *)cmd.reply_page;
+ if (pkt->u.status != CAN_ABORT_STATUS) {
+ /* The scan abort will return 1 for success or
+ * 2 for "failure". A failure condition can be
+ * due to simply not being in an active scan which
+ * can occur if we send the scan abort before we
+ * the microcode has notified us that a scan is
+ * completed. */
+ IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+ ret = -EIO;
+ }
+
+ iwl_free_pages(priv, cmd.reply_page);
+ return ret;
+}
+
+static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
+ /* check if scan was requested from mac80211 */
+ if (priv->scan_request) {
+ IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
+ ieee80211_scan_completed(priv->hw, aborted);
}
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ priv->is_internal_short_scan = false;
+ priv->scan_vif = NULL;
+ priv->scan_request = NULL;
+}
- } else
- IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
+void iwl_force_scan_end(struct iwl_priv *priv)
+{
+ lockdep_assert_held(&priv->mutex);
- return test_bit(STATUS_SCANNING, &priv->status);
+ if (!test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
+ return;
}
+ IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
+ clear_bit(STATUS_SCANNING, &priv->status);
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ iwl_complete_scan(priv, true);
+}
+EXPORT_SYMBOL(iwl_force_scan_end);
+
+static void iwl_do_scan_abort(struct iwl_priv *priv)
+{
+ int ret;
+
+ lockdep_assert_held(&priv->mutex);
+
+ if (!test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
+ return;
+ }
+
+ if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
+ return;
+ }
+
+ ret = iwl_send_scan_abort(priv);
+ if (ret) {
+ IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret);
+ iwl_force_scan_end(priv);
+ } else
+ IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
+}
+
+/**
+ * iwl_scan_cancel - Cancel any currently executing HW scan
+ */
+int iwl_scan_cancel(struct iwl_priv *priv)
+{
+ IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
+ queue_work(priv->workqueue, &priv->abort_scan);
return 0;
}
EXPORT_SYMBOL(iwl_scan_cancel);
+
/**
* iwl_scan_cancel_timeout - Cancel any currently executing HW scan
* @ms: amount of time to wait (in milliseconds) for scan to abort
*
- * NOTE: priv->mutex must be held before calling this function
*/
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
+ unsigned long timeout = jiffies + msecs_to_jiffies(ms);
- return ret;
-}
-EXPORT_SYMBOL(iwl_scan_cancel_timeout);
+ lockdep_assert_held(&priv->mutex);
-static int iwl_send_scan_abort(struct iwl_priv *priv)
-{
- int ret = 0;
- struct iwl_rx_packet *pkt;
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .flags = CMD_WANT_SKB,
- };
+ IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n");
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
+ iwl_do_scan_abort(priv);
- ret = iwl_send_cmd_sync(priv, &cmd);
- if (ret) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return ret;
+ while (time_before_eq(jiffies, timeout)) {
+ if (!test_bit(STATUS_SCAN_HW, &priv->status))
+ break;
+ msleep(20);
}
- pkt = (struct iwl_rx_packet *)cmd.reply_page;
- if (pkt->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
-
- iwl_free_pages(priv, cmd.reply_page);
-
- return ret;
+ return test_bit(STATUS_SCAN_HW, &priv->status);
}
+EXPORT_SYMBOL(iwl_scan_cancel_timeout);
/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -158,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
struct iwl_scanreq_notification *notif =
(struct iwl_scanreq_notification *)pkt->u.raw;
- IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
+ IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
#endif
}
@@ -206,7 +240,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
@@ -214,29 +247,37 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
scan_notif->scanned_channels,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
-#endif
/* The HW is no longer scanning */
clear_bit(STATUS_SCAN_HW, &priv->status);
- IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
+ IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
(priv->scan_start, jiffies)));
- /*
- * If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested
- */
- if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
- IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
-
- IWL_DEBUG_INFO(priv, "Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
queue_work(priv->workqueue, &priv->scan_completed);
+
+ if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
+ priv->cfg->advanced_bt_coexist &&
+ priv->bt_status != scan_notif->bt_status) {
+ if (scan_notif->bt_status) {
+ /* BT on */
+ if (!priv->bt_ch_announce)
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
+ /*
+ * otherwise, no traffic load information provided
+ * no changes made
+ */
+ } else {
+ /* BT off */
+ priv->bt_traffic_load =
+ IWL_BT_COEX_TRAFFIC_LOAD_NONE;
+ }
+ priv->bt_status = scan_notif->bt_status;
+ queue_work(priv->workqueue, &priv->bt_traffic_change_work);
+ }
}
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -268,18 +309,28 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx;
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
- if (iwl_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = vif ? vif->bss_conf.beacon_int : 0;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ if (iwl_is_any_associated(priv)) {
+ /*
+ * If we're associated, we clamp the maximum passive
+ * dwell time to be 98% of the smallest beacon interval
+ * (minus 2 * channel tune time)
+ */
+ for_each_context(priv, ctx) {
+ u16 value;
+
+ if (!iwl_is_associated_ctx(ctx))
+ continue;
+ value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+ if ((value > IWL_PASSIVE_DWELL_BASE) || !value)
+ value = IWL_PASSIVE_DWELL_BASE;
+ value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ passive = min(value, passive);
+ }
}
return passive;
@@ -296,19 +347,53 @@ void iwl_init_scan_params(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_init_scan_params);
-static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ bool internal,
+ enum nl80211_band band)
{
+ int ret;
+
lockdep_assert_held(&priv->mutex);
- IWL_DEBUG_INFO(priv, "Starting scan...\n");
+ if (WARN_ON(!priv->cfg->ops->utils->request_scan))
+ return -EOPNOTSUPP;
+
+ cancel_delayed_work(&priv->scan_check);
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_WARN(priv, "Request scan called when driver not ready.\n");
+ return -EIO;
+ }
+
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ IWL_DEBUG_SCAN(priv,
+ "Multiple concurrent scan requests in parallel.\n");
+ return -EBUSY;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
+ return -EBUSY;
+ }
+
+ IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
+ internal ? "internal short " : "");
+
set_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = false;
+ priv->is_internal_short_scan = internal;
priv->scan_start = jiffies;
+ priv->scan_band = band;
- if (WARN_ON(!priv->cfg->ops->utils->request_scan))
- return -EOPNOTSUPP;
+ ret = priv->cfg->ops->utils->request_scan(priv, vif);
+ if (ret) {
+ clear_bit(STATUS_SCANNING, &priv->status);
+ priv->is_internal_short_scan = false;
+ return ret;
+ }
- priv->cfg->ops->utils->request_scan(priv, vif);
+ queue_delayed_work(priv->workqueue, &priv->scan_check,
+ IWL_SCAN_CHECK_WATCHDOG);
return 0;
}
@@ -327,12 +412,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
- IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
if (test_bit(STATUS_SCANNING, &priv->status) &&
!priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
@@ -340,14 +419,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
goto out_unlock;
}
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- ret = -EAGAIN;
- goto out_unlock;
- }
-
/* mac80211 will only ask for one band at a time */
- priv->scan_band = req->channels[0]->band;
priv->scan_request = req;
priv->scan_vif = vif;
@@ -355,10 +427,12 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
* If an internal scan is in progress, just set
* up the scan_request as per above.
*/
- if (priv->is_internal_short_scan)
+ if (priv->is_internal_short_scan) {
+ IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
ret = 0;
- else
- ret = iwl_scan_initiate(priv, vif);
+ } else
+ ret = iwl_scan_initiate(priv, vif, false,
+ req->channels[0]->band);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -378,11 +452,13 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->start_internal_scan);
}
-void iwl_bg_start_internal_scan(struct work_struct *work)
+static void iwl_bg_start_internal_scan(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, start_internal_scan);
+ IWL_DEBUG_SCAN(priv, "Start internal scan\n");
+
mutex_lock(&priv->mutex);
if (priv->is_internal_short_scan == true) {
@@ -390,56 +466,31 @@ void iwl_bg_start_internal_scan(struct work_struct *work)
goto unlock;
}
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
- goto unlock;
- }
-
if (test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
goto unlock;
}
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- goto unlock;
- }
-
- priv->scan_band = priv->band;
-
- IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
- set_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = true;
-
- if (WARN_ON(!priv->cfg->ops->utils->request_scan))
- goto unlock;
-
- priv->cfg->ops->utils->request_scan(priv, NULL);
+ if (iwl_scan_initiate(priv, NULL, true, priv->band))
+ IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
unlock:
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_start_internal_scan);
-void iwl_bg_scan_check(struct work_struct *data)
+static void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ IWL_DEBUG_SCAN(priv, "Scan check work\n");
+ /* Since we are here firmware does not finish scan and
+ * most likely is in bad shape, so we don't bother to
+ * send abort command, just force scan complete to mac80211 */
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) &&
- !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl_send_scan_abort(priv);
- }
+ iwl_force_scan_end(priv);
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_scan_check);
/**
* iwl_fill_probe_req - fill in all required fields and IE for probe request
@@ -489,48 +540,69 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
}
EXPORT_SYMBOL(iwl_fill_probe_req);
-void iwl_bg_abort_scan(struct work_struct *work)
+static void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
- if (!test_bit(STATUS_READY, &priv->status) ||
- !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
- return;
-
- cancel_delayed_work(&priv->scan_check);
+ IWL_DEBUG_SCAN(priv, "Abort scan work\n");
+ /* We keep scan_check work queued in case when firmware will not
+ * report back scan completed notification */
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
- iwl_send_scan_abort(priv);
+ iwl_scan_cancel_timeout(priv, 200);
mutex_unlock(&priv->mutex);
}
-EXPORT_SYMBOL(iwl_bg_abort_scan);
-void iwl_bg_scan_completed(struct work_struct *work)
+static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- bool internal = false;
+ bool aborted;
+ struct iwl_rxon_context *ctx;
- IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
+ IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
+ priv->is_internal_short_scan ? "internal short " : "");
cancel_delayed_work(&priv->scan_check);
mutex_lock(&priv->mutex);
- if (priv->is_internal_short_scan) {
- priv->is_internal_short_scan = false;
- IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
- internal = true;
- } else {
- priv->scan_request = NULL;
- priv->scan_vif = NULL;
+
+ aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ if (aborted)
+ IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
+
+ if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
+ goto out_settings;
}
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ if (priv->is_internal_short_scan && !aborted) {
+ int err;
+
+ /* Check if mac80211 requested scan during our internal scan */
+ if (priv->scan_request == NULL)
+ goto out_complete;
+
+ /* If so request a new scan */
+ err = iwl_scan_initiate(priv, priv->scan_vif, false,
+ priv->scan_request->channels[0]->band);
+ if (err) {
+ IWL_DEBUG_SCAN(priv,
+ "failed to initiate pending scan: %d\n", err);
+ aborted = true;
+ goto out_complete;
+ }
+
goto out;
+ }
- if (internal && priv->scan_request)
- iwl_scan_initiate(priv, priv->scan_vif);
+out_complete:
+ iwl_complete_scan(priv, aborted);
+
+out_settings:
+ /* Can we still talk to firmware ? */
+ if (!iwl_is_ready_rf(priv))
+ goto out;
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
@@ -540,22 +612,15 @@ void iwl_bg_scan_completed(struct work_struct *work)
* Since setting the RXON may have been deferred while
* performing the scan, fire one off if needed
*/
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwlcore_commit_rxon(priv);
+ for_each_context(priv, ctx)
+ iwlcore_commit_rxon(priv, ctx);
+
+ if (priv->cfg->ops->hcmd->set_pan_params)
+ priv->cfg->ops->hcmd->set_pan_params(priv);
out:
mutex_unlock(&priv->mutex);
-
- /*
- * Do not hold mutex here since this will cause mac80211 to call
- * into driver again into functions that will attempt to take
- * mutex.
- */
- if (!internal)
- ieee80211_scan_completed(priv->hw, false);
}
-EXPORT_SYMBOL(iwl_bg_scan_completed);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
@@ -566,3 +631,16 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
+{
+ cancel_work_sync(&priv->start_internal_scan);
+ cancel_work_sync(&priv->abort_scan);
+ cancel_work_sync(&priv->scan_completed);
+
+ if (cancel_delayed_work_sync(&priv->scan_check)) {
+ mutex_lock(&priv->mutex);
+ iwl_force_scan_end(priv);
+ mutex_unlock(&priv->mutex);
+ }
+}
+EXPORT_SYMBOL(iwl_cancel_scan_deferred_work);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7e0829be5e78..6edd0341dfe2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -172,12 +172,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_send_add_sta);
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
- struct ieee80211_sta_ht_cap *sta_ht_inf)
+ struct ieee80211_sta *sta,
+ struct iwl_rxon_context *ctx)
{
+ struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
__le32 sta_flags;
u8 mimo_ps_mode;
- if (!sta_ht_inf || !sta_ht_inf->ht_supported)
+ if (!sta || !sta_ht_inf->ht_supported)
goto done;
mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
@@ -211,7 +213,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
sta_flags |= cpu_to_le32(
(u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
- if (iwl_is_ht40_tx_allowed(priv, sta_ht_inf))
+ if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
sta_flags |= STA_FLG_HT40_EN_MSK;
else
sta_flags &= ~STA_FLG_HT40_EN_MSK;
@@ -226,9 +228,9 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
*
* should be called with sta_lock held
*/
-static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info)
+static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta)
{
struct iwl_station_entry *station;
int i;
@@ -236,9 +238,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
u16 rate;
if (is_ap)
- sta_id = IWL_AP_ID;
+ sta_id = ctx->ap_sta_id;
else if (is_broadcast_ether_addr(addr))
- sta_id = priv->hw_params.bcast_sta_id;
+ sta_id = ctx->bcast_sta_id;
else
for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
@@ -289,14 +291,22 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
memcpy(station->sta.sta.addr, addr, ETH_ALEN);
station->sta.mode = 0;
station->sta.sta.sta_id = sta_id;
- station->sta.station_flags = 0;
+ station->sta.station_flags = ctx->station_flags;
+ station->ctxid = ctx->ctxid;
+
+ if (sta) {
+ struct iwl_station_priv_common *sta_priv;
+
+ sta_priv = (void *)sta->drv_priv;
+ sta_priv->ctx = ctx;
+ }
/*
* OK to call unconditionally, since local stations (IBSS BSSID
- * STA and broadcast STA) pass in a NULL ht_info, and mac80211
+ * STA and broadcast STA) pass in a NULL sta, and mac80211
* doesn't allow HT IBSS.
*/
- iwl_set_ht_add_station(priv, sta_id, ht_info);
+ iwl_set_ht_add_station(priv, sta_id, sta, ctx);
/* 3945 only */
rate = (priv->band == IEEE80211_BAND_5GHZ) ?
@@ -313,10 +323,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
/**
* iwl_add_station_common -
*/
-int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info,
- u8 *sta_id_r)
+int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta, u8 *sta_id_r)
{
unsigned long flags_spin;
int ret = 0;
@@ -325,7 +334,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
*sta_id_r = 0;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
+ sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
addr);
@@ -377,7 +386,8 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
{
int i, r;
struct iwl_link_quality_cmd *link_cmd;
- u32 rate_flags;
+ u32 rate_flags = 0;
+ __le32 rate_n_flags;
link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
if (!link_cmd) {
@@ -391,18 +401,14 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
else
r = IWL_RATE_1M_INDEX;
- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
- rate_flags = 0;
- if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
- rate_flags |= RATE_MCS_CCK_MSK;
+ if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+ rate_flags |= RATE_MCS_CCK_MSK;
- rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+ rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
RATE_MCS_ANT_POS;
-
- link_cmd->rs_table[i].rate_n_flags =
- iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
- r = iwl_get_prev_ieee_rate(r);
- }
+ rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+ link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
link_cmd->general_params.single_stream_ant_msk =
first_antenna(priv->hw_params.valid_tx_ant);
@@ -431,8 +437,8 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
*
* Function sleeps.
*/
-int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
- u8 *sta_id_r)
+int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool init_rs, u8 *sta_id_r)
{
int ret;
u8 sta_id;
@@ -442,7 +448,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
if (sta_id_r)
*sta_id_r = IWL_INVALID_STATION;
- ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
+ ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM\n", addr);
return ret;
@@ -464,7 +470,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
return -ENOMEM;
}
- ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
+ ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true);
if (ret)
IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
@@ -616,7 +622,8 @@ EXPORT_SYMBOL_GPL(iwl_remove_station);
* other than explicit station management would cause this in
* the ucode, e.g. unassociated RXON.
*/
-void iwl_clear_ucode_stations(struct iwl_priv *priv)
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
int i;
unsigned long flags_spin;
@@ -626,6 +633,9 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv)
spin_lock_irqsave(&priv->sta_lock, flags_spin);
for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (ctx && ctx->ctxid != priv->stations[i].ctxid)
+ continue;
+
if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -647,7 +657,7 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
*
* Function sleeps.
*/
-void iwl_restore_stations(struct iwl_priv *priv)
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_addsta_cmd sta_cmd;
struct iwl_link_quality_cmd lq;
@@ -665,6 +675,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
spin_lock_irqsave(&priv->sta_lock, flags_spin);
for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (ctx->ctxid != priv->stations[i].ctxid)
+ continue;
if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
!(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
@@ -700,7 +712,7 @@ void iwl_restore_stations(struct iwl_priv *priv)
* current LQ command
*/
if (send_lq)
- iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
+ iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
spin_lock_irqsave(&priv->sta_lock, flags_spin);
priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
}
@@ -718,7 +730,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
- for (i = 0; i < STA_KEY_MAX_NUM; i++)
+ for (i = 0; i < priv->sta_key_max_num; i++)
if (!test_and_set_bit(i, &priv->ucode_key_table))
return i;
@@ -726,7 +738,9 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
-static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
+static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
+ bool send_if_empty)
{
int i, not_empty = 0;
u8 buff[sizeof(struct iwl_wep_cmd) +
@@ -734,7 +748,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
size_t cmd_size = sizeof(struct iwl_wep_cmd);
struct iwl_host_cmd cmd = {
- .id = REPLY_WEPKEY,
+ .id = ctx->wep_key_cmd,
.data = wep_cmd,
.flags = CMD_SYNC,
};
@@ -746,16 +760,16 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
for (i = 0; i < WEP_KEYS_MAX ; i++) {
wep_cmd->key[i].key_index = i;
- if (priv->wep_keys[i].key_size) {
+ if (ctx->wep_keys[i].key_size) {
wep_cmd->key[i].key_offset = i;
not_empty = 1;
} else {
wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
}
- wep_cmd->key[i].key_size = priv->wep_keys[i].key_size;
- memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key,
- priv->wep_keys[i].key_size);
+ wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
+ memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
+ ctx->wep_keys[i].key_size);
}
wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
@@ -771,15 +785,17 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
return 0;
}
-int iwl_restore_default_wep_keys(struct iwl_priv *priv)
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
lockdep_assert_held(&priv->mutex);
- return iwl_send_static_wepkey_cmd(priv, 0);
+ return iwl_send_static_wepkey_cmd(priv, ctx, false);
}
EXPORT_SYMBOL(iwl_restore_default_wep_keys);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *keyconf)
{
int ret;
@@ -789,13 +805,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
keyconf->keyidx);
- memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
+ memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
if (iwl_is_rfkill(priv)) {
IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
/* but keys in device are clear anyway so return success */
return 0;
}
- ret = iwl_send_static_wepkey_cmd(priv, 1);
+ ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
keyconf->keyidx, ret);
@@ -804,6 +820,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_remove_default_wep_key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *keyconf)
{
int ret;
@@ -818,13 +835,13 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->hw_key_idx = HW_KEY_DEFAULT;
- priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
+ priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
- priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
- memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
+ ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
+ memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
keyconf->keylen);
- ret = iwl_send_static_wepkey_cmd(priv, 0);
+ ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
keyconf->keylen, keyconf->keyidx, ret);
@@ -833,8 +850,9 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_set_default_wep_key);
static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
__le16 key_flags = 0;
@@ -851,12 +869,12 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
if (keyconf->keylen == WEP_KEY_LEN_128)
key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == ctx->bcast_sta_id)
key_flags |= STA_KEY_MULTICAST_MSK;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
@@ -887,8 +905,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
}
static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
__le16 key_flags = 0;
@@ -900,13 +919,13 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
key_flags &= ~STA_KEY_FLG_INVALID;
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == ctx->bcast_sta_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
@@ -936,8 +955,9 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
}
static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
int ret = 0;
@@ -947,7 +967,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
key_flags &= ~STA_KEY_FLG_INVALID;
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == ctx->bcast_sta_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -955,7 +975,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
priv->stations[sta_id].keyinfo.keylen = 16;
if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
@@ -982,8 +1002,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
}
void iwl_update_tkip_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
{
u8 sta_id;
unsigned long flags;
@@ -995,7 +1016,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
return;
}
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
if (sta_id == IWL_INVALID_STATION)
return;
@@ -1018,8 +1039,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_update_tkip_key);
int iwl_remove_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
u16 key_flags;
@@ -1028,7 +1050,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
lockdep_assert_held(&priv->mutex);
- priv->key_mapping_key--;
+ ctx->key_mapping_keys--;
spin_lock_irqsave(&priv->sta_lock, flags);
key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
@@ -1080,34 +1102,36 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_remove_dynamic_key);
-int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf, u8 sta_id)
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
{
int ret;
lockdep_assert_held(&priv->mutex);
- priv->key_mapping_key++;
+ ctx->key_mapping_keys++;
keyconf->hw_key_idx = HW_KEY_DYNAMIC;
- switch (keyconf->alg) {
- case ALG_CCMP:
- ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
+ ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
break;
- case ALG_TKIP:
- ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
+ case WLAN_CIPHER_SUITE_TKIP:
+ ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
break;
- case ALG_WEP:
- ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
break;
default:
IWL_ERR(priv,
- "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ "Unknown alg: %s cipher = %x\n", __func__,
+ keyconf->cipher);
ret = -EINVAL;
}
- IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
- keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->cipher, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
return ret;
@@ -1147,16 +1171,16 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
* RXON flags are updated and when LQ command is updated.
*/
static bool is_lq_table_valid(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq)
{
int i;
- struct iwl_ht_config *ht_conf = &priv->current_ht_config;
- if (ht_conf->is_ht)
+ if (ctx->ht.enabled)
return true;
IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
- priv->active_rxon.channel);
+ ctx->active.channel);
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
IWL_DEBUG_INFO(priv,
@@ -1178,7 +1202,7 @@ static bool is_lq_table_valid(struct iwl_priv *priv,
* this case to clear the state indicating that station creation is in
* progress.
*/
-int iwl_send_lq_cmd(struct iwl_priv *priv,
+int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct iwl_link_quality_cmd *lq, u8 flags, bool init)
{
int ret = 0;
@@ -1197,7 +1221,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
iwl_dump_lq_cmd(priv, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));
- if (is_lq_table_valid(priv, lq))
+ if (is_lq_table_valid(priv, ctx, lq))
ret = iwl_send_cmd(priv, &cmd);
else
ret = -EINVAL;
@@ -1223,14 +1247,15 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
* and marks it driver active, so that it will be restored to the
* device at the next best time.
*/
-int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq)
+int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ bool init_lq)
{
struct iwl_link_quality_cmd *link_cmd;
unsigned long flags;
u8 sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
- sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL);
+ sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Unable to prepare broadcast station\n");
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -1265,11 +1290,12 @@ EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
* Only used by iwlagn. Placed here to have all bcast station management
* code together.
*/
-int iwl_update_bcast_station(struct iwl_priv *priv)
+static int iwl_update_bcast_station(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
{
unsigned long flags;
struct iwl_link_quality_cmd *link_cmd;
- u8 sta_id = priv->hw_params.bcast_sta_id;
+ u8 sta_id = ctx->bcast_sta_id;
link_cmd = iwl_sta_alloc_lq(priv, sta_id);
if (!link_cmd) {
@@ -1287,9 +1313,23 @@ int iwl_update_bcast_station(struct iwl_priv *priv)
return 0;
}
-EXPORT_SYMBOL_GPL(iwl_update_bcast_station);
-void iwl_dealloc_bcast_station(struct iwl_priv *priv)
+int iwl_update_bcast_stations(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+ int ret = 0;
+
+ for_each_context(priv, ctx) {
+ ret = iwl_update_bcast_station(priv, ctx);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iwl_update_bcast_stations);
+
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
{
unsigned long flags;
int i;
@@ -1307,7 +1347,7 @@ void iwl_dealloc_bcast_station(struct iwl_priv *priv)
}
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
-EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);
+EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
/**
* iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index d38a350ba0bd..56bad3f60d81 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -44,32 +44,37 @@
int iwl_remove_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *key);
-int iwl_restore_default_wep_keys(struct iwl_priv *priv);
-int iwl_set_dynamic_key(struct iwl_priv *priv,
+int iwl_restore_default_wep_keys(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *key, u8 sta_id);
-int iwl_remove_dynamic_key(struct iwl_priv *priv,
+int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
struct ieee80211_key_conf *key, u8 sta_id);
void iwl_update_tkip_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
-
-void iwl_restore_stations(struct iwl_priv *priv);
-void iwl_clear_ucode_stations(struct iwl_priv *priv);
-int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq);
-void iwl_dealloc_bcast_station(struct iwl_priv *priv);
-int iwl_update_bcast_station(struct iwl_priv *priv);
+ struct iwl_rxon_context *ctx,
+ struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
+
+void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+void iwl_clear_ucode_stations(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx);
+int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ bool init_lq);
+void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
+int iwl_update_bcast_stations(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags);
-int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
- u8 *sta_id_r);
-int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
- bool is_ap,
- struct ieee80211_sta_ht_cap *ht_info,
- u8 *sta_id_r);
+int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool init_rs, u8 *sta_id_r);
+int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+ const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta, u8 *sta_id_r);
int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
const u8 *addr);
int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -94,20 +99,25 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
{
unsigned long flags;
+ struct iwl_rxon_context *ctx;
spin_lock_irqsave(&priv->sta_lock, flags);
memset(priv->stations, 0, sizeof(priv->stations));
priv->num_stations = 0;
- /*
- * Remove all key information that is not stored as part of station
- * information since mac80211 may not have had a
- * chance to remove all the keys. When device is reconfigured by
- * mac80211 after an error all keys will be reconfigured.
- */
priv->ucode_key_table = 0;
- priv->key_mapping_key = 0;
- memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
+
+ for_each_context(priv, ctx) {
+ /*
+ * Remove all key information that is not stored as part
+ * of station information since mac80211 may not have had
+ * a chance to remove all the keys. When device is
+ * reconfigured by mac80211 after an error all keys will
+ * be reconfigured.
+ */
+ memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
+ ctx->key_mapping_keys = 0;
+ }
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
@@ -123,6 +133,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
/**
* iwl_sta_id_or_broadcast - return sta_id or broadcast sta
* @priv: iwl priv
+ * @context: the current context
* @sta: mac80211 station
*
* In certain circumstances mac80211 passes a station pointer
@@ -131,12 +142,13 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
* inline wraps that pattern.
*/
static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
+ struct iwl_rxon_context *context,
struct ieee80211_sta *sta)
{
int sta_id;
if (!sta)
- return priv->hw_params.bcast_sta_id;
+ return context->bcast_sta_id;
sta_id = iwl_sta_id(sta);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index a81989c06983..347d3dc6a015 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -134,7 +134,7 @@ EXPORT_SYMBOL(iwl_tx_queue_free);
*/
void iwl_cmd_queue_free(struct iwl_priv *priv)
{
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
struct device *dev = &priv->pci_dev->dev;
int i;
@@ -271,7 +271,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
+ if (id != priv->cmd_queue) {
txq->txb = kzalloc(sizeof(txq->txb[0]) *
TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->txb) {
@@ -314,13 +314,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
/*
* Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
+ * For the command queue (#4/#9), allocate command space + one big
* command for scan, since scan command is very huge; the system will
* not have two scans at the same time, so only one is needed.
* For normal Tx queues (all other queues), no super-size command
* space is needed.
*/
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
actual_slots++;
txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
@@ -355,7 +355,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
* need an swq_id so don't set one to catch errors, all others can
* be set up to the identity mapping.
*/
- if (txq_id != IWL_CMD_QUEUE_NUM)
+ if (txq_id != priv->cmd_queue)
txq->swq_id = txq_id;
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -385,7 +385,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
{
int actual_slots = slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
+ if (txq_id == priv->cmd_queue)
actual_slots++;
memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
@@ -413,7 +413,7 @@ EXPORT_SYMBOL(iwl_tx_queue_reset);
*/
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
struct iwl_queue *q = &txq->q;
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
@@ -422,6 +422,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
int len;
u32 idx;
u16 fix_size;
+ bool is_ct_kill = false;
cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
@@ -443,9 +444,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
IWL_ERR(priv, "No space in command queue\n");
- if (iwl_within_ct_kill_margin(priv))
- iwl_tt_enter_ct_kill(priv);
- else {
+ if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
+ is_ct_kill =
+ priv->cfg->ops->lib->tt_ops.ct_kill_check(priv);
+ }
+ if (!is_ct_kill) {
IWL_ERR(priv, "Restarting adapter due to queue full\n");
queue_work(priv->workqueue, &priv->restart);
}
@@ -480,7 +483,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
* information */
out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
+ out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) |
INDEX_TO_SEQ(q->write_ptr));
if (cmd->flags & CMD_SIZE_HUGE)
out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
@@ -497,15 +500,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
le16_to_cpu(out_cmd->hdr.sequence), fix_size,
- q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
- break;
+ q->write_ptr, idx, priv->cmd_queue);
+ break;
default:
IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
le16_to_cpu(out_cmd->hdr.sequence), fix_size,
- q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
+ q->write_ptr, idx, priv->cmd_queue);
}
#endif
txq->need_update = 1;
@@ -584,16 +587,16 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
struct iwl_device_cmd *cmd;
struct iwl_cmd_meta *meta;
- struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
/* If a Tx command is being handled and it isn't in the actual
* command queue then there a command routing bug has been introduced
* in the queue management code. */
- if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
- "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
- txq_id, sequence,
- priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
- priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
+ if (WARN(txq_id != priv->cmd_queue,
+ "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
+ txq_id, priv->cmd_queue, sequence,
+ priv->txq[priv->cmd_queue].q.read_ptr,
+ priv->txq[priv->cmd_queue].q.write_ptr)) {
iwl_print_hex_error(priv, pkt, 32);
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 59a308b02f95..116777122a79 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -143,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- if (sta_id == priv->hw_params.bcast_sta_id)
+ if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -151,7 +152,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags &= ~STA_KEY_FLG_INVALID;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
keyconf->keylen);
@@ -222,23 +223,25 @@ static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
keyconf->hw_key_idx = HW_KEY_DYNAMIC;
- switch (keyconf->alg) {
- case ALG_CCMP:
+ switch (keyconf->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__,
+ keyconf->cipher);
ret = -EINVAL;
}
- IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
- keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->cipher, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
return ret;
@@ -254,10 +257,11 @@ static int iwl3945_remove_static_key(struct iwl_priv *priv)
static int iwl3945_set_static_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key)
{
- if (key->alg == ALG_WEP)
+ if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104)
return -EOPNOTSUPP;
- IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+ IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher);
return -EINVAL;
}
@@ -313,7 +317,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
int left)
{
- if (!iwl_is_associated(priv) || !priv->ibss_beacon)
+ if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon)
return 0;
if (priv->ibss_beacon->len > left)
@@ -339,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
return -ENOMEM;
}
- rate = iwl_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv,
+ &priv->contexts[IWL_RXON_CTX_BSS]);
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
@@ -369,23 +374,25 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
- switch (keyinfo->alg) {
- case ALG_CCMP:
+ tx_cmd->sec_ctl = 0;
+
+ switch (keyinfo->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
break;
- case ALG_WEP:
- tx_cmd->sec_ctl = TX_CMD_SEC_WEP |
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
+ /* fall through */
+ case WLAN_CIPHER_SUITE_WEP40:
+ tx_cmd->sec_ctl |= TX_CMD_SEC_WEP |
(info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
- if (keyinfo->keylen == 13)
- tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
-
memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
@@ -393,7 +400,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
break;
default:
- IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
+ IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher);
break;
}
}
@@ -506,7 +513,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(
+ priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -536,6 +545,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb = skb;
+ txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS];
/* Init first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[idx];
@@ -677,11 +687,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
int rc;
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- if (iwl_is_associated(priv))
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
add_time = iwl_usecs_to_beacons(priv,
le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
- le16_to_cpu(priv->rxon_timing.beacon_interval));
+ le16_to_cpu(ctx->timing.beacon_interval));
memset(&spectrum, 0, sizeof(spectrum));
@@ -692,18 +703,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
cmd.len = sizeof(spectrum);
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
- if (iwl_is_associated(priv))
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
spectrum.start_time =
iwl_add_beacon_time(priv,
priv->_3945.last_beacon_time, add_time,
- le16_to_cpu(priv->rxon_timing.beacon_interval));
+ le16_to_cpu(ctx->timing.beacon_interval));
else
spectrum.start_time = 0;
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
spectrum.channels[0].channel = params->channel;
spectrum.channels[0].type = type;
- if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
@@ -792,7 +803,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+ beacon = ieee80211_beacon_get(priv->hw,
+ priv->contexts[IWL_RXON_CTX_BSS].vif);
if (!beacon) {
IWL_ERR(priv, "update beacon failed\n");
@@ -813,9 +825,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
+#ifdef CONFIG_IWLWIFI_DEBUG
u8 rate = beacon->beacon_notify_hdr.rate;
IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
@@ -827,6 +839,8 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
le32_to_cpu(beacon->low_tsf), rate);
#endif
+ priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
+
if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
(!test_bit(STATUS_EXIT_PENDING, &priv->status)))
queue_work(priv->workqueue, &priv->beacon_update);
@@ -1716,7 +1730,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
IWL_ERR(priv, "Microcode SW error detected. "
"Restarting 0x%X.\n", inta);
priv->isr_stats.sw++;
- priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -2460,6 +2473,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
{
int thermal_spin = 0;
u32 rfkill;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
@@ -2517,22 +2531,22 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl_power_update_mode(priv, true);
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
struct iwl3945_rxon_cmd *active_rxon =
- (struct iwl3945_rxon_cmd *)(&priv->active_rxon);
+ (struct iwl3945_rxon_cmd *)(&ctx->active);
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, NULL);
+ iwl_connection_init_rx_config(priv, ctx);
}
/* Configure Bluetooth device coexistence support */
priv->cfg->ops->hcmd->send_bt_config(priv);
/* Configure the adapter for unassociated operation */
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
iwl3945_reg_txpower_periodic(priv);
@@ -2553,19 +2567,22 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl3945_down(struct iwl_priv *priv)
{
unsigned long flags;
- int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
- struct ieee80211_conf *conf = NULL;
+ int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
- conf = ieee80211_get_hw_conf(priv->hw);
+ iwl_scan_cancel_timeout(priv, 200);
- if (!exit_pending)
- set_bit(STATUS_EXIT_PENDING, &priv->status);
+ exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
+
+ /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
+ * to prevent rearm timer */
+ if (priv->cfg->ops->lib->recover_from_tx_stall)
+ del_timer_sync(&priv->monitor_recover);
/* Station information will now be cleared in device */
- iwl_clear_ucode_stations(priv);
- iwl_dealloc_bcast_station(priv);
+ iwl_clear_ucode_stations(priv, NULL);
+ iwl_dealloc_bcast_stations(priv);
iwl_clear_driver_stations(priv);
/* Unblock any waiting calls */
@@ -2647,7 +2664,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;
- rc = iwl_alloc_bcast_station(priv, false);
+ rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ false);
if (rc)
return rc;
@@ -2799,7 +2817,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
}
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -2807,61 +2825,19 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
.flags = CMD_SIZE_HUGE,
};
struct iwl3945_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
u8 n_probes = 0;
enum ieee80211_band band;
bool is_active = false;
+ int ret;
- conf = ieee80211_get_hw_conf(priv->hw);
-
- cancel_delayed_work(&priv->scan_check);
-
- if (!iwl_is_ready(priv)) {
- IWL_WARN(priv, "request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't canceled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
- "Ignoring second request.\n");
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC(priv,
- "Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
- goto done;
- }
-
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC(priv,
- "Scan request while uninitialized. Queuing.\n");
- goto done;
- }
+ lockdep_assert_held(&priv->mutex);
if (!priv->scan_cmd) {
priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
- goto done;
+ return -ENOMEM;
}
}
scan = priv->scan_cmd;
@@ -2870,7 +2846,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl_is_associated(priv)) {
+ if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
@@ -2931,7 +2907,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -2956,7 +2932,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
break;
default:
IWL_WARN(priv, "Invalid scan band\n");
- goto done;
+ return -EIO;
}
if (!priv->is_internal_short_scan) {
@@ -2991,7 +2967,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
- goto done;
+ return -EIO;
}
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -3000,25 +2976,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->len = cpu_to_le16(cmd.len);
set_bit(STATUS_SCAN_HW, &priv->status);
- if (iwl_send_cmd_sync(priv, &cmd))
- goto done;
-
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
-
- return;
-
- done:
- /* can not perform scan make sure we clear scanning
- * bits from status so next scan request can be performed.
- * if we dont clear scanning status bit here all next scan
- * will fail
- */
- clear_bit(STATUS_SCAN_HW, &priv->status);
- clear_bit(STATUS_SCANNING, &priv->status);
-
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ return ret;
}
static void iwl3945_bg_restart(struct work_struct *data)
@@ -3029,8 +2990,10 @@ static void iwl3945_bg_restart(struct work_struct *data)
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ struct iwl_rxon_context *ctx;
mutex_lock(&priv->mutex);
- priv->vif = NULL;
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
priv->is_open = 0;
mutex_unlock(&priv->mutex);
iwl3945_down(priv);
@@ -3064,6 +3027,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (!vif || !priv->is_open)
return;
@@ -3074,7 +3038,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
}
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- vif->bss_conf.aid, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, ctx->active.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -3083,37 +3047,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
conf = ieee80211_get_hw_conf(priv->hw);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
- memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv, vif);
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ rc = iwl_send_rxon_timing(priv, ctx);
if (rc)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
vif->bss_conf.aid, vif->bss_conf.beacon_int);
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -3212,15 +3173,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
- if (iwl_is_ready_rf(priv)) {
- /* stop mac, cancel any scan request and clear
- * RXON_FILTER_ASSOC_MSK BIT
- */
- mutex_lock(&priv->mutex);
- iwl_scan_cancel_timeout(priv, 100);
- mutex_unlock(&priv->mutex);
- }
-
iwl3945_down(priv);
flush_workqueue(priv->workqueue);
@@ -3250,48 +3202,45 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int rc = 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
- if (!(iwl_is_associated(priv))) {
+ if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) {
/* RXON - unassoc (to set timing command) */
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv, vif);
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing),
- &priv->rxon_timing);
+ rc = iwl_send_rxon_timing(priv, ctx);
if (rc)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- priv->staging_rxon.assoc_id = 0;
+ ctx->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- priv->staging_rxon.flags |=
+ ctx->staging.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &=
+ ctx->staging.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
/* restore RXON assoc */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwlcore_commit_rxon(priv);
+ ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ iwlcore_commit_rxon(priv, ctx);
}
iwl3945_send_beacon_cmd(priv);
@@ -3317,10 +3266,11 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- static_key = !iwl_is_associated(priv);
+ static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS);
if (!static_key) {
- sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ sta_id = iwl_sta_id_or_broadcast(
+ priv, &priv->contexts[IWL_RXON_CTX_BSS], sta);
if (sta_id == IWL_INVALID_STATION)
return -EINVAL;
}
@@ -3371,8 +3321,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
sta_priv->common.sta_id = IWL_INVALID_STATION;
- ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
- &sta_id);
+ ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS],
+ sta->addr, is_ap, sta, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
sta->addr, ret);
@@ -3399,6 +3349,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
@@ -3418,8 +3369,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
- priv->staging_rxon.filter_flags &= ~filter_nand;
- priv->staging_rxon.filter_flags |= filter_or;
+ ctx->staging.filter_flags &= ~filter_nand;
+ ctx->staging.filter_flags |= filter_or;
/*
* Committing directly here breaks for some reason,
@@ -3533,8 +3484,9 @@ static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
- return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
+ return sprintf(buf, "0x%04X\n", ctx->active.flags);
}
static ssize_t store_flags(struct device *d,
@@ -3543,17 +3495,18 @@ static ssize_t store_flags(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
+ if (le32_to_cpu(ctx->staging.flags) != flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
- priv->staging_rxon.flags = cpu_to_le32(flags);
- iwlcore_commit_rxon(priv);
+ ctx->staging.flags = cpu_to_le32(flags);
+ iwlcore_commit_rxon(priv, ctx);
}
}
mutex_unlock(&priv->mutex);
@@ -3567,9 +3520,10 @@ static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
return sprintf(buf, "0x%04X\n",
- le32_to_cpu(priv->active_rxon.filter_flags));
+ le32_to_cpu(ctx->active.filter_flags));
}
static ssize_t store_filter_flags(struct device *d,
@@ -3577,19 +3531,20 @@ static ssize_t store_filter_flags(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
+ if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
- priv->staging_rxon.filter_flags =
+ ctx->staging.filter_flags =
cpu_to_le32(filter_flags);
- iwlcore_commit_rxon(priv);
+ iwlcore_commit_rxon(priv, ctx);
}
}
mutex_unlock(&priv->mutex);
@@ -3637,8 +3592,9 @@ static ssize_t store_measurement(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct ieee80211_measurement_params params = {
- .channel = le16_to_cpu(priv->active_rxon.channel),
+ .channel = le16_to_cpu(ctx->active.channel),
.start_time = cpu_to_le64(priv->_3945.last_tsf),
.duration = cpu_to_le16(1),
};
@@ -3785,10 +3741,8 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
- INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
- INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
- INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
- INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
+
+ iwl_setup_scan_deferred_work(priv);
iwl3945_hw_setup_deferred_work(priv);
@@ -3808,12 +3762,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
iwl3945_hw_cancel_deferred_work(priv);
cancel_delayed_work_sync(&priv->init_alive_start);
- cancel_delayed_work(&priv->scan_check);
cancel_delayed_work(&priv->alive_start);
- cancel_work_sync(&priv->start_internal_scan);
cancel_work_sync(&priv->beacon_update);
- if (priv->cfg->ops->lib->recover_from_tx_stall)
- del_timer_sync(&priv->monitor_recover);
+
+ iwl_cancel_scan_deferred_work(priv);
}
static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3853,6 +3805,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.hw_scan = iwl_mac_hw_scan,
.sta_add = iwl3945_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
+ .tx_last_beacon = iwl_mac_tx_last_beacon,
};
static int iwl3945_init_drv(struct iwl_priv *priv)
@@ -3933,8 +3886,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes;
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -3966,7 +3918,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int err = 0;
+ int err = 0, i;
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3988,6 +3940,27 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv = hw->priv;
SET_IEEE80211_DEV(hw, &pdev->dev);
+ priv->cmd_queue = IWL39_CMD_QUEUE_NUM;
+
+ /* 3945 has only one valid context */
+ priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
+
+ for (i = 0; i < NUM_IWL_RXON_CTX; i++)
+ priv->contexts[i].ctxid = i;
+
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
+ priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
+ priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
+ priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
+ priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+ priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
+ priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
+ priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
+
/*
* Disabling hardware scan means that mac80211 will perform scans
* "the hard way", rather than using device's scan.
@@ -4009,6 +3982,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/***************************
* 2. Initializing PCI bus
* *************************/
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
if (pci_enable_device(pdev)) {
err = -ENODEV;
goto out_ieee80211_free_hw;
@@ -4120,7 +4096,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
}
iwl_set_rxon_channel(priv,
- &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
+ &priv->bands[IEEE80211_BAND_2GHZ].channels[5],
+ &priv->contexts[IWL_RXON_CTX_BSS]);
iwl3945_setup_deferred_work(priv);
iwl3945_setup_rx_handlers(priv);
iwl_power_initialize(priv);
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index 53b0b7711f02..85f650ed9fb3 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -402,24 +402,28 @@ static const struct file_operations iwm_debugfs_txq_fops = {
.owner = THIS_MODULE,
.open = iwm_generic_open,
.read = iwm_debugfs_txq_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations iwm_debugfs_tx_credit_fops = {
.owner = THIS_MODULE,
.open = iwm_generic_open,
.read = iwm_debugfs_tx_credit_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations iwm_debugfs_rx_ticket_fops = {
.owner = THIS_MODULE,
.open = iwm_generic_open,
.read = iwm_debugfs_rx_ticket_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations iwm_debugfs_fw_err_fops = {
.owner = THIS_MODULE,
.open = iwm_generic_open,
.read = iwm_debugfs_fw_err_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
void iwm_debugfs_init(struct iwm_priv *iwm)
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index c02fcedea9fa..a944893ae3ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1195,11 +1195,8 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
"oid is 0x%x\n", hdr->oid);
- if (hdr->oid <= WIFI_IF_NTFY_MAX) {
- set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
- wake_up_interruptible(&iwm->wifi_ntfy_queue);
- } else
- return -EINVAL;
+ set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
+ wake_up_interruptible(&iwm->wifi_ntfy_queue);
switch (hdr->oid) {
case UMAC_WIFI_IF_CMD_SET_PROFILE:
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index edcb52330cf5..d2e36029ef36 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -364,6 +364,7 @@ static const struct file_operations iwm_debugfs_sdio_fops = {
.owner = THIS_MODULE,
.open = iwm_debugfs_sdio_open,
.read = iwm_debugfs_sdio_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir)
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 3e82f1627209..317f086ced0a 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -10,6 +10,7 @@
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/wait.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <asm/unaligned.h>
@@ -526,20 +527,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
pos = scanresp->bssdesc_and_tlvbuffer;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
+ scanresp->bssdescriptsize);
+
tsfdesc = pos + bsssize;
tsfsize = 4 + 8 * scanresp->nr_sets;
+ lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
/* Validity check: we expect a Marvell-Local TLV */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i != TLV_TYPE_TSFTIMESTAMP)
+ if (i != TLV_TYPE_TSFTIMESTAMP) {
+ lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
goto done;
+ }
+
/* Validity check: the TLV holds TSF values with 8 bytes each, so
* the size in the TLV must match the nr_sets value */
i = get_unaligned_le16(tsfdesc);
tsfdesc += 2;
- if (i / 8 != scanresp->nr_sets)
+ if (i / 8 != scanresp->nr_sets) {
+ lbs_deb_scan("scan response: invalid number of TSF timestamp "
+ "sets (expected %d got %d)\n", scanresp->nr_sets,
+ i / 8);
goto done;
+ }
for (i = 0; i < scanresp->nr_sets; i++) {
const u8 *bssid;
@@ -581,8 +593,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
id = *pos++;
elen = *pos++;
left -= 2;
- if (elen > left || elen == 0)
+ if (elen > left || elen == 0) {
+ lbs_deb_scan("scan response: invalid IE fmt\n");
goto done;
+ }
+
if (id == WLAN_EID_DS_PARAMS)
chan_no = *pos;
if (id == WLAN_EID_SSID) {
@@ -613,7 +628,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
capa, intvl, ie, ielen,
LBS_SCAN_RSSI_TO_MBM(rssi),
GFP_KERNEL);
- }
+ } else
+ lbs_deb_scan("scan response: missing BSS channel IE\n");
+
tsfdesc += 8;
}
ret = 0;
@@ -1103,7 +1120,7 @@ static int lbs_associate(struct lbs_private *priv,
lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
/* add auth type TLV */
- if (priv->fwrelease >= 0x09000000)
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
/* add WPA/WPA2 TLV */
@@ -1114,6 +1131,9 @@ static int lbs_associate(struct lbs_private *priv,
(u16)(pos - (u8 *) &cmd->iebuf);
cmd->hdr.size = cpu_to_le16(len);
+ lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
+ le16_to_cpu(cmd->hdr.size));
+
/* store for later use */
memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
@@ -1121,14 +1141,28 @@ static int lbs_associate(struct lbs_private *priv,
if (ret)
goto done;
-
/* generate connect message to cfg80211 */
resp = (void *) cmd; /* recast for easier field access */
status = le16_to_cpu(resp->statuscode);
- /* Convert statis code of old firmware */
- if (priv->fwrelease < 0x09000000)
+ /* Older FW versions map the IEEE 802.11 Status Code in the association
+ * response to the following values returned in resp->statuscode:
+ *
+ * IEEE Status Code Marvell Status Code
+ * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
+ * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
+ * others -> 0x0003 ASSOC_RESULT_REFUSED
+ *
+ * Other response codes:
+ * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
+ * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
+ * association response from the AP)
+ */
+ if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
switch (status) {
case 0:
break;
@@ -1150,11 +1184,16 @@ static int lbs_associate(struct lbs_private *priv,
break;
default:
lbs_deb_assoc("association failure %d\n", status);
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ /* v5 OLPC firmware does return the AP status code if
+ * it's not one of the values above. Let that through.
+ */
+ break;
+ }
}
- lbs_deb_assoc("status %d, capability 0x%04x\n", status,
- le16_to_cpu(resp->capability));
+ lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
+ "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
+ le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
resp_ie_len = le16_to_cpu(resp->hdr.size)
- sizeof(resp->hdr)
@@ -1174,7 +1213,6 @@ static int lbs_associate(struct lbs_private *priv,
netif_tx_wake_all_queues(priv->dev);
}
-
done:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 651a79c8de8a..9f7f805ca4a8 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -696,6 +696,7 @@ out_unlock:
.open = open_file_generic, \
.read = (fread), \
.write = (fwrite), \
+ .llseek = generic_file_llseek, \
}
struct lbs_debugfs_files {
@@ -961,6 +962,7 @@ static const struct file_operations lbs_debug_fops = {
.open = open_file_generic,
.write = lbs_debugfs_write,
.read = lbs_debugfs_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
/**
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 1d141fefd767..2ae752d10065 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -8,7 +8,14 @@
#define _LBS_DECL_H_
#include <linux/netdevice.h>
+#include <linux/firmware.h>
+/* Should be terminated by a NULL entry */
+struct lbs_fw_table {
+ int model;
+ const char *helper;
+ const char *fwname;
+};
struct lbs_private;
struct sk_buff;
@@ -53,4 +60,10 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
u32 lbs_fw_index_to_data_rate(u8 index);
u8 lbs_data_rate_to_fw_index(u32 rate);
+int lbs_get_firmware(struct device *dev, const char *user_helper,
+ const char *user_mainfw, u32 card_model,
+ const struct lbs_fw_table *fw_table,
+ const struct firmware **helper,
+ const struct firmware **mainfw);
+
#endif
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 9c298396be50..e213a5dc049d 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -48,7 +48,6 @@
MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("libertas_cs_helper.fw");
@@ -61,9 +60,34 @@ struct if_cs_card {
struct lbs_private *priv;
void __iomem *iobase;
bool align_regs;
+ u32 model;
};
+enum {
+ MODEL_UNKNOWN = 0x00,
+ MODEL_8305 = 0x01,
+ MODEL_8381 = 0x02,
+ MODEL_8385 = 0x03
+};
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8305, "libertas/cf8305.bin", NULL },
+ { MODEL_8305, "libertas_cs_helper.fw", NULL },
+ { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" },
+ { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" },
+ { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" },
+ { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" },
+ { 0, NULL, NULL }
+};
+MODULE_FIRMWARE("libertas/cf8305.bin");
+MODULE_FIRMWARE("libertas/cf8381_helper.bin");
+MODULE_FIRMWARE("libertas/cf8381.bin");
+MODULE_FIRMWARE("libertas/cf8385_helper.bin");
+MODULE_FIRMWARE("libertas/cf8385.bin");
+MODULE_FIRMWARE("libertas_cs_helper.fw");
+MODULE_FIRMWARE("libertas_cs.fw");
+
/********************************************************************/
/* Hardware access */
@@ -289,22 +313,19 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
#define CF8385_MANFID 0x02df
#define CF8385_CARDID 0x8103
-static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev)
-{
- return (p_dev->manf_id == CF8305_MANFID &&
- p_dev->card_id == CF8305_CARDID);
-}
-
-static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
-{
- return (p_dev->manf_id == CF8381_MANFID &&
- p_dev->card_id == CF8381_CARDID);
-}
-
-static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
+/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
+ * that gets fixed. Currently there's no way to access it from the probe hook.
+ */
+static inline u32 get_model(u16 manf_id, u16 card_id)
{
- return (p_dev->manf_id == CF8385_MANFID &&
- p_dev->card_id == CF8385_CARDID);
+ /* NOTE: keep in sync with if_cs_ids */
+ if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID)
+ return MODEL_8305;
+ else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID)
+ return MODEL_8381;
+ else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID)
+ return MODEL_8385;
+ return MODEL_UNKNOWN;
}
/********************************************************************/
@@ -558,12 +579,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
*
* Return 0 on success
*/
-static int if_cs_prog_helper(struct if_cs_card *card)
+static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
{
int ret = 0;
int sent = 0;
u8 scratch;
- const struct firmware *fw;
lbs_deb_enter(LBS_DEB_CS);
@@ -589,14 +609,6 @@ static int if_cs_prog_helper(struct if_cs_card *card)
goto done;
}
- /* TODO: make firmware file configurable */
- ret = request_firmware(&fw, "libertas_cs_helper.fw",
- &card->p_dev->dev);
- if (ret) {
- lbs_pr_err("can't load helper firmware\n");
- ret = -ENODEV;
- goto done;
- }
lbs_deb_cs("helper size %td\n", fw->size);
/* "Set the 5 bytes of the helper image to 0" */
@@ -635,7 +647,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
if (ret < 0) {
lbs_pr_err("can't download helper at 0x%x, ret %d\n",
sent, ret);
- goto err_release;
+ goto done;
}
if (count == 0)
@@ -644,17 +656,14 @@ static int if_cs_prog_helper(struct if_cs_card *card)
sent += count;
}
-err_release:
- release_firmware(fw);
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
}
-static int if_cs_prog_real(struct if_cs_card *card)
+static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
{
- const struct firmware *fw;
int ret = 0;
int retry = 0;
int len = 0;
@@ -662,21 +671,13 @@ static int if_cs_prog_real(struct if_cs_card *card)
lbs_deb_enter(LBS_DEB_CS);
- /* TODO: make firmware file configurable */
- ret = request_firmware(&fw, "libertas_cs.fw",
- &card->p_dev->dev);
- if (ret) {
- lbs_pr_err("can't load firmware\n");
- ret = -ENODEV;
- goto done;
- }
lbs_deb_cs("fw size %td\n", fw->size);
ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
IF_CS_SQ_HELPER_OK);
if (ret < 0) {
lbs_pr_err("helper firmware doesn't answer\n");
- goto err_release;
+ goto done;
}
for (sent = 0; sent < fw->size; sent += len) {
@@ -691,7 +692,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
if (retry > 20) {
lbs_pr_err("could not download firmware\n");
ret = -ENODEV;
- goto err_release;
+ goto done;
}
if (retry) {
sent -= len;
@@ -710,7 +711,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
IF_CS_BIT_COMMAND);
if (ret < 0) {
lbs_pr_err("can't download firmware at 0x%x\n", sent);
- goto err_release;
+ goto done;
}
}
@@ -718,9 +719,6 @@ static int if_cs_prog_real(struct if_cs_card *card)
if (ret < 0)
lbs_pr_err("firmware download failed\n");
-err_release:
- release_firmware(fw);
-
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
@@ -824,6 +822,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_CS);
@@ -843,7 +843,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
goto out1;
}
-
/*
* Allocate an interrupt line. Note that this does not assign
* a handler to the interrupt, unless the 'Handler' member of
@@ -881,34 +880,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
*/
card->align_regs = 0;
+ card->model = get_model(p_dev->manf_id, p_dev->card_id);
+ if (card->model == MODEL_UNKNOWN) {
+ lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
+ p_dev->manf_id, p_dev->card_id);
+ goto out2;
+ }
+
/* Check if we have a current silicon */
prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
- if (if_cs_hw_is_cf8305(p_dev)) {
+ if (card->model == MODEL_8305) {
card->align_regs = 1;
if (prod_id < IF_CS_CF8305_B1_REV) {
- lbs_pr_err("old chips like 8305 rev B3 "
- "aren't supported\n");
+ lbs_pr_err("8305 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
}
- if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
- lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
+ if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
+ lbs_pr_err("8381 rev B2 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
- if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) {
- lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
+ if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
+ lbs_pr_err("8385 rev B0 and older are not supported\n");
ret = -ENODEV;
goto out2;
}
+ ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
+ &fw_table[0], &helper, &mainfw);
+ if (ret) {
+ lbs_pr_err("failed to find firmware (%d)\n", ret);
+ goto out2;
+ }
+
/* Load the firmware early, before calling into libertas.ko */
- ret = if_cs_prog_helper(card);
- if (ret == 0 && !if_cs_hw_is_cf8305(p_dev))
- ret = if_cs_prog_real(card);
+ ret = if_cs_prog_helper(card, helper);
+ if (ret == 0 && (card->model != MODEL_8305))
+ ret = if_cs_prog_real(card, mainfw);
if (ret)
goto out2;
@@ -957,6 +969,11 @@ out2:
out1:
pcmcia_disable_device(p_dev);
out:
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
}
@@ -993,6 +1010,7 @@ static struct pcmcia_device_id if_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
+ /* NOTE: keep in sync with get_model() */
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index ba854c70ab94..296fd00a5129 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -76,36 +76,32 @@ static const struct sdio_device_id if_sdio_ids[] = {
MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
-struct if_sdio_model {
- int model;
- const char *helper;
- const char *firmware;
-};
-
-static struct if_sdio_model if_sdio_models[] = {
- {
- /* 8385 */
- .model = IF_SDIO_MODEL_8385,
- .helper = "sd8385_helper.bin",
- .firmware = "sd8385.bin",
- },
- {
- /* 8686 */
- .model = IF_SDIO_MODEL_8686,
- .helper = "sd8686_helper.bin",
- .firmware = "sd8686.bin",
- },
- {
- /* 8688 */
- .model = IF_SDIO_MODEL_8688,
- .helper = "sd8688_helper.bin",
- .firmware = "sd8688.bin",
- },
+#define MODEL_8385 0x04
+#define MODEL_8686 0x0b
+#define MODEL_8688 0x10
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" },
+ { MODEL_8385, "sd8385_helper.bin", "sd8385.bin" },
+ { MODEL_8686, "libertas/sd8686_v9_helper.bin", "libertas/sd8686_v9.bin" },
+ { MODEL_8686, "libertas/sd8686_v8_helper.bin", "libertas/sd8686_v8.bin" },
+ { MODEL_8686, "sd8686_helper.bin", "sd8686.bin" },
+ { MODEL_8688, "libertas/sd8688_helper.bin", "libertas/sd8688.bin" },
+ { MODEL_8688, "sd8688_helper.bin", "sd8688.bin" },
+ { 0, NULL, NULL }
};
+MODULE_FIRMWARE("libertas/sd8385_helper.bin");
+MODULE_FIRMWARE("libertas/sd8385.bin");
MODULE_FIRMWARE("sd8385_helper.bin");
MODULE_FIRMWARE("sd8385.bin");
+MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin");
+MODULE_FIRMWARE("libertas/sd8686_v9.bin");
+MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin");
+MODULE_FIRMWARE("libertas/sd8686_v8.bin");
MODULE_FIRMWARE("sd8686_helper.bin");
MODULE_FIRMWARE("sd8686.bin");
+MODULE_FIRMWARE("libertas/sd8688_helper.bin");
+MODULE_FIRMWARE("libertas/sd8688.bin");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
@@ -128,7 +124,7 @@ struct if_sdio_card {
bool helper_allocated;
bool firmware_allocated;
- u8 buffer[65536];
+ u8 buffer[65536] __attribute__((aligned(4)));
spinlock_t lock;
struct if_sdio_packet *packets;
@@ -187,11 +183,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
u16 rx_len;
switch (card->model) {
- case IF_SDIO_MODEL_8385:
- case IF_SDIO_MODEL_8686:
+ case MODEL_8385:
+ case MODEL_8686:
rx_len = if_sdio_read_scratch(card, &ret);
break;
- case IF_SDIO_MODEL_8688:
+ case MODEL_8688:
default: /* for newer chipsets */
rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
if (!ret)
@@ -288,7 +284,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
lbs_deb_enter(LBS_DEB_SDIO);
- if (card->model == IF_SDIO_MODEL_8385) {
+ if (card->model == MODEL_8385) {
event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
if (ret)
goto out;
@@ -466,10 +462,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
-static int if_sdio_prog_helper(struct if_sdio_card *card)
+static int if_sdio_prog_helper(struct if_sdio_card *card,
+ const struct firmware *fw)
{
int ret;
- const struct firmware *fw;
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
@@ -478,16 +474,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
- ret = request_firmware(&fw, card->helper, &card->func->dev);
- if (ret) {
- lbs_pr_err("can't load helper firmware\n");
- goto out;
- }
-
chunk_buffer = kzalloc(64, GFP_KERNEL);
if (!chunk_buffer) {
ret = -ENOMEM;
- goto release_fw;
+ goto out;
}
sdio_claim_host(card->func);
@@ -562,22 +552,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
release:
sdio_release_host(card->func);
kfree(chunk_buffer);
-release_fw:
- release_firmware(fw);
out:
if (ret)
lbs_pr_err("failed to load helper firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
return ret;
}
-static int if_sdio_prog_real(struct if_sdio_card *card)
+static int if_sdio_prog_real(struct if_sdio_card *card,
+ const struct firmware *fw)
{
int ret;
- const struct firmware *fw;
unsigned long timeout;
u8 *chunk_buffer;
u32 chunk_size;
@@ -586,16 +573,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
lbs_deb_enter(LBS_DEB_SDIO);
- ret = request_firmware(&fw, card->firmware, &card->func->dev);
- if (ret) {
- lbs_pr_err("can't load firmware\n");
- goto out;
- }
-
chunk_buffer = kzalloc(512, GFP_KERNEL);
if (!chunk_buffer) {
ret = -ENOMEM;
- goto release_fw;
+ goto out;
}
sdio_claim_host(card->func);
@@ -685,15 +666,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
release:
sdio_release_host(card->func);
kfree(chunk_buffer);
-release_fw:
- release_firmware(fw);
out:
if (ret)
lbs_pr_err("failed to load firmware\n");
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
return ret;
}
@@ -701,6 +679,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
{
int ret;
u16 scratch;
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_SDIO);
@@ -718,11 +698,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
goto success;
}
- ret = if_sdio_prog_helper(card);
+ ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
+ card->model, &fw_table[0], &helper, &mainfw);
+ if (ret) {
+ lbs_pr_err("failed to find firmware (%d)\n", ret);
+ goto out;
+ }
+
+ ret = if_sdio_prog_helper(card, helper);
if (ret)
goto out;
- ret = if_sdio_prog_real(card);
+ ret = if_sdio_prog_real(card, mainfw);
if (ret)
goto out;
@@ -733,8 +720,12 @@ success:
ret = 0;
out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
}
@@ -938,7 +929,7 @@ static int if_sdio_probe(struct sdio_func *func,
"ID: %x", &model) == 1)
break;
if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
- model = IF_SDIO_MODEL_8385;
+ model = MODEL_8385;
break;
}
}
@@ -956,13 +947,13 @@ static int if_sdio_probe(struct sdio_func *func,
card->model = model;
switch (card->model) {
- case IF_SDIO_MODEL_8385:
+ case MODEL_8385:
card->scratch_reg = IF_SDIO_SCRATCH_OLD;
break;
- case IF_SDIO_MODEL_8686:
+ case MODEL_8686:
card->scratch_reg = IF_SDIO_SCRATCH;
break;
- case IF_SDIO_MODEL_8688:
+ case MODEL_8688:
default: /* for newer chipsets */
card->scratch_reg = IF_SDIO_FW_STATUS;
break;
@@ -972,49 +963,17 @@ static int if_sdio_probe(struct sdio_func *func,
card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
- for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
- if (card->model == if_sdio_models[i].model)
+ /* Check if we support this card */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (card->model == fw_table[i].model)
break;
}
-
- if (i == ARRAY_SIZE(if_sdio_models)) {
+ if (i == ARRAY_SIZE(fw_table)) {
lbs_pr_err("unknown card model 0x%x\n", card->model);
ret = -ENODEV;
goto free;
}
- card->helper = if_sdio_models[i].helper;
- card->firmware = if_sdio_models[i].firmware;
-
- kparam_block_sysfs_write(helper_name);
- if (lbs_helper_name) {
- char *helper = kstrdup(lbs_helper_name, GFP_KERNEL);
- if (!helper) {
- kparam_unblock_sysfs_write(helper_name);
- ret = -ENOMEM;
- goto free;
- }
- lbs_deb_sdio("overriding helper firmware: %s\n",
- lbs_helper_name);
- card->helper = helper;
- card->helper_allocated = true;
- }
- kparam_unblock_sysfs_write(helper_name);
-
- kparam_block_sysfs_write(fw_name);
- if (lbs_fw_name) {
- char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL);
- if (!fw_name) {
- kparam_unblock_sysfs_write(fw_name);
- ret = -ENOMEM;
- goto free;
- }
- lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
- card->firmware = fw_name;
- card->firmware_allocated = true;
- }
- kparam_unblock_sysfs_write(fw_name);
-
sdio_claim_host(func);
ret = sdio_enable_func(func);
@@ -1028,7 +987,7 @@ static int if_sdio_probe(struct sdio_func *func,
/* For 1-bit transfers to the 8686 model, we need to enable the
* interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
* bit to allow access to non-vendor registers. */
- if ((card->model == IF_SDIO_MODEL_8686) &&
+ if ((card->model == MODEL_8686) &&
(host->caps & MMC_CAP_SDIO_IRQ) &&
(host->ios.bus_width == MMC_BUS_WIDTH_1)) {
u8 reg;
@@ -1091,8 +1050,8 @@ static int if_sdio_probe(struct sdio_func *func,
* Get rx_unit if the chip is SD8688 or newer.
* SD8385 & SD8686 do not have rx_unit.
*/
- if ((card->model != IF_SDIO_MODEL_8385)
- && (card->model != IF_SDIO_MODEL_8686))
+ if ((card->model != MODEL_8385)
+ && (card->model != MODEL_8686))
card->rx_unit = if_sdio_read_rx_unit(card);
else
card->rx_unit = 0;
@@ -1108,7 +1067,7 @@ static int if_sdio_probe(struct sdio_func *func,
/*
* FUNC_INIT is required for SD8688 WLAN/BT multiple functions
*/
- if (card->model == IF_SDIO_MODEL_8688) {
+ if (card->model == MODEL_8688) {
struct cmd_header cmd;
memset(&cmd, 0, sizeof(cmd));
@@ -1165,7 +1124,7 @@ static void if_sdio_remove(struct sdio_func *func)
card = sdio_get_drvdata(func);
- if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
+ if (user_rmmod && (card->model == MODEL_8688)) {
/*
* FUNC_SHUTDOWN is required for SD8688 WLAN/BT
* multiple functions
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 12179c1dc9c9..62fda3592f67 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -12,10 +12,6 @@
#ifndef _LBS_IF_SDIO_H
#define _LBS_IF_SDIO_H
-#define IF_SDIO_MODEL_8385 0x04
-#define IF_SDIO_MODEL_8686 0x0b
-#define IF_SDIO_MODEL_8688 0x10
-
#define IF_SDIO_IOPORT 0x00
#define IF_SDIO_H_INT_MASK 0x04
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index fe3f08028eb3..79bcb4e5d2ca 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -39,9 +39,6 @@ struct if_spi_card {
struct lbs_private *priv;
struct libertas_spi_platform_data *pdata;
- char helper_fw_name[IF_SPI_FW_NAME_MAX];
- char main_fw_name[IF_SPI_FW_NAME_MAX];
-
/* The card ID and card revision, as reported by the hardware. */
u16 card_id;
u8 card_rev;
@@ -70,10 +67,28 @@ static void free_if_spi_card(struct if_spi_card *card)
kfree(card);
}
-static struct chip_ident chip_id_to_device_name[] = {
- { .chip_id = 0x04, .name = 8385 },
- { .chip_id = 0x0b, .name = 8686 },
+#define MODEL_8385 0x04
+#define MODEL_8686 0x0b
+#define MODEL_8688 0x10
+
+static const struct lbs_fw_table fw_table[] = {
+ { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" },
+ { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" },
+ { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" },
+ { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" },
+ { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" },
+ { 0, NULL, NULL }
};
+MODULE_FIRMWARE("libertas/gspi8385_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8385.bin");
+MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8686_v9.bin");
+MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8686.bin");
+MODULE_FIRMWARE("libertas/gspi8688_helper.bin");
+MODULE_FIRMWARE("libertas/gspi8688.bin");
+
/*
* SPI Interface Unit Routines
@@ -399,26 +414,20 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes)
* Firmware Loading
*/
-static int if_spi_prog_helper_firmware(struct if_spi_card *card)
+static int if_spi_prog_helper_firmware(struct if_spi_card *card,
+ const struct firmware *firmware)
{
int err = 0;
- const struct firmware *firmware = NULL;
int bytes_remaining;
const u8 *fw;
u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
- struct spi_device *spi = card->spi;
lbs_deb_enter(LBS_DEB_SPI);
err = spu_set_interrupt_mode(card, 1, 0);
if (err)
goto out;
- /* Get helper firmware image */
- err = request_firmware(&firmware, card->helper_fw_name, &spi->dev);
- if (err) {
- lbs_pr_err("request_firmware failed with err = %d\n", err);
- goto out;
- }
+
bytes_remaining = firmware->size;
fw = firmware->data;
@@ -429,13 +438,13 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
HELPER_FW_LOAD_CHUNK_SZ);
if (err)
- goto release_firmware;
+ goto out;
err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
IF_SPI_HIST_CMD_DOWNLOAD_RDY,
IF_SPI_HIST_CMD_DOWNLOAD_RDY);
if (err)
- goto release_firmware;
+ goto out;
/* Feed the data into the command read/write port reg
* in chunks of 64 bytes */
@@ -446,16 +455,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
temp, HELPER_FW_LOAD_CHUNK_SZ);
if (err)
- goto release_firmware;
+ goto out;
/* Interrupt the boot code */
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
if (err)
- goto release_firmware;
+ goto out;
bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
fw += HELPER_FW_LOAD_CHUNK_SZ;
}
@@ -465,18 +474,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
* bootloader. This completes the helper download. */
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
- goto release_firmware;
+ goto out;
lbs_deb_spi("waiting for helper to boot...\n");
-release_firmware:
- release_firmware(firmware);
out:
if (err)
lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
@@ -523,13 +530,12 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
return len;
}
-static int if_spi_prog_main_firmware(struct if_spi_card *card)
+static int if_spi_prog_main_firmware(struct if_spi_card *card,
+ const struct firmware *firmware)
{
int len, prev_len;
int bytes, crc_err = 0, err = 0;
- const struct firmware *firmware = NULL;
const u8 *fw;
- struct spi_device *spi = card->spi;
u16 num_crc_errs;
lbs_deb_enter(LBS_DEB_SPI);
@@ -538,19 +544,11 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
if (err)
goto out;
- /* Get firmware image */
- err = request_firmware(&firmware, card->main_fw_name, &spi->dev);
- if (err) {
- lbs_pr_err("%s: can't get firmware '%s' from kernel. "
- "err = %d\n", __func__, card->main_fw_name, err);
- goto out;
- }
-
err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
if (err) {
lbs_pr_err("%s: timed out waiting for initial "
"scratch reg = 0\n", __func__);
- goto release_firmware;
+ goto out;
}
num_crc_errs = 0;
@@ -560,7 +558,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
if (len < 0) {
err = len;
- goto release_firmware;
+ goto out;
}
if (bytes < 0) {
/* If there are no more bytes left, we would normally
@@ -575,7 +573,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
lbs_pr_err("Too many CRC errors encountered "
"in firmware load.\n");
err = -EIO;
- goto release_firmware;
+ goto out;
}
} else {
/* Previous transfer succeeded. Advance counters. */
@@ -590,15 +588,15 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
card->cmd_buffer, len);
if (err)
- goto release_firmware;
+ goto out;
err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
IF_SPI_CIC_CMD_DOWNLOAD_OVER);
if (err)
- goto release_firmware;
+ goto out;
prev_len = len;
}
if (bytes > prev_len) {
@@ -611,12 +609,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
SUCCESSFUL_FW_DOWNLOAD_MAGIC);
if (err) {
lbs_pr_err("failed to confirm the firmware download\n");
- goto release_firmware;
+ goto out;
}
-release_firmware:
- release_firmware(firmware);
-
out:
if (err)
lbs_pr_err("failed to load firmware (err=%d)\n", err);
@@ -800,14 +795,16 @@ static int lbs_spi_thread(void *data)
goto err;
}
- if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY)
+ if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) {
err = if_spi_c2h_cmd(card);
if (err)
goto err;
- if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY)
+ }
+ if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) {
err = if_spi_c2h_data(card);
if (err)
goto err;
+ }
/* workaround: in PS mode, the card does not set the Command
* Download Ready bit, but it sets TX Download Ready. */
@@ -886,37 +883,16 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
* SPI callbacks
*/
-static int if_spi_calculate_fw_names(u16 card_id,
- char *helper_fw, char *main_fw)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
- if (card_id == chip_id_to_device_name[i].chip_id)
- break;
- }
- if (i == ARRAY_SIZE(chip_id_to_device_name)) {
- lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
- return -EAFNOSUPPORT;
- }
- snprintf(helper_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d_hlp.bin",
- chip_id_to_device_name[i].name);
- snprintf(main_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d.bin",
- chip_id_to_device_name[i].name);
- return 0;
-}
-MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
-MODULE_FIRMWARE("libertas/gspi8385.bin");
-MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
-MODULE_FIRMWARE("libertas/gspi8686.bin");
-
static int __devinit if_spi_probe(struct spi_device *spi)
{
struct if_spi_card *card;
struct lbs_private *priv = NULL;
struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
- int err = 0;
+ int err = 0, i;
u32 scratch;
struct sched_param param = { .sched_priority = 1 };
+ const struct firmware *helper = NULL;
+ const struct firmware *mainfw = NULL;
lbs_deb_enter(LBS_DEB_SPI);
@@ -961,10 +937,25 @@ static int __devinit if_spi_probe(struct spi_device *spi)
lbs_deb_spi("Firmware is already loaded for "
"Marvell WLAN 802.11 adapter\n");
else {
- err = if_spi_calculate_fw_names(card->card_id,
- card->helper_fw_name, card->main_fw_name);
- if (err)
+ /* Check if we support this card */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (card->card_id == fw_table[i].model)
+ break;
+ }
+ if (i == ARRAY_SIZE(fw_table)) {
+ lbs_pr_err("Unsupported chip_id: 0x%02x\n",
+ card->card_id);
+ err = -ENODEV;
goto free_card;
+ }
+
+ err = lbs_get_firmware(&card->spi->dev, NULL, NULL,
+ card->card_id, &fw_table[0], &helper,
+ &mainfw);
+ if (err) {
+ lbs_pr_err("failed to find firmware (%d)\n", err);
+ goto free_card;
+ }
lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
"(chip_id = 0x%04x, chip_rev = 0x%02x) "
@@ -973,10 +964,10 @@ static int __devinit if_spi_probe(struct spi_device *spi)
card->card_id, card->card_rev,
spi->master->bus_num, spi->chip_select,
spi->max_speed_hz);
- err = if_spi_prog_helper_firmware(card);
+ err = if_spi_prog_helper_firmware(card, helper);
if (err)
goto free_card;
- err = if_spi_prog_main_firmware(card);
+ err = if_spi_prog_main_firmware(card, mainfw);
if (err)
goto free_card;
lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
@@ -1044,6 +1035,11 @@ remove_card:
free_card:
free_if_spi_card(card);
out:
+ if (helper)
+ release_firmware(helper);
+ if (mainfw)
+ release_firmware(mainfw);
+
lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
return err;
}
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
index f87eec410848..8b1417d3b71b 100644
--- a/drivers/net/wireless/libertas/if_spi.h
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -25,11 +25,6 @@
#define IF_SPI_FW_NAME_MAX 30
-struct chip_ident {
- u16 chip_id;
- u16 name;
-};
-
#define MAX_MAIN_FW_LOAD_CRC_ERR 10
/* Chunk size when loading the helper firmware */
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 3ff61063671a..e906616232a2 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -26,15 +26,25 @@
#define MESSAGE_HEADER_LEN 4
-static char *lbs_fw_name = "usb8388.bin";
+static char *lbs_fw_name = NULL;
module_param_named(fw_name, lbs_fw_name, charp, 0644);
+MODULE_FIRMWARE("libertas/usb8388_v9.bin");
+MODULE_FIRMWARE("libertas/usb8388_v5.bin");
+MODULE_FIRMWARE("libertas/usb8388.bin");
+MODULE_FIRMWARE("libertas/usb8682.bin");
MODULE_FIRMWARE("usb8388.bin");
+enum {
+ MODEL_UNKNOWN = 0x0,
+ MODEL_8388 = 0x1,
+ MODEL_8682 = 0x2
+};
+
static struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
- { USB_DEVICE(0x1286, 0x2001) },
- { USB_DEVICE(0x05a3, 0x8388) },
+ { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
+ { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
{} /* Terminating entry */
};
@@ -66,6 +76,8 @@ static ssize_t if_usb_firmware_set(struct device *dev,
struct if_usb_card *cardp = priv->card;
int ret;
+ BUG_ON(buf == NULL);
+
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
if (ret == 0)
return count;
@@ -91,6 +103,8 @@ static ssize_t if_usb_boot2_set(struct device *dev,
struct if_usb_card *cardp = priv->card;
int ret;
+ BUG_ON(buf == NULL);
+
ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
if (ret == 0)
return count;
@@ -244,6 +258,7 @@ static int if_usb_probe(struct usb_interface *intf,
init_waitqueue_head(&cardp->fw_wq);
cardp->udev = udev;
+ cardp->model = (uint32_t) id->driver_info;
iface_desc = intf->cur_altsetting;
lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
@@ -924,6 +939,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp,
return ret;
}
+/* table of firmware file names */
+static const struct {
+ u32 model;
+ const char *fwname;
+} fw_table[] = {
+ { MODEL_8388, "libertas/usb8388_v9.bin" },
+ { MODEL_8388, "libertas/usb8388_v5.bin" },
+ { MODEL_8388, "libertas/usb8388.bin" },
+ { MODEL_8388, "usb8388.bin" },
+ { MODEL_8682, "libertas/usb8682.bin" }
+};
+
+static int get_fw(struct if_usb_card *cardp, const char *fwname)
+{
+ int i;
+
+ /* Try user-specified firmware first */
+ if (fwname)
+ return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
+
+ /* Otherwise search for firmware to use */
+ for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
+ if (fw_table[i].model != cardp->model)
+ continue;
+ if (request_firmware(&cardp->fw, fw_table[i].fwname,
+ &cardp->udev->dev) == 0)
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
static int __if_usb_prog_firmware(struct if_usb_card *cardp,
const char *fwname, int cmd)
{
@@ -933,10 +980,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
lbs_deb_enter(LBS_DEB_USB);
- ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
- if (ret < 0) {
- lbs_pr_err("request_firmware() failed with %#x\n", ret);
- lbs_pr_err("firmware %s not found\n", fwname);
+ ret = get_fw(cardp, fwname);
+ if (ret) {
+ lbs_pr_err("failed to find firmware (%d)\n", ret);
goto done;
}
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 5ba0aee0eb2f..d819e7e3c9aa 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -43,6 +43,7 @@ struct bootcmdresp
/** USB card description structure*/
struct if_usb_card {
struct usb_device *udev;
+ uint32_t model; /* MODEL_* */
struct urb *rx_urb, *tx_urb;
struct lbs_private *priv;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 24958a86747b..47ce5a6ba120 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1047,6 +1047,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
}
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
+/**
+ * @brief Retrieves two-stage firmware
+ *
+ * @param dev A pointer to device structure
+ * @param user_helper User-defined helper firmware file
+ * @param user_mainfw User-defined main firmware file
+ * @param card_model Bus-specific card model ID used to filter firmware table
+ * elements
+ * @param fw_table Table of firmware file names and device model numbers
+ * terminated by an entry with a NULL helper name
+ * @param helper On success, the helper firmware; caller must free
+ * @param mainfw On success, the main firmware; caller must free
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int lbs_get_firmware(struct device *dev, const char *user_helper,
+ const char *user_mainfw, u32 card_model,
+ const struct lbs_fw_table *fw_table,
+ const struct firmware **helper,
+ const struct firmware **mainfw)
+{
+ const struct lbs_fw_table *iter;
+ int ret;
+
+ BUG_ON(helper == NULL);
+ BUG_ON(mainfw == NULL);
+
+ /* Try user-specified firmware first */
+ if (user_helper) {
+ ret = request_firmware(helper, user_helper, dev);
+ if (ret) {
+ lbs_pr_err("couldn't find helper firmware %s",
+ user_helper);
+ goto fail;
+ }
+ }
+ if (user_mainfw) {
+ ret = request_firmware(mainfw, user_mainfw, dev);
+ if (ret) {
+ lbs_pr_err("couldn't find main firmware %s",
+ user_mainfw);
+ goto fail;
+ }
+ }
+
+ if (*helper && *mainfw)
+ return 0;
+
+ /* Otherwise search for firmware to use. If neither the helper or
+ * the main firmware were specified by the user, then we need to
+ * make sure that found helper & main are from the same entry in
+ * fw_table.
+ */
+ iter = fw_table;
+ while (iter && iter->helper) {
+ if (iter->model != card_model)
+ goto next;
+
+ if (*helper == NULL) {
+ ret = request_firmware(helper, iter->helper, dev);
+ if (ret)
+ goto next;
+
+ /* If the device has one-stage firmware (ie cf8305) and
+ * we've got it then we don't need to bother with the
+ * main firmware.
+ */
+ if (iter->fwname == NULL)
+ return 0;
+ }
+
+ if (*mainfw == NULL) {
+ ret = request_firmware(mainfw, iter->fwname, dev);
+ if (ret && !user_helper) {
+ /* Clear the helper if it wasn't user-specified
+ * and the main firmware load failed, to ensure
+ * we don't have mismatched firmware pairs.
+ */
+ release_firmware(*helper);
+ *helper = NULL;
+ }
+ }
+
+ if (*helper && *mainfw)
+ return 0;
+
+ next:
+ iter++;
+ }
+
+ fail:
+ /* Failed */
+ if (*helper) {
+ release_firmware(*helper);
+ *helper = NULL;
+ }
+ if (*mainfw) {
+ release_firmware(*mainfw);
+ *mainfw = NULL;
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(lbs_get_firmware);
+
static int __init lbs_init_module(void)
{
lbs_deb_enter(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 41a4f214ade1..ba7d96584cb6 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -54,7 +54,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
/**
* if_usb_wrike_bulk_callback - call back to handle URB status
*
- * @param urb pointer to urb structure
+ * @param urb pointer to urb structure
*/
static void if_usb_write_bulk_callback(struct urb *urb)
{
@@ -178,16 +178,19 @@ static int if_usb_probe(struct usb_interface *intf,
le16_to_cpu(endpoint->wMaxPacketSize);
cardp->ep_in = usb_endpoint_num(endpoint);
- lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
- lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
+ lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n",
+ cardp->ep_in);
+ lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n",
+ cardp->ep_in_size);
} else if (usb_endpoint_is_bulk_out(endpoint)) {
cardp->ep_out_size =
le16_to_cpu(endpoint->wMaxPacketSize);
cardp->ep_out = usb_endpoint_num(endpoint);
- lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
+ lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n",
+ cardp->ep_out);
lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n",
- cardp->ep_out_size);
+ cardp->ep_out_size);
}
}
if (!cardp->ep_out_size || !cardp->ep_in_size) {
@@ -318,10 +321,12 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
- lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
- cardp->fwseqnum, cardp->totalbytes);
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "seqnum = %d totalbytes = %d\n",
+ cardp->fwseqnum, cardp->totalbytes);
} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
- lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "Host has finished FW downloading\n");
lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
/* Host has finished FW downloading
@@ -367,7 +372,7 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device);
/**
* usb_tx_block - transfer data to the device
*
- * @priv pointer to struct lbtf_private
+ * @priv pointer to struct lbtf_private
* @payload pointer to payload data
* @nb data length
* @data non-zero for data, zero for commands
@@ -400,7 +405,8 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
urb->transfer_flags |= URB_ZERO_PACKET;
if (usb_submit_urb(urb, GFP_ATOMIC)) {
- lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "usb_submit_urb failed: %d\n", ret);
goto tx_ret;
}
@@ -438,10 +444,12 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
- lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
+ lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n",
+ cardp->rx_urb);
ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC);
if (ret) {
- lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "Submit Rx URB failed: %d\n", ret);
kfree_skb(skb);
cardp->rx_skb = NULL;
lbtf_deb_leave(LBTF_DEB_USB);
@@ -522,14 +530,14 @@ static void if_usb_receive_fwload(struct urb *urb)
}
} else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
pr_info("boot cmd response cmd_tag error (%d)\n",
- bcmdresp.cmd);
+ bcmdresp.cmd);
} else if (bcmdresp.result != BOOT_CMD_RESP_OK) {
pr_info("boot cmd response result error (%d)\n",
- bcmdresp.result);
+ bcmdresp.result);
} else {
cardp->bootcmdresp = 1;
lbtf_deb_usbd(&cardp->udev->dev,
- "Received valid boot command response\n");
+ "Received valid boot command response\n");
}
kfree_skb(skb);
@@ -541,19 +549,23 @@ static void if_usb_receive_fwload(struct urb *urb)
syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader),
GFP_ATOMIC);
if (!syncfwheader) {
- lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "Failure to allocate syncfwheader\n");
kfree_skb(skb);
lbtf_deb_leave(LBTF_DEB_USB);
return;
}
if (!syncfwheader->cmd) {
- lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
- lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
- le32_to_cpu(syncfwheader->seqnum));
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "FW received Blk with correct CRC\n");
+ lbtf_deb_usb2(&cardp->udev->dev,
+ "FW received Blk seqnum = %d\n",
+ le32_to_cpu(syncfwheader->seqnum));
cardp->CRC_OK = 1;
} else {
- lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
+ lbtf_deb_usbd(&cardp->udev->dev,
+ "FW received Blk with CRC error\n");
cardp->CRC_OK = 0;
}
@@ -666,7 +678,8 @@ static void if_usb_receive(struct urb *urb)
{
/* Event cause handling */
u32 event_cause = le32_to_cpu(pkt[1]);
- lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause);
+ lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n",
+ event_cause);
/* Icky undocumented magic special case */
if (event_cause & 0xffff0000) {
@@ -689,7 +702,7 @@ static void if_usb_receive(struct urb *urb)
}
default:
lbtf_deb_usbd(&cardp->udev->dev,
- "libertastf: unknown command type 0x%X\n", recvtype);
+ "libertastf: unknown command type 0x%X\n", recvtype);
kfree_skb(skb);
break;
}
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 86fa8abdd66f..92b486d46eb9 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -9,7 +9,8 @@
/*
* TODO:
- * - IBSS mode simulation (Beacon transmission with competition for "air time")
+ * - Add TSF sync and fix IBSS beacon transmission by adding
+ * competition for "air time" at TBTT
* - RX filtering based on filter configuration (data->rx_filter)
*/
@@ -600,6 +601,18 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
}
+static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum nl80211_iftype newtype)
+{
+ wiphy_debug(hw->wiphy,
+ "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
+ __func__, vif->type, newtype, vif->addr);
+ hwsim_check_magic(vif);
+
+ return 0;
+}
+
static void mac80211_hwsim_remove_interface(
struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
@@ -620,7 +633,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
hwsim_check_magic(vif);
if (vif->type != NL80211_IFTYPE_AP &&
- vif->type != NL80211_IFTYPE_MESH_POINT)
+ vif->type != NL80211_IFTYPE_MESH_POINT &&
+ vif->type != NL80211_IFTYPE_ADHOC)
return;
skb = ieee80211_beacon_get(hw, vif);
@@ -1025,6 +1039,7 @@ static struct ieee80211_ops mac80211_hwsim_ops =
.start = mac80211_hwsim_start,
.stop = mac80211_hwsim_stop,
.add_interface = mac80211_hwsim_add_interface,
+ .change_interface = mac80211_hwsim_change_interface,
.remove_interface = mac80211_hwsim_remove_interface,
.config = mac80211_hwsim_config,
.configure_filter = mac80211_hwsim_configure_filter,
@@ -1295,6 +1310,7 @@ static int __init init_mac80211_hwsim(void)
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->flags = IEEE80211_HW_MFP_CAPABLE |
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 077baa86756b..b4772c1c6135 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -762,14 +762,17 @@ int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if (bitrate_table[i].intersil_txratectrl == val)
+ if (bitrate_table[i].intersil_txratectrl == val) {
+ *bitrate = bitrate_table[i].bitrate * 100000;
break;
+ }
- if (i >= BITRATE_TABLE_SIZE)
+ if (i >= BITRATE_TABLE_SIZE) {
printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
priv->ndev->name, val);
+ err = -EIO;
+ }
- *bitrate = bitrate_table[i].bitrate * 100000;
break;
default:
BUG();
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index cf7be1eb6124..93505f93bf97 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -589,8 +589,15 @@ static int orinoco_ioctl_getrate(struct net_device *dev,
/* If the interface is running we try to find more about the
current mode */
- if (netif_running(dev))
- err = orinoco_hw_get_act_bitrate(priv, &bitrate);
+ if (netif_running(dev)) {
+ int act_bitrate;
+ int lerr;
+
+ /* Ignore errors if we can't get the actual bitrate */
+ lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate);
+ if (!lerr)
+ bitrate = act_bitrate;
+ }
orinoco_unlock(priv, &flags);
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index b0342a520bf1..e5f45cb2a7a2 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -2,6 +2,7 @@ config P54_COMMON
tristate "Softmac Prism54 support"
depends on MAC80211 && EXPERIMENTAL
select FW_LOADER
+ select CRC_CCITT
---help---
This is common code for isl38xx/stlc45xx based modules.
This module does nothing by itself - the USB/PCI/SPI front-ends
@@ -48,6 +49,23 @@ config P54_SPI
If you choose to build a module, it'll be called p54spi.
+config P54_SPI_DEFAULT_EEPROM
+ bool "Include fallback EEPROM blob"
+ depends on P54_SPI
+ default n
+ ---help---
+ Unlike the PCI or USB devices, the SPI variants don't have
+ a dedicated EEPROM chip to store all device specific values
+ for calibration, country and interface settings.
+
+ The driver will try to load the image "3826.eeprom", if the
+ file is put at the right place. (usually /lib/firmware.)
+
+ Only if this request fails, this option will provide a
+ backup set of generic values to get the device working.
+
+ Enabling this option adds about 4k to p54spi.
+
config P54_LEDS
bool
depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 78347041ec40..8c05266d37f4 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <net/mac80211.h>
+#include <linux/crc-ccitt.h>
#include "p54.h"
#include "eeprom.h"
@@ -540,6 +541,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
int err;
u8 *end = (u8 *)eeprom + len;
u16 synth = 0;
+ u16 crc16 = ~0;
wrap = (struct eeprom_pda_wrap *) eeprom;
entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -655,16 +657,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
break;
case PDR_END:
- /* make it overrun */
- entry_len = len;
+ crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
+ if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
+ wiphy_err(dev->wiphy, "eeprom failed checksum "
+ "test!\n");
+ err = -ENOMSG;
+ goto err;
+ } else {
+ goto good_eeprom;
+ }
break;
default:
break;
}
- entry = (void *)entry + (entry_len + 1)*2;
+ crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
+ entry = (void *)entry + (entry_len + 1) * 2;
}
+ wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
+ err = -ENODATA;
+ goto err;
+
+good_eeprom:
if (!synth || !priv->iq_autocal || !priv->output_limit ||
!priv->curve_data) {
wiphy_err(dev->wiphy,
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 15b20c29a604..92b9b1f05fd5 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -123,10 +123,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
bootrec = (struct bootrec *)&bootrec->data[len];
}
- if (fw_version)
+ if (fw_version) {
wiphy_info(priv->hw->wiphy,
"FW rev %s - Softmac protocol %x.%x\n",
fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
+ snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
+ "%s - %x.%x", fw_version,
+ priv->fw_var >> 8, priv->fw_var & 0xff);
+ }
if (priv->fw_var < 0x500)
wiphy_info(priv->hw->wiphy,
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 47db439b63bf..622d27b6d8f2 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -429,8 +429,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
mutex_lock(&priv->conf_mutex);
if (cmd == SET_KEY) {
- switch (key->alg) {
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
BR_DESC_PRIV_CAP_TKIP))) {
ret = -EOPNOTSUPP;
@@ -439,7 +439,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_TKIPMICHAEL;
break;
- case ALG_WEP:
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
ret = -EOPNOTSUPP;
goto out_unlock;
@@ -447,7 +448,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
algo = P54_CRYPTO_WEP;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
ret = -EOPNOTSUPP;
goto out_unlock;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 087bf0698a5a..18d24b7b1e34 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -32,11 +32,14 @@
#include <linux/slab.h>
#include "p54spi.h"
-#include "p54spi_eeprom.h"
#include "p54.h"
#include "lmac.h"
+#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
+#include "p54spi_eeprom.h"
+#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
+
MODULE_FIRMWARE("3826.arm");
MODULE_ALIAS("stlc45xx");
@@ -195,9 +198,13 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
if (ret < 0) {
+#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
dev_info(&priv->spi->dev, "loading default eeprom...\n");
ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
sizeof(p54spi_eeprom));
+#else
+ dev_err(&priv->spi->dev, "Failed to request user eeprom\n");
+#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
} else {
dev_info(&priv->spi->dev, "loading user eeprom...\n");
ret = p54_parse_eeprom(dev, (void *) eeprom->data,
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h
index 1ea1050911d9..d592cbd34d78 100644
--- a/drivers/net/wireless/p54/p54spi_eeprom.h
+++ b/drivers/net/wireless/p54/p54spi_eeprom.h
@@ -671,7 +671,7 @@ static unsigned char p54spi_eeprom[] = {
0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
0x02, 0x00, 0x00, 0x00, /* PDR_END */
- 0xa8, 0xf5 /* bogus data */
+ 0x67, 0x99,
};
#endif /* P54SPI_EEPROM_H */
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index ad595958b7df..063248b35069 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -930,8 +930,8 @@ static int __devinit p54u_probe(struct usb_interface *intf,
#ifdef CONFIG_PM
/* ISL3887 needs a full reset on resume */
udev->reset_resume = 1;
+#endif /* CONFIG_PM */
err = p54u_device_reset(dev);
-#endif
priv->hw_type = P54U_3887;
dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 173aec3d6e7e..76b2318a7dc7 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -275,15 +275,15 @@ static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
{
int band = priv->hw->conf.channel->band;
- if (priv->rxhw != 5)
+ if (priv->rxhw != 5) {
return ((rssi * priv->rssical_db[band].mul) / 64 +
priv->rssical_db[band].add) / 4;
- else
+ } else {
/*
* TODO: find the correct formula
*/
- return ((rssi * priv->rssical_db[band].mul) / 64 +
- priv->rssical_db[band].add) / 4;
+ return rssi / 2 - 110;
+ }
}
/*
@@ -446,7 +446,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
}
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (!payload->status))
+ !(payload->status & P54_TX_FAILED))
info->flags |= IEEE80211_TX_STAT_ACK;
if (payload->status & P54_TX_PSM_CANCELLED)
info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
@@ -683,14 +683,15 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
}
}
-static u8 p54_convert_algo(enum ieee80211_key_alg alg)
+static u8 p54_convert_algo(u32 cipher)
{
- switch (alg) {
- case ALG_WEP:
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
return P54_CRYPTO_WEP;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
return P54_CRYPTO_TKIPMICHAEL;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return P54_CRYPTO_AESCCMP;
default:
return 0;
@@ -731,7 +732,7 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
if (info->control.hw_key) {
crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
- if (info->control.hw_key->alg == ALG_TKIP) {
+ if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
u8 *iv = (u8 *)(skb->data + crypt_offset);
/*
* The firmware excepts that the IV has to have
@@ -827,10 +828,10 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
hdr->tries = ridx;
txhdr->rts_rate_idx = 0;
if (info->control.hw_key) {
- txhdr->key_type = p54_convert_algo(info->control.hw_key->alg);
+ txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher);
txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
- if (info->control.hw_key->alg == ALG_TKIP) {
+ if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
/* reserve space for the MIC key */
len += 8;
memcpy(skb_put(skb, 8), &(info->control.hw_key->key
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 77cd65db8500..d97a2caf582b 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3234,7 +3234,7 @@ prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
switch (cmd) {
case PRISM54_HOSTAPD:
if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ return -EPERM;
ret = prism54_hostapd(ndev, &wrq->u.data);
return ret;
}
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 88560d0ae50a..247a6cf82cc4 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -43,7 +43,6 @@
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
-#include <linux/ethtool.h>
#include <linux/ieee80211.h>
#include <pcmcia/cs.h>
@@ -80,8 +79,6 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map);
static struct net_device_stats *ray_get_stats(struct net_device *dev);
static int ray_dev_init(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
static int ray_open(struct net_device *dev);
static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
struct net_device *dev);
@@ -197,7 +194,7 @@ module_param(bc, int, 0);
module_param(phy_addr, charp, 0);
module_param(ray_mem_speed, int, 0);
-static UCHAR b5_default_startup_parms[] = {
+static const UCHAR b5_default_startup_parms[] = {
0, 0, /* Adhoc station */
'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
0, 0, 0, 0, 0, 0, 0, 0,
@@ -232,7 +229,7 @@ static UCHAR b5_default_startup_parms[] = {
2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
};
-static UCHAR b4_default_startup_parms[] = {
+static const UCHAR b4_default_startup_parms[] = {
0, 0, /* Adhoc station */
'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
0, 0, 0, 0, 0, 0, 0, 0,
@@ -264,9 +261,9 @@ static UCHAR b4_default_startup_parms[] = {
};
/*===========================================================================*/
-static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
+static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
-static char hop_pattern_length[] = { 1,
+static const char hop_pattern_length[] = { 1,
USA_HOP_MOD, EUROPE_HOP_MOD,
JAPAN_HOP_MOD, KOREA_HOP_MOD,
SPAIN_HOP_MOD, FRANCE_HOP_MOD,
@@ -274,7 +271,7 @@ static char hop_pattern_length[] = { 1,
JAPAN_TEST_HOP_MOD
};
-static char rcsid[] =
+static const char rcsid[] =
"Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
static const struct net_device_ops ray_netdev_ops = {
@@ -333,7 +330,6 @@ static int ray_probe(struct pcmcia_device *p_dev)
/* Raylink entries in the device structure */
dev->netdev_ops = &ray_netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->wireless_handlers = &ray_handler_def;
#ifdef WIRELESS_SPY
local->wireless_data.spy_data = &local->spy_data;
@@ -608,7 +604,7 @@ static int dl_startup_params(struct net_device *dev)
/* Start kernel timer to wait for dl startup to complete. */
local->timer.expires = jiffies + HZ / 2;
local->timer.data = (long)local;
- local->timer.function = &verify_dl_startup;
+ local->timer.function = verify_dl_startup;
add_timer(&local->timer);
dev_dbg(&link->dev,
"ray_cs dl_startup_params started timer for verify_dl_startup\n");
@@ -1062,18 +1058,6 @@ AP to AP 1 1 dest AP src AP dest source
}
} /* end encapsulate_frame */
-/*===========================================================================*/
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "ray_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/*====================================================================*/
/*------------------------------------------------------------------*/
@@ -1997,12 +1981,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" start failed\n",
local->sparm.b4.a_current_ess_id);
- local->timer.function = &start_net;
+ local->timer.function = start_net;
} else {
dev_dbg(&link->dev,
"ray_cs interrupt network \"%s\" join failed\n",
local->sparm.b4.a_current_ess_id);
- local->timer.function = &join_net;
+ local->timer.function = join_net;
}
add_timer(&local->timer);
}
@@ -2470,9 +2454,9 @@ static void authenticate(ray_dev_t *local)
del_timer(&local->timer);
if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
- local->timer.function = &join_net;
+ local->timer.function = join_net;
} else {
- local->timer.function = &authenticate_timeout;
+ local->timer.function = authenticate_timeout;
}
local->timer.expires = jiffies + HZ * 2;
local->timer.data = (long)local;
@@ -2557,7 +2541,7 @@ static void associate(ray_dev_t *local)
del_timer(&local->timer);
local->timer.expires = jiffies + HZ * 2;
local->timer.data = (long)local;
- local->timer.function = &join_net;
+ local->timer.function = join_net;
add_timer(&local->timer);
local->card_status = CARD_ASSOC_FAILED;
return;
@@ -2591,7 +2575,7 @@ static void clear_interrupt(ray_dev_t *local)
#ifdef CONFIG_PROC_FS
#define MAXDATA (PAGE_SIZE - 80)
-static char *card_status[] = {
+static const char *card_status[] = {
"Card inserted - uninitialized", /* 0 */
"Card not downloaded", /* 1 */
"Waiting for download parameters", /* 2 */
@@ -2608,8 +2592,8 @@ static char *card_status[] = {
"Association failed" /* 16 */
};
-static char *nettype[] = { "Adhoc", "Infra " };
-static char *framing[] = { "Encapsulation", "Translation" }
+static const char *nettype[] = { "Adhoc", "Infra " };
+static const char *framing[] = { "Encapsulation", "Translation" }
;
/*===========================================================================*/
@@ -2802,6 +2786,7 @@ static ssize_t ray_cs_essid_proc_write(struct file *file,
static const struct file_operations ray_cs_essid_proc_fops = {
.owner = THIS_MODULE,
.write = ray_cs_essid_proc_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static ssize_t int_proc_write(struct file *file, const char __user *buffer,
@@ -2835,6 +2820,7 @@ static ssize_t int_proc_write(struct file *file, const char __user *buffer,
static const struct file_operations int_proc_fops = {
.owner = THIS_MODULE,
.write = int_proc_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
#endif
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5063e01410e5..d49e830fa1da 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -321,7 +321,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
int preamble_mask;
u32 reg;
@@ -329,59 +330,72 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = erp->short_preamble << 3;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
- rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
- rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
- rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
- rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
- rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
- rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
- rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
- rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
- rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
-
- rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ preamble_mask = erp->short_preamble << 3;
+
+ rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
+ rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
+ rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 10));
+ rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
+ rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 20));
+ rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
+ rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 55));
+ rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
+ rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 110));
+ rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
- rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+ rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, CSR11, reg);
- rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
- rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
- rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+ rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+ rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+ rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+ rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+ rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
- rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
- rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ }
}
static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1007,12 +1021,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2400pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1096,7 +1109,7 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2400pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1112,24 +1125,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt2400pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
-static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2400pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
} else {
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
@@ -1481,15 +1494,17 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c2a555d5376b..2214c3231727 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -327,7 +327,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
int preamble_mask;
u32 reg;
@@ -335,59 +336,73 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = erp->short_preamble << 3;
-
- rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
- rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
- rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
- rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
- rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
- rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
- rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
- rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
- rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
- rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
-
- rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
- rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
- rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
- rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
- rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
-
- rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ preamble_mask = erp->short_preamble << 3;
+
+ rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
+ rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
+ rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 10));
+ rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
+ rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 20));
+ rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
+ rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 55));
+ rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
+
+ rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
+ rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 110));
+ rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
- rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
- rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
- rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+ rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, CSR11, reg);
- rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
- rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
- rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+ rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+ rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+ rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+ rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+ rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+ rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, CSR19, reg);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
- rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
- rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, CSR19, reg);
}
static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1161,12 +1176,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2500pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1249,7 +1263,7 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2500pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1265,24 +1279,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
-static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt2500pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
-static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2500pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
} else {
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
@@ -1795,19 +1809,23 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = DEFAULT_TXPOWER;
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = DEFAULT_TXPOWER;
+ }
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index cdaf93f48263..6e94356265b3 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
* it is known that not work at least on some hardware.
* SW crypto will be used in that case.
*/
- if (key->alg == ALG_WEP && key->keyidx != 0)
+ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+ key->keyidx != 0)
return -EOPNOTSUPP;
/*
@@ -492,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u16 reg;
- rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
+ }
- rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR11,
+ erp->basic_rates);
- rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL, erp->beacon_int * 4);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
+ erp->beacon_int * 4);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+ }
- rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
- rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
- rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
+ }
}
static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
@@ -1039,12 +1051,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2500usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txd = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -1127,7 +1138,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt2500usb_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1195,6 +1206,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
+static void rt2500usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
/*
* RX control handlers
*/
@@ -1698,19 +1717,23 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = DEFAULT_TXPOWER;
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = DEFAULT_TXPOWER;
+ }
}
return 0;
@@ -1789,7 +1812,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt2500usb_kill_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_shared_key = rt2500usb_config_key,
.config_pairwise_key = rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index ed4ebcdde7c9..2edc7742a7e9 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -639,6 +639,18 @@
#define LED_CFG_LED_POLAR FIELD32(0x40000000)
/*
+ * AMPDU_BA_WINSIZE: Force BlockAck window size
+ * FORCE_WINSIZE_ENABLE:
+ * 0: Disable forcing of BlockAck window size
+ * 1: Enable forcing of BlockAck window size, overwrites values BlockAck
+ * window size values in the TXWI
+ * FORCE_WINSIZE: BlockAck window size
+ */
+#define AMPDU_BA_WINSIZE 0x1040
+#define AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE FIELD32(0x00000020)
+#define AMPDU_BA_WINSIZE_FORCE_WINSIZE FIELD32(0x0000001f)
+
+/*
* XIFS_TIME_CFG: MAC timing
* CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
* OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
@@ -1318,7 +1330,25 @@
#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000)
/*
- * TX_STA_FIFO: TX Result for specific PID status fifo register
+ * TX_STA_FIFO: TX Result for specific PID status fifo register.
+ *
+ * This register is implemented as FIFO with 16 entries in the HW. Each
+ * register read fetches the next tx result. If the FIFO is full because
+ * it wasn't read fast enough after the according interrupt (TX_FIFO_STATUS)
+ * triggered, the hw seems to simply drop further tx results.
+ *
+ * VALID: 1: this tx result is valid
+ * 0: no valid tx result -> driver should stop reading
+ * PID_TYPE: The PID latched from the PID field in the TXWI, can be used
+ * to match a frame with its tx result (even though the PID is
+ * only 4 bits wide).
+ * TX_SUCCESS: Indicates tx success (1) or failure (0)
+ * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0)
+ * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0)
+ * WCID: The wireless client ID.
+ * MCS: The tx rate used during the last transmission of this frame, be it
+ * successful or not.
+ * PHYMODE: The phymode used for the transmission.
*/
#define TX_STA_FIFO 0x1718
#define TX_STA_FIFO_VALID FIELD32(0x00000001)
@@ -1841,6 +1871,13 @@ struct mac_iveiv_entry {
#define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00)
/*
+ * EEPROM Maximum TX power values
+ */
+#define EEPROM_MAX_TX_POWER 0x0027
+#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff)
+#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00)
+
+/*
* EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
* This is delta in 40MHZ.
* VALUE: Tx Power dalta value (MAX=4)
@@ -1928,6 +1965,8 @@ struct mac_iveiv_entry {
* TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
* BW: Channel bandwidth 20MHz or 40 MHz
* STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will
+ * aggregate consecutive frames with the same RA and QoS TID.
*/
#define TXWI_W0_FRAG FIELD32(0x00000001)
#define TXWI_W0_MIMO_PS FIELD32(0x00000002)
@@ -1945,6 +1984,15 @@ struct mac_iveiv_entry {
/*
* Word1
+ * ACK: 0: No Ack needed, 1: Ack needed
+ * NSEQ: 0: Don't assign hw sequence number, 1: Assign hw sequence number
+ * BW_WIN_SIZE: BA windows size of the recipient
+ * WIRELESS_CLI_ID: Client ID for WCID table access
+ * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame
+ * PACKETID: Will be latched into the TX_STA_FIFO register once the according
+ * frame was processed. If multiple frames are aggregated together
+ * (AMPDU==1) the reported tx status will always contain the packet
+ * id of the first frame. 0: Don't report tx status for this frame.
*/
#define TXWI_W1_ACK FIELD32(0x00000001)
#define TXWI_W1_NSEQ FIELD32(0x00000002)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b66e0fd8f0fa..3bb67492d754 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1,4 +1,5 @@
/*
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com>
@@ -254,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2800_mcu_request);
+int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i = 0;
+ u32 reg;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+ if (reg && reg != ~0)
+ return 0;
+ msleep(1);
+ }
+
+ ERROR(rt2x00dev, "Unstable hardware.\n");
+ return -EBUSY;
+}
+EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready);
+
int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
@@ -367,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
u32 reg;
/*
- * Wait for stable hardware.
+ * If driver doesn't wake up firmware here,
+ * rt2800_load_firmware will hang forever when interface is up again.
*/
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
- if (reg && reg != ~0)
- break;
- msleep(1);
- }
+ rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);
- if (i == REGISTER_BUSY_COUNT) {
- ERROR(rt2x00dev, "Unstable hardware.\n");
+ /*
+ * Wait for stable hardware.
+ */
+ if (rt2800_wait_csr_ready(rt2x00dev))
return -EBUSY;
- }
if (rt2x00_is_pci(rt2x00dev))
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
@@ -427,8 +442,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2800_load_firmware);
-void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
+void rt2800_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
{
+ __le32 *txwi = rt2800_drv_get_txwi(entry);
u32 word;
/*
@@ -437,7 +454,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
rt2x00_desc_read(txwi, 0, &word);
rt2x00_set_field32(&word, TXWI_W0_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
- rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+ rt2x00_set_field32(&word, TXWI_W0_MIMO_PS,
+ test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags));
rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
rt2x00_set_field32(&word, TXWI_W0_TS,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
@@ -465,7 +483,7 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
txdesc->key_idx : 0xff);
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
txdesc->length);
- rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1);
+ rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1);
rt2x00_desc_write(txwi, 1, word);
/*
@@ -478,7 +496,7 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
}
-EXPORT_SYMBOL_GPL(rt2800_write_txwi);
+EXPORT_SYMBOL_GPL(rt2800_write_tx_data);
static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
{
@@ -490,7 +508,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2)
u8 offset1;
u8 offset2;
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom);
offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0);
offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1);
@@ -569,6 +587,148 @@ void rt2800_process_rxwi(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
+{
+ __le32 *txwi;
+ u32 word;
+ int wcid, ack, pid;
+ int tx_wcid, tx_ack, tx_pid;
+
+ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+
+ /*
+ * This frames has returned with an IO error,
+ * so the status report is not intended for this
+ * frame.
+ */
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ return false;
+ }
+
+ /*
+ * Validate if this TX status report is intended for
+ * this entry by comparing the WCID/ACK/PID fields.
+ */
+ txwi = rt2800_drv_get_txwi(entry);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+ tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
+ tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+ if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+ WARNING(entry->queue->rt2x00dev,
+ "TX status report missed for queue %d entry %d\n",
+ entry->queue->qid, entry->entry_idx);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+ return false;
+ }
+
+ return true;
+}
+
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ struct queue_entry *entry;
+ __le32 *txwi;
+ struct txdone_entry_desc txdesc;
+ u32 word;
+ u32 reg;
+ u16 mcs, real_mcs;
+ u8 pid;
+ int i;
+
+ /*
+ * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
+ * at most X times and also stop processing once the TX_STA_FIFO_VALID
+ * flag is not set anymore.
+ *
+ * The legacy drivers use X=TX_RING_SIZE but state in a comment
+ * that the TX_STA_FIFO stack has a size of 16. We stick to our
+ * tx ring size for now.
+ */
+ for (i = 0; i < TX_ENTRIES; i++) {
+ rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
+ if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
+ break;
+
+ /*
+ * Skip this entry when it contains an invalid
+ * queue identication number.
+ */
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1;
+ if (pid >= QID_RX)
+ continue;
+
+ queue = rt2x00queue_get_queue(rt2x00dev, pid);
+ if (unlikely(!queue))
+ continue;
+
+ /*
+ * Inside each queue, we process each entry in a chronological
+ * order. We first check that the queue is not empty.
+ */
+ entry = NULL;
+ txwi = NULL;
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ if (rt2800_txdone_entry_check(entry, reg))
+ break;
+ }
+
+ if (!entry || rt2x00queue_empty(queue))
+ break;
+
+
+ /*
+ * Obtain the status about this packet.
+ */
+ txdesc.flags = 0;
+ txwi = rt2800_drv_get_txwi(entry);
+ rt2x00_desc_read(txwi, 0, &word);
+ mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
+ real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
+
+ /*
+ * Ralink has a retry mechanism using a global fallback
+ * table. We setup this fallback table to try the immediate
+ * lower rate for all rates. In the TX_STA_FIFO, the MCS field
+ * always contains the MCS used for the last transmission, be
+ * it successful or not.
+ */
+ if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
+ /*
+ * Transmission succeeded. The number of retries is
+ * mcs - real_mcs
+ */
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+ txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
+ } else {
+ /*
+ * Transmission failed. The number of retries is
+ * always 7 in this case (for a total number of 8
+ * frames sent).
+ */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ txdesc.retry = rt2x00dev->long_retry;
+ }
+
+ /*
+ * the frame was retried at least once
+ * -> hw used fallback rates
+ */
+ if (txdesc.retry)
+ __set_bit(TXDONE_FALLBACK, &txdesc.flags);
+
+ rt2x00lib_txdone(entry, &txdesc);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2800_txdone);
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -600,7 +760,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
/*
* Add the TXWI for the beacon to the skb.
*/
- rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
+ rt2800_write_tx_data(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -975,19 +1135,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
if (flags & CONFIG_UPDATE_MAC) {
- reg = le32_to_cpu(conf->mac[1]);
- rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
- conf->mac[1] = cpu_to_le32(reg);
+ if (!is_zero_ether_addr((const u8 *)conf->mac)) {
+ reg = le32_to_cpu(conf->mac[1]);
+ rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+ conf->mac[1] = cpu_to_le32(reg);
+ }
rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
conf->mac, sizeof(conf->mac));
}
if (flags & CONFIG_UPDATE_BSSID) {
- reg = le32_to_cpu(conf->bssid[1]);
- rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
- rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
- conf->bssid[1] = cpu_to_le32(reg);
+ if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
+ reg = le32_to_cpu(conf->bssid[1]);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
+ conf->bssid[1] = cpu_to_le32(reg);
+ }
rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
conf->bssid, sizeof(conf->bssid));
@@ -995,38 +1159,50 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
}
EXPORT_SYMBOL_GPL(rt2800_config_intf);
-void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
+ u32 changed)
{
u32 reg;
- rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
- rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
- !!erp->short_preamble);
- rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
- !!erp->short_preamble);
- rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+ !!erp->short_preamble);
+ rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+ !!erp->short_preamble);
+ rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+ }
- rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
- rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
- erp->cts_protection ? 2 : 0);
- rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+ rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+ erp->cts_protection ? 2 : 0);
+ rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+ }
- rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
- erp->basic_rates);
- rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+ erp->basic_rates);
+ rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+ }
- rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
- rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
- rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+ rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME,
+ erp->slot_time);
+ rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
- rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
- rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
- rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+ rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+ rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+ }
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
- rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+ rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+ }
}
EXPORT_SYMBOL_GPL(rt2800_config_erp);
@@ -1120,27 +1296,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
* double meaning, and we should set a 7DBm boost flag.
*/
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
- (info->tx_power1 >= 0));
+ (info->default_power1 >= 0));
- if (info->tx_power1 < 0)
- info->tx_power1 += 7;
+ if (info->default_power1 < 0)
+ info->default_power1 += 7;
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power1));
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1);
rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
- (info->tx_power2 >= 0));
+ (info->default_power2 >= 0));
- if (info->tx_power2 < 0)
- info->tx_power2 += 7;
+ if (info->default_power2 < 0)
+ info->default_power2 += 7;
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power2));
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2);
} else {
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power1));
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power2));
+ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1);
+ rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2);
}
rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
@@ -1180,13 +1352,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
- TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1);
rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
- TXPOWER_G_TO_DEV(info->tx_power2));
+ rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
@@ -1210,10 +1380,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
unsigned int tx_pin;
u8 bbp;
+ if (rf->channel <= 14) {
+ info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
+ info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2);
+ } else {
+ info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1);
+ info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
+ }
+
if (rt2x00_rf(rt2x00dev, RF2020) ||
rt2x00_rf(rt2x00dev, RF3020) ||
rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022))
+ rt2x00_rf(rt2x00dev, RF3022) ||
+ rt2x00_rf(rt2x00dev, RF3052))
rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
else
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1536,7 +1715,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
/*
* Initialization functions.
*/
-int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
u16 eeprom;
@@ -1886,6 +2065,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
/*
+ * Do not force the BA window size, we use the TXWI to set it
+ */
+ rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, &reg);
+ rt2x00_set_field32(&reg, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0);
+ rt2x00_set_field32(&reg, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0);
+ rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg);
+
+ /*
* We must clear the error counters.
* These registers are cleared on read,
* so we may pass a useless variable to store the value.
@@ -1906,7 +2093,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_registers);
static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
{
@@ -1949,7 +2135,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
return -EACCES;
}
-int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u16 eeprom;
@@ -2044,7 +2230,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_bbp);
static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
bool bw40, u8 rfcsr24, u8 filter_target)
@@ -2106,7 +2291,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
return rfcsr24;
}
-int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
{
u8 rfcsr;
u8 bbp;
@@ -2360,7 +2545,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
return 0;
}
-EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
+
+int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+ u16 word;
+
+ /*
+ * Initialize all registers.
+ */
+ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
+ rt2800_init_registers(rt2x00dev) ||
+ rt2800_init_bbp(rt2x00dev) ||
+ rt2800_init_rfcsr(rt2x00dev)))
+ return -EIO;
+
+ /*
+ * Send signal to firmware during boot time.
+ */
+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
+
+ if (rt2x00_is_usb(rt2x00dev) &&
+ (rt2x00_rt(rt2x00dev, RT3070) ||
+ rt2x00_rt(rt2x00dev, RT3071) ||
+ rt2x00_rt(rt2x00dev, RT3572))) {
+ udelay(200);
+ rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+ udelay(10);
+ }
+
+ /*
+ * Enable RX.
+ */
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ udelay(50);
+
+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ /*
+ * Initialize LED control
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+ rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+ word & 0xff, (word >> 8) & 0xff);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800_enable_radio);
+
+void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+ rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+ rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+ /* Wait for DMA, ignore error */
+ rt2800_wait_wpdma_ready(rt2x00dev);
+
+ rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 0);
+ rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+}
+EXPORT_SYMBOL_GPL(rt2800_disable_radio);
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
{
@@ -2516,6 +2794,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
default_lna_gain);
rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word);
+ if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER);
+ if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff)
+ rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER);
+ rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word);
+
return 0;
}
EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
@@ -2755,9 +3040,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
struct channel_info *info;
- char *tx_power1;
- char *tx_power2;
+ char *default_power1;
+ char *default_power2;
unsigned int i;
+ unsigned short max_power;
u16 eeprom;
/*
@@ -2865,27 +3151,32 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
- tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
- tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom);
+ max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ);
+ default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+ default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
for (i = 0; i < 14; i++) {
- info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
- info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+ info[i].max_power = max_power;
+ info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]);
+ info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]);
}
if (spec->num_channels > 14) {
- tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
- tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+ max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ);
+ default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+ default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
for (i = 14; i < spec->num_channels; i++) {
- info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
- info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+ info[i].max_power = max_power;
+ info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]);
+ info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]);
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 091641e3c5e2..600c5eb25c41 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -1,4 +1,6 @@
/*
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Bartlomiej Zolnierkiewicz
This program is free software; you can redistribute it and/or modify
@@ -44,6 +46,7 @@ struct rt2800_ops {
int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
+ __le32 *(*drv_get_txwi)(struct queue_entry *entry);
};
static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
@@ -126,18 +129,31 @@ static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev)
return rt2800ops->drv_init_registers(rt2x00dev);
}
+static inline __le32 *rt2800_drv_get_txwi(struct queue_entry *entry)
+{
+ const struct rt2800_ops *rt2800ops = entry->queue->rt2x00dev->ops->drv;
+
+ return rt2800ops->drv_get_txwi(entry);
+}
+
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1);
+int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev);
+int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
+
int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
-void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
+void rt2800_write_tx_data(struct queue_entry *entry,
+ struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
extern const struct rt2x00debug rt2800_rt2x00debug;
@@ -153,7 +169,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags);
void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, const unsigned int flags);
-void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp);
+void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
+ u32 changed);
void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant);
void rt2800_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
@@ -163,10 +180,8 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
const u32 count);
-int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
-int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
-int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
-int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
+int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
+void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 39b3846fa340..005ee153e0cc 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000);
-
/*
* enable Host program ram write selection
*/
@@ -344,24 +342,24 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
}
rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, 0);
rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, mask);
- rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, 0);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, 0);
rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
}
@@ -399,78 +397,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
- u16 word;
-
- /*
- * Initialize all registers.
- */
if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800pci_init_queues(rt2x00dev) ||
- rt2800_init_registers(rt2x00dev) ||
- rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800_init_bbp(rt2x00dev) ||
- rt2800_init_rfcsr(rt2x00dev)))
+ rt2800pci_init_queues(rt2x00dev)))
return -EIO;
- /*
- * Send signal to firmware during boot time.
- */
- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-
- /*
- * Enable RX.
- */
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- /*
- * Initialize LED control
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- return 0;
+ return rt2800_enable_radio(rt2x00dev);
}
static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+ rt2800_disable_radio(rt2x00dev);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280);
@@ -486,9 +424,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-
- /* Wait for DMA, ignore error */
- rt2800_wait_wpdma_ready(rt2x00dev);
}
static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -566,21 +501,16 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2800pci_write_tx_data(struct queue_entry* entry,
- struct txentry_desc *txdesc)
+static __le32 *rt2800pci_get_txwi(struct queue_entry *entry)
{
- __le32 *txwi = (__le32 *) entry->skb->data;
-
- rt2800_write_txwi(txwi, txdesc);
+ return (__le32 *) entry->skb->data;
}
-
-static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2800pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -600,7 +530,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len);
+ rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len);
rt2x00_set_field32(&word, TXD_W1_LAST_SEC1,
!test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_BURST,
@@ -631,41 +561,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
-static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue_idx)
+static void rt2800pci_kick_tx_queue(struct data_queue *queue)
{
- struct data_queue *queue;
- unsigned int idx, qidx = 0;
-
- if (queue_idx > QID_HCCA && queue_idx != QID_MGMT)
- return;
-
- queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
- idx = queue->index[Q_INDEX];
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ unsigned int qidx = 0;
- if (queue_idx == QID_MGMT)
+ if (queue->qid == QID_MGMT)
qidx = 5;
else
- qidx = queue_idx;
+ qidx = queue->qid;
- rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx);
+ rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx);
}
-static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2800pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
return;
}
rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI));
- rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO));
rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
}
@@ -728,110 +652,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
/*
* Interrupt functions.
*/
-static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
- struct queue_entry *entry;
- __le32 *txwi;
- struct txdone_entry_desc txdesc;
- u32 word;
- u32 reg;
- int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
- u16 mcs, real_mcs;
- int i;
-
- /*
- * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
- * at most X times and also stop processing once the TX_STA_FIFO_VALID
- * flag is not set anymore.
- *
- * The legacy drivers use X=TX_RING_SIZE but state in a comment
- * that the TX_STA_FIFO stack has a size of 16. We stick to our
- * tx ring size for now.
- */
- for (i = 0; i < TX_ENTRIES; i++) {
- rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
- if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
- break;
-
- wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
- ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
-
- /*
- * Skip this entry when it contains an invalid
- * queue identication number.
- */
- if (pid <= 0 || pid > QID_RX)
- continue;
-
- queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
- if (unlikely(!queue))
- continue;
-
- /*
- * Inside each queue, we process each entry in a chronological
- * order. We first check that the queue is not empty.
- */
- if (rt2x00queue_empty(queue))
- continue;
- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-
- /* Check if we got a match by looking at WCID/ACK/PID
- * fields */
- txwi = (__le32 *) entry->skb->data;
-
- rt2x00_desc_read(txwi, 1, &word);
- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
- tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
- tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
-
- if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
- WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
-
- /*
- * Obtain the status about this packet.
- */
- txdesc.flags = 0;
- rt2x00_desc_read(txwi, 0, &word);
- mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
- real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
-
- /*
- * Ralink has a retry mechanism using a global fallback
- * table. We setup this fallback table to try the immediate
- * lower rate for all rates. In the TX_STA_FIFO, the MCS field
- * always contains the MCS used for the last transmission, be
- * it successful or not.
- */
- if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
- /*
- * Transmission succeeded. The number of retries is
- * mcs - real_mcs
- */
- __set_bit(TXDONE_SUCCESS, &txdesc.flags);
- txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
- } else {
- /*
- * Transmission failed. The number of retries is
- * always 7 in this case (for a total number of 8
- * frames sent).
- */
- __set_bit(TXDONE_FAILURE, &txdesc.flags);
- txdesc.retry = 7;
- }
-
- /*
- * the frame was retried at least once
- * -> hw used fallback rates
- */
- if (txdesc.retry)
- __set_bit(TXDONE_FALLBACK, &txdesc.flags);
-
- rt2x00lib_txdone(entry, &txdesc);
- }
-}
-
static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
{
struct ieee80211_conf conf = { .flags = 0 };
@@ -867,7 +687,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance)
* 4 - Tx done interrupt.
*/
if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
- rt2800pci_txdone(rt2x00dev);
+ rt2800_txdone(rt2x00dev);
/*
* 5 - Auto wakeup interrupt.
@@ -1011,6 +831,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
.regbusy_read = rt2x00pci_regbusy_read,
.drv_write_firmware = rt2800pci_write_firmware,
.drv_init_registers = rt2800pci_init_registers,
+ .drv_get_txwi = rt2800pci_get_txwi,
};
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
@@ -1030,7 +851,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.reset_tuner = rt2800_reset_tuner,
.link_tuner = rt2800_link_tuner,
.write_tx_desc = rt2800pci_write_tx_desc,
- .write_tx_data = rt2800pci_write_tx_data,
+ .write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
.kick_tx_queue = rt2800pci_kick_tx_queue,
.kill_tx_queue = rt2800pci_kill_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5a2dfe87c6b6..3dff56ec195a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
@@ -100,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
msleep(10);
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
- /*
- * Send signal to firmware during boot time.
- */
- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-
- if (rt2x00_rt(rt2x00dev, RT3070) ||
- rt2x00_rt(rt2x00dev, RT3071) ||
- rt2x00_rt(rt2x00dev, RT3572)) {
- udelay(200);
- rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
- udelay(10);
- }
-
return 0;
}
@@ -134,26 +122,18 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- int i;
/*
* Wait until BBP and RF are ready.
*/
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
- if (reg && reg != ~0)
- break;
- msleep(1);
- }
-
- if (i == REGISTER_BUSY_COUNT) {
- ERROR(rt2x00dev, "Unstable hardware.\n");
+ if (rt2800_wait_csr_ready(rt2x00dev))
return -EBUSY;
- }
rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
@@ -172,30 +152,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
- u16 word;
- /*
- * Initialize all registers.
- */
- if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
- rt2800_init_registers(rt2x00dev) ||
- rt2800_init_bbp(rt2x00dev) ||
- rt2800_init_rfcsr(rt2x00dev)))
+ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev)))
return -EIO;
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- udelay(50);
-
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
-
rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
@@ -210,45 +170,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
- rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
- /*
- * Initialize LED control
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
- rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
- word & 0xff, (word >> 8) & 0xff);
-
- return 0;
+ return rt2800_enable_radio(rt2x00dev);
}
static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
- rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
-
- /* Wait for DMA, ignore error */
- rt2800_wait_wpdma_ready(rt2x00dev);
-
+ rt2800_disable_radio(rt2x00dev);
rt2x00usb_disable_radio(rt2x00dev);
}
@@ -320,21 +247,19 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt2800usb_write_tx_data(struct queue_entry* entry,
- struct txentry_desc *txdesc)
+static __le32 *rt2800usb_get_txwi(struct queue_entry *entry)
{
- __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE);
-
- rt2800_write_txwi(txwi, txdesc);
+ if (entry->queue->qid == QID_BEACON)
+ return (__le32 *) (entry->skb->data);
+ else
+ return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE);
}
-
-static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt2800usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txi = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txi = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -342,7 +267,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
*/
rt2x00_desc_read(txi, 0, &word);
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
- skb->len - TXINFO_DESC_SIZE);
+ entry->skb->len - TXINFO_DESC_SIZE);
rt2x00_set_field32(&word, TXINFO_W0_WIV,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -379,6 +304,46 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
}
/*
+ * TX control handlers
+ */
+static void rt2800usb_work_txdone(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, txdone_work);
+ struct data_queue *queue;
+ struct queue_entry *entry;
+
+ rt2800_txdone(rt2x00dev);
+
+ /*
+ * Process any trailing TX status reports for IO failures,
+ * we loop until we find the first non-IO error entry. This
+ * can either be a frame which is free, is being uploaded,
+ * or has completed the upload but didn't have an entry
+ * in the TX_STAT_FIFO register yet.
+ */
+ tx_queue_for_each(rt2x00dev, queue) {
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+ !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ break;
+
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ }
+ }
+}
+
+static void rt2800usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
+/*
* RX control handlers
*/
static void rt2800usb_fill_rxdone(struct queue_entry *entry,
@@ -514,6 +479,11 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+ /*
+ * Overwrite TX done handler
+ */
+ PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone);
+
return 0;
}
@@ -549,6 +519,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
.regbusy_read = rt2x00usb_regbusy_read,
.drv_write_firmware = rt2800usb_write_firmware,
.drv_init_registers = rt2800usb_init_registers,
+ .drv_get_txwi = rt2800usb_get_txwi,
};
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
@@ -566,11 +537,11 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_tuner = rt2800_link_tuner,
.watchdog = rt2x00usb_watchdog,
.write_tx_desc = rt2800usb_write_tx_desc,
- .write_tx_data = rt2800usb_write_tx_data,
+ .write_tx_data = rt2800_write_tx_data,
.write_beacon = rt2800_write_beacon,
.get_tx_data_len = rt2800usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt2800usb_kill_tx_queue,
.fill_rxdone = rt2800usb_fill_rxdone,
.config_shared_key = rt2800_config_shared_key,
.config_pairwise_key = rt2800_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c21af38cc5af..7832a5996a8c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
<http://rt2x00.serialmonkey.com>
@@ -212,8 +213,9 @@ struct channel_info {
unsigned int flags;
#define GEOGRAPHY_ALLOWED 0x00000001
- short tx_power1;
- short tx_power2;
+ short max_power;
+ short default_power1;
+ short default_power2;
};
/*
@@ -558,18 +560,15 @@ struct rt2x00lib_ops {
/*
* TX control handlers
*/
- void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+ void (*write_tx_desc) (struct queue_entry *entry,
struct txentry_desc *txdesc);
void (*write_tx_data) (struct queue_entry *entry,
struct txentry_desc *txdesc);
void (*write_beacon) (struct queue_entry *entry,
struct txentry_desc *txdesc);
int (*get_tx_data_len) (struct queue_entry *entry);
- void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue);
- void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue);
+ void (*kick_tx_queue) (struct data_queue *queue);
+ void (*kill_tx_queue) (struct data_queue *queue);
/*
* RX control handlers
@@ -597,7 +596,8 @@ struct rt2x00lib_ops {
#define CONFIG_UPDATE_BSSID ( 1 << 3 )
void (*config_erp) (struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp);
+ struct rt2x00lib_erp *erp,
+ u32 changed);
void (*config_ant) (struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant);
void (*config) (struct rt2x00_dev *rt2x00dev,
@@ -698,6 +698,7 @@ struct rt2x00_dev {
struct ieee80211_hw *hw;
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
enum ieee80211_band curr_band;
+ int curr_freq;
/*
* If enabled, the debugfs interface structures
@@ -850,11 +851,6 @@ struct rt2x00_dev {
struct ieee80211_low_level_stats low_level_stats;
/*
- * RX configuration information.
- */
- struct ieee80211_rx_status rx_status;
-
- /*
* Scheduled work.
* NOTE: intf_work will use ieee80211_iterate_active_interfaces()
* which means it cannot be placed on the hw->workqueue
@@ -862,6 +858,12 @@ struct rt2x00_dev {
*/
struct work_struct intf_work;
+ /**
+ * Scheduled work for TX/RX done handling (USB devices)
+ */
+ struct work_struct rxdone_work;
+ struct work_struct txdone_work;
+
/*
* Data queue arrays for RX, TX and Beacon.
* The Beacon array also contains the Atim queue
@@ -1069,8 +1071,10 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_dmadone(struct queue_entry *entry);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
+void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry);
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 953dc4f2c6af..4c7ff765a8bf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -81,7 +81,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
- struct ieee80211_bss_conf *bss_conf)
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
{
struct rt2x00lib_erp erp;
@@ -102,7 +103,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
/* Update global beacon interval time, this is needed for PS support */
rt2x00dev->beacon_int = bss_conf->beacon_int;
- rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
+ rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
}
static inline
@@ -126,25 +127,17 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
* ANTENNA_SW_DIVERSITY state to the driver.
* If that happens, fallback to hardware defaults,
* or our own default.
- * If diversity handling is active for a particular antenna,
- * we shouldn't overwrite that antenna.
- * The calls to rt2x00lib_config_antenna_check()
- * might have caused that we restore back to the already
- * active setting. If that has happened we can quit.
*/
if (!(ant->flags & ANTENNA_RX_DIVERSITY))
config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
- else
+ else if(config.rx == ANTENNA_SW_DIVERSITY)
config.rx = active->rx;
if (!(ant->flags & ANTENNA_TX_DIVERSITY))
config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx);
- else
+ else if (config.tx == ANTENNA_SW_DIVERSITY)
config.tx = active->tx;
- if (config.rx == active->rx && config.tx == active->tx)
- return;
-
/*
* Antenna setup changes require the RX to be disabled,
* else the changes will be ignored by the device.
@@ -209,10 +202,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
rt2x00link_reset_tuner(rt2x00dev, false);
rt2x00dev->curr_band = conf->channel->band;
+ rt2x00dev->curr_freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
rt2x00dev->short_retry = conf->short_frame_max_tx_count;
rt2x00dev->long_retry = conf->long_frame_max_tx_count;
-
- rt2x00dev->rx_status.band = conf->channel->band;
- rt2x00dev->rx_status.freq = conf->channel->center_freq;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 583dacd8d241..5e9074bf2b8e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -31,15 +31,14 @@
enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
{
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == WLAN_KEY_LEN_WEP40)
- return CIPHER_WEP64;
- else
- return CIPHER_WEP128;
- case ALG_TKIP:
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ return CIPHER_WEP64;
+ case WLAN_CIPHER_SUITE_WEP104:
+ return CIPHER_WEP128;
+ case WLAN_CIPHER_SUITE_TKIP:
return CIPHER_TKIP;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
return CIPHER_AES;
default:
return CIPHER_NONE;
@@ -95,7 +94,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
overhead += key->iv_len;
if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
- if (key->alg == ALG_TKIP)
+ if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
overhead += 8;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index b0498e7e7aae..989916505ce8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -315,6 +315,7 @@ static const struct file_operations rt2x00debug_fop_queue_dump = {
.poll = rt2x00debug_poll_queue_dump,
.open = rt2x00debug_open_queue_dump,
.release = rt2x00debug_release_queue_dump,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t rt2x00debug_read_queue_stats(struct file *file,
@@ -333,12 +334,12 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
if (*offset)
return 0;
- data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL);
+ data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL);
if (!data)
return -ENOMEM;
temp = data +
- sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n");
+ sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
queue_for_each(intf->rt2x00dev, queue) {
spin_lock_irqsave(&queue->lock, irqflags);
@@ -346,8 +347,8 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
queue->count, queue->limit, queue->length,
queue->index[Q_INDEX],
- queue->index[Q_INDEX_DONE],
- queue->index[Q_INDEX_CRYPTO]);
+ queue->index[Q_INDEX_DMA_DONE],
+ queue->index[Q_INDEX_DONE]);
spin_unlock_irqrestore(&queue->lock, irqflags);
}
@@ -371,6 +372,7 @@ static const struct file_operations rt2x00debug_fop_queue_stats = {
.read = rt2x00debug_read_queue_stats,
.open = rt2x00debug_file_open,
.release = rt2x00debug_file_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#ifdef CONFIG_RT2X00_LIB_CRYPTO
@@ -423,6 +425,7 @@ static const struct file_operations rt2x00debug_fop_crypto_stats = {
.read = rt2x00debug_read_crypto_stats,
.open = rt2x00debug_file_open,
.release = rt2x00debug_file_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif
@@ -481,6 +484,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
if (index >= debug->__name.word_count) \
return -EINVAL; \
\
+ if (length > sizeof(line)) \
+ return -EINVAL; \
+ \
if (copy_from_user(line, buf, length)) \
return -EFAULT; \
\
@@ -509,6 +515,7 @@ static const struct file_operations rt2x00debug_fop_##__name = {\
.write = rt2x00debug_write_##__name, \
.open = rt2x00debug_file_open, \
.release = rt2x00debug_file_release, \
+ .llseek = generic_file_llseek, \
};
RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
@@ -542,6 +549,7 @@ static const struct file_operations rt2x00debug_fop_dev_flags = {
.read = rt2x00debug_read_dev_flags,
.open = rt2x00debug_file_open,
.release = rt2x00debug_file_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct dentry *rt2x00debug_create_file_driver(const char *name,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 585e8166f22a..053fdd3bd720 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -250,6 +251,12 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
+void rt2x00lib_dmadone(struct queue_entry *entry)
+{
+ rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
+
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
@@ -383,15 +390,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* send the status report back.
*/
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
- /*
- * Only PCI and SOC devices process the tx status in process
- * context. Hence use ieee80211_tx_status for PCI and SOC
- * devices and stick to ieee80211_tx_status_irqsafe for USB.
- */
- if (rt2x00_is_usb(rt2x00dev))
- ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
- else
- ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);
else
dev_kfree_skb_any(entry->skb);
@@ -403,7 +402,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
rt2x00dev->ops->lib->clear_entry(entry);
- clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
@@ -416,6 +414,18 @@ void rt2x00lib_txdone(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
+void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status)
+{
+ struct txdone_entry_desc txdesc;
+
+ txdesc.flags = 0;
+ __set_bit(status, &txdesc.flags);
+ txdesc.retry = 0;
+
+ rt2x00lib_txdone(entry, &txdesc);
+}
+EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo);
+
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc)
{
@@ -460,9 +470,13 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
{
struct rxdone_entry_desc rxdesc;
struct sk_buff *skb;
- struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
+ struct ieee80211_rx_status *rx_status;
unsigned int header_length;
int rate_idx;
+
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ goto submit_entry;
+
/*
* Allocate a new sk_buffer. If no new buffer available, drop the
* received frame and reuse the existing buffer.
@@ -527,39 +541,32 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
*/
rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
+ /*
+ * Initialize RX status information, and send frame
+ * to mac80211.
+ */
+ rx_status = IEEE80211_SKB_RXCB(entry->skb);
rx_status->mactime = rxdesc.timestamp;
+ rx_status->band = rt2x00dev->curr_band;
+ rx_status->freq = rt2x00dev->curr_freq;
rx_status->rate_idx = rate_idx;
rx_status->signal = rxdesc.rssi;
rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
- /*
- * Send frame to mac80211 & debugfs.
- * mac80211 will clean up the skb structure.
- */
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
- memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
-
- /*
- * Currently only PCI and SOC devices handle rx interrupts in process
- * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni
- * for PCI and SOC devices.
- */
- if (rt2x00_is_usb(rt2x00dev))
- ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
- else
- ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
+ ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
/*
* Replace the skb with the freshly allocated one.
*/
entry->skb = skb;
- entry->flags = 0;
+submit_entry:
rt2x00dev->ops->lib->clear_entry(entry);
-
rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
@@ -710,7 +717,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
for (i = 0; i < spec->num_channels; i++) {
rt2x00lib_channel(&channels[i],
spec->channels[i].channel,
- spec->channels_info[i].tx_power1, i);
+ spec->channels_info[i].max_power, i);
}
/*
@@ -1017,6 +1024,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
* Stop all work.
*/
cancel_work_sync(&rt2x00dev->intf_work);
+ cancel_work_sync(&rt2x00dev->rxdone_work);
+ cancel_work_sync(&rt2x00dev->txdone_work);
/*
* Uninitialize device.
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index b818a43c4672..f0e1eb72befc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
fw->data[fw->size - 4], fw->data[fw->size - 3]);
+ snprintf(rt2x00dev->hw->wiphy->fw_version,
+ sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d",
+ fw->data[fw->size - 4], fw->data[fw->size - 3]);
retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
switch (retval) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index c004cd3a8847..ad3c7ff4837b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -54,6 +54,16 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
*/
if (txrate->flags & IEEE80211_TX_RC_MCS) {
txdesc->mcs = txrate->idx;
+
+ /*
+ * MIMO PS should be set to 1 for STA's using dynamic SM PS
+ * when using more then one tx stream (>MCS7).
+ */
+ if (tx_info->control.sta && txdesc->mcs > 7 &&
+ (tx_info->control.sta->ht_cap.cap &
+ (WLAN_HT_CAP_SM_PS_DYNAMIC <<
+ IEEE80211_HT_CAP_SM_PS_SHIFT)))
+ __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
} else {
txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index dc5c6574aaf4..70c85ac2e53e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -86,7 +86,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
const u8 *mac, const u8 *bssid);
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
- struct ieee80211_bss_conf *conf);
+ struct ieee80211_bss_conf *conf,
+ u32 changed);
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
struct antenna_setup ant);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 666cef3f8472..4d534e9dc628 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -188,7 +188,6 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
{
struct link_ant *ant = &rt2x00dev->link.ant;
- unsigned int flags = ant->flags;
/*
* Determine if software diversity is enabled for
@@ -196,13 +195,13 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
* Always perform this check since within the link
* tuner interval the configuration might have changed.
*/
- flags &= ~ANTENNA_RX_DIVERSITY;
- flags &= ~ANTENNA_TX_DIVERSITY;
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
- flags |= ANTENNA_RX_DIVERSITY;
+ ant->flags |= ANTENNA_RX_DIVERSITY;
if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- flags |= ANTENNA_TX_DIVERSITY;
+ ant->flags |= ANTENNA_TX_DIVERSITY;
if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
!(ant->flags & ANTENNA_TX_DIVERSITY)) {
@@ -210,9 +209,6 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
return true;
}
- /* Update flags */
- ant->flags = flags;
-
/*
* If we have only sampled the data over the last period
* we should now harvest the data. Otherwise just evaluate
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 235e037e6509..7862a840984a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* When the erp information has changed, we should perform
* additional configuration steps. For all other changes we are done.
*/
- if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
- rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
+ if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
+ BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
+ BSS_CHANGED_BEACON_INT))
+ rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
}
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a3401d301058..eede99939db9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
<http://rt2x00.serialmonkey.com>
@@ -311,7 +312,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
/*
* Initialize information from queue
*/
- txdesc->queue = entry->queue->qid;
+ txdesc->qid = entry->queue->qid;
txdesc->cw_min = entry->queue->cw_min;
txdesc->cw_max = entry->queue->cw_max;
txdesc->aifs = entry->queue->aifs;
@@ -448,15 +449,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct data_queue *queue = entry->queue;
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc);
/*
* All processing on the frame has been completed, this means
* it is now ready to be dumped to userspace through debugfs.
*/
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
@@ -476,7 +476,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
*/
if (rt2x00queue_threshold(queue) ||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kick_tx_queue(queue);
}
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -590,7 +590,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
intf->beacon->skb = NULL;
if (!enable_beacon) {
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+ rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
mutex_unlock(&intf->beacon_skb_mutex);
return 0;
}
@@ -625,6 +625,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
return 0;
}
+void rt2x00queue_for_each_entry(struct data_queue *queue,
+ enum queue_index start,
+ enum queue_index end,
+ void (*fn)(struct queue_entry *entry))
+{
+ unsigned long irqflags;
+ unsigned int index_start;
+ unsigned int index_end;
+ unsigned int i;
+
+ if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) {
+ ERROR(queue->rt2x00dev,
+ "Entry requested from invalid index range (%d - %d)\n",
+ start, end);
+ return;
+ }
+
+ /*
+ * Only protect the range we are going to loop over,
+ * if during our loop a extra entry is set to pending
+ * it should not be kicked during this run, since it
+ * is part of another TX operation.
+ */
+ spin_lock_irqsave(&queue->lock, irqflags);
+ index_start = queue->index[start];
+ index_end = queue->index[end];
+ spin_unlock_irqrestore(&queue->lock, irqflags);
+
+ /*
+ * Start from the TX done pointer, this guarentees that we will
+ * send out all frames in the correct order.
+ */
+ if (index_start < index_end) {
+ for (i = index_start; i < index_end; i++)
+ fn(&queue->entries[i]);
+ } else {
+ for (i = index_start; i < queue->limit; i++)
+ fn(&queue->entries[i]);
+
+ for (i = 0; i < index_end; i++)
+ fn(&queue->entries[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
+
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue)
{
@@ -686,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
if (queue->index[index] >= queue->limit)
queue->index[index] = 0;
+ queue->last_action[index] = jiffies;
+
if (index == Q_INDEX) {
queue->length++;
- queue->last_index = jiffies;
} else if (index == Q_INDEX_DONE) {
queue->length--;
queue->count++;
- queue->last_index_done = jiffies;
}
spin_unlock_irqrestore(&queue->lock, irqflags);
@@ -701,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
static void rt2x00queue_reset(struct data_queue *queue)
{
unsigned long irqflags;
+ unsigned int i;
spin_lock_irqsave(&queue->lock, irqflags);
queue->count = 0;
queue->length = 0;
- queue->last_index = jiffies;
- queue->last_index_done = jiffies;
- memset(queue->index, 0, sizeof(queue->index));
+
+ for (i = 0; i < Q_INDEX_MAX; i++) {
+ queue->index[i] = 0;
+ queue->last_action[i] = jiffies;
+ }
spin_unlock_irqrestore(&queue->lock, irqflags);
}
@@ -718,7 +766,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
txall_queue_for_each(rt2x00dev, queue)
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kill_tx_queue(queue);
}
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -730,9 +778,9 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00queue_reset(queue);
for (i = 0; i < queue->limit; i++) {
- queue->entries[i].flags = 0;
-
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
+ if (queue->qid == QID_RX)
+ rt2x00queue_index_inc(queue, Q_INDEX);
}
}
}
@@ -755,7 +803,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
* Allocate all queue entries.
*/
entry_size = sizeof(*entries) + qdesc->priv_size;
- entries = kzalloc(queue->limit * entry_size, GFP_KERNEL);
+ entries = kcalloc(queue->limit, entry_size, GFP_KERNEL);
if (!entries)
return -ENOMEM;
@@ -891,7 +939,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim;
- queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL);
+ queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL);
if (!queue) {
ERROR(rt2x00dev, "Queue allocation failed.\n");
return -ENOMEM;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 191e7775a9c0..d81d85f34866 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -268,6 +268,7 @@ struct txdone_entry_desc {
* @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
* @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
* @ENTRY_TXD_HT_SHORT_GI: Use short GI.
+ * @ENTRY_TXD_HT_MIMO_PS: The receiving STA is in dynamic SM PS mode.
*/
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
@@ -286,6 +287,7 @@ enum txentry_desc_flags {
ENTRY_TXD_HT_AMPDU,
ENTRY_TXD_HT_BW_40,
ENTRY_TXD_HT_SHORT_GI,
+ ENTRY_TXD_HT_MIMO_PS,
};
/**
@@ -294,7 +296,7 @@ enum txentry_desc_flags {
* Summary of information for the frame descriptor before sending a TX frame.
*
* @flags: Descriptor flags (See &enum queue_entry_flags).
- * @queue: Queue identification (See &enum data_queue_qid).
+ * @qid: Queue identification (See &enum data_queue_qid).
* @length: Length of the entire frame.
* @header_length: Length of 802.11 header.
* @length_high: PLCP length high word.
@@ -320,7 +322,7 @@ enum txentry_desc_flags {
struct txentry_desc {
unsigned long flags;
- enum data_queue_qid queue;
+ enum data_queue_qid qid;
u16 length;
u16 header_length;
@@ -358,17 +360,17 @@ struct txentry_desc {
* @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data
* transfer (either TX or RX depending on the queue). The entry should
* only be touched after the device has signaled it is done with it.
- * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data
- * encryption or decryption. The entry should only be touched after
- * the device has signaled it is done with it.
* @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting
* for the signal to start sending.
+ * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
+ * while transfering the data to the hardware. No TX status report will
+ * be expected from the hardware.
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
ENTRY_OWNER_DEVICE_DATA,
- ENTRY_OWNER_DEVICE_CRYPTO,
ENTRY_DATA_PENDING,
+ ENTRY_DATA_IO_FAILED
};
/**
@@ -399,18 +401,18 @@ struct queue_entry {
*
* @Q_INDEX: Index pointer to the current entry in the queue, if this entry is
* owned by the hardware then the queue is considered to be full.
+ * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been
+ * transfered to the hardware.
* @Q_INDEX_DONE: Index pointer to the next entry which will be completed by
* the hardware and for which we need to run the txdone handler. If this
* entry is not owned by the hardware the queue is considered to be empty.
- * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription
- * will be completed by the hardware next.
* @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size
* of the index array.
*/
enum queue_index {
Q_INDEX,
+ Q_INDEX_DMA_DONE,
Q_INDEX_DONE,
- Q_INDEX_CRYPTO,
Q_INDEX_MAX,
};
@@ -446,13 +448,12 @@ struct data_queue {
enum data_queue_qid qid;
spinlock_t lock;
- unsigned long last_index;
- unsigned long last_index_done;
unsigned int count;
unsigned short limit;
unsigned short threshold;
unsigned short length;
unsigned short index[Q_INDEX_MAX];
+ unsigned long last_action[Q_INDEX_MAX];
unsigned short txop;
unsigned short aifs;
@@ -565,6 +566,22 @@ struct data_queue_desc {
queue_loop(__entry, (__dev)->tx, queue_end(__dev))
/**
+ * rt2x00queue_for_each_entry - Loop through all entries in the queue
+ * @queue: Pointer to @data_queue
+ * @start: &enum queue_index Pointer to start index
+ * @end: &enum queue_index Pointer to end index
+ * @fn: The function to call for each &struct queue_entry
+ *
+ * This will walk through all entries in the queue, in chronological
+ * order. This means it will start at the current @start pointer
+ * and will walk through the queue until it reaches the @end pointer.
+ */
+void rt2x00queue_for_each_entry(struct data_queue *queue,
+ enum queue_index start,
+ enum queue_index end,
+ void (*fn)(struct queue_entry *entry));
+
+/**
* rt2x00queue_empty - Check if the queue is empty.
* @queue: Queue to check if empty.
*/
@@ -601,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
}
/**
- * rt2x00queue_timeout - Check if a timeout occured for this queue
+ * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts
* @queue: Queue to check.
*/
static inline int rt2x00queue_timeout(struct data_queue *queue)
{
- return time_after(queue->last_index, queue->last_index_done + (HZ / 10));
+ return time_after(queue->last_action[Q_INDEX_DMA_DONE],
+ queue->last_action[Q_INDEX_DONE] + (HZ / 10));
+}
+
+/**
+ * rt2x00queue_timeout - Check if a timeout occured for DMA transfers
+ * @queue: Queue to check.
+ */
+static inline int rt2x00queue_dma_timeout(struct data_queue *queue)
+{
+ return time_after(queue->last_action[Q_INDEX],
+ queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10));
}
/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index ff3a36622d1b..4c5ae3d45625 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
+ Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -167,137 +168,142 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read);
/*
* TX data handlers.
*/
-static void rt2x00usb_interrupt_txdone(struct urb *urb)
+static void rt2x00usb_work_txdone_entry(struct queue_entry *entry)
{
- struct queue_entry *entry = (struct queue_entry *)urb->context;
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct txdone_entry_desc txdesc;
-
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
- return;
-
/*
- * Obtain the status about this packet.
- * Note that when the status is 0 it does not mean the
+ * If the transfer to hardware succeeded, it does not mean the
* frame was send out correctly. It only means the frame
* was succesfully pushed to the hardware, we have no
* way to determine the transmission status right now.
* (Only indirectly by looking at the failed TX counters
* in the register).
*/
- txdesc.flags = 0;
- if (!urb->status)
- __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
else
- __set_bit(TXDONE_FAILURE, &txdesc.flags);
- txdesc.retry = 0;
-
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
}
-static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+static void rt2x00usb_work_txdone(struct work_struct *work)
{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
- struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- u32 length;
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, txdone_work);
+ struct data_queue *queue;
+ struct queue_entry *entry;
- if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) {
- /*
- * USB devices cannot blindly pass the skb->len as the
- * length of the data to usb_fill_bulk_urb. Pass the skb
- * to the driver to determine what the length should be.
- */
- length = rt2x00dev->ops->lib->get_tx_data_len(entry);
+ tx_queue_for_each(rt2x00dev, queue) {
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- usb_fill_bulk_urb(entry_priv->urb, usb_dev,
- usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
- entry->skb->data, length,
- rt2x00usb_interrupt_txdone, entry);
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ break;
- usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+ rt2x00usb_work_txdone_entry(entry);
+ }
}
}
-void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2x00usb_interrupt_txdone(struct urb *urb)
{
- struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
- unsigned long irqflags;
- unsigned int index;
- unsigned int index_done;
- unsigned int i;
+ struct queue_entry *entry = (struct queue_entry *)urb->context;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+
+ if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ return;
/*
- * Only protect the range we are going to loop over,
- * if during our loop a extra entry is set to pending
- * it should not be kicked during this run, since it
- * is part of another TX operation.
+ * Report the frame as DMA done
*/
- spin_lock_irqsave(&queue->lock, irqflags);
- index = queue->index[Q_INDEX];
- index_done = queue->index[Q_INDEX_DONE];
- spin_unlock_irqrestore(&queue->lock, irqflags);
+ rt2x00lib_dmadone(entry);
/*
- * Start from the TX done pointer, this guarentees that we will
- * send out all frames in the correct order.
+ * Check if the frame was correctly uploaded
*/
- if (index_done < index) {
- for (i = index_done; i < index; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
- } else {
- for (i = index_done; i < queue->limit; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ if (urb->status)
+ __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
- for (i = 0; i < index; i++)
- rt2x00usb_kick_tx_entry(&queue->entries[i]);
- }
+ /*
+ * Schedule the delayed work for reading the TX status
+ * from the device.
+ */
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
+}
+
+static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+ u32 length;
+
+ if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+ return;
+
+ /*
+ * USB devices cannot blindly pass the skb->len as the
+ * length of the data to usb_fill_bulk_urb. Pass the skb
+ * to the driver to determine what the length should be.
+ */
+ length = rt2x00dev->ops->lib->get_tx_data_len(entry);
+
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
+ entry->skb->data, length,
+ rt2x00usb_interrupt_txdone, entry);
+
+ usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+}
+
+void rt2x00usb_kick_tx_queue(struct data_queue *queue)
+{
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kick_tx_entry);
}
EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
-void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
{
- struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
- struct queue_entry_priv_usb *entry_priv;
- struct queue_entry_priv_usb_bcn *bcn_priv;
- unsigned int i;
- bool kill_guard;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+ struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
+
+ if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ return;
+
+ usb_kill_urb(entry_priv->urb);
/*
- * When killing the beacon queue, we must also kill
- * the beacon guard byte.
+ * Kill guardian urb (if required by driver).
*/
- kill_guard =
- (qid == QID_BEACON) &&
- (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags));
+ if ((entry->queue->qid == QID_BEACON) &&
+ (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
+ usb_kill_urb(bcn_priv->guardian_urb);
/*
- * Cancel all entries.
+ * We need a short delay here to wait for
+ * the URB to be canceled
*/
- for (i = 0; i < queue->limit; i++) {
- entry_priv = queue->entries[i].priv_data;
- usb_kill_urb(entry_priv->urb);
+ do {
+ udelay(100);
+ } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
+}
- /*
- * Kill guardian urb (if required by driver).
- */
- if (kill_guard) {
- bcn_priv = queue->entries[i].priv_data;
- usb_kill_urb(bcn_priv->guardian_urb);
- }
- }
+void rt2x00usb_kill_tx_queue(struct data_queue *queue)
+{
+ rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+ rt2x00usb_kill_tx_entry);
}
EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
-static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
+static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
{
- struct queue_entry_priv_usb *entry_priv;
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
unsigned short threshold = queue->threshold;
- WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid);
+ WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
+ " invoke forced forced reset", queue->qid);
/*
* Temporarily disable the TX queue, this will force mac80211
@@ -307,20 +313,33 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
* queue from being enabled during the txdone handler.
*/
queue->threshold = queue->limit;
- ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
+ ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
/*
- * Reset all currently uploaded TX frames.
+ * Kill all entries in the queue, afterwards we need to
+ * wait a bit for all URBs to be cancelled.
*/
- while (!rt2x00queue_empty(queue)) {
- entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data;
- usb_kill_urb(entry_priv->urb);
+ rt2x00usb_kill_tx_queue(queue);
- /*
- * We need a short delay here to wait for
- * the URB to be canceled and invoked the tx_done handler.
- */
- udelay(200);
+ /*
+ * In case that a driver has overriden the txdone_work
+ * function, we invoke the TX done through there.
+ */
+ rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
+
+ /*
+ * Security measure: if the driver did override the
+ * txdone_work function, and the hardware did arrive
+ * in a state which causes it to malfunction, it is
+ * possible that the driver couldn't handle the txdone
+ * event correctly. So after giving the driver the
+ * chance to cleanup, we now force a cleanup of any
+ * leftovers.
+ */
+ if (!rt2x00queue_empty(queue)) {
+ WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
+ " status handling failed, invoke hard reset", queue->qid);
+ rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
}
/*
@@ -328,7 +347,15 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue)
* queue again.
*/
queue->threshold = threshold;
- ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
+ ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
+}
+
+static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
+{
+ WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
+ " invoke forced tx handler", queue->qid);
+
+ ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
}
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -336,8 +363,10 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
tx_queue_for_each(rt2x00dev, queue) {
+ if (rt2x00queue_dma_timeout(queue))
+ rt2x00usb_watchdog_tx_dma(queue);
if (rt2x00queue_timeout(queue))
- rt2x00usb_watchdog_reset_tx(queue);
+ rt2x00usb_watchdog_tx_status(queue);
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
@@ -345,38 +374,62 @@ EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
/*
* RX data handlers.
*/
+static void rt2x00usb_work_rxdone(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, rxdone_work);
+ struct queue_entry *entry;
+ struct skb_frame_desc *skbdesc;
+ u8 rxd[32];
+
+ while (!rt2x00queue_empty(rt2x00dev->rx)) {
+ entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
+
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ break;
+
+ /*
+ * Fill in desc fields of the skb descriptor
+ */
+ skbdesc = get_skb_frame_desc(entry->skb);
+ skbdesc->desc = rxd;
+ skbdesc->desc_len = entry->queue->desc_size;
+
+ /*
+ * Send the frame to rt2x00lib for further processing.
+ */
+ rt2x00lib_rxdone(rt2x00dev, entry);
+ }
+}
+
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- u8 rxd[32];
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
/*
- * Check if the received data is simply too small
- * to be actually valid, or if the urb is signaling
- * a problem.
+ * Report the frame as DMA done
*/
- if (urb->actual_length < entry->queue->desc_size || urb->status) {
- set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_submit_urb(urb, GFP_ATOMIC);
- return;
- }
+ rt2x00lib_dmadone(entry);
/*
- * Fill in desc fields of the skb descriptor
+ * Check if the received data is simply too small
+ * to be actually valid, or if the urb is signaling
+ * a problem.
*/
- skbdesc->desc = rxd;
- skbdesc->desc_len = entry->queue->desc_size;
+ if (urb->actual_length < entry->queue->desc_size || urb->status)
+ __set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
/*
- * Send the frame to rt2x00lib for further processing.
+ * Schedule the delayed work for reading the RX status
+ * from the device.
*/
- rt2x00lib_rxdone(rt2x00dev, entry);
+ if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+ test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
}
/*
@@ -391,7 +444,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
* The USB version of kill_tx_queue also works
* on the RX queue.
*/
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX);
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
@@ -405,6 +458,8 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
int pipe;
+ entry->flags = 0;
+
if (entry->queue->qid == QID_RX) {
pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
@@ -413,8 +468,6 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
- } else {
- entry->flags = 0;
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
@@ -659,6 +712,9 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
+ INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone);
+ INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
+
retval = rt2x00usb_alloc_reg(rt2x00dev);
if (retval)
goto exit_free_device;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index d3d3ddc40875..c2d997f67b3e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn {
/**
* rt2x00usb_kick_tx_queue - Kick data queue
- * @rt2x00dev: Pointer to &struct rt2x00_dev
- * @qid: Data queue to kick
+ * @queue: Data queue to kick
*
* This will walk through all entries of the queue and push all pending
* frames to the hardware as a single burst.
*/
-void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid);
+void rt2x00usb_kick_tx_queue(struct data_queue *queue);
/**
* rt2x00usb_kill_tx_queue - Kill data queue
- * @rt2x00dev: Pointer to &struct rt2x00_dev
- * @qid: Data queue to kill
+ * @queue: Data queue to kill
*
* This will walk through all entries of the queue and kill all
* previously kicked frames before they can be send.
*/
-void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid);
+void rt2x00usb_kill_tx_queue(struct data_queue *queue);
/**
* rt2x00usb_watchdog - Watchdog for USB communication
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e539c6cb636f..97b3935f615b 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u32 reg;
@@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
+ }
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR5,
+ erp->basic_rates);
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+ }
- rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
- rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
- rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
- rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
- rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+ rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
+ }
}
static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -1050,7 +1059,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
/*
* Determine r17 bounds.
*/
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28;
up_bound = 0x48;
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
@@ -1645,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
rt2x00_set_field32(&reg, INT_MASK_CSR_TXDONE, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_RXDONE, mask);
+ rt2x00_set_field32(&reg, INT_MASK_CSR_BEACON_DONE, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_ENABLE_MITIGATION, mask);
rt2x00_set_field32(&reg, INT_MASK_CSR_MITIGATION_PERIOD, 0xff);
rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
@@ -1658,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_5, mask);
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_6, mask);
rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_7, mask);
+ rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_TWAKEUP, mask);
rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg);
}
@@ -1766,12 +1777,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt61pci_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
@@ -1779,7 +1789,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
* Start writing the descriptor words.
*/
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
@@ -1802,15 +1812,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
}
rt2x00_desc_read(txd, 5, &word);
- rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);
rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,
skbdesc->entry->entry_idx);
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
- TXPOWER_TO_DEV(rt2x00dev->tx_power));
+ TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
- if (txdesc->queue != QID_BEACON) {
+ if (txdesc->qid != QID_BEACON) {
rt2x00_desc_read(txd, 6, &word);
rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
skbdesc->skb_dma);
@@ -1857,7 +1867,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
*/
skbdesc->desc = txd;
skbdesc->desc_len =
- (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
+ (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
}
/*
@@ -1882,7 +1892,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt61pci_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1918,34 +1928,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
entry->skb = NULL;
}
-static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid queue)
+static void rt61pci_kick_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
-static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
- const enum data_queue_qid qid)
+static void rt61pci_kill_tx_queue(struct data_queue *queue)
{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
u32 reg;
- if (qid == QID_BEACON) {
+ if (queue->qid == QID_BEACON) {
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
return;
}
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
@@ -1972,7 +1982,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0;
}
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
if (lna == 3 || lna == 2)
offset += 10;
}
@@ -2107,11 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
"TX status report missed for entry %d\n",
entry_done->entry_idx);
- txdesc.flags = 0;
- __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
- txdesc.retry = 0;
-
- rt2x00lib_txdone(entry_done, &txdesc);
+ rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN);
entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
}
@@ -2654,20 +2660,24 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
}
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index aa9de18fd410..e22f01c1818e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
}
static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_erp *erp)
+ struct rt2x00lib_erp *erp,
+ u32 changed)
{
u32 reg;
@@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
- rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!erp->short_preamble);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
+ !!erp->short_preamble);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+ }
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR5,
+ erp->basic_rates);
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+ }
- rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
- rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
- rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
- rt2x00usb_register_read(rt2x00dev, MAC_CSR8, &reg);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
- rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
- rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
- rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR8, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+ rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg);
+ }
}
static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -929,7 +938,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
/*
* Determine r17 bounds.
*/
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28;
up_bound = 0x48;
@@ -1426,12 +1435,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
/*
* TX descriptor initialization
*/
-static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
+static void rt73usb_write_tx_desc(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *) skb->data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ __le32 *txd = (__le32 *) entry->skb->data;
u32 word;
/*
@@ -1464,7 +1472,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 0, word);
rt2x00_desc_read(txd, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);
rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
@@ -1487,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_read(txd, 5, &word);
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
- TXPOWER_TO_DEV(rt2x00dev->tx_power));
+ TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
@@ -1526,7 +1534,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
/*
* Write the TX descriptor for the beacon.
*/
- rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ rt73usb_write_tx_desc(entry, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -1574,6 +1582,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
return length;
}
+static void rt73usb_kill_tx_queue(struct data_queue *queue)
+{
+ if (queue->qid == QID_BEACON)
+ rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
+
+ rt2x00usb_kill_tx_queue(queue);
+}
+
/*
* RX control handlers
*/
@@ -1597,7 +1613,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0;
}
- if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
if (lna == 3 || lna == 2)
offset += 10;
@@ -2084,20 +2100,24 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Create channel information array
*/
- info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
- for (i = 0; i < 14; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 0; i < 14; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
if (spec->num_channels > 14) {
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
- for (i = 14; i < spec->num_channels; i++)
- info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ for (i = 14; i < spec->num_channels; i++) {
+ info[i].max_power = MAX_TXPOWER;
+ info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+ }
}
return 0;
@@ -2259,7 +2279,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
- .kill_tx_queue = rt2x00usb_kill_tx_queue,
+ .kill_tx_queue = rt73usb_kill_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 30107ce78dfb..05c6badbe201 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -99,19 +99,66 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
}
}
-static void rtl8180_handle_rx(struct ieee80211_hw *dev)
+static void rtl8180_handle_tx(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;
- unsigned int count = 32;
+ struct rtl8180_tx_ring *ring;
+ int prio;
+
+ spin_lock(&priv->lock);
+
+ for (prio = 3; prio >= 0; prio--) {
+ ring = &priv->tx_ring[prio];
+
+ while (skb_queue_len(&ring->queue)) {
+ struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u32 flags = le32_to_cpu(entry->flags);
+
+ if (flags & RTL818X_TX_DESC_FLAG_OWN)
+ break;
+
+ ring->idx = (ring->idx + 1) % ring->entries;
+ skb = __skb_dequeue(&ring->queue);
+ pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
+ skb->len, PCI_DMA_TODEVICE);
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (flags & RTL818X_TX_DESC_FLAG_TX_OK))
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = (flags & 0xFF) + 1;
+ info->status.rates[1].idx = -1;
+
+ ieee80211_tx_status(dev, skb);
+ if (ring->entries - skb_queue_len(&ring->queue) == 2)
+ ieee80211_wake_queue(dev, prio);
+ }
+ }
+
+ spin_unlock(&priv->lock);
+}
+
+static int rtl8180_poll(struct ieee80211_hw *dev, int budget)
+{
+ struct rtl8180_priv *priv = dev->priv;
+ unsigned int count = 0;
u8 signal, agc, sq;
- while (count--) {
+ /* handle pending Tx queue cleanup */
+ rtl8180_handle_tx(dev);
+
+ while (count++ < budget) {
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
u32 flags = le32_to_cpu(entry->flags);
if (flags & RTL818X_RX_DESC_FLAG_OWN)
- return;
+ break;
if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
RTL818X_RX_DESC_FLAG_FOF |
@@ -151,7 +198,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
- ieee80211_rx_irqsafe(dev, skb);
+ ieee80211_rx(dev, skb);
skb = new_skb;
priv->rx_buf[priv->rx_idx] = skb;
@@ -168,41 +215,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
priv->rx_idx = (priv->rx_idx + 1) % 32;
}
-}
-static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
-{
- struct rtl8180_priv *priv = dev->priv;
- struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
+ if (count < budget) {
+ /* disable polling */
+ ieee80211_napi_complete(dev);
- while (skb_queue_len(&ring->queue)) {
- struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- u32 flags = le32_to_cpu(entry->flags);
-
- if (flags & RTL818X_TX_DESC_FLAG_OWN)
- return;
-
- ring->idx = (ring->idx + 1) % ring->entries;
- skb = __skb_dequeue(&ring->queue);
- pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
- skb->len, PCI_DMA_TODEVICE);
-
- info = IEEE80211_SKB_CB(skb);
- ieee80211_tx_info_clear_status(info);
-
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (flags & RTL818X_TX_DESC_FLAG_TX_OK))
- info->flags |= IEEE80211_TX_STAT_ACK;
-
- info->status.rates[0].count = (flags & 0xFF) + 1;
- info->status.rates[1].idx = -1;
-
- ieee80211_tx_status_irqsafe(dev, skb);
- if (ring->entries - skb_queue_len(&ring->queue) == 2)
- ieee80211_wake_queue(dev, prio);
+ /* enable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
}
+
+ return count;
}
static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
@@ -211,31 +233,17 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
struct rtl8180_priv *priv = dev->priv;
u16 reg;
- spin_lock(&priv->lock);
reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
- if (unlikely(reg == 0xFFFF)) {
- spin_unlock(&priv->lock);
+ if (unlikely(reg == 0xFFFF))
return IRQ_HANDLED;
- }
rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
- if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
- rtl8180_handle_tx(dev, 3);
-
- if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
- rtl8180_handle_tx(dev, 2);
-
- if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
- rtl8180_handle_tx(dev, 1);
-
- if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
- rtl8180_handle_tx(dev, 0);
-
- if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
- rtl8180_handle_rx(dev);
+ /* disable interrupts */
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
- spin_unlock(&priv->lock);
+ /* enable polling */
+ ieee80211_napi_schedule(dev);
return IRQ_HANDLED;
}
@@ -247,7 +255,6 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_tx_ring *ring;
struct rtl8180_tx_desc *entry;
- unsigned long flags;
unsigned int idx, prio;
dma_addr_t mapping;
u32 tx_flags;
@@ -294,7 +301,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
plcp_len |= 1 << 15;
}
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
@@ -318,7 +325,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
if (ring->entries - skb_queue_len(&ring->queue) < 2)
ieee80211_stop_queue(dev, prio);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -783,6 +790,7 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_vif *vif_priv;
int i;
+ u8 reg;
vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
@@ -791,12 +799,14 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
rtl818x_iowrite8(priv, &priv->map->BSSID[i],
info->bssid[i]);
- if (is_valid_ether_addr(info->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR,
- RTL818X_MSR_NO_LINK);
+ if (is_valid_ether_addr(info->bssid)) {
+ if (vif->type == NL80211_IFTYPE_ADHOC)
+ reg = RTL818X_MSR_ADHOC;
+ else
+ reg = RTL818X_MSR_INFRA;
+ } else
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
}
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
@@ -861,6 +871,7 @@ static const struct ieee80211_ops rtl8180_ops = {
.prepare_multicast = rtl8180_prepare_multicast,
.configure_filter = rtl8180_configure_filter,
.get_tsf = rtl8180_get_tsf,
+ .napi_poll = rtl8180_poll,
};
static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -992,6 +1003,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
dev->queues = 1;
dev->max_signal = 65;
+ dev->napi_weight = 64;
+
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
reg &= RTL818X_TX_CONF_HWVER_MASK;
switch (reg) {
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 98e0351c1dd6..38fa8244cc96 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
else
reg = 0;
- if (is_valid_ether_addr(info->bssid)) {
+ if (is_valid_ether_addr(info->bssid))
reg |= RTL818X_MSR_INFRA;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- } else {
+ else
reg |= RTL818X_MSR_NO_LINK;
- rtl818x_iowrite8(priv, &priv->map->MSR, reg);
- }
+
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
mutex_unlock(&priv->conf_mutex);
}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 6b942a28e6a5..e113d4c1fb35 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008-2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -274,6 +272,8 @@ struct wl1251 {
int irq;
bool use_eeprom;
+ spinlock_t wl_lock;
+
enum wl1251_state state;
struct mutex mutex;
@@ -401,7 +401,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl);
#define WL1251_DEFAULT_POWER_LEVEL 20
-#define WL1251_TX_QUEUE_MAX_LENGTH 20
+#define WL1251_TX_QUEUE_LOW_WATERMARK 10
+#define WL1251_TX_QUEUE_HIGH_WATERMARK 25
#define WL1251_DEFAULT_BEACON_INT 100
#define WL1251_DEFAULT_DTIM_PERIOD 1
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index 91891f928070..2f8a2ba744dc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -380,7 +380,7 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl)
out:
kfree(pd);
- return 0;
+ return ret;
}
int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
index 842df310d92a..c7cc5c1e8a75 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -37,7 +35,7 @@ struct acx_header {
/* payload length (not including headers */
u16 len;
-};
+} __packed;
struct acx_error_counter {
struct acx_header header;
@@ -459,8 +457,8 @@ struct acx_beacon_filter_ie_table {
struct acx_header header;
u8 num_ie;
- u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
u8 pad[3];
+ u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
} __packed;
#define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */
@@ -471,7 +469,7 @@ struct acx_conn_monit_params {
u32 synch_fail_thold; /* number of beacons missed */
u32 bss_lose_timeout; /* number of TU's from synch fail */
-};
+} __packed;
enum {
SG_ENABLE = 0,
@@ -1056,7 +1054,7 @@ struct acx_rate_class {
u8 long_retry_limit;
u8 aflags;
u8 reserved;
-};
+} __packed;
struct acx_rate_policy {
struct acx_header header;
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 65e0416be5b6..468b47b0328a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -302,7 +300,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
- BT_PTA_PREDICTION_EVENT_ID;
+ BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
ret = wl1251_event_unmask(wl);
if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h
index 90063697e8f2..7661bc5e4662 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index ce3722f4c3e3..15fb68c6b542 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -200,7 +200,7 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
out:
kfree(vbm);
- return 0;
+ return ret;
}
int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
index a9e4991369be..e5c74c631374 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -111,7 +109,7 @@ struct wl1251_cmd_header {
struct wl1251_command {
struct wl1251_cmd_header header;
u8 parameters[MAX_CMD_PARAMS];
-};
+} __packed;
enum {
CMD_MAILBOX_IDLE = 0,
@@ -164,7 +162,7 @@ struct cmd_read_write_memory {
of this field is the Host in WRITE command or the Wilink in READ
command. */
u8 value[MAX_READ_SIZE];
-};
+} __packed;
#define CMDMBOX_HEADER_LEN 4
#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
@@ -339,7 +337,7 @@ struct wl1251_cmd_trigger_scan_to {
struct wl1251_cmd_header header;
u32 timeout;
-};
+} __packed;
/* HW encryption keys */
#define NUM_ACCESS_CATEGORIES_COPY 4
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index 5e4465ac08fa..b03b593ee76a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -50,6 +48,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
static const struct file_operations name## _ops = { \
.read = name## _read, \
.open = wl1251_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_ADD(name, parent) \
@@ -86,6 +85,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \
static const struct file_operations sub## _ ##name## _ops = { \
.read = sub## _ ##name## _read, \
.open = wl1251_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_FWSTATS_ADD(sub, name) \
@@ -236,6 +236,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_len_ops = {
.read = tx_queue_len_read,
.open = wl1251_open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
@@ -257,6 +258,7 @@ static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_status_ops = {
.read = tx_queue_status_read,
.open = wl1251_open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void wl1251_debugfs_delete_files(struct wl1251 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
index 6dc3d080853c..b3417c02a218 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c
index 020d764f9c13..54223556b308 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ b/drivers/net/wireless/wl12xx/wl1251_event.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -36,9 +34,7 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
mbox->scheduled_scan_channels);
if (wl->scanning) {
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
wl->scanning = false;
}
@@ -97,6 +93,35 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
return 0;
}
+/*
+ * Poll the mailbox event field until any of the bits in the mask is set or a
+ * timeout occurs (WL1251_EVENT_TIMEOUT in msecs)
+ */
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms)
+{
+ u32 events_vector, event;
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+ do {
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ msleep(1);
+
+ /* read from both event fields */
+ wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector,
+ sizeof(events_vector));
+ event = events_vector & mask;
+ wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector,
+ sizeof(events_vector));
+ event |= events_vector & mask;
+ } while (!event);
+
+ return 0;
+}
+
int wl1251_event_unmask(struct wl1251 *wl)
{
int ret;
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h
index f48a2b66bc5a..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_event.h
+++ b/drivers/net/wireless/wl12xx/wl1251_event.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -117,5 +115,6 @@ struct event_mailbox {
int wl1251_event_unmask(struct wl1251 *wl);
void wl1251_event_mbox_config(struct wl1251 *wl);
int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
+int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
index b538bdd7b320..c5daec05d9ee 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
index 269cefb3e7d4..543f17582ead 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl12xx/wl1251_init.h
@@ -3,8 +3,6 @@
*
* Copyright (C) 2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
index f1c232e0887f..ad6ca68b303f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 861a5f33761e..faf221ca3f41 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008-2009 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -293,14 +291,14 @@ static void wl1251_irq_work(struct work_struct *work)
wl1251_tx_complete(wl);
}
- if (intr & (WL1251_ACX_INTR_EVENT_A |
- WL1251_ACX_INTR_EVENT_B)) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)",
- intr);
- if (intr & WL1251_ACX_INTR_EVENT_A)
- wl1251_event_handle(wl, 0);
- else
- wl1251_event_handle(wl, 1);
+ if (intr & WL1251_ACX_INTR_EVENT_A) {
+ wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
+ wl1251_event_handle(wl, 0);
+ }
+
+ if (intr & WL1251_ACX_INTR_EVENT_B) {
+ wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B");
+ wl1251_event_handle(wl, 1);
}
if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
@@ -339,11 +337,9 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
if (ret < 0)
goto out;
- /*
- * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
- * locking we just sleep instead, for now
- */
- msleep(10);
+ ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
+ if (ret < 0)
+ wl1251_warning("join timeout");
out:
return ret;
@@ -379,6 +375,7 @@ out:
static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct wl1251 *wl = hw->priv;
+ unsigned long flags;
skb_queue_tail(&wl->tx_queue, skb);
@@ -393,16 +390,13 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* The workqueue is slow to process the tx_queue and we need stop
* the queue here, otherwise the queue will get too long.
*/
- if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
+ if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) {
wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
- ieee80211_stop_queues(wl->hw);
- /*
- * FIXME: this is racy, the variable is not properly
- * protected. Maybe fix this by removing the stupid
- * variable altogether and checking the real queue state?
- */
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_stop_queues(wl->hw);
wl->tx_queue_stopped = true;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
}
return NETDEV_TX_OK;
@@ -471,9 +465,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
WARN_ON(wl->state != WL1251_STATE_ON);
if (wl->scanning) {
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
wl->scanning = false;
}
@@ -725,8 +717,9 @@ static int wl1251_set_key_type(struct wl1251 *wl,
struct ieee80211_key_conf *mac80211_key,
const u8 *addr)
{
- switch (mac80211_key->alg) {
- case ALG_WEP:
+ switch (mac80211_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_WEP_DEFAULT;
else
@@ -734,7 +727,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->hw_key_idx = mac80211_key->keyidx;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_TKIP_MIC_GROUP;
else
@@ -742,7 +735,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->hw_key_idx = mac80211_key->keyidx;
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
if (is_broadcast_ether_addr(addr))
key->key_type = KEY_AES_GROUP;
else
@@ -750,7 +743,7 @@ static int wl1251_set_key_type(struct wl1251 *wl,
mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
break;
default:
- wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
+ wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher);
return -EOPNOTSUPP;
}
@@ -783,7 +776,7 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key->alg, key->keyidx, key->keylen, key->flags);
+ key->cipher, key->keyidx, key->keylen, key->flags);
wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
if (is_zero_ether_addr(addr)) {
@@ -1438,5 +1431,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw);
MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
MODULE_FIRMWARE(WL1251_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index b55cb2bd459a..0b997bdfec09 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h
index c688ac57aee4..e5db81fc1dfc 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.h
@@ -1,14 +1,9 @@
-#ifndef __WL1251_PS_H__
-#define __WL1251_PS_H__
-
/*
* This file is part of wl1251
*
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -25,6 +20,9 @@
*
*/
+#ifndef __WL1251_PS_H__
+#define __WL1251_PS_H__
+
#include "wl1251.h"
#include "wl1251_acx.h"
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
index d16edd9bf06c..a5809019c5c1 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1251_reg.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index 1b6294b3b996..25764592a596 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h
index da4e53406a0e..4448f635a4d8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index b901b6135654..c0b68b0a9aa8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -339,4 +339,4 @@ module_init(wl1251_sdio_init);
module_exit(wl1251_sdio_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 27fdfaaeb074..334ded9881c0 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -3,8 +3,6 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -344,5 +342,5 @@ module_init(wl1251_spi_init);
module_exit(wl1251_spi_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
MODULE_ALIAS("spi:wl1251");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
index 2e273a97e7f3..7dcf3cf7ae40 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index a38ec199187a..388492a7f41f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
@@ -189,7 +187,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
tx_hdr = (struct tx_double_buffer_desc *) skb->data;
if (control->control.hw_key &&
- control->control.hw_key->alg == ALG_TKIP) {
+ control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen;
__le16 fc;
u16 length;
@@ -322,11 +320,6 @@ void wl1251_tx_work(struct work_struct *work)
ret = wl1251_tx_frame(wl, skb);
if (ret == -EBUSY) {
- /* firmware buffer is full, stop queues */
- wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, "
- "stop queues");
- ieee80211_stop_queues(wl->hw);
- wl->tx_queue_stopped = true;
skb_queue_head(&wl->tx_queue, skb);
goto out;
} else if (ret < 0) {
@@ -399,7 +392,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl,
*/
frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
skb_pull(skb, WL1251_TKIP_IV_SPACE);
@@ -449,6 +442,7 @@ void wl1251_tx_complete(struct wl1251 *wl)
{
int i, result_index, num_complete = 0;
struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+ unsigned long flags;
if (unlikely(wl->state != WL1251_STATE_ON))
return;
@@ -477,6 +471,20 @@ void wl1251_tx_complete(struct wl1251 *wl)
}
}
+ if (wl->tx_queue_stopped
+ &&
+ skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){
+
+ /* firmware buffer has space, restart queues */
+ wl1251_debug(DEBUG_TX, "tx_complete: waking queues");
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ ieee80211_wake_queues(wl->hw);
+ wl->tx_queue_stopped = false;
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
+
+ }
+
/* Every completed frame needs to be acknowledged */
if (num_complete) {
/*
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
index f40eeb37f5aa..96011e78cd5a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -4,8 +4,6 @@
* Copyright (c) 1998-2007 Texas Instruments Incorporated
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index bb245f05af49..f03ad088db8b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -269,7 +269,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl)
out:
kfree(pd);
- return 0;
+ return ret;
}
int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index c239ef4d0b8d..ada84e583bda 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -51,6 +51,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
static const struct file_operations name## _ops = { \
.read = name## _read, \
.open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_ADD(name, parent) \
@@ -87,6 +88,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \
static const struct file_operations sub## _ ##name## _ops = { \
.read = sub## _ ##name## _read, \
.open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_FWSTATS_ADD(sub, name) \
@@ -237,6 +239,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_len_ops = {
.read = tx_queue_len_read,
.open = wl1271_open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
@@ -291,7 +294,8 @@ out:
static const struct file_operations gpio_power_ops = {
.read = gpio_power_read,
.write = gpio_power_write,
- .open = wl1271_open_file_generic
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void wl1271_debugfs_delete_files(struct wl1271 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 9d68f0012f05..8e55cf8d509d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -948,9 +948,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
ieee80211_enable_dyn_ps(wl->vif);
if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
@@ -1439,7 +1437,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key_conf->alg, key_conf->keyidx,
+ key_conf->cipher, key_conf->keyidx,
key_conf->keylen, key_conf->flags);
wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
@@ -1455,20 +1453,21 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (ret < 0)
goto out_unlock;
- switch (key_conf->alg) {
- case ALG_WEP:
+ switch (key_conf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
key_type = KEY_WEP;
key_conf->hw_key_idx = key_conf->keyidx;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
key_type = KEY_TKIP;
key_conf->hw_key_idx = key_conf->keyidx;
tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
key_type = KEY_AES;
key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -1476,7 +1475,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
default:
- wl1271_error("Unknown key algo 0x%x", key_conf->alg);
+ wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
ret = -EOPNOTSUPP;
goto out_sleep;
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index fec43eed8c55..e4950c8e396e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -215,9 +215,7 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_DONE:
- mutex_unlock(&wl->mutex);
ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
@@ -248,7 +246,7 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
wl->scan.req = req;
- wl->scan.scanned_ch = kzalloc(req->n_channels *
+ wl->scan.scanned_ch = kcalloc(req->n_channels,
sizeof(*wl->scan.scanned_ch),
GFP_KERNEL);
wl1271_scan_stm(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 7059b5cccf0f..b5d9565f659f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -107,6 +107,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
@@ -122,9 +124,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
}
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio read failed (%d)", ret);
-
}
static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -133,6 +136,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
@@ -147,26 +152,42 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
else
ret = sdio_memcpy_toio(func, addr, buf, len);
}
+
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio write failed (%d)", ret);
+}
+
+static void wl1271_sdio_power_on(struct wl1271 *wl)
+{
+ struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
}
-static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+static void wl1271_sdio_power_off(struct wl1271 *wl)
{
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+}
+
+static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+{
/* Let the SDIO stack handle wlan_enable control, so we
* keep host claimed while wlan is in use to keep wl1271
* alive.
*/
- if (enable) {
- sdio_claim_host(func);
- sdio_enable_func(func);
- } else {
- sdio_disable_func(func);
- sdio_release_host(func);
- }
+ if (enable)
+ wl1271_sdio_power_on(wl);
+ else
+ wl1271_sdio_power_off(wl);
+
}
static struct wl1271_if_operations sdio_ops = {
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index c592cc2e9fe8..dc0b46c93c4b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -193,7 +193,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP)
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
extra = WL1271_TKIP_IV_SPACE;
if (info->control.hw_key) {
@@ -347,7 +347,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
/* remove TKIP header space if present */
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen);
skb_pull(skb, WL1271_TKIP_IV_SPACE);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index a1cc2d498a1c..420e9e986a18 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -29,7 +29,6 @@
#include <linux/delay.h>
#include <linux/types.h>
-#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/in.h>
@@ -1411,15 +1410,6 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
return wstats;
}
-static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, "wl3501_cs", sizeof(info->driver));
-}
-
-static const struct ethtool_ops ops = {
- .get_drvinfo = wl3501_get_drvinfo
-};
-
/**
* wl3501_detach - deletes a driver "instance"
* @link - FILL_IN
@@ -1905,7 +1895,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
this->p_dev = p_dev;
dev->wireless_data = &this->wireless_data;
dev->wireless_handlers = &wl3501_handler_def;
- SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
p_dev->priv = dev;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index b2af3c549bb3..87a95bcfee57 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -973,6 +973,7 @@ static void dump_fw_registers(struct zd_chip *chip)
static int print_fw_version(struct zd_chip *chip)
{
+ struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy;
int r;
u16 version;
@@ -982,6 +983,10 @@ static int print_fw_version(struct zd_chip *chip)
return r;
dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
+
+ snprintf(wiphy->fw_version, sizeof(wiphy->fw_version),
+ "%04hx", version);
+
return 0;
}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index b50fedcef8ac..788a9bc1dbac 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1395,7 +1395,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
}
/* Common code used when first setting up, and when resuming. */
-static int talk_to_backend(struct xenbus_device *dev,
+static int talk_to_netback(struct xenbus_device *dev,
struct netfront_info *info)
{
const char *message;
@@ -1545,7 +1545,7 @@ static int xennet_connect(struct net_device *dev)
return -ENODEV;
}
- err = talk_to_backend(np->xbdev, np);
+ err = talk_to_netback(np->xbdev, np);
if (err)
return err;
@@ -1599,7 +1599,7 @@ static int xennet_connect(struct net_device *dev)
/**
* Callback received when the backend's state changes.
*/
-static void backend_changed(struct xenbus_device *dev,
+static void netback_changed(struct xenbus_device *dev,
enum xenbus_state backend_state)
{
struct netfront_info *np = dev_get_drvdata(&dev->dev);
@@ -1801,7 +1801,7 @@ static struct xenbus_driver netfront_driver = {
.probe = netfront_probe,
.remove = __devexit_p(xennet_remove),
.resume = netfront_resume,
- .otherend_changed = backend_changed,
+ .otherend_changed = netback_changed,
};
static int __init netif_init(void)
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index ecbbb688eba0..f3f8be5a35fa 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -641,7 +641,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
skb_put(skb, len); /* Tell the skb how much data we got */
skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
@@ -1269,6 +1269,16 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev)
return 0;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+xemaclite_poll_controller(struct net_device *ndev)
+{
+ disable_irq(ndev->irq);
+ xemaclite_interrupt(ndev->irq, ndev);
+ enable_irq(ndev->irq);
+}
+#endif
+
static struct net_device_ops xemaclite_netdev_ops = {
.ndo_open = xemaclite_open,
.ndo_stop = xemaclite_close,
@@ -1276,6 +1286,9 @@ static struct net_device_ops xemaclite_netdev_ops = {
.ndo_set_mac_address = xemaclite_set_mac_address,
.ndo_tx_timeout = xemaclite_tx_timeout,
.ndo_get_stats = xemaclite_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = xemaclite_poll_controller,
+#endif
};
/* Match table for OF platform binding */
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 4eb67aed68dd..cd1b3dcd61db 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -646,7 +646,7 @@ static int yellowfin_open(struct net_device *dev)
init_timer(&yp->timer);
yp->timer.expires = jiffies + 3*HZ;
yp->timer.data = (unsigned long)dev;
- yp->timer.function = &yellowfin_timer; /* timer handler */
+ yp->timer.function = yellowfin_timer; /* timer handler */
add_timer(&yp->timer);
return 0;
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index a9352b2c7ac4..b7e755f4178a 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -141,16 +141,6 @@ static struct notifier_block module_load_nb = {
.notifier_call = module_load_notify,
};
-
-static void end_sync(void)
-{
- end_cpu_work();
- /* make sure we don't leak task structs */
- process_task_mortuary();
- process_task_mortuary();
-}
-
-
int sync_start(void)
{
int err;
@@ -158,7 +148,7 @@ int sync_start(void)
if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL))
return -ENOMEM;
- start_cpu_work();
+ mutex_lock(&buffer_mutex);
err = task_handoff_register(&task_free_nb);
if (err)
@@ -173,7 +163,10 @@ int sync_start(void)
if (err)
goto out4;
+ start_cpu_work();
+
out:
+ mutex_unlock(&buffer_mutex);
return err;
out4:
profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
@@ -182,7 +175,6 @@ out3:
out2:
task_handoff_unregister(&task_free_nb);
out1:
- end_sync();
free_cpumask_var(marked_cpus);
goto out;
}
@@ -190,11 +182,20 @@ out1:
void sync_stop(void)
{
+ /* flush buffers */
+ mutex_lock(&buffer_mutex);
+ end_cpu_work();
unregister_module_notifier(&module_load_nb);
profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
task_handoff_unregister(&task_free_nb);
- end_sync();
+ mutex_unlock(&buffer_mutex);
+ flush_scheduled_work();
+
+ /* make sure we don't leak task structs */
+ process_task_mortuary();
+ process_task_mortuary();
+
free_cpumask_var(marked_cpus);
}
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 219f79e2210a..f179ac2ea801 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -120,8 +120,6 @@ void end_cpu_work(void)
cancel_delayed_work(&b->work);
}
-
- flush_scheduled_work();
}
/*
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index b336cd9ee7a1..b4a685719dba 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -257,16 +257,9 @@ static int __init oprofile_init(void)
printk(KERN_INFO "oprofile: using timer interrupt.\n");
err = oprofile_timer_init(&oprofile_ops);
if (err)
- goto out_arch;
+ return err;
}
- err = oprofilefs_register();
- if (err)
- goto out_arch;
- return 0;
-
-out_arch:
- oprofile_arch_exit();
- return err;
+ return oprofilefs_register();
}
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
index bbd7516e0869..eabef6b71970 100644
--- a/drivers/oprofile/oprofile_files.c
+++ b/drivers/oprofile/oprofile_files.c
@@ -59,6 +59,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf,
static const struct file_operations timeout_fops = {
.read = timeout_read,
.write = timeout_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif
@@ -93,7 +94,8 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou
static const struct file_operations depth_fops = {
.read = depth_read,
- .write = depth_write
+ .write = depth_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -105,6 +107,7 @@ static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t cou
static const struct file_operations pointer_size_fops = {
.read = pointer_size_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -116,6 +119,7 @@ static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count,
static const struct file_operations cpu_type_fops = {
.read = cpu_type_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -151,6 +155,7 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co
static const struct file_operations enable_fops = {
.read = enable_read,
.write = enable_write,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -163,6 +168,7 @@ static ssize_t dump_write(struct file *file, char const __user *buf, size_t coun
static const struct file_operations dump_fops = {
.write = dump_write,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
void oprofile_create_files(struct super_block *sb, struct dentry *root)
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 2766a6d3c2e9..bfe7ec9fd1da 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -117,12 +117,14 @@ static const struct file_operations ulong_fops = {
.read = ulong_read_file,
.write = ulong_write_file,
.open = default_open,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations ulong_ro_fops = {
.read = ulong_read_file,
.open = default_open,
+ .llseek = default_llseek,/* read accesses f_pos */
};
@@ -183,6 +185,7 @@ static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t coun
static const struct file_operations atomic_ro_fops = {
.read = atomic_read_file,
.open = default_open,
+ .llseek = default_llseek,/* read accesses f_pos */
};
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 0950fa40684f..8d62fb76cd41 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2599,7 +2599,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq,
printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n");
return 0;
case 0x8:
- DPRINTK(KERN_DEBUG "parport_pc: ITE8874 found (2S)\n");
+ printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n");
return 0;
default:
printk(KERN_INFO "parport_pc: unknown ITE887x\n");
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0a19708074c2..4ef56a0920a7 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -36,6 +36,7 @@
#include <linux/tboot.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <asm/iommu_table.h>
#define PREFIX "DMAR: "
@@ -687,7 +688,7 @@ failed:
return 0;
}
-void __init detect_intel_iommu(void)
+int __init detect_intel_iommu(void)
{
int ret;
@@ -723,6 +724,8 @@ void __init detect_intel_iommu(void)
}
early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
dmar_tbl = NULL;
+
+ return ret ? 1 : -ENODEV;
}
@@ -1455,3 +1458,4 @@ int __init dmar_ir_support(void)
return 0;
return dmar->flags & 0x1;
}
+IOMMU_INIT_POST(detect_intel_iommu);
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 45fcc1e96df9..3bc72d18b121 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
acpi_handle chandle, handle;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
- flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
- OSC_SHPC_NATIVE_HP_CONTROL |
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+ flags &= OSC_SHPC_NATIVE_HP_CONTROL;
if (!flags) {
err("Invalid flags %u specified!\n", flags);
return -EINVAL;
@@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s\n",
(char *)string.pointer);
- status = acpi_pci_osc_control_set(handle, flags);
+ status = acpi_pci_osc_control_set(handle, &flags, flags);
if (ACPI_SUCCESS(status))
goto got_one;
if (status == AE_SUPPORT)
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 56215322930a..4cb30447a486 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -34,10 +34,11 @@
#include <linux/workqueue.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/debugfs.h>
#include "cpqphp.h"
+static DEFINE_MUTEX(cpqphp_mutex);
static int show_ctrl (struct controller *ctrl, char *buf)
{
char *out = buf;
@@ -147,7 +148,7 @@ static int open(struct inode *inode, struct file *file)
struct ctrl_dbg *dbg;
int retval = -ENOMEM;
- lock_kernel();
+ mutex_lock(&cpqphp_mutex);
dbg = kmalloc(sizeof(*dbg), GFP_KERNEL);
if (!dbg)
goto exit;
@@ -160,7 +161,7 @@ static int open(struct inode *inode, struct file *file)
file->private_data = dbg;
retval = 0;
exit:
- unlock_kernel();
+ mutex_unlock(&cpqphp_mutex);
return retval;
}
@@ -169,7 +170,7 @@ static loff_t lseek(struct file *file, loff_t off, int whence)
struct ctrl_dbg *dbg;
loff_t new = -1;
- lock_kernel();
+ mutex_lock(&cpqphp_mutex);
dbg = file->private_data;
switch (whence) {
@@ -181,10 +182,10 @@ static loff_t lseek(struct file *file, loff_t off, int whence)
break;
}
if (new < 0 || new > dbg->size) {
- unlock_kernel();
+ mutex_unlock(&cpqphp_mutex);
return -EINVAL;
}
- unlock_kernel();
+ mutex_unlock(&cpqphp_mutex);
return (file->f_pos = new);
}
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index 1aaf3f32d3cd..f59ed30512b5 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -133,8 +133,8 @@ void __init ibmphp_hpc_initvars (void)
debug ("%s - Entry\n", __func__);
mutex_init(&sem_hpcaccess);
- init_MUTEX (&semOperations);
- init_MUTEX_LOCKED (&sem_exit);
+ sema_init(&semOperations, 1);
+ sema_init(&sem_exit, 0);
to_debug = 0;
debug ("%s - Exit\n", __func__);
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 4ed76b47b6dc..73d513989263 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -176,19 +176,11 @@ static inline void pciehp_firmware_init(void)
{
pciehp_acpi_slot_detection_init();
}
-
-static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
- int retval;
- u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
- retval = acpi_get_hp_hw_control_from_firmware(dev, flags);
- if (retval)
- return retval;
- return pciehp_acpi_slot_detection_check(dev);
-}
#else
#define pciehp_firmware_init() do {} while (0)
-#define pciehp_get_hp_hw_control_from_firmware(dev) 0
+static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
+{
+ return 0;
+}
#endif /* CONFIG_ACPI */
#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 1f4000a5a108..2574700db461 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev)
acpi_handle handle;
struct dummy_slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
- /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
- if (pciehp_get_hp_hw_control_from_firmware(pdev))
- return -ENODEV;
+
pos = pci_pcie_cap(pdev);
if (!pos)
return -ENODEV;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 3588ea61b0dd..aa5f3ff629ff 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
-MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
+MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
#define PCIE_MODULE_NAME "pciehp"
@@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev)
dev_info(&dev->device,
"Bypassing BIOS check for pciehp use on %s\n",
pci_name(dev->port));
- else if (pciehp_get_hp_hw_control_from_firmware(dev->port))
+ else if (pciehp_acpi_slot_detection_check(dev->port))
goto err_out_none;
ctrl = pcie_init(dev);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index ce6a3666b3d9..553d8ee55c1c 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -608,7 +608,7 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno,
* the VF BAR size multiplied by the number of VFs. The alignment
* is just the VF BAR size.
*/
-int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
{
struct resource tmp;
enum pci_bar_type type;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7fa3cbd742c5..cc232c016ef9 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2689,7 +2689,7 @@ int pcie_get_readrq(struct pci_dev *dev)
ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
if (!ret)
- ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
return ret;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 679c39de6a89..6beb11b617a9 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
#ifdef CONFIG_PCIEAER
void pci_no_aer(void);
+bool pci_aer_available(void);
#else
static inline void pci_no_aer(void) { }
+static inline bool pci_aer_available(void) { return false; }
#endif
static inline int pci_no_d1d2(struct pci_dev *dev)
@@ -262,7 +264,8 @@ extern int pci_iov_init(struct pci_dev *dev);
extern void pci_iov_release(struct pci_dev *dev);
extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
enum pci_bar_type *type);
-extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
+extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev,
+ int resno);
extern void pci_restore_iov_state(struct pci_dev *dev);
extern int pci_iov_bus_range(struct pci_bus *bus);
@@ -318,7 +321,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
}
#endif /* CONFIG_PCI_IOV */
-static inline int pci_resource_alignment(struct pci_dev *dev,
+static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
struct resource *res)
{
#ifdef CONFIG_PCI_IOV
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index ea654545e7c4..00c62df5a9fc 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -6,10 +6,11 @@
obj-$(CONFIG_PCIEASPM) += aspm.o
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
+pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
# Build PCI Express AER if needed
obj-$(CONFIG_PCIEAER) += aer/
-obj-$(CONFIG_PCIE_PME) += pme/
+obj-$(CONFIG_PCIE_PME) += pme.o
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 909924692b8a..e3714164d6e5 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -472,6 +472,7 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf,
static const struct file_operations aer_inject_fops = {
.write = aer_inject_write,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static struct miscdevice aer_inject_device = {
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 484cc55194b8..f409948e1a9b 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -72,6 +72,11 @@ void pci_no_aer(void)
pcie_aer_disable = 1; /* has priority over 'forceload' */
}
+bool pci_aer_available(void)
+{
+ return !pcie_aer_disable && pci_msi_enabled();
+}
+
static int set_device_error_reporting(struct pci_dev *dev, void *data)
{
bool enable = *((bool *)data);
@@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev)
*/
static int __init aer_service_init(void)
{
- if (pcie_aer_disable)
- return -ENXIO;
- if (!pci_msi_enabled())
+ if (!pci_aer_available())
return -ENXIO;
return pcie_port_service_register(&aerdriver);
}
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index f278d7b0d95d..2bb9b8972211 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -19,42 +19,6 @@
#include <acpi/apei.h>
#include "aerdrv.h"
-/**
- * aer_osc_setup - run ACPI _OSC method
- * @pciedev: pcie_device which AER is being enabled on
- *
- * @return: Zero on success. Nonzero otherwise.
- *
- * Invoked when PCIe bus loads AER service driver. To avoid conflict with
- * BIOS AER support requires BIOS to yield AER control to OS native driver.
- **/
-int aer_osc_setup(struct pcie_device *pciedev)
-{
- acpi_status status = AE_NOT_FOUND;
- struct pci_dev *pdev = pciedev->port;
- acpi_handle handle = NULL;
-
- if (acpi_pci_disabled)
- return -1;
-
- handle = acpi_find_root_bridge_handle(pdev);
- if (handle) {
- status = acpi_pci_osc_control_set(handle,
- OSC_PCI_EXPRESS_AER_CONTROL |
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
- }
-
- if (ACPI_FAILURE(status)) {
- dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't "
- "init device: %s\n",
- (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
- "no _OSC support" : "_OSC failed");
- return -1;
- }
-
- return 0;
-}
-
#ifdef CONFIG_ACPI_APEI
static inline int hest_match_pci(struct acpi_hest_aer_common *p,
struct pci_dev *pci)
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index fc0b5a93e1de..43421fbe080a 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -754,7 +754,7 @@ void aer_isr(struct work_struct *work)
{
struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
struct pcie_device *p_device = rpc->rpd;
- struct aer_err_source e_src;
+ struct aer_err_source uninitialized_var(e_src);
mutex_lock(&rpc->rpc_mutex);
while (get_e_source(rpc, &e_src))
@@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work)
*/
int aer_init(struct pcie_device *dev)
{
- if (pcie_aer_get_firmware_first(dev->port)) {
- dev_printk(KERN_DEBUG, &dev->device,
- "PCIe errors handled by platform firmware.\n");
- goto out;
- }
-
- if (aer_osc_setup(dev))
- goto out;
-
- return 0;
-out:
if (forceload) {
dev_printk(KERN_DEBUG, &dev->device,
"aerdrv forceload requested.\n");
pcie_aer_force_firmware_first(dev->port, 0);
- return 0;
}
- return -ENXIO;
+ return 0;
}
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme.c
index bbdea18693d9..2f3c90407227 100644
--- a/drivers/pci/pcie/pme/pcie_pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -23,38 +23,13 @@
#include <linux/pci-acpi.h>
#include <linux/pm_runtime.h>
-#include "../../pci.h"
-#include "pcie_pme.h"
+#include "../pci.h"
+#include "portdrv.h"
#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
/*
- * If set, this switch will prevent the PCIe root port PME service driver from
- * being registered. Consequently, the interrupt-based PCIe PME signaling will
- * not be used by any PCIe root ports in that case.
- */
-static bool pcie_pme_disabled = true;
-
-/*
- * The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
- * "In order to maintain compatibility with non-PCI Express-aware system
- * software, system power management logic must be configured by firmware to use
- * the legacy mechanism of signaling PME by default. PCI Express-aware system
- * software must notify the firmware prior to enabling native, interrupt-based
- * PME signaling." However, if the platform doesn't provide us with a suitable
- * notification mechanism or the notification fails, it is not clear whether or
- * not we are supposed to use the interrupt-based PCIe PME signaling. The
- * switch below can be used to indicate the desired behaviour. When set, it
- * will make the kernel use the interrupt-based PCIe PME signaling regardless of
- * the platform notification status, although the kernel will attempt to notify
- * the platform anyway. When unset, it will prevent the kernel from using the
- * the interrupt-based PCIe PME signaling if the platform notification fails,
- * which is the default.
- */
-static bool pcie_pme_force_enable;
-
-/*
* If this switch is set, MSI will not be used for PCIe PME signaling. This
* causes the PCIe port driver to use INTx interrupts only, but it turns out
* that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based
@@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled;
static int __init pcie_pme_setup(char *str)
{
- if (!strncmp(str, "auto", 4))
- pcie_pme_disabled = false;
- else if (!strncmp(str, "force", 5))
- pcie_pme_force_enable = true;
-
- str = strchr(str, ',');
- if (str) {
- str++;
- str += strspn(str, " \t");
- if (*str && !strcmp(str, "nomsi"))
- pcie_pme_msi_disabled = true;
- }
+ if (!strncmp(str, "nomsi", 5))
+ pcie_pme_msi_disabled = true;
return 1;
}
__setup("pcie_pme=", pcie_pme_setup);
-/**
- * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME.
- * @srv: PCIe PME root port service to use for carrying out the check.
- *
- * Notify the platform that the native PCIe PME is going to be used and return
- * 'true' if the control of the PCIe PME registers has been acquired from the
- * platform.
- */
-static bool pcie_pme_platform_setup(struct pcie_device *srv)
-{
- if (!pcie_pme_platform_notify(srv))
- return true;
- return pcie_pme_force_enable;
-}
-
struct pcie_pme_service_data {
spinlock_t lock;
struct pcie_device *srv;
@@ -108,7 +58,7 @@ struct pcie_pme_service_data {
* @dev: PCIe root port or event collector.
* @enable: Enable or disable the interrupt.
*/
-static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
+void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
{
int rtctl_pos;
u16 rtctl;
@@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv)
struct pcie_pme_service_data *data;
int ret;
- if (!pcie_pme_platform_setup(srv))
- return -EACCES;
-
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = {
*/
static int __init pcie_pme_service_init(void)
{
- return pcie_pme_disabled ?
- -ENODEV : pcie_port_service_register(&pcie_pme_driver);
+ return pcie_port_service_register(&pcie_pme_driver);
}
module_init(pcie_pme_service_init);
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile
deleted file mode 100644
index 8b9238053080..000000000000
--- a/drivers/pci/pcie/pme/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for PCI-Express Root Port PME signaling driver
-#
-
-obj-$(CONFIG_PCIE_PME) += pmedriver.o
-
-pmedriver-objs := pcie_pme.o
-pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h
deleted file mode 100644
index b30d2b7c9775..000000000000
--- a/drivers/pci/pcie/pme/pcie_pme.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * drivers/pci/pcie/pme/pcie_pme.h
- *
- * PCI Express Root Port PME signaling support
- *
- * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- */
-
-#ifndef _PCIE_PME_H_
-#define _PCIE_PME_H_
-
-struct pcie_device;
-
-#ifdef CONFIG_ACPI
-extern int pcie_pme_acpi_setup(struct pcie_device *srv);
-
-static inline int pcie_pme_platform_notify(struct pcie_device *srv)
-{
- return pcie_pme_acpi_setup(srv);
-}
-#else /* !CONFIG_ACPI */
-static inline int pcie_pme_platform_notify(struct pcie_device *srv)
-{
- return 0;
-}
-#endif /* !CONFIG_ACPI */
-
-#endif
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c
deleted file mode 100644
index 83ab2287ae3f..000000000000
--- a/drivers/pci/pcie/pme/pcie_pme_acpi.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * PCIe Native PME support, ACPI-related part
- *
- * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License V2. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/acpi.h>
-#include <linux/pci-acpi.h>
-#include <linux/pcieport_if.h>
-
-/**
- * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
- * @srv - PCIe PME service for a root port or event collector.
- *
- * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid
- * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
- * control to the kernel.
- */
-int pcie_pme_acpi_setup(struct pcie_device *srv)
-{
- acpi_status status = AE_NOT_FOUND;
- struct pci_dev *port = srv->port;
- acpi_handle handle;
- int error = 0;
-
- if (acpi_pci_disabled)
- return -ENOSYS;
-
- dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
-
- handle = acpi_find_root_bridge_handle(port);
- if (!handle)
- return -EINVAL;
-
- status = acpi_pci_osc_control_set(handle,
- OSC_PCI_EXPRESS_PME_CONTROL |
- OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
- if (ACPI_FAILURE(status)) {
- dev_info(&port->dev,
- "Failed to receive control of PCIe PME service: %s\n",
- (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
- "no _OSC support" : "ACPI _OSC failed");
- error = -ENODEV;
- }
-
- return error;
-}
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 813a5c3427b6..7b5aba0a3291 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -20,6 +20,9 @@
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
+extern bool pcie_ports_disabled;
+extern bool pcie_ports_auto;
+
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
@@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev);
extern int __must_check pcie_port_bus_register(void);
extern void pcie_port_bus_unregister(void);
+struct pci_dev;
+
#ifdef CONFIG_PCIE_PME
extern bool pcie_pme_msi_disabled;
@@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void)
{
return pcie_pme_msi_disabled;
}
+
+extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);
#else /* !CONFIG_PCIE_PME */
static inline void pcie_pme_disable_msi(void) {}
static inline bool pcie_pme_no_msi(void) { return false; }
+static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
#endif /* !CONFIG_PCIE_PME */
+#ifdef CONFIG_ACPI
+extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask);
+
+static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
+{
+ return pcie_port_acpi_setup(port, mask);
+}
+#else /* !CONFIG_ACPI */
+static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
+{
+ return 0;
+}
+#endif /* !CONFIG_ACPI */
+
#endif /* _PORTDRV_H_ */
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c
new file mode 100644
index 000000000000..b7c4cb1ccb23
--- /dev/null
+++ b/drivers/pci/pcie/portdrv_acpi.c
@@ -0,0 +1,77 @@
+/*
+ * PCIe Port Native Services Support, ACPI-Related Part
+ *
+ * Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License V2. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+#include <linux/pcieport_if.h>
+
+#include "aer/aerdrv.h"
+#include "../pci.h"
+
+/**
+ * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services.
+ * @port: PCIe Port service for a root port or event collector.
+ * @srv_mask: Bit mask of services that can be enabled for @port.
+ *
+ * Invoked when @port is identified as a PCIe port device. To avoid conflicts
+ * with the BIOS PCIe port native services support requires the BIOS to yield
+ * control of these services to the kernel. The mask of services that the BIOS
+ * allows to be enabled for @port is written to @srv_mask.
+ *
+ * NOTE: It turns out that we cannot do that for individual port services
+ * separately, because that would make some systems work incorrectly.
+ */
+int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
+{
+ acpi_status status;
+ acpi_handle handle;
+ u32 flags;
+
+ if (acpi_pci_disabled)
+ return 0;
+
+ handle = acpi_find_root_bridge_handle(port);
+ if (!handle)
+ return -EINVAL;
+
+ flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
+ | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
+ | OSC_PCI_EXPRESS_PME_CONTROL;
+
+ if (pci_aer_available()) {
+ if (pcie_aer_get_firmware_first(port))
+ dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
+ else
+ flags |= OSC_PCI_EXPRESS_AER_CONTROL;
+ }
+
+ status = acpi_pci_osc_control_set(handle, &flags,
+ OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+ if (ACPI_FAILURE(status)) {
+ dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n",
+ status);
+ return -ENODEV;
+ }
+
+ dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags);
+
+ *srv_mask = PCIE_PORT_SERVICE_VC;
+ if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
+ *srv_mask |= PCIE_PORT_SERVICE_HP;
+ if (flags & OSC_PCI_EXPRESS_PME_CONTROL)
+ *srv_mask |= PCIE_PORT_SERVICE_PME;
+ if (flags & OSC_PCI_EXPRESS_AER_CONTROL)
+ *srv_mask |= PCIE_PORT_SERVICE_AER;
+
+ return 0;
+}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e73effbe402c..a9c222d79ebc 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -14,6 +14,8 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pcieport_if.h>
+#include <linux/aer.h>
+#include <linux/pci-aspm.h>
#include "../pci.h"
#include "portdrv.h"
@@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev)
int services = 0, pos;
u16 reg16;
u32 reg32;
+ int cap_mask;
+ int err;
+
+ err = pcie_port_platform_notify(dev, &cap_mask);
+ if (pcie_ports_auto) {
+ if (err) {
+ pcie_no_aspm();
+ return 0;
+ }
+ } else {
+ cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
+ | PCIE_PORT_SERVICE_VC;
+ if (pci_aer_available())
+ cap_mask |= PCIE_PORT_SERVICE_AER;
+ }
pos = pci_pcie_cap(dev);
pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
/* Hot-Plug Capable */
- if (reg16 & PCI_EXP_FLAGS_SLOT) {
+ if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
- if (reg32 & PCI_EXP_SLTCAP_HPC)
+ if (reg32 & PCI_EXP_SLTCAP_HPC) {
services |= PCIE_PORT_SERVICE_HP;
+ /*
+ * Disable hot-plug interrupts in case they have been
+ * enabled by the BIOS and the hot-plug service driver
+ * is not loaded.
+ */
+ pos += PCI_EXP_SLTCTL;
+ pci_read_config_word(dev, pos, &reg16);
+ reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
+ pci_write_config_word(dev, pos, reg16);
+ }
}
/* AER capable */
- if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
+ if ((cap_mask & PCIE_PORT_SERVICE_AER)
+ && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
services |= PCIE_PORT_SERVICE_AER;
+ /*
+ * Disable AER on this port in case it's been enabled by the
+ * BIOS (the AER service driver will enable it when necessary).
+ */
+ pci_disable_pcie_error_reporting(dev);
+ }
/* VC support */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
/* Root ports are capable of generating PME too */
- if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ if ((cap_mask & PCIE_PORT_SERVICE_PME)
+ && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
services |= PCIE_PORT_SERVICE_PME;
+ /*
+ * Disable PME interrupt on this port in case it's been enabled
+ * by the BIOS (the PME service driver will enable it when
+ * necessary).
+ */
+ pcie_pme_interrupt_enable(dev, false);
+ }
return services;
}
@@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {}
*/
int pcie_port_service_register(struct pcie_port_service_driver *new)
{
+ if (pcie_ports_disabled)
+ return -ENODEV;
+
new->driver.name = (char *)new->name;
new->driver.bus = &pcie_port_bus_type;
new->driver.probe = pcie_port_probe_service;
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 3debed25e46b..f9033e190fb6 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -15,6 +15,7 @@
#include <linux/pcieport_if.h>
#include <linux/aer.h>
#include <linux/dmi.h>
+#include <linux/pci-aspm.h>
#include "portdrv.h"
#include "aer/aerdrv.h"
@@ -29,6 +30,31 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+/* If this switch is set, PCIe port native services should not be enabled. */
+bool pcie_ports_disabled;
+
+/*
+ * If this switch is set, ACPI _OSC will be used to determine whether or not to
+ * enable PCIe port native services.
+ */
+bool pcie_ports_auto = true;
+
+static int __init pcie_port_setup(char *str)
+{
+ if (!strncmp(str, "compat", 6)) {
+ pcie_ports_disabled = true;
+ } else if (!strncmp(str, "native", 6)) {
+ pcie_ports_disabled = false;
+ pcie_ports_auto = false;
+ } else if (!strncmp(str, "auto", 4)) {
+ pcie_ports_disabled = false;
+ pcie_ports_auto = true;
+ }
+
+ return 1;
+}
+__setup("pcie_ports=", pcie_port_setup);
+
/* global data */
static int pcie_portdrv_restore_config(struct pci_dev *dev)
@@ -301,6 +327,11 @@ static int __init pcie_portdrv_init(void)
{
int retval;
+ if (pcie_ports_disabled) {
+ pcie_no_aspm();
+ return -EACCES;
+ }
+
dmi_check_system(pcie_portdrv_dmi_table);
retval = pcie_port_bus_register();
@@ -315,11 +346,4 @@ static int __init pcie_portdrv_init(void)
return retval;
}
-static void __exit pcie_portdrv_exit(void)
-{
- pci_unregister_driver(&pcie_portdriver);
- pcie_port_bus_unregister();
-}
-
module_init(pcie_portdrv_init);
-module_exit(pcie_portdrv_exit);
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 659eaa0fc48f..968cfea04f74 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
}
/* these strings match up with the values in pci_bus_speed */
-static char *pci_bus_speed_strings[] = {
+static const char *pci_bus_speed_strings[] = {
"33 MHz PCI", /* 0x00 */
"66 MHz PCI", /* 0x01 */
"66 MHz PCI-X", /* 0x02 */
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cff7cc2c1f02..55579f137b64 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -92,6 +92,7 @@ config DELL_WMI
tristate "Dell WMI extras"
depends on ACPI_WMI
depends on INPUT
+ select INPUT_SPARSEKMAP
---help---
Say Y here if you want to support WMI-based hotkeys on Dell laptops.
@@ -140,6 +141,7 @@ config HP_WMI
depends on ACPI_WMI
depends on INPUT
depends on RFKILL || RFKILL = n
+ select INPUT_SPARSEKMAP
help
Say Y here if you want to support WMI-based hotkeys on HP laptops and
to read data from WMI such as docking or ambient light sensor state.
@@ -171,6 +173,7 @@ config PANASONIC_LAPTOP
tristate "Panasonic Laptop Extras"
depends on INPUT && ACPI
depends on BACKLIGHT_CLASS_DEVICE
+ select INPUT_SPARSEKMAP
---help---
This driver adds support for access to backlight control and hotkeys
on Panasonic Let's Note laptops.
@@ -478,6 +481,7 @@ config TOPSTAR_LAPTOP
tristate "Topstar Laptop Extras"
depends on ACPI
depends on INPUT
+ select INPUT_SPARSEKMAP
---help---
This driver adds support for hotkeys found on Topstar laptops.
@@ -492,6 +496,7 @@ config ACPI_TOSHIBA
depends on INPUT
depends on RFKILL || RFKILL = n
select INPUT_POLLDEV
+ select INPUT_SPARSEKMAP
---help---
This driver adds support for access to certain system settings
on "legacy free" Toshiba laptops. These laptops can be recognized by
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index 08fb70f6d9bf..77f1d55414c6 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <acpi/acpi_drivers.h>
#include <linux/acpi.h>
#include <linux/string.h>
@@ -44,78 +45,70 @@ static int acpi_video;
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
-struct key_entry {
- char type; /* See KE_* below */
- u16 code;
- u16 keycode;
-};
-
-enum { KE_KEY, KE_SW, KE_IGNORE, KE_END };
-
/*
* Certain keys are flagged as KE_IGNORE. All of these are either
* notifications (rather than requests for change) or are also sent
* via the keyboard controller so should not be sent again.
*/
-static struct key_entry dell_legacy_wmi_keymap[] = {
- {KE_KEY, 0xe045, KEY_PROG1},
- {KE_KEY, 0xe009, KEY_EJECTCD},
+static const struct key_entry dell_wmi_legacy_keymap[] __initconst = {
+ { KE_KEY, 0xe045, { KEY_PROG1 } },
+ { KE_KEY, 0xe009, { KEY_EJECTCD } },
/* These also contain the brightness level at offset 6 */
- {KE_KEY, 0xe006, KEY_BRIGHTNESSUP},
- {KE_KEY, 0xe005, KEY_BRIGHTNESSDOWN},
+ { KE_KEY, 0xe006, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0xe005, { KEY_BRIGHTNESSDOWN } },
/* Battery health status button */
- {KE_KEY, 0xe007, KEY_BATTERY},
+ { KE_KEY, 0xe007, { KEY_BATTERY } },
/* This is actually for all radios. Although physically a
* switch, the notification does not provide an indication of
* state and so it should be reported as a key */
- {KE_KEY, 0xe008, KEY_WLAN},
+ { KE_KEY, 0xe008, { KEY_WLAN } },
/* The next device is at offset 6, the active devices are at
offset 8 and the attached devices at offset 10 */
- {KE_KEY, 0xe00b, KEY_SWITCHVIDEOMODE},
+ { KE_KEY, 0xe00b, { KEY_SWITCHVIDEOMODE } },
- {KE_IGNORE, 0xe00c, KEY_KBDILLUMTOGGLE},
+ { KE_IGNORE, 0xe00c, { KEY_KBDILLUMTOGGLE } },
/* BIOS error detected */
- {KE_IGNORE, 0xe00d, KEY_RESERVED},
+ { KE_IGNORE, 0xe00d, { KEY_RESERVED } },
/* Wifi Catcher */
- {KE_KEY, 0xe011, KEY_PROG2},
+ { KE_KEY, 0xe011, {KEY_PROG2 } },
/* Ambient light sensor toggle */
- {KE_IGNORE, 0xe013, KEY_RESERVED},
-
- {KE_IGNORE, 0xe020, KEY_MUTE},
- {KE_IGNORE, 0xe02e, KEY_VOLUMEDOWN},
- {KE_IGNORE, 0xe030, KEY_VOLUMEUP},
- {KE_IGNORE, 0xe033, KEY_KBDILLUMUP},
- {KE_IGNORE, 0xe034, KEY_KBDILLUMDOWN},
- {KE_IGNORE, 0xe03a, KEY_CAPSLOCK},
- {KE_IGNORE, 0xe045, KEY_NUMLOCK},
- {KE_IGNORE, 0xe046, KEY_SCROLLLOCK},
- {KE_END, 0}
+ { KE_IGNORE, 0xe013, { KEY_RESERVED } },
+
+ { KE_IGNORE, 0xe020, { KEY_MUTE } },
+ { KE_IGNORE, 0xe02e, { KEY_VOLUMEDOWN } },
+ { KE_IGNORE, 0xe030, { KEY_VOLUMEUP } },
+ { KE_IGNORE, 0xe033, { KEY_KBDILLUMUP } },
+ { KE_IGNORE, 0xe034, { KEY_KBDILLUMDOWN } },
+ { KE_IGNORE, 0xe03a, { KEY_CAPSLOCK } },
+ { KE_IGNORE, 0xe045, { KEY_NUMLOCK } },
+ { KE_IGNORE, 0xe046, { KEY_SCROLLLOCK } },
+ { KE_END, 0 }
};
static bool dell_new_hk_type;
-struct dell_new_keymap_entry {
+struct dell_bios_keymap_entry {
u16 scancode;
u16 keycode;
};
-struct dell_hotkey_table {
+struct dell_bios_hotkey_table {
struct dmi_header header;
- struct dell_new_keymap_entry keymap[];
+ struct dell_bios_keymap_entry keymap[];
};
-static struct key_entry *dell_new_wmi_keymap;
+static const struct dell_bios_hotkey_table *dell_bios_hotkey_table;
-static u16 bios_to_linux_keycode[256] = {
+static const u16 bios_to_linux_keycode[256] __initconst = {
KEY_MEDIA, KEY_NEXTSONG, KEY_PLAYPAUSE, KEY_PREVIOUSSONG,
KEY_STOPCD, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
@@ -138,68 +131,11 @@ static u16 bios_to_linux_keycode[256] = {
KEY_PROG3
};
-
-static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap;
-
static struct input_dev *dell_wmi_input_dev;
-static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code)
-{
- struct key_entry *key;
-
- for (key = dell_wmi_keymap; key->type != KE_END; key++)
- if (code == key->code)
- return key;
-
- return NULL;
-}
-
-static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode)
-{
- struct key_entry *key;
-
- for (key = dell_wmi_keymap; key->type != KE_END; key++)
- if (key->type == KE_KEY && keycode == key->keycode)
- return key;
-
- return NULL;
-}
-
-static int dell_wmi_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
-
- if (key && key->type == KE_KEY) {
- *keycode = key->keycode;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int dell_wmi_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct key_entry *key;
- unsigned int old_keycode;
-
- key = dell_wmi_get_entry_by_scancode(scancode);
- if (key && key->type == KE_KEY) {
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!dell_wmi_get_entry_by_keycode(old_keycode))
- clear_bit(old_keycode, dev->keybit);
- return 0;
- }
- return -EINVAL;
-}
-
static void dell_wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
- static struct key_entry *key;
union acpi_object *obj;
acpi_status status;
@@ -212,8 +148,10 @@ static void dell_wmi_notify(u32 value, void *context)
obj = (union acpi_object *)response.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER) {
+ const struct key_entry *key;
int reported_key;
u16 *buffer_entry = (u16 *)obj->buffer.pointer;
+
if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
printk(KERN_INFO "dell-wmi: Received unknown WMI event"
" (0x%x)\n", buffer_entry[1]);
@@ -226,8 +164,8 @@ static void dell_wmi_notify(u32 value, void *context)
else
reported_key = (int)buffer_entry[1] & 0xffff;
- key = dell_wmi_get_entry_by_scancode(reported_key);
-
+ key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
+ reported_key);
if (!key) {
printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
reported_key);
@@ -237,92 +175,98 @@ static void dell_wmi_notify(u32 value, void *context)
* come via ACPI */
;
} else {
- input_report_key(dell_wmi_input_dev, key->keycode, 1);
- input_sync(dell_wmi_input_dev);
- input_report_key(dell_wmi_input_dev, key->keycode, 0);
- input_sync(dell_wmi_input_dev);
+ sparse_keymap_report_entry(dell_wmi_input_dev, key,
+ 1, true);
}
}
kfree(obj);
}
-
-static void setup_new_hk_map(const struct dmi_header *dm)
+static const struct key_entry * __init dell_wmi_prepare_new_keymap(void)
{
-
+ int hotkey_num = (dell_bios_hotkey_table->header.length - 4) /
+ sizeof(struct dell_bios_keymap_entry);
+ struct key_entry *keymap;
int i;
- int hotkey_num = (dm->length-4)/sizeof(struct dell_new_keymap_entry);
- struct dell_hotkey_table *table =
- container_of(dm, struct dell_hotkey_table, header);
- dell_new_wmi_keymap = kzalloc((hotkey_num+1) *
- sizeof(struct key_entry), GFP_KERNEL);
+ keymap = kcalloc(hotkey_num + 1, sizeof(struct key_entry), GFP_KERNEL);
+ if (!keymap)
+ return NULL;
for (i = 0; i < hotkey_num; i++) {
- dell_new_wmi_keymap[i].type = KE_KEY;
- dell_new_wmi_keymap[i].code = table->keymap[i].scancode;
- dell_new_wmi_keymap[i].keycode =
- (table->keymap[i].keycode > 255) ? 0 :
- bios_to_linux_keycode[table->keymap[i].keycode];
+ const struct dell_bios_keymap_entry *bios_entry =
+ &dell_bios_hotkey_table->keymap[i];
+ keymap[i].type = KE_KEY;
+ keymap[i].code = bios_entry->scancode;
+ keymap[i].keycode = bios_entry->keycode < 256 ?
+ bios_to_linux_keycode[bios_entry->keycode] :
+ KEY_RESERVED;
}
- dell_new_wmi_keymap[i].type = KE_END;
- dell_new_wmi_keymap[i].code = 0;
- dell_new_wmi_keymap[i].keycode = 0;
-
- dell_wmi_keymap = dell_new_wmi_keymap;
+ keymap[hotkey_num].type = KE_END;
+ return keymap;
}
-
-static void find_hk_type(const struct dmi_header *dm, void *dummy)
-{
-
- if ((dm->type == 0xb2) && (dm->length > 6)) {
- dell_new_hk_type = true;
- setup_new_hk_map(dm);
- }
-
-}
-
-
static int __init dell_wmi_input_setup(void)
{
- struct key_entry *key;
int err;
dell_wmi_input_dev = input_allocate_device();
-
if (!dell_wmi_input_dev)
return -ENOMEM;
dell_wmi_input_dev->name = "Dell WMI hotkeys";
dell_wmi_input_dev->phys = "wmi/input0";
dell_wmi_input_dev->id.bustype = BUS_HOST;
- dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
- dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
-
- for (key = dell_wmi_keymap; key->type != KE_END; key++) {
- switch (key->type) {
- case KE_KEY:
- set_bit(EV_KEY, dell_wmi_input_dev->evbit);
- set_bit(key->keycode, dell_wmi_input_dev->keybit);
- break;
- case KE_SW:
- set_bit(EV_SW, dell_wmi_input_dev->evbit);
- set_bit(key->keycode, dell_wmi_input_dev->swbit);
- break;
+
+ if (dell_new_hk_type) {
+ const struct key_entry *keymap = dell_wmi_prepare_new_keymap();
+ if (!keymap) {
+ err = -ENOMEM;
+ goto err_free_dev;
}
- }
- err = input_register_device(dell_wmi_input_dev);
+ err = sparse_keymap_setup(dell_wmi_input_dev, keymap, NULL);
- if (err) {
- input_free_device(dell_wmi_input_dev);
- return err;
+ /*
+ * Sparse keymap library makes a copy of keymap so we
+ * don't need the original one that was allocated.
+ */
+ kfree(keymap);
+ } else {
+ err = sparse_keymap_setup(dell_wmi_input_dev,
+ dell_wmi_legacy_keymap, NULL);
}
+ if (err)
+ goto err_free_dev;
+
+ err = input_register_device(dell_wmi_input_dev);
+ if (err)
+ goto err_free_keymap;
return 0;
+
+ err_free_keymap:
+ sparse_keymap_free(dell_wmi_input_dev);
+ err_free_dev:
+ input_free_device(dell_wmi_input_dev);
+ return err;
+}
+
+static void dell_wmi_input_destroy(void)
+{
+ sparse_keymap_free(dell_wmi_input_dev);
+ input_unregister_device(dell_wmi_input_dev);
+}
+
+static void __init find_hk_type(const struct dmi_header *dm, void *dummy)
+{
+ if (dm->type == 0xb2 && dm->length > 6) {
+ dell_new_hk_type = true;
+ dell_bios_hotkey_table =
+ container_of(dm, struct dell_bios_hotkey_table, header);
+ }
}
static int __init dell_wmi_init(void)
@@ -339,18 +283,13 @@ static int __init dell_wmi_init(void)
acpi_video = acpi_video_backlight_support();
err = dell_wmi_input_setup();
- if (err) {
- if (dell_new_hk_type)
- kfree(dell_wmi_keymap);
+ if (err)
return err;
- }
status = wmi_install_notify_handler(DELL_EVENT_GUID,
dell_wmi_notify, NULL);
if (ACPI_FAILURE(status)) {
- input_unregister_device(dell_wmi_input_dev);
- if (dell_new_hk_type)
- kfree(dell_wmi_keymap);
+ dell_wmi_input_destroy();
printk(KERN_ERR
"dell-wmi: Unable to register notify handler - %d\n",
status);
@@ -359,14 +298,11 @@ static int __init dell_wmi_init(void)
return 0;
}
+module_init(dell_wmi_init);
static void __exit dell_wmi_exit(void)
{
wmi_remove_notify_handler(DELL_EVENT_GUID);
- input_unregister_device(dell_wmi_input_dev);
- if (dell_new_hk_type)
- kfree(dell_wmi_keymap);
+ dell_wmi_input_destroy();
}
-
-module_init(dell_wmi_init);
module_exit(dell_wmi_exit);
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index c1741142a4cb..1dac659b5e0c 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -29,6 +29,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/rfkill.h>
@@ -88,24 +89,16 @@ struct bios_return {
u32 value;
};
-struct key_entry {
- char type; /* See KE_* below */
- u16 code;
- u16 keycode;
-};
-
-enum { KE_KEY, KE_END };
-
-static struct key_entry hp_wmi_keymap[] = {
- {KE_KEY, 0x02, KEY_BRIGHTNESSUP},
- {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN},
- {KE_KEY, 0x20e6, KEY_PROG1},
- {KE_KEY, 0x20e8, KEY_MEDIA},
- {KE_KEY, 0x2142, KEY_MEDIA},
- {KE_KEY, 0x213b, KEY_INFO},
- {KE_KEY, 0x2169, KEY_DIRECTION},
- {KE_KEY, 0x231b, KEY_HELP},
- {KE_END, 0}
+static const struct key_entry hp_wmi_keymap[] = {
+ { KE_KEY, 0x02, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 0x20e6, { KEY_PROG1 } },
+ { KE_KEY, 0x20e8, { KEY_MEDIA } },
+ { KE_KEY, 0x2142, { KEY_MEDIA } },
+ { KE_KEY, 0x213b, { KEY_INFO } },
+ { KE_KEY, 0x2169, { KEY_DIRECTION } },
+ { KE_KEY, 0x231b, { KEY_HELP } },
+ { KE_END, 0 }
};
static struct input_dev *hp_wmi_input_dev;
@@ -347,64 +340,9 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
-static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code)
-{
- struct key_entry *key;
-
- for (key = hp_wmi_keymap; key->type != KE_END; key++)
- if (code == key->code)
- return key;
-
- return NULL;
-}
-
-static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode)
-{
- struct key_entry *key;
-
- for (key = hp_wmi_keymap; key->type != KE_END; key++)
- if (key->type == KE_KEY && keycode == key->keycode)
- return key;
-
- return NULL;
-}
-
-static int hp_wmi_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode);
-
- if (key && key->type == KE_KEY) {
- *keycode = key->keycode;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int hp_wmi_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct key_entry *key;
- unsigned int old_keycode;
-
- key = hp_wmi_get_entry_by_scancode(scancode);
- if (key && key->type == KE_KEY) {
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!hp_wmi_get_entry_by_keycode(old_keycode))
- clear_bit(old_keycode, dev->keybit);
- return 0;
- }
-
- return -EINVAL;
-}
-
static void hp_wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
- static struct key_entry *key;
union acpi_object *obj;
u32 event_id, event_data;
int key_code = 0, ret;
@@ -465,19 +403,9 @@ static void hp_wmi_notify(u32 value, void *context)
sizeof(key_code));
if (ret)
break;
- key = hp_wmi_get_entry_by_scancode(key_code);
- if (key) {
- switch (key->type) {
- case KE_KEY:
- input_report_key(hp_wmi_input_dev,
- key->keycode, 1);
- input_sync(hp_wmi_input_dev);
- input_report_key(hp_wmi_input_dev,
- key->keycode, 0);
- input_sync(hp_wmi_input_dev);
- break;
- }
- } else
+
+ if (!sparse_keymap_report_event(hp_wmi_input_dev,
+ key_code, 1, true))
printk(KERN_INFO PREFIX "Unknown key code - 0x%x\n",
key_code);
break;
@@ -510,7 +438,7 @@ static void hp_wmi_notify(u32 value, void *context)
static int __init hp_wmi_input_setup(void)
{
- struct key_entry *key;
+ acpi_status status;
int err;
hp_wmi_input_dev = input_allocate_device();
@@ -520,21 +448,14 @@ static int __init hp_wmi_input_setup(void)
hp_wmi_input_dev->name = "HP WMI hotkeys";
hp_wmi_input_dev->phys = "wmi/input0";
hp_wmi_input_dev->id.bustype = BUS_HOST;
- hp_wmi_input_dev->getkeycode = hp_wmi_getkeycode;
- hp_wmi_input_dev->setkeycode = hp_wmi_setkeycode;
-
- for (key = hp_wmi_keymap; key->type != KE_END; key++) {
- switch (key->type) {
- case KE_KEY:
- set_bit(EV_KEY, hp_wmi_input_dev->evbit);
- set_bit(key->keycode, hp_wmi_input_dev->keybit);
- break;
- }
- }
- set_bit(EV_SW, hp_wmi_input_dev->evbit);
- set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
- set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+ __set_bit(EV_SW, hp_wmi_input_dev->evbit);
+ __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
+ __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
+
+ err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
/* Set initial hardware state */
input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state());
@@ -542,14 +463,32 @@ static int __init hp_wmi_input_setup(void)
hp_wmi_tablet_state());
input_sync(hp_wmi_input_dev);
- err = input_register_device(hp_wmi_input_dev);
-
- if (err) {
- input_free_device(hp_wmi_input_dev);
- return err;
+ status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ err = -EIO;
+ goto err_free_keymap;
}
+ err = input_register_device(hp_wmi_input_dev);
+ if (err)
+ goto err_uninstall_notifier;
+
return 0;
+
+ err_uninstall_notifier:
+ wmi_remove_notify_handler(HPWMI_EVENT_GUID);
+ err_free_keymap:
+ sparse_keymap_free(hp_wmi_input_dev);
+ err_free_dev:
+ input_free_device(hp_wmi_input_dev);
+ return err;
+}
+
+static void hp_wmi_input_destroy(void)
+{
+ wmi_remove_notify_handler(HPWMI_EVENT_GUID);
+ sparse_keymap_free(hp_wmi_input_dev);
+ input_unregister_device(hp_wmi_input_dev);
}
static void cleanup_sysfs(struct platform_device *device)
@@ -704,15 +643,9 @@ static int __init hp_wmi_init(void)
int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
if (event_capable) {
- err = wmi_install_notify_handler(HPWMI_EVENT_GUID,
- hp_wmi_notify, NULL);
- if (ACPI_FAILURE(err))
- return -EINVAL;
err = hp_wmi_input_setup();
- if (err) {
- wmi_remove_notify_handler(HPWMI_EVENT_GUID);
+ if (err)
return err;
- }
}
if (bios_capable) {
@@ -739,20 +672,17 @@ err_device_add:
err_device_alloc:
platform_driver_unregister(&hp_wmi_driver);
err_driver_reg:
- if (wmi_has_guid(HPWMI_EVENT_GUID)) {
- input_unregister_device(hp_wmi_input_dev);
- wmi_remove_notify_handler(HPWMI_EVENT_GUID);
- }
+ if (event_capable)
+ hp_wmi_input_destroy();
return err;
}
static void __exit hp_wmi_exit(void)
{
- if (wmi_has_guid(HPWMI_EVENT_GUID)) {
- wmi_remove_notify_handler(HPWMI_EVENT_GUID);
- input_unregister_device(hp_wmi_input_dev);
- }
+ if (wmi_has_guid(HPWMI_EVENT_GUID))
+ hp_wmi_input_destroy();
+
if (hp_wmi_platform_dev) {
platform_device_unregister(hp_wmi_platform_dev);
platform_driver_unregister(&hp_wmi_driver);
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index ec01c3d8fc5a..b3b9e0458ae1 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -128,6 +128,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#ifndef ACPI_HOTKEY_COMPONENT
@@ -200,30 +201,29 @@ static struct acpi_driver acpi_pcc_driver = {
},
};
-#define KEYMAP_SIZE 11
-static const unsigned int initial_keymap[KEYMAP_SIZE] = {
- /* 0 */ KEY_RESERVED,
- /* 1 */ KEY_BRIGHTNESSDOWN,
- /* 2 */ KEY_BRIGHTNESSUP,
- /* 3 */ KEY_DISPLAYTOGGLE,
- /* 4 */ KEY_MUTE,
- /* 5 */ KEY_VOLUMEDOWN,
- /* 6 */ KEY_VOLUMEUP,
- /* 7 */ KEY_SLEEP,
- /* 8 */ KEY_PROG1, /* Change CPU boost */
- /* 9 */ KEY_BATTERY,
- /* 10 */ KEY_SUSPEND,
+static const struct key_entry panasonic_keymap[] = {
+ { KE_KEY, 0, { KEY_RESERVED } },
+ { KE_KEY, 1, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 2, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 3, { KEY_DISPLAYTOGGLE } },
+ { KE_KEY, 4, { KEY_MUTE } },
+ { KE_KEY, 5, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 6, { KEY_VOLUMEUP } },
+ { KE_KEY, 7, { KEY_SLEEP } },
+ { KE_KEY, 8, { KEY_PROG1 } }, /* Change CPU boost */
+ { KE_KEY, 9, { KEY_BATTERY } },
+ { KE_KEY, 10, { KEY_SUSPEND } },
+ { KE_END, 0 }
};
struct pcc_acpi {
acpi_handle handle;
unsigned long num_sifr;
int sticky_mode;
- u32 *sinf;
+ u32 *sinf;
struct acpi_device *device;
struct input_dev *input_dev;
struct backlight_device *backlight;
- unsigned int keymap[KEYMAP_SIZE];
};
struct pcc_keyinput {
@@ -446,56 +446,10 @@ static struct attribute_group pcc_attr_group = {
/* hotkey input device driver */
-static int pcc_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct pcc_acpi *pcc = input_get_drvdata(dev);
-
- if (scancode >= ARRAY_SIZE(pcc->keymap))
- return -EINVAL;
-
- *keycode = pcc->keymap[scancode];
-
- return 0;
-}
-
-static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) {
- if (pcc->keymap[i] == keycode)
- return i+1;
- }
-
- return 0;
-}
-
-static int pcc_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct pcc_acpi *pcc = input_get_drvdata(dev);
- int oldkeycode;
-
- if (scancode >= ARRAY_SIZE(pcc->keymap))
- return -EINVAL;
-
- oldkeycode = pcc->keymap[scancode];
- pcc->keymap[scancode] = keycode;
-
- set_bit(keycode, dev->keybit);
-
- if (!keymap_get_by_keycode(pcc, oldkeycode))
- clear_bit(oldkeycode, dev->keybit);
-
- return 0;
-}
-
static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
{
struct input_dev *hotk_input_dev = pcc->input_dev;
int rc;
- int key_code, hkey_num;
unsigned long long result;
rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
@@ -508,25 +462,10 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result);
- hkey_num = result & 0xf;
-
- if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
+ if (!sparse_keymap_report_event(hotk_input_dev,
+ result & 0xf, result & 0x80, false))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "hotkey number out of range: %d\n",
- hkey_num));
- return;
- }
-
- key_code = pcc->keymap[hkey_num];
-
- if (key_code != KEY_RESERVED) {
- int pushed = (result & 0x80) ? TRUE : FALSE;
-
- input_report_key(hotk_input_dev, key_code, pushed);
- input_sync(hotk_input_dev);
- }
-
- return;
+ "Unknown hotkey event: %d\n", result));
}
static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
@@ -545,40 +484,55 @@ static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
static int acpi_pcc_init_input(struct pcc_acpi *pcc)
{
- int i, rc;
+ struct input_dev *input_dev;
+ int error;
- pcc->input_dev = input_allocate_device();
- if (!pcc->input_dev) {
+ input_dev = input_allocate_device();
+ if (!input_dev) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Couldn't allocate input device for hotkey"));
return -ENOMEM;
}
- pcc->input_dev->evbit[0] = BIT(EV_KEY);
-
- pcc->input_dev->name = ACPI_PCC_DRIVER_NAME;
- pcc->input_dev->phys = ACPI_PCC_INPUT_PHYS;
- pcc->input_dev->id.bustype = BUS_HOST;
- pcc->input_dev->id.vendor = 0x0001;
- pcc->input_dev->id.product = 0x0001;
- pcc->input_dev->id.version = 0x0100;
- pcc->input_dev->getkeycode = pcc_getkeycode;
- pcc->input_dev->setkeycode = pcc_setkeycode;
+ input_dev->name = ACPI_PCC_DRIVER_NAME;
+ input_dev->phys = ACPI_PCC_INPUT_PHYS;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0001;
+ input_dev->id.version = 0x0100;
- /* load initial keymap */
- memcpy(pcc->keymap, initial_keymap, sizeof(pcc->keymap));
+ error = sparse_keymap_setup(input_dev, panasonic_keymap, NULL);
+ if (error) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to setup input device keymap\n"));
+ goto err_free_dev;
+ }
- for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++)
- __set_bit(pcc->keymap[i], pcc->input_dev->keybit);
- __clear_bit(KEY_RESERVED, pcc->input_dev->keybit);
+ error = input_register_device(input_dev);
+ if (error) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Unable to register input device\n"));
+ goto err_free_keymap;
+ }
- input_set_drvdata(pcc->input_dev, pcc);
+ pcc->input_dev = input_dev;
+ return 0;
- rc = input_register_device(pcc->input_dev);
- if (rc < 0)
- input_free_device(pcc->input_dev);
+ err_free_keymap:
+ sparse_keymap_free(input_dev);
+ err_free_dev:
+ input_free_device(input_dev);
+ return error;
+}
- return rc;
+static void acpi_pcc_destroy_input(struct pcc_acpi *pcc)
+{
+ sparse_keymap_free(pcc->input_dev);
+ input_unregister_device(pcc->input_dev);
+ /*
+ * No need to input_free_device() since core input API refcounts
+ * and free()s the device.
+ */
}
/* kernel module interface */
@@ -636,7 +590,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error installing keyinput handler\n"));
- goto out_hotkey;
+ goto out_sinf;
}
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
@@ -651,7 +605,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
&pcc_backlight_ops, &props);
if (IS_ERR(pcc->backlight)) {
result = PTR_ERR(pcc->backlight);
- goto out_sinf;
+ goto out_input;
}
/* read the initial brightness setting from the hardware */
@@ -669,12 +623,10 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
out_backlight:
backlight_device_unregister(pcc->backlight);
+out_input:
+ acpi_pcc_destroy_input(pcc);
out_sinf:
kfree(pcc->sinf);
-out_input:
- input_unregister_device(pcc->input_dev);
- /* no need to input_free_device() since core input API refcount and
- * free()s the device */
out_hotkey:
kfree(pcc);
@@ -709,9 +661,7 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
backlight_device_unregister(pcc->backlight);
- input_unregister_device(pcc->input_dev);
- /* no need to input_free_device() since core input API refcount and
- * free()s the device */
+ acpi_pcc_destroy_input(pcc);
kfree(pcc->sinf);
kfree(pcc);
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index e3154ff7a39f..a61497494d47 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2360,6 +2360,7 @@ static const struct file_operations sonypi_misc_fops = {
.release = sonypi_misc_release,
.fasync = sonypi_misc_fasync,
.unlocked_ioctl = sonypi_misc_ioctl,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice sonypi_misc_device = {
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c
index ff4b476f1950..1d07d6d09f27 100644
--- a/drivers/platform/x86/topstar-laptop.c
+++ b/drivers/platform/x86/topstar-laptop.c
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#define ACPI_TOPSTAR_CLASS "topstar"
@@ -26,52 +27,37 @@ struct topstar_hkey {
struct input_dev *inputdev;
};
-struct tps_key_entry {
- u8 code;
- u16 keycode;
-};
-
-static struct tps_key_entry topstar_keymap[] = {
- { 0x80, KEY_BRIGHTNESSUP },
- { 0x81, KEY_BRIGHTNESSDOWN },
- { 0x83, KEY_VOLUMEUP },
- { 0x84, KEY_VOLUMEDOWN },
- { 0x85, KEY_MUTE },
- { 0x86, KEY_SWITCHVIDEOMODE },
- { 0x87, KEY_F13 }, /* touchpad enable/disable key */
- { 0x88, KEY_WLAN },
- { 0x8a, KEY_WWW },
- { 0x8b, KEY_MAIL },
- { 0x8c, KEY_MEDIA },
- { 0x96, KEY_F14 }, /* G key? */
- { }
-};
-
-static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code)
-{
- struct tps_key_entry *key;
-
- for (key = topstar_keymap; key->code; key++)
- if (code == key->code)
- return key;
+static const struct key_entry topstar_keymap[] = {
+ { KE_KEY, 0x80, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 0x83, { KEY_VOLUMEUP } },
+ { KE_KEY, 0x84, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 0x85, { KEY_MUTE } },
+ { KE_KEY, 0x86, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x87, { KEY_F13 } }, /* touchpad enable/disable key */
+ { KE_KEY, 0x88, { KEY_WLAN } },
+ { KE_KEY, 0x8a, { KEY_WWW } },
+ { KE_KEY, 0x8b, { KEY_MAIL } },
+ { KE_KEY, 0x8c, { KEY_MEDIA } },
- return NULL;
-}
-
-static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code)
-{
- struct tps_key_entry *key;
+ /* Known non hotkey events don't handled or that we don't care yet */
+ { KE_IGNORE, 0x8e, },
+ { KE_IGNORE, 0x8f, },
+ { KE_IGNORE, 0x90, },
- for (key = topstar_keymap; key->code; key++)
- if (code == key->keycode)
- return key;
+ /*
+ * 'G key' generate two event codes, convert to only
+ * one event/key code for now, consider replacing by
+ * a switch (3G switch - SW_3G?)
+ */
+ { KE_KEY, 0x96, { KEY_F14 } },
+ { KE_KEY, 0x97, { KEY_F14 } },
- return NULL;
-}
+ { KE_END, 0 }
+};
static void acpi_topstar_notify(struct acpi_device *device, u32 event)
{
- struct tps_key_entry *key;
static bool dup_evnt[2];
bool *dup;
struct topstar_hkey *hkey = acpi_driver_data(device);
@@ -86,27 +72,8 @@ static void acpi_topstar_notify(struct acpi_device *device, u32 event)
*dup = true;
}
- /*
- * 'G key' generate two event codes, convert to only
- * one event/key code for now (3G switch?)
- */
- if (event == 0x97)
- event = 0x96;
-
- key = tps_get_key_by_scancode(event);
- if (key) {
- input_report_key(hkey->inputdev, key->keycode, 1);
- input_sync(hkey->inputdev);
- input_report_key(hkey->inputdev, key->keycode, 0);
- input_sync(hkey->inputdev);
- return;
- }
-
- /* Known non hotkey events don't handled or that we don't care yet */
- if (event == 0x8e || event == 0x8f || event == 0x90)
- return;
-
- pr_info("unknown event = 0x%02x\n", event);
+ if (!sparse_keymap_report_event(hkey->inputdev, event, 1, true))
+ pr_info("unknown event = 0x%02x\n", event);
}
static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
@@ -127,62 +94,41 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
return 0;
}
-static int topstar_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
-
- if (!key)
- return -EINVAL;
-
- *keycode = key->keycode;
- return 0;
-}
-
-static int topstar_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct tps_key_entry *key;
- int old_keycode;
-
- key = tps_get_key_by_scancode(scancode);
-
- if (!key)
- return -EINVAL;
-
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!tps_get_key_by_keycode(old_keycode))
- clear_bit(old_keycode, dev->keybit);
- return 0;
-}
-
static int acpi_topstar_init_hkey(struct topstar_hkey *hkey)
{
- struct tps_key_entry *key;
+ struct input_dev *input;
+ int error;
- hkey->inputdev = input_allocate_device();
- if (!hkey->inputdev) {
+ input = input_allocate_device();
+ if (!input) {
pr_err("Unable to allocate input device\n");
- return -ENODEV;
+ return -ENOMEM;
}
- hkey->inputdev->name = "Topstar Laptop extra buttons";
- hkey->inputdev->phys = "topstar/input0";
- hkey->inputdev->id.bustype = BUS_HOST;
- hkey->inputdev->getkeycode = topstar_getkeycode;
- hkey->inputdev->setkeycode = topstar_setkeycode;
- for (key = topstar_keymap; key->code; key++) {
- set_bit(EV_KEY, hkey->inputdev->evbit);
- set_bit(key->keycode, hkey->inputdev->keybit);
+
+ input->name = "Topstar Laptop extra buttons";
+ input->phys = "topstar/input0";
+ input->id.bustype = BUS_HOST;
+
+ error = sparse_keymap_setup(input, topstar_keymap, NULL);
+ if (error) {
+ pr_err("Unable to setup input device keymap\n");
+ goto err_free_dev;
}
- if (input_register_device(hkey->inputdev)) {
+
+ error = input_register_device(input);
+ if (error) {
pr_err("Unable to register input device\n");
- input_free_device(hkey->inputdev);
- return -ENODEV;
+ goto err_free_keymap;
}
+ hkey->inputdev = input;
return 0;
+
+ err_free_keymap:
+ sparse_keymap_free(input);
+ err_free_dev:
+ input_free_device(input);
+ return error;
}
static int acpi_topstar_add(struct acpi_device *device)
@@ -216,6 +162,7 @@ static int acpi_topstar_remove(struct acpi_device *device, int type)
acpi_topstar_fncx_switch(device, false);
+ sparse_keymap_free(tps_hkey->inputdev);
input_unregister_device(tps_hkey->inputdev);
kfree(tps_hkey);
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 7d67a45bb2b0..06f304f46e02 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -48,6 +48,7 @@
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <linux/leds.h>
#include <linux/slab.h>
@@ -121,36 +122,28 @@ static const struct acpi_device_id toshiba_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
-struct key_entry {
- char type;
- u16 code;
- u16 keycode;
-};
-
-enum {KE_KEY, KE_END};
-
-static struct key_entry toshiba_acpi_keymap[] = {
- {KE_KEY, 0x101, KEY_MUTE},
- {KE_KEY, 0x102, KEY_ZOOMOUT},
- {KE_KEY, 0x103, KEY_ZOOMIN},
- {KE_KEY, 0x13b, KEY_COFFEE},
- {KE_KEY, 0x13c, KEY_BATTERY},
- {KE_KEY, 0x13d, KEY_SLEEP},
- {KE_KEY, 0x13e, KEY_SUSPEND},
- {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE},
- {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN},
- {KE_KEY, 0x141, KEY_BRIGHTNESSUP},
- {KE_KEY, 0x142, KEY_WLAN},
- {KE_KEY, 0x143, KEY_PROG1},
- {KE_KEY, 0xb05, KEY_PROG2},
- {KE_KEY, 0xb06, KEY_WWW},
- {KE_KEY, 0xb07, KEY_MAIL},
- {KE_KEY, 0xb30, KEY_STOP},
- {KE_KEY, 0xb31, KEY_PREVIOUSSONG},
- {KE_KEY, 0xb32, KEY_NEXTSONG},
- {KE_KEY, 0xb33, KEY_PLAYPAUSE},
- {KE_KEY, 0xb5a, KEY_MEDIA},
- {KE_END, 0, 0},
+static const struct key_entry toshiba_acpi_keymap[] __initconst = {
+ { KE_KEY, 0x101, { KEY_MUTE } },
+ { KE_KEY, 0x102, { KEY_ZOOMOUT } },
+ { KE_KEY, 0x103, { KEY_ZOOMIN } },
+ { KE_KEY, 0x13b, { KEY_COFFEE } },
+ { KE_KEY, 0x13c, { KEY_BATTERY } },
+ { KE_KEY, 0x13d, { KEY_SLEEP } },
+ { KE_KEY, 0x13e, { KEY_SUSPEND } },
+ { KE_KEY, 0x13f, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } },
+ { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0x142, { KEY_WLAN } },
+ { KE_KEY, 0x143, { KEY_PROG1 } },
+ { KE_KEY, 0xb05, { KEY_PROG2 } },
+ { KE_KEY, 0xb06, { KEY_WWW } },
+ { KE_KEY, 0xb07, { KEY_MAIL } },
+ { KE_KEY, 0xb30, { KEY_STOP } },
+ { KE_KEY, 0xb31, { KEY_PREVIOUSSONG } },
+ { KE_KEY, 0xb32, { KEY_NEXTSONG } },
+ { KE_KEY, 0xb33, { KEY_PLAYPAUSE } },
+ { KE_KEY, 0xb5a, { KEY_MEDIA } },
+ { KE_END, 0 },
};
/* utility
@@ -852,64 +845,9 @@ static struct backlight_ops toshiba_backlight_data = {
.update_status = set_lcd_status,
};
-static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
-{
- struct key_entry *key;
-
- for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
- if (code == key->code)
- return key;
-
- return NULL;
-}
-
-static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
-{
- struct key_entry *key;
-
- for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
- if (code == key->keycode && key->type == KE_KEY)
- return key;
-
- return NULL;
-}
-
-static int toshiba_acpi_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
-
- if (key && key->type == KE_KEY) {
- *keycode = key->keycode;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int toshiba_acpi_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct key_entry *key;
- unsigned int old_keycode;
-
- key = toshiba_acpi_get_entry_by_scancode(scancode);
- if (key && key->type == KE_KEY) {
- old_keycode = key->keycode;
- key->keycode = keycode;
- set_bit(keycode, dev->keybit);
- if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
- clear_bit(old_keycode, dev->keybit);
- return 0;
- }
-
- return -EINVAL;
-}
-
static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
{
u32 hci_result, value;
- struct key_entry *key;
if (event != 0x80)
return;
@@ -922,19 +860,11 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
if (value & 0x80)
continue;
- key = toshiba_acpi_get_entry_by_scancode
- (value);
- if (!key) {
+ if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev,
+ value, 1, true)) {
printk(MY_INFO "Unknown key %x\n",
value);
- continue;
}
- input_report_key(toshiba_acpi.hotkey_dev,
- key->keycode, 1);
- input_sync(toshiba_acpi.hotkey_dev);
- input_report_key(toshiba_acpi.hotkey_dev,
- key->keycode, 0);
- input_sync(toshiba_acpi.hotkey_dev);
} else if (hci_result == HCI_NOT_SUPPORTED) {
/* This is a workaround for an unresolved issue on
* some machines where system events sporadically
@@ -945,34 +875,17 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
} while (hci_result != HCI_EMPTY);
}
-static int toshiba_acpi_setup_keyboard(char *device)
+static int __init toshiba_acpi_setup_keyboard(char *device)
{
acpi_status status;
- acpi_handle handle;
- int result;
- const struct key_entry *key;
+ int error;
- status = acpi_get_handle(NULL, device, &handle);
+ status = acpi_get_handle(NULL, device, &toshiba_acpi.handle);
if (ACPI_FAILURE(status)) {
printk(MY_INFO "Unable to get notification device\n");
return -ENODEV;
}
- toshiba_acpi.handle = handle;
-
- status = acpi_evaluate_object(handle, "ENAB", NULL, NULL);
- if (ACPI_FAILURE(status)) {
- printk(MY_INFO "Unable to enable hotkeys\n");
- return -ENODEV;
- }
-
- status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
- toshiba_acpi_notify, NULL);
- if (ACPI_FAILURE(status)) {
- printk(MY_INFO "Unable to install hotkey notification\n");
- return -ENODEV;
- }
-
toshiba_acpi.hotkey_dev = input_allocate_device();
if (!toshiba_acpi.hotkey_dev) {
printk(MY_INFO "Unable to register input device\n");
@@ -982,27 +895,54 @@ static int toshiba_acpi_setup_keyboard(char *device)
toshiba_acpi.hotkey_dev->name = "Toshiba input device";
toshiba_acpi.hotkey_dev->phys = device;
toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST;
- toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode;
- toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode;
- for (key = toshiba_acpi_keymap; key->type != KE_END; key++) {
- set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit);
- set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit);
+ error = sparse_keymap_setup(toshiba_acpi.hotkey_dev,
+ toshiba_acpi_keymap, NULL);
+ if (error)
+ goto err_free_dev;
+
+ status = acpi_install_notify_handler(toshiba_acpi.handle,
+ ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(MY_INFO "Unable to install hotkey notification\n");
+ error = -ENODEV;
+ goto err_free_keymap;
+ }
+
+ status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL);
+ if (ACPI_FAILURE(status)) {
+ printk(MY_INFO "Unable to enable hotkeys\n");
+ error = -ENODEV;
+ goto err_remove_notify;
}
- result = input_register_device(toshiba_acpi.hotkey_dev);
- if (result) {
+ error = input_register_device(toshiba_acpi.hotkey_dev);
+ if (error) {
printk(MY_INFO "Unable to register input device\n");
- return result;
+ goto err_remove_notify;
}
return 0;
+
+ err_remove_notify:
+ acpi_remove_notify_handler(toshiba_acpi.handle,
+ ACPI_DEVICE_NOTIFY, toshiba_acpi_notify);
+ err_free_keymap:
+ sparse_keymap_free(toshiba_acpi.hotkey_dev);
+ err_free_dev:
+ input_free_device(toshiba_acpi.hotkey_dev);
+ toshiba_acpi.hotkey_dev = NULL;
+ return error;
}
static void toshiba_acpi_exit(void)
{
- if (toshiba_acpi.hotkey_dev)
+ if (toshiba_acpi.hotkey_dev) {
+ acpi_remove_notify_handler(toshiba_acpi.handle,
+ ACPI_DEVICE_NOTIFY, toshiba_acpi_notify);
+ sparse_keymap_free(toshiba_acpi.hotkey_dev);
input_unregister_device(toshiba_acpi.hotkey_dev);
+ }
if (toshiba_acpi.bt_rfk) {
rfkill_unregister(toshiba_acpi.bt_rfk);
@@ -1017,9 +957,6 @@ static void toshiba_acpi_exit(void)
if (toshiba_proc_dir)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
- acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
- toshiba_acpi_notify);
-
if (toshiba_acpi.illumination_installed)
led_classdev_unregister(&toshiba_led);
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 07343568a12e..4d9a637539b6 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -109,6 +109,13 @@ config BATTERY_WM97XX
help
Say Y to enable support for battery measured by WM97xx aux port.
+config BATTERY_BQ20Z75
+ tristate "TI BQ20z75 gas gauge"
+ depends on I2C
+ help
+ Say Y to include support for TI BQ20z75 SBS-compliant
+ gas gauge and protection IC.
+
config BATTERY_BQ27x00
tristate "BQ27x00 battery driver"
depends on I2C
@@ -166,4 +173,11 @@ config BATTERY_INTEL_MID
Say Y here to enable the battery driver on Intel MID
platforms.
+config CHARGER_ISP1704
+ tristate "ISP1704 USB Charger Detection"
+ depends on USB_OTG_UTILS
+ help
+ Say Y to enable support for USB Charger Detection with
+ ISP1707/ISP1704 USB transceivers.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 10143aaf4ee3..2799a8418186 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
+obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
@@ -37,3 +38,4 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
+obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c
new file mode 100644
index 000000000000..a1c7ae2ec9f8
--- /dev/null
+++ b/drivers/power/bq20z75.c
@@ -0,0 +1,385 @@
+/*
+ * Gas Gauge driver for TI's BQ20Z75
+ *
+ * Copyright (c) 2010, NVIDIA 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+enum {
+ REG_MANUFACTURER_DATA,
+ REG_TEMPERATURE,
+ REG_VOLTAGE,
+ REG_CURRENT,
+ REG_CAPACITY,
+ REG_TIME_TO_EMPTY,
+ REG_TIME_TO_FULL,
+ REG_STATUS,
+ REG_CYCLE_COUNT,
+ REG_SERIAL_NUMBER
+};
+
+/* manufacturer access defines */
+#define MANUFACTURER_ACCESS_STATUS 0x0006
+#define MANUFACTURER_ACCESS_SLEEP 0x0011
+
+/* battery status value bits */
+#define BATTERY_CHARGING 0x40
+#define BATTERY_FULL_CHARGED 0x20
+#define BATTERY_FULL_DISCHARGED 0x10
+
+#define BQ20Z75_DATA(_psp, _addr, _min_value, _max_value) { \
+ .psp = _psp, \
+ .addr = _addr, \
+ .min_value = _min_value, \
+ .max_value = _max_value, \
+}
+
+static const struct bq20z75_device_data {
+ enum power_supply_property psp;
+ u8 addr;
+ int min_value;
+ int max_value;
+} bq20z75_data[] = {
+ [REG_MANUFACTURER_DATA] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
+ [REG_TEMPERATURE] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
+ [REG_VOLTAGE] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
+ [REG_CURRENT] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768,
+ 32767),
+ [REG_CAPACITY] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100),
+ [REG_TIME_TO_EMPTY] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0,
+ 65535),
+ [REG_TIME_TO_FULL] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0,
+ 65535),
+ [REG_STATUS] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
+ [REG_CYCLE_COUNT] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
+ [REG_SERIAL_NUMBER] =
+ BQ20Z75_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
+};
+
+static enum power_supply_property bq20z75_properties[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CYCLE_COUNT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
+ POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
+ POWER_SUPPLY_PROP_SERIAL_NUMBER,
+};
+
+struct bq20z75_info {
+ struct i2c_client *client;
+ struct power_supply power_supply;
+};
+
+static int bq20z75_get_battery_presence_and_health(
+ struct i2c_client *client, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ s32 ret;
+
+ /* Write to ManufacturerAccess with
+ * ManufacturerAccess command and then
+ * read the status */
+ ret = i2c_smbus_write_word_data(client,
+ bq20z75_data[REG_MANUFACTURER_DATA].addr,
+ MANUFACTURER_ACCESS_STATUS);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: i2c write for battery presence failed\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ ret = i2c_smbus_read_word_data(client,
+ bq20z75_data[REG_MANUFACTURER_DATA].addr);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: i2c read for battery presence failed\n",
+ __func__);
+ return -EIO;
+ }
+
+ if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value ||
+ ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) {
+ val->intval = 0;
+ return 0;
+ }
+
+ /* Mask the upper nibble of 2nd byte and
+ * lower byte of response then
+ * shift the result by 8 to get status*/
+ ret &= 0x0F00;
+ ret >>= 8;
+ if (psp == POWER_SUPPLY_PROP_PRESENT) {
+ if (ret == 0x0F)
+ /* battery removed */
+ val->intval = 0;
+ else
+ val->intval = 1;
+ } else if (psp == POWER_SUPPLY_PROP_HEALTH) {
+ if (ret == 0x09)
+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ else if (ret == 0x0B)
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ else if (ret == 0x0C)
+ val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ }
+
+ return 0;
+}
+
+static int bq20z75_get_battery_property(struct i2c_client *client,
+ int reg_offset, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ s32 ret;
+
+ ret = i2c_smbus_read_word_data(client,
+ bq20z75_data[reg_offset].addr);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: i2c read for %d failed\n", __func__, reg_offset);
+ return -EIO;
+ }
+
+ if (ret >= bq20z75_data[reg_offset].min_value &&
+ ret <= bq20z75_data[reg_offset].max_value) {
+ val->intval = ret;
+ if (psp == POWER_SUPPLY_PROP_STATUS) {
+ if (ret & BATTERY_CHARGING)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else if (ret & BATTERY_FULL_CHARGED)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else if (ret & BATTERY_FULL_DISCHARGED)
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ }
+ /* bq20z75 provides battery tempreture in 0.1°K
+ * so convert it to °C */
+ else if (psp == POWER_SUPPLY_PROP_TEMP)
+ val->intval = ret - 2731;
+ } else {
+ if (psp == POWER_SUPPLY_PROP_STATUS)
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ else
+ val->intval = 0;
+ }
+
+ return 0;
+}
+
+static int bq20z75_get_battery_capacity(struct i2c_client *client,
+ union power_supply_propval *val)
+{
+ s32 ret;
+
+ ret = i2c_smbus_read_byte_data(client, bq20z75_data[REG_CAPACITY].addr);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: i2c read for %d failed\n", __func__, REG_CAPACITY);
+ return -EIO;
+ }
+
+ /* bq20z75 spec says that this can be >100 %
+ * even if max value is 100 % */
+ val->intval = min(ret, 100);
+
+ return 0;
+}
+
+static int bq20z75_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ int count;
+ int ret;
+ struct bq20z75_info *bq20z75_device = container_of(psy,
+ struct bq20z75_info, power_supply);
+ struct i2c_client *client = bq20z75_device->client;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ case POWER_SUPPLY_PROP_HEALTH:
+ ret = bq20z75_get_battery_presence_and_health(client, psp, val);
+ if (ret)
+ return ret;
+ break;
+
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = bq20z75_get_battery_capacity(client, val);
+ if (ret)
+ return ret;
+ break;
+
+ case POWER_SUPPLY_PROP_STATUS:
+ case POWER_SUPPLY_PROP_CYCLE_COUNT:
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ case POWER_SUPPLY_PROP_TEMP:
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ case POWER_SUPPLY_PROP_SERIAL_NUMBER:
+ for (count = 0; count < ARRAY_SIZE(bq20z75_data); count++) {
+ if (psp == bq20z75_data[count].psp)
+ break;
+ }
+
+ ret = bq20z75_get_battery_property(client, count, psp, val);
+ if (ret)
+ return ret;
+ break;
+
+ default:
+ dev_err(&client->dev,
+ "%s: INVALID property\n", __func__);
+ return -EINVAL;
+ }
+
+ dev_dbg(&client->dev,
+ "%s: property = %d, value = %d\n", __func__, psp, val->intval);
+
+ return 0;
+}
+
+static int bq20z75_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bq20z75_info *bq20z75_device;
+ int rc;
+
+ bq20z75_device = kzalloc(sizeof(struct bq20z75_info), GFP_KERNEL);
+ if (!bq20z75_device)
+ return -ENOMEM;
+
+ bq20z75_device->client = client;
+ bq20z75_device->power_supply.name = "battery";
+ bq20z75_device->power_supply.type = POWER_SUPPLY_TYPE_BATTERY;
+ bq20z75_device->power_supply.properties = bq20z75_properties;
+ bq20z75_device->power_supply.num_properties =
+ ARRAY_SIZE(bq20z75_properties);
+ bq20z75_device->power_supply.get_property = bq20z75_get_property;
+
+ i2c_set_clientdata(client, bq20z75_device);
+
+ rc = power_supply_register(&client->dev, &bq20z75_device->power_supply);
+ if (rc) {
+ dev_err(&client->dev,
+ "%s: Failed to register power supply\n", __func__);
+ kfree(bq20z75_device);
+ return rc;
+ }
+
+ dev_info(&client->dev,
+ "%s: battery gas gauge device registered\n", client->name);
+
+ return 0;
+}
+
+static int bq20z75_remove(struct i2c_client *client)
+{
+ struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
+
+ power_supply_unregister(&bq20z75_device->power_supply);
+ kfree(bq20z75_device);
+ bq20z75_device = NULL;
+
+ return 0;
+}
+
+#if defined CONFIG_PM
+static int bq20z75_suspend(struct i2c_client *client,
+ pm_message_t state)
+{
+ s32 ret;
+
+ /* write to manufacturer access with sleep command */
+ ret = i2c_smbus_write_word_data(client,
+ bq20z75_data[REG_MANUFACTURER_DATA].addr,
+ MANUFACTURER_ACCESS_SLEEP);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s: i2c write for %d failed\n",
+ __func__, MANUFACTURER_ACCESS_SLEEP);
+ return -EIO;
+ }
+
+ return 0;
+}
+#else
+#define bq20z75_suspend NULL
+#endif
+/* any smbus transaction will wake up bq20z75 */
+#define bq20z75_resume NULL
+
+static const struct i2c_device_id bq20z75_id[] = {
+ { "bq20z75", 0 },
+ {}
+};
+
+static struct i2c_driver bq20z75_battery_driver = {
+ .probe = bq20z75_probe,
+ .remove = bq20z75_remove,
+ .suspend = bq20z75_suspend,
+ .resume = bq20z75_resume,
+ .id_table = bq20z75_id,
+ .driver = {
+ .name = "bq20z75-battery",
+ },
+};
+
+static int __init bq20z75_battery_init(void)
+{
+ return i2c_add_driver(&bq20z75_battery_driver);
+}
+module_init(bq20z75_battery_init);
+
+static void __exit bq20z75_battery_exit(void)
+{
+ i2c_del_driver(&bq20z75_battery_driver);
+}
+module_exit(bq20z75_battery_exit);
+
+MODULE_DESCRIPTION("BQ20z75 battery monitor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
new file mode 100644
index 000000000000..72512185f3e2
--- /dev/null
+++ b/drivers/power/isp1704_charger.c
@@ -0,0 +1,369 @@
+/*
+ * ISP1704 USB Charger Detection driver
+ *
+ * Copyright (C) 2010 Nokia 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; 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/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/delay.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+/* Vendor specific Power Control register */
+#define ISP1704_PWR_CTRL 0x3d
+#define ISP1704_PWR_CTRL_SWCTRL (1 << 0)
+#define ISP1704_PWR_CTRL_DET_COMP (1 << 1)
+#define ISP1704_PWR_CTRL_BVALID_RISE (1 << 2)
+#define ISP1704_PWR_CTRL_BVALID_FALL (1 << 3)
+#define ISP1704_PWR_CTRL_DP_WKPU_EN (1 << 4)
+#define ISP1704_PWR_CTRL_VDAT_DET (1 << 5)
+#define ISP1704_PWR_CTRL_DPVSRC_EN (1 << 6)
+#define ISP1704_PWR_CTRL_HWDETECT (1 << 7)
+
+#define NXP_VENDOR_ID 0x04cc
+
+static u16 isp170x_id[] = {
+ 0x1704,
+ 0x1707,
+};
+
+struct isp1704_charger {
+ struct device *dev;
+ struct power_supply psy;
+ struct otg_transceiver *otg;
+ struct notifier_block nb;
+ struct work_struct work;
+
+ char model[7];
+ unsigned present:1;
+};
+
+/*
+ * ISP1704 detects PS/2 adapters as charger. To make sure the detected charger
+ * is actually a dedicated charger, the following steps need to be taken.
+ */
+static inline int isp1704_charger_verify(struct isp1704_charger *isp)
+{
+ int ret = 0;
+ u8 r;
+
+ /* Reset the transceiver */
+ r = otg_io_read(isp->otg, ULPI_FUNC_CTRL);
+ r |= ULPI_FUNC_CTRL_RESET;
+ otg_io_write(isp->otg, ULPI_FUNC_CTRL, r);
+ usleep_range(1000, 2000);
+
+ /* Set normal mode */
+ r &= ~(ULPI_FUNC_CTRL_RESET | ULPI_FUNC_CTRL_OPMODE_MASK);
+ otg_io_write(isp->otg, ULPI_FUNC_CTRL, r);
+
+ /* Clear the DP and DM pull-down bits */
+ r = ULPI_OTG_CTRL_DP_PULLDOWN | ULPI_OTG_CTRL_DM_PULLDOWN;
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), r);
+
+ /* Enable strong pull-up on DP (1.5K) and reset */
+ r = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET;
+ otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), r);
+ usleep_range(1000, 2000);
+
+ /* Read the line state */
+ if (!otg_io_read(isp->otg, ULPI_DEBUG)) {
+ /* Disable strong pull-up on DP (1.5K) */
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_TERMSELECT);
+ return 1;
+ }
+
+ /* Is it a charger or PS/2 connection */
+
+ /* Enable weak pull-up resistor on DP */
+ otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL),
+ ISP1704_PWR_CTRL_DP_WKPU_EN);
+
+ /* Disable strong pull-up on DP (1.5K) */
+ otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL),
+ ULPI_FUNC_CTRL_TERMSELECT);
+
+ /* Enable weak pull-down resistor on DM */
+ otg_io_write(isp->otg, ULPI_SET(ULPI_OTG_CTRL),
+ ULPI_OTG_CTRL_DM_PULLDOWN);
+
+ /* It's a charger if the line states are clear */
+ if (!(otg_io_read(isp->otg, ULPI_DEBUG)))
+ ret = 1;
+
+ /* Disable weak pull-up resistor on DP */
+ otg_io_write(isp->otg, ULPI_CLR(ISP1704_PWR_CTRL),
+ ISP1704_PWR_CTRL_DP_WKPU_EN);
+
+ return ret;
+}
+
+static inline int isp1704_charger_detect(struct isp1704_charger *isp)
+{
+ unsigned long timeout;
+ u8 r;
+ int ret = 0;
+
+ /* set SW control bit in PWR_CTRL register */
+ otg_io_write(isp->otg, ISP1704_PWR_CTRL,
+ ISP1704_PWR_CTRL_SWCTRL);
+
+ /* enable manual charger detection */
+ r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN);
+ otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r);
+ usleep_range(1000, 2000);
+
+ timeout = jiffies + msecs_to_jiffies(300);
+ do {
+ /* Check if there is a charger */
+ if (otg_io_read(isp->otg, ISP1704_PWR_CTRL)
+ & ISP1704_PWR_CTRL_VDAT_DET) {
+ ret = isp1704_charger_verify(isp);
+ break;
+ }
+ } while (!time_after(jiffies, timeout));
+
+ return ret;
+}
+
+static void isp1704_charger_work(struct work_struct *data)
+{
+ int detect;
+ struct isp1704_charger *isp =
+ container_of(data, struct isp1704_charger, work);
+
+ /*
+ * FIXME Only supporting dedicated chargers even though isp1704 can
+ * detect HUB and HOST chargers. If the device has already been
+ * enumerated, the detection will break the connection.
+ */
+ if (isp->otg->state != OTG_STATE_B_IDLE)
+ return;
+
+ /* disable data pullups */
+ if (isp->otg->gadget)
+ usb_gadget_disconnect(isp->otg->gadget);
+
+ /* detect charger */
+ detect = isp1704_charger_detect(isp);
+ if (detect) {
+ isp->present = detect;
+ power_supply_changed(&isp->psy);
+ }
+
+ /* enable data pullups */
+ if (isp->otg->gadget)
+ usb_gadget_connect(isp->otg->gadget);
+}
+
+static int isp1704_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *unused)
+{
+ struct isp1704_charger *isp =
+ container_of(nb, struct isp1704_charger, nb);
+
+ switch (event) {
+ case USB_EVENT_VBUS:
+ schedule_work(&isp->work);
+ break;
+ case USB_EVENT_NONE:
+ if (isp->present) {
+ isp->present = 0;
+ power_supply_changed(&isp->psy);
+ }
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int isp1704_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct isp1704_charger *isp =
+ container_of(psy, struct isp1704_charger, psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = isp->present;
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = isp->model;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = "NXP";
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property power_props[] = {
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static inline int isp1704_test_ulpi(struct isp1704_charger *isp)
+{
+ int vendor;
+ int product;
+ int i;
+ int ret = -ENODEV;
+
+ /* Test ULPI interface */
+ ret = otg_io_write(isp->otg, ULPI_SCRATCH, 0xaa);
+ if (ret < 0)
+ return ret;
+
+ ret = otg_io_read(isp->otg, ULPI_SCRATCH);
+ if (ret < 0)
+ return ret;
+
+ if (ret != 0xaa)
+ return -ENODEV;
+
+ /* Verify the product and vendor id matches */
+ vendor = otg_io_read(isp->otg, ULPI_VENDOR_ID_LOW);
+ vendor |= otg_io_read(isp->otg, ULPI_VENDOR_ID_HIGH) << 8;
+ if (vendor != NXP_VENDOR_ID)
+ return -ENODEV;
+
+ product = otg_io_read(isp->otg, ULPI_PRODUCT_ID_LOW);
+ product |= otg_io_read(isp->otg, ULPI_PRODUCT_ID_HIGH) << 8;
+
+ for (i = 0; i < ARRAY_SIZE(isp170x_id); i++) {
+ if (product == isp170x_id[i]) {
+ sprintf(isp->model, "isp%x", product);
+ return product;
+ }
+ }
+
+ dev_err(isp->dev, "product id %x not matching known ids", product);
+
+ return -ENODEV;
+}
+
+static int __devinit isp1704_charger_probe(struct platform_device *pdev)
+{
+ struct isp1704_charger *isp;
+ int ret = -ENODEV;
+
+ isp = kzalloc(sizeof *isp, GFP_KERNEL);
+ if (!isp)
+ return -ENOMEM;
+
+ isp->otg = otg_get_transceiver();
+ if (!isp->otg)
+ goto fail0;
+
+ ret = isp1704_test_ulpi(isp);
+ if (ret < 0)
+ goto fail1;
+
+ isp->dev = &pdev->dev;
+ platform_set_drvdata(pdev, isp);
+
+ isp->psy.name = "isp1704";
+ isp->psy.type = POWER_SUPPLY_TYPE_USB;
+ isp->psy.properties = power_props;
+ isp->psy.num_properties = ARRAY_SIZE(power_props);
+ isp->psy.get_property = isp1704_charger_get_property;
+
+ ret = power_supply_register(isp->dev, &isp->psy);
+ if (ret)
+ goto fail1;
+
+ /*
+ * REVISIT: using work in order to allow the otg notifications to be
+ * made atomically in the future.
+ */
+ INIT_WORK(&isp->work, isp1704_charger_work);
+
+ isp->nb.notifier_call = isp1704_notifier_call;
+
+ ret = otg_register_notifier(isp->otg, &isp->nb);
+ if (ret)
+ goto fail2;
+
+ dev_info(isp->dev, "registered with product id %s\n", isp->model);
+
+ return 0;
+fail2:
+ power_supply_unregister(&isp->psy);
+fail1:
+ otg_put_transceiver(isp->otg);
+fail0:
+ kfree(isp);
+
+ dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret);
+
+ return ret;
+}
+
+static int __devexit isp1704_charger_remove(struct platform_device *pdev)
+{
+ struct isp1704_charger *isp = platform_get_drvdata(pdev);
+
+ otg_unregister_notifier(isp->otg, &isp->nb);
+ power_supply_unregister(&isp->psy);
+ otg_put_transceiver(isp->otg);
+ kfree(isp);
+
+ return 0;
+}
+
+static struct platform_driver isp1704_charger_driver = {
+ .driver = {
+ .name = "isp1704_charger",
+ },
+ .probe = isp1704_charger_probe,
+ .remove = __devexit_p(isp1704_charger_remove),
+};
+
+static int __init isp1704_charger_init(void)
+{
+ return platform_driver_register(&isp1704_charger_driver);
+}
+module_init(isp1704_charger_init);
+
+static void __exit isp1704_charger_exit(void)
+{
+ platform_driver_unregister(&isp1704_charger_driver);
+}
+module_exit(isp1704_charger_exit);
+
+MODULE_ALIAS("platform:isp1704_charger");
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_DESCRIPTION("ISP170x USB Charger driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index fbcc36dae470..a57a94150cb8 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -267,7 +267,6 @@ static void wm831x_config_battery(struct wm831x *wm831x)
ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_1,
WM831X_CHG_ENA_MASK |
WM831X_CHG_FAST_MASK |
- WM831X_CHG_ITERM_MASK |
WM831X_CHG_ITERM_MASK,
reg1);
if (ret != 0)
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 7d149a8d8d9b..2ce2eb71d0f5 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -215,7 +215,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
int ret = -EINVAL;
- if (info->vol_table && (index < (2 << info->vol_nbits))) {
+ if (info->vol_table && (index < (1 << info->vol_nbits))) {
ret = info->vol_table[index];
if (info->slope_double)
ret <<= 1;
@@ -233,7 +233,7 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
max_uV = max_uV >> 1;
}
if (info->vol_table) {
- for (i = 0; i < (2 << info->vol_nbits); i++) {
+ for (i = 0; i < (1 << info->vol_nbits); i++) {
if (!info->vol_table[i])
break;
if ((min_uV <= info->vol_table[i])
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 172951bf23a4..4889caabc632 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -100,6 +100,14 @@ config REGULATOR_MAX8925
help
Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
+config REGULATOR_MAX8952
+ tristate "Maxim MAX8952 Power Management IC"
+ depends on I2C
+ help
+ This driver controls a Maxim 8952 voltage output regulator
+ via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS
+ modes ranging from 0.77V to 1.40V by 0.01V steps.
+
config REGULATOR_MAX8998
tristate "Maxim 8998 voltage regulator"
depends on MFD_MAX8998
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8285fd832e16..beff6da6eff6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
+obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 11790990277a..b349266a43de 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -634,12 +634,9 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
"%s: failed to register regulator %s err %d\n",
__func__, ab3100_regulator_desc[i].name,
err);
- i--;
/* remove the already registered regulators */
- while (i > 0) {
+ while (--i >= 0)
regulator_unregister(ab3100_regulators[i].rdev);
- i--;
- }
return err;
}
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index dc3f1a491675..db6b70f20511 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -21,6 +21,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h>
@@ -33,9 +34,11 @@
* @max_uV: maximum voltage (for variable voltage supplies)
* @min_uV: minimum voltage (for variable voltage supplies)
* @fixed_uV: typical voltage (for fixed voltage supplies)
+ * @update_bank: bank to control on/off
* @update_reg: register to control on/off
* @mask: mask to enable/disable regulator
* @enable: bits to enable the regulator in normal(high power) mode
+ * @voltage_bank: bank to control regulator voltage
* @voltage_reg: register to control regulator voltage
* @voltage_mask: mask to control regulator voltage
* @supported_voltages: supported voltage table
@@ -49,11 +52,13 @@ struct ab8500_regulator_info {
int max_uV;
int min_uV;
int fixed_uV;
- int update_reg;
- int mask;
- int enable;
- int voltage_reg;
- int voltage_mask;
+ u8 update_bank;
+ u8 update_reg;
+ u8 mask;
+ u8 enable;
+ u8 voltage_bank;
+ u8 voltage_reg;
+ u8 voltage_mask;
int const *supported_voltages;
int voltages_len;
};
@@ -97,8 +102,8 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev)
if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL;
- ret = ab8500_set_bits(info->ab8500, info->update_reg,
- info->mask, info->enable);
+ ret = abx500_mask_and_set_register_interruptible(info->dev,
+ info->update_bank, info->update_reg, info->mask, info->enable);
if (ret < 0)
dev_err(rdev_get_dev(rdev),
"couldn't set enable bits for regulator\n");
@@ -114,8 +119,8 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL;
- ret = ab8500_set_bits(info->ab8500, info->update_reg,
- info->mask, 0x0);
+ ret = abx500_mask_and_set_register_interruptible(info->dev,
+ info->update_bank, info->update_reg, info->mask, 0x0);
if (ret < 0)
dev_err(rdev_get_dev(rdev),
"couldn't set disable bits for regulator\n");
@@ -126,19 +131,21 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
{
int regulator_id, ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 value;
regulator_id = rdev_get_id(rdev);
if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL;
- ret = ab8500_read(info->ab8500, info->update_reg);
+ ret = abx500_get_register_interruptible(info->dev,
+ info->update_bank, info->update_reg, &value);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read 0x%x register\n", info->update_reg);
return ret;
}
- if (ret & info->mask)
+ if (value & info->mask)
return true;
else
return false;
@@ -157,7 +164,7 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector)
if (info->fixed_uV)
return info->fixed_uV;
- if (selector > info->voltages_len)
+ if (selector >= info->voltages_len)
return -EINVAL;
return info->supported_voltages[selector];
@@ -165,14 +172,16 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector)
static int ab8500_regulator_get_voltage(struct regulator_dev *rdev)
{
- int regulator_id, ret, val;
+ int regulator_id, ret;
struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 value;
regulator_id = rdev_get_id(rdev);
if (regulator_id >= AB8500_NUM_REGULATORS)
return -EINVAL;
- ret = ab8500_read(info->ab8500, info->voltage_reg);
+ ret = abx500_get_register_interruptible(info->dev, info->voltage_bank,
+ info->voltage_reg, &value);
if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"couldn't read voltage reg for regulator\n");
@@ -180,11 +189,11 @@ static int ab8500_regulator_get_voltage(struct regulator_dev *rdev)
}
/* vintcore has a different layout */
- val = ret & info->voltage_mask;
+ value &= info->voltage_mask;
if (regulator_id == AB8500_LDO_INTCORE)
- ret = info->supported_voltages[val >> 0x3];
+ ret = info->supported_voltages[value >> 0x3];
else
- ret = info->supported_voltages[val];
+ ret = info->supported_voltages[value];
return ret;
}
@@ -224,8 +233,9 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
}
/* set the registers for the request */
- ret = ab8500_set_bits(info->ab8500, info->voltage_reg,
- info->voltage_mask, ret);
+ ret = abx500_mask_and_set_register_interruptible(info->dev,
+ info->voltage_bank, info->voltage_reg,
+ info->voltage_mask, (u8)ret);
if (ret < 0)
dev_err(rdev_get_dev(rdev),
"couldn't set voltage reg for regulator\n");
@@ -262,9 +272,9 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.list_voltage = ab8500_list_voltage,
};
-#define AB8500_LDO(_id, min, max, reg, reg_mask, reg_enable, \
- volt_reg, volt_mask, voltages, \
- len_volts) \
+#define AB8500_LDO(_id, min, max, bank, reg, reg_mask, \
+ reg_enable, volt_bank, volt_reg, volt_mask, \
+ voltages, len_volts) \
{ \
.desc = { \
.name = "LDO-" #_id, \
@@ -275,9 +285,11 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
}, \
.min_uV = (min) * 1000, \
.max_uV = (max) * 1000, \
+ .update_bank = bank, \
.update_reg = reg, \
.mask = reg_mask, \
.enable = reg_enable, \
+ .voltage_bank = volt_bank, \
.voltage_reg = volt_reg, \
.voltage_mask = volt_mask, \
.supported_voltages = voltages, \
@@ -285,8 +297,8 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.fixed_uV = 0, \
}
-#define AB8500_FIXED_LDO(_id, fixed, reg, reg_mask, \
- reg_enable) \
+#define AB8500_FIXED_LDO(_id, fixed, bank, reg, \
+ reg_mask, reg_enable) \
{ \
.desc = { \
.name = "LDO-" #_id, \
@@ -296,6 +308,7 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
.owner = THIS_MODULE, \
}, \
.fixed_uV = fixed * 1000, \
+ .update_bank = bank, \
.update_reg = reg, \
.mask = reg_mask, \
.enable = reg_enable, \
@@ -304,28 +317,29 @@ static struct regulator_ops ab8500_ldo_fixed_ops = {
static struct ab8500_regulator_info ab8500_regulator_info[] = {
/*
* Variable Voltage LDOs
- * name, min uV, max uV, ctrl reg, reg mask, enable mask,
- * volt ctrl reg, volt ctrl mask, volt table, num supported volts
+ * name, min uV, max uV, ctrl bank, ctrl reg, reg mask, enable mask,
+ * volt ctrl bank, volt ctrl reg, volt ctrl mask, volt table,
+ * num supported volts
*/
- AB8500_LDO(AUX1, 1100, 3300, 0x0409, 0x3, 0x1, 0x041f, 0xf,
+ AB8500_LDO(AUX1, 1100, 3300, 0x04, 0x09, 0x3, 0x1, 0x04, 0x1f, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
- AB8500_LDO(AUX2, 1100, 3300, 0x0409, 0xc, 0x4, 0x0420, 0xf,
+ AB8500_LDO(AUX2, 1100, 3300, 0x04, 0x09, 0xc, 0x4, 0x04, 0x20, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
- AB8500_LDO(AUX3, 1100, 3300, 0x040a, 0x3, 0x1, 0x0421, 0xf,
+ AB8500_LDO(AUX3, 1100, 3300, 0x04, 0x0a, 0x3, 0x1, 0x04, 0x21, 0xf,
ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)),
- AB8500_LDO(INTCORE, 1100, 3300, 0x0380, 0x4, 0x4, 0x0380, 0x38,
+ AB8500_LDO(INTCORE, 1100, 3300, 0x03, 0x80, 0x4, 0x4, 0x03, 0x80, 0x38,
ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)),
/*
* Fixed Voltage LDOs
- * name, o/p uV, ctrl reg, enable, disable
+ * name, o/p uV, ctrl bank, ctrl reg, enable, disable
*/
- AB8500_FIXED_LDO(TVOUT, 2000, 0x0380, 0x2, 0x2),
- AB8500_FIXED_LDO(AUDIO, 2000, 0x0383, 0x2, 0x2),
- AB8500_FIXED_LDO(ANAMIC1, 2050, 0x0383, 0x4, 0x4),
- AB8500_FIXED_LDO(ANAMIC2, 2050, 0x0383, 0x8, 0x8),
- AB8500_FIXED_LDO(DMIC, 1800, 0x0383, 0x10, 0x10),
- AB8500_FIXED_LDO(ANA, 1200, 0x0383, 0xc, 0x4),
+ AB8500_FIXED_LDO(TVOUT, 2000, 0x03, 0x80, 0x2, 0x2),
+ AB8500_FIXED_LDO(AUDIO, 2000, 0x03, 0x83, 0x2, 0x2),
+ AB8500_FIXED_LDO(ANAMIC1, 2050, 0x03, 0x83, 0x4, 0x4),
+ AB8500_FIXED_LDO(ANAMIC2, 2050, 0x03, 0x83, 0x8, 0x8),
+ AB8500_FIXED_LDO(DMIC, 1800, 0x03, 0x83, 0x10, 0x10),
+ AB8500_FIXED_LDO(ANA, 1200, 0x03, 0x83, 0xc, 0x4),
};
static inline struct ab8500_regulator_info *find_regulator_info(int id)
@@ -344,13 +358,14 @@ static inline struct ab8500_regulator_info *find_regulator_info(int id)
static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
- struct ab8500_platform_data *pdata = dev_get_platdata(ab8500->dev);
+ struct ab8500_platform_data *pdata;
int i, err;
if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n");
return -EINVAL;
}
+ pdata = dev_get_platdata(ab8500->dev);
/* register all regulators */
for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
@@ -368,11 +383,9 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
/* when we fail, un-register all earlier regulators */
- i--;
- while (i > 0) {
+ while (--i >= 0) {
info = &ab8500_regulator_info[i];
regulator_unregister(info->regulator);
- i--;
}
return err;
}
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index d59d2f2314af..a4be41614eeb 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -25,7 +25,7 @@ struct ad5398_chip_info {
unsigned int current_level;
unsigned int current_mask;
unsigned int current_offset;
- struct regulator_dev rdev;
+ struct regulator_dev *rdev;
};
static int ad5398_calc_current(struct ad5398_chip_info *chip,
@@ -211,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, ad5398_id);
static int __devinit ad5398_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct regulator_dev *rdev;
struct regulator_init_data *init_data = client->dev.platform_data;
struct ad5398_chip_info *chip;
const struct ad5398_current_data_format *df =
@@ -233,9 +232,10 @@ static int __devinit ad5398_probe(struct i2c_client *client,
chip->current_offset = df->current_offset;
chip->current_mask = (chip->current_level - 1) << chip->current_offset;
- rdev = regulator_register(&ad5398_reg, &client->dev, init_data, chip);
- if (IS_ERR(rdev)) {
- ret = PTR_ERR(rdev);
+ chip->rdev = regulator_register(&ad5398_reg, &client->dev,
+ init_data, chip);
+ if (IS_ERR(chip->rdev)) {
+ ret = PTR_ERR(chip->rdev);
dev_err(&client->dev, "failed to register %s %s\n",
id->name, ad5398_reg.name);
goto err;
@@ -254,9 +254,8 @@ static int __devexit ad5398_remove(struct i2c_client *client)
{
struct ad5398_chip_info *chip = i2c_get_clientdata(client);
- regulator_unregister(&chip->rdev);
+ regulator_unregister(chip->rdev);
kfree(chip);
- i2c_set_clientdata(client, NULL);
return 0;
}
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c
index e49d2bd393f2..b8cc6389a541 100644
--- a/drivers/regulator/isl6271a-regulator.c
+++ b/drivers/regulator/isl6271a-regulator.c
@@ -165,7 +165,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
mutex_init(&pmic->mtx);
for (i = 0; i < 3; i++) {
- pmic->rdev[i] = regulator_register(&isl_rd[0], &i2c->dev,
+ pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
init_data, pmic);
if (IS_ERR(pmic->rdev[i])) {
dev_err(&i2c->dev, "failed to register %s\n", id->name);
@@ -191,8 +191,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
struct isl_pmic *pmic = i2c_get_clientdata(i2c);
int i;
- i2c_set_clientdata(i2c, NULL);
-
for (i = 0; i < 3; i++)
regulator_unregister(pmic->rdev[i]);
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index 8867c2710a6d..559cfa271a44 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -121,14 +121,14 @@ static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
return -EINVAL;
- if (min_uV >= 3000000)
- selector = 3;
- if (min_uV < 3000000)
- selector = 2;
- if (min_uV < 2500000)
- selector = 1;
if (min_uV < 1800000)
selector = 0;
+ else if (min_uV < 2500000)
+ selector = 1;
+ else if (min_uV < 3000000)
+ selector = 2;
+ else if (min_uV >= 3000000)
+ selector = 3;
if (max1586_v6_calc_voltage(selector) > max_uV)
return -EINVAL;
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
new file mode 100644
index 000000000000..f2af0b1c3925
--- /dev/null
+++ b/drivers/regulator/max8952.c
@@ -0,0 +1,360 @@
+/*
+ * max8952.c - Voltage and current regulation for the Maxim 8952
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ * MyungJoo Ham <myungjoo.ham@samsung.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
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max8952.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+/* Registers */
+enum {
+ MAX8952_REG_MODE0,
+ MAX8952_REG_MODE1,
+ MAX8952_REG_MODE2,
+ MAX8952_REG_MODE3,
+ MAX8952_REG_CONTROL,
+ MAX8952_REG_SYNC,
+ MAX8952_REG_RAMP,
+ MAX8952_REG_CHIP_ID1,
+ MAX8952_REG_CHIP_ID2,
+};
+
+struct max8952_data {
+ struct i2c_client *client;
+ struct device *dev;
+ struct mutex mutex;
+ struct max8952_platform_data *pdata;
+ struct regulator_dev *rdev;
+
+ bool vid0;
+ bool vid1;
+ bool en;
+};
+
+static int max8952_read_reg(struct max8952_data *max8952, u8 reg)
+{
+ int ret = i2c_smbus_read_byte_data(max8952->client, reg);
+ if (ret > 0)
+ ret &= 0xff;
+
+ return ret;
+}
+
+static int max8952_write_reg(struct max8952_data *max8952,
+ u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(max8952->client, reg, value);
+}
+
+static int max8952_voltage(struct max8952_data *max8952, u8 mode)
+{
+ return (max8952->pdata->dvs_mode[mode] * 10 + 770) * 1000;
+}
+
+static int max8952_list_voltage(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+
+ if (rdev_get_id(rdev) != 0)
+ return -EINVAL;
+
+ return max8952_voltage(max8952, selector);
+}
+
+static int max8952_is_enabled(struct regulator_dev *rdev)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+ return max8952->en;
+}
+
+static int max8952_enable(struct regulator_dev *rdev)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+
+ /* If not valid, assume "ALWAYS_HIGH" */
+ if (gpio_is_valid(max8952->pdata->gpio_en))
+ gpio_set_value(max8952->pdata->gpio_en, 1);
+
+ max8952->en = true;
+ return 0;
+}
+
+static int max8952_disable(struct regulator_dev *rdev)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+
+ /* If not valid, assume "ALWAYS_HIGH" -> not permitted */
+ if (gpio_is_valid(max8952->pdata->gpio_en))
+ gpio_set_value(max8952->pdata->gpio_en, 0);
+ else
+ return -EPERM;
+
+ max8952->en = false;
+ return 0;
+}
+
+static int max8952_get_voltage(struct regulator_dev *rdev)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+ u8 vid = 0;
+
+ if (max8952->vid0)
+ vid += 1;
+ if (max8952->vid1)
+ vid += 2;
+
+ return max8952_voltage(max8952, vid);
+}
+
+static int max8952_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct max8952_data *max8952 = rdev_get_drvdata(rdev);
+ u8 vid = -1, i;
+
+ if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
+ !gpio_is_valid(max8952->pdata->gpio_vid0)) {
+ /* DVS not supported */
+ return -EPERM;
+ }
+
+ for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) {
+ int volt = max8952_voltage(max8952, i);
+
+ /* Set the voltage as low as possible within the range */
+ if (volt <= max_uV && volt >= min_uV)
+ if (vid == -1 || max8952_voltage(max8952, vid) > volt)
+ vid = i;
+ }
+
+ if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) {
+ max8952->vid0 = (vid % 2 == 1);
+ max8952->vid1 = (((vid >> 1) % 2) == 1);
+ gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
+ gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct regulator_ops max8952_ops = {
+ .list_voltage = max8952_list_voltage,
+ .is_enabled = max8952_is_enabled,
+ .enable = max8952_enable,
+ .disable = max8952_disable,
+ .get_voltage = max8952_get_voltage,
+ .set_voltage = max8952_set_voltage,
+ .set_suspend_disable = max8952_disable,
+};
+
+static struct regulator_desc regulator = {
+ .name = "MAX8952_VOUT",
+ .id = 0,
+ .n_voltages = MAX8952_NUM_DVS_MODE,
+ .ops = &max8952_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+};
+
+static int __devinit max8952_pmic_probe(struct i2c_client *client,
+ const struct i2c_device_id *i2c_id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct max8952_platform_data *pdata = client->dev.platform_data;
+ struct max8952_data *max8952;
+
+ int ret = 0, err = 0;
+
+ if (!pdata) {
+ dev_err(&client->dev, "Require the platform data\n");
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
+
+ max8952 = kzalloc(sizeof(struct max8952_data), GFP_KERNEL);
+ if (!max8952)
+ return -ENOMEM;
+
+ max8952->client = client;
+ max8952->dev = &client->dev;
+ max8952->pdata = pdata;
+ mutex_init(&max8952->mutex);
+
+ max8952->rdev = regulator_register(&regulator, max8952->dev,
+ &pdata->reg_data, max8952);
+
+ ret = IS_ERR(max8952->rdev);
+ if (ret)
+ dev_err(max8952->dev, "regulator init failed (%d)\n", ret);
+
+ max8952->en = !!(pdata->reg_data.constraints.boot_on);
+ max8952->vid0 = (pdata->default_mode % 2) == 1;
+ max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1;
+
+ if (gpio_is_valid(pdata->gpio_en)) {
+ if (!gpio_request(pdata->gpio_en, "MAX8952 EN"))
+ gpio_direction_output(pdata->gpio_en, max8952->en);
+ else
+ err = 1;
+ } else
+ err = 2;
+
+ if (err) {
+ dev_info(max8952->dev, "EN gpio invalid: assume that EN"
+ "is always High\n");
+ max8952->en = 1;
+ pdata->gpio_en = -1; /* Mark invalid */
+ }
+
+ err = 0;
+
+ if (gpio_is_valid(pdata->gpio_vid0) &&
+ gpio_is_valid(pdata->gpio_vid1)) {
+ if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
+ gpio_direction_output(pdata->gpio_vid0,
+ (pdata->default_mode) % 2);
+ else
+ err = 1;
+
+ if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
+ gpio_direction_output(pdata->gpio_vid1,
+ (pdata->default_mode >> 1) % 2);
+ else {
+ if (!err)
+ gpio_free(pdata->gpio_vid0);
+ err = 2;
+ }
+
+ } else
+ err = 3;
+
+ if (err) {
+ dev_warn(max8952->dev, "VID0/1 gpio invalid: "
+ "DVS not avilable.\n");
+ max8952->vid0 = 0;
+ max8952->vid1 = 0;
+ /* Mark invalid */
+ pdata->gpio_vid0 = -1;
+ pdata->gpio_vid1 = -1;
+
+ /* Disable Pulldown of EN only */
+ max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60);
+
+ dev_err(max8952->dev, "DVS modes disabled because VID0 and VID1"
+ " do not have proper controls.\n");
+ } else {
+ /*
+ * Disable Pulldown on EN, VID0, VID1 to reduce
+ * leakage current of MAX8952 assuming that MAX8952
+ * is turned on (EN==1). Note that without having VID0/1
+ * properly connected, turning pulldown off can be
+ * problematic. Thus, turn this off only when they are
+ * controllable by GPIO.
+ */
+ max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x0);
+ }
+
+ max8952_write_reg(max8952, MAX8952_REG_MODE0,
+ (max8952_read_reg(max8952,
+ MAX8952_REG_MODE0) & 0xC0) |
+ (pdata->dvs_mode[0] & 0x3F));
+ max8952_write_reg(max8952, MAX8952_REG_MODE1,
+ (max8952_read_reg(max8952,
+ MAX8952_REG_MODE1) & 0xC0) |
+ (pdata->dvs_mode[1] & 0x3F));
+ max8952_write_reg(max8952, MAX8952_REG_MODE2,
+ (max8952_read_reg(max8952,
+ MAX8952_REG_MODE2) & 0xC0) |
+ (pdata->dvs_mode[2] & 0x3F));
+ max8952_write_reg(max8952, MAX8952_REG_MODE3,
+ (max8952_read_reg(max8952,
+ MAX8952_REG_MODE3) & 0xC0) |
+ (pdata->dvs_mode[3] & 0x3F));
+
+ max8952_write_reg(max8952, MAX8952_REG_SYNC,
+ (max8952_read_reg(max8952, MAX8952_REG_SYNC) & 0x3F) |
+ ((pdata->sync_freq & 0x3) << 6));
+ max8952_write_reg(max8952, MAX8952_REG_RAMP,
+ (max8952_read_reg(max8952, MAX8952_REG_RAMP) & 0x1F) |
+ ((pdata->ramp_speed & 0x7) << 5));
+
+ i2c_set_clientdata(client, max8952);
+
+ return ret;
+}
+
+static int __devexit max8952_pmic_remove(struct i2c_client *client)
+{
+ struct max8952_data *max8952 = i2c_get_clientdata(client);
+ struct max8952_platform_data *pdata = max8952->pdata;
+ struct regulator_dev *rdev = max8952->rdev;
+
+ regulator_unregister(rdev);
+
+ gpio_free(pdata->gpio_vid0);
+ gpio_free(pdata->gpio_vid1);
+ gpio_free(pdata->gpio_en);
+
+ kfree(max8952);
+ return 0;
+}
+
+static const struct i2c_device_id max8952_ids[] = {
+ { "max8952", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, max8952_ids);
+
+static struct i2c_driver max8952_pmic_driver = {
+ .probe = max8952_pmic_probe,
+ .remove = __devexit_p(max8952_pmic_remove),
+ .driver = {
+ .name = "max8952",
+ },
+ .id_table = max8952_ids,
+};
+
+static int __init max8952_pmic_init(void)
+{
+ return i2c_add_driver(&max8952_pmic_driver);
+}
+subsys_initcall(max8952_pmic_init);
+
+static void __exit max8952_pmic_exit(void)
+{
+ i2c_del_driver(&max8952_pmic_driver);
+}
+module_exit(max8952_pmic_exit);
+
+MODULE_DESCRIPTION("MAXIM 8952 voltage regulator driver");
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index ab67298799f9..7f5fe6f198cf 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -173,6 +173,7 @@ static int max8998_get_enable_register(struct regulator_dev *rdev,
static int max8998_ldo_is_enabled(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8998->iodev->i2c;
int ret, reg, shift = 8;
u8 val;
@@ -180,7 +181,7 @@ static int max8998_ldo_is_enabled(struct regulator_dev *rdev)
if (ret)
return ret;
- ret = max8998_read_reg(max8998->iodev, reg, &val);
+ ret = max8998_read_reg(i2c, reg, &val);
if (ret)
return ret;
@@ -190,25 +191,27 @@ static int max8998_ldo_is_enabled(struct regulator_dev *rdev)
static int max8998_ldo_enable(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8998->iodev->i2c;
int reg, shift = 8, ret;
ret = max8998_get_enable_register(rdev, &reg, &shift);
if (ret)
return ret;
- return max8998_update_reg(max8998->iodev, reg, 1<<shift, 1<<shift);
+ return max8998_update_reg(i2c, reg, 1<<shift, 1<<shift);
}
static int max8998_ldo_disable(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8998->iodev->i2c;
int reg, shift = 8, ret;
ret = max8998_get_enable_register(rdev, &reg, &shift);
if (ret)
return ret;
- return max8998_update_reg(max8998->iodev, reg, 0, 1<<shift);
+ return max8998_update_reg(i2c, reg, 0, 1<<shift);
}
static int max8998_get_voltage_register(struct regulator_dev *rdev,
@@ -276,6 +279,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev,
static int max8998_get_voltage(struct regulator_dev *rdev)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8998->iodev->i2c;
int reg, shift = 0, mask, ret;
u8 val;
@@ -283,7 +287,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev)
if (ret)
return ret;
- ret = max8998_read_reg(max8998->iodev, reg, &val);
+ ret = max8998_read_reg(i2c, reg, &val);
if (ret)
return ret;
@@ -297,6 +301,7 @@ static int max8998_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8998->iodev->i2c;
int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
int previous_vol = 0;
const struct voltage_map_desc *desc;
@@ -330,14 +335,14 @@ static int max8998_set_voltage(struct regulator_dev *rdev,
/* wait for RAMP_UP_DELAY if rdev is BUCK1/2 and
* ENRAMP is ON */
if (ldo == MAX8998_BUCK1 || ldo == MAX8998_BUCK2) {
- max8998_read_reg(max8998->iodev, MAX8998_REG_ONOFF4, &val);
+ max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
if (val & (1 << 4)) {
en_ramp = true;
previous_vol = max8998_get_voltage(rdev);
}
}
- ret = max8998_update_reg(max8998->iodev, reg, i<<shift, mask<<shift);
+ ret = max8998_update_reg(i2c, reg, i<<shift, mask<<shift);
if (en_ramp == true) {
int difference = desc->min + desc->step*i - previous_vol/1000;
@@ -549,7 +554,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
if (!max8998)
return -ENOMEM;
- size = sizeof(struct regulator_dev *) * (pdata->num_regulators + 1);
+ size = sizeof(struct regulator_dev *) * pdata->num_regulators;
max8998->rdev = kzalloc(size, GFP_KERNEL);
if (!max8998->rdev) {
kfree(max8998);
@@ -557,7 +562,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
}
rdev = max8998->rdev;
+ max8998->dev = &pdev->dev;
max8998->iodev = iodev;
+ max8998->num_regulators = pdata->num_regulators;
platform_set_drvdata(pdev, max8998);
for (i = 0; i < pdata->num_regulators; i++) {
@@ -583,7 +590,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
return 0;
err:
- for (i = 0; i <= max8998->num_regulators; i++)
+ for (i = 0; i < max8998->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
@@ -599,7 +606,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev)
struct regulator_dev **rdev = max8998->rdev;
int i;
- for (i = 0; i <= max8998->num_regulators; i++)
+ for (i = 0; i < max8998->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index c239f42aa4a3..020f5878d7ff 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -626,12 +626,6 @@ fail:
return error;
}
-/**
- * tps6507x_remove - TPS6507x driver i2c remove handler
- * @client: i2c driver client device structure
- *
- * Unregister TPS driver as an i2c client device driver
- */
static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
{
struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index 8cff1413a147..51237fbb1bbb 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -133,7 +133,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
val = (val & mask) >> ri->volt_shift;
- if (val > ri->desc.n_voltages)
+ if (val >= ri->desc.n_voltages)
BUG();
return ri->voltages[val] * 1000;
@@ -150,7 +150,7 @@ static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev,
if (ret)
return ret;
- return tps6586x_set_bits(parent, ri->go_reg, ri->go_bit);
+ return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
}
static int tps6586x_regulator_enable(struct regulator_dev *rdev)
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index e686cdb61b97..9edf8f692341 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -215,8 +215,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
case REGULATOR_MODE_IDLE:
ret = wm831x_set_bits(wm831x, ctrl_reg,
- WM831X_LDO1_LP_MODE,
- WM831X_LDO1_LP_MODE);
+ WM831X_LDO1_LP_MODE, 0);
if (ret < 0)
return ret;
@@ -225,10 +224,12 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
WM831X_LDO1_ON_MODE);
if (ret < 0)
return ret;
+ break;
case REGULATOR_MODE_STANDBY:
ret = wm831x_set_bits(wm831x, ctrl_reg,
- WM831X_LDO1_LP_MODE, 0);
+ WM831X_LDO1_LP_MODE,
+ WM831X_LDO1_LP_MODE);
if (ret < 0)
return ret;
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 0e6ed7db9364..fe4b8a8a9dfd 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1129,7 +1129,7 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
mode = REGULATOR_MODE_NORMAL;
} else if (!active && !sleep)
mode = REGULATOR_MODE_IDLE;
- else if (!sleep)
+ else if (sleep)
mode = REGULATOR_MODE_STANDBY;
return mode;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 48ca7132cc05..1097e5bfb19e 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -195,6 +195,16 @@ config RTC_DRV_MAX8925
This driver can also be built as a module. If so, the module
will be called rtc-max8925.
+config RTC_DRV_MAX8998
+ tristate "Maxim MAX8998"
+ depends on MFD_MAX8998
+ help
+ If you say yes here you will get support for the
+ RTC of Maxim MAX8998 PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max8998.
+
config RTC_DRV_RS5C372
tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0f207b3b5833..e239661d55e1 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
+obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 2fda03125e55..e346705aae92 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -14,26 +14,26 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
+#include <linux/mfd/abx500.h>
#include <linux/mfd/ab8500.h>
#include <linux/delay.h>
-#define AB8500_RTC_SOFF_STAT_REG 0x0F00
-#define AB8500_RTC_CC_CONF_REG 0x0F01
-#define AB8500_RTC_READ_REQ_REG 0x0F02
-#define AB8500_RTC_WATCH_TSECMID_REG 0x0F03
-#define AB8500_RTC_WATCH_TSECHI_REG 0x0F04
-#define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05
-#define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06
-#define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07
-#define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08
-#define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09
-#define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A
-#define AB8500_RTC_STAT_REG 0x0F0B
-#define AB8500_RTC_BKUP_CHG_REG 0x0F0C
-#define AB8500_RTC_FORCE_BKUP_REG 0x0F0D
-#define AB8500_RTC_CALIB_REG 0x0F0E
-#define AB8500_RTC_SWITCH_STAT_REG 0x0F0F
-#define AB8500_REV_REG 0x1080
+#define AB8500_RTC_SOFF_STAT_REG 0x00
+#define AB8500_RTC_CC_CONF_REG 0x01
+#define AB8500_RTC_READ_REQ_REG 0x02
+#define AB8500_RTC_WATCH_TSECMID_REG 0x03
+#define AB8500_RTC_WATCH_TSECHI_REG 0x04
+#define AB8500_RTC_WATCH_TMIN_LOW_REG 0x05
+#define AB8500_RTC_WATCH_TMIN_MID_REG 0x06
+#define AB8500_RTC_WATCH_TMIN_HI_REG 0x07
+#define AB8500_RTC_ALRM_MIN_LOW_REG 0x08
+#define AB8500_RTC_ALRM_MIN_MID_REG 0x09
+#define AB8500_RTC_ALRM_MIN_HI_REG 0x0A
+#define AB8500_RTC_STAT_REG 0x0B
+#define AB8500_RTC_BKUP_CHG_REG 0x0C
+#define AB8500_RTC_FORCE_BKUP_REG 0x0D
+#define AB8500_RTC_CALIB_REG 0x0E
+#define AB8500_RTC_SWITCH_STAT_REG 0x0F
/* RtcReadRequest bits */
#define RTC_READ_REQUEST 0x01
@@ -46,13 +46,13 @@
#define COUNTS_PER_SEC (0xF000 / 60)
#define AB8500_RTC_EPOCH 2000
-static const unsigned long ab8500_rtc_time_regs[] = {
+static const u8 ab8500_rtc_time_regs[] = {
AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG,
AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG,
AB8500_RTC_WATCH_TSECMID_REG
};
-static const unsigned long ab8500_rtc_alarm_regs[] = {
+static const u8 ab8500_rtc_alarm_regs[] = {
AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG,
AB8500_RTC_ALRM_MIN_LOW_REG
};
@@ -76,29 +76,30 @@ static unsigned long get_elapsed_seconds(int year)
static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
- struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
unsigned long timeout = jiffies + HZ;
int retval, i;
unsigned long mins, secs;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
+ u8 value;
/* Request a data read */
- retval = ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG,
- RTC_READ_REQUEST);
+ retval = abx500_set_register_interruptible(dev,
+ AB8500_RTC, AB8500_RTC_READ_REQ_REG, RTC_READ_REQUEST);
if (retval < 0)
return retval;
/* Early AB8500 chips will not clear the rtc read request bit */
- if (ab8500->revision == 0) {
+ if (abx500_get_chip_id(dev) == 0) {
msleep(1);
} else {
/* Wait for some cycles after enabling the rtc read in ab8500 */
while (time_before(jiffies, timeout)) {
- retval = ab8500_read(ab8500, AB8500_RTC_READ_REQ_REG);
+ retval = abx500_get_register_interruptible(dev,
+ AB8500_RTC, AB8500_RTC_READ_REQ_REG, &value);
if (retval < 0)
return retval;
- if (!(retval & RTC_READ_REQUEST))
+ if (!(value & RTC_READ_REQUEST))
break;
msleep(1);
@@ -107,10 +108,11 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* Read the Watchtime registers */
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
- retval = ab8500_read(ab8500, ab8500_rtc_time_regs[i]);
+ retval = abx500_get_register_interruptible(dev,
+ AB8500_RTC, ab8500_rtc_time_regs[i], &value);
if (retval < 0)
return retval;
- buf[i] = retval;
+ buf[i] = value;
}
mins = (buf[0] << 16) | (buf[1] << 8) | buf[2];
@@ -128,7 +130,6 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
- struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)];
unsigned long no_secs, no_mins, secs = 0;
@@ -162,27 +163,29 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
buf[0] = (no_mins >> 16) & 0xFF;
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) {
- retval = ab8500_write(ab8500, ab8500_rtc_time_regs[i], buf[i]);
+ retval = abx500_set_register_interruptible(dev, AB8500_RTC,
+ ab8500_rtc_time_regs[i], buf[i]);
if (retval < 0)
return retval;
}
/* Request a data write */
- return ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST);
+ return abx500_set_register_interruptible(dev, AB8500_RTC,
+ AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST);
}
static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
- struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i;
- int rtc_ctrl;
+ u8 rtc_ctrl, value;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
unsigned long secs, mins;
/* Check if the alarm is enabled or not */
- rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG);
- if (rtc_ctrl < 0)
- return rtc_ctrl;
+ retval = abx500_get_register_interruptible(dev, AB8500_RTC,
+ AB8500_RTC_STAT_REG, &rtc_ctrl);
+ if (retval < 0)
+ return retval;
if (rtc_ctrl & RTC_ALARM_ENA)
alarm->enabled = 1;
@@ -192,10 +195,11 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
alarm->pending = 0;
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
- retval = ab8500_read(ab8500, ab8500_rtc_alarm_regs[i]);
+ retval = abx500_get_register_interruptible(dev, AB8500_RTC,
+ ab8500_rtc_alarm_regs[i], &value);
if (retval < 0)
return retval;
- buf[i] = retval;
+ buf[i] = value;
}
mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
@@ -211,15 +215,13 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled)
{
- struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
-
- return ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_ALARM_ENA,
- enabled ? RTC_ALARM_ENA : 0);
+ return abx500_mask_and_set_register_interruptible(dev, AB8500_RTC,
+ AB8500_RTC_STAT_REG, RTC_ALARM_ENA,
+ enabled ? RTC_ALARM_ENA : 0);
}
static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
- struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
int retval, i;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
unsigned long mins, secs = 0;
@@ -247,7 +249,8 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
/* Set the alarm time */
for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) {
- retval = ab8500_write(ab8500, ab8500_rtc_alarm_regs[i], buf[i]);
+ retval = abx500_set_register_interruptible(dev, AB8500_RTC,
+ ab8500_rtc_alarm_regs[i], buf[i]);
if (retval < 0)
return retval;
}
@@ -276,10 +279,9 @@ static const struct rtc_class_ops ab8500_rtc_ops = {
static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
{
- struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
int err;
struct rtc_device *rtc;
- int rtc_ctrl;
+ u8 rtc_ctrl;
int irq;
irq = platform_get_irq_byname(pdev, "ALARM");
@@ -287,17 +289,18 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
return irq;
/* For RTC supply test */
- err = ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_STATUS_DATA,
- RTC_STATUS_DATA);
+ err = abx500_mask_and_set_register_interruptible(&pdev->dev, AB8500_RTC,
+ AB8500_RTC_STAT_REG, RTC_STATUS_DATA, RTC_STATUS_DATA);
if (err < 0)
return err;
/* Wait for reset by the PorRtc */
msleep(1);
- rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG);
- if (rtc_ctrl < 0)
- return rtc_ctrl;
+ err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC,
+ AB8500_RTC_STAT_REG, &rtc_ctrl);
+ if (err < 0)
+ return err;
/* Check if the RTC Supply fails */
if (!(rtc_ctrl & RTC_STATUS_DATA)) {
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 72b2bcc2c224..d4fb82d85e9b 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -426,7 +426,7 @@ static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state)
enable_irq_wake(IRQ_RTC);
bfin_rtc_sync_pending(&pdev->dev);
} else
- bfin_rtc_int_clear(-1);
+ bfin_rtc_int_clear(0);
return 0;
}
@@ -435,8 +435,17 @@ static int bfin_rtc_resume(struct platform_device *pdev)
{
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(IRQ_RTC);
- else
- bfin_write_RTC_ISTAT(-1);
+
+ /*
+ * Since only some of the RTC bits are maintained externally in the
+ * Vbat domain, we need to wait for the RTC MMRs to be synced into
+ * the core after waking up. This happens every RTC 1HZ. Once that
+ * has happened, we can go ahead and re-enable the important write
+ * complete interrupt event.
+ */
+ while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC))
+ continue;
+ bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE);
return 0;
}
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 9daed8db83d3..9de8516e3531 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -268,7 +268,6 @@ out_irq:
free_irq(client->irq, client);
out_free:
- i2c_set_clientdata(client, NULL);
kfree(ds3232);
return ret;
}
@@ -287,7 +286,6 @@ static int __devexit ds3232_remove(struct i2c_client *client)
}
rtc_device_unregister(ds3232->rtc);
- i2c_set_clientdata(client, NULL);
kfree(ds3232);
return 0;
}
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 66377f3e28b8..684d82f86b33 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -20,7 +20,7 @@
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/string.h>
#ifdef CONFIG_RTC_DRV_M41T80_WDT
#include <linux/fs.h>
@@ -68,6 +68,7 @@
#define DRV_VERSION "0.05"
+static DEFINE_MUTEX(m41t80_rtc_mutex);
static const struct i2c_device_id m41t80_id[] = {
{ "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
{ "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
@@ -364,7 +365,7 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_isdst = -1;
t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
- return rtc_valid_tm(t);
+ return 0;
}
static struct rtc_class_ops m41t80_rtc_ops = {
@@ -677,9 +678,9 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd,
{
int ret;
- lock_kernel();
+ mutex_lock(&m41t80_rtc_mutex);
ret = wdt_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&m41t80_rtc_mutex);
return ret;
}
@@ -693,16 +694,16 @@ static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd,
static int wdt_open(struct inode *inode, struct file *file)
{
if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
- lock_kernel();
+ mutex_lock(&m41t80_rtc_mutex);
if (test_and_set_bit(0, &wdt_is_open)) {
- unlock_kernel();
+ mutex_unlock(&m41t80_rtc_mutex);
return -EBUSY;
}
/*
* Activate
*/
wdt_is_open = 1;
- unlock_kernel();
+ mutex_unlock(&m41t80_rtc_mutex);
return nonseekable_open(inode, file);
}
return -ENODEV;
@@ -748,6 +749,7 @@ static const struct file_operations wdt_fops = {
.write = wdt_write,
.open = wdt_open,
.release = wdt_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice wdt_dev = {
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
new file mode 100644
index 000000000000..f22dee35f330
--- /dev/null
+++ b/drivers/rtc/rtc-max8998.c
@@ -0,0 +1,300 @@
+/*
+ * RTC driver for Maxim MAX8998
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ * Author: Minkyu Kang <mk7.kang@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.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/i2c.h>
+#include <linux/slab.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/max8998.h>
+#include <linux/mfd/max8998-private.h>
+
+#define MAX8998_RTC_SEC 0x00
+#define MAX8998_RTC_MIN 0x01
+#define MAX8998_RTC_HOUR 0x02
+#define MAX8998_RTC_WEEKDAY 0x03
+#define MAX8998_RTC_DATE 0x04
+#define MAX8998_RTC_MONTH 0x05
+#define MAX8998_RTC_YEAR1 0x06
+#define MAX8998_RTC_YEAR2 0x07
+#define MAX8998_ALARM0_SEC 0x08
+#define MAX8998_ALARM0_MIN 0x09
+#define MAX8998_ALARM0_HOUR 0x0a
+#define MAX8998_ALARM0_WEEKDAY 0x0b
+#define MAX8998_ALARM0_DATE 0x0c
+#define MAX8998_ALARM0_MONTH 0x0d
+#define MAX8998_ALARM0_YEAR1 0x0e
+#define MAX8998_ALARM0_YEAR2 0x0f
+#define MAX8998_ALARM1_SEC 0x10
+#define MAX8998_ALARM1_MIN 0x11
+#define MAX8998_ALARM1_HOUR 0x12
+#define MAX8998_ALARM1_WEEKDAY 0x13
+#define MAX8998_ALARM1_DATE 0x14
+#define MAX8998_ALARM1_MONTH 0x15
+#define MAX8998_ALARM1_YEAR1 0x16
+#define MAX8998_ALARM1_YEAR2 0x17
+#define MAX8998_ALARM0_CONF 0x18
+#define MAX8998_ALARM1_CONF 0x19
+#define MAX8998_RTC_STATUS 0x1a
+#define MAX8998_WTSR_SMPL_CNTL 0x1b
+#define MAX8998_TEST 0x1f
+
+#define HOUR_12 (1 << 7)
+#define HOUR_PM (1 << 5)
+#define ALARM0_STATUS (1 << 1)
+#define ALARM1_STATUS (1 << 2)
+
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+};
+
+struct max8998_rtc_info {
+ struct device *dev;
+ struct max8998_dev *max8998;
+ struct i2c_client *rtc;
+ struct rtc_device *rtc_dev;
+ int irq;
+};
+
+static void max8998_data_to_tm(u8 *data, struct rtc_time *tm)
+{
+ tm->tm_sec = bcd2bin(data[RTC_SEC]);
+ tm->tm_min = bcd2bin(data[RTC_MIN]);
+ if (data[RTC_HOUR] & HOUR_12) {
+ tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
+ if (data[RTC_HOUR] & HOUR_PM)
+ tm->tm_hour += 12;
+ } else
+ tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
+
+ tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
+ tm->tm_mday = bcd2bin(data[RTC_DATE]);
+ tm->tm_mon = bcd2bin(data[RTC_MONTH]);
+ tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
+ tm->tm_year -= 1900;
+}
+
+static void max8998_tm_to_data(struct rtc_time *tm, u8 *data)
+{
+ data[RTC_SEC] = bin2bcd(tm->tm_sec);
+ data[RTC_MIN] = bin2bcd(tm->tm_min);
+ data[RTC_HOUR] = bin2bcd(tm->tm_hour);
+ data[RTC_WEEKDAY] = tm->tm_wday;
+ data[RTC_DATE] = bin2bcd(tm->tm_mday);
+ data[RTC_MONTH] = bin2bcd(tm->tm_mon);
+ data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
+ data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
+}
+
+static int max8998_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8998_rtc_info *info = dev_get_drvdata(dev);
+ u8 data[8];
+ int ret;
+
+ ret = max8998_bulk_read(info->rtc, MAX8998_RTC_SEC, 8, data);
+ if (ret < 0)
+ return ret;
+
+ max8998_data_to_tm(data, tm);
+
+ return rtc_valid_tm(tm);
+}
+
+static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8998_rtc_info *info = dev_get_drvdata(dev);
+ u8 data[8];
+
+ max8998_tm_to_data(tm, data);
+
+ return max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data);
+}
+
+static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8998_rtc_info *info = dev_get_drvdata(dev);
+ u8 data[8];
+ u8 val;
+ int ret;
+
+ ret = max8998_bulk_read(info->rtc, MAX8998_ALARM0_SEC, 8, data);
+ if (ret < 0)
+ return ret;
+
+ max8998_data_to_tm(data, &alrm->time);
+
+ ret = max8998_read_reg(info->rtc, MAX8998_ALARM0_CONF, &val);
+ if (ret < 0)
+ return ret;
+
+ alrm->enabled = !!val;
+
+ ret = max8998_read_reg(info->rtc, MAX8998_RTC_STATUS, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val & ALARM0_STATUS)
+ alrm->pending = 1;
+ else
+ alrm->pending = 0;
+
+ return 0;
+}
+
+static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info)
+{
+ return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0);
+}
+
+static int max8998_rtc_start_alarm(struct max8998_rtc_info *info)
+{
+ return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0x77);
+}
+
+static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8998_rtc_info *info = dev_get_drvdata(dev);
+ u8 data[8];
+ int ret;
+
+ max8998_tm_to_data(&alrm->time, data);
+
+ ret = max8998_rtc_stop_alarm(info);
+ if (ret < 0)
+ return ret;
+
+ ret = max8998_bulk_write(info->rtc, MAX8998_ALARM0_SEC, 8, data);
+ if (ret < 0)
+ return ret;
+
+ if (alrm->enabled)
+ return max8998_rtc_start_alarm(info);
+
+ return 0;
+}
+
+static int max8998_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct max8998_rtc_info *info = dev_get_drvdata(dev);
+
+ if (enabled)
+ return max8998_rtc_start_alarm(info);
+ else
+ return max8998_rtc_stop_alarm(info);
+}
+
+static irqreturn_t max8998_rtc_alarm_irq(int irq, void *data)
+{
+ struct max8998_rtc_info *info = data;
+
+ rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+ return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops max8998_rtc_ops = {
+ .read_time = max8998_rtc_read_time,
+ .set_time = max8998_rtc_set_time,
+ .read_alarm = max8998_rtc_read_alarm,
+ .set_alarm = max8998_rtc_set_alarm,
+ .alarm_irq_enable = max8998_rtc_alarm_irq_enable,
+};
+
+static int __devinit max8998_rtc_probe(struct platform_device *pdev)
+{
+ struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent);
+ struct max8998_rtc_info *info;
+ int ret;
+
+ info = kzalloc(sizeof(struct max8998_rtc_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = &pdev->dev;
+ info->max8998 = max8998;
+ info->rtc = max8998->rtc;
+ info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0;
+
+ info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev,
+ &max8998_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(info->rtc_dev)) {
+ ret = PTR_ERR(info->rtc_dev);
+ dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+ goto out_rtc;
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0,
+ "rtc-alarm0", info);
+ if (ret < 0)
+ dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
+ info->irq, ret);
+
+ return 0;
+
+out_rtc:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit max8998_rtc_remove(struct platform_device *pdev)
+{
+ struct max8998_rtc_info *info = platform_get_drvdata(pdev);
+
+ if (info) {
+ free_irq(info->irq, info);
+ rtc_device_unregister(info->rtc_dev);
+ kfree(info);
+ }
+
+ return 0;
+}
+
+static struct platform_driver max8998_rtc_driver = {
+ .driver = {
+ .name = "max8998-rtc",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8998_rtc_probe,
+ .remove = __devexit_p(max8998_rtc_remove),
+};
+
+static int __init max8998_rtc_init(void)
+{
+ return platform_driver_register(&max8998_rtc_driver);
+}
+module_init(max8998_rtc_init);
+
+static void __exit max8998_rtc_exit(void)
+{
+ platform_driver_unregister(&max8998_rtc_driver);
+}
+module_exit(max8998_rtc_exit);
+
+MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
+MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
+MODULE_DESCRIPTION("Maxim MAX8998 RTC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index 62de66af0a68..ddb0857e15a4 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -274,7 +274,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
nuc900_rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev,
&nuc900_rtc_ops, THIS_MODULE);
if (IS_ERR(nuc900_rtc->rtcdev)) {
- dev_err(&pdev->dev, "rtc device register faild\n");
+ dev_err(&pdev->dev, "rtc device register failed\n");
err = PTR_ERR(nuc900_rtc->rtcdev);
goto fail3;
}
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 6c418fe7f288..b7a6690e5b35 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -403,7 +403,7 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id)
}
if (request_irq(adev->irq[0], pl031_interrupt,
- IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) {
+ IRQF_DISABLED, "rtc-pl031", ldata)) {
ret = -EIO;
goto out_no_irq;
}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 38e6fa9a2012..aa95f1001761 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2196,7 +2196,6 @@ static void dasd_setup_queue(struct dasd_block *block)
*/
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);
}
/*
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 85bfd8794856..968c76cf7127 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -221,6 +221,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
ccw->cmd_code = CCW_CMD_DCTL;
ccw->count = 4;
ccw->cda = (__u32)(addr_t) DCTL_data;
+ dctl_cqr->flags = erp->flags;
dctl_cqr->function = dasd_3990_erp_DCTL;
dctl_cqr->refers = erp;
dctl_cqr->startdev = device;
@@ -1710,6 +1711,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
ccw->cda = cpa;
/* fill erp related fields */
+ erp->flags = default_erp->flags;
erp->function = dasd_3990_erp_action_1B_32;
erp->refers = default_erp->refers;
erp->startdev = device;
@@ -2197,7 +2199,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
/*
*****************************************************************************
- * main ERP control fuctions (24 and 32 byte sense)
+ * main ERP control functions (24 and 32 byte sense)
*****************************************************************************
*/
@@ -2354,6 +2356,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
ccw->cda = (long)(cqr->cpaddr);
}
+ erp->flags = cqr->flags;
erp->function = dasd_3990_erp_add_erp;
erp->refers = cqr;
erp->startdev = device;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 7158f9528ecc..cb02f057329c 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -670,6 +670,7 @@ static const struct file_operations dasd_eer_fops = {
.read = &dasd_eer_read,
.poll = &dasd_eer_poll,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice *dasd_eer_dev = NULL;
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 857dfcb7b359..20359060eb8f 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -520,6 +520,7 @@ static const struct file_operations fs3270_fops = {
.compat_ioctl = fs3270_ioctl, /* ioctl */
.open = fs3270_open, /* open */
.release = fs3270_close, /* release */
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index e021ec663ef9..155a805a0f1d 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -447,6 +447,7 @@ static const struct file_operations mon_fops = {
.release = &mon_close,
.read = &mon_read,
.poll = &mon_poll,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice mon_dev = {
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 572a1e7fd099..1af480106b5c 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -274,6 +274,7 @@ static const struct file_operations monwrite_fops = {
.open = &monwrite_open,
.release = &monwrite_close,
.write = &monwrite_write,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice mon_dev = {
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index fc993acf99b6..deff2c3361e4 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -31,7 +31,7 @@ debug_info_t *TAPE_DBF_AREA = NULL;
EXPORT_SYMBOL(TAPE_DBF_AREA);
/*******************************************************************
- * Error Recovery fuctions:
+ * Error Recovery functions:
* - Read Opposite: implemented
* - Read Device (buffered) log: BRA
* - Read Library log: BRA
@@ -798,7 +798,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
}
/*
- * This fuction is called, when error recovery was successfull
+ * This function is called, when error recovery was successful
*/
static inline int
tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
@@ -809,7 +809,7 @@ tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
}
/*
- * This fuction is called, when error recovery was not successfull
+ * This function is called, when error recovery was not successful
*/
static inline int
tape_3590_erp_failed(struct tape_device *device, struct tape_request *request,
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index b7de02525ec9..f0fa9ca5cb2c 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -16,7 +16,7 @@
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/buffer_head.h>
#include <linux/kernel.h>
@@ -45,6 +45,7 @@
/*
* file operation structure for tape block frontend
*/
+static DEFINE_MUTEX(tape_block_mutex);
static int tapeblock_open(struct block_device *, fmode_t);
static int tapeblock_release(struct gendisk *, fmode_t);
static int tapeblock_medium_changed(struct gendisk *);
@@ -217,8 +218,7 @@ tapeblock_setup_device(struct tape_device * device)
if (!blkdat->request_queue)
return -ENOMEM;
- elevator_exit(blkdat->request_queue->elevator);
- rc = elevator_init(blkdat->request_queue, "noop");
+ rc = elevator_change(blkdat->request_queue, "noop");
if (rc)
goto cleanup_queue;
@@ -362,7 +362,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
struct tape_device * device;
int rc;
- lock_kernel();
+ mutex_lock(&tape_block_mutex);
device = tape_get_device(disk->private_data);
if (device->required_tapemarks) {
@@ -386,14 +386,14 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
* is called.
*/
tape_state_set(device, TS_BLKUSE);
- unlock_kernel();
+ mutex_unlock(&tape_block_mutex);
return 0;
release:
tape_release(device);
put_device:
tape_put_device(device);
- unlock_kernel();
+ mutex_unlock(&tape_block_mutex);
return rc;
}
@@ -408,11 +408,11 @@ tapeblock_release(struct gendisk *disk, fmode_t mode)
{
struct tape_device *device = disk->private_data;
- lock_kernel();
+ mutex_lock(&tape_block_mutex);
tape_state_set(device, TS_IN_USE);
tape_release(device);
tape_put_device(device);
- unlock_kernel();
+ mutex_unlock(&tape_block_mutex);
return 0;
}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 539045acaad4..fa4a0a097793 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -53,6 +53,7 @@ static const struct file_operations tape_fops =
#endif
.open = tapechar_open,
.release = tapechar_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int tapechar_major = TAPECHAR_MAJOR;
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 29c2d73d719d..027783c99c72 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -212,20 +212,32 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
void
tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
{
+ static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
+ static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
+ char *envp[] = { NULL, NULL };
+
if (device->medium_state == newstate)
return;
switch(newstate){
case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0);
- if (device->medium_state == MS_LOADED)
+ if (device->medium_state == MS_LOADED) {
pr_info("%s: The tape cartridge has been successfully "
"unloaded\n", dev_name(&device->cdev->dev));
+ envp[0] = env_state_unloaded;
+ kobject_uevent_env(&device->cdev->dev.kobj,
+ KOBJ_CHANGE, envp);
+ }
break;
case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0);
- if (device->medium_state == MS_UNLOADED)
+ if (device->medium_state == MS_UNLOADED) {
pr_info("%s: A tape cartridge has been mounted\n",
dev_name(&device->cdev->dev));
+ envp[0] = env_state_loaded;
+ kobject_uevent_env(&device->cdev->dev.kobj,
+ KOBJ_CHANGE, envp);
+ }
break;
default:
// print nothing
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 04e532eec032..2e44c0b7eb1b 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -177,6 +177,7 @@ static const struct file_operations vmcp_fops = {
.write = vmcp_write,
.unlocked_ioctl = vmcp_ioctl,
.compat_ioctl = vmcp_ioctl,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice vmcp_dev = {
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index e40a1b892866..25d63da6af96 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -97,6 +97,7 @@ static const struct file_operations vmlogrdr_fops = {
.open = vmlogrdr_open,
.release = vmlogrdr_release,
.read = vmlogrdr_read,
+ .llseek = no_llseek,/* open uses nonseekable */
};
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index e13508c98b1a..bbfdcf1df5f3 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -297,6 +297,7 @@ static const struct file_operations vmwdt_fops = {
.unlocked_ioctl = &vmwdt_ioctl,
.write = &vmwdt_write,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice vmwdt_dev = {
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index f5ea3384a4b9..e0e3cd749bdf 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -459,6 +459,7 @@ static const struct file_operations zcore_memmap_fops = {
.read = zcore_memmap_read,
.open = zcore_memmap_open,
.release = zcore_memmap_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
@@ -486,6 +487,7 @@ static const struct file_operations zcore_reipl_fops = {
.write = zcore_reipl_write,
.open = zcore_reipl_open,
.release = zcore_reipl_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
#ifdef CONFIG_32BIT
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 13cb60162e42..76058a5166ed 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -79,17 +79,15 @@ static int pure_hex(char **cp, unsigned int *val, int min_digit,
int max_digit, int max_val)
{
int diff;
- unsigned int value;
diff = 0;
*val = 0;
- while (isxdigit(**cp) && (diff <= max_digit)) {
+ while (diff <= max_digit) {
+ int value = hex_to_bin(**cp);
- if (isdigit(**cp))
- value = **cp - '0';
- else
- value = tolower(**cp) - 'a' + 10;
+ if (value < 0)
+ break;
*val = *val * 16 + value;
(*cp)++;
diff++;
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index a83877c664a6..d7ec8d71e4d1 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -806,6 +806,7 @@ static const struct file_operations chsc_fops = {
.open = nonseekable_open,
.unlocked_ioctl = chsc_ioctl,
.compat_ioctl = chsc_ioctl,
+ .llseek = no_llseek,/* nonseekable */
};
static struct miscdevice chsc_misc_device = {
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index ac94ac751459..c5a92e110892 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1067,6 +1067,7 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf,
static const struct file_operations cio_settle_proc_fops = {
.open = nonseekable_open,
.write = cio_settle_write,
+ .llseek = no_llseek,/* nonseekable */
};
static int __init cio_settle_init(void)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index f0037eefd44e..0f4ef8769a3d 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -208,6 +208,7 @@ struct qdio_dev_perf_stat {
unsigned int eqbs_partial;
unsigned int sqbs;
unsigned int sqbs_partial;
+ unsigned int int_discarded;
} ____cacheline_aligned;
struct qdio_queue_perf_stat {
@@ -222,6 +223,10 @@ struct qdio_queue_perf_stat {
unsigned int nr_sbal_total;
};
+enum qdio_queue_irq_states {
+ QDIO_QUEUE_IRQS_DISABLED,
+};
+
struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
@@ -231,6 +236,10 @@ struct qdio_input_q {
int ack_count;
/* last time of noticing incoming data */
u64 timestamp;
+ /* upper-layer polling flag */
+ unsigned long queue_irq_state;
+ /* callback to start upper-layer polling */
+ void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
};
struct qdio_output_q {
@@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q)
#define sub_buf(bufnr, dec) \
((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
+#define queue_irqs_enabled(q) \
+ (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0)
+#define queue_irqs_disabled(q) \
+ (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0)
+
+#define TIQDIO_SHARED_IND 63
+
+/* device state change indicators */
+struct indicator_t {
+ u32 ind; /* u32 because of compare-and-swap performance */
+ atomic_t count; /* use count, 0 or 1 for non-shared indicators */
+};
+
+extern struct indicator_t *q_indicators;
+
+static inline int shared_ind(struct qdio_irq *irq_ptr)
+{
+ return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+}
+
/* prototypes for thin interrupt */
void qdio_setup_thinint(struct qdio_irq *irq_ptr);
int qdio_establish_thinint(struct qdio_irq *irq_ptr);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 6ce83f56d537..28868e7471a5 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -56,9 +56,16 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "DSCI: %d nr_used: %d\n",
*(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
- seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move);
- seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
- q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count);
+ seq_printf(m, "ftc: %d last_move: %d\n",
+ q->first_to_check, q->last_move);
+ if (q->is_input_q) {
+ seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
+ q->u.in.polling, q->u.in.ack_start,
+ q->u.in.ack_count);
+ seq_printf(m, "IRQs disabled: %u\n",
+ test_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state));
+ }
seq_printf(m, "SBAL states:\n");
seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
@@ -113,22 +120,6 @@ static int qstat_show(struct seq_file *m, void *v)
return 0;
}
-static ssize_t qstat_seq_write(struct file *file, const char __user *buf,
- size_t count, loff_t *off)
-{
- struct seq_file *seq = file->private_data;
- struct qdio_q *q = seq->private;
-
- if (!q)
- return 0;
- if (q->is_input_q)
- xchg(q->irq_ptr->dsci, 1);
- local_bh_disable();
- tasklet_schedule(&q->tasklet);
- local_bh_enable();
- return count;
-}
-
static int qstat_seq_open(struct inode *inode, struct file *filp)
{
return single_open(filp, qstat_show,
@@ -139,7 +130,6 @@ static const struct file_operations debugfs_fops = {
.owner = THIS_MODULE,
.open = qstat_seq_open,
.read = seq_read,
- .write = qstat_seq_write,
.llseek = seq_lseek,
.release = single_release,
};
@@ -166,7 +156,8 @@ static char *qperf_names[] = {
"QEBSM eqbs",
"QEBSM eqbs partial",
"QEBSM sqbs",
- "QEBSM sqbs partial"
+ "QEBSM sqbs partial",
+ "Discarded interrupts"
};
static int qperf_show(struct seq_file *m, void *v)
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 00520f9a7a8e..5fcfa7f9e9ef 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -884,8 +884,19 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
return;
- for_each_input_queue(irq_ptr, q, i)
- tasklet_schedule(&q->tasklet);
+ for_each_input_queue(irq_ptr, q, i) {
+ if (q->u.in.queue_start_poll) {
+ /* skip if polling is enabled or already in work */
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state)) {
+ qperf_inc(q, int_discarded);
+ continue;
+ }
+ q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
+ q->irq_ptr->int_parm);
+ } else
+ tasklet_schedule(&q->tasklet);
+ }
if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
return;
@@ -1519,6 +1530,129 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
}
EXPORT_SYMBOL_GPL(do_QDIO);
+/**
+ * qdio_start_irq - process input buffers
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ *
+ * Return codes
+ * 0 - success
+ * 1 - irqs not started since new data is available
+ */
+int qdio_start_irq(struct ccw_device *cdev, int nr)
+{
+ struct qdio_q *q;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+
+ WARN_ON(queue_irqs_enabled(q));
+
+ if (!shared_ind(q->irq_ptr))
+ xchg(q->irq_ptr->dsci, 0);
+
+ qdio_stop_polling(q);
+ clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
+
+ /*
+ * We need to check again to not lose initiative after
+ * resetting the ACK state.
+ */
+ if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci)
+ goto rescan;
+ if (!qdio_inbound_q_done(q))
+ goto rescan;
+ return 0;
+
+rescan:
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state))
+ return 0;
+ else
+ return 1;
+
+}
+EXPORT_SYMBOL(qdio_start_irq);
+
+/**
+ * qdio_get_next_buffers - process input buffers
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ * @bufnr: first filled buffer number
+ * @error: buffers are in error state
+ *
+ * Return codes
+ * < 0 - error
+ * = 0 - no new buffers found
+ * > 0 - number of processed buffers
+ */
+int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
+ int *error)
+{
+ struct qdio_q *q;
+ int start, end;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+ WARN_ON(queue_irqs_enabled(q));
+
+ qdio_sync_after_thinint(q);
+
+ /*
+ * The interrupt could be caused by a PCI request. Check the
+ * PCI capable outbound queues.
+ */
+ qdio_check_outbound_after_thinint(q);
+
+ if (!qdio_inbound_q_moved(q))
+ return 0;
+
+ /* Note: upper-layer MUST stop processing immediately here ... */
+ if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
+ return -EIO;
+
+ start = q->first_to_kick;
+ end = q->first_to_check;
+ *bufnr = start;
+ *error = q->qdio_error;
+
+ /* for the next time */
+ q->first_to_kick = end;
+ q->qdio_error = 0;
+ return sub_buf(end, start);
+}
+EXPORT_SYMBOL(qdio_get_next_buffers);
+
+/**
+ * qdio_stop_irq - disable interrupt processing for the device
+ * @cdev: associated ccw_device for the qdio subchannel
+ * @nr: input queue number
+ *
+ * Return codes
+ * 0 - interrupts were already disabled
+ * 1 - interrupts successfully disabled
+ */
+int qdio_stop_irq(struct ccw_device *cdev, int nr)
+{
+ struct qdio_q *q;
+ struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+
+ if (!irq_ptr)
+ return -ENODEV;
+ q = irq_ptr->input_qs[nr];
+
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state))
+ return 0;
+ else
+ return 1;
+}
+EXPORT_SYMBOL(qdio_stop_irq);
+
static int __init init_QDIO(void)
{
int rc;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 34c7e4046df4..a13cf7ec64b2 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -161,6 +161,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
q->is_input_q = 1;
+ q->u.in.queue_start_poll = qdio_init->queue_start_poll;
setup_storage_lists(q, irq_ptr, input_sbal_array, i);
input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8daf1b99f153..752dbee06af5 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -25,24 +25,20 @@
*/
#define TIQDIO_NR_NONSHARED_IND 63
#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1)
-#define TIQDIO_SHARED_IND 63
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
-static unsigned char *tiqdio_alsi;
+static u8 *tiqdio_alsi;
-/* device state change indicators */
-struct indicator_t {
- u32 ind; /* u32 because of compare-and-swap performance */
- atomic_t count; /* use count, 0 or 1 for non-shared indicators */
-};
-static struct indicator_t *q_indicators;
+struct indicator_t *q_indicators;
static int css_qdio_omit_svs;
+static u64 last_ai_time;
+
static inline unsigned long do_clear_global_summary(void)
{
register unsigned long __fn asm("1") = 3;
@@ -116,59 +112,73 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
}
}
-static inline int shared_ind(struct qdio_irq *irq_ptr)
+static inline int shared_ind_used(void)
{
- return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
+ return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count);
}
/**
* tiqdio_thinint_handler - thin interrupt handler for qdio
- * @ind: pointer to adapter local summary indicator
- * @drv_data: NULL
+ * @alsi: pointer to adapter local summary indicator
+ * @data: NULL
*/
-static void tiqdio_thinint_handler(void *ind, void *drv_data)
+static void tiqdio_thinint_handler(void *alsi, void *data)
{
struct qdio_q *q;
+ last_ai_time = S390_lowcore.int_clock;
+
/*
* SVS only when needed: issue SVS to benefit from iqdio interrupt
- * avoidance (SVS clears adapter interrupt suppression overwrite)
+ * avoidance (SVS clears adapter interrupt suppression overwrite).
*/
if (!css_qdio_omit_svs)
do_clear_global_summary();
- /*
- * reset local summary indicator (tiqdio_alsi) to stop adapter
- * interrupts for now
- */
- xchg((u8 *)ind, 0);
+ /* reset local summary indicator */
+ if (shared_ind_used())
+ xchg(tiqdio_alsi, 0);
/* protect tiq_list entries, only changed in activate or shutdown */
rcu_read_lock();
/* check for work on all inbound thinint queues */
- list_for_each_entry_rcu(q, &tiq_list, entry)
+ list_for_each_entry_rcu(q, &tiq_list, entry) {
+
/* only process queues from changed sets */
- if (*q->irq_ptr->dsci) {
- qperf_inc(q, adapter_int);
+ if (!*q->irq_ptr->dsci)
+ continue;
+ if (q->u.in.queue_start_poll) {
+ /* skip if polling is enabled or already in work */
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+ &q->u.in.queue_irq_state)) {
+ qperf_inc(q, int_discarded);
+ continue;
+ }
+
+ /* avoid dsci clear here, done after processing */
+ q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
+ q->irq_ptr->int_parm);
+ } else {
/* only clear it if the indicator is non-shared */
if (!shared_ind(q->irq_ptr))
xchg(q->irq_ptr->dsci, 0);
/*
- * don't call inbound processing directly since
- * that could starve other thinint queues
+ * Call inbound processing but not directly
+ * since that could starve other thinint queues.
*/
tasklet_schedule(&q->tasklet);
}
-
+ qperf_inc(q, adapter_int);
+ }
rcu_read_unlock();
/*
- * if we used the shared indicator clear it now after all queues
- * were processed
+ * If the shared indicator was used clear it now after all queues
+ * were processed.
*/
- if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) {
+ if (shared_ind_used()) {
xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0);
/* prevent racing */
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 41e0aaefafd5..7b2a64d29ea8 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -897,7 +897,8 @@ static const struct file_operations zcrypt_fops = {
.compat_ioctl = zcrypt_compat_ioctl,
#endif
.open = zcrypt_open,
- .release = zcrypt_release
+ .release = zcrypt_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 4e298bc8949d..5a46b8c5d68a 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -32,6 +32,7 @@
* The pointer to our (page) of device descriptions.
*/
static void *kvm_devices;
+struct work_struct hotplug_work;
struct kvm_device {
struct virtio_device vdev;
@@ -328,13 +329,54 @@ static void scan_devices(void)
}
/*
+ * match for a kvm device with a specific desc pointer
+ */
+static int match_desc(struct device *dev, void *data)
+{
+ if ((ulong)to_kvmdev(dev_to_virtio(dev))->desc == (ulong)data)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * hotplug_device tries to find changes in the device page.
+ */
+static void hotplug_devices(struct work_struct *dummy)
+{
+ unsigned int i;
+ struct kvm_device_desc *d;
+ struct device *dev;
+
+ for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
+ d = kvm_devices + i;
+
+ /* end of list */
+ if (d->type == 0)
+ break;
+
+ /* device already exists */
+ dev = device_find_child(kvm_root, d, match_desc);
+ if (dev) {
+ /* XXX check for hotplug remove */
+ put_device(dev);
+ continue;
+ }
+
+ /* new device */
+ printk(KERN_INFO "Adding new virtio device %p\n", d);
+ add_kvm_device(d, i);
+ }
+}
+
+/*
* we emulate the request_irq behaviour on top of s390 extints
*/
static void kvm_extint_handler(u16 code)
{
struct virtqueue *vq;
u16 subcode;
- int config_changed;
+ u32 param;
subcode = S390_lowcore.cpu_addr;
if ((subcode & 0xff00) != VIRTIO_SUBCODE_64)
@@ -343,18 +385,28 @@ static void kvm_extint_handler(u16 code)
/* The LSB might be overloaded, we have to mask it */
vq = (struct virtqueue *)(S390_lowcore.ext_params2 & ~1UL);
- /* We use the LSB of extparam, to decide, if this interrupt is a config
- * change or a "standard" interrupt */
- config_changed = S390_lowcore.ext_params & 1;
+ /* We use ext_params to decide what this interrupt means */
+ param = S390_lowcore.ext_params & VIRTIO_PARAM_MASK;
- if (config_changed) {
+ switch (param) {
+ case VIRTIO_PARAM_CONFIG_CHANGED:
+ {
struct virtio_driver *drv;
drv = container_of(vq->vdev->dev.driver,
struct virtio_driver, driver);
if (drv->config_changed)
drv->config_changed(vq->vdev);
- } else
+
+ break;
+ }
+ case VIRTIO_PARAM_DEV_ADD:
+ schedule_work(&hotplug_work);
+ break;
+ case VIRTIO_PARAM_VRING_INTERRUPT:
+ default:
vring_interrupt(0, vq);
+ break;
+ }
}
/*
@@ -383,6 +435,8 @@ static int __init kvm_devices_init(void)
kvm_devices = (void *) real_memory_size;
+ INIT_WORK(&hotplug_work, hotplug_devices);
+
ctl_set_bit(0, 9);
register_external_interrupt(0x2603, kvm_extint_handler);
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 977bb4d4ed15..456b18743397 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -100,6 +100,6 @@ config QETH_IPV6
config CCWGROUP
tristate
- default (LCS || CTCM || QETH)
+ default (LCS || CTCM || QETH || CLAW)
endmenu
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index d1257768be90..6be43eb126b4 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -676,6 +676,7 @@ enum qeth_discipline_id {
};
struct qeth_discipline {
+ void (*start_poll)(struct ccw_device *, int, unsigned long);
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
int (*recover)(void *ptr);
@@ -702,6 +703,16 @@ struct qeth_skb_data {
#define QETH_SKB_MAGIC 0x71657468
#define QETH_SIGA_CC2_RETRIES 3
+struct qeth_rx {
+ int b_count;
+ int b_index;
+ struct qdio_buffer_element *b_element;
+ int e_offset;
+ int qdio_err;
+};
+
+#define QETH_NAPI_WEIGHT 128
+
struct qeth_card {
struct list_head list;
enum qeth_card_states state;
@@ -749,6 +760,8 @@ struct qeth_card {
debug_info_t *debug;
struct mutex conf_mutex;
struct mutex discipline_mutex;
+ struct napi_struct napi;
+ struct qeth_rx rx;
};
struct qeth_card_list_struct {
@@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
struct qdio_buffer *, struct qdio_buffer_element **, int *,
struct qeth_hdr **);
void qeth_schedule_recovery(struct qeth_card *);
+void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
+void qeth_qdio_input_handler(struct ccw_device *,
+ unsigned int, unsigned int, int,
+ int, unsigned long);
void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
int, int, int, unsigned long);
void qeth_clear_ipacmd_list(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3a5a18a0fc28..764267062601 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
}
}
+void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
+ unsigned long card_ptr)
+{
+ struct qeth_card *card = (struct qeth_card *)card_ptr;
+
+ if (card->dev)
+ napi_schedule(&card->napi);
+}
+EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
+
+void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
+ unsigned int queue, int first_element, int count,
+ unsigned long card_ptr)
+{
+ struct qeth_card *card = (struct qeth_card *)card_ptr;
+
+ if (qdio_err)
+ qeth_schedule_recovery(card);
+}
+EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
+
void qeth_qdio_output_handler(struct ccw_device *ccwdev,
unsigned int qdio_error, int __queue, int first_element,
int count, unsigned long card_ptr)
@@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.no_output_qs = card->qdio.no_out_queues;
init_data.input_handler = card->discipline.input_handler;
init_data.output_handler = card->discipline.output_handler;
+ init_data.queue_start_poll = card->discipline.start_poll;
init_data.int_parm = (unsigned long) card;
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
@@ -4513,8 +4535,8 @@ static struct {
/* 20 */{"queue 1 buffer usage"},
{"queue 2 buffer usage"},
{"queue 3 buffer usage"},
- {"rx handler time"},
- {"rx handler count"},
+ {"rx poll time"},
+ {"rx poll count"},
{"rx do_QDIO time"},
{"rx do_QDIO count"},
{"tx handler time"},
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 830d63524d61..01c3c1f77879 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -407,29 +407,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
return rc;
}
-static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
- struct qeth_qdio_buffer *buf, int index)
+static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
+ int budget, int *done)
{
- struct qdio_buffer_element *element;
+ int work_done = 0;
struct sk_buff *skb;
struct qeth_hdr *hdr;
- int offset;
unsigned int len;
- /* get first element of current buffer */
- element = (struct qdio_buffer_element *)&buf->buffer->element[0];
- offset = 0;
- if (card->options.performance_stats)
- card->perf_stats.bufs_rec++;
- while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
- &offset, &hdr))) {
- skb->dev = card->dev;
- /* is device UP ? */
- if (!(card->dev->flags & IFF_UP)) {
- dev_kfree_skb_any(skb);
- continue;
+ *done = 0;
+ BUG_ON(!budget);
+ while (budget) {
+ skb = qeth_core_get_next_skb(card,
+ card->qdio.in_q->bufs[card->rx.b_index].buffer,
+ &card->rx.b_element, &card->rx.e_offset, &hdr);
+ if (!skb) {
+ *done = 1;
+ break;
}
-
+ skb->dev = card->dev;
switch (hdr->hdr.l2.id) {
case QETH_HEADER_TYPE_LAYER2:
skb->pkt_type = PACKET_HOST;
@@ -441,7 +437,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
if (skb->protocol == htons(ETH_P_802_2))
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
len = skb->len;
- netif_rx(skb);
+ netif_receive_skb(skb);
break;
case QETH_HEADER_TYPE_OSN:
if (card->info.type == QETH_CARD_TYPE_OSN) {
@@ -459,9 +455,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
continue;
}
+ work_done++;
+ budget--;
card->stats.rx_packets++;
card->stats.rx_bytes += len;
}
+ return work_done;
+}
+
+static int qeth_l2_poll(struct napi_struct *napi, int budget)
+{
+ struct qeth_card *card = container_of(napi, struct qeth_card, napi);
+ int work_done = 0;
+ struct qeth_qdio_buffer *buffer;
+ int done;
+ int new_budget = budget;
+
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
+ }
+
+ while (1) {
+ if (!card->rx.b_count) {
+ card->rx.qdio_err = 0;
+ card->rx.b_count = qdio_get_next_buffers(
+ card->data.ccwdev, 0, &card->rx.b_index,
+ &card->rx.qdio_err);
+ if (card->rx.b_count <= 0) {
+ card->rx.b_count = 0;
+ break;
+ }
+ card->rx.b_element =
+ &card->qdio.in_q->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+
+ while (card->rx.b_count) {
+ buffer = &card->qdio.in_q->bufs[card->rx.b_index];
+ if (!(card->rx.qdio_err &&
+ qeth_check_qdio_errors(card, buffer->buffer,
+ card->rx.qdio_err, "qinerr")))
+ work_done += qeth_l2_process_inbound_buffer(
+ card, new_budget, &done);
+ else
+ done = 1;
+
+ if (done) {
+ if (card->options.performance_stats)
+ card->perf_stats.bufs_rec++;
+ qeth_put_buffer_pool_entry(card,
+ buffer->pool_entry);
+ qeth_queue_input_buffer(card, card->rx.b_index);
+ card->rx.b_count--;
+ if (card->rx.b_count) {
+ card->rx.b_index =
+ (card->rx.b_index + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ card->rx.b_element =
+ &card->qdio.in_q
+ ->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+ }
+
+ if (work_done >= budget)
+ goto out;
+ else
+ new_budget = budget - work_done;
+ }
+ }
+
+ napi_complete(napi);
+ if (qdio_start_irq(card->data.ccwdev, 0))
+ napi_schedule(&card->napi);
+out:
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
+ return work_done;
}
static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
@@ -755,49 +829,10 @@ tx_drop:
return NETDEV_TX_OK;
}
-static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
- unsigned int qdio_err, unsigned int queue,
- int first_element, int count, unsigned long card_ptr)
-{
- struct net_device *net_dev;
- struct qeth_card *card;
- struct qeth_qdio_buffer *buffer;
- int index;
- int i;
-
- card = (struct qeth_card *) card_ptr;
- net_dev = card->dev;
- if (card->options.performance_stats) {
- card->perf_stats.inbound_cnt++;
- card->perf_stats.inbound_start_time = qeth_get_micros();
- }
- if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
- QETH_CARD_TEXT(card, 1, "qdinchk");
- QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element,
- count);
- QETH_CARD_TEXT_(card, 1, "%04X", queue);
- qeth_schedule_recovery(card);
- return;
- }
- for (i = first_element; i < (first_element + count); ++i) {
- index = i % QDIO_MAX_BUFFERS_PER_Q;
- buffer = &card->qdio.in_q->bufs[index];
- if (!(qdio_err &&
- qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
- "qinerr")))
- qeth_l2_process_inbound_buffer(card, buffer, index);
- /* clear buffer and give back to hardware */
- qeth_put_buffer_pool_entry(card, buffer->pool_entry);
- qeth_queue_input_buffer(card, index);
- }
- if (card->options.performance_stats)
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
-}
-
static int qeth_l2_open(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
+ int rc = 0;
QETH_CARD_TEXT(card, 4, "qethopen");
if (card->state != CARD_STATE_SOFTSETUP)
@@ -814,18 +849,24 @@ static int qeth_l2_open(struct net_device *dev)
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
- return 0;
+ if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
+ napi_enable(&card->napi);
+ napi_schedule(&card->napi);
+ } else
+ rc = -EIO;
+ return rc;
}
-
static int qeth_l2_stop(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
QETH_CARD_TEXT(card, 4, "qethstop");
netif_tx_disable(dev);
- if (card->state == CARD_STATE_UP)
+ if (card->state == CARD_STATE_UP) {
card->state = CARD_STATE_SOFTSETUP;
+ napi_disable(&card->napi);
+ }
return 0;
}
@@ -836,8 +877,9 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
INIT_LIST_HEAD(&card->vid_list);
INIT_LIST_HEAD(&card->mc_list);
card->options.layer2 = 1;
+ card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
- qeth_l2_qdio_input_handler;
+ qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l2_recover;
@@ -923,6 +965,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
card->info.broadcast_capable = 1;
qeth_l2_request_initial_mac(card);
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
+ netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
return register_netdev(card->dev);
}
@@ -955,6 +998,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
card->state = CARD_STATE_HARDSETUP;
+ memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
/* softsetup */
@@ -1086,9 +1130,6 @@ static int qeth_l2_recover(void *ptr)
card->use_hard_stop = 1;
__qeth_l2_set_offline(card->gdev, 1);
rc = __qeth_l2_set_online(card->gdev, 1);
- /* don't run another scheduled recovery */
- qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
- qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
@@ -1099,6 +1140,8 @@ static int qeth_l2_recover(void *ptr)
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
+ qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
+ qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index e22ae248f613..5b79f573bd93 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
{
- sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x"
- ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- addr[0], addr[1], addr[2], addr[3],
- addr[4], addr[5], addr[6], addr[7],
- addr[8], addr[9], addr[10], addr[11],
- addr[12], addr[13], addr[14], addr[15]);
+ sprintf(buf, "%pI6", addr);
}
int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
@@ -2112,51 +2107,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
return vlan_id;
}
-static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
- struct qeth_qdio_buffer *buf, int index)
+static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
+ int budget, int *done)
{
- struct qdio_buffer_element *element;
+ int work_done = 0;
struct sk_buff *skb;
struct qeth_hdr *hdr;
- int offset;
__u16 vlan_tag = 0;
unsigned int len;
- /* get first element of current buffer */
- element = (struct qdio_buffer_element *)&buf->buffer->element[0];
- offset = 0;
- if (card->options.performance_stats)
- card->perf_stats.bufs_rec++;
- while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
- &offset, &hdr))) {
- skb->dev = card->dev;
- /* is device UP ? */
- if (!(card->dev->flags & IFF_UP)) {
- dev_kfree_skb_any(skb);
- continue;
- }
+ *done = 0;
+ BUG_ON(!budget);
+ while (budget) {
+ skb = qeth_core_get_next_skb(card,
+ card->qdio.in_q->bufs[card->rx.b_index].buffer,
+ &card->rx.b_element, &card->rx.e_offset, &hdr);
+ if (!skb) {
+ *done = 1;
+ break;
+ }
+ skb->dev = card->dev;
switch (hdr->hdr.l3.id) {
case QETH_HEADER_TYPE_LAYER3:
vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
len = skb->len;
if (vlan_tag && !card->options.sniffer)
if (card->vlangrp)
- vlan_hwaccel_rx(skb, card->vlangrp,
- vlan_tag);
+ vlan_gro_receive(&card->napi,
+ card->vlangrp, vlan_tag, skb);
else {
dev_kfree_skb_any(skb);
continue;
}
else
- netif_rx(skb);
+ napi_gro_receive(&card->napi, skb);
break;
case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, skb->dev);
- if (card->options.checksum_type == NO_CHECKSUMMING)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
len = skb->len;
netif_receive_skb(skb);
break;
@@ -2166,10 +2154,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
continue;
}
-
+ work_done++;
+ budget--;
card->stats.rx_packets++;
card->stats.rx_bytes += len;
}
+ return work_done;
+}
+
+static int qeth_l3_poll(struct napi_struct *napi, int budget)
+{
+ struct qeth_card *card = container_of(napi, struct qeth_card, napi);
+ int work_done = 0;
+ struct qeth_qdio_buffer *buffer;
+ int done;
+ int new_budget = budget;
+
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
+ }
+
+ while (1) {
+ if (!card->rx.b_count) {
+ card->rx.qdio_err = 0;
+ card->rx.b_count = qdio_get_next_buffers(
+ card->data.ccwdev, 0, &card->rx.b_index,
+ &card->rx.qdio_err);
+ if (card->rx.b_count <= 0) {
+ card->rx.b_count = 0;
+ break;
+ }
+ card->rx.b_element =
+ &card->qdio.in_q->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+
+ while (card->rx.b_count) {
+ buffer = &card->qdio.in_q->bufs[card->rx.b_index];
+ if (!(card->rx.qdio_err &&
+ qeth_check_qdio_errors(card, buffer->buffer,
+ card->rx.qdio_err, "qinerr")))
+ work_done += qeth_l3_process_inbound_buffer(
+ card, new_budget, &done);
+ else
+ done = 1;
+
+ if (done) {
+ if (card->options.performance_stats)
+ card->perf_stats.bufs_rec++;
+ qeth_put_buffer_pool_entry(card,
+ buffer->pool_entry);
+ qeth_queue_input_buffer(card, card->rx.b_index);
+ card->rx.b_count--;
+ if (card->rx.b_count) {
+ card->rx.b_index =
+ (card->rx.b_index + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ card->rx.b_element =
+ &card->qdio.in_q
+ ->bufs[card->rx.b_index]
+ .buffer->element[0];
+ card->rx.e_offset = 0;
+ }
+ }
+
+ if (work_done >= budget)
+ goto out;
+ else
+ new_budget = budget - work_done;
+ }
+ }
+
+ napi_complete(napi);
+ if (qdio_start_irq(card->data.ccwdev, 0))
+ napi_schedule(&card->napi);
+out:
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
+ return work_done;
}
static int qeth_l3_verify_vlan_dev(struct net_device *dev,
@@ -3103,6 +3168,7 @@ tx_drop:
static int qeth_l3_open(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
+ int rc = 0;
QETH_CARD_TEXT(card, 4, "qethopen");
if (card->state != CARD_STATE_SOFTSETUP)
@@ -3113,7 +3179,12 @@ static int qeth_l3_open(struct net_device *dev)
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
- return 0;
+ if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
+ napi_enable(&card->napi);
+ napi_schedule(&card->napi);
+ } else
+ rc = -EIO;
+ return rc;
}
static int qeth_l3_stop(struct net_device *dev)
@@ -3122,8 +3193,10 @@ static int qeth_l3_stop(struct net_device *dev)
QETH_CARD_TEXT(card, 4, "qethstop");
netif_tx_disable(dev);
- if (card->state == CARD_STATE_UP)
+ if (card->state == CARD_STATE_UP) {
card->state = CARD_STATE_SOFTSETUP;
+ napi_disable(&card->napi);
+ }
return 0;
}
@@ -3293,57 +3366,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
card->dev->gso_max_size = 15 * PAGE_SIZE;
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
+ netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
return register_netdev(card->dev);
}
-static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
- unsigned int qdio_err, unsigned int queue, int first_element,
- int count, unsigned long card_ptr)
-{
- struct net_device *net_dev;
- struct qeth_card *card;
- struct qeth_qdio_buffer *buffer;
- int index;
- int i;
-
- card = (struct qeth_card *) card_ptr;
- net_dev = card->dev;
- if (card->options.performance_stats) {
- card->perf_stats.inbound_cnt++;
- card->perf_stats.inbound_start_time = qeth_get_micros();
- }
- if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
- QETH_CARD_TEXT(card, 1, "qdinchk");
- QETH_CARD_TEXT_(card, 1, "%04X%04X",
- first_element, count);
- QETH_CARD_TEXT_(card, 1, "%04X", queue);
- qeth_schedule_recovery(card);
- return;
- }
- for (i = first_element; i < (first_element + count); ++i) {
- index = i % QDIO_MAX_BUFFERS_PER_Q;
- buffer = &card->qdio.in_q->bufs[index];
- if (!(qdio_err &&
- qeth_check_qdio_errors(card, buffer->buffer,
- qdio_err, "qinerr")))
- qeth_l3_process_inbound_buffer(card, buffer, index);
- /* clear buffer and give back to hardware */
- qeth_put_buffer_pool_entry(card, buffer->pool_entry);
- qeth_queue_input_buffer(card, index);
- }
- if (card->options.performance_stats)
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
-}
-
static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
qeth_l3_create_device_attributes(&gdev->dev);
card->options.layer2 = 0;
+ card->discipline.start_poll = qeth_qdio_start_poll;
card->discipline.input_handler = (qdio_handler_t *)
- qeth_l3_qdio_input_handler;
+ qeth_qdio_input_handler;
card->discipline.output_handler = (qdio_handler_t *)
qeth_qdio_output_handler;
card->discipline.recover = qeth_l3_recover;
@@ -3402,6 +3437,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
}
card->state = CARD_STATE_HARDSETUP;
+ memset(&card->rx, 0, sizeof(struct qeth_rx));
qeth_print_status_message(card);
/* softsetup */
@@ -3538,9 +3574,6 @@ static int qeth_l3_recover(void *ptr)
card->use_hard_stop = 1;
__qeth_l3_set_offline(card->gdev, 1);
rc = __qeth_l3_set_online(card->gdev, 1);
- /* don't run another scheduled recovery */
- qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
- qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
if (!rc)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
@@ -3551,6 +3584,8 @@ static int qeth_l3_recover(void *ptr)
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n");
}
+ qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
+ qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
return 0;
}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 96fa1f536394..68df57157d48 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -73,13 +73,14 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
if (!port)
goto out_port;
+ flush_work(&port->rport_work);
unit = zfcp_unit_enqueue(port, lun);
if (IS_ERR(unit))
goto out_unit;
zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
zfcp_erp_wait(adapter);
- flush_work(&unit->scsi_work);
+ zfcp_scsi_scan(unit);
out_unit:
put_device(&port->dev);
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index fcbd2b756da4..cf2d7b3977b4 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -251,8 +251,9 @@ static const struct file_operations zfcp_cfdc_fops = {
.open = nonseekable_open,
.unlocked_ioctl = zfcp_cfdc_dev_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = zfcp_cfdc_dev_ioctl
+ .compat_ioctl = zfcp_cfdc_dev_ioctl,
#endif
+ .llseek = no_llseek,/* nonseekable */
};
struct miscdevice zfcp_cfdc_misc = {
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index b2635759721c..da54a28a1b87 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -277,16 +277,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
struct zfcp_qdio *qdio)
{
-
+ memset(id, 0, sizeof(*id));
id->cdev = qdio->adapter->ccw_device;
id->q_format = QDIO_ZFCP_QFMT;
memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
ASCEBC(id->adapter_name, 8);
id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
- id->qib_param_field_format = 0;
- id->qib_param_field = NULL;
- id->input_slib_elements = NULL;
- id->output_slib_elements = NULL;
id->no_input_qs = 1;
id->no_output_qs = 1;
id->input_handler = zfcp_qdio_int_resp;
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 1690e53fb84a..deeffe17a002 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -162,6 +162,7 @@ static const struct file_operations d7s_fops = {
.compat_ioctl = d7s_ioctl,
.open = d7s_open,
.release = d7s_release,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice d7s_miscdev = {
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 078e5f4520ef..38a069c9fe81 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -720,6 +720,7 @@ static const struct file_operations envctrl_fops = {
#endif
.open = envctrl_open,
.release = envctrl_release,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static struct miscdevice envctrl_dev = {
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 4942050dc5b6..13f48e28a1e1 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -27,7 +27,7 @@
*/
#include <linux/module.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -68,6 +68,8 @@
#define JSF_PART_BITS 2 /* 2 bits of minors to cover JSF_NPART */
#define JSF_PART_MASK 0x3 /* 2 bits mask */
+static DEFINE_MUTEX(jsf_mutex);
+
/*
* Access functions.
* We could ioremap(), but it's easier this way.
@@ -225,7 +227,7 @@ static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
{
loff_t ret;
- lock_kernel();
+ mutex_lock(&jsf_mutex);
switch (orig) {
case 0:
file->f_pos = offset;
@@ -238,7 +240,7 @@ static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
default:
ret = -EINVAL;
}
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return ret;
}
@@ -384,18 +386,18 @@ static int jsf_ioctl_program(void __user *arg)
static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
- lock_kernel();
+ mutex_lock(&jsf_mutex);
int error = -ENOTTY;
void __user *argp = (void __user *)arg;
if (!capable(CAP_SYS_ADMIN)) {
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return -EPERM;
}
switch (cmd) {
case JSFLASH_IDENT:
if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) {
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return -EFAULT;
}
break;
@@ -407,7 +409,7 @@ static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
break;
}
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return error;
}
@@ -418,17 +420,17 @@ static int jsf_mmap(struct file * file, struct vm_area_struct * vma)
static int jsf_open(struct inode * inode, struct file * filp)
{
- lock_kernel();
+ mutex_lock(&jsf_mutex);
if (jsf0.base == 0) {
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return -ENXIO;
}
if (test_and_set_bit(0, (void *)&jsf0.busy) != 0) {
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return -EBUSY;
}
- unlock_kernel();
+ mutex_unlock(&jsf_mutex);
return 0; /* XXX What security? */
}
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index e20b7bdd4c78..13fc15642070 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -92,7 +92,6 @@
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -105,6 +104,7 @@
/* Globals */
#define TW_DRIVER_VERSION "2.26.02.014"
+static DEFINE_MUTEX(twa_chrdev_mutex);
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count;
static int twa_major = -1;
@@ -222,7 +222,8 @@ static const struct file_operations twa_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = twa_chrdev_ioctl,
.open = twa_chrdev_open,
- .release = NULL
+ .release = NULL,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* This function will complete an aen request from the isr */
@@ -658,7 +659,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
int retval = TW_IOCTL_ERROR_OS_EFAULT;
void __user *argp = (void __user *)arg;
- lock_kernel();
+ mutex_lock(&twa_chrdev_mutex);
/* Only let one of these through at a time */
if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
@@ -879,7 +880,7 @@ out3:
out2:
mutex_unlock(&tw_dev->ioctl_lock);
out:
- unlock_kernel();
+ mutex_unlock(&twa_chrdev_mutex);
return retval;
} /* End twa_chrdev_ioctl() */
@@ -890,7 +891,6 @@ static int twa_chrdev_open(struct inode *inode, struct file *file)
unsigned int minor_number;
int retval = TW_IOCTL_ERROR_OS_ENODEV;
- cycle_kernel_lock();
minor_number = iminor(inode);
if (minor_number >= twa_device_extension_count)
goto out;
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index f481e734aad4..7039de3257e2 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -64,7 +64,6 @@
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -77,6 +76,7 @@
/* Globals */
#define TW_DRIVER_VERSION "3.26.02.000"
+static DEFINE_MUTEX(twl_chrdev_mutex);
static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
static unsigned int twl_device_extension_count;
static int twl_major = -1;
@@ -764,7 +764,7 @@ static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
int retval = -EFAULT;
void __user *argp = (void __user *)arg;
- lock_kernel();
+ mutex_lock(&twl_chrdev_mutex);
/* Only let one of these through at a time */
if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
@@ -861,7 +861,7 @@ out3:
out2:
mutex_unlock(&tw_dev->ioctl_lock);
out:
- unlock_kernel();
+ mutex_unlock(&twl_chrdev_mutex);
return retval;
} /* End twl_chrdev_ioctl() */
@@ -876,7 +876,6 @@ static int twl_chrdev_open(struct inode *inode, struct file *file)
goto out;
}
- cycle_kernel_lock();
minor_number = iminor(inode);
if (minor_number >= twl_device_extension_count)
goto out;
@@ -890,7 +889,8 @@ static const struct file_operations twl_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = twl_chrdev_ioctl,
.open = twl_chrdev_open,
- .release = NULL
+ .release = NULL,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* This function passes sense data from firmware to scsi layer */
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 30d735ad35b5..71b5162aa317 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -199,7 +199,6 @@
#include <linux/module.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
@@ -221,6 +220,7 @@
/* Globals */
#define TW_DRIVER_VERSION "1.26.02.003"
+static DEFINE_MUTEX(tw_mutex);
static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
static int tw_device_extension_count = 0;
static int twe_major = -1;
@@ -900,10 +900,10 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a
dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
- lock_kernel();
+ mutex_lock(&tw_mutex);
/* Only let one of these through at a time */
if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
- unlock_kernel();
+ mutex_unlock(&tw_mutex);
return -EINTR;
}
@@ -1034,7 +1034,7 @@ out2:
dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
out:
mutex_unlock(&tw_dev->ioctl_lock);
- unlock_kernel();
+ mutex_unlock(&tw_mutex);
return retval;
} /* End tw_chrdev_ioctl() */
@@ -1044,7 +1044,6 @@ static int tw_chrdev_open(struct inode *inode, struct file *file)
{
unsigned int minor_number;
- cycle_kernel_lock();
dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
minor_number = iminor(inode);
@@ -1059,7 +1058,8 @@ static const struct file_operations tw_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tw_chrdev_ioctl,
.open = tw_chrdev_open,
- .release = NULL
+ .release = NULL,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* This function will free up device extension resources */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index bbf91aec64f5..2e9632e2c98b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -316,7 +316,8 @@ config SCSI_ISCSI_ATTRS
config SCSI_SAS_ATTRS
tristate "SAS Transport Attributes"
- depends on SCSI && BLK_DEV_BSG
+ depends on SCSI
+ select BLK_DEV_BSG
help
If you wish to export transport-specific information about
each attached SAS device to sysfs, say Y.
@@ -378,7 +379,7 @@ config ISCSI_BOOT_SYSFS
via sysfs to userspace. If you wish to export this information,
say Y. Otherwise, say N.
-source "drivers/scsi/cxgb3i/Kconfig"
+source "drivers/scsi/cxgbi/Kconfig"
source "drivers/scsi/bnx2i/Kconfig"
source "drivers/scsi/be2iscsi/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 2703c6ec5e36..2e9a87e8e7d8 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -133,7 +133,8 @@ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o
obj-$(CONFIG_SCSI_MVSAS) += mvsas/
obj-$(CONFIG_PS3_ROM) += ps3rom.o
-obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/
+obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgbi/
+obj-$(CONFIG_SCSI_CXGB4_ISCSI) += libiscsi.o libiscsi_tcp.o cxgbi/
obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index cad6f9abaeb9..5faacf431db2 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -38,7 +38,7 @@
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/delay.h>
@@ -76,6 +76,7 @@ MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
MODULE_LICENSE("GPL");
MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
+static DEFINE_MUTEX(aac_mutex);
static LIST_HEAD(aac_devices);
static int aac_cfg_major = -1;
char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
@@ -678,7 +679,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
unsigned minor_number = iminor(inode);
int err = -ENODEV;
- lock_kernel(); /* BKL pushdown: nothing else protects this list */
+ mutex_lock(&aac_mutex); /* BKL pushdown: nothing else protects this list */
list_for_each_entry(aac, &aac_devices, entry) {
if (aac->id == minor_number) {
file->private_data = aac;
@@ -686,7 +687,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
break;
}
}
- unlock_kernel();
+ mutex_unlock(&aac_mutex);
return err;
}
@@ -711,9 +712,9 @@ static long aac_cfg_ioctl(struct file *file,
int ret;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
- lock_kernel();
+ mutex_lock(&aac_mutex);
ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
- unlock_kernel();
+ mutex_unlock(&aac_mutex);
return ret;
}
@@ -722,7 +723,7 @@ static long aac_cfg_ioctl(struct file *file,
static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&aac_mutex);
switch (cmd) {
case FSACTL_MINIPORT_REV_CHECK:
case FSACTL_SENDFIB:
@@ -756,7 +757,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
ret = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
+ mutex_unlock(&aac_mutex);
return ret;
}
@@ -1039,6 +1040,7 @@ static const struct file_operations aac_cfg_fops = {
.compat_ioctl = aac_compat_cfg_ioctl,
#endif
.open = aac_cfg_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct scsi_host_template aac_driver_template = {
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 93984c9dfe14..e1cd6062776c 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -2850,12 +2850,6 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
aic_dev->r_total++;
ptr = aic_dev->r_bins;
}
- if(cmd->device->simple_tags && cmd->request->cmd_flags & REQ_HARDBARRIER)
- {
- aic_dev->barrier_total++;
- if(scb->tag_action == MSG_ORDERED_Q_TAG)
- aic_dev->ordered_total++;
- }
x = scb->sg_length;
x >>= 10;
for(i=0; i<6; i++)
@@ -10144,19 +10138,8 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
/* We always force TEST_UNIT_READY to untagged */
if (cmd->cmnd[0] != TEST_UNIT_READY && sdptr->simple_tags)
{
- if (req->cmd_flags & REQ_HARDBARRIER)
- {
- if(sdptr->ordered_tags)
- {
- hscb->control |= MSG_ORDERED_Q_TAG;
- scb->tag_action = MSG_ORDERED_Q_TAG;
- }
- }
- else
- {
- hscb->control |= MSG_SIMPLE_Q_TAG;
- scb->tag_action = MSG_SIMPLE_Q_TAG;
- }
+ hscb->control |= MSG_SIMPLE_Q_TAG;
+ scb->tag_action = MSG_SIMPLE_Q_TAG;
}
}
if ( !(aic_dev->dtr_pending) &&
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index c8dc392edd57..05a78e515a24 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -878,8 +878,8 @@ static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb,
if (!error) {
if (acb->devstate[id][lun] == ARECA_RAID_GONE)
acb->devstate[id][lun] = ARECA_RAID_GOOD;
- ccb->pcmd->result = DID_OK << 16;
- arcmsr_ccb_complete(ccb);
+ ccb->pcmd->result = DID_OK << 16;
+ arcmsr_ccb_complete(ccb);
}else{
switch (ccb->arcmsr_cdb.DeviceStatus) {
case ARCMSR_DEV_SELECT_TIMEOUT: {
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 7d4d2275573c..7f11f3e48e12 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -300,8 +300,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf)
{
struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
- int len = 0;
- int status;
+ int status = 0;
SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
switch (param) {
@@ -315,7 +314,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
default:
return iscsi_host_get_param(shost, param, buf);
}
- return len;
+ return status;
}
int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 26350e470bcc..877324fc594c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -368,7 +368,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
memset(req, 0, sizeof(*req));
wrb->tag0 |= tag;
- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 1);
+ be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
sizeof(*req));
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index 00c033511cbf..b6345d91bb66 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -753,7 +753,7 @@ extern int bnx2i_send_iscsi_tmf(struct bnx2i_conn *conn,
extern int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *conn,
struct bnx2i_cmd *cmnd);
extern int bnx2i_send_iscsi_nopout(struct bnx2i_conn *conn,
- struct iscsi_task *mtask, u32 ttt,
+ struct iscsi_task *mtask,
char *datap, int data_len, int unsol);
extern int bnx2i_send_iscsi_logout(struct bnx2i_conn *conn,
struct iscsi_task *mtask);
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index d23fc256d585..90cef716b796 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -385,7 +385,6 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
struct bnx2i_cmd *bnx2i_cmd;
struct bnx2i_tmf_request *tmfabort_wqe;
u32 dword;
- u32 scsi_lun[2];
bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data;
tmfabort_hdr = (struct iscsi_tm *)mtask->hdr;
@@ -393,38 +392,41 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
bnx2i_conn->ep->qp.sq_prod_qe;
tmfabort_wqe->op_code = tmfabort_hdr->opcode;
- tmfabort_wqe->op_attr = 0;
- tmfabort_wqe->op_attr =
- ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK;
+ tmfabort_wqe->op_attr = tmfabort_hdr->flags;
tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14));
tmfabort_wqe->reserved2 = 0;
tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn);
- ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
- if (!ctask || !ctask->sc)
- /*
- * the iscsi layer must have completed the cmd while this
- * was starting up.
- *
- * Note: In the case of a SCSI cmd timeout, the task's sc
- * is still active; hence ctask->sc != 0
- * In this case, the task must be aborted
- */
- return 0;
-
- ref_sc = ctask->sc;
-
- /* Retrieve LUN directly from the ref_sc */
- int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun);
- tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]);
- tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]);
-
- if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
- dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT);
- else
- dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT);
- tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK));
+ switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) {
+ case ISCSI_TM_FUNC_ABORT_TASK:
+ case ISCSI_TM_FUNC_TASK_REASSIGN:
+ ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
+ if (!ctask || !ctask->sc)
+ /*
+ * the iscsi layer must have completed the cmd while
+ * was starting up.
+ *
+ * Note: In the case of a SCSI cmd timeout, the task's
+ * sc is still active; hence ctask->sc != 0
+ * In this case, the task must be aborted
+ */
+ return 0;
+
+ ref_sc = ctask->sc;
+ if (ref_sc->sc_data_direction == DMA_TO_DEVICE)
+ dword = (ISCSI_TASK_TYPE_WRITE <<
+ ISCSI_CMD_REQUEST_TYPE_SHIFT);
+ else
+ dword = (ISCSI_TASK_TYPE_READ <<
+ ISCSI_CMD_REQUEST_TYPE_SHIFT);
+ tmfabort_wqe->ref_itt = (dword |
+ (tmfabort_hdr->rtt & ISCSI_ITT_MASK));
+ break;
+ default:
+ tmfabort_wqe->ref_itt = RESERVED_ITT;
+ }
+ memcpy(tmfabort_wqe->lun, tmfabort_hdr->lun, sizeof(struct scsi_lun));
tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn);
tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma;
@@ -464,7 +466,6 @@ int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *bnx2i_conn,
* @conn: iscsi connection
* @cmd: driver command structure which is requesting
* a WQE to sent to chip for further processing
- * @ttt: TTT to be used when building pdu header
* @datap: payload buffer pointer
* @data_len: payload data length
* @unsol: indicated whether nopout pdu is unsolicited pdu or
@@ -473,7 +474,7 @@ int bnx2i_send_iscsi_scsicmd(struct bnx2i_conn *bnx2i_conn,
* prepare and post a nopout request WQE to CNIC firmware
*/
int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
- struct iscsi_task *task, u32 ttt,
+ struct iscsi_task *task,
char *datap, int data_len, int unsol)
{
struct bnx2i_endpoint *ep = bnx2i_conn->ep;
@@ -498,7 +499,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
nopout_wqe->itt = ((u16)task->itt |
(ISCSI_TASK_TYPE_MPATH <<
ISCSI_TMF_REQUEST_TYPE_SHIFT));
- nopout_wqe->ttt = ttt;
+ nopout_wqe->ttt = nopout_hdr->ttt;
nopout_wqe->flags = 0;
if (!unsol)
nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index a796f565f383..50c2aa3b8eb1 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -17,15 +17,17 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
static u32 adapter_count;
#define DRV_MODULE_NAME "bnx2i"
-#define DRV_MODULE_VERSION "2.1.2"
-#define DRV_MODULE_RELDATE "Jun 28, 2010"
+#define DRV_MODULE_VERSION "2.1.3"
+#define DRV_MODULE_RELDATE "Aug 10, 2010"
static char version[] __devinitdata =
"Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com>");
+MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com> and "
+ "Eddie Wai <eddie.wai@broadcom.com>");
+
MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711"
" iSCSI Driver");
MODULE_LICENSE("GPL");
@@ -167,6 +169,38 @@ void bnx2i_start(void *handle)
/**
+ * bnx2i_chip_cleanup - local routine to handle chip cleanup
+ * @hba: Adapter instance to register
+ *
+ * Driver checks if adapter still has any active connections before
+ * executing the cleanup process
+ */
+static void bnx2i_chip_cleanup(struct bnx2i_hba *hba)
+{
+ struct bnx2i_endpoint *bnx2i_ep;
+ struct list_head *pos, *tmp;
+
+ if (hba->ofld_conns_active) {
+ /* Stage to force the disconnection
+ * This is the case where the daemon is either slow or
+ * not present
+ */
+ printk(KERN_ALERT "bnx2i: (%s) chip cleanup for %d active "
+ "connections\n", hba->netdev->name,
+ hba->ofld_conns_active);
+ mutex_lock(&hba->net_dev_lock);
+ list_for_each_safe(pos, tmp, &hba->ep_active_list) {
+ bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
+ /* Clean up the chip only */
+ bnx2i_hw_ep_disconnect(bnx2i_ep);
+ bnx2i_ep->cm_sk = NULL;
+ }
+ mutex_unlock(&hba->net_dev_lock);
+ }
+}
+
+
+/**
* bnx2i_stop - cnic callback to shutdown adapter instance
* @handle: transparent handle pointing to adapter structure
*
@@ -176,8 +210,6 @@ void bnx2i_start(void *handle)
void bnx2i_stop(void *handle)
{
struct bnx2i_hba *hba = handle;
- struct list_head *pos, *tmp;
- struct bnx2i_endpoint *bnx2i_ep;
int conns_active;
/* check if cleanup happened in GOING_DOWN context */
@@ -198,24 +230,7 @@ void bnx2i_stop(void *handle)
if (hba->ofld_conns_active == conns_active)
break;
}
- if (hba->ofld_conns_active) {
- /* Stage to force the disconnection
- * This is the case where the daemon is either slow or
- * not present
- */
- printk(KERN_ALERT "bnx2i: Wait timeout, force all eps "
- "to disconnect (%d)\n", hba->ofld_conns_active);
- mutex_lock(&hba->net_dev_lock);
- list_for_each_safe(pos, tmp, &hba->ep_active_list) {
- bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
- /* Clean up the chip only */
- bnx2i_hw_ep_disconnect(bnx2i_ep);
- }
- mutex_unlock(&hba->net_dev_lock);
- if (hba->ofld_conns_active)
- printk(KERN_ERR "bnx2i: EP disconnect timeout (%d)!\n",
- hba->ofld_conns_active);
- }
+ bnx2i_chip_cleanup(hba);
/* This flag should be cleared last so that ep_disconnect() gracefully
* cleans up connection context
@@ -457,6 +472,7 @@ static void __exit bnx2i_mod_exit(void)
adapter_count--;
if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
+ bnx2i_chip_cleanup(hba);
hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
}
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index a46ccc380ab1..fb50efbce087 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1078,11 +1078,9 @@ static int bnx2i_iscsi_send_generic_request(struct iscsi_task *task)
buf = bnx2i_conn->gen_pdu.req_buf;
if (data_len)
rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task,
- RESERVED_ITT,
buf, data_len, 1);
else
rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task,
- RESERVED_ITT,
NULL, 0, 1);
break;
case ISCSI_OP_LOGOUT:
@@ -1955,6 +1953,9 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
if (!cnic)
return 0;
+ if (bnx2i_ep->state == EP_STATE_IDLE)
+ return 0;
+
if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
goto destroy_conn;
@@ -1998,11 +1999,13 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
else
close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
+ /* No longer allow CFC delete if cm_close/abort fails the request */
if (close_ret)
- bnx2i_ep->state = EP_STATE_DISCONN_COMPL;
-
- /* wait for option-2 conn teardown */
- wait_event_interruptible(bnx2i_ep->ofld_wait,
+ printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n",
+ bnx2i_ep->hba->netdev->name, close, close_ret);
+ else
+ /* wait for option-2 conn teardown */
+ wait_event_interruptible(bnx2i_ep->ofld_wait,
bnx2i_ep->state != EP_STATE_DISCONN_START);
if (signal_pending(current))
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index d6532187f616..a07385a00b8a 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -22,7 +22,6 @@
#include <linux/chio.h> /* here are all the ioctls */
#include <linux/mutex.h>
#include <linux/idr.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -44,6 +43,7 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(SCSI_CHANGER_MAJOR);
MODULE_ALIAS_SCSI_DEVICE(TYPE_MEDIUM_CHANGER);
+static DEFINE_MUTEX(ch_mutex);
static int init = 1;
module_param(init, int, 0444);
MODULE_PARM_DESC(init, \
@@ -581,19 +581,19 @@ ch_open(struct inode *inode, struct file *file)
scsi_changer *ch;
int minor = iminor(inode);
- lock_kernel();
+ mutex_lock(&ch_mutex);
spin_lock(&ch_index_lock);
ch = idr_find(&ch_index_idr, minor);
if (NULL == ch || scsi_device_get(ch->device)) {
spin_unlock(&ch_index_lock);
- unlock_kernel();
+ mutex_unlock(&ch_mutex);
return -ENXIO;
}
spin_unlock(&ch_index_lock);
file->private_data = ch;
- unlock_kernel();
+ mutex_unlock(&ch_mutex);
return 0;
}
@@ -981,6 +981,7 @@ static const struct file_operations changer_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = ch_ioctl_compat,
#endif
+ .llseek = noop_llseek,/* no read or write fn */
};
static int __init init_ch_module(void)
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index cd05e049d5f6..d0c82340f0e2 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1404,13 +1404,13 @@ void scsi_print_sense(char *name, struct scsi_cmnd *cmd)
{
struct scsi_sense_hdr sshdr;
- scmd_printk(KERN_INFO, cmd, "");
+ scmd_printk(KERN_INFO, cmd, " ");
scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
&sshdr);
scsi_show_sense_hdr(&sshdr);
scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
&sshdr);
- scmd_printk(KERN_INFO, cmd, "");
+ scmd_printk(KERN_INFO, cmd, " ");
scsi_show_extd_sense(sshdr.asc, sshdr.ascq);
}
EXPORT_SYMBOL(scsi_print_sense);
@@ -1453,7 +1453,7 @@ EXPORT_SYMBOL(scsi_show_result);
void scsi_print_result(struct scsi_cmnd *cmd)
{
- scmd_printk(KERN_INFO, cmd, "");
+ scmd_printk(KERN_INFO, cmd, " ");
scsi_show_result(cmd->result);
}
EXPORT_SYMBOL(scsi_print_result);
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
deleted file mode 100644
index e3133b58e594..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * cxgb3i.h: Chelsio S3xx iSCSI driver.
- *
- * Copyright (c) 2008 Chelsio Communications, 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.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#ifndef __CXGB3I_H__
-#define __CXGB3I_H__
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/netdevice.h>
-#include <linux/scatterlist.h>
-#include <linux/skbuff.h>
-#include <scsi/libiscsi_tcp.h>
-
-/* from cxgb3 LLD */
-#include "common.h"
-#include "t3_cpl.h"
-#include "t3cdev.h"
-#include "cxgb3_ctl_defs.h"
-#include "cxgb3_offload.h"
-#include "firmware_exports.h"
-
-#include "cxgb3i_offload.h"
-#include "cxgb3i_ddp.h"
-
-#define CXGB3I_SCSI_HOST_QDEPTH 1024
-#define CXGB3I_MAX_TARGET CXGB3I_MAX_CONN
-#define CXGB3I_MAX_LUN 512
-#define ISCSI_PDU_NONPAYLOAD_MAX \
- (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + 2*ISCSI_DIGEST_SIZE)
-
-struct cxgb3i_adapter;
-struct cxgb3i_hba;
-struct cxgb3i_endpoint;
-
-/**
- * struct cxgb3i_hba - cxgb3i iscsi structure (per port)
- *
- * @snic: cxgb3i adapter containing this port
- * @ndev: pointer to netdev structure
- * @shost: pointer to scsi host structure
- */
-struct cxgb3i_hba {
- struct cxgb3i_adapter *snic;
- struct net_device *ndev;
- struct Scsi_Host *shost;
-};
-
-/**
- * struct cxgb3i_adapter - cxgb3i adapter structure (per pci)
- *
- * @listhead: list head to link elements
- * @lock: lock for this structure
- * @tdev: pointer to t3cdev used by cxgb3 driver
- * @pdev: pointer to pci dev
- * @hba_cnt: # of hbas (the same as # of ports)
- * @hba: all the hbas on this adapter
- * @flags: bit flag for adapter event/status
- * @tx_max_size: max. tx packet size supported
- * @rx_max_size: max. rx packet size supported
- * @tag_format: ddp tag format settings
- */
-#define CXGB3I_ADAPTER_FLAG_RESET 0x1
-struct cxgb3i_adapter {
- struct list_head list_head;
- spinlock_t lock;
- struct t3cdev *tdev;
- struct pci_dev *pdev;
- unsigned char hba_cnt;
- struct cxgb3i_hba *hba[MAX_NPORTS];
-
- unsigned int flags;
- unsigned int tx_max_size;
- unsigned int rx_max_size;
-
- struct cxgb3i_tag_format tag_format;
-};
-
-/**
- * struct cxgb3i_conn - cxgb3i iscsi connection
- *
- * @listhead: list head to link elements
- * @cep: pointer to iscsi_endpoint structure
- * @conn: pointer to iscsi_conn structure
- * @hba: pointer to the hba this conn. is going through
- * @task_idx_bits: # of bits needed for session->cmds_max
- */
-struct cxgb3i_conn {
- struct list_head list_head;
- struct cxgb3i_endpoint *cep;
- struct iscsi_conn *conn;
- struct cxgb3i_hba *hba;
- unsigned int task_idx_bits;
-};
-
-/**
- * struct cxgb3i_endpoint - iscsi tcp endpoint
- *
- * @c3cn: the h/w tcp connection representation
- * @hba: pointer to the hba this conn. is going through
- * @cconn: pointer to the associated cxgb3i iscsi connection
- */
-struct cxgb3i_endpoint {
- struct s3_conn *c3cn;
- struct cxgb3i_hba *hba;
- 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);
-
-struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *);
-void cxgb3i_adapter_open(struct t3cdev *);
-void cxgb3i_adapter_close(struct t3cdev *);
-
-struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *,
- struct net_device *);
-void cxgb3i_hba_host_remove(struct cxgb3i_hba *);
-
-int cxgb3i_pdu_init(void);
-void cxgb3i_pdu_cleanup(void);
-void cxgb3i_conn_cleanup_task(struct iscsi_task *);
-int cxgb3i_conn_alloc_pdu(struct iscsi_task *, u8);
-int cxgb3i_conn_init_pdu(struct iscsi_task *, unsigned int, unsigned int);
-int cxgb3i_conn_xmit_pdu(struct iscsi_task *);
-
-void cxgb3i_release_itt(struct iscsi_task *task, itt_t hdr_itt);
-int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt);
-
-#endif
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
deleted file mode 100644
index be0e23042c76..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * cxgb3i_ddp.c: Chelsio S3xx iSCSI DDP Manager.
- *
- * Copyright (c) 2008 Chelsio Communications, 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.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/scatterlist.h>
-
-/* from cxgb3 LLD */
-#include "common.h"
-#include "t3_cpl.h"
-#include "t3cdev.h"
-#include "cxgb3_ctl_defs.h"
-#include "cxgb3_offload.h"
-#include "firmware_exports.h"
-
-#include "cxgb3i_ddp.h"
-
-#define ddp_log_error(fmt...) printk(KERN_ERR "cxgb3i_ddp: ERR! " fmt)
-#define ddp_log_warn(fmt...) printk(KERN_WARNING "cxgb3i_ddp: WARN! " fmt)
-#define ddp_log_info(fmt...) printk(KERN_INFO "cxgb3i_ddp: " fmt)
-
-#ifdef __DEBUG_CXGB3I_DDP__
-#define ddp_log_debug(fmt, args...) \
- printk(KERN_INFO "cxgb3i_ddp: %s - " fmt, __func__ , ## args)
-#else
-#define ddp_log_debug(fmt...)
-#endif
-
-/*
- * iSCSI Direct Data Placement
- *
- * T3 h/w can directly place the iSCSI Data-In or Data-Out PDU's payload into
- * pre-posted final destination host-memory buffers based on the Initiator
- * Task Tag (ITT) in Data-In or Target Task Tag (TTT) in Data-Out PDUs.
- *
- * The host memory address is programmed into h/w in the format of pagepod
- * entries.
- * The location of the pagepod entry is encoded into ddp tag which is used or
- * is the base for ITT/TTT.
- */
-
-#define DDP_PGIDX_MAX 4
-#define DDP_THRESHOLD 2048
-static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
-static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
-static unsigned char page_idx = DDP_PGIDX_MAX;
-
-/*
- * functions to program the pagepod in h/w
- */
-static inline void ulp_mem_io_set_hdr(struct sk_buff *skb, unsigned int addr)
-{
- struct ulp_mem_io *req = (struct ulp_mem_io *)skb->head;
-
- req->wr.wr_lo = 0;
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS));
- req->cmd_lock_addr = htonl(V_ULP_MEMIO_ADDR(addr >> 5) |
- V_ULPTX_CMD(ULP_MEM_WRITE));
- req->len = htonl(V_ULP_MEMIO_DATA_LEN(PPOD_SIZE >> 5) |
- V_ULPTX_NFLITS((PPOD_SIZE >> 3) + 1));
-}
-
-static int set_ddp_map(struct cxgb3i_ddp_info *ddp, struct pagepod_hdr *hdr,
- unsigned int idx, unsigned int npods,
- struct cxgb3i_gather_list *gl)
-{
- unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
- int i;
-
- for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
- struct sk_buff *skb = ddp->gl_skb[idx];
- struct pagepod *ppod;
- int j, pidx;
-
- /* hold on to the skb until we clear the ddp mapping */
- skb_get(skb);
-
- ulp_mem_io_set_hdr(skb, pm_addr);
- ppod = (struct pagepod *)
- (skb->head + sizeof(struct ulp_mem_io));
- memcpy(&(ppod->hdr), hdr, sizeof(struct pagepod));
- for (pidx = 4 * i, j = 0; j < 5; ++j, ++pidx)
- ppod->addr[j] = pidx < gl->nelem ?
- cpu_to_be64(gl->phys_addr[pidx]) : 0UL;
-
- skb->priority = CPL_PRIORITY_CONTROL;
- cxgb3_ofld_send(ddp->tdev, skb);
- }
- return 0;
-}
-
-static void clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int tag,
- unsigned int idx, unsigned int npods)
-{
- unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
- int i;
-
- for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
- struct sk_buff *skb = ddp->gl_skb[idx];
-
- if (!skb) {
- ddp_log_error("ddp tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
- tag, idx, i, npods);
- continue;
- }
- ddp->gl_skb[idx] = NULL;
- memset((skb->head + sizeof(struct ulp_mem_io)), 0, PPOD_SIZE);
- ulp_mem_io_set_hdr(skb, pm_addr);
- skb->priority = CPL_PRIORITY_CONTROL;
- cxgb3_ofld_send(ddp->tdev, skb);
- }
-}
-
-static inline int ddp_find_unused_entries(struct cxgb3i_ddp_info *ddp,
- unsigned int start, unsigned int max,
- unsigned int count,
- struct cxgb3i_gather_list *gl)
-{
- unsigned int i, j, k;
-
- /* not enough entries */
- if ((max - start) < count)
- return -EBUSY;
-
- max -= count;
- spin_lock(&ddp->map_lock);
- for (i = start; i < max;) {
- for (j = 0, k = i; j < count; j++, k++) {
- if (ddp->gl_map[k])
- break;
- }
- if (j == count) {
- for (j = 0, k = i; j < count; j++, k++)
- ddp->gl_map[k] = gl;
- spin_unlock(&ddp->map_lock);
- return i;
- }
- i += j + 1;
- }
- spin_unlock(&ddp->map_lock);
- return -EBUSY;
-}
-
-static inline void ddp_unmark_entries(struct cxgb3i_ddp_info *ddp,
- int start, int count)
-{
- spin_lock(&ddp->map_lock);
- memset(&ddp->gl_map[start], 0,
- count * sizeof(struct cxgb3i_gather_list *));
- spin_unlock(&ddp->map_lock);
-}
-
-static inline void ddp_free_gl_skb(struct cxgb3i_ddp_info *ddp,
- int idx, int count)
-{
- int i;
-
- for (i = 0; i < count; i++, idx++)
- if (ddp->gl_skb[idx]) {
- kfree_skb(ddp->gl_skb[idx]);
- ddp->gl_skb[idx] = NULL;
- }
-}
-
-static inline int ddp_alloc_gl_skb(struct cxgb3i_ddp_info *ddp, int idx,
- int count, gfp_t gfp)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- struct sk_buff *skb = alloc_skb(sizeof(struct ulp_mem_io) +
- PPOD_SIZE, gfp);
- if (skb) {
- ddp->gl_skb[idx + i] = skb;
- skb_put(skb, sizeof(struct ulp_mem_io) + PPOD_SIZE);
- } else {
- ddp_free_gl_skb(ddp, idx, i);
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-/**
- * cxgb3i_ddp_find_page_index - return ddp page index for a given page size
- * @pgsz: page size
- * return the ddp page index, if no match is found return DDP_PGIDX_MAX.
- */
-int cxgb3i_ddp_find_page_index(unsigned long pgsz)
-{
- int i;
-
- for (i = 0; i < DDP_PGIDX_MAX; i++) {
- if (pgsz == (1UL << ddp_page_shift[i]))
- return i;
- }
- ddp_log_debug("ddp page size 0x%lx not supported.\n", pgsz);
- return DDP_PGIDX_MAX;
-}
-
-/**
- * cxgb3i_ddp_adjust_page_table - adjust page table with PAGE_SIZE
- * return the ddp page index, if no match is found return DDP_PGIDX_MAX.
- */
-int cxgb3i_ddp_adjust_page_table(void)
-{
- int i;
- unsigned int base_order, order;
-
- if (PAGE_SIZE < (1UL << ddp_page_shift[0])) {
- ddp_log_info("PAGE_SIZE 0x%lx too small, min. 0x%lx.\n",
- PAGE_SIZE, 1UL << ddp_page_shift[0]);
- return -EINVAL;
- }
-
- base_order = get_order(1UL << ddp_page_shift[0]);
- order = get_order(1 << PAGE_SHIFT);
- for (i = 0; i < DDP_PGIDX_MAX; i++) {
- /* first is the kernel page size, then just doubling the size */
- ddp_page_order[i] = order - base_order + i;
- ddp_page_shift[i] = PAGE_SHIFT + i;
- }
- return 0;
-}
-
-static inline void ddp_gl_unmap(struct pci_dev *pdev,
- struct cxgb3i_gather_list *gl)
-{
- int i;
-
- for (i = 0; i < gl->nelem; i++)
- pci_unmap_page(pdev, gl->phys_addr[i], PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
-}
-
-static inline int ddp_gl_map(struct pci_dev *pdev,
- struct cxgb3i_gather_list *gl)
-{
- int i;
-
- for (i = 0; i < gl->nelem; i++) {
- gl->phys_addr[i] = pci_map_page(pdev, gl->pages[i], 0,
- PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(pdev, gl->phys_addr[i])))
- goto unmap;
- }
-
- return i;
-
-unmap:
- if (i) {
- unsigned int nelem = gl->nelem;
-
- gl->nelem = i;
- ddp_gl_unmap(pdev, gl);
- gl->nelem = nelem;
- }
- return -ENOMEM;
-}
-
-/**
- * cxgb3i_ddp_make_gl - build ddp page buffer list
- * @xferlen: total buffer length
- * @sgl: page buffer scatter-gather list
- * @sgcnt: # of page buffers
- * @pdev: pci_dev, used for pci map
- * @gfp: allocation mode
- *
- * construct a ddp page buffer list from the scsi scattergather list.
- * coalesce buffers as much as possible, and obtain dma addresses for
- * each page.
- *
- * Return the cxgb3i_gather_list constructed from the page buffers if the
- * memory can be used for ddp. Return NULL otherwise.
- */
-struct cxgb3i_gather_list *cxgb3i_ddp_make_gl(unsigned int xferlen,
- struct scatterlist *sgl,
- unsigned int sgcnt,
- struct pci_dev *pdev,
- gfp_t gfp)
-{
- struct cxgb3i_gather_list *gl;
- struct scatterlist *sg = sgl;
- struct page *sgpage = sg_page(sg);
- unsigned int sglen = sg->length;
- unsigned int sgoffset = sg->offset;
- unsigned int npages = (xferlen + sgoffset + PAGE_SIZE - 1) >>
- PAGE_SHIFT;
- int i = 1, j = 0;
-
- if (xferlen < DDP_THRESHOLD) {
- ddp_log_debug("xfer %u < threshold %u, no ddp.\n",
- xferlen, DDP_THRESHOLD);
- return NULL;
- }
-
- gl = kzalloc(sizeof(struct cxgb3i_gather_list) +
- npages * (sizeof(dma_addr_t) + sizeof(struct page *)),
- gfp);
- if (!gl)
- return NULL;
-
- gl->pages = (struct page **)&gl->phys_addr[npages];
- gl->length = xferlen;
- gl->offset = sgoffset;
- gl->pages[0] = sgpage;
-
- sg = sg_next(sg);
- while (sg) {
- struct page *page = sg_page(sg);
-
- if (sgpage == page && sg->offset == sgoffset + sglen)
- sglen += sg->length;
- else {
- /* make sure the sgl is fit for ddp:
- * each has the same page size, and
- * all of the middle pages are used completely
- */
- if ((j && sgoffset) ||
- ((i != sgcnt - 1) &&
- ((sglen + sgoffset) & ~PAGE_MASK)))
- goto error_out;
-
- j++;
- if (j == gl->nelem || sg->offset)
- goto error_out;
- gl->pages[j] = page;
- sglen = sg->length;
- sgoffset = sg->offset;
- sgpage = page;
- }
- i++;
- sg = sg_next(sg);
- }
- gl->nelem = ++j;
-
- if (ddp_gl_map(pdev, gl) < 0)
- goto error_out;
-
- return gl;
-
-error_out:
- kfree(gl);
- return NULL;
-}
-
-/**
- * cxgb3i_ddp_release_gl - release a page buffer list
- * @gl: a ddp page buffer list
- * @pdev: pci_dev used for pci_unmap
- * free a ddp page buffer list resulted from cxgb3i_ddp_make_gl().
- */
-void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
- struct pci_dev *pdev)
-{
- ddp_gl_unmap(pdev, gl);
- kfree(gl);
-}
-
-/**
- * cxgb3i_ddp_tag_reserve - set up ddp for a data transfer
- * @tdev: t3cdev adapter
- * @tid: connection id
- * @tformat: tag format
- * @tagp: contains s/w tag initially, will be updated with ddp/hw tag
- * @gl: the page momory list
- * @gfp: allocation mode
- *
- * ddp setup for a given page buffer list and construct the ddp tag.
- * return 0 if success, < 0 otherwise.
- */
-int cxgb3i_ddp_tag_reserve(struct t3cdev *tdev, unsigned int tid,
- struct cxgb3i_tag_format *tformat, u32 *tagp,
- struct cxgb3i_gather_list *gl, gfp_t gfp)
-{
- struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
- struct pagepod_hdr hdr;
- unsigned int npods;
- int idx = -1;
- int err = -ENOMEM;
- u32 sw_tag = *tagp;
- u32 tag;
-
- if (page_idx >= DDP_PGIDX_MAX || !ddp || !gl || !gl->nelem ||
- gl->length < DDP_THRESHOLD) {
- ddp_log_debug("pgidx %u, xfer %u/%u, NO ddp.\n",
- page_idx, gl->length, DDP_THRESHOLD);
- return -EINVAL;
- }
-
- npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
-
- if (ddp->idx_last == ddp->nppods)
- idx = ddp_find_unused_entries(ddp, 0, ddp->nppods, npods, gl);
- else {
- idx = ddp_find_unused_entries(ddp, ddp->idx_last + 1,
- ddp->nppods, npods, gl);
- if (idx < 0 && ddp->idx_last >= npods) {
- idx = ddp_find_unused_entries(ddp, 0,
- min(ddp->idx_last + npods, ddp->nppods),
- npods, gl);
- }
- }
- if (idx < 0) {
- ddp_log_debug("xferlen %u, gl %u, npods %u NO DDP.\n",
- gl->length, gl->nelem, npods);
- return idx;
- }
-
- err = ddp_alloc_gl_skb(ddp, idx, npods, gfp);
- if (err < 0)
- goto unmark_entries;
-
- tag = cxgb3i_ddp_tag_base(tformat, sw_tag);
- tag |= idx << PPOD_IDX_SHIFT;
-
- hdr.rsvd = 0;
- hdr.vld_tid = htonl(F_PPOD_VALID | V_PPOD_TID(tid));
- hdr.pgsz_tag_clr = htonl(tag & ddp->rsvd_tag_mask);
- hdr.maxoffset = htonl(gl->length);
- hdr.pgoffset = htonl(gl->offset);
-
- err = set_ddp_map(ddp, &hdr, idx, npods, gl);
- if (err < 0)
- goto free_gl_skb;
-
- ddp->idx_last = idx;
- ddp_log_debug("xfer %u, gl %u,%u, tid 0x%x, 0x%x -> 0x%x(%u,%u).\n",
- gl->length, gl->nelem, gl->offset, tid, sw_tag, tag,
- idx, npods);
- *tagp = tag;
- return 0;
-
-free_gl_skb:
- ddp_free_gl_skb(ddp, idx, npods);
-unmark_entries:
- ddp_unmark_entries(ddp, idx, npods);
- return err;
-}
-
-/**
- * cxgb3i_ddp_tag_release - release a ddp tag
- * @tdev: t3cdev adapter
- * @tag: ddp tag
- * ddp cleanup for a given ddp tag and release all the resources held
- */
-void cxgb3i_ddp_tag_release(struct t3cdev *tdev, u32 tag)
-{
- struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
- u32 idx;
-
- if (!ddp) {
- ddp_log_error("release ddp tag 0x%x, ddp NULL.\n", tag);
- return;
- }
-
- idx = (tag >> PPOD_IDX_SHIFT) & ddp->idx_mask;
- if (idx < ddp->nppods) {
- struct cxgb3i_gather_list *gl = ddp->gl_map[idx];
- unsigned int npods;
-
- if (!gl || !gl->nelem) {
- ddp_log_error("release 0x%x, idx 0x%x, gl 0x%p, %u.\n",
- tag, idx, gl, gl ? gl->nelem : 0);
- return;
- }
- npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
- ddp_log_debug("ddp tag 0x%x, release idx 0x%x, npods %u.\n",
- tag, idx, npods);
- clear_ddp_map(ddp, tag, idx, npods);
- ddp_unmark_entries(ddp, idx, npods);
- cxgb3i_ddp_release_gl(gl, ddp->pdev);
- } else
- ddp_log_error("ddp tag 0x%x, idx 0x%x > max 0x%x.\n",
- tag, idx, ddp->nppods);
-}
-
-static int setup_conn_pgidx(struct t3cdev *tdev, unsigned int tid, int pg_idx,
- int reply)
-{
- struct sk_buff *skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
- GFP_KERNEL);
- struct cpl_set_tcb_field *req;
- u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
-
- if (!skb)
- return -ENOMEM;
-
- /* set up ulp submode and page size */
- req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req));
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
- req->wr.wr_lo = 0;
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
- req->reply = V_NO_REPLY(reply ? 0 : 1);
- req->cpu_idx = 0;
- req->word = htons(31);
- req->mask = cpu_to_be64(0xF0000000);
- req->val = cpu_to_be64(val << 28);
- skb->priority = CPL_PRIORITY_CONTROL;
-
- cxgb3_ofld_send(tdev, skb);
- return 0;
-}
-
-/**
- * cxgb3i_setup_conn_host_pagesize - setup the conn.'s ddp page size
- * @tdev: t3cdev adapter
- * @tid: connection id
- * @reply: request reply from h/w
- * set up the ddp page size based on the host PAGE_SIZE for a connection
- * identified by tid
- */
-int cxgb3i_setup_conn_host_pagesize(struct t3cdev *tdev, unsigned int tid,
- int reply)
-{
- return setup_conn_pgidx(tdev, tid, page_idx, reply);
-}
-
-/**
- * cxgb3i_setup_conn_pagesize - setup the conn.'s ddp page size
- * @tdev: t3cdev adapter
- * @tid: connection id
- * @reply: request reply from h/w
- * @pgsz: ddp page size
- * set up the ddp page size for a connection identified by tid
- */
-int cxgb3i_setup_conn_pagesize(struct t3cdev *tdev, unsigned int tid,
- int reply, unsigned long pgsz)
-{
- int pgidx = cxgb3i_ddp_find_page_index(pgsz);
-
- return setup_conn_pgidx(tdev, tid, pgidx, reply);
-}
-
-/**
- * cxgb3i_setup_conn_digest - setup conn. digest setting
- * @tdev: t3cdev adapter
- * @tid: connection id
- * @hcrc: header digest enabled
- * @dcrc: data digest enabled
- * @reply: request reply from h/w
- * set up the iscsi digest settings for a connection identified by tid
- */
-int cxgb3i_setup_conn_digest(struct t3cdev *tdev, unsigned int tid,
- int hcrc, int dcrc, int reply)
-{
- struct sk_buff *skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
- GFP_KERNEL);
- struct cpl_set_tcb_field *req;
- u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0);
-
- if (!skb)
- return -ENOMEM;
-
- /* set up ulp submode and page size */
- req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req));
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
- req->wr.wr_lo = 0;
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
- req->reply = V_NO_REPLY(reply ? 0 : 1);
- req->cpu_idx = 0;
- req->word = htons(31);
- req->mask = cpu_to_be64(0x0F000000);
- req->val = cpu_to_be64(val << 24);
- skb->priority = CPL_PRIORITY_CONTROL;
-
- cxgb3_ofld_send(tdev, skb);
- return 0;
-}
-
-
-/**
- * cxgb3i_adapter_ddp_info - read the adapter's ddp information
- * @tdev: t3cdev adapter
- * @tformat: tag format
- * @txsz: max tx pdu payload size, filled in by this func.
- * @rxsz: max rx pdu payload size, filled in by this func.
- * setup the tag format for a given iscsi entity
- */
-int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
- struct cxgb3i_tag_format *tformat,
- unsigned int *txsz, unsigned int *rxsz)
-{
- struct cxgb3i_ddp_info *ddp;
- unsigned char idx_bits;
-
- if (!tformat)
- return -EINVAL;
-
- if (!tdev->ulp_iscsi)
- return -EINVAL;
-
- ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
-
- idx_bits = 32 - tformat->sw_bits;
- tformat->rsvd_bits = ddp->idx_bits;
- tformat->rsvd_shift = PPOD_IDX_SHIFT;
- tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
-
- ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
- tformat->sw_bits, tformat->rsvd_bits,
- tformat->rsvd_shift, tformat->rsvd_mask);
-
- *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;
-}
-
-/**
- * cxgb3i_ddp_cleanup - release the cxgb3 adapter's ddp resource
- * @tdev: t3cdev adapter
- * release all the resource held by the ddp pagepod manager for a given
- * adapter if needed
- */
-
-static void ddp_cleanup(struct kref *kref)
-{
- struct cxgb3i_ddp_info *ddp = container_of(kref,
- struct cxgb3i_ddp_info,
- refcnt);
- int i = 0;
-
- ddp_log_info("kref release ddp 0x%p, t3dev 0x%p.\n", ddp, ddp->tdev);
-
- ddp->tdev->ulp_iscsi = NULL;
- while (i < ddp->nppods) {
- struct cxgb3i_gather_list *gl = ddp->gl_map[i];
- if (gl) {
- int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
- >> PPOD_PAGES_SHIFT;
- ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
- ddp->tdev, i, npods);
- kfree(gl);
- ddp_free_gl_skb(ddp, i, npods);
- i += npods;
- } else
- i++;
- }
- cxgb3i_free_big_mem(ddp);
-}
-
-void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
-{
- struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
-
- ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
- if (ddp)
- kref_put(&ddp->refcnt, ddp_cleanup);
-}
-
-/**
- * ddp_init - initialize the cxgb3 adapter's ddp resource
- * @tdev: t3cdev adapter
- * initialize the ddp pagepod manager for a given adapter
- */
-static void ddp_init(struct t3cdev *tdev)
-{
- struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
- struct ulp_iscsi_info uinfo;
- unsigned int ppmax, bits;
- int i, err;
-
- if (ddp) {
- kref_get(&ddp->refcnt);
- ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
- tdev, tdev->ulp_iscsi);
- return;
- }
-
- err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
- if (err < 0) {
- ddp_log_error("%s, failed to get iscsi param err=%d.\n",
- tdev->name, err);
- return;
- }
-
- ppmax = (uinfo.ulimit - uinfo.llimit + 1) >> PPOD_SIZE_SHIFT;
- bits = __ilog2_u32(ppmax) + 1;
- if (bits > PPOD_IDX_MAX_SIZE)
- bits = PPOD_IDX_MAX_SIZE;
- ppmax = (1 << (bits - 1)) - 1;
-
- ddp = cxgb3i_alloc_big_mem(sizeof(struct cxgb3i_ddp_info) +
- ppmax *
- (sizeof(struct cxgb3i_gather_list *) +
- sizeof(struct sk_buff *)),
- GFP_KERNEL);
- if (!ddp) {
- ddp_log_warn("%s unable to alloc ddp 0x%d, ddp disabled.\n",
- tdev->name, ppmax);
- return;
- }
- ddp->gl_map = (struct cxgb3i_gather_list **)(ddp + 1);
- ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
- ppmax *
- sizeof(struct cxgb3i_gather_list *));
- spin_lock_init(&ddp->map_lock);
- kref_init(&ddp->refcnt);
-
- ddp->tdev = tdev;
- ddp->pdev = uinfo.pdev;
- ddp->max_txsz = min_t(unsigned int, uinfo.max_txsz, ULP2_MAX_PKT_SIZE);
- ddp->max_rxsz = min_t(unsigned int, uinfo.max_rxsz, ULP2_MAX_PKT_SIZE);
- ddp->llimit = uinfo.llimit;
- ddp->ulimit = uinfo.ulimit;
- ddp->nppods = ppmax;
- ddp->idx_last = ppmax;
- ddp->idx_bits = bits;
- ddp->idx_mask = (1 << bits) - 1;
- ddp->rsvd_tag_mask = (1 << (bits + PPOD_IDX_SHIFT)) - 1;
-
- uinfo.tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
- for (i = 0; i < DDP_PGIDX_MAX; i++)
- uinfo.pgsz_factor[i] = ddp_page_order[i];
- uinfo.ulimit = uinfo.llimit + (ppmax << PPOD_SIZE_SHIFT);
-
- err = tdev->ctl(tdev, ULP_ISCSI_SET_PARAMS, &uinfo);
- if (err < 0) {
- ddp_log_warn("%s unable to set iscsi param err=%d, "
- "ddp disabled.\n", tdev->name, err);
- goto free_ddp_map;
- }
-
- tdev->ulp_iscsi = ddp;
-
- ddp_log_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u,"
- " %u/%u.\n",
- tdev, ppmax, ddp->idx_bits, ddp->idx_mask,
- ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
- ddp->max_rxsz, uinfo.max_rxsz);
- return;
-
-free_ddp_map:
- cxgb3i_free_big_mem(ddp);
-}
-
-/**
- * cxgb3i_ddp_init - initialize ddp functions
- */
-void cxgb3i_ddp_init(struct t3cdev *tdev)
-{
- if (page_idx == DDP_PGIDX_MAX) {
- page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
-
- if (page_idx == DDP_PGIDX_MAX) {
- ddp_log_info("system PAGE_SIZE %lu, update hw.\n",
- PAGE_SIZE);
- if (cxgb3i_ddp_adjust_page_table() < 0) {
- ddp_log_info("PAGE_SIZE %lu, ddp disabled.\n",
- PAGE_SIZE);
- return;
- }
- page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
- }
- ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
- PAGE_SIZE, page_idx);
- }
- ddp_init(tdev);
-}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
deleted file mode 100644
index 6761b329124d..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * cxgb3i_ddp.h: Chelsio S3xx iSCSI DDP Manager.
- *
- * Copyright (c) 2008 Chelsio Communications, 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.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#ifndef __CXGB3I_ULP2_DDP_H__
-#define __CXGB3I_ULP2_DDP_H__
-
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-/**
- * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
- *
- * @sw_bits: # of bits used by iscsi software layer
- * @rsvd_bits: # of bits used by h/w
- * @rsvd_shift: h/w bits shift left
- * @rsvd_mask: reserved bit mask
- */
-struct cxgb3i_tag_format {
- unsigned char sw_bits;
- unsigned char rsvd_bits;
- unsigned char rsvd_shift;
- unsigned char filler[1];
- u32 rsvd_mask;
-};
-
-/**
- * struct cxgb3i_gather_list - cxgb3i direct data placement memory
- *
- * @tag: ddp tag
- * @length: total data buffer length
- * @offset: initial offset to the 1st page
- * @nelem: # of pages
- * @pages: page pointers
- * @phys_addr: physical address
- */
-struct cxgb3i_gather_list {
- u32 tag;
- unsigned int length;
- unsigned int offset;
- unsigned int nelem;
- struct page **pages;
- dma_addr_t phys_addr[0];
-};
-
-/**
- * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload
- *
- * @list: list head to link elements
- * @refcnt: ref. count
- * @tdev: pointer to t3cdev used by cxgb3 driver
- * @max_txsz: max tx packet size for ddp
- * @max_rxsz: max rx packet size for ddp
- * @llimit: lower bound of the page pod memory
- * @ulimit: upper bound of the page pod memory
- * @nppods: # of page pod entries
- * @idx_last: page pod entry last used
- * @idx_bits: # of bits the pagepod index would take
- * @idx_mask: pagepod index mask
- * @rsvd_tag_mask: tag mask
- * @map_lock: lock to synchonize access to the page pod map
- * @gl_map: ddp memory gather list
- * @gl_skb: skb used to program the pagepod
- */
-struct cxgb3i_ddp_info {
- struct list_head list;
- struct kref refcnt;
- struct t3cdev *tdev;
- struct pci_dev *pdev;
- unsigned int max_txsz;
- unsigned int max_rxsz;
- unsigned int llimit;
- unsigned int ulimit;
- unsigned int nppods;
- unsigned int idx_last;
- unsigned char idx_bits;
- unsigned char filler[3];
- u32 idx_mask;
- u32 rsvd_tag_mask;
- spinlock_t map_lock;
- struct cxgb3i_gather_list **gl_map;
- 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_LEN)
-#define PPOD_PAGES_MAX 4
-#define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */
-
-/*
- * struct pagepod_hdr, pagepod - pagepod format
- */
-struct pagepod_hdr {
- u32 vld_tid;
- u32 pgsz_tag_clr;
- u32 maxoffset;
- u32 pgoffset;
- u64 rsvd;
-};
-
-struct pagepod {
- struct pagepod_hdr hdr;
- u64 addr[PPOD_PAGES_MAX + 1];
-};
-
-#define PPOD_SIZE sizeof(struct pagepod) /* 64 */
-#define PPOD_SIZE_SHIFT 6
-
-#define PPOD_COLOR_SHIFT 0
-#define PPOD_COLOR_SIZE 6
-#define PPOD_COLOR_MASK ((1 << PPOD_COLOR_SIZE) - 1)
-
-#define PPOD_IDX_SHIFT PPOD_COLOR_SIZE
-#define PPOD_IDX_MAX_SIZE 24
-
-#define S_PPOD_TID 0
-#define M_PPOD_TID 0xFFFFFF
-#define V_PPOD_TID(x) ((x) << S_PPOD_TID)
-
-#define S_PPOD_VALID 24
-#define V_PPOD_VALID(x) ((x) << S_PPOD_VALID)
-#define F_PPOD_VALID V_PPOD_VALID(1U)
-
-#define S_PPOD_COLOR 0
-#define M_PPOD_COLOR 0x3F
-#define V_PPOD_COLOR(x) ((x) << S_PPOD_COLOR)
-
-#define S_PPOD_TAG 6
-#define M_PPOD_TAG 0xFFFFFF
-#define V_PPOD_TAG(x) ((x) << S_PPOD_TAG)
-
-#define S_PPOD_PGSZ 30
-#define M_PPOD_PGSZ 0x3
-#define V_PPOD_PGSZ(x) ((x) << S_PPOD_PGSZ)
-
-/*
- * large memory chunk allocation/release
- * use vmalloc() if kmalloc() fails
- */
-static inline void *cxgb3i_alloc_big_mem(unsigned int size,
- gfp_t gfp)
-{
- void *p = kmalloc(size, gfp);
- if (!p)
- p = vmalloc(size);
- if (p)
- memset(p, 0, size);
- return p;
-}
-
-static inline void cxgb3i_free_big_mem(void *addr)
-{
- if (is_vmalloc_addr(addr))
- vfree(addr);
- else
- kfree(addr);
-}
-
-/*
- * cxgb3i ddp tag are 32 bits, it consists of reserved bits used by h/w and
- * non-reserved bits that can be used by the iscsi s/w.
- * The reserved bits are identified by the rsvd_bits and rsvd_shift fields
- * in struct cxgb3i_tag_format.
- *
- * The upper most reserved bit can be used to check if a tag is ddp tag or not:
- * if the bit is 0, the tag is a valid ddp tag
- */
-
-/**
- * cxgb3i_is_ddp_tag - check if a given tag is a hw/ddp tag
- * @tformat: tag format information
- * @tag: tag to be checked
- *
- * return true if the tag is a ddp tag, false otherwise.
- */
-static inline int cxgb3i_is_ddp_tag(struct cxgb3i_tag_format *tformat, u32 tag)
-{
- return !(tag & (1 << (tformat->rsvd_bits + tformat->rsvd_shift - 1)));
-}
-
-/**
- * cxgb3i_sw_tag_usable - check if s/w tag has enough bits left for hw bits
- * @tformat: tag format information
- * @sw_tag: s/w tag to be checked
- *
- * return true if the tag can be used for hw ddp tag, false otherwise.
- */
-static inline int cxgb3i_sw_tag_usable(struct cxgb3i_tag_format *tformat,
- u32 sw_tag)
-{
- sw_tag >>= (32 - tformat->rsvd_bits);
- return !sw_tag;
-}
-
-/**
- * cxgb3i_set_non_ddp_tag - mark a given s/w tag as an invalid ddp tag
- * @tformat: tag format information
- * @sw_tag: s/w tag to be checked
- *
- * insert 1 at the upper most reserved bit to mark it as an invalid ddp tag.
- */
-static inline u32 cxgb3i_set_non_ddp_tag(struct cxgb3i_tag_format *tformat,
- u32 sw_tag)
-{
- unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
- u32 mask = (1 << shift) - 1;
-
- if (sw_tag && (sw_tag & ~mask)) {
- u32 v1 = sw_tag & ((1 << shift) - 1);
- u32 v2 = (sw_tag >> (shift - 1)) << shift;
-
- return v2 | v1 | 1 << shift;
- }
- return sw_tag | 1 << shift;
-}
-
-/**
- * cxgb3i_ddp_tag_base - shift s/w tag bits so that reserved bits are not used
- * @tformat: tag format information
- * @sw_tag: s/w tag to be checked
- */
-static inline u32 cxgb3i_ddp_tag_base(struct cxgb3i_tag_format *tformat,
- u32 sw_tag)
-{
- u32 mask = (1 << tformat->rsvd_shift) - 1;
-
- if (sw_tag && (sw_tag & ~mask)) {
- u32 v1 = sw_tag & mask;
- u32 v2 = sw_tag >> tformat->rsvd_shift;
-
- v2 <<= tformat->rsvd_shift + tformat->rsvd_bits;
- return v2 | v1;
- }
- return sw_tag;
-}
-
-/**
- * cxgb3i_tag_rsvd_bits - get the reserved bits used by the h/w
- * @tformat: tag format information
- * @tag: tag to be checked
- *
- * return the reserved bits in the tag
- */
-static inline u32 cxgb3i_tag_rsvd_bits(struct cxgb3i_tag_format *tformat,
- u32 tag)
-{
- if (cxgb3i_is_ddp_tag(tformat, tag))
- return (tag >> tformat->rsvd_shift) & tformat->rsvd_mask;
- return 0;
-}
-
-/**
- * cxgb3i_tag_nonrsvd_bits - get the non-reserved bits used by the s/w
- * @tformat: tag format information
- * @tag: tag to be checked
- *
- * return the non-reserved bits in the tag.
- */
-static inline u32 cxgb3i_tag_nonrsvd_bits(struct cxgb3i_tag_format *tformat,
- u32 tag)
-{
- unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
- u32 v1, v2;
-
- if (cxgb3i_is_ddp_tag(tformat, tag)) {
- v1 = tag & ((1 << tformat->rsvd_shift) - 1);
- v2 = (tag >> (shift + 1)) << tformat->rsvd_shift;
- } else {
- u32 mask = (1 << shift) - 1;
-
- tag &= ~(1 << shift);
- v1 = tag & mask;
- v2 = (tag >> 1) & ~mask;
- }
- return v1 | v2;
-}
-
-int cxgb3i_ddp_tag_reserve(struct t3cdev *, unsigned int tid,
- struct cxgb3i_tag_format *, u32 *tag,
- struct cxgb3i_gather_list *, gfp_t gfp);
-void cxgb3i_ddp_tag_release(struct t3cdev *, u32 tag);
-
-struct cxgb3i_gather_list *cxgb3i_ddp_make_gl(unsigned int xferlen,
- struct scatterlist *sgl,
- unsigned int sgcnt,
- struct pci_dev *pdev,
- gfp_t gfp);
-void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
- struct pci_dev *pdev);
-
-int cxgb3i_setup_conn_host_pagesize(struct t3cdev *, unsigned int tid,
- int reply);
-int cxgb3i_setup_conn_pagesize(struct t3cdev *, unsigned int tid, int reply,
- unsigned long pgsz);
-int cxgb3i_setup_conn_digest(struct t3cdev *, unsigned int tid,
- int hcrc, int dcrc, int reply);
-int cxgb3i_ddp_find_page_index(unsigned long pgsz);
-int cxgb3i_adapter_ddp_info(struct t3cdev *, struct cxgb3i_tag_format *,
- unsigned int *txsz, unsigned int *rxsz);
-
-void cxgb3i_ddp_init(struct t3cdev *);
-void cxgb3i_ddp_cleanup(struct t3cdev *);
-#endif
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c
deleted file mode 100644
index 685af3698518..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_init.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* cxgb3i_init.c: Chelsio S3xx iSCSI driver.
- *
- * Copyright (c) 2008 Chelsio Communications, 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.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#include "cxgb3i.h"
-
-#define DRV_MODULE_NAME "cxgb3i"
-#define DRV_MODULE_VERSION "1.0.2"
-#define DRV_MODULE_RELDATE "Mar. 2009"
-
-static char version[] =
- "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
- " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
-MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>");
-MODULE_DESCRIPTION("Chelsio S3xx iSCSI Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_MODULE_VERSION);
-
-static void open_s3_dev(struct t3cdev *);
-static void close_s3_dev(struct t3cdev *);
-static void s3_event_handler(struct t3cdev *tdev, u32 event, u32 port);
-
-static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
-static struct cxgb3_client t3c_client = {
- .name = "iscsi_cxgb3",
- .handlers = cxgb3i_cpl_handlers,
- .add = open_s3_dev,
- .remove = close_s3_dev,
- .event_handler = s3_event_handler,
-};
-
-/**
- * open_s3_dev - register with cxgb3 LLD
- * @t3dev: cxgb3 adapter instance
- */
-static void open_s3_dev(struct t3cdev *t3dev)
-{
- static int vers_printed;
-
- if (!vers_printed) {
- printk(KERN_INFO "%s", version);
- vers_printed = 1;
- }
-
- cxgb3i_ddp_init(t3dev);
- cxgb3i_sdev_add(t3dev, &t3c_client);
- cxgb3i_adapter_open(t3dev);
-}
-
-/**
- * close_s3_dev - de-register with cxgb3 LLD
- * @t3dev: cxgb3 adapter instance
- */
-static void close_s3_dev(struct t3cdev *t3dev)
-{
- cxgb3i_adapter_close(t3dev);
- cxgb3i_sdev_remove(t3dev);
- cxgb3i_ddp_cleanup(t3dev);
-}
-
-static void s3_event_handler(struct t3cdev *tdev, u32 event, u32 port)
-{
- struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev);
-
- cxgb3i_log_info("snic 0x%p, tdev 0x%p, event 0x%x, port 0x%x.\n",
- snic, tdev, event, port);
- if (!snic)
- return;
-
- switch (event) {
- case OFFLOAD_STATUS_DOWN:
- snic->flags |= CXGB3I_ADAPTER_FLAG_RESET;
- break;
- case OFFLOAD_STATUS_UP:
- snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
- break;
- }
-}
-
-/**
- * cxgb3i_init_module - module init entry point
- *
- * initialize any driver wide global data structures and register itself
- * with the cxgb3 module
- */
-static int __init cxgb3i_init_module(void)
-{
- int err;
-
- err = cxgb3i_sdev_init(cxgb3i_cpl_handlers);
- if (err < 0)
- return err;
-
- err = cxgb3i_iscsi_init();
- if (err < 0)
- return err;
-
- err = cxgb3i_pdu_init();
- if (err < 0) {
- cxgb3i_iscsi_cleanup();
- return err;
- }
-
- cxgb3_register_client(&t3c_client);
-
- return 0;
-}
-
-/**
- * cxgb3i_exit_module - module cleanup/exit entry point
- *
- * go through the driver hba list and for each hba, release any resource held.
- * and unregisters iscsi transport and the cxgb3 module
- */
-static void __exit cxgb3i_exit_module(void)
-{
- cxgb3_unregister_client(&t3c_client);
- cxgb3i_pdu_cleanup();
- cxgb3i_iscsi_cleanup();
- cxgb3i_sdev_cleanup();
-}
-
-module_init(cxgb3i_init_module);
-module_exit(cxgb3i_exit_module);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
deleted file mode 100644
index 7b686abaae64..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/* cxgb3i_iscsi.c: Chelsio S3xx iSCSI driver.
- *
- * Copyright (c) 2008 Chelsio Communications, Inc.
- * Copyright (c) 2008 Mike Christie
- * Copyright (c) 2008 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#include <linux/inet.h>
-#include <linux/slab.h>
-#include <linux/crypto.h>
-#include <linux/if_vlan.h>
-#include <net/dst.h>
-#include <net/tcp.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi.h>
-#include <scsi/iscsi_proto.h>
-#include <scsi/libiscsi.h>
-#include <scsi/scsi_transport_iscsi.h>
-
-#include "cxgb3i.h"
-#include "cxgb3i_pdu.h"
-
-#ifdef __DEBUG_CXGB3I_TAG__
-#define cxgb3i_tag_debug cxgb3i_log_debug
-#else
-#define cxgb3i_tag_debug(fmt...)
-#endif
-
-#ifdef __DEBUG_CXGB3I_API__
-#define cxgb3i_api_debug cxgb3i_log_debug
-#else
-#define cxgb3i_api_debug(fmt...)
-#endif
-
-/*
- * align pdu size to multiple of 512 for better performance
- */
-#define align_pdu_size(n) do { n = (n) & (~511); } while (0)
-
-static struct scsi_transport_template *cxgb3i_scsi_transport;
-static struct scsi_host_template cxgb3i_host_template;
-static struct iscsi_transport cxgb3i_iscsi_transport;
-static unsigned char sw_tag_idx_bits;
-static unsigned char sw_tag_age_bits;
-
-static LIST_HEAD(cxgb3i_snic_list);
-static DEFINE_RWLOCK(cxgb3i_snic_rwlock);
-
-/**
- * cxgb3i_adpater_find_by_tdev - find the cxgb3i_adapter structure via t3cdev
- * @tdev: t3cdev pointer
- */
-struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *tdev)
-{
- struct cxgb3i_adapter *snic;
-
- read_lock(&cxgb3i_snic_rwlock);
- list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
- if (snic->tdev == tdev) {
- read_unlock(&cxgb3i_snic_rwlock);
- return snic;
- }
- }
- read_unlock(&cxgb3i_snic_rwlock);
- return NULL;
-}
-
-static inline int adapter_update(struct cxgb3i_adapter *snic)
-{
- cxgb3i_log_info("snic 0x%p, t3dev 0x%p, updating.\n",
- snic, snic->tdev);
- return cxgb3i_adapter_ddp_info(snic->tdev, &snic->tag_format,
- &snic->tx_max_size,
- &snic->rx_max_size);
-}
-
-static int adapter_add(struct cxgb3i_adapter *snic)
-{
- struct t3cdev *t3dev = snic->tdev;
- struct adapter *adapter = tdev2adap(t3dev);
- int i, err;
-
- snic->pdev = adapter->pdev;
- snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
-
- err = cxgb3i_adapter_ddp_info(t3dev, &snic->tag_format,
- &snic->tx_max_size,
- &snic->rx_max_size);
- if (err < 0)
- return err;
-
- for_each_port(adapter, i) {
- snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]);
- if (!snic->hba[i])
- return -EINVAL;
- }
- snic->hba_cnt = adapter->params.nports;
-
- /* add to the list */
- write_lock(&cxgb3i_snic_rwlock);
- list_add_tail(&snic->list_head, &cxgb3i_snic_list);
- write_unlock(&cxgb3i_snic_rwlock);
-
- cxgb3i_log_info("t3dev 0x%p open, snic 0x%p, %u scsi hosts added.\n",
- t3dev, snic, snic->hba_cnt);
- return 0;
-}
-
-/**
- * cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
- * @t3dev: t3cdev adapter
- */
-void cxgb3i_adapter_open(struct t3cdev *t3dev)
-{
- struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
- int err;
-
- if (snic)
- err = adapter_update(snic);
- else {
- snic = kzalloc(sizeof(*snic), GFP_KERNEL);
- if (snic) {
- spin_lock_init(&snic->lock);
- snic->tdev = t3dev;
- err = adapter_add(snic);
- } else
- err = -ENOMEM;
- }
-
- if (err < 0) {
- cxgb3i_log_info("snic 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
- snic, snic ? snic->flags : 0, t3dev, err);
- if (snic) {
- snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
- cxgb3i_adapter_close(t3dev);
- }
- }
-}
-
-/**
- * cxgb3i_adapter_close - release the resources held and cleanup h/w settings
- * @t3dev: t3cdev adapter
- */
-void cxgb3i_adapter_close(struct t3cdev *t3dev)
-{
- struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
- int i;
-
- if (!snic || snic->flags & CXGB3I_ADAPTER_FLAG_RESET) {
- cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, f 0x%x.\n",
- t3dev, snic, snic ? snic->flags : 0);
- return;
- }
-
- /* remove from the list */
- write_lock(&cxgb3i_snic_rwlock);
- list_del(&snic->list_head);
- write_unlock(&cxgb3i_snic_rwlock);
-
- for (i = 0; i < snic->hba_cnt; i++) {
- if (snic->hba[i]) {
- cxgb3i_hba_host_remove(snic->hba[i]);
- snic->hba[i] = NULL;
- }
- }
- cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, %u scsi hosts removed.\n",
- t3dev, snic, snic->hba_cnt);
- kfree(snic);
-}
-
-/**
- * cxgb3i_hba_find_by_netdev - find the cxgb3i_hba structure via net_device
- * @t3dev: t3cdev adapter
- */
-static struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev)
-{
- struct cxgb3i_adapter *snic;
- int i;
-
- if (ndev->priv_flags & IFF_802_1Q_VLAN)
- ndev = vlan_dev_real_dev(ndev);
-
- read_lock(&cxgb3i_snic_rwlock);
- list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
- for (i = 0; i < snic->hba_cnt; i++) {
- if (snic->hba[i]->ndev == ndev) {
- read_unlock(&cxgb3i_snic_rwlock);
- return snic->hba[i];
- }
- }
- }
- read_unlock(&cxgb3i_snic_rwlock);
- return NULL;
-}
-
-/**
- * cxgb3i_hba_host_add - register a new host with scsi/iscsi
- * @snic: the cxgb3i adapter
- * @ndev: associated net_device
- */
-struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
- struct net_device *ndev)
-{
- struct cxgb3i_hba *hba;
- struct Scsi_Host *shost;
- int err;
-
- shost = iscsi_host_alloc(&cxgb3i_host_template,
- sizeof(struct cxgb3i_hba), 1);
- if (!shost) {
- cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_alloc failed.\n",
- snic, ndev);
- return NULL;
- }
-
- shost->transportt = cxgb3i_scsi_transport;
- shost->max_lun = CXGB3I_MAX_LUN;
- shost->max_id = CXGB3I_MAX_TARGET;
- shost->max_channel = 0;
- shost->max_cmd_len = 16;
-
- hba = iscsi_host_priv(shost);
- hba->snic = snic;
- hba->ndev = ndev;
- hba->shost = shost;
-
- pci_dev_get(snic->pdev);
- err = iscsi_host_add(shost, &snic->pdev->dev);
- if (err) {
- cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_add failed.\n",
- snic, ndev);
- goto pci_dev_put;
- }
-
- cxgb3i_api_debug("shost 0x%p, hba 0x%p, no %u.\n",
- shost, hba, shost->host_no);
-
- return hba;
-
-pci_dev_put:
- pci_dev_put(snic->pdev);
- scsi_host_put(shost);
- return NULL;
-}
-
-/**
- * cxgb3i_hba_host_remove - de-register the host with scsi/iscsi
- * @hba: the cxgb3i hba
- */
-void cxgb3i_hba_host_remove(struct cxgb3i_hba *hba)
-{
- cxgb3i_api_debug("shost 0x%p, hba 0x%p, no %u.\n",
- hba->shost, hba, hba->shost->host_no);
- iscsi_host_remove(hba->shost);
- pci_dev_put(hba->snic->pdev);
- iscsi_host_free(hba->shost);
-}
-
-/**
- * cxgb3i_ep_connect - establish TCP connection to target portal
- * @shost: scsi host to use
- * @dst_addr: target IP address
- * @non_blocking: blocking or non-blocking call
- *
- * Initiates a TCP/IP connection to the dst_addr
- */
-static struct iscsi_endpoint *cxgb3i_ep_connect(struct Scsi_Host *shost,
- struct sockaddr *dst_addr,
- int non_blocking)
-{
- struct iscsi_endpoint *ep;
- struct cxgb3i_endpoint *cep;
- struct cxgb3i_hba *hba = NULL;
- struct s3_conn *c3cn = NULL;
- int err = 0;
-
- if (shost)
- hba = iscsi_host_priv(shost);
-
- cxgb3i_api_debug("shost 0x%p, hba 0x%p.\n", shost, hba);
-
- c3cn = cxgb3i_c3cn_create();
- if (!c3cn) {
- cxgb3i_log_info("ep connect OOM.\n");
- err = -ENOMEM;
- goto release_conn;
- }
-
- err = cxgb3i_c3cn_connect(hba ? hba->ndev : NULL, c3cn,
- (struct sockaddr_in *)dst_addr);
- if (err < 0) {
- cxgb3i_log_info("ep connect failed.\n");
- goto release_conn;
- }
-
- hba = cxgb3i_hba_find_by_netdev(c3cn->dst_cache->dev);
- if (!hba) {
- err = -ENOSPC;
- cxgb3i_log_info("NOT going through cxgbi device.\n");
- goto release_conn;
- }
-
- if (shost && hba != iscsi_host_priv(shost)) {
- err = -ENOSPC;
- cxgb3i_log_info("Could not connect through request host%u\n",
- shost->host_no);
- goto release_conn;
- }
-
- if (c3cn_is_closing(c3cn)) {
- err = -ENOSPC;
- cxgb3i_log_info("ep connect unable to connect.\n");
- goto release_conn;
- }
-
- ep = iscsi_create_endpoint(sizeof(*cep));
- if (!ep) {
- err = -ENOMEM;
- cxgb3i_log_info("iscsi alloc ep, OOM.\n");
- goto release_conn;
- }
- cep = ep->dd_data;
- cep->c3cn = c3cn;
- cep->hba = hba;
-
- cxgb3i_api_debug("ep 0x%p, 0x%p, c3cn 0x%p, hba 0x%p.\n",
- ep, cep, c3cn, hba);
- return ep;
-
-release_conn:
- cxgb3i_api_debug("conn 0x%p failed, release.\n", c3cn);
- if (c3cn)
- cxgb3i_c3cn_release(c3cn);
- return ERR_PTR(err);
-}
-
-/**
- * cxgb3i_ep_poll - polls for TCP connection establishement
- * @ep: TCP connection (endpoint) handle
- * @timeout_ms: timeout value in milli secs
- *
- * polls for TCP connect request to complete
- */
-static int cxgb3i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
-{
- struct cxgb3i_endpoint *cep = ep->dd_data;
- struct s3_conn *c3cn = cep->c3cn;
-
- if (!c3cn_is_established(c3cn))
- return 0;
- cxgb3i_api_debug("ep 0x%p, c3cn 0x%p established.\n", ep, c3cn);
- return 1;
-}
-
-/**
- * cxgb3i_ep_disconnect - teardown TCP connection
- * @ep: TCP connection (endpoint) handle
- *
- * teardown TCP connection
- */
-static void cxgb3i_ep_disconnect(struct iscsi_endpoint *ep)
-{
- struct cxgb3i_endpoint *cep = ep->dd_data;
- struct cxgb3i_conn *cconn = cep->cconn;
-
- cxgb3i_api_debug("ep 0x%p, cep 0x%p.\n", ep, cep);
-
- if (cconn && cconn->conn) {
- /*
- * stop the xmit path so the xmit_pdu function is
- * not being called
- */
- iscsi_suspend_tx(cconn->conn);
-
- write_lock_bh(&cep->c3cn->callback_lock);
- cep->c3cn->user_data = NULL;
- cconn->cep = NULL;
- write_unlock_bh(&cep->c3cn->callback_lock);
- }
-
- cxgb3i_api_debug("ep 0x%p, cep 0x%p, release c3cn 0x%p.\n",
- ep, cep, cep->c3cn);
- cxgb3i_c3cn_release(cep->c3cn);
- iscsi_destroy_endpoint(ep);
-}
-
-/**
- * cxgb3i_session_create - create a new iscsi session
- * @cmds_max: max # of commands
- * @qdepth: scsi queue depth
- * @initial_cmdsn: initial iscsi CMDSN for this session
- *
- * Creates a new iSCSI session
- */
-static struct iscsi_cls_session *
-cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
- u32 initial_cmdsn)
-{
- struct cxgb3i_endpoint *cep;
- struct cxgb3i_hba *hba;
- struct Scsi_Host *shost;
- struct iscsi_cls_session *cls_session;
- struct iscsi_session *session;
-
- if (!ep) {
- cxgb3i_log_error("%s, missing endpoint.\n", __func__);
- return NULL;
- }
-
- cep = ep->dd_data;
- hba = cep->hba;
- shost = hba->shost;
- cxgb3i_api_debug("ep 0x%p, cep 0x%p, hba 0x%p.\n", ep, cep, hba);
- BUG_ON(hba != iscsi_host_priv(shost));
-
- cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
- cmds_max, 0,
- sizeof(struct iscsi_tcp_task) +
- sizeof(struct cxgb3i_task_data),
- initial_cmdsn, ISCSI_MAX_TARGET);
- if (!cls_session)
- return NULL;
- session = cls_session->dd_data;
- if (iscsi_tcp_r2tpool_alloc(session))
- goto remove_session;
-
- return cls_session;
-
-remove_session:
- iscsi_session_teardown(cls_session);
- return NULL;
-}
-
-/**
- * cxgb3i_session_destroy - destroys iscsi session
- * @cls_session: pointer to iscsi cls session
- *
- * Destroys an iSCSI session instance and releases its all resources held
- */
-static void cxgb3i_session_destroy(struct iscsi_cls_session *cls_session)
-{
- cxgb3i_api_debug("sess 0x%p.\n", cls_session);
- iscsi_tcp_r2tpool_free(cls_session->dd_data);
- iscsi_session_teardown(cls_session);
-}
-
-/**
- * cxgb3i_conn_max_xmit_dlength -- calc the max. xmit pdu segment size
- * @conn: iscsi connection
- * check the max. xmit pdu payload, reduce it if needed
- */
-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 = 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(conn->max_xmit_dlength, max);
- else
- conn->max_xmit_dlength = max;
- align_pdu_size(conn->max_xmit_dlength);
- cxgb3i_api_debug("conn 0x%p, max xmit %u.\n",
- conn, conn->max_xmit_dlength);
- return 0;
-}
-
-/**
- * cxgb3i_conn_max_recv_dlength -- check the max. recv pdu segment size
- * @conn: iscsi connection
- * return 0 if the value is valid, < 0 otherwise.
- */
-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 = cconn->hba->snic->rx_max_size;
-
- align_pdu_size(max);
- if (conn->max_recv_dlength) {
- if (conn->max_recv_dlength > max) {
- cxgb3i_log_error("MaxRecvDataSegmentLength %u too big."
- " Need to be <= %u.\n",
- conn->max_recv_dlength, max);
- return -EINVAL;
- }
- conn->max_recv_dlength = min(conn->max_recv_dlength, max);
- align_pdu_size(conn->max_recv_dlength);
- } else
- conn->max_recv_dlength = max;
- cxgb3i_api_debug("conn 0x%p, max recv %u.\n",
- conn, conn->max_recv_dlength);
- return 0;
-}
-
-/**
- * cxgb3i_conn_create - create iscsi connection instance
- * @cls_session: pointer to iscsi cls session
- * @cid: iscsi cid
- *
- * Creates a new iSCSI connection instance for a given session
- */
-static struct iscsi_cls_conn *cxgb3i_conn_create(struct iscsi_cls_session
- *cls_session, u32 cid)
-{
- struct iscsi_cls_conn *cls_conn;
- struct iscsi_conn *conn;
- struct iscsi_tcp_conn *tcp_conn;
- struct cxgb3i_conn *cconn;
-
- cxgb3i_api_debug("sess 0x%p, cid %u.\n", cls_session, cid);
-
- cls_conn = iscsi_tcp_conn_setup(cls_session, sizeof(*cconn), cid);
- if (!cls_conn)
- return NULL;
- conn = cls_conn->dd_data;
- tcp_conn = conn->dd_data;
- cconn = tcp_conn->dd_data;
-
- cconn->conn = conn;
- return cls_conn;
-}
-
-/**
- * cxgb3i_conn_bind - binds iscsi sess, conn and endpoint together
- * @cls_session: pointer to iscsi cls session
- * @cls_conn: pointer to iscsi cls conn
- * @transport_eph: 64-bit EP handle
- * @is_leading: leading connection on this session?
- *
- * Binds together an iSCSI session, an iSCSI connection and a
- * TCP connection. This routine returns error code if the TCP
- * connection does not belong on the device iSCSI sess/conn is bound
- */
-
-static int cxgb3i_conn_bind(struct iscsi_cls_session *cls_session,
- struct iscsi_cls_conn *cls_conn,
- u64 transport_eph, int is_leading)
-{
- struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- struct cxgb3i_adapter *snic;
- struct iscsi_endpoint *ep;
- struct cxgb3i_endpoint *cep;
- struct s3_conn *c3cn;
- int err;
-
- ep = iscsi_lookup_endpoint(transport_eph);
- if (!ep)
- return -EINVAL;
-
- /* setup ddp pagesize */
- cep = ep->dd_data;
- c3cn = cep->c3cn;
- snic = cep->hba->snic;
- err = cxgb3i_setup_conn_host_pagesize(snic->tdev, c3cn->tid, 0);
- if (err < 0)
- return err;
-
- cxgb3i_api_debug("ep 0x%p, cls sess 0x%p, cls conn 0x%p.\n",
- ep, cls_session, cls_conn);
-
- err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
- if (err)
- return -EINVAL;
-
- /* calculate the tag idx bits needed for this conn based on cmds_max */
- cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
- cxgb3i_api_debug("session cmds_max 0x%x, bits %u.\n",
- conn->session->cmds_max, cconn->task_idx_bits);
-
- read_lock(&c3cn->callback_lock);
- c3cn->user_data = conn;
- cconn->hba = cep->hba;
- cconn->cep = cep;
- cep->cconn = cconn;
- read_unlock(&c3cn->callback_lock);
-
- cxgb3i_conn_max_xmit_dlength(conn);
- cxgb3i_conn_max_recv_dlength(conn);
-
- spin_lock_bh(&conn->session->lock);
- sprintf(conn->portal_address, "%pI4", &c3cn->daddr.sin_addr.s_addr);
- conn->portal_port = ntohs(c3cn->daddr.sin_port);
- spin_unlock_bh(&conn->session->lock);
-
- /* init recv engine */
- iscsi_tcp_hdr_recv_prep(tcp_conn);
-
- return 0;
-}
-
-/**
- * cxgb3i_conn_get_param - return iscsi connection parameter to caller
- * @cls_conn: pointer to iscsi cls conn
- * @param: parameter type identifier
- * @buf: buffer pointer
- *
- * returns iSCSI connection parameters
- */
-static int cxgb3i_conn_get_param(struct iscsi_cls_conn *cls_conn,
- enum iscsi_param param, char *buf)
-{
- struct iscsi_conn *conn = cls_conn->dd_data;
- int len;
-
- cxgb3i_api_debug("cls_conn 0x%p, param %d.\n", cls_conn, param);
-
- switch (param) {
- case ISCSI_PARAM_CONN_PORT:
- spin_lock_bh(&conn->session->lock);
- len = sprintf(buf, "%hu\n", conn->portal_port);
- spin_unlock_bh(&conn->session->lock);
- break;
- case ISCSI_PARAM_CONN_ADDRESS:
- spin_lock_bh(&conn->session->lock);
- len = sprintf(buf, "%s\n", conn->portal_address);
- spin_unlock_bh(&conn->session->lock);
- break;
- default:
- return iscsi_conn_get_param(cls_conn, param, buf);
- }
-
- return len;
-}
-
-/**
- * cxgb3i_conn_set_param - set iscsi connection parameter
- * @cls_conn: pointer to iscsi cls conn
- * @param: parameter type identifier
- * @buf: buffer pointer
- * @buflen: buffer length
- *
- * set iSCSI connection parameters
- */
-static int cxgb3i_conn_set_param(struct iscsi_cls_conn *cls_conn,
- enum iscsi_param param, char *buf, int buflen)
-{
- struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_session *session = conn->session;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- struct cxgb3i_adapter *snic = cconn->hba->snic;
- struct s3_conn *c3cn = cconn->cep->c3cn;
- int value, err = 0;
-
- switch (param) {
- case ISCSI_PARAM_HDRDGST_EN:
- err = iscsi_set_param(cls_conn, param, buf, buflen);
- if (!err && conn->hdrdgst_en)
- err = cxgb3i_setup_conn_digest(snic->tdev, c3cn->tid,
- conn->hdrdgst_en,
- conn->datadgst_en, 0);
- break;
- case ISCSI_PARAM_DATADGST_EN:
- err = iscsi_set_param(cls_conn, param, buf, buflen);
- if (!err && conn->datadgst_en)
- err = cxgb3i_setup_conn_digest(snic->tdev, c3cn->tid,
- conn->hdrdgst_en,
- conn->datadgst_en, 0);
- break;
- case ISCSI_PARAM_MAX_R2T:
- sscanf(buf, "%d", &value);
- if (value <= 0 || !is_power_of_2(value))
- return -EINVAL;
- if (session->max_r2t == value)
- break;
- iscsi_tcp_r2tpool_free(session);
- err = iscsi_set_param(cls_conn, param, buf, buflen);
- if (!err && iscsi_tcp_r2tpool_alloc(session))
- return -ENOMEM;
- case ISCSI_PARAM_MAX_RECV_DLENGTH:
- err = iscsi_set_param(cls_conn, param, buf, buflen);
- if (!err)
- err = cxgb3i_conn_max_recv_dlength(conn);
- break;
- case ISCSI_PARAM_MAX_XMIT_DLENGTH:
- err = iscsi_set_param(cls_conn, param, buf, buflen);
- if (!err)
- err = cxgb3i_conn_max_xmit_dlength(conn);
- break;
- default:
- return iscsi_set_param(cls_conn, param, buf, buflen);
- }
- return err;
-}
-
-/**
- * cxgb3i_host_set_param - configure host (adapter) related parameters
- * @shost: scsi host pointer
- * @param: parameter type identifier
- * @buf: buffer pointer
- */
-static int cxgb3i_host_set_param(struct Scsi_Host *shost,
- enum iscsi_host_param param,
- char *buf, int buflen)
-{
- struct cxgb3i_hba *hba = iscsi_host_priv(shost);
-
- if (!hba->ndev) {
- shost_printk(KERN_ERR, shost, "Could not set host param. "
- "Netdev for host not set.\n");
- return -ENODEV;
- }
-
- cxgb3i_api_debug("param %d, buf %s.\n", param, buf);
-
- switch (param) {
- case ISCSI_HOST_PARAM_IPADDRESS:
- {
- __be32 addr = in_aton(buf);
- cxgb3i_set_private_ipv4addr(hba->ndev, addr);
- return 0;
- }
- case ISCSI_HOST_PARAM_HWADDRESS:
- case ISCSI_HOST_PARAM_NETDEV_NAME:
- /* ignore */
- return 0;
- default:
- return iscsi_host_set_param(shost, param, buf, buflen);
- }
-}
-
-/**
- * cxgb3i_host_get_param - returns host (adapter) related parameters
- * @shost: scsi host pointer
- * @param: parameter type identifier
- * @buf: buffer pointer
- */
-static int cxgb3i_host_get_param(struct Scsi_Host *shost,
- enum iscsi_host_param param, char *buf)
-{
- struct cxgb3i_hba *hba = iscsi_host_priv(shost);
- int len = 0;
-
- if (!hba->ndev) {
- shost_printk(KERN_ERR, shost, "Could not set host param. "
- "Netdev for host not set.\n");
- return -ENODEV;
- }
-
- cxgb3i_api_debug("hba %s, param %d.\n", hba->ndev->name, param);
-
- switch (param) {
- case ISCSI_HOST_PARAM_HWADDRESS:
- len = sysfs_format_mac(buf, hba->ndev->dev_addr, 6);
- break;
- case ISCSI_HOST_PARAM_NETDEV_NAME:
- len = sprintf(buf, "%s\n", hba->ndev->name);
- break;
- case ISCSI_HOST_PARAM_IPADDRESS:
- {
- __be32 addr;
-
- addr = cxgb3i_get_private_ipv4addr(hba->ndev);
- len = sprintf(buf, "%pI4", &addr);
- break;
- }
- default:
- return iscsi_host_get_param(shost, param, buf);
- }
- return len;
-}
-
-/**
- * cxgb3i_conn_get_stats - returns iSCSI stats
- * @cls_conn: pointer to iscsi cls conn
- * @stats: pointer to iscsi statistic struct
- */
-static void cxgb3i_conn_get_stats(struct iscsi_cls_conn *cls_conn,
- struct iscsi_stats *stats)
-{
- struct iscsi_conn *conn = cls_conn->dd_data;
-
- stats->txdata_octets = conn->txdata_octets;
- stats->rxdata_octets = conn->rxdata_octets;
- stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
- stats->dataout_pdus = conn->dataout_pdus_cnt;
- stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
- stats->datain_pdus = conn->datain_pdus_cnt;
- stats->r2t_pdus = conn->r2t_pdus_cnt;
- stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
- stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
- stats->digest_err = 0;
- stats->timeout_err = 0;
- stats->custom_length = 1;
- strcpy(stats->custom[0].desc, "eh_abort_cnt");
- stats->custom[0].value = conn->eh_abort_cnt;
-}
-
-/**
- * cxgb3i_parse_itt - get the idx and age bits from a given tag
- * @conn: iscsi connection
- * @itt: itt tag
- * @idx: task index, filled in by this function
- * @age: session age, filled in by this function
- */
-static void cxgb3i_parse_itt(struct iscsi_conn *conn, itt_t itt,
- int *idx, int *age)
-{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- struct cxgb3i_adapter *snic = cconn->hba->snic;
- u32 tag = ntohl((__force u32) itt);
- u32 sw_bits;
-
- sw_bits = cxgb3i_tag_nonrsvd_bits(&snic->tag_format, tag);
- if (idx)
- *idx = sw_bits & ((1 << cconn->task_idx_bits) - 1);
- if (age)
- *age = (sw_bits >> cconn->task_idx_bits) & ISCSI_AGE_MASK;
-
- cxgb3i_tag_debug("parse tag 0x%x/0x%x, sw 0x%x, itt 0x%x, age 0x%x.\n",
- tag, itt, sw_bits, idx ? *idx : 0xFFFFF,
- age ? *age : 0xFF);
-}
-
-/**
- * cxgb3i_reserve_itt - generate tag for a give task
- * @task: iscsi task
- * @hdr_itt: tag, filled in by this function
- * Set up ddp for scsi read tasks if possible.
- */
-int cxgb3i_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt)
-{
- struct scsi_cmnd *sc = task->sc;
- struct iscsi_conn *conn = task->conn;
- struct iscsi_session *sess = conn->session;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- struct cxgb3i_adapter *snic = cconn->hba->snic;
- struct cxgb3i_tag_format *tformat = &snic->tag_format;
- u32 sw_tag = (sess->age << cconn->task_idx_bits) | task->itt;
- u32 tag;
- int err = -EINVAL;
-
- if (sc &&
- (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE) &&
- cxgb3i_sw_tag_usable(tformat, sw_tag)) {
- struct s3_conn *c3cn = cconn->cep->c3cn;
- struct cxgb3i_gather_list *gl;
-
- gl = cxgb3i_ddp_make_gl(scsi_in(sc)->length,
- scsi_in(sc)->table.sgl,
- scsi_in(sc)->table.nents,
- snic->pdev,
- GFP_ATOMIC);
- if (gl) {
- tag = sw_tag;
- err = cxgb3i_ddp_tag_reserve(snic->tdev, c3cn->tid,
- tformat, &tag,
- gl, GFP_ATOMIC);
- if (err < 0)
- cxgb3i_ddp_release_gl(gl, snic->pdev);
- }
- }
-
- if (err < 0)
- tag = cxgb3i_set_non_ddp_tag(tformat, sw_tag);
- /* the itt need to sent in big-endian order */
- *hdr_itt = (__force itt_t)htonl(tag);
-
- cxgb3i_tag_debug("new tag 0x%x/0x%x (itt 0x%x, age 0x%x).\n",
- tag, *hdr_itt, task->itt, sess->age);
- return 0;
-}
-
-/**
- * cxgb3i_release_itt - release the tag for a given task
- * @task: iscsi task
- * @hdr_itt: tag
- * If the tag is a ddp tag, release the ddp setup
- */
-void cxgb3i_release_itt(struct iscsi_task *task, itt_t hdr_itt)
-{
- struct scsi_cmnd *sc = task->sc;
- struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
- struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- struct cxgb3i_adapter *snic = cconn->hba->snic;
- struct cxgb3i_tag_format *tformat = &snic->tag_format;
- u32 tag = ntohl((__force u32)hdr_itt);
-
- cxgb3i_tag_debug("release tag 0x%x.\n", tag);
-
- if (sc &&
- (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE) &&
- cxgb3i_is_ddp_tag(tformat, tag))
- cxgb3i_ddp_tag_release(snic->tdev, tag);
-}
-
-/**
- * cxgb3i_host_template -- Scsi_Host_Template structure
- * used when registering with the scsi mid layer
- */
-static struct scsi_host_template cxgb3i_host_template = {
- .module = THIS_MODULE,
- .name = "Chelsio S3xx iSCSI Initiator",
- .proc_name = "cxgb3i",
- .queuecommand = iscsi_queuecommand,
- .change_queue_depth = iscsi_change_queue_depth,
- .can_queue = CXGB3I_SCSI_HOST_QDEPTH,
- .sg_tablesize = SG_ALL,
- .max_sectors = 0xFFFF,
- .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
- .eh_abort_handler = iscsi_eh_abort,
- .eh_device_reset_handler = iscsi_eh_device_reset,
- .eh_target_reset_handler = iscsi_eh_recover_target,
- .target_alloc = iscsi_target_alloc,
- .use_clustering = DISABLE_CLUSTERING,
- .this_id = -1,
-};
-
-static struct iscsi_transport cxgb3i_iscsi_transport = {
- .owner = THIS_MODULE,
- .name = "cxgb3i",
- .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
- | CAP_DATADGST | CAP_DIGEST_OFFLOAD |
- CAP_PADDING_OFFLOAD,
- .param_mask = ISCSI_MAX_RECV_DLENGTH |
- ISCSI_MAX_XMIT_DLENGTH |
- ISCSI_HDRDGST_EN |
- ISCSI_DATADGST_EN |
- ISCSI_INITIAL_R2T_EN |
- ISCSI_MAX_R2T |
- ISCSI_IMM_DATA_EN |
- ISCSI_FIRST_BURST |
- ISCSI_MAX_BURST |
- ISCSI_PDU_INORDER_EN |
- ISCSI_DATASEQ_INORDER_EN |
- ISCSI_ERL |
- ISCSI_CONN_PORT |
- ISCSI_CONN_ADDRESS |
- ISCSI_EXP_STATSN |
- ISCSI_PERSISTENT_PORT |
- ISCSI_PERSISTENT_ADDRESS |
- ISCSI_TARGET_NAME | ISCSI_TPGT |
- ISCSI_USERNAME | ISCSI_PASSWORD |
- ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
- ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
- ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
- ISCSI_PING_TMO | ISCSI_RECV_TMO |
- ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
- .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
- ISCSI_HOST_INITIATOR_NAME | ISCSI_HOST_NETDEV_NAME,
- .get_host_param = cxgb3i_host_get_param,
- .set_host_param = cxgb3i_host_set_param,
- /* session management */
- .create_session = cxgb3i_session_create,
- .destroy_session = cxgb3i_session_destroy,
- .get_session_param = iscsi_session_get_param,
- /* connection management */
- .create_conn = cxgb3i_conn_create,
- .bind_conn = cxgb3i_conn_bind,
- .destroy_conn = iscsi_tcp_conn_teardown,
- .start_conn = iscsi_conn_start,
- .stop_conn = iscsi_conn_stop,
- .get_conn_param = cxgb3i_conn_get_param,
- .set_param = cxgb3i_conn_set_param,
- .get_stats = cxgb3i_conn_get_stats,
- /* pdu xmit req. from user space */
- .send_pdu = iscsi_conn_send_pdu,
- /* task */
- .init_task = iscsi_tcp_task_init,
- .xmit_task = iscsi_tcp_task_xmit,
- .cleanup_task = cxgb3i_conn_cleanup_task,
-
- /* pdu */
- .alloc_pdu = cxgb3i_conn_alloc_pdu,
- .init_pdu = cxgb3i_conn_init_pdu,
- .xmit_pdu = cxgb3i_conn_xmit_pdu,
- .parse_pdu_itt = cxgb3i_parse_itt,
-
- /* TCP connect/disconnect */
- .ep_connect = cxgb3i_ep_connect,
- .ep_poll = cxgb3i_ep_poll,
- .ep_disconnect = cxgb3i_ep_disconnect,
- /* Error recovery timeout call */
- .session_recovery_timedout = iscsi_session_recovery_timedout,
-};
-
-int cxgb3i_iscsi_init(void)
-{
- sw_tag_idx_bits = (__ilog2_u32(ISCSI_ITT_MASK)) + 1;
- sw_tag_age_bits = (__ilog2_u32(ISCSI_AGE_MASK)) + 1;
- cxgb3i_log_info("tag itt 0x%x, %u bits, age 0x%x, %u bits.\n",
- ISCSI_ITT_MASK, sw_tag_idx_bits,
- ISCSI_AGE_MASK, sw_tag_age_bits);
-
- cxgb3i_scsi_transport =
- iscsi_register_transport(&cxgb3i_iscsi_transport);
- if (!cxgb3i_scsi_transport) {
- cxgb3i_log_error("Could not register cxgb3i transport.\n");
- return -ENODEV;
- }
- cxgb3i_api_debug("cxgb3i transport 0x%p.\n", cxgb3i_scsi_transport);
- return 0;
-}
-
-void cxgb3i_iscsi_cleanup(void)
-{
- if (cxgb3i_scsi_transport) {
- cxgb3i_api_debug("cxgb3i transport 0x%p.\n",
- cxgb3i_scsi_transport);
- iscsi_unregister_transport(&cxgb3i_iscsi_transport);
- }
-}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
deleted file mode 100644
index 3ee13cf9556b..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ /dev/null
@@ -1,1944 +0,0 @@
-/*
- * cxgb3i_offload.c: Chelsio S3xx iscsi offloaded tcp connection management
- *
- * Copyright (C) 2003-2008 Chelsio Communications. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
- * release for licensing terms and conditions.
- *
- * Written by: Dimitris Michailidis (dm@chelsio.com)
- * Karen Xie (kxie@chelsio.com)
- */
-
-#include <linux/if_vlan.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-
-#include "cxgb3_defs.h"
-#include "cxgb3_ctl_defs.h"
-#include "firmware_exports.h"
-#include "cxgb3i_offload.h"
-#include "cxgb3i_pdu.h"
-#include "cxgb3i_ddp.h"
-
-#ifdef __DEBUG_C3CN_CONN__
-#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
-#else
-#define c3cn_tx_debug(fmt...)
-#endif
-
-#ifdef __DEBUG_C3CN_RX__
-#define c3cn_rx_debug cxgb3i_log_debug
-#else
-#define c3cn_rx_debug(fmt...)
-#endif
-
-/*
- * module parameters releated to offloaded iscsi connection
- */
-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 = 128 * 1024;
-module_param(cxgb3_snd_win, int, 0644);
-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);
-MODULE_PARM_DESC(rx_credit_thres,
- "RX credits return threshold in bytes (default=10KB)");
-
-static unsigned int cxgb3_max_connect = 8 * 1024;
-module_param(cxgb3_max_connect, uint, 0644);
-MODULE_PARM_DESC(cxgb3_max_connect, "Max. # of connections (default=8092)");
-
-static unsigned int cxgb3_sport_base = 20000;
-module_param(cxgb3_sport_base, uint, 0644);
-MODULE_PARM_DESC(cxgb3_sport_base, "starting port number (default=20000)");
-
-/*
- * cxgb3i tcp connection data(per adapter) list
- */
-static LIST_HEAD(cdata_list);
-static DEFINE_RWLOCK(cdata_rwlock);
-
-static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion);
-static void c3cn_release_offload_resources(struct s3_conn *c3cn);
-
-/*
- * iscsi source port management
- *
- * Find a free source port in the port allocation map. We use a very simple
- * rotor scheme to look for the next free port.
- *
- * If a source port has been specified make sure that it doesn't collide with
- * our normal source port allocation map. If it's outside the range of our
- * allocation/deallocation scheme just let them use it.
- *
- * If the source port is outside our allocation range, the caller is
- * responsible for keeping track of their port usage.
- */
-static int c3cn_get_port(struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata)
-{
- unsigned int start;
- int idx;
-
- if (!cdata)
- goto error_out;
-
- if (c3cn->saddr.sin_port) {
- cxgb3i_log_error("connect, sin_port NON-ZERO %u.\n",
- c3cn->saddr.sin_port);
- return -EADDRINUSE;
- }
-
- spin_lock_bh(&cdata->lock);
- start = idx = cdata->sport_next;
- do {
- if (++idx >= cxgb3_max_connect)
- idx = 0;
- if (!cdata->sport_conn[idx]) {
- c3cn->saddr.sin_port = htons(cxgb3_sport_base + idx);
- cdata->sport_next = idx;
- cdata->sport_conn[idx] = c3cn;
- spin_unlock_bh(&cdata->lock);
-
- c3cn_conn_debug("%s reserve port %u.\n",
- cdata->cdev->name,
- cxgb3_sport_base + idx);
- return 0;
- }
- } while (idx != start);
- spin_unlock_bh(&cdata->lock);
-
-error_out:
- return -EADDRNOTAVAIL;
-}
-
-static void c3cn_put_port(struct s3_conn *c3cn)
-{
- if (!c3cn->cdev)
- return;
-
- if (c3cn->saddr.sin_port) {
- struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
- int idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
-
- c3cn->saddr.sin_port = 0;
- if (idx < 0 || idx >= cxgb3_max_connect)
- return;
- spin_lock_bh(&cdata->lock);
- cdata->sport_conn[idx] = NULL;
- spin_unlock_bh(&cdata->lock);
- c3cn_conn_debug("%s, release port %u.\n",
- cdata->cdev->name, cxgb3_sport_base + idx);
- }
-}
-
-static inline void c3cn_set_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
-{
- __set_bit(flag, &c3cn->flags);
- c3cn_conn_debug("c3cn 0x%p, set %d, s %u, f 0x%lx.\n",
- c3cn, flag, c3cn->state, c3cn->flags);
-}
-
-static inline void c3cn_clear_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
-{
- __clear_bit(flag, &c3cn->flags);
- c3cn_conn_debug("c3cn 0x%p, clear %d, s %u, f 0x%lx.\n",
- c3cn, flag, c3cn->state, c3cn->flags);
-}
-
-static inline int c3cn_flag(struct s3_conn *c3cn, enum c3cn_flags flag)
-{
- if (c3cn == NULL)
- return 0;
- return test_bit(flag, &c3cn->flags);
-}
-
-static void c3cn_set_state(struct s3_conn *c3cn, int state)
-{
- c3cn_conn_debug("c3cn 0x%p state -> %u.\n", c3cn, state);
- c3cn->state = state;
-}
-
-static inline void c3cn_hold(struct s3_conn *c3cn)
-{
- atomic_inc(&c3cn->refcnt);
-}
-
-static inline void c3cn_put(struct s3_conn *c3cn)
-{
- if (atomic_dec_and_test(&c3cn->refcnt)) {
- c3cn_conn_debug("free c3cn 0x%p, s %u, f 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
- kfree(c3cn);
- }
-}
-
-static void c3cn_closed(struct s3_conn *c3cn)
-{
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- c3cn_put_port(c3cn);
- c3cn_release_offload_resources(c3cn);
- c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
- cxgb3i_conn_closing(c3cn);
-}
-
-/*
- * CPL (Chelsio Protocol Language) defines a message passing interface between
- * the host driver and T3 asic.
- * The section below implments CPLs that related to iscsi tcp connection
- * open/close/abort and data send/receive.
- */
-
-/*
- * CPL connection active open request: host ->
- */
-static unsigned int find_best_mtu(const struct t3c_data *d, unsigned short mtu)
-{
- int i = 0;
-
- while (i < d->nmtus - 1 && d->mtus[i + 1] <= mtu)
- ++i;
- return i;
-}
-
-static unsigned int select_mss(struct s3_conn *c3cn, unsigned int pmtu)
-{
- unsigned int idx;
- struct dst_entry *dst = c3cn->dst_cache;
- struct t3cdev *cdev = c3cn->cdev;
- const struct t3c_data *td = T3C_DATA(cdev);
- u16 advmss = dst_metric(dst, RTAX_ADVMSS);
-
- if (advmss > pmtu - 40)
- advmss = pmtu - 40;
- if (advmss < td->mtus[0] - 40)
- advmss = td->mtus[0] - 40;
- idx = find_best_mtu(td, advmss + 40);
- return idx;
-}
-
-static inline int compute_wscale(int win)
-{
- int wscale = 0;
- while (wscale < 14 && (65535<<wscale) < win)
- wscale++;
- return wscale;
-}
-
-static inline unsigned int calc_opt0h(struct s3_conn *c3cn)
-{
- int wscale = compute_wscale(cxgb3_rcv_win);
- return V_KEEP_ALIVE(1) |
- F_TCAM_BYPASS |
- V_WND_SCALE(wscale) |
- V_MSS_IDX(c3cn->mss_idx);
-}
-
-static inline unsigned int calc_opt0l(struct s3_conn *c3cn)
-{
- return V_ULP_MODE(ULP_MODE_ISCSI) |
- V_RCV_BUFSIZ(cxgb3_rcv_win>>10);
-}
-
-static void make_act_open_req(struct s3_conn *c3cn, struct sk_buff *skb,
- unsigned int atid, const struct l2t_entry *e)
-{
- struct cpl_act_open_req *req;
-
- c3cn_conn_debug("c3cn 0x%p, atid 0x%x.\n", c3cn, atid);
-
- skb->priority = CPL_PRIORITY_SETUP;
- req = (struct cpl_act_open_req *)__skb_put(skb, sizeof(*req));
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
- req->wr.wr_lo = 0;
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, atid));
- req->local_port = c3cn->saddr.sin_port;
- req->peer_port = c3cn->daddr.sin_port;
- req->local_ip = c3cn->saddr.sin_addr.s_addr;
- req->peer_ip = c3cn->daddr.sin_addr.s_addr;
- req->opt0h = htonl(calc_opt0h(c3cn) | V_L2T_IDX(e->idx) |
- V_TX_CHANNEL(e->smt_idx));
- req->opt0l = htonl(calc_opt0l(c3cn));
- req->params = 0;
- req->opt2 = 0;
-}
-
-static void fail_act_open(struct s3_conn *c3cn, int errno)
-{
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
- c3cn->err = errno;
- c3cn_closed(c3cn);
-}
-
-static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
-{
- struct s3_conn *c3cn = (struct s3_conn *)skb->sk;
-
- c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);
-
- c3cn_hold(c3cn);
- spin_lock_bh(&c3cn->lock);
- if (c3cn->state == C3CN_STATE_CONNECTING)
- fail_act_open(c3cn, -EHOSTUNREACH);
- spin_unlock_bh(&c3cn->lock);
- c3cn_put(c3cn);
- __kfree_skb(skb);
-}
-
-/*
- * CPL connection close request: host ->
- *
- * Close a connection by sending a CPL_CLOSE_CON_REQ message and queue it to
- * the write queue (i.e., after any unsent txt data).
- */
-static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb,
- int flags)
-{
- skb_tcp_seq(skb) = c3cn->write_seq;
- skb_flags(skb) = flags;
- __skb_queue_tail(&c3cn->write_queue, skb);
-}
-
-static void send_close_req(struct s3_conn *c3cn)
-{
- struct sk_buff *skb = c3cn->cpl_close;
- struct cpl_close_con_req *req = (struct cpl_close_con_req *)skb->head;
- unsigned int tid = c3cn->tid;
-
- c3cn_conn_debug("c3cn 0x%p, state 0x%x, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- c3cn->cpl_close = NULL;
-
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
- req->wr.wr_lo = htonl(V_WR_TID(tid));
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid));
- req->rsvd = htonl(c3cn->write_seq);
-
- skb_entail(c3cn, skb, C3CB_FLAG_NO_APPEND);
- if (c3cn->state != C3CN_STATE_CONNECTING)
- c3cn_push_tx_frames(c3cn, 1);
-}
-
-/*
- * CPL connection abort request: host ->
- *
- * Send an ABORT_REQ message. Makes sure we do not send multiple ABORT_REQs
- * for the same connection and also that we do not try to send a message
- * after the connection has closed.
- */
-static void abort_arp_failure(struct t3cdev *cdev, struct sk_buff *skb)
-{
- struct cpl_abort_req *req = cplhdr(skb);
-
- c3cn_conn_debug("tdev 0x%p.\n", cdev);
-
- req->cmd = CPL_ABORT_NO_RST;
- cxgb3_ofld_send(cdev, skb);
-}
-
-static inline void c3cn_purge_write_queue(struct s3_conn *c3cn)
-{
- struct sk_buff *skb;
-
- while ((skb = __skb_dequeue(&c3cn->write_queue)))
- __kfree_skb(skb);
-}
-
-static void send_abort_req(struct s3_conn *c3cn)
-{
- struct sk_buff *skb = c3cn->cpl_abort_req;
- struct cpl_abort_req *req;
- unsigned int tid = c3cn->tid;
-
- if (unlikely(c3cn->state == C3CN_STATE_ABORTING) || !skb ||
- !c3cn->cdev)
- return;
-
- c3cn_set_state(c3cn, C3CN_STATE_ABORTING);
-
- c3cn_conn_debug("c3cn 0x%p, flag ABORT_RPL + ABORT_SHUT.\n", c3cn);
-
- c3cn_set_flag(c3cn, C3CN_ABORT_RPL_PENDING);
-
- /* Purge the send queue so we don't send anything after an abort. */
- c3cn_purge_write_queue(c3cn);
-
- c3cn->cpl_abort_req = NULL;
- req = (struct cpl_abort_req *)skb->head;
- memset(req, 0, sizeof(*req));
-
- skb->priority = CPL_PRIORITY_DATA;
- set_arp_failure_handler(skb, abort_arp_failure);
-
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ));
- req->wr.wr_lo = htonl(V_WR_TID(tid));
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
- req->rsvd0 = htonl(c3cn->snd_nxt);
- req->rsvd1 = !c3cn_flag(c3cn, C3CN_TX_DATA_SENT);
- req->cmd = CPL_ABORT_SEND_RST;
-
- l2t_send(c3cn->cdev, skb, c3cn->l2t);
-}
-
-/*
- * CPL connection abort reply: host ->
- *
- * Send an ABORT_RPL message in response of the ABORT_REQ received.
- */
-static void send_abort_rpl(struct s3_conn *c3cn, int rst_status)
-{
- struct sk_buff *skb = c3cn->cpl_abort_rpl;
- struct cpl_abort_rpl *rpl = (struct cpl_abort_rpl *)skb->head;
-
- c3cn->cpl_abort_rpl = NULL;
-
- skb->priority = CPL_PRIORITY_DATA;
- memset(rpl, 0, sizeof(*rpl));
- rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
- rpl->wr.wr_lo = htonl(V_WR_TID(c3cn->tid));
- OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, c3cn->tid));
- rpl->cmd = rst_status;
-
- cxgb3_ofld_send(c3cn->cdev, skb);
-}
-
-/*
- * CPL connection rx data ack: host ->
- * Send RX credits through an RX_DATA_ACK CPL message. Returns the number of
- * credits sent.
- */
-static u32 send_rx_credits(struct s3_conn *c3cn, u32 credits, u32 dack)
-{
- struct sk_buff *skb;
- struct cpl_rx_data_ack *req;
-
- skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
- if (!skb)
- return 0;
-
- req = (struct cpl_rx_data_ack *)__skb_put(skb, sizeof(*req));
- req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
- req->wr.wr_lo = 0;
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, c3cn->tid));
- req->credit_dack = htonl(dack | V_RX_CREDITS(credits));
- skb->priority = CPL_PRIORITY_ACK;
- cxgb3_ofld_send(c3cn->cdev, skb);
- return credits;
-}
-
-/*
- * CPL connection tx data: host ->
- *
- * Send iscsi PDU via TX_DATA CPL message. Returns the number of
- * credits sent.
- * Each TX_DATA consumes work request credit (wrs), so we need to keep track of
- * how many we've used so far and how many are pending (i.e., yet ack'ed by T3).
- */
-
-/*
- * For ULP connections HW may inserts digest bytes into the pdu. Those digest
- * bytes are not sent by the host but are part of the TCP payload and therefore
- * consume TCP sequence space.
- */
-static const unsigned int cxgb3_ulp_extra_len[] = { 0, 4, 4, 8 };
-static inline unsigned int ulp_extra_len(const struct sk_buff *skb)
-{
- return cxgb3_ulp_extra_len[skb_ulp_mode(skb) & 3];
-}
-
-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 extra two fragments are for iscsi bhs and payload padding.
- */
-#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)
-{
- int i;
-
- if (skb_wrs[1]) /* already initialized */
- return;
-
- for (i = 1; i < SKB_WR_LIST_SIZE; i++) {
- int sgl_len = (3 * i) / 2 + (i & 1);
-
- sgl_len += 3;
- skb_wrs[i] = (sgl_len <= wr_len
- ? 1 : 1 + (sgl_len - 2) / (wr_len - 1));
- }
-
- wrlen = wr_len * 8;
-}
-
-static inline void reset_wr_list(struct s3_conn *c3cn)
-{
- c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL;
-}
-
-/*
- * Add a WR to a connections's list of pending WRs. This is a singly-linked
- * list of sk_buffs operating as a FIFO. The head is kept in wr_pending_head
- * and the tail in wr_pending_tail.
- */
-static inline void enqueue_wr(struct s3_conn *c3cn,
- struct sk_buff *skb)
-{
- skb_tx_wr_next(skb) = NULL;
-
- /*
- * We want to take an extra reference since both us and the driver
- * need to free the packet before it's really freed. We know there's
- * just one user currently so we use atomic_set rather than skb_get
- * to avoid the atomic op.
- */
- atomic_set(&skb->users, 2);
-
- if (!c3cn->wr_pending_head)
- c3cn->wr_pending_head = skb;
- else
- 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;
-}
-
-static inline void free_wr_skb(struct sk_buff *skb)
-{
- kfree_skb(skb);
-}
-
-static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn)
-{
- struct sk_buff *skb = c3cn->wr_pending_head;
-
- if (likely(skb)) {
- /* Don't bother clearing the tail */
- c3cn->wr_pending_head = skb_tx_wr_next(skb);
- skb_tx_wr_next(skb) = NULL;
- }
- return skb;
-}
-
-static void purge_wr_queue(struct s3_conn *c3cn)
-{
- struct sk_buff *skb;
- while ((skb = dequeue_wr(c3cn)) != NULL)
- free_wr_skb(skb);
-}
-
-static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb,
- 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_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 */
- req->len = htonl(len);
- req->param = htonl(V_TX_PORT(c3cn->l2t->smt_idx));
- /* V_TX_ULP_SUBMODE sets both the mode and submode */
- req->flags = htonl(V_TX_ULP_SUBMODE(skb_ulp_mode(skb)) |
- V_TX_SHOVE((skb_peek(&c3cn->write_queue) ? 0 : 1)));
-
- if (!c3cn_flag(c3cn, C3CN_TX_DATA_SENT)) {
- req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT |
- V_TX_CPU_IDX(c3cn->qset));
- /* Sendbuffer is in units of 32KB. */
- req->param |= htonl(V_TX_SNDBUF(cxgb3_snd_win >> 15));
- c3cn_set_flag(c3cn, C3CN_TX_DATA_SENT);
- }
-}
-
-/**
- * c3cn_push_tx_frames -- start transmit
- * @c3cn: the offloaded connection
- * @req_completion: request wr_ack or not
- *
- * Prepends TX_DATA_WR or CPL_CLOSE_CON_REQ headers to buffers waiting in a
- * connection's send queue and sends them on to T3. Must be called with the
- * connection's lock held. Returns the amount of send buffer space that was
- * freed as a result of sending queued data to T3.
- */
-static void arp_failure_discard(struct t3cdev *cdev, struct sk_buff *skb)
-{
- kfree_skb(skb);
-}
-
-static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
-{
- int total_size = 0;
- struct sk_buff *skb;
- struct t3cdev *cdev;
- struct cxgb3i_sdev_data *cdata;
-
- if (unlikely(c3cn->state == C3CN_STATE_CONNECTING ||
- c3cn->state == C3CN_STATE_CLOSE_WAIT_1 ||
- c3cn->state >= C3CN_STATE_ABORTING)) {
- c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n",
- c3cn, c3cn->state);
- return 0;
- }
-
- cdev = c3cn->cdev;
- cdata = CXGB3_SDEV_DATA(cdev);
-
- while (c3cn->wr_avail
- && (skb = skb_peek(&c3cn->write_queue)) != NULL) {
- int len = skb->len; /* length before skb_push */
- int frags = skb_shinfo(skb)->nr_frags + (len != skb->data_len);
- int wrs_needed = skb_wrs[frags];
-
- if (wrs_needed > 1 && len + sizeof(struct tx_data_wr) <= wrlen)
- wrs_needed = 1;
-
- WARN_ON(frags >= SKB_WR_LIST_SIZE || wrs_needed < 1);
-
- 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->data_len, frags,
- wrs_needed, c3cn->wr_avail);
- break;
- }
-
- __skb_unlink(skb, &c3cn->write_queue);
- skb->priority = CPL_PRIORITY_DATA;
- skb->csum = wrs_needed; /* remember this until the WR_ACK */
- c3cn->wr_avail -= wrs_needed;
- c3cn->wr_unacked += wrs_needed;
- enqueue_wr(c3cn, 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);
-
-
- 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;
- }
- 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;
- set_arp_failure_handler(skb, arp_failure_discard);
- l2t_send(cdev, skb, c3cn->l2t);
- }
- return total_size;
-}
-
-/*
- * process_cpl_msg: -> host
- * Top-level CPL message processing used by most CPL messages that
- * pertain to connections.
- */
-static inline void process_cpl_msg(void (*fn)(struct s3_conn *,
- struct sk_buff *),
- struct s3_conn *c3cn,
- struct sk_buff *skb)
-{
- spin_lock_bh(&c3cn->lock);
- fn(c3cn, skb);
- spin_unlock_bh(&c3cn->lock);
-}
-
-/*
- * process_cpl_msg_ref: -> host
- * Similar to process_cpl_msg() but takes an extra connection reference around
- * the call to the handler. Should be used if the handler may drop a
- * connection reference.
- */
-static inline void process_cpl_msg_ref(void (*fn) (struct s3_conn *,
- struct sk_buff *),
- struct s3_conn *c3cn,
- struct sk_buff *skb)
-{
- c3cn_hold(c3cn);
- process_cpl_msg(fn, c3cn, skb);
- c3cn_put(c3cn);
-}
-
-/*
- * Process a CPL_ACT_ESTABLISH message: -> host
- * Updates connection state from an active establish CPL message. Runs with
- * the connection lock held.
- */
-
-static inline void s3_free_atid(struct t3cdev *cdev, unsigned int tid)
-{
- struct s3_conn *c3cn = cxgb3_free_atid(cdev, tid);
- if (c3cn)
- c3cn_put(c3cn);
-}
-
-static void c3cn_established(struct s3_conn *c3cn, u32 snd_isn,
- unsigned int opt)
-{
- c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);
-
- c3cn->write_seq = c3cn->snd_nxt = c3cn->snd_una = snd_isn;
-
- /*
- * Causes the first RX_DATA_ACK to supply any Rx credits we couldn't
- * pass through opt0.
- */
- if (cxgb3_rcv_win > (M_RCV_BUFSIZ << 10))
- c3cn->rcv_wup -= cxgb3_rcv_win - (M_RCV_BUFSIZ << 10);
-
- dst_confirm(c3cn->dst_cache);
-
- smp_mb();
-
- c3cn_set_state(c3cn, C3CN_STATE_ESTABLISHED);
-}
-
-static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- struct cpl_act_establish *req = cplhdr(skb);
- u32 rcv_isn = ntohl(req->rcv_isn); /* real RCV_ISN + 1 */
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (unlikely(c3cn->state != C3CN_STATE_CONNECTING))
- cxgb3i_log_error("TID %u expected SYN_SENT, got EST., s %u\n",
- c3cn->tid, c3cn->state);
-
- c3cn->copied_seq = c3cn->rcv_wup = c3cn->rcv_nxt = rcv_isn;
- c3cn_established(c3cn, ntohl(req->snd_isn), ntohs(req->tcp_opt));
-
- __kfree_skb(skb);
-
- if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED)))
- /* upper layer has requested closing */
- send_abort_req(c3cn);
- 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,
- void *ctx)
-{
- struct cpl_act_establish *req = cplhdr(skb);
- unsigned int tid = GET_TID(req);
- unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
- struct s3_conn *c3cn = ctx;
- struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
-
- c3cn_conn_debug("rcv, tid 0x%x, c3cn 0x%p, s %u, f 0x%lx.\n",
- tid, c3cn, c3cn->state, c3cn->flags);
-
- c3cn->tid = tid;
- c3cn_hold(c3cn);
- cxgb3_insert_tid(cdata->cdev, cdata->client, c3cn, tid);
- s3_free_atid(cdev, atid);
-
- c3cn->qset = G_QNUM(ntohl(skb->csum));
-
- process_cpl_msg(process_act_establish, c3cn, skb);
- return 0;
-}
-
-/*
- * Process a CPL_ACT_OPEN_RPL message: -> host
- * Handle active open failures.
- */
-static int act_open_rpl_status_to_errno(int status)
-{
- switch (status) {
- case CPL_ERR_CONN_RESET:
- return -ECONNREFUSED;
- case CPL_ERR_ARP_MISS:
- return -EHOSTUNREACH;
- case CPL_ERR_CONN_TIMEDOUT:
- return -ETIMEDOUT;
- case CPL_ERR_TCAM_FULL:
- return -ENOMEM;
- case CPL_ERR_CONN_EXIST:
- cxgb3i_log_error("ACTIVE_OPEN_RPL: 4-tuple in use\n");
- return -EADDRINUSE;
- default:
- return -EIO;
- }
-}
-
-static void act_open_retry_timer(unsigned long data)
-{
- struct sk_buff *skb;
- struct s3_conn *c3cn = (struct s3_conn *)data;
-
- c3cn_conn_debug("c3cn 0x%p, state %u.\n", c3cn, c3cn->state);
-
- spin_lock_bh(&c3cn->lock);
- skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC);
- if (!skb)
- fail_act_open(c3cn, -ENOMEM);
- else {
- skb->sk = (struct sock *)c3cn;
- set_arp_failure_handler(skb, act_open_req_arp_failure);
- make_act_open_req(c3cn, skb, c3cn->tid, c3cn->l2t);
- l2t_send(c3cn->cdev, skb, c3cn->l2t);
- }
- spin_unlock_bh(&c3cn->lock);
- c3cn_put(c3cn);
-}
-
-static void process_act_open_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- struct cpl_act_open_rpl *rpl = cplhdr(skb);
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (rpl->status == CPL_ERR_CONN_EXIST &&
- c3cn->retry_timer.function != act_open_retry_timer) {
- c3cn->retry_timer.function = act_open_retry_timer;
- if (!mod_timer(&c3cn->retry_timer, jiffies + HZ / 2))
- c3cn_hold(c3cn);
- } else
- fail_act_open(c3cn, act_open_rpl_status_to_errno(rpl->status));
- __kfree_skb(skb);
-}
-
-static int do_act_open_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
-{
- struct s3_conn *c3cn = ctx;
- struct cpl_act_open_rpl *rpl = cplhdr(skb);
-
- c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, s %u, f 0x%lx.\n",
- rpl->status, c3cn, c3cn->state, c3cn->flags);
-
- if (rpl->status != CPL_ERR_TCAM_FULL &&
- rpl->status != CPL_ERR_CONN_EXIST &&
- rpl->status != CPL_ERR_ARP_MISS)
- cxgb3_queue_tid_release(cdev, GET_TID(rpl));
-
- process_cpl_msg_ref(process_act_open_rpl, c3cn, skb);
- return 0;
-}
-
-/*
- * Process PEER_CLOSE CPL messages: -> host
- * Handle peer FIN.
- */
-static void process_peer_close(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
- goto out;
-
- switch (c3cn->state) {
- case C3CN_STATE_ESTABLISHED:
- c3cn_set_state(c3cn, C3CN_STATE_PASSIVE_CLOSE);
- break;
- case C3CN_STATE_ACTIVE_CLOSE:
- c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_2);
- break;
- case C3CN_STATE_CLOSE_WAIT_1:
- c3cn_closed(c3cn);
- break;
- case C3CN_STATE_ABORTING:
- break;
- default:
- cxgb3i_log_error("%s: peer close, TID %u in bad state %u\n",
- c3cn->cdev->name, c3cn->tid, c3cn->state);
- }
-
- cxgb3i_conn_closing(c3cn);
-out:
- __kfree_skb(skb);
-}
-
-static int do_peer_close(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
-{
- struct s3_conn *c3cn = ctx;
-
- c3cn_conn_debug("rcv, c3cn 0x%p, s %u, f 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
- process_cpl_msg_ref(process_peer_close, c3cn, skb);
- return 0;
-}
-
-/*
- * Process CLOSE_CONN_RPL CPL message: -> host
- * Process a peer ACK to our FIN.
- */
-static void process_close_con_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- struct cpl_close_con_rpl *rpl = cplhdr(skb);
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- c3cn->snd_una = ntohl(rpl->snd_nxt) - 1; /* exclude FIN */
-
- if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING))
- goto out;
-
- switch (c3cn->state) {
- case C3CN_STATE_ACTIVE_CLOSE:
- c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_1);
- break;
- case C3CN_STATE_CLOSE_WAIT_1:
- case C3CN_STATE_CLOSE_WAIT_2:
- c3cn_closed(c3cn);
- break;
- case C3CN_STATE_ABORTING:
- break;
- default:
- cxgb3i_log_error("%s: close_rpl, TID %u in bad state %u\n",
- c3cn->cdev->name, c3cn->tid, c3cn->state);
- }
-
-out:
- kfree_skb(skb);
-}
-
-static int do_close_con_rpl(struct t3cdev *cdev, struct sk_buff *skb,
- void *ctx)
-{
- struct s3_conn *c3cn = ctx;
-
- c3cn_conn_debug("rcv, c3cn 0x%p, s %u, f 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- process_cpl_msg_ref(process_close_con_rpl, c3cn, skb);
- return 0;
-}
-
-/*
- * Process ABORT_REQ_RSS CPL message: -> host
- * Process abort requests. If we are waiting for an ABORT_RPL we ignore this
- * request except that we need to reply to it.
- */
-
-static int abort_status_to_errno(struct s3_conn *c3cn, int abort_reason,
- int *need_rst)
-{
- switch (abort_reason) {
- case CPL_ERR_BAD_SYN: /* fall through */
- case CPL_ERR_CONN_RESET:
- return c3cn->state > C3CN_STATE_ESTABLISHED ?
- -EPIPE : -ECONNRESET;
- case CPL_ERR_XMIT_TIMEDOUT:
- case CPL_ERR_PERSIST_TIMEDOUT:
- case CPL_ERR_FINWAIT2_TIMEDOUT:
- case CPL_ERR_KEEPALIVE_TIMEDOUT:
- return -ETIMEDOUT;
- default:
- return -EIO;
- }
-}
-
-static void process_abort_req(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- int rst_status = CPL_ABORT_NO_RST;
- const struct cpl_abort_req_rss *req = cplhdr(skb);
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (!c3cn_flag(c3cn, C3CN_ABORT_REQ_RCVD)) {
- c3cn_set_flag(c3cn, C3CN_ABORT_REQ_RCVD);
- c3cn_set_state(c3cn, C3CN_STATE_ABORTING);
- __kfree_skb(skb);
- return;
- }
-
- c3cn_clear_flag(c3cn, C3CN_ABORT_REQ_RCVD);
- send_abort_rpl(c3cn, rst_status);
-
- if (!c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING)) {
- c3cn->err =
- abort_status_to_errno(c3cn, req->status, &rst_status);
- c3cn_closed(c3cn);
- }
-}
-
-static int do_abort_req(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
-{
- const struct cpl_abort_req_rss *req = cplhdr(skb);
- struct s3_conn *c3cn = ctx;
-
- c3cn_conn_debug("rcv, c3cn 0x%p, s 0x%x, f 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
- req->status == CPL_ERR_PERSIST_NEG_ADVICE) {
- __kfree_skb(skb);
- return 0;
- }
-
- process_cpl_msg_ref(process_abort_req, c3cn, skb);
- return 0;
-}
-
-/*
- * Process ABORT_RPL_RSS CPL message: -> host
- * Process abort replies. We only process these messages if we anticipate
- * them as the coordination between SW and HW in this area is somewhat lacking
- * and sometimes we get ABORT_RPLs after we are done with the connection that
- * originated the ABORT_REQ.
- */
-static void process_abort_rpl(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- if (c3cn_flag(c3cn, C3CN_ABORT_RPL_PENDING)) {
- if (!c3cn_flag(c3cn, C3CN_ABORT_RPL_RCVD))
- c3cn_set_flag(c3cn, C3CN_ABORT_RPL_RCVD);
- else {
- c3cn_clear_flag(c3cn, C3CN_ABORT_RPL_RCVD);
- c3cn_clear_flag(c3cn, C3CN_ABORT_RPL_PENDING);
- if (c3cn_flag(c3cn, C3CN_ABORT_REQ_RCVD))
- cxgb3i_log_error("%s tid %u, ABORT_RPL_RSS\n",
- c3cn->cdev->name, c3cn->tid);
- c3cn_closed(c3cn);
- }
- }
- __kfree_skb(skb);
-}
-
-static int do_abort_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
-{
- struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
- struct s3_conn *c3cn = ctx;
-
- c3cn_conn_debug("rcv, status 0x%x, c3cn 0x%p, s %u, 0x%lx.\n",
- rpl->status, c3cn, c3cn ? c3cn->state : 0,
- c3cn ? c3cn->flags : 0UL);
-
- /*
- * Ignore replies to post-close aborts indicating that the abort was
- * requested too late. These connections are terminated when we get
- * PEER_CLOSE or CLOSE_CON_RPL and by the time the abort_rpl_rss
- * arrives the TID is either no longer used or it has been recycled.
- */
- if (rpl->status == CPL_ERR_ABORT_FAILED)
- goto discard;
-
- /*
- * Sometimes we've already closed the connection, e.g., a post-close
- * abort races with ABORT_REQ_RSS, the latter frees the connection
- * expecting the ABORT_REQ will fail with CPL_ERR_ABORT_FAILED,
- * but FW turns the ABORT_REQ into a regular one and so we get
- * ABORT_RPL_RSS with status 0 and no connection.
- */
- if (!c3cn)
- goto discard;
-
- process_cpl_msg_ref(process_abort_rpl, c3cn, skb);
- return 0;
-
-discard:
- __kfree_skb(skb);
- return 0;
-}
-
-/*
- * Process RX_ISCSI_HDR CPL message: -> host
- * Handle received PDUs, the payload could be DDP'ed. If not, the payload
- * follow after the bhs.
- */
-static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- struct cpl_iscsi_hdr *hdr_cpl = cplhdr(skb);
- struct cpl_iscsi_hdr_norss data_cpl;
- struct cpl_rx_data_ddp_norss ddp_cpl;
- unsigned int hdr_len, data_len, status;
- unsigned int len;
- int err;
-
- if (unlikely(c3cn->state >= C3CN_STATE_PASSIVE_CLOSE)) {
- if (c3cn->state != C3CN_STATE_ABORTING)
- send_abort_req(c3cn);
- __kfree_skb(skb);
- return;
- }
-
- 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));
-
- len = hdr_len = ntohs(hdr_cpl->len);
- /* msg coalesce is off or not enough data received */
- if (skb->len <= hdr_len) {
- cxgb3i_log_error("%s: TID %u, ISCSI_HDR, skb len %u < %u.\n",
- c3cn->cdev->name, c3cn->tid,
- skb->len, hdr_len);
- goto abort_conn;
- }
-
- err = skb_copy_bits(skb, skb->len - sizeof(ddp_cpl), &ddp_cpl,
- sizeof(ddp_cpl));
- if (err < 0)
- goto abort_conn;
-
- skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY;
- 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_rx_pdulen(skb), status);
-
- if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT))
- skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR;
- if (status & (1 << RX_DDP_STATUS_DCRC_SHIFT))
- skb_ulp_mode(skb) |= ULP2_FLAG_DCRC_ERROR;
- if (status & (1 << RX_DDP_STATUS_PAD_SHIFT))
- skb_ulp_mode(skb) |= ULP2_FLAG_PAD_ERROR;
-
- if (skb->len > (hdr_len + sizeof(ddp_cpl))) {
- err = skb_copy_bits(skb, hdr_len, &data_cpl, sizeof(data_cpl));
- if (err < 0)
- goto abort_conn;
- data_len = ntohs(data_cpl.len);
- len += sizeof(data_cpl) + data_len;
- } 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_rx_pdulen(skb);
- __pskb_trim(skb, len);
- __skb_queue_tail(&c3cn->receive_queue, skb);
- cxgb3i_conn_pdu_ready(c3cn);
-
- return;
-
-abort_conn:
- send_abort_req(c3cn);
- __kfree_skb(skb);
-}
-
-static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
-{
- struct s3_conn *c3cn = ctx;
-
- process_cpl_msg(process_rx_iscsi_hdr, c3cn, skb);
- return 0;
-}
-
-/*
- * Process TX_DATA_ACK CPL messages: -> host
- * 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;
-
- while (credits) {
- struct sk_buff *p = peek_wr(c3cn);
-
- if (unlikely(!p)) {
- cxgb3i_log_error("%u WR_ACK credits for TID %u with "
- "nothing pending, state %u\n",
- credits, c3cn->tid, c3cn->state);
- 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 {
- dequeue_wr(c3cn);
- credits -= p->csum;
- free_wr_skb(p);
- }
- }
-
- 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)) {
- if (c3cn_push_tx_frames(c3cn, 0))
- cxgb3i_conn_tx_open(c3cn);
- } else
- cxgb3i_conn_tx_open(c3cn);
-out_free:
- __kfree_skb(skb);
-}
-
-static int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
-{
- struct s3_conn *c3cn = ctx;
-
- process_cpl_msg(process_wr_ack, c3cn, skb);
- return 0;
-}
-
-/*
- * for each connection, pre-allocate skbs needed for close/abort requests. So
- * that we can service the request right away.
- */
-static void c3cn_free_cpl_skbs(struct s3_conn *c3cn)
-{
- if (c3cn->cpl_close)
- kfree_skb(c3cn->cpl_close);
- if (c3cn->cpl_abort_req)
- kfree_skb(c3cn->cpl_abort_req);
- if (c3cn->cpl_abort_rpl)
- kfree_skb(c3cn->cpl_abort_rpl);
-}
-
-static int c3cn_alloc_cpl_skbs(struct s3_conn *c3cn)
-{
- c3cn->cpl_close = alloc_skb(sizeof(struct cpl_close_con_req),
- GFP_KERNEL);
- if (!c3cn->cpl_close)
- return -ENOMEM;
- skb_put(c3cn->cpl_close, sizeof(struct cpl_close_con_req));
-
- c3cn->cpl_abort_req = alloc_skb(sizeof(struct cpl_abort_req),
- GFP_KERNEL);
- if (!c3cn->cpl_abort_req)
- goto free_cpl_skbs;
- skb_put(c3cn->cpl_abort_req, sizeof(struct cpl_abort_req));
-
- c3cn->cpl_abort_rpl = alloc_skb(sizeof(struct cpl_abort_rpl),
- GFP_KERNEL);
- if (!c3cn->cpl_abort_rpl)
- goto free_cpl_skbs;
- skb_put(c3cn->cpl_abort_rpl, sizeof(struct cpl_abort_rpl));
-
- return 0;
-
-free_cpl_skbs:
- c3cn_free_cpl_skbs(c3cn);
- return -ENOMEM;
-}
-
-/**
- * c3cn_release_offload_resources - release offload resource
- * @c3cn: the offloaded iscsi tcp connection.
- * Release resources held by an offload connection (TID, L2T entry, etc.)
- */
-static void c3cn_release_offload_resources(struct s3_conn *c3cn)
-{
- struct t3cdev *cdev = c3cn->cdev;
- unsigned int tid = c3cn->tid;
-
- c3cn->qset = 0;
- c3cn_free_cpl_skbs(c3cn);
-
- if (c3cn->wr_avail != c3cn->wr_max) {
- purge_wr_queue(c3cn);
- reset_wr_list(c3cn);
- }
-
- if (cdev) {
- if (c3cn->l2t) {
- l2t_release(L2DATA(cdev), c3cn->l2t);
- c3cn->l2t = NULL;
- }
- if (c3cn->state == C3CN_STATE_CONNECTING)
- /* we have ATID */
- s3_free_atid(cdev, tid);
- else {
- /* we have TID */
- cxgb3_remove_tid(cdev, (void *)c3cn, tid);
- c3cn_put(c3cn);
- }
- }
-
- c3cn->dst_cache = NULL;
- c3cn->cdev = NULL;
-}
-
-/**
- * cxgb3i_c3cn_create - allocate and initialize an s3_conn structure
- * returns the s3_conn structure allocated.
- */
-struct s3_conn *cxgb3i_c3cn_create(void)
-{
- struct s3_conn *c3cn;
-
- c3cn = kzalloc(sizeof(*c3cn), GFP_KERNEL);
- if (!c3cn)
- return NULL;
-
- /* pre-allocate close/abort cpl, so we don't need to wait for memory
- when close/abort is requested. */
- if (c3cn_alloc_cpl_skbs(c3cn) < 0)
- goto free_c3cn;
-
- c3cn_conn_debug("alloc c3cn 0x%p.\n", c3cn);
-
- c3cn->flags = 0;
- spin_lock_init(&c3cn->lock);
- atomic_set(&c3cn->refcnt, 1);
- skb_queue_head_init(&c3cn->receive_queue);
- skb_queue_head_init(&c3cn->write_queue);
- setup_timer(&c3cn->retry_timer, NULL, (unsigned long)c3cn);
- rwlock_init(&c3cn->callback_lock);
-
- return c3cn;
-
-free_c3cn:
- kfree(c3cn);
- return NULL;
-}
-
-static void c3cn_active_close(struct s3_conn *c3cn)
-{
- int data_lost;
- int close_req = 0;
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
-
- dst_confirm(c3cn->dst_cache);
-
- c3cn_hold(c3cn);
- spin_lock_bh(&c3cn->lock);
-
- data_lost = skb_queue_len(&c3cn->receive_queue);
- __skb_queue_purge(&c3cn->receive_queue);
-
- switch (c3cn->state) {
- case C3CN_STATE_CLOSED:
- case C3CN_STATE_ACTIVE_CLOSE:
- case C3CN_STATE_CLOSE_WAIT_1:
- case C3CN_STATE_CLOSE_WAIT_2:
- case C3CN_STATE_ABORTING:
- /* nothing need to be done */
- break;
- case C3CN_STATE_CONNECTING:
- /* defer until cpl_act_open_rpl or cpl_act_establish */
- c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
- break;
- case C3CN_STATE_ESTABLISHED:
- close_req = 1;
- c3cn_set_state(c3cn, C3CN_STATE_ACTIVE_CLOSE);
- break;
- case C3CN_STATE_PASSIVE_CLOSE:
- close_req = 1;
- c3cn_set_state(c3cn, C3CN_STATE_CLOSE_WAIT_2);
- break;
- }
-
- if (close_req) {
- if (data_lost)
- /* Unread data was tossed, zap the connection. */
- send_abort_req(c3cn);
- else
- send_close_req(c3cn);
- }
-
- spin_unlock_bh(&c3cn->lock);
- c3cn_put(c3cn);
-}
-
-/**
- * cxgb3i_c3cn_release - close and release an iscsi tcp connection and any
- * resource held
- * @c3cn: the iscsi tcp connection
- */
-void cxgb3i_c3cn_release(struct s3_conn *c3cn)
-{
- c3cn_conn_debug("c3cn 0x%p, s %u, f 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
- if (unlikely(c3cn->state == C3CN_STATE_CONNECTING))
- c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
- else if (likely(c3cn->state != C3CN_STATE_CLOSED))
- c3cn_active_close(c3cn);
- c3cn_put(c3cn);
-}
-
-static int is_cxgb3_dev(struct net_device *dev)
-{
- struct cxgb3i_sdev_data *cdata;
- struct net_device *ndev = dev;
-
- if (dev->priv_flags & IFF_802_1Q_VLAN)
- ndev = vlan_dev_real_dev(dev);
-
- write_lock(&cdata_rwlock);
- list_for_each_entry(cdata, &cdata_list, list) {
- struct adap_ports *ports = &cdata->ports;
- int i;
-
- for (i = 0; i < ports->nports; i++)
- if (ndev == ports->lldevs[i]) {
- write_unlock(&cdata_rwlock);
- return 1;
- }
- }
- write_unlock(&cdata_rwlock);
- return 0;
-}
-
-/**
- * cxgb3_egress_dev - return the cxgb3 egress device
- * @root_dev: the root device anchoring the search
- * @c3cn: the connection used to determine egress port in bonding mode
- * @context: in bonding mode, indicates a connection set up or failover
- *
- * Return egress device or NULL if the egress device isn't one of our ports.
- */
-static struct net_device *cxgb3_egress_dev(struct net_device *root_dev,
- struct s3_conn *c3cn,
- int context)
-{
- while (root_dev) {
- if (root_dev->priv_flags & IFF_802_1Q_VLAN)
- root_dev = vlan_dev_real_dev(root_dev);
- else if (is_cxgb3_dev(root_dev))
- return root_dev;
- else
- return NULL;
- }
- return NULL;
-}
-
-static struct rtable *find_route(struct net_device *dev,
- __be32 saddr, __be32 daddr,
- __be16 sport, __be16 dport)
-{
- struct rtable *rt;
- struct flowi fl = {
- .oif = dev ? dev->ifindex : 0,
- .nl_u = {
- .ip4_u = {
- .daddr = daddr,
- .saddr = saddr,
- .tos = 0 } },
- .proto = IPPROTO_TCP,
- .uli_u = {
- .ports = {
- .sport = sport,
- .dport = dport } } };
-
- if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0))
- return NULL;
- return rt;
-}
-
-/*
- * Assign offload parameters to some connection fields.
- */
-static void init_offload_conn(struct s3_conn *c3cn,
- struct t3cdev *cdev,
- struct dst_entry *dst)
-{
- BUG_ON(c3cn->cdev != cdev);
- 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));
-
- reset_wr_list(c3cn);
-}
-
-static int initiate_act_open(struct s3_conn *c3cn, struct net_device *dev)
-{
- struct cxgb3i_sdev_data *cdata = NDEV2CDATA(dev);
- struct t3cdev *cdev = cdata->cdev;
- struct dst_entry *dst = c3cn->dst_cache;
- struct sk_buff *skb;
-
- c3cn_conn_debug("c3cn 0x%p, state %u, flag 0x%lx.\n",
- c3cn, c3cn->state, c3cn->flags);
- /*
- * Initialize connection data. Note that the flags and ULP mode are
- * initialized higher up ...
- */
- c3cn->dev = dev;
- c3cn->cdev = cdev;
- c3cn->tid = cxgb3_alloc_atid(cdev, cdata->client, c3cn);
- if (c3cn->tid < 0)
- goto out_err;
-
- c3cn->qset = 0;
- c3cn->l2t = t3_l2t_get(cdev, dst->neighbour, dev);
- if (!c3cn->l2t)
- goto free_tid;
-
- skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_KERNEL);
- if (!skb)
- goto free_l2t;
-
- skb->sk = (struct sock *)c3cn;
- set_arp_failure_handler(skb, act_open_req_arp_failure);
-
- c3cn_hold(c3cn);
-
- init_offload_conn(c3cn, cdev, dst);
- c3cn->err = 0;
-
- make_act_open_req(c3cn, skb, c3cn->tid, c3cn->l2t);
- l2t_send(cdev, skb, c3cn->l2t);
- return 0;
-
-free_l2t:
- l2t_release(L2DATA(cdev), c3cn->l2t);
-free_tid:
- s3_free_atid(cdev, c3cn->tid);
- c3cn->tid = 0;
-out_err:
- return -EINVAL;
-}
-
-/**
- * cxgb3i_find_dev - find the interface associated with the given address
- * @ipaddr: ip address
- */
-static struct net_device *
-cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr)
-{
- struct flowi fl;
- int err;
- struct rtable *rt;
-
- memset(&fl, 0, sizeof(fl));
- fl.nl_u.ip4_u.daddr = ipaddr;
-
- err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl);
- if (!err)
- return (&rt->dst)->dev;
-
- return NULL;
-}
-
-/**
- * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address
- * @c3cn: the iscsi tcp connection
- * @usin: destination address
- *
- * return 0 if active open request is sent, < 0 otherwise.
- */
-int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn,
- struct sockaddr_in *usin)
-{
- struct rtable *rt;
- struct cxgb3i_sdev_data *cdata;
- struct t3cdev *cdev;
- __be32 sipv4;
- struct net_device *dstdev;
- int err;
-
- c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev);
-
- if (usin->sin_family != AF_INET)
- return -EAFNOSUPPORT;
-
- c3cn->daddr.sin_port = usin->sin_port;
- c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr;
-
- dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr);
- if (!dstdev || !is_cxgb3_dev(dstdev))
- return -ENETUNREACH;
-
- if (dstdev->priv_flags & IFF_802_1Q_VLAN)
- dev = dstdev;
-
- rt = find_route(dev, c3cn->saddr.sin_addr.s_addr,
- c3cn->daddr.sin_addr.s_addr,
- c3cn->saddr.sin_port,
- c3cn->daddr.sin_port);
- if (rt == NULL) {
- c3cn_conn_debug("NO route to 0x%x, port %u, dev %s.\n",
- c3cn->daddr.sin_addr.s_addr,
- ntohs(c3cn->daddr.sin_port),
- dev ? dev->name : "any");
- return -ENETUNREACH;
- }
-
- if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
- c3cn_conn_debug("multi-cast route to 0x%x, port %u, dev %s.\n",
- c3cn->daddr.sin_addr.s_addr,
- ntohs(c3cn->daddr.sin_port),
- dev ? dev->name : "any");
- ip_rt_put(rt);
- return -ENETUNREACH;
- }
-
- if (!c3cn->saddr.sin_addr.s_addr)
- c3cn->saddr.sin_addr.s_addr = rt->rt_src;
-
- /* now commit destination to connection */
- c3cn->dst_cache = &rt->dst;
-
- /* try to establish an offloaded connection */
- dev = cxgb3_egress_dev(c3cn->dst_cache->dev, c3cn, 0);
- if (dev == NULL) {
- c3cn_conn_debug("c3cn 0x%p, egress dev NULL.\n", c3cn);
- return -ENETUNREACH;
- }
- cdata = NDEV2CDATA(dev);
- cdev = cdata->cdev;
-
- /* get a source port if one hasn't been provided */
- err = c3cn_get_port(c3cn, cdata);
- if (err)
- return err;
-
- c3cn_conn_debug("c3cn 0x%p get port %u.\n",
- c3cn, ntohs(c3cn->saddr.sin_port));
-
- sipv4 = cxgb3i_get_private_ipv4addr(dev);
- if (!sipv4) {
- c3cn_conn_debug("c3cn 0x%p, iscsi ip not configured.\n", c3cn);
- sipv4 = c3cn->saddr.sin_addr.s_addr;
- cxgb3i_set_private_ipv4addr(dev, sipv4);
- } else
- c3cn->saddr.sin_addr.s_addr = sipv4;
-
- c3cn_conn_debug("c3cn 0x%p, %pI4,%u-%pI4,%u SYN_SENT.\n",
- c3cn,
- &c3cn->saddr.sin_addr.s_addr,
- ntohs(c3cn->saddr.sin_port),
- &c3cn->daddr.sin_addr.s_addr,
- ntohs(c3cn->daddr.sin_port));
-
- c3cn_set_state(c3cn, C3CN_STATE_CONNECTING);
- if (!initiate_act_open(c3cn, dev))
- return 0;
-
- /*
- * If we get here, we don't have an offload connection so simply
- * return a failure.
- */
- err = -ENOTSUPP;
-
- /*
- * This trashes the connection and releases the local port,
- * if necessary.
- */
- c3cn_conn_debug("c3cn 0x%p -> CLOSED.\n", c3cn);
- c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
- ip_rt_put(rt);
- c3cn_put_port(c3cn);
- return err;
-}
-
-/**
- * cxgb3i_c3cn_rx_credits - ack received tcp data.
- * @c3cn: iscsi tcp connection
- * @copied: # of bytes processed
- *
- * Called after some received data has been read. It returns RX credits
- * to the HW for the amount of data processed.
- */
-void cxgb3i_c3cn_rx_credits(struct s3_conn *c3cn, int copied)
-{
- struct t3cdev *cdev;
- int must_send;
- u32 credits, dack = 0;
-
- if (c3cn->state != C3CN_STATE_ESTABLISHED)
- return;
-
- credits = c3cn->copied_seq - c3cn->rcv_wup;
- if (unlikely(!credits))
- return;
-
- cdev = c3cn->cdev;
-
- if (unlikely(cxgb3_rx_credit_thres == 0))
- return;
-
- dack = F_RX_DACK_CHANGE | V_RX_DACK_MODE(1);
-
- /*
- * For coalescing to work effectively ensure the receive window has
- * at least 16KB left.
- */
- must_send = credits + 16384 >= cxgb3_rcv_win;
-
- if (must_send || credits >= cxgb3_rx_credit_thres)
- c3cn->rcv_wup += send_rx_credits(c3cn, credits, dack);
-}
-
-/**
- * cxgb3i_c3cn_send_pdus - send the skbs containing iscsi pdus
- * @c3cn: iscsi tcp connection
- * @skb: skb contains the iscsi pdu
- *
- * Add a list of skbs to a connection send queue. The skbs must comply with
- * the max size limit of the device and have a headroom of at least
- * TX_HEADER_LEN bytes.
- * Return # of bytes queued.
- */
-int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
-{
- struct sk_buff *next;
- int err, copied = 0;
-
- spin_lock_bh(&c3cn->lock);
-
- if (c3cn->state != C3CN_STATE_ESTABLISHED) {
- c3cn_tx_debug("c3cn 0x%p, not in est. state %u.\n",
- c3cn, c3cn->state);
- err = -EAGAIN;
- goto out_err;
- }
-
- 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 = -ENOBUFS;
- goto out_err;
- }
-
- while (skb) {
- int frags = skb_shinfo(skb)->nr_frags +
- (skb->len != skb->data_len);
-
- if (unlikely(skb_headroom(skb) < TX_HEADER_LEN)) {
- c3cn_tx_debug("c3cn 0x%p, skb head.\n", c3cn);
- err = -EINVAL;
- goto out_err;
- }
-
- if (frags >= SKB_WR_LIST_SIZE) {
- cxgb3i_log_error("c3cn 0x%p, tx frags %d, len %u,%u.\n",
- c3cn, skb_shinfo(skb)->nr_frags,
- skb->len, skb->data_len);
- err = -EINVAL;
- goto out_err;
- }
-
- next = skb->next;
- skb->next = NULL;
- skb_entail(c3cn, skb, C3CB_FLAG_NO_APPEND | C3CB_FLAG_NEED_HDR);
- copied += skb->len;
- c3cn->write_seq += skb->len + ulp_extra_len(skb);
- skb = next;
- }
-done:
- if (likely(skb_queue_len(&c3cn->write_queue)))
- c3cn_push_tx_frames(c3cn, 1);
- spin_unlock_bh(&c3cn->lock);
- return copied;
-
-out_err:
- if (copied == 0 && err == -EPIPE)
- copied = c3cn->err ? c3cn->err : -EPIPE;
- else
- copied = err;
- goto done;
-}
-
-static void sdev_data_cleanup(struct cxgb3i_sdev_data *cdata)
-{
- struct adap_ports *ports = &cdata->ports;
- struct s3_conn *c3cn;
- int i;
-
- for (i = 0; i < cxgb3_max_connect; i++) {
- if (cdata->sport_conn[i]) {
- c3cn = cdata->sport_conn[i];
- cdata->sport_conn[i] = NULL;
-
- spin_lock_bh(&c3cn->lock);
- c3cn->cdev = NULL;
- c3cn_set_flag(c3cn, C3CN_OFFLOAD_DOWN);
- c3cn_closed(c3cn);
- spin_unlock_bh(&c3cn->lock);
- }
- }
-
- for (i = 0; i < ports->nports; i++)
- NDEV2CDATA(ports->lldevs[i]) = NULL;
-
- cxgb3i_free_big_mem(cdata);
-}
-
-void cxgb3i_sdev_cleanup(void)
-{
- struct cxgb3i_sdev_data *cdata;
-
- write_lock(&cdata_rwlock);
- list_for_each_entry(cdata, &cdata_list, list) {
- list_del(&cdata->list);
- sdev_data_cleanup(cdata);
- }
- write_unlock(&cdata_rwlock);
-}
-
-int cxgb3i_sdev_init(cxgb3_cpl_handler_func *cpl_handlers)
-{
- cpl_handlers[CPL_ACT_ESTABLISH] = do_act_establish;
- cpl_handlers[CPL_ACT_OPEN_RPL] = do_act_open_rpl;
- cpl_handlers[CPL_PEER_CLOSE] = do_peer_close;
- cpl_handlers[CPL_ABORT_REQ_RSS] = do_abort_req;
- cpl_handlers[CPL_ABORT_RPL_RSS] = do_abort_rpl;
- cpl_handlers[CPL_CLOSE_CON_RPL] = do_close_con_rpl;
- cpl_handlers[CPL_TX_DMA_ACK] = do_wr_ack;
- cpl_handlers[CPL_ISCSI_HDR] = do_iscsi_hdr;
-
- if (cxgb3_max_connect > CXGB3I_MAX_CONN)
- cxgb3_max_connect = CXGB3I_MAX_CONN;
- return 0;
-}
-
-/**
- * cxgb3i_sdev_add - allocate and initialize resources for each adapter found
- * @cdev: t3cdev adapter
- * @client: cxgb3 driver client
- */
-void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
-{
- struct cxgb3i_sdev_data *cdata;
- struct ofld_page_info rx_page_info;
- unsigned int wr_len;
- int mapsize = cxgb3_max_connect * sizeof(struct s3_conn *);
- int i;
-
- cdata = cxgb3i_alloc_big_mem(sizeof(*cdata) + mapsize, GFP_KERNEL);
- if (!cdata) {
- cxgb3i_log_warn("t3dev 0x%p, offload up, OOM %d.\n",
- cdev, mapsize);
- return;
- }
-
- if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0 ||
- cdev->ctl(cdev, GET_PORTS, &cdata->ports) < 0 ||
- cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
- cxgb3i_log_warn("t3dev 0x%p, offload up, ioctl failed.\n",
- cdev);
- goto free_cdata;
- }
-
- s3_init_wr_tab(wr_len);
-
- spin_lock_init(&cdata->lock);
- INIT_LIST_HEAD(&cdata->list);
- cdata->cdev = cdev;
- cdata->client = client;
-
- for (i = 0; i < cdata->ports.nports; i++)
- NDEV2CDATA(cdata->ports.lldevs[i]) = cdata;
-
- write_lock(&cdata_rwlock);
- list_add_tail(&cdata->list, &cdata_list);
- write_unlock(&cdata_rwlock);
-
- cxgb3i_log_info("t3dev 0x%p, offload up, added.\n", cdev);
- return;
-
-free_cdata:
- cxgb3i_free_big_mem(cdata);
-}
-
-/**
- * cxgb3i_sdev_remove - free the allocated resources for the adapter
- * @cdev: t3cdev adapter
- */
-void cxgb3i_sdev_remove(struct t3cdev *cdev)
-{
- struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
-
- cxgb3i_log_info("t3dev 0x%p, offload down, remove.\n", cdev);
-
- write_lock(&cdata_rwlock);
- list_del(&cdata->list);
- write_unlock(&cdata_rwlock);
-
- sdev_data_cleanup(cdata);
-}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
deleted file mode 100644
index 6a1d86b1fafe..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * cxgb3i_offload.h: Chelsio S3xx iscsi offloaded tcp connection management
- *
- * Copyright (C) 2003-2008 Chelsio Communications. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
- * release for licensing terms and conditions.
- *
- * Written by: Dimitris Michailidis (dm@chelsio.com)
- * Karen Xie (kxie@chelsio.com)
- */
-
-#ifndef _CXGB3I_OFFLOAD_H
-#define _CXGB3I_OFFLOAD_H
-
-#include <linux/skbuff.h>
-#include <linux/in.h>
-
-#include "common.h"
-#include "adapter.h"
-#include "t3cdev.h"
-#include "cxgb3_offload.h"
-
-#define cxgb3i_log_error(fmt...) printk(KERN_ERR "cxgb3i: ERR! " fmt)
-#define cxgb3i_log_warn(fmt...) printk(KERN_WARNING "cxgb3i: WARN! " fmt)
-#define cxgb3i_log_info(fmt...) printk(KERN_INFO "cxgb3i: " fmt)
-#define cxgb3i_log_debug(fmt, args...) \
- printk(KERN_INFO "cxgb3i: %s - " fmt, __func__ , ## args)
-
-/**
- * struct s3_conn - an iscsi tcp connection structure
- *
- * @dev: net device of with connection
- * @cdev: adapter t3cdev for net device
- * @flags: see c3cn_flags below
- * @tid: connection id assigned by the h/w
- * @qset: queue set used by connection
- * @mss_idx: Maximum Segment Size table index
- * @l2t: ARP resolution entry for offload packets
- * @wr_max: maximum in-flight writes
- * @wr_avail: number of writes available
- * @wr_unacked: writes since last request for completion notification
- * @wr_pending_head: head of pending write queue
- * @wr_pending_tail: tail of pending write queue
- * @cpl_close: skb for cpl_close_req
- * @cpl_abort_req: skb for cpl_abort_req
- * @cpl_abort_rpl: skb for cpl_abort_rpl
- * @lock: connection status lock
- * @refcnt: reference count on connection
- * @state: connection state
- * @saddr: source ip/port address
- * @daddr: destination ip/port address
- * @dst_cache: reference to destination route
- * @receive_queue: received PDUs
- * @write_queue: un-pushed pending writes
- * @retry_timer: retry timer for various operations
- * @err: connection error status
- * @callback_lock: lock for opaque user context
- * @user_data: opaque user context
- * @rcv_nxt: next receive seq. #
- * @copied_seq: head of yet unread data
- * @rcv_wup: rcv_nxt on last window update sent
- * @snd_nxt: next sequence we send
- * @snd_una: first byte we want an ack for
- * @write_seq: tail+1 of data held in send buffer
- */
-struct s3_conn {
- struct net_device *dev;
- struct t3cdev *cdev;
- unsigned long flags;
- int tid;
- int qset;
- int mss_idx;
- struct l2t_entry *l2t;
- int wr_max;
- int wr_avail;
- int wr_unacked;
- struct sk_buff *wr_pending_head;
- struct sk_buff *wr_pending_tail;
- struct sk_buff *cpl_close;
- struct sk_buff *cpl_abort_req;
- struct sk_buff *cpl_abort_rpl;
- spinlock_t lock;
- atomic_t refcnt;
- volatile unsigned int state;
- struct sockaddr_in saddr;
- struct sockaddr_in daddr;
- struct dst_entry *dst_cache;
- struct sk_buff_head receive_queue;
- struct sk_buff_head write_queue;
- struct timer_list retry_timer;
- int err;
- rwlock_t callback_lock;
- void *user_data;
-
- u32 rcv_nxt;
- u32 copied_seq;
- u32 rcv_wup;
- u32 snd_nxt;
- u32 snd_una;
- u32 write_seq;
-};
-
-/*
- * connection state
- */
-enum conn_states {
- C3CN_STATE_CONNECTING = 1,
- C3CN_STATE_ESTABLISHED,
- C3CN_STATE_ACTIVE_CLOSE,
- C3CN_STATE_PASSIVE_CLOSE,
- C3CN_STATE_CLOSE_WAIT_1,
- C3CN_STATE_CLOSE_WAIT_2,
- C3CN_STATE_ABORTING,
- C3CN_STATE_CLOSED,
-};
-
-static inline unsigned int c3cn_is_closing(const struct s3_conn *c3cn)
-{
- return c3cn->state >= C3CN_STATE_ACTIVE_CLOSE;
-}
-static inline unsigned int c3cn_is_established(const struct s3_conn *c3cn)
-{
- return c3cn->state == C3CN_STATE_ESTABLISHED;
-}
-
-/*
- * Connection flags -- many to track some close related events.
- */
-enum c3cn_flags {
- C3CN_ABORT_RPL_RCVD, /* received one ABORT_RPL_RSS message */
- C3CN_ABORT_REQ_RCVD, /* received one ABORT_REQ_RSS message */
- C3CN_ABORT_RPL_PENDING, /* expecting an abort reply */
- C3CN_TX_DATA_SENT, /* already sent a TX_DATA WR */
- C3CN_ACTIVE_CLOSE_NEEDED, /* need to be closed */
- C3CN_OFFLOAD_DOWN /* offload function off */
-};
-
-/**
- * cxgb3i_sdev_data - Per adapter data.
- * Linked off of each Ethernet device port on the adapter.
- * Also available via the t3cdev structure since we have pointers to our port
- * net_device's there ...
- *
- * @list: list head to link elements
- * @cdev: t3cdev adapter
- * @client: CPL client pointer
- * @ports: array of adapter ports
- * @sport_next: next port
- * @sport_conn: source port connection
- */
-struct cxgb3i_sdev_data {
- struct list_head list;
- struct t3cdev *cdev;
- struct cxgb3_client *client;
- struct adap_ports ports;
- spinlock_t lock;
- unsigned int sport_next;
- struct s3_conn *sport_conn[0];
-};
-#define NDEV2CDATA(ndev) (*(struct cxgb3i_sdev_data **)&(ndev)->ec_ptr)
-#define CXGB3_SDEV_DATA(cdev) NDEV2CDATA((cdev)->lldev)
-
-void cxgb3i_sdev_cleanup(void);
-int cxgb3i_sdev_init(cxgb3_cpl_handler_func *);
-void cxgb3i_sdev_add(struct t3cdev *, struct cxgb3_client *);
-void cxgb3i_sdev_remove(struct t3cdev *);
-
-struct s3_conn *cxgb3i_c3cn_create(void);
-int cxgb3i_c3cn_connect(struct net_device *, struct s3_conn *,
- struct sockaddr_in *);
-void cxgb3i_c3cn_rx_credits(struct s3_conn *, int);
-int cxgb3i_c3cn_send_pdus(struct s3_conn *, struct sk_buff *);
-void cxgb3i_c3cn_release(struct s3_conn *);
-
-/**
- * cxgb3_skb_cb - control block for received pdu state and ULP mode management.
- *
- * @flag: see C3CB_FLAG_* below
- * @ulp_mode: ULP mode/submode of sk_buff
- * @seq: tcp sequence number
- */
-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;
- 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_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 */
- C3CB_FLAG_NO_APPEND = 1 << 1, /* don't grow this skb */
- C3CB_FLAG_COMPL = 1 << 2, /* request WR completion */
-};
-
-/**
- * sge_opaque_hdr -
- * Opaque version of structure the SGE stores at skb->head of TX_DATA packets
- * and for which we must reserve space.
- */
-struct sge_opaque_hdr {
- void *dev;
- dma_addr_t addr[MAX_SKB_FRAGS + 1];
-};
-
-/* 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
- */
-#define cxgb3i_get_private_ipv4addr(ndev) \
- (((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr)
-#define cxgb3i_set_private_ipv4addr(ndev, addr) \
- (((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr) = addr
-
-/* max. connections per adapter */
-#define CXGB3I_MAX_CONN 16384
-#endif /* _CXGB3_OFFLOAD_H */
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
deleted file mode 100644
index dc5e3e77a351..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * cxgb3i_pdu.c: Chelsio S3xx iSCSI driver.
- *
- * Copyright (c) 2008 Chelsio Communications, Inc.
- * Copyright (c) 2008 Mike Christie
- * Copyright (c) 2008 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/crypto.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_host.h>
-
-#include "cxgb3i.h"
-#include "cxgb3i_pdu.h"
-
-#ifdef __DEBUG_CXGB3I_RX__
-#define cxgb3i_rx_debug cxgb3i_log_debug
-#else
-#define cxgb3i_rx_debug(fmt...)
-#endif
-
-#ifdef __DEBUG_CXGB3I_TX__
-#define cxgb3i_tx_debug cxgb3i_log_debug
-#else
-#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;
-
-/*
- * pdu receive, interact with libiscsi_tcp
- */
-static inline int read_pdu_skb(struct iscsi_conn *conn, struct sk_buff *skb,
- unsigned int offset, int offloaded)
-{
- int status = 0;
- int bytes_read;
-
- bytes_read = iscsi_tcp_recv_skb(conn, skb, offset, offloaded, &status);
- switch (status) {
- case ISCSI_TCP_CONN_ERR:
- return -EIO;
- case ISCSI_TCP_SUSPENDED:
- /* no transfer - just have caller flush queue */
- return bytes_read;
- case ISCSI_TCP_SKB_DONE:
- /*
- * pdus should always fit in the skb and we should get
- * segment done notifcation.
- */
- iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu or skb.");
- return -EFAULT;
- case ISCSI_TCP_SEGMENT_DONE:
- return bytes_read;
- default:
- iscsi_conn_printk(KERN_ERR, conn, "Invalid iscsi_tcp_recv_skb "
- "status %d\n", status);
- return -EINVAL;
- }
-}
-
-static int cxgb3i_conn_read_pdu_skb(struct iscsi_conn *conn,
- struct sk_buff *skb)
-{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- bool offloaded = 0;
- unsigned int offset;
- int rc;
-
- cxgb3i_rx_debug("conn 0x%p, skb 0x%p, len %u, flag 0x%x.\n",
- conn, skb, skb->len, skb_ulp_mode(skb));
-
- if (!iscsi_tcp_recv_segment_is_hdr(tcp_conn)) {
- iscsi_conn_failure(conn, ISCSI_ERR_PROTO);
- return -EIO;
- }
-
- if (conn->hdrdgst_en && (skb_ulp_mode(skb) & ULP2_FLAG_HCRC_ERROR)) {
- iscsi_conn_failure(conn, ISCSI_ERR_HDR_DGST);
- return -EIO;
- }
-
- if (conn->datadgst_en && (skb_ulp_mode(skb) & ULP2_FLAG_DCRC_ERROR)) {
- iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
- return -EIO;
- }
-
- /* iscsi hdr */
- rc = read_pdu_skb(conn, skb, 0, 0);
- if (rc <= 0)
- return rc;
-
- if (iscsi_tcp_recv_segment_is_hdr(tcp_conn))
- return 0;
-
- offset = rc;
- if (conn->hdrdgst_en)
- offset += ISCSI_DIGEST_SIZE;
-
- /* iscsi data */
- if (skb_ulp_mode(skb) & ULP2_FLAG_DATA_DDPED) {
- cxgb3i_rx_debug("skb 0x%p, opcode 0x%x, data %u, ddp'ed, "
- "itt 0x%x.\n",
- skb,
- tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK,
- tcp_conn->in.datalen,
- ntohl(tcp_conn->in.hdr->itt));
- offloaded = 1;
- } else {
- cxgb3i_rx_debug("skb 0x%p, opcode 0x%x, data %u, NOT ddp'ed, "
- "itt 0x%x.\n",
- skb,
- tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK,
- tcp_conn->in.datalen,
- ntohl(tcp_conn->in.hdr->itt));
- offset += sizeof(struct cpl_iscsi_hdr_norss);
- }
-
- rc = read_pdu_skb(conn, skb, offset, offloaded);
- if (rc < 0)
- return rc;
- else
- return 0;
-}
-
-/*
- * pdu transmit, interact with libiscsi_tcp
- */
-static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc)
-{
- u8 submode = 0;
-
- if (hcrc)
- submode |= 1;
- if (dcrc)
- submode |= 2;
- skb_ulp_mode(skb) = (ULP_MODE_ISCSI << 4) | submode;
-}
-
-void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
-{
- struct cxgb3i_task_data *tdata = task->dd_data +
- sizeof(struct iscsi_tcp_task);
-
- /* never reached the xmit task callout */
- 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 */
- cxgb3i_release_itt(task, task->hdr_itt);
- iscsi_tcp_cleanup_task(task);
-}
-
-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 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;
-
- /* 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, tdata->skb);
-
- 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)
- cxgb3i_reserve_itt(task, &task->hdr->itt);
-
- return 0;
-}
-
-int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
- unsigned int count)
-{
- struct iscsi_conn *conn = task->conn;
- 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);
- 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);
-
- skb_put(skb, task->hdr_len);
- tx_skb_setmode(skb, conn->hdrdgst_en, datalen ? conn->datadgst_en : 0);
- if (!count)
- return 0;
-
- if (task->sc) {
- 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;
- }
- 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);
- }
- if (padlen) {
- memset(dst, 0, padlen);
- padlen = 0;
- }
- 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);
-
- 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;
- 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;
- }
-
- return 0;
-}
-
-int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
-{
- 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;
-
- if (!skb)
- return 0;
-
- datalen = skb->data_len;
- tdata->skb = NULL;
- err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb);
- 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)
- pdulen += ISCSI_DIGEST_SIZE;
-
- task->conn->txdata_octets += pdulen;
- return 0;
- }
-
- if (err == -EAGAIN || err == -ENOBUFS) {
- /* reset skb to send when we are called again */
- tdata->skb = skb;
- return err;
- }
-
- kfree_skb(skb);
- cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n",
- task->itt, skb, skb->len, skb->data_len, err);
- iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err);
- iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED);
- return err;
-}
-
-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;
- memset(page_address(pad_page), 0, PAGE_SIZE);
- return 0;
-}
-
-void cxgb3i_pdu_cleanup(void)
-{
- if (pad_page) {
- __free_page(pad_page);
- pad_page = NULL;
- }
-}
-
-void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
-{
- struct sk_buff *skb;
- unsigned int read = 0;
- struct iscsi_conn *conn = c3cn->user_data;
- int err = 0;
-
- cxgb3i_rx_debug("cn 0x%p.\n", c3cn);
-
- read_lock(&c3cn->callback_lock);
- if (unlikely(!conn || conn->suspend_rx)) {
- cxgb3i_rx_debug("conn 0x%p, id %d, suspend_rx %lu!\n",
- conn, conn ? conn->id : 0xFF,
- conn ? conn->suspend_rx : 0xFF);
- read_unlock(&c3cn->callback_lock);
- return;
- }
- skb = skb_peek(&c3cn->receive_queue);
- while (!err && skb) {
- __skb_unlink(skb, &c3cn->receive_queue);
- 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);
- }
- read_unlock(&c3cn->callback_lock);
- c3cn->copied_seq += read;
- 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)
-{
- struct iscsi_conn *conn = c3cn->user_data;
-
- cxgb3i_tx_debug("cn 0x%p.\n", c3cn);
- if (conn) {
- cxgb3i_tx_debug("cn 0x%p, cid %d.\n", c3cn, conn->id);
- iscsi_conn_queue_work(conn);
- }
-}
-
-void cxgb3i_conn_closing(struct s3_conn *c3cn)
-{
- struct iscsi_conn *conn;
-
- read_lock(&c3cn->callback_lock);
- conn = c3cn->user_data;
- if (conn && c3cn->state != C3CN_STATE_ESTABLISHED)
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- read_unlock(&c3cn->callback_lock);
-}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/drivers/scsi/cxgb3i/cxgb3i_pdu.h
deleted file mode 100644
index 0770b23d90da..000000000000
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * cxgb3i_ulp2.h: Chelsio S3xx iSCSI driver.
- *
- * Copyright (c) 2008 Chelsio Communications, 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.
- *
- * Written by: Karen Xie (kxie@chelsio.com)
- */
-
-#ifndef __CXGB3I_ULP2_PDU_H__
-#define __CXGB3I_ULP2_PDU_H__
-
-struct cpl_iscsi_hdr_norss {
- union opcode_tid ot;
- u16 pdu_len_ddp;
- u16 len;
- u32 seq;
- u16 urg;
- u8 rsvd;
- u8 status;
-};
-
-struct cpl_rx_data_ddp_norss {
- union opcode_tid ot;
- u16 urg;
- u16 len;
- u32 seq;
- u32 nxt_seq;
- u32 ulp_crc;
- u32 ddp_status;
-};
-
-#define RX_DDP_STATUS_IPP_SHIFT 27 /* invalid pagepod */
-#define RX_DDP_STATUS_TID_SHIFT 26 /* tid mismatch */
-#define RX_DDP_STATUS_COLOR_SHIFT 25 /* color mismatch */
-#define RX_DDP_STATUS_OFFSET_SHIFT 24 /* offset mismatch */
-#define RX_DDP_STATUS_ULIMIT_SHIFT 23 /* ulimit error */
-#define RX_DDP_STATUS_TAG_SHIFT 22 /* tag mismatch */
-#define RX_DDP_STATUS_DCRC_SHIFT 21 /* dcrc error */
-#define RX_DDP_STATUS_HCRC_SHIFT 20 /* hcrc error */
-#define RX_DDP_STATUS_PAD_SHIFT 19 /* pad error */
-#define RX_DDP_STATUS_PPP_SHIFT 18 /* pagepod parity error */
-#define RX_DDP_STATUS_LLIMIT_SHIFT 17 /* llimit error */
-#define RX_DDP_STATUS_DDP_SHIFT 16 /* ddp'able */
-#define RX_DDP_STATUS_PMM_SHIFT 15 /* pagepod mismatch */
-
-#define ULP2_FLAG_DATA_READY 0x1
-#define ULP2_FLAG_DATA_DDPED 0x2
-#define ULP2_FLAG_HCRC_ERROR 0x10
-#define ULP2_FLAG_DCRC_ERROR 0x20
-#define ULP2_FLAG_PAD_ERROR 0x40
-
-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/cxgbi/Kconfig b/drivers/scsi/cxgbi/Kconfig
new file mode 100644
index 000000000000..17eb5d522f42
--- /dev/null
+++ b/drivers/scsi/cxgbi/Kconfig
@@ -0,0 +1,2 @@
+source "drivers/scsi/cxgbi/cxgb3i/Kconfig"
+source "drivers/scsi/cxgbi/cxgb4i/Kconfig"
diff --git a/drivers/scsi/cxgbi/Makefile b/drivers/scsi/cxgbi/Makefile
new file mode 100644
index 000000000000..86007e344955
--- /dev/null
+++ b/drivers/scsi/cxgbi/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libcxgbi.o cxgb3i/
+obj-$(CONFIG_SCSI_CXGB4_ISCSI) += libcxgbi.o cxgb4i/
diff --git a/drivers/scsi/cxgb3i/Kbuild b/drivers/scsi/cxgbi/cxgb3i/Kbuild
index 70d060b7ff4f..09dbf9efc8ea 100644
--- a/drivers/scsi/cxgb3i/Kbuild
+++ b/drivers/scsi/cxgbi/cxgb3i/Kbuild
@@ -1,4 +1,3 @@
EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb3
-cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o
diff --git a/drivers/scsi/cxgb3i/Kconfig b/drivers/scsi/cxgbi/cxgb3i/Kconfig
index bfdcaf5c9c57..5cf4e9831f1b 100644
--- a/drivers/scsi/cxgb3i/Kconfig
+++ b/drivers/scsi/cxgbi/cxgb3i/Kconfig
@@ -1,7 +1,7 @@
config SCSI_CXGB3_ISCSI
- tristate "Chelsio S3xx iSCSI support"
+ tristate "Chelsio T3 iSCSI support"
depends on CHELSIO_T3_DEPENDS
select CHELSIO_T3
select SCSI_ISCSI_ATTRS
---help---
- This driver supports iSCSI offload for the Chelsio S3 series devices.
+ This driver supports iSCSI offload for the Chelsio T3 devices.
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
new file mode 100644
index 000000000000..a01c1e238938
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -0,0 +1,1432 @@
+/*
+ * cxgb3i_offload.c: Chelsio S3xx iscsi offloaded tcp connection management
+ *
+ * Copyright (C) 2003-2008 Chelsio Communications. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
+ * release for licensing terms and conditions.
+ *
+ * Written by: Dimitris Michailidis (dm@chelsio.com)
+ * Karen Xie (kxie@chelsio.com)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <scsi/scsi_host.h>
+
+#include "common.h"
+#include "t3_cpl.h"
+#include "t3cdev.h"
+#include "cxgb3_defs.h"
+#include "cxgb3_ctl_defs.h"
+#include "cxgb3_offload.h"
+#include "firmware_exports.h"
+#include "cxgb3i.h"
+
+static unsigned int dbg_level;
+#include "../libcxgbi.h"
+
+#define DRV_MODULE_NAME "cxgb3i"
+#define DRV_MODULE_DESC "Chelsio T3 iSCSI Driver"
+#define DRV_MODULE_VERSION "2.0.0"
+#define DRV_MODULE_RELDATE "Jun. 2010"
+
+static char version[] =
+ DRV_MODULE_DESC " " DRV_MODULE_NAME
+ " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Chelsio Communications, Inc.");
+MODULE_DESCRIPTION(DRV_MODULE_DESC);
+MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(dbg_level, uint, 0644);
+MODULE_PARM_DESC(dbg_level, "debug flag (default=0)");
+
+static int cxgb3i_rcv_win = 256 * 1024;
+module_param(cxgb3i_rcv_win, int, 0644);
+MODULE_PARM_DESC(cxgb3i_rcv_win, "TCP receive window in bytes (default=256KB)");
+
+static int cxgb3i_snd_win = 128 * 1024;
+module_param(cxgb3i_snd_win, int, 0644);
+MODULE_PARM_DESC(cxgb3i_snd_win, "TCP send window in bytes (default=128KB)");
+
+static int cxgb3i_rx_credit_thres = 10 * 1024;
+module_param(cxgb3i_rx_credit_thres, int, 0644);
+MODULE_PARM_DESC(rx_credit_thres,
+ "RX credits return threshold in bytes (default=10KB)");
+
+static unsigned int cxgb3i_max_connect = 8 * 1024;
+module_param(cxgb3i_max_connect, uint, 0644);
+MODULE_PARM_DESC(cxgb3i_max_connect, "Max. # of connections (default=8092)");
+
+static unsigned int cxgb3i_sport_base = 20000;
+module_param(cxgb3i_sport_base, uint, 0644);
+MODULE_PARM_DESC(cxgb3i_sport_base, "starting port number (default=20000)");
+
+static void cxgb3i_dev_open(struct t3cdev *);
+static void cxgb3i_dev_close(struct t3cdev *);
+static void cxgb3i_dev_event_handler(struct t3cdev *, u32, u32);
+
+static struct cxgb3_client t3_client = {
+ .name = DRV_MODULE_NAME,
+ .handlers = cxgb3i_cpl_handlers,
+ .add = cxgb3i_dev_open,
+ .remove = cxgb3i_dev_close,
+ .event_handler = cxgb3i_dev_event_handler,
+};
+
+static struct scsi_host_template cxgb3i_host_template = {
+ .module = THIS_MODULE,
+ .name = DRV_MODULE_NAME,
+ .proc_name = DRV_MODULE_NAME,
+ .can_queue = CXGB3I_SCSI_HOST_QDEPTH,
+ .queuecommand = iscsi_queuecommand,
+ .change_queue_depth = iscsi_change_queue_depth,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = 0xFFFF,
+ .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
+ .eh_abort_handler = iscsi_eh_abort,
+ .eh_device_reset_handler = iscsi_eh_device_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
+ .target_alloc = iscsi_target_alloc,
+ .use_clustering = DISABLE_CLUSTERING,
+ .this_id = -1,
+};
+
+static struct iscsi_transport cxgb3i_iscsi_transport = {
+ .owner = THIS_MODULE,
+ .name = DRV_MODULE_NAME,
+ /* owner and name should be set already */
+ .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
+ | CAP_DATADGST | CAP_DIGEST_OFFLOAD |
+ CAP_PADDING_OFFLOAD,
+ .param_mask = ISCSI_MAX_RECV_DLENGTH | ISCSI_MAX_XMIT_DLENGTH |
+ ISCSI_HDRDGST_EN | ISCSI_DATADGST_EN |
+ ISCSI_INITIAL_R2T_EN | ISCSI_MAX_R2T |
+ ISCSI_IMM_DATA_EN | ISCSI_FIRST_BURST |
+ ISCSI_MAX_BURST | ISCSI_PDU_INORDER_EN |
+ ISCSI_DATASEQ_INORDER_EN | ISCSI_ERL |
+ ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS |
+ ISCSI_EXP_STATSN | ISCSI_PERSISTENT_PORT |
+ ISCSI_PERSISTENT_ADDRESS |
+ ISCSI_TARGET_NAME | ISCSI_TPGT |
+ ISCSI_USERNAME | ISCSI_PASSWORD |
+ ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
+ ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+ ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
+ ISCSI_PING_TMO | ISCSI_RECV_TMO |
+ ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
+ .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
+ ISCSI_HOST_INITIATOR_NAME |
+ ISCSI_HOST_NETDEV_NAME,
+ .get_host_param = cxgbi_get_host_param,
+ .set_host_param = cxgbi_set_host_param,
+ /* session management */
+ .create_session = cxgbi_create_session,
+ .destroy_session = cxgbi_destroy_session,
+ .get_session_param = iscsi_session_get_param,
+ /* connection management */
+ .create_conn = cxgbi_create_conn,
+ .bind_conn = cxgbi_bind_conn,
+ .destroy_conn = iscsi_tcp_conn_teardown,
+ .start_conn = iscsi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+ .get_conn_param = cxgbi_get_conn_param,
+ .set_param = cxgbi_set_conn_param,
+ .get_stats = cxgbi_get_conn_stats,
+ /* pdu xmit req from user space */
+ .send_pdu = iscsi_conn_send_pdu,
+ /* task */
+ .init_task = iscsi_tcp_task_init,
+ .xmit_task = iscsi_tcp_task_xmit,
+ .cleanup_task = cxgbi_cleanup_task,
+ /* pdu */
+ .alloc_pdu = cxgbi_conn_alloc_pdu,
+ .init_pdu = cxgbi_conn_init_pdu,
+ .xmit_pdu = cxgbi_conn_xmit_pdu,
+ .parse_pdu_itt = cxgbi_parse_pdu_itt,
+ /* TCP connect/disconnect */
+ .ep_connect = cxgbi_ep_connect,
+ .ep_poll = cxgbi_ep_poll,
+ .ep_disconnect = cxgbi_ep_disconnect,
+ /* Error recovery timeout call */
+ .session_recovery_timedout = iscsi_session_recovery_timedout,
+};
+
+static struct scsi_transport_template *cxgb3i_stt;
+
+/*
+ * CPL (Chelsio Protocol Language) defines a message passing interface between
+ * the host driver and Chelsio asic.
+ * The section below implments CPLs that related to iscsi tcp connection
+ * open/close/abort and data send/receive.
+ */
+
+static int push_tx_frames(struct cxgbi_sock *csk, int req_completion);
+
+static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
+ const struct l2t_entry *e)
+{
+ unsigned int wscale = cxgbi_sock_compute_wscale(cxgb3i_rcv_win);
+ struct cpl_act_open_req *req = (struct cpl_act_open_req *)skb->head;
+
+ skb->priority = CPL_PRIORITY_SETUP;
+
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, csk->atid));
+ req->local_port = csk->saddr.sin_port;
+ req->peer_port = csk->daddr.sin_port;
+ req->local_ip = csk->saddr.sin_addr.s_addr;
+ req->peer_ip = csk->daddr.sin_addr.s_addr;
+
+ req->opt0h = htonl(V_KEEP_ALIVE(1) | F_TCAM_BYPASS |
+ V_WND_SCALE(wscale) | V_MSS_IDX(csk->mss_idx) |
+ V_L2T_IDX(e->idx) | V_TX_CHANNEL(e->smt_idx));
+ req->opt0l = htonl(V_ULP_MODE(ULP2_MODE_ISCSI) |
+ V_RCV_BUFSIZ(cxgb3i_rcv_win>>10));
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, %pI4:%u-%pI4:%u, %u,%u,%u.\n",
+ csk, csk->state, csk->flags, csk->atid,
+ &req->local_ip, ntohs(req->local_port),
+ &req->peer_ip, ntohs(req->peer_port),
+ csk->mss_idx, e->idx, e->smt_idx);
+
+ l2t_send(csk->cdev->lldev, skb, csk->l2t);
+}
+
+static inline void act_open_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
+{
+ cxgbi_sock_act_open_req_arp_failure(NULL, skb);
+}
+
+/*
+ * CPL connection close request: host ->
+ *
+ * Close a connection by sending a CPL_CLOSE_CON_REQ message and queue it to
+ * the write queue (i.e., after any unsent txt data).
+ */
+static void send_close_req(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb = csk->cpl_close;
+ struct cpl_close_con_req *req = (struct cpl_close_con_req *)skb->head;
+ unsigned int tid = csk->tid;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ csk->cpl_close = NULL;
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
+ req->wr.wr_lo = htonl(V_WR_TID(tid));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid));
+ req->rsvd = htonl(csk->write_seq);
+
+ cxgbi_sock_skb_entail(csk, skb);
+ if (csk->state >= CTP_ESTABLISHED)
+ push_tx_frames(csk, 1);
+}
+
+/*
+ * CPL connection abort request: host ->
+ *
+ * Send an ABORT_REQ message. Makes sure we do not send multiple ABORT_REQs
+ * for the same connection and also that we do not try to send a message
+ * after the connection has closed.
+ */
+static void abort_arp_failure(struct t3cdev *tdev, struct sk_buff *skb)
+{
+ struct cpl_abort_req *req = cplhdr(skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "t3dev 0x%p, tid %u, skb 0x%p.\n",
+ tdev, GET_TID(req), skb);
+ req->cmd = CPL_ABORT_NO_RST;
+ cxgb3_ofld_send(tdev, skb);
+}
+
+static void send_abort_req(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb = csk->cpl_abort_req;
+ struct cpl_abort_req *req;
+
+ if (unlikely(csk->state == CTP_ABORTING || !skb))
+ return;
+ cxgbi_sock_set_state(csk, CTP_ABORTING);
+ cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_PENDING);
+ /* Purge the send queue so we don't send anything after an abort. */
+ cxgbi_sock_purge_write_queue(csk);
+
+ csk->cpl_abort_req = NULL;
+ req = (struct cpl_abort_req *)skb->head;
+ skb->priority = CPL_PRIORITY_DATA;
+ set_arp_failure_handler(skb, abort_arp_failure);
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ));
+ req->wr.wr_lo = htonl(V_WR_TID(csk->tid));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, csk->tid));
+ req->rsvd0 = htonl(csk->snd_nxt);
+ req->rsvd1 = !cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT);
+ req->cmd = CPL_ABORT_SEND_RST;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, snd_nxt %u, 0x%x.\n",
+ csk, csk->state, csk->flags, csk->tid, csk->snd_nxt,
+ req->rsvd1);
+
+ l2t_send(csk->cdev->lldev, skb, csk->l2t);
+}
+
+/*
+ * CPL connection abort reply: host ->
+ *
+ * Send an ABORT_RPL message in response of the ABORT_REQ received.
+ */
+static void send_abort_rpl(struct cxgbi_sock *csk, int rst_status)
+{
+ struct sk_buff *skb = csk->cpl_abort_rpl;
+ struct cpl_abort_rpl *rpl = (struct cpl_abort_rpl *)skb->head;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, status %d.\n",
+ csk, csk->state, csk->flags, csk->tid, rst_status);
+
+ csk->cpl_abort_rpl = NULL;
+ skb->priority = CPL_PRIORITY_DATA;
+ rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
+ rpl->wr.wr_lo = htonl(V_WR_TID(csk->tid));
+ OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, csk->tid));
+ rpl->cmd = rst_status;
+ cxgb3_ofld_send(csk->cdev->lldev, skb);
+}
+
+/*
+ * CPL connection rx data ack: host ->
+ * Send RX credits through an RX_DATA_ACK CPL message. Returns the number of
+ * credits sent.
+ */
+static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
+{
+ struct sk_buff *skb;
+ struct cpl_rx_data_ack *req;
+ u32 dack = F_RX_DACK_CHANGE | V_RX_DACK_MODE(1);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx,%u, credit %u, dack %u.\n",
+ csk, csk->state, csk->flags, csk->tid, credits, dack);
+
+ skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+ if (!skb) {
+ pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
+ return 0;
+ }
+ req = (struct cpl_rx_data_ack *)skb->head;
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, csk->tid));
+ req->credit_dack = htonl(F_RX_DACK_CHANGE | V_RX_DACK_MODE(1) |
+ V_RX_CREDITS(credits));
+ skb->priority = CPL_PRIORITY_ACK;
+ cxgb3_ofld_send(csk->cdev->lldev, skb);
+ return credits;
+}
+
+/*
+ * CPL connection tx data: host ->
+ *
+ * Send iscsi PDU via TX_DATA CPL message. Returns the number of
+ * credits sent.
+ * Each TX_DATA consumes work request credit (wrs), so we need to keep track of
+ * how many we've used so far and how many are pending (i.e., yet ack'ed by T3).
+ */
+
+static unsigned int wrlen __read_mostly;
+static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly;
+
+static void init_wr_tab(unsigned int wr_len)
+{
+ int i;
+
+ if (skb_wrs[1]) /* already initialized */
+ return;
+ for (i = 1; i < SKB_WR_LIST_SIZE; i++) {
+ int sgl_len = (3 * i) / 2 + (i & 1);
+
+ sgl_len += 3;
+ skb_wrs[i] = (sgl_len <= wr_len
+ ? 1 : 1 + (sgl_len - 2) / (wr_len - 1));
+ }
+ wrlen = wr_len * 8;
+}
+
+static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb,
+ int len, int req_completion)
+{
+ struct tx_data_wr *req;
+ struct l2t_entry *l2t = csk->l2t;
+
+ 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_completion ? F_WR_COMPL : 0));
+ req->wr_lo = htonl(V_WR_TID(csk->tid));
+ /* len includes the length of any HW ULP additions */
+ req->len = htonl(len);
+ /* V_TX_ULP_SUBMODE sets both the mode and submode */
+ req->flags = htonl(V_TX_ULP_SUBMODE(cxgbi_skcb_ulp_mode(skb)) |
+ V_TX_SHOVE((skb_peek(&csk->write_queue) ? 0 : 1)));
+ req->sndseq = htonl(csk->snd_nxt);
+ req->param = htonl(V_TX_PORT(l2t->smt_idx));
+
+ if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) {
+ req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT |
+ V_TX_CPU_IDX(csk->rss_qid));
+ /* sendbuffer is in units of 32KB. */
+ req->param |= htonl(V_TX_SNDBUF(cxgb3i_snd_win >> 15));
+ cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT);
+ }
+}
+
+/**
+ * push_tx_frames -- start transmit
+ * @c3cn: the offloaded connection
+ * @req_completion: request wr_ack or not
+ *
+ * Prepends TX_DATA_WR or CPL_CLOSE_CON_REQ headers to buffers waiting in a
+ * connection's send queue and sends them on to T3. Must be called with the
+ * connection's lock held. Returns the amount of send buffer space that was
+ * freed as a result of sending queued data to T3.
+ */
+
+static void arp_failure_skb_discard(struct t3cdev *dev, struct sk_buff *skb)
+{
+ kfree_skb(skb);
+}
+
+static int push_tx_frames(struct cxgbi_sock *csk, int req_completion)
+{
+ int total_size = 0;
+ struct sk_buff *skb;
+
+ if (unlikely(csk->state < CTP_ESTABLISHED ||
+ csk->state == CTP_CLOSE_WAIT_1 || csk->state >= CTP_ABORTING)) {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, in closing state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ return 0;
+ }
+
+ while (csk->wr_cred && (skb = skb_peek(&csk->write_queue)) != NULL) {
+ int len = skb->len; /* length before skb_push */
+ int frags = skb_shinfo(skb)->nr_frags + (len != skb->data_len);
+ int wrs_needed = skb_wrs[frags];
+
+ if (wrs_needed > 1 && len + sizeof(struct tx_data_wr) <= wrlen)
+ wrs_needed = 1;
+
+ WARN_ON(frags >= SKB_WR_LIST_SIZE || wrs_needed < 1);
+
+ if (csk->wr_cred < wrs_needed) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p, skb len %u/%u, frag %u, wr %d<%u.\n",
+ csk, skb->len, skb->data_len, frags,
+ wrs_needed, csk->wr_cred);
+ break;
+ }
+
+ __skb_unlink(skb, &csk->write_queue);
+ skb->priority = CPL_PRIORITY_DATA;
+ skb->csum = wrs_needed; /* remember this until the WR_ACK */
+ csk->wr_cred -= wrs_needed;
+ csk->wr_una_cred += wrs_needed;
+ cxgbi_sock_enqueue_wr(csk, skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p, enqueue, skb len %u/%u, frag %u, wr %d, "
+ "left %u, unack %u.\n",
+ csk, skb->len, skb->data_len, frags, skb->csum,
+ csk->wr_cred, csk->wr_una_cred);
+
+ if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) {
+ if ((req_completion &&
+ csk->wr_una_cred == wrs_needed) ||
+ csk->wr_una_cred >= csk->wr_max_cred / 2) {
+ req_completion = 1;
+ csk->wr_una_cred = 0;
+ }
+ len += cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb));
+ make_tx_data_wr(csk, skb, len, req_completion);
+ csk->snd_nxt += len;
+ cxgbi_skcb_clear_flag(skb, SKCBF_TX_NEED_HDR);
+ }
+ total_size += skb->truesize;
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p, tid 0x%x, send skb 0x%p.\n",
+ csk, csk->tid, skb);
+ set_arp_failure_handler(skb, arp_failure_skb_discard);
+ l2t_send(csk->cdev->lldev, skb, csk->l2t);
+ }
+ return total_size;
+}
+
+/*
+ * Process a CPL_ACT_ESTABLISH message: -> host
+ * Updates connection state from an active establish CPL message. Runs with
+ * the connection lock held.
+ */
+
+static inline void free_atid(struct cxgbi_sock *csk)
+{
+ if (cxgbi_sock_flag(csk, CTPF_HAS_ATID)) {
+ cxgb3_free_atid(csk->cdev->lldev, csk->atid);
+ cxgbi_sock_clear_flag(csk, CTPF_HAS_ATID);
+ cxgbi_sock_put(csk);
+ }
+}
+
+static int do_act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+ struct cpl_act_establish *req = cplhdr(skb);
+ unsigned int tid = GET_TID(req);
+ unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid));
+ u32 rcv_isn = ntohl(req->rcv_isn); /* real RCV_ISN + 1 */
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "atid 0x%x,tid 0x%x, csk 0x%p,%u,0x%lx, isn %u.\n",
+ atid, atid, csk, csk->state, csk->flags, rcv_isn);
+
+ cxgbi_sock_get(csk);
+ cxgbi_sock_set_flag(csk, CTPF_HAS_TID);
+ csk->tid = tid;
+ cxgb3_insert_tid(csk->cdev->lldev, &t3_client, csk, tid);
+
+ free_atid(csk);
+
+ csk->rss_qid = G_QNUM(ntohs(skb->csum));
+
+ spin_lock_bh(&csk->lock);
+ if (csk->retry_timer.function) {
+ del_timer(&csk->retry_timer);
+ csk->retry_timer.function = NULL;
+ }
+
+ if (unlikely(csk->state != CTP_ACTIVE_OPEN))
+ pr_info("csk 0x%p,%u,0x%lx,%u, got EST.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ csk->copied_seq = csk->rcv_wup = csk->rcv_nxt = rcv_isn;
+ if (cxgb3i_rcv_win > (M_RCV_BUFSIZ << 10))
+ csk->rcv_wup -= cxgb3i_rcv_win - (M_RCV_BUFSIZ << 10);
+
+ cxgbi_sock_established(csk, ntohl(req->snd_isn), ntohs(req->tcp_opt));
+
+ if (unlikely(cxgbi_sock_flag(csk, CTPF_ACTIVE_CLOSE_NEEDED)))
+ /* upper layer has requested closing */
+ send_abort_req(csk);
+ else {
+ if (skb_queue_len(&csk->write_queue))
+ push_tx_frames(csk, 1);
+ cxgbi_conn_tx_open(csk);
+ }
+
+ spin_unlock_bh(&csk->lock);
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process a CPL_ACT_OPEN_RPL message: -> host
+ * Handle active open failures.
+ */
+static int act_open_rpl_status_to_errno(int status)
+{
+ switch (status) {
+ case CPL_ERR_CONN_RESET:
+ return -ECONNREFUSED;
+ case CPL_ERR_ARP_MISS:
+ return -EHOSTUNREACH;
+ case CPL_ERR_CONN_TIMEDOUT:
+ return -ETIMEDOUT;
+ case CPL_ERR_TCAM_FULL:
+ return -ENOMEM;
+ case CPL_ERR_CONN_EXIST:
+ return -EADDRINUSE;
+ default:
+ return -EIO;
+ }
+}
+
+static void act_open_retry_timer(unsigned long data)
+{
+ struct sk_buff *skb;
+ struct cxgbi_sock *csk = (struct cxgbi_sock *)data;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+ skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+ if (!skb)
+ cxgbi_sock_fail_act_open(csk, -ENOMEM);
+ else {
+ skb->sk = (struct sock *)csk;
+ set_arp_failure_handler(skb, act_open_arp_failure);
+ send_act_open_req(csk, skb, csk->l2t);
+ }
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+}
+
+static int do_act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+ struct cpl_act_open_rpl *rpl = cplhdr(skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, status %u.\n",
+ csk, csk->state, csk->flags, csk->atid, rpl->status);
+
+ if (rpl->status != CPL_ERR_TCAM_FULL &&
+ rpl->status != CPL_ERR_CONN_EXIST &&
+ rpl->status != CPL_ERR_ARP_MISS)
+ cxgb3_queue_tid_release(tdev, GET_TID(rpl));
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+ if (rpl->status == CPL_ERR_CONN_EXIST &&
+ csk->retry_timer.function != act_open_retry_timer) {
+ csk->retry_timer.function = act_open_retry_timer;
+ mod_timer(&csk->retry_timer, jiffies + HZ / 2);
+ } else
+ cxgbi_sock_fail_act_open(csk,
+ act_open_rpl_status_to_errno(rpl->status));
+
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process PEER_CLOSE CPL messages: -> host
+ * Handle peer FIN.
+ */
+static int do_peer_close(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ cxgbi_sock_rcv_peer_close(csk);
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process CLOSE_CONN_RPL CPL message: -> host
+ * Process a peer ACK to our FIN.
+ */
+static int do_close_con_rpl(struct t3cdev *cdev, struct sk_buff *skb,
+ void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+ struct cpl_close_con_rpl *rpl = cplhdr(skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, snxt %u.\n",
+ csk, csk->state, csk->flags, csk->tid, ntohl(rpl->snd_nxt));
+
+ cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt));
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process ABORT_REQ_RSS CPL message: -> host
+ * Process abort requests. If we are waiting for an ABORT_RPL we ignore this
+ * request except that we need to reply to it.
+ */
+
+static int abort_status_to_errno(struct cxgbi_sock *csk, int abort_reason,
+ int *need_rst)
+{
+ switch (abort_reason) {
+ case CPL_ERR_BAD_SYN: /* fall through */
+ case CPL_ERR_CONN_RESET:
+ return csk->state > CTP_ESTABLISHED ?
+ -EPIPE : -ECONNRESET;
+ case CPL_ERR_XMIT_TIMEDOUT:
+ case CPL_ERR_PERSIST_TIMEDOUT:
+ case CPL_ERR_FINWAIT2_TIMEDOUT:
+ case CPL_ERR_KEEPALIVE_TIMEDOUT:
+ return -ETIMEDOUT;
+ default:
+ return -EIO;
+ }
+}
+
+static int do_abort_req(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
+{
+ const struct cpl_abort_req_rss *req = cplhdr(skb);
+ struct cxgbi_sock *csk = ctx;
+ int rst_status = CPL_ABORT_NO_RST;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
+ req->status == CPL_ERR_PERSIST_NEG_ADVICE) {
+ goto done;
+ }
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+
+ if (!cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD)) {
+ cxgbi_sock_set_flag(csk, CTPF_ABORT_REQ_RCVD);
+ cxgbi_sock_set_state(csk, CTP_ABORTING);
+ goto out;
+ }
+
+ cxgbi_sock_clear_flag(csk, CTPF_ABORT_REQ_RCVD);
+ send_abort_rpl(csk, rst_status);
+
+ if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) {
+ csk->err = abort_status_to_errno(csk, req->status, &rst_status);
+ cxgbi_sock_closed(csk);
+ }
+
+out:
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+done:
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process ABORT_RPL_RSS CPL message: -> host
+ * Process abort replies. We only process these messages if we anticipate
+ * them as the coordination between SW and HW in this area is somewhat lacking
+ * and sometimes we get ABORT_RPLs after we are done with the connection that
+ * originated the ABORT_REQ.
+ */
+static int do_abort_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
+{
+ struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
+ struct cxgbi_sock *csk = ctx;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "status 0x%x, csk 0x%p, s %u, 0x%lx.\n",
+ rpl->status, csk, csk ? csk->state : 0,
+ csk ? csk->flags : 0UL);
+ /*
+ * Ignore replies to post-close aborts indicating that the abort was
+ * requested too late. These connections are terminated when we get
+ * PEER_CLOSE or CLOSE_CON_RPL and by the time the abort_rpl_rss
+ * arrives the TID is either no longer used or it has been recycled.
+ */
+ if (rpl->status == CPL_ERR_ABORT_FAILED)
+ goto rel_skb;
+ /*
+ * Sometimes we've already closed the connection, e.g., a post-close
+ * abort races with ABORT_REQ_RSS, the latter frees the connection
+ * expecting the ABORT_REQ will fail with CPL_ERR_ABORT_FAILED,
+ * but FW turns the ABORT_REQ into a regular one and so we get
+ * ABORT_RPL_RSS with status 0 and no connection.
+ */
+ if (csk)
+ cxgbi_sock_rcv_abort_rpl(csk);
+rel_skb:
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process RX_ISCSI_HDR CPL message: -> host
+ * Handle received PDUs, the payload could be DDP'ed. If not, the payload
+ * follow after the bhs.
+ */
+static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+ struct cpl_iscsi_hdr *hdr_cpl = cplhdr(skb);
+ struct cpl_iscsi_hdr_norss data_cpl;
+ struct cpl_rx_data_ddp_norss ddp_cpl;
+ unsigned int hdr_len, data_len, status;
+ unsigned int len;
+ int err;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx,%u, skb 0x%p,%u.\n",
+ csk, csk->state, csk->flags, csk->tid, skb, skb->len);
+
+ spin_lock_bh(&csk->lock);
+
+ if (unlikely(csk->state >= CTP_PASSIVE_CLOSE)) {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, bad state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ if (csk->state != CTP_ABORTING)
+ goto abort_conn;
+ else
+ goto discard;
+ }
+
+ cxgbi_skcb_tcp_seq(skb) = ntohl(hdr_cpl->seq);
+ cxgbi_skcb_flags(skb) = 0;
+
+ skb_reset_transport_header(skb);
+ __skb_pull(skb, sizeof(struct cpl_iscsi_hdr));
+
+ len = hdr_len = ntohs(hdr_cpl->len);
+ /* msg coalesce is off or not enough data received */
+ if (skb->len <= hdr_len) {
+ pr_err("%s: tid %u, CPL_ISCSI_HDR, skb len %u < %u.\n",
+ csk->cdev->ports[csk->port_id]->name, csk->tid,
+ skb->len, hdr_len);
+ goto abort_conn;
+ }
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_COALESCED);
+
+ err = skb_copy_bits(skb, skb->len - sizeof(ddp_cpl), &ddp_cpl,
+ sizeof(ddp_cpl));
+ if (err < 0) {
+ pr_err("%s: tid %u, copy cpl_ddp %u-%zu failed %d.\n",
+ csk->cdev->ports[csk->port_id]->name, csk->tid,
+ skb->len, sizeof(ddp_cpl), err);
+ goto abort_conn;
+ }
+
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_STATUS);
+ cxgbi_skcb_rx_pdulen(skb) = ntohs(ddp_cpl.len);
+ cxgbi_skcb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
+ status = ntohl(ddp_cpl.ddp_status);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, skb 0x%p,%u, pdulen %u, status 0x%x.\n",
+ csk, skb, skb->len, cxgbi_skcb_rx_pdulen(skb), status);
+
+ if (status & (1 << CPL_RX_DDP_STATUS_HCRC_SHIFT))
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_HCRC_ERR);
+ if (status & (1 << CPL_RX_DDP_STATUS_DCRC_SHIFT))
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_DCRC_ERR);
+ if (status & (1 << CPL_RX_DDP_STATUS_PAD_SHIFT))
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_PAD_ERR);
+
+ if (skb->len > (hdr_len + sizeof(ddp_cpl))) {
+ err = skb_copy_bits(skb, hdr_len, &data_cpl, sizeof(data_cpl));
+ if (err < 0) {
+ pr_err("%s: tid %u, cp %zu/%u failed %d.\n",
+ csk->cdev->ports[csk->port_id]->name,
+ csk->tid, sizeof(data_cpl), skb->len, err);
+ goto abort_conn;
+ }
+ data_len = ntohs(data_cpl.len);
+ log_debug(1 << CXGBI_DBG_DDP | 1 << CXGBI_DBG_PDU_RX,
+ "skb 0x%p, pdu not ddp'ed %u/%u, status 0x%x.\n",
+ skb, data_len, cxgbi_skcb_rx_pdulen(skb), status);
+ len += sizeof(data_cpl) + data_len;
+ } else if (status & (1 << CPL_RX_DDP_STATUS_DDP_SHIFT))
+ cxgbi_skcb_set_flag(skb, SKCBF_RX_DATA_DDPD);
+
+ csk->rcv_nxt = ntohl(ddp_cpl.seq) + cxgbi_skcb_rx_pdulen(skb);
+ __pskb_trim(skb, len);
+ __skb_queue_tail(&csk->receive_queue, skb);
+ cxgbi_conn_pdu_ready(csk);
+
+ spin_unlock_bh(&csk->lock);
+ return 0;
+
+abort_conn:
+ send_abort_req(csk);
+discard:
+ spin_unlock_bh(&csk->lock);
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * Process TX_DATA_ACK CPL messages: -> host
+ * Process an acknowledgment of WR completion. Advance snd_una and send the
+ * next batch of work requests from the write queue.
+ */
+static int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx)
+{
+ struct cxgbi_sock *csk = ctx;
+ struct cpl_wr_ack *hdr = cplhdr(skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx,%u, cr %u.\n",
+ csk, csk->state, csk->flags, csk->tid, ntohs(hdr->credits));
+
+ cxgbi_sock_rcv_wr_ack(csk, ntohs(hdr->credits), ntohl(hdr->snd_una), 1);
+ __kfree_skb(skb);
+ return 0;
+}
+
+/*
+ * for each connection, pre-allocate skbs needed for close/abort requests. So
+ * that we can service the request right away.
+ */
+static int alloc_cpls(struct cxgbi_sock *csk)
+{
+ csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req), 0,
+ GFP_KERNEL);
+ if (!csk->cpl_close)
+ return -ENOMEM;
+ csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req), 0,
+ GFP_KERNEL);
+ if (!csk->cpl_abort_req)
+ goto free_cpl_skbs;
+
+ csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl), 0,
+ GFP_KERNEL);
+ if (!csk->cpl_abort_rpl)
+ goto free_cpl_skbs;
+
+ return 0;
+
+free_cpl_skbs:
+ cxgbi_sock_free_cpl_skbs(csk);
+ return -ENOMEM;
+}
+
+/**
+ * release_offload_resources - release offload resource
+ * @c3cn: the offloaded iscsi tcp connection.
+ * Release resources held by an offload connection (TID, L2T entry, etc.)
+ */
+static void l2t_put(struct cxgbi_sock *csk)
+{
+ struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev;
+
+ if (csk->l2t) {
+ l2t_release(L2DATA(t3dev), csk->l2t);
+ csk->l2t = NULL;
+ cxgbi_sock_put(csk);
+ }
+}
+
+static void release_offload_resources(struct cxgbi_sock *csk)
+{
+ struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ csk->rss_qid = 0;
+ cxgbi_sock_free_cpl_skbs(csk);
+
+ if (csk->wr_cred != csk->wr_max_cred) {
+ cxgbi_sock_purge_wr_queue(csk);
+ cxgbi_sock_reset_wr_list(csk);
+ }
+ l2t_put(csk);
+ if (cxgbi_sock_flag(csk, CTPF_HAS_ATID))
+ free_atid(csk);
+ else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) {
+ cxgb3_remove_tid(t3dev, (void *)csk, csk->tid);
+ cxgbi_sock_clear_flag(csk, CTPF_HAS_TID);
+ cxgbi_sock_put(csk);
+ }
+ csk->dst = NULL;
+ csk->cdev = NULL;
+}
+
+static int init_act_open(struct cxgbi_sock *csk)
+{
+ struct dst_entry *dst = csk->dst;
+ struct cxgbi_device *cdev = csk->cdev;
+ struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev;
+ struct net_device *ndev = cdev->ports[csk->port_id];
+ struct sk_buff *skb = NULL;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags);
+
+ csk->rss_qid = 0;
+ csk->l2t = t3_l2t_get(t3dev, dst->neighbour, ndev);
+ if (!csk->l2t) {
+ pr_err("NO l2t available.\n");
+ return -EINVAL;
+ }
+ cxgbi_sock_get(csk);
+
+ csk->atid = cxgb3_alloc_atid(t3dev, &t3_client, csk);
+ if (csk->atid < 0) {
+ pr_err("NO atid available.\n");
+ goto rel_resource;
+ }
+ cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
+ cxgbi_sock_get(csk);
+
+ skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
+ if (!skb)
+ goto rel_resource;
+ skb->sk = (struct sock *)csk;
+ set_arp_failure_handler(skb, act_open_arp_failure);
+
+ csk->wr_max_cred = csk->wr_cred = T3C_DATA(t3dev)->max_wrs - 1;
+ csk->wr_una_cred = 0;
+ csk->mss_idx = cxgbi_sock_select_mss(csk, dst_mtu(dst));
+ cxgbi_sock_reset_wr_list(csk);
+ csk->err = 0;
+
+ cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN);
+ send_act_open_req(csk, skb, csk->l2t);
+ return 0;
+
+rel_resource:
+ if (skb)
+ __kfree_skb(skb);
+ return -EINVAL;
+}
+
+cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS] = {
+ [CPL_ACT_ESTABLISH] = do_act_establish,
+ [CPL_ACT_OPEN_RPL] = do_act_open_rpl,
+ [CPL_PEER_CLOSE] = do_peer_close,
+ [CPL_ABORT_REQ_RSS] = do_abort_req,
+ [CPL_ABORT_RPL_RSS] = do_abort_rpl,
+ [CPL_CLOSE_CON_RPL] = do_close_con_rpl,
+ [CPL_TX_DMA_ACK] = do_wr_ack,
+ [CPL_ISCSI_HDR] = do_iscsi_hdr,
+};
+
+/**
+ * cxgb3i_ofld_init - allocate and initialize resources for each adapter found
+ * @cdev: cxgbi adapter
+ */
+int cxgb3i_ofld_init(struct cxgbi_device *cdev)
+{
+ struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev;
+ struct adap_ports port;
+ struct ofld_page_info rx_page_info;
+ unsigned int wr_len;
+ int rc;
+
+ if (t3dev->ctl(t3dev, GET_WR_LEN, &wr_len) < 0 ||
+ t3dev->ctl(t3dev, GET_PORTS, &port) < 0 ||
+ t3dev->ctl(t3dev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
+ pr_warn("t3 0x%p, offload up, ioctl failed.\n", t3dev);
+ return -EINVAL;
+ }
+
+ if (cxgb3i_max_connect > CXGBI_MAX_CONN)
+ cxgb3i_max_connect = CXGBI_MAX_CONN;
+
+ rc = cxgbi_device_portmap_create(cdev, cxgb3i_sport_base,
+ cxgb3i_max_connect);
+ if (rc < 0)
+ return rc;
+
+ init_wr_tab(wr_len);
+ cdev->csk_release_offload_resources = release_offload_resources;
+ cdev->csk_push_tx_frames = push_tx_frames;
+ cdev->csk_send_abort_req = send_abort_req;
+ cdev->csk_send_close_req = send_close_req;
+ cdev->csk_send_rx_credits = send_rx_credits;
+ cdev->csk_alloc_cpls = alloc_cpls;
+ cdev->csk_init_act_open = init_act_open;
+
+ pr_info("cdev 0x%p, offload up, added.\n", cdev);
+ return 0;
+}
+
+/*
+ * functions to program the pagepod in h/w
+ */
+static inline void ulp_mem_io_set_hdr(struct sk_buff *skb, unsigned int addr)
+{
+ struct ulp_mem_io *req = (struct ulp_mem_io *)skb->head;
+
+ memset(req, 0, sizeof(*req));
+
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS));
+ req->cmd_lock_addr = htonl(V_ULP_MEMIO_ADDR(addr >> 5) |
+ V_ULPTX_CMD(ULP_MEM_WRITE));
+ req->len = htonl(V_ULP_MEMIO_DATA_LEN(PPOD_SIZE >> 5) |
+ V_ULPTX_NFLITS((PPOD_SIZE >> 3) + 1));
+}
+
+static int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
+ unsigned int idx, unsigned int npods,
+ struct cxgbi_gather_list *gl)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
+ int i;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "csk 0x%p, idx %u, npods %u, gl 0x%p.\n",
+ csk, idx, npods, gl);
+
+ for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
+ struct sk_buff *skb = ddp->gl_skb[idx];
+
+ /* hold on to the skb until we clear the ddp mapping */
+ skb_get(skb);
+
+ ulp_mem_io_set_hdr(skb, pm_addr);
+ cxgbi_ddp_ppod_set((struct cxgbi_pagepod *)(skb->head +
+ sizeof(struct ulp_mem_io)),
+ hdr, gl, i * PPOD_PAGES_MAX);
+ skb->priority = CPL_PRIORITY_CONTROL;
+ cxgb3_ofld_send(cdev->lldev, skb);
+ }
+ return 0;
+}
+
+static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
+ unsigned int idx, unsigned int npods)
+{
+ struct cxgbi_device *cdev = chba->cdev;
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
+ int i;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "cdev 0x%p, idx %u, npods %u, tag 0x%x.\n",
+ cdev, idx, npods, tag);
+
+ for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
+ struct sk_buff *skb = ddp->gl_skb[idx];
+
+ if (!skb) {
+ pr_err("tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
+ tag, idx, i, npods);
+ continue;
+ }
+ ddp->gl_skb[idx] = NULL;
+ memset(skb->head + sizeof(struct ulp_mem_io), 0, PPOD_SIZE);
+ ulp_mem_io_set_hdr(skb, pm_addr);
+ skb->priority = CPL_PRIORITY_CONTROL;
+ cxgb3_ofld_send(cdev->lldev, skb);
+ }
+}
+
+static void ddp_free_gl_skb(struct cxgbi_ddp_info *ddp, int idx, int cnt)
+{
+ int i;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "ddp 0x%p, idx %d, cnt %d.\n", ddp, idx, cnt);
+
+ for (i = 0; i < cnt; i++, idx++)
+ if (ddp->gl_skb[idx]) {
+ kfree_skb(ddp->gl_skb[idx]);
+ ddp->gl_skb[idx] = NULL;
+ }
+}
+
+static int ddp_alloc_gl_skb(struct cxgbi_ddp_info *ddp, int idx,
+ int cnt, gfp_t gfp)
+{
+ int i;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "ddp 0x%p, idx %d, cnt %d.\n", ddp, idx, cnt);
+
+ for (i = 0; i < cnt; i++) {
+ struct sk_buff *skb = alloc_cpl(sizeof(struct ulp_mem_io) +
+ PPOD_SIZE, 0, gfp);
+ if (skb) {
+ ddp->gl_skb[idx + i] = skb;
+ } else {
+ ddp_free_gl_skb(ddp, idx, i);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
+ unsigned int tid, int pg_idx, bool reply)
+{
+ struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+ GFP_KERNEL);
+ struct cpl_set_tcb_field *req;
+ u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "csk 0x%p, tid %u, pg_idx %d.\n", csk, tid, pg_idx);
+ if (!skb)
+ return -ENOMEM;
+
+ /* set up ulp submode and page size */
+ req = (struct cpl_set_tcb_field *)skb->head;
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
+ req->reply = V_NO_REPLY(reply ? 0 : 1);
+ req->cpu_idx = 0;
+ req->word = htons(31);
+ req->mask = cpu_to_be64(0xF0000000);
+ req->val = cpu_to_be64(val << 28);
+ skb->priority = CPL_PRIORITY_CONTROL;
+
+ cxgb3_ofld_send(csk->cdev->lldev, skb);
+ return 0;
+}
+
+/**
+ * cxgb3i_setup_conn_digest - setup conn. digest setting
+ * @csk: cxgb tcp socket
+ * @tid: connection id
+ * @hcrc: header digest enabled
+ * @dcrc: data digest enabled
+ * @reply: request reply from h/w
+ * set up the iscsi digest settings for a connection identified by tid
+ */
+static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
+ int hcrc, int dcrc, int reply)
+{
+ struct sk_buff *skb = alloc_cpl(sizeof(struct cpl_set_tcb_field), 0,
+ GFP_KERNEL);
+ struct cpl_set_tcb_field *req;
+ u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0);
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "csk 0x%p, tid %u, crc %d,%d.\n", csk, tid, hcrc, dcrc);
+ if (!skb)
+ return -ENOMEM;
+
+ /* set up ulp submode and page size */
+ req = (struct cpl_set_tcb_field *)skb->head;
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
+ req->reply = V_NO_REPLY(reply ? 0 : 1);
+ req->cpu_idx = 0;
+ req->word = htons(31);
+ req->mask = cpu_to_be64(0x0F000000);
+ req->val = cpu_to_be64(val << 24);
+ skb->priority = CPL_PRIORITY_CONTROL;
+
+ cxgb3_ofld_send(csk->cdev->lldev, skb);
+ return 0;
+}
+
+/**
+ * t3_ddp_cleanup - release the cxgb3 adapter's ddp resource
+ * @cdev: cxgb3i adapter
+ * release all the resource held by the ddp pagepod manager for a given
+ * adapter if needed
+ */
+
+static void t3_ddp_cleanup(struct cxgbi_device *cdev)
+{
+ struct t3cdev *tdev = (struct t3cdev *)cdev->lldev;
+
+ if (cxgbi_ddp_cleanup(cdev)) {
+ pr_info("t3dev 0x%p, ulp_iscsi no more user.\n", tdev);
+ tdev->ulp_iscsi = NULL;
+ }
+}
+
+/**
+ * ddp_init - initialize the cxgb3 adapter's ddp resource
+ * @cdev: cxgb3i adapter
+ * initialize the ddp pagepod manager for a given adapter
+ */
+static int cxgb3i_ddp_init(struct cxgbi_device *cdev)
+{
+ struct t3cdev *tdev = (struct t3cdev *)cdev->lldev;
+ struct cxgbi_ddp_info *ddp = tdev->ulp_iscsi;
+ struct ulp_iscsi_info uinfo;
+ unsigned int pgsz_factor[4];
+ int err;
+
+ if (ddp) {
+ kref_get(&ddp->refcnt);
+ pr_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
+ tdev, tdev->ulp_iscsi);
+ cdev->ddp = ddp;
+ return -EALREADY;
+ }
+
+ err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
+ if (err < 0) {
+ pr_err("%s, failed to get iscsi param err=%d.\n",
+ tdev->name, err);
+ return err;
+ }
+
+ err = cxgbi_ddp_init(cdev, uinfo.llimit, uinfo.ulimit,
+ uinfo.max_txsz, uinfo.max_rxsz);
+ if (err < 0)
+ return err;
+
+ ddp = cdev->ddp;
+
+ uinfo.tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
+ cxgbi_ddp_page_size_factor(pgsz_factor);
+ uinfo.ulimit = uinfo.llimit + (ddp->nppods << PPOD_SIZE_SHIFT);
+
+ err = tdev->ctl(tdev, ULP_ISCSI_SET_PARAMS, &uinfo);
+ if (err < 0) {
+ pr_warn("%s unable to set iscsi param err=%d, ddp disabled.\n",
+ tdev->name, err);
+ cxgbi_ddp_cleanup(cdev);
+ return err;
+ }
+ tdev->ulp_iscsi = ddp;
+
+ cdev->csk_ddp_free_gl_skb = ddp_free_gl_skb;
+ cdev->csk_ddp_alloc_gl_skb = ddp_alloc_gl_skb;
+ cdev->csk_ddp_setup_digest = ddp_setup_conn_digest;
+ cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx;
+ cdev->csk_ddp_set = ddp_set_map;
+ cdev->csk_ddp_clear = ddp_clear_map;
+
+ pr_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u, "
+ "%u/%u.\n",
+ tdev, ddp->nppods, ddp->idx_bits, ddp->idx_mask,
+ ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
+ ddp->max_rxsz, uinfo.max_rxsz);
+ return 0;
+}
+
+static void cxgb3i_dev_close(struct t3cdev *t3dev)
+{
+ struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev);
+
+ if (!cdev || cdev->flags & CXGBI_FLAG_ADAPTER_RESET) {
+ pr_info("0x%p close, f 0x%x.\n", cdev, cdev ? cdev->flags : 0);
+ return;
+ }
+
+ cxgbi_device_unregister(cdev);
+}
+
+/**
+ * cxgb3i_dev_open - init a t3 adapter structure and any h/w settings
+ * @t3dev: t3cdev adapter
+ */
+static void cxgb3i_dev_open(struct t3cdev *t3dev)
+{
+ struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev);
+ struct adapter *adapter = tdev2adap(t3dev);
+ int i, err;
+
+ if (cdev) {
+ pr_info("0x%p, updating.\n", cdev);
+ return;
+ }
+
+ cdev = cxgbi_device_register(0, adapter->params.nports);
+ if (!cdev) {
+ pr_warn("device 0x%p register failed.\n", t3dev);
+ return;
+ }
+
+ cdev->flags = CXGBI_FLAG_DEV_T3 | CXGBI_FLAG_IPV4_SET;
+ cdev->lldev = t3dev;
+ cdev->pdev = adapter->pdev;
+ cdev->ports = adapter->port;
+ cdev->nports = adapter->params.nports;
+ cdev->mtus = adapter->params.mtus;
+ cdev->nmtus = NMTUS;
+ cdev->snd_win = cxgb3i_snd_win;
+ cdev->rcv_win = cxgb3i_rcv_win;
+ cdev->rx_credit_thres = cxgb3i_rx_credit_thres;
+ cdev->skb_tx_rsvd = CXGB3I_TX_HEADER_LEN;
+ cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr_norss);
+ cdev->dev_ddp_cleanup = t3_ddp_cleanup;
+ cdev->itp = &cxgb3i_iscsi_transport;
+
+ err = cxgb3i_ddp_init(cdev);
+ if (err) {
+ pr_info("0x%p ddp init failed\n", cdev);
+ goto err_out;
+ }
+
+ err = cxgb3i_ofld_init(cdev);
+ if (err) {
+ pr_info("0x%p offload init failed\n", cdev);
+ goto err_out;
+ }
+
+ err = cxgbi_hbas_add(cdev, CXGB3I_MAX_LUN, CXGBI_MAX_CONN,
+ &cxgb3i_host_template, cxgb3i_stt);
+ if (err)
+ goto err_out;
+
+ for (i = 0; i < cdev->nports; i++)
+ cdev->hbas[i]->ipv4addr =
+ cxgb3i_get_private_ipv4addr(cdev->ports[i]);
+
+ pr_info("cdev 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
+ cdev, cdev ? cdev->flags : 0, t3dev, err);
+ return;
+
+err_out:
+ cxgbi_device_unregister(cdev);
+}
+
+static void cxgb3i_dev_event_handler(struct t3cdev *t3dev, u32 event, u32 port)
+{
+ struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev);
+
+ log_debug(1 << CXGBI_DBG_TOE,
+ "0x%p, cdev 0x%p, event 0x%x, port 0x%x.\n",
+ t3dev, cdev, event, port);
+ if (!cdev)
+ return;
+
+ switch (event) {
+ case OFFLOAD_STATUS_DOWN:
+ cdev->flags |= CXGBI_FLAG_ADAPTER_RESET;
+ break;
+ case OFFLOAD_STATUS_UP:
+ cdev->flags &= ~CXGBI_FLAG_ADAPTER_RESET;
+ break;
+ }
+}
+
+/**
+ * cxgb3i_init_module - module init entry point
+ *
+ * initialize any driver wide global data structures and register itself
+ * with the cxgb3 module
+ */
+static int __init cxgb3i_init_module(void)
+{
+ int rc;
+
+ printk(KERN_INFO "%s", version);
+
+ rc = cxgbi_iscsi_init(&cxgb3i_iscsi_transport, &cxgb3i_stt);
+ if (rc < 0)
+ return rc;
+
+ cxgb3_register_client(&t3_client);
+ return 0;
+}
+
+/**
+ * cxgb3i_exit_module - module cleanup/exit entry point
+ *
+ * go through the driver hba list and for each hba, release any resource held.
+ * and unregisters iscsi transport and the cxgb3 module
+ */
+static void __exit cxgb3i_exit_module(void)
+{
+ cxgb3_unregister_client(&t3_client);
+ cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T3);
+ cxgbi_iscsi_cleanup(&cxgb3i_iscsi_transport, &cxgb3i_stt);
+}
+
+module_init(cxgb3i_init_module);
+module_exit(cxgb3i_exit_module);
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.h
new file mode 100644
index 000000000000..5f5e3394b594
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.h
@@ -0,0 +1,51 @@
+/*
+ * cxgb3i.h: Chelsio S3xx iSCSI driver.
+ *
+ * Copyright (c) 2008 Chelsio Communications, 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.
+ *
+ * Written by: Karen Xie (kxie@chelsio.com)
+ */
+
+#ifndef __CXGB3I_H__
+#define __CXGB3I_H__
+
+#define CXGB3I_SCSI_HOST_QDEPTH 1024
+#define CXGB3I_MAX_LUN 512
+#define ISCSI_PDU_NONPAYLOAD_MAX \
+ (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + 2*ISCSI_DIGEST_SIZE)
+
+/*for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
+#define CXGB3I_TX_HEADER_LEN \
+ (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr))
+
+extern cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
+
+#define cxgb3i_get_private_ipv4addr(ndev) \
+ (((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr)
+#define cxgb3i_set_private_ipv4addr(ndev, addr) \
+ (((struct port_info *)(netdev_priv(ndev)))->iscsi_ipv4addr) = addr
+
+struct cpl_iscsi_hdr_norss {
+ union opcode_tid ot;
+ u16 pdu_len_ddp;
+ u16 len;
+ u32 seq;
+ u16 urg;
+ u8 rsvd;
+ u8 status;
+};
+
+struct cpl_rx_data_ddp_norss {
+ union opcode_tid ot;
+ u16 urg;
+ u16 len;
+ u32 seq;
+ u32 nxt_seq;
+ u32 ulp_crc;
+ u32 ddp_status;
+};
+#endif
diff --git a/drivers/scsi/cxgbi/cxgb4i/Kbuild b/drivers/scsi/cxgbi/cxgb4i/Kbuild
new file mode 100644
index 000000000000..b9f4af7454b7
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb4i/Kbuild
@@ -0,0 +1,3 @@
+EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb4
+
+obj-$(CONFIG_SCSI_CXGB4_ISCSI) += cxgb4i.o
diff --git a/drivers/scsi/cxgbi/cxgb4i/Kconfig b/drivers/scsi/cxgbi/cxgb4i/Kconfig
new file mode 100644
index 000000000000..bb94b39b17b3
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb4i/Kconfig
@@ -0,0 +1,7 @@
+config SCSI_CXGB4_ISCSI
+ tristate "Chelsio T4 iSCSI support"
+ depends on CHELSIO_T4_DEPENDS
+ select CHELSIO_T4
+ select SCSI_ISCSI_ATTRS
+ ---help---
+ This driver supports iSCSI offload for the Chelsio T4 devices.
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
new file mode 100644
index 000000000000..b375a683a6b0
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -0,0 +1,1600 @@
+/*
+ * cxgb4i.c: Chelsio T4 iSCSI driver.
+ *
+ * Copyright (c) 2010 Chelsio Communications, 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.
+ *
+ * Written by: Karen Xie (kxie@chelsio.com)
+ * Rakesh Ranjan (rranjan@chelsio.com)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <scsi/scsi_host.h>
+#include <net/tcp.h>
+#include <net/dst.h>
+#include <linux/netdevice.h>
+
+#include "t4_msg.h"
+#include "cxgb4.h"
+#include "cxgb4_uld.h"
+#include "t4fw_api.h"
+#include "l2t.h"
+#include "cxgb4i.h"
+
+static unsigned int dbg_level;
+
+#include "../libcxgbi.h"
+
+#define DRV_MODULE_NAME "cxgb4i"
+#define DRV_MODULE_DESC "Chelsio T4 iSCSI Driver"
+#define DRV_MODULE_VERSION "0.9.0"
+#define DRV_MODULE_RELDATE "May 2010"
+
+static char version[] =
+ DRV_MODULE_DESC " " DRV_MODULE_NAME
+ " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Chelsio Communications, Inc.");
+MODULE_DESCRIPTION(DRV_MODULE_DESC);
+MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(dbg_level, uint, 0644);
+MODULE_PARM_DESC(dbg_level, "Debug flag (default=0)");
+
+static int cxgb4i_rcv_win = 256 * 1024;
+module_param(cxgb4i_rcv_win, int, 0644);
+MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP reveive window in bytes");
+
+static int cxgb4i_snd_win = 128 * 1024;
+module_param(cxgb4i_snd_win, int, 0644);
+MODULE_PARM_DESC(cxgb4i_snd_win, "TCP send window in bytes");
+
+static int cxgb4i_rx_credit_thres = 10 * 1024;
+module_param(cxgb4i_rx_credit_thres, int, 0644);
+MODULE_PARM_DESC(cxgb4i_rx_credit_thres,
+ "RX credits return threshold in bytes (default=10KB)");
+
+static unsigned int cxgb4i_max_connect = (8 * 1024);
+module_param(cxgb4i_max_connect, uint, 0644);
+MODULE_PARM_DESC(cxgb4i_max_connect, "Maximum number of connections");
+
+static unsigned short cxgb4i_sport_base = 20000;
+module_param(cxgb4i_sport_base, ushort, 0644);
+MODULE_PARM_DESC(cxgb4i_sport_base, "Starting port number (default 20000)");
+
+typedef void (*cxgb4i_cplhandler_func)(struct cxgbi_device *, struct sk_buff *);
+
+static void *t4_uld_add(const struct cxgb4_lld_info *);
+static int t4_uld_rx_handler(void *, const __be64 *, const struct pkt_gl *);
+static int t4_uld_state_change(void *, enum cxgb4_state state);
+
+static const struct cxgb4_uld_info cxgb4i_uld_info = {
+ .name = DRV_MODULE_NAME,
+ .add = t4_uld_add,
+ .rx_handler = t4_uld_rx_handler,
+ .state_change = t4_uld_state_change,
+};
+
+static struct scsi_host_template cxgb4i_host_template = {
+ .module = THIS_MODULE,
+ .name = DRV_MODULE_NAME,
+ .proc_name = DRV_MODULE_NAME,
+ .can_queue = CXGB4I_SCSI_HOST_QDEPTH,
+ .queuecommand = iscsi_queuecommand,
+ .change_queue_depth = iscsi_change_queue_depth,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = 0xFFFF,
+ .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
+ .eh_abort_handler = iscsi_eh_abort,
+ .eh_device_reset_handler = iscsi_eh_device_reset,
+ .eh_target_reset_handler = iscsi_eh_recover_target,
+ .target_alloc = iscsi_target_alloc,
+ .use_clustering = DISABLE_CLUSTERING,
+ .this_id = -1,
+};
+
+static struct iscsi_transport cxgb4i_iscsi_transport = {
+ .owner = THIS_MODULE,
+ .name = DRV_MODULE_NAME,
+ .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST |
+ CAP_DATADGST | CAP_DIGEST_OFFLOAD |
+ CAP_PADDING_OFFLOAD,
+ .param_mask = ISCSI_MAX_RECV_DLENGTH | ISCSI_MAX_XMIT_DLENGTH |
+ ISCSI_HDRDGST_EN | ISCSI_DATADGST_EN |
+ ISCSI_INITIAL_R2T_EN | ISCSI_MAX_R2T |
+ ISCSI_IMM_DATA_EN | ISCSI_FIRST_BURST |
+ ISCSI_MAX_BURST | ISCSI_PDU_INORDER_EN |
+ ISCSI_DATASEQ_INORDER_EN | ISCSI_ERL |
+ ISCSI_CONN_PORT | ISCSI_CONN_ADDRESS |
+ ISCSI_EXP_STATSN | ISCSI_PERSISTENT_PORT |
+ ISCSI_PERSISTENT_ADDRESS |
+ ISCSI_TARGET_NAME | ISCSI_TPGT |
+ ISCSI_USERNAME | ISCSI_PASSWORD |
+ ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
+ ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+ ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
+ ISCSI_PING_TMO | ISCSI_RECV_TMO |
+ ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
+ .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
+ ISCSI_HOST_INITIATOR_NAME |
+ ISCSI_HOST_NETDEV_NAME,
+ .get_host_param = cxgbi_get_host_param,
+ .set_host_param = cxgbi_set_host_param,
+ /* session management */
+ .create_session = cxgbi_create_session,
+ .destroy_session = cxgbi_destroy_session,
+ .get_session_param = iscsi_session_get_param,
+ /* connection management */
+ .create_conn = cxgbi_create_conn,
+ .bind_conn = cxgbi_bind_conn,
+ .destroy_conn = iscsi_tcp_conn_teardown,
+ .start_conn = iscsi_conn_start,
+ .stop_conn = iscsi_conn_stop,
+ .get_conn_param = cxgbi_get_conn_param,
+ .set_param = cxgbi_set_conn_param,
+ .get_stats = cxgbi_get_conn_stats,
+ /* pdu xmit req from user space */
+ .send_pdu = iscsi_conn_send_pdu,
+ /* task */
+ .init_task = iscsi_tcp_task_init,
+ .xmit_task = iscsi_tcp_task_xmit,
+ .cleanup_task = cxgbi_cleanup_task,
+ /* pdu */
+ .alloc_pdu = cxgbi_conn_alloc_pdu,
+ .init_pdu = cxgbi_conn_init_pdu,
+ .xmit_pdu = cxgbi_conn_xmit_pdu,
+ .parse_pdu_itt = cxgbi_parse_pdu_itt,
+ /* TCP connect/disconnect */
+ .ep_connect = cxgbi_ep_connect,
+ .ep_poll = cxgbi_ep_poll,
+ .ep_disconnect = cxgbi_ep_disconnect,
+ /* Error recovery timeout call */
+ .session_recovery_timedout = iscsi_session_recovery_timedout,
+};
+
+static struct scsi_transport_template *cxgb4i_stt;
+
+/*
+ * CPL (Chelsio Protocol Language) defines a message passing interface between
+ * the host driver and Chelsio asic.
+ * The section below implments CPLs that related to iscsi tcp connection
+ * open/close/abort and data send/receive.
+ */
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#define RCV_BUFSIZ_MASK 0x3FFU
+#define MAX_IMM_TX_PKT_LEN 128
+
+static inline void set_queue(struct sk_buff *skb, unsigned int queue,
+ const struct cxgbi_sock *csk)
+{
+ skb->queue_mapping = queue;
+}
+
+static int push_tx_frames(struct cxgbi_sock *, int);
+
+/*
+ * is_ofld_imm - check whether a packet can be sent as immediate data
+ * @skb: the packet
+ *
+ * Returns true if a packet can be sent as an offload WR with immediate
+ * data. We currently use the same limit as for Ethernet packets.
+ */
+static inline int is_ofld_imm(const struct sk_buff *skb)
+{
+ return skb->len <= (MAX_IMM_TX_PKT_LEN -
+ sizeof(struct fw_ofld_tx_data_wr));
+}
+
+static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
+ struct l2t_entry *e)
+{
+ struct cpl_act_open_req *req;
+ int wscale = cxgbi_sock_compute_wscale(csk->mss_idx);
+ unsigned long long opt0;
+ unsigned int opt2;
+ unsigned int qid_atid = ((unsigned int)csk->atid) |
+ (((unsigned int)csk->rss_qid) << 14);
+
+ opt0 = KEEP_ALIVE(1) |
+ WND_SCALE(wscale) |
+ MSS_IDX(csk->mss_idx) |
+ L2T_IDX(((struct l2t_entry *)csk->l2t)->idx) |
+ TX_CHAN(csk->tx_chan) |
+ SMAC_SEL(csk->smac_idx) |
+ ULP_MODE(ULP_MODE_ISCSI) |
+ RCV_BUFSIZ(cxgb4i_rcv_win >> 10);
+ opt2 = RX_CHANNEL(0) |
+ RSS_QUEUE_VALID |
+ (1 << 20) | (1 << 22) |
+ RSS_QUEUE(csk->rss_qid);
+
+ set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id);
+ req = (struct cpl_act_open_req *)skb->head;
+
+ INIT_TP_WR(req, 0);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
+ qid_atid));
+ req->local_port = csk->saddr.sin_port;
+ req->peer_port = csk->daddr.sin_port;
+ req->local_ip = csk->saddr.sin_addr.s_addr;
+ req->peer_ip = csk->daddr.sin_addr.s_addr;
+ req->opt0 = cpu_to_be64(opt0);
+ req->params = 0;
+ req->opt2 = cpu_to_be32(opt2);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n",
+ csk, &req->local_ip, ntohs(req->local_port),
+ &req->peer_ip, ntohs(req->peer_port),
+ csk->atid, csk->rss_qid);
+
+ cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
+}
+
+static void send_close_req(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb = csk->cpl_close;
+ struct cpl_close_con_req *req = (struct cpl_close_con_req *)skb->head;
+ unsigned int tid = csk->tid;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, tid %u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ csk->cpl_close = NULL;
+ set_wr_txq(skb, CPL_PRIORITY_DATA, csk->port_id);
+ INIT_TP_WR(req, tid);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid));
+ req->rsvd = 0;
+
+ cxgbi_sock_skb_entail(csk, skb);
+ if (csk->state >= CTP_ESTABLISHED)
+ push_tx_frames(csk, 1);
+}
+
+static void abort_arp_failure(void *handle, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk = (struct cxgbi_sock *)handle;
+ struct cpl_abort_req *req;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, tid %u, abort.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ req = (struct cpl_abort_req *)skb->data;
+ req->cmd = CPL_ABORT_NO_RST;
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+}
+
+static void send_abort_req(struct cxgbi_sock *csk)
+{
+ struct cpl_abort_req *req;
+ struct sk_buff *skb = csk->cpl_abort_req;
+
+ if (unlikely(csk->state == CTP_ABORTING) || !skb || !csk->cdev)
+ return;
+ cxgbi_sock_set_state(csk, CTP_ABORTING);
+ cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_PENDING);
+ cxgbi_sock_purge_write_queue(csk);
+
+ csk->cpl_abort_req = NULL;
+ req = (struct cpl_abort_req *)skb->head;
+ set_queue(skb, CPL_PRIORITY_DATA, csk);
+ req->cmd = CPL_ABORT_SEND_RST;
+ t4_set_arp_err_handler(skb, csk, abort_arp_failure);
+ INIT_TP_WR(req, csk->tid);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, csk->tid));
+ req->rsvd0 = htonl(csk->snd_nxt);
+ req->rsvd1 = !cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, snd_nxt %u, 0x%x.\n",
+ csk, csk->state, csk->flags, csk->tid, csk->snd_nxt,
+ req->rsvd1);
+
+ cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
+}
+
+static void send_abort_rpl(struct cxgbi_sock *csk, int rst_status)
+{
+ struct sk_buff *skb = csk->cpl_abort_rpl;
+ struct cpl_abort_rpl *rpl = (struct cpl_abort_rpl *)skb->head;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, status %d.\n",
+ csk, csk->state, csk->flags, csk->tid, rst_status);
+
+ csk->cpl_abort_rpl = NULL;
+ set_queue(skb, CPL_PRIORITY_DATA, csk);
+ INIT_TP_WR(rpl, csk->tid);
+ OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, csk->tid));
+ rpl->cmd = rst_status;
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+}
+
+/*
+ * CPL connection rx data ack: host ->
+ * Send RX credits through an RX_DATA_ACK CPL message. Returns the number of
+ * credits sent.
+ */
+static u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits)
+{
+ struct sk_buff *skb;
+ struct cpl_rx_data_ack *req;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx,%u, credit %u.\n",
+ csk, csk->state, csk->flags, csk->tid, credits);
+
+ skb = alloc_cpl(sizeof(*req), 0, GFP_ATOMIC);
+ if (!skb) {
+ pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits);
+ return 0;
+ }
+ req = (struct cpl_rx_data_ack *)skb->head;
+
+ set_wr_txq(skb, CPL_PRIORITY_ACK, csk->port_id);
+ INIT_TP_WR(req, csk->tid);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK,
+ csk->tid));
+ req->credit_dack = cpu_to_be32(RX_CREDITS(credits) | RX_FORCE_ACK(1));
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+ return credits;
+}
+
+/*
+ * sgl_len - calculates the size of an SGL of the given capacity
+ * @n: the number of SGL entries
+ * Calculates the number of flits needed for a scatter/gather list that
+ * can hold the given number of entries.
+ */
+static inline unsigned int sgl_len(unsigned int n)
+{
+ n--;
+ return (3 * n) / 2 + (n & 1) + 2;
+}
+
+/*
+ * calc_tx_flits_ofld - calculate # of flits for an offload packet
+ * @skb: the packet
+ *
+ * Returns the number of flits needed for the given offload packet.
+ * These packets are already fully constructed and no additional headers
+ * will be added.
+ */
+static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
+{
+ unsigned int flits, cnt;
+
+ if (is_ofld_imm(skb))
+ return DIV_ROUND_UP(skb->len, 8);
+ flits = skb_transport_offset(skb) / 8;
+ cnt = skb_shinfo(skb)->nr_frags;
+ if (skb->tail != skb->transport_header)
+ cnt++;
+ return flits + sgl_len(cnt);
+}
+
+static inline void send_tx_flowc_wr(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb;
+ struct fw_flowc_wr *flowc;
+ int flowclen, i;
+
+ flowclen = 80;
+ skb = alloc_cpl(flowclen, 0, GFP_ATOMIC);
+ flowc = (struct fw_flowc_wr *)skb->head;
+ flowc->op_to_nparams =
+ htonl(FW_WR_OP(FW_FLOWC_WR) | FW_FLOWC_WR_NPARAMS(8));
+ flowc->flowid_len16 =
+ htonl(FW_WR_LEN16(DIV_ROUND_UP(72, 16)) |
+ FW_WR_FLOWID(csk->tid));
+ flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
+ flowc->mnemval[0].val = htonl(0);
+ flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
+ flowc->mnemval[1].val = htonl(csk->tx_chan);
+ flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
+ flowc->mnemval[2].val = htonl(csk->tx_chan);
+ flowc->mnemval[3].mnemonic = FW_FLOWC_MNEM_IQID;
+ flowc->mnemval[3].val = htonl(csk->rss_qid);
+ flowc->mnemval[4].mnemonic = FW_FLOWC_MNEM_SNDNXT;
+ flowc->mnemval[4].val = htonl(csk->snd_nxt);
+ flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_RCVNXT;
+ flowc->mnemval[5].val = htonl(csk->rcv_nxt);
+ flowc->mnemval[6].mnemonic = FW_FLOWC_MNEM_SNDBUF;
+ flowc->mnemval[6].val = htonl(cxgb4i_snd_win);
+ flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;
+ flowc->mnemval[7].val = htonl(csk->advmss);
+ flowc->mnemval[8].mnemonic = 0;
+ flowc->mnemval[8].val = 0;
+ for (i = 0; i < 9; i++) {
+ flowc->mnemval[i].r4[0] = 0;
+ flowc->mnemval[i].r4[1] = 0;
+ flowc->mnemval[i].r4[2] = 0;
+ }
+ set_queue(skb, CPL_PRIORITY_DATA, csk);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, tid 0x%x, %u,%u,%u,%u,%u,%u,%u.\n",
+ csk, csk->tid, 0, csk->tx_chan, csk->rss_qid,
+ csk->snd_nxt, csk->rcv_nxt, cxgb4i_snd_win,
+ csk->advmss);
+
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+}
+
+static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb,
+ int dlen, int len, u32 credits, int compl)
+{
+ struct fw_ofld_tx_data_wr *req;
+ unsigned int submode = cxgbi_skcb_ulp_mode(skb) & 3;
+ unsigned int wr_ulp_mode = 0;
+
+ req = (struct fw_ofld_tx_data_wr *)__skb_push(skb, sizeof(*req));
+
+ if (is_ofld_imm(skb)) {
+ req->op_to_immdlen = htonl(FW_WR_OP(FW_OFLD_TX_DATA_WR) |
+ FW_WR_COMPL(1) |
+ FW_WR_IMMDLEN(dlen));
+ req->flowid_len16 = htonl(FW_WR_FLOWID(csk->tid) |
+ FW_WR_LEN16(credits));
+ } else {
+ req->op_to_immdlen =
+ cpu_to_be32(FW_WR_OP(FW_OFLD_TX_DATA_WR) |
+ FW_WR_COMPL(1) |
+ FW_WR_IMMDLEN(0));
+ req->flowid_len16 =
+ cpu_to_be32(FW_WR_FLOWID(csk->tid) |
+ FW_WR_LEN16(credits));
+ }
+ if (submode)
+ wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE(ULP2_MODE_ISCSI) |
+ FW_OFLD_TX_DATA_WR_ULPSUBMODE(submode);
+ req->tunnel_to_proxy = htonl(wr_ulp_mode) |
+ FW_OFLD_TX_DATA_WR_SHOVE(skb_peek(&csk->write_queue) ? 0 : 1);
+ req->plen = htonl(len);
+ if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT))
+ cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT);
+}
+
+static void arp_failure_skb_discard(void *handle, struct sk_buff *skb)
+{
+ kfree_skb(skb);
+}
+
+static int push_tx_frames(struct cxgbi_sock *csk, int req_completion)
+{
+ int total_size = 0;
+ struct sk_buff *skb;
+
+ if (unlikely(csk->state < CTP_ESTABLISHED ||
+ csk->state == CTP_CLOSE_WAIT_1 || csk->state >= CTP_ABORTING)) {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK |
+ 1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, in closing state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ return 0;
+ }
+
+ while (csk->wr_cred && (skb = skb_peek(&csk->write_queue)) != NULL) {
+ int dlen = skb->len;
+ int len = skb->len;
+ unsigned int credits_needed;
+
+ skb_reset_transport_header(skb);
+ if (is_ofld_imm(skb))
+ credits_needed = DIV_ROUND_UP(dlen +
+ sizeof(struct fw_ofld_tx_data_wr), 16);
+ else
+ credits_needed = DIV_ROUND_UP(8*calc_tx_flits_ofld(skb)
+ + sizeof(struct fw_ofld_tx_data_wr),
+ 16);
+
+ if (csk->wr_cred < credits_needed) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p, skb %u/%u, wr %d < %u.\n",
+ csk, skb->len, skb->data_len,
+ credits_needed, csk->wr_cred);
+ break;
+ }
+ __skb_unlink(skb, &csk->write_queue);
+ set_queue(skb, CPL_PRIORITY_DATA, csk);
+ skb->csum = credits_needed;
+ csk->wr_cred -= credits_needed;
+ csk->wr_una_cred += credits_needed;
+ cxgbi_sock_enqueue_wr(csk, skb);
+
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p, skb %u/%u, wr %d, left %u, unack %u.\n",
+ csk, skb->len, skb->data_len, credits_needed,
+ csk->wr_cred, csk->wr_una_cred);
+
+ if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) {
+ if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) {
+ send_tx_flowc_wr(csk);
+ skb->csum += 5;
+ csk->wr_cred -= 5;
+ csk->wr_una_cred += 5;
+ }
+ len += cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb));
+ make_tx_data_wr(csk, skb, dlen, len, credits_needed,
+ req_completion);
+ csk->snd_nxt += len;
+ cxgbi_skcb_clear_flag(skb, SKCBF_TX_NEED_HDR);
+ }
+ total_size += skb->truesize;
+ t4_set_arp_err_handler(skb, csk, arp_failure_skb_discard);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, skb 0x%p, %u.\n",
+ csk, csk->state, csk->flags, csk->tid, skb, len);
+
+ cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
+ }
+ return total_size;
+}
+
+static inline void free_atid(struct cxgbi_sock *csk)
+{
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
+
+ if (cxgbi_sock_flag(csk, CTPF_HAS_ATID)) {
+ cxgb4_free_atid(lldi->tids, csk->atid);
+ cxgbi_sock_clear_flag(csk, CTPF_HAS_ATID);
+ cxgbi_sock_put(csk);
+ }
+}
+
+static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_act_establish *req = (struct cpl_act_establish *)skb->data;
+ unsigned short tcp_opt = ntohs(req->tcp_opt);
+ unsigned int tid = GET_TID(req);
+ unsigned int atid = GET_TID_TID(ntohl(req->tos_atid));
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+ u32 rcv_isn = be32_to_cpu(req->rcv_isn);
+
+ csk = lookup_atid(t, atid);
+ if (unlikely(!csk)) {
+ pr_err("NO conn. for atid %u, cdev 0x%p.\n", atid, cdev);
+ goto rel_skb;
+ }
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, tid %u, atid %u, rseq %u.\n",
+ csk, csk->state, csk->flags, tid, atid, rcv_isn);
+
+ cxgbi_sock_get(csk);
+ csk->tid = tid;
+ cxgb4_insert_tid(lldi->tids, csk, tid);
+ cxgbi_sock_set_flag(csk, CTPF_HAS_TID);
+
+ free_atid(csk);
+
+ spin_lock_bh(&csk->lock);
+ if (unlikely(csk->state != CTP_ACTIVE_OPEN))
+ pr_info("csk 0x%p,%u,0x%lx,%u, got EST.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ if (csk->retry_timer.function) {
+ del_timer(&csk->retry_timer);
+ csk->retry_timer.function = NULL;
+ }
+
+ csk->copied_seq = csk->rcv_wup = csk->rcv_nxt = rcv_isn;
+ /*
+ * Causes the first RX_DATA_ACK to supply any Rx credits we couldn't
+ * pass through opt0.
+ */
+ if (cxgb4i_rcv_win > (RCV_BUFSIZ_MASK << 10))
+ csk->rcv_wup -= cxgb4i_rcv_win - (RCV_BUFSIZ_MASK << 10);
+
+ csk->advmss = lldi->mtus[GET_TCPOPT_MSS(tcp_opt)] - 40;
+ if (GET_TCPOPT_TSTAMP(tcp_opt))
+ csk->advmss -= 12;
+ if (csk->advmss < 128)
+ csk->advmss = 128;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, mss_idx %u, advmss %u.\n",
+ csk, GET_TCPOPT_MSS(tcp_opt), csk->advmss);
+
+ cxgbi_sock_established(csk, ntohl(req->snd_isn), ntohs(req->tcp_opt));
+
+ if (unlikely(cxgbi_sock_flag(csk, CTPF_ACTIVE_CLOSE_NEEDED)))
+ send_abort_req(csk);
+ else {
+ if (skb_queue_len(&csk->write_queue))
+ push_tx_frames(csk, 0);
+ cxgbi_conn_tx_open(csk);
+ }
+ spin_unlock_bh(&csk->lock);
+
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static int act_open_rpl_status_to_errno(int status)
+{
+ switch (status) {
+ case CPL_ERR_CONN_RESET:
+ return -ECONNREFUSED;
+ case CPL_ERR_ARP_MISS:
+ return -EHOSTUNREACH;
+ case CPL_ERR_CONN_TIMEDOUT:
+ return -ETIMEDOUT;
+ case CPL_ERR_TCAM_FULL:
+ return -ENOMEM;
+ case CPL_ERR_CONN_EXIST:
+ return -EADDRINUSE;
+ default:
+ return -EIO;
+ }
+}
+
+static void csk_act_open_retry_timer(unsigned long data)
+{
+ struct sk_buff *skb;
+ struct cxgbi_sock *csk = (struct cxgbi_sock *)data;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+ skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+ if (!skb)
+ cxgbi_sock_fail_act_open(csk, -ENOMEM);
+ else {
+ skb->sk = (struct sock *)csk;
+ t4_set_arp_err_handler(skb, csk,
+ cxgbi_sock_act_open_req_arp_failure);
+ send_act_open_req(csk, skb, csk->l2t);
+ }
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+}
+
+static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_act_open_rpl *rpl = (struct cpl_act_open_rpl *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ unsigned int atid =
+ GET_TID_TID(GET_AOPEN_ATID(be32_to_cpu(rpl->atid_status)));
+ unsigned int status = GET_AOPEN_STATUS(be32_to_cpu(rpl->atid_status));
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_atid(t, atid);
+ if (unlikely(!csk)) {
+ pr_err("NO matching conn. atid %u, tid %u.\n", atid, tid);
+ goto rel_skb;
+ }
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, status %u, atid %u, tid %u.\n",
+ csk, csk->state, csk->flags, status, atid, tid);
+
+ if (status && status != CPL_ERR_TCAM_FULL &&
+ status != CPL_ERR_CONN_EXIST &&
+ status != CPL_ERR_ARP_MISS)
+ cxgb4_remove_tid(lldi->tids, csk->port_id, GET_TID(rpl));
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+
+ if (status == CPL_ERR_CONN_EXIST &&
+ csk->retry_timer.function != csk_act_open_retry_timer) {
+ csk->retry_timer.function = csk_act_open_retry_timer;
+ mod_timer(&csk->retry_timer, jiffies + HZ / 2);
+ } else
+ cxgbi_sock_fail_act_open(csk,
+ act_open_rpl_status_to_errno(status));
+
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_peer_close(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_peer_close *req = (struct cpl_peer_close *)skb->data;
+ unsigned int tid = GET_TID(req);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk)) {
+ pr_err("can't find connection for tid %u.\n", tid);
+ goto rel_skb;
+ }
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ cxgbi_sock_rcv_peer_close(csk);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_close_con_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_close_con_rpl *rpl = (struct cpl_close_con_rpl *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk)) {
+ pr_err("can't find connection for tid %u.\n", tid);
+ goto rel_skb;
+ }
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt));
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static int abort_status_to_errno(struct cxgbi_sock *csk, int abort_reason,
+ int *need_rst)
+{
+ switch (abort_reason) {
+ case CPL_ERR_BAD_SYN: /* fall through */
+ case CPL_ERR_CONN_RESET:
+ return csk->state > CTP_ESTABLISHED ?
+ -EPIPE : -ECONNRESET;
+ case CPL_ERR_XMIT_TIMEDOUT:
+ case CPL_ERR_PERSIST_TIMEDOUT:
+ case CPL_ERR_FINWAIT2_TIMEDOUT:
+ case CPL_ERR_KEEPALIVE_TIMEDOUT:
+ return -ETIMEDOUT;
+ default:
+ return -EIO;
+ }
+}
+
+static void do_abort_req_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_abort_req_rss *req = (struct cpl_abort_req_rss *)skb->data;
+ unsigned int tid = GET_TID(req);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+ int rst_status = CPL_ABORT_NO_RST;
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk)) {
+ pr_err("can't find connection for tid %u.\n", tid);
+ goto rel_skb;
+ }
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, tid %u, status 0x%x.\n",
+ csk, csk->state, csk->flags, csk->tid, req->status);
+
+ if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
+ req->status == CPL_ERR_PERSIST_NEG_ADVICE)
+ goto rel_skb;
+
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+
+ if (!cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD)) {
+ cxgbi_sock_set_flag(csk, CTPF_ABORT_REQ_RCVD);
+ cxgbi_sock_set_state(csk, CTP_ABORTING);
+ goto done;
+ }
+
+ cxgbi_sock_clear_flag(csk, CTPF_ABORT_REQ_RCVD);
+ send_abort_rpl(csk, rst_status);
+
+ if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) {
+ csk->err = abort_status_to_errno(csk, req->status, &rst_status);
+ cxgbi_sock_closed(csk);
+ }
+done:
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_abort_rpl_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_abort_rpl_rss *rpl = (struct cpl_abort_rpl_rss *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_tid(t, tid);
+ if (!csk)
+ goto rel_skb;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "status 0x%x, csk 0x%p, s %u, 0x%lx.\n",
+ rpl->status, csk, csk ? csk->state : 0,
+ csk ? csk->flags : 0UL);
+
+ if (rpl->status == CPL_ERR_ABORT_FAILED)
+ goto rel_skb;
+
+ cxgbi_sock_rcv_abort_rpl(csk);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_rx_iscsi_hdr(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_iscsi_hdr *cpl = (struct cpl_iscsi_hdr *)skb->data;
+ unsigned short pdu_len_ddp = be16_to_cpu(cpl->pdu_len_ddp);
+ unsigned int tid = GET_TID(cpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+ struct sk_buff *lskb;
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk)) {
+ pr_err("can't find conn. for tid %u.\n", tid);
+ goto rel_skb;
+ }
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx, tid %u, skb 0x%p,%u, 0x%x.\n",
+ csk, csk->state, csk->flags, csk->tid, skb, skb->len,
+ pdu_len_ddp);
+
+ spin_lock_bh(&csk->lock);
+
+ if (unlikely(csk->state >= CTP_PASSIVE_CLOSE)) {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, bad state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ if (csk->state != CTP_ABORTING)
+ goto abort_conn;
+ else
+ goto discard;
+ }
+
+ cxgbi_skcb_tcp_seq(skb) = ntohl(cpl->seq);
+ skb_reset_transport_header(skb);
+ __skb_pull(skb, sizeof(*cpl));
+ __pskb_trim(skb, ntohs(cpl->len));
+
+ if (!csk->skb_ulp_lhdr) {
+ unsigned char *bhs;
+ unsigned int hlen, dlen;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx, tid %u, skb 0x%p header.\n",
+ csk, csk->state, csk->flags, csk->tid, skb);
+ csk->skb_ulp_lhdr = skb;
+ lskb = csk->skb_ulp_lhdr;
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_HDR);
+
+ if (cxgbi_skcb_tcp_seq(lskb) != csk->rcv_nxt) {
+ pr_info("tid %u, CPL_ISCSI_HDR, bad seq, 0x%x/0x%x.\n",
+ csk->tid, cxgbi_skcb_tcp_seq(lskb),
+ csk->rcv_nxt);
+ goto abort_conn;
+ }
+
+ bhs = lskb->data;
+ hlen = ntohs(cpl->len);
+ dlen = ntohl(*(unsigned int *)(bhs + 4)) & 0xFFFFFF;
+
+ if ((hlen + dlen) != ISCSI_PDU_LEN(pdu_len_ddp) - 40) {
+ pr_info("tid 0x%x, CPL_ISCSI_HDR, pdu len "
+ "mismatch %u != %u + %u, seq 0x%x.\n",
+ csk->tid, ISCSI_PDU_LEN(pdu_len_ddp) - 40,
+ hlen, dlen, cxgbi_skcb_tcp_seq(skb));
+ goto abort_conn;
+ }
+
+ cxgbi_skcb_rx_pdulen(skb) = (hlen + dlen + 3) & (~0x3);
+ if (dlen)
+ cxgbi_skcb_rx_pdulen(skb) += csk->dcrc_len;
+ csk->rcv_nxt += cxgbi_skcb_rx_pdulen(skb);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, skb 0x%p, 0x%x,%u+%u,0x%x,0x%x.\n",
+ csk, skb, *bhs, hlen, dlen,
+ ntohl(*((unsigned int *)(bhs + 16))),
+ ntohl(*((unsigned int *)(bhs + 24))));
+
+ } else {
+ lskb = csk->skb_ulp_lhdr;
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx, skb 0x%p data, 0x%p.\n",
+ csk, csk->state, csk->flags, skb, lskb);
+ }
+
+ __skb_queue_tail(&csk->receive_queue, skb);
+ spin_unlock_bh(&csk->lock);
+ return;
+
+abort_conn:
+ send_abort_req(csk);
+discard:
+ spin_unlock_bh(&csk->lock);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_rx_data_ddp(struct cxgbi_device *cdev,
+ struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct sk_buff *lskb;
+ struct cpl_rx_data_ddp *rpl = (struct cpl_rx_data_ddp *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+ unsigned int status = ntohl(rpl->ddpvld);
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk)) {
+ pr_err("can't find connection for tid %u.\n", tid);
+ goto rel_skb;
+ }
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lx, skb 0x%p,0x%x, lhdr 0x%p.\n",
+ csk, csk->state, csk->flags, skb, status, csk->skb_ulp_lhdr);
+
+ spin_lock_bh(&csk->lock);
+
+ if (unlikely(csk->state >= CTP_PASSIVE_CLOSE)) {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, bad state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ if (csk->state != CTP_ABORTING)
+ goto abort_conn;
+ else
+ goto discard;
+ }
+
+ if (!csk->skb_ulp_lhdr) {
+ pr_err("tid 0x%x, rcv RX_DATA_DDP w/o pdu bhs.\n", csk->tid);
+ goto abort_conn;
+ }
+
+ lskb = csk->skb_ulp_lhdr;
+ csk->skb_ulp_lhdr = NULL;
+
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_STATUS);
+ cxgbi_skcb_rx_ddigest(lskb) = ntohl(rpl->ulp_crc);
+
+ if (ntohs(rpl->len) != cxgbi_skcb_rx_pdulen(lskb))
+ pr_info("tid 0x%x, RX_DATA_DDP pdulen %u != %u.\n",
+ csk->tid, ntohs(rpl->len), cxgbi_skcb_rx_pdulen(lskb));
+
+ if (status & (1 << CPL_RX_DDP_STATUS_HCRC_SHIFT)) {
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, lhdr 0x%p, status 0x%x, hcrc bad.\n",
+ csk, lskb, status);
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_HCRC_ERR);
+ }
+ if (status & (1 << CPL_RX_DDP_STATUS_DCRC_SHIFT)) {
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, lhdr 0x%p, status 0x%x, dcrc bad.\n",
+ csk, lskb, status);
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_DCRC_ERR);
+ }
+ if (status & (1 << CPL_RX_DDP_STATUS_PAD_SHIFT)) {
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, lhdr 0x%p, status 0x%x, pad bad.\n",
+ csk, lskb, status);
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_PAD_ERR);
+ }
+ if ((status & (1 << CPL_RX_DDP_STATUS_DDP_SHIFT)) &&
+ !cxgbi_skcb_test_flag(lskb, SKCBF_RX_DATA)) {
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, lhdr 0x%p, 0x%x, data ddp'ed.\n",
+ csk, lskb, status);
+ cxgbi_skcb_set_flag(lskb, SKCBF_RX_DATA_DDPD);
+ }
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, lskb 0x%p, f 0x%lx.\n",
+ csk, lskb, cxgbi_skcb_flags(lskb));
+
+ cxgbi_conn_pdu_ready(csk);
+ spin_unlock_bh(&csk->lock);
+ goto rel_skb;
+
+abort_conn:
+ send_abort_req(csk);
+discard:
+ spin_unlock_bh(&csk->lock);
+rel_skb:
+ __kfree_skb(skb);
+}
+
+static void do_fw4_ack(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk;
+ struct cpl_fw4_ack *rpl = (struct cpl_fw4_ack *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+
+ csk = lookup_tid(t, tid);
+ if (unlikely(!csk))
+ pr_err("can't find connection for tid %u.\n", tid);
+ else {
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ cxgbi_sock_rcv_wr_ack(csk, rpl->credits, ntohl(rpl->snd_una),
+ rpl->seq_vld);
+ }
+ __kfree_skb(skb);
+}
+
+static void do_set_tcb_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
+{
+ struct cpl_set_tcb_rpl *rpl = (struct cpl_set_tcb_rpl *)skb->data;
+ unsigned int tid = GET_TID(rpl);
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct tid_info *t = lldi->tids;
+ struct cxgbi_sock *csk;
+
+ csk = lookup_tid(t, tid);
+ if (!csk)
+ pr_err("can't find conn. for tid %u.\n", tid);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,%lx,%u, status 0x%x.\n",
+ csk, csk->state, csk->flags, csk->tid, rpl->status);
+
+ if (rpl->status != CPL_ERR_NONE)
+ pr_err("csk 0x%p,%u, SET_TCB_RPL status %u.\n",
+ csk, tid, rpl->status);
+
+ __kfree_skb(skb);
+}
+
+static int alloc_cpls(struct cxgbi_sock *csk)
+{
+ csk->cpl_close = alloc_cpl(sizeof(struct cpl_close_con_req),
+ 0, GFP_NOIO);
+ if (!csk->cpl_close)
+ return -ENOMEM;
+
+ csk->cpl_abort_req = alloc_cpl(sizeof(struct cpl_abort_req),
+ 0, GFP_NOIO);
+ if (!csk->cpl_abort_req)
+ goto free_cpls;
+
+ csk->cpl_abort_rpl = alloc_cpl(sizeof(struct cpl_abort_rpl),
+ 0, GFP_NOIO);
+ if (!csk->cpl_abort_rpl)
+ goto free_cpls;
+ return 0;
+
+free_cpls:
+ cxgbi_sock_free_cpl_skbs(csk);
+ return -ENOMEM;
+}
+
+static inline void l2t_put(struct cxgbi_sock *csk)
+{
+ if (csk->l2t) {
+ cxgb4_l2t_release(csk->l2t);
+ csk->l2t = NULL;
+ cxgbi_sock_put(csk);
+ }
+}
+
+static void release_offload_resources(struct cxgbi_sock *csk)
+{
+ struct cxgb4_lld_info *lldi;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ cxgbi_sock_free_cpl_skbs(csk);
+ if (csk->wr_cred != csk->wr_max_cred) {
+ cxgbi_sock_purge_wr_queue(csk);
+ cxgbi_sock_reset_wr_list(csk);
+ }
+
+ l2t_put(csk);
+ if (cxgbi_sock_flag(csk, CTPF_HAS_ATID))
+ free_atid(csk);
+ else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) {
+ lldi = cxgbi_cdev_priv(csk->cdev);
+ cxgb4_remove_tid(lldi->tids, 0, csk->tid);
+ cxgbi_sock_clear_flag(csk, CTPF_HAS_TID);
+ cxgbi_sock_put(csk);
+ }
+ csk->dst = NULL;
+ csk->cdev = NULL;
+}
+
+static int init_act_open(struct cxgbi_sock *csk)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct net_device *ndev = cdev->ports[csk->port_id];
+ struct port_info *pi = netdev_priv(ndev);
+ struct sk_buff *skb = NULL;
+ unsigned int step;
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, csk->state, csk->flags, csk->tid);
+
+ csk->atid = cxgb4_alloc_atid(lldi->tids, csk);
+ if (csk->atid < 0) {
+ pr_err("%s, NO atid available.\n", ndev->name);
+ return -EINVAL;
+ }
+ cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
+ cxgbi_sock_get(csk);
+
+ csk->l2t = cxgb4_l2t_get(lldi->l2t, csk->dst->neighbour, ndev, 0);
+ if (!csk->l2t) {
+ pr_err("%s, cannot alloc l2t.\n", ndev->name);
+ goto rel_resource;
+ }
+ cxgbi_sock_get(csk);
+
+ skb = alloc_cpl(sizeof(struct cpl_act_open_req), 0, GFP_NOIO);
+ if (!skb)
+ goto rel_resource;
+ skb->sk = (struct sock *)csk;
+ t4_set_arp_err_handler(skb, csk, cxgbi_sock_act_open_req_arp_failure);
+
+ if (!csk->mtu)
+ csk->mtu = dst_mtu(csk->dst);
+ cxgb4_best_mtu(lldi->mtus, csk->mtu, &csk->mss_idx);
+ csk->tx_chan = cxgb4_port_chan(ndev);
+ /* SMT two entries per row */
+ csk->smac_idx = ((cxgb4_port_viid(ndev) & 0x7F)) << 1;
+ step = lldi->ntxq / lldi->nchan;
+ csk->txq_idx = cxgb4_port_idx(ndev) * step;
+ step = lldi->nrxq / lldi->nchan;
+ csk->rss_qid = lldi->rxq_ids[cxgb4_port_idx(ndev) * step];
+ csk->wr_max_cred = csk->wr_cred = lldi->wr_cred;
+ csk->wr_una_cred = 0;
+ cxgbi_sock_reset_wr_list(csk);
+ csk->err = 0;
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,p%d,%s, %u,%u,%u, mss %u,%u, smac %u.\n",
+ csk, pi->port_id, ndev->name, csk->tx_chan,
+ csk->txq_idx, csk->rss_qid, csk->mtu, csk->mss_idx,
+ csk->smac_idx);
+
+ cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN);
+ send_act_open_req(csk, skb, csk->l2t);
+ return 0;
+
+rel_resource:
+ if (skb)
+ __kfree_skb(skb);
+ return -EINVAL;
+}
+
+cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = {
+ [CPL_ACT_ESTABLISH] = do_act_establish,
+ [CPL_ACT_OPEN_RPL] = do_act_open_rpl,
+ [CPL_PEER_CLOSE] = do_peer_close,
+ [CPL_ABORT_REQ_RSS] = do_abort_req_rss,
+ [CPL_ABORT_RPL_RSS] = do_abort_rpl_rss,
+ [CPL_CLOSE_CON_RPL] = do_close_con_rpl,
+ [CPL_FW4_ACK] = do_fw4_ack,
+ [CPL_ISCSI_HDR] = do_rx_iscsi_hdr,
+ [CPL_SET_TCB_RPL] = do_set_tcb_rpl,
+ [CPL_RX_DATA_DDP] = do_rx_data_ddp,
+};
+
+int cxgb4i_ofld_init(struct cxgbi_device *cdev)
+{
+ int rc;
+
+ if (cxgb4i_max_connect > CXGB4I_MAX_CONN)
+ cxgb4i_max_connect = CXGB4I_MAX_CONN;
+
+ rc = cxgbi_device_portmap_create(cdev, cxgb4i_sport_base,
+ cxgb4i_max_connect);
+ if (rc < 0)
+ return rc;
+
+ cdev->csk_release_offload_resources = release_offload_resources;
+ cdev->csk_push_tx_frames = push_tx_frames;
+ cdev->csk_send_abort_req = send_abort_req;
+ cdev->csk_send_close_req = send_close_req;
+ cdev->csk_send_rx_credits = send_rx_credits;
+ cdev->csk_alloc_cpls = alloc_cpls;
+ cdev->csk_init_act_open = init_act_open;
+
+ pr_info("cdev 0x%p, offload up, added.\n", cdev);
+ return 0;
+}
+
+/*
+ * functions to program the pagepod in h/w
+ */
+static inline void ulp_mem_io_set_hdr(struct ulp_mem_io *req,
+ unsigned int dlen, unsigned int pm_addr)
+{
+ struct ulptx_sgl *sgl;
+ unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
+ sizeof(struct ulptx_sgl), 16);
+
+ INIT_ULPTX_WR(req, wr_len, 0, 0);
+ req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE));
+ req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5));
+ req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5));
+ req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16));
+ sgl = (struct ulptx_sgl *)(req + 1);
+ sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(1));
+ sgl->len0 = htonl(dlen);
+}
+
+static int ddp_ppod_write_sgl(struct cxgbi_device *cdev, unsigned int port_id,
+ struct cxgbi_pagepod_hdr *hdr, unsigned int idx,
+ unsigned int npods,
+ struct cxgbi_gather_list *gl,
+ unsigned int gl_pidx)
+{
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ unsigned int dlen, pm_addr;
+ struct sk_buff *skb;
+ struct ulp_mem_io *req;
+ struct ulptx_sgl *sgl;
+ struct cxgbi_pagepod *ppod;
+ unsigned int i;
+
+ dlen = PPOD_SIZE * npods;
+ pm_addr = idx * PPOD_SIZE + ddp->llimit;
+
+ skb = alloc_cpl(sizeof(*req) + sizeof(*sgl), dlen, GFP_ATOMIC);
+ if (!skb) {
+ pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
+ cdev, idx, npods);
+ return -ENOMEM;
+ }
+ req = (struct ulp_mem_io *)skb->head;
+ set_queue(skb, CPL_PRIORITY_CONTROL, NULL);
+
+ ulp_mem_io_set_hdr(req, dlen, pm_addr);
+ sgl = (struct ulptx_sgl *)(req + 1);
+ ppod = (struct cxgbi_pagepod *)(sgl + 1);
+ sgl->addr0 = cpu_to_be64(virt_to_phys(ppod));
+
+ for (i = 0; i < npods; i++, ppod++, gl_pidx += PPOD_PAGES_MAX) {
+ if (!hdr && !gl)
+ cxgbi_ddp_ppod_clear(ppod);
+ else
+ cxgbi_ddp_ppod_set(ppod, hdr, gl, gl_pidx);
+ }
+
+ cxgb4_ofld_send(cdev->ports[port_id], skb);
+ return 0;
+}
+
+static int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
+ unsigned int idx, unsigned int npods,
+ struct cxgbi_gather_list *gl)
+{
+ unsigned int i, cnt;
+ int err = 0;
+
+ for (i = 0; i < npods; i += cnt, idx += cnt) {
+ cnt = npods - i;
+ if (cnt > ULPMEM_DSGL_MAX_NPPODS)
+ cnt = ULPMEM_DSGL_MAX_NPPODS;
+ err = ddp_ppod_write_sgl(csk->cdev, csk->port_id, hdr,
+ idx, cnt, gl, 4 * i);
+ if (err < 0)
+ break;
+ }
+ return err;
+}
+
+static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
+ unsigned int idx, unsigned int npods)
+{
+ unsigned int i, cnt;
+ int err;
+
+ for (i = 0; i < npods; i += cnt, idx += cnt) {
+ cnt = npods - i;
+ if (cnt > ULPMEM_DSGL_MAX_NPPODS)
+ cnt = ULPMEM_DSGL_MAX_NPPODS;
+ err = ddp_ppod_write_sgl(chba->cdev, chba->port_id, NULL,
+ idx, cnt, NULL, 0);
+ if (err < 0)
+ break;
+ }
+}
+
+static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
+ int pg_idx, bool reply)
+{
+ struct sk_buff *skb;
+ struct cpl_set_tcb_field *req;
+ u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;
+
+ if (!pg_idx)
+ return 0;
+
+ skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ /* set up ulp submode and page size */
+ val = (val & 0x03) << 2;
+ val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
+
+ req = (struct cpl_set_tcb_field *)skb->head;
+ INIT_TP_WR(req, csk->tid);
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, csk->tid));
+ req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
+ req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
+ req->mask = cpu_to_be64(TCB_ULP_TYPE(TCB_ULP_TYPE_MASK));
+ req->val = cpu_to_be64(val);
+ set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, tid 0x%x, pg_idx %u.\n", csk, csk->tid, pg_idx);
+
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+ return 0;
+}
+
+static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
+ int hcrc, int dcrc, int reply)
+{
+ struct sk_buff *skb;
+ struct cpl_set_tcb_field *req;
+ u64 val = (hcrc ? ULP_CRC_HEADER : 0) | (dcrc ? ULP_CRC_DATA : 0);
+
+ val = TCB_ULP_RAW(val);
+ val |= TCB_ULP_TYPE(ULP2_MODE_ISCSI);
+
+ skb = alloc_cpl(sizeof(*req), 0, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ csk->hcrc_len = (hcrc ? 4 : 0);
+ csk->dcrc_len = (dcrc ? 4 : 0);
+ /* set up ulp submode and page size */
+ req = (struct cpl_set_tcb_field *)skb->head;
+ INIT_TP_WR(req, tid);
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
+ req->reply_ctrl = htons(NO_REPLY(reply) | QUEUENO(csk->rss_qid));
+ req->word_cookie = htons(TCB_WORD(W_TCB_ULP_RAW));
+ req->mask = cpu_to_be64(TCB_ULP_RAW(TCB_ULP_RAW_MASK));
+ req->val = cpu_to_be64(val);
+ set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
+
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, tid 0x%x, crc %d,%d.\n", csk, csk->tid, hcrc, dcrc);
+
+ cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
+ return 0;
+}
+
+static int cxgb4i_ddp_init(struct cxgbi_device *cdev)
+{
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ unsigned int tagmask, pgsz_factor[4];
+ int err;
+
+ if (ddp) {
+ kref_get(&ddp->refcnt);
+ pr_warn("cdev 0x%p, ddp 0x%p already set up.\n",
+ cdev, cdev->ddp);
+ return -EALREADY;
+ }
+
+ err = cxgbi_ddp_init(cdev, lldi->vr->iscsi.start,
+ lldi->vr->iscsi.start + lldi->vr->iscsi.size - 1,
+ lldi->iscsi_iolen, lldi->iscsi_iolen);
+ if (err < 0)
+ return err;
+
+ ddp = cdev->ddp;
+
+ tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
+ cxgbi_ddp_page_size_factor(pgsz_factor);
+ cxgb4_iscsi_init(lldi->ports[0], tagmask, pgsz_factor);
+
+ cdev->csk_ddp_free_gl_skb = NULL;
+ cdev->csk_ddp_alloc_gl_skb = NULL;
+ cdev->csk_ddp_setup_digest = ddp_setup_conn_digest;
+ cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx;
+ cdev->csk_ddp_set = ddp_set_map;
+ cdev->csk_ddp_clear = ddp_clear_map;
+
+ pr_info("cxgb4i 0x%p tag: sw %u, rsvd %u,%u, mask 0x%x.\n",
+ cdev, cdev->tag_format.sw_bits, cdev->tag_format.rsvd_bits,
+ cdev->tag_format.rsvd_shift, cdev->tag_format.rsvd_mask);
+ pr_info("cxgb4i 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u, "
+ " %u/%u.\n",
+ cdev, ddp->nppods, ddp->idx_bits, ddp->idx_mask,
+ ddp->rsvd_tag_mask, ddp->max_txsz, lldi->iscsi_iolen,
+ ddp->max_rxsz, lldi->iscsi_iolen);
+ pr_info("cxgb4i 0x%p max payload size: %u/%u, %u/%u.\n",
+ cdev, cdev->tx_max_size, ddp->max_txsz, cdev->rx_max_size,
+ ddp->max_rxsz);
+ return 0;
+}
+
+static void *t4_uld_add(const struct cxgb4_lld_info *lldi)
+{
+ struct cxgbi_device *cdev;
+ struct port_info *pi;
+ int i, rc;
+
+ cdev = cxgbi_device_register(sizeof(*lldi), lldi->nports);
+ if (!cdev) {
+ pr_info("t4 device 0x%p, register failed.\n", lldi);
+ return NULL;
+ }
+ pr_info("0x%p,0x%x, ports %u,%s, chan %u, q %u,%u, wr %u.\n",
+ cdev, lldi->adapter_type, lldi->nports,
+ lldi->ports[0]->name, lldi->nchan, lldi->ntxq,
+ lldi->nrxq, lldi->wr_cred);
+ for (i = 0; i < lldi->nrxq; i++)
+ log_debug(1 << CXGBI_DBG_DEV,
+ "t4 0x%p, rxq id #%d: %u.\n",
+ cdev, i, lldi->rxq_ids[i]);
+
+ memcpy(cxgbi_cdev_priv(cdev), lldi, sizeof(*lldi));
+ cdev->flags = CXGBI_FLAG_DEV_T4;
+ cdev->pdev = lldi->pdev;
+ cdev->ports = lldi->ports;
+ cdev->nports = lldi->nports;
+ cdev->mtus = lldi->mtus;
+ cdev->nmtus = NMTUS;
+ cdev->snd_win = cxgb4i_snd_win;
+ cdev->rcv_win = cxgb4i_rcv_win;
+ cdev->rx_credit_thres = cxgb4i_rx_credit_thres;
+ cdev->skb_tx_rsvd = CXGB4I_TX_HEADER_LEN;
+ cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr);
+ cdev->itp = &cxgb4i_iscsi_transport;
+
+ rc = cxgb4i_ddp_init(cdev);
+ if (rc) {
+ pr_info("t4 0x%p ddp init failed.\n", cdev);
+ goto err_out;
+ }
+ rc = cxgb4i_ofld_init(cdev);
+ if (rc) {
+ pr_info("t4 0x%p ofld init failed.\n", cdev);
+ goto err_out;
+ }
+
+ rc = cxgbi_hbas_add(cdev, CXGB4I_MAX_LUN, CXGBI_MAX_CONN,
+ &cxgb4i_host_template, cxgb4i_stt);
+ if (rc)
+ goto err_out;
+
+ for (i = 0; i < cdev->nports; i++) {
+ pi = netdev_priv(lldi->ports[i]);
+ cdev->hbas[i]->port_id = pi->port_id;
+ }
+ return cdev;
+
+err_out:
+ cxgbi_device_unregister(cdev);
+ return ERR_PTR(-ENOMEM);
+}
+
+#define RX_PULL_LEN 128
+static int t4_uld_rx_handler(void *handle, const __be64 *rsp,
+ const struct pkt_gl *pgl)
+{
+ const struct cpl_act_establish *rpl;
+ struct sk_buff *skb;
+ unsigned int opc;
+ struct cxgbi_device *cdev = handle;
+
+ if (pgl == NULL) {
+ unsigned int len = 64 - sizeof(struct rsp_ctrl) - 8;
+
+ skb = alloc_cpl(len, 0, GFP_ATOMIC);
+ if (!skb)
+ goto nomem;
+ skb_copy_to_linear_data(skb, &rsp[1], len);
+ } else {
+ if (unlikely(*(u8 *)rsp != *(u8 *)pgl->va)) {
+ pr_info("? FL 0x%p,RSS%#llx,FL %#llx,len %u.\n",
+ pgl->va, be64_to_cpu(*rsp),
+ be64_to_cpu(*(u64 *)pgl->va),
+ pgl->tot_len);
+ return 0;
+ }
+ skb = cxgb4_pktgl_to_skb(pgl, RX_PULL_LEN, RX_PULL_LEN);
+ if (unlikely(!skb))
+ goto nomem;
+ }
+
+ rpl = (struct cpl_act_establish *)skb->data;
+ opc = rpl->ot.opcode;
+ log_debug(1 << CXGBI_DBG_TOE,
+ "cdev %p, opcode 0x%x(0x%x,0x%x), skb %p.\n",
+ cdev, opc, rpl->ot.opcode_tid, ntohl(rpl->ot.opcode_tid), skb);
+ if (cxgb4i_cplhandlers[opc])
+ cxgb4i_cplhandlers[opc](cdev, skb);
+ else {
+ pr_err("No handler for opcode 0x%x.\n", opc);
+ __kfree_skb(skb);
+ }
+ return 0;
+nomem:
+ log_debug(1 << CXGBI_DBG_TOE, "OOM bailing out.\n");
+ return 1;
+}
+
+static int t4_uld_state_change(void *handle, enum cxgb4_state state)
+{
+ struct cxgbi_device *cdev = handle;
+
+ switch (state) {
+ case CXGB4_STATE_UP:
+ pr_info("cdev 0x%p, UP.\n", cdev);
+ /* re-initialize */
+ break;
+ case CXGB4_STATE_START_RECOVERY:
+ pr_info("cdev 0x%p, RECOVERY.\n", cdev);
+ /* close all connections */
+ break;
+ case CXGB4_STATE_DOWN:
+ pr_info("cdev 0x%p, DOWN.\n", cdev);
+ break;
+ case CXGB4_STATE_DETACH:
+ pr_info("cdev 0x%p, DETACH.\n", cdev);
+ break;
+ default:
+ pr_info("cdev 0x%p, unknown state %d.\n", cdev, state);
+ break;
+ }
+ return 0;
+}
+
+static int __init cxgb4i_init_module(void)
+{
+ int rc;
+
+ printk(KERN_INFO "%s", version);
+
+ rc = cxgbi_iscsi_init(&cxgb4i_iscsi_transport, &cxgb4i_stt);
+ if (rc < 0)
+ return rc;
+ cxgb4_register_uld(CXGB4_ULD_ISCSI, &cxgb4i_uld_info);
+ return 0;
+}
+
+static void __exit cxgb4i_exit_module(void)
+{
+ cxgb4_unregister_uld(CXGB4_ULD_ISCSI);
+ cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T4);
+ cxgbi_iscsi_cleanup(&cxgb4i_iscsi_transport, &cxgb4i_stt);
+}
+
+module_init(cxgb4i_init_module);
+module_exit(cxgb4i_exit_module);
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
new file mode 100644
index 000000000000..342263b1f542
--- /dev/null
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.h
@@ -0,0 +1,38 @@
+/*
+ * cxgb4i.h: Chelsio T4 iSCSI driver.
+ *
+ * Copyright (c) 2010 Chelsio Communications, 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.
+ *
+ * Written by: Karen Xie (kxie@chelsio.com)
+ * Written by: Rakesh Ranjan (rranjan@chelsio.com)
+ */
+
+#ifndef __CXGB4I_H__
+#define __CXGB4I_H__
+
+#define CXGB4I_SCSI_HOST_QDEPTH 1024
+#define CXGB4I_MAX_CONN 16384
+#define CXGB4I_MAX_TARGET CXGB4I_MAX_CONN
+#define CXGB4I_MAX_LUN 0x1000
+
+/* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
+#define CXGB4I_TX_HEADER_LEN \
+ (sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr))
+
+struct cpl_rx_data_ddp {
+ union opcode_tid ot;
+ __be16 urg;
+ __be16 len;
+ __be32 seq;
+ union {
+ __be32 nxt_seq;
+ __be32 ddp_report;
+ };
+ __be32 ulp_crc;
+ __be32 ddpvld;
+};
+#endif /* __CXGB4I_H__ */
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
new file mode 100644
index 000000000000..db9d08a831d0
--- /dev/null
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -0,0 +1,2610 @@
+/*
+ * libcxgbi.c: Chelsio common library for T3/T4 iSCSI driver.
+ *
+ * Copyright (c) 2010 Chelsio Communications, 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.
+ *
+ * Written by: Karen Xie (kxie@chelsio.com)
+ * Written by: Rakesh Ranjan (rranjan@chelsio.com)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
+
+#include <linux/skbuff.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <linux/pci.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <linux/if_vlan.h>
+#include <linux/inet.h>
+#include <net/dst.h>
+#include <net/route.h>
+#include <linux/inetdevice.h> /* ip_dev_find */
+#include <net/tcp.h>
+
+static unsigned int dbg_level;
+
+#include "libcxgbi.h"
+
+#define DRV_MODULE_NAME "libcxgbi"
+#define DRV_MODULE_DESC "Chelsio iSCSI driver library"
+#define DRV_MODULE_VERSION "0.9.0"
+#define DRV_MODULE_RELDATE "Jun. 2010"
+
+MODULE_AUTHOR("Chelsio Communications, Inc.");
+MODULE_DESCRIPTION(DRV_MODULE_DESC);
+MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(dbg_level, uint, 0644);
+MODULE_PARM_DESC(dbg_level, "libiscsi debug level (default=0)");
+
+
+/*
+ * cxgbi device management
+ * maintains a list of the cxgbi devices
+ */
+static LIST_HEAD(cdev_list);
+static DEFINE_MUTEX(cdev_mutex);
+
+int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base,
+ unsigned int max_conn)
+{
+ struct cxgbi_ports_map *pmap = &cdev->pmap;
+
+ pmap->port_csk = cxgbi_alloc_big_mem(max_conn *
+ sizeof(struct cxgbi_sock *),
+ GFP_KERNEL);
+ if (!pmap->port_csk) {
+ pr_warn("cdev 0x%p, portmap OOM %u.\n", cdev, max_conn);
+ return -ENOMEM;
+ }
+
+ pmap->max_connect = max_conn;
+ pmap->sport_base = base;
+ spin_lock_init(&pmap->lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_portmap_create);
+
+void cxgbi_device_portmap_cleanup(struct cxgbi_device *cdev)
+{
+ struct cxgbi_ports_map *pmap = &cdev->pmap;
+ struct cxgbi_sock *csk;
+ int i;
+
+ for (i = 0; i < pmap->max_connect; i++) {
+ if (pmap->port_csk[i]) {
+ csk = pmap->port_csk[i];
+ pmap->port_csk[i] = NULL;
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, cdev 0x%p, offload down.\n",
+ csk, cdev);
+ spin_lock_bh(&csk->lock);
+ cxgbi_sock_set_flag(csk, CTPF_OFFLOAD_DOWN);
+ cxgbi_sock_closed(csk);
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_portmap_cleanup);
+
+static inline void cxgbi_device_destroy(struct cxgbi_device *cdev)
+{
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p# %u.\n", cdev, cdev->nports);
+ cxgbi_hbas_remove(cdev);
+ cxgbi_device_portmap_cleanup(cdev);
+ if (cdev->dev_ddp_cleanup)
+ cdev->dev_ddp_cleanup(cdev);
+ else
+ cxgbi_ddp_cleanup(cdev);
+ if (cdev->ddp)
+ cxgbi_ddp_cleanup(cdev);
+ if (cdev->pmap.max_connect)
+ cxgbi_free_big_mem(cdev->pmap.port_csk);
+ kfree(cdev);
+}
+
+struct cxgbi_device *cxgbi_device_register(unsigned int extra,
+ unsigned int nports)
+{
+ struct cxgbi_device *cdev;
+
+ cdev = kzalloc(sizeof(*cdev) + extra + nports *
+ (sizeof(struct cxgbi_hba *) +
+ sizeof(struct net_device *)),
+ GFP_KERNEL);
+ if (!cdev) {
+ pr_warn("nport %d, OOM.\n", nports);
+ return NULL;
+ }
+ cdev->ports = (struct net_device **)(cdev + 1);
+ cdev->hbas = (struct cxgbi_hba **)(((char*)cdev->ports) + nports *
+ sizeof(struct net_device *));
+ if (extra)
+ cdev->dd_data = ((char *)cdev->hbas) +
+ nports * sizeof(struct cxgbi_hba *);
+ spin_lock_init(&cdev->pmap.lock);
+
+ mutex_lock(&cdev_mutex);
+ list_add_tail(&cdev->list_head, &cdev_list);
+ mutex_unlock(&cdev_mutex);
+
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p# %u.\n", cdev, nports);
+ return cdev;
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_register);
+
+void cxgbi_device_unregister(struct cxgbi_device *cdev)
+{
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p# %u,%s.\n",
+ cdev, cdev->nports, cdev->nports ? cdev->ports[0]->name : "");
+ mutex_lock(&cdev_mutex);
+ list_del(&cdev->list_head);
+ mutex_unlock(&cdev_mutex);
+ cxgbi_device_destroy(cdev);
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_unregister);
+
+void cxgbi_device_unregister_all(unsigned int flag)
+{
+ struct cxgbi_device *cdev, *tmp;
+
+ mutex_lock(&cdev_mutex);
+ list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
+ if ((cdev->flags & flag) == flag) {
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p# %u,%s.\n",
+ cdev, cdev->nports, cdev->nports ?
+ cdev->ports[0]->name : "");
+ list_del(&cdev->list_head);
+ cxgbi_device_destroy(cdev);
+ }
+ }
+ mutex_unlock(&cdev_mutex);
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_unregister_all);
+
+struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev)
+{
+ struct cxgbi_device *cdev, *tmp;
+
+ mutex_lock(&cdev_mutex);
+ list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
+ if (cdev->lldev == lldev) {
+ mutex_unlock(&cdev_mutex);
+ return cdev;
+ }
+ }
+ mutex_unlock(&cdev_mutex);
+ log_debug(1 << CXGBI_DBG_DEV,
+ "lldev 0x%p, NO match found.\n", lldev);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev);
+
+static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
+ int *port)
+{
+ struct cxgbi_device *cdev, *tmp;
+ int i;
+
+ if (ndev->priv_flags & IFF_802_1Q_VLAN)
+ ndev = vlan_dev_real_dev(ndev);
+
+ mutex_lock(&cdev_mutex);
+ list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
+ for (i = 0; i < cdev->nports; i++) {
+ if (ndev == cdev->ports[i]) {
+ mutex_unlock(&cdev_mutex);
+ if (port)
+ *port = i;
+ return cdev;
+ }
+ }
+ }
+ mutex_unlock(&cdev_mutex);
+ log_debug(1 << CXGBI_DBG_DEV,
+ "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name);
+ return NULL;
+}
+
+struct cxgbi_hba *cxgbi_hba_find_by_netdev(struct net_device *dev,
+ struct cxgbi_device *cdev)
+{
+ int i;
+
+ if (dev->priv_flags & IFF_802_1Q_VLAN)
+ dev = vlan_dev_real_dev(dev);
+
+ for (i = 0; i < cdev->nports; i++) {
+ if (cdev->hbas[i]->ndev == dev)
+ return cdev->hbas[i];
+ }
+ log_debug(1 << CXGBI_DBG_DEV,
+ "ndev 0x%p, %s, cdev 0x%p, NO match found.\n",
+ dev, dev->name, cdev);
+ return NULL;
+}
+
+void cxgbi_hbas_remove(struct cxgbi_device *cdev)
+{
+ int i;
+ struct cxgbi_hba *chba;
+
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p#%u.\n", cdev, cdev->nports);
+
+ for (i = 0; i < cdev->nports; i++) {
+ chba = cdev->hbas[i];
+ if (chba) {
+ cdev->hbas[i] = NULL;
+ iscsi_host_remove(chba->shost);
+ pci_dev_put(cdev->pdev);
+ iscsi_host_free(chba->shost);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_hbas_remove);
+
+int cxgbi_hbas_add(struct cxgbi_device *cdev, unsigned int max_lun,
+ unsigned int max_id, struct scsi_host_template *sht,
+ struct scsi_transport_template *stt)
+{
+ struct cxgbi_hba *chba;
+ struct Scsi_Host *shost;
+ int i, err;
+
+ log_debug(1 << CXGBI_DBG_DEV, "cdev 0x%p, p#%u.\n", cdev, cdev->nports);
+
+ for (i = 0; i < cdev->nports; i++) {
+ shost = iscsi_host_alloc(sht, sizeof(*chba), 1);
+ if (!shost) {
+ pr_info("0x%p, p%d, %s, host alloc failed.\n",
+ cdev, i, cdev->ports[i]->name);
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ shost->transportt = stt;
+ shost->max_lun = max_lun;
+ shost->max_id = max_id;
+ shost->max_channel = 0;
+ shost->max_cmd_len = 16;
+
+ chba = iscsi_host_priv(shost);
+ chba->cdev = cdev;
+ chba->ndev = cdev->ports[i];
+ chba->shost = shost;
+
+ log_debug(1 << CXGBI_DBG_DEV,
+ "cdev 0x%p, p#%d %s: chba 0x%p.\n",
+ cdev, i, cdev->ports[i]->name, chba);
+
+ pci_dev_get(cdev->pdev);
+ err = iscsi_host_add(shost, &cdev->pdev->dev);
+ if (err) {
+ pr_info("cdev 0x%p, p#%d %s, host add failed.\n",
+ cdev, i, cdev->ports[i]->name);
+ pci_dev_put(cdev->pdev);
+ scsi_host_put(shost);
+ goto err_out;
+ }
+
+ cdev->hbas[i] = chba;
+ }
+
+ return 0;
+
+err_out:
+ cxgbi_hbas_remove(cdev);
+ return err;
+}
+EXPORT_SYMBOL_GPL(cxgbi_hbas_add);
+
+/*
+ * iSCSI offload
+ *
+ * - source port management
+ * To find a free source port in the port allocation map we use a very simple
+ * rotor scheme to look for the next free port.
+ *
+ * If a source port has been specified make sure that it doesn't collide with
+ * our normal source port allocation map. If it's outside the range of our
+ * allocation/deallocation scheme just let them use it.
+ *
+ * If the source port is outside our allocation range, the caller is
+ * responsible for keeping track of their port usage.
+ */
+static int sock_get_port(struct cxgbi_sock *csk)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgbi_ports_map *pmap = &cdev->pmap;
+ unsigned int start;
+ int idx;
+
+ if (!pmap->max_connect) {
+ pr_err("cdev 0x%p, p#%u %s, NO port map.\n",
+ cdev, csk->port_id, cdev->ports[csk->port_id]->name);
+ return -EADDRNOTAVAIL;
+ }
+
+ if (csk->saddr.sin_port) {
+ pr_err("source port NON-ZERO %u.\n",
+ ntohs(csk->saddr.sin_port));
+ return -EADDRINUSE;
+ }
+
+ spin_lock_bh(&pmap->lock);
+ if (pmap->used >= pmap->max_connect) {
+ spin_unlock_bh(&pmap->lock);
+ pr_info("cdev 0x%p, p#%u %s, ALL ports used.\n",
+ cdev, csk->port_id, cdev->ports[csk->port_id]->name);
+ return -EADDRNOTAVAIL;
+ }
+
+ start = idx = pmap->next;
+ do {
+ if (++idx >= pmap->max_connect)
+ idx = 0;
+ if (!pmap->port_csk[idx]) {
+ pmap->used++;
+ csk->saddr.sin_port =
+ htons(pmap->sport_base + idx);
+ pmap->next = idx;
+ pmap->port_csk[idx] = csk;
+ spin_unlock_bh(&pmap->lock);
+ cxgbi_sock_get(csk);
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "cdev 0x%p, p#%u %s, p %u, %u.\n",
+ cdev, csk->port_id,
+ cdev->ports[csk->port_id]->name,
+ pmap->sport_base + idx, pmap->next);
+ return 0;
+ }
+ } while (idx != start);
+ spin_unlock_bh(&pmap->lock);
+
+ /* should not happen */
+ pr_warn("cdev 0x%p, p#%u %s, next %u?\n",
+ cdev, csk->port_id, cdev->ports[csk->port_id]->name,
+ pmap->next);
+ return -EADDRNOTAVAIL;
+}
+
+static void sock_put_port(struct cxgbi_sock *csk)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgbi_ports_map *pmap = &cdev->pmap;
+
+ if (csk->saddr.sin_port) {
+ int idx = ntohs(csk->saddr.sin_port) - pmap->sport_base;
+
+ csk->saddr.sin_port = 0;
+ if (idx < 0 || idx >= pmap->max_connect) {
+ pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n",
+ cdev, csk->port_id,
+ cdev->ports[csk->port_id]->name,
+ ntohs(csk->saddr.sin_port));
+ return;
+ }
+
+ spin_lock_bh(&pmap->lock);
+ pmap->port_csk[idx] = NULL;
+ pmap->used--;
+ spin_unlock_bh(&pmap->lock);
+
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "cdev 0x%p, p#%u %s, release %u.\n",
+ cdev, csk->port_id, cdev->ports[csk->port_id]->name,
+ pmap->sport_base + idx);
+
+ cxgbi_sock_put(csk);
+ }
+}
+
+/*
+ * iscsi tcp connection
+ */
+void cxgbi_sock_free_cpl_skbs(struct cxgbi_sock *csk)
+{
+ if (csk->cpl_close) {
+ kfree_skb(csk->cpl_close);
+ csk->cpl_close = NULL;
+ }
+ if (csk->cpl_abort_req) {
+ kfree_skb(csk->cpl_abort_req);
+ csk->cpl_abort_req = NULL;
+ }
+ if (csk->cpl_abort_rpl) {
+ kfree_skb(csk->cpl_abort_rpl);
+ csk->cpl_abort_rpl = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_free_cpl_skbs);
+
+static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev)
+{
+ struct cxgbi_sock *csk = kzalloc(sizeof(*csk), GFP_NOIO);
+
+ if (!csk) {
+ pr_info("alloc csk %zu failed.\n", sizeof(*csk));
+ return NULL;
+ }
+
+ if (cdev->csk_alloc_cpls(csk) < 0) {
+ pr_info("csk 0x%p, alloc cpls failed.\n", csk);
+ kfree(csk);
+ return NULL;
+ }
+
+ spin_lock_init(&csk->lock);
+ kref_init(&csk->refcnt);
+ skb_queue_head_init(&csk->receive_queue);
+ skb_queue_head_init(&csk->write_queue);
+ setup_timer(&csk->retry_timer, NULL, (unsigned long)csk);
+ rwlock_init(&csk->callback_lock);
+ csk->cdev = cdev;
+ csk->flags = 0;
+ cxgbi_sock_set_state(csk, CTP_CLOSED);
+
+ log_debug(1 << CXGBI_DBG_SOCK, "cdev 0x%p, new csk 0x%p.\n", cdev, csk);
+
+ return csk;
+}
+
+static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport, u8 tos)
+{
+ struct rtable *rt;
+ struct flowi fl = {
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = daddr,
+ .saddr = saddr,
+ .tos = tos }
+ },
+ .proto = IPPROTO_TCP,
+ .uli_u = {
+ .ports = {
+ .sport = sport,
+ .dport = dport }
+ }
+ };
+
+ if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0))
+ return NULL;
+
+ return rt;
+}
+
+static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
+{
+ struct sockaddr_in *daddr = (struct sockaddr_in *)dst_addr;
+ struct dst_entry *dst;
+ struct net_device *ndev;
+ struct cxgbi_device *cdev;
+ struct rtable *rt = NULL;
+ struct cxgbi_sock *csk = NULL;
+ unsigned int mtu = 0;
+ int port = 0xFFFF;
+ int err = 0;
+
+ if (daddr->sin_family != AF_INET) {
+ pr_info("address family 0x%x NOT supported.\n",
+ daddr->sin_family);
+ err = -EAFNOSUPPORT;
+ goto err_out;
+ }
+
+ rt = find_route_ipv4(0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
+ if (!rt) {
+ pr_info("no route to ipv4 0x%x, port %u.\n",
+ daddr->sin_addr.s_addr, daddr->sin_port);
+ err = -ENETUNREACH;
+ goto err_out;
+ }
+ dst = &rt->dst;
+ ndev = dst->neighbour->dev;
+
+ if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
+ pr_info("multi-cast route %pI4, port %u, dev %s.\n",
+ &daddr->sin_addr.s_addr, ntohs(daddr->sin_port),
+ ndev->name);
+ err = -ENETUNREACH;
+ goto rel_rt;
+ }
+
+ if (ndev->flags & IFF_LOOPBACK) {
+ ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr);
+ mtu = ndev->mtu;
+ pr_info("rt dev %s, loopback -> %s, mtu %u.\n",
+ dst->neighbour->dev->name, ndev->name, mtu);
+ }
+
+ if (ndev->priv_flags & IFF_802_1Q_VLAN) {
+ ndev = vlan_dev_real_dev(ndev);
+ pr_info("rt dev %s, vlan -> %s.\n",
+ dst->neighbour->dev->name, ndev->name);
+ }
+
+ cdev = cxgbi_device_find_by_netdev(ndev, &port);
+ if (!cdev) {
+ pr_info("dst %pI4, %s, NOT cxgbi device.\n",
+ &daddr->sin_addr.s_addr, ndev->name);
+ err = -ENETUNREACH;
+ goto rel_rt;
+ }
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "route to %pI4 :%u, ndev p#%d,%s, cdev 0x%p.\n",
+ &daddr->sin_addr.s_addr, ntohs(daddr->sin_port),
+ port, ndev->name, cdev);
+
+ csk = cxgbi_sock_create(cdev);
+ if (!csk) {
+ err = -ENOMEM;
+ goto rel_rt;
+ }
+ csk->cdev = cdev;
+ csk->port_id = port;
+ csk->mtu = mtu;
+ csk->dst = dst;
+ csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
+ csk->daddr.sin_port = daddr->sin_port;
+ if (cdev->hbas[port]->ipv4addr)
+ csk->saddr.sin_addr.s_addr = cdev->hbas[port]->ipv4addr;
+ else
+ csk->saddr.sin_addr.s_addr = rt->rt_src;
+
+ return csk;
+
+rel_rt:
+ ip_rt_put(rt);
+ if (csk)
+ cxgbi_sock_closed(csk);
+err_out:
+ return ERR_PTR(err);
+}
+
+void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn,
+ unsigned int opt)
+{
+ csk->write_seq = csk->snd_nxt = csk->snd_una = snd_isn;
+ dst_confirm(csk->dst);
+ smp_mb();
+ cxgbi_sock_set_state(csk, CTP_ESTABLISHED);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_established);
+
+static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
+{
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, state %u, flags 0x%lx, conn 0x%p.\n",
+ csk, csk->state, csk->flags, csk->user_data);
+
+ if (csk->state != CTP_ESTABLISHED) {
+ read_lock(&csk->callback_lock);
+ if (csk->user_data)
+ iscsi_conn_failure(csk->user_data,
+ ISCSI_ERR_CONN_FAILED);
+ read_unlock(&csk->callback_lock);
+ }
+}
+
+void cxgbi_sock_closed(struct cxgbi_sock *csk)
+{
+ log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, (csk)->state, (csk)->flags, (csk)->tid);
+ cxgbi_sock_set_flag(csk, CTPF_ACTIVE_CLOSE_NEEDED);
+ if (csk->state == CTP_ACTIVE_OPEN || csk->state == CTP_CLOSED)
+ return;
+ if (csk->saddr.sin_port)
+ sock_put_port(csk);
+ if (csk->dst)
+ dst_release(csk->dst);
+ csk->cdev->csk_release_offload_resources(csk);
+ cxgbi_sock_set_state(csk, CTP_CLOSED);
+ cxgbi_inform_iscsi_conn_closing(csk);
+ cxgbi_sock_put(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_closed);
+
+static void need_active_close(struct cxgbi_sock *csk)
+{
+ int data_lost;
+ int close_req = 0;
+
+ log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, (csk)->state, (csk)->flags, (csk)->tid);
+ spin_lock_bh(&csk->lock);
+ dst_confirm(csk->dst);
+ data_lost = skb_queue_len(&csk->receive_queue);
+ __skb_queue_purge(&csk->receive_queue);
+
+ if (csk->state == CTP_ACTIVE_OPEN)
+ cxgbi_sock_set_flag(csk, CTPF_ACTIVE_CLOSE_NEEDED);
+ else if (csk->state == CTP_ESTABLISHED) {
+ close_req = 1;
+ cxgbi_sock_set_state(csk, CTP_ACTIVE_CLOSE);
+ } else if (csk->state == CTP_PASSIVE_CLOSE) {
+ close_req = 1;
+ cxgbi_sock_set_state(csk, CTP_CLOSE_WAIT_2);
+ }
+
+ if (close_req) {
+ if (data_lost)
+ csk->cdev->csk_send_abort_req(csk);
+ else
+ csk->cdev->csk_send_close_req(csk);
+ }
+
+ spin_unlock_bh(&csk->lock);
+}
+
+void cxgbi_sock_fail_act_open(struct cxgbi_sock *csk, int errno)
+{
+ pr_info("csk 0x%p,%u,%lx, %pI4:%u-%pI4:%u, err %d.\n",
+ csk, csk->state, csk->flags,
+ &csk->saddr.sin_addr.s_addr, csk->saddr.sin_port,
+ &csk->daddr.sin_addr.s_addr, csk->daddr.sin_port,
+ errno);
+
+ cxgbi_sock_set_state(csk, CTP_CONNECTING);
+ csk->err = errno;
+ cxgbi_sock_closed(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_fail_act_open);
+
+void cxgbi_sock_act_open_req_arp_failure(void *handle, struct sk_buff *skb)
+{
+ struct cxgbi_sock *csk = (struct cxgbi_sock *)skb->sk;
+
+ log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, (csk)->state, (csk)->flags, (csk)->tid);
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+ if (csk->state == CTP_ACTIVE_OPEN)
+ cxgbi_sock_fail_act_open(csk, -EHOSTUNREACH);
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+ __kfree_skb(skb);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_act_open_req_arp_failure);
+
+void cxgbi_sock_rcv_abort_rpl(struct cxgbi_sock *csk)
+{
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+ if (cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) {
+ if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_RCVD))
+ cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_RCVD);
+ else {
+ cxgbi_sock_clear_flag(csk, CTPF_ABORT_RPL_RCVD);
+ cxgbi_sock_clear_flag(csk, CTPF_ABORT_RPL_PENDING);
+ if (cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD))
+ pr_err("csk 0x%p,%u,0x%lx,%u,ABT_RPL_RSS.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ cxgbi_sock_closed(csk);
+ }
+ }
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_rcv_abort_rpl);
+
+void cxgbi_sock_rcv_peer_close(struct cxgbi_sock *csk)
+{
+ log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, (csk)->state, (csk)->flags, (csk)->tid);
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+
+ if (cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING))
+ goto done;
+
+ switch (csk->state) {
+ case CTP_ESTABLISHED:
+ cxgbi_sock_set_state(csk, CTP_PASSIVE_CLOSE);
+ break;
+ case CTP_ACTIVE_CLOSE:
+ cxgbi_sock_set_state(csk, CTP_CLOSE_WAIT_2);
+ break;
+ case CTP_CLOSE_WAIT_1:
+ cxgbi_sock_closed(csk);
+ break;
+ case CTP_ABORTING:
+ break;
+ default:
+ pr_err("csk 0x%p,%u,0x%lx,%u, bad state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ }
+ cxgbi_inform_iscsi_conn_closing(csk);
+done:
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_rcv_peer_close);
+
+void cxgbi_sock_rcv_close_conn_rpl(struct cxgbi_sock *csk, u32 snd_nxt)
+{
+ log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx,%u.\n",
+ csk, (csk)->state, (csk)->flags, (csk)->tid);
+ cxgbi_sock_get(csk);
+ spin_lock_bh(&csk->lock);
+
+ csk->snd_una = snd_nxt - 1;
+ if (cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING))
+ goto done;
+
+ switch (csk->state) {
+ case CTP_ACTIVE_CLOSE:
+ cxgbi_sock_set_state(csk, CTP_CLOSE_WAIT_1);
+ break;
+ case CTP_CLOSE_WAIT_1:
+ case CTP_CLOSE_WAIT_2:
+ cxgbi_sock_closed(csk);
+ break;
+ case CTP_ABORTING:
+ break;
+ default:
+ pr_err("csk 0x%p,%u,0x%lx,%u, bad state.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ }
+done:
+ spin_unlock_bh(&csk->lock);
+ cxgbi_sock_put(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_rcv_close_conn_rpl);
+
+void cxgbi_sock_rcv_wr_ack(struct cxgbi_sock *csk, unsigned int credits,
+ unsigned int snd_una, int seq_chk)
+{
+ log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx,%u, cr %u,%u+%u, snd_una %u,%d.\n",
+ csk, csk->state, csk->flags, csk->tid, credits,
+ csk->wr_cred, csk->wr_una_cred, snd_una, seq_chk);
+
+ spin_lock_bh(&csk->lock);
+
+ csk->wr_cred += credits;
+ if (csk->wr_una_cred > csk->wr_max_cred - csk->wr_cred)
+ csk->wr_una_cred = csk->wr_max_cred - csk->wr_cred;
+
+ while (credits) {
+ struct sk_buff *p = cxgbi_sock_peek_wr(csk);
+
+ if (unlikely(!p)) {
+ pr_err("csk 0x%p,%u,0x%lx,%u, cr %u,%u+%u, empty.\n",
+ csk, csk->state, csk->flags, csk->tid, credits,
+ csk->wr_cred, csk->wr_una_cred);
+ break;
+ }
+
+ if (unlikely(credits < p->csum)) {
+ pr_warn("csk 0x%p,%u,0x%lx,%u, cr %u,%u+%u, < %u.\n",
+ csk, csk->state, csk->flags, csk->tid,
+ credits, csk->wr_cred, csk->wr_una_cred,
+ p->csum);
+ p->csum -= credits;
+ break;
+ } else {
+ cxgbi_sock_dequeue_wr(csk);
+ credits -= p->csum;
+ kfree_skb(p);
+ }
+ }
+
+ cxgbi_sock_check_wr_invariants(csk);
+
+ if (seq_chk) {
+ if (unlikely(before(snd_una, csk->snd_una))) {
+ pr_warn("csk 0x%p,%u,0x%lx,%u, snd_una %u/%u.",
+ csk, csk->state, csk->flags, csk->tid, snd_una,
+ csk->snd_una);
+ goto done;
+ }
+
+ if (csk->snd_una != snd_una) {
+ csk->snd_una = snd_una;
+ dst_confirm(csk->dst);
+ }
+ }
+
+ if (skb_queue_len(&csk->write_queue)) {
+ if (csk->cdev->csk_push_tx_frames(csk, 0))
+ cxgbi_conn_tx_open(csk);
+ } else
+ cxgbi_conn_tx_open(csk);
+done:
+ spin_unlock_bh(&csk->lock);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_rcv_wr_ack);
+
+static unsigned int cxgbi_sock_find_best_mtu(struct cxgbi_sock *csk,
+ unsigned short mtu)
+{
+ int i = 0;
+
+ while (i < csk->cdev->nmtus - 1 && csk->cdev->mtus[i + 1] <= mtu)
+ ++i;
+
+ return i;
+}
+
+unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *csk, unsigned int pmtu)
+{
+ unsigned int idx;
+ struct dst_entry *dst = csk->dst;
+
+ csk->advmss = dst_metric(dst, RTAX_ADVMSS);
+
+ if (csk->advmss > pmtu - 40)
+ csk->advmss = pmtu - 40;
+ if (csk->advmss < csk->cdev->mtus[0] - 40)
+ csk->advmss = csk->cdev->mtus[0] - 40;
+ idx = cxgbi_sock_find_best_mtu(csk, csk->advmss + 40);
+
+ return idx;
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_select_mss);
+
+void cxgbi_sock_skb_entail(struct cxgbi_sock *csk, struct sk_buff *skb)
+{
+ cxgbi_skcb_tcp_seq(skb) = csk->write_seq;
+ __skb_queue_tail(&csk->write_queue, skb);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_skb_entail);
+
+void cxgbi_sock_purge_wr_queue(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb;
+
+ while ((skb = cxgbi_sock_dequeue_wr(csk)) != NULL)
+ kfree_skb(skb);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_purge_wr_queue);
+
+void cxgbi_sock_check_wr_invariants(const struct cxgbi_sock *csk)
+{
+ int pending = cxgbi_sock_count_pending_wrs(csk);
+
+ if (unlikely(csk->wr_cred + pending != csk->wr_max_cred))
+ pr_err("csk 0x%p, tid %u, credit %u + %u != %u.\n",
+ csk, csk->tid, csk->wr_cred, pending, csk->wr_max_cred);
+}
+EXPORT_SYMBOL_GPL(cxgbi_sock_check_wr_invariants);
+
+static int cxgbi_sock_send_pdus(struct cxgbi_sock *csk, struct sk_buff *skb)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct sk_buff *next;
+ int err, copied = 0;
+
+ spin_lock_bh(&csk->lock);
+
+ if (csk->state != CTP_ESTABLISHED) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, EAGAIN.\n",
+ csk, csk->state, csk->flags, csk->tid);
+ err = -EAGAIN;
+ goto out_err;
+ }
+
+ if (csk->err) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, EPIPE %d.\n",
+ csk, csk->state, csk->flags, csk->tid, csk->err);
+ err = -EPIPE;
+ goto out_err;
+ }
+
+ if (csk->write_seq - csk->snd_una >= cdev->snd_win) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "csk 0x%p,%u,0x%lx,%u, FULL %u-%u >= %u.\n",
+ csk, csk->state, csk->flags, csk->tid, csk->write_seq,
+ csk->snd_una, cdev->snd_win);
+ err = -ENOBUFS;
+ goto out_err;
+ }
+
+ while (skb) {
+ int frags = skb_shinfo(skb)->nr_frags +
+ (skb->len != skb->data_len);
+
+ if (unlikely(skb_headroom(skb) < cdev->skb_tx_rsvd)) {
+ pr_err("csk 0x%p, skb head %u < %u.\n",
+ csk, skb_headroom(skb), cdev->skb_tx_rsvd);
+ err = -EINVAL;
+ goto out_err;
+ }
+
+ if (frags >= SKB_WR_LIST_SIZE) {
+ pr_err("csk 0x%p, frags %d, %u,%u >%u.\n",
+ csk, skb_shinfo(skb)->nr_frags, skb->len,
+ skb->data_len, (uint)(SKB_WR_LIST_SIZE));
+ err = -EINVAL;
+ goto out_err;
+ }
+
+ next = skb->next;
+ skb->next = NULL;
+ cxgbi_skcb_set_flag(skb, SKCBF_TX_NEED_HDR);
+ cxgbi_sock_skb_entail(csk, skb);
+ copied += skb->len;
+ csk->write_seq += skb->len +
+ cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb));
+ skb = next;
+ }
+done:
+ if (likely(skb_queue_len(&csk->write_queue)))
+ cdev->csk_push_tx_frames(csk, 1);
+ spin_unlock_bh(&csk->lock);
+ return copied;
+
+out_err:
+ if (copied == 0 && err == -EPIPE)
+ copied = csk->err ? csk->err : -EPIPE;
+ else
+ copied = err;
+ goto done;
+}
+
+/*
+ * Direct Data Placement -
+ * Directly place the iSCSI Data-In or Data-Out PDU's payload into pre-posted
+ * final destination host-memory buffers based on the Initiator Task Tag (ITT)
+ * in Data-In or Target Task Tag (TTT) in Data-Out PDUs.
+ * The host memory address is programmed into h/w in the format of pagepod
+ * entries.
+ * The location of the pagepod entry is encoded into ddp tag which is used as
+ * the base for ITT/TTT.
+ */
+
+static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
+static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
+static unsigned char page_idx = DDP_PGIDX_MAX;
+
+static unsigned char sw_tag_idx_bits;
+static unsigned char sw_tag_age_bits;
+
+/*
+ * Direct-Data Placement page size adjustment
+ */
+static int ddp_adjust_page_table(void)
+{
+ int i;
+ unsigned int base_order, order;
+
+ if (PAGE_SIZE < (1UL << ddp_page_shift[0])) {
+ pr_info("PAGE_SIZE 0x%lx too small, min 0x%lx\n",
+ PAGE_SIZE, 1UL << ddp_page_shift[0]);
+ return -EINVAL;
+ }
+
+ base_order = get_order(1UL << ddp_page_shift[0]);
+ order = get_order(1UL << PAGE_SHIFT);
+
+ for (i = 0; i < DDP_PGIDX_MAX; i++) {
+ /* first is the kernel page size, then just doubling */
+ ddp_page_order[i] = order - base_order + i;
+ ddp_page_shift[i] = PAGE_SHIFT + i;
+ }
+ return 0;
+}
+
+static int ddp_find_page_index(unsigned long pgsz)
+{
+ int i;
+
+ for (i = 0; i < DDP_PGIDX_MAX; i++) {
+ if (pgsz == (1UL << ddp_page_shift[i]))
+ return i;
+ }
+ pr_info("ddp page size %lu not supported.\n", pgsz);
+ return DDP_PGIDX_MAX;
+}
+
+static void ddp_setup_host_page_size(void)
+{
+ if (page_idx == DDP_PGIDX_MAX) {
+ page_idx = ddp_find_page_index(PAGE_SIZE);
+
+ if (page_idx == DDP_PGIDX_MAX) {
+ pr_info("system PAGE %lu, update hw.\n", PAGE_SIZE);
+ if (ddp_adjust_page_table() < 0) {
+ pr_info("PAGE %lu, disable ddp.\n", PAGE_SIZE);
+ return;
+ }
+ page_idx = ddp_find_page_index(PAGE_SIZE);
+ }
+ pr_info("system PAGE %lu, ddp idx %u.\n", PAGE_SIZE, page_idx);
+ }
+}
+
+void cxgbi_ddp_page_size_factor(int *pgsz_factor)
+{
+ int i;
+
+ for (i = 0; i < DDP_PGIDX_MAX; i++)
+ pgsz_factor[i] = ddp_page_order[i];
+}
+EXPORT_SYMBOL_GPL(cxgbi_ddp_page_size_factor);
+
+/*
+ * DDP setup & teardown
+ */
+
+void cxgbi_ddp_ppod_set(struct cxgbi_pagepod *ppod,
+ struct cxgbi_pagepod_hdr *hdr,
+ struct cxgbi_gather_list *gl, unsigned int gidx)
+{
+ int i;
+
+ memcpy(ppod, hdr, sizeof(*hdr));
+ for (i = 0; i < (PPOD_PAGES_MAX + 1); i++, gidx++) {
+ ppod->addr[i] = gidx < gl->nelem ?
+ cpu_to_be64(gl->phys_addr[gidx]) : 0ULL;
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_ddp_ppod_set);
+
+void cxgbi_ddp_ppod_clear(struct cxgbi_pagepod *ppod)
+{
+ memset(ppod, 0, sizeof(*ppod));
+}
+EXPORT_SYMBOL_GPL(cxgbi_ddp_ppod_clear);
+
+static inline int ddp_find_unused_entries(struct cxgbi_ddp_info *ddp,
+ unsigned int start, unsigned int max,
+ unsigned int count,
+ struct cxgbi_gather_list *gl)
+{
+ unsigned int i, j, k;
+
+ /* not enough entries */
+ if ((max - start) < count) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "NOT enough entries %u+%u < %u.\n", start, count, max);
+ return -EBUSY;
+ }
+
+ max -= count;
+ spin_lock(&ddp->map_lock);
+ for (i = start; i < max;) {
+ for (j = 0, k = i; j < count; j++, k++) {
+ if (ddp->gl_map[k])
+ break;
+ }
+ if (j == count) {
+ for (j = 0, k = i; j < count; j++, k++)
+ ddp->gl_map[k] = gl;
+ spin_unlock(&ddp->map_lock);
+ return i;
+ }
+ i += j + 1;
+ }
+ spin_unlock(&ddp->map_lock);
+ log_debug(1 << CXGBI_DBG_DDP,
+ "NO suitable entries %u available.\n", count);
+ return -EBUSY;
+}
+
+static inline void ddp_unmark_entries(struct cxgbi_ddp_info *ddp,
+ int start, int count)
+{
+ spin_lock(&ddp->map_lock);
+ memset(&ddp->gl_map[start], 0,
+ count * sizeof(struct cxgbi_gather_list *));
+ spin_unlock(&ddp->map_lock);
+}
+
+static inline void ddp_gl_unmap(struct pci_dev *pdev,
+ struct cxgbi_gather_list *gl)
+{
+ int i;
+
+ for (i = 0; i < gl->nelem; i++)
+ dma_unmap_page(&pdev->dev, gl->phys_addr[i], PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+}
+
+static inline int ddp_gl_map(struct pci_dev *pdev,
+ struct cxgbi_gather_list *gl)
+{
+ int i;
+
+ for (i = 0; i < gl->nelem; i++) {
+ gl->phys_addr[i] = dma_map_page(&pdev->dev, gl->pages[i], 0,
+ PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(dma_mapping_error(&pdev->dev, gl->phys_addr[i]))) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "page %d 0x%p, 0x%p dma mapping err.\n",
+ i, gl->pages[i], pdev);
+ goto unmap;
+ }
+ }
+ return i;
+unmap:
+ if (i) {
+ unsigned int nelem = gl->nelem;
+
+ gl->nelem = i;
+ ddp_gl_unmap(pdev, gl);
+ gl->nelem = nelem;
+ }
+ return -EINVAL;
+}
+
+static void ddp_release_gl(struct cxgbi_gather_list *gl,
+ struct pci_dev *pdev)
+{
+ ddp_gl_unmap(pdev, gl);
+ kfree(gl);
+}
+
+static struct cxgbi_gather_list *ddp_make_gl(unsigned int xferlen,
+ struct scatterlist *sgl,
+ unsigned int sgcnt,
+ struct pci_dev *pdev,
+ gfp_t gfp)
+{
+ struct cxgbi_gather_list *gl;
+ struct scatterlist *sg = sgl;
+ struct page *sgpage = sg_page(sg);
+ unsigned int sglen = sg->length;
+ unsigned int sgoffset = sg->offset;
+ unsigned int npages = (xferlen + sgoffset + PAGE_SIZE - 1) >>
+ PAGE_SHIFT;
+ int i = 1, j = 0;
+
+ if (xferlen < DDP_THRESHOLD) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "xfer %u < threshold %u, no ddp.\n",
+ xferlen, DDP_THRESHOLD);
+ return NULL;
+ }
+
+ gl = kzalloc(sizeof(struct cxgbi_gather_list) +
+ npages * (sizeof(dma_addr_t) +
+ sizeof(struct page *)), gfp);
+ if (!gl) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "xfer %u, %u pages, OOM.\n", xferlen, npages);
+ return NULL;
+ }
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "xfer %u, sgl %u, gl max %u.\n", xferlen, sgcnt, npages);
+
+ gl->pages = (struct page **)&gl->phys_addr[npages];
+ gl->nelem = npages;
+ gl->length = xferlen;
+ gl->offset = sgoffset;
+ gl->pages[0] = sgpage;
+
+ for (i = 1, sg = sg_next(sgl), j = 0; i < sgcnt;
+ i++, sg = sg_next(sg)) {
+ struct page *page = sg_page(sg);
+
+ if (sgpage == page && sg->offset == sgoffset + sglen)
+ sglen += sg->length;
+ else {
+ /* make sure the sgl is fit for ddp:
+ * each has the same page size, and
+ * all of the middle pages are used completely
+ */
+ if ((j && sgoffset) || ((i != sgcnt - 1) &&
+ ((sglen + sgoffset) & ~PAGE_MASK))) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "page %d/%u, %u + %u.\n",
+ i, sgcnt, sgoffset, sglen);
+ goto error_out;
+ }
+
+ j++;
+ if (j == gl->nelem || sg->offset) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "page %d/%u, offset %u.\n",
+ j, gl->nelem, sg->offset);
+ goto error_out;
+ }
+ gl->pages[j] = page;
+ sglen = sg->length;
+ sgoffset = sg->offset;
+ sgpage = page;
+ }
+ }
+ gl->nelem = ++j;
+
+ if (ddp_gl_map(pdev, gl) < 0)
+ goto error_out;
+
+ return gl;
+
+error_out:
+ kfree(gl);
+ return NULL;
+}
+
+static void ddp_tag_release(struct cxgbi_hba *chba, u32 tag)
+{
+ struct cxgbi_device *cdev = chba->cdev;
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ u32 idx;
+
+ idx = (tag >> PPOD_IDX_SHIFT) & ddp->idx_mask;
+ if (idx < ddp->nppods) {
+ struct cxgbi_gather_list *gl = ddp->gl_map[idx];
+ unsigned int npods;
+
+ if (!gl || !gl->nelem) {
+ pr_warn("tag 0x%x, idx %u, gl 0x%p, %u.\n",
+ tag, idx, gl, gl ? gl->nelem : 0);
+ return;
+ }
+ npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
+ log_debug(1 << CXGBI_DBG_DDP,
+ "tag 0x%x, release idx %u, npods %u.\n",
+ tag, idx, npods);
+ cdev->csk_ddp_clear(chba, tag, idx, npods);
+ ddp_unmark_entries(ddp, idx, npods);
+ ddp_release_gl(gl, ddp->pdev);
+ } else
+ pr_warn("tag 0x%x, idx %u > max %u.\n", tag, idx, ddp->nppods);
+}
+
+static int ddp_tag_reserve(struct cxgbi_sock *csk, unsigned int tid,
+ u32 sw_tag, u32 *tagp, struct cxgbi_gather_list *gl,
+ gfp_t gfp)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+ struct cxgbi_tag_format *tformat = &cdev->tag_format;
+ struct cxgbi_pagepod_hdr hdr;
+ unsigned int npods;
+ int idx = -1;
+ int err = -ENOMEM;
+ u32 tag;
+
+ npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
+ if (ddp->idx_last == ddp->nppods)
+ idx = ddp_find_unused_entries(ddp, 0, ddp->nppods,
+ npods, gl);
+ else {
+ idx = ddp_find_unused_entries(ddp, ddp->idx_last + 1,
+ ddp->nppods, npods,
+ gl);
+ if (idx < 0 && ddp->idx_last >= npods) {
+ idx = ddp_find_unused_entries(ddp, 0,
+ min(ddp->idx_last + npods, ddp->nppods),
+ npods, gl);
+ }
+ }
+ if (idx < 0) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "xferlen %u, gl %u, npods %u NO DDP.\n",
+ gl->length, gl->nelem, npods);
+ return idx;
+ }
+
+ if (cdev->csk_ddp_alloc_gl_skb) {
+ err = cdev->csk_ddp_alloc_gl_skb(ddp, idx, npods, gfp);
+ if (err < 0)
+ goto unmark_entries;
+ }
+
+ tag = cxgbi_ddp_tag_base(tformat, sw_tag);
+ tag |= idx << PPOD_IDX_SHIFT;
+
+ hdr.rsvd = 0;
+ hdr.vld_tid = htonl(PPOD_VALID_FLAG | PPOD_TID(tid));
+ hdr.pgsz_tag_clr = htonl(tag & ddp->rsvd_tag_mask);
+ hdr.max_offset = htonl(gl->length);
+ hdr.page_offset = htonl(gl->offset);
+
+ err = cdev->csk_ddp_set(csk, &hdr, idx, npods, gl);
+ if (err < 0) {
+ if (cdev->csk_ddp_free_gl_skb)
+ cdev->csk_ddp_free_gl_skb(ddp, idx, npods);
+ goto unmark_entries;
+ }
+
+ ddp->idx_last = idx;
+ log_debug(1 << CXGBI_DBG_DDP,
+ "xfer %u, gl %u,%u, tid 0x%x, tag 0x%x->0x%x(%u,%u).\n",
+ gl->length, gl->nelem, gl->offset, tid, sw_tag, tag, idx,
+ npods);
+ *tagp = tag;
+ return 0;
+
+unmark_entries:
+ ddp_unmark_entries(ddp, idx, npods);
+ return err;
+}
+
+int cxgbi_ddp_reserve(struct cxgbi_sock *csk, unsigned int *tagp,
+ unsigned int sw_tag, unsigned int xferlen,
+ struct scatterlist *sgl, unsigned int sgcnt, gfp_t gfp)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct cxgbi_tag_format *tformat = &cdev->tag_format;
+ struct cxgbi_gather_list *gl;
+ int err;
+
+ if (page_idx >= DDP_PGIDX_MAX || !cdev->ddp ||
+ xferlen < DDP_THRESHOLD) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "pgidx %u, xfer %u, NO ddp.\n", page_idx, xferlen);
+ return -EINVAL;
+ }
+
+ if (!cxgbi_sw_tag_usable(tformat, sw_tag)) {
+ log_debug(1 << CXGBI_DBG_DDP,
+ "sw_tag 0x%x NOT usable.\n", sw_tag);
+ return -EINVAL;
+ }
+
+ gl = ddp_make_gl(xferlen, sgl, sgcnt, cdev->pdev, gfp);
+ if (!gl)
+ return -ENOMEM;
+
+ err = ddp_tag_reserve(csk, csk->tid, sw_tag, tagp, gl, gfp);
+ if (err < 0)
+ ddp_release_gl(gl, cdev->pdev);
+
+ return err;
+}
+
+static void ddp_destroy(struct kref *kref)
+{
+ struct cxgbi_ddp_info *ddp = container_of(kref,
+ struct cxgbi_ddp_info,
+ refcnt);
+ struct cxgbi_device *cdev = ddp->cdev;
+ int i = 0;
+
+ pr_info("kref 0, destroy ddp 0x%p, cdev 0x%p.\n", ddp, cdev);
+
+ while (i < ddp->nppods) {
+ struct cxgbi_gather_list *gl = ddp->gl_map[i];
+
+ if (gl) {
+ int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
+ >> PPOD_PAGES_SHIFT;
+ pr_info("cdev 0x%p, ddp %d + %d.\n", cdev, i, npods);
+ kfree(gl);
+ if (cdev->csk_ddp_free_gl_skb)
+ cdev->csk_ddp_free_gl_skb(ddp, i, npods);
+ i += npods;
+ } else
+ i++;
+ }
+ cxgbi_free_big_mem(ddp);
+}
+
+int cxgbi_ddp_cleanup(struct cxgbi_device *cdev)
+{
+ struct cxgbi_ddp_info *ddp = cdev->ddp;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "cdev 0x%p, release ddp 0x%p.\n", cdev, ddp);
+ cdev->ddp = NULL;
+ if (ddp)
+ return kref_put(&ddp->refcnt, ddp_destroy);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_ddp_cleanup);
+
+int cxgbi_ddp_init(struct cxgbi_device *cdev,
+ unsigned int llimit, unsigned int ulimit,
+ unsigned int max_txsz, unsigned int max_rxsz)
+{
+ struct cxgbi_ddp_info *ddp;
+ unsigned int ppmax, bits;
+
+ ppmax = (ulimit - llimit + 1) >> PPOD_SIZE_SHIFT;
+ bits = __ilog2_u32(ppmax) + 1;
+ if (bits > PPOD_IDX_MAX_SIZE)
+ bits = PPOD_IDX_MAX_SIZE;
+ ppmax = (1 << (bits - 1)) - 1;
+
+ ddp = cxgbi_alloc_big_mem(sizeof(struct cxgbi_ddp_info) +
+ ppmax * (sizeof(struct cxgbi_gather_list *) +
+ sizeof(struct sk_buff *)),
+ GFP_KERNEL);
+ if (!ddp) {
+ pr_warn("cdev 0x%p, ddp ppmax %u OOM.\n", cdev, ppmax);
+ return -ENOMEM;
+ }
+ ddp->gl_map = (struct cxgbi_gather_list **)(ddp + 1);
+ ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
+ ppmax * sizeof(struct cxgbi_gather_list *));
+ cdev->ddp = ddp;
+
+ spin_lock_init(&ddp->map_lock);
+ kref_init(&ddp->refcnt);
+
+ ddp->cdev = cdev;
+ ddp->pdev = cdev->pdev;
+ ddp->llimit = llimit;
+ ddp->ulimit = ulimit;
+ ddp->max_txsz = min_t(unsigned int, max_txsz, ULP2_MAX_PKT_SIZE);
+ ddp->max_rxsz = min_t(unsigned int, max_rxsz, ULP2_MAX_PKT_SIZE);
+ ddp->nppods = ppmax;
+ ddp->idx_last = ppmax;
+ ddp->idx_bits = bits;
+ ddp->idx_mask = (1 << bits) - 1;
+ ddp->rsvd_tag_mask = (1 << (bits + PPOD_IDX_SHIFT)) - 1;
+
+ cdev->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
+ cdev->tag_format.rsvd_bits = ddp->idx_bits;
+ cdev->tag_format.rsvd_shift = PPOD_IDX_SHIFT;
+ cdev->tag_format.rsvd_mask = (1 << cdev->tag_format.rsvd_bits) - 1;
+
+ pr_info("%s tag format, sw %u, rsvd %u,%u, mask 0x%x.\n",
+ cdev->ports[0]->name, cdev->tag_format.sw_bits,
+ cdev->tag_format.rsvd_bits, cdev->tag_format.rsvd_shift,
+ cdev->tag_format.rsvd_mask);
+
+ cdev->tx_max_size = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ cdev->rx_max_size = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "%s max payload size: %u/%u, %u/%u.\n",
+ cdev->ports[0]->name, cdev->tx_max_size, ddp->max_txsz,
+ cdev->rx_max_size, ddp->max_rxsz);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_ddp_init);
+
+/*
+ * APIs interacting with open-iscsi libraries
+ */
+
+static unsigned char padding[4];
+
+static void task_release_itt(struct iscsi_task *task, itt_t hdr_itt)
+{
+ struct scsi_cmnd *sc = task->sc;
+ struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_hba *chba = cconn->chba;
+ struct cxgbi_tag_format *tformat = &chba->cdev->tag_format;
+ u32 tag = ntohl((__force u32)hdr_itt);
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "cdev 0x%p, release tag 0x%x.\n", chba->cdev, tag);
+ if (sc &&
+ (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE) &&
+ cxgbi_is_ddp_tag(tformat, tag))
+ ddp_tag_release(chba, tag);
+}
+
+static int task_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt)
+{
+ struct scsi_cmnd *sc = task->sc;
+ struct iscsi_conn *conn = task->conn;
+ struct iscsi_session *sess = conn->session;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_hba *chba = cconn->chba;
+ struct cxgbi_tag_format *tformat = &chba->cdev->tag_format;
+ u32 sw_tag = (sess->age << cconn->task_idx_bits) | task->itt;
+ u32 tag = 0;
+ int err = -EINVAL;
+
+ if (sc &&
+ (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE)) {
+ err = cxgbi_ddp_reserve(cconn->cep->csk, &tag, sw_tag,
+ scsi_in(sc)->length,
+ scsi_in(sc)->table.sgl,
+ scsi_in(sc)->table.nents,
+ GFP_ATOMIC);
+ if (err < 0)
+ log_debug(1 << CXGBI_DBG_DDP,
+ "csk 0x%p, R task 0x%p, %u,%u, no ddp.\n",
+ cconn->cep->csk, task, scsi_in(sc)->length,
+ scsi_in(sc)->table.nents);
+ }
+
+ if (err < 0)
+ tag = cxgbi_set_non_ddp_tag(tformat, sw_tag);
+ /* the itt need to sent in big-endian order */
+ *hdr_itt = (__force itt_t)htonl(tag);
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "cdev 0x%p, task 0x%p, 0x%x(0x%x,0x%x)->0x%x/0x%x.\n",
+ chba->cdev, task, sw_tag, task->itt, sess->age, tag, *hdr_itt);
+ return 0;
+}
+
+void cxgbi_parse_pdu_itt(struct iscsi_conn *conn, itt_t itt, int *idx, int *age)
+{
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_device *cdev = cconn->chba->cdev;
+ u32 tag = ntohl((__force u32) itt);
+ u32 sw_bits;
+
+ sw_bits = cxgbi_tag_nonrsvd_bits(&cdev->tag_format, tag);
+ if (idx)
+ *idx = sw_bits & ((1 << cconn->task_idx_bits) - 1);
+ if (age)
+ *age = (sw_bits >> cconn->task_idx_bits) & ISCSI_AGE_MASK;
+
+ log_debug(1 << CXGBI_DBG_DDP,
+ "cdev 0x%p, tag 0x%x/0x%x, -> 0x%x(0x%x,0x%x).\n",
+ cdev, tag, itt, sw_bits, idx ? *idx : 0xFFFFF,
+ age ? *age : 0xFF);
+}
+EXPORT_SYMBOL_GPL(cxgbi_parse_pdu_itt);
+
+void cxgbi_conn_tx_open(struct cxgbi_sock *csk)
+{
+ struct iscsi_conn *conn = csk->user_data;
+
+ if (conn) {
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p, cid %d.\n", csk, conn->id);
+ iscsi_conn_queue_work(conn);
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_conn_tx_open);
+
+/*
+ * pdu receive, interact with libiscsi_tcp
+ */
+static inline int read_pdu_skb(struct iscsi_conn *conn,
+ struct sk_buff *skb,
+ unsigned int offset,
+ int offloaded)
+{
+ int status = 0;
+ int bytes_read;
+
+ bytes_read = iscsi_tcp_recv_skb(conn, skb, offset, offloaded, &status);
+ switch (status) {
+ case ISCSI_TCP_CONN_ERR:
+ pr_info("skb 0x%p, off %u, %d, TCP_ERR.\n",
+ skb, offset, offloaded);
+ return -EIO;
+ case ISCSI_TCP_SUSPENDED:
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "skb 0x%p, off %u, %d, TCP_SUSPEND, rc %d.\n",
+ skb, offset, offloaded, bytes_read);
+ /* no transfer - just have caller flush queue */
+ return bytes_read;
+ case ISCSI_TCP_SKB_DONE:
+ pr_info("skb 0x%p, off %u, %d, TCP_SKB_DONE.\n",
+ skb, offset, offloaded);
+ /*
+ * pdus should always fit in the skb and we should get
+ * segment done notifcation.
+ */
+ iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu or skb.");
+ return -EFAULT;
+ case ISCSI_TCP_SEGMENT_DONE:
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "skb 0x%p, off %u, %d, TCP_SEG_DONE, rc %d.\n",
+ skb, offset, offloaded, bytes_read);
+ return bytes_read;
+ default:
+ pr_info("skb 0x%p, off %u, %d, invalid status %d.\n",
+ skb, offset, offloaded, status);
+ return -EINVAL;
+ }
+}
+
+static int skb_read_pdu_bhs(struct iscsi_conn *conn, struct sk_buff *skb)
+{
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "conn 0x%p, skb 0x%p, len %u, flag 0x%lx.\n",
+ conn, skb, skb->len, cxgbi_skcb_flags(skb));
+
+ if (!iscsi_tcp_recv_segment_is_hdr(tcp_conn)) {
+ pr_info("conn 0x%p, skb 0x%p, not hdr.\n", conn, skb);
+ iscsi_conn_failure(conn, ISCSI_ERR_PROTO);
+ return -EIO;
+ }
+
+ if (conn->hdrdgst_en &&
+ cxgbi_skcb_test_flag(skb, SKCBF_RX_HCRC_ERR)) {
+ pr_info("conn 0x%p, skb 0x%p, hcrc.\n", conn, skb);
+ iscsi_conn_failure(conn, ISCSI_ERR_HDR_DGST);
+ return -EIO;
+ }
+
+ return read_pdu_skb(conn, skb, 0, 0);
+}
+
+static int skb_read_pdu_data(struct iscsi_conn *conn, struct sk_buff *lskb,
+ struct sk_buff *skb, unsigned int offset)
+{
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ bool offloaded = 0;
+ int opcode = tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK;
+
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "conn 0x%p, skb 0x%p, len %u, flag 0x%lx.\n",
+ conn, skb, skb->len, cxgbi_skcb_flags(skb));
+
+ if (conn->datadgst_en &&
+ cxgbi_skcb_test_flag(lskb, SKCBF_RX_DCRC_ERR)) {
+ pr_info("conn 0x%p, skb 0x%p, dcrc 0x%lx.\n",
+ conn, lskb, cxgbi_skcb_flags(lskb));
+ iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+ return -EIO;
+ }
+
+ if (iscsi_tcp_recv_segment_is_hdr(tcp_conn))
+ return 0;
+
+ /* coalesced, add header digest length */
+ if (lskb == skb && conn->hdrdgst_en)
+ offset += ISCSI_DIGEST_SIZE;
+
+ if (cxgbi_skcb_test_flag(lskb, SKCBF_RX_DATA_DDPD))
+ offloaded = 1;
+
+ if (opcode == ISCSI_OP_SCSI_DATA_IN)
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "skb 0x%p, op 0x%x, itt 0x%x, %u %s ddp'ed.\n",
+ skb, opcode, ntohl(tcp_conn->in.hdr->itt),
+ tcp_conn->in.datalen, offloaded ? "is" : "not");
+
+ return read_pdu_skb(conn, skb, offset, offloaded);
+}
+
+static void csk_return_rx_credits(struct cxgbi_sock *csk, int copied)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ int must_send;
+ u32 credits;
+
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p,%u,0x%lu,%u, seq %u, wup %u, thre %u, %u.\n",
+ csk, csk->state, csk->flags, csk->tid, csk->copied_seq,
+ csk->rcv_wup, cdev->rx_credit_thres,
+ cdev->rcv_win);
+
+ if (csk->state != CTP_ESTABLISHED)
+ return;
+
+ credits = csk->copied_seq - csk->rcv_wup;
+ if (unlikely(!credits))
+ return;
+ if (unlikely(cdev->rx_credit_thres == 0))
+ return;
+
+ must_send = credits + 16384 >= cdev->rcv_win;
+ if (must_send || credits >= cdev->rx_credit_thres)
+ csk->rcv_wup += cdev->csk_send_rx_credits(csk, credits);
+}
+
+void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
+{
+ struct cxgbi_device *cdev = csk->cdev;
+ struct iscsi_conn *conn = csk->user_data;
+ struct sk_buff *skb;
+ unsigned int read = 0;
+ int err = 0;
+
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, conn 0x%p.\n", csk, conn);
+
+ if (unlikely(!conn || conn->suspend_rx)) {
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
+ csk, conn, conn ? conn->id : 0xFF,
+ conn ? conn->suspend_rx : 0xFF);
+ read_unlock(&csk->callback_lock);
+ return;
+ }
+
+ while (!err) {
+ read_lock(&csk->callback_lock);
+ skb = skb_peek(&csk->receive_queue);
+ if (!skb ||
+ !(cxgbi_skcb_test_flag(skb, SKCBF_RX_STATUS))) {
+ if (skb)
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "skb 0x%p, NOT ready 0x%lx.\n",
+ skb, cxgbi_skcb_flags(skb));
+ read_unlock(&csk->callback_lock);
+ break;
+ }
+ __skb_unlink(skb, &csk->receive_queue);
+ read_unlock(&csk->callback_lock);
+
+ read += cxgbi_skcb_rx_pdulen(skb);
+ log_debug(1 << CXGBI_DBG_PDU_RX,
+ "csk 0x%p, skb 0x%p,%u,f 0x%lx, pdu len %u.\n",
+ csk, skb, skb->len, cxgbi_skcb_flags(skb),
+ cxgbi_skcb_rx_pdulen(skb));
+
+ if (cxgbi_skcb_test_flag(skb, SKCBF_RX_COALESCED)) {
+ err = skb_read_pdu_bhs(conn, skb);
+ if (err < 0)
+ break;
+ err = skb_read_pdu_data(conn, skb, skb,
+ err + cdev->skb_rx_extra);
+ } else {
+ err = skb_read_pdu_bhs(conn, skb);
+ if (err < 0)
+ break;
+ if (cxgbi_skcb_test_flag(skb, SKCBF_RX_DATA)) {
+ struct sk_buff *dskb;
+
+ read_lock(&csk->callback_lock);
+ dskb = skb_peek(&csk->receive_queue);
+ if (!dskb) {
+ read_unlock(&csk->callback_lock);
+ pr_err("csk 0x%p, NO data.\n", csk);
+ err = -EAGAIN;
+ break;
+ }
+ __skb_unlink(dskb, &csk->receive_queue);
+ read_unlock(&csk->callback_lock);
+
+ err = skb_read_pdu_data(conn, skb, dskb, 0);
+ __kfree_skb(dskb);
+ } else
+ err = skb_read_pdu_data(conn, skb, skb, 0);
+ }
+ if (err < 0)
+ break;
+
+ __kfree_skb(skb);
+ }
+
+ log_debug(1 << CXGBI_DBG_PDU_RX, "csk 0x%p, read %u.\n", csk, read);
+ if (read) {
+ csk->copied_seq += read;
+ csk_return_rx_credits(csk, read);
+ conn->rxdata_octets += read;
+ }
+
+ if (err < 0) {
+ pr_info("csk 0x%p, 0x%p, rx failed %d.\n", csk, conn, err);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_conn_pdu_ready);
+
+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) {
+ pr_warn("sg %d NULL, len %u/%u.\n",
+ i, 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) {
+ pr_warn("too many pages %u, dlen %u.\n",
+ 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 cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
+{
+ struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_device *cdev = cconn->chba->cdev;
+ struct iscsi_conn *conn = task->conn;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgbi_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+ struct scsi_cmnd *sc = task->sc;
+ int headroom = SKB_TX_ISCSI_PDU_HEADER_MAX;
+
+ tcp_task->dd_data = tdata;
+ task->hdr = NULL;
+
+ if (SKB_MAX_HEAD(cdev->skb_tx_rsvd) > (512 * MAX_SKB_FRAGS) &&
+ (opcode == ISCSI_OP_SCSI_DATA_OUT ||
+ (opcode == ISCSI_OP_SCSI_CMD &&
+ (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
+ /* data could goes into skb head */
+ headroom += min_t(unsigned int,
+ SKB_MAX_HEAD(cdev->skb_tx_rsvd),
+ conn->max_xmit_dlength);
+
+ tdata->skb = alloc_skb(cdev->skb_tx_rsvd + headroom, GFP_ATOMIC);
+ if (!tdata->skb) {
+ pr_warn("alloc skb %u+%u, opcode 0x%x failed.\n",
+ cdev->skb_tx_rsvd, headroom, opcode);
+ return -ENOMEM;
+ }
+
+ skb_reserve(tdata->skb, cdev->skb_tx_rsvd);
+ task->hdr = (struct iscsi_hdr *)tdata->skb->data;
+ task->hdr_max = SKB_TX_ISCSI_PDU_HEADER_MAX; /* BHS + AHS */
+
+ /* data_out uses scsi_cmd's itt */
+ if (opcode != ISCSI_OP_SCSI_DATA_OUT)
+ task_reserve_itt(task, &task->hdr->itt);
+
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_PDU_TX,
+ "task 0x%p, op 0x%x, skb 0x%p,%u+%u/%u, itt 0x%x.\n",
+ task, opcode, tdata->skb, cdev->skb_tx_rsvd, headroom,
+ conn->max_xmit_dlength, ntohl(task->hdr->itt));
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_conn_alloc_pdu);
+
+static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc)
+{
+ u8 submode = 0;
+
+ if (hcrc)
+ submode |= 1;
+ if (dcrc)
+ submode |= 2;
+ cxgbi_skcb_ulp_mode(skb) = (ULP2_MODE_ISCSI << 4) | submode;
+}
+
+int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
+ unsigned int count)
+{
+ struct iscsi_conn *conn = task->conn;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgbi_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
+ unsigned int datalen = count;
+ int i, padlen = iscsi_padding(count);
+ struct page *pg;
+
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_PDU_TX,
+ "task 0x%p,0x%p, skb 0x%p, 0x%x,0x%x,0x%x, %u+%u.\n",
+ task, task->sc, skb, (*skb->data) & ISCSI_OPCODE_MASK,
+ ntohl(task->cmdsn), ntohl(task->hdr->itt), offset, count);
+
+ skb_put(skb, task->hdr_len);
+ tx_skb_setmode(skb, conn->hdrdgst_en, datalen ? conn->datadgst_en : 0);
+ if (!count)
+ return 0;
+
+ if (task->sc) {
+ 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) {
+ pr_warn("tpdu, sgl %u, bad offset %u/%u.\n",
+ sdb->table.nents, tdata->offset, sdb->length);
+ return err;
+ }
+ err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count,
+ tdata->frags, MAX_PDU_FRAGS);
+ if (err < 0) {
+ pr_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);
+ }
+ if (padlen) {
+ memset(dst, 0, padlen);
+ padlen = 0;
+ }
+ 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);
+
+ 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;
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
+ virt_to_page(padding), offset_in_page(padding),
+ padlen);
+
+ skb->data_len += padlen;
+ skb->truesize += padlen;
+ skb->len += padlen;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_conn_init_pdu);
+
+int cxgbi_conn_xmit_pdu(struct iscsi_task *task)
+{
+ struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgbi_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
+ unsigned int datalen;
+ int err;
+
+ if (!skb) {
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_PDU_TX,
+ "task 0x%p, skb NULL.\n", task);
+ return 0;
+ }
+
+ datalen = skb->data_len;
+ tdata->skb = NULL;
+ err = cxgbi_sock_send_pdus(cconn->cep->csk, skb);
+ if (err > 0) {
+ int pdulen = err;
+
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "task 0x%p,0x%p, skb 0x%p, len %u/%u, rv %d.\n",
+ task, task->sc, skb, skb->len, skb->data_len, err);
+
+ if (task->conn->hdrdgst_en)
+ pdulen += ISCSI_DIGEST_SIZE;
+
+ if (datalen && task->conn->datadgst_en)
+ pdulen += ISCSI_DIGEST_SIZE;
+
+ task->conn->txdata_octets += pdulen;
+ return 0;
+ }
+
+ if (err == -EAGAIN || err == -ENOBUFS) {
+ log_debug(1 << CXGBI_DBG_PDU_TX,
+ "task 0x%p, skb 0x%p, len %u/%u, %d EAGAIN.\n",
+ task, skb, skb->len, skb->data_len, err);
+ /* reset skb to send when we are called again */
+ tdata->skb = skb;
+ return err;
+ }
+
+ kfree_skb(skb);
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_PDU_TX,
+ "itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n",
+ task->itt, skb, skb->len, skb->data_len, err);
+ iscsi_conn_printk(KERN_ERR, task->conn, "xmit err %d.\n", err);
+ iscsi_conn_failure(task->conn, ISCSI_ERR_XMIT_FAILED);
+ return err;
+}
+EXPORT_SYMBOL_GPL(cxgbi_conn_xmit_pdu);
+
+void cxgbi_cleanup_task(struct iscsi_task *task)
+{
+ struct cxgbi_task_data *tdata = task->dd_data +
+ sizeof(struct iscsi_tcp_task);
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "task 0x%p, skb 0x%p, itt 0x%x.\n",
+ task, tdata->skb, task->hdr_itt);
+
+ /* never reached the xmit task callout */
+ if (tdata->skb)
+ __kfree_skb(tdata->skb);
+ memset(tdata, 0, sizeof(*tdata));
+
+ task_release_itt(task, task->hdr_itt);
+ iscsi_tcp_cleanup_task(task);
+}
+EXPORT_SYMBOL_GPL(cxgbi_cleanup_task);
+
+void cxgbi_get_conn_stats(struct iscsi_cls_conn *cls_conn,
+ struct iscsi_stats *stats)
+{
+ struct iscsi_conn *conn = cls_conn->dd_data;
+
+ stats->txdata_octets = conn->txdata_octets;
+ stats->rxdata_octets = conn->rxdata_octets;
+ stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
+ stats->dataout_pdus = conn->dataout_pdus_cnt;
+ stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
+ stats->datain_pdus = conn->datain_pdus_cnt;
+ stats->r2t_pdus = conn->r2t_pdus_cnt;
+ stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
+ stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
+ stats->digest_err = 0;
+ stats->timeout_err = 0;
+ stats->custom_length = 1;
+ strcpy(stats->custom[0].desc, "eh_abort_cnt");
+ stats->custom[0].value = conn->eh_abort_cnt;
+}
+EXPORT_SYMBOL_GPL(cxgbi_get_conn_stats);
+
+static int cxgbi_conn_max_xmit_dlength(struct iscsi_conn *conn)
+{
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_device *cdev = cconn->chba->cdev;
+ unsigned int headroom = SKB_MAX_HEAD(cdev->skb_tx_rsvd);
+ unsigned int max_def = 512 * MAX_SKB_FRAGS;
+ unsigned int max = max(max_def, headroom);
+
+ max = min(cconn->chba->cdev->tx_max_size, max);
+ if (conn->max_xmit_dlength)
+ conn->max_xmit_dlength = min(conn->max_xmit_dlength, max);
+ else
+ conn->max_xmit_dlength = max;
+ cxgbi_align_pdu_size(conn->max_xmit_dlength);
+
+ return 0;
+}
+
+static int cxgbi_conn_max_recv_dlength(struct iscsi_conn *conn)
+{
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ unsigned int max = cconn->chba->cdev->rx_max_size;
+
+ cxgbi_align_pdu_size(max);
+
+ if (conn->max_recv_dlength) {
+ if (conn->max_recv_dlength > max) {
+ pr_err("MaxRecvDataSegmentLength %u > %u.\n",
+ conn->max_recv_dlength, max);
+ return -EINVAL;
+ }
+ conn->max_recv_dlength = min(conn->max_recv_dlength, max);
+ cxgbi_align_pdu_size(conn->max_recv_dlength);
+ } else
+ conn->max_recv_dlength = max;
+
+ return 0;
+}
+
+int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn,
+ enum iscsi_param param, char *buf, int buflen)
+{
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_session *session = conn->session;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct cxgbi_sock *csk = cconn->cep->csk;
+ int value, err = 0;
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "cls_conn 0x%p, param %d, buf(%d) %s.\n",
+ cls_conn, param, buflen, buf);
+
+ switch (param) {
+ case ISCSI_PARAM_HDRDGST_EN:
+ err = iscsi_set_param(cls_conn, param, buf, buflen);
+ if (!err && conn->hdrdgst_en)
+ err = csk->cdev->csk_ddp_setup_digest(csk, csk->tid,
+ conn->hdrdgst_en,
+ conn->datadgst_en, 0);
+ break;
+ case ISCSI_PARAM_DATADGST_EN:
+ err = iscsi_set_param(cls_conn, param, buf, buflen);
+ if (!err && conn->datadgst_en)
+ err = csk->cdev->csk_ddp_setup_digest(csk, csk->tid,
+ conn->hdrdgst_en,
+ conn->datadgst_en, 0);
+ break;
+ case ISCSI_PARAM_MAX_R2T:
+ sscanf(buf, "%d", &value);
+ if (value <= 0 || !is_power_of_2(value))
+ return -EINVAL;
+ if (session->max_r2t == value)
+ break;
+ iscsi_tcp_r2tpool_free(session);
+ err = iscsi_set_param(cls_conn, param, buf, buflen);
+ if (!err && iscsi_tcp_r2tpool_alloc(session))
+ return -ENOMEM;
+ case ISCSI_PARAM_MAX_RECV_DLENGTH:
+ err = iscsi_set_param(cls_conn, param, buf, buflen);
+ if (!err)
+ err = cxgbi_conn_max_recv_dlength(conn);
+ break;
+ case ISCSI_PARAM_MAX_XMIT_DLENGTH:
+ err = iscsi_set_param(cls_conn, param, buf, buflen);
+ if (!err)
+ err = cxgbi_conn_max_xmit_dlength(conn);
+ break;
+ default:
+ return iscsi_set_param(cls_conn, param, buf, buflen);
+ }
+ return err;
+}
+EXPORT_SYMBOL_GPL(cxgbi_set_conn_param);
+
+int cxgbi_get_conn_param(struct iscsi_cls_conn *cls_conn,
+ enum iscsi_param param, char *buf)
+{
+ struct iscsi_conn *iconn = cls_conn->dd_data;
+ int len;
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "cls_conn 0x%p, param %d.\n", cls_conn, param);
+
+ switch (param) {
+ case ISCSI_PARAM_CONN_PORT:
+ spin_lock_bh(&iconn->session->lock);
+ len = sprintf(buf, "%hu\n", iconn->portal_port);
+ spin_unlock_bh(&iconn->session->lock);
+ break;
+ case ISCSI_PARAM_CONN_ADDRESS:
+ spin_lock_bh(&iconn->session->lock);
+ len = sprintf(buf, "%s\n", iconn->portal_address);
+ spin_unlock_bh(&iconn->session->lock);
+ break;
+ default:
+ return iscsi_conn_get_param(cls_conn, param, buf);
+ }
+ return len;
+}
+EXPORT_SYMBOL_GPL(cxgbi_get_conn_param);
+
+struct iscsi_cls_conn *
+cxgbi_create_conn(struct iscsi_cls_session *cls_session, u32 cid)
+{
+ struct iscsi_cls_conn *cls_conn;
+ struct iscsi_conn *conn;
+ struct iscsi_tcp_conn *tcp_conn;
+ struct cxgbi_conn *cconn;
+
+ cls_conn = iscsi_tcp_conn_setup(cls_session, sizeof(*cconn), cid);
+ if (!cls_conn)
+ return NULL;
+
+ conn = cls_conn->dd_data;
+ tcp_conn = conn->dd_data;
+ cconn = tcp_conn->dd_data;
+ cconn->iconn = conn;
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "cid %u(0x%x), cls 0x%p,0x%p, conn 0x%p,0x%p,0x%p.\n",
+ cid, cid, cls_session, cls_conn, conn, tcp_conn, cconn);
+
+ return cls_conn;
+}
+EXPORT_SYMBOL_GPL(cxgbi_create_conn);
+
+int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
+ struct iscsi_cls_conn *cls_conn,
+ u64 transport_eph, int is_leading)
+{
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct cxgbi_conn *cconn = tcp_conn->dd_data;
+ struct iscsi_endpoint *ep;
+ struct cxgbi_endpoint *cep;
+ struct cxgbi_sock *csk;
+ int err;
+
+ ep = iscsi_lookup_endpoint(transport_eph);
+ if (!ep)
+ return -EINVAL;
+
+ /* setup ddp pagesize */
+ cep = ep->dd_data;
+ csk = cep->csk;
+ err = csk->cdev->csk_ddp_setup_pgidx(csk, csk->tid, page_idx, 0);
+ if (err < 0)
+ return err;
+
+ err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
+ if (err)
+ return -EINVAL;
+
+ /* calculate the tag idx bits needed for this conn based on cmds_max */
+ cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
+
+ write_lock(&csk->callback_lock);
+ csk->user_data = conn;
+ cconn->chba = cep->chba;
+ cconn->cep = cep;
+ cep->cconn = cconn;
+ write_unlock(&csk->callback_lock);
+
+ cxgbi_conn_max_xmit_dlength(conn);
+ cxgbi_conn_max_recv_dlength(conn);
+
+ spin_lock_bh(&conn->session->lock);
+ sprintf(conn->portal_address, "%pI4", &csk->daddr.sin_addr.s_addr);
+ conn->portal_port = ntohs(csk->daddr.sin_port);
+ spin_unlock_bh(&conn->session->lock);
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "cls 0x%p,0x%p, ep 0x%p, cconn 0x%p, csk 0x%p.\n",
+ cls_session, cls_conn, ep, cconn, csk);
+ /* init recv engine */
+ iscsi_tcp_hdr_recv_prep(tcp_conn);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_bind_conn);
+
+struct iscsi_cls_session *cxgbi_create_session(struct iscsi_endpoint *ep,
+ u16 cmds_max, u16 qdepth,
+ u32 initial_cmdsn)
+{
+ struct cxgbi_endpoint *cep;
+ struct cxgbi_hba *chba;
+ struct Scsi_Host *shost;
+ struct iscsi_cls_session *cls_session;
+ struct iscsi_session *session;
+
+ if (!ep) {
+ pr_err("missing endpoint.\n");
+ return NULL;
+ }
+
+ cep = ep->dd_data;
+ chba = cep->chba;
+ shost = chba->shost;
+
+ BUG_ON(chba != iscsi_host_priv(shost));
+
+ cls_session = iscsi_session_setup(chba->cdev->itp, shost,
+ cmds_max, 0,
+ sizeof(struct iscsi_tcp_task) +
+ sizeof(struct cxgbi_task_data),
+ initial_cmdsn, ISCSI_MAX_TARGET);
+ if (!cls_session)
+ return NULL;
+
+ session = cls_session->dd_data;
+ if (iscsi_tcp_r2tpool_alloc(session))
+ goto remove_session;
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "ep 0x%p, cls sess 0x%p.\n", ep, cls_session);
+ return cls_session;
+
+remove_session:
+ iscsi_session_teardown(cls_session);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(cxgbi_create_session);
+
+void cxgbi_destroy_session(struct iscsi_cls_session *cls_session)
+{
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "cls sess 0x%p.\n", cls_session);
+
+ iscsi_tcp_r2tpool_free(cls_session->dd_data);
+ iscsi_session_teardown(cls_session);
+}
+EXPORT_SYMBOL_GPL(cxgbi_destroy_session);
+
+int cxgbi_set_host_param(struct Scsi_Host *shost, enum iscsi_host_param param,
+ char *buf, int buflen)
+{
+ struct cxgbi_hba *chba = iscsi_host_priv(shost);
+
+ if (!chba->ndev) {
+ shost_printk(KERN_ERR, shost, "Could not get host param. "
+ "netdev for host not set.\n");
+ return -ENODEV;
+ }
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "shost 0x%p, hba 0x%p,%s, param %d, buf(%d) %s.\n",
+ shost, chba, chba->ndev->name, param, buflen, buf);
+
+ switch (param) {
+ case ISCSI_HOST_PARAM_IPADDRESS:
+ {
+ __be32 addr = in_aton(buf);
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "hba %s, req. ipv4 %pI4.\n", chba->ndev->name, &addr);
+ cxgbi_set_iscsi_ipv4(chba, addr);
+ return 0;
+ }
+ case ISCSI_HOST_PARAM_HWADDRESS:
+ case ISCSI_HOST_PARAM_NETDEV_NAME:
+ return 0;
+ default:
+ return iscsi_host_set_param(shost, param, buf, buflen);
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_set_host_param);
+
+int cxgbi_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param,
+ char *buf)
+{
+ struct cxgbi_hba *chba = iscsi_host_priv(shost);
+ int len = 0;
+
+ if (!chba->ndev) {
+ shost_printk(KERN_ERR, shost, "Could not get host param. "
+ "netdev for host not set.\n");
+ return -ENODEV;
+ }
+
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "shost 0x%p, hba 0x%p,%s, param %d.\n",
+ shost, chba, chba->ndev->name, param);
+
+ switch (param) {
+ case ISCSI_HOST_PARAM_HWADDRESS:
+ len = sysfs_format_mac(buf, chba->ndev->dev_addr, 6);
+ break;
+ case ISCSI_HOST_PARAM_NETDEV_NAME:
+ len = sprintf(buf, "%s\n", chba->ndev->name);
+ break;
+ case ISCSI_HOST_PARAM_IPADDRESS:
+ {
+ __be32 addr;
+
+ addr = cxgbi_get_iscsi_ipv4(chba);
+ len = sprintf(buf, "%pI4", &addr);
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "hba %s, ipv4 %pI4.\n", chba->ndev->name, &addr);
+ break;
+ }
+ default:
+ return iscsi_host_get_param(shost, param, buf);
+ }
+
+ return len;
+}
+EXPORT_SYMBOL_GPL(cxgbi_get_host_param);
+
+struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost,
+ struct sockaddr *dst_addr,
+ int non_blocking)
+{
+ struct iscsi_endpoint *ep;
+ struct cxgbi_endpoint *cep;
+ struct cxgbi_hba *hba = NULL;
+ struct cxgbi_sock *csk;
+ int err = -EINVAL;
+
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_SOCK,
+ "shost 0x%p, non_blocking %d, dst_addr 0x%p.\n",
+ shost, non_blocking, dst_addr);
+
+ if (shost) {
+ hba = iscsi_host_priv(shost);
+ if (!hba) {
+ pr_info("shost 0x%p, priv NULL.\n", shost);
+ goto err_out;
+ }
+ }
+
+ csk = cxgbi_check_route(dst_addr);
+ if (IS_ERR(csk))
+ return (struct iscsi_endpoint *)csk;
+ cxgbi_sock_get(csk);
+
+ if (!hba)
+ hba = csk->cdev->hbas[csk->port_id];
+ else if (hba != csk->cdev->hbas[csk->port_id]) {
+ pr_info("Could not connect through requested host %u"
+ "hba 0x%p != 0x%p (%u).\n",
+ shost->host_no, hba,
+ csk->cdev->hbas[csk->port_id], csk->port_id);
+ err = -ENOSPC;
+ goto release_conn;
+ }
+
+ err = sock_get_port(csk);
+ if (err)
+ goto release_conn;
+
+ cxgbi_sock_set_state(csk, CTP_CONNECTING);
+ err = csk->cdev->csk_init_act_open(csk);
+ if (err)
+ goto release_conn;
+
+ if (cxgbi_sock_is_closing(csk)) {
+ err = -ENOSPC;
+ pr_info("csk 0x%p is closing.\n", csk);
+ goto release_conn;
+ }
+
+ ep = iscsi_create_endpoint(sizeof(*cep));
+ if (!ep) {
+ err = -ENOMEM;
+ pr_info("iscsi alloc ep, OOM.\n");
+ goto release_conn;
+ }
+
+ cep = ep->dd_data;
+ cep->csk = csk;
+ cep->chba = hba;
+
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_SOCK,
+ "ep 0x%p, cep 0x%p, csk 0x%p, hba 0x%p,%s.\n",
+ ep, cep, csk, hba, hba->ndev->name);
+ return ep;
+
+release_conn:
+ cxgbi_sock_put(csk);
+ cxgbi_sock_closed(csk);
+err_out:
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(cxgbi_ep_connect);
+
+int cxgbi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
+{
+ struct cxgbi_endpoint *cep = ep->dd_data;
+ struct cxgbi_sock *csk = cep->csk;
+
+ if (!cxgbi_sock_is_established(csk))
+ return 0;
+ return 1;
+}
+EXPORT_SYMBOL_GPL(cxgbi_ep_poll);
+
+void cxgbi_ep_disconnect(struct iscsi_endpoint *ep)
+{
+ struct cxgbi_endpoint *cep = ep->dd_data;
+ struct cxgbi_conn *cconn = cep->cconn;
+ struct cxgbi_sock *csk = cep->csk;
+
+ log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_SOCK,
+ "ep 0x%p, cep 0x%p, cconn 0x%p, csk 0x%p,%u,0x%lx.\n",
+ ep, cep, cconn, csk, csk->state, csk->flags);
+
+ if (cconn && cconn->iconn) {
+ iscsi_suspend_tx(cconn->iconn);
+ write_lock_bh(&csk->callback_lock);
+ cep->csk->user_data = NULL;
+ cconn->cep = NULL;
+ write_unlock_bh(&csk->callback_lock);
+ }
+ iscsi_destroy_endpoint(ep);
+
+ if (likely(csk->state >= CTP_ESTABLISHED))
+ need_active_close(csk);
+ else
+ cxgbi_sock_closed(csk);
+
+ cxgbi_sock_put(csk);
+}
+EXPORT_SYMBOL_GPL(cxgbi_ep_disconnect);
+
+int cxgbi_iscsi_init(struct iscsi_transport *itp,
+ struct scsi_transport_template **stt)
+{
+ *stt = iscsi_register_transport(itp);
+ if (*stt == NULL) {
+ pr_err("unable to register %s transport 0x%p.\n",
+ itp->name, itp);
+ return -ENODEV;
+ }
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "%s, registered iscsi transport 0x%p.\n",
+ itp->name, stt);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxgbi_iscsi_init);
+
+void cxgbi_iscsi_cleanup(struct iscsi_transport *itp,
+ struct scsi_transport_template **stt)
+{
+ if (*stt) {
+ log_debug(1 << CXGBI_DBG_ISCSI,
+ "de-register transport 0x%p, %s, stt 0x%p.\n",
+ itp, itp->name, *stt);
+ *stt = NULL;
+ iscsi_unregister_transport(itp);
+ }
+}
+EXPORT_SYMBOL_GPL(cxgbi_iscsi_cleanup);
+
+static int __init libcxgbi_init_module(void)
+{
+ sw_tag_idx_bits = (__ilog2_u32(ISCSI_ITT_MASK)) + 1;
+ sw_tag_age_bits = (__ilog2_u32(ISCSI_AGE_MASK)) + 1;
+
+ pr_info("tag itt 0x%x, %u bits, age 0x%x, %u bits.\n",
+ ISCSI_ITT_MASK, sw_tag_idx_bits,
+ ISCSI_AGE_MASK, sw_tag_age_bits);
+
+ ddp_setup_host_page_size();
+ return 0;
+}
+
+static void __exit libcxgbi_exit_module(void)
+{
+ cxgbi_device_unregister_all(0xFF);
+ return;
+}
+
+module_init(libcxgbi_init_module);
+module_exit(libcxgbi_exit_module);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
new file mode 100644
index 000000000000..40551f3be5dc
--- /dev/null
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -0,0 +1,753 @@
+/*
+ * libcxgbi.h: Chelsio common library for T3/T4 iSCSI driver.
+ *
+ * Copyright (c) 2010 Chelsio Communications, 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.
+ *
+ * Written by: Karen Xie (kxie@chelsio.com)
+ * Written by: Rakesh Ranjan (rranjan@chelsio.com)
+ */
+
+#ifndef __LIBCXGBI_H__
+#define __LIBCXGBI_H__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/debugfs.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/scatterlist.h>
+#include <linux/skbuff.h>
+#include <linux/vmalloc.h>
+#include <scsi/scsi_device.h>
+#include <scsi/libiscsi_tcp.h>
+
+enum cxgbi_dbg_flag {
+ CXGBI_DBG_ISCSI,
+ CXGBI_DBG_DDP,
+ CXGBI_DBG_TOE,
+ CXGBI_DBG_SOCK,
+
+ CXGBI_DBG_PDU_TX,
+ CXGBI_DBG_PDU_RX,
+ CXGBI_DBG_DEV,
+};
+
+#define log_debug(level, fmt, ...) \
+ do { \
+ if (dbg_level & (level)) \
+ pr_info(fmt, ##__VA_ARGS__); \
+ } while (0)
+
+/* max. connections per adapter */
+#define CXGBI_MAX_CONN 16384
+
+/* always allocate rooms for AHS */
+#define SKB_TX_ISCSI_PDU_HEADER_MAX \
+ (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE)
+
+#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8)*/
+
+/*
+ * align pdu size to multiple of 512 for better performance
+ */
+#define cxgbi_align_pdu_size(n) do { n = (n) & (~511); } while (0)
+
+#define ULP2_MODE_ISCSI 2
+
+#define ULP2_MAX_PKT_SIZE 16224
+#define ULP2_MAX_PDU_PAYLOAD \
+ (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
+
+/*
+ * For iscsi connections HW may inserts digest bytes into the pdu. Those digest
+ * bytes are not sent by the host but are part of the TCP payload and therefore
+ * consume TCP sequence space.
+ */
+static const unsigned int ulp2_extra_len[] = { 0, 4, 4, 8 };
+static inline unsigned int cxgbi_ulp_extra_len(int submode)
+{
+ return ulp2_extra_len[submode & 3];
+}
+
+/*
+ * struct pagepod_hdr, pagepod - pagepod format
+ */
+
+#define CPL_RX_DDP_STATUS_DDP_SHIFT 16 /* ddp'able */
+#define CPL_RX_DDP_STATUS_PAD_SHIFT 19 /* pad error */
+#define CPL_RX_DDP_STATUS_HCRC_SHIFT 20 /* hcrc error */
+#define CPL_RX_DDP_STATUS_DCRC_SHIFT 21 /* dcrc error */
+
+struct cxgbi_pagepod_hdr {
+ u32 vld_tid;
+ u32 pgsz_tag_clr;
+ u32 max_offset;
+ u32 page_offset;
+ u64 rsvd;
+};
+
+#define PPOD_PAGES_MAX 4
+struct cxgbi_pagepod {
+ struct cxgbi_pagepod_hdr hdr;
+ u64 addr[PPOD_PAGES_MAX + 1];
+};
+
+struct cxgbi_tag_format {
+ unsigned char sw_bits;
+ unsigned char rsvd_bits;
+ unsigned char rsvd_shift;
+ unsigned char filler[1];
+ u32 rsvd_mask;
+};
+
+struct cxgbi_gather_list {
+ unsigned int tag;
+ unsigned int length;
+ unsigned int offset;
+ unsigned int nelem;
+ struct page **pages;
+ dma_addr_t phys_addr[0];
+};
+
+struct cxgbi_ddp_info {
+ struct kref refcnt;
+ struct cxgbi_device *cdev;
+ struct pci_dev *pdev;
+ unsigned int max_txsz;
+ unsigned int max_rxsz;
+ unsigned int llimit;
+ unsigned int ulimit;
+ unsigned int nppods;
+ unsigned int idx_last;
+ unsigned char idx_bits;
+ unsigned char filler[3];
+ unsigned int idx_mask;
+ unsigned int rsvd_tag_mask;
+ spinlock_t map_lock;
+ struct cxgbi_gather_list **gl_map;
+ struct sk_buff **gl_skb;
+};
+
+#define DDP_PGIDX_MAX 4
+#define DDP_THRESHOLD 2048
+
+#define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */
+
+#define PPOD_SIZE sizeof(struct cxgbi_pagepod) /* 64 */
+#define PPOD_SIZE_SHIFT 6
+
+#define ULPMEM_DSGL_MAX_NPPODS 16 /* 1024/PPOD_SIZE */
+#define ULPMEM_IDATA_MAX_NPPODS 4 /* 256/PPOD_SIZE */
+#define PCIE_MEMWIN_MAX_NPPODS 16 /* 1024/PPOD_SIZE */
+
+#define PPOD_COLOR_SHIFT 0
+#define PPOD_COLOR(x) ((x) << PPOD_COLOR_SHIFT)
+
+#define PPOD_IDX_SHIFT 6
+#define PPOD_IDX_MAX_SIZE 24
+
+#define PPOD_TID_SHIFT 0
+#define PPOD_TID(x) ((x) << PPOD_TID_SHIFT)
+
+#define PPOD_TAG_SHIFT 6
+#define PPOD_TAG(x) ((x) << PPOD_TAG_SHIFT)
+
+#define PPOD_VALID_SHIFT 24
+#define PPOD_VALID(x) ((x) << PPOD_VALID_SHIFT)
+#define PPOD_VALID_FLAG PPOD_VALID(1U)
+
+#define W_TCB_ULP_TYPE 0
+#define TCB_ULP_TYPE_SHIFT 0
+#define TCB_ULP_TYPE_MASK 0xfULL
+#define TCB_ULP_TYPE(x) ((x) << TCB_ULP_TYPE_SHIFT)
+
+#define W_TCB_ULP_RAW 0
+#define TCB_ULP_RAW_SHIFT 4
+#define TCB_ULP_RAW_MASK 0xffULL
+#define TCB_ULP_RAW(x) ((x) << TCB_ULP_RAW_SHIFT)
+
+/*
+ * sge_opaque_hdr -
+ * Opaque version of structure the SGE stores at skb->head of TX_DATA packets
+ * and for which we must reserve space.
+ */
+struct sge_opaque_hdr {
+ void *dev;
+ dma_addr_t addr[MAX_SKB_FRAGS + 1];
+};
+
+struct cxgbi_sock {
+ struct cxgbi_device *cdev;
+
+ int tid;
+ int atid;
+ unsigned long flags;
+ unsigned int mtu;
+ unsigned short rss_qid;
+ unsigned short txq_idx;
+ unsigned short advmss;
+ unsigned int tx_chan;
+ unsigned int rx_chan;
+ unsigned int mss_idx;
+ unsigned int smac_idx;
+ unsigned char port_id;
+ int wr_max_cred;
+ int wr_cred;
+ int wr_una_cred;
+ unsigned char hcrc_len;
+ unsigned char dcrc_len;
+
+ void *l2t;
+ struct sk_buff *wr_pending_head;
+ struct sk_buff *wr_pending_tail;
+ struct sk_buff *cpl_close;
+ struct sk_buff *cpl_abort_req;
+ struct sk_buff *cpl_abort_rpl;
+ struct sk_buff *skb_ulp_lhdr;
+ spinlock_t lock;
+ struct kref refcnt;
+ unsigned int state;
+ struct sockaddr_in saddr;
+ struct sockaddr_in daddr;
+ struct dst_entry *dst;
+ struct sk_buff_head receive_queue;
+ struct sk_buff_head write_queue;
+ struct timer_list retry_timer;
+ int err;
+ rwlock_t callback_lock;
+ void *user_data;
+
+ u32 rcv_nxt;
+ u32 copied_seq;
+ u32 rcv_wup;
+ u32 snd_nxt;
+ u32 snd_una;
+ u32 write_seq;
+};
+
+/*
+ * connection states
+ */
+enum cxgbi_sock_states{
+ CTP_CLOSED,
+ CTP_CONNECTING,
+ CTP_ACTIVE_OPEN,
+ CTP_ESTABLISHED,
+ CTP_ACTIVE_CLOSE,
+ CTP_PASSIVE_CLOSE,
+ CTP_CLOSE_WAIT_1,
+ CTP_CLOSE_WAIT_2,
+ CTP_ABORTING,
+};
+
+/*
+ * Connection flags -- many to track some close related events.
+ */
+enum cxgbi_sock_flags {
+ CTPF_ABORT_RPL_RCVD, /*received one ABORT_RPL_RSS message */
+ CTPF_ABORT_REQ_RCVD, /*received one ABORT_REQ_RSS message */
+ CTPF_ABORT_RPL_PENDING, /* expecting an abort reply */
+ CTPF_TX_DATA_SENT, /* already sent a TX_DATA WR */
+ CTPF_ACTIVE_CLOSE_NEEDED,/* need to be closed */
+ CTPF_HAS_ATID, /* reserved atid */
+ CTPF_HAS_TID, /* reserved hw tid */
+ CTPF_OFFLOAD_DOWN, /* offload function off */
+};
+
+struct cxgbi_skb_rx_cb {
+ __u32 ddigest;
+ __u32 pdulen;
+};
+
+struct cxgbi_skb_tx_cb {
+ void *l2t;
+ struct sk_buff *wr_next;
+};
+
+enum cxgbi_skcb_flags {
+ SKCBF_TX_NEED_HDR, /* packet needs a header */
+ SKCBF_RX_COALESCED, /* received whole pdu */
+ SKCBF_RX_HDR, /* recieved pdu header */
+ SKCBF_RX_DATA, /* recieved pdu payload */
+ SKCBF_RX_STATUS, /* recieved ddp status */
+ SKCBF_RX_DATA_DDPD, /* pdu payload ddp'd */
+ SKCBF_RX_HCRC_ERR, /* header digest error */
+ SKCBF_RX_DCRC_ERR, /* data digest error */
+ SKCBF_RX_PAD_ERR, /* padding byte error */
+};
+
+struct cxgbi_skb_cb {
+ unsigned char ulp_mode;
+ unsigned long flags;
+ unsigned int seq;
+ union {
+ struct cxgbi_skb_rx_cb rx;
+ struct cxgbi_skb_tx_cb tx;
+ };
+};
+
+#define CXGBI_SKB_CB(skb) ((struct cxgbi_skb_cb *)&((skb)->cb[0]))
+#define cxgbi_skcb_flags(skb) (CXGBI_SKB_CB(skb)->flags)
+#define cxgbi_skcb_ulp_mode(skb) (CXGBI_SKB_CB(skb)->ulp_mode)
+#define cxgbi_skcb_tcp_seq(skb) (CXGBI_SKB_CB(skb)->seq)
+#define cxgbi_skcb_rx_ddigest(skb) (CXGBI_SKB_CB(skb)->rx.ddigest)
+#define cxgbi_skcb_rx_pdulen(skb) (CXGBI_SKB_CB(skb)->rx.pdulen)
+#define cxgbi_skcb_tx_wr_next(skb) (CXGBI_SKB_CB(skb)->tx.wr_next)
+
+static inline void cxgbi_skcb_set_flag(struct sk_buff *skb,
+ enum cxgbi_skcb_flags flag)
+{
+ __set_bit(flag, &(cxgbi_skcb_flags(skb)));
+}
+
+static inline void cxgbi_skcb_clear_flag(struct sk_buff *skb,
+ enum cxgbi_skcb_flags flag)
+{
+ __clear_bit(flag, &(cxgbi_skcb_flags(skb)));
+}
+
+static inline int cxgbi_skcb_test_flag(struct sk_buff *skb,
+ enum cxgbi_skcb_flags flag)
+{
+ return test_bit(flag, &(cxgbi_skcb_flags(skb)));
+}
+
+static inline void cxgbi_sock_set_flag(struct cxgbi_sock *csk,
+ enum cxgbi_sock_flags flag)
+{
+ __set_bit(flag, &csk->flags);
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, bit %d.\n",
+ csk, csk->state, csk->flags, flag);
+}
+
+static inline void cxgbi_sock_clear_flag(struct cxgbi_sock *csk,
+ enum cxgbi_sock_flags flag)
+{
+ __clear_bit(flag, &csk->flags);
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, bit %d.\n",
+ csk, csk->state, csk->flags, flag);
+}
+
+static inline int cxgbi_sock_flag(struct cxgbi_sock *csk,
+ enum cxgbi_sock_flags flag)
+{
+ if (csk == NULL)
+ return 0;
+ return test_bit(flag, &csk->flags);
+}
+
+static inline void cxgbi_sock_set_state(struct cxgbi_sock *csk, int state)
+{
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "csk 0x%p,%u,0x%lx, state -> %u.\n",
+ csk, csk->state, csk->flags, state);
+ csk->state = state;
+}
+
+static inline void cxgbi_sock_free(struct kref *kref)
+{
+ struct cxgbi_sock *csk = container_of(kref,
+ struct cxgbi_sock,
+ refcnt);
+ if (csk) {
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "free csk 0x%p, state %u, flags 0x%lx\n",
+ csk, csk->state, csk->flags);
+ kfree(csk);
+ }
+}
+
+static inline void __cxgbi_sock_put(const char *fn, struct cxgbi_sock *csk)
+{
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "%s, put csk 0x%p, ref %u-1.\n",
+ fn, csk, atomic_read(&csk->refcnt.refcount));
+ kref_put(&csk->refcnt, cxgbi_sock_free);
+}
+#define cxgbi_sock_put(csk) __cxgbi_sock_put(__func__, csk)
+
+static inline void __cxgbi_sock_get(const char *fn, struct cxgbi_sock *csk)
+{
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "%s, get csk 0x%p, ref %u+1.\n",
+ fn, csk, atomic_read(&csk->refcnt.refcount));
+ kref_get(&csk->refcnt);
+}
+#define cxgbi_sock_get(csk) __cxgbi_sock_get(__func__, csk)
+
+static inline int cxgbi_sock_is_closing(struct cxgbi_sock *csk)
+{
+ return csk->state >= CTP_ACTIVE_CLOSE;
+}
+
+static inline int cxgbi_sock_is_established(struct cxgbi_sock *csk)
+{
+ return csk->state == CTP_ESTABLISHED;
+}
+
+static inline void cxgbi_sock_purge_write_queue(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb;
+
+ while ((skb = __skb_dequeue(&csk->write_queue)))
+ __kfree_skb(skb);
+}
+
+static inline unsigned int cxgbi_sock_compute_wscale(unsigned int win)
+{
+ unsigned int wscale = 0;
+
+ while (wscale < 14 && (65535 << wscale) < win)
+ wscale++;
+ return wscale;
+}
+
+static inline struct sk_buff *alloc_cpl(int cpl_len, int dlen, gfp_t gfp)
+{
+ int wrlen = roundup(cpl_len, 16);
+ struct sk_buff *skb = alloc_skb(wrlen + dlen, gfp);
+
+ if (skb) {
+ __skb_put(skb, wrlen);
+ memset(skb->head, 0, wrlen + dlen);
+ } else
+ pr_info("alloc cpl skb %u+%u, OOM.\n", cpl_len, dlen);
+ return skb;
+}
+
+
+/*
+ * 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 extra two fragments are for iscsi bhs and payload padding.
+ */
+#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2)
+
+static inline void cxgbi_sock_reset_wr_list(struct cxgbi_sock *csk)
+{
+ csk->wr_pending_head = csk->wr_pending_tail = NULL;
+}
+
+static inline void cxgbi_sock_enqueue_wr(struct cxgbi_sock *csk,
+ struct sk_buff *skb)
+{
+ cxgbi_skcb_tx_wr_next(skb) = NULL;
+ /*
+ * We want to take an extra reference since both us and the driver
+ * need to free the packet before it's really freed. We know there's
+ * just one user currently so we use atomic_set rather than skb_get
+ * to avoid the atomic op.
+ */
+ atomic_set(&skb->users, 2);
+
+ if (!csk->wr_pending_head)
+ csk->wr_pending_head = skb;
+ else
+ cxgbi_skcb_tx_wr_next(csk->wr_pending_tail) = skb;
+ csk->wr_pending_tail = skb;
+}
+
+static inline int cxgbi_sock_count_pending_wrs(const struct cxgbi_sock *csk)
+{
+ int n = 0;
+ const struct sk_buff *skb = csk->wr_pending_head;
+
+ while (skb) {
+ n += skb->csum;
+ skb = cxgbi_skcb_tx_wr_next(skb);
+ }
+ return n;
+}
+
+static inline struct sk_buff *cxgbi_sock_peek_wr(const struct cxgbi_sock *csk)
+{
+ return csk->wr_pending_head;
+}
+
+static inline struct sk_buff *cxgbi_sock_dequeue_wr(struct cxgbi_sock *csk)
+{
+ struct sk_buff *skb = csk->wr_pending_head;
+
+ if (likely(skb)) {
+ csk->wr_pending_head = cxgbi_skcb_tx_wr_next(skb);
+ cxgbi_skcb_tx_wr_next(skb) = NULL;
+ }
+ return skb;
+}
+
+void cxgbi_sock_check_wr_invariants(const struct cxgbi_sock *);
+void cxgbi_sock_purge_wr_queue(struct cxgbi_sock *);
+void cxgbi_sock_skb_entail(struct cxgbi_sock *, struct sk_buff *);
+void cxgbi_sock_fail_act_open(struct cxgbi_sock *, int);
+void cxgbi_sock_act_open_req_arp_failure(void *, struct sk_buff *);
+void cxgbi_sock_closed(struct cxgbi_sock *);
+void cxgbi_sock_established(struct cxgbi_sock *, unsigned int, unsigned int);
+void cxgbi_sock_rcv_abort_rpl(struct cxgbi_sock *);
+void cxgbi_sock_rcv_peer_close(struct cxgbi_sock *);
+void cxgbi_sock_rcv_close_conn_rpl(struct cxgbi_sock *, u32);
+void cxgbi_sock_rcv_wr_ack(struct cxgbi_sock *, unsigned int, unsigned int,
+ int);
+unsigned int cxgbi_sock_select_mss(struct cxgbi_sock *, unsigned int);
+void cxgbi_sock_free_cpl_skbs(struct cxgbi_sock *);
+
+struct cxgbi_hba {
+ struct net_device *ndev;
+ struct Scsi_Host *shost;
+ struct cxgbi_device *cdev;
+ __be32 ipv4addr;
+ unsigned char port_id;
+};
+
+struct cxgbi_ports_map {
+ unsigned int max_connect;
+ unsigned int used;
+ unsigned short sport_base;
+ spinlock_t lock;
+ unsigned int next;
+ struct cxgbi_sock **port_csk;
+};
+
+#define CXGBI_FLAG_DEV_T3 0x1
+#define CXGBI_FLAG_DEV_T4 0x2
+#define CXGBI_FLAG_ADAPTER_RESET 0x4
+#define CXGBI_FLAG_IPV4_SET 0x10
+struct cxgbi_device {
+ struct list_head list_head;
+ unsigned int flags;
+ struct net_device **ports;
+ void *lldev;
+ struct cxgbi_hba **hbas;
+ const unsigned short *mtus;
+ unsigned char nmtus;
+ unsigned char nports;
+ struct pci_dev *pdev;
+ struct dentry *debugfs_root;
+ struct iscsi_transport *itp;
+
+ unsigned int pfvf;
+ unsigned int snd_win;
+ unsigned int rcv_win;
+ unsigned int rx_credit_thres;
+ unsigned int skb_tx_rsvd;
+ unsigned int skb_rx_extra; /* for msg coalesced mode */
+ unsigned int tx_max_size;
+ unsigned int rx_max_size;
+ struct cxgbi_ports_map pmap;
+ struct cxgbi_tag_format tag_format;
+ struct cxgbi_ddp_info *ddp;
+
+ void (*dev_ddp_cleanup)(struct cxgbi_device *);
+ void (*csk_ddp_free_gl_skb)(struct cxgbi_ddp_info *, int, int);
+ int (*csk_ddp_alloc_gl_skb)(struct cxgbi_ddp_info *, int, int, gfp_t);
+ int (*csk_ddp_set)(struct cxgbi_sock *, struct cxgbi_pagepod_hdr *,
+ unsigned int, unsigned int,
+ struct cxgbi_gather_list *);
+ void (*csk_ddp_clear)(struct cxgbi_hba *,
+ unsigned int, unsigned int, unsigned int);
+ int (*csk_ddp_setup_digest)(struct cxgbi_sock *,
+ unsigned int, int, int, int);
+ int (*csk_ddp_setup_pgidx)(struct cxgbi_sock *,
+ unsigned int, int, bool);
+
+ void (*csk_release_offload_resources)(struct cxgbi_sock *);
+ int (*csk_rx_pdu_ready)(struct cxgbi_sock *, struct sk_buff *);
+ u32 (*csk_send_rx_credits)(struct cxgbi_sock *, u32);
+ int (*csk_push_tx_frames)(struct cxgbi_sock *, int);
+ void (*csk_send_abort_req)(struct cxgbi_sock *);
+ void (*csk_send_close_req)(struct cxgbi_sock *);
+ int (*csk_alloc_cpls)(struct cxgbi_sock *);
+ int (*csk_init_act_open)(struct cxgbi_sock *);
+
+ void *dd_data;
+};
+#define cxgbi_cdev_priv(cdev) ((cdev)->dd_data)
+
+struct cxgbi_conn {
+ struct cxgbi_endpoint *cep;
+ struct iscsi_conn *iconn;
+ struct cxgbi_hba *chba;
+ u32 task_idx_bits;
+};
+
+struct cxgbi_endpoint {
+ struct cxgbi_conn *cconn;
+ struct cxgbi_hba *chba;
+ struct cxgbi_sock *csk;
+};
+
+#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512)
+struct cxgbi_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;
+};
+
+static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag)
+{
+ return !(tag & (1 << (tformat->rsvd_bits + tformat->rsvd_shift - 1)));
+}
+
+static inline int cxgbi_sw_tag_usable(struct cxgbi_tag_format *tformat,
+ u32 sw_tag)
+{
+ sw_tag >>= (32 - tformat->rsvd_bits);
+ return !sw_tag;
+}
+
+static inline u32 cxgbi_set_non_ddp_tag(struct cxgbi_tag_format *tformat,
+ u32 sw_tag)
+{
+ unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
+ u32 mask = (1 << shift) - 1;
+
+ if (sw_tag && (sw_tag & ~mask)) {
+ u32 v1 = sw_tag & ((1 << shift) - 1);
+ u32 v2 = (sw_tag >> (shift - 1)) << shift;
+
+ return v2 | v1 | 1 << shift;
+ }
+
+ return sw_tag | 1 << shift;
+}
+
+static inline u32 cxgbi_ddp_tag_base(struct cxgbi_tag_format *tformat,
+ u32 sw_tag)
+{
+ u32 mask = (1 << tformat->rsvd_shift) - 1;
+
+ if (sw_tag && (sw_tag & ~mask)) {
+ u32 v1 = sw_tag & mask;
+ u32 v2 = sw_tag >> tformat->rsvd_shift;
+
+ v2 <<= tformat->rsvd_bits + tformat->rsvd_shift;
+
+ return v2 | v1;
+ }
+
+ return sw_tag;
+}
+
+static inline u32 cxgbi_tag_rsvd_bits(struct cxgbi_tag_format *tformat,
+ u32 tag)
+{
+ if (cxgbi_is_ddp_tag(tformat, tag))
+ return (tag >> tformat->rsvd_shift) & tformat->rsvd_mask;
+
+ return 0;
+}
+
+static inline u32 cxgbi_tag_nonrsvd_bits(struct cxgbi_tag_format *tformat,
+ u32 tag)
+{
+ unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
+ u32 v1, v2;
+
+ if (cxgbi_is_ddp_tag(tformat, tag)) {
+ v1 = tag & ((1 << tformat->rsvd_shift) - 1);
+ v2 = (tag >> (shift + 1)) << tformat->rsvd_shift;
+ } else {
+ u32 mask = (1 << shift) - 1;
+ tag &= ~(1 << shift);
+ v1 = tag & mask;
+ v2 = (tag >> 1) & ~mask;
+ }
+ return v1 | v2;
+}
+
+static inline void *cxgbi_alloc_big_mem(unsigned int size,
+ gfp_t gfp)
+{
+ void *p = kmalloc(size, gfp);
+ if (!p)
+ p = vmalloc(size);
+ if (p)
+ memset(p, 0, size);
+ return p;
+}
+
+static inline void cxgbi_free_big_mem(void *addr)
+{
+ if (is_vmalloc_addr(addr))
+ vfree(addr);
+ else
+ kfree(addr);
+}
+
+static inline void cxgbi_set_iscsi_ipv4(struct cxgbi_hba *chba, __be32 ipaddr)
+{
+ if (chba->cdev->flags & CXGBI_FLAG_IPV4_SET)
+ chba->ipv4addr = ipaddr;
+ else
+ pr_info("set iscsi ipv4 NOT supported, using %s ipv4.\n",
+ chba->ndev->name);
+}
+
+static inline __be32 cxgbi_get_iscsi_ipv4(struct cxgbi_hba *chba)
+{
+ return chba->ipv4addr;
+}
+
+struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int);
+void cxgbi_device_unregister(struct cxgbi_device *);
+void cxgbi_device_unregister_all(unsigned int flag);
+struct cxgbi_device *cxgbi_device_find_by_lldev(void *);
+int cxgbi_hbas_add(struct cxgbi_device *, unsigned int, unsigned int,
+ struct scsi_host_template *,
+ struct scsi_transport_template *);
+void cxgbi_hbas_remove(struct cxgbi_device *);
+
+int cxgbi_device_portmap_create(struct cxgbi_device *cdev, unsigned int base,
+ unsigned int max_conn);
+void cxgbi_device_portmap_cleanup(struct cxgbi_device *cdev);
+
+void cxgbi_conn_tx_open(struct cxgbi_sock *);
+void cxgbi_conn_pdu_ready(struct cxgbi_sock *);
+int cxgbi_conn_alloc_pdu(struct iscsi_task *, u8);
+int cxgbi_conn_init_pdu(struct iscsi_task *, unsigned int , unsigned int);
+int cxgbi_conn_xmit_pdu(struct iscsi_task *);
+
+void cxgbi_cleanup_task(struct iscsi_task *task);
+
+void cxgbi_get_conn_stats(struct iscsi_cls_conn *, struct iscsi_stats *);
+int cxgbi_set_conn_param(struct iscsi_cls_conn *,
+ enum iscsi_param, char *, int);
+int cxgbi_get_conn_param(struct iscsi_cls_conn *, enum iscsi_param, char *);
+struct iscsi_cls_conn *cxgbi_create_conn(struct iscsi_cls_session *, u32);
+int cxgbi_bind_conn(struct iscsi_cls_session *,
+ struct iscsi_cls_conn *, u64, int);
+void cxgbi_destroy_session(struct iscsi_cls_session *);
+struct iscsi_cls_session *cxgbi_create_session(struct iscsi_endpoint *,
+ u16, u16, u32);
+int cxgbi_set_host_param(struct Scsi_Host *,
+ enum iscsi_host_param, char *, int);
+int cxgbi_get_host_param(struct Scsi_Host *, enum iscsi_host_param, char *);
+struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *,
+ struct sockaddr *, int);
+int cxgbi_ep_poll(struct iscsi_endpoint *, int);
+void cxgbi_ep_disconnect(struct iscsi_endpoint *);
+
+int cxgbi_iscsi_init(struct iscsi_transport *,
+ struct scsi_transport_template **);
+void cxgbi_iscsi_cleanup(struct iscsi_transport *,
+ struct scsi_transport_template **);
+void cxgbi_parse_pdu_itt(struct iscsi_conn *, itt_t, int *, int *);
+int cxgbi_ddp_init(struct cxgbi_device *, unsigned int, unsigned int,
+ unsigned int, unsigned int);
+int cxgbi_ddp_cleanup(struct cxgbi_device *);
+void cxgbi_ddp_page_size_factor(int *);
+void cxgbi_ddp_ppod_clear(struct cxgbi_pagepod *);
+void cxgbi_ddp_ppod_set(struct cxgbi_pagepod *, struct cxgbi_pagepod_hdr *,
+ struct cxgbi_gather_list *, unsigned int);
+#endif /*__LIBCXGBI_H__*/
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index ffc1edf5e80d..c5fa4472109e 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -49,7 +49,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/kernel.h> /* for printk */
#include <linux/sched.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
@@ -76,6 +75,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
* Needed for our management apps
*============================================================================
*/
+static DEFINE_MUTEX(adpt_mutex);
static dpt_sig_S DPTI_sig = {
{'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
#ifdef __i386__
@@ -126,6 +126,7 @@ static const struct file_operations adpt_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_adpt_ioctl,
#endif
+ .llseek = noop_llseek,/* no read or write fn */
};
/* Structures and definitions for synchronous message posting.
@@ -1732,12 +1733,12 @@ static int adpt_open(struct inode *inode, struct file *file)
int minor;
adpt_hba* pHba;
- lock_kernel();
+ mutex_lock(&adpt_mutex);
//TODO check for root access
//
minor = iminor(inode);
if (minor >= hba_count) {
- unlock_kernel();
+ mutex_unlock(&adpt_mutex);
return -ENXIO;
}
mutex_lock(&adpt_configuration_lock);
@@ -1748,7 +1749,7 @@ static int adpt_open(struct inode *inode, struct file *file)
}
if (pHba == NULL) {
mutex_unlock(&adpt_configuration_lock);
- unlock_kernel();
+ mutex_unlock(&adpt_mutex);
return -ENXIO;
}
@@ -1759,7 +1760,7 @@ static int adpt_open(struct inode *inode, struct file *file)
pHba->in_use = 1;
mutex_unlock(&adpt_configuration_lock);
- unlock_kernel();
+ mutex_unlock(&adpt_mutex);
return 0;
}
@@ -2160,9 +2161,9 @@ static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg)
inode = file->f_dentry->d_inode;
- lock_kernel();
+ mutex_lock(&adpt_mutex);
ret = adpt_ioctl(inode, file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&adpt_mutex);
return ret;
}
@@ -2176,7 +2177,7 @@ static long compat_adpt_ioctl(struct file *file,
inode = file->f_dentry->d_inode;
- lock_kernel();
+ mutex_lock(&adpt_mutex);
switch(cmd) {
case DPT_SIGNATURE:
@@ -2194,7 +2195,7 @@ static long compat_adpt_ioctl(struct file *file,
ret = -ENOIOCTLCMD;
}
- unlock_kernel();
+ mutex_unlock(&adpt_mutex);
return ret;
}
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 9eb7a9ebccae..df91a61591b2 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -80,8 +80,6 @@ static struct libfc_function_template fnic_transport_template = {
static int fnic_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
- struct fc_lport *lp = shost_priv(sdev->host);
- struct fnic *fnic = lport_priv(lp);
sdev->tagged_supported = 1;
@@ -89,8 +87,6 @@ static int fnic_slave_alloc(struct scsi_device *sdev)
return -ENXIO;
scsi_activate_tcq(sdev, FNIC_DFLT_QUEUE_DEPTH);
- rport->dev_loss_tmo = fnic->config.port_down_timeout / 1000;
-
return 0;
}
@@ -113,6 +109,15 @@ static struct scsi_host_template fnic_host_template = {
.shost_attrs = fnic_attrs,
};
+static void
+fnic_get_host_def_loss_tmo(struct Scsi_Host *shost)
+{
+ struct fc_lport *lp = shost_priv(shost);
+ struct fnic *fnic = lport_priv(lp);
+
+ fc_host_def_dev_loss_tmo(shost) = fnic->config.port_down_timeout / 1000;
+}
+
static void fnic_get_host_speed(struct Scsi_Host *shost);
static struct scsi_transport_template *fnic_fc_transport;
static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *);
@@ -142,6 +147,7 @@ static struct fc_function_template fnic_fc_functions = {
.show_rport_dev_loss_tmo = 1,
.issue_fc_host_lip = fnic_reset,
.get_fc_host_stats = fnic_get_stats,
+ .get_host_def_dev_loss_tmo = fnic_get_host_def_loss_tmo,
.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
.terminate_rport_io = fnic_terminate_rport_io,
.bsg_request = fc_lport_bsg_request,
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index b860d650a563..f3ec22ca40ca 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -120,7 +120,7 @@
#include <linux/timer.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#ifdef GDTH_RTC
@@ -140,6 +140,7 @@
#include <scsi/scsi_host.h>
#include "gdth.h"
+static DEFINE_MUTEX(gdth_mutex);
static void gdth_delay(int milliseconds);
static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs);
static irqreturn_t gdth_interrupt(int irq, void *dev_id);
@@ -372,6 +373,7 @@ static const struct file_operations gdth_fops = {
.unlocked_ioctl = gdth_unlocked_ioctl,
.open = gdth_open,
.release = gdth_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
#include "gdth_proc.h"
@@ -4042,12 +4044,12 @@ static int gdth_open(struct inode *inode, struct file *filep)
{
gdth_ha_str *ha;
- lock_kernel();
+ mutex_lock(&gdth_mutex);
list_for_each_entry(ha, &gdth_instances, list) {
if (!ha->sdev)
ha->sdev = scsi_get_host_dev(ha->shost);
}
- unlock_kernel();
+ mutex_unlock(&gdth_mutex);
TRACE(("gdth_open()\n"));
return 0;
@@ -4615,9 +4617,9 @@ static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd,
{
int ret;
- lock_kernel();
+ mutex_lock(&gdth_mutex);
ret = gdth_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&gdth_mutex);
return ret;
}
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 8a8f803439e1..ba7f87acc00d 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -411,9 +411,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
device_initialize(&shost->shost_gendev);
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
-#ifndef CONFIG_SYSFS_DEPRECATED
shost->shost_gendev.bus = &scsi_bus_type;
-#endif
shost->shost_gendev.type = &scsi_host_type;
device_initialize(&shost->shost_dev);
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4f5551b5fe53..c5d0606ad097 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3231,6 +3231,12 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
misc_fw_support = readl(&cfgtable->misc_fw_support);
use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+ /* The doorbell reset seems to cause lockups on some Smart
+ * Arrays (e.g. P410, P410i, maybe others). Until this is
+ * fixed or at least isolated, avoid the doorbell reset.
+ */
+ use_doorbell = 0;
+
rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
if (rc)
goto unmap_cfgtable;
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 9f75a6d519a2..a5dd9b4a0ae8 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1030,6 +1030,11 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost)
spin_unlock_irqrestore(shost->host_lock, flags);
}
+static void ibmvfc_set_host_def_dev_loss_tmo(struct Scsi_Host *shost)
+{
+ fc_host_def_dev_loss_tmo(shost) = dev_loss_tmo;
+}
+
/**
* ibmvfc_set_rport_dev_loss_tmo - Set rport's device loss timeout
* @rport: rport struct
@@ -2788,7 +2793,6 @@ static int ibmvfc_target_alloc(struct scsi_target *starget)
static int ibmvfc_slave_configure(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
- struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
unsigned long flags = 0;
spin_lock_irqsave(shost->host_lock, flags);
@@ -2800,8 +2804,6 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
scsi_activate_tcq(sdev, sdev->queue_depth);
} else
scsi_deactivate_tcq(sdev, sdev->queue_depth);
-
- rport->dev_loss_tmo = dev_loss_tmo;
spin_unlock_irqrestore(shost->host_lock, flags);
return 0;
}
@@ -4889,6 +4891,8 @@ static struct fc_function_template ibmvfc_transport_functions = {
.get_host_speed = ibmvfc_get_host_speed,
.show_host_speed = 1,
+ .get_host_def_dev_loss_tmo = ibmvfc_set_host_def_dev_loss_tmo,
+
.issue_fc_host_lip = ibmvfc_issue_fc_host_lip,
.terminate_rport_io = ibmvfc_terminate_rport_io,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 52568588039f..3b28e8728131 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1096,6 +1096,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
res->bus = cfgtew->u.cfgte->res_addr.bus;
res->target = cfgtew->u.cfgte->res_addr.target;
res->lun = cfgtew->u.cfgte->res_addr.lun;
+ res->lun_wwn = get_unaligned_be64(cfgtew->u.cfgte->lun_wwn);
}
ipr_update_ata_class(res, proto);
@@ -1142,7 +1143,7 @@ static char *ipr_format_res_path(u8 *res_path, char *buffer, int len)
int i;
char *p = buffer;
- res_path[0] = '\0';
+ *p = '\0';
p += snprintf(p, buffer + len - p, "%02X", res_path[0]);
for (i = 1; res_path[i] != 0xff && ((i * 3) < len); i++)
p += snprintf(p, buffer + len - p, "-%02X", res_path[i]);
@@ -4089,6 +4090,7 @@ static int ipr_change_queue_type(struct scsi_device *sdev, int tag_type)
/**
* ipr_show_adapter_handle - Show the adapter's resource handle for this device
* @dev: device struct
+ * @attr: device attribute structure
* @buf: buffer
*
* Return value:
@@ -4122,6 +4124,7 @@ static struct device_attribute ipr_adapter_handle_attr = {
* ipr_show_resource_path - Show the resource path or the resource address for
* this device.
* @dev: device struct
+ * @attr: device attribute structure
* @buf: buffer
*
* Return value:
@@ -4159,8 +4162,45 @@ static struct device_attribute ipr_resource_path_attr = {
};
/**
+ * ipr_show_device_id - Show the device_id for this device.
+ * @dev: device struct
+ * @attr: device attribute structure
+ * @buf: buffer
+ *
+ * Return value:
+ * number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_device_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+ struct ipr_resource_entry *res;
+ unsigned long lock_flags = 0;
+ ssize_t len = -ENXIO;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ res = (struct ipr_resource_entry *)sdev->hostdata;
+ if (res && ioa_cfg->sis64)
+ len = snprintf(buf, PAGE_SIZE, "0x%llx\n", res->dev_id);
+ else if (res)
+ len = snprintf(buf, PAGE_SIZE, "0x%llx\n", res->lun_wwn);
+
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return len;
+}
+
+static struct device_attribute ipr_device_id_attr = {
+ .attr = {
+ .name = "device_id",
+ .mode = S_IRUGO,
+ },
+ .show = ipr_show_device_id
+};
+
+/**
* ipr_show_resource_type - Show the resource type for this device.
* @dev: device struct
+ * @attr: device attribute structure
* @buf: buffer
*
* Return value:
@@ -4195,6 +4235,7 @@ static struct device_attribute ipr_resource_type_attr = {
static struct device_attribute *ipr_dev_attrs[] = {
&ipr_adapter_handle_attr,
&ipr_resource_path_attr,
+ &ipr_device_id_attr,
&ipr_resource_type_attr,
NULL,
};
@@ -4898,39 +4939,15 @@ static int ipr_eh_abort(struct scsi_cmnd * scsi_cmd)
/**
* ipr_handle_other_interrupt - Handle "other" interrupts
* @ioa_cfg: ioa config struct
+ * @int_reg: interrupt register
*
* Return value:
* IRQ_NONE / IRQ_HANDLED
**/
-static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg)
+static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
+ volatile u32 int_reg)
{
irqreturn_t rc = IRQ_HANDLED;
- volatile u32 int_reg, int_mask_reg;
-
- int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
-
- /* If an interrupt on the adapter did not occur, ignore it.
- * Or in the case of SIS 64, check for a stage change interrupt.
- */
- if ((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0) {
- if (ioa_cfg->sis64) {
- int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
- if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
-
- /* clear stage change */
- writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
- list_del(&ioa_cfg->reset_cmd->queue);
- del_timer(&ioa_cfg->reset_cmd->timer);
- ipr_reset_ioa_job(ioa_cfg->reset_cmd);
- return IRQ_HANDLED;
- }
- }
-
- return IRQ_NONE;
- }
if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
/* Mask the interrupt */
@@ -4991,7 +5008,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
{
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
unsigned long lock_flags = 0;
- volatile u32 int_reg;
+ volatile u32 int_reg, int_mask_reg;
u32 ioasc;
u16 cmd_index;
int num_hrrq = 0;
@@ -5006,6 +5023,33 @@ static irqreturn_t ipr_isr(int irq, void *devp)
return IRQ_NONE;
}
+ int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
+
+ /* If an interrupt on the adapter did not occur, ignore it.
+ * Or in the case of SIS 64, check for a stage change interrupt.
+ */
+ if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
+ if (ioa_cfg->sis64) {
+ int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
+
+ /* clear stage change */
+ writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+ list_del(&ioa_cfg->reset_cmd->queue);
+ del_timer(&ioa_cfg->reset_cmd->timer);
+ ipr_reset_ioa_job(ioa_cfg->reset_cmd);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return IRQ_HANDLED;
+ }
+ }
+
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return IRQ_NONE;
+ }
+
while (1) {
ipr_cmd = NULL;
@@ -5045,7 +5089,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
/* Clear the PCI interrupt */
do {
writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
- int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
} while (int_reg & IPR_PCII_HRRQ_UPDATED &&
num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
@@ -5060,7 +5104,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
}
if (unlikely(rc == IRQ_NONE))
- rc = ipr_handle_other_interrupt(ioa_cfg);
+ rc = ipr_handle_other_interrupt(ioa_cfg, int_reg);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return rc;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 4d31625ab9cf..67cae67378ad 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -26,6 +26,7 @@
#ifndef _IPR_H
#define _IPR_H
+#include <asm/unaligned.h>
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/libata.h>
@@ -37,8 +38,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.5.0"
-#define IPR_DRIVER_DATE "(February 11, 2010)"
+#define IPR_DRIVER_VERSION "2.5.1"
+#define IPR_DRIVER_DATE "(August 10, 2010)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -372,7 +373,7 @@ struct ipr_config_table_entry {
struct ipr_res_addr res_addr;
__be32 res_handle;
- __be32 reserved4[2];
+ __be32 lun_wwn[2];
struct ipr_std_inq_data std_inq_data;
}__attribute__ ((packed, aligned (4)));
@@ -1210,6 +1211,7 @@ struct ipr_resource_entry {
__be32 res_handle;
__be64 dev_id;
+ __be64 lun_wwn;
struct scsi_lun dev_lun;
u8 res_path[8];
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index f0cfba9a1fc8..535085cd27ec 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -130,17 +130,6 @@ static void sas_scsi_task_done(struct sas_task *task)
sc->scsi_done(sc);
}
-static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
-{
- enum task_attribute ta = TASK_ATTR_SIMPLE;
- if (cmd->request && blk_rq_tagged(cmd->request)) {
- if (cmd->device->ordered_tags &&
- (cmd->request->cmd_flags & REQ_HARDBARRIER))
- ta = TASK_ATTR_ORDERED;
- }
- return ta;
-}
-
static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
struct domain_device *dev,
gfp_t gfp_flags)
@@ -160,7 +149,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
task->ssp_task.retry_count = 1;
int_to_scsilun(cmd->device->lun, &lun);
memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
- task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd);
+ task->ssp_task.task_attr = TASK_ATTR_SIMPLE;
memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
task->scatter = scsi_sglist(cmd);
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 23ce45708335..87c2b6b858f7 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4370,6 +4370,14 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
}
+static void
+lpfc_get_host_def_loss_tmo(struct Scsi_Host *shost)
+{
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+
+ fc_host_def_dev_loss_tmo(shost) = vport->cfg_devloss_tmo;
+}
+
/**
* lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
* @rport: fc rport address.
@@ -4478,6 +4486,7 @@ struct fc_function_template lpfc_transport_functions = {
.get_host_fabric_name = lpfc_get_host_fabric_name,
.show_host_fabric_name = 1,
+ .get_host_def_dev_loss_tmo = lpfc_get_host_def_loss_tmo,
/*
* The LPFC driver treats linkdown handling as target loss events
* so there are no sysfs handlers for link_down_tmo.
@@ -4545,6 +4554,7 @@ struct fc_function_template lpfc_vport_transport_functions = {
.get_host_fabric_name = lpfc_get_host_fabric_name,
.show_host_fabric_name = 1,
+ .get_host_def_dev_loss_tmo = lpfc_get_host_def_loss_tmo,
/*
* The LPFC driver treats linkdown handling as target loss events
* so there are no sysfs handlers for link_down_tmo.
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 1f62ea8c165d..ddd8c8096eea 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -5507,7 +5507,7 @@ lpfc_get_rec_conf23(uint8_t *buff, uint32_t size, uint8_t rec_type)
* @buff: Buffer containing config region 23 data.
* @size: Size of the data buffer.
*
- * This fuction parse the FCoE config parameters in config region 23 and
+ * This function parses the FCoE config parameters in config region 23 and
* populate driver data structure with the parameters.
*/
void
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 2e51aa6b45b3..6e331c73170e 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3656,7 +3656,6 @@ lpfc_slave_alloc(struct scsi_device *sdev)
*
* This routine configures following items
* - Tag command queuing support for @sdev if supported.
- * - Dev loss time out value of fc_rport.
* - Enable SLI polling for fcp ring if ENABLE_FCP_RING_POLLING flag is set.
*
* Return codes:
@@ -3667,21 +3666,12 @@ lpfc_slave_configure(struct scsi_device *sdev)
{
struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
struct lpfc_hba *phba = vport->phba;
- struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
if (sdev->tagged_supported)
scsi_activate_tcq(sdev, vport->cfg_lun_queue_depth);
else
scsi_deactivate_tcq(sdev, vport->cfg_lun_queue_depth);
- /*
- * Initialize the fc transport attributes for the target
- * containing this scsi device. Also note that the driver's
- * target pointer is stored in the starget_data for the
- * driver's sysfs entry point functions.
- */
- rport->dev_loss_tmo = vport->cfg_devloss_tmo;
-
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
lpfc_sli_handle_fast_ring_event(phba,
&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index fb8905f893f5..23a47e536858 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -8476,7 +8476,7 @@ lpfc_sli_intr_handler(int irq, void *dev_id)
* If there is deferred error attention, do not check for any interrupt.
*/
if (unlikely(phba->hba_flag & DEFER_ERATT)) {
- spin_unlock_irq(&phba->hbalock);
+ spin_unlock(&phba->hbalock);
return IRQ_NONE;
}
@@ -12827,9 +12827,9 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
}
ndlp = (struct lpfc_nodelist *) mb->context2;
if (ndlp) {
- spin_lock_irq(shost->host_lock);
+ spin_lock(shost->host_lock);
ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
- spin_unlock_irq(shost->host_lock);
+ spin_unlock(shost->host_lock);
lpfc_nlp_put(ndlp);
mb->context2 = NULL;
}
@@ -12845,9 +12845,9 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
ndlp = (struct lpfc_nodelist *) mb->context2;
if (ndlp) {
- spin_lock_irq(shost->host_lock);
+ spin_lock(shost->host_lock);
ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL;
- spin_unlock_irq(shost->host_lock);
+ spin_unlock(shost->host_lock);
lpfc_nlp_put(ndlp);
mb->context2 = NULL;
}
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 0b6e3228610a..5074dae98661 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -46,7 +46,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <scsi/scsicam.h>
@@ -62,6 +62,7 @@ MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
MODULE_LICENSE ("GPL");
MODULE_VERSION(MEGARAID_MODULE_VERSION);
+static DEFINE_MUTEX(megadev_mutex);
static unsigned int max_cmd_per_lun = DEF_CMD_PER_LUN;
module_param(max_cmd_per_lun, uint, 0);
MODULE_PARM_DESC(max_cmd_per_lun, "Maximum number of commands which can be issued to a single LUN (default=DEF_CMD_PER_LUN=63)");
@@ -101,6 +102,7 @@ static const struct file_operations megadev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = megadev_unlocked_ioctl,
.open = megadev_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
@@ -3282,7 +3284,6 @@ mega_init_scb(adapter_t *adapter)
static int
megadev_open (struct inode *inode, struct file *filep)
{
- cycle_kernel_lock();
/*
* Only allow superuser to access private ioctl interface
*/
@@ -3701,9 +3702,9 @@ megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&megadev_mutex);
ret = megadev_ioctl(filep, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&megadev_mutex);
return ret;
}
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 41f82f76d884..fef75e56e8d0 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -16,11 +16,12 @@
*/
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include "megaraid_mm.h"
// Entry points for char node driver
+static DEFINE_MUTEX(mraid_mm_mutex);
static int mraid_mm_open(struct inode *, struct file *);
static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long);
@@ -75,6 +76,7 @@ static const struct file_operations lsi_fops = {
.compat_ioctl = mraid_mm_compat_ioctl,
#endif
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice megaraid_mm_dev = {
@@ -98,7 +100,6 @@ mraid_mm_open(struct inode *inode, struct file *filep)
*/
if (!capable(CAP_SYS_ADMIN)) return (-EACCES);
- cycle_kernel_lock();
return 0;
}
@@ -224,9 +225,9 @@ mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd,
int err;
/* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */
- lock_kernel();
+ mutex_lock(&mraid_mm_mutex);
err = mraid_mm_ioctl(filep, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&mraid_mm_mutex);
return err;
}
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 99e4478c3f3e..6c0f501f1c73 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -33,7 +33,6 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/uio.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -3557,7 +3556,6 @@ static void megasas_shutdown(struct pci_dev *pdev)
*/
static int megasas_mgmt_open(struct inode *inode, struct file *filep)
{
- cycle_kernel_lock();
/*
* Allow only those users with admin rights
*/
@@ -3957,6 +3955,7 @@ static const struct file_operations megasas_mgmt_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = megasas_mgmt_compat_ioctl,
#endif
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 57bcd5c9dcff..12faf64f91b0 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -534,7 +534,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
if (event_data->DiscoveryStatus)
printk("discovery_status(0x%08x)",
le32_to_cpu(event_data->DiscoveryStatus));
- printk("\n");
+ printk("\n");
return;
}
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index b774973f0765..1eb40508ca44 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -51,7 +51,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compat.h>
#include <linux/poll.h>
@@ -61,6 +61,7 @@
#include "mpt2sas_base.h"
#include "mpt2sas_ctl.h"
+static DEFINE_MUTEX(_ctl_mutex);
static struct fasync_struct *async_queue;
static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);
@@ -2238,9 +2239,9 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&_ctl_mutex);
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
- unlock_kernel();
+ mutex_unlock(&_ctl_mutex);
return ret;
}
@@ -2309,12 +2310,12 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&_ctl_mutex);
if (cmd == MPT2COMMAND32)
ret = _ctl_compat_mpt_command(file, cmd, arg);
else
ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
- unlock_kernel();
+ mutex_unlock(&_ctl_mutex);
return ret;
}
#endif
@@ -2952,6 +2953,7 @@ static const struct file_operations ctl_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = _ctl_ioctl_compat,
#endif
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice ctl_dev = {
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index fda4de3440c4..e88bbdde49c5 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -865,7 +865,7 @@ void osd_req_read(struct osd_request *or,
{
_osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len);
WARN_ON(or->in.bio || or->in.total_bytes);
- WARN_ON(1 == (bio->bi_rw & REQ_WRITE));
+ WARN_ON(bio->bi_rw & REQ_WRITE);
or->in.bio = bio;
or->in.total_bytes = len;
}
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index ffdd9fdb9995..cefb2c089d67 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -182,6 +182,7 @@ static const struct file_operations osd_fops = {
.open = osd_uld_open,
.release = osd_uld_release,
.unlocked_ioctl = osd_uld_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
struct osd_dev *osduld_path_lookup(const char *name)
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 278b352ae78d..54de1d1af1a7 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -51,7 +51,7 @@ static const char * osst_version = "0.99.4";
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#include <asm/system.h>
@@ -80,6 +80,7 @@ static const char * osst_version = "0.99.4";
#include "osst_options.h"
#include "osst_detect.h"
+static DEFINE_MUTEX(osst_int_mutex);
static int max_dev = 0;
static int write_threshold_kbs = 0;
static int max_sg_segs = 0;
@@ -4807,9 +4808,9 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
{
int ret;
- lock_kernel();
+ mutex_lock(&osst_int_mutex);
ret = __os_scsi_tape_open(inode, filp);
- unlock_kernel();
+ mutex_unlock(&osst_int_mutex);
return ret;
}
@@ -4943,9 +4944,9 @@ static long osst_ioctl(struct file * file,
char * name = tape_name(STp);
void __user * p = (void __user *)arg;
- lock_kernel();
+ mutex_lock(&osst_int_mutex);
if (mutex_lock_interruptible(&STp->lock)) {
- unlock_kernel();
+ mutex_unlock(&osst_int_mutex);
return -ERESTARTSYS;
}
@@ -5260,14 +5261,14 @@ static long osst_ioctl(struct file * file,
mutex_unlock(&STp->lock);
retval = scsi_ioctl(STp->device, cmd_in, p);
- unlock_kernel();
+ mutex_unlock(&osst_int_mutex);
return retval;
out:
if (SRpnt) osst_release_request(SRpnt);
mutex_unlock(&STp->lock);
- unlock_kernel();
+ mutex_unlock(&osst_int_mutex);
return retval;
}
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 9793aa6afb10..d8db0137c0c7 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4194,6 +4194,8 @@ static int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
nvmd_type = ioctl_payload->minor_function;
fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+ if (!fw_control_context)
+ return -ENOMEM;
fw_control_context->usrAddr = (u8 *)&ioctl_payload->func_specific[0];
fw_control_context->len = ioctl_payload->length;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
@@ -4272,6 +4274,8 @@ static int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
nvmd_type = ioctl_payload->minor_function;
fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+ if (!fw_control_context)
+ return -ENOMEM;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
ioctl_payload->func_specific,
@@ -4381,6 +4385,8 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
struct pm8001_ioctl_payload *ioctl_payload = payload;
fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
+ if (!fw_control_context)
+ return -ENOMEM;
fw_control = (struct fw_control_info *)&ioctl_payload->func_specific[0];
if (fw_control->len != 0) {
if (pm8001_mem_alloc(pm8001_ha->pdev,
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index ecc45c8b4e6b..24c57e3d5bba 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -4165,6 +4165,7 @@ static const struct file_operations pmcraid_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = pmcraid_chr_ioctl,
#endif
+ .llseek = noop_llseek,/* no read or write fn */
};
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 420238cc794e..3cd794f4d8f1 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1530,6 +1530,15 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
}
static void
+qla2x00_get_host_def_loss_tmo(struct Scsi_Host *shost)
+{
+ scsi_qla_host_t *vha = shost_priv(shost);
+ struct qla_hw_data *ha = vha->hw;
+
+ fc_host_def_dev_loss_tmo(shost) = ha->port_down_retry_count;
+}
+
+static void
qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
{
struct Scsi_Host *host = rport_to_shost(rport);
@@ -1538,22 +1547,22 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
if (!fcport)
return;
- if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
- return;
-
- if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
- qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
- return;
- }
-
/*
* Transport has effectively 'deleted' the rport, clear
* all local references.
*/
spin_lock_irq(host->host_lock);
- fcport->rport = NULL;
+ fcport->rport = fcport->drport = NULL;
*((fc_port_t **)rport->dd_data) = NULL;
spin_unlock_irq(host->host_lock);
+
+ if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
+ return;
+
+ if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
+ qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+ return;
+ }
}
static void
@@ -1676,14 +1685,14 @@ static void
qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
{
scsi_qla_host_t *vha = shost_priv(shost);
- u64 node_name;
+ uint8_t node_name[WWN_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, \
+ 0xFF, 0xFF, 0xFF, 0xFF};
+ u64 fabric_name = wwn_to_u64(node_name);
if (vha->device_flags & SWITCH_FOUND)
- node_name = wwn_to_u64(vha->fabric_node_name);
- else
- node_name = wwn_to_u64(vha->node_name);
+ fabric_name = wwn_to_u64(vha->fabric_node_name);
- fc_host_fabric_name(shost) = node_name;
+ fc_host_fabric_name(shost) = fabric_name;
}
static void
@@ -1838,26 +1847,33 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
qla24xx_disable_vp(vha);
+ vha->flags.delete_progress = 1;
+
fc_remove_host(vha->host);
scsi_remove_host(vha->host);
- qla2x00_free_fcports(vha);
+ if (vha->timer_active) {
+ qla2x00_vp_stop_timer(vha);
+ DEBUG15(printk(KERN_INFO "scsi(%ld): timer for the vport[%d]"
+ " = %p has stopped\n", vha->host_no, vha->vp_idx, vha));
+ }
qla24xx_deallocate_vp_id(vha);
+ /* No pending activities shall be there on the vha now */
+ DEBUG(msleep(random32()%10)); /* Just to see if something falls on
+ * the net we have placed below */
+
+ BUG_ON(atomic_read(&vha->vref_count));
+
+ qla2x00_free_fcports(vha);
+
mutex_lock(&ha->vport_lock);
ha->cur_vport_count--;
clear_bit(vha->vp_idx, ha->vp_idx_map);
mutex_unlock(&ha->vport_lock);
- if (vha->timer_active) {
- qla2x00_vp_stop_timer(vha);
- DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
- "has stopped\n",
- vha->host_no, vha->vp_idx, vha));
- }
-
if (vha->req->id && !ha->flags.cpu_affinity_enabled) {
if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
qla_printk(KERN_WARNING, ha,
@@ -1903,6 +1919,7 @@ struct fc_function_template qla2xxx_transport_functions = {
.show_host_fabric_name = 1,
.get_host_port_state = qla2x00_get_host_port_state,
.show_host_port_state = 1,
+ .get_host_def_dev_loss_tmo = qla2x00_get_host_def_loss_tmo,
.dd_fcrport_size = sizeof(struct fc_port *),
.show_rport_supported_classes = 1,
@@ -1949,6 +1966,7 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
.show_host_fabric_name = 1,
.get_host_port_state = qla2x00_get_host_port_state,
.show_host_port_state = 1,
+ .get_host_def_dev_loss_tmo = qla2x00_get_host_def_loss_tmo,
.dd_fcrport_size = sizeof(struct fc_port *),
.show_rport_supported_classes = 1,
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 9067629817ea..fdfbf83a6330 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1254,10 +1254,9 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
return -EINVAL;
}
- if (fcport->loop_id == FC_NO_LOOP_ID) {
- DEBUG2(printk(KERN_ERR "%s(%ld): Invalid port loop id, "
- "loop_id = 0x%x\n",
- __func__, vha->host_no, fcport->loop_id));
+ if (atomic_read(&fcport->state) != FCS_ONLINE) {
+ DEBUG2(printk(KERN_ERR "%s(%ld): Port not online\n",
+ __func__, vha->host_no));
return -EINVAL;
}
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 6cfc28a25eb3..b74e6b5743dc 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -29,8 +29,6 @@
/* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */
/* #define QL_DEBUG_LEVEL_18 */ /* Output T10 CRC trace messages */
-/* #define QL_PRINTK_BUF */ /* Captures printk to buffer */
-
/*
* Macros use for debugging the driver.
*/
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 3a432ea0c7a3..e1d3ad40a946 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -706,6 +706,11 @@ typedef struct {
#define MBC_SET_PORT_CONFIG 0x122 /* Set port configuration */
#define MBC_GET_PORT_CONFIG 0x123 /* Get port configuration */
+/*
+ * ISP81xx mailbox commands
+ */
+#define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */
+
/* Firmware return data sizes */
#define FCAL_MAP_SIZE 128
@@ -2641,6 +2646,7 @@ struct qla_hw_data {
#define MBX_UPDATE_FLASH_ACTIVE 3
struct mutex vport_lock; /* Virtual port synchronization */
+ spinlock_t vport_slock; /* order is hardware_lock, then vport_slock */
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
struct completion dcbx_comp; /* For set port config notification */
@@ -2828,6 +2834,7 @@ typedef struct scsi_qla_host {
uint32_t management_server_logged_in :1;
uint32_t process_response_queue :1;
uint32_t difdix_supported:1;
+ uint32_t delete_progress:1;
} flags;
atomic_t loop_state;
@@ -2858,6 +2865,7 @@ typedef struct scsi_qla_host {
#define NPIV_CONFIG_NEEDED 16
#define ISP_UNRECOVERABLE 17
#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
+#define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */
uint32_t device_flags;
#define SWITCH_FOUND BIT_0
@@ -2922,6 +2930,8 @@ typedef struct scsi_qla_host {
struct req_que *req;
int fw_heartbeat_counter;
int seconds_since_last_heartbeat;
+
+ atomic_t vref_count;
} scsi_qla_host_t;
/*
@@ -2932,6 +2942,22 @@ typedef struct scsi_qla_host {
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
atomic_read(&ha->loop_state) == LOOP_DOWN)
+#define QLA_VHA_MARK_BUSY(__vha, __bail) do { \
+ atomic_inc(&__vha->vref_count); \
+ mb(); \
+ if (__vha->flags.delete_progress) { \
+ atomic_dec(&__vha->vref_count); \
+ __bail = 1; \
+ } else { \
+ __bail = 0; \
+ } \
+} while (0)
+
+#define QLA_VHA_MARK_NOT_BUSY(__vha) do { \
+ atomic_dec(&__vha->vref_count); \
+} while (0)
+
+
#define qla_printk(level, ha, format, arg...) \
dev_printk(level , &((ha)->pdev->dev) , format , ## arg)
@@ -2983,6 +3009,8 @@ typedef struct scsi_qla_host {
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
+#define QLA_SG_ALL 1024
+
enum nexus_wait_type {
WAIT_HOST = 0,
WAIT_TARGET,
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 1a1b281cea33..c33dec827e1e 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -352,6 +352,8 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *);
extern int
qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);
+extern int
+qla81xx_write_mpi_register(scsi_qla_host_t *, uint16_t *);
extern int qla2x00_get_data_rate(scsi_qla_host_t *);
extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t,
uint16_t *);
@@ -501,7 +503,6 @@ extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
/* PCI related functions */
extern int qla82xx_pci_config(struct scsi_qla_host *);
extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int);
-extern int qla82xx_pci_mem_write_2M(struct qla_hw_data *, u64, void *, int);
extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *);
extern int qla82xx_pci_region_offset(struct pci_dev *, int);
extern int qla82xx_iospace_config(struct qla_hw_data *);
@@ -509,8 +510,8 @@ extern int qla82xx_iospace_config(struct qla_hw_data *);
/* Initialization related functions */
extern void qla82xx_reset_chip(struct scsi_qla_host *);
extern void qla82xx_config_rings(struct scsi_qla_host *);
-extern int qla82xx_pinit_from_rom(scsi_qla_host_t *);
extern void qla82xx_watchdog(scsi_qla_host_t *);
+extern int qla82xx_start_firmware(scsi_qla_host_t *);
/* Firmware and flash related functions */
extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *);
@@ -533,25 +534,17 @@ extern irqreturn_t qla82xx_msix_default(int, void *);
extern irqreturn_t qla82xx_msix_rsp_q(int, void *);
extern void qla82xx_enable_intrs(struct qla_hw_data *);
extern void qla82xx_disable_intrs(struct qla_hw_data *);
-extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
extern void qla82xx_poll(int, void *);
extern void qla82xx_init_flags(struct qla_hw_data *);
/* ISP 8021 hardware related */
-extern int qla82xx_crb_win_lock(struct qla_hw_data *);
+extern void qla82xx_set_drv_active(scsi_qla_host_t *);
extern void qla82xx_crb_win_unlock(struct qla_hw_data *);
-extern int qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *, ulong *);
extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32);
extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int);
extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int);
-extern int qla82xx_check_for_bad_spd(struct qla_hw_data *);
-extern int qla82xx_load_fw(scsi_qla_host_t *);
-extern int qla82xx_rom_lock(struct qla_hw_data *);
extern void qla82xx_rom_unlock(struct qla_hw_data *);
-extern int qla82xx_rom_fast_read(struct qla_hw_data *, int , int *);
-extern int qla82xx_do_rom_fast_read(struct qla_hw_data *, int, int *);
-extern unsigned long qla82xx_decode_crb_addr(unsigned long);
/* ISP 8021 IDC */
extern void qla82xx_clear_drv_active(struct qla_hw_data *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index d863ed2619b5..3cafbef40737 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -69,21 +69,29 @@ qla2x00_ctx_sp_free(srb_t *sp)
{
struct srb_ctx *ctx = sp->ctx;
struct srb_iocb *iocb = ctx->u.iocb_cmd;
+ struct scsi_qla_host *vha = sp->fcport->vha;
del_timer_sync(&iocb->timer);
kfree(iocb);
kfree(ctx);
mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
+
+ QLA_VHA_MARK_NOT_BUSY(vha);
}
inline srb_t *
qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
unsigned long tmo)
{
- srb_t *sp;
+ srb_t *sp = NULL;
struct qla_hw_data *ha = vha->hw;
struct srb_ctx *ctx;
struct srb_iocb *iocb;
+ uint8_t bail;
+
+ QLA_VHA_MARK_BUSY(vha, bail);
+ if (bail)
+ return NULL;
sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
if (!sp)
@@ -116,6 +124,8 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
iocb->timer.function = qla2x00_ctx_sp_timeout;
add_timer(&iocb->timer);
done:
+ if (!sp)
+ QLA_VHA_MARK_NOT_BUSY(vha);
return sp;
}
@@ -944,6 +954,19 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
}
/**
+ * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
+ *
+ * Returns 0 on success.
+ */
+int
+qla81xx_reset_mpi(scsi_qla_host_t *vha)
+{
+ uint16_t mb[4] = {0x1010, 0, 1, 0};
+
+ return qla81xx_write_mpi_register(vha, mb);
+}
+
+/**
* qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
* @ha: HA context
*
@@ -957,6 +980,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
uint32_t cnt, d2;
uint16_t wd;
+ static int abts_cnt; /* ISP abort retry counts */
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -990,6 +1014,23 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
barrier();
}
+ /* If required, do an MPI FW reset now */
+ if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
+ if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) {
+ if (++abts_cnt < 5) {
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ set_bit(MPI_RESET_NEEDED, &vha->dpc_flags);
+ } else {
+ /*
+ * We exhausted the ISP abort retries. We have to
+ * set the board offline.
+ */
+ abts_cnt = 0;
+ vha->flags.online = 0;
+ }
+ }
+ }
+
WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
RD_REG_DWORD(&reg->hccr);
@@ -1777,11 +1818,15 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
qla2x00_init_response_q_entries(rsp);
}
+ spin_lock_irqsave(&ha->vport_slock, flags);
/* Clear RSCN queue. */
list_for_each_entry(vp, &ha->vp_list, list) {
vp->rscn_in_ptr = 0;
vp->rscn_out_ptr = 0;
}
+
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
ha->isp_ops->config_rings(vha);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2785,6 +2830,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
if (!IS_IIDMA_CAPABLE(ha))
return;
+ if (atomic_read(&fcport->state) != FCS_ONLINE)
+ return;
+
if (fcport->fp_speed == PORT_SPEED_UNKNOWN ||
fcport->fp_speed > ha->link_data_rate)
return;
@@ -3218,12 +3266,17 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
/* Bypass virtual ports of the same host. */
found = 0;
if (ha->num_vhosts) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
if (new_fcport->d_id.b24 == vp->d_id.b24) {
found = 1;
break;
}
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
if (found)
continue;
}
@@ -3343,6 +3396,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp;
struct scsi_qla_host *tvp;
+ unsigned long flags = 0;
rval = QLA_SUCCESS;
@@ -3367,6 +3421,8 @@ 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;
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
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 &&
@@ -3379,6 +3435,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
if (found)
break;
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
/* If not in use then it is free to use. */
if (!found) {
@@ -3791,14 +3848,27 @@ void
qla2x00_update_fcports(scsi_qla_host_t *base_vha)
{
fc_port_t *fcport;
- struct scsi_qla_host *tvp, *vha;
+ struct scsi_qla_host *vha;
+ struct qla_hw_data *ha = base_vha->hw;
+ unsigned long flags;
+ spin_lock_irqsave(&ha->vport_slock, flags);
/* Go with deferred removal of rport references. */
- list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list)
- list_for_each_entry(fcport, &vha->vp_fcports, list)
+ list_for_each_entry(vha, &base_vha->hw->vp_list, list) {
+ atomic_inc(&vha->vref_count);
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport && fcport->drport &&
- atomic_read(&fcport->state) != FCS_UNCONFIGURED)
+ atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
qla2x00_rport_del(fcport);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ }
+ }
+ atomic_dec(&vha->vref_count);
+ }
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
}
void
@@ -3806,7 +3876,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
- struct scsi_qla_host *tvp;
+ unsigned long flags;
vha->flags.online = 0;
ha->flags.chip_reset_done = 0;
@@ -3824,25 +3894,37 @@ qla2x00_abort_isp_cleanup(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_safe(vp, tvp, &base_vha->hw->vp_list, list)
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vp, &base_vha->hw->vp_list, list) {
+ atomic_inc(&vp->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
qla2x00_mark_all_devices_lost(vp, 0);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ atomic_dec(&vp->vref_count);
+ }
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
}
- /* Make sure for ISP 82XX IO DMA is complete */
- if (IS_QLA82XX(ha)) {
- if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
- WAIT_HOST) == QLA_SUCCESS) {
- DEBUG2(qla_printk(KERN_INFO, ha,
- "Done wait for pending commands\n"));
+ if (!ha->flags.eeh_busy) {
+ /* Make sure for ISP 82XX IO DMA is complete */
+ if (IS_QLA82XX(ha)) {
+ if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
+ WAIT_HOST) == QLA_SUCCESS) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Done wait for pending commands\n"));
+ }
}
- }
- /* Requeue all commands in outstanding command list. */
- qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+ /* Requeue all commands in outstanding command list. */
+ qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+ }
}
/*
@@ -3862,8 +3944,8 @@ 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];
+ unsigned long flags;
if (vha->flags.online) {
qla2x00_abort_isp_cleanup(vha);
@@ -3970,10 +4052,21 @@ 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_safe(vp, tvp, &ha->vp_list, list) {
- if (vp->vp_idx)
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vp, &ha->vp_list, list) {
+ if (vp->vp_idx) {
+ atomic_inc(&vp->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
qla2x00_vp_abort_isp(vp);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ atomic_dec(&vp->vref_count);
+ }
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
} else {
qla_printk(KERN_INFO, ha,
"qla2x00_abort_isp: **** FAILED ****\n");
@@ -5185,7 +5278,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
struct req_que *req = ha->req_q_map[0];
struct rsp_que *rsp = ha->rsp_q_map[0];
struct scsi_qla_host *vp;
- struct scsi_qla_host *tvp;
+ unsigned long flags;
status = qla2x00_init_rings(vha);
if (!status) {
@@ -5272,10 +5365,21 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
DEBUG(printk(KERN_INFO
"qla82xx_restart_isp(%ld): succeeded.\n",
vha->host_no));
- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
- if (vp->vp_idx)
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vp, &ha->vp_list, list) {
+ if (vp->vp_idx) {
+ atomic_inc(&vp->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
qla2x00_vp_abort_isp(vp);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ atomic_dec(&vp->vref_count);
+ }
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
} else {
qla_printk(KERN_INFO, ha,
"qla82xx_restart_isp: **** FAILED ****\n");
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6982ba70e12a..e0e43d9e7ed1 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -412,8 +412,14 @@ skip_rio:
"Unrecoverable Hardware Error: adapter "
"marked OFFLINE!\n");
vha->flags.online = 0;
- } else
+ } else {
+ /* Check to see if MPI timeout occured */
+ if ((mbx & MBX_3) && (ha->flags.port0))
+ set_bit(MPI_RESET_NEEDED,
+ &vha->dpc_flags);
+
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ }
} else if (mb[1] == 0) {
qla_printk(KERN_INFO, ha,
"Unrecoverable Hardware Error: adapter marked "
@@ -1706,19 +1712,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
cp->result = DID_ERROR << 16;
break;
}
- } else if (!lscsi_status) {
+ } else {
DEBUG2(qla_printk(KERN_INFO, ha,
"scsi(%ld:%d:%d) Dropped frame(s) detected (0x%x "
"of 0x%x bytes).\n", vha->host_no, cp->device->id,
cp->device->lun, resid, scsi_bufflen(cp)));
- cp->result = DID_ERROR << 16;
- break;
+ cp->result = DID_ERROR << 16 | lscsi_status;
+ goto check_scsi_status;
}
cp->result = DID_OK << 16 | lscsi_status;
logit = 0;
+check_scsi_status:
/*
* Check to see if SCSI Status is non zero. If so report SCSI
* Status.
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 6009b0c69488..effd8a1403d9 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2913,7 +2913,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;
+ unsigned long flags;
if (rptid_entry->entry_status != 0)
return;
@@ -2945,9 +2945,12 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
return;
}
- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vp, &ha->vp_list, list)
if (vp_idx == vp->vp_idx)
break;
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
if (!vp)
return;
@@ -3825,8 +3828,6 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
/* Copy mailbox information */
memcpy( mresp, mcp->mb, 64);
- mresp[3] = mcp->mb[18];
- mresp[4] = mcp->mb[19];
return rval;
}
@@ -3887,9 +3888,10 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
}
/* Copy mailbox information */
- memcpy( mresp, mcp->mb, 32);
+ memcpy(mresp, mcp->mb, 64);
return rval;
}
+
int
qla84xx_reset_chip(scsi_qla_host_t *ha, uint16_t enable_diagnostic)
{
@@ -3950,6 +3952,67 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
}
int
+qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
+{
+ int rval;
+ uint32_t stat, timer;
+ uint16_t mb0 = 0;
+ struct qla_hw_data *ha = vha->hw;
+ struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+ rval = QLA_SUCCESS;
+
+ DEBUG11(qla_printk(KERN_INFO, ha,
+ "%s(%ld): entered.\n", __func__, vha->host_no));
+
+ clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+ /* Write the MBC data to the registers */
+ WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
+ WRT_REG_WORD(&reg->mailbox1, mb[0]);
+ WRT_REG_WORD(&reg->mailbox2, mb[1]);
+ WRT_REG_WORD(&reg->mailbox3, mb[2]);
+ WRT_REG_WORD(&reg->mailbox4, mb[3]);
+
+ WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+
+ /* Poll for MBC interrupt */
+ for (timer = 6000000; timer; timer--) {
+ /* Check for pending interrupts. */
+ stat = RD_REG_DWORD(&reg->host_status);
+ if (stat & HSRX_RISC_INT) {
+ stat &= 0xff;
+
+ if (stat == 0x1 || stat == 0x2 ||
+ stat == 0x10 || stat == 0x11) {
+ set_bit(MBX_INTERRUPT,
+ &ha->mbx_cmd_flags);
+ mb0 = RD_REG_WORD(&reg->mailbox0);
+ WRT_REG_DWORD(&reg->hccr,
+ HCCRX_CLR_RISC_INT);
+ RD_REG_DWORD(&reg->hccr);
+ break;
+ }
+ }
+ udelay(5);
+ }
+
+ if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
+ rval = mb0 & MBS_MASK;
+ else
+ rval = QLA_FUNCTION_FAILED;
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n",
+ __func__, vha->host_no, rval, mb[0]));
+ } else {
+ DEBUG11(printk(KERN_INFO
+ "%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+int
qla2x00_get_data_rate(scsi_qla_host_t *vha)
{
int rval;
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 987c5b0ca78e..2b69392a71a1 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -30,6 +30,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
{
uint32_t vp_id;
struct qla_hw_data *ha = vha->hw;
+ unsigned long flags;
/* Find an empty slot and assign an vp_id */
mutex_lock(&ha->vport_lock);
@@ -44,7 +45,11 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
set_bit(vp_id, ha->vp_idx_map);
ha->num_vhosts++;
vha->vp_idx = vp_id;
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
list_add_tail(&vha->list, &ha->vp_list);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
mutex_unlock(&ha->vport_lock);
return vp_id;
}
@@ -54,12 +59,31 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
{
uint16_t vp_id;
struct qla_hw_data *ha = vha->hw;
+ unsigned long flags = 0;
mutex_lock(&ha->vport_lock);
+ /*
+ * Wait for all pending activities to finish before removing vport from
+ * the list.
+ * Lock needs to be held for safe removal from the list (it
+ * ensures no active vp_list traversal while the vport is removed
+ * from the queue)
+ */
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ while (atomic_read(&vha->vref_count)) {
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
+ msleep(500);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ }
+ list_del(&vha->list);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
vp_id = vha->vp_idx;
ha->num_vhosts--;
clear_bit(vp_id, ha->vp_idx_map);
- list_del(&vha->list);
+
mutex_unlock(&ha->vport_lock);
}
@@ -68,12 +92,17 @@ qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name)
{
scsi_qla_host_t *vha;
struct scsi_qla_host *tvha;
+ unsigned long flags;
+ spin_lock_irqsave(&ha->vport_slock, flags);
/* Locate matching device in database. */
list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
- if (!memcmp(port_name, vha->port_name, WWN_SIZE))
+ if (!memcmp(port_name, vha->port_name, WWN_SIZE)) {
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
return vha;
+ }
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
return NULL;
}
@@ -93,6 +122,12 @@ qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name)
static void
qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
{
+ /*
+ * !!! NOTE !!!
+ * This function, if called in contexts other than vp create, disable
+ * or delete, please make sure this is synchronized with the
+ * delete thread.
+ */
fc_port_t *fcport;
list_for_each_entry(fcport, &vha->vp_fcports, list) {
@@ -100,7 +135,6 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
"loop_id=0x%04x :%x\n",
vha->host_no, fcport->loop_id, fcport->vp_idx));
- atomic_set(&fcport->state, FCS_DEVICE_DEAD);
qla2x00_mark_device_lost(vha, fcport, 0, 0);
atomic_set(&fcport->state, FCS_UNCONFIGURED);
}
@@ -194,12 +228,17 @@ 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, *tvha;
+ scsi_qla_host_t *vha;
struct qla_hw_data *ha = rsp->hw;
int i = 0;
+ unsigned long flags;
- list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vha, &ha->vp_list, list) {
if (vha->vp_idx) {
+ atomic_inc(&vha->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
switch (mb[0]) {
case MBA_LIP_OCCURRED:
case MBA_LOOP_UP:
@@ -215,9 +254,13 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
qla2x00_async_event(vha, rsp, mb);
break;
}
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ atomic_dec(&vha->vref_count);
}
i++;
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
}
int
@@ -297,7 +340,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;
+ unsigned long flags = 0;
if (vha->vp_idx)
return;
@@ -309,10 +352,19 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
if (!(ha->current_topology & ISP_CFG_F))
return;
- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
- if (vp->vp_idx)
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vp, &ha->vp_list, list) {
+ if (vp->vp_idx) {
+ atomic_inc(&vp->vref_count);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
ret = qla2x00_do_dpc_vp(vp);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ atomic_dec(&vp->vref_count);
+ }
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
}
int
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 915b77a6e193..c5ac87615db6 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -403,6 +403,54 @@ qla82xx_pci_set_crbwindow(struct qla_hw_data *ha, u64 off)
return off;
}
+static int
+qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong *off)
+{
+ struct crb_128M_2M_sub_block_map *m;
+
+ if (*off >= QLA82XX_CRB_MAX)
+ return -1;
+
+ if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) {
+ *off = (*off - QLA82XX_PCI_CAMQM) +
+ QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase;
+ return 0;
+ }
+
+ if (*off < QLA82XX_PCI_CRBSPACE)
+ return -1;
+
+ *off -= QLA82XX_PCI_CRBSPACE;
+
+ /* Try direct map */
+ m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
+
+ if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
+ *off = *off + m->start_2M - m->start_128M + ha->nx_pcibase;
+ return 0;
+ }
+ /* Not in direct map, use crb window */
+ return 1;
+}
+
+#define CRB_WIN_LOCK_TIMEOUT 100000000
+static int qla82xx_crb_win_lock(struct qla_hw_data *ha)
+{
+ int done = 0, timeout = 0;
+
+ while (!done) {
+ /* acquire semaphore3 from PCI HW block */
+ done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
+ if (done == 1)
+ break;
+ if (timeout >= CRB_WIN_LOCK_TIMEOUT)
+ return -1;
+ timeout++;
+ }
+ qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum);
+ return 0;
+}
+
int
qla82xx_wr_32(struct qla_hw_data *ha, ulong off, u32 data)
{
@@ -453,24 +501,6 @@ qla82xx_rd_32(struct qla_hw_data *ha, ulong off)
return data;
}
-#define CRB_WIN_LOCK_TIMEOUT 100000000
-int qla82xx_crb_win_lock(struct qla_hw_data *ha)
-{
- int done = 0, timeout = 0;
-
- while (!done) {
- /* acquire semaphore3 from PCI HW block */
- done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
- if (done == 1)
- break;
- if (timeout >= CRB_WIN_LOCK_TIMEOUT)
- return -1;
- timeout++;
- }
- qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum);
- return 0;
-}
-
#define IDC_LOCK_TIMEOUT 100000000
int qla82xx_idc_lock(struct qla_hw_data *ha)
{
@@ -504,36 +534,6 @@ void qla82xx_idc_unlock(struct qla_hw_data *ha)
qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));
}
-int
-qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong *off)
-{
- struct crb_128M_2M_sub_block_map *m;
-
- if (*off >= QLA82XX_CRB_MAX)
- return -1;
-
- if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) {
- *off = (*off - QLA82XX_PCI_CAMQM) +
- QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase;
- return 0;
- }
-
- if (*off < QLA82XX_PCI_CRBSPACE)
- return -1;
-
- *off -= QLA82XX_PCI_CRBSPACE;
-
- /* Try direct map */
- m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
-
- if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
- *off = *off + m->start_2M - m->start_128M + ha->nx_pcibase;
- return 0;
- }
- /* Not in direct map, use crb window */
- return 1;
-}
-
/* PCI Windowing for DDR regions. */
#define QLA82XX_ADDR_IN_RANGE(addr, low, high) \
(((addr) <= (high)) && ((addr) >= (low)))
@@ -557,7 +557,7 @@ qla82xx_pci_mem_bound_check(struct qla_hw_data *ha,
int qla82xx_pci_set_window_warning_count;
-unsigned long
+static unsigned long
qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr)
{
int window;
@@ -798,7 +798,8 @@ qla82xx_pci_mem_write_direct(struct qla_hw_data *ha,
}
#define MTU_FUDGE_FACTOR 100
-unsigned long qla82xx_decode_crb_addr(unsigned long addr)
+static unsigned long
+qla82xx_decode_crb_addr(unsigned long addr)
{
int i;
unsigned long base_addr, offset, pci_base;
@@ -824,7 +825,7 @@ unsigned long qla82xx_decode_crb_addr(unsigned long addr)
static long rom_max_timeout = 100;
static long qla82xx_rom_lock_timeout = 100;
-int
+static int
qla82xx_rom_lock(struct qla_hw_data *ha)
{
int done = 0, timeout = 0;
@@ -842,7 +843,7 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
return 0;
}
-int
+static int
qla82xx_wait_rom_busy(struct qla_hw_data *ha)
{
long timeout = 0;
@@ -862,7 +863,7 @@ qla82xx_wait_rom_busy(struct qla_hw_data *ha)
return 0;
}
-int
+static int
qla82xx_wait_rom_done(struct qla_hw_data *ha)
{
long timeout = 0;
@@ -882,7 +883,7 @@ qla82xx_wait_rom_done(struct qla_hw_data *ha)
return 0;
}
-int
+static int
qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
{
qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
@@ -905,7 +906,7 @@ qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
return 0;
}
-int
+static int
qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
{
int ret, loops = 0;
@@ -926,7 +927,7 @@ qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
return ret;
}
-int
+static int
qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
{
qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR);
@@ -940,7 +941,7 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
return 0;
}
-int
+static int
qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
{
long timeout = 0;
@@ -964,7 +965,7 @@ qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
return ret;
}
-int
+static int
qla82xx_flash_set_write_enable(struct qla_hw_data *ha)
{
uint32_t val;
@@ -981,7 +982,7 @@ qla82xx_flash_set_write_enable(struct qla_hw_data *ha)
return 0;
}
-int
+static int
qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val)
{
if (qla82xx_flash_set_write_enable(ha))
@@ -996,7 +997,7 @@ qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val)
return qla82xx_flash_wait_write_finish(ha);
}
-int
+static int
qla82xx_write_disable_flash(struct qla_hw_data *ha)
{
qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI);
@@ -1008,7 +1009,7 @@ qla82xx_write_disable_flash(struct qla_hw_data *ha)
return 0;
}
-int
+static int
ql82xx_rom_lock_d(struct qla_hw_data *ha)
{
int loops = 0;
@@ -1024,7 +1025,7 @@ ql82xx_rom_lock_d(struct qla_hw_data *ha)
return 0;;
}
-int
+static int
qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr,
uint32_t data)
{
@@ -1061,7 +1062,8 @@ done_write:
/* This routine does CRB initialize sequence
* to put the ISP into operational state
*/
-int qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
+static int
+qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
{
int addr, val;
int i ;
@@ -1207,7 +1209,8 @@ int qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
return 0;
}
-int qla82xx_check_for_bad_spd(struct qla_hw_data *ha)
+static int
+qla82xx_check_for_bad_spd(struct qla_hw_data *ha)
{
u32 val = 0;
val = qla82xx_rd_32(ha, BOOT_LOADER_DIMM_STATUS);
@@ -1225,7 +1228,116 @@ int qla82xx_check_for_bad_spd(struct qla_hw_data *ha)
return 0;
}
-int
+static int
+qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
+ u64 off, void *data, int size)
+{
+ int i, j, ret = 0, loop, sz[2], off0;
+ int scale, shift_amount, startword;
+ uint32_t temp;
+ uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
+
+ /*
+ * If not MN, go check for MS or invalid.
+ */
+ if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
+ mem_crb = QLA82XX_CRB_QDR_NET;
+ else {
+ mem_crb = QLA82XX_CRB_DDR_NET;
+ if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)
+ return qla82xx_pci_mem_write_direct(ha,
+ off, data, size);
+ }
+
+ off0 = off & 0x7;
+ sz[0] = (size < (8 - off0)) ? size : (8 - off0);
+ sz[1] = size - sz[0];
+
+ off8 = off & 0xfffffff0;
+ loop = (((off & 0xf) + size - 1) >> 4) + 1;
+ shift_amount = 4;
+ scale = 2;
+ startword = (off & 0xf)/8;
+
+ for (i = 0; i < loop; i++) {
+ if (qla82xx_pci_mem_read_2M(ha, off8 +
+ (i << shift_amount), &word[i * scale], 8))
+ return -1;
+ }
+
+ switch (size) {
+ case 1:
+ tmpw = *((uint8_t *)data);
+ break;
+ case 2:
+ tmpw = *((uint16_t *)data);
+ break;
+ case 4:
+ tmpw = *((uint32_t *)data);
+ break;
+ case 8:
+ default:
+ tmpw = *((uint64_t *)data);
+ break;
+ }
+
+ if (sz[0] == 8) {
+ word[startword] = tmpw;
+ } else {
+ word[startword] &=
+ ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
+ word[startword] |= tmpw << (off0 * 8);
+ }
+ if (sz[1] != 0) {
+ word[startword+1] &= ~(~0ULL << (sz[1] * 8));
+ word[startword+1] |= tmpw >> (sz[0] * 8);
+ }
+
+ /*
+ * don't lock here - write_wx gets the lock if each time
+ * write_lock_irqsave(&adapter->adapter_lock, flags);
+ * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+ */
+ for (i = 0; i < loop; i++) {
+ temp = off8 + (i << shift_amount);
+ qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
+ temp = 0;
+ qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
+ temp = word[i * scale] & 0xffffffff;
+ qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
+ temp = (word[i * scale] >> 32) & 0xffffffff;
+ qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
+ temp = word[i*scale + 1] & 0xffffffff;
+ qla82xx_wr_32(ha, mem_crb +
+ MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
+ temp = (word[i*scale + 1] >> 32) & 0xffffffff;
+ qla82xx_wr_32(ha, mem_crb +
+ MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
+
+ temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+ qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
+ temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+ qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
+
+ for (j = 0; j < MAX_CTL_CHECK; j++) {
+ temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
+ if ((temp & MIU_TA_CTL_BUSY) == 0)
+ break;
+ }
+
+ if (j >= MAX_CTL_CHECK) {
+ if (printk_ratelimit())
+ dev_err(&ha->pdev->dev,
+ "failed to write through agent\n");
+ ret = -1;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int
qla82xx_fw_load_from_flash(struct qla_hw_data *ha)
{
int i;
@@ -1357,114 +1469,6 @@ qla82xx_pci_mem_read_2M(struct qla_hw_data *ha,
return 0;
}
-int
-qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,
- u64 off, void *data, int size)
-{
- int i, j, ret = 0, loop, sz[2], off0;
- int scale, shift_amount, startword;
- uint32_t temp;
- uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
-
- /*
- * If not MN, go check for MS or invalid.
- */
- if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
- mem_crb = QLA82XX_CRB_QDR_NET;
- else {
- mem_crb = QLA82XX_CRB_DDR_NET;
- if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)
- return qla82xx_pci_mem_write_direct(ha,
- off, data, size);
- }
-
- off0 = off & 0x7;
- sz[0] = (size < (8 - off0)) ? size : (8 - off0);
- sz[1] = size - sz[0];
-
- off8 = off & 0xfffffff0;
- loop = (((off & 0xf) + size - 1) >> 4) + 1;
- shift_amount = 4;
- scale = 2;
- startword = (off & 0xf)/8;
-
- for (i = 0; i < loop; i++) {
- if (qla82xx_pci_mem_read_2M(ha, off8 +
- (i << shift_amount), &word[i * scale], 8))
- return -1;
- }
-
- switch (size) {
- case 1:
- tmpw = *((uint8_t *)data);
- break;
- case 2:
- tmpw = *((uint16_t *)data);
- break;
- case 4:
- tmpw = *((uint32_t *)data);
- break;
- case 8:
- default:
- tmpw = *((uint64_t *)data);
- break;
- }
-
- if (sz[0] == 8) {
- word[startword] = tmpw;
- } else {
- word[startword] &=
- ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
- word[startword] |= tmpw << (off0 * 8);
- }
- if (sz[1] != 0) {
- word[startword+1] &= ~(~0ULL << (sz[1] * 8));
- word[startword+1] |= tmpw >> (sz[0] * 8);
- }
-
- /*
- * don't lock here - write_wx gets the lock if each time
- * write_lock_irqsave(&adapter->adapter_lock, flags);
- * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
- */
- for (i = 0; i < loop; i++) {
- temp = off8 + (i << shift_amount);
- qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
- temp = 0;
- qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
- temp = word[i * scale] & 0xffffffff;
- qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
- temp = (word[i * scale] >> 32) & 0xffffffff;
- qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
- temp = word[i*scale + 1] & 0xffffffff;
- qla82xx_wr_32(ha, mem_crb +
- MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
- temp = (word[i*scale + 1] >> 32) & 0xffffffff;
- qla82xx_wr_32(ha, mem_crb +
- MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
-
- temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
- temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
-
- for (j = 0; j < MAX_CTL_CHECK; j++) {
- temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
- if ((temp & MIU_TA_CTL_BUSY) == 0)
- break;
- }
-
- if (j >= MAX_CTL_CHECK) {
- if (printk_ratelimit())
- dev_err(&ha->pdev->dev,
- "failed to write through agent\n");
- ret = -1;
- break;
- }
- }
-
- return ret;
-}
static struct qla82xx_uri_table_desc *
qla82xx_get_table_desc(const u8 *unirom, int section)
@@ -1725,7 +1729,8 @@ void qla82xx_reset_adapter(struct scsi_qla_host *vha)
ha->isp_ops->disable_intrs(ha);
}
-int qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
+static int
+qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
{
u64 *ptr64;
u32 i, flashaddr, size;
@@ -1836,7 +1841,8 @@ qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type)
return 0;
}
-int qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)
+static int
+qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)
{
u32 val = 0;
int retries = 60;
@@ -1874,7 +1880,8 @@ int qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)
return QLA_FUNCTION_FAILED;
}
-int qla82xx_check_rcvpeg_state(struct qla_hw_data *ha)
+static int
+qla82xx_check_rcvpeg_state(struct qla_hw_data *ha)
{
u32 val = 0;
int retries = 60;
@@ -1933,7 +1940,7 @@ static struct qla82xx_legacy_intr_set legacy_intr[] = \
* @ha: SCSI driver HA context
* @mb0: Mailbox0 register
*/
-void
+static void
qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
{
uint16_t cnt;
@@ -2257,7 +2264,7 @@ void qla82xx_init_flags(struct qla_hw_data *ha)
ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
}
-static inline void
+inline void
qla82xx_set_drv_active(scsi_qla_host_t *vha)
{
uint32_t drv_active;
@@ -2267,10 +2274,11 @@ qla82xx_set_drv_active(scsi_qla_host_t *vha)
/* If reset value is all FF's, initialize DRV_ACTIVE */
if (drv_active == 0xffffffff) {
- qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, 0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE,
+ QLA82XX_DRV_NOT_ACTIVE);
drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
}
- drv_active |= (1 << (ha->portnum * 4));
+ drv_active |= (QLA82XX_DRV_ACTIVE << (ha->portnum * 4));
qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
}
@@ -2280,7 +2288,7 @@ qla82xx_clear_drv_active(struct qla_hw_data *ha)
uint32_t drv_active;
drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- drv_active &= ~(1 << (ha->portnum * 4));
+ drv_active &= ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4));
qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
}
@@ -2291,7 +2299,7 @@ qla82xx_need_reset(struct qla_hw_data *ha)
int rval;
drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- rval = drv_state & (1 << (ha->portnum * 4));
+ rval = drv_state & (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));
return rval;
}
@@ -2305,7 +2313,7 @@ qla82xx_set_rst_ready(struct qla_hw_data *ha)
/* If reset value is all FF's, initialize DRV_STATE */
if (drv_state == 0xffffffff) {
- qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, QLA82XX_DRVST_NOT_RDY);
drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
}
drv_state |= (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));
@@ -2335,7 +2343,8 @@ qla82xx_set_qsnt_ready(struct qla_hw_data *ha)
qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
}
-int qla82xx_load_fw(scsi_qla_host_t *vha)
+static int
+qla82xx_load_fw(scsi_qla_host_t *vha)
{
int rst;
struct fw_blob *blob;
@@ -2411,7 +2420,7 @@ fw_load_failed:
return QLA_FUNCTION_FAILED;
}
-static int
+int
qla82xx_start_firmware(scsi_qla_host_t *vha)
{
int pcie_cap;
@@ -2419,7 +2428,7 @@ qla82xx_start_firmware(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
/* scrub dma mask expansion register */
- qla82xx_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
+ qla82xx_wr_32(ha, CRB_DMA_SHIFT, QLA82XX_DMA_SHIFT_VALUE);
/* Put both the PEG CMD and RCV PEG to default state
* of 0 before resetting the hardware
@@ -2672,6 +2681,19 @@ qla82xx_start_scsi(srb_t *sp)
sufficient_dsds:
req_cnt = 1;
+ if (req->cnt < (req_cnt + 2)) {
+ cnt = (uint16_t)RD_REG_DWORD_RELAXED(
+ &reg->req_q_out[0]);
+ if (req->ring_index < cnt)
+ req->cnt = cnt - req->ring_index;
+ else
+ req->cnt = req->length -
+ (req->ring_index - cnt);
+ }
+
+ if (req->cnt < (req_cnt + 2))
+ goto queuing_error;
+
ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
if (!sp->ctx) {
DEBUG(printk(KERN_INFO
@@ -2869,7 +2891,7 @@ queuing_error:
return QLA_FUNCTION_FAILED;
}
-uint32_t *
+static uint32_t *
qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
uint32_t length)
{
@@ -2890,7 +2912,7 @@ done_read:
return dwptr;
}
-int
+static int
qla82xx_unprotect_flash(struct qla_hw_data *ha)
{
int ret;
@@ -2921,7 +2943,7 @@ done_unprotect:
return ret;
}
-int
+static int
qla82xx_protect_flash(struct qla_hw_data *ha)
{
int ret;
@@ -2950,7 +2972,7 @@ done_protect:
return ret;
}
-int
+static int
qla82xx_erase_sector(struct qla_hw_data *ha, int addr)
{
int ret = 0;
@@ -3291,6 +3313,9 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
fw_heartbeat_counter = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+ /* all 0xff, assume AER/EEH in progress, ignore */
+ if (fw_heartbeat_counter == 0xffffffff)
+ return;
if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
vha->seconds_since_last_heartbeat++;
/* FW not alive after 2 seconds */
@@ -3307,16 +3332,19 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha)
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
}
qla2xxx_wake_dpc(vha);
+ ha->flags.fw_hung = 1;
if (ha->flags.mbox_busy) {
- ha->flags.fw_hung = 1;
ha->flags.mbox_int = 1;
DEBUG2(qla_printk(KERN_ERR, ha,
- "Due to fw hung, doing premature "
- "completion of mbx command\n"));
- complete(&ha->mbx_intr_comp);
+ "Due to fw hung, doing premature "
+ "completion of mbx command\n"));
+ if (test_bit(MBX_INTR_WAIT,
+ &ha->mbx_cmd_flags))
+ complete(&ha->mbx_intr_comp);
}
}
- }
+ } else
+ vha->seconds_since_last_heartbeat = 0;
vha->fw_heartbeat_counter = fw_heartbeat_counter;
}
@@ -3418,13 +3446,15 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
"%s(): Adapter reset needed!\n", __func__);
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
+ ha->flags.fw_hung = 1;
if (ha->flags.mbox_busy) {
- ha->flags.fw_hung = 1;
ha->flags.mbox_int = 1;
DEBUG2(qla_printk(KERN_ERR, ha,
- "Need reset, doing premature "
- "completion of mbx command\n"));
- complete(&ha->mbx_intr_comp);
+ "Need reset, doing premature "
+ "completion of mbx command\n"));
+ if (test_bit(MBX_INTR_WAIT,
+ &ha->mbx_cmd_flags))
+ complete(&ha->mbx_intr_comp);
}
} else {
qla82xx_check_fw_alive(vha);
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index 15559cab39f8..51ec0c5380e8 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -26,6 +26,7 @@
#define CRB_RCVPEG_STATE QLA82XX_REG(0x13c)
#define BOOT_LOADER_DIMM_STATUS QLA82XX_REG(0x54)
#define CRB_DMA_SHIFT QLA82XX_REG(0xcc)
+#define QLA82XX_DMA_SHIFT_VALUE 0x55555555
#define QLA82XX_HW_H0_CH_HUB_ADR 0x05
#define QLA82XX_HW_H1_CH_HUB_ADR 0x0E
@@ -583,6 +584,10 @@
#define QLA82XX_DRVST_RST_RDY 1
#define QLA82XX_DRVST_QSNT_RDY 2
+/* Different drive active state */
+#define QLA82XX_DRV_NOT_ACTIVE 0
+#define QLA82XX_DRV_ACTIVE 1
+
/*
* The PCI VendorID and DeviceID for our board.
*/
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 8c80b49ac1c4..eb0851bac45d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1295,17 +1295,12 @@ static int
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 = vha->req;
if (sdev->tagged_supported)
scsi_activate_tcq(sdev, req->max_q_depth);
else
scsi_deactivate_tcq(sdev, req->max_q_depth);
-
- rport->dev_loss_tmo = ha->port_down_retry_count;
-
return 0;
}
@@ -2141,8 +2136,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
else
base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
base_vha->vp_idx;
- if (IS_QLA2100(ha))
- host->sg_tablesize = 32;
+
+ /* Set the SG table size based on ISP type */
+ if (!IS_FWI2_CAPABLE(ha)) {
+ if (IS_QLA2100(ha))
+ host->sg_tablesize = 32;
+ } else {
+ if (!IS_QLA82XX(ha))
+ host->sg_tablesize = QLA_SG_ALL;
+ }
+
host->max_id = max_id;
host->this_id = 255;
host->cmd_per_lun = 3;
@@ -2341,16 +2344,28 @@ probe_out:
static void
qla2x00_remove_one(struct pci_dev *pdev)
{
- scsi_qla_host_t *base_vha, *vha, *temp;
+ scsi_qla_host_t *base_vha, *vha;
struct qla_hw_data *ha;
+ unsigned long flags;
base_vha = pci_get_drvdata(pdev);
ha = base_vha->hw;
- list_for_each_entry_safe(vha, temp, &ha->vp_list, list) {
- if (vha && vha->fc_vport)
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ list_for_each_entry(vha, &ha->vp_list, list) {
+ atomic_inc(&vha->vref_count);
+
+ if (vha && vha->fc_vport) {
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
+
fc_vport_terminate(vha->fc_vport);
+
+ spin_lock_irqsave(&ha->vport_slock, flags);
+ }
+
+ atomic_dec(&vha->vref_count);
}
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
set_bit(UNLOADING, &base_vha->dpc_flags);
@@ -2975,10 +2990,17 @@ static struct qla_work_evt *
qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
{
struct qla_work_evt *e;
+ uint8_t bail;
+
+ QLA_VHA_MARK_BUSY(vha, bail);
+ if (bail)
+ return NULL;
e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC);
- if (!e)
+ if (!e) {
+ QLA_VHA_MARK_NOT_BUSY(vha);
return NULL;
+ }
INIT_LIST_HEAD(&e->list);
e->type = type;
@@ -3135,6 +3157,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
}
if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e);
+
+ /* For each work completed decrement vha ref count */
+ QLA_VHA_MARK_NOT_BUSY(vha);
}
}
@@ -3531,6 +3556,11 @@ qla2x00_timer(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
struct req_que *req;
+ if (ha->flags.eeh_busy) {
+ qla2x00_restart_timer(vha, WATCH_INTERVAL);
+ return;
+ }
+
if (IS_QLA82XX(ha))
qla82xx_watchdog(vha);
@@ -3760,8 +3790,21 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
return PCI_ERS_RESULT_CAN_RECOVER;
case pci_channel_io_frozen:
ha->flags.eeh_busy = 1;
+ /* For ISP82XX complete any pending mailbox cmd */
+ if (IS_QLA82XX(ha)) {
+ ha->flags.fw_hung = 1;
+ if (ha->flags.mbox_busy) {
+ ha->flags.mbox_int = 1;
+ DEBUG2(qla_printk(KERN_ERR, ha,
+ "Due to pci channel io frozen, doing premature "
+ "completion of mbx command\n"));
+ complete(&ha->mbx_intr_comp);
+ }
+ }
qla2x00_free_irqs(vha);
pci_disable_device(pdev);
+ /* Return back all IOs */
+ qla2x00_abort_all_cmds(vha, DID_RESET << 16);
return PCI_ERS_RESULT_NEED_RESET;
case pci_channel_io_perm_failure:
ha->flags.pci_channel_io_perm_failure = 1;
@@ -3782,6 +3825,9 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev)
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
+ if (IS_QLA82XX(ha))
+ return PCI_ERS_RESULT_RECOVERED;
+
spin_lock_irqsave(&ha->hardware_lock, flags);
if (IS_QLA2100(ha) || IS_QLA2200(ha)){
stat = RD_REG_DWORD(&reg->hccr);
@@ -3808,6 +3854,109 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev)
return PCI_ERS_RESULT_RECOVERED;
}
+uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
+{
+ uint32_t rval = QLA_FUNCTION_FAILED;
+ uint32_t drv_active = 0;
+ struct qla_hw_data *ha = base_vha->hw;
+ int fn;
+ struct pci_dev *other_pdev = NULL;
+
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "scsi(%ld): In qla82xx_error_recovery\n", base_vha->host_no));
+
+ set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
+
+ if (base_vha->flags.online) {
+ /* Abort all outstanding commands,
+ * so as to be requeued later */
+ qla2x00_abort_isp_cleanup(base_vha);
+ }
+
+
+ fn = PCI_FUNC(ha->pdev->devfn);
+ while (fn > 0) {
+ fn--;
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "Finding pci device at function = 0x%x\n", fn));
+ other_pdev =
+ pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
+ ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
+ fn));
+
+ if (!other_pdev)
+ continue;
+ if (atomic_read(&other_pdev->enable_cnt)) {
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "Found PCI func availabe and enabled at 0x%x\n",
+ fn));
+ pci_dev_put(other_pdev);
+ break;
+ }
+ pci_dev_put(other_pdev);
+ }
+
+ if (!fn) {
+ /* Reset owner */
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "This devfn is reset owner = 0x%x\n", ha->pdev->devfn));
+ qla82xx_idc_lock(ha);
+
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA82XX_DEV_INITIALIZING);
+
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
+ QLA82XX_IDC_VERSION);
+
+ drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "drv_active = 0x%x\n", drv_active));
+
+ qla82xx_idc_unlock(ha);
+ /* Reset if device is not already reset
+ * drv_active would be 0 if a reset has already been done
+ */
+ if (drv_active)
+ rval = qla82xx_start_firmware(base_vha);
+ else
+ rval = QLA_SUCCESS;
+ qla82xx_idc_lock(ha);
+
+ if (rval != QLA_SUCCESS) {
+ qla_printk(KERN_INFO, ha, "HW State: FAILED\n");
+ qla82xx_clear_drv_active(ha);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA82XX_DEV_FAILED);
+ } else {
+ qla_printk(KERN_INFO, ha, "HW State: READY\n");
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA82XX_DEV_READY);
+ qla82xx_idc_unlock(ha);
+ ha->flags.fw_hung = 0;
+ rval = qla82xx_restart_isp(base_vha);
+ qla82xx_idc_lock(ha);
+ /* Clear driver state register */
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
+ qla82xx_set_drv_active(base_vha);
+ }
+ qla82xx_idc_unlock(ha);
+ } else {
+ DEBUG17(qla_printk(KERN_INFO, ha,
+ "This devfn is not reset owner = 0x%x\n", ha->pdev->devfn));
+ if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
+ QLA82XX_DEV_READY)) {
+ ha->flags.fw_hung = 0;
+ rval = qla82xx_restart_isp(base_vha);
+ qla82xx_idc_lock(ha);
+ qla82xx_set_drv_active(base_vha);
+ qla82xx_idc_unlock(ha);
+ }
+ }
+ clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
+
+ return rval;
+}
+
static pci_ers_result_t
qla2xxx_pci_slot_reset(struct pci_dev *pdev)
{
@@ -3840,15 +3989,23 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev)
if (rc) {
qla_printk(KERN_WARNING, ha,
"Can't re-enable PCI device after reset.\n");
- return ret;
+ goto exit_slot_reset;
}
rsp = ha->rsp_q_map[0];
if (qla2x00_request_irqs(ha, rsp))
- return ret;
+ goto exit_slot_reset;
if (ha->isp_ops->pci_config(base_vha))
- return ret;
+ goto exit_slot_reset;
+
+ if (IS_QLA82XX(ha)) {
+ if (qla82xx_error_recovery(base_vha) == QLA_SUCCESS) {
+ ret = PCI_ERS_RESULT_RECOVERED;
+ goto exit_slot_reset;
+ } else
+ goto exit_slot_reset;
+ }
while (ha->flags.mbox_busy && retries--)
msleep(1000);
@@ -3859,6 +4016,7 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev)
clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
+exit_slot_reset:
DEBUG17(qla_printk(KERN_WARNING, ha,
"slot_reset-return:ret=%x\n", ret));
@@ -3926,6 +4084,7 @@ static struct pci_driver qla2xxx_pci_driver = {
static struct file_operations apidev_fops = {
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* no read or write fn */
};
/**
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index e75ccb91317d..8edbccb3232d 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.03-k0"
+#define QLA2XXX_VERSION "8.03.04-k0"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
-#define QLA_DRIVER_PATCH_VER 3
+#define QLA_DRIVER_PATCH_VER 4
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index b02bdc6c2cd1..06329d47b38f 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -109,10 +109,12 @@ static const char * scsi_debug_version_date = "20100324";
#define DEF_PHYSBLK_EXP 0
#define DEF_LOWEST_ALIGNED 0
#define DEF_OPT_BLKS 64
-#define DEF_UNMAP_MAX_BLOCKS 0
-#define DEF_UNMAP_MAX_DESC 0
-#define DEF_UNMAP_GRANULARITY 0
+#define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF
+#define DEF_UNMAP_MAX_DESC 256
+#define DEF_UNMAP_GRANULARITY 1
#define DEF_UNMAP_ALIGNMENT 0
+#define DEF_TPWS 0
+#define DEF_TPU 0
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
@@ -177,10 +179,12 @@ static int scsi_debug_ato = DEF_ATO;
static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP;
static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
static int scsi_debug_opt_blks = DEF_OPT_BLKS;
-static int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
-static int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
-static int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY;
-static int scsi_debug_unmap_alignment = DEF_UNMAP_ALIGNMENT;
+static unsigned int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
+static unsigned int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
+static unsigned int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY;
+static unsigned int scsi_debug_unmap_alignment = DEF_UNMAP_ALIGNMENT;
+static unsigned int scsi_debug_tpws = DEF_TPWS;
+static unsigned int scsi_debug_tpu = DEF_TPU;
static int scsi_debug_cmnd_count = 0;
@@ -723,16 +727,9 @@ static int inquiry_evpd_b0(unsigned char * arr)
/* Optimal Transfer Length */
put_unaligned_be32(scsi_debug_opt_blks, &arr[8]);
- if (scsi_debug_unmap_max_desc) {
- unsigned int blocks;
-
- if (scsi_debug_unmap_max_blocks)
- blocks = scsi_debug_unmap_max_blocks;
- else
- blocks = 0xffffffff;
-
+ if (scsi_debug_tpu) {
/* Maximum Unmap LBA Count */
- put_unaligned_be32(blocks, &arr[16]);
+ put_unaligned_be32(scsi_debug_unmap_max_blocks, &arr[16]);
/* Maximum Unmap Block Descriptor Count */
put_unaligned_be32(scsi_debug_unmap_max_desc, &arr[20]);
@@ -745,10 +742,9 @@ static int inquiry_evpd_b0(unsigned char * arr)
}
/* Optimal Unmap Granularity */
- if (scsi_debug_unmap_granularity) {
- put_unaligned_be32(scsi_debug_unmap_granularity, &arr[24]);
- return 0x3c; /* Mandatory page length for thin provisioning */
- }
+ put_unaligned_be32(scsi_debug_unmap_granularity, &arr[24]);
+
+ return 0x3c; /* Mandatory page length for thin provisioning */
return sizeof(vpdb0_data);
}
@@ -765,6 +761,21 @@ static int inquiry_evpd_b1(unsigned char *arr)
return 0x3c;
}
+/* Thin provisioning VPD page (SBC-3) */
+static int inquiry_evpd_b2(unsigned char *arr)
+{
+ memset(arr, 0, 0x8);
+ arr[0] = 0; /* threshold exponent */
+
+ if (scsi_debug_tpu)
+ arr[1] = 1 << 7;
+
+ if (scsi_debug_tpws)
+ arr[1] |= 1 << 6;
+
+ return 0x8;
+}
+
#define SDEBUG_LONG_INQ_SZ 96
#define SDEBUG_MAX_INQ_ARR_SZ 584
@@ -820,6 +831,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
arr[n++] = 0x89; /* ATA information */
arr[n++] = 0xb0; /* Block limits (SBC) */
arr[n++] = 0xb1; /* Block characteristics (SBC) */
+ arr[n++] = 0xb2; /* Thin provisioning (SBC) */
arr[3] = n - 4; /* number of supported VPD pages */
} else if (0x80 == cmd[2]) { /* unit serial number */
arr[1] = cmd[2]; /*sanity */
@@ -867,6 +879,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
} else if (0xb1 == cmd[2]) { /* Block characteristics (SBC) */
arr[1] = cmd[2]; /*sanity */
arr[3] = inquiry_evpd_b1(&arr[4]);
+ } else if (0xb2 == cmd[2]) { /* Thin provisioning (SBC) */
+ arr[1] = cmd[2]; /*sanity */
+ arr[3] = inquiry_evpd_b2(&arr[4]);
} else {
/* Illegal request, invalid field in cdb */
mk_sense_buffer(devip, ILLEGAL_REQUEST,
@@ -1038,7 +1053,7 @@ static int resp_readcap16(struct scsi_cmnd * scp,
arr[13] = scsi_debug_physblk_exp & 0xf;
arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f;
- if (scsi_debug_unmap_granularity)
+ if (scsi_debug_tpu || scsi_debug_tpws)
arr[14] |= 0x80; /* TPE */
arr[15] = scsi_debug_lowest_aligned & 0xff;
@@ -2708,6 +2723,8 @@ module_param_named(unmap_max_blocks, scsi_debug_unmap_max_blocks, int, S_IRUGO);
module_param_named(unmap_max_desc, scsi_debug_unmap_max_desc, int, S_IRUGO);
module_param_named(unmap_granularity, scsi_debug_unmap_granularity, int, S_IRUGO);
module_param_named(unmap_alignment, scsi_debug_unmap_alignment, int, S_IRUGO);
+module_param_named(tpu, scsi_debug_tpu, int, S_IRUGO);
+module_param_named(tpws, scsi_debug_tpws, int, S_IRUGO);
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
MODULE_DESCRIPTION("SCSI debug adapter driver");
@@ -2739,10 +2756,12 @@ MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)");
MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)");
-MODULE_PARM_DESC(unmap_max_blocks, "max # of blocks can be unmapped in one cmd (def=0)");
-MODULE_PARM_DESC(unmap_max_desc, "max # of ranges that can be unmapped in one cmd (def=0)");
-MODULE_PARM_DESC(unmap_granularity, "thin provisioning granularity in blocks (def=0)");
+MODULE_PARM_DESC(unmap_max_blocks, "max # of blocks can be unmapped in one cmd (def=0xffffffff)");
+MODULE_PARM_DESC(unmap_max_desc, "max # of ranges that can be unmapped in one cmd (def=256)");
+MODULE_PARM_DESC(unmap_granularity, "thin provisioning granularity in blocks (def=1)");
MODULE_PARM_DESC(unmap_alignment, "lowest aligned thin provisioning lba (def=0)");
+MODULE_PARM_DESC(tpu, "enable TP, support UNMAP command (def=0)");
+MODULE_PARM_DESC(tpws, "enable TP, support WRITE SAME(16) with UNMAP bit (def=0)");
static char sdebug_info[256];
@@ -3130,7 +3149,7 @@ static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf)
{
ssize_t count;
- if (scsi_debug_unmap_granularity == 0)
+ if (scsi_debug_tpu == 0 && scsi_debug_tpws == 0)
return scnprintf(buf, PAGE_SIZE, "0-%u\n",
sdebug_store_sectors);
@@ -3322,10 +3341,21 @@ static int __init scsi_debug_init(void)
memset(dif_storep, 0xff, dif_size);
}
- if (scsi_debug_unmap_granularity) {
+ /* Thin Provisioning */
+ if (scsi_debug_tpu || scsi_debug_tpws) {
unsigned int map_bytes;
- if (scsi_debug_unmap_granularity < scsi_debug_unmap_alignment) {
+ scsi_debug_unmap_max_blocks =
+ clamp(scsi_debug_unmap_max_blocks, 0U, 0xffffffffU);
+
+ scsi_debug_unmap_max_desc =
+ clamp(scsi_debug_unmap_max_desc, 0U, 256U);
+
+ scsi_debug_unmap_granularity =
+ clamp(scsi_debug_unmap_granularity, 1U, 0xffffffffU);
+
+ if (scsi_debug_unmap_alignment &&
+ scsi_debug_unmap_granularity < scsi_debug_unmap_alignment) {
printk(KERN_ERR
"%s: ERR: unmap_granularity < unmap_alignment\n",
__func__);
@@ -3642,7 +3672,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
errsts = resp_readcap16(SCpnt, devip);
else if (cmd[1] == SAI_GET_LBA_STATUS) {
- if (scsi_debug_unmap_max_desc == 0) {
+ if (scsi_debug_tpu == 0 && scsi_debug_tpws == 0) {
mk_sense_buffer(devip, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
@@ -3753,8 +3783,16 @@ write:
}
break;
case WRITE_SAME_16:
- if (cmd[1] & 0x8)
- unmap = 1;
+ if (cmd[1] & 0x8) {
+ if (scsi_debug_tpws == 0) {
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_FIELD_IN_CDB, 0);
+ errsts = check_condition_result;
+ } else
+ unmap = 1;
+ }
+ if (errsts)
+ break;
/* fall through */
case WRITE_SAME:
errsts = check_readiness(SCpnt, 0, devip);
@@ -3768,7 +3806,7 @@ write:
if (errsts)
break;
- if (scsi_debug_unmap_max_desc == 0) {
+ if (scsi_debug_unmap_max_desc == 0 || scsi_debug_tpu == 0) {
mk_sense_buffer(devip, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9ade720422c6..ee02d3838a0a 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1011,8 +1011,8 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
err_exit:
scsi_release_buffers(cmd);
- scsi_put_command(cmd);
cmd->request->special = NULL;
+ scsi_put_command(cmd);
return error;
}
EXPORT_SYMBOL(scsi_init_io);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 3d0a1e6e9c48..087821fac8fe 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -417,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
starget->reap_ref = 1;
dev->parent = get_device(parent);
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
-#ifndef CONFIG_SYSFS_DEPRECATED
dev->bus = &scsi_bus_type;
-#endif
dev->type = &scsi_target_type;
starget->id = id;
starget->channel = channel;
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index a87e21c35ef2..b4e5b56ce8d8 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -22,7 +22,6 @@
#include <linux/miscdevice.h>
#include <linux/gfp.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -323,7 +322,6 @@ static int tgt_open(struct inode *inode, struct file *file)
{
tx_ring.tr_idx = rx_ring.tr_idx = 0;
- cycle_kernel_lock();
return 0;
}
@@ -333,6 +331,7 @@ static const struct file_operations tgt_fops = {
.poll = tgt_poll,
.write = tgt_write,
.mmap = tgt_mmap,
+ .llseek = noop_llseek,/* write uses no f_pos */
};
static struct miscdevice tgt_miscdev = {
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index d7e470a06180..78486d540652 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -2525,7 +2525,11 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
rport->maxframe_size = -1;
rport->supported_classes = FC_COS_UNSPECIFIED;
- rport->dev_loss_tmo = fc_dev_loss_tmo;
+ if (fci->f->get_host_def_dev_loss_tmo) {
+ fci->f->get_host_def_dev_loss_tmo(shost);
+ rport->dev_loss_tmo = fc_host_def_dev_loss_tmo(shost);
+ } else
+ rport->dev_loss_tmo = fc_dev_loss_tmo;
memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
rport->port_id = ids->port_id;
@@ -4044,11 +4048,54 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
/**
* fc_bsg_remove - Deletes the bsg hooks on fchosts/rports
* @q: the request_queue that is to be torn down.
+ *
+ * Notes:
+ * Before unregistering the queue empty any requests that are blocked
+ *
+ *
*/
static void
fc_bsg_remove(struct request_queue *q)
{
+ struct request *req; /* block request */
+ int counts; /* totals for request_list count and starved */
+
if (q) {
+ /* Stop taking in new requests */
+ spin_lock_irq(q->queue_lock);
+ blk_stop_queue(q);
+
+ /* drain all requests in the queue */
+ while (1) {
+ /* need the lock to fetch a request
+ * this may fetch the same reqeust as the previous pass
+ */
+ req = blk_fetch_request(q);
+ /* save requests in use and starved */
+ counts = q->rq.count[0] + q->rq.count[1] +
+ q->rq.starved[0] + q->rq.starved[1];
+ spin_unlock_irq(q->queue_lock);
+ /* any requests still outstanding? */
+ if (counts == 0)
+ break;
+
+ /* This may be the same req as the previous iteration,
+ * always send the blk_end_request_all after a prefetch.
+ * It is not okay to not end the request because the
+ * prefetch started the request.
+ */
+ if (req) {
+ /* return -ENXIO to indicate that this queue is
+ * going away
+ */
+ req->errors = -ENXIO;
+ blk_end_request_all(req, -ENXIO);
+ }
+
+ msleep(200); /* allow bsg to possibly finish */
+ spin_lock_irq(q->queue_lock);
+ }
+
bsg_unregister_queue(q);
blk_cleanup_queue(q);
}
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index e84026def1f4..332387a6bc25 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -537,7 +537,7 @@ static void iscsi_scan_session(struct work_struct *work)
/**
* iscsi_block_scsi_eh - block scsi eh until session state has transistioned
- * cmd: scsi cmd passed to scsi eh handler
+ * @cmd: scsi cmd passed to scsi eh handler
*
* If the session is down this function will wait for the recovery
* timer to fire or for the session to be logged back in. If the
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2714becc2eaf..da32e59b8929 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -477,7 +477,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
{
- rq->timeout = SD_TIMEOUT;
+ rq->timeout = SD_FLUSH_TIMEOUT;
rq->retries = SD_MAX_RETRIES;
rq->cmd[0] = SYNCHRONIZE_CACHE;
rq->cmd_len = 10;
@@ -870,7 +870,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n"));
- if (atomic_dec_return(&sdkp->openers) && sdev->removable) {
+ if (atomic_dec_return(&sdkp->openers) == 0 && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
}
@@ -1072,7 +1072,7 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
* flush everything.
*/
res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
- SD_TIMEOUT, SD_MAX_RETRIES, NULL);
+ SD_FLUSH_TIMEOUT, SD_MAX_RETRIES, NULL);
if (res == 0)
break;
}
@@ -2109,7 +2109,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
unsigned char *buffer;
- unsigned ordered;
+ unsigned flush = 0;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_revalidate_disk\n"));
@@ -2151,17 +2151,15 @@ static int sd_revalidate_disk(struct gendisk *disk)
/*
* We now have all cache related info, determine how we deal
- * with ordered requests. Note that as the current SCSI
- * dispatch function can alter request order, we cannot use
- * QUEUE_ORDERED_TAG_* even when ordered tag is supported.
+ * with flush requests.
*/
- if (sdkp->WCE)
- ordered = sdkp->DPOFUA
- ? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH;
- else
- ordered = QUEUE_ORDERED_DRAIN;
+ if (sdkp->WCE) {
+ flush |= REQ_FLUSH;
+ if (sdkp->DPOFUA)
+ flush |= REQ_FUA;
+ }
- blk_queue_ordered(sdkp->disk->queue, ordered);
+ blk_queue_flush(sdkp->disk->queue, flush);
set_capacity(disk, sdkp->capacity);
kfree(buffer);
@@ -2625,15 +2623,15 @@ module_exit(exit_sd);
static void sd_print_sense_hdr(struct scsi_disk *sdkp,
struct scsi_sense_hdr *sshdr)
{
- sd_printk(KERN_INFO, sdkp, "");
+ sd_printk(KERN_INFO, sdkp, " ");
scsi_show_sense_hdr(sshdr);
- sd_printk(KERN_INFO, sdkp, "");
+ sd_printk(KERN_INFO, sdkp, " ");
scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
}
static void sd_print_result(struct scsi_disk *sdkp, int result)
{
- sd_printk(KERN_INFO, sdkp, "");
+ sd_printk(KERN_INFO, sdkp, " ");
scsi_show_result(result);
}
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index f81a9309e6de..315ce9d96b1f 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -19,6 +19,7 @@
*/
#define SD_TIMEOUT (30 * HZ)
#define SD_MOD_TIMEOUT (75 * HZ)
+#define SD_FLUSH_TIMEOUT (60 * HZ)
/*
* Number of allowed retries
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 78d616315d8e..13776a71f629 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -49,7 +49,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/blktrace_api.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -62,6 +62,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
+static DEFINE_MUTEX(sg_mutex);
static char *sg_version_date = "20061027";
static int sg_proc_init(void);
@@ -229,7 +230,7 @@ sg_open(struct inode *inode, struct file *filp)
int res;
int retval;
- lock_kernel();
+ mutex_lock(&sg_mutex);
nonseekable_open(inode, filp);
SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
sdp = sg_get_dev(dev);
@@ -314,7 +315,7 @@ sdp_put:
sg_put:
if (sdp)
sg_put_dev(sdp);
- unlock_kernel();
+ mutex_unlock(&sg_mutex);
return retval;
}
@@ -1092,9 +1093,9 @@ sg_unlocked_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&sg_mutex);
ret = sg_ioctl(filp, cmd_in, arg);
- unlock_kernel();
+ mutex_unlock(&sg_mutex);
return ret;
}
@@ -1351,6 +1352,7 @@ static const struct file_operations sg_fops = {
.mmap = sg_mmap,
.release = sg_release,
.fasync = sg_fasync,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct class *sg_sysfs_class;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index ba9c3e0387ce..e148341079b5 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -44,7 +44,6 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
@@ -76,6 +75,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
CDC_MRW|CDC_MRW_W|CDC_RAM)
+static DEFINE_MUTEX(sr_mutex);
static int sr_probe(struct device *);
static int sr_remove(struct device *);
static int sr_done(struct scsi_cmnd *);
@@ -470,24 +470,24 @@ static int sr_block_open(struct block_device *bdev, fmode_t mode)
struct scsi_cd *cd;
int ret = -ENXIO;
- lock_kernel();
+ mutex_lock(&sr_mutex);
cd = scsi_cd_get(bdev->bd_disk);
if (cd) {
ret = cdrom_open(&cd->cdi, bdev, mode);
if (ret)
scsi_cd_put(cd);
}
- unlock_kernel();
+ mutex_unlock(&sr_mutex);
return ret;
}
static int sr_block_release(struct gendisk *disk, fmode_t mode)
{
struct scsi_cd *cd = scsi_cd(disk);
- lock_kernel();
+ mutex_lock(&sr_mutex);
cdrom_release(&cd->cdi, mode);
scsi_cd_put(cd);
- unlock_kernel();
+ mutex_unlock(&sr_mutex);
return 0;
}
@@ -499,7 +499,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
void __user *argp = (void __user *)arg;
int ret;
- lock_kernel();
+ mutex_lock(&sr_mutex);
/*
* Send SCSI addressing ioctls directly to mid level, send other
@@ -529,7 +529,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
ret = scsi_ioctl(sdev, cmd, argp);
out:
- unlock_kernel();
+ mutex_unlock(&sr_mutex);
return ret;
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 24211d0efa6d..afdc3f5d915c 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -39,7 +39,6 @@ static const char *verstr = "20081215";
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
@@ -76,6 +75,7 @@ static const char *verstr = "20081215";
#include "st_options.h"
#include "st.h"
+static DEFINE_MUTEX(st_mutex);
static int buffer_kbs;
static int max_sg_segs;
static int try_direct_io = TRY_DIRECT_IO;
@@ -1180,7 +1180,7 @@ static int st_open(struct inode *inode, struct file *filp)
int dev = TAPE_NR(inode);
char *name;
- lock_kernel();
+ mutex_lock(&st_mutex);
/*
* We really want to do nonseekable_open(inode, filp); here, but some
* versions of tar incorrectly call lseek on tapes and bail out if that
@@ -1189,7 +1189,7 @@ static int st_open(struct inode *inode, struct file *filp)
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
if (!(STp = scsi_tape_get(dev))) {
- unlock_kernel();
+ mutex_unlock(&st_mutex);
return -ENXIO;
}
@@ -1200,7 +1200,7 @@ static int st_open(struct inode *inode, struct file *filp)
if (STp->in_use) {
write_unlock(&st_dev_arr_lock);
scsi_tape_put(STp);
- unlock_kernel();
+ mutex_unlock(&st_mutex);
DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY);
}
@@ -1249,14 +1249,14 @@ static int st_open(struct inode *inode, struct file *filp)
retval = (-EIO);
goto err_out;
}
- unlock_kernel();
+ mutex_unlock(&st_mutex);
return 0;
err_out:
normalize_buffer(STp->buffer);
STp->in_use = 0;
scsi_tape_put(STp);
- unlock_kernel();
+ mutex_unlock(&st_mutex);
return retval;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index a7bc8b7b09ac..2c3e89ddf069 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -72,10 +72,7 @@ static void sym_printl_hex(u_char *p, int n)
static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
{
- if (label)
- sym_print_addr(cp->cmd, "%s: ", label);
- else
- sym_print_addr(cp->cmd, "");
+ sym_print_addr(cp->cmd, "%s: ", label);
spi_print_msg(msg);
printf("\n");
@@ -4558,7 +4555,8 @@ static void sym_int_sir(struct sym_hcb *np)
switch (np->msgin [2]) {
case M_X_MODIFY_DP:
if (DEBUG_FLAGS & DEBUG_POINTER)
- sym_print_msg(cp, NULL, np->msgin);
+ sym_print_msg(cp, "extended msg ",
+ np->msgin);
tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
(np->msgin[5]<<8) + (np->msgin[6]);
sym_modify_dp(np, tp, cp, tmp);
@@ -4585,7 +4583,7 @@ static void sym_int_sir(struct sym_hcb *np)
*/
case M_IGN_RESIDUE:
if (DEBUG_FLAGS & DEBUG_POINTER)
- sym_print_msg(cp, NULL, np->msgin);
+ sym_print_msg(cp, "1 or 2 byte ", np->msgin);
if (cp->host_flags & HF_SENSE)
OUTL_DSP(np, SCRIPTA_BA(np, clrack));
else
diff --git a/drivers/serial/68328serial.h b/drivers/serial/68328serial.h
index 58aa2154655b..664ceb0a158c 100644
--- a/drivers/serial/68328serial.h
+++ b/drivers/serial/68328serial.h
@@ -181,13 +181,8 @@ struct m68k_serial {
/*
* Define the number of ports supported and their irqs.
*/
-#ifndef CONFIG_68328_SERIAL_UART2
#define NR_PORTS 1
#define UART_IRQ_DEFNS {UART_IRQ_NUM}
-#else
-#define NR_PORTS 2
-#define UART_IRQ_DEFNS {UART1_IRQ_NUM, UART2_IRQ_NUM}
-#endif
#endif /* __KERNEL__ */
#endif /* !(_MC683XX_SERIAL_H) */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 12900f7083b0..3198c5335f0b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS
int
depends on ARM && PLAT_SAMSUNG
default 2 if ARCH_S3C2400
+ default 6 if ARCH_S5P6450
default 4 if SERIAL_SAMSUNG_UARTS_4
default 3
help
@@ -526,12 +527,12 @@ config SERIAL_S3C24A0
Serial port support for the Samsung S3C24A0 SoC
config SERIAL_S3C6400
- tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100)
+ tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
select SERIAL_SAMSUNG_UARTS_4
default y
help
- Serial port support for the Samsung S3C6400, S3C6410, S5P6440
+ Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
and S5PC100 SoCs
config SERIAL_S5PV210
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 50441ffe8e38..2904aa044126 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -472,14 +472,9 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
spin_unlock_irqrestore(&uap->port.lock, flags);
}
-static void pl010_set_ldisc(struct uart_port *port)
+static void pl010_set_ldisc(struct uart_port *port, int new)
{
- int line = port->line;
-
- if (line >= port->state->port.tty->driver->num)
- return;
-
- if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+ if (new == N_PPS) {
port->flags |= UPF_HARDPPS_CD;
pl010_enable_ms(port);
} else
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index e57fb3d228e2..5318dd3774ae 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -121,7 +121,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate)
unsigned int sclk = get_sclk();
/* Set TCR1 and TCR2, TFSR is not enabled for uart */
- SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK));
+ SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK));
SPORT_PUT_TCR2(up, size + 1);
pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up));
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 39f9a1adaa75..62b6edc54754 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -18,6 +18,7 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
+#include <linux/kbd_kern.h>
#define MAX_CONFIG_LEN 40
@@ -37,12 +38,16 @@ static struct tty_driver *kgdb_tty_driver;
static int kgdb_tty_line;
#ifdef CONFIG_KDB_KEYBOARD
+static bool kgdboc_use_kbd;
+
static int kgdboc_register_kbd(char **cptr)
{
+ kgdboc_use_kbd = false;
if (strncmp(*cptr, "kbd", 3) == 0) {
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
kdb_poll_idx++;
+ kgdboc_use_kbd = true;
if (cptr[0][3] == ',')
*cptr += 4;
else
@@ -65,9 +70,16 @@ static void kgdboc_unregister_kbd(void)
}
}
}
+
+static inline void kgdboc_clear_kbd(void)
+{
+ if (kgdboc_use_kbd)
+ kbd_dbg_clear_keys(); /* Release all pressed keys */
+}
#else /* ! CONFIG_KDB_KEYBOARD */
#define kgdboc_register_kbd(x) 0
#define kgdboc_unregister_kbd()
+#define kgdboc_clear_kbd()
#endif /* ! CONFIG_KDB_KEYBOARD */
static int kgdboc_option_setup(char *opt)
@@ -231,6 +243,7 @@ static void kgdboc_post_exp_handler(void)
dbg_restore_graphics = 0;
con_debug_leave();
}
+ kgdboc_clear_kbd();
}
static struct kgdb_io kgdboc_io_ops = {
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c
index bc9af503907f..0d7148854fe5 100644
--- a/drivers/serial/mfd.c
+++ b/drivers/serial/mfd.c
@@ -171,6 +171,9 @@ static ssize_t port_show_regs(struct file *file, char __user *user_buf,
len += snprintf(buf + len, HSU_REGS_BUFSIZE - len,
"DIV: \t\t0x%08x\n", serial_in(up, UART_DIV));
+ if (len > HSU_REGS_BUFSIZE)
+ len = HSU_REGS_BUFSIZE;
+
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return ret;
@@ -218,6 +221,9 @@ static ssize_t dma_show_regs(struct file *file, char __user *user_buf,
len += snprintf(buf + len, HSU_REGS_BUFSIZE - len,
"D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3TSR));
+ if (len > HSU_REGS_BUFSIZE)
+ len = HSU_REGS_BUFSIZE;
+
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return ret;
@@ -227,12 +233,14 @@ static const struct file_operations port_regs_ops = {
.owner = THIS_MODULE,
.open = hsu_show_regs_open,
.read = port_show_regs,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations dma_regs_ops = {
.owner = THIS_MODULE,
.open = hsu_show_regs_open,
.read = dma_show_regs,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int hsu_debugfs_init(struct hsu_port *hsu)
@@ -1423,7 +1431,6 @@ static void hsu_global_init(void)
}
phsu = hsu;
-
hsu_debugfs_init(hsu);
return;
@@ -1435,18 +1442,20 @@ err_free_region:
static void serial_hsu_remove(struct pci_dev *pdev)
{
- struct hsu_port *hsu;
- int i;
+ void *priv = pci_get_drvdata(pdev);
+ struct uart_hsu_port *up;
- hsu = pci_get_drvdata(pdev);
- if (!hsu)
+ if (!priv)
return;
- for (i = 0; i < 3; i++)
- uart_remove_one_port(&serial_hsu_reg, &hsu->port[i].port);
+ /* For port 0/1/2, priv is the address of uart_hsu_port */
+ if (pdev->device != 0x081E) {
+ up = priv;
+ uart_remove_one_port(&serial_hsu_reg, &up->port);
+ }
pci_set_drvdata(pdev, NULL);
- free_irq(hsu->irq, hsu);
+ free_irq(pdev->irq, priv);
pci_disable_device(pdev);
}
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 8dedb266f143..c4399e23565a 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -500,6 +500,7 @@ static int __init mpc512x_psc_fifoc_init(void)
psc_fifoc = of_iomap(np, 0);
if (!psc_fifoc) {
pr_err("%s: Can't map FIFOC\n", __func__);
+ of_node_put(np);
return -ENODEV;
}
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index b1156ba8ad14..7ac2bf5167cd 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -1101,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
port->mapbase = res->start;
- port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000);
+ port->membase = S3C_VA_UART + (res->start & 0xfffff);
ret = platform_get_irq(platdev, 0);
if (ret < 0)
port->irq = 0;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index cd8511298bcb..bc6cddd10294 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2065,7 +2065,19 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
/*
* Re-enable the console device after suspending.
*/
- if (uart_console(uport)) {
+ if (console_suspend_enabled && uart_console(uport)) {
+ /*
+ * First try to use the console cflag setting.
+ */
+ memset(&termios, 0, sizeof(struct ktermios));
+ termios.c_cflag = uport->cons->cflag;
+
+ /*
+ * If that's unset, use the tty termios setting.
+ */
+ if (port->tty && port->tty->termios && termios.c_cflag == 0)
+ termios = *(port->tty->termios);
+
uart_change_pm(state, 0);
uport->ops->set_termios(uport, &termios, NULL);
console_start(uport->cons);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 141c69554bd4..dd0fa1213c15 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -335,8 +335,6 @@ static int serial_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- link->resource[0]->end = 8;
link->conf.Attributes = CONF_ENABLE_IRQ;
if (do_sound) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -466,7 +464,7 @@ static int simple_config(struct pcmcia_device *link)
unsigned int port = 0;
if ((link->resource[1]->end != 0) &&
(resource_size(link->resource[1]) == 8)) {
- port = link->resource[1]->end;
+ port = link->resource[1]->start;
info->slave = 1;
} else if ((info->manfid == MANFID_OSITECH) &&
(resource_size(link->resource[0]) == 0x40)) {
@@ -479,6 +477,9 @@ static int simple_config(struct pcmcia_device *link)
}
}
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[0]->end = 8;
+
/* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 4; try++)
@@ -558,6 +559,7 @@ static int multi_config(struct pcmcia_device *link)
int i, base2 = 0;
/* First, look for a generic full-sized window */
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = info->multi * 8;
if (pcmcia_loop_config(link, multi_config_check, &base2)) {
/* If that didn't work, look for two windows */
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 9b52f77a9305..d2352ac437c5 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -140,7 +140,15 @@
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# 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 */
+
+#if defined(CONFIG_SH_SH2007)
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=0 */
+# define SCSCR_INIT(port) 0x38
+#else
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=1 */
+# define SCSCR_INIT(port) 0x3a
+#endif
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SH7786)
# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
@@ -616,9 +624,10 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785) || \
- defined(CONFIG_CPU_SUBTYPE_SH7786)
+#if (defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)) && \
+ !defined(CONFIG_SH_SH2007)
#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/uartlite.c b/drivers/serial/uartlite.c
index 9b03d7b3e456..c4bf54bb3fc7 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -322,6 +322,26 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser)
return -EINVAL;
}
+#ifdef CONFIG_CONSOLE_POLL
+static int ulite_get_poll_char(struct uart_port *port)
+{
+ if (!(ioread32be(port->membase + ULITE_STATUS)
+ & ULITE_STATUS_RXVALID))
+ return NO_POLL_CHAR;
+
+ return ioread32be(port->membase + ULITE_RX);
+}
+
+static void ulite_put_poll_char(struct uart_port *port, unsigned char ch)
+{
+ while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL)
+ cpu_relax();
+
+ /* write char to device */
+ iowrite32be(ch, port->membase + ULITE_TX);
+}
+#endif
+
static struct uart_ops ulite_ops = {
.tx_empty = ulite_tx_empty,
.set_mctrl = ulite_set_mctrl,
@@ -338,7 +358,11 @@ static struct uart_ops ulite_ops = {
.release_port = ulite_release_port,
.request_port = ulite_request_port,
.config_port = ulite_config_port,
- .verify_port = ulite_verify_port
+ .verify_port = ulite_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = ulite_get_poll_char,
+ .poll_put_char = ulite_put_poll_char,
+#endif
};
/* ---------------------------------------------------------------------
diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c
index 5d84adac9ec4..b9c57a640c24 100644
--- a/drivers/sh/clk.c
+++ b/drivers/sh/clk.c
@@ -1,7 +1,7 @@
/*
* drivers/sh/clk.c - SuperH clock framework
*
- * Copyright (C) 2005 - 2009 Paul Mundt
+ * Copyright (C) 2005 - 2010 Paul Mundt
*
* This clock framework is derived from the OMAP version by:
*
@@ -76,7 +76,8 @@ long clk_rate_table_round(struct clk *clk,
unsigned long highest, lowest;
int i;
- highest = lowest = 0;
+ highest = 0;
+ lowest = ~0UL;
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned long freq = freq_table[i].frequency;
@@ -354,10 +355,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
ret = clk_reparent(clk, parent);
if (ret == 0) {
- pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
- clk->name, clk->parent->name, clk->rate);
if (clk->ops->recalc)
clk->rate = clk->ops->recalc(clk);
+ pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
+ clk->name, clk->parent->name, clk->rate);
propagate_rate(clk);
}
} else
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index acd35d1ebd12..4c37c4e28647 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -503,8 +503,9 @@ static void giveback(struct pl022 *pl022)
msg->state = NULL;
if (msg->complete)
msg->complete(msg->context);
- /* This message is completed, so let's turn off the clock! */
+ /* This message is completed, so let's turn off the clocks! */
clk_disable(pl022->clk);
+ amba_pclk_disable(pl022->adev);
}
/**
@@ -1139,9 +1140,10 @@ static void pump_messages(struct work_struct *work)
/* Setup the SPI using the per chip configuration */
pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
/*
- * We enable the clock here, then the clock will be disabled when
+ * We enable the clocks here, then the clocks will be disabled when
* giveback() is called in each method (poll/interrupt/DMA)
*/
+ amba_pclk_enable(pl022->adev);
clk_enable(pl022->clk);
restore_state(pl022);
flush(pl022);
@@ -1786,11 +1788,9 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
}
/* Disable SSP */
- clk_enable(pl022->clk);
writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
SSP_CR1(pl022->virtbase));
load_ssp_default_config(pl022);
- clk_disable(pl022->clk);
status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022",
pl022);
@@ -1818,6 +1818,8 @@ pl022_probe(struct amba_device *adev, struct amba_id *id)
goto err_spi_register;
}
dev_dbg(dev, "probe succeded\n");
+ /* Disable the silicon block pclk and clock it when needed */
+ amba_pclk_disable(adev);
return 0;
err_spi_register:
@@ -1879,9 +1881,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
return status;
}
- clk_enable(pl022->clk);
+ amba_pclk_enable(adev);
load_ssp_default_config(pl022);
- clk_disable(pl022->clk);
+ amba_pclk_disable(adev);
dev_dbg(&adev->dev, "suspended\n");
return 0;
}
@@ -1981,7 +1983,7 @@ static int __init pl022_init(void)
return amba_driver_register(&pl022_driver);
}
-module_init(pl022_init);
+subsys_initcall(pl022_init);
static void __exit pl022_exit(void)
{
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index d256cb00604c..6dec1bdc111a 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -131,6 +131,7 @@ static const struct file_operations mrst_spi_regs_ops = {
.owner = THIS_MODULE,
.open = spi_show_regs_open,
.read = spi_show_regs,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int mrst_spi_debugfs_init(struct dw_spi *dws)
@@ -181,10 +182,6 @@ static void flush(struct dw_spi *dws)
wait_till_not_busy(dws);
}
-static void null_cs_control(u32 command)
-{
-}
-
static int null_writer(struct dw_spi *dws)
{
u8 n_bytes = dws->n_bytes;
@@ -322,7 +319,7 @@ static void giveback(struct dw_spi *dws)
struct spi_transfer,
transfer_list);
- if (!last_transfer->cs_change)
+ if (!last_transfer->cs_change && dws->cs_control)
dws->cs_control(MRST_SPI_DEASSERT);
msg->state = NULL;
@@ -396,6 +393,11 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
static irqreturn_t dw_spi_irq(int irq, void *dev_id)
{
struct dw_spi *dws = dev_id;
+ u16 irq_status, irq_mask = 0x3f;
+
+ irq_status = dw_readw(dws, isr) & irq_mask;
+ if (!irq_status)
+ return IRQ_NONE;
if (!dws->cur_msg) {
spi_mask_intr(dws, SPI_INT_TXEI);
@@ -544,13 +546,13 @@ static void pump_transfers(unsigned long data)
*/
if (dws->cs_control) {
if (dws->rx && dws->tx)
- chip->tmode = 0x00;
+ chip->tmode = SPI_TMOD_TR;
else if (dws->rx)
- chip->tmode = 0x02;
+ chip->tmode = SPI_TMOD_RO;
else
- chip->tmode = 0x01;
+ chip->tmode = SPI_TMOD_TO;
- cr0 &= ~(0x3 << SPI_MODE_OFFSET);
+ cr0 &= ~SPI_TMOD_MASK;
cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
}
@@ -699,9 +701,6 @@ static int dw_spi_setup(struct spi_device *spi)
chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
if (!chip)
return -ENOMEM;
-
- chip->cs_control = null_cs_control;
- chip->enable_dma = 0;
}
/*
@@ -883,7 +882,7 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
dws->dma_inited = 0;
dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
- ret = request_irq(dws->irq, dw_spi_irq, 0,
+ ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED,
"dw_spi", dws);
if (ret < 0) {
dev_err(&master->dev, "can not get IRQ\n");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a9e5c79ae52a..0bcf4c1601a2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -554,11 +554,9 @@ done:
EXPORT_SYMBOL_GPL(spi_register_master);
-static int __unregister(struct device *dev, void *master_dev)
+static int __unregister(struct device *dev, void *null)
{
- /* note: before about 2.6.14-rc1 this would corrupt memory: */
- if (dev != master_dev)
- spi_unregister_device(to_spi_device(dev));
+ spi_unregister_device(to_spi_device(dev));
return 0;
}
@@ -576,8 +574,7 @@ void spi_unregister_master(struct spi_master *master)
{
int dummy;
- dummy = device_for_each_child(master->dev.parent, &master->dev,
- __unregister);
+ dummy = device_for_each_child(&master->dev, NULL, __unregister);
device_unregister(&master->dev);
}
EXPORT_SYMBOL_GPL(spi_unregister_master);
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c
index 97365815a729..c3038da2648a 100644
--- a/drivers/spi/spi_s3c64xx.c
+++ b/drivers/spi/spi_s3c64xx.c
@@ -200,6 +200,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
val = readl(regs + S3C64XX_SPI_STATUS);
} while (TX_FIFO_LVL(val, sci) && loops--);
+ if (loops == 0)
+ dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
+
/* Flush RxFIFO*/
loops = msecs_to_loops(1);
do {
@@ -210,6 +213,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
break;
} while (loops--);
+ if (loops == 0)
+ dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n");
+
val = readl(regs + S3C64XX_SPI_CH_CFG);
val &= ~S3C64XX_SPI_CH_SW_RST;
writel(val, regs + S3C64XX_SPI_CH_CFG);
@@ -320,16 +326,17 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
/* millisecs to xfer 'len' bytes @ 'cur_speed' */
ms = xfer->len * 8 * 1000 / sdd->cur_speed;
- ms += 5; /* some tolerance */
+ ms += 10; /* some tolerance */
if (dma_mode) {
val = msecs_to_jiffies(ms) + 10;
val = wait_for_completion_timeout(&sdd->xfer_completion, val);
} else {
+ u32 status;
val = msecs_to_loops(ms);
do {
- val = readl(regs + S3C64XX_SPI_STATUS);
- } while (RX_FIFO_LVL(val, sci) < xfer->len && --val);
+ status = readl(regs + S3C64XX_SPI_STATUS);
+ } while (RX_FIFO_LVL(status, sci) < xfer->len && --val);
}
if (!val)
@@ -447,8 +454,8 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
writel(val, regs + S3C64XX_SPI_CLK_CFG);
}
-void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
- int size, enum s3c2410_dma_buffresult res)
+static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
+ int size, enum s3c2410_dma_buffresult res)
{
struct s3c64xx_spi_driver_data *sdd = buf_id;
unsigned long flags;
@@ -467,8 +474,8 @@ void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
spin_unlock_irqrestore(&sdd->lock, flags);
}
-void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
- int size, enum s3c2410_dma_buffresult res)
+static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
+ int size, enum s3c2410_dma_buffresult res)
{
struct s3c64xx_spi_driver_data *sdd = buf_id;
unsigned long flags;
@@ -508,8 +515,9 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (xfer->tx_buf != NULL) {
- xfer->tx_dma = dma_map_single(dev, xfer->tx_buf,
- xfer->len, DMA_TO_DEVICE);
+ xfer->tx_dma = dma_map_single(dev,
+ (void *)xfer->tx_buf, xfer->len,
+ DMA_TO_DEVICE);
if (dma_mapping_error(dev, xfer->tx_dma)) {
dev_err(dev, "dma_map_single Tx failed\n");
xfer->tx_dma = XFER_DMAADDR_INVALID;
@@ -919,6 +927,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return -ENODEV;
}
+ sci = pdev->dev.platform_data;
+ if (!sci->src_clk_name) {
+ dev_err(&pdev->dev,
+ "Board init must call s3c64xx_spi_set_info()\n");
+ return -EINVAL;
+ }
+
/* Check for availability of necessary resource */
dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -946,8 +961,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return -ENOMEM;
}
- sci = pdev->dev.platform_data;
-
platform_set_drvdata(pdev, master);
sdd = spi_master_get_devdata(master);
@@ -1170,7 +1183,7 @@ static int __init s3c64xx_spi_init(void)
{
return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
}
-module_init(s3c64xx_spi_init);
+subsys_initcall(s3c64xx_spi_init);
static void __exit s3c64xx_spi_exit(void)
{
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index ea1bec3c9a13..7325a833a350 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -545,6 +545,7 @@ static const struct file_operations spidev_fops = {
.unlocked_ioctl = spidev_ioctl,
.open = spidev_open,
.release = spidev_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 335311a98fdc..015f0a787e8d 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -61,6 +61,8 @@ source "drivers/staging/echo/Kconfig"
source "drivers/staging/otus/Kconfig"
+source "drivers/staging/brcm80211/Kconfig"
+
source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
@@ -73,12 +75,12 @@ source "drivers/staging/panel/Kconfig"
source "drivers/staging/rtl8187se/Kconfig"
-source "drivers/staging/rtl8192su/Kconfig"
-
source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
+source "drivers/staging/rtl8712/Kconfig"
+
source "drivers/staging/frontier/Kconfig"
source "drivers/staging/dream/Kconfig"
@@ -139,8 +141,6 @@ source "drivers/staging/adis16255/Kconfig"
source "drivers/staging/xgifb/Kconfig"
-source "drivers/staging/mrst-touchscreen/Kconfig"
-
source "drivers/staging/msm/Kconfig"
source "drivers/staging/lirc/Kconfig"
@@ -153,5 +153,15 @@ source "drivers/staging/tidspbridge/Kconfig"
source "drivers/staging/quickstart/Kconfig"
+source "drivers/staging/westbridge/Kconfig"
+
+source "drivers/staging/sbe-2t3e3/Kconfig"
+
+source "drivers/staging/ath6kl/Kconfig"
+
+source "drivers/staging/keucr/Kconfig"
+
+source "drivers/staging/bcm/Kconfig"
+
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index e3f1e1b6095e..714266c3b0c8 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -14,15 +14,16 @@ obj-$(CONFIG_W35UND) += winbond/
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_OTUS) += otus/
+obj-$(CONFIG_BRCM80211) += brcm80211/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
obj-$(CONFIG_R8187SE) += rtl8187se/
-obj-$(CONFIG_RTL8192SU) += rtl8192su/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
+obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_SPECTRA) += spectra/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_DREAM) += dream/
@@ -51,9 +52,13 @@ obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_TI_ST) += ti-st/
obj-$(CONFIG_ADIS16255) += adis16255/
obj-$(CONFIG_FB_XGI) += xgifb/
-obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
+obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/
+obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
+obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/
+obj-$(CONFIG_USB_ENESTORAGE) += keucr/
+obj-$(CONFIG_BCM_WIMAX) += bcm/
diff --git a/drivers/staging/adis16255/adis16255.c b/drivers/staging/adis16255/adis16255.c
index c3e6a4d5f334..8d4d7cbab979 100644
--- a/drivers/staging/adis16255/adis16255.c
+++ b/drivers/staging/adis16255/adis16255.c
@@ -406,12 +406,14 @@ static int __devinit spi_adis16255_probe(struct spi_device *spi)
status = spi_adis16255_bringup(spiadis);
if (status != 0)
- goto irq_err;
+ goto sysfs_err;
dev_info(&spi->dev, "spi_adis16255 driver added!\n");
return status;
+sysfs_err:
+ sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group);
irq_err:
free_irq(spiadis->irq, spiadis);
gpio_err:
diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig
new file mode 100644
index 000000000000..ae2cdf48b74c
--- /dev/null
+++ b/drivers/staging/ath6kl/Kconfig
@@ -0,0 +1,163 @@
+config ATH6K_LEGACY
+ tristate "Atheros AR6003 support (non mac80211)"
+ depends on MMC && WLAN
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ help
+ This module adds support for wireless adapters based on Atheros AR6003 chipset running over SDIO. If you choose to build it as a module, it will be called ath6kl. Pls note that AR6002 and AR6001 are not supported by this driver.
+
+choice
+ prompt "AR6003 Board Data Configuration"
+ depends on ATH6K_LEGACY
+ default AR600x_SD31_XXX
+ help
+ Select the appropriate board data template from the list below that matches your AR6003 based reference design.
+
+config AR600x_SD31_XXX
+ bool "SD31-xxx"
+ help
+ Board Data file for a standard SD31 reference design (File: bdata.SD31.bin)
+
+config AR600x_WB31_XXX
+ bool "WB31-xxx"
+ help
+ Board Data file for a standard WB31 (BT/WiFi) reference design (File: bdata.WB31.bin)
+
+config AR600x_SD32_XXX
+ bool "SD32-xxx"
+ help
+ Board Data file for a standard SD32 (5GHz) reference design (File: bdata.SD32.bin)
+
+config AR600x_CUSTOM_XXX
+ bool "CUSTOM-xxx"
+ help
+ Board Data file for a custom reference design (File: should be named as bdata.CUSTOM.bin)
+endchoice
+
+config ATH6KL_ENABLE_COEXISTENCE
+ bool "BT Coexistence support"
+ depends on ATH6K_LEGACY
+ help
+ Enables WLAN/BT coexistence support. Select the apprpriate configuration from below.
+
+choice
+ prompt "Front-End Antenna Configuration"
+ depends on ATH6KL_ENABLE_COEXISTENCE
+ default AR600x_DUAL_ANTENNA
+ help
+ Indicates the number of antennas being used by BT and WLAN. Select the appropriate configuration from the list below that matches your AR6003 based reference design.
+
+config AR600x_DUAL_ANTENNA
+ bool "Dual Antenna"
+ help
+ Dual Antenna Design
+
+config AR600x_SINGLE_ANTENNA
+ bool "Single Antenna"
+ help
+ Single Antenna Design
+endchoice
+
+choice
+ prompt "Collocated Bluetooth Type"
+ depends on ATH6KL_ENABLE_COEXISTENCE
+ default AR600x_BT_AR3001
+ help
+ Select the appropriate configuration from the list below that matches your AR6003 based reference design.
+
+config AR600x_BT_QCOM
+ bool "Qualcomm BTS4020X"
+ help
+ Qualcomm BT (3 Wire PTA)
+
+config AR600x_BT_CSR
+ bool "CSR BC06"
+ help
+ CSR BT (3 Wire PTA)
+
+config AR600x_BT_AR3001
+ bool "Atheros AR3001"
+ help
+ Atheros BT (3 Wire PTA)
+endchoice
+
+config ATH6KL_HCI_BRIDGE
+ bool "HCI over SDIO support"
+ depends on ATH6K_LEGACY
+ help
+ Enables BT over SDIO. Applicable only for combo designs (eg: WB31)
+
+config ATH6KL_CONFIG_GPIO_BT_RESET
+ bool "Configure BT Reset GPIO"
+ depends on ATH6KL_HCI_BRIDGE
+ help
+ Configure a WLAN GPIO for use with BT.
+
+config AR600x_BT_RESET_PIN
+ int "GPIO"
+ depends on ATH6KL_CONFIG_GPIO_BT_RESET
+ default 22
+ help
+ WLAN GPIO to be used for resetting BT
+
+config ATH6KL_CFG80211
+ bool "CFG80211 support"
+ depends on ATH6K_LEGACY
+ help
+ Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space.
+
+config ATH6KL_HTC_RAW_INTERFACE
+ bool "RAW HTC support"
+ depends on ATH6K_LEGACY
+ help
+ Enables raw HTC interface. Allows application to directly talk to the HTC interface via the ioctl interface
+
+config ATH6KL_VIRTUAL_SCATTER_GATHER
+ bool "Virtual Scatter-Gather support"
+ depends on ATH6K_LEGACY
+ help
+ Enables virtual scatter gather support for the hardware that does not support it natively.
+
+config ATH6KL_SKIP_ABI_VERSION_CHECK
+ bool "Skip ABI version check support"
+ depends on ATH6K_LEGACY
+ help
+ Forces the driver to disable ABI version check. Caution: Incompatilbity between the host driver and target firmware may lead to unknown side effects.
+
+config ATH6KL_BT_UART_FC_POLARITY
+ int "UART Flow Control Polarity"
+ depends on ATH6KL_LEGACY
+ default 0
+ help
+ Configures the polarity of UART Flow Control. A value of 0 implies active low and is the default setting. Set it to 1 for active high.
+
+config ATH6KL_DEBUG
+ bool "Debug support"
+ depends on ATH6K_LEGACY
+ help
+ Enables debug support
+
+config ATH6KL_ENABLE_HOST_DEBUG
+ bool "Host Debug support"
+ depends on ATH6KL_DEBUG
+ help
+ Enables debug support in the driver
+
+config ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
+ bool "Target Debug support - Enable UART prints"
+ depends on ATH6KL_DEBUG
+ help
+ Enables uart prints
+
+config AR600x_DEBUG_UART_TX_PIN
+ int "GPIO"
+ depends on ATH6KL_ENABLE_TARGET_DEBUG_PRINTS
+ default 8
+ help
+ WLAN GPIO to be used for Debug UART (Tx)
+
+config ATH6KL_DISABLE_TARGET_DBGLOGS
+ bool "Target Debug support - Disable Debug logs"
+ depends on ATH6KL_DEBUG
+ help
+ Enables debug logs
diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile
new file mode 100644
index 000000000000..ab68078699f2
--- /dev/null
+++ b/drivers/staging/ath6kl/Makefile
@@ -0,0 +1,159 @@
+#------------------------------------------------------------------------------
+# Copyright (c) 2004-2010 Atheros Communications Inc.
+# All rights reserved.
+#
+#
+#
+# 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.
+#
+#
+#
+# Author(s): ="Atheros"
+#------------------------------------------------------------------------------
+
+ccflags-y += -I$(obj)/include
+ccflags-y += -I$(obj)/include/common
+ccflags-y += -I$(obj)/wlan/include
+ccflags-y += -I$(obj)/os/linux/include
+ccflags-y += -I$(obj)/os
+ccflags-y += -I$(obj)/bmi/include
+ccflags-y += -I$(obj)/include/common/AR6002/hw4.0
+
+ifeq ($(CONFIG_AR600x_SD31_XXX),y)
+ccflags-y += -DAR600x_SD31_XXX
+endif
+
+ifeq ($(CONFIG_AR600x_WB31_XXX),y)
+ccflags-y += -DAR600x_WB31_XXX
+endif
+
+ifeq ($(CONFIG_AR600x_SD32_XXX),y)
+ccflags-y += -DAR600x_SD32_XXX
+endif
+
+ifeq ($(CONFIG_AR600x_CUSTOM_XXX),y)
+ccflags-y += -DAR600x_CUSTOM_XXX
+endif
+
+ifeq ($(CONFIG_ATH6KL_ENABLE_COEXISTENCE),y)
+ccflags-y += -DENABLE_COEXISTENCE
+endif
+
+ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y)
+ccflags-y += -DAR600x_DUAL_ANTENNA
+endif
+
+ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y)
+ccflags-y += -DAR600x_SINGLE_ANTENNA
+endif
+
+ifeq ($(CONFIG_AR600x_BT_QCOM),y)
+ccflags-y += -DAR600x_BT_QCOM
+endif
+
+ifeq ($(CONFIG_AR600x_BT_CSR),y)
+ccflags-y += -DAR600x_BT_CSR
+endif
+
+ifeq ($(CONFIG_AR600x_BT_AR3001),y)
+ccflags-y += -DAR600x_BT_AR3001
+endif
+
+ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y)
+ccflags-y += -DATH_AR6K_ENABLE_GMBOX
+ccflags-y += -DHCI_TRANSPORT_SDIO
+ccflags-y += -DSETUPHCI_ENABLED
+ccflags-y += -DSETUPBTDEV_ENABLED
+ath6kl-y += htc2/AR6000/ar6k_gmbox.o
+ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o
+ath6kl-y += miscdrv/ar3kconfig.o
+ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o
+ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o
+endif
+
+ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y)
+ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET
+endif
+
+ifeq ($(CONFIG_ATH6KL_CFG80211),y)
+ccflags-y += -DATH6K_CONFIG_CFG80211
+ath6kl-y += os/linux/cfg80211.o
+endif
+
+ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y)
+ccflags-y += -DHTC_RAW_INTERFACE
+endif
+
+ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y)
+ccflags-y += -DDEBUG
+ccflags-y += -DATH_DEBUG_MODULE
+endif
+
+ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y)
+ccflags-y += -DENABLEUARTPRINT_SET
+endif
+
+ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y)
+ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS
+endif
+
+ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y)
+ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
+endif
+
+ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y)
+ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK
+endif
+
+ccflags-y += -DLINUX -DKERNEL_2_6
+ccflags-y += -DTCMD
+ccflags-y += -DSEND_EVENT_TO_APP
+ccflags-y += -DUSER_KEYS
+ccflags-y += -DNO_SYNC_FLUSH
+ccflags-y += -DHTC_EP_STAT_PROFILING
+ccflags-y += -DATH_AR6K_11N_SUPPORT
+ccflags-y += -DWAPI_ENABLE
+ccflags-y += -DCHECKSUM_OFFLOAD
+ccflags-y += -DWLAN_HEADERS
+ccflags-y += -DINIT_MODE_DRV_ENABLED
+ccflags-y += -DBMIENABLE_SET
+
+obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o
+ath6kl-y += htc2/AR6000/ar6k.o
+ath6kl-y += htc2/AR6000/ar6k_events.o
+ath6kl-y += htc2/htc_send.o
+ath6kl-y += htc2/htc_recv.o
+ath6kl-y += htc2/htc_services.o
+ath6kl-y += htc2/htc.o
+ath6kl-y += bmi/src/bmi.o
+ath6kl-y += os/linux/ar6000_drv.o
+ath6kl-y += os/linux/ar6000_raw_if.o
+ath6kl-y += os/linux/ar6000_pm.o
+ath6kl-y += os/linux/netbuf.o
+ath6kl-y += os/linux/wireless_ext.o
+ath6kl-y += os/linux/ioctl.o
+ath6kl-y += os/linux/hci_bridge.o
+ath6kl-y += os/linux/ar6k_pal.o
+ath6kl-y += miscdrv/common_drv.o
+ath6kl-y += miscdrv/credit_dist.o
+ath6kl-y += wmi/wmi.o
+ath6kl-y += reorder/rcv_aggr.o
+ath6kl-y += wlan/src/wlan_node.o
+ath6kl-y += wlan/src/wlan_recv_beacon.o
+ath6kl-y += wlan/src/wlan_utils.o
+
+# ATH_HIF_TYPE := sdio
+ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include
+ccflags-y += -DSDIO
+ath6kl-y += hif/sdio/linux_sdio/src/hif.o
+ath6kl-y += hif/sdio/linux_sdio/src/hif_scatter.o
diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO
new file mode 100644
index 000000000000..d4629274397d
--- /dev/null
+++ b/drivers/staging/ath6kl/TODO
@@ -0,0 +1,8 @@
+- The driver is a stop-gap measure until a proper mac80211 driver is available.
+- The driver does not conform to the Linux coding style.
+- The driver has been tested on a wide variety of embedded platforms running different versions of the Linux kernel but may still have bringup/performance issues with a new platform.
+- Pls use the following link to get information about the driver's architecture, exposed APIs, supported features, limitations, testing, hardware availability and other details.
+ http://wireless.kernel.org/en/users/Drivers/ath6kl
+- Pls send any patches to
+ - Greg Kroah-Hartman <greg@kroah.com>
+ - Vipin Mehta <vmehta@atheros.com>
diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
new file mode 100644
index 000000000000..a44027cee4ea
--- /dev/null
+++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef BMI_INTERNAL_H
+#define BMI_INTERNAL_H
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#define ATH_MODULE_NAME bmi
+#include "a_debug.h"
+#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "bmi_msg.h"
+
+#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
+
+
+#define BMI_COMMUNICATION_TIMEOUT 100000
+
+/* ------ Global Variable Declarations ------- */
+static A_BOOL bmiDone;
+
+A_STATUS
+bmiBufferSend(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+bmiBufferReceive(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_BOOL want_timeout);
+
+#endif
diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c
new file mode 100644
index 000000000000..f17f5636f5b2
--- /dev/null
+++ b/drivers/staging/ath6kl/bmi/src/bmi.c
@@ -0,0 +1,1010 @@
+//------------------------------------------------------------------------------
+// <copyright file="bmi.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+
+#ifdef THREAD_X
+#include <string.h>
+#endif
+
+#include "hif.h"
+#include "bmi.h"
+#include "htc_api.h"
+#include "bmi_internal.h"
+
+#ifdef ATH_DEBUG_MODULE
+static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
+ { ATH_DEBUG_BMI , "BMI Tracing"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
+ "bmi",
+ "Boot Manager Interface",
+ ATH_DEBUG_MASK_DEFAULTS,
+ ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
+ bmi_debug_desc);
+
+#endif
+
+/*
+Although we had envisioned BMI to run on top of HTC, this is not how the
+final implementation ended up. On the Target side, BMI is a part of the BSP
+and does not use the HTC protocol nor even DMA -- it is intentionally kept
+very simple.
+*/
+
+static A_BOOL pendingEventsFuncCheck = FALSE;
+static A_UINT32 *pBMICmdCredits;
+static A_UCHAR *pBMICmdBuf;
+#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
+ sizeof(A_UINT32) /* cmd */ + \
+ sizeof(A_UINT32) /* addr */ + \
+ sizeof(A_UINT32))/* length */
+#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
+
+/* APIs visible to the driver */
+void
+BMIInit(void)
+{
+ bmiDone = FALSE;
+ pendingEventsFuncCheck = FALSE;
+
+ /*
+ * On some platforms, it's not possible to DMA to a static variable
+ * in a device driver (e.g. Linux loadable driver module).
+ * So we need to A_MALLOC space for "command credits" and for commands.
+ *
+ * Note: implicitly relies on A_MALLOC to provide a buffer that is
+ * suitable for DMA (or PIO). This buffer will be passed down the
+ * bus stack.
+ */
+ if (!pBMICmdCredits) {
+ pBMICmdCredits = (A_UINT32 *)A_MALLOC_NOWAIT(4);
+ A_ASSERT(pBMICmdCredits);
+ }
+
+ if (!pBMICmdBuf) {
+ pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
+ A_ASSERT(pBMICmdBuf);
+ }
+
+ A_REGISTER_MODULE_DEBUG_INFO(bmi);
+}
+
+void
+BMICleanup(void)
+{
+ if (pBMICmdCredits) {
+ A_FREE(pBMICmdCredits);
+ pBMICmdCredits = NULL;
+ }
+
+ if (pBMICmdBuf) {
+ A_FREE(pBMICmdBuf);
+ pBMICmdBuf = NULL;
+ }
+}
+
+A_STATUS
+BMIDone(HIF_DEVICE *device)
+{
+ A_STATUS status;
+ A_UINT32 cid;
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
+ return A_OK;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
+ bmiDone = TRUE;
+ cid = BMI_DONE;
+
+ status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ if (pBMICmdCredits) {
+ A_FREE(pBMICmdCredits);
+ pBMICmdCredits = NULL;
+ }
+
+ if (pBMICmdBuf) {
+ A_FREE(pBMICmdBuf);
+ pBMICmdBuf = NULL;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
+
+ return A_OK;
+}
+
+A_STATUS
+BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
+{
+ A_STATUS status;
+ A_UINT32 cid;
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
+ cid = BMI_GET_TARGET_INFO;
+
+ status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver,
+ sizeof(targ_info->target_ver), TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
+ return A_ERROR;
+ }
+
+ if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
+ /* Determine how many bytes are in the Target's targ_info */
+ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count,
+ sizeof(targ_info->target_info_byte_count), TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
+ return A_ERROR;
+ }
+
+ /*
+ * The Target's targ_info doesn't match the Host's targ_info.
+ * We need to do some backwards compatibility work to make this OK.
+ */
+ A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
+
+ /* Read the remainder of the targ_info */
+ status = bmiBufferReceive(device,
+ ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count),
+ sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
+ targ_info->target_info_byte_count));
+ return A_ERROR;
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
+ targ_info->target_ver, targ_info->target_type));
+
+ return A_OK;
+}
+
+A_STATUS
+BMIReadMemory(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+ A_UINT32 remaining, rxlen;
+
+ A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
+ memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
+ device, address, length));
+
+ cid = BMI_READ_MEMORY;
+
+ remaining = length;
+
+ while (remaining)
+ {
+ rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
+ offset += sizeof(length);
+
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+ status = bmiBufferReceive(device, pBMICmdBuf, rxlen, TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
+ return A_ERROR;
+ }
+ A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen);
+ remaining -= rxlen; address += rxlen;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
+ return A_OK;
+}
+
+A_STATUS
+BMIWriteMemory(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+ A_UINT32 remaining, txlen;
+ const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
+ A_UCHAR alignedBuffer[BMI_DATASZ_MAX];
+ A_UCHAR *src;
+
+ A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
+ memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
+ device, address, length));
+
+ cid = BMI_WRITE_MEMORY;
+
+ remaining = length;
+ while (remaining)
+ {
+ src = &buffer[length - remaining];
+ if (remaining < (BMI_DATASZ_MAX - header)) {
+ if (remaining & 3) {
+ /* align it with 4 bytes */
+ remaining = remaining + (4 - (remaining & 3));
+ memcpy(alignedBuffer, src, remaining);
+ src = alignedBuffer;
+ }
+ txlen = remaining;
+ } else {
+ txlen = (BMI_DATASZ_MAX - header);
+ }
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
+ offset += sizeof(txlen);
+ A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen);
+ offset += txlen;
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+ remaining -= txlen; address += txlen;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
+
+ return A_OK;
+}
+
+A_STATUS
+BMIExecute(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 *param)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
+ device, address, *param));
+
+ cid = BMI_EXECUTE;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param));
+ offset += sizeof(*param);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), FALSE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
+ return A_ERROR;
+ }
+
+ A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
+ return A_OK;
+}
+
+A_STATUS
+BMISetAppStart(HIF_DEVICE *device,
+ A_UINT32 address)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
+ device, address));
+
+ cid = BMI_SET_APP_START;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
+ return A_OK;
+}
+
+A_STATUS
+BMIReadSOCRegister(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 *param)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
+ device, address));
+
+ cid = BMI_READ_SOC_REGISTER;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
+ return A_ERROR;
+ }
+ A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
+ return A_OK;
+}
+
+A_STATUS
+BMIWriteSOCRegister(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 param)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
+ device, address, param));
+
+ cid = BMI_WRITE_SOC_REGISTER;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &param, sizeof(param));
+ offset += sizeof(param);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
+ return A_OK;
+}
+
+A_STATUS
+BMIrompatchInstall(HIF_DEVICE *device,
+ A_UINT32 ROM_addr,
+ A_UINT32 RAM_addr,
+ A_UINT32 nbytes,
+ A_UINT32 do_activate,
+ A_UINT32 *rompatch_id)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
+ sizeof(nbytes) + sizeof(do_activate)));
+ memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
+ sizeof(nbytes) + sizeof(do_activate));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
+ device, ROM_addr, RAM_addr, nbytes, do_activate));
+
+ cid = BMI_ROMPATCH_INSTALL;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
+ offset += sizeof(ROM_addr);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
+ offset += sizeof(RAM_addr);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
+ offset += sizeof(nbytes);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
+ offset += sizeof(do_activate);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), TRUE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
+ return A_ERROR;
+ }
+ A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
+ return A_OK;
+}
+
+A_STATUS
+BMIrompatchUninstall(HIF_DEVICE *device,
+ A_UINT32 rompatch_id)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
+ device, rompatch_id));
+
+ cid = BMI_ROMPATCH_UNINSTALL;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
+ offset += sizeof(rompatch_id);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
+ return A_OK;
+}
+
+static A_STATUS
+_BMIrompatchChangeActivation(HIF_DEVICE *device,
+ A_UINT32 rompatch_count,
+ A_UINT32 *rompatch_list,
+ A_UINT32 do_activate)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+ A_UINT32 length;
+
+ A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)));
+ memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
+ device, rompatch_count));
+
+ cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
+
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
+ offset += sizeof(rompatch_count);
+ length = rompatch_count * sizeof(*rompatch_list);
+ A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length);
+ offset += length;
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
+
+ return A_OK;
+}
+
+A_STATUS
+BMIrompatchActivate(HIF_DEVICE *device,
+ A_UINT32 rompatch_count,
+ A_UINT32 *rompatch_list)
+{
+ return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
+}
+
+A_STATUS
+BMIrompatchDeactivate(HIF_DEVICE *device,
+ A_UINT32 rompatch_count,
+ A_UINT32 *rompatch_list)
+{
+ return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
+}
+
+A_STATUS
+BMILZData(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+ A_UINT32 remaining, txlen;
+ const A_UINT32 header = sizeof(cid) + sizeof(length);
+
+ A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
+ memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
+ device, length));
+
+ cid = BMI_LZ_DATA;
+
+ remaining = length;
+ while (remaining)
+ {
+ txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
+ remaining : (BMI_DATASZ_MAX - header);
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
+ offset += sizeof(txlen);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
+ offset += txlen;
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
+ return A_ERROR;
+ }
+ remaining -= txlen;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
+
+ return A_OK;
+}
+
+A_STATUS
+BMILZStreamStart(HIF_DEVICE *device,
+ A_UINT32 address)
+{
+ A_UINT32 cid;
+ A_STATUS status;
+ A_UINT32 offset;
+
+ A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
+ memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
+
+ if (bmiDone) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
+ ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
+ device, address));
+
+ cid = BMI_LZ_STREAM_START;
+ offset = 0;
+ A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
+ offset += sizeof(address);
+ status = bmiBufferSend(device, pBMICmdBuf, offset);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
+ return A_ERROR;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
+
+ return A_OK;
+}
+
+/* BMI Access routines */
+A_STATUS
+bmiBufferSend(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length)
+{
+ A_STATUS status;
+ A_UINT32 timeout;
+ A_UINT32 address;
+ A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
+
+ HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
+ &mboxAddress[0], sizeof(mboxAddress));
+
+ *pBMICmdCredits = 0;
+ timeout = BMI_COMMUNICATION_TIMEOUT;
+
+ while(timeout-- && !(*pBMICmdCredits)) {
+ /* Read the counter register to get the command credits */
+ address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
+ /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
+ * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to
+ * make all HIF accesses 4-byte aligned */
+ status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4,
+ HIF_RD_SYNC_BYTE_INC, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
+ return A_ERROR;
+ }
+ /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
+ (*pBMICmdCredits) &= 0xFF;
+ }
+
+ if (*pBMICmdCredits) {
+ address = mboxAddress[ENDPOINT1];
+ status = HIFReadWrite(device, address, buffer, length,
+ HIF_WR_SYNC_BYTE_INC, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
+ return A_ERROR;
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
+ return A_ERROR;
+ }
+
+ return status;
+}
+
+A_STATUS
+bmiBufferReceive(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_BOOL want_timeout)
+{
+ A_STATUS status;
+ A_UINT32 address;
+ A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
+ HIF_PENDING_EVENTS_INFO hifPendingEvents;
+ static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
+
+ if (!pendingEventsFuncCheck) {
+ /* see if the HIF layer implements an alternative function to get pending events
+ * do this only once! */
+ HIFConfigureDevice(device,
+ HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
+ &getPendingEventsFunc,
+ sizeof(getPendingEventsFunc));
+ pendingEventsFuncCheck = TRUE;
+ }
+
+ HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
+ &mboxAddress[0], sizeof(mboxAddress));
+
+ /*
+ * During normal bootup, small reads may be required.
+ * Rather than issue an HIF Read and then wait as the Target
+ * adds successive bytes to the FIFO, we wait here until
+ * we know that response data is available.
+ *
+ * This allows us to cleanly timeout on an unexpected
+ * Target failure rather than risk problems at the HIF level. In
+ * particular, this avoids SDIO timeouts and possibly garbage
+ * data on some host controllers. And on an interconnect
+ * such as Compact Flash (as well as some SDIO masters) which
+ * does not provide any indication on data timeout, it avoids
+ * a potential hang or garbage response.
+ *
+ * Synchronization is more difficult for reads larger than the
+ * size of the MBOX FIFO (128B), because the Target is unable
+ * to push the 129th byte of data until AFTER the Host posts an
+ * HIF Read and removes some FIFO data. So for large reads the
+ * Host proceeds to post an HIF Read BEFORE all the data is
+ * actually available to read. Fortunately, large BMI reads do
+ * not occur in practice -- they're supported for debug/development.
+ *
+ * So Host/Target BMI synchronization is divided into these cases:
+ * CASE 1: length < 4
+ * Should not happen
+ *
+ * CASE 2: 4 <= length <= 128
+ * Wait for first 4 bytes to be in FIFO
+ * If CONSERVATIVE_BMI_READ is enabled, also wait for
+ * a BMI command credit, which indicates that the ENTIRE
+ * response is available in the the FIFO
+ *
+ * CASE 3: length > 128
+ * Wait for the first 4 bytes to be in FIFO
+ *
+ * For most uses, a small timeout should be sufficient and we will
+ * usually see a response quickly; but there may be some unusual
+ * (debug) cases of BMI_EXECUTE where we want an larger timeout.
+ * For now, we use an unbounded busy loop while waiting for
+ * BMI_EXECUTE.
+ *
+ * If BMI_EXECUTE ever needs to support longer-latency execution,
+ * especially in production, this code needs to be enhanced to sleep
+ * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
+ * a function of Host processor speed.
+ */
+ if (length >= 4) { /* NB: Currently, always true */
+ /*
+ * NB: word_available is declared static for esoteric reasons
+ * having to do with protection on some OSes.
+ */
+ static A_UINT32 word_available;
+ A_UINT32 timeout;
+
+ word_available = 0;
+ timeout = BMI_COMMUNICATION_TIMEOUT;
+ while((!want_timeout || timeout--) && !word_available) {
+
+ if (getPendingEventsFunc != NULL) {
+ status = getPendingEventsFunc(device,
+ &hifPendingEvents,
+ NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
+ break;
+ }
+
+ if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) {
+ word_available = 1;
+ }
+ continue;
+ }
+
+ status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *)&word_available,
+ sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n"));
+ return A_ERROR;
+ }
+ /* We did a 4-byte read to the same register; all we really want is one bit */
+ word_available &= (1 << ENDPOINT1);
+ }
+
+ if (!word_available) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n"));
+ return A_ERROR;
+ }
+ }
+
+#define CONSERVATIVE_BMI_READ 0
+#if CONSERVATIVE_BMI_READ
+ /*
+ * This is an extra-conservative CREDIT check. It guarantees
+ * that ALL data is available in the FIFO before we start to
+ * read from the interconnect.
+ *
+ * This credit check is useless when firmware chooses to
+ * allow multiple outstanding BMI Command Credits, since the next
+ * credit will already be present. To restrict the Target to one
+ * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
+ *
+ * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
+ * we cannot wait for the next credit because the Target's FIFO
+ * will not hold the entire response. So we need the Host to
+ * start to empty the FIFO sooner. (And again, large reads are
+ * not used in practice; they are for debug/development only.)
+ *
+ * For a more conservative Host implementation (which would be
+ * safer for a Compact Flash interconnect):
+ * Set CONSERVATIVE_BMI_READ (above) to 1
+ * Set HI_OPTION_BMI_CRED_LIMIT and
+ * reduce BMI_DATASZ_MAX to 32 or 64
+ */
+ if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
+ A_UINT32 timeout;
+
+ *pBMICmdCredits = 0;
+ timeout = BMI_COMMUNICATION_TIMEOUT;
+ while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
+ /* Read the counter register to get the command credits */
+ address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
+ /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing,
+ * we can read this counter multiple times using a non-incrementing address mode.
+ * The rationale here is to make all HIF accesses a multiple of 4 bytes */
+ status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
+ HIF_RD_SYNC_BYTE_FIX, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
+ return A_ERROR;
+ }
+ /* we did a 4-byte read to the same count register so mask off upper bytes */
+ (*pBMICmdCredits) &= 0xFF;
+ }
+
+ if (!(*pBMICmdCredits)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n"));
+ return A_ERROR;
+ }
+ }
+#endif
+
+ address = mboxAddress[ENDPOINT1];
+ status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
+ return A_ERROR;
+ }
+
+ return A_OK;
+}
+
+A_STATUS
+BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length)
+{
+ A_STATUS status = A_ERROR;
+ A_UINT32 lastWord = 0;
+ A_UINT32 lastWordOffset = length & ~0x3;
+ A_UINT32 unalignedBytes = length & 0x3;
+
+ status = BMILZStreamStart (device, address);
+ if (A_FAILED(status)) {
+ return A_ERROR;
+ }
+
+ if (unalignedBytes) {
+ /* copy the last word into a zero padded buffer */
+ A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes);
+ }
+
+ status = BMILZData(device, buffer, lastWordOffset);
+
+ if (A_FAILED(status)) {
+ return A_ERROR;
+ }
+
+ if (unalignedBytes) {
+ status = BMILZData(device, (A_UINT8 *)&lastWord, 4);
+ }
+
+ if (A_SUCCESS(status)) {
+ //
+ // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches.
+ //
+ status = BMILZStreamStart (device, 0x00);
+ if (A_FAILED(status)) {
+ return A_ERROR;
+ }
+ }
+ return status;
+}
+
+A_STATUS
+BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
+{
+ return bmiBufferSend(device, buffer, length);
+}
+
+A_STATUS
+BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout)
+{
+ return bmiBufferReceive(device, buffer, length, want_timeout);
+}
diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
new file mode 100644
index 000000000000..0f4e913cb13b
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h
@@ -0,0 +1,87 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// common header file for HIF modules designed for SDIO
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef HIF_SDIO_COMMON_H_
+#define HIF_SDIO_COMMON_H_
+
+ /* SDIO manufacturer ID and Codes */
+#define MANUFACTURER_ID_AR6002_BASE 0x200
+#define MANUFACTURER_ID_AR6003_BASE 0x300
+#define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00
+#define FUNCTION_CLASS 0x0
+#define MANUFACTURER_CODE 0x271 /* Atheros */
+
+ /* Mailbox address in SDIO address space */
+#define HIF_MBOX_BASE_ADDR 0x800
+#define HIF_MBOX_WIDTH 0x800
+#define HIF_MBOX_START_ADDR(mbox) \
+ ( HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH)
+
+#define HIF_MBOX_END_ADDR(mbox) \
+ (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1)
+
+ /* extended MBOX address for larger MBOX writes to MBOX 0*/
+#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800
+#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024)
+#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024)
+
+ /* version 1 of the chip has only a 12K extended mbox range */
+#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000
+#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024)
+
+ /* GMBOX addresses */
+#define HIF_GMBOX_BASE_ADDR 0x7000
+#define HIF_GMBOX_WIDTH 0x4000
+
+ /* for SDIO we recommend a 128-byte block size */
+#define HIF_DEFAULT_IO_BLOCK_SIZE 128
+
+ /* set extended MBOX window information for SDIO interconnects */
+static INLINE void SetExtendedMboxWindowInfo(A_UINT16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo)
+{
+ switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) {
+ case MANUFACTURER_ID_AR6002_BASE :
+ /* MBOX 0 has an extended range */
+ pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR;
+ pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002;
+ break;
+ case MANUFACTURER_ID_AR6003_BASE :
+ /* MBOX 0 has an extended range */
+ pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1;
+ pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
+ pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR;
+ pInfo->GMboxSize = HIF_GMBOX_WIDTH;
+ break;
+ default:
+ A_ASSERT(FALSE);
+ break;
+ }
+}
+
+/* special CCCR (func 0) registers */
+
+#define CCCR_SDIO_IRQ_MODE_REG 0xF0 /* interrupt mode register */
+#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) /* mode to enable special 4-bit interrupt assertion without clock*/
+
+#endif /*HIF_SDIO_COMMON_H_*/
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
new file mode 100644
index 000000000000..857f35f36ca2
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+// <copyright file="hif_internal.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// internal header file for hif layer
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HIF_INTERNAL_H_
+#define _HIF_INTERNAL_H_
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "hif.h"
+#include "../../../common/hif_sdio_common.h"
+#include <linux/scatterlist.h>
+#define HIF_LINUX_MMC_SCATTER_SUPPORT
+
+#define BUS_REQUEST_MAX_NUM 64
+
+#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000
+#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20
+#define FLAGS_CARD_ENAB 0x02
+#define FLAGS_CARD_IRQ_UNMSK 0x04
+
+#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE
+#define HIF_MBOX0_BLOCK_SIZE 1
+#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+
+struct _HIF_SCATTER_REQ_PRIV;
+
+typedef struct bus_request {
+ struct bus_request *next; /* link list of available requests */
+ struct bus_request *inusenext; /* link list of in use requests */
+ struct semaphore sem_req;
+ A_UINT32 address; /* request data */
+ A_UCHAR *buffer;
+ A_UINT32 length;
+ A_UINT32 request;
+ void *context;
+ A_STATUS status;
+ struct _HIF_SCATTER_REQ_PRIV *pScatterReq; /* this request is a scatter request */
+} BUS_REQUEST;
+
+struct hif_device {
+ struct sdio_func *func;
+ spinlock_t asynclock;
+ struct task_struct* async_task; /* task to handle async commands */
+ struct semaphore sem_async; /* wake up for async task */
+ int async_shutdown; /* stop the async task */
+ struct completion async_completion; /* thread completion */
+ BUS_REQUEST *asyncreq; /* request for async tasklet */
+ BUS_REQUEST *taskreq; /* async tasklet data */
+ spinlock_t lock;
+ BUS_REQUEST *s_busRequestFreeQueue; /* free list */
+ BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */
+ void *claimedContext;
+ HTC_CALLBACKS htcCallbacks;
+ A_UINT8 *dma_buffer;
+ DL_LIST ScatterReqHead; /* scatter request list head */
+ A_BOOL scatter_enabled; /* scatter enabled flag */
+ A_BOOL is_suspend;
+ A_BOOL is_disabled;
+ atomic_t irqHandling;
+ HIF_DEVICE_POWER_CHANGE_TYPE powerConfig;
+ const struct sdio_device_id *id;
+};
+
+#define HIF_DMA_BUFFER_SIZE (32 * 1024)
+#define CMD53_FIXED_ADDRESS 1
+#define CMD53_INCR_ADDRESS 2
+
+BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device);
+void hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest);
+void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest);
+
+#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
+
+#define MAX_SCATTER_REQUESTS 4
+#define MAX_SCATTER_ENTRIES_PER_REQ 16
+#define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024
+
+typedef struct _HIF_SCATTER_REQ_PRIV {
+ HIF_SCATTER_REQ *pHifScatterReq; /* HIF scatter request with allocated entries */
+ HIF_DEVICE *device; /* this device */
+ BUS_REQUEST *busrequest; /* request associated with request */
+ /* scatter list for linux */
+ struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ];
+} HIF_SCATTER_REQ_PRIV;
+
+#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0)
+
+A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo);
+void CleanupHIFScatterResources(HIF_DEVICE *device);
+A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest);
+
+#else // HIF_LINUX_MMC_SCATTER_SUPPORT
+
+static inline A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
+{
+ return A_ENOTSUP;
+}
+
+static inline A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest)
+{
+ return A_ENOTSUP;
+}
+
+#define CleanupHIFScatterResources(d) { }
+
+#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
+
+#endif // _HIF_INTERNAL_H_
+
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
new file mode 100644
index 000000000000..c307a5559362
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
@@ -0,0 +1,1298 @@
+//------------------------------------------------------------------------------
+// <copyright file="hif.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HIF layer reference implementation for Linux Native MMC stack
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sd.h>
+#include <linux/kthread.h>
+
+/* by default setup a bounce buffer for the data packets, if the underlying host controller driver
+ does not use DMA you may be able to skip this step and save the memory allocation and transfer time */
+#define HIF_USE_DMA_BOUNCE_BUFFER 1
+#include "hif_internal.h"
+#define ATH_MODULE_NAME hif
+#include "a_debug.h"
+#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+
+#if HIF_USE_DMA_BOUNCE_BUFFER
+/* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the
+ * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack).
+ * virt_addr_valid check fails on stack memory.
+ */
+#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer)))
+#else
+#define BUFFER_NEEDS_BOUNCE(buffer) (FALSE)
+#endif
+
+/* ATHENV */
+#if defined(CONFIG_PM)
+#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev)
+#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv)
+static int hifDeviceSuspend(struct device *dev);
+static int hifDeviceResume(struct device *dev);
+#endif /* CONFIG_PM */
+static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id);
+static void hifDeviceRemoved(struct sdio_func *func);
+static HIF_DEVICE *addHifDevice(struct sdio_func *func);
+static HIF_DEVICE *getHifDevice(struct sdio_func *func);
+static void delHifDevice(HIF_DEVICE * device);
+static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
+static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
+
+int reset_sdio_on_unload = 0;
+module_param(reset_sdio_on_unload, int, 0644);
+
+extern A_UINT32 nohifscattersupport;
+
+
+/* ------ Static Variables ------ */
+static const struct sdio_device_id ar6k_id_table[] = {
+ { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
+ { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
+ { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
+ { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
+ { /* null */ },
+};
+MODULE_DEVICE_TABLE(sdio, ar6k_id_table);
+
+static struct sdio_driver ar6k_driver = {
+ .name = "ar6k_wlan",
+ .id_table = ar6k_id_table,
+ .probe = hifDeviceInserted,
+ .remove = hifDeviceRemoved,
+};
+
+#if defined(CONFIG_PM)
+/* New suspend/resume based on linux-2.6.32
+ * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch
+ * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host
+ */
+static struct dev_pm_ops ar6k_device_pm_ops = {
+ .suspend = hifDeviceSuspend,
+ .resume = hifDeviceResume,
+};
+#endif /* CONFIG_PM */
+
+/* make sure we only unregister when registered. */
+static int registered = 0;
+
+OSDRV_CALLBACKS osdrvCallbacks;
+extern A_UINT32 onebitmode;
+extern A_UINT32 busspeedlow;
+extern A_UINT32 debughif;
+
+static void ResetAllCards(void);
+static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func);
+static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func);
+
+#ifdef DEBUG
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif,
+ "hif",
+ "(Linux MMC) Host Interconnect Framework",
+ ATH_DEBUG_MASK_DEFAULTS,
+ 0,
+ NULL);
+
+#endif
+
+
+/* ------ Functions ------ */
+A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks)
+{
+ int status;
+ AR_DEBUG_ASSERT(callbacks != NULL);
+
+ A_REGISTER_MODULE_DEBUG_INFO(hif);
+
+ /* store the callback handlers */
+ osdrvCallbacks = *callbacks;
+
+ /* Register with bus driver core */
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n"));
+ registered = 1;
+#if defined(CONFIG_PM)
+ if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) {
+ ar6k_driver.drv.pm = &ar6k_device_pm_ops;
+ }
+#endif /* CONFIG_PM */
+ status = sdio_register_driver(&ar6k_driver);
+ AR_DEBUG_ASSERT(status==0);
+
+ if (status != 0) {
+ return A_ERROR;
+ }
+
+ return A_OK;
+
+}
+
+static A_STATUS
+__HIFReadWrite(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_UINT32 request,
+ void *context)
+{
+ A_UINT8 opcode;
+ A_STATUS status = A_OK;
+ int ret;
+ A_UINT8 *tbuffer;
+ A_BOOL bounced = FALSE;
+
+ AR_DEBUG_ASSERT(device != NULL);
+ AR_DEBUG_ASSERT(device->func != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n",
+ device, buffer, address));
+
+ do {
+ if (request & HIF_EXTENDED_IO) {
+ //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n"));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: Invalid command type: 0x%08x\n", request));
+ status = A_EINVAL;
+ break;
+ }
+
+ if (request & HIF_BLOCK_BASIS) {
+ /* round to whole block length size */
+ length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: Block mode (BlockLen: %d)\n",
+ length));
+ } else if (request & HIF_BYTE_BASIS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: Byte mode (BlockLen: %d)\n",
+ length));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: Invalid data mode: 0x%08x\n", request));
+ status = A_EINVAL;
+ break;
+ }
+
+#if 0
+ /* useful for checking register accesses */
+ if (length & 0x3) {
+ A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n",
+ request & HIF_WRITE ? "write":"read", address, length);
+ }
+#endif
+
+ if (request & HIF_WRITE) {
+ if ((address >= HIF_MBOX_START_ADDR(0)) &&
+ (address <= HIF_MBOX_END_ADDR(3)))
+ {
+
+ AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH);
+
+ /*
+ * Mailbox write. Adjust the address so that the last byte
+ * falls on the EOM address.
+ */
+ address += (HIF_MBOX_WIDTH - length);
+ }
+ }
+
+ if (request & HIF_FIXED_ADDRESS) {
+ opcode = CMD53_FIXED_ADDRESS;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address));
+ } else if (request & HIF_INCREMENTAL_ADDRESS) {
+ opcode = CMD53_INCR_ADDRESS;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: Invalid address mode: 0x%08x\n", request));
+ status = A_EINVAL;
+ break;
+ }
+
+ if (request & HIF_WRITE) {
+#if HIF_USE_DMA_BOUNCE_BUFFER
+ if (BUFFER_NEEDS_BOUNCE(buffer)) {
+ AR_DEBUG_ASSERT(device->dma_buffer != NULL);
+ tbuffer = device->dma_buffer;
+ /* copy the write data to the dma buffer */
+ AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
+ memcpy(tbuffer, buffer, length);
+ bounced = TRUE;
+ } else {
+ tbuffer = buffer;
+ }
+#else
+ tbuffer = buffer;
+#endif
+ if (opcode == CMD53_FIXED_ADDRESS) {
+ ret = sdio_writesb(device->func, address, tbuffer, length);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n",
+ ret, address, length, *(int *)tbuffer));
+ } else {
+ ret = sdio_memcpy_toio(device->func, address, tbuffer, length);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
+ ret, address, length, *(int *)tbuffer));
+ }
+ } else if (request & HIF_READ) {
+#if HIF_USE_DMA_BOUNCE_BUFFER
+ if (BUFFER_NEEDS_BOUNCE(buffer)) {
+ AR_DEBUG_ASSERT(device->dma_buffer != NULL);
+ AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
+ tbuffer = device->dma_buffer;
+ bounced = TRUE;
+ } else {
+ tbuffer = buffer;
+ }
+#else
+ tbuffer = buffer;
+#endif
+ if (opcode == CMD53_FIXED_ADDRESS) {
+ ret = sdio_readsb(device->func, tbuffer, address, length);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n",
+ ret, address, length, *(int *)tbuffer));
+ } else {
+ ret = sdio_memcpy_fromio(device->func, tbuffer, address, length);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
+ ret, address, length, *(int *)tbuffer));
+ }
+#if HIF_USE_DMA_BOUNCE_BUFFER
+ if (bounced) {
+ /* copy the read data from the dma buffer */
+ memcpy(buffer, tbuffer, length);
+ }
+#endif
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: Invalid direction: 0x%08x\n", request));
+ status = A_EINVAL;
+ break;
+ }
+
+ if (ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret));
+ status = A_ERROR;
+ }
+ } while (FALSE);
+
+ return status;
+}
+
+void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest)
+{
+ unsigned long flags;
+ BUS_REQUEST *async;
+ BUS_REQUEST *active;
+
+ spin_lock_irqsave(&device->asynclock, flags);
+ active = device->asyncreq;
+ if (active == NULL) {
+ device->asyncreq = busrequest;
+ device->asyncreq->inusenext = NULL;
+ } else {
+ for (async = device->asyncreq;
+ async != NULL;
+ async = async->inusenext) {
+ active = async;
+ }
+ active->inusenext = busrequest;
+ busrequest->inusenext = NULL;
+ }
+ spin_unlock_irqrestore(&device->asynclock, flags);
+}
+
+
+/* queue a read/write request */
+A_STATUS
+HIFReadWrite(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_UINT32 request,
+ void *context)
+{
+ A_STATUS status = A_OK;
+ BUS_REQUEST *busrequest;
+
+
+ AR_DEBUG_ASSERT(device != NULL);
+ AR_DEBUG_ASSERT(device->func != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address));
+
+ do {
+ if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){
+ /* serialize all requests through the async thread */
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n",
+ (request & HIF_ASYNCHRONOUS)?"Async":"Synch"));
+ busrequest = hifAllocateBusRequest(device);
+ if (busrequest == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n",
+ request & HIF_READ ? "READ":"WRITE", address, length));
+ return A_ERROR;
+ }
+ busrequest->address = address;
+ busrequest->buffer = buffer;
+ busrequest->length = length;
+ busrequest->request = request;
+ busrequest->context = context;
+
+ AddToAsyncList(device, busrequest);
+
+ if (request & HIF_SYNCHRONOUS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest));
+
+ /* wait for completion */
+ up(&device->sem_async);
+ if (down_interruptible(&busrequest->sem_req) != 0) {
+ /* interrupted, exit */
+ return A_ERROR;
+ } else {
+ A_STATUS status = busrequest->status;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n",
+ (unsigned long)busrequest, busrequest->status));
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request));
+ hifFreeBusRequest(device, busrequest);
+ return status;
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest));
+ up(&device->sem_async);
+ return A_PENDING;
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request));
+ status = A_EINVAL;
+ break;
+ }
+ } while(0);
+
+ return status;
+}
+/* thread to serialize all requests, both sync and async */
+static int async_task(void *param)
+ {
+ HIF_DEVICE *device;
+ BUS_REQUEST *request;
+ A_STATUS status;
+ unsigned long flags;
+
+ device = (HIF_DEVICE *)param;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n"));
+ set_current_state(TASK_INTERRUPTIBLE);
+ while(!device->async_shutdown) {
+ /* wait for work */
+ if (down_interruptible(&device->sem_async) != 0) {
+ /* interrupted, exit */
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n"));
+ break;
+ }
+ if (device->async_shutdown) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n"));
+ break;
+ }
+ /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */
+ sdio_claim_host(device->func);
+ spin_lock_irqsave(&device->asynclock, flags);
+ /* pull the request to work on */
+ while (device->asyncreq != NULL) {
+ request = device->asyncreq;
+ if (request->inusenext != NULL) {
+ device->asyncreq = request->inusenext;
+ } else {
+ device->asyncreq = NULL;
+ }
+ spin_unlock_irqrestore(&device->asynclock, flags);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request));
+
+ if (request->pScatterReq != NULL) {
+ A_ASSERT(device->scatter_enabled);
+ /* this is a queued scatter request, pass the request to scatter routine which
+ * executes it synchronously, note, no need to free the request since scatter requests
+ * are maintained on a separate list */
+ status = DoHifReadWriteScatter(device,request);
+ } else {
+ /* call HIFReadWrite in sync mode to do the work */
+ status = __HIFReadWrite(device, request->address, request->buffer,
+ request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
+ if (request->request & HIF_ASYNCHRONOUS) {
+ void *context = request->context;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request));
+ hifFreeBusRequest(device, request);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request));
+ device->htcCallbacks.rwCompletionHandler(context, status);
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request));
+ request->status = status;
+ up(&request->sem_req);
+ }
+ }
+ spin_lock_irqsave(&device->asynclock, flags);
+ }
+ spin_unlock_irqrestore(&device->asynclock, flags);
+ sdio_release_host(device->func);
+ }
+
+ complete_and_exit(&device->async_completion, 0);
+ return 0;
+}
+
+static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg, A_UINT32 flags, A_UINT32 *resp)
+{
+ struct mmc_command cmd;
+ A_INT32 err;
+ struct mmc_host *host;
+ struct sdio_func *func;
+
+ func = device->func;
+ host = func->card->host;
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ cmd.opcode = opcode;
+ cmd.arg = arg;
+ cmd.flags = flags;
+ err = mmc_wait_for_cmd(host, &cmd, 3);
+
+ if ((!err) && (resp)) {
+ *resp = cmd.resp[0];
+ }
+
+ return err;
+}
+
+A_STATUS ReinitSDIO(HIF_DEVICE *device)
+{
+ A_INT32 err;
+ struct mmc_host *host;
+ struct mmc_card *card;
+ struct sdio_func *func;
+ A_UINT8 cmd52_resp;
+ A_UINT32 clock;
+
+ func = device->func;
+ card = func->card;
+ host = card->host;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n"));
+ sdio_claim_host(func);
+
+ do {
+ if (!device->is_suspend) {
+ A_UINT32 resp;
+ A_UINT16 rca;
+ A_UINT32 i;
+ int bit = fls(host->ocr_avail) - 1;
+ /* emulate the mmc_power_up(...) */
+ host->ios.vdd = bit;
+ host->ios.chip_select = MMC_CS_DONTCARE;
+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+ host->ios.power_mode = MMC_POWER_UP;
+ host->ios.bus_width = MMC_BUS_WIDTH_1;
+ host->ios.timing = MMC_TIMING_LEGACY;
+ host->ops->set_ios(host, &host->ios);
+ /*
+ * This delay should be sufficient to allow the power supply
+ * to reach the minimum voltage.
+ */
+ msleep(2);
+
+ host->ios.clock = host->f_min;
+ host->ios.power_mode = MMC_POWER_ON;
+ host->ops->set_ios(host, &host->ios);
+
+ /*
+ * This delay must be at least 74 clock sizes, or 1 ms, or the
+ * time required to reach a stable voltage.
+ */
+ msleep(2);
+
+ /* Issue CMD0. Goto idle state */
+ host->ios.chip_select = MMC_CS_HIGH;
+ host->ops->set_ios(host, &host->ios);
+ msleep(1);
+ err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL);
+ host->ios.chip_select = MMC_CS_DONTCARE;
+ host->ops->set_ios(host, &host->ios);
+ msleep(1);
+ host->use_spi_crc = 0;
+
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err));
+ break;
+ }
+
+ if (!host->ocr) {
+ /* Issue CMD5, arg = 0 */
+ err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
+ break;
+ }
+ host->ocr = resp;
+ }
+
+ /* Issue CMD5, arg = ocr. Wait till card is ready */
+ for (i=0;i<100;i++) {
+ err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err));
+ break;
+ }
+ if (resp & MMC_CARD_BUSY) {
+ break;
+ }
+ msleep(10);
+ }
+
+ if ((i == 100) || (err)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err));
+ break;
+ }
+
+ /* Issue CMD3, get RCA */
+ err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err));
+ break;
+ }
+ rca = resp >> 16;
+ host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
+ host->ops->set_ios(host, &host->ios);
+
+ /* Issue CMD7, select card */
+ err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err));
+ break;
+ }
+ }
+
+ /* Enable high speed */
+ if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n"));
+ err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err));
+ card->state &= ~MMC_STATE_HIGHSPEED;
+ /* no need to break */
+ } else {
+ err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS));
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err));
+ break;
+ }
+ mmc_card_set_highspeed(card);
+ host->ios.timing = MMC_TIMING_SD_HS;
+ host->ops->set_ios(host, &host->ios);
+ }
+ }
+
+ /* Set clock */
+ if (mmc_card_highspeed(card)) {
+ clock = 50000000;
+ } else {
+ clock = card->cis.max_dtr;
+ }
+
+ if (clock > host->f_max) {
+ clock = host->f_max;
+ }
+ host->ios.clock = clock;
+ host->ops->set_ios(host, &host->ios);
+
+
+ if (card->host->caps & MMC_CAP_4_BIT_DATA) {
+ /* CMD52: Set bus width & disable card detect resistor */
+ err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT);
+ if (err) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err));
+ break;
+ }
+ host->ios.bus_width = MMC_BUS_WIDTH_4;
+ host->ops->set_ios(host, &host->ios);
+ }
+ } while (0);
+
+ sdio_release_host(func);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n"));
+
+ return (err) ? A_ERROR : A_OK;
+}
+
+A_STATUS
+PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config)
+{
+ A_STATUS status = A_OK;
+#if defined(CONFIG_PM)
+ struct sdio_func *func = device->func;
+ int old_reset_val;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config));
+ switch (config) {
+ case HIF_DEVICE_POWER_DOWN:
+ case HIF_DEVICE_POWER_CUT:
+ old_reset_val = reset_sdio_on_unload;
+ reset_sdio_on_unload = 1;
+ status = hifDisableFunc(device, func);
+ reset_sdio_on_unload = old_reset_val;
+ if (!device->is_suspend) {
+ struct mmc_host *host = func->card->host;
+ host->ios.clock = 0;
+ host->ios.vdd = 0;
+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+ host->ios.chip_select = MMC_CS_DONTCARE;
+ host->ios.power_mode = MMC_POWER_OFF;
+ host->ios.bus_width = MMC_BUS_WIDTH_1;
+ host->ios.timing = MMC_TIMING_LEGACY;
+ host->ops->set_ios(host, &host->ios);
+ }
+ break;
+ case HIF_DEVICE_POWER_UP:
+ if (device->powerConfig == HIF_DEVICE_POWER_CUT) {
+ status = ReinitSDIO(device);
+ }
+ if (status == A_OK) {
+ status = hifEnableFunc(device, func);
+ }
+ break;
+ }
+ device->powerConfig = config;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n"));
+#endif
+ return status;
+}
+
+A_STATUS
+HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
+ void *config, A_UINT32 configLen)
+{
+ A_UINT32 count;
+ A_STATUS status = A_OK;
+
+ switch(opcode) {
+ case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
+ ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
+ ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
+ ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
+ ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
+ break;
+
+ case HIF_DEVICE_GET_MBOX_ADDR:
+ for (count = 0; count < 4; count ++) {
+ ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
+ }
+
+ if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) {
+ SetExtendedMboxWindowInfo((A_UINT16)device->func->device,
+ (HIF_DEVICE_MBOX_INFO *)config);
+ }
+
+ break;
+ case HIF_DEVICE_GET_IRQ_PROC_MODE:
+ *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY;
+ break;
+ case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT:
+ if (!device->scatter_enabled) {
+ return A_ENOTSUP;
+ }
+ status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config);
+ if (A_FAILED(status)) {
+ device->scatter_enabled = FALSE;
+ }
+ break;
+ case HIF_DEVICE_GET_OS_DEVICE:
+ /* pass back a pointer to the SDIO function's "dev" struct */
+ ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev;
+ break;
+ case HIF_DEVICE_POWER_STATE_CHANGE:
+ status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config);
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ ("AR6000: Unsupported configuration opcode: %d\n", opcode));
+ status = A_ERROR;
+ }
+
+ return status;
+}
+
+void
+HIFShutDownDevice(HIF_DEVICE *device)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n"));
+ if (device != NULL) {
+ AR_DEBUG_ASSERT(device->func != NULL);
+ } else {
+ /* since we are unloading the driver anyways, reset all cards in case the SDIO card
+ * is externally powered and we are unloading the SDIO stack. This avoids the problem when
+ * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already
+ * enumerated */
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n"));
+ ResetAllCards();
+
+ /* Unregister with bus driver core */
+ if (registered) {
+ registered = 0;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: Unregistering with the bus driver\n"));
+ sdio_unregister_driver(&ar6k_driver);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: Unregistered\n"));
+ }
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n"));
+}
+
+static void
+hifIRQHandler(struct sdio_func *func)
+{
+ A_STATUS status;
+ HIF_DEVICE *device;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
+
+ device = getHifDevice(func);
+ atomic_set(&device->irqHandling, 1);
+ /* release the host during ints so we can pick it back up when we process cmds */
+ sdio_release_host(device->func);
+ status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
+ sdio_claim_host(device->func);
+ atomic_set(&device->irqHandling, 0);
+ AR_DEBUG_ASSERT(status == A_OK || status == A_ECANCELED);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n"));
+}
+
+/* handle HTC startup via thread*/
+static int startup_task(void *param)
+{
+ HIF_DEVICE *device;
+
+ device = (HIF_DEVICE *)param;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n"));
+ /* start up inform DRV layer */
+ if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
+ }
+ return 0;
+}
+
+#if defined(CONFIG_PM)
+static int enable_task(void *param)
+{
+ HIF_DEVICE *device;
+ device = (HIF_DEVICE *)param;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n"));
+
+ /* start up inform DRV layer */
+ if (device &&
+ device->claimedContext &&
+ osdrvCallbacks.devicePowerChangeHandler &&
+ osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n"));
+ }
+
+ return 0;
+}
+#endif
+
+static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
+{
+ int ret;
+ HIF_DEVICE * device;
+ int count;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+ ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n",
+ func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize));
+
+ addHifDevice(func);
+ device = getHifDevice(func);
+
+ device->id = id;
+ device->is_disabled = TRUE;
+
+ spin_lock_init(&device->lock);
+
+ spin_lock_init(&device->asynclock);
+
+ DL_LIST_INIT(&device->ScatterReqHead);
+
+ if (!nohifscattersupport) {
+ /* try to allow scatter operation on all instances,
+ * unless globally overridden */
+ device->scatter_enabled = TRUE;
+ }
+
+ /* Initialize the bus requests to be used later */
+ A_MEMZERO(device->busRequest, sizeof(device->busRequest));
+ for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
+ sema_init(&device->busRequest[count].sem_req, 0);
+ hifFreeBusRequest(device, &device->busRequest[count]);
+ }
+ sema_init(&device->sem_async, 0);
+
+ ret = hifEnableFunc(device, func);
+
+ return ret;
+}
+
+
+void
+HIFAckInterrupt(HIF_DEVICE *device)
+{
+ AR_DEBUG_ASSERT(device != NULL);
+
+ /* Acknowledge our function IRQ */
+}
+
+void
+HIFUnMaskInterrupt(HIF_DEVICE *device)
+{
+ int ret;;
+
+ AR_DEBUG_ASSERT(device != NULL);
+ AR_DEBUG_ASSERT(device->func != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n"));
+
+ /* Register the IRQ Handler */
+ sdio_claim_host(device->func);
+ ret = sdio_claim_irq(device->func, hifIRQHandler);
+ sdio_release_host(device->func);
+ AR_DEBUG_ASSERT(ret == 0);
+}
+
+void HIFMaskInterrupt(HIF_DEVICE *device)
+{
+ int ret;
+ AR_DEBUG_ASSERT(device != NULL);
+ AR_DEBUG_ASSERT(device->func != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n"));
+
+ /* Mask our function IRQ */
+ sdio_claim_host(device->func);
+ while (atomic_read(&device->irqHandling)) {
+ sdio_release_host(device->func);
+ schedule_timeout(HZ/10);
+ sdio_claim_host(device->func);
+ }
+ ret = sdio_release_irq(device->func);
+ sdio_release_host(device->func);
+ AR_DEBUG_ASSERT(ret == 0);
+}
+
+BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device)
+{
+ BUS_REQUEST *busrequest;
+ unsigned long flag;
+
+ /* Acquire lock */
+ spin_lock_irqsave(&device->lock, flag);
+
+ /* Remove first in list */
+ if((busrequest = device->s_busRequestFreeQueue) != NULL)
+ {
+ device->s_busRequestFreeQueue = busrequest->next;
+ }
+ /* Release lock */
+ spin_unlock_irqrestore(&device->lock, flag);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest));
+ return busrequest;
+}
+
+void
+hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest)
+{
+ unsigned long flag;
+
+ AR_DEBUG_ASSERT(busrequest != NULL);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest));
+ /* Acquire lock */
+ spin_lock_irqsave(&device->lock, flag);
+
+
+ /* Insert first in list */
+ busrequest->next = device->s_busRequestFreeQueue;
+ busrequest->inusenext = NULL;
+ device->s_busRequestFreeQueue = busrequest;
+
+ /* Release lock */
+ spin_unlock_irqrestore(&device->lock, flag);
+}
+
+static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func)
+{
+ int ret;
+ A_STATUS status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
+ device = getHifDevice(func);
+ if (!IS_ERR(device->async_task)) {
+ init_completion(&device->async_completion);
+ device->async_shutdown = 1;
+ up(&device->sem_async);
+ wait_for_completion(&device->async_completion);
+ device->async_task = NULL;
+ }
+ /* Disable the card */
+ sdio_claim_host(device->func);
+ ret = sdio_disable_func(device->func);
+ if (ret) {
+ status = A_ERROR;
+ }
+
+ if (reset_sdio_on_unload) {
+ /* reset the SDIO interface. This is useful in automated testing where the card
+ * does not need to be removed at the end of the test. It is expected that the user will
+ * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n"));
+
+ /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access
+ * to undefined registers in the range of: 0xF0-0xFF */
+
+ ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3));
+ if (ret) {
+ status = A_ERROR;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret));
+ }
+ }
+
+ sdio_release_host(device->func);
+
+ if (status == A_OK) {
+ device->is_disabled = TRUE;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n"));
+
+ return status;
+}
+
+static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func)
+{
+ struct task_struct* pTask;
+ const char *taskName = NULL;
+ int (*taskFunc)(void *) = NULL;
+ int ret = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
+ device = getHifDevice(func);
+
+ if (device->is_disabled) {
+ /* enable the SDIO function */
+ sdio_claim_host(func);
+
+ if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
+ /* enable 4-bit ASYNC interrupt on AR6003 or later devices */
+ ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
+ if (ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
+ sdio_release_host(func);
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
+ }
+ /* give us some time to enable, in ms */
+ func->enable_timeout = 100;
+ ret = sdio_enable_func(func);
+ if (ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
+ __FUNCTION__, ret));
+ sdio_release_host(func);
+ return A_ERROR;
+ }
+ ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
+ sdio_release_host(func);
+ if (ret) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n",
+ __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
+ return A_ERROR;
+ }
+ device->is_disabled = FALSE;
+ /* create async I/O thread */
+ if (!device->async_task) {
+ device->async_shutdown = 0;
+ device->async_task = kthread_create(async_task,
+ (void *)device,
+ "AR6K Async");
+ if (IS_ERR(device->async_task)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
+ wake_up_process(device->async_task );
+ }
+ }
+
+ if (!device->claimedContext) {
+ taskFunc = startup_task;
+ taskName = "AR6K startup";
+ ret = A_OK;
+#if defined(CONFIG_PM)
+ } else {
+ taskFunc = enable_task;
+ taskName = "AR6K enable";
+ ret = A_PENDING;
+#endif /* CONFIG_PM */
+ }
+ /* create resume thread */
+ pTask = kthread_create(taskFunc, (void *)device, taskName);
+ if (IS_ERR(pTask)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
+ return A_ERROR;
+ }
+ wake_up_process(pTask);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
+
+ /* task will call the enable func, indicate pending */
+ return ret;
+}
+
+#if defined(CONFIG_PM)
+static int hifDeviceSuspend(struct device *dev)
+{
+ struct sdio_func *func=dev_to_sdio_func(dev);
+ A_STATUS status = A_OK;
+ HIF_DEVICE *device;
+
+ device = getHifDevice(func);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n"));
+ if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
+ device->is_suspend = TRUE; /* set true first for PowerStateChangeNotify(..) */
+ status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext);
+ if (status != A_OK) {
+ device->is_suspend = FALSE;
+ }
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n"));
+
+ switch (status) {
+ case A_OK:
+ return 0;
+ case A_EBUSY:
+ return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */
+ default:
+ return -1;
+ }
+}
+
+static int hifDeviceResume(struct device *dev)
+{
+ struct sdio_func *func=dev_to_sdio_func(dev);
+ A_STATUS status = A_OK;
+ HIF_DEVICE *device;
+
+ device = getHifDevice(func);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n"));
+ if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
+ status = osdrvCallbacks.deviceResumeHandler(device->claimedContext);
+ if (status == A_OK) {
+ device->is_suspend = FALSE;
+ }
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n"));
+
+ return A_SUCCESS(status) ? 0 : status;
+}
+#endif /* CONFIG_PM */
+
+static void hifDeviceRemoved(struct sdio_func *func)
+{
+ A_STATUS status = A_OK;
+ HIF_DEVICE *device;
+ AR_DEBUG_ASSERT(func != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
+ device = getHifDevice(func);
+ if (device->claimedContext != NULL) {
+ status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
+ }
+
+ if (device->is_disabled) {
+ device->is_disabled = FALSE;
+ } else {
+ status = hifDisableFunc(device, func);
+ }
+ CleanupHIFScatterResources(device);
+
+ delHifDevice(device);
+ AR_DEBUG_ASSERT(status == A_OK);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
+}
+
+/*
+ * This should be moved to AR6K HTC layer.
+ */
+A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device)
+{
+ A_INT32 cnt = 10;
+ A_UINT8 host_int_status;
+ A_STATUS status = A_OK;
+
+ do {
+ while (atomic_read(&device->irqHandling)) {
+ /* wait until irq handler finished all the jobs */
+ schedule_timeout(HZ/10);
+ }
+ /* check if there is any pending irq due to force done */
+ host_int_status = 0;
+ status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS,
+ (A_UINT8 *)&host_int_status, sizeof(host_int_status),
+ HIF_RD_SYNC_BYTE_INC, NULL);
+ host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0;
+ if (host_int_status) {
+ schedule(); /* schedule for next dsrHandler */
+ }
+ } while (host_int_status && --cnt > 0);
+
+ if (host_int_status && cnt == 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__));
+ }
+
+ return A_OK;
+}
+
+
+static HIF_DEVICE *
+addHifDevice(struct sdio_func *func)
+{
+ HIF_DEVICE *hifdevice;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
+ AR_DEBUG_ASSERT(func != NULL);
+ hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
+ AR_DEBUG_ASSERT(hifdevice != NULL);
+#if HIF_USE_DMA_BOUNCE_BUFFER
+ hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
+ AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL);
+#endif
+ hifdevice->func = func;
+ hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
+ sdio_set_drvdata(func, hifdevice);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice));
+ return hifdevice;
+}
+
+static HIF_DEVICE *
+getHifDevice(struct sdio_func *func)
+{
+ AR_DEBUG_ASSERT(func != NULL);
+ return (HIF_DEVICE *)sdio_get_drvdata(func);
+}
+
+static void
+delHifDevice(HIF_DEVICE * device)
+{
+ AR_DEBUG_ASSERT(device!= NULL);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device));
+ if (device->dma_buffer != NULL) {
+ kfree(device->dma_buffer);
+ }
+ kfree(device);
+}
+
+static void ResetAllCards(void)
+{
+}
+
+void HIFClaimDevice(HIF_DEVICE *device, void *context)
+{
+ device->claimedContext = context;
+}
+
+void HIFReleaseDevice(HIF_DEVICE *device)
+{
+ device->claimedContext = NULL;
+}
+
+A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks)
+{
+ if (device->htcCallbacks.context != NULL) {
+ /* already in use! */
+ return A_ERROR;
+ }
+ device->htcCallbacks = *callbacks;
+ return A_OK;
+}
+
+void HIFDetachHTC(HIF_DEVICE *device)
+{
+ A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
+}
+
+#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
+ (arg) = (((rw) & 1) << 31) | \
+ (((func) & 0x7) << 28) | \
+ (((raw) & 1) << 27) | \
+ (1 << 26) | \
+ (((address) & 0x1FFFF) << 9) | \
+ (1 << 8) | \
+ ((writedata) & 0xFF)
+
+#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
+ SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00)
+#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
+ SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value)
+
+static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte)
+{
+ struct mmc_command ioCmd;
+ unsigned long arg;
+
+ memset(&ioCmd,0,sizeof(ioCmd));
+ SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte);
+ ioCmd.opcode = SD_IO_RW_DIRECT;
+ ioCmd.arg = arg;
+ ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+
+ return mmc_wait_for_cmd(card->host, &ioCmd, 0);
+}
+
+static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte)
+{
+ struct mmc_command ioCmd;
+ unsigned long arg;
+ A_INT32 err;
+
+ memset(&ioCmd,0,sizeof(ioCmd));
+ SDIO_SET_CMD52_READ_ARG(arg,0,address);
+ ioCmd.opcode = SD_IO_RW_DIRECT;
+ ioCmd.arg = arg;
+ ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+
+ err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
+
+ if ((!err) && (byte)) {
+ *byte = ioCmd.resp[0] & 0xFF;
+ }
+
+ return err;
+}
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
new file mode 100644
index 000000000000..22c6c6659f5b
--- /dev/null
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
@@ -0,0 +1,393 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HIF scatter implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/kthread.h>
+#include "hif_internal.h"
+#define ATH_MODULE_NAME hif
+#include "a_debug.h"
+
+#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT
+
+#define _CMD53_ARG_READ 0
+#define _CMD53_ARG_WRITE 1
+#define _CMD53_ARG_BLOCK_BASIS 1
+#define _CMD53_ARG_FIXED_ADDRESS 0
+#define _CMD53_ARG_INCR_ADDRESS 1
+
+#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \
+ (arg) = (((rw) & 1) << 31) | \
+ (((func) & 0x7) << 28) | \
+ (((mode) & 1) << 27) | \
+ (((opcode) & 1) << 26) | \
+ (((address) & 0x1FFFF) << 9) | \
+ ((bytes_blocks) & 0x1FF)
+
+static void FreeScatterReq(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&device->lock, flag);
+
+ DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink);
+
+ spin_unlock_irqrestore(&device->lock, flag);
+
+}
+
+static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device)
+{
+ DL_LIST *pItem;
+ unsigned long flag;
+
+ spin_lock_irqsave(&device->lock, flag);
+
+ pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead);
+
+ spin_unlock_irqrestore(&device->lock, flag);
+
+ if (pItem != NULL) {
+ return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink);
+ }
+
+ return NULL;
+}
+
+ /* called by async task to perform the operation synchronously using direct MMC APIs */
+A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest)
+{
+ int i;
+ A_UINT8 rw;
+ A_UINT8 opcode;
+ struct mmc_request mmcreq;
+ struct mmc_command cmd;
+ struct mmc_data data;
+ HIF_SCATTER_REQ_PRIV *pReqPriv;
+ HIF_SCATTER_REQ *pReq;
+ A_STATUS status = A_OK;
+ struct scatterlist *pSg;
+
+ pReqPriv = busrequest->pScatterReq;
+
+ A_ASSERT(pReqPriv != NULL);
+
+ pReq = pReqPriv->pHifScatterReq;
+
+ memset(&mmcreq, 0, sizeof(struct mmc_request));
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ memset(&data, 0, sizeof(struct mmc_data));
+
+ data.blksz = HIF_MBOX_BLOCK_SIZE;
+ data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n",
+ (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks,
+ pReq->TotalLength,pReq->ValidScatterEntries));
+
+ if (pReq->Request & HIF_WRITE) {
+ rw = _CMD53_ARG_WRITE;
+ data.flags = MMC_DATA_WRITE;
+ } else {
+ rw = _CMD53_ARG_READ;
+ data.flags = MMC_DATA_READ;
+ }
+
+ if (pReq->Request & HIF_FIXED_ADDRESS) {
+ opcode = _CMD53_ARG_FIXED_ADDRESS;
+ } else {
+ opcode = _CMD53_ARG_INCR_ADDRESS;
+ }
+
+ /* fill SG entries */
+ pSg = pReqPriv->sgentries;
+ sg_init_table(pSg, pReq->ValidScatterEntries);
+
+ /* assemble SG list */
+ for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) {
+ /* setup each sg entry */
+ if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) {
+ /* note some scatter engines can handle unaligned buffers, print this
+ * as informational only */
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
+ ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n",
+ pReq->Request & HIF_WRITE ? "WRITE":"READ",
+ (unsigned long)pReq->ScatterList[i].pBuffer));
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, (" %d: Addr:0x%lX, Len:%d \n",
+ i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length));
+
+ sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length);
+ }
+ /* set scatter-gather table for request */
+ data.sg = pReqPriv->sgentries;
+ data.sg_len = pReq->ValidScatterEntries;
+ /* set command argument */
+ SDIO_SET_CMD53_ARG(cmd.arg,
+ rw,
+ device->func->num,
+ _CMD53_ARG_BLOCK_BASIS,
+ opcode,
+ pReq->Address,
+ data.blocks);
+
+ cmd.opcode = SD_IO_RW_EXTENDED;
+ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+ mmcreq.cmd = &cmd;
+ mmcreq.data = &data;
+
+ mmc_set_data_timeout(&data, device->func->card);
+ /* synchronous call to process request */
+ mmc_wait_for_req(device->func->card->host, &mmcreq);
+
+ if (cmd.error) {
+ status = A_ERROR;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error));
+ }
+
+ if (data.error) {
+ status = A_ERROR;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error));
+ }
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n",
+ (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks));
+ }
+
+ /* set completion status, fail or success */
+ pReq->CompletionStatus = status;
+
+ if (pReq->Request & HIF_ASYNCHRONOUS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status));
+ /* complete the request */
+ A_ASSERT(pReq->CompletionRoutine != NULL);
+ pReq->CompletionRoutine(pReq);
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status));
+ /* signal wait */
+ up(&busrequest->sem_req);
+ }
+
+ return status;
+}
+
+ /* callback to issue a read-write scatter request */
+static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
+{
+ A_STATUS status = A_EINVAL;
+ A_UINT32 request = pReq->Request;
+ HIF_SCATTER_REQ_PRIV *pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0];
+
+ do {
+
+ A_ASSERT(pReqPriv != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n",
+ pReq->TotalLength, pReq->ValidScatterEntries));
+
+ if (!(request & HIF_EXTENDED_IO)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("HIF-SCATTER: Invalid command type: 0x%08x\n", request));
+ break;
+ }
+
+ if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request));
+ break;
+ }
+
+ if (!(request & HIF_BLOCK_BASIS)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request));
+ break;
+ }
+
+ if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+ ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength));
+ break;
+ }
+
+ if (pReq->TotalLength == 0) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* add bus request to the async list for the async I/O thread to process */
+ AddToAsyncList(device, pReqPriv->busrequest);
+
+ if (request & HIF_SYNCHRONOUS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
+ /* signal thread and wait */
+ up(&device->sem_async);
+ if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n"));
+ /* interrupted, exit */
+ status = A_ERROR;
+ break;
+ } else {
+ status = pReq->CompletionStatus;
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest));
+ /* wake thread, it will process and then take care of the async callback */
+ up(&device->sem_async);
+ status = A_OK;
+ }
+
+ } while (FALSE);
+
+ if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
+ pReq->CompletionStatus = status;
+ pReq->CompletionRoutine(pReq);
+ status = A_OK;
+ }
+
+ return status;
+}
+
+ /* setup of HIF scatter resources */
+A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
+{
+ A_STATUS status = A_ERROR;
+ int i;
+ HIF_SCATTER_REQ_PRIV *pReqPriv;
+ BUS_REQUEST *busrequest;
+
+ do {
+
+ /* check if host supports scatter requests and it meets our requirements */
+ if (device->func->card->host->max_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
+ device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ));
+ status = A_ENOTSUP;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
+ MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ));
+
+ for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {
+ /* allocate the private request blob */
+ pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV));
+ if (NULL == pReqPriv) {
+ break;
+ }
+ A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV));
+ /* save the device instance*/
+ pReqPriv->device = device;
+ /* allocate the scatter request */
+ pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) +
+ (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM)));
+
+ if (NULL == pReqPriv->pHifScatterReq) {
+ A_FREE(pReqPriv);
+ break;
+ }
+ /* just zero the main part of the scatter request */
+ A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ));
+ /* back pointer to the private struct */
+ pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
+ /* allocate a bus request for this scatter request */
+ busrequest = hifAllocateBusRequest(device);
+ if (NULL == busrequest) {
+ A_FREE(pReqPriv->pHifScatterReq);
+ A_FREE(pReqPriv);
+ break;
+ }
+ /* assign the scatter request to this bus request */
+ busrequest->pScatterReq = pReqPriv;
+ /* point back to the request */
+ pReqPriv->busrequest = busrequest;
+ /* add it to the scatter pool */
+ FreeScatterReq(device,pReqPriv->pHifScatterReq);
+ }
+
+ if (i != MAX_SCATTER_REQUESTS) {
+ status = A_NO_MEMORY;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
+ break;
+ }
+
+ /* set scatter function pointers */
+ pInfo->pAllocateReqFunc = AllocScatterReq;
+ pInfo->pFreeReqFunc = FreeScatterReq;
+ pInfo->pReadWriteScatterFunc = HifReadWriteScatter;
+ pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
+ pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
+
+ status = A_OK;
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ CleanupHIFScatterResources(device);
+ }
+
+ return status;
+}
+
+ /* clean up scatter support */
+void CleanupHIFScatterResources(HIF_DEVICE *device)
+{
+ HIF_SCATTER_REQ_PRIV *pReqPriv;
+ HIF_SCATTER_REQ *pReq;
+
+ /* empty the free list */
+
+ while (1) {
+
+ pReq = AllocScatterReq(device);
+
+ if (NULL == pReq) {
+ break;
+ }
+
+ pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0];
+ A_ASSERT(pReqPriv != NULL);
+
+ if (pReqPriv->busrequest != NULL) {
+ pReqPriv->busrequest->pScatterReq = NULL;
+ /* free bus request */
+ hifFreeBusRequest(device, pReqPriv->busrequest);
+ pReqPriv->busrequest = NULL;
+ }
+
+ if (pReqPriv->pHifScatterReq != NULL) {
+ A_FREE(pReqPriv->pHifScatterReq);
+ pReqPriv->pHifScatterReq = NULL;
+ }
+
+ A_FREE(pReqPriv);
+ }
+}
+
+#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
new file mode 100644
index 000000000000..1efc85ce02b2
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
@@ -0,0 +1,1471 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6k.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// AR6K device layer that handles register level I/O
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "a_osapi.h"
+#include "../htc_debug.h"
+#include "hif.h"
+#include "htc_packet.h"
+#include "ar6k.h"
+
+#define MAILBOX_FOR_BLOCK_SIZE 1
+
+A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev);
+A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev);
+
+static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev);
+
+void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket)
+{
+ LOCK_AR6K(pDev);
+ HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket);
+ UNLOCK_AR6K(pDev);
+}
+
+HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev)
+{
+ HTC_PACKET *pPacket;
+
+ LOCK_AR6K(pDev);
+ pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList);
+ UNLOCK_AR6K(pDev);
+
+ return pPacket;
+}
+
+void DevCleanup(AR6K_DEVICE *pDev)
+{
+ DevCleanupGMbox(pDev);
+
+ if (pDev->HifAttached) {
+ HIFDetachHTC(pDev->HIFDevice);
+ pDev->HifAttached = FALSE;
+ }
+
+ DevCleanupVirtualScatterSupport(pDev);
+
+ if (A_IS_MUTEX_VALID(&pDev->Lock)) {
+ A_MUTEX_DELETE(&pDev->Lock);
+ }
+}
+
+A_STATUS DevSetup(AR6K_DEVICE *pDev)
+{
+ A_UINT32 blocksizes[AR6K_MAILBOXES];
+ A_STATUS status = A_OK;
+ int i;
+ HTC_CALLBACKS htcCallbacks;
+
+ do {
+
+ DL_LIST_INIT(&pDev->ScatterReqHead);
+ /* initialize our free list of IO packets */
+ INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
+ A_MUTEX_INIT(&pDev->Lock);
+
+ A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
+ /* the device layer handles these */
+ htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
+ htcCallbacks.dsrHandler = DevDsrHandler;
+ htcCallbacks.context = pDev;
+
+ status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ pDev->HifAttached = TRUE;
+
+ /* get the addresses for all 4 mailboxes */
+ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
+ &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));
+
+ if (status != A_OK) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* carve up register I/O packets (these are for ASYNC register I/O ) */
+ for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
+ HTC_PACKET *pIOPacket;
+ pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
+ SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
+ pDev,
+ pDev->RegIOBuffers[i].Buffer,
+ AR6K_REG_IO_BUFFER_SIZE,
+ 0); /* don't care */
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ /* get the block sizes */
+ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+ blocksizes, sizeof(blocksizes));
+
+ if (status != A_OK) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
+ * size on mailbox 0 is artificially set to 1. So we use the block size that is set
+ * for the other 3 mailboxes */
+ pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
+ /* must be a power of 2 */
+ A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);
+
+ /* assemble mask, used for padding to a block */
+ pDev->BlockMask = pDev->BlockSize - 1;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
+ pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));
+
+ pDev->GetPendingEventsFunc = NULL;
+ /* see if the HIF layer implements the get pending events function */
+ HIFConfigureDevice(pDev->HIFDevice,
+ HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
+ &pDev->GetPendingEventsFunc,
+ sizeof(pDev->GetPendingEventsFunc));
+
+ /* assume we can process HIF interrupt events asynchronously */
+ pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;
+
+ /* see if the HIF layer overrides this assumption */
+ HIFConfigureDevice(pDev->HIFDevice,
+ HIF_DEVICE_GET_IRQ_PROC_MODE,
+ &pDev->HifIRQProcessingMode,
+ sizeof(pDev->HifIRQProcessingMode));
+
+ switch (pDev->HifIRQProcessingMode) {
+ case HIF_DEVICE_IRQ_SYNC_ONLY:
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
+ /* see if HIF layer wants HTC to yield */
+ HIFConfigureDevice(pDev->HIFDevice,
+ HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
+ &pDev->HifIRQYieldParams,
+ sizeof(pDev->HifIRQYieldParams));
+
+ if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ ("HIF requests that DSR yield per %d RECV packets \n",
+ pDev->HifIRQYieldParams.RecvPacketYieldCount));
+ pDev->DSRCanYield = TRUE;
+ }
+ break;
+ case HIF_DEVICE_IRQ_ASYNC_SYNC:
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
+ break;
+ default:
+ A_ASSERT(FALSE);
+ }
+
+ pDev->HifMaskUmaskRecvEvent = NULL;
+
+ /* see if the HIF layer implements the mask/unmask recv events function */
+ HIFConfigureDevice(pDev->HIFDevice,
+ HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
+ &pDev->HifMaskUmaskRecvEvent,
+ sizeof(pDev->HifMaskUmaskRecvEvent));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
+ (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));
+
+ status = DevDisableInterrupts(pDev);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ status = DevSetupGMbox(pDev);
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ if (pDev->HifAttached) {
+ HIFDetachHTC(pDev->HIFDevice);
+ pDev->HifAttached = FALSE;
+ }
+ }
+
+ return status;
+
+}
+
+A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev)
+{
+ A_STATUS status;
+ AR6K_IRQ_ENABLE_REGISTERS regs;
+
+ LOCK_AR6K(pDev);
+
+ /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
+ pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
+ INT_STATUS_ENABLE_CPU_SET(0x01) |
+ INT_STATUS_ENABLE_COUNTER_SET(0x01);
+
+ if (NULL == pDev->GetPendingEventsFunc) {
+ pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
+ } else {
+ /* The HIF layer provided us with a pending events function which means that
+ * the detection of pending mbox messages is handled in the HIF layer.
+ * This is the case for the SPI2 interface.
+ * In the normal case we enable MBOX interrupts, for the case
+ * with HIFs that offer this mechanism, we keep these interrupts
+ * masked */
+ pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
+ }
+
+
+ /* Set up the CPU Interrupt Status Register */
+ pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
+
+ /* Set up the Error Interrupt Status Register */
+ pDev->IrqEnableRegisters.error_status_enable =
+ ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
+ ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
+
+ /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
+ pDev->IrqEnableRegisters.counter_int_status_enable =
+ COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK);
+
+ /* copy into our temp area */
+ A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+
+ UNLOCK_AR6K(pDev);
+
+ /* always synchronous */
+ status = HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_enable,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ /* Can't write it for some reason */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Failed to update interrupt control registers err: %d\n", status));
+
+ }
+
+ return status;
+}
+
+A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev)
+{
+ AR6K_IRQ_ENABLE_REGISTERS regs;
+
+ LOCK_AR6K(pDev);
+ /* Disable all interrupts */
+ pDev->IrqEnableRegisters.int_status_enable = 0;
+ pDev->IrqEnableRegisters.cpu_int_status_enable = 0;
+ pDev->IrqEnableRegisters.error_status_enable = 0;
+ pDev->IrqEnableRegisters.counter_int_status_enable = 0;
+ /* copy into our temp area */
+ A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+
+ UNLOCK_AR6K(pDev);
+
+ /* always synchronous */
+ return HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_enable,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+}
+
+/* enable device interrupts */
+A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev)
+{
+ /* for good measure, make sure interrupt are disabled before unmasking at the HIF
+ * layer.
+ * The rationale here is that between device insertion (where we clear the interrupts the first time)
+ * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets.
+ * The AR6K interrupt enables reset back to an "enabled" state when this happens.
+ * */
+ A_STATUS IntStatus = A_OK;
+ DevDisableInterrupts(pDev);
+
+#ifdef THREAD_X
+ // Tobe verified...
+ IntStatus = DevEnableInterrupts(pDev);
+ /* Unmask the host controller interrupts */
+ HIFUnMaskInterrupt(pDev->HIFDevice);
+#else
+ /* Unmask the host controller interrupts */
+ HIFUnMaskInterrupt(pDev->HIFDevice);
+ IntStatus = DevEnableInterrupts(pDev);
+#endif
+
+ return IntStatus;
+}
+
+/* disable all device interrupts */
+A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev)
+{
+ /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while
+ * we zero out our shadow registers in DevDisableInterrupts()*/
+ HIFMaskInterrupt(pDev->HIFDevice);
+
+ return DevDisableInterrupts(pDev);
+}
+
+/* callback when our fetch to enable/disable completes */
+static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacket)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" Failed to disable receiver, status:%d \n", pPacket->Status));
+ }
+ /* free this IO packet */
+ AR6KFreeIOPacket(pDev,pPacket);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n"));
+}
+
+/* disable packet reception (used in case the host runs out of buffers)
+ * this is the "override" method when the HIF reports another methods to
+ * disable recv events */
+static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket = NULL;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n",
+ EnableRecv,AsyncMode));
+
+ do {
+
+ if (AsyncMode) {
+
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
+ pIOPacket->pContext = pDev;
+
+ /* call the HIF layer override and do this asynchronously */
+ status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
+ EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
+ pIOPacket);
+ break;
+ }
+
+ /* if we get here we are doing it synchronously */
+ status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice,
+ EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV,
+ NULL);
+
+ } while (FALSE);
+
+ if (A_FAILED(status) && (pIOPacket != NULL)) {
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ return status;
+}
+
+/* disable packet reception (used in case the host runs out of buffers)
+ * this is the "normal" method using the interrupt enable registers through
+ * the host I/F */
+static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket = NULL;
+ AR6K_IRQ_ENABLE_REGISTERS regs;
+
+ /* take the lock to protect interrupt enable shadows */
+ LOCK_AR6K(pDev);
+
+ if (EnableRecv) {
+ pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
+ } else {
+ pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01);
+ }
+
+ /* copy into our temp area */
+ A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+ UNLOCK_AR6K(pDev);
+
+ do {
+
+ if (AsyncMode) {
+
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* copy values to write to our async I/O buffer */
+ A_MEMCPY(pIOPacket->pBuffer,&regs,AR6K_IRQ_ENABLE_REGS_SIZE);
+
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler;
+ pIOPacket->pContext = pDev;
+
+ /* write it out asynchronously */
+ HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ pIOPacket->pBuffer,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_ASYNC_BYTE_INC,
+ pIOPacket);
+ break;
+ }
+
+ /* if we get here we are doing it synchronously */
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_enable,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ } while (FALSE);
+
+ if (A_FAILED(status) && (pIOPacket != NULL)) {
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ return status;
+}
+
+
+A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode)
+{
+ if (NULL == pDev->HifMaskUmaskRecvEvent) {
+ return DevDoEnableDisableRecvNormal(pDev,FALSE,AsyncMode);
+ } else {
+ return DevDoEnableDisableRecvOverride(pDev,FALSE,AsyncMode);
+ }
+}
+
+A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode)
+{
+ if (NULL == pDev->HifMaskUmaskRecvEvent) {
+ return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode);
+ } else {
+ return DevDoEnableDisableRecvOverride(pDev,TRUE,AsyncMode);
+ }
+}
+
+A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending)
+{
+ A_STATUS status = A_OK;
+ A_UCHAR host_int_status = 0x0;
+ A_UINT32 counter = 0x0;
+
+ if(TimeoutInMs < 100)
+ {
+ TimeoutInMs = 100;
+ }
+
+ counter = TimeoutInMs / 100;
+
+ do
+ {
+ //Read the Host Interrupt Status Register
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ &host_int_status,
+ sizeof(A_UCHAR),
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+ if(A_FAILED(status))
+ {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status));
+ break;
+ }
+
+ host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)):0;
+ if(!host_int_status)
+ {
+ status = A_OK;
+ *pbIsRecvPending = FALSE;
+ break;
+ }
+ else
+ {
+ *pbIsRecvPending = TRUE;
+ }
+
+ A_MDELAY(100);
+
+ counter--;
+
+ }while(counter);
+ return status;
+}
+
+void DevDumpRegisters(AR6K_DEVICE *pDev,
+ AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs,
+ AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n"));
+
+ if (pIrqProcRegs != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_status));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_valid));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0]));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1]));
+
+ if (pDev->MailBoxInfo.GMboxAddress != 0) {
+ /* if the target supports GMBOX hardware, dump some additional state */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_status2));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avail));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[0]));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[1]));
+ }
+
+ }
+
+ if (pIrqEnableRegs != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n"));
+}
+
+
+#define DEV_GET_VIRT_DMA_INFO(p) ((DEV_SCATTER_DMA_VIRTUAL_INFO *)((p)->HIFPrivate[0]))
+
+static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context)
+{
+ DL_LIST *pItem;
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+ LOCK_AR6K(pDev);
+ pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead);
+ UNLOCK_AR6K(pDev);
+ if (pItem != NULL) {
+ return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink);
+ }
+ return NULL;
+}
+
+static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+ LOCK_AR6K(pDev);
+ DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink);
+ UNLOCK_AR6K(pDev);
+}
+
+A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA)
+{
+ A_UINT8 *pDMABuffer = NULL;
+ int i, remaining;
+ A_UINT32 length;
+
+ pDMABuffer = pReq->pScatterBounceBuffer;
+
+ if (pDMABuffer == NULL) {
+ A_ASSERT(FALSE);
+ return A_EINVAL;
+ }
+
+ remaining = (int)pReq->TotalLength;
+
+ for (i = 0; i < pReq->ValidScatterEntries; i++) {
+
+ length = min((int)pReq->ScatterList[i].Length, remaining);
+
+ if (length != (int)pReq->ScatterList[i].Length) {
+ A_ASSERT(FALSE);
+ /* there is a problem with the scatter list */
+ return A_EINVAL;
+ }
+
+ if (FromDMA) {
+ /* from DMA buffer */
+ A_MEMCPY(pReq->ScatterList[i].pBuffer, pDMABuffer , length);
+ } else {
+ /* to DMA buffer */
+ A_MEMCPY(pDMABuffer, pReq->ScatterList[i].pBuffer, length);
+ }
+
+ pDMABuffer += length;
+ remaining -= length;
+ }
+
+ return A_OK;
+}
+
+static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+ HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ pReq->CompletionStatus = pPacket->Status;
+
+ AR6KFreeIOPacket(pDev,pPacket);
+
+ pReq->CompletionRoutine(pReq);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n"));
+}
+
+static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket = NULL;
+ A_UINT32 request = pReq->Request;
+
+ do {
+
+ if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Invalid length: %d \n", pReq->TotalLength));
+ break;
+ }
+
+ if (pReq->TotalLength == 0) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ if (request & HIF_ASYNCHRONOUS) {
+ /* use an I/O packet to carry this request */
+ pIOPacket = AR6KAllocIOPacket(pDev);
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ /* save the request */
+ pIOPacket->pPktContext = pReq;
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevReadWriteScatterAsyncHandler;
+ pIOPacket->pContext = pDev;
+ }
+
+ if (request & HIF_WRITE) {
+ /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API
+ * this API will adjust the address automatically for the last byte to fall on the mailbox
+ * EOM. */
+
+ /* if the address is an extended address, we can adjust the address here since the extended
+ * address will bypass the normal checks in legacy HIF layers */
+ if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) {
+ pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength;
+ }
+ }
+
+ /* use legacy readwrite */
+ status = HIFReadWrite(pDev->HIFDevice,
+ pReq->Address,
+ DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer,
+ pReq->TotalLength,
+ request,
+ (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL);
+
+ } while (FALSE);
+
+ if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
+ if (pIOPacket != NULL) {
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+ pReq->CompletionStatus = status;
+ pReq->CompletionRoutine(pReq);
+ status = A_OK;
+ }
+
+ return status;
+}
+
+
+static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev)
+{
+ HIF_SCATTER_REQ *pReq;
+
+ while (1) {
+ pReq = DevAllocScatterReq((HIF_DEVICE *)pDev);
+ if (NULL == pReq) {
+ break;
+ }
+ A_FREE(pReq);
+ }
+
+}
+
+ /* function to set up virtual scatter support if HIF layer has not implemented the interface */
+static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev)
+{
+ A_STATUS status = A_OK;
+ int bufferSize, sgreqSize;
+ int i;
+ DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo;
+ HIF_SCATTER_REQ *pReq;
+
+ bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) +
+ 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
+
+ sgreqSize = sizeof(HIF_SCATTER_REQ) +
+ (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM));
+
+ for (i = 0; i < AR6K_SCATTER_REQS; i++) {
+ /* allocate the scatter request, buffer info and the actual virtual buffer itself */
+ pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize);
+
+ if (NULL == pReq) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_MEMZERO(pReq, sgreqSize);
+
+ /* the virtual DMA starts after the scatter request struct */
+ pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqSize);
+ A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO));
+
+ pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0];
+ /* align buffer to cache line in case host controller can actually DMA this */
+ pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer);
+ /* store the structure in the private area */
+ pReq->HIFPrivate[0] = pVirtualInfo;
+ /* we emulate a DMA bounce interface */
+ pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
+ pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer;
+ /* free request to the list */
+ DevFreeScatterReq((HIF_DEVICE *)pDev,pReq);
+ }
+
+ if (A_FAILED(status)) {
+ DevCleanupVirtualScatterSupport(pDev);
+ } else {
+ pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq;
+ pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq;
+ pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter;
+ if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n"));
+ pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ;
+ pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER;
+ } else {
+ pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ;
+ pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
+ }
+ pDev->ScatterIsVirtual = TRUE;
+ }
+
+ return status;
+}
+
+
+A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer)
+{
+ A_STATUS status;
+
+ if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n"));
+ return A_ENOTSUP;
+ }
+
+ status = HIFConfigureDevice(pDev->HIFDevice,
+ HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
+ &pDev->HifScatterInfo,
+ sizeof(pDev->HifScatterInfo));
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status));
+
+ /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */
+ status = DevSetupVirtualScatterSupport(pDev);
+
+ if (A_SUCCESS(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n",
+ DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
+ }
+
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("AR6K: HIF layer supports scatter requests (max scatter items:%d: maxlen:%d) \n",
+ DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev)));
+ }
+
+ if (A_SUCCESS(status)) {
+ /* for the recv path, the maximum number of bytes per recv bundle is just limited
+ * by the maximum transfer size at the HIF layer */
+ pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
+
+ if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundling disabled\n"));
+ pDev->MaxSendBundleSize = 0;
+ } else {
+ /* for the send path, the max transfer size is limited by the existence and size of
+ * the extended mailbox address range */
+ if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) {
+ pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize;
+ } else {
+ /* legacy */
+ pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH;
+ }
+
+ if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerScatterReq) {
+ /* limit send bundle size to what the HIF can support for scatter requests */
+ pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq;
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("AR6K: max recv: %d max send: %d \n",
+ DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)));
+
+ }
+ return status;
+}
+
+A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async)
+{
+ A_STATUS status;
+
+ if (Read) {
+ /* read operation */
+ pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX;
+ pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
+ A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev));
+ } else {
+ A_UINT32 mailboxWidth;
+
+ /* write operation */
+ pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC;
+ A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev));
+ if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) {
+ /* for large writes use the extended address */
+ pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress;
+ mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize;
+ } else {
+ pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
+ mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH;
+ }
+
+ if (!pDev->ScatterIsVirtual) {
+ /* we are passing this scatter list down to the HIF layer' scatter request handler, fixup the address
+ * so that the last byte falls on the EOM, we do this for those HIFs that support the
+ * scatter API */
+ pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength);
+ }
+
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND,
+ ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x%X (mode: %s : %s)\n",
+ pScatterReq->ValidScatterEntries,
+ pScatterReq->TotalLength,
+ pScatterReq->Address,
+ Async ? "ASYNC" : "SYNC",
+ (Read) ? "RD" : "WR"));
+
+ status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq);
+
+ if (A_FAILED(status)) {
+ if (Async) {
+ pScatterReq->CompletionStatus = status;
+ pScatterReq->CompletionRoutine(pScatterReq);
+ return A_OK;
+ }
+ return status;
+ }
+
+ status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ? pDev : pDev->HIFDevice,
+ pScatterReq);
+ if (!Async) {
+ /* in sync mode, we can touch the scatter request */
+ pScatterReq->CompletionStatus = status;
+ DEV_FINISH_SCATTER_OPERATION(pScatterReq);
+ } else {
+ if (status == A_PENDING) {
+ status = A_OK;
+ }
+ }
+
+ return status;
+}
+
+
+#ifdef MBOXHW_UNIT_TEST
+
+
+/* This is a mailbox hardware unit test that must be called in a schedulable context
+ * This test is very simple, it will send a list of buffers with a counting pattern
+ * and the target will invert the data and send the message back
+ *
+ * the unit test has the following constraints:
+ *
+ * The target has at least 8 buffers of 256 bytes each. The host will send
+ * the following pattern of buffers in rapid succession :
+ *
+ * 1 buffer - 128 bytes
+ * 1 buffer - 256 bytes
+ * 1 buffer - 512 bytes
+ * 1 buffer - 1024 bytes
+ *
+ * The host will send the buffers to one mailbox and wait for buffers to be reflected
+ * back from the same mailbox. The target sends the buffers FIFO order.
+ * Once the final buffer has been received for a mailbox, the next mailbox is tested.
+ *
+ *
+ * Note: To simplifythe test , we assume that the chosen buffer sizes
+ * will fall on a nice block pad
+ *
+ * It is expected that higher-order tests will be written to stress the mailboxes using
+ * a message-based protocol (with some performance timming) that can create more
+ * randomness in the packets sent over mailboxes.
+ *
+ * */
+
+#define A_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
+
+#define BUFFER_BLOCK_PAD 128
+
+#if 0
+#define BUFFER1 128
+#define BUFFER2 256
+#define BUFFER3 512
+#define BUFFER4 1024
+#endif
+
+#if 1
+#define BUFFER1 80
+#define BUFFER2 200
+#define BUFFER3 444
+#define BUFFER4 800
+#endif
+
+#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \
+ A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \
+ A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \
+ A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) )
+
+#define TEST_BYTES (BUFFER1 + BUFFER2 + BUFFER3 + BUFFER4)
+
+#define TEST_CREDITS_RECV_TIMEOUT 100
+
+static A_UINT8 g_Buffer[TOTAL_BYTES];
+static A_UINT32 g_MailboxAddrs[AR6K_MAILBOXES];
+static A_UINT32 g_BlockSizes[AR6K_MAILBOXES];
+
+#define BUFFER_PROC_LIST_DEPTH 4
+
+typedef struct _BUFFER_PROC_LIST{
+ A_UINT8 *pBuffer;
+ A_UINT32 length;
+}BUFFER_PROC_LIST;
+
+
+#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \
+{ \
+ (pList)->pBuffer = (pCurrpos); \
+ (pList)->length = (len); \
+ (pCurrpos) += (len); \
+ (pList)++; \
+}
+
+/* a simple and crude way to send different "message" sizes */
+static void AssembleBufferList(BUFFER_PROC_LIST *pList)
+{
+ A_UINT8 *pBuffer = g_Buffer;
+
+#if BUFFER_PROC_LIST_DEPTH < 4
+#error "Buffer processing list depth is not deep enough!!"
+#endif
+
+ PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer);
+ PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer);
+ PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer);
+ PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer);
+
+}
+
+#define FILL_ZERO TRUE
+#define FILL_COUNTING FALSE
+static void InitBuffers(A_BOOL Zero)
+{
+ A_UINT16 *pBuffer16 = (A_UINT16 *)g_Buffer;
+ int i;
+
+ /* fill buffer with 16 bit counting pattern or zeros */
+ for (i = 0; i < (TOTAL_BYTES / 2) ; i++) {
+ if (!Zero) {
+ pBuffer16[i] = (A_UINT16)i;
+ } else {
+ pBuffer16[i] = 0;
+ }
+ }
+}
+
+
+static A_BOOL CheckOneBuffer(A_UINT16 *pBuffer16, int Length)
+{
+ int i;
+ A_UINT16 startCount;
+ A_BOOL success = TRUE;
+
+ /* get the starting count */
+ startCount = pBuffer16[0];
+ /* invert it, this is the expected value */
+ startCount = ~startCount;
+ /* scan the buffer and verify */
+ for (i = 0; i < (Length / 2) ; i++,startCount++) {
+ /* target will invert all the data */
+ if ((A_UINT16)pBuffer16[i] != (A_UINT16)~startCount) {
+ success = FALSE;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n",
+ pBuffer16[i], ((A_UINT16)~startCount), i, Length));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n",
+ pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3]));
+ break;
+ }
+ }
+
+ return success;
+}
+
+static A_BOOL CheckBuffers(void)
+{
+ int i;
+ A_BOOL success = TRUE;
+ BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH];
+
+ /* assemble the list */
+ AssembleBufferList(checkList);
+
+ /* scan the buffers and verify */
+ for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) {
+ success = CheckOneBuffer((A_UINT16 *)checkList[i].pBuffer, checkList[i].length);
+ if (!success) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n",
+ (A_UINT32)checkList[i].pBuffer, checkList[i].length));
+ break;
+ }
+ }
+
+ return success;
+}
+
+ /* find the end marker for the last buffer we will be sending */
+static A_UINT16 GetEndMarker(void)
+{
+ A_UINT8 *pBuffer;
+ BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH];
+
+ /* fill up buffers with the normal counting pattern */
+ InitBuffers(FILL_COUNTING);
+
+ /* assemble the list we will be sending down */
+ AssembleBufferList(checkList);
+ /* point to the last 2 bytes of the last buffer */
+ pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]);
+
+ /* the last count in the last buffer is the marker */
+ return (A_UINT16)pBuffer[0] | ((A_UINT16)pBuffer[1] << 8);
+}
+
+#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR
+
+/* send the ordered buffers to the target */
+static A_STATUS SendBuffers(AR6K_DEVICE *pDev, int mbox)
+{
+ A_STATUS status = A_OK;
+ A_UINT32 request = HIF_WR_SYNC_BLOCK_INC;
+ BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH];
+ int i;
+ int totalBytes = 0;
+ int paddedLength;
+ int totalwPadding = 0;
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox));
+
+ /* fill buffer with counting pattern */
+ InitBuffers(FILL_COUNTING);
+
+ /* assemble the order in which we send */
+ AssembleBufferList(sendList);
+
+ for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) {
+
+ /* we are doing block transfers, so we need to pad everything to a block size */
+ paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) &
+ (~(g_BlockSizes[mbox] - 1));
+
+ /* send each buffer synchronously */
+ status = HIFReadWrite(pDev->HIFDevice,
+ g_MailboxAddrs[mbox],
+ sendList[i].pBuffer,
+ paddedLength,
+ request,
+ NULL);
+ if (status != A_OK) {
+ break;
+ }
+ totalBytes += sendList[i].length;
+ totalwPadding += paddedLength;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox));
+
+ return status;
+}
+
+/* poll the mailbox credit counter until we get a credit or timeout */
+static A_STATUS GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits)
+{
+ A_STATUS status = A_OK;
+ int timeout = TEST_CREDITS_RECV_TIMEOUT;
+ A_UINT8 credits = 0;
+ A_UINT32 address;
+
+ while (TRUE) {
+
+ /* Read the counter register to get credits, this auto-decrements */
+ address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4;
+ status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits),
+ HIF_RD_SYNC_BYTE_FIX, NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Unable to decrement the command credit count register (mbox=%d)\n",mbox));
+ status = A_ERROR;
+ break;
+ }
+
+ if (credits) {
+ break;
+ }
+
+ timeout--;
+
+ if (timeout <= 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address));
+ status = A_ERROR;
+ break;
+ }
+
+ /* delay a little, target may not be ready */
+ A_MDELAY(1000);
+
+ }
+
+ if (status == A_OK) {
+ *pCredits = credits;
+ }
+
+ return status;
+}
+
+
+/* wait for the buffers to come back */
+static A_STATUS RecvBuffers(AR6K_DEVICE *pDev, int mbox)
+{
+ A_STATUS status = A_OK;
+ A_UINT32 request = HIF_RD_SYNC_BLOCK_INC;
+ BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH];
+ int curBuffer;
+ int credits;
+ int i;
+ int totalBytes = 0;
+ int paddedLength;
+ int totalwPadding = 0;
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox));
+
+ /* zero the buffers */
+ InitBuffers(FILL_ZERO);
+
+ /* assemble the order in which we should receive */
+ AssembleBufferList(recvList);
+
+ curBuffer = 0;
+
+ while (curBuffer < BUFFER_PROC_LIST_DEPTH) {
+
+ /* get number of buffers that have been completed, this blocks
+ * until we get at least 1 credit or it times out */
+ status = GetCredits(pDev, mbox, &credits);
+
+ if (status != A_OK) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox));
+
+ /* get all the buffers that are sitting on the queue */
+ for (i = 0; i < credits; i++) {
+ A_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH);
+ /* recv the current buffer synchronously, the buffers should come back in
+ * order... with padding applied by the target */
+ paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) &
+ (~(g_BlockSizes[mbox] - 1));
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ g_MailboxAddrs[mbox],
+ recvList[curBuffer].pBuffer,
+ paddedLength,
+ request,
+ NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n",
+ recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox]));
+ break;
+ }
+
+ totalwPadding += paddedLength;
+ totalBytes += recvList[curBuffer].length;
+ curBuffer++;
+ }
+
+ if (status != A_OK) {
+ break;
+ }
+ /* go back and get some more */
+ credits = 0;
+ }
+
+ if (totalBytes != TEST_BYTES) {
+ A_ASSERT(FALSE);
+ } else {
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n",
+ mbox, totalBytes, totalwPadding));
+ }
+
+ return status;
+
+
+}
+
+static A_STATUS DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox)
+{
+ A_STATUS status;
+
+ do {
+ /* send out buffers */
+ status = SendBuffers(pDev,mbox);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox));
+ break;
+ }
+
+ /* go get them, this will block */
+ status = RecvBuffers(pDev, mbox);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox));
+ break;
+ }
+
+ /* check the returned data patterns */
+ if (!CheckBuffers()) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox));
+ status = A_ERROR;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox));
+
+ } while (FALSE);
+
+ return status;
+}
+
+/* here is where the test starts */
+A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev)
+{
+ int i;
+ A_STATUS status;
+ int credits = 0;
+ A_UINT8 params[4];
+ int numBufs;
+ int bufferSize;
+ A_UINT16 temp;
+
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n"));
+
+ do {
+ /* get the addresses for all 4 mailboxes */
+ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
+ g_MailboxAddrs, sizeof(g_MailboxAddrs));
+
+ if (status != A_OK) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* get the block sizes */
+ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+ g_BlockSizes, sizeof(g_BlockSizes));
+
+ if (status != A_OK) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* note, the HIF layer usually reports mbox 0 to have a block size of
+ * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes
+ * the same. */
+ g_BlockSizes[0] = g_BlockSizes[1];
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0]));
+
+ if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) {
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n",
+ g_BlockSizes[1], BUFFER_BLOCK_PAD));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n"));
+
+ /* the target lets us know it is ready by giving us 1 credit on
+ * mailbox 0 */
+ status = GetCredits(pDev, 0, &credits);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n"));
+
+ /* read the first 4 scratch registers */
+ status = HIFReadWrite(pDev->HIFDevice,
+ SCRATCH_ADDRESS,
+ params,
+ 4,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n"));
+ break;
+ }
+
+ numBufs = params[0];
+ bufferSize = (int)(((A_UINT16)params[2] << 8) | (A_UINT16)params[1]);
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE,
+ ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n",
+ numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES));
+
+ if ((numBufs * bufferSize) < TOTAL_BYTES) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n",
+ TOTAL_BYTES, (numBufs*bufferSize)));
+ status = A_ERROR;
+ break;
+ }
+
+ temp = GetEndMarker();
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ SCRATCH_ADDRESS + 4,
+ (A_UINT8 *)&temp,
+ 2,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp));
+
+ temp = (A_UINT16)g_BlockSizes[1];
+ /* convert to a mask */
+ temp = temp - 1;
+ status = HIFReadWrite(pDev->HIFDevice,
+ SCRATCH_ADDRESS + 6,
+ (A_UINT8 *)&temp,
+ 2,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp));
+
+ /* execute the test on each mailbox */
+ for (i = 0; i < AR6K_MAILBOXES; i++) {
+ status = DoOneMboxHWTest(pDev, i);
+ if (status != A_OK) {
+ break;
+ }
+ }
+
+ } while (FALSE);
+
+ if (status == A_OK) {
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n"));
+ } else {
+ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n"));
+ }
+ /* don't let HTC_Start continue, the target is actually not running any HTC code */
+ return A_ERROR;
+}
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
new file mode 100644
index 000000000000..b30fd877aebf
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
@@ -0,0 +1,398 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6k.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// AR6K device layer that handles register level I/O
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef AR6K_H_
+#define AR6K_H_
+
+#include "hci_transport_api.h"
+#include "../htc_debug.h"
+
+#define AR6K_MAILBOXES 4
+
+/* HTC runs over mailbox 0 */
+#define HTC_MAILBOX 0
+
+#define AR6K_TARGET_DEBUG_INTR_MASK 0x01
+
+#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
+ INT_STATUS_ENABLE_CPU_MASK | \
+ INT_STATUS_ENABLE_COUNTER_MASK)
+
+
+//#define MBOXHW_UNIT_TEST 1
+
+#include "athstartpack.h"
+typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS {
+ A_UINT8 host_int_status;
+ A_UINT8 cpu_int_status;
+ A_UINT8 error_int_status;
+ A_UINT8 counter_int_status;
+ A_UINT8 mbox_frame;
+ A_UINT8 rx_lookahead_valid;
+ A_UINT8 host_int_status2;
+ A_UINT8 gmbox_rx_avail;
+ A_UINT32 rx_lookahead[2];
+ A_UINT32 rx_gmbox_lookahead_alias[2];
+} POSTPACK AR6K_IRQ_PROC_REGISTERS;
+
+#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS)
+
+typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS {
+ A_UINT8 int_status_enable;
+ A_UINT8 cpu_int_status_enable;
+ A_UINT8 error_status_enable;
+ A_UINT8 counter_int_status_enable;
+} POSTPACK AR6K_IRQ_ENABLE_REGISTERS;
+
+typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS {
+ A_UINT8 int_status_enable;
+} POSTPACK AR6K_GMBOX_CTRL_REGISTERS;
+
+#include "athendpack.h"
+
+#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS)
+
+#define AR6K_REG_IO_BUFFER_SIZE 32
+#define AR6K_MAX_REG_IO_BUFFERS 8
+#define FROM_DMA_BUFFER TRUE
+#define TO_DMA_BUFFER FALSE
+#define AR6K_SCATTER_ENTRIES_PER_REQ 16
+#define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024
+#define AR6K_SCATTER_REQS 4
+#define AR6K_LEGACY_MAX_WRITE_LENGTH 2048
+
+#ifndef A_CACHE_LINE_PAD
+#define A_CACHE_LINE_PAD 128
+#endif
+#define AR6K_MIN_SCATTER_ENTRIES_PER_REQ 2
+#define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024
+
+/* buffers for ASYNC I/O */
+typedef struct AR6K_ASYNC_REG_IO_BUFFER {
+ HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */
+ A_UINT8 _Pad1[A_CACHE_LINE_PAD];
+ A_UINT8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */
+ A_UINT8 _Pad2[A_CACHE_LINE_PAD];
+} AR6K_ASYNC_REG_IO_BUFFER;
+
+typedef struct _AR6K_GMBOX_INFO {
+ void *pProtocolContext;
+ A_STATUS (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes);
+ A_STATUS (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled);
+ void (*pTargetFailureCallback)(void *pContext, A_STATUS Status);
+ void (*pStateDumpCallback)(void *pContext);
+ A_BOOL CreditCountIRQEnabled;
+} AR6K_GMBOX_INFO;
+
+typedef struct _AR6K_DEVICE {
+ A_MUTEX_T Lock;
+ A_UINT8 _Pad1[A_CACHE_LINE_PAD];
+ AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */
+ A_UINT8 _Pad2[A_CACHE_LINE_PAD];
+ AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */
+ A_UINT8 _Pad3[A_CACHE_LINE_PAD];
+ void *HIFDevice;
+ A_UINT32 BlockSize;
+ A_UINT32 BlockMask;
+ HIF_DEVICE_MBOX_INFO MailBoxInfo;
+ HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc;
+ void *HTCContext;
+ HTC_PACKET_QUEUE RegisterIOList;
+ AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
+ void (*TargetFailureCallback)(void *Context);
+ A_STATUS (*MessagePendingCallback)(void *Context,
+ A_UINT32 LookAheads[],
+ int NumLookAheads,
+ A_BOOL *pAsyncProc,
+ int *pNumPktsFetched);
+ HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode;
+ HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent;
+ A_BOOL HifAttached;
+ HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams;
+ A_BOOL DSRCanYield;
+ int CurrentDSRRecvCount;
+ HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo;
+ DL_LIST ScatterReqHead;
+ A_BOOL ScatterIsVirtual;
+ int MaxRecvBundleSize;
+ int MaxSendBundleSize;
+ AR6K_GMBOX_INFO GMboxInfo;
+ A_BOOL GMboxEnabled;
+ AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters;
+ int RecheckIRQStatusCnt;
+} AR6K_DEVICE;
+
+#define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock);
+#define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock);
+#define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */
+
+A_STATUS DevSetup(AR6K_DEVICE *pDev);
+void DevCleanup(AR6K_DEVICE *pDev);
+A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
+A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
+A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
+ A_UINT32 *pLookAhead,
+ int TimeoutMS);
+A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
+A_STATUS DevDsrHandler(void *context);
+A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
+void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev);
+void DevDumpRegisters(AR6K_DEVICE *pDev,
+ AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs,
+ AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs);
+
+#define DEV_STOP_RECV_ASYNC TRUE
+#define DEV_STOP_RECV_SYNC FALSE
+#define DEV_ENABLE_RECV_ASYNC TRUE
+#define DEV_ENABLE_RECV_SYNC FALSE
+A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
+A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
+A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev);
+A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev);
+A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending);
+
+#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask)))
+#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length)
+#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0)
+
+static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) {
+ A_UINT32 paddedLength;
+ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
+ A_STATUS status;
+
+ /* adjust the length to be a multiple of block size if appropriate */
+ paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
+
+#if 0
+ if (paddedLength > pPacket->BufferLength) {
+ A_ASSERT(FALSE);
+ if (pPacket->Completion != NULL) {
+ COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
+ return A_OK;
+ }
+ return A_EINVAL;
+ }
+#endif
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
+ paddedLength,
+ pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
+ sync ? "SYNC" : "ASYNC"));
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
+ pPacket->pBuffer,
+ paddedLength, /* the padded length */
+ sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
+ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
+
+ if (sync) {
+ pPacket->Status = status;
+ } else {
+ if (status == A_PENDING) {
+ status = A_OK;
+ }
+ }
+
+ return status;
+}
+
+static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) {
+ A_UINT32 paddedLength;
+ A_STATUS status;
+ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
+
+ /* adjust the length to be a multiple of block size if appropriate */
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
+
+ if (paddedLength > pPacket->BufferLength) {
+ A_ASSERT(FALSE);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
+ paddedLength,RecvLength,pPacket->BufferLength));
+ if (pPacket->Completion != NULL) {
+ COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
+ return A_OK;
+ }
+ return A_EINVAL;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
+ (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
+ paddedLength,
+ pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
+ sync ? "SYNC" : "ASYNC"));
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
+ pPacket->pBuffer,
+ paddedLength,
+ sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
+ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
+
+ if (sync) {
+ pPacket->Status = status;
+ }
+
+ return status;
+}
+
+#define DEV_CHECK_RECV_YIELD(pDev) \
+ ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)
+
+#define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode)
+#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
+
+/**************************************************/
+/****** Scatter Function and Definitions
+ *
+ *
+ */
+
+A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA);
+
+ /* copy any READ data back into scatter list */
+#define DEV_FINISH_SCATTER_OPERATION(pR) \
+ if (A_SUCCESS((pR)->CompletionStatus) && \
+ !((pR)->Request & HIF_WRITE) && \
+ ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \
+ (pR)->CompletionStatus = DevCopyScatterListToFromDMABuffer((pR),FROM_DMA_BUFFER); \
+ }
+
+ /* copy any WRITE data to bounce buffer */
+static INLINE A_STATUS DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) {
+ if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
+ return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);
+ } else {
+ return A_OK;
+ }
+}
+
+
+A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer);
+
+#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries
+#define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
+#define DEV_ALLOC_SCATTER_REQ(pDev) \
+ (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
+
+#define DEV_FREE_SCATTER_REQ(pDev,pR) \
+ (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
+
+#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize
+#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize
+
+#define DEV_SCATTER_READ TRUE
+#define DEV_SCATTER_WRITE FALSE
+#define DEV_SCATTER_ASYNC TRUE
+#define DEV_SCATTER_SYNC FALSE
+A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async);
+
+#ifdef MBOXHW_UNIT_TEST
+A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
+#endif
+
+ /* completely virtual */
+typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO {
+ A_UINT8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */
+ A_UINT8 DataArea[1]; /* start of data area */
+} DEV_SCATTER_DMA_VIRTUAL_INFO;
+
+
+
+void DumpAR6KDevState(AR6K_DEVICE *pDev);
+
+/**************************************************/
+/****** GMBOX functions and definitions
+ *
+ *
+ */
+
+#ifdef ATH_AR6K_ENABLE_GMBOX
+
+void DevCleanupGMbox(AR6K_DEVICE *pDev);
+A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev);
+A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev);
+void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev);
+
+#else
+
+ /* compiled out */
+#define DevCleanupGMbox(p)
+#define DevCheckGMboxInterrupts(p) A_OK
+#define DevNotifyGMboxTargetFailure(p)
+
+static INLINE A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) {
+ pDev->GMboxEnabled = FALSE;
+ return A_OK;
+}
+
+#endif
+
+#ifdef ATH_AR6K_ENABLE_GMBOX
+
+ /* GMBOX protocol modules must expose each of these internal APIs */
+HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo);
+A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev);
+void GMboxProtocolUninstall(AR6K_DEVICE *pDev);
+
+ /* API used by GMBOX protocol modules */
+AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle);
+#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
+{ \
+ (pDev)->GMboxInfo.pProtocolContext = (context); \
+ (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \
+ (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
+ (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \
+ (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \
+}
+
+#define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext
+
+A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength);
+A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength);
+
+#define PROC_IO_ASYNC TRUE
+#define PROC_IO_SYNC FALSE
+typedef enum GMBOX_IRQ_ACTION_TYPE {
+ GMBOX_ACTION_NONE = 0,
+ GMBOX_DISABLE_ALL,
+ GMBOX_ERRORS_IRQ_ENABLE,
+ GMBOX_RECV_IRQ_ENABLE,
+ GMBOX_RECV_IRQ_DISABLE,
+ GMBOX_CREDIT_IRQ_ENABLE,
+ GMBOX_CREDIT_IRQ_DISABLE,
+} GMBOX_IRQ_ACTION_TYPE;
+
+A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode);
+A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits);
+A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize);
+A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes);
+A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS);
+
+#endif
+
+#endif /*AR6K_H_*/
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
new file mode 100644
index 000000000000..920123b9ba1a
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
@@ -0,0 +1,784 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6k_events.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// AR6K Driver layer event handling (i.e. interrupts, message polling)
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "a_osapi.h"
+#include "../htc_debug.h"
+#include "hif.h"
+#include "htc_packet.h"
+#include "ar6k.h"
+
+extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket);
+extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev);
+
+static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev);
+
+#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */
+
+/* completion routine for ALL HIF layer async I/O */
+A_STATUS DevRWCompletionHandler(void *context, A_STATUS status)
+{
+ HTC_PACKET *pPacket = (HTC_PACKET *)context;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n",
+ (unsigned long)pPacket,
+ status));
+
+ COMPLETE_HTC_PACKET(pPacket,status);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("-DevRWCompletionHandler\n"));
+
+ return A_OK;
+}
+
+/* mailbox recv message polling */
+A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
+ A_UINT32 *pLookAhead,
+ int TimeoutMS)
+{
+ A_STATUS status = A_OK;
+ int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS;
+
+ A_ASSERT(timeout > 0);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n"));
+
+ while (TRUE) {
+
+ if (pDev->GetPendingEventsFunc != NULL) {
+
+ HIF_PENDING_EVENTS_INFO events;
+
+#ifdef THREAD_X
+ events.Polling =1;
+#endif
+
+ /* the HIF layer uses a special mechanism to get events, do this
+ * synchronously */
+ status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
+ &events,
+ NULL);
+ if (A_FAILED(status))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"));
+ break;
+ }
+
+ if (events.Events & HIF_RECV_MSG_AVAIL)
+ {
+ /* there is a message available, the lookahead should be valid now */
+ *pLookAhead = events.LookAhead;
+
+ break;
+ }
+ } else {
+
+ /* this is the standard HIF way.... */
+ /* load the register table */
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ (A_UINT8 *)&pDev->IrqProcRegisters,
+ AR6K_IRQ_PROC_REGS_SIZE,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ if (A_FAILED(status)){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n"));
+ break;
+ }
+
+ /* check for MBOX data and valid lookahead */
+ if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) {
+ if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX))
+ {
+ /* mailbox has a message and the look ahead is valid */
+ *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
+ break;
+ }
+ }
+
+ }
+
+ timeout--;
+
+ if (timeout <= 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n"));
+ status = A_ERROR;
+
+ /* check if the target asserted */
+ if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
+ /* target signaled an assert, process this pending interrupt
+ * this will call the target failure handler */
+ DevServiceDebugInterrupt(pDev);
+ }
+
+ break;
+ }
+
+ /* delay a little */
+ A_MDELAY(DELAY_PER_INTERVAL_MS);
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Retry Mbox Poll : %d \n",timeout));
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n"));
+
+ return status;
+}
+
+static A_STATUS DevServiceCPUInterrupt(AR6K_DEVICE *pDev)
+{
+ A_STATUS status;
+ A_UINT8 cpu_int_status;
+ A_UINT8 regBuffer[4];
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n"));
+ cpu_int_status = pDev->IrqProcRegisters.cpu_int_status &
+ pDev->IrqEnableRegisters.cpu_int_status_enable;
+ A_ASSERT(cpu_int_status);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
+ cpu_int_status));
+
+ /* Clear the interrupt */
+ pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */
+
+ /* set up the register transfer buffer to hit the register 4 times , this is done
+ * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
+ * restrict bus transfer lengths to be a multiple of 4-bytes */
+
+ /* set W1C value to clear the interrupt, this hits the register first */
+ regBuffer[0] = cpu_int_status;
+ /* the remaining 4 values are set to zero which have no-effect */
+ regBuffer[1] = 0;
+ regBuffer[2] = 0;
+ regBuffer[3] = 0;
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ CPU_INT_STATUS_ADDRESS,
+ regBuffer,
+ 4,
+ HIF_WR_SYNC_BYTE_FIX,
+ NULL);
+
+ A_ASSERT(status == A_OK);
+ return status;
+}
+
+
+static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev)
+{
+ A_STATUS status;
+ A_UINT8 error_int_status;
+ A_UINT8 regBuffer[4];
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n"));
+ error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F;
+ A_ASSERT(error_int_status);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
+ error_int_status));
+
+ if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
+ /* Wakeup */
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n"));
+ }
+
+ if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
+ /* Rx Underflow */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n"));
+ }
+
+ if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
+ /* Tx Overflow */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n"));
+ }
+
+ /* Clear the interrupt */
+ pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */
+
+ /* set up the register transfer buffer to hit the register 4 times , this is done
+ * to make the access 4-byte aligned to mitigate issues with host bus interconnects that
+ * restrict bus transfer lengths to be a multiple of 4-bytes */
+
+ /* set W1C value to clear the interrupt, this hits the register first */
+ regBuffer[0] = error_int_status;
+ /* the remaining 4 values are set to zero which have no-effect */
+ regBuffer[1] = 0;
+ regBuffer[2] = 0;
+ regBuffer[3] = 0;
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ ERROR_INT_STATUS_ADDRESS,
+ regBuffer,
+ 4,
+ HIF_WR_SYNC_BYTE_FIX,
+ NULL);
+
+ A_ASSERT(status == A_OK);
+ return status;
+}
+
+static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev)
+{
+ A_UINT32 dummy;
+ A_STATUS status;
+
+ /* Send a target failure event to the application */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n"));
+
+ if (pDev->TargetFailureCallback != NULL) {
+ pDev->TargetFailureCallback(pDev->HTCContext);
+ }
+
+ if (pDev->GMboxEnabled) {
+ DevNotifyGMboxTargetFailure(pDev);
+ }
+
+ /* clear the interrupt , the debug error interrupt is
+ * counter 0 */
+ /* read counter to clear interrupt */
+ status = HIFReadWrite(pDev->HIFDevice,
+ COUNT_DEC_ADDRESS,
+ (A_UINT8 *)&dummy,
+ 4,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ A_ASSERT(status == A_OK);
+ return status;
+}
+
+static A_STATUS DevServiceCounterInterrupt(AR6K_DEVICE *pDev)
+{
+ A_UINT8 counter_int_status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));
+
+ counter_int_status = pDev->IrqProcRegisters.counter_int_status &
+ pDev->IrqEnableRegisters.counter_int_status_enable;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
+ counter_int_status));
+
+ /* Check if the debug interrupt is pending
+ * NOTE: other modules like GMBOX may use the counter interrupt for
+ * credit flow control on other counters, we only need to check for the debug assertion
+ * counter interrupt */
+ if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) {
+ return DevServiceDebugInterrupt(pDev);
+ }
+
+ return A_OK;
+}
+
+/* callback when our fetch to get interrupt status registers completes */
+static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+ A_UINT32 lookAhead = 0;
+ A_BOOL otherInts = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ do {
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" GetEvents I/O request failed, status:%d \n", pPacket->Status));
+ /* bail out, don't unmask HIF interrupt */
+ break;
+ }
+
+ if (pDev->GetPendingEventsFunc != NULL) {
+ /* the HIF layer collected the information for us */
+ HIF_PENDING_EVENTS_INFO *pEvents = (HIF_PENDING_EVENTS_INFO *)pPacket->pBuffer;
+ if (pEvents->Events & HIF_RECV_MSG_AVAIL) {
+ lookAhead = pEvents->LookAhead;
+ if (0 == lookAhead) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n"));
+ }
+ }
+ if (pEvents->Events & HIF_OTHER_EVENTS) {
+ otherInts = TRUE;
+ }
+ } else {
+ /* standard interrupt table handling.... */
+ AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer;
+ A_UINT8 host_int_status;
+
+ host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable;
+
+ if (host_int_status & (1 << HTC_MAILBOX)) {
+ host_int_status &= ~(1 << HTC_MAILBOX);
+ if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) {
+ /* mailbox has a message and the look ahead is valid */
+ lookAhead = pReg->rx_lookahead[HTC_MAILBOX];
+ if (0 == lookAhead) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n"));
+ }
+ }
+ }
+
+ if (host_int_status) {
+ /* there are other interrupts to handle */
+ otherInts = TRUE;
+ }
+ }
+
+ if (otherInts || (lookAhead == 0)) {
+ /* if there are other interrupts to process, we cannot do this in the async handler so
+ * ack the interrupt which will cause our sync handler to run again
+ * if however there are no more messages, we can now ack the interrupt */
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n",
+ otherInts, lookAhead));
+ HIFAckInterrupt(pDev->HIFDevice);
+ } else {
+ int fetched = 0;
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n",
+ lookAhead));
+ /* lookahead is non-zero and there are no other interrupts to service,
+ * go get the next message */
+ status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched);
+
+ if (A_SUCCESS(status) && !fetched) {
+ /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n"));
+ DevAsyncIrqProcessComplete(pDev);
+ }
+ }
+
+ } while (FALSE);
+
+ /* free this IO packet */
+ AR6KFreeIOPacket(pDev,pPacket);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n"));
+}
+
+/* called by the HTC layer when it wants us to check if the device has any more pending
+ * recv messages, this starts off a series of async requests to read interrupt registers */
+A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)context;
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket;
+
+ /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can
+ * cause us to switch contexts */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ do {
+
+ if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
+ /* break the async processing chain right here, no need to continue.
+ * The DevDsrHandler() will handle things in a loop when things are driven
+ * synchronously */
+ break;
+ }
+
+ /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
+ * the target, if upper layers determine that we are in a low-throughput mode, we can
+ * rely on taking another interrupt rather than re-checking the status registers which can
+ * re-wake the target */
+ if (pDev->RecheckIRQStatusCnt == 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n"));
+ /* ack interrupt */
+ HIFAckInterrupt(pDev->HIFDevice);
+ break;
+ }
+
+ /* first allocate one of our HTC packets we created for async I/O
+ * we reuse HTC packet definitions so that we can use the completion mechanism
+ * in DevRWCompletionHandler() */
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ /* there should be only 1 asynchronous request out at a time to read these registers
+ * so this should actually never happen */
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevGetEventAsyncHandler;
+ pIOPacket->pContext = pDev;
+
+ if (pDev->GetPendingEventsFunc) {
+ /* HIF layer has it's own mechanism, pass the IO to it.. */
+ status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
+ (HIF_PENDING_EVENTS_INFO *)pIOPacket->pBuffer,
+ pIOPacket);
+
+ } else {
+ /* standard way, read the interrupt register table asynchronously again */
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ pIOPacket->pBuffer,
+ AR6K_IRQ_PROC_REGS_SIZE,
+ HIF_RD_ASYNC_BYTE_INC,
+ pIOPacket);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n"));
+ } while (FALSE);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n"));
+
+ return status;
+}
+
+void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
+ HIFAckInterrupt(pDev->HIFDevice);
+}
+
+/* process pending interrupts synchronously */
+static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 host_int_status = 0;
+ A_UINT32 lookAhead = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ /*** NOTE: the HIF implementation guarantees that the context of this call allows
+ * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that
+ * can block or switch thread/task ontexts.
+ * This is a fully schedulable context.
+ * */
+ do {
+
+ if (pDev->IrqEnableRegisters.int_status_enable == 0) {
+ /* interrupt enables have been cleared, do not try to process any pending interrupts that
+ * may result in more bus transactions. The target may be unresponsive at this
+ * point. */
+ break;
+ }
+
+ if (pDev->GetPendingEventsFunc != NULL) {
+ HIF_PENDING_EVENTS_INFO events;
+
+#ifdef THREAD_X
+ events.Polling= 0;
+#endif
+ /* the HIF layer uses a special mechanism to get events
+ * get this synchronously */
+ status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
+ &events,
+ NULL);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (events.Events & HIF_RECV_MSG_AVAIL) {
+ lookAhead = events.LookAhead;
+ if (0 == lookAhead) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n"));
+ }
+ }
+
+ if (!(events.Events & HIF_OTHER_EVENTS) ||
+ !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) {
+ /* no need to read the register table, no other interesting interrupts.
+ * Some interfaces (like SPI) can shadow interrupt sources without
+ * requiring the host to do a full table read */
+ break;
+ }
+
+ /* otherwise fall through and read the register table */
+ }
+
+ /*
+ * Read the first 28 bytes of the HTC register table. This will yield us
+ * the value of different int status registers and the lookahead
+ * registers.
+ * length = sizeof(int_status) + sizeof(cpu_int_status) +
+ * sizeof(error_int_status) + sizeof(counter_int_status) +
+ * sizeof(mbox_frame) + sizeof(rx_lookahead_valid) +
+ * sizeof(hole) + sizeof(rx_lookahead) +
+ * sizeof(int_status_enable) + sizeof(cpu_int_status_enable) +
+ * sizeof(error_status_enable) +
+ * sizeof(counter_int_status_enable);
+ *
+ */
+#ifdef CONFIG_MMC_SDHCI_S3C
+ pDev->IrqProcRegisters.host_int_status = 0;
+ pDev->IrqProcRegisters.rx_lookahead_valid = 0;
+ pDev->IrqProcRegisters.host_int_status2 = 0;
+ pDev->IrqProcRegisters.rx_lookahead[0] = 0;
+ pDev->IrqProcRegisters.rx_lookahead[1] = 0xaaa5555;
+#endif /* CONFIG_MMC_SDHCI_S3C */
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ (A_UINT8 *)&pDev->IrqProcRegisters,
+ AR6K_IRQ_PROC_REGS_SIZE,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+#ifdef ATH_DEBUG_MODULE
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
+ DevDumpRegisters(pDev,
+ &pDev->IrqProcRegisters,
+ &pDev->IrqEnableRegisters);
+ }
+#endif
+
+ /* Update only those registers that are enabled */
+ host_int_status = pDev->IrqProcRegisters.host_int_status &
+ pDev->IrqEnableRegisters.int_status_enable;
+
+ if (NULL == pDev->GetPendingEventsFunc) {
+ /* only look at mailbox status if the HIF layer did not provide this function,
+ * on some HIF interfaces reading the RX lookahead is not valid to do */
+ if (host_int_status & (1 << HTC_MAILBOX)) {
+ /* mask out pending mailbox value, we use "lookAhead" as the real flag for
+ * mailbox processing below */
+ host_int_status &= ~(1 << HTC_MAILBOX);
+ if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) {
+ /* mailbox has a message and the look ahead is valid */
+ lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX];
+ if (0 == lookAhead) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n"));
+ }
+ }
+ }
+ } else {
+ /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/
+ host_int_status &= ~(1 << HTC_MAILBOX);
+ }
+
+ if (pDev->GMboxEnabled) {
+ /*call GMBOX layer to process any interrupts of interest */
+ status = DevCheckGMboxInterrupts(pDev);
+ }
+
+ } while (FALSE);
+
+
+ do {
+
+ /* did the interrupt status fetches succeed? */
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if ((0 == host_int_status) && (0 == lookAhead)) {
+ /* nothing to process, the caller can use this to break out of a loop */
+ *pDone = TRUE;
+ break;
+ }
+
+ if (lookAhead != 0) {
+ int fetched = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead));
+ /* Mailbox Interrupt, the HTC layer may issue async requests to empty the
+ * mailbox...
+ * When emptying the recv mailbox we use the async handler above called from the
+ * completion routine of the callers read request. This can improve performance
+ * by reducing context switching when we rapidly pull packets */
+ status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (!fetched) {
+ /* HTC could not pull any messages out due to lack of resources */
+ /* force DSR handler to ack the interrupt */
+ *pASyncProcessing = FALSE;
+ pDev->RecheckIRQStatusCnt = 0;
+ }
+ }
+
+ /* now handle the rest of them */
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n",
+ host_int_status));
+
+ if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
+ /* CPU Interrupt */
+ status = DevServiceCPUInterrupt(pDev);
+ if (A_FAILED(status)){
+ break;
+ }
+ }
+
+ if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
+ /* Error Interrupt */
+ status = DevServiceErrorInterrupt(pDev);
+ if (A_FAILED(status)){
+ break;
+ }
+ }
+
+ if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
+ /* Counter Interrupt */
+ status = DevServiceCounterInterrupt(pDev);
+ if (A_FAILED(status)){
+ break;
+ }
+ }
+
+ } while (FALSE);
+
+ /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake
+ * the target, if upper layers determine that we are in a low-throughput mode, we can
+ * rely on taking another interrupt rather than re-checking the status registers which can
+ * re-wake the target.
+ *
+ * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot
+ * be used due to possible side-effects. For example, SPI requires the host to drain all
+ * messages from the mailbox before exiting the ISR routine. */
+ if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n"));
+ *pDone = TRUE;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n",
+ *pDone, *pASyncProcessing, status));
+
+ return status;
+}
+
+
+/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/
+A_STATUS DevDsrHandler(void *context)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)context;
+ A_STATUS status = A_OK;
+ A_BOOL done = FALSE;
+ A_BOOL asyncProc = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ /* reset the recv counter that tracks when we need to yield from the DSR */
+ pDev->CurrentDSRRecvCount = 0;
+ /* reset counter used to flag a re-scan of IRQ status registers on the target */
+ pDev->RecheckIRQStatusCnt = 0;
+
+ while (!done) {
+ status = ProcessPendingIRQs(pDev, &done, &asyncProc);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) {
+ /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */
+ asyncProc = FALSE;
+ /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers.
+ * this has a nice side effect of blocking us until all async read requests are completed.
+ * This behavior is required on some HIF implementations that do not allow ASYNC
+ * processing in interrupt handlers (like Windows CE) */
+
+ if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) {
+ /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop
+ * checking for more messages and return */
+ break;
+ }
+ }
+
+ if (asyncProc) {
+ /* the function performed some async I/O for performance, we
+ need to exit the ISR immediately, the check below will prevent the interrupt from being
+ Ack'd while we handle it asynchronously */
+ break;
+ }
+
+ }
+
+ if (A_SUCCESS(status) && !asyncProc) {
+ /* Ack the interrupt only if :
+ * 1. we did not get any errors in processing interrupts
+ * 2. there are no outstanding async processing requests */
+ if (pDev->DSRCanYield) {
+ /* if the DSR can yield do not ACK the interrupt, there could be more pending messages.
+ * The HIF layer must ACK the interrupt on behalf of HTC */
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n"));
+ HIFAckInterrupt(pDev->HIFDevice);
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n"));
+ return status;
+}
+
+#ifdef ATH_DEBUG_MODULE
+void DumpAR6KDevState(AR6K_DEVICE *pDev)
+{
+ A_STATUS status;
+ AR6K_IRQ_ENABLE_REGISTERS regs;
+ AR6K_IRQ_PROC_REGISTERS procRegs;
+
+ LOCK_AR6K(pDev);
+ /* copy into our temp area */
+ A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+ UNLOCK_AR6K(pDev);
+
+ /* load the register table from the device */
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ (A_UINT8 *)&procRegs,
+ AR6K_IRQ_PROC_REGS_SIZE,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("DumpAR6KDevState : Failed to read register table (%d) \n",status));
+ return;
+ }
+
+ DevDumpRegisters(pDev,&procRegs,&regs);
+
+ if (pDev->GMboxInfo.pStateDumpCallback != NULL) {
+ pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
+ }
+
+ /* dump any bus state at the HIF layer */
+ HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0);
+
+}
+#endif
+
+
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
new file mode 100644
index 000000000000..e3d270d1d626
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
@@ -0,0 +1,756 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6k_gmbox.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Generic MBOX API implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "../htc_debug.h"
+#include "hif.h"
+#include "htc_packet.h"
+#include "ar6k.h"
+#include "hw/mbox_host_reg.h"
+#include "gmboxif.h"
+
+/*
+ * This file provides management functions and a toolbox for GMBOX protocol modules.
+ * Only one protocol module can be installed at a time. The determination of which protocol
+ * module is installed is determined at compile time.
+ *
+ */
+#ifdef ATH_AR6K_ENABLE_GMBOX
+ /* GMBOX definitions */
+#define GMBOX_INT_STATUS_ENABLE_REG 0x488
+#define GMBOX_INT_STATUS_RX_DATA (1 << 0)
+#define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1)
+#define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2)
+
+#define GMBOX_LOOKAHEAD_MUX_REG 0x498
+#define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0)
+
+#define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER)
+#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER)
+
+
+ /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */
+extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket);
+extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev);
+
+
+/* callback when our fetch to enable/disable completes */
+static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status));
+ }
+ /* free this IO packet */
+ AR6KFreeIOPacket(pDev,pPacket);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
+}
+
+static A_STATUS DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode)
+{
+ A_STATUS status = A_OK;
+ AR6K_IRQ_ENABLE_REGISTERS regs;
+ HTC_PACKET *pIOPacket = NULL;
+
+ LOCK_AR6K(pDev);
+
+ if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
+ pDev->GMboxInfo.CreditCountIRQEnabled = TRUE;
+ pDev->IrqEnableRegisters.counter_int_status_enable |=
+ COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
+ pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01);
+ } else {
+ pDev->GMboxInfo.CreditCountIRQEnabled = FALSE;
+ pDev->IrqEnableRegisters.counter_int_status_enable &=
+ ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER));
+ }
+ /* copy into our temp area */
+ A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+
+ UNLOCK_AR6K(pDev);
+
+ do {
+
+ if (AsyncMode) {
+
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* copy values to write to our async I/O buffer */
+ A_MEMCPY(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
+
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
+ pIOPacket->pContext = pDev;
+ pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
+ /* write it out asynchronously */
+ HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ pIOPacket->pBuffer,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_ASYNC_BYTE_INC,
+ pIOPacket);
+
+ pIOPacket = NULL;
+ break;
+ }
+
+ /* if we get here we are doing it synchronously */
+ status = HIFReadWrite(pDev->HIFDevice,
+ INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_enable,
+ AR6K_IRQ_ENABLE_REGS_SIZE,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
+ } else {
+ if (!AsyncMode) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ (" IRQAction Operation (%d) success \n", IrqAction));
+ }
+ }
+
+ if (pIOPacket != NULL) {
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ return status;
+}
+
+
+A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket = NULL;
+ A_UINT8 GMboxIntControl[4];
+
+ if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
+ return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode);
+ } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
+ return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
+ }
+
+ if (GMBOX_DISABLE_ALL == IrqAction) {
+ /* disable credit IRQ, those are on a different set of registers */
+ DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
+ }
+
+ /* take the lock to protect interrupt enable shadows */
+ LOCK_AR6K(pDev);
+
+ switch (IrqAction) {
+
+ case GMBOX_DISABLE_ALL:
+ pDev->GMboxControlRegisters.int_status_enable = 0;
+ break;
+ case GMBOX_ERRORS_IRQ_ENABLE:
+ pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW |
+ GMBOX_INT_STATUS_RX_OVERFLOW;
+ break;
+ case GMBOX_RECV_IRQ_ENABLE:
+ pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA;
+ break;
+ case GMBOX_RECV_IRQ_DISABLE:
+ pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA;
+ break;
+ case GMBOX_ACTION_NONE:
+ default:
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
+ GMboxIntControl[1] = GMboxIntControl[0];
+ GMboxIntControl[2] = GMboxIntControl[0];
+ GMboxIntControl[3] = GMboxIntControl[0];
+
+ UNLOCK_AR6K(pDev);
+
+ do {
+
+ if (AsyncMode) {
+
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* copy values to write to our async I/O buffer */
+ A_MEMCPY(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl));
+
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
+ pIOPacket->pContext = pDev;
+ pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
+ /* write it out asynchronously */
+ HIFReadWrite(pDev->HIFDevice,
+ GMBOX_INT_STATUS_ENABLE_REG,
+ pIOPacket->pBuffer,
+ sizeof(GMboxIntControl),
+ HIF_WR_ASYNC_BYTE_FIX,
+ pIOPacket);
+ pIOPacket = NULL;
+ break;
+ }
+
+ /* if we get here we are doing it synchronously */
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ GMBOX_INT_STATUS_ENABLE_REG,
+ GMboxIntControl,
+ sizeof(GMboxIntControl),
+ HIF_WR_SYNC_BYTE_FIX,
+ NULL);
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status));
+ } else {
+ if (!AsyncMode) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
+ (" IRQAction Operation (%d) success \n", IrqAction));
+ }
+ }
+
+ if (pIOPacket != NULL) {
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ return status;
+}
+
+void DevCleanupGMbox(AR6K_DEVICE *pDev)
+{
+ if (pDev->GMboxEnabled) {
+ pDev->GMboxEnabled = FALSE;
+ GMboxProtocolUninstall(pDev);
+ }
+}
+
+A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 muxControl[4];
+
+ do {
+
+ if (0 == pDev->MailBoxInfo.GMboxAddress) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n",
+ pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize));
+
+ status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* write to mailbox look ahead mux control register, we want the
+ * GMBOX lookaheads to appear on lookaheads 2 and 3
+ * the register is 1-byte wide so we need to hit it 4 times to align the operation
+ * to 4-bytes */
+ muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
+ muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
+ muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
+ muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ GMBOX_LOOKAHEAD_MUX_REG,
+ muxControl,
+ sizeof(muxControl),
+ HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */
+ NULL);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ status = GMboxProtocolInstall(pDev);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ pDev->GMboxEnabled = TRUE;
+
+ } while (FALSE);
+
+ return status;
+}
+
+A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 counter_int_status;
+ int credits;
+ A_UINT8 host_int_status2;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n"));
+
+ /* the caller guarantees that this is a context that allows for blocking I/O */
+
+ do {
+
+ host_int_status2 = pDev->IrqProcRegisters.host_int_status2 &
+ pDev->GMboxControlRegisters.int_status_enable;
+
+ if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n"));
+ status = A_ECOMM;
+ }
+
+ if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n"));
+ status = A_ECOMM;
+ }
+
+ if (A_FAILED(status)) {
+ if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
+ pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status);
+ }
+ break;
+ }
+
+ if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) {
+ if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) {
+ A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL);
+ status = pDev->GMboxInfo.pMessagePendingCallBack(
+ pDev->GMboxInfo.pProtocolContext,
+ (A_UINT8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0],
+ pDev->IrqProcRegisters.gmbox_rx_avail);
+ }
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ counter_int_status = pDev->IrqProcRegisters.counter_int_status &
+ pDev->IrqEnableRegisters.counter_int_status_enable;
+
+ /* check if credit interrupt is pending */
+ if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) {
+
+ /* do synchronous read */
+ status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL);
+ status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
+ credits,
+ pDev->GMboxInfo.CreditCountIRQEnabled);
+ }
+
+ } while (FALSE);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status));
+
+ return status;
+}
+
+
+A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength)
+{
+ A_UINT32 paddedLength;
+ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
+ A_STATUS status;
+ A_UINT32 address;
+
+ /* adjust the length to be a multiple of block size if appropriate */
+ paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
+ WriteLength,
+ pDev->MailBoxInfo.GMboxAddress,
+ sync ? "SYNC" : "ASYNC"));
+
+ /* last byte of packet has to hit the EOM marker */
+ address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength;
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ address,
+ pPacket->pBuffer,
+ paddedLength, /* the padded length */
+ sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
+ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
+
+ if (sync) {
+ pPacket->Status = status;
+ } else {
+ if (status == A_PENDING) {
+ status = A_OK;
+ }
+ }
+
+ return status;
+}
+
+A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength)
+{
+
+ A_UINT32 paddedLength;
+ A_STATUS status;
+ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
+
+ /* adjust the length to be a multiple of block size if appropriate */
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
+
+ if (paddedLength > pPacket->BufferLength) {
+ A_ASSERT(FALSE);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
+ paddedLength,ReadLength,pPacket->BufferLength));
+ if (pPacket->Completion != NULL) {
+ COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
+ return A_OK;
+ }
+ return A_EINVAL;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
+ (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
+ paddedLength,
+ pDev->MailBoxInfo.GMboxAddress,
+ sync ? "SYNC" : "ASYNC"));
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ pDev->MailBoxInfo.GMboxAddress,
+ pPacket->pBuffer,
+ paddedLength,
+ sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
+ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */
+
+ if (sync) {
+ pPacket->Status = status;
+ }
+
+ return status;
+}
+
+
+static int ProcessCreditCounterReadBuffer(A_UINT8 *pBuffer, int Length)
+{
+ int credits = 0;
+
+ /* theory of how this works:
+ * We read the credit decrement register multiple times on a byte-wide basis.
+ * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a
+ * reasonable chance to acquire "all" pending credits in a single I/O operation.
+ *
+ * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions.
+ * Each non-zero byte represents a single credit decrement (which is a credit given back to the host)
+ * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
+ * pattern "could" appear:
+ *
+ * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros
+ * <---------> <----------------------------->
+ * \_ credits aleady there \_ target adding 4 more credits
+ *
+ * The total available credits would be 7, since there are 7 non-zero bytes in the buffer.
+ *
+ * */
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer");
+ }
+
+ while (Length) {
+ if (*pBuffer != 0) {
+ credits++;
+ }
+ Length--;
+ pBuffer++;
+ }
+
+ return credits;
+}
+
+
+/* callback when our fetch to enable/disable completes */
+static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket)
+{
+ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Read Credit Operation failed! status:%d \n", pPacket->Status));
+ } else {
+ int credits = 0;
+ credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
+ pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext,
+ credits,
+ pDev->GMboxInfo.CreditCountIRQEnabled);
+
+
+ }
+ /* free this IO packet */
+ AR6KFreeIOPacket(pDev,pPacket);
+ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
+}
+
+A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pIOPacket = NULL;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
+
+ do {
+
+ pIOPacket = AR6KAllocIOPacket(pDev);
+
+ if (NULL == pIOPacket) {
+ status = A_NO_MEMORY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
+
+ if (AsyncMode) {
+ /* stick in our completion routine when the I/O operation completes */
+ pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
+ pIOPacket->pContext = pDev;
+ /* read registers asynchronously */
+ HIFReadWrite(pDev->HIFDevice,
+ AR6K_GMBOX_CREDIT_DEC_ADDRESS,
+ pIOPacket->pBuffer,
+ AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */
+ HIF_RD_ASYNC_BYTE_FIX,
+ pIOPacket);
+ pIOPacket = NULL;
+ break;
+ }
+
+ pIOPacket->Completion = NULL;
+ /* if we get here we are doing it synchronously */
+ status = HIFReadWrite(pDev->HIFDevice,
+ AR6K_GMBOX_CREDIT_DEC_ADDRESS,
+ pIOPacket->pBuffer,
+ AR6K_REG_IO_BUFFER_SIZE,
+ HIF_RD_SYNC_BYTE_FIX,
+ NULL);
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" DevGMboxReadCreditCounter failed! status:%d \n", status));
+ }
+
+ if (pIOPacket != NULL) {
+ if (A_SUCCESS(status)) {
+ /* sync mode processing */
+ *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);
+ }
+ AR6KFreeIOPacket(pDev,pIOPacket);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n",
+ AsyncMode ? "ASYNC" : "SYNC", status));
+
+ return status;
+}
+
+A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize)
+{
+ A_STATUS status;
+ A_UINT8 buffer[4];
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ AR6K_GMBOX_CREDIT_SIZE_ADDRESS,
+ buffer,
+ sizeof(buffer),
+ HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
+ NULL);
+
+ if (A_SUCCESS(status)) {
+ if (buffer[0] == 0) {
+ *pCreditSize = 256;
+ } else {
+ *pCreditSize = buffer[0];
+ }
+
+ }
+
+ return status;
+}
+
+void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev)
+{
+ /* Target ASSERTED!!! */
+ if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
+ pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);
+ }
+}
+
+A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes)
+{
+
+ A_STATUS status = A_OK;
+ AR6K_IRQ_PROC_REGISTERS procRegs;
+ int maxCopy;
+
+ do {
+ /* on entry the caller provides the length of the lookahead buffer */
+ if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
+ A_ASSERT(FALSE);
+ status = A_EINVAL;
+ break;
+ }
+
+ maxCopy = *pLookAheadBytes;
+ *pLookAheadBytes = 0;
+ /* load the register table from the device */
+ status = HIFReadWrite(pDev->HIFDevice,
+ HOST_INT_STATUS_ADDRESS,
+ (A_UINT8 *)&procRegs,
+ AR6K_IRQ_PROC_REGS_SIZE,
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
+ break;
+ }
+
+ if (procRegs.gmbox_rx_avail > 0) {
+ int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail;
+ A_MEMCPY(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
+ *pLookAheadBytes = bytes;
+ }
+
+ } while (FALSE);
+
+ return status;
+}
+
+A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS)
+{
+ A_STATUS status = A_OK;
+ int i;
+ A_UINT8 buffer[4];
+
+ A_MEMZERO(buffer, sizeof(buffer));
+
+ do {
+
+ if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
+ status = A_EINVAL;
+ break;
+ }
+
+ /* set the last buffer to do the actual signal trigger */
+ buffer[3] = (1 << Signal);
+
+ status = HIFReadWrite(pDev->HIFDevice,
+ INT_WLAN_ADDRESS,
+ buffer,
+ sizeof(buffer),
+ HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
+ NULL);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ } while (FALSE);
+
+
+ if (A_SUCCESS(status)) {
+ /* now read back the register to see if the bit cleared */
+ while (AckTimeoutMS) {
+ status = HIFReadWrite(pDev->HIFDevice,
+ INT_WLAN_ADDRESS,
+ buffer,
+ sizeof(buffer),
+ HIF_RD_SYNC_BYTE_FIX,
+ NULL);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ for (i = 0; i < sizeof(buffer); i++) {
+ if (buffer[i] & (1 << Signal)) {
+ /* bit is still set */
+ break;
+ }
+ }
+
+ if (i >= sizeof(buffer)) {
+ /* done */
+ break;
+ }
+
+ AckTimeoutMS--;
+ A_MDELAY(1);
+ }
+
+ if (0 == AckTimeoutMS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal));
+ status = A_ERROR;
+ }
+ }
+
+ return status;
+
+}
+
+#endif //ATH_AR6K_ENABLE_GMBOX
+
+
+
+
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
new file mode 100644
index 000000000000..db6d30c113b0
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
@@ -0,0 +1,1280 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6k_prot_hciUart.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Protocol module for use in bridging HCI-UART packets over the GMBOX interface
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "../htc_debug.h"
+#include "hif.h"
+#include "htc_packet.h"
+#include "ar6k.h"
+#include "hci_transport_api.h"
+#include "gmboxif.h"
+#include "ar6000_diag.h"
+#include "hw/apb_map.h"
+#include "hw/mbox_reg.h"
+
+#ifdef ATH_AR6K_ENABLE_GMBOX
+#define HCI_UART_COMMAND_PKT 0x01
+#define HCI_UART_ACL_PKT 0x02
+#define HCI_UART_SCO_PKT 0x03
+#define HCI_UART_EVENT_PKT 0x04
+
+#define HCI_RECV_WAIT_BUFFERS (1 << 0)
+
+#define HCI_SEND_WAIT_CREDITS (1 << 0)
+
+#define HCI_UART_BRIDGE_CREDIT_SIZE 128
+
+#define CREDIT_POLL_COUNT 256
+
+#define HCI_DELAY_PER_INTERVAL_MS 10
+#define BTON_TIMEOUT_MS 500
+#define BTOFF_TIMEOUT_MS 500
+#define BAUD_TIMEOUT_MS 1
+#define BTPWRSAV_TIMEOUT_MS 1
+
+typedef struct {
+ HCI_TRANSPORT_CONFIG_INFO HCIConfig;
+ A_BOOL HCIAttached;
+ A_BOOL HCIStopped;
+ A_UINT32 RecvStateFlags;
+ A_UINT32 SendStateFlags;
+ HCI_TRANSPORT_PACKET_TYPE WaitBufferType;
+ HTC_PACKET_QUEUE SendQueue; /* write queue holding HCI Command and ACL packets */
+ HTC_PACKET_QUEUE HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */
+ HTC_PACKET_QUEUE HCIEventBuffers; /* recv queue holding buffers for incomming event packets */
+ AR6K_DEVICE *pDev;
+ A_MUTEX_T HCIRxLock;
+ A_MUTEX_T HCITxLock;
+ int CreditsMax;
+ int CreditsConsumed;
+ int CreditsAvailable;
+ int CreditSize;
+ int CreditsCurrentSeek;
+ int SendProcessCount;
+} GMBOX_PROTO_HCI_UART;
+
+#define LOCK_HCI_RX(t) A_MUTEX_LOCK(&(t)->HCIRxLock);
+#define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock);
+#define LOCK_HCI_TX(t) A_MUTEX_LOCK(&(t)->HCITxLock);
+#define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock);
+
+#define DO_HCI_RECV_INDICATION(p,pt) \
+{ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \
+ (unsigned long)(pt),(pt)->Status, A_SUCCESS((pt)->Status) ? (pt)->ActualLength : 0, HCI_GET_PACKET_TYPE(pt))); \
+ (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \
+}
+
+#define DO_HCI_SEND_INDICATION(p,pt) \
+{ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n", \
+ (unsigned long)(pt),(pt)->Status,HCI_GET_PACKET_TYPE(pt))); \
+ (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \
+}
+
+static A_STATUS HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous);
+
+static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol)
+{
+ A_ASSERT(pProtocol != NULL);
+
+ A_MUTEX_DELETE(&pProtocol->HCIRxLock);
+ A_MUTEX_DELETE(&pProtocol->HCITxLock);
+
+ A_FREE(pProtocol);
+}
+
+static A_STATUS InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt)
+{
+ A_STATUS status;
+ int credits;
+ int creditPollCount = CREDIT_POLL_COUNT;
+ A_BOOL gotCredits = FALSE;
+
+ pProt->CreditsConsumed = 0;
+
+ do {
+
+ if (pProt->CreditsMax != 0) {
+ /* we can only call this only once per target reset */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called! \n"));
+ A_ASSERT(FALSE);
+ status = A_EINVAL;
+ break;
+ }
+
+ /* read the credit counter. At startup the target will set the credit counter
+ * to the max available, we read this in a loop because it may take
+ * multiple credit counter reads to get all credits */
+
+ while (creditPollCount) {
+
+ credits = 0;
+
+ status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (!gotCredits && (0 == credits)) {
+ creditPollCount--;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: credit is 0, retrying (%d) \n",creditPollCount));
+ A_MDELAY(HCI_DELAY_PER_INTERVAL_MS);
+ continue;
+ } else {
+ gotCredits = TRUE;
+ }
+
+ if (0 == credits) {
+ break;
+ }
+
+ pProt->CreditsMax += credits;
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (0 == creditPollCount) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("** HCI : Failed to get credits! GMBOX Target was not available \n"));
+ status = A_ERROR;
+ break;
+ }
+
+ /* now get the size */
+ status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ } while (FALSE);
+
+ if (A_SUCCESS(status)) {
+ pProt->CreditsAvailable = pProt->CreditsMax;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n",
+ pProt->CreditsAvailable, pProt->CreditSize));
+ }
+
+ return status;
+}
+
+static A_STATUS CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIRQEnabled)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext;
+ A_BOOL enableCreditIrq = FALSE;
+ A_BOOL disableCreditIrq = FALSE;
+ A_BOOL doPendingSends = FALSE;
+ A_STATUS status = A_OK;
+
+ /** this callback is called under 2 conditions:
+ * 1. The credit IRQ interrupt was enabled and signaled.
+ * 2. A credit counter read completed.
+ *
+ * The function must not assume that the calling context can block !
+ */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback (Credits:%d, IRQ:%s) \n",
+ Credits, CreditIRQEnabled ? "ON" : "OFF"));
+
+ LOCK_HCI_TX(pProt);
+
+ do {
+
+ if (0 == Credits) {
+ if (!CreditIRQEnabled) {
+ /* enable credit IRQ */
+ enableCreditIrq = TRUE;
+ }
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: current credit state, consumed:%d available:%d max:%d seek:%d\n",
+ pProt->CreditsConsumed,
+ pProt->CreditsAvailable,
+ pProt->CreditsMax,
+ pProt->CreditsCurrentSeek));
+
+ pProt->CreditsAvailable += Credits;
+ A_ASSERT(pProt->CreditsAvailable <= pProt->CreditsMax);
+ pProt->CreditsConsumed -= Credits;
+ A_ASSERT(pProt->CreditsConsumed >= 0);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state, consumed:%d available:%d max:%d seek:%d\n",
+ pProt->CreditsConsumed,
+ pProt->CreditsAvailable,
+ pProt->CreditsMax,
+ pProt->CreditsCurrentSeek));
+
+ if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
+ /* we have enough credits to fullfill at least 1 packet waiting in the queue */
+ pProt->CreditsCurrentSeek = 0;
+ pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS;
+ doPendingSends = TRUE;
+ if (CreditIRQEnabled) {
+ /* credit IRQ was enabled, we shouldn't need it anymore */
+ disableCreditIrq = TRUE;
+ }
+ } else {
+ /* not enough credits yet, enable credit IRQ if we haven't already */
+ if (!CreditIRQEnabled) {
+ enableCreditIrq = TRUE;
+ }
+ }
+
+ } while (FALSE);
+
+ UNLOCK_HCI_TX(pProt);
+
+ if (enableCreditIrq) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Enabling credit count IRQ...\n"));
+ /* must use async only */
+ status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_ENABLE, PROC_IO_ASYNC);
+ } else if (disableCreditIrq) {
+ /* must use async only */
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Disabling credit count IRQ...\n"));
+ status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_DISABLE, PROC_IO_ASYNC);
+ }
+
+ if (doPendingSends) {
+ HCITrySend(pProt, NULL, FALSE);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n"));
+ return status;
+}
+
+static INLINE void NotifyTransportFailure(GMBOX_PROTO_HCI_UART *pProt, A_STATUS status)
+{
+ if (pProt->HCIConfig.TransportFailure != NULL) {
+ pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status);
+ }
+}
+
+static void FailureCallback(void *pContext, A_STATUS Status)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext;
+
+ /* target assertion occured */
+ NotifyTransportFailure(pProt, Status);
+}
+
+static void StateDumpCallback(void *pContext)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags : 0x%X \n",pProt->RecvStateFlags));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendStateFlags : 0x%X \n",pProt->SendStateFlags));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("WaitBufferType : %d \n",pProt->WaitBufferType));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendQueue Depth : %d \n",HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsMax : %d \n",pProt->CreditsMax));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsConsumed : %d \n",pProt->CreditsConsumed));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsAvailable : %d \n",pProt->CreditsAvailable));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n"));
+}
+
+static A_STATUS HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext;
+ A_STATUS status = A_OK;
+ int totalRecvLength = 0;
+ HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID;
+ A_BOOL recvRefillCalled = FALSE;
+ A_BOOL blockRecv = FALSE;
+ HTC_PACKET *pPacket = NULL;
+
+ /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCIUartMessagePending Lookahead Bytes:%d \n",ValidBytes));
+
+ LOCK_HCI_RX(pProt);
+
+ do {
+
+ if (ValidBytes < 3) {
+ /* not enough for ACL or event header */
+ break;
+ }
+
+ if ((LookAheadBytes[0] == HCI_UART_ACL_PKT) && (ValidBytes < 5)) {
+ /* not enough for ACL data header */
+ break;
+ }
+
+ switch (LookAheadBytes[0]) {
+ case HCI_UART_EVENT_PKT:
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
+ LookAheadBytes[1], LookAheadBytes[2]));
+ totalRecvLength = LookAheadBytes[2];
+ totalRecvLength += 3; /* add type + event code + length field */
+ pktType = HCI_EVENT_TYPE;
+ break;
+ case HCI_UART_ACL_PKT:
+ totalRecvLength = (LookAheadBytes[4] << 8) | LookAheadBytes[3];
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI ACL: conn:0x%X length: %d \n",
+ ((LookAheadBytes[2] & 0xF0) << 8) | LookAheadBytes[1], totalRecvLength));
+ totalRecvLength += 5; /* add type + connection handle + length field */
+ pktType = HCI_ACL_TYPE;
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",LookAheadBytes[0]));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pProt->HCIConfig.pHCIPktRecvAlloc != NULL) {
+ UNLOCK_HCI_RX(pProt);
+ /* user is using a per-packet allocation callback */
+ pPacket = pProt->HCIConfig.pHCIPktRecvAlloc(pProt->HCIConfig.pContext,
+ pktType,
+ totalRecvLength);
+ LOCK_HCI_RX(pProt);
+
+ } else {
+ HTC_PACKET_QUEUE *pQueue;
+ /* user is using a refill handler that can refill multiple HTC buffers */
+
+ /* select buffer queue */
+ if (pktType == HCI_ACL_TYPE) {
+ pQueue = &pProt->HCIACLRecvBuffers;
+ } else {
+ pQueue = &pProt->HCIEventBuffers;
+ }
+
+ if (HTC_QUEUE_EMPTY(pQueue)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("** HCI pkt type: %d has no buffers available calling allocation handler \n",
+ pktType));
+ /* check for refill handler */
+ if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) {
+ recvRefillCalled = TRUE;
+ UNLOCK_HCI_RX(pProt);
+ /* call the re-fill handler */
+ pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
+ pktType,
+ 0);
+ LOCK_HCI_RX(pProt);
+ /* check if we have more buffers */
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ /* fall through */
+ }
+ } else {
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("HCI pkt type: %d now has %d recv buffers left \n",
+ pktType, HTC_PACKET_QUEUE_DEPTH(pQueue)));
+ }
+ }
+
+ if (NULL == pPacket) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("** HCI pkt type: %d has no buffers available stopping recv...\n", pktType));
+ /* this is not an error, we simply need to mark that we are waiting for buffers.*/
+ pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS;
+ pProt->WaitBufferType = pktType;
+ blockRecv = TRUE;
+ break;
+ }
+
+ if (totalRecvLength > (int)pPacket->BufferLength) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI-UART pkt: %d requires %d bytes (%d buffer bytes avail) ! \n",
+ LookAheadBytes[0], totalRecvLength, pPacket->BufferLength));
+ status = A_EINVAL;
+ break;
+ }
+
+ } while (FALSE);
+
+ UNLOCK_HCI_RX(pProt);
+
+ /* locks are released, we can go fetch the packet */
+
+ do {
+
+ if (A_FAILED(status) || (NULL == pPacket)) {
+ break;
+ }
+
+ /* do this synchronously, we don't need to be fast here */
+ pPacket->Completion = NULL;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI : getting recv packet len:%d hci-uart-type: %s \n",
+ totalRecvLength, (LookAheadBytes[0] == HCI_UART_EVENT_PKT) ? "EVENT" : "ACL"));
+
+ status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pPacket->pBuffer[0] != LookAheadBytes[0]) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not contain expected packet type: %d ! \n",
+ pPacket->pBuffer[0]));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pPacket->pBuffer[0] == HCI_UART_EVENT_PKT) {
+ /* validate event header fields */
+ if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
+ (pPacket->pBuffer[2] != LookAheadBytes[2])) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
+ DebugDumpBytes(LookAheadBytes, 3, "Expected HCI-UART Header");
+ DebugDumpBytes(pPacket->pBuffer, 3, "** Bad HCI-UART Header");
+ status = A_EPROTO;
+ break;
+ }
+ } else if (pPacket->pBuffer[0] == HCI_UART_ACL_PKT) {
+ /* validate acl header fields */
+ if ((pPacket->pBuffer[1] != LookAheadBytes[1]) ||
+ (pPacket->pBuffer[2] != LookAheadBytes[2]) ||
+ (pPacket->pBuffer[3] != LookAheadBytes[3]) ||
+ (pPacket->pBuffer[4] != LookAheadBytes[4])) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n"));
+ DebugDumpBytes(LookAheadBytes, 5, "Expected HCI-UART Header");
+ DebugDumpBytes(pPacket->pBuffer, 5, "** Bad HCI-UART Header");
+ status = A_EPROTO;
+ break;
+ }
+ }
+
+ /* adjust buffer to move past packet ID */
+ pPacket->pBuffer++;
+ pPacket->ActualLength = totalRecvLength - 1;
+ pPacket->Status = A_OK;
+ /* indicate packet */
+ DO_HCI_RECV_INDICATION(pProt,pPacket);
+ pPacket = NULL;
+
+ /* check if we need to refill recv buffers */
+ if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) {
+ HTC_PACKET_QUEUE *pQueue;
+ int watermark;
+
+ if (pktType == HCI_ACL_TYPE) {
+ watermark = pProt->HCIConfig.ACLRecvBufferWaterMark;
+ pQueue = &pProt->HCIACLRecvBuffers;
+ } else {
+ watermark = pProt->HCIConfig.EventRecvBufferWaterMark;
+ pQueue = &pProt->HCIEventBuffers;
+ }
+
+ if (HTC_PACKET_QUEUE_DEPTH(pQueue) < watermark) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("** HCI pkt type: %d watermark hit (%d) current:%d \n",
+ pktType, watermark, HTC_PACKET_QUEUE_DEPTH(pQueue)));
+ /* call the re-fill handler */
+ pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext,
+ pktType,
+ HTC_PACKET_QUEUE_DEPTH(pQueue));
+ }
+ }
+
+ } while (FALSE);
+
+ /* check if we need to disable the reciever */
+ if (A_FAILED(status) || blockRecv) {
+ DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC);
+ }
+
+ /* see if we need to recycle the recv buffer */
+ if (A_FAILED(status) && (pPacket != NULL)) {
+ HTC_PACKET_QUEUE queue;
+
+ if (A_EPROTO == status) {
+ DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet");
+ }
+ /* recycle packet */
+ HTC_PACKET_RESET_RX(pPacket);
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
+ HCI_TransportAddReceivePkts(pProt,&queue);
+ NotifyTransportFailure(pProt,status);
+ }
+
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCIUartMessagePending \n"));
+
+ return status;
+}
+
+static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)Context;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket));
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n",
+ (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength));
+ }
+
+ DO_HCI_SEND_INDICATION(pProt,pPacket);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n"));
+}
+
+static A_STATUS SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt)
+{
+ A_STATUS status = A_OK;
+ int credits;
+ int retry = 100;
+
+ while (TRUE) {
+ credits = 0;
+ status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits);
+ if (A_FAILED(status)) {
+ break;
+ }
+ LOCK_HCI_TX(pProt);
+ pProt->CreditsAvailable += credits;
+ pProt->CreditsConsumed -= credits;
+ if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) {
+ pProt->CreditsCurrentSeek = 0;
+ UNLOCK_HCI_TX(pProt);
+ break;
+ }
+ UNLOCK_HCI_TX(pProt);
+ retry--;
+ if (0 == retry) {
+ status = A_EBUSY;
+ break;
+ }
+ A_MDELAY(20);
+ }
+
+ return status;
+}
+
+static A_STATUS HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous)
+{
+ A_STATUS status = A_OK;
+ int transferLength;
+ int creditsRequired, remainder;
+ A_UINT8 hciUartType;
+ A_BOOL synchSendComplete = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket,
+ Synchronous ? "SYNC" :"ASYNC"));
+
+ LOCK_HCI_TX(pProt);
+
+ /* increment write processing count on entry */
+ pProt->SendProcessCount++;
+
+ do {
+
+ if (pProt->HCIStopped) {
+ status = A_ECANCELED;
+ break;
+ }
+
+ if (pPacket != NULL) {
+ /* packet was supplied */
+ if (Synchronous) {
+ /* in synchronous mode, the send queue can only hold 1 packet */
+ if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
+ status = A_EBUSY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ if (pProt->SendProcessCount > 1) {
+ /* another thread or task is draining the TX queues */
+ status = A_EBUSY;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
+
+ } else {
+ /* see if adding this packet hits the max depth (asynchronous mode only) */
+ if ((pProt->HCIConfig.MaxSendQueueDepth > 0) &&
+ ((HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue) + 1) >= pProt->HCIConfig.MaxSendQueueDepth)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("HCI Send queue is full, Depth:%d, Max:%d \n",
+ HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue),
+ pProt->HCIConfig.MaxSendQueueDepth));
+ /* queue will be full, invoke any callbacks to determine what action to take */
+ if (pProt->HCIConfig.pHCISendFull != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ ("HCI : Calling driver's send full callback.... \n"));
+ if (pProt->HCIConfig.pHCISendFull(pProt->HCIConfig.pContext,
+ pPacket) == HCI_SEND_FULL_DROP) {
+ /* drop it */
+ status = A_NO_RESOURCE;
+ break;
+ }
+ }
+ }
+
+ HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket);
+ }
+
+ }
+
+ if (pProt->SendStateFlags & HCI_SEND_WAIT_CREDITS) {
+ break;
+ }
+
+ if (pProt->SendProcessCount > 1) {
+ /* another thread or task is draining the TX queues */
+ break;
+ }
+
+ /***** beyond this point only 1 thread may enter ******/
+
+ /* now drain the send queue for transmission as long as we have enough
+ * credits */
+ while (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
+
+ pPacket = HTC_PACKET_DEQUEUE(&pProt->SendQueue);
+
+ switch (HCI_GET_PACKET_TYPE(pPacket)) {
+ case HCI_COMMAND_TYPE:
+ hciUartType = HCI_UART_COMMAND_PKT;
+ break;
+ case HCI_ACL_TYPE:
+ hciUartType = HCI_UART_ACL_PKT;
+ break;
+ default:
+ status = A_EINVAL;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Got head packet:0x%lX , Type:%d Length: %d Remaining Queue Depth: %d\n",
+ (unsigned long)pPacket, HCI_GET_PACKET_TYPE(pPacket), pPacket->ActualLength,
+ HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue)));
+
+ transferLength = 1; /* UART type header is 1 byte */
+ transferLength += pPacket->ActualLength;
+ transferLength = DEV_CALC_SEND_PADDED_LEN(pProt->pDev, transferLength);
+
+ /* figure out how many credits this message requires */
+ creditsRequired = transferLength / pProt->CreditSize;
+ remainder = transferLength % pProt->CreditSize;
+
+ if (remainder) {
+ creditsRequired++;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Creds Required:%d Got:%d\n",
+ creditsRequired, pProt->CreditsAvailable));
+
+ if (creditsRequired > pProt->CreditsAvailable) {
+ if (Synchronous) {
+ /* in synchronous mode we need to seek credits in synchronously */
+ pProt->CreditsCurrentSeek = creditsRequired;
+ UNLOCK_HCI_TX(pProt);
+ status = SeekCreditsSynch(pProt);
+ LOCK_HCI_TX(pProt);
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* fall through and continue processing this send op */
+ } else {
+ /* not enough credits, queue back to the head */
+ HTC_PACKET_ENQUEUE_TO_HEAD(&pProt->SendQueue,pPacket);
+ /* waiting for credits */
+ pProt->SendStateFlags |= HCI_SEND_WAIT_CREDITS;
+ /* provide a hint to reduce attempts to re-send if credits are dribbling back
+ * this hint is the short fall of credits */
+ pProt->CreditsCurrentSeek = creditsRequired;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: packet:0x%lX placed back in queue. head packet needs: %d credits \n",
+ (unsigned long)pPacket, pProt->CreditsCurrentSeek));
+ pPacket = NULL;
+ UNLOCK_HCI_TX(pProt);
+
+ /* schedule a credit counter read, our CreditsAvailableCallback callback will be called
+ * with the result */
+ DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_ASYNC, NULL);
+
+ LOCK_HCI_TX(pProt);
+ break;
+ }
+ }
+
+ /* caller guarantees some head room */
+ pPacket->pBuffer--;
+ pPacket->pBuffer[0] = hciUartType;
+
+ pProt->CreditsAvailable -= creditsRequired;
+ pProt->CreditsConsumed += creditsRequired;
+ A_ASSERT(pProt->CreditsConsumed <= pProt->CreditsMax);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state: consumed:%d available:%d max:%d\n",
+ pProt->CreditsConsumed, pProt->CreditsAvailable, pProt->CreditsMax));
+
+ UNLOCK_HCI_TX(pProt);
+
+ /* write it out */
+ if (Synchronous) {
+ pPacket->Completion = NULL;
+ pPacket->pContext = NULL;
+ } else {
+ pPacket->Completion = HCISendPacketCompletion;
+ pPacket->pContext = pProt;
+ }
+
+ status = DevGMboxWrite(pProt->pDev,pPacket,transferLength);
+ if (Synchronous) {
+ synchSendComplete = TRUE;
+ } else {
+ pPacket = NULL;
+ }
+
+ LOCK_HCI_TX(pProt);
+
+ }
+
+ } while (FALSE);
+
+ pProt->SendProcessCount--;
+ A_ASSERT(pProt->SendProcessCount >= 0);
+ UNLOCK_HCI_TX(pProt);
+
+ if (Synchronous) {
+ A_ASSERT(pPacket != NULL);
+ if (A_SUCCESS(status) && (!synchSendComplete)) {
+ status = A_EBUSY;
+ A_ASSERT(FALSE);
+ LOCK_HCI_TX(pProt);
+ if (pPacket->ListLink.pNext != NULL) {
+ /* remove from the queue */
+ HTC_PACKET_REMOVE(&pProt->SendQueue,pPacket);
+ }
+ UNLOCK_HCI_TX(pProt);
+ }
+ } else {
+ if (A_FAILED(status) && (pPacket != NULL)) {
+ pPacket->Status = status;
+ DO_HCI_SEND_INDICATION(pProt,pPacket);
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HCITrySend: \n"));
+ return status;
+}
+
+static void FlushSendQueue(GMBOX_PROTO_HCI_UART *pProt)
+{
+ HTC_PACKET *pPacket;
+ HTC_PACKET_QUEUE discardQueue;
+
+ INIT_HTC_PACKET_QUEUE(&discardQueue);
+
+ LOCK_HCI_TX(pProt);
+
+ if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) {
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->SendQueue);
+ }
+
+ UNLOCK_HCI_TX(pProt);
+
+ /* discard packets */
+ while (!HTC_QUEUE_EMPTY(&discardQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
+ pPacket->Status = A_ECANCELED;
+ DO_HCI_SEND_INDICATION(pProt,pPacket);
+ }
+
+}
+
+static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt)
+{
+ HTC_PACKET_QUEUE discardQueue;
+ HTC_PACKET *pPacket;
+
+ INIT_HTC_PACKET_QUEUE(&discardQueue);
+
+ LOCK_HCI_RX(pProt);
+ /*transfer list items from ACL and event buffer queues to the discard queue */
+ if (!HTC_QUEUE_EMPTY(&pProt->HCIACLRecvBuffers)) {
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIACLRecvBuffers);
+ }
+ if (!HTC_QUEUE_EMPTY(&pProt->HCIEventBuffers)) {
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIEventBuffers);
+ }
+ UNLOCK_HCI_RX(pProt);
+
+ /* now empty the discard queue */
+ while (!HTC_QUEUE_EMPTY(&discardQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
+ pPacket->Status = A_ECANCELED;
+ DO_HCI_RECV_INDICATION(pProt,pPacket);
+ }
+
+}
+
+/*** protocol module install entry point ***/
+
+A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev)
+{
+ A_STATUS status = A_OK;
+ GMBOX_PROTO_HCI_UART *pProtocol = NULL;
+
+ do {
+
+ pProtocol = A_MALLOC(sizeof(GMBOX_PROTO_HCI_UART));
+
+ if (NULL == pProtocol) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_MEMZERO(pProtocol, sizeof(*pProtocol));
+ pProtocol->pDev = pDev;
+ INIT_HTC_PACKET_QUEUE(&pProtocol->SendQueue);
+ INIT_HTC_PACKET_QUEUE(&pProtocol->HCIACLRecvBuffers);
+ INIT_HTC_PACKET_QUEUE(&pProtocol->HCIEventBuffers);
+ A_MUTEX_INIT(&pProtocol->HCIRxLock);
+ A_MUTEX_INIT(&pProtocol->HCITxLock);
+
+ } while (FALSE);
+
+ if (A_SUCCESS(status)) {
+ LOCK_AR6K(pDev);
+ DEV_GMBOX_SET_PROTOCOL(pDev,
+ HCIUartMessagePending,
+ CreditsAvailableCallback,
+ FailureCallback,
+ StateDumpCallback,
+ pProtocol);
+ UNLOCK_AR6K(pDev);
+ } else {
+ if (pProtocol != NULL) {
+ HCIUartCleanup(pProtocol);
+ }
+ }
+
+ return status;
+}
+
+/*** protocol module uninstall entry point ***/
+void GMboxProtocolUninstall(AR6K_DEVICE *pDev)
+{
+ GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)DEV_GMBOX_GET_PROTOCOL(pDev);
+
+ if (pProtocol != NULL) {
+
+ /* notify anyone attached */
+ if (pProtocol->HCIAttached) {
+ A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL);
+ pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext);
+ pProtocol->HCIAttached = FALSE;
+ }
+
+ HCIUartCleanup(pProtocol);
+ DEV_GMBOX_SET_PROTOCOL(pDev,NULL,NULL,NULL,NULL,NULL);
+ }
+
+}
+
+static A_STATUS NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt)
+{
+ HCI_TRANSPORT_PROPERTIES props;
+ A_STATUS status = A_OK;
+
+ do {
+
+ A_MEMZERO(&props,sizeof(props));
+
+ /* HCI UART only needs one extra byte at the head to indicate the packet TYPE */
+ props.HeadRoom = 1;
+ props.TailRoom = 0;
+ props.IOBlockPad = pProt->pDev->BlockSize;
+ if (pProt->HCIAttached) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI: notifying attached client to transport... \n"));
+ A_ASSERT(pProt->HCIConfig.TransportReady != NULL);
+ status = pProt->HCIConfig.TransportReady(pProt,
+ &props,
+ pProt->HCIConfig.pContext);
+ }
+
+ } while (FALSE);
+
+ return status;
+}
+
+/*********** HCI UART protocol implementation ************************************************/
+
+HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo)
+{
+ GMBOX_PROTO_HCI_UART *pProtocol = NULL;
+ AR6K_DEVICE *pDev;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n"));
+
+ pDev = HTCGetAR6KDevice(HTCHandle);
+
+ LOCK_AR6K(pDev);
+
+ do {
+
+ pProtocol = (GMBOX_PROTO_HCI_UART *)DEV_GMBOX_GET_PROTOCOL(pDev);
+
+ if (NULL == pProtocol) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n"));
+ break;
+ }
+
+ if (pProtocol->HCIAttached) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol already attached! \n"));
+ break;
+ }
+
+ A_MEMCPY(&pProtocol->HCIConfig, pInfo, sizeof(HCI_TRANSPORT_CONFIG_INFO));
+
+ A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL);
+ A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL);
+
+ pProtocol->HCIAttached = TRUE;
+
+ } while (FALSE);
+
+ UNLOCK_AR6K(pDev);
+
+ if (pProtocol != NULL) {
+ /* TODO ... should we use a worker? */
+ NotifyTransportReady(pProtocol);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach (0x%lX) \n",(unsigned long)pProtocol));
+ return (HCI_TRANSPORT_HANDLE)pProtocol;
+}
+
+void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans)
+{
+ GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)HciTrans;
+ AR6K_DEVICE *pDev = pProtocol->pDev;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n"));
+
+ LOCK_AR6K(pDev);
+ if (!pProtocol->HCIAttached) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not attached! \n"));
+ UNLOCK_AR6K(pDev);
+ return;
+ }
+ pProtocol->HCIAttached = FALSE;
+ UNLOCK_AR6K(pDev);
+
+ HCI_TransportStop(HciTrans);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n"));
+}
+
+A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+ A_STATUS status = A_OK;
+ A_BOOL unblockRecv = FALSE;
+ HTC_PACKET *pPacket;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n"));
+
+ LOCK_HCI_RX(pProt);
+
+ do {
+
+ if (pProt->HCIStopped) {
+ status = A_ECANCELED;
+ break;
+ }
+
+ pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
+
+ if (NULL == pPacket) {
+ status = A_EINVAL;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv packet added, type :%d, len:%d num:%d \n",
+ HCI_GET_PACKET_TYPE(pPacket), pPacket->BufferLength, HTC_PACKET_QUEUE_DEPTH(pQueue)));
+
+ if (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) {
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIEventBuffers, pQueue);
+ } else if (HCI_GET_PACKET_TYPE(pPacket) == HCI_ACL_TYPE) {
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIACLRecvBuffers, pQueue);
+ } else {
+ status = A_EINVAL;
+ break;
+ }
+
+ if (pProt->RecvStateFlags & HCI_RECV_WAIT_BUFFERS) {
+ if (pProt->WaitBufferType == HCI_GET_PACKET_TYPE(pPacket)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv was blocked on packet type :%d, unblocking.. \n",
+ pProt->WaitBufferType));
+ pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS;
+ pProt->WaitBufferType = HCI_PACKET_INVALID;
+ unblockRecv = TRUE;
+ }
+ }
+
+ } while (FALSE);
+
+ UNLOCK_HCI_RX(pProt);
+
+ if (A_FAILED(status)) {
+ while (!HTC_QUEUE_EMPTY(pQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ pPacket->Status = A_ECANCELED;
+ DO_HCI_RECV_INDICATION(pProt,pPacket);
+ }
+ }
+
+ if (unblockRecv) {
+ DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_ASYNC);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n"));
+
+ return A_OK;
+}
+
+A_STATUS HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+
+ return HCITrySend(pProt,pPacket,Synchronous);
+}
+
+void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n"));
+
+ LOCK_AR6K(pProt->pDev);
+ if (pProt->HCIStopped) {
+ UNLOCK_AR6K(pProt->pDev);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
+ return;
+ }
+ pProt->HCIStopped = TRUE;
+ UNLOCK_AR6K(pProt->pDev);
+
+ /* disable interrupts */
+ DevGMboxIRQAction(pProt->pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
+ FlushSendQueue(pProt);
+ FlushRecvBuffers(pProt);
+
+ /* signal bridge side to power down BT */
+ DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_OFF, BTOFF_TIMEOUT_MS);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n"));
+}
+
+A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans)
+{
+ A_STATUS status;
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n"));
+
+ /* set stopped in case we have a problem in starting */
+ pProt->HCIStopped = TRUE;
+
+ do {
+
+ status = InitTxCreditState(pProt);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* enable recv */
+ status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* signal bridge side to power up BT */
+ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n"));
+ break;
+ }
+
+ /* we made it */
+ pProt->HCIStopped = FALSE;
+
+ } while (FALSE);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n"));
+
+ return status;
+}
+
+A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+ return DevGMboxIRQAction(pProt->pDev,
+ Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE,
+ PROC_IO_SYNC);
+
+}
+
+A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
+ HTC_PACKET *pPacket,
+ int MaxPollMS)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+ A_STATUS status = A_OK;
+ A_UINT8 lookAhead[8];
+ int bytes;
+ int totalRecvLength;
+
+ MaxPollMS = MaxPollMS / 16;
+
+ if (MaxPollMS < 2) {
+ MaxPollMS = 2;
+ }
+
+ while (MaxPollMS) {
+
+ bytes = sizeof(lookAhead);
+ status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (bytes < 3) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI recv poll got bytes: %d, retry : %d \n",
+ bytes, MaxPollMS));
+ A_MDELAY(16);
+ MaxPollMS--;
+ continue;
+ }
+
+ totalRecvLength = 0;
+ switch (lookAhead[0]) {
+ case HCI_UART_EVENT_PKT:
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n",
+ lookAhead[1], lookAhead[2]));
+ totalRecvLength = lookAhead[2];
+ totalRecvLength += 3; /* add type + event code + length field */
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",lookAhead[0]));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ pPacket->Completion = NULL;
+ status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ pPacket->pBuffer++;
+ pPacket->ActualLength = totalRecvLength - 1;
+ pPacket->Status = A_OK;
+ break;
+ }
+
+ if (MaxPollMS == 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI recv poll timeout! \n"));
+ status = A_ERROR;
+ }
+
+ return status;
+}
+
+#define LSB_SCRATCH_IDX 4
+#define MSB_SCRATCH_IDX 5
+A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud)
+{
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+ HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice);
+ A_UINT32 scaledBaud, scratchAddr;
+ A_STATUS status = A_OK;
+
+ /* Divide the desired baud rate by 100
+ * Store the LSB in the local scratch register 4 and the MSB in the local
+ * scratch register 5 for the target to read
+ */
+ scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * LSB_SCRATCH_IDX);
+ scaledBaud = (Baud / 100) & LOCAL_SCRATCH_VALUE_MASK;
+ status = ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
+ scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX);
+ scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK;
+ status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud);
+ if (A_OK != status) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!"));
+ return status;
+ }
+
+ /* Now interrupt the target to tell it about the baud rate */
+ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS);
+ if (A_OK != status) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!"));
+ }
+
+ return status;
+}
+
+A_STATUS HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable)
+{
+ A_STATUS status;
+ GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans;
+
+ if (Enable) {
+ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS);
+ } else {
+ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS);
+ }
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n"));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n"));
+ }
+
+ return status;
+}
+
+#endif //ATH_AR6K_ENABLE_GMBOX
+
diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c
new file mode 100644
index 000000000000..7df62a20d482
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc.c
@@ -0,0 +1,579 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#include "htc_internal.h"
+
+#ifdef ATH_DEBUG_MODULE
+static ATH_DEBUG_MASK_DESCRIPTION g_HTCDebugDescription[] = {
+ { ATH_DEBUG_SEND , "Send"},
+ { ATH_DEBUG_RECV , "Recv"},
+ { ATH_DEBUG_SYNC , "Sync"},
+ { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"},
+ { ATH_DEBUG_IRQ , "Interrupt Processing"}
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc,
+ "htc",
+ "Host Target Communications",
+ ATH_DEBUG_MASK_DEFAULTS,
+ ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription),
+ g_HTCDebugDescription);
+
+#endif
+
+static void HTCReportFailure(void *Context);
+static void ResetEndpointStates(HTC_TARGET *target);
+
+void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList)
+{
+ LOCK_HTC(target);
+ HTC_PACKET_ENQUEUE(pList,pPacket);
+ UNLOCK_HTC(target);
+}
+
+HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList)
+{
+ HTC_PACKET *pPacket;
+
+ LOCK_HTC(target);
+ pPacket = HTC_PACKET_DEQUEUE(pList);
+ UNLOCK_HTC(target);
+
+ return pPacket;
+}
+
+/* cleanup the HTC instance */
+static void HTCCleanup(HTC_TARGET *target)
+{
+ A_INT32 i;
+
+ DevCleanup(&target->Device);
+
+ for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
+ if (target->HTCControlBuffers[i].Buffer) {
+ A_FREE(target->HTCControlBuffers[i].Buffer);
+ }
+ }
+
+ if (A_IS_MUTEX_VALID(&target->HTCLock)) {
+ A_MUTEX_DELETE(&target->HTCLock);
+ }
+
+ if (A_IS_MUTEX_VALID(&target->HTCRxLock)) {
+ A_MUTEX_DELETE(&target->HTCRxLock);
+ }
+
+ if (A_IS_MUTEX_VALID(&target->HTCTxLock)) {
+ A_MUTEX_DELETE(&target->HTCTxLock);
+ }
+ /* free our instance */
+ A_FREE(target);
+}
+
+/* registered target arrival callback from the HIF layer */
+HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo)
+{
+ HTC_TARGET *target = NULL;
+ A_STATUS status = A_OK;
+ int i;
+ A_UINT32 ctrl_bufsz;
+ A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
+
+ A_REGISTER_MODULE_DEBUG_INFO(htc);
+
+ do {
+
+ /* allocate target memory */
+ if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
+ status = A_ERROR;
+ break;
+ }
+
+ A_MEMZERO(target, sizeof(HTC_TARGET));
+ A_MUTEX_INIT(&target->HTCLock);
+ A_MUTEX_INIT(&target->HTCRxLock);
+ A_MUTEX_INIT(&target->HTCTxLock);
+ INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
+ INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);
+
+ /* give device layer the hif device handle */
+ target->Device.HIFDevice = hif_handle;
+ /* give the device layer our context (for event processing)
+ * the device layer will register it's own context with HIF
+ * so we need to set this so we can fetch it in the target remove handler */
+ target->Device.HTCContext = target;
+ /* set device layer target failure callback */
+ target->Device.TargetFailureCallback = HTCReportFailure;
+ /* set device layer recv message pending callback */
+ target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
+ target->EpWaitingForBuffers = ENDPOINT_MAX;
+
+ A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
+
+ ResetEndpointStates(target);
+
+ /* setup device layer */
+ status = DevSetup(&target->Device);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+
+ /* get the block sizes */
+ status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+ blocksizes, sizeof(blocksizes));
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
+ break;
+ }
+
+ /* Set the control buffer size based on the block size */
+ if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) {
+ ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
+ } else {
+ ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
+ }
+ for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
+ target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);
+ if (target->HTCControlBuffers[i].Buffer == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
+ status = A_ERROR;
+ break;
+ }
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* carve up buffers/packets for control messages */
+ for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
+ HTC_PACKET *pControlPacket;
+ pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
+ SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
+ target,
+ target->HTCControlBuffers[i].Buffer,
+ ctrl_bufsz,
+ ENDPOINT_0);
+ HTC_FREE_CONTROL_RX(target,pControlPacket);
+ }
+
+ for (;i < NUM_CONTROL_BUFFERS;i++) {
+ HTC_PACKET *pControlPacket;
+ pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
+ INIT_HTC_PACKET_INFO(pControlPacket,
+ target->HTCControlBuffers[i].Buffer,
+ ctrl_bufsz);
+ HTC_FREE_CONTROL_TX(target,pControlPacket);
+ }
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ if (target != NULL) {
+ HTCCleanup(target);
+ target = NULL;
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
+
+ return target;
+}
+
+void HTCDestroy(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%lX \n",(unsigned long)target));
+ HTCCleanup(target);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n"));
+}
+
+/* get the low level HIF device for the caller , the caller may wish to do low level
+ * HIF requests */
+void *HTCGetHifDevice(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ return target->Device.HIFDevice;
+}
+
+/* wait for the target to arrive (sends HTC Ready message)
+ * this operation is fully synchronous and the message is polled for */
+A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ A_STATUS status;
+ HTC_PACKET *pPacket = NULL;
+ HTC_READY_EX_MSG *pRdyMsg;
+
+ HTC_SERVICE_CONNECT_REQ connect;
+ HTC_SERVICE_CONNECT_RESP resp;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target));
+
+ do {
+
+#ifdef MBOXHW_UNIT_TEST
+
+ status = DoMboxHWTest(&target->Device);
+
+ if (status != A_OK) {
+ break;
+ }
+
+#endif
+
+ /* we should be getting 1 control message that the target is ready */
+ status = HTCWaitforControlMessage(target, &pPacket);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
+ break;
+ }
+
+ /* we controlled the buffer creation so it has to be properly aligned */
+ pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer;
+
+ if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) ||
+ (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
+ /* this message is not valid */
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+
+ if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) {
+ /* this message is not valid */
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount;
+ target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size: %d\n",
+ target->TargetCredits, target->TargetCreditSize));
+
+ /* check if this is an extended ready message */
+ if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) {
+ /* this is an extended message */
+ target->HTCTargetVersion = pRdyMsg->HTCVersion;
+ target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle;
+ } else {
+ /* legacy */
+ target->HTCTargetVersion = HTC_VERSION_2P0;
+ target->MaxMsgPerBundle = 0;
+ }
+
+#ifdef HTC_FORCE_LEGACY_2P0
+ /* for testing and comparison...*/
+ target->HTCTargetVersion = HTC_VERSION_2P0;
+ target->MaxMsgPerBundle = 0;
+#endif
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+ ("Using HTC Protocol Version : %s (%d)\n ",
+ (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
+ target->HTCTargetVersion));
+
+ if (target->MaxMsgPerBundle > 0) {
+ /* limit what HTC can handle */
+ target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle);
+ /* target supports message bundling, setup device layer */
+ if (A_FAILED(DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle))) {
+ /* device layer can't handle bundling */
+ target->MaxMsgPerBundle = 0;
+ } else {
+ /* limit bundle what the device layer can handle */
+ target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target->Device),
+ target->MaxMsgPerBundle);
+ }
+ }
+
+ if (target->MaxMsgPerBundle > 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+ (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle));
+
+ if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) {
+ target->SendBundlingEnabled = TRUE;
+ }
+ if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) {
+ target->RecvBundlingEnabled = TRUE;
+ }
+
+ if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not block aligned! Disabling send bundling \n",
+ target->TargetCreditSize));
+ /* disallow send bundling since the credit size is not aligned to a block size
+ * the I/O block padding will spill into the next credit buffer which is fatal */
+ target->SendBundlingEnabled = FALSE;
+ }
+ }
+
+ /* setup our pseudo HTC control endpoint connection */
+ A_MEMZERO(&connect,sizeof(connect));
+ A_MEMZERO(&resp,sizeof(resp));
+ connect.EpCallbacks.pContext = target;
+ connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
+ connect.EpCallbacks.EpRecv = HTCControlRecv;
+ connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */
+ connect.EpCallbacks.EpSendFull = NULL; /* not nedded */
+ connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
+ connect.ServiceID = HTC_CTRL_RSVD_SVC;
+
+ /* connect fake service */
+ status = HTCConnectService((HTC_HANDLE)target,
+ &connect,
+ &resp);
+
+ if (!A_FAILED(status)) {
+ break;
+ }
+
+ } while (FALSE);
+
+ if (pPacket != NULL) {
+ HTC_FREE_CONTROL_RX(target,pPacket);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n"));
+
+ return status;
+}
+
+
+
+/* Start HTC, enable interrupts and let the target know host has finished setup */
+A_STATUS HTCStart(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_PACKET *pPacket;
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
+
+ /* make sure interrupts are disabled at the chip level,
+ * this function can be called again from a reboot of the target without shutting down HTC */
+ DevDisableInterrupts(&target->Device);
+ /* make sure state is cleared again */
+ target->OpStateFlags = 0;
+ target->RecvStateFlags = 0;
+
+ /* now that we are starting, push control receive buffers into the
+ * HTC control endpoint */
+
+ while (1) {
+ pPacket = HTC_ALLOC_CONTROL_RX(target);
+ if (NULL == pPacket) {
+ break;
+ }
+ HTCAddReceivePkt((HTC_HANDLE)target,pPacket);
+ }
+
+ do {
+
+ AR_DEBUG_ASSERT(target->InitCredits != NULL);
+ AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL);
+ AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL);
+
+ /* call init credits callback to do the distribution ,
+ * NOTE: the first entry in the distribution list is ENDPOINT_0, so
+ * we pass the start of the list after this one. */
+ target->InitCredits(target->pCredDistContext,
+ target->EpCreditDistributionListHead->pNext,
+ target->TargetCredits);
+
+#ifdef ATH_DEBUG_MODULE
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
+ DumpCreditDistStates(target);
+ }
+#endif
+
+ /* the caller is done connecting to services, so we can indicate to the
+ * target that the setup phase is complete */
+ status = HTCSendSetupComplete(target);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* unmask interrupts */
+ status = DevUnmaskInterrupts(&target->Device);
+
+ if (A_FAILED(status)) {
+ HTCStop(target);
+ }
+
+ } while (FALSE);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
+ return status;
+}
+
+static void ResetEndpointStates(HTC_TARGET *target)
+{
+ HTC_ENDPOINT *pEndpoint;
+ int i;
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ pEndpoint = &target->EndPoint[i];
+
+ A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist));
+ pEndpoint->ServiceID = 0;
+ pEndpoint->MaxMsgLength = 0;
+ pEndpoint->MaxTxQueueDepth = 0;
+#ifdef HTC_EP_STAT_PROFILING
+ A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
+#endif
+ INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
+ INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
+ INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
+ pEndpoint->target = target;
+ }
+ /* reset distribution list */
+ target->EpCreditDistributionListHead = NULL;
+}
+
+/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */
+void HTCStop(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n"));
+
+ LOCK_HTC(target);
+ /* mark that we are shutting down .. */
+ target->OpStateFlags |= HTC_OP_STATE_STOPPING;
+ UNLOCK_HTC(target);
+
+ /* Masking interrupts is a synchronous operation, when this function returns
+ * all pending HIF I/O has completed, we can safely flush the queues */
+ DevMaskInterrupts(&target->Device);
+
+#ifdef THREAD_X
+ //
+ // Is this delay required
+ //
+ A_MDELAY(200); // wait for IRQ process done
+#endif
+ /* flush all send packets */
+ HTCFlushSendPkts(target);
+ /* flush all recv buffers */
+ HTCFlushRecvBuffers(target);
+
+ ResetEndpointStates(target);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
+}
+
+#ifdef ATH_DEBUG_MODULE
+void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+
+ LOCK_HTC_TX(target);
+
+ DumpCreditDistStates(target);
+
+ UNLOCK_HTC_TX(target);
+
+ DumpAR6KDevState(&target->Device);
+}
+#endif
+/* report a target failure from the device, this is a callback from the device layer
+ * which uses a mechanism to report errors from the target (i.e. special interrupts) */
+static void HTCReportFailure(void *Context)
+{
+ HTC_TARGET *target = (HTC_TARGET *)Context;
+
+ target->TargetFailure = TRUE;
+
+ if (target->HTCInitInfo.TargetFailure != NULL) {
+ /* let upper layer know, it needs to call HTCStop() */
+ target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR);
+ }
+}
+
+A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint,
+ HTC_ENDPOINT_STAT_ACTION Action,
+ HTC_ENDPOINT_STATS *pStats)
+{
+
+#ifdef HTC_EP_STAT_PROFILING
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ A_BOOL clearStats = FALSE;
+ A_BOOL sample = FALSE;
+
+ switch (Action) {
+ case HTC_EP_STAT_SAMPLE :
+ sample = TRUE;
+ break;
+ case HTC_EP_STAT_SAMPLE_AND_CLEAR :
+ sample = TRUE;
+ clearStats = TRUE;
+ break;
+ case HTC_EP_STAT_CLEAR :
+ clearStats = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ A_ASSERT(Endpoint < ENDPOINT_MAX);
+
+ /* lock out TX and RX while we sample and/or clear */
+ LOCK_HTC_TX(target);
+ LOCK_HTC_RX(target);
+
+ if (sample) {
+ A_ASSERT(pStats != NULL);
+ /* return the stats to the caller */
+ A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS));
+ }
+
+ if (clearStats) {
+ /* reset stats */
+ A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS));
+ }
+
+ UNLOCK_HTC_RX(target);
+ UNLOCK_HTC_TX(target);
+
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ return &target->Device;
+}
+
diff --git a/drivers/staging/ath6kl/htc2/htc_debug.h b/drivers/staging/ath6kl/htc2/htc_debug.h
new file mode 100644
index 000000000000..8455703e221c
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_debug.h
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_debug.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef HTC_DEBUG_H_
+#define HTC_DEBUG_H_
+
+#define ATH_MODULE_NAME htc
+#include "a_debug.h"
+
+/* ------- Debug related stuff ------- */
+
+#define ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0)
+#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1)
+#define ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2)
+#define ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3)
+#define ATH_DEBUG_IRQ ATH_DEBUG_MAKE_MODULE_MASK(4)
+
+
+#endif /*HTC_DEBUG_H_*/
diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h
new file mode 100644
index 000000000000..bd6754beb221
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_internal.h
@@ -0,0 +1,220 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_internal.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HTC_INTERNAL_H_
+#define _HTC_INTERNAL_H_
+
+/* for debugging, uncomment this to capture the last frame header, on frame header
+ * processing errors, the last frame header is dump for comparison */
+//#define HTC_CAPTURE_LAST_FRAME
+
+//#define HTC_EP_STAT_PROFILING
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "htc_debug.h"
+#include "htc.h"
+#include "htc_api.h"
+#include "bmi_msg.h"
+#include "hif.h"
+#include "AR6000/ar6k.h"
+
+/* HTC operational parameters */
+#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
+#define HTC_TARGET_DEBUG_INTR_MASK 0x01
+#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
+
+#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
+#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
+
+/* packet flags */
+
+#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
+#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
+#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
+#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
+
+/* scatter request flags */
+
+#define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE (1 << 0)
+
+typedef struct _HTC_ENDPOINT {
+ HTC_ENDPOINT_ID Id;
+ HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to
+ non-zero value means this endpoint is in use */
+ HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */
+ HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */
+ HTC_ENDPOINT_CREDIT_DIST CreditDist; /* credit distribution structure (exposed to driver layer) */
+ HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */
+ int MaxTxQueueDepth; /* max depth of the TX queue before we need to
+ call driver's full handler */
+ int MaxMsgLength; /* max length of endpoint message */
+ int TxProcessCount; /* reference count to continue tx processing */
+ HTC_PACKET_QUEUE RecvIndicationQueue; /* recv packets ready to be indicated */
+ int RxProcessCount; /* reference count to allow single processing context */
+ struct _HTC_TARGET *target; /* back pointer to target */
+ A_UINT8 SeqNo; /* TX seq no (helpful) for debugging */
+ A_UINT32 LocalConnectionFlags; /* local connection flags */
+#ifdef HTC_EP_STAT_PROFILING
+ HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */
+#endif
+} HTC_ENDPOINT;
+
+#ifdef HTC_EP_STAT_PROFILING
+#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
+#else
+#define INC_HTC_EP_STAT(p,stat,count)
+#endif
+
+#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL
+
+#define NUM_CONTROL_BUFFERS 8
+#define NUM_CONTROL_TX_BUFFERS 2
+#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
+
+typedef struct HTC_CONTROL_BUFFER {
+ HTC_PACKET HtcPacket;
+ A_UINT8 *Buffer;
+} HTC_CONTROL_BUFFER;
+
+#define HTC_RECV_WAIT_BUFFERS (1 << 0)
+#define HTC_OP_STATE_STOPPING (1 << 0)
+
+/* our HTC target state */
+typedef struct _HTC_TARGET {
+ HTC_ENDPOINT EndPoint[ENDPOINT_MAX];
+ HTC_CONTROL_BUFFER HTCControlBuffers[NUM_CONTROL_BUFFERS];
+ HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead;
+ HTC_PACKET_QUEUE ControlBufferTXFreeList;
+ HTC_PACKET_QUEUE ControlBufferRXFreeList;
+ HTC_CREDIT_DIST_CALLBACK DistributeCredits;
+ HTC_CREDIT_INIT_CALLBACK InitCredits;
+ void *pCredDistContext;
+ int TargetCredits;
+ unsigned int TargetCreditSize;
+ A_MUTEX_T HTCLock;
+ A_MUTEX_T HTCRxLock;
+ A_MUTEX_T HTCTxLock;
+ AR6K_DEVICE Device; /* AR6K - specific state */
+ A_UINT32 OpStateFlags;
+ A_UINT32 RecvStateFlags;
+ HTC_ENDPOINT_ID EpWaitingForBuffers;
+ A_BOOL TargetFailure;
+#ifdef HTC_CAPTURE_LAST_FRAME
+ HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */
+ A_UINT8 LastTrailer[256];
+ A_UINT8 LastTrailerLength;
+#endif
+ HTC_INIT_INFO HTCInitInfo;
+ A_UINT8 HTCTargetVersion;
+ int MaxMsgPerBundle; /* max messages per bundle for HTC */
+ A_BOOL SendBundlingEnabled; /* run time enable for send bundling (dynamic) */
+ int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */
+} HTC_TARGET;
+
+#define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING)
+#define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock);
+#define UNLOCK_HTC(t) A_MUTEX_UNLOCK(&(t)->HTCLock);
+#define LOCK_HTC_RX(t) A_MUTEX_LOCK(&(t)->HTCRxLock);
+#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock);
+#define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock);
+#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock);
+
+#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd))
+#define HTC_RECYCLE_RX_PKT(target,p,e) \
+{ \
+ if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) { \
+ HTC_PACKET_RESET_RX(pPacket); \
+ pPacket->Status = A_ECANCELED; \
+ (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \
+ (p)); \
+ } else { \
+ HTC_PACKET_RESET_RX(pPacket); \
+ HTCAddReceivePkt((HTC_HANDLE)(target),(p)); \
+ } \
+}
+
+/* internal HTC functions */
+void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket);
+void HTCControlRecv(void *Context, HTC_PACKET *pPacket);
+A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket);
+HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList);
+void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList);
+A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket);
+void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket);
+A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched);
+void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
+A_STATUS HTCSendSetupComplete(HTC_TARGET *target);
+void HTCFlushRecvBuffers(HTC_TARGET *target);
+void HTCFlushSendPkts(HTC_TARGET *target);
+
+#ifdef ATH_DEBUG_MODULE
+void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist);
+void DumpCreditDistStates(HTC_TARGET *target);
+void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription);
+#endif
+
+static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) {
+ HTC_PACKET *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList);
+ if (pPacket != NULL) {
+ /* set payload pointer area with some headroom */
+ pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH;
+ }
+ return pPacket;
+}
+
+#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList)
+#define HTC_ALLOC_CONTROL_RX(t) HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList)
+#define HTC_FREE_CONTROL_RX(t,p) \
+{ \
+ HTC_PACKET_RESET_RX(p); \
+ HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \
+}
+
+#define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1) \
+{ \
+ A_UINT8 *pHdrBuf; \
+ (pP)->pBuffer -= HTC_HDR_LENGTH; \
+ pHdrBuf = (pP)->pBuffer; \
+ A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)(pP)->ActualLength); \
+ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,(sendflags)); \
+ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (A_UINT8)(pP)->Endpoint); \
+ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (A_UINT8)(ctrl0)); \
+ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[1], (A_UINT8)(ctrl1)); \
+}
+
+#define HTC_UNPREPARE_SEND_PKT(pP) \
+ (pP)->pBuffer += HTC_HDR_LENGTH; \
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTC_INTERNAL_H_ */
diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c
new file mode 100644
index 000000000000..3503657fe7d2
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_recv.c
@@ -0,0 +1,1578 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_recv.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#include "htc_internal.h"
+
+#define HTCIssueRecv(t, p) \
+ DevRecvPacket(&(t)->Device, \
+ (p), \
+ (p)->ActualLength)
+
+#define DO_RCV_COMPLETION(e,q) DoRecvCompletion(e,q)
+
+#define DUMP_RECV_PKT_INFO(pP) \
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC RECV packet 0x%lX (%d bytes) (hdr:0x%X) on ep : %d \n", \
+ (unsigned long)(pP), \
+ (pP)->ActualLength, \
+ (pP)->PktInfo.AsRx.ExpectedHdr, \
+ (pP)->Endpoint))
+
+#ifdef HTC_EP_STAT_PROFILING
+#define HTC_RX_STAT_PROFILE(t,ep,numLookAheads) \
+{ \
+ INC_HTC_EP_STAT((ep), RxReceived, 1); \
+ if ((numLookAheads) == 1) { \
+ INC_HTC_EP_STAT((ep), RxLookAheads, 1); \
+ } else if ((numLookAheads) > 1) { \
+ INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1); \
+ } \
+}
+#else
+#define HTC_RX_STAT_PROFILE(t,ep,lookAhead)
+#endif
+
+static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pQueueToIndicate)
+{
+
+ do {
+
+ if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
+ /* nothing to indicate */
+ break;
+ }
+
+ if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n",
+ pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
+ /* a recv multiple handler is being used, pass the queue to the handler */
+ pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext,
+ pQueueToIndicate);
+ INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
+ } else {
+ HTC_PACKET *pPacket;
+ /* using legacy EpRecv */
+ do {
+ pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet 0x%lX \n", \
+ pEndpoint->Id, (unsigned long)(pPacket)));
+ pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket);
+ } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
+ }
+
+ } while (FALSE);
+
+}
+
+static INLINE A_STATUS HTCProcessTrailer(HTC_TARGET *target,
+ A_UINT8 *pBuffer,
+ int Length,
+ A_UINT32 *pNextLookAheads,
+ int *pNumLookAheads,
+ HTC_ENDPOINT_ID FromEndpoint)
+{
+ HTC_RECORD_HDR *pRecord;
+ A_UINT8 *pRecordBuf;
+ HTC_LOOKAHEAD_REPORT *pLookAhead;
+ A_UINT8 *pOrigBuffer;
+ int origLength;
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length));
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer");
+ }
+
+ pOrigBuffer = pBuffer;
+ origLength = Length;
+ status = A_OK;
+
+ while (Length > 0) {
+
+ if (Length < sizeof(HTC_RECORD_HDR)) {
+ status = A_EPROTO;
+ break;
+ }
+ /* these are byte aligned structs */
+ pRecord = (HTC_RECORD_HDR *)pBuffer;
+ Length -= sizeof(HTC_RECORD_HDR);
+ pBuffer += sizeof(HTC_RECORD_HDR);
+
+ if (pRecord->Length > Length) {
+ /* no room left in buffer for record */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" invalid record length: %d (id:%d) buffer has: %d bytes left \n",
+ pRecord->Length, pRecord->RecordID, Length));
+ status = A_EPROTO;
+ break;
+ }
+ /* start of record follows the header */
+ pRecordBuf = pBuffer;
+
+ switch (pRecord->RecordID) {
+ case HTC_RECORD_CREDITS:
+ AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT));
+ HTCProcessCreditRpt(target,
+ (HTC_CREDIT_REPORT *)pRecordBuf,
+ pRecord->Length / (sizeof(HTC_CREDIT_REPORT)),
+ FromEndpoint);
+ break;
+ case HTC_RECORD_LOOKAHEAD:
+ AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT));
+ pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf;
+ if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) &&
+ (pNextLookAheads != NULL)) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n",
+ pLookAhead->PreValid,
+ pLookAhead->PostValid));
+
+ /* look ahead bytes are valid, copy them over */
+ ((A_UINT8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0];
+ ((A_UINT8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1];
+ ((A_UINT8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2];
+ ((A_UINT8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3];
+
+#ifdef ATH_DEBUG_MODULE
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ DebugDumpBytes((A_UINT8 *)pNextLookAheads,4,"Next Look Ahead");
+ }
+#endif
+ /* just one normal lookahead */
+ *pNumLookAheads = 1;
+ }
+ break;
+ case HTC_RECORD_LOOKAHEAD_BUNDLE:
+ AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT));
+ if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) &&
+ (pNextLookAheads != NULL)) {
+ HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt;
+ int i;
+
+ pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf;
+
+#ifdef ATH_DEBUG_MODULE
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ DebugDumpBytes(pRecordBuf,pRecord->Length,"Bundle LookAhead");
+ }
+#endif
+
+ if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) >
+ HTC_HOST_MAX_MSG_PER_BUNDLE) {
+ /* this should never happen, the target restricts the number
+ * of messages per bundle configured by the host */
+ A_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) {
+ ((A_UINT8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0];
+ ((A_UINT8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1];
+ ((A_UINT8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2];
+ ((A_UINT8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3];
+ pBundledLookAheadRpt++;
+ }
+
+ *pNumLookAheads = i;
+ }
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n",
+ pRecord->RecordID, pRecord->Length));
+ break;
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* advance buffer past this record for next time around */
+ pBuffer += pRecord->Length;
+ Length -= pRecord->Length;
+ }
+
+#ifdef ATH_DEBUG_MODULE
+ if (A_FAILED(status)) {
+ DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer");
+ }
+#endif
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n"));
+ return status;
+
+}
+
+/* process a received message (i.e. strip off header, process any trailer data)
+ * note : locks must be released when this function is called */
+static A_STATUS HTCProcessRecvHeader(HTC_TARGET *target,
+ HTC_PACKET *pPacket,
+ A_UINT32 *pNextLookAheads,
+ int *pNumLookAheads)
+{
+ A_UINT8 temp;
+ A_UINT8 *pBuf;
+ A_STATUS status = A_OK;
+ A_UINT16 payloadLen;
+ A_UINT32 lookAhead;
+
+ pBuf = pPacket->pBuffer;
+
+ if (pNumLookAheads != NULL) {
+ *pNumLookAheads = 0;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n"));
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT");
+ }
+
+ do {
+ /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to
+ * retrieve 16 bit fields */
+ payloadLen = A_GET_UINT16_FIELD(pBuf, HTC_FRAME_HDR, PayloadLen);
+
+ ((A_UINT8 *)&lookAhead)[0] = pBuf[0];
+ ((A_UINT8 *)&lookAhead)[1] = pBuf[1];
+ ((A_UINT8 *)&lookAhead)[2] = pBuf[2];
+ ((A_UINT8 *)&lookAhead)[3] = pBuf[3];
+
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) {
+ /* refresh expected hdr, since this was unknown at the time we grabbed the packets
+ * as part of a bundle */
+ pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
+ /* refresh actual length since we now have the real header */
+ pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH;
+
+ /* validate the actual header that was refreshed */
+ if (pPacket->ActualLength > pPacket->BufferLength) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n",
+ payloadLen, lookAhead));
+ /* limit this to max buffer just to print out some of the buffer */
+ pPacket->ActualLength = min(pPacket->ActualLength, pPacket->BufferLength);
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, EndpointID)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n",
+ A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, EndpointID), pPacket->Endpoint));
+ status = A_EPROTO;
+ break;
+ }
+ }
+
+ if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) {
+ /* somehow the lookahead that gave us the full read length did not
+ * reflect the actual header in the pending message */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n",
+ (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags));
+#ifdef ATH_DEBUG_MODULE
+ DebugDumpBytes((A_UINT8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead");
+ DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header");
+#ifdef HTC_CAPTURE_LAST_FRAME
+ DebugDumpBytes((A_UINT8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header");
+ if (target->LastTrailerLength != 0) {
+ DebugDumpBytes(target->LastTrailer,
+ target->LastTrailerLength,
+ "Last trailer");
+ }
+#endif
+#endif
+ status = A_EPROTO;
+ break;
+ }
+
+ /* get flags */
+ temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, Flags);
+
+ if (temp & HTC_FLAGS_RECV_TRAILER) {
+ /* this packet has a trailer */
+
+ /* extract the trailer length in control byte 0 */
+ temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, ControlBytes[0]);
+
+ if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n",
+ payloadLen, temp));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
+ /* this packet was fetched as part of an HTC bundle, the embedded lookahead is
+ * not valid since the next packet may have already been fetched as part of the
+ * bundle */
+ pNextLookAheads = NULL;
+ pNumLookAheads = NULL;
+ }
+
+ /* process trailer data that follows HDR + application payload */
+ status = HTCProcessTrailer(target,
+ (pBuf + HTC_HDR_LENGTH + payloadLen - temp),
+ temp,
+ pNextLookAheads,
+ pNumLookAheads,
+ pPacket->Endpoint);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+#ifdef HTC_CAPTURE_LAST_FRAME
+ A_MEMCPY(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp);
+ target->LastTrailerLength = temp;
+#endif
+ /* trim length by trailer bytes */
+ pPacket->ActualLength -= temp;
+ }
+#ifdef HTC_CAPTURE_LAST_FRAME
+ else {
+ target->LastTrailerLength = 0;
+ }
+#endif
+
+ /* if we get to this point, the packet is good */
+ /* remove header and adjust length */
+ pPacket->pBuffer += HTC_HDR_LENGTH;
+ pPacket->ActualLength -= HTC_HDR_LENGTH;
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ /* dump the whole packet */
+#ifdef ATH_DEBUG_MODULE
+ DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT");
+#endif
+ } else {
+#ifdef HTC_CAPTURE_LAST_FRAME
+ A_MEMCPY(&target->LastFrameHdr,pBuf,sizeof(HTC_FRAME_HDR));
+#endif
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
+ if (pPacket->ActualLength > 0) {
+ AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg");
+ }
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n"));
+ return status;
+}
+
+static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target,
+ A_UINT32 NextLookAheads[],
+ int NumLookAheads,
+ A_BOOL CheckMoreMsgs)
+{
+ /* was there a lookahead for the next packet? */
+ if (NumLookAheads > 0) {
+ A_STATUS nextStatus;
+ int fetched = 0;
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n",
+ NumLookAheads));
+ /* force status re-check */
+ REF_IRQ_STATUS_RECHECK(&target->Device);
+ /* we have more packets, get the next packet fetch started */
+ nextStatus = HTCRecvMessagePendingHandler(target, NextLookAheads, NumLookAheads, NULL, &fetched);
+ if (A_EPROTO == nextStatus) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Next look ahead from recv header was INVALID\n"));
+#ifdef ATH_DEBUG_MODULE
+ DebugDumpBytes((A_UINT8 *)NextLookAheads,
+ NumLookAheads * (sizeof(A_UINT32)),
+ "BAD lookaheads from lookahead report");
+#endif
+ }
+ if (A_SUCCESS(nextStatus) && !fetched) {
+ /* we could not fetch any more packets due to resources */
+ DevAsyncIrqProcessComplete(&target->Device);
+ }
+ } else {
+ if (CheckMoreMsgs) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("HTCAsyncRecvCheckMorePackets - rechecking for more messages...\n"));
+ /* if we did not get anything on the look-ahead,
+ * call device layer to asynchronously re-check for messages. If we can keep the async
+ * processing going we get better performance. If there is a pending message we will keep processing
+ * messages asynchronously which should pipeline things nicely */
+ DevCheckPendingRecvMsgsAsync(&target->Device);
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - no check \n"));
+ }
+ }
+
+
+}
+
+ /* unload the recv completion queue */
+static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
+{
+ HTC_PACKET_QUEUE recvCompletions;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n"));
+
+ INIT_HTC_PACKET_QUEUE(&recvCompletions);
+
+ LOCK_HTC_RX(target);
+
+ /* increment rx processing count on entry */
+ pEndpoint->RxProcessCount++;
+ if (pEndpoint->RxProcessCount > 1) {
+ pEndpoint->RxProcessCount--;
+ /* another thread or task is draining the RX completion queue on this endpoint
+ * that thread will reset the rx processing count when the queue is drained */
+ UNLOCK_HTC_RX(target);
+ return;
+ }
+
+ /******* at this point only 1 thread may enter ******/
+
+ while (TRUE) {
+
+ /* transfer items from main recv queue to the local one so we can release the lock */
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue);
+
+ if (HTC_QUEUE_EMPTY(&recvCompletions)) {
+ /* all drained */
+ break;
+ }
+
+ /* release lock while we do the recv completions
+ * other threads can now queue more recv completions */
+ UNLOCK_HTC_RX(target);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("DrainRecvIndicationQueue : completing %d RECV packets \n",
+ HTC_PACKET_QUEUE_DEPTH(&recvCompletions)));
+ /* do completion */
+ DO_RCV_COMPLETION(pEndpoint,&recvCompletions);
+
+ /* re-acquire lock to grab some more completions */
+ LOCK_HTC_RX(target);
+ }
+
+ /* reset count */
+ pEndpoint->RxProcessCount = 0;
+ UNLOCK_HTC_RX(target);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DrainRecvIndicationQueue \n"));
+
+}
+
+ /* optimization for recv packets, we can indicate a "hint" that there are more
+ * single-packets to fetch on this endpoint */
+#define SET_MORE_RX_PACKET_INDICATION_FLAG(L,N,E,P) \
+ if ((N) > 0) { SetRxPacketIndicationFlags((L)[0],(E),(P)); }
+
+ /* for bundled frames, we can force the flag to indicate there are more packets */
+#define FORCE_MORE_RX_PACKET_INDICATION_FLAG(P) \
+ (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS;
+
+ /* note: this function can be called with the RX lock held */
+static INLINE void SetRxPacketIndicationFlags(A_UINT32 LookAhead,
+ HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET *pPacket)
+{
+ HTC_FRAME_HDR *pHdr = (HTC_FRAME_HDR *)&LookAhead;
+ /* check to see if the "next" packet is from the same endpoint of the
+ completing packet */
+ if (pHdr->EndpointID == pPacket->Endpoint) {
+ /* check that there is a buffer available to actually fetch it */
+ if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) {
+ /* provide a hint that there are more RX packets to fetch */
+ FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
+ }
+ }
+}
+
+
+/* asynchronous completion handler for recv packet fetching, when the device layer
+ * completes a read request, it will call this completion handler */
+void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket)
+{
+ HTC_TARGET *target = (HTC_TARGET *)Context;
+ HTC_ENDPOINT *pEndpoint;
+ A_UINT32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
+ int numLookAheads = 0;
+ A_STATUS status;
+ A_BOOL checkMorePkts = TRUE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n",
+ (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint));
+
+ A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
+ AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
+ pEndpoint = &target->EndPoint[pPacket->Endpoint];
+ pPacket->Completion = NULL;
+
+ /* get completion status */
+ status = pPacket->Status;
+
+ do {
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n",
+ pPacket->Status, pPacket->Endpoint));
+ break;
+ }
+ /* process the header for any trailer data */
+ status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
+ /* this packet was part of a bundle that had to be broken up.
+ * It was fetched one message at a time. There may be other asynchronous reads queued behind this one.
+ * Do no issue another check for more packets since the last one in the series of requests
+ * will handle it */
+ checkMorePkts = FALSE;
+ }
+
+ DUMP_RECV_PKT_INFO(pPacket);
+ LOCK_HTC_RX(target);
+ SET_MORE_RX_PACKET_INDICATION_FLAG(nextLookAheads,numLookAheads,pEndpoint,pPacket);
+ /* we have a good packet, queue it to the completion queue */
+ HTC_PACKET_ENQUEUE(&pEndpoint->RecvIndicationQueue,pPacket);
+ HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
+ UNLOCK_HTC_RX(target);
+
+ /* check for more recv packets before indicating */
+ HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts);
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n",
+ status));
+ /* recycle this packet */
+ HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
+ } else {
+ /* a good packet was queued, drain the queue */
+ DrainRecvIndicationQueue(target,pEndpoint);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n"));
+}
+
+/* synchronously wait for a control message from the target,
+ * This function is used at initialization time ONLY. At init messages
+ * on ENDPOINT 0 are expected. */
+A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket)
+{
+ A_STATUS status;
+ A_UINT32 lookAhead;
+ HTC_PACKET *pPacket = NULL;
+ HTC_FRAME_HDR *pHdr;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n"));
+
+ do {
+
+ *ppControlPacket = NULL;
+
+ /* call the polling function to see if we have a message */
+ status = DevPollMboxMsgRecv(&target->Device,
+ &lookAhead,
+ HTC_TARGET_RESPONSE_TIMEOUT);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead));
+
+ /* check the lookahead */
+ pHdr = (HTC_FRAME_HDR *)&lookAhead;
+
+ if (pHdr->EndpointID != ENDPOINT_0) {
+ /* unexpected endpoint number, should be zero */
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ if (A_FAILED(status)) {
+ /* bad message */
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ pPacket = HTC_ALLOC_CONTROL_RX(target);
+
+ if (pPacket == NULL) {
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ pPacket->PktInfo.AsRx.HTCRxFlags = 0;
+ pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead;
+ pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
+
+ if (pPacket->ActualLength > pPacket->BufferLength) {
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ /* we want synchronous operation */
+ pPacket->Completion = NULL;
+
+ /* get the message from the device, this will block */
+ status = HTCIssueRecv(target, pPacket);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* process receive header */
+ status = HTCProcessRecvHeader(target,pPacket,NULL,NULL);
+
+ pPacket->Status = status;
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n",
+ status));
+ break;
+ }
+
+ /* give the caller this control message packet, they are responsible to free */
+ *ppControlPacket = pPacket;
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ if (pPacket != NULL) {
+ /* cleanup buffer on error */
+ HTC_FREE_CONTROL_RX(target,pPacket);
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n"));
+
+ return status;
+}
+
+static A_STATUS AllocAndPrepareRxPackets(HTC_TARGET *target,
+ A_UINT32 LookAheads[],
+ int Messages,
+ HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pQueue)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pPacket;
+ HTC_FRAME_HDR *pHdr;
+ int i,j;
+ int numMessages;
+ int fullLength;
+ A_BOOL noRecycle;
+
+ /* lock RX while we assemble the packet buffers */
+ LOCK_HTC_RX(target);
+
+ for (i = 0; i < Messages; i++) {
+
+ pHdr = (HTC_FRAME_HDR *)&LookAheads[i];
+
+ if (pHdr->EndpointID >= ENDPOINT_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID));
+ /* invalid endpoint */
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pHdr->EndpointID != pEndpoint->Id) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d should be : %d (index:%d)\n",
+ pHdr->EndpointID, pEndpoint->Id, i));
+ /* invalid endpoint */
+ status = A_EPROTO;
+ break;
+ }
+
+ if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n",
+ pHdr->PayloadLen, (A_UINT32)HTC_MAX_PAYLOAD_LENGTH));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (0 == pEndpoint->ServiceID) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID));
+ /* endpoint isn't even connected */
+ status = A_EPROTO;
+ break;
+ }
+
+ if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) {
+ /* HTC header only indicates 1 message to fetch */
+ numMessages = 1;
+ } else {
+ /* HTC header indicates that every packet to follow has the same padded length so that it can
+ * be optimally fetched as a full bundle */
+ numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT;
+ /* the count doesn't include the starter frame, just a count of frames to follow */
+ numMessages++;
+ A_ASSERT(numMessages <= target->MaxMsgPerBundle);
+ INC_HTC_EP_STAT(pEndpoint, RxBundleIndFromHdr, 1);
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages));
+ }
+
+ fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR));
+
+ /* get packet buffers for each message, if there was a bundle detected in the header,
+ * use pHdr as a template to fetch all packets in the bundle */
+ for (j = 0; j < numMessages; j++) {
+
+ /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup,
+ * they must be explicitly returned */
+ noRecycle = FALSE;
+
+ if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) {
+ UNLOCK_HTC_RX(target);
+ noRecycle = TRUE;
+ /* user is using a per-packet allocation callback */
+ pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext,
+ pEndpoint->Id,
+ fullLength);
+ LOCK_HTC_RX(target);
+
+ } else if ((pEndpoint->EpCallBacks.EpRecvAllocThresh != NULL) &&
+ (fullLength > pEndpoint->EpCallBacks.RecvAllocThreshold)) {
+ INC_HTC_EP_STAT(pEndpoint,RxAllocThreshHit,1);
+ INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen);
+ /* threshold was hit, call the special recv allocation callback */
+ UNLOCK_HTC_RX(target);
+ noRecycle = TRUE;
+ /* user wants to allocate packets above a certain threshold */
+ pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext,
+ pEndpoint->Id,
+ fullLength);
+ LOCK_HTC_RX(target);
+
+ } else {
+ /* user is using a refill handler that can refill multiple HTC buffers */
+
+ /* get a packet from the endpoint recv queue */
+ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
+
+ if (NULL == pPacket) {
+ /* check for refill handler */
+ if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) {
+ UNLOCK_HTC_RX(target);
+ /* call the re-fill handler */
+ pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
+ pEndpoint->Id);
+ LOCK_HTC_RX(target);
+ /* check if we have more buffers */
+ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers);
+ /* fall through */
+ }
+ }
+ }
+
+ if (NULL == pPacket) {
+ /* this is not an error, we simply need to mark that we are waiting for buffers.*/
+ target->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS;
+ target->EpWaitingForBuffers = pEndpoint->Id;
+ status = A_NO_RESOURCE;
+ break;
+ }
+
+ AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id);
+ /* clear flags */
+ pPacket->PktInfo.AsRx.HTCRxFlags = 0;
+ pPacket->PktInfo.AsRx.IndicationFlags = 0;
+ pPacket->Status = A_OK;
+
+ if (noRecycle) {
+ /* flag that these packets cannot be recycled, they have to be returned to the
+ * user */
+ pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE;
+ }
+ /* add packet to queue (also incase we need to cleanup down below) */
+ HTC_PACKET_ENQUEUE(pQueue,pPacket);
+
+ if (HTC_STOPPING(target)) {
+ status = A_ECANCELED;
+ break;
+ }
+
+ /* make sure this message can fit in the endpoint buffer */
+ if ((A_UINT32)fullLength > pPacket->BufferLength) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n",
+ pHdr->PayloadLen, fullLength, pPacket->BufferLength));
+ status = A_EPROTO;
+ break;
+ }
+
+ if (j > 0) {
+ /* for messages fetched in a bundle the expected lookahead is unknown since we
+ * are only using the lookahead of the first packet as a template of what to
+ * expect for lengths */
+ /* flag that once we get the real HTC header we need to refesh the information */
+ pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR;
+ /* set it to something invalid */
+ pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF;
+ } else {
+
+ pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */
+ }
+ /* set the amount of data to fetch */
+ pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH;
+ }
+
+ if (A_FAILED(status)) {
+ if (A_NO_RESOURCE == status) {
+ /* this is actually okay */
+ status = A_OK;
+ }
+ break;
+ }
+
+ }
+
+ UNLOCK_HTC_RX(target);
+
+ if (A_FAILED(status)) {
+ while (!HTC_QUEUE_EMPTY(pQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ /* recycle all allocated packets */
+ HTC_RECYCLE_RX_PKT(target,pPacket,&target->EndPoint[pPacket->Endpoint]);
+ }
+ }
+
+ return status;
+}
+
+static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq)
+{
+ int i;
+ HTC_PACKET *pPacket;
+ HTC_ENDPOINT *pEndpoint;
+ A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
+ int numLookAheads = 0;
+ HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context;
+ A_STATUS status;
+ A_BOOL partialBundle = FALSE;
+ HTC_PACKET_QUEUE localRecvQueue;
+ A_BOOL procError = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n",
+ pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
+
+ A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device));
+
+ if (A_FAILED(pScatterReq->CompletionStatus)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
+ }
+
+ if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) {
+ partialBundle = TRUE;
+ }
+
+ DEV_FINISH_SCATTER_OPERATION(pScatterReq);
+
+ INIT_HTC_PACKET_QUEUE(&localRecvQueue);
+
+ pPacket = (HTC_PACKET *)pScatterReq->ScatterList[0].pCallerContexts[0];
+ /* note: all packets in a scatter req are for the same endpoint ! */
+ pEndpoint = &target->EndPoint[pPacket->Endpoint];
+
+ /* walk through the scatter list and process */
+ /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock
+ * as it processes credit reports */
+ for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
+ pPacket = (HTC_PACKET *)pScatterReq->ScatterList[i].pCallerContexts[0];
+ A_ASSERT(pPacket != NULL);
+ /* reset count, we are only interested in the look ahead in the last packet when we
+ * break out of this loop */
+ numLookAheads = 0;
+
+ if (A_SUCCESS(pScatterReq->CompletionStatus)) {
+ /* process header for each of the recv packets */
+ status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads);
+ } else {
+ status = A_ERROR;
+ }
+
+ if (A_SUCCESS(status)) {
+#ifdef HTC_EP_STAT_PROFILING
+ LOCK_HTC_RX(target);
+ HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
+ INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
+ UNLOCK_HTC_RX(target);
+#endif
+ if (i == (pScatterReq->ValidScatterEntries - 1)) {
+ /* last packet's more packets flag is set based on the lookahead */
+ SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket);
+ } else {
+ /* packets in a bundle automatically have this flag set */
+ FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
+ }
+
+ DUMP_RECV_PKT_INFO(pPacket);
+ /* since we can't hold a lock in this loop, we insert into our local recv queue for
+ * storage until we can transfer them to the recv completion queue */
+ HTC_PACKET_ENQUEUE(&localRecvQueue,pPacket);
+
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Recv packet scatter entry %d failed (out of %d) \n",
+ i, pScatterReq->ValidScatterEntries));
+ /* recycle failed recv */
+ HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint);
+ /* set flag and continue processing the remaining scatter entries */
+ procError = TRUE;
+ }
+
+ }
+
+ /* free scatter request */
+ DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
+
+ LOCK_HTC_RX(target);
+ /* transfer the packets in the local recv queue to the recv completion queue */
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RecvIndicationQueue, &localRecvQueue);
+
+ UNLOCK_HTC_RX(target);
+
+ if (!procError) {
+ /* pipeline the next check (asynchronously) for more packets */
+ HTCAsyncRecvCheckMorePackets(target,
+ lookAheads,
+ numLookAheads,
+ partialBundle ? FALSE : TRUE);
+ }
+
+ /* now drain the indication queue */
+ DrainRecvIndicationQueue(target,pEndpoint);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n"));
+}
+
+static A_STATUS HTCIssueRecvPacketBundle(HTC_TARGET *target,
+ HTC_PACKET_QUEUE *pRecvPktQueue,
+ HTC_PACKET_QUEUE *pSyncCompletionQueue,
+ int *pNumPacketsFetched,
+ A_BOOL PartialBundle)
+{
+ A_STATUS status = A_OK;
+ HIF_SCATTER_REQ *pScatterReq;
+ int i, totalLength;
+ int pktsToScatter;
+ HTC_PACKET *pPacket;
+ A_BOOL asyncMode = (pSyncCompletionQueue == NULL) ? TRUE : FALSE;
+ int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device);
+
+ pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue);
+ pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
+
+ if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) {
+ /* we were forced to split this bundle receive operation
+ * all packets in this partial bundle must have their lookaheads ignored */
+ PartialBundle = TRUE;
+ /* this would only happen if the target ignored our max bundle limit */
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n",
+ HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
+ }
+
+ totalLength = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCIssueRecvPacketBundle (Numpackets: %d , actual : %d) \n",
+ HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter));
+
+ do {
+
+ pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
+
+ if (pScatterReq == NULL) {
+ /* no scatter resources left, just let caller handle it the legacy way */
+ break;
+ }
+
+ pScatterReq->CallerFlags = 0;
+
+ if (PartialBundle) {
+ /* mark that this is a partial bundle, this has special ramifications to the
+ * scatter completion routine */
+ pScatterReq->CallerFlags |= HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE;
+ }
+
+ /* convert HTC packets to scatter list */
+ for (i = 0; i < pktsToScatter; i++) {
+ int paddedLength;
+
+ pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue);
+ A_ASSERT(pPacket != NULL);
+
+ paddedLength = DEV_CALC_RECV_PADDED_LEN(&target->Device, pPacket->ActualLength);
+
+ if ((scatterSpaceRemaining - paddedLength) < 0) {
+ /* exceeds what we can transfer, put the packet back */
+ HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue,pPacket);
+ break;
+ }
+
+ scatterSpaceRemaining -= paddedLength;
+
+ if (PartialBundle || (i < (pktsToScatter - 1))) {
+ /* packet 0..n-1 cannot be checked for look-aheads since we are fetching a bundle
+ * the last packet however can have it's lookahead used */
+ pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
+ }
+
+ /* note: 1 HTC packet per scatter entry */
+ /* setup packet into */
+ pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
+ pScatterReq->ScatterList[i].Length = paddedLength;
+
+ pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE;
+
+ if (asyncMode) {
+ /* save HTC packet for async completion routine */
+ pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
+ } else {
+ /* queue to caller's sync completion queue, caller will unload this when we return */
+ HTC_PACKET_ENQUEUE(pSyncCompletionQueue,pPacket);
+ }
+
+ A_ASSERT(pScatterReq->ScatterList[i].Length);
+ totalLength += pScatterReq->ScatterList[i].Length;
+ }
+
+ pScatterReq->TotalLength = totalLength;
+ pScatterReq->ValidScatterEntries = i;
+
+ if (asyncMode) {
+ pScatterReq->CompletionRoutine = HTCAsyncRecvScatterCompletion;
+ pScatterReq->Context = target;
+ }
+
+ status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode);
+
+ if (A_SUCCESS(status)) {
+ *pNumPacketsFetched = i;
+ }
+
+ if (!asyncMode) {
+ /* free scatter request */
+ DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq);
+ }
+
+ } while (FALSE);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n",
+ status,*pNumPacketsFetched));
+
+ return status;
+}
+
+static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint)
+{
+ /* see if endpoint is using a refill watermark
+ * ** no need to use a lock here, since we are only inspecting...
+ * caller may must not hold locks when calling this function */
+ if (pEndpoint->EpCallBacks.RecvRefillWaterMark > 0) {
+ if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBuffers) < pEndpoint->EpCallBacks.RecvRefillWaterMark) {
+ /* call the re-fill handler before we continue */
+ pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext,
+ pEndpoint->Id);
+ }
+ }
+}
+
+/* callback when device layer or lookahead report parsing detects a pending message */
+A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched)
+{
+ HTC_TARGET *target = (HTC_TARGET *)Context;
+ A_STATUS status = A_OK;
+ HTC_PACKET *pPacket;
+ HTC_ENDPOINT *pEndpoint;
+ A_BOOL asyncProc = FALSE;
+ A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
+ int pktsFetched;
+ HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue;
+ A_BOOL partialBundle;
+ HTC_ENDPOINT_ID id;
+ int totalFetched = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler NumLookAheads: %d \n",NumLookAheads));
+
+ if (pNumPktsFetched != NULL) {
+ *pNumPktsFetched = 0;
+ }
+
+ if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) {
+ /* We use async mode to get the packets if the device layer supports it.
+ * The device layer interfaces with HIF in which HIF may have restrictions on
+ * how interrupts are processed */
+ asyncProc = TRUE;
+ }
+
+ if (pAsyncProc != NULL) {
+ /* indicate to caller how we decided to process this */
+ *pAsyncProc = asyncProc;
+ }
+
+ if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
+ A_ASSERT(FALSE);
+ return A_EPROTO;
+ }
+
+ /* on first entry copy the lookaheads into our temp array for processing */
+ A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads);
+
+ while (TRUE) {
+
+ /* reset packets queues */
+ INIT_HTC_PACKET_QUEUE(&recvPktQueue);
+ INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue);
+
+ if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) {
+ status = A_EPROTO;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ /* first lookahead sets the expected endpoint IDs for all packets in a bundle */
+ id = ((HTC_FRAME_HDR *)&lookAheads[0])->EndpointID;
+ pEndpoint = &target->EndPoint[id];
+
+ if (id >= ENDPOINT_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MsgPend, Invalid Endpoint in look-ahead: %d \n",id));
+ status = A_EPROTO;
+ break;
+ }
+
+ /* try to allocate as many HTC RX packets indicated by the lookaheads
+ * these packets are stored in the recvPkt queue */
+ status = AllocAndPrepareRxPackets(target,
+ lookAheads,
+ NumLookAheads,
+ pEndpoint,
+ &recvPktQueue);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) >= 2) {
+ /* a recv bundle was detected, force IRQ status re-check again */
+ REF_IRQ_STATUS_RECHECK(&target->Device);
+ }
+
+ totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue);
+
+ /* we've got packet buffers for all we can currently fetch,
+ * this count is not valid anymore */
+ NumLookAheads = 0;
+ partialBundle = FALSE;
+
+ /* now go fetch the list of HTC packets */
+ while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
+
+ pktsFetched = 0;
+
+ if (target->RecvBundlingEnabled && (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) {
+ /* there are enough packets to attempt a bundle transfer and recv bundling is allowed */
+ status = HTCIssueRecvPacketBundle(target,
+ &recvPktQueue,
+ asyncProc ? NULL : &syncCompletedPktsQueue,
+ &pktsFetched,
+ partialBundle);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) {
+ /* we couldn't fetch all packets at one time, this creates a broken
+ * bundle */
+ partialBundle = TRUE;
+ }
+ }
+
+ /* see if the previous operation fetched any packets using bundling */
+ if (0 == pktsFetched) {
+ /* dequeue one packet */
+ pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
+ A_ASSERT(pPacket != NULL);
+
+ if (asyncProc) {
+ /* we use async mode to get the packet if the device layer supports it
+ * set our callback and context */
+ pPacket->Completion = HTCRecvCompleteHandler;
+ pPacket->pContext = target;
+ } else {
+ /* fully synchronous */
+ pPacket->Completion = NULL;
+ }
+
+ if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) {
+ /* lookaheads in all packets except the last one in the bundle must be ignored */
+ pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD;
+ }
+
+ /* go fetch the packet */
+ status = HTCIssueRecv(target, pPacket);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (!asyncProc) {
+ /* sent synchronously, queue this packet for synchronous completion */
+ HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue,pPacket);
+ }
+
+ }
+
+ }
+
+ if (A_SUCCESS(status)) {
+ CheckRecvWaterMark(pEndpoint);
+ }
+
+ if (asyncProc) {
+ /* we did this asynchronously so we can get out of the loop, the asynch processing
+ * creates a chain of requests to continue processing pending messages in the
+ * context of callbacks */
+ break;
+ }
+
+ /* synchronous handling */
+ if (target->Device.DSRCanYield) {
+ /* for the SYNC case, increment count that tracks when the DSR should yield */
+ target->Device.CurrentDSRRecvCount++;
+ }
+
+ /* in the sync case, all packet buffers are now filled,
+ * we can process each packet, check lookaheads and then repeat */
+
+ /* unload sync completion queue */
+ while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
+ HTC_PACKET_QUEUE container;
+
+ pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
+ A_ASSERT(pPacket != NULL);
+
+ pEndpoint = &target->EndPoint[pPacket->Endpoint];
+ /* reset count on each iteration, we are only interested in the last packet's lookahead
+ * information when we break out of this loop */
+ NumLookAheads = 0;
+ /* process header for each of the recv packets
+ * note: the lookahead of the last packet is useful for us to continue in this loop */
+ status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
+ /* last packet's more packets flag is set based on the lookahead */
+ SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,NumLookAheads,pEndpoint,pPacket);
+ } else {
+ /* packets in a bundle automatically have this flag set */
+ FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket);
+ }
+ /* good packet, indicate it */
+ HTC_RX_STAT_PROFILE(target,pEndpoint,NumLookAheads);
+
+ if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_PART_OF_BUNDLE) {
+ INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
+ }
+
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
+ DO_RCV_COMPLETION(pEndpoint,&container);
+ }
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (NumLookAheads == 0) {
+ /* no more look aheads */
+ break;
+ }
+
+ /* when we process recv synchronously we need to check if we should yield and stop
+ * fetching more packets indicated by the embedded lookaheads */
+ if (target->Device.DSRCanYield) {
+ if (DEV_CHECK_RECV_YIELD(&target->Device)) {
+ /* break out, don't fetch any more packets */
+ break;
+ }
+ }
+
+
+ /* check whether other OS contexts have queued any WMI command/data for WLAN.
+ * This check is needed only if WLAN Tx and Rx happens in same thread context */
+ A_CHECK_DRV_TX();
+
+ /* for SYNCH processing, if we get here, we are running through the loop again due to a detected lookahead.
+ * Set flag that we should re-check IRQ status registers again before leaving IRQ processing,
+ * this can net better performance in high throughput situations */
+ REF_IRQ_STATUS_RECHECK(&target->Device);
+ }
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Failed to get pending recv messages (%d) \n",status));
+ /* cleanup any packets we allocated but didn't use to actually fetch any packets */
+ while (!HTC_QUEUE_EMPTY(&recvPktQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue);
+ /* clean up packets */
+ HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
+ }
+ /* cleanup any packets in sync completion queue */
+ while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) {
+ pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue);
+ /* clean up packets */
+ HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]);
+ }
+ if (HTC_STOPPING(target)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ (" Host is going to stop. blocking receiver for HTCStop.. \n"));
+ DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
+ }
+ }
+ /* before leaving, check to see if host ran out of buffers and needs to stop the
+ * receiver */
+ if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
+ (" Host has no RX buffers, blocking receiver to prevent overrun.. \n"));
+ /* try to stop receive at the device layer */
+ DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC);
+ }
+
+ if (pNumPktsFetched != NULL) {
+ *pNumPktsFetched = totalFetched;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n"));
+
+ return status;
+}
+
+A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_ENDPOINT *pEndpoint;
+ A_BOOL unblockRecv = FALSE;
+ A_STATUS status = A_OK;
+ HTC_PACKET *pFirstPacket;
+
+ pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
+
+ if (NULL == pFirstPacket) {
+ A_ASSERT(FALSE);
+ return A_EINVAL;
+ }
+
+ AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
+ ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n",
+ pFirstPacket->Endpoint,
+ HTC_PACKET_QUEUE_DEPTH(pPktQueue),
+ pFirstPacket->BufferLength));
+
+ do {
+
+ pEndpoint = &target->EndPoint[pFirstPacket->Endpoint];
+
+ LOCK_HTC_RX(target);
+
+ if (HTC_STOPPING(target)) {
+ HTC_PACKET *pPacket;
+
+ UNLOCK_HTC_RX(target);
+
+ /* walk through queue and mark each one canceled */
+ HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
+ pPacket->Status = A_ECANCELED;
+ } HTC_PACKET_QUEUE_ITERATE_END;
+
+ DO_RCV_COMPLETION(pEndpoint,pPktQueue);
+ break;
+ }
+
+ /* store receive packets */
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBuffers, pPktQueue);
+
+ /* check if we are blocked waiting for a new buffer */
+ if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
+ if (target->EpWaitingForBuffers == pFirstPacket->Endpoint) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n",
+ target->EpWaitingForBuffers));
+ target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
+ target->EpWaitingForBuffers = ENDPOINT_MAX;
+ unblockRecv = TRUE;
+ }
+ }
+
+ UNLOCK_HTC_RX(target);
+
+ if (unblockRecv && !HTC_STOPPING(target)) {
+ /* TODO : implement a buffer threshold count? */
+ DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
+ }
+
+ } while (FALSE);
+
+ return status;
+}
+
+/* Makes a buffer available to the HTC module */
+A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
+{
+ HTC_PACKET_QUEUE queue;
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
+ return HTCAddReceivePktMultiple(HTCHandle, &queue);
+}
+
+void HTCUnblockRecv(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ A_BOOL unblockRecv = FALSE;
+
+ LOCK_HTC_RX(target);
+
+ /* check if we are blocked waiting for a new buffer */
+ if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n",
+ target->EpWaitingForBuffers));
+ target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS;
+ target->EpWaitingForBuffers = ENDPOINT_MAX;
+ unblockRecv = TRUE;
+ }
+
+ UNLOCK_HTC_RX(target);
+
+ if (unblockRecv && !HTC_STOPPING(target)) {
+ /* re-enable */
+ DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC);
+ }
+}
+
+static void HTCFlushRxQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pQueue)
+{
+ HTC_PACKET *pPacket;
+ HTC_PACKET_QUEUE container;
+
+ LOCK_HTC_RX(target);
+
+ while (1) {
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ if (NULL == pPacket) {
+ break;
+ }
+ UNLOCK_HTC_RX(target);
+ pPacket->Status = A_ECANCELED;
+ pPacket->ActualLength = 0;
+ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:0x%lX, length:%d, ep:%d \n",
+ (unsigned long)pPacket, pPacket->BufferLength, pPacket->Endpoint));
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
+ /* give the packet back */
+ DO_RCV_COMPLETION(pEndpoint,&container);
+ LOCK_HTC_RX(target);
+ }
+
+ UNLOCK_HTC_RX(target);
+}
+
+static void HTCFlushEndpointRX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
+{
+ /* flush any recv indications not already made */
+ HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue);
+ /* flush any rx buffers */
+ HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers);
+}
+
+void HTCFlushRecvBuffers(HTC_TARGET *target)
+{
+ HTC_ENDPOINT *pEndpoint;
+ int i;
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ pEndpoint = &target->EndPoint[i];
+ if (pEndpoint->ServiceID == 0) {
+ /* not in use.. */
+ continue;
+ }
+ HTCFlushEndpointRX(target,pEndpoint);
+ }
+}
+
+
+void HTCEnableRecv(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+
+ if (!HTC_STOPPING(target)) {
+ /* re-enable */
+ DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
+ }
+}
+
+void HTCDisableRecv(HTC_HANDLE HTCHandle)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+
+ if (!HTC_STOPPING(target)) {
+ /* disable */
+ DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC);
+ }
+}
+
+int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers));
+}
+
+A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
+ A_UINT32 TimeoutInMs,
+ A_BOOL *pbIsRecvPending)
+{
+ A_STATUS status = A_OK;
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+
+ status = DevWaitForPendingRecv(&target->Device,
+ TimeoutInMs,
+ pbIsRecvPending);
+
+ return status;
+}
diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c
new file mode 100644
index 000000000000..bc7ee7848263
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_send.c
@@ -0,0 +1,1023 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_send.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#include "htc_internal.h"
+
+typedef enum _HTC_SEND_QUEUE_RESULT {
+ HTC_SEND_QUEUE_OK = 0, /* packet was queued */
+ HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */
+} HTC_SEND_QUEUE_RESULT;
+
+#define DO_EP_TX_COMPLETION(ep,q) DoSendCompletion(ep,q)
+
+/* call the distribute credits callback with the distribution */
+#define DO_DISTRIBUTION(t,reason,description,pList) \
+{ \
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \
+ (" calling distribute function (%s) (dfn:0x%lX, ctxt:0x%lX, dist:0x%lX) \n", \
+ (description), \
+ (unsigned long)(t)->DistributeCredits, \
+ (unsigned long)(t)->pCredDistContext, \
+ (unsigned long)pList)); \
+ (t)->DistributeCredits((t)->pCredDistContext, \
+ (pList), \
+ (reason)); \
+}
+
+static void DoSendCompletion(HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pQueueToIndicate)
+{
+ do {
+
+ if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
+ /* nothing to indicate */
+ break;
+ }
+
+ if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n",
+ pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate)));
+ /* a multiple send complete handler is being used, pass the queue to the handler */
+ pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext,
+ pQueueToIndicate);
+ /* all packets are now owned by the callback, reset queue to be safe */
+ INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
+ } else {
+ HTC_PACKET *pPacket;
+ /* using legacy EpTxComplete */
+ do {
+ pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate);
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet 0x%lX \n", \
+ pEndpoint->Id, (unsigned long)(pPacket)));
+ pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);
+ } while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
+ }
+
+ } while (FALSE);
+
+}
+
+/* do final completion on sent packet */
+static INLINE void CompleteSentPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET *pPacket)
+{
+ pPacket->Completion = NULL;
+
+ if (A_FAILED(pPacket->Status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n",
+ pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed));
+ /* on failure to submit, reclaim credits for this packet */
+ LOCK_HTC_TX(target);
+ pEndpoint->CreditDist.TxCreditsToDist += pPacket->PktInfo.AsTx.CreditsUsed;
+ pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
+ DO_DISTRIBUTION(target,
+ HTC_CREDIT_DIST_SEND_COMPLETE,
+ "Send Complete",
+ target->EpCreditDistributionListHead->pNext);
+ UNLOCK_HTC_TX(target);
+ }
+ /* first, fixup the head room we allocated */
+ pPacket->pBuffer += HTC_HDR_LENGTH;
+}
+
+/* our internal send packet completion handler when packets are submited to the AR6K device
+ * layer */
+static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket)
+{
+ HTC_TARGET *target = (HTC_TARGET *)Context;
+ HTC_ENDPOINT *pEndpoint = &target->EndPoint[pPacket->Endpoint];
+ HTC_PACKET_QUEUE container;
+
+ CompleteSentPacket(target,pEndpoint,pPacket);
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
+ /* do completion */
+ DO_EP_TX_COMPLETION(pEndpoint,&container);
+}
+
+A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket)
+{
+ A_STATUS status;
+ A_BOOL sync = FALSE;
+
+ if (pPacket->Completion == NULL) {
+ /* mark that this request was synchronously issued */
+ sync = TRUE;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ ("+-HTCIssueSend: transmit length : %d (%s) \n",
+ pPacket->ActualLength + (A_UINT32)HTC_HDR_LENGTH,
+ sync ? "SYNC" : "ASYNC" ));
+
+ /* send message to device */
+ status = DevSendPacket(&target->Device,
+ pPacket,
+ pPacket->ActualLength + HTC_HDR_LENGTH);
+
+ if (sync) {
+ /* use local sync variable. If this was issued asynchronously, pPacket is no longer
+ * safe to access. */
+ pPacket->pBuffer += HTC_HDR_LENGTH;
+ }
+
+ /* if this request was asynchronous, the packet completion routine will be invoked by
+ * the device layer when the HIF layer completes the request */
+
+ return status;
+}
+
+ /* get HTC send packets from the TX queue on an endpoint */
+static INLINE void GetHTCSendPackets(HTC_TARGET *target,
+ HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pQueue)
+{
+ int creditsRequired;
+ int remainder;
+ A_UINT8 sendFlags;
+ HTC_PACKET *pPacket;
+ unsigned int transferLength;
+
+ /****** NOTE : the TX lock is held when this function is called *****************/
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n"));
+
+ /* loop until we can grab as many packets out of the queue as we can */
+ while (TRUE) {
+
+ sendFlags = 0;
+ /* get packet at head, but don't remove it */
+ pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue);
+ if (pPacket == NULL) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%lX , Queue Depth: %d\n",
+ (unsigned long)pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
+
+ transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, pPacket->ActualLength + HTC_HDR_LENGTH);
+
+ if (transferLength <= target->TargetCreditSize) {
+ creditsRequired = 1;
+ } else {
+ /* figure out how many credits this message requires */
+ creditsRequired = transferLength / target->TargetCreditSize;
+ remainder = transferLength % target->TargetCreditSize;
+
+ if (remainder) {
+ creditsRequired++;
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n",
+ creditsRequired, pEndpoint->CreditDist.TxCredits));
+
+ if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
+
+ /* not enough credits */
+ if (pPacket->Endpoint == ENDPOINT_0) {
+ /* leave it in the queue */
+ break;
+ }
+ /* invoke the registered distribution function only if this is not
+ * endpoint 0, we let the driver layer provide more credits if it can.
+ * We pass the credit distribution list starting at the endpoint in question
+ * */
+
+ /* set how many credits we need */
+ pEndpoint->CreditDist.TxCreditsSeek =
+ creditsRequired - pEndpoint->CreditDist.TxCredits;
+ DO_DISTRIBUTION(target,
+ HTC_CREDIT_DIST_SEEK_CREDITS,
+ "Seek Credits",
+ &pEndpoint->CreditDist);
+ pEndpoint->CreditDist.TxCreditsSeek = 0;
+
+ if (pEndpoint->CreditDist.TxCredits < creditsRequired) {
+ /* still not enough credits to send, leave packet in the queue */
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ (" Not enough credits for ep %d leaving packet in queue..\n",
+ pPacket->Endpoint));
+ break;
+ }
+
+ }
+
+ pEndpoint->CreditDist.TxCredits -= creditsRequired;
+ INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired);
+
+ /* check if we need credits back from the target */
+ if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
+ /* we are getting low on credits, see if we can ask for more from the distribution function */
+ pEndpoint->CreditDist.TxCreditsSeek =
+ pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits;
+
+ DO_DISTRIBUTION(target,
+ HTC_CREDIT_DIST_SEEK_CREDITS,
+ "Seek Credits",
+ &pEndpoint->CreditDist);
+
+ pEndpoint->CreditDist.TxCreditsSeek = 0;
+ /* see if we were successful in getting more */
+ if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
+ /* tell the target we need credits ASAP! */
+ sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
+ INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1);
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n"));
+ }
+ }
+
+ /* now we can fully dequeue */
+ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue);
+ /* save the number of credits this packet consumed */
+ pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired;
+ /* all TX packets are handled asynchronously */
+ pPacket->Completion = HTCSendPktCompletionHandler;
+ pPacket->pContext = target;
+ INC_HTC_EP_STAT(pEndpoint, TxIssued, 1);
+ /* save send flags */
+ pPacket->PktInfo.AsTx.SendFlags = sendFlags;
+ pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo;
+ pEndpoint->SeqNo++;
+ /* queue this packet into the caller's queue */
+ HTC_PACKET_ENQUEUE(pQueue,pPacket);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n"));
+
+}
+
+static void HTCAsyncSendScatterCompletion(HIF_SCATTER_REQ *pScatterReq)
+{
+ int i;
+ HTC_PACKET *pPacket;
+ HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pScatterReq->Context;
+ HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target;
+ A_STATUS status = A_OK;
+ HTC_PACKET_QUEUE sendCompletes;
+
+ INIT_HTC_PACKET_QUEUE(&sendCompletes);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCAsyncSendScatterCompletion TotLen: %d Entries: %d\n",
+ pScatterReq->TotalLength, pScatterReq->ValidScatterEntries));
+
+ DEV_FINISH_SCATTER_OPERATION(pScatterReq);
+
+ if (A_FAILED(pScatterReq->CompletionStatus)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus));
+ status = A_ERROR;
+ }
+
+ /* walk through the scatter list and process */
+ for (i = 0; i < pScatterReq->ValidScatterEntries; i++) {
+ pPacket = (HTC_PACKET *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
+ A_ASSERT(pPacket != NULL);
+ pPacket->Status = status;
+ CompleteSentPacket(target,pEndpoint,pPacket);
+ /* add it to the completion queue */
+ HTC_PACKET_ENQUEUE(&sendCompletes, pPacket);
+ }
+
+ /* free scatter request */
+ DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
+ /* complete all packets */
+ DO_EP_TX_COMPLETION(pEndpoint,&sendCompletes);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCAsyncSendScatterCompletion \n"));
+}
+
+ /* drain a queue and send as bundles
+ * this function may return without fully draining the queue under the following conditions :
+ * - scatter resources are exhausted
+ * - a message that will consume a partial credit will stop the bundling process early
+ * - we drop below the minimum number of messages for a bundle
+ * */
+static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pQueue,
+ int *pBundlesSent,
+ int *pTotalBundlesPkts)
+{
+ int pktsToScatter;
+ unsigned int scatterSpaceRemaining;
+ HIF_SCATTER_REQ *pScatterReq = NULL;
+ int i, packetsInScatterReq;
+ unsigned int transferLength;
+ HTC_PACKET *pPacket;
+ A_BOOL done = FALSE;
+ int bundlesSent = 0;
+ int totalPktsInBundle = 0;
+ HTC_TARGET *target = pEndpoint->target;
+ int creditRemainder = 0;
+ int creditPad;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCIssueSendBundle \n"));
+
+ while (!done) {
+
+ pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pQueue);
+ pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle);
+
+ if (pktsToScatter < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
+ /* not enough to bundle */
+ break;
+ }
+
+ pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device);
+
+ if (pScatterReq == NULL) {
+ /* no scatter resources */
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" No more scatter resources \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" pkts to scatter: %d \n", pktsToScatter));
+
+ pScatterReq->TotalLength = 0;
+ pScatterReq->ValidScatterEntries = 0;
+
+ packetsInScatterReq = 0;
+ scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device);
+
+ for (i = 0; i < pktsToScatter; i++) {
+
+ pScatterReq->ScatterList[i].pCallerContexts[0] = NULL;
+
+ pPacket = HTC_GET_PKT_AT_HEAD(pQueue);
+ if (pPacket == NULL) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ creditPad = 0;
+ transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device,
+ pPacket->ActualLength + HTC_HDR_LENGTH);
+ /* see if the padded transfer length falls on a credit boundary */
+ creditRemainder = transferLength % target->TargetCreditSize;
+
+ if (creditRemainder != 0) {
+ /* the transfer consumes a "partial" credit, this packet cannot be bundled unless
+ * we add additional "dummy" padding (max 255 bytes) to consume the entire credit
+ *** NOTE: only allow the send padding if the endpoint is allowed to */
+ if (pEndpoint->LocalConnectionFlags & HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING) {
+ if (transferLength < target->TargetCreditSize) {
+ /* special case where the transfer is less than a credit */
+ creditPad = target->TargetCreditSize - transferLength;
+ } else {
+ creditPad = creditRemainder;
+ }
+
+ /* now check to see if we can indicate padding in the HTC header */
+ if ((creditPad > 0) && (creditPad <= 255)) {
+ /* adjust the transferlength of this packet with the new credit padding */
+ transferLength += creditPad;
+ } else {
+ /* the amount to pad is too large, bail on this packet, we have to
+ * send it using the non-bundled method */
+ pPacket = NULL;
+ }
+ } else {
+ /* bail on this packet, user does not want padding applied */
+ pPacket = NULL;
+ }
+ }
+
+ if (NULL == pPacket) {
+ /* can't bundle */
+ done = TRUE;
+ break;
+ }
+
+ if (scatterSpaceRemaining < transferLength) {
+ /* exceeds what we can transfer */
+ break;
+ }
+
+ scatterSpaceRemaining -= transferLength;
+ /* now remove it from the queue */
+ pPacket = HTC_PACKET_DEQUEUE(pQueue);
+ /* save it in the scatter list */
+ pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket;
+ /* prepare packet and flag message as part of a send bundle */
+ HTC_PREPARE_SEND_PKT(pPacket,
+ pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE,
+ creditPad,
+ pPacket->PktInfo.AsTx.SeqNo);
+ pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer;
+ pScatterReq->ScatterList[i].Length = transferLength;
+ A_ASSERT(transferLength);
+ pScatterReq->TotalLength += transferLength;
+ pScatterReq->ValidScatterEntries++;
+ packetsInScatterReq++;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" %d, Adding packet : 0x%lX, len:%d (remaining space:%d) \n",
+ i, (unsigned long)pPacket,transferLength,scatterSpaceRemaining));
+ }
+
+ if (packetsInScatterReq >= HTC_MIN_HTC_MSGS_TO_BUNDLE) {
+ /* send path is always asynchronous */
+ pScatterReq->CompletionRoutine = HTCAsyncSendScatterCompletion;
+ pScatterReq->Context = pEndpoint;
+ bundlesSent++;
+ totalPktsInBundle += packetsInScatterReq;
+ packetsInScatterReq = 0;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Send Scatter total bytes: %d , entries: %d\n",
+ pScatterReq->TotalLength,pScatterReq->ValidScatterEntries));
+ DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_WRITE, DEV_SCATTER_ASYNC);
+ /* we don't own this anymore */
+ pScatterReq = NULL;
+ /* try to send some more */
+ continue;
+ }
+
+ /* not enough packets to use the scatter request, cleanup */
+ if (pScatterReq != NULL) {
+ if (packetsInScatterReq > 0) {
+ /* work backwards to requeue requests */
+ for (i = (packetsInScatterReq - 1); i >= 0; i--) {
+ pPacket = (HTC_PACKET *)(pScatterReq->ScatterList[i].pCallerContexts[0]);
+ if (pPacket != NULL) {
+ /* undo any prep */
+ HTC_UNPREPARE_SEND_PKT(pPacket);
+ /* queue back to the head */
+ HTC_PACKET_ENQUEUE_TO_HEAD(pQueue,pPacket);
+ }
+ }
+ }
+ DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq);
+ }
+
+ /* if we get here, we sent all that we could, get out */
+ break;
+
+ }
+
+ *pBundlesSent = bundlesSent;
+ *pTotalBundlesPkts = totalPktsInBundle;
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCIssueSendBundle (sent:%d) \n",bundlesSent));
+
+ return;
+}
+
+/*
+ * if there are no credits, the packet(s) remains in the queue.
+ * this function returns the result of the attempt to send a queue of HTC packets */
+static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target,
+ HTC_ENDPOINT *pEndpoint,
+ HTC_PACKET_QUEUE *pCallersSendQueue)
+{
+ HTC_PACKET_QUEUE sendQueue; /* temp queue to hold packets at various stages */
+ HTC_PACKET *pPacket;
+ int bundlesSent;
+ int pktsInBundles;
+ int overflow;
+ HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:0x%lX Depth:%d)\n",
+ (unsigned long)pCallersSendQueue,
+ (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue)));
+
+ /* init the local send queue */
+ INIT_HTC_PACKET_QUEUE(&sendQueue);
+
+ do {
+
+ if (NULL == pCallersSendQueue) {
+ /* caller didn't provide a queue, just wants us to check queues and send */
+ break;
+ }
+
+ if (HTC_QUEUE_EMPTY(pCallersSendQueue)) {
+ /* empty queue */
+ result = HTC_SEND_QUEUE_DROP;
+ break;
+ }
+
+ if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) {
+ /* we've already overflowed */
+ overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
+ } else {
+ /* figure out how much we will overflow by */
+ overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
+ overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue);
+ /* figure out how much we will overflow the TX queue by */
+ overflow -= pEndpoint->MaxTxQueueDepth;
+ }
+
+ /* if overflow is negative or zero, we are okay */
+ if (overflow > 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n",
+ pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth));
+ }
+ if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) {
+ /* all packets will fit or caller did not provide send full indication handler
+ * -- just move all of them to the local sendQueue object */
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue);
+ } else {
+ int i;
+ int goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow;
+
+ A_ASSERT(goodPkts >= 0);
+ /* we have overflowed, and a callback is provided */
+ /* dequeue all non-overflow packets into the sendqueue */
+ for (i = 0; i < goodPkts; i++) {
+ /* pop off caller's queue*/
+ pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue);
+ A_ASSERT(pPacket != NULL);
+ /* insert into local queue */
+ HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
+ }
+
+ /* the caller's queue has all the packets that won't fit*/
+ /* walk through the caller's queue and indicate each one to the send full handler */
+ ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, HTC_PACKET, ListLink) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n",
+ (unsigned long)pPacket));
+ if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext,
+ pPacket) == HTC_SEND_FULL_DROP) {
+ /* callback wants the packet dropped */
+ INC_HTC_EP_STAT(pEndpoint, TxDropped, 1);
+ /* leave this one in the caller's queue for cleanup */
+ } else {
+ /* callback wants to keep this packet, remove from caller's queue */
+ HTC_PACKET_REMOVE(pCallersSendQueue, pPacket);
+ /* put it in the send queue */
+ HTC_PACKET_ENQUEUE(&sendQueue,pPacket);
+ }
+
+ } ITERATE_END;
+
+ if (HTC_QUEUE_EMPTY(&sendQueue)) {
+ /* no packets made it in, caller will cleanup */
+ result = HTC_SEND_QUEUE_DROP;
+ break;
+ }
+ }
+
+ } while (FALSE);
+
+ if (result != HTC_SEND_QUEUE_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
+ return result;
+ }
+
+ LOCK_HTC_TX(target);
+
+ if (!HTC_QUEUE_EMPTY(&sendQueue)) {
+ /* transfer packets */
+ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue);
+ A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue));
+ INIT_HTC_PACKET_QUEUE(&sendQueue);
+ }
+
+ /* increment tx processing count on entry */
+ pEndpoint->TxProcessCount++;
+ if (pEndpoint->TxProcessCount > 1) {
+ /* another thread or task is draining the TX queues on this endpoint
+ * that thread will reset the tx processing count when the queue is drained */
+ pEndpoint->TxProcessCount--;
+ UNLOCK_HTC_TX(target);
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n"));
+ return HTC_SEND_QUEUE_OK;
+ }
+
+ /***** beyond this point only 1 thread may enter ******/
+
+ /* now drain the endpoint TX queue for transmission as long as we have enough
+ * credits */
+ while (TRUE) {
+
+ if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) {
+ break;
+ }
+
+ /* get all the packets for this endpoint that we can for this pass */
+ GetHTCSendPackets(target, pEndpoint, &sendQueue);
+
+ if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) {
+ /* didn't get any packets due to a lack of credits */
+ break;
+ }
+
+ UNLOCK_HTC_TX(target);
+
+ /* any packets to send are now in our local send queue */
+
+ bundlesSent = 0;
+ pktsInBundles = 0;
+
+ while (TRUE) {
+
+ /* try to send a bundle on each pass */
+ if ((target->SendBundlingEnabled) &&
+ (HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
+ int temp1,temp2;
+ /* bundling is enabled and there is at least a minimum number of packets in the send queue
+ * send what we can in this pass */
+ HTCIssueSendBundle(pEndpoint, &sendQueue, &temp1, &temp2);
+ bundlesSent += temp1;
+ pktsInBundles += temp2;
+ }
+
+ /* if not bundling or there was a packet that could not be placed in a bundle, pull it out
+ * and send it the normal way */
+ pPacket = HTC_PACKET_DEQUEUE(&sendQueue);
+ if (NULL == pPacket) {
+ /* local queue is fully drained */
+ break;
+ }
+ HTC_PREPARE_SEND_PKT(pPacket,
+ pPacket->PktInfo.AsTx.SendFlags,
+ 0,
+ pPacket->PktInfo.AsTx.SeqNo);
+ HTCIssueSend(target, pPacket);
+
+ /* go back and see if we can bundle some more */
+ }
+
+ LOCK_HTC_TX(target);
+
+ INC_HTC_EP_STAT(pEndpoint, TxBundles, bundlesSent);
+ INC_HTC_EP_STAT(pEndpoint, TxPacketsBundled, pktsInBundles);
+
+ }
+
+ /* done with this endpoint, we can clear the count */
+ pEndpoint->TxProcessCount = 0;
+ UNLOCK_HTC_TX(target);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n"));
+
+ return HTC_SEND_QUEUE_OK;
+}
+
+A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_ENDPOINT *pEndpoint;
+ HTC_PACKET *pPacket;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n",
+ (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue)));
+
+ /* get packet at head to figure out which endpoint these packets will go into */
+ pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue);
+ if (NULL == pPacket) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
+ return A_EINVAL;
+ }
+
+ AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX);
+ pEndpoint = &target->EndPoint[pPacket->Endpoint];
+
+ HTCTrySend(target, pEndpoint, pPktQueue);
+
+ /* do completion on any packets that couldn't get in */
+ if (!HTC_QUEUE_EMPTY(pPktQueue)) {
+
+ HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) {
+ if (HTC_STOPPING(target)) {
+ pPacket->Status = A_ECANCELED;
+ } else {
+ pPacket->Status = A_NO_RESOURCE;
+ }
+ } HTC_PACKET_QUEUE_ITERATE_END;
+
+ DO_EP_TX_COMPLETION(pEndpoint,pPktQueue);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n"));
+
+ return A_OK;
+}
+
+/* HTC API - HTCSendPkt */
+A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
+{
+ HTC_PACKET_QUEUE queue;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
+ ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n",
+ pPacket->Endpoint, (unsigned long)pPacket->pBuffer, pPacket->ActualLength));
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket);
+ return HTCSendPktsMultiple(HTCHandle, &queue);
+}
+
+/* check TX queues to drain because of credit distribution update */
+static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target)
+{
+ HTC_ENDPOINT *pEndpoint;
+ HTC_ENDPOINT_CREDIT_DIST *pDistItem;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n"));
+ pDistItem = target->EpCreditDistributionListHead;
+
+ /* run through the credit distribution list to see
+ * if there are packets queued
+ * NOTE: no locks need to be taken since the distribution list
+ * is not dynamic (cannot be re-ordered) and we are not modifying any state */
+ while (pDistItem != NULL) {
+ pEndpoint = (HTC_ENDPOINT *)pDistItem->pHTCReserved;
+
+ if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n",
+ pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)));
+ /* try to start the stalled queue, this list is ordered by priority.
+ * Highest priority queue get's processed first, if there are credits available the
+ * highest priority queue will get a chance to reclaim credits from lower priority
+ * ones */
+ HTCTrySend(target, pEndpoint, NULL);
+ }
+
+ pDistItem = pDistItem->pNext;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n"));
+}
+
+/* process credit reports and call distribution function */
+void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint)
+{
+ int i;
+ HTC_ENDPOINT *pEndpoint;
+ int totalCredits = 0;
+ A_BOOL doDist = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries));
+
+ /* lock out TX while we update credits */
+ LOCK_HTC_TX(target);
+
+ for (i = 0; i < NumEntries; i++, pRpt++) {
+ if (pRpt->EndpointID >= ENDPOINT_MAX) {
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+
+ pEndpoint = &target->EndPoint[pRpt->EndpointID];
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n",
+ pRpt->EndpointID, pRpt->Credits));
+
+
+#ifdef HTC_EP_STAT_PROFILING
+
+ INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
+ INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits);
+
+ if (FromEndpoint == pRpt->EndpointID) {
+ /* this credit report arrived on the same endpoint indicating it arrived in an RX
+ * packet */
+ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits);
+ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1);
+ } else if (FromEndpoint == ENDPOINT_0) {
+ /* this credit arrived on endpoint 0 as a NULL message */
+ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits);
+ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1);
+ } else {
+ /* arrived on another endpoint */
+ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits);
+ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
+ }
+
+#endif
+
+ if (ENDPOINT_0 == pRpt->EndpointID) {
+ /* always give endpoint 0 credits back */
+ pEndpoint->CreditDist.TxCredits += pRpt->Credits;
+ } else {
+ /* for all other endpoints, update credits to distribute, the distribution function
+ * will handle giving out credits back to the endpoints */
+ pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits;
+ /* flag that we have to do the distribution */
+ doDist = TRUE;
+ }
+
+ /* refresh tx depth for distribution function that will recover these credits
+ * NOTE: this is only valid when there are credits to recover! */
+ pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
+
+ totalCredits += pRpt->Credits;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits));
+
+ if (doDist) {
+ /* this was a credit return based on a completed send operations
+ * note, this is done with the lock held */
+ DO_DISTRIBUTION(target,
+ HTC_CREDIT_DIST_SEND_COMPLETE,
+ "Send Complete",
+ target->EpCreditDistributionListHead->pNext);
+ }
+
+ UNLOCK_HTC_TX(target);
+
+ if (totalCredits) {
+ HTCCheckEndpointTxQueues(target);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n"));
+}
+
+/* flush endpoint TX queue */
+static void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag)
+{
+ HTC_PACKET *pPacket;
+ HTC_PACKET_QUEUE discardQueue;
+ HTC_PACKET_QUEUE container;
+
+ /* initialize the discard queue */
+ INIT_HTC_PACKET_QUEUE(&discardQueue);
+
+ LOCK_HTC_TX(target);
+
+ /* interate from the front of the TX queue and flush out packets */
+ ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, HTC_PACKET, ListLink) {
+
+ /* check for removal */
+ if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) {
+ /* remove from queue */
+ HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket);
+ /* add it to the discard pile */
+ HTC_PACKET_ENQUEUE(&discardQueue, pPacket);
+ }
+
+ } ITERATE_END;
+
+ UNLOCK_HTC_TX(target);
+
+ /* empty the discard queue */
+ while (1) {
+ pPacket = HTC_PACKET_DEQUEUE(&discardQueue);
+ if (NULL == pPacket) {
+ break;
+ }
+ pPacket->Status = A_ECANCELED;
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%lX, length:%d, ep:%d tag:0x%X \n",
+ (unsigned long)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag));
+ INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket);
+ DO_EP_TX_COMPLETION(pEndpoint,&container);
+ }
+
+}
+
+void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n",
+ pEPDist->Endpoint, pEPDist->ServiceID));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%lX next:0x%lX prev:0x%lX\n",
+ (unsigned long)pEPDist, (unsigned long)pEPDist->pNext, (unsigned long)pEPDist->pPrev));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n",
+ HTC_PACKET_QUEUE_DEPTH(&((HTC_ENDPOINT *)pEPDist->pHTCReserved)->TxQueue)));
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n"));
+}
+
+void DumpCreditDistStates(HTC_TARGET *target)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pEPList = target->EpCreditDistributionListHead;
+
+ while (pEPList != NULL) {
+ DumpCreditDist(pEPList);
+ pEPList = pEPList->pNext;
+ }
+
+ if (target->DistributeCredits != NULL) {
+ DO_DISTRIBUTION(target,
+ HTC_DUMP_CREDIT_STATE,
+ "Dump State",
+ NULL);
+ }
+}
+
+/* flush all send packets from all endpoint queues */
+void HTCFlushSendPkts(HTC_TARGET *target)
+{
+ HTC_ENDPOINT *pEndpoint;
+ int i;
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
+ DumpCreditDistStates(target);
+ }
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ pEndpoint = &target->EndPoint[i];
+ if (pEndpoint->ServiceID == 0) {
+ /* not in use.. */
+ continue;
+ }
+ HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL);
+ }
+
+
+}
+
+/* HTC API to flush an endpoint's TX queue*/
+void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint];
+
+ if (pEndpoint->ServiceID == 0) {
+ AR_DEBUG_ASSERT(FALSE);
+ /* not in use.. */
+ return;
+ }
+
+ HTCFlushEndpointTX(target, pEndpoint, Tag);
+}
+
+/* HTC API to indicate activity to the credit distribution function */
+void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint,
+ A_BOOL Active)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint];
+ A_BOOL doDist = FALSE;
+
+ if (pEndpoint->ServiceID == 0) {
+ AR_DEBUG_ASSERT(FALSE);
+ /* not in use.. */
+ return;
+ }
+
+ LOCK_HTC_TX(target);
+
+ if (Active) {
+ if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) {
+ /* mark active now */
+ pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE;
+ doDist = TRUE;
+ }
+ } else {
+ if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
+ /* mark inactive now */
+ pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE;
+ doDist = TRUE;
+ }
+ }
+
+ if (doDist) {
+ /* indicate current Tx Queue depth to the credit distribution function */
+ pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue);
+ /* do distribution again based on activity change
+ * note, this is done with the lock held */
+ DO_DISTRIBUTION(target,
+ HTC_CREDIT_DIST_ACTIVITY_CHANGE,
+ "Activity Change",
+ target->EpCreditDistributionListHead->pNext);
+ }
+
+ UNLOCK_HTC_TX(target);
+
+ if (doDist && !Active) {
+ /* if a stream went inactive and this resulted in a credit distribution change,
+ * some credits may now be available for HTC packets that are stuck in
+ * HTC queues */
+ HTCCheckEndpointTxQueues(target);
+ }
+}
+
+A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint];
+
+ if (pEndpoint->ServiceID == 0) {
+ return FALSE;
+ }
+
+ if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c
new file mode 100644
index 000000000000..64fddc0ee376
--- /dev/null
+++ b/drivers/staging/ath6kl/htc2/htc_services.c
@@ -0,0 +1,450 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_services.c" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#include "htc_internal.h"
+
+void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket)
+{
+ /* not implemented
+ * we do not send control TX frames during normal runtime, only during setup */
+ AR_DEBUG_ASSERT(FALSE);
+}
+
+ /* callback when a control message arrives on this endpoint */
+void HTCControlRecv(void *Context, HTC_PACKET *pPacket)
+{
+ AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0);
+
+ if (pPacket->Status == A_ECANCELED) {
+ /* this is a flush operation, return the control packet back to the pool */
+ HTC_FREE_CONTROL_RX((HTC_TARGET*)Context,pPacket);
+ return;
+ }
+
+ /* the only control messages we are expecting are NULL messages (credit resports) */
+ if (pPacket->ActualLength > 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("HTCControlRecv, got message with length:%d \n",
+ pPacket->ActualLength + (A_UINT32)HTC_HDR_LENGTH));
+
+#ifdef ATH_DEBUG_MODULE
+ /* dump header and message */
+ DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
+ pPacket->ActualLength + HTC_HDR_LENGTH,
+ "Unexpected ENDPOINT 0 Message");
+#endif
+ }
+
+ HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->EndPoint[0]);
+}
+
+A_STATUS HTCSendSetupComplete(HTC_TARGET *target)
+{
+ HTC_PACKET *pSendPacket = NULL;
+ A_STATUS status;
+
+ do {
+ /* allocate a packet to send to the target */
+ pSendPacket = HTC_ALLOC_CONTROL_TX(target);
+
+ if (NULL == pSendPacket) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
+ HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
+ A_UINT32 setupFlags = 0;
+
+ pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer;
+ A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
+ pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;
+ if (target->MaxMsgPerBundle > 0) {
+ /* host can do HTC bundling, indicate this to the target */
+ setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
+ pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle;
+ }
+ A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));
+ SET_HTC_PACKET_INFO_TX(pSendPacket,
+ NULL,
+ (A_UINT8 *)pSetupCompleteEx,
+ sizeof(HTC_SETUP_COMPLETE_EX_MSG),
+ ENDPOINT_0,
+ HTC_SERVICE_TX_PACKET_TAG);
+
+ } else {
+ HTC_SETUP_COMPLETE_MSG *pSetupComplete;
+ /* assemble setup complete message */
+ pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
+ A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
+ pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;
+ SET_HTC_PACKET_INFO_TX(pSendPacket,
+ NULL,
+ (A_UINT8 *)pSetupComplete,
+ sizeof(HTC_SETUP_COMPLETE_MSG),
+ ENDPOINT_0,
+ HTC_SERVICE_TX_PACKET_TAG);
+ }
+
+ /* we want synchronous operation */
+ pSendPacket->Completion = NULL;
+ HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
+ /* send the message */
+ status = HTCIssueSend(target,pSendPacket);
+
+ } while (FALSE);
+
+ if (pSendPacket != NULL) {
+ HTC_FREE_CONTROL_TX(target,pSendPacket);
+ }
+
+ return status;
+}
+
+
+A_STATUS HTCConnectService(HTC_HANDLE HTCHandle,
+ HTC_SERVICE_CONNECT_REQ *pConnectReq,
+ HTC_SERVICE_CONNECT_RESP *pConnectResp)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ A_STATUS status = A_OK;
+ HTC_PACKET *pRecvPacket = NULL;
+ HTC_PACKET *pSendPacket = NULL;
+ HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg;
+ HTC_CONNECT_SERVICE_MSG *pConnectMsg;
+ HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX;
+ HTC_ENDPOINT *pEndpoint;
+ unsigned int maxMsgSize = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n",
+ (unsigned long)target, pConnectReq->ServiceID));
+
+ do {
+
+ AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);
+
+ if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
+ /* special case for pseudo control service */
+ assignedEndpoint = ENDPOINT_0;
+ maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
+ } else {
+ /* allocate a packet to send to the target */
+ pSendPacket = HTC_ALLOC_CONTROL_TX(target);
+
+ if (NULL == pSendPacket) {
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_NO_MEMORY;
+ break;
+ }
+ /* assemble connect service message */
+ pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
+ AR_DEBUG_ASSERT(pConnectMsg != NULL);
+ A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
+ pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
+ pConnectMsg->ServiceID = pConnectReq->ServiceID;
+ pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
+ /* check caller if it wants to transfer meta data */
+ if ((pConnectReq->pMetaData != NULL) &&
+ (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
+ /* copy meta data into message buffer (after header ) */
+ A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
+ pConnectReq->pMetaData,
+ pConnectReq->MetaDataLength);
+ pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
+ }
+
+ SET_HTC_PACKET_INFO_TX(pSendPacket,
+ NULL,
+ (A_UINT8 *)pConnectMsg,
+ sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
+ ENDPOINT_0,
+ HTC_SERVICE_TX_PACKET_TAG);
+
+ /* we want synchronous operation */
+ pSendPacket->Completion = NULL;
+ HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
+ status = HTCIssueSend(target,pSendPacket);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* wait for response */
+ status = HTCWaitforControlMessage(target, &pRecvPacket);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* we controlled the buffer creation so it has to be properly aligned */
+ pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;
+
+ if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
+ (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
+ /* this message is not valid */
+ AR_DEBUG_ASSERT(FALSE);
+ status = A_EPROTO;
+ break;
+ }
+
+ pConnectResp->ConnectRespCode = pResponseMsg->Status;
+ /* check response status */
+ if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ (" Target failed service 0x%X connect request (status:%d)\n",
+ pResponseMsg->ServiceID, pResponseMsg->Status));
+ status = A_EPROTO;
+ break;
+ }
+
+ assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
+ maxMsgSize = pResponseMsg->MaxMsgSize;
+
+ if ((pConnectResp->pMetaData != NULL) &&
+ (pResponseMsg->ServiceMetaLength > 0) &&
+ (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
+ /* caller supplied a buffer and the target responded with data */
+ int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
+ /* copy the meta data */
+ A_MEMCPY(pConnectResp->pMetaData,
+ ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
+ copyLength);
+ pConnectResp->ActualLength = copyLength;
+ }
+
+ }
+
+ /* the rest of these are parameter checks so set the error status */
+ status = A_EPROTO;
+
+ if (assignedEndpoint >= ENDPOINT_MAX) {
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+
+ if (0 == maxMsgSize) {
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+
+ pEndpoint = &target->EndPoint[assignedEndpoint];
+ pEndpoint->Id = assignedEndpoint;
+ if (pEndpoint->ServiceID != 0) {
+ /* endpoint already in use! */
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+
+ /* return assigned endpoint to caller */
+ pConnectResp->Endpoint = assignedEndpoint;
+ pConnectResp->MaxMsgLength = maxMsgSize;
+
+ /* setup the endpoint */
+ pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
+ pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
+ pEndpoint->MaxMsgLength = maxMsgSize;
+ /* copy all the callbacks */
+ pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
+ /* set the credit distribution info for this endpoint, this information is
+ * passed back to the credit distribution callback function */
+ pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
+ pEndpoint->CreditDist.pHTCReserved = pEndpoint;
+ pEndpoint->CreditDist.Endpoint = assignedEndpoint;
+ pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
+
+ if (pConnectReq->MaxSendMsgSize != 0) {
+ /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
+ * since the host will actually issue smaller messages in the Send path */
+ if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
+ /* can't be larger than the maximum the target can support */
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+ pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
+ } else {
+ pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
+ }
+
+ if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
+ pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
+ }
+
+ /* save local connection flags */
+ pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
+
+ status = A_OK;
+
+ } while (FALSE);
+
+ if (pSendPacket != NULL) {
+ HTC_FREE_CONTROL_TX(target,pSendPacket);
+ }
+
+ if (pRecvPacket != NULL) {
+ HTC_FREE_CONTROL_RX(target,pRecvPacket);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));
+
+ return status;
+}
+
+static void AddToEndpointDistList(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST *pEpDist)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEntry,*pLastEntry;
+
+ if (NULL == target->EpCreditDistributionListHead) {
+ target->EpCreditDistributionListHead = pEpDist;
+ pEpDist->pNext = NULL;
+ pEpDist->pPrev = NULL;
+ return;
+ }
+
+ /* queue to the end of the list, this does not have to be very
+ * fast since this list is built at startup time */
+ pCurEntry = target->EpCreditDistributionListHead;
+
+ while (pCurEntry) {
+ pLastEntry = pCurEntry;
+ pCurEntry = pCurEntry->pNext;
+ }
+
+ pLastEntry->pNext = pEpDist;
+ pEpDist->pPrev = pLastEntry;
+ pEpDist->pNext = NULL;
+}
+
+
+
+/* default credit init callback */
+static void HTCDefaultCreditInit(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPList,
+ int TotalCredits)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
+ int totalEps = 0;
+ int creditsPerEndpoint;
+
+ pCurEpDist = pEPList;
+ /* first run through the list and figure out how many endpoints we are dealing with */
+ while (pCurEpDist != NULL) {
+ pCurEpDist = pCurEpDist->pNext;
+ totalEps++;
+ }
+
+ /* even distribution */
+ creditsPerEndpoint = TotalCredits/totalEps;
+
+ pCurEpDist = pEPList;
+ /* run through the list and set minimum and normal credits and
+ * provide the endpoint with some credits to start */
+ while (pCurEpDist != NULL) {
+
+ if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) {
+ /* too many endpoints and not enough credits */
+ AR_DEBUG_ASSERT(FALSE);
+ break;
+ }
+ /* our minimum is set for at least 1 max message */
+ pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
+ /* this value is ignored by our credit alg, since we do
+ * not dynamically adjust credits, this is the policy of
+ * the "default" credit distribution, something simple and easy */
+ pCurEpDist->TxCreditsNorm = 0xFFFF;
+ /* give the endpoint minimum credits */
+ pCurEpDist->TxCredits = creditsPerEndpoint;
+ pCurEpDist->TxCreditsAssigned = creditsPerEndpoint;
+ pCurEpDist = pCurEpDist->pNext;
+ }
+
+}
+
+/* default credit distribution callback, NOTE, this callback holds the TX lock */
+void HTCDefaultCreditDist(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDistList,
+ HTC_CREDIT_DIST_REASON Reason)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
+
+ if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) {
+ pCurEpDist = pEPDistList;
+ /* simple distribution */
+ while (pCurEpDist != NULL) {
+ if (pCurEpDist->TxCreditsToDist > 0) {
+ /* just give the endpoint back the credits */
+ pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
+ pCurEpDist->TxCreditsToDist = 0;
+ }
+ pCurEpDist = pCurEpDist->pNext;
+ }
+ }
+
+ /* note we do not need to handle the other reason codes as this is a very
+ * simple distribution scheme, no need to seek for more credits or handle inactivity */
+}
+
+void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
+ void *pCreditDistContext,
+ HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
+ HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
+ HTC_SERVICE_ID ServicePriorityOrder[],
+ int ListLength)
+{
+ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
+ int i;
+ int ep;
+
+ if (CreditInitFunc != NULL) {
+ /* caller has supplied their own distribution functions */
+ target->InitCredits = CreditInitFunc;
+ AR_DEBUG_ASSERT(CreditDistFunc != NULL);
+ target->DistributeCredits = CreditDistFunc;
+ target->pCredDistContext = pCreditDistContext;
+ } else {
+ /* caller wants HTC to do distribution */
+ /* if caller wants service to handle distributions then
+ * it must set both of these to NULL! */
+ AR_DEBUG_ASSERT(CreditDistFunc == NULL);
+ target->InitCredits = HTCDefaultCreditInit;
+ target->DistributeCredits = HTCDefaultCreditDist;
+ target->pCredDistContext = target;
+ }
+
+ /* always add HTC control endpoint first, we only expose the list after the
+ * first one, this is added for TX queue checking */
+ AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist);
+
+ /* build the list of credit distribution structures in priority order
+ * supplied by the caller, these will follow endpoint 0 */
+ for (i = 0; i < ListLength; i++) {
+ /* match services with endpoints and add the endpoints to the distribution list
+ * in FIFO order */
+ for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
+ if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) {
+ /* queue this one to the list */
+ AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist);
+ break;
+ }
+ }
+ AR_DEBUG_ASSERT(ep < ENDPOINT_MAX);
+ }
+
+}
diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h
new file mode 100644
index 000000000000..4a0083c65113
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_config.h
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_config.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains software configuration options that enables
+// specific software "features"
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_CONFIG_H_
+#define _A_CONFIG_H_
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/config.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/config.h"
+#endif
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/config_linux.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/config_rexos.h"
+#endif
+
+#ifdef WIN_NWF
+#include "../os/windows/include/win/config_win.h"
+#endif
+
+#ifdef THREADX
+#include "../os/threadx/include/common/config_threadx.h"
+#endif
+
+#endif
diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h
new file mode 100644
index 000000000000..5a1b01fbb93c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_debug.h
@@ -0,0 +1,224 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_debug.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_DEBUG_H_
+#define _A_DEBUG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <a_types.h>
+#include <a_osapi.h>
+
+ /* standard debug print masks bits 0..7 */
+#define ATH_DEBUG_ERR (1 << 0) /* errors */
+#define ATH_DEBUG_WARN (1 << 1) /* warnings */
+#define ATH_DEBUG_INFO (1 << 2) /* informational (module startup info) */
+#define ATH_DEBUG_TRC (1 << 3) /* generic function call tracing */
+#define ATH_DEBUG_RSVD1 (1 << 4)
+#define ATH_DEBUG_RSVD2 (1 << 5)
+#define ATH_DEBUG_RSVD3 (1 << 6)
+#define ATH_DEBUG_RSVD4 (1 << 7)
+
+#define ATH_DEBUG_MASK_DEFAULTS (ATH_DEBUG_ERR | ATH_DEBUG_WARN)
+#define ATH_DEBUG_ANY 0xFFFF
+
+ /* other aliases used throughout */
+#define ATH_DEBUG_ERROR ATH_DEBUG_ERR
+#define ATH_LOG_ERR ATH_DEBUG_ERR
+#define ATH_LOG_INF ATH_DEBUG_INFO
+#define ATH_LOG_TRC ATH_DEBUG_TRC
+#define ATH_DEBUG_TRACE ATH_DEBUG_TRC
+#define ATH_DEBUG_INIT ATH_DEBUG_INFO
+
+ /* bits 8..31 are module-specific masks */
+#define ATH_DEBUG_MODULE_MASK_SHIFT 8
+
+ /* macro to make a module-specific masks */
+#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
+
+void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription);
+
+/* Debug support on a per-module basis
+ *
+ * Usage:
+ *
+ * Each module can utilize it's own debug mask variable. A set of commonly used
+ * masks are provided (ERRORS, WARNINGS, TRACE etc..). It is up to each module
+ * to define module-specific masks using the macros above.
+ *
+ * Each module defines a single debug mask variable debug_XXX where the "name" of the module is
+ * common to all C-files within that module. This requires every C-file that includes a_debug.h
+ * to define the module name in that file.
+ *
+ * Example:
+ *
+ * #define ATH_MODULE_NAME htc
+ * #include "a_debug.h"
+ *
+ * This will define a debug mask structure called debug_htc and all debug macros will reference this
+ * variable.
+ *
+ * A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro:
+ *
+ * #define ATH_DEBUG_MY_MASK1 ATH_DEBUG_MAKE_MODULE_MASK(0)
+ * #define ATH_DEBUG_MY_MASK2 ATH_DEBUG_MAKE_MODULE_MASK(1)
+ *
+ * The instantiation of the debug structure should be made by the module. When a module is
+ * instantiated, the module can set a description string, a default mask and an array of description
+ * entries containing information on each module-defined debug mask.
+ * NOTE: The instantiation is statically allocated, only one instance can exist per module.
+ *
+ * Example:
+ *
+ *
+ * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
+ *
+ * #ifdef DEBUG
+ * static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
+ * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask
+ * };
+ *
+ * ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
+ * "bmi" <== module name
+ * "Boot Manager Interface", <== description of module
+ * ATH_DEBUG_MASK_DEFAULTS, <== defaults
+ * ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
+ * bmi_debug_desc);
+ *
+ * #endif
+ *
+ * A module can optionally register it's debug module information in order for other tools to change the
+ * bit mask at runtime. A module can call A_REGISTER_MODULE_DEBUG_INFO() in it's module
+ * init code. This macro can be called multiple times without consequence. The debug info maintains
+ * state to indicate whether the information was previously registered.
+ *
+ * */
+
+#define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32
+#define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64
+
+typedef struct {
+ A_UINT32 Mask;
+ A_CHAR Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
+} ATH_DEBUG_MASK_DESCRIPTION;
+
+#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
+
+typedef struct _ATH_DEBUG_MODULE_DBG_INFO{
+ struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
+ A_CHAR ModuleName[16];
+ A_CHAR ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
+ A_UINT32 Flags;
+ A_UINT32 CurrentMask;
+ int MaxDescriptions;
+ ATH_DEBUG_MASK_DESCRIPTION *pMaskDescriptions; /* pointer to array of descriptions */
+} ATH_DEBUG_MODULE_DBG_INFO;
+
+#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(ATH_DEBUG_MASK_DESCRIPTION)))
+
+#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s)
+#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask
+#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s
+
+#ifdef ATH_DEBUG_MODULE
+
+ /* for source files that will instantiate the debug variables */
+#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \
+ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \
+ {NULL,(name),(moddesc),0,(initmask),count,(descriptions)}
+
+#ifdef ATH_MODULE_NAME
+extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME);
+#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl))
+#endif /* ATH_MODULE_NAME */
+
+#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl)
+
+#define ATH_DEBUG_DECLARE_EXTERN(s) \
+ extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s)
+
+#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc)
+
+
+#define AR_DEBUG_ASSERT A_ASSERT
+
+void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
+void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo);
+#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
+#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s)))
+
+#else /* !ATH_DEBUG_MODULE */
+ /* NON ATH_DEBUG_MODULE */
+#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions)
+#define AR_DEBUG_LVL_CHECK(lvl) 0
+#define AR_DEBUG_PRINTBUF(buffer, length, desc)
+#define AR_DEBUG_ASSERT(test)
+#define ATH_DEBUG_DECLARE_EXTERN(s)
+#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl)
+#define A_DUMP_MODULE_DEBUG_INFO(s)
+#define A_REGISTER_MODULE_DEBUG_INFO(s)
+
+#endif
+
+A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask);
+A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask);
+void a_dump_module_debug_info_by_name(A_CHAR *module_name);
+void a_module_debug_support_init(void);
+void a_module_debug_support_cleanup(void);
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/debug.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/debug.h"
+#endif
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/debug_linux.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/debug_rexos.h"
+#endif
+
+#if defined ART_WIN
+#include "../os/win_art/include/debug_win.h"
+#endif
+
+#ifdef WIN_NWF
+#include <debug_win.h>
+#endif
+
+#ifdef THREADX
+#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
+#include "../os/threadx/include/common/debug_threadx.h"
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h
new file mode 100644
index 000000000000..6db10f0f2d10
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_drv.h
@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_drv.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the definitions of the basic atheros data types.
+// It is used to map the data types in atheros files to a platform specific
+// type.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_DRV_H_
+#define _A_DRV_H_
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/athdrv_linux.h"
+#endif
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/athdrv.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/athdrv.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/athdrv_rexos.h"
+#endif
+
+#ifdef WIN_NWF
+#include "../os/windows/include/athdrv.h"
+#endif
+
+#ifdef THREADX
+#include "../os/threadx/include/common/athdrv_threadx.h"
+#endif
+
+#endif /* _ADRV_H_ */
diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h
new file mode 100644
index 000000000000..7d077c62ad70
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_drv_api.h
@@ -0,0 +1,232 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_drv_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_DRV_API_H_
+#define _A_DRV_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************/
+/****************************************************************************/
+/** **/
+/** WMI related hooks **/
+/** **/
+/****************************************************************************/
+/****************************************************************************/
+
+#include <ar6000_api.h>
+
+#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList) \
+ ar6000_channelList_rx((devt), (numChan), (chanList))
+
+#define A_WMI_SET_NUMDATAENDPTS(devt, num) \
+ ar6000_set_numdataendpts((devt), (num))
+
+#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \
+ ar6000_control_tx((devt), (osbuf), (streamID))
+
+#define A_WMI_TARGETSTATS_EVENT(devt, pStats, len) \
+ ar6000_targetStats_event((devt), (pStats), (len))
+
+#define A_WMI_SCANCOMPLETE_EVENT(devt, status) \
+ ar6000_scanComplete_event((devt), (status))
+
+#ifdef CONFIG_HOST_DSET_SUPPORT
+
+#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg) \
+ ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg))
+
+#define A_WMI_DSET_CLOSE(devt, access_cookie) \
+ ar6000_dset_close((devt), (access_cookie))
+
+#endif
+
+#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \
+ ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg))
+
+#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \
+ ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo))
+
+#define A_WMI_PSPOLL_EVENT(devt, aid)\
+ ar6000_pspoll_event((devt),(aid))
+
+#define A_WMI_DTIMEXPIRY_EVENT(devt)\
+ ar6000_dtimexpiry_event((devt))
+
+#ifdef WAPI_ENABLE
+#define A_WMI_WAPI_REKEY_EVENT(devt, type, mac)\
+ ap_wapi_rekey_event((devt),(type),(mac))
+#endif
+
+#define A_WMI_REGDOMAIN_EVENT(devt, regCode) \
+ ar6000_regDomain_event((devt), (regCode))
+
+#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info) \
+ ar6000_neighborReport_event((devt), (numAps), (info))
+
+#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \
+ ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus))
+
+#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast) \
+ ar6000_tkip_micerr_event((devt), (keyid), (ismcast))
+
+#define A_WMI_BITRATE_RX(devt, rateKbps) \
+ ar6000_bitrate_rx((devt), (rateKbps))
+
+#define A_WMI_TXPWR_RX(devt, txPwr) \
+ ar6000_txPwr_rx((devt), (txPwr))
+
+#define A_WMI_READY_EVENT(devt, datap, phyCap, sw_ver, abi_ver) \
+ ar6000_ready_event((devt), (datap), (phyCap), (sw_ver), (abi_ver))
+
+#define A_WMI_DBGLOG_INIT_DONE(ar) \
+ ar6000_dbglog_init_done(ar);
+
+#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi) \
+ ar6000_rssiThreshold_event((devt), (newThreshold), (rssi))
+
+#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal) \
+ ar6000_reportError_event((devt), (errorVal))
+
+#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \
+ ar6000_roam_tbl_event((devt), (pTbl))
+
+#define A_WMI_ROAM_DATA_EVENT(devt, p) \
+ ar6000_roam_data_event((devt), (p))
+
+#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters) \
+ ar6000_wow_list_event((devt), (num_filters), (wow_filters))
+
+#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion) \
+ ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion))
+
+#define A_WMI_CHANNEL_CHANGE_EVENT(devt, oldChannel, newChannel) \
+ ar6000_channel_change_event((devt), (oldChannel), (newChannel))
+
+#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list, bssid_list) \
+ ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list), (bssid_list))
+
+#define A_WMI_PEER_EVENT(devt, eventCode, bssid) \
+ ar6000_peer_event ((devt), (eventCode), (bssid))
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+
+#define A_WMI_GPIO_INTR_RX(intr_mask, input_values) \
+ ar6000_gpio_intr_rx((intr_mask), (input_values))
+
+#define A_WMI_GPIO_DATA_RX(reg_id, value) \
+ ar6000_gpio_data_rx((reg_id), (value))
+
+#define A_WMI_GPIO_ACK_RX() \
+ ar6000_gpio_ack_rx()
+
+#endif
+
+#ifdef SEND_EVENT_TO_APP
+
+#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \
+ ar6000_send_event_to_app((ar), (eventId), (datap), (len))
+
+#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) \
+ ar6000_send_generic_event_to_app((ar), (eventId), (datap), (len))
+
+#else
+
+#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len)
+#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len)
+
+#endif
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \
+ ar6000_tcmd_rx_report_event((devt), (results), (len))
+#endif
+
+#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \
+ ar6000_hbChallengeResp_event((devt), (cookie), (source))
+
+#define A_WMI_TX_RETRY_ERR_EVENT(devt) \
+ ar6000_tx_retry_err_event((devt))
+
+#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \
+ ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr))
+
+#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \
+ ar6000_lqThresholdEvent_rx((devt), (range), (lqVal))
+
+#define A_WMI_RATEMASK_RX(devt, ratemask) \
+ ar6000_ratemask_rx((devt), (ratemask))
+
+#define A_WMI_KEEPALIVE_RX(devt, configured) \
+ ar6000_keepalive_rx((devt), (configured))
+
+#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len) \
+ ar6000_bssInfo_event_rx((ar), (datap), (len))
+
+#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \
+ ar6000_dbglog_event((ar), (dropped), (buffer), (length));
+
+#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \
+ ar6000_indicate_tx_activity((devt),(trafficClass), TRUE)
+
+#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \
+ ar6000_indicate_tx_activity((devt),(trafficClass), FALSE)
+#define A_WMI_Ac2EndpointID(devht, ac)\
+ ar6000_ac2_endpoint_id((devht), (ac))
+
+#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, cmd)\
+ ar6000_aggr_rcv_addba_req_evt((devt), (cmd))
+#define A_WMI_AGGR_RECV_ADDBA_RESP_EVT(devt, cmd)\
+ ar6000_aggr_rcv_addba_resp_evt((devt), (cmd))
+#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, cmd)\
+ ar6000_aggr_rcv_delba_req_evt((devt), (cmd))
+#define A_WMI_HCI_EVENT_EVT(devt, cmd)\
+ ar6000_hci_event_rcv_evt((devt), (cmd))
+
+#define A_WMI_Endpoint2Ac(devt, ep) \
+ ar6000_endpoint_id2_ac((devt), (ep))
+
+#define A_WMI_BTCOEX_CONFIG_EVENT(devt, evt, len)\
+ ar6000_btcoex_config_event((devt), (evt), (len))
+
+#define A_WMI_BTCOEX_STATS_EVENT(devt, datap, len)\
+ ar6000_btcoex_stats_event((devt), (datap), (len))
+
+/****************************************************************************/
+/****************************************************************************/
+/** **/
+/** HTC related hooks **/
+/** **/
+/****************************************************************************/
+/****************************************************************************/
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+#define A_WMI_PROF_COUNT_RX(addr, count) prof_count_rx((addr), (count))
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h
new file mode 100644
index 000000000000..7bdeeea21503
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_osapi.h
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_osapi.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the definitions of the basic atheros data types.
+// It is used to map the data types in atheros files to a platform specific
+// type.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_OSAPI_H_
+#define _A_OSAPI_H_
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/osapi_linux.h"
+#endif
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/osapi.h"
+#include "../os/windows/include/netbuf.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/osapi.h"
+#include "../os/windows/include/netbuf.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/osapi_rexos.h"
+#endif
+
+#if defined ART_WIN
+#include "../os/win_art/include/osapi_win.h"
+#include "../os/win_art/include/netbuf.h"
+#endif
+
+#ifdef WIN_NWF
+#include <osapi_win.h>
+#endif
+
+#if defined(THREADX)
+#include "../os/threadx/include/common/osapi_threadx.h"
+#endif
+
+#endif /* _OSAPI_H_ */
diff --git a/drivers/staging/ath6kl/include/a_types.h b/drivers/staging/ath6kl/include/a_types.h
new file mode 100644
index 000000000000..18f4cfe4f97d
--- /dev/null
+++ b/drivers/staging/ath6kl/include/a_types.h
@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+// <copyright file="a_types.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the definitions of the basic atheros data types.
+// It is used to map the data types in atheros files to a platform specific
+// type.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _A_TYPES_H_
+#define _A_TYPES_H_
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/athtypes_linux.h"
+#endif
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/athtypes.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/athtypes.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/athtypes_rexos.h"
+#endif
+
+#if defined ART_WIN
+#include "../os/win_art/include/athtypes_win.h"
+#endif
+
+#ifdef WIN_NWF
+#include <athtypes_win.h>
+#endif
+
+#ifdef THREADX
+#include "../os/threadx/include/common/athtypes_threadx.h"
+#endif
+
+#endif /* _ATHTYPES_H_ */
diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h
new file mode 100644
index 000000000000..0682bb4edcf1
--- /dev/null
+++ b/drivers/staging/ath6kl/include/aggr_recv_api.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ *
+//
+// 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 __AGGR_RECV_API_H__
+#define __AGGR_RECV_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (* RX_CALLBACK)(void * dev, void *osbuf);
+
+typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, A_UINT16 num);
+
+/*
+ * aggr_init:
+ * Initialises the data structures, allocates data queues and
+ * os buffers. Netbuf allocator is the input param, used by the
+ * aggr module for allocation of NETBUFs from driver context.
+ * These NETBUFs are used for AMSDU processing.
+ * Returns the context for the aggr module.
+ */
+void *
+aggr_init(ALLOC_NETBUFS netbuf_allocator);
+
+
+/*
+ * aggr_register_rx_dispatcher:
+ * Registers OS call back function to deliver the
+ * frames to OS. This is generally the topmost layer of
+ * the driver context, after which the frames go to
+ * IP stack via the call back function.
+ * This dispatcher is active only when aggregation is ON.
+ */
+void
+aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn);
+
+
+/*
+ * aggr_process_bar:
+ * When target receives BAR, it communicates to host driver
+ * for modifying window parameters. Target indicates this via the
+ * event: WMI_ADDBA_REQ_EVENTID. Host will dequeue all frames
+ * up to the indicated sequence number.
+ */
+void
+aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no);
+
+
+/*
+ * aggr_recv_addba_req_evt:
+ * This event is to initiate/modify the receive side window.
+ * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup
+ * recv re-ordering queues. Target will negotiate ADDBA with peer,
+ * and indicate via this event after succesfully completing the
+ * negotiation. This happens in two situations:
+ * 1. Initial setup of aggregation
+ * 2. Renegotiation of current recv window.
+ * Window size for re-ordering is limited by target buffer
+ * space, which is reflected in win_sz.
+ * (Re)Start the periodic timer to deliver long standing frames,
+ * in hold_q to OS.
+ */
+void
+aggr_recv_addba_req_evt(void * cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_sz);
+
+
+/*
+ * aggr_recv_delba_req_evt:
+ * Target indicates deletion of a BA window for a tid via the
+ * WMI_DELBA_EVENTID. Host would deliver all the frames in the
+ * hold_q, reset tid config and disable the periodic timer, if
+ * aggr is not enabled on any tid.
+ */
+void
+aggr_recv_delba_req_evt(void * cntxt, A_UINT8 tid);
+
+
+
+/*
+ * aggr_process_recv_frm:
+ * Called only for data frames. When aggr is ON for a tid, the buffer
+ * is always consumed, and osbuf would be NULL. For a non-aggr case,
+ * osbuf is not modified.
+ * AMSDU frames are consumed and are later freed. They are sliced and
+ * diced to individual frames and dispatched to stack.
+ * After consuming a osbuf(when aggr is ON), a previously registered
+ * callback may be called to deliver frames in order.
+ */
+void
+aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf);
+
+
+/*
+ * aggr_module_destroy:
+ * Frees up all the queues and frames in them. Releases the cntxt to OS.
+ */
+void
+aggr_module_destroy(void *cntxt);
+
+/*
+ * Dumps the aggregation stats
+ */
+void
+aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf);
+
+/*
+ * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
+ * hold Q state. Examples include when a Connect event or disconnect event is
+ * received.
+ */
+void
+aggr_reset_state(void *cntxt);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__AGGR_RECV_API_H__ */
diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h
new file mode 100644
index 000000000000..a10788cee461
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar3kconfig.h
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+/* AR3K module configuration APIs for HCI-bridge operation */
+
+#ifndef AR3KCONFIG_H_
+#define AR3KCONFIG_H_
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT (1 << 0)
+#define AR3K_CONFIG_FLAG_SET_AR3K_BAUD (1 << 1)
+#define AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY (1 << 2)
+#define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP (1 << 3)
+
+
+typedef struct {
+ A_UINT32 Flags; /* config flags */
+ void *pHCIDev; /* HCI bridge device */
+ HCI_TRANSPORT_PROPERTIES *pHCIProps; /* HCI bridge props */
+ HIF_DEVICE *pHIFDevice; /* HIF layer device */
+
+ A_UINT32 AR3KBaudRate; /* AR3K operational baud rate */
+ A_UINT16 AR6KScale; /* AR6K UART scale value */
+ A_UINT16 AR6KStep; /* AR6K UART step value */
+ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
+ A_UINT32 PwrMgmtEnabled; /* TLPM enabled? */
+ A_UINT16 IdleTimeout; /* TLPM idle timeout */
+ A_UINT16 WakeupTimeout; /* TLPM wakeup timeout */
+ A_UINT8 bdaddr[6]; /* Bluetooth device address */
+} AR3K_CONFIG_INFO;
+
+A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo);
+
+A_STATUS AR3KConfigureExit(void *config);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*AR3KCONFIG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h
new file mode 100644
index 000000000000..1e1d92a507e2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6000_api.h
@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6000_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the API to access the OS dependent atheros host driver
+// by the WMI or WLAN generic modules.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _AR6000_API_H_
+#define _AR6000_API_H_
+
+#if defined(__linux__) && !defined(LINUX_EMULATION)
+#include "../os/linux/include/ar6xapi_linux.h"
+#endif
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/ar6xapi.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/ar6xapi.h"
+#endif
+
+#ifdef REXOS
+#include "../os/rexos/include/common/ar6xapi_rexos.h"
+#endif
+
+#if defined ART_WIN
+#include "../os/win_art/include/ar6xapi_win.h"
+#endif
+
+#ifdef WIN_NWF
+#include "../os/windows/include/ar6xapi.h"
+#endif
+
+#endif /* _AR6000_API_H */
+
diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h
new file mode 100644
index 000000000000..b53512e23d32
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6000_diag.h
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+// <copyright file="ar6000_diag.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef AR6000_DIAG_H_
+#define AR6000_DIAG_H_
+
+
+A_STATUS
+ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+
+A_STATUS
+ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+
+A_STATUS
+ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
+ A_UCHAR *data, A_UINT32 length);
+
+A_STATUS
+ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
+ A_UCHAR *data, A_UINT32 length);
+
+A_STATUS
+ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval);
+
+void
+ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs);
+
+#endif /*AR6000_DIAG_H_*/
diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h
new file mode 100644
index 000000000000..9b1b8bfae675
--- /dev/null
+++ b/drivers/staging/ath6kl/include/ar6kap_common.h
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+
+// <copyright file="ar6kap_common.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+
+//==============================================================================
+
+// This file contains the definitions of common AP mode data structures.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _AR6KAP_COMMON_H_
+#define _AR6KAP_COMMON_H_
+/*
+ * Used with AR6000_XIOCTL_AP_GET_STA_LIST
+ */
+typedef struct {
+ A_UINT8 mac[ATH_MAC_LEN];
+ A_UINT8 aid;
+ A_UINT8 keymgmt;
+ A_UINT8 ucipher;
+ A_UINT8 auth;
+} station_t;
+typedef struct {
+ station_t sta[AP_MAX_NUM_STA];
+} ap_get_sta_t;
+#endif /* _AR6KAP_COMMON_H_ */
diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h
new file mode 100644
index 000000000000..dbe68bbb727c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/athbtfilter.h
@@ -0,0 +1,135 @@
+//------------------------------------------------------------------------------
+// <copyright file="athbtfilter.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Public Bluetooth filter APIs
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef ATHBTFILTER_H_
+#define ATHBTFILTER_H_
+
+#define ATH_DEBUG_INFO (1 << 2)
+#define ATH_DEBUG_INF ATH_DEBUG_INFO
+
+typedef enum _ATHBT_HCI_CTRL_TYPE {
+ ATHBT_HCI_COMMAND = 0,
+ ATHBT_HCI_EVENT = 1,
+} ATHBT_HCI_CTRL_TYPE;
+
+typedef enum _ATHBT_STATE_INDICATION {
+ ATH_BT_NOOP = 0,
+ ATH_BT_INQUIRY = 1,
+ ATH_BT_CONNECT = 2,
+ ATH_BT_SCO = 3,
+ ATH_BT_ACL = 4,
+ ATH_BT_A2DP = 5,
+ ATH_BT_ESCO = 6,
+ /* new states go here.. */
+
+ ATH_BT_MAX_STATE_INDICATION
+} ATHBT_STATE_INDICATION;
+
+ /* filter function for OUTGOING commands and INCOMMING events */
+typedef void (*ATHBT_FILTER_CMD_EVENTS_FN)(void *pContext, ATHBT_HCI_CTRL_TYPE Type, unsigned char *pBuffer, int Length);
+
+ /* filter function for OUTGOING data HCI packets */
+typedef void (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length);
+
+typedef enum _ATHBT_STATE {
+ STATE_OFF = 0,
+ STATE_ON = 1,
+ STATE_MAX
+} ATHBT_STATE;
+
+ /* BT state indication (when filter functions are not used) */
+
+typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion);
+
+typedef struct _ATHBT_FILTER_INSTANCE {
+#ifdef UNDER_CE
+ WCHAR *pWlanAdapterName; /* filled in by user */
+#else
+ char *pWlanAdapterName; /* filled in by user */
+#endif /* UNDER_CE */
+ int FilterEnabled; /* filtering is enabled */
+ int Attached; /* filter library is attached */
+ void *pContext; /* private context for filter library */
+ ATHBT_FILTER_CMD_EVENTS_FN pFilterCmdEvents; /* function ptr to filter a command or event */
+ ATHBT_FILTER_DATA_FN pFilterAclDataOut; /* function ptr to filter ACL data out (to radio) */
+ ATHBT_FILTER_DATA_FN pFilterAclDataIn; /* function ptr to filter ACL data in (from radio) */
+ ATHBT_INDICATE_STATE_FN pIndicateState; /* function ptr to indicate a state */
+} ATH_BT_FILTER_INSTANCE;
+
+
+/* API MACROS */
+
+#define AthBtFilterHciCommand(instance,packet,length) \
+ if ((instance)->FilterEnabled) { \
+ (instance)->pFilterCmdEvents((instance)->pContext, \
+ ATHBT_HCI_COMMAND, \
+ (unsigned char *)(packet), \
+ (length)); \
+ }
+
+#define AthBtFilterHciEvent(instance,packet,length) \
+ if ((instance)->FilterEnabled) { \
+ (instance)->pFilterCmdEvents((instance)->pContext, \
+ ATHBT_HCI_EVENT, \
+ (unsigned char *)(packet), \
+ (length)); \
+ }
+
+#define AthBtFilterHciAclDataOut(instance,packet,length) \
+ if ((instance)->FilterEnabled) { \
+ (instance)->pFilterAclDataOut((instance)->pContext, \
+ (unsigned char *)(packet), \
+ (length)); \
+ }
+
+#define AthBtFilterHciAclDataIn(instance,packet,length) \
+ if ((instance)->FilterEnabled) { \
+ (instance)->pFilterAclDataIn((instance)->pContext, \
+ (unsigned char *)(packet), \
+ (length)); \
+ }
+
+/* if filtering is not desired, the application can indicate the state directly using this
+ * macro:
+ */
+#define AthBtIndicateState(instance,indication,state) \
+ if ((instance)->FilterEnabled) { \
+ (instance)->pIndicateState((instance)->pContext, \
+ (indication), \
+ (state), \
+ 0); \
+ }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API prototypes */
+int AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags);
+void AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ATHBTFILTER_H_*/
diff --git a/drivers/staging/ath6kl/include/athendpack.h b/drivers/staging/ath6kl/include/athendpack.h
new file mode 100644
index 000000000000..1b940503bb21
--- /dev/null
+++ b/drivers/staging/ath6kl/include/athendpack.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// <copyright file="athendpack.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// end compiler-specific structure packing
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifdef VXWORKS
+#endif /* VXWORKS */
+
+#if defined(LINUX) || defined(__linux__)
+#endif /* LINUX */
+
+#ifdef QNX
+#endif /* QNX */
+
+#ifdef INTEGRITY
+#include "integrity/athendpack_integrity.h"
+#endif /* INTEGRITY */
+
+#ifdef NUCLEUS
+#endif /* NUCLEUS */
+
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/athendpack.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/athendpack.h"
+#endif /* WINCE */
+
+#ifdef WIN_NWF
+#include <athendpack_win.h>
+#endif
diff --git a/drivers/staging/ath6kl/include/athstartpack.h b/drivers/staging/ath6kl/include/athstartpack.h
new file mode 100644
index 000000000000..1c45f666d8a2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/athstartpack.h
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+// <copyright file="athstartpack.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// start compiler-specific structure packing
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifdef VXWORKS
+#endif /* VXWORKS */
+
+#if defined(LINUX) || defined(__linux__)
+#endif /* LINUX */
+
+#ifdef QNX
+#endif /* QNX */
+
+#ifdef INTEGRITY
+#include "integrity/athstartpack_integrity.h"
+#endif /* INTEGRITY */
+
+#ifdef NUCLEUS
+#endif /* NUCLEUS */
+
+#ifdef UNDER_NWIFI
+#include "../os/windows/include/athstartpack.h"
+#endif
+
+#ifdef ATHR_CE_LEGACY
+#include "../os/windows/include/athstartpack.h"
+#endif /* WINCE */
+
+#ifdef WIN_NWF
+#include <athstartpack_win.h>
+#endif
+
+#ifdef THREADX
+#include "../os/threadx/include/common/osapi_threadx.h"
+#endif
diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h
new file mode 100644
index 000000000000..27aa98df9c0b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/bmi.h
@@ -0,0 +1,135 @@
+//------------------------------------------------------------------------------
+// <copyright file="bmi.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// BMI declarations and prototypes
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _BMI_H_
+#define _BMI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "hif.h"
+#include "a_osapi.h"
+#include "bmi_msg.h"
+
+void
+BMIInit(void);
+
+void
+BMICleanup(void);
+
+A_STATUS
+BMIDone(HIF_DEVICE *device);
+
+A_STATUS
+BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info);
+
+A_STATUS
+BMIReadMemory(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+BMIWriteMemory(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+BMIExecute(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 *param);
+
+A_STATUS
+BMISetAppStart(HIF_DEVICE *device,
+ A_UINT32 address);
+
+A_STATUS
+BMIReadSOCRegister(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 *param);
+
+A_STATUS
+BMIWriteSOCRegister(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UINT32 param);
+
+A_STATUS
+BMIrompatchInstall(HIF_DEVICE *device,
+ A_UINT32 ROM_addr,
+ A_UINT32 RAM_addr,
+ A_UINT32 nbytes,
+ A_UINT32 do_activate,
+ A_UINT32 *patch_id);
+
+A_STATUS
+BMIrompatchUninstall(HIF_DEVICE *device,
+ A_UINT32 rompatch_id);
+
+A_STATUS
+BMIrompatchActivate(HIF_DEVICE *device,
+ A_UINT32 rompatch_count,
+ A_UINT32 *rompatch_list);
+
+A_STATUS
+BMIrompatchDeactivate(HIF_DEVICE *device,
+ A_UINT32 rompatch_count,
+ A_UINT32 *rompatch_list);
+
+A_STATUS
+BMILZStreamStart(HIF_DEVICE *device,
+ A_UINT32 address);
+
+A_STATUS
+BMILZData(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+BMIFastDownload(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+BMIRawWrite(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length);
+
+A_STATUS
+BMIRawRead(HIF_DEVICE *device,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_BOOL want_timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h b/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h
new file mode 100644
index 000000000000..e3291cf4dbd4
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2006-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __AR6002_REGDUMP_H__
+#define __AR6002_REGDUMP_H__
+
+#if !defined(__ASSEMBLER__)
+/*
+ * XTensa CPU state
+ * This must match the state saved by the target exception handler.
+ */
+struct XTensa_exception_frame_s {
+ A_UINT32 xt_pc;
+ A_UINT32 xt_ps;
+ A_UINT32 xt_sar;
+ A_UINT32 xt_vpri;
+ A_UINT32 xt_a2;
+ A_UINT32 xt_a3;
+ A_UINT32 xt_a4;
+ A_UINT32 xt_a5;
+ A_UINT32 xt_exccause;
+ A_UINT32 xt_lcount;
+ A_UINT32 xt_lbeg;
+ A_UINT32 xt_lend;
+
+ A_UINT32 epc1, epc2, epc3, epc4;
+
+ /* Extra info to simplify post-mortem stack walkback */
+#define AR6002_REGDUMP_FRAMES 10
+ struct {
+ A_UINT32 a0; /* pc */
+ A_UINT32 a1; /* sp */
+ A_UINT32 a2;
+ A_UINT32 a3;
+ } wb[AR6002_REGDUMP_FRAMES];
+};
+typedef struct XTensa_exception_frame_s CPU_exception_frame_t;
+#define RD_SIZE sizeof(CPU_exception_frame_t)
+
+#endif
+#endif /* __AR6002_REGDUMP_H__ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
new file mode 100644
index 000000000000..5407e05d9b05
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// <copyright file="AR6K_version.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#define __VER_MAJOR_ 3
+#define __VER_MINOR_ 0
+#define __VER_PATCH_ 0
+
+/* The makear6ksdk script (used for release builds) modifies the following line. */
+#define __BUILD_NUMBER_ 233
+
+
+/* Format of the version number. */
+#define VER_MAJOR_BIT_OFFSET 28
+#define VER_MINOR_BIT_OFFSET 24
+#define VER_PATCH_BIT_OFFSET 16
+#define VER_BUILD_NUM_BIT_OFFSET 0
+
+
+/*
+ * The version has the following format:
+ * Bits 28-31: Major version
+ * Bits 24-27: Minor version
+ * Bits 16-23: Patch version
+ * Bits 0-15: Build number (automatically generated during build process )
+ * E.g. Build 1.1.3.7 would be represented as 0x11030007.
+ *
+ * DO NOT split the following macro into multiple lines as this may confuse the build scripts.
+ */
+#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) )
+
+/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly */
+#define AR6K_ABI_VERSION 1
diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
new file mode 100644
index 000000000000..eaaccf4cad7b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/addrs.h
@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef __ADDRS_H__
+#define __ADDRS_H__
+
+/*
+ * Special AR6002 Addresses that may be needed by special
+ * applications (e.g. ART) on the Host as well as Target.
+ */
+
+#if defined(AR6002_REV2)
+#define AR6K_RAM_START 0x00500000
+#define TARG_RAM_OFFSET(vaddr) ((A_UINT32)(vaddr) & 0xfffff)
+#define TARG_RAM_SZ (184*1024)
+#define TARG_ROM_SZ (80*1024)
+#endif
+#if defined(AR6002_REV4) || defined(AR6003)
+#define AR6K_RAM_START 0x00540000
+#define TARG_RAM_OFFSET(vaddr) (((A_UINT32)(vaddr) & 0xfffff) - 0x40000)
+#define TARG_RAM_SZ (256*1024)
+#define TARG_ROM_SZ (256*1024)
+#endif
+
+#define AR6002_BOARD_DATA_SZ 768
+#define AR6002_BOARD_EXT_DATA_SZ 0
+#define AR6003_BOARD_DATA_SZ 1024
+#define AR6003_BOARD_EXT_DATA_SZ 768
+
+#define AR6K_RAM_ADDR(byte_offset) (AR6K_RAM_START+(byte_offset))
+#define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset)
+
+#define AR6K_ROM_START 0x004e0000
+#define TARG_ROM_OFFSET(vaddr) (((A_UINT32)(vaddr) & 0x1fffff) - 0xe0000)
+#define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset))
+#define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset)
+
+/*
+ * At this ROM address is a pointer to the start of the ROM DataSet Index.
+ * If there are no ROM DataSets, there's a 0 at this address.
+ */
+#define ROM_DATASET_INDEX_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-8)
+#define ROM_MBIST_CKSUM_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-4)
+
+/*
+ * The API A_BOARD_DATA_ADDR() is the proper way to get a read pointer to
+ * board data.
+ */
+
+/* Size of Board Data, in bytes */
+#if defined(AR6002_REV4) || defined(AR6003)
+#define BOARD_DATA_SZ AR6003_BOARD_DATA_SZ
+#else
+#define BOARD_DATA_SZ AR6002_BOARD_DATA_SZ
+#endif
+
+
+/*
+ * Constants used by ASM code to access fields of host_interest_s,
+ * which is at a fixed location in RAM.
+ */
+#if defined(AR6002_REV4) || defined(AR6003)
+#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x60c)
+#else
+#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x40c)
+#endif
+#define FLASH_IS_PRESENT_TARGADDR HOST_INTEREST_FLASH_IS_PRESENT_ADDR
+
+#endif /* __ADDRS_H__ */
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h
new file mode 100644
index 000000000000..9c82767b6efb
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h
@@ -0,0 +1,64 @@
+#ifndef _ANALOG_INTF_REG_REG_H_
+#define _ANALOG_INTF_REG_REG_H_
+
+#define SW_OVERRIDE_ADDRESS 0x00000080
+#define SW_OVERRIDE_OFFSET 0x00000080
+#define SW_OVERRIDE_SUPDATE_DELAY_MSB 1
+#define SW_OVERRIDE_SUPDATE_DELAY_LSB 1
+#define SW_OVERRIDE_SUPDATE_DELAY_MASK 0x00000002
+#define SW_OVERRIDE_SUPDATE_DELAY_GET(x) (((x) & SW_OVERRIDE_SUPDATE_DELAY_MASK) >> SW_OVERRIDE_SUPDATE_DELAY_LSB)
+#define SW_OVERRIDE_SUPDATE_DELAY_SET(x) (((x) << SW_OVERRIDE_SUPDATE_DELAY_LSB) & SW_OVERRIDE_SUPDATE_DELAY_MASK)
+#define SW_OVERRIDE_ENABLE_MSB 0
+#define SW_OVERRIDE_ENABLE_LSB 0
+#define SW_OVERRIDE_ENABLE_MASK 0x00000001
+#define SW_OVERRIDE_ENABLE_GET(x) (((x) & SW_OVERRIDE_ENABLE_MASK) >> SW_OVERRIDE_ENABLE_LSB)
+#define SW_OVERRIDE_ENABLE_SET(x) (((x) << SW_OVERRIDE_ENABLE_LSB) & SW_OVERRIDE_ENABLE_MASK)
+
+#define SIN_VAL_ADDRESS 0x00000084
+#define SIN_VAL_OFFSET 0x00000084
+#define SIN_VAL_SIN_MSB 0
+#define SIN_VAL_SIN_LSB 0
+#define SIN_VAL_SIN_MASK 0x00000001
+#define SIN_VAL_SIN_GET(x) (((x) & SIN_VAL_SIN_MASK) >> SIN_VAL_SIN_LSB)
+#define SIN_VAL_SIN_SET(x) (((x) << SIN_VAL_SIN_LSB) & SIN_VAL_SIN_MASK)
+
+#define SW_SCLK_ADDRESS 0x00000088
+#define SW_SCLK_OFFSET 0x00000088
+#define SW_SCLK_SW_SCLK_MSB 0
+#define SW_SCLK_SW_SCLK_LSB 0
+#define SW_SCLK_SW_SCLK_MASK 0x00000001
+#define SW_SCLK_SW_SCLK_GET(x) (((x) & SW_SCLK_SW_SCLK_MASK) >> SW_SCLK_SW_SCLK_LSB)
+#define SW_SCLK_SW_SCLK_SET(x) (((x) << SW_SCLK_SW_SCLK_LSB) & SW_SCLK_SW_SCLK_MASK)
+
+#define SW_CNTL_ADDRESS 0x0000008c
+#define SW_CNTL_OFFSET 0x0000008c
+#define SW_CNTL_SW_SCAPTURE_MSB 2
+#define SW_CNTL_SW_SCAPTURE_LSB 2
+#define SW_CNTL_SW_SCAPTURE_MASK 0x00000004
+#define SW_CNTL_SW_SCAPTURE_GET(x) (((x) & SW_CNTL_SW_SCAPTURE_MASK) >> SW_CNTL_SW_SCAPTURE_LSB)
+#define SW_CNTL_SW_SCAPTURE_SET(x) (((x) << SW_CNTL_SW_SCAPTURE_LSB) & SW_CNTL_SW_SCAPTURE_MASK)
+#define SW_CNTL_SW_SUPDATE_MSB 1
+#define SW_CNTL_SW_SUPDATE_LSB 1
+#define SW_CNTL_SW_SUPDATE_MASK 0x00000002
+#define SW_CNTL_SW_SUPDATE_GET(x) (((x) & SW_CNTL_SW_SUPDATE_MASK) >> SW_CNTL_SW_SUPDATE_LSB)
+#define SW_CNTL_SW_SUPDATE_SET(x) (((x) << SW_CNTL_SW_SUPDATE_LSB) & SW_CNTL_SW_SUPDATE_MASK)
+#define SW_CNTL_SW_SOUT_MSB 0
+#define SW_CNTL_SW_SOUT_LSB 0
+#define SW_CNTL_SW_SOUT_MASK 0x00000001
+#define SW_CNTL_SW_SOUT_GET(x) (((x) & SW_CNTL_SW_SOUT_MASK) >> SW_CNTL_SW_SOUT_LSB)
+#define SW_CNTL_SW_SOUT_SET(x) (((x) << SW_CNTL_SW_SOUT_LSB) & SW_CNTL_SW_SOUT_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct analog_intf_reg_reg_s {
+ unsigned char pad0[128]; /* pad to 0x80 */
+ volatile unsigned int sw_override;
+ volatile unsigned int sin_val;
+ volatile unsigned int sw_sclk;
+ volatile unsigned int sw_cntl;
+} analog_intf_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _ANALOG_INTF_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h
new file mode 100644
index 000000000000..cf562b86f655
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h
@@ -0,0 +1,1932 @@
+#ifndef _ANALOG_REG_REG_H_
+#define _ANALOG_REG_REG_H_
+
+#define SYNTH_SYNTH1_ADDRESS 0x00000000
+#define SYNTH_SYNTH1_OFFSET 0x00000000
+#define SYNTH_SYNTH1_PWD_BIAS_MSB 31
+#define SYNTH_SYNTH1_PWD_BIAS_LSB 31
+#define SYNTH_SYNTH1_PWD_BIAS_MASK 0x80000000
+#define SYNTH_SYNTH1_PWD_BIAS_GET(x) (((x) & SYNTH_SYNTH1_PWD_BIAS_MASK) >> SYNTH_SYNTH1_PWD_BIAS_LSB)
+#define SYNTH_SYNTH1_PWD_BIAS_SET(x) (((x) << SYNTH_SYNTH1_PWD_BIAS_LSB) & SYNTH_SYNTH1_PWD_BIAS_MASK)
+#define SYNTH_SYNTH1_PWD_CP_MSB 30
+#define SYNTH_SYNTH1_PWD_CP_LSB 30
+#define SYNTH_SYNTH1_PWD_CP_MASK 0x40000000
+#define SYNTH_SYNTH1_PWD_CP_GET(x) (((x) & SYNTH_SYNTH1_PWD_CP_MASK) >> SYNTH_SYNTH1_PWD_CP_LSB)
+#define SYNTH_SYNTH1_PWD_CP_SET(x) (((x) << SYNTH_SYNTH1_PWD_CP_LSB) & SYNTH_SYNTH1_PWD_CP_MASK)
+#define SYNTH_SYNTH1_PWD_VCMON_MSB 29
+#define SYNTH_SYNTH1_PWD_VCMON_LSB 29
+#define SYNTH_SYNTH1_PWD_VCMON_MASK 0x20000000
+#define SYNTH_SYNTH1_PWD_VCMON_GET(x) (((x) & SYNTH_SYNTH1_PWD_VCMON_MASK) >> SYNTH_SYNTH1_PWD_VCMON_LSB)
+#define SYNTH_SYNTH1_PWD_VCMON_SET(x) (((x) << SYNTH_SYNTH1_PWD_VCMON_LSB) & SYNTH_SYNTH1_PWD_VCMON_MASK)
+#define SYNTH_SYNTH1_PWD_VCO_MSB 28
+#define SYNTH_SYNTH1_PWD_VCO_LSB 28
+#define SYNTH_SYNTH1_PWD_VCO_MASK 0x10000000
+#define SYNTH_SYNTH1_PWD_VCO_GET(x) (((x) & SYNTH_SYNTH1_PWD_VCO_MASK) >> SYNTH_SYNTH1_PWD_VCO_LSB)
+#define SYNTH_SYNTH1_PWD_VCO_SET(x) (((x) << SYNTH_SYNTH1_PWD_VCO_LSB) & SYNTH_SYNTH1_PWD_VCO_MASK)
+#define SYNTH_SYNTH1_PWD_PRESC_MSB 27
+#define SYNTH_SYNTH1_PWD_PRESC_LSB 27
+#define SYNTH_SYNTH1_PWD_PRESC_MASK 0x08000000
+#define SYNTH_SYNTH1_PWD_PRESC_GET(x) (((x) & SYNTH_SYNTH1_PWD_PRESC_MASK) >> SYNTH_SYNTH1_PWD_PRESC_LSB)
+#define SYNTH_SYNTH1_PWD_PRESC_SET(x) (((x) << SYNTH_SYNTH1_PWD_PRESC_LSB) & SYNTH_SYNTH1_PWD_PRESC_MASK)
+#define SYNTH_SYNTH1_PWD_LODIV_MSB 26
+#define SYNTH_SYNTH1_PWD_LODIV_LSB 26
+#define SYNTH_SYNTH1_PWD_LODIV_MASK 0x04000000
+#define SYNTH_SYNTH1_PWD_LODIV_GET(x) (((x) & SYNTH_SYNTH1_PWD_LODIV_MASK) >> SYNTH_SYNTH1_PWD_LODIV_LSB)
+#define SYNTH_SYNTH1_PWD_LODIV_SET(x) (((x) << SYNTH_SYNTH1_PWD_LODIV_LSB) & SYNTH_SYNTH1_PWD_LODIV_MASK)
+#define SYNTH_SYNTH1_PWD_LOMIX_MSB 25
+#define SYNTH_SYNTH1_PWD_LOMIX_LSB 25
+#define SYNTH_SYNTH1_PWD_LOMIX_MASK 0x02000000
+#define SYNTH_SYNTH1_PWD_LOMIX_GET(x) (((x) & SYNTH_SYNTH1_PWD_LOMIX_MASK) >> SYNTH_SYNTH1_PWD_LOMIX_LSB)
+#define SYNTH_SYNTH1_PWD_LOMIX_SET(x) (((x) << SYNTH_SYNTH1_PWD_LOMIX_LSB) & SYNTH_SYNTH1_PWD_LOMIX_MASK)
+#define SYNTH_SYNTH1_FORCE_LO_ON_MSB 24
+#define SYNTH_SYNTH1_FORCE_LO_ON_LSB 24
+#define SYNTH_SYNTH1_FORCE_LO_ON_MASK 0x01000000
+#define SYNTH_SYNTH1_FORCE_LO_ON_GET(x) (((x) & SYNTH_SYNTH1_FORCE_LO_ON_MASK) >> SYNTH_SYNTH1_FORCE_LO_ON_LSB)
+#define SYNTH_SYNTH1_FORCE_LO_ON_SET(x) (((x) << SYNTH_SYNTH1_FORCE_LO_ON_LSB) & SYNTH_SYNTH1_FORCE_LO_ON_MASK)
+#define SYNTH_SYNTH1_PWD_LOBUF5G_MSB 23
+#define SYNTH_SYNTH1_PWD_LOBUF5G_LSB 23
+#define SYNTH_SYNTH1_PWD_LOBUF5G_MASK 0x00800000
+#define SYNTH_SYNTH1_PWD_LOBUF5G_GET(x) (((x) & SYNTH_SYNTH1_PWD_LOBUF5G_MASK) >> SYNTH_SYNTH1_PWD_LOBUF5G_LSB)
+#define SYNTH_SYNTH1_PWD_LOBUF5G_SET(x) (((x) << SYNTH_SYNTH1_PWD_LOBUF5G_LSB) & SYNTH_SYNTH1_PWD_LOBUF5G_MASK)
+#define SYNTH_SYNTH1_VCOREGBYPASS_MSB 22
+#define SYNTH_SYNTH1_VCOREGBYPASS_LSB 22
+#define SYNTH_SYNTH1_VCOREGBYPASS_MASK 0x00400000
+#define SYNTH_SYNTH1_VCOREGBYPASS_GET(x) (((x) & SYNTH_SYNTH1_VCOREGBYPASS_MASK) >> SYNTH_SYNTH1_VCOREGBYPASS_LSB)
+#define SYNTH_SYNTH1_VCOREGBYPASS_SET(x) (((x) << SYNTH_SYNTH1_VCOREGBYPASS_LSB) & SYNTH_SYNTH1_VCOREGBYPASS_MASK)
+#define SYNTH_SYNTH1_VCOREGLEVEL_MSB 21
+#define SYNTH_SYNTH1_VCOREGLEVEL_LSB 20
+#define SYNTH_SYNTH1_VCOREGLEVEL_MASK 0x00300000
+#define SYNTH_SYNTH1_VCOREGLEVEL_GET(x) (((x) & SYNTH_SYNTH1_VCOREGLEVEL_MASK) >> SYNTH_SYNTH1_VCOREGLEVEL_LSB)
+#define SYNTH_SYNTH1_VCOREGLEVEL_SET(x) (((x) << SYNTH_SYNTH1_VCOREGLEVEL_LSB) & SYNTH_SYNTH1_VCOREGLEVEL_MASK)
+#define SYNTH_SYNTH1_VCOREGBIAS_MSB 19
+#define SYNTH_SYNTH1_VCOREGBIAS_LSB 18
+#define SYNTH_SYNTH1_VCOREGBIAS_MASK 0x000c0000
+#define SYNTH_SYNTH1_VCOREGBIAS_GET(x) (((x) & SYNTH_SYNTH1_VCOREGBIAS_MASK) >> SYNTH_SYNTH1_VCOREGBIAS_LSB)
+#define SYNTH_SYNTH1_VCOREGBIAS_SET(x) (((x) << SYNTH_SYNTH1_VCOREGBIAS_LSB) & SYNTH_SYNTH1_VCOREGBIAS_MASK)
+#define SYNTH_SYNTH1_SLIDINGIF_MSB 17
+#define SYNTH_SYNTH1_SLIDINGIF_LSB 17
+#define SYNTH_SYNTH1_SLIDINGIF_MASK 0x00020000
+#define SYNTH_SYNTH1_SLIDINGIF_GET(x) (((x) & SYNTH_SYNTH1_SLIDINGIF_MASK) >> SYNTH_SYNTH1_SLIDINGIF_LSB)
+#define SYNTH_SYNTH1_SLIDINGIF_SET(x) (((x) << SYNTH_SYNTH1_SLIDINGIF_LSB) & SYNTH_SYNTH1_SLIDINGIF_MASK)
+#define SYNTH_SYNTH1_SPARE_PWD_MSB 16
+#define SYNTH_SYNTH1_SPARE_PWD_LSB 16
+#define SYNTH_SYNTH1_SPARE_PWD_MASK 0x00010000
+#define SYNTH_SYNTH1_SPARE_PWD_GET(x) (((x) & SYNTH_SYNTH1_SPARE_PWD_MASK) >> SYNTH_SYNTH1_SPARE_PWD_LSB)
+#define SYNTH_SYNTH1_SPARE_PWD_SET(x) (((x) << SYNTH_SYNTH1_SPARE_PWD_LSB) & SYNTH_SYNTH1_SPARE_PWD_MASK)
+#define SYNTH_SYNTH1_CON_VDDVCOREG_MSB 15
+#define SYNTH_SYNTH1_CON_VDDVCOREG_LSB 15
+#define SYNTH_SYNTH1_CON_VDDVCOREG_MASK 0x00008000
+#define SYNTH_SYNTH1_CON_VDDVCOREG_GET(x) (((x) & SYNTH_SYNTH1_CON_VDDVCOREG_MASK) >> SYNTH_SYNTH1_CON_VDDVCOREG_LSB)
+#define SYNTH_SYNTH1_CON_VDDVCOREG_SET(x) (((x) << SYNTH_SYNTH1_CON_VDDVCOREG_LSB) & SYNTH_SYNTH1_CON_VDDVCOREG_MASK)
+#define SYNTH_SYNTH1_CON_IVCOREG_MSB 14
+#define SYNTH_SYNTH1_CON_IVCOREG_LSB 14
+#define SYNTH_SYNTH1_CON_IVCOREG_MASK 0x00004000
+#define SYNTH_SYNTH1_CON_IVCOREG_GET(x) (((x) & SYNTH_SYNTH1_CON_IVCOREG_MASK) >> SYNTH_SYNTH1_CON_IVCOREG_LSB)
+#define SYNTH_SYNTH1_CON_IVCOREG_SET(x) (((x) << SYNTH_SYNTH1_CON_IVCOREG_LSB) & SYNTH_SYNTH1_CON_IVCOREG_MASK)
+#define SYNTH_SYNTH1_CON_IVCOBUF_MSB 13
+#define SYNTH_SYNTH1_CON_IVCOBUF_LSB 13
+#define SYNTH_SYNTH1_CON_IVCOBUF_MASK 0x00002000
+#define SYNTH_SYNTH1_CON_IVCOBUF_GET(x) (((x) & SYNTH_SYNTH1_CON_IVCOBUF_MASK) >> SYNTH_SYNTH1_CON_IVCOBUF_LSB)
+#define SYNTH_SYNTH1_CON_IVCOBUF_SET(x) (((x) << SYNTH_SYNTH1_CON_IVCOBUF_LSB) & SYNTH_SYNTH1_CON_IVCOBUF_MASK)
+#define SYNTH_SYNTH1_SEL_VCMONABUS_MSB 12
+#define SYNTH_SYNTH1_SEL_VCMONABUS_LSB 10
+#define SYNTH_SYNTH1_SEL_VCMONABUS_MASK 0x00001c00
+#define SYNTH_SYNTH1_SEL_VCMONABUS_GET(x) (((x) & SYNTH_SYNTH1_SEL_VCMONABUS_MASK) >> SYNTH_SYNTH1_SEL_VCMONABUS_LSB)
+#define SYNTH_SYNTH1_SEL_VCMONABUS_SET(x) (((x) << SYNTH_SYNTH1_SEL_VCMONABUS_LSB) & SYNTH_SYNTH1_SEL_VCMONABUS_MASK)
+#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_MSB 9
+#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB 9
+#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK 0x00000200
+#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_GET(x) (((x) & SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK) >> SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB)
+#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_SET(x) (((x) << SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB) & SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK)
+#define SYNTH_SYNTH1_PWUP_LODIV_PD_MSB 8
+#define SYNTH_SYNTH1_PWUP_LODIV_PD_LSB 8
+#define SYNTH_SYNTH1_PWUP_LODIV_PD_MASK 0x00000100
+#define SYNTH_SYNTH1_PWUP_LODIV_PD_GET(x) (((x) & SYNTH_SYNTH1_PWUP_LODIV_PD_MASK) >> SYNTH_SYNTH1_PWUP_LODIV_PD_LSB)
+#define SYNTH_SYNTH1_PWUP_LODIV_PD_SET(x) (((x) << SYNTH_SYNTH1_PWUP_LODIV_PD_LSB) & SYNTH_SYNTH1_PWUP_LODIV_PD_MASK)
+#define SYNTH_SYNTH1_PWUP_LOMIX_PD_MSB 7
+#define SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB 7
+#define SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK 0x00000080
+#define SYNTH_SYNTH1_PWUP_LOMIX_PD_GET(x) (((x) & SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK) >> SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB)
+#define SYNTH_SYNTH1_PWUP_LOMIX_PD_SET(x) (((x) << SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB) & SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK)
+#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MSB 6
+#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB 6
+#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK 0x00000040
+#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_GET(x) (((x) & SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK) >> SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB)
+#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_SET(x) (((x) << SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB) & SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK)
+#define SYNTH_SYNTH1_MONITOR_FB_MSB 5
+#define SYNTH_SYNTH1_MONITOR_FB_LSB 5
+#define SYNTH_SYNTH1_MONITOR_FB_MASK 0x00000020
+#define SYNTH_SYNTH1_MONITOR_FB_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_FB_MASK) >> SYNTH_SYNTH1_MONITOR_FB_LSB)
+#define SYNTH_SYNTH1_MONITOR_FB_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_FB_LSB) & SYNTH_SYNTH1_MONITOR_FB_MASK)
+#define SYNTH_SYNTH1_MONITOR_REF_MSB 4
+#define SYNTH_SYNTH1_MONITOR_REF_LSB 4
+#define SYNTH_SYNTH1_MONITOR_REF_MASK 0x00000010
+#define SYNTH_SYNTH1_MONITOR_REF_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_REF_MASK) >> SYNTH_SYNTH1_MONITOR_REF_LSB)
+#define SYNTH_SYNTH1_MONITOR_REF_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_REF_LSB) & SYNTH_SYNTH1_MONITOR_REF_MASK)
+#define SYNTH_SYNTH1_MONITOR_FB_DIV2_MSB 3
+#define SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB 3
+#define SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK 0x00000008
+#define SYNTH_SYNTH1_MONITOR_FB_DIV2_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK) >> SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB)
+#define SYNTH_SYNTH1_MONITOR_FB_DIV2_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB) & SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK)
+#define SYNTH_SYNTH1_MONITOR_VC2HIGH_MSB 2
+#define SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB 2
+#define SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK 0x00000004
+#define SYNTH_SYNTH1_MONITOR_VC2HIGH_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK) >> SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB)
+#define SYNTH_SYNTH1_MONITOR_VC2HIGH_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB) & SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK)
+#define SYNTH_SYNTH1_MONITOR_VC2LOW_MSB 1
+#define SYNTH_SYNTH1_MONITOR_VC2LOW_LSB 1
+#define SYNTH_SYNTH1_MONITOR_VC2LOW_MASK 0x00000002
+#define SYNTH_SYNTH1_MONITOR_VC2LOW_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_VC2LOW_MASK) >> SYNTH_SYNTH1_MONITOR_VC2LOW_LSB)
+#define SYNTH_SYNTH1_MONITOR_VC2LOW_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_VC2LOW_LSB) & SYNTH_SYNTH1_MONITOR_VC2LOW_MASK)
+#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB 0
+#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB 0
+#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK 0x00000001
+#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK) >> SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB)
+#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB) & SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK)
+
+#define SYNTH_SYNTH2_ADDRESS 0x00000004
+#define SYNTH_SYNTH2_OFFSET 0x00000004
+#define SYNTH_SYNTH2_VC_CAL_REF_MSB 31
+#define SYNTH_SYNTH2_VC_CAL_REF_LSB 29
+#define SYNTH_SYNTH2_VC_CAL_REF_MASK 0xe0000000
+#define SYNTH_SYNTH2_VC_CAL_REF_GET(x) (((x) & SYNTH_SYNTH2_VC_CAL_REF_MASK) >> SYNTH_SYNTH2_VC_CAL_REF_LSB)
+#define SYNTH_SYNTH2_VC_CAL_REF_SET(x) (((x) << SYNTH_SYNTH2_VC_CAL_REF_LSB) & SYNTH_SYNTH2_VC_CAL_REF_MASK)
+#define SYNTH_SYNTH2_VC_HI_REF_MSB 28
+#define SYNTH_SYNTH2_VC_HI_REF_LSB 26
+#define SYNTH_SYNTH2_VC_HI_REF_MASK 0x1c000000
+#define SYNTH_SYNTH2_VC_HI_REF_GET(x) (((x) & SYNTH_SYNTH2_VC_HI_REF_MASK) >> SYNTH_SYNTH2_VC_HI_REF_LSB)
+#define SYNTH_SYNTH2_VC_HI_REF_SET(x) (((x) << SYNTH_SYNTH2_VC_HI_REF_LSB) & SYNTH_SYNTH2_VC_HI_REF_MASK)
+#define SYNTH_SYNTH2_VC_MID_REF_MSB 25
+#define SYNTH_SYNTH2_VC_MID_REF_LSB 23
+#define SYNTH_SYNTH2_VC_MID_REF_MASK 0x03800000
+#define SYNTH_SYNTH2_VC_MID_REF_GET(x) (((x) & SYNTH_SYNTH2_VC_MID_REF_MASK) >> SYNTH_SYNTH2_VC_MID_REF_LSB)
+#define SYNTH_SYNTH2_VC_MID_REF_SET(x) (((x) << SYNTH_SYNTH2_VC_MID_REF_LSB) & SYNTH_SYNTH2_VC_MID_REF_MASK)
+#define SYNTH_SYNTH2_VC_LOW_REF_MSB 22
+#define SYNTH_SYNTH2_VC_LOW_REF_LSB 20
+#define SYNTH_SYNTH2_VC_LOW_REF_MASK 0x00700000
+#define SYNTH_SYNTH2_VC_LOW_REF_GET(x) (((x) & SYNTH_SYNTH2_VC_LOW_REF_MASK) >> SYNTH_SYNTH2_VC_LOW_REF_LSB)
+#define SYNTH_SYNTH2_VC_LOW_REF_SET(x) (((x) << SYNTH_SYNTH2_VC_LOW_REF_LSB) & SYNTH_SYNTH2_VC_LOW_REF_MASK)
+#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MSB 19
+#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB 15
+#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK 0x000f8000
+#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_GET(x) (((x) & SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK) >> SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB)
+#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_SET(x) (((x) << SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB) & SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK)
+#define SYNTH_SYNTH2_LOOP_CP_MSB 14
+#define SYNTH_SYNTH2_LOOP_CP_LSB 10
+#define SYNTH_SYNTH2_LOOP_CP_MASK 0x00007c00
+#define SYNTH_SYNTH2_LOOP_CP_GET(x) (((x) & SYNTH_SYNTH2_LOOP_CP_MASK) >> SYNTH_SYNTH2_LOOP_CP_LSB)
+#define SYNTH_SYNTH2_LOOP_CP_SET(x) (((x) << SYNTH_SYNTH2_LOOP_CP_LSB) & SYNTH_SYNTH2_LOOP_CP_MASK)
+#define SYNTH_SYNTH2_LOOP_RS_MSB 9
+#define SYNTH_SYNTH2_LOOP_RS_LSB 5
+#define SYNTH_SYNTH2_LOOP_RS_MASK 0x000003e0
+#define SYNTH_SYNTH2_LOOP_RS_GET(x) (((x) & SYNTH_SYNTH2_LOOP_RS_MASK) >> SYNTH_SYNTH2_LOOP_RS_LSB)
+#define SYNTH_SYNTH2_LOOP_RS_SET(x) (((x) << SYNTH_SYNTH2_LOOP_RS_LSB) & SYNTH_SYNTH2_LOOP_RS_MASK)
+#define SYNTH_SYNTH2_LOOP_CS_MSB 4
+#define SYNTH_SYNTH2_LOOP_CS_LSB 3
+#define SYNTH_SYNTH2_LOOP_CS_MASK 0x00000018
+#define SYNTH_SYNTH2_LOOP_CS_GET(x) (((x) & SYNTH_SYNTH2_LOOP_CS_MASK) >> SYNTH_SYNTH2_LOOP_CS_LSB)
+#define SYNTH_SYNTH2_LOOP_CS_SET(x) (((x) << SYNTH_SYNTH2_LOOP_CS_LSB) & SYNTH_SYNTH2_LOOP_CS_MASK)
+#define SYNTH_SYNTH2_SPARE_BITS_MSB 2
+#define SYNTH_SYNTH2_SPARE_BITS_LSB 0
+#define SYNTH_SYNTH2_SPARE_BITS_MASK 0x00000007
+#define SYNTH_SYNTH2_SPARE_BITS_GET(x) (((x) & SYNTH_SYNTH2_SPARE_BITS_MASK) >> SYNTH_SYNTH2_SPARE_BITS_LSB)
+#define SYNTH_SYNTH2_SPARE_BITS_SET(x) (((x) << SYNTH_SYNTH2_SPARE_BITS_LSB) & SYNTH_SYNTH2_SPARE_BITS_MASK)
+
+#define SYNTH_SYNTH3_ADDRESS 0x00000008
+#define SYNTH_SYNTH3_OFFSET 0x00000008
+#define SYNTH_SYNTH3_DIS_CLK_XTAL_MSB 31
+#define SYNTH_SYNTH3_DIS_CLK_XTAL_LSB 31
+#define SYNTH_SYNTH3_DIS_CLK_XTAL_MASK 0x80000000
+#define SYNTH_SYNTH3_DIS_CLK_XTAL_GET(x) (((x) & SYNTH_SYNTH3_DIS_CLK_XTAL_MASK) >> SYNTH_SYNTH3_DIS_CLK_XTAL_LSB)
+#define SYNTH_SYNTH3_DIS_CLK_XTAL_SET(x) (((x) << SYNTH_SYNTH3_DIS_CLK_XTAL_LSB) & SYNTH_SYNTH3_DIS_CLK_XTAL_MASK)
+#define SYNTH_SYNTH3_SEL_CLK_DIV2_MSB 30
+#define SYNTH_SYNTH3_SEL_CLK_DIV2_LSB 30
+#define SYNTH_SYNTH3_SEL_CLK_DIV2_MASK 0x40000000
+#define SYNTH_SYNTH3_SEL_CLK_DIV2_GET(x) (((x) & SYNTH_SYNTH3_SEL_CLK_DIV2_MASK) >> SYNTH_SYNTH3_SEL_CLK_DIV2_LSB)
+#define SYNTH_SYNTH3_SEL_CLK_DIV2_SET(x) (((x) << SYNTH_SYNTH3_SEL_CLK_DIV2_LSB) & SYNTH_SYNTH3_SEL_CLK_DIV2_MASK)
+#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MSB 29
+#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB 24
+#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK 0x3f000000
+#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_GET(x) (((x) & SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK) >> SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB)
+#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_SET(x) (((x) << SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB) & SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK)
+#define SYNTH_SYNTH3_WAIT_PWRUP_MSB 23
+#define SYNTH_SYNTH3_WAIT_PWRUP_LSB 18
+#define SYNTH_SYNTH3_WAIT_PWRUP_MASK 0x00fc0000
+#define SYNTH_SYNTH3_WAIT_PWRUP_GET(x) (((x) & SYNTH_SYNTH3_WAIT_PWRUP_MASK) >> SYNTH_SYNTH3_WAIT_PWRUP_LSB)
+#define SYNTH_SYNTH3_WAIT_PWRUP_SET(x) (((x) << SYNTH_SYNTH3_WAIT_PWRUP_LSB) & SYNTH_SYNTH3_WAIT_PWRUP_MASK)
+#define SYNTH_SYNTH3_WAIT_CAL_BIN_MSB 17
+#define SYNTH_SYNTH3_WAIT_CAL_BIN_LSB 12
+#define SYNTH_SYNTH3_WAIT_CAL_BIN_MASK 0x0003f000
+#define SYNTH_SYNTH3_WAIT_CAL_BIN_GET(x) (((x) & SYNTH_SYNTH3_WAIT_CAL_BIN_MASK) >> SYNTH_SYNTH3_WAIT_CAL_BIN_LSB)
+#define SYNTH_SYNTH3_WAIT_CAL_BIN_SET(x) (((x) << SYNTH_SYNTH3_WAIT_CAL_BIN_LSB) & SYNTH_SYNTH3_WAIT_CAL_BIN_MASK)
+#define SYNTH_SYNTH3_WAIT_CAL_LIN_MSB 11
+#define SYNTH_SYNTH3_WAIT_CAL_LIN_LSB 6
+#define SYNTH_SYNTH3_WAIT_CAL_LIN_MASK 0x00000fc0
+#define SYNTH_SYNTH3_WAIT_CAL_LIN_GET(x) (((x) & SYNTH_SYNTH3_WAIT_CAL_LIN_MASK) >> SYNTH_SYNTH3_WAIT_CAL_LIN_LSB)
+#define SYNTH_SYNTH3_WAIT_CAL_LIN_SET(x) (((x) << SYNTH_SYNTH3_WAIT_CAL_LIN_LSB) & SYNTH_SYNTH3_WAIT_CAL_LIN_MASK)
+#define SYNTH_SYNTH3_WAIT_VC_CHECK_MSB 5
+#define SYNTH_SYNTH3_WAIT_VC_CHECK_LSB 0
+#define SYNTH_SYNTH3_WAIT_VC_CHECK_MASK 0x0000003f
+#define SYNTH_SYNTH3_WAIT_VC_CHECK_GET(x) (((x) & SYNTH_SYNTH3_WAIT_VC_CHECK_MASK) >> SYNTH_SYNTH3_WAIT_VC_CHECK_LSB)
+#define SYNTH_SYNTH3_WAIT_VC_CHECK_SET(x) (((x) << SYNTH_SYNTH3_WAIT_VC_CHECK_LSB) & SYNTH_SYNTH3_WAIT_VC_CHECK_MASK)
+
+#define SYNTH_SYNTH4_ADDRESS 0x0000000c
+#define SYNTH_SYNTH4_OFFSET 0x0000000c
+#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MSB 31
+#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB 31
+#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK 0x80000000
+#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_GET(x) (((x) & SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK) >> SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB)
+#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_SET(x) (((x) << SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB) & SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK)
+#define SYNTH_SYNTH4_DIS_LOSTVC_MSB 30
+#define SYNTH_SYNTH4_DIS_LOSTVC_LSB 30
+#define SYNTH_SYNTH4_DIS_LOSTVC_MASK 0x40000000
+#define SYNTH_SYNTH4_DIS_LOSTVC_GET(x) (((x) & SYNTH_SYNTH4_DIS_LOSTVC_MASK) >> SYNTH_SYNTH4_DIS_LOSTVC_LSB)
+#define SYNTH_SYNTH4_DIS_LOSTVC_SET(x) (((x) << SYNTH_SYNTH4_DIS_LOSTVC_LSB) & SYNTH_SYNTH4_DIS_LOSTVC_MASK)
+#define SYNTH_SYNTH4_ALWAYS_SHORTR_MSB 29
+#define SYNTH_SYNTH4_ALWAYS_SHORTR_LSB 29
+#define SYNTH_SYNTH4_ALWAYS_SHORTR_MASK 0x20000000
+#define SYNTH_SYNTH4_ALWAYS_SHORTR_GET(x) (((x) & SYNTH_SYNTH4_ALWAYS_SHORTR_MASK) >> SYNTH_SYNTH4_ALWAYS_SHORTR_LSB)
+#define SYNTH_SYNTH4_ALWAYS_SHORTR_SET(x) (((x) << SYNTH_SYNTH4_ALWAYS_SHORTR_LSB) & SYNTH_SYNTH4_ALWAYS_SHORTR_MASK)
+#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MSB 28
+#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB 28
+#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK 0x10000000
+#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x) (((x) & SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK) >> SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB)
+#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x) (((x) << SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB) & SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK)
+#define SYNTH_SYNTH4_FORCE_PINVC_MSB 27
+#define SYNTH_SYNTH4_FORCE_PINVC_LSB 27
+#define SYNTH_SYNTH4_FORCE_PINVC_MASK 0x08000000
+#define SYNTH_SYNTH4_FORCE_PINVC_GET(x) (((x) & SYNTH_SYNTH4_FORCE_PINVC_MASK) >> SYNTH_SYNTH4_FORCE_PINVC_LSB)
+#define SYNTH_SYNTH4_FORCE_PINVC_SET(x) (((x) << SYNTH_SYNTH4_FORCE_PINVC_LSB) & SYNTH_SYNTH4_FORCE_PINVC_MASK)
+#define SYNTH_SYNTH4_FORCE_VCOCAP_MSB 26
+#define SYNTH_SYNTH4_FORCE_VCOCAP_LSB 26
+#define SYNTH_SYNTH4_FORCE_VCOCAP_MASK 0x04000000
+#define SYNTH_SYNTH4_FORCE_VCOCAP_GET(x) (((x) & SYNTH_SYNTH4_FORCE_VCOCAP_MASK) >> SYNTH_SYNTH4_FORCE_VCOCAP_LSB)
+#define SYNTH_SYNTH4_FORCE_VCOCAP_SET(x) (((x) << SYNTH_SYNTH4_FORCE_VCOCAP_LSB) & SYNTH_SYNTH4_FORCE_VCOCAP_MASK)
+#define SYNTH_SYNTH4_VCOCAP_OVR_MSB 25
+#define SYNTH_SYNTH4_VCOCAP_OVR_LSB 18
+#define SYNTH_SYNTH4_VCOCAP_OVR_MASK 0x03fc0000
+#define SYNTH_SYNTH4_VCOCAP_OVR_GET(x) (((x) & SYNTH_SYNTH4_VCOCAP_OVR_MASK) >> SYNTH_SYNTH4_VCOCAP_OVR_LSB)
+#define SYNTH_SYNTH4_VCOCAP_OVR_SET(x) (((x) << SYNTH_SYNTH4_VCOCAP_OVR_LSB) & SYNTH_SYNTH4_VCOCAP_OVR_MASK)
+#define SYNTH_SYNTH4_VCOCAPPULLUP_MSB 17
+#define SYNTH_SYNTH4_VCOCAPPULLUP_LSB 17
+#define SYNTH_SYNTH4_VCOCAPPULLUP_MASK 0x00020000
+#define SYNTH_SYNTH4_VCOCAPPULLUP_GET(x) (((x) & SYNTH_SYNTH4_VCOCAPPULLUP_MASK) >> SYNTH_SYNTH4_VCOCAPPULLUP_LSB)
+#define SYNTH_SYNTH4_VCOCAPPULLUP_SET(x) (((x) << SYNTH_SYNTH4_VCOCAPPULLUP_LSB) & SYNTH_SYNTH4_VCOCAPPULLUP_MASK)
+#define SYNTH_SYNTH4_REFDIVSEL_MSB 16
+#define SYNTH_SYNTH4_REFDIVSEL_LSB 15
+#define SYNTH_SYNTH4_REFDIVSEL_MASK 0x00018000
+#define SYNTH_SYNTH4_REFDIVSEL_GET(x) (((x) & SYNTH_SYNTH4_REFDIVSEL_MASK) >> SYNTH_SYNTH4_REFDIVSEL_LSB)
+#define SYNTH_SYNTH4_REFDIVSEL_SET(x) (((x) << SYNTH_SYNTH4_REFDIVSEL_LSB) & SYNTH_SYNTH4_REFDIVSEL_MASK)
+#define SYNTH_SYNTH4_PFDDELAY_MSB 14
+#define SYNTH_SYNTH4_PFDDELAY_LSB 14
+#define SYNTH_SYNTH4_PFDDELAY_MASK 0x00004000
+#define SYNTH_SYNTH4_PFDDELAY_GET(x) (((x) & SYNTH_SYNTH4_PFDDELAY_MASK) >> SYNTH_SYNTH4_PFDDELAY_LSB)
+#define SYNTH_SYNTH4_PFDDELAY_SET(x) (((x) << SYNTH_SYNTH4_PFDDELAY_LSB) & SYNTH_SYNTH4_PFDDELAY_MASK)
+#define SYNTH_SYNTH4_PFD_DISABLE_MSB 13
+#define SYNTH_SYNTH4_PFD_DISABLE_LSB 13
+#define SYNTH_SYNTH4_PFD_DISABLE_MASK 0x00002000
+#define SYNTH_SYNTH4_PFD_DISABLE_GET(x) (((x) & SYNTH_SYNTH4_PFD_DISABLE_MASK) >> SYNTH_SYNTH4_PFD_DISABLE_LSB)
+#define SYNTH_SYNTH4_PFD_DISABLE_SET(x) (((x) << SYNTH_SYNTH4_PFD_DISABLE_LSB) & SYNTH_SYNTH4_PFD_DISABLE_MASK)
+#define SYNTH_SYNTH4_PRESCSEL_MSB 12
+#define SYNTH_SYNTH4_PRESCSEL_LSB 11
+#define SYNTH_SYNTH4_PRESCSEL_MASK 0x00001800
+#define SYNTH_SYNTH4_PRESCSEL_GET(x) (((x) & SYNTH_SYNTH4_PRESCSEL_MASK) >> SYNTH_SYNTH4_PRESCSEL_LSB)
+#define SYNTH_SYNTH4_PRESCSEL_SET(x) (((x) << SYNTH_SYNTH4_PRESCSEL_LSB) & SYNTH_SYNTH4_PRESCSEL_MASK)
+#define SYNTH_SYNTH4_RESET_PRESC_MSB 10
+#define SYNTH_SYNTH4_RESET_PRESC_LSB 10
+#define SYNTH_SYNTH4_RESET_PRESC_MASK 0x00000400
+#define SYNTH_SYNTH4_RESET_PRESC_GET(x) (((x) & SYNTH_SYNTH4_RESET_PRESC_MASK) >> SYNTH_SYNTH4_RESET_PRESC_LSB)
+#define SYNTH_SYNTH4_RESET_PRESC_SET(x) (((x) << SYNTH_SYNTH4_RESET_PRESC_LSB) & SYNTH_SYNTH4_RESET_PRESC_MASK)
+#define SYNTH_SYNTH4_SDM_DISABLE_MSB 9
+#define SYNTH_SYNTH4_SDM_DISABLE_LSB 9
+#define SYNTH_SYNTH4_SDM_DISABLE_MASK 0x00000200
+#define SYNTH_SYNTH4_SDM_DISABLE_GET(x) (((x) & SYNTH_SYNTH4_SDM_DISABLE_MASK) >> SYNTH_SYNTH4_SDM_DISABLE_LSB)
+#define SYNTH_SYNTH4_SDM_DISABLE_SET(x) (((x) << SYNTH_SYNTH4_SDM_DISABLE_LSB) & SYNTH_SYNTH4_SDM_DISABLE_MASK)
+#define SYNTH_SYNTH4_SDM_MODE_MSB 8
+#define SYNTH_SYNTH4_SDM_MODE_LSB 8
+#define SYNTH_SYNTH4_SDM_MODE_MASK 0x00000100
+#define SYNTH_SYNTH4_SDM_MODE_GET(x) (((x) & SYNTH_SYNTH4_SDM_MODE_MASK) >> SYNTH_SYNTH4_SDM_MODE_LSB)
+#define SYNTH_SYNTH4_SDM_MODE_SET(x) (((x) << SYNTH_SYNTH4_SDM_MODE_LSB) & SYNTH_SYNTH4_SDM_MODE_MASK)
+#define SYNTH_SYNTH4_SDM_DITHER_MSB 7
+#define SYNTH_SYNTH4_SDM_DITHER_LSB 6
+#define SYNTH_SYNTH4_SDM_DITHER_MASK 0x000000c0
+#define SYNTH_SYNTH4_SDM_DITHER_GET(x) (((x) & SYNTH_SYNTH4_SDM_DITHER_MASK) >> SYNTH_SYNTH4_SDM_DITHER_LSB)
+#define SYNTH_SYNTH4_SDM_DITHER_SET(x) (((x) << SYNTH_SYNTH4_SDM_DITHER_LSB) & SYNTH_SYNTH4_SDM_DITHER_MASK)
+#define SYNTH_SYNTH4_PSCOUNT_FBSEL_MSB 5
+#define SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB 5
+#define SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK 0x00000020
+#define SYNTH_SYNTH4_PSCOUNT_FBSEL_GET(x) (((x) & SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK) >> SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB)
+#define SYNTH_SYNTH4_PSCOUNT_FBSEL_SET(x) (((x) << SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB) & SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK)
+#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MSB 4
+#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB 4
+#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK 0x00000010
+#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_GET(x) (((x) & SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK) >> SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB)
+#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_SET(x) (((x) << SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB) & SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK)
+#define SYNTH_SYNTH4_SPARE_MISC_MSB 3
+#define SYNTH_SYNTH4_SPARE_MISC_LSB 2
+#define SYNTH_SYNTH4_SPARE_MISC_MASK 0x0000000c
+#define SYNTH_SYNTH4_SPARE_MISC_GET(x) (((x) & SYNTH_SYNTH4_SPARE_MISC_MASK) >> SYNTH_SYNTH4_SPARE_MISC_LSB)
+#define SYNTH_SYNTH4_SPARE_MISC_SET(x) (((x) << SYNTH_SYNTH4_SPARE_MISC_LSB) & SYNTH_SYNTH4_SPARE_MISC_MASK)
+#define SYNTH_SYNTH4_LONGSHIFTSEL_MSB 1
+#define SYNTH_SYNTH4_LONGSHIFTSEL_LSB 1
+#define SYNTH_SYNTH4_LONGSHIFTSEL_MASK 0x00000002
+#define SYNTH_SYNTH4_LONGSHIFTSEL_GET(x) (((x) & SYNTH_SYNTH4_LONGSHIFTSEL_MASK) >> SYNTH_SYNTH4_LONGSHIFTSEL_LSB)
+#define SYNTH_SYNTH4_LONGSHIFTSEL_SET(x) (((x) << SYNTH_SYNTH4_LONGSHIFTSEL_LSB) & SYNTH_SYNTH4_LONGSHIFTSEL_MASK)
+#define SYNTH_SYNTH4_FORCE_SHIFTREG_MSB 0
+#define SYNTH_SYNTH4_FORCE_SHIFTREG_LSB 0
+#define SYNTH_SYNTH4_FORCE_SHIFTREG_MASK 0x00000001
+#define SYNTH_SYNTH4_FORCE_SHIFTREG_GET(x) (((x) & SYNTH_SYNTH4_FORCE_SHIFTREG_MASK) >> SYNTH_SYNTH4_FORCE_SHIFTREG_LSB)
+#define SYNTH_SYNTH4_FORCE_SHIFTREG_SET(x) (((x) << SYNTH_SYNTH4_FORCE_SHIFTREG_LSB) & SYNTH_SYNTH4_FORCE_SHIFTREG_MASK)
+
+#define SYNTH_SYNTH5_ADDRESS 0x00000010
+#define SYNTH_SYNTH5_OFFSET 0x00000010
+#define SYNTH_SYNTH5_LOOP_IP0_MSB 31
+#define SYNTH_SYNTH5_LOOP_IP0_LSB 28
+#define SYNTH_SYNTH5_LOOP_IP0_MASK 0xf0000000
+#define SYNTH_SYNTH5_LOOP_IP0_GET(x) (((x) & SYNTH_SYNTH5_LOOP_IP0_MASK) >> SYNTH_SYNTH5_LOOP_IP0_LSB)
+#define SYNTH_SYNTH5_LOOP_IP0_SET(x) (((x) << SYNTH_SYNTH5_LOOP_IP0_LSB) & SYNTH_SYNTH5_LOOP_IP0_MASK)
+#define SYNTH_SYNTH5_SLOPE_IP_MSB 27
+#define SYNTH_SYNTH5_SLOPE_IP_LSB 25
+#define SYNTH_SYNTH5_SLOPE_IP_MASK 0x0e000000
+#define SYNTH_SYNTH5_SLOPE_IP_GET(x) (((x) & SYNTH_SYNTH5_SLOPE_IP_MASK) >> SYNTH_SYNTH5_SLOPE_IP_LSB)
+#define SYNTH_SYNTH5_SLOPE_IP_SET(x) (((x) << SYNTH_SYNTH5_SLOPE_IP_LSB) & SYNTH_SYNTH5_SLOPE_IP_MASK)
+#define SYNTH_SYNTH5_CPBIAS_MSB 24
+#define SYNTH_SYNTH5_CPBIAS_LSB 23
+#define SYNTH_SYNTH5_CPBIAS_MASK 0x01800000
+#define SYNTH_SYNTH5_CPBIAS_GET(x) (((x) & SYNTH_SYNTH5_CPBIAS_MASK) >> SYNTH_SYNTH5_CPBIAS_LSB)
+#define SYNTH_SYNTH5_CPBIAS_SET(x) (((x) << SYNTH_SYNTH5_CPBIAS_LSB) & SYNTH_SYNTH5_CPBIAS_MASK)
+#define SYNTH_SYNTH5_CPSTEERING_EN_MSB 22
+#define SYNTH_SYNTH5_CPSTEERING_EN_LSB 22
+#define SYNTH_SYNTH5_CPSTEERING_EN_MASK 0x00400000
+#define SYNTH_SYNTH5_CPSTEERING_EN_GET(x) (((x) & SYNTH_SYNTH5_CPSTEERING_EN_MASK) >> SYNTH_SYNTH5_CPSTEERING_EN_LSB)
+#define SYNTH_SYNTH5_CPSTEERING_EN_SET(x) (((x) << SYNTH_SYNTH5_CPSTEERING_EN_LSB) & SYNTH_SYNTH5_CPSTEERING_EN_MASK)
+#define SYNTH_SYNTH5_CPLOWLK_MSB 21
+#define SYNTH_SYNTH5_CPLOWLK_LSB 21
+#define SYNTH_SYNTH5_CPLOWLK_MASK 0x00200000
+#define SYNTH_SYNTH5_CPLOWLK_GET(x) (((x) & SYNTH_SYNTH5_CPLOWLK_MASK) >> SYNTH_SYNTH5_CPLOWLK_LSB)
+#define SYNTH_SYNTH5_CPLOWLK_SET(x) (((x) << SYNTH_SYNTH5_CPLOWLK_LSB) & SYNTH_SYNTH5_CPLOWLK_MASK)
+#define SYNTH_SYNTH5_LOOPLEAKCUR_MSB 20
+#define SYNTH_SYNTH5_LOOPLEAKCUR_LSB 17
+#define SYNTH_SYNTH5_LOOPLEAKCUR_MASK 0x001e0000
+#define SYNTH_SYNTH5_LOOPLEAKCUR_GET(x) (((x) & SYNTH_SYNTH5_LOOPLEAKCUR_MASK) >> SYNTH_SYNTH5_LOOPLEAKCUR_LSB)
+#define SYNTH_SYNTH5_LOOPLEAKCUR_SET(x) (((x) << SYNTH_SYNTH5_LOOPLEAKCUR_LSB) & SYNTH_SYNTH5_LOOPLEAKCUR_MASK)
+#define SYNTH_SYNTH5_CAPRANGE1_MSB 16
+#define SYNTH_SYNTH5_CAPRANGE1_LSB 13
+#define SYNTH_SYNTH5_CAPRANGE1_MASK 0x0001e000
+#define SYNTH_SYNTH5_CAPRANGE1_GET(x) (((x) & SYNTH_SYNTH5_CAPRANGE1_MASK) >> SYNTH_SYNTH5_CAPRANGE1_LSB)
+#define SYNTH_SYNTH5_CAPRANGE1_SET(x) (((x) << SYNTH_SYNTH5_CAPRANGE1_LSB) & SYNTH_SYNTH5_CAPRANGE1_MASK)
+#define SYNTH_SYNTH5_CAPRANGE2_MSB 12
+#define SYNTH_SYNTH5_CAPRANGE2_LSB 9
+#define SYNTH_SYNTH5_CAPRANGE2_MASK 0x00001e00
+#define SYNTH_SYNTH5_CAPRANGE2_GET(x) (((x) & SYNTH_SYNTH5_CAPRANGE2_MASK) >> SYNTH_SYNTH5_CAPRANGE2_LSB)
+#define SYNTH_SYNTH5_CAPRANGE2_SET(x) (((x) << SYNTH_SYNTH5_CAPRANGE2_LSB) & SYNTH_SYNTH5_CAPRANGE2_MASK)
+#define SYNTH_SYNTH5_CAPRANGE3_MSB 8
+#define SYNTH_SYNTH5_CAPRANGE3_LSB 5
+#define SYNTH_SYNTH5_CAPRANGE3_MASK 0x000001e0
+#define SYNTH_SYNTH5_CAPRANGE3_GET(x) (((x) & SYNTH_SYNTH5_CAPRANGE3_MASK) >> SYNTH_SYNTH5_CAPRANGE3_LSB)
+#define SYNTH_SYNTH5_CAPRANGE3_SET(x) (((x) << SYNTH_SYNTH5_CAPRANGE3_LSB) & SYNTH_SYNTH5_CAPRANGE3_MASK)
+#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MSB 4
+#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB 4
+#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK 0x00000010
+#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_GET(x) (((x) & SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK) >> SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB)
+#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_SET(x) (((x) << SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB) & SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK)
+#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MSB 3
+#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB 2
+#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK 0x0000000c
+#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_GET(x) (((x) & SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK) >> SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB)
+#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_SET(x) (((x) << SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB) & SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK)
+#define SYNTH_SYNTH5_SPARE_MSB 1
+#define SYNTH_SYNTH5_SPARE_LSB 0
+#define SYNTH_SYNTH5_SPARE_MASK 0x00000003
+#define SYNTH_SYNTH5_SPARE_GET(x) (((x) & SYNTH_SYNTH5_SPARE_MASK) >> SYNTH_SYNTH5_SPARE_LSB)
+#define SYNTH_SYNTH5_SPARE_SET(x) (((x) << SYNTH_SYNTH5_SPARE_LSB) & SYNTH_SYNTH5_SPARE_MASK)
+
+#define SYNTH_SYNTH6_ADDRESS 0x00000014
+#define SYNTH_SYNTH6_OFFSET 0x00000014
+#define SYNTH_SYNTH6_IRCP_MSB 31
+#define SYNTH_SYNTH6_IRCP_LSB 29
+#define SYNTH_SYNTH6_IRCP_MASK 0xe0000000
+#define SYNTH_SYNTH6_IRCP_GET(x) (((x) & SYNTH_SYNTH6_IRCP_MASK) >> SYNTH_SYNTH6_IRCP_LSB)
+#define SYNTH_SYNTH6_IRCP_SET(x) (((x) << SYNTH_SYNTH6_IRCP_LSB) & SYNTH_SYNTH6_IRCP_MASK)
+#define SYNTH_SYNTH6_IRVCMON_MSB 28
+#define SYNTH_SYNTH6_IRVCMON_LSB 26
+#define SYNTH_SYNTH6_IRVCMON_MASK 0x1c000000
+#define SYNTH_SYNTH6_IRVCMON_GET(x) (((x) & SYNTH_SYNTH6_IRVCMON_MASK) >> SYNTH_SYNTH6_IRVCMON_LSB)
+#define SYNTH_SYNTH6_IRVCMON_SET(x) (((x) << SYNTH_SYNTH6_IRVCMON_LSB) & SYNTH_SYNTH6_IRVCMON_MASK)
+#define SYNTH_SYNTH6_IRSPARE_MSB 25
+#define SYNTH_SYNTH6_IRSPARE_LSB 23
+#define SYNTH_SYNTH6_IRSPARE_MASK 0x03800000
+#define SYNTH_SYNTH6_IRSPARE_GET(x) (((x) & SYNTH_SYNTH6_IRSPARE_MASK) >> SYNTH_SYNTH6_IRSPARE_LSB)
+#define SYNTH_SYNTH6_IRSPARE_SET(x) (((x) << SYNTH_SYNTH6_IRSPARE_LSB) & SYNTH_SYNTH6_IRSPARE_MASK)
+#define SYNTH_SYNTH6_ICPRESC_MSB 22
+#define SYNTH_SYNTH6_ICPRESC_LSB 20
+#define SYNTH_SYNTH6_ICPRESC_MASK 0x00700000
+#define SYNTH_SYNTH6_ICPRESC_GET(x) (((x) & SYNTH_SYNTH6_ICPRESC_MASK) >> SYNTH_SYNTH6_ICPRESC_LSB)
+#define SYNTH_SYNTH6_ICPRESC_SET(x) (((x) << SYNTH_SYNTH6_ICPRESC_LSB) & SYNTH_SYNTH6_ICPRESC_MASK)
+#define SYNTH_SYNTH6_ICLODIV_MSB 19
+#define SYNTH_SYNTH6_ICLODIV_LSB 17
+#define SYNTH_SYNTH6_ICLODIV_MASK 0x000e0000
+#define SYNTH_SYNTH6_ICLODIV_GET(x) (((x) & SYNTH_SYNTH6_ICLODIV_MASK) >> SYNTH_SYNTH6_ICLODIV_LSB)
+#define SYNTH_SYNTH6_ICLODIV_SET(x) (((x) << SYNTH_SYNTH6_ICLODIV_LSB) & SYNTH_SYNTH6_ICLODIV_MASK)
+#define SYNTH_SYNTH6_ICLOMIX_MSB 16
+#define SYNTH_SYNTH6_ICLOMIX_LSB 14
+#define SYNTH_SYNTH6_ICLOMIX_MASK 0x0001c000
+#define SYNTH_SYNTH6_ICLOMIX_GET(x) (((x) & SYNTH_SYNTH6_ICLOMIX_MASK) >> SYNTH_SYNTH6_ICLOMIX_LSB)
+#define SYNTH_SYNTH6_ICLOMIX_SET(x) (((x) << SYNTH_SYNTH6_ICLOMIX_LSB) & SYNTH_SYNTH6_ICLOMIX_MASK)
+#define SYNTH_SYNTH6_ICSPAREA_MSB 13
+#define SYNTH_SYNTH6_ICSPAREA_LSB 11
+#define SYNTH_SYNTH6_ICSPAREA_MASK 0x00003800
+#define SYNTH_SYNTH6_ICSPAREA_GET(x) (((x) & SYNTH_SYNTH6_ICSPAREA_MASK) >> SYNTH_SYNTH6_ICSPAREA_LSB)
+#define SYNTH_SYNTH6_ICSPAREA_SET(x) (((x) << SYNTH_SYNTH6_ICSPAREA_LSB) & SYNTH_SYNTH6_ICSPAREA_MASK)
+#define SYNTH_SYNTH6_ICSPAREB_MSB 10
+#define SYNTH_SYNTH6_ICSPAREB_LSB 8
+#define SYNTH_SYNTH6_ICSPAREB_MASK 0x00000700
+#define SYNTH_SYNTH6_ICSPAREB_GET(x) (((x) & SYNTH_SYNTH6_ICSPAREB_MASK) >> SYNTH_SYNTH6_ICSPAREB_LSB)
+#define SYNTH_SYNTH6_ICSPAREB_SET(x) (((x) << SYNTH_SYNTH6_ICSPAREB_LSB) & SYNTH_SYNTH6_ICSPAREB_MASK)
+#define SYNTH_SYNTH6_ICVCO_MSB 7
+#define SYNTH_SYNTH6_ICVCO_LSB 5
+#define SYNTH_SYNTH6_ICVCO_MASK 0x000000e0
+#define SYNTH_SYNTH6_ICVCO_GET(x) (((x) & SYNTH_SYNTH6_ICVCO_MASK) >> SYNTH_SYNTH6_ICVCO_LSB)
+#define SYNTH_SYNTH6_ICVCO_SET(x) (((x) << SYNTH_SYNTH6_ICVCO_LSB) & SYNTH_SYNTH6_ICVCO_MASK)
+#define SYNTH_SYNTH6_VCOBUFBIAS_MSB 4
+#define SYNTH_SYNTH6_VCOBUFBIAS_LSB 3
+#define SYNTH_SYNTH6_VCOBUFBIAS_MASK 0x00000018
+#define SYNTH_SYNTH6_VCOBUFBIAS_GET(x) (((x) & SYNTH_SYNTH6_VCOBUFBIAS_MASK) >> SYNTH_SYNTH6_VCOBUFBIAS_LSB)
+#define SYNTH_SYNTH6_VCOBUFBIAS_SET(x) (((x) << SYNTH_SYNTH6_VCOBUFBIAS_LSB) & SYNTH_SYNTH6_VCOBUFBIAS_MASK)
+#define SYNTH_SYNTH6_SPARE_BIAS_MSB 2
+#define SYNTH_SYNTH6_SPARE_BIAS_LSB 0
+#define SYNTH_SYNTH6_SPARE_BIAS_MASK 0x00000007
+#define SYNTH_SYNTH6_SPARE_BIAS_GET(x) (((x) & SYNTH_SYNTH6_SPARE_BIAS_MASK) >> SYNTH_SYNTH6_SPARE_BIAS_LSB)
+#define SYNTH_SYNTH6_SPARE_BIAS_SET(x) (((x) << SYNTH_SYNTH6_SPARE_BIAS_LSB) & SYNTH_SYNTH6_SPARE_BIAS_MASK)
+
+#define SYNTH_SYNTH7_ADDRESS 0x00000018
+#define SYNTH_SYNTH7_OFFSET 0x00000018
+#define SYNTH_SYNTH7_SYNTH_ON_MSB 31
+#define SYNTH_SYNTH7_SYNTH_ON_LSB 31
+#define SYNTH_SYNTH7_SYNTH_ON_MASK 0x80000000
+#define SYNTH_SYNTH7_SYNTH_ON_GET(x) (((x) & SYNTH_SYNTH7_SYNTH_ON_MASK) >> SYNTH_SYNTH7_SYNTH_ON_LSB)
+#define SYNTH_SYNTH7_SYNTH_ON_SET(x) (((x) << SYNTH_SYNTH7_SYNTH_ON_LSB) & SYNTH_SYNTH7_SYNTH_ON_MASK)
+#define SYNTH_SYNTH7_SYNTH_SM_STATE_MSB 30
+#define SYNTH_SYNTH7_SYNTH_SM_STATE_LSB 27
+#define SYNTH_SYNTH7_SYNTH_SM_STATE_MASK 0x78000000
+#define SYNTH_SYNTH7_SYNTH_SM_STATE_GET(x) (((x) & SYNTH_SYNTH7_SYNTH_SM_STATE_MASK) >> SYNTH_SYNTH7_SYNTH_SM_STATE_LSB)
+#define SYNTH_SYNTH7_SYNTH_SM_STATE_SET(x) (((x) << SYNTH_SYNTH7_SYNTH_SM_STATE_LSB) & SYNTH_SYNTH7_SYNTH_SM_STATE_MASK)
+#define SYNTH_SYNTH7_CAP_SEARCH_MSB 26
+#define SYNTH_SYNTH7_CAP_SEARCH_LSB 26
+#define SYNTH_SYNTH7_CAP_SEARCH_MASK 0x04000000
+#define SYNTH_SYNTH7_CAP_SEARCH_GET(x) (((x) & SYNTH_SYNTH7_CAP_SEARCH_MASK) >> SYNTH_SYNTH7_CAP_SEARCH_LSB)
+#define SYNTH_SYNTH7_CAP_SEARCH_SET(x) (((x) << SYNTH_SYNTH7_CAP_SEARCH_LSB) & SYNTH_SYNTH7_CAP_SEARCH_MASK)
+#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MSB 25
+#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB 25
+#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK 0x02000000
+#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_GET(x) (((x) & SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK) >> SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB)
+#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_SET(x) (((x) << SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB) & SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK)
+#define SYNTH_SYNTH7_PIN_VC_MSB 24
+#define SYNTH_SYNTH7_PIN_VC_LSB 24
+#define SYNTH_SYNTH7_PIN_VC_MASK 0x01000000
+#define SYNTH_SYNTH7_PIN_VC_GET(x) (((x) & SYNTH_SYNTH7_PIN_VC_MASK) >> SYNTH_SYNTH7_PIN_VC_LSB)
+#define SYNTH_SYNTH7_PIN_VC_SET(x) (((x) << SYNTH_SYNTH7_PIN_VC_LSB) & SYNTH_SYNTH7_PIN_VC_MASK)
+#define SYNTH_SYNTH7_VCO_CAP_ST_MSB 23
+#define SYNTH_SYNTH7_VCO_CAP_ST_LSB 16
+#define SYNTH_SYNTH7_VCO_CAP_ST_MASK 0x00ff0000
+#define SYNTH_SYNTH7_VCO_CAP_ST_GET(x) (((x) & SYNTH_SYNTH7_VCO_CAP_ST_MASK) >> SYNTH_SYNTH7_VCO_CAP_ST_LSB)
+#define SYNTH_SYNTH7_VCO_CAP_ST_SET(x) (((x) << SYNTH_SYNTH7_VCO_CAP_ST_LSB) & SYNTH_SYNTH7_VCO_CAP_ST_MASK)
+#define SYNTH_SYNTH7_SHORT_R_MSB 15
+#define SYNTH_SYNTH7_SHORT_R_LSB 15
+#define SYNTH_SYNTH7_SHORT_R_MASK 0x00008000
+#define SYNTH_SYNTH7_SHORT_R_GET(x) (((x) & SYNTH_SYNTH7_SHORT_R_MASK) >> SYNTH_SYNTH7_SHORT_R_LSB)
+#define SYNTH_SYNTH7_SHORT_R_SET(x) (((x) << SYNTH_SYNTH7_SHORT_R_LSB) & SYNTH_SYNTH7_SHORT_R_MASK)
+#define SYNTH_SYNTH7_RESET_RFD_MSB 14
+#define SYNTH_SYNTH7_RESET_RFD_LSB 14
+#define SYNTH_SYNTH7_RESET_RFD_MASK 0x00004000
+#define SYNTH_SYNTH7_RESET_RFD_GET(x) (((x) & SYNTH_SYNTH7_RESET_RFD_MASK) >> SYNTH_SYNTH7_RESET_RFD_LSB)
+#define SYNTH_SYNTH7_RESET_RFD_SET(x) (((x) << SYNTH_SYNTH7_RESET_RFD_LSB) & SYNTH_SYNTH7_RESET_RFD_MASK)
+#define SYNTH_SYNTH7_RESET_PFD_MSB 13
+#define SYNTH_SYNTH7_RESET_PFD_LSB 13
+#define SYNTH_SYNTH7_RESET_PFD_MASK 0x00002000
+#define SYNTH_SYNTH7_RESET_PFD_GET(x) (((x) & SYNTH_SYNTH7_RESET_PFD_MASK) >> SYNTH_SYNTH7_RESET_PFD_LSB)
+#define SYNTH_SYNTH7_RESET_PFD_SET(x) (((x) << SYNTH_SYNTH7_RESET_PFD_LSB) & SYNTH_SYNTH7_RESET_PFD_MASK)
+#define SYNTH_SYNTH7_RESET_PSCOUNTERS_MSB 12
+#define SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB 12
+#define SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK 0x00001000
+#define SYNTH_SYNTH7_RESET_PSCOUNTERS_GET(x) (((x) & SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK) >> SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB)
+#define SYNTH_SYNTH7_RESET_PSCOUNTERS_SET(x) (((x) << SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB) & SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK)
+#define SYNTH_SYNTH7_RESET_SDM_B_MSB 11
+#define SYNTH_SYNTH7_RESET_SDM_B_LSB 11
+#define SYNTH_SYNTH7_RESET_SDM_B_MASK 0x00000800
+#define SYNTH_SYNTH7_RESET_SDM_B_GET(x) (((x) & SYNTH_SYNTH7_RESET_SDM_B_MASK) >> SYNTH_SYNTH7_RESET_SDM_B_LSB)
+#define SYNTH_SYNTH7_RESET_SDM_B_SET(x) (((x) << SYNTH_SYNTH7_RESET_SDM_B_LSB) & SYNTH_SYNTH7_RESET_SDM_B_MASK)
+#define SYNTH_SYNTH7_VC2HIGH_MSB 10
+#define SYNTH_SYNTH7_VC2HIGH_LSB 10
+#define SYNTH_SYNTH7_VC2HIGH_MASK 0x00000400
+#define SYNTH_SYNTH7_VC2HIGH_GET(x) (((x) & SYNTH_SYNTH7_VC2HIGH_MASK) >> SYNTH_SYNTH7_VC2HIGH_LSB)
+#define SYNTH_SYNTH7_VC2HIGH_SET(x) (((x) << SYNTH_SYNTH7_VC2HIGH_LSB) & SYNTH_SYNTH7_VC2HIGH_MASK)
+#define SYNTH_SYNTH7_VC2LOW_MSB 9
+#define SYNTH_SYNTH7_VC2LOW_LSB 9
+#define SYNTH_SYNTH7_VC2LOW_MASK 0x00000200
+#define SYNTH_SYNTH7_VC2LOW_GET(x) (((x) & SYNTH_SYNTH7_VC2LOW_MASK) >> SYNTH_SYNTH7_VC2LOW_LSB)
+#define SYNTH_SYNTH7_VC2LOW_SET(x) (((x) << SYNTH_SYNTH7_VC2LOW_LSB) & SYNTH_SYNTH7_VC2LOW_MASK)
+#define SYNTH_SYNTH7_LOOP_IP_MSB 8
+#define SYNTH_SYNTH7_LOOP_IP_LSB 5
+#define SYNTH_SYNTH7_LOOP_IP_MASK 0x000001e0
+#define SYNTH_SYNTH7_LOOP_IP_GET(x) (((x) & SYNTH_SYNTH7_LOOP_IP_MASK) >> SYNTH_SYNTH7_LOOP_IP_LSB)
+#define SYNTH_SYNTH7_LOOP_IP_SET(x) (((x) << SYNTH_SYNTH7_LOOP_IP_LSB) & SYNTH_SYNTH7_LOOP_IP_MASK)
+#define SYNTH_SYNTH7_LOBUF5GTUNE_MSB 4
+#define SYNTH_SYNTH7_LOBUF5GTUNE_LSB 3
+#define SYNTH_SYNTH7_LOBUF5GTUNE_MASK 0x00000018
+#define SYNTH_SYNTH7_LOBUF5GTUNE_GET(x) (((x) & SYNTH_SYNTH7_LOBUF5GTUNE_MASK) >> SYNTH_SYNTH7_LOBUF5GTUNE_LSB)
+#define SYNTH_SYNTH7_LOBUF5GTUNE_SET(x) (((x) << SYNTH_SYNTH7_LOBUF5GTUNE_LSB) & SYNTH_SYNTH7_LOBUF5GTUNE_MASK)
+#define SYNTH_SYNTH7_SPARE_READ_MSB 2
+#define SYNTH_SYNTH7_SPARE_READ_LSB 0
+#define SYNTH_SYNTH7_SPARE_READ_MASK 0x00000007
+#define SYNTH_SYNTH7_SPARE_READ_GET(x) (((x) & SYNTH_SYNTH7_SPARE_READ_MASK) >> SYNTH_SYNTH7_SPARE_READ_LSB)
+#define SYNTH_SYNTH7_SPARE_READ_SET(x) (((x) << SYNTH_SYNTH7_SPARE_READ_LSB) & SYNTH_SYNTH7_SPARE_READ_MASK)
+
+#define SYNTH_SYNTH8_ADDRESS 0x0000001c
+#define SYNTH_SYNTH8_OFFSET 0x0000001c
+#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_MSB 31
+#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB 31
+#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK 0x80000000
+#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_GET(x) (((x) & SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK) >> SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB)
+#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_SET(x) (((x) << SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB) & SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK)
+#define SYNTH_SYNTH8_FRACMODE_MSB 30
+#define SYNTH_SYNTH8_FRACMODE_LSB 30
+#define SYNTH_SYNTH8_FRACMODE_MASK 0x40000000
+#define SYNTH_SYNTH8_FRACMODE_GET(x) (((x) & SYNTH_SYNTH8_FRACMODE_MASK) >> SYNTH_SYNTH8_FRACMODE_LSB)
+#define SYNTH_SYNTH8_FRACMODE_SET(x) (((x) << SYNTH_SYNTH8_FRACMODE_LSB) & SYNTH_SYNTH8_FRACMODE_MASK)
+#define SYNTH_SYNTH8_AMODEREFSEL_MSB 29
+#define SYNTH_SYNTH8_AMODEREFSEL_LSB 28
+#define SYNTH_SYNTH8_AMODEREFSEL_MASK 0x30000000
+#define SYNTH_SYNTH8_AMODEREFSEL_GET(x) (((x) & SYNTH_SYNTH8_AMODEREFSEL_MASK) >> SYNTH_SYNTH8_AMODEREFSEL_LSB)
+#define SYNTH_SYNTH8_AMODEREFSEL_SET(x) (((x) << SYNTH_SYNTH8_AMODEREFSEL_LSB) & SYNTH_SYNTH8_AMODEREFSEL_MASK)
+#define SYNTH_SYNTH8_SPARE_MSB 27
+#define SYNTH_SYNTH8_SPARE_LSB 27
+#define SYNTH_SYNTH8_SPARE_MASK 0x08000000
+#define SYNTH_SYNTH8_SPARE_GET(x) (((x) & SYNTH_SYNTH8_SPARE_MASK) >> SYNTH_SYNTH8_SPARE_LSB)
+#define SYNTH_SYNTH8_SPARE_SET(x) (((x) << SYNTH_SYNTH8_SPARE_LSB) & SYNTH_SYNTH8_SPARE_MASK)
+#define SYNTH_SYNTH8_CHANSEL_MSB 26
+#define SYNTH_SYNTH8_CHANSEL_LSB 18
+#define SYNTH_SYNTH8_CHANSEL_MASK 0x07fc0000
+#define SYNTH_SYNTH8_CHANSEL_GET(x) (((x) & SYNTH_SYNTH8_CHANSEL_MASK) >> SYNTH_SYNTH8_CHANSEL_LSB)
+#define SYNTH_SYNTH8_CHANSEL_SET(x) (((x) << SYNTH_SYNTH8_CHANSEL_LSB) & SYNTH_SYNTH8_CHANSEL_MASK)
+#define SYNTH_SYNTH8_CHANFRAC_MSB 17
+#define SYNTH_SYNTH8_CHANFRAC_LSB 1
+#define SYNTH_SYNTH8_CHANFRAC_MASK 0x0003fffe
+#define SYNTH_SYNTH8_CHANFRAC_GET(x) (((x) & SYNTH_SYNTH8_CHANFRAC_MASK) >> SYNTH_SYNTH8_CHANFRAC_LSB)
+#define SYNTH_SYNTH8_CHANFRAC_SET(x) (((x) << SYNTH_SYNTH8_CHANFRAC_LSB) & SYNTH_SYNTH8_CHANFRAC_MASK)
+#define SYNTH_SYNTH8_FORCE_FRACLSB_MSB 0
+#define SYNTH_SYNTH8_FORCE_FRACLSB_LSB 0
+#define SYNTH_SYNTH8_FORCE_FRACLSB_MASK 0x00000001
+#define SYNTH_SYNTH8_FORCE_FRACLSB_GET(x) (((x) & SYNTH_SYNTH8_FORCE_FRACLSB_MASK) >> SYNTH_SYNTH8_FORCE_FRACLSB_LSB)
+#define SYNTH_SYNTH8_FORCE_FRACLSB_SET(x) (((x) << SYNTH_SYNTH8_FORCE_FRACLSB_LSB) & SYNTH_SYNTH8_FORCE_FRACLSB_MASK)
+
+#define RF5G_RF5G1_ADDRESS 0x00000020
+#define RF5G_RF5G1_OFFSET 0x00000020
+#define RF5G_RF5G1_PDTXLO5_MSB 31
+#define RF5G_RF5G1_PDTXLO5_LSB 31
+#define RF5G_RF5G1_PDTXLO5_MASK 0x80000000
+#define RF5G_RF5G1_PDTXLO5_GET(x) (((x) & RF5G_RF5G1_PDTXLO5_MASK) >> RF5G_RF5G1_PDTXLO5_LSB)
+#define RF5G_RF5G1_PDTXLO5_SET(x) (((x) << RF5G_RF5G1_PDTXLO5_LSB) & RF5G_RF5G1_PDTXLO5_MASK)
+#define RF5G_RF5G1_PDTXMIX5_MSB 30
+#define RF5G_RF5G1_PDTXMIX5_LSB 30
+#define RF5G_RF5G1_PDTXMIX5_MASK 0x40000000
+#define RF5G_RF5G1_PDTXMIX5_GET(x) (((x) & RF5G_RF5G1_PDTXMIX5_MASK) >> RF5G_RF5G1_PDTXMIX5_LSB)
+#define RF5G_RF5G1_PDTXMIX5_SET(x) (((x) << RF5G_RF5G1_PDTXMIX5_LSB) & RF5G_RF5G1_PDTXMIX5_MASK)
+#define RF5G_RF5G1_PDTXBUF5_MSB 29
+#define RF5G_RF5G1_PDTXBUF5_LSB 29
+#define RF5G_RF5G1_PDTXBUF5_MASK 0x20000000
+#define RF5G_RF5G1_PDTXBUF5_GET(x) (((x) & RF5G_RF5G1_PDTXBUF5_MASK) >> RF5G_RF5G1_PDTXBUF5_LSB)
+#define RF5G_RF5G1_PDTXBUF5_SET(x) (((x) << RF5G_RF5G1_PDTXBUF5_LSB) & RF5G_RF5G1_PDTXBUF5_MASK)
+#define RF5G_RF5G1_PDPADRV5_MSB 28
+#define RF5G_RF5G1_PDPADRV5_LSB 28
+#define RF5G_RF5G1_PDPADRV5_MASK 0x10000000
+#define RF5G_RF5G1_PDPADRV5_GET(x) (((x) & RF5G_RF5G1_PDPADRV5_MASK) >> RF5G_RF5G1_PDPADRV5_LSB)
+#define RF5G_RF5G1_PDPADRV5_SET(x) (((x) << RF5G_RF5G1_PDPADRV5_LSB) & RF5G_RF5G1_PDPADRV5_MASK)
+#define RF5G_RF5G1_PDPAOUT5_MSB 27
+#define RF5G_RF5G1_PDPAOUT5_LSB 27
+#define RF5G_RF5G1_PDPAOUT5_MASK 0x08000000
+#define RF5G_RF5G1_PDPAOUT5_GET(x) (((x) & RF5G_RF5G1_PDPAOUT5_MASK) >> RF5G_RF5G1_PDPAOUT5_LSB)
+#define RF5G_RF5G1_PDPAOUT5_SET(x) (((x) << RF5G_RF5G1_PDPAOUT5_LSB) & RF5G_RF5G1_PDPAOUT5_MASK)
+#define RF5G_RF5G1_TUNE_PADRV5_MSB 26
+#define RF5G_RF5G1_TUNE_PADRV5_LSB 24
+#define RF5G_RF5G1_TUNE_PADRV5_MASK 0x07000000
+#define RF5G_RF5G1_TUNE_PADRV5_GET(x) (((x) & RF5G_RF5G1_TUNE_PADRV5_MASK) >> RF5G_RF5G1_TUNE_PADRV5_LSB)
+#define RF5G_RF5G1_TUNE_PADRV5_SET(x) (((x) << RF5G_RF5G1_TUNE_PADRV5_LSB) & RF5G_RF5G1_TUNE_PADRV5_MASK)
+#define RF5G_RF5G1_PWDTXPKD_MSB 23
+#define RF5G_RF5G1_PWDTXPKD_LSB 21
+#define RF5G_RF5G1_PWDTXPKD_MASK 0x00e00000
+#define RF5G_RF5G1_PWDTXPKD_GET(x) (((x) & RF5G_RF5G1_PWDTXPKD_MASK) >> RF5G_RF5G1_PWDTXPKD_LSB)
+#define RF5G_RF5G1_PWDTXPKD_SET(x) (((x) << RF5G_RF5G1_PWDTXPKD_LSB) & RF5G_RF5G1_PWDTXPKD_MASK)
+#define RF5G_RF5G1_DB5_MSB 20
+#define RF5G_RF5G1_DB5_LSB 18
+#define RF5G_RF5G1_DB5_MASK 0x001c0000
+#define RF5G_RF5G1_DB5_GET(x) (((x) & RF5G_RF5G1_DB5_MASK) >> RF5G_RF5G1_DB5_LSB)
+#define RF5G_RF5G1_DB5_SET(x) (((x) << RF5G_RF5G1_DB5_LSB) & RF5G_RF5G1_DB5_MASK)
+#define RF5G_RF5G1_OB5_MSB 17
+#define RF5G_RF5G1_OB5_LSB 15
+#define RF5G_RF5G1_OB5_MASK 0x00038000
+#define RF5G_RF5G1_OB5_GET(x) (((x) & RF5G_RF5G1_OB5_MASK) >> RF5G_RF5G1_OB5_LSB)
+#define RF5G_RF5G1_OB5_SET(x) (((x) << RF5G_RF5G1_OB5_LSB) & RF5G_RF5G1_OB5_MASK)
+#define RF5G_RF5G1_TX5_ATB_SEL_MSB 14
+#define RF5G_RF5G1_TX5_ATB_SEL_LSB 12
+#define RF5G_RF5G1_TX5_ATB_SEL_MASK 0x00007000
+#define RF5G_RF5G1_TX5_ATB_SEL_GET(x) (((x) & RF5G_RF5G1_TX5_ATB_SEL_MASK) >> RF5G_RF5G1_TX5_ATB_SEL_LSB)
+#define RF5G_RF5G1_TX5_ATB_SEL_SET(x) (((x) << RF5G_RF5G1_TX5_ATB_SEL_LSB) & RF5G_RF5G1_TX5_ATB_SEL_MASK)
+#define RF5G_RF5G1_PDLO5DIV_MSB 11
+#define RF5G_RF5G1_PDLO5DIV_LSB 11
+#define RF5G_RF5G1_PDLO5DIV_MASK 0x00000800
+#define RF5G_RF5G1_PDLO5DIV_GET(x) (((x) & RF5G_RF5G1_PDLO5DIV_MASK) >> RF5G_RF5G1_PDLO5DIV_LSB)
+#define RF5G_RF5G1_PDLO5DIV_SET(x) (((x) << RF5G_RF5G1_PDLO5DIV_LSB) & RF5G_RF5G1_PDLO5DIV_MASK)
+#define RF5G_RF5G1_PDLO5MIX_MSB 10
+#define RF5G_RF5G1_PDLO5MIX_LSB 10
+#define RF5G_RF5G1_PDLO5MIX_MASK 0x00000400
+#define RF5G_RF5G1_PDLO5MIX_GET(x) (((x) & RF5G_RF5G1_PDLO5MIX_MASK) >> RF5G_RF5G1_PDLO5MIX_LSB)
+#define RF5G_RF5G1_PDLO5MIX_SET(x) (((x) << RF5G_RF5G1_PDLO5MIX_LSB) & RF5G_RF5G1_PDLO5MIX_MASK)
+#define RF5G_RF5G1_PDQBUF5_MSB 9
+#define RF5G_RF5G1_PDQBUF5_LSB 9
+#define RF5G_RF5G1_PDQBUF5_MASK 0x00000200
+#define RF5G_RF5G1_PDQBUF5_GET(x) (((x) & RF5G_RF5G1_PDQBUF5_MASK) >> RF5G_RF5G1_PDQBUF5_LSB)
+#define RF5G_RF5G1_PDQBUF5_SET(x) (((x) << RF5G_RF5G1_PDQBUF5_LSB) & RF5G_RF5G1_PDQBUF5_MASK)
+#define RF5G_RF5G1_PDLO5AGC_MSB 8
+#define RF5G_RF5G1_PDLO5AGC_LSB 8
+#define RF5G_RF5G1_PDLO5AGC_MASK 0x00000100
+#define RF5G_RF5G1_PDLO5AGC_GET(x) (((x) & RF5G_RF5G1_PDLO5AGC_MASK) >> RF5G_RF5G1_PDLO5AGC_LSB)
+#define RF5G_RF5G1_PDLO5AGC_SET(x) (((x) << RF5G_RF5G1_PDLO5AGC_LSB) & RF5G_RF5G1_PDLO5AGC_MASK)
+#define RF5G_RF5G1_PDREGLO5_MSB 7
+#define RF5G_RF5G1_PDREGLO5_LSB 7
+#define RF5G_RF5G1_PDREGLO5_MASK 0x00000080
+#define RF5G_RF5G1_PDREGLO5_GET(x) (((x) & RF5G_RF5G1_PDREGLO5_MASK) >> RF5G_RF5G1_PDREGLO5_LSB)
+#define RF5G_RF5G1_PDREGLO5_SET(x) (((x) << RF5G_RF5G1_PDREGLO5_LSB) & RF5G_RF5G1_PDREGLO5_MASK)
+#define RF5G_RF5G1_LO5_ATB_SEL_MSB 6
+#define RF5G_RF5G1_LO5_ATB_SEL_LSB 4
+#define RF5G_RF5G1_LO5_ATB_SEL_MASK 0x00000070
+#define RF5G_RF5G1_LO5_ATB_SEL_GET(x) (((x) & RF5G_RF5G1_LO5_ATB_SEL_MASK) >> RF5G_RF5G1_LO5_ATB_SEL_LSB)
+#define RF5G_RF5G1_LO5_ATB_SEL_SET(x) (((x) << RF5G_RF5G1_LO5_ATB_SEL_LSB) & RF5G_RF5G1_LO5_ATB_SEL_MASK)
+#define RF5G_RF5G1_LO5CONTROL_MSB 3
+#define RF5G_RF5G1_LO5CONTROL_LSB 3
+#define RF5G_RF5G1_LO5CONTROL_MASK 0x00000008
+#define RF5G_RF5G1_LO5CONTROL_GET(x) (((x) & RF5G_RF5G1_LO5CONTROL_MASK) >> RF5G_RF5G1_LO5CONTROL_LSB)
+#define RF5G_RF5G1_LO5CONTROL_SET(x) (((x) << RF5G_RF5G1_LO5CONTROL_LSB) & RF5G_RF5G1_LO5CONTROL_MASK)
+#define RF5G_RF5G1_REGLO_BYPASS5_MSB 2
+#define RF5G_RF5G1_REGLO_BYPASS5_LSB 2
+#define RF5G_RF5G1_REGLO_BYPASS5_MASK 0x00000004
+#define RF5G_RF5G1_REGLO_BYPASS5_GET(x) (((x) & RF5G_RF5G1_REGLO_BYPASS5_MASK) >> RF5G_RF5G1_REGLO_BYPASS5_LSB)
+#define RF5G_RF5G1_REGLO_BYPASS5_SET(x) (((x) << RF5G_RF5G1_REGLO_BYPASS5_LSB) & RF5G_RF5G1_REGLO_BYPASS5_MASK)
+#define RF5G_RF5G1_SPARE_MSB 1
+#define RF5G_RF5G1_SPARE_LSB 0
+#define RF5G_RF5G1_SPARE_MASK 0x00000003
+#define RF5G_RF5G1_SPARE_GET(x) (((x) & RF5G_RF5G1_SPARE_MASK) >> RF5G_RF5G1_SPARE_LSB)
+#define RF5G_RF5G1_SPARE_SET(x) (((x) << RF5G_RF5G1_SPARE_LSB) & RF5G_RF5G1_SPARE_MASK)
+
+#define RF5G_RF5G2_ADDRESS 0x00000024
+#define RF5G_RF5G2_OFFSET 0x00000024
+#define RF5G_RF5G2_AGCLO_B_MSB 31
+#define RF5G_RF5G2_AGCLO_B_LSB 29
+#define RF5G_RF5G2_AGCLO_B_MASK 0xe0000000
+#define RF5G_RF5G2_AGCLO_B_GET(x) (((x) & RF5G_RF5G2_AGCLO_B_MASK) >> RF5G_RF5G2_AGCLO_B_LSB)
+#define RF5G_RF5G2_AGCLO_B_SET(x) (((x) << RF5G_RF5G2_AGCLO_B_LSB) & RF5G_RF5G2_AGCLO_B_MASK)
+#define RF5G_RF5G2_RX5_ATB_SEL_MSB 28
+#define RF5G_RF5G2_RX5_ATB_SEL_LSB 26
+#define RF5G_RF5G2_RX5_ATB_SEL_MASK 0x1c000000
+#define RF5G_RF5G2_RX5_ATB_SEL_GET(x) (((x) & RF5G_RF5G2_RX5_ATB_SEL_MASK) >> RF5G_RF5G2_RX5_ATB_SEL_LSB)
+#define RF5G_RF5G2_RX5_ATB_SEL_SET(x) (((x) << RF5G_RF5G2_RX5_ATB_SEL_LSB) & RF5G_RF5G2_RX5_ATB_SEL_MASK)
+#define RF5G_RF5G2_PDCMOSLO5_MSB 25
+#define RF5G_RF5G2_PDCMOSLO5_LSB 25
+#define RF5G_RF5G2_PDCMOSLO5_MASK 0x02000000
+#define RF5G_RF5G2_PDCMOSLO5_GET(x) (((x) & RF5G_RF5G2_PDCMOSLO5_MASK) >> RF5G_RF5G2_PDCMOSLO5_LSB)
+#define RF5G_RF5G2_PDCMOSLO5_SET(x) (((x) << RF5G_RF5G2_PDCMOSLO5_LSB) & RF5G_RF5G2_PDCMOSLO5_MASK)
+#define RF5G_RF5G2_PDVGM5_MSB 24
+#define RF5G_RF5G2_PDVGM5_LSB 24
+#define RF5G_RF5G2_PDVGM5_MASK 0x01000000
+#define RF5G_RF5G2_PDVGM5_GET(x) (((x) & RF5G_RF5G2_PDVGM5_MASK) >> RF5G_RF5G2_PDVGM5_LSB)
+#define RF5G_RF5G2_PDVGM5_SET(x) (((x) << RF5G_RF5G2_PDVGM5_LSB) & RF5G_RF5G2_PDVGM5_MASK)
+#define RF5G_RF5G2_PDCSLNA5_MSB 23
+#define RF5G_RF5G2_PDCSLNA5_LSB 23
+#define RF5G_RF5G2_PDCSLNA5_MASK 0x00800000
+#define RF5G_RF5G2_PDCSLNA5_GET(x) (((x) & RF5G_RF5G2_PDCSLNA5_MASK) >> RF5G_RF5G2_PDCSLNA5_LSB)
+#define RF5G_RF5G2_PDCSLNA5_SET(x) (((x) << RF5G_RF5G2_PDCSLNA5_LSB) & RF5G_RF5G2_PDCSLNA5_MASK)
+#define RF5G_RF5G2_PDRFVGA5_MSB 22
+#define RF5G_RF5G2_PDRFVGA5_LSB 22
+#define RF5G_RF5G2_PDRFVGA5_MASK 0x00400000
+#define RF5G_RF5G2_PDRFVGA5_GET(x) (((x) & RF5G_RF5G2_PDRFVGA5_MASK) >> RF5G_RF5G2_PDRFVGA5_LSB)
+#define RF5G_RF5G2_PDRFVGA5_SET(x) (((x) << RF5G_RF5G2_PDRFVGA5_LSB) & RF5G_RF5G2_PDRFVGA5_MASK)
+#define RF5G_RF5G2_PDREGFE5_MSB 21
+#define RF5G_RF5G2_PDREGFE5_LSB 21
+#define RF5G_RF5G2_PDREGFE5_MASK 0x00200000
+#define RF5G_RF5G2_PDREGFE5_GET(x) (((x) & RF5G_RF5G2_PDREGFE5_MASK) >> RF5G_RF5G2_PDREGFE5_LSB)
+#define RF5G_RF5G2_PDREGFE5_SET(x) (((x) << RF5G_RF5G2_PDREGFE5_LSB) & RF5G_RF5G2_PDREGFE5_MASK)
+#define RF5G_RF5G2_TUNE_RFVGA5_MSB 20
+#define RF5G_RF5G2_TUNE_RFVGA5_LSB 18
+#define RF5G_RF5G2_TUNE_RFVGA5_MASK 0x001c0000
+#define RF5G_RF5G2_TUNE_RFVGA5_GET(x) (((x) & RF5G_RF5G2_TUNE_RFVGA5_MASK) >> RF5G_RF5G2_TUNE_RFVGA5_LSB)
+#define RF5G_RF5G2_TUNE_RFVGA5_SET(x) (((x) << RF5G_RF5G2_TUNE_RFVGA5_LSB) & RF5G_RF5G2_TUNE_RFVGA5_MASK)
+#define RF5G_RF5G2_BRFVGA5_MSB 17
+#define RF5G_RF5G2_BRFVGA5_LSB 15
+#define RF5G_RF5G2_BRFVGA5_MASK 0x00038000
+#define RF5G_RF5G2_BRFVGA5_GET(x) (((x) & RF5G_RF5G2_BRFVGA5_MASK) >> RF5G_RF5G2_BRFVGA5_LSB)
+#define RF5G_RF5G2_BRFVGA5_SET(x) (((x) << RF5G_RF5G2_BRFVGA5_LSB) & RF5G_RF5G2_BRFVGA5_MASK)
+#define RF5G_RF5G2_BCSLNA5_MSB 14
+#define RF5G_RF5G2_BCSLNA5_LSB 12
+#define RF5G_RF5G2_BCSLNA5_MASK 0x00007000
+#define RF5G_RF5G2_BCSLNA5_GET(x) (((x) & RF5G_RF5G2_BCSLNA5_MASK) >> RF5G_RF5G2_BCSLNA5_LSB)
+#define RF5G_RF5G2_BCSLNA5_SET(x) (((x) << RF5G_RF5G2_BCSLNA5_LSB) & RF5G_RF5G2_BCSLNA5_MASK)
+#define RF5G_RF5G2_BVGM5_MSB 11
+#define RF5G_RF5G2_BVGM5_LSB 9
+#define RF5G_RF5G2_BVGM5_MASK 0x00000e00
+#define RF5G_RF5G2_BVGM5_GET(x) (((x) & RF5G_RF5G2_BVGM5_MASK) >> RF5G_RF5G2_BVGM5_LSB)
+#define RF5G_RF5G2_BVGM5_SET(x) (((x) << RF5G_RF5G2_BVGM5_LSB) & RF5G_RF5G2_BVGM5_MASK)
+#define RF5G_RF5G2_REGFE_BYPASS5_MSB 8
+#define RF5G_RF5G2_REGFE_BYPASS5_LSB 8
+#define RF5G_RF5G2_REGFE_BYPASS5_MASK 0x00000100
+#define RF5G_RF5G2_REGFE_BYPASS5_GET(x) (((x) & RF5G_RF5G2_REGFE_BYPASS5_MASK) >> RF5G_RF5G2_REGFE_BYPASS5_LSB)
+#define RF5G_RF5G2_REGFE_BYPASS5_SET(x) (((x) << RF5G_RF5G2_REGFE_BYPASS5_LSB) & RF5G_RF5G2_REGFE_BYPASS5_MASK)
+#define RF5G_RF5G2_LNA5_ATTENMODE_MSB 7
+#define RF5G_RF5G2_LNA5_ATTENMODE_LSB 6
+#define RF5G_RF5G2_LNA5_ATTENMODE_MASK 0x000000c0
+#define RF5G_RF5G2_LNA5_ATTENMODE_GET(x) (((x) & RF5G_RF5G2_LNA5_ATTENMODE_MASK) >> RF5G_RF5G2_LNA5_ATTENMODE_LSB)
+#define RF5G_RF5G2_LNA5_ATTENMODE_SET(x) (((x) << RF5G_RF5G2_LNA5_ATTENMODE_LSB) & RF5G_RF5G2_LNA5_ATTENMODE_MASK)
+#define RF5G_RF5G2_ENABLE_PCA_MSB 5
+#define RF5G_RF5G2_ENABLE_PCA_LSB 5
+#define RF5G_RF5G2_ENABLE_PCA_MASK 0x00000020
+#define RF5G_RF5G2_ENABLE_PCA_GET(x) (((x) & RF5G_RF5G2_ENABLE_PCA_MASK) >> RF5G_RF5G2_ENABLE_PCA_LSB)
+#define RF5G_RF5G2_ENABLE_PCA_SET(x) (((x) << RF5G_RF5G2_ENABLE_PCA_LSB) & RF5G_RF5G2_ENABLE_PCA_MASK)
+#define RF5G_RF5G2_TUNE_LO_MSB 4
+#define RF5G_RF5G2_TUNE_LO_LSB 2
+#define RF5G_RF5G2_TUNE_LO_MASK 0x0000001c
+#define RF5G_RF5G2_TUNE_LO_GET(x) (((x) & RF5G_RF5G2_TUNE_LO_MASK) >> RF5G_RF5G2_TUNE_LO_LSB)
+#define RF5G_RF5G2_TUNE_LO_SET(x) (((x) << RF5G_RF5G2_TUNE_LO_LSB) & RF5G_RF5G2_TUNE_LO_MASK)
+#define RF5G_RF5G2_SPARE_MSB 1
+#define RF5G_RF5G2_SPARE_LSB 0
+#define RF5G_RF5G2_SPARE_MASK 0x00000003
+#define RF5G_RF5G2_SPARE_GET(x) (((x) & RF5G_RF5G2_SPARE_MASK) >> RF5G_RF5G2_SPARE_LSB)
+#define RF5G_RF5G2_SPARE_SET(x) (((x) << RF5G_RF5G2_SPARE_LSB) & RF5G_RF5G2_SPARE_MASK)
+
+#define RF2G_RF2G1_ADDRESS 0x00000028
+#define RF2G_RF2G1_OFFSET 0x00000028
+#define RF2G_RF2G1_BLNA1_MSB 31
+#define RF2G_RF2G1_BLNA1_LSB 29
+#define RF2G_RF2G1_BLNA1_MASK 0xe0000000
+#define RF2G_RF2G1_BLNA1_GET(x) (((x) & RF2G_RF2G1_BLNA1_MASK) >> RF2G_RF2G1_BLNA1_LSB)
+#define RF2G_RF2G1_BLNA1_SET(x) (((x) << RF2G_RF2G1_BLNA1_LSB) & RF2G_RF2G1_BLNA1_MASK)
+#define RF2G_RF2G1_BLNA1F_MSB 28
+#define RF2G_RF2G1_BLNA1F_LSB 26
+#define RF2G_RF2G1_BLNA1F_MASK 0x1c000000
+#define RF2G_RF2G1_BLNA1F_GET(x) (((x) & RF2G_RF2G1_BLNA1F_MASK) >> RF2G_RF2G1_BLNA1F_LSB)
+#define RF2G_RF2G1_BLNA1F_SET(x) (((x) << RF2G_RF2G1_BLNA1F_LSB) & RF2G_RF2G1_BLNA1F_MASK)
+#define RF2G_RF2G1_BLNA1BUF_MSB 25
+#define RF2G_RF2G1_BLNA1BUF_LSB 23
+#define RF2G_RF2G1_BLNA1BUF_MASK 0x03800000
+#define RF2G_RF2G1_BLNA1BUF_GET(x) (((x) & RF2G_RF2G1_BLNA1BUF_MASK) >> RF2G_RF2G1_BLNA1BUF_LSB)
+#define RF2G_RF2G1_BLNA1BUF_SET(x) (((x) << RF2G_RF2G1_BLNA1BUF_LSB) & RF2G_RF2G1_BLNA1BUF_MASK)
+#define RF2G_RF2G1_BLNA2_MSB 22
+#define RF2G_RF2G1_BLNA2_LSB 20
+#define RF2G_RF2G1_BLNA2_MASK 0x00700000
+#define RF2G_RF2G1_BLNA2_GET(x) (((x) & RF2G_RF2G1_BLNA2_MASK) >> RF2G_RF2G1_BLNA2_LSB)
+#define RF2G_RF2G1_BLNA2_SET(x) (((x) << RF2G_RF2G1_BLNA2_LSB) & RF2G_RF2G1_BLNA2_MASK)
+#define RF2G_RF2G1_DB_MSB 19
+#define RF2G_RF2G1_DB_LSB 17
+#define RF2G_RF2G1_DB_MASK 0x000e0000
+#define RF2G_RF2G1_DB_GET(x) (((x) & RF2G_RF2G1_DB_MASK) >> RF2G_RF2G1_DB_LSB)
+#define RF2G_RF2G1_DB_SET(x) (((x) << RF2G_RF2G1_DB_LSB) & RF2G_RF2G1_DB_MASK)
+#define RF2G_RF2G1_OB_MSB 16
+#define RF2G_RF2G1_OB_LSB 14
+#define RF2G_RF2G1_OB_MASK 0x0001c000
+#define RF2G_RF2G1_OB_GET(x) (((x) & RF2G_RF2G1_OB_MASK) >> RF2G_RF2G1_OB_LSB)
+#define RF2G_RF2G1_OB_SET(x) (((x) << RF2G_RF2G1_OB_LSB) & RF2G_RF2G1_OB_MASK)
+#define RF2G_RF2G1_FE_ATB_SEL_MSB 13
+#define RF2G_RF2G1_FE_ATB_SEL_LSB 11
+#define RF2G_RF2G1_FE_ATB_SEL_MASK 0x00003800
+#define RF2G_RF2G1_FE_ATB_SEL_GET(x) (((x) & RF2G_RF2G1_FE_ATB_SEL_MASK) >> RF2G_RF2G1_FE_ATB_SEL_LSB)
+#define RF2G_RF2G1_FE_ATB_SEL_SET(x) (((x) << RF2G_RF2G1_FE_ATB_SEL_LSB) & RF2G_RF2G1_FE_ATB_SEL_MASK)
+#define RF2G_RF2G1_RF_ATB_SEL_MSB 10
+#define RF2G_RF2G1_RF_ATB_SEL_LSB 8
+#define RF2G_RF2G1_RF_ATB_SEL_MASK 0x00000700
+#define RF2G_RF2G1_RF_ATB_SEL_GET(x) (((x) & RF2G_RF2G1_RF_ATB_SEL_MASK) >> RF2G_RF2G1_RF_ATB_SEL_LSB)
+#define RF2G_RF2G1_RF_ATB_SEL_SET(x) (((x) << RF2G_RF2G1_RF_ATB_SEL_LSB) & RF2G_RF2G1_RF_ATB_SEL_MASK)
+#define RF2G_RF2G1_SELLNA_MSB 7
+#define RF2G_RF2G1_SELLNA_LSB 7
+#define RF2G_RF2G1_SELLNA_MASK 0x00000080
+#define RF2G_RF2G1_SELLNA_GET(x) (((x) & RF2G_RF2G1_SELLNA_MASK) >> RF2G_RF2G1_SELLNA_LSB)
+#define RF2G_RF2G1_SELLNA_SET(x) (((x) << RF2G_RF2G1_SELLNA_LSB) & RF2G_RF2G1_SELLNA_MASK)
+#define RF2G_RF2G1_LOCONTROL_MSB 6
+#define RF2G_RF2G1_LOCONTROL_LSB 6
+#define RF2G_RF2G1_LOCONTROL_MASK 0x00000040
+#define RF2G_RF2G1_LOCONTROL_GET(x) (((x) & RF2G_RF2G1_LOCONTROL_MASK) >> RF2G_RF2G1_LOCONTROL_LSB)
+#define RF2G_RF2G1_LOCONTROL_SET(x) (((x) << RF2G_RF2G1_LOCONTROL_LSB) & RF2G_RF2G1_LOCONTROL_MASK)
+#define RF2G_RF2G1_SHORTLNA2_MSB 5
+#define RF2G_RF2G1_SHORTLNA2_LSB 5
+#define RF2G_RF2G1_SHORTLNA2_MASK 0x00000020
+#define RF2G_RF2G1_SHORTLNA2_GET(x) (((x) & RF2G_RF2G1_SHORTLNA2_MASK) >> RF2G_RF2G1_SHORTLNA2_LSB)
+#define RF2G_RF2G1_SHORTLNA2_SET(x) (((x) << RF2G_RF2G1_SHORTLNA2_LSB) & RF2G_RF2G1_SHORTLNA2_MASK)
+#define RF2G_RF2G1_SPARE_MSB 4
+#define RF2G_RF2G1_SPARE_LSB 0
+#define RF2G_RF2G1_SPARE_MASK 0x0000001f
+#define RF2G_RF2G1_SPARE_GET(x) (((x) & RF2G_RF2G1_SPARE_MASK) >> RF2G_RF2G1_SPARE_LSB)
+#define RF2G_RF2G1_SPARE_SET(x) (((x) << RF2G_RF2G1_SPARE_LSB) & RF2G_RF2G1_SPARE_MASK)
+
+#define RF2G_RF2G2_ADDRESS 0x0000002c
+#define RF2G_RF2G2_OFFSET 0x0000002c
+#define RF2G_RF2G2_PDCGLNA_MSB 31
+#define RF2G_RF2G2_PDCGLNA_LSB 31
+#define RF2G_RF2G2_PDCGLNA_MASK 0x80000000
+#define RF2G_RF2G2_PDCGLNA_GET(x) (((x) & RF2G_RF2G2_PDCGLNA_MASK) >> RF2G_RF2G2_PDCGLNA_LSB)
+#define RF2G_RF2G2_PDCGLNA_SET(x) (((x) << RF2G_RF2G2_PDCGLNA_LSB) & RF2G_RF2G2_PDCGLNA_MASK)
+#define RF2G_RF2G2_PDCGLNABUF_MSB 30
+#define RF2G_RF2G2_PDCGLNABUF_LSB 30
+#define RF2G_RF2G2_PDCGLNABUF_MASK 0x40000000
+#define RF2G_RF2G2_PDCGLNABUF_GET(x) (((x) & RF2G_RF2G2_PDCGLNABUF_MASK) >> RF2G_RF2G2_PDCGLNABUF_LSB)
+#define RF2G_RF2G2_PDCGLNABUF_SET(x) (((x) << RF2G_RF2G2_PDCGLNABUF_LSB) & RF2G_RF2G2_PDCGLNABUF_MASK)
+#define RF2G_RF2G2_PDCSLNA_MSB 29
+#define RF2G_RF2G2_PDCSLNA_LSB 29
+#define RF2G_RF2G2_PDCSLNA_MASK 0x20000000
+#define RF2G_RF2G2_PDCSLNA_GET(x) (((x) & RF2G_RF2G2_PDCSLNA_MASK) >> RF2G_RF2G2_PDCSLNA_LSB)
+#define RF2G_RF2G2_PDCSLNA_SET(x) (((x) << RF2G_RF2G2_PDCSLNA_LSB) & RF2G_RF2G2_PDCSLNA_MASK)
+#define RF2G_RF2G2_PDDIV_MSB 28
+#define RF2G_RF2G2_PDDIV_LSB 28
+#define RF2G_RF2G2_PDDIV_MASK 0x10000000
+#define RF2G_RF2G2_PDDIV_GET(x) (((x) & RF2G_RF2G2_PDDIV_MASK) >> RF2G_RF2G2_PDDIV_LSB)
+#define RF2G_RF2G2_PDDIV_SET(x) (((x) << RF2G_RF2G2_PDDIV_LSB) & RF2G_RF2G2_PDDIV_MASK)
+#define RF2G_RF2G2_PDPADRV_MSB 27
+#define RF2G_RF2G2_PDPADRV_LSB 27
+#define RF2G_RF2G2_PDPADRV_MASK 0x08000000
+#define RF2G_RF2G2_PDPADRV_GET(x) (((x) & RF2G_RF2G2_PDPADRV_MASK) >> RF2G_RF2G2_PDPADRV_LSB)
+#define RF2G_RF2G2_PDPADRV_SET(x) (((x) << RF2G_RF2G2_PDPADRV_LSB) & RF2G_RF2G2_PDPADRV_MASK)
+#define RF2G_RF2G2_PDPAOUT_MSB 26
+#define RF2G_RF2G2_PDPAOUT_LSB 26
+#define RF2G_RF2G2_PDPAOUT_MASK 0x04000000
+#define RF2G_RF2G2_PDPAOUT_GET(x) (((x) & RF2G_RF2G2_PDPAOUT_MASK) >> RF2G_RF2G2_PDPAOUT_LSB)
+#define RF2G_RF2G2_PDPAOUT_SET(x) (((x) << RF2G_RF2G2_PDPAOUT_LSB) & RF2G_RF2G2_PDPAOUT_MASK)
+#define RF2G_RF2G2_PDREGLNA_MSB 25
+#define RF2G_RF2G2_PDREGLNA_LSB 25
+#define RF2G_RF2G2_PDREGLNA_MASK 0x02000000
+#define RF2G_RF2G2_PDREGLNA_GET(x) (((x) & RF2G_RF2G2_PDREGLNA_MASK) >> RF2G_RF2G2_PDREGLNA_LSB)
+#define RF2G_RF2G2_PDREGLNA_SET(x) (((x) << RF2G_RF2G2_PDREGLNA_LSB) & RF2G_RF2G2_PDREGLNA_MASK)
+#define RF2G_RF2G2_PDREGLO_MSB 24
+#define RF2G_RF2G2_PDREGLO_LSB 24
+#define RF2G_RF2G2_PDREGLO_MASK 0x01000000
+#define RF2G_RF2G2_PDREGLO_GET(x) (((x) & RF2G_RF2G2_PDREGLO_MASK) >> RF2G_RF2G2_PDREGLO_LSB)
+#define RF2G_RF2G2_PDREGLO_SET(x) (((x) << RF2G_RF2G2_PDREGLO_LSB) & RF2G_RF2G2_PDREGLO_MASK)
+#define RF2G_RF2G2_PDRFGM_MSB 23
+#define RF2G_RF2G2_PDRFGM_LSB 23
+#define RF2G_RF2G2_PDRFGM_MASK 0x00800000
+#define RF2G_RF2G2_PDRFGM_GET(x) (((x) & RF2G_RF2G2_PDRFGM_MASK) >> RF2G_RF2G2_PDRFGM_LSB)
+#define RF2G_RF2G2_PDRFGM_SET(x) (((x) << RF2G_RF2G2_PDRFGM_LSB) & RF2G_RF2G2_PDRFGM_MASK)
+#define RF2G_RF2G2_PDRXLO_MSB 22
+#define RF2G_RF2G2_PDRXLO_LSB 22
+#define RF2G_RF2G2_PDRXLO_MASK 0x00400000
+#define RF2G_RF2G2_PDRXLO_GET(x) (((x) & RF2G_RF2G2_PDRXLO_MASK) >> RF2G_RF2G2_PDRXLO_LSB)
+#define RF2G_RF2G2_PDRXLO_SET(x) (((x) << RF2G_RF2G2_PDRXLO_LSB) & RF2G_RF2G2_PDRXLO_MASK)
+#define RF2G_RF2G2_PDTXLO_MSB 21
+#define RF2G_RF2G2_PDTXLO_LSB 21
+#define RF2G_RF2G2_PDTXLO_MASK 0x00200000
+#define RF2G_RF2G2_PDTXLO_GET(x) (((x) & RF2G_RF2G2_PDTXLO_MASK) >> RF2G_RF2G2_PDTXLO_LSB)
+#define RF2G_RF2G2_PDTXLO_SET(x) (((x) << RF2G_RF2G2_PDTXLO_LSB) & RF2G_RF2G2_PDTXLO_MASK)
+#define RF2G_RF2G2_PDTXMIX_MSB 20
+#define RF2G_RF2G2_PDTXMIX_LSB 20
+#define RF2G_RF2G2_PDTXMIX_MASK 0x00100000
+#define RF2G_RF2G2_PDTXMIX_GET(x) (((x) & RF2G_RF2G2_PDTXMIX_MASK) >> RF2G_RF2G2_PDTXMIX_LSB)
+#define RF2G_RF2G2_PDTXMIX_SET(x) (((x) << RF2G_RF2G2_PDTXMIX_LSB) & RF2G_RF2G2_PDTXMIX_MASK)
+#define RF2G_RF2G2_REGLNA_BYPASS_MSB 19
+#define RF2G_RF2G2_REGLNA_BYPASS_LSB 19
+#define RF2G_RF2G2_REGLNA_BYPASS_MASK 0x00080000
+#define RF2G_RF2G2_REGLNA_BYPASS_GET(x) (((x) & RF2G_RF2G2_REGLNA_BYPASS_MASK) >> RF2G_RF2G2_REGLNA_BYPASS_LSB)
+#define RF2G_RF2G2_REGLNA_BYPASS_SET(x) (((x) << RF2G_RF2G2_REGLNA_BYPASS_LSB) & RF2G_RF2G2_REGLNA_BYPASS_MASK)
+#define RF2G_RF2G2_REGLO_BYPASS_MSB 18
+#define RF2G_RF2G2_REGLO_BYPASS_LSB 18
+#define RF2G_RF2G2_REGLO_BYPASS_MASK 0x00040000
+#define RF2G_RF2G2_REGLO_BYPASS_GET(x) (((x) & RF2G_RF2G2_REGLO_BYPASS_MASK) >> RF2G_RF2G2_REGLO_BYPASS_LSB)
+#define RF2G_RF2G2_REGLO_BYPASS_SET(x) (((x) << RF2G_RF2G2_REGLO_BYPASS_LSB) & RF2G_RF2G2_REGLO_BYPASS_MASK)
+#define RF2G_RF2G2_ENABLE_PCB_MSB 17
+#define RF2G_RF2G2_ENABLE_PCB_LSB 17
+#define RF2G_RF2G2_ENABLE_PCB_MASK 0x00020000
+#define RF2G_RF2G2_ENABLE_PCB_GET(x) (((x) & RF2G_RF2G2_ENABLE_PCB_MASK) >> RF2G_RF2G2_ENABLE_PCB_LSB)
+#define RF2G_RF2G2_ENABLE_PCB_SET(x) (((x) << RF2G_RF2G2_ENABLE_PCB_LSB) & RF2G_RF2G2_ENABLE_PCB_MASK)
+#define RF2G_RF2G2_SPARE_MSB 16
+#define RF2G_RF2G2_SPARE_LSB 0
+#define RF2G_RF2G2_SPARE_MASK 0x0001ffff
+#define RF2G_RF2G2_SPARE_GET(x) (((x) & RF2G_RF2G2_SPARE_MASK) >> RF2G_RF2G2_SPARE_LSB)
+#define RF2G_RF2G2_SPARE_SET(x) (((x) << RF2G_RF2G2_SPARE_LSB) & RF2G_RF2G2_SPARE_MASK)
+
+#define TOP_GAIN_ADDRESS 0x00000030
+#define TOP_GAIN_OFFSET 0x00000030
+#define TOP_GAIN_TX6DBLOQGAIN_MSB 31
+#define TOP_GAIN_TX6DBLOQGAIN_LSB 30
+#define TOP_GAIN_TX6DBLOQGAIN_MASK 0xc0000000
+#define TOP_GAIN_TX6DBLOQGAIN_GET(x) (((x) & TOP_GAIN_TX6DBLOQGAIN_MASK) >> TOP_GAIN_TX6DBLOQGAIN_LSB)
+#define TOP_GAIN_TX6DBLOQGAIN_SET(x) (((x) << TOP_GAIN_TX6DBLOQGAIN_LSB) & TOP_GAIN_TX6DBLOQGAIN_MASK)
+#define TOP_GAIN_TX1DBLOQGAIN_MSB 29
+#define TOP_GAIN_TX1DBLOQGAIN_LSB 27
+#define TOP_GAIN_TX1DBLOQGAIN_MASK 0x38000000
+#define TOP_GAIN_TX1DBLOQGAIN_GET(x) (((x) & TOP_GAIN_TX1DBLOQGAIN_MASK) >> TOP_GAIN_TX1DBLOQGAIN_LSB)
+#define TOP_GAIN_TX1DBLOQGAIN_SET(x) (((x) << TOP_GAIN_TX1DBLOQGAIN_LSB) & TOP_GAIN_TX1DBLOQGAIN_MASK)
+#define TOP_GAIN_TXV2IGAIN_MSB 26
+#define TOP_GAIN_TXV2IGAIN_LSB 25
+#define TOP_GAIN_TXV2IGAIN_MASK 0x06000000
+#define TOP_GAIN_TXV2IGAIN_GET(x) (((x) & TOP_GAIN_TXV2IGAIN_MASK) >> TOP_GAIN_TXV2IGAIN_LSB)
+#define TOP_GAIN_TXV2IGAIN_SET(x) (((x) << TOP_GAIN_TXV2IGAIN_LSB) & TOP_GAIN_TXV2IGAIN_MASK)
+#define TOP_GAIN_PABUF5GN_MSB 24
+#define TOP_GAIN_PABUF5GN_LSB 24
+#define TOP_GAIN_PABUF5GN_MASK 0x01000000
+#define TOP_GAIN_PABUF5GN_GET(x) (((x) & TOP_GAIN_PABUF5GN_MASK) >> TOP_GAIN_PABUF5GN_LSB)
+#define TOP_GAIN_PABUF5GN_SET(x) (((x) << TOP_GAIN_PABUF5GN_LSB) & TOP_GAIN_PABUF5GN_MASK)
+#define TOP_GAIN_PADRVGN_MSB 23
+#define TOP_GAIN_PADRVGN_LSB 21
+#define TOP_GAIN_PADRVGN_MASK 0x00e00000
+#define TOP_GAIN_PADRVGN_GET(x) (((x) & TOP_GAIN_PADRVGN_MASK) >> TOP_GAIN_PADRVGN_LSB)
+#define TOP_GAIN_PADRVGN_SET(x) (((x) << TOP_GAIN_PADRVGN_LSB) & TOP_GAIN_PADRVGN_MASK)
+#define TOP_GAIN_PAOUT2GN_MSB 20
+#define TOP_GAIN_PAOUT2GN_LSB 18
+#define TOP_GAIN_PAOUT2GN_MASK 0x001c0000
+#define TOP_GAIN_PAOUT2GN_GET(x) (((x) & TOP_GAIN_PAOUT2GN_MASK) >> TOP_GAIN_PAOUT2GN_LSB)
+#define TOP_GAIN_PAOUT2GN_SET(x) (((x) << TOP_GAIN_PAOUT2GN_LSB) & TOP_GAIN_PAOUT2GN_MASK)
+#define TOP_GAIN_LNAON_MSB 17
+#define TOP_GAIN_LNAON_LSB 17
+#define TOP_GAIN_LNAON_MASK 0x00020000
+#define TOP_GAIN_LNAON_GET(x) (((x) & TOP_GAIN_LNAON_MASK) >> TOP_GAIN_LNAON_LSB)
+#define TOP_GAIN_LNAON_SET(x) (((x) << TOP_GAIN_LNAON_LSB) & TOP_GAIN_LNAON_MASK)
+#define TOP_GAIN_LNAGAIN_MSB 16
+#define TOP_GAIN_LNAGAIN_LSB 13
+#define TOP_GAIN_LNAGAIN_MASK 0x0001e000
+#define TOP_GAIN_LNAGAIN_GET(x) (((x) & TOP_GAIN_LNAGAIN_MASK) >> TOP_GAIN_LNAGAIN_LSB)
+#define TOP_GAIN_LNAGAIN_SET(x) (((x) << TOP_GAIN_LNAGAIN_LSB) & TOP_GAIN_LNAGAIN_MASK)
+#define TOP_GAIN_RFVGA5GAIN_MSB 12
+#define TOP_GAIN_RFVGA5GAIN_LSB 11
+#define TOP_GAIN_RFVGA5GAIN_MASK 0x00001800
+#define TOP_GAIN_RFVGA5GAIN_GET(x) (((x) & TOP_GAIN_RFVGA5GAIN_MASK) >> TOP_GAIN_RFVGA5GAIN_LSB)
+#define TOP_GAIN_RFVGA5GAIN_SET(x) (((x) << TOP_GAIN_RFVGA5GAIN_LSB) & TOP_GAIN_RFVGA5GAIN_MASK)
+#define TOP_GAIN_RFGMGN_MSB 10
+#define TOP_GAIN_RFGMGN_LSB 8
+#define TOP_GAIN_RFGMGN_MASK 0x00000700
+#define TOP_GAIN_RFGMGN_GET(x) (((x) & TOP_GAIN_RFGMGN_MASK) >> TOP_GAIN_RFGMGN_LSB)
+#define TOP_GAIN_RFGMGN_SET(x) (((x) << TOP_GAIN_RFGMGN_LSB) & TOP_GAIN_RFGMGN_MASK)
+#define TOP_GAIN_RX6DBLOQGAIN_MSB 7
+#define TOP_GAIN_RX6DBLOQGAIN_LSB 6
+#define TOP_GAIN_RX6DBLOQGAIN_MASK 0x000000c0
+#define TOP_GAIN_RX6DBLOQGAIN_GET(x) (((x) & TOP_GAIN_RX6DBLOQGAIN_MASK) >> TOP_GAIN_RX6DBLOQGAIN_LSB)
+#define TOP_GAIN_RX6DBLOQGAIN_SET(x) (((x) << TOP_GAIN_RX6DBLOQGAIN_LSB) & TOP_GAIN_RX6DBLOQGAIN_MASK)
+#define TOP_GAIN_RX1DBLOQGAIN_MSB 5
+#define TOP_GAIN_RX1DBLOQGAIN_LSB 3
+#define TOP_GAIN_RX1DBLOQGAIN_MASK 0x00000038
+#define TOP_GAIN_RX1DBLOQGAIN_GET(x) (((x) & TOP_GAIN_RX1DBLOQGAIN_MASK) >> TOP_GAIN_RX1DBLOQGAIN_LSB)
+#define TOP_GAIN_RX1DBLOQGAIN_SET(x) (((x) << TOP_GAIN_RX1DBLOQGAIN_LSB) & TOP_GAIN_RX1DBLOQGAIN_MASK)
+#define TOP_GAIN_RX6DBHIQGAIN_MSB 2
+#define TOP_GAIN_RX6DBHIQGAIN_LSB 1
+#define TOP_GAIN_RX6DBHIQGAIN_MASK 0x00000006
+#define TOP_GAIN_RX6DBHIQGAIN_GET(x) (((x) & TOP_GAIN_RX6DBHIQGAIN_MASK) >> TOP_GAIN_RX6DBHIQGAIN_LSB)
+#define TOP_GAIN_RX6DBHIQGAIN_SET(x) (((x) << TOP_GAIN_RX6DBHIQGAIN_LSB) & TOP_GAIN_RX6DBHIQGAIN_MASK)
+#define TOP_GAIN_SPARE_MSB 0
+#define TOP_GAIN_SPARE_LSB 0
+#define TOP_GAIN_SPARE_MASK 0x00000001
+#define TOP_GAIN_SPARE_GET(x) (((x) & TOP_GAIN_SPARE_MASK) >> TOP_GAIN_SPARE_LSB)
+#define TOP_GAIN_SPARE_SET(x) (((x) << TOP_GAIN_SPARE_LSB) & TOP_GAIN_SPARE_MASK)
+
+#define TOP_TOP_ADDRESS 0x00000034
+#define TOP_TOP_OFFSET 0x00000034
+#define TOP_TOP_LOCALTXGAIN_MSB 31
+#define TOP_TOP_LOCALTXGAIN_LSB 31
+#define TOP_TOP_LOCALTXGAIN_MASK 0x80000000
+#define TOP_TOP_LOCALTXGAIN_GET(x) (((x) & TOP_TOP_LOCALTXGAIN_MASK) >> TOP_TOP_LOCALTXGAIN_LSB)
+#define TOP_TOP_LOCALTXGAIN_SET(x) (((x) << TOP_TOP_LOCALTXGAIN_LSB) & TOP_TOP_LOCALTXGAIN_MASK)
+#define TOP_TOP_LOCALRXGAIN_MSB 30
+#define TOP_TOP_LOCALRXGAIN_LSB 30
+#define TOP_TOP_LOCALRXGAIN_MASK 0x40000000
+#define TOP_TOP_LOCALRXGAIN_GET(x) (((x) & TOP_TOP_LOCALRXGAIN_MASK) >> TOP_TOP_LOCALRXGAIN_LSB)
+#define TOP_TOP_LOCALRXGAIN_SET(x) (((x) << TOP_TOP_LOCALRXGAIN_LSB) & TOP_TOP_LOCALRXGAIN_MASK)
+#define TOP_TOP_LOCALMODE_MSB 29
+#define TOP_TOP_LOCALMODE_LSB 29
+#define TOP_TOP_LOCALMODE_MASK 0x20000000
+#define TOP_TOP_LOCALMODE_GET(x) (((x) & TOP_TOP_LOCALMODE_MASK) >> TOP_TOP_LOCALMODE_LSB)
+#define TOP_TOP_LOCALMODE_SET(x) (((x) << TOP_TOP_LOCALMODE_LSB) & TOP_TOP_LOCALMODE_MASK)
+#define TOP_TOP_CALFC_MSB 28
+#define TOP_TOP_CALFC_LSB 28
+#define TOP_TOP_CALFC_MASK 0x10000000
+#define TOP_TOP_CALFC_GET(x) (((x) & TOP_TOP_CALFC_MASK) >> TOP_TOP_CALFC_LSB)
+#define TOP_TOP_CALFC_SET(x) (((x) << TOP_TOP_CALFC_LSB) & TOP_TOP_CALFC_MASK)
+#define TOP_TOP_CALDC_MSB 27
+#define TOP_TOP_CALDC_LSB 27
+#define TOP_TOP_CALDC_MASK 0x08000000
+#define TOP_TOP_CALDC_GET(x) (((x) & TOP_TOP_CALDC_MASK) >> TOP_TOP_CALDC_LSB)
+#define TOP_TOP_CALDC_SET(x) (((x) << TOP_TOP_CALDC_LSB) & TOP_TOP_CALDC_MASK)
+#define TOP_TOP_CAL_RESIDUE_MSB 26
+#define TOP_TOP_CAL_RESIDUE_LSB 26
+#define TOP_TOP_CAL_RESIDUE_MASK 0x04000000
+#define TOP_TOP_CAL_RESIDUE_GET(x) (((x) & TOP_TOP_CAL_RESIDUE_MASK) >> TOP_TOP_CAL_RESIDUE_LSB)
+#define TOP_TOP_CAL_RESIDUE_SET(x) (((x) << TOP_TOP_CAL_RESIDUE_LSB) & TOP_TOP_CAL_RESIDUE_MASK)
+#define TOP_TOP_BMODE_MSB 25
+#define TOP_TOP_BMODE_LSB 25
+#define TOP_TOP_BMODE_MASK 0x02000000
+#define TOP_TOP_BMODE_GET(x) (((x) & TOP_TOP_BMODE_MASK) >> TOP_TOP_BMODE_LSB)
+#define TOP_TOP_BMODE_SET(x) (((x) << TOP_TOP_BMODE_LSB) & TOP_TOP_BMODE_MASK)
+#define TOP_TOP_SYNTHON_MSB 24
+#define TOP_TOP_SYNTHON_LSB 24
+#define TOP_TOP_SYNTHON_MASK 0x01000000
+#define TOP_TOP_SYNTHON_GET(x) (((x) & TOP_TOP_SYNTHON_MASK) >> TOP_TOP_SYNTHON_LSB)
+#define TOP_TOP_SYNTHON_SET(x) (((x) << TOP_TOP_SYNTHON_LSB) & TOP_TOP_SYNTHON_MASK)
+#define TOP_TOP_RXON_MSB 23
+#define TOP_TOP_RXON_LSB 23
+#define TOP_TOP_RXON_MASK 0x00800000
+#define TOP_TOP_RXON_GET(x) (((x) & TOP_TOP_RXON_MASK) >> TOP_TOP_RXON_LSB)
+#define TOP_TOP_RXON_SET(x) (((x) << TOP_TOP_RXON_LSB) & TOP_TOP_RXON_MASK)
+#define TOP_TOP_TXON_MSB 22
+#define TOP_TOP_TXON_LSB 22
+#define TOP_TOP_TXON_MASK 0x00400000
+#define TOP_TOP_TXON_GET(x) (((x) & TOP_TOP_TXON_MASK) >> TOP_TOP_TXON_LSB)
+#define TOP_TOP_TXON_SET(x) (((x) << TOP_TOP_TXON_LSB) & TOP_TOP_TXON_MASK)
+#define TOP_TOP_PAON_MSB 21
+#define TOP_TOP_PAON_LSB 21
+#define TOP_TOP_PAON_MASK 0x00200000
+#define TOP_TOP_PAON_GET(x) (((x) & TOP_TOP_PAON_MASK) >> TOP_TOP_PAON_LSB)
+#define TOP_TOP_PAON_SET(x) (((x) << TOP_TOP_PAON_LSB) & TOP_TOP_PAON_MASK)
+#define TOP_TOP_CALTX_MSB 20
+#define TOP_TOP_CALTX_LSB 20
+#define TOP_TOP_CALTX_MASK 0x00100000
+#define TOP_TOP_CALTX_GET(x) (((x) & TOP_TOP_CALTX_MASK) >> TOP_TOP_CALTX_LSB)
+#define TOP_TOP_CALTX_SET(x) (((x) << TOP_TOP_CALTX_LSB) & TOP_TOP_CALTX_MASK)
+#define TOP_TOP_LOCALADDAC_MSB 19
+#define TOP_TOP_LOCALADDAC_LSB 19
+#define TOP_TOP_LOCALADDAC_MASK 0x00080000
+#define TOP_TOP_LOCALADDAC_GET(x) (((x) & TOP_TOP_LOCALADDAC_MASK) >> TOP_TOP_LOCALADDAC_LSB)
+#define TOP_TOP_LOCALADDAC_SET(x) (((x) << TOP_TOP_LOCALADDAC_LSB) & TOP_TOP_LOCALADDAC_MASK)
+#define TOP_TOP_PWDPLL_MSB 18
+#define TOP_TOP_PWDPLL_LSB 18
+#define TOP_TOP_PWDPLL_MASK 0x00040000
+#define TOP_TOP_PWDPLL_GET(x) (((x) & TOP_TOP_PWDPLL_MASK) >> TOP_TOP_PWDPLL_LSB)
+#define TOP_TOP_PWDPLL_SET(x) (((x) << TOP_TOP_PWDPLL_LSB) & TOP_TOP_PWDPLL_MASK)
+#define TOP_TOP_PWDADC_MSB 17
+#define TOP_TOP_PWDADC_LSB 17
+#define TOP_TOP_PWDADC_MASK 0x00020000
+#define TOP_TOP_PWDADC_GET(x) (((x) & TOP_TOP_PWDADC_MASK) >> TOP_TOP_PWDADC_LSB)
+#define TOP_TOP_PWDADC_SET(x) (((x) << TOP_TOP_PWDADC_LSB) & TOP_TOP_PWDADC_MASK)
+#define TOP_TOP_PWDDAC_MSB 16
+#define TOP_TOP_PWDDAC_LSB 16
+#define TOP_TOP_PWDDAC_MASK 0x00010000
+#define TOP_TOP_PWDDAC_GET(x) (((x) & TOP_TOP_PWDDAC_MASK) >> TOP_TOP_PWDDAC_LSB)
+#define TOP_TOP_PWDDAC_SET(x) (((x) << TOP_TOP_PWDDAC_LSB) & TOP_TOP_PWDDAC_MASK)
+#define TOP_TOP_LOCALXTAL_MSB 15
+#define TOP_TOP_LOCALXTAL_LSB 15
+#define TOP_TOP_LOCALXTAL_MASK 0x00008000
+#define TOP_TOP_LOCALXTAL_GET(x) (((x) & TOP_TOP_LOCALXTAL_MASK) >> TOP_TOP_LOCALXTAL_LSB)
+#define TOP_TOP_LOCALXTAL_SET(x) (((x) << TOP_TOP_LOCALXTAL_LSB) & TOP_TOP_LOCALXTAL_MASK)
+#define TOP_TOP_PWDCLKIN_MSB 14
+#define TOP_TOP_PWDCLKIN_LSB 14
+#define TOP_TOP_PWDCLKIN_MASK 0x00004000
+#define TOP_TOP_PWDCLKIN_GET(x) (((x) & TOP_TOP_PWDCLKIN_MASK) >> TOP_TOP_PWDCLKIN_LSB)
+#define TOP_TOP_PWDCLKIN_SET(x) (((x) << TOP_TOP_PWDCLKIN_LSB) & TOP_TOP_PWDCLKIN_MASK)
+#define TOP_TOP_OSCON_MSB 13
+#define TOP_TOP_OSCON_LSB 13
+#define TOP_TOP_OSCON_MASK 0x00002000
+#define TOP_TOP_OSCON_GET(x) (((x) & TOP_TOP_OSCON_MASK) >> TOP_TOP_OSCON_LSB)
+#define TOP_TOP_OSCON_SET(x) (((x) << TOP_TOP_OSCON_LSB) & TOP_TOP_OSCON_MASK)
+#define TOP_TOP_SCLKEN_FORCE_MSB 12
+#define TOP_TOP_SCLKEN_FORCE_LSB 12
+#define TOP_TOP_SCLKEN_FORCE_MASK 0x00001000
+#define TOP_TOP_SCLKEN_FORCE_GET(x) (((x) & TOP_TOP_SCLKEN_FORCE_MASK) >> TOP_TOP_SCLKEN_FORCE_LSB)
+#define TOP_TOP_SCLKEN_FORCE_SET(x) (((x) << TOP_TOP_SCLKEN_FORCE_LSB) & TOP_TOP_SCLKEN_FORCE_MASK)
+#define TOP_TOP_SYNTHON_FORCE_MSB 11
+#define TOP_TOP_SYNTHON_FORCE_LSB 11
+#define TOP_TOP_SYNTHON_FORCE_MASK 0x00000800
+#define TOP_TOP_SYNTHON_FORCE_GET(x) (((x) & TOP_TOP_SYNTHON_FORCE_MASK) >> TOP_TOP_SYNTHON_FORCE_LSB)
+#define TOP_TOP_SYNTHON_FORCE_SET(x) (((x) << TOP_TOP_SYNTHON_FORCE_LSB) & TOP_TOP_SYNTHON_FORCE_MASK)
+#define TOP_TOP_PDBIAS_MSB 10
+#define TOP_TOP_PDBIAS_LSB 10
+#define TOP_TOP_PDBIAS_MASK 0x00000400
+#define TOP_TOP_PDBIAS_GET(x) (((x) & TOP_TOP_PDBIAS_MASK) >> TOP_TOP_PDBIAS_LSB)
+#define TOP_TOP_PDBIAS_SET(x) (((x) << TOP_TOP_PDBIAS_LSB) & TOP_TOP_PDBIAS_MASK)
+#define TOP_TOP_DATAOUTSEL_MSB 9
+#define TOP_TOP_DATAOUTSEL_LSB 8
+#define TOP_TOP_DATAOUTSEL_MASK 0x00000300
+#define TOP_TOP_DATAOUTSEL_GET(x) (((x) & TOP_TOP_DATAOUTSEL_MASK) >> TOP_TOP_DATAOUTSEL_LSB)
+#define TOP_TOP_DATAOUTSEL_SET(x) (((x) << TOP_TOP_DATAOUTSEL_LSB) & TOP_TOP_DATAOUTSEL_MASK)
+#define TOP_TOP_REVID_MSB 7
+#define TOP_TOP_REVID_LSB 5
+#define TOP_TOP_REVID_MASK 0x000000e0
+#define TOP_TOP_REVID_GET(x) (((x) & TOP_TOP_REVID_MASK) >> TOP_TOP_REVID_LSB)
+#define TOP_TOP_REVID_SET(x) (((x) << TOP_TOP_REVID_LSB) & TOP_TOP_REVID_MASK)
+#define TOP_TOP_INT2PAD_MSB 4
+#define TOP_TOP_INT2PAD_LSB 4
+#define TOP_TOP_INT2PAD_MASK 0x00000010
+#define TOP_TOP_INT2PAD_GET(x) (((x) & TOP_TOP_INT2PAD_MASK) >> TOP_TOP_INT2PAD_LSB)
+#define TOP_TOP_INT2PAD_SET(x) (((x) << TOP_TOP_INT2PAD_LSB) & TOP_TOP_INT2PAD_MASK)
+#define TOP_TOP_INTH2PAD_MSB 3
+#define TOP_TOP_INTH2PAD_LSB 3
+#define TOP_TOP_INTH2PAD_MASK 0x00000008
+#define TOP_TOP_INTH2PAD_GET(x) (((x) & TOP_TOP_INTH2PAD_MASK) >> TOP_TOP_INTH2PAD_LSB)
+#define TOP_TOP_INTH2PAD_SET(x) (((x) << TOP_TOP_INTH2PAD_LSB) & TOP_TOP_INTH2PAD_MASK)
+#define TOP_TOP_PAD2GND_MSB 2
+#define TOP_TOP_PAD2GND_LSB 2
+#define TOP_TOP_PAD2GND_MASK 0x00000004
+#define TOP_TOP_PAD2GND_GET(x) (((x) & TOP_TOP_PAD2GND_MASK) >> TOP_TOP_PAD2GND_LSB)
+#define TOP_TOP_PAD2GND_SET(x) (((x) << TOP_TOP_PAD2GND_LSB) & TOP_TOP_PAD2GND_MASK)
+#define TOP_TOP_INT2GND_MSB 1
+#define TOP_TOP_INT2GND_LSB 1
+#define TOP_TOP_INT2GND_MASK 0x00000002
+#define TOP_TOP_INT2GND_GET(x) (((x) & TOP_TOP_INT2GND_MASK) >> TOP_TOP_INT2GND_LSB)
+#define TOP_TOP_INT2GND_SET(x) (((x) << TOP_TOP_INT2GND_LSB) & TOP_TOP_INT2GND_MASK)
+#define TOP_TOP_FORCE_XPAON_MSB 0
+#define TOP_TOP_FORCE_XPAON_LSB 0
+#define TOP_TOP_FORCE_XPAON_MASK 0x00000001
+#define TOP_TOP_FORCE_XPAON_GET(x) (((x) & TOP_TOP_FORCE_XPAON_MASK) >> TOP_TOP_FORCE_XPAON_LSB)
+#define TOP_TOP_FORCE_XPAON_SET(x) (((x) << TOP_TOP_FORCE_XPAON_LSB) & TOP_TOP_FORCE_XPAON_MASK)
+
+#define BIAS_BIAS_SEL_ADDRESS 0x00000038
+#define BIAS_BIAS_SEL_OFFSET 0x00000038
+#define BIAS_BIAS_SEL_PADON_MSB 31
+#define BIAS_BIAS_SEL_PADON_LSB 31
+#define BIAS_BIAS_SEL_PADON_MASK 0x80000000
+#define BIAS_BIAS_SEL_PADON_GET(x) (((x) & BIAS_BIAS_SEL_PADON_MASK) >> BIAS_BIAS_SEL_PADON_LSB)
+#define BIAS_BIAS_SEL_PADON_SET(x) (((x) << BIAS_BIAS_SEL_PADON_LSB) & BIAS_BIAS_SEL_PADON_MASK)
+#define BIAS_BIAS_SEL_SEL_BIAS_MSB 30
+#define BIAS_BIAS_SEL_SEL_BIAS_LSB 25
+#define BIAS_BIAS_SEL_SEL_BIAS_MASK 0x7e000000
+#define BIAS_BIAS_SEL_SEL_BIAS_GET(x) (((x) & BIAS_BIAS_SEL_SEL_BIAS_MASK) >> BIAS_BIAS_SEL_SEL_BIAS_LSB)
+#define BIAS_BIAS_SEL_SEL_BIAS_SET(x) (((x) << BIAS_BIAS_SEL_SEL_BIAS_LSB) & BIAS_BIAS_SEL_SEL_BIAS_MASK)
+#define BIAS_BIAS_SEL_SEL_SPARE_MSB 24
+#define BIAS_BIAS_SEL_SEL_SPARE_LSB 21
+#define BIAS_BIAS_SEL_SEL_SPARE_MASK 0x01e00000
+#define BIAS_BIAS_SEL_SEL_SPARE_GET(x) (((x) & BIAS_BIAS_SEL_SEL_SPARE_MASK) >> BIAS_BIAS_SEL_SEL_SPARE_LSB)
+#define BIAS_BIAS_SEL_SEL_SPARE_SET(x) (((x) << BIAS_BIAS_SEL_SEL_SPARE_LSB) & BIAS_BIAS_SEL_SEL_SPARE_MASK)
+#define BIAS_BIAS_SEL_SPARE_MSB 20
+#define BIAS_BIAS_SEL_SPARE_LSB 20
+#define BIAS_BIAS_SEL_SPARE_MASK 0x00100000
+#define BIAS_BIAS_SEL_SPARE_GET(x) (((x) & BIAS_BIAS_SEL_SPARE_MASK) >> BIAS_BIAS_SEL_SPARE_LSB)
+#define BIAS_BIAS_SEL_SPARE_SET(x) (((x) << BIAS_BIAS_SEL_SPARE_LSB) & BIAS_BIAS_SEL_SPARE_MASK)
+#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MSB 19
+#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB 17
+#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK 0x000e0000
+#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK) >> BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB)
+#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB) & BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK)
+#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MSB 16
+#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB 16
+#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK 0x00010000
+#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK) >> BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB)
+#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB) & BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK)
+#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MSB 15
+#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB 15
+#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK 0x00008000
+#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK) >> BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB)
+#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB) & BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK)
+#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MSB 14
+#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB 14
+#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK 0x00004000
+#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK) >> BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB) & BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICCPLL25_MSB 13
+#define BIAS_BIAS_SEL_PWD_ICCPLL25_LSB 13
+#define BIAS_BIAS_SEL_PWD_ICCPLL25_MASK 0x00002000
+#define BIAS_BIAS_SEL_PWD_ICCPLL25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICCPLL25_MASK) >> BIAS_BIAS_SEL_PWD_ICCPLL25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICCPLL25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICCPLL25_LSB) & BIAS_BIAS_SEL_PWD_ICCPLL25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MSB 12
+#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB 10
+#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK 0x00001c00
+#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK) >> BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB) & BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICXTAL25_MSB 9
+#define BIAS_BIAS_SEL_PWD_ICXTAL25_LSB 7
+#define BIAS_BIAS_SEL_PWD_ICXTAL25_MASK 0x00000380
+#define BIAS_BIAS_SEL_PWD_ICXTAL25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICXTAL25_MASK) >> BIAS_BIAS_SEL_PWD_ICXTAL25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICXTAL25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICXTAL25_LSB) & BIAS_BIAS_SEL_PWD_ICXTAL25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICTSENS25_MSB 6
+#define BIAS_BIAS_SEL_PWD_ICTSENS25_LSB 4
+#define BIAS_BIAS_SEL_PWD_ICTSENS25_MASK 0x00000070
+#define BIAS_BIAS_SEL_PWD_ICTSENS25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICTSENS25_MASK) >> BIAS_BIAS_SEL_PWD_ICTSENS25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICTSENS25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICTSENS25_LSB) & BIAS_BIAS_SEL_PWD_ICTSENS25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICTXPC25_MSB 3
+#define BIAS_BIAS_SEL_PWD_ICTXPC25_LSB 1
+#define BIAS_BIAS_SEL_PWD_ICTXPC25_MASK 0x0000000e
+#define BIAS_BIAS_SEL_PWD_ICTXPC25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICTXPC25_MASK) >> BIAS_BIAS_SEL_PWD_ICTXPC25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICTXPC25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICTXPC25_LSB) & BIAS_BIAS_SEL_PWD_ICTXPC25_MASK)
+#define BIAS_BIAS_SEL_PWD_ICLDO25_MSB 0
+#define BIAS_BIAS_SEL_PWD_ICLDO25_LSB 0
+#define BIAS_BIAS_SEL_PWD_ICLDO25_MASK 0x00000001
+#define BIAS_BIAS_SEL_PWD_ICLDO25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICLDO25_MASK) >> BIAS_BIAS_SEL_PWD_ICLDO25_LSB)
+#define BIAS_BIAS_SEL_PWD_ICLDO25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICLDO25_LSB) & BIAS_BIAS_SEL_PWD_ICLDO25_MASK)
+
+#define BIAS_BIAS1_ADDRESS 0x0000003c
+#define BIAS_BIAS1_OFFSET 0x0000003c
+#define BIAS_BIAS1_PWD_ICDAC2BB25_MSB 31
+#define BIAS_BIAS1_PWD_ICDAC2BB25_LSB 29
+#define BIAS_BIAS1_PWD_ICDAC2BB25_MASK 0xe0000000
+#define BIAS_BIAS1_PWD_ICDAC2BB25_GET(x) (((x) & BIAS_BIAS1_PWD_ICDAC2BB25_MASK) >> BIAS_BIAS1_PWD_ICDAC2BB25_LSB)
+#define BIAS_BIAS1_PWD_ICDAC2BB25_SET(x) (((x) << BIAS_BIAS1_PWD_ICDAC2BB25_LSB) & BIAS_BIAS1_PWD_ICDAC2BB25_MASK)
+#define BIAS_BIAS1_PWD_IC2GVGM25_MSB 28
+#define BIAS_BIAS1_PWD_IC2GVGM25_LSB 26
+#define BIAS_BIAS1_PWD_IC2GVGM25_MASK 0x1c000000
+#define BIAS_BIAS1_PWD_IC2GVGM25_GET(x) (((x) & BIAS_BIAS1_PWD_IC2GVGM25_MASK) >> BIAS_BIAS1_PWD_IC2GVGM25_LSB)
+#define BIAS_BIAS1_PWD_IC2GVGM25_SET(x) (((x) << BIAS_BIAS1_PWD_IC2GVGM25_LSB) & BIAS_BIAS1_PWD_IC2GVGM25_MASK)
+#define BIAS_BIAS1_PWD_IC2GRFFE25_MSB 25
+#define BIAS_BIAS1_PWD_IC2GRFFE25_LSB 23
+#define BIAS_BIAS1_PWD_IC2GRFFE25_MASK 0x03800000
+#define BIAS_BIAS1_PWD_IC2GRFFE25_GET(x) (((x) & BIAS_BIAS1_PWD_IC2GRFFE25_MASK) >> BIAS_BIAS1_PWD_IC2GRFFE25_LSB)
+#define BIAS_BIAS1_PWD_IC2GRFFE25_SET(x) (((x) << BIAS_BIAS1_PWD_IC2GRFFE25_LSB) & BIAS_BIAS1_PWD_IC2GRFFE25_MASK)
+#define BIAS_BIAS1_PWD_IC2GLOREG25_MSB 22
+#define BIAS_BIAS1_PWD_IC2GLOREG25_LSB 20
+#define BIAS_BIAS1_PWD_IC2GLOREG25_MASK 0x00700000
+#define BIAS_BIAS1_PWD_IC2GLOREG25_GET(x) (((x) & BIAS_BIAS1_PWD_IC2GLOREG25_MASK) >> BIAS_BIAS1_PWD_IC2GLOREG25_LSB)
+#define BIAS_BIAS1_PWD_IC2GLOREG25_SET(x) (((x) << BIAS_BIAS1_PWD_IC2GLOREG25_LSB) & BIAS_BIAS1_PWD_IC2GLOREG25_MASK)
+#define BIAS_BIAS1_PWD_IC2GLNAREG25_MSB 19
+#define BIAS_BIAS1_PWD_IC2GLNAREG25_LSB 17
+#define BIAS_BIAS1_PWD_IC2GLNAREG25_MASK 0x000e0000
+#define BIAS_BIAS1_PWD_IC2GLNAREG25_GET(x) (((x) & BIAS_BIAS1_PWD_IC2GLNAREG25_MASK) >> BIAS_BIAS1_PWD_IC2GLNAREG25_LSB)
+#define BIAS_BIAS1_PWD_IC2GLNAREG25_SET(x) (((x) << BIAS_BIAS1_PWD_IC2GLNAREG25_LSB) & BIAS_BIAS1_PWD_IC2GLNAREG25_MASK)
+#define BIAS_BIAS1_PWD_ICDETECTORB25_MSB 16
+#define BIAS_BIAS1_PWD_ICDETECTORB25_LSB 16
+#define BIAS_BIAS1_PWD_ICDETECTORB25_MASK 0x00010000
+#define BIAS_BIAS1_PWD_ICDETECTORB25_GET(x) (((x) & BIAS_BIAS1_PWD_ICDETECTORB25_MASK) >> BIAS_BIAS1_PWD_ICDETECTORB25_LSB)
+#define BIAS_BIAS1_PWD_ICDETECTORB25_SET(x) (((x) << BIAS_BIAS1_PWD_ICDETECTORB25_LSB) & BIAS_BIAS1_PWD_ICDETECTORB25_MASK)
+#define BIAS_BIAS1_PWD_ICDETECTORA25_MSB 15
+#define BIAS_BIAS1_PWD_ICDETECTORA25_LSB 15
+#define BIAS_BIAS1_PWD_ICDETECTORA25_MASK 0x00008000
+#define BIAS_BIAS1_PWD_ICDETECTORA25_GET(x) (((x) & BIAS_BIAS1_PWD_ICDETECTORA25_MASK) >> BIAS_BIAS1_PWD_ICDETECTORA25_LSB)
+#define BIAS_BIAS1_PWD_ICDETECTORA25_SET(x) (((x) << BIAS_BIAS1_PWD_ICDETECTORA25_LSB) & BIAS_BIAS1_PWD_ICDETECTORA25_MASK)
+#define BIAS_BIAS1_PWD_IC5GRXRF25_MSB 14
+#define BIAS_BIAS1_PWD_IC5GRXRF25_LSB 14
+#define BIAS_BIAS1_PWD_IC5GRXRF25_MASK 0x00004000
+#define BIAS_BIAS1_PWD_IC5GRXRF25_GET(x) (((x) & BIAS_BIAS1_PWD_IC5GRXRF25_MASK) >> BIAS_BIAS1_PWD_IC5GRXRF25_LSB)
+#define BIAS_BIAS1_PWD_IC5GRXRF25_SET(x) (((x) << BIAS_BIAS1_PWD_IC5GRXRF25_LSB) & BIAS_BIAS1_PWD_IC5GRXRF25_MASK)
+#define BIAS_BIAS1_PWD_IC5GTXPA25_MSB 13
+#define BIAS_BIAS1_PWD_IC5GTXPA25_LSB 11
+#define BIAS_BIAS1_PWD_IC5GTXPA25_MASK 0x00003800
+#define BIAS_BIAS1_PWD_IC5GTXPA25_GET(x) (((x) & BIAS_BIAS1_PWD_IC5GTXPA25_MASK) >> BIAS_BIAS1_PWD_IC5GTXPA25_LSB)
+#define BIAS_BIAS1_PWD_IC5GTXPA25_SET(x) (((x) << BIAS_BIAS1_PWD_IC5GTXPA25_LSB) & BIAS_BIAS1_PWD_IC5GTXPA25_MASK)
+#define BIAS_BIAS1_PWD_IC5GTXBUF25_MSB 10
+#define BIAS_BIAS1_PWD_IC5GTXBUF25_LSB 8
+#define BIAS_BIAS1_PWD_IC5GTXBUF25_MASK 0x00000700
+#define BIAS_BIAS1_PWD_IC5GTXBUF25_GET(x) (((x) & BIAS_BIAS1_PWD_IC5GTXBUF25_MASK) >> BIAS_BIAS1_PWD_IC5GTXBUF25_LSB)
+#define BIAS_BIAS1_PWD_IC5GTXBUF25_SET(x) (((x) << BIAS_BIAS1_PWD_IC5GTXBUF25_LSB) & BIAS_BIAS1_PWD_IC5GTXBUF25_MASK)
+#define BIAS_BIAS1_PWD_IC5GQB25_MSB 7
+#define BIAS_BIAS1_PWD_IC5GQB25_LSB 5
+#define BIAS_BIAS1_PWD_IC5GQB25_MASK 0x000000e0
+#define BIAS_BIAS1_PWD_IC5GQB25_GET(x) (((x) & BIAS_BIAS1_PWD_IC5GQB25_MASK) >> BIAS_BIAS1_PWD_IC5GQB25_LSB)
+#define BIAS_BIAS1_PWD_IC5GQB25_SET(x) (((x) << BIAS_BIAS1_PWD_IC5GQB25_LSB) & BIAS_BIAS1_PWD_IC5GQB25_MASK)
+#define BIAS_BIAS1_PWD_IC5GMIXQ25_MSB 4
+#define BIAS_BIAS1_PWD_IC5GMIXQ25_LSB 2
+#define BIAS_BIAS1_PWD_IC5GMIXQ25_MASK 0x0000001c
+#define BIAS_BIAS1_PWD_IC5GMIXQ25_GET(x) (((x) & BIAS_BIAS1_PWD_IC5GMIXQ25_MASK) >> BIAS_BIAS1_PWD_IC5GMIXQ25_LSB)
+#define BIAS_BIAS1_PWD_IC5GMIXQ25_SET(x) (((x) << BIAS_BIAS1_PWD_IC5GMIXQ25_LSB) & BIAS_BIAS1_PWD_IC5GMIXQ25_MASK)
+#define BIAS_BIAS1_SPARE_MSB 1
+#define BIAS_BIAS1_SPARE_LSB 0
+#define BIAS_BIAS1_SPARE_MASK 0x00000003
+#define BIAS_BIAS1_SPARE_GET(x) (((x) & BIAS_BIAS1_SPARE_MASK) >> BIAS_BIAS1_SPARE_LSB)
+#define BIAS_BIAS1_SPARE_SET(x) (((x) << BIAS_BIAS1_SPARE_LSB) & BIAS_BIAS1_SPARE_MASK)
+
+#define BIAS_BIAS2_ADDRESS 0x00000040
+#define BIAS_BIAS2_OFFSET 0x00000040
+#define BIAS_BIAS2_PWD_IC5GMIXI25_MSB 31
+#define BIAS_BIAS2_PWD_IC5GMIXI25_LSB 29
+#define BIAS_BIAS2_PWD_IC5GMIXI25_MASK 0xe0000000
+#define BIAS_BIAS2_PWD_IC5GMIXI25_GET(x) (((x) & BIAS_BIAS2_PWD_IC5GMIXI25_MASK) >> BIAS_BIAS2_PWD_IC5GMIXI25_LSB)
+#define BIAS_BIAS2_PWD_IC5GMIXI25_SET(x) (((x) << BIAS_BIAS2_PWD_IC5GMIXI25_LSB) & BIAS_BIAS2_PWD_IC5GMIXI25_MASK)
+#define BIAS_BIAS2_PWD_IC5GDIV25_MSB 28
+#define BIAS_BIAS2_PWD_IC5GDIV25_LSB 26
+#define BIAS_BIAS2_PWD_IC5GDIV25_MASK 0x1c000000
+#define BIAS_BIAS2_PWD_IC5GDIV25_GET(x) (((x) & BIAS_BIAS2_PWD_IC5GDIV25_MASK) >> BIAS_BIAS2_PWD_IC5GDIV25_LSB)
+#define BIAS_BIAS2_PWD_IC5GDIV25_SET(x) (((x) << BIAS_BIAS2_PWD_IC5GDIV25_LSB) & BIAS_BIAS2_PWD_IC5GDIV25_MASK)
+#define BIAS_BIAS2_PWD_IC5GLOREG25_MSB 25
+#define BIAS_BIAS2_PWD_IC5GLOREG25_LSB 23
+#define BIAS_BIAS2_PWD_IC5GLOREG25_MASK 0x03800000
+#define BIAS_BIAS2_PWD_IC5GLOREG25_GET(x) (((x) & BIAS_BIAS2_PWD_IC5GLOREG25_MASK) >> BIAS_BIAS2_PWD_IC5GLOREG25_LSB)
+#define BIAS_BIAS2_PWD_IC5GLOREG25_SET(x) (((x) << BIAS_BIAS2_PWD_IC5GLOREG25_LSB) & BIAS_BIAS2_PWD_IC5GLOREG25_MASK)
+#define BIAS_BIAS2_PWD_IRPLL25_MSB 22
+#define BIAS_BIAS2_PWD_IRPLL25_LSB 22
+#define BIAS_BIAS2_PWD_IRPLL25_MASK 0x00400000
+#define BIAS_BIAS2_PWD_IRPLL25_GET(x) (((x) & BIAS_BIAS2_PWD_IRPLL25_MASK) >> BIAS_BIAS2_PWD_IRPLL25_LSB)
+#define BIAS_BIAS2_PWD_IRPLL25_SET(x) (((x) << BIAS_BIAS2_PWD_IRPLL25_LSB) & BIAS_BIAS2_PWD_IRPLL25_MASK)
+#define BIAS_BIAS2_PWD_IRXTAL25_MSB 21
+#define BIAS_BIAS2_PWD_IRXTAL25_LSB 19
+#define BIAS_BIAS2_PWD_IRXTAL25_MASK 0x00380000
+#define BIAS_BIAS2_PWD_IRXTAL25_GET(x) (((x) & BIAS_BIAS2_PWD_IRXTAL25_MASK) >> BIAS_BIAS2_PWD_IRXTAL25_LSB)
+#define BIAS_BIAS2_PWD_IRXTAL25_SET(x) (((x) << BIAS_BIAS2_PWD_IRXTAL25_LSB) & BIAS_BIAS2_PWD_IRXTAL25_MASK)
+#define BIAS_BIAS2_PWD_IRTSENS25_MSB 18
+#define BIAS_BIAS2_PWD_IRTSENS25_LSB 16
+#define BIAS_BIAS2_PWD_IRTSENS25_MASK 0x00070000
+#define BIAS_BIAS2_PWD_IRTSENS25_GET(x) (((x) & BIAS_BIAS2_PWD_IRTSENS25_MASK) >> BIAS_BIAS2_PWD_IRTSENS25_LSB)
+#define BIAS_BIAS2_PWD_IRTSENS25_SET(x) (((x) << BIAS_BIAS2_PWD_IRTSENS25_LSB) & BIAS_BIAS2_PWD_IRTSENS25_MASK)
+#define BIAS_BIAS2_PWD_IRTXPC25_MSB 15
+#define BIAS_BIAS2_PWD_IRTXPC25_LSB 13
+#define BIAS_BIAS2_PWD_IRTXPC25_MASK 0x0000e000
+#define BIAS_BIAS2_PWD_IRTXPC25_GET(x) (((x) & BIAS_BIAS2_PWD_IRTXPC25_MASK) >> BIAS_BIAS2_PWD_IRTXPC25_LSB)
+#define BIAS_BIAS2_PWD_IRTXPC25_SET(x) (((x) << BIAS_BIAS2_PWD_IRTXPC25_LSB) & BIAS_BIAS2_PWD_IRTXPC25_MASK)
+#define BIAS_BIAS2_PWD_IRLDO25_MSB 12
+#define BIAS_BIAS2_PWD_IRLDO25_LSB 12
+#define BIAS_BIAS2_PWD_IRLDO25_MASK 0x00001000
+#define BIAS_BIAS2_PWD_IRLDO25_GET(x) (((x) & BIAS_BIAS2_PWD_IRLDO25_MASK) >> BIAS_BIAS2_PWD_IRLDO25_LSB)
+#define BIAS_BIAS2_PWD_IRLDO25_SET(x) (((x) << BIAS_BIAS2_PWD_IRLDO25_LSB) & BIAS_BIAS2_PWD_IRLDO25_MASK)
+#define BIAS_BIAS2_PWD_IR2GTXMIX25_MSB 11
+#define BIAS_BIAS2_PWD_IR2GTXMIX25_LSB 9
+#define BIAS_BIAS2_PWD_IR2GTXMIX25_MASK 0x00000e00
+#define BIAS_BIAS2_PWD_IR2GTXMIX25_GET(x) (((x) & BIAS_BIAS2_PWD_IR2GTXMIX25_MASK) >> BIAS_BIAS2_PWD_IR2GTXMIX25_LSB)
+#define BIAS_BIAS2_PWD_IR2GTXMIX25_SET(x) (((x) << BIAS_BIAS2_PWD_IR2GTXMIX25_LSB) & BIAS_BIAS2_PWD_IR2GTXMIX25_MASK)
+#define BIAS_BIAS2_PWD_IR2GLOREG25_MSB 8
+#define BIAS_BIAS2_PWD_IR2GLOREG25_LSB 6
+#define BIAS_BIAS2_PWD_IR2GLOREG25_MASK 0x000001c0
+#define BIAS_BIAS2_PWD_IR2GLOREG25_GET(x) (((x) & BIAS_BIAS2_PWD_IR2GLOREG25_MASK) >> BIAS_BIAS2_PWD_IR2GLOREG25_LSB)
+#define BIAS_BIAS2_PWD_IR2GLOREG25_SET(x) (((x) << BIAS_BIAS2_PWD_IR2GLOREG25_LSB) & BIAS_BIAS2_PWD_IR2GLOREG25_MASK)
+#define BIAS_BIAS2_PWD_IR2GLNAREG25_MSB 5
+#define BIAS_BIAS2_PWD_IR2GLNAREG25_LSB 3
+#define BIAS_BIAS2_PWD_IR2GLNAREG25_MASK 0x00000038
+#define BIAS_BIAS2_PWD_IR2GLNAREG25_GET(x) (((x) & BIAS_BIAS2_PWD_IR2GLNAREG25_MASK) >> BIAS_BIAS2_PWD_IR2GLNAREG25_LSB)
+#define BIAS_BIAS2_PWD_IR2GLNAREG25_SET(x) (((x) << BIAS_BIAS2_PWD_IR2GLNAREG25_LSB) & BIAS_BIAS2_PWD_IR2GLNAREG25_MASK)
+#define BIAS_BIAS2_PWD_IR5GRFVREF2525_MSB 2
+#define BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB 0
+#define BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK 0x00000007
+#define BIAS_BIAS2_PWD_IR5GRFVREF2525_GET(x) (((x) & BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK) >> BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB)
+#define BIAS_BIAS2_PWD_IR5GRFVREF2525_SET(x) (((x) << BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB) & BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK)
+
+#define BIAS_BIAS3_ADDRESS 0x00000044
+#define BIAS_BIAS3_OFFSET 0x00000044
+#define BIAS_BIAS3_PWD_IR5GTXMIX25_MSB 31
+#define BIAS_BIAS3_PWD_IR5GTXMIX25_LSB 29
+#define BIAS_BIAS3_PWD_IR5GTXMIX25_MASK 0xe0000000
+#define BIAS_BIAS3_PWD_IR5GTXMIX25_GET(x) (((x) & BIAS_BIAS3_PWD_IR5GTXMIX25_MASK) >> BIAS_BIAS3_PWD_IR5GTXMIX25_LSB)
+#define BIAS_BIAS3_PWD_IR5GTXMIX25_SET(x) (((x) << BIAS_BIAS3_PWD_IR5GTXMIX25_LSB) & BIAS_BIAS3_PWD_IR5GTXMIX25_MASK)
+#define BIAS_BIAS3_PWD_IR5GAGC25_MSB 28
+#define BIAS_BIAS3_PWD_IR5GAGC25_LSB 26
+#define BIAS_BIAS3_PWD_IR5GAGC25_MASK 0x1c000000
+#define BIAS_BIAS3_PWD_IR5GAGC25_GET(x) (((x) & BIAS_BIAS3_PWD_IR5GAGC25_MASK) >> BIAS_BIAS3_PWD_IR5GAGC25_LSB)
+#define BIAS_BIAS3_PWD_IR5GAGC25_SET(x) (((x) << BIAS_BIAS3_PWD_IR5GAGC25_LSB) & BIAS_BIAS3_PWD_IR5GAGC25_MASK)
+#define BIAS_BIAS3_PWD_ICDAC50_MSB 25
+#define BIAS_BIAS3_PWD_ICDAC50_LSB 23
+#define BIAS_BIAS3_PWD_ICDAC50_MASK 0x03800000
+#define BIAS_BIAS3_PWD_ICDAC50_GET(x) (((x) & BIAS_BIAS3_PWD_ICDAC50_MASK) >> BIAS_BIAS3_PWD_ICDAC50_LSB)
+#define BIAS_BIAS3_PWD_ICDAC50_SET(x) (((x) << BIAS_BIAS3_PWD_ICDAC50_LSB) & BIAS_BIAS3_PWD_ICDAC50_MASK)
+#define BIAS_BIAS3_PWD_ICSYNTH50_MSB 22
+#define BIAS_BIAS3_PWD_ICSYNTH50_LSB 22
+#define BIAS_BIAS3_PWD_ICSYNTH50_MASK 0x00400000
+#define BIAS_BIAS3_PWD_ICSYNTH50_GET(x) (((x) & BIAS_BIAS3_PWD_ICSYNTH50_MASK) >> BIAS_BIAS3_PWD_ICSYNTH50_LSB)
+#define BIAS_BIAS3_PWD_ICSYNTH50_SET(x) (((x) << BIAS_BIAS3_PWD_ICSYNTH50_LSB) & BIAS_BIAS3_PWD_ICSYNTH50_MASK)
+#define BIAS_BIAS3_PWD_ICBB50_MSB 21
+#define BIAS_BIAS3_PWD_ICBB50_LSB 21
+#define BIAS_BIAS3_PWD_ICBB50_MASK 0x00200000
+#define BIAS_BIAS3_PWD_ICBB50_GET(x) (((x) & BIAS_BIAS3_PWD_ICBB50_MASK) >> BIAS_BIAS3_PWD_ICBB50_LSB)
+#define BIAS_BIAS3_PWD_ICBB50_SET(x) (((x) << BIAS_BIAS3_PWD_ICBB50_LSB) & BIAS_BIAS3_PWD_ICBB50_MASK)
+#define BIAS_BIAS3_PWD_IC2GDIV50_MSB 20
+#define BIAS_BIAS3_PWD_IC2GDIV50_LSB 18
+#define BIAS_BIAS3_PWD_IC2GDIV50_MASK 0x001c0000
+#define BIAS_BIAS3_PWD_IC2GDIV50_GET(x) (((x) & BIAS_BIAS3_PWD_IC2GDIV50_MASK) >> BIAS_BIAS3_PWD_IC2GDIV50_LSB)
+#define BIAS_BIAS3_PWD_IC2GDIV50_SET(x) (((x) << BIAS_BIAS3_PWD_IC2GDIV50_LSB) & BIAS_BIAS3_PWD_IC2GDIV50_MASK)
+#define BIAS_BIAS3_PWD_IRSYNTH50_MSB 17
+#define BIAS_BIAS3_PWD_IRSYNTH50_LSB 17
+#define BIAS_BIAS3_PWD_IRSYNTH50_MASK 0x00020000
+#define BIAS_BIAS3_PWD_IRSYNTH50_GET(x) (((x) & BIAS_BIAS3_PWD_IRSYNTH50_MASK) >> BIAS_BIAS3_PWD_IRSYNTH50_LSB)
+#define BIAS_BIAS3_PWD_IRSYNTH50_SET(x) (((x) << BIAS_BIAS3_PWD_IRSYNTH50_LSB) & BIAS_BIAS3_PWD_IRSYNTH50_MASK)
+#define BIAS_BIAS3_PWD_IRBB50_MSB 16
+#define BIAS_BIAS3_PWD_IRBB50_LSB 16
+#define BIAS_BIAS3_PWD_IRBB50_MASK 0x00010000
+#define BIAS_BIAS3_PWD_IRBB50_GET(x) (((x) & BIAS_BIAS3_PWD_IRBB50_MASK) >> BIAS_BIAS3_PWD_IRBB50_LSB)
+#define BIAS_BIAS3_PWD_IRBB50_SET(x) (((x) << BIAS_BIAS3_PWD_IRBB50_LSB) & BIAS_BIAS3_PWD_IRBB50_MASK)
+#define BIAS_BIAS3_PWD_IC25SPARE1_MSB 15
+#define BIAS_BIAS3_PWD_IC25SPARE1_LSB 13
+#define BIAS_BIAS3_PWD_IC25SPARE1_MASK 0x0000e000
+#define BIAS_BIAS3_PWD_IC25SPARE1_GET(x) (((x) & BIAS_BIAS3_PWD_IC25SPARE1_MASK) >> BIAS_BIAS3_PWD_IC25SPARE1_LSB)
+#define BIAS_BIAS3_PWD_IC25SPARE1_SET(x) (((x) << BIAS_BIAS3_PWD_IC25SPARE1_LSB) & BIAS_BIAS3_PWD_IC25SPARE1_MASK)
+#define BIAS_BIAS3_PWD_IC25SPARE2_MSB 12
+#define BIAS_BIAS3_PWD_IC25SPARE2_LSB 10
+#define BIAS_BIAS3_PWD_IC25SPARE2_MASK 0x00001c00
+#define BIAS_BIAS3_PWD_IC25SPARE2_GET(x) (((x) & BIAS_BIAS3_PWD_IC25SPARE2_MASK) >> BIAS_BIAS3_PWD_IC25SPARE2_LSB)
+#define BIAS_BIAS3_PWD_IC25SPARE2_SET(x) (((x) << BIAS_BIAS3_PWD_IC25SPARE2_LSB) & BIAS_BIAS3_PWD_IC25SPARE2_MASK)
+#define BIAS_BIAS3_PWD_IR25SPARE1_MSB 9
+#define BIAS_BIAS3_PWD_IR25SPARE1_LSB 7
+#define BIAS_BIAS3_PWD_IR25SPARE1_MASK 0x00000380
+#define BIAS_BIAS3_PWD_IR25SPARE1_GET(x) (((x) & BIAS_BIAS3_PWD_IR25SPARE1_MASK) >> BIAS_BIAS3_PWD_IR25SPARE1_LSB)
+#define BIAS_BIAS3_PWD_IR25SPARE1_SET(x) (((x) << BIAS_BIAS3_PWD_IR25SPARE1_LSB) & BIAS_BIAS3_PWD_IR25SPARE1_MASK)
+#define BIAS_BIAS3_PWD_IR25SPARE2_MSB 6
+#define BIAS_BIAS3_PWD_IR25SPARE2_LSB 4
+#define BIAS_BIAS3_PWD_IR25SPARE2_MASK 0x00000070
+#define BIAS_BIAS3_PWD_IR25SPARE2_GET(x) (((x) & BIAS_BIAS3_PWD_IR25SPARE2_MASK) >> BIAS_BIAS3_PWD_IR25SPARE2_LSB)
+#define BIAS_BIAS3_PWD_IR25SPARE2_SET(x) (((x) << BIAS_BIAS3_PWD_IR25SPARE2_LSB) & BIAS_BIAS3_PWD_IR25SPARE2_MASK)
+#define BIAS_BIAS3_PWD_ICDACREG12P5_MSB 3
+#define BIAS_BIAS3_PWD_ICDACREG12P5_LSB 1
+#define BIAS_BIAS3_PWD_ICDACREG12P5_MASK 0x0000000e
+#define BIAS_BIAS3_PWD_ICDACREG12P5_GET(x) (((x) & BIAS_BIAS3_PWD_ICDACREG12P5_MASK) >> BIAS_BIAS3_PWD_ICDACREG12P5_LSB)
+#define BIAS_BIAS3_PWD_ICDACREG12P5_SET(x) (((x) << BIAS_BIAS3_PWD_ICDACREG12P5_LSB) & BIAS_BIAS3_PWD_ICDACREG12P5_MASK)
+#define BIAS_BIAS3_SPARE_MSB 0
+#define BIAS_BIAS3_SPARE_LSB 0
+#define BIAS_BIAS3_SPARE_MASK 0x00000001
+#define BIAS_BIAS3_SPARE_GET(x) (((x) & BIAS_BIAS3_SPARE_MASK) >> BIAS_BIAS3_SPARE_LSB)
+#define BIAS_BIAS3_SPARE_SET(x) (((x) << BIAS_BIAS3_SPARE_LSB) & BIAS_BIAS3_SPARE_MASK)
+
+#define TXPC_TXPC_ADDRESS 0x00000048
+#define TXPC_TXPC_OFFSET 0x00000048
+#define TXPC_TXPC_SELINTPD_MSB 31
+#define TXPC_TXPC_SELINTPD_LSB 31
+#define TXPC_TXPC_SELINTPD_MASK 0x80000000
+#define TXPC_TXPC_SELINTPD_GET(x) (((x) & TXPC_TXPC_SELINTPD_MASK) >> TXPC_TXPC_SELINTPD_LSB)
+#define TXPC_TXPC_SELINTPD_SET(x) (((x) << TXPC_TXPC_SELINTPD_LSB) & TXPC_TXPC_SELINTPD_MASK)
+#define TXPC_TXPC_TEST_MSB 30
+#define TXPC_TXPC_TEST_LSB 30
+#define TXPC_TXPC_TEST_MASK 0x40000000
+#define TXPC_TXPC_TEST_GET(x) (((x) & TXPC_TXPC_TEST_MASK) >> TXPC_TXPC_TEST_LSB)
+#define TXPC_TXPC_TEST_SET(x) (((x) << TXPC_TXPC_TEST_LSB) & TXPC_TXPC_TEST_MASK)
+#define TXPC_TXPC_TESTGAIN_MSB 29
+#define TXPC_TXPC_TESTGAIN_LSB 28
+#define TXPC_TXPC_TESTGAIN_MASK 0x30000000
+#define TXPC_TXPC_TESTGAIN_GET(x) (((x) & TXPC_TXPC_TESTGAIN_MASK) >> TXPC_TXPC_TESTGAIN_LSB)
+#define TXPC_TXPC_TESTGAIN_SET(x) (((x) << TXPC_TXPC_TESTGAIN_LSB) & TXPC_TXPC_TESTGAIN_MASK)
+#define TXPC_TXPC_TESTDAC_MSB 27
+#define TXPC_TXPC_TESTDAC_LSB 22
+#define TXPC_TXPC_TESTDAC_MASK 0x0fc00000
+#define TXPC_TXPC_TESTDAC_GET(x) (((x) & TXPC_TXPC_TESTDAC_MASK) >> TXPC_TXPC_TESTDAC_LSB)
+#define TXPC_TXPC_TESTDAC_SET(x) (((x) << TXPC_TXPC_TESTDAC_LSB) & TXPC_TXPC_TESTDAC_MASK)
+#define TXPC_TXPC_TESTPWDPC_MSB 21
+#define TXPC_TXPC_TESTPWDPC_LSB 21
+#define TXPC_TXPC_TESTPWDPC_MASK 0x00200000
+#define TXPC_TXPC_TESTPWDPC_GET(x) (((x) & TXPC_TXPC_TESTPWDPC_MASK) >> TXPC_TXPC_TESTPWDPC_LSB)
+#define TXPC_TXPC_TESTPWDPC_SET(x) (((x) << TXPC_TXPC_TESTPWDPC_LSB) & TXPC_TXPC_TESTPWDPC_MASK)
+#define TXPC_TXPC_CURHALF_MSB 20
+#define TXPC_TXPC_CURHALF_LSB 20
+#define TXPC_TXPC_CURHALF_MASK 0x00100000
+#define TXPC_TXPC_CURHALF_GET(x) (((x) & TXPC_TXPC_CURHALF_MASK) >> TXPC_TXPC_CURHALF_LSB)
+#define TXPC_TXPC_CURHALF_SET(x) (((x) << TXPC_TXPC_CURHALF_LSB) & TXPC_TXPC_CURHALF_MASK)
+#define TXPC_TXPC_NEGOUT_MSB 19
+#define TXPC_TXPC_NEGOUT_LSB 19
+#define TXPC_TXPC_NEGOUT_MASK 0x00080000
+#define TXPC_TXPC_NEGOUT_GET(x) (((x) & TXPC_TXPC_NEGOUT_MASK) >> TXPC_TXPC_NEGOUT_LSB)
+#define TXPC_TXPC_NEGOUT_SET(x) (((x) << TXPC_TXPC_NEGOUT_LSB) & TXPC_TXPC_NEGOUT_MASK)
+#define TXPC_TXPC_CLKDELAY_MSB 18
+#define TXPC_TXPC_CLKDELAY_LSB 18
+#define TXPC_TXPC_CLKDELAY_MASK 0x00040000
+#define TXPC_TXPC_CLKDELAY_GET(x) (((x) & TXPC_TXPC_CLKDELAY_MASK) >> TXPC_TXPC_CLKDELAY_LSB)
+#define TXPC_TXPC_CLKDELAY_SET(x) (((x) << TXPC_TXPC_CLKDELAY_LSB) & TXPC_TXPC_CLKDELAY_MASK)
+#define TXPC_TXPC_SELMODREF_MSB 17
+#define TXPC_TXPC_SELMODREF_LSB 17
+#define TXPC_TXPC_SELMODREF_MASK 0x00020000
+#define TXPC_TXPC_SELMODREF_GET(x) (((x) & TXPC_TXPC_SELMODREF_MASK) >> TXPC_TXPC_SELMODREF_LSB)
+#define TXPC_TXPC_SELMODREF_SET(x) (((x) << TXPC_TXPC_SELMODREF_LSB) & TXPC_TXPC_SELMODREF_MASK)
+#define TXPC_TXPC_SELCMOUT_MSB 16
+#define TXPC_TXPC_SELCMOUT_LSB 16
+#define TXPC_TXPC_SELCMOUT_MASK 0x00010000
+#define TXPC_TXPC_SELCMOUT_GET(x) (((x) & TXPC_TXPC_SELCMOUT_MASK) >> TXPC_TXPC_SELCMOUT_LSB)
+#define TXPC_TXPC_SELCMOUT_SET(x) (((x) << TXPC_TXPC_SELCMOUT_LSB) & TXPC_TXPC_SELCMOUT_MASK)
+#define TXPC_TXPC_TSMODE_MSB 15
+#define TXPC_TXPC_TSMODE_LSB 14
+#define TXPC_TXPC_TSMODE_MASK 0x0000c000
+#define TXPC_TXPC_TSMODE_GET(x) (((x) & TXPC_TXPC_TSMODE_MASK) >> TXPC_TXPC_TSMODE_LSB)
+#define TXPC_TXPC_TSMODE_SET(x) (((x) << TXPC_TXPC_TSMODE_LSB) & TXPC_TXPC_TSMODE_MASK)
+#define TXPC_TXPC_N_MSB 13
+#define TXPC_TXPC_N_LSB 6
+#define TXPC_TXPC_N_MASK 0x00003fc0
+#define TXPC_TXPC_N_GET(x) (((x) & TXPC_TXPC_N_MASK) >> TXPC_TXPC_N_LSB)
+#define TXPC_TXPC_N_SET(x) (((x) << TXPC_TXPC_N_LSB) & TXPC_TXPC_N_MASK)
+#define TXPC_TXPC_ON1STSYNTHON_MSB 5
+#define TXPC_TXPC_ON1STSYNTHON_LSB 5
+#define TXPC_TXPC_ON1STSYNTHON_MASK 0x00000020
+#define TXPC_TXPC_ON1STSYNTHON_GET(x) (((x) & TXPC_TXPC_ON1STSYNTHON_MASK) >> TXPC_TXPC_ON1STSYNTHON_LSB)
+#define TXPC_TXPC_ON1STSYNTHON_SET(x) (((x) << TXPC_TXPC_ON1STSYNTHON_LSB) & TXPC_TXPC_ON1STSYNTHON_MASK)
+#define TXPC_TXPC_SELINIT_MSB 4
+#define TXPC_TXPC_SELINIT_LSB 3
+#define TXPC_TXPC_SELINIT_MASK 0x00000018
+#define TXPC_TXPC_SELINIT_GET(x) (((x) & TXPC_TXPC_SELINIT_MASK) >> TXPC_TXPC_SELINIT_LSB)
+#define TXPC_TXPC_SELINIT_SET(x) (((x) << TXPC_TXPC_SELINIT_LSB) & TXPC_TXPC_SELINIT_MASK)
+#define TXPC_TXPC_SELCOUNT_MSB 2
+#define TXPC_TXPC_SELCOUNT_LSB 2
+#define TXPC_TXPC_SELCOUNT_MASK 0x00000004
+#define TXPC_TXPC_SELCOUNT_GET(x) (((x) & TXPC_TXPC_SELCOUNT_MASK) >> TXPC_TXPC_SELCOUNT_LSB)
+#define TXPC_TXPC_SELCOUNT_SET(x) (((x) << TXPC_TXPC_SELCOUNT_LSB) & TXPC_TXPC_SELCOUNT_MASK)
+#define TXPC_TXPC_ATBSEL_MSB 1
+#define TXPC_TXPC_ATBSEL_LSB 0
+#define TXPC_TXPC_ATBSEL_MASK 0x00000003
+#define TXPC_TXPC_ATBSEL_GET(x) (((x) & TXPC_TXPC_ATBSEL_MASK) >> TXPC_TXPC_ATBSEL_LSB)
+#define TXPC_TXPC_ATBSEL_SET(x) (((x) << TXPC_TXPC_ATBSEL_LSB) & TXPC_TXPC_ATBSEL_MASK)
+
+#define TXPC_MISC_ADDRESS 0x0000004c
+#define TXPC_MISC_OFFSET 0x0000004c
+#define TXPC_MISC_FLIPBMODE_MSB 31
+#define TXPC_MISC_FLIPBMODE_LSB 31
+#define TXPC_MISC_FLIPBMODE_MASK 0x80000000
+#define TXPC_MISC_FLIPBMODE_GET(x) (((x) & TXPC_MISC_FLIPBMODE_MASK) >> TXPC_MISC_FLIPBMODE_LSB)
+#define TXPC_MISC_FLIPBMODE_SET(x) (((x) << TXPC_MISC_FLIPBMODE_LSB) & TXPC_MISC_FLIPBMODE_MASK)
+#define TXPC_MISC_LEVEL_MSB 30
+#define TXPC_MISC_LEVEL_LSB 29
+#define TXPC_MISC_LEVEL_MASK 0x60000000
+#define TXPC_MISC_LEVEL_GET(x) (((x) & TXPC_MISC_LEVEL_MASK) >> TXPC_MISC_LEVEL_LSB)
+#define TXPC_MISC_LEVEL_SET(x) (((x) << TXPC_MISC_LEVEL_LSB) & TXPC_MISC_LEVEL_MASK)
+#define TXPC_MISC_LDO_TEST_MODE_MSB 28
+#define TXPC_MISC_LDO_TEST_MODE_LSB 28
+#define TXPC_MISC_LDO_TEST_MODE_MASK 0x10000000
+#define TXPC_MISC_LDO_TEST_MODE_GET(x) (((x) & TXPC_MISC_LDO_TEST_MODE_MASK) >> TXPC_MISC_LDO_TEST_MODE_LSB)
+#define TXPC_MISC_LDO_TEST_MODE_SET(x) (((x) << TXPC_MISC_LDO_TEST_MODE_LSB) & TXPC_MISC_LDO_TEST_MODE_MASK)
+#define TXPC_MISC_NOTCXODET_MSB 27
+#define TXPC_MISC_NOTCXODET_LSB 27
+#define TXPC_MISC_NOTCXODET_MASK 0x08000000
+#define TXPC_MISC_NOTCXODET_GET(x) (((x) & TXPC_MISC_NOTCXODET_MASK) >> TXPC_MISC_NOTCXODET_LSB)
+#define TXPC_MISC_NOTCXODET_SET(x) (((x) << TXPC_MISC_NOTCXODET_LSB) & TXPC_MISC_NOTCXODET_MASK)
+#define TXPC_MISC_PWDCLKIND_MSB 26
+#define TXPC_MISC_PWDCLKIND_LSB 26
+#define TXPC_MISC_PWDCLKIND_MASK 0x04000000
+#define TXPC_MISC_PWDCLKIND_GET(x) (((x) & TXPC_MISC_PWDCLKIND_MASK) >> TXPC_MISC_PWDCLKIND_LSB)
+#define TXPC_MISC_PWDCLKIND_SET(x) (((x) << TXPC_MISC_PWDCLKIND_LSB) & TXPC_MISC_PWDCLKIND_MASK)
+#define TXPC_MISC_PWDXINPAD_MSB 25
+#define TXPC_MISC_PWDXINPAD_LSB 25
+#define TXPC_MISC_PWDXINPAD_MASK 0x02000000
+#define TXPC_MISC_PWDXINPAD_GET(x) (((x) & TXPC_MISC_PWDXINPAD_MASK) >> TXPC_MISC_PWDXINPAD_LSB)
+#define TXPC_MISC_PWDXINPAD_SET(x) (((x) << TXPC_MISC_PWDXINPAD_LSB) & TXPC_MISC_PWDXINPAD_MASK)
+#define TXPC_MISC_LOCALBIAS_MSB 24
+#define TXPC_MISC_LOCALBIAS_LSB 24
+#define TXPC_MISC_LOCALBIAS_MASK 0x01000000
+#define TXPC_MISC_LOCALBIAS_GET(x) (((x) & TXPC_MISC_LOCALBIAS_MASK) >> TXPC_MISC_LOCALBIAS_LSB)
+#define TXPC_MISC_LOCALBIAS_SET(x) (((x) << TXPC_MISC_LOCALBIAS_LSB) & TXPC_MISC_LOCALBIAS_MASK)
+#define TXPC_MISC_LOCALBIAS2X_MSB 23
+#define TXPC_MISC_LOCALBIAS2X_LSB 23
+#define TXPC_MISC_LOCALBIAS2X_MASK 0x00800000
+#define TXPC_MISC_LOCALBIAS2X_GET(x) (((x) & TXPC_MISC_LOCALBIAS2X_MASK) >> TXPC_MISC_LOCALBIAS2X_LSB)
+#define TXPC_MISC_LOCALBIAS2X_SET(x) (((x) << TXPC_MISC_LOCALBIAS2X_LSB) & TXPC_MISC_LOCALBIAS2X_MASK)
+#define TXPC_MISC_SELTSP_MSB 22
+#define TXPC_MISC_SELTSP_LSB 22
+#define TXPC_MISC_SELTSP_MASK 0x00400000
+#define TXPC_MISC_SELTSP_GET(x) (((x) & TXPC_MISC_SELTSP_MASK) >> TXPC_MISC_SELTSP_LSB)
+#define TXPC_MISC_SELTSP_SET(x) (((x) << TXPC_MISC_SELTSP_LSB) & TXPC_MISC_SELTSP_MASK)
+#define TXPC_MISC_SELTSN_MSB 21
+#define TXPC_MISC_SELTSN_LSB 21
+#define TXPC_MISC_SELTSN_MASK 0x00200000
+#define TXPC_MISC_SELTSN_GET(x) (((x) & TXPC_MISC_SELTSN_MASK) >> TXPC_MISC_SELTSN_LSB)
+#define TXPC_MISC_SELTSN_SET(x) (((x) << TXPC_MISC_SELTSN_LSB) & TXPC_MISC_SELTSN_MASK)
+#define TXPC_MISC_SPARE_A_MSB 20
+#define TXPC_MISC_SPARE_A_LSB 18
+#define TXPC_MISC_SPARE_A_MASK 0x001c0000
+#define TXPC_MISC_SPARE_A_GET(x) (((x) & TXPC_MISC_SPARE_A_MASK) >> TXPC_MISC_SPARE_A_LSB)
+#define TXPC_MISC_SPARE_A_SET(x) (((x) << TXPC_MISC_SPARE_A_LSB) & TXPC_MISC_SPARE_A_MASK)
+#define TXPC_MISC_DECOUT_MSB 17
+#define TXPC_MISC_DECOUT_LSB 8
+#define TXPC_MISC_DECOUT_MASK 0x0003ff00
+#define TXPC_MISC_DECOUT_GET(x) (((x) & TXPC_MISC_DECOUT_MASK) >> TXPC_MISC_DECOUT_LSB)
+#define TXPC_MISC_DECOUT_SET(x) (((x) << TXPC_MISC_DECOUT_LSB) & TXPC_MISC_DECOUT_MASK)
+#define TXPC_MISC_XTALDIV_MSB 7
+#define TXPC_MISC_XTALDIV_LSB 6
+#define TXPC_MISC_XTALDIV_MASK 0x000000c0
+#define TXPC_MISC_XTALDIV_GET(x) (((x) & TXPC_MISC_XTALDIV_MASK) >> TXPC_MISC_XTALDIV_LSB)
+#define TXPC_MISC_XTALDIV_SET(x) (((x) << TXPC_MISC_XTALDIV_LSB) & TXPC_MISC_XTALDIV_MASK)
+#define TXPC_MISC_SPARE_MSB 5
+#define TXPC_MISC_SPARE_LSB 0
+#define TXPC_MISC_SPARE_MASK 0x0000003f
+#define TXPC_MISC_SPARE_GET(x) (((x) & TXPC_MISC_SPARE_MASK) >> TXPC_MISC_SPARE_LSB)
+#define TXPC_MISC_SPARE_SET(x) (((x) << TXPC_MISC_SPARE_LSB) & TXPC_MISC_SPARE_MASK)
+
+#define RXTXBB_RXTXBB1_ADDRESS 0x00000050
+#define RXTXBB_RXTXBB1_OFFSET 0x00000050
+#define RXTXBB_RXTXBB1_SPARE_MSB 31
+#define RXTXBB_RXTXBB1_SPARE_LSB 19
+#define RXTXBB_RXTXBB1_SPARE_MASK 0xfff80000
+#define RXTXBB_RXTXBB1_SPARE_GET(x) (((x) & RXTXBB_RXTXBB1_SPARE_MASK) >> RXTXBB_RXTXBB1_SPARE_LSB)
+#define RXTXBB_RXTXBB1_SPARE_SET(x) (((x) << RXTXBB_RXTXBB1_SPARE_LSB) & RXTXBB_RXTXBB1_SPARE_MASK)
+#define RXTXBB_RXTXBB1_FNOTCH_MSB 18
+#define RXTXBB_RXTXBB1_FNOTCH_LSB 17
+#define RXTXBB_RXTXBB1_FNOTCH_MASK 0x00060000
+#define RXTXBB_RXTXBB1_FNOTCH_GET(x) (((x) & RXTXBB_RXTXBB1_FNOTCH_MASK) >> RXTXBB_RXTXBB1_FNOTCH_LSB)
+#define RXTXBB_RXTXBB1_FNOTCH_SET(x) (((x) << RXTXBB_RXTXBB1_FNOTCH_LSB) & RXTXBB_RXTXBB1_FNOTCH_MASK)
+#define RXTXBB_RXTXBB1_SEL_ATB_MSB 16
+#define RXTXBB_RXTXBB1_SEL_ATB_LSB 9
+#define RXTXBB_RXTXBB1_SEL_ATB_MASK 0x0001fe00
+#define RXTXBB_RXTXBB1_SEL_ATB_GET(x) (((x) & RXTXBB_RXTXBB1_SEL_ATB_MASK) >> RXTXBB_RXTXBB1_SEL_ATB_LSB)
+#define RXTXBB_RXTXBB1_SEL_ATB_SET(x) (((x) << RXTXBB_RXTXBB1_SEL_ATB_LSB) & RXTXBB_RXTXBB1_SEL_ATB_MASK)
+#define RXTXBB_RXTXBB1_PDDACINTERFACE_MSB 8
+#define RXTXBB_RXTXBB1_PDDACINTERFACE_LSB 8
+#define RXTXBB_RXTXBB1_PDDACINTERFACE_MASK 0x00000100
+#define RXTXBB_RXTXBB1_PDDACINTERFACE_GET(x) (((x) & RXTXBB_RXTXBB1_PDDACINTERFACE_MASK) >> RXTXBB_RXTXBB1_PDDACINTERFACE_LSB)
+#define RXTXBB_RXTXBB1_PDDACINTERFACE_SET(x) (((x) << RXTXBB_RXTXBB1_PDDACINTERFACE_LSB) & RXTXBB_RXTXBB1_PDDACINTERFACE_MASK)
+#define RXTXBB_RXTXBB1_PDV2I_MSB 7
+#define RXTXBB_RXTXBB1_PDV2I_LSB 7
+#define RXTXBB_RXTXBB1_PDV2I_MASK 0x00000080
+#define RXTXBB_RXTXBB1_PDV2I_GET(x) (((x) & RXTXBB_RXTXBB1_PDV2I_MASK) >> RXTXBB_RXTXBB1_PDV2I_LSB)
+#define RXTXBB_RXTXBB1_PDV2I_SET(x) (((x) << RXTXBB_RXTXBB1_PDV2I_LSB) & RXTXBB_RXTXBB1_PDV2I_MASK)
+#define RXTXBB_RXTXBB1_PDI2V_MSB 6
+#define RXTXBB_RXTXBB1_PDI2V_LSB 6
+#define RXTXBB_RXTXBB1_PDI2V_MASK 0x00000040
+#define RXTXBB_RXTXBB1_PDI2V_GET(x) (((x) & RXTXBB_RXTXBB1_PDI2V_MASK) >> RXTXBB_RXTXBB1_PDI2V_LSB)
+#define RXTXBB_RXTXBB1_PDI2V_SET(x) (((x) << RXTXBB_RXTXBB1_PDI2V_LSB) & RXTXBB_RXTXBB1_PDI2V_MASK)
+#define RXTXBB_RXTXBB1_PDRXTXBB_MSB 5
+#define RXTXBB_RXTXBB1_PDRXTXBB_LSB 5
+#define RXTXBB_RXTXBB1_PDRXTXBB_MASK 0x00000020
+#define RXTXBB_RXTXBB1_PDRXTXBB_GET(x) (((x) & RXTXBB_RXTXBB1_PDRXTXBB_MASK) >> RXTXBB_RXTXBB1_PDRXTXBB_LSB)
+#define RXTXBB_RXTXBB1_PDRXTXBB_SET(x) (((x) << RXTXBB_RXTXBB1_PDRXTXBB_LSB) & RXTXBB_RXTXBB1_PDRXTXBB_MASK)
+#define RXTXBB_RXTXBB1_PDOFFSETLOQ_MSB 4
+#define RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB 4
+#define RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK 0x00000010
+#define RXTXBB_RXTXBB1_PDOFFSETLOQ_GET(x) (((x) & RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK) >> RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB)
+#define RXTXBB_RXTXBB1_PDOFFSETLOQ_SET(x) (((x) << RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB) & RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK)
+#define RXTXBB_RXTXBB1_PDOFFSETHIQ_MSB 3
+#define RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB 3
+#define RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK 0x00000008
+#define RXTXBB_RXTXBB1_PDOFFSETHIQ_GET(x) (((x) & RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK) >> RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB)
+#define RXTXBB_RXTXBB1_PDOFFSETHIQ_SET(x) (((x) << RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB) & RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK)
+#define RXTXBB_RXTXBB1_PDOFFSETI2V_MSB 2
+#define RXTXBB_RXTXBB1_PDOFFSETI2V_LSB 2
+#define RXTXBB_RXTXBB1_PDOFFSETI2V_MASK 0x00000004
+#define RXTXBB_RXTXBB1_PDOFFSETI2V_GET(x) (((x) & RXTXBB_RXTXBB1_PDOFFSETI2V_MASK) >> RXTXBB_RXTXBB1_PDOFFSETI2V_LSB)
+#define RXTXBB_RXTXBB1_PDOFFSETI2V_SET(x) (((x) << RXTXBB_RXTXBB1_PDOFFSETI2V_LSB) & RXTXBB_RXTXBB1_PDOFFSETI2V_MASK)
+#define RXTXBB_RXTXBB1_PDLOQ_MSB 1
+#define RXTXBB_RXTXBB1_PDLOQ_LSB 1
+#define RXTXBB_RXTXBB1_PDLOQ_MASK 0x00000002
+#define RXTXBB_RXTXBB1_PDLOQ_GET(x) (((x) & RXTXBB_RXTXBB1_PDLOQ_MASK) >> RXTXBB_RXTXBB1_PDLOQ_LSB)
+#define RXTXBB_RXTXBB1_PDLOQ_SET(x) (((x) << RXTXBB_RXTXBB1_PDLOQ_LSB) & RXTXBB_RXTXBB1_PDLOQ_MASK)
+#define RXTXBB_RXTXBB1_PDHIQ_MSB 0
+#define RXTXBB_RXTXBB1_PDHIQ_LSB 0
+#define RXTXBB_RXTXBB1_PDHIQ_MASK 0x00000001
+#define RXTXBB_RXTXBB1_PDHIQ_GET(x) (((x) & RXTXBB_RXTXBB1_PDHIQ_MASK) >> RXTXBB_RXTXBB1_PDHIQ_LSB)
+#define RXTXBB_RXTXBB1_PDHIQ_SET(x) (((x) << RXTXBB_RXTXBB1_PDHIQ_LSB) & RXTXBB_RXTXBB1_PDHIQ_MASK)
+
+#define RXTXBB_RXTXBB2_ADDRESS 0x00000054
+#define RXTXBB_RXTXBB2_OFFSET 0x00000054
+#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MSB 31
+#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB 29
+#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK 0xe0000000
+#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB)
+#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK)
+#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MSB 28
+#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB 26
+#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK 0x1c000000
+#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB)
+#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK)
+#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MSB 25
+#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB 23
+#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK 0x03800000
+#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB)
+#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK)
+#define RXTXBB_RXTXBB2_SPARE_MSB 22
+#define RXTXBB_RXTXBB2_SPARE_LSB 21
+#define RXTXBB_RXTXBB2_SPARE_MASK 0x00600000
+#define RXTXBB_RXTXBB2_SPARE_GET(x) (((x) & RXTXBB_RXTXBB2_SPARE_MASK) >> RXTXBB_RXTXBB2_SPARE_LSB)
+#define RXTXBB_RXTXBB2_SPARE_SET(x) (((x) << RXTXBB_RXTXBB2_SPARE_LSB) & RXTXBB_RXTXBB2_SPARE_MASK)
+#define RXTXBB_RXTXBB2_SHORTBUFFER_MSB 20
+#define RXTXBB_RXTXBB2_SHORTBUFFER_LSB 20
+#define RXTXBB_RXTXBB2_SHORTBUFFER_MASK 0x00100000
+#define RXTXBB_RXTXBB2_SHORTBUFFER_GET(x) (((x) & RXTXBB_RXTXBB2_SHORTBUFFER_MASK) >> RXTXBB_RXTXBB2_SHORTBUFFER_LSB)
+#define RXTXBB_RXTXBB2_SHORTBUFFER_SET(x) (((x) << RXTXBB_RXTXBB2_SHORTBUFFER_LSB) & RXTXBB_RXTXBB2_SHORTBUFFER_MASK)
+#define RXTXBB_RXTXBB2_SELBUFFER_MSB 19
+#define RXTXBB_RXTXBB2_SELBUFFER_LSB 19
+#define RXTXBB_RXTXBB2_SELBUFFER_MASK 0x00080000
+#define RXTXBB_RXTXBB2_SELBUFFER_GET(x) (((x) & RXTXBB_RXTXBB2_SELBUFFER_MASK) >> RXTXBB_RXTXBB2_SELBUFFER_LSB)
+#define RXTXBB_RXTXBB2_SELBUFFER_SET(x) (((x) << RXTXBB_RXTXBB2_SELBUFFER_LSB) & RXTXBB_RXTXBB2_SELBUFFER_MASK)
+#define RXTXBB_RXTXBB2_SEL_DAC_TEST_MSB 18
+#define RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB 18
+#define RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK 0x00040000
+#define RXTXBB_RXTXBB2_SEL_DAC_TEST_GET(x) (((x) & RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB)
+#define RXTXBB_RXTXBB2_SEL_DAC_TEST_SET(x) (((x) << RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB) & RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK)
+#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_MSB 17
+#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB 17
+#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK 0x00020000
+#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_GET(x) (((x) & RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB)
+#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_SET(x) (((x) << RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB) & RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK)
+#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_MSB 16
+#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB 16
+#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK 0x00010000
+#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_GET(x) (((x) & RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB)
+#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_SET(x) (((x) << RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB) & RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK)
+#define RXTXBB_RXTXBB2_SEL_I2V_TEST_MSB 15
+#define RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB 15
+#define RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK 0x00008000
+#define RXTXBB_RXTXBB2_SEL_I2V_TEST_GET(x) (((x) & RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB)
+#define RXTXBB_RXTXBB2_SEL_I2V_TEST_SET(x) (((x) << RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB) & RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK)
+#define RXTXBB_RXTXBB2_CMSEL_MSB 14
+#define RXTXBB_RXTXBB2_CMSEL_LSB 13
+#define RXTXBB_RXTXBB2_CMSEL_MASK 0x00006000
+#define RXTXBB_RXTXBB2_CMSEL_GET(x) (((x) & RXTXBB_RXTXBB2_CMSEL_MASK) >> RXTXBB_RXTXBB2_CMSEL_LSB)
+#define RXTXBB_RXTXBB2_CMSEL_SET(x) (((x) << RXTXBB_RXTXBB2_CMSEL_LSB) & RXTXBB_RXTXBB2_CMSEL_MASK)
+#define RXTXBB_RXTXBB2_FILTERFC_MSB 12
+#define RXTXBB_RXTXBB2_FILTERFC_LSB 8
+#define RXTXBB_RXTXBB2_FILTERFC_MASK 0x00001f00
+#define RXTXBB_RXTXBB2_FILTERFC_GET(x) (((x) & RXTXBB_RXTXBB2_FILTERFC_MASK) >> RXTXBB_RXTXBB2_FILTERFC_LSB)
+#define RXTXBB_RXTXBB2_FILTERFC_SET(x) (((x) << RXTXBB_RXTXBB2_FILTERFC_LSB) & RXTXBB_RXTXBB2_FILTERFC_MASK)
+#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_MSB 7
+#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB 7
+#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK 0x00000080
+#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_GET(x) (((x) & RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK) >> RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB)
+#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_SET(x) (((x) << RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB) & RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK)
+#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_MSB 6
+#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB 6
+#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK 0x00000040
+#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_GET(x) (((x) & RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK) >> RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB)
+#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_SET(x) (((x) << RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB) & RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK)
+#define RXTXBB_RXTXBB2_PATH2HIQ_EN_MSB 5
+#define RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB 5
+#define RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK 0x00000020
+#define RXTXBB_RXTXBB2_PATH2HIQ_EN_GET(x) (((x) & RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB)
+#define RXTXBB_RXTXBB2_PATH2HIQ_EN_SET(x) (((x) << RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB) & RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK)
+#define RXTXBB_RXTXBB2_PATH1HIQ_EN_MSB 4
+#define RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB 4
+#define RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK 0x00000010
+#define RXTXBB_RXTXBB2_PATH1HIQ_EN_GET(x) (((x) & RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB)
+#define RXTXBB_RXTXBB2_PATH1HIQ_EN_SET(x) (((x) << RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB) & RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK)
+#define RXTXBB_RXTXBB2_PATH3LOQ_EN_MSB 3
+#define RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB 3
+#define RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK 0x00000008
+#define RXTXBB_RXTXBB2_PATH3LOQ_EN_GET(x) (((x) & RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB)
+#define RXTXBB_RXTXBB2_PATH3LOQ_EN_SET(x) (((x) << RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK)
+#define RXTXBB_RXTXBB2_PATH2LOQ_EN_MSB 2
+#define RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB 2
+#define RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK 0x00000004
+#define RXTXBB_RXTXBB2_PATH2LOQ_EN_GET(x) (((x) & RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB)
+#define RXTXBB_RXTXBB2_PATH2LOQ_EN_SET(x) (((x) << RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK)
+#define RXTXBB_RXTXBB2_PATH1LOQ_EN_MSB 1
+#define RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB 1
+#define RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK 0x00000002
+#define RXTXBB_RXTXBB2_PATH1LOQ_EN_GET(x) (((x) & RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB)
+#define RXTXBB_RXTXBB2_PATH1LOQ_EN_SET(x) (((x) << RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK)
+#define RXTXBB_RXTXBB2_PATH_OVERRIDE_MSB 0
+#define RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB 0
+#define RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK 0x00000001
+#define RXTXBB_RXTXBB2_PATH_OVERRIDE_GET(x) (((x) & RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK) >> RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB)
+#define RXTXBB_RXTXBB2_PATH_OVERRIDE_SET(x) (((x) << RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB) & RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK)
+
+#define RXTXBB_RXTXBB3_ADDRESS 0x00000058
+#define RXTXBB_RXTXBB3_OFFSET 0x00000058
+#define RXTXBB_RXTXBB3_SPARE_MSB 31
+#define RXTXBB_RXTXBB3_SPARE_LSB 27
+#define RXTXBB_RXTXBB3_SPARE_MASK 0xf8000000
+#define RXTXBB_RXTXBB3_SPARE_GET(x) (((x) & RXTXBB_RXTXBB3_SPARE_MASK) >> RXTXBB_RXTXBB3_SPARE_LSB)
+#define RXTXBB_RXTXBB3_SPARE_SET(x) (((x) << RXTXBB_RXTXBB3_SPARE_LSB) & RXTXBB_RXTXBB3_SPARE_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MSB 26
+#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB 24
+#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK 0x07000000
+#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MSB 23
+#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB 21
+#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK 0x00e00000
+#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MSB 20
+#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB 18
+#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK 0x001c0000
+#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MSB 17
+#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB 15
+#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK 0x00038000
+#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MSB 14
+#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB 12
+#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK 0x00007000
+#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MSB 11
+#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB 9
+#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK 0x00000e00
+#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MSB 8
+#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB 6
+#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK 0x000001c0
+#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MSB 5
+#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB 3
+#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK 0x00000038
+#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK) >> RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB) & RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK)
+#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MSB 2
+#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB 0
+#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK 0x00000007
+#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB)
+#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK)
+
+#define RXTXBB_RXTXBB4_ADDRESS 0x0000005c
+#define RXTXBB_RXTXBB4_OFFSET 0x0000005c
+#define RXTXBB_RXTXBB4_SPARE_MSB 31
+#define RXTXBB_RXTXBB4_SPARE_LSB 31
+#define RXTXBB_RXTXBB4_SPARE_MASK 0x80000000
+#define RXTXBB_RXTXBB4_SPARE_GET(x) (((x) & RXTXBB_RXTXBB4_SPARE_MASK) >> RXTXBB_RXTXBB4_SPARE_LSB)
+#define RXTXBB_RXTXBB4_SPARE_SET(x) (((x) << RXTXBB_RXTXBB4_SPARE_LSB) & RXTXBB_RXTXBB4_SPARE_MASK)
+#define RXTXBB_RXTXBB4_LOCALOFFSET_MSB 30
+#define RXTXBB_RXTXBB4_LOCALOFFSET_LSB 30
+#define RXTXBB_RXTXBB4_LOCALOFFSET_MASK 0x40000000
+#define RXTXBB_RXTXBB4_LOCALOFFSET_GET(x) (((x) & RXTXBB_RXTXBB4_LOCALOFFSET_MASK) >> RXTXBB_RXTXBB4_LOCALOFFSET_LSB)
+#define RXTXBB_RXTXBB4_LOCALOFFSET_SET(x) (((x) << RXTXBB_RXTXBB4_LOCALOFFSET_LSB) & RXTXBB_RXTXBB4_LOCALOFFSET_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRHII_MSB 29
+#define RXTXBB_RXTXBB4_OFSTCORRHII_LSB 25
+#define RXTXBB_RXTXBB4_OFSTCORRHII_MASK 0x3e000000
+#define RXTXBB_RXTXBB4_OFSTCORRHII_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRHII_MASK) >> RXTXBB_RXTXBB4_OFSTCORRHII_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRHII_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRHII_LSB) & RXTXBB_RXTXBB4_OFSTCORRHII_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRHIQ_MSB 24
+#define RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB 20
+#define RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK 0x01f00000
+#define RXTXBB_RXTXBB4_OFSTCORRHIQ_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRHIQ_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRLOI_MSB 19
+#define RXTXBB_RXTXBB4_OFSTCORRLOI_LSB 15
+#define RXTXBB_RXTXBB4_OFSTCORRLOI_MASK 0x000f8000
+#define RXTXBB_RXTXBB4_OFSTCORRLOI_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRLOI_MASK) >> RXTXBB_RXTXBB4_OFSTCORRLOI_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRLOI_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRLOI_LSB) & RXTXBB_RXTXBB4_OFSTCORRLOI_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRLOQ_MSB 14
+#define RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB 10
+#define RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK 0x00007c00
+#define RXTXBB_RXTXBB4_OFSTCORRLOQ_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRLOQ_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRI2VI_MSB 9
+#define RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB 5
+#define RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK 0x000003e0
+#define RXTXBB_RXTXBB4_OFSTCORRI2VI_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK) >> RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRI2VI_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB) & RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK)
+#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_MSB 4
+#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB 0
+#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK 0x0000001f
+#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_GET(x) (((x) & RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB)
+#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_SET(x) (((x) << RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK)
+
+#define ADDAC_ADDAC1_ADDRESS 0x00000060
+#define ADDAC_ADDAC1_OFFSET 0x00000060
+#define ADDAC_ADDAC1_PLL_SVREG_MSB 31
+#define ADDAC_ADDAC1_PLL_SVREG_LSB 31
+#define ADDAC_ADDAC1_PLL_SVREG_MASK 0x80000000
+#define ADDAC_ADDAC1_PLL_SVREG_GET(x) (((x) & ADDAC_ADDAC1_PLL_SVREG_MASK) >> ADDAC_ADDAC1_PLL_SVREG_LSB)
+#define ADDAC_ADDAC1_PLL_SVREG_SET(x) (((x) << ADDAC_ADDAC1_PLL_SVREG_LSB) & ADDAC_ADDAC1_PLL_SVREG_MASK)
+#define ADDAC_ADDAC1_PLL_SCLAMP_MSB 30
+#define ADDAC_ADDAC1_PLL_SCLAMP_LSB 28
+#define ADDAC_ADDAC1_PLL_SCLAMP_MASK 0x70000000
+#define ADDAC_ADDAC1_PLL_SCLAMP_GET(x) (((x) & ADDAC_ADDAC1_PLL_SCLAMP_MASK) >> ADDAC_ADDAC1_PLL_SCLAMP_LSB)
+#define ADDAC_ADDAC1_PLL_SCLAMP_SET(x) (((x) << ADDAC_ADDAC1_PLL_SCLAMP_LSB) & ADDAC_ADDAC1_PLL_SCLAMP_MASK)
+#define ADDAC_ADDAC1_PLL_ATB_MSB 27
+#define ADDAC_ADDAC1_PLL_ATB_LSB 26
+#define ADDAC_ADDAC1_PLL_ATB_MASK 0x0c000000
+#define ADDAC_ADDAC1_PLL_ATB_GET(x) (((x) & ADDAC_ADDAC1_PLL_ATB_MASK) >> ADDAC_ADDAC1_PLL_ATB_LSB)
+#define ADDAC_ADDAC1_PLL_ATB_SET(x) (((x) << ADDAC_ADDAC1_PLL_ATB_LSB) & ADDAC_ADDAC1_PLL_ATB_MASK)
+#define ADDAC_ADDAC1_PLL_ICP_MSB 25
+#define ADDAC_ADDAC1_PLL_ICP_LSB 23
+#define ADDAC_ADDAC1_PLL_ICP_MASK 0x03800000
+#define ADDAC_ADDAC1_PLL_ICP_GET(x) (((x) & ADDAC_ADDAC1_PLL_ICP_MASK) >> ADDAC_ADDAC1_PLL_ICP_LSB)
+#define ADDAC_ADDAC1_PLL_ICP_SET(x) (((x) << ADDAC_ADDAC1_PLL_ICP_LSB) & ADDAC_ADDAC1_PLL_ICP_MASK)
+#define ADDAC_ADDAC1_PLL_FILTER_MSB 22
+#define ADDAC_ADDAC1_PLL_FILTER_LSB 15
+#define ADDAC_ADDAC1_PLL_FILTER_MASK 0x007f8000
+#define ADDAC_ADDAC1_PLL_FILTER_GET(x) (((x) & ADDAC_ADDAC1_PLL_FILTER_MASK) >> ADDAC_ADDAC1_PLL_FILTER_LSB)
+#define ADDAC_ADDAC1_PLL_FILTER_SET(x) (((x) << ADDAC_ADDAC1_PLL_FILTER_LSB) & ADDAC_ADDAC1_PLL_FILTER_MASK)
+#define ADDAC_ADDAC1_PWDPLL_MSB 14
+#define ADDAC_ADDAC1_PWDPLL_LSB 14
+#define ADDAC_ADDAC1_PWDPLL_MASK 0x00004000
+#define ADDAC_ADDAC1_PWDPLL_GET(x) (((x) & ADDAC_ADDAC1_PWDPLL_MASK) >> ADDAC_ADDAC1_PWDPLL_LSB)
+#define ADDAC_ADDAC1_PWDPLL_SET(x) (((x) << ADDAC_ADDAC1_PWDPLL_LSB) & ADDAC_ADDAC1_PWDPLL_MASK)
+#define ADDAC_ADDAC1_PWDADC_MSB 13
+#define ADDAC_ADDAC1_PWDADC_LSB 13
+#define ADDAC_ADDAC1_PWDADC_MASK 0x00002000
+#define ADDAC_ADDAC1_PWDADC_GET(x) (((x) & ADDAC_ADDAC1_PWDADC_MASK) >> ADDAC_ADDAC1_PWDADC_LSB)
+#define ADDAC_ADDAC1_PWDADC_SET(x) (((x) << ADDAC_ADDAC1_PWDADC_LSB) & ADDAC_ADDAC1_PWDADC_MASK)
+#define ADDAC_ADDAC1_PWDDAC_MSB 12
+#define ADDAC_ADDAC1_PWDDAC_LSB 12
+#define ADDAC_ADDAC1_PWDDAC_MASK 0x00001000
+#define ADDAC_ADDAC1_PWDDAC_GET(x) (((x) & ADDAC_ADDAC1_PWDDAC_MASK) >> ADDAC_ADDAC1_PWDDAC_LSB)
+#define ADDAC_ADDAC1_PWDDAC_SET(x) (((x) << ADDAC_ADDAC1_PWDDAC_LSB) & ADDAC_ADDAC1_PWDDAC_MASK)
+#define ADDAC_ADDAC1_FORCEMSBLOW_MSB 11
+#define ADDAC_ADDAC1_FORCEMSBLOW_LSB 11
+#define ADDAC_ADDAC1_FORCEMSBLOW_MASK 0x00000800
+#define ADDAC_ADDAC1_FORCEMSBLOW_GET(x) (((x) & ADDAC_ADDAC1_FORCEMSBLOW_MASK) >> ADDAC_ADDAC1_FORCEMSBLOW_LSB)
+#define ADDAC_ADDAC1_FORCEMSBLOW_SET(x) (((x) << ADDAC_ADDAC1_FORCEMSBLOW_LSB) & ADDAC_ADDAC1_FORCEMSBLOW_MASK)
+#define ADDAC_ADDAC1_SELMANPWDS_MSB 10
+#define ADDAC_ADDAC1_SELMANPWDS_LSB 10
+#define ADDAC_ADDAC1_SELMANPWDS_MASK 0x00000400
+#define ADDAC_ADDAC1_SELMANPWDS_GET(x) (((x) & ADDAC_ADDAC1_SELMANPWDS_MASK) >> ADDAC_ADDAC1_SELMANPWDS_LSB)
+#define ADDAC_ADDAC1_SELMANPWDS_SET(x) (((x) << ADDAC_ADDAC1_SELMANPWDS_LSB) & ADDAC_ADDAC1_SELMANPWDS_MASK)
+#define ADDAC_ADDAC1_INV_CLK160_ADC_MSB 9
+#define ADDAC_ADDAC1_INV_CLK160_ADC_LSB 9
+#define ADDAC_ADDAC1_INV_CLK160_ADC_MASK 0x00000200
+#define ADDAC_ADDAC1_INV_CLK160_ADC_GET(x) (((x) & ADDAC_ADDAC1_INV_CLK160_ADC_MASK) >> ADDAC_ADDAC1_INV_CLK160_ADC_LSB)
+#define ADDAC_ADDAC1_INV_CLK160_ADC_SET(x) (((x) << ADDAC_ADDAC1_INV_CLK160_ADC_LSB) & ADDAC_ADDAC1_INV_CLK160_ADC_MASK)
+#define ADDAC_ADDAC1_CM_SEL_MSB 8
+#define ADDAC_ADDAC1_CM_SEL_LSB 7
+#define ADDAC_ADDAC1_CM_SEL_MASK 0x00000180
+#define ADDAC_ADDAC1_CM_SEL_GET(x) (((x) & ADDAC_ADDAC1_CM_SEL_MASK) >> ADDAC_ADDAC1_CM_SEL_LSB)
+#define ADDAC_ADDAC1_CM_SEL_SET(x) (((x) << ADDAC_ADDAC1_CM_SEL_LSB) & ADDAC_ADDAC1_CM_SEL_MASK)
+#define ADDAC_ADDAC1_DISABLE_DAC_REG_MSB 6
+#define ADDAC_ADDAC1_DISABLE_DAC_REG_LSB 6
+#define ADDAC_ADDAC1_DISABLE_DAC_REG_MASK 0x00000040
+#define ADDAC_ADDAC1_DISABLE_DAC_REG_GET(x) (((x) & ADDAC_ADDAC1_DISABLE_DAC_REG_MASK) >> ADDAC_ADDAC1_DISABLE_DAC_REG_LSB)
+#define ADDAC_ADDAC1_DISABLE_DAC_REG_SET(x) (((x) << ADDAC_ADDAC1_DISABLE_DAC_REG_LSB) & ADDAC_ADDAC1_DISABLE_DAC_REG_MASK)
+#define ADDAC_ADDAC1_SPARE_MSB 5
+#define ADDAC_ADDAC1_SPARE_LSB 0
+#define ADDAC_ADDAC1_SPARE_MASK 0x0000003f
+#define ADDAC_ADDAC1_SPARE_GET(x) (((x) & ADDAC_ADDAC1_SPARE_MASK) >> ADDAC_ADDAC1_SPARE_LSB)
+#define ADDAC_ADDAC1_SPARE_SET(x) (((x) << ADDAC_ADDAC1_SPARE_LSB) & ADDAC_ADDAC1_SPARE_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct analog_reg_reg_s {
+ volatile unsigned int synth_synth1;
+ volatile unsigned int synth_synth2;
+ volatile unsigned int synth_synth3;
+ volatile unsigned int synth_synth4;
+ volatile unsigned int synth_synth5;
+ volatile unsigned int synth_synth6;
+ volatile unsigned int synth_synth7;
+ volatile unsigned int synth_synth8;
+ volatile unsigned int rf5g_rf5g1;
+ volatile unsigned int rf5g_rf5g2;
+ volatile unsigned int rf2g_rf2g1;
+ volatile unsigned int rf2g_rf2g2;
+ volatile unsigned int top_gain;
+ volatile unsigned int top_top;
+ volatile unsigned int bias_bias_sel;
+ volatile unsigned int bias_bias1;
+ volatile unsigned int bias_bias2;
+ volatile unsigned int bias_bias3;
+ volatile unsigned int txpc_txpc;
+ volatile unsigned int txpc_misc;
+ volatile unsigned int rxtxbb_rxtxbb1;
+ volatile unsigned int rxtxbb_rxtxbb2;
+ volatile unsigned int rxtxbb_rxtxbb3;
+ volatile unsigned int rxtxbb_rxtxbb4;
+ volatile unsigned int addac_addac1;
+} analog_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _ANALOG_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h
new file mode 100644
index 000000000000..f3bf6d6cc82b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h
@@ -0,0 +1,13 @@
+#ifndef _APB_MAP_H_
+#define _APB_MAP_H_
+
+#define RTC_BASE_ADDRESS 0x00004000
+#define VMC_BASE_ADDRESS 0x00008000
+#define UART_BASE_ADDRESS 0x0000c000
+#define SI_BASE_ADDRESS 0x00010000
+#define GPIO_BASE_ADDRESS 0x00014000
+#define MBOX_BASE_ADDRESS 0x00018000
+#define ANALOG_INTF_BASE_ADDRESS 0x0001c000
+#define MAC_BASE_ADDRESS 0x00020000
+
+#endif /* _APB_MAP_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h
new file mode 100644
index 000000000000..4f2b964b7df3
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h
@@ -0,0 +1,977 @@
+#ifndef _GPIO_REG_REG_H_
+#define _GPIO_REG_REG_H_
+
+#define GPIO_OUT_ADDRESS 0x00000000
+#define GPIO_OUT_OFFSET 0x00000000
+#define GPIO_OUT_DATA_MSB 17
+#define GPIO_OUT_DATA_LSB 0
+#define GPIO_OUT_DATA_MASK 0x0003ffff
+#define GPIO_OUT_DATA_GET(x) (((x) & GPIO_OUT_DATA_MASK) >> GPIO_OUT_DATA_LSB)
+#define GPIO_OUT_DATA_SET(x) (((x) << GPIO_OUT_DATA_LSB) & GPIO_OUT_DATA_MASK)
+
+#define GPIO_OUT_W1TS_ADDRESS 0x00000004
+#define GPIO_OUT_W1TS_OFFSET 0x00000004
+#define GPIO_OUT_W1TS_DATA_MSB 17
+#define GPIO_OUT_W1TS_DATA_LSB 0
+#define GPIO_OUT_W1TS_DATA_MASK 0x0003ffff
+#define GPIO_OUT_W1TS_DATA_GET(x) (((x) & GPIO_OUT_W1TS_DATA_MASK) >> GPIO_OUT_W1TS_DATA_LSB)
+#define GPIO_OUT_W1TS_DATA_SET(x) (((x) << GPIO_OUT_W1TS_DATA_LSB) & GPIO_OUT_W1TS_DATA_MASK)
+
+#define GPIO_OUT_W1TC_ADDRESS 0x00000008
+#define GPIO_OUT_W1TC_OFFSET 0x00000008
+#define GPIO_OUT_W1TC_DATA_MSB 17
+#define GPIO_OUT_W1TC_DATA_LSB 0
+#define GPIO_OUT_W1TC_DATA_MASK 0x0003ffff
+#define GPIO_OUT_W1TC_DATA_GET(x) (((x) & GPIO_OUT_W1TC_DATA_MASK) >> GPIO_OUT_W1TC_DATA_LSB)
+#define GPIO_OUT_W1TC_DATA_SET(x) (((x) << GPIO_OUT_W1TC_DATA_LSB) & GPIO_OUT_W1TC_DATA_MASK)
+
+#define GPIO_ENABLE_ADDRESS 0x0000000c
+#define GPIO_ENABLE_OFFSET 0x0000000c
+#define GPIO_ENABLE_DATA_MSB 17
+#define GPIO_ENABLE_DATA_LSB 0
+#define GPIO_ENABLE_DATA_MASK 0x0003ffff
+#define GPIO_ENABLE_DATA_GET(x) (((x) & GPIO_ENABLE_DATA_MASK) >> GPIO_ENABLE_DATA_LSB)
+#define GPIO_ENABLE_DATA_SET(x) (((x) << GPIO_ENABLE_DATA_LSB) & GPIO_ENABLE_DATA_MASK)
+
+#define GPIO_ENABLE_W1TS_ADDRESS 0x00000010
+#define GPIO_ENABLE_W1TS_OFFSET 0x00000010
+#define GPIO_ENABLE_W1TS_DATA_MSB 17
+#define GPIO_ENABLE_W1TS_DATA_LSB 0
+#define GPIO_ENABLE_W1TS_DATA_MASK 0x0003ffff
+#define GPIO_ENABLE_W1TS_DATA_GET(x) (((x) & GPIO_ENABLE_W1TS_DATA_MASK) >> GPIO_ENABLE_W1TS_DATA_LSB)
+#define GPIO_ENABLE_W1TS_DATA_SET(x) (((x) << GPIO_ENABLE_W1TS_DATA_LSB) & GPIO_ENABLE_W1TS_DATA_MASK)
+
+#define GPIO_ENABLE_W1TC_ADDRESS 0x00000014
+#define GPIO_ENABLE_W1TC_OFFSET 0x00000014
+#define GPIO_ENABLE_W1TC_DATA_MSB 17
+#define GPIO_ENABLE_W1TC_DATA_LSB 0
+#define GPIO_ENABLE_W1TC_DATA_MASK 0x0003ffff
+#define GPIO_ENABLE_W1TC_DATA_GET(x) (((x) & GPIO_ENABLE_W1TC_DATA_MASK) >> GPIO_ENABLE_W1TC_DATA_LSB)
+#define GPIO_ENABLE_W1TC_DATA_SET(x) (((x) << GPIO_ENABLE_W1TC_DATA_LSB) & GPIO_ENABLE_W1TC_DATA_MASK)
+
+#define GPIO_IN_ADDRESS 0x00000018
+#define GPIO_IN_OFFSET 0x00000018
+#define GPIO_IN_DATA_MSB 17
+#define GPIO_IN_DATA_LSB 0
+#define GPIO_IN_DATA_MASK 0x0003ffff
+#define GPIO_IN_DATA_GET(x) (((x) & GPIO_IN_DATA_MASK) >> GPIO_IN_DATA_LSB)
+#define GPIO_IN_DATA_SET(x) (((x) << GPIO_IN_DATA_LSB) & GPIO_IN_DATA_MASK)
+
+#define GPIO_STATUS_ADDRESS 0x0000001c
+#define GPIO_STATUS_OFFSET 0x0000001c
+#define GPIO_STATUS_INTERRUPT_MSB 17
+#define GPIO_STATUS_INTERRUPT_LSB 0
+#define GPIO_STATUS_INTERRUPT_MASK 0x0003ffff
+#define GPIO_STATUS_INTERRUPT_GET(x) (((x) & GPIO_STATUS_INTERRUPT_MASK) >> GPIO_STATUS_INTERRUPT_LSB)
+#define GPIO_STATUS_INTERRUPT_SET(x) (((x) << GPIO_STATUS_INTERRUPT_LSB) & GPIO_STATUS_INTERRUPT_MASK)
+
+#define GPIO_STATUS_W1TS_ADDRESS 0x00000020
+#define GPIO_STATUS_W1TS_OFFSET 0x00000020
+#define GPIO_STATUS_W1TS_INTERRUPT_MSB 17
+#define GPIO_STATUS_W1TS_INTERRUPT_LSB 0
+#define GPIO_STATUS_W1TS_INTERRUPT_MASK 0x0003ffff
+#define GPIO_STATUS_W1TS_INTERRUPT_GET(x) (((x) & GPIO_STATUS_W1TS_INTERRUPT_MASK) >> GPIO_STATUS_W1TS_INTERRUPT_LSB)
+#define GPIO_STATUS_W1TS_INTERRUPT_SET(x) (((x) << GPIO_STATUS_W1TS_INTERRUPT_LSB) & GPIO_STATUS_W1TS_INTERRUPT_MASK)
+
+#define GPIO_STATUS_W1TC_ADDRESS 0x00000024
+#define GPIO_STATUS_W1TC_OFFSET 0x00000024
+#define GPIO_STATUS_W1TC_INTERRUPT_MSB 17
+#define GPIO_STATUS_W1TC_INTERRUPT_LSB 0
+#define GPIO_STATUS_W1TC_INTERRUPT_MASK 0x0003ffff
+#define GPIO_STATUS_W1TC_INTERRUPT_GET(x) (((x) & GPIO_STATUS_W1TC_INTERRUPT_MASK) >> GPIO_STATUS_W1TC_INTERRUPT_LSB)
+#define GPIO_STATUS_W1TC_INTERRUPT_SET(x) (((x) << GPIO_STATUS_W1TC_INTERRUPT_LSB) & GPIO_STATUS_W1TC_INTERRUPT_MASK)
+
+#define GPIO_PIN0_ADDRESS 0x00000028
+#define GPIO_PIN0_OFFSET 0x00000028
+#define GPIO_PIN0_CONFIG_MSB 12
+#define GPIO_PIN0_CONFIG_LSB 11
+#define GPIO_PIN0_CONFIG_MASK 0x00001800
+#define GPIO_PIN0_CONFIG_GET(x) (((x) & GPIO_PIN0_CONFIG_MASK) >> GPIO_PIN0_CONFIG_LSB)
+#define GPIO_PIN0_CONFIG_SET(x) (((x) << GPIO_PIN0_CONFIG_LSB) & GPIO_PIN0_CONFIG_MASK)
+#define GPIO_PIN0_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN0_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN0_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN0_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN0_WAKEUP_ENABLE_MASK) >> GPIO_PIN0_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN0_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN0_WAKEUP_ENABLE_LSB) & GPIO_PIN0_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN0_INT_TYPE_MSB 9
+#define GPIO_PIN0_INT_TYPE_LSB 7
+#define GPIO_PIN0_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN0_INT_TYPE_GET(x) (((x) & GPIO_PIN0_INT_TYPE_MASK) >> GPIO_PIN0_INT_TYPE_LSB)
+#define GPIO_PIN0_INT_TYPE_SET(x) (((x) << GPIO_PIN0_INT_TYPE_LSB) & GPIO_PIN0_INT_TYPE_MASK)
+#define GPIO_PIN0_PAD_DRIVER_MSB 2
+#define GPIO_PIN0_PAD_DRIVER_LSB 2
+#define GPIO_PIN0_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN0_PAD_DRIVER_GET(x) (((x) & GPIO_PIN0_PAD_DRIVER_MASK) >> GPIO_PIN0_PAD_DRIVER_LSB)
+#define GPIO_PIN0_PAD_DRIVER_SET(x) (((x) << GPIO_PIN0_PAD_DRIVER_LSB) & GPIO_PIN0_PAD_DRIVER_MASK)
+#define GPIO_PIN0_SOURCE_MSB 0
+#define GPIO_PIN0_SOURCE_LSB 0
+#define GPIO_PIN0_SOURCE_MASK 0x00000001
+#define GPIO_PIN0_SOURCE_GET(x) (((x) & GPIO_PIN0_SOURCE_MASK) >> GPIO_PIN0_SOURCE_LSB)
+#define GPIO_PIN0_SOURCE_SET(x) (((x) << GPIO_PIN0_SOURCE_LSB) & GPIO_PIN0_SOURCE_MASK)
+
+#define GPIO_PIN1_ADDRESS 0x0000002c
+#define GPIO_PIN1_OFFSET 0x0000002c
+#define GPIO_PIN1_CONFIG_MSB 12
+#define GPIO_PIN1_CONFIG_LSB 11
+#define GPIO_PIN1_CONFIG_MASK 0x00001800
+#define GPIO_PIN1_CONFIG_GET(x) (((x) & GPIO_PIN1_CONFIG_MASK) >> GPIO_PIN1_CONFIG_LSB)
+#define GPIO_PIN1_CONFIG_SET(x) (((x) << GPIO_PIN1_CONFIG_LSB) & GPIO_PIN1_CONFIG_MASK)
+#define GPIO_PIN1_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN1_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN1_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN1_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN1_WAKEUP_ENABLE_MASK) >> GPIO_PIN1_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN1_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN1_WAKEUP_ENABLE_LSB) & GPIO_PIN1_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN1_INT_TYPE_MSB 9
+#define GPIO_PIN1_INT_TYPE_LSB 7
+#define GPIO_PIN1_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN1_INT_TYPE_GET(x) (((x) & GPIO_PIN1_INT_TYPE_MASK) >> GPIO_PIN1_INT_TYPE_LSB)
+#define GPIO_PIN1_INT_TYPE_SET(x) (((x) << GPIO_PIN1_INT_TYPE_LSB) & GPIO_PIN1_INT_TYPE_MASK)
+#define GPIO_PIN1_PAD_DRIVER_MSB 2
+#define GPIO_PIN1_PAD_DRIVER_LSB 2
+#define GPIO_PIN1_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN1_PAD_DRIVER_GET(x) (((x) & GPIO_PIN1_PAD_DRIVER_MASK) >> GPIO_PIN1_PAD_DRIVER_LSB)
+#define GPIO_PIN1_PAD_DRIVER_SET(x) (((x) << GPIO_PIN1_PAD_DRIVER_LSB) & GPIO_PIN1_PAD_DRIVER_MASK)
+#define GPIO_PIN1_SOURCE_MSB 0
+#define GPIO_PIN1_SOURCE_LSB 0
+#define GPIO_PIN1_SOURCE_MASK 0x00000001
+#define GPIO_PIN1_SOURCE_GET(x) (((x) & GPIO_PIN1_SOURCE_MASK) >> GPIO_PIN1_SOURCE_LSB)
+#define GPIO_PIN1_SOURCE_SET(x) (((x) << GPIO_PIN1_SOURCE_LSB) & GPIO_PIN1_SOURCE_MASK)
+
+#define GPIO_PIN2_ADDRESS 0x00000030
+#define GPIO_PIN2_OFFSET 0x00000030
+#define GPIO_PIN2_CONFIG_MSB 12
+#define GPIO_PIN2_CONFIG_LSB 11
+#define GPIO_PIN2_CONFIG_MASK 0x00001800
+#define GPIO_PIN2_CONFIG_GET(x) (((x) & GPIO_PIN2_CONFIG_MASK) >> GPIO_PIN2_CONFIG_LSB)
+#define GPIO_PIN2_CONFIG_SET(x) (((x) << GPIO_PIN2_CONFIG_LSB) & GPIO_PIN2_CONFIG_MASK)
+#define GPIO_PIN2_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN2_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN2_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN2_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN2_WAKEUP_ENABLE_MASK) >> GPIO_PIN2_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN2_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN2_WAKEUP_ENABLE_LSB) & GPIO_PIN2_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN2_INT_TYPE_MSB 9
+#define GPIO_PIN2_INT_TYPE_LSB 7
+#define GPIO_PIN2_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN2_INT_TYPE_GET(x) (((x) & GPIO_PIN2_INT_TYPE_MASK) >> GPIO_PIN2_INT_TYPE_LSB)
+#define GPIO_PIN2_INT_TYPE_SET(x) (((x) << GPIO_PIN2_INT_TYPE_LSB) & GPIO_PIN2_INT_TYPE_MASK)
+#define GPIO_PIN2_PAD_DRIVER_MSB 2
+#define GPIO_PIN2_PAD_DRIVER_LSB 2
+#define GPIO_PIN2_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN2_PAD_DRIVER_GET(x) (((x) & GPIO_PIN2_PAD_DRIVER_MASK) >> GPIO_PIN2_PAD_DRIVER_LSB)
+#define GPIO_PIN2_PAD_DRIVER_SET(x) (((x) << GPIO_PIN2_PAD_DRIVER_LSB) & GPIO_PIN2_PAD_DRIVER_MASK)
+#define GPIO_PIN2_SOURCE_MSB 0
+#define GPIO_PIN2_SOURCE_LSB 0
+#define GPIO_PIN2_SOURCE_MASK 0x00000001
+#define GPIO_PIN2_SOURCE_GET(x) (((x) & GPIO_PIN2_SOURCE_MASK) >> GPIO_PIN2_SOURCE_LSB)
+#define GPIO_PIN2_SOURCE_SET(x) (((x) << GPIO_PIN2_SOURCE_LSB) & GPIO_PIN2_SOURCE_MASK)
+
+#define GPIO_PIN3_ADDRESS 0x00000034
+#define GPIO_PIN3_OFFSET 0x00000034
+#define GPIO_PIN3_CONFIG_MSB 12
+#define GPIO_PIN3_CONFIG_LSB 11
+#define GPIO_PIN3_CONFIG_MASK 0x00001800
+#define GPIO_PIN3_CONFIG_GET(x) (((x) & GPIO_PIN3_CONFIG_MASK) >> GPIO_PIN3_CONFIG_LSB)
+#define GPIO_PIN3_CONFIG_SET(x) (((x) << GPIO_PIN3_CONFIG_LSB) & GPIO_PIN3_CONFIG_MASK)
+#define GPIO_PIN3_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN3_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN3_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN3_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN3_WAKEUP_ENABLE_MASK) >> GPIO_PIN3_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN3_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN3_WAKEUP_ENABLE_LSB) & GPIO_PIN3_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN3_INT_TYPE_MSB 9
+#define GPIO_PIN3_INT_TYPE_LSB 7
+#define GPIO_PIN3_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN3_INT_TYPE_GET(x) (((x) & GPIO_PIN3_INT_TYPE_MASK) >> GPIO_PIN3_INT_TYPE_LSB)
+#define GPIO_PIN3_INT_TYPE_SET(x) (((x) << GPIO_PIN3_INT_TYPE_LSB) & GPIO_PIN3_INT_TYPE_MASK)
+#define GPIO_PIN3_PAD_DRIVER_MSB 2
+#define GPIO_PIN3_PAD_DRIVER_LSB 2
+#define GPIO_PIN3_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN3_PAD_DRIVER_GET(x) (((x) & GPIO_PIN3_PAD_DRIVER_MASK) >> GPIO_PIN3_PAD_DRIVER_LSB)
+#define GPIO_PIN3_PAD_DRIVER_SET(x) (((x) << GPIO_PIN3_PAD_DRIVER_LSB) & GPIO_PIN3_PAD_DRIVER_MASK)
+#define GPIO_PIN3_SOURCE_MSB 0
+#define GPIO_PIN3_SOURCE_LSB 0
+#define GPIO_PIN3_SOURCE_MASK 0x00000001
+#define GPIO_PIN3_SOURCE_GET(x) (((x) & GPIO_PIN3_SOURCE_MASK) >> GPIO_PIN3_SOURCE_LSB)
+#define GPIO_PIN3_SOURCE_SET(x) (((x) << GPIO_PIN3_SOURCE_LSB) & GPIO_PIN3_SOURCE_MASK)
+
+#define GPIO_PIN4_ADDRESS 0x00000038
+#define GPIO_PIN4_OFFSET 0x00000038
+#define GPIO_PIN4_CONFIG_MSB 12
+#define GPIO_PIN4_CONFIG_LSB 11
+#define GPIO_PIN4_CONFIG_MASK 0x00001800
+#define GPIO_PIN4_CONFIG_GET(x) (((x) & GPIO_PIN4_CONFIG_MASK) >> GPIO_PIN4_CONFIG_LSB)
+#define GPIO_PIN4_CONFIG_SET(x) (((x) << GPIO_PIN4_CONFIG_LSB) & GPIO_PIN4_CONFIG_MASK)
+#define GPIO_PIN4_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN4_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN4_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN4_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN4_WAKEUP_ENABLE_MASK) >> GPIO_PIN4_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN4_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN4_WAKEUP_ENABLE_LSB) & GPIO_PIN4_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN4_INT_TYPE_MSB 9
+#define GPIO_PIN4_INT_TYPE_LSB 7
+#define GPIO_PIN4_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN4_INT_TYPE_GET(x) (((x) & GPIO_PIN4_INT_TYPE_MASK) >> GPIO_PIN4_INT_TYPE_LSB)
+#define GPIO_PIN4_INT_TYPE_SET(x) (((x) << GPIO_PIN4_INT_TYPE_LSB) & GPIO_PIN4_INT_TYPE_MASK)
+#define GPIO_PIN4_PAD_DRIVER_MSB 2
+#define GPIO_PIN4_PAD_DRIVER_LSB 2
+#define GPIO_PIN4_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN4_PAD_DRIVER_GET(x) (((x) & GPIO_PIN4_PAD_DRIVER_MASK) >> GPIO_PIN4_PAD_DRIVER_LSB)
+#define GPIO_PIN4_PAD_DRIVER_SET(x) (((x) << GPIO_PIN4_PAD_DRIVER_LSB) & GPIO_PIN4_PAD_DRIVER_MASK)
+#define GPIO_PIN4_SOURCE_MSB 0
+#define GPIO_PIN4_SOURCE_LSB 0
+#define GPIO_PIN4_SOURCE_MASK 0x00000001
+#define GPIO_PIN4_SOURCE_GET(x) (((x) & GPIO_PIN4_SOURCE_MASK) >> GPIO_PIN4_SOURCE_LSB)
+#define GPIO_PIN4_SOURCE_SET(x) (((x) << GPIO_PIN4_SOURCE_LSB) & GPIO_PIN4_SOURCE_MASK)
+
+#define GPIO_PIN5_ADDRESS 0x0000003c
+#define GPIO_PIN5_OFFSET 0x0000003c
+#define GPIO_PIN5_CONFIG_MSB 12
+#define GPIO_PIN5_CONFIG_LSB 11
+#define GPIO_PIN5_CONFIG_MASK 0x00001800
+#define GPIO_PIN5_CONFIG_GET(x) (((x) & GPIO_PIN5_CONFIG_MASK) >> GPIO_PIN5_CONFIG_LSB)
+#define GPIO_PIN5_CONFIG_SET(x) (((x) << GPIO_PIN5_CONFIG_LSB) & GPIO_PIN5_CONFIG_MASK)
+#define GPIO_PIN5_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN5_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN5_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN5_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN5_WAKEUP_ENABLE_MASK) >> GPIO_PIN5_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN5_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN5_WAKEUP_ENABLE_LSB) & GPIO_PIN5_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN5_INT_TYPE_MSB 9
+#define GPIO_PIN5_INT_TYPE_LSB 7
+#define GPIO_PIN5_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN5_INT_TYPE_GET(x) (((x) & GPIO_PIN5_INT_TYPE_MASK) >> GPIO_PIN5_INT_TYPE_LSB)
+#define GPIO_PIN5_INT_TYPE_SET(x) (((x) << GPIO_PIN5_INT_TYPE_LSB) & GPIO_PIN5_INT_TYPE_MASK)
+#define GPIO_PIN5_PAD_DRIVER_MSB 2
+#define GPIO_PIN5_PAD_DRIVER_LSB 2
+#define GPIO_PIN5_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN5_PAD_DRIVER_GET(x) (((x) & GPIO_PIN5_PAD_DRIVER_MASK) >> GPIO_PIN5_PAD_DRIVER_LSB)
+#define GPIO_PIN5_PAD_DRIVER_SET(x) (((x) << GPIO_PIN5_PAD_DRIVER_LSB) & GPIO_PIN5_PAD_DRIVER_MASK)
+#define GPIO_PIN5_SOURCE_MSB 0
+#define GPIO_PIN5_SOURCE_LSB 0
+#define GPIO_PIN5_SOURCE_MASK 0x00000001
+#define GPIO_PIN5_SOURCE_GET(x) (((x) & GPIO_PIN5_SOURCE_MASK) >> GPIO_PIN5_SOURCE_LSB)
+#define GPIO_PIN5_SOURCE_SET(x) (((x) << GPIO_PIN5_SOURCE_LSB) & GPIO_PIN5_SOURCE_MASK)
+
+#define GPIO_PIN6_ADDRESS 0x00000040
+#define GPIO_PIN6_OFFSET 0x00000040
+#define GPIO_PIN6_CONFIG_MSB 12
+#define GPIO_PIN6_CONFIG_LSB 11
+#define GPIO_PIN6_CONFIG_MASK 0x00001800
+#define GPIO_PIN6_CONFIG_GET(x) (((x) & GPIO_PIN6_CONFIG_MASK) >> GPIO_PIN6_CONFIG_LSB)
+#define GPIO_PIN6_CONFIG_SET(x) (((x) << GPIO_PIN6_CONFIG_LSB) & GPIO_PIN6_CONFIG_MASK)
+#define GPIO_PIN6_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN6_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN6_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN6_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN6_WAKEUP_ENABLE_MASK) >> GPIO_PIN6_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN6_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN6_WAKEUP_ENABLE_LSB) & GPIO_PIN6_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN6_INT_TYPE_MSB 9
+#define GPIO_PIN6_INT_TYPE_LSB 7
+#define GPIO_PIN6_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN6_INT_TYPE_GET(x) (((x) & GPIO_PIN6_INT_TYPE_MASK) >> GPIO_PIN6_INT_TYPE_LSB)
+#define GPIO_PIN6_INT_TYPE_SET(x) (((x) << GPIO_PIN6_INT_TYPE_LSB) & GPIO_PIN6_INT_TYPE_MASK)
+#define GPIO_PIN6_PAD_DRIVER_MSB 2
+#define GPIO_PIN6_PAD_DRIVER_LSB 2
+#define GPIO_PIN6_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN6_PAD_DRIVER_GET(x) (((x) & GPIO_PIN6_PAD_DRIVER_MASK) >> GPIO_PIN6_PAD_DRIVER_LSB)
+#define GPIO_PIN6_PAD_DRIVER_SET(x) (((x) << GPIO_PIN6_PAD_DRIVER_LSB) & GPIO_PIN6_PAD_DRIVER_MASK)
+#define GPIO_PIN6_SOURCE_MSB 0
+#define GPIO_PIN6_SOURCE_LSB 0
+#define GPIO_PIN6_SOURCE_MASK 0x00000001
+#define GPIO_PIN6_SOURCE_GET(x) (((x) & GPIO_PIN6_SOURCE_MASK) >> GPIO_PIN6_SOURCE_LSB)
+#define GPIO_PIN6_SOURCE_SET(x) (((x) << GPIO_PIN6_SOURCE_LSB) & GPIO_PIN6_SOURCE_MASK)
+
+#define GPIO_PIN7_ADDRESS 0x00000044
+#define GPIO_PIN7_OFFSET 0x00000044
+#define GPIO_PIN7_CONFIG_MSB 12
+#define GPIO_PIN7_CONFIG_LSB 11
+#define GPIO_PIN7_CONFIG_MASK 0x00001800
+#define GPIO_PIN7_CONFIG_GET(x) (((x) & GPIO_PIN7_CONFIG_MASK) >> GPIO_PIN7_CONFIG_LSB)
+#define GPIO_PIN7_CONFIG_SET(x) (((x) << GPIO_PIN7_CONFIG_LSB) & GPIO_PIN7_CONFIG_MASK)
+#define GPIO_PIN7_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN7_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN7_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN7_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN7_WAKEUP_ENABLE_MASK) >> GPIO_PIN7_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN7_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN7_WAKEUP_ENABLE_LSB) & GPIO_PIN7_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN7_INT_TYPE_MSB 9
+#define GPIO_PIN7_INT_TYPE_LSB 7
+#define GPIO_PIN7_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN7_INT_TYPE_GET(x) (((x) & GPIO_PIN7_INT_TYPE_MASK) >> GPIO_PIN7_INT_TYPE_LSB)
+#define GPIO_PIN7_INT_TYPE_SET(x) (((x) << GPIO_PIN7_INT_TYPE_LSB) & GPIO_PIN7_INT_TYPE_MASK)
+#define GPIO_PIN7_PAD_DRIVER_MSB 2
+#define GPIO_PIN7_PAD_DRIVER_LSB 2
+#define GPIO_PIN7_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN7_PAD_DRIVER_GET(x) (((x) & GPIO_PIN7_PAD_DRIVER_MASK) >> GPIO_PIN7_PAD_DRIVER_LSB)
+#define GPIO_PIN7_PAD_DRIVER_SET(x) (((x) << GPIO_PIN7_PAD_DRIVER_LSB) & GPIO_PIN7_PAD_DRIVER_MASK)
+#define GPIO_PIN7_SOURCE_MSB 0
+#define GPIO_PIN7_SOURCE_LSB 0
+#define GPIO_PIN7_SOURCE_MASK 0x00000001
+#define GPIO_PIN7_SOURCE_GET(x) (((x) & GPIO_PIN7_SOURCE_MASK) >> GPIO_PIN7_SOURCE_LSB)
+#define GPIO_PIN7_SOURCE_SET(x) (((x) << GPIO_PIN7_SOURCE_LSB) & GPIO_PIN7_SOURCE_MASK)
+
+#define GPIO_PIN8_ADDRESS 0x00000048
+#define GPIO_PIN8_OFFSET 0x00000048
+#define GPIO_PIN8_CONFIG_MSB 12
+#define GPIO_PIN8_CONFIG_LSB 11
+#define GPIO_PIN8_CONFIG_MASK 0x00001800
+#define GPIO_PIN8_CONFIG_GET(x) (((x) & GPIO_PIN8_CONFIG_MASK) >> GPIO_PIN8_CONFIG_LSB)
+#define GPIO_PIN8_CONFIG_SET(x) (((x) << GPIO_PIN8_CONFIG_LSB) & GPIO_PIN8_CONFIG_MASK)
+#define GPIO_PIN8_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN8_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN8_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN8_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN8_WAKEUP_ENABLE_MASK) >> GPIO_PIN8_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN8_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN8_WAKEUP_ENABLE_LSB) & GPIO_PIN8_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN8_INT_TYPE_MSB 9
+#define GPIO_PIN8_INT_TYPE_LSB 7
+#define GPIO_PIN8_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN8_INT_TYPE_GET(x) (((x) & GPIO_PIN8_INT_TYPE_MASK) >> GPIO_PIN8_INT_TYPE_LSB)
+#define GPIO_PIN8_INT_TYPE_SET(x) (((x) << GPIO_PIN8_INT_TYPE_LSB) & GPIO_PIN8_INT_TYPE_MASK)
+#define GPIO_PIN8_PAD_DRIVER_MSB 2
+#define GPIO_PIN8_PAD_DRIVER_LSB 2
+#define GPIO_PIN8_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN8_PAD_DRIVER_GET(x) (((x) & GPIO_PIN8_PAD_DRIVER_MASK) >> GPIO_PIN8_PAD_DRIVER_LSB)
+#define GPIO_PIN8_PAD_DRIVER_SET(x) (((x) << GPIO_PIN8_PAD_DRIVER_LSB) & GPIO_PIN8_PAD_DRIVER_MASK)
+#define GPIO_PIN8_SOURCE_MSB 0
+#define GPIO_PIN8_SOURCE_LSB 0
+#define GPIO_PIN8_SOURCE_MASK 0x00000001
+#define GPIO_PIN8_SOURCE_GET(x) (((x) & GPIO_PIN8_SOURCE_MASK) >> GPIO_PIN8_SOURCE_LSB)
+#define GPIO_PIN8_SOURCE_SET(x) (((x) << GPIO_PIN8_SOURCE_LSB) & GPIO_PIN8_SOURCE_MASK)
+
+#define GPIO_PIN9_ADDRESS 0x0000004c
+#define GPIO_PIN9_OFFSET 0x0000004c
+#define GPIO_PIN9_CONFIG_MSB 12
+#define GPIO_PIN9_CONFIG_LSB 11
+#define GPIO_PIN9_CONFIG_MASK 0x00001800
+#define GPIO_PIN9_CONFIG_GET(x) (((x) & GPIO_PIN9_CONFIG_MASK) >> GPIO_PIN9_CONFIG_LSB)
+#define GPIO_PIN9_CONFIG_SET(x) (((x) << GPIO_PIN9_CONFIG_LSB) & GPIO_PIN9_CONFIG_MASK)
+#define GPIO_PIN9_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN9_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN9_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN9_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN9_WAKEUP_ENABLE_MASK) >> GPIO_PIN9_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN9_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN9_WAKEUP_ENABLE_LSB) & GPIO_PIN9_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN9_INT_TYPE_MSB 9
+#define GPIO_PIN9_INT_TYPE_LSB 7
+#define GPIO_PIN9_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN9_INT_TYPE_GET(x) (((x) & GPIO_PIN9_INT_TYPE_MASK) >> GPIO_PIN9_INT_TYPE_LSB)
+#define GPIO_PIN9_INT_TYPE_SET(x) (((x) << GPIO_PIN9_INT_TYPE_LSB) & GPIO_PIN9_INT_TYPE_MASK)
+#define GPIO_PIN9_PAD_DRIVER_MSB 2
+#define GPIO_PIN9_PAD_DRIVER_LSB 2
+#define GPIO_PIN9_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN9_PAD_DRIVER_GET(x) (((x) & GPIO_PIN9_PAD_DRIVER_MASK) >> GPIO_PIN9_PAD_DRIVER_LSB)
+#define GPIO_PIN9_PAD_DRIVER_SET(x) (((x) << GPIO_PIN9_PAD_DRIVER_LSB) & GPIO_PIN9_PAD_DRIVER_MASK)
+#define GPIO_PIN9_SOURCE_MSB 0
+#define GPIO_PIN9_SOURCE_LSB 0
+#define GPIO_PIN9_SOURCE_MASK 0x00000001
+#define GPIO_PIN9_SOURCE_GET(x) (((x) & GPIO_PIN9_SOURCE_MASK) >> GPIO_PIN9_SOURCE_LSB)
+#define GPIO_PIN9_SOURCE_SET(x) (((x) << GPIO_PIN9_SOURCE_LSB) & GPIO_PIN9_SOURCE_MASK)
+
+#define GPIO_PIN10_ADDRESS 0x00000050
+#define GPIO_PIN10_OFFSET 0x00000050
+#define GPIO_PIN10_CONFIG_MSB 12
+#define GPIO_PIN10_CONFIG_LSB 11
+#define GPIO_PIN10_CONFIG_MASK 0x00001800
+#define GPIO_PIN10_CONFIG_GET(x) (((x) & GPIO_PIN10_CONFIG_MASK) >> GPIO_PIN10_CONFIG_LSB)
+#define GPIO_PIN10_CONFIG_SET(x) (((x) << GPIO_PIN10_CONFIG_LSB) & GPIO_PIN10_CONFIG_MASK)
+#define GPIO_PIN10_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN10_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN10_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN10_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN10_WAKEUP_ENABLE_MASK) >> GPIO_PIN10_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN10_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN10_WAKEUP_ENABLE_LSB) & GPIO_PIN10_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN10_INT_TYPE_MSB 9
+#define GPIO_PIN10_INT_TYPE_LSB 7
+#define GPIO_PIN10_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN10_INT_TYPE_GET(x) (((x) & GPIO_PIN10_INT_TYPE_MASK) >> GPIO_PIN10_INT_TYPE_LSB)
+#define GPIO_PIN10_INT_TYPE_SET(x) (((x) << GPIO_PIN10_INT_TYPE_LSB) & GPIO_PIN10_INT_TYPE_MASK)
+#define GPIO_PIN10_PAD_DRIVER_MSB 2
+#define GPIO_PIN10_PAD_DRIVER_LSB 2
+#define GPIO_PIN10_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN10_PAD_DRIVER_GET(x) (((x) & GPIO_PIN10_PAD_DRIVER_MASK) >> GPIO_PIN10_PAD_DRIVER_LSB)
+#define GPIO_PIN10_PAD_DRIVER_SET(x) (((x) << GPIO_PIN10_PAD_DRIVER_LSB) & GPIO_PIN10_PAD_DRIVER_MASK)
+#define GPIO_PIN10_SOURCE_MSB 0
+#define GPIO_PIN10_SOURCE_LSB 0
+#define GPIO_PIN10_SOURCE_MASK 0x00000001
+#define GPIO_PIN10_SOURCE_GET(x) (((x) & GPIO_PIN10_SOURCE_MASK) >> GPIO_PIN10_SOURCE_LSB)
+#define GPIO_PIN10_SOURCE_SET(x) (((x) << GPIO_PIN10_SOURCE_LSB) & GPIO_PIN10_SOURCE_MASK)
+
+#define GPIO_PIN11_ADDRESS 0x00000054
+#define GPIO_PIN11_OFFSET 0x00000054
+#define GPIO_PIN11_CONFIG_MSB 12
+#define GPIO_PIN11_CONFIG_LSB 11
+#define GPIO_PIN11_CONFIG_MASK 0x00001800
+#define GPIO_PIN11_CONFIG_GET(x) (((x) & GPIO_PIN11_CONFIG_MASK) >> GPIO_PIN11_CONFIG_LSB)
+#define GPIO_PIN11_CONFIG_SET(x) (((x) << GPIO_PIN11_CONFIG_LSB) & GPIO_PIN11_CONFIG_MASK)
+#define GPIO_PIN11_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN11_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN11_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN11_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN11_WAKEUP_ENABLE_MASK) >> GPIO_PIN11_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN11_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN11_WAKEUP_ENABLE_LSB) & GPIO_PIN11_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN11_INT_TYPE_MSB 9
+#define GPIO_PIN11_INT_TYPE_LSB 7
+#define GPIO_PIN11_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN11_INT_TYPE_GET(x) (((x) & GPIO_PIN11_INT_TYPE_MASK) >> GPIO_PIN11_INT_TYPE_LSB)
+#define GPIO_PIN11_INT_TYPE_SET(x) (((x) << GPIO_PIN11_INT_TYPE_LSB) & GPIO_PIN11_INT_TYPE_MASK)
+#define GPIO_PIN11_PAD_DRIVER_MSB 2
+#define GPIO_PIN11_PAD_DRIVER_LSB 2
+#define GPIO_PIN11_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN11_PAD_DRIVER_GET(x) (((x) & GPIO_PIN11_PAD_DRIVER_MASK) >> GPIO_PIN11_PAD_DRIVER_LSB)
+#define GPIO_PIN11_PAD_DRIVER_SET(x) (((x) << GPIO_PIN11_PAD_DRIVER_LSB) & GPIO_PIN11_PAD_DRIVER_MASK)
+#define GPIO_PIN11_SOURCE_MSB 0
+#define GPIO_PIN11_SOURCE_LSB 0
+#define GPIO_PIN11_SOURCE_MASK 0x00000001
+#define GPIO_PIN11_SOURCE_GET(x) (((x) & GPIO_PIN11_SOURCE_MASK) >> GPIO_PIN11_SOURCE_LSB)
+#define GPIO_PIN11_SOURCE_SET(x) (((x) << GPIO_PIN11_SOURCE_LSB) & GPIO_PIN11_SOURCE_MASK)
+
+#define GPIO_PIN12_ADDRESS 0x00000058
+#define GPIO_PIN12_OFFSET 0x00000058
+#define GPIO_PIN12_CONFIG_MSB 12
+#define GPIO_PIN12_CONFIG_LSB 11
+#define GPIO_PIN12_CONFIG_MASK 0x00001800
+#define GPIO_PIN12_CONFIG_GET(x) (((x) & GPIO_PIN12_CONFIG_MASK) >> GPIO_PIN12_CONFIG_LSB)
+#define GPIO_PIN12_CONFIG_SET(x) (((x) << GPIO_PIN12_CONFIG_LSB) & GPIO_PIN12_CONFIG_MASK)
+#define GPIO_PIN12_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN12_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN12_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN12_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN12_WAKEUP_ENABLE_MASK) >> GPIO_PIN12_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN12_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN12_WAKEUP_ENABLE_LSB) & GPIO_PIN12_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN12_INT_TYPE_MSB 9
+#define GPIO_PIN12_INT_TYPE_LSB 7
+#define GPIO_PIN12_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN12_INT_TYPE_GET(x) (((x) & GPIO_PIN12_INT_TYPE_MASK) >> GPIO_PIN12_INT_TYPE_LSB)
+#define GPIO_PIN12_INT_TYPE_SET(x) (((x) << GPIO_PIN12_INT_TYPE_LSB) & GPIO_PIN12_INT_TYPE_MASK)
+#define GPIO_PIN12_PAD_DRIVER_MSB 2
+#define GPIO_PIN12_PAD_DRIVER_LSB 2
+#define GPIO_PIN12_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN12_PAD_DRIVER_GET(x) (((x) & GPIO_PIN12_PAD_DRIVER_MASK) >> GPIO_PIN12_PAD_DRIVER_LSB)
+#define GPIO_PIN12_PAD_DRIVER_SET(x) (((x) << GPIO_PIN12_PAD_DRIVER_LSB) & GPIO_PIN12_PAD_DRIVER_MASK)
+#define GPIO_PIN12_SOURCE_MSB 0
+#define GPIO_PIN12_SOURCE_LSB 0
+#define GPIO_PIN12_SOURCE_MASK 0x00000001
+#define GPIO_PIN12_SOURCE_GET(x) (((x) & GPIO_PIN12_SOURCE_MASK) >> GPIO_PIN12_SOURCE_LSB)
+#define GPIO_PIN12_SOURCE_SET(x) (((x) << GPIO_PIN12_SOURCE_LSB) & GPIO_PIN12_SOURCE_MASK)
+
+#define GPIO_PIN13_ADDRESS 0x0000005c
+#define GPIO_PIN13_OFFSET 0x0000005c
+#define GPIO_PIN13_CONFIG_MSB 12
+#define GPIO_PIN13_CONFIG_LSB 11
+#define GPIO_PIN13_CONFIG_MASK 0x00001800
+#define GPIO_PIN13_CONFIG_GET(x) (((x) & GPIO_PIN13_CONFIG_MASK) >> GPIO_PIN13_CONFIG_LSB)
+#define GPIO_PIN13_CONFIG_SET(x) (((x) << GPIO_PIN13_CONFIG_LSB) & GPIO_PIN13_CONFIG_MASK)
+#define GPIO_PIN13_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN13_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN13_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN13_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN13_WAKEUP_ENABLE_MASK) >> GPIO_PIN13_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN13_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN13_WAKEUP_ENABLE_LSB) & GPIO_PIN13_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN13_INT_TYPE_MSB 9
+#define GPIO_PIN13_INT_TYPE_LSB 7
+#define GPIO_PIN13_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN13_INT_TYPE_GET(x) (((x) & GPIO_PIN13_INT_TYPE_MASK) >> GPIO_PIN13_INT_TYPE_LSB)
+#define GPIO_PIN13_INT_TYPE_SET(x) (((x) << GPIO_PIN13_INT_TYPE_LSB) & GPIO_PIN13_INT_TYPE_MASK)
+#define GPIO_PIN13_PAD_DRIVER_MSB 2
+#define GPIO_PIN13_PAD_DRIVER_LSB 2
+#define GPIO_PIN13_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN13_PAD_DRIVER_GET(x) (((x) & GPIO_PIN13_PAD_DRIVER_MASK) >> GPIO_PIN13_PAD_DRIVER_LSB)
+#define GPIO_PIN13_PAD_DRIVER_SET(x) (((x) << GPIO_PIN13_PAD_DRIVER_LSB) & GPIO_PIN13_PAD_DRIVER_MASK)
+#define GPIO_PIN13_SOURCE_MSB 0
+#define GPIO_PIN13_SOURCE_LSB 0
+#define GPIO_PIN13_SOURCE_MASK 0x00000001
+#define GPIO_PIN13_SOURCE_GET(x) (((x) & GPIO_PIN13_SOURCE_MASK) >> GPIO_PIN13_SOURCE_LSB)
+#define GPIO_PIN13_SOURCE_SET(x) (((x) << GPIO_PIN13_SOURCE_LSB) & GPIO_PIN13_SOURCE_MASK)
+
+#define GPIO_PIN14_ADDRESS 0x00000060
+#define GPIO_PIN14_OFFSET 0x00000060
+#define GPIO_PIN14_CONFIG_MSB 12
+#define GPIO_PIN14_CONFIG_LSB 11
+#define GPIO_PIN14_CONFIG_MASK 0x00001800
+#define GPIO_PIN14_CONFIG_GET(x) (((x) & GPIO_PIN14_CONFIG_MASK) >> GPIO_PIN14_CONFIG_LSB)
+#define GPIO_PIN14_CONFIG_SET(x) (((x) << GPIO_PIN14_CONFIG_LSB) & GPIO_PIN14_CONFIG_MASK)
+#define GPIO_PIN14_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN14_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN14_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN14_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN14_WAKEUP_ENABLE_MASK) >> GPIO_PIN14_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN14_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN14_WAKEUP_ENABLE_LSB) & GPIO_PIN14_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN14_INT_TYPE_MSB 9
+#define GPIO_PIN14_INT_TYPE_LSB 7
+#define GPIO_PIN14_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN14_INT_TYPE_GET(x) (((x) & GPIO_PIN14_INT_TYPE_MASK) >> GPIO_PIN14_INT_TYPE_LSB)
+#define GPIO_PIN14_INT_TYPE_SET(x) (((x) << GPIO_PIN14_INT_TYPE_LSB) & GPIO_PIN14_INT_TYPE_MASK)
+#define GPIO_PIN14_PAD_DRIVER_MSB 2
+#define GPIO_PIN14_PAD_DRIVER_LSB 2
+#define GPIO_PIN14_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN14_PAD_DRIVER_GET(x) (((x) & GPIO_PIN14_PAD_DRIVER_MASK) >> GPIO_PIN14_PAD_DRIVER_LSB)
+#define GPIO_PIN14_PAD_DRIVER_SET(x) (((x) << GPIO_PIN14_PAD_DRIVER_LSB) & GPIO_PIN14_PAD_DRIVER_MASK)
+#define GPIO_PIN14_SOURCE_MSB 0
+#define GPIO_PIN14_SOURCE_LSB 0
+#define GPIO_PIN14_SOURCE_MASK 0x00000001
+#define GPIO_PIN14_SOURCE_GET(x) (((x) & GPIO_PIN14_SOURCE_MASK) >> GPIO_PIN14_SOURCE_LSB)
+#define GPIO_PIN14_SOURCE_SET(x) (((x) << GPIO_PIN14_SOURCE_LSB) & GPIO_PIN14_SOURCE_MASK)
+
+#define GPIO_PIN15_ADDRESS 0x00000064
+#define GPIO_PIN15_OFFSET 0x00000064
+#define GPIO_PIN15_CONFIG_MSB 12
+#define GPIO_PIN15_CONFIG_LSB 11
+#define GPIO_PIN15_CONFIG_MASK 0x00001800
+#define GPIO_PIN15_CONFIG_GET(x) (((x) & GPIO_PIN15_CONFIG_MASK) >> GPIO_PIN15_CONFIG_LSB)
+#define GPIO_PIN15_CONFIG_SET(x) (((x) << GPIO_PIN15_CONFIG_LSB) & GPIO_PIN15_CONFIG_MASK)
+#define GPIO_PIN15_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN15_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN15_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN15_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN15_WAKEUP_ENABLE_MASK) >> GPIO_PIN15_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN15_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN15_WAKEUP_ENABLE_LSB) & GPIO_PIN15_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN15_INT_TYPE_MSB 9
+#define GPIO_PIN15_INT_TYPE_LSB 7
+#define GPIO_PIN15_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN15_INT_TYPE_GET(x) (((x) & GPIO_PIN15_INT_TYPE_MASK) >> GPIO_PIN15_INT_TYPE_LSB)
+#define GPIO_PIN15_INT_TYPE_SET(x) (((x) << GPIO_PIN15_INT_TYPE_LSB) & GPIO_PIN15_INT_TYPE_MASK)
+#define GPIO_PIN15_PAD_DRIVER_MSB 2
+#define GPIO_PIN15_PAD_DRIVER_LSB 2
+#define GPIO_PIN15_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN15_PAD_DRIVER_GET(x) (((x) & GPIO_PIN15_PAD_DRIVER_MASK) >> GPIO_PIN15_PAD_DRIVER_LSB)
+#define GPIO_PIN15_PAD_DRIVER_SET(x) (((x) << GPIO_PIN15_PAD_DRIVER_LSB) & GPIO_PIN15_PAD_DRIVER_MASK)
+#define GPIO_PIN15_SOURCE_MSB 0
+#define GPIO_PIN15_SOURCE_LSB 0
+#define GPIO_PIN15_SOURCE_MASK 0x00000001
+#define GPIO_PIN15_SOURCE_GET(x) (((x) & GPIO_PIN15_SOURCE_MASK) >> GPIO_PIN15_SOURCE_LSB)
+#define GPIO_PIN15_SOURCE_SET(x) (((x) << GPIO_PIN15_SOURCE_LSB) & GPIO_PIN15_SOURCE_MASK)
+
+#define GPIO_PIN16_ADDRESS 0x00000068
+#define GPIO_PIN16_OFFSET 0x00000068
+#define GPIO_PIN16_CONFIG_MSB 12
+#define GPIO_PIN16_CONFIG_LSB 11
+#define GPIO_PIN16_CONFIG_MASK 0x00001800
+#define GPIO_PIN16_CONFIG_GET(x) (((x) & GPIO_PIN16_CONFIG_MASK) >> GPIO_PIN16_CONFIG_LSB)
+#define GPIO_PIN16_CONFIG_SET(x) (((x) << GPIO_PIN16_CONFIG_LSB) & GPIO_PIN16_CONFIG_MASK)
+#define GPIO_PIN16_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN16_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN16_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN16_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN16_WAKEUP_ENABLE_MASK) >> GPIO_PIN16_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN16_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN16_WAKEUP_ENABLE_LSB) & GPIO_PIN16_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN16_INT_TYPE_MSB 9
+#define GPIO_PIN16_INT_TYPE_LSB 7
+#define GPIO_PIN16_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN16_INT_TYPE_GET(x) (((x) & GPIO_PIN16_INT_TYPE_MASK) >> GPIO_PIN16_INT_TYPE_LSB)
+#define GPIO_PIN16_INT_TYPE_SET(x) (((x) << GPIO_PIN16_INT_TYPE_LSB) & GPIO_PIN16_INT_TYPE_MASK)
+#define GPIO_PIN16_PAD_DRIVER_MSB 2
+#define GPIO_PIN16_PAD_DRIVER_LSB 2
+#define GPIO_PIN16_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN16_PAD_DRIVER_GET(x) (((x) & GPIO_PIN16_PAD_DRIVER_MASK) >> GPIO_PIN16_PAD_DRIVER_LSB)
+#define GPIO_PIN16_PAD_DRIVER_SET(x) (((x) << GPIO_PIN16_PAD_DRIVER_LSB) & GPIO_PIN16_PAD_DRIVER_MASK)
+#define GPIO_PIN16_SOURCE_MSB 0
+#define GPIO_PIN16_SOURCE_LSB 0
+#define GPIO_PIN16_SOURCE_MASK 0x00000001
+#define GPIO_PIN16_SOURCE_GET(x) (((x) & GPIO_PIN16_SOURCE_MASK) >> GPIO_PIN16_SOURCE_LSB)
+#define GPIO_PIN16_SOURCE_SET(x) (((x) << GPIO_PIN16_SOURCE_LSB) & GPIO_PIN16_SOURCE_MASK)
+
+#define GPIO_PIN17_ADDRESS 0x0000006c
+#define GPIO_PIN17_OFFSET 0x0000006c
+#define GPIO_PIN17_CONFIG_MSB 12
+#define GPIO_PIN17_CONFIG_LSB 11
+#define GPIO_PIN17_CONFIG_MASK 0x00001800
+#define GPIO_PIN17_CONFIG_GET(x) (((x) & GPIO_PIN17_CONFIG_MASK) >> GPIO_PIN17_CONFIG_LSB)
+#define GPIO_PIN17_CONFIG_SET(x) (((x) << GPIO_PIN17_CONFIG_LSB) & GPIO_PIN17_CONFIG_MASK)
+#define GPIO_PIN17_WAKEUP_ENABLE_MSB 10
+#define GPIO_PIN17_WAKEUP_ENABLE_LSB 10
+#define GPIO_PIN17_WAKEUP_ENABLE_MASK 0x00000400
+#define GPIO_PIN17_WAKEUP_ENABLE_GET(x) (((x) & GPIO_PIN17_WAKEUP_ENABLE_MASK) >> GPIO_PIN17_WAKEUP_ENABLE_LSB)
+#define GPIO_PIN17_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN17_WAKEUP_ENABLE_LSB) & GPIO_PIN17_WAKEUP_ENABLE_MASK)
+#define GPIO_PIN17_INT_TYPE_MSB 9
+#define GPIO_PIN17_INT_TYPE_LSB 7
+#define GPIO_PIN17_INT_TYPE_MASK 0x00000380
+#define GPIO_PIN17_INT_TYPE_GET(x) (((x) & GPIO_PIN17_INT_TYPE_MASK) >> GPIO_PIN17_INT_TYPE_LSB)
+#define GPIO_PIN17_INT_TYPE_SET(x) (((x) << GPIO_PIN17_INT_TYPE_LSB) & GPIO_PIN17_INT_TYPE_MASK)
+#define GPIO_PIN17_PAD_DRIVER_MSB 2
+#define GPIO_PIN17_PAD_DRIVER_LSB 2
+#define GPIO_PIN17_PAD_DRIVER_MASK 0x00000004
+#define GPIO_PIN17_PAD_DRIVER_GET(x) (((x) & GPIO_PIN17_PAD_DRIVER_MASK) >> GPIO_PIN17_PAD_DRIVER_LSB)
+#define GPIO_PIN17_PAD_DRIVER_SET(x) (((x) << GPIO_PIN17_PAD_DRIVER_LSB) & GPIO_PIN17_PAD_DRIVER_MASK)
+#define GPIO_PIN17_SOURCE_MSB 0
+#define GPIO_PIN17_SOURCE_LSB 0
+#define GPIO_PIN17_SOURCE_MASK 0x00000001
+#define GPIO_PIN17_SOURCE_GET(x) (((x) & GPIO_PIN17_SOURCE_MASK) >> GPIO_PIN17_SOURCE_LSB)
+#define GPIO_PIN17_SOURCE_SET(x) (((x) << GPIO_PIN17_SOURCE_LSB) & GPIO_PIN17_SOURCE_MASK)
+
+#define SDIO_PIN_ADDRESS 0x00000070
+#define SDIO_PIN_OFFSET 0x00000070
+#define SDIO_PIN_PAD_PULL_MSB 3
+#define SDIO_PIN_PAD_PULL_LSB 2
+#define SDIO_PIN_PAD_PULL_MASK 0x0000000c
+#define SDIO_PIN_PAD_PULL_GET(x) (((x) & SDIO_PIN_PAD_PULL_MASK) >> SDIO_PIN_PAD_PULL_LSB)
+#define SDIO_PIN_PAD_PULL_SET(x) (((x) << SDIO_PIN_PAD_PULL_LSB) & SDIO_PIN_PAD_PULL_MASK)
+#define SDIO_PIN_PAD_STRENGTH_MSB 1
+#define SDIO_PIN_PAD_STRENGTH_LSB 0
+#define SDIO_PIN_PAD_STRENGTH_MASK 0x00000003
+#define SDIO_PIN_PAD_STRENGTH_GET(x) (((x) & SDIO_PIN_PAD_STRENGTH_MASK) >> SDIO_PIN_PAD_STRENGTH_LSB)
+#define SDIO_PIN_PAD_STRENGTH_SET(x) (((x) << SDIO_PIN_PAD_STRENGTH_LSB) & SDIO_PIN_PAD_STRENGTH_MASK)
+
+#define CLK_REQ_PIN_ADDRESS 0x00000074
+#define CLK_REQ_PIN_OFFSET 0x00000074
+#define CLK_REQ_PIN_ATE_OE_L_MSB 4
+#define CLK_REQ_PIN_ATE_OE_L_LSB 4
+#define CLK_REQ_PIN_ATE_OE_L_MASK 0x00000010
+#define CLK_REQ_PIN_ATE_OE_L_GET(x) (((x) & CLK_REQ_PIN_ATE_OE_L_MASK) >> CLK_REQ_PIN_ATE_OE_L_LSB)
+#define CLK_REQ_PIN_ATE_OE_L_SET(x) (((x) << CLK_REQ_PIN_ATE_OE_L_LSB) & CLK_REQ_PIN_ATE_OE_L_MASK)
+#define CLK_REQ_PIN_PAD_PULL_MSB 3
+#define CLK_REQ_PIN_PAD_PULL_LSB 2
+#define CLK_REQ_PIN_PAD_PULL_MASK 0x0000000c
+#define CLK_REQ_PIN_PAD_PULL_GET(x) (((x) & CLK_REQ_PIN_PAD_PULL_MASK) >> CLK_REQ_PIN_PAD_PULL_LSB)
+#define CLK_REQ_PIN_PAD_PULL_SET(x) (((x) << CLK_REQ_PIN_PAD_PULL_LSB) & CLK_REQ_PIN_PAD_PULL_MASK)
+#define CLK_REQ_PIN_PAD_STRENGTH_MSB 1
+#define CLK_REQ_PIN_PAD_STRENGTH_LSB 0
+#define CLK_REQ_PIN_PAD_STRENGTH_MASK 0x00000003
+#define CLK_REQ_PIN_PAD_STRENGTH_GET(x) (((x) & CLK_REQ_PIN_PAD_STRENGTH_MASK) >> CLK_REQ_PIN_PAD_STRENGTH_LSB)
+#define CLK_REQ_PIN_PAD_STRENGTH_SET(x) (((x) << CLK_REQ_PIN_PAD_STRENGTH_LSB) & CLK_REQ_PIN_PAD_STRENGTH_MASK)
+
+#define SIGMA_DELTA_ADDRESS 0x00000078
+#define SIGMA_DELTA_OFFSET 0x00000078
+#define SIGMA_DELTA_ENABLE_MSB 16
+#define SIGMA_DELTA_ENABLE_LSB 16
+#define SIGMA_DELTA_ENABLE_MASK 0x00010000
+#define SIGMA_DELTA_ENABLE_GET(x) (((x) & SIGMA_DELTA_ENABLE_MASK) >> SIGMA_DELTA_ENABLE_LSB)
+#define SIGMA_DELTA_ENABLE_SET(x) (((x) << SIGMA_DELTA_ENABLE_LSB) & SIGMA_DELTA_ENABLE_MASK)
+#define SIGMA_DELTA_PRESCALAR_MSB 15
+#define SIGMA_DELTA_PRESCALAR_LSB 8
+#define SIGMA_DELTA_PRESCALAR_MASK 0x0000ff00
+#define SIGMA_DELTA_PRESCALAR_GET(x) (((x) & SIGMA_DELTA_PRESCALAR_MASK) >> SIGMA_DELTA_PRESCALAR_LSB)
+#define SIGMA_DELTA_PRESCALAR_SET(x) (((x) << SIGMA_DELTA_PRESCALAR_LSB) & SIGMA_DELTA_PRESCALAR_MASK)
+#define SIGMA_DELTA_TARGET_MSB 7
+#define SIGMA_DELTA_TARGET_LSB 0
+#define SIGMA_DELTA_TARGET_MASK 0x000000ff
+#define SIGMA_DELTA_TARGET_GET(x) (((x) & SIGMA_DELTA_TARGET_MASK) >> SIGMA_DELTA_TARGET_LSB)
+#define SIGMA_DELTA_TARGET_SET(x) (((x) << SIGMA_DELTA_TARGET_LSB) & SIGMA_DELTA_TARGET_MASK)
+
+#define DEBUG_CONTROL_ADDRESS 0x0000007c
+#define DEBUG_CONTROL_OFFSET 0x0000007c
+#define DEBUG_CONTROL_OBS_OE_L_MSB 1
+#define DEBUG_CONTROL_OBS_OE_L_LSB 1
+#define DEBUG_CONTROL_OBS_OE_L_MASK 0x00000002
+#define DEBUG_CONTROL_OBS_OE_L_GET(x) (((x) & DEBUG_CONTROL_OBS_OE_L_MASK) >> DEBUG_CONTROL_OBS_OE_L_LSB)
+#define DEBUG_CONTROL_OBS_OE_L_SET(x) (((x) << DEBUG_CONTROL_OBS_OE_L_LSB) & DEBUG_CONTROL_OBS_OE_L_MASK)
+#define DEBUG_CONTROL_ENABLE_MSB 0
+#define DEBUG_CONTROL_ENABLE_LSB 0
+#define DEBUG_CONTROL_ENABLE_MASK 0x00000001
+#define DEBUG_CONTROL_ENABLE_GET(x) (((x) & DEBUG_CONTROL_ENABLE_MASK) >> DEBUG_CONTROL_ENABLE_LSB)
+#define DEBUG_CONTROL_ENABLE_SET(x) (((x) << DEBUG_CONTROL_ENABLE_LSB) & DEBUG_CONTROL_ENABLE_MASK)
+
+#define DEBUG_INPUT_SEL_ADDRESS 0x00000080
+#define DEBUG_INPUT_SEL_OFFSET 0x00000080
+#define DEBUG_INPUT_SEL_SRC_MSB 3
+#define DEBUG_INPUT_SEL_SRC_LSB 0
+#define DEBUG_INPUT_SEL_SRC_MASK 0x0000000f
+#define DEBUG_INPUT_SEL_SRC_GET(x) (((x) & DEBUG_INPUT_SEL_SRC_MASK) >> DEBUG_INPUT_SEL_SRC_LSB)
+#define DEBUG_INPUT_SEL_SRC_SET(x) (((x) << DEBUG_INPUT_SEL_SRC_LSB) & DEBUG_INPUT_SEL_SRC_MASK)
+
+#define DEBUG_OUT_ADDRESS 0x00000084
+#define DEBUG_OUT_OFFSET 0x00000084
+#define DEBUG_OUT_DATA_MSB 17
+#define DEBUG_OUT_DATA_LSB 0
+#define DEBUG_OUT_DATA_MASK 0x0003ffff
+#define DEBUG_OUT_DATA_GET(x) (((x) & DEBUG_OUT_DATA_MASK) >> DEBUG_OUT_DATA_LSB)
+#define DEBUG_OUT_DATA_SET(x) (((x) << DEBUG_OUT_DATA_LSB) & DEBUG_OUT_DATA_MASK)
+
+#define LA_CONTROL_ADDRESS 0x00000088
+#define LA_CONTROL_OFFSET 0x00000088
+#define LA_CONTROL_RUN_MSB 1
+#define LA_CONTROL_RUN_LSB 1
+#define LA_CONTROL_RUN_MASK 0x00000002
+#define LA_CONTROL_RUN_GET(x) (((x) & LA_CONTROL_RUN_MASK) >> LA_CONTROL_RUN_LSB)
+#define LA_CONTROL_RUN_SET(x) (((x) << LA_CONTROL_RUN_LSB) & LA_CONTROL_RUN_MASK)
+#define LA_CONTROL_TRIGGERED_MSB 0
+#define LA_CONTROL_TRIGGERED_LSB 0
+#define LA_CONTROL_TRIGGERED_MASK 0x00000001
+#define LA_CONTROL_TRIGGERED_GET(x) (((x) & LA_CONTROL_TRIGGERED_MASK) >> LA_CONTROL_TRIGGERED_LSB)
+#define LA_CONTROL_TRIGGERED_SET(x) (((x) << LA_CONTROL_TRIGGERED_LSB) & LA_CONTROL_TRIGGERED_MASK)
+
+#define LA_CLOCK_ADDRESS 0x0000008c
+#define LA_CLOCK_OFFSET 0x0000008c
+#define LA_CLOCK_DIV_MSB 7
+#define LA_CLOCK_DIV_LSB 0
+#define LA_CLOCK_DIV_MASK 0x000000ff
+#define LA_CLOCK_DIV_GET(x) (((x) & LA_CLOCK_DIV_MASK) >> LA_CLOCK_DIV_LSB)
+#define LA_CLOCK_DIV_SET(x) (((x) << LA_CLOCK_DIV_LSB) & LA_CLOCK_DIV_MASK)
+
+#define LA_STATUS_ADDRESS 0x00000090
+#define LA_STATUS_OFFSET 0x00000090
+#define LA_STATUS_INTERRUPT_MSB 0
+#define LA_STATUS_INTERRUPT_LSB 0
+#define LA_STATUS_INTERRUPT_MASK 0x00000001
+#define LA_STATUS_INTERRUPT_GET(x) (((x) & LA_STATUS_INTERRUPT_MASK) >> LA_STATUS_INTERRUPT_LSB)
+#define LA_STATUS_INTERRUPT_SET(x) (((x) << LA_STATUS_INTERRUPT_LSB) & LA_STATUS_INTERRUPT_MASK)
+
+#define LA_TRIGGER_SAMPLE_ADDRESS 0x00000094
+#define LA_TRIGGER_SAMPLE_OFFSET 0x00000094
+#define LA_TRIGGER_SAMPLE_COUNT_MSB 15
+#define LA_TRIGGER_SAMPLE_COUNT_LSB 0
+#define LA_TRIGGER_SAMPLE_COUNT_MASK 0x0000ffff
+#define LA_TRIGGER_SAMPLE_COUNT_GET(x) (((x) & LA_TRIGGER_SAMPLE_COUNT_MASK) >> LA_TRIGGER_SAMPLE_COUNT_LSB)
+#define LA_TRIGGER_SAMPLE_COUNT_SET(x) (((x) << LA_TRIGGER_SAMPLE_COUNT_LSB) & LA_TRIGGER_SAMPLE_COUNT_MASK)
+
+#define LA_TRIGGER_POSITION_ADDRESS 0x00000098
+#define LA_TRIGGER_POSITION_OFFSET 0x00000098
+#define LA_TRIGGER_POSITION_VALUE_MSB 15
+#define LA_TRIGGER_POSITION_VALUE_LSB 0
+#define LA_TRIGGER_POSITION_VALUE_MASK 0x0000ffff
+#define LA_TRIGGER_POSITION_VALUE_GET(x) (((x) & LA_TRIGGER_POSITION_VALUE_MASK) >> LA_TRIGGER_POSITION_VALUE_LSB)
+#define LA_TRIGGER_POSITION_VALUE_SET(x) (((x) << LA_TRIGGER_POSITION_VALUE_LSB) & LA_TRIGGER_POSITION_VALUE_MASK)
+
+#define LA_PRE_TRIGGER_ADDRESS 0x0000009c
+#define LA_PRE_TRIGGER_OFFSET 0x0000009c
+#define LA_PRE_TRIGGER_COUNT_MSB 15
+#define LA_PRE_TRIGGER_COUNT_LSB 0
+#define LA_PRE_TRIGGER_COUNT_MASK 0x0000ffff
+#define LA_PRE_TRIGGER_COUNT_GET(x) (((x) & LA_PRE_TRIGGER_COUNT_MASK) >> LA_PRE_TRIGGER_COUNT_LSB)
+#define LA_PRE_TRIGGER_COUNT_SET(x) (((x) << LA_PRE_TRIGGER_COUNT_LSB) & LA_PRE_TRIGGER_COUNT_MASK)
+
+#define LA_POST_TRIGGER_ADDRESS 0x000000a0
+#define LA_POST_TRIGGER_OFFSET 0x000000a0
+#define LA_POST_TRIGGER_COUNT_MSB 15
+#define LA_POST_TRIGGER_COUNT_LSB 0
+#define LA_POST_TRIGGER_COUNT_MASK 0x0000ffff
+#define LA_POST_TRIGGER_COUNT_GET(x) (((x) & LA_POST_TRIGGER_COUNT_MASK) >> LA_POST_TRIGGER_COUNT_LSB)
+#define LA_POST_TRIGGER_COUNT_SET(x) (((x) << LA_POST_TRIGGER_COUNT_LSB) & LA_POST_TRIGGER_COUNT_MASK)
+
+#define LA_FILTER_CONTROL_ADDRESS 0x000000a4
+#define LA_FILTER_CONTROL_OFFSET 0x000000a4
+#define LA_FILTER_CONTROL_DELTA_MSB 0
+#define LA_FILTER_CONTROL_DELTA_LSB 0
+#define LA_FILTER_CONTROL_DELTA_MASK 0x00000001
+#define LA_FILTER_CONTROL_DELTA_GET(x) (((x) & LA_FILTER_CONTROL_DELTA_MASK) >> LA_FILTER_CONTROL_DELTA_LSB)
+#define LA_FILTER_CONTROL_DELTA_SET(x) (((x) << LA_FILTER_CONTROL_DELTA_LSB) & LA_FILTER_CONTROL_DELTA_MASK)
+
+#define LA_FILTER_DATA_ADDRESS 0x000000a8
+#define LA_FILTER_DATA_OFFSET 0x000000a8
+#define LA_FILTER_DATA_MATCH_MSB 17
+#define LA_FILTER_DATA_MATCH_LSB 0
+#define LA_FILTER_DATA_MATCH_MASK 0x0003ffff
+#define LA_FILTER_DATA_MATCH_GET(x) (((x) & LA_FILTER_DATA_MATCH_MASK) >> LA_FILTER_DATA_MATCH_LSB)
+#define LA_FILTER_DATA_MATCH_SET(x) (((x) << LA_FILTER_DATA_MATCH_LSB) & LA_FILTER_DATA_MATCH_MASK)
+
+#define LA_FILTER_WILDCARD_ADDRESS 0x000000ac
+#define LA_FILTER_WILDCARD_OFFSET 0x000000ac
+#define LA_FILTER_WILDCARD_MATCH_MSB 17
+#define LA_FILTER_WILDCARD_MATCH_LSB 0
+#define LA_FILTER_WILDCARD_MATCH_MASK 0x0003ffff
+#define LA_FILTER_WILDCARD_MATCH_GET(x) (((x) & LA_FILTER_WILDCARD_MATCH_MASK) >> LA_FILTER_WILDCARD_MATCH_LSB)
+#define LA_FILTER_WILDCARD_MATCH_SET(x) (((x) << LA_FILTER_WILDCARD_MATCH_LSB) & LA_FILTER_WILDCARD_MATCH_MASK)
+
+#define LA_TRIGGERA_DATA_ADDRESS 0x000000b0
+#define LA_TRIGGERA_DATA_OFFSET 0x000000b0
+#define LA_TRIGGERA_DATA_MATCH_MSB 17
+#define LA_TRIGGERA_DATA_MATCH_LSB 0
+#define LA_TRIGGERA_DATA_MATCH_MASK 0x0003ffff
+#define LA_TRIGGERA_DATA_MATCH_GET(x) (((x) & LA_TRIGGERA_DATA_MATCH_MASK) >> LA_TRIGGERA_DATA_MATCH_LSB)
+#define LA_TRIGGERA_DATA_MATCH_SET(x) (((x) << LA_TRIGGERA_DATA_MATCH_LSB) & LA_TRIGGERA_DATA_MATCH_MASK)
+
+#define LA_TRIGGERA_WILDCARD_ADDRESS 0x000000b4
+#define LA_TRIGGERA_WILDCARD_OFFSET 0x000000b4
+#define LA_TRIGGERA_WILDCARD_MATCH_MSB 17
+#define LA_TRIGGERA_WILDCARD_MATCH_LSB 0
+#define LA_TRIGGERA_WILDCARD_MATCH_MASK 0x0003ffff
+#define LA_TRIGGERA_WILDCARD_MATCH_GET(x) (((x) & LA_TRIGGERA_WILDCARD_MATCH_MASK) >> LA_TRIGGERA_WILDCARD_MATCH_LSB)
+#define LA_TRIGGERA_WILDCARD_MATCH_SET(x) (((x) << LA_TRIGGERA_WILDCARD_MATCH_LSB) & LA_TRIGGERA_WILDCARD_MATCH_MASK)
+
+#define LA_TRIGGERB_DATA_ADDRESS 0x000000b8
+#define LA_TRIGGERB_DATA_OFFSET 0x000000b8
+#define LA_TRIGGERB_DATA_MATCH_MSB 17
+#define LA_TRIGGERB_DATA_MATCH_LSB 0
+#define LA_TRIGGERB_DATA_MATCH_MASK 0x0003ffff
+#define LA_TRIGGERB_DATA_MATCH_GET(x) (((x) & LA_TRIGGERB_DATA_MATCH_MASK) >> LA_TRIGGERB_DATA_MATCH_LSB)
+#define LA_TRIGGERB_DATA_MATCH_SET(x) (((x) << LA_TRIGGERB_DATA_MATCH_LSB) & LA_TRIGGERB_DATA_MATCH_MASK)
+
+#define LA_TRIGGERB_WILDCARD_ADDRESS 0x000000bc
+#define LA_TRIGGERB_WILDCARD_OFFSET 0x000000bc
+#define LA_TRIGGERB_WILDCARD_MATCH_MSB 17
+#define LA_TRIGGERB_WILDCARD_MATCH_LSB 0
+#define LA_TRIGGERB_WILDCARD_MATCH_MASK 0x0003ffff
+#define LA_TRIGGERB_WILDCARD_MATCH_GET(x) (((x) & LA_TRIGGERB_WILDCARD_MATCH_MASK) >> LA_TRIGGERB_WILDCARD_MATCH_LSB)
+#define LA_TRIGGERB_WILDCARD_MATCH_SET(x) (((x) << LA_TRIGGERB_WILDCARD_MATCH_LSB) & LA_TRIGGERB_WILDCARD_MATCH_MASK)
+
+#define LA_TRIGGER_ADDRESS 0x000000c0
+#define LA_TRIGGER_OFFSET 0x000000c0
+#define LA_TRIGGER_EVENT_MSB 2
+#define LA_TRIGGER_EVENT_LSB 0
+#define LA_TRIGGER_EVENT_MASK 0x00000007
+#define LA_TRIGGER_EVENT_GET(x) (((x) & LA_TRIGGER_EVENT_MASK) >> LA_TRIGGER_EVENT_LSB)
+#define LA_TRIGGER_EVENT_SET(x) (((x) << LA_TRIGGER_EVENT_LSB) & LA_TRIGGER_EVENT_MASK)
+
+#define LA_FIFO_ADDRESS 0x000000c4
+#define LA_FIFO_OFFSET 0x000000c4
+#define LA_FIFO_FULL_MSB 1
+#define LA_FIFO_FULL_LSB 1
+#define LA_FIFO_FULL_MASK 0x00000002
+#define LA_FIFO_FULL_GET(x) (((x) & LA_FIFO_FULL_MASK) >> LA_FIFO_FULL_LSB)
+#define LA_FIFO_FULL_SET(x) (((x) << LA_FIFO_FULL_LSB) & LA_FIFO_FULL_MASK)
+#define LA_FIFO_EMPTY_MSB 0
+#define LA_FIFO_EMPTY_LSB 0
+#define LA_FIFO_EMPTY_MASK 0x00000001
+#define LA_FIFO_EMPTY_GET(x) (((x) & LA_FIFO_EMPTY_MASK) >> LA_FIFO_EMPTY_LSB)
+#define LA_FIFO_EMPTY_SET(x) (((x) << LA_FIFO_EMPTY_LSB) & LA_FIFO_EMPTY_MASK)
+
+#define LA_ADDRESS 0x000000c8
+#define LA_OFFSET 0x000000c8
+#define LA_DATA_MSB 17
+#define LA_DATA_LSB 0
+#define LA_DATA_MASK 0x0003ffff
+#define LA_DATA_GET(x) (((x) & LA_DATA_MASK) >> LA_DATA_LSB)
+#define LA_DATA_SET(x) (((x) << LA_DATA_LSB) & LA_DATA_MASK)
+
+#define ANT_PIN_ADDRESS 0x000000d0
+#define ANT_PIN_OFFSET 0x000000d0
+#define ANT_PIN_PAD_PULL_MSB 3
+#define ANT_PIN_PAD_PULL_LSB 2
+#define ANT_PIN_PAD_PULL_MASK 0x0000000c
+#define ANT_PIN_PAD_PULL_GET(x) (((x) & ANT_PIN_PAD_PULL_MASK) >> ANT_PIN_PAD_PULL_LSB)
+#define ANT_PIN_PAD_PULL_SET(x) (((x) << ANT_PIN_PAD_PULL_LSB) & ANT_PIN_PAD_PULL_MASK)
+#define ANT_PIN_PAD_STRENGTH_MSB 1
+#define ANT_PIN_PAD_STRENGTH_LSB 0
+#define ANT_PIN_PAD_STRENGTH_MASK 0x00000003
+#define ANT_PIN_PAD_STRENGTH_GET(x) (((x) & ANT_PIN_PAD_STRENGTH_MASK) >> ANT_PIN_PAD_STRENGTH_LSB)
+#define ANT_PIN_PAD_STRENGTH_SET(x) (((x) << ANT_PIN_PAD_STRENGTH_LSB) & ANT_PIN_PAD_STRENGTH_MASK)
+
+#define ANTD_PIN_ADDRESS 0x000000d4
+#define ANTD_PIN_OFFSET 0x000000d4
+#define ANTD_PIN_PAD_PULL_MSB 1
+#define ANTD_PIN_PAD_PULL_LSB 0
+#define ANTD_PIN_PAD_PULL_MASK 0x00000003
+#define ANTD_PIN_PAD_PULL_GET(x) (((x) & ANTD_PIN_PAD_PULL_MASK) >> ANTD_PIN_PAD_PULL_LSB)
+#define ANTD_PIN_PAD_PULL_SET(x) (((x) << ANTD_PIN_PAD_PULL_LSB) & ANTD_PIN_PAD_PULL_MASK)
+
+#define GPIO_PIN_ADDRESS 0x000000d8
+#define GPIO_PIN_OFFSET 0x000000d8
+#define GPIO_PIN_PAD_PULL_MSB 3
+#define GPIO_PIN_PAD_PULL_LSB 2
+#define GPIO_PIN_PAD_PULL_MASK 0x0000000c
+#define GPIO_PIN_PAD_PULL_GET(x) (((x) & GPIO_PIN_PAD_PULL_MASK) >> GPIO_PIN_PAD_PULL_LSB)
+#define GPIO_PIN_PAD_PULL_SET(x) (((x) << GPIO_PIN_PAD_PULL_LSB) & GPIO_PIN_PAD_PULL_MASK)
+#define GPIO_PIN_PAD_STRENGTH_MSB 1
+#define GPIO_PIN_PAD_STRENGTH_LSB 0
+#define GPIO_PIN_PAD_STRENGTH_MASK 0x00000003
+#define GPIO_PIN_PAD_STRENGTH_GET(x) (((x) & GPIO_PIN_PAD_STRENGTH_MASK) >> GPIO_PIN_PAD_STRENGTH_LSB)
+#define GPIO_PIN_PAD_STRENGTH_SET(x) (((x) << GPIO_PIN_PAD_STRENGTH_LSB) & GPIO_PIN_PAD_STRENGTH_MASK)
+
+#define GPIO_H_PIN_ADDRESS 0x000000dc
+#define GPIO_H_PIN_OFFSET 0x000000dc
+#define GPIO_H_PIN_PAD_PULL_MSB 1
+#define GPIO_H_PIN_PAD_PULL_LSB 0
+#define GPIO_H_PIN_PAD_PULL_MASK 0x00000003
+#define GPIO_H_PIN_PAD_PULL_GET(x) (((x) & GPIO_H_PIN_PAD_PULL_MASK) >> GPIO_H_PIN_PAD_PULL_LSB)
+#define GPIO_H_PIN_PAD_PULL_SET(x) (((x) << GPIO_H_PIN_PAD_PULL_LSB) & GPIO_H_PIN_PAD_PULL_MASK)
+
+#define BT_PIN_ADDRESS 0x000000e0
+#define BT_PIN_OFFSET 0x000000e0
+#define BT_PIN_PAD_PULL_MSB 3
+#define BT_PIN_PAD_PULL_LSB 2
+#define BT_PIN_PAD_PULL_MASK 0x0000000c
+#define BT_PIN_PAD_PULL_GET(x) (((x) & BT_PIN_PAD_PULL_MASK) >> BT_PIN_PAD_PULL_LSB)
+#define BT_PIN_PAD_PULL_SET(x) (((x) << BT_PIN_PAD_PULL_LSB) & BT_PIN_PAD_PULL_MASK)
+#define BT_PIN_PAD_STRENGTH_MSB 1
+#define BT_PIN_PAD_STRENGTH_LSB 0
+#define BT_PIN_PAD_STRENGTH_MASK 0x00000003
+#define BT_PIN_PAD_STRENGTH_GET(x) (((x) & BT_PIN_PAD_STRENGTH_MASK) >> BT_PIN_PAD_STRENGTH_LSB)
+#define BT_PIN_PAD_STRENGTH_SET(x) (((x) << BT_PIN_PAD_STRENGTH_LSB) & BT_PIN_PAD_STRENGTH_MASK)
+
+#define BT_WLAN_PIN_ADDRESS 0x000000e4
+#define BT_WLAN_PIN_OFFSET 0x000000e4
+#define BT_WLAN_PIN_PAD_PULL_MSB 1
+#define BT_WLAN_PIN_PAD_PULL_LSB 0
+#define BT_WLAN_PIN_PAD_PULL_MASK 0x00000003
+#define BT_WLAN_PIN_PAD_PULL_GET(x) (((x) & BT_WLAN_PIN_PAD_PULL_MASK) >> BT_WLAN_PIN_PAD_PULL_LSB)
+#define BT_WLAN_PIN_PAD_PULL_SET(x) (((x) << BT_WLAN_PIN_PAD_PULL_LSB) & BT_WLAN_PIN_PAD_PULL_MASK)
+
+#define SI_UART_PIN_ADDRESS 0x000000e8
+#define SI_UART_PIN_OFFSET 0x000000e8
+#define SI_UART_PIN_PAD_PULL_MSB 3
+#define SI_UART_PIN_PAD_PULL_LSB 2
+#define SI_UART_PIN_PAD_PULL_MASK 0x0000000c
+#define SI_UART_PIN_PAD_PULL_GET(x) (((x) & SI_UART_PIN_PAD_PULL_MASK) >> SI_UART_PIN_PAD_PULL_LSB)
+#define SI_UART_PIN_PAD_PULL_SET(x) (((x) << SI_UART_PIN_PAD_PULL_LSB) & SI_UART_PIN_PAD_PULL_MASK)
+#define SI_UART_PIN_PAD_STRENGTH_MSB 1
+#define SI_UART_PIN_PAD_STRENGTH_LSB 0
+#define SI_UART_PIN_PAD_STRENGTH_MASK 0x00000003
+#define SI_UART_PIN_PAD_STRENGTH_GET(x) (((x) & SI_UART_PIN_PAD_STRENGTH_MASK) >> SI_UART_PIN_PAD_STRENGTH_LSB)
+#define SI_UART_PIN_PAD_STRENGTH_SET(x) (((x) << SI_UART_PIN_PAD_STRENGTH_LSB) & SI_UART_PIN_PAD_STRENGTH_MASK)
+
+#define CLK32K_PIN_ADDRESS 0x000000ec
+#define CLK32K_PIN_OFFSET 0x000000ec
+#define CLK32K_PIN_PAD_PULL_MSB 1
+#define CLK32K_PIN_PAD_PULL_LSB 0
+#define CLK32K_PIN_PAD_PULL_MASK 0x00000003
+#define CLK32K_PIN_PAD_PULL_GET(x) (((x) & CLK32K_PIN_PAD_PULL_MASK) >> CLK32K_PIN_PAD_PULL_LSB)
+#define CLK32K_PIN_PAD_PULL_SET(x) (((x) << CLK32K_PIN_PAD_PULL_LSB) & CLK32K_PIN_PAD_PULL_MASK)
+
+#define RESET_TUPLE_STATUS_ADDRESS 0x000000f0
+#define RESET_TUPLE_STATUS_OFFSET 0x000000f0
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB 11
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB 8
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK 0x00000f00
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) (((x) & RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB)
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) (((x) << RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK)
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB 7
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB 0
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK 0x000000ff
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) (((x) & RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB)
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) (((x) << RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct gpio_reg_reg_s {
+ volatile unsigned int gpio_out;
+ volatile unsigned int gpio_out_w1ts;
+ volatile unsigned int gpio_out_w1tc;
+ volatile unsigned int gpio_enable;
+ volatile unsigned int gpio_enable_w1ts;
+ volatile unsigned int gpio_enable_w1tc;
+ volatile unsigned int gpio_in;
+ volatile unsigned int gpio_status;
+ volatile unsigned int gpio_status_w1ts;
+ volatile unsigned int gpio_status_w1tc;
+ volatile unsigned int gpio_pin0;
+ volatile unsigned int gpio_pin1;
+ volatile unsigned int gpio_pin2;
+ volatile unsigned int gpio_pin3;
+ volatile unsigned int gpio_pin4;
+ volatile unsigned int gpio_pin5;
+ volatile unsigned int gpio_pin6;
+ volatile unsigned int gpio_pin7;
+ volatile unsigned int gpio_pin8;
+ volatile unsigned int gpio_pin9;
+ volatile unsigned int gpio_pin10;
+ volatile unsigned int gpio_pin11;
+ volatile unsigned int gpio_pin12;
+ volatile unsigned int gpio_pin13;
+ volatile unsigned int gpio_pin14;
+ volatile unsigned int gpio_pin15;
+ volatile unsigned int gpio_pin16;
+ volatile unsigned int gpio_pin17;
+ volatile unsigned int sdio_pin;
+ volatile unsigned int clk_req_pin;
+ volatile unsigned int sigma_delta;
+ volatile unsigned int debug_control;
+ volatile unsigned int debug_input_sel;
+ volatile unsigned int debug_out;
+ volatile unsigned int la_control;
+ volatile unsigned int la_clock;
+ volatile unsigned int la_status;
+ volatile unsigned int la_trigger_sample;
+ volatile unsigned int la_trigger_position;
+ volatile unsigned int la_pre_trigger;
+ volatile unsigned int la_post_trigger;
+ volatile unsigned int la_filter_control;
+ volatile unsigned int la_filter_data;
+ volatile unsigned int la_filter_wildcard;
+ volatile unsigned int la_triggera_data;
+ volatile unsigned int la_triggera_wildcard;
+ volatile unsigned int la_triggerb_data;
+ volatile unsigned int la_triggerb_wildcard;
+ volatile unsigned int la_trigger;
+ volatile unsigned int la_fifo;
+ volatile unsigned int la[2];
+ volatile unsigned int ant_pin;
+ volatile unsigned int antd_pin;
+ volatile unsigned int gpio_pin;
+ volatile unsigned int gpio_h_pin;
+ volatile unsigned int bt_pin;
+ volatile unsigned int bt_wlan_pin;
+ volatile unsigned int si_uart_pin;
+ volatile unsigned int clk32k_pin;
+ volatile unsigned int reset_tuple_status;
+} gpio_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _GPIO_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h
new file mode 100644
index 000000000000..f836ae47a303
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h
@@ -0,0 +1,386 @@
+#ifndef _MBOX_HOST_REG_REG_H_
+#define _MBOX_HOST_REG_REG_H_
+
+#define HOST_INT_STATUS_ADDRESS 0x00000400
+#define HOST_INT_STATUS_OFFSET 0x00000400
+#define HOST_INT_STATUS_ERROR_MSB 7
+#define HOST_INT_STATUS_ERROR_LSB 7
+#define HOST_INT_STATUS_ERROR_MASK 0x00000080
+#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
+#define HOST_INT_STATUS_CPU_MSB 6
+#define HOST_INT_STATUS_CPU_LSB 6
+#define HOST_INT_STATUS_CPU_MASK 0x00000040
+#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
+#define HOST_INT_STATUS_DRAGON_INT_MSB 5
+#define HOST_INT_STATUS_DRAGON_INT_LSB 5
+#define HOST_INT_STATUS_DRAGON_INT_MASK 0x00000020
+#define HOST_INT_STATUS_DRAGON_INT_GET(x) (((x) & HOST_INT_STATUS_DRAGON_INT_MASK) >> HOST_INT_STATUS_DRAGON_INT_LSB)
+#define HOST_INT_STATUS_DRAGON_INT_SET(x) (((x) << HOST_INT_STATUS_DRAGON_INT_LSB) & HOST_INT_STATUS_DRAGON_INT_MASK)
+#define HOST_INT_STATUS_COUNTER_MSB 4
+#define HOST_INT_STATUS_COUNTER_LSB 4
+#define HOST_INT_STATUS_COUNTER_MASK 0x00000010
+#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
+#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
+#define HOST_INT_STATUS_MBOX_DATA_MSB 3
+#define HOST_INT_STATUS_MBOX_DATA_LSB 0
+#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f
+#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
+#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ADDRESS 0x00000401
+#define CPU_INT_STATUS_OFFSET 0x00000401
+#define CPU_INT_STATUS_BIT_MSB 7
+#define CPU_INT_STATUS_BIT_LSB 0
+#define CPU_INT_STATUS_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_BIT_GET(x) (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
+#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
+
+#define ERROR_INT_STATUS_ADDRESS 0x00000402
+#define ERROR_INT_STATUS_OFFSET 0x00000402
+#define ERROR_INT_STATUS_SPI_MSB 3
+#define ERROR_INT_STATUS_SPI_LSB 3
+#define ERROR_INT_STATUS_SPI_MASK 0x00000008
+#define ERROR_INT_STATUS_SPI_GET(x) (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
+#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
+#define ERROR_INT_STATUS_WAKEUP_MSB 2
+#define ERROR_INT_STATUS_WAKEUP_LSB 2
+#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004
+#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ADDRESS 0x00000403
+#define COUNTER_INT_STATUS_OFFSET 0x00000403
+#define COUNTER_INT_STATUS_COUNTER_MSB 7
+#define COUNTER_INT_STATUS_COUNTER_LSB 0
+#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff
+#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
+#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
+
+#define MBOX_FRAME_ADDRESS 0x00000404
+#define MBOX_FRAME_OFFSET 0x00000404
+#define MBOX_FRAME_RX_EOM_MSB 7
+#define MBOX_FRAME_RX_EOM_LSB 4
+#define MBOX_FRAME_RX_EOM_MASK 0x000000f0
+#define MBOX_FRAME_RX_EOM_GET(x) (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
+#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
+#define MBOX_FRAME_RX_SOM_MSB 3
+#define MBOX_FRAME_RX_SOM_LSB 0
+#define MBOX_FRAME_RX_SOM_MASK 0x0000000f
+#define MBOX_FRAME_RX_SOM_GET(x) (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
+#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
+
+#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
+#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405
+#define RX_LOOKAHEAD_VALID_MBOX_MSB 3
+#define RX_LOOKAHEAD_VALID_MBOX_LSB 0
+#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f
+#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
+#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
+
+#define RX_LOOKAHEAD0_ADDRESS 0x00000408
+#define RX_LOOKAHEAD0_OFFSET 0x00000408
+#define RX_LOOKAHEAD0_DATA_MSB 7
+#define RX_LOOKAHEAD0_DATA_LSB 0
+#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD0_DATA_GET(x) (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
+#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
+
+#define RX_LOOKAHEAD1_ADDRESS 0x0000040c
+#define RX_LOOKAHEAD1_OFFSET 0x0000040c
+#define RX_LOOKAHEAD1_DATA_MSB 7
+#define RX_LOOKAHEAD1_DATA_LSB 0
+#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD1_DATA_GET(x) (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
+#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
+
+#define RX_LOOKAHEAD2_ADDRESS 0x00000410
+#define RX_LOOKAHEAD2_OFFSET 0x00000410
+#define RX_LOOKAHEAD2_DATA_MSB 7
+#define RX_LOOKAHEAD2_DATA_LSB 0
+#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD2_DATA_GET(x) (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
+#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
+
+#define RX_LOOKAHEAD3_ADDRESS 0x00000414
+#define RX_LOOKAHEAD3_OFFSET 0x00000414
+#define RX_LOOKAHEAD3_DATA_MSB 7
+#define RX_LOOKAHEAD3_DATA_LSB 0
+#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD3_DATA_GET(x) (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
+#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
+
+#define INT_STATUS_ENABLE_ADDRESS 0x00000418
+#define INT_STATUS_ENABLE_OFFSET 0x00000418
+#define INT_STATUS_ENABLE_ERROR_MSB 7
+#define INT_STATUS_ENABLE_ERROR_LSB 7
+#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080
+#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
+#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_MSB 6
+#define INT_STATUS_ENABLE_CPU_LSB 6
+#define INT_STATUS_ENABLE_CPU_MASK 0x00000040
+#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
+#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_DRAGON_INT_MSB 5
+#define INT_STATUS_ENABLE_DRAGON_INT_LSB 5
+#define INT_STATUS_ENABLE_DRAGON_INT_MASK 0x00000020
+#define INT_STATUS_ENABLE_DRAGON_INT_GET(x) (((x) & INT_STATUS_ENABLE_DRAGON_INT_MASK) >> INT_STATUS_ENABLE_DRAGON_INT_LSB)
+#define INT_STATUS_ENABLE_DRAGON_INT_SET(x) (((x) << INT_STATUS_ENABLE_DRAGON_INT_LSB) & INT_STATUS_ENABLE_DRAGON_INT_MASK)
+#define INT_STATUS_ENABLE_COUNTER_MSB 4
+#define INT_STATUS_ENABLE_COUNTER_LSB 4
+#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
+#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
+#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
+#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
+#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
+#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_MSB 7
+#define CPU_INT_STATUS_ENABLE_BIT_LSB 0
+#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
+#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
+
+#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
+#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a
+#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004
+#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
+#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
+#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+
+#define COUNT_ADDRESS 0x00000420
+#define COUNT_OFFSET 0x00000420
+#define COUNT_VALUE_MSB 7
+#define COUNT_VALUE_LSB 0
+#define COUNT_VALUE_MASK 0x000000ff
+#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
+#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
+
+#define COUNT_DEC_ADDRESS 0x00000440
+#define COUNT_DEC_OFFSET 0x00000440
+#define COUNT_DEC_VALUE_MSB 7
+#define COUNT_DEC_VALUE_LSB 0
+#define COUNT_DEC_VALUE_MASK 0x000000ff
+#define COUNT_DEC_VALUE_GET(x) (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
+#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
+
+#define SCRATCH_ADDRESS 0x00000460
+#define SCRATCH_OFFSET 0x00000460
+#define SCRATCH_VALUE_MSB 7
+#define SCRATCH_VALUE_LSB 0
+#define SCRATCH_VALUE_MASK 0x000000ff
+#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
+#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ADDRESS 0x00000468
+#define FIFO_TIMEOUT_OFFSET 0x00000468
+#define FIFO_TIMEOUT_VALUE_MSB 7
+#define FIFO_TIMEOUT_VALUE_LSB 0
+#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff
+#define FIFO_TIMEOUT_VALUE_GET(x) (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
+#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469
+#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469
+#define FIFO_TIMEOUT_ENABLE_SET_MSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_LSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001
+#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
+#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
+
+#define DISABLE_SLEEP_ADDRESS 0x0000046a
+#define DISABLE_SLEEP_OFFSET 0x0000046a
+#define DISABLE_SLEEP_FOR_INT_MSB 1
+#define DISABLE_SLEEP_FOR_INT_LSB 1
+#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002
+#define DISABLE_SLEEP_FOR_INT_GET(x) (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
+#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
+#define DISABLE_SLEEP_ON_MSB 0
+#define DISABLE_SLEEP_ON_LSB 0
+#define DISABLE_SLEEP_ON_MASK 0x00000001
+#define DISABLE_SLEEP_ON_GET(x) (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
+#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
+
+#define LOCAL_BUS_ADDRESS 0x00000470
+#define LOCAL_BUS_OFFSET 0x00000470
+#define LOCAL_BUS_STATE_MSB 1
+#define LOCAL_BUS_STATE_LSB 0
+#define LOCAL_BUS_STATE_MASK 0x00000003
+#define LOCAL_BUS_STATE_GET(x) (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
+#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
+
+#define INT_WLAN_ADDRESS 0x00000472
+#define INT_WLAN_OFFSET 0x00000472
+#define INT_WLAN_VECTOR_MSB 7
+#define INT_WLAN_VECTOR_LSB 0
+#define INT_WLAN_VECTOR_MASK 0x000000ff
+#define INT_WLAN_VECTOR_GET(x) (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
+#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
+
+#define WINDOW_DATA_ADDRESS 0x00000474
+#define WINDOW_DATA_OFFSET 0x00000474
+#define WINDOW_DATA_DATA_MSB 7
+#define WINDOW_DATA_DATA_LSB 0
+#define WINDOW_DATA_DATA_MASK 0x000000ff
+#define WINDOW_DATA_DATA_GET(x) (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
+#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
+
+#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
+#define WINDOW_WRITE_ADDR_OFFSET 0x00000478
+#define WINDOW_WRITE_ADDR_ADDR_MSB 7
+#define WINDOW_WRITE_ADDR_ADDR_LSB 0
+#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff
+#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
+#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
+
+#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
+#define WINDOW_READ_ADDR_OFFSET 0x0000047c
+#define WINDOW_READ_ADDR_ADDR_MSB 7
+#define WINDOW_READ_ADDR_ADDR_LSB 0
+#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff
+#define WINDOW_READ_ADDR_ADDR_GET(x) (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
+#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
+
+#define SPI_CONFIG_ADDRESS 0x00000480
+#define SPI_CONFIG_OFFSET 0x00000480
+#define SPI_CONFIG_SPI_RESET_MSB 4
+#define SPI_CONFIG_SPI_RESET_LSB 4
+#define SPI_CONFIG_SPI_RESET_MASK 0x00000010
+#define SPI_CONFIG_SPI_RESET_GET(x) (((x) & SPI_CONFIG_SPI_RESET_MASK) >> SPI_CONFIG_SPI_RESET_LSB)
+#define SPI_CONFIG_SPI_RESET_SET(x) (((x) << SPI_CONFIG_SPI_RESET_LSB) & SPI_CONFIG_SPI_RESET_MASK)
+#define SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
+#define SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
+#define SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
+#define SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> SPI_CONFIG_INTERRUPT_ENABLE_LSB)
+#define SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << SPI_CONFIG_INTERRUPT_ENABLE_LSB) & SPI_CONFIG_INTERRUPT_ENABLE_MASK)
+#define SPI_CONFIG_TEST_MODE_MSB 2
+#define SPI_CONFIG_TEST_MODE_LSB 2
+#define SPI_CONFIG_TEST_MODE_MASK 0x00000004
+#define SPI_CONFIG_TEST_MODE_GET(x) (((x) & SPI_CONFIG_TEST_MODE_MASK) >> SPI_CONFIG_TEST_MODE_LSB)
+#define SPI_CONFIG_TEST_MODE_SET(x) (((x) << SPI_CONFIG_TEST_MODE_LSB) & SPI_CONFIG_TEST_MODE_MASK)
+#define SPI_CONFIG_DATA_SIZE_MSB 1
+#define SPI_CONFIG_DATA_SIZE_LSB 0
+#define SPI_CONFIG_DATA_SIZE_MASK 0x00000003
+#define SPI_CONFIG_DATA_SIZE_GET(x) (((x) & SPI_CONFIG_DATA_SIZE_MASK) >> SPI_CONFIG_DATA_SIZE_LSB)
+#define SPI_CONFIG_DATA_SIZE_SET(x) (((x) << SPI_CONFIG_DATA_SIZE_LSB) & SPI_CONFIG_DATA_SIZE_MASK)
+
+#define SPI_STATUS_ADDRESS 0x00000481
+#define SPI_STATUS_OFFSET 0x00000481
+#define SPI_STATUS_ADDR_ERR_MSB 3
+#define SPI_STATUS_ADDR_ERR_LSB 3
+#define SPI_STATUS_ADDR_ERR_MASK 0x00000008
+#define SPI_STATUS_ADDR_ERR_GET(x) (((x) & SPI_STATUS_ADDR_ERR_MASK) >> SPI_STATUS_ADDR_ERR_LSB)
+#define SPI_STATUS_ADDR_ERR_SET(x) (((x) << SPI_STATUS_ADDR_ERR_LSB) & SPI_STATUS_ADDR_ERR_MASK)
+#define SPI_STATUS_RD_ERR_MSB 2
+#define SPI_STATUS_RD_ERR_LSB 2
+#define SPI_STATUS_RD_ERR_MASK 0x00000004
+#define SPI_STATUS_RD_ERR_GET(x) (((x) & SPI_STATUS_RD_ERR_MASK) >> SPI_STATUS_RD_ERR_LSB)
+#define SPI_STATUS_RD_ERR_SET(x) (((x) << SPI_STATUS_RD_ERR_LSB) & SPI_STATUS_RD_ERR_MASK)
+#define SPI_STATUS_WR_ERR_MSB 1
+#define SPI_STATUS_WR_ERR_LSB 1
+#define SPI_STATUS_WR_ERR_MASK 0x00000002
+#define SPI_STATUS_WR_ERR_GET(x) (((x) & SPI_STATUS_WR_ERR_MASK) >> SPI_STATUS_WR_ERR_LSB)
+#define SPI_STATUS_WR_ERR_SET(x) (((x) << SPI_STATUS_WR_ERR_LSB) & SPI_STATUS_WR_ERR_MASK)
+#define SPI_STATUS_READY_MSB 0
+#define SPI_STATUS_READY_LSB 0
+#define SPI_STATUS_READY_MASK 0x00000001
+#define SPI_STATUS_READY_GET(x) (((x) & SPI_STATUS_READY_MASK) >> SPI_STATUS_READY_LSB)
+#define SPI_STATUS_READY_SET(x) (((x) << SPI_STATUS_READY_LSB) & SPI_STATUS_READY_MASK)
+
+#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482
+#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482
+#define NON_ASSOC_SLEEP_EN_BIT_MSB 0
+#define NON_ASSOC_SLEEP_EN_BIT_LSB 0
+#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001
+#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
+#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
+
+#define CIS_WINDOW_ADDRESS 0x00000600
+#define CIS_WINDOW_OFFSET 0x00000600
+#define CIS_WINDOW_DATA_MSB 7
+#define CIS_WINDOW_DATA_LSB 0
+#define CIS_WINDOW_DATA_MASK 0x000000ff
+#define CIS_WINDOW_DATA_GET(x) (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
+#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct mbox_host_reg_reg_s {
+ unsigned char pad0[1024]; /* pad to 0x400 */
+ volatile unsigned char host_int_status;
+ volatile unsigned char cpu_int_status;
+ volatile unsigned char error_int_status;
+ volatile unsigned char counter_int_status;
+ volatile unsigned char mbox_frame;
+ volatile unsigned char rx_lookahead_valid;
+ unsigned char pad1[2]; /* pad to 0x408 */
+ volatile unsigned char rx_lookahead0[4];
+ volatile unsigned char rx_lookahead1[4];
+ volatile unsigned char rx_lookahead2[4];
+ volatile unsigned char rx_lookahead3[4];
+ volatile unsigned char int_status_enable;
+ volatile unsigned char cpu_int_status_enable;
+ volatile unsigned char error_status_enable;
+ volatile unsigned char counter_int_status_enable;
+ unsigned char pad2[4]; /* pad to 0x420 */
+ volatile unsigned char count[8];
+ unsigned char pad3[24]; /* pad to 0x440 */
+ volatile unsigned char count_dec[32];
+ volatile unsigned char scratch[8];
+ volatile unsigned char fifo_timeout;
+ volatile unsigned char fifo_timeout_enable;
+ volatile unsigned char disable_sleep;
+ unsigned char pad4[5]; /* pad to 0x470 */
+ volatile unsigned char local_bus;
+ unsigned char pad5[1]; /* pad to 0x472 */
+ volatile unsigned char int_wlan;
+ unsigned char pad6[1]; /* pad to 0x474 */
+ volatile unsigned char window_data[4];
+ volatile unsigned char window_write_addr[4];
+ volatile unsigned char window_read_addr[4];
+ volatile unsigned char spi_config;
+ volatile unsigned char spi_status;
+ volatile unsigned char non_assoc_sleep_en;
+ unsigned char pad7[381]; /* pad to 0x600 */
+ volatile unsigned char cis_window[512];
+} mbox_host_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_HOST_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h
new file mode 100644
index 000000000000..4e07d2286107
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h
@@ -0,0 +1,481 @@
+#ifndef _MBOX_REG_REG_H_
+#define _MBOX_REG_REG_H_
+
+#define MBOX_FIFO_ADDRESS 0x00000000
+#define MBOX_FIFO_OFFSET 0x00000000
+#define MBOX_FIFO_DATA_MSB 19
+#define MBOX_FIFO_DATA_LSB 0
+#define MBOX_FIFO_DATA_MASK 0x000fffff
+#define MBOX_FIFO_DATA_GET(x) (((x) & MBOX_FIFO_DATA_MASK) >> MBOX_FIFO_DATA_LSB)
+#define MBOX_FIFO_DATA_SET(x) (((x) << MBOX_FIFO_DATA_LSB) & MBOX_FIFO_DATA_MASK)
+
+#define MBOX_FIFO_STATUS_ADDRESS 0x00000010
+#define MBOX_FIFO_STATUS_OFFSET 0x00000010
+#define MBOX_FIFO_STATUS_EMPTY_MSB 19
+#define MBOX_FIFO_STATUS_EMPTY_LSB 16
+#define MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000
+#define MBOX_FIFO_STATUS_EMPTY_GET(x) (((x) & MBOX_FIFO_STATUS_EMPTY_MASK) >> MBOX_FIFO_STATUS_EMPTY_LSB)
+#define MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << MBOX_FIFO_STATUS_EMPTY_LSB) & MBOX_FIFO_STATUS_EMPTY_MASK)
+#define MBOX_FIFO_STATUS_FULL_MSB 15
+#define MBOX_FIFO_STATUS_FULL_LSB 12
+#define MBOX_FIFO_STATUS_FULL_MASK 0x0000f000
+#define MBOX_FIFO_STATUS_FULL_GET(x) (((x) & MBOX_FIFO_STATUS_FULL_MASK) >> MBOX_FIFO_STATUS_FULL_LSB)
+#define MBOX_FIFO_STATUS_FULL_SET(x) (((x) << MBOX_FIFO_STATUS_FULL_LSB) & MBOX_FIFO_STATUS_FULL_MASK)
+
+#define MBOX_DMA_POLICY_ADDRESS 0x00000014
+#define MBOX_DMA_POLICY_OFFSET 0x00000014
+#define MBOX_DMA_POLICY_TX_QUANTUM_MSB 3
+#define MBOX_DMA_POLICY_TX_QUANTUM_LSB 3
+#define MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008
+#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> MBOX_DMA_POLICY_TX_QUANTUM_LSB)
+#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << MBOX_DMA_POLICY_TX_QUANTUM_LSB) & MBOX_DMA_POLICY_TX_QUANTUM_MASK)
+#define MBOX_DMA_POLICY_TX_ORDER_MSB 2
+#define MBOX_DMA_POLICY_TX_ORDER_LSB 2
+#define MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004
+#define MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & MBOX_DMA_POLICY_TX_ORDER_MASK) >> MBOX_DMA_POLICY_TX_ORDER_LSB)
+#define MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << MBOX_DMA_POLICY_TX_ORDER_LSB) & MBOX_DMA_POLICY_TX_ORDER_MASK)
+#define MBOX_DMA_POLICY_RX_QUANTUM_MSB 1
+#define MBOX_DMA_POLICY_RX_QUANTUM_LSB 1
+#define MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002
+#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> MBOX_DMA_POLICY_RX_QUANTUM_LSB)
+#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << MBOX_DMA_POLICY_RX_QUANTUM_LSB) & MBOX_DMA_POLICY_RX_QUANTUM_MASK)
+#define MBOX_DMA_POLICY_RX_ORDER_MSB 0
+#define MBOX_DMA_POLICY_RX_ORDER_LSB 0
+#define MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001
+#define MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & MBOX_DMA_POLICY_RX_ORDER_MASK) >> MBOX_DMA_POLICY_RX_ORDER_LSB)
+#define MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << MBOX_DMA_POLICY_RX_ORDER_LSB) & MBOX_DMA_POLICY_RX_ORDER_MASK)
+
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c
+#define MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c
+#define MBOX0_DMA_RX_CONTROL_RESUME_MSB 2
+#define MBOX0_DMA_RX_CONTROL_RESUME_LSB 2
+#define MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> MBOX0_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_RESUME_LSB) & MBOX0_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX0_DMA_RX_CONTROL_START_MSB 1
+#define MBOX0_DMA_RX_CONTROL_START_LSB 1
+#define MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
+#define MBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & MBOX0_DMA_RX_CONTROL_START_MASK) >> MBOX0_DMA_RX_CONTROL_START_LSB)
+#define MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_START_LSB) & MBOX0_DMA_RX_CONTROL_START_MASK)
+#define MBOX0_DMA_RX_CONTROL_STOP_MSB 0
+#define MBOX0_DMA_RX_CONTROL_STOP_LSB 0
+#define MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & MBOX0_DMA_RX_CONTROL_STOP_MASK) >> MBOX0_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_STOP_LSB) & MBOX0_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024
+#define MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024
+#define MBOX0_DMA_TX_CONTROL_RESUME_MSB 2
+#define MBOX0_DMA_TX_CONTROL_RESUME_LSB 2
+#define MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> MBOX0_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_RESUME_LSB) & MBOX0_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX0_DMA_TX_CONTROL_START_MSB 1
+#define MBOX0_DMA_TX_CONTROL_START_LSB 1
+#define MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
+#define MBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & MBOX0_DMA_TX_CONTROL_START_MASK) >> MBOX0_DMA_TX_CONTROL_START_LSB)
+#define MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_START_LSB) & MBOX0_DMA_TX_CONTROL_START_MASK)
+#define MBOX0_DMA_TX_CONTROL_STOP_MSB 0
+#define MBOX0_DMA_TX_CONTROL_STOP_LSB 0
+#define MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & MBOX0_DMA_TX_CONTROL_STOP_MASK) >> MBOX0_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_STOP_LSB) & MBOX0_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c
+#define MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c
+#define MBOX1_DMA_RX_CONTROL_RESUME_MSB 2
+#define MBOX1_DMA_RX_CONTROL_RESUME_LSB 2
+#define MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x) & MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> MBOX1_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_RESUME_LSB) & MBOX1_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX1_DMA_RX_CONTROL_START_MSB 1
+#define MBOX1_DMA_RX_CONTROL_START_LSB 1
+#define MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002
+#define MBOX1_DMA_RX_CONTROL_START_GET(x) (((x) & MBOX1_DMA_RX_CONTROL_START_MASK) >> MBOX1_DMA_RX_CONTROL_START_LSB)
+#define MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_START_LSB) & MBOX1_DMA_RX_CONTROL_START_MASK)
+#define MBOX1_DMA_RX_CONTROL_STOP_MSB 0
+#define MBOX1_DMA_RX_CONTROL_STOP_LSB 0
+#define MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x) & MBOX1_DMA_RX_CONTROL_STOP_MASK) >> MBOX1_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_STOP_LSB) & MBOX1_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034
+#define MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034
+#define MBOX1_DMA_TX_CONTROL_RESUME_MSB 2
+#define MBOX1_DMA_TX_CONTROL_RESUME_LSB 2
+#define MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x) & MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> MBOX1_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_RESUME_LSB) & MBOX1_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX1_DMA_TX_CONTROL_START_MSB 1
+#define MBOX1_DMA_TX_CONTROL_START_LSB 1
+#define MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002
+#define MBOX1_DMA_TX_CONTROL_START_GET(x) (((x) & MBOX1_DMA_TX_CONTROL_START_MASK) >> MBOX1_DMA_TX_CONTROL_START_LSB)
+#define MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_START_LSB) & MBOX1_DMA_TX_CONTROL_START_MASK)
+#define MBOX1_DMA_TX_CONTROL_STOP_MSB 0
+#define MBOX1_DMA_TX_CONTROL_STOP_LSB 0
+#define MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x) & MBOX1_DMA_TX_CONTROL_STOP_MASK) >> MBOX1_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_STOP_LSB) & MBOX1_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c
+#define MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c
+#define MBOX2_DMA_RX_CONTROL_RESUME_MSB 2
+#define MBOX2_DMA_RX_CONTROL_RESUME_LSB 2
+#define MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x) & MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> MBOX2_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_RESUME_LSB) & MBOX2_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX2_DMA_RX_CONTROL_START_MSB 1
+#define MBOX2_DMA_RX_CONTROL_START_LSB 1
+#define MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002
+#define MBOX2_DMA_RX_CONTROL_START_GET(x) (((x) & MBOX2_DMA_RX_CONTROL_START_MASK) >> MBOX2_DMA_RX_CONTROL_START_LSB)
+#define MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_START_LSB) & MBOX2_DMA_RX_CONTROL_START_MASK)
+#define MBOX2_DMA_RX_CONTROL_STOP_MSB 0
+#define MBOX2_DMA_RX_CONTROL_STOP_LSB 0
+#define MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x) & MBOX2_DMA_RX_CONTROL_STOP_MASK) >> MBOX2_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_STOP_LSB) & MBOX2_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044
+#define MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044
+#define MBOX2_DMA_TX_CONTROL_RESUME_MSB 2
+#define MBOX2_DMA_TX_CONTROL_RESUME_LSB 2
+#define MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x) & MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> MBOX2_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_RESUME_LSB) & MBOX2_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX2_DMA_TX_CONTROL_START_MSB 1
+#define MBOX2_DMA_TX_CONTROL_START_LSB 1
+#define MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002
+#define MBOX2_DMA_TX_CONTROL_START_GET(x) (((x) & MBOX2_DMA_TX_CONTROL_START_MASK) >> MBOX2_DMA_TX_CONTROL_START_LSB)
+#define MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_START_LSB) & MBOX2_DMA_TX_CONTROL_START_MASK)
+#define MBOX2_DMA_TX_CONTROL_STOP_MSB 0
+#define MBOX2_DMA_TX_CONTROL_STOP_LSB 0
+#define MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x) & MBOX2_DMA_TX_CONTROL_STOP_MASK) >> MBOX2_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_STOP_LSB) & MBOX2_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c
+#define MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c
+#define MBOX3_DMA_RX_CONTROL_RESUME_MSB 2
+#define MBOX3_DMA_RX_CONTROL_RESUME_LSB 2
+#define MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x) & MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> MBOX3_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_RESUME_LSB) & MBOX3_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX3_DMA_RX_CONTROL_START_MSB 1
+#define MBOX3_DMA_RX_CONTROL_START_LSB 1
+#define MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002
+#define MBOX3_DMA_RX_CONTROL_START_GET(x) (((x) & MBOX3_DMA_RX_CONTROL_START_MASK) >> MBOX3_DMA_RX_CONTROL_START_LSB)
+#define MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_START_LSB) & MBOX3_DMA_RX_CONTROL_START_MASK)
+#define MBOX3_DMA_RX_CONTROL_STOP_MSB 0
+#define MBOX3_DMA_RX_CONTROL_STOP_LSB 0
+#define MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x) & MBOX3_DMA_RX_CONTROL_STOP_MASK) >> MBOX3_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_STOP_LSB) & MBOX3_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054
+#define MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054
+#define MBOX3_DMA_TX_CONTROL_RESUME_MSB 2
+#define MBOX3_DMA_TX_CONTROL_RESUME_LSB 2
+#define MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x) & MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> MBOX3_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_RESUME_LSB) & MBOX3_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX3_DMA_TX_CONTROL_START_MSB 1
+#define MBOX3_DMA_TX_CONTROL_START_LSB 1
+#define MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002
+#define MBOX3_DMA_TX_CONTROL_START_GET(x) (((x) & MBOX3_DMA_TX_CONTROL_START_MASK) >> MBOX3_DMA_TX_CONTROL_START_LSB)
+#define MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_START_LSB) & MBOX3_DMA_TX_CONTROL_START_MASK)
+#define MBOX3_DMA_TX_CONTROL_STOP_MSB 0
+#define MBOX3_DMA_TX_CONTROL_STOP_LSB 0
+#define MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x) & MBOX3_DMA_TX_CONTROL_STOP_MASK) >> MBOX3_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_STOP_LSB) & MBOX3_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX_INT_STATUS_ADDRESS 0x00000058
+#define MBOX_INT_STATUS_OFFSET 0x00000058
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_OVERFLOW_MSB 17
+#define MBOX_INT_STATUS_TX_OVERFLOW_LSB 17
+#define MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000
+#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> MBOX_INT_STATUS_TX_OVERFLOW_LSB)
+#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << MBOX_INT_STATUS_TX_OVERFLOW_LSB) & MBOX_INT_STATUS_TX_OVERFLOW_MASK)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16
+#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000
+#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
+#define MBOX_INT_STATUS_RX_NOT_FULL_MSB 11
+#define MBOX_INT_STATUS_RX_NOT_FULL_LSB 8
+#define MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00
+#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> MBOX_INT_STATUS_RX_NOT_FULL_LSB)
+#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << MBOX_INT_STATUS_RX_NOT_FULL_LSB) & MBOX_INT_STATUS_RX_NOT_FULL_MASK)
+#define MBOX_INT_STATUS_HOST_MSB 7
+#define MBOX_INT_STATUS_HOST_LSB 0
+#define MBOX_INT_STATUS_HOST_MASK 0x000000ff
+#define MBOX_INT_STATUS_HOST_GET(x) (((x) & MBOX_INT_STATUS_HOST_MASK) >> MBOX_INT_STATUS_HOST_LSB)
+#define MBOX_INT_STATUS_HOST_SET(x) (((x) << MBOX_INT_STATUS_HOST_LSB) & MBOX_INT_STATUS_HOST_MASK)
+
+#define MBOX_INT_ENABLE_ADDRESS 0x0000005c
+#define MBOX_INT_ENABLE_OFFSET 0x0000005c
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17
+#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000
+#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11
+#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00
+#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
+#define MBOX_INT_ENABLE_HOST_MSB 7
+#define MBOX_INT_ENABLE_HOST_LSB 0
+#define MBOX_INT_ENABLE_HOST_MASK 0x000000ff
+#define MBOX_INT_ENABLE_HOST_GET(x) (((x) & MBOX_INT_ENABLE_HOST_MASK) >> MBOX_INT_ENABLE_HOST_LSB)
+#define MBOX_INT_ENABLE_HOST_SET(x) (((x) << MBOX_INT_ENABLE_HOST_LSB) & MBOX_INT_ENABLE_HOST_MASK)
+
+#define INT_HOST_ADDRESS 0x00000060
+#define INT_HOST_OFFSET 0x00000060
+#define INT_HOST_VECTOR_MSB 7
+#define INT_HOST_VECTOR_LSB 0
+#define INT_HOST_VECTOR_MASK 0x000000ff
+#define INT_HOST_VECTOR_GET(x) (((x) & INT_HOST_VECTOR_MASK) >> INT_HOST_VECTOR_LSB)
+#define INT_HOST_VECTOR_SET(x) (((x) << INT_HOST_VECTOR_LSB) & INT_HOST_VECTOR_MASK)
+
+#define LOCAL_COUNT_ADDRESS 0x00000080
+#define LOCAL_COUNT_OFFSET 0x00000080
+#define LOCAL_COUNT_VALUE_MSB 7
+#define LOCAL_COUNT_VALUE_LSB 0
+#define LOCAL_COUNT_VALUE_MASK 0x000000ff
+#define LOCAL_COUNT_VALUE_GET(x) (((x) & LOCAL_COUNT_VALUE_MASK) >> LOCAL_COUNT_VALUE_LSB)
+#define LOCAL_COUNT_VALUE_SET(x) (((x) << LOCAL_COUNT_VALUE_LSB) & LOCAL_COUNT_VALUE_MASK)
+
+#define COUNT_INC_ADDRESS 0x000000a0
+#define COUNT_INC_OFFSET 0x000000a0
+#define COUNT_INC_VALUE_MSB 7
+#define COUNT_INC_VALUE_LSB 0
+#define COUNT_INC_VALUE_MASK 0x000000ff
+#define COUNT_INC_VALUE_GET(x) (((x) & COUNT_INC_VALUE_MASK) >> COUNT_INC_VALUE_LSB)
+#define COUNT_INC_VALUE_SET(x) (((x) << COUNT_INC_VALUE_LSB) & COUNT_INC_VALUE_MASK)
+
+#define LOCAL_SCRATCH_ADDRESS 0x000000c0
+#define LOCAL_SCRATCH_OFFSET 0x000000c0
+#define LOCAL_SCRATCH_VALUE_MSB 7
+#define LOCAL_SCRATCH_VALUE_LSB 0
+#define LOCAL_SCRATCH_VALUE_MASK 0x000000ff
+#define LOCAL_SCRATCH_VALUE_GET(x) (((x) & LOCAL_SCRATCH_VALUE_MASK) >> LOCAL_SCRATCH_VALUE_LSB)
+#define LOCAL_SCRATCH_VALUE_SET(x) (((x) << LOCAL_SCRATCH_VALUE_LSB) & LOCAL_SCRATCH_VALUE_MASK)
+
+#define USE_LOCAL_BUS_ADDRESS 0x000000e0
+#define USE_LOCAL_BUS_OFFSET 0x000000e0
+#define USE_LOCAL_BUS_PIN_INIT_MSB 0
+#define USE_LOCAL_BUS_PIN_INIT_LSB 0
+#define USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001
+#define USE_LOCAL_BUS_PIN_INIT_GET(x) (((x) & USE_LOCAL_BUS_PIN_INIT_MASK) >> USE_LOCAL_BUS_PIN_INIT_LSB)
+#define USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << USE_LOCAL_BUS_PIN_INIT_LSB) & USE_LOCAL_BUS_PIN_INIT_MASK)
+
+#define SDIO_CONFIG_ADDRESS 0x000000e4
+#define SDIO_CONFIG_OFFSET 0x000000e4
+#define SDIO_CONFIG_CCCR_IOR1_MSB 0
+#define SDIO_CONFIG_CCCR_IOR1_LSB 0
+#define SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001
+#define SDIO_CONFIG_CCCR_IOR1_GET(x) (((x) & SDIO_CONFIG_CCCR_IOR1_MASK) >> SDIO_CONFIG_CCCR_IOR1_LSB)
+#define SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << SDIO_CONFIG_CCCR_IOR1_LSB) & SDIO_CONFIG_CCCR_IOR1_MASK)
+
+#define MBOX_DEBUG_ADDRESS 0x000000e8
+#define MBOX_DEBUG_OFFSET 0x000000e8
+#define MBOX_DEBUG_SEL_MSB 2
+#define MBOX_DEBUG_SEL_LSB 0
+#define MBOX_DEBUG_SEL_MASK 0x00000007
+#define MBOX_DEBUG_SEL_GET(x) (((x) & MBOX_DEBUG_SEL_MASK) >> MBOX_DEBUG_SEL_LSB)
+#define MBOX_DEBUG_SEL_SET(x) (((x) << MBOX_DEBUG_SEL_LSB) & MBOX_DEBUG_SEL_MASK)
+
+#define MBOX_FIFO_RESET_ADDRESS 0x000000ec
+#define MBOX_FIFO_RESET_OFFSET 0x000000ec
+#define MBOX_FIFO_RESET_INIT_MSB 0
+#define MBOX_FIFO_RESET_INIT_LSB 0
+#define MBOX_FIFO_RESET_INIT_MASK 0x00000001
+#define MBOX_FIFO_RESET_INIT_GET(x) (((x) & MBOX_FIFO_RESET_INIT_MASK) >> MBOX_FIFO_RESET_INIT_LSB)
+#define MBOX_FIFO_RESET_INIT_SET(x) (((x) << MBOX_FIFO_RESET_INIT_LSB) & MBOX_FIFO_RESET_INIT_MASK)
+
+#define MBOX_TXFIFO_POP_ADDRESS 0x000000f0
+#define MBOX_TXFIFO_POP_OFFSET 0x000000f0
+#define MBOX_TXFIFO_POP_DATA_MSB 0
+#define MBOX_TXFIFO_POP_DATA_LSB 0
+#define MBOX_TXFIFO_POP_DATA_MASK 0x00000001
+#define MBOX_TXFIFO_POP_DATA_GET(x) (((x) & MBOX_TXFIFO_POP_DATA_MASK) >> MBOX_TXFIFO_POP_DATA_LSB)
+#define MBOX_TXFIFO_POP_DATA_SET(x) (((x) << MBOX_TXFIFO_POP_DATA_LSB) & MBOX_TXFIFO_POP_DATA_MASK)
+
+#define MBOX_RXFIFO_POP_ADDRESS 0x00000100
+#define MBOX_RXFIFO_POP_OFFSET 0x00000100
+#define MBOX_RXFIFO_POP_DATA_MSB 0
+#define MBOX_RXFIFO_POP_DATA_LSB 0
+#define MBOX_RXFIFO_POP_DATA_MASK 0x00000001
+#define MBOX_RXFIFO_POP_DATA_GET(x) (((x) & MBOX_RXFIFO_POP_DATA_MASK) >> MBOX_RXFIFO_POP_DATA_LSB)
+#define MBOX_RXFIFO_POP_DATA_SET(x) (((x) << MBOX_RXFIFO_POP_DATA_LSB) & MBOX_RXFIFO_POP_DATA_MASK)
+
+#define SDIO_DEBUG_ADDRESS 0x00000110
+#define SDIO_DEBUG_OFFSET 0x00000110
+#define SDIO_DEBUG_SEL_MSB 3
+#define SDIO_DEBUG_SEL_LSB 0
+#define SDIO_DEBUG_SEL_MASK 0x0000000f
+#define SDIO_DEBUG_SEL_GET(x) (((x) & SDIO_DEBUG_SEL_MASK) >> SDIO_DEBUG_SEL_LSB)
+#define SDIO_DEBUG_SEL_SET(x) (((x) << SDIO_DEBUG_SEL_LSB) & SDIO_DEBUG_SEL_MASK)
+
+#define HOST_IF_WINDOW_ADDRESS 0x00002000
+#define HOST_IF_WINDOW_OFFSET 0x00002000
+#define HOST_IF_WINDOW_DATA_MSB 7
+#define HOST_IF_WINDOW_DATA_LSB 0
+#define HOST_IF_WINDOW_DATA_MASK 0x000000ff
+#define HOST_IF_WINDOW_DATA_GET(x) (((x) & HOST_IF_WINDOW_DATA_MASK) >> HOST_IF_WINDOW_DATA_LSB)
+#define HOST_IF_WINDOW_DATA_SET(x) (((x) << HOST_IF_WINDOW_DATA_LSB) & HOST_IF_WINDOW_DATA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct mbox_reg_reg_s {
+ volatile unsigned int mbox_fifo[4];
+ volatile unsigned int mbox_fifo_status;
+ volatile unsigned int mbox_dma_policy;
+ volatile unsigned int mbox0_dma_rx_descriptor_base;
+ volatile unsigned int mbox0_dma_rx_control;
+ volatile unsigned int mbox0_dma_tx_descriptor_base;
+ volatile unsigned int mbox0_dma_tx_control;
+ volatile unsigned int mbox1_dma_rx_descriptor_base;
+ volatile unsigned int mbox1_dma_rx_control;
+ volatile unsigned int mbox1_dma_tx_descriptor_base;
+ volatile unsigned int mbox1_dma_tx_control;
+ volatile unsigned int mbox2_dma_rx_descriptor_base;
+ volatile unsigned int mbox2_dma_rx_control;
+ volatile unsigned int mbox2_dma_tx_descriptor_base;
+ volatile unsigned int mbox2_dma_tx_control;
+ volatile unsigned int mbox3_dma_rx_descriptor_base;
+ volatile unsigned int mbox3_dma_rx_control;
+ volatile unsigned int mbox3_dma_tx_descriptor_base;
+ volatile unsigned int mbox3_dma_tx_control;
+ volatile unsigned int mbox_int_status;
+ volatile unsigned int mbox_int_enable;
+ volatile unsigned int int_host;
+ unsigned char pad0[28]; /* pad to 0x80 */
+ volatile unsigned int local_count[8];
+ volatile unsigned int count_inc[8];
+ volatile unsigned int local_scratch[8];
+ volatile unsigned int use_local_bus;
+ volatile unsigned int sdio_config;
+ volatile unsigned int mbox_debug;
+ volatile unsigned int mbox_fifo_reset;
+ volatile unsigned int mbox_txfifo_pop[4];
+ volatile unsigned int mbox_rxfifo_pop[4];
+ volatile unsigned int sdio_debug;
+ unsigned char pad1[7916]; /* pad to 0x2000 */
+ volatile unsigned int host_if_window[2048];
+} mbox_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h
new file mode 100644
index 000000000000..8b3980afb643
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h
@@ -0,0 +1,1163 @@
+#ifndef _RTC_REG_REG_H_
+#define _RTC_REG_REG_H_
+
+#define RESET_CONTROL_ADDRESS 0x00000000
+#define RESET_CONTROL_OFFSET 0x00000000
+#define RESET_CONTROL_CPU_INIT_RESET_MSB 11
+#define RESET_CONTROL_CPU_INIT_RESET_LSB 11
+#define RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800
+#define RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & RESET_CONTROL_CPU_INIT_RESET_MASK) >> RESET_CONTROL_CPU_INIT_RESET_LSB)
+#define RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << RESET_CONTROL_CPU_INIT_RESET_LSB) & RESET_CONTROL_CPU_INIT_RESET_MASK)
+#define RESET_CONTROL_VMC_REMAP_RESET_MSB 10
+#define RESET_CONTROL_VMC_REMAP_RESET_LSB 10
+#define RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400
+#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & RESET_CONTROL_VMC_REMAP_RESET_MASK) >> RESET_CONTROL_VMC_REMAP_RESET_LSB)
+#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << RESET_CONTROL_VMC_REMAP_RESET_LSB) & RESET_CONTROL_VMC_REMAP_RESET_MASK)
+#define RESET_CONTROL_RST_OUT_MSB 9
+#define RESET_CONTROL_RST_OUT_LSB 9
+#define RESET_CONTROL_RST_OUT_MASK 0x00000200
+#define RESET_CONTROL_RST_OUT_GET(x) (((x) & RESET_CONTROL_RST_OUT_MASK) >> RESET_CONTROL_RST_OUT_LSB)
+#define RESET_CONTROL_RST_OUT_SET(x) (((x) << RESET_CONTROL_RST_OUT_LSB) & RESET_CONTROL_RST_OUT_MASK)
+#define RESET_CONTROL_COLD_RST_MSB 8
+#define RESET_CONTROL_COLD_RST_LSB 8
+#define RESET_CONTROL_COLD_RST_MASK 0x00000100
+#define RESET_CONTROL_COLD_RST_GET(x) (((x) & RESET_CONTROL_COLD_RST_MASK) >> RESET_CONTROL_COLD_RST_LSB)
+#define RESET_CONTROL_COLD_RST_SET(x) (((x) << RESET_CONTROL_COLD_RST_LSB) & RESET_CONTROL_COLD_RST_MASK)
+#define RESET_CONTROL_WARM_RST_MSB 7
+#define RESET_CONTROL_WARM_RST_LSB 7
+#define RESET_CONTROL_WARM_RST_MASK 0x00000080
+#define RESET_CONTROL_WARM_RST_GET(x) (((x) & RESET_CONTROL_WARM_RST_MASK) >> RESET_CONTROL_WARM_RST_LSB)
+#define RESET_CONTROL_WARM_RST_SET(x) (((x) << RESET_CONTROL_WARM_RST_LSB) & RESET_CONTROL_WARM_RST_MASK)
+#define RESET_CONTROL_CPU_WARM_RST_MSB 6
+#define RESET_CONTROL_CPU_WARM_RST_LSB 6
+#define RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
+#define RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & RESET_CONTROL_CPU_WARM_RST_MASK) >> RESET_CONTROL_CPU_WARM_RST_LSB)
+#define RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << RESET_CONTROL_CPU_WARM_RST_LSB) & RESET_CONTROL_CPU_WARM_RST_MASK)
+#define RESET_CONTROL_MAC_COLD_RST_MSB 5
+#define RESET_CONTROL_MAC_COLD_RST_LSB 5
+#define RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020
+#define RESET_CONTROL_MAC_COLD_RST_GET(x) (((x) & RESET_CONTROL_MAC_COLD_RST_MASK) >> RESET_CONTROL_MAC_COLD_RST_LSB)
+#define RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << RESET_CONTROL_MAC_COLD_RST_LSB) & RESET_CONTROL_MAC_COLD_RST_MASK)
+#define RESET_CONTROL_MAC_WARM_RST_MSB 4
+#define RESET_CONTROL_MAC_WARM_RST_LSB 4
+#define RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010
+#define RESET_CONTROL_MAC_WARM_RST_GET(x) (((x) & RESET_CONTROL_MAC_WARM_RST_MASK) >> RESET_CONTROL_MAC_WARM_RST_LSB)
+#define RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << RESET_CONTROL_MAC_WARM_RST_LSB) & RESET_CONTROL_MAC_WARM_RST_MASK)
+#define RESET_CONTROL_MBOX_RST_MSB 2
+#define RESET_CONTROL_MBOX_RST_LSB 2
+#define RESET_CONTROL_MBOX_RST_MASK 0x00000004
+#define RESET_CONTROL_MBOX_RST_GET(x) (((x) & RESET_CONTROL_MBOX_RST_MASK) >> RESET_CONTROL_MBOX_RST_LSB)
+#define RESET_CONTROL_MBOX_RST_SET(x) (((x) << RESET_CONTROL_MBOX_RST_LSB) & RESET_CONTROL_MBOX_RST_MASK)
+#define RESET_CONTROL_UART_RST_MSB 1
+#define RESET_CONTROL_UART_RST_LSB 1
+#define RESET_CONTROL_UART_RST_MASK 0x00000002
+#define RESET_CONTROL_UART_RST_GET(x) (((x) & RESET_CONTROL_UART_RST_MASK) >> RESET_CONTROL_UART_RST_LSB)
+#define RESET_CONTROL_UART_RST_SET(x) (((x) << RESET_CONTROL_UART_RST_LSB) & RESET_CONTROL_UART_RST_MASK)
+#define RESET_CONTROL_SI0_RST_MSB 0
+#define RESET_CONTROL_SI0_RST_LSB 0
+#define RESET_CONTROL_SI0_RST_MASK 0x00000001
+#define RESET_CONTROL_SI0_RST_GET(x) (((x) & RESET_CONTROL_SI0_RST_MASK) >> RESET_CONTROL_SI0_RST_LSB)
+#define RESET_CONTROL_SI0_RST_SET(x) (((x) << RESET_CONTROL_SI0_RST_LSB) & RESET_CONTROL_SI0_RST_MASK)
+
+#define XTAL_CONTROL_ADDRESS 0x00000004
+#define XTAL_CONTROL_OFFSET 0x00000004
+#define XTAL_CONTROL_TCXO_MSB 0
+#define XTAL_CONTROL_TCXO_LSB 0
+#define XTAL_CONTROL_TCXO_MASK 0x00000001
+#define XTAL_CONTROL_TCXO_GET(x) (((x) & XTAL_CONTROL_TCXO_MASK) >> XTAL_CONTROL_TCXO_LSB)
+#define XTAL_CONTROL_TCXO_SET(x) (((x) << XTAL_CONTROL_TCXO_LSB) & XTAL_CONTROL_TCXO_MASK)
+
+#define TCXO_DETECT_ADDRESS 0x00000008
+#define TCXO_DETECT_OFFSET 0x00000008
+#define TCXO_DETECT_PRESENT_MSB 0
+#define TCXO_DETECT_PRESENT_LSB 0
+#define TCXO_DETECT_PRESENT_MASK 0x00000001
+#define TCXO_DETECT_PRESENT_GET(x) (((x) & TCXO_DETECT_PRESENT_MASK) >> TCXO_DETECT_PRESENT_LSB)
+#define TCXO_DETECT_PRESENT_SET(x) (((x) << TCXO_DETECT_PRESENT_LSB) & TCXO_DETECT_PRESENT_MASK)
+
+#define XTAL_TEST_ADDRESS 0x0000000c
+#define XTAL_TEST_OFFSET 0x0000000c
+#define XTAL_TEST_NOTCXODET_MSB 0
+#define XTAL_TEST_NOTCXODET_LSB 0
+#define XTAL_TEST_NOTCXODET_MASK 0x00000001
+#define XTAL_TEST_NOTCXODET_GET(x) (((x) & XTAL_TEST_NOTCXODET_MASK) >> XTAL_TEST_NOTCXODET_LSB)
+#define XTAL_TEST_NOTCXODET_SET(x) (((x) << XTAL_TEST_NOTCXODET_LSB) & XTAL_TEST_NOTCXODET_MASK)
+
+#define QUADRATURE_ADDRESS 0x00000010
+#define QUADRATURE_OFFSET 0x00000010
+#define QUADRATURE_ADC_MSB 5
+#define QUADRATURE_ADC_LSB 4
+#define QUADRATURE_ADC_MASK 0x00000030
+#define QUADRATURE_ADC_GET(x) (((x) & QUADRATURE_ADC_MASK) >> QUADRATURE_ADC_LSB)
+#define QUADRATURE_ADC_SET(x) (((x) << QUADRATURE_ADC_LSB) & QUADRATURE_ADC_MASK)
+#define QUADRATURE_SEL_MSB 2
+#define QUADRATURE_SEL_LSB 2
+#define QUADRATURE_SEL_MASK 0x00000004
+#define QUADRATURE_SEL_GET(x) (((x) & QUADRATURE_SEL_MASK) >> QUADRATURE_SEL_LSB)
+#define QUADRATURE_SEL_SET(x) (((x) << QUADRATURE_SEL_LSB) & QUADRATURE_SEL_MASK)
+#define QUADRATURE_DAC_MSB 1
+#define QUADRATURE_DAC_LSB 0
+#define QUADRATURE_DAC_MASK 0x00000003
+#define QUADRATURE_DAC_GET(x) (((x) & QUADRATURE_DAC_MASK) >> QUADRATURE_DAC_LSB)
+#define QUADRATURE_DAC_SET(x) (((x) << QUADRATURE_DAC_LSB) & QUADRATURE_DAC_MASK)
+
+#define PLL_CONTROL_ADDRESS 0x00000014
+#define PLL_CONTROL_OFFSET 0x00000014
+#define PLL_CONTROL_DIG_TEST_CLK_MSB 20
+#define PLL_CONTROL_DIG_TEST_CLK_LSB 20
+#define PLL_CONTROL_DIG_TEST_CLK_MASK 0x00100000
+#define PLL_CONTROL_DIG_TEST_CLK_GET(x) (((x) & PLL_CONTROL_DIG_TEST_CLK_MASK) >> PLL_CONTROL_DIG_TEST_CLK_LSB)
+#define PLL_CONTROL_DIG_TEST_CLK_SET(x) (((x) << PLL_CONTROL_DIG_TEST_CLK_LSB) & PLL_CONTROL_DIG_TEST_CLK_MASK)
+#define PLL_CONTROL_MAC_OVERRIDE_MSB 19
+#define PLL_CONTROL_MAC_OVERRIDE_LSB 19
+#define PLL_CONTROL_MAC_OVERRIDE_MASK 0x00080000
+#define PLL_CONTROL_MAC_OVERRIDE_GET(x) (((x) & PLL_CONTROL_MAC_OVERRIDE_MASK) >> PLL_CONTROL_MAC_OVERRIDE_LSB)
+#define PLL_CONTROL_MAC_OVERRIDE_SET(x) (((x) << PLL_CONTROL_MAC_OVERRIDE_LSB) & PLL_CONTROL_MAC_OVERRIDE_MASK)
+#define PLL_CONTROL_NOPWD_MSB 18
+#define PLL_CONTROL_NOPWD_LSB 18
+#define PLL_CONTROL_NOPWD_MASK 0x00040000
+#define PLL_CONTROL_NOPWD_GET(x) (((x) & PLL_CONTROL_NOPWD_MASK) >> PLL_CONTROL_NOPWD_LSB)
+#define PLL_CONTROL_NOPWD_SET(x) (((x) << PLL_CONTROL_NOPWD_LSB) & PLL_CONTROL_NOPWD_MASK)
+#define PLL_CONTROL_UPDATING_MSB 17
+#define PLL_CONTROL_UPDATING_LSB 17
+#define PLL_CONTROL_UPDATING_MASK 0x00020000
+#define PLL_CONTROL_UPDATING_GET(x) (((x) & PLL_CONTROL_UPDATING_MASK) >> PLL_CONTROL_UPDATING_LSB)
+#define PLL_CONTROL_UPDATING_SET(x) (((x) << PLL_CONTROL_UPDATING_LSB) & PLL_CONTROL_UPDATING_MASK)
+#define PLL_CONTROL_BYPASS_MSB 16
+#define PLL_CONTROL_BYPASS_LSB 16
+#define PLL_CONTROL_BYPASS_MASK 0x00010000
+#define PLL_CONTROL_BYPASS_GET(x) (((x) & PLL_CONTROL_BYPASS_MASK) >> PLL_CONTROL_BYPASS_LSB)
+#define PLL_CONTROL_BYPASS_SET(x) (((x) << PLL_CONTROL_BYPASS_LSB) & PLL_CONTROL_BYPASS_MASK)
+#define PLL_CONTROL_REFDIV_MSB 15
+#define PLL_CONTROL_REFDIV_LSB 12
+#define PLL_CONTROL_REFDIV_MASK 0x0000f000
+#define PLL_CONTROL_REFDIV_GET(x) (((x) & PLL_CONTROL_REFDIV_MASK) >> PLL_CONTROL_REFDIV_LSB)
+#define PLL_CONTROL_REFDIV_SET(x) (((x) << PLL_CONTROL_REFDIV_LSB) & PLL_CONTROL_REFDIV_MASK)
+#define PLL_CONTROL_DIV_MSB 9
+#define PLL_CONTROL_DIV_LSB 0
+#define PLL_CONTROL_DIV_MASK 0x000003ff
+#define PLL_CONTROL_DIV_GET(x) (((x) & PLL_CONTROL_DIV_MASK) >> PLL_CONTROL_DIV_LSB)
+#define PLL_CONTROL_DIV_SET(x) (((x) << PLL_CONTROL_DIV_LSB) & PLL_CONTROL_DIV_MASK)
+
+#define PLL_SETTLE_ADDRESS 0x00000018
+#define PLL_SETTLE_OFFSET 0x00000018
+#define PLL_SETTLE_TIME_MSB 11
+#define PLL_SETTLE_TIME_LSB 0
+#define PLL_SETTLE_TIME_MASK 0x00000fff
+#define PLL_SETTLE_TIME_GET(x) (((x) & PLL_SETTLE_TIME_MASK) >> PLL_SETTLE_TIME_LSB)
+#define PLL_SETTLE_TIME_SET(x) (((x) << PLL_SETTLE_TIME_LSB) & PLL_SETTLE_TIME_MASK)
+
+#define XTAL_SETTLE_ADDRESS 0x0000001c
+#define XTAL_SETTLE_OFFSET 0x0000001c
+#define XTAL_SETTLE_TIME_MSB 7
+#define XTAL_SETTLE_TIME_LSB 0
+#define XTAL_SETTLE_TIME_MASK 0x000000ff
+#define XTAL_SETTLE_TIME_GET(x) (((x) & XTAL_SETTLE_TIME_MASK) >> XTAL_SETTLE_TIME_LSB)
+#define XTAL_SETTLE_TIME_SET(x) (((x) << XTAL_SETTLE_TIME_LSB) & XTAL_SETTLE_TIME_MASK)
+
+#define CPU_CLOCK_ADDRESS 0x00000020
+#define CPU_CLOCK_OFFSET 0x00000020
+#define CPU_CLOCK_STANDARD_MSB 1
+#define CPU_CLOCK_STANDARD_LSB 0
+#define CPU_CLOCK_STANDARD_MASK 0x00000003
+#define CPU_CLOCK_STANDARD_GET(x) (((x) & CPU_CLOCK_STANDARD_MASK) >> CPU_CLOCK_STANDARD_LSB)
+#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK)
+
+#define CLOCK_OUT_ADDRESS 0x00000024
+#define CLOCK_OUT_OFFSET 0x00000024
+#define CLOCK_OUT_SELECT_MSB 3
+#define CLOCK_OUT_SELECT_LSB 0
+#define CLOCK_OUT_SELECT_MASK 0x0000000f
+#define CLOCK_OUT_SELECT_GET(x) (((x) & CLOCK_OUT_SELECT_MASK) >> CLOCK_OUT_SELECT_LSB)
+#define CLOCK_OUT_SELECT_SET(x) (((x) << CLOCK_OUT_SELECT_LSB) & CLOCK_OUT_SELECT_MASK)
+
+#define CLOCK_CONTROL_ADDRESS 0x00000028
+#define CLOCK_CONTROL_OFFSET 0x00000028
+#define CLOCK_CONTROL_LF_CLK32_MSB 2
+#define CLOCK_CONTROL_LF_CLK32_LSB 2
+#define CLOCK_CONTROL_LF_CLK32_MASK 0x00000004
+#define CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & CLOCK_CONTROL_LF_CLK32_MASK) >> CLOCK_CONTROL_LF_CLK32_LSB)
+#define CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << CLOCK_CONTROL_LF_CLK32_LSB) & CLOCK_CONTROL_LF_CLK32_MASK)
+#define CLOCK_CONTROL_UART_CLK_MSB 1
+#define CLOCK_CONTROL_UART_CLK_LSB 1
+#define CLOCK_CONTROL_UART_CLK_MASK 0x00000002
+#define CLOCK_CONTROL_UART_CLK_GET(x) (((x) & CLOCK_CONTROL_UART_CLK_MASK) >> CLOCK_CONTROL_UART_CLK_LSB)
+#define CLOCK_CONTROL_UART_CLK_SET(x) (((x) << CLOCK_CONTROL_UART_CLK_LSB) & CLOCK_CONTROL_UART_CLK_MASK)
+#define CLOCK_CONTROL_SI0_CLK_MSB 0
+#define CLOCK_CONTROL_SI0_CLK_LSB 0
+#define CLOCK_CONTROL_SI0_CLK_MASK 0x00000001
+#define CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & CLOCK_CONTROL_SI0_CLK_MASK) >> CLOCK_CONTROL_SI0_CLK_LSB)
+#define CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << CLOCK_CONTROL_SI0_CLK_LSB) & CLOCK_CONTROL_SI0_CLK_MASK)
+
+#define BIAS_OVERRIDE_ADDRESS 0x0000002c
+#define BIAS_OVERRIDE_OFFSET 0x0000002c
+#define BIAS_OVERRIDE_ON_MSB 0
+#define BIAS_OVERRIDE_ON_LSB 0
+#define BIAS_OVERRIDE_ON_MASK 0x00000001
+#define BIAS_OVERRIDE_ON_GET(x) (((x) & BIAS_OVERRIDE_ON_MASK) >> BIAS_OVERRIDE_ON_LSB)
+#define BIAS_OVERRIDE_ON_SET(x) (((x) << BIAS_OVERRIDE_ON_LSB) & BIAS_OVERRIDE_ON_MASK)
+
+#define WDT_CONTROL_ADDRESS 0x00000030
+#define WDT_CONTROL_OFFSET 0x00000030
+#define WDT_CONTROL_ACTION_MSB 2
+#define WDT_CONTROL_ACTION_LSB 0
+#define WDT_CONTROL_ACTION_MASK 0x00000007
+#define WDT_CONTROL_ACTION_GET(x) (((x) & WDT_CONTROL_ACTION_MASK) >> WDT_CONTROL_ACTION_LSB)
+#define WDT_CONTROL_ACTION_SET(x) (((x) << WDT_CONTROL_ACTION_LSB) & WDT_CONTROL_ACTION_MASK)
+
+#define WDT_STATUS_ADDRESS 0x00000034
+#define WDT_STATUS_OFFSET 0x00000034
+#define WDT_STATUS_INTERRUPT_MSB 0
+#define WDT_STATUS_INTERRUPT_LSB 0
+#define WDT_STATUS_INTERRUPT_MASK 0x00000001
+#define WDT_STATUS_INTERRUPT_GET(x) (((x) & WDT_STATUS_INTERRUPT_MASK) >> WDT_STATUS_INTERRUPT_LSB)
+#define WDT_STATUS_INTERRUPT_SET(x) (((x) << WDT_STATUS_INTERRUPT_LSB) & WDT_STATUS_INTERRUPT_MASK)
+
+#define WDT_ADDRESS 0x00000038
+#define WDT_OFFSET 0x00000038
+#define WDT_TARGET_MSB 21
+#define WDT_TARGET_LSB 0
+#define WDT_TARGET_MASK 0x003fffff
+#define WDT_TARGET_GET(x) (((x) & WDT_TARGET_MASK) >> WDT_TARGET_LSB)
+#define WDT_TARGET_SET(x) (((x) << WDT_TARGET_LSB) & WDT_TARGET_MASK)
+
+#define WDT_COUNT_ADDRESS 0x0000003c
+#define WDT_COUNT_OFFSET 0x0000003c
+#define WDT_COUNT_VALUE_MSB 21
+#define WDT_COUNT_VALUE_LSB 0
+#define WDT_COUNT_VALUE_MASK 0x003fffff
+#define WDT_COUNT_VALUE_GET(x) (((x) & WDT_COUNT_VALUE_MASK) >> WDT_COUNT_VALUE_LSB)
+#define WDT_COUNT_VALUE_SET(x) (((x) << WDT_COUNT_VALUE_LSB) & WDT_COUNT_VALUE_MASK)
+
+#define WDT_RESET_ADDRESS 0x00000040
+#define WDT_RESET_OFFSET 0x00000040
+#define WDT_RESET_VALUE_MSB 0
+#define WDT_RESET_VALUE_LSB 0
+#define WDT_RESET_VALUE_MASK 0x00000001
+#define WDT_RESET_VALUE_GET(x) (((x) & WDT_RESET_VALUE_MASK) >> WDT_RESET_VALUE_LSB)
+#define WDT_RESET_VALUE_SET(x) (((x) << WDT_RESET_VALUE_LSB) & WDT_RESET_VALUE_MASK)
+
+#define INT_STATUS_ADDRESS 0x00000044
+#define INT_STATUS_OFFSET 0x00000044
+#define INT_STATUS_RTC_POWER_MSB 14
+#define INT_STATUS_RTC_POWER_LSB 14
+#define INT_STATUS_RTC_POWER_MASK 0x00004000
+#define INT_STATUS_RTC_POWER_GET(x) (((x) & INT_STATUS_RTC_POWER_MASK) >> INT_STATUS_RTC_POWER_LSB)
+#define INT_STATUS_RTC_POWER_SET(x) (((x) << INT_STATUS_RTC_POWER_LSB) & INT_STATUS_RTC_POWER_MASK)
+#define INT_STATUS_MAC_MSB 13
+#define INT_STATUS_MAC_LSB 13
+#define INT_STATUS_MAC_MASK 0x00002000
+#define INT_STATUS_MAC_GET(x) (((x) & INT_STATUS_MAC_MASK) >> INT_STATUS_MAC_LSB)
+#define INT_STATUS_MAC_SET(x) (((x) << INT_STATUS_MAC_LSB) & INT_STATUS_MAC_MASK)
+#define INT_STATUS_MAILBOX_MSB 12
+#define INT_STATUS_MAILBOX_LSB 12
+#define INT_STATUS_MAILBOX_MASK 0x00001000
+#define INT_STATUS_MAILBOX_GET(x) (((x) & INT_STATUS_MAILBOX_MASK) >> INT_STATUS_MAILBOX_LSB)
+#define INT_STATUS_MAILBOX_SET(x) (((x) << INT_STATUS_MAILBOX_LSB) & INT_STATUS_MAILBOX_MASK)
+#define INT_STATUS_RTC_ALARM_MSB 11
+#define INT_STATUS_RTC_ALARM_LSB 11
+#define INT_STATUS_RTC_ALARM_MASK 0x00000800
+#define INT_STATUS_RTC_ALARM_GET(x) (((x) & INT_STATUS_RTC_ALARM_MASK) >> INT_STATUS_RTC_ALARM_LSB)
+#define INT_STATUS_RTC_ALARM_SET(x) (((x) << INT_STATUS_RTC_ALARM_LSB) & INT_STATUS_RTC_ALARM_MASK)
+#define INT_STATUS_HF_TIMER_MSB 10
+#define INT_STATUS_HF_TIMER_LSB 10
+#define INT_STATUS_HF_TIMER_MASK 0x00000400
+#define INT_STATUS_HF_TIMER_GET(x) (((x) & INT_STATUS_HF_TIMER_MASK) >> INT_STATUS_HF_TIMER_LSB)
+#define INT_STATUS_HF_TIMER_SET(x) (((x) << INT_STATUS_HF_TIMER_LSB) & INT_STATUS_HF_TIMER_MASK)
+#define INT_STATUS_LF_TIMER3_MSB 9
+#define INT_STATUS_LF_TIMER3_LSB 9
+#define INT_STATUS_LF_TIMER3_MASK 0x00000200
+#define INT_STATUS_LF_TIMER3_GET(x) (((x) & INT_STATUS_LF_TIMER3_MASK) >> INT_STATUS_LF_TIMER3_LSB)
+#define INT_STATUS_LF_TIMER3_SET(x) (((x) << INT_STATUS_LF_TIMER3_LSB) & INT_STATUS_LF_TIMER3_MASK)
+#define INT_STATUS_LF_TIMER2_MSB 8
+#define INT_STATUS_LF_TIMER2_LSB 8
+#define INT_STATUS_LF_TIMER2_MASK 0x00000100
+#define INT_STATUS_LF_TIMER2_GET(x) (((x) & INT_STATUS_LF_TIMER2_MASK) >> INT_STATUS_LF_TIMER2_LSB)
+#define INT_STATUS_LF_TIMER2_SET(x) (((x) << INT_STATUS_LF_TIMER2_LSB) & INT_STATUS_LF_TIMER2_MASK)
+#define INT_STATUS_LF_TIMER1_MSB 7
+#define INT_STATUS_LF_TIMER1_LSB 7
+#define INT_STATUS_LF_TIMER1_MASK 0x00000080
+#define INT_STATUS_LF_TIMER1_GET(x) (((x) & INT_STATUS_LF_TIMER1_MASK) >> INT_STATUS_LF_TIMER1_LSB)
+#define INT_STATUS_LF_TIMER1_SET(x) (((x) << INT_STATUS_LF_TIMER1_LSB) & INT_STATUS_LF_TIMER1_MASK)
+#define INT_STATUS_LF_TIMER0_MSB 6
+#define INT_STATUS_LF_TIMER0_LSB 6
+#define INT_STATUS_LF_TIMER0_MASK 0x00000040
+#define INT_STATUS_LF_TIMER0_GET(x) (((x) & INT_STATUS_LF_TIMER0_MASK) >> INT_STATUS_LF_TIMER0_LSB)
+#define INT_STATUS_LF_TIMER0_SET(x) (((x) << INT_STATUS_LF_TIMER0_LSB) & INT_STATUS_LF_TIMER0_MASK)
+#define INT_STATUS_KEYPAD_MSB 5
+#define INT_STATUS_KEYPAD_LSB 5
+#define INT_STATUS_KEYPAD_MASK 0x00000020
+#define INT_STATUS_KEYPAD_GET(x) (((x) & INT_STATUS_KEYPAD_MASK) >> INT_STATUS_KEYPAD_LSB)
+#define INT_STATUS_KEYPAD_SET(x) (((x) << INT_STATUS_KEYPAD_LSB) & INT_STATUS_KEYPAD_MASK)
+#define INT_STATUS_SI_MSB 4
+#define INT_STATUS_SI_LSB 4
+#define INT_STATUS_SI_MASK 0x00000010
+#define INT_STATUS_SI_GET(x) (((x) & INT_STATUS_SI_MASK) >> INT_STATUS_SI_LSB)
+#define INT_STATUS_SI_SET(x) (((x) << INT_STATUS_SI_LSB) & INT_STATUS_SI_MASK)
+#define INT_STATUS_GPIO_MSB 3
+#define INT_STATUS_GPIO_LSB 3
+#define INT_STATUS_GPIO_MASK 0x00000008
+#define INT_STATUS_GPIO_GET(x) (((x) & INT_STATUS_GPIO_MASK) >> INT_STATUS_GPIO_LSB)
+#define INT_STATUS_GPIO_SET(x) (((x) << INT_STATUS_GPIO_LSB) & INT_STATUS_GPIO_MASK)
+#define INT_STATUS_UART_MSB 2
+#define INT_STATUS_UART_LSB 2
+#define INT_STATUS_UART_MASK 0x00000004
+#define INT_STATUS_UART_GET(x) (((x) & INT_STATUS_UART_MASK) >> INT_STATUS_UART_LSB)
+#define INT_STATUS_UART_SET(x) (((x) << INT_STATUS_UART_LSB) & INT_STATUS_UART_MASK)
+#define INT_STATUS_ERROR_MSB 1
+#define INT_STATUS_ERROR_LSB 1
+#define INT_STATUS_ERROR_MASK 0x00000002
+#define INT_STATUS_ERROR_GET(x) (((x) & INT_STATUS_ERROR_MASK) >> INT_STATUS_ERROR_LSB)
+#define INT_STATUS_ERROR_SET(x) (((x) << INT_STATUS_ERROR_LSB) & INT_STATUS_ERROR_MASK)
+#define INT_STATUS_WDT_INT_MSB 0
+#define INT_STATUS_WDT_INT_LSB 0
+#define INT_STATUS_WDT_INT_MASK 0x00000001
+#define INT_STATUS_WDT_INT_GET(x) (((x) & INT_STATUS_WDT_INT_MASK) >> INT_STATUS_WDT_INT_LSB)
+#define INT_STATUS_WDT_INT_SET(x) (((x) << INT_STATUS_WDT_INT_LSB) & INT_STATUS_WDT_INT_MASK)
+
+#define LF_TIMER0_ADDRESS 0x00000048
+#define LF_TIMER0_OFFSET 0x00000048
+#define LF_TIMER0_TARGET_MSB 31
+#define LF_TIMER0_TARGET_LSB 0
+#define LF_TIMER0_TARGET_MASK 0xffffffff
+#define LF_TIMER0_TARGET_GET(x) (((x) & LF_TIMER0_TARGET_MASK) >> LF_TIMER0_TARGET_LSB)
+#define LF_TIMER0_TARGET_SET(x) (((x) << LF_TIMER0_TARGET_LSB) & LF_TIMER0_TARGET_MASK)
+
+#define LF_TIMER_COUNT0_ADDRESS 0x0000004c
+#define LF_TIMER_COUNT0_OFFSET 0x0000004c
+#define LF_TIMER_COUNT0_VALUE_MSB 31
+#define LF_TIMER_COUNT0_VALUE_LSB 0
+#define LF_TIMER_COUNT0_VALUE_MASK 0xffffffff
+#define LF_TIMER_COUNT0_VALUE_GET(x) (((x) & LF_TIMER_COUNT0_VALUE_MASK) >> LF_TIMER_COUNT0_VALUE_LSB)
+#define LF_TIMER_COUNT0_VALUE_SET(x) (((x) << LF_TIMER_COUNT0_VALUE_LSB) & LF_TIMER_COUNT0_VALUE_MASK)
+
+#define LF_TIMER_CONTROL0_ADDRESS 0x00000050
+#define LF_TIMER_CONTROL0_OFFSET 0x00000050
+#define LF_TIMER_CONTROL0_ENABLE_MSB 2
+#define LF_TIMER_CONTROL0_ENABLE_LSB 2
+#define LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
+#define LF_TIMER_CONTROL0_ENABLE_GET(x) (((x) & LF_TIMER_CONTROL0_ENABLE_MASK) >> LF_TIMER_CONTROL0_ENABLE_LSB)
+#define LF_TIMER_CONTROL0_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL0_ENABLE_LSB) & LF_TIMER_CONTROL0_ENABLE_MASK)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB 1
+#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB 1
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002
+#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) (((x) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL0_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) (((x) << LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL0_RESET_MSB 0
+#define LF_TIMER_CONTROL0_RESET_LSB 0
+#define LF_TIMER_CONTROL0_RESET_MASK 0x00000001
+#define LF_TIMER_CONTROL0_RESET_GET(x) (((x) & LF_TIMER_CONTROL0_RESET_MASK) >> LF_TIMER_CONTROL0_RESET_LSB)
+#define LF_TIMER_CONTROL0_RESET_SET(x) (((x) << LF_TIMER_CONTROL0_RESET_LSB) & LF_TIMER_CONTROL0_RESET_MASK)
+
+#define LF_TIMER_STATUS0_ADDRESS 0x00000054
+#define LF_TIMER_STATUS0_OFFSET 0x00000054
+#define LF_TIMER_STATUS0_INTERRUPT_MSB 0
+#define LF_TIMER_STATUS0_INTERRUPT_LSB 0
+#define LF_TIMER_STATUS0_INTERRUPT_MASK 0x00000001
+#define LF_TIMER_STATUS0_INTERRUPT_GET(x) (((x) & LF_TIMER_STATUS0_INTERRUPT_MASK) >> LF_TIMER_STATUS0_INTERRUPT_LSB)
+#define LF_TIMER_STATUS0_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS0_INTERRUPT_LSB) & LF_TIMER_STATUS0_INTERRUPT_MASK)
+
+#define LF_TIMER1_ADDRESS 0x00000058
+#define LF_TIMER1_OFFSET 0x00000058
+#define LF_TIMER1_TARGET_MSB 31
+#define LF_TIMER1_TARGET_LSB 0
+#define LF_TIMER1_TARGET_MASK 0xffffffff
+#define LF_TIMER1_TARGET_GET(x) (((x) & LF_TIMER1_TARGET_MASK) >> LF_TIMER1_TARGET_LSB)
+#define LF_TIMER1_TARGET_SET(x) (((x) << LF_TIMER1_TARGET_LSB) & LF_TIMER1_TARGET_MASK)
+
+#define LF_TIMER_COUNT1_ADDRESS 0x0000005c
+#define LF_TIMER_COUNT1_OFFSET 0x0000005c
+#define LF_TIMER_COUNT1_VALUE_MSB 31
+#define LF_TIMER_COUNT1_VALUE_LSB 0
+#define LF_TIMER_COUNT1_VALUE_MASK 0xffffffff
+#define LF_TIMER_COUNT1_VALUE_GET(x) (((x) & LF_TIMER_COUNT1_VALUE_MASK) >> LF_TIMER_COUNT1_VALUE_LSB)
+#define LF_TIMER_COUNT1_VALUE_SET(x) (((x) << LF_TIMER_COUNT1_VALUE_LSB) & LF_TIMER_COUNT1_VALUE_MASK)
+
+#define LF_TIMER_CONTROL1_ADDRESS 0x00000060
+#define LF_TIMER_CONTROL1_OFFSET 0x00000060
+#define LF_TIMER_CONTROL1_ENABLE_MSB 2
+#define LF_TIMER_CONTROL1_ENABLE_LSB 2
+#define LF_TIMER_CONTROL1_ENABLE_MASK 0x00000004
+#define LF_TIMER_CONTROL1_ENABLE_GET(x) (((x) & LF_TIMER_CONTROL1_ENABLE_MASK) >> LF_TIMER_CONTROL1_ENABLE_LSB)
+#define LF_TIMER_CONTROL1_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL1_ENABLE_LSB) & LF_TIMER_CONTROL1_ENABLE_MASK)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB 1
+#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB 1
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002
+#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) (((x) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL1_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) (((x) << LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL1_RESET_MSB 0
+#define LF_TIMER_CONTROL1_RESET_LSB 0
+#define LF_TIMER_CONTROL1_RESET_MASK 0x00000001
+#define LF_TIMER_CONTROL1_RESET_GET(x) (((x) & LF_TIMER_CONTROL1_RESET_MASK) >> LF_TIMER_CONTROL1_RESET_LSB)
+#define LF_TIMER_CONTROL1_RESET_SET(x) (((x) << LF_TIMER_CONTROL1_RESET_LSB) & LF_TIMER_CONTROL1_RESET_MASK)
+
+#define LF_TIMER_STATUS1_ADDRESS 0x00000064
+#define LF_TIMER_STATUS1_OFFSET 0x00000064
+#define LF_TIMER_STATUS1_INTERRUPT_MSB 0
+#define LF_TIMER_STATUS1_INTERRUPT_LSB 0
+#define LF_TIMER_STATUS1_INTERRUPT_MASK 0x00000001
+#define LF_TIMER_STATUS1_INTERRUPT_GET(x) (((x) & LF_TIMER_STATUS1_INTERRUPT_MASK) >> LF_TIMER_STATUS1_INTERRUPT_LSB)
+#define LF_TIMER_STATUS1_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS1_INTERRUPT_LSB) & LF_TIMER_STATUS1_INTERRUPT_MASK)
+
+#define LF_TIMER2_ADDRESS 0x00000068
+#define LF_TIMER2_OFFSET 0x00000068
+#define LF_TIMER2_TARGET_MSB 31
+#define LF_TIMER2_TARGET_LSB 0
+#define LF_TIMER2_TARGET_MASK 0xffffffff
+#define LF_TIMER2_TARGET_GET(x) (((x) & LF_TIMER2_TARGET_MASK) >> LF_TIMER2_TARGET_LSB)
+#define LF_TIMER2_TARGET_SET(x) (((x) << LF_TIMER2_TARGET_LSB) & LF_TIMER2_TARGET_MASK)
+
+#define LF_TIMER_COUNT2_ADDRESS 0x0000006c
+#define LF_TIMER_COUNT2_OFFSET 0x0000006c
+#define LF_TIMER_COUNT2_VALUE_MSB 31
+#define LF_TIMER_COUNT2_VALUE_LSB 0
+#define LF_TIMER_COUNT2_VALUE_MASK 0xffffffff
+#define LF_TIMER_COUNT2_VALUE_GET(x) (((x) & LF_TIMER_COUNT2_VALUE_MASK) >> LF_TIMER_COUNT2_VALUE_LSB)
+#define LF_TIMER_COUNT2_VALUE_SET(x) (((x) << LF_TIMER_COUNT2_VALUE_LSB) & LF_TIMER_COUNT2_VALUE_MASK)
+
+#define LF_TIMER_CONTROL2_ADDRESS 0x00000070
+#define LF_TIMER_CONTROL2_OFFSET 0x00000070
+#define LF_TIMER_CONTROL2_ENABLE_MSB 2
+#define LF_TIMER_CONTROL2_ENABLE_LSB 2
+#define LF_TIMER_CONTROL2_ENABLE_MASK 0x00000004
+#define LF_TIMER_CONTROL2_ENABLE_GET(x) (((x) & LF_TIMER_CONTROL2_ENABLE_MASK) >> LF_TIMER_CONTROL2_ENABLE_LSB)
+#define LF_TIMER_CONTROL2_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL2_ENABLE_LSB) & LF_TIMER_CONTROL2_ENABLE_MASK)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB 1
+#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB 1
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002
+#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) (((x) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL2_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) (((x) << LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL2_RESET_MSB 0
+#define LF_TIMER_CONTROL2_RESET_LSB 0
+#define LF_TIMER_CONTROL2_RESET_MASK 0x00000001
+#define LF_TIMER_CONTROL2_RESET_GET(x) (((x) & LF_TIMER_CONTROL2_RESET_MASK) >> LF_TIMER_CONTROL2_RESET_LSB)
+#define LF_TIMER_CONTROL2_RESET_SET(x) (((x) << LF_TIMER_CONTROL2_RESET_LSB) & LF_TIMER_CONTROL2_RESET_MASK)
+
+#define LF_TIMER_STATUS2_ADDRESS 0x00000074
+#define LF_TIMER_STATUS2_OFFSET 0x00000074
+#define LF_TIMER_STATUS2_INTERRUPT_MSB 0
+#define LF_TIMER_STATUS2_INTERRUPT_LSB 0
+#define LF_TIMER_STATUS2_INTERRUPT_MASK 0x00000001
+#define LF_TIMER_STATUS2_INTERRUPT_GET(x) (((x) & LF_TIMER_STATUS2_INTERRUPT_MASK) >> LF_TIMER_STATUS2_INTERRUPT_LSB)
+#define LF_TIMER_STATUS2_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS2_INTERRUPT_LSB) & LF_TIMER_STATUS2_INTERRUPT_MASK)
+
+#define LF_TIMER3_ADDRESS 0x00000078
+#define LF_TIMER3_OFFSET 0x00000078
+#define LF_TIMER3_TARGET_MSB 31
+#define LF_TIMER3_TARGET_LSB 0
+#define LF_TIMER3_TARGET_MASK 0xffffffff
+#define LF_TIMER3_TARGET_GET(x) (((x) & LF_TIMER3_TARGET_MASK) >> LF_TIMER3_TARGET_LSB)
+#define LF_TIMER3_TARGET_SET(x) (((x) << LF_TIMER3_TARGET_LSB) & LF_TIMER3_TARGET_MASK)
+
+#define LF_TIMER_COUNT3_ADDRESS 0x0000007c
+#define LF_TIMER_COUNT3_OFFSET 0x0000007c
+#define LF_TIMER_COUNT3_VALUE_MSB 31
+#define LF_TIMER_COUNT3_VALUE_LSB 0
+#define LF_TIMER_COUNT3_VALUE_MASK 0xffffffff
+#define LF_TIMER_COUNT3_VALUE_GET(x) (((x) & LF_TIMER_COUNT3_VALUE_MASK) >> LF_TIMER_COUNT3_VALUE_LSB)
+#define LF_TIMER_COUNT3_VALUE_SET(x) (((x) << LF_TIMER_COUNT3_VALUE_LSB) & LF_TIMER_COUNT3_VALUE_MASK)
+
+#define LF_TIMER_CONTROL3_ADDRESS 0x00000080
+#define LF_TIMER_CONTROL3_OFFSET 0x00000080
+#define LF_TIMER_CONTROL3_ENABLE_MSB 2
+#define LF_TIMER_CONTROL3_ENABLE_LSB 2
+#define LF_TIMER_CONTROL3_ENABLE_MASK 0x00000004
+#define LF_TIMER_CONTROL3_ENABLE_GET(x) (((x) & LF_TIMER_CONTROL3_ENABLE_MASK) >> LF_TIMER_CONTROL3_ENABLE_LSB)
+#define LF_TIMER_CONTROL3_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL3_ENABLE_LSB) & LF_TIMER_CONTROL3_ENABLE_MASK)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB 1
+#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB 1
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002
+#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) (((x) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL3_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) (((x) << LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL3_RESET_MSB 0
+#define LF_TIMER_CONTROL3_RESET_LSB 0
+#define LF_TIMER_CONTROL3_RESET_MASK 0x00000001
+#define LF_TIMER_CONTROL3_RESET_GET(x) (((x) & LF_TIMER_CONTROL3_RESET_MASK) >> LF_TIMER_CONTROL3_RESET_LSB)
+#define LF_TIMER_CONTROL3_RESET_SET(x) (((x) << LF_TIMER_CONTROL3_RESET_LSB) & LF_TIMER_CONTROL3_RESET_MASK)
+
+#define LF_TIMER_STATUS3_ADDRESS 0x00000084
+#define LF_TIMER_STATUS3_OFFSET 0x00000084
+#define LF_TIMER_STATUS3_INTERRUPT_MSB 0
+#define LF_TIMER_STATUS3_INTERRUPT_LSB 0
+#define LF_TIMER_STATUS3_INTERRUPT_MASK 0x00000001
+#define LF_TIMER_STATUS3_INTERRUPT_GET(x) (((x) & LF_TIMER_STATUS3_INTERRUPT_MASK) >> LF_TIMER_STATUS3_INTERRUPT_LSB)
+#define LF_TIMER_STATUS3_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS3_INTERRUPT_LSB) & LF_TIMER_STATUS3_INTERRUPT_MASK)
+
+#define HF_TIMER_ADDRESS 0x00000088
+#define HF_TIMER_OFFSET 0x00000088
+#define HF_TIMER_TARGET_MSB 31
+#define HF_TIMER_TARGET_LSB 12
+#define HF_TIMER_TARGET_MASK 0xfffff000
+#define HF_TIMER_TARGET_GET(x) (((x) & HF_TIMER_TARGET_MASK) >> HF_TIMER_TARGET_LSB)
+#define HF_TIMER_TARGET_SET(x) (((x) << HF_TIMER_TARGET_LSB) & HF_TIMER_TARGET_MASK)
+
+#define HF_TIMER_COUNT_ADDRESS 0x0000008c
+#define HF_TIMER_COUNT_OFFSET 0x0000008c
+#define HF_TIMER_COUNT_VALUE_MSB 31
+#define HF_TIMER_COUNT_VALUE_LSB 12
+#define HF_TIMER_COUNT_VALUE_MASK 0xfffff000
+#define HF_TIMER_COUNT_VALUE_GET(x) (((x) & HF_TIMER_COUNT_VALUE_MASK) >> HF_TIMER_COUNT_VALUE_LSB)
+#define HF_TIMER_COUNT_VALUE_SET(x) (((x) << HF_TIMER_COUNT_VALUE_LSB) & HF_TIMER_COUNT_VALUE_MASK)
+
+#define HF_LF_COUNT_ADDRESS 0x00000090
+#define HF_LF_COUNT_OFFSET 0x00000090
+#define HF_LF_COUNT_VALUE_MSB 31
+#define HF_LF_COUNT_VALUE_LSB 0
+#define HF_LF_COUNT_VALUE_MASK 0xffffffff
+#define HF_LF_COUNT_VALUE_GET(x) (((x) & HF_LF_COUNT_VALUE_MASK) >> HF_LF_COUNT_VALUE_LSB)
+#define HF_LF_COUNT_VALUE_SET(x) (((x) << HF_LF_COUNT_VALUE_LSB) & HF_LF_COUNT_VALUE_MASK)
+
+#define HF_TIMER_CONTROL_ADDRESS 0x00000094
+#define HF_TIMER_CONTROL_OFFSET 0x00000094
+#define HF_TIMER_CONTROL_ENABLE_MSB 3
+#define HF_TIMER_CONTROL_ENABLE_LSB 3
+#define HF_TIMER_CONTROL_ENABLE_MASK 0x00000008
+#define HF_TIMER_CONTROL_ENABLE_GET(x) (((x) & HF_TIMER_CONTROL_ENABLE_MASK) >> HF_TIMER_CONTROL_ENABLE_LSB)
+#define HF_TIMER_CONTROL_ENABLE_SET(x) (((x) << HF_TIMER_CONTROL_ENABLE_LSB) & HF_TIMER_CONTROL_ENABLE_MASK)
+#define HF_TIMER_CONTROL_ON_MSB 2
+#define HF_TIMER_CONTROL_ON_LSB 2
+#define HF_TIMER_CONTROL_ON_MASK 0x00000004
+#define HF_TIMER_CONTROL_ON_GET(x) (((x) & HF_TIMER_CONTROL_ON_MASK) >> HF_TIMER_CONTROL_ON_LSB)
+#define HF_TIMER_CONTROL_ON_SET(x) (((x) << HF_TIMER_CONTROL_ON_LSB) & HF_TIMER_CONTROL_ON_MASK)
+#define HF_TIMER_CONTROL_AUTO_RESTART_MSB 1
+#define HF_TIMER_CONTROL_AUTO_RESTART_LSB 1
+#define HF_TIMER_CONTROL_AUTO_RESTART_MASK 0x00000002
+#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x) (((x) & HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> HF_TIMER_CONTROL_AUTO_RESTART_LSB)
+#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x) (((x) << HF_TIMER_CONTROL_AUTO_RESTART_LSB) & HF_TIMER_CONTROL_AUTO_RESTART_MASK)
+#define HF_TIMER_CONTROL_RESET_MSB 0
+#define HF_TIMER_CONTROL_RESET_LSB 0
+#define HF_TIMER_CONTROL_RESET_MASK 0x00000001
+#define HF_TIMER_CONTROL_RESET_GET(x) (((x) & HF_TIMER_CONTROL_RESET_MASK) >> HF_TIMER_CONTROL_RESET_LSB)
+#define HF_TIMER_CONTROL_RESET_SET(x) (((x) << HF_TIMER_CONTROL_RESET_LSB) & HF_TIMER_CONTROL_RESET_MASK)
+
+#define HF_TIMER_STATUS_ADDRESS 0x00000098
+#define HF_TIMER_STATUS_OFFSET 0x00000098
+#define HF_TIMER_STATUS_INTERRUPT_MSB 0
+#define HF_TIMER_STATUS_INTERRUPT_LSB 0
+#define HF_TIMER_STATUS_INTERRUPT_MASK 0x00000001
+#define HF_TIMER_STATUS_INTERRUPT_GET(x) (((x) & HF_TIMER_STATUS_INTERRUPT_MASK) >> HF_TIMER_STATUS_INTERRUPT_LSB)
+#define HF_TIMER_STATUS_INTERRUPT_SET(x) (((x) << HF_TIMER_STATUS_INTERRUPT_LSB) & HF_TIMER_STATUS_INTERRUPT_MASK)
+
+#define RTC_CONTROL_ADDRESS 0x0000009c
+#define RTC_CONTROL_OFFSET 0x0000009c
+#define RTC_CONTROL_ENABLE_MSB 2
+#define RTC_CONTROL_ENABLE_LSB 2
+#define RTC_CONTROL_ENABLE_MASK 0x00000004
+#define RTC_CONTROL_ENABLE_GET(x) (((x) & RTC_CONTROL_ENABLE_MASK) >> RTC_CONTROL_ENABLE_LSB)
+#define RTC_CONTROL_ENABLE_SET(x) (((x) << RTC_CONTROL_ENABLE_LSB) & RTC_CONTROL_ENABLE_MASK)
+#define RTC_CONTROL_LOAD_RTC_MSB 1
+#define RTC_CONTROL_LOAD_RTC_LSB 1
+#define RTC_CONTROL_LOAD_RTC_MASK 0x00000002
+#define RTC_CONTROL_LOAD_RTC_GET(x) (((x) & RTC_CONTROL_LOAD_RTC_MASK) >> RTC_CONTROL_LOAD_RTC_LSB)
+#define RTC_CONTROL_LOAD_RTC_SET(x) (((x) << RTC_CONTROL_LOAD_RTC_LSB) & RTC_CONTROL_LOAD_RTC_MASK)
+#define RTC_CONTROL_LOAD_ALARM_MSB 0
+#define RTC_CONTROL_LOAD_ALARM_LSB 0
+#define RTC_CONTROL_LOAD_ALARM_MASK 0x00000001
+#define RTC_CONTROL_LOAD_ALARM_GET(x) (((x) & RTC_CONTROL_LOAD_ALARM_MASK) >> RTC_CONTROL_LOAD_ALARM_LSB)
+#define RTC_CONTROL_LOAD_ALARM_SET(x) (((x) << RTC_CONTROL_LOAD_ALARM_LSB) & RTC_CONTROL_LOAD_ALARM_MASK)
+
+#define RTC_TIME_ADDRESS 0x000000a0
+#define RTC_TIME_OFFSET 0x000000a0
+#define RTC_TIME_WEEK_DAY_MSB 26
+#define RTC_TIME_WEEK_DAY_LSB 24
+#define RTC_TIME_WEEK_DAY_MASK 0x07000000
+#define RTC_TIME_WEEK_DAY_GET(x) (((x) & RTC_TIME_WEEK_DAY_MASK) >> RTC_TIME_WEEK_DAY_LSB)
+#define RTC_TIME_WEEK_DAY_SET(x) (((x) << RTC_TIME_WEEK_DAY_LSB) & RTC_TIME_WEEK_DAY_MASK)
+#define RTC_TIME_HOUR_MSB 21
+#define RTC_TIME_HOUR_LSB 16
+#define RTC_TIME_HOUR_MASK 0x003f0000
+#define RTC_TIME_HOUR_GET(x) (((x) & RTC_TIME_HOUR_MASK) >> RTC_TIME_HOUR_LSB)
+#define RTC_TIME_HOUR_SET(x) (((x) << RTC_TIME_HOUR_LSB) & RTC_TIME_HOUR_MASK)
+#define RTC_TIME_MINUTE_MSB 14
+#define RTC_TIME_MINUTE_LSB 8
+#define RTC_TIME_MINUTE_MASK 0x00007f00
+#define RTC_TIME_MINUTE_GET(x) (((x) & RTC_TIME_MINUTE_MASK) >> RTC_TIME_MINUTE_LSB)
+#define RTC_TIME_MINUTE_SET(x) (((x) << RTC_TIME_MINUTE_LSB) & RTC_TIME_MINUTE_MASK)
+#define RTC_TIME_SECOND_MSB 6
+#define RTC_TIME_SECOND_LSB 0
+#define RTC_TIME_SECOND_MASK 0x0000007f
+#define RTC_TIME_SECOND_GET(x) (((x) & RTC_TIME_SECOND_MASK) >> RTC_TIME_SECOND_LSB)
+#define RTC_TIME_SECOND_SET(x) (((x) << RTC_TIME_SECOND_LSB) & RTC_TIME_SECOND_MASK)
+
+#define RTC_DATE_ADDRESS 0x000000a4
+#define RTC_DATE_OFFSET 0x000000a4
+#define RTC_DATE_YEAR_MSB 23
+#define RTC_DATE_YEAR_LSB 16
+#define RTC_DATE_YEAR_MASK 0x00ff0000
+#define RTC_DATE_YEAR_GET(x) (((x) & RTC_DATE_YEAR_MASK) >> RTC_DATE_YEAR_LSB)
+#define RTC_DATE_YEAR_SET(x) (((x) << RTC_DATE_YEAR_LSB) & RTC_DATE_YEAR_MASK)
+#define RTC_DATE_MONTH_MSB 12
+#define RTC_DATE_MONTH_LSB 8
+#define RTC_DATE_MONTH_MASK 0x00001f00
+#define RTC_DATE_MONTH_GET(x) (((x) & RTC_DATE_MONTH_MASK) >> RTC_DATE_MONTH_LSB)
+#define RTC_DATE_MONTH_SET(x) (((x) << RTC_DATE_MONTH_LSB) & RTC_DATE_MONTH_MASK)
+#define RTC_DATE_MONTH_DAY_MSB 5
+#define RTC_DATE_MONTH_DAY_LSB 0
+#define RTC_DATE_MONTH_DAY_MASK 0x0000003f
+#define RTC_DATE_MONTH_DAY_GET(x) (((x) & RTC_DATE_MONTH_DAY_MASK) >> RTC_DATE_MONTH_DAY_LSB)
+#define RTC_DATE_MONTH_DAY_SET(x) (((x) << RTC_DATE_MONTH_DAY_LSB) & RTC_DATE_MONTH_DAY_MASK)
+
+#define RTC_SET_TIME_ADDRESS 0x000000a8
+#define RTC_SET_TIME_OFFSET 0x000000a8
+#define RTC_SET_TIME_WEEK_DAY_MSB 26
+#define RTC_SET_TIME_WEEK_DAY_LSB 24
+#define RTC_SET_TIME_WEEK_DAY_MASK 0x07000000
+#define RTC_SET_TIME_WEEK_DAY_GET(x) (((x) & RTC_SET_TIME_WEEK_DAY_MASK) >> RTC_SET_TIME_WEEK_DAY_LSB)
+#define RTC_SET_TIME_WEEK_DAY_SET(x) (((x) << RTC_SET_TIME_WEEK_DAY_LSB) & RTC_SET_TIME_WEEK_DAY_MASK)
+#define RTC_SET_TIME_HOUR_MSB 21
+#define RTC_SET_TIME_HOUR_LSB 16
+#define RTC_SET_TIME_HOUR_MASK 0x003f0000
+#define RTC_SET_TIME_HOUR_GET(x) (((x) & RTC_SET_TIME_HOUR_MASK) >> RTC_SET_TIME_HOUR_LSB)
+#define RTC_SET_TIME_HOUR_SET(x) (((x) << RTC_SET_TIME_HOUR_LSB) & RTC_SET_TIME_HOUR_MASK)
+#define RTC_SET_TIME_MINUTE_MSB 14
+#define RTC_SET_TIME_MINUTE_LSB 8
+#define RTC_SET_TIME_MINUTE_MASK 0x00007f00
+#define RTC_SET_TIME_MINUTE_GET(x) (((x) & RTC_SET_TIME_MINUTE_MASK) >> RTC_SET_TIME_MINUTE_LSB)
+#define RTC_SET_TIME_MINUTE_SET(x) (((x) << RTC_SET_TIME_MINUTE_LSB) & RTC_SET_TIME_MINUTE_MASK)
+#define RTC_SET_TIME_SECOND_MSB 6
+#define RTC_SET_TIME_SECOND_LSB 0
+#define RTC_SET_TIME_SECOND_MASK 0x0000007f
+#define RTC_SET_TIME_SECOND_GET(x) (((x) & RTC_SET_TIME_SECOND_MASK) >> RTC_SET_TIME_SECOND_LSB)
+#define RTC_SET_TIME_SECOND_SET(x) (((x) << RTC_SET_TIME_SECOND_LSB) & RTC_SET_TIME_SECOND_MASK)
+
+#define RTC_SET_DATE_ADDRESS 0x000000ac
+#define RTC_SET_DATE_OFFSET 0x000000ac
+#define RTC_SET_DATE_YEAR_MSB 23
+#define RTC_SET_DATE_YEAR_LSB 16
+#define RTC_SET_DATE_YEAR_MASK 0x00ff0000
+#define RTC_SET_DATE_YEAR_GET(x) (((x) & RTC_SET_DATE_YEAR_MASK) >> RTC_SET_DATE_YEAR_LSB)
+#define RTC_SET_DATE_YEAR_SET(x) (((x) << RTC_SET_DATE_YEAR_LSB) & RTC_SET_DATE_YEAR_MASK)
+#define RTC_SET_DATE_MONTH_MSB 12
+#define RTC_SET_DATE_MONTH_LSB 8
+#define RTC_SET_DATE_MONTH_MASK 0x00001f00
+#define RTC_SET_DATE_MONTH_GET(x) (((x) & RTC_SET_DATE_MONTH_MASK) >> RTC_SET_DATE_MONTH_LSB)
+#define RTC_SET_DATE_MONTH_SET(x) (((x) << RTC_SET_DATE_MONTH_LSB) & RTC_SET_DATE_MONTH_MASK)
+#define RTC_SET_DATE_MONTH_DAY_MSB 5
+#define RTC_SET_DATE_MONTH_DAY_LSB 0
+#define RTC_SET_DATE_MONTH_DAY_MASK 0x0000003f
+#define RTC_SET_DATE_MONTH_DAY_GET(x) (((x) & RTC_SET_DATE_MONTH_DAY_MASK) >> RTC_SET_DATE_MONTH_DAY_LSB)
+#define RTC_SET_DATE_MONTH_DAY_SET(x) (((x) << RTC_SET_DATE_MONTH_DAY_LSB) & RTC_SET_DATE_MONTH_DAY_MASK)
+
+#define RTC_SET_ALARM_ADDRESS 0x000000b0
+#define RTC_SET_ALARM_OFFSET 0x000000b0
+#define RTC_SET_ALARM_HOUR_MSB 21
+#define RTC_SET_ALARM_HOUR_LSB 16
+#define RTC_SET_ALARM_HOUR_MASK 0x003f0000
+#define RTC_SET_ALARM_HOUR_GET(x) (((x) & RTC_SET_ALARM_HOUR_MASK) >> RTC_SET_ALARM_HOUR_LSB)
+#define RTC_SET_ALARM_HOUR_SET(x) (((x) << RTC_SET_ALARM_HOUR_LSB) & RTC_SET_ALARM_HOUR_MASK)
+#define RTC_SET_ALARM_MINUTE_MSB 14
+#define RTC_SET_ALARM_MINUTE_LSB 8
+#define RTC_SET_ALARM_MINUTE_MASK 0x00007f00
+#define RTC_SET_ALARM_MINUTE_GET(x) (((x) & RTC_SET_ALARM_MINUTE_MASK) >> RTC_SET_ALARM_MINUTE_LSB)
+#define RTC_SET_ALARM_MINUTE_SET(x) (((x) << RTC_SET_ALARM_MINUTE_LSB) & RTC_SET_ALARM_MINUTE_MASK)
+#define RTC_SET_ALARM_SECOND_MSB 6
+#define RTC_SET_ALARM_SECOND_LSB 0
+#define RTC_SET_ALARM_SECOND_MASK 0x0000007f
+#define RTC_SET_ALARM_SECOND_GET(x) (((x) & RTC_SET_ALARM_SECOND_MASK) >> RTC_SET_ALARM_SECOND_LSB)
+#define RTC_SET_ALARM_SECOND_SET(x) (((x) << RTC_SET_ALARM_SECOND_LSB) & RTC_SET_ALARM_SECOND_MASK)
+
+#define RTC_CONFIG_ADDRESS 0x000000b4
+#define RTC_CONFIG_OFFSET 0x000000b4
+#define RTC_CONFIG_BCD_MSB 2
+#define RTC_CONFIG_BCD_LSB 2
+#define RTC_CONFIG_BCD_MASK 0x00000004
+#define RTC_CONFIG_BCD_GET(x) (((x) & RTC_CONFIG_BCD_MASK) >> RTC_CONFIG_BCD_LSB)
+#define RTC_CONFIG_BCD_SET(x) (((x) << RTC_CONFIG_BCD_LSB) & RTC_CONFIG_BCD_MASK)
+#define RTC_CONFIG_TWELVE_HOUR_MSB 1
+#define RTC_CONFIG_TWELVE_HOUR_LSB 1
+#define RTC_CONFIG_TWELVE_HOUR_MASK 0x00000002
+#define RTC_CONFIG_TWELVE_HOUR_GET(x) (((x) & RTC_CONFIG_TWELVE_HOUR_MASK) >> RTC_CONFIG_TWELVE_HOUR_LSB)
+#define RTC_CONFIG_TWELVE_HOUR_SET(x) (((x) << RTC_CONFIG_TWELVE_HOUR_LSB) & RTC_CONFIG_TWELVE_HOUR_MASK)
+#define RTC_CONFIG_DSE_MSB 0
+#define RTC_CONFIG_DSE_LSB 0
+#define RTC_CONFIG_DSE_MASK 0x00000001
+#define RTC_CONFIG_DSE_GET(x) (((x) & RTC_CONFIG_DSE_MASK) >> RTC_CONFIG_DSE_LSB)
+#define RTC_CONFIG_DSE_SET(x) (((x) << RTC_CONFIG_DSE_LSB) & RTC_CONFIG_DSE_MASK)
+
+#define RTC_ALARM_STATUS_ADDRESS 0x000000b8
+#define RTC_ALARM_STATUS_OFFSET 0x000000b8
+#define RTC_ALARM_STATUS_ENABLE_MSB 1
+#define RTC_ALARM_STATUS_ENABLE_LSB 1
+#define RTC_ALARM_STATUS_ENABLE_MASK 0x00000002
+#define RTC_ALARM_STATUS_ENABLE_GET(x) (((x) & RTC_ALARM_STATUS_ENABLE_MASK) >> RTC_ALARM_STATUS_ENABLE_LSB)
+#define RTC_ALARM_STATUS_ENABLE_SET(x) (((x) << RTC_ALARM_STATUS_ENABLE_LSB) & RTC_ALARM_STATUS_ENABLE_MASK)
+#define RTC_ALARM_STATUS_INTERRUPT_MSB 0
+#define RTC_ALARM_STATUS_INTERRUPT_LSB 0
+#define RTC_ALARM_STATUS_INTERRUPT_MASK 0x00000001
+#define RTC_ALARM_STATUS_INTERRUPT_GET(x) (((x) & RTC_ALARM_STATUS_INTERRUPT_MASK) >> RTC_ALARM_STATUS_INTERRUPT_LSB)
+#define RTC_ALARM_STATUS_INTERRUPT_SET(x) (((x) << RTC_ALARM_STATUS_INTERRUPT_LSB) & RTC_ALARM_STATUS_INTERRUPT_MASK)
+
+#define UART_WAKEUP_ADDRESS 0x000000bc
+#define UART_WAKEUP_OFFSET 0x000000bc
+#define UART_WAKEUP_ENABLE_MSB 0
+#define UART_WAKEUP_ENABLE_LSB 0
+#define UART_WAKEUP_ENABLE_MASK 0x00000001
+#define UART_WAKEUP_ENABLE_GET(x) (((x) & UART_WAKEUP_ENABLE_MASK) >> UART_WAKEUP_ENABLE_LSB)
+#define UART_WAKEUP_ENABLE_SET(x) (((x) << UART_WAKEUP_ENABLE_LSB) & UART_WAKEUP_ENABLE_MASK)
+
+#define RESET_CAUSE_ADDRESS 0x000000c0
+#define RESET_CAUSE_OFFSET 0x000000c0
+#define RESET_CAUSE_LAST_MSB 2
+#define RESET_CAUSE_LAST_LSB 0
+#define RESET_CAUSE_LAST_MASK 0x00000007
+#define RESET_CAUSE_LAST_GET(x) (((x) & RESET_CAUSE_LAST_MASK) >> RESET_CAUSE_LAST_LSB)
+#define RESET_CAUSE_LAST_SET(x) (((x) << RESET_CAUSE_LAST_LSB) & RESET_CAUSE_LAST_MASK)
+
+#define SYSTEM_SLEEP_ADDRESS 0x000000c4
+#define SYSTEM_SLEEP_OFFSET 0x000000c4
+#define SYSTEM_SLEEP_HOST_IF_MSB 4
+#define SYSTEM_SLEEP_HOST_IF_LSB 4
+#define SYSTEM_SLEEP_HOST_IF_MASK 0x00000010
+#define SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & SYSTEM_SLEEP_HOST_IF_MASK) >> SYSTEM_SLEEP_HOST_IF_LSB)
+#define SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << SYSTEM_SLEEP_HOST_IF_LSB) & SYSTEM_SLEEP_HOST_IF_MASK)
+#define SYSTEM_SLEEP_MBOX_MSB 3
+#define SYSTEM_SLEEP_MBOX_LSB 3
+#define SYSTEM_SLEEP_MBOX_MASK 0x00000008
+#define SYSTEM_SLEEP_MBOX_GET(x) (((x) & SYSTEM_SLEEP_MBOX_MASK) >> SYSTEM_SLEEP_MBOX_LSB)
+#define SYSTEM_SLEEP_MBOX_SET(x) (((x) << SYSTEM_SLEEP_MBOX_LSB) & SYSTEM_SLEEP_MBOX_MASK)
+#define SYSTEM_SLEEP_MAC_IF_MSB 2
+#define SYSTEM_SLEEP_MAC_IF_LSB 2
+#define SYSTEM_SLEEP_MAC_IF_MASK 0x00000004
+#define SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & SYSTEM_SLEEP_MAC_IF_MASK) >> SYSTEM_SLEEP_MAC_IF_LSB)
+#define SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << SYSTEM_SLEEP_MAC_IF_LSB) & SYSTEM_SLEEP_MAC_IF_MASK)
+#define SYSTEM_SLEEP_LIGHT_MSB 1
+#define SYSTEM_SLEEP_LIGHT_LSB 1
+#define SYSTEM_SLEEP_LIGHT_MASK 0x00000002
+#define SYSTEM_SLEEP_LIGHT_GET(x) (((x) & SYSTEM_SLEEP_LIGHT_MASK) >> SYSTEM_SLEEP_LIGHT_LSB)
+#define SYSTEM_SLEEP_LIGHT_SET(x) (((x) << SYSTEM_SLEEP_LIGHT_LSB) & SYSTEM_SLEEP_LIGHT_MASK)
+#define SYSTEM_SLEEP_DISABLE_MSB 0
+#define SYSTEM_SLEEP_DISABLE_LSB 0
+#define SYSTEM_SLEEP_DISABLE_MASK 0x00000001
+#define SYSTEM_SLEEP_DISABLE_GET(x) (((x) & SYSTEM_SLEEP_DISABLE_MASK) >> SYSTEM_SLEEP_DISABLE_LSB)
+#define SYSTEM_SLEEP_DISABLE_SET(x) (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK)
+
+#define SDIO_WRAPPER_ADDRESS 0x000000c8
+#define SDIO_WRAPPER_OFFSET 0x000000c8
+#define SDIO_WRAPPER_SLEEP_MSB 3
+#define SDIO_WRAPPER_SLEEP_LSB 3
+#define SDIO_WRAPPER_SLEEP_MASK 0x00000008
+#define SDIO_WRAPPER_SLEEP_GET(x) (((x) & SDIO_WRAPPER_SLEEP_MASK) >> SDIO_WRAPPER_SLEEP_LSB)
+#define SDIO_WRAPPER_SLEEP_SET(x) (((x) << SDIO_WRAPPER_SLEEP_LSB) & SDIO_WRAPPER_SLEEP_MASK)
+#define SDIO_WRAPPER_WAKEUP_MSB 2
+#define SDIO_WRAPPER_WAKEUP_LSB 2
+#define SDIO_WRAPPER_WAKEUP_MASK 0x00000004
+#define SDIO_WRAPPER_WAKEUP_GET(x) (((x) & SDIO_WRAPPER_WAKEUP_MASK) >> SDIO_WRAPPER_WAKEUP_LSB)
+#define SDIO_WRAPPER_WAKEUP_SET(x) (((x) << SDIO_WRAPPER_WAKEUP_LSB) & SDIO_WRAPPER_WAKEUP_MASK)
+#define SDIO_WRAPPER_SOC_ON_MSB 1
+#define SDIO_WRAPPER_SOC_ON_LSB 1
+#define SDIO_WRAPPER_SOC_ON_MASK 0x00000002
+#define SDIO_WRAPPER_SOC_ON_GET(x) (((x) & SDIO_WRAPPER_SOC_ON_MASK) >> SDIO_WRAPPER_SOC_ON_LSB)
+#define SDIO_WRAPPER_SOC_ON_SET(x) (((x) << SDIO_WRAPPER_SOC_ON_LSB) & SDIO_WRAPPER_SOC_ON_MASK)
+#define SDIO_WRAPPER_ON_MSB 0
+#define SDIO_WRAPPER_ON_LSB 0
+#define SDIO_WRAPPER_ON_MASK 0x00000001
+#define SDIO_WRAPPER_ON_GET(x) (((x) & SDIO_WRAPPER_ON_MASK) >> SDIO_WRAPPER_ON_LSB)
+#define SDIO_WRAPPER_ON_SET(x) (((x) << SDIO_WRAPPER_ON_LSB) & SDIO_WRAPPER_ON_MASK)
+
+#define MAC_SLEEP_CONTROL_ADDRESS 0x000000cc
+#define MAC_SLEEP_CONTROL_OFFSET 0x000000cc
+#define MAC_SLEEP_CONTROL_ENABLE_MSB 1
+#define MAC_SLEEP_CONTROL_ENABLE_LSB 0
+#define MAC_SLEEP_CONTROL_ENABLE_MASK 0x00000003
+#define MAC_SLEEP_CONTROL_ENABLE_GET(x) (((x) & MAC_SLEEP_CONTROL_ENABLE_MASK) >> MAC_SLEEP_CONTROL_ENABLE_LSB)
+#define MAC_SLEEP_CONTROL_ENABLE_SET(x) (((x) << MAC_SLEEP_CONTROL_ENABLE_LSB) & MAC_SLEEP_CONTROL_ENABLE_MASK)
+
+#define KEEP_AWAKE_ADDRESS 0x000000d0
+#define KEEP_AWAKE_OFFSET 0x000000d0
+#define KEEP_AWAKE_COUNT_MSB 7
+#define KEEP_AWAKE_COUNT_LSB 0
+#define KEEP_AWAKE_COUNT_MASK 0x000000ff
+#define KEEP_AWAKE_COUNT_GET(x) (((x) & KEEP_AWAKE_COUNT_MASK) >> KEEP_AWAKE_COUNT_LSB)
+#define KEEP_AWAKE_COUNT_SET(x) (((x) << KEEP_AWAKE_COUNT_LSB) & KEEP_AWAKE_COUNT_MASK)
+
+#define LPO_CAL_TIME_ADDRESS 0x000000d4
+#define LPO_CAL_TIME_OFFSET 0x000000d4
+#define LPO_CAL_TIME_LENGTH_MSB 13
+#define LPO_CAL_TIME_LENGTH_LSB 0
+#define LPO_CAL_TIME_LENGTH_MASK 0x00003fff
+#define LPO_CAL_TIME_LENGTH_GET(x) (((x) & LPO_CAL_TIME_LENGTH_MASK) >> LPO_CAL_TIME_LENGTH_LSB)
+#define LPO_CAL_TIME_LENGTH_SET(x) (((x) << LPO_CAL_TIME_LENGTH_LSB) & LPO_CAL_TIME_LENGTH_MASK)
+
+#define LPO_INIT_DIVIDEND_INT_ADDRESS 0x000000d8
+#define LPO_INIT_DIVIDEND_INT_OFFSET 0x000000d8
+#define LPO_INIT_DIVIDEND_INT_VALUE_MSB 23
+#define LPO_INIT_DIVIDEND_INT_VALUE_LSB 0
+#define LPO_INIT_DIVIDEND_INT_VALUE_MASK 0x00ffffff
+#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) (((x) & LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> LPO_INIT_DIVIDEND_INT_VALUE_LSB)
+#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) (((x) << LPO_INIT_DIVIDEND_INT_VALUE_LSB) & LPO_INIT_DIVIDEND_INT_VALUE_MASK)
+
+#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS 0x000000dc
+#define LPO_INIT_DIVIDEND_FRACTION_OFFSET 0x000000dc
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) (((x) & LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB)
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) (((x) << LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK)
+
+#define LPO_CAL_ADDRESS 0x000000e0
+#define LPO_CAL_OFFSET 0x000000e0
+#define LPO_CAL_ENABLE_MSB 20
+#define LPO_CAL_ENABLE_LSB 20
+#define LPO_CAL_ENABLE_MASK 0x00100000
+#define LPO_CAL_ENABLE_GET(x) (((x) & LPO_CAL_ENABLE_MASK) >> LPO_CAL_ENABLE_LSB)
+#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK)
+#define LPO_CAL_COUNT_MSB 19
+#define LPO_CAL_COUNT_LSB 0
+#define LPO_CAL_COUNT_MASK 0x000fffff
+#define LPO_CAL_COUNT_GET(x) (((x) & LPO_CAL_COUNT_MASK) >> LPO_CAL_COUNT_LSB)
+#define LPO_CAL_COUNT_SET(x) (((x) << LPO_CAL_COUNT_LSB) & LPO_CAL_COUNT_MASK)
+
+#define LPO_CAL_TEST_CONTROL_ADDRESS 0x000000e4
+#define LPO_CAL_TEST_CONTROL_OFFSET 0x000000e4
+#define LPO_CAL_TEST_CONTROL_ENABLE_MSB 5
+#define LPO_CAL_TEST_CONTROL_ENABLE_LSB 5
+#define LPO_CAL_TEST_CONTROL_ENABLE_MASK 0x00000020
+#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x) (((x) & LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> LPO_CAL_TEST_CONTROL_ENABLE_LSB)
+#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x) (((x) << LPO_CAL_TEST_CONTROL_ENABLE_LSB) & LPO_CAL_TEST_CONTROL_ENABLE_MASK)
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 4
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000001f
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) (((x) & LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB)
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) (((x) << LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK)
+
+#define LPO_CAL_TEST_STATUS_ADDRESS 0x000000e8
+#define LPO_CAL_TEST_STATUS_OFFSET 0x000000e8
+#define LPO_CAL_TEST_STATUS_READY_MSB 16
+#define LPO_CAL_TEST_STATUS_READY_LSB 16
+#define LPO_CAL_TEST_STATUS_READY_MASK 0x00010000
+#define LPO_CAL_TEST_STATUS_READY_GET(x) (((x) & LPO_CAL_TEST_STATUS_READY_MASK) >> LPO_CAL_TEST_STATUS_READY_LSB)
+#define LPO_CAL_TEST_STATUS_READY_SET(x) (((x) << LPO_CAL_TEST_STATUS_READY_LSB) & LPO_CAL_TEST_STATUS_READY_MASK)
+#define LPO_CAL_TEST_STATUS_COUNT_MSB 15
+#define LPO_CAL_TEST_STATUS_COUNT_LSB 0
+#define LPO_CAL_TEST_STATUS_COUNT_MASK 0x0000ffff
+#define LPO_CAL_TEST_STATUS_COUNT_GET(x) (((x) & LPO_CAL_TEST_STATUS_COUNT_MASK) >> LPO_CAL_TEST_STATUS_COUNT_LSB)
+#define LPO_CAL_TEST_STATUS_COUNT_SET(x) (((x) << LPO_CAL_TEST_STATUS_COUNT_LSB) & LPO_CAL_TEST_STATUS_COUNT_MASK)
+
+#define CHIP_ID_ADDRESS 0x000000ec
+#define CHIP_ID_OFFSET 0x000000ec
+#define CHIP_ID_DEVICE_ID_MSB 31
+#define CHIP_ID_DEVICE_ID_LSB 16
+#define CHIP_ID_DEVICE_ID_MASK 0xffff0000
+#define CHIP_ID_DEVICE_ID_GET(x) (((x) & CHIP_ID_DEVICE_ID_MASK) >> CHIP_ID_DEVICE_ID_LSB)
+#define CHIP_ID_DEVICE_ID_SET(x) (((x) << CHIP_ID_DEVICE_ID_LSB) & CHIP_ID_DEVICE_ID_MASK)
+#define CHIP_ID_CONFIG_ID_MSB 15
+#define CHIP_ID_CONFIG_ID_LSB 4
+#define CHIP_ID_CONFIG_ID_MASK 0x0000fff0
+#define CHIP_ID_CONFIG_ID_GET(x) (((x) & CHIP_ID_CONFIG_ID_MASK) >> CHIP_ID_CONFIG_ID_LSB)
+#define CHIP_ID_CONFIG_ID_SET(x) (((x) << CHIP_ID_CONFIG_ID_LSB) & CHIP_ID_CONFIG_ID_MASK)
+#define CHIP_ID_VERSION_ID_MSB 3
+#define CHIP_ID_VERSION_ID_LSB 0
+#define CHIP_ID_VERSION_ID_MASK 0x0000000f
+#define CHIP_ID_VERSION_ID_GET(x) (((x) & CHIP_ID_VERSION_ID_MASK) >> CHIP_ID_VERSION_ID_LSB)
+#define CHIP_ID_VERSION_ID_SET(x) (((x) << CHIP_ID_VERSION_ID_LSB) & CHIP_ID_VERSION_ID_MASK)
+
+#define DERIVED_RTC_CLK_ADDRESS 0x000000f0
+#define DERIVED_RTC_CLK_OFFSET 0x000000f0
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB 20
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB 20
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK 0x00100000
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) (((x) & DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB 18
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB 18
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK 0x00040000
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) (((x) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK)
+#define DERIVED_RTC_CLK_FORCE_MSB 17
+#define DERIVED_RTC_CLK_FORCE_LSB 16
+#define DERIVED_RTC_CLK_FORCE_MASK 0x00030000
+#define DERIVED_RTC_CLK_FORCE_GET(x) (((x) & DERIVED_RTC_CLK_FORCE_MASK) >> DERIVED_RTC_CLK_FORCE_LSB)
+#define DERIVED_RTC_CLK_FORCE_SET(x) (((x) << DERIVED_RTC_CLK_FORCE_LSB) & DERIVED_RTC_CLK_FORCE_MASK)
+#define DERIVED_RTC_CLK_PERIOD_MSB 15
+#define DERIVED_RTC_CLK_PERIOD_LSB 1
+#define DERIVED_RTC_CLK_PERIOD_MASK 0x0000fffe
+#define DERIVED_RTC_CLK_PERIOD_GET(x) (((x) & DERIVED_RTC_CLK_PERIOD_MASK) >> DERIVED_RTC_CLK_PERIOD_LSB)
+#define DERIVED_RTC_CLK_PERIOD_SET(x) (((x) << DERIVED_RTC_CLK_PERIOD_LSB) & DERIVED_RTC_CLK_PERIOD_MASK)
+
+#define MAC_PCU_SLP32_MODE_ADDRESS 0x000000f4
+#define MAC_PCU_SLP32_MODE_OFFSET 0x000000f4
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MSB 21
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB 21
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK 0x00200000
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB)
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK)
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB 19
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB 0
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) (((x) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB)
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK)
+
+#define MAC_PCU_SLP32_WAKE_ADDRESS 0x000000f8
+#define MAC_PCU_SLP32_WAKE_OFFSET 0x000000f8
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB 15
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB 0
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK 0x0000ffff
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x) (((x) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB)
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x) (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK)
+
+#define MAC_PCU_SLP32_INC_ADDRESS 0x000000fc
+#define MAC_PCU_SLP32_INC_OFFSET 0x000000fc
+#define MAC_PCU_SLP32_INC_TSF_INC_MSB 19
+#define MAC_PCU_SLP32_INC_TSF_INC_LSB 0
+#define MAC_PCU_SLP32_INC_TSF_INC_MASK 0x000fffff
+#define MAC_PCU_SLP32_INC_TSF_INC_GET(x) (((x) & MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB)
+#define MAC_PCU_SLP32_INC_TSF_INC_SET(x) (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK)
+
+#define MAC_PCU_SLP_MIB1_ADDRESS 0x00000100
+#define MAC_PCU_SLP_MIB1_OFFSET 0x00000100
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB 31
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB 0
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK 0xffffffff
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB)
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK)
+
+#define MAC_PCU_SLP_MIB2_ADDRESS 0x00000104
+#define MAC_PCU_SLP_MIB2_OFFSET 0x00000104
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB 31
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB 0
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK 0xffffffff
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB)
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK)
+
+#define MAC_PCU_SLP_MIB3_ADDRESS 0x00000108
+#define MAC_PCU_SLP_MIB3_OFFSET 0x00000108
+#define MAC_PCU_SLP_MIB3_PENDING_MSB 1
+#define MAC_PCU_SLP_MIB3_PENDING_LSB 1
+#define MAC_PCU_SLP_MIB3_PENDING_MASK 0x00000002
+#define MAC_PCU_SLP_MIB3_PENDING_GET(x) (((x) & MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB)
+#define MAC_PCU_SLP_MIB3_PENDING_SET(x) (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK)
+#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB 0
+#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB 0
+#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK 0x00000001
+#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB)
+#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK)
+
+#define MAC_PCU_SLP_BEACON_ADDRESS 0x0000010c
+#define MAC_PCU_SLP_BEACON_OFFSET 0x0000010c
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MSB 24
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB 24
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK 0x01000000
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_GET(x) (((x) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB)
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_SET(x) (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK)
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MSB 23
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB 0
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK 0x00ffffff
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_GET(x) (((x) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB)
+#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_SET(x) (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK)
+
+#define POWER_REG_ADDRESS 0x00000110
+#define POWER_REG_OFFSET 0x00000110
+#define POWER_REG_VLVL_MSB 11
+#define POWER_REG_VLVL_LSB 8
+#define POWER_REG_VLVL_MASK 0x00000f00
+#define POWER_REG_VLVL_GET(x) (((x) & POWER_REG_VLVL_MASK) >> POWER_REG_VLVL_LSB)
+#define POWER_REG_VLVL_SET(x) (((x) << POWER_REG_VLVL_LSB) & POWER_REG_VLVL_MASK)
+#define POWER_REG_CPU_INT_ENABLE_MSB 7
+#define POWER_REG_CPU_INT_ENABLE_LSB 7
+#define POWER_REG_CPU_INT_ENABLE_MASK 0x00000080
+#define POWER_REG_CPU_INT_ENABLE_GET(x) (((x) & POWER_REG_CPU_INT_ENABLE_MASK) >> POWER_REG_CPU_INT_ENABLE_LSB)
+#define POWER_REG_CPU_INT_ENABLE_SET(x) (((x) << POWER_REG_CPU_INT_ENABLE_LSB) & POWER_REG_CPU_INT_ENABLE_MASK)
+#define POWER_REG_WLAN_ISO_DIS_MSB 6
+#define POWER_REG_WLAN_ISO_DIS_LSB 6
+#define POWER_REG_WLAN_ISO_DIS_MASK 0x00000040
+#define POWER_REG_WLAN_ISO_DIS_GET(x) (((x) & POWER_REG_WLAN_ISO_DIS_MASK) >> POWER_REG_WLAN_ISO_DIS_LSB)
+#define POWER_REG_WLAN_ISO_DIS_SET(x) (((x) << POWER_REG_WLAN_ISO_DIS_LSB) & POWER_REG_WLAN_ISO_DIS_MASK)
+#define POWER_REG_WLAN_ISO_CNTL_MSB 5
+#define POWER_REG_WLAN_ISO_CNTL_LSB 5
+#define POWER_REG_WLAN_ISO_CNTL_MASK 0x00000020
+#define POWER_REG_WLAN_ISO_CNTL_GET(x) (((x) & POWER_REG_WLAN_ISO_CNTL_MASK) >> POWER_REG_WLAN_ISO_CNTL_LSB)
+#define POWER_REG_WLAN_ISO_CNTL_SET(x) (((x) << POWER_REG_WLAN_ISO_CNTL_LSB) & POWER_REG_WLAN_ISO_CNTL_MASK)
+#define POWER_REG_RADIO_PWD_EN_MSB 4
+#define POWER_REG_RADIO_PWD_EN_LSB 4
+#define POWER_REG_RADIO_PWD_EN_MASK 0x00000010
+#define POWER_REG_RADIO_PWD_EN_GET(x) (((x) & POWER_REG_RADIO_PWD_EN_MASK) >> POWER_REG_RADIO_PWD_EN_LSB)
+#define POWER_REG_RADIO_PWD_EN_SET(x) (((x) << POWER_REG_RADIO_PWD_EN_LSB) & POWER_REG_RADIO_PWD_EN_MASK)
+#define POWER_REG_SOC_SCALE_EN_MSB 3
+#define POWER_REG_SOC_SCALE_EN_LSB 3
+#define POWER_REG_SOC_SCALE_EN_MASK 0x00000008
+#define POWER_REG_SOC_SCALE_EN_GET(x) (((x) & POWER_REG_SOC_SCALE_EN_MASK) >> POWER_REG_SOC_SCALE_EN_LSB)
+#define POWER_REG_SOC_SCALE_EN_SET(x) (((x) << POWER_REG_SOC_SCALE_EN_LSB) & POWER_REG_SOC_SCALE_EN_MASK)
+#define POWER_REG_WLAN_SCALE_EN_MSB 2
+#define POWER_REG_WLAN_SCALE_EN_LSB 2
+#define POWER_REG_WLAN_SCALE_EN_MASK 0x00000004
+#define POWER_REG_WLAN_SCALE_EN_GET(x) (((x) & POWER_REG_WLAN_SCALE_EN_MASK) >> POWER_REG_WLAN_SCALE_EN_LSB)
+#define POWER_REG_WLAN_SCALE_EN_SET(x) (((x) << POWER_REG_WLAN_SCALE_EN_LSB) & POWER_REG_WLAN_SCALE_EN_MASK)
+#define POWER_REG_WLAN_PWD_EN_MSB 1
+#define POWER_REG_WLAN_PWD_EN_LSB 1
+#define POWER_REG_WLAN_PWD_EN_MASK 0x00000002
+#define POWER_REG_WLAN_PWD_EN_GET(x) (((x) & POWER_REG_WLAN_PWD_EN_MASK) >> POWER_REG_WLAN_PWD_EN_LSB)
+#define POWER_REG_WLAN_PWD_EN_SET(x) (((x) << POWER_REG_WLAN_PWD_EN_LSB) & POWER_REG_WLAN_PWD_EN_MASK)
+#define POWER_REG_POWER_EN_MSB 0
+#define POWER_REG_POWER_EN_LSB 0
+#define POWER_REG_POWER_EN_MASK 0x00000001
+#define POWER_REG_POWER_EN_GET(x) (((x) & POWER_REG_POWER_EN_MASK) >> POWER_REG_POWER_EN_LSB)
+#define POWER_REG_POWER_EN_SET(x) (((x) << POWER_REG_POWER_EN_LSB) & POWER_REG_POWER_EN_MASK)
+
+#define CORE_CLK_CTRL_ADDRESS 0x00000114
+#define CORE_CLK_CTRL_OFFSET 0x00000114
+#define CORE_CLK_CTRL_DIV_MSB 2
+#define CORE_CLK_CTRL_DIV_LSB 0
+#define CORE_CLK_CTRL_DIV_MASK 0x00000007
+#define CORE_CLK_CTRL_DIV_GET(x) (((x) & CORE_CLK_CTRL_DIV_MASK) >> CORE_CLK_CTRL_DIV_LSB)
+#define CORE_CLK_CTRL_DIV_SET(x) (((x) << CORE_CLK_CTRL_DIV_LSB) & CORE_CLK_CTRL_DIV_MASK)
+
+#define SDIO_SETUP_CIRCUIT_ADDRESS 0x00000120
+#define SDIO_SETUP_CIRCUIT_OFFSET 0x00000120
+#define SDIO_SETUP_CIRCUIT_VECTOR_MSB 7
+#define SDIO_SETUP_CIRCUIT_VECTOR_LSB 0
+#define SDIO_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff
+#define SDIO_SETUP_CIRCUIT_VECTOR_GET(x) (((x) & SDIO_SETUP_CIRCUIT_VECTOR_MASK) >> SDIO_SETUP_CIRCUIT_VECTOR_LSB)
+#define SDIO_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << SDIO_SETUP_CIRCUIT_VECTOR_LSB) & SDIO_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define SDIO_SETUP_CONFIG_ADDRESS 0x00000140
+#define SDIO_SETUP_CONFIG_OFFSET 0x00000140
+#define SDIO_SETUP_CONFIG_ENABLE_MSB 1
+#define SDIO_SETUP_CONFIG_ENABLE_LSB 1
+#define SDIO_SETUP_CONFIG_ENABLE_MASK 0x00000002
+#define SDIO_SETUP_CONFIG_ENABLE_GET(x) (((x) & SDIO_SETUP_CONFIG_ENABLE_MASK) >> SDIO_SETUP_CONFIG_ENABLE_LSB)
+#define SDIO_SETUP_CONFIG_ENABLE_SET(x) (((x) << SDIO_SETUP_CONFIG_ENABLE_LSB) & SDIO_SETUP_CONFIG_ENABLE_MASK)
+#define SDIO_SETUP_CONFIG_CLEAR_MSB 0
+#define SDIO_SETUP_CONFIG_CLEAR_LSB 0
+#define SDIO_SETUP_CONFIG_CLEAR_MASK 0x00000001
+#define SDIO_SETUP_CONFIG_CLEAR_GET(x) (((x) & SDIO_SETUP_CONFIG_CLEAR_MASK) >> SDIO_SETUP_CONFIG_CLEAR_LSB)
+#define SDIO_SETUP_CONFIG_CLEAR_SET(x) (((x) << SDIO_SETUP_CONFIG_CLEAR_LSB) & SDIO_SETUP_CONFIG_CLEAR_MASK)
+
+#define CPU_SETUP_CONFIG_ADDRESS 0x00000144
+#define CPU_SETUP_CONFIG_OFFSET 0x00000144
+#define CPU_SETUP_CONFIG_ENABLE_MSB 1
+#define CPU_SETUP_CONFIG_ENABLE_LSB 1
+#define CPU_SETUP_CONFIG_ENABLE_MASK 0x00000002
+#define CPU_SETUP_CONFIG_ENABLE_GET(x) (((x) & CPU_SETUP_CONFIG_ENABLE_MASK) >> CPU_SETUP_CONFIG_ENABLE_LSB)
+#define CPU_SETUP_CONFIG_ENABLE_SET(x) (((x) << CPU_SETUP_CONFIG_ENABLE_LSB) & CPU_SETUP_CONFIG_ENABLE_MASK)
+#define CPU_SETUP_CONFIG_CLEAR_MSB 0
+#define CPU_SETUP_CONFIG_CLEAR_LSB 0
+#define CPU_SETUP_CONFIG_CLEAR_MASK 0x00000001
+#define CPU_SETUP_CONFIG_CLEAR_GET(x) (((x) & CPU_SETUP_CONFIG_CLEAR_MASK) >> CPU_SETUP_CONFIG_CLEAR_LSB)
+#define CPU_SETUP_CONFIG_CLEAR_SET(x) (((x) << CPU_SETUP_CONFIG_CLEAR_LSB) & CPU_SETUP_CONFIG_CLEAR_MASK)
+
+#define CPU_SETUP_CIRCUIT_ADDRESS 0x00000160
+#define CPU_SETUP_CIRCUIT_OFFSET 0x00000160
+#define CPU_SETUP_CIRCUIT_VECTOR_MSB 7
+#define CPU_SETUP_CIRCUIT_VECTOR_LSB 0
+#define CPU_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff
+#define CPU_SETUP_CIRCUIT_VECTOR_GET(x) (((x) & CPU_SETUP_CIRCUIT_VECTOR_MASK) >> CPU_SETUP_CIRCUIT_VECTOR_LSB)
+#define CPU_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << CPU_SETUP_CIRCUIT_VECTOR_LSB) & CPU_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define BB_SETUP_CONFIG_ADDRESS 0x00000180
+#define BB_SETUP_CONFIG_OFFSET 0x00000180
+#define BB_SETUP_CONFIG_ENABLE_MSB 1
+#define BB_SETUP_CONFIG_ENABLE_LSB 1
+#define BB_SETUP_CONFIG_ENABLE_MASK 0x00000002
+#define BB_SETUP_CONFIG_ENABLE_GET(x) (((x) & BB_SETUP_CONFIG_ENABLE_MASK) >> BB_SETUP_CONFIG_ENABLE_LSB)
+#define BB_SETUP_CONFIG_ENABLE_SET(x) (((x) << BB_SETUP_CONFIG_ENABLE_LSB) & BB_SETUP_CONFIG_ENABLE_MASK)
+#define BB_SETUP_CONFIG_CLEAR_MSB 0
+#define BB_SETUP_CONFIG_CLEAR_LSB 0
+#define BB_SETUP_CONFIG_CLEAR_MASK 0x00000001
+#define BB_SETUP_CONFIG_CLEAR_GET(x) (((x) & BB_SETUP_CONFIG_CLEAR_MASK) >> BB_SETUP_CONFIG_CLEAR_LSB)
+#define BB_SETUP_CONFIG_CLEAR_SET(x) (((x) << BB_SETUP_CONFIG_CLEAR_LSB) & BB_SETUP_CONFIG_CLEAR_MASK)
+
+#define BB_SETUP_CIRCUIT_ADDRESS 0x000001a0
+#define BB_SETUP_CIRCUIT_OFFSET 0x000001a0
+#define BB_SETUP_CIRCUIT_VECTOR_MSB 7
+#define BB_SETUP_CIRCUIT_VECTOR_LSB 0
+#define BB_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff
+#define BB_SETUP_CIRCUIT_VECTOR_GET(x) (((x) & BB_SETUP_CIRCUIT_VECTOR_MASK) >> BB_SETUP_CIRCUIT_VECTOR_LSB)
+#define BB_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << BB_SETUP_CIRCUIT_VECTOR_LSB) & BB_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define GPIO_WAKEUP_CONTROL_ADDRESS 0x000001c0
+#define GPIO_WAKEUP_CONTROL_OFFSET 0x000001c0
+#define GPIO_WAKEUP_CONTROL_ENABLE_MSB 0
+#define GPIO_WAKEUP_CONTROL_ENABLE_LSB 0
+#define GPIO_WAKEUP_CONTROL_ENABLE_MASK 0x00000001
+#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) (((x) & GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> GPIO_WAKEUP_CONTROL_ENABLE_LSB)
+#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) (((x) << GPIO_WAKEUP_CONTROL_ENABLE_LSB) & GPIO_WAKEUP_CONTROL_ENABLE_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct rtc_reg_reg_s {
+ volatile unsigned int reset_control;
+ volatile unsigned int xtal_control;
+ volatile unsigned int tcxo_detect;
+ volatile unsigned int xtal_test;
+ volatile unsigned int quadrature;
+ volatile unsigned int pll_control;
+ volatile unsigned int pll_settle;
+ volatile unsigned int xtal_settle;
+ volatile unsigned int cpu_clock;
+ volatile unsigned int clock_out;
+ volatile unsigned int clock_control;
+ volatile unsigned int bias_override;
+ volatile unsigned int wdt_control;
+ volatile unsigned int wdt_status;
+ volatile unsigned int wdt;
+ volatile unsigned int wdt_count;
+ volatile unsigned int wdt_reset;
+ volatile unsigned int int_status;
+ volatile unsigned int lf_timer0;
+ volatile unsigned int lf_timer_count0;
+ volatile unsigned int lf_timer_control0;
+ volatile unsigned int lf_timer_status0;
+ volatile unsigned int lf_timer1;
+ volatile unsigned int lf_timer_count1;
+ volatile unsigned int lf_timer_control1;
+ volatile unsigned int lf_timer_status1;
+ volatile unsigned int lf_timer2;
+ volatile unsigned int lf_timer_count2;
+ volatile unsigned int lf_timer_control2;
+ volatile unsigned int lf_timer_status2;
+ volatile unsigned int lf_timer3;
+ volatile unsigned int lf_timer_count3;
+ volatile unsigned int lf_timer_control3;
+ volatile unsigned int lf_timer_status3;
+ volatile unsigned int hf_timer;
+ volatile unsigned int hf_timer_count;
+ volatile unsigned int hf_lf_count;
+ volatile unsigned int hf_timer_control;
+ volatile unsigned int hf_timer_status;
+ volatile unsigned int rtc_control;
+ volatile unsigned int rtc_time;
+ volatile unsigned int rtc_date;
+ volatile unsigned int rtc_set_time;
+ volatile unsigned int rtc_set_date;
+ volatile unsigned int rtc_set_alarm;
+ volatile unsigned int rtc_config;
+ volatile unsigned int rtc_alarm_status;
+ volatile unsigned int uart_wakeup;
+ volatile unsigned int reset_cause;
+ volatile unsigned int system_sleep;
+ volatile unsigned int sdio_wrapper;
+ volatile unsigned int mac_sleep_control;
+ volatile unsigned int keep_awake;
+ volatile unsigned int lpo_cal_time;
+ volatile unsigned int lpo_init_dividend_int;
+ volatile unsigned int lpo_init_dividend_fraction;
+ volatile unsigned int lpo_cal;
+ volatile unsigned int lpo_cal_test_control;
+ volatile unsigned int lpo_cal_test_status;
+ volatile unsigned int chip_id;
+ volatile unsigned int derived_rtc_clk;
+ volatile unsigned int mac_pcu_slp32_mode;
+ volatile unsigned int mac_pcu_slp32_wake;
+ volatile unsigned int mac_pcu_slp32_inc;
+ volatile unsigned int mac_pcu_slp_mib1;
+ volatile unsigned int mac_pcu_slp_mib2;
+ volatile unsigned int mac_pcu_slp_mib3;
+ volatile unsigned int mac_pcu_slp_beacon;
+ volatile unsigned int power_reg;
+ volatile unsigned int core_clk_ctrl;
+ unsigned char pad0[8]; /* pad to 0x120 */
+ volatile unsigned int sdio_setup_circuit[8];
+ volatile unsigned int sdio_setup_config;
+ volatile unsigned int cpu_setup_config;
+ unsigned char pad1[24]; /* pad to 0x160 */
+ volatile unsigned int cpu_setup_circuit[8];
+ volatile unsigned int bb_setup_config;
+ unsigned char pad2[28]; /* pad to 0x1a0 */
+ volatile unsigned int bb_setup_circuit[8];
+ volatile unsigned int gpio_wakeup_control;
+} rtc_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _RTC_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h
new file mode 100644
index 000000000000..16fb99cfd0b8
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h
@@ -0,0 +1,186 @@
+#ifndef _SI_REG_REG_H_
+#define _SI_REG_REG_H_
+
+#define SI_CONFIG_ADDRESS 0x00000000
+#define SI_CONFIG_OFFSET 0x00000000
+#define SI_CONFIG_ERR_INT_MSB 19
+#define SI_CONFIG_ERR_INT_LSB 19
+#define SI_CONFIG_ERR_INT_MASK 0x00080000
+#define SI_CONFIG_ERR_INT_GET(x) (((x) & SI_CONFIG_ERR_INT_MASK) >> SI_CONFIG_ERR_INT_LSB)
+#define SI_CONFIG_ERR_INT_SET(x) (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_MSB 18
+#define SI_CONFIG_BIDIR_OD_DATA_LSB 18
+#define SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000
+#define SI_CONFIG_BIDIR_OD_DATA_GET(x) (((x) & SI_CONFIG_BIDIR_OD_DATA_MASK) >> SI_CONFIG_BIDIR_OD_DATA_LSB)
+#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_MSB 16
+#define SI_CONFIG_I2C_LSB 16
+#define SI_CONFIG_I2C_MASK 0x00010000
+#define SI_CONFIG_I2C_GET(x) (((x) & SI_CONFIG_I2C_MASK) >> SI_CONFIG_I2C_LSB)
+#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_MSB 7
+#define SI_CONFIG_POS_SAMPLE_LSB 7
+#define SI_CONFIG_POS_SAMPLE_MASK 0x00000080
+#define SI_CONFIG_POS_SAMPLE_GET(x) (((x) & SI_CONFIG_POS_SAMPLE_MASK) >> SI_CONFIG_POS_SAMPLE_LSB)
+#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_POS_DRIVE_MSB 6
+#define SI_CONFIG_POS_DRIVE_LSB 6
+#define SI_CONFIG_POS_DRIVE_MASK 0x00000040
+#define SI_CONFIG_POS_DRIVE_GET(x) (((x) & SI_CONFIG_POS_DRIVE_MASK) >> SI_CONFIG_POS_DRIVE_LSB)
+#define SI_CONFIG_POS_DRIVE_SET(x) (((x) << SI_CONFIG_POS_DRIVE_LSB) & SI_CONFIG_POS_DRIVE_MASK)
+#define SI_CONFIG_INACTIVE_DATA_MSB 5
+#define SI_CONFIG_INACTIVE_DATA_LSB 5
+#define SI_CONFIG_INACTIVE_DATA_MASK 0x00000020
+#define SI_CONFIG_INACTIVE_DATA_GET(x) (((x) & SI_CONFIG_INACTIVE_DATA_MASK) >> SI_CONFIG_INACTIVE_DATA_LSB)
+#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_INACTIVE_CLK_MSB 4
+#define SI_CONFIG_INACTIVE_CLK_LSB 4
+#define SI_CONFIG_INACTIVE_CLK_MASK 0x00000010
+#define SI_CONFIG_INACTIVE_CLK_GET(x) (((x) & SI_CONFIG_INACTIVE_CLK_MASK) >> SI_CONFIG_INACTIVE_CLK_LSB)
+#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_DIVIDER_MSB 3
+#define SI_CONFIG_DIVIDER_LSB 0
+#define SI_CONFIG_DIVIDER_MASK 0x0000000f
+#define SI_CONFIG_DIVIDER_GET(x) (((x) & SI_CONFIG_DIVIDER_MASK) >> SI_CONFIG_DIVIDER_LSB)
+#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
+
+#define SI_CS_ADDRESS 0x00000004
+#define SI_CS_OFFSET 0x00000004
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_MSB 13
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_LSB 11
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_MASK 0x00003800
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_GET(x) (((x) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) >> SI_CS_BIT_CNT_IN_LAST_BYTE_LSB)
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_SET(x) (((x) << SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK)
+#define SI_CS_DONE_ERR_MSB 10
+#define SI_CS_DONE_ERR_LSB 10
+#define SI_CS_DONE_ERR_MASK 0x00000400
+#define SI_CS_DONE_ERR_GET(x) (((x) & SI_CS_DONE_ERR_MASK) >> SI_CS_DONE_ERR_LSB)
+#define SI_CS_DONE_ERR_SET(x) (((x) << SI_CS_DONE_ERR_LSB) & SI_CS_DONE_ERR_MASK)
+#define SI_CS_DONE_INT_MSB 9
+#define SI_CS_DONE_INT_LSB 9
+#define SI_CS_DONE_INT_MASK 0x00000200
+#define SI_CS_DONE_INT_GET(x) (((x) & SI_CS_DONE_INT_MASK) >> SI_CS_DONE_INT_LSB)
+#define SI_CS_DONE_INT_SET(x) (((x) << SI_CS_DONE_INT_LSB) & SI_CS_DONE_INT_MASK)
+#define SI_CS_START_MSB 8
+#define SI_CS_START_LSB 8
+#define SI_CS_START_MASK 0x00000100
+#define SI_CS_START_GET(x) (((x) & SI_CS_START_MASK) >> SI_CS_START_LSB)
+#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
+#define SI_CS_RX_CNT_MSB 7
+#define SI_CS_RX_CNT_LSB 4
+#define SI_CS_RX_CNT_MASK 0x000000f0
+#define SI_CS_RX_CNT_GET(x) (((x) & SI_CS_RX_CNT_MASK) >> SI_CS_RX_CNT_LSB)
+#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_MSB 3
+#define SI_CS_TX_CNT_LSB 0
+#define SI_CS_TX_CNT_MASK 0x0000000f
+#define SI_CS_TX_CNT_GET(x) (((x) & SI_CS_TX_CNT_MASK) >> SI_CS_TX_CNT_LSB)
+#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
+
+#define SI_TX_DATA0_ADDRESS 0x00000008
+#define SI_TX_DATA0_OFFSET 0x00000008
+#define SI_TX_DATA0_DATA3_MSB 31
+#define SI_TX_DATA0_DATA3_LSB 24
+#define SI_TX_DATA0_DATA3_MASK 0xff000000
+#define SI_TX_DATA0_DATA3_GET(x) (((x) & SI_TX_DATA0_DATA3_MASK) >> SI_TX_DATA0_DATA3_LSB)
+#define SI_TX_DATA0_DATA3_SET(x) (((x) << SI_TX_DATA0_DATA3_LSB) & SI_TX_DATA0_DATA3_MASK)
+#define SI_TX_DATA0_DATA2_MSB 23
+#define SI_TX_DATA0_DATA2_LSB 16
+#define SI_TX_DATA0_DATA2_MASK 0x00ff0000
+#define SI_TX_DATA0_DATA2_GET(x) (((x) & SI_TX_DATA0_DATA2_MASK) >> SI_TX_DATA0_DATA2_LSB)
+#define SI_TX_DATA0_DATA2_SET(x) (((x) << SI_TX_DATA0_DATA2_LSB) & SI_TX_DATA0_DATA2_MASK)
+#define SI_TX_DATA0_DATA1_MSB 15
+#define SI_TX_DATA0_DATA1_LSB 8
+#define SI_TX_DATA0_DATA1_MASK 0x0000ff00
+#define SI_TX_DATA0_DATA1_GET(x) (((x) & SI_TX_DATA0_DATA1_MASK) >> SI_TX_DATA0_DATA1_LSB)
+#define SI_TX_DATA0_DATA1_SET(x) (((x) << SI_TX_DATA0_DATA1_LSB) & SI_TX_DATA0_DATA1_MASK)
+#define SI_TX_DATA0_DATA0_MSB 7
+#define SI_TX_DATA0_DATA0_LSB 0
+#define SI_TX_DATA0_DATA0_MASK 0x000000ff
+#define SI_TX_DATA0_DATA0_GET(x) (((x) & SI_TX_DATA0_DATA0_MASK) >> SI_TX_DATA0_DATA0_LSB)
+#define SI_TX_DATA0_DATA0_SET(x) (((x) << SI_TX_DATA0_DATA0_LSB) & SI_TX_DATA0_DATA0_MASK)
+
+#define SI_TX_DATA1_ADDRESS 0x0000000c
+#define SI_TX_DATA1_OFFSET 0x0000000c
+#define SI_TX_DATA1_DATA7_MSB 31
+#define SI_TX_DATA1_DATA7_LSB 24
+#define SI_TX_DATA1_DATA7_MASK 0xff000000
+#define SI_TX_DATA1_DATA7_GET(x) (((x) & SI_TX_DATA1_DATA7_MASK) >> SI_TX_DATA1_DATA7_LSB)
+#define SI_TX_DATA1_DATA7_SET(x) (((x) << SI_TX_DATA1_DATA7_LSB) & SI_TX_DATA1_DATA7_MASK)
+#define SI_TX_DATA1_DATA6_MSB 23
+#define SI_TX_DATA1_DATA6_LSB 16
+#define SI_TX_DATA1_DATA6_MASK 0x00ff0000
+#define SI_TX_DATA1_DATA6_GET(x) (((x) & SI_TX_DATA1_DATA6_MASK) >> SI_TX_DATA1_DATA6_LSB)
+#define SI_TX_DATA1_DATA6_SET(x) (((x) << SI_TX_DATA1_DATA6_LSB) & SI_TX_DATA1_DATA6_MASK)
+#define SI_TX_DATA1_DATA5_MSB 15
+#define SI_TX_DATA1_DATA5_LSB 8
+#define SI_TX_DATA1_DATA5_MASK 0x0000ff00
+#define SI_TX_DATA1_DATA5_GET(x) (((x) & SI_TX_DATA1_DATA5_MASK) >> SI_TX_DATA1_DATA5_LSB)
+#define SI_TX_DATA1_DATA5_SET(x) (((x) << SI_TX_DATA1_DATA5_LSB) & SI_TX_DATA1_DATA5_MASK)
+#define SI_TX_DATA1_DATA4_MSB 7
+#define SI_TX_DATA1_DATA4_LSB 0
+#define SI_TX_DATA1_DATA4_MASK 0x000000ff
+#define SI_TX_DATA1_DATA4_GET(x) (((x) & SI_TX_DATA1_DATA4_MASK) >> SI_TX_DATA1_DATA4_LSB)
+#define SI_TX_DATA1_DATA4_SET(x) (((x) << SI_TX_DATA1_DATA4_LSB) & SI_TX_DATA1_DATA4_MASK)
+
+#define SI_RX_DATA0_ADDRESS 0x00000010
+#define SI_RX_DATA0_OFFSET 0x00000010
+#define SI_RX_DATA0_DATA3_MSB 31
+#define SI_RX_DATA0_DATA3_LSB 24
+#define SI_RX_DATA0_DATA3_MASK 0xff000000
+#define SI_RX_DATA0_DATA3_GET(x) (((x) & SI_RX_DATA0_DATA3_MASK) >> SI_RX_DATA0_DATA3_LSB)
+#define SI_RX_DATA0_DATA3_SET(x) (((x) << SI_RX_DATA0_DATA3_LSB) & SI_RX_DATA0_DATA3_MASK)
+#define SI_RX_DATA0_DATA2_MSB 23
+#define SI_RX_DATA0_DATA2_LSB 16
+#define SI_RX_DATA0_DATA2_MASK 0x00ff0000
+#define SI_RX_DATA0_DATA2_GET(x) (((x) & SI_RX_DATA0_DATA2_MASK) >> SI_RX_DATA0_DATA2_LSB)
+#define SI_RX_DATA0_DATA2_SET(x) (((x) << SI_RX_DATA0_DATA2_LSB) & SI_RX_DATA0_DATA2_MASK)
+#define SI_RX_DATA0_DATA1_MSB 15
+#define SI_RX_DATA0_DATA1_LSB 8
+#define SI_RX_DATA0_DATA1_MASK 0x0000ff00
+#define SI_RX_DATA0_DATA1_GET(x) (((x) & SI_RX_DATA0_DATA1_MASK) >> SI_RX_DATA0_DATA1_LSB)
+#define SI_RX_DATA0_DATA1_SET(x) (((x) << SI_RX_DATA0_DATA1_LSB) & SI_RX_DATA0_DATA1_MASK)
+#define SI_RX_DATA0_DATA0_MSB 7
+#define SI_RX_DATA0_DATA0_LSB 0
+#define SI_RX_DATA0_DATA0_MASK 0x000000ff
+#define SI_RX_DATA0_DATA0_GET(x) (((x) & SI_RX_DATA0_DATA0_MASK) >> SI_RX_DATA0_DATA0_LSB)
+#define SI_RX_DATA0_DATA0_SET(x) (((x) << SI_RX_DATA0_DATA0_LSB) & SI_RX_DATA0_DATA0_MASK)
+
+#define SI_RX_DATA1_ADDRESS 0x00000014
+#define SI_RX_DATA1_OFFSET 0x00000014
+#define SI_RX_DATA1_DATA7_MSB 31
+#define SI_RX_DATA1_DATA7_LSB 24
+#define SI_RX_DATA1_DATA7_MASK 0xff000000
+#define SI_RX_DATA1_DATA7_GET(x) (((x) & SI_RX_DATA1_DATA7_MASK) >> SI_RX_DATA1_DATA7_LSB)
+#define SI_RX_DATA1_DATA7_SET(x) (((x) << SI_RX_DATA1_DATA7_LSB) & SI_RX_DATA1_DATA7_MASK)
+#define SI_RX_DATA1_DATA6_MSB 23
+#define SI_RX_DATA1_DATA6_LSB 16
+#define SI_RX_DATA1_DATA6_MASK 0x00ff0000
+#define SI_RX_DATA1_DATA6_GET(x) (((x) & SI_RX_DATA1_DATA6_MASK) >> SI_RX_DATA1_DATA6_LSB)
+#define SI_RX_DATA1_DATA6_SET(x) (((x) << SI_RX_DATA1_DATA6_LSB) & SI_RX_DATA1_DATA6_MASK)
+#define SI_RX_DATA1_DATA5_MSB 15
+#define SI_RX_DATA1_DATA5_LSB 8
+#define SI_RX_DATA1_DATA5_MASK 0x0000ff00
+#define SI_RX_DATA1_DATA5_GET(x) (((x) & SI_RX_DATA1_DATA5_MASK) >> SI_RX_DATA1_DATA5_LSB)
+#define SI_RX_DATA1_DATA5_SET(x) (((x) << SI_RX_DATA1_DATA5_LSB) & SI_RX_DATA1_DATA5_MASK)
+#define SI_RX_DATA1_DATA4_MSB 7
+#define SI_RX_DATA1_DATA4_LSB 0
+#define SI_RX_DATA1_DATA4_MASK 0x000000ff
+#define SI_RX_DATA1_DATA4_GET(x) (((x) & SI_RX_DATA1_DATA4_MASK) >> SI_RX_DATA1_DATA4_LSB)
+#define SI_RX_DATA1_DATA4_SET(x) (((x) << SI_RX_DATA1_DATA4_LSB) & SI_RX_DATA1_DATA4_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct si_reg_reg_s {
+ volatile unsigned int si_config;
+ volatile unsigned int si_cs;
+ volatile unsigned int si_tx_data0;
+ volatile unsigned int si_tx_data1;
+ volatile unsigned int si_rx_data0;
+ volatile unsigned int si_rx_data1;
+} si_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _SI_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h
new file mode 100644
index 000000000000..5db321b72b2c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h
@@ -0,0 +1,327 @@
+#ifndef _UART_REG_REG_H_
+#define _UART_REG_REG_H_
+
+#define RBR_ADDRESS 0x00000000
+#define RBR_OFFSET 0x00000000
+#define RBR_RBR_MSB 7
+#define RBR_RBR_LSB 0
+#define RBR_RBR_MASK 0x000000ff
+#define RBR_RBR_GET(x) (((x) & RBR_RBR_MASK) >> RBR_RBR_LSB)
+#define RBR_RBR_SET(x) (((x) << RBR_RBR_LSB) & RBR_RBR_MASK)
+
+#define THR_ADDRESS 0x00000000
+#define THR_OFFSET 0x00000000
+#define THR_THR_MSB 7
+#define THR_THR_LSB 0
+#define THR_THR_MASK 0x000000ff
+#define THR_THR_GET(x) (((x) & THR_THR_MASK) >> THR_THR_LSB)
+#define THR_THR_SET(x) (((x) << THR_THR_LSB) & THR_THR_MASK)
+
+#define DLL_ADDRESS 0x00000000
+#define DLL_OFFSET 0x00000000
+#define DLL_DLL_MSB 7
+#define DLL_DLL_LSB 0
+#define DLL_DLL_MASK 0x000000ff
+#define DLL_DLL_GET(x) (((x) & DLL_DLL_MASK) >> DLL_DLL_LSB)
+#define DLL_DLL_SET(x) (((x) << DLL_DLL_LSB) & DLL_DLL_MASK)
+
+#define DLH_ADDRESS 0x00000004
+#define DLH_OFFSET 0x00000004
+#define DLH_DLH_MSB 7
+#define DLH_DLH_LSB 0
+#define DLH_DLH_MASK 0x000000ff
+#define DLH_DLH_GET(x) (((x) & DLH_DLH_MASK) >> DLH_DLH_LSB)
+#define DLH_DLH_SET(x) (((x) << DLH_DLH_LSB) & DLH_DLH_MASK)
+
+#define IER_ADDRESS 0x00000004
+#define IER_OFFSET 0x00000004
+#define IER_EDDSI_MSB 3
+#define IER_EDDSI_LSB 3
+#define IER_EDDSI_MASK 0x00000008
+#define IER_EDDSI_GET(x) (((x) & IER_EDDSI_MASK) >> IER_EDDSI_LSB)
+#define IER_EDDSI_SET(x) (((x) << IER_EDDSI_LSB) & IER_EDDSI_MASK)
+#define IER_ELSI_MSB 2
+#define IER_ELSI_LSB 2
+#define IER_ELSI_MASK 0x00000004
+#define IER_ELSI_GET(x) (((x) & IER_ELSI_MASK) >> IER_ELSI_LSB)
+#define IER_ELSI_SET(x) (((x) << IER_ELSI_LSB) & IER_ELSI_MASK)
+#define IER_ETBEI_MSB 1
+#define IER_ETBEI_LSB 1
+#define IER_ETBEI_MASK 0x00000002
+#define IER_ETBEI_GET(x) (((x) & IER_ETBEI_MASK) >> IER_ETBEI_LSB)
+#define IER_ETBEI_SET(x) (((x) << IER_ETBEI_LSB) & IER_ETBEI_MASK)
+#define IER_ERBFI_MSB 0
+#define IER_ERBFI_LSB 0
+#define IER_ERBFI_MASK 0x00000001
+#define IER_ERBFI_GET(x) (((x) & IER_ERBFI_MASK) >> IER_ERBFI_LSB)
+#define IER_ERBFI_SET(x) (((x) << IER_ERBFI_LSB) & IER_ERBFI_MASK)
+
+#define IIR_ADDRESS 0x00000008
+#define IIR_OFFSET 0x00000008
+#define IIR_FIFO_STATUS_MSB 7
+#define IIR_FIFO_STATUS_LSB 6
+#define IIR_FIFO_STATUS_MASK 0x000000c0
+#define IIR_FIFO_STATUS_GET(x) (((x) & IIR_FIFO_STATUS_MASK) >> IIR_FIFO_STATUS_LSB)
+#define IIR_FIFO_STATUS_SET(x) (((x) << IIR_FIFO_STATUS_LSB) & IIR_FIFO_STATUS_MASK)
+#define IIR_IID_MSB 3
+#define IIR_IID_LSB 0
+#define IIR_IID_MASK 0x0000000f
+#define IIR_IID_GET(x) (((x) & IIR_IID_MASK) >> IIR_IID_LSB)
+#define IIR_IID_SET(x) (((x) << IIR_IID_LSB) & IIR_IID_MASK)
+
+#define FCR_ADDRESS 0x00000008
+#define FCR_OFFSET 0x00000008
+#define FCR_RCVR_TRIG_MSB 7
+#define FCR_RCVR_TRIG_LSB 6
+#define FCR_RCVR_TRIG_MASK 0x000000c0
+#define FCR_RCVR_TRIG_GET(x) (((x) & FCR_RCVR_TRIG_MASK) >> FCR_RCVR_TRIG_LSB)
+#define FCR_RCVR_TRIG_SET(x) (((x) << FCR_RCVR_TRIG_LSB) & FCR_RCVR_TRIG_MASK)
+#define FCR_DMA_MODE_MSB 3
+#define FCR_DMA_MODE_LSB 3
+#define FCR_DMA_MODE_MASK 0x00000008
+#define FCR_DMA_MODE_GET(x) (((x) & FCR_DMA_MODE_MASK) >> FCR_DMA_MODE_LSB)
+#define FCR_DMA_MODE_SET(x) (((x) << FCR_DMA_MODE_LSB) & FCR_DMA_MODE_MASK)
+#define FCR_XMIT_FIFO_RST_MSB 2
+#define FCR_XMIT_FIFO_RST_LSB 2
+#define FCR_XMIT_FIFO_RST_MASK 0x00000004
+#define FCR_XMIT_FIFO_RST_GET(x) (((x) & FCR_XMIT_FIFO_RST_MASK) >> FCR_XMIT_FIFO_RST_LSB)
+#define FCR_XMIT_FIFO_RST_SET(x) (((x) << FCR_XMIT_FIFO_RST_LSB) & FCR_XMIT_FIFO_RST_MASK)
+#define FCR_RCVR_FIFO_RST_MSB 1
+#define FCR_RCVR_FIFO_RST_LSB 1
+#define FCR_RCVR_FIFO_RST_MASK 0x00000002
+#define FCR_RCVR_FIFO_RST_GET(x) (((x) & FCR_RCVR_FIFO_RST_MASK) >> FCR_RCVR_FIFO_RST_LSB)
+#define FCR_RCVR_FIFO_RST_SET(x) (((x) << FCR_RCVR_FIFO_RST_LSB) & FCR_RCVR_FIFO_RST_MASK)
+#define FCR_FIFO_EN_MSB 0
+#define FCR_FIFO_EN_LSB 0
+#define FCR_FIFO_EN_MASK 0x00000001
+#define FCR_FIFO_EN_GET(x) (((x) & FCR_FIFO_EN_MASK) >> FCR_FIFO_EN_LSB)
+#define FCR_FIFO_EN_SET(x) (((x) << FCR_FIFO_EN_LSB) & FCR_FIFO_EN_MASK)
+
+#define LCR_ADDRESS 0x0000000c
+#define LCR_OFFSET 0x0000000c
+#define LCR_DLAB_MSB 7
+#define LCR_DLAB_LSB 7
+#define LCR_DLAB_MASK 0x00000080
+#define LCR_DLAB_GET(x) (((x) & LCR_DLAB_MASK) >> LCR_DLAB_LSB)
+#define LCR_DLAB_SET(x) (((x) << LCR_DLAB_LSB) & LCR_DLAB_MASK)
+#define LCR_BREAK_MSB 6
+#define LCR_BREAK_LSB 6
+#define LCR_BREAK_MASK 0x00000040
+#define LCR_BREAK_GET(x) (((x) & LCR_BREAK_MASK) >> LCR_BREAK_LSB)
+#define LCR_BREAK_SET(x) (((x) << LCR_BREAK_LSB) & LCR_BREAK_MASK)
+#define LCR_EPS_MSB 4
+#define LCR_EPS_LSB 4
+#define LCR_EPS_MASK 0x00000010
+#define LCR_EPS_GET(x) (((x) & LCR_EPS_MASK) >> LCR_EPS_LSB)
+#define LCR_EPS_SET(x) (((x) << LCR_EPS_LSB) & LCR_EPS_MASK)
+#define LCR_PEN_MSB 3
+#define LCR_PEN_LSB 3
+#define LCR_PEN_MASK 0x00000008
+#define LCR_PEN_GET(x) (((x) & LCR_PEN_MASK) >> LCR_PEN_LSB)
+#define LCR_PEN_SET(x) (((x) << LCR_PEN_LSB) & LCR_PEN_MASK)
+#define LCR_STOP_MSB 2
+#define LCR_STOP_LSB 2
+#define LCR_STOP_MASK 0x00000004
+#define LCR_STOP_GET(x) (((x) & LCR_STOP_MASK) >> LCR_STOP_LSB)
+#define LCR_STOP_SET(x) (((x) << LCR_STOP_LSB) & LCR_STOP_MASK)
+#define LCR_CLS_MSB 1
+#define LCR_CLS_LSB 0
+#define LCR_CLS_MASK 0x00000003
+#define LCR_CLS_GET(x) (((x) & LCR_CLS_MASK) >> LCR_CLS_LSB)
+#define LCR_CLS_SET(x) (((x) << LCR_CLS_LSB) & LCR_CLS_MASK)
+
+#define MCR_ADDRESS 0x00000010
+#define MCR_OFFSET 0x00000010
+#define MCR_LOOPBACK_MSB 5
+#define MCR_LOOPBACK_LSB 5
+#define MCR_LOOPBACK_MASK 0x00000020
+#define MCR_LOOPBACK_GET(x) (((x) & MCR_LOOPBACK_MASK) >> MCR_LOOPBACK_LSB)
+#define MCR_LOOPBACK_SET(x) (((x) << MCR_LOOPBACK_LSB) & MCR_LOOPBACK_MASK)
+#define MCR_OUT2_MSB 3
+#define MCR_OUT2_LSB 3
+#define MCR_OUT2_MASK 0x00000008
+#define MCR_OUT2_GET(x) (((x) & MCR_OUT2_MASK) >> MCR_OUT2_LSB)
+#define MCR_OUT2_SET(x) (((x) << MCR_OUT2_LSB) & MCR_OUT2_MASK)
+#define MCR_OUT1_MSB 2
+#define MCR_OUT1_LSB 2
+#define MCR_OUT1_MASK 0x00000004
+#define MCR_OUT1_GET(x) (((x) & MCR_OUT1_MASK) >> MCR_OUT1_LSB)
+#define MCR_OUT1_SET(x) (((x) << MCR_OUT1_LSB) & MCR_OUT1_MASK)
+#define MCR_RTS_MSB 1
+#define MCR_RTS_LSB 1
+#define MCR_RTS_MASK 0x00000002
+#define MCR_RTS_GET(x) (((x) & MCR_RTS_MASK) >> MCR_RTS_LSB)
+#define MCR_RTS_SET(x) (((x) << MCR_RTS_LSB) & MCR_RTS_MASK)
+#define MCR_DTR_MSB 0
+#define MCR_DTR_LSB 0
+#define MCR_DTR_MASK 0x00000001
+#define MCR_DTR_GET(x) (((x) & MCR_DTR_MASK) >> MCR_DTR_LSB)
+#define MCR_DTR_SET(x) (((x) << MCR_DTR_LSB) & MCR_DTR_MASK)
+
+#define LSR_ADDRESS 0x00000014
+#define LSR_OFFSET 0x00000014
+#define LSR_FERR_MSB 7
+#define LSR_FERR_LSB 7
+#define LSR_FERR_MASK 0x00000080
+#define LSR_FERR_GET(x) (((x) & LSR_FERR_MASK) >> LSR_FERR_LSB)
+#define LSR_FERR_SET(x) (((x) << LSR_FERR_LSB) & LSR_FERR_MASK)
+#define LSR_TEMT_MSB 6
+#define LSR_TEMT_LSB 6
+#define LSR_TEMT_MASK 0x00000040
+#define LSR_TEMT_GET(x) (((x) & LSR_TEMT_MASK) >> LSR_TEMT_LSB)
+#define LSR_TEMT_SET(x) (((x) << LSR_TEMT_LSB) & LSR_TEMT_MASK)
+#define LSR_THRE_MSB 5
+#define LSR_THRE_LSB 5
+#define LSR_THRE_MASK 0x00000020
+#define LSR_THRE_GET(x) (((x) & LSR_THRE_MASK) >> LSR_THRE_LSB)
+#define LSR_THRE_SET(x) (((x) << LSR_THRE_LSB) & LSR_THRE_MASK)
+#define LSR_BI_MSB 4
+#define LSR_BI_LSB 4
+#define LSR_BI_MASK 0x00000010
+#define LSR_BI_GET(x) (((x) & LSR_BI_MASK) >> LSR_BI_LSB)
+#define LSR_BI_SET(x) (((x) << LSR_BI_LSB) & LSR_BI_MASK)
+#define LSR_FE_MSB 3
+#define LSR_FE_LSB 3
+#define LSR_FE_MASK 0x00000008
+#define LSR_FE_GET(x) (((x) & LSR_FE_MASK) >> LSR_FE_LSB)
+#define LSR_FE_SET(x) (((x) << LSR_FE_LSB) & LSR_FE_MASK)
+#define LSR_PE_MSB 2
+#define LSR_PE_LSB 2
+#define LSR_PE_MASK 0x00000004
+#define LSR_PE_GET(x) (((x) & LSR_PE_MASK) >> LSR_PE_LSB)
+#define LSR_PE_SET(x) (((x) << LSR_PE_LSB) & LSR_PE_MASK)
+#define LSR_OE_MSB 1
+#define LSR_OE_LSB 1
+#define LSR_OE_MASK 0x00000002
+#define LSR_OE_GET(x) (((x) & LSR_OE_MASK) >> LSR_OE_LSB)
+#define LSR_OE_SET(x) (((x) << LSR_OE_LSB) & LSR_OE_MASK)
+#define LSR_DR_MSB 0
+#define LSR_DR_LSB 0
+#define LSR_DR_MASK 0x00000001
+#define LSR_DR_GET(x) (((x) & LSR_DR_MASK) >> LSR_DR_LSB)
+#define LSR_DR_SET(x) (((x) << LSR_DR_LSB) & LSR_DR_MASK)
+
+#define MSR_ADDRESS 0x00000018
+#define MSR_OFFSET 0x00000018
+#define MSR_DCD_MSB 7
+#define MSR_DCD_LSB 7
+#define MSR_DCD_MASK 0x00000080
+#define MSR_DCD_GET(x) (((x) & MSR_DCD_MASK) >> MSR_DCD_LSB)
+#define MSR_DCD_SET(x) (((x) << MSR_DCD_LSB) & MSR_DCD_MASK)
+#define MSR_RI_MSB 6
+#define MSR_RI_LSB 6
+#define MSR_RI_MASK 0x00000040
+#define MSR_RI_GET(x) (((x) & MSR_RI_MASK) >> MSR_RI_LSB)
+#define MSR_RI_SET(x) (((x) << MSR_RI_LSB) & MSR_RI_MASK)
+#define MSR_DSR_MSB 5
+#define MSR_DSR_LSB 5
+#define MSR_DSR_MASK 0x00000020
+#define MSR_DSR_GET(x) (((x) & MSR_DSR_MASK) >> MSR_DSR_LSB)
+#define MSR_DSR_SET(x) (((x) << MSR_DSR_LSB) & MSR_DSR_MASK)
+#define MSR_CTS_MSB 4
+#define MSR_CTS_LSB 4
+#define MSR_CTS_MASK 0x00000010
+#define MSR_CTS_GET(x) (((x) & MSR_CTS_MASK) >> MSR_CTS_LSB)
+#define MSR_CTS_SET(x) (((x) << MSR_CTS_LSB) & MSR_CTS_MASK)
+#define MSR_DDCD_MSB 3
+#define MSR_DDCD_LSB 3
+#define MSR_DDCD_MASK 0x00000008
+#define MSR_DDCD_GET(x) (((x) & MSR_DDCD_MASK) >> MSR_DDCD_LSB)
+#define MSR_DDCD_SET(x) (((x) << MSR_DDCD_LSB) & MSR_DDCD_MASK)
+#define MSR_TERI_MSB 2
+#define MSR_TERI_LSB 2
+#define MSR_TERI_MASK 0x00000004
+#define MSR_TERI_GET(x) (((x) & MSR_TERI_MASK) >> MSR_TERI_LSB)
+#define MSR_TERI_SET(x) (((x) << MSR_TERI_LSB) & MSR_TERI_MASK)
+#define MSR_DDSR_MSB 1
+#define MSR_DDSR_LSB 1
+#define MSR_DDSR_MASK 0x00000002
+#define MSR_DDSR_GET(x) (((x) & MSR_DDSR_MASK) >> MSR_DDSR_LSB)
+#define MSR_DDSR_SET(x) (((x) << MSR_DDSR_LSB) & MSR_DDSR_MASK)
+#define MSR_DCTS_MSB 0
+#define MSR_DCTS_LSB 0
+#define MSR_DCTS_MASK 0x00000001
+#define MSR_DCTS_GET(x) (((x) & MSR_DCTS_MASK) >> MSR_DCTS_LSB)
+#define MSR_DCTS_SET(x) (((x) << MSR_DCTS_LSB) & MSR_DCTS_MASK)
+
+#define SCR_ADDRESS 0x0000001c
+#define SCR_OFFSET 0x0000001c
+#define SCR_SCR_MSB 7
+#define SCR_SCR_LSB 0
+#define SCR_SCR_MASK 0x000000ff
+#define SCR_SCR_GET(x) (((x) & SCR_SCR_MASK) >> SCR_SCR_LSB)
+#define SCR_SCR_SET(x) (((x) << SCR_SCR_LSB) & SCR_SCR_MASK)
+
+#define SRBR_ADDRESS 0x00000020
+#define SRBR_OFFSET 0x00000020
+#define SRBR_SRBR_MSB 7
+#define SRBR_SRBR_LSB 0
+#define SRBR_SRBR_MASK 0x000000ff
+#define SRBR_SRBR_GET(x) (((x) & SRBR_SRBR_MASK) >> SRBR_SRBR_LSB)
+#define SRBR_SRBR_SET(x) (((x) << SRBR_SRBR_LSB) & SRBR_SRBR_MASK)
+
+#define SIIR_ADDRESS 0x00000028
+#define SIIR_OFFSET 0x00000028
+#define SIIR_SIIR_MSB 7
+#define SIIR_SIIR_LSB 0
+#define SIIR_SIIR_MASK 0x000000ff
+#define SIIR_SIIR_GET(x) (((x) & SIIR_SIIR_MASK) >> SIIR_SIIR_LSB)
+#define SIIR_SIIR_SET(x) (((x) << SIIR_SIIR_LSB) & SIIR_SIIR_MASK)
+
+#define MWR_ADDRESS 0x0000002c
+#define MWR_OFFSET 0x0000002c
+#define MWR_MWR_MSB 31
+#define MWR_MWR_LSB 0
+#define MWR_MWR_MASK 0xffffffff
+#define MWR_MWR_GET(x) (((x) & MWR_MWR_MASK) >> MWR_MWR_LSB)
+#define MWR_MWR_SET(x) (((x) << MWR_MWR_LSB) & MWR_MWR_MASK)
+
+#define SLSR_ADDRESS 0x00000034
+#define SLSR_OFFSET 0x00000034
+#define SLSR_SLSR_MSB 7
+#define SLSR_SLSR_LSB 0
+#define SLSR_SLSR_MASK 0x000000ff
+#define SLSR_SLSR_GET(x) (((x) & SLSR_SLSR_MASK) >> SLSR_SLSR_LSB)
+#define SLSR_SLSR_SET(x) (((x) << SLSR_SLSR_LSB) & SLSR_SLSR_MASK)
+
+#define SMSR_ADDRESS 0x00000038
+#define SMSR_OFFSET 0x00000038
+#define SMSR_SMSR_MSB 7
+#define SMSR_SMSR_LSB 0
+#define SMSR_SMSR_MASK 0x000000ff
+#define SMSR_SMSR_GET(x) (((x) & SMSR_SMSR_MASK) >> SMSR_SMSR_LSB)
+#define SMSR_SMSR_SET(x) (((x) << SMSR_SMSR_LSB) & SMSR_SMSR_MASK)
+
+#define MRR_ADDRESS 0x0000003c
+#define MRR_OFFSET 0x0000003c
+#define MRR_MRR_MSB 31
+#define MRR_MRR_LSB 0
+#define MRR_MRR_MASK 0xffffffff
+#define MRR_MRR_GET(x) (((x) & MRR_MRR_MASK) >> MRR_MRR_LSB)
+#define MRR_MRR_SET(x) (((x) << MRR_MRR_LSB) & MRR_MRR_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct uart_reg_reg_s {
+ volatile unsigned int rbr;
+ volatile unsigned int dlh;
+ volatile unsigned int iir;
+ volatile unsigned int lcr;
+ volatile unsigned int mcr;
+ volatile unsigned int lsr;
+ volatile unsigned int msr;
+ volatile unsigned int scr;
+ volatile unsigned int srbr;
+ unsigned char pad0[4]; /* pad to 0x28 */
+ volatile unsigned int siir;
+ volatile unsigned int mwr;
+ unsigned char pad1[4]; /* pad to 0x34 */
+ volatile unsigned int slsr;
+ volatile unsigned int smsr;
+ volatile unsigned int mrr;
+} uart_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _UART_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h
new file mode 100644
index 000000000000..932ec510d26b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h
@@ -0,0 +1,76 @@
+#ifndef _VMC_REG_REG_H_
+#define _VMC_REG_REG_H_
+
+#define MC_TCAM_VALID_ADDRESS 0x00000000
+#define MC_TCAM_VALID_OFFSET 0x00000000
+#define MC_TCAM_VALID_BIT_MSB 0
+#define MC_TCAM_VALID_BIT_LSB 0
+#define MC_TCAM_VALID_BIT_MASK 0x00000001
+#define MC_TCAM_VALID_BIT_GET(x) (((x) & MC_TCAM_VALID_BIT_MASK) >> MC_TCAM_VALID_BIT_LSB)
+#define MC_TCAM_VALID_BIT_SET(x) (((x) << MC_TCAM_VALID_BIT_LSB) & MC_TCAM_VALID_BIT_MASK)
+
+#define MC_TCAM_MASK_ADDRESS 0x00000080
+#define MC_TCAM_MASK_OFFSET 0x00000080
+#define MC_TCAM_MASK_SIZE_MSB 2
+#define MC_TCAM_MASK_SIZE_LSB 0
+#define MC_TCAM_MASK_SIZE_MASK 0x00000007
+#define MC_TCAM_MASK_SIZE_GET(x) (((x) & MC_TCAM_MASK_SIZE_MASK) >> MC_TCAM_MASK_SIZE_LSB)
+#define MC_TCAM_MASK_SIZE_SET(x) (((x) << MC_TCAM_MASK_SIZE_LSB) & MC_TCAM_MASK_SIZE_MASK)
+
+#define MC_TCAM_COMPARE_ADDRESS 0x00000100
+#define MC_TCAM_COMPARE_OFFSET 0x00000100
+#define MC_TCAM_COMPARE_KEY_MSB 21
+#define MC_TCAM_COMPARE_KEY_LSB 5
+#define MC_TCAM_COMPARE_KEY_MASK 0x003fffe0
+#define MC_TCAM_COMPARE_KEY_GET(x) (((x) & MC_TCAM_COMPARE_KEY_MASK) >> MC_TCAM_COMPARE_KEY_LSB)
+#define MC_TCAM_COMPARE_KEY_SET(x) (((x) << MC_TCAM_COMPARE_KEY_LSB) & MC_TCAM_COMPARE_KEY_MASK)
+
+#define MC_TCAM_TARGET_ADDRESS 0x00000180
+#define MC_TCAM_TARGET_OFFSET 0x00000180
+#define MC_TCAM_TARGET_ADDR_MSB 21
+#define MC_TCAM_TARGET_ADDR_LSB 5
+#define MC_TCAM_TARGET_ADDR_MASK 0x003fffe0
+#define MC_TCAM_TARGET_ADDR_GET(x) (((x) & MC_TCAM_TARGET_ADDR_MASK) >> MC_TCAM_TARGET_ADDR_LSB)
+#define MC_TCAM_TARGET_ADDR_SET(x) (((x) << MC_TCAM_TARGET_ADDR_LSB) & MC_TCAM_TARGET_ADDR_MASK)
+
+#define ADDR_ERROR_CONTROL_ADDRESS 0x00000200
+#define ADDR_ERROR_CONTROL_OFFSET 0x00000200
+#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB 1
+#define ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB 1
+#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK 0x00000002
+#define ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) (((x) & ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB)
+#define ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) (((x) << ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) & ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK)
+#define ADDR_ERROR_CONTROL_ENABLE_MSB 0
+#define ADDR_ERROR_CONTROL_ENABLE_LSB 0
+#define ADDR_ERROR_CONTROL_ENABLE_MASK 0x00000001
+#define ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x) & ADDR_ERROR_CONTROL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_ENABLE_LSB)
+#define ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << ADDR_ERROR_CONTROL_ENABLE_LSB) & ADDR_ERROR_CONTROL_ENABLE_MASK)
+
+#define ADDR_ERROR_STATUS_ADDRESS 0x00000204
+#define ADDR_ERROR_STATUS_OFFSET 0x00000204
+#define ADDR_ERROR_STATUS_WRITE_MSB 25
+#define ADDR_ERROR_STATUS_WRITE_LSB 25
+#define ADDR_ERROR_STATUS_WRITE_MASK 0x02000000
+#define ADDR_ERROR_STATUS_WRITE_GET(x) (((x) & ADDR_ERROR_STATUS_WRITE_MASK) >> ADDR_ERROR_STATUS_WRITE_LSB)
+#define ADDR_ERROR_STATUS_WRITE_SET(x) (((x) << ADDR_ERROR_STATUS_WRITE_LSB) & ADDR_ERROR_STATUS_WRITE_MASK)
+#define ADDR_ERROR_STATUS_ADDRESS_MSB 24
+#define ADDR_ERROR_STATUS_ADDRESS_LSB 0
+#define ADDR_ERROR_STATUS_ADDRESS_MASK 0x01ffffff
+#define ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x) & ADDR_ERROR_STATUS_ADDRESS_MASK) >> ADDR_ERROR_STATUS_ADDRESS_LSB)
+#define ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << ADDR_ERROR_STATUS_ADDRESS_LSB) & ADDR_ERROR_STATUS_ADDRESS_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct vmc_reg_reg_s {
+ volatile unsigned int mc_tcam_valid[32];
+ volatile unsigned int mc_tcam_mask[32];
+ volatile unsigned int mc_tcam_compare[32];
+ volatile unsigned int mc_tcam_target[32];
+ volatile unsigned int addr_error_control;
+ volatile unsigned int addr_error_status;
+} vmc_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _VMC_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h
new file mode 100644
index 000000000000..5970fa94d4d2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h
@@ -0,0 +1,3291 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+/* Copyright (C) 2009 Denali Software Inc. All rights reserved */
+/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT */
+
+
+#ifndef _ANALOG_INTF_ARES_REG_REG_H_
+#define _ANALOG_INTF_ARES_REG_REG_H_
+
+
+/* macros for RXRF_BIAS1 */
+#define PHY_ANALOG_RXRF_BIAS1_ADDRESS 0x00000000
+#define PHY_ANALOG_RXRF_BIAS1_OFFSET 0x00000000
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MSB 3
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_LSB 1
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MASK 0x0000000e
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MSB 6
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_LSB 4
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MASK 0x00000070
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MSB 9
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_LSB 7
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MASK 0x00000380
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MSB 12
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_LSB 10
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MASK 0x00001c00
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_GET(x) (((x) & 0x00001c00) >> 10)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_SET(x) (((x) << 10) & 0x00001c00)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MSB 15
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_LSB 13
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MASK 0x0000e000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MSB 18
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_LSB 16
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MASK 0x00070000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MSB 21
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_LSB 19
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MASK 0x00380000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MSB 24
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_LSB 22
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MASK 0x01c00000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_GET(x) (((x) & 0x01c00000) >> 22)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_SET(x) (((x) << 22) & 0x01c00000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MSB 27
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_LSB 25
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MASK 0x0e000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MSB 30
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_LSB 28
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MASK 0x70000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_GET(x) (((x) & 0x70000000) >> 28)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_SET(x) (((x) << 28) & 0x70000000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MSB 31
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_LSB 31
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MASK 0x80000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXRF_BIAS2 */
+#define PHY_ANALOG_RXRF_BIAS2_ADDRESS 0x00000004
+#define PHY_ANALOG_RXRF_BIAS2_OFFSET 0x00000004
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_MSB 3
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_LSB 1
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_MASK 0x0000000e
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MSB 6
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_LSB 4
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MASK 0x00000070
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MSB 7
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_LSB 7
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MASK 0x00000080
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_MSB 10
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_LSB 8
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_MASK 0x00000700
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_MSB 13
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_LSB 11
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_MASK 0x00003800
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_MSB 16
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_LSB 14
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_MASK 0x0001c000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_MSB 19
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_LSB 17
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_MASK 0x000e0000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_MSB 22
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_LSB 20
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_MASK 0x00700000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_MSB 25
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_LSB 23
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_MASK 0x03800000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MSB 28
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_LSB 26
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MASK 0x1c000000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MSB 31
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_LSB 29
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MASK 0xe0000000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXRF_GAINSTAGES */
+#define PHY_ANALOG_RXRF_GAINSTAGES_ADDRESS 0x00000008
+#define PHY_ANALOG_RXRF_GAINSTAGES_OFFSET 0x00000008
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MSB 1
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_LSB 1
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MASK 0x00000002
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MSB 3
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_LSB 2
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MASK 0x0000000c
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MSB 5
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_LSB 4
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MASK 0x00000030
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MSB 6
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_LSB 6
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MASK 0x00000040
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MSB 7
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_LSB 7
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MASK 0x00000080
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MSB 8
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_LSB 8
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MASK 0x00000100
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MSB 9
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_LSB 9
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MASK 0x00000200
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MSB 10
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_LSB 10
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MASK 0x00000400
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MSB 12
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_LSB 11
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MASK 0x00001800
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_GET(x) (((x) & 0x00001800) >> 11)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_SET(x) (((x) << 11) & 0x00001800)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MSB 13
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_LSB 13
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MASK 0x00002000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MSB 14
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_LSB 14
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MASK 0x00004000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MSB 15
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_LSB 15
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MASK 0x00008000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MSB 16
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_LSB 16
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MASK 0x00010000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MSB 17
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_LSB 17
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MASK 0x00020000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MSB 19
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_LSB 18
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MASK 0x000c0000
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MSB 22
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_LSB 20
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MASK 0x00700000
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MSB 25
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_LSB 23
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MASK 0x03800000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MSB 27
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_LSB 26
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MASK 0x0c000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MSB 30
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_LSB 28
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MASK 0x70000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_GET(x) (((x) & 0x70000000) >> 28)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_SET(x) (((x) << 28) & 0x70000000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MSB 31
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_LSB 31
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXRF_AGC */
+#define PHY_ANALOG_RXRF_AGC_ADDRESS 0x0000000c
+#define PHY_ANALOG_RXRF_AGC_OFFSET 0x0000000c
+#define PHY_ANALOG_RXRF_AGC_SPARE_MSB 5
+#define PHY_ANALOG_RXRF_AGC_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_AGC_SPARE_MASK 0x0000003f
+#define PHY_ANALOG_RXRF_AGC_SPARE_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_ANALOG_RXRF_AGC_SPARE_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MSB 8
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_LSB 6
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MASK 0x000001c0
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MSB 14
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_LSB 9
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MASK 0x00007e00
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_GET(x) (((x) & 0x00007e00) >> 9)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_SET(x) (((x) << 9) & 0x00007e00)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MSB 18
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_LSB 15
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MASK 0x00078000
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_GET(x) (((x) & 0x00078000) >> 15)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_SET(x) (((x) << 15) & 0x00078000)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MSB 24
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_LSB 19
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MASK 0x01f80000
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_GET(x) (((x) & 0x01f80000) >> 19)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_SET(x) (((x) << 19) & 0x01f80000)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MSB 28
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_LSB 25
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MASK 0x1e000000
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_GET(x) (((x) & 0x1e000000) >> 25)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_SET(x) (((x) << 25) & 0x1e000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MSB 29
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_LSB 29
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MASK 0x20000000
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MSB 30
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_LSB 30
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MASK 0x40000000
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MSB 31
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_LSB 31
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF1 */
+#define PHY_ANALOG_TXRF1_ADDRESS 0x00000040
+#define PHY_ANALOG_TXRF1_OFFSET 0x00000040
+#define PHY_ANALOG_TXRF1_DCAS2G_MSB 2
+#define PHY_ANALOG_TXRF1_DCAS2G_LSB 0
+#define PHY_ANALOG_TXRF1_DCAS2G_MASK 0x00000007
+#define PHY_ANALOG_TXRF1_DCAS2G_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_TXRF1_DCAS2G_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_TXRF1_OB2G_PALOFF_MSB 5
+#define PHY_ANALOG_TXRF1_OB2G_PALOFF_LSB 3
+#define PHY_ANALOG_TXRF1_OB2G_PALOFF_MASK 0x00000038
+#define PHY_ANALOG_TXRF1_OB2G_PALOFF_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_TXRF1_OB2G_PALOFF_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_TXRF1_OB2G_QAM_MSB 8
+#define PHY_ANALOG_TXRF1_OB2G_QAM_LSB 6
+#define PHY_ANALOG_TXRF1_OB2G_QAM_MASK 0x000001c0
+#define PHY_ANALOG_TXRF1_OB2G_QAM_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_ANALOG_TXRF1_OB2G_QAM_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_ANALOG_TXRF1_OB2G_PSK_MSB 11
+#define PHY_ANALOG_TXRF1_OB2G_PSK_LSB 9
+#define PHY_ANALOG_TXRF1_OB2G_PSK_MASK 0x00000e00
+#define PHY_ANALOG_TXRF1_OB2G_PSK_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_ANALOG_TXRF1_OB2G_PSK_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_ANALOG_TXRF1_OB2G_CCK_MSB 14
+#define PHY_ANALOG_TXRF1_OB2G_CCK_LSB 12
+#define PHY_ANALOG_TXRF1_OB2G_CCK_MASK 0x00007000
+#define PHY_ANALOG_TXRF1_OB2G_CCK_GET(x) (((x) & 0x00007000) >> 12)
+#define PHY_ANALOG_TXRF1_OB2G_CCK_SET(x) (((x) << 12) & 0x00007000)
+#define PHY_ANALOG_TXRF1_DB2G_MSB 17
+#define PHY_ANALOG_TXRF1_DB2G_LSB 15
+#define PHY_ANALOG_TXRF1_DB2G_MASK 0x00038000
+#define PHY_ANALOG_TXRF1_DB2G_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_TXRF1_DB2G_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_TXRF1_PDOUT2G_MSB 18
+#define PHY_ANALOG_TXRF1_PDOUT2G_LSB 18
+#define PHY_ANALOG_TXRF1_PDOUT2G_MASK 0x00040000
+#define PHY_ANALOG_TXRF1_PDOUT2G_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_TXRF1_PDOUT2G_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_TXRF1_PDDR2G_MSB 19
+#define PHY_ANALOG_TXRF1_PDDR2G_LSB 19
+#define PHY_ANALOG_TXRF1_PDDR2G_MASK 0x00080000
+#define PHY_ANALOG_TXRF1_PDDR2G_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_TXRF1_PDDR2G_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_TXRF1_PDMXR2G_MSB 20
+#define PHY_ANALOG_TXRF1_PDMXR2G_LSB 20
+#define PHY_ANALOG_TXRF1_PDMXR2G_MASK 0x00100000
+#define PHY_ANALOG_TXRF1_PDMXR2G_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TXRF1_PDMXR2G_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TXRF1_PDLO2G_MSB 21
+#define PHY_ANALOG_TXRF1_PDLO2G_LSB 21
+#define PHY_ANALOG_TXRF1_PDLO2G_MASK 0x00200000
+#define PHY_ANALOG_TXRF1_PDLO2G_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TXRF1_PDLO2G_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MSB 22
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_LSB 22
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MASK 0x00400000
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MSB 23
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_LSB 23
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MASK 0x00800000
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_TXRF1_PADRVGN2G_MSB 30
+#define PHY_ANALOG_TXRF1_PADRVGN2G_LSB 24
+#define PHY_ANALOG_TXRF1_PADRVGN2G_MASK 0x7f000000
+#define PHY_ANALOG_TXRF1_PADRVGN2G_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TXRF1_PADRVGN2G_SET(x) (((x) << 24) & 0x7f000000)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MSB 31
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_LSB 31
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MASK 0x80000000
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF2 */
+#define PHY_ANALOG_TXRF2_ADDRESS 0x00000044
+#define PHY_ANALOG_TXRF2_OFFSET 0x00000044
+#define PHY_ANALOG_TXRF2_SPARE2_MSB 0
+#define PHY_ANALOG_TXRF2_SPARE2_LSB 0
+#define PHY_ANALOG_TXRF2_SPARE2_MASK 0x00000001
+#define PHY_ANALOG_TXRF2_SPARE2_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF2_SPARE2_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TXRF2_D3B5G_MSB 3
+#define PHY_ANALOG_TXRF2_D3B5G_LSB 1
+#define PHY_ANALOG_TXRF2_D3B5G_MASK 0x0000000e
+#define PHY_ANALOG_TXRF2_D3B5G_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_TXRF2_D3B5G_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_TXRF2_D4B5G_MSB 6
+#define PHY_ANALOG_TXRF2_D4B5G_LSB 4
+#define PHY_ANALOG_TXRF2_D4B5G_MASK 0x00000070
+#define PHY_ANALOG_TXRF2_D4B5G_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_TXRF2_D4B5G_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_TXRF2_PDOUT5G_MSB 10
+#define PHY_ANALOG_TXRF2_PDOUT5G_LSB 7
+#define PHY_ANALOG_TXRF2_PDOUT5G_MASK 0x00000780
+#define PHY_ANALOG_TXRF2_PDOUT5G_GET(x) (((x) & 0x00000780) >> 7)
+#define PHY_ANALOG_TXRF2_PDOUT5G_SET(x) (((x) << 7) & 0x00000780)
+#define PHY_ANALOG_TXRF2_PDMXR5G_MSB 11
+#define PHY_ANALOG_TXRF2_PDMXR5G_LSB 11
+#define PHY_ANALOG_TXRF2_PDMXR5G_MASK 0x00000800
+#define PHY_ANALOG_TXRF2_PDMXR5G_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_TXRF2_PDMXR5G_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_TXRF2_PDLOBUF5G_MSB 12
+#define PHY_ANALOG_TXRF2_PDLOBUF5G_LSB 12
+#define PHY_ANALOG_TXRF2_PDLOBUF5G_MASK 0x00001000
+#define PHY_ANALOG_TXRF2_PDLOBUF5G_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_TXRF2_PDLOBUF5G_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_TXRF2_PDLODIV5G_MSB 13
+#define PHY_ANALOG_TXRF2_PDLODIV5G_LSB 13
+#define PHY_ANALOG_TXRF2_PDLODIV5G_MASK 0x00002000
+#define PHY_ANALOG_TXRF2_PDLODIV5G_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TXRF2_PDLODIV5G_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_MSB 14
+#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_LSB 14
+#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_MASK 0x00004000
+#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_TXRF2_LODIV5GFORCED_MSB 15
+#define PHY_ANALOG_TXRF2_LODIV5GFORCED_LSB 15
+#define PHY_ANALOG_TXRF2_LODIV5GFORCED_MASK 0x00008000
+#define PHY_ANALOG_TXRF2_LODIV5GFORCED_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_TXRF2_LODIV5GFORCED_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_TXRF2_PADRV2GN5G_MSB 19
+#define PHY_ANALOG_TXRF2_PADRV2GN5G_LSB 16
+#define PHY_ANALOG_TXRF2_PADRV2GN5G_MASK 0x000f0000
+#define PHY_ANALOG_TXRF2_PADRV2GN5G_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_TXRF2_PADRV2GN5G_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_TXRF2_PADRV3GN5G_MSB 23
+#define PHY_ANALOG_TXRF2_PADRV3GN5G_LSB 20
+#define PHY_ANALOG_TXRF2_PADRV3GN5G_MASK 0x00f00000
+#define PHY_ANALOG_TXRF2_PADRV3GN5G_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_ANALOG_TXRF2_PADRV3GN5G_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_ANALOG_TXRF2_PADRV4GN5G_MSB 27
+#define PHY_ANALOG_TXRF2_PADRV4GN5G_LSB 24
+#define PHY_ANALOG_TXRF2_PADRV4GN5G_MASK 0x0f000000
+#define PHY_ANALOG_TXRF2_PADRV4GN5G_GET(x) (((x) & 0x0f000000) >> 24)
+#define PHY_ANALOG_TXRF2_PADRV4GN5G_SET(x) (((x) << 24) & 0x0f000000)
+#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_MSB 28
+#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_LSB 28
+#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_MASK 0x10000000
+#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_TXRF2_OCAS2G_MSB 31
+#define PHY_ANALOG_TXRF2_OCAS2G_LSB 29
+#define PHY_ANALOG_TXRF2_OCAS2G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF2_OCAS2G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF2_OCAS2G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF3 */
+#define PHY_ANALOG_TXRF3_ADDRESS 0x00000048
+#define PHY_ANALOG_TXRF3_OFFSET 0x00000048
+#define PHY_ANALOG_TXRF3_SPARE3_MSB 22
+#define PHY_ANALOG_TXRF3_SPARE3_LSB 0
+#define PHY_ANALOG_TXRF3_SPARE3_MASK 0x007fffff
+#define PHY_ANALOG_TXRF3_SPARE3_GET(x) (((x) & 0x007fffff) >> 0)
+#define PHY_ANALOG_TXRF3_SPARE3_SET(x) (((x) << 0) & 0x007fffff)
+#define PHY_ANALOG_TXRF3_CAS5G_MSB 25
+#define PHY_ANALOG_TXRF3_CAS5G_LSB 23
+#define PHY_ANALOG_TXRF3_CAS5G_MASK 0x03800000
+#define PHY_ANALOG_TXRF3_CAS5G_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF3_CAS5G_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF3_OB5G_MSB 28
+#define PHY_ANALOG_TXRF3_OB5G_LSB 26
+#define PHY_ANALOG_TXRF3_OB5G_MASK 0x1c000000
+#define PHY_ANALOG_TXRF3_OB5G_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF3_OB5G_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF3_D2B5G_MSB 31
+#define PHY_ANALOG_TXRF3_D2B5G_LSB 29
+#define PHY_ANALOG_TXRF3_D2B5G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF3_D2B5G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF3_D2B5G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF4 */
+#define PHY_ANALOG_TXRF4_ADDRESS 0x0000004c
+#define PHY_ANALOG_TXRF4_OFFSET 0x0000004c
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_MSB 2
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_LSB 0
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_MASK 0x00000007
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_MSB 5
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_LSB 3
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_MASK 0x00000038
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MSB 8
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_LSB 6
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MASK 0x000001c0
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MSB 11
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_LSB 9
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MASK 0x00000e00
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MSB 14
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_LSB 12
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MASK 0x00007000
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_GET(x) (((x) & 0x00007000) >> 12)
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_SET(x) (((x) << 12) & 0x00007000)
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_MSB 17
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_LSB 15
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_MASK 0x00038000
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_TXRF4_FILTR2G_MSB 19
+#define PHY_ANALOG_TXRF4_FILTR2G_LSB 18
+#define PHY_ANALOG_TXRF4_FILTR2G_MASK 0x000c0000
+#define PHY_ANALOG_TXRF4_FILTR2G_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_TXRF4_FILTR2G_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_TXRF4_PWDFB2_2G_MSB 20
+#define PHY_ANALOG_TXRF4_PWDFB2_2G_LSB 20
+#define PHY_ANALOG_TXRF4_PWDFB2_2G_MASK 0x00100000
+#define PHY_ANALOG_TXRF4_PWDFB2_2G_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TXRF4_PWDFB2_2G_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TXRF4_PWDFB1_2G_MSB 21
+#define PHY_ANALOG_TXRF4_PWDFB1_2G_LSB 21
+#define PHY_ANALOG_TXRF4_PWDFB1_2G_MASK 0x00200000
+#define PHY_ANALOG_TXRF4_PWDFB1_2G_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TXRF4_PWDFB1_2G_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TXRF4_PDFB2G_MSB 22
+#define PHY_ANALOG_TXRF4_PDFB2G_LSB 22
+#define PHY_ANALOG_TXRF4_PDFB2G_MASK 0x00400000
+#define PHY_ANALOG_TXRF4_PDFB2G_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TXRF4_PDFB2G_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TXRF4_RDIV5G_MSB 24
+#define PHY_ANALOG_TXRF4_RDIV5G_LSB 23
+#define PHY_ANALOG_TXRF4_RDIV5G_MASK 0x01800000
+#define PHY_ANALOG_TXRF4_RDIV5G_GET(x) (((x) & 0x01800000) >> 23)
+#define PHY_ANALOG_TXRF4_RDIV5G_SET(x) (((x) << 23) & 0x01800000)
+#define PHY_ANALOG_TXRF4_CAPDIV5G_MSB 27
+#define PHY_ANALOG_TXRF4_CAPDIV5G_LSB 25
+#define PHY_ANALOG_TXRF4_CAPDIV5G_MASK 0x0e000000
+#define PHY_ANALOG_TXRF4_CAPDIV5G_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_ANALOG_TXRF4_CAPDIV5G_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_ANALOG_TXRF4_PDPREDIST5G_MSB 28
+#define PHY_ANALOG_TXRF4_PDPREDIST5G_LSB 28
+#define PHY_ANALOG_TXRF4_PDPREDIST5G_MASK 0x10000000
+#define PHY_ANALOG_TXRF4_PDPREDIST5G_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_TXRF4_PDPREDIST5G_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_TXRF4_RDIV2G_MSB 30
+#define PHY_ANALOG_TXRF4_RDIV2G_LSB 29
+#define PHY_ANALOG_TXRF4_RDIV2G_MASK 0x60000000
+#define PHY_ANALOG_TXRF4_RDIV2G_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_ANALOG_TXRF4_RDIV2G_SET(x) (((x) << 29) & 0x60000000)
+#define PHY_ANALOG_TXRF4_PDPREDIST2G_MSB 31
+#define PHY_ANALOG_TXRF4_PDPREDIST2G_LSB 31
+#define PHY_ANALOG_TXRF4_PDPREDIST2G_MASK 0x80000000
+#define PHY_ANALOG_TXRF4_PDPREDIST2G_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF4_PDPREDIST2G_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF5 */
+#define PHY_ANALOG_TXRF5_ADDRESS 0x00000050
+#define PHY_ANALOG_TXRF5_OFFSET 0x00000050
+#define PHY_ANALOG_TXRF5_FBHI2G_MSB 0
+#define PHY_ANALOG_TXRF5_FBHI2G_LSB 0
+#define PHY_ANALOG_TXRF5_FBHI2G_MASK 0x00000001
+#define PHY_ANALOG_TXRF5_FBHI2G_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF5_FBLO2G_MSB 1
+#define PHY_ANALOG_TXRF5_FBLO2G_LSB 1
+#define PHY_ANALOG_TXRF5_FBLO2G_MASK 0x00000002
+#define PHY_ANALOG_TXRF5_FBLO2G_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_TXRF5_REFHI2G_MSB 4
+#define PHY_ANALOG_TXRF5_REFHI2G_LSB 2
+#define PHY_ANALOG_TXRF5_REFHI2G_MASK 0x0000001c
+#define PHY_ANALOG_TXRF5_REFHI2G_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_TXRF5_REFHI2G_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_TXRF5_REFLO2G_MSB 7
+#define PHY_ANALOG_TXRF5_REFLO2G_LSB 5
+#define PHY_ANALOG_TXRF5_REFLO2G_MASK 0x000000e0
+#define PHY_ANALOG_TXRF5_REFLO2G_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_TXRF5_REFLO2G_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MSB 9
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_LSB 8
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MASK 0x00000300
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MSB 11
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_LSB 10
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MASK 0x00000c00
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_GET(x) (((x) & 0x00000c00) >> 10)
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_SET(x) (((x) << 10) & 0x00000c00)
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MSB 13
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_LSB 12
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MASK 0x00003000
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_SET(x) (((x) << 12) & 0x00003000)
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MSB 15
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_LSB 14
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MASK 0x0000c000
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MSB 17
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_LSB 16
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MASK 0x00030000
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_GET(x) (((x) & 0x00030000) >> 16)
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_SET(x) (((x) << 16) & 0x00030000)
+#define PHY_ANALOG_TXRF5_PK1B2G_CCK_MSB 19
+#define PHY_ANALOG_TXRF5_PK1B2G_CCK_LSB 18
+#define PHY_ANALOG_TXRF5_PK1B2G_CCK_MASK 0x000c0000
+#define PHY_ANALOG_TXRF5_PK1B2G_CCK_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_TXRF5_PK1B2G_CCK_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_TXRF5_MIOB2G_QAM_MSB 22
+#define PHY_ANALOG_TXRF5_MIOB2G_QAM_LSB 20
+#define PHY_ANALOG_TXRF5_MIOB2G_QAM_MASK 0x00700000
+#define PHY_ANALOG_TXRF5_MIOB2G_QAM_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF5_MIOB2G_QAM_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF5_MIOB2G_PSK_MSB 25
+#define PHY_ANALOG_TXRF5_MIOB2G_PSK_LSB 23
+#define PHY_ANALOG_TXRF5_MIOB2G_PSK_MASK 0x03800000
+#define PHY_ANALOG_TXRF5_MIOB2G_PSK_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF5_MIOB2G_PSK_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF5_MIOB2G_CCK_MSB 28
+#define PHY_ANALOG_TXRF5_MIOB2G_CCK_LSB 26
+#define PHY_ANALOG_TXRF5_MIOB2G_CCK_MASK 0x1c000000
+#define PHY_ANALOG_TXRF5_MIOB2G_CCK_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF5_MIOB2G_CCK_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF5_COMP2G_QAM_MSB 31
+#define PHY_ANALOG_TXRF5_COMP2G_QAM_LSB 29
+#define PHY_ANALOG_TXRF5_COMP2G_QAM_MASK 0xe0000000
+#define PHY_ANALOG_TXRF5_COMP2G_QAM_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF5_COMP2G_QAM_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF6 */
+#define PHY_ANALOG_TXRF6_ADDRESS 0x00000054
+#define PHY_ANALOG_TXRF6_OFFSET 0x00000054
+#define PHY_ANALOG_TXRF6_SPARE6_MSB 0
+#define PHY_ANALOG_TXRF6_SPARE6_LSB 0
+#define PHY_ANALOG_TXRF6_SPARE6_MASK 0x00000001
+#define PHY_ANALOG_TXRF6_SPARE6_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF6_SPARE6_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TXRF6_PAL_LOCKED_MSB 1
+#define PHY_ANALOG_TXRF6_PAL_LOCKED_LSB 1
+#define PHY_ANALOG_TXRF6_PAL_LOCKED_MASK 0x00000002
+#define PHY_ANALOG_TXRF6_PAL_LOCKED_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_MSB 7
+#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_LSB 2
+#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_MASK 0x000000fc
+#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_MSB 10
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_LSB 8
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_MASK 0x00000700
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MSB 11
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_LSB 11
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MASK 0x00000800
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MSB 15
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_LSB 12
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MASK 0x0000f000
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MSB 18
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_LSB 16
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MASK 0x00070000
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_ANALOG_TXRF6_CAPDIV2G_MSB 21
+#define PHY_ANALOG_TXRF6_CAPDIV2G_LSB 19
+#define PHY_ANALOG_TXRF6_CAPDIV2G_MASK 0x00380000
+#define PHY_ANALOG_TXRF6_CAPDIV2G_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_TXRF6_CAPDIV2G_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MSB 22
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_LSB 22
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MASK 0x00400000
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TXRF6_ENPACAL2G_MSB 23
+#define PHY_ANALOG_TXRF6_ENPACAL2G_LSB 23
+#define PHY_ANALOG_TXRF6_ENPACAL2G_MASK 0x00800000
+#define PHY_ANALOG_TXRF6_ENPACAL2G_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_TXRF6_ENPACAL2G_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_TXRF6_OFFSET2G_MSB 30
+#define PHY_ANALOG_TXRF6_OFFSET2G_LSB 24
+#define PHY_ANALOG_TXRF6_OFFSET2G_MASK 0x7f000000
+#define PHY_ANALOG_TXRF6_OFFSET2G_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TXRF6_OFFSET2G_SET(x) (((x) << 24) & 0x7f000000)
+#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_MSB 31
+#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_LSB 31
+#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_MASK 0x80000000
+#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF7 */
+#define PHY_ANALOG_TXRF7_ADDRESS 0x00000058
+#define PHY_ANALOG_TXRF7_OFFSET 0x00000058
+#define PHY_ANALOG_TXRF7_SPARE7_MSB 1
+#define PHY_ANALOG_TXRF7_SPARE7_LSB 0
+#define PHY_ANALOG_TXRF7_SPARE7_MASK 0x00000003
+#define PHY_ANALOG_TXRF7_SPARE7_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF7_SPARE7_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MSB 7
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_LSB 2
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MASK 0x000000fc
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MSB 13
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_LSB 8
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MASK 0x00003f00
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MSB 19
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_LSB 14
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MASK 0x000fc000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MSB 25
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_LSB 20
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MASK 0x03f00000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MSB 31
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_LSB 26
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MASK 0xfc000000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF8 */
+#define PHY_ANALOG_TXRF8_ADDRESS 0x0000005c
+#define PHY_ANALOG_TXRF8_OFFSET 0x0000005c
+#define PHY_ANALOG_TXRF8_SPARE8_MSB 1
+#define PHY_ANALOG_TXRF8_SPARE8_LSB 0
+#define PHY_ANALOG_TXRF8_SPARE8_MASK 0x00000003
+#define PHY_ANALOG_TXRF8_SPARE8_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF8_SPARE8_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MSB 7
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_LSB 2
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MASK 0x000000fc
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MSB 13
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_LSB 8
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MASK 0x00003f00
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MSB 19
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_LSB 14
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MASK 0x000fc000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MSB 25
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_LSB 20
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MASK 0x03f00000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MSB 31
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_LSB 26
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MASK 0xfc000000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF9 */
+#define PHY_ANALOG_TXRF9_ADDRESS 0x00000060
+#define PHY_ANALOG_TXRF9_OFFSET 0x00000060
+#define PHY_ANALOG_TXRF9_SPARE9_MSB 1
+#define PHY_ANALOG_TXRF9_SPARE9_LSB 0
+#define PHY_ANALOG_TXRF9_SPARE9_MASK 0x00000003
+#define PHY_ANALOG_TXRF9_SPARE9_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF9_SPARE9_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MSB 7
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_LSB 2
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MASK 0x000000fc
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MSB 13
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_LSB 8
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MASK 0x00003f00
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MSB 19
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_LSB 14
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MASK 0x000fc000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MSB 25
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_LSB 20
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MASK 0x03f00000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MSB 31
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_LSB 26
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MASK 0xfc000000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF10 */
+#define PHY_ANALOG_TXRF10_ADDRESS 0x00000064
+#define PHY_ANALOG_TXRF10_OFFSET 0x00000064
+#define PHY_ANALOG_TXRF10_SPARE10_MSB 12
+#define PHY_ANALOG_TXRF10_SPARE10_LSB 0
+#define PHY_ANALOG_TXRF10_SPARE10_MASK 0x00001fff
+#define PHY_ANALOG_TXRF10_SPARE10_GET(x) (((x) & 0x00001fff) >> 0)
+#define PHY_ANALOG_TXRF10_SPARE10_SET(x) (((x) << 0) & 0x00001fff)
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MSB 13
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_LSB 13
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MASK 0x00002000
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_MSB 16
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_LSB 14
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_MASK 0x0001c000
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_MSB 19
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_LSB 17
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_MASK 0x000e0000
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MSB 26
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_LSB 20
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MASK 0x07f00000
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_GET(x) (((x) & 0x07f00000) >> 20)
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_SET(x) (((x) << 20) & 0x07f00000)
+#define PHY_ANALOG_TXRF10_DB2GCALTX_MSB 29
+#define PHY_ANALOG_TXRF10_DB2GCALTX_LSB 27
+#define PHY_ANALOG_TXRF10_DB2GCALTX_MASK 0x38000000
+#define PHY_ANALOG_TXRF10_DB2GCALTX_GET(x) (((x) & 0x38000000) >> 27)
+#define PHY_ANALOG_TXRF10_DB2GCALTX_SET(x) (((x) << 27) & 0x38000000)
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_MSB 30
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_LSB 30
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_MASK 0x40000000
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MSB 31
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_LSB 31
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MASK 0x80000000
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF11 */
+#define PHY_ANALOG_TXRF11_ADDRESS 0x00000068
+#define PHY_ANALOG_TXRF11_OFFSET 0x00000068
+#define PHY_ANALOG_TXRF11_SPARE11_MSB 1
+#define PHY_ANALOG_TXRF11_SPARE11_LSB 0
+#define PHY_ANALOG_TXRF11_SPARE11_MASK 0x00000003
+#define PHY_ANALOG_TXRF11_SPARE11_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF11_SPARE11_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_MSB 4
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_LSB 2
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_MASK 0x0000001c
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MSB 7
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_LSB 5
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MASK 0x000000e0
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MSB 10
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_LSB 8
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MASK 0x00000700
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MSB 13
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_LSB 11
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MASK 0x00003800
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MSB 16
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_LSB 14
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MASK 0x0001c000
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MSB 19
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_LSB 17
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MASK 0x000e0000
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MSB 22
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_LSB 20
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MASK 0x00700000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MSB 25
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_LSB 23
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MASK 0x03800000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MSB 28
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_LSB 26
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MASK 0x1c000000
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MSB 31
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_LSB 29
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF12 */
+#define PHY_ANALOG_TXRF12_ADDRESS 0x0000006c
+#define PHY_ANALOG_TXRF12_OFFSET 0x0000006c
+#define PHY_ANALOG_TXRF12_SPARE12_2_MSB 7
+#define PHY_ANALOG_TXRF12_SPARE12_2_LSB 0
+#define PHY_ANALOG_TXRF12_SPARE12_2_MASK 0x000000ff
+#define PHY_ANALOG_TXRF12_SPARE12_2_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_ANALOG_TXRF12_SPARE12_1_MSB 15
+#define PHY_ANALOG_TXRF12_SPARE12_1_LSB 8
+#define PHY_ANALOG_TXRF12_SPARE12_1_MASK 0x0000ff00
+#define PHY_ANALOG_TXRF12_SPARE12_1_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_ANALOG_TXRF12_SPARE12_1_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_ANALOG_TXRF12_ATBSEL5G_MSB 19
+#define PHY_ANALOG_TXRF12_ATBSEL5G_LSB 16
+#define PHY_ANALOG_TXRF12_ATBSEL5G_MASK 0x000f0000
+#define PHY_ANALOG_TXRF12_ATBSEL5G_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_TXRF12_ATBSEL5G_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_TXRF12_ATBSEL2G_MSB 22
+#define PHY_ANALOG_TXRF12_ATBSEL2G_LSB 20
+#define PHY_ANALOG_TXRF12_ATBSEL2G_MASK 0x00700000
+#define PHY_ANALOG_TXRF12_ATBSEL2G_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF12_ATBSEL2G_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MSB 25
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_LSB 23
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MASK 0x03800000
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MSB 28
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_LSB 26
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MASK 0x1c000000
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MSB 31
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_LSB 29
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MASK 0xe0000000
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for SYNTH1 */
+#define PHY_ANALOG_SYNTH1_ADDRESS 0x00000080
+#define PHY_ANALOG_SYNTH1_OFFSET 0x00000080
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MSB 2
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_LSB 0
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MASK 0x00000007
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MSB 5
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_LSB 3
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MASK 0x00000038
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB 6
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB 6
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK 0x00000040
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MSB 7
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_LSB 7
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MASK 0x00000080
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MSB 8
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_LSB 8
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MASK 0x00000100
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MSB 9
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_LSB 9
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MASK 0x00000200
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_MSB 10
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_LSB 10
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_MASK 0x00000400
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_MSB 11
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_LSB 11
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_MASK 0x00000800
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MSB 12
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_LSB 12
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MASK 0x00001000
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_SYNTH1_PWUP_PD_MSB 15
+#define PHY_ANALOG_SYNTH1_PWUP_PD_LSB 13
+#define PHY_ANALOG_SYNTH1_PWUP_PD_MASK 0x0000e000
+#define PHY_ANALOG_SYNTH1_PWUP_PD_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_SYNTH1_PWUP_PD_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MSB 16
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_LSB 16
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MASK 0x00010000
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MSB 18
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_LSB 17
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MASK 0x00060000
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MSB 20
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_LSB 19
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MASK 0x00180000
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_GET(x) (((x) & 0x00180000) >> 19)
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_SET(x) (((x) << 19) & 0x00180000)
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MSB 21
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_LSB 21
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MASK 0x00200000
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MSB 22
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_LSB 22
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MASK 0x00400000
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MSB 23
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_LSB 23
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MASK 0x00800000
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_MSB 24
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_LSB 24
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_MASK 0x01000000
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MSB 25
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_LSB 25
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MASK 0x02000000
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MSB 26
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_LSB 26
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MASK 0x04000000
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_MSB 27
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_LSB 27
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_MASK 0x08000000
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_SYNTH1_PWD_VCO_MSB 28
+#define PHY_ANALOG_SYNTH1_PWD_VCO_LSB 28
+#define PHY_ANALOG_SYNTH1_PWD_VCO_MASK 0x10000000
+#define PHY_ANALOG_SYNTH1_PWD_VCO_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_SYNTH1_PWD_VCO_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_MSB 29
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_LSB 29
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_MASK 0x20000000
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_SYNTH1_PWD_CP_MSB 30
+#define PHY_ANALOG_SYNTH1_PWD_CP_LSB 30
+#define PHY_ANALOG_SYNTH1_PWD_CP_MASK 0x40000000
+#define PHY_ANALOG_SYNTH1_PWD_CP_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH1_PWD_CP_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_MSB 31
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_LSB 31
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_MASK 0x80000000
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH2 */
+#define PHY_ANALOG_SYNTH2_ADDRESS 0x00000084
+#define PHY_ANALOG_SYNTH2_OFFSET 0x00000084
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_MSB 3
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_LSB 0
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_MASK 0x0000000f
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_MSB 7
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_LSB 4
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_MASK 0x000000f0
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_MSB 11
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_LSB 8
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_MSB 15
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_LSB 12
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_MASK 0x0000f000
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_ANALOG_SYNTH2_CPLOWLK_MSB 16
+#define PHY_ANALOG_SYNTH2_CPLOWLK_LSB 16
+#define PHY_ANALOG_SYNTH2_CPLOWLK_MASK 0x00010000
+#define PHY_ANALOG_SYNTH2_CPLOWLK_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH2_CPLOWLK_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MSB 17
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_LSB 17
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MASK 0x00020000
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_SYNTH2_CPBIAS_MSB 19
+#define PHY_ANALOG_SYNTH2_CPBIAS_LSB 18
+#define PHY_ANALOG_SYNTH2_CPBIAS_MASK 0x000c0000
+#define PHY_ANALOG_SYNTH2_CPBIAS_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_SYNTH2_CPBIAS_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MSB 22
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_LSB 20
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MASK 0x00700000
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_MSB 25
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_LSB 23
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_MASK 0x03800000
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_MSB 28
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_LSB 26
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_MASK 0x1c000000
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MSB 31
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_LSB 29
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MASK 0xe0000000
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for SYNTH3 */
+#define PHY_ANALOG_SYNTH3_ADDRESS 0x00000088
+#define PHY_ANALOG_SYNTH3_OFFSET 0x00000088
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MSB 5
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_LSB 0
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MASK 0x0000003f
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MSB 11
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_LSB 6
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MASK 0x00000fc0
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MSB 17
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_LSB 12
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MASK 0x0003f000
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MSB 23
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_LSB 18
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MASK 0x00fc0000
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_SET(x) (((x) << 18) & 0x00fc0000)
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MSB 29
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_LSB 24
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MASK 0x3f000000
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_SET(x) (((x) << 24) & 0x3f000000)
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MSB 30
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_LSB 30
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MASK 0x40000000
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MSB 31
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_LSB 31
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MASK 0x80000000
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH4 */
+#define PHY_ANALOG_SYNTH4_ADDRESS 0x0000008c
+#define PHY_ANALOG_SYNTH4_OFFSET 0x0000008c
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MSB 0
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_LSB 0
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MASK 0x00000001
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MSB 1
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_LSB 1
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MASK 0x00000002
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MSB 3
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_LSB 2
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MASK 0x0000000c
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MSB 4
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_LSB 4
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MASK 0x00000010
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MSB 5
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_LSB 5
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MASK 0x00000020
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_SYNTH4_SDM_DITHER_MSB 7
+#define PHY_ANALOG_SYNTH4_SDM_DITHER_LSB 6
+#define PHY_ANALOG_SYNTH4_SDM_DITHER_MASK 0x000000c0
+#define PHY_ANALOG_SYNTH4_SDM_DITHER_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_ANALOG_SYNTH4_SDM_DITHER_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_ANALOG_SYNTH4_SDM_MODE_MSB 8
+#define PHY_ANALOG_SYNTH4_SDM_MODE_LSB 8
+#define PHY_ANALOG_SYNTH4_SDM_MODE_MASK 0x00000100
+#define PHY_ANALOG_SYNTH4_SDM_MODE_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_SYNTH4_SDM_MODE_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MSB 9
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_LSB 9
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MASK 0x00000200
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_MSB 10
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_LSB 10
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_MASK 0x00000400
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH4_PRESCSEL_MSB 12
+#define PHY_ANALOG_SYNTH4_PRESCSEL_LSB 11
+#define PHY_ANALOG_SYNTH4_PRESCSEL_MASK 0x00001800
+#define PHY_ANALOG_SYNTH4_PRESCSEL_GET(x) (((x) & 0x00001800) >> 11)
+#define PHY_ANALOG_SYNTH4_PRESCSEL_SET(x) (((x) << 11) & 0x00001800)
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MSB 13
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_LSB 13
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MASK 0x00002000
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MSB 14
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_LSB 14
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MASK 0x00004000
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MSB 15
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_LSB 15
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MASK 0x00008000
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MSB 16
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_LSB 16
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MASK 0x00010000
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MSB 17
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_LSB 17
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MASK 0x00020000
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MSB 25
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_LSB 18
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MASK 0x03fc0000
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_GET(x) (((x) & 0x03fc0000) >> 18)
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_SET(x) (((x) << 18) & 0x03fc0000)
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MSB 26
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_LSB 26
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MASK 0x04000000
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MSB 27
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_LSB 27
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MASK 0x08000000
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MSB 28
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_LSB 28
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MASK 0x10000000
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MSB 29
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_LSB 29
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MASK 0x20000000
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MSB 30
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_LSB 30
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MASK 0x40000000
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MSB 31
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_LSB 31
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MASK 0x80000000
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH5 */
+#define PHY_ANALOG_SYNTH5_ADDRESS 0x00000090
+#define PHY_ANALOG_SYNTH5_OFFSET 0x00000090
+#define PHY_ANALOG_SYNTH5_VCOBIAS_MSB 1
+#define PHY_ANALOG_SYNTH5_VCOBIAS_LSB 0
+#define PHY_ANALOG_SYNTH5_VCOBIAS_MASK 0x00000003
+#define PHY_ANALOG_SYNTH5_VCOBIAS_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH5_VCOBIAS_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MSB 4
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_LSB 2
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MASK 0x0000001c
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MSB 7
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_LSB 5
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MASK 0x000000e0
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MSB 10
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_LSB 8
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MASK 0x00000700
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MSB 13
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_LSB 11
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MASK 0x00003800
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MSB 14
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_LSB 14
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MASK 0x00004000
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MSB 17
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_LSB 15
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MASK 0x00038000
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MSB 20
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_LSB 18
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MASK 0x001c0000
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_GET(x) (((x) & 0x001c0000) >> 18)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_SET(x) (((x) << 18) & 0x001c0000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MSB 23
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_LSB 21
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MASK 0x00e00000
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_GET(x) (((x) & 0x00e00000) >> 21)
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_SET(x) (((x) << 21) & 0x00e00000)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MSB 26
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_LSB 24
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MASK 0x07000000
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MSB 29
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_LSB 27
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MASK 0x38000000
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_GET(x) (((x) & 0x38000000) >> 27)
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_SET(x) (((x) << 27) & 0x38000000)
+#define PHY_ANALOG_SYNTH5_SPARE5A_MSB 31
+#define PHY_ANALOG_SYNTH5_SPARE5A_LSB 30
+#define PHY_ANALOG_SYNTH5_SPARE5A_MASK 0xc0000000
+#define PHY_ANALOG_SYNTH5_SPARE5A_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_SYNTH5_SPARE5A_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for SYNTH6 */
+#define PHY_ANALOG_SYNTH6_ADDRESS 0x00000094
+#define PHY_ANALOG_SYNTH6_OFFSET 0x00000094
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MSB 1
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_LSB 0
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MASK 0x00000003
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH6_LOOP_IP_MSB 8
+#define PHY_ANALOG_SYNTH6_LOOP_IP_LSB 2
+#define PHY_ANALOG_SYNTH6_LOOP_IP_MASK 0x000001fc
+#define PHY_ANALOG_SYNTH6_LOOP_IP_GET(x) (((x) & 0x000001fc) >> 2)
+#define PHY_ANALOG_SYNTH6_VC2LOW_MSB 9
+#define PHY_ANALOG_SYNTH6_VC2LOW_LSB 9
+#define PHY_ANALOG_SYNTH6_VC2LOW_MASK 0x00000200
+#define PHY_ANALOG_SYNTH6_VC2LOW_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH6_VC2HIGH_MSB 10
+#define PHY_ANALOG_SYNTH6_VC2HIGH_LSB 10
+#define PHY_ANALOG_SYNTH6_VC2HIGH_MASK 0x00000400
+#define PHY_ANALOG_SYNTH6_VC2HIGH_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MSB 11
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_LSB 11
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MASK 0x00000800
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MSB 12
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_LSB 12
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MASK 0x00001000
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_SYNTH6_RESET_PFD_MSB 13
+#define PHY_ANALOG_SYNTH6_RESET_PFD_LSB 13
+#define PHY_ANALOG_SYNTH6_RESET_PFD_MASK 0x00002000
+#define PHY_ANALOG_SYNTH6_RESET_PFD_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_SYNTH6_RESET_RFD_MSB 14
+#define PHY_ANALOG_SYNTH6_RESET_RFD_LSB 14
+#define PHY_ANALOG_SYNTH6_RESET_RFD_MASK 0x00004000
+#define PHY_ANALOG_SYNTH6_RESET_RFD_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH6_SHORT_R_MSB 15
+#define PHY_ANALOG_SYNTH6_SHORT_R_LSB 15
+#define PHY_ANALOG_SYNTH6_SHORT_R_MASK 0x00008000
+#define PHY_ANALOG_SYNTH6_SHORT_R_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MSB 23
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_LSB 16
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MASK 0x00ff0000
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_SYNTH6_PIN_VC_MSB 24
+#define PHY_ANALOG_SYNTH6_PIN_VC_LSB 24
+#define PHY_ANALOG_SYNTH6_PIN_VC_MASK 0x01000000
+#define PHY_ANALOG_SYNTH6_PIN_VC_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MSB 25
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_LSB 25
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MASK 0x02000000
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MSB 26
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_LSB 26
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MASK 0x04000000
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MSB 30
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_LSB 27
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MASK 0x78000000
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_MSB 31
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_LSB 31
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_MASK 0x80000000
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_GET(x) (((x) & 0x80000000) >> 31)
+
+/* macros for SYNTH7 */
+#define PHY_ANALOG_SYNTH7_ADDRESS 0x00000098
+#define PHY_ANALOG_SYNTH7_OFFSET 0x00000098
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MSB 0
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_LSB 0
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MASK 0x00000001
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MSB 1
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_LSB 1
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MASK 0x00000002
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_SYNTH7_CHANFRAC_MSB 18
+#define PHY_ANALOG_SYNTH7_CHANFRAC_LSB 2
+#define PHY_ANALOG_SYNTH7_CHANFRAC_MASK 0x0007fffc
+#define PHY_ANALOG_SYNTH7_CHANFRAC_GET(x) (((x) & 0x0007fffc) >> 2)
+#define PHY_ANALOG_SYNTH7_CHANFRAC_SET(x) (((x) << 2) & 0x0007fffc)
+#define PHY_ANALOG_SYNTH7_CHANSEL_MSB 27
+#define PHY_ANALOG_SYNTH7_CHANSEL_LSB 19
+#define PHY_ANALOG_SYNTH7_CHANSEL_MASK 0x0ff80000
+#define PHY_ANALOG_SYNTH7_CHANSEL_GET(x) (((x) & 0x0ff80000) >> 19)
+#define PHY_ANALOG_SYNTH7_CHANSEL_SET(x) (((x) << 19) & 0x0ff80000)
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MSB 29
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_LSB 28
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MASK 0x30000000
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_GET(x) (((x) & 0x30000000) >> 28)
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_SET(x) (((x) << 28) & 0x30000000)
+#define PHY_ANALOG_SYNTH7_FRACMODE_MSB 30
+#define PHY_ANALOG_SYNTH7_FRACMODE_LSB 30
+#define PHY_ANALOG_SYNTH7_FRACMODE_MASK 0x40000000
+#define PHY_ANALOG_SYNTH7_FRACMODE_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH7_FRACMODE_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MSB 31
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_LSB 31
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MASK 0x80000000
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH8 */
+#define PHY_ANALOG_SYNTH8_ADDRESS 0x0000009c
+#define PHY_ANALOG_SYNTH8_OFFSET 0x0000009c
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MSB 0
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_LSB 0
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MASK 0x00000001
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MSB 7
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_LSB 1
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MASK 0x000000fe
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_MSB 11
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_LSB 8
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_MSB 16
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_LSB 12
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_MASK 0x0001f000
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_MSB 21
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_LSB 17
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_MASK 0x003e0000
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MSB 26
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_LSB 22
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH8_REFDIVB_MSB 31
+#define PHY_ANALOG_SYNTH8_REFDIVB_LSB 27
+#define PHY_ANALOG_SYNTH8_REFDIVB_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH8_REFDIVB_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH8_REFDIVB_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH9 */
+#define PHY_ANALOG_SYNTH9_ADDRESS 0x000000a0
+#define PHY_ANALOG_SYNTH9_OFFSET 0x000000a0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MSB 0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_LSB 0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MASK 0x00000001
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MSB 3
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_LSB 1
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MASK 0x0000000e
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MSB 7
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_LSB 4
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MASK 0x000000f0
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MSB 11
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_LSB 8
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MSB 16
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_LSB 12
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MASK 0x0001f000
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MSB 21
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_LSB 17
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MASK 0x003e0000
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MSB 26
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_LSB 22
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH9_REFDIVA_MSB 31
+#define PHY_ANALOG_SYNTH9_REFDIVA_LSB 27
+#define PHY_ANALOG_SYNTH9_REFDIVA_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH9_REFDIVA_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH9_REFDIVA_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH10 */
+#define PHY_ANALOG_SYNTH10_ADDRESS 0x000000a4
+#define PHY_ANALOG_SYNTH10_OFFSET 0x000000a4
+#define PHY_ANALOG_SYNTH10_SPARE10A_MSB 0
+#define PHY_ANALOG_SYNTH10_SPARE10A_LSB 0
+#define PHY_ANALOG_SYNTH10_SPARE10A_MASK 0x00000001
+#define PHY_ANALOG_SYNTH10_SPARE10A_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH10_SPARE10A_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MSB 3
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_LSB 1
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MASK 0x0000000e
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_MSB 4
+#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_LSB 4
+#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_MASK 0x00000010
+#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MSB 7
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_LSB 5
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MASK 0x000000e0
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MSB 10
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_LSB 8
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MASK 0x00000700
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MSB 13
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_LSB 11
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MASK 0x00003800
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MSB 17
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_LSB 14
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MASK 0x0003c000
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_GET(x) (((x) & 0x0003c000) >> 14)
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_SET(x) (((x) << 14) & 0x0003c000)
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MSB 21
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_LSB 18
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MASK 0x003c0000
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_GET(x) (((x) & 0x003c0000) >> 18)
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_SET(x) (((x) << 18) & 0x003c0000)
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MSB 26
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_LSB 22
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MSB 31
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_LSB 27
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH11 */
+#define PHY_ANALOG_SYNTH11_ADDRESS 0x000000a8
+#define PHY_ANALOG_SYNTH11_OFFSET 0x000000a8
+#define PHY_ANALOG_SYNTH11_SPARE11A_MSB 4
+#define PHY_ANALOG_SYNTH11_SPARE11A_LSB 0
+#define PHY_ANALOG_SYNTH11_SPARE11A_MASK 0x0000001f
+#define PHY_ANALOG_SYNTH11_SPARE11A_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_SYNTH11_SPARE11A_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MSB 5
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_LSB 5
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MASK 0x00000020
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_SYNTH11_LOREFSEL_MSB 7
+#define PHY_ANALOG_SYNTH11_LOREFSEL_LSB 6
+#define PHY_ANALOG_SYNTH11_LOREFSEL_MASK 0x000000c0
+#define PHY_ANALOG_SYNTH11_LOREFSEL_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_ANALOG_SYNTH11_LOREFSEL_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MSB 9
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_LSB 8
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MASK 0x00000300
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MSB 10
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_LSB 10
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MASK 0x00000400
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MSB 13
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_LSB 11
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MASK 0x00003800
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MSB 17
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_LSB 14
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MASK 0x0003c000
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_GET(x) (((x) & 0x0003c000) >> 14)
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_SET(x) (((x) << 14) & 0x0003c000)
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MSB 21
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_LSB 18
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MASK 0x003c0000
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_GET(x) (((x) & 0x003c0000) >> 18)
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_SET(x) (((x) << 18) & 0x003c0000)
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MSB 26
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_LSB 22
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MSB 31
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_LSB 27
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH12 */
+#define PHY_ANALOG_SYNTH12_ADDRESS 0x000000ac
+#define PHY_ANALOG_SYNTH12_OFFSET 0x000000ac
+#define PHY_ANALOG_SYNTH12_SPARE12A_MSB 17
+#define PHY_ANALOG_SYNTH12_SPARE12A_LSB 0
+#define PHY_ANALOG_SYNTH12_SPARE12A_MASK 0x0003ffff
+#define PHY_ANALOG_SYNTH12_SPARE12A_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_ANALOG_SYNTH12_SPARE12A_SET(x) (((x) << 0) & 0x0003ffff)
+#define PHY_ANALOG_SYNTH12_STRCONT_MSB 18
+#define PHY_ANALOG_SYNTH12_STRCONT_LSB 18
+#define PHY_ANALOG_SYNTH12_STRCONT_MASK 0x00040000
+#define PHY_ANALOG_SYNTH12_STRCONT_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_SYNTH12_STRCONT_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_SYNTH12_VREFMUL3_MSB 22
+#define PHY_ANALOG_SYNTH12_VREFMUL3_LSB 19
+#define PHY_ANALOG_SYNTH12_VREFMUL3_MASK 0x00780000
+#define PHY_ANALOG_SYNTH12_VREFMUL3_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_ANALOG_SYNTH12_VREFMUL3_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_ANALOG_SYNTH12_VREFMUL2_MSB 26
+#define PHY_ANALOG_SYNTH12_VREFMUL2_LSB 23
+#define PHY_ANALOG_SYNTH12_VREFMUL2_MASK 0x07800000
+#define PHY_ANALOG_SYNTH12_VREFMUL2_GET(x) (((x) & 0x07800000) >> 23)
+#define PHY_ANALOG_SYNTH12_VREFMUL2_SET(x) (((x) << 23) & 0x07800000)
+#define PHY_ANALOG_SYNTH12_VREFMUL1_MSB 30
+#define PHY_ANALOG_SYNTH12_VREFMUL1_LSB 27
+#define PHY_ANALOG_SYNTH12_VREFMUL1_MASK 0x78000000
+#define PHY_ANALOG_SYNTH12_VREFMUL1_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_SYNTH12_VREFMUL1_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MSB 31
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_LSB 31
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MASK 0x80000000
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BIAS1 */
+#define PHY_ANALOG_BIAS1_ADDRESS 0x000000c0
+#define PHY_ANALOG_BIAS1_OFFSET 0x000000c0
+#define PHY_ANALOG_BIAS1_SPARE1_MSB 6
+#define PHY_ANALOG_BIAS1_SPARE1_LSB 0
+#define PHY_ANALOG_BIAS1_SPARE1_MASK 0x0000007f
+#define PHY_ANALOG_BIAS1_SPARE1_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_BIAS1_SPARE1_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MSB 9
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_LSB 7
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MASK 0x00000380
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MSB 12
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_LSB 10
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MASK 0x00001c00
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_GET(x) (((x) & 0x00001c00) >> 10)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_SET(x) (((x) << 10) & 0x00001c00)
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_MSB 15
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_LSB 13
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_MASK 0x0000e000
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MSB 18
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_LSB 16
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MASK 0x00070000
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MSB 21
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_LSB 19
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MASK 0x00380000
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MSB 24
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_LSB 22
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MASK 0x01c00000
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_GET(x) (((x) & 0x01c00000) >> 22)
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_SET(x) (((x) << 22) & 0x01c00000)
+#define PHY_ANALOG_BIAS1_BIAS_SEL_MSB 31
+#define PHY_ANALOG_BIAS1_BIAS_SEL_LSB 25
+#define PHY_ANALOG_BIAS1_BIAS_SEL_MASK 0xfe000000
+#define PHY_ANALOG_BIAS1_BIAS_SEL_GET(x) (((x) & 0xfe000000) >> 25)
+#define PHY_ANALOG_BIAS1_BIAS_SEL_SET(x) (((x) << 25) & 0xfe000000)
+
+/* macros for BIAS2 */
+#define PHY_ANALOG_BIAS2_ADDRESS 0x000000c4
+#define PHY_ANALOG_BIAS2_OFFSET 0x000000c4
+#define PHY_ANALOG_BIAS2_SPARE2_MSB 4
+#define PHY_ANALOG_BIAS2_SPARE2_LSB 0
+#define PHY_ANALOG_BIAS2_SPARE2_MASK 0x0000001f
+#define PHY_ANALOG_BIAS2_SPARE2_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_BIAS2_SPARE2_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_MSB 7
+#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_LSB 5
+#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_MASK 0x000000e0
+#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MSB 10
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_LSB 8
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MASK 0x00000700
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MSB 13
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_LSB 11
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MASK 0x00003800
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MSB 16
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_LSB 14
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MASK 0x0001c000
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_MSB 19
+#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_LSB 17
+#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_MASK 0x000e0000
+#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MSB 22
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_LSB 20
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MASK 0x00700000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MSB 25
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_LSB 23
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MASK 0x03800000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MSB 28
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_LSB 26
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MASK 0x1c000000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MSB 31
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_LSB 29
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MASK 0xe0000000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for BIAS3 */
+#define PHY_ANALOG_BIAS3_ADDRESS 0x000000c8
+#define PHY_ANALOG_BIAS3_OFFSET 0x000000c8
+#define PHY_ANALOG_BIAS3_SPARE3_MSB 1
+#define PHY_ANALOG_BIAS3_SPARE3_LSB 0
+#define PHY_ANALOG_BIAS3_SPARE3_MASK 0x00000003
+#define PHY_ANALOG_BIAS3_SPARE3_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_BIAS3_SPARE3_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_MSB 4
+#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_LSB 2
+#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_MASK 0x0000001c
+#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MSB 7
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_LSB 5
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MASK 0x000000e0
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MSB 10
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_LSB 8
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MASK 0x00000700
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_MSB 13
+#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_LSB 11
+#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_MASK 0x00003800
+#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MSB 16
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_LSB 14
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MASK 0x0001c000
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_MSB 19
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_LSB 17
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_MASK 0x000e0000
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MSB 22
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_LSB 20
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MASK 0x00700000
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MSB 25
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_LSB 23
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MASK 0x03800000
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MSB 28
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_LSB 26
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MASK 0x1c000000
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MSB 31
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_LSB 29
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MASK 0xe0000000
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for BIAS4 */
+#define PHY_ANALOG_BIAS4_ADDRESS 0x000000cc
+#define PHY_ANALOG_BIAS4_OFFSET 0x000000cc
+#define PHY_ANALOG_BIAS4_SPARE4_MSB 13
+#define PHY_ANALOG_BIAS4_SPARE4_LSB 0
+#define PHY_ANALOG_BIAS4_SPARE4_MASK 0x00003fff
+#define PHY_ANALOG_BIAS4_SPARE4_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_ANALOG_BIAS4_SPARE4_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MSB 16
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_LSB 14
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MASK 0x0001c000
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MSB 19
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_LSB 17
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MASK 0x000e0000
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_MSB 22
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_LSB 20
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_MASK 0x00700000
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MSB 25
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_LSB 23
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MASK 0x03800000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MSB 28
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_LSB 26
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MASK 0x1c000000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MSB 31
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_LSB 29
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MASK 0xe0000000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXTX1 */
+#define PHY_ANALOG_RXTX1_ADDRESS 0x00000100
+#define PHY_ANALOG_RXTX1_OFFSET 0x00000100
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MSB 0
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_LSB 0
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MASK 0x00000001
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXTX1_MANRXGAIN_MSB 1
+#define PHY_ANALOG_RXTX1_MANRXGAIN_LSB 1
+#define PHY_ANALOG_RXTX1_MANRXGAIN_MASK 0x00000002
+#define PHY_ANALOG_RXTX1_MANRXGAIN_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXTX1_MANRXGAIN_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_MSB 5
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_LSB 2
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_MASK 0x0000003c
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_GET(x) (((x) & 0x0000003c) >> 2)
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_SET(x) (((x) << 2) & 0x0000003c)
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MSB 6
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_LSB 6
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MASK 0x00000040
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_MSB 7
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_LSB 7
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_MASK 0x00000080
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MSB 8
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_LSB 8
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MSB 11
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_LSB 9
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MASK 0x00000e00
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MSB 13
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_LSB 12
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MASK 0x00003000
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_SET(x) (((x) << 12) & 0x00003000)
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MSB 14
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_LSB 14
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MASK 0x00004000
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXTX1_PADRV2GN_MSB 18
+#define PHY_ANALOG_RXTX1_PADRV2GN_LSB 15
+#define PHY_ANALOG_RXTX1_PADRV2GN_MASK 0x00078000
+#define PHY_ANALOG_RXTX1_PADRV2GN_GET(x) (((x) & 0x00078000) >> 15)
+#define PHY_ANALOG_RXTX1_PADRV2GN_SET(x) (((x) << 15) & 0x00078000)
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_MSB 22
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_LSB 19
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_MASK 0x00780000
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_MSB 26
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_LSB 23
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_MASK 0x07800000
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_GET(x) (((x) & 0x07800000) >> 23)
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_SET(x) (((x) << 23) & 0x07800000)
+#define PHY_ANALOG_RXTX1_TXBB_GC_MSB 30
+#define PHY_ANALOG_RXTX1_TXBB_GC_LSB 27
+#define PHY_ANALOG_RXTX1_TXBB_GC_MASK 0x78000000
+#define PHY_ANALOG_RXTX1_TXBB_GC_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_RXTX1_TXBB_GC_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_RXTX1_MANTXGAIN_MSB 31
+#define PHY_ANALOG_RXTX1_MANTXGAIN_LSB 31
+#define PHY_ANALOG_RXTX1_MANTXGAIN_MASK 0x80000000
+#define PHY_ANALOG_RXTX1_MANTXGAIN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXTX1_MANTXGAIN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXTX2 */
+#define PHY_ANALOG_RXTX2_ADDRESS 0x00000104
+#define PHY_ANALOG_RXTX2_OFFSET 0x00000104
+#define PHY_ANALOG_RXTX2_BMODE_MSB 0
+#define PHY_ANALOG_RXTX2_BMODE_LSB 0
+#define PHY_ANALOG_RXTX2_BMODE_MASK 0x00000001
+#define PHY_ANALOG_RXTX2_BMODE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXTX2_BMODE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXTX2_BMODE_OVR_MSB 1
+#define PHY_ANALOG_RXTX2_BMODE_OVR_LSB 1
+#define PHY_ANALOG_RXTX2_BMODE_OVR_MASK 0x00000002
+#define PHY_ANALOG_RXTX2_BMODE_OVR_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXTX2_BMODE_OVR_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXTX2_SYNTHON_MSB 2
+#define PHY_ANALOG_RXTX2_SYNTHON_LSB 2
+#define PHY_ANALOG_RXTX2_SYNTHON_MASK 0x00000004
+#define PHY_ANALOG_RXTX2_SYNTHON_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_RXTX2_SYNTHON_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MSB 3
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_LSB 3
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MASK 0x00000008
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RXTX2_BW_ST_MSB 5
+#define PHY_ANALOG_RXTX2_BW_ST_LSB 4
+#define PHY_ANALOG_RXTX2_BW_ST_MASK 0x00000030
+#define PHY_ANALOG_RXTX2_BW_ST_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_ANALOG_RXTX2_BW_ST_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_MSB 6
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_LSB 6
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_MASK 0x00000040
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX2_TXON_MSB 7
+#define PHY_ANALOG_RXTX2_TXON_LSB 7
+#define PHY_ANALOG_RXTX2_TXON_MASK 0x00000080
+#define PHY_ANALOG_RXTX2_TXON_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX2_TXON_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX2_TXON_OVR_MSB 8
+#define PHY_ANALOG_RXTX2_TXON_OVR_LSB 8
+#define PHY_ANALOG_RXTX2_TXON_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX2_TXON_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX2_TXON_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX2_PAON_MSB 9
+#define PHY_ANALOG_RXTX2_PAON_LSB 9
+#define PHY_ANALOG_RXTX2_PAON_MASK 0x00000200
+#define PHY_ANALOG_RXTX2_PAON_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXTX2_PAON_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXTX2_PAON_OVR_MSB 10
+#define PHY_ANALOG_RXTX2_PAON_OVR_LSB 10
+#define PHY_ANALOG_RXTX2_PAON_OVR_MASK 0x00000400
+#define PHY_ANALOG_RXTX2_PAON_OVR_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXTX2_PAON_OVR_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXTX2_RXON_MSB 11
+#define PHY_ANALOG_RXTX2_RXON_LSB 11
+#define PHY_ANALOG_RXTX2_RXON_MASK 0x00000800
+#define PHY_ANALOG_RXTX2_RXON_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_RXTX2_RXON_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_RXTX2_RXON_OVR_MSB 12
+#define PHY_ANALOG_RXTX2_RXON_OVR_LSB 12
+#define PHY_ANALOG_RXTX2_RXON_OVR_MASK 0x00001000
+#define PHY_ANALOG_RXTX2_RXON_OVR_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_RXTX2_RXON_OVR_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_RXTX2_AGCON_MSB 13
+#define PHY_ANALOG_RXTX2_AGCON_LSB 13
+#define PHY_ANALOG_RXTX2_AGCON_MASK 0x00002000
+#define PHY_ANALOG_RXTX2_AGCON_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RXTX2_AGCON_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RXTX2_AGCON_OVR_MSB 14
+#define PHY_ANALOG_RXTX2_AGCON_OVR_LSB 14
+#define PHY_ANALOG_RXTX2_AGCON_OVR_MASK 0x00004000
+#define PHY_ANALOG_RXTX2_AGCON_OVR_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXTX2_AGCON_OVR_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXTX2_TXMOD_MSB 17
+#define PHY_ANALOG_RXTX2_TXMOD_LSB 15
+#define PHY_ANALOG_RXTX2_TXMOD_MASK 0x00038000
+#define PHY_ANALOG_RXTX2_TXMOD_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_RXTX2_TXMOD_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_MSB 18
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_LSB 18
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_MASK 0x00040000
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MSB 21
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_LSB 19
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MASK 0x00380000
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MSB 23
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_LSB 22
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MASK 0x00c00000
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_RXTX2_MXRGAIN_MSB 25
+#define PHY_ANALOG_RXTX2_MXRGAIN_LSB 24
+#define PHY_ANALOG_RXTX2_MXRGAIN_MASK 0x03000000
+#define PHY_ANALOG_RXTX2_MXRGAIN_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_ANALOG_RXTX2_MXRGAIN_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_ANALOG_RXTX2_VGAGAIN_MSB 28
+#define PHY_ANALOG_RXTX2_VGAGAIN_LSB 26
+#define PHY_ANALOG_RXTX2_VGAGAIN_MASK 0x1c000000
+#define PHY_ANALOG_RXTX2_VGAGAIN_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_RXTX2_VGAGAIN_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_RXTX2_LNAGAIN_MSB 31
+#define PHY_ANALOG_RXTX2_LNAGAIN_LSB 29
+#define PHY_ANALOG_RXTX2_LNAGAIN_MASK 0xe0000000
+#define PHY_ANALOG_RXTX2_LNAGAIN_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_RXTX2_LNAGAIN_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXTX3 */
+#define PHY_ANALOG_RXTX3_ADDRESS 0x00000108
+#define PHY_ANALOG_RXTX3_OFFSET 0x00000108
+#define PHY_ANALOG_RXTX3_SPARE3_MSB 2
+#define PHY_ANALOG_RXTX3_SPARE3_LSB 0
+#define PHY_ANALOG_RXTX3_SPARE3_MASK 0x00000007
+#define PHY_ANALOG_RXTX3_SPARE3_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_RXTX3_SPARE3_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_MSB 3
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_LSB 3
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_MASK 0x00000008
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RXTX3_DACRSTB_MSB 4
+#define PHY_ANALOG_RXTX3_DACRSTB_LSB 4
+#define PHY_ANALOG_RXTX3_DACRSTB_MASK 0x00000010
+#define PHY_ANALOG_RXTX3_DACRSTB_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RXTX3_DACRSTB_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_MSB 5
+#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_LSB 5
+#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_MASK 0x00000020
+#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_RXTX3_ADCSHORT_MSB 6
+#define PHY_ANALOG_RXTX3_ADCSHORT_LSB 6
+#define PHY_ANALOG_RXTX3_ADCSHORT_MASK 0x00000040
+#define PHY_ANALOG_RXTX3_ADCSHORT_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX3_ADCSHORT_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX3_DACPWD_MSB 7
+#define PHY_ANALOG_RXTX3_DACPWD_LSB 7
+#define PHY_ANALOG_RXTX3_DACPWD_MASK 0x00000080
+#define PHY_ANALOG_RXTX3_DACPWD_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX3_DACPWD_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_MSB 8
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_LSB 8
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX3_ADCPWD_MSB 9
+#define PHY_ANALOG_RXTX3_ADCPWD_LSB 9
+#define PHY_ANALOG_RXTX3_ADCPWD_MASK 0x00000200
+#define PHY_ANALOG_RXTX3_ADCPWD_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXTX3_ADCPWD_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MSB 10
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_LSB 10
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MASK 0x00000400
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_MSB 16
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_LSB 11
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_MASK 0x0001f800
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_GET(x) (((x) & 0x0001f800) >> 11)
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_SET(x) (((x) << 11) & 0x0001f800)
+#define PHY_ANALOG_RXTX3_AGC_CAL_MSB 17
+#define PHY_ANALOG_RXTX3_AGC_CAL_LSB 17
+#define PHY_ANALOG_RXTX3_AGC_CAL_MASK 0x00020000
+#define PHY_ANALOG_RXTX3_AGC_CAL_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RXTX3_AGC_CAL_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MSB 18
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_LSB 18
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MASK 0x00040000
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_RXTX3_LOFORCEDON_MSB 19
+#define PHY_ANALOG_RXTX3_LOFORCEDON_LSB 19
+#define PHY_ANALOG_RXTX3_LOFORCEDON_MASK 0x00080000
+#define PHY_ANALOG_RXTX3_LOFORCEDON_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_RXTX3_LOFORCEDON_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_MSB 20
+#define PHY_ANALOG_RXTX3_CALRESIDUE_LSB 20
+#define PHY_ANALOG_RXTX3_CALRESIDUE_MASK 0x00100000
+#define PHY_ANALOG_RXTX3_CALRESIDUE_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MSB 21
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_LSB 21
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MASK 0x00200000
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_RXTX3_CALFC_MSB 22
+#define PHY_ANALOG_RXTX3_CALFC_LSB 22
+#define PHY_ANALOG_RXTX3_CALFC_MASK 0x00400000
+#define PHY_ANALOG_RXTX3_CALFC_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_RXTX3_CALFC_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_RXTX3_CALFC_OVR_MSB 23
+#define PHY_ANALOG_RXTX3_CALFC_OVR_LSB 23
+#define PHY_ANALOG_RXTX3_CALFC_OVR_MASK 0x00800000
+#define PHY_ANALOG_RXTX3_CALFC_OVR_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_RXTX3_CALFC_OVR_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_RXTX3_CALTX_MSB 24
+#define PHY_ANALOG_RXTX3_CALTX_LSB 24
+#define PHY_ANALOG_RXTX3_CALTX_MASK 0x01000000
+#define PHY_ANALOG_RXTX3_CALTX_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_RXTX3_CALTX_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_RXTX3_CALTX_OVR_MSB 25
+#define PHY_ANALOG_RXTX3_CALTX_OVR_LSB 25
+#define PHY_ANALOG_RXTX3_CALTX_OVR_MASK 0x02000000
+#define PHY_ANALOG_RXTX3_CALTX_OVR_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_RXTX3_CALTX_OVR_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_MSB 26
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_LSB 26
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_MASK 0x04000000
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MSB 27
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_LSB 27
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MASK 0x08000000
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_RXTX3_CALPA_MSB 28
+#define PHY_ANALOG_RXTX3_CALPA_LSB 28
+#define PHY_ANALOG_RXTX3_CALPA_MASK 0x10000000
+#define PHY_ANALOG_RXTX3_CALPA_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_RXTX3_CALPA_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_RXTX3_CALPA_OVR_MSB 29
+#define PHY_ANALOG_RXTX3_CALPA_OVR_LSB 29
+#define PHY_ANALOG_RXTX3_CALPA_OVR_MASK 0x20000000
+#define PHY_ANALOG_RXTX3_CALPA_OVR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_RXTX3_CALPA_OVR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_RXTX3_SPURON_MSB 30
+#define PHY_ANALOG_RXTX3_SPURON_LSB 30
+#define PHY_ANALOG_RXTX3_SPURON_MASK 0x40000000
+#define PHY_ANALOG_RXTX3_SPURON_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_RXTX3_SPURON_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_RXTX3_SPURON_OVR_MSB 31
+#define PHY_ANALOG_RXTX3_SPURON_OVR_LSB 31
+#define PHY_ANALOG_RXTX3_SPURON_OVR_MASK 0x80000000
+#define PHY_ANALOG_RXTX3_SPURON_OVR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXTX3_SPURON_OVR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB1 */
+#define PHY_ANALOG_BB1_ADDRESS 0x00000140
+#define PHY_ANALOG_BB1_OFFSET 0x00000140
+#define PHY_ANALOG_BB1_I2V_CURR2X_MSB 0
+#define PHY_ANALOG_BB1_I2V_CURR2X_LSB 0
+#define PHY_ANALOG_BB1_I2V_CURR2X_MASK 0x00000001
+#define PHY_ANALOG_BB1_I2V_CURR2X_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_BB1_I2V_CURR2X_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_BB1_ENABLE_LOQ_MSB 1
+#define PHY_ANALOG_BB1_ENABLE_LOQ_LSB 1
+#define PHY_ANALOG_BB1_ENABLE_LOQ_MASK 0x00000002
+#define PHY_ANALOG_BB1_ENABLE_LOQ_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_BB1_ENABLE_LOQ_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_BB1_FORCE_LOQ_MSB 2
+#define PHY_ANALOG_BB1_FORCE_LOQ_LSB 2
+#define PHY_ANALOG_BB1_FORCE_LOQ_MASK 0x00000004
+#define PHY_ANALOG_BB1_FORCE_LOQ_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_BB1_FORCE_LOQ_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_MSB 3
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_LSB 3
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_MASK 0x00000008
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_BB1_FORCE_NOTCH_MSB 4
+#define PHY_ANALOG_BB1_FORCE_NOTCH_LSB 4
+#define PHY_ANALOG_BB1_FORCE_NOTCH_MASK 0x00000010
+#define PHY_ANALOG_BB1_FORCE_NOTCH_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_BB1_FORCE_NOTCH_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MSB 5
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_LSB 5
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MASK 0x00000020
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_MSB 6
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_LSB 6
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_MASK 0x00000040
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_MSB 7
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_LSB 7
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_MASK 0x00000080
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_BB1_FORCE_OSDAC_MSB 8
+#define PHY_ANALOG_BB1_FORCE_OSDAC_LSB 8
+#define PHY_ANALOG_BB1_FORCE_OSDAC_MASK 0x00000100
+#define PHY_ANALOG_BB1_FORCE_OSDAC_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_BB1_FORCE_OSDAC_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_BB1_ENABLE_V2I_MSB 9
+#define PHY_ANALOG_BB1_ENABLE_V2I_LSB 9
+#define PHY_ANALOG_BB1_ENABLE_V2I_MASK 0x00000200
+#define PHY_ANALOG_BB1_ENABLE_V2I_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_BB1_ENABLE_V2I_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_BB1_FORCE_V2I_MSB 10
+#define PHY_ANALOG_BB1_FORCE_V2I_LSB 10
+#define PHY_ANALOG_BB1_FORCE_V2I_MASK 0x00000400
+#define PHY_ANALOG_BB1_FORCE_V2I_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_BB1_FORCE_V2I_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_BB1_ENABLE_I2V_MSB 11
+#define PHY_ANALOG_BB1_ENABLE_I2V_LSB 11
+#define PHY_ANALOG_BB1_ENABLE_I2V_MASK 0x00000800
+#define PHY_ANALOG_BB1_ENABLE_I2V_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_BB1_ENABLE_I2V_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_BB1_FORCE_I2V_MSB 12
+#define PHY_ANALOG_BB1_FORCE_I2V_LSB 12
+#define PHY_ANALOG_BB1_FORCE_I2V_MASK 0x00001000
+#define PHY_ANALOG_BB1_FORCE_I2V_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_BB1_FORCE_I2V_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_BB1_CMSEL_MSB 15
+#define PHY_ANALOG_BB1_CMSEL_LSB 13
+#define PHY_ANALOG_BB1_CMSEL_MASK 0x0000e000
+#define PHY_ANALOG_BB1_CMSEL_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_BB1_CMSEL_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_BB1_ATBSEL_MSB 17
+#define PHY_ANALOG_BB1_ATBSEL_LSB 16
+#define PHY_ANALOG_BB1_ATBSEL_MASK 0x00030000
+#define PHY_ANALOG_BB1_ATBSEL_GET(x) (((x) & 0x00030000) >> 16)
+#define PHY_ANALOG_BB1_ATBSEL_SET(x) (((x) << 16) & 0x00030000)
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MSB 18
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_LSB 18
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MASK 0x00040000
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MSB 23
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_LSB 19
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MASK 0x00f80000
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_GET(x) (((x) & 0x00f80000) >> 19)
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_SET(x) (((x) << 19) & 0x00f80000)
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_MSB 28
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_LSB 24
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_MASK 0x1f000000
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_SET(x) (((x) << 24) & 0x1f000000)
+#define PHY_ANALOG_BB1_LOCALOFFSET_MSB 29
+#define PHY_ANALOG_BB1_LOCALOFFSET_LSB 29
+#define PHY_ANALOG_BB1_LOCALOFFSET_MASK 0x20000000
+#define PHY_ANALOG_BB1_LOCALOFFSET_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_BB1_LOCALOFFSET_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_BB1_RANGE_OSDAC_MSB 31
+#define PHY_ANALOG_BB1_RANGE_OSDAC_LSB 30
+#define PHY_ANALOG_BB1_RANGE_OSDAC_MASK 0xc0000000
+#define PHY_ANALOG_BB1_RANGE_OSDAC_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_BB1_RANGE_OSDAC_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for BB2 */
+#define PHY_ANALOG_BB2_ADDRESS 0x00000144
+#define PHY_ANALOG_BB2_OFFSET 0x00000144
+#define PHY_ANALOG_BB2_SPARE_MSB 6
+#define PHY_ANALOG_BB2_SPARE_LSB 0
+#define PHY_ANALOG_BB2_SPARE_MASK 0x0000007f
+#define PHY_ANALOG_BB2_SPARE_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_BB2_SPARE_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_BB2_SEL_TEST_MSB 9
+#define PHY_ANALOG_BB2_SEL_TEST_LSB 7
+#define PHY_ANALOG_BB2_SEL_TEST_MASK 0x00000380
+#define PHY_ANALOG_BB2_SEL_TEST_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_BB2_SEL_TEST_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_BB2_SCFIR_CAP_MSB 14
+#define PHY_ANALOG_BB2_SCFIR_CAP_LSB 10
+#define PHY_ANALOG_BB2_SCFIR_CAP_MASK 0x00007c00
+#define PHY_ANALOG_BB2_SCFIR_CAP_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_ANALOG_BB2_SCFIR_CAP_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_MSB 15
+#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_LSB 15
+#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_MASK 0x00008000
+#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_BB2_FNOTCH_MSB 19
+#define PHY_ANALOG_BB2_FNOTCH_LSB 16
+#define PHY_ANALOG_BB2_FNOTCH_MASK 0x000f0000
+#define PHY_ANALOG_BB2_FNOTCH_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_BB2_FNOTCH_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MSB 20
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_LSB 20
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MASK 0x00100000
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_BB2_FILTERFC_MSB 25
+#define PHY_ANALOG_BB2_FILTERFC_LSB 21
+#define PHY_ANALOG_BB2_FILTERFC_MASK 0x03e00000
+#define PHY_ANALOG_BB2_FILTERFC_GET(x) (((x) & 0x03e00000) >> 21)
+#define PHY_ANALOG_BB2_FILTERFC_SET(x) (((x) << 21) & 0x03e00000)
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MSB 26
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_LSB 26
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MASK 0x04000000
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MSB 27
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_LSB 27
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MASK 0x08000000
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MSB 28
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_LSB 28
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MASK 0x10000000
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_MSB 29
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_LSB 29
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_MASK 0x20000000
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_MSB 30
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_LSB 30
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_MASK 0x40000000
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MSB 31
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_LSB 31
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TOP1 */
+#define PHY_ANALOG_TOP1_ADDRESS 0x00000280
+#define PHY_ANALOG_TOP1_OFFSET 0x00000280
+#define PHY_ANALOG_TOP1_SEL_KVCO_MSB 1
+#define PHY_ANALOG_TOP1_SEL_KVCO_LSB 0
+#define PHY_ANALOG_TOP1_SEL_KVCO_MASK 0x00000003
+#define PHY_ANALOG_TOP1_SEL_KVCO_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TOP1_SEL_KVCO_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TOP1_PLLATB_MSB 3
+#define PHY_ANALOG_TOP1_PLLATB_LSB 2
+#define PHY_ANALOG_TOP1_PLLATB_MASK 0x0000000c
+#define PHY_ANALOG_TOP1_PLLATB_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_TOP1_PLLATB_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_TOP1_PLL_SVREG_MSB 4
+#define PHY_ANALOG_TOP1_PLL_SVREG_LSB 4
+#define PHY_ANALOG_TOP1_PLL_SVREG_MASK 0x00000010
+#define PHY_ANALOG_TOP1_PLL_SVREG_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_TOP1_PLL_SVREG_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_TOP1_HI_FREQ_EN_MSB 5
+#define PHY_ANALOG_TOP1_HI_FREQ_EN_LSB 5
+#define PHY_ANALOG_TOP1_HI_FREQ_EN_MASK 0x00000020
+#define PHY_ANALOG_TOP1_HI_FREQ_EN_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_TOP1_HI_FREQ_EN_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_TOP1_PWDPLL_MSB 6
+#define PHY_ANALOG_TOP1_PWDPLL_LSB 6
+#define PHY_ANALOG_TOP1_PWDPLL_MASK 0x00000040
+#define PHY_ANALOG_TOP1_PWDPLL_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_TOP1_PWDPLL_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_MSB 7
+#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_LSB 7
+#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_MASK 0x00000080
+#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_TOP1_ADCPWD_PHASE_MSB 9
+#define PHY_ANALOG_TOP1_ADCPWD_PHASE_LSB 8
+#define PHY_ANALOG_TOP1_ADCPWD_PHASE_MASK 0x00000300
+#define PHY_ANALOG_TOP1_ADCPWD_PHASE_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_TOP1_ADCPWD_PHASE_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_TOP1_ADCCLK_PHASE_MSB 11
+#define PHY_ANALOG_TOP1_ADCCLK_PHASE_LSB 10
+#define PHY_ANALOG_TOP1_ADCCLK_PHASE_MASK 0x00000c00
+#define PHY_ANALOG_TOP1_ADCCLK_PHASE_GET(x) (((x) & 0x00000c00) >> 10)
+#define PHY_ANALOG_TOP1_ADCCLK_PHASE_SET(x) (((x) << 10) & 0x00000c00)
+#define PHY_ANALOG_TOP1_DAC_CLK_SEL_MSB 13
+#define PHY_ANALOG_TOP1_DAC_CLK_SEL_LSB 12
+#define PHY_ANALOG_TOP1_DAC_CLK_SEL_MASK 0x00003000
+#define PHY_ANALOG_TOP1_DAC_CLK_SEL_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_ANALOG_TOP1_DAC_CLK_SEL_SET(x) (((x) << 12) & 0x00003000)
+#define PHY_ANALOG_TOP1_ADC_CLK_SEL_MSB 15
+#define PHY_ANALOG_TOP1_ADC_CLK_SEL_LSB 14
+#define PHY_ANALOG_TOP1_ADC_CLK_SEL_MASK 0x0000c000
+#define PHY_ANALOG_TOP1_ADC_CLK_SEL_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_ANALOG_TOP1_ADC_CLK_SEL_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_ANALOG_TOP1_REFDIV_MSB 19
+#define PHY_ANALOG_TOP1_REFDIV_LSB 16
+#define PHY_ANALOG_TOP1_REFDIV_MASK 0x000f0000
+#define PHY_ANALOG_TOP1_REFDIV_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_TOP1_REFDIV_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_TOP1_DIV_MSB 29
+#define PHY_ANALOG_TOP1_DIV_LSB 20
+#define PHY_ANALOG_TOP1_DIV_MASK 0x3ff00000
+#define PHY_ANALOG_TOP1_DIV_GET(x) (((x) & 0x3ff00000) >> 20)
+#define PHY_ANALOG_TOP1_DIV_SET(x) (((x) << 20) & 0x3ff00000)
+#define PHY_ANALOG_TOP1_PLLBYPASS_MSB 30
+#define PHY_ANALOG_TOP1_PLLBYPASS_LSB 30
+#define PHY_ANALOG_TOP1_PLLBYPASS_MASK 0x40000000
+#define PHY_ANALOG_TOP1_PLLBYPASS_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_TOP1_PLLBYPASS_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_TOP1_CLKMOD_RSTB_MSB 31
+#define PHY_ANALOG_TOP1_CLKMOD_RSTB_LSB 31
+#define PHY_ANALOG_TOP1_CLKMOD_RSTB_MASK 0x80000000
+#define PHY_ANALOG_TOP1_CLKMOD_RSTB_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TOP1_CLKMOD_RSTB_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TOP2 */
+#define PHY_ANALOG_TOP2_ADDRESS 0x00000284
+#define PHY_ANALOG_TOP2_OFFSET 0x00000284
+#define PHY_ANALOG_TOP2_PLL_LOWLEAK_MSB 0
+#define PHY_ANALOG_TOP2_PLL_LOWLEAK_LSB 0
+#define PHY_ANALOG_TOP2_PLL_LOWLEAK_MASK 0x00000001
+#define PHY_ANALOG_TOP2_PLL_LOWLEAK_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TOP2_PLL_LOWLEAK_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TOP2_PLL_LEAK_MSB 4
+#define PHY_ANALOG_TOP2_PLL_LEAK_LSB 1
+#define PHY_ANALOG_TOP2_PLL_LEAK_MASK 0x0000001e
+#define PHY_ANALOG_TOP2_PLL_LEAK_GET(x) (((x) & 0x0000001e) >> 1)
+#define PHY_ANALOG_TOP2_PLL_LEAK_SET(x) (((x) << 1) & 0x0000001e)
+#define PHY_ANALOG_TOP2_PLLFRAC_MSB 19
+#define PHY_ANALOG_TOP2_PLLFRAC_LSB 5
+#define PHY_ANALOG_TOP2_PLLFRAC_MASK 0x000fffe0
+#define PHY_ANALOG_TOP2_PLLFRAC_GET(x) (((x) & 0x000fffe0) >> 5)
+#define PHY_ANALOG_TOP2_PLLFRAC_SET(x) (((x) << 5) & 0x000fffe0)
+#define PHY_ANALOG_TOP2_PWD_PLLSDM_MSB 20
+#define PHY_ANALOG_TOP2_PWD_PLLSDM_LSB 20
+#define PHY_ANALOG_TOP2_PWD_PLLSDM_MASK 0x00100000
+#define PHY_ANALOG_TOP2_PWD_PLLSDM_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TOP2_PWD_PLLSDM_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TOP2_PLLICP_MSB 23
+#define PHY_ANALOG_TOP2_PLLICP_LSB 21
+#define PHY_ANALOG_TOP2_PLLICP_MASK 0x00e00000
+#define PHY_ANALOG_TOP2_PLLICP_GET(x) (((x) & 0x00e00000) >> 21)
+#define PHY_ANALOG_TOP2_PLLICP_SET(x) (((x) << 21) & 0x00e00000)
+#define PHY_ANALOG_TOP2_PLLFILTER_MSB 31
+#define PHY_ANALOG_TOP2_PLLFILTER_LSB 24
+#define PHY_ANALOG_TOP2_PLLFILTER_MASK 0xff000000
+#define PHY_ANALOG_TOP2_PLLFILTER_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_ANALOG_TOP2_PLLFILTER_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for TOP3 */
+#define PHY_ANALOG_TOP3_ADDRESS 0x00000288
+#define PHY_ANALOG_TOP3_OFFSET 0x00000288
+#define PHY_ANALOG_TOP3_INT2GND_MSB 0
+#define PHY_ANALOG_TOP3_INT2GND_LSB 0
+#define PHY_ANALOG_TOP3_INT2GND_MASK 0x00000001
+#define PHY_ANALOG_TOP3_INT2GND_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TOP3_INT2GND_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TOP3_PWDPALCLK_MSB 1
+#define PHY_ANALOG_TOP3_PWDPALCLK_LSB 1
+#define PHY_ANALOG_TOP3_PWDPALCLK_MASK 0x00000002
+#define PHY_ANALOG_TOP3_PWDPALCLK_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_TOP3_PWDPALCLK_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_TOP3_PWDAGCCLK_MSB 2
+#define PHY_ANALOG_TOP3_PWDAGCCLK_LSB 2
+#define PHY_ANALOG_TOP3_PWDAGCCLK_MASK 0x00000004
+#define PHY_ANALOG_TOP3_PWDAGCCLK_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_TOP3_PWDAGCCLK_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_TOP3_PWDV2I_MSB 3
+#define PHY_ANALOG_TOP3_PWDV2I_LSB 3
+#define PHY_ANALOG_TOP3_PWDV2I_MASK 0x00000008
+#define PHY_ANALOG_TOP3_PWDV2I_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TOP3_PWDV2I_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_TOP3_PWDBIAS_MSB 4
+#define PHY_ANALOG_TOP3_PWDBIAS_LSB 4
+#define PHY_ANALOG_TOP3_PWDBIAS_MASK 0x00000010
+#define PHY_ANALOG_TOP3_PWDBIAS_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_TOP3_PWDBIAS_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_TOP3_PWDBG_MSB 5
+#define PHY_ANALOG_TOP3_PWDBG_LSB 5
+#define PHY_ANALOG_TOP3_PWDBG_MASK 0x00000020
+#define PHY_ANALOG_TOP3_PWDBG_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_TOP3_PWDBG_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_TOP3_XTAL_SELVREG_MSB 6
+#define PHY_ANALOG_TOP3_XTAL_SELVREG_LSB 6
+#define PHY_ANALOG_TOP3_XTAL_SELVREG_MASK 0x00000040
+#define PHY_ANALOG_TOP3_XTAL_SELVREG_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_TOP3_XTAL_SELVREG_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_TOP3_XTAL_PWDREG_MSB 7
+#define PHY_ANALOG_TOP3_XTAL_PWDREG_LSB 7
+#define PHY_ANALOG_TOP3_XTAL_PWDREG_MASK 0x00000080
+#define PHY_ANALOG_TOP3_XTAL_PWDREG_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_TOP3_XTAL_PWDREG_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_MSB 8
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_LSB 8
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_MASK 0x00000100
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_MSB 9
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_LSB 9
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_MASK 0x00000200
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_TOP3_XTAL_OSCON_MSB 10
+#define PHY_ANALOG_TOP3_XTAL_OSCON_LSB 10
+#define PHY_ANALOG_TOP3_XTAL_OSCON_MASK 0x00000400
+#define PHY_ANALOG_TOP3_XTAL_OSCON_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_TOP3_XTAL_OSCON_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_MSB 11
+#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_LSB 11
+#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_MASK 0x00000800
+#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_MSB 12
+#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_LSB 12
+#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_MASK 0x00001000
+#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_TOP3_XTAL_HIGHZ_MSB 13
+#define PHY_ANALOG_TOP3_XTAL_HIGHZ_LSB 13
+#define PHY_ANALOG_TOP3_XTAL_HIGHZ_MASK 0x00002000
+#define PHY_ANALOG_TOP3_XTAL_HIGHZ_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TOP3_XTAL_HIGHZ_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TOP3_XTAL_DRVPNR_MSB 15
+#define PHY_ANALOG_TOP3_XTAL_DRVPNR_LSB 14
+#define PHY_ANALOG_TOP3_XTAL_DRVPNR_MASK 0x0000c000
+#define PHY_ANALOG_TOP3_XTAL_DRVPNR_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_ANALOG_TOP3_XTAL_DRVPNR_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_MSB 22
+#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_LSB 16
+#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_MASK 0x007f0000
+#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_GET(x) (((x) & 0x007f0000) >> 16)
+#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_SET(x) (((x) << 16) & 0x007f0000)
+#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_MSB 29
+#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_LSB 23
+#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_MASK 0x3f800000
+#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_GET(x) (((x) & 0x3f800000) >> 23)
+#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_SET(x) (((x) << 23) & 0x3f800000)
+#define PHY_ANALOG_TOP3_XTAL_BIAS2X_MSB 30
+#define PHY_ANALOG_TOP3_XTAL_BIAS2X_LSB 30
+#define PHY_ANALOG_TOP3_XTAL_BIAS2X_MASK 0x40000000
+#define PHY_ANALOG_TOP3_XTAL_BIAS2X_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_TOP3_XTAL_BIAS2X_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_TOP3_TCXODET_MSB 31
+#define PHY_ANALOG_TOP3_TCXODET_LSB 31
+#define PHY_ANALOG_TOP3_TCXODET_MASK 0x80000000
+#define PHY_ANALOG_TOP3_TCXODET_GET(x) (((x) & 0x80000000) >> 31)
+
+/* macros for TOP4 */
+#define PHY_ANALOG_TOP4_ADDRESS 0x0000028c
+#define PHY_ANALOG_TOP4_OFFSET 0x0000028c
+#define PHY_ANALOG_TOP4_SPARE4_MSB 19
+#define PHY_ANALOG_TOP4_SPARE4_LSB 0
+#define PHY_ANALOG_TOP4_SPARE4_MASK 0x000fffff
+#define PHY_ANALOG_TOP4_SPARE4_GET(x) (((x) & 0x000fffff) >> 0)
+#define PHY_ANALOG_TOP4_SPARE4_SET(x) (((x) << 0) & 0x000fffff)
+#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_MSB 20
+#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_LSB 20
+#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_MASK 0x00100000
+#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TOP4_ADCPWD_OVR_MSB 21
+#define PHY_ANALOG_TOP4_ADCPWD_OVR_LSB 21
+#define PHY_ANALOG_TOP4_ADCPWD_OVR_MASK 0x00200000
+#define PHY_ANALOG_TOP4_ADCPWD_OVR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TOP4_ADCPWD_OVR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TOP4_ADCPWD_INT_MSB 22
+#define PHY_ANALOG_TOP4_ADCPWD_INT_LSB 22
+#define PHY_ANALOG_TOP4_ADCPWD_INT_MASK 0x00400000
+#define PHY_ANALOG_TOP4_ADCPWD_INT_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TOP4_ADCPWD_INT_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TOP4_TESTIQ_OFF_MSB 23
+#define PHY_ANALOG_TOP4_TESTIQ_OFF_LSB 23
+#define PHY_ANALOG_TOP4_TESTIQ_OFF_MASK 0x00800000
+#define PHY_ANALOG_TOP4_TESTIQ_OFF_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_TOP4_TESTIQ_OFF_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_MSB 24
+#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_LSB 24
+#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_MASK 0x01000000
+#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_MSB 25
+#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_LSB 25
+#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_MASK 0x02000000
+#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_MSB 26
+#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_LSB 26
+#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_MASK 0x04000000
+#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_TOP4_ENBTCLK_MSB 27
+#define PHY_ANALOG_TOP4_ENBTCLK_LSB 27
+#define PHY_ANALOG_TOP4_ENBTCLK_MASK 0x08000000
+#define PHY_ANALOG_TOP4_ENBTCLK_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_TOP4_ENBTCLK_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_TOP4_PAD2GND_MSB 28
+#define PHY_ANALOG_TOP4_PAD2GND_LSB 28
+#define PHY_ANALOG_TOP4_PAD2GND_MASK 0x10000000
+#define PHY_ANALOG_TOP4_PAD2GND_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_TOP4_PAD2GND_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_TOP4_INTH2PAD_MSB 29
+#define PHY_ANALOG_TOP4_INTH2PAD_LSB 29
+#define PHY_ANALOG_TOP4_INTH2PAD_MASK 0x20000000
+#define PHY_ANALOG_TOP4_INTH2PAD_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_TOP4_INTH2PAD_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_TOP4_INTH2GND_MSB 30
+#define PHY_ANALOG_TOP4_INTH2GND_LSB 30
+#define PHY_ANALOG_TOP4_INTH2GND_MASK 0x40000000
+#define PHY_ANALOG_TOP4_INTH2GND_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_TOP4_INTH2GND_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_TOP4_INT2PAD_MSB 31
+#define PHY_ANALOG_TOP4_INT2PAD_LSB 31
+#define PHY_ANALOG_TOP4_INT2PAD_MASK 0x80000000
+#define PHY_ANALOG_TOP4_INT2PAD_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TOP4_INT2PAD_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for rbist_cntrl */
+#define PHY_ANALOG_RBIST_CNTRL_ADDRESS 0x00000380
+#define PHY_ANALOG_RBIST_CNTRL_OFFSET 0x00000380
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MSB 0
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_LSB 0
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MASK 0x00000001
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MSB 1
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_LSB 1
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MASK 0x00000002
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MSB 2
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_LSB 2
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MASK 0x00000004
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MSB 3
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_LSB 3
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MASK 0x00000008
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MSB 4
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_LSB 4
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MASK 0x00000010
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MSB 5
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_LSB 5
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MASK 0x00000020
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MSB 6
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_LSB 6
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MASK 0x00000040
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MSB 7
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_LSB 7
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MASK 0x00000080
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MSB 8
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_LSB 8
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MASK 0x00000100
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MSB 9
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_LSB 9
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MASK 0x00000200
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MSB 10
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_LSB 10
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MASK 0x00000400
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MSB 11
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_LSB 11
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MASK 0x00000800
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MSB 12
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_LSB 12
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MASK 0x00001000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MSB 13
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_LSB 13
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MASK 0x00002000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MSB 14
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_LSB 14
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MASK 0x00004000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MSB 15
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_LSB 15
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MASK 0x00008000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MSB 16
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_LSB 16
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MASK 0x00010000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MSB 17
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_LSB 17
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MASK 0x00020000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_SET(x) (((x) << 17) & 0x00020000)
+
+/* macros for tx_dc_offset */
+#define PHY_ANALOG_TX_DC_OFFSET_ADDRESS 0x00000384
+#define PHY_ANALOG_TX_DC_OFFSET_OFFSET 0x00000384
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MSB 10
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_LSB 0
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MASK 0x000007ff
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MSB 26
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_LSB 16
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MASK 0x07ff0000
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_GET(x) (((x) & 0x07ff0000) >> 16)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_SET(x) (((x) << 16) & 0x07ff0000)
+
+/* macros for tx_tonegen0 */
+#define PHY_ANALOG_TX_TONEGEN0_ADDRESS 0x00000388
+#define PHY_ANALOG_TX_TONEGEN0_OFFSET 0x00000388
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_tonegen1 */
+#define PHY_ANALOG_TX_TONEGEN1_ADDRESS 0x0000038c
+#define PHY_ANALOG_TX_TONEGEN1_OFFSET 0x0000038c
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_lftonegen0 */
+#define PHY_ANALOG_TX_LFTONEGEN0_ADDRESS 0x00000390
+#define PHY_ANALOG_TX_LFTONEGEN0_OFFSET 0x00000390
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_linear_ramp_i */
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ADDRESS 0x00000394
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_OFFSET 0x00000394
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MSB 10
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_LSB 0
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MASK 0x000007ff
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MSB 21
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_LSB 12
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MASK 0x003ff000
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MSB 29
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_LSB 24
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MASK 0x3f000000
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for tx_linear_ramp_q */
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ADDRESS 0x00000398
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_OFFSET 0x00000398
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MSB 10
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_LSB 0
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MASK 0x000007ff
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MSB 21
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_LSB 12
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MASK 0x003ff000
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MSB 29
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_LSB 24
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MASK 0x3f000000
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for tx_prbs_mag */
+#define PHY_ANALOG_TX_PRBS_MAG_ADDRESS 0x0000039c
+#define PHY_ANALOG_TX_PRBS_MAG_OFFSET 0x0000039c
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MSB 9
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_LSB 0
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MASK 0x000003ff
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MSB 25
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_LSB 16
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MASK 0x03ff0000
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_SET(x) (((x) << 16) & 0x03ff0000)
+
+/* macros for tx_prbs_seed_i */
+#define PHY_ANALOG_TX_PRBS_SEED_I_ADDRESS 0x000003a0
+#define PHY_ANALOG_TX_PRBS_SEED_I_OFFSET 0x000003a0
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MSB 30
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_LSB 0
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MASK 0x7fffffff
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_GET(x) (((x) & 0x7fffffff) >> 0)
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_SET(x) (((x) << 0) & 0x7fffffff)
+
+/* macros for tx_prbs_seed_q */
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ADDRESS 0x000003a4
+#define PHY_ANALOG_TX_PRBS_SEED_Q_OFFSET 0x000003a4
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MSB 30
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_LSB 0
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MASK 0x7fffffff
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_GET(x) (((x) & 0x7fffffff) >> 0)
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_SET(x) (((x) << 0) & 0x7fffffff)
+
+/* macros for cmac_dc_cancel */
+#define PHY_ANALOG_CMAC_DC_CANCEL_ADDRESS 0x000003a8
+#define PHY_ANALOG_CMAC_DC_CANCEL_OFFSET 0x000003a8
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MSB 9
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_LSB 0
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MASK 0x000003ff
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MSB 25
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_LSB 16
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MASK 0x03ff0000
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_SET(x) (((x) << 16) & 0x03ff0000)
+
+/* macros for cmac_dc_offset */
+#define PHY_ANALOG_CMAC_DC_OFFSET_ADDRESS 0x000003ac
+#define PHY_ANALOG_CMAC_DC_OFFSET_OFFSET 0x000003ac
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_corr */
+#define PHY_ANALOG_CMAC_CORR_ADDRESS 0x000003b0
+#define PHY_ANALOG_CMAC_CORR_OFFSET 0x000003b0
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MSB 4
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MASK 0x0000001f
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MSB 13
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_LSB 8
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MASK 0x00003f00
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_SET(x) (((x) << 8) & 0x00003f00)
+
+/* macros for cmac_power */
+#define PHY_ANALOG_CMAC_POWER_ADDRESS 0x000003b4
+#define PHY_ANALOG_CMAC_POWER_OFFSET 0x000003b4
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_cross_corr */
+#define PHY_ANALOG_CMAC_CROSS_CORR_ADDRESS 0x000003b8
+#define PHY_ANALOG_CMAC_CROSS_CORR_OFFSET 0x000003b8
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_i2q2 */
+#define PHY_ANALOG_CMAC_I2Q2_ADDRESS 0x000003bc
+#define PHY_ANALOG_CMAC_I2Q2_OFFSET 0x000003bc
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_power_hpf */
+#define PHY_ANALOG_CMAC_POWER_HPF_ADDRESS 0x000003c0
+#define PHY_ANALOG_CMAC_POWER_HPF_OFFSET 0x000003c0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MSB 7
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_LSB 4
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MASK 0x000000f0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_SET(x) (((x) << 4) & 0x000000f0)
+
+/* macros for rxdac_set1 */
+#define PHY_ANALOG_RXDAC_SET1_ADDRESS 0x000003c4
+#define PHY_ANALOG_RXDAC_SET1_OFFSET 0x000003c4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MSB 1
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_LSB 0
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MASK 0x00000003
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MSB 4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_LSB 4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MASK 0x00000010
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MSB 13
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_LSB 8
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MASK 0x00003f00
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MSB 19
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_LSB 16
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MASK 0x000f0000
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_SET(x) (((x) << 16) & 0x000f0000)
+
+/* macros for rxdac_set2 */
+#define PHY_ANALOG_RXDAC_SET2_ADDRESS 0x000003c8
+#define PHY_ANALOG_RXDAC_SET2_OFFSET 0x000003c8
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MSB 4
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_LSB 0
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MASK 0x0000001f
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MSB 12
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_LSB 8
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MASK 0x00001f00
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_SET(x) (((x) << 8) & 0x00001f00)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MSB 20
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_LSB 16
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MASK 0x001f0000
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MSB 28
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_LSB 24
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MASK 0x1f000000
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_SET(x) (((x) << 24) & 0x1f000000)
+
+/* macros for rxdac_long_shift */
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ADDRESS 0x000003cc
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_OFFSET 0x000003cc
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MSB 4
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_LSB 0
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MASK 0x0000001f
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MSB 12
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_LSB 8
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MASK 0x00001f00
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_SET(x) (((x) << 8) & 0x00001f00)
+
+/* macros for cmac_results_i */
+#define PHY_ANALOG_CMAC_RESULTS_I_ADDRESS 0x000003d0
+#define PHY_ANALOG_CMAC_RESULTS_I_OFFSET 0x000003d0
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MSB 31
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_LSB 0
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MASK 0xffffffff
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for cmac_results_q */
+#define PHY_ANALOG_CMAC_RESULTS_Q_ADDRESS 0x000003d4
+#define PHY_ANALOG_CMAC_RESULTS_Q_OFFSET 0x000003d4
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MSB 31
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_LSB 0
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MASK 0xffffffff
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for PMU1 */
+#define PHY_ANALOG_PMU1_ADDRESS 0x00000740
+#define PHY_ANALOG_PMU1_OFFSET 0x00000740
+#define PHY_ANALOG_PMU1_SPARE_MSB 10
+#define PHY_ANALOG_PMU1_SPARE_LSB 0
+#define PHY_ANALOG_PMU1_SPARE_MASK 0x000007ff
+#define PHY_ANALOG_PMU1_SPARE_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_PMU1_SPARE_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_MSB 11
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_LSB 11
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_MASK 0x00000800
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_PMU1_PAREGON_MAN_MSB 12
+#define PHY_ANALOG_PMU1_PAREGON_MAN_LSB 12
+#define PHY_ANALOG_PMU1_PAREGON_MAN_MASK 0x00001000
+#define PHY_ANALOG_PMU1_PAREGON_MAN_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_PMU1_PAREGON_MAN_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_MSB 13
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_LSB 13
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_MASK 0x00002000
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_PMU1_DREGON_MAN_MSB 14
+#define PHY_ANALOG_PMU1_DREGON_MAN_LSB 14
+#define PHY_ANALOG_PMU1_DREGON_MAN_MASK 0x00004000
+#define PHY_ANALOG_PMU1_DREGON_MAN_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_PMU1_DREGON_MAN_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_MSB 15
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_LSB 15
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_MASK 0x00008000
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_PMU1_SWREGON_MAN_MSB 16
+#define PHY_ANALOG_PMU1_SWREGON_MAN_LSB 16
+#define PHY_ANALOG_PMU1_SWREGON_MAN_MASK 0x00010000
+#define PHY_ANALOG_PMU1_SWREGON_MAN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_PMU1_SWREGON_MAN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MSB 18
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_LSB 17
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MASK 0x00060000
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MSB 21
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_LSB 19
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MASK 0x00380000
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MSB 23
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_LSB 22
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MASK 0x00c00000
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_MSB 25
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_LSB 24
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_MASK 0x03000000
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_MSB 27
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_LSB 26
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_MASK 0x0c000000
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_ANALOG_PMU1_PAREG_XPNP_MSB 28
+#define PHY_ANALOG_PMU1_PAREG_XPNP_LSB 28
+#define PHY_ANALOG_PMU1_PAREG_XPNP_MASK 0x10000000
+#define PHY_ANALOG_PMU1_PAREG_XPNP_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_PMU1_PAREG_XPNP_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MSB 31
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_LSB 29
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MASK 0xe0000000
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for PMU2 */
+#define PHY_ANALOG_PMU2_ADDRESS 0x00000744
+#define PHY_ANALOG_PMU2_OFFSET 0x00000744
+#define PHY_ANALOG_PMU2_SPARE_MSB 7
+#define PHY_ANALOG_PMU2_SPARE_LSB 0
+#define PHY_ANALOG_PMU2_SPARE_MASK 0x000000ff
+#define PHY_ANALOG_PMU2_SPARE_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_ANALOG_PMU2_SPARE_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MSB 8
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_LSB 8
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MASK 0x00000100
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MSB 9
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_LSB 9
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MASK 0x00000200
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MSB 10
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_LSB 10
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MASK 0x00000400
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MSB 11
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_LSB 11
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MASK 0x00000800
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MSB 12
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_LSB 12
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MASK 0x00001000
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MSB 13
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_LSB 13
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MASK 0x00002000
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MSB 14
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_LSB 14
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MASK 0x00004000
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MSB 15
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_LSB 15
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MASK 0x00008000
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MSB 16
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_LSB 16
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MASK 0x00010000
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MSB 18
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_LSB 17
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MASK 0x00060000
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MSB 19
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_LSB 19
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MASK 0x00080000
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MSB 21
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_LSB 20
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MASK 0x00300000
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_GET(x) (((x) & 0x00300000) >> 20)
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_SET(x) (((x) << 20) & 0x00300000)
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MSB 22
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_LSB 22
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MASK 0x00400000
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MSB 24
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_LSB 23
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MASK 0x01800000
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_GET(x) (((x) & 0x01800000) >> 23)
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_SET(x) (((x) << 23) & 0x01800000)
+#define PHY_ANALOG_PMU2_SWREG2ATB_MSB 27
+#define PHY_ANALOG_PMU2_SWREG2ATB_LSB 25
+#define PHY_ANALOG_PMU2_SWREG2ATB_MASK 0x0e000000
+#define PHY_ANALOG_PMU2_SWREG2ATB_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_ANALOG_PMU2_SWREG2ATB_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_ANALOG_PMU2_OTPREG2ATB_MSB 28
+#define PHY_ANALOG_PMU2_OTPREG2ATB_LSB 28
+#define PHY_ANALOG_PMU2_OTPREG2ATB_MASK 0x10000000
+#define PHY_ANALOG_PMU2_OTPREG2ATB_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_PMU2_OTPREG2ATB_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MSB 30
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_LSB 29
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MASK 0x60000000
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_SET(x) (((x) << 29) & 0x60000000)
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MSB 31
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_LSB 31
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MASK 0x80000000
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_SET(x) (((x) << 31) & 0x80000000)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct analog_intf_ares_reg_reg_s {
+ volatile unsigned int RXRF_BIAS1; /* 0x0 - 0x4 */
+ volatile unsigned int RXRF_BIAS2; /* 0x4 - 0x8 */
+ volatile unsigned int RXRF_GAINSTAGES; /* 0x8 - 0xc */
+ volatile unsigned int RXRF_AGC; /* 0xc - 0x10 */
+ volatile char pad__0[0x30]; /* 0x10 - 0x40 */
+ volatile unsigned int TXRF1; /* 0x40 - 0x44 */
+ volatile unsigned int TXRF2; /* 0x44 - 0x48 */
+ volatile unsigned int TXRF3; /* 0x48 - 0x4c */
+ volatile unsigned int TXRF4; /* 0x4c - 0x50 */
+ volatile unsigned int TXRF5; /* 0x50 - 0x54 */
+ volatile unsigned int TXRF6; /* 0x54 - 0x58 */
+ volatile unsigned int TXRF7; /* 0x58 - 0x5c */
+ volatile unsigned int TXRF8; /* 0x5c - 0x60 */
+ volatile unsigned int TXRF9; /* 0x60 - 0x64 */
+ volatile unsigned int TXRF10; /* 0x64 - 0x68 */
+ volatile unsigned int TXRF11; /* 0x68 - 0x6c */
+ volatile unsigned int TXRF12; /* 0x6c - 0x70 */
+ volatile char pad__1[0x10]; /* 0x70 - 0x80 */
+ volatile unsigned int SYNTH1; /* 0x80 - 0x84 */
+ volatile unsigned int SYNTH2; /* 0x84 - 0x88 */
+ volatile unsigned int SYNTH3; /* 0x88 - 0x8c */
+ volatile unsigned int SYNTH4; /* 0x8c - 0x90 */
+ volatile unsigned int SYNTH5; /* 0x90 - 0x94 */
+ volatile unsigned int SYNTH6; /* 0x94 - 0x98 */
+ volatile unsigned int SYNTH7; /* 0x98 - 0x9c */
+ volatile unsigned int SYNTH8; /* 0x9c - 0xa0 */
+ volatile unsigned int SYNTH9; /* 0xa0 - 0xa4 */
+ volatile unsigned int SYNTH10; /* 0xa4 - 0xa8 */
+ volatile unsigned int SYNTH11; /* 0xa8 - 0xac */
+ volatile unsigned int SYNTH12; /* 0xac - 0xb0 */
+ volatile char pad__2[0x10]; /* 0xb0 - 0xc0 */
+ volatile unsigned int BIAS1; /* 0xc0 - 0xc4 */
+ volatile unsigned int BIAS2; /* 0xc4 - 0xc8 */
+ volatile unsigned int BIAS3; /* 0xc8 - 0xcc */
+ volatile unsigned int BIAS4; /* 0xcc - 0xd0 */
+ volatile char pad__3[0x30]; /* 0xd0 - 0x100 */
+ volatile unsigned int RXTX1; /* 0x100 - 0x104 */
+ volatile unsigned int RXTX2; /* 0x104 - 0x108 */
+ volatile unsigned int RXTX3; /* 0x108 - 0x10c */
+ volatile char pad__4[0x34]; /* 0x10c - 0x140 */
+ volatile unsigned int BB1; /* 0x140 - 0x144 */
+ volatile unsigned int BB2; /* 0x144 - 0x148 */
+ volatile char pad__5[0x138]; /* 0x148 - 0x280 */
+ volatile unsigned int TOP1; /* 0x280 - 0x284 */
+ volatile unsigned int TOP2; /* 0x284 - 0x288 */
+ volatile unsigned int TOP3; /* 0x288 - 0x28c */
+ volatile unsigned int TOP4; /* 0x28c - 0x290 */
+ volatile char pad__6[0xf0]; /* 0x290 - 0x380 */
+ volatile unsigned int rbist_cntrl; /* 0x380 - 0x384 */
+ volatile unsigned int tx_dc_offset; /* 0x384 - 0x388 */
+ volatile unsigned int tx_tonegen0; /* 0x388 - 0x38c */
+ volatile unsigned int tx_tonegen1; /* 0x38c - 0x390 */
+ volatile unsigned int tx_lftonegen0; /* 0x390 - 0x394 */
+ volatile unsigned int tx_linear_ramp_i; /* 0x394 - 0x398 */
+ volatile unsigned int tx_linear_ramp_q; /* 0x398 - 0x39c */
+ volatile unsigned int tx_prbs_mag; /* 0x39c - 0x3a0 */
+ volatile unsigned int tx_prbs_seed_i; /* 0x3a0 - 0x3a4 */
+ volatile unsigned int tx_prbs_seed_q; /* 0x3a4 - 0x3a8 */
+ volatile unsigned int cmac_dc_cancel; /* 0x3a8 - 0x3ac */
+ volatile unsigned int cmac_dc_offset; /* 0x3ac - 0x3b0 */
+ volatile unsigned int cmac_corr; /* 0x3b0 - 0x3b4 */
+ volatile unsigned int cmac_power; /* 0x3b4 - 0x3b8 */
+ volatile unsigned int cmac_cross_corr; /* 0x3b8 - 0x3bc */
+ volatile unsigned int cmac_i2q2; /* 0x3bc - 0x3c0 */
+ volatile unsigned int cmac_power_hpf; /* 0x3c0 - 0x3c4 */
+ volatile unsigned int rxdac_set1; /* 0x3c4 - 0x3c8 */
+ volatile unsigned int rxdac_set2; /* 0x3c8 - 0x3cc */
+ volatile unsigned int rxdac_long_shift; /* 0x3cc - 0x3d0 */
+ volatile unsigned int cmac_results_i; /* 0x3d0 - 0x3d4 */
+ volatile unsigned int cmac_results_q; /* 0x3d4 - 0x3d8 */
+ volatile char pad__7[0x368]; /* 0x3d8 - 0x740 */
+ volatile unsigned int PMU1; /* 0x740 - 0x744 */
+ volatile unsigned int PMU2; /* 0x744 - 0x748 */
+} analog_intf_ares_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _ANALOG_INTF_ARES_REG_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h
new file mode 100644
index 000000000000..1c243fbbc810
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h
@@ -0,0 +1,3674 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+/* Copyright (C) 2009 Denali Software Inc. All rights reserved */
+/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT */
+
+
+#ifndef _ANALOG_INTF_ATHR_WLAN_REG_REG_H_
+#define _ANALOG_INTF_ATHR_WLAN_REG_REG_H_
+
+
+/* macros for RXRF_BIAS1 */
+#define PHY_ANALOG_RXRF_BIAS1_ADDRESS 0x00000000
+#define PHY_ANALOG_RXRF_BIAS1_OFFSET 0x00000000
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_BIAS1_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MSB 3
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_LSB 1
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MASK 0x0000000e
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MSB 6
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_LSB 4
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MASK 0x00000070
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MSB 9
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_LSB 7
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MASK 0x00000380
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MSB 12
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_LSB 10
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MASK 0x00001c00
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_GET(x) (((x) & 0x00001c00) >> 10)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_SET(x) (((x) << 10) & 0x00001c00)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MSB 15
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_LSB 13
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MASK 0x0000e000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MSB 18
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_LSB 16
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MASK 0x00070000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MSB 21
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_LSB 19
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MASK 0x00380000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MSB 24
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_LSB 22
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MASK 0x01c00000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_GET(x) (((x) & 0x01c00000) >> 22)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_SET(x) (((x) << 22) & 0x01c00000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MSB 27
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_LSB 25
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MASK 0x0e000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MSB 30
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_LSB 28
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MASK 0x70000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_GET(x) (((x) & 0x70000000) >> 28)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_SET(x) (((x) << 28) & 0x70000000)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MSB 31
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_LSB 31
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MASK 0x80000000
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXRF_BIAS2 */
+#define PHY_ANALOG_RXRF_BIAS2_ADDRESS 0x00000004
+#define PHY_ANALOG_RXRF_BIAS2_OFFSET 0x00000004
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_BIAS2_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_MSB 3
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_LSB 1
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_MASK 0x0000000e
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_RXRF_BIAS2_PKEN_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MSB 6
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_LSB 4
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MASK 0x00000070
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MSB 7
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_LSB 7
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MASK 0x00000080
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_MSB 10
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_LSB 8
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_MASK 0x00000700
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_MSB 13
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_LSB 11
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_MASK 0x00003800
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_MSB 16
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_LSB 14
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_MASK 0x0001c000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_MSB 19
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_LSB 17
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_MASK 0x000e0000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_MSB 22
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_LSB 20
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_MASK 0x00700000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_MSB 25
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_LSB 23
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_MASK 0x03800000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MSB 28
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_LSB 26
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MASK 0x1c000000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MSB 31
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_LSB 29
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MASK 0xe0000000
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXRF_GAINSTAGES */
+#define PHY_ANALOG_RXRF_GAINSTAGES_ADDRESS 0x00000008
+#define PHY_ANALOG_RXRF_GAINSTAGES_OFFSET 0x00000008
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MSB 0
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_LSB 0
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MASK 0x00000001
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MSB 1
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_LSB 1
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MASK 0x00000002
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MSB 3
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_LSB 2
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MASK 0x0000000c
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MSB 5
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_LSB 4
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MASK 0x00000030
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MSB 6
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_LSB 6
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MASK 0x00000040
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MSB 7
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_LSB 7
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MASK 0x00000080
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MSB 8
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_LSB 8
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MASK 0x00000100
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MSB 9
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_LSB 9
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MASK 0x00000200
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MSB 10
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_LSB 10
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MASK 0x00000400
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MSB 12
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_LSB 11
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MASK 0x00001800
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_GET(x) (((x) & 0x00001800) >> 11)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_SET(x) (((x) << 11) & 0x00001800)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MSB 13
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_LSB 13
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MASK 0x00002000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MSB 14
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_LSB 14
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MASK 0x00004000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MSB 15
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_LSB 15
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MASK 0x00008000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MSB 16
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_LSB 16
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MASK 0x00010000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MSB 17
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_LSB 17
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MASK 0x00020000
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MSB 19
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_LSB 18
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MASK 0x000c0000
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MSB 22
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_LSB 20
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MASK 0x00700000
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MSB 25
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_LSB 23
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MASK 0x03800000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MSB 27
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_LSB 26
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MASK 0x0c000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MSB 30
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_LSB 28
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MASK 0x70000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_GET(x) (((x) & 0x70000000) >> 28)
+#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_SET(x) (((x) << 28) & 0x70000000)
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MSB 31
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_LSB 31
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXRF_AGC */
+#define PHY_ANALOG_RXRF_AGC_ADDRESS 0x0000000c
+#define PHY_ANALOG_RXRF_AGC_OFFSET 0x0000000c
+#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_MSB 0
+#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_LSB 0
+#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_MASK 0x00000001
+#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_MSB 1
+#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_LSB 1
+#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_MASK 0x00000002
+#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXRF_AGC_AGC_OUT_MSB 2
+#define PHY_ANALOG_RXRF_AGC_AGC_OUT_LSB 2
+#define PHY_ANALOG_RXRF_AGC_AGC_OUT_MASK 0x00000004
+#define PHY_ANALOG_RXRF_AGC_AGC_OUT_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_MSB 3
+#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_LSB 3
+#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_MASK 0x00000008
+#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_MSB 4
+#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_LSB 4
+#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_MASK 0x00000010
+#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_MSB 5
+#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_LSB 5
+#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_MASK 0x00000020
+#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MSB 8
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_LSB 6
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MASK 0x000001c0
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MSB 14
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_LSB 9
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MASK 0x00007e00
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_GET(x) (((x) & 0x00007e00) >> 9)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_SET(x) (((x) << 9) & 0x00007e00)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MSB 18
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_LSB 15
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MASK 0x00078000
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_GET(x) (((x) & 0x00078000) >> 15)
+#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_SET(x) (((x) << 15) & 0x00078000)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MSB 24
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_LSB 19
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MASK 0x01f80000
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_GET(x) (((x) & 0x01f80000) >> 19)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_SET(x) (((x) << 19) & 0x01f80000)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MSB 28
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_LSB 25
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MASK 0x1e000000
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_GET(x) (((x) & 0x1e000000) >> 25)
+#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_SET(x) (((x) << 25) & 0x1e000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MSB 29
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_LSB 29
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MASK 0x20000000
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MSB 30
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_LSB 30
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MASK 0x40000000
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MSB 31
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_LSB 31
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF1 */
+#define PHY_ANALOG_TXRF1_ADDRESS 0x00000040
+#define PHY_ANALOG_TXRF1_OFFSET 0x00000040
+#define PHY_ANALOG_TXRF1_PDLOBUF5G_MSB 0
+#define PHY_ANALOG_TXRF1_PDLOBUF5G_LSB 0
+#define PHY_ANALOG_TXRF1_PDLOBUF5G_MASK 0x00000001
+#define PHY_ANALOG_TXRF1_PDLOBUF5G_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF1_PDLOBUF5G_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TXRF1_PDLODIV5G_MSB 1
+#define PHY_ANALOG_TXRF1_PDLODIV5G_LSB 1
+#define PHY_ANALOG_TXRF1_PDLODIV5G_MASK 0x00000002
+#define PHY_ANALOG_TXRF1_PDLODIV5G_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_TXRF1_PDLODIV5G_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_MSB 2
+#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_LSB 2
+#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_MASK 0x00000004
+#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_TXRF1_LODIV5GFORCED_MSB 3
+#define PHY_ANALOG_TXRF1_LODIV5GFORCED_LSB 3
+#define PHY_ANALOG_TXRF1_LODIV5GFORCED_MASK 0x00000008
+#define PHY_ANALOG_TXRF1_LODIV5GFORCED_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TXRF1_LODIV5GFORCED_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_TXRF1_PADRV2GN5G_MSB 7
+#define PHY_ANALOG_TXRF1_PADRV2GN5G_LSB 4
+#define PHY_ANALOG_TXRF1_PADRV2GN5G_MASK 0x000000f0
+#define PHY_ANALOG_TXRF1_PADRV2GN5G_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_TXRF1_PADRV2GN5G_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_TXRF1_PADRV3GN5G_MSB 11
+#define PHY_ANALOG_TXRF1_PADRV3GN5G_LSB 8
+#define PHY_ANALOG_TXRF1_PADRV3GN5G_MASK 0x00000f00
+#define PHY_ANALOG_TXRF1_PADRV3GN5G_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TXRF1_PADRV3GN5G_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TXRF1_PADRV4GN5G_MSB 15
+#define PHY_ANALOG_TXRF1_PADRV4GN5G_LSB 12
+#define PHY_ANALOG_TXRF1_PADRV4GN5G_MASK 0x0000f000
+#define PHY_ANALOG_TXRF1_PADRV4GN5G_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_ANALOG_TXRF1_PADRV4GN5G_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_MSB 16
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_LSB 16
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_MASK 0x00010000
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_TXRF1_PDOUT2G_MSB 17
+#define PHY_ANALOG_TXRF1_PDOUT2G_LSB 17
+#define PHY_ANALOG_TXRF1_PDOUT2G_MASK 0x00020000
+#define PHY_ANALOG_TXRF1_PDOUT2G_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_TXRF1_PDOUT2G_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_TXRF1_PDDR2G_MSB 18
+#define PHY_ANALOG_TXRF1_PDDR2G_LSB 18
+#define PHY_ANALOG_TXRF1_PDDR2G_MASK 0x00040000
+#define PHY_ANALOG_TXRF1_PDDR2G_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_TXRF1_PDDR2G_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_TXRF1_PDMXR2G_MSB 19
+#define PHY_ANALOG_TXRF1_PDMXR2G_LSB 19
+#define PHY_ANALOG_TXRF1_PDMXR2G_MASK 0x00080000
+#define PHY_ANALOG_TXRF1_PDMXR2G_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_TXRF1_PDMXR2G_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_TXRF1_PDLOBUF2G_MSB 20
+#define PHY_ANALOG_TXRF1_PDLOBUF2G_LSB 20
+#define PHY_ANALOG_TXRF1_PDLOBUF2G_MASK 0x00100000
+#define PHY_ANALOG_TXRF1_PDLOBUF2G_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TXRF1_PDLOBUF2G_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TXRF1_PDLODIV2G_MSB 21
+#define PHY_ANALOG_TXRF1_PDLODIV2G_LSB 21
+#define PHY_ANALOG_TXRF1_PDLODIV2G_MASK 0x00200000
+#define PHY_ANALOG_TXRF1_PDLODIV2G_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TXRF1_PDLODIV2G_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MSB 22
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_LSB 22
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MASK 0x00400000
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MSB 23
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_LSB 23
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MASK 0x00800000
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_TXRF1_LODIV2GFORCED_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_TXRF1_PADRVGN2G_MSB 30
+#define PHY_ANALOG_TXRF1_PADRVGN2G_LSB 24
+#define PHY_ANALOG_TXRF1_PADRVGN2G_MASK 0x7f000000
+#define PHY_ANALOG_TXRF1_PADRVGN2G_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TXRF1_PADRVGN2G_SET(x) (((x) << 24) & 0x7f000000)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MSB 31
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_LSB 31
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MASK 0x80000000
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF2 */
+#define PHY_ANALOG_TXRF2_ADDRESS 0x00000044
+#define PHY_ANALOG_TXRF2_OFFSET 0x00000044
+#define PHY_ANALOG_TXRF2_D3B5G_MSB 2
+#define PHY_ANALOG_TXRF2_D3B5G_LSB 0
+#define PHY_ANALOG_TXRF2_D3B5G_MASK 0x00000007
+#define PHY_ANALOG_TXRF2_D3B5G_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_TXRF2_D3B5G_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_TXRF2_D4B5G_MSB 5
+#define PHY_ANALOG_TXRF2_D4B5G_LSB 3
+#define PHY_ANALOG_TXRF2_D4B5G_MASK 0x00000038
+#define PHY_ANALOG_TXRF2_D4B5G_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_TXRF2_D4B5G_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_TXRF2_OCAS2G_MSB 8
+#define PHY_ANALOG_TXRF2_OCAS2G_LSB 6
+#define PHY_ANALOG_TXRF2_OCAS2G_MASK 0x000001c0
+#define PHY_ANALOG_TXRF2_OCAS2G_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_ANALOG_TXRF2_OCAS2G_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_ANALOG_TXRF2_DCAS2G_MSB 11
+#define PHY_ANALOG_TXRF2_DCAS2G_LSB 9
+#define PHY_ANALOG_TXRF2_DCAS2G_MASK 0x00000e00
+#define PHY_ANALOG_TXRF2_DCAS2G_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_ANALOG_TXRF2_DCAS2G_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_ANALOG_TXRF2_OB2G_PALOFF_MSB 14
+#define PHY_ANALOG_TXRF2_OB2G_PALOFF_LSB 12
+#define PHY_ANALOG_TXRF2_OB2G_PALOFF_MASK 0x00007000
+#define PHY_ANALOG_TXRF2_OB2G_PALOFF_GET(x) (((x) & 0x00007000) >> 12)
+#define PHY_ANALOG_TXRF2_OB2G_PALOFF_SET(x) (((x) << 12) & 0x00007000)
+#define PHY_ANALOG_TXRF2_OB2G_QAM_MSB 17
+#define PHY_ANALOG_TXRF2_OB2G_QAM_LSB 15
+#define PHY_ANALOG_TXRF2_OB2G_QAM_MASK 0x00038000
+#define PHY_ANALOG_TXRF2_OB2G_QAM_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_TXRF2_OB2G_QAM_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_TXRF2_OB2G_PSK_MSB 20
+#define PHY_ANALOG_TXRF2_OB2G_PSK_LSB 18
+#define PHY_ANALOG_TXRF2_OB2G_PSK_MASK 0x001c0000
+#define PHY_ANALOG_TXRF2_OB2G_PSK_GET(x) (((x) & 0x001c0000) >> 18)
+#define PHY_ANALOG_TXRF2_OB2G_PSK_SET(x) (((x) << 18) & 0x001c0000)
+#define PHY_ANALOG_TXRF2_OB2G_CCK_MSB 23
+#define PHY_ANALOG_TXRF2_OB2G_CCK_LSB 21
+#define PHY_ANALOG_TXRF2_OB2G_CCK_MASK 0x00e00000
+#define PHY_ANALOG_TXRF2_OB2G_CCK_GET(x) (((x) & 0x00e00000) >> 21)
+#define PHY_ANALOG_TXRF2_OB2G_CCK_SET(x) (((x) << 21) & 0x00e00000)
+#define PHY_ANALOG_TXRF2_DB2G_MSB 26
+#define PHY_ANALOG_TXRF2_DB2G_LSB 24
+#define PHY_ANALOG_TXRF2_DB2G_MASK 0x07000000
+#define PHY_ANALOG_TXRF2_DB2G_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_ANALOG_TXRF2_DB2G_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_ANALOG_TXRF2_PDOUT5G_MSB 30
+#define PHY_ANALOG_TXRF2_PDOUT5G_LSB 27
+#define PHY_ANALOG_TXRF2_PDOUT5G_MASK 0x78000000
+#define PHY_ANALOG_TXRF2_PDOUT5G_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_TXRF2_PDOUT5G_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_TXRF2_PDMXR5G_MSB 31
+#define PHY_ANALOG_TXRF2_PDMXR5G_LSB 31
+#define PHY_ANALOG_TXRF2_PDMXR5G_MASK 0x80000000
+#define PHY_ANALOG_TXRF2_PDMXR5G_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF2_PDMXR5G_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF3 */
+#define PHY_ANALOG_TXRF3_ADDRESS 0x00000048
+#define PHY_ANALOG_TXRF3_OFFSET 0x00000048
+#define PHY_ANALOG_TXRF3_FILTR2G_MSB 1
+#define PHY_ANALOG_TXRF3_FILTR2G_LSB 0
+#define PHY_ANALOG_TXRF3_FILTR2G_MASK 0x00000003
+#define PHY_ANALOG_TXRF3_FILTR2G_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF3_FILTR2G_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF3_PWDFB2_2G_MSB 2
+#define PHY_ANALOG_TXRF3_PWDFB2_2G_LSB 2
+#define PHY_ANALOG_TXRF3_PWDFB2_2G_MASK 0x00000004
+#define PHY_ANALOG_TXRF3_PWDFB2_2G_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_TXRF3_PWDFB2_2G_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_TXRF3_PWDFB1_2G_MSB 3
+#define PHY_ANALOG_TXRF3_PWDFB1_2G_LSB 3
+#define PHY_ANALOG_TXRF3_PWDFB1_2G_MASK 0x00000008
+#define PHY_ANALOG_TXRF3_PWDFB1_2G_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TXRF3_PWDFB1_2G_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_TXRF3_PDFB2G_MSB 4
+#define PHY_ANALOG_TXRF3_PDFB2G_LSB 4
+#define PHY_ANALOG_TXRF3_PDFB2G_MASK 0x00000010
+#define PHY_ANALOG_TXRF3_PDFB2G_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_TXRF3_PDFB2G_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_TXRF3_RDIV5G_MSB 6
+#define PHY_ANALOG_TXRF3_RDIV5G_LSB 5
+#define PHY_ANALOG_TXRF3_RDIV5G_MASK 0x00000060
+#define PHY_ANALOG_TXRF3_RDIV5G_GET(x) (((x) & 0x00000060) >> 5)
+#define PHY_ANALOG_TXRF3_RDIV5G_SET(x) (((x) << 5) & 0x00000060)
+#define PHY_ANALOG_TXRF3_CAPDIV5G_MSB 9
+#define PHY_ANALOG_TXRF3_CAPDIV5G_LSB 7
+#define PHY_ANALOG_TXRF3_CAPDIV5G_MASK 0x00000380
+#define PHY_ANALOG_TXRF3_CAPDIV5G_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_TXRF3_CAPDIV5G_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_TXRF3_PDPREDIST5G_MSB 10
+#define PHY_ANALOG_TXRF3_PDPREDIST5G_LSB 10
+#define PHY_ANALOG_TXRF3_PDPREDIST5G_MASK 0x00000400
+#define PHY_ANALOG_TXRF3_PDPREDIST5G_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_TXRF3_PDPREDIST5G_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_TXRF3_RDIV2G_MSB 12
+#define PHY_ANALOG_TXRF3_RDIV2G_LSB 11
+#define PHY_ANALOG_TXRF3_RDIV2G_MASK 0x00001800
+#define PHY_ANALOG_TXRF3_RDIV2G_GET(x) (((x) & 0x00001800) >> 11)
+#define PHY_ANALOG_TXRF3_RDIV2G_SET(x) (((x) << 11) & 0x00001800)
+#define PHY_ANALOG_TXRF3_PDPREDIST2G_MSB 13
+#define PHY_ANALOG_TXRF3_PDPREDIST2G_LSB 13
+#define PHY_ANALOG_TXRF3_PDPREDIST2G_MASK 0x00002000
+#define PHY_ANALOG_TXRF3_PDPREDIST2G_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TXRF3_PDPREDIST2G_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TXRF3_OCAS5G_MSB 16
+#define PHY_ANALOG_TXRF3_OCAS5G_LSB 14
+#define PHY_ANALOG_TXRF3_OCAS5G_MASK 0x0001c000
+#define PHY_ANALOG_TXRF3_OCAS5G_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF3_OCAS5G_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF3_D2CAS5G_MSB 19
+#define PHY_ANALOG_TXRF3_D2CAS5G_LSB 17
+#define PHY_ANALOG_TXRF3_D2CAS5G_MASK 0x000e0000
+#define PHY_ANALOG_TXRF3_D2CAS5G_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF3_D2CAS5G_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF3_D3CAS5G_MSB 22
+#define PHY_ANALOG_TXRF3_D3CAS5G_LSB 20
+#define PHY_ANALOG_TXRF3_D3CAS5G_MASK 0x00700000
+#define PHY_ANALOG_TXRF3_D3CAS5G_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF3_D3CAS5G_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF3_D4CAS5G_MSB 25
+#define PHY_ANALOG_TXRF3_D4CAS5G_LSB 23
+#define PHY_ANALOG_TXRF3_D4CAS5G_MASK 0x03800000
+#define PHY_ANALOG_TXRF3_D4CAS5G_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF3_D4CAS5G_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF3_OB5G_MSB 28
+#define PHY_ANALOG_TXRF3_OB5G_LSB 26
+#define PHY_ANALOG_TXRF3_OB5G_MASK 0x1c000000
+#define PHY_ANALOG_TXRF3_OB5G_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF3_OB5G_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF3_D2B5G_MSB 31
+#define PHY_ANALOG_TXRF3_D2B5G_LSB 29
+#define PHY_ANALOG_TXRF3_D2B5G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF3_D2B5G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF3_D2B5G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF4 */
+#define PHY_ANALOG_TXRF4_ADDRESS 0x0000004c
+#define PHY_ANALOG_TXRF4_OFFSET 0x0000004c
+#define PHY_ANALOG_TXRF4_PK1B2G_CCK_MSB 1
+#define PHY_ANALOG_TXRF4_PK1B2G_CCK_LSB 0
+#define PHY_ANALOG_TXRF4_PK1B2G_CCK_MASK 0x00000003
+#define PHY_ANALOG_TXRF4_PK1B2G_CCK_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF4_PK1B2G_CCK_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF4_MIOB2G_QAM_MSB 4
+#define PHY_ANALOG_TXRF4_MIOB2G_QAM_LSB 2
+#define PHY_ANALOG_TXRF4_MIOB2G_QAM_MASK 0x0000001c
+#define PHY_ANALOG_TXRF4_MIOB2G_QAM_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_TXRF4_MIOB2G_QAM_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_TXRF4_MIOB2G_PSK_MSB 7
+#define PHY_ANALOG_TXRF4_MIOB2G_PSK_LSB 5
+#define PHY_ANALOG_TXRF4_MIOB2G_PSK_MASK 0x000000e0
+#define PHY_ANALOG_TXRF4_MIOB2G_PSK_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_TXRF4_MIOB2G_PSK_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_TXRF4_MIOB2G_CCK_MSB 10
+#define PHY_ANALOG_TXRF4_MIOB2G_CCK_LSB 8
+#define PHY_ANALOG_TXRF4_MIOB2G_CCK_MASK 0x00000700
+#define PHY_ANALOG_TXRF4_MIOB2G_CCK_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_TXRF4_MIOB2G_CCK_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_TXRF4_COMP2G_QAM_MSB 13
+#define PHY_ANALOG_TXRF4_COMP2G_QAM_LSB 11
+#define PHY_ANALOG_TXRF4_COMP2G_QAM_MASK 0x00003800
+#define PHY_ANALOG_TXRF4_COMP2G_QAM_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_TXRF4_COMP2G_QAM_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_MSB 16
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_LSB 14
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_MASK 0x0001c000
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF4_COMP2G_PSK_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_MSB 19
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_LSB 17
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_MASK 0x000e0000
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF4_COMP2G_CCK_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MSB 22
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_LSB 20
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MASK 0x00700000
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MSB 25
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_LSB 23
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MASK 0x03800000
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MSB 28
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_LSB 26
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MASK 0x1c000000
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_MSB 31
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_LSB 29
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF4_AMP2CAS2G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF5 */
+#define PHY_ANALOG_TXRF5_ADDRESS 0x00000050
+#define PHY_ANALOG_TXRF5_OFFSET 0x00000050
+#define PHY_ANALOG_TXRF5_SPARE5_MSB 0
+#define PHY_ANALOG_TXRF5_SPARE5_LSB 0
+#define PHY_ANALOG_TXRF5_SPARE5_MASK 0x00000001
+#define PHY_ANALOG_TXRF5_SPARE5_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF5_SPARE5_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TXRF5_PAL_LOCKED_MSB 1
+#define PHY_ANALOG_TXRF5_PAL_LOCKED_LSB 1
+#define PHY_ANALOG_TXRF5_PAL_LOCKED_MASK 0x00000002
+#define PHY_ANALOG_TXRF5_PAL_LOCKED_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_TXRF5_FBHI2G_MSB 2
+#define PHY_ANALOG_TXRF5_FBHI2G_LSB 2
+#define PHY_ANALOG_TXRF5_FBHI2G_MASK 0x00000004
+#define PHY_ANALOG_TXRF5_FBHI2G_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_TXRF5_FBLO2G_MSB 3
+#define PHY_ANALOG_TXRF5_FBLO2G_LSB 3
+#define PHY_ANALOG_TXRF5_FBLO2G_MASK 0x00000008
+#define PHY_ANALOG_TXRF5_FBLO2G_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TXRF5_NOPALGAIN2G_MSB 4
+#define PHY_ANALOG_TXRF5_NOPALGAIN2G_LSB 4
+#define PHY_ANALOG_TXRF5_NOPALGAIN2G_MASK 0x00000010
+#define PHY_ANALOG_TXRF5_NOPALGAIN2G_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_TXRF5_NOPALGAIN2G_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_TXRF5_ENPACAL2G_MSB 5
+#define PHY_ANALOG_TXRF5_ENPACAL2G_LSB 5
+#define PHY_ANALOG_TXRF5_ENPACAL2G_MASK 0x00000020
+#define PHY_ANALOG_TXRF5_ENPACAL2G_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_TXRF5_ENPACAL2G_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_TXRF5_OFFSET2G_MSB 12
+#define PHY_ANALOG_TXRF5_OFFSET2G_LSB 6
+#define PHY_ANALOG_TXRF5_OFFSET2G_MASK 0x00001fc0
+#define PHY_ANALOG_TXRF5_OFFSET2G_GET(x) (((x) & 0x00001fc0) >> 6)
+#define PHY_ANALOG_TXRF5_OFFSET2G_SET(x) (((x) << 6) & 0x00001fc0)
+#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_MSB 13
+#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_LSB 13
+#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_MASK 0x00002000
+#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TXRF5_REFHI2G_MSB 16
+#define PHY_ANALOG_TXRF5_REFHI2G_LSB 14
+#define PHY_ANALOG_TXRF5_REFHI2G_MASK 0x0001c000
+#define PHY_ANALOG_TXRF5_REFHI2G_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF5_REFHI2G_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF5_REFLO2G_MSB 19
+#define PHY_ANALOG_TXRF5_REFLO2G_LSB 17
+#define PHY_ANALOG_TXRF5_REFLO2G_MASK 0x000e0000
+#define PHY_ANALOG_TXRF5_REFLO2G_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF5_REFLO2G_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF5_PALCLAMP2G_MSB 21
+#define PHY_ANALOG_TXRF5_PALCLAMP2G_LSB 20
+#define PHY_ANALOG_TXRF5_PALCLAMP2G_MASK 0x00300000
+#define PHY_ANALOG_TXRF5_PALCLAMP2G_GET(x) (((x) & 0x00300000) >> 20)
+#define PHY_ANALOG_TXRF5_PALCLAMP2G_SET(x) (((x) << 20) & 0x00300000)
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MSB 23
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_LSB 22
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MASK 0x00c00000
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_TXRF5_PK2B2G_QAM_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MSB 25
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_LSB 24
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MASK 0x03000000
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_ANALOG_TXRF5_PK2B2G_PSK_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MSB 27
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_LSB 26
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MASK 0x0c000000
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_ANALOG_TXRF5_PK2B2G_CCK_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MSB 29
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_LSB 28
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MASK 0x30000000
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_GET(x) (((x) & 0x30000000) >> 28)
+#define PHY_ANALOG_TXRF5_PK1B2G_QAM_SET(x) (((x) << 28) & 0x30000000)
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MSB 31
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_LSB 30
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MASK 0xc0000000
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_TXRF5_PK1B2G_PSK_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for TXRF6 */
+#define PHY_ANALOG_TXRF6_ADDRESS 0x00000054
+#define PHY_ANALOG_TXRF6_OFFSET 0x00000054
+#define PHY_ANALOG_TXRF6_PALCLKGATE2G_MSB 0
+#define PHY_ANALOG_TXRF6_PALCLKGATE2G_LSB 0
+#define PHY_ANALOG_TXRF6_PALCLKGATE2G_MASK 0x00000001
+#define PHY_ANALOG_TXRF6_PALCLKGATE2G_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_TXRF6_PALCLKGATE2G_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_MSB 8
+#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_LSB 1
+#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_MASK 0x000001fe
+#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_GET(x) (((x) & 0x000001fe) >> 1)
+#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_SET(x) (((x) << 1) & 0x000001fe)
+#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_MSB 10
+#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_LSB 9
+#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_MASK 0x00000600
+#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_GET(x) (((x) & 0x00000600) >> 9)
+#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_SET(x) (((x) << 9) & 0x00000600)
+#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_MSB 11
+#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_LSB 11
+#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_MASK 0x00000800
+#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_MSB 14
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_LSB 12
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_MASK 0x00007000
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_GET(x) (((x) & 0x00007000) >> 12)
+#define PHY_ANALOG_TXRF6_GAINSTEP2G_SET(x) (((x) << 12) & 0x00007000)
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MSB 15
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_LSB 15
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MASK 0x00008000
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_TXRF6_CAPDIV_I2G_MSB 19
+#define PHY_ANALOG_TXRF6_CAPDIV_I2G_LSB 16
+#define PHY_ANALOG_TXRF6_CAPDIV_I2G_MASK 0x000f0000
+#define PHY_ANALOG_TXRF6_CAPDIV_I2G_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_TXRF6_CAPDIV_I2G_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MSB 23
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_LSB 20
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MASK 0x00f00000
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MSB 26
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_LSB 24
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MASK 0x07000000
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_ANALOG_TXRF6_VCMONDELAY2G_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_ANALOG_TXRF6_CAPDIV2G_MSB 30
+#define PHY_ANALOG_TXRF6_CAPDIV2G_LSB 27
+#define PHY_ANALOG_TXRF6_CAPDIV2G_MASK 0x78000000
+#define PHY_ANALOG_TXRF6_CAPDIV2G_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_TXRF6_CAPDIV2G_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MSB 31
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_LSB 31
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MASK 0x80000000
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for TXRF7 */
+#define PHY_ANALOG_TXRF7_ADDRESS 0x00000058
+#define PHY_ANALOG_TXRF7_OFFSET 0x00000058
+#define PHY_ANALOG_TXRF7_SPARE7_MSB 1
+#define PHY_ANALOG_TXRF7_SPARE7_LSB 0
+#define PHY_ANALOG_TXRF7_SPARE7_MASK 0x00000003
+#define PHY_ANALOG_TXRF7_SPARE7_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF7_SPARE7_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MSB 7
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_LSB 2
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MASK 0x000000fc
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MSB 13
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_LSB 8
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MASK 0x00003f00
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MSB 19
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_LSB 14
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MASK 0x000fc000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MSB 25
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_LSB 20
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MASK 0x03f00000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MSB 31
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_LSB 26
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MASK 0xfc000000
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF8 */
+#define PHY_ANALOG_TXRF8_ADDRESS 0x0000005c
+#define PHY_ANALOG_TXRF8_OFFSET 0x0000005c
+#define PHY_ANALOG_TXRF8_SPARE8_MSB 1
+#define PHY_ANALOG_TXRF8_SPARE8_LSB 0
+#define PHY_ANALOG_TXRF8_SPARE8_MASK 0x00000003
+#define PHY_ANALOG_TXRF8_SPARE8_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF8_SPARE8_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MSB 7
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_LSB 2
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MASK 0x000000fc
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MSB 13
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_LSB 8
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MASK 0x00003f00
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MSB 19
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_LSB 14
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MASK 0x000fc000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MSB 25
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_LSB 20
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MASK 0x03f00000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MSB 31
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_LSB 26
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MASK 0xfc000000
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF9 */
+#define PHY_ANALOG_TXRF9_ADDRESS 0x00000060
+#define PHY_ANALOG_TXRF9_OFFSET 0x00000060
+#define PHY_ANALOG_TXRF9_SPARE9_MSB 1
+#define PHY_ANALOG_TXRF9_SPARE9_LSB 0
+#define PHY_ANALOG_TXRF9_SPARE9_MASK 0x00000003
+#define PHY_ANALOG_TXRF9_SPARE9_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF9_SPARE9_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MSB 7
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_LSB 2
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MASK 0x000000fc
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MSB 13
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_LSB 8
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MASK 0x00003f00
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MSB 19
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_LSB 14
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MASK 0x000fc000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MSB 25
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_LSB 20
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MASK 0x03f00000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MSB 31
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_LSB 26
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MASK 0xfc000000
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for TXRF10 */
+#define PHY_ANALOG_TXRF10_ADDRESS 0x00000064
+#define PHY_ANALOG_TXRF10_OFFSET 0x00000064
+#define PHY_ANALOG_TXRF10_SPARE10_MSB 2
+#define PHY_ANALOG_TXRF10_SPARE10_LSB 0
+#define PHY_ANALOG_TXRF10_SPARE10_MASK 0x00000007
+#define PHY_ANALOG_TXRF10_SPARE10_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_TXRF10_SPARE10_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MSB 3
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_LSB 3
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MASK 0x00000008
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_MSB 6
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_LSB 4
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_MASK 0x00000070
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_GET(x) (((x) & 0x00000070) >> 4)
+#define PHY_ANALOG_TXRF10_D3B5GCALTX_SET(x) (((x) << 4) & 0x00000070)
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_MSB 9
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_LSB 7
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_MASK 0x00000380
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_TXRF10_D4B5GCALTX_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MSB 16
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_LSB 10
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MASK 0x0001fc00
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_GET(x) (((x) & 0x0001fc00) >> 10)
+#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_SET(x) (((x) << 10) & 0x0001fc00)
+#define PHY_ANALOG_TXRF10_DB2GCALTX_MSB 19
+#define PHY_ANALOG_TXRF10_DB2GCALTX_LSB 17
+#define PHY_ANALOG_TXRF10_DB2GCALTX_MASK 0x000e0000
+#define PHY_ANALOG_TXRF10_DB2GCALTX_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF10_DB2GCALTX_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_MSB 20
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_LSB 20
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_MASK 0x00100000
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TXRF10_CALTXSHIFT_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MSB 21
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_LSB 21
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MASK 0x00200000
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_MSB 27
+#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_LSB 22
+#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_MASK 0x0fc00000
+#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_GET(x) (((x) & 0x0fc00000) >> 22)
+#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_MSB 31
+#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_LSB 28
+#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_MASK 0xf0000000
+#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_GET(x) (((x) & 0xf0000000) >> 28)
+
+/* macros for TXRF11 */
+#define PHY_ANALOG_TXRF11_ADDRESS 0x00000068
+#define PHY_ANALOG_TXRF11_OFFSET 0x00000068
+#define PHY_ANALOG_TXRF11_SPARE11_MSB 1
+#define PHY_ANALOG_TXRF11_SPARE11_LSB 0
+#define PHY_ANALOG_TXRF11_SPARE11_MASK 0x00000003
+#define PHY_ANALOG_TXRF11_SPARE11_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_TXRF11_SPARE11_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MSB 4
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_LSB 2
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MASK 0x0000001c
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MSB 7
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_LSB 5
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MASK 0x000000e0
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MSB 10
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_LSB 8
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MASK 0x00000700
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MSB 13
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_LSB 11
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MASK 0x00003800
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MSB 16
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_LSB 14
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MASK 0x0001c000
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF11_PWD_ICSPARE_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_MSB 19
+#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_LSB 17
+#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_MASK 0x000e0000
+#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MSB 22
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_LSB 20
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MASK 0x00700000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MSB 25
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_LSB 23
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MASK 0x03800000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MSB 28
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_LSB 26
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MASK 0x1c000000
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MSB 31
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_LSB 29
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for TXRF12 */
+#define PHY_ANALOG_TXRF12_ADDRESS 0x0000006c
+#define PHY_ANALOG_TXRF12_OFFSET 0x0000006c
+#define PHY_ANALOG_TXRF12_SPARE12_2_MSB 7
+#define PHY_ANALOG_TXRF12_SPARE12_2_LSB 0
+#define PHY_ANALOG_TXRF12_SPARE12_2_MASK 0x000000ff
+#define PHY_ANALOG_TXRF12_SPARE12_2_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_ANALOG_TXRF12_SPARE12_1_MSB 9
+#define PHY_ANALOG_TXRF12_SPARE12_1_LSB 8
+#define PHY_ANALOG_TXRF12_SPARE12_1_MASK 0x00000300
+#define PHY_ANALOG_TXRF12_SPARE12_1_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_TXRF12_SPARE12_1_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_TXRF12_ATBSEL5G_MSB 13
+#define PHY_ANALOG_TXRF12_ATBSEL5G_LSB 10
+#define PHY_ANALOG_TXRF12_ATBSEL5G_MASK 0x00003c00
+#define PHY_ANALOG_TXRF12_ATBSEL5G_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_ANALOG_TXRF12_ATBSEL5G_SET(x) (((x) << 10) & 0x00003c00)
+#define PHY_ANALOG_TXRF12_ATBSEL2G_MSB 16
+#define PHY_ANALOG_TXRF12_ATBSEL2G_LSB 14
+#define PHY_ANALOG_TXRF12_ATBSEL2G_MASK 0x0001c000
+#define PHY_ANALOG_TXRF12_ATBSEL2G_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_TXRF12_ATBSEL2G_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MSB 19
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_LSB 17
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MASK 0x000e0000
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_TXRF12_PWD_IRSPARE_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_MSB 22
+#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_LSB 20
+#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_MASK 0x00700000
+#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MSB 25
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_LSB 23
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MASK 0x03800000
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MSB 28
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_LSB 26
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MASK 0x1c000000
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_MSB 31
+#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_LSB 29
+#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_MASK 0xe0000000
+#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for SYNTH1 */
+#define PHY_ANALOG_SYNTH1_ADDRESS 0x00000080
+#define PHY_ANALOG_SYNTH1_OFFSET 0x00000080
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MSB 2
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_LSB 0
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MASK 0x00000007
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MSB 5
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_LSB 3
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MASK 0x00000038
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB 6
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB 6
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK 0x00000040
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MSB 7
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_LSB 7
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MASK 0x00000080
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MSB 8
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_LSB 8
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MASK 0x00000100
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MSB 9
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_LSB 9
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MASK 0x00000200
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_MSB 10
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_LSB 10
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_MASK 0x00000400
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH1_MONITOR_REF_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_MSB 11
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_LSB 11
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_MASK 0x00000800
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_SYNTH1_MONITOR_FB_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MSB 12
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_LSB 12
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MASK 0x00001000
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_SYNTH1_PWUP_PD_MSB 15
+#define PHY_ANALOG_SYNTH1_PWUP_PD_LSB 13
+#define PHY_ANALOG_SYNTH1_PWUP_PD_MASK 0x0000e000
+#define PHY_ANALOG_SYNTH1_PWUP_PD_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_SYNTH1_PWUP_PD_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MSB 16
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_LSB 16
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MASK 0x00010000
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MSB 18
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_LSB 17
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MASK 0x00060000
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MSB 20
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_LSB 19
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MASK 0x00180000
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_GET(x) (((x) & 0x00180000) >> 19)
+#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_SET(x) (((x) << 19) & 0x00180000)
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MSB 21
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_LSB 21
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MASK 0x00200000
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MSB 22
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_LSB 22
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MASK 0x00400000
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_SYNTH1_PWUP_LOREF_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MSB 23
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_LSB 23
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MASK 0x00800000
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_SYNTH1_PWD_LOMIX_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_MSB 24
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_LSB 24
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_MASK 0x01000000
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_SYNTH1_PWD_LODIV_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MSB 25
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_LSB 25
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MASK 0x02000000
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MSB 26
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_LSB 26
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MASK 0x04000000
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_MSB 27
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_LSB 27
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_MASK 0x08000000
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_SYNTH1_PWD_PRESC_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_SYNTH1_PWD_VCO_MSB 28
+#define PHY_ANALOG_SYNTH1_PWD_VCO_LSB 28
+#define PHY_ANALOG_SYNTH1_PWD_VCO_MASK 0x10000000
+#define PHY_ANALOG_SYNTH1_PWD_VCO_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_SYNTH1_PWD_VCO_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_MSB 29
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_LSB 29
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_MASK 0x20000000
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_SYNTH1_PWD_VCMON_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_SYNTH1_PWD_CP_MSB 30
+#define PHY_ANALOG_SYNTH1_PWD_CP_LSB 30
+#define PHY_ANALOG_SYNTH1_PWD_CP_MASK 0x40000000
+#define PHY_ANALOG_SYNTH1_PWD_CP_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH1_PWD_CP_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_MSB 31
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_LSB 31
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_MASK 0x80000000
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH1_PWD_BIAS_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH2 */
+#define PHY_ANALOG_SYNTH2_ADDRESS 0x00000084
+#define PHY_ANALOG_SYNTH2_OFFSET 0x00000084
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_MSB 3
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_LSB 0
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_MASK 0x0000000f
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_SYNTH2_CAPRANGE3_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_MSB 7
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_LSB 4
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_MASK 0x000000f0
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_SYNTH2_CAPRANGE2_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_MSB 11
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_LSB 8
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH2_CAPRANGE1_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_MSB 15
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_LSB 12
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_MASK 0x0000f000
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_MSB 16
+#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_LSB 16
+#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_MASK 0x00010000
+#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MSB 17
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_LSB 17
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MASK 0x00020000
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_MSB 19
+#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_LSB 18
+#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_MASK 0x000c0000
+#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MSB 22
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_LSB 20
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MASK 0x00700000
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_SYNTH2_VC_LOW_REF_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_MSB 25
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_LSB 23
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_MASK 0x03800000
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_SYNTH2_VC_MID_REF_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_MSB 28
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_LSB 26
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_MASK 0x1c000000
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_SYNTH2_VC_HI_REF_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MSB 31
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_LSB 29
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MASK 0xe0000000
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_SYNTH2_VC_CAL_REF_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for SYNTH3 */
+#define PHY_ANALOG_SYNTH3_ADDRESS 0x00000088
+#define PHY_ANALOG_SYNTH3_OFFSET 0x00000088
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MSB 5
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_LSB 0
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MASK 0x0000003f
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MSB 11
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_LSB 6
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MASK 0x00000fc0
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MSB 17
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_LSB 12
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MASK 0x0003f000
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MSB 23
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_LSB 18
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MASK 0x00fc0000
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_SET(x) (((x) << 18) & 0x00fc0000)
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MSB 29
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_LSB 24
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MASK 0x3f000000
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_SET(x) (((x) << 24) & 0x3f000000)
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MSB 30
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_LSB 30
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MASK 0x40000000
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MSB 31
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_LSB 31
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MASK 0x80000000
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH4 */
+#define PHY_ANALOG_SYNTH4_ADDRESS 0x0000008c
+#define PHY_ANALOG_SYNTH4_OFFSET 0x0000008c
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MSB 0
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_LSB 0
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MASK 0x00000001
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MSB 1
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_LSB 1
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MASK 0x00000002
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MSB 3
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_LSB 2
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MASK 0x0000000c
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MSB 4
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_LSB 4
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MASK 0x00000010
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MSB 5
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_LSB 5
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MASK 0x00000020
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_SYNTH4_SDM_DITHER1_MSB 7
+#define PHY_ANALOG_SYNTH4_SDM_DITHER1_LSB 6
+#define PHY_ANALOG_SYNTH4_SDM_DITHER1_MASK 0x000000c0
+#define PHY_ANALOG_SYNTH4_SDM_DITHER1_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_ANALOG_SYNTH4_SDM_DITHER1_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_ANALOG_SYNTH4_SDM_MODE_MSB 8
+#define PHY_ANALOG_SYNTH4_SDM_MODE_LSB 8
+#define PHY_ANALOG_SYNTH4_SDM_MODE_MASK 0x00000100
+#define PHY_ANALOG_SYNTH4_SDM_MODE_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_SYNTH4_SDM_MODE_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MSB 9
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_LSB 9
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MASK 0x00000200
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH4_SDM_DISABLE_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_MSB 10
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_LSB 10
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_MASK 0x00000400
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH4_RESET_PRESC_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH4_PRESCSEL_MSB 12
+#define PHY_ANALOG_SYNTH4_PRESCSEL_LSB 11
+#define PHY_ANALOG_SYNTH4_PRESCSEL_MASK 0x00001800
+#define PHY_ANALOG_SYNTH4_PRESCSEL_GET(x) (((x) & 0x00001800) >> 11)
+#define PHY_ANALOG_SYNTH4_PRESCSEL_SET(x) (((x) << 11) & 0x00001800)
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MSB 13
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_LSB 13
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MASK 0x00002000
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_SYNTH4_PFD_DISABLE_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MSB 14
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_LSB 14
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MASK 0x00004000
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MSB 15
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_LSB 15
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MASK 0x00008000
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MSB 16
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_LSB 16
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MASK 0x00010000
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MSB 17
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_LSB 17
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MASK 0x00020000
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MSB 25
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_LSB 18
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MASK 0x03fc0000
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_GET(x) (((x) & 0x03fc0000) >> 18)
+#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_SET(x) (((x) << 18) & 0x03fc0000)
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MSB 26
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_LSB 26
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MASK 0x04000000
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MSB 27
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_LSB 27
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MASK 0x08000000
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_SYNTH4_FORCE_PINVC_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MSB 28
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_LSB 28
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MASK 0x10000000
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MSB 29
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_LSB 29
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MASK 0x20000000
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MSB 30
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_LSB 30
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MASK 0x40000000
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MSB 31
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_LSB 31
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MASK 0x80000000
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH5 */
+#define PHY_ANALOG_SYNTH5_ADDRESS 0x00000090
+#define PHY_ANALOG_SYNTH5_OFFSET 0x00000090
+#define PHY_ANALOG_SYNTH5_VCOBIAS_MSB 1
+#define PHY_ANALOG_SYNTH5_VCOBIAS_LSB 0
+#define PHY_ANALOG_SYNTH5_VCOBIAS_MASK 0x00000003
+#define PHY_ANALOG_SYNTH5_VCOBIAS_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH5_VCOBIAS_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MSB 4
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_LSB 2
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MASK 0x0000001c
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MSB 7
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_LSB 5
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MASK 0x000000e0
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MSB 10
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_LSB 8
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MASK 0x00000700
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MSB 13
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_LSB 11
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MASK 0x00003800
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MSB 14
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_LSB 14
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MASK 0x00004000
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MSB 17
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_LSB 15
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MASK 0x00038000
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MSB 20
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_LSB 18
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MASK 0x001c0000
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_GET(x) (((x) & 0x001c0000) >> 18)
+#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_SET(x) (((x) << 18) & 0x001c0000)
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MSB 23
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_LSB 21
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MASK 0x00e00000
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_GET(x) (((x) & 0x00e00000) >> 21)
+#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_SET(x) (((x) << 21) & 0x00e00000)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MSB 26
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_LSB 24
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MASK 0x07000000
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MSB 29
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_LSB 27
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MASK 0x38000000
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_GET(x) (((x) & 0x38000000) >> 27)
+#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_SET(x) (((x) << 27) & 0x38000000)
+#define PHY_ANALOG_SYNTH5_SDM_DITHER2_MSB 31
+#define PHY_ANALOG_SYNTH5_SDM_DITHER2_LSB 30
+#define PHY_ANALOG_SYNTH5_SDM_DITHER2_MASK 0xc0000000
+#define PHY_ANALOG_SYNTH5_SDM_DITHER2_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_SYNTH5_SDM_DITHER2_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for SYNTH6 */
+#define PHY_ANALOG_SYNTH6_ADDRESS 0x00000094
+#define PHY_ANALOG_SYNTH6_OFFSET 0x00000094
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MSB 1
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_LSB 0
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MASK 0x00000003
+#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH6_LOOP_IP_MSB 8
+#define PHY_ANALOG_SYNTH6_LOOP_IP_LSB 2
+#define PHY_ANALOG_SYNTH6_LOOP_IP_MASK 0x000001fc
+#define PHY_ANALOG_SYNTH6_LOOP_IP_GET(x) (((x) & 0x000001fc) >> 2)
+#define PHY_ANALOG_SYNTH6_VC2LOW_MSB 9
+#define PHY_ANALOG_SYNTH6_VC2LOW_LSB 9
+#define PHY_ANALOG_SYNTH6_VC2LOW_MASK 0x00000200
+#define PHY_ANALOG_SYNTH6_VC2LOW_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_SYNTH6_VC2HIGH_MSB 10
+#define PHY_ANALOG_SYNTH6_VC2HIGH_LSB 10
+#define PHY_ANALOG_SYNTH6_VC2HIGH_MASK 0x00000400
+#define PHY_ANALOG_SYNTH6_VC2HIGH_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MSB 11
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_LSB 11
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MASK 0x00000800
+#define PHY_ANALOG_SYNTH6_RESET_SDM_B_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MSB 12
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_LSB 12
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MASK 0x00001000
+#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_SYNTH6_RESET_PFD_MSB 13
+#define PHY_ANALOG_SYNTH6_RESET_PFD_LSB 13
+#define PHY_ANALOG_SYNTH6_RESET_PFD_MASK 0x00002000
+#define PHY_ANALOG_SYNTH6_RESET_PFD_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_SYNTH6_RESET_RFD_MSB 14
+#define PHY_ANALOG_SYNTH6_RESET_RFD_LSB 14
+#define PHY_ANALOG_SYNTH6_RESET_RFD_MASK 0x00004000
+#define PHY_ANALOG_SYNTH6_RESET_RFD_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH6_SHORT_R_MSB 15
+#define PHY_ANALOG_SYNTH6_SHORT_R_LSB 15
+#define PHY_ANALOG_SYNTH6_SHORT_R_MASK 0x00008000
+#define PHY_ANALOG_SYNTH6_SHORT_R_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MSB 23
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_LSB 16
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MASK 0x00ff0000
+#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_SYNTH6_PIN_VC_MSB 24
+#define PHY_ANALOG_SYNTH6_PIN_VC_LSB 24
+#define PHY_ANALOG_SYNTH6_PIN_VC_MASK 0x01000000
+#define PHY_ANALOG_SYNTH6_PIN_VC_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MSB 25
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_LSB 25
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MASK 0x02000000
+#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MSB 26
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_LSB 26
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MASK 0x04000000
+#define PHY_ANALOG_SYNTH6_CAP_SEARCH_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MSB 30
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_LSB 27
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MASK 0x78000000
+#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_MSB 31
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_LSB 31
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_MASK 0x80000000
+#define PHY_ANALOG_SYNTH6_SYNTH_ON_GET(x) (((x) & 0x80000000) >> 31)
+
+/* macros for SYNTH7 */
+#define PHY_ANALOG_SYNTH7_ADDRESS 0x00000098
+#define PHY_ANALOG_SYNTH7_OFFSET 0x00000098
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MSB 0
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_LSB 0
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MASK 0x00000001
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MSB 1
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_LSB 1
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MASK 0x00000002
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_SYNTH7_CHANFRAC_MSB 18
+#define PHY_ANALOG_SYNTH7_CHANFRAC_LSB 2
+#define PHY_ANALOG_SYNTH7_CHANFRAC_MASK 0x0007fffc
+#define PHY_ANALOG_SYNTH7_CHANFRAC_GET(x) (((x) & 0x0007fffc) >> 2)
+#define PHY_ANALOG_SYNTH7_CHANFRAC_SET(x) (((x) << 2) & 0x0007fffc)
+#define PHY_ANALOG_SYNTH7_CHANSEL_MSB 27
+#define PHY_ANALOG_SYNTH7_CHANSEL_LSB 19
+#define PHY_ANALOG_SYNTH7_CHANSEL_MASK 0x0ff80000
+#define PHY_ANALOG_SYNTH7_CHANSEL_GET(x) (((x) & 0x0ff80000) >> 19)
+#define PHY_ANALOG_SYNTH7_CHANSEL_SET(x) (((x) << 19) & 0x0ff80000)
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MSB 29
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_LSB 28
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MASK 0x30000000
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_GET(x) (((x) & 0x30000000) >> 28)
+#define PHY_ANALOG_SYNTH7_AMODEREFSEL_SET(x) (((x) << 28) & 0x30000000)
+#define PHY_ANALOG_SYNTH7_FRACMODE_MSB 30
+#define PHY_ANALOG_SYNTH7_FRACMODE_LSB 30
+#define PHY_ANALOG_SYNTH7_FRACMODE_MASK 0x40000000
+#define PHY_ANALOG_SYNTH7_FRACMODE_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_SYNTH7_FRACMODE_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MSB 31
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_LSB 31
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MASK 0x80000000
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH8 */
+#define PHY_ANALOG_SYNTH8_ADDRESS 0x0000009c
+#define PHY_ANALOG_SYNTH8_OFFSET 0x0000009c
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MSB 0
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_LSB 0
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MASK 0x00000001
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MSB 7
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_LSB 1
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MASK 0x000000fe
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_ANALOG_SYNTH8_LOOP_ICPB_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_MSB 11
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_LSB 8
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH8_LOOP_CSB_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_MSB 16
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_LSB 12
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_MASK 0x0001f000
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_ANALOG_SYNTH8_LOOP_RSB_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_MSB 21
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_LSB 17
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_MASK 0x003e0000
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_ANALOG_SYNTH8_LOOP_CPB_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MSB 26
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_LSB 22
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH8_REFDIVB_MSB 31
+#define PHY_ANALOG_SYNTH8_REFDIVB_LSB 27
+#define PHY_ANALOG_SYNTH8_REFDIVB_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH8_REFDIVB_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH8_REFDIVB_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH9 */
+#define PHY_ANALOG_SYNTH9_ADDRESS 0x000000a0
+#define PHY_ANALOG_SYNTH9_OFFSET 0x000000a0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MSB 0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_LSB 0
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MASK 0x00000001
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MSB 3
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_LSB 1
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MASK 0x0000000e
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MSB 7
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_LSB 4
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MASK 0x000000f0
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MSB 11
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_LSB 8
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH9_LOOP_CSA0_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MSB 16
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_LSB 12
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MASK 0x0001f000
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_ANALOG_SYNTH9_LOOP_RSA0_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MSB 21
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_LSB 17
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MASK 0x003e0000
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_ANALOG_SYNTH9_LOOP_CPA0_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MSB 26
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_LSB 22
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH9_REFDIVA_MSB 31
+#define PHY_ANALOG_SYNTH9_REFDIVA_LSB 27
+#define PHY_ANALOG_SYNTH9_REFDIVA_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH9_REFDIVA_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH9_REFDIVA_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH10 */
+#define PHY_ANALOG_SYNTH10_ADDRESS 0x000000a4
+#define PHY_ANALOG_SYNTH10_OFFSET 0x000000a4
+#define PHY_ANALOG_SYNTH10_SPARE10A_MSB 1
+#define PHY_ANALOG_SYNTH10_SPARE10A_LSB 0
+#define PHY_ANALOG_SYNTH10_SPARE10A_MASK 0x00000003
+#define PHY_ANALOG_SYNTH10_SPARE10A_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH10_SPARE10A_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MSB 4
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_LSB 2
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MASK 0x0000001c
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MSB 7
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_LSB 5
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MASK 0x000000e0
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MSB 10
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_LSB 8
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MASK 0x00000700
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MSB 13
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_LSB 11
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MASK 0x00003800
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MSB 17
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_LSB 14
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MASK 0x0003c000
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_GET(x) (((x) & 0x0003c000) >> 14)
+#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_SET(x) (((x) << 14) & 0x0003c000)
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MSB 21
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_LSB 18
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MASK 0x003c0000
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_GET(x) (((x) & 0x003c0000) >> 18)
+#define PHY_ANALOG_SYNTH10_LOOP_CSA1_SET(x) (((x) << 18) & 0x003c0000)
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MSB 26
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_LSB 22
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH10_LOOP_RSA1_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MSB 31
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_LSB 27
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH10_LOOP_CPA1_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH11 */
+#define PHY_ANALOG_SYNTH11_ADDRESS 0x000000a8
+#define PHY_ANALOG_SYNTH11_OFFSET 0x000000a8
+#define PHY_ANALOG_SYNTH11_SPARE11A_MSB 4
+#define PHY_ANALOG_SYNTH11_SPARE11A_LSB 0
+#define PHY_ANALOG_SYNTH11_SPARE11A_MASK 0x0000001f
+#define PHY_ANALOG_SYNTH11_SPARE11A_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_SYNTH11_SPARE11A_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MSB 5
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_LSB 5
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MASK 0x00000020
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_SYNTH11_LOREFSEL_MSB 7
+#define PHY_ANALOG_SYNTH11_LOREFSEL_LSB 6
+#define PHY_ANALOG_SYNTH11_LOREFSEL_MASK 0x000000c0
+#define PHY_ANALOG_SYNTH11_LOREFSEL_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_ANALOG_SYNTH11_LOREFSEL_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MSB 9
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_LSB 8
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MASK 0x00000300
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MSB 10
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_LSB 10
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MASK 0x00000400
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MSB 13
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_LSB 11
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MASK 0x00003800
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MSB 17
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_LSB 14
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MASK 0x0003c000
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_GET(x) (((x) & 0x0003c000) >> 14)
+#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_SET(x) (((x) << 14) & 0x0003c000)
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MSB 21
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_LSB 18
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MASK 0x003c0000
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_GET(x) (((x) & 0x003c0000) >> 18)
+#define PHY_ANALOG_SYNTH11_LOOP_CSA2_SET(x) (((x) << 18) & 0x003c0000)
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MSB 26
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_LSB 22
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH11_LOOP_RSA2_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MSB 31
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_LSB 27
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH11_LOOP_CPA2_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH12 */
+#define PHY_ANALOG_SYNTH12_ADDRESS 0x000000ac
+#define PHY_ANALOG_SYNTH12_OFFSET 0x000000ac
+#define PHY_ANALOG_SYNTH12_SPARE12A_MSB 9
+#define PHY_ANALOG_SYNTH12_SPARE12A_LSB 0
+#define PHY_ANALOG_SYNTH12_SPARE12A_MASK 0x000003ff
+#define PHY_ANALOG_SYNTH12_SPARE12A_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_ANALOG_SYNTH12_SPARE12A_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_MSB 13
+#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_LSB 10
+#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_MASK 0x00003c00
+#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_SET(x) (((x) << 10) & 0x00003c00)
+#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_MSB 14
+#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_LSB 14
+#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_MASK 0x00004000
+#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_MSB 16
+#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_LSB 15
+#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_MASK 0x00018000
+#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_GET(x) (((x) & 0x00018000) >> 15)
+#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_SET(x) (((x) << 15) & 0x00018000)
+#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_MSB 17
+#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_LSB 17
+#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_MASK 0x00020000
+#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_SYNTH12_STRCONT_MSB 18
+#define PHY_ANALOG_SYNTH12_STRCONT_LSB 18
+#define PHY_ANALOG_SYNTH12_STRCONT_MASK 0x00040000
+#define PHY_ANALOG_SYNTH12_STRCONT_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_SYNTH12_STRCONT_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_SYNTH12_VREFMUL3_MSB 22
+#define PHY_ANALOG_SYNTH12_VREFMUL3_LSB 19
+#define PHY_ANALOG_SYNTH12_VREFMUL3_MASK 0x00780000
+#define PHY_ANALOG_SYNTH12_VREFMUL3_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_ANALOG_SYNTH12_VREFMUL3_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_ANALOG_SYNTH12_VREFMUL2_MSB 26
+#define PHY_ANALOG_SYNTH12_VREFMUL2_LSB 23
+#define PHY_ANALOG_SYNTH12_VREFMUL2_MASK 0x07800000
+#define PHY_ANALOG_SYNTH12_VREFMUL2_GET(x) (((x) & 0x07800000) >> 23)
+#define PHY_ANALOG_SYNTH12_VREFMUL2_SET(x) (((x) << 23) & 0x07800000)
+#define PHY_ANALOG_SYNTH12_VREFMUL1_MSB 30
+#define PHY_ANALOG_SYNTH12_VREFMUL1_LSB 27
+#define PHY_ANALOG_SYNTH12_VREFMUL1_MASK 0x78000000
+#define PHY_ANALOG_SYNTH12_VREFMUL1_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_SYNTH12_VREFMUL1_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MSB 31
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_LSB 31
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MASK 0x80000000
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for SYNTH13 */
+#define PHY_ANALOG_SYNTH13_ADDRESS 0x000000b0
+#define PHY_ANALOG_SYNTH13_OFFSET 0x000000b0
+#define PHY_ANALOG_SYNTH13_SPARE13A_MSB 0
+#define PHY_ANALOG_SYNTH13_SPARE13A_LSB 0
+#define PHY_ANALOG_SYNTH13_SPARE13A_MASK 0x00000001
+#define PHY_ANALOG_SYNTH13_SPARE13A_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_SYNTH13_SPARE13A_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_MSB 3
+#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_LSB 1
+#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_MASK 0x0000000e
+#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_MSB 7
+#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_LSB 4
+#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_MASK 0x000000f0
+#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_MSB 11
+#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_LSB 8
+#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_MASK 0x00000f00
+#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_MSB 16
+#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_LSB 12
+#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_MASK 0x0001f000
+#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_MSB 21
+#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_LSB 17
+#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_MASK 0x003e0000
+#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_MSB 26
+#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_LSB 22
+#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_MASK 0x07c00000
+#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_GET(x) (((x) & 0x07c00000) >> 22)
+#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_SET(x) (((x) << 22) & 0x07c00000)
+#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_MSB 31
+#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_LSB 27
+#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_MASK 0xf8000000
+#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for SYNTH14 */
+#define PHY_ANALOG_SYNTH14_ADDRESS 0x000000b4
+#define PHY_ANALOG_SYNTH14_OFFSET 0x000000b4
+#define PHY_ANALOG_SYNTH14_SPARE14A_MSB 1
+#define PHY_ANALOG_SYNTH14_SPARE14A_LSB 0
+#define PHY_ANALOG_SYNTH14_SPARE14A_MASK 0x00000003
+#define PHY_ANALOG_SYNTH14_SPARE14A_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_SYNTH14_SPARE14A_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_MSB 3
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_LSB 2
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_MASK 0x0000000c
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_MSB 5
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_LSB 4
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_MASK 0x00000030
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_MSB 7
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_LSB 6
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_MASK 0x000000c0
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_MSB 9
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_LSB 8
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_MASK 0x00000300
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_MSB 10
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_LSB 10
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_MASK 0x00000400
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_MSB 11
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_LSB 11
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_MASK 0x00000800
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_MSB 12
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_LSB 12
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_MASK 0x00001000
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_MSB 13
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_LSB 13
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_MASK 0x00002000
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_MSB 16
+#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_LSB 14
+#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_MASK 0x0001c000
+#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_MSB 19
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_LSB 17
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_MASK 0x000e0000
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_MSB 22
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_LSB 20
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_MASK 0x00700000
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_MSB 25
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_LSB 23
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_MASK 0x03800000
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_MSB 28
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_LSB 26
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_MASK 0x1c000000
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_MSB 31
+#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_LSB 29
+#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_MASK 0xe0000000
+#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for BIAS1 */
+#define PHY_ANALOG_BIAS1_ADDRESS 0x000000c0
+#define PHY_ANALOG_BIAS1_OFFSET 0x000000c0
+#define PHY_ANALOG_BIAS1_SPARE1_MSB 6
+#define PHY_ANALOG_BIAS1_SPARE1_LSB 0
+#define PHY_ANALOG_BIAS1_SPARE1_MASK 0x0000007f
+#define PHY_ANALOG_BIAS1_SPARE1_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_BIAS1_SPARE1_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MSB 9
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_LSB 7
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MASK 0x00000380
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_GET(x) (((x) & 0x00000380) >> 7)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_SET(x) (((x) << 7) & 0x00000380)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MSB 12
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_LSB 10
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MASK 0x00001c00
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_GET(x) (((x) & 0x00001c00) >> 10)
+#define PHY_ANALOG_BIAS1_PWD_IC25V2II_SET(x) (((x) << 10) & 0x00001c00)
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_MSB 15
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_LSB 13
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_MASK 0x0000e000
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_BIAS1_PWD_IC25BB_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MSB 18
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_LSB 16
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MASK 0x00070000
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_ANALOG_BIAS1_PWD_IC25DAC_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MSB 21
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_LSB 19
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MASK 0x00380000
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_BIAS1_PWD_IC25FIR_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MSB 24
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_LSB 22
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MASK 0x01c00000
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_GET(x) (((x) & 0x01c00000) >> 22)
+#define PHY_ANALOG_BIAS1_PWD_IC25ADC_SET(x) (((x) << 22) & 0x01c00000)
+#define PHY_ANALOG_BIAS1_BIAS_SEL_MSB 31
+#define PHY_ANALOG_BIAS1_BIAS_SEL_LSB 25
+#define PHY_ANALOG_BIAS1_BIAS_SEL_MASK 0xfe000000
+#define PHY_ANALOG_BIAS1_BIAS_SEL_GET(x) (((x) & 0xfe000000) >> 25)
+#define PHY_ANALOG_BIAS1_BIAS_SEL_SET(x) (((x) << 25) & 0xfe000000)
+
+/* macros for BIAS2 */
+#define PHY_ANALOG_BIAS2_ADDRESS 0x000000c4
+#define PHY_ANALOG_BIAS2_OFFSET 0x000000c4
+#define PHY_ANALOG_BIAS2_SPARE2_MSB 4
+#define PHY_ANALOG_BIAS2_SPARE2_LSB 0
+#define PHY_ANALOG_BIAS2_SPARE2_MASK 0x0000001f
+#define PHY_ANALOG_BIAS2_SPARE2_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_BIAS2_SPARE2_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_BIAS2_PWD_IC25XPA_MSB 7
+#define PHY_ANALOG_BIAS2_PWD_IC25XPA_LSB 5
+#define PHY_ANALOG_BIAS2_PWD_IC25XPA_MASK 0x000000e0
+#define PHY_ANALOG_BIAS2_PWD_IC25XPA_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_BIAS2_PWD_IC25XPA_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MSB 10
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_LSB 8
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MASK 0x00000700
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MSB 13
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_LSB 11
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MASK 0x00003800
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MSB 16
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_LSB 14
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MASK 0x0001c000
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_MSB 19
+#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_LSB 17
+#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_MASK 0x000e0000
+#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MSB 22
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_LSB 20
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MASK 0x00700000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MSB 25
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_LSB 23
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MASK 0x03800000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MSB 28
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_LSB 26
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MASK 0x1c000000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MSB 31
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_LSB 29
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MASK 0xe0000000
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for BIAS3 */
+#define PHY_ANALOG_BIAS3_ADDRESS 0x000000c8
+#define PHY_ANALOG_BIAS3_OFFSET 0x000000c8
+#define PHY_ANALOG_BIAS3_SPARE3_MSB 1
+#define PHY_ANALOG_BIAS3_SPARE3_LSB 0
+#define PHY_ANALOG_BIAS3_SPARE3_MASK 0x00000003
+#define PHY_ANALOG_BIAS3_SPARE3_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_BIAS3_SPARE3_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_BIAS3_PWD_IR25SAR_MSB 4
+#define PHY_ANALOG_BIAS3_PWD_IR25SAR_LSB 2
+#define PHY_ANALOG_BIAS3_PWD_IR25SAR_MASK 0x0000001c
+#define PHY_ANALOG_BIAS3_PWD_IR25SAR_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_ANALOG_BIAS3_PWD_IR25SAR_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MSB 7
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_LSB 5
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MASK 0x000000e0
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_SET(x) (((x) << 5) & 0x000000e0)
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MSB 10
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_LSB 8
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MASK 0x00000700
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_MSB 13
+#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_LSB 11
+#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_MASK 0x00003800
+#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MSB 16
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_LSB 14
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MASK 0x0001c000
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_MSB 19
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_LSB 17
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_MASK 0x000e0000
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS3_PWD_IR25BB_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MSB 22
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_LSB 20
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MASK 0x00700000
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS3_PWD_IR50DAC_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MSB 25
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_LSB 23
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MASK 0x03800000
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS3_PWD_IR25DAC_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MSB 28
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_LSB 26
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MASK 0x1c000000
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS3_PWD_IR25FIR_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MSB 31
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_LSB 29
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MASK 0xe0000000
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS3_PWD_IR50ADC_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for BIAS4 */
+#define PHY_ANALOG_BIAS4_ADDRESS 0x000000cc
+#define PHY_ANALOG_BIAS4_OFFSET 0x000000cc
+#define PHY_ANALOG_BIAS4_SPARE4_MSB 10
+#define PHY_ANALOG_BIAS4_SPARE4_LSB 0
+#define PHY_ANALOG_BIAS4_SPARE4_MASK 0x000007ff
+#define PHY_ANALOG_BIAS4_SPARE4_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_BIAS4_SPARE4_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_MSB 13
+#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_LSB 11
+#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_MASK 0x00003800
+#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_GET(x) (((x) & 0x00003800) >> 11)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_SET(x) (((x) << 11) & 0x00003800)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MSB 16
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_LSB 14
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MASK 0x0001c000
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_GET(x) (((x) & 0x0001c000) >> 14)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_SET(x) (((x) << 14) & 0x0001c000)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MSB 19
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_LSB 17
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MASK 0x000e0000
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_ANALOG_BIAS4_PWD_IR25XPA_MSB 22
+#define PHY_ANALOG_BIAS4_PWD_IR25XPA_LSB 20
+#define PHY_ANALOG_BIAS4_PWD_IR25XPA_MASK 0x00700000
+#define PHY_ANALOG_BIAS4_PWD_IR25XPA_GET(x) (((x) & 0x00700000) >> 20)
+#define PHY_ANALOG_BIAS4_PWD_IR25XPA_SET(x) (((x) << 20) & 0x00700000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MSB 25
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_LSB 23
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MASK 0x03800000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_GET(x) (((x) & 0x03800000) >> 23)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_SET(x) (((x) << 23) & 0x03800000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MSB 28
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_LSB 26
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MASK 0x1c000000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MSB 31
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_LSB 29
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MASK 0xe0000000
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXTX1 */
+#define PHY_ANALOG_RXTX1_ADDRESS 0x00000100
+#define PHY_ANALOG_RXTX1_OFFSET 0x00000100
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MSB 0
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_LSB 0
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MASK 0x00000001
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXTX1_SCFIR_GAIN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXTX1_MANRXGAIN_MSB 1
+#define PHY_ANALOG_RXTX1_MANRXGAIN_LSB 1
+#define PHY_ANALOG_RXTX1_MANRXGAIN_MASK 0x00000002
+#define PHY_ANALOG_RXTX1_MANRXGAIN_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXTX1_MANRXGAIN_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_MSB 5
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_LSB 2
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_MASK 0x0000003c
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_GET(x) (((x) & 0x0000003c) >> 2)
+#define PHY_ANALOG_RXTX1_AGC_DBDAC_SET(x) (((x) << 2) & 0x0000003c)
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MSB 6
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_LSB 6
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MASK 0x00000040
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_MSB 7
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_LSB 7
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_MASK 0x00000080
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MSB 8
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_LSB 8
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MSB 11
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_LSB 9
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MASK 0x00000e00
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MSB 13
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_LSB 12
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MASK 0x00003000
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_SET(x) (((x) << 12) & 0x00003000)
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MSB 14
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_LSB 14
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MASK 0x00004000
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXTX1_PADRV2GN_MSB 18
+#define PHY_ANALOG_RXTX1_PADRV2GN_LSB 15
+#define PHY_ANALOG_RXTX1_PADRV2GN_MASK 0x00078000
+#define PHY_ANALOG_RXTX1_PADRV2GN_GET(x) (((x) & 0x00078000) >> 15)
+#define PHY_ANALOG_RXTX1_PADRV2GN_SET(x) (((x) << 15) & 0x00078000)
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_MSB 22
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_LSB 19
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_MASK 0x00780000
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_ANALOG_RXTX1_PADRV3GN5G_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_MSB 26
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_LSB 23
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_MASK 0x07800000
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_GET(x) (((x) & 0x07800000) >> 23)
+#define PHY_ANALOG_RXTX1_PADRV4GN5G_SET(x) (((x) << 23) & 0x07800000)
+#define PHY_ANALOG_RXTX1_TXBB_GC_MSB 30
+#define PHY_ANALOG_RXTX1_TXBB_GC_LSB 27
+#define PHY_ANALOG_RXTX1_TXBB_GC_MASK 0x78000000
+#define PHY_ANALOG_RXTX1_TXBB_GC_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_ANALOG_RXTX1_TXBB_GC_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_ANALOG_RXTX1_MANTXGAIN_MSB 31
+#define PHY_ANALOG_RXTX1_MANTXGAIN_LSB 31
+#define PHY_ANALOG_RXTX1_MANTXGAIN_MASK 0x80000000
+#define PHY_ANALOG_RXTX1_MANTXGAIN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXTX1_MANTXGAIN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for RXTX2 */
+#define PHY_ANALOG_RXTX2_ADDRESS 0x00000104
+#define PHY_ANALOG_RXTX2_OFFSET 0x00000104
+#define PHY_ANALOG_RXTX2_BMODE_MSB 0
+#define PHY_ANALOG_RXTX2_BMODE_LSB 0
+#define PHY_ANALOG_RXTX2_BMODE_MASK 0x00000001
+#define PHY_ANALOG_RXTX2_BMODE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RXTX2_BMODE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RXTX2_BMODE_OVR_MSB 1
+#define PHY_ANALOG_RXTX2_BMODE_OVR_LSB 1
+#define PHY_ANALOG_RXTX2_BMODE_OVR_MASK 0x00000002
+#define PHY_ANALOG_RXTX2_BMODE_OVR_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RXTX2_BMODE_OVR_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RXTX2_SYNTHON_MSB 2
+#define PHY_ANALOG_RXTX2_SYNTHON_LSB 2
+#define PHY_ANALOG_RXTX2_SYNTHON_MASK 0x00000004
+#define PHY_ANALOG_RXTX2_SYNTHON_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_RXTX2_SYNTHON_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MSB 3
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_LSB 3
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MASK 0x00000008
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RXTX2_SYNTHON_OVR_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RXTX2_BW_ST_MSB 5
+#define PHY_ANALOG_RXTX2_BW_ST_LSB 4
+#define PHY_ANALOG_RXTX2_BW_ST_MASK 0x00000030
+#define PHY_ANALOG_RXTX2_BW_ST_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_ANALOG_RXTX2_BW_ST_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_MSB 6
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_LSB 6
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_MASK 0x00000040
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX2_BW_ST_OVR_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX2_TXON_MSB 7
+#define PHY_ANALOG_RXTX2_TXON_LSB 7
+#define PHY_ANALOG_RXTX2_TXON_MASK 0x00000080
+#define PHY_ANALOG_RXTX2_TXON_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX2_TXON_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX2_TXON_OVR_MSB 8
+#define PHY_ANALOG_RXTX2_TXON_OVR_LSB 8
+#define PHY_ANALOG_RXTX2_TXON_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX2_TXON_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX2_TXON_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX2_PAON_MSB 9
+#define PHY_ANALOG_RXTX2_PAON_LSB 9
+#define PHY_ANALOG_RXTX2_PAON_MASK 0x00000200
+#define PHY_ANALOG_RXTX2_PAON_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXTX2_PAON_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXTX2_PAON_OVR_MSB 10
+#define PHY_ANALOG_RXTX2_PAON_OVR_LSB 10
+#define PHY_ANALOG_RXTX2_PAON_OVR_MASK 0x00000400
+#define PHY_ANALOG_RXTX2_PAON_OVR_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXTX2_PAON_OVR_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXTX2_RXON_MSB 11
+#define PHY_ANALOG_RXTX2_RXON_LSB 11
+#define PHY_ANALOG_RXTX2_RXON_MASK 0x00000800
+#define PHY_ANALOG_RXTX2_RXON_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_RXTX2_RXON_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_RXTX2_RXON_OVR_MSB 12
+#define PHY_ANALOG_RXTX2_RXON_OVR_LSB 12
+#define PHY_ANALOG_RXTX2_RXON_OVR_MASK 0x00001000
+#define PHY_ANALOG_RXTX2_RXON_OVR_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_RXTX2_RXON_OVR_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_RXTX2_AGCON_MSB 13
+#define PHY_ANALOG_RXTX2_AGCON_LSB 13
+#define PHY_ANALOG_RXTX2_AGCON_MASK 0x00002000
+#define PHY_ANALOG_RXTX2_AGCON_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RXTX2_AGCON_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RXTX2_AGCON_OVR_MSB 14
+#define PHY_ANALOG_RXTX2_AGCON_OVR_LSB 14
+#define PHY_ANALOG_RXTX2_AGCON_OVR_MASK 0x00004000
+#define PHY_ANALOG_RXTX2_AGCON_OVR_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RXTX2_AGCON_OVR_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RXTX2_TXMOD_MSB 17
+#define PHY_ANALOG_RXTX2_TXMOD_LSB 15
+#define PHY_ANALOG_RXTX2_TXMOD_MASK 0x00038000
+#define PHY_ANALOG_RXTX2_TXMOD_GET(x) (((x) & 0x00038000) >> 15)
+#define PHY_ANALOG_RXTX2_TXMOD_SET(x) (((x) << 15) & 0x00038000)
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_MSB 18
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_LSB 18
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_MASK 0x00040000
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_RXTX2_TXMOD_OVR_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MSB 21
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_LSB 19
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MASK 0x00380000
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MSB 23
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_LSB 22
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MASK 0x00c00000
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_RXTX2_MXRGAIN_MSB 25
+#define PHY_ANALOG_RXTX2_MXRGAIN_LSB 24
+#define PHY_ANALOG_RXTX2_MXRGAIN_MASK 0x03000000
+#define PHY_ANALOG_RXTX2_MXRGAIN_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_ANALOG_RXTX2_MXRGAIN_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_ANALOG_RXTX2_VGAGAIN_MSB 28
+#define PHY_ANALOG_RXTX2_VGAGAIN_LSB 26
+#define PHY_ANALOG_RXTX2_VGAGAIN_MASK 0x1c000000
+#define PHY_ANALOG_RXTX2_VGAGAIN_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_ANALOG_RXTX2_VGAGAIN_SET(x) (((x) << 26) & 0x1c000000)
+#define PHY_ANALOG_RXTX2_LNAGAIN_MSB 31
+#define PHY_ANALOG_RXTX2_LNAGAIN_LSB 29
+#define PHY_ANALOG_RXTX2_LNAGAIN_MASK 0xe0000000
+#define PHY_ANALOG_RXTX2_LNAGAIN_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_RXTX2_LNAGAIN_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for RXTX3 */
+#define PHY_ANALOG_RXTX3_ADDRESS 0x00000108
+#define PHY_ANALOG_RXTX3_OFFSET 0x00000108
+#define PHY_ANALOG_RXTX3_SPARE3_MSB 2
+#define PHY_ANALOG_RXTX3_SPARE3_LSB 0
+#define PHY_ANALOG_RXTX3_SPARE3_MASK 0x00000007
+#define PHY_ANALOG_RXTX3_SPARE3_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_RXTX3_SPARE3_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_RXTX3_SPURON_MSB 3
+#define PHY_ANALOG_RXTX3_SPURON_LSB 3
+#define PHY_ANALOG_RXTX3_SPURON_MASK 0x00000008
+#define PHY_ANALOG_RXTX3_SPURON_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RXTX3_SPURON_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_MSB 4
+#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_LSB 4
+#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_MASK 0x00000010
+#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_MSB 5
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_LSB 5
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_MASK 0x00000020
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_RXTX3_DACFULLSCALE_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_RXTX3_ADCSHORT_MSB 6
+#define PHY_ANALOG_RXTX3_ADCSHORT_LSB 6
+#define PHY_ANALOG_RXTX3_ADCSHORT_MASK 0x00000040
+#define PHY_ANALOG_RXTX3_ADCSHORT_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RXTX3_ADCSHORT_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RXTX3_DACPWD_MSB 7
+#define PHY_ANALOG_RXTX3_DACPWD_LSB 7
+#define PHY_ANALOG_RXTX3_DACPWD_MASK 0x00000080
+#define PHY_ANALOG_RXTX3_DACPWD_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RXTX3_DACPWD_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_MSB 8
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_LSB 8
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_MASK 0x00000100
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RXTX3_DACPWD_OVR_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RXTX3_ADCPWD_MSB 9
+#define PHY_ANALOG_RXTX3_ADCPWD_LSB 9
+#define PHY_ANALOG_RXTX3_ADCPWD_MASK 0x00000200
+#define PHY_ANALOG_RXTX3_ADCPWD_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RXTX3_ADCPWD_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MSB 10
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_LSB 10
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MASK 0x00000400
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RXTX3_ADCPWD_OVR_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_MSB 16
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_LSB 11
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_MASK 0x0001f800
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_GET(x) (((x) & 0x0001f800) >> 11)
+#define PHY_ANALOG_RXTX3_AGC_CALDAC_SET(x) (((x) << 11) & 0x0001f800)
+#define PHY_ANALOG_RXTX3_AGC_CAL_MSB 17
+#define PHY_ANALOG_RXTX3_AGC_CAL_LSB 17
+#define PHY_ANALOG_RXTX3_AGC_CAL_MASK 0x00020000
+#define PHY_ANALOG_RXTX3_AGC_CAL_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RXTX3_AGC_CAL_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MSB 18
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_LSB 18
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MASK 0x00040000
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_RXTX3_LOFORCEDON_MSB 19
+#define PHY_ANALOG_RXTX3_LOFORCEDON_LSB 19
+#define PHY_ANALOG_RXTX3_LOFORCEDON_MASK 0x00080000
+#define PHY_ANALOG_RXTX3_LOFORCEDON_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_RXTX3_LOFORCEDON_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_MSB 20
+#define PHY_ANALOG_RXTX3_CALRESIDUE_LSB 20
+#define PHY_ANALOG_RXTX3_CALRESIDUE_MASK 0x00100000
+#define PHY_ANALOG_RXTX3_CALRESIDUE_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MSB 21
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_LSB 21
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MASK 0x00200000
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_RXTX3_CALFC_MSB 22
+#define PHY_ANALOG_RXTX3_CALFC_LSB 22
+#define PHY_ANALOG_RXTX3_CALFC_MASK 0x00400000
+#define PHY_ANALOG_RXTX3_CALFC_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_RXTX3_CALFC_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_RXTX3_CALFC_OVR_MSB 23
+#define PHY_ANALOG_RXTX3_CALFC_OVR_LSB 23
+#define PHY_ANALOG_RXTX3_CALFC_OVR_MASK 0x00800000
+#define PHY_ANALOG_RXTX3_CALFC_OVR_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_RXTX3_CALFC_OVR_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_RXTX3_CALTX_MSB 24
+#define PHY_ANALOG_RXTX3_CALTX_LSB 24
+#define PHY_ANALOG_RXTX3_CALTX_MASK 0x01000000
+#define PHY_ANALOG_RXTX3_CALTX_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_RXTX3_CALTX_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_RXTX3_CALTX_OVR_MSB 25
+#define PHY_ANALOG_RXTX3_CALTX_OVR_LSB 25
+#define PHY_ANALOG_RXTX3_CALTX_OVR_MASK 0x02000000
+#define PHY_ANALOG_RXTX3_CALTX_OVR_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_RXTX3_CALTX_OVR_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_MSB 26
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_LSB 26
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_MASK 0x04000000
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MSB 27
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_LSB 27
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MASK 0x08000000
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_RXTX3_CALPA_MSB 28
+#define PHY_ANALOG_RXTX3_CALPA_LSB 28
+#define PHY_ANALOG_RXTX3_CALPA_MASK 0x10000000
+#define PHY_ANALOG_RXTX3_CALPA_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_RXTX3_CALPA_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_RXTX3_CALPA_OVR_MSB 29
+#define PHY_ANALOG_RXTX3_CALPA_OVR_LSB 29
+#define PHY_ANALOG_RXTX3_CALPA_OVR_MASK 0x20000000
+#define PHY_ANALOG_RXTX3_CALPA_OVR_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_RXTX3_CALPA_OVR_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_RXTX3_TURBOADC_MSB 30
+#define PHY_ANALOG_RXTX3_TURBOADC_LSB 30
+#define PHY_ANALOG_RXTX3_TURBOADC_MASK 0x40000000
+#define PHY_ANALOG_RXTX3_TURBOADC_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_RXTX3_TURBOADC_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_RXTX3_TURBOADC_OVR_MSB 31
+#define PHY_ANALOG_RXTX3_TURBOADC_OVR_LSB 31
+#define PHY_ANALOG_RXTX3_TURBOADC_OVR_MASK 0x80000000
+#define PHY_ANALOG_RXTX3_TURBOADC_OVR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_RXTX3_TURBOADC_OVR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB1 */
+#define PHY_ANALOG_BB1_ADDRESS 0x00000140
+#define PHY_ANALOG_BB1_OFFSET 0x00000140
+#define PHY_ANALOG_BB1_I2V_CURR2X_MSB 0
+#define PHY_ANALOG_BB1_I2V_CURR2X_LSB 0
+#define PHY_ANALOG_BB1_I2V_CURR2X_MASK 0x00000001
+#define PHY_ANALOG_BB1_I2V_CURR2X_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_BB1_I2V_CURR2X_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_BB1_ENABLE_LOQ_MSB 1
+#define PHY_ANALOG_BB1_ENABLE_LOQ_LSB 1
+#define PHY_ANALOG_BB1_ENABLE_LOQ_MASK 0x00000002
+#define PHY_ANALOG_BB1_ENABLE_LOQ_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_BB1_ENABLE_LOQ_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_BB1_FORCE_LOQ_MSB 2
+#define PHY_ANALOG_BB1_FORCE_LOQ_LSB 2
+#define PHY_ANALOG_BB1_FORCE_LOQ_MASK 0x00000004
+#define PHY_ANALOG_BB1_FORCE_LOQ_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_BB1_FORCE_LOQ_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_MSB 3
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_LSB 3
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_MASK 0x00000008
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_BB1_ENABLE_NOTCH_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_BB1_FORCE_NOTCH_MSB 4
+#define PHY_ANALOG_BB1_FORCE_NOTCH_LSB 4
+#define PHY_ANALOG_BB1_FORCE_NOTCH_MASK 0x00000010
+#define PHY_ANALOG_BB1_FORCE_NOTCH_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_BB1_FORCE_NOTCH_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MSB 5
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_LSB 5
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MASK 0x00000020
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_BB1_ENABLE_BIQUAD_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_MSB 6
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_LSB 6
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_MASK 0x00000040
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_BB1_FORCE_BIQUAD_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_MSB 7
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_LSB 7
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_MASK 0x00000080
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_BB1_ENABLE_OSDAC_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_BB1_FORCE_OSDAC_MSB 8
+#define PHY_ANALOG_BB1_FORCE_OSDAC_LSB 8
+#define PHY_ANALOG_BB1_FORCE_OSDAC_MASK 0x00000100
+#define PHY_ANALOG_BB1_FORCE_OSDAC_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_BB1_FORCE_OSDAC_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_BB1_ENABLE_V2I_MSB 9
+#define PHY_ANALOG_BB1_ENABLE_V2I_LSB 9
+#define PHY_ANALOG_BB1_ENABLE_V2I_MASK 0x00000200
+#define PHY_ANALOG_BB1_ENABLE_V2I_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_BB1_ENABLE_V2I_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_BB1_FORCE_V2I_MSB 10
+#define PHY_ANALOG_BB1_FORCE_V2I_LSB 10
+#define PHY_ANALOG_BB1_FORCE_V2I_MASK 0x00000400
+#define PHY_ANALOG_BB1_FORCE_V2I_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_BB1_FORCE_V2I_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_BB1_ENABLE_I2V_MSB 11
+#define PHY_ANALOG_BB1_ENABLE_I2V_LSB 11
+#define PHY_ANALOG_BB1_ENABLE_I2V_MASK 0x00000800
+#define PHY_ANALOG_BB1_ENABLE_I2V_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_BB1_ENABLE_I2V_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_BB1_FORCE_I2V_MSB 12
+#define PHY_ANALOG_BB1_FORCE_I2V_LSB 12
+#define PHY_ANALOG_BB1_FORCE_I2V_MASK 0x00001000
+#define PHY_ANALOG_BB1_FORCE_I2V_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_BB1_FORCE_I2V_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_BB1_CMSEL_MSB 15
+#define PHY_ANALOG_BB1_CMSEL_LSB 13
+#define PHY_ANALOG_BB1_CMSEL_MASK 0x0000e000
+#define PHY_ANALOG_BB1_CMSEL_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_ANALOG_BB1_CMSEL_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_ANALOG_BB1_ATBSEL_MSB 17
+#define PHY_ANALOG_BB1_ATBSEL_LSB 16
+#define PHY_ANALOG_BB1_ATBSEL_MASK 0x00030000
+#define PHY_ANALOG_BB1_ATBSEL_GET(x) (((x) & 0x00030000) >> 16)
+#define PHY_ANALOG_BB1_ATBSEL_SET(x) (((x) << 16) & 0x00030000)
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MSB 18
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_LSB 18
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MASK 0x00040000
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MSB 23
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_LSB 19
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MASK 0x00f80000
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_GET(x) (((x) & 0x00f80000) >> 19)
+#define PHY_ANALOG_BB1_OFSTCORRI2VQ_SET(x) (((x) << 19) & 0x00f80000)
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_MSB 28
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_LSB 24
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_MASK 0x1f000000
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_ANALOG_BB1_OFSTCORRI2VI_SET(x) (((x) << 24) & 0x1f000000)
+#define PHY_ANALOG_BB1_LOCALOFFSET_MSB 29
+#define PHY_ANALOG_BB1_LOCALOFFSET_LSB 29
+#define PHY_ANALOG_BB1_LOCALOFFSET_MASK 0x20000000
+#define PHY_ANALOG_BB1_LOCALOFFSET_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_BB1_LOCALOFFSET_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_BB1_RANGE_OSDAC_MSB 31
+#define PHY_ANALOG_BB1_RANGE_OSDAC_LSB 30
+#define PHY_ANALOG_BB1_RANGE_OSDAC_MASK 0xc0000000
+#define PHY_ANALOG_BB1_RANGE_OSDAC_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_BB1_RANGE_OSDAC_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for BB2 */
+#define PHY_ANALOG_BB2_ADDRESS 0x00000144
+#define PHY_ANALOG_BB2_OFFSET 0x00000144
+#define PHY_ANALOG_BB2_SPARE_MSB 3
+#define PHY_ANALOG_BB2_SPARE_LSB 0
+#define PHY_ANALOG_BB2_SPARE_MASK 0x0000000f
+#define PHY_ANALOG_BB2_SPARE_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_BB2_SPARE_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_MSB 7
+#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_LSB 4
+#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_MASK 0x000000f0
+#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_ANALOG_BB2_SEL_TEST_MSB 9
+#define PHY_ANALOG_BB2_SEL_TEST_LSB 8
+#define PHY_ANALOG_BB2_SEL_TEST_MASK 0x00000300
+#define PHY_ANALOG_BB2_SEL_TEST_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_ANALOG_BB2_SEL_TEST_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_ANALOG_BB2_RCFILTER_CAP_MSB 14
+#define PHY_ANALOG_BB2_RCFILTER_CAP_LSB 10
+#define PHY_ANALOG_BB2_RCFILTER_CAP_MASK 0x00007c00
+#define PHY_ANALOG_BB2_RCFILTER_CAP_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_ANALOG_BB2_RCFILTER_CAP_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_MSB 15
+#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_LSB 15
+#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_MASK 0x00008000
+#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_BB2_FNOTCH_MSB 19
+#define PHY_ANALOG_BB2_FNOTCH_LSB 16
+#define PHY_ANALOG_BB2_FNOTCH_MASK 0x000f0000
+#define PHY_ANALOG_BB2_FNOTCH_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_BB2_FNOTCH_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MSB 20
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_LSB 20
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MASK 0x00100000
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_BB2_FILTERFC_MSB 25
+#define PHY_ANALOG_BB2_FILTERFC_LSB 21
+#define PHY_ANALOG_BB2_FILTERFC_MASK 0x03e00000
+#define PHY_ANALOG_BB2_FILTERFC_GET(x) (((x) & 0x03e00000) >> 21)
+#define PHY_ANALOG_BB2_FILTERFC_SET(x) (((x) << 21) & 0x03e00000)
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MSB 26
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_LSB 26
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MASK 0x04000000
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MSB 27
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_LSB 27
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MASK 0x08000000
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_BB2_I2V2RXOUT_EN_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MSB 28
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_LSB 28
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MASK 0x10000000
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_BB2_BQ2RXOUT_EN_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_MSB 29
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_LSB 29
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_MASK 0x20000000
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_BB2_RXIN2I2V_EN_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_MSB 30
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_LSB 30
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_MASK 0x40000000
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_BB2_RXIN2BQ_EN_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MSB 31
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_LSB 31
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MASK 0x80000000
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB3 */
+#define PHY_ANALOG_BB3_ADDRESS 0x00000148
+#define PHY_ANALOG_BB3_OFFSET 0x00000148
+#define PHY_ANALOG_BB3_SPARE_MSB 15
+#define PHY_ANALOG_BB3_SPARE_LSB 0
+#define PHY_ANALOG_BB3_SPARE_MASK 0x0000ffff
+#define PHY_ANALOG_BB3_SPARE_GET(x) (((x) & 0x0000ffff) >> 0)
+#define PHY_ANALOG_BB3_SPARE_SET(x) (((x) << 0) & 0x0000ffff)
+#define PHY_ANALOG_BB3_FILTERFC_MSB 20
+#define PHY_ANALOG_BB3_FILTERFC_LSB 16
+#define PHY_ANALOG_BB3_FILTERFC_MASK 0x001f0000
+#define PHY_ANALOG_BB3_FILTERFC_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_ANALOG_BB3_OFSTCORRI2VQ_MSB 25
+#define PHY_ANALOG_BB3_OFSTCORRI2VQ_LSB 21
+#define PHY_ANALOG_BB3_OFSTCORRI2VQ_MASK 0x03e00000
+#define PHY_ANALOG_BB3_OFSTCORRI2VQ_GET(x) (((x) & 0x03e00000) >> 21)
+#define PHY_ANALOG_BB3_OFSTCORRI2VI_MSB 30
+#define PHY_ANALOG_BB3_OFSTCORRI2VI_LSB 26
+#define PHY_ANALOG_BB3_OFSTCORRI2VI_MASK 0x7c000000
+#define PHY_ANALOG_BB3_OFSTCORRI2VI_GET(x) (((x) & 0x7c000000) >> 26)
+#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_MSB 31
+#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_LSB 31
+#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_MASK 0x80000000
+#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for PLLCLKMODA */
+#define PHY_ANALOG_PLLCLKMODA_ADDRESS 0x00000280
+#define PHY_ANALOG_PLLCLKMODA_OFFSET 0x00000280
+#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_MSB 0
+#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_LSB 0
+#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_MASK 0x00000001
+#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_PLLCLKMODA_PWDPLL_MSB 1
+#define PHY_ANALOG_PLLCLKMODA_PWDPLL_LSB 1
+#define PHY_ANALOG_PLLCLKMODA_PWDPLL_MASK 0x00000002
+#define PHY_ANALOG_PLLCLKMODA_PWDPLL_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_PLLCLKMODA_PWDPLL_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_MSB 16
+#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_LSB 2
+#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_MASK 0x0001fffc
+#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_GET(x) (((x) & 0x0001fffc) >> 2)
+#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_SET(x) (((x) << 2) & 0x0001fffc)
+#define PHY_ANALOG_PLLCLKMODA_REFDIV_MSB 20
+#define PHY_ANALOG_PLLCLKMODA_REFDIV_LSB 17
+#define PHY_ANALOG_PLLCLKMODA_REFDIV_MASK 0x001e0000
+#define PHY_ANALOG_PLLCLKMODA_REFDIV_GET(x) (((x) & 0x001e0000) >> 17)
+#define PHY_ANALOG_PLLCLKMODA_REFDIV_SET(x) (((x) << 17) & 0x001e0000)
+#define PHY_ANALOG_PLLCLKMODA_DIV_MSB 30
+#define PHY_ANALOG_PLLCLKMODA_DIV_LSB 21
+#define PHY_ANALOG_PLLCLKMODA_DIV_MASK 0x7fe00000
+#define PHY_ANALOG_PLLCLKMODA_DIV_GET(x) (((x) & 0x7fe00000) >> 21)
+#define PHY_ANALOG_PLLCLKMODA_DIV_SET(x) (((x) << 21) & 0x7fe00000)
+#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_MSB 31
+#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_LSB 31
+#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_MASK 0x80000000
+#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for PLLCLKMODA2 */
+#define PHY_ANALOG_PLLCLKMODA2_ADDRESS 0x00000284
+#define PHY_ANALOG_PLLCLKMODA2_OFFSET 0x00000284
+#define PHY_ANALOG_PLLCLKMODA2_SPARE_MSB 3
+#define PHY_ANALOG_PLLCLKMODA2_SPARE_LSB 0
+#define PHY_ANALOG_PLLCLKMODA2_SPARE_MASK 0x0000000f
+#define PHY_ANALOG_PLLCLKMODA2_SPARE_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_PLLCLKMODA2_SPARE_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_PLLCLKMODA2_DACPWD_MSB 4
+#define PHY_ANALOG_PLLCLKMODA2_DACPWD_LSB 4
+#define PHY_ANALOG_PLLCLKMODA2_DACPWD_MASK 0x00000010
+#define PHY_ANALOG_PLLCLKMODA2_DACPWD_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_PLLCLKMODA2_DACPWD_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_MSB 5
+#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_LSB 5
+#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_MASK 0x00000020
+#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_MSB 6
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_LSB 6
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_MASK 0x00000040
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_MSB 8
+#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_LSB 7
+#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_MASK 0x00000180
+#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_GET(x) (((x) & 0x00000180) >> 7)
+#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_SET(x) (((x) << 7) & 0x00000180)
+#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_MSB 12
+#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_LSB 9
+#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_MASK 0x00001e00
+#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_GET(x) (((x) & 0x00001e00) >> 9)
+#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_SET(x) (((x) << 9) & 0x00001e00)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_MSB 13
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_LSB 13
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_MASK 0x00002000
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_MSB 14
+#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_LSB 14
+#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_MASK 0x00004000
+#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_MSB 15
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_LSB 15
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_MASK 0x00008000
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_PLLCLKMODA2_PLLATB_MSB 17
+#define PHY_ANALOG_PLLCLKMODA2_PLLATB_LSB 16
+#define PHY_ANALOG_PLLCLKMODA2_PLLATB_MASK 0x00030000
+#define PHY_ANALOG_PLLCLKMODA2_PLLATB_GET(x) (((x) & 0x00030000) >> 16)
+#define PHY_ANALOG_PLLCLKMODA2_PLLATB_SET(x) (((x) << 16) & 0x00030000)
+#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_MSB 18
+#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_LSB 18
+#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_MASK 0x00040000
+#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_MSB 19
+#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_LSB 19
+#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_MASK 0x00080000
+#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_MSB 20
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_LSB 20
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_MASK 0x00100000
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_MSB 21
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_LSB 21
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_MASK 0x00200000
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_MSB 23
+#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_LSB 22
+#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_MASK 0x00c00000
+#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_PLLCLKMODA2_PLLICP_MSB 26
+#define PHY_ANALOG_PLLCLKMODA2_PLLICP_LSB 24
+#define PHY_ANALOG_PLLCLKMODA2_PLLICP_MASK 0x07000000
+#define PHY_ANALOG_PLLCLKMODA2_PLLICP_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_ANALOG_PLLCLKMODA2_PLLICP_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_MSB 31
+#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_LSB 27
+#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_MASK 0xf8000000
+#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for TOP */
+#define PHY_ANALOG_TOP_ADDRESS 0x00000288
+#define PHY_ANALOG_TOP_OFFSET 0x00000288
+#define PHY_ANALOG_TOP_SPARE_MSB 2
+#define PHY_ANALOG_TOP_SPARE_LSB 0
+#define PHY_ANALOG_TOP_SPARE_MASK 0x00000007
+#define PHY_ANALOG_TOP_SPARE_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_TOP_SPARE_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_TOP_PWDBIAS_MSB 3
+#define PHY_ANALOG_TOP_PWDBIAS_LSB 3
+#define PHY_ANALOG_TOP_PWDBIAS_MASK 0x00000008
+#define PHY_ANALOG_TOP_PWDBIAS_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_TOP_PWDBIAS_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_TOP_FLIP_XPABIAS_MSB 4
+#define PHY_ANALOG_TOP_FLIP_XPABIAS_LSB 4
+#define PHY_ANALOG_TOP_FLIP_XPABIAS_MASK 0x00000010
+#define PHY_ANALOG_TOP_FLIP_XPABIAS_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_TOP_FLIP_XPABIAS_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_TOP_XPAON2_MSB 5
+#define PHY_ANALOG_TOP_XPAON2_LSB 5
+#define PHY_ANALOG_TOP_XPAON2_MASK 0x00000020
+#define PHY_ANALOG_TOP_XPAON2_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_TOP_XPAON2_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_TOP_XPAON5_MSB 6
+#define PHY_ANALOG_TOP_XPAON5_LSB 6
+#define PHY_ANALOG_TOP_XPAON5_MASK 0x00000040
+#define PHY_ANALOG_TOP_XPAON5_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_TOP_XPAON5_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_TOP_XPASHORT2GND_MSB 7
+#define PHY_ANALOG_TOP_XPASHORT2GND_LSB 7
+#define PHY_ANALOG_TOP_XPASHORT2GND_MASK 0x00000080
+#define PHY_ANALOG_TOP_XPASHORT2GND_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_TOP_XPASHORT2GND_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_TOP_XPABIASLVL_MSB 11
+#define PHY_ANALOG_TOP_XPABIASLVL_LSB 8
+#define PHY_ANALOG_TOP_XPABIASLVL_MASK 0x00000f00
+#define PHY_ANALOG_TOP_XPABIASLVL_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TOP_XPABIASLVL_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TOP_XPABIAS_EN_MSB 12
+#define PHY_ANALOG_TOP_XPABIAS_EN_LSB 12
+#define PHY_ANALOG_TOP_XPABIAS_EN_MASK 0x00001000
+#define PHY_ANALOG_TOP_XPABIAS_EN_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_TOP_XPABIAS_EN_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_TOP_ATBSELECT_MSB 13
+#define PHY_ANALOG_TOP_ATBSELECT_LSB 13
+#define PHY_ANALOG_TOP_ATBSELECT_MASK 0x00002000
+#define PHY_ANALOG_TOP_ATBSELECT_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_TOP_ATBSELECT_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_TOP_LOCAL_XPA_MSB 14
+#define PHY_ANALOG_TOP_LOCAL_XPA_LSB 14
+#define PHY_ANALOG_TOP_LOCAL_XPA_MASK 0x00004000
+#define PHY_ANALOG_TOP_LOCAL_XPA_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_TOP_LOCAL_XPA_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_TOP_XPABIAS_BYPASS_MSB 15
+#define PHY_ANALOG_TOP_XPABIAS_BYPASS_LSB 15
+#define PHY_ANALOG_TOP_XPABIAS_BYPASS_MASK 0x00008000
+#define PHY_ANALOG_TOP_XPABIAS_BYPASS_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_TOP_XPABIAS_BYPASS_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_TOP_TEST_PADQ_EN_MSB 16
+#define PHY_ANALOG_TOP_TEST_PADQ_EN_LSB 16
+#define PHY_ANALOG_TOP_TEST_PADQ_EN_MASK 0x00010000
+#define PHY_ANALOG_TOP_TEST_PADQ_EN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_TOP_TEST_PADQ_EN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_TOP_TEST_PADI_EN_MSB 17
+#define PHY_ANALOG_TOP_TEST_PADI_EN_LSB 17
+#define PHY_ANALOG_TOP_TEST_PADI_EN_MASK 0x00020000
+#define PHY_ANALOG_TOP_TEST_PADI_EN_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_TOP_TEST_PADI_EN_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_ANALOG_TOP_TESTIQ_RSEL_MSB 18
+#define PHY_ANALOG_TOP_TESTIQ_RSEL_LSB 18
+#define PHY_ANALOG_TOP_TESTIQ_RSEL_MASK 0x00040000
+#define PHY_ANALOG_TOP_TESTIQ_RSEL_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_ANALOG_TOP_TESTIQ_RSEL_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_ANALOG_TOP_TESTIQ_BUFEN_MSB 19
+#define PHY_ANALOG_TOP_TESTIQ_BUFEN_LSB 19
+#define PHY_ANALOG_TOP_TESTIQ_BUFEN_MASK 0x00080000
+#define PHY_ANALOG_TOP_TESTIQ_BUFEN_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_TOP_TESTIQ_BUFEN_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_TOP_PAD2GND_MSB 20
+#define PHY_ANALOG_TOP_PAD2GND_LSB 20
+#define PHY_ANALOG_TOP_PAD2GND_MASK 0x00100000
+#define PHY_ANALOG_TOP_PAD2GND_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_ANALOG_TOP_PAD2GND_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_ANALOG_TOP_INTH2PAD_MSB 21
+#define PHY_ANALOG_TOP_INTH2PAD_LSB 21
+#define PHY_ANALOG_TOP_INTH2PAD_MASK 0x00200000
+#define PHY_ANALOG_TOP_INTH2PAD_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_ANALOG_TOP_INTH2PAD_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_ANALOG_TOP_INTH2GND_MSB 22
+#define PHY_ANALOG_TOP_INTH2GND_LSB 22
+#define PHY_ANALOG_TOP_INTH2GND_MASK 0x00400000
+#define PHY_ANALOG_TOP_INTH2GND_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_TOP_INTH2GND_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_TOP_INT2PAD_MSB 23
+#define PHY_ANALOG_TOP_INT2PAD_LSB 23
+#define PHY_ANALOG_TOP_INT2PAD_MASK 0x00800000
+#define PHY_ANALOG_TOP_INT2PAD_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_TOP_INT2PAD_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_TOP_INT2GND_MSB 24
+#define PHY_ANALOG_TOP_INT2GND_LSB 24
+#define PHY_ANALOG_TOP_INT2GND_MASK 0x01000000
+#define PHY_ANALOG_TOP_INT2GND_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_TOP_INT2GND_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_TOP_PWDPALCLK_MSB 25
+#define PHY_ANALOG_TOP_PWDPALCLK_LSB 25
+#define PHY_ANALOG_TOP_PWDPALCLK_MASK 0x02000000
+#define PHY_ANALOG_TOP_PWDPALCLK_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_ANALOG_TOP_PWDPALCLK_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_ANALOG_TOP_INV_CLK320_ADC_MSB 26
+#define PHY_ANALOG_TOP_INV_CLK320_ADC_LSB 26
+#define PHY_ANALOG_TOP_INV_CLK320_ADC_MASK 0x04000000
+#define PHY_ANALOG_TOP_INV_CLK320_ADC_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_ANALOG_TOP_INV_CLK320_ADC_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_ANALOG_TOP_FLIP_REFCLK40_MSB 27
+#define PHY_ANALOG_TOP_FLIP_REFCLK40_LSB 27
+#define PHY_ANALOG_TOP_FLIP_REFCLK40_MASK 0x08000000
+#define PHY_ANALOG_TOP_FLIP_REFCLK40_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_TOP_FLIP_REFCLK40_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_TOP_FLIP_PLLCLK320_MSB 28
+#define PHY_ANALOG_TOP_FLIP_PLLCLK320_LSB 28
+#define PHY_ANALOG_TOP_FLIP_PLLCLK320_MASK 0x10000000
+#define PHY_ANALOG_TOP_FLIP_PLLCLK320_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_TOP_FLIP_PLLCLK320_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_TOP_FLIP_PLLCLK160_MSB 29
+#define PHY_ANALOG_TOP_FLIP_PLLCLK160_LSB 29
+#define PHY_ANALOG_TOP_FLIP_PLLCLK160_MASK 0x20000000
+#define PHY_ANALOG_TOP_FLIP_PLLCLK160_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_TOP_FLIP_PLLCLK160_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_TOP_CLK_SEL_MSB 31
+#define PHY_ANALOG_TOP_CLK_SEL_LSB 30
+#define PHY_ANALOG_TOP_CLK_SEL_MASK 0xc0000000
+#define PHY_ANALOG_TOP_CLK_SEL_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_ANALOG_TOP_CLK_SEL_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for THERM */
+#define PHY_ANALOG_THERM_ADDRESS 0x0000028c
+#define PHY_ANALOG_THERM_OFFSET 0x0000028c
+#define PHY_ANALOG_THERM_LOREG_LVL_MSB 2
+#define PHY_ANALOG_THERM_LOREG_LVL_LSB 0
+#define PHY_ANALOG_THERM_LOREG_LVL_MASK 0x00000007
+#define PHY_ANALOG_THERM_LOREG_LVL_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_ANALOG_THERM_LOREG_LVL_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_ANALOG_THERM_RFREG_LVL_MSB 5
+#define PHY_ANALOG_THERM_RFREG_LVL_LSB 3
+#define PHY_ANALOG_THERM_RFREG_LVL_MASK 0x00000038
+#define PHY_ANALOG_THERM_RFREG_LVL_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_ANALOG_THERM_RFREG_LVL_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_ANALOG_THERM_SAR_ADC_DONE_MSB 6
+#define PHY_ANALOG_THERM_SAR_ADC_DONE_LSB 6
+#define PHY_ANALOG_THERM_SAR_ADC_DONE_MASK 0x00000040
+#define PHY_ANALOG_THERM_SAR_ADC_DONE_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_THERM_SAR_ADC_OUT_MSB 14
+#define PHY_ANALOG_THERM_SAR_ADC_OUT_LSB 7
+#define PHY_ANALOG_THERM_SAR_ADC_OUT_MASK 0x00007f80
+#define PHY_ANALOG_THERM_SAR_ADC_OUT_GET(x) (((x) & 0x00007f80) >> 7)
+#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_MSB 22
+#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_LSB 15
+#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_MASK 0x007f8000
+#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_GET(x) (((x) & 0x007f8000) >> 15)
+#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_SET(x) (((x) << 15) & 0x007f8000)
+#define PHY_ANALOG_THERM_SAR_DACTEST_EN_MSB 23
+#define PHY_ANALOG_THERM_SAR_DACTEST_EN_LSB 23
+#define PHY_ANALOG_THERM_SAR_DACTEST_EN_MASK 0x00800000
+#define PHY_ANALOG_THERM_SAR_DACTEST_EN_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_ANALOG_THERM_SAR_DACTEST_EN_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_MSB 24
+#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_LSB 24
+#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_MASK 0x01000000
+#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_ANALOG_THERM_THERMSEL_MSB 26
+#define PHY_ANALOG_THERM_THERMSEL_LSB 25
+#define PHY_ANALOG_THERM_THERMSEL_MASK 0x06000000
+#define PHY_ANALOG_THERM_THERMSEL_GET(x) (((x) & 0x06000000) >> 25)
+#define PHY_ANALOG_THERM_THERMSEL_SET(x) (((x) << 25) & 0x06000000)
+#define PHY_ANALOG_THERM_SAR_SLOW_EN_MSB 27
+#define PHY_ANALOG_THERM_SAR_SLOW_EN_LSB 27
+#define PHY_ANALOG_THERM_SAR_SLOW_EN_MASK 0x08000000
+#define PHY_ANALOG_THERM_SAR_SLOW_EN_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_ANALOG_THERM_SAR_SLOW_EN_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_ANALOG_THERM_THERMSTART_MSB 28
+#define PHY_ANALOG_THERM_THERMSTART_LSB 28
+#define PHY_ANALOG_THERM_THERMSTART_MASK 0x10000000
+#define PHY_ANALOG_THERM_THERMSTART_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_THERM_THERMSTART_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_MSB 29
+#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_LSB 29
+#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_MASK 0x20000000
+#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_ANALOG_THERM_THERMON_MSB 30
+#define PHY_ANALOG_THERM_THERMON_LSB 30
+#define PHY_ANALOG_THERM_THERMON_MASK 0x40000000
+#define PHY_ANALOG_THERM_THERMON_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_THERM_THERMON_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_THERM_LOCAL_THERM_MSB 31
+#define PHY_ANALOG_THERM_LOCAL_THERM_LSB 31
+#define PHY_ANALOG_THERM_LOCAL_THERM_MASK 0x80000000
+#define PHY_ANALOG_THERM_LOCAL_THERM_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_THERM_LOCAL_THERM_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for XTAL */
+#define PHY_ANALOG_XTAL_ADDRESS 0x00000290
+#define PHY_ANALOG_XTAL_OFFSET 0x00000290
+#define PHY_ANALOG_XTAL_SPARE_MSB 5
+#define PHY_ANALOG_XTAL_SPARE_LSB 0
+#define PHY_ANALOG_XTAL_SPARE_MASK 0x0000003f
+#define PHY_ANALOG_XTAL_SPARE_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_ANALOG_XTAL_SPARE_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_MSB 6
+#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_LSB 6
+#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_MASK 0x00000040
+#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_XTAL_LOCALBIAS2X_MSB 7
+#define PHY_ANALOG_XTAL_LOCALBIAS2X_LSB 7
+#define PHY_ANALOG_XTAL_LOCALBIAS2X_MASK 0x00000080
+#define PHY_ANALOG_XTAL_LOCALBIAS2X_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_XTAL_LOCALBIAS2X_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_XTAL_LOCAL_XTAL_MSB 8
+#define PHY_ANALOG_XTAL_LOCAL_XTAL_LSB 8
+#define PHY_ANALOG_XTAL_LOCAL_XTAL_MASK 0x00000100
+#define PHY_ANALOG_XTAL_LOCAL_XTAL_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_XTAL_LOCAL_XTAL_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_MSB 9
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_LSB 9
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_MASK 0x00000200
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_XTAL_XTAL_OSCON_MSB 10
+#define PHY_ANALOG_XTAL_XTAL_OSCON_LSB 10
+#define PHY_ANALOG_XTAL_XTAL_OSCON_MASK 0x00000400
+#define PHY_ANALOG_XTAL_XTAL_OSCON_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_XTAL_XTAL_OSCON_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_MSB 11
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_LSB 11
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_MASK 0x00000800
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_MSB 12
+#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_LSB 12
+#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_MASK 0x00001000
+#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_MSB 13
+#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_LSB 13
+#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_MASK 0x00002000
+#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_XTAL_XTAL_DRVSTR_MSB 15
+#define PHY_ANALOG_XTAL_XTAL_DRVSTR_LSB 14
+#define PHY_ANALOG_XTAL_XTAL_DRVSTR_MASK 0x0000c000
+#define PHY_ANALOG_XTAL_XTAL_DRVSTR_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_ANALOG_XTAL_XTAL_DRVSTR_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_MSB 22
+#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_LSB 16
+#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_MASK 0x007f0000
+#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_GET(x) (((x) & 0x007f0000) >> 16)
+#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_SET(x) (((x) << 16) & 0x007f0000)
+#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_MSB 29
+#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_LSB 23
+#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_MASK 0x3f800000
+#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_GET(x) (((x) & 0x3f800000) >> 23)
+#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_SET(x) (((x) << 23) & 0x3f800000)
+#define PHY_ANALOG_XTAL_XTAL_BIAS2X_MSB 30
+#define PHY_ANALOG_XTAL_XTAL_BIAS2X_LSB 30
+#define PHY_ANALOG_XTAL_XTAL_BIAS2X_MASK 0x40000000
+#define PHY_ANALOG_XTAL_XTAL_BIAS2X_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_ANALOG_XTAL_XTAL_BIAS2X_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_ANALOG_XTAL_TCXODET_MSB 31
+#define PHY_ANALOG_XTAL_TCXODET_LSB 31
+#define PHY_ANALOG_XTAL_TCXODET_MASK 0x80000000
+#define PHY_ANALOG_XTAL_TCXODET_GET(x) (((x) & 0x80000000) >> 31)
+
+/* macros for rbist_cntrl */
+#define PHY_ANALOG_RBIST_CNTRL_ADDRESS 0x00000380
+#define PHY_ANALOG_RBIST_CNTRL_OFFSET 0x00000380
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MSB 0
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_LSB 0
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MASK 0x00000001
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MSB 1
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_LSB 1
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MASK 0x00000002
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MSB 2
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_LSB 2
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MASK 0x00000004
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MSB 3
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_LSB 3
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MASK 0x00000008
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MSB 4
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_LSB 4
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MASK 0x00000010
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MSB 5
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_LSB 5
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MASK 0x00000020
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MSB 6
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_LSB 6
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MASK 0x00000040
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MSB 7
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_LSB 7
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MASK 0x00000080
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MSB 8
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_LSB 8
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MASK 0x00000100
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MSB 9
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_LSB 9
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MASK 0x00000200
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MSB 10
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_LSB 10
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MASK 0x00000400
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MSB 11
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_LSB 11
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MASK 0x00000800
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MSB 12
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_LSB 12
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MASK 0x00001000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MSB 13
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_LSB 13
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MASK 0x00002000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MSB 14
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_LSB 14
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MASK 0x00004000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MSB 15
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_LSB 15
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MASK 0x00008000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MSB 16
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_LSB 16
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MASK 0x00010000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MSB 17
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_LSB 17
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MASK 0x00020000
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_SET(x) (((x) << 17) & 0x00020000)
+
+/* macros for tx_dc_offset */
+#define PHY_ANALOG_TX_DC_OFFSET_ADDRESS 0x00000384
+#define PHY_ANALOG_TX_DC_OFFSET_OFFSET 0x00000384
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MSB 10
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_LSB 0
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MASK 0x000007ff
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MSB 26
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_LSB 16
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MASK 0x07ff0000
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_GET(x) (((x) & 0x07ff0000) >> 16)
+#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_SET(x) (((x) << 16) & 0x07ff0000)
+
+/* macros for tx_tonegen0 */
+#define PHY_ANALOG_TX_TONEGEN0_ADDRESS 0x00000388
+#define PHY_ANALOG_TX_TONEGEN0_OFFSET 0x00000388
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_tonegen1 */
+#define PHY_ANALOG_TX_TONEGEN1_ADDRESS 0x0000038c
+#define PHY_ANALOG_TX_TONEGEN1_OFFSET 0x0000038c
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_lftonegen0 */
+#define PHY_ANALOG_TX_LFTONEGEN0_ADDRESS 0x00000390
+#define PHY_ANALOG_TX_LFTONEGEN0_OFFSET 0x00000390
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB 6
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB 0
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK 0x0000007f
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB 11
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB 8
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK 0x00000f00
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB 23
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB 16
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK 0x00ff0000
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB 30
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB 24
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK 0x7f000000
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for tx_linear_ramp_i */
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ADDRESS 0x00000394
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_OFFSET 0x00000394
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MSB 10
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_LSB 0
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MASK 0x000007ff
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MSB 21
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_LSB 12
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MASK 0x003ff000
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MSB 29
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_LSB 24
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MASK 0x3f000000
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for tx_linear_ramp_q */
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ADDRESS 0x00000398
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_OFFSET 0x00000398
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MSB 10
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_LSB 0
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MASK 0x000007ff
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MSB 21
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_LSB 12
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MASK 0x003ff000
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MSB 29
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_LSB 24
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MASK 0x3f000000
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for tx_prbs_mag */
+#define PHY_ANALOG_TX_PRBS_MAG_ADDRESS 0x0000039c
+#define PHY_ANALOG_TX_PRBS_MAG_OFFSET 0x0000039c
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MSB 9
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_LSB 0
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MASK 0x000003ff
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MSB 25
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_LSB 16
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MASK 0x03ff0000
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_SET(x) (((x) << 16) & 0x03ff0000)
+
+/* macros for tx_prbs_seed_i */
+#define PHY_ANALOG_TX_PRBS_SEED_I_ADDRESS 0x000003a0
+#define PHY_ANALOG_TX_PRBS_SEED_I_OFFSET 0x000003a0
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MSB 30
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_LSB 0
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MASK 0x7fffffff
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_GET(x) (((x) & 0x7fffffff) >> 0)
+#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_SET(x) (((x) << 0) & 0x7fffffff)
+
+/* macros for tx_prbs_seed_q */
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ADDRESS 0x000003a4
+#define PHY_ANALOG_TX_PRBS_SEED_Q_OFFSET 0x000003a4
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MSB 30
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_LSB 0
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MASK 0x7fffffff
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_GET(x) (((x) & 0x7fffffff) >> 0)
+#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_SET(x) (((x) << 0) & 0x7fffffff)
+
+/* macros for cmac_dc_cancel */
+#define PHY_ANALOG_CMAC_DC_CANCEL_ADDRESS 0x000003a8
+#define PHY_ANALOG_CMAC_DC_CANCEL_OFFSET 0x000003a8
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MSB 9
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_LSB 0
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MASK 0x000003ff
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MSB 25
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_LSB 16
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MASK 0x03ff0000
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_SET(x) (((x) << 16) & 0x03ff0000)
+
+/* macros for cmac_dc_offset */
+#define PHY_ANALOG_CMAC_DC_OFFSET_ADDRESS 0x000003ac
+#define PHY_ANALOG_CMAC_DC_OFFSET_OFFSET 0x000003ac
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_corr */
+#define PHY_ANALOG_CMAC_CORR_ADDRESS 0x000003b0
+#define PHY_ANALOG_CMAC_CORR_OFFSET 0x000003b0
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MSB 4
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MASK 0x0000001f
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MSB 13
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_LSB 8
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MASK 0x00003f00
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_SET(x) (((x) << 8) & 0x00003f00)
+
+/* macros for cmac_power */
+#define PHY_ANALOG_CMAC_POWER_ADDRESS 0x000003b4
+#define PHY_ANALOG_CMAC_POWER_OFFSET 0x000003b4
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_cross_corr */
+#define PHY_ANALOG_CMAC_CROSS_CORR_ADDRESS 0x000003b8
+#define PHY_ANALOG_CMAC_CROSS_CORR_OFFSET 0x000003b8
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_i2q2 */
+#define PHY_ANALOG_CMAC_I2Q2_ADDRESS 0x000003bc
+#define PHY_ANALOG_CMAC_I2Q2_OFFSET 0x000003bc
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+
+/* macros for cmac_power_hpf */
+#define PHY_ANALOG_CMAC_POWER_HPF_ADDRESS 0x000003c0
+#define PHY_ANALOG_CMAC_POWER_HPF_OFFSET 0x000003c0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MSB 3
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_LSB 0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MASK 0x0000000f
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MSB 7
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_LSB 4
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MASK 0x000000f0
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_SET(x) (((x) << 4) & 0x000000f0)
+
+/* macros for rxdac_set1 */
+#define PHY_ANALOG_RXDAC_SET1_ADDRESS 0x000003c4
+#define PHY_ANALOG_RXDAC_SET1_OFFSET 0x000003c4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MSB 1
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_LSB 0
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MASK 0x00000003
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MSB 4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_LSB 4
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MASK 0x00000010
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MSB 13
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_LSB 8
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MASK 0x00003f00
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MSB 19
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_LSB 16
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MASK 0x000f0000
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_SET(x) (((x) << 16) & 0x000f0000)
+
+/* macros for rxdac_set2 */
+#define PHY_ANALOG_RXDAC_SET2_ADDRESS 0x000003c8
+#define PHY_ANALOG_RXDAC_SET2_OFFSET 0x000003c8
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MSB 4
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_LSB 0
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MASK 0x0000001f
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MSB 12
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_LSB 8
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MASK 0x00001f00
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_SET(x) (((x) << 8) & 0x00001f00)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MSB 20
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_LSB 16
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MASK 0x001f0000
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MSB 28
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_LSB 24
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MASK 0x1f000000
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_SET(x) (((x) << 24) & 0x1f000000)
+
+/* macros for rxdac_long_shift */
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ADDRESS 0x000003cc
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_OFFSET 0x000003cc
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MSB 4
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_LSB 0
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MASK 0x0000001f
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MSB 12
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_LSB 8
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MASK 0x00001f00
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_SET(x) (((x) << 8) & 0x00001f00)
+
+/* macros for cmac_results_i */
+#define PHY_ANALOG_CMAC_RESULTS_I_ADDRESS 0x000003d0
+#define PHY_ANALOG_CMAC_RESULTS_I_OFFSET 0x000003d0
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MSB 31
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_LSB 0
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MASK 0xffffffff
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for cmac_results_q */
+#define PHY_ANALOG_CMAC_RESULTS_Q_ADDRESS 0x000003d4
+#define PHY_ANALOG_CMAC_RESULTS_Q_OFFSET 0x000003d4
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MSB 31
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_LSB 0
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MASK 0xffffffff
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for PMU1 */
+#define PHY_ANALOG_PMU1_ADDRESS 0x00000740
+#define PHY_ANALOG_PMU1_OFFSET 0x00000740
+#define PHY_ANALOG_PMU1_SPARE_MSB 10
+#define PHY_ANALOG_PMU1_SPARE_LSB 0
+#define PHY_ANALOG_PMU1_SPARE_MASK 0x000007ff
+#define PHY_ANALOG_PMU1_SPARE_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_ANALOG_PMU1_SPARE_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_MSB 11
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_LSB 11
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_MASK 0x00000800
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_PMU1_OTP_V25_PWD_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_PMU1_PAREGON_MAN_MSB 12
+#define PHY_ANALOG_PMU1_PAREGON_MAN_LSB 12
+#define PHY_ANALOG_PMU1_PAREGON_MAN_MASK 0x00001000
+#define PHY_ANALOG_PMU1_PAREGON_MAN_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_PMU1_PAREGON_MAN_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_MSB 13
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_LSB 13
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_MASK 0x00002000
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_PMU1_OTPREGON_MAN_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_PMU1_DREGON_MAN_MSB 14
+#define PHY_ANALOG_PMU1_DREGON_MAN_LSB 14
+#define PHY_ANALOG_PMU1_DREGON_MAN_MASK 0x00004000
+#define PHY_ANALOG_PMU1_DREGON_MAN_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_PMU1_DREGON_MAN_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_MSB 15
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_LSB 15
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_MASK 0x00008000
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_PMU1_DISCONTMODEEN_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_PMU1_SWREGON_MAN_MSB 16
+#define PHY_ANALOG_PMU1_SWREGON_MAN_LSB 16
+#define PHY_ANALOG_PMU1_SWREGON_MAN_MASK 0x00010000
+#define PHY_ANALOG_PMU1_SWREGON_MAN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_PMU1_SWREGON_MAN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MSB 18
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_LSB 17
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MASK 0x00060000
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_PMU1_SWREG_FREQCUR_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MSB 21
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_LSB 19
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MASK 0x00380000
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_ANALOG_PMU1_SWREG_FREQCAP_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MSB 23
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_LSB 22
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MASK 0x00c00000
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_ANALOG_PMU1_SWREG_LVLCTR_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_MSB 25
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_LSB 24
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_MASK 0x03000000
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_ANALOG_PMU1_SREG_LVLCTR_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_MSB 27
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_LSB 26
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_MASK 0x0c000000
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_ANALOG_PMU1_DREG_LVLCTR_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_ANALOG_PMU1_PAREG_XPNP_MSB 28
+#define PHY_ANALOG_PMU1_PAREG_XPNP_LSB 28
+#define PHY_ANALOG_PMU1_PAREG_XPNP_MASK 0x10000000
+#define PHY_ANALOG_PMU1_PAREG_XPNP_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_PMU1_PAREG_XPNP_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MSB 31
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_LSB 29
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MASK 0xe0000000
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_GET(x) (((x) & 0xe0000000) >> 29)
+#define PHY_ANALOG_PMU1_PAREG_LVLCTR_SET(x) (((x) << 29) & 0xe0000000)
+
+/* macros for PMU2 */
+#define PHY_ANALOG_PMU2_ADDRESS 0x00000744
+#define PHY_ANALOG_PMU2_OFFSET 0x00000744
+#define PHY_ANALOG_PMU2_SPARE_MSB 7
+#define PHY_ANALOG_PMU2_SPARE_LSB 0
+#define PHY_ANALOG_PMU2_SPARE_MASK 0x000000ff
+#define PHY_ANALOG_PMU2_SPARE_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_ANALOG_PMU2_SPARE_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MSB 8
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_LSB 8
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MASK 0x00000100
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MSB 9
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_LSB 9
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MASK 0x00000200
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MSB 10
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_LSB 10
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MASK 0x00000400
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MSB 11
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_LSB 11
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MASK 0x00000800
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MSB 12
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_LSB 12
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MASK 0x00001000
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_ANALOG_PMU2_PWD_LFO_MAN_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MSB 13
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_LSB 13
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MASK 0x00002000
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_ANALOG_PMU2_VBATT_LT_3P2_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MSB 14
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_LSB 14
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MASK 0x00004000
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_ANALOG_PMU2_VBATT_LT_2P8_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MSB 15
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_LSB 15
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MASK 0x00008000
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_ANALOG_PMU2_VBATT_GT_4P2_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MSB 16
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_LSB 16
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MASK 0x00010000
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MSB 18
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_LSB 17
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MASK 0x00060000
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_GET(x) (((x) & 0x00060000) >> 17)
+#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_SET(x) (((x) << 17) & 0x00060000)
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MSB 19
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_LSB 19
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MASK 0x00080000
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MSB 21
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_LSB 20
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MASK 0x00300000
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_GET(x) (((x) & 0x00300000) >> 20)
+#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_SET(x) (((x) << 20) & 0x00300000)
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MSB 22
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_LSB 22
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MASK 0x00400000
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MSB 24
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_LSB 23
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MASK 0x01800000
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_GET(x) (((x) & 0x01800000) >> 23)
+#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_SET(x) (((x) << 23) & 0x01800000)
+#define PHY_ANALOG_PMU2_SWREG2ATB_MSB 27
+#define PHY_ANALOG_PMU2_SWREG2ATB_LSB 25
+#define PHY_ANALOG_PMU2_SWREG2ATB_MASK 0x0e000000
+#define PHY_ANALOG_PMU2_SWREG2ATB_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_ANALOG_PMU2_SWREG2ATB_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_ANALOG_PMU2_OTPREG2ATB_MSB 28
+#define PHY_ANALOG_PMU2_OTPREG2ATB_LSB 28
+#define PHY_ANALOG_PMU2_OTPREG2ATB_MASK 0x10000000
+#define PHY_ANALOG_PMU2_OTPREG2ATB_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_ANALOG_PMU2_OTPREG2ATB_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MSB 30
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_LSB 29
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MASK 0x60000000
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_SET(x) (((x) << 29) & 0x60000000)
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MSB 31
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_LSB 31
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MASK 0x80000000
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_SET(x) (((x) << 31) & 0x80000000)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct analog_intf_athr_wlan_reg_reg_s {
+ volatile unsigned int RXRF_BIAS1; /* 0x0 - 0x4 */
+ volatile unsigned int RXRF_BIAS2; /* 0x4 - 0x8 */
+ volatile unsigned int RXRF_GAINSTAGES; /* 0x8 - 0xc */
+ volatile unsigned int RXRF_AGC; /* 0xc - 0x10 */
+ volatile char pad__0[0x30]; /* 0x10 - 0x40 */
+ volatile unsigned int TXRF1; /* 0x40 - 0x44 */
+ volatile unsigned int TXRF2; /* 0x44 - 0x48 */
+ volatile unsigned int TXRF3; /* 0x48 - 0x4c */
+ volatile unsigned int TXRF4; /* 0x4c - 0x50 */
+ volatile unsigned int TXRF5; /* 0x50 - 0x54 */
+ volatile unsigned int TXRF6; /* 0x54 - 0x58 */
+ volatile unsigned int TXRF7; /* 0x58 - 0x5c */
+ volatile unsigned int TXRF8; /* 0x5c - 0x60 */
+ volatile unsigned int TXRF9; /* 0x60 - 0x64 */
+ volatile unsigned int TXRF10; /* 0x64 - 0x68 */
+ volatile unsigned int TXRF11; /* 0x68 - 0x6c */
+ volatile unsigned int TXRF12; /* 0x6c - 0x70 */
+ volatile char pad__1[0x10]; /* 0x70 - 0x80 */
+ volatile unsigned int SYNTH1; /* 0x80 - 0x84 */
+ volatile unsigned int SYNTH2; /* 0x84 - 0x88 */
+ volatile unsigned int SYNTH3; /* 0x88 - 0x8c */
+ volatile unsigned int SYNTH4; /* 0x8c - 0x90 */
+ volatile unsigned int SYNTH5; /* 0x90 - 0x94 */
+ volatile unsigned int SYNTH6; /* 0x94 - 0x98 */
+ volatile unsigned int SYNTH7; /* 0x98 - 0x9c */
+ volatile unsigned int SYNTH8; /* 0x9c - 0xa0 */
+ volatile unsigned int SYNTH9; /* 0xa0 - 0xa4 */
+ volatile unsigned int SYNTH10; /* 0xa4 - 0xa8 */
+ volatile unsigned int SYNTH11; /* 0xa8 - 0xac */
+ volatile unsigned int SYNTH12; /* 0xac - 0xb0 */
+ volatile unsigned int SYNTH13; /* 0xb0 - 0xb4 */
+ volatile unsigned int SYNTH14; /* 0xb4 - 0xb8 */
+ volatile char pad__2[0x8]; /* 0xb8 - 0xc0 */
+ volatile unsigned int BIAS1; /* 0xc0 - 0xc4 */
+ volatile unsigned int BIAS2; /* 0xc4 - 0xc8 */
+ volatile unsigned int BIAS3; /* 0xc8 - 0xcc */
+ volatile unsigned int BIAS4; /* 0xcc - 0xd0 */
+ volatile char pad__3[0x30]; /* 0xd0 - 0x100 */
+ volatile unsigned int RXTX1; /* 0x100 - 0x104 */
+ volatile unsigned int RXTX2; /* 0x104 - 0x108 */
+ volatile unsigned int RXTX3; /* 0x108 - 0x10c */
+ volatile char pad__4[0x34]; /* 0x10c - 0x140 */
+ volatile unsigned int BB1; /* 0x140 - 0x144 */
+ volatile unsigned int BB2; /* 0x144 - 0x148 */
+ volatile unsigned int BB3; /* 0x148 - 0x14c */
+ volatile char pad__5[0x134]; /* 0x14c - 0x280 */
+ volatile unsigned int PLLCLKMODA; /* 0x280 - 0x284 */
+ volatile unsigned int PLLCLKMODA2; /* 0x284 - 0x288 */
+ volatile unsigned int TOP; /* 0x288 - 0x28c */
+ volatile unsigned int THERM; /* 0x28c - 0x290 */
+ volatile unsigned int XTAL; /* 0x290 - 0x294 */
+ volatile char pad__6[0xec]; /* 0x294 - 0x380 */
+ volatile unsigned int rbist_cntrl; /* 0x380 - 0x384 */
+ volatile unsigned int tx_dc_offset; /* 0x384 - 0x388 */
+ volatile unsigned int tx_tonegen0; /* 0x388 - 0x38c */
+ volatile unsigned int tx_tonegen1; /* 0x38c - 0x390 */
+ volatile unsigned int tx_lftonegen0; /* 0x390 - 0x394 */
+ volatile unsigned int tx_linear_ramp_i; /* 0x394 - 0x398 */
+ volatile unsigned int tx_linear_ramp_q; /* 0x398 - 0x39c */
+ volatile unsigned int tx_prbs_mag; /* 0x39c - 0x3a0 */
+ volatile unsigned int tx_prbs_seed_i; /* 0x3a0 - 0x3a4 */
+ volatile unsigned int tx_prbs_seed_q; /* 0x3a4 - 0x3a8 */
+ volatile unsigned int cmac_dc_cancel; /* 0x3a8 - 0x3ac */
+ volatile unsigned int cmac_dc_offset; /* 0x3ac - 0x3b0 */
+ volatile unsigned int cmac_corr; /* 0x3b0 - 0x3b4 */
+ volatile unsigned int cmac_power; /* 0x3b4 - 0x3b8 */
+ volatile unsigned int cmac_cross_corr; /* 0x3b8 - 0x3bc */
+ volatile unsigned int cmac_i2q2; /* 0x3bc - 0x3c0 */
+ volatile unsigned int cmac_power_hpf; /* 0x3c0 - 0x3c4 */
+ volatile unsigned int rxdac_set1; /* 0x3c4 - 0x3c8 */
+ volatile unsigned int rxdac_set2; /* 0x3c8 - 0x3cc */
+ volatile unsigned int rxdac_long_shift; /* 0x3cc - 0x3d0 */
+ volatile unsigned int cmac_results_i; /* 0x3d0 - 0x3d4 */
+ volatile unsigned int cmac_results_q; /* 0x3d4 - 0x3d8 */
+ volatile char pad__7[0x368]; /* 0x3d8 - 0x740 */
+ volatile unsigned int PMU1; /* 0x740 - 0x744 */
+ volatile unsigned int PMU2; /* 0x744 - 0x748 */
+} analog_intf_athr_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _ANALOG_INTF_ATHR_WLAN_REG_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h
new file mode 100644
index 000000000000..01b9eb54a43c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h
@@ -0,0 +1,37 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "analog_intf_athr_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
new file mode 100644
index 000000000000..609eb9841f59
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h
@@ -0,0 +1,40 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _APB_ATHR_WLAN_MAP_H_
+#define _APB_ATHR_WLAN_MAP_H_
+
+#define WLAN_RTC_BASE_ADDRESS 0x00004000
+#define WLAN_VMC_BASE_ADDRESS 0x00008000
+#define WLAN_UART_BASE_ADDRESS 0x0000c000
+#define WLAN_DBG_UART_BASE_ADDRESS 0x0000d000
+#define WLAN_UMBOX_BASE_ADDRESS 0x0000e000
+#define WLAN_SI_BASE_ADDRESS 0x00010000
+#define WLAN_GPIO_BASE_ADDRESS 0x00014000
+#define WLAN_MBOX_BASE_ADDRESS 0x00018000
+#define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000
+#define WLAN_MAC_BASE_ADDRESS 0x00020000
+#define WLAN_RDMA_BASE_ADDRESS 0x00030100
+#define EFUSE_BASE_ADDRESS 0x00031000
+
+#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
new file mode 100644
index 000000000000..e4d2d62f0bb4
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
@@ -0,0 +1,48 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "apb_athr_wlan_map.h"
+
+
+#ifndef BT_HEADERS
+
+#define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS
+#define VMC_BASE_ADDRESS WLAN_VMC_BASE_ADDRESS
+#define UART_BASE_ADDRESS WLAN_UART_BASE_ADDRESS
+#define DBG_UART_BASE_ADDRESS WLAN_DBG_UART_BASE_ADDRESS
+#define UMBOX_BASE_ADDRESS WLAN_UMBOX_BASE_ADDRESS
+#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS
+#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS
+#define MBOX_BASE_ADDRESS WLAN_MBOX_BASE_ADDRESS
+#define ANALOG_INTF_BASE_ADDRESS WLAN_ANALOG_INTF_BASE_ADDRESS
+#define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS
+#define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h
new file mode 100644
index 000000000000..271192953162
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h
@@ -0,0 +1,7076 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+/* Copyright (C) 2009 Denali Software Inc. All rights reserved */
+/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT */
+
+
+#ifndef _BB_LC_REG_REG_H_
+#define _BB_LC_REG_REG_H_
+
+
+/* macros for BB_test_controls */
+#define PHY_BB_TEST_CONTROLS_ADDRESS 0x00009800
+#define PHY_BB_TEST_CONTROLS_OFFSET 0x00009800
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_MSB 3
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_LSB 0
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_MASK 0x0000000f
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_MSB 4
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_LSB 4
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_MASK 0x00000010
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_MSB 6
+#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_LSB 5
+#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_MASK 0x00000060
+#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_GET(x) (((x) & 0x00000060) >> 5)
+#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_SET(x) (((x) << 5) & 0x00000060)
+#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_MSB 9
+#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_LSB 8
+#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_MASK 0x00000300
+#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_MSB 10
+#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_LSB 10
+#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_MASK 0x00000400
+#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_MSB 13
+#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_LSB 13
+#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_MASK 0x00002000
+#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_MSB 15
+#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_LSB 15
+#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_MASK 0x00008000
+#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_MSB 17
+#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_LSB 17
+#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_MASK 0x00020000
+#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_MSB 18
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_LSB 18
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_MASK 0x00040000
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_MSB 22
+#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_LSB 19
+#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_MASK 0x00780000
+#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_MSB 23
+#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_LSB 23
+#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_MASK 0x00800000
+#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_MSB 24
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_LSB 24
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_MASK 0x01000000
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_MSB 28
+#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_LSB 28
+#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_MASK 0x10000000
+#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_MSB 31
+#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_LSB 30
+#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_MASK 0xc0000000
+#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for BB_gen_controls */
+#define PHY_BB_GEN_CONTROLS_ADDRESS 0x00009804
+#define PHY_BB_GEN_CONTROLS_OFFSET 0x00009804
+#define PHY_BB_GEN_CONTROLS_TURBO_MSB 0
+#define PHY_BB_GEN_CONTROLS_TURBO_LSB 0
+#define PHY_BB_GEN_CONTROLS_TURBO_MASK 0x00000001
+#define PHY_BB_GEN_CONTROLS_TURBO_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_GEN_CONTROLS_TURBO_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_GEN_CONTROLS_CF_SHORT20_MSB 1
+#define PHY_BB_GEN_CONTROLS_CF_SHORT20_LSB 1
+#define PHY_BB_GEN_CONTROLS_CF_SHORT20_MASK 0x00000002
+#define PHY_BB_GEN_CONTROLS_CF_SHORT20_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_GEN_CONTROLS_CF_SHORT20_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_MSB 2
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_LSB 2
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_MASK 0x00000004
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_MSB 3
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_LSB 3
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_MASK 0x00000008
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_MSB 4
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_LSB 4
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_MASK 0x00000010
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_MSB 5
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_LSB 5
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_MASK 0x00000020
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_BB_GEN_CONTROLS_HT_ENABLE_MSB 6
+#define PHY_BB_GEN_CONTROLS_HT_ENABLE_LSB 6
+#define PHY_BB_GEN_CONTROLS_HT_ENABLE_MASK 0x00000040
+#define PHY_BB_GEN_CONTROLS_HT_ENABLE_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_GEN_CONTROLS_HT_ENABLE_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_MSB 7
+#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_LSB 7
+#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_MASK 0x00000080
+#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_MSB 8
+#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_LSB 8
+#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_MASK 0x00000100
+#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_MSB 9
+#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_LSB 9
+#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_MASK 0x00000200
+#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_GEN_CONTROLS_GF_ENABLE_MSB 10
+#define PHY_BB_GEN_CONTROLS_GF_ENABLE_LSB 10
+#define PHY_BB_GEN_CONTROLS_GF_ENABLE_MASK 0x00000400
+#define PHY_BB_GEN_CONTROLS_GF_ENABLE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_GEN_CONTROLS_GF_ENABLE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_MSB 11
+#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_LSB 11
+#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_MASK 0x00000800
+#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_SET(x) (((x) << 11) & 0x00000800)
+
+/* macros for BB_test_controls_status */
+#define PHY_BB_TEST_CONTROLS_STATUS_ADDRESS 0x00009808
+#define PHY_BB_TEST_CONTROLS_STATUS_OFFSET 0x00009808
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_MSB 0
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_LSB 0
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_MASK 0x00000001
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_MSB 1
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_LSB 1
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_MASK 0x00000002
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_MSB 4
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_LSB 2
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_MASK 0x0000001c
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_GET(x) (((x) & 0x0000001c) >> 2)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_SET(x) (((x) << 2) & 0x0000001c)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_MSB 6
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_LSB 5
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_MASK 0x00000060
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_GET(x) (((x) & 0x00000060) >> 5)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_SET(x) (((x) << 5) & 0x00000060)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_MSB 7
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_LSB 7
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_MASK 0x00000080
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_MSB 8
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_LSB 8
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_MASK 0x00000100
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_MSB 9
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_LSB 9
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_MASK 0x00000200
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_MSB 13
+#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_LSB 10
+#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_MASK 0x00003c00
+#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_SET(x) (((x) << 10) & 0x00003c00)
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_MSB 14
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_LSB 14
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_MASK 0x00004000
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_MSB 15
+#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_LSB 15
+#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_MASK 0x00008000
+#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_MSB 18
+#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_LSB 16
+#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_MASK 0x00070000
+#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_MSB 19
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_LSB 19
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_MASK 0x00080000
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_MSB 23
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_LSB 23
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_MASK 0x00800000
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_MSB 27
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_LSB 27
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_MASK 0x08000000
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_MSB 28
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_LSB 28
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_MASK 0x10000000
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_MSB 30
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_LSB 29
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_MASK 0x60000000
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_SET(x) (((x) << 29) & 0x60000000)
+
+/* macros for BB_timing_controls_1 */
+#define PHY_BB_TIMING_CONTROLS_1_ADDRESS 0x0000980c
+#define PHY_BB_TIMING_CONTROLS_1_OFFSET 0x0000980c
+#define PHY_BB_TIMING_CONTROLS_1_STE_THR_MSB 6
+#define PHY_BB_TIMING_CONTROLS_1_STE_THR_LSB 0
+#define PHY_BB_TIMING_CONTROLS_1_STE_THR_MASK 0x0000007f
+#define PHY_BB_TIMING_CONTROLS_1_STE_THR_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_TIMING_CONTROLS_1_STE_THR_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_MSB 12
+#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_LSB 7
+#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_MASK 0x00001f80
+#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_GET(x) (((x) & 0x00001f80) >> 7)
+#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_SET(x) (((x) << 7) & 0x00001f80)
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_MSB 16
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_LSB 13
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_MASK 0x0001e000
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_GET(x) (((x) & 0x0001e000) >> 13)
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_SET(x) (((x) << 13) & 0x0001e000)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_MSB 17
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_LSB 17
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_MASK 0x00020000
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_MSB 19
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_LSB 18
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_MASK 0x000c0000
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_MSB 21
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_LSB 20
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_MASK 0x00300000
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_GET(x) (((x) & 0x00300000) >> 20)
+#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_SET(x) (((x) << 20) & 0x00300000)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_MSB 22
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_LSB 22
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_MASK 0x00400000
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_MSB 23
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_LSB 23
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_MASK 0x00800000
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_MSB 24
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_LSB 24
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_MASK 0x01000000
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_MSB 26
+#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_LSB 25
+#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_MASK 0x06000000
+#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_GET(x) (((x) & 0x06000000) >> 25)
+#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_SET(x) (((x) << 25) & 0x06000000)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_MSB 27
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_LSB 27
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_MASK 0x08000000
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_MSB 28
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_LSB 28
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_MASK 0x10000000
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_MSB 30
+#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_LSB 29
+#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_MASK 0x60000000
+#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_SET(x) (((x) << 29) & 0x60000000)
+#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_MSB 31
+#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_LSB 31
+#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_MASK 0x80000000
+#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_timing_controls_2 */
+#define PHY_BB_TIMING_CONTROLS_2_ADDRESS 0x00009810
+#define PHY_BB_TIMING_CONTROLS_2_OFFSET 0x00009810
+#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_MSB 11
+#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_LSB 0
+#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_MASK 0x00000fff
+#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_SET(x) (((x) << 0) & 0x00000fff)
+#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_MSB 12
+#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_LSB 12
+#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_MASK 0x00001000
+#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_MSB 13
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_LSB 13
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_MASK 0x00002000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_MSB 14
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_LSB 14
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_MASK 0x00004000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_MSB 15
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_LSB 15
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_MASK 0x00008000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_MSB 22
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_LSB 16
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_MASK 0x007f0000
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_GET(x) (((x) & 0x007f0000) >> 16)
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_SET(x) (((x) << 16) & 0x007f0000)
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_MSB 26
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_LSB 24
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_MASK 0x07000000
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_MSB 27
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_LSB 27
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_MASK 0x08000000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_MSB 28
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_LSB 28
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_MASK 0x10000000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_MSB 29
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_LSB 29
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_MASK 0x20000000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_MSB 30
+#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_LSB 30
+#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_MASK 0x40000000
+#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_MSB 31
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_LSB 31
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_MASK 0x80000000
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_timing_controls_3 */
+#define PHY_BB_TIMING_CONTROLS_3_ADDRESS 0x00009814
+#define PHY_BB_TIMING_CONTROLS_3_OFFSET 0x00009814
+#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_MSB 7
+#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_LSB 0
+#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_MASK 0x000000ff
+#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_MSB 8
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_LSB 8
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_MASK 0x00000100
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_MSB 9
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_LSB 9
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_MASK 0x00000200
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_MSB 10
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_LSB 10
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_MASK 0x00000400
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_MSB 11
+#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_LSB 11
+#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_MASK 0x00000800
+#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_MSB 12
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_LSB 12
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_MASK 0x00001000
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_MSB 16
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_LSB 13
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_MASK 0x0001e000
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_GET(x) (((x) & 0x0001e000) >> 13)
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_SET(x) (((x) << 13) & 0x0001e000)
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_MSB 31
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_LSB 17
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_MASK 0xfffe0000
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_GET(x) (((x) & 0xfffe0000) >> 17)
+#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_SET(x) (((x) << 17) & 0xfffe0000)
+
+/* macros for BB_D2_chip_id */
+#define PHY_BB_D2_CHIP_ID_ADDRESS 0x00009818
+#define PHY_BB_D2_CHIP_ID_OFFSET 0x00009818
+#define PHY_BB_D2_CHIP_ID_OLD_ID_MSB 7
+#define PHY_BB_D2_CHIP_ID_OLD_ID_LSB 0
+#define PHY_BB_D2_CHIP_ID_OLD_ID_MASK 0x000000ff
+#define PHY_BB_D2_CHIP_ID_OLD_ID_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_D2_CHIP_ID_ID_MSB 31
+#define PHY_BB_D2_CHIP_ID_ID_LSB 8
+#define PHY_BB_D2_CHIP_ID_ID_MASK 0xffffff00
+#define PHY_BB_D2_CHIP_ID_ID_GET(x) (((x) & 0xffffff00) >> 8)
+
+/* macros for BB_active */
+#define PHY_BB_ACTIVE_ADDRESS 0x0000981c
+#define PHY_BB_ACTIVE_OFFSET 0x0000981c
+#define PHY_BB_ACTIVE_CF_ACTIVE_MSB 0
+#define PHY_BB_ACTIVE_CF_ACTIVE_LSB 0
+#define PHY_BB_ACTIVE_CF_ACTIVE_MASK 0x00000001
+#define PHY_BB_ACTIVE_CF_ACTIVE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_ACTIVE_CF_ACTIVE_SET(x) (((x) << 0) & 0x00000001)
+
+/* macros for BB_tx_timing_1 */
+#define PHY_BB_TX_TIMING_1_ADDRESS 0x00009820
+#define PHY_BB_TX_TIMING_1_OFFSET 0x00009820
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_MSB 7
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_LSB 0
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_MASK 0x000000ff
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_MSB 15
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_LSB 8
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_MASK 0x0000ff00
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_MSB 23
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_LSB 16
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_MASK 0x00ff0000
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_MSB 31
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_LSB 24
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_MASK 0xff000000
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_tx_timing_2 */
+#define PHY_BB_TX_TIMING_2_ADDRESS 0x00009824
+#define PHY_BB_TX_TIMING_2_OFFSET 0x00009824
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_MSB 7
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_LSB 0
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_MASK 0x000000ff
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_MSB 15
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_LSB 8
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_MASK 0x0000ff00
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_MSB 23
+#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_LSB 16
+#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_MASK 0x00ff0000
+#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_MSB 31
+#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_LSB 24
+#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_MASK 0xff000000
+#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_tx_timing_3 */
+#define PHY_BB_TX_TIMING_3_ADDRESS 0x00009828
+#define PHY_BB_TX_TIMING_3_OFFSET 0x00009828
+#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_MSB 7
+#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_LSB 0
+#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_MASK 0x000000ff
+#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_MSB 15
+#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_LSB 8
+#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_MASK 0x0000ff00
+#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_MSB 23
+#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_LSB 16
+#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_MASK 0x00ff0000
+#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_MSB 31
+#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_LSB 24
+#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_MASK 0xff000000
+#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_addac_parallel_control */
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ADDRESS 0x0000982c
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFFSET 0x0000982c
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_MSB 12
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_LSB 12
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_MASK 0x00001000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_MSB 13
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_LSB 13
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_MASK 0x00002000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_MSB 15
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_LSB 15
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_MASK 0x00008000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_MSB 28
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_LSB 28
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_MASK 0x10000000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_MSB 29
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_LSB 29
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_MASK 0x20000000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_MSB 31
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_LSB 31
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_MASK 0x80000000
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_xpa_timing_control */
+#define PHY_BB_XPA_TIMING_CONTROL_ADDRESS 0x00009834
+#define PHY_BB_XPA_TIMING_CONTROL_OFFSET 0x00009834
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_MSB 7
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_LSB 0
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_MASK 0x000000ff
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_MSB 15
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_LSB 8
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_MASK 0x0000ff00
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_MSB 23
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_LSB 16
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_MASK 0x00ff0000
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_MSB 31
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_LSB 24
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_MASK 0xff000000
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_misc_pa_control */
+#define PHY_BB_MISC_PA_CONTROL_ADDRESS 0x00009838
+#define PHY_BB_MISC_PA_CONTROL_OFFSET 0x00009838
+#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_MSB 0
+#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_LSB 0
+#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_MASK 0x00000001
+#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_MSB 1
+#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_LSB 1
+#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_MASK 0x00000002
+#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_MSB 2
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_LSB 2
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_MASK 0x00000004
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_MSB 3
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_LSB 3
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_MASK 0x00000008
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_SET(x) (((x) << 3) & 0x00000008)
+
+/* macros for BB_tstdac_constant */
+#define PHY_BB_TSTDAC_CONSTANT_ADDRESS 0x0000983c
+#define PHY_BB_TSTDAC_CONSTANT_OFFSET 0x0000983c
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_MSB 10
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_LSB 0
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_MASK 0x000007ff
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_GET(x) (((x) & 0x000007ff) >> 0)
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_SET(x) (((x) << 0) & 0x000007ff)
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_MSB 21
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_LSB 11
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_MASK 0x003ff800
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_GET(x) (((x) & 0x003ff800) >> 11)
+#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_SET(x) (((x) << 11) & 0x003ff800)
+
+/* macros for BB_find_signal_low */
+#define PHY_BB_FIND_SIGNAL_LOW_ADDRESS 0x00009840
+#define PHY_BB_FIND_SIGNAL_LOW_OFFSET 0x00009840
+#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_MSB 5
+#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_LSB 0
+#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_MASK 0x0000003f
+#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_MSB 11
+#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_LSB 6
+#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_MASK 0x00000fc0
+#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_MSB 19
+#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_LSB 12
+#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_MASK 0x000ff000
+#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_GET(x) (((x) & 0x000ff000) >> 12)
+#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_SET(x) (((x) << 12) & 0x000ff000)
+#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_MSB 23
+#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_LSB 20
+#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_MASK 0x00f00000
+#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_MSB 30
+#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_LSB 24
+#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_MASK 0x7f000000
+#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for BB_settling_time */
+#define PHY_BB_SETTLING_TIME_ADDRESS 0x00009844
+#define PHY_BB_SETTLING_TIME_OFFSET 0x00009844
+#define PHY_BB_SETTLING_TIME_AGC_SETTLING_MSB 6
+#define PHY_BB_SETTLING_TIME_AGC_SETTLING_LSB 0
+#define PHY_BB_SETTLING_TIME_AGC_SETTLING_MASK 0x0000007f
+#define PHY_BB_SETTLING_TIME_AGC_SETTLING_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_SETTLING_TIME_AGC_SETTLING_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_MSB 13
+#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_LSB 7
+#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_MASK 0x00003f80
+#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_GET(x) (((x) & 0x00003f80) >> 7)
+#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_SET(x) (((x) << 7) & 0x00003f80)
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_MSB 19
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_LSB 14
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_MASK 0x000fc000
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_SET(x) (((x) << 14) & 0x000fc000)
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_MSB 25
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_LSB 20
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_MASK 0x03f00000
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_GET(x) (((x) & 0x03f00000) >> 20)
+#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_SET(x) (((x) << 20) & 0x03f00000)
+#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_MSB 29
+#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_LSB 26
+#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_MASK 0x3c000000
+#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_GET(x) (((x) & 0x3c000000) >> 26)
+#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_SET(x) (((x) << 26) & 0x3c000000)
+
+/* macros for BB_gain_force_max_gains_b0 */
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ADDRESS 0x00009848
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_OFFSET 0x00009848
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_MSB 13
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_LSB 7
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_MASK 0x00003f80
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_GET(x) (((x) & 0x00003f80) >> 7)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_SET(x) (((x) << 7) & 0x00003f80)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_MSB 20
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_LSB 14
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_MASK 0x001fc000
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_GET(x) (((x) & 0x001fc000) >> 14)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_SET(x) (((x) << 14) & 0x001fc000)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_MSB 21
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_LSB 21
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_MASK 0x00200000
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_MSB 31
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_LSB 31
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_MASK 0x80000000
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_gains_min_offsets_b0 */
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_ADDRESS 0x0000984c
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSET 0x0000984c
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_MSB 6
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_LSB 0
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_MASK 0x0000007f
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_MSB 11
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_LSB 7
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_MASK 0x00000f80
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_GET(x) (((x) & 0x00000f80) >> 7)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_SET(x) (((x) << 7) & 0x00000f80)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_MSB 16
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_LSB 12
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_MASK 0x0001f000
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_MSB 24
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_LSB 17
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_MASK 0x01fe0000
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_GET(x) (((x) & 0x01fe0000) >> 17)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_SET(x) (((x) << 17) & 0x01fe0000)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_MSB 25
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_LSB 25
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_MASK 0x02000000
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_MSB 26
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_LSB 26
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_MASK 0x04000000
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_SET(x) (((x) << 26) & 0x04000000)
+
+/* macros for BB_desired_sigsize */
+#define PHY_BB_DESIRED_SIGSIZE_ADDRESS 0x00009850
+#define PHY_BB_DESIRED_SIGSIZE_OFFSET 0x00009850
+#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_MSB 7
+#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_LSB 0
+#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_MASK 0x000000ff
+#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_MSB 27
+#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_LSB 20
+#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_MASK 0x0ff00000
+#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_GET(x) (((x) & 0x0ff00000) >> 20)
+#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_SET(x) (((x) << 20) & 0x0ff00000)
+#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_MSB 29
+#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_LSB 28
+#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_MASK 0x30000000
+#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_GET(x) (((x) & 0x30000000) >> 28)
+#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_SET(x) (((x) << 28) & 0x30000000)
+#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_MSB 30
+#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_LSB 30
+#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_MASK 0x40000000
+#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_MSB 31
+#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_LSB 31
+#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_MASK 0x80000000
+#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_timing_control_3a */
+#define PHY_BB_TIMING_CONTROL_3A_ADDRESS 0x00009854
+#define PHY_BB_TIMING_CONTROL_3A_OFFSET 0x00009854
+#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_MSB 6
+#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_LSB 0
+#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_MASK 0x0000007f
+#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_SET(x) (((x) << 0) & 0x0000007f)
+
+/* macros for BB_find_signal */
+#define PHY_BB_FIND_SIGNAL_ADDRESS 0x00009858
+#define PHY_BB_FIND_SIGNAL_OFFSET 0x00009858
+#define PHY_BB_FIND_SIGNAL_RELSTEP_MSB 5
+#define PHY_BB_FIND_SIGNAL_RELSTEP_LSB 0
+#define PHY_BB_FIND_SIGNAL_RELSTEP_MASK 0x0000003f
+#define PHY_BB_FIND_SIGNAL_RELSTEP_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_FIND_SIGNAL_RELSTEP_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_FIND_SIGNAL_RELPWR_MSB 11
+#define PHY_BB_FIND_SIGNAL_RELPWR_LSB 6
+#define PHY_BB_FIND_SIGNAL_RELPWR_MASK 0x00000fc0
+#define PHY_BB_FIND_SIGNAL_RELPWR_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_FIND_SIGNAL_RELPWR_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_FIND_SIGNAL_FIRSTEP_MSB 17
+#define PHY_BB_FIND_SIGNAL_FIRSTEP_LSB 12
+#define PHY_BB_FIND_SIGNAL_FIRSTEP_MASK 0x0003f000
+#define PHY_BB_FIND_SIGNAL_FIRSTEP_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_FIND_SIGNAL_FIRSTEP_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_FIND_SIGNAL_FIRPWR_MSB 25
+#define PHY_BB_FIND_SIGNAL_FIRPWR_LSB 18
+#define PHY_BB_FIND_SIGNAL_FIRPWR_MASK 0x03fc0000
+#define PHY_BB_FIND_SIGNAL_FIRPWR_GET(x) (((x) & 0x03fc0000) >> 18)
+#define PHY_BB_FIND_SIGNAL_FIRPWR_SET(x) (((x) << 18) & 0x03fc0000)
+#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_MSB 31
+#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_LSB 26
+#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_MASK 0xfc000000
+#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for BB_agc */
+#define PHY_BB_AGC_ADDRESS 0x0000985c
+#define PHY_BB_AGC_OFFSET 0x0000985c
+#define PHY_BB_AGC_COARSEPWR_CONST_MSB 6
+#define PHY_BB_AGC_COARSEPWR_CONST_LSB 0
+#define PHY_BB_AGC_COARSEPWR_CONST_MASK 0x0000007f
+#define PHY_BB_AGC_COARSEPWR_CONST_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_AGC_COARSEPWR_CONST_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_AGC_COARSE_LOW_MSB 14
+#define PHY_BB_AGC_COARSE_LOW_LSB 7
+#define PHY_BB_AGC_COARSE_LOW_MASK 0x00007f80
+#define PHY_BB_AGC_COARSE_LOW_GET(x) (((x) & 0x00007f80) >> 7)
+#define PHY_BB_AGC_COARSE_LOW_SET(x) (((x) << 7) & 0x00007f80)
+#define PHY_BB_AGC_COARSE_HIGH_MSB 21
+#define PHY_BB_AGC_COARSE_HIGH_LSB 15
+#define PHY_BB_AGC_COARSE_HIGH_MASK 0x003f8000
+#define PHY_BB_AGC_COARSE_HIGH_GET(x) (((x) & 0x003f8000) >> 15)
+#define PHY_BB_AGC_COARSE_HIGH_SET(x) (((x) << 15) & 0x003f8000)
+#define PHY_BB_AGC_QUICK_DROP_MSB 29
+#define PHY_BB_AGC_QUICK_DROP_LSB 22
+#define PHY_BB_AGC_QUICK_DROP_MASK 0x3fc00000
+#define PHY_BB_AGC_QUICK_DROP_GET(x) (((x) & 0x3fc00000) >> 22)
+#define PHY_BB_AGC_QUICK_DROP_SET(x) (((x) << 22) & 0x3fc00000)
+#define PHY_BB_AGC_RSSI_OUT_SELECT_MSB 31
+#define PHY_BB_AGC_RSSI_OUT_SELECT_LSB 30
+#define PHY_BB_AGC_RSSI_OUT_SELECT_MASK 0xc0000000
+#define PHY_BB_AGC_RSSI_OUT_SELECT_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_BB_AGC_RSSI_OUT_SELECT_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for BB_agc_control */
+#define PHY_BB_AGC_CONTROL_ADDRESS 0x00009860
+#define PHY_BB_AGC_CONTROL_OFFSET 0x00009860
+#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_MSB 0
+#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_LSB 0
+#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_MASK 0x00000001
+#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_MSB 1
+#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_LSB 1
+#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_MASK 0x00000002
+#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_MSB 5
+#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_LSB 3
+#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_MASK 0x00000038
+#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_BB_AGC_CONTROL_YCOK_MAX_MSB 9
+#define PHY_BB_AGC_CONTROL_YCOK_MAX_LSB 6
+#define PHY_BB_AGC_CONTROL_YCOK_MAX_MASK 0x000003c0
+#define PHY_BB_AGC_CONTROL_YCOK_MAX_GET(x) (((x) & 0x000003c0) >> 6)
+#define PHY_BB_AGC_CONTROL_YCOK_MAX_SET(x) (((x) << 6) & 0x000003c0)
+#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_MSB 10
+#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_LSB 10
+#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_MASK 0x00000400
+#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_AGC_CONTROL_CAL_ENABLE_MSB 11
+#define PHY_BB_AGC_CONTROL_CAL_ENABLE_LSB 11
+#define PHY_BB_AGC_CONTROL_CAL_ENABLE_MASK 0x00000800
+#define PHY_BB_AGC_CONTROL_CAL_ENABLE_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_AGC_CONTROL_CAL_ENABLE_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_MSB 12
+#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_LSB 12
+#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_MASK 0x00001000
+#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_MSB 13
+#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_LSB 13
+#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_MASK 0x00002000
+#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_MSB 15
+#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_LSB 15
+#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_MASK 0x00008000
+#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_MSB 16
+#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_LSB 16
+#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_MASK 0x00010000
+#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_MSB 17
+#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_LSB 17
+#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_MASK 0x00020000
+#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_MSB 18
+#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_LSB 18
+#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_MASK 0x00040000
+#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_MSB 19
+#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_LSB 19
+#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_MASK 0x00080000
+#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_MSB 20
+#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_LSB 20
+#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_MASK 0x00100000
+#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_SET(x) (((x) << 20) & 0x00100000)
+
+/* macros for BB_cca_b0 */
+#define PHY_BB_CCA_B0_ADDRESS 0x00009864
+#define PHY_BB_CCA_B0_OFFSET 0x00009864
+#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_MSB 8
+#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_LSB 0
+#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_MASK 0x000001ff
+#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_SET(x) (((x) << 0) & 0x000001ff)
+#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_MSB 11
+#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_LSB 9
+#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_MASK 0x00000e00
+#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_SET(x) (((x) << 9) & 0x00000e00)
+#define PHY_BB_CCA_B0_CF_THRESH62_MSB 19
+#define PHY_BB_CCA_B0_CF_THRESH62_LSB 12
+#define PHY_BB_CCA_B0_CF_THRESH62_MASK 0x000ff000
+#define PHY_BB_CCA_B0_CF_THRESH62_GET(x) (((x) & 0x000ff000) >> 12)
+#define PHY_BB_CCA_B0_CF_THRESH62_SET(x) (((x) << 12) & 0x000ff000)
+#define PHY_BB_CCA_B0_MINCCAPWR_0_MSB 28
+#define PHY_BB_CCA_B0_MINCCAPWR_0_LSB 20
+#define PHY_BB_CCA_B0_MINCCAPWR_0_MASK 0x1ff00000
+#define PHY_BB_CCA_B0_MINCCAPWR_0_GET(x) (((x) & 0x1ff00000) >> 20)
+
+/* macros for BB_sfcorr */
+#define PHY_BB_SFCORR_ADDRESS 0x00009868
+#define PHY_BB_SFCORR_OFFSET 0x00009868
+#define PHY_BB_SFCORR_M2COUNT_THR_MSB 4
+#define PHY_BB_SFCORR_M2COUNT_THR_LSB 0
+#define PHY_BB_SFCORR_M2COUNT_THR_MASK 0x0000001f
+#define PHY_BB_SFCORR_M2COUNT_THR_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_SFCORR_M2COUNT_THR_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_SFCORR_ADCSAT_THRESH_MSB 10
+#define PHY_BB_SFCORR_ADCSAT_THRESH_LSB 5
+#define PHY_BB_SFCORR_ADCSAT_THRESH_MASK 0x000007e0
+#define PHY_BB_SFCORR_ADCSAT_THRESH_GET(x) (((x) & 0x000007e0) >> 5)
+#define PHY_BB_SFCORR_ADCSAT_THRESH_SET(x) (((x) << 5) & 0x000007e0)
+#define PHY_BB_SFCORR_ADCSAT_ICOUNT_MSB 16
+#define PHY_BB_SFCORR_ADCSAT_ICOUNT_LSB 11
+#define PHY_BB_SFCORR_ADCSAT_ICOUNT_MASK 0x0001f800
+#define PHY_BB_SFCORR_ADCSAT_ICOUNT_GET(x) (((x) & 0x0001f800) >> 11)
+#define PHY_BB_SFCORR_ADCSAT_ICOUNT_SET(x) (((x) << 11) & 0x0001f800)
+#define PHY_BB_SFCORR_M1_THRES_MSB 23
+#define PHY_BB_SFCORR_M1_THRES_LSB 17
+#define PHY_BB_SFCORR_M1_THRES_MASK 0x00fe0000
+#define PHY_BB_SFCORR_M1_THRES_GET(x) (((x) & 0x00fe0000) >> 17)
+#define PHY_BB_SFCORR_M1_THRES_SET(x) (((x) << 17) & 0x00fe0000)
+#define PHY_BB_SFCORR_M2_THRES_MSB 30
+#define PHY_BB_SFCORR_M2_THRES_LSB 24
+#define PHY_BB_SFCORR_M2_THRES_MASK 0x7f000000
+#define PHY_BB_SFCORR_M2_THRES_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_BB_SFCORR_M2_THRES_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for BB_self_corr_low */
+#define PHY_BB_SELF_CORR_LOW_ADDRESS 0x0000986c
+#define PHY_BB_SELF_CORR_LOW_OFFSET 0x0000986c
+#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_MSB 0
+#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_LSB 0
+#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_MASK 0x00000001
+#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_MSB 7
+#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_LSB 1
+#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_MASK 0x000000fe
+#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_MSB 13
+#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_LSB 8
+#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_MASK 0x00003f00
+#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_MSB 20
+#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_LSB 14
+#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_MASK 0x001fc000
+#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_GET(x) (((x) & 0x001fc000) >> 14)
+#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_SET(x) (((x) << 14) & 0x001fc000)
+#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_MSB 27
+#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_LSB 21
+#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_MASK 0x0fe00000
+#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_GET(x) (((x) & 0x0fe00000) >> 21)
+#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_SET(x) (((x) << 21) & 0x0fe00000)
+
+/* macros for BB_synth_control */
+#define PHY_BB_SYNTH_CONTROL_ADDRESS 0x00009874
+#define PHY_BB_SYNTH_CONTROL_OFFSET 0x00009874
+#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_MSB 16
+#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_LSB 0
+#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_MASK 0x0001ffff
+#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_GET(x) (((x) & 0x0001ffff) >> 0)
+#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_SET(x) (((x) << 0) & 0x0001ffff)
+#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_MSB 25
+#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_LSB 17
+#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_MASK 0x03fe0000
+#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_GET(x) (((x) & 0x03fe0000) >> 17)
+#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_SET(x) (((x) << 17) & 0x03fe0000)
+#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_MSB 27
+#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_LSB 26
+#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_MASK 0x0c000000
+#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_GET(x) (((x) & 0x0c000000) >> 26)
+#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_SET(x) (((x) << 26) & 0x0c000000)
+#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_MSB 28
+#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_LSB 28
+#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_MASK 0x10000000
+#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_SYNTH_CONTROL_RFBMODE_MSB 29
+#define PHY_BB_SYNTH_CONTROL_RFBMODE_LSB 29
+#define PHY_BB_SYNTH_CONTROL_RFBMODE_MASK 0x20000000
+#define PHY_BB_SYNTH_CONTROL_RFBMODE_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_SYNTH_CONTROL_RFBMODE_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_MSB 30
+#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_LSB 30
+#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_MASK 0x40000000
+#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_SET(x) (((x) << 30) & 0x40000000)
+
+/* macros for BB_addac_clk_select */
+#define PHY_BB_ADDAC_CLK_SELECT_ADDRESS 0x00009878
+#define PHY_BB_ADDAC_CLK_SELECT_OFFSET 0x00009878
+#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_MSB 3
+#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_LSB 2
+#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_MASK 0x0000000c
+#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_MSB 5
+#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_LSB 4
+#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_MASK 0x00000030
+#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_SET(x) (((x) << 4) & 0x00000030)
+
+/* macros for BB_pll_cntl */
+#define PHY_BB_PLL_CNTL_ADDRESS 0x0000987c
+#define PHY_BB_PLL_CNTL_OFFSET 0x0000987c
+#define PHY_BB_PLL_CNTL_BB_PLL_DIV_MSB 9
+#define PHY_BB_PLL_CNTL_BB_PLL_DIV_LSB 0
+#define PHY_BB_PLL_CNTL_BB_PLL_DIV_MASK 0x000003ff
+#define PHY_BB_PLL_CNTL_BB_PLL_DIV_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_PLL_CNTL_BB_PLL_DIV_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_MSB 13
+#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_LSB 10
+#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_MASK 0x00003c00
+#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_SET(x) (((x) << 10) & 0x00003c00)
+#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_MSB 15
+#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_LSB 14
+#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_MASK 0x0000c000
+#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_MSB 16
+#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_LSB 16
+#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_MASK 0x00010000
+#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_MSB 27
+#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_LSB 17
+#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_MASK 0x0ffe0000
+#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_GET(x) (((x) & 0x0ffe0000) >> 17)
+#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_SET(x) (((x) << 17) & 0x0ffe0000)
+
+/* macros for BB_vit_spur_mask_A */
+#define PHY_BB_VIT_SPUR_MASK_A_ADDRESS 0x00009900
+#define PHY_BB_VIT_SPUR_MASK_A_OFFSET 0x00009900
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_MSB 9
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_LSB 0
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_MASK 0x000003ff
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_MSB 16
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_LSB 10
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_MASK 0x0001fc00
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_GET(x) (((x) & 0x0001fc00) >> 10)
+#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_SET(x) (((x) << 10) & 0x0001fc00)
+
+/* macros for BB_vit_spur_mask_B */
+#define PHY_BB_VIT_SPUR_MASK_B_ADDRESS 0x00009904
+#define PHY_BB_VIT_SPUR_MASK_B_OFFSET 0x00009904
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_MSB 9
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_LSB 0
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_MASK 0x000003ff
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_MSB 16
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_LSB 10
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_MASK 0x0001fc00
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_GET(x) (((x) & 0x0001fc00) >> 10)
+#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_SET(x) (((x) << 10) & 0x0001fc00)
+
+/* macros for BB_pilot_spur_mask */
+#define PHY_BB_PILOT_SPUR_MASK_ADDRESS 0x00009908
+#define PHY_BB_PILOT_SPUR_MASK_OFFSET 0x00009908
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_MSB 4
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_LSB 0
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_MASK 0x0000001f
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_MSB 11
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_LSB 5
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_MASK 0x00000fe0
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_GET(x) (((x) & 0x00000fe0) >> 5)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_SET(x) (((x) << 5) & 0x00000fe0)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_MSB 16
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_LSB 12
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_MASK 0x0001f000
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_MSB 23
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_LSB 17
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_MASK 0x00fe0000
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_GET(x) (((x) & 0x00fe0000) >> 17)
+#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_SET(x) (((x) << 17) & 0x00fe0000)
+
+/* macros for BB_chan_spur_mask */
+#define PHY_BB_CHAN_SPUR_MASK_ADDRESS 0x0000990c
+#define PHY_BB_CHAN_SPUR_MASK_OFFSET 0x0000990c
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_MSB 4
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_LSB 0
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_MASK 0x0000001f
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_MSB 11
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_LSB 5
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_MASK 0x00000fe0
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_GET(x) (((x) & 0x00000fe0) >> 5)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_SET(x) (((x) << 5) & 0x00000fe0)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_MSB 16
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_LSB 12
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_MASK 0x0001f000
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_MSB 23
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_LSB 17
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_MASK 0x00fe0000
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_GET(x) (((x) & 0x00fe0000) >> 17)
+#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_SET(x) (((x) << 17) & 0x00fe0000)
+
+/* macros for BB_spectral_scan */
+#define PHY_BB_SPECTRAL_SCAN_ADDRESS 0x00009910
+#define PHY_BB_SPECTRAL_SCAN_OFFSET 0x00009910
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_MSB 0
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_LSB 0
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_MASK 0x00000001
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_MSB 1
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_LSB 1
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_MASK 0x00000002
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_MSB 2
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_LSB 2
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_MASK 0x00000004
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_MSB 3
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_LSB 3
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_MASK 0x00000008
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_MSB 7
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_LSB 4
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_MASK 0x000000f0
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_MSB 15
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_LSB 8
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_MASK 0x0000ff00
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_MSB 27
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_LSB 16
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_MASK 0x0fff0000
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_GET(x) (((x) & 0x0fff0000) >> 16)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_SET(x) (((x) << 16) & 0x0fff0000)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_MSB 28
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_LSB 28
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_MASK 0x10000000
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_MSB 29
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_LSB 29
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_MASK 0x20000000
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_MSB 30
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_LSB 30
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_MASK 0x40000000
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_SET(x) (((x) << 30) & 0x40000000)
+
+/* macros for BB_analog_power_on_time */
+#define PHY_BB_ANALOG_POWER_ON_TIME_ADDRESS 0x00009914
+#define PHY_BB_ANALOG_POWER_ON_TIME_OFFSET 0x00009914
+#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_MSB 13
+#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_LSB 0
+#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_MASK 0x00003fff
+#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_SET(x) (((x) << 0) & 0x00003fff)
+
+/* macros for BB_search_start_delay */
+#define PHY_BB_SEARCH_START_DELAY_ADDRESS 0x00009918
+#define PHY_BB_SEARCH_START_DELAY_OFFSET 0x00009918
+#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_MSB 11
+#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_LSB 0
+#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_MASK 0x00000fff
+#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_SET(x) (((x) << 0) & 0x00000fff)
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_MSB 12
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_LSB 12
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_MASK 0x00001000
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_MSB 13
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_LSB 13
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_MASK 0x00002000
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_SET(x) (((x) << 13) & 0x00002000)
+
+/* macros for BB_max_rx_length */
+#define PHY_BB_MAX_RX_LENGTH_ADDRESS 0x0000991c
+#define PHY_BB_MAX_RX_LENGTH_OFFSET 0x0000991c
+#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_MSB 11
+#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_LSB 0
+#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_MASK 0x00000fff
+#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_SET(x) (((x) << 0) & 0x00000fff)
+#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_MSB 29
+#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_LSB 12
+#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_MASK 0x3ffff000
+#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_GET(x) (((x) & 0x3ffff000) >> 12)
+#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_SET(x) (((x) << 12) & 0x3ffff000)
+
+/* macros for BB_timing_control_4 */
+#define PHY_BB_TIMING_CONTROL_4_ADDRESS 0x00009920
+#define PHY_BB_TIMING_CONTROL_4_OFFSET 0x00009920
+#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_MSB 15
+#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_LSB 12
+#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_MASK 0x0000f000
+#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_MSB 16
+#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_LSB 16
+#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_MASK 0x00010000
+#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_MSB 20
+#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_LSB 17
+#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_MASK 0x001e0000
+#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_GET(x) (((x) & 0x001e0000) >> 17)
+#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_SET(x) (((x) << 17) & 0x001e0000)
+#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_MSB 27
+#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_LSB 21
+#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_MASK 0x0fe00000
+#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_GET(x) (((x) & 0x0fe00000) >> 21)
+#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_SET(x) (((x) << 21) & 0x0fe00000)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_MSB 28
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_LSB 28
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_MASK 0x10000000
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_MSB 29
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_LSB 29
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_MASK 0x20000000
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_MSB 30
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_LSB 30
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_MASK 0x40000000
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_MSB 31
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_LSB 31
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_MASK 0x80000000
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_timing_control_5 */
+#define PHY_BB_TIMING_CONTROL_5_ADDRESS 0x00009924
+#define PHY_BB_TIMING_CONTROL_5_OFFSET 0x00009924
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_MSB 0
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_LSB 0
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_MASK 0x00000001
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_MSB 7
+#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_LSB 1
+#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_MASK 0x000000fe
+#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_MSB 15
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_LSB 15
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_MASK 0x00008000
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_MSB 22
+#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_LSB 16
+#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_MASK 0x007f0000
+#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_GET(x) (((x) & 0x007f0000) >> 16)
+#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_SET(x) (((x) << 16) & 0x007f0000)
+#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_MSB 29
+#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_LSB 23
+#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_MASK 0x3f800000
+#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_GET(x) (((x) & 0x3f800000) >> 23)
+#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_SET(x) (((x) << 23) & 0x3f800000)
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_MSB 30
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_LSB 30
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_MASK 0x40000000
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_MSB 31
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_LSB 31
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_MASK 0x80000000
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_phyonly_warm_reset */
+#define PHY_BB_PHYONLY_WARM_RESET_ADDRESS 0x00009928
+#define PHY_BB_PHYONLY_WARM_RESET_OFFSET 0x00009928
+#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_MSB 0
+#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_LSB 0
+#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_MASK 0x00000001
+#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_SET(x) (((x) << 0) & 0x00000001)
+
+/* macros for BB_phyonly_control */
+#define PHY_BB_PHYONLY_CONTROL_ADDRESS 0x0000992c
+#define PHY_BB_PHYONLY_CONTROL_OFFSET 0x0000992c
+#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_MSB 0
+#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_LSB 0
+#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_MASK 0x00000001
+#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_MSB 1
+#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_LSB 1
+#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_MASK 0x00000002
+#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_MSB 2
+#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_LSB 2
+#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_MASK 0x00000004
+#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_MSB 3
+#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_LSB 3
+#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_MASK 0x00000008
+#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_MSB 4
+#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_LSB 4
+#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_MASK 0x00000010
+#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_MSB 5
+#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_LSB 5
+#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_MASK 0x00000020
+#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_MSB 6
+#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_LSB 6
+#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_MASK 0x00000040
+#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_MSB 7
+#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_LSB 7
+#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_MASK 0x00000080
+#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_SET(x) (((x) << 7) & 0x00000080)
+
+/* macros for BB_powertx_rate1 */
+#define PHY_BB_POWERTX_RATE1_ADDRESS 0x00009934
+#define PHY_BB_POWERTX_RATE1_OFFSET 0x00009934
+#define PHY_BB_POWERTX_RATE1_POWERTX_0_MSB 5
+#define PHY_BB_POWERTX_RATE1_POWERTX_0_LSB 0
+#define PHY_BB_POWERTX_RATE1_POWERTX_0_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE1_POWERTX_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE1_POWERTX_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE1_POWERTX_1_MSB 13
+#define PHY_BB_POWERTX_RATE1_POWERTX_1_LSB 8
+#define PHY_BB_POWERTX_RATE1_POWERTX_1_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE1_POWERTX_1_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE1_POWERTX_1_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE1_POWERTX_2_MSB 21
+#define PHY_BB_POWERTX_RATE1_POWERTX_2_LSB 16
+#define PHY_BB_POWERTX_RATE1_POWERTX_2_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE1_POWERTX_2_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE1_POWERTX_2_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE1_POWERTX_3_MSB 29
+#define PHY_BB_POWERTX_RATE1_POWERTX_3_LSB 24
+#define PHY_BB_POWERTX_RATE1_POWERTX_3_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE1_POWERTX_3_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE1_POWERTX_3_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate2 */
+#define PHY_BB_POWERTX_RATE2_ADDRESS 0x00009938
+#define PHY_BB_POWERTX_RATE2_OFFSET 0x00009938
+#define PHY_BB_POWERTX_RATE2_POWERTX_4_MSB 5
+#define PHY_BB_POWERTX_RATE2_POWERTX_4_LSB 0
+#define PHY_BB_POWERTX_RATE2_POWERTX_4_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE2_POWERTX_4_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE2_POWERTX_4_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE2_POWERTX_5_MSB 13
+#define PHY_BB_POWERTX_RATE2_POWERTX_5_LSB 8
+#define PHY_BB_POWERTX_RATE2_POWERTX_5_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE2_POWERTX_5_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE2_POWERTX_5_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE2_POWERTX_6_MSB 21
+#define PHY_BB_POWERTX_RATE2_POWERTX_6_LSB 16
+#define PHY_BB_POWERTX_RATE2_POWERTX_6_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE2_POWERTX_6_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE2_POWERTX_6_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE2_POWERTX_7_MSB 29
+#define PHY_BB_POWERTX_RATE2_POWERTX_7_LSB 24
+#define PHY_BB_POWERTX_RATE2_POWERTX_7_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE2_POWERTX_7_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE2_POWERTX_7_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_max */
+#define PHY_BB_POWERTX_MAX_ADDRESS 0x0000993c
+#define PHY_BB_POWERTX_MAX_OFFSET 0x0000993c
+#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_MSB 6
+#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_LSB 6
+#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_MASK 0x00000040
+#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_SET(x) (((x) << 6) & 0x00000040)
+
+/* macros for BB_extension_radar */
+#define PHY_BB_EXTENSION_RADAR_ADDRESS 0x00009940
+#define PHY_BB_EXTENSION_RADAR_OFFSET 0x00009940
+#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_MSB 13
+#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_LSB 8
+#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_MASK 0x00003f00
+#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_MSB 14
+#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_LSB 14
+#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_MASK 0x00004000
+#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_MSB 22
+#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_LSB 15
+#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_MASK 0x007f8000
+#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_GET(x) (((x) & 0x007f8000) >> 15)
+#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_SET(x) (((x) << 15) & 0x007f8000)
+#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_MSB 30
+#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_LSB 23
+#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_MASK 0x7f800000
+#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_GET(x) (((x) & 0x7f800000) >> 23)
+#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_SET(x) (((x) << 23) & 0x7f800000)
+#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_MSB 31
+#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_LSB 31
+#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_MASK 0x80000000
+#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_frame_control */
+#define PHY_BB_FRAME_CONTROL_ADDRESS 0x00009944
+#define PHY_BB_FRAME_CONTROL_OFFSET 0x00009944
+#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_MSB 1
+#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_LSB 0
+#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_MASK 0x00000003
+#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_MSB 2
+#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_LSB 2
+#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_MASK 0x00000004
+#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_MSB 5
+#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_LSB 3
+#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_MASK 0x00000038
+#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_MSB 7
+#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_LSB 6
+#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_MASK 0x000000c0
+#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_MSB 15
+#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_LSB 8
+#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_MASK 0x0000ff00
+#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_MSB 16
+#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_LSB 16
+#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_MASK 0x00010000
+#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_MSB 17
+#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_LSB 17
+#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_MASK 0x00020000
+#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_MSB 18
+#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_LSB 18
+#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_MASK 0x00040000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_MSB 19
+#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_LSB 19
+#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_MASK 0x00080000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_MSB 20
+#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_LSB 20
+#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_MASK 0x00100000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_MSB 21
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_LSB 21
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_MASK 0x00200000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_MSB 22
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_LSB 22
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_MASK 0x00400000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_MSB 23
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_LSB 23
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_MASK 0x00800000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_MSB 24
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_LSB 24
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_MASK 0x01000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_MSB 25
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_LSB 25
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_MASK 0x02000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_MSB 26
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_LSB 26
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_MASK 0x04000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_MSB 27
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_LSB 27
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_MASK 0x08000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_MSB 28
+#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_LSB 28
+#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_MASK 0x10000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_MSB 29
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_LSB 29
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_MASK 0x20000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_MSB 30
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_LSB 30
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_MASK 0x40000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_MSB 31
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_LSB 31
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_MASK 0x80000000
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_timing_control_6 */
+#define PHY_BB_TIMING_CONTROL_6_ADDRESS 0x00009948
+#define PHY_BB_TIMING_CONTROL_6_OFFSET 0x00009948
+#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_MSB 7
+#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_LSB 0
+#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_MASK 0x000000ff
+#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_MSB 14
+#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_LSB 8
+#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_MASK 0x00007f00
+#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_GET(x) (((x) & 0x00007f00) >> 8)
+#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_SET(x) (((x) << 8) & 0x00007f00)
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_MSB 20
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_LSB 15
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_MASK 0x001f8000
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_GET(x) (((x) & 0x001f8000) >> 15)
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_SET(x) (((x) << 15) & 0x001f8000)
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_MSB 27
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_LSB 21
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_MASK 0x0fe00000
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_GET(x) (((x) & 0x0fe00000) >> 21)
+#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_SET(x) (((x) << 21) & 0x0fe00000)
+#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_MSB 31
+#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_LSB 28
+#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_MASK 0xf0000000
+#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_GET(x) (((x) & 0xf0000000) >> 28)
+#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_SET(x) (((x) << 28) & 0xf0000000)
+
+/* macros for BB_spur_mask_controls */
+#define PHY_BB_SPUR_MASK_CONTROLS_ADDRESS 0x0000994c
+#define PHY_BB_SPUR_MASK_CONTROLS_OFFSET 0x0000994c
+#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_MSB 7
+#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_LSB 0
+#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_MASK 0x000000ff
+#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_MSB 8
+#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_LSB 8
+#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_MASK 0x00000100
+#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_MSB 17
+#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_LSB 17
+#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_MASK 0x00020000
+#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_MSB 25
+#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_LSB 18
+#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_MASK 0x03fc0000
+#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_GET(x) (((x) & 0x03fc0000) >> 18)
+#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_SET(x) (((x) << 18) & 0x03fc0000)
+
+/* macros for BB_rx_iq_corr_b0 */
+#define PHY_BB_RX_IQ_CORR_B0_ADDRESS 0x00009950
+#define PHY_BB_RX_IQ_CORR_B0_OFFSET 0x00009950
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_MSB 6
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_LSB 0
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_MASK 0x0000007f
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_MSB 13
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_LSB 7
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_MASK 0x00003f80
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_GET(x) (((x) & 0x00003f80) >> 7)
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_SET(x) (((x) << 7) & 0x00003f80)
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_MSB 14
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_LSB 14
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_MASK 0x00004000
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_MSB 21
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_LSB 15
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_MASK 0x003f8000
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_GET(x) (((x) & 0x003f8000) >> 15)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_SET(x) (((x) << 15) & 0x003f8000)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_MSB 28
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_LSB 22
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_MASK 0x1fc00000
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_GET(x) (((x) & 0x1fc00000) >> 22)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_SET(x) (((x) << 22) & 0x1fc00000)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_MSB 29
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_LSB 29
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_MASK 0x20000000
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_SET(x) (((x) << 29) & 0x20000000)
+
+/* macros for BB_radar_detection */
+#define PHY_BB_RADAR_DETECTION_ADDRESS 0x00009954
+#define PHY_BB_RADAR_DETECTION_OFFSET 0x00009954
+#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_MSB 0
+#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_LSB 0
+#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_MASK 0x00000001
+#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_MSB 5
+#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_LSB 1
+#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_MASK 0x0000003e
+#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_GET(x) (((x) & 0x0000003e) >> 1)
+#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_SET(x) (((x) << 1) & 0x0000003e)
+#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_MSB 11
+#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_LSB 6
+#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_MASK 0x00000fc0
+#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_MSB 17
+#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_LSB 12
+#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_MASK 0x0003f000
+#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_MSB 23
+#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_LSB 18
+#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_MASK 0x00fc0000
+#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_SET(x) (((x) << 18) & 0x00fc0000)
+#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_MSB 30
+#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_LSB 24
+#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_MASK 0x7f000000
+#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_SET(x) (((x) << 24) & 0x7f000000)
+#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_MSB 31
+#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_LSB 31
+#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_MASK 0x80000000
+#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_radar_detection_2 */
+#define PHY_BB_RADAR_DETECTION_2_ADDRESS 0x00009958
+#define PHY_BB_RADAR_DETECTION_2_OFFSET 0x00009958
+#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_MSB 7
+#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_LSB 0
+#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_MASK 0x000000ff
+#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_MSB 12
+#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_LSB 8
+#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_MASK 0x00001f00
+#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_SET(x) (((x) << 8) & 0x00001f00)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_MSB 13
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_LSB 13
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_MASK 0x00002000
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_MSB 14
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_LSB 14
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_MASK 0x00004000
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_MSB 15
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_LSB 15
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_MASK 0x00008000
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_MSB 21
+#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_LSB 16
+#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_MASK 0x003f0000
+#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_MSB 22
+#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_LSB 22
+#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_MASK 0x00400000
+#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_MSB 23
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_LSB 23
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_MASK 0x00800000
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_MSB 26
+#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_LSB 24
+#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_MASK 0x07000000
+#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_GET(x) (((x) & 0x07000000) >> 24)
+#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_SET(x) (((x) << 24) & 0x07000000)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_MSB 27
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_LSB 27
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_MASK 0x08000000
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_SET(x) (((x) << 27) & 0x08000000)
+
+/* macros for BB_tx_phase_ramp_b0 */
+#define PHY_BB_TX_PHASE_RAMP_B0_ADDRESS 0x0000995c
+#define PHY_BB_TX_PHASE_RAMP_B0_OFFSET 0x0000995c
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_MSB 0
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_LSB 0
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_MASK 0x00000001
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_MSB 6
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_LSB 1
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_MASK 0x0000007e
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_GET(x) (((x) & 0x0000007e) >> 1)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_SET(x) (((x) << 1) & 0x0000007e)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_MSB 16
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_LSB 7
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_MASK 0x0001ff80
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_GET(x) (((x) & 0x0001ff80) >> 7)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_SET(x) (((x) << 7) & 0x0001ff80)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_MSB 24
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_LSB 17
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_MASK 0x01fe0000
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_GET(x) (((x) & 0x01fe0000) >> 17)
+#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_SET(x) (((x) << 17) & 0x01fe0000)
+
+/* macros for BB_switch_table_chn_b0 */
+#define PHY_BB_SWITCH_TABLE_CHN_B0_ADDRESS 0x00009960
+#define PHY_BB_SWITCH_TABLE_CHN_B0_OFFSET 0x00009960
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_MSB 1
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_LSB 0
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_MASK 0x00000003
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_MSB 3
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_LSB 2
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_MASK 0x0000000c
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_MSB 5
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_LSB 4
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_MASK 0x00000030
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_MSB 7
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_LSB 6
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_MASK 0x000000c0
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_SET(x) (((x) << 6) & 0x000000c0)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_MSB 9
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_LSB 8
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_MASK 0x00000300
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_MSB 11
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_LSB 10
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_MASK 0x00000c00
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_GET(x) (((x) & 0x00000c00) >> 10)
+#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_SET(x) (((x) << 10) & 0x00000c00)
+
+/* macros for BB_switch_table_com1 */
+#define PHY_BB_SWITCH_TABLE_COM1_ADDRESS 0x00009964
+#define PHY_BB_SWITCH_TABLE_COM1_OFFSET 0x00009964
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_MSB 3
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_LSB 0
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_MASK 0x0000000f
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_MSB 7
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_LSB 4
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_MASK 0x000000f0
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_MSB 11
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_LSB 8
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_MASK 0x00000f00
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_MSB 15
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_LSB 12
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_MASK 0x0000f000
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_SET(x) (((x) << 12) & 0x0000f000)
+
+/* macros for BB_cca_ctrl_2_b0 */
+#define PHY_BB_CCA_CTRL_2_B0_ADDRESS 0x00009968
+#define PHY_BB_CCA_CTRL_2_B0_OFFSET 0x00009968
+#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_MSB 8
+#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_LSB 0
+#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_MASK 0x000001ff
+#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_SET(x) (((x) << 0) & 0x000001ff)
+#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_MSB 9
+#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_LSB 9
+#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_MASK 0x00000200
+#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_MSB 17
+#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_LSB 10
+#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_MASK 0x0003fc00
+#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_GET(x) (((x) & 0x0003fc00) >> 10)
+#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_SET(x) (((x) << 10) & 0x0003fc00)
+#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_MSB 18
+#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_LSB 18
+#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_MASK 0x00040000
+#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_SET(x) (((x) << 18) & 0x00040000)
+
+/* macros for BB_switch_table_com2 */
+#define PHY_BB_SWITCH_TABLE_COM2_ADDRESS 0x0000996c
+#define PHY_BB_SWITCH_TABLE_COM2_OFFSET 0x0000996c
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_MSB 3
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_LSB 0
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_MASK 0x0000000f
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_MSB 7
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_LSB 4
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_MASK 0x000000f0
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_MSB 11
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_LSB 8
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_MASK 0x00000f00
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_MSB 15
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_LSB 12
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_MASK 0x0000f000
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_MSB 19
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_LSB 16
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_MASK 0x000f0000
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_MSB 23
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_LSB 20
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_MASK 0x00f00000
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_MSB 27
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_LSB 24
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_MASK 0x0f000000
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_GET(x) (((x) & 0x0f000000) >> 24)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_SET(x) (((x) << 24) & 0x0f000000)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_MSB 31
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_LSB 28
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_MASK 0xf0000000
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_GET(x) (((x) & 0xf0000000) >> 28)
+#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_SET(x) (((x) << 28) & 0xf0000000)
+
+/* macros for BB_restart */
+#define PHY_BB_RESTART_ADDRESS 0x00009970
+#define PHY_BB_RESTART_OFFSET 0x00009970
+#define PHY_BB_RESTART_ENABLE_RESTART_MSB 0
+#define PHY_BB_RESTART_ENABLE_RESTART_LSB 0
+#define PHY_BB_RESTART_ENABLE_RESTART_MASK 0x00000001
+#define PHY_BB_RESTART_ENABLE_RESTART_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_RESTART_ENABLE_RESTART_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_MSB 5
+#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_LSB 1
+#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_MASK 0x0000003e
+#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_GET(x) (((x) & 0x0000003e) >> 1)
+#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_SET(x) (((x) << 1) & 0x0000003e)
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_MSB 6
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_LSB 6
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_MASK 0x00000040
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_MSB 11
+#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_LSB 7
+#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_MASK 0x00000f80
+#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_GET(x) (((x) & 0x00000f80) >> 7)
+#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_SET(x) (((x) << 7) & 0x00000f80)
+#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_MSB 17
+#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_LSB 12
+#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_MASK 0x0003f000
+#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_MSB 20
+#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_LSB 18
+#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_MASK 0x001c0000
+#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_GET(x) (((x) & 0x001c0000) >> 18)
+#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_SET(x) (((x) << 18) & 0x001c0000)
+#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_MSB 21
+#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_LSB 21
+#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_MASK 0x00200000
+#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_MSB 28
+#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_LSB 22
+#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_MASK 0x1fc00000
+#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_GET(x) (((x) & 0x1fc00000) >> 22)
+#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_SET(x) (((x) << 22) & 0x1fc00000)
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_MSB 29
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_LSB 29
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_MASK 0x20000000
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_RESTART_DISABLE_DC_RESTART_MSB 30
+#define PHY_BB_RESTART_DISABLE_DC_RESTART_LSB 30
+#define PHY_BB_RESTART_DISABLE_DC_RESTART_MASK 0x40000000
+#define PHY_BB_RESTART_DISABLE_DC_RESTART_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_RESTART_DISABLE_DC_RESTART_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_RESTART_RESTART_MODE_BW40_MSB 31
+#define PHY_BB_RESTART_RESTART_MODE_BW40_LSB 31
+#define PHY_BB_RESTART_RESTART_MODE_BW40_MASK 0x80000000
+#define PHY_BB_RESTART_RESTART_MODE_BW40_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_RESTART_RESTART_MODE_BW40_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_scrambler_seed */
+#define PHY_BB_SCRAMBLER_SEED_ADDRESS 0x00009978
+#define PHY_BB_SCRAMBLER_SEED_OFFSET 0x00009978
+#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_MSB 6
+#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_LSB 0
+#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_MASK 0x0000007f
+#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_SET(x) (((x) << 0) & 0x0000007f)
+
+/* macros for BB_rfbus_request */
+#define PHY_BB_RFBUS_REQUEST_ADDRESS 0x0000997c
+#define PHY_BB_RFBUS_REQUEST_OFFSET 0x0000997c
+#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_MSB 0
+#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_LSB 0
+#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_MASK 0x00000001
+#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_SET(x) (((x) << 0) & 0x00000001)
+
+/* macros for BB_timing_control_11 */
+#define PHY_BB_TIMING_CONTROL_11_ADDRESS 0x000099a0
+#define PHY_BB_TIMING_CONTROL_11_OFFSET 0x000099a0
+#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_MSB 19
+#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_LSB 0
+#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_MASK 0x000fffff
+#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_GET(x) (((x) & 0x000fffff) >> 0)
+#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_SET(x) (((x) << 0) & 0x000fffff)
+#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_MSB 29
+#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_LSB 20
+#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_MASK 0x3ff00000
+#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_GET(x) (((x) & 0x3ff00000) >> 20)
+#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_SET(x) (((x) << 20) & 0x3ff00000)
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_MSB 30
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_LSB 30
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_MASK 0x40000000
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_MSB 31
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_LSB 31
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_MASK 0x80000000
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_multichain_enable */
+#define PHY_BB_MULTICHAIN_ENABLE_ADDRESS 0x000099a4
+#define PHY_BB_MULTICHAIN_ENABLE_OFFSET 0x000099a4
+#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_MSB 2
+#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_LSB 0
+#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK 0x00000007
+#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_SET(x) (((x) << 0) & 0x00000007)
+
+/* macros for BB_multichain_control */
+#define PHY_BB_MULTICHAIN_CONTROL_ADDRESS 0x000099a8
+#define PHY_BB_MULTICHAIN_CONTROL_OFFSET 0x000099a8
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_MSB 0
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_LSB 0
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_MASK 0x00000001
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_MSB 7
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_LSB 1
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_MASK 0x000000fe
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_MSB 8
+#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_LSB 8
+#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_MASK 0x00000100
+#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_MSB 9
+#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_LSB 9
+#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_MASK 0x00000200
+#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_MSB 20
+#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_LSB 10
+#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_MASK 0x001ffc00
+#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_GET(x) (((x) & 0x001ffc00) >> 10)
+#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_SET(x) (((x) << 10) & 0x001ffc00)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_MSB 28
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_LSB 22
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_MASK 0x1fc00000
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_GET(x) (((x) & 0x1fc00000) >> 22)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_SET(x) (((x) << 22) & 0x1fc00000)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_MSB 29
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_LSB 29
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_MASK 0x20000000
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_SET(x) (((x) << 29) & 0x20000000)
+
+/* macros for BB_multichain_gain_ctrl */
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ADDRESS 0x000099ac
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_OFFSET 0x000099ac
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_MSB 7
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_LSB 0
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_MASK 0x000000ff
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_MSB 8
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_LSB 8
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_MASK 0x00000100
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_MSB 14
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_LSB 9
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_MASK 0x00007e00
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_GET(x) (((x) & 0x00007e00) >> 9)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_SET(x) (((x) << 9) & 0x00007e00)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_MSB 20
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_LSB 15
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_MASK 0x001f8000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_GET(x) (((x) & 0x001f8000) >> 15)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_SET(x) (((x) << 15) & 0x001f8000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_MSB 21
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_LSB 21
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_MASK 0x00200000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_MSB 22
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_LSB 22
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_MASK 0x00400000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_MSB 23
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_LSB 23
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_MASK 0x00800000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_SET(x) (((x) << 23) & 0x00800000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_MSB 24
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_LSB 24
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_MASK 0x01000000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_MSB 26
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_LSB 25
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_MASK 0x06000000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_GET(x) (((x) & 0x06000000) >> 25)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_SET(x) (((x) << 25) & 0x06000000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_MSB 28
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_LSB 27
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_MASK 0x18000000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_GET(x) (((x) & 0x18000000) >> 27)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_SET(x) (((x) << 27) & 0x18000000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_MSB 29
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_LSB 29
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_MASK 0x20000000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_MSB 30
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_LSB 30
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_MASK 0x40000000
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_SET(x) (((x) << 30) & 0x40000000)
+
+/* macros for BB_adc_gain_dc_corr_b0 */
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADDRESS 0x000099b4
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_OFFSET 0x000099b4
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_MSB 5
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_LSB 0
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_MASK 0x0000003f
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_MSB 11
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_LSB 6
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_MASK 0x00000fc0
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_MSB 20
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_LSB 12
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_MASK 0x001ff000
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_GET(x) (((x) & 0x001ff000) >> 12)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_SET(x) (((x) << 12) & 0x001ff000)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_MSB 29
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_LSB 21
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_MASK 0x3fe00000
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_GET(x) (((x) & 0x3fe00000) >> 21)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_SET(x) (((x) << 21) & 0x3fe00000)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_MSB 30
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_LSB 30
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_MASK 0x40000000
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_MSB 31
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_LSB 31
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_MASK 0x80000000
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_ext_chan_pwr_thr_1 */
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ADDRESS 0x000099b8
+#define PHY_BB_EXT_CHAN_PWR_THR_1_OFFSET 0x000099b8
+#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_MSB 7
+#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_LSB 0
+#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_MASK 0x000000ff
+#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_MSB 15
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_LSB 8
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_MASK 0x0000ff00
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_MSB 20
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_LSB 16
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_MASK 0x001f0000
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_MSB 26
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_LSB 21
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_MASK 0x07e00000
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_GET(x) (((x) & 0x07e00000) >> 21)
+#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_SET(x) (((x) << 21) & 0x07e00000)
+
+/* macros for BB_ext_chan_pwr_thr_2_b0 */
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_ADDRESS 0x000099bc
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_OFFSET 0x000099bc
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_MSB 8
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_LSB 0
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_MASK 0x000001ff
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_SET(x) (((x) << 0) & 0x000001ff)
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_MSB 15
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_LSB 9
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_MASK 0x0000fe00
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_GET(x) (((x) & 0x0000fe00) >> 9)
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_SET(x) (((x) << 9) & 0x0000fe00)
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_MSB 24
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_LSB 16
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_MASK 0x01ff0000
+#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_GET(x) (((x) & 0x01ff0000) >> 16)
+
+/* macros for BB_ext_chan_scorr_thr */
+#define PHY_BB_EXT_CHAN_SCORR_THR_ADDRESS 0x000099c0
+#define PHY_BB_EXT_CHAN_SCORR_THR_OFFSET 0x000099c0
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_MSB 6
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_LSB 0
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_MASK 0x0000007f
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_GET(x) (((x) & 0x0000007f) >> 0)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_SET(x) (((x) << 0) & 0x0000007f)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_MSB 13
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_LSB 7
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_MASK 0x00003f80
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_GET(x) (((x) & 0x00003f80) >> 7)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_SET(x) (((x) << 7) & 0x00003f80)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_MSB 20
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_LSB 14
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_MASK 0x001fc000
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_GET(x) (((x) & 0x001fc000) >> 14)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_SET(x) (((x) << 14) & 0x001fc000)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_MSB 27
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_LSB 21
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_MASK 0x0fe00000
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_GET(x) (((x) & 0x0fe00000) >> 21)
+#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_SET(x) (((x) << 21) & 0x0fe00000)
+#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_MSB 28
+#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_LSB 28
+#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_MASK 0x10000000
+#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_SET(x) (((x) << 28) & 0x10000000)
+
+/* macros for BB_ext_chan_detect_win */
+#define PHY_BB_EXT_CHAN_DETECT_WIN_ADDRESS 0x000099c4
+#define PHY_BB_EXT_CHAN_DETECT_WIN_OFFSET 0x000099c4
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_MSB 3
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LSB 0
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_MASK 0x0000000f
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_MSB 7
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_LSB 4
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_MASK 0x000000f0
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_MSB 12
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_LSB 8
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_MASK 0x00001f00
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_SET(x) (((x) << 8) & 0x00001f00)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_MSB 15
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_LSB 13
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_MASK 0x0000e000
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_GET(x) (((x) & 0x0000e000) >> 13)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_SET(x) (((x) << 13) & 0x0000e000)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_MSB 18
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_LSB 16
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_MASK 0x00070000
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_MSB 24
+#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_LSB 19
+#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_MASK 0x01f80000
+#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_GET(x) (((x) & 0x01f80000) >> 19)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_SET(x) (((x) << 19) & 0x01f80000)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_MSB 28
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_LSB 25
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_MASK 0x1e000000
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_GET(x) (((x) & 0x1e000000) >> 25)
+#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_SET(x) (((x) << 25) & 0x1e000000)
+
+/* macros for BB_pwr_thr_20_40_det */
+#define PHY_BB_PWR_THR_20_40_DET_ADDRESS 0x000099c8
+#define PHY_BB_PWR_THR_20_40_DET_OFFSET 0x000099c8
+#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_MSB 4
+#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_LSB 0
+#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_MASK 0x0000001f
+#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_MSB 10
+#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_LSB 5
+#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_MASK 0x000007e0
+#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_GET(x) (((x) & 0x000007e0) >> 5)
+#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_SET(x) (((x) << 5) & 0x000007e0)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_MSB 15
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_LSB 11
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_MASK 0x0000f800
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_GET(x) (((x) & 0x0000f800) >> 11)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_SET(x) (((x) << 11) & 0x0000f800)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_MSB 23
+#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_LSB 16
+#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_MASK 0x00ff0000
+#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_MSB 28
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_LSB 24
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_MASK 0x1f000000
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_SET(x) (((x) << 24) & 0x1f000000)
+#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_MSB 29
+#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_LSB 29
+#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_MASK 0x20000000
+#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_MSB 30
+#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_LSB 30
+#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_MASK 0x40000000
+#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_SET(x) (((x) << 30) & 0x40000000)
+
+/* macros for BB_short_gi_delta_slope */
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_ADDRESS 0x000099d0
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_OFFSET 0x000099d0
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_MSB 3
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_LSB 0
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_MASK 0x0000000f
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_MSB 18
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_LSB 4
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_MASK 0x0007fff0
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_GET(x) (((x) & 0x0007fff0) >> 4)
+#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_SET(x) (((x) << 4) & 0x0007fff0)
+
+/* macros for BB_chaninfo_ctrl */
+#define PHY_BB_CHANINFO_CTRL_ADDRESS 0x000099dc
+#define PHY_BB_CHANINFO_CTRL_OFFSET 0x000099dc
+#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_MSB 0
+#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_LSB 0
+#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK 0x00000001
+#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_MSB 1
+#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_LSB 1
+#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_MASK 0x00000002
+#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_SET(x) (((x) << 1) & 0x00000002)
+
+/* macros for BB_heavy_clip_ctrl */
+#define PHY_BB_HEAVY_CLIP_CTRL_ADDRESS 0x000099e0
+#define PHY_BB_HEAVY_CLIP_CTRL_OFFSET 0x000099e0
+#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_MSB 8
+#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_LSB 0
+#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_MASK 0x000001ff
+#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_SET(x) (((x) << 0) & 0x000001ff)
+#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_MSB 9
+#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_LSB 9
+#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_MASK 0x00000200
+#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_SET(x) (((x) << 9) & 0x00000200)
+
+/* macros for BB_heavy_clip_20 */
+#define PHY_BB_HEAVY_CLIP_20_ADDRESS 0x000099e4
+#define PHY_BB_HEAVY_CLIP_20_OFFSET 0x000099e4
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_MSB 7
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_LSB 0
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_MASK 0x000000ff
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_MSB 15
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_LSB 8
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_MASK 0x0000ff00
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_MSB 23
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_LSB 16
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_MASK 0x00ff0000
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_MSB 31
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_LSB 24
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_MASK 0xff000000
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_heavy_clip_40 */
+#define PHY_BB_HEAVY_CLIP_40_ADDRESS 0x000099e8
+#define PHY_BB_HEAVY_CLIP_40_OFFSET 0x000099e8
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_MSB 7
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_LSB 0
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_MASK 0x000000ff
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_MSB 15
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_LSB 8
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_MASK 0x0000ff00
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_MSB 23
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_LSB 16
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_MASK 0x00ff0000
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_MSB 31
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_LSB 24
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_MASK 0xff000000
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_rifs_srch */
+#define PHY_BB_RIFS_SRCH_ADDRESS 0x000099ec
+#define PHY_BB_RIFS_SRCH_OFFSET 0x000099ec
+#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_MSB 7
+#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_LSB 0
+#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_MASK 0x000000ff
+#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_MSB 15
+#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_LSB 8
+#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_MASK 0x0000ff00
+#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_MSB 25
+#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_LSB 16
+#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_MASK 0x03ff0000
+#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_SET(x) (((x) << 16) & 0x03ff0000)
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_MSB 26
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_LSB 26
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_MASK 0x04000000
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_MSB 27
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_LSB 27
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_MASK 0x08000000
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_SET(x) (((x) << 27) & 0x08000000)
+
+/* macros for BB_iq_adc_cal_mode */
+#define PHY_BB_IQ_ADC_CAL_MODE_ADDRESS 0x000099f0
+#define PHY_BB_IQ_ADC_CAL_MODE_OFFSET 0x000099f0
+#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_MSB 1
+#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_LSB 0
+#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_MASK 0x00000003
+#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_GET(x) (((x) & 0x00000003) >> 0)
+#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_SET(x) (((x) << 0) & 0x00000003)
+#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_MSB 2
+#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_LSB 2
+#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_MASK 0x00000004
+#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_SET(x) (((x) << 2) & 0x00000004)
+
+/* macros for BB_per_chain_csd */
+#define PHY_BB_PER_CHAIN_CSD_ADDRESS 0x000099fc
+#define PHY_BB_PER_CHAIN_CSD_OFFSET 0x000099fc
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_MSB 4
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_LSB 0
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_MASK 0x0000001f
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_MSB 9
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_LSB 5
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_MASK 0x000003e0
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_MSB 14
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_LSB 10
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_MASK 0x00007c00
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_SET(x) (((x) << 10) & 0x00007c00)
+
+/* macros for BB_rx_ocgain */
+#define PHY_BB_RX_OCGAIN_ADDRESS 0x00009a00
+#define PHY_BB_RX_OCGAIN_OFFSET 0x00009a00
+#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_MSB 31
+#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_LSB 0
+#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_MASK 0xffffffff
+#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_crc */
+#define PHY_BB_TX_CRC_ADDRESS 0x00009c00
+#define PHY_BB_TX_CRC_OFFSET 0x00009c00
+#define PHY_BB_TX_CRC_TX_CRC_MSB 15
+#define PHY_BB_TX_CRC_TX_CRC_LSB 0
+#define PHY_BB_TX_CRC_TX_CRC_MASK 0x0000ffff
+#define PHY_BB_TX_CRC_TX_CRC_GET(x) (((x) & 0x0000ffff) >> 0)
+
+/* macros for BB_iq_adc_meas_0_b0 */
+#define PHY_BB_IQ_ADC_MEAS_0_B0_ADDRESS 0x00009c10
+#define PHY_BB_IQ_ADC_MEAS_0_B0_OFFSET 0x00009c10
+#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_MSB 31
+#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_LSB 0
+#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_MASK 0xffffffff
+#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_GET(x) (((x) & 0xffffffff) >> 0)
+
+/* macros for BB_iq_adc_meas_1_b0 */
+#define PHY_BB_IQ_ADC_MEAS_1_B0_ADDRESS 0x00009c14
+#define PHY_BB_IQ_ADC_MEAS_1_B0_OFFSET 0x00009c14
+#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_MSB 31
+#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_LSB 0
+#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_MASK 0xffffffff
+#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_GET(x) (((x) & 0xffffffff) >> 0)
+
+/* macros for BB_iq_adc_meas_2_b0 */
+#define PHY_BB_IQ_ADC_MEAS_2_B0_ADDRESS 0x00009c18
+#define PHY_BB_IQ_ADC_MEAS_2_B0_OFFSET 0x00009c18
+#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_MSB 31
+#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_LSB 0
+#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_MASK 0xffffffff
+#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_GET(x) (((x) & 0xffffffff) >> 0)
+
+/* macros for BB_iq_adc_meas_3_b0 */
+#define PHY_BB_IQ_ADC_MEAS_3_B0_ADDRESS 0x00009c1c
+#define PHY_BB_IQ_ADC_MEAS_3_B0_OFFSET 0x00009c1c
+#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_MSB 31
+#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_LSB 0
+#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_MASK 0xffffffff
+#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_GET(x) (((x) & 0xffffffff) >> 0)
+
+/* macros for BB_rfbus_grant */
+#define PHY_BB_RFBUS_GRANT_ADDRESS 0x00009c20
+#define PHY_BB_RFBUS_GRANT_OFFSET 0x00009c20
+#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_MSB 0
+#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_LSB 0
+#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_MASK 0x00000001
+#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_RFBUS_GRANT_BT_ANT_MSB 1
+#define PHY_BB_RFBUS_GRANT_BT_ANT_LSB 1
+#define PHY_BB_RFBUS_GRANT_BT_ANT_MASK 0x00000002
+#define PHY_BB_RFBUS_GRANT_BT_ANT_GET(x) (((x) & 0x00000002) >> 1)
+
+/* macros for BB_tstadc */
+#define PHY_BB_TSTADC_ADDRESS 0x00009c24
+#define PHY_BB_TSTADC_OFFSET 0x00009c24
+#define PHY_BB_TSTADC_TSTADC_OUT_Q_MSB 9
+#define PHY_BB_TSTADC_TSTADC_OUT_Q_LSB 0
+#define PHY_BB_TSTADC_TSTADC_OUT_Q_MASK 0x000003ff
+#define PHY_BB_TSTADC_TSTADC_OUT_Q_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_TSTADC_TSTADC_OUT_I_MSB 19
+#define PHY_BB_TSTADC_TSTADC_OUT_I_LSB 10
+#define PHY_BB_TSTADC_TSTADC_OUT_I_MASK 0x000ffc00
+#define PHY_BB_TSTADC_TSTADC_OUT_I_GET(x) (((x) & 0x000ffc00) >> 10)
+
+/* macros for BB_tstdac */
+#define PHY_BB_TSTDAC_ADDRESS 0x00009c28
+#define PHY_BB_TSTDAC_OFFSET 0x00009c28
+#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_MSB 9
+#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_LSB 0
+#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_MASK 0x000003ff
+#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_TSTDAC_TSTDAC_OUT_I_MSB 19
+#define PHY_BB_TSTDAC_TSTDAC_OUT_I_LSB 10
+#define PHY_BB_TSTDAC_TSTDAC_OUT_I_MASK 0x000ffc00
+#define PHY_BB_TSTDAC_TSTDAC_OUT_I_GET(x) (((x) & 0x000ffc00) >> 10)
+
+/* macros for BB_illegal_tx_rate */
+#define PHY_BB_ILLEGAL_TX_RATE_ADDRESS 0x00009c30
+#define PHY_BB_ILLEGAL_TX_RATE_OFFSET 0x00009c30
+#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_MSB 0
+#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_LSB 0
+#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_MASK 0x00000001
+#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_GET(x) (((x) & 0x00000001) >> 0)
+
+/* macros for BB_spur_report_b0 */
+#define PHY_BB_SPUR_REPORT_B0_ADDRESS 0x00009c34
+#define PHY_BB_SPUR_REPORT_B0_OFFSET 0x00009c34
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_MSB 7
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_LSB 0
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_MASK 0x000000ff
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_MSB 15
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_LSB 8
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_MASK 0x0000ff00
+#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_MSB 31
+#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_LSB 16
+#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_MASK 0xffff0000
+#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_GET(x) (((x) & 0xffff0000) >> 16)
+
+/* macros for BB_channel_status */
+#define PHY_BB_CHANNEL_STATUS_ADDRESS 0x00009c38
+#define PHY_BB_CHANNEL_STATUS_OFFSET 0x00009c38
+#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_MSB 0
+#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_LSB 0
+#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_MASK 0x00000001
+#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_MSB 1
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_LSB 1
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_MASK 0x00000002
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_MSB 2
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_LSB 2
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_MASK 0x00000004
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_MSB 3
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_LSB 3
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_MASK 0x00000008
+#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_MSB 5
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_LSB 4
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_MASK 0x00000030
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_MSB 7
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_LSB 6
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_MASK 0x000000c0
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_GET(x) (((x) & 0x000000c0) >> 6)
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_MSB 9
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_LSB 8
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_MASK 0x00000300
+#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_MSB 13
+#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_LSB 10
+#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_MASK 0x00003c00
+#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_MSB 16
+#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_LSB 14
+#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_MASK 0x0001c000
+#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_GET(x) (((x) & 0x0001c000) >> 14)
+
+/* macros for BB_rssi_b0 */
+#define PHY_BB_RSSI_B0_ADDRESS 0x00009c3c
+#define PHY_BB_RSSI_B0_OFFSET 0x00009c3c
+#define PHY_BB_RSSI_B0_RSSI_0_MSB 7
+#define PHY_BB_RSSI_B0_RSSI_0_LSB 0
+#define PHY_BB_RSSI_B0_RSSI_0_MASK 0x000000ff
+#define PHY_BB_RSSI_B0_RSSI_0_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_RSSI_B0_RSSI_EXT_0_MSB 15
+#define PHY_BB_RSSI_B0_RSSI_EXT_0_LSB 8
+#define PHY_BB_RSSI_B0_RSSI_EXT_0_MASK 0x0000ff00
+#define PHY_BB_RSSI_B0_RSSI_EXT_0_GET(x) (((x) & 0x0000ff00) >> 8)
+
+/* macros for BB_spur_est_cck_report_b0 */
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_ADDRESS 0x00009c40
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_OFFSET 0x00009c40
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_MSB 7
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_LSB 0
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_MASK 0x000000ff
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_MSB 15
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_LSB 8
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_MASK 0x0000ff00
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_MSB 23
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_LSB 16
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_MASK 0x00ff0000
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_MSB 31
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_LSB 24
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_MASK 0xff000000
+#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_GET(x) (((x) & 0xff000000) >> 24)
+
+/* macros for BB_chan_info_noise_pwr */
+#define PHY_BB_CHAN_INFO_NOISE_PWR_ADDRESS 0x00009cac
+#define PHY_BB_CHAN_INFO_NOISE_PWR_OFFSET 0x00009cac
+#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_MSB 11
+#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_LSB 0
+#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_MASK 0x00000fff
+#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_GET(x) (((x) & 0x00000fff) >> 0)
+
+/* macros for BB_chan_info_gain_diff */
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_ADDRESS 0x00009cb0
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_OFFSET 0x00009cb0
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_MSB 11
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_LSB 0
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_MASK 0x00000fff
+#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_GET(x) (((x) & 0x00000fff) >> 0)
+
+/* macros for BB_chan_info_fine_timing */
+#define PHY_BB_CHAN_INFO_FINE_TIMING_ADDRESS 0x00009cb4
+#define PHY_BB_CHAN_INFO_FINE_TIMING_OFFSET 0x00009cb4
+#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_MSB 11
+#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_LSB 0
+#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_MASK 0x00000fff
+#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_MSB 21
+#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_LSB 12
+#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_MASK 0x003ff000
+#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_GET(x) (((x) & 0x003ff000) >> 12)
+
+/* macros for BB_chan_info_gain_b0 */
+#define PHY_BB_CHAN_INFO_GAIN_B0_ADDRESS 0x00009cb8
+#define PHY_BB_CHAN_INFO_GAIN_B0_OFFSET 0x00009cb8
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_MSB 7
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_LSB 0
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_MASK 0x000000ff
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_MSB 15
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_LSB 8
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_MASK 0x0000ff00
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_MSB 16
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_LSB 16
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_MASK 0x00010000
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_MSB 17
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_LSB 17
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_MASK 0x00020000
+#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_GET(x) (((x) & 0x00020000) >> 17)
+
+/* macros for BB_chan_info_chan_tab_b0 */
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_ADDRESS 0x00009cbc
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_OFFSET 0x00009cbc
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_MSB 5
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_LSB 0
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_MASK 0x0000003f
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_MSB 11
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_LSB 6
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_MASK 0x00000fc0
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_MSB 15
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_LSB 12
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_MASK 0x0000f000
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_MSB 21
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_LSB 16
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_MASK 0x003f0000
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_MSB 27
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_LSB 22
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_MASK 0x0fc00000
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_GET(x) (((x) & 0x0fc00000) >> 22)
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_MSB 31
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_LSB 28
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_MASK 0xf0000000
+#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_GET(x) (((x) & 0xf0000000) >> 28)
+
+/* macros for BB_paprd_am2am_mask */
+#define PHY_BB_PAPRD_AM2AM_MASK_ADDRESS 0x00009de4
+#define PHY_BB_PAPRD_AM2AM_MASK_OFFSET 0x00009de4
+#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_MSB 24
+#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_LSB 0
+#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_MASK 0x01ffffff
+#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_GET(x) (((x) & 0x01ffffff) >> 0)
+#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_SET(x) (((x) << 0) & 0x01ffffff)
+
+/* macros for BB_paprd_am2pm_mask */
+#define PHY_BB_PAPRD_AM2PM_MASK_ADDRESS 0x00009de8
+#define PHY_BB_PAPRD_AM2PM_MASK_OFFSET 0x00009de8
+#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_MSB 24
+#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_LSB 0
+#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_MASK 0x01ffffff
+#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_GET(x) (((x) & 0x01ffffff) >> 0)
+#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_SET(x) (((x) << 0) & 0x01ffffff)
+
+/* macros for BB_paprd_ht40_mask */
+#define PHY_BB_PAPRD_HT40_MASK_ADDRESS 0x00009dec
+#define PHY_BB_PAPRD_HT40_MASK_OFFSET 0x00009dec
+#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_MSB 24
+#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_LSB 0
+#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_MASK 0x01ffffff
+#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_GET(x) (((x) & 0x01ffffff) >> 0)
+#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_SET(x) (((x) << 0) & 0x01ffffff)
+
+/* macros for BB_paprd_ctrl0 */
+#define PHY_BB_PAPRD_CTRL0_ADDRESS 0x00009df0
+#define PHY_BB_PAPRD_CTRL0_OFFSET 0x00009df0
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_MSB 0
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_LSB 0
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_MASK 0x00000001
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_MSB 1
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_LSB 1
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_MASK 0x00000002
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_MSB 26
+#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_LSB 2
+#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_MASK 0x07fffffc
+#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_GET(x) (((x) & 0x07fffffc) >> 2)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_SET(x) (((x) << 2) & 0x07fffffc)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_MSB 31
+#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_LSB 27
+#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_MASK 0xf8000000
+#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_GET(x) (((x) & 0xf8000000) >> 27)
+#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_SET(x) (((x) << 27) & 0xf8000000)
+
+/* macros for BB_paprd_ctrl1 */
+#define PHY_BB_PAPRD_CTRL1_ADDRESS 0x00009df4
+#define PHY_BB_PAPRD_CTRL1_OFFSET 0x00009df4
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_MSB 0
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_LSB 0
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_MASK 0x00000001
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_MSB 1
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_LSB 1
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_MASK 0x00000002
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_MSB 2
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_LSB 2
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_MASK 0x00000004
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_MSB 8
+#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_LSB 3
+#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_MASK 0x000001f8
+#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_GET(x) (((x) & 0x000001f8) >> 3)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_SET(x) (((x) << 3) & 0x000001f8)
+#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_MSB 16
+#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_LSB 9
+#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_MASK 0x0001fe00
+#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_GET(x) (((x) & 0x0001fe00) >> 9)
+#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_SET(x) (((x) << 9) & 0x0001fe00)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_MSB 26
+#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_LSB 17
+#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_MASK 0x07fe0000
+#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_GET(x) (((x) & 0x07fe0000) >> 17)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_SET(x) (((x) << 17) & 0x07fe0000)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_MSB 27
+#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_LSB 27
+#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_MASK 0x08000000
+#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_SET(x) (((x) << 27) & 0x08000000)
+
+/* macros for BB_pa_gain123 */
+#define PHY_BB_PA_GAIN123_ADDRESS 0x00009df8
+#define PHY_BB_PA_GAIN123_OFFSET 0x00009df8
+#define PHY_BB_PA_GAIN123_PA_GAIN1_MSB 9
+#define PHY_BB_PA_GAIN123_PA_GAIN1_LSB 0
+#define PHY_BB_PA_GAIN123_PA_GAIN1_MASK 0x000003ff
+#define PHY_BB_PA_GAIN123_PA_GAIN1_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_PA_GAIN123_PA_GAIN1_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_PA_GAIN123_PA_GAIN2_MSB 19
+#define PHY_BB_PA_GAIN123_PA_GAIN2_LSB 10
+#define PHY_BB_PA_GAIN123_PA_GAIN2_MASK 0x000ffc00
+#define PHY_BB_PA_GAIN123_PA_GAIN2_GET(x) (((x) & 0x000ffc00) >> 10)
+#define PHY_BB_PA_GAIN123_PA_GAIN2_SET(x) (((x) << 10) & 0x000ffc00)
+#define PHY_BB_PA_GAIN123_PA_GAIN3_MSB 29
+#define PHY_BB_PA_GAIN123_PA_GAIN3_LSB 20
+#define PHY_BB_PA_GAIN123_PA_GAIN3_MASK 0x3ff00000
+#define PHY_BB_PA_GAIN123_PA_GAIN3_GET(x) (((x) & 0x3ff00000) >> 20)
+#define PHY_BB_PA_GAIN123_PA_GAIN3_SET(x) (((x) << 20) & 0x3ff00000)
+
+/* macros for BB_pa_gain45 */
+#define PHY_BB_PA_GAIN45_ADDRESS 0x00009dfc
+#define PHY_BB_PA_GAIN45_OFFSET 0x00009dfc
+#define PHY_BB_PA_GAIN45_PA_GAIN4_MSB 9
+#define PHY_BB_PA_GAIN45_PA_GAIN4_LSB 0
+#define PHY_BB_PA_GAIN45_PA_GAIN4_MASK 0x000003ff
+#define PHY_BB_PA_GAIN45_PA_GAIN4_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_PA_GAIN45_PA_GAIN4_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_PA_GAIN45_PA_GAIN5_MSB 19
+#define PHY_BB_PA_GAIN45_PA_GAIN5_LSB 10
+#define PHY_BB_PA_GAIN45_PA_GAIN5_MASK 0x000ffc00
+#define PHY_BB_PA_GAIN45_PA_GAIN5_GET(x) (((x) & 0x000ffc00) >> 10)
+#define PHY_BB_PA_GAIN45_PA_GAIN5_SET(x) (((x) << 10) & 0x000ffc00)
+#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_MSB 24
+#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_LSB 20
+#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_MASK 0x01f00000
+#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_SET(x) (((x) << 20) & 0x01f00000)
+
+/* macros for BB_paprd_pre_post_scale_0 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_ADDRESS 0x00009e00
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_OFFSET 0x00009e00
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_1 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_ADDRESS 0x00009e04
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_OFFSET 0x00009e04
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_2 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_ADDRESS 0x00009e08
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_OFFSET 0x00009e08
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_3 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_ADDRESS 0x00009e0c
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_OFFSET 0x00009e0c
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_4 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_ADDRESS 0x00009e10
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_OFFSET 0x00009e10
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_5 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_ADDRESS 0x00009e14
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_OFFSET 0x00009e14
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_6 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_ADDRESS 0x00009e18
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_OFFSET 0x00009e18
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_pre_post_scale_7 */
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_ADDRESS 0x00009e1c
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_OFFSET 0x00009e1c
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_MSB 17
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_LSB 0
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_MASK 0x0003ffff
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_GET(x) (((x) & 0x0003ffff) >> 0)
+#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_SET(x) (((x) << 0) & 0x0003ffff)
+
+/* macros for BB_paprd_mem_tab */
+#define PHY_BB_PAPRD_MEM_TAB_ADDRESS 0x00009e20
+#define PHY_BB_PAPRD_MEM_TAB_OFFSET 0x00009e20
+#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_MSB 21
+#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_LSB 0
+#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_MASK 0x003fffff
+#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_GET(x) (((x) & 0x003fffff) >> 0)
+#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_SET(x) (((x) << 0) & 0x003fffff)
+
+/* macros for BB_peak_det_ctrl_1 */
+#define PHY_BB_PEAK_DET_CTRL_1_ADDRESS 0x0000a000
+#define PHY_BB_PEAK_DET_CTRL_1_OFFSET 0x0000a000
+#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_MSB 0
+#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_LSB 0
+#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_MASK 0x00000001
+#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_MSB 1
+#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_LSB 1
+#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_MASK 0x00000002
+#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_MSB 7
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_LSB 2
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_MASK 0x000000fc
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_GET(x) (((x) & 0x000000fc) >> 2)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_SET(x) (((x) << 2) & 0x000000fc)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_MSB 12
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_LSB 8
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_MASK 0x00001f00
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_GET(x) (((x) & 0x00001f00) >> 8)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_SET(x) (((x) << 8) & 0x00001f00)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_MSB 17
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_LSB 13
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_MASK 0x0003e000
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_GET(x) (((x) & 0x0003e000) >> 13)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_SET(x) (((x) << 13) & 0x0003e000)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_MSB 22
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_LSB 18
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_MASK 0x007c0000
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_GET(x) (((x) & 0x007c0000) >> 18)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_SET(x) (((x) << 18) & 0x007c0000)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_MSB 29
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_LSB 23
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_MASK 0x3f800000
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_GET(x) (((x) & 0x3f800000) >> 23)
+#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_SET(x) (((x) << 23) & 0x3f800000)
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_MSB 30
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_LSB 30
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_MASK 0x40000000
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_MSB 31
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_LSB 31
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_MASK 0x80000000
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_peak_det_ctrl_2 */
+#define PHY_BB_PEAK_DET_CTRL_2_ADDRESS 0x0000a004
+#define PHY_BB_PEAK_DET_CTRL_2_OFFSET 0x0000a004
+#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_MSB 9
+#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_LSB 0
+#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_MASK 0x000003ff
+#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_MSB 14
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_LSB 10
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_MASK 0x00007c00
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_MSB 19
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_LSB 15
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_MASK 0x000f8000
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_MSB 24
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_LSB 20
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_MASK 0x01f00000
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_MSB 29
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_LSB 25
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_MASK 0x3e000000
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_rx_gain_bounds_1 */
+#define PHY_BB_RX_GAIN_BOUNDS_1_ADDRESS 0x0000a008
+#define PHY_BB_RX_GAIN_BOUNDS_1_OFFSET 0x0000a008
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_MSB 7
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_LSB 0
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_MASK 0x000000ff
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_MSB 15
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_LSB 8
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_MASK 0x0000ff00
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_MSB 23
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_LSB 16
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_MASK 0x00ff0000
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_MSB 24
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_LSB 24
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_MASK 0x01000000
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_MSB 25
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_LSB 25
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_MASK 0x02000000
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_SET(x) (((x) << 25) & 0x02000000)
+
+/* macros for BB_rx_gain_bounds_2 */
+#define PHY_BB_RX_GAIN_BOUNDS_2_ADDRESS 0x0000a00c
+#define PHY_BB_RX_GAIN_BOUNDS_2_OFFSET 0x0000a00c
+#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_MSB 7
+#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_LSB 0
+#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_MASK 0x000000ff
+#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_MSB 15
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_LSB 8
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_MASK 0x0000ff00
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_MSB 23
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_LSB 16
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_MASK 0x00ff0000
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_MSB 31
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_LSB 24
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_MASK 0xff000000
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_peak_det_cal_ctrl */
+#define PHY_BB_PEAK_DET_CAL_CTRL_ADDRESS 0x0000a010
+#define PHY_BB_PEAK_DET_CAL_CTRL_OFFSET 0x0000a010
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_MSB 5
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_LSB 0
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_MASK 0x0000003f
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_MSB 11
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_LSB 6
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_MASK 0x00000fc0
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_MSB 13
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_LSB 12
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_MASK 0x00003000
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_SET(x) (((x) << 12) & 0x00003000)
+
+/* macros for BB_agc_dig_dc_ctrl */
+#define PHY_BB_AGC_DIG_DC_CTRL_ADDRESS 0x0000a014
+#define PHY_BB_AGC_DIG_DC_CTRL_OFFSET 0x0000a014
+#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_MSB 0
+#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_LSB 0
+#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_MASK 0x00000001
+#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_MSB 3
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_LSB 1
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_MASK 0x0000000e
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_MSB 9
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_LSB 4
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_MASK 0x000003f0
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_GET(x) (((x) & 0x000003f0) >> 4)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_SET(x) (((x) << 4) & 0x000003f0)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_MSB 31
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_LSB 16
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_MASK 0xffff0000
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_GET(x) (((x) & 0xffff0000) >> 16)
+#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_SET(x) (((x) << 16) & 0xffff0000)
+
+/* macros for BB_agc_dig_dc_status_i_b0 */
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_ADDRESS 0x0000a018
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_OFFSET 0x0000a018
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_MSB 8
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_LSB 0
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_MASK 0x000001ff
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_MSB 17
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_LSB 9
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_MASK 0x0003fe00
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_GET(x) (((x) & 0x0003fe00) >> 9)
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_MSB 26
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_LSB 18
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_MASK 0x07fc0000
+#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_GET(x) (((x) & 0x07fc0000) >> 18)
+
+/* macros for BB_agc_dig_dc_status_q_b0 */
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_ADDRESS 0x0000a01c
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_OFFSET 0x0000a01c
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_MSB 8
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_LSB 0
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_MASK 0x000001ff
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_GET(x) (((x) & 0x000001ff) >> 0)
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_MSB 17
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_LSB 9
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_MASK 0x0003fe00
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_GET(x) (((x) & 0x0003fe00) >> 9)
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_MSB 26
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_LSB 18
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_MASK 0x07fc0000
+#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_GET(x) (((x) & 0x07fc0000) >> 18)
+
+/* macros for BB_bbb_txfir_0 */
+#define PHY_BB_BBB_TXFIR_0_ADDRESS 0x0000a1f4
+#define PHY_BB_BBB_TXFIR_0_OFFSET 0x0000a1f4
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_MSB 3
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_LSB 0
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_MASK 0x0000000f
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_MSB 11
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_LSB 8
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_MASK 0x00000f00
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_MSB 20
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_LSB 16
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_MASK 0x001f0000
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_MSB 28
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_LSB 24
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_MASK 0x1f000000
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_GET(x) (((x) & 0x1f000000) >> 24)
+#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_SET(x) (((x) << 24) & 0x1f000000)
+
+/* macros for BB_bbb_txfir_1 */
+#define PHY_BB_BBB_TXFIR_1_ADDRESS 0x0000a1f8
+#define PHY_BB_BBB_TXFIR_1_OFFSET 0x0000a1f8
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_MSB 5
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_LSB 0
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_MASK 0x0000003f
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_MSB 13
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_LSB 8
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_MASK 0x00003f00
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_MSB 22
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_LSB 16
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_MASK 0x007f0000
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_GET(x) (((x) & 0x007f0000) >> 16)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_SET(x) (((x) << 16) & 0x007f0000)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_MSB 30
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_LSB 24
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_MASK 0x7f000000
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_SET(x) (((x) << 24) & 0x7f000000)
+
+/* macros for BB_bbb_txfir_2 */
+#define PHY_BB_BBB_TXFIR_2_ADDRESS 0x0000a1fc
+#define PHY_BB_BBB_TXFIR_2_OFFSET 0x0000a1fc
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_MSB 7
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_LSB 0
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_MASK 0x000000ff
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_MSB 15
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_LSB 8
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_MASK 0x0000ff00
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_MSB 23
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_LSB 16
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_MASK 0x00ff0000
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_MSB 31
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_LSB 24
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_MASK 0xff000000
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_modes_select */
+#define PHY_BB_MODES_SELECT_ADDRESS 0x0000a200
+#define PHY_BB_MODES_SELECT_OFFSET 0x0000a200
+#define PHY_BB_MODES_SELECT_CCK_MODE_MSB 0
+#define PHY_BB_MODES_SELECT_CCK_MODE_LSB 0
+#define PHY_BB_MODES_SELECT_CCK_MODE_MASK 0x00000001
+#define PHY_BB_MODES_SELECT_CCK_MODE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_MODES_SELECT_CCK_MODE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_MSB 2
+#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_LSB 2
+#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_MASK 0x00000004
+#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_MSB 5
+#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_LSB 5
+#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_MASK 0x00000020
+#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_MSB 6
+#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_LSB 6
+#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_MASK 0x00000040
+#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_MSB 7
+#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_LSB 7
+#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_MASK 0x00000080
+#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_MSB 8
+#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_LSB 8
+#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_MASK 0x00000100
+#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_SET(x) (((x) << 8) & 0x00000100)
+
+/* macros for BB_bbb_tx_ctrl */
+#define PHY_BB_BBB_TX_CTRL_ADDRESS 0x0000a204
+#define PHY_BB_BBB_TX_CTRL_OFFSET 0x0000a204
+#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_MSB 0
+#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_LSB 0
+#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_MASK 0x00000001
+#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_MSB 1
+#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_LSB 1
+#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_MASK 0x00000002
+#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_MSB 3
+#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_LSB 2
+#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_MASK 0x0000000c
+#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_MSB 4
+#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_LSB 4
+#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_MASK 0x00000010
+#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_MSB 5
+#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_LSB 5
+#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_MASK 0x00000020
+#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_MSB 8
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_LSB 6
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_MASK 0x000001c0
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_GET(x) (((x) & 0x000001c0) >> 6)
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_SET(x) (((x) << 6) & 0x000001c0)
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_MSB 11
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_LSB 9
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_MASK 0x00000e00
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_GET(x) (((x) & 0x00000e00) >> 9)
+#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_SET(x) (((x) << 9) & 0x00000e00)
+
+/* macros for BB_bbb_sig_detect */
+#define PHY_BB_BBB_SIG_DETECT_ADDRESS 0x0000a208
+#define PHY_BB_BBB_SIG_DETECT_OFFSET 0x0000a208
+#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_MSB 5
+#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_LSB 0
+#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_MASK 0x0000003f
+#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_MSB 12
+#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_LSB 6
+#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_MASK 0x00001fc0
+#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_GET(x) (((x) & 0x00001fc0) >> 6)
+#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_SET(x) (((x) << 6) & 0x00001fc0)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_MSB 13
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_LSB 13
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_MASK 0x00002000
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_MSB 14
+#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_LSB 14
+#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_MASK 0x00004000
+#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_MSB 15
+#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_LSB 15
+#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_MASK 0x00008000
+#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_MSB 16
+#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_LSB 16
+#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_MASK 0x00010000
+#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_MSB 17
+#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_LSB 17
+#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_MASK 0x00020000
+#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_MSB 18
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_LSB 18
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_MASK 0x00040000
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_MSB 19
+#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_LSB 19
+#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_MASK 0x00080000
+#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_MSB 20
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_LSB 20
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_MASK 0x00100000
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_MSB 21
+#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_LSB 21
+#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_MASK 0x00200000
+#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_MSB 22
+#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_LSB 22
+#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_MASK 0x00400000
+#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_MSB 31
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_LSB 31
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_MASK 0x80000000
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_ext_atten_switch_ctl_b0 */
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_ADDRESS 0x0000a20c
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_OFFSET 0x0000a20c
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_MSB 5
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_LSB 0
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_MASK 0x0000003f
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_MSB 11
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_LSB 6
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_MASK 0x00000fc0
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_MSB 16
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_LSB 12
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_MASK 0x0001f000
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_MSB 21
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_LSB 17
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_MASK 0x003e0000
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_SET(x) (((x) << 17) & 0x003e0000)
+
+/* macros for BB_bbb_rx_ctrl_1 */
+#define PHY_BB_BBB_RX_CTRL_1_ADDRESS 0x0000a210
+#define PHY_BB_BBB_RX_CTRL_1_OFFSET 0x0000a210
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_MSB 2
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_LSB 0
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_MASK 0x00000007
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_MSB 7
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_LSB 3
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_MASK 0x000000f8
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_GET(x) (((x) & 0x000000f8) >> 3)
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_SET(x) (((x) << 3) & 0x000000f8)
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_MSB 10
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_LSB 8
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_MASK 0x00000700
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_GET(x) (((x) & 0x00000700) >> 8)
+#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_SET(x) (((x) << 8) & 0x00000700)
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_MSB 15
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_LSB 11
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_MASK 0x0000f800
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_GET(x) (((x) & 0x0000f800) >> 11)
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_SET(x) (((x) << 11) & 0x0000f800)
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_MSB 20
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_LSB 16
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_MASK 0x001f0000
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_MSB 23
+#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_LSB 21
+#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_MASK 0x00e00000
+#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_GET(x) (((x) & 0x00e00000) >> 21)
+#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_SET(x) (((x) << 21) & 0x00e00000)
+#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_MSB 30
+#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_LSB 24
+#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_MASK 0x7f000000
+#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_GET(x) (((x) & 0x7f000000) >> 24)
+#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_SET(x) (((x) << 24) & 0x7f000000)
+#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_MSB 31
+#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_LSB 31
+#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_MASK 0x80000000
+#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_bbb_rx_ctrl_2 */
+#define PHY_BB_BBB_RX_CTRL_2_ADDRESS 0x0000a214
+#define PHY_BB_BBB_RX_CTRL_2_OFFSET 0x0000a214
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_MSB 5
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_LSB 0
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_MASK 0x0000003f
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_MSB 11
+#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_LSB 6
+#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_MASK 0x00000fc0
+#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_MSB 16
+#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_LSB 12
+#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_MASK 0x0001f000
+#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_MSB 21
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_LSB 17
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_MASK 0x003e0000
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_SET(x) (((x) << 17) & 0x003e0000)
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_MSB 25
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_LSB 22
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_MASK 0x03c00000
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_GET(x) (((x) & 0x03c00000) >> 22)
+#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_SET(x) (((x) << 22) & 0x03c00000)
+#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_MSB 31
+#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_LSB 26
+#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_MASK 0xfc000000
+#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_GET(x) (((x) & 0xfc000000) >> 26)
+#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_SET(x) (((x) << 26) & 0xfc000000)
+
+/* macros for BB_bbb_rx_ctrl_3 */
+#define PHY_BB_BBB_RX_CTRL_3_ADDRESS 0x0000a218
+#define PHY_BB_BBB_RX_CTRL_3_OFFSET 0x0000a218
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_MSB 7
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_LSB 0
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_MASK 0x000000ff
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_MSB 15
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_LSB 8
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_MASK 0x0000ff00
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_MSB 23
+#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_LSB 16
+#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_MASK 0x00ff0000
+#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_SET(x) (((x) << 16) & 0x00ff0000)
+
+/* macros for BB_bbb_rx_ctrl_4 */
+#define PHY_BB_BBB_RX_CTRL_4_ADDRESS 0x0000a21c
+#define PHY_BB_BBB_RX_CTRL_4_OFFSET 0x0000a21c
+#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_MSB 3
+#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_LSB 0
+#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_MASK 0x0000000f
+#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_MSB 15
+#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_LSB 4
+#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_MASK 0x0000fff0
+#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_GET(x) (((x) & 0x0000fff0) >> 4)
+#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_SET(x) (((x) << 4) & 0x0000fff0)
+#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_MSB 16
+#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_LSB 16
+#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_MASK 0x00010000
+#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_MSB 17
+#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_LSB 17
+#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_MASK 0x00020000
+#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_MSB 18
+#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_LSB 18
+#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_MASK 0x00040000
+#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_MSB 24
+#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_LSB 19
+#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_MASK 0x01f80000
+#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_GET(x) (((x) & 0x01f80000) >> 19)
+#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_SET(x) (((x) << 19) & 0x01f80000)
+#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_MSB 30
+#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_LSB 25
+#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_MASK 0x7e000000
+#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_GET(x) (((x) & 0x7e000000) >> 25)
+#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_SET(x) (((x) << 25) & 0x7e000000)
+
+/* macros for BB_bbb_rx_ctrl_5 */
+#define PHY_BB_BBB_RX_CTRL_5_ADDRESS 0x0000a220
+#define PHY_BB_BBB_RX_CTRL_5_OFFSET 0x0000a220
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_MSB 4
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_LSB 0
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_MASK 0x0000001f
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_MSB 9
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_LSB 5
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_MASK 0x000003e0
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_MSB 15
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_LSB 10
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_MASK 0x0000fc00
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_GET(x) (((x) & 0x0000fc00) >> 10)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_SET(x) (((x) << 10) & 0x0000fc00)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_MSB 20
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_LSB 16
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_MASK 0x001f0000
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_MSB 26
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_LSB 21
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_MASK 0x07e00000
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_GET(x) (((x) & 0x07e00000) >> 21)
+#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_SET(x) (((x) << 21) & 0x07e00000)
+
+/* macros for BB_bbb_rx_ctrl_6 */
+#define PHY_BB_BBB_RX_CTRL_6_ADDRESS 0x0000a224
+#define PHY_BB_BBB_RX_CTRL_6_OFFSET 0x0000a224
+#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_MSB 9
+#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_LSB 0
+#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_MASK 0x000003ff
+#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_MSB 10
+#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_LSB 10
+#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_MASK 0x00000400
+#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_MSB 20
+#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_LSB 11
+#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_MASK 0x001ff800
+#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_GET(x) (((x) & 0x001ff800) >> 11)
+#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_SET(x) (((x) << 11) & 0x001ff800)
+
+/* macros for BB_bbb_dagc_ctrl */
+#define PHY_BB_BBB_DAGC_CTRL_ADDRESS 0x0000a228
+#define PHY_BB_BBB_DAGC_CTRL_OFFSET 0x0000a228
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_MSB 0
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_LSB 0
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_MASK 0x00000001
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_MSB 8
+#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_LSB 1
+#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_MASK 0x000001fe
+#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_GET(x) (((x) & 0x000001fe) >> 1)
+#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_SET(x) (((x) << 1) & 0x000001fe)
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_MSB 9
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_LSB 9
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_MASK 0x00000200
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_MSB 16
+#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_LSB 10
+#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_MASK 0x0001fc00
+#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_GET(x) (((x) & 0x0001fc00) >> 10)
+#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_SET(x) (((x) << 10) & 0x0001fc00)
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_MSB 17
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_LSB 17
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_MASK 0x00020000
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_MSB 23
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_LSB 18
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_MASK 0x00fc0000
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_SET(x) (((x) << 18) & 0x00fc0000)
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_MSB 27
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_LSB 24
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_MASK 0x0f000000
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_GET(x) (((x) & 0x0f000000) >> 24)
+#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_SET(x) (((x) << 24) & 0x0f000000)
+
+/* macros for BB_force_clken_cck */
+#define PHY_BB_FORCE_CLKEN_CCK_ADDRESS 0x0000a22c
+#define PHY_BB_FORCE_CLKEN_CCK_OFFSET 0x0000a22c
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_MSB 0
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_LSB 0
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_MASK 0x00000001
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_MSB 1
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_LSB 1
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_MASK 0x00000002
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_MSB 2
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_LSB 2
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_MASK 0x00000004
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_MSB 3
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_LSB 3
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_MASK 0x00000008
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_MSB 4
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_LSB 4
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_MASK 0x00000010
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_MSB 5
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_LSB 5
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_MASK 0x00000020
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_SET(x) (((x) << 5) & 0x00000020)
+
+/* macros for BB_rx_clear_delay */
+#define PHY_BB_RX_CLEAR_DELAY_ADDRESS 0x0000a230
+#define PHY_BB_RX_CLEAR_DELAY_OFFSET 0x0000a230
+#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_MSB 9
+#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_LSB 0
+#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_MASK 0x000003ff
+#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_SET(x) (((x) << 0) & 0x000003ff)
+
+/* macros for BB_powertx_rate3 */
+#define PHY_BB_POWERTX_RATE3_ADDRESS 0x0000a234
+#define PHY_BB_POWERTX_RATE3_OFFSET 0x0000a234
+#define PHY_BB_POWERTX_RATE3_POWERTX_1L_MSB 5
+#define PHY_BB_POWERTX_RATE3_POWERTX_1L_LSB 0
+#define PHY_BB_POWERTX_RATE3_POWERTX_1L_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE3_POWERTX_1L_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE3_POWERTX_1L_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE3_POWERTX_2L_MSB 21
+#define PHY_BB_POWERTX_RATE3_POWERTX_2L_LSB 16
+#define PHY_BB_POWERTX_RATE3_POWERTX_2L_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE3_POWERTX_2L_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE3_POWERTX_2L_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE3_POWERTX_2S_MSB 29
+#define PHY_BB_POWERTX_RATE3_POWERTX_2S_LSB 24
+#define PHY_BB_POWERTX_RATE3_POWERTX_2S_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE3_POWERTX_2S_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE3_POWERTX_2S_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate4 */
+#define PHY_BB_POWERTX_RATE4_ADDRESS 0x0000a238
+#define PHY_BB_POWERTX_RATE4_OFFSET 0x0000a238
+#define PHY_BB_POWERTX_RATE4_POWERTX_55L_MSB 5
+#define PHY_BB_POWERTX_RATE4_POWERTX_55L_LSB 0
+#define PHY_BB_POWERTX_RATE4_POWERTX_55L_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE4_POWERTX_55L_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE4_POWERTX_55L_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE4_POWERTX_55S_MSB 13
+#define PHY_BB_POWERTX_RATE4_POWERTX_55S_LSB 8
+#define PHY_BB_POWERTX_RATE4_POWERTX_55S_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE4_POWERTX_55S_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE4_POWERTX_55S_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE4_POWERTX_11L_MSB 21
+#define PHY_BB_POWERTX_RATE4_POWERTX_11L_LSB 16
+#define PHY_BB_POWERTX_RATE4_POWERTX_11L_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE4_POWERTX_11L_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE4_POWERTX_11L_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE4_POWERTX_11S_MSB 29
+#define PHY_BB_POWERTX_RATE4_POWERTX_11S_LSB 24
+#define PHY_BB_POWERTX_RATE4_POWERTX_11S_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE4_POWERTX_11S_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE4_POWERTX_11S_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_cck_spur_mit */
+#define PHY_BB_CCK_SPUR_MIT_ADDRESS 0x0000a240
+#define PHY_BB_CCK_SPUR_MIT_OFFSET 0x0000a240
+#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_MSB 0
+#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_LSB 0
+#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_MASK 0x00000001
+#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_MSB 8
+#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_LSB 1
+#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_MASK 0x000001fe
+#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_GET(x) (((x) & 0x000001fe) >> 1)
+#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_SET(x) (((x) << 1) & 0x000001fe)
+#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_MSB 28
+#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_LSB 9
+#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_MASK 0x1ffffe00
+#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_GET(x) (((x) & 0x1ffffe00) >> 9)
+#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_SET(x) (((x) << 9) & 0x1ffffe00)
+#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_MSB 30
+#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_LSB 29
+#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_MASK 0x60000000
+#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_SET(x) (((x) << 29) & 0x60000000)
+
+/* macros for BB_panic_watchdog_status */
+#define PHY_BB_PANIC_WATCHDOG_STATUS_ADDRESS 0x0000a244
+#define PHY_BB_PANIC_WATCHDOG_STATUS_OFFSET 0x0000a244
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_MSB 2
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_LSB 0
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_MASK 0x00000007
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_MSB 3
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_LSB 3
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_MASK 0x00000008
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_MSB 7
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_LSB 4
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_MASK 0x000000f0
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_MSB 11
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_LSB 8
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_MASK 0x00000f00
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_GET(x) (((x) & 0x00000f00) >> 8)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_SET(x) (((x) << 8) & 0x00000f00)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_MSB 15
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_LSB 12
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_MASK 0x0000f000
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_MSB 19
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_LSB 16
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_MASK 0x000f0000
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_GET(x) (((x) & 0x000f0000) >> 16)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_SET(x) (((x) << 16) & 0x000f0000)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_MSB 23
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_LSB 20
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_MASK 0x00f00000
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_MSB 27
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_LSB 24
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_MASK 0x0f000000
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_GET(x) (((x) & 0x0f000000) >> 24)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_SET(x) (((x) << 24) & 0x0f000000)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_MSB 31
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_LSB 28
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_MASK 0xf0000000
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_GET(x) (((x) & 0xf0000000) >> 28)
+#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_SET(x) (((x) << 28) & 0xf0000000)
+
+/* macros for BB_panic_watchdog_ctrl_1 */
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ADDRESS 0x0000a248
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_OFFSET 0x0000a248
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_MSB 0
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_LSB 0
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_MASK 0x00000001
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_MSB 1
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_LSB 1
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_MASK 0x00000002
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_MSB 15
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_LSB 2
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_MASK 0x0000fffc
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_GET(x) (((x) & 0x0000fffc) >> 2)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_SET(x) (((x) << 2) & 0x0000fffc)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_MSB 31
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_LSB 16
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_MASK 0xffff0000
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_GET(x) (((x) & 0xffff0000) >> 16)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_SET(x) (((x) << 16) & 0xffff0000)
+
+/* macros for BB_panic_watchdog_ctrl_2 */
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_ADDRESS 0x0000a24c
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_OFFSET 0x0000a24c
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_MSB 0
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_LSB 0
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_MASK 0x00000001
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_MSB 1
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_LSB 1
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_MASK 0x00000002
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_MSB 2
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_LSB 2
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_MASK 0x00000004
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_SET(x) (((x) << 2) & 0x00000004)
+
+/* macros for BB_iqcorr_ctrl_cck */
+#define PHY_BB_IQCORR_CTRL_CCK_ADDRESS 0x0000a250
+#define PHY_BB_IQCORR_CTRL_CCK_OFFSET 0x0000a250
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_MSB 4
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_LSB 0
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_MASK 0x0000001f
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_MSB 10
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_LSB 5
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_MASK 0x000007e0
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_GET(x) (((x) & 0x000007e0) >> 5)
+#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_SET(x) (((x) << 5) & 0x000007e0)
+#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_MSB 11
+#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_LSB 11
+#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_MASK 0x00000800
+#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_MSB 13
+#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_LSB 12
+#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_MASK 0x00003000
+#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_GET(x) (((x) & 0x00003000) >> 12)
+#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_SET(x) (((x) << 12) & 0x00003000)
+#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_MSB 15
+#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_LSB 14
+#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_MASK 0x0000c000
+#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_MSB 20
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_LSB 16
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_MASK 0x001f0000
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_MSB 21
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_LSB 21
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_MASK 0x00200000
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_SET(x) (((x) << 21) & 0x00200000)
+
+/* macros for BB_bluetooth_cntl */
+#define PHY_BB_BLUETOOTH_CNTL_ADDRESS 0x0000a254
+#define PHY_BB_BLUETOOTH_CNTL_OFFSET 0x0000a254
+#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_MSB 0
+#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_LSB 0
+#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_MASK 0x00000001
+#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_MSB 1
+#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_LSB 1
+#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_MASK 0x00000002
+#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_SET(x) (((x) << 1) & 0x00000002)
+
+/* macros for BB_tpc_1 */
+#define PHY_BB_TPC_1_ADDRESS 0x0000a258
+#define PHY_BB_TPC_1_OFFSET 0x0000a258
+#define PHY_BB_TPC_1_FORCE_DAC_GAIN_MSB 0
+#define PHY_BB_TPC_1_FORCE_DAC_GAIN_LSB 0
+#define PHY_BB_TPC_1_FORCE_DAC_GAIN_MASK 0x00000001
+#define PHY_BB_TPC_1_FORCE_DAC_GAIN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TPC_1_FORCE_DAC_GAIN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TPC_1_FORCED_DAC_GAIN_MSB 5
+#define PHY_BB_TPC_1_FORCED_DAC_GAIN_LSB 1
+#define PHY_BB_TPC_1_FORCED_DAC_GAIN_MASK 0x0000003e
+#define PHY_BB_TPC_1_FORCED_DAC_GAIN_GET(x) (((x) & 0x0000003e) >> 1)
+#define PHY_BB_TPC_1_FORCED_DAC_GAIN_SET(x) (((x) << 1) & 0x0000003e)
+#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_MSB 13
+#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_LSB 6
+#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_MASK 0x00003fc0
+#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_GET(x) (((x) & 0x00003fc0) >> 6)
+#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_SET(x) (((x) << 6) & 0x00003fc0)
+#define PHY_BB_TPC_1_NUM_PD_GAIN_MSB 15
+#define PHY_BB_TPC_1_NUM_PD_GAIN_LSB 14
+#define PHY_BB_TPC_1_NUM_PD_GAIN_MASK 0x0000c000
+#define PHY_BB_TPC_1_NUM_PD_GAIN_GET(x) (((x) & 0x0000c000) >> 14)
+#define PHY_BB_TPC_1_NUM_PD_GAIN_SET(x) (((x) << 14) & 0x0000c000)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING1_MSB 17
+#define PHY_BB_TPC_1_PD_GAIN_SETTING1_LSB 16
+#define PHY_BB_TPC_1_PD_GAIN_SETTING1_MASK 0x00030000
+#define PHY_BB_TPC_1_PD_GAIN_SETTING1_GET(x) (((x) & 0x00030000) >> 16)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING1_SET(x) (((x) << 16) & 0x00030000)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING2_MSB 19
+#define PHY_BB_TPC_1_PD_GAIN_SETTING2_LSB 18
+#define PHY_BB_TPC_1_PD_GAIN_SETTING2_MASK 0x000c0000
+#define PHY_BB_TPC_1_PD_GAIN_SETTING2_GET(x) (((x) & 0x000c0000) >> 18)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING2_SET(x) (((x) << 18) & 0x000c0000)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING3_MSB 21
+#define PHY_BB_TPC_1_PD_GAIN_SETTING3_LSB 20
+#define PHY_BB_TPC_1_PD_GAIN_SETTING3_MASK 0x00300000
+#define PHY_BB_TPC_1_PD_GAIN_SETTING3_GET(x) (((x) & 0x00300000) >> 20)
+#define PHY_BB_TPC_1_PD_GAIN_SETTING3_SET(x) (((x) << 20) & 0x00300000)
+#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_MSB 22
+#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_LSB 22
+#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_MASK 0x00400000
+#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_MSB 28
+#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_LSB 23
+#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_MASK 0x1f800000
+#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_GET(x) (((x) & 0x1f800000) >> 23)
+#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_SET(x) (((x) << 23) & 0x1f800000)
+#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_MSB 29
+#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_LSB 29
+#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_MASK 0x20000000
+#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_MSB 31
+#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_LSB 30
+#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_MASK 0xc0000000
+#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_GET(x) (((x) & 0xc0000000) >> 30)
+#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_SET(x) (((x) << 30) & 0xc0000000)
+
+/* macros for BB_tpc_2 */
+#define PHY_BB_TPC_2_ADDRESS 0x0000a25c
+#define PHY_BB_TPC_2_OFFSET 0x0000a25c
+#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_MSB 7
+#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_LSB 0
+#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_MASK 0x000000ff
+#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_MSB 15
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_LSB 8
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_MASK 0x0000ff00
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_MSB 23
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_LSB 16
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_MASK 0x00ff0000
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_SET(x) (((x) << 16) & 0x00ff0000)
+
+/* macros for BB_tpc_3 */
+#define PHY_BB_TPC_3_ADDRESS 0x0000a260
+#define PHY_BB_TPC_3_OFFSET 0x0000a260
+#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_MSB 7
+#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_LSB 0
+#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_MASK 0x000000ff
+#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_MSB 15
+#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_LSB 8
+#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_MASK 0x0000ff00
+#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_MSB 18
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_LSB 16
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_MASK 0x00070000
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_MSB 21
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_LSB 19
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_MASK 0x00380000
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_GET(x) (((x) & 0x00380000) >> 19)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_SET(x) (((x) << 19) & 0x00380000)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_MSB 24
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_LSB 22
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_MASK 0x01c00000
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_GET(x) (((x) & 0x01c00000) >> 22)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_SET(x) (((x) << 22) & 0x01c00000)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_MSB 27
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_LSB 25
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_MASK 0x0e000000
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_GET(x) (((x) & 0x0e000000) >> 25)
+#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_SET(x) (((x) << 25) & 0x0e000000)
+#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_MSB 31
+#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_LSB 31
+#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_MASK 0x80000000
+#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_tpc_4_b0 */
+#define PHY_BB_TPC_4_B0_ADDRESS 0x0000a264
+#define PHY_BB_TPC_4_B0_OFFSET 0x0000a264
+#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_MSB 0
+#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_LSB 0
+#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_MASK 0x00000001
+#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_MSB 8
+#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_LSB 1
+#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_MASK 0x000001fe
+#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_GET(x) (((x) & 0x000001fe) >> 1)
+#define PHY_BB_TPC_4_B0_DAC_GAIN_0_MSB 13
+#define PHY_BB_TPC_4_B0_DAC_GAIN_0_LSB 9
+#define PHY_BB_TPC_4_B0_DAC_GAIN_0_MASK 0x00003e00
+#define PHY_BB_TPC_4_B0_DAC_GAIN_0_GET(x) (((x) & 0x00003e00) >> 9)
+#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_MSB 19
+#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_LSB 14
+#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_MASK 0x000fc000
+#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_GET(x) (((x) & 0x000fc000) >> 14)
+#define PHY_BB_TPC_4_B0_RATE_SENT_0_MSB 24
+#define PHY_BB_TPC_4_B0_RATE_SENT_0_LSB 20
+#define PHY_BB_TPC_4_B0_RATE_SENT_0_MASK 0x01f00000
+#define PHY_BB_TPC_4_B0_RATE_SENT_0_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_MSB 30
+#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_LSB 25
+#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_MASK 0x7e000000
+#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_GET(x) (((x) & 0x7e000000) >> 25)
+#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_SET(x) (((x) << 25) & 0x7e000000)
+
+/* macros for BB_analog_swap */
+#define PHY_BB_ANALOG_SWAP_ADDRESS 0x0000a268
+#define PHY_BB_ANALOG_SWAP_OFFSET 0x0000a268
+#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_MSB 2
+#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_LSB 0
+#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_MASK 0x00000007
+#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_MSB 5
+#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_LSB 3
+#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_MASK 0x00000038
+#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_GET(x) (((x) & 0x00000038) >> 3)
+#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_SET(x) (((x) << 3) & 0x00000038)
+#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_MSB 6
+#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_LSB 6
+#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_MASK 0x00000040
+#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_MSB 7
+#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_LSB 7
+#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_MASK 0x00000080
+#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_MSB 8
+#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_LSB 8
+#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_MASK 0x00000100
+#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_SET(x) (((x) << 8) & 0x00000100)
+
+/* macros for BB_tpc_5_b0 */
+#define PHY_BB_TPC_5_B0_ADDRESS 0x0000a26c
+#define PHY_BB_TPC_5_B0_OFFSET 0x0000a26c
+#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_MSB 3
+#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_LSB 0
+#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_MASK 0x0000000f
+#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_MSB 9
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_LSB 4
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_MASK 0x000003f0
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_GET(x) (((x) & 0x000003f0) >> 4)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_SET(x) (((x) << 4) & 0x000003f0)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_MSB 15
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_LSB 10
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_MASK 0x0000fc00
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_GET(x) (((x) & 0x0000fc00) >> 10)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_SET(x) (((x) << 10) & 0x0000fc00)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_MSB 21
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_LSB 16
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_MASK 0x003f0000
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_MSB 27
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_LSB 22
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_MASK 0x0fc00000
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_GET(x) (((x) & 0x0fc00000) >> 22)
+#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_SET(x) (((x) << 22) & 0x0fc00000)
+
+/* macros for BB_tpc_6_b0 */
+#define PHY_BB_TPC_6_B0_ADDRESS 0x0000a270
+#define PHY_BB_TPC_6_B0_OFFSET 0x0000a270
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_MSB 5
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_LSB 0
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_MASK 0x0000003f
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_MSB 11
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_LSB 6
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_MASK 0x00000fc0
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_MSB 17
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_LSB 12
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_MASK 0x0003f000
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_MSB 23
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_LSB 18
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_MASK 0x00fc0000
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_SET(x) (((x) << 18) & 0x00fc0000)
+#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_MSB 25
+#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_LSB 24
+#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_MASK 0x03000000
+#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_MSB 28
+#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_LSB 26
+#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_MASK 0x1c000000
+#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_GET(x) (((x) & 0x1c000000) >> 26)
+#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_SET(x) (((x) << 26) & 0x1c000000)
+
+/* macros for BB_tpc_7 */
+#define PHY_BB_TPC_7_ADDRESS 0x0000a274
+#define PHY_BB_TPC_7_OFFSET 0x0000a274
+#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_MSB 5
+#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_LSB 0
+#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_MASK 0x0000003f
+#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_MSB 11
+#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_LSB 6
+#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_MASK 0x00000fc0
+#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_MSB 12
+#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_LSB 12
+#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_MASK 0x00001000
+#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_MSB 13
+#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_LSB 13
+#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_MASK 0x00002000
+#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_MSB 14
+#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_LSB 14
+#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_MASK 0x00004000
+#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_MSB 15
+#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_LSB 15
+#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_MASK 0x00008000
+#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_SET(x) (((x) << 15) & 0x00008000)
+
+/* macros for BB_tpc_8 */
+#define PHY_BB_TPC_8_ADDRESS 0x0000a278
+#define PHY_BB_TPC_8_OFFSET 0x0000a278
+#define PHY_BB_TPC_8_DESIRED_SCALE_0_MSB 4
+#define PHY_BB_TPC_8_DESIRED_SCALE_0_LSB 0
+#define PHY_BB_TPC_8_DESIRED_SCALE_0_MASK 0x0000001f
+#define PHY_BB_TPC_8_DESIRED_SCALE_0_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_8_DESIRED_SCALE_0_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_8_DESIRED_SCALE_1_MSB 9
+#define PHY_BB_TPC_8_DESIRED_SCALE_1_LSB 5
+#define PHY_BB_TPC_8_DESIRED_SCALE_1_MASK 0x000003e0
+#define PHY_BB_TPC_8_DESIRED_SCALE_1_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_8_DESIRED_SCALE_1_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_8_DESIRED_SCALE_2_MSB 14
+#define PHY_BB_TPC_8_DESIRED_SCALE_2_LSB 10
+#define PHY_BB_TPC_8_DESIRED_SCALE_2_MASK 0x00007c00
+#define PHY_BB_TPC_8_DESIRED_SCALE_2_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_8_DESIRED_SCALE_2_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_8_DESIRED_SCALE_3_MSB 19
+#define PHY_BB_TPC_8_DESIRED_SCALE_3_LSB 15
+#define PHY_BB_TPC_8_DESIRED_SCALE_3_MASK 0x000f8000
+#define PHY_BB_TPC_8_DESIRED_SCALE_3_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_TPC_8_DESIRED_SCALE_3_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_TPC_8_DESIRED_SCALE_4_MSB 24
+#define PHY_BB_TPC_8_DESIRED_SCALE_4_LSB 20
+#define PHY_BB_TPC_8_DESIRED_SCALE_4_MASK 0x01f00000
+#define PHY_BB_TPC_8_DESIRED_SCALE_4_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_8_DESIRED_SCALE_4_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_TPC_8_DESIRED_SCALE_5_MSB 29
+#define PHY_BB_TPC_8_DESIRED_SCALE_5_LSB 25
+#define PHY_BB_TPC_8_DESIRED_SCALE_5_MASK 0x3e000000
+#define PHY_BB_TPC_8_DESIRED_SCALE_5_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_TPC_8_DESIRED_SCALE_5_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_tpc_9 */
+#define PHY_BB_TPC_9_ADDRESS 0x0000a27c
+#define PHY_BB_TPC_9_OFFSET 0x0000a27c
+#define PHY_BB_TPC_9_DESIRED_SCALE_6_MSB 4
+#define PHY_BB_TPC_9_DESIRED_SCALE_6_LSB 0
+#define PHY_BB_TPC_9_DESIRED_SCALE_6_MASK 0x0000001f
+#define PHY_BB_TPC_9_DESIRED_SCALE_6_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_9_DESIRED_SCALE_6_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_9_DESIRED_SCALE_7_MSB 9
+#define PHY_BB_TPC_9_DESIRED_SCALE_7_LSB 5
+#define PHY_BB_TPC_9_DESIRED_SCALE_7_MASK 0x000003e0
+#define PHY_BB_TPC_9_DESIRED_SCALE_7_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_9_DESIRED_SCALE_7_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_MSB 14
+#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_LSB 10
+#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_MASK 0x00007c00
+#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_MSB 20
+#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_LSB 20
+#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_MASK 0x00100000
+#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_MSB 26
+#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_LSB 21
+#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_MASK 0x07e00000
+#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_GET(x) (((x) & 0x07e00000) >> 21)
+#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_SET(x) (((x) << 21) & 0x07e00000)
+#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_MSB 30
+#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_LSB 27
+#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_MASK 0x78000000
+#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_SET(x) (((x) << 27) & 0x78000000)
+#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_MSB 31
+#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_LSB 31
+#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_MASK 0x80000000
+#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_pdadc_tab_b0 */
+#define PHY_BB_PDADC_TAB_B0_ADDRESS 0x0000a280
+#define PHY_BB_PDADC_TAB_B0_OFFSET 0x0000a280
+#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_MSB 31
+#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_LSB 0
+#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_MASK 0xffffffff
+#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_tab_b0 */
+#define PHY_BB_CL_TAB_B0_ADDRESS 0x0000a300
+#define PHY_BB_CL_TAB_B0_OFFSET 0x0000a300
+#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_MSB 4
+#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_LSB 0
+#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_MASK 0x0000001f
+#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_MSB 15
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_LSB 5
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_MASK 0x0000ffe0
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_GET(x) (((x) & 0x0000ffe0) >> 5)
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_SET(x) (((x) << 5) & 0x0000ffe0)
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_MSB 26
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_LSB 16
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_MASK 0x07ff0000
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_GET(x) (((x) & 0x07ff0000) >> 16)
+#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_SET(x) (((x) << 16) & 0x07ff0000)
+#define PHY_BB_CL_TAB_B0_BB_GAIN_MSB 30
+#define PHY_BB_CL_TAB_B0_BB_GAIN_LSB 27
+#define PHY_BB_CL_TAB_B0_BB_GAIN_MASK 0x78000000
+#define PHY_BB_CL_TAB_B0_BB_GAIN_GET(x) (((x) & 0x78000000) >> 27)
+#define PHY_BB_CL_TAB_B0_BB_GAIN_SET(x) (((x) << 27) & 0x78000000)
+
+/* macros for BB_cl_map_0_b0 */
+#define PHY_BB_CL_MAP_0_B0_ADDRESS 0x0000a340
+#define PHY_BB_CL_MAP_0_B0_OFFSET 0x0000a340
+#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_MSB 31
+#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_LSB 0
+#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_MASK 0xffffffff
+#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_1_b0 */
+#define PHY_BB_CL_MAP_1_B0_ADDRESS 0x0000a344
+#define PHY_BB_CL_MAP_1_B0_OFFSET 0x0000a344
+#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_MSB 31
+#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_LSB 0
+#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_MASK 0xffffffff
+#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_2_b0 */
+#define PHY_BB_CL_MAP_2_B0_ADDRESS 0x0000a348
+#define PHY_BB_CL_MAP_2_B0_OFFSET 0x0000a348
+#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_MSB 31
+#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_LSB 0
+#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_MASK 0xffffffff
+#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_3_b0 */
+#define PHY_BB_CL_MAP_3_B0_ADDRESS 0x0000a34c
+#define PHY_BB_CL_MAP_3_B0_OFFSET 0x0000a34c
+#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_MSB 31
+#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_LSB 0
+#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_MASK 0xffffffff
+#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_cal_ctrl */
+#define PHY_BB_CL_CAL_CTRL_ADDRESS 0x0000a358
+#define PHY_BB_CL_CAL_CTRL_OFFSET 0x0000a358
+#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_MSB 0
+#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_LSB 0
+#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_MASK 0x00000001
+#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_MSB 1
+#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_LSB 1
+#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_MASK 0x00000002
+#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_MSB 3
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_LSB 2
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_MASK 0x0000000c
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_MSB 7
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_LSB 4
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_MASK 0x000000f0
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_GET(x) (((x) & 0x000000f0) >> 4)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_SET(x) (((x) << 4) & 0x000000f0)
+#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_MSB 15
+#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_LSB 8
+#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_MASK 0x0000ff00
+#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_MSB 21
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_LSB 16
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_MASK 0x003f0000
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_MSB 29
+#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_LSB 22
+#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_MASK 0x3fc00000
+#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_GET(x) (((x) & 0x3fc00000) >> 22)
+#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_SET(x) (((x) << 22) & 0x3fc00000)
+#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_MSB 30
+#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_LSB 30
+#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_MASK 0x40000000
+#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_SET(x) (((x) << 30) & 0x40000000)
+#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_MSB 31
+#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_LSB 31
+#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_MASK 0x80000000
+#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_cl_map_pal_0_b0 */
+#define PHY_BB_CL_MAP_PAL_0_B0_ADDRESS 0x0000a35c
+#define PHY_BB_CL_MAP_PAL_0_B0_OFFSET 0x0000a35c
+#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_MSB 31
+#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_LSB 0
+#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_MASK 0xffffffff
+#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_pal_1_b0 */
+#define PHY_BB_CL_MAP_PAL_1_B0_ADDRESS 0x0000a360
+#define PHY_BB_CL_MAP_PAL_1_B0_OFFSET 0x0000a360
+#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_MSB 31
+#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_LSB 0
+#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_MASK 0xffffffff
+#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_pal_2_b0 */
+#define PHY_BB_CL_MAP_PAL_2_B0_ADDRESS 0x0000a364
+#define PHY_BB_CL_MAP_PAL_2_B0_OFFSET 0x0000a364
+#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_MSB 31
+#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_LSB 0
+#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_MASK 0xffffffff
+#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_cl_map_pal_3_b0 */
+#define PHY_BB_CL_MAP_PAL_3_B0_ADDRESS 0x0000a368
+#define PHY_BB_CL_MAP_PAL_3_B0_OFFSET 0x0000a368
+#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_MSB 31
+#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_LSB 0
+#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_MASK 0xffffffff
+#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_rifs */
+#define PHY_BB_RIFS_ADDRESS 0x0000a388
+#define PHY_BB_RIFS_OFFSET 0x0000a388
+#define PHY_BB_RIFS_DISABLE_FCC_FIX_MSB 25
+#define PHY_BB_RIFS_DISABLE_FCC_FIX_LSB 25
+#define PHY_BB_RIFS_DISABLE_FCC_FIX_MASK 0x02000000
+#define PHY_BB_RIFS_DISABLE_FCC_FIX_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_BB_RIFS_DISABLE_FCC_FIX_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_MSB 26
+#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_LSB 26
+#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_MASK 0x04000000
+#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_BB_RIFS_DISABLE_FCC_FIX2_MSB 27
+#define PHY_BB_RIFS_DISABLE_FCC_FIX2_LSB 27
+#define PHY_BB_RIFS_DISABLE_FCC_FIX2_MASK 0x08000000
+#define PHY_BB_RIFS_DISABLE_FCC_FIX2_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_RIFS_DISABLE_FCC_FIX2_SET(x) (((x) << 27) & 0x08000000)
+#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_MSB 28
+#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_LSB 28
+#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_MASK 0x10000000
+#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_SET(x) (((x) << 28) & 0x10000000)
+#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_MSB 29
+#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_LSB 29
+#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_MASK 0x20000000
+#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_GET(x) (((x) & 0x20000000) >> 29)
+#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_SET(x) (((x) << 29) & 0x20000000)
+#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_MSB 30
+#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_LSB 30
+#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_MASK 0x40000000
+#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_GET(x) (((x) & 0x40000000) >> 30)
+#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_SET(x) (((x) << 30) & 0x40000000)
+
+/* macros for BB_powertx_rate5 */
+#define PHY_BB_POWERTX_RATE5_ADDRESS 0x0000a38c
+#define PHY_BB_POWERTX_RATE5_OFFSET 0x0000a38c
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_MSB 5
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_LSB 0
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_MSB 13
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_LSB 8
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_MSB 21
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_LSB 16
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_MSB 29
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_LSB 24
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate6 */
+#define PHY_BB_POWERTX_RATE6_ADDRESS 0x0000a390
+#define PHY_BB_POWERTX_RATE6_OFFSET 0x0000a390
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_MSB 5
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_LSB 0
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_MSB 13
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_LSB 8
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_MSB 21
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_LSB 16
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_MSB 29
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_LSB 24
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_tpc_10 */
+#define PHY_BB_TPC_10_ADDRESS 0x0000a394
+#define PHY_BB_TPC_10_OFFSET 0x0000a394
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_MSB 4
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_LSB 0
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_MASK 0x0000001f
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_MSB 9
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_LSB 5
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_MASK 0x000003e0
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_MSB 14
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_LSB 10
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_MASK 0x00007c00
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_MSB 19
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_LSB 15
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_MASK 0x000f8000
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_MSB 24
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_LSB 20
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_MASK 0x01f00000
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_MSB 29
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_LSB 25
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_MASK 0x3e000000
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_tpc_11_b0 */
+#define PHY_BB_TPC_11_B0_ADDRESS 0x0000a398
+#define PHY_BB_TPC_11_B0_OFFSET 0x0000a398
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_MSB 4
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_LSB 0
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_MASK 0x0000001f
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_MSB 9
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_LSB 5
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_MASK 0x000003e0
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_MSB 23
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_LSB 16
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_MASK 0x00ff0000
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_MSB 31
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_LSB 24
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_MASK 0xff000000
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_GET(x) (((x) & 0xff000000) >> 24)
+#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_SET(x) (((x) << 24) & 0xff000000)
+
+/* macros for BB_cal_chain_mask */
+#define PHY_BB_CAL_CHAIN_MASK_ADDRESS 0x0000a39c
+#define PHY_BB_CAL_CHAIN_MASK_OFFSET 0x0000a39c
+#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_MSB 2
+#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_LSB 0
+#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_MASK 0x00000007
+#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_SET(x) (((x) << 0) & 0x00000007)
+
+/* macros for BB_powertx_sub */
+#define PHY_BB_POWERTX_SUB_ADDRESS 0x0000a3bc
+#define PHY_BB_POWERTX_SUB_OFFSET 0x0000a3bc
+#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_MSB 5
+#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_LSB 0
+#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_MASK 0x0000003f
+#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_SET(x) (((x) << 0) & 0x0000003f)
+
+/* macros for BB_powertx_rate7 */
+#define PHY_BB_POWERTX_RATE7_ADDRESS 0x0000a3c0
+#define PHY_BB_POWERTX_RATE7_OFFSET 0x0000a3c0
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_MSB 5
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_LSB 0
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_MSB 13
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_LSB 8
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_MSB 21
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_LSB 16
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_MSB 29
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_LSB 24
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate8 */
+#define PHY_BB_POWERTX_RATE8_ADDRESS 0x0000a3c4
+#define PHY_BB_POWERTX_RATE8_OFFSET 0x0000a3c4
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_MSB 5
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_LSB 0
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_MSB 13
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_LSB 8
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_MSB 21
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_LSB 16
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_MSB 29
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_LSB 24
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate9 */
+#define PHY_BB_POWERTX_RATE9_ADDRESS 0x0000a3c8
+#define PHY_BB_POWERTX_RATE9_OFFSET 0x0000a3c8
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_MSB 5
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_LSB 0
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_MSB 13
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_LSB 8
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_MSB 21
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_LSB 16
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_MSB 29
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_LSB 24
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate10 */
+#define PHY_BB_POWERTX_RATE10_ADDRESS 0x0000a3cc
+#define PHY_BB_POWERTX_RATE10_OFFSET 0x0000a3cc
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_MSB 5
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_LSB 0
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_MSB 13
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_LSB 8
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_MSB 21
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_LSB 16
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_MSB 29
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_LSB 24
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate11 */
+#define PHY_BB_POWERTX_RATE11_ADDRESS 0x0000a3d0
+#define PHY_BB_POWERTX_RATE11_OFFSET 0x0000a3d0
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_MSB 5
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_LSB 0
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_MSB 13
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_LSB 8
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_MSB 21
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_LSB 16
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_MSB 29
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_LSB 24
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_powertx_rate12 */
+#define PHY_BB_POWERTX_RATE12_ADDRESS 0x0000a3d4
+#define PHY_BB_POWERTX_RATE12_OFFSET 0x0000a3d4
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_MSB 5
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_LSB 0
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_MASK 0x0000003f
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_MSB 13
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_LSB 8
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_MASK 0x00003f00
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_MSB 21
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_LSB 16
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_MASK 0x003f0000
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_MSB 29
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_LSB 24
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_MASK 0x3f000000
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_force_analog */
+#define PHY_BB_FORCE_ANALOG_ADDRESS 0x0000a3d8
+#define PHY_BB_FORCE_ANALOG_OFFSET 0x0000a3d8
+#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_MSB 0
+#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_LSB 0
+#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_MASK 0x00000001
+#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_MSB 3
+#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_LSB 1
+#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_MASK 0x0000000e
+#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_MSB 4
+#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_LSB 4
+#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_MASK 0x00000010
+#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_MSB 7
+#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_LSB 5
+#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_MASK 0x000000e0
+#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_GET(x) (((x) & 0x000000e0) >> 5)
+#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_SET(x) (((x) << 5) & 0x000000e0)
+
+/* macros for BB_tpc_12 */
+#define PHY_BB_TPC_12_ADDRESS 0x0000a3dc
+#define PHY_BB_TPC_12_OFFSET 0x0000a3dc
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_MSB 4
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_LSB 0
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_MASK 0x0000001f
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_MSB 9
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_LSB 5
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_MASK 0x000003e0
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_MSB 14
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_LSB 10
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_MASK 0x00007c00
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_MSB 19
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_LSB 15
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_MASK 0x000f8000
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_MSB 24
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_LSB 20
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_MASK 0x01f00000
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_MSB 29
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_LSB 25
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_MASK 0x3e000000
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_tpc_13 */
+#define PHY_BB_TPC_13_ADDRESS 0x0000a3e0
+#define PHY_BB_TPC_13_OFFSET 0x0000a3e0
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_MSB 4
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_LSB 0
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_MASK 0x0000001f
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_MSB 9
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_LSB 5
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_MASK 0x000003e0
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_SET(x) (((x) << 5) & 0x000003e0)
+
+/* macros for BB_tpc_14 */
+#define PHY_BB_TPC_14_ADDRESS 0x0000a3e4
+#define PHY_BB_TPC_14_OFFSET 0x0000a3e4
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_MSB 4
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_LSB 0
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_MASK 0x0000001f
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_MSB 9
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_LSB 5
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_MASK 0x000003e0
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_MSB 14
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_LSB 10
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_MASK 0x00007c00
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_MSB 19
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_LSB 15
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_MASK 0x000f8000
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_MSB 24
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_LSB 20
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_MASK 0x01f00000
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_MSB 29
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_LSB 25
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_MASK 0x3e000000
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_tpc_15 */
+#define PHY_BB_TPC_15_ADDRESS 0x0000a3e8
+#define PHY_BB_TPC_15_OFFSET 0x0000a3e8
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_MSB 4
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_LSB 0
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_MASK 0x0000001f
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_GET(x) (((x) & 0x0000001f) >> 0)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_SET(x) (((x) << 0) & 0x0000001f)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_MSB 9
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_LSB 5
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_MASK 0x000003e0
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_GET(x) (((x) & 0x000003e0) >> 5)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_SET(x) (((x) << 5) & 0x000003e0)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_MSB 14
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_LSB 10
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_MASK 0x00007c00
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_GET(x) (((x) & 0x00007c00) >> 10)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_SET(x) (((x) << 10) & 0x00007c00)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_MSB 19
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_LSB 15
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_MASK 0x000f8000
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_GET(x) (((x) & 0x000f8000) >> 15)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_SET(x) (((x) << 15) & 0x000f8000)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_MSB 24
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_LSB 20
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_MASK 0x01f00000
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_MSB 29
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_LSB 25
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_MASK 0x3e000000
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_tpc_16 */
+#define PHY_BB_TPC_16_ADDRESS 0x0000a3ec
+#define PHY_BB_TPC_16_OFFSET 0x0000a3ec
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_MSB 13
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_LSB 8
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_MASK 0x00003f00
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_GET(x) (((x) & 0x00003f00) >> 8)
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_SET(x) (((x) << 8) & 0x00003f00)
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_MSB 21
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_LSB 16
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_MASK 0x003f0000
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_GET(x) (((x) & 0x003f0000) >> 16)
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_SET(x) (((x) << 16) & 0x003f0000)
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_MSB 29
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_LSB 24
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_MASK 0x3f000000
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_GET(x) (((x) & 0x3f000000) >> 24)
+#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_SET(x) (((x) << 24) & 0x3f000000)
+
+/* macros for BB_tpc_17 */
+#define PHY_BB_TPC_17_ADDRESS 0x0000a3f0
+#define PHY_BB_TPC_17_OFFSET 0x0000a3f0
+#define PHY_BB_TPC_17_ENABLE_PAL_MSB 0
+#define PHY_BB_TPC_17_ENABLE_PAL_LSB 0
+#define PHY_BB_TPC_17_ENABLE_PAL_MASK 0x00000001
+#define PHY_BB_TPC_17_ENABLE_PAL_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TPC_17_ENABLE_PAL_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TPC_17_ENABLE_PAL_CCK_MSB 1
+#define PHY_BB_TPC_17_ENABLE_PAL_CCK_LSB 1
+#define PHY_BB_TPC_17_ENABLE_PAL_CCK_MASK 0x00000002
+#define PHY_BB_TPC_17_ENABLE_PAL_CCK_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_TPC_17_ENABLE_PAL_CCK_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_MSB 2
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_LSB 2
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_MASK 0x00000004
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_MSB 3
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_LSB 3
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_MASK 0x00000008
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_MSB 9
+#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_LSB 4
+#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_MASK 0x000003f0
+#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_GET(x) (((x) & 0x000003f0) >> 4)
+#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_SET(x) (((x) << 4) & 0x000003f0)
+#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_MSB 10
+#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_LSB 10
+#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_MASK 0x00000400
+#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_MSB 16
+#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_LSB 11
+#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_MASK 0x0001f800
+#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_GET(x) (((x) & 0x0001f800) >> 11)
+#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_SET(x) (((x) << 11) & 0x0001f800)
+
+/* macros for BB_tpc_18 */
+#define PHY_BB_TPC_18_ADDRESS 0x0000a3f4
+#define PHY_BB_TPC_18_OFFSET 0x0000a3f4
+#define PHY_BB_TPC_18_THERM_CAL_VALUE_MSB 7
+#define PHY_BB_TPC_18_THERM_CAL_VALUE_LSB 0
+#define PHY_BB_TPC_18_THERM_CAL_VALUE_MASK 0x000000ff
+#define PHY_BB_TPC_18_THERM_CAL_VALUE_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TPC_18_THERM_CAL_VALUE_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TPC_18_VOLT_CAL_VALUE_MSB 15
+#define PHY_BB_TPC_18_VOLT_CAL_VALUE_LSB 8
+#define PHY_BB_TPC_18_VOLT_CAL_VALUE_MASK 0x0000ff00
+#define PHY_BB_TPC_18_VOLT_CAL_VALUE_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TPC_18_VOLT_CAL_VALUE_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TPC_18_USE_LEGACY_TPC_MSB 16
+#define PHY_BB_TPC_18_USE_LEGACY_TPC_LSB 16
+#define PHY_BB_TPC_18_USE_LEGACY_TPC_MASK 0x00010000
+#define PHY_BB_TPC_18_USE_LEGACY_TPC_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_TPC_18_USE_LEGACY_TPC_SET(x) (((x) << 16) & 0x00010000)
+
+/* macros for BB_tpc_19 */
+#define PHY_BB_TPC_19_ADDRESS 0x0000a3f8
+#define PHY_BB_TPC_19_OFFSET 0x0000a3f8
+#define PHY_BB_TPC_19_ALPHA_THERM_MSB 7
+#define PHY_BB_TPC_19_ALPHA_THERM_LSB 0
+#define PHY_BB_TPC_19_ALPHA_THERM_MASK 0x000000ff
+#define PHY_BB_TPC_19_ALPHA_THERM_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_TPC_19_ALPHA_THERM_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_MSB 15
+#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_LSB 8
+#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_MASK 0x0000ff00
+#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_TPC_19_ALPHA_VOLT_MSB 20
+#define PHY_BB_TPC_19_ALPHA_VOLT_LSB 16
+#define PHY_BB_TPC_19_ALPHA_VOLT_MASK 0x001f0000
+#define PHY_BB_TPC_19_ALPHA_VOLT_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_TPC_19_ALPHA_VOLT_SET(x) (((x) << 16) & 0x001f0000)
+#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_MSB 25
+#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_LSB 21
+#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_MASK 0x03e00000
+#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_GET(x) (((x) & 0x03e00000) >> 21)
+#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_SET(x) (((x) << 21) & 0x03e00000)
+
+/* macros for BB_tpc_20 */
+#define PHY_BB_TPC_20_ADDRESS 0x0000a3fc
+#define PHY_BB_TPC_20_OFFSET 0x0000a3fc
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_MSB 0
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_LSB 0
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_MASK 0x00000001
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_MSB 1
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_LSB 1
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_MASK 0x00000002
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_MSB 2
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_LSB 2
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_MASK 0x00000004
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_SET(x) (((x) << 2) & 0x00000004)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_MSB 3
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_LSB 3
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_MASK 0x00000008
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_SET(x) (((x) << 3) & 0x00000008)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_MSB 4
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_LSB 4
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_MASK 0x00000010
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_GET(x) (((x) & 0x00000010) >> 4)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_SET(x) (((x) << 4) & 0x00000010)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_MSB 5
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_LSB 5
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_MASK 0x00000020
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_GET(x) (((x) & 0x00000020) >> 5)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_SET(x) (((x) << 5) & 0x00000020)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_MSB 6
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_LSB 6
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_MASK 0x00000040
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_GET(x) (((x) & 0x00000040) >> 6)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_SET(x) (((x) << 6) & 0x00000040)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_MSB 7
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_LSB 7
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_MASK 0x00000080
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_GET(x) (((x) & 0x00000080) >> 7)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_SET(x) (((x) << 7) & 0x00000080)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_MSB 8
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_LSB 8
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_MASK 0x00000100
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_MSB 9
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_LSB 9
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_MASK 0x00000200
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_MSB 10
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_LSB 10
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_MASK 0x00000400
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_MSB 11
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_LSB 11
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_MASK 0x00000800
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_MSB 12
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_LSB 12
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_MASK 0x00001000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_GET(x) (((x) & 0x00001000) >> 12)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_SET(x) (((x) << 12) & 0x00001000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_MSB 13
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_LSB 13
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_MASK 0x00002000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_GET(x) (((x) & 0x00002000) >> 13)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_SET(x) (((x) << 13) & 0x00002000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_MSB 14
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_LSB 14
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_MASK 0x00004000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_GET(x) (((x) & 0x00004000) >> 14)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_SET(x) (((x) << 14) & 0x00004000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_MSB 15
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_LSB 15
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_MASK 0x00008000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_MSB 16
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_LSB 16
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_MASK 0x00010000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_GET(x) (((x) & 0x00010000) >> 16)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_SET(x) (((x) << 16) & 0x00010000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_MSB 17
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_LSB 17
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_MASK 0x00020000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_GET(x) (((x) & 0x00020000) >> 17)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_SET(x) (((x) << 17) & 0x00020000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_MSB 18
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_LSB 18
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_MASK 0x00040000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_GET(x) (((x) & 0x00040000) >> 18)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_SET(x) (((x) << 18) & 0x00040000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_MSB 19
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_LSB 19
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_MASK 0x00080000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_GET(x) (((x) & 0x00080000) >> 19)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_SET(x) (((x) << 19) & 0x00080000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_MSB 20
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_LSB 20
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_MASK 0x00100000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_GET(x) (((x) & 0x00100000) >> 20)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_SET(x) (((x) << 20) & 0x00100000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_MSB 21
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_LSB 21
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_MASK 0x00200000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_GET(x) (((x) & 0x00200000) >> 21)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_SET(x) (((x) << 21) & 0x00200000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_MSB 22
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_LSB 22
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_MASK 0x00400000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_GET(x) (((x) & 0x00400000) >> 22)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_SET(x) (((x) << 22) & 0x00400000)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_MSB 23
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_LSB 23
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_MASK 0x00800000
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_GET(x) (((x) & 0x00800000) >> 23)
+#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_SET(x) (((x) << 23) & 0x00800000)
+
+/* macros for BB_tx_gain_tab_1 */
+#define PHY_BB_TX_GAIN_TAB_1_ADDRESS 0x0000a400
+#define PHY_BB_TX_GAIN_TAB_1_OFFSET 0x0000a400
+#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_MSB 31
+#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_LSB 0
+#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_2 */
+#define PHY_BB_TX_GAIN_TAB_2_ADDRESS 0x0000a404
+#define PHY_BB_TX_GAIN_TAB_2_OFFSET 0x0000a404
+#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_MSB 31
+#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_LSB 0
+#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_3 */
+#define PHY_BB_TX_GAIN_TAB_3_ADDRESS 0x0000a408
+#define PHY_BB_TX_GAIN_TAB_3_OFFSET 0x0000a408
+#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_MSB 31
+#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_LSB 0
+#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_4 */
+#define PHY_BB_TX_GAIN_TAB_4_ADDRESS 0x0000a40c
+#define PHY_BB_TX_GAIN_TAB_4_OFFSET 0x0000a40c
+#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_MSB 31
+#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_LSB 0
+#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_5 */
+#define PHY_BB_TX_GAIN_TAB_5_ADDRESS 0x0000a410
+#define PHY_BB_TX_GAIN_TAB_5_OFFSET 0x0000a410
+#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_MSB 31
+#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_LSB 0
+#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_6 */
+#define PHY_BB_TX_GAIN_TAB_6_ADDRESS 0x0000a414
+#define PHY_BB_TX_GAIN_TAB_6_OFFSET 0x0000a414
+#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_MSB 31
+#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_LSB 0
+#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_7 */
+#define PHY_BB_TX_GAIN_TAB_7_ADDRESS 0x0000a418
+#define PHY_BB_TX_GAIN_TAB_7_OFFSET 0x0000a418
+#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_MSB 31
+#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_LSB 0
+#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_8 */
+#define PHY_BB_TX_GAIN_TAB_8_ADDRESS 0x0000a41c
+#define PHY_BB_TX_GAIN_TAB_8_OFFSET 0x0000a41c
+#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_MSB 31
+#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_LSB 0
+#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_9 */
+#define PHY_BB_TX_GAIN_TAB_9_ADDRESS 0x0000a420
+#define PHY_BB_TX_GAIN_TAB_9_OFFSET 0x0000a420
+#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_MSB 31
+#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_LSB 0
+#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_10 */
+#define PHY_BB_TX_GAIN_TAB_10_ADDRESS 0x0000a424
+#define PHY_BB_TX_GAIN_TAB_10_OFFSET 0x0000a424
+#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_MSB 31
+#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_LSB 0
+#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_11 */
+#define PHY_BB_TX_GAIN_TAB_11_ADDRESS 0x0000a428
+#define PHY_BB_TX_GAIN_TAB_11_OFFSET 0x0000a428
+#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_MSB 31
+#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_LSB 0
+#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_12 */
+#define PHY_BB_TX_GAIN_TAB_12_ADDRESS 0x0000a42c
+#define PHY_BB_TX_GAIN_TAB_12_OFFSET 0x0000a42c
+#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_MSB 31
+#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_LSB 0
+#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_13 */
+#define PHY_BB_TX_GAIN_TAB_13_ADDRESS 0x0000a430
+#define PHY_BB_TX_GAIN_TAB_13_OFFSET 0x0000a430
+#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_MSB 31
+#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_LSB 0
+#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_14 */
+#define PHY_BB_TX_GAIN_TAB_14_ADDRESS 0x0000a434
+#define PHY_BB_TX_GAIN_TAB_14_OFFSET 0x0000a434
+#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_MSB 31
+#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_LSB 0
+#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_15 */
+#define PHY_BB_TX_GAIN_TAB_15_ADDRESS 0x0000a438
+#define PHY_BB_TX_GAIN_TAB_15_OFFSET 0x0000a438
+#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_MSB 31
+#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_LSB 0
+#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_16 */
+#define PHY_BB_TX_GAIN_TAB_16_ADDRESS 0x0000a43c
+#define PHY_BB_TX_GAIN_TAB_16_OFFSET 0x0000a43c
+#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_MSB 31
+#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_LSB 0
+#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_17 */
+#define PHY_BB_TX_GAIN_TAB_17_ADDRESS 0x0000a440
+#define PHY_BB_TX_GAIN_TAB_17_OFFSET 0x0000a440
+#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_MSB 31
+#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_LSB 0
+#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_18 */
+#define PHY_BB_TX_GAIN_TAB_18_ADDRESS 0x0000a444
+#define PHY_BB_TX_GAIN_TAB_18_OFFSET 0x0000a444
+#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_MSB 31
+#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_LSB 0
+#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_19 */
+#define PHY_BB_TX_GAIN_TAB_19_ADDRESS 0x0000a448
+#define PHY_BB_TX_GAIN_TAB_19_OFFSET 0x0000a448
+#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_MSB 31
+#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_LSB 0
+#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_20 */
+#define PHY_BB_TX_GAIN_TAB_20_ADDRESS 0x0000a44c
+#define PHY_BB_TX_GAIN_TAB_20_OFFSET 0x0000a44c
+#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_MSB 31
+#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_LSB 0
+#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_21 */
+#define PHY_BB_TX_GAIN_TAB_21_ADDRESS 0x0000a450
+#define PHY_BB_TX_GAIN_TAB_21_OFFSET 0x0000a450
+#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_MSB 31
+#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_LSB 0
+#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_22 */
+#define PHY_BB_TX_GAIN_TAB_22_ADDRESS 0x0000a454
+#define PHY_BB_TX_GAIN_TAB_22_OFFSET 0x0000a454
+#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_MSB 31
+#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_LSB 0
+#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_23 */
+#define PHY_BB_TX_GAIN_TAB_23_ADDRESS 0x0000a458
+#define PHY_BB_TX_GAIN_TAB_23_OFFSET 0x0000a458
+#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_MSB 31
+#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_LSB 0
+#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_24 */
+#define PHY_BB_TX_GAIN_TAB_24_ADDRESS 0x0000a45c
+#define PHY_BB_TX_GAIN_TAB_24_OFFSET 0x0000a45c
+#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_MSB 31
+#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_LSB 0
+#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_25 */
+#define PHY_BB_TX_GAIN_TAB_25_ADDRESS 0x0000a460
+#define PHY_BB_TX_GAIN_TAB_25_OFFSET 0x0000a460
+#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_MSB 31
+#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_LSB 0
+#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_26 */
+#define PHY_BB_TX_GAIN_TAB_26_ADDRESS 0x0000a464
+#define PHY_BB_TX_GAIN_TAB_26_OFFSET 0x0000a464
+#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_MSB 31
+#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_LSB 0
+#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_27 */
+#define PHY_BB_TX_GAIN_TAB_27_ADDRESS 0x0000a468
+#define PHY_BB_TX_GAIN_TAB_27_OFFSET 0x0000a468
+#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_MSB 31
+#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_LSB 0
+#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_28 */
+#define PHY_BB_TX_GAIN_TAB_28_ADDRESS 0x0000a46c
+#define PHY_BB_TX_GAIN_TAB_28_OFFSET 0x0000a46c
+#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_MSB 31
+#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_LSB 0
+#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_29 */
+#define PHY_BB_TX_GAIN_TAB_29_ADDRESS 0x0000a470
+#define PHY_BB_TX_GAIN_TAB_29_OFFSET 0x0000a470
+#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_MSB 31
+#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_LSB 0
+#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_30 */
+#define PHY_BB_TX_GAIN_TAB_30_ADDRESS 0x0000a474
+#define PHY_BB_TX_GAIN_TAB_30_OFFSET 0x0000a474
+#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_MSB 31
+#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_LSB 0
+#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_31 */
+#define PHY_BB_TX_GAIN_TAB_31_ADDRESS 0x0000a478
+#define PHY_BB_TX_GAIN_TAB_31_OFFSET 0x0000a478
+#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_MSB 31
+#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_LSB 0
+#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_32 */
+#define PHY_BB_TX_GAIN_TAB_32_ADDRESS 0x0000a47c
+#define PHY_BB_TX_GAIN_TAB_32_OFFSET 0x0000a47c
+#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_MSB 31
+#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_LSB 0
+#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_1 */
+#define PHY_BB_TX_GAIN_TAB_PAL_1_ADDRESS 0x0000a480
+#define PHY_BB_TX_GAIN_TAB_PAL_1_OFFSET 0x0000a480
+#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_2 */
+#define PHY_BB_TX_GAIN_TAB_PAL_2_ADDRESS 0x0000a484
+#define PHY_BB_TX_GAIN_TAB_PAL_2_OFFSET 0x0000a484
+#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_3 */
+#define PHY_BB_TX_GAIN_TAB_PAL_3_ADDRESS 0x0000a488
+#define PHY_BB_TX_GAIN_TAB_PAL_3_OFFSET 0x0000a488
+#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_4 */
+#define PHY_BB_TX_GAIN_TAB_PAL_4_ADDRESS 0x0000a48c
+#define PHY_BB_TX_GAIN_TAB_PAL_4_OFFSET 0x0000a48c
+#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_5 */
+#define PHY_BB_TX_GAIN_TAB_PAL_5_ADDRESS 0x0000a490
+#define PHY_BB_TX_GAIN_TAB_PAL_5_OFFSET 0x0000a490
+#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_6 */
+#define PHY_BB_TX_GAIN_TAB_PAL_6_ADDRESS 0x0000a494
+#define PHY_BB_TX_GAIN_TAB_PAL_6_OFFSET 0x0000a494
+#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_7 */
+#define PHY_BB_TX_GAIN_TAB_PAL_7_ADDRESS 0x0000a498
+#define PHY_BB_TX_GAIN_TAB_PAL_7_OFFSET 0x0000a498
+#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_8 */
+#define PHY_BB_TX_GAIN_TAB_PAL_8_ADDRESS 0x0000a49c
+#define PHY_BB_TX_GAIN_TAB_PAL_8_OFFSET 0x0000a49c
+#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_9 */
+#define PHY_BB_TX_GAIN_TAB_PAL_9_ADDRESS 0x0000a4a0
+#define PHY_BB_TX_GAIN_TAB_PAL_9_OFFSET 0x0000a4a0
+#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_10 */
+#define PHY_BB_TX_GAIN_TAB_PAL_10_ADDRESS 0x0000a4a4
+#define PHY_BB_TX_GAIN_TAB_PAL_10_OFFSET 0x0000a4a4
+#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_11 */
+#define PHY_BB_TX_GAIN_TAB_PAL_11_ADDRESS 0x0000a4a8
+#define PHY_BB_TX_GAIN_TAB_PAL_11_OFFSET 0x0000a4a8
+#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_12 */
+#define PHY_BB_TX_GAIN_TAB_PAL_12_ADDRESS 0x0000a4ac
+#define PHY_BB_TX_GAIN_TAB_PAL_12_OFFSET 0x0000a4ac
+#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_13 */
+#define PHY_BB_TX_GAIN_TAB_PAL_13_ADDRESS 0x0000a4b0
+#define PHY_BB_TX_GAIN_TAB_PAL_13_OFFSET 0x0000a4b0
+#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_14 */
+#define PHY_BB_TX_GAIN_TAB_PAL_14_ADDRESS 0x0000a4b4
+#define PHY_BB_TX_GAIN_TAB_PAL_14_OFFSET 0x0000a4b4
+#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_15 */
+#define PHY_BB_TX_GAIN_TAB_PAL_15_ADDRESS 0x0000a4b8
+#define PHY_BB_TX_GAIN_TAB_PAL_15_OFFSET 0x0000a4b8
+#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_16 */
+#define PHY_BB_TX_GAIN_TAB_PAL_16_ADDRESS 0x0000a4bc
+#define PHY_BB_TX_GAIN_TAB_PAL_16_OFFSET 0x0000a4bc
+#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_17 */
+#define PHY_BB_TX_GAIN_TAB_PAL_17_ADDRESS 0x0000a4c0
+#define PHY_BB_TX_GAIN_TAB_PAL_17_OFFSET 0x0000a4c0
+#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_18 */
+#define PHY_BB_TX_GAIN_TAB_PAL_18_ADDRESS 0x0000a4c4
+#define PHY_BB_TX_GAIN_TAB_PAL_18_OFFSET 0x0000a4c4
+#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_19 */
+#define PHY_BB_TX_GAIN_TAB_PAL_19_ADDRESS 0x0000a4c8
+#define PHY_BB_TX_GAIN_TAB_PAL_19_OFFSET 0x0000a4c8
+#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_20 */
+#define PHY_BB_TX_GAIN_TAB_PAL_20_ADDRESS 0x0000a4cc
+#define PHY_BB_TX_GAIN_TAB_PAL_20_OFFSET 0x0000a4cc
+#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_21 */
+#define PHY_BB_TX_GAIN_TAB_PAL_21_ADDRESS 0x0000a4d0
+#define PHY_BB_TX_GAIN_TAB_PAL_21_OFFSET 0x0000a4d0
+#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_22 */
+#define PHY_BB_TX_GAIN_TAB_PAL_22_ADDRESS 0x0000a4d4
+#define PHY_BB_TX_GAIN_TAB_PAL_22_OFFSET 0x0000a4d4
+#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_23 */
+#define PHY_BB_TX_GAIN_TAB_PAL_23_ADDRESS 0x0000a4d8
+#define PHY_BB_TX_GAIN_TAB_PAL_23_OFFSET 0x0000a4d8
+#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_24 */
+#define PHY_BB_TX_GAIN_TAB_PAL_24_ADDRESS 0x0000a4dc
+#define PHY_BB_TX_GAIN_TAB_PAL_24_OFFSET 0x0000a4dc
+#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_25 */
+#define PHY_BB_TX_GAIN_TAB_PAL_25_ADDRESS 0x0000a4e0
+#define PHY_BB_TX_GAIN_TAB_PAL_25_OFFSET 0x0000a4e0
+#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_26 */
+#define PHY_BB_TX_GAIN_TAB_PAL_26_ADDRESS 0x0000a4e4
+#define PHY_BB_TX_GAIN_TAB_PAL_26_OFFSET 0x0000a4e4
+#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_27 */
+#define PHY_BB_TX_GAIN_TAB_PAL_27_ADDRESS 0x0000a4e8
+#define PHY_BB_TX_GAIN_TAB_PAL_27_OFFSET 0x0000a4e8
+#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_28 */
+#define PHY_BB_TX_GAIN_TAB_PAL_28_ADDRESS 0x0000a4ec
+#define PHY_BB_TX_GAIN_TAB_PAL_28_OFFSET 0x0000a4ec
+#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_29 */
+#define PHY_BB_TX_GAIN_TAB_PAL_29_ADDRESS 0x0000a4f0
+#define PHY_BB_TX_GAIN_TAB_PAL_29_OFFSET 0x0000a4f0
+#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_30 */
+#define PHY_BB_TX_GAIN_TAB_PAL_30_ADDRESS 0x0000a4f4
+#define PHY_BB_TX_GAIN_TAB_PAL_30_OFFSET 0x0000a4f4
+#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_31 */
+#define PHY_BB_TX_GAIN_TAB_PAL_31_ADDRESS 0x0000a4f8
+#define PHY_BB_TX_GAIN_TAB_PAL_31_OFFSET 0x0000a4f8
+#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_tx_gain_tab_pal_32 */
+#define PHY_BB_TX_GAIN_TAB_PAL_32_ADDRESS 0x0000a4fc
+#define PHY_BB_TX_GAIN_TAB_PAL_32_OFFSET 0x0000a4fc
+#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_MSB 31
+#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_LSB 0
+#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_MASK 0xffffffff
+#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_caltx_gain_set_0 */
+#define PHY_BB_CALTX_GAIN_SET_0_ADDRESS 0x0000a518
+#define PHY_BB_CALTX_GAIN_SET_0_OFFSET 0x0000a518
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_2 */
+#define PHY_BB_CALTX_GAIN_SET_2_ADDRESS 0x0000a51c
+#define PHY_BB_CALTX_GAIN_SET_2_OFFSET 0x0000a51c
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_4 */
+#define PHY_BB_CALTX_GAIN_SET_4_ADDRESS 0x0000a520
+#define PHY_BB_CALTX_GAIN_SET_4_OFFSET 0x0000a520
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_6 */
+#define PHY_BB_CALTX_GAIN_SET_6_ADDRESS 0x0000a524
+#define PHY_BB_CALTX_GAIN_SET_6_OFFSET 0x0000a524
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_8 */
+#define PHY_BB_CALTX_GAIN_SET_8_ADDRESS 0x0000a528
+#define PHY_BB_CALTX_GAIN_SET_8_OFFSET 0x0000a528
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_10 */
+#define PHY_BB_CALTX_GAIN_SET_10_ADDRESS 0x0000a52c
+#define PHY_BB_CALTX_GAIN_SET_10_OFFSET 0x0000a52c
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_12 */
+#define PHY_BB_CALTX_GAIN_SET_12_ADDRESS 0x0000a530
+#define PHY_BB_CALTX_GAIN_SET_12_OFFSET 0x0000a530
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_14 */
+#define PHY_BB_CALTX_GAIN_SET_14_ADDRESS 0x0000a534
+#define PHY_BB_CALTX_GAIN_SET_14_OFFSET 0x0000a534
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_16 */
+#define PHY_BB_CALTX_GAIN_SET_16_ADDRESS 0x0000a538
+#define PHY_BB_CALTX_GAIN_SET_16_OFFSET 0x0000a538
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_18 */
+#define PHY_BB_CALTX_GAIN_SET_18_ADDRESS 0x0000a53c
+#define PHY_BB_CALTX_GAIN_SET_18_OFFSET 0x0000a53c
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_20 */
+#define PHY_BB_CALTX_GAIN_SET_20_ADDRESS 0x0000a540
+#define PHY_BB_CALTX_GAIN_SET_20_OFFSET 0x0000a540
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_22 */
+#define PHY_BB_CALTX_GAIN_SET_22_ADDRESS 0x0000a544
+#define PHY_BB_CALTX_GAIN_SET_22_OFFSET 0x0000a544
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_24 */
+#define PHY_BB_CALTX_GAIN_SET_24_ADDRESS 0x0000a548
+#define PHY_BB_CALTX_GAIN_SET_24_OFFSET 0x0000a548
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_26 */
+#define PHY_BB_CALTX_GAIN_SET_26_ADDRESS 0x0000a54c
+#define PHY_BB_CALTX_GAIN_SET_26_OFFSET 0x0000a54c
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_28 */
+#define PHY_BB_CALTX_GAIN_SET_28_ADDRESS 0x0000a550
+#define PHY_BB_CALTX_GAIN_SET_28_OFFSET 0x0000a550
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_caltx_gain_set_30 */
+#define PHY_BB_CALTX_GAIN_SET_30_ADDRESS 0x0000a554
+#define PHY_BB_CALTX_GAIN_SET_30_OFFSET 0x0000a554
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_MSB 13
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_LSB 0
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_MASK 0x00003fff
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_MSB 27
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_LSB 14
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_MASK 0x0fffc000
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiqcal_meas_b0 */
+#define PHY_BB_TXIQCAL_MEAS_B0_ADDRESS 0x0000a558
+#define PHY_BB_TXIQCAL_MEAS_B0_OFFSET 0x0000a558
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_MSB 11
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_LSB 0
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_MASK 0x00000fff
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_MSB 23
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_LSB 12
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_MASK 0x00fff000
+#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_GET(x) (((x) & 0x00fff000) >> 12)
+
+/* macros for BB_txiqcal_start */
+#define PHY_BB_TXIQCAL_START_ADDRESS 0x0000a6d8
+#define PHY_BB_TXIQCAL_START_OFFSET 0x0000a6d8
+#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_MSB 0
+#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_LSB 0
+#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_MASK 0x00000001
+#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_SET(x) (((x) << 0) & 0x00000001)
+
+/* macros for BB_txiqcal_control_0 */
+#define PHY_BB_TXIQCAL_CONTROL_0_ADDRESS 0x0000a6dc
+#define PHY_BB_TXIQCAL_CONTROL_0_OFFSET 0x0000a6dc
+#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_MSB 0
+#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_LSB 0
+#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_MASK 0x00000001
+#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_MSB 6
+#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_LSB 1
+#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_MASK 0x0000007e
+#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_GET(x) (((x) & 0x0000007e) >> 1)
+#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_SET(x) (((x) << 1) & 0x0000007e)
+#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_MSB 12
+#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_LSB 7
+#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_MASK 0x00001f80
+#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_GET(x) (((x) & 0x00001f80) >> 7)
+#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_SET(x) (((x) << 7) & 0x00001f80)
+#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_MSB 18
+#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_LSB 13
+#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_MASK 0x0007e000
+#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_GET(x) (((x) & 0x0007e000) >> 13)
+#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_SET(x) (((x) << 13) & 0x0007e000)
+#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_MSB 22
+#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_LSB 19
+#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_MASK 0x00780000
+#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_GET(x) (((x) & 0x00780000) >> 19)
+#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_SET(x) (((x) << 19) & 0x00780000)
+#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_MSB 29
+#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_LSB 23
+#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_MASK 0x3f800000
+#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_GET(x) (((x) & 0x3f800000) >> 23)
+#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_SET(x) (((x) << 23) & 0x3f800000)
+
+/* macros for BB_txiqcal_control_1 */
+#define PHY_BB_TXIQCAL_CONTROL_1_ADDRESS 0x0000a6e0
+#define PHY_BB_TXIQCAL_CONTROL_1_OFFSET 0x0000a6e0
+#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_MSB 5
+#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_LSB 0
+#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_MASK 0x0000003f
+#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_MSB 11
+#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_LSB 6
+#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_MASK 0x00000fc0
+#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_MSB 17
+#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_LSB 12
+#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_MASK 0x0003f000
+#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_MSB 24
+#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_LSB 18
+#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_MASK 0x01fc0000
+#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_GET(x) (((x) & 0x01fc0000) >> 18)
+#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_SET(x) (((x) << 18) & 0x01fc0000)
+
+/* macros for BB_txiqcal_control_2 */
+#define PHY_BB_TXIQCAL_CONTROL_2_ADDRESS 0x0000a6e4
+#define PHY_BB_TXIQCAL_CONTROL_2_OFFSET 0x0000a6e4
+#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_MSB 3
+#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_LSB 0
+#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_MASK 0x0000000f
+#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_GET(x) (((x) & 0x0000000f) >> 0)
+#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_SET(x) (((x) << 0) & 0x0000000f)
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_MSB 8
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_LSB 4
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_MASK 0x000001f0
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_GET(x) (((x) & 0x000001f0) >> 4)
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_SET(x) (((x) << 4) & 0x000001f0)
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_MSB 13
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_LSB 9
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_MASK 0x00003e00
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_GET(x) (((x) & 0x00003e00) >> 9)
+#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_SET(x) (((x) << 9) & 0x00003e00)
+
+/* macros for BB_txiqcal_control_3 */
+#define PHY_BB_TXIQCAL_CONTROL_3_ADDRESS 0x0000a6e8
+#define PHY_BB_TXIQCAL_CONTROL_3_OFFSET 0x0000a6e8
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_MSB 5
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_LSB 0
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_MASK 0x0000003f
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_MSB 11
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_LSB 6
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_MASK 0x00000fc0
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_MSB 21
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_LSB 12
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_MASK 0x003ff000
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_MSB 23
+#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_LSB 22
+#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_MASK 0x00c00000
+#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_MSB 24
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_LSB 24
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_MASK 0x01000000
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_SET(x) (((x) << 24) & 0x01000000)
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_MSB 26
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_LSB 25
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_MASK 0x06000000
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_GET(x) (((x) & 0x06000000) >> 25)
+#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_SET(x) (((x) << 25) & 0x06000000)
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_MSB 28
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_LSB 27
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_MASK 0x18000000
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_GET(x) (((x) & 0x18000000) >> 27)
+#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_SET(x) (((x) << 27) & 0x18000000)
+#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_MSB 30
+#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_LSB 29
+#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_MASK 0x60000000
+#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_GET(x) (((x) & 0x60000000) >> 29)
+#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_SET(x) (((x) << 29) & 0x60000000)
+#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_MSB 31
+#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_LSB 31
+#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_MASK 0x80000000
+#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_GET(x) (((x) & 0x80000000) >> 31)
+#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_SET(x) (((x) << 31) & 0x80000000)
+
+/* macros for BB_txiq_corr_coeff_01_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_ADDRESS 0x0000a6ec
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_OFFSET 0x0000a6ec
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_23_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_ADDRESS 0x0000a6f0
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_OFFSET 0x0000a6f0
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_45_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_ADDRESS 0x0000a6f4
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_OFFSET 0x0000a6f4
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_67_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_ADDRESS 0x0000a6f8
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_OFFSET 0x0000a6f8
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_89_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_ADDRESS 0x0000a6fc
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_OFFSET 0x0000a6fc
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_ab_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_ADDRESS 0x0000a700
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_OFFSET 0x0000a700
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_cd_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_ADDRESS 0x0000a704
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_OFFSET 0x0000a704
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_txiq_corr_coeff_ef_b0 */
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_ADDRESS 0x0000a708
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_OFFSET 0x0000a708
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_MSB 13
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_LSB 0
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_MASK 0x00003fff
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_GET(x) (((x) & 0x00003fff) >> 0)
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_SET(x) (((x) << 0) & 0x00003fff)
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_MSB 27
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_LSB 14
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_MASK 0x0fffc000
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_GET(x) (((x) & 0x0fffc000) >> 14)
+#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_SET(x) (((x) << 14) & 0x0fffc000)
+
+/* macros for BB_cal_rxbb_gain_tbl_0 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_ADDRESS 0x0000a70c
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_OFFSET 0x0000a70c
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_4 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_ADDRESS 0x0000a710
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_OFFSET 0x0000a710
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_8 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_ADDRESS 0x0000a714
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_OFFSET 0x0000a714
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_12 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_ADDRESS 0x0000a718
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_OFFSET 0x0000a718
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_16 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_ADDRESS 0x0000a71c
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_OFFSET 0x0000a71c
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_20 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_ADDRESS 0x0000a720
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_OFFSET 0x0000a720
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_MSB 11
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_LSB 6
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_MASK 0x00000fc0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_MSB 17
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_LSB 12
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_MASK 0x0003f000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_SET(x) (((x) << 12) & 0x0003f000)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_MSB 23
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_LSB 18
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_MASK 0x00fc0000
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_GET(x) (((x) & 0x00fc0000) >> 18)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_SET(x) (((x) << 18) & 0x00fc0000)
+
+/* macros for BB_cal_rxbb_gain_tbl_24 */
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_ADDRESS 0x0000a724
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_OFFSET 0x0000a724
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_MSB 5
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_LSB 0
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_MASK 0x0000003f
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_SET(x) (((x) << 0) & 0x0000003f)
+
+/* macros for BB_txiqcal_status_b0 */
+#define PHY_BB_TXIQCAL_STATUS_B0_ADDRESS 0x0000a728
+#define PHY_BB_TXIQCAL_STATUS_B0_OFFSET 0x0000a728
+#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_MSB 0
+#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_LSB 0
+#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_MASK 0x00000001
+#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_MSB 5
+#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_LSB 1
+#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_MASK 0x0000003e
+#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_GET(x) (((x) & 0x0000003e) >> 1)
+#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_MSB 11
+#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_LSB 6
+#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_MASK 0x00000fc0
+#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_MSB 17
+#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_LSB 12
+#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_MASK 0x0003f000
+#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_GET(x) (((x) & 0x0003f000) >> 12)
+#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_MSB 24
+#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_LSB 18
+#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_MASK 0x01fc0000
+#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_GET(x) (((x) & 0x01fc0000) >> 18)
+
+/* macros for BB_paprd_trainer_cntl1 */
+#define PHY_BB_PAPRD_TRAINER_CNTL1_ADDRESS 0x0000a72c
+#define PHY_BB_PAPRD_TRAINER_CNTL1_OFFSET 0x0000a72c
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_MSB 0
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_LSB 0
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_MASK 0x00000001
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_MSB 7
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_LSB 1
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_MASK 0x000000fe
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_GET(x) (((x) & 0x000000fe) >> 1)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_SET(x) (((x) << 1) & 0x000000fe)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_MSB 8
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_LSB 8
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_MASK 0x00000100
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_GET(x) (((x) & 0x00000100) >> 8)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_SET(x) (((x) << 8) & 0x00000100)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_MSB 9
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_LSB 9
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_MASK 0x00000200
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_GET(x) (((x) & 0x00000200) >> 9)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_SET(x) (((x) << 9) & 0x00000200)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_MSB 10
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_LSB 10
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_MASK 0x00000400
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_GET(x) (((x) & 0x00000400) >> 10)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_SET(x) (((x) << 10) & 0x00000400)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_MSB 11
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_LSB 11
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_MASK 0x00000800
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_GET(x) (((x) & 0x00000800) >> 11)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_SET(x) (((x) << 11) & 0x00000800)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_MSB 18
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_LSB 12
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_MASK 0x0007f000
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_GET(x) (((x) & 0x0007f000) >> 12)
+#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_SET(x) (((x) << 12) & 0x0007f000)
+
+/* macros for BB_paprd_trainer_cntl2 */
+#define PHY_BB_PAPRD_TRAINER_CNTL2_ADDRESS 0x0000a730
+#define PHY_BB_PAPRD_TRAINER_CNTL2_OFFSET 0x0000a730
+#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_MSB 31
+#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_LSB 0
+#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_MASK 0xffffffff
+#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_GET(x) (((x) & 0xffffffff) >> 0)
+#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_paprd_trainer_cntl3 */
+#define PHY_BB_PAPRD_TRAINER_CNTL3_ADDRESS 0x0000a734
+#define PHY_BB_PAPRD_TRAINER_CNTL3_OFFSET 0x0000a734
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_MSB 5
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_LSB 0
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_MASK 0x0000003f
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_MSB 11
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_LSB 6
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_MASK 0x00000fc0
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_MSB 16
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_LSB 12
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_MASK 0x0001f000
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_MSB 19
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_LSB 17
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_MASK 0x000e0000
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_GET(x) (((x) & 0x000e0000) >> 17)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_SET(x) (((x) << 17) & 0x000e0000)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_MSB 23
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_LSB 20
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_MASK 0x00f00000
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_GET(x) (((x) & 0x00f00000) >> 20)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_SET(x) (((x) << 20) & 0x00f00000)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_MSB 27
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_LSB 24
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_MASK 0x0f000000
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_GET(x) (((x) & 0x0f000000) >> 24)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_SET(x) (((x) << 24) & 0x0f000000)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_MSB 28
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_LSB 28
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_MASK 0x10000000
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_GET(x) (((x) & 0x10000000) >> 28)
+#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_SET(x) (((x) << 28) & 0x10000000)
+
+/* macros for BB_paprd_trainer_cntl4 */
+#define PHY_BB_PAPRD_TRAINER_CNTL4_ADDRESS 0x0000a738
+#define PHY_BB_PAPRD_TRAINER_CNTL4_OFFSET 0x0000a738
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_MSB 11
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_LSB 0
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_MASK 0x00000fff
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_SET(x) (((x) << 0) & 0x00000fff)
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_MSB 15
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_LSB 12
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_MASK 0x0000f000
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_GET(x) (((x) & 0x0000f000) >> 12)
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_SET(x) (((x) << 12) & 0x0000f000)
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_MSB 25
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_LSB 16
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_MASK 0x03ff0000
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_GET(x) (((x) & 0x03ff0000) >> 16)
+#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_SET(x) (((x) << 16) & 0x03ff0000)
+
+/* macros for BB_paprd_trainer_stat1 */
+#define PHY_BB_PAPRD_TRAINER_STAT1_ADDRESS 0x0000a73c
+#define PHY_BB_PAPRD_TRAINER_STAT1_OFFSET 0x0000a73c
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_MSB 0
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_LSB 0
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_MASK 0x00000001
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_MSB 1
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_LSB 1
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_MASK 0x00000002
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_MSB 2
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_LSB 2
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_MASK 0x00000004
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_GET(x) (((x) & 0x00000004) >> 2)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_MSB 3
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_LSB 3
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_MASK 0x00000008
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_GET(x) (((x) & 0x00000008) >> 3)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_MSB 8
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_LSB 4
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_MASK 0x000001f0
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_GET(x) (((x) & 0x000001f0) >> 4)
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_MSB 16
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_LSB 9
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_MASK 0x0001fe00
+#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_GET(x) (((x) & 0x0001fe00) >> 9)
+
+/* macros for BB_paprd_trainer_stat2 */
+#define PHY_BB_PAPRD_TRAINER_STAT2_ADDRESS 0x0000a740
+#define PHY_BB_PAPRD_TRAINER_STAT2_OFFSET 0x0000a740
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_MSB 15
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_LSB 0
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_MASK 0x0000ffff
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_GET(x) (((x) & 0x0000ffff) >> 0)
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_MSB 20
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_LSB 16
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_MASK 0x001f0000
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_GET(x) (((x) & 0x001f0000) >> 16)
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_MSB 22
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_LSB 21
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_MASK 0x00600000
+#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_GET(x) (((x) & 0x00600000) >> 21)
+
+/* macros for BB_paprd_trainer_stat3 */
+#define PHY_BB_PAPRD_TRAINER_STAT3_ADDRESS 0x0000a744
+#define PHY_BB_PAPRD_TRAINER_STAT3_OFFSET 0x0000a744
+#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_MSB 19
+#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_LSB 0
+#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_MASK 0x000fffff
+#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_GET(x) (((x) & 0x000fffff) >> 0)
+
+/* macros for BB_fcal_1 */
+#define PHY_BB_FCAL_1_ADDRESS 0x0000a7d8
+#define PHY_BB_FCAL_1_OFFSET 0x0000a7d8
+#define PHY_BB_FCAL_1_FLC_PB_FSTEP_MSB 9
+#define PHY_BB_FCAL_1_FLC_PB_FSTEP_LSB 0
+#define PHY_BB_FCAL_1_FLC_PB_FSTEP_MASK 0x000003ff
+#define PHY_BB_FCAL_1_FLC_PB_FSTEP_GET(x) (((x) & 0x000003ff) >> 0)
+#define PHY_BB_FCAL_1_FLC_PB_FSTEP_SET(x) (((x) << 0) & 0x000003ff)
+#define PHY_BB_FCAL_1_FLC_SB_FSTEP_MSB 19
+#define PHY_BB_FCAL_1_FLC_SB_FSTEP_LSB 10
+#define PHY_BB_FCAL_1_FLC_SB_FSTEP_MASK 0x000ffc00
+#define PHY_BB_FCAL_1_FLC_SB_FSTEP_GET(x) (((x) & 0x000ffc00) >> 10)
+#define PHY_BB_FCAL_1_FLC_SB_FSTEP_SET(x) (((x) << 10) & 0x000ffc00)
+#define PHY_BB_FCAL_1_FLC_PB_ATTEN_MSB 24
+#define PHY_BB_FCAL_1_FLC_PB_ATTEN_LSB 20
+#define PHY_BB_FCAL_1_FLC_PB_ATTEN_MASK 0x01f00000
+#define PHY_BB_FCAL_1_FLC_PB_ATTEN_GET(x) (((x) & 0x01f00000) >> 20)
+#define PHY_BB_FCAL_1_FLC_PB_ATTEN_SET(x) (((x) << 20) & 0x01f00000)
+#define PHY_BB_FCAL_1_FLC_SB_ATTEN_MSB 29
+#define PHY_BB_FCAL_1_FLC_SB_ATTEN_LSB 25
+#define PHY_BB_FCAL_1_FLC_SB_ATTEN_MASK 0x3e000000
+#define PHY_BB_FCAL_1_FLC_SB_ATTEN_GET(x) (((x) & 0x3e000000) >> 25)
+#define PHY_BB_FCAL_1_FLC_SB_ATTEN_SET(x) (((x) << 25) & 0x3e000000)
+
+/* macros for BB_fcal_2_b0 */
+#define PHY_BB_FCAL_2_B0_ADDRESS 0x0000a7dc
+#define PHY_BB_FCAL_2_B0_OFFSET 0x0000a7dc
+#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_MSB 2
+#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_LSB 0
+#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_MASK 0x00000007
+#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_GET(x) (((x) & 0x00000007) >> 0)
+#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_SET(x) (((x) << 0) & 0x00000007)
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_MSB 7
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_LSB 3
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_MASK 0x000000f8
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_GET(x) (((x) & 0x000000f8) >> 3)
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_SET(x) (((x) << 3) & 0x000000f8)
+#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_MSB 9
+#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_LSB 8
+#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_MASK 0x00000300
+#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_GET(x) (((x) & 0x00000300) >> 8)
+#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_SET(x) (((x) << 8) & 0x00000300)
+#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_MSB 12
+#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_LSB 10
+#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_MASK 0x00001c00
+#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_GET(x) (((x) & 0x00001c00) >> 10)
+#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_SET(x) (((x) << 10) & 0x00001c00)
+#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_MSB 14
+#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_LSB 13
+#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_MASK 0x00006000
+#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_GET(x) (((x) & 0x00006000) >> 13)
+#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_SET(x) (((x) << 13) & 0x00006000)
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_MSB 15
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_LSB 15
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_MASK 0x00008000
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_GET(x) (((x) & 0x00008000) >> 15)
+#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_SET(x) (((x) << 15) & 0x00008000)
+#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_MSB 18
+#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_LSB 16
+#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_MASK 0x00070000
+#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_GET(x) (((x) & 0x00070000) >> 16)
+#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_SET(x) (((x) << 16) & 0x00070000)
+#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_MSB 24
+#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_LSB 20
+#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_MASK 0x01f00000
+#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_GET(x) (((x) & 0x01f00000) >> 20)
+
+/* macros for BB_radar_bw_filter */
+#define PHY_BB_RADAR_BW_FILTER_ADDRESS 0x0000a7e0
+#define PHY_BB_RADAR_BW_FILTER_OFFSET 0x0000a7e0
+#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_MSB 0
+#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_LSB 0
+#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_MASK 0x00000001
+#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_MSB 1
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_LSB 1
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_MASK 0x00000002
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_GET(x) (((x) & 0x00000002) >> 1)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_SET(x) (((x) << 1) & 0x00000002)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_MSB 3
+#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_LSB 2
+#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_MASK 0x0000000c
+#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_MSB 5
+#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_LSB 4
+#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_MASK 0x00000030
+#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_MSB 14
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_LSB 8
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_MASK 0x00007f00
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_GET(x) (((x) & 0x00007f00) >> 8)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_SET(x) (((x) << 8) & 0x00007f00)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_MSB 20
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_LSB 15
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_MASK 0x001f8000
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_GET(x) (((x) & 0x001f8000) >> 15)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_SET(x) (((x) << 15) & 0x001f8000)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_MSB 26
+#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_LSB 21
+#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_MASK 0x07e00000
+#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_GET(x) (((x) & 0x07e00000) >> 21)
+#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_SET(x) (((x) << 21) & 0x07e00000)
+
+/* macros for BB_dft_tone_ctrl_b0 */
+#define PHY_BB_DFT_TONE_CTRL_B0_ADDRESS 0x0000a7e4
+#define PHY_BB_DFT_TONE_CTRL_B0_OFFSET 0x0000a7e4
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_MSB 0
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_LSB 0
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_MASK 0x00000001
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_MSB 3
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_LSB 2
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_MASK 0x0000000c
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_GET(x) (((x) & 0x0000000c) >> 2)
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_SET(x) (((x) << 2) & 0x0000000c)
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_MSB 12
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_LSB 4
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_MASK 0x00001ff0
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_GET(x) (((x) & 0x00001ff0) >> 4)
+#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_SET(x) (((x) << 4) & 0x00001ff0)
+
+/* macros for BB_therm_adc_1 */
+#define PHY_BB_THERM_ADC_1_ADDRESS 0x0000a7e8
+#define PHY_BB_THERM_ADC_1_OFFSET 0x0000a7e8
+#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_MSB 7
+#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_LSB 0
+#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_MASK 0x000000ff
+#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_MSB 15
+#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_LSB 8
+#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_MASK 0x0000ff00
+#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_SET(x) (((x) << 8) & 0x0000ff00)
+#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_MSB 23
+#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_LSB 16
+#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_MASK 0x00ff0000
+#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_GET(x) (((x) & 0x00ff0000) >> 16)
+#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_SET(x) (((x) << 16) & 0x00ff0000)
+#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_MSB 25
+#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_LSB 24
+#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_MASK 0x03000000
+#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_GET(x) (((x) & 0x03000000) >> 24)
+#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_SET(x) (((x) << 24) & 0x03000000)
+#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_MSB 26
+#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_LSB 26
+#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_MASK 0x04000000
+#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_SET(x) (((x) << 26) & 0x04000000)
+#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_MSB 27
+#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_LSB 27
+#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_MASK 0x08000000
+#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_GET(x) (((x) & 0x08000000) >> 27)
+#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_SET(x) (((x) << 27) & 0x08000000)
+
+/* macros for BB_therm_adc_2 */
+#define PHY_BB_THERM_ADC_2_ADDRESS 0x0000a7ec
+#define PHY_BB_THERM_ADC_2_OFFSET 0x0000a7ec
+#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_MSB 11
+#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_LSB 0
+#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_MASK 0x00000fff
+#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_GET(x) (((x) & 0x00000fff) >> 0)
+#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_SET(x) (((x) << 0) & 0x00000fff)
+#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_MSB 21
+#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_LSB 12
+#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_MASK 0x003ff000
+#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_GET(x) (((x) & 0x003ff000) >> 12)
+#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_SET(x) (((x) << 12) & 0x003ff000)
+#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_MSB 31
+#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_LSB 22
+#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_MASK 0xffc00000
+#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_GET(x) (((x) & 0xffc00000) >> 22)
+#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_SET(x) (((x) << 22) & 0xffc00000)
+
+/* macros for BB_therm_adc_3 */
+#define PHY_BB_THERM_ADC_3_ADDRESS 0x0000a7f0
+#define PHY_BB_THERM_ADC_3_OFFSET 0x0000a7f0
+#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_MSB 7
+#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_LSB 0
+#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_MASK 0x000000ff
+#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_SET(x) (((x) << 0) & 0x000000ff)
+#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_MSB 16
+#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_LSB 8
+#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_MASK 0x0001ff00
+#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_GET(x) (((x) & 0x0001ff00) >> 8)
+#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_SET(x) (((x) << 8) & 0x0001ff00)
+#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_MSB 29
+#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_LSB 17
+#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_MASK 0x3ffe0000
+#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_GET(x) (((x) & 0x3ffe0000) >> 17)
+#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_SET(x) (((x) << 17) & 0x3ffe0000)
+
+/* macros for BB_therm_adc_4 */
+#define PHY_BB_THERM_ADC_4_ADDRESS 0x0000a7f4
+#define PHY_BB_THERM_ADC_4_OFFSET 0x0000a7f4
+#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_MSB 7
+#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_LSB 0
+#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_MASK 0x000000ff
+#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_MSB 15
+#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_LSB 8
+#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_MASK 0x0000ff00
+#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_GET(x) (((x) & 0x0000ff00) >> 8)
+#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_MSB 23
+#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_LSB 16
+#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_MASK 0x00ff0000
+#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_GET(x) (((x) & 0x00ff0000) >> 16)
+
+/* macros for BB_tx_forced_gain */
+#define PHY_BB_TX_FORCED_GAIN_ADDRESS 0x0000a7f8
+#define PHY_BB_TX_FORCED_GAIN_OFFSET 0x0000a7f8
+#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_MSB 0
+#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_LSB 0
+#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_MASK 0x00000001
+#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_GET(x) (((x) & 0x00000001) >> 0)
+#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_SET(x) (((x) << 0) & 0x00000001)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_MSB 3
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_LSB 1
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_MASK 0x0000000e
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_GET(x) (((x) & 0x0000000e) >> 1)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_SET(x) (((x) << 1) & 0x0000000e)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_MSB 5
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_LSB 4
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_MASK 0x00000030
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_GET(x) (((x) & 0x00000030) >> 4)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_SET(x) (((x) << 4) & 0x00000030)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_MSB 9
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_LSB 6
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_MASK 0x000003c0
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_GET(x) (((x) & 0x000003c0) >> 6)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_SET(x) (((x) << 6) & 0x000003c0)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_MSB 13
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_LSB 10
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_MASK 0x00003c00
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_GET(x) (((x) & 0x00003c00) >> 10)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_SET(x) (((x) << 10) & 0x00003c00)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_MSB 17
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_LSB 14
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_MASK 0x0003c000
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_GET(x) (((x) & 0x0003c000) >> 14)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_SET(x) (((x) << 14) & 0x0003c000)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_MSB 21
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_LSB 18
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_MASK 0x003c0000
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_GET(x) (((x) & 0x003c0000) >> 18)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_SET(x) (((x) << 18) & 0x003c0000)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_MSB 23
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_LSB 22
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_MASK 0x00c00000
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_GET(x) (((x) & 0x00c00000) >> 22)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_SET(x) (((x) << 22) & 0x00c00000)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_MSB 24
+#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_LSB 24
+#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_MASK 0x01000000
+#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_GET(x) (((x) & 0x01000000) >> 24)
+#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_SET(x) (((x) << 24) & 0x01000000)
+
+/* macros for BB_eco_ctrl */
+#define PHY_BB_ECO_CTRL_ADDRESS 0x0000a7fc
+#define PHY_BB_ECO_CTRL_OFFSET 0x0000a7fc
+#define PHY_BB_ECO_CTRL_ECO_CTRL_MSB 7
+#define PHY_BB_ECO_CTRL_ECO_CTRL_LSB 0
+#define PHY_BB_ECO_CTRL_ECO_CTRL_MASK 0x000000ff
+#define PHY_BB_ECO_CTRL_ECO_CTRL_GET(x) (((x) & 0x000000ff) >> 0)
+#define PHY_BB_ECO_CTRL_ECO_CTRL_SET(x) (((x) << 0) & 0x000000ff)
+
+/* macros for BB_gain_force_max_gains_b1 */
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_ADDRESS 0x0000a848
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_OFFSET 0x0000a848
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_MSB 13
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_LSB 7
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_MASK 0x00003f80
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_GET(x) (((x) & 0x00003f80) >> 7)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_SET(x) (((x) << 7) & 0x00003f80)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_MSB 20
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_LSB 14
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_MASK 0x001fc000
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_GET(x) (((x) & 0x001fc000) >> 14)
+#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_SET(x) (((x) << 14) & 0x001fc000)
+
+/* macros for BB_gains_min_offsets_b1 */
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_ADDRESS 0x0000a84c
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_OFFSET 0x0000a84c
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_MSB 24
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_LSB 17
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_MASK 0x01fe0000
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_GET(x) (((x) & 0x01fe0000) >> 17)
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_SET(x) (((x) << 17) & 0x01fe0000)
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_MSB 25
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_LSB 25
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_MASK 0x02000000
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_GET(x) (((x) & 0x02000000) >> 25)
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_SET(x) (((x) << 25) & 0x02000000)
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_MSB 26
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_LSB 26
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_MASK 0x04000000
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_GET(x) (((x) & 0x04000000) >> 26)
+#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_SET(x) (((x) << 26) & 0x04000000)
+
+/* macros for BB_rx_ocgain2 */
+#define PHY_BB_RX_OCGAIN2_ADDRESS 0x0000aa00
+#define PHY_BB_RX_OCGAIN2_OFFSET 0x0000aa00
+#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_MSB 31
+#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_LSB 0
+#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_MASK 0xffffffff
+#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_SET(x) (((x) << 0) & 0xffffffff)
+
+/* macros for BB_ext_atten_switch_ctl_b1 */
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_ADDRESS 0x0000b20c
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_OFFSET 0x0000b20c
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_MSB 5
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_LSB 0
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_MASK 0x0000003f
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_GET(x) (((x) & 0x0000003f) >> 0)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_SET(x) (((x) << 0) & 0x0000003f)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_MSB 11
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_LSB 6
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_MASK 0x00000fc0
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_GET(x) (((x) & 0x00000fc0) >> 6)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_SET(x) (((x) << 6) & 0x00000fc0)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_MSB 16
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_LSB 12
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_MASK 0x0001f000
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_GET(x) (((x) & 0x0001f000) >> 12)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_SET(x) (((x) << 12) & 0x0001f000)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_MSB 21
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_LSB 17
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_MASK 0x003e0000
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_GET(x) (((x) & 0x003e0000) >> 17)
+#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_SET(x) (((x) << 17) & 0x003e0000)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct bb_lc_reg_reg_s {
+ volatile char pad__0[0x9800]; /* 0x0 - 0x9800 */
+ volatile unsigned int BB_test_controls; /* 0x9800 - 0x9804 */
+ volatile unsigned int BB_gen_controls; /* 0x9804 - 0x9808 */
+ volatile unsigned int BB_test_controls_status; /* 0x9808 - 0x980c */
+ volatile unsigned int BB_timing_controls_1; /* 0x980c - 0x9810 */
+ volatile unsigned int BB_timing_controls_2; /* 0x9810 - 0x9814 */
+ volatile unsigned int BB_timing_controls_3; /* 0x9814 - 0x9818 */
+ volatile unsigned int BB_D2_chip_id; /* 0x9818 - 0x981c */
+ volatile unsigned int BB_active; /* 0x981c - 0x9820 */
+ volatile unsigned int BB_tx_timing_1; /* 0x9820 - 0x9824 */
+ volatile unsigned int BB_tx_timing_2; /* 0x9824 - 0x9828 */
+ volatile unsigned int BB_tx_timing_3; /* 0x9828 - 0x982c */
+ volatile unsigned int BB_addac_parallel_control; /* 0x982c - 0x9830 */
+ volatile char pad__1[0x4]; /* 0x9830 - 0x9834 */
+ volatile unsigned int BB_xpa_timing_control; /* 0x9834 - 0x9838 */
+ volatile unsigned int BB_misc_pa_control; /* 0x9838 - 0x983c */
+ volatile unsigned int BB_tstdac_constant; /* 0x983c - 0x9840 */
+ volatile unsigned int BB_find_signal_low; /* 0x9840 - 0x9844 */
+ volatile unsigned int BB_settling_time; /* 0x9844 - 0x9848 */
+ volatile unsigned int BB_gain_force_max_gains_b0; /* 0x9848 - 0x984c */
+ volatile unsigned int BB_gains_min_offsets_b0; /* 0x984c - 0x9850 */
+ volatile unsigned int BB_desired_sigsize; /* 0x9850 - 0x9854 */
+ volatile unsigned int BB_timing_control_3a; /* 0x9854 - 0x9858 */
+ volatile unsigned int BB_find_signal; /* 0x9858 - 0x985c */
+ volatile unsigned int BB_agc; /* 0x985c - 0x9860 */
+ volatile unsigned int BB_agc_control; /* 0x9860 - 0x9864 */
+ volatile unsigned int BB_cca_b0; /* 0x9864 - 0x9868 */
+ volatile unsigned int BB_sfcorr; /* 0x9868 - 0x986c */
+ volatile unsigned int BB_self_corr_low; /* 0x986c - 0x9870 */
+ volatile char pad__2[0x4]; /* 0x9870 - 0x9874 */
+ volatile unsigned int BB_synth_control; /* 0x9874 - 0x9878 */
+ volatile unsigned int BB_addac_clk_select; /* 0x9878 - 0x987c */
+ volatile unsigned int BB_pll_cntl; /* 0x987c - 0x9880 */
+ volatile char pad__3[0x80]; /* 0x9880 - 0x9900 */
+ volatile unsigned int BB_vit_spur_mask_A; /* 0x9900 - 0x9904 */
+ volatile unsigned int BB_vit_spur_mask_B; /* 0x9904 - 0x9908 */
+ volatile unsigned int BB_pilot_spur_mask; /* 0x9908 - 0x990c */
+ volatile unsigned int BB_chan_spur_mask; /* 0x990c - 0x9910 */
+ volatile unsigned int BB_spectral_scan; /* 0x9910 - 0x9914 */
+ volatile unsigned int BB_analog_power_on_time; /* 0x9914 - 0x9918 */
+ volatile unsigned int BB_search_start_delay; /* 0x9918 - 0x991c */
+ volatile unsigned int BB_max_rx_length; /* 0x991c - 0x9920 */
+ volatile unsigned int BB_timing_control_4; /* 0x9920 - 0x9924 */
+ volatile unsigned int BB_timing_control_5; /* 0x9924 - 0x9928 */
+ volatile unsigned int BB_phyonly_warm_reset; /* 0x9928 - 0x992c */
+ volatile unsigned int BB_phyonly_control; /* 0x992c - 0x9930 */
+ volatile char pad__4[0x4]; /* 0x9930 - 0x9934 */
+ volatile unsigned int BB_powertx_rate1; /* 0x9934 - 0x9938 */
+ volatile unsigned int BB_powertx_rate2; /* 0x9938 - 0x993c */
+ volatile unsigned int BB_powertx_max; /* 0x993c - 0x9940 */
+ volatile unsigned int BB_extension_radar; /* 0x9940 - 0x9944 */
+ volatile unsigned int BB_frame_control; /* 0x9944 - 0x9948 */
+ volatile unsigned int BB_timing_control_6; /* 0x9948 - 0x994c */
+ volatile unsigned int BB_spur_mask_controls; /* 0x994c - 0x9950 */
+ volatile unsigned int BB_rx_iq_corr_b0; /* 0x9950 - 0x9954 */
+ volatile unsigned int BB_radar_detection; /* 0x9954 - 0x9958 */
+ volatile unsigned int BB_radar_detection_2; /* 0x9958 - 0x995c */
+ volatile unsigned int BB_tx_phase_ramp_b0; /* 0x995c - 0x9960 */
+ volatile unsigned int BB_switch_table_chn_b0; /* 0x9960 - 0x9964 */
+ volatile unsigned int BB_switch_table_com1; /* 0x9964 - 0x9968 */
+ volatile unsigned int BB_cca_ctrl_2_b0; /* 0x9968 - 0x996c */
+ volatile unsigned int BB_switch_table_com2; /* 0x996c - 0x9970 */
+ volatile unsigned int BB_restart; /* 0x9970 - 0x9974 */
+ volatile char pad__5[0x4]; /* 0x9974 - 0x9978 */
+ volatile unsigned int BB_scrambler_seed; /* 0x9978 - 0x997c */
+ volatile unsigned int BB_rfbus_request; /* 0x997c - 0x9980 */
+ volatile char pad__6[0x20]; /* 0x9980 - 0x99a0 */
+ volatile unsigned int BB_timing_control_11; /* 0x99a0 - 0x99a4 */
+ volatile unsigned int BB_multichain_enable; /* 0x99a4 - 0x99a8 */
+ volatile unsigned int BB_multichain_control; /* 0x99a8 - 0x99ac */
+ volatile unsigned int BB_multichain_gain_ctrl; /* 0x99ac - 0x99b0 */
+ volatile char pad__7[0x4]; /* 0x99b0 - 0x99b4 */
+ volatile unsigned int BB_adc_gain_dc_corr_b0; /* 0x99b4 - 0x99b8 */
+ volatile unsigned int BB_ext_chan_pwr_thr_1; /* 0x99b8 - 0x99bc */
+ volatile unsigned int BB_ext_chan_pwr_thr_2_b0; /* 0x99bc - 0x99c0 */
+ volatile unsigned int BB_ext_chan_scorr_thr; /* 0x99c0 - 0x99c4 */
+ volatile unsigned int BB_ext_chan_detect_win; /* 0x99c4 - 0x99c8 */
+ volatile unsigned int BB_pwr_thr_20_40_det; /* 0x99c8 - 0x99cc */
+ volatile char pad__8[0x4]; /* 0x99cc - 0x99d0 */
+ volatile unsigned int BB_short_gi_delta_slope; /* 0x99d0 - 0x99d4 */
+ volatile char pad__9[0x8]; /* 0x99d4 - 0x99dc */
+ volatile unsigned int BB_chaninfo_ctrl; /* 0x99dc - 0x99e0 */
+ volatile unsigned int BB_heavy_clip_ctrl; /* 0x99e0 - 0x99e4 */
+ volatile unsigned int BB_heavy_clip_20; /* 0x99e4 - 0x99e8 */
+ volatile unsigned int BB_heavy_clip_40; /* 0x99e8 - 0x99ec */
+ volatile unsigned int BB_rifs_srch; /* 0x99ec - 0x99f0 */
+ volatile unsigned int BB_iq_adc_cal_mode; /* 0x99f0 - 0x99f4 */
+ volatile char pad__10[0x8]; /* 0x99f4 - 0x99fc */
+ volatile unsigned int BB_per_chain_csd; /* 0x99fc - 0x9a00 */
+ volatile unsigned int BB_rx_ocgain[128]; /* 0x9a00 - 0x9c00 */
+ volatile unsigned int BB_tx_crc; /* 0x9c00 - 0x9c04 */
+ volatile char pad__11[0xc]; /* 0x9c04 - 0x9c10 */
+ volatile unsigned int BB_iq_adc_meas_0_b0; /* 0x9c10 - 0x9c14 */
+ volatile unsigned int BB_iq_adc_meas_1_b0; /* 0x9c14 - 0x9c18 */
+ volatile unsigned int BB_iq_adc_meas_2_b0; /* 0x9c18 - 0x9c1c */
+ volatile unsigned int BB_iq_adc_meas_3_b0; /* 0x9c1c - 0x9c20 */
+ volatile unsigned int BB_rfbus_grant; /* 0x9c20 - 0x9c24 */
+ volatile unsigned int BB_tstadc; /* 0x9c24 - 0x9c28 */
+ volatile unsigned int BB_tstdac; /* 0x9c28 - 0x9c2c */
+ volatile char pad__12[0x4]; /* 0x9c2c - 0x9c30 */
+ volatile unsigned int BB_illegal_tx_rate; /* 0x9c30 - 0x9c34 */
+ volatile unsigned int BB_spur_report_b0; /* 0x9c34 - 0x9c38 */
+ volatile unsigned int BB_channel_status; /* 0x9c38 - 0x9c3c */
+ volatile unsigned int BB_rssi_b0; /* 0x9c3c - 0x9c40 */
+ volatile unsigned int BB_spur_est_cck_report_b0; /* 0x9c40 - 0x9c44 */
+ volatile char pad__13[0x68]; /* 0x9c44 - 0x9cac */
+ volatile unsigned int BB_chan_info_noise_pwr; /* 0x9cac - 0x9cb0 */
+ volatile unsigned int BB_chan_info_gain_diff; /* 0x9cb0 - 0x9cb4 */
+ volatile unsigned int BB_chan_info_fine_timing; /* 0x9cb4 - 0x9cb8 */
+ volatile unsigned int BB_chan_info_gain_b0; /* 0x9cb8 - 0x9cbc */
+ volatile unsigned int BB_chan_info_chan_tab_b0[60]; /* 0x9cbc - 0x9dac */
+ volatile char pad__14[0x38]; /* 0x9dac - 0x9de4 */
+ volatile unsigned int BB_paprd_am2am_mask; /* 0x9de4 - 0x9de8 */
+ volatile unsigned int BB_paprd_am2pm_mask; /* 0x9de8 - 0x9dec */
+ volatile unsigned int BB_paprd_ht40_mask; /* 0x9dec - 0x9df0 */
+ volatile unsigned int BB_paprd_ctrl0; /* 0x9df0 - 0x9df4 */
+ volatile unsigned int BB_paprd_ctrl1; /* 0x9df4 - 0x9df8 */
+ volatile unsigned int BB_pa_gain123; /* 0x9df8 - 0x9dfc */
+ volatile unsigned int BB_pa_gain45; /* 0x9dfc - 0x9e00 */
+ volatile unsigned int BB_paprd_pre_post_scale_0; /* 0x9e00 - 0x9e04 */
+ volatile unsigned int BB_paprd_pre_post_scale_1; /* 0x9e04 - 0x9e08 */
+ volatile unsigned int BB_paprd_pre_post_scale_2; /* 0x9e08 - 0x9e0c */
+ volatile unsigned int BB_paprd_pre_post_scale_3; /* 0x9e0c - 0x9e10 */
+ volatile unsigned int BB_paprd_pre_post_scale_4; /* 0x9e10 - 0x9e14 */
+ volatile unsigned int BB_paprd_pre_post_scale_5; /* 0x9e14 - 0x9e18 */
+ volatile unsigned int BB_paprd_pre_post_scale_6; /* 0x9e18 - 0x9e1c */
+ volatile unsigned int BB_paprd_pre_post_scale_7; /* 0x9e1c - 0x9e20 */
+ volatile unsigned int BB_paprd_mem_tab[120]; /* 0x9e20 - 0xa000 */
+ volatile unsigned int BB_peak_det_ctrl_1; /* 0xa000 - 0xa004 */
+ volatile unsigned int BB_peak_det_ctrl_2; /* 0xa004 - 0xa008 */
+ volatile unsigned int BB_rx_gain_bounds_1; /* 0xa008 - 0xa00c */
+ volatile unsigned int BB_rx_gain_bounds_2; /* 0xa00c - 0xa010 */
+ volatile unsigned int BB_peak_det_cal_ctrl; /* 0xa010 - 0xa014 */
+ volatile unsigned int BB_agc_dig_dc_ctrl; /* 0xa014 - 0xa018 */
+ volatile unsigned int BB_agc_dig_dc_status_i_b0; /* 0xa018 - 0xa01c */
+ volatile unsigned int BB_agc_dig_dc_status_q_b0; /* 0xa01c - 0xa020 */
+ volatile char pad__15[0x1d4]; /* 0xa020 - 0xa1f4 */
+ volatile unsigned int BB_bbb_txfir_0; /* 0xa1f4 - 0xa1f8 */
+ volatile unsigned int BB_bbb_txfir_1; /* 0xa1f8 - 0xa1fc */
+ volatile unsigned int BB_bbb_txfir_2; /* 0xa1fc - 0xa200 */
+ volatile unsigned int BB_modes_select; /* 0xa200 - 0xa204 */
+ volatile unsigned int BB_bbb_tx_ctrl; /* 0xa204 - 0xa208 */
+ volatile unsigned int BB_bbb_sig_detect; /* 0xa208 - 0xa20c */
+ volatile unsigned int BB_ext_atten_switch_ctl_b0; /* 0xa20c - 0xa210 */
+ volatile unsigned int BB_bbb_rx_ctrl_1; /* 0xa210 - 0xa214 */
+ volatile unsigned int BB_bbb_rx_ctrl_2; /* 0xa214 - 0xa218 */
+ volatile unsigned int BB_bbb_rx_ctrl_3; /* 0xa218 - 0xa21c */
+ volatile unsigned int BB_bbb_rx_ctrl_4; /* 0xa21c - 0xa220 */
+ volatile unsigned int BB_bbb_rx_ctrl_5; /* 0xa220 - 0xa224 */
+ volatile unsigned int BB_bbb_rx_ctrl_6; /* 0xa224 - 0xa228 */
+ volatile unsigned int BB_bbb_dagc_ctrl; /* 0xa228 - 0xa22c */
+ volatile unsigned int BB_force_clken_cck; /* 0xa22c - 0xa230 */
+ volatile unsigned int BB_rx_clear_delay; /* 0xa230 - 0xa234 */
+ volatile unsigned int BB_powertx_rate3; /* 0xa234 - 0xa238 */
+ volatile unsigned int BB_powertx_rate4; /* 0xa238 - 0xa23c */
+ volatile char pad__16[0x4]; /* 0xa23c - 0xa240 */
+ volatile unsigned int BB_cck_spur_mit; /* 0xa240 - 0xa244 */
+ volatile unsigned int BB_panic_watchdog_status; /* 0xa244 - 0xa248 */
+ volatile unsigned int BB_panic_watchdog_ctrl_1; /* 0xa248 - 0xa24c */
+ volatile unsigned int BB_panic_watchdog_ctrl_2; /* 0xa24c - 0xa250 */
+ volatile unsigned int BB_iqcorr_ctrl_cck; /* 0xa250 - 0xa254 */
+ volatile unsigned int BB_bluetooth_cntl; /* 0xa254 - 0xa258 */
+ volatile unsigned int BB_tpc_1; /* 0xa258 - 0xa25c */
+ volatile unsigned int BB_tpc_2; /* 0xa25c - 0xa260 */
+ volatile unsigned int BB_tpc_3; /* 0xa260 - 0xa264 */
+ volatile unsigned int BB_tpc_4_b0; /* 0xa264 - 0xa268 */
+ volatile unsigned int BB_analog_swap; /* 0xa268 - 0xa26c */
+ volatile unsigned int BB_tpc_5_b0; /* 0xa26c - 0xa270 */
+ volatile unsigned int BB_tpc_6_b0; /* 0xa270 - 0xa274 */
+ volatile unsigned int BB_tpc_7; /* 0xa274 - 0xa278 */
+ volatile unsigned int BB_tpc_8; /* 0xa278 - 0xa27c */
+ volatile unsigned int BB_tpc_9; /* 0xa27c - 0xa280 */
+ volatile unsigned int BB_pdadc_tab_b0[32]; /* 0xa280 - 0xa300 */
+ volatile unsigned int BB_cl_tab_b0[16]; /* 0xa300 - 0xa340 */
+ volatile unsigned int BB_cl_map_0_b0; /* 0xa340 - 0xa344 */
+ volatile unsigned int BB_cl_map_1_b0; /* 0xa344 - 0xa348 */
+ volatile unsigned int BB_cl_map_2_b0; /* 0xa348 - 0xa34c */
+ volatile unsigned int BB_cl_map_3_b0; /* 0xa34c - 0xa350 */
+ volatile char pad__17[0x8]; /* 0xa350 - 0xa358 */
+ volatile unsigned int BB_cl_cal_ctrl; /* 0xa358 - 0xa35c */
+ volatile unsigned int BB_cl_map_pal_0_b0; /* 0xa35c - 0xa360 */
+ volatile unsigned int BB_cl_map_pal_1_b0; /* 0xa360 - 0xa364 */
+ volatile unsigned int BB_cl_map_pal_2_b0; /* 0xa364 - 0xa368 */
+ volatile unsigned int BB_cl_map_pal_3_b0; /* 0xa368 - 0xa36c */
+ volatile char pad__18[0x1c]; /* 0xa36c - 0xa388 */
+ volatile unsigned int BB_rifs; /* 0xa388 - 0xa38c */
+ volatile unsigned int BB_powertx_rate5; /* 0xa38c - 0xa390 */
+ volatile unsigned int BB_powertx_rate6; /* 0xa390 - 0xa394 */
+ volatile unsigned int BB_tpc_10; /* 0xa394 - 0xa398 */
+ volatile unsigned int BB_tpc_11_b0; /* 0xa398 - 0xa39c */
+ volatile unsigned int BB_cal_chain_mask; /* 0xa39c - 0xa3a0 */
+ volatile char pad__19[0x1c]; /* 0xa3a0 - 0xa3bc */
+ volatile unsigned int BB_powertx_sub; /* 0xa3bc - 0xa3c0 */
+ volatile unsigned int BB_powertx_rate7; /* 0xa3c0 - 0xa3c4 */
+ volatile unsigned int BB_powertx_rate8; /* 0xa3c4 - 0xa3c8 */
+ volatile unsigned int BB_powertx_rate9; /* 0xa3c8 - 0xa3cc */
+ volatile unsigned int BB_powertx_rate10; /* 0xa3cc - 0xa3d0 */
+ volatile unsigned int BB_powertx_rate11; /* 0xa3d0 - 0xa3d4 */
+ volatile unsigned int BB_powertx_rate12; /* 0xa3d4 - 0xa3d8 */
+ volatile unsigned int BB_force_analog; /* 0xa3d8 - 0xa3dc */
+ volatile unsigned int BB_tpc_12; /* 0xa3dc - 0xa3e0 */
+ volatile unsigned int BB_tpc_13; /* 0xa3e0 - 0xa3e4 */
+ volatile unsigned int BB_tpc_14; /* 0xa3e4 - 0xa3e8 */
+ volatile unsigned int BB_tpc_15; /* 0xa3e8 - 0xa3ec */
+ volatile unsigned int BB_tpc_16; /* 0xa3ec - 0xa3f0 */
+ volatile unsigned int BB_tpc_17; /* 0xa3f0 - 0xa3f4 */
+ volatile unsigned int BB_tpc_18; /* 0xa3f4 - 0xa3f8 */
+ volatile unsigned int BB_tpc_19; /* 0xa3f8 - 0xa3fc */
+ volatile unsigned int BB_tpc_20; /* 0xa3fc - 0xa400 */
+ volatile unsigned int BB_tx_gain_tab_1; /* 0xa400 - 0xa404 */
+ volatile unsigned int BB_tx_gain_tab_2; /* 0xa404 - 0xa408 */
+ volatile unsigned int BB_tx_gain_tab_3; /* 0xa408 - 0xa40c */
+ volatile unsigned int BB_tx_gain_tab_4; /* 0xa40c - 0xa410 */
+ volatile unsigned int BB_tx_gain_tab_5; /* 0xa410 - 0xa414 */
+ volatile unsigned int BB_tx_gain_tab_6; /* 0xa414 - 0xa418 */
+ volatile unsigned int BB_tx_gain_tab_7; /* 0xa418 - 0xa41c */
+ volatile unsigned int BB_tx_gain_tab_8; /* 0xa41c - 0xa420 */
+ volatile unsigned int BB_tx_gain_tab_9; /* 0xa420 - 0xa424 */
+ volatile unsigned int BB_tx_gain_tab_10; /* 0xa424 - 0xa428 */
+ volatile unsigned int BB_tx_gain_tab_11; /* 0xa428 - 0xa42c */
+ volatile unsigned int BB_tx_gain_tab_12; /* 0xa42c - 0xa430 */
+ volatile unsigned int BB_tx_gain_tab_13; /* 0xa430 - 0xa434 */
+ volatile unsigned int BB_tx_gain_tab_14; /* 0xa434 - 0xa438 */
+ volatile unsigned int BB_tx_gain_tab_15; /* 0xa438 - 0xa43c */
+ volatile unsigned int BB_tx_gain_tab_16; /* 0xa43c - 0xa440 */
+ volatile unsigned int BB_tx_gain_tab_17; /* 0xa440 - 0xa444 */
+ volatile unsigned int BB_tx_gain_tab_18; /* 0xa444 - 0xa448 */
+ volatile unsigned int BB_tx_gain_tab_19; /* 0xa448 - 0xa44c */
+ volatile unsigned int BB_tx_gain_tab_20; /* 0xa44c - 0xa450 */
+ volatile unsigned int BB_tx_gain_tab_21; /* 0xa450 - 0xa454 */
+ volatile unsigned int BB_tx_gain_tab_22; /* 0xa454 - 0xa458 */
+ volatile unsigned int BB_tx_gain_tab_23; /* 0xa458 - 0xa45c */
+ volatile unsigned int BB_tx_gain_tab_24; /* 0xa45c - 0xa460 */
+ volatile unsigned int BB_tx_gain_tab_25; /* 0xa460 - 0xa464 */
+ volatile unsigned int BB_tx_gain_tab_26; /* 0xa464 - 0xa468 */
+ volatile unsigned int BB_tx_gain_tab_27; /* 0xa468 - 0xa46c */
+ volatile unsigned int BB_tx_gain_tab_28; /* 0xa46c - 0xa470 */
+ volatile unsigned int BB_tx_gain_tab_29; /* 0xa470 - 0xa474 */
+ volatile unsigned int BB_tx_gain_tab_30; /* 0xa474 - 0xa478 */
+ volatile unsigned int BB_tx_gain_tab_31; /* 0xa478 - 0xa47c */
+ volatile unsigned int BB_tx_gain_tab_32; /* 0xa47c - 0xa480 */
+ volatile unsigned int BB_tx_gain_tab_pal_1; /* 0xa480 - 0xa484 */
+ volatile unsigned int BB_tx_gain_tab_pal_2; /* 0xa484 - 0xa488 */
+ volatile unsigned int BB_tx_gain_tab_pal_3; /* 0xa488 - 0xa48c */
+ volatile unsigned int BB_tx_gain_tab_pal_4; /* 0xa48c - 0xa490 */
+ volatile unsigned int BB_tx_gain_tab_pal_5; /* 0xa490 - 0xa494 */
+ volatile unsigned int BB_tx_gain_tab_pal_6; /* 0xa494 - 0xa498 */
+ volatile unsigned int BB_tx_gain_tab_pal_7; /* 0xa498 - 0xa49c */
+ volatile unsigned int BB_tx_gain_tab_pal_8; /* 0xa49c - 0xa4a0 */
+ volatile unsigned int BB_tx_gain_tab_pal_9; /* 0xa4a0 - 0xa4a4 */
+ volatile unsigned int BB_tx_gain_tab_pal_10; /* 0xa4a4 - 0xa4a8 */
+ volatile unsigned int BB_tx_gain_tab_pal_11; /* 0xa4a8 - 0xa4ac */
+ volatile unsigned int BB_tx_gain_tab_pal_12; /* 0xa4ac - 0xa4b0 */
+ volatile unsigned int BB_tx_gain_tab_pal_13; /* 0xa4b0 - 0xa4b4 */
+ volatile unsigned int BB_tx_gain_tab_pal_14; /* 0xa4b4 - 0xa4b8 */
+ volatile unsigned int BB_tx_gain_tab_pal_15; /* 0xa4b8 - 0xa4bc */
+ volatile unsigned int BB_tx_gain_tab_pal_16; /* 0xa4bc - 0xa4c0 */
+ volatile unsigned int BB_tx_gain_tab_pal_17; /* 0xa4c0 - 0xa4c4 */
+ volatile unsigned int BB_tx_gain_tab_pal_18; /* 0xa4c4 - 0xa4c8 */
+ volatile unsigned int BB_tx_gain_tab_pal_19; /* 0xa4c8 - 0xa4cc */
+ volatile unsigned int BB_tx_gain_tab_pal_20; /* 0xa4cc - 0xa4d0 */
+ volatile unsigned int BB_tx_gain_tab_pal_21; /* 0xa4d0 - 0xa4d4 */
+ volatile unsigned int BB_tx_gain_tab_pal_22; /* 0xa4d4 - 0xa4d8 */
+ volatile unsigned int BB_tx_gain_tab_pal_23; /* 0xa4d8 - 0xa4dc */
+ volatile unsigned int BB_tx_gain_tab_pal_24; /* 0xa4dc - 0xa4e0 */
+ volatile unsigned int BB_tx_gain_tab_pal_25; /* 0xa4e0 - 0xa4e4 */
+ volatile unsigned int BB_tx_gain_tab_pal_26; /* 0xa4e4 - 0xa4e8 */
+ volatile unsigned int BB_tx_gain_tab_pal_27; /* 0xa4e8 - 0xa4ec */
+ volatile unsigned int BB_tx_gain_tab_pal_28; /* 0xa4ec - 0xa4f0 */
+ volatile unsigned int BB_tx_gain_tab_pal_29; /* 0xa4f0 - 0xa4f4 */
+ volatile unsigned int BB_tx_gain_tab_pal_30; /* 0xa4f4 - 0xa4f8 */
+ volatile unsigned int BB_tx_gain_tab_pal_31; /* 0xa4f8 - 0xa4fc */
+ volatile unsigned int BB_tx_gain_tab_pal_32; /* 0xa4fc - 0xa500 */
+ volatile char pad__20[0x18]; /* 0xa500 - 0xa518 */
+ volatile unsigned int BB_caltx_gain_set_0; /* 0xa518 - 0xa51c */
+ volatile unsigned int BB_caltx_gain_set_2; /* 0xa51c - 0xa520 */
+ volatile unsigned int BB_caltx_gain_set_4; /* 0xa520 - 0xa524 */
+ volatile unsigned int BB_caltx_gain_set_6; /* 0xa524 - 0xa528 */
+ volatile unsigned int BB_caltx_gain_set_8; /* 0xa528 - 0xa52c */
+ volatile unsigned int BB_caltx_gain_set_10; /* 0xa52c - 0xa530 */
+ volatile unsigned int BB_caltx_gain_set_12; /* 0xa530 - 0xa534 */
+ volatile unsigned int BB_caltx_gain_set_14; /* 0xa534 - 0xa538 */
+ volatile unsigned int BB_caltx_gain_set_16; /* 0xa538 - 0xa53c */
+ volatile unsigned int BB_caltx_gain_set_18; /* 0xa53c - 0xa540 */
+ volatile unsigned int BB_caltx_gain_set_20; /* 0xa540 - 0xa544 */
+ volatile unsigned int BB_caltx_gain_set_22; /* 0xa544 - 0xa548 */
+ volatile unsigned int BB_caltx_gain_set_24; /* 0xa548 - 0xa54c */
+ volatile unsigned int BB_caltx_gain_set_26; /* 0xa54c - 0xa550 */
+ volatile unsigned int BB_caltx_gain_set_28; /* 0xa550 - 0xa554 */
+ volatile unsigned int BB_caltx_gain_set_30; /* 0xa554 - 0xa558 */
+ volatile unsigned int BB_txiqcal_meas_b0[96]; /* 0xa558 - 0xa6d8 */
+ volatile unsigned int BB_txiqcal_start; /* 0xa6d8 - 0xa6dc */
+ volatile unsigned int BB_txiqcal_control_0; /* 0xa6dc - 0xa6e0 */
+ volatile unsigned int BB_txiqcal_control_1; /* 0xa6e0 - 0xa6e4 */
+ volatile unsigned int BB_txiqcal_control_2; /* 0xa6e4 - 0xa6e8 */
+ volatile unsigned int BB_txiqcal_control_3; /* 0xa6e8 - 0xa6ec */
+ volatile unsigned int BB_txiq_corr_coeff_01_b0; /* 0xa6ec - 0xa6f0 */
+ volatile unsigned int BB_txiq_corr_coeff_23_b0; /* 0xa6f0 - 0xa6f4 */
+ volatile unsigned int BB_txiq_corr_coeff_45_b0; /* 0xa6f4 - 0xa6f8 */
+ volatile unsigned int BB_txiq_corr_coeff_67_b0; /* 0xa6f8 - 0xa6fc */
+ volatile unsigned int BB_txiq_corr_coeff_89_b0; /* 0xa6fc - 0xa700 */
+ volatile unsigned int BB_txiq_corr_coeff_ab_b0; /* 0xa700 - 0xa704 */
+ volatile unsigned int BB_txiq_corr_coeff_cd_b0; /* 0xa704 - 0xa708 */
+ volatile unsigned int BB_txiq_corr_coeff_ef_b0; /* 0xa708 - 0xa70c */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_0; /* 0xa70c - 0xa710 */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_4; /* 0xa710 - 0xa714 */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_8; /* 0xa714 - 0xa718 */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_12; /* 0xa718 - 0xa71c */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_16; /* 0xa71c - 0xa720 */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_20; /* 0xa720 - 0xa724 */
+ volatile unsigned int BB_cal_rxbb_gain_tbl_24; /* 0xa724 - 0xa728 */
+ volatile unsigned int BB_txiqcal_status_b0; /* 0xa728 - 0xa72c */
+ volatile unsigned int BB_paprd_trainer_cntl1; /* 0xa72c - 0xa730 */
+ volatile unsigned int BB_paprd_trainer_cntl2; /* 0xa730 - 0xa734 */
+ volatile unsigned int BB_paprd_trainer_cntl3; /* 0xa734 - 0xa738 */
+ volatile unsigned int BB_paprd_trainer_cntl4; /* 0xa738 - 0xa73c */
+ volatile unsigned int BB_paprd_trainer_stat1; /* 0xa73c - 0xa740 */
+ volatile unsigned int BB_paprd_trainer_stat2; /* 0xa740 - 0xa744 */
+ volatile unsigned int BB_paprd_trainer_stat3; /* 0xa744 - 0xa748 */
+ volatile char pad__21[0x90]; /* 0xa748 - 0xa7d8 */
+ volatile unsigned int BB_fcal_1; /* 0xa7d8 - 0xa7dc */
+ volatile unsigned int BB_fcal_2_b0; /* 0xa7dc - 0xa7e0 */
+ volatile unsigned int BB_radar_bw_filter; /* 0xa7e0 - 0xa7e4 */
+ volatile unsigned int BB_dft_tone_ctrl_b0; /* 0xa7e4 - 0xa7e8 */
+ volatile unsigned int BB_therm_adc_1; /* 0xa7e8 - 0xa7ec */
+ volatile unsigned int BB_therm_adc_2; /* 0xa7ec - 0xa7f0 */
+ volatile unsigned int BB_therm_adc_3; /* 0xa7f0 - 0xa7f4 */
+ volatile unsigned int BB_therm_adc_4; /* 0xa7f4 - 0xa7f8 */
+ volatile unsigned int BB_tx_forced_gain; /* 0xa7f8 - 0xa7fc */
+ volatile unsigned int BB_eco_ctrl; /* 0xa7fc - 0xa800 */
+ volatile char pad__22[0x48]; /* 0xa800 - 0xa848 */
+ volatile unsigned int BB_gain_force_max_gains_b1; /* 0xa848 - 0xa84c */
+ volatile unsigned int BB_gains_min_offsets_b1; /* 0xa84c - 0xa850 */
+ volatile char pad__23[0x1b0]; /* 0xa850 - 0xaa00 */
+ volatile unsigned int BB_rx_ocgain2[128]; /* 0xaa00 - 0xac00 */
+ volatile char pad__24[0x60c]; /* 0xac00 - 0xb20c */
+ volatile unsigned int BB_ext_atten_switch_ctl_b1; /* 0xb20c - 0xb210 */
+} bb_lc_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _BB_LC_REG_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h
new file mode 100644
index 000000000000..12cadb337482
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h
@@ -0,0 +1,108 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _EFUSE_REG_REG_H_
+#define _EFUSE_REG_REG_H_
+
+#define EFUSE_WR_ENABLE_REG_ADDRESS 0x00000000
+#define EFUSE_WR_ENABLE_REG_OFFSET 0x00000000
+#define EFUSE_WR_ENABLE_REG_V_MSB 0
+#define EFUSE_WR_ENABLE_REG_V_LSB 0
+#define EFUSE_WR_ENABLE_REG_V_MASK 0x00000001
+#define EFUSE_WR_ENABLE_REG_V_GET(x) (((x) & EFUSE_WR_ENABLE_REG_V_MASK) >> EFUSE_WR_ENABLE_REG_V_LSB)
+#define EFUSE_WR_ENABLE_REG_V_SET(x) (((x) << EFUSE_WR_ENABLE_REG_V_LSB) & EFUSE_WR_ENABLE_REG_V_MASK)
+
+#define EFUSE_INT_ENABLE_REG_ADDRESS 0x00000004
+#define EFUSE_INT_ENABLE_REG_OFFSET 0x00000004
+#define EFUSE_INT_ENABLE_REG_V_MSB 0
+#define EFUSE_INT_ENABLE_REG_V_LSB 0
+#define EFUSE_INT_ENABLE_REG_V_MASK 0x00000001
+#define EFUSE_INT_ENABLE_REG_V_GET(x) (((x) & EFUSE_INT_ENABLE_REG_V_MASK) >> EFUSE_INT_ENABLE_REG_V_LSB)
+#define EFUSE_INT_ENABLE_REG_V_SET(x) (((x) << EFUSE_INT_ENABLE_REG_V_LSB) & EFUSE_INT_ENABLE_REG_V_MASK)
+
+#define EFUSE_INT_STATUS_REG_ADDRESS 0x00000008
+#define EFUSE_INT_STATUS_REG_OFFSET 0x00000008
+#define EFUSE_INT_STATUS_REG_V_MSB 0
+#define EFUSE_INT_STATUS_REG_V_LSB 0
+#define EFUSE_INT_STATUS_REG_V_MASK 0x00000001
+#define EFUSE_INT_STATUS_REG_V_GET(x) (((x) & EFUSE_INT_STATUS_REG_V_MASK) >> EFUSE_INT_STATUS_REG_V_LSB)
+#define EFUSE_INT_STATUS_REG_V_SET(x) (((x) << EFUSE_INT_STATUS_REG_V_LSB) & EFUSE_INT_STATUS_REG_V_MASK)
+
+#define BITMASK_WR_REG_ADDRESS 0x0000000c
+#define BITMASK_WR_REG_OFFSET 0x0000000c
+#define BITMASK_WR_REG_V_MSB 31
+#define BITMASK_WR_REG_V_LSB 0
+#define BITMASK_WR_REG_V_MASK 0xffffffff
+#define BITMASK_WR_REG_V_GET(x) (((x) & BITMASK_WR_REG_V_MASK) >> BITMASK_WR_REG_V_LSB)
+#define BITMASK_WR_REG_V_SET(x) (((x) << BITMASK_WR_REG_V_LSB) & BITMASK_WR_REG_V_MASK)
+
+#define VDDQ_SETTLE_TIME_REG_ADDRESS 0x00000010
+#define VDDQ_SETTLE_TIME_REG_OFFSET 0x00000010
+#define VDDQ_SETTLE_TIME_REG_V_MSB 31
+#define VDDQ_SETTLE_TIME_REG_V_LSB 0
+#define VDDQ_SETTLE_TIME_REG_V_MASK 0xffffffff
+#define VDDQ_SETTLE_TIME_REG_V_GET(x) (((x) & VDDQ_SETTLE_TIME_REG_V_MASK) >> VDDQ_SETTLE_TIME_REG_V_LSB)
+#define VDDQ_SETTLE_TIME_REG_V_SET(x) (((x) << VDDQ_SETTLE_TIME_REG_V_LSB) & VDDQ_SETTLE_TIME_REG_V_MASK)
+
+#define RD_STROBE_PW_REG_ADDRESS 0x00000014
+#define RD_STROBE_PW_REG_OFFSET 0x00000014
+#define RD_STROBE_PW_REG_V_MSB 31
+#define RD_STROBE_PW_REG_V_LSB 0
+#define RD_STROBE_PW_REG_V_MASK 0xffffffff
+#define RD_STROBE_PW_REG_V_GET(x) (((x) & RD_STROBE_PW_REG_V_MASK) >> RD_STROBE_PW_REG_V_LSB)
+#define RD_STROBE_PW_REG_V_SET(x) (((x) << RD_STROBE_PW_REG_V_LSB) & RD_STROBE_PW_REG_V_MASK)
+
+#define PG_STROBE_PW_REG_ADDRESS 0x00000018
+#define PG_STROBE_PW_REG_OFFSET 0x00000018
+#define PG_STROBE_PW_REG_V_MSB 31
+#define PG_STROBE_PW_REG_V_LSB 0
+#define PG_STROBE_PW_REG_V_MASK 0xffffffff
+#define PG_STROBE_PW_REG_V_GET(x) (((x) & PG_STROBE_PW_REG_V_MASK) >> PG_STROBE_PW_REG_V_LSB)
+#define PG_STROBE_PW_REG_V_SET(x) (((x) << PG_STROBE_PW_REG_V_LSB) & PG_STROBE_PW_REG_V_MASK)
+
+#define EFUSE_INTF_ADDRESS 0x00000800
+#define EFUSE_INTF_OFFSET 0x00000800
+#define EFUSE_INTF_R_MSB 31
+#define EFUSE_INTF_R_LSB 0
+#define EFUSE_INTF_R_MASK 0xffffffff
+#define EFUSE_INTF_R_GET(x) (((x) & EFUSE_INTF_R_MASK) >> EFUSE_INTF_R_LSB)
+#define EFUSE_INTF_R_SET(x) (((x) << EFUSE_INTF_R_LSB) & EFUSE_INTF_R_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct efuse_reg_reg_s {
+ volatile unsigned int efuse_wr_enable_reg;
+ volatile unsigned int efuse_int_enable_reg;
+ volatile unsigned int efuse_int_status_reg;
+ volatile unsigned int bitmask_wr_reg;
+ volatile unsigned int vddq_settle_time_reg;
+ volatile unsigned int rd_strobe_pw_reg;
+ volatile unsigned int pg_strobe_pw_reg;
+ unsigned char pad0[2020]; /* pad to 0x800 */
+ volatile unsigned int efuse_intf[512];
+} efuse_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _EFUSE_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h
new file mode 100644
index 000000000000..1adee707de7c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h
@@ -0,0 +1,1253 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _GPIO_ATHR_WLAN_REG_REG_H_
+#define _GPIO_ATHR_WLAN_REG_REG_H_
+
+#define WLAN_GPIO_OUT_ADDRESS 0x00000000
+#define WLAN_GPIO_OUT_OFFSET 0x00000000
+#define WLAN_GPIO_OUT_DATA_MSB 25
+#define WLAN_GPIO_OUT_DATA_LSB 0
+#define WLAN_GPIO_OUT_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_OUT_DATA_GET(x) (((x) & WLAN_GPIO_OUT_DATA_MASK) >> WLAN_GPIO_OUT_DATA_LSB)
+#define WLAN_GPIO_OUT_DATA_SET(x) (((x) << WLAN_GPIO_OUT_DATA_LSB) & WLAN_GPIO_OUT_DATA_MASK)
+
+#define WLAN_GPIO_OUT_W1TS_ADDRESS 0x00000004
+#define WLAN_GPIO_OUT_W1TS_OFFSET 0x00000004
+#define WLAN_GPIO_OUT_W1TS_DATA_MSB 25
+#define WLAN_GPIO_OUT_W1TS_DATA_LSB 0
+#define WLAN_GPIO_OUT_W1TS_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_OUT_W1TS_DATA_GET(x) (((x) & WLAN_GPIO_OUT_W1TS_DATA_MASK) >> WLAN_GPIO_OUT_W1TS_DATA_LSB)
+#define WLAN_GPIO_OUT_W1TS_DATA_SET(x) (((x) << WLAN_GPIO_OUT_W1TS_DATA_LSB) & WLAN_GPIO_OUT_W1TS_DATA_MASK)
+
+#define WLAN_GPIO_OUT_W1TC_ADDRESS 0x00000008
+#define WLAN_GPIO_OUT_W1TC_OFFSET 0x00000008
+#define WLAN_GPIO_OUT_W1TC_DATA_MSB 25
+#define WLAN_GPIO_OUT_W1TC_DATA_LSB 0
+#define WLAN_GPIO_OUT_W1TC_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_OUT_W1TC_DATA_GET(x) (((x) & WLAN_GPIO_OUT_W1TC_DATA_MASK) >> WLAN_GPIO_OUT_W1TC_DATA_LSB)
+#define WLAN_GPIO_OUT_W1TC_DATA_SET(x) (((x) << WLAN_GPIO_OUT_W1TC_DATA_LSB) & WLAN_GPIO_OUT_W1TC_DATA_MASK)
+
+#define WLAN_GPIO_ENABLE_ADDRESS 0x0000000c
+#define WLAN_GPIO_ENABLE_OFFSET 0x0000000c
+#define WLAN_GPIO_ENABLE_DATA_MSB 25
+#define WLAN_GPIO_ENABLE_DATA_LSB 0
+#define WLAN_GPIO_ENABLE_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_ENABLE_DATA_GET(x) (((x) & WLAN_GPIO_ENABLE_DATA_MASK) >> WLAN_GPIO_ENABLE_DATA_LSB)
+#define WLAN_GPIO_ENABLE_DATA_SET(x) (((x) << WLAN_GPIO_ENABLE_DATA_LSB) & WLAN_GPIO_ENABLE_DATA_MASK)
+
+#define WLAN_GPIO_ENABLE_W1TS_ADDRESS 0x00000010
+#define WLAN_GPIO_ENABLE_W1TS_OFFSET 0x00000010
+#define WLAN_GPIO_ENABLE_W1TS_DATA_MSB 25
+#define WLAN_GPIO_ENABLE_W1TS_DATA_LSB 0
+#define WLAN_GPIO_ENABLE_W1TS_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_ENABLE_W1TS_DATA_GET(x) (((x) & WLAN_GPIO_ENABLE_W1TS_DATA_MASK) >> WLAN_GPIO_ENABLE_W1TS_DATA_LSB)
+#define WLAN_GPIO_ENABLE_W1TS_DATA_SET(x) (((x) << WLAN_GPIO_ENABLE_W1TS_DATA_LSB) & WLAN_GPIO_ENABLE_W1TS_DATA_MASK)
+
+#define WLAN_GPIO_ENABLE_W1TC_ADDRESS 0x00000014
+#define WLAN_GPIO_ENABLE_W1TC_OFFSET 0x00000014
+#define WLAN_GPIO_ENABLE_W1TC_DATA_MSB 25
+#define WLAN_GPIO_ENABLE_W1TC_DATA_LSB 0
+#define WLAN_GPIO_ENABLE_W1TC_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_ENABLE_W1TC_DATA_GET(x) (((x) & WLAN_GPIO_ENABLE_W1TC_DATA_MASK) >> WLAN_GPIO_ENABLE_W1TC_DATA_LSB)
+#define WLAN_GPIO_ENABLE_W1TC_DATA_SET(x) (((x) << WLAN_GPIO_ENABLE_W1TC_DATA_LSB) & WLAN_GPIO_ENABLE_W1TC_DATA_MASK)
+
+#define WLAN_GPIO_IN_ADDRESS 0x00000018
+#define WLAN_GPIO_IN_OFFSET 0x00000018
+#define WLAN_GPIO_IN_DATA_MSB 25
+#define WLAN_GPIO_IN_DATA_LSB 0
+#define WLAN_GPIO_IN_DATA_MASK 0x03ffffff
+#define WLAN_GPIO_IN_DATA_GET(x) (((x) & WLAN_GPIO_IN_DATA_MASK) >> WLAN_GPIO_IN_DATA_LSB)
+#define WLAN_GPIO_IN_DATA_SET(x) (((x) << WLAN_GPIO_IN_DATA_LSB) & WLAN_GPIO_IN_DATA_MASK)
+
+#define WLAN_GPIO_STATUS_ADDRESS 0x0000001c
+#define WLAN_GPIO_STATUS_OFFSET 0x0000001c
+#define WLAN_GPIO_STATUS_INTERRUPT_MSB 25
+#define WLAN_GPIO_STATUS_INTERRUPT_LSB 0
+#define WLAN_GPIO_STATUS_INTERRUPT_MASK 0x03ffffff
+#define WLAN_GPIO_STATUS_INTERRUPT_GET(x) (((x) & WLAN_GPIO_STATUS_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_INTERRUPT_LSB)
+#define WLAN_GPIO_STATUS_INTERRUPT_SET(x) (((x) << WLAN_GPIO_STATUS_INTERRUPT_LSB) & WLAN_GPIO_STATUS_INTERRUPT_MASK)
+
+#define WLAN_GPIO_STATUS_W1TS_ADDRESS 0x00000020
+#define WLAN_GPIO_STATUS_W1TS_OFFSET 0x00000020
+#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_MSB 25
+#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB 0
+#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK 0x03ffffff
+#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_GET(x) (((x) & WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB)
+#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_SET(x) (((x) << WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB) & WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK)
+
+#define WLAN_GPIO_STATUS_W1TC_ADDRESS 0x00000024
+#define WLAN_GPIO_STATUS_W1TC_OFFSET 0x00000024
+#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_MSB 25
+#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB 0
+#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK 0x03ffffff
+#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_GET(x) (((x) & WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB)
+#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_SET(x) (((x) << WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB) & WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK)
+
+#define WLAN_GPIO_PIN0_ADDRESS 0x00000028
+#define WLAN_GPIO_PIN0_OFFSET 0x00000028
+#define WLAN_GPIO_PIN0_CONFIG_MSB 13
+#define WLAN_GPIO_PIN0_CONFIG_LSB 11
+#define WLAN_GPIO_PIN0_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN0_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN0_CONFIG_MASK) >> WLAN_GPIO_PIN0_CONFIG_LSB)
+#define WLAN_GPIO_PIN0_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN0_CONFIG_LSB) & WLAN_GPIO_PIN0_CONFIG_MASK)
+#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN0_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN0_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN0_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN0_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN0_INT_TYPE_MASK) >> WLAN_GPIO_PIN0_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN0_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN0_INT_TYPE_LSB) & WLAN_GPIO_PIN0_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN0_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN0_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN0_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN0_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN0_PAD_PULL_MASK) >> WLAN_GPIO_PIN0_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN0_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN0_PAD_PULL_LSB) & WLAN_GPIO_PIN0_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN0_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN0_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN0_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN0_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN0_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN0_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN0_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN0_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN0_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN0_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN0_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN0_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN0_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN0_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN0_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN0_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN0_PAD_DRIVER_LSB) & WLAN_GPIO_PIN0_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN0_SOURCE_MSB 0
+#define WLAN_GPIO_PIN0_SOURCE_LSB 0
+#define WLAN_GPIO_PIN0_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN0_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN0_SOURCE_MASK) >> WLAN_GPIO_PIN0_SOURCE_LSB)
+#define WLAN_GPIO_PIN0_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN0_SOURCE_LSB) & WLAN_GPIO_PIN0_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN1_ADDRESS 0x0000002c
+#define WLAN_GPIO_PIN1_OFFSET 0x0000002c
+#define WLAN_GPIO_PIN1_CONFIG_MSB 13
+#define WLAN_GPIO_PIN1_CONFIG_LSB 11
+#define WLAN_GPIO_PIN1_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN1_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN1_CONFIG_MASK) >> WLAN_GPIO_PIN1_CONFIG_LSB)
+#define WLAN_GPIO_PIN1_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN1_CONFIG_LSB) & WLAN_GPIO_PIN1_CONFIG_MASK)
+#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN1_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN1_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN1_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN1_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN1_INT_TYPE_MASK) >> WLAN_GPIO_PIN1_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN1_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN1_INT_TYPE_LSB) & WLAN_GPIO_PIN1_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN1_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN1_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN1_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN1_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN1_PAD_PULL_MASK) >> WLAN_GPIO_PIN1_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN1_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN1_PAD_PULL_LSB) & WLAN_GPIO_PIN1_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN1_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN1_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN1_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN1_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN1_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN1_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN1_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN1_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN1_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN1_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN1_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN1_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN1_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN1_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN1_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN1_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN1_PAD_DRIVER_LSB) & WLAN_GPIO_PIN1_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN1_SOURCE_MSB 0
+#define WLAN_GPIO_PIN1_SOURCE_LSB 0
+#define WLAN_GPIO_PIN1_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN1_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN1_SOURCE_MASK) >> WLAN_GPIO_PIN1_SOURCE_LSB)
+#define WLAN_GPIO_PIN1_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN1_SOURCE_LSB) & WLAN_GPIO_PIN1_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN2_ADDRESS 0x00000030
+#define WLAN_GPIO_PIN2_OFFSET 0x00000030
+#define WLAN_GPIO_PIN2_CONFIG_MSB 13
+#define WLAN_GPIO_PIN2_CONFIG_LSB 11
+#define WLAN_GPIO_PIN2_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN2_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN2_CONFIG_MASK) >> WLAN_GPIO_PIN2_CONFIG_LSB)
+#define WLAN_GPIO_PIN2_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN2_CONFIG_LSB) & WLAN_GPIO_PIN2_CONFIG_MASK)
+#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN2_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN2_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN2_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN2_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN2_INT_TYPE_MASK) >> WLAN_GPIO_PIN2_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN2_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN2_INT_TYPE_LSB) & WLAN_GPIO_PIN2_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN2_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN2_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN2_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN2_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN2_PAD_PULL_MASK) >> WLAN_GPIO_PIN2_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN2_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN2_PAD_PULL_LSB) & WLAN_GPIO_PIN2_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN2_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN2_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN2_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN2_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN2_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN2_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN2_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN2_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN2_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN2_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN2_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN2_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN2_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN2_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN2_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN2_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN2_PAD_DRIVER_LSB) & WLAN_GPIO_PIN2_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN2_SOURCE_MSB 0
+#define WLAN_GPIO_PIN2_SOURCE_LSB 0
+#define WLAN_GPIO_PIN2_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN2_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN2_SOURCE_MASK) >> WLAN_GPIO_PIN2_SOURCE_LSB)
+#define WLAN_GPIO_PIN2_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN2_SOURCE_LSB) & WLAN_GPIO_PIN2_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN3_ADDRESS 0x00000034
+#define WLAN_GPIO_PIN3_OFFSET 0x00000034
+#define WLAN_GPIO_PIN3_CONFIG_MSB 13
+#define WLAN_GPIO_PIN3_CONFIG_LSB 11
+#define WLAN_GPIO_PIN3_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN3_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN3_CONFIG_MASK) >> WLAN_GPIO_PIN3_CONFIG_LSB)
+#define WLAN_GPIO_PIN3_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN3_CONFIG_LSB) & WLAN_GPIO_PIN3_CONFIG_MASK)
+#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN3_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN3_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN3_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN3_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN3_INT_TYPE_MASK) >> WLAN_GPIO_PIN3_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN3_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN3_INT_TYPE_LSB) & WLAN_GPIO_PIN3_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN3_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN3_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN3_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN3_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN3_PAD_PULL_MASK) >> WLAN_GPIO_PIN3_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN3_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN3_PAD_PULL_LSB) & WLAN_GPIO_PIN3_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN3_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN3_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN3_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN3_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN3_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN3_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN3_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN3_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN3_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN3_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN3_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN3_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN3_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN3_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN3_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN3_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN3_PAD_DRIVER_LSB) & WLAN_GPIO_PIN3_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN3_SOURCE_MSB 0
+#define WLAN_GPIO_PIN3_SOURCE_LSB 0
+#define WLAN_GPIO_PIN3_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN3_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN3_SOURCE_MASK) >> WLAN_GPIO_PIN3_SOURCE_LSB)
+#define WLAN_GPIO_PIN3_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN3_SOURCE_LSB) & WLAN_GPIO_PIN3_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN4_ADDRESS 0x00000038
+#define WLAN_GPIO_PIN4_OFFSET 0x00000038
+#define WLAN_GPIO_PIN4_CONFIG_MSB 13
+#define WLAN_GPIO_PIN4_CONFIG_LSB 11
+#define WLAN_GPIO_PIN4_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN4_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN4_CONFIG_MASK) >> WLAN_GPIO_PIN4_CONFIG_LSB)
+#define WLAN_GPIO_PIN4_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN4_CONFIG_LSB) & WLAN_GPIO_PIN4_CONFIG_MASK)
+#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN4_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN4_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN4_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN4_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN4_INT_TYPE_MASK) >> WLAN_GPIO_PIN4_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN4_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN4_INT_TYPE_LSB) & WLAN_GPIO_PIN4_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN4_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN4_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN4_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN4_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN4_PAD_PULL_MASK) >> WLAN_GPIO_PIN4_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN4_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN4_PAD_PULL_LSB) & WLAN_GPIO_PIN4_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN4_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN4_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN4_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN4_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN4_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN4_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN4_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN4_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN4_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN4_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN4_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN4_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN4_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN4_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN4_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN4_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN4_PAD_DRIVER_LSB) & WLAN_GPIO_PIN4_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN4_SOURCE_MSB 0
+#define WLAN_GPIO_PIN4_SOURCE_LSB 0
+#define WLAN_GPIO_PIN4_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN4_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN4_SOURCE_MASK) >> WLAN_GPIO_PIN4_SOURCE_LSB)
+#define WLAN_GPIO_PIN4_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN4_SOURCE_LSB) & WLAN_GPIO_PIN4_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN5_ADDRESS 0x0000003c
+#define WLAN_GPIO_PIN5_OFFSET 0x0000003c
+#define WLAN_GPIO_PIN5_CONFIG_MSB 13
+#define WLAN_GPIO_PIN5_CONFIG_LSB 11
+#define WLAN_GPIO_PIN5_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN5_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN5_CONFIG_MASK) >> WLAN_GPIO_PIN5_CONFIG_LSB)
+#define WLAN_GPIO_PIN5_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN5_CONFIG_LSB) & WLAN_GPIO_PIN5_CONFIG_MASK)
+#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN5_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN5_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN5_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN5_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN5_INT_TYPE_MASK) >> WLAN_GPIO_PIN5_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN5_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN5_INT_TYPE_LSB) & WLAN_GPIO_PIN5_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN5_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN5_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN5_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN5_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN5_PAD_PULL_MASK) >> WLAN_GPIO_PIN5_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN5_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN5_PAD_PULL_LSB) & WLAN_GPIO_PIN5_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN5_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN5_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN5_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN5_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN5_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN5_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN5_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN5_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN5_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN5_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN5_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN5_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN5_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN5_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN5_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN5_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN5_PAD_DRIVER_LSB) & WLAN_GPIO_PIN5_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN5_SOURCE_MSB 0
+#define WLAN_GPIO_PIN5_SOURCE_LSB 0
+#define WLAN_GPIO_PIN5_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN5_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN5_SOURCE_MASK) >> WLAN_GPIO_PIN5_SOURCE_LSB)
+#define WLAN_GPIO_PIN5_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN5_SOURCE_LSB) & WLAN_GPIO_PIN5_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN6_ADDRESS 0x00000040
+#define WLAN_GPIO_PIN6_OFFSET 0x00000040
+#define WLAN_GPIO_PIN6_CONFIG_MSB 13
+#define WLAN_GPIO_PIN6_CONFIG_LSB 11
+#define WLAN_GPIO_PIN6_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN6_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN6_CONFIG_MASK) >> WLAN_GPIO_PIN6_CONFIG_LSB)
+#define WLAN_GPIO_PIN6_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN6_CONFIG_LSB) & WLAN_GPIO_PIN6_CONFIG_MASK)
+#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN6_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN6_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN6_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN6_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN6_INT_TYPE_MASK) >> WLAN_GPIO_PIN6_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN6_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN6_INT_TYPE_LSB) & WLAN_GPIO_PIN6_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN6_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN6_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN6_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN6_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN6_PAD_PULL_MASK) >> WLAN_GPIO_PIN6_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN6_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN6_PAD_PULL_LSB) & WLAN_GPIO_PIN6_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN6_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN6_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN6_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN6_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN6_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN6_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN6_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN6_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN6_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN6_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN6_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN6_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN6_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN6_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN6_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN6_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN6_PAD_DRIVER_LSB) & WLAN_GPIO_PIN6_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN6_SOURCE_MSB 0
+#define WLAN_GPIO_PIN6_SOURCE_LSB 0
+#define WLAN_GPIO_PIN6_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN6_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN6_SOURCE_MASK) >> WLAN_GPIO_PIN6_SOURCE_LSB)
+#define WLAN_GPIO_PIN6_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN6_SOURCE_LSB) & WLAN_GPIO_PIN6_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN7_ADDRESS 0x00000044
+#define WLAN_GPIO_PIN7_OFFSET 0x00000044
+#define WLAN_GPIO_PIN7_CONFIG_MSB 13
+#define WLAN_GPIO_PIN7_CONFIG_LSB 11
+#define WLAN_GPIO_PIN7_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN7_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN7_CONFIG_MASK) >> WLAN_GPIO_PIN7_CONFIG_LSB)
+#define WLAN_GPIO_PIN7_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN7_CONFIG_LSB) & WLAN_GPIO_PIN7_CONFIG_MASK)
+#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN7_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN7_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN7_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN7_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN7_INT_TYPE_MASK) >> WLAN_GPIO_PIN7_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN7_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN7_INT_TYPE_LSB) & WLAN_GPIO_PIN7_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN7_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN7_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN7_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN7_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN7_PAD_PULL_MASK) >> WLAN_GPIO_PIN7_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN7_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN7_PAD_PULL_LSB) & WLAN_GPIO_PIN7_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN7_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN7_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN7_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN7_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN7_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN7_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN7_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN7_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN7_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN7_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN7_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN7_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN7_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN7_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN7_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN7_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN7_PAD_DRIVER_LSB) & WLAN_GPIO_PIN7_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN7_SOURCE_MSB 0
+#define WLAN_GPIO_PIN7_SOURCE_LSB 0
+#define WLAN_GPIO_PIN7_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN7_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN7_SOURCE_MASK) >> WLAN_GPIO_PIN7_SOURCE_LSB)
+#define WLAN_GPIO_PIN7_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN7_SOURCE_LSB) & WLAN_GPIO_PIN7_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN8_ADDRESS 0x00000048
+#define WLAN_GPIO_PIN8_OFFSET 0x00000048
+#define WLAN_GPIO_PIN8_CONFIG_MSB 13
+#define WLAN_GPIO_PIN8_CONFIG_LSB 11
+#define WLAN_GPIO_PIN8_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN8_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN8_CONFIG_MASK) >> WLAN_GPIO_PIN8_CONFIG_LSB)
+#define WLAN_GPIO_PIN8_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN8_CONFIG_LSB) & WLAN_GPIO_PIN8_CONFIG_MASK)
+#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN8_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN8_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN8_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN8_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN8_INT_TYPE_MASK) >> WLAN_GPIO_PIN8_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN8_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN8_INT_TYPE_LSB) & WLAN_GPIO_PIN8_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN8_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN8_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN8_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN8_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN8_PAD_PULL_MASK) >> WLAN_GPIO_PIN8_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN8_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN8_PAD_PULL_LSB) & WLAN_GPIO_PIN8_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN8_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN8_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN8_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN8_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN8_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN8_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN8_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN8_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN8_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN8_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN8_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN8_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN8_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN8_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN8_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN8_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN8_PAD_DRIVER_LSB) & WLAN_GPIO_PIN8_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN8_SOURCE_MSB 0
+#define WLAN_GPIO_PIN8_SOURCE_LSB 0
+#define WLAN_GPIO_PIN8_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN8_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN8_SOURCE_MASK) >> WLAN_GPIO_PIN8_SOURCE_LSB)
+#define WLAN_GPIO_PIN8_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN8_SOURCE_LSB) & WLAN_GPIO_PIN8_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN9_ADDRESS 0x0000004c
+#define WLAN_GPIO_PIN9_OFFSET 0x0000004c
+#define WLAN_GPIO_PIN9_CONFIG_MSB 13
+#define WLAN_GPIO_PIN9_CONFIG_LSB 11
+#define WLAN_GPIO_PIN9_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN9_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN9_CONFIG_MASK) >> WLAN_GPIO_PIN9_CONFIG_LSB)
+#define WLAN_GPIO_PIN9_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN9_CONFIG_LSB) & WLAN_GPIO_PIN9_CONFIG_MASK)
+#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN9_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN9_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN9_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN9_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN9_INT_TYPE_MASK) >> WLAN_GPIO_PIN9_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN9_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN9_INT_TYPE_LSB) & WLAN_GPIO_PIN9_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN9_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN9_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN9_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN9_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN9_PAD_PULL_MASK) >> WLAN_GPIO_PIN9_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN9_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN9_PAD_PULL_LSB) & WLAN_GPIO_PIN9_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN9_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN9_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN9_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN9_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN9_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN9_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN9_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN9_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN9_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN9_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN9_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN9_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN9_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN9_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN9_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN9_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN9_PAD_DRIVER_LSB) & WLAN_GPIO_PIN9_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN9_SOURCE_MSB 0
+#define WLAN_GPIO_PIN9_SOURCE_LSB 0
+#define WLAN_GPIO_PIN9_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN9_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN9_SOURCE_MASK) >> WLAN_GPIO_PIN9_SOURCE_LSB)
+#define WLAN_GPIO_PIN9_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN9_SOURCE_LSB) & WLAN_GPIO_PIN9_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN10_ADDRESS 0x00000050
+#define WLAN_GPIO_PIN10_OFFSET 0x00000050
+#define WLAN_GPIO_PIN10_CONFIG_MSB 13
+#define WLAN_GPIO_PIN10_CONFIG_LSB 11
+#define WLAN_GPIO_PIN10_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN10_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN10_CONFIG_MASK) >> WLAN_GPIO_PIN10_CONFIG_LSB)
+#define WLAN_GPIO_PIN10_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN10_CONFIG_LSB) & WLAN_GPIO_PIN10_CONFIG_MASK)
+#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN10_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN10_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN10_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN10_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN10_INT_TYPE_MASK) >> WLAN_GPIO_PIN10_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN10_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN10_INT_TYPE_LSB) & WLAN_GPIO_PIN10_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN10_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN10_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN10_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN10_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN10_PAD_PULL_MASK) >> WLAN_GPIO_PIN10_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN10_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN10_PAD_PULL_LSB) & WLAN_GPIO_PIN10_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN10_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN10_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN10_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN10_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN10_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN10_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN10_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN10_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN10_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN10_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN10_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN10_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN10_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN10_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN10_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN10_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN10_PAD_DRIVER_LSB) & WLAN_GPIO_PIN10_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN10_SOURCE_MSB 0
+#define WLAN_GPIO_PIN10_SOURCE_LSB 0
+#define WLAN_GPIO_PIN10_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN10_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN10_SOURCE_MASK) >> WLAN_GPIO_PIN10_SOURCE_LSB)
+#define WLAN_GPIO_PIN10_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN10_SOURCE_LSB) & WLAN_GPIO_PIN10_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN11_ADDRESS 0x00000054
+#define WLAN_GPIO_PIN11_OFFSET 0x00000054
+#define WLAN_GPIO_PIN11_CONFIG_MSB 13
+#define WLAN_GPIO_PIN11_CONFIG_LSB 11
+#define WLAN_GPIO_PIN11_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN11_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN11_CONFIG_MASK) >> WLAN_GPIO_PIN11_CONFIG_LSB)
+#define WLAN_GPIO_PIN11_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN11_CONFIG_LSB) & WLAN_GPIO_PIN11_CONFIG_MASK)
+#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN11_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN11_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN11_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN11_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN11_INT_TYPE_MASK) >> WLAN_GPIO_PIN11_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN11_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN11_INT_TYPE_LSB) & WLAN_GPIO_PIN11_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN11_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN11_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN11_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN11_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN11_PAD_PULL_MASK) >> WLAN_GPIO_PIN11_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN11_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN11_PAD_PULL_LSB) & WLAN_GPIO_PIN11_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN11_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN11_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN11_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN11_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN11_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN11_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN11_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN11_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN11_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN11_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN11_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN11_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN11_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN11_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN11_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN11_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN11_PAD_DRIVER_LSB) & WLAN_GPIO_PIN11_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN11_SOURCE_MSB 0
+#define WLAN_GPIO_PIN11_SOURCE_LSB 0
+#define WLAN_GPIO_PIN11_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN11_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN11_SOURCE_MASK) >> WLAN_GPIO_PIN11_SOURCE_LSB)
+#define WLAN_GPIO_PIN11_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN11_SOURCE_LSB) & WLAN_GPIO_PIN11_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN12_ADDRESS 0x00000058
+#define WLAN_GPIO_PIN12_OFFSET 0x00000058
+#define WLAN_GPIO_PIN12_CONFIG_MSB 13
+#define WLAN_GPIO_PIN12_CONFIG_LSB 11
+#define WLAN_GPIO_PIN12_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN12_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN12_CONFIG_MASK) >> WLAN_GPIO_PIN12_CONFIG_LSB)
+#define WLAN_GPIO_PIN12_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN12_CONFIG_LSB) & WLAN_GPIO_PIN12_CONFIG_MASK)
+#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN12_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN12_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN12_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN12_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN12_INT_TYPE_MASK) >> WLAN_GPIO_PIN12_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN12_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN12_INT_TYPE_LSB) & WLAN_GPIO_PIN12_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN12_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN12_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN12_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN12_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN12_PAD_PULL_MASK) >> WLAN_GPIO_PIN12_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN12_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN12_PAD_PULL_LSB) & WLAN_GPIO_PIN12_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN12_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN12_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN12_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN12_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN12_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN12_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN12_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN12_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN12_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN12_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN12_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN12_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN12_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN12_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN12_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN12_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN12_PAD_DRIVER_LSB) & WLAN_GPIO_PIN12_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN12_SOURCE_MSB 0
+#define WLAN_GPIO_PIN12_SOURCE_LSB 0
+#define WLAN_GPIO_PIN12_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN12_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN12_SOURCE_MASK) >> WLAN_GPIO_PIN12_SOURCE_LSB)
+#define WLAN_GPIO_PIN12_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN12_SOURCE_LSB) & WLAN_GPIO_PIN12_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN13_ADDRESS 0x0000005c
+#define WLAN_GPIO_PIN13_OFFSET 0x0000005c
+#define WLAN_GPIO_PIN13_CONFIG_MSB 13
+#define WLAN_GPIO_PIN13_CONFIG_LSB 11
+#define WLAN_GPIO_PIN13_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN13_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN13_CONFIG_MASK) >> WLAN_GPIO_PIN13_CONFIG_LSB)
+#define WLAN_GPIO_PIN13_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN13_CONFIG_LSB) & WLAN_GPIO_PIN13_CONFIG_MASK)
+#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN13_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN13_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN13_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN13_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN13_INT_TYPE_MASK) >> WLAN_GPIO_PIN13_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN13_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN13_INT_TYPE_LSB) & WLAN_GPIO_PIN13_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN13_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN13_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN13_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN13_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN13_PAD_PULL_MASK) >> WLAN_GPIO_PIN13_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN13_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN13_PAD_PULL_LSB) & WLAN_GPIO_PIN13_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN13_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN13_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN13_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN13_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN13_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN13_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN13_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN13_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN13_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN13_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN13_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN13_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN13_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN13_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN13_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN13_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN13_PAD_DRIVER_LSB) & WLAN_GPIO_PIN13_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN13_SOURCE_MSB 0
+#define WLAN_GPIO_PIN13_SOURCE_LSB 0
+#define WLAN_GPIO_PIN13_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN13_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN13_SOURCE_MASK) >> WLAN_GPIO_PIN13_SOURCE_LSB)
+#define WLAN_GPIO_PIN13_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN13_SOURCE_LSB) & WLAN_GPIO_PIN13_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN14_ADDRESS 0x00000060
+#define WLAN_GPIO_PIN14_OFFSET 0x00000060
+#define WLAN_GPIO_PIN14_CONFIG_MSB 13
+#define WLAN_GPIO_PIN14_CONFIG_LSB 11
+#define WLAN_GPIO_PIN14_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN14_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN14_CONFIG_MASK) >> WLAN_GPIO_PIN14_CONFIG_LSB)
+#define WLAN_GPIO_PIN14_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN14_CONFIG_LSB) & WLAN_GPIO_PIN14_CONFIG_MASK)
+#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN14_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN14_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN14_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN14_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN14_INT_TYPE_MASK) >> WLAN_GPIO_PIN14_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN14_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN14_INT_TYPE_LSB) & WLAN_GPIO_PIN14_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN14_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN14_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN14_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN14_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN14_PAD_PULL_MASK) >> WLAN_GPIO_PIN14_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN14_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN14_PAD_PULL_LSB) & WLAN_GPIO_PIN14_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN14_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN14_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN14_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN14_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN14_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN14_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN14_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN14_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN14_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN14_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN14_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN14_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN14_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN14_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN14_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN14_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN14_PAD_DRIVER_LSB) & WLAN_GPIO_PIN14_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN14_SOURCE_MSB 0
+#define WLAN_GPIO_PIN14_SOURCE_LSB 0
+#define WLAN_GPIO_PIN14_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN14_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN14_SOURCE_MASK) >> WLAN_GPIO_PIN14_SOURCE_LSB)
+#define WLAN_GPIO_PIN14_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN14_SOURCE_LSB) & WLAN_GPIO_PIN14_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN15_ADDRESS 0x00000064
+#define WLAN_GPIO_PIN15_OFFSET 0x00000064
+#define WLAN_GPIO_PIN15_CONFIG_MSB 13
+#define WLAN_GPIO_PIN15_CONFIG_LSB 11
+#define WLAN_GPIO_PIN15_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN15_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN15_CONFIG_MASK) >> WLAN_GPIO_PIN15_CONFIG_LSB)
+#define WLAN_GPIO_PIN15_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN15_CONFIG_LSB) & WLAN_GPIO_PIN15_CONFIG_MASK)
+#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN15_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN15_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN15_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN15_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN15_INT_TYPE_MASK) >> WLAN_GPIO_PIN15_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN15_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN15_INT_TYPE_LSB) & WLAN_GPIO_PIN15_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN15_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN15_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN15_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN15_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN15_PAD_PULL_MASK) >> WLAN_GPIO_PIN15_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN15_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN15_PAD_PULL_LSB) & WLAN_GPIO_PIN15_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN15_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN15_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN15_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN15_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN15_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN15_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN15_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN15_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN15_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN15_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN15_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN15_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN15_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN15_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN15_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN15_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN15_PAD_DRIVER_LSB) & WLAN_GPIO_PIN15_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN15_SOURCE_MSB 0
+#define WLAN_GPIO_PIN15_SOURCE_LSB 0
+#define WLAN_GPIO_PIN15_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN15_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN15_SOURCE_MASK) >> WLAN_GPIO_PIN15_SOURCE_LSB)
+#define WLAN_GPIO_PIN15_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN15_SOURCE_LSB) & WLAN_GPIO_PIN15_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN16_ADDRESS 0x00000068
+#define WLAN_GPIO_PIN16_OFFSET 0x00000068
+#define WLAN_GPIO_PIN16_CONFIG_MSB 13
+#define WLAN_GPIO_PIN16_CONFIG_LSB 11
+#define WLAN_GPIO_PIN16_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN16_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN16_CONFIG_MASK) >> WLAN_GPIO_PIN16_CONFIG_LSB)
+#define WLAN_GPIO_PIN16_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN16_CONFIG_LSB) & WLAN_GPIO_PIN16_CONFIG_MASK)
+#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN16_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN16_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN16_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN16_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN16_INT_TYPE_MASK) >> WLAN_GPIO_PIN16_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN16_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN16_INT_TYPE_LSB) & WLAN_GPIO_PIN16_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN16_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN16_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN16_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN16_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN16_PAD_PULL_MASK) >> WLAN_GPIO_PIN16_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN16_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN16_PAD_PULL_LSB) & WLAN_GPIO_PIN16_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN16_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN16_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN16_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN16_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN16_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN16_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN16_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN16_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN16_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN16_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN16_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN16_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN16_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN16_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN16_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN16_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN16_PAD_DRIVER_LSB) & WLAN_GPIO_PIN16_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN16_SOURCE_MSB 0
+#define WLAN_GPIO_PIN16_SOURCE_LSB 0
+#define WLAN_GPIO_PIN16_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN16_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN16_SOURCE_MASK) >> WLAN_GPIO_PIN16_SOURCE_LSB)
+#define WLAN_GPIO_PIN16_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN16_SOURCE_LSB) & WLAN_GPIO_PIN16_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN17_ADDRESS 0x0000006c
+#define WLAN_GPIO_PIN17_OFFSET 0x0000006c
+#define WLAN_GPIO_PIN17_CONFIG_MSB 13
+#define WLAN_GPIO_PIN17_CONFIG_LSB 11
+#define WLAN_GPIO_PIN17_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN17_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN17_CONFIG_MASK) >> WLAN_GPIO_PIN17_CONFIG_LSB)
+#define WLAN_GPIO_PIN17_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN17_CONFIG_LSB) & WLAN_GPIO_PIN17_CONFIG_MASK)
+#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN17_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN17_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN17_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN17_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN17_INT_TYPE_MASK) >> WLAN_GPIO_PIN17_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN17_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN17_INT_TYPE_LSB) & WLAN_GPIO_PIN17_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN17_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN17_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN17_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN17_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN17_PAD_PULL_MASK) >> WLAN_GPIO_PIN17_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN17_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN17_PAD_PULL_LSB) & WLAN_GPIO_PIN17_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN17_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN17_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN17_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN17_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN17_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN17_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN17_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN17_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN17_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN17_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN17_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN17_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN17_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN17_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN17_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN17_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN17_PAD_DRIVER_LSB) & WLAN_GPIO_PIN17_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN17_SOURCE_MSB 0
+#define WLAN_GPIO_PIN17_SOURCE_LSB 0
+#define WLAN_GPIO_PIN17_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN17_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN17_SOURCE_MASK) >> WLAN_GPIO_PIN17_SOURCE_LSB)
+#define WLAN_GPIO_PIN17_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN17_SOURCE_LSB) & WLAN_GPIO_PIN17_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN18_ADDRESS 0x00000070
+#define WLAN_GPIO_PIN18_OFFSET 0x00000070
+#define WLAN_GPIO_PIN18_CONFIG_MSB 13
+#define WLAN_GPIO_PIN18_CONFIG_LSB 11
+#define WLAN_GPIO_PIN18_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN18_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN18_CONFIG_MASK) >> WLAN_GPIO_PIN18_CONFIG_LSB)
+#define WLAN_GPIO_PIN18_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN18_CONFIG_LSB) & WLAN_GPIO_PIN18_CONFIG_MASK)
+#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN18_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN18_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN18_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN18_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN18_INT_TYPE_MASK) >> WLAN_GPIO_PIN18_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN18_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN18_INT_TYPE_LSB) & WLAN_GPIO_PIN18_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN18_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN18_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN18_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN18_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN18_PAD_PULL_MASK) >> WLAN_GPIO_PIN18_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN18_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN18_PAD_PULL_LSB) & WLAN_GPIO_PIN18_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN18_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN18_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN18_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN18_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN18_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN18_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN18_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN18_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN18_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN18_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN18_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN18_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN18_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN18_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN18_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN18_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN18_PAD_DRIVER_LSB) & WLAN_GPIO_PIN18_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN18_SOURCE_MSB 0
+#define WLAN_GPIO_PIN18_SOURCE_LSB 0
+#define WLAN_GPIO_PIN18_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN18_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN18_SOURCE_MASK) >> WLAN_GPIO_PIN18_SOURCE_LSB)
+#define WLAN_GPIO_PIN18_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN18_SOURCE_LSB) & WLAN_GPIO_PIN18_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN19_ADDRESS 0x00000074
+#define WLAN_GPIO_PIN19_OFFSET 0x00000074
+#define WLAN_GPIO_PIN19_CONFIG_MSB 13
+#define WLAN_GPIO_PIN19_CONFIG_LSB 11
+#define WLAN_GPIO_PIN19_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN19_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN19_CONFIG_MASK) >> WLAN_GPIO_PIN19_CONFIG_LSB)
+#define WLAN_GPIO_PIN19_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN19_CONFIG_LSB) & WLAN_GPIO_PIN19_CONFIG_MASK)
+#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN19_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN19_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN19_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN19_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN19_INT_TYPE_MASK) >> WLAN_GPIO_PIN19_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN19_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN19_INT_TYPE_LSB) & WLAN_GPIO_PIN19_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN19_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN19_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN19_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN19_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN19_PAD_PULL_MASK) >> WLAN_GPIO_PIN19_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN19_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN19_PAD_PULL_LSB) & WLAN_GPIO_PIN19_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN19_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN19_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN19_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN19_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN19_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN19_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN19_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN19_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN19_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN19_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN19_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN19_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN19_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN19_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN19_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN19_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN19_PAD_DRIVER_LSB) & WLAN_GPIO_PIN19_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN19_SOURCE_MSB 0
+#define WLAN_GPIO_PIN19_SOURCE_LSB 0
+#define WLAN_GPIO_PIN19_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN19_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN19_SOURCE_MASK) >> WLAN_GPIO_PIN19_SOURCE_LSB)
+#define WLAN_GPIO_PIN19_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN19_SOURCE_LSB) & WLAN_GPIO_PIN19_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN20_ADDRESS 0x00000078
+#define WLAN_GPIO_PIN20_OFFSET 0x00000078
+#define WLAN_GPIO_PIN20_CONFIG_MSB 13
+#define WLAN_GPIO_PIN20_CONFIG_LSB 11
+#define WLAN_GPIO_PIN20_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN20_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN20_CONFIG_MASK) >> WLAN_GPIO_PIN20_CONFIG_LSB)
+#define WLAN_GPIO_PIN20_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN20_CONFIG_LSB) & WLAN_GPIO_PIN20_CONFIG_MASK)
+#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN20_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN20_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN20_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN20_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN20_INT_TYPE_MASK) >> WLAN_GPIO_PIN20_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN20_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN20_INT_TYPE_LSB) & WLAN_GPIO_PIN20_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN20_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN20_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN20_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN20_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN20_PAD_PULL_MASK) >> WLAN_GPIO_PIN20_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN20_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN20_PAD_PULL_LSB) & WLAN_GPIO_PIN20_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN20_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN20_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN20_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN20_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN20_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN20_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN20_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN20_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN20_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN20_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN20_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN20_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN20_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN20_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN20_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN20_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN20_PAD_DRIVER_LSB) & WLAN_GPIO_PIN20_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN20_SOURCE_MSB 0
+#define WLAN_GPIO_PIN20_SOURCE_LSB 0
+#define WLAN_GPIO_PIN20_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN20_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN20_SOURCE_MASK) >> WLAN_GPIO_PIN20_SOURCE_LSB)
+#define WLAN_GPIO_PIN20_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN20_SOURCE_LSB) & WLAN_GPIO_PIN20_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN21_ADDRESS 0x0000007c
+#define WLAN_GPIO_PIN21_OFFSET 0x0000007c
+#define WLAN_GPIO_PIN21_CONFIG_MSB 13
+#define WLAN_GPIO_PIN21_CONFIG_LSB 11
+#define WLAN_GPIO_PIN21_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN21_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN21_CONFIG_MASK) >> WLAN_GPIO_PIN21_CONFIG_LSB)
+#define WLAN_GPIO_PIN21_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN21_CONFIG_LSB) & WLAN_GPIO_PIN21_CONFIG_MASK)
+#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN21_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN21_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN21_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN21_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN21_INT_TYPE_MASK) >> WLAN_GPIO_PIN21_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN21_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN21_INT_TYPE_LSB) & WLAN_GPIO_PIN21_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN21_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN21_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN21_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN21_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN21_PAD_PULL_MASK) >> WLAN_GPIO_PIN21_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN21_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN21_PAD_PULL_LSB) & WLAN_GPIO_PIN21_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN21_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN21_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN21_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN21_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN21_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN21_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN21_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN21_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN21_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN21_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN21_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN21_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN21_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN21_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN21_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN21_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN21_PAD_DRIVER_LSB) & WLAN_GPIO_PIN21_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN21_SOURCE_MSB 0
+#define WLAN_GPIO_PIN21_SOURCE_LSB 0
+#define WLAN_GPIO_PIN21_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN21_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN21_SOURCE_MASK) >> WLAN_GPIO_PIN21_SOURCE_LSB)
+#define WLAN_GPIO_PIN21_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN21_SOURCE_LSB) & WLAN_GPIO_PIN21_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN22_ADDRESS 0x00000080
+#define WLAN_GPIO_PIN22_OFFSET 0x00000080
+#define WLAN_GPIO_PIN22_CONFIG_MSB 13
+#define WLAN_GPIO_PIN22_CONFIG_LSB 11
+#define WLAN_GPIO_PIN22_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN22_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN22_CONFIG_MASK) >> WLAN_GPIO_PIN22_CONFIG_LSB)
+#define WLAN_GPIO_PIN22_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN22_CONFIG_LSB) & WLAN_GPIO_PIN22_CONFIG_MASK)
+#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN22_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN22_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN22_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN22_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN22_INT_TYPE_MASK) >> WLAN_GPIO_PIN22_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN22_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN22_INT_TYPE_LSB) & WLAN_GPIO_PIN22_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN22_PAD_PULL_MSB 6
+#define WLAN_GPIO_PIN22_PAD_PULL_LSB 5
+#define WLAN_GPIO_PIN22_PAD_PULL_MASK 0x00000060
+#define WLAN_GPIO_PIN22_PAD_PULL_GET(x) (((x) & WLAN_GPIO_PIN22_PAD_PULL_MASK) >> WLAN_GPIO_PIN22_PAD_PULL_LSB)
+#define WLAN_GPIO_PIN22_PAD_PULL_SET(x) (((x) << WLAN_GPIO_PIN22_PAD_PULL_LSB) & WLAN_GPIO_PIN22_PAD_PULL_MASK)
+#define WLAN_GPIO_PIN22_PAD_STRENGTH_MSB 4
+#define WLAN_GPIO_PIN22_PAD_STRENGTH_LSB 3
+#define WLAN_GPIO_PIN22_PAD_STRENGTH_MASK 0x00000018
+#define WLAN_GPIO_PIN22_PAD_STRENGTH_GET(x) (((x) & WLAN_GPIO_PIN22_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN22_PAD_STRENGTH_LSB)
+#define WLAN_GPIO_PIN22_PAD_STRENGTH_SET(x) (((x) << WLAN_GPIO_PIN22_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN22_PAD_STRENGTH_MASK)
+#define WLAN_GPIO_PIN22_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN22_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN22_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN22_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN22_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN22_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN22_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN22_PAD_DRIVER_LSB) & WLAN_GPIO_PIN22_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN22_SOURCE_MSB 0
+#define WLAN_GPIO_PIN22_SOURCE_LSB 0
+#define WLAN_GPIO_PIN22_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN22_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN22_SOURCE_MASK) >> WLAN_GPIO_PIN22_SOURCE_LSB)
+#define WLAN_GPIO_PIN22_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN22_SOURCE_LSB) & WLAN_GPIO_PIN22_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN23_ADDRESS 0x00000084
+#define WLAN_GPIO_PIN23_OFFSET 0x00000084
+#define WLAN_GPIO_PIN23_CONFIG_MSB 13
+#define WLAN_GPIO_PIN23_CONFIG_LSB 11
+#define WLAN_GPIO_PIN23_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN23_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN23_CONFIG_MASK) >> WLAN_GPIO_PIN23_CONFIG_LSB)
+#define WLAN_GPIO_PIN23_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN23_CONFIG_LSB) & WLAN_GPIO_PIN23_CONFIG_MASK)
+#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN23_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN23_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN23_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN23_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN23_INT_TYPE_MASK) >> WLAN_GPIO_PIN23_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN23_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN23_INT_TYPE_LSB) & WLAN_GPIO_PIN23_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN23_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN23_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN23_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN23_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN23_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN23_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN23_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN23_PAD_DRIVER_LSB) & WLAN_GPIO_PIN23_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN23_SOURCE_MSB 0
+#define WLAN_GPIO_PIN23_SOURCE_LSB 0
+#define WLAN_GPIO_PIN23_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN23_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN23_SOURCE_MASK) >> WLAN_GPIO_PIN23_SOURCE_LSB)
+#define WLAN_GPIO_PIN23_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN23_SOURCE_LSB) & WLAN_GPIO_PIN23_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN24_ADDRESS 0x00000088
+#define WLAN_GPIO_PIN24_OFFSET 0x00000088
+#define WLAN_GPIO_PIN24_CONFIG_MSB 13
+#define WLAN_GPIO_PIN24_CONFIG_LSB 11
+#define WLAN_GPIO_PIN24_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN24_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN24_CONFIG_MASK) >> WLAN_GPIO_PIN24_CONFIG_LSB)
+#define WLAN_GPIO_PIN24_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN24_CONFIG_LSB) & WLAN_GPIO_PIN24_CONFIG_MASK)
+#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN24_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN24_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN24_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN24_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN24_INT_TYPE_MASK) >> WLAN_GPIO_PIN24_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN24_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN24_INT_TYPE_LSB) & WLAN_GPIO_PIN24_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN24_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN24_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN24_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN24_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN24_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN24_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN24_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN24_PAD_DRIVER_LSB) & WLAN_GPIO_PIN24_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN24_SOURCE_MSB 0
+#define WLAN_GPIO_PIN24_SOURCE_LSB 0
+#define WLAN_GPIO_PIN24_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN24_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN24_SOURCE_MASK) >> WLAN_GPIO_PIN24_SOURCE_LSB)
+#define WLAN_GPIO_PIN24_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN24_SOURCE_LSB) & WLAN_GPIO_PIN24_SOURCE_MASK)
+
+#define WLAN_GPIO_PIN25_ADDRESS 0x0000008c
+#define WLAN_GPIO_PIN25_OFFSET 0x0000008c
+#define WLAN_GPIO_PIN25_CONFIG_MSB 13
+#define WLAN_GPIO_PIN25_CONFIG_LSB 11
+#define WLAN_GPIO_PIN25_CONFIG_MASK 0x00003800
+#define WLAN_GPIO_PIN25_CONFIG_GET(x) (((x) & WLAN_GPIO_PIN25_CONFIG_MASK) >> WLAN_GPIO_PIN25_CONFIG_LSB)
+#define WLAN_GPIO_PIN25_CONFIG_SET(x) (((x) << WLAN_GPIO_PIN25_CONFIG_LSB) & WLAN_GPIO_PIN25_CONFIG_MASK)
+#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_MSB 10
+#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB 10
+#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK 0x00000400
+#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_GET(x) (((x) & WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB)
+#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_SET(x) (((x) << WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK)
+#define WLAN_GPIO_PIN25_INT_TYPE_MSB 9
+#define WLAN_GPIO_PIN25_INT_TYPE_LSB 7
+#define WLAN_GPIO_PIN25_INT_TYPE_MASK 0x00000380
+#define WLAN_GPIO_PIN25_INT_TYPE_GET(x) (((x) & WLAN_GPIO_PIN25_INT_TYPE_MASK) >> WLAN_GPIO_PIN25_INT_TYPE_LSB)
+#define WLAN_GPIO_PIN25_INT_TYPE_SET(x) (((x) << WLAN_GPIO_PIN25_INT_TYPE_LSB) & WLAN_GPIO_PIN25_INT_TYPE_MASK)
+#define WLAN_GPIO_PIN25_PAD_DRIVER_MSB 2
+#define WLAN_GPIO_PIN25_PAD_DRIVER_LSB 2
+#define WLAN_GPIO_PIN25_PAD_DRIVER_MASK 0x00000004
+#define WLAN_GPIO_PIN25_PAD_DRIVER_GET(x) (((x) & WLAN_GPIO_PIN25_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN25_PAD_DRIVER_LSB)
+#define WLAN_GPIO_PIN25_PAD_DRIVER_SET(x) (((x) << WLAN_GPIO_PIN25_PAD_DRIVER_LSB) & WLAN_GPIO_PIN25_PAD_DRIVER_MASK)
+#define WLAN_GPIO_PIN25_SOURCE_MSB 0
+#define WLAN_GPIO_PIN25_SOURCE_LSB 0
+#define WLAN_GPIO_PIN25_SOURCE_MASK 0x00000001
+#define WLAN_GPIO_PIN25_SOURCE_GET(x) (((x) & WLAN_GPIO_PIN25_SOURCE_MASK) >> WLAN_GPIO_PIN25_SOURCE_LSB)
+#define WLAN_GPIO_PIN25_SOURCE_SET(x) (((x) << WLAN_GPIO_PIN25_SOURCE_LSB) & WLAN_GPIO_PIN25_SOURCE_MASK)
+
+#define SDIO_ADDRESS 0x00000090
+#define SDIO_OFFSET 0x00000090
+#define SDIO_PINS_EN_MSB 0
+#define SDIO_PINS_EN_LSB 0
+#define SDIO_PINS_EN_MASK 0x00000001
+#define SDIO_PINS_EN_GET(x) (((x) & SDIO_PINS_EN_MASK) >> SDIO_PINS_EN_LSB)
+#define SDIO_PINS_EN_SET(x) (((x) << SDIO_PINS_EN_LSB) & SDIO_PINS_EN_MASK)
+
+#define FUNC_BUS_ADDRESS 0x00000094
+#define FUNC_BUS_OFFSET 0x00000094
+#define FUNC_BUS_GPIO_MODE_MSB 22
+#define FUNC_BUS_GPIO_MODE_LSB 22
+#define FUNC_BUS_GPIO_MODE_MASK 0x00400000
+#define FUNC_BUS_GPIO_MODE_GET(x) (((x) & FUNC_BUS_GPIO_MODE_MASK) >> FUNC_BUS_GPIO_MODE_LSB)
+#define FUNC_BUS_GPIO_MODE_SET(x) (((x) << FUNC_BUS_GPIO_MODE_LSB) & FUNC_BUS_GPIO_MODE_MASK)
+#define FUNC_BUS_OE_L_MSB 21
+#define FUNC_BUS_OE_L_LSB 0
+#define FUNC_BUS_OE_L_MASK 0x003fffff
+#define FUNC_BUS_OE_L_GET(x) (((x) & FUNC_BUS_OE_L_MASK) >> FUNC_BUS_OE_L_LSB)
+#define FUNC_BUS_OE_L_SET(x) (((x) << FUNC_BUS_OE_L_LSB) & FUNC_BUS_OE_L_MASK)
+
+#define WL_SOC_APB_ADDRESS 0x00000098
+#define WL_SOC_APB_OFFSET 0x00000098
+#define WL_SOC_APB_TOGGLE_MSB 0
+#define WL_SOC_APB_TOGGLE_LSB 0
+#define WL_SOC_APB_TOGGLE_MASK 0x00000001
+#define WL_SOC_APB_TOGGLE_GET(x) (((x) & WL_SOC_APB_TOGGLE_MASK) >> WL_SOC_APB_TOGGLE_LSB)
+#define WL_SOC_APB_TOGGLE_SET(x) (((x) << WL_SOC_APB_TOGGLE_LSB) & WL_SOC_APB_TOGGLE_MASK)
+
+#define WLAN_SIGMA_DELTA_ADDRESS 0x0000009c
+#define WLAN_SIGMA_DELTA_OFFSET 0x0000009c
+#define WLAN_SIGMA_DELTA_ENABLE_MSB 16
+#define WLAN_SIGMA_DELTA_ENABLE_LSB 16
+#define WLAN_SIGMA_DELTA_ENABLE_MASK 0x00010000
+#define WLAN_SIGMA_DELTA_ENABLE_GET(x) (((x) & WLAN_SIGMA_DELTA_ENABLE_MASK) >> WLAN_SIGMA_DELTA_ENABLE_LSB)
+#define WLAN_SIGMA_DELTA_ENABLE_SET(x) (((x) << WLAN_SIGMA_DELTA_ENABLE_LSB) & WLAN_SIGMA_DELTA_ENABLE_MASK)
+#define WLAN_SIGMA_DELTA_PRESCALAR_MSB 15
+#define WLAN_SIGMA_DELTA_PRESCALAR_LSB 8
+#define WLAN_SIGMA_DELTA_PRESCALAR_MASK 0x0000ff00
+#define WLAN_SIGMA_DELTA_PRESCALAR_GET(x) (((x) & WLAN_SIGMA_DELTA_PRESCALAR_MASK) >> WLAN_SIGMA_DELTA_PRESCALAR_LSB)
+#define WLAN_SIGMA_DELTA_PRESCALAR_SET(x) (((x) << WLAN_SIGMA_DELTA_PRESCALAR_LSB) & WLAN_SIGMA_DELTA_PRESCALAR_MASK)
+#define WLAN_SIGMA_DELTA_TARGET_MSB 7
+#define WLAN_SIGMA_DELTA_TARGET_LSB 0
+#define WLAN_SIGMA_DELTA_TARGET_MASK 0x000000ff
+#define WLAN_SIGMA_DELTA_TARGET_GET(x) (((x) & WLAN_SIGMA_DELTA_TARGET_MASK) >> WLAN_SIGMA_DELTA_TARGET_LSB)
+#define WLAN_SIGMA_DELTA_TARGET_SET(x) (((x) << WLAN_SIGMA_DELTA_TARGET_LSB) & WLAN_SIGMA_DELTA_TARGET_MASK)
+
+#define WL_BOOTSTRAP_ADDRESS 0x000000a0
+#define WL_BOOTSTRAP_OFFSET 0x000000a0
+#define WL_BOOTSTRAP_STATUS_MSB 22
+#define WL_BOOTSTRAP_STATUS_LSB 0
+#define WL_BOOTSTRAP_STATUS_MASK 0x007fffff
+#define WL_BOOTSTRAP_STATUS_GET(x) (((x) & WL_BOOTSTRAP_STATUS_MASK) >> WL_BOOTSTRAP_STATUS_LSB)
+#define WL_BOOTSTRAP_STATUS_SET(x) (((x) << WL_BOOTSTRAP_STATUS_LSB) & WL_BOOTSTRAP_STATUS_MASK)
+
+#define CLOCK_GPIO_ADDRESS 0x000000a4
+#define CLOCK_GPIO_OFFSET 0x000000a4
+#define CLOCK_GPIO_CLK_REQ_OUT_EN_MSB 2
+#define CLOCK_GPIO_CLK_REQ_OUT_EN_LSB 2
+#define CLOCK_GPIO_CLK_REQ_OUT_EN_MASK 0x00000004
+#define CLOCK_GPIO_CLK_REQ_OUT_EN_GET(x) (((x) & CLOCK_GPIO_CLK_REQ_OUT_EN_MASK) >> CLOCK_GPIO_CLK_REQ_OUT_EN_LSB)
+#define CLOCK_GPIO_CLK_REQ_OUT_EN_SET(x) (((x) << CLOCK_GPIO_CLK_REQ_OUT_EN_LSB) & CLOCK_GPIO_CLK_REQ_OUT_EN_MASK)
+#define CLOCK_GPIO_BT_CLK_REQ_EN_MSB 1
+#define CLOCK_GPIO_BT_CLK_REQ_EN_LSB 1
+#define CLOCK_GPIO_BT_CLK_REQ_EN_MASK 0x00000002
+#define CLOCK_GPIO_BT_CLK_REQ_EN_GET(x) (((x) & CLOCK_GPIO_BT_CLK_REQ_EN_MASK) >> CLOCK_GPIO_BT_CLK_REQ_EN_LSB)
+#define CLOCK_GPIO_BT_CLK_REQ_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_REQ_EN_LSB) & CLOCK_GPIO_BT_CLK_REQ_EN_MASK)
+#define CLOCK_GPIO_BT_CLK_OUT_EN_MSB 0
+#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0
+#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0x00000001
+#define CLOCK_GPIO_BT_CLK_OUT_EN_GET(x) (((x) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) >> CLOCK_GPIO_BT_CLK_OUT_EN_LSB)
+#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
+
+#define WLAN_DEBUG_CONTROL_ADDRESS 0x000000a8
+#define WLAN_DEBUG_CONTROL_OFFSET 0x000000a8
+#define WLAN_DEBUG_CONTROL_ENABLE_MSB 0
+#define WLAN_DEBUG_CONTROL_ENABLE_LSB 0
+#define WLAN_DEBUG_CONTROL_ENABLE_MASK 0x00000001
+#define WLAN_DEBUG_CONTROL_ENABLE_GET(x) (((x) & WLAN_DEBUG_CONTROL_ENABLE_MASK) >> WLAN_DEBUG_CONTROL_ENABLE_LSB)
+#define WLAN_DEBUG_CONTROL_ENABLE_SET(x) (((x) << WLAN_DEBUG_CONTROL_ENABLE_LSB) & WLAN_DEBUG_CONTROL_ENABLE_MASK)
+
+#define WLAN_DEBUG_INPUT_SEL_ADDRESS 0x000000ac
+#define WLAN_DEBUG_INPUT_SEL_OFFSET 0x000000ac
+#define WLAN_DEBUG_INPUT_SEL_SHIFT_MSB 5
+#define WLAN_DEBUG_INPUT_SEL_SHIFT_LSB 4
+#define WLAN_DEBUG_INPUT_SEL_SHIFT_MASK 0x00000030
+#define WLAN_DEBUG_INPUT_SEL_SHIFT_GET(x) (((x) & WLAN_DEBUG_INPUT_SEL_SHIFT_MASK) >> WLAN_DEBUG_INPUT_SEL_SHIFT_LSB)
+#define WLAN_DEBUG_INPUT_SEL_SHIFT_SET(x) (((x) << WLAN_DEBUG_INPUT_SEL_SHIFT_LSB) & WLAN_DEBUG_INPUT_SEL_SHIFT_MASK)
+#define WLAN_DEBUG_INPUT_SEL_SRC_MSB 3
+#define WLAN_DEBUG_INPUT_SEL_SRC_LSB 0
+#define WLAN_DEBUG_INPUT_SEL_SRC_MASK 0x0000000f
+#define WLAN_DEBUG_INPUT_SEL_SRC_GET(x) (((x) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) >> WLAN_DEBUG_INPUT_SEL_SRC_LSB)
+#define WLAN_DEBUG_INPUT_SEL_SRC_SET(x) (((x) << WLAN_DEBUG_INPUT_SEL_SRC_LSB) & WLAN_DEBUG_INPUT_SEL_SRC_MASK)
+
+#define WLAN_DEBUG_OUT_ADDRESS 0x000000b0
+#define WLAN_DEBUG_OUT_OFFSET 0x000000b0
+#define WLAN_DEBUG_OUT_DATA_MSB 17
+#define WLAN_DEBUG_OUT_DATA_LSB 0
+#define WLAN_DEBUG_OUT_DATA_MASK 0x0003ffff
+#define WLAN_DEBUG_OUT_DATA_GET(x) (((x) & WLAN_DEBUG_OUT_DATA_MASK) >> WLAN_DEBUG_OUT_DATA_LSB)
+#define WLAN_DEBUG_OUT_DATA_SET(x) (((x) << WLAN_DEBUG_OUT_DATA_LSB) & WLAN_DEBUG_OUT_DATA_MASK)
+
+#define WLAN_RESET_TUPLE_STATUS_ADDRESS 0x000000b4
+#define WLAN_RESET_TUPLE_STATUS_OFFSET 0x000000b4
+#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB 11
+#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB 8
+#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK 0x00000f00
+#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) (((x) & WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) >> WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB)
+#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) (((x) << WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) & WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK)
+#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB 7
+#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB 0
+#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK 0x000000ff
+#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) (((x) & WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) >> WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB)
+#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) (((x) << WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) & WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK)
+
+#define ANTENNA_SLEEP_CONTROL_ADDRESS 0x000000b8
+#define ANTENNA_SLEEP_CONTROL_OFFSET 0x000000b8
+#define ANTENNA_SLEEP_CONTROL_OVERRIDE_MSB 14
+#define ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB 10
+#define ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK 0x00007c00
+#define ANTENNA_SLEEP_CONTROL_OVERRIDE_GET(x) (((x) & ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK) >> ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB)
+#define ANTENNA_SLEEP_CONTROL_OVERRIDE_SET(x) (((x) << ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB) & ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK)
+#define ANTENNA_SLEEP_CONTROL_VALUE_MSB 9
+#define ANTENNA_SLEEP_CONTROL_VALUE_LSB 5
+#define ANTENNA_SLEEP_CONTROL_VALUE_MASK 0x000003e0
+#define ANTENNA_SLEEP_CONTROL_VALUE_GET(x) (((x) & ANTENNA_SLEEP_CONTROL_VALUE_MASK) >> ANTENNA_SLEEP_CONTROL_VALUE_LSB)
+#define ANTENNA_SLEEP_CONTROL_VALUE_SET(x) (((x) << ANTENNA_SLEEP_CONTROL_VALUE_LSB) & ANTENNA_SLEEP_CONTROL_VALUE_MASK)
+#define ANTENNA_SLEEP_CONTROL_ENABLE_MSB 4
+#define ANTENNA_SLEEP_CONTROL_ENABLE_LSB 0
+#define ANTENNA_SLEEP_CONTROL_ENABLE_MASK 0x0000001f
+#define ANTENNA_SLEEP_CONTROL_ENABLE_GET(x) (((x) & ANTENNA_SLEEP_CONTROL_ENABLE_MASK) >> ANTENNA_SLEEP_CONTROL_ENABLE_LSB)
+#define ANTENNA_SLEEP_CONTROL_ENABLE_SET(x) (((x) << ANTENNA_SLEEP_CONTROL_ENABLE_LSB) & ANTENNA_SLEEP_CONTROL_ENABLE_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct gpio_athr_wlan_reg_reg_s {
+ volatile unsigned int wlan_gpio_out;
+ volatile unsigned int wlan_gpio_out_w1ts;
+ volatile unsigned int wlan_gpio_out_w1tc;
+ volatile unsigned int wlan_gpio_enable;
+ volatile unsigned int wlan_gpio_enable_w1ts;
+ volatile unsigned int wlan_gpio_enable_w1tc;
+ volatile unsigned int wlan_gpio_in;
+ volatile unsigned int wlan_gpio_status;
+ volatile unsigned int wlan_gpio_status_w1ts;
+ volatile unsigned int wlan_gpio_status_w1tc;
+ volatile unsigned int wlan_gpio_pin0;
+ volatile unsigned int wlan_gpio_pin1;
+ volatile unsigned int wlan_gpio_pin2;
+ volatile unsigned int wlan_gpio_pin3;
+ volatile unsigned int wlan_gpio_pin4;
+ volatile unsigned int wlan_gpio_pin5;
+ volatile unsigned int wlan_gpio_pin6;
+ volatile unsigned int wlan_gpio_pin7;
+ volatile unsigned int wlan_gpio_pin8;
+ volatile unsigned int wlan_gpio_pin9;
+ volatile unsigned int wlan_gpio_pin10;
+ volatile unsigned int wlan_gpio_pin11;
+ volatile unsigned int wlan_gpio_pin12;
+ volatile unsigned int wlan_gpio_pin13;
+ volatile unsigned int wlan_gpio_pin14;
+ volatile unsigned int wlan_gpio_pin15;
+ volatile unsigned int wlan_gpio_pin16;
+ volatile unsigned int wlan_gpio_pin17;
+ volatile unsigned int wlan_gpio_pin18;
+ volatile unsigned int wlan_gpio_pin19;
+ volatile unsigned int wlan_gpio_pin20;
+ volatile unsigned int wlan_gpio_pin21;
+ volatile unsigned int wlan_gpio_pin22;
+ volatile unsigned int wlan_gpio_pin23;
+ volatile unsigned int wlan_gpio_pin24;
+ volatile unsigned int wlan_gpio_pin25;
+ volatile unsigned int sdio;
+ volatile unsigned int func_bus;
+ volatile unsigned int wl_soc_apb;
+ volatile unsigned int wlan_sigma_delta;
+ volatile unsigned int wl_bootstrap;
+ volatile unsigned int clock_gpio;
+ volatile unsigned int wlan_debug_control;
+ volatile unsigned int wlan_debug_input_sel;
+ volatile unsigned int wlan_debug_out;
+ volatile unsigned int wlan_reset_tuple_status;
+ volatile unsigned int antenna_sleep_control;
+} gpio_athr_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _GPIO_ATHR_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h
new file mode 100644
index 000000000000..b3e7126e26a2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h
@@ -0,0 +1,1094 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "gpio_athr_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+#define GPIO_OUT_ADDRESS WLAN_GPIO_OUT_ADDRESS
+#define GPIO_OUT_OFFSET WLAN_GPIO_OUT_OFFSET
+#define GPIO_OUT_DATA_MSB WLAN_GPIO_OUT_DATA_MSB
+#define GPIO_OUT_DATA_LSB WLAN_GPIO_OUT_DATA_LSB
+#define GPIO_OUT_DATA_MASK WLAN_GPIO_OUT_DATA_MASK
+#define GPIO_OUT_DATA_GET(x) WLAN_GPIO_OUT_DATA_GET(x)
+#define GPIO_OUT_DATA_SET(x) WLAN_GPIO_OUT_DATA_SET(x)
+#define GPIO_OUT_W1TS_ADDRESS WLAN_GPIO_OUT_W1TS_ADDRESS
+#define GPIO_OUT_W1TS_OFFSET WLAN_GPIO_OUT_W1TS_OFFSET
+#define GPIO_OUT_W1TS_DATA_MSB WLAN_GPIO_OUT_W1TS_DATA_MSB
+#define GPIO_OUT_W1TS_DATA_LSB WLAN_GPIO_OUT_W1TS_DATA_LSB
+#define GPIO_OUT_W1TS_DATA_MASK WLAN_GPIO_OUT_W1TS_DATA_MASK
+#define GPIO_OUT_W1TS_DATA_GET(x) WLAN_GPIO_OUT_W1TS_DATA_GET(x)
+#define GPIO_OUT_W1TS_DATA_SET(x) WLAN_GPIO_OUT_W1TS_DATA_SET(x)
+#define GPIO_OUT_W1TC_ADDRESS WLAN_GPIO_OUT_W1TC_ADDRESS
+#define GPIO_OUT_W1TC_OFFSET WLAN_GPIO_OUT_W1TC_OFFSET
+#define GPIO_OUT_W1TC_DATA_MSB WLAN_GPIO_OUT_W1TC_DATA_MSB
+#define GPIO_OUT_W1TC_DATA_LSB WLAN_GPIO_OUT_W1TC_DATA_LSB
+#define GPIO_OUT_W1TC_DATA_MASK WLAN_GPIO_OUT_W1TC_DATA_MASK
+#define GPIO_OUT_W1TC_DATA_GET(x) WLAN_GPIO_OUT_W1TC_DATA_GET(x)
+#define GPIO_OUT_W1TC_DATA_SET(x) WLAN_GPIO_OUT_W1TC_DATA_SET(x)
+#define GPIO_ENABLE_ADDRESS WLAN_GPIO_ENABLE_ADDRESS
+#define GPIO_ENABLE_OFFSET WLAN_GPIO_ENABLE_OFFSET
+#define GPIO_ENABLE_DATA_MSB WLAN_GPIO_ENABLE_DATA_MSB
+#define GPIO_ENABLE_DATA_LSB WLAN_GPIO_ENABLE_DATA_LSB
+#define GPIO_ENABLE_DATA_MASK WLAN_GPIO_ENABLE_DATA_MASK
+#define GPIO_ENABLE_DATA_GET(x) WLAN_GPIO_ENABLE_DATA_GET(x)
+#define GPIO_ENABLE_DATA_SET(x) WLAN_GPIO_ENABLE_DATA_SET(x)
+#define GPIO_ENABLE_W1TS_ADDRESS WLAN_GPIO_ENABLE_W1TS_ADDRESS
+#define GPIO_ENABLE_W1TS_OFFSET WLAN_GPIO_ENABLE_W1TS_OFFSET
+#define GPIO_ENABLE_W1TS_DATA_MSB WLAN_GPIO_ENABLE_W1TS_DATA_MSB
+#define GPIO_ENABLE_W1TS_DATA_LSB WLAN_GPIO_ENABLE_W1TS_DATA_LSB
+#define GPIO_ENABLE_W1TS_DATA_MASK WLAN_GPIO_ENABLE_W1TS_DATA_MASK
+#define GPIO_ENABLE_W1TS_DATA_GET(x) WLAN_GPIO_ENABLE_W1TS_DATA_GET(x)
+#define GPIO_ENABLE_W1TS_DATA_SET(x) WLAN_GPIO_ENABLE_W1TS_DATA_SET(x)
+#define GPIO_ENABLE_W1TC_ADDRESS WLAN_GPIO_ENABLE_W1TC_ADDRESS
+#define GPIO_ENABLE_W1TC_OFFSET WLAN_GPIO_ENABLE_W1TC_OFFSET
+#define GPIO_ENABLE_W1TC_DATA_MSB WLAN_GPIO_ENABLE_W1TC_DATA_MSB
+#define GPIO_ENABLE_W1TC_DATA_LSB WLAN_GPIO_ENABLE_W1TC_DATA_LSB
+#define GPIO_ENABLE_W1TC_DATA_MASK WLAN_GPIO_ENABLE_W1TC_DATA_MASK
+#define GPIO_ENABLE_W1TC_DATA_GET(x) WLAN_GPIO_ENABLE_W1TC_DATA_GET(x)
+#define GPIO_ENABLE_W1TC_DATA_SET(x) WLAN_GPIO_ENABLE_W1TC_DATA_SET(x)
+#define GPIO_IN_ADDRESS WLAN_GPIO_IN_ADDRESS
+#define GPIO_IN_OFFSET WLAN_GPIO_IN_OFFSET
+#define GPIO_IN_DATA_MSB WLAN_GPIO_IN_DATA_MSB
+#define GPIO_IN_DATA_LSB WLAN_GPIO_IN_DATA_LSB
+#define GPIO_IN_DATA_MASK WLAN_GPIO_IN_DATA_MASK
+#define GPIO_IN_DATA_GET(x) WLAN_GPIO_IN_DATA_GET(x)
+#define GPIO_IN_DATA_SET(x) WLAN_GPIO_IN_DATA_SET(x)
+#define GPIO_STATUS_ADDRESS WLAN_GPIO_STATUS_ADDRESS
+#define GPIO_STATUS_OFFSET WLAN_GPIO_STATUS_OFFSET
+#define GPIO_STATUS_INTERRUPT_MSB WLAN_GPIO_STATUS_INTERRUPT_MSB
+#define GPIO_STATUS_INTERRUPT_LSB WLAN_GPIO_STATUS_INTERRUPT_LSB
+#define GPIO_STATUS_INTERRUPT_MASK WLAN_GPIO_STATUS_INTERRUPT_MASK
+#define GPIO_STATUS_INTERRUPT_GET(x) WLAN_GPIO_STATUS_INTERRUPT_GET(x)
+#define GPIO_STATUS_INTERRUPT_SET(x) WLAN_GPIO_STATUS_INTERRUPT_SET(x)
+#define GPIO_STATUS_W1TS_ADDRESS WLAN_GPIO_STATUS_W1TS_ADDRESS
+#define GPIO_STATUS_W1TS_OFFSET WLAN_GPIO_STATUS_W1TS_OFFSET
+#define GPIO_STATUS_W1TS_INTERRUPT_MSB WLAN_GPIO_STATUS_W1TS_INTERRUPT_MSB
+#define GPIO_STATUS_W1TS_INTERRUPT_LSB WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB
+#define GPIO_STATUS_W1TS_INTERRUPT_MASK WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK
+#define GPIO_STATUS_W1TS_INTERRUPT_GET(x) WLAN_GPIO_STATUS_W1TS_INTERRUPT_GET(x)
+#define GPIO_STATUS_W1TS_INTERRUPT_SET(x) WLAN_GPIO_STATUS_W1TS_INTERRUPT_SET(x)
+#define GPIO_STATUS_W1TC_ADDRESS WLAN_GPIO_STATUS_W1TC_ADDRESS
+#define GPIO_STATUS_W1TC_OFFSET WLAN_GPIO_STATUS_W1TC_OFFSET
+#define GPIO_STATUS_W1TC_INTERRUPT_MSB WLAN_GPIO_STATUS_W1TC_INTERRUPT_MSB
+#define GPIO_STATUS_W1TC_INTERRUPT_LSB WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB
+#define GPIO_STATUS_W1TC_INTERRUPT_MASK WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK
+#define GPIO_STATUS_W1TC_INTERRUPT_GET(x) WLAN_GPIO_STATUS_W1TC_INTERRUPT_GET(x)
+#define GPIO_STATUS_W1TC_INTERRUPT_SET(x) WLAN_GPIO_STATUS_W1TC_INTERRUPT_SET(x)
+#define GPIO_PIN0_ADDRESS WLAN_GPIO_PIN0_ADDRESS
+#define GPIO_PIN0_OFFSET WLAN_GPIO_PIN0_OFFSET
+#define GPIO_PIN0_CONFIG_MSB WLAN_GPIO_PIN0_CONFIG_MSB
+#define GPIO_PIN0_CONFIG_LSB WLAN_GPIO_PIN0_CONFIG_LSB
+#define GPIO_PIN0_CONFIG_MASK WLAN_GPIO_PIN0_CONFIG_MASK
+#define GPIO_PIN0_CONFIG_GET(x) WLAN_GPIO_PIN0_CONFIG_GET(x)
+#define GPIO_PIN0_CONFIG_SET(x) WLAN_GPIO_PIN0_CONFIG_SET(x)
+#define GPIO_PIN0_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN0_WAKEUP_ENABLE_MSB
+#define GPIO_PIN0_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB
+#define GPIO_PIN0_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK
+#define GPIO_PIN0_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN0_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN0_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN0_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN0_INT_TYPE_MSB WLAN_GPIO_PIN0_INT_TYPE_MSB
+#define GPIO_PIN0_INT_TYPE_LSB WLAN_GPIO_PIN0_INT_TYPE_LSB
+#define GPIO_PIN0_INT_TYPE_MASK WLAN_GPIO_PIN0_INT_TYPE_MASK
+#define GPIO_PIN0_INT_TYPE_GET(x) WLAN_GPIO_PIN0_INT_TYPE_GET(x)
+#define GPIO_PIN0_INT_TYPE_SET(x) WLAN_GPIO_PIN0_INT_TYPE_SET(x)
+#define GPIO_PIN0_PAD_PULL_MSB WLAN_GPIO_PIN0_PAD_PULL_MSB
+#define GPIO_PIN0_PAD_PULL_LSB WLAN_GPIO_PIN0_PAD_PULL_LSB
+#define GPIO_PIN0_PAD_PULL_MASK WLAN_GPIO_PIN0_PAD_PULL_MASK
+#define GPIO_PIN0_PAD_PULL_GET(x) WLAN_GPIO_PIN0_PAD_PULL_GET(x)
+#define GPIO_PIN0_PAD_PULL_SET(x) WLAN_GPIO_PIN0_PAD_PULL_SET(x)
+#define GPIO_PIN0_PAD_STRENGTH_MSB WLAN_GPIO_PIN0_PAD_STRENGTH_MSB
+#define GPIO_PIN0_PAD_STRENGTH_LSB WLAN_GPIO_PIN0_PAD_STRENGTH_LSB
+#define GPIO_PIN0_PAD_STRENGTH_MASK WLAN_GPIO_PIN0_PAD_STRENGTH_MASK
+#define GPIO_PIN0_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN0_PAD_STRENGTH_GET(x)
+#define GPIO_PIN0_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN0_PAD_STRENGTH_SET(x)
+#define GPIO_PIN0_PAD_DRIVER_MSB WLAN_GPIO_PIN0_PAD_DRIVER_MSB
+#define GPIO_PIN0_PAD_DRIVER_LSB WLAN_GPIO_PIN0_PAD_DRIVER_LSB
+#define GPIO_PIN0_PAD_DRIVER_MASK WLAN_GPIO_PIN0_PAD_DRIVER_MASK
+#define GPIO_PIN0_PAD_DRIVER_GET(x) WLAN_GPIO_PIN0_PAD_DRIVER_GET(x)
+#define GPIO_PIN0_PAD_DRIVER_SET(x) WLAN_GPIO_PIN0_PAD_DRIVER_SET(x)
+#define GPIO_PIN0_SOURCE_MSB WLAN_GPIO_PIN0_SOURCE_MSB
+#define GPIO_PIN0_SOURCE_LSB WLAN_GPIO_PIN0_SOURCE_LSB
+#define GPIO_PIN0_SOURCE_MASK WLAN_GPIO_PIN0_SOURCE_MASK
+#define GPIO_PIN0_SOURCE_GET(x) WLAN_GPIO_PIN0_SOURCE_GET(x)
+#define GPIO_PIN0_SOURCE_SET(x) WLAN_GPIO_PIN0_SOURCE_SET(x)
+#define GPIO_PIN1_ADDRESS WLAN_GPIO_PIN1_ADDRESS
+#define GPIO_PIN1_OFFSET WLAN_GPIO_PIN1_OFFSET
+#define GPIO_PIN1_CONFIG_MSB WLAN_GPIO_PIN1_CONFIG_MSB
+#define GPIO_PIN1_CONFIG_LSB WLAN_GPIO_PIN1_CONFIG_LSB
+#define GPIO_PIN1_CONFIG_MASK WLAN_GPIO_PIN1_CONFIG_MASK
+#define GPIO_PIN1_CONFIG_GET(x) WLAN_GPIO_PIN1_CONFIG_GET(x)
+#define GPIO_PIN1_CONFIG_SET(x) WLAN_GPIO_PIN1_CONFIG_SET(x)
+#define GPIO_PIN1_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN1_WAKEUP_ENABLE_MSB
+#define GPIO_PIN1_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB
+#define GPIO_PIN1_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK
+#define GPIO_PIN1_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN1_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN1_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN1_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN1_INT_TYPE_MSB WLAN_GPIO_PIN1_INT_TYPE_MSB
+#define GPIO_PIN1_INT_TYPE_LSB WLAN_GPIO_PIN1_INT_TYPE_LSB
+#define GPIO_PIN1_INT_TYPE_MASK WLAN_GPIO_PIN1_INT_TYPE_MASK
+#define GPIO_PIN1_INT_TYPE_GET(x) WLAN_GPIO_PIN1_INT_TYPE_GET(x)
+#define GPIO_PIN1_INT_TYPE_SET(x) WLAN_GPIO_PIN1_INT_TYPE_SET(x)
+#define GPIO_PIN1_PAD_PULL_MSB WLAN_GPIO_PIN1_PAD_PULL_MSB
+#define GPIO_PIN1_PAD_PULL_LSB WLAN_GPIO_PIN1_PAD_PULL_LSB
+#define GPIO_PIN1_PAD_PULL_MASK WLAN_GPIO_PIN1_PAD_PULL_MASK
+#define GPIO_PIN1_PAD_PULL_GET(x) WLAN_GPIO_PIN1_PAD_PULL_GET(x)
+#define GPIO_PIN1_PAD_PULL_SET(x) WLAN_GPIO_PIN1_PAD_PULL_SET(x)
+#define GPIO_PIN1_PAD_STRENGTH_MSB WLAN_GPIO_PIN1_PAD_STRENGTH_MSB
+#define GPIO_PIN1_PAD_STRENGTH_LSB WLAN_GPIO_PIN1_PAD_STRENGTH_LSB
+#define GPIO_PIN1_PAD_STRENGTH_MASK WLAN_GPIO_PIN1_PAD_STRENGTH_MASK
+#define GPIO_PIN1_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN1_PAD_STRENGTH_GET(x)
+#define GPIO_PIN1_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN1_PAD_STRENGTH_SET(x)
+#define GPIO_PIN1_PAD_DRIVER_MSB WLAN_GPIO_PIN1_PAD_DRIVER_MSB
+#define GPIO_PIN1_PAD_DRIVER_LSB WLAN_GPIO_PIN1_PAD_DRIVER_LSB
+#define GPIO_PIN1_PAD_DRIVER_MASK WLAN_GPIO_PIN1_PAD_DRIVER_MASK
+#define GPIO_PIN1_PAD_DRIVER_GET(x) WLAN_GPIO_PIN1_PAD_DRIVER_GET(x)
+#define GPIO_PIN1_PAD_DRIVER_SET(x) WLAN_GPIO_PIN1_PAD_DRIVER_SET(x)
+#define GPIO_PIN1_SOURCE_MSB WLAN_GPIO_PIN1_SOURCE_MSB
+#define GPIO_PIN1_SOURCE_LSB WLAN_GPIO_PIN1_SOURCE_LSB
+#define GPIO_PIN1_SOURCE_MASK WLAN_GPIO_PIN1_SOURCE_MASK
+#define GPIO_PIN1_SOURCE_GET(x) WLAN_GPIO_PIN1_SOURCE_GET(x)
+#define GPIO_PIN1_SOURCE_SET(x) WLAN_GPIO_PIN1_SOURCE_SET(x)
+#define GPIO_PIN2_ADDRESS WLAN_GPIO_PIN2_ADDRESS
+#define GPIO_PIN2_OFFSET WLAN_GPIO_PIN2_OFFSET
+#define GPIO_PIN2_CONFIG_MSB WLAN_GPIO_PIN2_CONFIG_MSB
+#define GPIO_PIN2_CONFIG_LSB WLAN_GPIO_PIN2_CONFIG_LSB
+#define GPIO_PIN2_CONFIG_MASK WLAN_GPIO_PIN2_CONFIG_MASK
+#define GPIO_PIN2_CONFIG_GET(x) WLAN_GPIO_PIN2_CONFIG_GET(x)
+#define GPIO_PIN2_CONFIG_SET(x) WLAN_GPIO_PIN2_CONFIG_SET(x)
+#define GPIO_PIN2_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN2_WAKEUP_ENABLE_MSB
+#define GPIO_PIN2_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB
+#define GPIO_PIN2_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK
+#define GPIO_PIN2_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN2_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN2_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN2_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN2_INT_TYPE_MSB WLAN_GPIO_PIN2_INT_TYPE_MSB
+#define GPIO_PIN2_INT_TYPE_LSB WLAN_GPIO_PIN2_INT_TYPE_LSB
+#define GPIO_PIN2_INT_TYPE_MASK WLAN_GPIO_PIN2_INT_TYPE_MASK
+#define GPIO_PIN2_INT_TYPE_GET(x) WLAN_GPIO_PIN2_INT_TYPE_GET(x)
+#define GPIO_PIN2_INT_TYPE_SET(x) WLAN_GPIO_PIN2_INT_TYPE_SET(x)
+#define GPIO_PIN2_PAD_PULL_MSB WLAN_GPIO_PIN2_PAD_PULL_MSB
+#define GPIO_PIN2_PAD_PULL_LSB WLAN_GPIO_PIN2_PAD_PULL_LSB
+#define GPIO_PIN2_PAD_PULL_MASK WLAN_GPIO_PIN2_PAD_PULL_MASK
+#define GPIO_PIN2_PAD_PULL_GET(x) WLAN_GPIO_PIN2_PAD_PULL_GET(x)
+#define GPIO_PIN2_PAD_PULL_SET(x) WLAN_GPIO_PIN2_PAD_PULL_SET(x)
+#define GPIO_PIN2_PAD_STRENGTH_MSB WLAN_GPIO_PIN2_PAD_STRENGTH_MSB
+#define GPIO_PIN2_PAD_STRENGTH_LSB WLAN_GPIO_PIN2_PAD_STRENGTH_LSB
+#define GPIO_PIN2_PAD_STRENGTH_MASK WLAN_GPIO_PIN2_PAD_STRENGTH_MASK
+#define GPIO_PIN2_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN2_PAD_STRENGTH_GET(x)
+#define GPIO_PIN2_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN2_PAD_STRENGTH_SET(x)
+#define GPIO_PIN2_PAD_DRIVER_MSB WLAN_GPIO_PIN2_PAD_DRIVER_MSB
+#define GPIO_PIN2_PAD_DRIVER_LSB WLAN_GPIO_PIN2_PAD_DRIVER_LSB
+#define GPIO_PIN2_PAD_DRIVER_MASK WLAN_GPIO_PIN2_PAD_DRIVER_MASK
+#define GPIO_PIN2_PAD_DRIVER_GET(x) WLAN_GPIO_PIN2_PAD_DRIVER_GET(x)
+#define GPIO_PIN2_PAD_DRIVER_SET(x) WLAN_GPIO_PIN2_PAD_DRIVER_SET(x)
+#define GPIO_PIN2_SOURCE_MSB WLAN_GPIO_PIN2_SOURCE_MSB
+#define GPIO_PIN2_SOURCE_LSB WLAN_GPIO_PIN2_SOURCE_LSB
+#define GPIO_PIN2_SOURCE_MASK WLAN_GPIO_PIN2_SOURCE_MASK
+#define GPIO_PIN2_SOURCE_GET(x) WLAN_GPIO_PIN2_SOURCE_GET(x)
+#define GPIO_PIN2_SOURCE_SET(x) WLAN_GPIO_PIN2_SOURCE_SET(x)
+#define GPIO_PIN3_ADDRESS WLAN_GPIO_PIN3_ADDRESS
+#define GPIO_PIN3_OFFSET WLAN_GPIO_PIN3_OFFSET
+#define GPIO_PIN3_CONFIG_MSB WLAN_GPIO_PIN3_CONFIG_MSB
+#define GPIO_PIN3_CONFIG_LSB WLAN_GPIO_PIN3_CONFIG_LSB
+#define GPIO_PIN3_CONFIG_MASK WLAN_GPIO_PIN3_CONFIG_MASK
+#define GPIO_PIN3_CONFIG_GET(x) WLAN_GPIO_PIN3_CONFIG_GET(x)
+#define GPIO_PIN3_CONFIG_SET(x) WLAN_GPIO_PIN3_CONFIG_SET(x)
+#define GPIO_PIN3_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN3_WAKEUP_ENABLE_MSB
+#define GPIO_PIN3_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB
+#define GPIO_PIN3_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK
+#define GPIO_PIN3_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN3_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN3_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN3_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN3_INT_TYPE_MSB WLAN_GPIO_PIN3_INT_TYPE_MSB
+#define GPIO_PIN3_INT_TYPE_LSB WLAN_GPIO_PIN3_INT_TYPE_LSB
+#define GPIO_PIN3_INT_TYPE_MASK WLAN_GPIO_PIN3_INT_TYPE_MASK
+#define GPIO_PIN3_INT_TYPE_GET(x) WLAN_GPIO_PIN3_INT_TYPE_GET(x)
+#define GPIO_PIN3_INT_TYPE_SET(x) WLAN_GPIO_PIN3_INT_TYPE_SET(x)
+#define GPIO_PIN3_PAD_PULL_MSB WLAN_GPIO_PIN3_PAD_PULL_MSB
+#define GPIO_PIN3_PAD_PULL_LSB WLAN_GPIO_PIN3_PAD_PULL_LSB
+#define GPIO_PIN3_PAD_PULL_MASK WLAN_GPIO_PIN3_PAD_PULL_MASK
+#define GPIO_PIN3_PAD_PULL_GET(x) WLAN_GPIO_PIN3_PAD_PULL_GET(x)
+#define GPIO_PIN3_PAD_PULL_SET(x) WLAN_GPIO_PIN3_PAD_PULL_SET(x)
+#define GPIO_PIN3_PAD_STRENGTH_MSB WLAN_GPIO_PIN3_PAD_STRENGTH_MSB
+#define GPIO_PIN3_PAD_STRENGTH_LSB WLAN_GPIO_PIN3_PAD_STRENGTH_LSB
+#define GPIO_PIN3_PAD_STRENGTH_MASK WLAN_GPIO_PIN3_PAD_STRENGTH_MASK
+#define GPIO_PIN3_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN3_PAD_STRENGTH_GET(x)
+#define GPIO_PIN3_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN3_PAD_STRENGTH_SET(x)
+#define GPIO_PIN3_PAD_DRIVER_MSB WLAN_GPIO_PIN3_PAD_DRIVER_MSB
+#define GPIO_PIN3_PAD_DRIVER_LSB WLAN_GPIO_PIN3_PAD_DRIVER_LSB
+#define GPIO_PIN3_PAD_DRIVER_MASK WLAN_GPIO_PIN3_PAD_DRIVER_MASK
+#define GPIO_PIN3_PAD_DRIVER_GET(x) WLAN_GPIO_PIN3_PAD_DRIVER_GET(x)
+#define GPIO_PIN3_PAD_DRIVER_SET(x) WLAN_GPIO_PIN3_PAD_DRIVER_SET(x)
+#define GPIO_PIN3_SOURCE_MSB WLAN_GPIO_PIN3_SOURCE_MSB
+#define GPIO_PIN3_SOURCE_LSB WLAN_GPIO_PIN3_SOURCE_LSB
+#define GPIO_PIN3_SOURCE_MASK WLAN_GPIO_PIN3_SOURCE_MASK
+#define GPIO_PIN3_SOURCE_GET(x) WLAN_GPIO_PIN3_SOURCE_GET(x)
+#define GPIO_PIN3_SOURCE_SET(x) WLAN_GPIO_PIN3_SOURCE_SET(x)
+#define GPIO_PIN4_ADDRESS WLAN_GPIO_PIN4_ADDRESS
+#define GPIO_PIN4_OFFSET WLAN_GPIO_PIN4_OFFSET
+#define GPIO_PIN4_CONFIG_MSB WLAN_GPIO_PIN4_CONFIG_MSB
+#define GPIO_PIN4_CONFIG_LSB WLAN_GPIO_PIN4_CONFIG_LSB
+#define GPIO_PIN4_CONFIG_MASK WLAN_GPIO_PIN4_CONFIG_MASK
+#define GPIO_PIN4_CONFIG_GET(x) WLAN_GPIO_PIN4_CONFIG_GET(x)
+#define GPIO_PIN4_CONFIG_SET(x) WLAN_GPIO_PIN4_CONFIG_SET(x)
+#define GPIO_PIN4_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN4_WAKEUP_ENABLE_MSB
+#define GPIO_PIN4_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB
+#define GPIO_PIN4_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK
+#define GPIO_PIN4_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN4_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN4_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN4_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN4_INT_TYPE_MSB WLAN_GPIO_PIN4_INT_TYPE_MSB
+#define GPIO_PIN4_INT_TYPE_LSB WLAN_GPIO_PIN4_INT_TYPE_LSB
+#define GPIO_PIN4_INT_TYPE_MASK WLAN_GPIO_PIN4_INT_TYPE_MASK
+#define GPIO_PIN4_INT_TYPE_GET(x) WLAN_GPIO_PIN4_INT_TYPE_GET(x)
+#define GPIO_PIN4_INT_TYPE_SET(x) WLAN_GPIO_PIN4_INT_TYPE_SET(x)
+#define GPIO_PIN4_PAD_PULL_MSB WLAN_GPIO_PIN4_PAD_PULL_MSB
+#define GPIO_PIN4_PAD_PULL_LSB WLAN_GPIO_PIN4_PAD_PULL_LSB
+#define GPIO_PIN4_PAD_PULL_MASK WLAN_GPIO_PIN4_PAD_PULL_MASK
+#define GPIO_PIN4_PAD_PULL_GET(x) WLAN_GPIO_PIN4_PAD_PULL_GET(x)
+#define GPIO_PIN4_PAD_PULL_SET(x) WLAN_GPIO_PIN4_PAD_PULL_SET(x)
+#define GPIO_PIN4_PAD_STRENGTH_MSB WLAN_GPIO_PIN4_PAD_STRENGTH_MSB
+#define GPIO_PIN4_PAD_STRENGTH_LSB WLAN_GPIO_PIN4_PAD_STRENGTH_LSB
+#define GPIO_PIN4_PAD_STRENGTH_MASK WLAN_GPIO_PIN4_PAD_STRENGTH_MASK
+#define GPIO_PIN4_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN4_PAD_STRENGTH_GET(x)
+#define GPIO_PIN4_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN4_PAD_STRENGTH_SET(x)
+#define GPIO_PIN4_PAD_DRIVER_MSB WLAN_GPIO_PIN4_PAD_DRIVER_MSB
+#define GPIO_PIN4_PAD_DRIVER_LSB WLAN_GPIO_PIN4_PAD_DRIVER_LSB
+#define GPIO_PIN4_PAD_DRIVER_MASK WLAN_GPIO_PIN4_PAD_DRIVER_MASK
+#define GPIO_PIN4_PAD_DRIVER_GET(x) WLAN_GPIO_PIN4_PAD_DRIVER_GET(x)
+#define GPIO_PIN4_PAD_DRIVER_SET(x) WLAN_GPIO_PIN4_PAD_DRIVER_SET(x)
+#define GPIO_PIN4_SOURCE_MSB WLAN_GPIO_PIN4_SOURCE_MSB
+#define GPIO_PIN4_SOURCE_LSB WLAN_GPIO_PIN4_SOURCE_LSB
+#define GPIO_PIN4_SOURCE_MASK WLAN_GPIO_PIN4_SOURCE_MASK
+#define GPIO_PIN4_SOURCE_GET(x) WLAN_GPIO_PIN4_SOURCE_GET(x)
+#define GPIO_PIN4_SOURCE_SET(x) WLAN_GPIO_PIN4_SOURCE_SET(x)
+#define GPIO_PIN5_ADDRESS WLAN_GPIO_PIN5_ADDRESS
+#define GPIO_PIN5_OFFSET WLAN_GPIO_PIN5_OFFSET
+#define GPIO_PIN5_CONFIG_MSB WLAN_GPIO_PIN5_CONFIG_MSB
+#define GPIO_PIN5_CONFIG_LSB WLAN_GPIO_PIN5_CONFIG_LSB
+#define GPIO_PIN5_CONFIG_MASK WLAN_GPIO_PIN5_CONFIG_MASK
+#define GPIO_PIN5_CONFIG_GET(x) WLAN_GPIO_PIN5_CONFIG_GET(x)
+#define GPIO_PIN5_CONFIG_SET(x) WLAN_GPIO_PIN5_CONFIG_SET(x)
+#define GPIO_PIN5_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN5_WAKEUP_ENABLE_MSB
+#define GPIO_PIN5_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB
+#define GPIO_PIN5_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK
+#define GPIO_PIN5_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN5_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN5_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN5_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN5_INT_TYPE_MSB WLAN_GPIO_PIN5_INT_TYPE_MSB
+#define GPIO_PIN5_INT_TYPE_LSB WLAN_GPIO_PIN5_INT_TYPE_LSB
+#define GPIO_PIN5_INT_TYPE_MASK WLAN_GPIO_PIN5_INT_TYPE_MASK
+#define GPIO_PIN5_INT_TYPE_GET(x) WLAN_GPIO_PIN5_INT_TYPE_GET(x)
+#define GPIO_PIN5_INT_TYPE_SET(x) WLAN_GPIO_PIN5_INT_TYPE_SET(x)
+#define GPIO_PIN5_PAD_PULL_MSB WLAN_GPIO_PIN5_PAD_PULL_MSB
+#define GPIO_PIN5_PAD_PULL_LSB WLAN_GPIO_PIN5_PAD_PULL_LSB
+#define GPIO_PIN5_PAD_PULL_MASK WLAN_GPIO_PIN5_PAD_PULL_MASK
+#define GPIO_PIN5_PAD_PULL_GET(x) WLAN_GPIO_PIN5_PAD_PULL_GET(x)
+#define GPIO_PIN5_PAD_PULL_SET(x) WLAN_GPIO_PIN5_PAD_PULL_SET(x)
+#define GPIO_PIN5_PAD_STRENGTH_MSB WLAN_GPIO_PIN5_PAD_STRENGTH_MSB
+#define GPIO_PIN5_PAD_STRENGTH_LSB WLAN_GPIO_PIN5_PAD_STRENGTH_LSB
+#define GPIO_PIN5_PAD_STRENGTH_MASK WLAN_GPIO_PIN5_PAD_STRENGTH_MASK
+#define GPIO_PIN5_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN5_PAD_STRENGTH_GET(x)
+#define GPIO_PIN5_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN5_PAD_STRENGTH_SET(x)
+#define GPIO_PIN5_PAD_DRIVER_MSB WLAN_GPIO_PIN5_PAD_DRIVER_MSB
+#define GPIO_PIN5_PAD_DRIVER_LSB WLAN_GPIO_PIN5_PAD_DRIVER_LSB
+#define GPIO_PIN5_PAD_DRIVER_MASK WLAN_GPIO_PIN5_PAD_DRIVER_MASK
+#define GPIO_PIN5_PAD_DRIVER_GET(x) WLAN_GPIO_PIN5_PAD_DRIVER_GET(x)
+#define GPIO_PIN5_PAD_DRIVER_SET(x) WLAN_GPIO_PIN5_PAD_DRIVER_SET(x)
+#define GPIO_PIN5_SOURCE_MSB WLAN_GPIO_PIN5_SOURCE_MSB
+#define GPIO_PIN5_SOURCE_LSB WLAN_GPIO_PIN5_SOURCE_LSB
+#define GPIO_PIN5_SOURCE_MASK WLAN_GPIO_PIN5_SOURCE_MASK
+#define GPIO_PIN5_SOURCE_GET(x) WLAN_GPIO_PIN5_SOURCE_GET(x)
+#define GPIO_PIN5_SOURCE_SET(x) WLAN_GPIO_PIN5_SOURCE_SET(x)
+#define GPIO_PIN6_ADDRESS WLAN_GPIO_PIN6_ADDRESS
+#define GPIO_PIN6_OFFSET WLAN_GPIO_PIN6_OFFSET
+#define GPIO_PIN6_CONFIG_MSB WLAN_GPIO_PIN6_CONFIG_MSB
+#define GPIO_PIN6_CONFIG_LSB WLAN_GPIO_PIN6_CONFIG_LSB
+#define GPIO_PIN6_CONFIG_MASK WLAN_GPIO_PIN6_CONFIG_MASK
+#define GPIO_PIN6_CONFIG_GET(x) WLAN_GPIO_PIN6_CONFIG_GET(x)
+#define GPIO_PIN6_CONFIG_SET(x) WLAN_GPIO_PIN6_CONFIG_SET(x)
+#define GPIO_PIN6_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN6_WAKEUP_ENABLE_MSB
+#define GPIO_PIN6_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB
+#define GPIO_PIN6_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK
+#define GPIO_PIN6_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN6_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN6_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN6_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN6_INT_TYPE_MSB WLAN_GPIO_PIN6_INT_TYPE_MSB
+#define GPIO_PIN6_INT_TYPE_LSB WLAN_GPIO_PIN6_INT_TYPE_LSB
+#define GPIO_PIN6_INT_TYPE_MASK WLAN_GPIO_PIN6_INT_TYPE_MASK
+#define GPIO_PIN6_INT_TYPE_GET(x) WLAN_GPIO_PIN6_INT_TYPE_GET(x)
+#define GPIO_PIN6_INT_TYPE_SET(x) WLAN_GPIO_PIN6_INT_TYPE_SET(x)
+#define GPIO_PIN6_PAD_PULL_MSB WLAN_GPIO_PIN6_PAD_PULL_MSB
+#define GPIO_PIN6_PAD_PULL_LSB WLAN_GPIO_PIN6_PAD_PULL_LSB
+#define GPIO_PIN6_PAD_PULL_MASK WLAN_GPIO_PIN6_PAD_PULL_MASK
+#define GPIO_PIN6_PAD_PULL_GET(x) WLAN_GPIO_PIN6_PAD_PULL_GET(x)
+#define GPIO_PIN6_PAD_PULL_SET(x) WLAN_GPIO_PIN6_PAD_PULL_SET(x)
+#define GPIO_PIN6_PAD_STRENGTH_MSB WLAN_GPIO_PIN6_PAD_STRENGTH_MSB
+#define GPIO_PIN6_PAD_STRENGTH_LSB WLAN_GPIO_PIN6_PAD_STRENGTH_LSB
+#define GPIO_PIN6_PAD_STRENGTH_MASK WLAN_GPIO_PIN6_PAD_STRENGTH_MASK
+#define GPIO_PIN6_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN6_PAD_STRENGTH_GET(x)
+#define GPIO_PIN6_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN6_PAD_STRENGTH_SET(x)
+#define GPIO_PIN6_PAD_DRIVER_MSB WLAN_GPIO_PIN6_PAD_DRIVER_MSB
+#define GPIO_PIN6_PAD_DRIVER_LSB WLAN_GPIO_PIN6_PAD_DRIVER_LSB
+#define GPIO_PIN6_PAD_DRIVER_MASK WLAN_GPIO_PIN6_PAD_DRIVER_MASK
+#define GPIO_PIN6_PAD_DRIVER_GET(x) WLAN_GPIO_PIN6_PAD_DRIVER_GET(x)
+#define GPIO_PIN6_PAD_DRIVER_SET(x) WLAN_GPIO_PIN6_PAD_DRIVER_SET(x)
+#define GPIO_PIN6_SOURCE_MSB WLAN_GPIO_PIN6_SOURCE_MSB
+#define GPIO_PIN6_SOURCE_LSB WLAN_GPIO_PIN6_SOURCE_LSB
+#define GPIO_PIN6_SOURCE_MASK WLAN_GPIO_PIN6_SOURCE_MASK
+#define GPIO_PIN6_SOURCE_GET(x) WLAN_GPIO_PIN6_SOURCE_GET(x)
+#define GPIO_PIN6_SOURCE_SET(x) WLAN_GPIO_PIN6_SOURCE_SET(x)
+#define GPIO_PIN7_ADDRESS WLAN_GPIO_PIN7_ADDRESS
+#define GPIO_PIN7_OFFSET WLAN_GPIO_PIN7_OFFSET
+#define GPIO_PIN7_CONFIG_MSB WLAN_GPIO_PIN7_CONFIG_MSB
+#define GPIO_PIN7_CONFIG_LSB WLAN_GPIO_PIN7_CONFIG_LSB
+#define GPIO_PIN7_CONFIG_MASK WLAN_GPIO_PIN7_CONFIG_MASK
+#define GPIO_PIN7_CONFIG_GET(x) WLAN_GPIO_PIN7_CONFIG_GET(x)
+#define GPIO_PIN7_CONFIG_SET(x) WLAN_GPIO_PIN7_CONFIG_SET(x)
+#define GPIO_PIN7_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN7_WAKEUP_ENABLE_MSB
+#define GPIO_PIN7_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB
+#define GPIO_PIN7_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK
+#define GPIO_PIN7_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN7_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN7_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN7_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN7_INT_TYPE_MSB WLAN_GPIO_PIN7_INT_TYPE_MSB
+#define GPIO_PIN7_INT_TYPE_LSB WLAN_GPIO_PIN7_INT_TYPE_LSB
+#define GPIO_PIN7_INT_TYPE_MASK WLAN_GPIO_PIN7_INT_TYPE_MASK
+#define GPIO_PIN7_INT_TYPE_GET(x) WLAN_GPIO_PIN7_INT_TYPE_GET(x)
+#define GPIO_PIN7_INT_TYPE_SET(x) WLAN_GPIO_PIN7_INT_TYPE_SET(x)
+#define GPIO_PIN7_PAD_PULL_MSB WLAN_GPIO_PIN7_PAD_PULL_MSB
+#define GPIO_PIN7_PAD_PULL_LSB WLAN_GPIO_PIN7_PAD_PULL_LSB
+#define GPIO_PIN7_PAD_PULL_MASK WLAN_GPIO_PIN7_PAD_PULL_MASK
+#define GPIO_PIN7_PAD_PULL_GET(x) WLAN_GPIO_PIN7_PAD_PULL_GET(x)
+#define GPIO_PIN7_PAD_PULL_SET(x) WLAN_GPIO_PIN7_PAD_PULL_SET(x)
+#define GPIO_PIN7_PAD_STRENGTH_MSB WLAN_GPIO_PIN7_PAD_STRENGTH_MSB
+#define GPIO_PIN7_PAD_STRENGTH_LSB WLAN_GPIO_PIN7_PAD_STRENGTH_LSB
+#define GPIO_PIN7_PAD_STRENGTH_MASK WLAN_GPIO_PIN7_PAD_STRENGTH_MASK
+#define GPIO_PIN7_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN7_PAD_STRENGTH_GET(x)
+#define GPIO_PIN7_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN7_PAD_STRENGTH_SET(x)
+#define GPIO_PIN7_PAD_DRIVER_MSB WLAN_GPIO_PIN7_PAD_DRIVER_MSB
+#define GPIO_PIN7_PAD_DRIVER_LSB WLAN_GPIO_PIN7_PAD_DRIVER_LSB
+#define GPIO_PIN7_PAD_DRIVER_MASK WLAN_GPIO_PIN7_PAD_DRIVER_MASK
+#define GPIO_PIN7_PAD_DRIVER_GET(x) WLAN_GPIO_PIN7_PAD_DRIVER_GET(x)
+#define GPIO_PIN7_PAD_DRIVER_SET(x) WLAN_GPIO_PIN7_PAD_DRIVER_SET(x)
+#define GPIO_PIN7_SOURCE_MSB WLAN_GPIO_PIN7_SOURCE_MSB
+#define GPIO_PIN7_SOURCE_LSB WLAN_GPIO_PIN7_SOURCE_LSB
+#define GPIO_PIN7_SOURCE_MASK WLAN_GPIO_PIN7_SOURCE_MASK
+#define GPIO_PIN7_SOURCE_GET(x) WLAN_GPIO_PIN7_SOURCE_GET(x)
+#define GPIO_PIN7_SOURCE_SET(x) WLAN_GPIO_PIN7_SOURCE_SET(x)
+#define GPIO_PIN8_ADDRESS WLAN_GPIO_PIN8_ADDRESS
+#define GPIO_PIN8_OFFSET WLAN_GPIO_PIN8_OFFSET
+#define GPIO_PIN8_CONFIG_MSB WLAN_GPIO_PIN8_CONFIG_MSB
+#define GPIO_PIN8_CONFIG_LSB WLAN_GPIO_PIN8_CONFIG_LSB
+#define GPIO_PIN8_CONFIG_MASK WLAN_GPIO_PIN8_CONFIG_MASK
+#define GPIO_PIN8_CONFIG_GET(x) WLAN_GPIO_PIN8_CONFIG_GET(x)
+#define GPIO_PIN8_CONFIG_SET(x) WLAN_GPIO_PIN8_CONFIG_SET(x)
+#define GPIO_PIN8_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN8_WAKEUP_ENABLE_MSB
+#define GPIO_PIN8_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB
+#define GPIO_PIN8_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK
+#define GPIO_PIN8_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN8_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN8_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN8_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN8_INT_TYPE_MSB WLAN_GPIO_PIN8_INT_TYPE_MSB
+#define GPIO_PIN8_INT_TYPE_LSB WLAN_GPIO_PIN8_INT_TYPE_LSB
+#define GPIO_PIN8_INT_TYPE_MASK WLAN_GPIO_PIN8_INT_TYPE_MASK
+#define GPIO_PIN8_INT_TYPE_GET(x) WLAN_GPIO_PIN8_INT_TYPE_GET(x)
+#define GPIO_PIN8_INT_TYPE_SET(x) WLAN_GPIO_PIN8_INT_TYPE_SET(x)
+#define GPIO_PIN8_PAD_PULL_MSB WLAN_GPIO_PIN8_PAD_PULL_MSB
+#define GPIO_PIN8_PAD_PULL_LSB WLAN_GPIO_PIN8_PAD_PULL_LSB
+#define GPIO_PIN8_PAD_PULL_MASK WLAN_GPIO_PIN8_PAD_PULL_MASK
+#define GPIO_PIN8_PAD_PULL_GET(x) WLAN_GPIO_PIN8_PAD_PULL_GET(x)
+#define GPIO_PIN8_PAD_PULL_SET(x) WLAN_GPIO_PIN8_PAD_PULL_SET(x)
+#define GPIO_PIN8_PAD_STRENGTH_MSB WLAN_GPIO_PIN8_PAD_STRENGTH_MSB
+#define GPIO_PIN8_PAD_STRENGTH_LSB WLAN_GPIO_PIN8_PAD_STRENGTH_LSB
+#define GPIO_PIN8_PAD_STRENGTH_MASK WLAN_GPIO_PIN8_PAD_STRENGTH_MASK
+#define GPIO_PIN8_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN8_PAD_STRENGTH_GET(x)
+#define GPIO_PIN8_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN8_PAD_STRENGTH_SET(x)
+#define GPIO_PIN8_PAD_DRIVER_MSB WLAN_GPIO_PIN8_PAD_DRIVER_MSB
+#define GPIO_PIN8_PAD_DRIVER_LSB WLAN_GPIO_PIN8_PAD_DRIVER_LSB
+#define GPIO_PIN8_PAD_DRIVER_MASK WLAN_GPIO_PIN8_PAD_DRIVER_MASK
+#define GPIO_PIN8_PAD_DRIVER_GET(x) WLAN_GPIO_PIN8_PAD_DRIVER_GET(x)
+#define GPIO_PIN8_PAD_DRIVER_SET(x) WLAN_GPIO_PIN8_PAD_DRIVER_SET(x)
+#define GPIO_PIN8_SOURCE_MSB WLAN_GPIO_PIN8_SOURCE_MSB
+#define GPIO_PIN8_SOURCE_LSB WLAN_GPIO_PIN8_SOURCE_LSB
+#define GPIO_PIN8_SOURCE_MASK WLAN_GPIO_PIN8_SOURCE_MASK
+#define GPIO_PIN8_SOURCE_GET(x) WLAN_GPIO_PIN8_SOURCE_GET(x)
+#define GPIO_PIN8_SOURCE_SET(x) WLAN_GPIO_PIN8_SOURCE_SET(x)
+#define GPIO_PIN9_ADDRESS WLAN_GPIO_PIN9_ADDRESS
+#define GPIO_PIN9_OFFSET WLAN_GPIO_PIN9_OFFSET
+#define GPIO_PIN9_CONFIG_MSB WLAN_GPIO_PIN9_CONFIG_MSB
+#define GPIO_PIN9_CONFIG_LSB WLAN_GPIO_PIN9_CONFIG_LSB
+#define GPIO_PIN9_CONFIG_MASK WLAN_GPIO_PIN9_CONFIG_MASK
+#define GPIO_PIN9_CONFIG_GET(x) WLAN_GPIO_PIN9_CONFIG_GET(x)
+#define GPIO_PIN9_CONFIG_SET(x) WLAN_GPIO_PIN9_CONFIG_SET(x)
+#define GPIO_PIN9_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN9_WAKEUP_ENABLE_MSB
+#define GPIO_PIN9_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB
+#define GPIO_PIN9_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK
+#define GPIO_PIN9_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN9_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN9_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN9_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN9_INT_TYPE_MSB WLAN_GPIO_PIN9_INT_TYPE_MSB
+#define GPIO_PIN9_INT_TYPE_LSB WLAN_GPIO_PIN9_INT_TYPE_LSB
+#define GPIO_PIN9_INT_TYPE_MASK WLAN_GPIO_PIN9_INT_TYPE_MASK
+#define GPIO_PIN9_INT_TYPE_GET(x) WLAN_GPIO_PIN9_INT_TYPE_GET(x)
+#define GPIO_PIN9_INT_TYPE_SET(x) WLAN_GPIO_PIN9_INT_TYPE_SET(x)
+#define GPIO_PIN9_PAD_PULL_MSB WLAN_GPIO_PIN9_PAD_PULL_MSB
+#define GPIO_PIN9_PAD_PULL_LSB WLAN_GPIO_PIN9_PAD_PULL_LSB
+#define GPIO_PIN9_PAD_PULL_MASK WLAN_GPIO_PIN9_PAD_PULL_MASK
+#define GPIO_PIN9_PAD_PULL_GET(x) WLAN_GPIO_PIN9_PAD_PULL_GET(x)
+#define GPIO_PIN9_PAD_PULL_SET(x) WLAN_GPIO_PIN9_PAD_PULL_SET(x)
+#define GPIO_PIN9_PAD_STRENGTH_MSB WLAN_GPIO_PIN9_PAD_STRENGTH_MSB
+#define GPIO_PIN9_PAD_STRENGTH_LSB WLAN_GPIO_PIN9_PAD_STRENGTH_LSB
+#define GPIO_PIN9_PAD_STRENGTH_MASK WLAN_GPIO_PIN9_PAD_STRENGTH_MASK
+#define GPIO_PIN9_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN9_PAD_STRENGTH_GET(x)
+#define GPIO_PIN9_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN9_PAD_STRENGTH_SET(x)
+#define GPIO_PIN9_PAD_DRIVER_MSB WLAN_GPIO_PIN9_PAD_DRIVER_MSB
+#define GPIO_PIN9_PAD_DRIVER_LSB WLAN_GPIO_PIN9_PAD_DRIVER_LSB
+#define GPIO_PIN9_PAD_DRIVER_MASK WLAN_GPIO_PIN9_PAD_DRIVER_MASK
+#define GPIO_PIN9_PAD_DRIVER_GET(x) WLAN_GPIO_PIN9_PAD_DRIVER_GET(x)
+#define GPIO_PIN9_PAD_DRIVER_SET(x) WLAN_GPIO_PIN9_PAD_DRIVER_SET(x)
+#define GPIO_PIN9_SOURCE_MSB WLAN_GPIO_PIN9_SOURCE_MSB
+#define GPIO_PIN9_SOURCE_LSB WLAN_GPIO_PIN9_SOURCE_LSB
+#define GPIO_PIN9_SOURCE_MASK WLAN_GPIO_PIN9_SOURCE_MASK
+#define GPIO_PIN9_SOURCE_GET(x) WLAN_GPIO_PIN9_SOURCE_GET(x)
+#define GPIO_PIN9_SOURCE_SET(x) WLAN_GPIO_PIN9_SOURCE_SET(x)
+#define GPIO_PIN10_ADDRESS WLAN_GPIO_PIN10_ADDRESS
+#define GPIO_PIN10_OFFSET WLAN_GPIO_PIN10_OFFSET
+#define GPIO_PIN10_CONFIG_MSB WLAN_GPIO_PIN10_CONFIG_MSB
+#define GPIO_PIN10_CONFIG_LSB WLAN_GPIO_PIN10_CONFIG_LSB
+#define GPIO_PIN10_CONFIG_MASK WLAN_GPIO_PIN10_CONFIG_MASK
+#define GPIO_PIN10_CONFIG_GET(x) WLAN_GPIO_PIN10_CONFIG_GET(x)
+#define GPIO_PIN10_CONFIG_SET(x) WLAN_GPIO_PIN10_CONFIG_SET(x)
+#define GPIO_PIN10_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN10_WAKEUP_ENABLE_MSB
+#define GPIO_PIN10_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB
+#define GPIO_PIN10_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK
+#define GPIO_PIN10_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN10_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN10_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN10_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN10_INT_TYPE_MSB WLAN_GPIO_PIN10_INT_TYPE_MSB
+#define GPIO_PIN10_INT_TYPE_LSB WLAN_GPIO_PIN10_INT_TYPE_LSB
+#define GPIO_PIN10_INT_TYPE_MASK WLAN_GPIO_PIN10_INT_TYPE_MASK
+#define GPIO_PIN10_INT_TYPE_GET(x) WLAN_GPIO_PIN10_INT_TYPE_GET(x)
+#define GPIO_PIN10_INT_TYPE_SET(x) WLAN_GPIO_PIN10_INT_TYPE_SET(x)
+#define GPIO_PIN10_PAD_PULL_MSB WLAN_GPIO_PIN10_PAD_PULL_MSB
+#define GPIO_PIN10_PAD_PULL_LSB WLAN_GPIO_PIN10_PAD_PULL_LSB
+#define GPIO_PIN10_PAD_PULL_MASK WLAN_GPIO_PIN10_PAD_PULL_MASK
+#define GPIO_PIN10_PAD_PULL_GET(x) WLAN_GPIO_PIN10_PAD_PULL_GET(x)
+#define GPIO_PIN10_PAD_PULL_SET(x) WLAN_GPIO_PIN10_PAD_PULL_SET(x)
+#define GPIO_PIN10_PAD_STRENGTH_MSB WLAN_GPIO_PIN10_PAD_STRENGTH_MSB
+#define GPIO_PIN10_PAD_STRENGTH_LSB WLAN_GPIO_PIN10_PAD_STRENGTH_LSB
+#define GPIO_PIN10_PAD_STRENGTH_MASK WLAN_GPIO_PIN10_PAD_STRENGTH_MASK
+#define GPIO_PIN10_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN10_PAD_STRENGTH_GET(x)
+#define GPIO_PIN10_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN10_PAD_STRENGTH_SET(x)
+#define GPIO_PIN10_PAD_DRIVER_MSB WLAN_GPIO_PIN10_PAD_DRIVER_MSB
+#define GPIO_PIN10_PAD_DRIVER_LSB WLAN_GPIO_PIN10_PAD_DRIVER_LSB
+#define GPIO_PIN10_PAD_DRIVER_MASK WLAN_GPIO_PIN10_PAD_DRIVER_MASK
+#define GPIO_PIN10_PAD_DRIVER_GET(x) WLAN_GPIO_PIN10_PAD_DRIVER_GET(x)
+#define GPIO_PIN10_PAD_DRIVER_SET(x) WLAN_GPIO_PIN10_PAD_DRIVER_SET(x)
+#define GPIO_PIN10_SOURCE_MSB WLAN_GPIO_PIN10_SOURCE_MSB
+#define GPIO_PIN10_SOURCE_LSB WLAN_GPIO_PIN10_SOURCE_LSB
+#define GPIO_PIN10_SOURCE_MASK WLAN_GPIO_PIN10_SOURCE_MASK
+#define GPIO_PIN10_SOURCE_GET(x) WLAN_GPIO_PIN10_SOURCE_GET(x)
+#define GPIO_PIN10_SOURCE_SET(x) WLAN_GPIO_PIN10_SOURCE_SET(x)
+#define GPIO_PIN11_ADDRESS WLAN_GPIO_PIN11_ADDRESS
+#define GPIO_PIN11_OFFSET WLAN_GPIO_PIN11_OFFSET
+#define GPIO_PIN11_CONFIG_MSB WLAN_GPIO_PIN11_CONFIG_MSB
+#define GPIO_PIN11_CONFIG_LSB WLAN_GPIO_PIN11_CONFIG_LSB
+#define GPIO_PIN11_CONFIG_MASK WLAN_GPIO_PIN11_CONFIG_MASK
+#define GPIO_PIN11_CONFIG_GET(x) WLAN_GPIO_PIN11_CONFIG_GET(x)
+#define GPIO_PIN11_CONFIG_SET(x) WLAN_GPIO_PIN11_CONFIG_SET(x)
+#define GPIO_PIN11_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN11_WAKEUP_ENABLE_MSB
+#define GPIO_PIN11_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB
+#define GPIO_PIN11_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK
+#define GPIO_PIN11_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN11_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN11_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN11_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN11_INT_TYPE_MSB WLAN_GPIO_PIN11_INT_TYPE_MSB
+#define GPIO_PIN11_INT_TYPE_LSB WLAN_GPIO_PIN11_INT_TYPE_LSB
+#define GPIO_PIN11_INT_TYPE_MASK WLAN_GPIO_PIN11_INT_TYPE_MASK
+#define GPIO_PIN11_INT_TYPE_GET(x) WLAN_GPIO_PIN11_INT_TYPE_GET(x)
+#define GPIO_PIN11_INT_TYPE_SET(x) WLAN_GPIO_PIN11_INT_TYPE_SET(x)
+#define GPIO_PIN11_PAD_PULL_MSB WLAN_GPIO_PIN11_PAD_PULL_MSB
+#define GPIO_PIN11_PAD_PULL_LSB WLAN_GPIO_PIN11_PAD_PULL_LSB
+#define GPIO_PIN11_PAD_PULL_MASK WLAN_GPIO_PIN11_PAD_PULL_MASK
+#define GPIO_PIN11_PAD_PULL_GET(x) WLAN_GPIO_PIN11_PAD_PULL_GET(x)
+#define GPIO_PIN11_PAD_PULL_SET(x) WLAN_GPIO_PIN11_PAD_PULL_SET(x)
+#define GPIO_PIN11_PAD_STRENGTH_MSB WLAN_GPIO_PIN11_PAD_STRENGTH_MSB
+#define GPIO_PIN11_PAD_STRENGTH_LSB WLAN_GPIO_PIN11_PAD_STRENGTH_LSB
+#define GPIO_PIN11_PAD_STRENGTH_MASK WLAN_GPIO_PIN11_PAD_STRENGTH_MASK
+#define GPIO_PIN11_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN11_PAD_STRENGTH_GET(x)
+#define GPIO_PIN11_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN11_PAD_STRENGTH_SET(x)
+#define GPIO_PIN11_PAD_DRIVER_MSB WLAN_GPIO_PIN11_PAD_DRIVER_MSB
+#define GPIO_PIN11_PAD_DRIVER_LSB WLAN_GPIO_PIN11_PAD_DRIVER_LSB
+#define GPIO_PIN11_PAD_DRIVER_MASK WLAN_GPIO_PIN11_PAD_DRIVER_MASK
+#define GPIO_PIN11_PAD_DRIVER_GET(x) WLAN_GPIO_PIN11_PAD_DRIVER_GET(x)
+#define GPIO_PIN11_PAD_DRIVER_SET(x) WLAN_GPIO_PIN11_PAD_DRIVER_SET(x)
+#define GPIO_PIN11_SOURCE_MSB WLAN_GPIO_PIN11_SOURCE_MSB
+#define GPIO_PIN11_SOURCE_LSB WLAN_GPIO_PIN11_SOURCE_LSB
+#define GPIO_PIN11_SOURCE_MASK WLAN_GPIO_PIN11_SOURCE_MASK
+#define GPIO_PIN11_SOURCE_GET(x) WLAN_GPIO_PIN11_SOURCE_GET(x)
+#define GPIO_PIN11_SOURCE_SET(x) WLAN_GPIO_PIN11_SOURCE_SET(x)
+#define GPIO_PIN12_ADDRESS WLAN_GPIO_PIN12_ADDRESS
+#define GPIO_PIN12_OFFSET WLAN_GPIO_PIN12_OFFSET
+#define GPIO_PIN12_CONFIG_MSB WLAN_GPIO_PIN12_CONFIG_MSB
+#define GPIO_PIN12_CONFIG_LSB WLAN_GPIO_PIN12_CONFIG_LSB
+#define GPIO_PIN12_CONFIG_MASK WLAN_GPIO_PIN12_CONFIG_MASK
+#define GPIO_PIN12_CONFIG_GET(x) WLAN_GPIO_PIN12_CONFIG_GET(x)
+#define GPIO_PIN12_CONFIG_SET(x) WLAN_GPIO_PIN12_CONFIG_SET(x)
+#define GPIO_PIN12_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN12_WAKEUP_ENABLE_MSB
+#define GPIO_PIN12_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB
+#define GPIO_PIN12_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK
+#define GPIO_PIN12_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN12_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN12_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN12_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN12_INT_TYPE_MSB WLAN_GPIO_PIN12_INT_TYPE_MSB
+#define GPIO_PIN12_INT_TYPE_LSB WLAN_GPIO_PIN12_INT_TYPE_LSB
+#define GPIO_PIN12_INT_TYPE_MASK WLAN_GPIO_PIN12_INT_TYPE_MASK
+#define GPIO_PIN12_INT_TYPE_GET(x) WLAN_GPIO_PIN12_INT_TYPE_GET(x)
+#define GPIO_PIN12_INT_TYPE_SET(x) WLAN_GPIO_PIN12_INT_TYPE_SET(x)
+#define GPIO_PIN12_PAD_PULL_MSB WLAN_GPIO_PIN12_PAD_PULL_MSB
+#define GPIO_PIN12_PAD_PULL_LSB WLAN_GPIO_PIN12_PAD_PULL_LSB
+#define GPIO_PIN12_PAD_PULL_MASK WLAN_GPIO_PIN12_PAD_PULL_MASK
+#define GPIO_PIN12_PAD_PULL_GET(x) WLAN_GPIO_PIN12_PAD_PULL_GET(x)
+#define GPIO_PIN12_PAD_PULL_SET(x) WLAN_GPIO_PIN12_PAD_PULL_SET(x)
+#define GPIO_PIN12_PAD_STRENGTH_MSB WLAN_GPIO_PIN12_PAD_STRENGTH_MSB
+#define GPIO_PIN12_PAD_STRENGTH_LSB WLAN_GPIO_PIN12_PAD_STRENGTH_LSB
+#define GPIO_PIN12_PAD_STRENGTH_MASK WLAN_GPIO_PIN12_PAD_STRENGTH_MASK
+#define GPIO_PIN12_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN12_PAD_STRENGTH_GET(x)
+#define GPIO_PIN12_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN12_PAD_STRENGTH_SET(x)
+#define GPIO_PIN12_PAD_DRIVER_MSB WLAN_GPIO_PIN12_PAD_DRIVER_MSB
+#define GPIO_PIN12_PAD_DRIVER_LSB WLAN_GPIO_PIN12_PAD_DRIVER_LSB
+#define GPIO_PIN12_PAD_DRIVER_MASK WLAN_GPIO_PIN12_PAD_DRIVER_MASK
+#define GPIO_PIN12_PAD_DRIVER_GET(x) WLAN_GPIO_PIN12_PAD_DRIVER_GET(x)
+#define GPIO_PIN12_PAD_DRIVER_SET(x) WLAN_GPIO_PIN12_PAD_DRIVER_SET(x)
+#define GPIO_PIN12_SOURCE_MSB WLAN_GPIO_PIN12_SOURCE_MSB
+#define GPIO_PIN12_SOURCE_LSB WLAN_GPIO_PIN12_SOURCE_LSB
+#define GPIO_PIN12_SOURCE_MASK WLAN_GPIO_PIN12_SOURCE_MASK
+#define GPIO_PIN12_SOURCE_GET(x) WLAN_GPIO_PIN12_SOURCE_GET(x)
+#define GPIO_PIN12_SOURCE_SET(x) WLAN_GPIO_PIN12_SOURCE_SET(x)
+#define GPIO_PIN13_ADDRESS WLAN_GPIO_PIN13_ADDRESS
+#define GPIO_PIN13_OFFSET WLAN_GPIO_PIN13_OFFSET
+#define GPIO_PIN13_CONFIG_MSB WLAN_GPIO_PIN13_CONFIG_MSB
+#define GPIO_PIN13_CONFIG_LSB WLAN_GPIO_PIN13_CONFIG_LSB
+#define GPIO_PIN13_CONFIG_MASK WLAN_GPIO_PIN13_CONFIG_MASK
+#define GPIO_PIN13_CONFIG_GET(x) WLAN_GPIO_PIN13_CONFIG_GET(x)
+#define GPIO_PIN13_CONFIG_SET(x) WLAN_GPIO_PIN13_CONFIG_SET(x)
+#define GPIO_PIN13_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN13_WAKEUP_ENABLE_MSB
+#define GPIO_PIN13_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB
+#define GPIO_PIN13_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK
+#define GPIO_PIN13_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN13_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN13_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN13_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN13_INT_TYPE_MSB WLAN_GPIO_PIN13_INT_TYPE_MSB
+#define GPIO_PIN13_INT_TYPE_LSB WLAN_GPIO_PIN13_INT_TYPE_LSB
+#define GPIO_PIN13_INT_TYPE_MASK WLAN_GPIO_PIN13_INT_TYPE_MASK
+#define GPIO_PIN13_INT_TYPE_GET(x) WLAN_GPIO_PIN13_INT_TYPE_GET(x)
+#define GPIO_PIN13_INT_TYPE_SET(x) WLAN_GPIO_PIN13_INT_TYPE_SET(x)
+#define GPIO_PIN13_PAD_PULL_MSB WLAN_GPIO_PIN13_PAD_PULL_MSB
+#define GPIO_PIN13_PAD_PULL_LSB WLAN_GPIO_PIN13_PAD_PULL_LSB
+#define GPIO_PIN13_PAD_PULL_MASK WLAN_GPIO_PIN13_PAD_PULL_MASK
+#define GPIO_PIN13_PAD_PULL_GET(x) WLAN_GPIO_PIN13_PAD_PULL_GET(x)
+#define GPIO_PIN13_PAD_PULL_SET(x) WLAN_GPIO_PIN13_PAD_PULL_SET(x)
+#define GPIO_PIN13_PAD_STRENGTH_MSB WLAN_GPIO_PIN13_PAD_STRENGTH_MSB
+#define GPIO_PIN13_PAD_STRENGTH_LSB WLAN_GPIO_PIN13_PAD_STRENGTH_LSB
+#define GPIO_PIN13_PAD_STRENGTH_MASK WLAN_GPIO_PIN13_PAD_STRENGTH_MASK
+#define GPIO_PIN13_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN13_PAD_STRENGTH_GET(x)
+#define GPIO_PIN13_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN13_PAD_STRENGTH_SET(x)
+#define GPIO_PIN13_PAD_DRIVER_MSB WLAN_GPIO_PIN13_PAD_DRIVER_MSB
+#define GPIO_PIN13_PAD_DRIVER_LSB WLAN_GPIO_PIN13_PAD_DRIVER_LSB
+#define GPIO_PIN13_PAD_DRIVER_MASK WLAN_GPIO_PIN13_PAD_DRIVER_MASK
+#define GPIO_PIN13_PAD_DRIVER_GET(x) WLAN_GPIO_PIN13_PAD_DRIVER_GET(x)
+#define GPIO_PIN13_PAD_DRIVER_SET(x) WLAN_GPIO_PIN13_PAD_DRIVER_SET(x)
+#define GPIO_PIN13_SOURCE_MSB WLAN_GPIO_PIN13_SOURCE_MSB
+#define GPIO_PIN13_SOURCE_LSB WLAN_GPIO_PIN13_SOURCE_LSB
+#define GPIO_PIN13_SOURCE_MASK WLAN_GPIO_PIN13_SOURCE_MASK
+#define GPIO_PIN13_SOURCE_GET(x) WLAN_GPIO_PIN13_SOURCE_GET(x)
+#define GPIO_PIN13_SOURCE_SET(x) WLAN_GPIO_PIN13_SOURCE_SET(x)
+#define GPIO_PIN14_ADDRESS WLAN_GPIO_PIN14_ADDRESS
+#define GPIO_PIN14_OFFSET WLAN_GPIO_PIN14_OFFSET
+#define GPIO_PIN14_CONFIG_MSB WLAN_GPIO_PIN14_CONFIG_MSB
+#define GPIO_PIN14_CONFIG_LSB WLAN_GPIO_PIN14_CONFIG_LSB
+#define GPIO_PIN14_CONFIG_MASK WLAN_GPIO_PIN14_CONFIG_MASK
+#define GPIO_PIN14_CONFIG_GET(x) WLAN_GPIO_PIN14_CONFIG_GET(x)
+#define GPIO_PIN14_CONFIG_SET(x) WLAN_GPIO_PIN14_CONFIG_SET(x)
+#define GPIO_PIN14_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN14_WAKEUP_ENABLE_MSB
+#define GPIO_PIN14_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB
+#define GPIO_PIN14_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK
+#define GPIO_PIN14_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN14_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN14_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN14_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN14_INT_TYPE_MSB WLAN_GPIO_PIN14_INT_TYPE_MSB
+#define GPIO_PIN14_INT_TYPE_LSB WLAN_GPIO_PIN14_INT_TYPE_LSB
+#define GPIO_PIN14_INT_TYPE_MASK WLAN_GPIO_PIN14_INT_TYPE_MASK
+#define GPIO_PIN14_INT_TYPE_GET(x) WLAN_GPIO_PIN14_INT_TYPE_GET(x)
+#define GPIO_PIN14_INT_TYPE_SET(x) WLAN_GPIO_PIN14_INT_TYPE_SET(x)
+#define GPIO_PIN14_PAD_PULL_MSB WLAN_GPIO_PIN14_PAD_PULL_MSB
+#define GPIO_PIN14_PAD_PULL_LSB WLAN_GPIO_PIN14_PAD_PULL_LSB
+#define GPIO_PIN14_PAD_PULL_MASK WLAN_GPIO_PIN14_PAD_PULL_MASK
+#define GPIO_PIN14_PAD_PULL_GET(x) WLAN_GPIO_PIN14_PAD_PULL_GET(x)
+#define GPIO_PIN14_PAD_PULL_SET(x) WLAN_GPIO_PIN14_PAD_PULL_SET(x)
+#define GPIO_PIN14_PAD_STRENGTH_MSB WLAN_GPIO_PIN14_PAD_STRENGTH_MSB
+#define GPIO_PIN14_PAD_STRENGTH_LSB WLAN_GPIO_PIN14_PAD_STRENGTH_LSB
+#define GPIO_PIN14_PAD_STRENGTH_MASK WLAN_GPIO_PIN14_PAD_STRENGTH_MASK
+#define GPIO_PIN14_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN14_PAD_STRENGTH_GET(x)
+#define GPIO_PIN14_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN14_PAD_STRENGTH_SET(x)
+#define GPIO_PIN14_PAD_DRIVER_MSB WLAN_GPIO_PIN14_PAD_DRIVER_MSB
+#define GPIO_PIN14_PAD_DRIVER_LSB WLAN_GPIO_PIN14_PAD_DRIVER_LSB
+#define GPIO_PIN14_PAD_DRIVER_MASK WLAN_GPIO_PIN14_PAD_DRIVER_MASK
+#define GPIO_PIN14_PAD_DRIVER_GET(x) WLAN_GPIO_PIN14_PAD_DRIVER_GET(x)
+#define GPIO_PIN14_PAD_DRIVER_SET(x) WLAN_GPIO_PIN14_PAD_DRIVER_SET(x)
+#define GPIO_PIN14_SOURCE_MSB WLAN_GPIO_PIN14_SOURCE_MSB
+#define GPIO_PIN14_SOURCE_LSB WLAN_GPIO_PIN14_SOURCE_LSB
+#define GPIO_PIN14_SOURCE_MASK WLAN_GPIO_PIN14_SOURCE_MASK
+#define GPIO_PIN14_SOURCE_GET(x) WLAN_GPIO_PIN14_SOURCE_GET(x)
+#define GPIO_PIN14_SOURCE_SET(x) WLAN_GPIO_PIN14_SOURCE_SET(x)
+#define GPIO_PIN15_ADDRESS WLAN_GPIO_PIN15_ADDRESS
+#define GPIO_PIN15_OFFSET WLAN_GPIO_PIN15_OFFSET
+#define GPIO_PIN15_CONFIG_MSB WLAN_GPIO_PIN15_CONFIG_MSB
+#define GPIO_PIN15_CONFIG_LSB WLAN_GPIO_PIN15_CONFIG_LSB
+#define GPIO_PIN15_CONFIG_MASK WLAN_GPIO_PIN15_CONFIG_MASK
+#define GPIO_PIN15_CONFIG_GET(x) WLAN_GPIO_PIN15_CONFIG_GET(x)
+#define GPIO_PIN15_CONFIG_SET(x) WLAN_GPIO_PIN15_CONFIG_SET(x)
+#define GPIO_PIN15_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN15_WAKEUP_ENABLE_MSB
+#define GPIO_PIN15_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB
+#define GPIO_PIN15_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK
+#define GPIO_PIN15_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN15_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN15_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN15_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN15_INT_TYPE_MSB WLAN_GPIO_PIN15_INT_TYPE_MSB
+#define GPIO_PIN15_INT_TYPE_LSB WLAN_GPIO_PIN15_INT_TYPE_LSB
+#define GPIO_PIN15_INT_TYPE_MASK WLAN_GPIO_PIN15_INT_TYPE_MASK
+#define GPIO_PIN15_INT_TYPE_GET(x) WLAN_GPIO_PIN15_INT_TYPE_GET(x)
+#define GPIO_PIN15_INT_TYPE_SET(x) WLAN_GPIO_PIN15_INT_TYPE_SET(x)
+#define GPIO_PIN15_PAD_PULL_MSB WLAN_GPIO_PIN15_PAD_PULL_MSB
+#define GPIO_PIN15_PAD_PULL_LSB WLAN_GPIO_PIN15_PAD_PULL_LSB
+#define GPIO_PIN15_PAD_PULL_MASK WLAN_GPIO_PIN15_PAD_PULL_MASK
+#define GPIO_PIN15_PAD_PULL_GET(x) WLAN_GPIO_PIN15_PAD_PULL_GET(x)
+#define GPIO_PIN15_PAD_PULL_SET(x) WLAN_GPIO_PIN15_PAD_PULL_SET(x)
+#define GPIO_PIN15_PAD_STRENGTH_MSB WLAN_GPIO_PIN15_PAD_STRENGTH_MSB
+#define GPIO_PIN15_PAD_STRENGTH_LSB WLAN_GPIO_PIN15_PAD_STRENGTH_LSB
+#define GPIO_PIN15_PAD_STRENGTH_MASK WLAN_GPIO_PIN15_PAD_STRENGTH_MASK
+#define GPIO_PIN15_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN15_PAD_STRENGTH_GET(x)
+#define GPIO_PIN15_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN15_PAD_STRENGTH_SET(x)
+#define GPIO_PIN15_PAD_DRIVER_MSB WLAN_GPIO_PIN15_PAD_DRIVER_MSB
+#define GPIO_PIN15_PAD_DRIVER_LSB WLAN_GPIO_PIN15_PAD_DRIVER_LSB
+#define GPIO_PIN15_PAD_DRIVER_MASK WLAN_GPIO_PIN15_PAD_DRIVER_MASK
+#define GPIO_PIN15_PAD_DRIVER_GET(x) WLAN_GPIO_PIN15_PAD_DRIVER_GET(x)
+#define GPIO_PIN15_PAD_DRIVER_SET(x) WLAN_GPIO_PIN15_PAD_DRIVER_SET(x)
+#define GPIO_PIN15_SOURCE_MSB WLAN_GPIO_PIN15_SOURCE_MSB
+#define GPIO_PIN15_SOURCE_LSB WLAN_GPIO_PIN15_SOURCE_LSB
+#define GPIO_PIN15_SOURCE_MASK WLAN_GPIO_PIN15_SOURCE_MASK
+#define GPIO_PIN15_SOURCE_GET(x) WLAN_GPIO_PIN15_SOURCE_GET(x)
+#define GPIO_PIN15_SOURCE_SET(x) WLAN_GPIO_PIN15_SOURCE_SET(x)
+#define GPIO_PIN16_ADDRESS WLAN_GPIO_PIN16_ADDRESS
+#define GPIO_PIN16_OFFSET WLAN_GPIO_PIN16_OFFSET
+#define GPIO_PIN16_CONFIG_MSB WLAN_GPIO_PIN16_CONFIG_MSB
+#define GPIO_PIN16_CONFIG_LSB WLAN_GPIO_PIN16_CONFIG_LSB
+#define GPIO_PIN16_CONFIG_MASK WLAN_GPIO_PIN16_CONFIG_MASK
+#define GPIO_PIN16_CONFIG_GET(x) WLAN_GPIO_PIN16_CONFIG_GET(x)
+#define GPIO_PIN16_CONFIG_SET(x) WLAN_GPIO_PIN16_CONFIG_SET(x)
+#define GPIO_PIN16_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN16_WAKEUP_ENABLE_MSB
+#define GPIO_PIN16_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB
+#define GPIO_PIN16_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK
+#define GPIO_PIN16_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN16_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN16_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN16_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN16_INT_TYPE_MSB WLAN_GPIO_PIN16_INT_TYPE_MSB
+#define GPIO_PIN16_INT_TYPE_LSB WLAN_GPIO_PIN16_INT_TYPE_LSB
+#define GPIO_PIN16_INT_TYPE_MASK WLAN_GPIO_PIN16_INT_TYPE_MASK
+#define GPIO_PIN16_INT_TYPE_GET(x) WLAN_GPIO_PIN16_INT_TYPE_GET(x)
+#define GPIO_PIN16_INT_TYPE_SET(x) WLAN_GPIO_PIN16_INT_TYPE_SET(x)
+#define GPIO_PIN16_PAD_PULL_MSB WLAN_GPIO_PIN16_PAD_PULL_MSB
+#define GPIO_PIN16_PAD_PULL_LSB WLAN_GPIO_PIN16_PAD_PULL_LSB
+#define GPIO_PIN16_PAD_PULL_MASK WLAN_GPIO_PIN16_PAD_PULL_MASK
+#define GPIO_PIN16_PAD_PULL_GET(x) WLAN_GPIO_PIN16_PAD_PULL_GET(x)
+#define GPIO_PIN16_PAD_PULL_SET(x) WLAN_GPIO_PIN16_PAD_PULL_SET(x)
+#define GPIO_PIN16_PAD_STRENGTH_MSB WLAN_GPIO_PIN16_PAD_STRENGTH_MSB
+#define GPIO_PIN16_PAD_STRENGTH_LSB WLAN_GPIO_PIN16_PAD_STRENGTH_LSB
+#define GPIO_PIN16_PAD_STRENGTH_MASK WLAN_GPIO_PIN16_PAD_STRENGTH_MASK
+#define GPIO_PIN16_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN16_PAD_STRENGTH_GET(x)
+#define GPIO_PIN16_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN16_PAD_STRENGTH_SET(x)
+#define GPIO_PIN16_PAD_DRIVER_MSB WLAN_GPIO_PIN16_PAD_DRIVER_MSB
+#define GPIO_PIN16_PAD_DRIVER_LSB WLAN_GPIO_PIN16_PAD_DRIVER_LSB
+#define GPIO_PIN16_PAD_DRIVER_MASK WLAN_GPIO_PIN16_PAD_DRIVER_MASK
+#define GPIO_PIN16_PAD_DRIVER_GET(x) WLAN_GPIO_PIN16_PAD_DRIVER_GET(x)
+#define GPIO_PIN16_PAD_DRIVER_SET(x) WLAN_GPIO_PIN16_PAD_DRIVER_SET(x)
+#define GPIO_PIN16_SOURCE_MSB WLAN_GPIO_PIN16_SOURCE_MSB
+#define GPIO_PIN16_SOURCE_LSB WLAN_GPIO_PIN16_SOURCE_LSB
+#define GPIO_PIN16_SOURCE_MASK WLAN_GPIO_PIN16_SOURCE_MASK
+#define GPIO_PIN16_SOURCE_GET(x) WLAN_GPIO_PIN16_SOURCE_GET(x)
+#define GPIO_PIN16_SOURCE_SET(x) WLAN_GPIO_PIN16_SOURCE_SET(x)
+#define GPIO_PIN17_ADDRESS WLAN_GPIO_PIN17_ADDRESS
+#define GPIO_PIN17_OFFSET WLAN_GPIO_PIN17_OFFSET
+#define GPIO_PIN17_CONFIG_MSB WLAN_GPIO_PIN17_CONFIG_MSB
+#define GPIO_PIN17_CONFIG_LSB WLAN_GPIO_PIN17_CONFIG_LSB
+#define GPIO_PIN17_CONFIG_MASK WLAN_GPIO_PIN17_CONFIG_MASK
+#define GPIO_PIN17_CONFIG_GET(x) WLAN_GPIO_PIN17_CONFIG_GET(x)
+#define GPIO_PIN17_CONFIG_SET(x) WLAN_GPIO_PIN17_CONFIG_SET(x)
+#define GPIO_PIN17_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN17_WAKEUP_ENABLE_MSB
+#define GPIO_PIN17_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB
+#define GPIO_PIN17_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK
+#define GPIO_PIN17_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN17_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN17_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN17_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN17_INT_TYPE_MSB WLAN_GPIO_PIN17_INT_TYPE_MSB
+#define GPIO_PIN17_INT_TYPE_LSB WLAN_GPIO_PIN17_INT_TYPE_LSB
+#define GPIO_PIN17_INT_TYPE_MASK WLAN_GPIO_PIN17_INT_TYPE_MASK
+#define GPIO_PIN17_INT_TYPE_GET(x) WLAN_GPIO_PIN17_INT_TYPE_GET(x)
+#define GPIO_PIN17_INT_TYPE_SET(x) WLAN_GPIO_PIN17_INT_TYPE_SET(x)
+#define GPIO_PIN17_PAD_PULL_MSB WLAN_GPIO_PIN17_PAD_PULL_MSB
+#define GPIO_PIN17_PAD_PULL_LSB WLAN_GPIO_PIN17_PAD_PULL_LSB
+#define GPIO_PIN17_PAD_PULL_MASK WLAN_GPIO_PIN17_PAD_PULL_MASK
+#define GPIO_PIN17_PAD_PULL_GET(x) WLAN_GPIO_PIN17_PAD_PULL_GET(x)
+#define GPIO_PIN17_PAD_PULL_SET(x) WLAN_GPIO_PIN17_PAD_PULL_SET(x)
+#define GPIO_PIN17_PAD_STRENGTH_MSB WLAN_GPIO_PIN17_PAD_STRENGTH_MSB
+#define GPIO_PIN17_PAD_STRENGTH_LSB WLAN_GPIO_PIN17_PAD_STRENGTH_LSB
+#define GPIO_PIN17_PAD_STRENGTH_MASK WLAN_GPIO_PIN17_PAD_STRENGTH_MASK
+#define GPIO_PIN17_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN17_PAD_STRENGTH_GET(x)
+#define GPIO_PIN17_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN17_PAD_STRENGTH_SET(x)
+#define GPIO_PIN17_PAD_DRIVER_MSB WLAN_GPIO_PIN17_PAD_DRIVER_MSB
+#define GPIO_PIN17_PAD_DRIVER_LSB WLAN_GPIO_PIN17_PAD_DRIVER_LSB
+#define GPIO_PIN17_PAD_DRIVER_MASK WLAN_GPIO_PIN17_PAD_DRIVER_MASK
+#define GPIO_PIN17_PAD_DRIVER_GET(x) WLAN_GPIO_PIN17_PAD_DRIVER_GET(x)
+#define GPIO_PIN17_PAD_DRIVER_SET(x) WLAN_GPIO_PIN17_PAD_DRIVER_SET(x)
+#define GPIO_PIN17_SOURCE_MSB WLAN_GPIO_PIN17_SOURCE_MSB
+#define GPIO_PIN17_SOURCE_LSB WLAN_GPIO_PIN17_SOURCE_LSB
+#define GPIO_PIN17_SOURCE_MASK WLAN_GPIO_PIN17_SOURCE_MASK
+#define GPIO_PIN17_SOURCE_GET(x) WLAN_GPIO_PIN17_SOURCE_GET(x)
+#define GPIO_PIN17_SOURCE_SET(x) WLAN_GPIO_PIN17_SOURCE_SET(x)
+#define GPIO_PIN18_ADDRESS WLAN_GPIO_PIN18_ADDRESS
+#define GPIO_PIN18_OFFSET WLAN_GPIO_PIN18_OFFSET
+#define GPIO_PIN18_CONFIG_MSB WLAN_GPIO_PIN18_CONFIG_MSB
+#define GPIO_PIN18_CONFIG_LSB WLAN_GPIO_PIN18_CONFIG_LSB
+#define GPIO_PIN18_CONFIG_MASK WLAN_GPIO_PIN18_CONFIG_MASK
+#define GPIO_PIN18_CONFIG_GET(x) WLAN_GPIO_PIN18_CONFIG_GET(x)
+#define GPIO_PIN18_CONFIG_SET(x) WLAN_GPIO_PIN18_CONFIG_SET(x)
+#define GPIO_PIN18_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN18_WAKEUP_ENABLE_MSB
+#define GPIO_PIN18_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB
+#define GPIO_PIN18_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK
+#define GPIO_PIN18_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN18_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN18_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN18_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN18_INT_TYPE_MSB WLAN_GPIO_PIN18_INT_TYPE_MSB
+#define GPIO_PIN18_INT_TYPE_LSB WLAN_GPIO_PIN18_INT_TYPE_LSB
+#define GPIO_PIN18_INT_TYPE_MASK WLAN_GPIO_PIN18_INT_TYPE_MASK
+#define GPIO_PIN18_INT_TYPE_GET(x) WLAN_GPIO_PIN18_INT_TYPE_GET(x)
+#define GPIO_PIN18_INT_TYPE_SET(x) WLAN_GPIO_PIN18_INT_TYPE_SET(x)
+#define GPIO_PIN18_PAD_PULL_MSB WLAN_GPIO_PIN18_PAD_PULL_MSB
+#define GPIO_PIN18_PAD_PULL_LSB WLAN_GPIO_PIN18_PAD_PULL_LSB
+#define GPIO_PIN18_PAD_PULL_MASK WLAN_GPIO_PIN18_PAD_PULL_MASK
+#define GPIO_PIN18_PAD_PULL_GET(x) WLAN_GPIO_PIN18_PAD_PULL_GET(x)
+#define GPIO_PIN18_PAD_PULL_SET(x) WLAN_GPIO_PIN18_PAD_PULL_SET(x)
+#define GPIO_PIN18_PAD_STRENGTH_MSB WLAN_GPIO_PIN18_PAD_STRENGTH_MSB
+#define GPIO_PIN18_PAD_STRENGTH_LSB WLAN_GPIO_PIN18_PAD_STRENGTH_LSB
+#define GPIO_PIN18_PAD_STRENGTH_MASK WLAN_GPIO_PIN18_PAD_STRENGTH_MASK
+#define GPIO_PIN18_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN18_PAD_STRENGTH_GET(x)
+#define GPIO_PIN18_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN18_PAD_STRENGTH_SET(x)
+#define GPIO_PIN18_PAD_DRIVER_MSB WLAN_GPIO_PIN18_PAD_DRIVER_MSB
+#define GPIO_PIN18_PAD_DRIVER_LSB WLAN_GPIO_PIN18_PAD_DRIVER_LSB
+#define GPIO_PIN18_PAD_DRIVER_MASK WLAN_GPIO_PIN18_PAD_DRIVER_MASK
+#define GPIO_PIN18_PAD_DRIVER_GET(x) WLAN_GPIO_PIN18_PAD_DRIVER_GET(x)
+#define GPIO_PIN18_PAD_DRIVER_SET(x) WLAN_GPIO_PIN18_PAD_DRIVER_SET(x)
+#define GPIO_PIN18_SOURCE_MSB WLAN_GPIO_PIN18_SOURCE_MSB
+#define GPIO_PIN18_SOURCE_LSB WLAN_GPIO_PIN18_SOURCE_LSB
+#define GPIO_PIN18_SOURCE_MASK WLAN_GPIO_PIN18_SOURCE_MASK
+#define GPIO_PIN18_SOURCE_GET(x) WLAN_GPIO_PIN18_SOURCE_GET(x)
+#define GPIO_PIN18_SOURCE_SET(x) WLAN_GPIO_PIN18_SOURCE_SET(x)
+#define GPIO_PIN19_ADDRESS WLAN_GPIO_PIN19_ADDRESS
+#define GPIO_PIN19_OFFSET WLAN_GPIO_PIN19_OFFSET
+#define GPIO_PIN19_CONFIG_MSB WLAN_GPIO_PIN19_CONFIG_MSB
+#define GPIO_PIN19_CONFIG_LSB WLAN_GPIO_PIN19_CONFIG_LSB
+#define GPIO_PIN19_CONFIG_MASK WLAN_GPIO_PIN19_CONFIG_MASK
+#define GPIO_PIN19_CONFIG_GET(x) WLAN_GPIO_PIN19_CONFIG_GET(x)
+#define GPIO_PIN19_CONFIG_SET(x) WLAN_GPIO_PIN19_CONFIG_SET(x)
+#define GPIO_PIN19_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN19_WAKEUP_ENABLE_MSB
+#define GPIO_PIN19_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB
+#define GPIO_PIN19_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK
+#define GPIO_PIN19_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN19_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN19_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN19_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN19_INT_TYPE_MSB WLAN_GPIO_PIN19_INT_TYPE_MSB
+#define GPIO_PIN19_INT_TYPE_LSB WLAN_GPIO_PIN19_INT_TYPE_LSB
+#define GPIO_PIN19_INT_TYPE_MASK WLAN_GPIO_PIN19_INT_TYPE_MASK
+#define GPIO_PIN19_INT_TYPE_GET(x) WLAN_GPIO_PIN19_INT_TYPE_GET(x)
+#define GPIO_PIN19_INT_TYPE_SET(x) WLAN_GPIO_PIN19_INT_TYPE_SET(x)
+#define GPIO_PIN19_PAD_PULL_MSB WLAN_GPIO_PIN19_PAD_PULL_MSB
+#define GPIO_PIN19_PAD_PULL_LSB WLAN_GPIO_PIN19_PAD_PULL_LSB
+#define GPIO_PIN19_PAD_PULL_MASK WLAN_GPIO_PIN19_PAD_PULL_MASK
+#define GPIO_PIN19_PAD_PULL_GET(x) WLAN_GPIO_PIN19_PAD_PULL_GET(x)
+#define GPIO_PIN19_PAD_PULL_SET(x) WLAN_GPIO_PIN19_PAD_PULL_SET(x)
+#define GPIO_PIN19_PAD_STRENGTH_MSB WLAN_GPIO_PIN19_PAD_STRENGTH_MSB
+#define GPIO_PIN19_PAD_STRENGTH_LSB WLAN_GPIO_PIN19_PAD_STRENGTH_LSB
+#define GPIO_PIN19_PAD_STRENGTH_MASK WLAN_GPIO_PIN19_PAD_STRENGTH_MASK
+#define GPIO_PIN19_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN19_PAD_STRENGTH_GET(x)
+#define GPIO_PIN19_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN19_PAD_STRENGTH_SET(x)
+#define GPIO_PIN19_PAD_DRIVER_MSB WLAN_GPIO_PIN19_PAD_DRIVER_MSB
+#define GPIO_PIN19_PAD_DRIVER_LSB WLAN_GPIO_PIN19_PAD_DRIVER_LSB
+#define GPIO_PIN19_PAD_DRIVER_MASK WLAN_GPIO_PIN19_PAD_DRIVER_MASK
+#define GPIO_PIN19_PAD_DRIVER_GET(x) WLAN_GPIO_PIN19_PAD_DRIVER_GET(x)
+#define GPIO_PIN19_PAD_DRIVER_SET(x) WLAN_GPIO_PIN19_PAD_DRIVER_SET(x)
+#define GPIO_PIN19_SOURCE_MSB WLAN_GPIO_PIN19_SOURCE_MSB
+#define GPIO_PIN19_SOURCE_LSB WLAN_GPIO_PIN19_SOURCE_LSB
+#define GPIO_PIN19_SOURCE_MASK WLAN_GPIO_PIN19_SOURCE_MASK
+#define GPIO_PIN19_SOURCE_GET(x) WLAN_GPIO_PIN19_SOURCE_GET(x)
+#define GPIO_PIN19_SOURCE_SET(x) WLAN_GPIO_PIN19_SOURCE_SET(x)
+#define GPIO_PIN20_ADDRESS WLAN_GPIO_PIN20_ADDRESS
+#define GPIO_PIN20_OFFSET WLAN_GPIO_PIN20_OFFSET
+#define GPIO_PIN20_CONFIG_MSB WLAN_GPIO_PIN20_CONFIG_MSB
+#define GPIO_PIN20_CONFIG_LSB WLAN_GPIO_PIN20_CONFIG_LSB
+#define GPIO_PIN20_CONFIG_MASK WLAN_GPIO_PIN20_CONFIG_MASK
+#define GPIO_PIN20_CONFIG_GET(x) WLAN_GPIO_PIN20_CONFIG_GET(x)
+#define GPIO_PIN20_CONFIG_SET(x) WLAN_GPIO_PIN20_CONFIG_SET(x)
+#define GPIO_PIN20_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN20_WAKEUP_ENABLE_MSB
+#define GPIO_PIN20_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB
+#define GPIO_PIN20_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK
+#define GPIO_PIN20_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN20_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN20_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN20_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN20_INT_TYPE_MSB WLAN_GPIO_PIN20_INT_TYPE_MSB
+#define GPIO_PIN20_INT_TYPE_LSB WLAN_GPIO_PIN20_INT_TYPE_LSB
+#define GPIO_PIN20_INT_TYPE_MASK WLAN_GPIO_PIN20_INT_TYPE_MASK
+#define GPIO_PIN20_INT_TYPE_GET(x) WLAN_GPIO_PIN20_INT_TYPE_GET(x)
+#define GPIO_PIN20_INT_TYPE_SET(x) WLAN_GPIO_PIN20_INT_TYPE_SET(x)
+#define GPIO_PIN20_PAD_PULL_MSB WLAN_GPIO_PIN20_PAD_PULL_MSB
+#define GPIO_PIN20_PAD_PULL_LSB WLAN_GPIO_PIN20_PAD_PULL_LSB
+#define GPIO_PIN20_PAD_PULL_MASK WLAN_GPIO_PIN20_PAD_PULL_MASK
+#define GPIO_PIN20_PAD_PULL_GET(x) WLAN_GPIO_PIN20_PAD_PULL_GET(x)
+#define GPIO_PIN20_PAD_PULL_SET(x) WLAN_GPIO_PIN20_PAD_PULL_SET(x)
+#define GPIO_PIN20_PAD_STRENGTH_MSB WLAN_GPIO_PIN20_PAD_STRENGTH_MSB
+#define GPIO_PIN20_PAD_STRENGTH_LSB WLAN_GPIO_PIN20_PAD_STRENGTH_LSB
+#define GPIO_PIN20_PAD_STRENGTH_MASK WLAN_GPIO_PIN20_PAD_STRENGTH_MASK
+#define GPIO_PIN20_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN20_PAD_STRENGTH_GET(x)
+#define GPIO_PIN20_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN20_PAD_STRENGTH_SET(x)
+#define GPIO_PIN20_PAD_DRIVER_MSB WLAN_GPIO_PIN20_PAD_DRIVER_MSB
+#define GPIO_PIN20_PAD_DRIVER_LSB WLAN_GPIO_PIN20_PAD_DRIVER_LSB
+#define GPIO_PIN20_PAD_DRIVER_MASK WLAN_GPIO_PIN20_PAD_DRIVER_MASK
+#define GPIO_PIN20_PAD_DRIVER_GET(x) WLAN_GPIO_PIN20_PAD_DRIVER_GET(x)
+#define GPIO_PIN20_PAD_DRIVER_SET(x) WLAN_GPIO_PIN20_PAD_DRIVER_SET(x)
+#define GPIO_PIN20_SOURCE_MSB WLAN_GPIO_PIN20_SOURCE_MSB
+#define GPIO_PIN20_SOURCE_LSB WLAN_GPIO_PIN20_SOURCE_LSB
+#define GPIO_PIN20_SOURCE_MASK WLAN_GPIO_PIN20_SOURCE_MASK
+#define GPIO_PIN20_SOURCE_GET(x) WLAN_GPIO_PIN20_SOURCE_GET(x)
+#define GPIO_PIN20_SOURCE_SET(x) WLAN_GPIO_PIN20_SOURCE_SET(x)
+#define GPIO_PIN21_ADDRESS WLAN_GPIO_PIN21_ADDRESS
+#define GPIO_PIN21_OFFSET WLAN_GPIO_PIN21_OFFSET
+#define GPIO_PIN21_CONFIG_MSB WLAN_GPIO_PIN21_CONFIG_MSB
+#define GPIO_PIN21_CONFIG_LSB WLAN_GPIO_PIN21_CONFIG_LSB
+#define GPIO_PIN21_CONFIG_MASK WLAN_GPIO_PIN21_CONFIG_MASK
+#define GPIO_PIN21_CONFIG_GET(x) WLAN_GPIO_PIN21_CONFIG_GET(x)
+#define GPIO_PIN21_CONFIG_SET(x) WLAN_GPIO_PIN21_CONFIG_SET(x)
+#define GPIO_PIN21_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN21_WAKEUP_ENABLE_MSB
+#define GPIO_PIN21_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB
+#define GPIO_PIN21_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK
+#define GPIO_PIN21_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN21_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN21_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN21_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN21_INT_TYPE_MSB WLAN_GPIO_PIN21_INT_TYPE_MSB
+#define GPIO_PIN21_INT_TYPE_LSB WLAN_GPIO_PIN21_INT_TYPE_LSB
+#define GPIO_PIN21_INT_TYPE_MASK WLAN_GPIO_PIN21_INT_TYPE_MASK
+#define GPIO_PIN21_INT_TYPE_GET(x) WLAN_GPIO_PIN21_INT_TYPE_GET(x)
+#define GPIO_PIN21_INT_TYPE_SET(x) WLAN_GPIO_PIN21_INT_TYPE_SET(x)
+#define GPIO_PIN21_PAD_PULL_MSB WLAN_GPIO_PIN21_PAD_PULL_MSB
+#define GPIO_PIN21_PAD_PULL_LSB WLAN_GPIO_PIN21_PAD_PULL_LSB
+#define GPIO_PIN21_PAD_PULL_MASK WLAN_GPIO_PIN21_PAD_PULL_MASK
+#define GPIO_PIN21_PAD_PULL_GET(x) WLAN_GPIO_PIN21_PAD_PULL_GET(x)
+#define GPIO_PIN21_PAD_PULL_SET(x) WLAN_GPIO_PIN21_PAD_PULL_SET(x)
+#define GPIO_PIN21_PAD_STRENGTH_MSB WLAN_GPIO_PIN21_PAD_STRENGTH_MSB
+#define GPIO_PIN21_PAD_STRENGTH_LSB WLAN_GPIO_PIN21_PAD_STRENGTH_LSB
+#define GPIO_PIN21_PAD_STRENGTH_MASK WLAN_GPIO_PIN21_PAD_STRENGTH_MASK
+#define GPIO_PIN21_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN21_PAD_STRENGTH_GET(x)
+#define GPIO_PIN21_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN21_PAD_STRENGTH_SET(x)
+#define GPIO_PIN21_PAD_DRIVER_MSB WLAN_GPIO_PIN21_PAD_DRIVER_MSB
+#define GPIO_PIN21_PAD_DRIVER_LSB WLAN_GPIO_PIN21_PAD_DRIVER_LSB
+#define GPIO_PIN21_PAD_DRIVER_MASK WLAN_GPIO_PIN21_PAD_DRIVER_MASK
+#define GPIO_PIN21_PAD_DRIVER_GET(x) WLAN_GPIO_PIN21_PAD_DRIVER_GET(x)
+#define GPIO_PIN21_PAD_DRIVER_SET(x) WLAN_GPIO_PIN21_PAD_DRIVER_SET(x)
+#define GPIO_PIN21_SOURCE_MSB WLAN_GPIO_PIN21_SOURCE_MSB
+#define GPIO_PIN21_SOURCE_LSB WLAN_GPIO_PIN21_SOURCE_LSB
+#define GPIO_PIN21_SOURCE_MASK WLAN_GPIO_PIN21_SOURCE_MASK
+#define GPIO_PIN21_SOURCE_GET(x) WLAN_GPIO_PIN21_SOURCE_GET(x)
+#define GPIO_PIN21_SOURCE_SET(x) WLAN_GPIO_PIN21_SOURCE_SET(x)
+#define GPIO_PIN22_ADDRESS WLAN_GPIO_PIN22_ADDRESS
+#define GPIO_PIN22_OFFSET WLAN_GPIO_PIN22_OFFSET
+#define GPIO_PIN22_CONFIG_MSB WLAN_GPIO_PIN22_CONFIG_MSB
+#define GPIO_PIN22_CONFIG_LSB WLAN_GPIO_PIN22_CONFIG_LSB
+#define GPIO_PIN22_CONFIG_MASK WLAN_GPIO_PIN22_CONFIG_MASK
+#define GPIO_PIN22_CONFIG_GET(x) WLAN_GPIO_PIN22_CONFIG_GET(x)
+#define GPIO_PIN22_CONFIG_SET(x) WLAN_GPIO_PIN22_CONFIG_SET(x)
+#define GPIO_PIN22_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN22_WAKEUP_ENABLE_MSB
+#define GPIO_PIN22_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB
+#define GPIO_PIN22_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK
+#define GPIO_PIN22_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN22_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN22_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN22_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN22_INT_TYPE_MSB WLAN_GPIO_PIN22_INT_TYPE_MSB
+#define GPIO_PIN22_INT_TYPE_LSB WLAN_GPIO_PIN22_INT_TYPE_LSB
+#define GPIO_PIN22_INT_TYPE_MASK WLAN_GPIO_PIN22_INT_TYPE_MASK
+#define GPIO_PIN22_INT_TYPE_GET(x) WLAN_GPIO_PIN22_INT_TYPE_GET(x)
+#define GPIO_PIN22_INT_TYPE_SET(x) WLAN_GPIO_PIN22_INT_TYPE_SET(x)
+#define GPIO_PIN22_PAD_PULL_MSB WLAN_GPIO_PIN22_PAD_PULL_MSB
+#define GPIO_PIN22_PAD_PULL_LSB WLAN_GPIO_PIN22_PAD_PULL_LSB
+#define GPIO_PIN22_PAD_PULL_MASK WLAN_GPIO_PIN22_PAD_PULL_MASK
+#define GPIO_PIN22_PAD_PULL_GET(x) WLAN_GPIO_PIN22_PAD_PULL_GET(x)
+#define GPIO_PIN22_PAD_PULL_SET(x) WLAN_GPIO_PIN22_PAD_PULL_SET(x)
+#define GPIO_PIN22_PAD_STRENGTH_MSB WLAN_GPIO_PIN22_PAD_STRENGTH_MSB
+#define GPIO_PIN22_PAD_STRENGTH_LSB WLAN_GPIO_PIN22_PAD_STRENGTH_LSB
+#define GPIO_PIN22_PAD_STRENGTH_MASK WLAN_GPIO_PIN22_PAD_STRENGTH_MASK
+#define GPIO_PIN22_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN22_PAD_STRENGTH_GET(x)
+#define GPIO_PIN22_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN22_PAD_STRENGTH_SET(x)
+#define GPIO_PIN22_PAD_DRIVER_MSB WLAN_GPIO_PIN22_PAD_DRIVER_MSB
+#define GPIO_PIN22_PAD_DRIVER_LSB WLAN_GPIO_PIN22_PAD_DRIVER_LSB
+#define GPIO_PIN22_PAD_DRIVER_MASK WLAN_GPIO_PIN22_PAD_DRIVER_MASK
+#define GPIO_PIN22_PAD_DRIVER_GET(x) WLAN_GPIO_PIN22_PAD_DRIVER_GET(x)
+#define GPIO_PIN22_PAD_DRIVER_SET(x) WLAN_GPIO_PIN22_PAD_DRIVER_SET(x)
+#define GPIO_PIN22_SOURCE_MSB WLAN_GPIO_PIN22_SOURCE_MSB
+#define GPIO_PIN22_SOURCE_LSB WLAN_GPIO_PIN22_SOURCE_LSB
+#define GPIO_PIN22_SOURCE_MASK WLAN_GPIO_PIN22_SOURCE_MASK
+#define GPIO_PIN22_SOURCE_GET(x) WLAN_GPIO_PIN22_SOURCE_GET(x)
+#define GPIO_PIN22_SOURCE_SET(x) WLAN_GPIO_PIN22_SOURCE_SET(x)
+#define GPIO_PIN23_ADDRESS WLAN_GPIO_PIN23_ADDRESS
+#define GPIO_PIN23_OFFSET WLAN_GPIO_PIN23_OFFSET
+#define GPIO_PIN23_CONFIG_MSB WLAN_GPIO_PIN23_CONFIG_MSB
+#define GPIO_PIN23_CONFIG_LSB WLAN_GPIO_PIN23_CONFIG_LSB
+#define GPIO_PIN23_CONFIG_MASK WLAN_GPIO_PIN23_CONFIG_MASK
+#define GPIO_PIN23_CONFIG_GET(x) WLAN_GPIO_PIN23_CONFIG_GET(x)
+#define GPIO_PIN23_CONFIG_SET(x) WLAN_GPIO_PIN23_CONFIG_SET(x)
+#define GPIO_PIN23_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN23_WAKEUP_ENABLE_MSB
+#define GPIO_PIN23_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB
+#define GPIO_PIN23_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK
+#define GPIO_PIN23_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN23_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN23_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN23_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN23_INT_TYPE_MSB WLAN_GPIO_PIN23_INT_TYPE_MSB
+#define GPIO_PIN23_INT_TYPE_LSB WLAN_GPIO_PIN23_INT_TYPE_LSB
+#define GPIO_PIN23_INT_TYPE_MASK WLAN_GPIO_PIN23_INT_TYPE_MASK
+#define GPIO_PIN23_INT_TYPE_GET(x) WLAN_GPIO_PIN23_INT_TYPE_GET(x)
+#define GPIO_PIN23_INT_TYPE_SET(x) WLAN_GPIO_PIN23_INT_TYPE_SET(x)
+#define GPIO_PIN23_PAD_DRIVER_MSB WLAN_GPIO_PIN23_PAD_DRIVER_MSB
+#define GPIO_PIN23_PAD_DRIVER_LSB WLAN_GPIO_PIN23_PAD_DRIVER_LSB
+#define GPIO_PIN23_PAD_DRIVER_MASK WLAN_GPIO_PIN23_PAD_DRIVER_MASK
+#define GPIO_PIN23_PAD_DRIVER_GET(x) WLAN_GPIO_PIN23_PAD_DRIVER_GET(x)
+#define GPIO_PIN23_PAD_DRIVER_SET(x) WLAN_GPIO_PIN23_PAD_DRIVER_SET(x)
+#define GPIO_PIN23_SOURCE_MSB WLAN_GPIO_PIN23_SOURCE_MSB
+#define GPIO_PIN23_SOURCE_LSB WLAN_GPIO_PIN23_SOURCE_LSB
+#define GPIO_PIN23_SOURCE_MASK WLAN_GPIO_PIN23_SOURCE_MASK
+#define GPIO_PIN23_SOURCE_GET(x) WLAN_GPIO_PIN23_SOURCE_GET(x)
+#define GPIO_PIN23_SOURCE_SET(x) WLAN_GPIO_PIN23_SOURCE_SET(x)
+#define GPIO_PIN24_ADDRESS WLAN_GPIO_PIN24_ADDRESS
+#define GPIO_PIN24_OFFSET WLAN_GPIO_PIN24_OFFSET
+#define GPIO_PIN24_CONFIG_MSB WLAN_GPIO_PIN24_CONFIG_MSB
+#define GPIO_PIN24_CONFIG_LSB WLAN_GPIO_PIN24_CONFIG_LSB
+#define GPIO_PIN24_CONFIG_MASK WLAN_GPIO_PIN24_CONFIG_MASK
+#define GPIO_PIN24_CONFIG_GET(x) WLAN_GPIO_PIN24_CONFIG_GET(x)
+#define GPIO_PIN24_CONFIG_SET(x) WLAN_GPIO_PIN24_CONFIG_SET(x)
+#define GPIO_PIN24_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN24_WAKEUP_ENABLE_MSB
+#define GPIO_PIN24_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB
+#define GPIO_PIN24_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK
+#define GPIO_PIN24_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN24_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN24_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN24_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN24_INT_TYPE_MSB WLAN_GPIO_PIN24_INT_TYPE_MSB
+#define GPIO_PIN24_INT_TYPE_LSB WLAN_GPIO_PIN24_INT_TYPE_LSB
+#define GPIO_PIN24_INT_TYPE_MASK WLAN_GPIO_PIN24_INT_TYPE_MASK
+#define GPIO_PIN24_INT_TYPE_GET(x) WLAN_GPIO_PIN24_INT_TYPE_GET(x)
+#define GPIO_PIN24_INT_TYPE_SET(x) WLAN_GPIO_PIN24_INT_TYPE_SET(x)
+#define GPIO_PIN24_PAD_DRIVER_MSB WLAN_GPIO_PIN24_PAD_DRIVER_MSB
+#define GPIO_PIN24_PAD_DRIVER_LSB WLAN_GPIO_PIN24_PAD_DRIVER_LSB
+#define GPIO_PIN24_PAD_DRIVER_MASK WLAN_GPIO_PIN24_PAD_DRIVER_MASK
+#define GPIO_PIN24_PAD_DRIVER_GET(x) WLAN_GPIO_PIN24_PAD_DRIVER_GET(x)
+#define GPIO_PIN24_PAD_DRIVER_SET(x) WLAN_GPIO_PIN24_PAD_DRIVER_SET(x)
+#define GPIO_PIN24_SOURCE_MSB WLAN_GPIO_PIN24_SOURCE_MSB
+#define GPIO_PIN24_SOURCE_LSB WLAN_GPIO_PIN24_SOURCE_LSB
+#define GPIO_PIN24_SOURCE_MASK WLAN_GPIO_PIN24_SOURCE_MASK
+#define GPIO_PIN24_SOURCE_GET(x) WLAN_GPIO_PIN24_SOURCE_GET(x)
+#define GPIO_PIN24_SOURCE_SET(x) WLAN_GPIO_PIN24_SOURCE_SET(x)
+#define GPIO_PIN25_ADDRESS WLAN_GPIO_PIN25_ADDRESS
+#define GPIO_PIN25_OFFSET WLAN_GPIO_PIN25_OFFSET
+#define GPIO_PIN25_CONFIG_MSB WLAN_GPIO_PIN25_CONFIG_MSB
+#define GPIO_PIN25_CONFIG_LSB WLAN_GPIO_PIN25_CONFIG_LSB
+#define GPIO_PIN25_CONFIG_MASK WLAN_GPIO_PIN25_CONFIG_MASK
+#define GPIO_PIN25_CONFIG_GET(x) WLAN_GPIO_PIN25_CONFIG_GET(x)
+#define GPIO_PIN25_CONFIG_SET(x) WLAN_GPIO_PIN25_CONFIG_SET(x)
+#define GPIO_PIN25_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN25_WAKEUP_ENABLE_MSB
+#define GPIO_PIN25_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB
+#define GPIO_PIN25_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK
+#define GPIO_PIN25_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN25_WAKEUP_ENABLE_GET(x)
+#define GPIO_PIN25_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN25_WAKEUP_ENABLE_SET(x)
+#define GPIO_PIN25_INT_TYPE_MSB WLAN_GPIO_PIN25_INT_TYPE_MSB
+#define GPIO_PIN25_INT_TYPE_LSB WLAN_GPIO_PIN25_INT_TYPE_LSB
+#define GPIO_PIN25_INT_TYPE_MASK WLAN_GPIO_PIN25_INT_TYPE_MASK
+#define GPIO_PIN25_INT_TYPE_GET(x) WLAN_GPIO_PIN25_INT_TYPE_GET(x)
+#define GPIO_PIN25_INT_TYPE_SET(x) WLAN_GPIO_PIN25_INT_TYPE_SET(x)
+#define GPIO_PIN25_PAD_DRIVER_MSB WLAN_GPIO_PIN25_PAD_DRIVER_MSB
+#define GPIO_PIN25_PAD_DRIVER_LSB WLAN_GPIO_PIN25_PAD_DRIVER_LSB
+#define GPIO_PIN25_PAD_DRIVER_MASK WLAN_GPIO_PIN25_PAD_DRIVER_MASK
+#define GPIO_PIN25_PAD_DRIVER_GET(x) WLAN_GPIO_PIN25_PAD_DRIVER_GET(x)
+#define GPIO_PIN25_PAD_DRIVER_SET(x) WLAN_GPIO_PIN25_PAD_DRIVER_SET(x)
+#define GPIO_PIN25_SOURCE_MSB WLAN_GPIO_PIN25_SOURCE_MSB
+#define GPIO_PIN25_SOURCE_LSB WLAN_GPIO_PIN25_SOURCE_LSB
+#define GPIO_PIN25_SOURCE_MASK WLAN_GPIO_PIN25_SOURCE_MASK
+#define GPIO_PIN25_SOURCE_GET(x) WLAN_GPIO_PIN25_SOURCE_GET(x)
+#define GPIO_PIN25_SOURCE_SET(x) WLAN_GPIO_PIN25_SOURCE_SET(x)
+#define SIGMA_DELTA_ADDRESS WLAN_SIGMA_DELTA_ADDRESS
+#define SIGMA_DELTA_OFFSET WLAN_SIGMA_DELTA_OFFSET
+#define SIGMA_DELTA_ENABLE_MSB WLAN_SIGMA_DELTA_ENABLE_MSB
+#define SIGMA_DELTA_ENABLE_LSB WLAN_SIGMA_DELTA_ENABLE_LSB
+#define SIGMA_DELTA_ENABLE_MASK WLAN_SIGMA_DELTA_ENABLE_MASK
+#define SIGMA_DELTA_ENABLE_GET(x) WLAN_SIGMA_DELTA_ENABLE_GET(x)
+#define SIGMA_DELTA_ENABLE_SET(x) WLAN_SIGMA_DELTA_ENABLE_SET(x)
+#define SIGMA_DELTA_PRESCALAR_MSB WLAN_SIGMA_DELTA_PRESCALAR_MSB
+#define SIGMA_DELTA_PRESCALAR_LSB WLAN_SIGMA_DELTA_PRESCALAR_LSB
+#define SIGMA_DELTA_PRESCALAR_MASK WLAN_SIGMA_DELTA_PRESCALAR_MASK
+#define SIGMA_DELTA_PRESCALAR_GET(x) WLAN_SIGMA_DELTA_PRESCALAR_GET(x)
+#define SIGMA_DELTA_PRESCALAR_SET(x) WLAN_SIGMA_DELTA_PRESCALAR_SET(x)
+#define SIGMA_DELTA_TARGET_MSB WLAN_SIGMA_DELTA_TARGET_MSB
+#define SIGMA_DELTA_TARGET_LSB WLAN_SIGMA_DELTA_TARGET_LSB
+#define SIGMA_DELTA_TARGET_MASK WLAN_SIGMA_DELTA_TARGET_MASK
+#define SIGMA_DELTA_TARGET_GET(x) WLAN_SIGMA_DELTA_TARGET_GET(x)
+#define SIGMA_DELTA_TARGET_SET(x) WLAN_SIGMA_DELTA_TARGET_SET(x)
+#define DEBUG_CONTROL_ADDRESS WLAN_DEBUG_CONTROL_ADDRESS
+#define DEBUG_CONTROL_OFFSET WLAN_DEBUG_CONTROL_OFFSET
+#define DEBUG_CONTROL_ENABLE_MSB WLAN_DEBUG_CONTROL_ENABLE_MSB
+#define DEBUG_CONTROL_ENABLE_LSB WLAN_DEBUG_CONTROL_ENABLE_LSB
+#define DEBUG_CONTROL_ENABLE_MASK WLAN_DEBUG_CONTROL_ENABLE_MASK
+#define DEBUG_CONTROL_ENABLE_GET(x) WLAN_DEBUG_CONTROL_ENABLE_GET(x)
+#define DEBUG_CONTROL_ENABLE_SET(x) WLAN_DEBUG_CONTROL_ENABLE_SET(x)
+#define DEBUG_INPUT_SEL_ADDRESS WLAN_DEBUG_INPUT_SEL_ADDRESS
+#define DEBUG_INPUT_SEL_OFFSET WLAN_DEBUG_INPUT_SEL_OFFSET
+#define DEBUG_INPUT_SEL_SHIFT_MSB WLAN_DEBUG_INPUT_SEL_SHIFT_MSB
+#define DEBUG_INPUT_SEL_SHIFT_LSB WLAN_DEBUG_INPUT_SEL_SHIFT_LSB
+#define DEBUG_INPUT_SEL_SHIFT_MASK WLAN_DEBUG_INPUT_SEL_SHIFT_MASK
+#define DEBUG_INPUT_SEL_SHIFT_GET(x) WLAN_DEBUG_INPUT_SEL_SHIFT_GET(x)
+#define DEBUG_INPUT_SEL_SHIFT_SET(x) WLAN_DEBUG_INPUT_SEL_SHIFT_SET(x)
+#define DEBUG_INPUT_SEL_SRC_MSB WLAN_DEBUG_INPUT_SEL_SRC_MSB
+#define DEBUG_INPUT_SEL_SRC_LSB WLAN_DEBUG_INPUT_SEL_SRC_LSB
+#define DEBUG_INPUT_SEL_SRC_MASK WLAN_DEBUG_INPUT_SEL_SRC_MASK
+#define DEBUG_INPUT_SEL_SRC_GET(x) WLAN_DEBUG_INPUT_SEL_SRC_GET(x)
+#define DEBUG_INPUT_SEL_SRC_SET(x) WLAN_DEBUG_INPUT_SEL_SRC_SET(x)
+#define DEBUG_OUT_ADDRESS WLAN_DEBUG_OUT_ADDRESS
+#define DEBUG_OUT_OFFSET WLAN_DEBUG_OUT_OFFSET
+#define DEBUG_OUT_DATA_MSB WLAN_DEBUG_OUT_DATA_MSB
+#define DEBUG_OUT_DATA_LSB WLAN_DEBUG_OUT_DATA_LSB
+#define DEBUG_OUT_DATA_MASK WLAN_DEBUG_OUT_DATA_MASK
+#define DEBUG_OUT_DATA_GET(x) WLAN_DEBUG_OUT_DATA_GET(x)
+#define DEBUG_OUT_DATA_SET(x) WLAN_DEBUG_OUT_DATA_SET(x)
+#define RESET_TUPLE_STATUS_ADDRESS WLAN_RESET_TUPLE_STATUS_ADDRESS
+#define RESET_TUPLE_STATUS_OFFSET WLAN_RESET_TUPLE_STATUS_OFFSET
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x)
+#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x)
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x)
+#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x)
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h
new file mode 100644
index 000000000000..f82f809171a0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h
@@ -0,0 +1,605 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2002-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+/*****************************************************************************/
+/* AR6003 WLAN MAC DMA register definitions */
+/*****************************************************************************/
+
+#ifndef _AR6000_DMAREG_H_
+#define _AR6000_DMAREG_H_
+
+/*
+ * Definitions for the Atheros AR6003 chipset.
+ */
+
+/* DMA Control and Interrupt Registers */
+#define MAC_DMA_CR_ADDRESS 0x00000008 /* MAC control register */
+#define MAC_DMA_CR_RXE_MASK 0x00000004 /* Receive enable */
+#define MAC_DMA_CR_RXD_MASK 0x00000020 /* Receive disable */
+#define MAC_DMA_CR_SWI_MASK 0x00000040 /* One-shot software interrupt */
+
+#define MAC_DMA_RXDP_ADDRESS 0x0000000C /* MAC receive queue descriptor pointer */
+
+#define MAC_DMA_CFG_ADDRESS 0x00000014 /* MAC configuration and status register */
+#define MAC_DMA_CFG_SWTD_MASK 0x00000001 /* byteswap tx descriptor words */
+#define MAC_DMA_CFG_SWTB_MASK 0x00000002 /* byteswap tx data buffer words */
+#define MAC_DMA_CFG_SWRD_MASK 0x00000004 /* byteswap rx descriptor words */
+#define MAC_DMA_CFG_SWRB_MASK 0x00000008 /* byteswap rx data buffer words */
+#define MAC_DMA_CFG_SWRG_MASK 0x00000010 /* byteswap register access data words */
+#define MAC_DMA_CFG_AP_ADHOC_INDICATION_MASK 0x00000020 /* AP/adhoc indication (0-AP, 1-Adhoc) */
+#define MAC_DMA_CFG_PHOK_MASK 0x00000100 /* PHY OK status */
+#define MAC_DMA_CFG_CLK_GATE_DIS_MASK 0x00000400 /* Clock gating disable */
+
+#define MAC_DMA_MIRT_ADDRESS 0x00000020 /* Maximum rate threshold register */
+#define MAC_DMA_MIRT_THRESH_MASK 0x0000FFFF
+
+#define MAC_DMA_IER_ADDRESS 0x00000024 /* MAC Interrupt enable register */
+#define MAC_DMA_IER_ENABLE_MASK 0x00000001 /* Global interrupt enable */
+#define MAC_DMA_IER_DISABLE_MASK 0x00000000 /* Global interrupt disable */
+
+#define MAC_DMA_TIMT_ADDRESS 0x00000028 /* Transmit Interrupt Mitigation Threshold */
+#define MAC_DMA_TIMT_LAST_PACKER_THRESH_MASK 0x0000FFFF /* Last packet threshold mask */
+#define MAC_DMA_TIMT_FIRST_PACKER_THRESH_MASK 0xFFFF0000 /* First packet threshold mask */
+
+#define MAC_DMA_RIMT_ADDRESS 0x0000002C /* Receive Interrupt Mitigation Threshold */
+#define MAC_DMA_RIMT_LAST_PACKER_THRESH_MASK 0x0000FFFF /* Last packet threshold mask */
+#define MAC_DMA_RIMT_FIRST_PACKER_THRESH_MASK 0xFFFF0000 /* First packet threshold mask */
+
+#define MAC_DMA_TXCFG_ADDRESS 0x00000030 /* MAC tx DMA size config register */
+#define MAC_DMA_FTRIG_MASK 0x000003F0 /* Mask for Frame trigger level */
+#define MAC_DMA_FTRIG_LSB 4 /* Shift for Frame trigger level */
+#define MAC_DMA_FTRIG_IMMED 0x00000000 /* bytes in PCU TX FIFO before air */
+#define MAC_DMA_FTRIG_64B 0x00000010 /* default */
+#define MAC_DMA_FTRIG_128B 0x00000020
+#define MAC_DMA_FTRIG_192B 0x00000030
+#define MAC_DMA_FTRIG_256B 0x00000040 /* 5 bits total */
+#define MAC_DMA_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY_MASK 0x00000800
+
+#define MAC_DMA_RXCFG_ADDRESS 0x00000034 /* MAC rx DMA size config register */
+#define MAC_DMA_RXCFG_ZLFDMA_MASK 0x00000010 /* Enable DMA of zero-length frame */
+#define MAC_DMA_RXCFG_DMASIZE_4B 0x00000000 /* DMA size 4 bytes (TXCFG + RXCFG) */
+#define MAC_DMA_RXCFG_DMASIZE_8B 0x00000001 /* DMA size 8 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_16B 0x00000002 /* DMA size 16 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_32B 0x00000003 /* DMA size 32 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_64B 0x00000004 /* DMA size 64 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_128B 0x00000005 /* DMA size 128 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_256B 0x00000006 /* DMA size 256 bytes */
+#define MAC_DMA_RXCFG_DMASIZE_512B 0x00000007 /* DMA size 512 bytes */
+
+#define MAC_DMA_MIBC_ADDRESS 0x00000040 /* MAC MIB control register */
+#define MAC_DMA_MIBC_COW_MASK 0x00000001 /* counter overflow warning */
+#define MAC_DMA_MIBC_FMC_MASK 0x00000002 /* freeze MIB counters */
+#define MAC_DMA_MIBC_CMC_MASK 0x00000004 /* clear MIB counters */
+#define MAC_DMA_MIBC_MCS_MASK 0x00000008 /* MIB counter strobe, increment all */
+
+#define MAC_DMA_TOPS_ADDRESS 0x00000044 /* MAC timeout prescale count */
+#define MAC_DMA_TOPS_MASK 0x0000FFFF /* Mask for timeout prescale */
+
+#define MAC_DMA_RXNPTO_ADDRESS 0x00000048 /* MAC no frame received timeout */
+#define MAC_DMA_RXNPTO_MASK 0x000003FF /* Mask for no frame received timeout */
+
+#define MAC_DMA_TXNPTO_ADDRESS 0x0000004C /* MAC no frame trasmitted timeout */
+#define MAC_DMA_TXNPTO_MASK 0x000003FF /* Mask for no frame transmitted timeout */
+#define MAC_DMA_TXNPTO_QCU_MASK 0x000FFC00 /* Mask indicating the set of QCUs */
+ /* for which frame completions will cause */
+ /* a reset of the no frame xmit'd timeout */
+
+#define MAC_DMA_RPGTO_ADDRESS 0x00000050 /* MAC receive frame gap timeout */
+#define MAC_DMA_RPGTO_MASK 0x000003FF /* Mask for receive frame gap timeout */
+
+#define MAC_DMA_RPCNT_ADDRESS 0x00000054 /* MAC receive frame count limit */
+#define MAC_DMA_RPCNT_MASK 0x0000001F /* Mask for receive frame count limit */
+
+#define MAC_DMA_MACMISC_ADDRESS 0x00000058 /* MAC miscellaneous control/status register */
+#define MAC_DMA_MACMISC_DMA_OBS_MASK 0x000001E0 /* Mask for DMA observation bus mux select */
+#define MAC_DMA_MACMISC_DMA_OBS_LSB 5 /* Shift for DMA observation bus mux select */
+#define MAC_DMA_MACMISC_MISC_OBS 0x00000E00 /* Mask for MISC observation bus mux select */
+#define MAC_DMA_MACMISC_MISC_OBS_LSB 9 /* Shift for MISC observation bus mux select */
+#define MAC_DMA_MACMISC_MAC_OBS_BUS_LSB 0x00007000 /* Mask for MAC observation bus mux select (lsb) */
+#define MAC_DMA_MACMISC_MAC_OBS_BUS_LSB_LSB 12 /* Shift for MAC observation bus mux select (lsb) */
+#define MAC_DMA_MACMISC_MAC_OBS_BUS_MSB 0x00038000 /* Mask for MAC observation bus mux select (msb) */
+#define MAC_DMA_MACMISC_MAC_OBS_BUS_MSB_LSB 15 /* Shift for MAC observation bus mux select (msb) */
+
+
+#define MAC_DMA_ISR_ADDRESS 0x00000080 /* MAC Primary interrupt status register */
+/*
+ * Interrupt Status Registers
+ *
+ * Only the bits in the ISR_P register and the IMR_P registers
+ * control whether the MAC's INTA# output is asserted. The bits in
+ * the secondary interrupt status/mask registers control what bits
+ * are set in the primary interrupt status register; however the
+ * IMR_S* registers DO NOT determine whether INTA# is asserted.
+ * That is INTA# is asserted only when the logical AND of ISR_P
+ * and IMR_P is non-zero. The secondary interrupt mask/status
+ * registers affect what bits are set in ISR_P but they do not
+ * directly affect whether INTA# is asserted.
+ */
+#define MAC_DMA_ISR_RXOK_MASK 0x00000001 /* At least one frame received sans errors */
+#define MAC_DMA_ISR_RXDESC_MASK 0x00000002 /* Receive interrupt request */
+#define MAC_DMA_ISR_RXERR_MASK 0x00000004 /* Receive error interrupt */
+#define MAC_DMA_ISR_RXNOPKT_MASK 0x00000008 /* No frame received within timeout clock */
+#define MAC_DMA_ISR_RXEOL_MASK 0x00000010 /* Received descriptor empty interrupt */
+#define MAC_DMA_ISR_RXORN_MASK 0x00000020 /* Receive FIFO overrun interrupt */
+#define MAC_DMA_ISR_TXOK_MASK 0x00000040 /* Transmit okay interrupt */
+#define MAC_DMA_ISR_TXDESC_MASK 0x00000080 /* Transmit interrupt request */
+#define MAC_DMA_ISR_TXERR_MASK 0x00000100 /* Transmit error interrupt */
+#define MAC_DMA_ISR_TXNOPKT_MASK 0x00000200 /* No frame transmitted interrupt */
+#define MAC_DMA_ISR_TXEOL_MASK 0x00000400 /* Transmit descriptor empty interrupt */
+#define MAC_DMA_ISR_TXURN_MASK 0x00000800 /* Transmit FIFO underrun interrupt */
+#define MAC_DMA_ISR_MIB_MASK 0x00001000 /* MIB interrupt - see MIBC */
+#define MAC_DMA_ISR_SWI_MASK 0x00002000 /* Software interrupt */
+#define MAC_DMA_ISR_RXPHY_MASK 0x00004000 /* PHY receive error interrupt */
+#define MAC_DMA_ISR_RXKCM_MASK 0x00008000 /* Key-cache miss interrupt */
+#define MAC_DMA_ISR_BRSSI_HI_MASK 0x00010000 /* Beacon rssi high threshold interrupt */
+#define MAC_DMA_ISR_BRSSI_LO_MASK 0x00020000 /* Beacon threshold interrupt */
+#define MAC_DMA_ISR_BMISS_MASK 0x00040000 /* Beacon missed interrupt */
+#define MAC_DMA_ISR_TXMINTR_MASK 0x00080000 /* Maximum transmit interrupt rate */
+#define MAC_DMA_ISR_BNR_MASK 0x00100000 /* Beacon not ready interrupt */
+#define MAC_DMA_ISR_HIUERR_MASK 0x00200000 /* An unexpected bus error has occurred */
+#define MAC_DMA_ISR_BCNMISC_MASK 0x00800000 /* 'or' of TIM, CABEND, DTIMSYNC, BCNTO */
+#define MAC_DMA_ISR_RXMINTR_MASK 0x01000000 /* Maximum receive interrupt rate */
+#define MAC_DMA_ISR_QCBROVF_MASK 0x02000000 /* QCU CBR overflow interrupt */
+#define MAC_DMA_ISR_QCBRURN_MASK 0x04000000 /* QCU CBR underrun interrupt */
+#define MAC_DMA_ISR_QTRIG_MASK 0x08000000 /* QCU scheduling trigger interrupt */
+#define MAC_DMA_ISR_TIMER_MASK 0x10000000 /* GENTMR interrupt */
+#define MAC_DMA_ISR_HCFTO_MASK 0x20000000 /* HCFTO interrupt */
+#define MAC_DMA_ISR_TXINTM_MASK 0x40000000 /* Transmit completion mitigation interrupt */
+#define MAC_DMA_ISR_RXINTM_MASK 0x80000000 /* Receive completion mitigation interrupt */
+
+#define MAC_DMA_ISR_S0_ADDRESS 0x00000084 /* MAC Secondary interrupt status register 0 */
+#define MAC_DMA_ISR_S0_QCU_TXOK_MASK 0x000003FF /* Mask for TXOK (QCU 0-9) */
+#define MAC_DMA_ISR_S0_QCU_TXOK_LSB 0
+#define MAC_DMA_ISR_S0_QCU_TXDESC_MASK 0x03FF0000 /* Mask for TXDESC (QCU 0-9) */
+#define MAC_DMA_ISR_S0_QCU_TXDESC_LSB 16
+
+#define MAC_DMA_ISR_S1_ADDRESS 0x00000088 /* MAC Secondary interrupt status register 1 */
+#define MAC_DMA_ISR_S1_QCU_TXERR_MASK 0x000003FF /* Mask for TXERR (QCU 0-9) */
+#define MAC_DMA_ISR_S1_QCU_TXERR_LSB 0
+#define MAC_DMA_ISR_S1_QCU_TXEOL_MASK 0x03FF0000 /* Mask for TXEOL (QCU 0-9) */
+#define MAC_DMA_ISR_S1_QCU_TXEOL_LSB 16
+
+#define MAC_DMA_ISR_S2_ADDRESS 0x0000008c /* MAC Secondary interrupt status register 2 */
+#define MAC_DMA_ISR_S2_QCU_TXURN_MASK 0x000003FF /* Mask for TXURN (QCU 0-9) */
+#define MAC_DMA_ISR_S2_QCU_TXURN_LSB 0 /* Shift for TXURN (QCU 0-9) */
+#define MAC_DMA_ISR_S2_RX_INT_MASK 0x00000800
+#define MAC_DMA_ISR_S2_WL_STOMPED_MASK 0x00001000
+#define MAC_DMA_ISR_S2_RX_PTR_BAD_MASK 0x00002000
+#define MAC_DMA_ISR_S2_BT_LOW_PRIORITY_RISING_MASK 0x00004000
+#define MAC_DMA_ISR_S2_BT_LOW_PRIORITY_FALLING_MASK 0x00008000
+#define MAC_DMA_ISR_S2_BB_PANIC_IRQ_MASK 0x00010000
+#define MAC_DMA_ISR_S2_BT_STOMPED_MASK 0x00020000
+#define MAC_DMA_ISR_S2_BT_ACTIVE_RISING_MASK 0x00040000
+#define MAC_DMA_ISR_S2_BT_ACTIVE_FALLING_MASK 0x00080000
+#define MAC_DMA_ISR_S2_BT_PRIORITY_RISING_MASK 0x00100000
+#define MAC_DMA_ISR_S2_BT_PRIORITY_FALLING_MASK 0x00200000
+#define MAC_DMA_ISR_S2_CST_MASK 0x00400000
+#define MAC_DMA_ISR_S2_GTT_MASK 0x00800000
+#define MAC_DMA_ISR_S2_TIM_MASK 0x01000000 /* TIM */
+#define MAC_DMA_ISR_S2_CABEND_MASK 0x02000000 /* CABEND */
+#define MAC_DMA_ISR_S2_DTIMSYNC_MASK 0x04000000 /* DTIMSYNC */
+#define MAC_DMA_ISR_S2_BCNTO_MASK 0x08000000 /* BCNTO */
+#define MAC_DMA_ISR_S2_CABTO_MASK 0x10000000 /* CABTO */
+#define MAC_DMA_ISR_S2_DTIM_MASK 0x20000000 /* DTIM */
+#define MAC_DMA_ISR_S2_TSFOOR_MASK 0x40000000 /* TSFOOR */
+
+#define MAC_DMA_ISR_S3_ADDRESS 0x00000090 /* MAC Secondary interrupt status register 3 */
+#define MAC_DMA_ISR_S3_QCU_QCBROVF_MASK 0x000003FF /* Mask for QCBROVF (QCU 0-9) */
+#define MAC_DMA_ISR_S3_QCU_QCBRURN_MASK 0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */
+
+#define MAC_DMA_ISR_S4_ADDRESS 0x00000094 /* MAC Secondary interrupt status register 4 */
+#define MAC_DMA_ISR_S4_QCU_QTRIG_MASK 0x000003FF /* Mask for QTRIG (QCU 0-9) */
+
+#define MAC_DMA_ISR_S5_ADDRESS 0x00000098 /* MAC Secondary interrupt status register 5 */
+#define MAC_DMA_ISR_S5_TBTT_TIMER_TRIGGER_MASK 0x00000001
+#define MAC_DMA_ISR_S5_DBA_TIMER_TRIGGER_MASK 0x00000002
+#define MAC_DMA_ISR_S5_SBA_TIMER_TRIGGER_MASK 0x00000004
+#define MAC_DMA_ISR_S5_HCF_TIMER_TRIGGER_MASK 0x00000008
+#define MAC_DMA_ISR_S5_TIM_TIMER_TRIGGER_MASK 0x00000010
+#define MAC_DMA_ISR_S5_DTIM_TIMER_TRIGGER_MASK 0x00000020
+#define MAC_DMA_ISR_S5_QUIET_TIMER_TRIGGER_MASK 0x00000040
+#define MAC_DMA_ISR_S5_NDP_TIMER_TRIGGER_MASK 0x00000080
+#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER_MASK 0x0000FF00
+#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER_LSB 8
+#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER(_i) (0x00000100 << (_i))
+#define MAC_DMA_ISR_S5_TIMER_OVERFLOW_MASK 0x00010000
+#define MAC_DMA_ISR_S5_DBA_TIMER_THRESHOLD_MASK 0x00020000
+#define MAC_DMA_ISR_S5_SBA_TIMER_THRESHOLD_MASK 0x00040000
+#define MAC_DMA_ISR_S5_HCF_TIMER_THRESHOLD_MASK 0x00080000
+#define MAC_DMA_ISR_S5_TIM_TIMER_THRESHOLD_MASK 0x00100000
+#define MAC_DMA_ISR_S5_DTIM_TIMER_THRESHOLD_MASK 0x00200000
+#define MAC_DMA_ISR_S5_QUIET_TIMER_THRESHOLD_MASK 0x00400000
+#define MAC_DMA_ISR_S5_NDP_TIMER_THRESHOLD_MASK 0x00800000
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_MASK 0xFF000000
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_LSB 24
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD(_i) (0x01000000 << (_i))
+
+#define MAC_DMA_IMR_ADDRESS 0x000000A0 /* MAC Primary interrupt mask register */
+/*
+ * Interrupt Mask Registers
+ *
+ * Only the bits in the IMR control whether the MAC's INTA#
+ * output will be asserted. The bits in the secondary interrupt
+ * mask registers control what bits get set in the primary
+ * interrupt status register; however the IMR_S* registers
+ * DO NOT determine whether INTA# is asserted.
+ */
+#define MAC_DMA_IMR_RXOK_MASK 0x00000001 /* At least one frame received sans errors */
+#define MAC_DMA_IMR_RXDESC_MASK 0x00000002 /* Receive interrupt request */
+#define MAC_DMA_IMR_RXERR_MASK 0x00000004 /* Receive error interrupt */
+#define MAC_DMA_IMR_RXNOPKT_MASK 0x00000008 /* No frame received within timeout clock */
+#define MAC_DMA_IMR_RXEOL_MASK 0x00000010 /* Received descriptor empty interrupt */
+#define MAC_DMA_IMR_RXORN_MASK 0x00000020 /* Receive FIFO overrun interrupt */
+#define MAC_DMA_IMR_TXOK_MASK 0x00000040 /* Transmit okay interrupt */
+#define MAC_DMA_IMR_TXDESC_MASK 0x00000080 /* Transmit interrupt request */
+#define MAC_DMA_IMR_TXERR_MASK 0x00000100 /* Transmit error interrupt */
+#define MAC_DMA_IMR_TXNOPKT_MASK 0x00000200 /* No frame transmitted interrupt */
+#define MAC_DMA_IMR_TXEOL_MASK 0x00000400 /* Transmit descriptor empty interrupt */
+#define MAC_DMA_IMR_TXURN_MASK 0x00000800 /* Transmit FIFO underrun interrupt */
+#define MAC_DMA_IMR_MIB_MASK 0x00001000 /* MIB interrupt - see MIBC */
+#define MAC_DMA_IMR_SWI_MASK 0x00002000 /* Software interrupt */
+#define MAC_DMA_IMR_RXPHY_MASK 0x00004000 /* PHY receive error interrupt */
+#define MAC_DMA_IMR_RXKCM_MASK 0x00008000 /* Key-cache miss interrupt */
+#define MAC_DMA_IMR_BRSSI_HI_MASK 0x00010000 /* Beacon rssi hi threshold interrupt */
+#define MAC_DMA_IMR_BRSSI_LO_MASK 0x00020000 /* Beacon rssi lo threshold interrupt */
+#define MAC_DMA_IMR_BMISS_MASK 0x00040000 /* Beacon missed interrupt */
+#define MAC_DMA_IMR_TXMINTR_MASK 0x00080000 /* Maximum transmit interrupt rate */
+#define MAC_DMA_IMR_BNR_MASK 0x00100000 /* BNR interrupt */
+#define MAC_DMA_IMR_HIUERR_MASK 0x00200000 /* An unexpected bus error has occurred */
+#define MAC_DMA_IMR_BCNMISC_MASK 0x00800000 /* Beacon Misc */
+#define MAC_DMA_IMR_RXMINTR_MASK 0x01000000 /* Maximum receive interrupt rate */
+#define MAC_DMA_IMR_QCBROVF_MASK 0x02000000 /* QCU CBR overflow interrupt */
+#define MAC_DMA_IMR_QCBRURN_MASK 0x04000000 /* QCU CBR underrun interrupt */
+#define MAC_DMA_IMR_QTRIG_MASK 0x08000000 /* QCU scheduling trigger interrupt */
+#define MAC_DMA_IMR_TIMER_MASK 0x10000000 /* GENTMR interrupt */
+#define MAC_DMA_IMR_HCFTO_MASK 0x20000000 /* HCFTO interrupt*/
+#define MAC_DMA_IMR_TXINTM_MASK 0x40000000 /* Transmit completion mitigation interrupt */
+#define MAC_DMA_IMR_RXINTM_MASK 0x80000000 /* Receive completion mitigation interrupt */
+
+#define MAC_DMA_IMR_S0_ADDRESS 0x000000A4 /* MAC Secondary interrupt mask register 0 */
+#define MAC_DMA_IMR_S0_QCU_TXOK_MASK 0x000003FF /* TXOK (QCU 0-9) */
+#define MAC_DMA_IMR_S0_QCU_TXOK_LSB 0
+#define MAC_DMA_IMR_S0_QCU_TXDESC_MASK 0x03FF0000 /* TXDESC (QCU 0-9) */
+#define MAC_DMA_IMR_S0_QCU_TXDESC_LSB 16
+
+#define MAC_DMA_IMR_S1_ADDRESS 0x000000A8 /* MAC Secondary interrupt mask register 1 */
+#define MAC_DMA_IMR_S1_QCU_TXERR_MASK 0x000003FF /* TXERR (QCU 0-9) */
+#define MAC_DMA_IMR_S1_QCU_TXERR_LSB 0
+#define MAC_DMA_IMR_S1_QCU_TXEOL_MASK 0x03FF0000 /* TXEOL (QCU 0-9) */
+#define MAC_DMA_IMR_S1_QCU_TXEOL_LSB 16
+
+#define MAC_DMA_IMR_S2_ADDRESS 0x000000AC /* MAC Secondary interrupt mask register 2 */
+#define MAC_DMA_IMR_S2_QCU_TXURN_MASK 0x000003FF /* Mask for TXURN (QCU 0-9) */
+#define MAC_DMA_IMR_S2_QCU_TXURN_LSB 0
+#define MAC_DMA_IMR_S2_RX_INT_MASK 0x00000800
+#define MAC_DMA_IMR_S2_WL_STOMPED_MASK 0x00001000
+#define MAC_DMA_IMR_S2_RX_PTR_BAD_MASK 0x00002000
+#define MAC_DMA_IMR_S2_BT_LOW_PRIORITY_RISING_MASK 0x00004000
+#define MAC_DMA_IMR_S2_BT_LOW_PRIORITY_FALLING_MASK 0x00008000
+#define MAC_DMA_IMR_S2_BB_PANIC_IRQ_MASK 0x00010000
+#define MAC_DMA_IMR_S2_BT_STOMPED_MASK 0x00020000
+#define MAC_DMA_IMR_S2_BT_ACTIVE_RISING_MASK 0x00040000
+#define MAC_DMA_IMR_S2_BT_ACTIVE_FALLING_MASK 0x00080000
+#define MAC_DMA_IMR_S2_BT_PRIORITY_RISING_MASK 0x00100000
+#define MAC_DMA_IMR_S2_BT_PRIORITY_FALLING_MASK 0x00200000
+#define MAC_DMA_IMR_S2_CST_MASK 0x00400000
+#define MAC_DMA_IMR_S2_GTT_MASK 0x00800000
+#define MAC_DMA_IMR_S2_TIM_MASK 0x01000000 /* TIM */
+#define MAC_DMA_IMR_S2_CABEND_MASK 0x02000000 /* CABEND */
+#define MAC_DMA_IMR_S2_DTIMSYNC_MASK 0x04000000 /* DTIMSYNC */
+#define MAC_DMA_IMR_S2_BCNTO_MASK 0x08000000 /* BCNTO */
+#define MAC_DMA_IMR_S2_CABTO_MASK 0x10000000 /* CABTO */
+#define MAC_DMA_IMR_S2_DTIM_MASK 0x20000000 /* DTIM */
+#define MAC_DMA_IMR_S2_TSFOOR_MASK 0x40000000 /* TSFOOR */
+
+#define MAC_DMA_IMR_S3_ADDRESS 0x000000B0 /* MAC Secondary interrupt mask register 3 */
+#define MAC_DMA_IMR_S3_QCU_QCBROVF_MASK 0x000003FF /* Mask for QCBROVF (QCU 0-9) */
+#define MAC_DMA_IMR_S3_QCU_QCBRURN_MASK 0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */
+#define MAC_DMA_IMR_S3_QCU_QCBRURN_LSB 16
+
+#define MAC_DMA_IMR_S4_ADDRESS 0x000000B4 /* MAC Secondary interrupt mask register 4 */
+#define MAC_DMA_IMR_S4_QCU_QTRIG_MASK 0x000003FF /* Mask for QTRIG (QCU 0-9) */
+
+#define MAC_DMA_IMR_S5_ADDRESS 0x000000B8 /* MAC Secondary interrupt mask register 5 */
+#define MAC_DMA_IMR_S5_TBTT_TIMER_TRIGGER_MASK 0x00000001
+#define MAC_DMA_IMR_S5_DBA_TIMER_TRIGGER_MASK 0x00000002
+#define MAC_DMA_IMR_S5_SBA_TIMER_TRIGGER_MASK 0x00000004
+#define MAC_DMA_IMR_S5_HCF_TIMER_TRIGGER_MASK 0x00000008
+#define MAC_DMA_IMR_S5_TIM_TIMER_TRIGGER_MASK 0x00000010
+#define MAC_DMA_IMR_S5_DTIM_TIMER_TRIGGER_MASK 0x00000020
+#define MAC_DMA_IMR_S5_QUIET_TIMER_TRIGGER_MASK 0x00000040
+#define MAC_DMA_IMR_S5_NDP_TIMER_TRIGGER_MASK 0x00000080
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER_MASK 0x0000FF00
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER_LSB 8
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER(_i) (0x100 << (_i))
+#define MAC_DMA_IMR_S5_TIMER_OVERFLOW_MASK 0x00010000
+#define MAC_DMA_IMR_S5_DBA_TIMER_THRESHOLD_MASK 0x00020000
+#define MAC_DMA_IMR_S5_SBA_TIMER_THRESHOLD_MASK 0x00040000
+#define MAC_DMA_IMR_S5_HCF_TIMER_THRESHOLD_MASK 0x00080000
+#define MAC_DMA_IMR_S5_TIM_TIMER_THRESHOLD_MASK 0x00100000
+#define MAC_DMA_IMR_S5_DTIM_TIMER_THRESHOLD_MASK 0x00200000
+#define MAC_DMA_IMR_S5_QUIET_TIMER_THRESHOLD_MASK 0000400000
+#define MAC_DMA_IMR_S5_NDP_TIMER_THRESHOLD_MASK 0x00800000
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_MASK 0xFF000000
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_LSB 24
+#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD(_i) (0x01000000 << (_i))
+
+#define MAC_DMA_ISR_RAC_ADDRESS 0x000000C0 /* ISR read-and-clear access */
+
+/* Shadow copies with read-and-clear access */
+#define MAC_DMA_ISR_S0_S_ADDRESS 0x000000C4 /* ISR_S0 shadow copy */
+#define MAC_DMA_ISR_S1_S_ADDRESS 0x000000C8 /* ISR_S1 shadow copy */
+#define MAC_DMA_ISR_S2_S_ADDRESS 0x000000Cc /* ISR_S2 shadow copy */
+#define MAC_DMA_ISR_S3_S_ADDRESS 0x000000D0 /* ISR_S3 shadow copy */
+#define MAC_DMA_ISR_S4_S_ADDRESS 0x000000D4 /* ISR_S4 shadow copy */
+#define MAC_DMA_ISR_S5_S_ADDRESS 0x000000D8 /* ISR_S5 shadow copy */
+
+#define MAC_DMA_Q0_TXDP_ADDRESS 0x00000800 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q1_TXDP_ADDRESS 0x00000804 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q2_TXDP_ADDRESS 0x00000808 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q3_TXDP_ADDRESS 0x0000080C /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q4_TXDP_ADDRESS 0x00000810 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q5_TXDP_ADDRESS 0x00000814 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q6_TXDP_ADDRESS 0x00000818 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q7_TXDP_ADDRESS 0x0000081C /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q8_TXDP_ADDRESS 0x00000820 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_Q9_TXDP_ADDRESS 0x00000824 /* MAC Transmit Queue descriptor pointer */
+#define MAC_DMA_QTXDP_ADDRESS(_i) (MAC_DMA_Q0_TXDP_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_Q_TXE_ADDRESS 0x00000840 /* MAC Transmit Queue enable */
+#define MAC_DMA_Q_TXD_ADDRESS 0x00000880 /* MAC Transmit Queue disable */
+/* QCU registers */
+
+#define MAC_DMA_Q0_CBRCFG_ADDRESS 0x000008C0 /* MAC CBR configuration */
+#define MAC_DMA_Q1_CBRCFG_ADDRESS 0x000008C4 /* MAC CBR configuration */
+#define MAC_DMA_Q2_CBRCFG_ADDRESS 0x000008C8 /* MAC CBR configuration */
+#define MAC_DMA_Q3_CBRCFG_ADDRESS 0x000008CC /* MAC CBR configuration */
+#define MAC_DMA_Q4_CBRCFG_ADDRESS 0x000008D0 /* MAC CBR configuration */
+#define MAC_DMA_Q5_CBRCFG_ADDRESS 0x000008D4 /* MAC CBR configuration */
+#define MAC_DMA_Q6_CBRCFG_ADDRESS 0x000008D8 /* MAC CBR configuration */
+#define MAC_DMA_Q7_CBRCFG_ADDRESS 0x000008DC /* MAC CBR configuration */
+#define MAC_DMA_Q8_CBRCFG_ADDRESS 0x000008E0 /* MAC CBR configuration */
+#define MAC_DMA_Q9_CBRCFG_ADDRESS 0x000008E4 /* MAC CBR configuration */
+#define MAC_DMA_QCBRCFG_ADDRESS(_i) (MAC_DMA_Q0_CBRCFG_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_Q_CBRCFG_CBR_INTERVAL_MASK 0x00FFFFFF /* Mask for CBR interval (us) */
+#define MAC_DMA_Q_CBRCFG_CBR_INTERVAL_LSB 0 /* Shift for CBR interval */
+#define MAC_DMA_Q_CBRCFG_CBR_OVF_THRESH_MASK 0xFF000000 /* Mask for CBR overflow threshold */
+#define MAC_DMA_Q_CBRCFG_CBR_OVF_THRESH_LSB 24 /* Shift for CBR overflow thresh */
+
+
+#define MAC_DMA_Q0_RDYTIMECFG_ADDRESS 0x00000900 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q1_RDYTIMECFG_ADDRESS 0x00000904 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q2_RDYTIMECFG_ADDRESS 0x00000908 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q3_RDYTIMECFG_ADDRESS 0x0000090C /* MAC ReadyTime configuration */
+#define MAC_DMA_Q4_RDYTIMECFG_ADDRESS 0x00000910 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q5_RDYTIMECFG_ADDRESS 0x00000914 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q6_RDYTIMECFG_ADDRESS 0x00000918 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q7_RDYTIMECFG_ADDRESS 0x0000091C /* MAC ReadyTime configuration */
+#define MAC_DMA_Q8_RDYTIMECFG_ADDRESS 0x00000920 /* MAC ReadyTime configuration */
+#define MAC_DMA_Q9_RDYTIMECFG_ADDRESS 0x00000924 /* MAC ReadyTime configuration */
+#define MAC_DMA_QRDYTIMECFG_ADDRESS(_i) (MAC_DMA_Q0_RDYTIMECFG_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_Q_RDYTIMECFG_INT_MASK 0x00FFFFFF /* CBR interval (us) */
+#define MAC_DMA_Q_RDYTIMECFG_INT_LSB 0 /* Shift for ReadyTime Interval (us) */
+#define MAC_DMA_Q_RDYTIMECFG_ENA_MASK 0x01000000 /* CBR enable */
+
+#define MAC_DMA_Q_ONESHOTMAC_DMAM_SC_ADDRESS 0x00000940 /* MAC OneShotArm set control */
+#define MAC_DMA_Q_ONESHOTMAC_DMAM_CC_ADDRESS 0x00000980 /* MAC OneShotArm clear control */
+
+#define MAC_DMA_Q0_MISC_ADDRESS 0x000009C0 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q1_MISC_ADDRESS 0x000009C4 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q2_MISC_ADDRESS 0x000009C8 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q3_MISC_ADDRESS 0x000009CC /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q4_MISC_ADDRESS 0x000009D0 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q5_MISC_ADDRESS 0x000009D4 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q6_MISC_ADDRESS 0x000009D8 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q7_MISC_ADDRESS 0x000009DC /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q8_MISC_ADDRESS 0x000009E0 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_Q9_MISC_ADDRESS 0x000009E4 /* MAC Miscellaneous QCU settings */
+#define MAC_DMA_QMISC_ADDRESS(_i) (MAC_DMA_Q0_MISC_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_Q_MISC_FSP_MASK 0x0000000F /* Frame Scheduling Policy mask */
+#define MAC_DMA_Q_MISC_FSP_ASAP 0 /* ASAP */
+#define MAC_DMA_Q_MISC_FSP_CBR 1 /* CBR */
+#define MAC_DMA_Q_MISC_FSP_DBA_GATED 2 /* DMA Beacon Alert gated */
+#define MAC_DMA_Q_MISC_FSP_TIM_GATED 3 /* TIM gated */
+#define MAC_DMA_Q_MISC_FSP_BEACON_SENT_GATED 4 /* Beacon-sent-gated */
+#define MAC_DMA_Q_MISC_ONE_SHOT_EN_MASK 0x00000010 /* OneShot enable */
+#define MAC_DMA_Q_MISC_CBR_INCR_DIS1_MASK 0x00000020 /* Disable CBR expired counter incr
+ (empty q) */
+#define MAC_DMA_Q_MISC_CBR_INCR_DIS0_MASK 0x00000040 /* Disable CBR expired counter incr
+ (empty beacon q) */
+#define MAC_DMA_Q_MISC_BEACON_USE_MASK 0x00000080 /* Beacon use indication */
+#define MAC_DMA_Q_MISC_CBR_EXP_CNTR_LIMIT_MASK 0x00000100 /* CBR expired counter limit enable */
+#define MAC_DMA_Q_MISC_RDYTIME_EXP_POLICY_MASK 0x00000200 /* Enable TXE cleared on ReadyTime expired or VEOL */
+#define MAC_DMA_Q_MISC_RESET_CBR_EXP_CTR_MASK 0x00000400 /* Reset CBR expired counter */
+#define MAC_DMA_Q_MISC_DCU_EARLY_TERM_REQ_MASK 0x00000800 /* DCU frame early termination request control */
+
+#define MAC_DMA_Q0_STS_ADDRESS 0x00000A00 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q1_STS_ADDRESS 0x00000A04 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q2_STS_ADDRESS 0x00000A08 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q3_STS_ADDRESS 0x00000A0C /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q4_STS_ADDRESS 0x00000A10 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q5_STS_ADDRESS 0x00000A14 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q6_STS_ADDRESS 0x00000A18 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q7_STS_ADDRESS 0x00000A1C /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q8_STS_ADDRESS 0x00000A20 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_Q9_STS_ADDRESS 0x00000A24 /* MAC Miscellaneous QCU status */
+#define MAC_DMA_QSTS_ADDRESS(_i) (MAC_DMA_Q0_STS_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_Q_STS_PEND_FR_CNT_MASK 0x00000003 /* Mask for Pending Frame Count */
+#define MAC_DMA_Q_STS_CBR_EXP_CNT_MASK 0x0000FF00 /* Mask for CBR expired counter */
+
+#define MAC_DMA_Q_RDYTIMESHDN_ADDRESS 0x00000A40 /* MAC ReadyTimeShutdown status */
+
+/* DCU registers */
+
+#define MAC_DMA_D0_QCUMASK_ADDRESS 0x00001000 /* MAC QCU Mask */
+#define MAC_DMA_D1_QCUMASK_ADDRESS 0x00001004 /* MAC QCU Mask */
+#define MAC_DMA_D2_QCUMASK_ADDRESS 0x00001008 /* MAC QCU Mask */
+#define MAC_DMA_D3_QCUMASK_ADDRESS 0x0000100C /* MAC QCU Mask */
+#define MAC_DMA_D4_QCUMASK_ADDRESS 0x00001010 /* MAC QCU Mask */
+#define MAC_DMA_D5_QCUMASK_ADDRESS 0x00001014 /* MAC QCU Mask */
+#define MAC_DMA_D6_QCUMASK_ADDRESS 0x00001018 /* MAC QCU Mask */
+#define MAC_DMA_D7_QCUMASK_ADDRESS 0x0000101C /* MAC QCU Mask */
+#define MAC_DMA_D8_QCUMASK_ADDRESS 0x00001020 /* MAC QCU Mask */
+#define MAC_DMA_D9_QCUMASK_ADDRESS 0x00001024 /* MAC QCU Mask */
+#define MAC_DMA_DQCUMASK_ADDRESS(_i) (MAC_DMA_D0_QCUMASK_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_D_QCUMASK_MASK 0x000003FF /* Mask for QCU Mask (QCU 0-9) */
+
+#define MAC_DMA_D_GBL_IFS_SIFS_ADDRESS 0x00001030 /* DCU global SIFS settings */
+
+
+#define MAC_DMA_D0_LCL_IFS_ADDRESS 0x00001040 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D1_LCL_IFS_ADDRESS 0x00001044 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D2_LCL_IFS_ADDRESS 0x00001048 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D3_LCL_IFS_ADDRESS 0x0000104C /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D4_LCL_IFS_ADDRESS 0x00001050 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D5_LCL_IFS_ADDRESS 0x00001054 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D6_LCL_IFS_ADDRESS 0x00001058 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D7_LCL_IFS_ADDRESS 0x0000105C /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D8_LCL_IFS_ADDRESS 0x00001060 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_D9_LCL_IFS_ADDRESS 0x00001064 /* MAC DCU-specific IFS settings */
+#define MAC_DMA_DLCL_IFS_ADDRESS(_i) (MAC_DMA_D0_LCL_IFS_ADDRESS + ((_i)<<2))
+#define MAC_DMA_D_LCL_IFS_CWMIN_MASK 0x000003FF /* Mask for CW_MIN */
+#define MAC_DMA_D_LCL_IFS_CWMIN_LSB 0
+#define MAC_DMA_D_LCL_IFS_CWMAX_MASK 0x000FFC00 /* Mask for CW_MAX */
+#define MAC_DMA_D_LCL_IFS_CWMAX_LSB 10
+#define MAC_DMA_D_LCL_IFS_AIFS_MASK 0x0FF00000 /* Mask for AIFS */
+#define MAC_DMA_D_LCL_IFS_AIFS_LSB 20
+/*
+ * Note: even though this field is 8 bits wide the
+ * maximum supported AIFS value is 0xFc. Setting the AIFS value
+ * to 0xFd 0xFe, or 0xFf will not work correctly and will cause
+ * the DCU to hang.
+ */
+#define MAC_DMA_D_GBL_IFS_SLOT_ADDRESS 0x00001070 /* DC global slot interval */
+
+#define MAC_DMA_D0_RETRY_LIMIT_ADDRESS 0x00001080 /* MAC Retry limits */
+#define MAC_DMA_D1_RETRY_LIMIT_ADDRESS 0x00001084 /* MAC Retry limits */
+#define MAC_DMA_D2_RETRY_LIMIT_ADDRESS 0x00001088 /* MAC Retry limits */
+#define MAC_DMA_D3_RETRY_LIMIT_ADDRESS 0x0000108C /* MAC Retry limits */
+#define MAC_DMA_D4_RETRY_LIMIT_ADDRESS 0x00001090 /* MAC Retry limits */
+#define MAC_DMA_D5_RETRY_LIMIT_ADDRESS 0x00001094 /* MAC Retry limits */
+#define MAC_DMA_D6_RETRY_LIMIT_ADDRESS 0x00001098 /* MAC Retry limits */
+#define MAC_DMA_D7_RETRY_LIMIT_ADDRESS 0x0000109C /* MAC Retry limits */
+#define MAC_DMA_D8_RETRY_LIMIT_ADDRESS 0x000010A0 /* MAC Retry limits */
+#define MAC_DMA_D9_RETRY_LIMIT_ADDRESS 0x000010A4 /* MAC Retry limits */
+#define MAC_DMA_DRETRY_LIMIT_ADDRESS(_i) (MAC_DMA_D0_RETRY_LIMIT_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_D_RETRY_LIMIT_FR_RTS_MASK 0x0000000F /* frame RTS failure limit */
+#define MAC_DMA_D_RETRY_LIMIT_FR_RTS_LSB 0
+#define MAC_DMA_D_RETRY_LIMIT_STA_RTS_MASK 0x00003F00 /* station RTS failure limit */
+#define MAC_DMA_D_RETRY_LIMIT_STA_RTS_LSB 8
+#define MAC_DMA_D_RETRY_LIMIT_STA_DATA_MASK 0x000FC000 /* station short retry limit */
+#define MAC_DMA_D_RETRY_LIMIT_STA_DATA_LSB 14
+
+#define MAC_DMA_D_GBL_IFS_EIFS_ADDRESS 0x000010B0 /* DCU global EIFS setting */
+
+#define MAC_DMA_D0_CHNTIME_ADDRESS 0x000010C0 /* MAC ChannelTime settings */
+#define MAC_DMA_D1_CHNTIME_ADDRESS 0x000010C4 /* MAC ChannelTime settings */
+#define MAC_DMA_D2_CHNTIME_ADDRESS 0x000010C8 /* MAC ChannelTime settings */
+#define MAC_DMA_D3_CHNTIME_ADDRESS 0x000010CC /* MAC ChannelTime settings */
+#define MAC_DMA_D4_CHNTIME_ADDRESS 0x000010D0 /* MAC ChannelTime settings */
+#define MAC_DMA_D5_CHNTIME_ADDRESS 0x000010D4 /* MAC ChannelTime settings */
+#define MAC_DMA_D6_CHNTIME_ADDRESS 0x000010D8 /* MAC ChannelTime settings */
+#define MAC_DMA_D7_CHNTIME_ADDRESS 0x000010DC /* MAC ChannelTime settings */
+#define MAC_DMA_D8_CHNTIME_ADDRESS 0x000010E0 /* MAC ChannelTime settings */
+#define MAC_DMA_D9_CHNTIME_ADDRESS 0x000010E4 /* MAC ChannelTime settings */
+#define MAC_DMA_DCHNTIME_ADDRESS(_i) (MAC_DMA_D0_CHNTIME_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_D_CHNTIME_DUR_MASK 0x000FFFFF /* ChannelTime duration (us) */
+#define MAC_DMA_D_CHNTIME_DUR_LSB 0 /* Shift for ChannelTime duration */
+#define MAC_DMA_D_CHNTIME_EN_MASK 0x00100000 /* ChannelTime enable */
+
+#define MAC_DMA_D_GBL_IFS_MISC_ADDRESS 0x000010f0 /* DCU global misc. IFS settings */
+#define MAC_DMA_D_GBL_IFS_MISC_LFSR_SLICE_SEL_MASK 0x00000007 /* LFSR slice select */
+#define MAC_DMA_D_GBL_IFS_MISC_TURBO_MODE_MASK 0x00000008 /* Turbo mode indication */
+#define MAC_DMA_D_GBL_IFS_MISC_DCU_ARBITER_DLY_MASK 0x00300000 /* DCU arbiter delay */
+#define MAC_DMA_D_GBL_IFS_IGNORE_BACKOFF_MASK 0x10000000
+
+#define MAC_DMA_D0_MISC_ADDRESS 0x00001100 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D1_MISC_ADDRESS 0x00001104 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D2_MISC_ADDRESS 0x00001108 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D3_MISC_ADDRESS 0x0000110C /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D4_MISC_ADDRESS 0x00001110 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D5_MISC_ADDRESS 0x00001114 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D6_MISC_ADDRESS 0x00001118 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D7_MISC_ADDRESS 0x0000111C /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D8_MISC_ADDRESS 0x00001120 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_D9_MISC_ADDRESS 0x00001124 /* MAC Miscellaneous DCU-specific settings */
+#define MAC_DMA_DMISC_ADDRESS(_i) (MAC_DMA_D0_MISC_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_D0_EOL_ADDRESS 0x00001180
+#define MAC_DMA_D1_EOL_ADDRESS 0x00001184
+#define MAC_DMA_D2_EOL_ADDRESS 0x00001188
+#define MAC_DMA_D3_EOL_ADDRESS 0x0000118C
+#define MAC_DMA_D4_EOL_ADDRESS 0x00001190
+#define MAC_DMA_D5_EOL_ADDRESS 0x00001194
+#define MAC_DMA_D6_EOL_ADDRESS 0x00001198
+#define MAC_DMA_D7_EOL_ADDRESS 0x0000119C
+#define MAC_DMA_D8_EOL_ADDRESS 0x00001200
+#define MAC_DMA_D9_EOL_ADDRESS 0x00001204
+#define MAC_DMA_DEOL_ADDRESS(_i) (MAC_DMA_D0_EOL_ADDRESS + ((_i)<<2))
+
+#define MAC_DMA_D_MISC_BKOFF_THRESH_MASK 0x0000003F /* Backoff threshold */
+#define MAC_DMA_D_MISC_BACK_OFF_THRESH_LSB 0
+#define MAC_DMA_D_MISC_ETS_RTS_MASK 0x00000040 /* End of transmission series
+ station RTS/data failure
+ count reset policy */
+#define MAC_DMA_D_MISC_ETS_CW_MASK 0x00000080 /* End of transmission series
+ CW reset policy */
+#define MAC_DMA_D_MISC_FRAG_WAIT_EN_MASK 0x00000100 /* Fragment Starvation Policy */
+
+#define MAC_DMA_D_MISC_FRAG_BKOFF_EN_MASK 0x00000200 /* Backoff during a frag burst */
+#define MAC_DMA_D_MISC_HCF_POLL_EN_MASK 0x00000800 /* HFC poll enable */
+#define MAC_DMA_D_MISC_BKOFF_PERSISTENCE_MASK 0x00001000 /* Backoff persistence factor
+ setting */
+#define MAC_DMA_D_MISC_VIR_COL_HANDLING_MASK 0x0000C000 /* Mask for Virtual collision
+ handling policy */
+#define MAC_DMA_D_MISC_VIR_COL_HANDLING_LSB 14
+#define MAC_DMA_D_MISC_VIR_COL_HANDLING_DEFAULT 0 /* Normal */
+#define MAC_DMA_D_MISC_VIR_COL_HANDLING_IGNORE 1 /* Ignore */
+#define MAC_DMA_D_MISC_BEACON_USE_MASK 0x00010000 /* Beacon use indication */
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_MASK 0x00060000 /* Mask for DCU arbiter lockout control */
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_LSB 17
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0 /* No lockout*/
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1 /* Intra-frame*/
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2 /* Global */
+#define MAC_DMA_D_MISC_ARB_LOCKOUT_IGNORE_MASK 0x00080000 /* DCU arbiter lockout ignore control */
+#define MAC_DMA_D_MISC_SEQ_NUM_INCR_DIS_MASK 0x00100000 /* Sequence number increment disable */
+#define MAC_DMA_D_MISC_POST_FR_BKOFF_DIS_MASK 0x00200000 /* Post-frame backoff disable */
+#define MAC_DMA_D_MISC_VIRT_COLL_POLICY_MASK 0x00400000 /* Virtual coll. handling policy */
+#define MAC_DMA_D_MISC_BLOWN_IFS_POLICY_MASK 0x00800000 /* Blown IFS handling policy */
+
+#define MAC_DMA_D_SEQNUM_ADDRESS 0x00001140 /* MAC Frame sequence number */
+
+
+
+#define MAC_DMA_D_FPCTL_ADDRESS 0x00001230 /* DCU frame prefetch settings */
+#define MAC_DMA_D_TXPSE_ADDRESS 0x00001270 /* DCU transmit pause control/status */
+
+#endif /* _AR6000_DMMAEG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h
new file mode 100644
index 000000000000..6ccb08c5dab2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h
@@ -0,0 +1,3065 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _MAC_PCU_REG_H_
+#define _MAC_PCU_REG_H_
+
+#define MAC_PCU_STA_ADDR_L32_ADDRESS 0x00008000
+#define MAC_PCU_STA_ADDR_L32_OFFSET 0x00000000
+#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_MSB 31
+#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB 0
+#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK 0xffffffff
+#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_GET(x) (((x) & MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK) >> MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB)
+#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_SET(x) (((x) << MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB) & MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK)
+
+#define MAC_PCU_STA_ADDR_U16_ADDRESS 0x00008004
+#define MAC_PCU_STA_ADDR_U16_OFFSET 0x00000004
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MSB 31
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB 31
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK 0x80000000
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK) >> MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB)
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB) & MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK)
+#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MSB 30
+#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB 30
+#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK 0x40000000
+#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK) >> MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB)
+#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB) & MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK)
+#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MSB 29
+#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB 29
+#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK 0x20000000
+#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK) >> MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB)
+#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB) & MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK)
+#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MSB 28
+#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB 28
+#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK 0x10000000
+#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK) >> MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB)
+#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB) & MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK)
+#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MSB 27
+#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB 27
+#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK 0x08000000
+#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK) >> MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB)
+#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB) & MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK)
+#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MSB 26
+#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB 26
+#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK 0x04000000
+#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK) >> MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB)
+#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB) & MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK)
+#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MSB 25
+#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB 25
+#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK 0x02000000
+#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK) >> MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB)
+#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB) & MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK)
+#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MSB 24
+#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB 24
+#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK 0x01000000
+#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK) >> MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB)
+#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB) & MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK)
+#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MSB 23
+#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB 23
+#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK 0x00800000
+#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK) >> MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB)
+#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB) & MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK)
+#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MSB 22
+#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB 22
+#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK 0x00400000
+#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK) >> MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB)
+#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB) & MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK)
+#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_MSB 21
+#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB 21
+#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK 0x00200000
+#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK) >> MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB)
+#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB) & MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK)
+#define MAC_PCU_STA_ADDR_U16_PCF_MSB 20
+#define MAC_PCU_STA_ADDR_U16_PCF_LSB 20
+#define MAC_PCU_STA_ADDR_U16_PCF_MASK 0x00100000
+#define MAC_PCU_STA_ADDR_U16_PCF_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_PCF_MASK) >> MAC_PCU_STA_ADDR_U16_PCF_LSB)
+#define MAC_PCU_STA_ADDR_U16_PCF_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_PCF_LSB) & MAC_PCU_STA_ADDR_U16_PCF_MASK)
+#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MSB 19
+#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB 19
+#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK 0x00080000
+#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK) >> MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB)
+#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB) & MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK)
+#define MAC_PCU_STA_ADDR_U16_PW_SAVE_MSB 18
+#define MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB 18
+#define MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK 0x00040000
+#define MAC_PCU_STA_ADDR_U16_PW_SAVE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK) >> MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB)
+#define MAC_PCU_STA_ADDR_U16_PW_SAVE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB) & MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK)
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MSB 17
+#define MAC_PCU_STA_ADDR_U16_ADHOC_LSB 17
+#define MAC_PCU_STA_ADDR_U16_ADHOC_MASK 0x00020000
+#define MAC_PCU_STA_ADDR_U16_ADHOC_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_ADHOC_MASK) >> MAC_PCU_STA_ADDR_U16_ADHOC_LSB)
+#define MAC_PCU_STA_ADDR_U16_ADHOC_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_ADHOC_LSB) & MAC_PCU_STA_ADDR_U16_ADHOC_MASK)
+#define MAC_PCU_STA_ADDR_U16_STA_AP_MSB 16
+#define MAC_PCU_STA_ADDR_U16_STA_AP_LSB 16
+#define MAC_PCU_STA_ADDR_U16_STA_AP_MASK 0x00010000
+#define MAC_PCU_STA_ADDR_U16_STA_AP_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_STA_AP_MASK) >> MAC_PCU_STA_ADDR_U16_STA_AP_LSB)
+#define MAC_PCU_STA_ADDR_U16_STA_AP_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_STA_AP_LSB) & MAC_PCU_STA_ADDR_U16_STA_AP_MASK)
+#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_MSB 15
+#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB 0
+#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK 0x0000ffff
+#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK) >> MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB)
+#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB) & MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK)
+
+#define MAC_PCU_BSSID_L32_ADDRESS 0x00008008
+#define MAC_PCU_BSSID_L32_OFFSET 0x00000008
+#define MAC_PCU_BSSID_L32_ADDR_MSB 31
+#define MAC_PCU_BSSID_L32_ADDR_LSB 0
+#define MAC_PCU_BSSID_L32_ADDR_MASK 0xffffffff
+#define MAC_PCU_BSSID_L32_ADDR_GET(x) (((x) & MAC_PCU_BSSID_L32_ADDR_MASK) >> MAC_PCU_BSSID_L32_ADDR_LSB)
+#define MAC_PCU_BSSID_L32_ADDR_SET(x) (((x) << MAC_PCU_BSSID_L32_ADDR_LSB) & MAC_PCU_BSSID_L32_ADDR_MASK)
+
+#define MAC_PCU_BSSID_U16_ADDRESS 0x0000800c
+#define MAC_PCU_BSSID_U16_OFFSET 0x0000000c
+#define MAC_PCU_BSSID_U16_AID_MSB 26
+#define MAC_PCU_BSSID_U16_AID_LSB 16
+#define MAC_PCU_BSSID_U16_AID_MASK 0x07ff0000
+#define MAC_PCU_BSSID_U16_AID_GET(x) (((x) & MAC_PCU_BSSID_U16_AID_MASK) >> MAC_PCU_BSSID_U16_AID_LSB)
+#define MAC_PCU_BSSID_U16_AID_SET(x) (((x) << MAC_PCU_BSSID_U16_AID_LSB) & MAC_PCU_BSSID_U16_AID_MASK)
+#define MAC_PCU_BSSID_U16_ADDR_MSB 15
+#define MAC_PCU_BSSID_U16_ADDR_LSB 0
+#define MAC_PCU_BSSID_U16_ADDR_MASK 0x0000ffff
+#define MAC_PCU_BSSID_U16_ADDR_GET(x) (((x) & MAC_PCU_BSSID_U16_ADDR_MASK) >> MAC_PCU_BSSID_U16_ADDR_LSB)
+#define MAC_PCU_BSSID_U16_ADDR_SET(x) (((x) << MAC_PCU_BSSID_U16_ADDR_LSB) & MAC_PCU_BSSID_U16_ADDR_MASK)
+
+#define MAC_PCU_BCN_RSSI_AVE_ADDRESS 0x00008010
+#define MAC_PCU_BCN_RSSI_AVE_OFFSET 0x00000010
+#define MAC_PCU_BCN_RSSI_AVE_VALUE_MSB 11
+#define MAC_PCU_BCN_RSSI_AVE_VALUE_LSB 0
+#define MAC_PCU_BCN_RSSI_AVE_VALUE_MASK 0x00000fff
+#define MAC_PCU_BCN_RSSI_AVE_VALUE_GET(x) (((x) & MAC_PCU_BCN_RSSI_AVE_VALUE_MASK) >> MAC_PCU_BCN_RSSI_AVE_VALUE_LSB)
+#define MAC_PCU_BCN_RSSI_AVE_VALUE_SET(x) (((x) << MAC_PCU_BCN_RSSI_AVE_VALUE_LSB) & MAC_PCU_BCN_RSSI_AVE_VALUE_MASK)
+
+#define MAC_PCU_ACK_CTS_TIMEOUT_ADDRESS 0x00008014
+#define MAC_PCU_ACK_CTS_TIMEOUT_OFFSET 0x00000014
+#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MSB 29
+#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB 16
+#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK 0x3fff0000
+#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_GET(x) (((x) & MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK) >> MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB)
+#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_SET(x) (((x) << MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB) & MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK)
+#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MSB 13
+#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB 0
+#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK 0x00003fff
+#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_GET(x) (((x) & MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK) >> MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB)
+#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_SET(x) (((x) << MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB) & MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK)
+
+#define MAC_PCU_BCN_RSSI_CTL_ADDRESS 0x00008018
+#define MAC_PCU_BCN_RSSI_CTL_OFFSET 0x00000018
+#define MAC_PCU_BCN_RSSI_CTL_RESET_MSB 29
+#define MAC_PCU_BCN_RSSI_CTL_RESET_LSB 29
+#define MAC_PCU_BCN_RSSI_CTL_RESET_MASK 0x20000000
+#define MAC_PCU_BCN_RSSI_CTL_RESET_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_RESET_MASK) >> MAC_PCU_BCN_RSSI_CTL_RESET_LSB)
+#define MAC_PCU_BCN_RSSI_CTL_RESET_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_RESET_LSB) & MAC_PCU_BCN_RSSI_CTL_RESET_MASK)
+#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_MSB 28
+#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB 24
+#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK 0x1f000000
+#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK) >> MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB)
+#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB) & MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK)
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MSB 23
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB 16
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK 0x00ff0000
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB)
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK)
+#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MSB 15
+#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB 8
+#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK 0x0000ff00
+#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB)
+#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK)
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MSB 7
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB 0
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK 0x000000ff
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB)
+#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK)
+
+#define MAC_PCU_USEC_LATENCY_ADDRESS 0x0000801c
+#define MAC_PCU_USEC_LATENCY_OFFSET 0x0000001c
+#define MAC_PCU_USEC_LATENCY_RX_LATENCY_MSB 28
+#define MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB 23
+#define MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK 0x1f800000
+#define MAC_PCU_USEC_LATENCY_RX_LATENCY_GET(x) (((x) & MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK) >> MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB)
+#define MAC_PCU_USEC_LATENCY_RX_LATENCY_SET(x) (((x) << MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB) & MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK)
+#define MAC_PCU_USEC_LATENCY_TX_LATENCY_MSB 22
+#define MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB 14
+#define MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK 0x007fc000
+#define MAC_PCU_USEC_LATENCY_TX_LATENCY_GET(x) (((x) & MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK) >> MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB)
+#define MAC_PCU_USEC_LATENCY_TX_LATENCY_SET(x) (((x) << MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB) & MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK)
+#define MAC_PCU_USEC_LATENCY_USEC_MSB 7
+#define MAC_PCU_USEC_LATENCY_USEC_LSB 0
+#define MAC_PCU_USEC_LATENCY_USEC_MASK 0x000000ff
+#define MAC_PCU_USEC_LATENCY_USEC_GET(x) (((x) & MAC_PCU_USEC_LATENCY_USEC_MASK) >> MAC_PCU_USEC_LATENCY_USEC_LSB)
+#define MAC_PCU_USEC_LATENCY_USEC_SET(x) (((x) << MAC_PCU_USEC_LATENCY_USEC_LSB) & MAC_PCU_USEC_LATENCY_USEC_MASK)
+
+#define PCU_MAX_CFP_DUR_ADDRESS 0x00008020
+#define PCU_MAX_CFP_DUR_OFFSET 0x00000020
+#define PCU_MAX_CFP_DUR_VALUE_MSB 15
+#define PCU_MAX_CFP_DUR_VALUE_LSB 0
+#define PCU_MAX_CFP_DUR_VALUE_MASK 0x0000ffff
+#define PCU_MAX_CFP_DUR_VALUE_GET(x) (((x) & PCU_MAX_CFP_DUR_VALUE_MASK) >> PCU_MAX_CFP_DUR_VALUE_LSB)
+#define PCU_MAX_CFP_DUR_VALUE_SET(x) (((x) << PCU_MAX_CFP_DUR_VALUE_LSB) & PCU_MAX_CFP_DUR_VALUE_MASK)
+
+#define MAC_PCU_RX_FILTER_ADDRESS 0x00008024
+#define MAC_PCU_RX_FILTER_OFFSET 0x00000024
+#define MAC_PCU_RX_FILTER_GENERIC_FILTER_MSB 25
+#define MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB 24
+#define MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK 0x03000000
+#define MAC_PCU_RX_FILTER_GENERIC_FILTER_GET(x) (((x) & MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK) >> MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB)
+#define MAC_PCU_RX_FILTER_GENERIC_FILTER_SET(x) (((x) << MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB) & MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK)
+#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_MSB 23
+#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB 18
+#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK 0x00fc0000
+#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_GET(x) (((x) & MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK) >> MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB)
+#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_SET(x) (((x) << MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB) & MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK)
+#define MAC_PCU_RX_FILTER_FROM_TO_DS_MSB 17
+#define MAC_PCU_RX_FILTER_FROM_TO_DS_LSB 17
+#define MAC_PCU_RX_FILTER_FROM_TO_DS_MASK 0x00020000
+#define MAC_PCU_RX_FILTER_FROM_TO_DS_GET(x) (((x) & MAC_PCU_RX_FILTER_FROM_TO_DS_MASK) >> MAC_PCU_RX_FILTER_FROM_TO_DS_LSB)
+#define MAC_PCU_RX_FILTER_FROM_TO_DS_SET(x) (((x) << MAC_PCU_RX_FILTER_FROM_TO_DS_LSB) & MAC_PCU_RX_FILTER_FROM_TO_DS_MASK)
+#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MSB 16
+#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB 16
+#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK 0x00010000
+#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_GET(x) (((x) & MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK) >> MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB)
+#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_SET(x) (((x) << MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB) & MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK)
+#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MSB 15
+#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB 15
+#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK 0x00008000
+#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_GET(x) (((x) & MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK) >> MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB)
+#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_SET(x) (((x) << MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB) & MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK)
+#define MAC_PCU_RX_FILTER_PS_POLL_MSB 14
+#define MAC_PCU_RX_FILTER_PS_POLL_LSB 14
+#define MAC_PCU_RX_FILTER_PS_POLL_MASK 0x00004000
+#define MAC_PCU_RX_FILTER_PS_POLL_GET(x) (((x) & MAC_PCU_RX_FILTER_PS_POLL_MASK) >> MAC_PCU_RX_FILTER_PS_POLL_LSB)
+#define MAC_PCU_RX_FILTER_PS_POLL_SET(x) (((x) << MAC_PCU_RX_FILTER_PS_POLL_LSB) & MAC_PCU_RX_FILTER_PS_POLL_MASK)
+#define MAC_PCU_RX_FILTER_ASSUME_RADAR_MSB 13
+#define MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB 13
+#define MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK 0x00002000
+#define MAC_PCU_RX_FILTER_ASSUME_RADAR_GET(x) (((x) & MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK) >> MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB)
+#define MAC_PCU_RX_FILTER_ASSUME_RADAR_SET(x) (((x) << MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB) & MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK)
+#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MSB 12
+#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB 12
+#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK 0x00001000
+#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_GET(x) (((x) & MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK) >> MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB)
+#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_SET(x) (((x) << MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB) & MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK)
+#define MAC_PCU_RX_FILTER_COMPRESSED_BA_MSB 11
+#define MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB 11
+#define MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK 0x00000800
+#define MAC_PCU_RX_FILTER_COMPRESSED_BA_GET(x) (((x) & MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK) >> MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB)
+#define MAC_PCU_RX_FILTER_COMPRESSED_BA_SET(x) (((x) << MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB) & MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK)
+#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_MSB 10
+#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB 10
+#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK 0x00000400
+#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_GET(x) (((x) & MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK) >> MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB)
+#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_SET(x) (((x) << MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB) & MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK)
+#define MAC_PCU_RX_FILTER_MY_BEACON_MSB 9
+#define MAC_PCU_RX_FILTER_MY_BEACON_LSB 9
+#define MAC_PCU_RX_FILTER_MY_BEACON_MASK 0x00000200
+#define MAC_PCU_RX_FILTER_MY_BEACON_GET(x) (((x) & MAC_PCU_RX_FILTER_MY_BEACON_MASK) >> MAC_PCU_RX_FILTER_MY_BEACON_LSB)
+#define MAC_PCU_RX_FILTER_MY_BEACON_SET(x) (((x) << MAC_PCU_RX_FILTER_MY_BEACON_LSB) & MAC_PCU_RX_FILTER_MY_BEACON_MASK)
+#define MAC_PCU_RX_FILTER_SYNC_FRAME_MSB 8
+#define MAC_PCU_RX_FILTER_SYNC_FRAME_LSB 8
+#define MAC_PCU_RX_FILTER_SYNC_FRAME_MASK 0x00000100
+#define MAC_PCU_RX_FILTER_SYNC_FRAME_GET(x) (((x) & MAC_PCU_RX_FILTER_SYNC_FRAME_MASK) >> MAC_PCU_RX_FILTER_SYNC_FRAME_LSB)
+#define MAC_PCU_RX_FILTER_SYNC_FRAME_SET(x) (((x) << MAC_PCU_RX_FILTER_SYNC_FRAME_LSB) & MAC_PCU_RX_FILTER_SYNC_FRAME_MASK)
+#define MAC_PCU_RX_FILTER_PROBE_REQ_MSB 7
+#define MAC_PCU_RX_FILTER_PROBE_REQ_LSB 7
+#define MAC_PCU_RX_FILTER_PROBE_REQ_MASK 0x00000080
+#define MAC_PCU_RX_FILTER_PROBE_REQ_GET(x) (((x) & MAC_PCU_RX_FILTER_PROBE_REQ_MASK) >> MAC_PCU_RX_FILTER_PROBE_REQ_LSB)
+#define MAC_PCU_RX_FILTER_PROBE_REQ_SET(x) (((x) << MAC_PCU_RX_FILTER_PROBE_REQ_LSB) & MAC_PCU_RX_FILTER_PROBE_REQ_MASK)
+#define MAC_PCU_RX_FILTER_XR_POLL_MSB 6
+#define MAC_PCU_RX_FILTER_XR_POLL_LSB 6
+#define MAC_PCU_RX_FILTER_XR_POLL_MASK 0x00000040
+#define MAC_PCU_RX_FILTER_XR_POLL_GET(x) (((x) & MAC_PCU_RX_FILTER_XR_POLL_MASK) >> MAC_PCU_RX_FILTER_XR_POLL_LSB)
+#define MAC_PCU_RX_FILTER_XR_POLL_SET(x) (((x) << MAC_PCU_RX_FILTER_XR_POLL_LSB) & MAC_PCU_RX_FILTER_XR_POLL_MASK)
+#define MAC_PCU_RX_FILTER_PROMISCUOUS_MSB 5
+#define MAC_PCU_RX_FILTER_PROMISCUOUS_LSB 5
+#define MAC_PCU_RX_FILTER_PROMISCUOUS_MASK 0x00000020
+#define MAC_PCU_RX_FILTER_PROMISCUOUS_GET(x) (((x) & MAC_PCU_RX_FILTER_PROMISCUOUS_MASK) >> MAC_PCU_RX_FILTER_PROMISCUOUS_LSB)
+#define MAC_PCU_RX_FILTER_PROMISCUOUS_SET(x) (((x) << MAC_PCU_RX_FILTER_PROMISCUOUS_LSB) & MAC_PCU_RX_FILTER_PROMISCUOUS_MASK)
+#define MAC_PCU_RX_FILTER_BEACON_MSB 4
+#define MAC_PCU_RX_FILTER_BEACON_LSB 4
+#define MAC_PCU_RX_FILTER_BEACON_MASK 0x00000010
+#define MAC_PCU_RX_FILTER_BEACON_GET(x) (((x) & MAC_PCU_RX_FILTER_BEACON_MASK) >> MAC_PCU_RX_FILTER_BEACON_LSB)
+#define MAC_PCU_RX_FILTER_BEACON_SET(x) (((x) << MAC_PCU_RX_FILTER_BEACON_LSB) & MAC_PCU_RX_FILTER_BEACON_MASK)
+#define MAC_PCU_RX_FILTER_CONTROL_MSB 3
+#define MAC_PCU_RX_FILTER_CONTROL_LSB 3
+#define MAC_PCU_RX_FILTER_CONTROL_MASK 0x00000008
+#define MAC_PCU_RX_FILTER_CONTROL_GET(x) (((x) & MAC_PCU_RX_FILTER_CONTROL_MASK) >> MAC_PCU_RX_FILTER_CONTROL_LSB)
+#define MAC_PCU_RX_FILTER_CONTROL_SET(x) (((x) << MAC_PCU_RX_FILTER_CONTROL_LSB) & MAC_PCU_RX_FILTER_CONTROL_MASK)
+#define MAC_PCU_RX_FILTER_BROADCAST_MSB 2
+#define MAC_PCU_RX_FILTER_BROADCAST_LSB 2
+#define MAC_PCU_RX_FILTER_BROADCAST_MASK 0x00000004
+#define MAC_PCU_RX_FILTER_BROADCAST_GET(x) (((x) & MAC_PCU_RX_FILTER_BROADCAST_MASK) >> MAC_PCU_RX_FILTER_BROADCAST_LSB)
+#define MAC_PCU_RX_FILTER_BROADCAST_SET(x) (((x) << MAC_PCU_RX_FILTER_BROADCAST_LSB) & MAC_PCU_RX_FILTER_BROADCAST_MASK)
+#define MAC_PCU_RX_FILTER_MULTICAST_MSB 1
+#define MAC_PCU_RX_FILTER_MULTICAST_LSB 1
+#define MAC_PCU_RX_FILTER_MULTICAST_MASK 0x00000002
+#define MAC_PCU_RX_FILTER_MULTICAST_GET(x) (((x) & MAC_PCU_RX_FILTER_MULTICAST_MASK) >> MAC_PCU_RX_FILTER_MULTICAST_LSB)
+#define MAC_PCU_RX_FILTER_MULTICAST_SET(x) (((x) << MAC_PCU_RX_FILTER_MULTICAST_LSB) & MAC_PCU_RX_FILTER_MULTICAST_MASK)
+#define MAC_PCU_RX_FILTER_UNICAST_MSB 0
+#define MAC_PCU_RX_FILTER_UNICAST_LSB 0
+#define MAC_PCU_RX_FILTER_UNICAST_MASK 0x00000001
+#define MAC_PCU_RX_FILTER_UNICAST_GET(x) (((x) & MAC_PCU_RX_FILTER_UNICAST_MASK) >> MAC_PCU_RX_FILTER_UNICAST_LSB)
+#define MAC_PCU_RX_FILTER_UNICAST_SET(x) (((x) << MAC_PCU_RX_FILTER_UNICAST_LSB) & MAC_PCU_RX_FILTER_UNICAST_MASK)
+
+#define MAC_PCU_MCAST_FILTER_L32_ADDRESS 0x00008028
+#define MAC_PCU_MCAST_FILTER_L32_OFFSET 0x00000028
+#define MAC_PCU_MCAST_FILTER_L32_VALUE_MSB 31
+#define MAC_PCU_MCAST_FILTER_L32_VALUE_LSB 0
+#define MAC_PCU_MCAST_FILTER_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_MCAST_FILTER_L32_VALUE_GET(x) (((x) & MAC_PCU_MCAST_FILTER_L32_VALUE_MASK) >> MAC_PCU_MCAST_FILTER_L32_VALUE_LSB)
+#define MAC_PCU_MCAST_FILTER_L32_VALUE_SET(x) (((x) << MAC_PCU_MCAST_FILTER_L32_VALUE_LSB) & MAC_PCU_MCAST_FILTER_L32_VALUE_MASK)
+
+#define MAC_PCU_MCAST_FILTER_U32_ADDRESS 0x0000802c
+#define MAC_PCU_MCAST_FILTER_U32_OFFSET 0x0000002c
+#define MAC_PCU_MCAST_FILTER_U32_VALUE_MSB 31
+#define MAC_PCU_MCAST_FILTER_U32_VALUE_LSB 0
+#define MAC_PCU_MCAST_FILTER_U32_VALUE_MASK 0xffffffff
+#define MAC_PCU_MCAST_FILTER_U32_VALUE_GET(x) (((x) & MAC_PCU_MCAST_FILTER_U32_VALUE_MASK) >> MAC_PCU_MCAST_FILTER_U32_VALUE_LSB)
+#define MAC_PCU_MCAST_FILTER_U32_VALUE_SET(x) (((x) << MAC_PCU_MCAST_FILTER_U32_VALUE_LSB) & MAC_PCU_MCAST_FILTER_U32_VALUE_MASK)
+
+#define MAC_PCU_DIAG_SW_ADDRESS 0x00008030
+#define MAC_PCU_DIAG_SW_OFFSET 0x00000030
+#define MAC_PCU_DIAG_SW_DEBUG_MODE_MSB 31
+#define MAC_PCU_DIAG_SW_DEBUG_MODE_LSB 30
+#define MAC_PCU_DIAG_SW_DEBUG_MODE_MASK 0xc0000000
+#define MAC_PCU_DIAG_SW_DEBUG_MODE_GET(x) (((x) & MAC_PCU_DIAG_SW_DEBUG_MODE_MASK) >> MAC_PCU_DIAG_SW_DEBUG_MODE_LSB)
+#define MAC_PCU_DIAG_SW_DEBUG_MODE_SET(x) (((x) << MAC_PCU_DIAG_SW_DEBUG_MODE_LSB) & MAC_PCU_DIAG_SW_DEBUG_MODE_MASK)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MSB 29
+#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB 29
+#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK 0x20000000
+#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_GET(x) (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_SET(x) (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MSB 28
+#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB 28
+#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK 0x10000000
+#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_GET(x) (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_SET(x) (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK)
+#define MAC_PCU_DIAG_SW_OBS_SEL_2_MSB 27
+#define MAC_PCU_DIAG_SW_OBS_SEL_2_LSB 27
+#define MAC_PCU_DIAG_SW_OBS_SEL_2_MASK 0x08000000
+#define MAC_PCU_DIAG_SW_OBS_SEL_2_GET(x) (((x) & MAC_PCU_DIAG_SW_OBS_SEL_2_MASK) >> MAC_PCU_DIAG_SW_OBS_SEL_2_LSB)
+#define MAC_PCU_DIAG_SW_OBS_SEL_2_SET(x) (((x) << MAC_PCU_DIAG_SW_OBS_SEL_2_LSB) & MAC_PCU_DIAG_SW_OBS_SEL_2_MASK)
+#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MSB 26
+#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB 26
+#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK 0x04000000
+#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_GET(x) (((x) & MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK) >> MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB)
+#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_SET(x) (((x) << MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB) & MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK)
+#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MSB 25
+#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB 25
+#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK 0x02000000
+#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_GET(x) (((x) & MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK) >> MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB)
+#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_SET(x) (((x) << MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB) & MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK)
+#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MSB 24
+#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB 24
+#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK 0x01000000
+#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_GET(x) (((x) & MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK) >> MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB)
+#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_SET(x) (((x) << MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB) & MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK)
+#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MSB 23
+#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB 23
+#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK 0x00800000
+#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_GET(x) (((x) & MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK) >> MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB)
+#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_SET(x) (((x) << MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB) & MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK)
+#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MSB 22
+#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB 22
+#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK 0x00400000
+#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_GET(x) (((x) & MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK) >> MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB)
+#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_SET(x) (((x) << MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB) & MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK)
+#define MAC_PCU_DIAG_SW_IGNORE_NAV_MSB 21
+#define MAC_PCU_DIAG_SW_IGNORE_NAV_LSB 21
+#define MAC_PCU_DIAG_SW_IGNORE_NAV_MASK 0x00200000
+#define MAC_PCU_DIAG_SW_IGNORE_NAV_GET(x) (((x) & MAC_PCU_DIAG_SW_IGNORE_NAV_MASK) >> MAC_PCU_DIAG_SW_IGNORE_NAV_LSB)
+#define MAC_PCU_DIAG_SW_IGNORE_NAV_SET(x) (((x) << MAC_PCU_DIAG_SW_IGNORE_NAV_LSB) & MAC_PCU_DIAG_SW_IGNORE_NAV_MASK)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MSB 20
+#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB 20
+#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK 0x00100000
+#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_GET(x) (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB)
+#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_SET(x) (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK)
+#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_MSB 19
+#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB 18
+#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK 0x000c0000
+#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_GET(x) (((x) & MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK) >> MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB)
+#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_SET(x) (((x) << MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB) & MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK)
+#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MSB 17
+#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB 17
+#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK 0x00020000
+#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_GET(x) (((x) & MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK) >> MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB)
+#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_SET(x) (((x) << MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB) & MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK)
+#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MSB 8
+#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB 8
+#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK 0x00000100
+#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_GET(x) (((x) & MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK) >> MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB)
+#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_SET(x) (((x) << MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB) & MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK)
+#define MAC_PCU_DIAG_SW_CORRUPT_FCS_MSB 7
+#define MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB 7
+#define MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK 0x00000080
+#define MAC_PCU_DIAG_SW_CORRUPT_FCS_GET(x) (((x) & MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK) >> MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB)
+#define MAC_PCU_DIAG_SW_CORRUPT_FCS_SET(x) (((x) << MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB) & MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK)
+#define MAC_PCU_DIAG_SW_LOOP_BACK_MSB 6
+#define MAC_PCU_DIAG_SW_LOOP_BACK_LSB 6
+#define MAC_PCU_DIAG_SW_LOOP_BACK_MASK 0x00000040
+#define MAC_PCU_DIAG_SW_LOOP_BACK_GET(x) (((x) & MAC_PCU_DIAG_SW_LOOP_BACK_MASK) >> MAC_PCU_DIAG_SW_LOOP_BACK_LSB)
+#define MAC_PCU_DIAG_SW_LOOP_BACK_SET(x) (((x) << MAC_PCU_DIAG_SW_LOOP_BACK_LSB) & MAC_PCU_DIAG_SW_LOOP_BACK_MASK)
+#define MAC_PCU_DIAG_SW_HALT_RX_MSB 5
+#define MAC_PCU_DIAG_SW_HALT_RX_LSB 5
+#define MAC_PCU_DIAG_SW_HALT_RX_MASK 0x00000020
+#define MAC_PCU_DIAG_SW_HALT_RX_GET(x) (((x) & MAC_PCU_DIAG_SW_HALT_RX_MASK) >> MAC_PCU_DIAG_SW_HALT_RX_LSB)
+#define MAC_PCU_DIAG_SW_HALT_RX_SET(x) (((x) << MAC_PCU_DIAG_SW_HALT_RX_LSB) & MAC_PCU_DIAG_SW_HALT_RX_MASK)
+#define MAC_PCU_DIAG_SW_NO_DECRYPT_MSB 4
+#define MAC_PCU_DIAG_SW_NO_DECRYPT_LSB 4
+#define MAC_PCU_DIAG_SW_NO_DECRYPT_MASK 0x00000010
+#define MAC_PCU_DIAG_SW_NO_DECRYPT_GET(x) (((x) & MAC_PCU_DIAG_SW_NO_DECRYPT_MASK) >> MAC_PCU_DIAG_SW_NO_DECRYPT_LSB)
+#define MAC_PCU_DIAG_SW_NO_DECRYPT_SET(x) (((x) << MAC_PCU_DIAG_SW_NO_DECRYPT_LSB) & MAC_PCU_DIAG_SW_NO_DECRYPT_MASK)
+#define MAC_PCU_DIAG_SW_NO_ENCRYPT_MSB 3
+#define MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB 3
+#define MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK 0x00000008
+#define MAC_PCU_DIAG_SW_NO_ENCRYPT_GET(x) (((x) & MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK) >> MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB)
+#define MAC_PCU_DIAG_SW_NO_ENCRYPT_SET(x) (((x) << MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB) & MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK)
+#define MAC_PCU_DIAG_SW_NO_CTS_MSB 2
+#define MAC_PCU_DIAG_SW_NO_CTS_LSB 2
+#define MAC_PCU_DIAG_SW_NO_CTS_MASK 0x00000004
+#define MAC_PCU_DIAG_SW_NO_CTS_GET(x) (((x) & MAC_PCU_DIAG_SW_NO_CTS_MASK) >> MAC_PCU_DIAG_SW_NO_CTS_LSB)
+#define MAC_PCU_DIAG_SW_NO_CTS_SET(x) (((x) << MAC_PCU_DIAG_SW_NO_CTS_LSB) & MAC_PCU_DIAG_SW_NO_CTS_MASK)
+#define MAC_PCU_DIAG_SW_NO_ACK_MSB 1
+#define MAC_PCU_DIAG_SW_NO_ACK_LSB 1
+#define MAC_PCU_DIAG_SW_NO_ACK_MASK 0x00000002
+#define MAC_PCU_DIAG_SW_NO_ACK_GET(x) (((x) & MAC_PCU_DIAG_SW_NO_ACK_MASK) >> MAC_PCU_DIAG_SW_NO_ACK_LSB)
+#define MAC_PCU_DIAG_SW_NO_ACK_SET(x) (((x) << MAC_PCU_DIAG_SW_NO_ACK_LSB) & MAC_PCU_DIAG_SW_NO_ACK_MASK)
+#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MSB 0
+#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB 0
+#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK 0x00000001
+#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_GET(x) (((x) & MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK) >> MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB)
+#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_SET(x) (((x) << MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB) & MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK)
+
+#define MAC_PCU_TST_ADDAC_ADDRESS 0x00008034
+#define MAC_PCU_TST_ADDAC_OFFSET 0x00000034
+#define MAC_PCU_TST_ADDAC_TEST_ARM_MSB 20
+#define MAC_PCU_TST_ADDAC_TEST_ARM_LSB 20
+#define MAC_PCU_TST_ADDAC_TEST_ARM_MASK 0x00100000
+#define MAC_PCU_TST_ADDAC_TEST_ARM_GET(x) (((x) & MAC_PCU_TST_ADDAC_TEST_ARM_MASK) >> MAC_PCU_TST_ADDAC_TEST_ARM_LSB)
+#define MAC_PCU_TST_ADDAC_TEST_ARM_SET(x) (((x) << MAC_PCU_TST_ADDAC_TEST_ARM_LSB) & MAC_PCU_TST_ADDAC_TEST_ARM_MASK)
+#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_MSB 19
+#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB 19
+#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK 0x00080000
+#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_GET(x) (((x) & MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK) >> MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB)
+#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_SET(x) (((x) << MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB) & MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK)
+#define MAC_PCU_TST_ADDAC_CONT_TEST_MSB 18
+#define MAC_PCU_TST_ADDAC_CONT_TEST_LSB 18
+#define MAC_PCU_TST_ADDAC_CONT_TEST_MASK 0x00040000
+#define MAC_PCU_TST_ADDAC_CONT_TEST_GET(x) (((x) & MAC_PCU_TST_ADDAC_CONT_TEST_MASK) >> MAC_PCU_TST_ADDAC_CONT_TEST_LSB)
+#define MAC_PCU_TST_ADDAC_CONT_TEST_SET(x) (((x) << MAC_PCU_TST_ADDAC_CONT_TEST_LSB) & MAC_PCU_TST_ADDAC_CONT_TEST_MASK)
+#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_MSB 17
+#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB 17
+#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK 0x00020000
+#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_GET(x) (((x) & MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK) >> MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB)
+#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_SET(x) (((x) << MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB) & MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK)
+#define MAC_PCU_TST_ADDAC_TRIG_SEL_MSB 16
+#define MAC_PCU_TST_ADDAC_TRIG_SEL_LSB 16
+#define MAC_PCU_TST_ADDAC_TRIG_SEL_MASK 0x00010000
+#define MAC_PCU_TST_ADDAC_TRIG_SEL_GET(x) (((x) & MAC_PCU_TST_ADDAC_TRIG_SEL_MASK) >> MAC_PCU_TST_ADDAC_TRIG_SEL_LSB)
+#define MAC_PCU_TST_ADDAC_TRIG_SEL_SET(x) (((x) << MAC_PCU_TST_ADDAC_TRIG_SEL_LSB) & MAC_PCU_TST_ADDAC_TRIG_SEL_MASK)
+#define MAC_PCU_TST_ADDAC_UPPER_8B_MSB 14
+#define MAC_PCU_TST_ADDAC_UPPER_8B_LSB 14
+#define MAC_PCU_TST_ADDAC_UPPER_8B_MASK 0x00004000
+#define MAC_PCU_TST_ADDAC_UPPER_8B_GET(x) (((x) & MAC_PCU_TST_ADDAC_UPPER_8B_MASK) >> MAC_PCU_TST_ADDAC_UPPER_8B_LSB)
+#define MAC_PCU_TST_ADDAC_UPPER_8B_SET(x) (((x) << MAC_PCU_TST_ADDAC_UPPER_8B_LSB) & MAC_PCU_TST_ADDAC_UPPER_8B_MASK)
+#define MAC_PCU_TST_ADDAC_LOOP_LEN_MSB 13
+#define MAC_PCU_TST_ADDAC_LOOP_LEN_LSB 3
+#define MAC_PCU_TST_ADDAC_LOOP_LEN_MASK 0x00003ff8
+#define MAC_PCU_TST_ADDAC_LOOP_LEN_GET(x) (((x) & MAC_PCU_TST_ADDAC_LOOP_LEN_MASK) >> MAC_PCU_TST_ADDAC_LOOP_LEN_LSB)
+#define MAC_PCU_TST_ADDAC_LOOP_LEN_SET(x) (((x) << MAC_PCU_TST_ADDAC_LOOP_LEN_LSB) & MAC_PCU_TST_ADDAC_LOOP_LEN_MASK)
+#define MAC_PCU_TST_ADDAC_LOOP_MSB 2
+#define MAC_PCU_TST_ADDAC_LOOP_LSB 2
+#define MAC_PCU_TST_ADDAC_LOOP_MASK 0x00000004
+#define MAC_PCU_TST_ADDAC_LOOP_GET(x) (((x) & MAC_PCU_TST_ADDAC_LOOP_MASK) >> MAC_PCU_TST_ADDAC_LOOP_LSB)
+#define MAC_PCU_TST_ADDAC_LOOP_SET(x) (((x) << MAC_PCU_TST_ADDAC_LOOP_LSB) & MAC_PCU_TST_ADDAC_LOOP_MASK)
+#define MAC_PCU_TST_ADDAC_TESTMODE_MSB 1
+#define MAC_PCU_TST_ADDAC_TESTMODE_LSB 1
+#define MAC_PCU_TST_ADDAC_TESTMODE_MASK 0x00000002
+#define MAC_PCU_TST_ADDAC_TESTMODE_GET(x) (((x) & MAC_PCU_TST_ADDAC_TESTMODE_MASK) >> MAC_PCU_TST_ADDAC_TESTMODE_LSB)
+#define MAC_PCU_TST_ADDAC_TESTMODE_SET(x) (((x) << MAC_PCU_TST_ADDAC_TESTMODE_LSB) & MAC_PCU_TST_ADDAC_TESTMODE_MASK)
+#define MAC_PCU_TST_ADDAC_CONT_TX_MSB 0
+#define MAC_PCU_TST_ADDAC_CONT_TX_LSB 0
+#define MAC_PCU_TST_ADDAC_CONT_TX_MASK 0x00000001
+#define MAC_PCU_TST_ADDAC_CONT_TX_GET(x) (((x) & MAC_PCU_TST_ADDAC_CONT_TX_MASK) >> MAC_PCU_TST_ADDAC_CONT_TX_LSB)
+#define MAC_PCU_TST_ADDAC_CONT_TX_SET(x) (((x) << MAC_PCU_TST_ADDAC_CONT_TX_LSB) & MAC_PCU_TST_ADDAC_CONT_TX_MASK)
+
+#define MAC_PCU_DEF_ANTENNA_ADDRESS 0x00008038
+#define MAC_PCU_DEF_ANTENNA_OFFSET 0x00000038
+#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MSB 28
+#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB 28
+#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK 0x10000000
+#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_GET(x) (((x) & MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK) >> MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB)
+#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_SET(x) (((x) << MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB) & MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK)
+#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MSB 24
+#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB 24
+#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK 0x01000000
+#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_GET(x) (((x) & MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK) >> MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB)
+#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_SET(x) (((x) << MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB) & MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK)
+#define MAC_PCU_DEF_ANTENNA_VALUE_MSB 23
+#define MAC_PCU_DEF_ANTENNA_VALUE_LSB 0
+#define MAC_PCU_DEF_ANTENNA_VALUE_MASK 0x00ffffff
+#define MAC_PCU_DEF_ANTENNA_VALUE_GET(x) (((x) & MAC_PCU_DEF_ANTENNA_VALUE_MASK) >> MAC_PCU_DEF_ANTENNA_VALUE_LSB)
+#define MAC_PCU_DEF_ANTENNA_VALUE_SET(x) (((x) << MAC_PCU_DEF_ANTENNA_VALUE_LSB) & MAC_PCU_DEF_ANTENNA_VALUE_MASK)
+
+#define MAC_PCU_AES_MUTE_MASK_0_ADDRESS 0x0000803c
+#define MAC_PCU_AES_MUTE_MASK_0_OFFSET 0x0000003c
+#define MAC_PCU_AES_MUTE_MASK_0_QOS_MSB 31
+#define MAC_PCU_AES_MUTE_MASK_0_QOS_LSB 16
+#define MAC_PCU_AES_MUTE_MASK_0_QOS_MASK 0xffff0000
+#define MAC_PCU_AES_MUTE_MASK_0_QOS_GET(x) (((x) & MAC_PCU_AES_MUTE_MASK_0_QOS_MASK) >> MAC_PCU_AES_MUTE_MASK_0_QOS_LSB)
+#define MAC_PCU_AES_MUTE_MASK_0_QOS_SET(x) (((x) << MAC_PCU_AES_MUTE_MASK_0_QOS_LSB) & MAC_PCU_AES_MUTE_MASK_0_QOS_MASK)
+#define MAC_PCU_AES_MUTE_MASK_0_FC_MSB 15
+#define MAC_PCU_AES_MUTE_MASK_0_FC_LSB 0
+#define MAC_PCU_AES_MUTE_MASK_0_FC_MASK 0x0000ffff
+#define MAC_PCU_AES_MUTE_MASK_0_FC_GET(x) (((x) & MAC_PCU_AES_MUTE_MASK_0_FC_MASK) >> MAC_PCU_AES_MUTE_MASK_0_FC_LSB)
+#define MAC_PCU_AES_MUTE_MASK_0_FC_SET(x) (((x) << MAC_PCU_AES_MUTE_MASK_0_FC_LSB) & MAC_PCU_AES_MUTE_MASK_0_FC_MASK)
+
+#define MAC_PCU_AES_MUTE_MASK_1_ADDRESS 0x00008040
+#define MAC_PCU_AES_MUTE_MASK_1_OFFSET 0x00000040
+#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MSB 31
+#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB 16
+#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK 0xffff0000
+#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_GET(x) (((x) & MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK) >> MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB)
+#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_SET(x) (((x) << MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB) & MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK)
+#define MAC_PCU_AES_MUTE_MASK_1_SEQ_MSB 15
+#define MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB 0
+#define MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK 0x0000ffff
+#define MAC_PCU_AES_MUTE_MASK_1_SEQ_GET(x) (((x) & MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK) >> MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB)
+#define MAC_PCU_AES_MUTE_MASK_1_SEQ_SET(x) (((x) << MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB) & MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK)
+
+#define MAC_PCU_GATED_CLKS_ADDRESS 0x00008044
+#define MAC_PCU_GATED_CLKS_OFFSET 0x00000044
+#define MAC_PCU_GATED_CLKS_GATED_REG_MSB 3
+#define MAC_PCU_GATED_CLKS_GATED_REG_LSB 3
+#define MAC_PCU_GATED_CLKS_GATED_REG_MASK 0x00000008
+#define MAC_PCU_GATED_CLKS_GATED_REG_GET(x) (((x) & MAC_PCU_GATED_CLKS_GATED_REG_MASK) >> MAC_PCU_GATED_CLKS_GATED_REG_LSB)
+#define MAC_PCU_GATED_CLKS_GATED_REG_SET(x) (((x) << MAC_PCU_GATED_CLKS_GATED_REG_LSB) & MAC_PCU_GATED_CLKS_GATED_REG_MASK)
+#define MAC_PCU_GATED_CLKS_GATED_RX_MSB 2
+#define MAC_PCU_GATED_CLKS_GATED_RX_LSB 2
+#define MAC_PCU_GATED_CLKS_GATED_RX_MASK 0x00000004
+#define MAC_PCU_GATED_CLKS_GATED_RX_GET(x) (((x) & MAC_PCU_GATED_CLKS_GATED_RX_MASK) >> MAC_PCU_GATED_CLKS_GATED_RX_LSB)
+#define MAC_PCU_GATED_CLKS_GATED_RX_SET(x) (((x) << MAC_PCU_GATED_CLKS_GATED_RX_LSB) & MAC_PCU_GATED_CLKS_GATED_RX_MASK)
+#define MAC_PCU_GATED_CLKS_GATED_TX_MSB 1
+#define MAC_PCU_GATED_CLKS_GATED_TX_LSB 1
+#define MAC_PCU_GATED_CLKS_GATED_TX_MASK 0x00000002
+#define MAC_PCU_GATED_CLKS_GATED_TX_GET(x) (((x) & MAC_PCU_GATED_CLKS_GATED_TX_MASK) >> MAC_PCU_GATED_CLKS_GATED_TX_LSB)
+#define MAC_PCU_GATED_CLKS_GATED_TX_SET(x) (((x) << MAC_PCU_GATED_CLKS_GATED_TX_LSB) & MAC_PCU_GATED_CLKS_GATED_TX_MASK)
+
+#define MAC_PCU_OBS_BUS_2_ADDRESS 0x00008048
+#define MAC_PCU_OBS_BUS_2_OFFSET 0x00000048
+#define MAC_PCU_OBS_BUS_2_VALUE_MSB 17
+#define MAC_PCU_OBS_BUS_2_VALUE_LSB 0
+#define MAC_PCU_OBS_BUS_2_VALUE_MASK 0x0003ffff
+#define MAC_PCU_OBS_BUS_2_VALUE_GET(x) (((x) & MAC_PCU_OBS_BUS_2_VALUE_MASK) >> MAC_PCU_OBS_BUS_2_VALUE_LSB)
+#define MAC_PCU_OBS_BUS_2_VALUE_SET(x) (((x) << MAC_PCU_OBS_BUS_2_VALUE_LSB) & MAC_PCU_OBS_BUS_2_VALUE_MASK)
+
+#define MAC_PCU_OBS_BUS_1_ADDRESS 0x0000804c
+#define MAC_PCU_OBS_BUS_1_OFFSET 0x0000004c
+#define MAC_PCU_OBS_BUS_1_TX_STATE_MSB 30
+#define MAC_PCU_OBS_BUS_1_TX_STATE_LSB 25
+#define MAC_PCU_OBS_BUS_1_TX_STATE_MASK 0x7e000000
+#define MAC_PCU_OBS_BUS_1_TX_STATE_GET(x) (((x) & MAC_PCU_OBS_BUS_1_TX_STATE_MASK) >> MAC_PCU_OBS_BUS_1_TX_STATE_LSB)
+#define MAC_PCU_OBS_BUS_1_TX_STATE_SET(x) (((x) << MAC_PCU_OBS_BUS_1_TX_STATE_LSB) & MAC_PCU_OBS_BUS_1_TX_STATE_MASK)
+#define MAC_PCU_OBS_BUS_1_RX_STATE_MSB 24
+#define MAC_PCU_OBS_BUS_1_RX_STATE_LSB 20
+#define MAC_PCU_OBS_BUS_1_RX_STATE_MASK 0x01f00000
+#define MAC_PCU_OBS_BUS_1_RX_STATE_GET(x) (((x) & MAC_PCU_OBS_BUS_1_RX_STATE_MASK) >> MAC_PCU_OBS_BUS_1_RX_STATE_LSB)
+#define MAC_PCU_OBS_BUS_1_RX_STATE_SET(x) (((x) << MAC_PCU_OBS_BUS_1_RX_STATE_LSB) & MAC_PCU_OBS_BUS_1_RX_STATE_MASK)
+#define MAC_PCU_OBS_BUS_1_WEP_STATE_MSB 17
+#define MAC_PCU_OBS_BUS_1_WEP_STATE_LSB 12
+#define MAC_PCU_OBS_BUS_1_WEP_STATE_MASK 0x0003f000
+#define MAC_PCU_OBS_BUS_1_WEP_STATE_GET(x) (((x) & MAC_PCU_OBS_BUS_1_WEP_STATE_MASK) >> MAC_PCU_OBS_BUS_1_WEP_STATE_LSB)
+#define MAC_PCU_OBS_BUS_1_WEP_STATE_SET(x) (((x) << MAC_PCU_OBS_BUS_1_WEP_STATE_LSB) & MAC_PCU_OBS_BUS_1_WEP_STATE_MASK)
+#define MAC_PCU_OBS_BUS_1_RX_CLEAR_MSB 11
+#define MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB 11
+#define MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK 0x00000800
+#define MAC_PCU_OBS_BUS_1_RX_CLEAR_GET(x) (((x) & MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK) >> MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB)
+#define MAC_PCU_OBS_BUS_1_RX_CLEAR_SET(x) (((x) << MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB) & MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK)
+#define MAC_PCU_OBS_BUS_1_RX_FRAME_MSB 10
+#define MAC_PCU_OBS_BUS_1_RX_FRAME_LSB 10
+#define MAC_PCU_OBS_BUS_1_RX_FRAME_MASK 0x00000400
+#define MAC_PCU_OBS_BUS_1_RX_FRAME_GET(x) (((x) & MAC_PCU_OBS_BUS_1_RX_FRAME_MASK) >> MAC_PCU_OBS_BUS_1_RX_FRAME_LSB)
+#define MAC_PCU_OBS_BUS_1_RX_FRAME_SET(x) (((x) << MAC_PCU_OBS_BUS_1_RX_FRAME_LSB) & MAC_PCU_OBS_BUS_1_RX_FRAME_MASK)
+#define MAC_PCU_OBS_BUS_1_TX_FRAME_MSB 9
+#define MAC_PCU_OBS_BUS_1_TX_FRAME_LSB 9
+#define MAC_PCU_OBS_BUS_1_TX_FRAME_MASK 0x00000200
+#define MAC_PCU_OBS_BUS_1_TX_FRAME_GET(x) (((x) & MAC_PCU_OBS_BUS_1_TX_FRAME_MASK) >> MAC_PCU_OBS_BUS_1_TX_FRAME_LSB)
+#define MAC_PCU_OBS_BUS_1_TX_FRAME_SET(x) (((x) << MAC_PCU_OBS_BUS_1_TX_FRAME_LSB) & MAC_PCU_OBS_BUS_1_TX_FRAME_MASK)
+#define MAC_PCU_OBS_BUS_1_TX_HOLD_MSB 8
+#define MAC_PCU_OBS_BUS_1_TX_HOLD_LSB 8
+#define MAC_PCU_OBS_BUS_1_TX_HOLD_MASK 0x00000100
+#define MAC_PCU_OBS_BUS_1_TX_HOLD_GET(x) (((x) & MAC_PCU_OBS_BUS_1_TX_HOLD_MASK) >> MAC_PCU_OBS_BUS_1_TX_HOLD_LSB)
+#define MAC_PCU_OBS_BUS_1_TX_HOLD_SET(x) (((x) << MAC_PCU_OBS_BUS_1_TX_HOLD_LSB) & MAC_PCU_OBS_BUS_1_TX_HOLD_MASK)
+#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MSB 7
+#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB 7
+#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK 0x00000080
+#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_GET(x) (((x) & MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK) >> MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB)
+#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_SET(x) (((x) << MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB) & MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK)
+#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MSB 6
+#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB 6
+#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK 0x00000040
+#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_GET(x) (((x) & MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK) >> MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB)
+#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_SET(x) (((x) << MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB) & MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK)
+#define MAC_PCU_OBS_BUS_1_TX_HCF_MSB 5
+#define MAC_PCU_OBS_BUS_1_TX_HCF_LSB 5
+#define MAC_PCU_OBS_BUS_1_TX_HCF_MASK 0x00000020
+#define MAC_PCU_OBS_BUS_1_TX_HCF_GET(x) (((x) & MAC_PCU_OBS_BUS_1_TX_HCF_MASK) >> MAC_PCU_OBS_BUS_1_TX_HCF_LSB)
+#define MAC_PCU_OBS_BUS_1_TX_HCF_SET(x) (((x) << MAC_PCU_OBS_BUS_1_TX_HCF_LSB) & MAC_PCU_OBS_BUS_1_TX_HCF_MASK)
+#define MAC_PCU_OBS_BUS_1_FILTER_PASS_MSB 4
+#define MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB 4
+#define MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK 0x00000010
+#define MAC_PCU_OBS_BUS_1_FILTER_PASS_GET(x) (((x) & MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK) >> MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB)
+#define MAC_PCU_OBS_BUS_1_FILTER_PASS_SET(x) (((x) << MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB) & MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK)
+#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MSB 3
+#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB 3
+#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK 0x00000008
+#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_GET(x) (((x) & MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK) >> MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB)
+#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_SET(x) (((x) << MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB) & MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK)
+#define MAC_PCU_OBS_BUS_1_RX_WEP_MSB 2
+#define MAC_PCU_OBS_BUS_1_RX_WEP_LSB 2
+#define MAC_PCU_OBS_BUS_1_RX_WEP_MASK 0x00000004
+#define MAC_PCU_OBS_BUS_1_RX_WEP_GET(x) (((x) & MAC_PCU_OBS_BUS_1_RX_WEP_MASK) >> MAC_PCU_OBS_BUS_1_RX_WEP_LSB)
+#define MAC_PCU_OBS_BUS_1_RX_WEP_SET(x) (((x) << MAC_PCU_OBS_BUS_1_RX_WEP_LSB) & MAC_PCU_OBS_BUS_1_RX_WEP_MASK)
+#define MAC_PCU_OBS_BUS_1_PCU_RX_END_MSB 1
+#define MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB 1
+#define MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK 0x00000002
+#define MAC_PCU_OBS_BUS_1_PCU_RX_END_GET(x) (((x) & MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK) >> MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB)
+#define MAC_PCU_OBS_BUS_1_PCU_RX_END_SET(x) (((x) << MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB) & MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK)
+#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MSB 0
+#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB 0
+#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK 0x00000001
+#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_GET(x) (((x) & MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK) >> MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB)
+#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_SET(x) (((x) << MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB) & MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK)
+
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_ADDRESS 0x00008050
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_OFFSET 0x00000050
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MSB 10
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB 8
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK 0x00000700
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MSB 6
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB 4
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK 0x00000070
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MSB 2
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB 2
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK 0x00000004
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MSB 1
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB 1
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK 0x00000002
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MSB 0
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB 0
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK 0x00000001
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB)
+#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK)
+
+#define MAC_PCU_LAST_BEACON_TSF_ADDRESS 0x00008054
+#define MAC_PCU_LAST_BEACON_TSF_OFFSET 0x00000054
+#define MAC_PCU_LAST_BEACON_TSF_VALUE_MSB 31
+#define MAC_PCU_LAST_BEACON_TSF_VALUE_LSB 0
+#define MAC_PCU_LAST_BEACON_TSF_VALUE_MASK 0xffffffff
+#define MAC_PCU_LAST_BEACON_TSF_VALUE_GET(x) (((x) & MAC_PCU_LAST_BEACON_TSF_VALUE_MASK) >> MAC_PCU_LAST_BEACON_TSF_VALUE_LSB)
+#define MAC_PCU_LAST_BEACON_TSF_VALUE_SET(x) (((x) << MAC_PCU_LAST_BEACON_TSF_VALUE_LSB) & MAC_PCU_LAST_BEACON_TSF_VALUE_MASK)
+
+#define MAC_PCU_NAV_ADDRESS 0x00008058
+#define MAC_PCU_NAV_OFFSET 0x00000058
+#define MAC_PCU_NAV_VALUE_MSB 25
+#define MAC_PCU_NAV_VALUE_LSB 0
+#define MAC_PCU_NAV_VALUE_MASK 0x03ffffff
+#define MAC_PCU_NAV_VALUE_GET(x) (((x) & MAC_PCU_NAV_VALUE_MASK) >> MAC_PCU_NAV_VALUE_LSB)
+#define MAC_PCU_NAV_VALUE_SET(x) (((x) << MAC_PCU_NAV_VALUE_LSB) & MAC_PCU_NAV_VALUE_MASK)
+
+#define MAC_PCU_RTS_SUCCESS_CNT_ADDRESS 0x0000805c
+#define MAC_PCU_RTS_SUCCESS_CNT_OFFSET 0x0000005c
+#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_MSB 15
+#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB 0
+#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_GET(x) (((x) & MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK) >> MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB)
+#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_SET(x) (((x) << MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB) & MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK)
+
+#define MAC_PCU_RTS_FAIL_CNT_ADDRESS 0x00008060
+#define MAC_PCU_RTS_FAIL_CNT_OFFSET 0x00000060
+#define MAC_PCU_RTS_FAIL_CNT_VALUE_MSB 15
+#define MAC_PCU_RTS_FAIL_CNT_VALUE_LSB 0
+#define MAC_PCU_RTS_FAIL_CNT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_RTS_FAIL_CNT_VALUE_GET(x) (((x) & MAC_PCU_RTS_FAIL_CNT_VALUE_MASK) >> MAC_PCU_RTS_FAIL_CNT_VALUE_LSB)
+#define MAC_PCU_RTS_FAIL_CNT_VALUE_SET(x) (((x) << MAC_PCU_RTS_FAIL_CNT_VALUE_LSB) & MAC_PCU_RTS_FAIL_CNT_VALUE_MASK)
+
+#define MAC_PCU_ACK_FAIL_CNT_ADDRESS 0x00008064
+#define MAC_PCU_ACK_FAIL_CNT_OFFSET 0x00000064
+#define MAC_PCU_ACK_FAIL_CNT_VALUE_MSB 15
+#define MAC_PCU_ACK_FAIL_CNT_VALUE_LSB 0
+#define MAC_PCU_ACK_FAIL_CNT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_ACK_FAIL_CNT_VALUE_GET(x) (((x) & MAC_PCU_ACK_FAIL_CNT_VALUE_MASK) >> MAC_PCU_ACK_FAIL_CNT_VALUE_LSB)
+#define MAC_PCU_ACK_FAIL_CNT_VALUE_SET(x) (((x) << MAC_PCU_ACK_FAIL_CNT_VALUE_LSB) & MAC_PCU_ACK_FAIL_CNT_VALUE_MASK)
+
+#define MAC_PCU_FCS_FAIL_CNT_ADDRESS 0x00008068
+#define MAC_PCU_FCS_FAIL_CNT_OFFSET 0x00000068
+#define MAC_PCU_FCS_FAIL_CNT_VALUE_MSB 15
+#define MAC_PCU_FCS_FAIL_CNT_VALUE_LSB 0
+#define MAC_PCU_FCS_FAIL_CNT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_FCS_FAIL_CNT_VALUE_GET(x) (((x) & MAC_PCU_FCS_FAIL_CNT_VALUE_MASK) >> MAC_PCU_FCS_FAIL_CNT_VALUE_LSB)
+#define MAC_PCU_FCS_FAIL_CNT_VALUE_SET(x) (((x) << MAC_PCU_FCS_FAIL_CNT_VALUE_LSB) & MAC_PCU_FCS_FAIL_CNT_VALUE_MASK)
+
+#define MAC_PCU_BEACON_CNT_ADDRESS 0x0000806c
+#define MAC_PCU_BEACON_CNT_OFFSET 0x0000006c
+#define MAC_PCU_BEACON_CNT_VALUE_MSB 15
+#define MAC_PCU_BEACON_CNT_VALUE_LSB 0
+#define MAC_PCU_BEACON_CNT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_BEACON_CNT_VALUE_GET(x) (((x) & MAC_PCU_BEACON_CNT_VALUE_MASK) >> MAC_PCU_BEACON_CNT_VALUE_LSB)
+#define MAC_PCU_BEACON_CNT_VALUE_SET(x) (((x) << MAC_PCU_BEACON_CNT_VALUE_LSB) & MAC_PCU_BEACON_CNT_VALUE_MASK)
+
+#define MAC_PCU_XRMODE_ADDRESS 0x00008070
+#define MAC_PCU_XRMODE_OFFSET 0x00000070
+#define MAC_PCU_XRMODE_FRAME_HOLD_MSB 31
+#define MAC_PCU_XRMODE_FRAME_HOLD_LSB 20
+#define MAC_PCU_XRMODE_FRAME_HOLD_MASK 0xfff00000
+#define MAC_PCU_XRMODE_FRAME_HOLD_GET(x) (((x) & MAC_PCU_XRMODE_FRAME_HOLD_MASK) >> MAC_PCU_XRMODE_FRAME_HOLD_LSB)
+#define MAC_PCU_XRMODE_FRAME_HOLD_SET(x) (((x) << MAC_PCU_XRMODE_FRAME_HOLD_LSB) & MAC_PCU_XRMODE_FRAME_HOLD_MASK)
+#define MAC_PCU_XRMODE_WAIT_FOR_POLL_MSB 7
+#define MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB 7
+#define MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK 0x00000080
+#define MAC_PCU_XRMODE_WAIT_FOR_POLL_GET(x) (((x) & MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK) >> MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB)
+#define MAC_PCU_XRMODE_WAIT_FOR_POLL_SET(x) (((x) << MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB) & MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK)
+#define MAC_PCU_XRMODE_POLL_TYPE_MSB 5
+#define MAC_PCU_XRMODE_POLL_TYPE_LSB 0
+#define MAC_PCU_XRMODE_POLL_TYPE_MASK 0x0000003f
+#define MAC_PCU_XRMODE_POLL_TYPE_GET(x) (((x) & MAC_PCU_XRMODE_POLL_TYPE_MASK) >> MAC_PCU_XRMODE_POLL_TYPE_LSB)
+#define MAC_PCU_XRMODE_POLL_TYPE_SET(x) (((x) << MAC_PCU_XRMODE_POLL_TYPE_LSB) & MAC_PCU_XRMODE_POLL_TYPE_MASK)
+
+#define MAC_PCU_XRDEL_ADDRESS 0x00008074
+#define MAC_PCU_XRDEL_OFFSET 0x00000074
+#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MSB 31
+#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB 16
+#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK 0xffff0000
+#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_GET(x) (((x) & MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK) >> MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB)
+#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_SET(x) (((x) << MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB) & MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK)
+#define MAC_PCU_XRDEL_SLOT_DELAY_MSB 15
+#define MAC_PCU_XRDEL_SLOT_DELAY_LSB 0
+#define MAC_PCU_XRDEL_SLOT_DELAY_MASK 0x0000ffff
+#define MAC_PCU_XRDEL_SLOT_DELAY_GET(x) (((x) & MAC_PCU_XRDEL_SLOT_DELAY_MASK) >> MAC_PCU_XRDEL_SLOT_DELAY_LSB)
+#define MAC_PCU_XRDEL_SLOT_DELAY_SET(x) (((x) << MAC_PCU_XRDEL_SLOT_DELAY_LSB) & MAC_PCU_XRDEL_SLOT_DELAY_MASK)
+
+#define MAC_PCU_XRTO_ADDRESS 0x00008078
+#define MAC_PCU_XRTO_OFFSET 0x00000078
+#define MAC_PCU_XRTO_POLL_TIMEOUT_MSB 31
+#define MAC_PCU_XRTO_POLL_TIMEOUT_LSB 16
+#define MAC_PCU_XRTO_POLL_TIMEOUT_MASK 0xffff0000
+#define MAC_PCU_XRTO_POLL_TIMEOUT_GET(x) (((x) & MAC_PCU_XRTO_POLL_TIMEOUT_MASK) >> MAC_PCU_XRTO_POLL_TIMEOUT_LSB)
+#define MAC_PCU_XRTO_POLL_TIMEOUT_SET(x) (((x) << MAC_PCU_XRTO_POLL_TIMEOUT_LSB) & MAC_PCU_XRTO_POLL_TIMEOUT_MASK)
+#define MAC_PCU_XRTO_CHIRP_TIMEOUT_MSB 15
+#define MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB 0
+#define MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK 0x0000ffff
+#define MAC_PCU_XRTO_CHIRP_TIMEOUT_GET(x) (((x) & MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK) >> MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB)
+#define MAC_PCU_XRTO_CHIRP_TIMEOUT_SET(x) (((x) << MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB) & MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK)
+
+#define MAC_PCU_XRCRP_ADDRESS 0x0000807c
+#define MAC_PCU_XRCRP_OFFSET 0x0000007c
+#define MAC_PCU_XRCRP_CHIRP_GAP_MSB 31
+#define MAC_PCU_XRCRP_CHIRP_GAP_LSB 16
+#define MAC_PCU_XRCRP_CHIRP_GAP_MASK 0xffff0000
+#define MAC_PCU_XRCRP_CHIRP_GAP_GET(x) (((x) & MAC_PCU_XRCRP_CHIRP_GAP_MASK) >> MAC_PCU_XRCRP_CHIRP_GAP_LSB)
+#define MAC_PCU_XRCRP_CHIRP_GAP_SET(x) (((x) << MAC_PCU_XRCRP_CHIRP_GAP_LSB) & MAC_PCU_XRCRP_CHIRP_GAP_MASK)
+#define MAC_PCU_XRCRP_SEND_CHIRP_MSB 0
+#define MAC_PCU_XRCRP_SEND_CHIRP_LSB 0
+#define MAC_PCU_XRCRP_SEND_CHIRP_MASK 0x00000001
+#define MAC_PCU_XRCRP_SEND_CHIRP_GET(x) (((x) & MAC_PCU_XRCRP_SEND_CHIRP_MASK) >> MAC_PCU_XRCRP_SEND_CHIRP_LSB)
+#define MAC_PCU_XRCRP_SEND_CHIRP_SET(x) (((x) << MAC_PCU_XRCRP_SEND_CHIRP_LSB) & MAC_PCU_XRCRP_SEND_CHIRP_MASK)
+
+#define MAC_PCU_XRSTMP_ADDRESS 0x00008080
+#define MAC_PCU_XRSTMP_OFFSET 0x00000080
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MSB 23
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB 16
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK 0x00ff0000
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_GET(x) (((x) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB)
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_SET(x) (((x) << MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK)
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MSB 15
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB 8
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK 0x0000ff00
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_GET(x) (((x) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB)
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_SET(x) (((x) << MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK)
+#define MAC_PCU_XRSTMP_RX_ABORT_DATA_MSB 5
+#define MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB 5
+#define MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK 0x00000020
+#define MAC_PCU_XRSTMP_RX_ABORT_DATA_GET(x) (((x) & MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB)
+#define MAC_PCU_XRSTMP_RX_ABORT_DATA_SET(x) (((x) << MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB) & MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK)
+#define MAC_PCU_XRSTMP_TX_STOMP_DATA_MSB 4
+#define MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB 4
+#define MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK 0x00000010
+#define MAC_PCU_XRSTMP_TX_STOMP_DATA_GET(x) (((x) & MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB)
+#define MAC_PCU_XRSTMP_TX_STOMP_DATA_SET(x) (((x) << MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB) & MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK)
+#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_MSB 3
+#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB 3
+#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK 0x00000008
+#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_GET(x) (((x) & MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB)
+#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_SET(x) (((x) << MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB) & MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK)
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_MSB 2
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB 2
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK 0x00000004
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_GET(x) (((x) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB)
+#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_SET(x) (((x) << MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK)
+#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_MSB 1
+#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB 1
+#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK 0x00000002
+#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_GET(x) (((x) & MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB)
+#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_SET(x) (((x) << MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB) & MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK)
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_MSB 0
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB 0
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK 0x00000001
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_GET(x) (((x) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB)
+#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_SET(x) (((x) << MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK)
+
+#define MAC_PCU_ADDR1_MASK_L32_ADDRESS 0x00008084
+#define MAC_PCU_ADDR1_MASK_L32_OFFSET 0x00000084
+#define MAC_PCU_ADDR1_MASK_L32_VALUE_MSB 31
+#define MAC_PCU_ADDR1_MASK_L32_VALUE_LSB 0
+#define MAC_PCU_ADDR1_MASK_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_ADDR1_MASK_L32_VALUE_GET(x) (((x) & MAC_PCU_ADDR1_MASK_L32_VALUE_MASK) >> MAC_PCU_ADDR1_MASK_L32_VALUE_LSB)
+#define MAC_PCU_ADDR1_MASK_L32_VALUE_SET(x) (((x) << MAC_PCU_ADDR1_MASK_L32_VALUE_LSB) & MAC_PCU_ADDR1_MASK_L32_VALUE_MASK)
+
+#define MAC_PCU_ADDR1_MASK_U16_ADDRESS 0x00008088
+#define MAC_PCU_ADDR1_MASK_U16_OFFSET 0x00000088
+#define MAC_PCU_ADDR1_MASK_U16_VALUE_MSB 15
+#define MAC_PCU_ADDR1_MASK_U16_VALUE_LSB 0
+#define MAC_PCU_ADDR1_MASK_U16_VALUE_MASK 0x0000ffff
+#define MAC_PCU_ADDR1_MASK_U16_VALUE_GET(x) (((x) & MAC_PCU_ADDR1_MASK_U16_VALUE_MASK) >> MAC_PCU_ADDR1_MASK_U16_VALUE_LSB)
+#define MAC_PCU_ADDR1_MASK_U16_VALUE_SET(x) (((x) << MAC_PCU_ADDR1_MASK_U16_VALUE_LSB) & MAC_PCU_ADDR1_MASK_U16_VALUE_MASK)
+
+#define MAC_PCU_TPC_ADDRESS 0x0000808c
+#define MAC_PCU_TPC_OFFSET 0x0000008c
+#define MAC_PCU_TPC_CHIRP_PWR_MSB 21
+#define MAC_PCU_TPC_CHIRP_PWR_LSB 16
+#define MAC_PCU_TPC_CHIRP_PWR_MASK 0x003f0000
+#define MAC_PCU_TPC_CHIRP_PWR_GET(x) (((x) & MAC_PCU_TPC_CHIRP_PWR_MASK) >> MAC_PCU_TPC_CHIRP_PWR_LSB)
+#define MAC_PCU_TPC_CHIRP_PWR_SET(x) (((x) << MAC_PCU_TPC_CHIRP_PWR_LSB) & MAC_PCU_TPC_CHIRP_PWR_MASK)
+#define MAC_PCU_TPC_CTS_PWR_MSB 13
+#define MAC_PCU_TPC_CTS_PWR_LSB 8
+#define MAC_PCU_TPC_CTS_PWR_MASK 0x00003f00
+#define MAC_PCU_TPC_CTS_PWR_GET(x) (((x) & MAC_PCU_TPC_CTS_PWR_MASK) >> MAC_PCU_TPC_CTS_PWR_LSB)
+#define MAC_PCU_TPC_CTS_PWR_SET(x) (((x) << MAC_PCU_TPC_CTS_PWR_LSB) & MAC_PCU_TPC_CTS_PWR_MASK)
+#define MAC_PCU_TPC_ACK_PWR_MSB 5
+#define MAC_PCU_TPC_ACK_PWR_LSB 0
+#define MAC_PCU_TPC_ACK_PWR_MASK 0x0000003f
+#define MAC_PCU_TPC_ACK_PWR_GET(x) (((x) & MAC_PCU_TPC_ACK_PWR_MASK) >> MAC_PCU_TPC_ACK_PWR_LSB)
+#define MAC_PCU_TPC_ACK_PWR_SET(x) (((x) << MAC_PCU_TPC_ACK_PWR_LSB) & MAC_PCU_TPC_ACK_PWR_MASK)
+
+#define MAC_PCU_TX_FRAME_CNT_ADDRESS 0x00008090
+#define MAC_PCU_TX_FRAME_CNT_OFFSET 0x00000090
+#define MAC_PCU_TX_FRAME_CNT_VALUE_MSB 31
+#define MAC_PCU_TX_FRAME_CNT_VALUE_LSB 0
+#define MAC_PCU_TX_FRAME_CNT_VALUE_MASK 0xffffffff
+#define MAC_PCU_TX_FRAME_CNT_VALUE_GET(x) (((x) & MAC_PCU_TX_FRAME_CNT_VALUE_MASK) >> MAC_PCU_TX_FRAME_CNT_VALUE_LSB)
+#define MAC_PCU_TX_FRAME_CNT_VALUE_SET(x) (((x) << MAC_PCU_TX_FRAME_CNT_VALUE_LSB) & MAC_PCU_TX_FRAME_CNT_VALUE_MASK)
+
+#define MAC_PCU_RX_FRAME_CNT_ADDRESS 0x00008094
+#define MAC_PCU_RX_FRAME_CNT_OFFSET 0x00000094
+#define MAC_PCU_RX_FRAME_CNT_VALUE_MSB 31
+#define MAC_PCU_RX_FRAME_CNT_VALUE_LSB 0
+#define MAC_PCU_RX_FRAME_CNT_VALUE_MASK 0xffffffff
+#define MAC_PCU_RX_FRAME_CNT_VALUE_GET(x) (((x) & MAC_PCU_RX_FRAME_CNT_VALUE_MASK) >> MAC_PCU_RX_FRAME_CNT_VALUE_LSB)
+#define MAC_PCU_RX_FRAME_CNT_VALUE_SET(x) (((x) << MAC_PCU_RX_FRAME_CNT_VALUE_LSB) & MAC_PCU_RX_FRAME_CNT_VALUE_MASK)
+
+#define MAC_PCU_RX_CLEAR_CNT_ADDRESS 0x00008098
+#define MAC_PCU_RX_CLEAR_CNT_OFFSET 0x00000098
+#define MAC_PCU_RX_CLEAR_CNT_VALUE_MSB 31
+#define MAC_PCU_RX_CLEAR_CNT_VALUE_LSB 0
+#define MAC_PCU_RX_CLEAR_CNT_VALUE_MASK 0xffffffff
+#define MAC_PCU_RX_CLEAR_CNT_VALUE_GET(x) (((x) & MAC_PCU_RX_CLEAR_CNT_VALUE_MASK) >> MAC_PCU_RX_CLEAR_CNT_VALUE_LSB)
+#define MAC_PCU_RX_CLEAR_CNT_VALUE_SET(x) (((x) << MAC_PCU_RX_CLEAR_CNT_VALUE_LSB) & MAC_PCU_RX_CLEAR_CNT_VALUE_MASK)
+
+#define MAC_PCU_CYCLE_CNT_ADDRESS 0x0000809c
+#define MAC_PCU_CYCLE_CNT_OFFSET 0x0000009c
+#define MAC_PCU_CYCLE_CNT_VALUE_MSB 31
+#define MAC_PCU_CYCLE_CNT_VALUE_LSB 0
+#define MAC_PCU_CYCLE_CNT_VALUE_MASK 0xffffffff
+#define MAC_PCU_CYCLE_CNT_VALUE_GET(x) (((x) & MAC_PCU_CYCLE_CNT_VALUE_MASK) >> MAC_PCU_CYCLE_CNT_VALUE_LSB)
+#define MAC_PCU_CYCLE_CNT_VALUE_SET(x) (((x) << MAC_PCU_CYCLE_CNT_VALUE_LSB) & MAC_PCU_CYCLE_CNT_VALUE_MASK)
+
+#define MAC_PCU_QUIET_TIME_1_ADDRESS 0x000080a0
+#define MAC_PCU_QUIET_TIME_1_OFFSET 0x000000a0
+#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MSB 17
+#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB 17
+#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK 0x00020000
+#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_GET(x) (((x) & MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK) >> MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB)
+#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_SET(x) (((x) << MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB) & MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK)
+
+#define MAC_PCU_QUIET_TIME_2_ADDRESS 0x000080a4
+#define MAC_PCU_QUIET_TIME_2_OFFSET 0x000000a4
+#define MAC_PCU_QUIET_TIME_2_DURATION_MSB 31
+#define MAC_PCU_QUIET_TIME_2_DURATION_LSB 16
+#define MAC_PCU_QUIET_TIME_2_DURATION_MASK 0xffff0000
+#define MAC_PCU_QUIET_TIME_2_DURATION_GET(x) (((x) & MAC_PCU_QUIET_TIME_2_DURATION_MASK) >> MAC_PCU_QUIET_TIME_2_DURATION_LSB)
+#define MAC_PCU_QUIET_TIME_2_DURATION_SET(x) (((x) << MAC_PCU_QUIET_TIME_2_DURATION_LSB) & MAC_PCU_QUIET_TIME_2_DURATION_MASK)
+
+#define MAC_PCU_QOS_NO_ACK_ADDRESS 0x000080a8
+#define MAC_PCU_QOS_NO_ACK_OFFSET 0x000000a8
+#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MSB 8
+#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB 7
+#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK 0x00000180
+#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_GET(x) (((x) & MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK) >> MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB)
+#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_SET(x) (((x) << MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB) & MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK)
+#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MSB 6
+#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB 4
+#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK 0x00000070
+#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_GET(x) (((x) & MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK) >> MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB)
+#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_SET(x) (((x) << MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB) & MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK)
+#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MSB 3
+#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB 0
+#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK 0x0000000f
+#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_GET(x) (((x) & MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK) >> MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB)
+#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_SET(x) (((x) << MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB) & MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK)
+
+#define MAC_PCU_PHY_ERROR_MASK_ADDRESS 0x000080ac
+#define MAC_PCU_PHY_ERROR_MASK_OFFSET 0x000000ac
+#define MAC_PCU_PHY_ERROR_MASK_VALUE_MSB 31
+#define MAC_PCU_PHY_ERROR_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERROR_MASK_VALUE_MASK 0xffffffff
+#define MAC_PCU_PHY_ERROR_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERROR_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_VALUE_MASK)
+
+#define MAC_PCU_XRLAT_ADDRESS 0x000080b0
+#define MAC_PCU_XRLAT_OFFSET 0x000000b0
+#define MAC_PCU_XRLAT_VALUE_MSB 11
+#define MAC_PCU_XRLAT_VALUE_LSB 0
+#define MAC_PCU_XRLAT_VALUE_MASK 0x00000fff
+#define MAC_PCU_XRLAT_VALUE_GET(x) (((x) & MAC_PCU_XRLAT_VALUE_MASK) >> MAC_PCU_XRLAT_VALUE_LSB)
+#define MAC_PCU_XRLAT_VALUE_SET(x) (((x) << MAC_PCU_XRLAT_VALUE_LSB) & MAC_PCU_XRLAT_VALUE_MASK)
+
+#define MAC_PCU_RXBUF_ADDRESS 0x000080b4
+#define MAC_PCU_RXBUF_OFFSET 0x000000b4
+#define MAC_PCU_RXBUF_REG_RD_ENABLE_MSB 11
+#define MAC_PCU_RXBUF_REG_RD_ENABLE_LSB 11
+#define MAC_PCU_RXBUF_REG_RD_ENABLE_MASK 0x00000800
+#define MAC_PCU_RXBUF_REG_RD_ENABLE_GET(x) (((x) & MAC_PCU_RXBUF_REG_RD_ENABLE_MASK) >> MAC_PCU_RXBUF_REG_RD_ENABLE_LSB)
+#define MAC_PCU_RXBUF_REG_RD_ENABLE_SET(x) (((x) << MAC_PCU_RXBUF_REG_RD_ENABLE_LSB) & MAC_PCU_RXBUF_REG_RD_ENABLE_MASK)
+#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MSB 10
+#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB 0
+#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK 0x000007ff
+#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_GET(x) (((x) & MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK) >> MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB)
+#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_SET(x) (((x) << MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB) & MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK)
+
+#define MAC_PCU_MIC_QOS_CONTROL_ADDRESS 0x000080b8
+#define MAC_PCU_MIC_QOS_CONTROL_OFFSET 0x000000b8
+#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_MSB 16
+#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB 16
+#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK 0x00010000
+#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK) >> MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB) & MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MSB 15
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB 14
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK 0x0000c000
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MSB 13
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB 12
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK 0x00003000
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MSB 11
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB 10
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK 0x00000c00
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MSB 9
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB 8
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK 0x00000300
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MSB 7
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB 6
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK 0x000000c0
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MSB 5
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB 4
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK 0x00000030
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MSB 3
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB 2
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK 0x0000000c
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MSB 1
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB 0
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK 0x00000003
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_GET(x) (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB)
+#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_SET(x) (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK)
+
+#define MAC_PCU_MIC_QOS_SELECT_ADDRESS 0x000080bc
+#define MAC_PCU_MIC_QOS_SELECT_OFFSET 0x000000bc
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_MSB 31
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB 28
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK 0xf0000000
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_MSB 27
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB 24
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK 0x0f000000
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_MSB 23
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB 20
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK 0x00f00000
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_MSB 19
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB 16
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK 0x000f0000
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_MSB 15
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB 12
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK 0x0000f000
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_MSB 11
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB 8
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK 0x00000f00
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_MSB 7
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB 4
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK 0x000000f0
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_MSB 3
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB 0
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK 0x0000000f
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_GET(x) (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB)
+#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_SET(x) (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK)
+
+#define MAC_PCU_MISC_MODE_ADDRESS 0x000080c0
+#define MAC_PCU_MISC_MODE_OFFSET 0x000000c0
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_MSB 31
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_LSB 30
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_MASK 0xc0000000
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_LSB)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_MASK)
+#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MSB 29
+#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB 29
+#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK 0x20000000
+#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_GET(x) (((x) & MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK) >> MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB)
+#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_SET(x) (((x) << MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB) & MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK)
+#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MSB 28
+#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB 28
+#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK 0x10000000
+#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_GET(x) (((x) & MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK) >> MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB)
+#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_SET(x) (((x) << MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB) & MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK)
+#define MAC_PCU_MISC_MODE_SEL_EVM_MSB 27
+#define MAC_PCU_MISC_MODE_SEL_EVM_LSB 27
+#define MAC_PCU_MISC_MODE_SEL_EVM_MASK 0x08000000
+#define MAC_PCU_MISC_MODE_SEL_EVM_GET(x) (((x) & MAC_PCU_MISC_MODE_SEL_EVM_MASK) >> MAC_PCU_MISC_MODE_SEL_EVM_LSB)
+#define MAC_PCU_MISC_MODE_SEL_EVM_SET(x) (((x) << MAC_PCU_MISC_MODE_SEL_EVM_LSB) & MAC_PCU_MISC_MODE_SEL_EVM_MASK)
+#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MSB 26
+#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB 26
+#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK 0x04000000
+#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_GET(x) (((x) & MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK) >> MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB)
+#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_SET(x) (((x) << MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB) & MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK)
+#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MSB 25
+#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB 25
+#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK 0x02000000
+#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_GET(x) (((x) & MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK) >> MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB)
+#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_SET(x) (((x) << MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB) & MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK)
+#define MAC_PCU_MISC_MODE_CLEAR_VMF_MSB 24
+#define MAC_PCU_MISC_MODE_CLEAR_VMF_LSB 24
+#define MAC_PCU_MISC_MODE_CLEAR_VMF_MASK 0x01000000
+#define MAC_PCU_MISC_MODE_CLEAR_VMF_GET(x) (((x) & MAC_PCU_MISC_MODE_CLEAR_VMF_MASK) >> MAC_PCU_MISC_MODE_CLEAR_VMF_LSB)
+#define MAC_PCU_MISC_MODE_CLEAR_VMF_SET(x) (((x) << MAC_PCU_MISC_MODE_CLEAR_VMF_LSB) & MAC_PCU_MISC_MODE_CLEAR_VMF_MASK)
+#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MSB 23
+#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB 23
+#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK 0x00800000
+#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK) >> MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB) & MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MSB 22
+#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB 22
+#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK 0x00400000
+#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_GET(x) (((x) & MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK) >> MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB)
+#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_SET(x) (((x) << MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB) & MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK)
+#define MAC_PCU_MISC_MODE_TBTT_PROTECT_MSB 21
+#define MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB 21
+#define MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK 0x00200000
+#define MAC_PCU_MISC_MODE_TBTT_PROTECT_GET(x) (((x) & MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK) >> MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB)
+#define MAC_PCU_MISC_MODE_TBTT_PROTECT_SET(x) (((x) << MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB) & MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK)
+#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MSB 20
+#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB 20
+#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK 0x00100000
+#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_GET(x) (((x) & MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK) >> MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB)
+#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_SET(x) (((x) << MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB) & MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK)
+#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MSB 18
+#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB 18
+#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK 0x00040000
+#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_GET(x) (((x) & MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK) >> MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB)
+#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_SET(x) (((x) << MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB) & MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK)
+#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MSB 14
+#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB 14
+#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK 0x00004000
+#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_GET(x) (((x) & MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK) >> MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB)
+#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_SET(x) (((x) << MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB) & MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK)
+#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MSB 12
+#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB 12
+#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK 0x00001000
+#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK) >> MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB) & MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MSB 11
+#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB 11
+#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK 0x00000800
+#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_GET(x) (((x) & MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK) >> MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB)
+#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_SET(x) (((x) << MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB) & MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MSB 10
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB 10
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK 0x00000400
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MSB 9
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB 9
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK 0x00000200
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK)
+#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MSB 4
+#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB 4
+#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK 0x00000010
+#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_GET(x) (((x) & MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK) >> MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB)
+#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_SET(x) (((x) << MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB) & MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK)
+#define MAC_PCU_MISC_MODE_TX_ADD_TSF_MSB 3
+#define MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB 3
+#define MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK 0x00000008
+#define MAC_PCU_MISC_MODE_TX_ADD_TSF_GET(x) (((x) & MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK) >> MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB)
+#define MAC_PCU_MISC_MODE_TX_ADD_TSF_SET(x) (((x) << MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB) & MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK)
+#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MSB 2
+#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB 2
+#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK 0x00000004
+#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK) >> MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB) & MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MSB 1
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB 1
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK 0x00000002
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB)
+#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK)
+#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MSB 0
+#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB 0
+#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK 0x00000001
+#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_GET(x) (((x) & MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK) >> MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB)
+#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_SET(x) (((x) << MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB) & MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK)
+
+#define MAC_PCU_FILTER_OFDM_CNT_ADDRESS 0x000080c4
+#define MAC_PCU_FILTER_OFDM_CNT_OFFSET 0x000000c4
+#define MAC_PCU_FILTER_OFDM_CNT_VALUE_MSB 23
+#define MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB 0
+#define MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK 0x00ffffff
+#define MAC_PCU_FILTER_OFDM_CNT_VALUE_GET(x) (((x) & MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK) >> MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB)
+#define MAC_PCU_FILTER_OFDM_CNT_VALUE_SET(x) (((x) << MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB) & MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK)
+
+#define MAC_PCU_FILTER_CCK_CNT_ADDRESS 0x000080c8
+#define MAC_PCU_FILTER_CCK_CNT_OFFSET 0x000000c8
+#define MAC_PCU_FILTER_CCK_CNT_VALUE_MSB 23
+#define MAC_PCU_FILTER_CCK_CNT_VALUE_LSB 0
+#define MAC_PCU_FILTER_CCK_CNT_VALUE_MASK 0x00ffffff
+#define MAC_PCU_FILTER_CCK_CNT_VALUE_GET(x) (((x) & MAC_PCU_FILTER_CCK_CNT_VALUE_MASK) >> MAC_PCU_FILTER_CCK_CNT_VALUE_LSB)
+#define MAC_PCU_FILTER_CCK_CNT_VALUE_SET(x) (((x) << MAC_PCU_FILTER_CCK_CNT_VALUE_LSB) & MAC_PCU_FILTER_CCK_CNT_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_1_ADDRESS 0x000080cc
+#define MAC_PCU_PHY_ERR_CNT_1_OFFSET 0x000000cc
+#define MAC_PCU_PHY_ERR_CNT_1_VALUE_MSB 23
+#define MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK 0x00ffffff
+#define MAC_PCU_PHY_ERR_CNT_1_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_1_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_ADDRESS 0x000080d0
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_OFFSET 0x000000d0
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MSB 31
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK 0xffffffff
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_2_ADDRESS 0x000080d4
+#define MAC_PCU_PHY_ERR_CNT_2_OFFSET 0x000000d4
+#define MAC_PCU_PHY_ERR_CNT_2_VALUE_MSB 23
+#define MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK 0x00ffffff
+#define MAC_PCU_PHY_ERR_CNT_2_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_2_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_ADDRESS 0x000080d8
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_OFFSET 0x000000d8
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MSB 31
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK 0xffffffff
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK)
+
+#define MAC_PCU_TSF_THRESHOLD_ADDRESS 0x000080dc
+#define MAC_PCU_TSF_THRESHOLD_OFFSET 0x000000dc
+#define MAC_PCU_TSF_THRESHOLD_VALUE_MSB 15
+#define MAC_PCU_TSF_THRESHOLD_VALUE_LSB 0
+#define MAC_PCU_TSF_THRESHOLD_VALUE_MASK 0x0000ffff
+#define MAC_PCU_TSF_THRESHOLD_VALUE_GET(x) (((x) & MAC_PCU_TSF_THRESHOLD_VALUE_MASK) >> MAC_PCU_TSF_THRESHOLD_VALUE_LSB)
+#define MAC_PCU_TSF_THRESHOLD_VALUE_SET(x) (((x) << MAC_PCU_TSF_THRESHOLD_VALUE_LSB) & MAC_PCU_TSF_THRESHOLD_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_ADDRESS 0x000080e0
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_OFFSET 0x000000e0
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MSB 31
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK 0xffffffff
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_3_ADDRESS 0x000080e4
+#define MAC_PCU_PHY_ERR_CNT_3_OFFSET 0x000000e4
+#define MAC_PCU_PHY_ERR_CNT_3_VALUE_MSB 23
+#define MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK 0x00ffffff
+#define MAC_PCU_PHY_ERR_CNT_3_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_3_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_ADDRESS 0x000080e8
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_OFFSET 0x000000e8
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MSB 31
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK 0xffffffff
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK)
+
+#define MAC_PCU_BLUETOOTH_MODE_ADDRESS 0x000080ec
+#define MAC_PCU_BLUETOOTH_MODE_OFFSET 0x000000ec
+#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MSB 31
+#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB 24
+#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK 0xff000000
+#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MSB 23
+#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB 18
+#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK 0x00fc0000
+#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MSB 17
+#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB 17
+#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK 0x00020000
+#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK) >> MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB) & MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MSB 16
+#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB 13
+#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK 0x0001e000
+#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK) >> MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB) & MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_QUIET_MSB 12
+#define MAC_PCU_BLUETOOTH_MODE_QUIET_LSB 12
+#define MAC_PCU_BLUETOOTH_MODE_QUIET_MASK 0x00001000
+#define MAC_PCU_BLUETOOTH_MODE_QUIET_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_QUIET_MASK) >> MAC_PCU_BLUETOOTH_MODE_QUIET_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_QUIET_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_QUIET_LSB) & MAC_PCU_BLUETOOTH_MODE_QUIET_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_MODE_MSB 11
+#define MAC_PCU_BLUETOOTH_MODE_MODE_LSB 10
+#define MAC_PCU_BLUETOOTH_MODE_MODE_MASK 0x00000c00
+#define MAC_PCU_BLUETOOTH_MODE_MODE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_MODE_MASK) >> MAC_PCU_BLUETOOTH_MODE_MODE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_MODE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_MODE_LSB) & MAC_PCU_BLUETOOTH_MODE_MODE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MSB 9
+#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB 9
+#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK 0x00000200
+#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MSB 8
+#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB 8
+#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK 0x00000100
+#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK)
+#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MSB 7
+#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB 0
+#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK 0x000000ff
+#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK)
+
+#define MAC_PCU_BLUETOOTH_WEIGHTS_ADDRESS 0x000080f0
+#define MAC_PCU_BLUETOOTH_WEIGHTS_OFFSET 0x000000f0
+#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MSB 31
+#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB 16
+#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK 0xffff0000
+#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB)
+#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK)
+#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MSB 15
+#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB 0
+#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK 0x0000ffff
+#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB)
+#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK)
+
+#define MAC_PCU_BLUETOOTH_MODE2_ADDRESS 0x000080f4
+#define MAC_PCU_BLUETOOTH_MODE2_OFFSET 0x000000f4
+#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MSB 31
+#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB 31
+#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK 0x80000000
+#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB) & MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MSB 30
+#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB 30
+#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK 0x40000000
+#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB) & MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MSB 29
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB 28
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK 0x30000000
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK) >> MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MSB 27
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB 26
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK 0x0c000000
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK) >> MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MSB 25
+#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB 25
+#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK 0x02000000
+#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MSB 24
+#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB 24
+#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK 0x01000000
+#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB) & MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MSB 23
+#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB 22
+#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK 0x00c00000
+#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB) & MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MSB 21
+#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB 21
+#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK 0x00200000
+#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB) & MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MSB 20
+#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB 20
+#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK 0x00100000
+#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK) >> MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB) & MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MSB 19
+#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB 19
+#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK 0x00080000
+#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK) >> MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB) & MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MSB 17
+#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB 17
+#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK 0x00020000
+#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK) >> MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB) & MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MSB 16
+#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB 16
+#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK 0x00010000
+#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK) >> MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB) & MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MSB 15
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB 8
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK 0x0000ff00
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK) >> MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK)
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MSB 7
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB 0
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK 0x000000ff
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK) >> MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB)
+#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK)
+
+#define MAC_PCU_TXSIFS_ADDRESS 0x000080f8
+#define MAC_PCU_TXSIFS_OFFSET 0x000000f8
+#define MAC_PCU_TXSIFS_ACK_SHIFT_MSB 14
+#define MAC_PCU_TXSIFS_ACK_SHIFT_LSB 12
+#define MAC_PCU_TXSIFS_ACK_SHIFT_MASK 0x00007000
+#define MAC_PCU_TXSIFS_ACK_SHIFT_GET(x) (((x) & MAC_PCU_TXSIFS_ACK_SHIFT_MASK) >> MAC_PCU_TXSIFS_ACK_SHIFT_LSB)
+#define MAC_PCU_TXSIFS_ACK_SHIFT_SET(x) (((x) << MAC_PCU_TXSIFS_ACK_SHIFT_LSB) & MAC_PCU_TXSIFS_ACK_SHIFT_MASK)
+#define MAC_PCU_TXSIFS_TX_LATENCY_MSB 11
+#define MAC_PCU_TXSIFS_TX_LATENCY_LSB 8
+#define MAC_PCU_TXSIFS_TX_LATENCY_MASK 0x00000f00
+#define MAC_PCU_TXSIFS_TX_LATENCY_GET(x) (((x) & MAC_PCU_TXSIFS_TX_LATENCY_MASK) >> MAC_PCU_TXSIFS_TX_LATENCY_LSB)
+#define MAC_PCU_TXSIFS_TX_LATENCY_SET(x) (((x) << MAC_PCU_TXSIFS_TX_LATENCY_LSB) & MAC_PCU_TXSIFS_TX_LATENCY_MASK)
+#define MAC_PCU_TXSIFS_SIFS_TIME_MSB 7
+#define MAC_PCU_TXSIFS_SIFS_TIME_LSB 0
+#define MAC_PCU_TXSIFS_SIFS_TIME_MASK 0x000000ff
+#define MAC_PCU_TXSIFS_SIFS_TIME_GET(x) (((x) & MAC_PCU_TXSIFS_SIFS_TIME_MASK) >> MAC_PCU_TXSIFS_SIFS_TIME_LSB)
+#define MAC_PCU_TXSIFS_SIFS_TIME_SET(x) (((x) << MAC_PCU_TXSIFS_SIFS_TIME_LSB) & MAC_PCU_TXSIFS_SIFS_TIME_MASK)
+
+#define MAC_PCU_TXOP_X_ADDRESS 0x000080fc
+#define MAC_PCU_TXOP_X_OFFSET 0x000000fc
+#define MAC_PCU_TXOP_X_VALUE_MSB 7
+#define MAC_PCU_TXOP_X_VALUE_LSB 0
+#define MAC_PCU_TXOP_X_VALUE_MASK 0x000000ff
+#define MAC_PCU_TXOP_X_VALUE_GET(x) (((x) & MAC_PCU_TXOP_X_VALUE_MASK) >> MAC_PCU_TXOP_X_VALUE_LSB)
+#define MAC_PCU_TXOP_X_VALUE_SET(x) (((x) << MAC_PCU_TXOP_X_VALUE_LSB) & MAC_PCU_TXOP_X_VALUE_MASK)
+
+#define MAC_PCU_TXOP_0_3_ADDRESS 0x00008100
+#define MAC_PCU_TXOP_0_3_OFFSET 0x00000100
+#define MAC_PCU_TXOP_0_3_VALUE_3_MSB 31
+#define MAC_PCU_TXOP_0_3_VALUE_3_LSB 24
+#define MAC_PCU_TXOP_0_3_VALUE_3_MASK 0xff000000
+#define MAC_PCU_TXOP_0_3_VALUE_3_GET(x) (((x) & MAC_PCU_TXOP_0_3_VALUE_3_MASK) >> MAC_PCU_TXOP_0_3_VALUE_3_LSB)
+#define MAC_PCU_TXOP_0_3_VALUE_3_SET(x) (((x) << MAC_PCU_TXOP_0_3_VALUE_3_LSB) & MAC_PCU_TXOP_0_3_VALUE_3_MASK)
+#define MAC_PCU_TXOP_0_3_VALUE_2_MSB 23
+#define MAC_PCU_TXOP_0_3_VALUE_2_LSB 16
+#define MAC_PCU_TXOP_0_3_VALUE_2_MASK 0x00ff0000
+#define MAC_PCU_TXOP_0_3_VALUE_2_GET(x) (((x) & MAC_PCU_TXOP_0_3_VALUE_2_MASK) >> MAC_PCU_TXOP_0_3_VALUE_2_LSB)
+#define MAC_PCU_TXOP_0_3_VALUE_2_SET(x) (((x) << MAC_PCU_TXOP_0_3_VALUE_2_LSB) & MAC_PCU_TXOP_0_3_VALUE_2_MASK)
+#define MAC_PCU_TXOP_0_3_VALUE_1_MSB 15
+#define MAC_PCU_TXOP_0_3_VALUE_1_LSB 8
+#define MAC_PCU_TXOP_0_3_VALUE_1_MASK 0x0000ff00
+#define MAC_PCU_TXOP_0_3_VALUE_1_GET(x) (((x) & MAC_PCU_TXOP_0_3_VALUE_1_MASK) >> MAC_PCU_TXOP_0_3_VALUE_1_LSB)
+#define MAC_PCU_TXOP_0_3_VALUE_1_SET(x) (((x) << MAC_PCU_TXOP_0_3_VALUE_1_LSB) & MAC_PCU_TXOP_0_3_VALUE_1_MASK)
+#define MAC_PCU_TXOP_0_3_VALUE_0_MSB 7
+#define MAC_PCU_TXOP_0_3_VALUE_0_LSB 0
+#define MAC_PCU_TXOP_0_3_VALUE_0_MASK 0x000000ff
+#define MAC_PCU_TXOP_0_3_VALUE_0_GET(x) (((x) & MAC_PCU_TXOP_0_3_VALUE_0_MASK) >> MAC_PCU_TXOP_0_3_VALUE_0_LSB)
+#define MAC_PCU_TXOP_0_3_VALUE_0_SET(x) (((x) << MAC_PCU_TXOP_0_3_VALUE_0_LSB) & MAC_PCU_TXOP_0_3_VALUE_0_MASK)
+
+#define MAC_PCU_TXOP_4_7_ADDRESS 0x00008104
+#define MAC_PCU_TXOP_4_7_OFFSET 0x00000104
+#define MAC_PCU_TXOP_4_7_VALUE_7_MSB 31
+#define MAC_PCU_TXOP_4_7_VALUE_7_LSB 24
+#define MAC_PCU_TXOP_4_7_VALUE_7_MASK 0xff000000
+#define MAC_PCU_TXOP_4_7_VALUE_7_GET(x) (((x) & MAC_PCU_TXOP_4_7_VALUE_7_MASK) >> MAC_PCU_TXOP_4_7_VALUE_7_LSB)
+#define MAC_PCU_TXOP_4_7_VALUE_7_SET(x) (((x) << MAC_PCU_TXOP_4_7_VALUE_7_LSB) & MAC_PCU_TXOP_4_7_VALUE_7_MASK)
+#define MAC_PCU_TXOP_4_7_VALUE_6_MSB 23
+#define MAC_PCU_TXOP_4_7_VALUE_6_LSB 16
+#define MAC_PCU_TXOP_4_7_VALUE_6_MASK 0x00ff0000
+#define MAC_PCU_TXOP_4_7_VALUE_6_GET(x) (((x) & MAC_PCU_TXOP_4_7_VALUE_6_MASK) >> MAC_PCU_TXOP_4_7_VALUE_6_LSB)
+#define MAC_PCU_TXOP_4_7_VALUE_6_SET(x) (((x) << MAC_PCU_TXOP_4_7_VALUE_6_LSB) & MAC_PCU_TXOP_4_7_VALUE_6_MASK)
+#define MAC_PCU_TXOP_4_7_VALUE_5_MSB 15
+#define MAC_PCU_TXOP_4_7_VALUE_5_LSB 8
+#define MAC_PCU_TXOP_4_7_VALUE_5_MASK 0x0000ff00
+#define MAC_PCU_TXOP_4_7_VALUE_5_GET(x) (((x) & MAC_PCU_TXOP_4_7_VALUE_5_MASK) >> MAC_PCU_TXOP_4_7_VALUE_5_LSB)
+#define MAC_PCU_TXOP_4_7_VALUE_5_SET(x) (((x) << MAC_PCU_TXOP_4_7_VALUE_5_LSB) & MAC_PCU_TXOP_4_7_VALUE_5_MASK)
+#define MAC_PCU_TXOP_4_7_VALUE_4_MSB 7
+#define MAC_PCU_TXOP_4_7_VALUE_4_LSB 0
+#define MAC_PCU_TXOP_4_7_VALUE_4_MASK 0x000000ff
+#define MAC_PCU_TXOP_4_7_VALUE_4_GET(x) (((x) & MAC_PCU_TXOP_4_7_VALUE_4_MASK) >> MAC_PCU_TXOP_4_7_VALUE_4_LSB)
+#define MAC_PCU_TXOP_4_7_VALUE_4_SET(x) (((x) << MAC_PCU_TXOP_4_7_VALUE_4_LSB) & MAC_PCU_TXOP_4_7_VALUE_4_MASK)
+
+#define MAC_PCU_TXOP_8_11_ADDRESS 0x00008108
+#define MAC_PCU_TXOP_8_11_OFFSET 0x00000108
+#define MAC_PCU_TXOP_8_11_VALUE_11_MSB 31
+#define MAC_PCU_TXOP_8_11_VALUE_11_LSB 24
+#define MAC_PCU_TXOP_8_11_VALUE_11_MASK 0xff000000
+#define MAC_PCU_TXOP_8_11_VALUE_11_GET(x) (((x) & MAC_PCU_TXOP_8_11_VALUE_11_MASK) >> MAC_PCU_TXOP_8_11_VALUE_11_LSB)
+#define MAC_PCU_TXOP_8_11_VALUE_11_SET(x) (((x) << MAC_PCU_TXOP_8_11_VALUE_11_LSB) & MAC_PCU_TXOP_8_11_VALUE_11_MASK)
+#define MAC_PCU_TXOP_8_11_VALUE_10_MSB 23
+#define MAC_PCU_TXOP_8_11_VALUE_10_LSB 16
+#define MAC_PCU_TXOP_8_11_VALUE_10_MASK 0x00ff0000
+#define MAC_PCU_TXOP_8_11_VALUE_10_GET(x) (((x) & MAC_PCU_TXOP_8_11_VALUE_10_MASK) >> MAC_PCU_TXOP_8_11_VALUE_10_LSB)
+#define MAC_PCU_TXOP_8_11_VALUE_10_SET(x) (((x) << MAC_PCU_TXOP_8_11_VALUE_10_LSB) & MAC_PCU_TXOP_8_11_VALUE_10_MASK)
+#define MAC_PCU_TXOP_8_11_VALUE_9_MSB 15
+#define MAC_PCU_TXOP_8_11_VALUE_9_LSB 8
+#define MAC_PCU_TXOP_8_11_VALUE_9_MASK 0x0000ff00
+#define MAC_PCU_TXOP_8_11_VALUE_9_GET(x) (((x) & MAC_PCU_TXOP_8_11_VALUE_9_MASK) >> MAC_PCU_TXOP_8_11_VALUE_9_LSB)
+#define MAC_PCU_TXOP_8_11_VALUE_9_SET(x) (((x) << MAC_PCU_TXOP_8_11_VALUE_9_LSB) & MAC_PCU_TXOP_8_11_VALUE_9_MASK)
+#define MAC_PCU_TXOP_8_11_VALUE_8_MSB 7
+#define MAC_PCU_TXOP_8_11_VALUE_8_LSB 0
+#define MAC_PCU_TXOP_8_11_VALUE_8_MASK 0x000000ff
+#define MAC_PCU_TXOP_8_11_VALUE_8_GET(x) (((x) & MAC_PCU_TXOP_8_11_VALUE_8_MASK) >> MAC_PCU_TXOP_8_11_VALUE_8_LSB)
+#define MAC_PCU_TXOP_8_11_VALUE_8_SET(x) (((x) << MAC_PCU_TXOP_8_11_VALUE_8_LSB) & MAC_PCU_TXOP_8_11_VALUE_8_MASK)
+
+#define MAC_PCU_TXOP_12_15_ADDRESS 0x0000810c
+#define MAC_PCU_TXOP_12_15_OFFSET 0x0000010c
+#define MAC_PCU_TXOP_12_15_VALUE_15_MSB 31
+#define MAC_PCU_TXOP_12_15_VALUE_15_LSB 24
+#define MAC_PCU_TXOP_12_15_VALUE_15_MASK 0xff000000
+#define MAC_PCU_TXOP_12_15_VALUE_15_GET(x) (((x) & MAC_PCU_TXOP_12_15_VALUE_15_MASK) >> MAC_PCU_TXOP_12_15_VALUE_15_LSB)
+#define MAC_PCU_TXOP_12_15_VALUE_15_SET(x) (((x) << MAC_PCU_TXOP_12_15_VALUE_15_LSB) & MAC_PCU_TXOP_12_15_VALUE_15_MASK)
+#define MAC_PCU_TXOP_12_15_VALUE_14_MSB 23
+#define MAC_PCU_TXOP_12_15_VALUE_14_LSB 16
+#define MAC_PCU_TXOP_12_15_VALUE_14_MASK 0x00ff0000
+#define MAC_PCU_TXOP_12_15_VALUE_14_GET(x) (((x) & MAC_PCU_TXOP_12_15_VALUE_14_MASK) >> MAC_PCU_TXOP_12_15_VALUE_14_LSB)
+#define MAC_PCU_TXOP_12_15_VALUE_14_SET(x) (((x) << MAC_PCU_TXOP_12_15_VALUE_14_LSB) & MAC_PCU_TXOP_12_15_VALUE_14_MASK)
+#define MAC_PCU_TXOP_12_15_VALUE_13_MSB 15
+#define MAC_PCU_TXOP_12_15_VALUE_13_LSB 8
+#define MAC_PCU_TXOP_12_15_VALUE_13_MASK 0x0000ff00
+#define MAC_PCU_TXOP_12_15_VALUE_13_GET(x) (((x) & MAC_PCU_TXOP_12_15_VALUE_13_MASK) >> MAC_PCU_TXOP_12_15_VALUE_13_LSB)
+#define MAC_PCU_TXOP_12_15_VALUE_13_SET(x) (((x) << MAC_PCU_TXOP_12_15_VALUE_13_LSB) & MAC_PCU_TXOP_12_15_VALUE_13_MASK)
+#define MAC_PCU_TXOP_12_15_VALUE_12_MSB 7
+#define MAC_PCU_TXOP_12_15_VALUE_12_LSB 0
+#define MAC_PCU_TXOP_12_15_VALUE_12_MASK 0x000000ff
+#define MAC_PCU_TXOP_12_15_VALUE_12_GET(x) (((x) & MAC_PCU_TXOP_12_15_VALUE_12_MASK) >> MAC_PCU_TXOP_12_15_VALUE_12_LSB)
+#define MAC_PCU_TXOP_12_15_VALUE_12_SET(x) (((x) << MAC_PCU_TXOP_12_15_VALUE_12_LSB) & MAC_PCU_TXOP_12_15_VALUE_12_MASK)
+
+#define MAC_PCU_LOGIC_ANALYZER_ADDRESS 0x00008110
+#define MAC_PCU_LOGIC_ANALYZER_OFFSET 0x00000110
+#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MSB 31
+#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB 18
+#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK 0xfffc0000
+#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK) >> MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB) & MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MSB 17
+#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB 8
+#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK 0x0003ff00
+#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK) >> MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB) & MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MSB 7
+#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB 4
+#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK 0x000000f0
+#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK) >> MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB) & MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_ENABLE_MSB 3
+#define MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB 3
+#define MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK 0x00000008
+#define MAC_PCU_LOGIC_ANALYZER_ENABLE_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK) >> MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_ENABLE_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB) & MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_STATE_MSB 2
+#define MAC_PCU_LOGIC_ANALYZER_STATE_LSB 2
+#define MAC_PCU_LOGIC_ANALYZER_STATE_MASK 0x00000004
+#define MAC_PCU_LOGIC_ANALYZER_STATE_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_STATE_MASK) >> MAC_PCU_LOGIC_ANALYZER_STATE_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_STATE_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_STATE_LSB) & MAC_PCU_LOGIC_ANALYZER_STATE_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_CLEAR_MSB 1
+#define MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB 1
+#define MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK 0x00000002
+#define MAC_PCU_LOGIC_ANALYZER_CLEAR_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK) >> MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_CLEAR_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB) & MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK)
+#define MAC_PCU_LOGIC_ANALYZER_HOLD_MSB 0
+#define MAC_PCU_LOGIC_ANALYZER_HOLD_LSB 0
+#define MAC_PCU_LOGIC_ANALYZER_HOLD_MASK 0x00000001
+#define MAC_PCU_LOGIC_ANALYZER_HOLD_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_HOLD_MASK) >> MAC_PCU_LOGIC_ANALYZER_HOLD_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_HOLD_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_HOLD_LSB) & MAC_PCU_LOGIC_ANALYZER_HOLD_MASK)
+
+#define MAC_PCU_LOGIC_ANALYZER_32L_ADDRESS 0x00008114
+#define MAC_PCU_LOGIC_ANALYZER_32L_OFFSET 0x00000114
+#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_MSB 31
+#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB 0
+#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK 0xffffffff
+#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK) >> MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB) & MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK)
+
+#define MAC_PCU_LOGIC_ANALYZER_16U_ADDRESS 0x00008118
+#define MAC_PCU_LOGIC_ANALYZER_16U_OFFSET 0x00000118
+#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_MSB 15
+#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB 0
+#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK 0x0000ffff
+#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_GET(x) (((x) & MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK) >> MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB)
+#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_SET(x) (((x) << MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB) & MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK)
+
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_ADDRESS 0x0000811c
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_OFFSET 0x0000011c
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MSB 23
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB 16
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK 0x00ff0000
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB)
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK)
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MSB 15
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB 8
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK 0x0000ff00
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB)
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK)
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MSB 7
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB 0
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK 0x000000ff
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB)
+#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK)
+
+#define MAC_PCU_AZIMUTH_MODE_ADDRESS 0x00008120
+#define MAC_PCU_AZIMUTH_MODE_OFFSET 0x00000120
+#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MSB 7
+#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB 7
+#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK 0x00000080
+#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK) >> MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB)
+#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB) & MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK)
+#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MSB 6
+#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB 6
+#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK 0x00000040
+#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK) >> MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB)
+#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB) & MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK)
+#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MSB 5
+#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB 5
+#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK 0x00000020
+#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK) >> MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB)
+#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB) & MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK)
+#define MAC_PCU_AZIMUTH_MODE_CLK_EN_MSB 4
+#define MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB 4
+#define MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK 0x00000010
+#define MAC_PCU_AZIMUTH_MODE_CLK_EN_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK) >> MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB)
+#define MAC_PCU_AZIMUTH_MODE_CLK_EN_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB) & MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK)
+#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MSB 3
+#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB 3
+#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK 0x00000008
+#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK) >> MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB)
+#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB) & MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK)
+#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MSB 2
+#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB 2
+#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK 0x00000004
+#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK) >> MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB)
+#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB) & MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK)
+#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MSB 1
+#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB 1
+#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK 0x00000002
+#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK) >> MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB)
+#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB) & MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK)
+#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MSB 0
+#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB 0
+#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK 0x00000001
+#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK) >> MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB)
+#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB) & MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK)
+
+#define MAC_PCU_20_40_MODE_ADDRESS 0x00008124
+#define MAC_PCU_20_40_MODE_OFFSET 0x00000124
+#define MAC_PCU_20_40_MODE_PIFS_CYCLES_MSB 15
+#define MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB 4
+#define MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK 0x0000fff0
+#define MAC_PCU_20_40_MODE_PIFS_CYCLES_GET(x) (((x) & MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK) >> MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB)
+#define MAC_PCU_20_40_MODE_PIFS_CYCLES_SET(x) (((x) << MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB) & MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK)
+#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MSB 3
+#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB 3
+#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK 0x00000008
+#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_GET(x) (((x) & MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK) >> MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB)
+#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_SET(x) (((x) << MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB) & MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK)
+#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MSB 2
+#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB 2
+#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK 0x00000004
+#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_GET(x) (((x) & MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK) >> MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB)
+#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_SET(x) (((x) << MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB) & MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK)
+#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MSB 1
+#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB 1
+#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK 0x00000002
+#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_GET(x) (((x) & MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK) >> MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB)
+#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_SET(x) (((x) << MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB) & MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK)
+#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MSB 0
+#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB 0
+#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK 0x00000001
+#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_GET(x) (((x) & MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK) >> MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB)
+#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_SET(x) (((x) << MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB) & MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK)
+
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_ADDRESS 0x00008128
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_OFFSET 0x00000128
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MSB 31
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB 0
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK 0xffffffff
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_GET(x) (((x) & MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK) >> MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB)
+#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_SET(x) (((x) << MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB) & MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK)
+
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_ADDRESS 0x0000812c
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_OFFSET 0x0000012c
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MSB 2
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB 0
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK 0x00000007
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_GET(x) (((x) & MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK) >> MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB)
+#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_SET(x) (((x) << MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB) & MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK)
+
+#define MAC_PCU_BA_BAR_CONTROL_ADDRESS 0x00008130
+#define MAC_PCU_BA_BAR_CONTROL_OFFSET 0x00000130
+#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MSB 12
+#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB 12
+#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK 0x00001000
+#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK) >> MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB) & MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MSB 11
+#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB 11
+#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK 0x00000800
+#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK) >> MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB) & MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MSB 10
+#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB 10
+#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK 0x00000400
+#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK) >> MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB) & MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MSB 9
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB 9
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK 0x00000200
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK) >> MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MSB 8
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB 8
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK 0x00000100
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK) >> MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MSB 7
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB 4
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK 0x000000f0
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK) >> MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK)
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MSB 3
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB 0
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK 0x0000000f
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK) >> MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB)
+#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK)
+
+#define MAC_PCU_LEGACY_PLCP_SPOOF_ADDRESS 0x00008134
+#define MAC_PCU_LEGACY_PLCP_SPOOF_OFFSET 0x00000134
+#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MSB 12
+#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB 8
+#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK 0x00001f00
+#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_GET(x) (((x) & MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK) >> MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB)
+#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_SET(x) (((x) << MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB) & MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK)
+#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MSB 7
+#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB 0
+#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK 0x000000ff
+#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_GET(x) (((x) & MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK) >> MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB)
+#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_SET(x) (((x) << MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB) & MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK)
+
+#define MAC_PCU_PHY_ERROR_MASK_CONT_ADDRESS 0x00008138
+#define MAC_PCU_PHY_ERROR_MASK_CONT_OFFSET 0x00000138
+#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MSB 23
+#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB 16
+#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK 0x00ff0000
+#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB)
+#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK)
+#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MSB 7
+#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB 0
+#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK 0x000000ff
+#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB)
+#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK)
+
+#define MAC_PCU_TX_TIMER_ADDRESS 0x0000813c
+#define MAC_PCU_TX_TIMER_OFFSET 0x0000013c
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MSB 25
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB 25
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK 0x02000000
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_GET(x) (((x) & MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK) >> MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB)
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_SET(x) (((x) << MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB) & MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK)
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_MSB 24
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_LSB 20
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_MASK 0x01f00000
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_GET(x) (((x) & MAC_PCU_TX_TIMER_QUIET_TIMER_MASK) >> MAC_PCU_TX_TIMER_QUIET_TIMER_LSB)
+#define MAC_PCU_TX_TIMER_QUIET_TIMER_SET(x) (((x) << MAC_PCU_TX_TIMER_QUIET_TIMER_LSB) & MAC_PCU_TX_TIMER_QUIET_TIMER_MASK)
+#define MAC_PCU_TX_TIMER_RIFS_TIMER_MSB 19
+#define MAC_PCU_TX_TIMER_RIFS_TIMER_LSB 16
+#define MAC_PCU_TX_TIMER_RIFS_TIMER_MASK 0x000f0000
+#define MAC_PCU_TX_TIMER_RIFS_TIMER_GET(x) (((x) & MAC_PCU_TX_TIMER_RIFS_TIMER_MASK) >> MAC_PCU_TX_TIMER_RIFS_TIMER_LSB)
+#define MAC_PCU_TX_TIMER_RIFS_TIMER_SET(x) (((x) << MAC_PCU_TX_TIMER_RIFS_TIMER_LSB) & MAC_PCU_TX_TIMER_RIFS_TIMER_MASK)
+#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MSB 15
+#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB 15
+#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK 0x00008000
+#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_GET(x) (((x) & MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK) >> MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB)
+#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_SET(x) (((x) << MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB) & MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK)
+#define MAC_PCU_TX_TIMER_TX_TIMER_MSB 14
+#define MAC_PCU_TX_TIMER_TX_TIMER_LSB 0
+#define MAC_PCU_TX_TIMER_TX_TIMER_MASK 0x00007fff
+#define MAC_PCU_TX_TIMER_TX_TIMER_GET(x) (((x) & MAC_PCU_TX_TIMER_TX_TIMER_MASK) >> MAC_PCU_TX_TIMER_TX_TIMER_LSB)
+#define MAC_PCU_TX_TIMER_TX_TIMER_SET(x) (((x) << MAC_PCU_TX_TIMER_TX_TIMER_LSB) & MAC_PCU_TX_TIMER_TX_TIMER_MASK)
+
+#define MAC_PCU_TXBUF_CTRL_ADDRESS 0x00008140
+#define MAC_PCU_TXBUF_CTRL_OFFSET 0x00000140
+#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MSB 16
+#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB 16
+#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK 0x00010000
+#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_GET(x) (((x) & MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK) >> MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB)
+#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_SET(x) (((x) << MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB) & MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK)
+#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MSB 11
+#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB 0
+#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK 0x00000fff
+#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_GET(x) (((x) & MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK) >> MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB)
+#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_SET(x) (((x) << MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB) & MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK)
+
+#define MAC_PCU_MISC_MODE2_ADDRESS 0x00008144
+#define MAC_PCU_MISC_MODE2_OFFSET 0x00000144
+#define MAC_PCU_MISC_MODE2_RESERVED_1_MSB 31
+#define MAC_PCU_MISC_MODE2_RESERVED_1_LSB 28
+#define MAC_PCU_MISC_MODE2_RESERVED_1_MASK 0xf0000000
+#define MAC_PCU_MISC_MODE2_RESERVED_1_GET(x) (((x) & MAC_PCU_MISC_MODE2_RESERVED_1_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_1_LSB)
+#define MAC_PCU_MISC_MODE2_RESERVED_1_SET(x) (((x) << MAC_PCU_MISC_MODE2_RESERVED_1_LSB) & MAC_PCU_MISC_MODE2_RESERVED_1_MASK)
+#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MSB 27
+#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB 27
+#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK 0x08000000
+#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_GET(x) (((x) & MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK) >> MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB)
+#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_SET(x) (((x) << MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB) & MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK)
+#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MSB 26
+#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB 26
+#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK 0x04000000
+#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_GET(x) (((x) & MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK) >> MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB)
+#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_SET(x) (((x) << MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB) & MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK)
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MSB 25
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB 25
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK 0x02000000
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_GET(x) (((x) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK) >> MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB)
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_SET(x) (((x) << MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK)
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MSB 24
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB 24
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK 0x01000000
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_GET(x) (((x) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK) >> MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB)
+#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_SET(x) (((x) << MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK)
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MSB 23
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB 23
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK 0x00800000
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_GET(x) (((x) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK) >> MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB)
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_SET(x) (((x) << MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK)
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MSB 22
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB 22
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK 0x00400000
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_GET(x) (((x) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK) >> MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB)
+#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_SET(x) (((x) << MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK)
+#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MSB 21
+#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB 21
+#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK 0x00200000
+#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_GET(x) (((x) & MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK) >> MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB)
+#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_SET(x) (((x) << MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB) & MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK)
+#define MAC_PCU_MISC_MODE2_BUG_28676_MSB 20
+#define MAC_PCU_MISC_MODE2_BUG_28676_LSB 20
+#define MAC_PCU_MISC_MODE2_BUG_28676_MASK 0x00100000
+#define MAC_PCU_MISC_MODE2_BUG_28676_GET(x) (((x) & MAC_PCU_MISC_MODE2_BUG_28676_MASK) >> MAC_PCU_MISC_MODE2_BUG_28676_LSB)
+#define MAC_PCU_MISC_MODE2_BUG_28676_SET(x) (((x) << MAC_PCU_MISC_MODE2_BUG_28676_LSB) & MAC_PCU_MISC_MODE2_BUG_28676_MASK)
+#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MSB 19
+#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB 19
+#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK 0x00080000
+#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_GET(x) (((x) & MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK) >> MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB)
+#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_SET(x) (((x) << MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB) & MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK)
+#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MSB 18
+#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB 18
+#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK 0x00040000
+#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK) >> MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB)
+#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB) & MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK)
+#define MAC_PCU_MISC_MODE2_AGG_WEP_MSB 17
+#define MAC_PCU_MISC_MODE2_AGG_WEP_LSB 17
+#define MAC_PCU_MISC_MODE2_AGG_WEP_MASK 0x00020000
+#define MAC_PCU_MISC_MODE2_AGG_WEP_GET(x) (((x) & MAC_PCU_MISC_MODE2_AGG_WEP_MASK) >> MAC_PCU_MISC_MODE2_AGG_WEP_LSB)
+#define MAC_PCU_MISC_MODE2_AGG_WEP_SET(x) (((x) << MAC_PCU_MISC_MODE2_AGG_WEP_LSB) & MAC_PCU_MISC_MODE2_AGG_WEP_MASK)
+#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MSB 16
+#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB 16
+#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK 0x00010000
+#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_GET(x) (((x) & MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK) >> MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB)
+#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_SET(x) (((x) << MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB) & MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK)
+#define MAC_PCU_MISC_MODE2_MGMT_QOS_MSB 15
+#define MAC_PCU_MISC_MODE2_MGMT_QOS_LSB 8
+#define MAC_PCU_MISC_MODE2_MGMT_QOS_MASK 0x0000ff00
+#define MAC_PCU_MISC_MODE2_MGMT_QOS_GET(x) (((x) & MAC_PCU_MISC_MODE2_MGMT_QOS_MASK) >> MAC_PCU_MISC_MODE2_MGMT_QOS_LSB)
+#define MAC_PCU_MISC_MODE2_MGMT_QOS_SET(x) (((x) << MAC_PCU_MISC_MODE2_MGMT_QOS_LSB) & MAC_PCU_MISC_MODE2_MGMT_QOS_MASK)
+#define MAC_PCU_MISC_MODE2_CFP_IGNORE_MSB 7
+#define MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB 7
+#define MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK 0x00000080
+#define MAC_PCU_MISC_MODE2_CFP_IGNORE_GET(x) (((x) & MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK) >> MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB)
+#define MAC_PCU_MISC_MODE2_CFP_IGNORE_SET(x) (((x) << MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB) & MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK)
+#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MSB 6
+#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB 6
+#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK 0x00000040
+#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB) & MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE2_RESERVED_2_MSB 5
+#define MAC_PCU_MISC_MODE2_RESERVED_2_LSB 5
+#define MAC_PCU_MISC_MODE2_RESERVED_2_MASK 0x00000020
+#define MAC_PCU_MISC_MODE2_RESERVED_2_GET(x) (((x) & MAC_PCU_MISC_MODE2_RESERVED_2_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_2_LSB)
+#define MAC_PCU_MISC_MODE2_RESERVED_2_SET(x) (((x) << MAC_PCU_MISC_MODE2_RESERVED_2_LSB) & MAC_PCU_MISC_MODE2_RESERVED_2_MASK)
+#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MSB 4
+#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB 4
+#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK 0x00000010
+#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB) & MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE2_RESERVED_0_MSB 3
+#define MAC_PCU_MISC_MODE2_RESERVED_0_LSB 3
+#define MAC_PCU_MISC_MODE2_RESERVED_0_MASK 0x00000008
+#define MAC_PCU_MISC_MODE2_RESERVED_0_GET(x) (((x) & MAC_PCU_MISC_MODE2_RESERVED_0_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_0_LSB)
+#define MAC_PCU_MISC_MODE2_RESERVED_0_SET(x) (((x) << MAC_PCU_MISC_MODE2_RESERVED_0_LSB) & MAC_PCU_MISC_MODE2_RESERVED_0_MASK)
+#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MSB 2
+#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB 2
+#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK 0x00000004
+#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_GET(x) (((x) & MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK) >> MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB)
+#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_SET(x) (((x) << MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB) & MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK)
+#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MSB 1
+#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB 1
+#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK 0x00000002
+#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB) & MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK)
+#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MSB 0
+#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB 0
+#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK 0x00000001
+#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB)
+#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB) & MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK)
+
+#define MAC_PCU_ALT_AES_MUTE_MASK_ADDRESS 0x00008148
+#define MAC_PCU_ALT_AES_MUTE_MASK_OFFSET 0x00000148
+#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_MSB 31
+#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB 16
+#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK 0xffff0000
+#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_GET(x) (((x) & MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK) >> MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB)
+#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_SET(x) (((x) << MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB) & MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK)
+
+#define MAC_PCU_AZIMUTH_TIME_STAMP_ADDRESS 0x0000814c
+#define MAC_PCU_AZIMUTH_TIME_STAMP_OFFSET 0x0000014c
+#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MSB 31
+#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB 0
+#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK 0xffffffff
+#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_GET(x) (((x) & MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK) >> MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB)
+#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_SET(x) (((x) << MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB) & MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK)
+
+#define MAC_PCU_MAX_CFP_DUR_ADDRESS 0x00008150
+#define MAC_PCU_MAX_CFP_DUR_OFFSET 0x00000150
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MSB 7
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB 4
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK 0x000000f0
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_GET(x) (((x) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK) >> MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB)
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_SET(x) (((x) << MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK)
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MSB 3
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB 0
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK 0x0000000f
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_GET(x) (((x) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK) >> MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB)
+#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_SET(x) (((x) << MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK)
+
+#define MAC_PCU_HCF_TIMEOUT_ADDRESS 0x00008154
+#define MAC_PCU_HCF_TIMEOUT_OFFSET 0x00000154
+#define MAC_PCU_HCF_TIMEOUT_VALUE_MSB 15
+#define MAC_PCU_HCF_TIMEOUT_VALUE_LSB 0
+#define MAC_PCU_HCF_TIMEOUT_VALUE_MASK 0x0000ffff
+#define MAC_PCU_HCF_TIMEOUT_VALUE_GET(x) (((x) & MAC_PCU_HCF_TIMEOUT_VALUE_MASK) >> MAC_PCU_HCF_TIMEOUT_VALUE_LSB)
+#define MAC_PCU_HCF_TIMEOUT_VALUE_SET(x) (((x) << MAC_PCU_HCF_TIMEOUT_VALUE_LSB) & MAC_PCU_HCF_TIMEOUT_VALUE_MASK)
+
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_ADDRESS 0x00008158
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_OFFSET 0x00000158
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MSB 31
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB 16
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK 0xffff0000
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB)
+#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK)
+
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_ADDRESS 0x0000815c
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_OFFSET 0x0000015c
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MSB 31
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB 0
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK 0xffffffff
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_GET(x) (((x) & MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK) >> MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB)
+#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_SET(x) (((x) << MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB) & MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK)
+
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_ADDRESS 0x00008160
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_OFFSET 0x00000160
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MSB 31
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB 0
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK 0xffffffff
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_GET(x) (((x) & MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK) >> MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB)
+#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_SET(x) (((x) << MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB) & MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK)
+
+#define MAC_PCU_BLUETOOTH_MODE3_ADDRESS 0x00008164
+#define MAC_PCU_BLUETOOTH_MODE3_OFFSET 0x00000164
+#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MSB 31
+#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB 28
+#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK 0xf0000000
+#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK) >> MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB) & MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MSB 27
+#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB 27
+#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK 0x08000000
+#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MSB 26
+#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB 25
+#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK 0x06000000
+#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK) >> MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB) & MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MSB 24
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB 24
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK 0x01000000
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MSB 23
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB 23
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK 0x00800000
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MSB 22
+#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB 22
+#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK 0x00400000
+#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK) >> MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB) & MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MSB 21
+#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB 21
+#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK 0x00200000
+#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MSB 20
+#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB 20
+#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK 0x00100000
+#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK) >> MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB) & MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MSB 19
+#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB 16
+#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK 0x000f0000
+#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK) >> MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB) & MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MSB 15
+#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB 8
+#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK 0x0000ff00
+#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MSB 7
+#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB 0
+#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK 0x000000ff
+#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB)
+#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK)
+
+#define MAC_PCU_BLUETOOTH_MODE4_ADDRESS 0x00008168
+#define MAC_PCU_BLUETOOTH_MODE4_OFFSET 0x00000168
+#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MSB 31
+#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB 16
+#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK 0xffff0000
+#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK)
+#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MSB 15
+#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB 0
+#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK 0x0000ffff
+#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB)
+#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK)
+
+#define MAC_PCU_BT_BT_ADDRESS 0x00008200
+#define MAC_PCU_BT_BT_OFFSET 0x00000200
+#define MAC_PCU_BT_BT_WEIGHT_MSB 31
+#define MAC_PCU_BT_BT_WEIGHT_LSB 0
+#define MAC_PCU_BT_BT_WEIGHT_MASK 0xffffffff
+#define MAC_PCU_BT_BT_WEIGHT_GET(x) (((x) & MAC_PCU_BT_BT_WEIGHT_MASK) >> MAC_PCU_BT_BT_WEIGHT_LSB)
+#define MAC_PCU_BT_BT_WEIGHT_SET(x) (((x) << MAC_PCU_BT_BT_WEIGHT_LSB) & MAC_PCU_BT_BT_WEIGHT_MASK)
+
+#define MAC_PCU_BT_BT_ASYNC_ADDRESS 0x00008300
+#define MAC_PCU_BT_BT_ASYNC_OFFSET 0x00000300
+#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MSB 15
+#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB 12
+#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK 0x0000f000
+#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_GET(x) (((x) & MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB)
+#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_SET(x) (((x) << MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK)
+#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MSB 11
+#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB 8
+#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK 0x00000f00
+#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_GET(x) (((x) & MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB)
+#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_SET(x) (((x) << MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK)
+#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MSB 7
+#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB 4
+#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK 0x000000f0
+#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_GET(x) (((x) & MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB)
+#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_SET(x) (((x) << MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK)
+#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MSB 3
+#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB 0
+#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK 0x0000000f
+#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_GET(x) (((x) & MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB)
+#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_SET(x) (((x) << MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK)
+
+#define MAC_PCU_BT_WL_1_ADDRESS 0x00008304
+#define MAC_PCU_BT_WL_1_OFFSET 0x00000304
+#define MAC_PCU_BT_WL_1_WEIGHT_MSB 31
+#define MAC_PCU_BT_WL_1_WEIGHT_LSB 0
+#define MAC_PCU_BT_WL_1_WEIGHT_MASK 0xffffffff
+#define MAC_PCU_BT_WL_1_WEIGHT_GET(x) (((x) & MAC_PCU_BT_WL_1_WEIGHT_MASK) >> MAC_PCU_BT_WL_1_WEIGHT_LSB)
+#define MAC_PCU_BT_WL_1_WEIGHT_SET(x) (((x) << MAC_PCU_BT_WL_1_WEIGHT_LSB) & MAC_PCU_BT_WL_1_WEIGHT_MASK)
+
+#define MAC_PCU_BT_WL_2_ADDRESS 0x00008308
+#define MAC_PCU_BT_WL_2_OFFSET 0x00000308
+#define MAC_PCU_BT_WL_2_WEIGHT_MSB 31
+#define MAC_PCU_BT_WL_2_WEIGHT_LSB 0
+#define MAC_PCU_BT_WL_2_WEIGHT_MASK 0xffffffff
+#define MAC_PCU_BT_WL_2_WEIGHT_GET(x) (((x) & MAC_PCU_BT_WL_2_WEIGHT_MASK) >> MAC_PCU_BT_WL_2_WEIGHT_LSB)
+#define MAC_PCU_BT_WL_2_WEIGHT_SET(x) (((x) << MAC_PCU_BT_WL_2_WEIGHT_LSB) & MAC_PCU_BT_WL_2_WEIGHT_MASK)
+
+#define MAC_PCU_BT_WL_3_ADDRESS 0x0000830c
+#define MAC_PCU_BT_WL_3_OFFSET 0x0000030c
+#define MAC_PCU_BT_WL_3_WEIGHT_MSB 31
+#define MAC_PCU_BT_WL_3_WEIGHT_LSB 0
+#define MAC_PCU_BT_WL_3_WEIGHT_MASK 0xffffffff
+#define MAC_PCU_BT_WL_3_WEIGHT_GET(x) (((x) & MAC_PCU_BT_WL_3_WEIGHT_MASK) >> MAC_PCU_BT_WL_3_WEIGHT_LSB)
+#define MAC_PCU_BT_WL_3_WEIGHT_SET(x) (((x) << MAC_PCU_BT_WL_3_WEIGHT_LSB) & MAC_PCU_BT_WL_3_WEIGHT_MASK)
+
+#define MAC_PCU_BT_WL_4_ADDRESS 0x00008310
+#define MAC_PCU_BT_WL_4_OFFSET 0x00000310
+#define MAC_PCU_BT_WL_4_WEIGHT_MSB 31
+#define MAC_PCU_BT_WL_4_WEIGHT_LSB 0
+#define MAC_PCU_BT_WL_4_WEIGHT_MASK 0xffffffff
+#define MAC_PCU_BT_WL_4_WEIGHT_GET(x) (((x) & MAC_PCU_BT_WL_4_WEIGHT_MASK) >> MAC_PCU_BT_WL_4_WEIGHT_LSB)
+#define MAC_PCU_BT_WL_4_WEIGHT_SET(x) (((x) << MAC_PCU_BT_WL_4_WEIGHT_LSB) & MAC_PCU_BT_WL_4_WEIGHT_MASK)
+
+#define MAC_PCU_COEX_EPTA_ADDRESS 0x00008314
+#define MAC_PCU_COEX_EPTA_OFFSET 0x00000314
+#define MAC_PCU_COEX_EPTA_WT_IDX_MSB 12
+#define MAC_PCU_COEX_EPTA_WT_IDX_LSB 6
+#define MAC_PCU_COEX_EPTA_WT_IDX_MASK 0x00001fc0
+#define MAC_PCU_COEX_EPTA_WT_IDX_GET(x) (((x) & MAC_PCU_COEX_EPTA_WT_IDX_MASK) >> MAC_PCU_COEX_EPTA_WT_IDX_LSB)
+#define MAC_PCU_COEX_EPTA_WT_IDX_SET(x) (((x) << MAC_PCU_COEX_EPTA_WT_IDX_LSB) & MAC_PCU_COEX_EPTA_WT_IDX_MASK)
+#define MAC_PCU_COEX_EPTA_LINKID_MSB 5
+#define MAC_PCU_COEX_EPTA_LINKID_LSB 0
+#define MAC_PCU_COEX_EPTA_LINKID_MASK 0x0000003f
+#define MAC_PCU_COEX_EPTA_LINKID_GET(x) (((x) & MAC_PCU_COEX_EPTA_LINKID_MASK) >> MAC_PCU_COEX_EPTA_LINKID_LSB)
+#define MAC_PCU_COEX_EPTA_LINKID_SET(x) (((x) << MAC_PCU_COEX_EPTA_LINKID_LSB) & MAC_PCU_COEX_EPTA_LINKID_MASK)
+
+#define MAC_PCU_COEX_LNAMAXGAIN1_ADDRESS 0x00008318
+#define MAC_PCU_COEX_LNAMAXGAIN1_OFFSET 0x00000318
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MSB 31
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB 24
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK 0xff000000
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MSB 23
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB 16
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK 0x00ff0000
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MSB 15
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB 8
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK 0x0000ff00
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MSB 7
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB 0
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK 0x000000ff
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK)
+
+#define MAC_PCU_COEX_LNAMAXGAIN2_ADDRESS 0x0000831c
+#define MAC_PCU_COEX_LNAMAXGAIN2_OFFSET 0x0000031c
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MSB 31
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB 24
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK 0xff000000
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MSB 23
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB 16
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK 0x00ff0000
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MSB 15
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB 8
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK 0x0000ff00
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MSB 7
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB 0
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK 0x000000ff
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK)
+
+#define MAC_PCU_COEX_LNAMAXGAIN3_ADDRESS 0x00008320
+#define MAC_PCU_COEX_LNAMAXGAIN3_OFFSET 0x00000320
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MSB 31
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB 24
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK 0xff000000
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MSB 23
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB 16
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK 0x00ff0000
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MSB 15
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB 8
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK 0x0000ff00
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MSB 7
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB 0
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK 0x000000ff
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK)
+
+#define MAC_PCU_COEX_LNAMAXGAIN4_ADDRESS 0x00008324
+#define MAC_PCU_COEX_LNAMAXGAIN4_OFFSET 0x00000324
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MSB 31
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB 24
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK 0xff000000
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MSB 23
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB 16
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK 0x00ff0000
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MSB 15
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB 8
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK 0x0000ff00
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MSB 7
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB 0
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK 0x000000ff
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB)
+#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK)
+
+#define MAC_PCU_BASIC_RATE_SET0_ADDRESS 0x00008328
+#define MAC_PCU_BASIC_RATE_SET0_OFFSET 0x00000328
+#define MAC_PCU_BASIC_RATE_SET0_VALUE_MSB 29
+#define MAC_PCU_BASIC_RATE_SET0_VALUE_LSB 0
+#define MAC_PCU_BASIC_RATE_SET0_VALUE_MASK 0x3fffffff
+#define MAC_PCU_BASIC_RATE_SET0_VALUE_GET(x) (((x) & MAC_PCU_BASIC_RATE_SET0_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET0_VALUE_LSB)
+#define MAC_PCU_BASIC_RATE_SET0_VALUE_SET(x) (((x) << MAC_PCU_BASIC_RATE_SET0_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET0_VALUE_MASK)
+
+#define MAC_PCU_BASIC_RATE_SET1_ADDRESS 0x0000832c
+#define MAC_PCU_BASIC_RATE_SET1_OFFSET 0x0000032c
+#define MAC_PCU_BASIC_RATE_SET1_VALUE_MSB 29
+#define MAC_PCU_BASIC_RATE_SET1_VALUE_LSB 0
+#define MAC_PCU_BASIC_RATE_SET1_VALUE_MASK 0x3fffffff
+#define MAC_PCU_BASIC_RATE_SET1_VALUE_GET(x) (((x) & MAC_PCU_BASIC_RATE_SET1_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET1_VALUE_LSB)
+#define MAC_PCU_BASIC_RATE_SET1_VALUE_SET(x) (((x) << MAC_PCU_BASIC_RATE_SET1_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET1_VALUE_MASK)
+
+#define MAC_PCU_BASIC_RATE_SET2_ADDRESS 0x00008330
+#define MAC_PCU_BASIC_RATE_SET2_OFFSET 0x00000330
+#define MAC_PCU_BASIC_RATE_SET2_VALUE_MSB 29
+#define MAC_PCU_BASIC_RATE_SET2_VALUE_LSB 0
+#define MAC_PCU_BASIC_RATE_SET2_VALUE_MASK 0x3fffffff
+#define MAC_PCU_BASIC_RATE_SET2_VALUE_GET(x) (((x) & MAC_PCU_BASIC_RATE_SET2_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET2_VALUE_LSB)
+#define MAC_PCU_BASIC_RATE_SET2_VALUE_SET(x) (((x) << MAC_PCU_BASIC_RATE_SET2_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET2_VALUE_MASK)
+
+#define MAC_PCU_BASIC_RATE_SET3_ADDRESS 0x00008334
+#define MAC_PCU_BASIC_RATE_SET3_OFFSET 0x00000334
+#define MAC_PCU_BASIC_RATE_SET3_VALUE_MSB 24
+#define MAC_PCU_BASIC_RATE_SET3_VALUE_LSB 0
+#define MAC_PCU_BASIC_RATE_SET3_VALUE_MASK 0x01ffffff
+#define MAC_PCU_BASIC_RATE_SET3_VALUE_GET(x) (((x) & MAC_PCU_BASIC_RATE_SET3_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET3_VALUE_LSB)
+#define MAC_PCU_BASIC_RATE_SET3_VALUE_SET(x) (((x) << MAC_PCU_BASIC_RATE_SET3_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET3_VALUE_MASK)
+
+#define MAC_PCU_RX_INT_STATUS0_ADDRESS 0x00008338
+#define MAC_PCU_RX_INT_STATUS0_OFFSET 0x00000338
+#define MAC_PCU_RX_INT_STATUS0_DURATION_H_MSB 31
+#define MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB 24
+#define MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK 0xff000000
+#define MAC_PCU_RX_INT_STATUS0_DURATION_H_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK) >> MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB)
+#define MAC_PCU_RX_INT_STATUS0_DURATION_H_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB) & MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK)
+#define MAC_PCU_RX_INT_STATUS0_DURATION_L_MSB 23
+#define MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB 16
+#define MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK 0x00ff0000
+#define MAC_PCU_RX_INT_STATUS0_DURATION_L_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK) >> MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB)
+#define MAC_PCU_RX_INT_STATUS0_DURATION_L_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB) & MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK)
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MSB 15
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB 8
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK 0x0000ff00
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK) >> MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB)
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK)
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MSB 7
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB 0
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK 0x000000ff
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK) >> MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB)
+#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK)
+
+#define MAC_PCU_RX_INT_STATUS1_ADDRESS 0x0000833c
+#define MAC_PCU_RX_INT_STATUS1_OFFSET 0x0000033c
+#define MAC_PCU_RX_INT_STATUS1_VALUE_MSB 17
+#define MAC_PCU_RX_INT_STATUS1_VALUE_LSB 0
+#define MAC_PCU_RX_INT_STATUS1_VALUE_MASK 0x0003ffff
+#define MAC_PCU_RX_INT_STATUS1_VALUE_GET(x) (((x) & MAC_PCU_RX_INT_STATUS1_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS1_VALUE_LSB)
+#define MAC_PCU_RX_INT_STATUS1_VALUE_SET(x) (((x) << MAC_PCU_RX_INT_STATUS1_VALUE_LSB) & MAC_PCU_RX_INT_STATUS1_VALUE_MASK)
+
+#define MAC_PCU_RX_INT_STATUS2_ADDRESS 0x00008340
+#define MAC_PCU_RX_INT_STATUS2_OFFSET 0x00000340
+#define MAC_PCU_RX_INT_STATUS2_VALUE_MSB 26
+#define MAC_PCU_RX_INT_STATUS2_VALUE_LSB 0
+#define MAC_PCU_RX_INT_STATUS2_VALUE_MASK 0x07ffffff
+#define MAC_PCU_RX_INT_STATUS2_VALUE_GET(x) (((x) & MAC_PCU_RX_INT_STATUS2_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS2_VALUE_LSB)
+#define MAC_PCU_RX_INT_STATUS2_VALUE_SET(x) (((x) << MAC_PCU_RX_INT_STATUS2_VALUE_LSB) & MAC_PCU_RX_INT_STATUS2_VALUE_MASK)
+
+#define MAC_PCU_RX_INT_STATUS3_ADDRESS 0x00008344
+#define MAC_PCU_RX_INT_STATUS3_OFFSET 0x00000344
+#define MAC_PCU_RX_INT_STATUS3_VALUE_MSB 23
+#define MAC_PCU_RX_INT_STATUS3_VALUE_LSB 0
+#define MAC_PCU_RX_INT_STATUS3_VALUE_MASK 0x00ffffff
+#define MAC_PCU_RX_INT_STATUS3_VALUE_GET(x) (((x) & MAC_PCU_RX_INT_STATUS3_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS3_VALUE_LSB)
+#define MAC_PCU_RX_INT_STATUS3_VALUE_SET(x) (((x) << MAC_PCU_RX_INT_STATUS3_VALUE_LSB) & MAC_PCU_RX_INT_STATUS3_VALUE_MASK)
+
+#define HT_HALF_GI_RATE1_ADDRESS 0x00008348
+#define HT_HALF_GI_RATE1_OFFSET 0x00000348
+#define HT_HALF_GI_RATE1_MCS3_MSB 31
+#define HT_HALF_GI_RATE1_MCS3_LSB 24
+#define HT_HALF_GI_RATE1_MCS3_MASK 0xff000000
+#define HT_HALF_GI_RATE1_MCS3_GET(x) (((x) & HT_HALF_GI_RATE1_MCS3_MASK) >> HT_HALF_GI_RATE1_MCS3_LSB)
+#define HT_HALF_GI_RATE1_MCS3_SET(x) (((x) << HT_HALF_GI_RATE1_MCS3_LSB) & HT_HALF_GI_RATE1_MCS3_MASK)
+#define HT_HALF_GI_RATE1_MCS2_MSB 23
+#define HT_HALF_GI_RATE1_MCS2_LSB 16
+#define HT_HALF_GI_RATE1_MCS2_MASK 0x00ff0000
+#define HT_HALF_GI_RATE1_MCS2_GET(x) (((x) & HT_HALF_GI_RATE1_MCS2_MASK) >> HT_HALF_GI_RATE1_MCS2_LSB)
+#define HT_HALF_GI_RATE1_MCS2_SET(x) (((x) << HT_HALF_GI_RATE1_MCS2_LSB) & HT_HALF_GI_RATE1_MCS2_MASK)
+#define HT_HALF_GI_RATE1_MCS1_MSB 15
+#define HT_HALF_GI_RATE1_MCS1_LSB 8
+#define HT_HALF_GI_RATE1_MCS1_MASK 0x0000ff00
+#define HT_HALF_GI_RATE1_MCS1_GET(x) (((x) & HT_HALF_GI_RATE1_MCS1_MASK) >> HT_HALF_GI_RATE1_MCS1_LSB)
+#define HT_HALF_GI_RATE1_MCS1_SET(x) (((x) << HT_HALF_GI_RATE1_MCS1_LSB) & HT_HALF_GI_RATE1_MCS1_MASK)
+#define HT_HALF_GI_RATE1_MCS0_MSB 7
+#define HT_HALF_GI_RATE1_MCS0_LSB 0
+#define HT_HALF_GI_RATE1_MCS0_MASK 0x000000ff
+#define HT_HALF_GI_RATE1_MCS0_GET(x) (((x) & HT_HALF_GI_RATE1_MCS0_MASK) >> HT_HALF_GI_RATE1_MCS0_LSB)
+#define HT_HALF_GI_RATE1_MCS0_SET(x) (((x) << HT_HALF_GI_RATE1_MCS0_LSB) & HT_HALF_GI_RATE1_MCS0_MASK)
+
+#define HT_HALF_GI_RATE2_ADDRESS 0x0000834c
+#define HT_HALF_GI_RATE2_OFFSET 0x0000034c
+#define HT_HALF_GI_RATE2_MCS7_MSB 31
+#define HT_HALF_GI_RATE2_MCS7_LSB 24
+#define HT_HALF_GI_RATE2_MCS7_MASK 0xff000000
+#define HT_HALF_GI_RATE2_MCS7_GET(x) (((x) & HT_HALF_GI_RATE2_MCS7_MASK) >> HT_HALF_GI_RATE2_MCS7_LSB)
+#define HT_HALF_GI_RATE2_MCS7_SET(x) (((x) << HT_HALF_GI_RATE2_MCS7_LSB) & HT_HALF_GI_RATE2_MCS7_MASK)
+#define HT_HALF_GI_RATE2_MCS6_MSB 23
+#define HT_HALF_GI_RATE2_MCS6_LSB 16
+#define HT_HALF_GI_RATE2_MCS6_MASK 0x00ff0000
+#define HT_HALF_GI_RATE2_MCS6_GET(x) (((x) & HT_HALF_GI_RATE2_MCS6_MASK) >> HT_HALF_GI_RATE2_MCS6_LSB)
+#define HT_HALF_GI_RATE2_MCS6_SET(x) (((x) << HT_HALF_GI_RATE2_MCS6_LSB) & HT_HALF_GI_RATE2_MCS6_MASK)
+#define HT_HALF_GI_RATE2_MCS5_MSB 15
+#define HT_HALF_GI_RATE2_MCS5_LSB 8
+#define HT_HALF_GI_RATE2_MCS5_MASK 0x0000ff00
+#define HT_HALF_GI_RATE2_MCS5_GET(x) (((x) & HT_HALF_GI_RATE2_MCS5_MASK) >> HT_HALF_GI_RATE2_MCS5_LSB)
+#define HT_HALF_GI_RATE2_MCS5_SET(x) (((x) << HT_HALF_GI_RATE2_MCS5_LSB) & HT_HALF_GI_RATE2_MCS5_MASK)
+#define HT_HALF_GI_RATE2_MCS4_MSB 7
+#define HT_HALF_GI_RATE2_MCS4_LSB 0
+#define HT_HALF_GI_RATE2_MCS4_MASK 0x000000ff
+#define HT_HALF_GI_RATE2_MCS4_GET(x) (((x) & HT_HALF_GI_RATE2_MCS4_MASK) >> HT_HALF_GI_RATE2_MCS4_LSB)
+#define HT_HALF_GI_RATE2_MCS4_SET(x) (((x) << HT_HALF_GI_RATE2_MCS4_LSB) & HT_HALF_GI_RATE2_MCS4_MASK)
+
+#define HT_FULL_GI_RATE1_ADDRESS 0x00008350
+#define HT_FULL_GI_RATE1_OFFSET 0x00000350
+#define HT_FULL_GI_RATE1_MCS3_MSB 31
+#define HT_FULL_GI_RATE1_MCS3_LSB 24
+#define HT_FULL_GI_RATE1_MCS3_MASK 0xff000000
+#define HT_FULL_GI_RATE1_MCS3_GET(x) (((x) & HT_FULL_GI_RATE1_MCS3_MASK) >> HT_FULL_GI_RATE1_MCS3_LSB)
+#define HT_FULL_GI_RATE1_MCS3_SET(x) (((x) << HT_FULL_GI_RATE1_MCS3_LSB) & HT_FULL_GI_RATE1_MCS3_MASK)
+#define HT_FULL_GI_RATE1_MCS2_MSB 23
+#define HT_FULL_GI_RATE1_MCS2_LSB 16
+#define HT_FULL_GI_RATE1_MCS2_MASK 0x00ff0000
+#define HT_FULL_GI_RATE1_MCS2_GET(x) (((x) & HT_FULL_GI_RATE1_MCS2_MASK) >> HT_FULL_GI_RATE1_MCS2_LSB)
+#define HT_FULL_GI_RATE1_MCS2_SET(x) (((x) << HT_FULL_GI_RATE1_MCS2_LSB) & HT_FULL_GI_RATE1_MCS2_MASK)
+#define HT_FULL_GI_RATE1_MCS1_MSB 15
+#define HT_FULL_GI_RATE1_MCS1_LSB 8
+#define HT_FULL_GI_RATE1_MCS1_MASK 0x0000ff00
+#define HT_FULL_GI_RATE1_MCS1_GET(x) (((x) & HT_FULL_GI_RATE1_MCS1_MASK) >> HT_FULL_GI_RATE1_MCS1_LSB)
+#define HT_FULL_GI_RATE1_MCS1_SET(x) (((x) << HT_FULL_GI_RATE1_MCS1_LSB) & HT_FULL_GI_RATE1_MCS1_MASK)
+#define HT_FULL_GI_RATE1_MCS0_MSB 7
+#define HT_FULL_GI_RATE1_MCS0_LSB 0
+#define HT_FULL_GI_RATE1_MCS0_MASK 0x000000ff
+#define HT_FULL_GI_RATE1_MCS0_GET(x) (((x) & HT_FULL_GI_RATE1_MCS0_MASK) >> HT_FULL_GI_RATE1_MCS0_LSB)
+#define HT_FULL_GI_RATE1_MCS0_SET(x) (((x) << HT_FULL_GI_RATE1_MCS0_LSB) & HT_FULL_GI_RATE1_MCS0_MASK)
+
+#define HT_FULL_GI_RATE2_ADDRESS 0x00008354
+#define HT_FULL_GI_RATE2_OFFSET 0x00000354
+#define HT_FULL_GI_RATE2_MCS7_MSB 31
+#define HT_FULL_GI_RATE2_MCS7_LSB 24
+#define HT_FULL_GI_RATE2_MCS7_MASK 0xff000000
+#define HT_FULL_GI_RATE2_MCS7_GET(x) (((x) & HT_FULL_GI_RATE2_MCS7_MASK) >> HT_FULL_GI_RATE2_MCS7_LSB)
+#define HT_FULL_GI_RATE2_MCS7_SET(x) (((x) << HT_FULL_GI_RATE2_MCS7_LSB) & HT_FULL_GI_RATE2_MCS7_MASK)
+#define HT_FULL_GI_RATE2_MCS6_MSB 23
+#define HT_FULL_GI_RATE2_MCS6_LSB 16
+#define HT_FULL_GI_RATE2_MCS6_MASK 0x00ff0000
+#define HT_FULL_GI_RATE2_MCS6_GET(x) (((x) & HT_FULL_GI_RATE2_MCS6_MASK) >> HT_FULL_GI_RATE2_MCS6_LSB)
+#define HT_FULL_GI_RATE2_MCS6_SET(x) (((x) << HT_FULL_GI_RATE2_MCS6_LSB) & HT_FULL_GI_RATE2_MCS6_MASK)
+#define HT_FULL_GI_RATE2_MCS5_MSB 15
+#define HT_FULL_GI_RATE2_MCS5_LSB 8
+#define HT_FULL_GI_RATE2_MCS5_MASK 0x0000ff00
+#define HT_FULL_GI_RATE2_MCS5_GET(x) (((x) & HT_FULL_GI_RATE2_MCS5_MASK) >> HT_FULL_GI_RATE2_MCS5_LSB)
+#define HT_FULL_GI_RATE2_MCS5_SET(x) (((x) << HT_FULL_GI_RATE2_MCS5_LSB) & HT_FULL_GI_RATE2_MCS5_MASK)
+#define HT_FULL_GI_RATE2_MCS4_MSB 7
+#define HT_FULL_GI_RATE2_MCS4_LSB 0
+#define HT_FULL_GI_RATE2_MCS4_MASK 0x000000ff
+#define HT_FULL_GI_RATE2_MCS4_GET(x) (((x) & HT_FULL_GI_RATE2_MCS4_MASK) >> HT_FULL_GI_RATE2_MCS4_LSB)
+#define HT_FULL_GI_RATE2_MCS4_SET(x) (((x) << HT_FULL_GI_RATE2_MCS4_LSB) & HT_FULL_GI_RATE2_MCS4_MASK)
+
+#define LEGACY_RATE1_ADDRESS 0x00008358
+#define LEGACY_RATE1_OFFSET 0x00000358
+#define LEGACY_RATE1_RATE12_MSB 29
+#define LEGACY_RATE1_RATE12_LSB 24
+#define LEGACY_RATE1_RATE12_MASK 0x3f000000
+#define LEGACY_RATE1_RATE12_GET(x) (((x) & LEGACY_RATE1_RATE12_MASK) >> LEGACY_RATE1_RATE12_LSB)
+#define LEGACY_RATE1_RATE12_SET(x) (((x) << LEGACY_RATE1_RATE12_LSB) & LEGACY_RATE1_RATE12_MASK)
+#define LEGACY_RATE1_RATE11_MSB 23
+#define LEGACY_RATE1_RATE11_LSB 18
+#define LEGACY_RATE1_RATE11_MASK 0x00fc0000
+#define LEGACY_RATE1_RATE11_GET(x) (((x) & LEGACY_RATE1_RATE11_MASK) >> LEGACY_RATE1_RATE11_LSB)
+#define LEGACY_RATE1_RATE11_SET(x) (((x) << LEGACY_RATE1_RATE11_LSB) & LEGACY_RATE1_RATE11_MASK)
+#define LEGACY_RATE1_RATE10_MSB 17
+#define LEGACY_RATE1_RATE10_LSB 12
+#define LEGACY_RATE1_RATE10_MASK 0x0003f000
+#define LEGACY_RATE1_RATE10_GET(x) (((x) & LEGACY_RATE1_RATE10_MASK) >> LEGACY_RATE1_RATE10_LSB)
+#define LEGACY_RATE1_RATE10_SET(x) (((x) << LEGACY_RATE1_RATE10_LSB) & LEGACY_RATE1_RATE10_MASK)
+#define LEGACY_RATE1_RATE9_MSB 11
+#define LEGACY_RATE1_RATE9_LSB 6
+#define LEGACY_RATE1_RATE9_MASK 0x00000fc0
+#define LEGACY_RATE1_RATE9_GET(x) (((x) & LEGACY_RATE1_RATE9_MASK) >> LEGACY_RATE1_RATE9_LSB)
+#define LEGACY_RATE1_RATE9_SET(x) (((x) << LEGACY_RATE1_RATE9_LSB) & LEGACY_RATE1_RATE9_MASK)
+#define LEGACY_RATE1_RATE8_MSB 5
+#define LEGACY_RATE1_RATE8_LSB 0
+#define LEGACY_RATE1_RATE8_MASK 0x0000003f
+#define LEGACY_RATE1_RATE8_GET(x) (((x) & LEGACY_RATE1_RATE8_MASK) >> LEGACY_RATE1_RATE8_LSB)
+#define LEGACY_RATE1_RATE8_SET(x) (((x) << LEGACY_RATE1_RATE8_LSB) & LEGACY_RATE1_RATE8_MASK)
+
+#define LEGACY_RATE2_ADDRESS 0x0000835c
+#define LEGACY_RATE2_OFFSET 0x0000035c
+#define LEGACY_RATE2_RATE25_MSB 29
+#define LEGACY_RATE2_RATE25_LSB 24
+#define LEGACY_RATE2_RATE25_MASK 0x3f000000
+#define LEGACY_RATE2_RATE25_GET(x) (((x) & LEGACY_RATE2_RATE25_MASK) >> LEGACY_RATE2_RATE25_LSB)
+#define LEGACY_RATE2_RATE25_SET(x) (((x) << LEGACY_RATE2_RATE25_LSB) & LEGACY_RATE2_RATE25_MASK)
+#define LEGACY_RATE2_RATE24_MSB 23
+#define LEGACY_RATE2_RATE24_LSB 18
+#define LEGACY_RATE2_RATE24_MASK 0x00fc0000
+#define LEGACY_RATE2_RATE24_GET(x) (((x) & LEGACY_RATE2_RATE24_MASK) >> LEGACY_RATE2_RATE24_LSB)
+#define LEGACY_RATE2_RATE24_SET(x) (((x) << LEGACY_RATE2_RATE24_LSB) & LEGACY_RATE2_RATE24_MASK)
+#define LEGACY_RATE2_RATE15_MSB 17
+#define LEGACY_RATE2_RATE15_LSB 12
+#define LEGACY_RATE2_RATE15_MASK 0x0003f000
+#define LEGACY_RATE2_RATE15_GET(x) (((x) & LEGACY_RATE2_RATE15_MASK) >> LEGACY_RATE2_RATE15_LSB)
+#define LEGACY_RATE2_RATE15_SET(x) (((x) << LEGACY_RATE2_RATE15_LSB) & LEGACY_RATE2_RATE15_MASK)
+#define LEGACY_RATE2_RATE14_MSB 11
+#define LEGACY_RATE2_RATE14_LSB 6
+#define LEGACY_RATE2_RATE14_MASK 0x00000fc0
+#define LEGACY_RATE2_RATE14_GET(x) (((x) & LEGACY_RATE2_RATE14_MASK) >> LEGACY_RATE2_RATE14_LSB)
+#define LEGACY_RATE2_RATE14_SET(x) (((x) << LEGACY_RATE2_RATE14_LSB) & LEGACY_RATE2_RATE14_MASK)
+#define LEGACY_RATE2_RATE13_MSB 5
+#define LEGACY_RATE2_RATE13_LSB 0
+#define LEGACY_RATE2_RATE13_MASK 0x0000003f
+#define LEGACY_RATE2_RATE13_GET(x) (((x) & LEGACY_RATE2_RATE13_MASK) >> LEGACY_RATE2_RATE13_LSB)
+#define LEGACY_RATE2_RATE13_SET(x) (((x) << LEGACY_RATE2_RATE13_LSB) & LEGACY_RATE2_RATE13_MASK)
+
+#define LEGACY_RATE3_ADDRESS 0x00008360
+#define LEGACY_RATE3_OFFSET 0x00000360
+#define LEGACY_RATE3_RATE30_MSB 29
+#define LEGACY_RATE3_RATE30_LSB 24
+#define LEGACY_RATE3_RATE30_MASK 0x3f000000
+#define LEGACY_RATE3_RATE30_GET(x) (((x) & LEGACY_RATE3_RATE30_MASK) >> LEGACY_RATE3_RATE30_LSB)
+#define LEGACY_RATE3_RATE30_SET(x) (((x) << LEGACY_RATE3_RATE30_LSB) & LEGACY_RATE3_RATE30_MASK)
+#define LEGACY_RATE3_RATE29_MSB 23
+#define LEGACY_RATE3_RATE29_LSB 18
+#define LEGACY_RATE3_RATE29_MASK 0x00fc0000
+#define LEGACY_RATE3_RATE29_GET(x) (((x) & LEGACY_RATE3_RATE29_MASK) >> LEGACY_RATE3_RATE29_LSB)
+#define LEGACY_RATE3_RATE29_SET(x) (((x) << LEGACY_RATE3_RATE29_LSB) & LEGACY_RATE3_RATE29_MASK)
+#define LEGACY_RATE3_RATE28_MSB 17
+#define LEGACY_RATE3_RATE28_LSB 12
+#define LEGACY_RATE3_RATE28_MASK 0x0003f000
+#define LEGACY_RATE3_RATE28_GET(x) (((x) & LEGACY_RATE3_RATE28_MASK) >> LEGACY_RATE3_RATE28_LSB)
+#define LEGACY_RATE3_RATE28_SET(x) (((x) << LEGACY_RATE3_RATE28_LSB) & LEGACY_RATE3_RATE28_MASK)
+#define LEGACY_RATE3_RATE27_MSB 11
+#define LEGACY_RATE3_RATE27_LSB 6
+#define LEGACY_RATE3_RATE27_MASK 0x00000fc0
+#define LEGACY_RATE3_RATE27_GET(x) (((x) & LEGACY_RATE3_RATE27_MASK) >> LEGACY_RATE3_RATE27_LSB)
+#define LEGACY_RATE3_RATE27_SET(x) (((x) << LEGACY_RATE3_RATE27_LSB) & LEGACY_RATE3_RATE27_MASK)
+#define LEGACY_RATE3_RATE26_MSB 5
+#define LEGACY_RATE3_RATE26_LSB 0
+#define LEGACY_RATE3_RATE26_MASK 0x0000003f
+#define LEGACY_RATE3_RATE26_GET(x) (((x) & LEGACY_RATE3_RATE26_MASK) >> LEGACY_RATE3_RATE26_LSB)
+#define LEGACY_RATE3_RATE26_SET(x) (((x) << LEGACY_RATE3_RATE26_LSB) & LEGACY_RATE3_RATE26_MASK)
+
+#define RX_INT_FILTER_ADDRESS 0x00008364
+#define RX_INT_FILTER_OFFSET 0x00000364
+#define RX_INT_FILTER_BEACON_MSB 17
+#define RX_INT_FILTER_BEACON_LSB 17
+#define RX_INT_FILTER_BEACON_MASK 0x00020000
+#define RX_INT_FILTER_BEACON_GET(x) (((x) & RX_INT_FILTER_BEACON_MASK) >> RX_INT_FILTER_BEACON_LSB)
+#define RX_INT_FILTER_BEACON_SET(x) (((x) << RX_INT_FILTER_BEACON_LSB) & RX_INT_FILTER_BEACON_MASK)
+#define RX_INT_FILTER_AMPDU_MSB 16
+#define RX_INT_FILTER_AMPDU_LSB 16
+#define RX_INT_FILTER_AMPDU_MASK 0x00010000
+#define RX_INT_FILTER_AMPDU_GET(x) (((x) & RX_INT_FILTER_AMPDU_MASK) >> RX_INT_FILTER_AMPDU_LSB)
+#define RX_INT_FILTER_AMPDU_SET(x) (((x) << RX_INT_FILTER_AMPDU_LSB) & RX_INT_FILTER_AMPDU_MASK)
+#define RX_INT_FILTER_EOSP_MSB 15
+#define RX_INT_FILTER_EOSP_LSB 15
+#define RX_INT_FILTER_EOSP_MASK 0x00008000
+#define RX_INT_FILTER_EOSP_GET(x) (((x) & RX_INT_FILTER_EOSP_MASK) >> RX_INT_FILTER_EOSP_LSB)
+#define RX_INT_FILTER_EOSP_SET(x) (((x) << RX_INT_FILTER_EOSP_LSB) & RX_INT_FILTER_EOSP_MASK)
+#define RX_INT_FILTER_LENGTH_LOW_MSB 14
+#define RX_INT_FILTER_LENGTH_LOW_LSB 14
+#define RX_INT_FILTER_LENGTH_LOW_MASK 0x00004000
+#define RX_INT_FILTER_LENGTH_LOW_GET(x) (((x) & RX_INT_FILTER_LENGTH_LOW_MASK) >> RX_INT_FILTER_LENGTH_LOW_LSB)
+#define RX_INT_FILTER_LENGTH_LOW_SET(x) (((x) << RX_INT_FILTER_LENGTH_LOW_LSB) & RX_INT_FILTER_LENGTH_LOW_MASK)
+#define RX_INT_FILTER_LENGTH_HIGH_MSB 13
+#define RX_INT_FILTER_LENGTH_HIGH_LSB 13
+#define RX_INT_FILTER_LENGTH_HIGH_MASK 0x00002000
+#define RX_INT_FILTER_LENGTH_HIGH_GET(x) (((x) & RX_INT_FILTER_LENGTH_HIGH_MASK) >> RX_INT_FILTER_LENGTH_HIGH_LSB)
+#define RX_INT_FILTER_LENGTH_HIGH_SET(x) (((x) << RX_INT_FILTER_LENGTH_HIGH_LSB) & RX_INT_FILTER_LENGTH_HIGH_MASK)
+#define RX_INT_FILTER_RSSI_MSB 12
+#define RX_INT_FILTER_RSSI_LSB 12
+#define RX_INT_FILTER_RSSI_MASK 0x00001000
+#define RX_INT_FILTER_RSSI_GET(x) (((x) & RX_INT_FILTER_RSSI_MASK) >> RX_INT_FILTER_RSSI_LSB)
+#define RX_INT_FILTER_RSSI_SET(x) (((x) << RX_INT_FILTER_RSSI_LSB) & RX_INT_FILTER_RSSI_MASK)
+#define RX_INT_FILTER_RATE_LOW_MSB 11
+#define RX_INT_FILTER_RATE_LOW_LSB 11
+#define RX_INT_FILTER_RATE_LOW_MASK 0x00000800
+#define RX_INT_FILTER_RATE_LOW_GET(x) (((x) & RX_INT_FILTER_RATE_LOW_MASK) >> RX_INT_FILTER_RATE_LOW_LSB)
+#define RX_INT_FILTER_RATE_LOW_SET(x) (((x) << RX_INT_FILTER_RATE_LOW_LSB) & RX_INT_FILTER_RATE_LOW_MASK)
+#define RX_INT_FILTER_RATE_HIGH_MSB 10
+#define RX_INT_FILTER_RATE_HIGH_LSB 10
+#define RX_INT_FILTER_RATE_HIGH_MASK 0x00000400
+#define RX_INT_FILTER_RATE_HIGH_GET(x) (((x) & RX_INT_FILTER_RATE_HIGH_MASK) >> RX_INT_FILTER_RATE_HIGH_LSB)
+#define RX_INT_FILTER_RATE_HIGH_SET(x) (((x) << RX_INT_FILTER_RATE_HIGH_LSB) & RX_INT_FILTER_RATE_HIGH_MASK)
+#define RX_INT_FILTER_MORE_FRAG_MSB 9
+#define RX_INT_FILTER_MORE_FRAG_LSB 9
+#define RX_INT_FILTER_MORE_FRAG_MASK 0x00000200
+#define RX_INT_FILTER_MORE_FRAG_GET(x) (((x) & RX_INT_FILTER_MORE_FRAG_MASK) >> RX_INT_FILTER_MORE_FRAG_LSB)
+#define RX_INT_FILTER_MORE_FRAG_SET(x) (((x) << RX_INT_FILTER_MORE_FRAG_LSB) & RX_INT_FILTER_MORE_FRAG_MASK)
+#define RX_INT_FILTER_MORE_DATA_MSB 8
+#define RX_INT_FILTER_MORE_DATA_LSB 8
+#define RX_INT_FILTER_MORE_DATA_MASK 0x00000100
+#define RX_INT_FILTER_MORE_DATA_GET(x) (((x) & RX_INT_FILTER_MORE_DATA_MASK) >> RX_INT_FILTER_MORE_DATA_LSB)
+#define RX_INT_FILTER_MORE_DATA_SET(x) (((x) << RX_INT_FILTER_MORE_DATA_LSB) & RX_INT_FILTER_MORE_DATA_MASK)
+#define RX_INT_FILTER_RETRY_MSB 7
+#define RX_INT_FILTER_RETRY_LSB 7
+#define RX_INT_FILTER_RETRY_MASK 0x00000080
+#define RX_INT_FILTER_RETRY_GET(x) (((x) & RX_INT_FILTER_RETRY_MASK) >> RX_INT_FILTER_RETRY_LSB)
+#define RX_INT_FILTER_RETRY_SET(x) (((x) << RX_INT_FILTER_RETRY_LSB) & RX_INT_FILTER_RETRY_MASK)
+#define RX_INT_FILTER_CTS_MSB 6
+#define RX_INT_FILTER_CTS_LSB 6
+#define RX_INT_FILTER_CTS_MASK 0x00000040
+#define RX_INT_FILTER_CTS_GET(x) (((x) & RX_INT_FILTER_CTS_MASK) >> RX_INT_FILTER_CTS_LSB)
+#define RX_INT_FILTER_CTS_SET(x) (((x) << RX_INT_FILTER_CTS_LSB) & RX_INT_FILTER_CTS_MASK)
+#define RX_INT_FILTER_ACK_MSB 5
+#define RX_INT_FILTER_ACK_LSB 5
+#define RX_INT_FILTER_ACK_MASK 0x00000020
+#define RX_INT_FILTER_ACK_GET(x) (((x) & RX_INT_FILTER_ACK_MASK) >> RX_INT_FILTER_ACK_LSB)
+#define RX_INT_FILTER_ACK_SET(x) (((x) << RX_INT_FILTER_ACK_LSB) & RX_INT_FILTER_ACK_MASK)
+#define RX_INT_FILTER_RTS_MSB 4
+#define RX_INT_FILTER_RTS_LSB 4
+#define RX_INT_FILTER_RTS_MASK 0x00000010
+#define RX_INT_FILTER_RTS_GET(x) (((x) & RX_INT_FILTER_RTS_MASK) >> RX_INT_FILTER_RTS_LSB)
+#define RX_INT_FILTER_RTS_SET(x) (((x) << RX_INT_FILTER_RTS_LSB) & RX_INT_FILTER_RTS_MASK)
+#define RX_INT_FILTER_MCAST_MSB 3
+#define RX_INT_FILTER_MCAST_LSB 3
+#define RX_INT_FILTER_MCAST_MASK 0x00000008
+#define RX_INT_FILTER_MCAST_GET(x) (((x) & RX_INT_FILTER_MCAST_MASK) >> RX_INT_FILTER_MCAST_LSB)
+#define RX_INT_FILTER_MCAST_SET(x) (((x) << RX_INT_FILTER_MCAST_LSB) & RX_INT_FILTER_MCAST_MASK)
+#define RX_INT_FILTER_BCAST_MSB 2
+#define RX_INT_FILTER_BCAST_LSB 2
+#define RX_INT_FILTER_BCAST_MASK 0x00000004
+#define RX_INT_FILTER_BCAST_GET(x) (((x) & RX_INT_FILTER_BCAST_MASK) >> RX_INT_FILTER_BCAST_LSB)
+#define RX_INT_FILTER_BCAST_SET(x) (((x) << RX_INT_FILTER_BCAST_LSB) & RX_INT_FILTER_BCAST_MASK)
+#define RX_INT_FILTER_DIRECTED_MSB 1
+#define RX_INT_FILTER_DIRECTED_LSB 1
+#define RX_INT_FILTER_DIRECTED_MASK 0x00000002
+#define RX_INT_FILTER_DIRECTED_GET(x) (((x) & RX_INT_FILTER_DIRECTED_MASK) >> RX_INT_FILTER_DIRECTED_LSB)
+#define RX_INT_FILTER_DIRECTED_SET(x) (((x) << RX_INT_FILTER_DIRECTED_LSB) & RX_INT_FILTER_DIRECTED_MASK)
+#define RX_INT_FILTER_ENABLE_MSB 0
+#define RX_INT_FILTER_ENABLE_LSB 0
+#define RX_INT_FILTER_ENABLE_MASK 0x00000001
+#define RX_INT_FILTER_ENABLE_GET(x) (((x) & RX_INT_FILTER_ENABLE_MASK) >> RX_INT_FILTER_ENABLE_LSB)
+#define RX_INT_FILTER_ENABLE_SET(x) (((x) << RX_INT_FILTER_ENABLE_LSB) & RX_INT_FILTER_ENABLE_MASK)
+
+#define RX_INT_OVERFLOW_ADDRESS 0x00008368
+#define RX_INT_OVERFLOW_OFFSET 0x00000368
+#define RX_INT_OVERFLOW_STATUS_MSB 0
+#define RX_INT_OVERFLOW_STATUS_LSB 0
+#define RX_INT_OVERFLOW_STATUS_MASK 0x00000001
+#define RX_INT_OVERFLOW_STATUS_GET(x) (((x) & RX_INT_OVERFLOW_STATUS_MASK) >> RX_INT_OVERFLOW_STATUS_LSB)
+#define RX_INT_OVERFLOW_STATUS_SET(x) (((x) << RX_INT_OVERFLOW_STATUS_LSB) & RX_INT_OVERFLOW_STATUS_MASK)
+
+#define RX_FILTER_THRESH_ADDRESS 0x0000836c
+#define RX_FILTER_THRESH_OFFSET 0x0000036c
+#define RX_FILTER_THRESH_RSSI_LOW_MSB 23
+#define RX_FILTER_THRESH_RSSI_LOW_LSB 16
+#define RX_FILTER_THRESH_RSSI_LOW_MASK 0x00ff0000
+#define RX_FILTER_THRESH_RSSI_LOW_GET(x) (((x) & RX_FILTER_THRESH_RSSI_LOW_MASK) >> RX_FILTER_THRESH_RSSI_LOW_LSB)
+#define RX_FILTER_THRESH_RSSI_LOW_SET(x) (((x) << RX_FILTER_THRESH_RSSI_LOW_LSB) & RX_FILTER_THRESH_RSSI_LOW_MASK)
+#define RX_FILTER_THRESH_RATE_LOW_MSB 15
+#define RX_FILTER_THRESH_RATE_LOW_LSB 8
+#define RX_FILTER_THRESH_RATE_LOW_MASK 0x0000ff00
+#define RX_FILTER_THRESH_RATE_LOW_GET(x) (((x) & RX_FILTER_THRESH_RATE_LOW_MASK) >> RX_FILTER_THRESH_RATE_LOW_LSB)
+#define RX_FILTER_THRESH_RATE_LOW_SET(x) (((x) << RX_FILTER_THRESH_RATE_LOW_LSB) & RX_FILTER_THRESH_RATE_LOW_MASK)
+#define RX_FILTER_THRESH_RATE_HIGH_MSB 7
+#define RX_FILTER_THRESH_RATE_HIGH_LSB 0
+#define RX_FILTER_THRESH_RATE_HIGH_MASK 0x000000ff
+#define RX_FILTER_THRESH_RATE_HIGH_GET(x) (((x) & RX_FILTER_THRESH_RATE_HIGH_MASK) >> RX_FILTER_THRESH_RATE_HIGH_LSB)
+#define RX_FILTER_THRESH_RATE_HIGH_SET(x) (((x) << RX_FILTER_THRESH_RATE_HIGH_LSB) & RX_FILTER_THRESH_RATE_HIGH_MASK)
+
+#define RX_FILTER_THRESH1_ADDRESS 0x00008370
+#define RX_FILTER_THRESH1_OFFSET 0x00000370
+#define RX_FILTER_THRESH1_LENGTH_LOW_MSB 23
+#define RX_FILTER_THRESH1_LENGTH_LOW_LSB 12
+#define RX_FILTER_THRESH1_LENGTH_LOW_MASK 0x00fff000
+#define RX_FILTER_THRESH1_LENGTH_LOW_GET(x) (((x) & RX_FILTER_THRESH1_LENGTH_LOW_MASK) >> RX_FILTER_THRESH1_LENGTH_LOW_LSB)
+#define RX_FILTER_THRESH1_LENGTH_LOW_SET(x) (((x) << RX_FILTER_THRESH1_LENGTH_LOW_LSB) & RX_FILTER_THRESH1_LENGTH_LOW_MASK)
+#define RX_FILTER_THRESH1_LENGTH_HIGH_MSB 11
+#define RX_FILTER_THRESH1_LENGTH_HIGH_LSB 0
+#define RX_FILTER_THRESH1_LENGTH_HIGH_MASK 0x00000fff
+#define RX_FILTER_THRESH1_LENGTH_HIGH_GET(x) (((x) & RX_FILTER_THRESH1_LENGTH_HIGH_MASK) >> RX_FILTER_THRESH1_LENGTH_HIGH_LSB)
+#define RX_FILTER_THRESH1_LENGTH_HIGH_SET(x) (((x) << RX_FILTER_THRESH1_LENGTH_HIGH_LSB) & RX_FILTER_THRESH1_LENGTH_HIGH_MASK)
+
+#define RX_PRIORITY_THRESH0_ADDRESS 0x00008374
+#define RX_PRIORITY_THRESH0_OFFSET 0x00000374
+#define RX_PRIORITY_THRESH0_RSSI_LOW_MSB 31
+#define RX_PRIORITY_THRESH0_RSSI_LOW_LSB 24
+#define RX_PRIORITY_THRESH0_RSSI_LOW_MASK 0xff000000
+#define RX_PRIORITY_THRESH0_RSSI_LOW_GET(x) (((x) & RX_PRIORITY_THRESH0_RSSI_LOW_MASK) >> RX_PRIORITY_THRESH0_RSSI_LOW_LSB)
+#define RX_PRIORITY_THRESH0_RSSI_LOW_SET(x) (((x) << RX_PRIORITY_THRESH0_RSSI_LOW_LSB) & RX_PRIORITY_THRESH0_RSSI_LOW_MASK)
+#define RX_PRIORITY_THRESH0_RSSI_HIGH_MSB 23
+#define RX_PRIORITY_THRESH0_RSSI_HIGH_LSB 16
+#define RX_PRIORITY_THRESH0_RSSI_HIGH_MASK 0x00ff0000
+#define RX_PRIORITY_THRESH0_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH0_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH0_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH0_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH0_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH0_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH0_RATE_LOW_MSB 15
+#define RX_PRIORITY_THRESH0_RATE_LOW_LSB 8
+#define RX_PRIORITY_THRESH0_RATE_LOW_MASK 0x0000ff00
+#define RX_PRIORITY_THRESH0_RATE_LOW_GET(x) (((x) & RX_PRIORITY_THRESH0_RATE_LOW_MASK) >> RX_PRIORITY_THRESH0_RATE_LOW_LSB)
+#define RX_PRIORITY_THRESH0_RATE_LOW_SET(x) (((x) << RX_PRIORITY_THRESH0_RATE_LOW_LSB) & RX_PRIORITY_THRESH0_RATE_LOW_MASK)
+#define RX_PRIORITY_THRESH0_RATE_HIGH_MSB 7
+#define RX_PRIORITY_THRESH0_RATE_HIGH_LSB 0
+#define RX_PRIORITY_THRESH0_RATE_HIGH_MASK 0x000000ff
+#define RX_PRIORITY_THRESH0_RATE_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH0_RATE_HIGH_MASK) >> RX_PRIORITY_THRESH0_RATE_HIGH_LSB)
+#define RX_PRIORITY_THRESH0_RATE_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH0_RATE_HIGH_LSB) & RX_PRIORITY_THRESH0_RATE_HIGH_MASK)
+
+#define RX_PRIORITY_THRESH1_ADDRESS 0x00008378
+#define RX_PRIORITY_THRESH1_OFFSET 0x00000378
+#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MSB 31
+#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB 24
+#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK 0xff000000
+#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH1_LENGTH_LOW_MSB 23
+#define RX_PRIORITY_THRESH1_LENGTH_LOW_LSB 12
+#define RX_PRIORITY_THRESH1_LENGTH_LOW_MASK 0x00fff000
+#define RX_PRIORITY_THRESH1_LENGTH_LOW_GET(x) (((x) & RX_PRIORITY_THRESH1_LENGTH_LOW_MASK) >> RX_PRIORITY_THRESH1_LENGTH_LOW_LSB)
+#define RX_PRIORITY_THRESH1_LENGTH_LOW_SET(x) (((x) << RX_PRIORITY_THRESH1_LENGTH_LOW_LSB) & RX_PRIORITY_THRESH1_LENGTH_LOW_MASK)
+#define RX_PRIORITY_THRESH1_LENGTH_HIGH_MSB 11
+#define RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB 0
+#define RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK 0x00000fff
+#define RX_PRIORITY_THRESH1_LENGTH_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK) >> RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB)
+#define RX_PRIORITY_THRESH1_LENGTH_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB) & RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK)
+
+#define RX_PRIORITY_THRESH2_ADDRESS 0x0000837c
+#define RX_PRIORITY_THRESH2_OFFSET 0x0000037c
+#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MSB 31
+#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB 24
+#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK 0xff000000
+#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MSB 23
+#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB 16
+#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK 0x00ff0000
+#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MSB 15
+#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB 8
+#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK 0x0000ff00
+#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MSB 7
+#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB 0
+#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK 0x000000ff
+#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK)
+
+#define RX_PRIORITY_THRESH3_ADDRESS 0x00008380
+#define RX_PRIORITY_THRESH3_OFFSET 0x00000380
+#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MSB 15
+#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB 8
+#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK 0x0000ff00
+#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK)
+#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MSB 7
+#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB 0
+#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK 0x000000ff
+#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB)
+#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK)
+
+#define RX_PRIORITY_OFFSET0_ADDRESS 0x00008384
+#define RX_PRIORITY_OFFSET0_OFFSET 0x00000384
+#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MSB 29
+#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB 24
+#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK 0x3f000000
+#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET0_RSSI_LOW_MSB 23
+#define RX_PRIORITY_OFFSET0_RSSI_LOW_LSB 18
+#define RX_PRIORITY_OFFSET0_RSSI_LOW_MASK 0x00fc0000
+#define RX_PRIORITY_OFFSET0_RSSI_LOW_GET(x) (((x) & RX_PRIORITY_OFFSET0_RSSI_LOW_MASK) >> RX_PRIORITY_OFFSET0_RSSI_LOW_LSB)
+#define RX_PRIORITY_OFFSET0_RSSI_LOW_SET(x) (((x) << RX_PRIORITY_OFFSET0_RSSI_LOW_LSB) & RX_PRIORITY_OFFSET0_RSSI_LOW_MASK)
+#define RX_PRIORITY_OFFSET0_RSSI_HIGH_MSB 17
+#define RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB 12
+#define RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET0_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET0_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MSB 11
+#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB 6
+#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_GET(x) (((x) & RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK) >> RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB)
+#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_SET(x) (((x) << RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB) & RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK)
+#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MSB 5
+#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB 0
+#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK) >> RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB)
+#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB) & RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK)
+
+#define RX_PRIORITY_OFFSET1_ADDRESS 0x00008388
+#define RX_PRIORITY_OFFSET1_OFFSET 0x00000388
+#define RX_PRIORITY_OFFSET1_RTS_MSB 29
+#define RX_PRIORITY_OFFSET1_RTS_LSB 24
+#define RX_PRIORITY_OFFSET1_RTS_MASK 0x3f000000
+#define RX_PRIORITY_OFFSET1_RTS_GET(x) (((x) & RX_PRIORITY_OFFSET1_RTS_MASK) >> RX_PRIORITY_OFFSET1_RTS_LSB)
+#define RX_PRIORITY_OFFSET1_RTS_SET(x) (((x) << RX_PRIORITY_OFFSET1_RTS_LSB) & RX_PRIORITY_OFFSET1_RTS_MASK)
+#define RX_PRIORITY_OFFSET1_RETX_MSB 23
+#define RX_PRIORITY_OFFSET1_RETX_LSB 18
+#define RX_PRIORITY_OFFSET1_RETX_MASK 0x00fc0000
+#define RX_PRIORITY_OFFSET1_RETX_GET(x) (((x) & RX_PRIORITY_OFFSET1_RETX_MASK) >> RX_PRIORITY_OFFSET1_RETX_LSB)
+#define RX_PRIORITY_OFFSET1_RETX_SET(x) (((x) << RX_PRIORITY_OFFSET1_RETX_LSB) & RX_PRIORITY_OFFSET1_RETX_MASK)
+#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MSB 17
+#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB 12
+#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET1_LENGTH_LOW_MSB 11
+#define RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB 6
+#define RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET1_LENGTH_LOW_GET(x) (((x) & RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK) >> RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB)
+#define RX_PRIORITY_OFFSET1_LENGTH_LOW_SET(x) (((x) << RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB) & RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK)
+#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_MSB 5
+#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB 0
+#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK) >> RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB)
+#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB) & RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK)
+
+#define RX_PRIORITY_OFFSET2_ADDRESS 0x0000838c
+#define RX_PRIORITY_OFFSET2_OFFSET 0x0000038c
+#define RX_PRIORITY_OFFSET2_BEACON_MSB 29
+#define RX_PRIORITY_OFFSET2_BEACON_LSB 24
+#define RX_PRIORITY_OFFSET2_BEACON_MASK 0x3f000000
+#define RX_PRIORITY_OFFSET2_BEACON_GET(x) (((x) & RX_PRIORITY_OFFSET2_BEACON_MASK) >> RX_PRIORITY_OFFSET2_BEACON_LSB)
+#define RX_PRIORITY_OFFSET2_BEACON_SET(x) (((x) << RX_PRIORITY_OFFSET2_BEACON_LSB) & RX_PRIORITY_OFFSET2_BEACON_MASK)
+#define RX_PRIORITY_OFFSET2_MGMT_MSB 23
+#define RX_PRIORITY_OFFSET2_MGMT_LSB 18
+#define RX_PRIORITY_OFFSET2_MGMT_MASK 0x00fc0000
+#define RX_PRIORITY_OFFSET2_MGMT_GET(x) (((x) & RX_PRIORITY_OFFSET2_MGMT_MASK) >> RX_PRIORITY_OFFSET2_MGMT_LSB)
+#define RX_PRIORITY_OFFSET2_MGMT_SET(x) (((x) << RX_PRIORITY_OFFSET2_MGMT_LSB) & RX_PRIORITY_OFFSET2_MGMT_MASK)
+#define RX_PRIORITY_OFFSET2_ATIM_MSB 17
+#define RX_PRIORITY_OFFSET2_ATIM_LSB 12
+#define RX_PRIORITY_OFFSET2_ATIM_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET2_ATIM_GET(x) (((x) & RX_PRIORITY_OFFSET2_ATIM_MASK) >> RX_PRIORITY_OFFSET2_ATIM_LSB)
+#define RX_PRIORITY_OFFSET2_ATIM_SET(x) (((x) << RX_PRIORITY_OFFSET2_ATIM_LSB) & RX_PRIORITY_OFFSET2_ATIM_MASK)
+#define RX_PRIORITY_OFFSET2_PRESP_MSB 11
+#define RX_PRIORITY_OFFSET2_PRESP_LSB 6
+#define RX_PRIORITY_OFFSET2_PRESP_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET2_PRESP_GET(x) (((x) & RX_PRIORITY_OFFSET2_PRESP_MASK) >> RX_PRIORITY_OFFSET2_PRESP_LSB)
+#define RX_PRIORITY_OFFSET2_PRESP_SET(x) (((x) << RX_PRIORITY_OFFSET2_PRESP_LSB) & RX_PRIORITY_OFFSET2_PRESP_MASK)
+#define RX_PRIORITY_OFFSET2_XCAST_MSB 5
+#define RX_PRIORITY_OFFSET2_XCAST_LSB 0
+#define RX_PRIORITY_OFFSET2_XCAST_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET2_XCAST_GET(x) (((x) & RX_PRIORITY_OFFSET2_XCAST_MASK) >> RX_PRIORITY_OFFSET2_XCAST_LSB)
+#define RX_PRIORITY_OFFSET2_XCAST_SET(x) (((x) << RX_PRIORITY_OFFSET2_XCAST_LSB) & RX_PRIORITY_OFFSET2_XCAST_MASK)
+
+#define RX_PRIORITY_OFFSET3_ADDRESS 0x00008390
+#define RX_PRIORITY_OFFSET3_OFFSET 0x00000390
+#define RX_PRIORITY_OFFSET3_PS_POLL_MSB 29
+#define RX_PRIORITY_OFFSET3_PS_POLL_LSB 24
+#define RX_PRIORITY_OFFSET3_PS_POLL_MASK 0x3f000000
+#define RX_PRIORITY_OFFSET3_PS_POLL_GET(x) (((x) & RX_PRIORITY_OFFSET3_PS_POLL_MASK) >> RX_PRIORITY_OFFSET3_PS_POLL_LSB)
+#define RX_PRIORITY_OFFSET3_PS_POLL_SET(x) (((x) << RX_PRIORITY_OFFSET3_PS_POLL_LSB) & RX_PRIORITY_OFFSET3_PS_POLL_MASK)
+#define RX_PRIORITY_OFFSET3_AMSDU_MSB 23
+#define RX_PRIORITY_OFFSET3_AMSDU_LSB 18
+#define RX_PRIORITY_OFFSET3_AMSDU_MASK 0x00fc0000
+#define RX_PRIORITY_OFFSET3_AMSDU_GET(x) (((x) & RX_PRIORITY_OFFSET3_AMSDU_MASK) >> RX_PRIORITY_OFFSET3_AMSDU_LSB)
+#define RX_PRIORITY_OFFSET3_AMSDU_SET(x) (((x) << RX_PRIORITY_OFFSET3_AMSDU_LSB) & RX_PRIORITY_OFFSET3_AMSDU_MASK)
+#define RX_PRIORITY_OFFSET3_AMPDU_MSB 17
+#define RX_PRIORITY_OFFSET3_AMPDU_LSB 12
+#define RX_PRIORITY_OFFSET3_AMPDU_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET3_AMPDU_GET(x) (((x) & RX_PRIORITY_OFFSET3_AMPDU_MASK) >> RX_PRIORITY_OFFSET3_AMPDU_LSB)
+#define RX_PRIORITY_OFFSET3_AMPDU_SET(x) (((x) << RX_PRIORITY_OFFSET3_AMPDU_LSB) & RX_PRIORITY_OFFSET3_AMPDU_MASK)
+#define RX_PRIORITY_OFFSET3_EOSP_MSB 11
+#define RX_PRIORITY_OFFSET3_EOSP_LSB 6
+#define RX_PRIORITY_OFFSET3_EOSP_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET3_EOSP_GET(x) (((x) & RX_PRIORITY_OFFSET3_EOSP_MASK) >> RX_PRIORITY_OFFSET3_EOSP_LSB)
+#define RX_PRIORITY_OFFSET3_EOSP_SET(x) (((x) << RX_PRIORITY_OFFSET3_EOSP_LSB) & RX_PRIORITY_OFFSET3_EOSP_MASK)
+#define RX_PRIORITY_OFFSET3_MORE_MSB 5
+#define RX_PRIORITY_OFFSET3_MORE_LSB 0
+#define RX_PRIORITY_OFFSET3_MORE_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET3_MORE_GET(x) (((x) & RX_PRIORITY_OFFSET3_MORE_MASK) >> RX_PRIORITY_OFFSET3_MORE_LSB)
+#define RX_PRIORITY_OFFSET3_MORE_SET(x) (((x) << RX_PRIORITY_OFFSET3_MORE_LSB) & RX_PRIORITY_OFFSET3_MORE_MASK)
+
+#define RX_PRIORITY_OFFSET4_ADDRESS 0x00008394
+#define RX_PRIORITY_OFFSET4_OFFSET 0x00000394
+#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MSB 29
+#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB 24
+#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK 0x3f000000
+#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MSB 23
+#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB 18
+#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK 0x00fc0000
+#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET4_BEACON_SSID_MSB 17
+#define RX_PRIORITY_OFFSET4_BEACON_SSID_LSB 12
+#define RX_PRIORITY_OFFSET4_BEACON_SSID_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET4_BEACON_SSID_GET(x) (((x) & RX_PRIORITY_OFFSET4_BEACON_SSID_MASK) >> RX_PRIORITY_OFFSET4_BEACON_SSID_LSB)
+#define RX_PRIORITY_OFFSET4_BEACON_SSID_SET(x) (((x) << RX_PRIORITY_OFFSET4_BEACON_SSID_LSB) & RX_PRIORITY_OFFSET4_BEACON_SSID_MASK)
+#define RX_PRIORITY_OFFSET4_NULL_MSB 11
+#define RX_PRIORITY_OFFSET4_NULL_LSB 6
+#define RX_PRIORITY_OFFSET4_NULL_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET4_NULL_GET(x) (((x) & RX_PRIORITY_OFFSET4_NULL_MASK) >> RX_PRIORITY_OFFSET4_NULL_LSB)
+#define RX_PRIORITY_OFFSET4_NULL_SET(x) (((x) << RX_PRIORITY_OFFSET4_NULL_LSB) & RX_PRIORITY_OFFSET4_NULL_MASK)
+#define RX_PRIORITY_OFFSET4_PREQ_MSB 5
+#define RX_PRIORITY_OFFSET4_PREQ_LSB 0
+#define RX_PRIORITY_OFFSET4_PREQ_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET4_PREQ_GET(x) (((x) & RX_PRIORITY_OFFSET4_PREQ_MASK) >> RX_PRIORITY_OFFSET4_PREQ_LSB)
+#define RX_PRIORITY_OFFSET4_PREQ_SET(x) (((x) << RX_PRIORITY_OFFSET4_PREQ_LSB) & RX_PRIORITY_OFFSET4_PREQ_MASK)
+
+#define RX_PRIORITY_OFFSET5_ADDRESS 0x00008398
+#define RX_PRIORITY_OFFSET5_OFFSET 0x00000398
+#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MSB 17
+#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB 12
+#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK 0x0003f000
+#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MSB 11
+#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB 6
+#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK 0x00000fc0
+#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK)
+#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MSB 5
+#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB 0
+#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK 0x0000003f
+#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB)
+#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK)
+
+#define MAC_PCU_BSSID2_L32_ADDRESS 0x0000839c
+#define MAC_PCU_BSSID2_L32_OFFSET 0x0000039c
+#define MAC_PCU_BSSID2_L32_ADDR_MSB 31
+#define MAC_PCU_BSSID2_L32_ADDR_LSB 0
+#define MAC_PCU_BSSID2_L32_ADDR_MASK 0xffffffff
+#define MAC_PCU_BSSID2_L32_ADDR_GET(x) (((x) & MAC_PCU_BSSID2_L32_ADDR_MASK) >> MAC_PCU_BSSID2_L32_ADDR_LSB)
+#define MAC_PCU_BSSID2_L32_ADDR_SET(x) (((x) << MAC_PCU_BSSID2_L32_ADDR_LSB) & MAC_PCU_BSSID2_L32_ADDR_MASK)
+
+#define MAC_PCU_BSSID2_U16_ADDRESS 0x000083a0
+#define MAC_PCU_BSSID2_U16_OFFSET 0x000003a0
+#define MAC_PCU_BSSID2_U16_ENABLE_MSB 16
+#define MAC_PCU_BSSID2_U16_ENABLE_LSB 16
+#define MAC_PCU_BSSID2_U16_ENABLE_MASK 0x00010000
+#define MAC_PCU_BSSID2_U16_ENABLE_GET(x) (((x) & MAC_PCU_BSSID2_U16_ENABLE_MASK) >> MAC_PCU_BSSID2_U16_ENABLE_LSB)
+#define MAC_PCU_BSSID2_U16_ENABLE_SET(x) (((x) << MAC_PCU_BSSID2_U16_ENABLE_LSB) & MAC_PCU_BSSID2_U16_ENABLE_MASK)
+#define MAC_PCU_BSSID2_U16_ADDR_MSB 15
+#define MAC_PCU_BSSID2_U16_ADDR_LSB 0
+#define MAC_PCU_BSSID2_U16_ADDR_MASK 0x0000ffff
+#define MAC_PCU_BSSID2_U16_ADDR_GET(x) (((x) & MAC_PCU_BSSID2_U16_ADDR_MASK) >> MAC_PCU_BSSID2_U16_ADDR_LSB)
+#define MAC_PCU_BSSID2_U16_ADDR_SET(x) (((x) << MAC_PCU_BSSID2_U16_ADDR_LSB) & MAC_PCU_BSSID2_U16_ADDR_MASK)
+
+#define MAC_PCU_TSF1_STATUS_L32_ADDRESS 0x000083a4
+#define MAC_PCU_TSF1_STATUS_L32_OFFSET 0x000003a4
+#define MAC_PCU_TSF1_STATUS_L32_VALUE_MSB 31
+#define MAC_PCU_TSF1_STATUS_L32_VALUE_LSB 0
+#define MAC_PCU_TSF1_STATUS_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF1_STATUS_L32_VALUE_GET(x) (((x) & MAC_PCU_TSF1_STATUS_L32_VALUE_MASK) >> MAC_PCU_TSF1_STATUS_L32_VALUE_LSB)
+#define MAC_PCU_TSF1_STATUS_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF1_STATUS_L32_VALUE_LSB) & MAC_PCU_TSF1_STATUS_L32_VALUE_MASK)
+
+#define MAC_PCU_TSF1_STATUS_U32_ADDRESS 0x000083a8
+#define MAC_PCU_TSF1_STATUS_U32_OFFSET 0x000003a8
+#define MAC_PCU_TSF1_STATUS_U32_VALUE_MSB 31
+#define MAC_PCU_TSF1_STATUS_U32_VALUE_LSB 0
+#define MAC_PCU_TSF1_STATUS_U32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF1_STATUS_U32_VALUE_GET(x) (((x) & MAC_PCU_TSF1_STATUS_U32_VALUE_MASK) >> MAC_PCU_TSF1_STATUS_U32_VALUE_LSB)
+#define MAC_PCU_TSF1_STATUS_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF1_STATUS_U32_VALUE_LSB) & MAC_PCU_TSF1_STATUS_U32_VALUE_MASK)
+
+#define MAC_PCU_TSF2_STATUS_L32_ADDRESS 0x000083ac
+#define MAC_PCU_TSF2_STATUS_L32_OFFSET 0x000003ac
+#define MAC_PCU_TSF2_STATUS_L32_VALUE_MSB 31
+#define MAC_PCU_TSF2_STATUS_L32_VALUE_LSB 0
+#define MAC_PCU_TSF2_STATUS_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF2_STATUS_L32_VALUE_GET(x) (((x) & MAC_PCU_TSF2_STATUS_L32_VALUE_MASK) >> MAC_PCU_TSF2_STATUS_L32_VALUE_LSB)
+#define MAC_PCU_TSF2_STATUS_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_STATUS_L32_VALUE_LSB) & MAC_PCU_TSF2_STATUS_L32_VALUE_MASK)
+
+#define MAC_PCU_TSF2_STATUS_U32_ADDRESS 0x000083b0
+#define MAC_PCU_TSF2_STATUS_U32_OFFSET 0x000003b0
+#define MAC_PCU_TSF2_STATUS_U32_VALUE_MSB 31
+#define MAC_PCU_TSF2_STATUS_U32_VALUE_LSB 0
+#define MAC_PCU_TSF2_STATUS_U32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF2_STATUS_U32_VALUE_GET(x) (((x) & MAC_PCU_TSF2_STATUS_U32_VALUE_MASK) >> MAC_PCU_TSF2_STATUS_U32_VALUE_LSB)
+#define MAC_PCU_TSF2_STATUS_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_STATUS_U32_VALUE_LSB) & MAC_PCU_TSF2_STATUS_U32_VALUE_MASK)
+
+#define MAC_PCU_TXBUF_BA_ADDRESS 0x00008400
+#define MAC_PCU_TXBUF_BA_OFFSET 0x00000400
+#define MAC_PCU_TXBUF_BA_DATA_MSB 31
+#define MAC_PCU_TXBUF_BA_DATA_LSB 0
+#define MAC_PCU_TXBUF_BA_DATA_MASK 0xffffffff
+#define MAC_PCU_TXBUF_BA_DATA_GET(x) (((x) & MAC_PCU_TXBUF_BA_DATA_MASK) >> MAC_PCU_TXBUF_BA_DATA_LSB)
+#define MAC_PCU_TXBUF_BA_DATA_SET(x) (((x) << MAC_PCU_TXBUF_BA_DATA_LSB) & MAC_PCU_TXBUF_BA_DATA_MASK)
+
+#define MAC_PCU_KEY_CACHE_1_ADDRESS 0x00008800
+#define MAC_PCU_KEY_CACHE_1_OFFSET 0x00000800
+#define MAC_PCU_KEY_CACHE_1_DATA_MSB 31
+#define MAC_PCU_KEY_CACHE_1_DATA_LSB 0
+#define MAC_PCU_KEY_CACHE_1_DATA_MASK 0xffffffff
+#define MAC_PCU_KEY_CACHE_1_DATA_GET(x) (((x) & MAC_PCU_KEY_CACHE_1_DATA_MASK) >> MAC_PCU_KEY_CACHE_1_DATA_LSB)
+#define MAC_PCU_KEY_CACHE_1_DATA_SET(x) (((x) << MAC_PCU_KEY_CACHE_1_DATA_LSB) & MAC_PCU_KEY_CACHE_1_DATA_MASK)
+
+#define MAC_PCU_BASEBAND_0_ADDRESS 0x00009800
+#define MAC_PCU_BASEBAND_0_OFFSET 0x00001800
+#define MAC_PCU_BASEBAND_0_DATA_MSB 31
+#define MAC_PCU_BASEBAND_0_DATA_LSB 0
+#define MAC_PCU_BASEBAND_0_DATA_MASK 0xffffffff
+#define MAC_PCU_BASEBAND_0_DATA_GET(x) (((x) & MAC_PCU_BASEBAND_0_DATA_MASK) >> MAC_PCU_BASEBAND_0_DATA_LSB)
+#define MAC_PCU_BASEBAND_0_DATA_SET(x) (((x) << MAC_PCU_BASEBAND_0_DATA_LSB) & MAC_PCU_BASEBAND_0_DATA_MASK)
+
+#define MAC_PCU_BASEBAND_1_ADDRESS 0x0000a000
+#define MAC_PCU_BASEBAND_1_OFFSET 0x00002000
+#define MAC_PCU_BASEBAND_1_DATA_MSB 31
+#define MAC_PCU_BASEBAND_1_DATA_LSB 0
+#define MAC_PCU_BASEBAND_1_DATA_MASK 0xffffffff
+#define MAC_PCU_BASEBAND_1_DATA_GET(x) (((x) & MAC_PCU_BASEBAND_1_DATA_MASK) >> MAC_PCU_BASEBAND_1_DATA_LSB)
+#define MAC_PCU_BASEBAND_1_DATA_SET(x) (((x) << MAC_PCU_BASEBAND_1_DATA_LSB) & MAC_PCU_BASEBAND_1_DATA_MASK)
+
+#define MAC_PCU_BASEBAND_2_ADDRESS 0x0000c000
+#define MAC_PCU_BASEBAND_2_OFFSET 0x00004000
+#define MAC_PCU_BASEBAND_2_DATA_MSB 31
+#define MAC_PCU_BASEBAND_2_DATA_LSB 0
+#define MAC_PCU_BASEBAND_2_DATA_MASK 0xffffffff
+#define MAC_PCU_BASEBAND_2_DATA_GET(x) (((x) & MAC_PCU_BASEBAND_2_DATA_MASK) >> MAC_PCU_BASEBAND_2_DATA_LSB)
+#define MAC_PCU_BASEBAND_2_DATA_SET(x) (((x) << MAC_PCU_BASEBAND_2_DATA_LSB) & MAC_PCU_BASEBAND_2_DATA_MASK)
+
+#define MAC_PCU_BASEBAND_3_ADDRESS 0x0000d000
+#define MAC_PCU_BASEBAND_3_OFFSET 0x00005000
+#define MAC_PCU_BASEBAND_3_DATA_MSB 31
+#define MAC_PCU_BASEBAND_3_DATA_LSB 0
+#define MAC_PCU_BASEBAND_3_DATA_MASK 0xffffffff
+#define MAC_PCU_BASEBAND_3_DATA_GET(x) (((x) & MAC_PCU_BASEBAND_3_DATA_MASK) >> MAC_PCU_BASEBAND_3_DATA_LSB)
+#define MAC_PCU_BASEBAND_3_DATA_SET(x) (((x) << MAC_PCU_BASEBAND_3_DATA_LSB) & MAC_PCU_BASEBAND_3_DATA_MASK)
+
+#define MAC_PCU_BUF_ADDRESS 0x0000e000
+#define MAC_PCU_BUF_OFFSET 0x00006000
+#define MAC_PCU_BUF_DATA_MSB 31
+#define MAC_PCU_BUF_DATA_LSB 0
+#define MAC_PCU_BUF_DATA_MASK 0xffffffff
+#define MAC_PCU_BUF_DATA_GET(x) (((x) & MAC_PCU_BUF_DATA_MASK) >> MAC_PCU_BUF_DATA_LSB)
+#define MAC_PCU_BUF_DATA_SET(x) (((x) << MAC_PCU_BUF_DATA_LSB) & MAC_PCU_BUF_DATA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct mac_pcu_reg_s {
+ volatile unsigned int mac_pcu_sta_addr_l32;
+ volatile unsigned int mac_pcu_sta_addr_u16;
+ volatile unsigned int mac_pcu_bssid_l32;
+ volatile unsigned int mac_pcu_bssid_u16;
+ volatile unsigned int mac_pcu_bcn_rssi_ave;
+ volatile unsigned int mac_pcu_ack_cts_timeout;
+ volatile unsigned int mac_pcu_bcn_rssi_ctl;
+ volatile unsigned int mac_pcu_usec_latency;
+ volatile unsigned int pcu_max_cfp_dur;
+ volatile unsigned int mac_pcu_rx_filter;
+ volatile unsigned int mac_pcu_mcast_filter_l32;
+ volatile unsigned int mac_pcu_mcast_filter_u32;
+ volatile unsigned int mac_pcu_diag_sw;
+ volatile unsigned int mac_pcu_tst_addac;
+ volatile unsigned int mac_pcu_def_antenna;
+ volatile unsigned int mac_pcu_aes_mute_mask_0;
+ volatile unsigned int mac_pcu_aes_mute_mask_1;
+ volatile unsigned int mac_pcu_gated_clks;
+ volatile unsigned int mac_pcu_obs_bus_2;
+ volatile unsigned int mac_pcu_obs_bus_1;
+ volatile unsigned int mac_pcu_dym_mimo_pwr_save;
+ volatile unsigned int mac_pcu_last_beacon_tsf;
+ volatile unsigned int mac_pcu_nav;
+ volatile unsigned int mac_pcu_rts_success_cnt;
+ volatile unsigned int mac_pcu_rts_fail_cnt;
+ volatile unsigned int mac_pcu_ack_fail_cnt;
+ volatile unsigned int mac_pcu_fcs_fail_cnt;
+ volatile unsigned int mac_pcu_beacon_cnt;
+ volatile unsigned int mac_pcu_xrmode;
+ volatile unsigned int mac_pcu_xrdel;
+ volatile unsigned int mac_pcu_xrto;
+ volatile unsigned int mac_pcu_xrcrp;
+ volatile unsigned int mac_pcu_xrstmp;
+ volatile unsigned int mac_pcu_addr1_mask_l32;
+ volatile unsigned int mac_pcu_addr1_mask_u16;
+ volatile unsigned int mac_pcu_tpc;
+ volatile unsigned int mac_pcu_tx_frame_cnt;
+ volatile unsigned int mac_pcu_rx_frame_cnt;
+ volatile unsigned int mac_pcu_rx_clear_cnt;
+ volatile unsigned int mac_pcu_cycle_cnt;
+ volatile unsigned int mac_pcu_quiet_time_1;
+ volatile unsigned int mac_pcu_quiet_time_2;
+ volatile unsigned int mac_pcu_qos_no_ack;
+ volatile unsigned int mac_pcu_phy_error_mask;
+ volatile unsigned int mac_pcu_xrlat;
+ volatile unsigned int mac_pcu_rxbuf;
+ volatile unsigned int mac_pcu_mic_qos_control;
+ volatile unsigned int mac_pcu_mic_qos_select;
+ volatile unsigned int mac_pcu_misc_mode;
+ volatile unsigned int mac_pcu_filter_ofdm_cnt;
+ volatile unsigned int mac_pcu_filter_cck_cnt;
+ volatile unsigned int mac_pcu_phy_err_cnt_1;
+ volatile unsigned int mac_pcu_phy_err_cnt_1_mask;
+ volatile unsigned int mac_pcu_phy_err_cnt_2;
+ volatile unsigned int mac_pcu_phy_err_cnt_2_mask;
+ volatile unsigned int mac_pcu_tsf_threshold;
+ volatile unsigned int mac_pcu_phy_error_eifs_mask;
+ volatile unsigned int mac_pcu_phy_err_cnt_3;
+ volatile unsigned int mac_pcu_phy_err_cnt_3_mask;
+ volatile unsigned int mac_pcu_bluetooth_mode;
+ volatile unsigned int mac_pcu_bluetooth_weights;
+ volatile unsigned int mac_pcu_bluetooth_mode2;
+ volatile unsigned int mac_pcu_txsifs;
+ volatile unsigned int mac_pcu_txop_x;
+ volatile unsigned int mac_pcu_txop_0_3;
+ volatile unsigned int mac_pcu_txop_4_7;
+ volatile unsigned int mac_pcu_txop_8_11;
+ volatile unsigned int mac_pcu_txop_12_15;
+ volatile unsigned int mac_pcu_logic_analyzer;
+ volatile unsigned int mac_pcu_logic_analyzer_32l;
+ volatile unsigned int mac_pcu_logic_analyzer_16u;
+ volatile unsigned int mac_pcu_phy_err_cnt_mask_cont;
+ volatile unsigned int mac_pcu_azimuth_mode;
+ volatile unsigned int mac_pcu_20_40_mode;
+ volatile unsigned int mac_pcu_rx_clear_diff_cnt;
+ volatile unsigned int mac_pcu_self_gen_antenna_mask;
+ volatile unsigned int mac_pcu_ba_bar_control;
+ volatile unsigned int mac_pcu_legacy_plcp_spoof;
+ volatile unsigned int mac_pcu_phy_error_mask_cont;
+ volatile unsigned int mac_pcu_tx_timer;
+ volatile unsigned int mac_pcu_txbuf_ctrl;
+ volatile unsigned int mac_pcu_misc_mode2;
+ volatile unsigned int mac_pcu_alt_aes_mute_mask;
+ volatile unsigned int mac_pcu_azimuth_time_stamp;
+ volatile unsigned int mac_pcu_max_cfp_dur;
+ volatile unsigned int mac_pcu_hcf_timeout;
+ volatile unsigned int mac_pcu_bluetooth_weights2;
+ volatile unsigned int mac_pcu_bluetooth_tsf_bt_active;
+ volatile unsigned int mac_pcu_bluetooth_tsf_bt_priority;
+ volatile unsigned int mac_pcu_bluetooth_mode3;
+ volatile unsigned int mac_pcu_bluetooth_mode4;
+ unsigned char pad0[148]; /* pad to 0x200 */
+ volatile unsigned int mac_pcu_bt_bt[64];
+ volatile unsigned int mac_pcu_bt_bt_async;
+ volatile unsigned int mac_pcu_bt_wl_1;
+ volatile unsigned int mac_pcu_bt_wl_2;
+ volatile unsigned int mac_pcu_bt_wl_3;
+ volatile unsigned int mac_pcu_bt_wl_4;
+ volatile unsigned int mac_pcu_coex_epta;
+ volatile unsigned int mac_pcu_coex_lnamaxgain1;
+ volatile unsigned int mac_pcu_coex_lnamaxgain2;
+ volatile unsigned int mac_pcu_coex_lnamaxgain3;
+ volatile unsigned int mac_pcu_coex_lnamaxgain4;
+ volatile unsigned int mac_pcu_basic_rate_set0;
+ volatile unsigned int mac_pcu_basic_rate_set1;
+ volatile unsigned int mac_pcu_basic_rate_set2;
+ volatile unsigned int mac_pcu_basic_rate_set3;
+ volatile unsigned int mac_pcu_rx_int_status0;
+ volatile unsigned int mac_pcu_rx_int_status1;
+ volatile unsigned int mac_pcu_rx_int_status2;
+ volatile unsigned int mac_pcu_rx_int_status3;
+ volatile unsigned int ht_half_gi_rate1;
+ volatile unsigned int ht_half_gi_rate2;
+ volatile unsigned int ht_full_gi_rate1;
+ volatile unsigned int ht_full_gi_rate2;
+ volatile unsigned int legacy_rate1;
+ volatile unsigned int legacy_rate2;
+ volatile unsigned int legacy_rate3;
+ volatile unsigned int rx_int_filter;
+ volatile unsigned int rx_int_overflow;
+ volatile unsigned int rx_filter_thresh;
+ volatile unsigned int rx_filter_thresh1;
+ volatile unsigned int rx_priority_thresh0;
+ volatile unsigned int rx_priority_thresh1;
+ volatile unsigned int rx_priority_thresh2;
+ volatile unsigned int rx_priority_thresh3;
+ volatile unsigned int rx_priority_offset0;
+ volatile unsigned int rx_priority_offset1;
+ volatile unsigned int rx_priority_offset2;
+ volatile unsigned int rx_priority_offset3;
+ volatile unsigned int rx_priority_offset4;
+ volatile unsigned int rx_priority_offset5;
+ volatile unsigned int mac_pcu_bssid2_l32;
+ volatile unsigned int mac_pcu_bssid2_u16;
+ volatile unsigned int mac_pcu_tsf1_status_l32;
+ volatile unsigned int mac_pcu_tsf1_status_u32;
+ volatile unsigned int mac_pcu_tsf2_status_l32;
+ volatile unsigned int mac_pcu_tsf2_status_u32;
+ unsigned char pad1[76]; /* pad to 0x400 */
+ volatile unsigned int mac_pcu_txbuf_ba[64];
+ unsigned char pad2[768]; /* pad to 0x800 */
+ volatile unsigned int mac_pcu_key_cache_1[256];
+ unsigned char pad3[3072]; /* pad to 0x1800 */
+ volatile unsigned int mac_pcu_baseband_0[512];
+ volatile unsigned int mac_pcu_baseband_1[2048];
+ volatile unsigned int mac_pcu_baseband_2[1024];
+ volatile unsigned int mac_pcu_baseband_3[1024];
+ volatile unsigned int mac_pcu_buf[512];
+} mac_pcu_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MAC_PCU_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
new file mode 100644
index 000000000000..3af562156f6e
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
@@ -0,0 +1,37 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "mbox_wlan_host_reg.h"
+
+
+#ifndef BT_HEADERS
+
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
new file mode 100644
index 000000000000..cc67585e2e8b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
@@ -0,0 +1,560 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "mbox_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+#define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS
+#define MBOX_FIFO_OFFSET WLAN_MBOX_FIFO_OFFSET
+#define MBOX_FIFO_DATA_MSB WLAN_MBOX_FIFO_DATA_MSB
+#define MBOX_FIFO_DATA_LSB WLAN_MBOX_FIFO_DATA_LSB
+#define MBOX_FIFO_DATA_MASK WLAN_MBOX_FIFO_DATA_MASK
+#define MBOX_FIFO_DATA_GET(x) WLAN_MBOX_FIFO_DATA_GET(x)
+#define MBOX_FIFO_DATA_SET(x) WLAN_MBOX_FIFO_DATA_SET(x)
+#define MBOX_FIFO_STATUS_ADDRESS WLAN_MBOX_FIFO_STATUS_ADDRESS
+#define MBOX_FIFO_STATUS_OFFSET WLAN_MBOX_FIFO_STATUS_OFFSET
+#define MBOX_FIFO_STATUS_EMPTY_MSB WLAN_MBOX_FIFO_STATUS_EMPTY_MSB
+#define MBOX_FIFO_STATUS_EMPTY_LSB WLAN_MBOX_FIFO_STATUS_EMPTY_LSB
+#define MBOX_FIFO_STATUS_EMPTY_MASK WLAN_MBOX_FIFO_STATUS_EMPTY_MASK
+#define MBOX_FIFO_STATUS_EMPTY_GET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x)
+#define MBOX_FIFO_STATUS_EMPTY_SET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x)
+#define MBOX_FIFO_STATUS_FULL_MSB WLAN_MBOX_FIFO_STATUS_FULL_MSB
+#define MBOX_FIFO_STATUS_FULL_LSB WLAN_MBOX_FIFO_STATUS_FULL_LSB
+#define MBOX_FIFO_STATUS_FULL_MASK WLAN_MBOX_FIFO_STATUS_FULL_MASK
+#define MBOX_FIFO_STATUS_FULL_GET(x) WLAN_MBOX_FIFO_STATUS_FULL_GET(x)
+#define MBOX_FIFO_STATUS_FULL_SET(x) WLAN_MBOX_FIFO_STATUS_FULL_SET(x)
+#define MBOX_DMA_POLICY_ADDRESS WLAN_MBOX_DMA_POLICY_ADDRESS
+#define MBOX_DMA_POLICY_OFFSET WLAN_MBOX_DMA_POLICY_OFFSET
+#define MBOX_DMA_POLICY_TX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB
+#define MBOX_DMA_POLICY_TX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB
+#define MBOX_DMA_POLICY_TX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK
+#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x)
+#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x)
+#define MBOX_DMA_POLICY_TX_ORDER_MSB WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB
+#define MBOX_DMA_POLICY_TX_ORDER_LSB WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB
+#define MBOX_DMA_POLICY_TX_ORDER_MASK WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK
+#define MBOX_DMA_POLICY_TX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x)
+#define MBOX_DMA_POLICY_TX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x)
+#define MBOX_DMA_POLICY_RX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB
+#define MBOX_DMA_POLICY_RX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB
+#define MBOX_DMA_POLICY_RX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK
+#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x)
+#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x)
+#define MBOX_DMA_POLICY_RX_ORDER_MSB WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB
+#define MBOX_DMA_POLICY_RX_ORDER_LSB WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB
+#define MBOX_DMA_POLICY_RX_ORDER_MASK WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK
+#define MBOX_DMA_POLICY_RX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x)
+#define MBOX_DMA_POLICY_RX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x)
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX0_DMA_RX_CONTROL_ADDRESS WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS
+#define MBOX0_DMA_RX_CONTROL_OFFSET WLAN_MBOX0_DMA_RX_CONTROL_OFFSET
+#define MBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB
+#define MBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB
+#define MBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK
+#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x)
+#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x)
+#define MBOX0_DMA_RX_CONTROL_START_MSB WLAN_MBOX0_DMA_RX_CONTROL_START_MSB
+#define MBOX0_DMA_RX_CONTROL_START_LSB WLAN_MBOX0_DMA_RX_CONTROL_START_LSB
+#define MBOX0_DMA_RX_CONTROL_START_MASK WLAN_MBOX0_DMA_RX_CONTROL_START_MASK
+#define MBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x)
+#define MBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x)
+#define MBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB
+#define MBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB
+#define MBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK
+#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x)
+#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x)
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX0_DMA_TX_CONTROL_ADDRESS WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS
+#define MBOX0_DMA_TX_CONTROL_OFFSET WLAN_MBOX0_DMA_TX_CONTROL_OFFSET
+#define MBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB
+#define MBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB
+#define MBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK
+#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x)
+#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x)
+#define MBOX0_DMA_TX_CONTROL_START_MSB WLAN_MBOX0_DMA_TX_CONTROL_START_MSB
+#define MBOX0_DMA_TX_CONTROL_START_LSB WLAN_MBOX0_DMA_TX_CONTROL_START_LSB
+#define MBOX0_DMA_TX_CONTROL_START_MASK WLAN_MBOX0_DMA_TX_CONTROL_START_MASK
+#define MBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x)
+#define MBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x)
+#define MBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB
+#define MBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB
+#define MBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK
+#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x)
+#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x)
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX1_DMA_RX_CONTROL_ADDRESS WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS
+#define MBOX1_DMA_RX_CONTROL_OFFSET WLAN_MBOX1_DMA_RX_CONTROL_OFFSET
+#define MBOX1_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB
+#define MBOX1_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB
+#define MBOX1_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK
+#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x)
+#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x)
+#define MBOX1_DMA_RX_CONTROL_START_MSB WLAN_MBOX1_DMA_RX_CONTROL_START_MSB
+#define MBOX1_DMA_RX_CONTROL_START_LSB WLAN_MBOX1_DMA_RX_CONTROL_START_LSB
+#define MBOX1_DMA_RX_CONTROL_START_MASK WLAN_MBOX1_DMA_RX_CONTROL_START_MASK
+#define MBOX1_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x)
+#define MBOX1_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x)
+#define MBOX1_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB
+#define MBOX1_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB
+#define MBOX1_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK
+#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x)
+#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x)
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX1_DMA_TX_CONTROL_ADDRESS WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS
+#define MBOX1_DMA_TX_CONTROL_OFFSET WLAN_MBOX1_DMA_TX_CONTROL_OFFSET
+#define MBOX1_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB
+#define MBOX1_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB
+#define MBOX1_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK
+#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x)
+#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x)
+#define MBOX1_DMA_TX_CONTROL_START_MSB WLAN_MBOX1_DMA_TX_CONTROL_START_MSB
+#define MBOX1_DMA_TX_CONTROL_START_LSB WLAN_MBOX1_DMA_TX_CONTROL_START_LSB
+#define MBOX1_DMA_TX_CONTROL_START_MASK WLAN_MBOX1_DMA_TX_CONTROL_START_MASK
+#define MBOX1_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x)
+#define MBOX1_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x)
+#define MBOX1_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB
+#define MBOX1_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB
+#define MBOX1_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK
+#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x)
+#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x)
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX2_DMA_RX_CONTROL_ADDRESS WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS
+#define MBOX2_DMA_RX_CONTROL_OFFSET WLAN_MBOX2_DMA_RX_CONTROL_OFFSET
+#define MBOX2_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB
+#define MBOX2_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB
+#define MBOX2_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK
+#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x)
+#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x)
+#define MBOX2_DMA_RX_CONTROL_START_MSB WLAN_MBOX2_DMA_RX_CONTROL_START_MSB
+#define MBOX2_DMA_RX_CONTROL_START_LSB WLAN_MBOX2_DMA_RX_CONTROL_START_LSB
+#define MBOX2_DMA_RX_CONTROL_START_MASK WLAN_MBOX2_DMA_RX_CONTROL_START_MASK
+#define MBOX2_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x)
+#define MBOX2_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x)
+#define MBOX2_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB
+#define MBOX2_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB
+#define MBOX2_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK
+#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x)
+#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x)
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX2_DMA_TX_CONTROL_ADDRESS WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS
+#define MBOX2_DMA_TX_CONTROL_OFFSET WLAN_MBOX2_DMA_TX_CONTROL_OFFSET
+#define MBOX2_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB
+#define MBOX2_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB
+#define MBOX2_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK
+#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x)
+#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x)
+#define MBOX2_DMA_TX_CONTROL_START_MSB WLAN_MBOX2_DMA_TX_CONTROL_START_MSB
+#define MBOX2_DMA_TX_CONTROL_START_LSB WLAN_MBOX2_DMA_TX_CONTROL_START_LSB
+#define MBOX2_DMA_TX_CONTROL_START_MASK WLAN_MBOX2_DMA_TX_CONTROL_START_MASK
+#define MBOX2_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x)
+#define MBOX2_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x)
+#define MBOX2_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB
+#define MBOX2_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB
+#define MBOX2_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK
+#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x)
+#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x)
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX3_DMA_RX_CONTROL_ADDRESS WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS
+#define MBOX3_DMA_RX_CONTROL_OFFSET WLAN_MBOX3_DMA_RX_CONTROL_OFFSET
+#define MBOX3_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB
+#define MBOX3_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB
+#define MBOX3_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK
+#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x)
+#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x)
+#define MBOX3_DMA_RX_CONTROL_START_MSB WLAN_MBOX3_DMA_RX_CONTROL_START_MSB
+#define MBOX3_DMA_RX_CONTROL_START_LSB WLAN_MBOX3_DMA_RX_CONTROL_START_LSB
+#define MBOX3_DMA_RX_CONTROL_START_MASK WLAN_MBOX3_DMA_RX_CONTROL_START_MASK
+#define MBOX3_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x)
+#define MBOX3_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x)
+#define MBOX3_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB
+#define MBOX3_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB
+#define MBOX3_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK
+#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x)
+#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x)
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define MBOX3_DMA_TX_CONTROL_ADDRESS WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS
+#define MBOX3_DMA_TX_CONTROL_OFFSET WLAN_MBOX3_DMA_TX_CONTROL_OFFSET
+#define MBOX3_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB
+#define MBOX3_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB
+#define MBOX3_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK
+#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x)
+#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x)
+#define MBOX3_DMA_TX_CONTROL_START_MSB WLAN_MBOX3_DMA_TX_CONTROL_START_MSB
+#define MBOX3_DMA_TX_CONTROL_START_LSB WLAN_MBOX3_DMA_TX_CONTROL_START_LSB
+#define MBOX3_DMA_TX_CONTROL_START_MASK WLAN_MBOX3_DMA_TX_CONTROL_START_MASK
+#define MBOX3_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x)
+#define MBOX3_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x)
+#define MBOX3_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB
+#define MBOX3_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB
+#define MBOX3_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK
+#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x)
+#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x)
+#define MBOX_INT_STATUS_ADDRESS WLAN_MBOX_INT_STATUS_ADDRESS
+#define MBOX_INT_STATUS_OFFSET WLAN_MBOX_INT_STATUS_OFFSET
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
+#define MBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB
+#define MBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB
+#define MBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK
+#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x)
+#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB
+#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK
+#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
+#define MBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB
+#define MBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB
+#define MBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK
+#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x)
+#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x)
+#define MBOX_INT_STATUS_HOST_MSB WLAN_MBOX_INT_STATUS_HOST_MSB
+#define MBOX_INT_STATUS_HOST_LSB WLAN_MBOX_INT_STATUS_HOST_LSB
+#define MBOX_INT_STATUS_HOST_MASK WLAN_MBOX_INT_STATUS_HOST_MASK
+#define MBOX_INT_STATUS_HOST_GET(x) WLAN_MBOX_INT_STATUS_HOST_GET(x)
+#define MBOX_INT_STATUS_HOST_SET(x) WLAN_MBOX_INT_STATUS_HOST_SET(x)
+#define MBOX_INT_ENABLE_ADDRESS WLAN_MBOX_INT_ENABLE_ADDRESS
+#define MBOX_INT_ENABLE_OFFSET WLAN_MBOX_INT_ENABLE_OFFSET
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB
+#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK
+#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB
+#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK
+#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
+#define MBOX_INT_ENABLE_HOST_MSB WLAN_MBOX_INT_ENABLE_HOST_MSB
+#define MBOX_INT_ENABLE_HOST_LSB WLAN_MBOX_INT_ENABLE_HOST_LSB
+#define MBOX_INT_ENABLE_HOST_MASK WLAN_MBOX_INT_ENABLE_HOST_MASK
+#define MBOX_INT_ENABLE_HOST_GET(x) WLAN_MBOX_INT_ENABLE_HOST_GET(x)
+#define MBOX_INT_ENABLE_HOST_SET(x) WLAN_MBOX_INT_ENABLE_HOST_SET(x)
+#define INT_HOST_ADDRESS WLAN_INT_HOST_ADDRESS
+#define INT_HOST_OFFSET WLAN_INT_HOST_OFFSET
+#define INT_HOST_VECTOR_MSB WLAN_INT_HOST_VECTOR_MSB
+#define INT_HOST_VECTOR_LSB WLAN_INT_HOST_VECTOR_LSB
+#define INT_HOST_VECTOR_MASK WLAN_INT_HOST_VECTOR_MASK
+#define INT_HOST_VECTOR_GET(x) WLAN_INT_HOST_VECTOR_GET(x)
+#define INT_HOST_VECTOR_SET(x) WLAN_INT_HOST_VECTOR_SET(x)
+#define LOCAL_COUNT_ADDRESS WLAN_LOCAL_COUNT_ADDRESS
+#define LOCAL_COUNT_OFFSET WLAN_LOCAL_COUNT_OFFSET
+#define LOCAL_COUNT_VALUE_MSB WLAN_LOCAL_COUNT_VALUE_MSB
+#define LOCAL_COUNT_VALUE_LSB WLAN_LOCAL_COUNT_VALUE_LSB
+#define LOCAL_COUNT_VALUE_MASK WLAN_LOCAL_COUNT_VALUE_MASK
+#define LOCAL_COUNT_VALUE_GET(x) WLAN_LOCAL_COUNT_VALUE_GET(x)
+#define LOCAL_COUNT_VALUE_SET(x) WLAN_LOCAL_COUNT_VALUE_SET(x)
+#define COUNT_INC_ADDRESS WLAN_COUNT_INC_ADDRESS
+#define COUNT_INC_OFFSET WLAN_COUNT_INC_OFFSET
+#define COUNT_INC_VALUE_MSB WLAN_COUNT_INC_VALUE_MSB
+#define COUNT_INC_VALUE_LSB WLAN_COUNT_INC_VALUE_LSB
+#define COUNT_INC_VALUE_MASK WLAN_COUNT_INC_VALUE_MASK
+#define COUNT_INC_VALUE_GET(x) WLAN_COUNT_INC_VALUE_GET(x)
+#define COUNT_INC_VALUE_SET(x) WLAN_COUNT_INC_VALUE_SET(x)
+#define LOCAL_SCRATCH_ADDRESS WLAN_LOCAL_SCRATCH_ADDRESS
+#define LOCAL_SCRATCH_OFFSET WLAN_LOCAL_SCRATCH_OFFSET
+#define LOCAL_SCRATCH_VALUE_MSB WLAN_LOCAL_SCRATCH_VALUE_MSB
+#define LOCAL_SCRATCH_VALUE_LSB WLAN_LOCAL_SCRATCH_VALUE_LSB
+#define LOCAL_SCRATCH_VALUE_MASK WLAN_LOCAL_SCRATCH_VALUE_MASK
+#define LOCAL_SCRATCH_VALUE_GET(x) WLAN_LOCAL_SCRATCH_VALUE_GET(x)
+#define LOCAL_SCRATCH_VALUE_SET(x) WLAN_LOCAL_SCRATCH_VALUE_SET(x)
+#define USE_LOCAL_BUS_ADDRESS WLAN_USE_LOCAL_BUS_ADDRESS
+#define USE_LOCAL_BUS_OFFSET WLAN_USE_LOCAL_BUS_OFFSET
+#define USE_LOCAL_BUS_PIN_INIT_MSB WLAN_USE_LOCAL_BUS_PIN_INIT_MSB
+#define USE_LOCAL_BUS_PIN_INIT_LSB WLAN_USE_LOCAL_BUS_PIN_INIT_LSB
+#define USE_LOCAL_BUS_PIN_INIT_MASK WLAN_USE_LOCAL_BUS_PIN_INIT_MASK
+#define USE_LOCAL_BUS_PIN_INIT_GET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x)
+#define USE_LOCAL_BUS_PIN_INIT_SET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x)
+#define SDIO_CONFIG_ADDRESS WLAN_SDIO_CONFIG_ADDRESS
+#define SDIO_CONFIG_OFFSET WLAN_SDIO_CONFIG_OFFSET
+#define SDIO_CONFIG_CCCR_IOR1_MSB WLAN_SDIO_CONFIG_CCCR_IOR1_MSB
+#define SDIO_CONFIG_CCCR_IOR1_LSB WLAN_SDIO_CONFIG_CCCR_IOR1_LSB
+#define SDIO_CONFIG_CCCR_IOR1_MASK WLAN_SDIO_CONFIG_CCCR_IOR1_MASK
+#define SDIO_CONFIG_CCCR_IOR1_GET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x)
+#define SDIO_CONFIG_CCCR_IOR1_SET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x)
+#define MBOX_DEBUG_ADDRESS WLAN_MBOX_DEBUG_ADDRESS
+#define MBOX_DEBUG_OFFSET WLAN_MBOX_DEBUG_OFFSET
+#define MBOX_DEBUG_SEL_MSB WLAN_MBOX_DEBUG_SEL_MSB
+#define MBOX_DEBUG_SEL_LSB WLAN_MBOX_DEBUG_SEL_LSB
+#define MBOX_DEBUG_SEL_MASK WLAN_MBOX_DEBUG_SEL_MASK
+#define MBOX_DEBUG_SEL_GET(x) WLAN_MBOX_DEBUG_SEL_GET(x)
+#define MBOX_DEBUG_SEL_SET(x) WLAN_MBOX_DEBUG_SEL_SET(x)
+#define MBOX_FIFO_RESET_ADDRESS WLAN_MBOX_FIFO_RESET_ADDRESS
+#define MBOX_FIFO_RESET_OFFSET WLAN_MBOX_FIFO_RESET_OFFSET
+#define MBOX_FIFO_RESET_INIT_MSB WLAN_MBOX_FIFO_RESET_INIT_MSB
+#define MBOX_FIFO_RESET_INIT_LSB WLAN_MBOX_FIFO_RESET_INIT_LSB
+#define MBOX_FIFO_RESET_INIT_MASK WLAN_MBOX_FIFO_RESET_INIT_MASK
+#define MBOX_FIFO_RESET_INIT_GET(x) WLAN_MBOX_FIFO_RESET_INIT_GET(x)
+#define MBOX_FIFO_RESET_INIT_SET(x) WLAN_MBOX_FIFO_RESET_INIT_SET(x)
+#define MBOX_TXFIFO_POP_ADDRESS WLAN_MBOX_TXFIFO_POP_ADDRESS
+#define MBOX_TXFIFO_POP_OFFSET WLAN_MBOX_TXFIFO_POP_OFFSET
+#define MBOX_TXFIFO_POP_DATA_MSB WLAN_MBOX_TXFIFO_POP_DATA_MSB
+#define MBOX_TXFIFO_POP_DATA_LSB WLAN_MBOX_TXFIFO_POP_DATA_LSB
+#define MBOX_TXFIFO_POP_DATA_MASK WLAN_MBOX_TXFIFO_POP_DATA_MASK
+#define MBOX_TXFIFO_POP_DATA_GET(x) WLAN_MBOX_TXFIFO_POP_DATA_GET(x)
+#define MBOX_TXFIFO_POP_DATA_SET(x) WLAN_MBOX_TXFIFO_POP_DATA_SET(x)
+#define MBOX_RXFIFO_POP_ADDRESS WLAN_MBOX_RXFIFO_POP_ADDRESS
+#define MBOX_RXFIFO_POP_OFFSET WLAN_MBOX_RXFIFO_POP_OFFSET
+#define MBOX_RXFIFO_POP_DATA_MSB WLAN_MBOX_RXFIFO_POP_DATA_MSB
+#define MBOX_RXFIFO_POP_DATA_LSB WLAN_MBOX_RXFIFO_POP_DATA_LSB
+#define MBOX_RXFIFO_POP_DATA_MASK WLAN_MBOX_RXFIFO_POP_DATA_MASK
+#define MBOX_RXFIFO_POP_DATA_GET(x) WLAN_MBOX_RXFIFO_POP_DATA_GET(x)
+#define MBOX_RXFIFO_POP_DATA_SET(x) WLAN_MBOX_RXFIFO_POP_DATA_SET(x)
+#define SDIO_DEBUG_ADDRESS WLAN_SDIO_DEBUG_ADDRESS
+#define SDIO_DEBUG_OFFSET WLAN_SDIO_DEBUG_OFFSET
+#define SDIO_DEBUG_SEL_MSB WLAN_SDIO_DEBUG_SEL_MSB
+#define SDIO_DEBUG_SEL_LSB WLAN_SDIO_DEBUG_SEL_LSB
+#define SDIO_DEBUG_SEL_MASK WLAN_SDIO_DEBUG_SEL_MASK
+#define SDIO_DEBUG_SEL_GET(x) WLAN_SDIO_DEBUG_SEL_GET(x)
+#define SDIO_DEBUG_SEL_SET(x) WLAN_SDIO_DEBUG_SEL_SET(x)
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define GMBOX0_DMA_RX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS
+#define GMBOX0_DMA_RX_CONTROL_OFFSET WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET
+#define GMBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB
+#define GMBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB
+#define GMBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK
+#define GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x)
+#define GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x)
+#define GMBOX0_DMA_RX_CONTROL_START_MSB WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB
+#define GMBOX0_DMA_RX_CONTROL_START_LSB WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB
+#define GMBOX0_DMA_RX_CONTROL_START_MASK WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK
+#define GMBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x)
+#define GMBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x)
+#define GMBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB
+#define GMBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB
+#define GMBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK
+#define GMBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x)
+#define GMBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x)
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x)
+#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x)
+#define GMBOX0_DMA_TX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS
+#define GMBOX0_DMA_TX_CONTROL_OFFSET WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET
+#define GMBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB
+#define GMBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB
+#define GMBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK
+#define GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x)
+#define GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x)
+#define GMBOX0_DMA_TX_CONTROL_START_MSB WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB
+#define GMBOX0_DMA_TX_CONTROL_START_LSB WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB
+#define GMBOX0_DMA_TX_CONTROL_START_MASK WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK
+#define GMBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x)
+#define GMBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x)
+#define GMBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB
+#define GMBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB
+#define GMBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK
+#define GMBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x)
+#define GMBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x)
+#define GMBOX_INT_STATUS_ADDRESS WLAN_GMBOX_INT_STATUS_ADDRESS
+#define GMBOX_INT_STATUS_OFFSET WLAN_GMBOX_INT_STATUS_OFFSET
+#define GMBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB
+#define GMBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB
+#define GMBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK
+#define GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x)
+#define GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x)
+#define GMBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB
+#define GMBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB
+#define GMBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK
+#define GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x)
+#define GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x)
+#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB
+#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB
+#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK
+#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)
+#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)
+#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB
+#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB
+#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK
+#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x)
+#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x)
+#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB
+#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB
+#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK
+#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)
+#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)
+#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB
+#define GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB
+#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK
+#define GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)
+#define GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)
+#define GMBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB
+#define GMBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB
+#define GMBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK
+#define GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x)
+#define GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x)
+#define GMBOX_INT_ENABLE_ADDRESS WLAN_GMBOX_INT_ENABLE_ADDRESS
+#define GMBOX_INT_ENABLE_OFFSET WLAN_GMBOX_INT_ENABLE_OFFSET
+#define GMBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB
+#define GMBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB
+#define GMBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK
+#define GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x)
+#define GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x)
+#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB
+#define GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB
+#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK
+#define GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)
+#define GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)
+#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB
+#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB
+#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK
+#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)
+#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)
+#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB
+#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB
+#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK
+#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x)
+#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x)
+#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB
+#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB
+#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK
+#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)
+#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)
+#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB
+#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB
+#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK
+#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)
+#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)
+#define GMBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB
+#define GMBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB
+#define GMBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK
+#define GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x)
+#define GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x)
+#define HOST_IF_WINDOW_ADDRESS WLAN_HOST_IF_WINDOW_ADDRESS
+#define HOST_IF_WINDOW_OFFSET WLAN_HOST_IF_WINDOW_OFFSET
+#define HOST_IF_WINDOW_DATA_MSB WLAN_HOST_IF_WINDOW_DATA_MSB
+#define HOST_IF_WINDOW_DATA_LSB WLAN_HOST_IF_WINDOW_DATA_LSB
+#define HOST_IF_WINDOW_DATA_MASK WLAN_HOST_IF_WINDOW_DATA_MASK
+#define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x)
+#define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x)
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
new file mode 100644
index 000000000000..60855021c2b0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
@@ -0,0 +1,522 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _MBOX_WLAN_HOST_REG_REG_H_
+#define _MBOX_WLAN_HOST_REG_REG_H_
+
+#define HOST_INT_STATUS_ADDRESS 0x00000400
+#define HOST_INT_STATUS_OFFSET 0x00000400
+#define HOST_INT_STATUS_ERROR_MSB 7
+#define HOST_INT_STATUS_ERROR_LSB 7
+#define HOST_INT_STATUS_ERROR_MASK 0x00000080
+#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
+#define HOST_INT_STATUS_CPU_MSB 6
+#define HOST_INT_STATUS_CPU_LSB 6
+#define HOST_INT_STATUS_CPU_MASK 0x00000040
+#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
+#define HOST_INT_STATUS_INT_MSB 5
+#define HOST_INT_STATUS_INT_LSB 5
+#define HOST_INT_STATUS_INT_MASK 0x00000020
+#define HOST_INT_STATUS_INT_GET(x) (((x) & HOST_INT_STATUS_INT_MASK) >> HOST_INT_STATUS_INT_LSB)
+#define HOST_INT_STATUS_INT_SET(x) (((x) << HOST_INT_STATUS_INT_LSB) & HOST_INT_STATUS_INT_MASK)
+#define HOST_INT_STATUS_COUNTER_MSB 4
+#define HOST_INT_STATUS_COUNTER_LSB 4
+#define HOST_INT_STATUS_COUNTER_MASK 0x00000010
+#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
+#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
+#define HOST_INT_STATUS_MBOX_DATA_MSB 3
+#define HOST_INT_STATUS_MBOX_DATA_LSB 0
+#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f
+#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
+#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ADDRESS 0x00000401
+#define CPU_INT_STATUS_OFFSET 0x00000401
+#define CPU_INT_STATUS_BIT_MSB 7
+#define CPU_INT_STATUS_BIT_LSB 0
+#define CPU_INT_STATUS_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_BIT_GET(x) (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
+#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
+
+#define ERROR_INT_STATUS_ADDRESS 0x00000402
+#define ERROR_INT_STATUS_OFFSET 0x00000402
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB)
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK)
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MSB 5
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB 5
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB)
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK)
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MSB 4
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB 4
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_SPI_MSB 3
+#define ERROR_INT_STATUS_SPI_LSB 3
+#define ERROR_INT_STATUS_SPI_MASK 0x00000008
+#define ERROR_INT_STATUS_SPI_GET(x) (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
+#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
+#define ERROR_INT_STATUS_WAKEUP_MSB 2
+#define ERROR_INT_STATUS_WAKEUP_LSB 2
+#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004
+#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ADDRESS 0x00000403
+#define COUNTER_INT_STATUS_OFFSET 0x00000403
+#define COUNTER_INT_STATUS_COUNTER_MSB 7
+#define COUNTER_INT_STATUS_COUNTER_LSB 0
+#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff
+#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
+#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
+
+#define MBOX_FRAME_ADDRESS 0x00000404
+#define MBOX_FRAME_OFFSET 0x00000404
+#define MBOX_FRAME_RX_EOM_MSB 7
+#define MBOX_FRAME_RX_EOM_LSB 4
+#define MBOX_FRAME_RX_EOM_MASK 0x000000f0
+#define MBOX_FRAME_RX_EOM_GET(x) (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
+#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
+#define MBOX_FRAME_RX_SOM_MSB 3
+#define MBOX_FRAME_RX_SOM_LSB 0
+#define MBOX_FRAME_RX_SOM_MASK 0x0000000f
+#define MBOX_FRAME_RX_SOM_GET(x) (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
+#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
+
+#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
+#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405
+#define RX_LOOKAHEAD_VALID_MBOX_MSB 3
+#define RX_LOOKAHEAD_VALID_MBOX_LSB 0
+#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f
+#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
+#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
+
+#define HOST_INT_STATUS2_ADDRESS 0x00000406
+#define HOST_INT_STATUS2_OFFSET 0x00000406
+#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MSB 2
+#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB 2
+#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK 0x00000004
+#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB)
+#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK)
+#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MSB 1
+#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB 1
+#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK 0x00000002
+#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB)
+#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK)
+#define HOST_INT_STATUS2_GMBOX_DATA_MSB 0
+#define HOST_INT_STATUS2_GMBOX_DATA_LSB 0
+#define HOST_INT_STATUS2_GMBOX_DATA_MASK 0x00000001
+#define HOST_INT_STATUS2_GMBOX_DATA_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_DATA_MASK) >> HOST_INT_STATUS2_GMBOX_DATA_LSB)
+#define HOST_INT_STATUS2_GMBOX_DATA_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_DATA_LSB) & HOST_INT_STATUS2_GMBOX_DATA_MASK)
+
+#define GMBOX_RX_AVAIL_ADDRESS 0x00000407
+#define GMBOX_RX_AVAIL_OFFSET 0x00000407
+#define GMBOX_RX_AVAIL_BYTE_MSB 6
+#define GMBOX_RX_AVAIL_BYTE_LSB 0
+#define GMBOX_RX_AVAIL_BYTE_MASK 0x0000007f
+#define GMBOX_RX_AVAIL_BYTE_GET(x) (((x) & GMBOX_RX_AVAIL_BYTE_MASK) >> GMBOX_RX_AVAIL_BYTE_LSB)
+#define GMBOX_RX_AVAIL_BYTE_SET(x) (((x) << GMBOX_RX_AVAIL_BYTE_LSB) & GMBOX_RX_AVAIL_BYTE_MASK)
+
+#define RX_LOOKAHEAD0_ADDRESS 0x00000408
+#define RX_LOOKAHEAD0_OFFSET 0x00000408
+#define RX_LOOKAHEAD0_DATA_MSB 7
+#define RX_LOOKAHEAD0_DATA_LSB 0
+#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD0_DATA_GET(x) (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
+#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
+
+#define RX_LOOKAHEAD1_ADDRESS 0x0000040c
+#define RX_LOOKAHEAD1_OFFSET 0x0000040c
+#define RX_LOOKAHEAD1_DATA_MSB 7
+#define RX_LOOKAHEAD1_DATA_LSB 0
+#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD1_DATA_GET(x) (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
+#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
+
+#define RX_LOOKAHEAD2_ADDRESS 0x00000410
+#define RX_LOOKAHEAD2_OFFSET 0x00000410
+#define RX_LOOKAHEAD2_DATA_MSB 7
+#define RX_LOOKAHEAD2_DATA_LSB 0
+#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD2_DATA_GET(x) (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
+#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
+
+#define RX_LOOKAHEAD3_ADDRESS 0x00000414
+#define RX_LOOKAHEAD3_OFFSET 0x00000414
+#define RX_LOOKAHEAD3_DATA_MSB 7
+#define RX_LOOKAHEAD3_DATA_LSB 0
+#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD3_DATA_GET(x) (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
+#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
+
+#define INT_STATUS_ENABLE_ADDRESS 0x00000418
+#define INT_STATUS_ENABLE_OFFSET 0x00000418
+#define INT_STATUS_ENABLE_ERROR_MSB 7
+#define INT_STATUS_ENABLE_ERROR_LSB 7
+#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080
+#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
+#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_MSB 6
+#define INT_STATUS_ENABLE_CPU_LSB 6
+#define INT_STATUS_ENABLE_CPU_MASK 0x00000040
+#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
+#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_INT_MSB 5
+#define INT_STATUS_ENABLE_INT_LSB 5
+#define INT_STATUS_ENABLE_INT_MASK 0x00000020
+#define INT_STATUS_ENABLE_INT_GET(x) (((x) & INT_STATUS_ENABLE_INT_MASK) >> INT_STATUS_ENABLE_INT_LSB)
+#define INT_STATUS_ENABLE_INT_SET(x) (((x) << INT_STATUS_ENABLE_INT_LSB) & INT_STATUS_ENABLE_INT_MASK)
+#define INT_STATUS_ENABLE_COUNTER_MSB 4
+#define INT_STATUS_ENABLE_COUNTER_LSB 4
+#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
+#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
+#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
+#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
+#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
+#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_MSB 7
+#define CPU_INT_STATUS_ENABLE_BIT_LSB 0
+#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
+#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
+
+#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
+#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MSB 6
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB 6
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB)
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK)
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MSB 5
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB 5
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MSB 4
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB 4
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004
+#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
+#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
+#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+
+#define COUNT_ADDRESS 0x00000420
+#define COUNT_OFFSET 0x00000420
+#define COUNT_VALUE_MSB 7
+#define COUNT_VALUE_LSB 0
+#define COUNT_VALUE_MASK 0x000000ff
+#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
+#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
+
+#define COUNT_DEC_ADDRESS 0x00000440
+#define COUNT_DEC_OFFSET 0x00000440
+#define COUNT_DEC_VALUE_MSB 7
+#define COUNT_DEC_VALUE_LSB 0
+#define COUNT_DEC_VALUE_MASK 0x000000ff
+#define COUNT_DEC_VALUE_GET(x) (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
+#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
+
+#define SCRATCH_ADDRESS 0x00000460
+#define SCRATCH_OFFSET 0x00000460
+#define SCRATCH_VALUE_MSB 7
+#define SCRATCH_VALUE_LSB 0
+#define SCRATCH_VALUE_MASK 0x000000ff
+#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
+#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ADDRESS 0x00000468
+#define FIFO_TIMEOUT_OFFSET 0x00000468
+#define FIFO_TIMEOUT_VALUE_MSB 7
+#define FIFO_TIMEOUT_VALUE_LSB 0
+#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff
+#define FIFO_TIMEOUT_VALUE_GET(x) (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
+#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469
+#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469
+#define FIFO_TIMEOUT_ENABLE_SET_MSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_LSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001
+#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
+#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
+
+#define DISABLE_SLEEP_ADDRESS 0x0000046a
+#define DISABLE_SLEEP_OFFSET 0x0000046a
+#define DISABLE_SLEEP_FOR_INT_MSB 1
+#define DISABLE_SLEEP_FOR_INT_LSB 1
+#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002
+#define DISABLE_SLEEP_FOR_INT_GET(x) (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
+#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
+#define DISABLE_SLEEP_ON_MSB 0
+#define DISABLE_SLEEP_ON_LSB 0
+#define DISABLE_SLEEP_ON_MASK 0x00000001
+#define DISABLE_SLEEP_ON_GET(x) (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
+#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
+
+#define LOCAL_BUS_ADDRESS 0x00000470
+#define LOCAL_BUS_OFFSET 0x00000470
+#define LOCAL_BUS_STATE_MSB 1
+#define LOCAL_BUS_STATE_LSB 0
+#define LOCAL_BUS_STATE_MASK 0x00000003
+#define LOCAL_BUS_STATE_GET(x) (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
+#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
+
+#define INT_WLAN_ADDRESS 0x00000472
+#define INT_WLAN_OFFSET 0x00000472
+#define INT_WLAN_VECTOR_MSB 7
+#define INT_WLAN_VECTOR_LSB 0
+#define INT_WLAN_VECTOR_MASK 0x000000ff
+#define INT_WLAN_VECTOR_GET(x) (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
+#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
+
+#define WINDOW_DATA_ADDRESS 0x00000474
+#define WINDOW_DATA_OFFSET 0x00000474
+#define WINDOW_DATA_DATA_MSB 7
+#define WINDOW_DATA_DATA_LSB 0
+#define WINDOW_DATA_DATA_MASK 0x000000ff
+#define WINDOW_DATA_DATA_GET(x) (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
+#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
+
+#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
+#define WINDOW_WRITE_ADDR_OFFSET 0x00000478
+#define WINDOW_WRITE_ADDR_ADDR_MSB 7
+#define WINDOW_WRITE_ADDR_ADDR_LSB 0
+#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff
+#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
+#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
+
+#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
+#define WINDOW_READ_ADDR_OFFSET 0x0000047c
+#define WINDOW_READ_ADDR_ADDR_MSB 7
+#define WINDOW_READ_ADDR_ADDR_LSB 0
+#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff
+#define WINDOW_READ_ADDR_ADDR_GET(x) (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
+#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
+
+#define HOST_CTRL_SPI_CONFIG_ADDRESS 0x00000480
+#define HOST_CTRL_SPI_CONFIG_OFFSET 0x00000480
+#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MSB 4
+#define HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB 4
+#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK 0x00000010
+#define HOST_CTRL_SPI_CONFIG_SPI_RESET_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) >> HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB)
+#define HOST_CTRL_SPI_CONFIG_SPI_RESET_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK)
+#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
+#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
+#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
+#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB)
+#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK)
+#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MSB 2
+#define HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB 2
+#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK 0x00000004
+#define HOST_CTRL_SPI_CONFIG_TEST_MODE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) >> HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB)
+#define HOST_CTRL_SPI_CONFIG_TEST_MODE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK)
+#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MSB 1
+#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB 0
+#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK 0x00000003
+#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) >> HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB)
+#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK)
+
+#define HOST_CTRL_SPI_STATUS_ADDRESS 0x00000481
+#define HOST_CTRL_SPI_STATUS_OFFSET 0x00000481
+#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MSB 3
+#define HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB 3
+#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK 0x00000008
+#define HOST_CTRL_SPI_STATUS_ADDR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB)
+#define HOST_CTRL_SPI_STATUS_ADDR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK)
+#define HOST_CTRL_SPI_STATUS_RD_ERR_MSB 2
+#define HOST_CTRL_SPI_STATUS_RD_ERR_LSB 2
+#define HOST_CTRL_SPI_STATUS_RD_ERR_MASK 0x00000004
+#define HOST_CTRL_SPI_STATUS_RD_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) >> HOST_CTRL_SPI_STATUS_RD_ERR_LSB)
+#define HOST_CTRL_SPI_STATUS_RD_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_RD_ERR_LSB) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK)
+#define HOST_CTRL_SPI_STATUS_WR_ERR_MSB 1
+#define HOST_CTRL_SPI_STATUS_WR_ERR_LSB 1
+#define HOST_CTRL_SPI_STATUS_WR_ERR_MASK 0x00000002
+#define HOST_CTRL_SPI_STATUS_WR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_WR_ERR_LSB)
+#define HOST_CTRL_SPI_STATUS_WR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_WR_ERR_LSB) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK)
+#define HOST_CTRL_SPI_STATUS_READY_MSB 0
+#define HOST_CTRL_SPI_STATUS_READY_LSB 0
+#define HOST_CTRL_SPI_STATUS_READY_MASK 0x00000001
+#define HOST_CTRL_SPI_STATUS_READY_GET(x) (((x) & HOST_CTRL_SPI_STATUS_READY_MASK) >> HOST_CTRL_SPI_STATUS_READY_LSB)
+#define HOST_CTRL_SPI_STATUS_READY_SET(x) (((x) << HOST_CTRL_SPI_STATUS_READY_LSB) & HOST_CTRL_SPI_STATUS_READY_MASK)
+
+#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482
+#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482
+#define NON_ASSOC_SLEEP_EN_BIT_MSB 0
+#define NON_ASSOC_SLEEP_EN_BIT_LSB 0
+#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001
+#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
+#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
+
+#define CPU_DBG_SEL_ADDRESS 0x00000483
+#define CPU_DBG_SEL_OFFSET 0x00000483
+#define CPU_DBG_SEL_BIT_MSB 5
+#define CPU_DBG_SEL_BIT_LSB 0
+#define CPU_DBG_SEL_BIT_MASK 0x0000003f
+#define CPU_DBG_SEL_BIT_GET(x) (((x) & CPU_DBG_SEL_BIT_MASK) >> CPU_DBG_SEL_BIT_LSB)
+#define CPU_DBG_SEL_BIT_SET(x) (((x) << CPU_DBG_SEL_BIT_LSB) & CPU_DBG_SEL_BIT_MASK)
+
+#define CPU_DBG_ADDRESS 0x00000484
+#define CPU_DBG_OFFSET 0x00000484
+#define CPU_DBG_DATA_MSB 7
+#define CPU_DBG_DATA_LSB 0
+#define CPU_DBG_DATA_MASK 0x000000ff
+#define CPU_DBG_DATA_GET(x) (((x) & CPU_DBG_DATA_MASK) >> CPU_DBG_DATA_LSB)
+#define CPU_DBG_DATA_SET(x) (((x) << CPU_DBG_DATA_LSB) & CPU_DBG_DATA_MASK)
+
+#define INT_STATUS2_ENABLE_ADDRESS 0x00000488
+#define INT_STATUS2_ENABLE_OFFSET 0x00000488
+#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MSB 2
+#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB 2
+#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK 0x00000004
+#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB)
+#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK)
+#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MSB 1
+#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB 1
+#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK 0x00000002
+#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB)
+#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK)
+#define INT_STATUS2_ENABLE_GMBOX_DATA_MSB 0
+#define INT_STATUS2_ENABLE_GMBOX_DATA_LSB 0
+#define INT_STATUS2_ENABLE_GMBOX_DATA_MASK 0x00000001
+#define INT_STATUS2_ENABLE_GMBOX_DATA_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) >> INT_STATUS2_ENABLE_GMBOX_DATA_LSB)
+#define INT_STATUS2_ENABLE_GMBOX_DATA_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_DATA_LSB) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK)
+
+#define GMBOX_RX_LOOKAHEAD_ADDRESS 0x00000490
+#define GMBOX_RX_LOOKAHEAD_OFFSET 0x00000490
+#define GMBOX_RX_LOOKAHEAD_DATA_MSB 7
+#define GMBOX_RX_LOOKAHEAD_DATA_LSB 0
+#define GMBOX_RX_LOOKAHEAD_DATA_MASK 0x000000ff
+#define GMBOX_RX_LOOKAHEAD_DATA_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_DATA_MASK) >> GMBOX_RX_LOOKAHEAD_DATA_LSB)
+#define GMBOX_RX_LOOKAHEAD_DATA_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_DATA_LSB) & GMBOX_RX_LOOKAHEAD_DATA_MASK)
+
+#define GMBOX_RX_LOOKAHEAD_MUX_ADDRESS 0x00000498
+#define GMBOX_RX_LOOKAHEAD_MUX_OFFSET 0x00000498
+#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MSB 0
+#define GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB 0
+#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK 0x00000001
+#define GMBOX_RX_LOOKAHEAD_MUX_SEL_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) >> GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB)
+#define GMBOX_RX_LOOKAHEAD_MUX_SEL_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK)
+
+#define CIS_WINDOW_ADDRESS 0x00000600
+#define CIS_WINDOW_OFFSET 0x00000600
+#define CIS_WINDOW_DATA_MSB 7
+#define CIS_WINDOW_DATA_LSB 0
+#define CIS_WINDOW_DATA_MASK 0x000000ff
+#define CIS_WINDOW_DATA_GET(x) (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
+#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct mbox_wlan_host_reg_reg_s {
+ unsigned char pad0[1024]; /* pad to 0x400 */
+ volatile unsigned char host_int_status;
+ volatile unsigned char cpu_int_status;
+ volatile unsigned char error_int_status;
+ volatile unsigned char counter_int_status;
+ volatile unsigned char mbox_frame;
+ volatile unsigned char rx_lookahead_valid;
+ volatile unsigned char host_int_status2;
+ volatile unsigned char gmbox_rx_avail;
+ volatile unsigned char rx_lookahead0[4];
+ volatile unsigned char rx_lookahead1[4];
+ volatile unsigned char rx_lookahead2[4];
+ volatile unsigned char rx_lookahead3[4];
+ volatile unsigned char int_status_enable;
+ volatile unsigned char cpu_int_status_enable;
+ volatile unsigned char error_status_enable;
+ volatile unsigned char counter_int_status_enable;
+ unsigned char pad1[4]; /* pad to 0x420 */
+ volatile unsigned char count[8];
+ unsigned char pad2[24]; /* pad to 0x440 */
+ volatile unsigned char count_dec[32];
+ volatile unsigned char scratch[8];
+ volatile unsigned char fifo_timeout;
+ volatile unsigned char fifo_timeout_enable;
+ volatile unsigned char disable_sleep;
+ unsigned char pad3[5]; /* pad to 0x470 */
+ volatile unsigned char local_bus;
+ unsigned char pad4[1]; /* pad to 0x472 */
+ volatile unsigned char int_wlan;
+ unsigned char pad5[1]; /* pad to 0x474 */
+ volatile unsigned char window_data[4];
+ volatile unsigned char window_write_addr[4];
+ volatile unsigned char window_read_addr[4];
+ volatile unsigned char host_ctrl_spi_config;
+ volatile unsigned char host_ctrl_spi_status;
+ volatile unsigned char non_assoc_sleep_en;
+ volatile unsigned char cpu_dbg_sel;
+ volatile unsigned char cpu_dbg[4];
+ volatile unsigned char int_status2_enable;
+ unsigned char pad6[7]; /* pad to 0x490 */
+ volatile unsigned char gmbox_rx_lookahead[8];
+ volatile unsigned char gmbox_rx_lookahead_mux;
+ unsigned char pad7[359]; /* pad to 0x600 */
+ volatile unsigned char cis_window[512];
+} mbox_wlan_host_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_WLAN_HOST_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
new file mode 100644
index 000000000000..e00270fc1450
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
@@ -0,0 +1,638 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _MBOX_WLAN_REG_REG_H_
+#define _MBOX_WLAN_REG_REG_H_
+
+#define WLAN_MBOX_FIFO_ADDRESS 0x00000000
+#define WLAN_MBOX_FIFO_OFFSET 0x00000000
+#define WLAN_MBOX_FIFO_DATA_MSB 19
+#define WLAN_MBOX_FIFO_DATA_LSB 0
+#define WLAN_MBOX_FIFO_DATA_MASK 0x000fffff
+#define WLAN_MBOX_FIFO_DATA_GET(x) (((x) & WLAN_MBOX_FIFO_DATA_MASK) >> WLAN_MBOX_FIFO_DATA_LSB)
+#define WLAN_MBOX_FIFO_DATA_SET(x) (((x) << WLAN_MBOX_FIFO_DATA_LSB) & WLAN_MBOX_FIFO_DATA_MASK)
+
+#define WLAN_MBOX_FIFO_STATUS_ADDRESS 0x00000010
+#define WLAN_MBOX_FIFO_STATUS_OFFSET 0x00000010
+#define WLAN_MBOX_FIFO_STATUS_EMPTY_MSB 19
+#define WLAN_MBOX_FIFO_STATUS_EMPTY_LSB 16
+#define WLAN_MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000
+#define WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) >> WLAN_MBOX_FIFO_STATUS_EMPTY_LSB)
+#define WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK)
+#define WLAN_MBOX_FIFO_STATUS_FULL_MSB 15
+#define WLAN_MBOX_FIFO_STATUS_FULL_LSB 12
+#define WLAN_MBOX_FIFO_STATUS_FULL_MASK 0x0000f000
+#define WLAN_MBOX_FIFO_STATUS_FULL_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) >> WLAN_MBOX_FIFO_STATUS_FULL_LSB)
+#define WLAN_MBOX_FIFO_STATUS_FULL_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_FULL_LSB) & WLAN_MBOX_FIFO_STATUS_FULL_MASK)
+
+#define WLAN_MBOX_DMA_POLICY_ADDRESS 0x00000014
+#define WLAN_MBOX_DMA_POLICY_OFFSET 0x00000014
+#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB 3
+#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB 3
+#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008
+#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB)
+#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK)
+#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB 2
+#define WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB 2
+#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004
+#define WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB)
+#define WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK)
+#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB 1
+#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB 1
+#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002
+#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB)
+#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK)
+#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB 0
+#define WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB 0
+#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001
+#define WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB)
+#define WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK)
+
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c
+#define WLAN_MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c
+#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX0_DMA_RX_CONTROL_START_MSB 1
+#define WLAN_MBOX0_DMA_RX_CONTROL_START_LSB 1
+#define WLAN_MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_START_LSB)
+#define WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK)
+#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB)
+#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024
+#define WLAN_MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024
+#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX0_DMA_TX_CONTROL_START_MSB 1
+#define WLAN_MBOX0_DMA_TX_CONTROL_START_LSB 1
+#define WLAN_MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_START_LSB)
+#define WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK)
+#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB)
+#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c
+#define WLAN_MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c
+#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX1_DMA_RX_CONTROL_START_MSB 1
+#define WLAN_MBOX1_DMA_RX_CONTROL_START_LSB 1
+#define WLAN_MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_START_LSB)
+#define WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK)
+#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB)
+#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034
+#define WLAN_MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034
+#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX1_DMA_TX_CONTROL_START_MSB 1
+#define WLAN_MBOX1_DMA_TX_CONTROL_START_LSB 1
+#define WLAN_MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_START_LSB)
+#define WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK)
+#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB)
+#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c
+#define WLAN_MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c
+#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX2_DMA_RX_CONTROL_START_MSB 1
+#define WLAN_MBOX2_DMA_RX_CONTROL_START_LSB 1
+#define WLAN_MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_START_LSB)
+#define WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK)
+#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB)
+#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044
+#define WLAN_MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044
+#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX2_DMA_TX_CONTROL_START_MSB 1
+#define WLAN_MBOX2_DMA_TX_CONTROL_START_LSB 1
+#define WLAN_MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_START_LSB)
+#define WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK)
+#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB)
+#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c
+#define WLAN_MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c
+#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX3_DMA_RX_CONTROL_START_MSB 1
+#define WLAN_MBOX3_DMA_RX_CONTROL_START_LSB 1
+#define WLAN_MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_START_LSB)
+#define WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK)
+#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB)
+#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054
+#define WLAN_MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054
+#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB 2
+#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB 2
+#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB)
+#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK)
+#define WLAN_MBOX3_DMA_TX_CONTROL_START_MSB 1
+#define WLAN_MBOX3_DMA_TX_CONTROL_START_LSB 1
+#define WLAN_MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002
+#define WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_START_LSB)
+#define WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK)
+#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB 0
+#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB 0
+#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB)
+#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK)
+
+#define WLAN_MBOX_INT_STATUS_ADDRESS 0x00000058
+#define WLAN_MBOX_INT_STATUS_OFFSET 0x00000058
+#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31
+#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28
+#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000
+#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
+#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
+#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27
+#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24
+#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
+#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
+#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23
+#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20
+#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000
+#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
+#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
+#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB 17
+#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB 17
+#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000
+#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB)
+#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK)
+#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16
+#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16
+#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000
+#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
+#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
+#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15
+#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12
+#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000
+#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
+#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
+#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB 11
+#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB 8
+#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00
+#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB)
+#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK)
+#define WLAN_MBOX_INT_STATUS_HOST_MSB 7
+#define WLAN_MBOX_INT_STATUS_HOST_LSB 0
+#define WLAN_MBOX_INT_STATUS_HOST_MASK 0x000000ff
+#define WLAN_MBOX_INT_STATUS_HOST_GET(x) (((x) & WLAN_MBOX_INT_STATUS_HOST_MASK) >> WLAN_MBOX_INT_STATUS_HOST_LSB)
+#define WLAN_MBOX_INT_STATUS_HOST_SET(x) (((x) << WLAN_MBOX_INT_STATUS_HOST_LSB) & WLAN_MBOX_INT_STATUS_HOST_MASK)
+
+#define WLAN_MBOX_INT_ENABLE_ADDRESS 0x0000005c
+#define WLAN_MBOX_INT_ENABLE_OFFSET 0x0000005c
+#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31
+#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28
+#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000
+#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
+#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
+#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
+#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17
+#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17
+#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000
+#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
+#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
+#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16
+#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16
+#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000
+#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
+#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
+#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15
+#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12
+#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000
+#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
+#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
+#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11
+#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8
+#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00
+#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
+#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
+#define WLAN_MBOX_INT_ENABLE_HOST_MSB 7
+#define WLAN_MBOX_INT_ENABLE_HOST_LSB 0
+#define WLAN_MBOX_INT_ENABLE_HOST_MASK 0x000000ff
+#define WLAN_MBOX_INT_ENABLE_HOST_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_HOST_MASK) >> WLAN_MBOX_INT_ENABLE_HOST_LSB)
+#define WLAN_MBOX_INT_ENABLE_HOST_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_HOST_LSB) & WLAN_MBOX_INT_ENABLE_HOST_MASK)
+
+#define WLAN_INT_HOST_ADDRESS 0x00000060
+#define WLAN_INT_HOST_OFFSET 0x00000060
+#define WLAN_INT_HOST_VECTOR_MSB 7
+#define WLAN_INT_HOST_VECTOR_LSB 0
+#define WLAN_INT_HOST_VECTOR_MASK 0x000000ff
+#define WLAN_INT_HOST_VECTOR_GET(x) (((x) & WLAN_INT_HOST_VECTOR_MASK) >> WLAN_INT_HOST_VECTOR_LSB)
+#define WLAN_INT_HOST_VECTOR_SET(x) (((x) << WLAN_INT_HOST_VECTOR_LSB) & WLAN_INT_HOST_VECTOR_MASK)
+
+#define WLAN_LOCAL_COUNT_ADDRESS 0x00000080
+#define WLAN_LOCAL_COUNT_OFFSET 0x00000080
+#define WLAN_LOCAL_COUNT_VALUE_MSB 7
+#define WLAN_LOCAL_COUNT_VALUE_LSB 0
+#define WLAN_LOCAL_COUNT_VALUE_MASK 0x000000ff
+#define WLAN_LOCAL_COUNT_VALUE_GET(x) (((x) & WLAN_LOCAL_COUNT_VALUE_MASK) >> WLAN_LOCAL_COUNT_VALUE_LSB)
+#define WLAN_LOCAL_COUNT_VALUE_SET(x) (((x) << WLAN_LOCAL_COUNT_VALUE_LSB) & WLAN_LOCAL_COUNT_VALUE_MASK)
+
+#define WLAN_COUNT_INC_ADDRESS 0x000000a0
+#define WLAN_COUNT_INC_OFFSET 0x000000a0
+#define WLAN_COUNT_INC_VALUE_MSB 7
+#define WLAN_COUNT_INC_VALUE_LSB 0
+#define WLAN_COUNT_INC_VALUE_MASK 0x000000ff
+#define WLAN_COUNT_INC_VALUE_GET(x) (((x) & WLAN_COUNT_INC_VALUE_MASK) >> WLAN_COUNT_INC_VALUE_LSB)
+#define WLAN_COUNT_INC_VALUE_SET(x) (((x) << WLAN_COUNT_INC_VALUE_LSB) & WLAN_COUNT_INC_VALUE_MASK)
+
+#define WLAN_LOCAL_SCRATCH_ADDRESS 0x000000c0
+#define WLAN_LOCAL_SCRATCH_OFFSET 0x000000c0
+#define WLAN_LOCAL_SCRATCH_VALUE_MSB 7
+#define WLAN_LOCAL_SCRATCH_VALUE_LSB 0
+#define WLAN_LOCAL_SCRATCH_VALUE_MASK 0x000000ff
+#define WLAN_LOCAL_SCRATCH_VALUE_GET(x) (((x) & WLAN_LOCAL_SCRATCH_VALUE_MASK) >> WLAN_LOCAL_SCRATCH_VALUE_LSB)
+#define WLAN_LOCAL_SCRATCH_VALUE_SET(x) (((x) << WLAN_LOCAL_SCRATCH_VALUE_LSB) & WLAN_LOCAL_SCRATCH_VALUE_MASK)
+
+#define WLAN_USE_LOCAL_BUS_ADDRESS 0x000000e0
+#define WLAN_USE_LOCAL_BUS_OFFSET 0x000000e0
+#define WLAN_USE_LOCAL_BUS_PIN_INIT_MSB 0
+#define WLAN_USE_LOCAL_BUS_PIN_INIT_LSB 0
+#define WLAN_USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001
+#define WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x) (((x) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) >> WLAN_USE_LOCAL_BUS_PIN_INIT_LSB)
+#define WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK)
+
+#define WLAN_SDIO_CONFIG_ADDRESS 0x000000e4
+#define WLAN_SDIO_CONFIG_OFFSET 0x000000e4
+#define WLAN_SDIO_CONFIG_CCCR_IOR1_MSB 0
+#define WLAN_SDIO_CONFIG_CCCR_IOR1_LSB 0
+#define WLAN_SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001
+#define WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x) (((x) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) >> WLAN_SDIO_CONFIG_CCCR_IOR1_LSB)
+#define WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK)
+
+#define WLAN_MBOX_DEBUG_ADDRESS 0x000000e8
+#define WLAN_MBOX_DEBUG_OFFSET 0x000000e8
+#define WLAN_MBOX_DEBUG_SEL_MSB 2
+#define WLAN_MBOX_DEBUG_SEL_LSB 0
+#define WLAN_MBOX_DEBUG_SEL_MASK 0x00000007
+#define WLAN_MBOX_DEBUG_SEL_GET(x) (((x) & WLAN_MBOX_DEBUG_SEL_MASK) >> WLAN_MBOX_DEBUG_SEL_LSB)
+#define WLAN_MBOX_DEBUG_SEL_SET(x) (((x) << WLAN_MBOX_DEBUG_SEL_LSB) & WLAN_MBOX_DEBUG_SEL_MASK)
+
+#define WLAN_MBOX_FIFO_RESET_ADDRESS 0x000000ec
+#define WLAN_MBOX_FIFO_RESET_OFFSET 0x000000ec
+#define WLAN_MBOX_FIFO_RESET_INIT_MSB 0
+#define WLAN_MBOX_FIFO_RESET_INIT_LSB 0
+#define WLAN_MBOX_FIFO_RESET_INIT_MASK 0x00000001
+#define WLAN_MBOX_FIFO_RESET_INIT_GET(x) (((x) & WLAN_MBOX_FIFO_RESET_INIT_MASK) >> WLAN_MBOX_FIFO_RESET_INIT_LSB)
+#define WLAN_MBOX_FIFO_RESET_INIT_SET(x) (((x) << WLAN_MBOX_FIFO_RESET_INIT_LSB) & WLAN_MBOX_FIFO_RESET_INIT_MASK)
+
+#define WLAN_MBOX_TXFIFO_POP_ADDRESS 0x000000f0
+#define WLAN_MBOX_TXFIFO_POP_OFFSET 0x000000f0
+#define WLAN_MBOX_TXFIFO_POP_DATA_MSB 0
+#define WLAN_MBOX_TXFIFO_POP_DATA_LSB 0
+#define WLAN_MBOX_TXFIFO_POP_DATA_MASK 0x00000001
+#define WLAN_MBOX_TXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) >> WLAN_MBOX_TXFIFO_POP_DATA_LSB)
+#define WLAN_MBOX_TXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_TXFIFO_POP_DATA_LSB) & WLAN_MBOX_TXFIFO_POP_DATA_MASK)
+
+#define WLAN_MBOX_RXFIFO_POP_ADDRESS 0x00000100
+#define WLAN_MBOX_RXFIFO_POP_OFFSET 0x00000100
+#define WLAN_MBOX_RXFIFO_POP_DATA_MSB 0
+#define WLAN_MBOX_RXFIFO_POP_DATA_LSB 0
+#define WLAN_MBOX_RXFIFO_POP_DATA_MASK 0x00000001
+#define WLAN_MBOX_RXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) >> WLAN_MBOX_RXFIFO_POP_DATA_LSB)
+#define WLAN_MBOX_RXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_RXFIFO_POP_DATA_LSB) & WLAN_MBOX_RXFIFO_POP_DATA_MASK)
+
+#define WLAN_SDIO_DEBUG_ADDRESS 0x00000110
+#define WLAN_SDIO_DEBUG_OFFSET 0x00000110
+#define WLAN_SDIO_DEBUG_SEL_MSB 3
+#define WLAN_SDIO_DEBUG_SEL_LSB 0
+#define WLAN_SDIO_DEBUG_SEL_MASK 0x0000000f
+#define WLAN_SDIO_DEBUG_SEL_GET(x) (((x) & WLAN_SDIO_DEBUG_SEL_MASK) >> WLAN_SDIO_DEBUG_SEL_LSB)
+#define WLAN_SDIO_DEBUG_SEL_SET(x) (((x) << WLAN_SDIO_DEBUG_SEL_LSB) & WLAN_SDIO_DEBUG_SEL_MASK)
+
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000114
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000114
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS 0x00000118
+#define WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET 0x00000118
+#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB 2
+#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB 2
+#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB)
+#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK)
+#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB 1
+#define WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB 1
+#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
+#define WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB)
+#define WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK)
+#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB 0
+#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB 0
+#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB)
+#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK)
+
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x0000011c
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x0000011c
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS 0x00000120
+#define WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET 0x00000120
+#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB 2
+#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB 2
+#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB)
+#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK)
+#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB 1
+#define WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB 1
+#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
+#define WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB)
+#define WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK)
+#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB 0
+#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB 0
+#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB)
+#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK)
+
+#define WLAN_GMBOX_INT_STATUS_ADDRESS 0x00000124
+#define WLAN_GMBOX_INT_STATUS_OFFSET 0x00000124
+#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB 6
+#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB 6
+#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00000040
+#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB)
+#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK)
+#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB 5
+#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB 5
+#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00000020
+#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
+#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
+#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 4
+#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 4
+#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000010
+#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 3
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 3
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000008
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 2
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 2
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000004
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB 1
+#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB 1
+#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x00000002
+#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
+#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
+#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB 0
+#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB 0
+#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000001
+#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB)
+#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK)
+
+#define WLAN_GMBOX_INT_ENABLE_ADDRESS 0x00000128
+#define WLAN_GMBOX_INT_ENABLE_OFFSET 0x00000128
+#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB 6
+#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB 6
+#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00000040
+#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
+#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
+#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB 5
+#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB 5
+#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00000020
+#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
+#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
+#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 4
+#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 4
+#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000010
+#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 3
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 3
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000008
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 2
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 2
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000004
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
+#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
+#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 1
+#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 1
+#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x00000002
+#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
+#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
+#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB 0
+#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB 0
+#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000001
+#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
+#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
+
+#define WLAN_HOST_IF_WINDOW_ADDRESS 0x00002000
+#define WLAN_HOST_IF_WINDOW_OFFSET 0x00002000
+#define WLAN_HOST_IF_WINDOW_DATA_MSB 7
+#define WLAN_HOST_IF_WINDOW_DATA_LSB 0
+#define WLAN_HOST_IF_WINDOW_DATA_MASK 0x000000ff
+#define WLAN_HOST_IF_WINDOW_DATA_GET(x) (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB)
+#define WLAN_HOST_IF_WINDOW_DATA_SET(x) (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct mbox_wlan_reg_reg_s {
+ volatile unsigned int wlan_mbox_fifo[4];
+ volatile unsigned int wlan_mbox_fifo_status;
+ volatile unsigned int wlan_mbox_dma_policy;
+ volatile unsigned int wlan_mbox0_dma_rx_descriptor_base;
+ volatile unsigned int wlan_mbox0_dma_rx_control;
+ volatile unsigned int wlan_mbox0_dma_tx_descriptor_base;
+ volatile unsigned int wlan_mbox0_dma_tx_control;
+ volatile unsigned int wlan_mbox1_dma_rx_descriptor_base;
+ volatile unsigned int wlan_mbox1_dma_rx_control;
+ volatile unsigned int wlan_mbox1_dma_tx_descriptor_base;
+ volatile unsigned int wlan_mbox1_dma_tx_control;
+ volatile unsigned int wlan_mbox2_dma_rx_descriptor_base;
+ volatile unsigned int wlan_mbox2_dma_rx_control;
+ volatile unsigned int wlan_mbox2_dma_tx_descriptor_base;
+ volatile unsigned int wlan_mbox2_dma_tx_control;
+ volatile unsigned int wlan_mbox3_dma_rx_descriptor_base;
+ volatile unsigned int wlan_mbox3_dma_rx_control;
+ volatile unsigned int wlan_mbox3_dma_tx_descriptor_base;
+ volatile unsigned int wlan_mbox3_dma_tx_control;
+ volatile unsigned int wlan_mbox_int_status;
+ volatile unsigned int wlan_mbox_int_enable;
+ volatile unsigned int wlan_int_host;
+ unsigned char pad0[28]; /* pad to 0x80 */
+ volatile unsigned int wlan_local_count[8];
+ volatile unsigned int wlan_count_inc[8];
+ volatile unsigned int wlan_local_scratch[8];
+ volatile unsigned int wlan_use_local_bus;
+ volatile unsigned int wlan_sdio_config;
+ volatile unsigned int wlan_mbox_debug;
+ volatile unsigned int wlan_mbox_fifo_reset;
+ volatile unsigned int wlan_mbox_txfifo_pop[4];
+ volatile unsigned int wlan_mbox_rxfifo_pop[4];
+ volatile unsigned int wlan_sdio_debug;
+ volatile unsigned int wlan_gmbox0_dma_rx_descriptor_base;
+ volatile unsigned int wlan_gmbox0_dma_rx_control;
+ volatile unsigned int wlan_gmbox0_dma_tx_descriptor_base;
+ volatile unsigned int wlan_gmbox0_dma_tx_control;
+ volatile unsigned int wlan_gmbox_int_status;
+ volatile unsigned int wlan_gmbox_int_enable;
+ unsigned char pad1[7892]; /* pad to 0x2000 */
+ volatile unsigned int wlan_host_if_window[2048];
+} mbox_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h
new file mode 100644
index 000000000000..56ffda5b1a30
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h
@@ -0,0 +1,564 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _RDMA_REG_REG_H_
+#define _RDMA_REG_REG_H_
+
+#define DMA_CONFIG_ADDRESS 0x00000000
+#define DMA_CONFIG_OFFSET 0x00000000
+#define DMA_CONFIG_WLBB_PWD_EN_MSB 4
+#define DMA_CONFIG_WLBB_PWD_EN_LSB 4
+#define DMA_CONFIG_WLBB_PWD_EN_MASK 0x00000010
+#define DMA_CONFIG_WLBB_PWD_EN_GET(x) (((x) & DMA_CONFIG_WLBB_PWD_EN_MASK) >> DMA_CONFIG_WLBB_PWD_EN_LSB)
+#define DMA_CONFIG_WLBB_PWD_EN_SET(x) (((x) << DMA_CONFIG_WLBB_PWD_EN_LSB) & DMA_CONFIG_WLBB_PWD_EN_MASK)
+#define DMA_CONFIG_WLMAC_PWD_EN_MSB 3
+#define DMA_CONFIG_WLMAC_PWD_EN_LSB 3
+#define DMA_CONFIG_WLMAC_PWD_EN_MASK 0x00000008
+#define DMA_CONFIG_WLMAC_PWD_EN_GET(x) (((x) & DMA_CONFIG_WLMAC_PWD_EN_MASK) >> DMA_CONFIG_WLMAC_PWD_EN_LSB)
+#define DMA_CONFIG_WLMAC_PWD_EN_SET(x) (((x) << DMA_CONFIG_WLMAC_PWD_EN_LSB) & DMA_CONFIG_WLMAC_PWD_EN_MASK)
+#define DMA_CONFIG_ENABLE_RETENTION_MSB 2
+#define DMA_CONFIG_ENABLE_RETENTION_LSB 2
+#define DMA_CONFIG_ENABLE_RETENTION_MASK 0x00000004
+#define DMA_CONFIG_ENABLE_RETENTION_GET(x) (((x) & DMA_CONFIG_ENABLE_RETENTION_MASK) >> DMA_CONFIG_ENABLE_RETENTION_LSB)
+#define DMA_CONFIG_ENABLE_RETENTION_SET(x) (((x) << DMA_CONFIG_ENABLE_RETENTION_LSB) & DMA_CONFIG_ENABLE_RETENTION_MASK)
+#define DMA_CONFIG_RTC_PRIORITY_MSB 1
+#define DMA_CONFIG_RTC_PRIORITY_LSB 1
+#define DMA_CONFIG_RTC_PRIORITY_MASK 0x00000002
+#define DMA_CONFIG_RTC_PRIORITY_GET(x) (((x) & DMA_CONFIG_RTC_PRIORITY_MASK) >> DMA_CONFIG_RTC_PRIORITY_LSB)
+#define DMA_CONFIG_RTC_PRIORITY_SET(x) (((x) << DMA_CONFIG_RTC_PRIORITY_LSB) & DMA_CONFIG_RTC_PRIORITY_MASK)
+#define DMA_CONFIG_DMA_TYPE_MSB 0
+#define DMA_CONFIG_DMA_TYPE_LSB 0
+#define DMA_CONFIG_DMA_TYPE_MASK 0x00000001
+#define DMA_CONFIG_DMA_TYPE_GET(x) (((x) & DMA_CONFIG_DMA_TYPE_MASK) >> DMA_CONFIG_DMA_TYPE_LSB)
+#define DMA_CONFIG_DMA_TYPE_SET(x) (((x) << DMA_CONFIG_DMA_TYPE_LSB) & DMA_CONFIG_DMA_TYPE_MASK)
+
+#define DMA_CONTROL_ADDRESS 0x00000004
+#define DMA_CONTROL_OFFSET 0x00000004
+#define DMA_CONTROL_START_MSB 1
+#define DMA_CONTROL_START_LSB 1
+#define DMA_CONTROL_START_MASK 0x00000002
+#define DMA_CONTROL_START_GET(x) (((x) & DMA_CONTROL_START_MASK) >> DMA_CONTROL_START_LSB)
+#define DMA_CONTROL_START_SET(x) (((x) << DMA_CONTROL_START_LSB) & DMA_CONTROL_START_MASK)
+#define DMA_CONTROL_STOP_MSB 0
+#define DMA_CONTROL_STOP_LSB 0
+#define DMA_CONTROL_STOP_MASK 0x00000001
+#define DMA_CONTROL_STOP_GET(x) (((x) & DMA_CONTROL_STOP_MASK) >> DMA_CONTROL_STOP_LSB)
+#define DMA_CONTROL_STOP_SET(x) (((x) << DMA_CONTROL_STOP_LSB) & DMA_CONTROL_STOP_MASK)
+
+#define DMA_SRC_ADDRESS 0x00000008
+#define DMA_SRC_OFFSET 0x00000008
+#define DMA_SRC_ADDR_MSB 31
+#define DMA_SRC_ADDR_LSB 2
+#define DMA_SRC_ADDR_MASK 0xfffffffc
+#define DMA_SRC_ADDR_GET(x) (((x) & DMA_SRC_ADDR_MASK) >> DMA_SRC_ADDR_LSB)
+#define DMA_SRC_ADDR_SET(x) (((x) << DMA_SRC_ADDR_LSB) & DMA_SRC_ADDR_MASK)
+
+#define DMA_DEST_ADDRESS 0x0000000c
+#define DMA_DEST_OFFSET 0x0000000c
+#define DMA_DEST_ADDR_MSB 31
+#define DMA_DEST_ADDR_LSB 2
+#define DMA_DEST_ADDR_MASK 0xfffffffc
+#define DMA_DEST_ADDR_GET(x) (((x) & DMA_DEST_ADDR_MASK) >> DMA_DEST_ADDR_LSB)
+#define DMA_DEST_ADDR_SET(x) (((x) << DMA_DEST_ADDR_LSB) & DMA_DEST_ADDR_MASK)
+
+#define DMA_LENGTH_ADDRESS 0x00000010
+#define DMA_LENGTH_OFFSET 0x00000010
+#define DMA_LENGTH_WORDS_MSB 11
+#define DMA_LENGTH_WORDS_LSB 0
+#define DMA_LENGTH_WORDS_MASK 0x00000fff
+#define DMA_LENGTH_WORDS_GET(x) (((x) & DMA_LENGTH_WORDS_MASK) >> DMA_LENGTH_WORDS_LSB)
+#define DMA_LENGTH_WORDS_SET(x) (((x) << DMA_LENGTH_WORDS_LSB) & DMA_LENGTH_WORDS_MASK)
+
+#define VMC_BASE_ADDRESS 0x00000014
+#define VMC_BASE_OFFSET 0x00000014
+#define VMC_BASE_ADDR_MSB 31
+#define VMC_BASE_ADDR_LSB 2
+#define VMC_BASE_ADDR_MASK 0xfffffffc
+#define VMC_BASE_ADDR_GET(x) (((x) & VMC_BASE_ADDR_MASK) >> VMC_BASE_ADDR_LSB)
+#define VMC_BASE_ADDR_SET(x) (((x) << VMC_BASE_ADDR_LSB) & VMC_BASE_ADDR_MASK)
+
+#define INDIRECT_REG_ADDRESS 0x00000018
+#define INDIRECT_REG_OFFSET 0x00000018
+#define INDIRECT_REG_ID_MSB 31
+#define INDIRECT_REG_ID_LSB 2
+#define INDIRECT_REG_ID_MASK 0xfffffffc
+#define INDIRECT_REG_ID_GET(x) (((x) & INDIRECT_REG_ID_MASK) >> INDIRECT_REG_ID_LSB)
+#define INDIRECT_REG_ID_SET(x) (((x) << INDIRECT_REG_ID_LSB) & INDIRECT_REG_ID_MASK)
+
+#define INDIRECT_RETURN_ADDRESS 0x0000001c
+#define INDIRECT_RETURN_OFFSET 0x0000001c
+#define INDIRECT_RETURN_ADDR_MSB 31
+#define INDIRECT_RETURN_ADDR_LSB 2
+#define INDIRECT_RETURN_ADDR_MASK 0xfffffffc
+#define INDIRECT_RETURN_ADDR_GET(x) (((x) & INDIRECT_RETURN_ADDR_MASK) >> INDIRECT_RETURN_ADDR_LSB)
+#define INDIRECT_RETURN_ADDR_SET(x) (((x) << INDIRECT_RETURN_ADDR_LSB) & INDIRECT_RETURN_ADDR_MASK)
+
+#define RDMA_REGION_0__ADDRESS 0x00000020
+#define RDMA_REGION_0__OFFSET 0x00000020
+#define RDMA_REGION_0__ADDR_MSB 31
+#define RDMA_REGION_0__ADDR_LSB 13
+#define RDMA_REGION_0__ADDR_MASK 0xffffe000
+#define RDMA_REGION_0__ADDR_GET(x) (((x) & RDMA_REGION_0__ADDR_MASK) >> RDMA_REGION_0__ADDR_LSB)
+#define RDMA_REGION_0__ADDR_SET(x) (((x) << RDMA_REGION_0__ADDR_LSB) & RDMA_REGION_0__ADDR_MASK)
+#define RDMA_REGION_0__LENGTH_MSB 12
+#define RDMA_REGION_0__LENGTH_LSB 2
+#define RDMA_REGION_0__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_0__LENGTH_GET(x) (((x) & RDMA_REGION_0__LENGTH_MASK) >> RDMA_REGION_0__LENGTH_LSB)
+#define RDMA_REGION_0__LENGTH_SET(x) (((x) << RDMA_REGION_0__LENGTH_LSB) & RDMA_REGION_0__LENGTH_MASK)
+#define RDMA_REGION_0__INDI_MSB 1
+#define RDMA_REGION_0__INDI_LSB 1
+#define RDMA_REGION_0__INDI_MASK 0x00000002
+#define RDMA_REGION_0__INDI_GET(x) (((x) & RDMA_REGION_0__INDI_MASK) >> RDMA_REGION_0__INDI_LSB)
+#define RDMA_REGION_0__INDI_SET(x) (((x) << RDMA_REGION_0__INDI_LSB) & RDMA_REGION_0__INDI_MASK)
+#define RDMA_REGION_0__NEXT_MSB 0
+#define RDMA_REGION_0__NEXT_LSB 0
+#define RDMA_REGION_0__NEXT_MASK 0x00000001
+#define RDMA_REGION_0__NEXT_GET(x) (((x) & RDMA_REGION_0__NEXT_MASK) >> RDMA_REGION_0__NEXT_LSB)
+#define RDMA_REGION_0__NEXT_SET(x) (((x) << RDMA_REGION_0__NEXT_LSB) & RDMA_REGION_0__NEXT_MASK)
+
+#define RDMA_REGION_1__ADDRESS 0x00000024
+#define RDMA_REGION_1__OFFSET 0x00000024
+#define RDMA_REGION_1__ADDR_MSB 31
+#define RDMA_REGION_1__ADDR_LSB 13
+#define RDMA_REGION_1__ADDR_MASK 0xffffe000
+#define RDMA_REGION_1__ADDR_GET(x) (((x) & RDMA_REGION_1__ADDR_MASK) >> RDMA_REGION_1__ADDR_LSB)
+#define RDMA_REGION_1__ADDR_SET(x) (((x) << RDMA_REGION_1__ADDR_LSB) & RDMA_REGION_1__ADDR_MASK)
+#define RDMA_REGION_1__LENGTH_MSB 12
+#define RDMA_REGION_1__LENGTH_LSB 2
+#define RDMA_REGION_1__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_1__LENGTH_GET(x) (((x) & RDMA_REGION_1__LENGTH_MASK) >> RDMA_REGION_1__LENGTH_LSB)
+#define RDMA_REGION_1__LENGTH_SET(x) (((x) << RDMA_REGION_1__LENGTH_LSB) & RDMA_REGION_1__LENGTH_MASK)
+#define RDMA_REGION_1__INDI_MSB 1
+#define RDMA_REGION_1__INDI_LSB 1
+#define RDMA_REGION_1__INDI_MASK 0x00000002
+#define RDMA_REGION_1__INDI_GET(x) (((x) & RDMA_REGION_1__INDI_MASK) >> RDMA_REGION_1__INDI_LSB)
+#define RDMA_REGION_1__INDI_SET(x) (((x) << RDMA_REGION_1__INDI_LSB) & RDMA_REGION_1__INDI_MASK)
+#define RDMA_REGION_1__NEXT_MSB 0
+#define RDMA_REGION_1__NEXT_LSB 0
+#define RDMA_REGION_1__NEXT_MASK 0x00000001
+#define RDMA_REGION_1__NEXT_GET(x) (((x) & RDMA_REGION_1__NEXT_MASK) >> RDMA_REGION_1__NEXT_LSB)
+#define RDMA_REGION_1__NEXT_SET(x) (((x) << RDMA_REGION_1__NEXT_LSB) & RDMA_REGION_1__NEXT_MASK)
+
+#define RDMA_REGION_2__ADDRESS 0x00000028
+#define RDMA_REGION_2__OFFSET 0x00000028
+#define RDMA_REGION_2__ADDR_MSB 31
+#define RDMA_REGION_2__ADDR_LSB 13
+#define RDMA_REGION_2__ADDR_MASK 0xffffe000
+#define RDMA_REGION_2__ADDR_GET(x) (((x) & RDMA_REGION_2__ADDR_MASK) >> RDMA_REGION_2__ADDR_LSB)
+#define RDMA_REGION_2__ADDR_SET(x) (((x) << RDMA_REGION_2__ADDR_LSB) & RDMA_REGION_2__ADDR_MASK)
+#define RDMA_REGION_2__LENGTH_MSB 12
+#define RDMA_REGION_2__LENGTH_LSB 2
+#define RDMA_REGION_2__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_2__LENGTH_GET(x) (((x) & RDMA_REGION_2__LENGTH_MASK) >> RDMA_REGION_2__LENGTH_LSB)
+#define RDMA_REGION_2__LENGTH_SET(x) (((x) << RDMA_REGION_2__LENGTH_LSB) & RDMA_REGION_2__LENGTH_MASK)
+#define RDMA_REGION_2__INDI_MSB 1
+#define RDMA_REGION_2__INDI_LSB 1
+#define RDMA_REGION_2__INDI_MASK 0x00000002
+#define RDMA_REGION_2__INDI_GET(x) (((x) & RDMA_REGION_2__INDI_MASK) >> RDMA_REGION_2__INDI_LSB)
+#define RDMA_REGION_2__INDI_SET(x) (((x) << RDMA_REGION_2__INDI_LSB) & RDMA_REGION_2__INDI_MASK)
+#define RDMA_REGION_2__NEXT_MSB 0
+#define RDMA_REGION_2__NEXT_LSB 0
+#define RDMA_REGION_2__NEXT_MASK 0x00000001
+#define RDMA_REGION_2__NEXT_GET(x) (((x) & RDMA_REGION_2__NEXT_MASK) >> RDMA_REGION_2__NEXT_LSB)
+#define RDMA_REGION_2__NEXT_SET(x) (((x) << RDMA_REGION_2__NEXT_LSB) & RDMA_REGION_2__NEXT_MASK)
+
+#define RDMA_REGION_3__ADDRESS 0x0000002c
+#define RDMA_REGION_3__OFFSET 0x0000002c
+#define RDMA_REGION_3__ADDR_MSB 31
+#define RDMA_REGION_3__ADDR_LSB 13
+#define RDMA_REGION_3__ADDR_MASK 0xffffe000
+#define RDMA_REGION_3__ADDR_GET(x) (((x) & RDMA_REGION_3__ADDR_MASK) >> RDMA_REGION_3__ADDR_LSB)
+#define RDMA_REGION_3__ADDR_SET(x) (((x) << RDMA_REGION_3__ADDR_LSB) & RDMA_REGION_3__ADDR_MASK)
+#define RDMA_REGION_3__LENGTH_MSB 12
+#define RDMA_REGION_3__LENGTH_LSB 2
+#define RDMA_REGION_3__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_3__LENGTH_GET(x) (((x) & RDMA_REGION_3__LENGTH_MASK) >> RDMA_REGION_3__LENGTH_LSB)
+#define RDMA_REGION_3__LENGTH_SET(x) (((x) << RDMA_REGION_3__LENGTH_LSB) & RDMA_REGION_3__LENGTH_MASK)
+#define RDMA_REGION_3__INDI_MSB 1
+#define RDMA_REGION_3__INDI_LSB 1
+#define RDMA_REGION_3__INDI_MASK 0x00000002
+#define RDMA_REGION_3__INDI_GET(x) (((x) & RDMA_REGION_3__INDI_MASK) >> RDMA_REGION_3__INDI_LSB)
+#define RDMA_REGION_3__INDI_SET(x) (((x) << RDMA_REGION_3__INDI_LSB) & RDMA_REGION_3__INDI_MASK)
+#define RDMA_REGION_3__NEXT_MSB 0
+#define RDMA_REGION_3__NEXT_LSB 0
+#define RDMA_REGION_3__NEXT_MASK 0x00000001
+#define RDMA_REGION_3__NEXT_GET(x) (((x) & RDMA_REGION_3__NEXT_MASK) >> RDMA_REGION_3__NEXT_LSB)
+#define RDMA_REGION_3__NEXT_SET(x) (((x) << RDMA_REGION_3__NEXT_LSB) & RDMA_REGION_3__NEXT_MASK)
+
+#define RDMA_REGION_4__ADDRESS 0x00000030
+#define RDMA_REGION_4__OFFSET 0x00000030
+#define RDMA_REGION_4__ADDR_MSB 31
+#define RDMA_REGION_4__ADDR_LSB 13
+#define RDMA_REGION_4__ADDR_MASK 0xffffe000
+#define RDMA_REGION_4__ADDR_GET(x) (((x) & RDMA_REGION_4__ADDR_MASK) >> RDMA_REGION_4__ADDR_LSB)
+#define RDMA_REGION_4__ADDR_SET(x) (((x) << RDMA_REGION_4__ADDR_LSB) & RDMA_REGION_4__ADDR_MASK)
+#define RDMA_REGION_4__LENGTH_MSB 12
+#define RDMA_REGION_4__LENGTH_LSB 2
+#define RDMA_REGION_4__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_4__LENGTH_GET(x) (((x) & RDMA_REGION_4__LENGTH_MASK) >> RDMA_REGION_4__LENGTH_LSB)
+#define RDMA_REGION_4__LENGTH_SET(x) (((x) << RDMA_REGION_4__LENGTH_LSB) & RDMA_REGION_4__LENGTH_MASK)
+#define RDMA_REGION_4__INDI_MSB 1
+#define RDMA_REGION_4__INDI_LSB 1
+#define RDMA_REGION_4__INDI_MASK 0x00000002
+#define RDMA_REGION_4__INDI_GET(x) (((x) & RDMA_REGION_4__INDI_MASK) >> RDMA_REGION_4__INDI_LSB)
+#define RDMA_REGION_4__INDI_SET(x) (((x) << RDMA_REGION_4__INDI_LSB) & RDMA_REGION_4__INDI_MASK)
+#define RDMA_REGION_4__NEXT_MSB 0
+#define RDMA_REGION_4__NEXT_LSB 0
+#define RDMA_REGION_4__NEXT_MASK 0x00000001
+#define RDMA_REGION_4__NEXT_GET(x) (((x) & RDMA_REGION_4__NEXT_MASK) >> RDMA_REGION_4__NEXT_LSB)
+#define RDMA_REGION_4__NEXT_SET(x) (((x) << RDMA_REGION_4__NEXT_LSB) & RDMA_REGION_4__NEXT_MASK)
+
+#define RDMA_REGION_5__ADDRESS 0x00000034
+#define RDMA_REGION_5__OFFSET 0x00000034
+#define RDMA_REGION_5__ADDR_MSB 31
+#define RDMA_REGION_5__ADDR_LSB 13
+#define RDMA_REGION_5__ADDR_MASK 0xffffe000
+#define RDMA_REGION_5__ADDR_GET(x) (((x) & RDMA_REGION_5__ADDR_MASK) >> RDMA_REGION_5__ADDR_LSB)
+#define RDMA_REGION_5__ADDR_SET(x) (((x) << RDMA_REGION_5__ADDR_LSB) & RDMA_REGION_5__ADDR_MASK)
+#define RDMA_REGION_5__LENGTH_MSB 12
+#define RDMA_REGION_5__LENGTH_LSB 2
+#define RDMA_REGION_5__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_5__LENGTH_GET(x) (((x) & RDMA_REGION_5__LENGTH_MASK) >> RDMA_REGION_5__LENGTH_LSB)
+#define RDMA_REGION_5__LENGTH_SET(x) (((x) << RDMA_REGION_5__LENGTH_LSB) & RDMA_REGION_5__LENGTH_MASK)
+#define RDMA_REGION_5__INDI_MSB 1
+#define RDMA_REGION_5__INDI_LSB 1
+#define RDMA_REGION_5__INDI_MASK 0x00000002
+#define RDMA_REGION_5__INDI_GET(x) (((x) & RDMA_REGION_5__INDI_MASK) >> RDMA_REGION_5__INDI_LSB)
+#define RDMA_REGION_5__INDI_SET(x) (((x) << RDMA_REGION_5__INDI_LSB) & RDMA_REGION_5__INDI_MASK)
+#define RDMA_REGION_5__NEXT_MSB 0
+#define RDMA_REGION_5__NEXT_LSB 0
+#define RDMA_REGION_5__NEXT_MASK 0x00000001
+#define RDMA_REGION_5__NEXT_GET(x) (((x) & RDMA_REGION_5__NEXT_MASK) >> RDMA_REGION_5__NEXT_LSB)
+#define RDMA_REGION_5__NEXT_SET(x) (((x) << RDMA_REGION_5__NEXT_LSB) & RDMA_REGION_5__NEXT_MASK)
+
+#define RDMA_REGION_6__ADDRESS 0x00000038
+#define RDMA_REGION_6__OFFSET 0x00000038
+#define RDMA_REGION_6__ADDR_MSB 31
+#define RDMA_REGION_6__ADDR_LSB 13
+#define RDMA_REGION_6__ADDR_MASK 0xffffe000
+#define RDMA_REGION_6__ADDR_GET(x) (((x) & RDMA_REGION_6__ADDR_MASK) >> RDMA_REGION_6__ADDR_LSB)
+#define RDMA_REGION_6__ADDR_SET(x) (((x) << RDMA_REGION_6__ADDR_LSB) & RDMA_REGION_6__ADDR_MASK)
+#define RDMA_REGION_6__LENGTH_MSB 12
+#define RDMA_REGION_6__LENGTH_LSB 2
+#define RDMA_REGION_6__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_6__LENGTH_GET(x) (((x) & RDMA_REGION_6__LENGTH_MASK) >> RDMA_REGION_6__LENGTH_LSB)
+#define RDMA_REGION_6__LENGTH_SET(x) (((x) << RDMA_REGION_6__LENGTH_LSB) & RDMA_REGION_6__LENGTH_MASK)
+#define RDMA_REGION_6__INDI_MSB 1
+#define RDMA_REGION_6__INDI_LSB 1
+#define RDMA_REGION_6__INDI_MASK 0x00000002
+#define RDMA_REGION_6__INDI_GET(x) (((x) & RDMA_REGION_6__INDI_MASK) >> RDMA_REGION_6__INDI_LSB)
+#define RDMA_REGION_6__INDI_SET(x) (((x) << RDMA_REGION_6__INDI_LSB) & RDMA_REGION_6__INDI_MASK)
+#define RDMA_REGION_6__NEXT_MSB 0
+#define RDMA_REGION_6__NEXT_LSB 0
+#define RDMA_REGION_6__NEXT_MASK 0x00000001
+#define RDMA_REGION_6__NEXT_GET(x) (((x) & RDMA_REGION_6__NEXT_MASK) >> RDMA_REGION_6__NEXT_LSB)
+#define RDMA_REGION_6__NEXT_SET(x) (((x) << RDMA_REGION_6__NEXT_LSB) & RDMA_REGION_6__NEXT_MASK)
+
+#define RDMA_REGION_7__ADDRESS 0x0000003c
+#define RDMA_REGION_7__OFFSET 0x0000003c
+#define RDMA_REGION_7__ADDR_MSB 31
+#define RDMA_REGION_7__ADDR_LSB 13
+#define RDMA_REGION_7__ADDR_MASK 0xffffe000
+#define RDMA_REGION_7__ADDR_GET(x) (((x) & RDMA_REGION_7__ADDR_MASK) >> RDMA_REGION_7__ADDR_LSB)
+#define RDMA_REGION_7__ADDR_SET(x) (((x) << RDMA_REGION_7__ADDR_LSB) & RDMA_REGION_7__ADDR_MASK)
+#define RDMA_REGION_7__LENGTH_MSB 12
+#define RDMA_REGION_7__LENGTH_LSB 2
+#define RDMA_REGION_7__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_7__LENGTH_GET(x) (((x) & RDMA_REGION_7__LENGTH_MASK) >> RDMA_REGION_7__LENGTH_LSB)
+#define RDMA_REGION_7__LENGTH_SET(x) (((x) << RDMA_REGION_7__LENGTH_LSB) & RDMA_REGION_7__LENGTH_MASK)
+#define RDMA_REGION_7__INDI_MSB 1
+#define RDMA_REGION_7__INDI_LSB 1
+#define RDMA_REGION_7__INDI_MASK 0x00000002
+#define RDMA_REGION_7__INDI_GET(x) (((x) & RDMA_REGION_7__INDI_MASK) >> RDMA_REGION_7__INDI_LSB)
+#define RDMA_REGION_7__INDI_SET(x) (((x) << RDMA_REGION_7__INDI_LSB) & RDMA_REGION_7__INDI_MASK)
+#define RDMA_REGION_7__NEXT_MSB 0
+#define RDMA_REGION_7__NEXT_LSB 0
+#define RDMA_REGION_7__NEXT_MASK 0x00000001
+#define RDMA_REGION_7__NEXT_GET(x) (((x) & RDMA_REGION_7__NEXT_MASK) >> RDMA_REGION_7__NEXT_LSB)
+#define RDMA_REGION_7__NEXT_SET(x) (((x) << RDMA_REGION_7__NEXT_LSB) & RDMA_REGION_7__NEXT_MASK)
+
+#define RDMA_REGION_8__ADDRESS 0x00000040
+#define RDMA_REGION_8__OFFSET 0x00000040
+#define RDMA_REGION_8__ADDR_MSB 31
+#define RDMA_REGION_8__ADDR_LSB 13
+#define RDMA_REGION_8__ADDR_MASK 0xffffe000
+#define RDMA_REGION_8__ADDR_GET(x) (((x) & RDMA_REGION_8__ADDR_MASK) >> RDMA_REGION_8__ADDR_LSB)
+#define RDMA_REGION_8__ADDR_SET(x) (((x) << RDMA_REGION_8__ADDR_LSB) & RDMA_REGION_8__ADDR_MASK)
+#define RDMA_REGION_8__LENGTH_MSB 12
+#define RDMA_REGION_8__LENGTH_LSB 2
+#define RDMA_REGION_8__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_8__LENGTH_GET(x) (((x) & RDMA_REGION_8__LENGTH_MASK) >> RDMA_REGION_8__LENGTH_LSB)
+#define RDMA_REGION_8__LENGTH_SET(x) (((x) << RDMA_REGION_8__LENGTH_LSB) & RDMA_REGION_8__LENGTH_MASK)
+#define RDMA_REGION_8__INDI_MSB 1
+#define RDMA_REGION_8__INDI_LSB 1
+#define RDMA_REGION_8__INDI_MASK 0x00000002
+#define RDMA_REGION_8__INDI_GET(x) (((x) & RDMA_REGION_8__INDI_MASK) >> RDMA_REGION_8__INDI_LSB)
+#define RDMA_REGION_8__INDI_SET(x) (((x) << RDMA_REGION_8__INDI_LSB) & RDMA_REGION_8__INDI_MASK)
+#define RDMA_REGION_8__NEXT_MSB 0
+#define RDMA_REGION_8__NEXT_LSB 0
+#define RDMA_REGION_8__NEXT_MASK 0x00000001
+#define RDMA_REGION_8__NEXT_GET(x) (((x) & RDMA_REGION_8__NEXT_MASK) >> RDMA_REGION_8__NEXT_LSB)
+#define RDMA_REGION_8__NEXT_SET(x) (((x) << RDMA_REGION_8__NEXT_LSB) & RDMA_REGION_8__NEXT_MASK)
+
+#define RDMA_REGION_9__ADDRESS 0x00000044
+#define RDMA_REGION_9__OFFSET 0x00000044
+#define RDMA_REGION_9__ADDR_MSB 31
+#define RDMA_REGION_9__ADDR_LSB 13
+#define RDMA_REGION_9__ADDR_MASK 0xffffe000
+#define RDMA_REGION_9__ADDR_GET(x) (((x) & RDMA_REGION_9__ADDR_MASK) >> RDMA_REGION_9__ADDR_LSB)
+#define RDMA_REGION_9__ADDR_SET(x) (((x) << RDMA_REGION_9__ADDR_LSB) & RDMA_REGION_9__ADDR_MASK)
+#define RDMA_REGION_9__LENGTH_MSB 12
+#define RDMA_REGION_9__LENGTH_LSB 2
+#define RDMA_REGION_9__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_9__LENGTH_GET(x) (((x) & RDMA_REGION_9__LENGTH_MASK) >> RDMA_REGION_9__LENGTH_LSB)
+#define RDMA_REGION_9__LENGTH_SET(x) (((x) << RDMA_REGION_9__LENGTH_LSB) & RDMA_REGION_9__LENGTH_MASK)
+#define RDMA_REGION_9__INDI_MSB 1
+#define RDMA_REGION_9__INDI_LSB 1
+#define RDMA_REGION_9__INDI_MASK 0x00000002
+#define RDMA_REGION_9__INDI_GET(x) (((x) & RDMA_REGION_9__INDI_MASK) >> RDMA_REGION_9__INDI_LSB)
+#define RDMA_REGION_9__INDI_SET(x) (((x) << RDMA_REGION_9__INDI_LSB) & RDMA_REGION_9__INDI_MASK)
+#define RDMA_REGION_9__NEXT_MSB 0
+#define RDMA_REGION_9__NEXT_LSB 0
+#define RDMA_REGION_9__NEXT_MASK 0x00000001
+#define RDMA_REGION_9__NEXT_GET(x) (((x) & RDMA_REGION_9__NEXT_MASK) >> RDMA_REGION_9__NEXT_LSB)
+#define RDMA_REGION_9__NEXT_SET(x) (((x) << RDMA_REGION_9__NEXT_LSB) & RDMA_REGION_9__NEXT_MASK)
+
+#define RDMA_REGION_10__ADDRESS 0x00000048
+#define RDMA_REGION_10__OFFSET 0x00000048
+#define RDMA_REGION_10__ADDR_MSB 31
+#define RDMA_REGION_10__ADDR_LSB 13
+#define RDMA_REGION_10__ADDR_MASK 0xffffe000
+#define RDMA_REGION_10__ADDR_GET(x) (((x) & RDMA_REGION_10__ADDR_MASK) >> RDMA_REGION_10__ADDR_LSB)
+#define RDMA_REGION_10__ADDR_SET(x) (((x) << RDMA_REGION_10__ADDR_LSB) & RDMA_REGION_10__ADDR_MASK)
+#define RDMA_REGION_10__LENGTH_MSB 12
+#define RDMA_REGION_10__LENGTH_LSB 2
+#define RDMA_REGION_10__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_10__LENGTH_GET(x) (((x) & RDMA_REGION_10__LENGTH_MASK) >> RDMA_REGION_10__LENGTH_LSB)
+#define RDMA_REGION_10__LENGTH_SET(x) (((x) << RDMA_REGION_10__LENGTH_LSB) & RDMA_REGION_10__LENGTH_MASK)
+#define RDMA_REGION_10__INDI_MSB 1
+#define RDMA_REGION_10__INDI_LSB 1
+#define RDMA_REGION_10__INDI_MASK 0x00000002
+#define RDMA_REGION_10__INDI_GET(x) (((x) & RDMA_REGION_10__INDI_MASK) >> RDMA_REGION_10__INDI_LSB)
+#define RDMA_REGION_10__INDI_SET(x) (((x) << RDMA_REGION_10__INDI_LSB) & RDMA_REGION_10__INDI_MASK)
+#define RDMA_REGION_10__NEXT_MSB 0
+#define RDMA_REGION_10__NEXT_LSB 0
+#define RDMA_REGION_10__NEXT_MASK 0x00000001
+#define RDMA_REGION_10__NEXT_GET(x) (((x) & RDMA_REGION_10__NEXT_MASK) >> RDMA_REGION_10__NEXT_LSB)
+#define RDMA_REGION_10__NEXT_SET(x) (((x) << RDMA_REGION_10__NEXT_LSB) & RDMA_REGION_10__NEXT_MASK)
+
+#define RDMA_REGION_11__ADDRESS 0x0000004c
+#define RDMA_REGION_11__OFFSET 0x0000004c
+#define RDMA_REGION_11__ADDR_MSB 31
+#define RDMA_REGION_11__ADDR_LSB 13
+#define RDMA_REGION_11__ADDR_MASK 0xffffe000
+#define RDMA_REGION_11__ADDR_GET(x) (((x) & RDMA_REGION_11__ADDR_MASK) >> RDMA_REGION_11__ADDR_LSB)
+#define RDMA_REGION_11__ADDR_SET(x) (((x) << RDMA_REGION_11__ADDR_LSB) & RDMA_REGION_11__ADDR_MASK)
+#define RDMA_REGION_11__LENGTH_MSB 12
+#define RDMA_REGION_11__LENGTH_LSB 2
+#define RDMA_REGION_11__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_11__LENGTH_GET(x) (((x) & RDMA_REGION_11__LENGTH_MASK) >> RDMA_REGION_11__LENGTH_LSB)
+#define RDMA_REGION_11__LENGTH_SET(x) (((x) << RDMA_REGION_11__LENGTH_LSB) & RDMA_REGION_11__LENGTH_MASK)
+#define RDMA_REGION_11__INDI_MSB 1
+#define RDMA_REGION_11__INDI_LSB 1
+#define RDMA_REGION_11__INDI_MASK 0x00000002
+#define RDMA_REGION_11__INDI_GET(x) (((x) & RDMA_REGION_11__INDI_MASK) >> RDMA_REGION_11__INDI_LSB)
+#define RDMA_REGION_11__INDI_SET(x) (((x) << RDMA_REGION_11__INDI_LSB) & RDMA_REGION_11__INDI_MASK)
+#define RDMA_REGION_11__NEXT_MSB 0
+#define RDMA_REGION_11__NEXT_LSB 0
+#define RDMA_REGION_11__NEXT_MASK 0x00000001
+#define RDMA_REGION_11__NEXT_GET(x) (((x) & RDMA_REGION_11__NEXT_MASK) >> RDMA_REGION_11__NEXT_LSB)
+#define RDMA_REGION_11__NEXT_SET(x) (((x) << RDMA_REGION_11__NEXT_LSB) & RDMA_REGION_11__NEXT_MASK)
+
+#define RDMA_REGION_12__ADDRESS 0x00000050
+#define RDMA_REGION_12__OFFSET 0x00000050
+#define RDMA_REGION_12__ADDR_MSB 31
+#define RDMA_REGION_12__ADDR_LSB 13
+#define RDMA_REGION_12__ADDR_MASK 0xffffe000
+#define RDMA_REGION_12__ADDR_GET(x) (((x) & RDMA_REGION_12__ADDR_MASK) >> RDMA_REGION_12__ADDR_LSB)
+#define RDMA_REGION_12__ADDR_SET(x) (((x) << RDMA_REGION_12__ADDR_LSB) & RDMA_REGION_12__ADDR_MASK)
+#define RDMA_REGION_12__LENGTH_MSB 12
+#define RDMA_REGION_12__LENGTH_LSB 2
+#define RDMA_REGION_12__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_12__LENGTH_GET(x) (((x) & RDMA_REGION_12__LENGTH_MASK) >> RDMA_REGION_12__LENGTH_LSB)
+#define RDMA_REGION_12__LENGTH_SET(x) (((x) << RDMA_REGION_12__LENGTH_LSB) & RDMA_REGION_12__LENGTH_MASK)
+#define RDMA_REGION_12__INDI_MSB 1
+#define RDMA_REGION_12__INDI_LSB 1
+#define RDMA_REGION_12__INDI_MASK 0x00000002
+#define RDMA_REGION_12__INDI_GET(x) (((x) & RDMA_REGION_12__INDI_MASK) >> RDMA_REGION_12__INDI_LSB)
+#define RDMA_REGION_12__INDI_SET(x) (((x) << RDMA_REGION_12__INDI_LSB) & RDMA_REGION_12__INDI_MASK)
+#define RDMA_REGION_12__NEXT_MSB 0
+#define RDMA_REGION_12__NEXT_LSB 0
+#define RDMA_REGION_12__NEXT_MASK 0x00000001
+#define RDMA_REGION_12__NEXT_GET(x) (((x) & RDMA_REGION_12__NEXT_MASK) >> RDMA_REGION_12__NEXT_LSB)
+#define RDMA_REGION_12__NEXT_SET(x) (((x) << RDMA_REGION_12__NEXT_LSB) & RDMA_REGION_12__NEXT_MASK)
+
+#define RDMA_REGION_13__ADDRESS 0x00000054
+#define RDMA_REGION_13__OFFSET 0x00000054
+#define RDMA_REGION_13__ADDR_MSB 31
+#define RDMA_REGION_13__ADDR_LSB 13
+#define RDMA_REGION_13__ADDR_MASK 0xffffe000
+#define RDMA_REGION_13__ADDR_GET(x) (((x) & RDMA_REGION_13__ADDR_MASK) >> RDMA_REGION_13__ADDR_LSB)
+#define RDMA_REGION_13__ADDR_SET(x) (((x) << RDMA_REGION_13__ADDR_LSB) & RDMA_REGION_13__ADDR_MASK)
+#define RDMA_REGION_13__LENGTH_MSB 12
+#define RDMA_REGION_13__LENGTH_LSB 2
+#define RDMA_REGION_13__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_13__LENGTH_GET(x) (((x) & RDMA_REGION_13__LENGTH_MASK) >> RDMA_REGION_13__LENGTH_LSB)
+#define RDMA_REGION_13__LENGTH_SET(x) (((x) << RDMA_REGION_13__LENGTH_LSB) & RDMA_REGION_13__LENGTH_MASK)
+#define RDMA_REGION_13__INDI_MSB 1
+#define RDMA_REGION_13__INDI_LSB 1
+#define RDMA_REGION_13__INDI_MASK 0x00000002
+#define RDMA_REGION_13__INDI_GET(x) (((x) & RDMA_REGION_13__INDI_MASK) >> RDMA_REGION_13__INDI_LSB)
+#define RDMA_REGION_13__INDI_SET(x) (((x) << RDMA_REGION_13__INDI_LSB) & RDMA_REGION_13__INDI_MASK)
+#define RDMA_REGION_13__NEXT_MSB 0
+#define RDMA_REGION_13__NEXT_LSB 0
+#define RDMA_REGION_13__NEXT_MASK 0x00000001
+#define RDMA_REGION_13__NEXT_GET(x) (((x) & RDMA_REGION_13__NEXT_MASK) >> RDMA_REGION_13__NEXT_LSB)
+#define RDMA_REGION_13__NEXT_SET(x) (((x) << RDMA_REGION_13__NEXT_LSB) & RDMA_REGION_13__NEXT_MASK)
+
+#define RDMA_REGION_14__ADDRESS 0x00000058
+#define RDMA_REGION_14__OFFSET 0x00000058
+#define RDMA_REGION_14__ADDR_MSB 31
+#define RDMA_REGION_14__ADDR_LSB 13
+#define RDMA_REGION_14__ADDR_MASK 0xffffe000
+#define RDMA_REGION_14__ADDR_GET(x) (((x) & RDMA_REGION_14__ADDR_MASK) >> RDMA_REGION_14__ADDR_LSB)
+#define RDMA_REGION_14__ADDR_SET(x) (((x) << RDMA_REGION_14__ADDR_LSB) & RDMA_REGION_14__ADDR_MASK)
+#define RDMA_REGION_14__LENGTH_MSB 12
+#define RDMA_REGION_14__LENGTH_LSB 2
+#define RDMA_REGION_14__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_14__LENGTH_GET(x) (((x) & RDMA_REGION_14__LENGTH_MASK) >> RDMA_REGION_14__LENGTH_LSB)
+#define RDMA_REGION_14__LENGTH_SET(x) (((x) << RDMA_REGION_14__LENGTH_LSB) & RDMA_REGION_14__LENGTH_MASK)
+#define RDMA_REGION_14__INDI_MSB 1
+#define RDMA_REGION_14__INDI_LSB 1
+#define RDMA_REGION_14__INDI_MASK 0x00000002
+#define RDMA_REGION_14__INDI_GET(x) (((x) & RDMA_REGION_14__INDI_MASK) >> RDMA_REGION_14__INDI_LSB)
+#define RDMA_REGION_14__INDI_SET(x) (((x) << RDMA_REGION_14__INDI_LSB) & RDMA_REGION_14__INDI_MASK)
+#define RDMA_REGION_14__NEXT_MSB 0
+#define RDMA_REGION_14__NEXT_LSB 0
+#define RDMA_REGION_14__NEXT_MASK 0x00000001
+#define RDMA_REGION_14__NEXT_GET(x) (((x) & RDMA_REGION_14__NEXT_MASK) >> RDMA_REGION_14__NEXT_LSB)
+#define RDMA_REGION_14__NEXT_SET(x) (((x) << RDMA_REGION_14__NEXT_LSB) & RDMA_REGION_14__NEXT_MASK)
+
+#define RDMA_REGION_15__ADDRESS 0x0000005c
+#define RDMA_REGION_15__OFFSET 0x0000005c
+#define RDMA_REGION_15__ADDR_MSB 31
+#define RDMA_REGION_15__ADDR_LSB 13
+#define RDMA_REGION_15__ADDR_MASK 0xffffe000
+#define RDMA_REGION_15__ADDR_GET(x) (((x) & RDMA_REGION_15__ADDR_MASK) >> RDMA_REGION_15__ADDR_LSB)
+#define RDMA_REGION_15__ADDR_SET(x) (((x) << RDMA_REGION_15__ADDR_LSB) & RDMA_REGION_15__ADDR_MASK)
+#define RDMA_REGION_15__LENGTH_MSB 12
+#define RDMA_REGION_15__LENGTH_LSB 2
+#define RDMA_REGION_15__LENGTH_MASK 0x00001ffc
+#define RDMA_REGION_15__LENGTH_GET(x) (((x) & RDMA_REGION_15__LENGTH_MASK) >> RDMA_REGION_15__LENGTH_LSB)
+#define RDMA_REGION_15__LENGTH_SET(x) (((x) << RDMA_REGION_15__LENGTH_LSB) & RDMA_REGION_15__LENGTH_MASK)
+#define RDMA_REGION_15__INDI_MSB 1
+#define RDMA_REGION_15__INDI_LSB 1
+#define RDMA_REGION_15__INDI_MASK 0x00000002
+#define RDMA_REGION_15__INDI_GET(x) (((x) & RDMA_REGION_15__INDI_MASK) >> RDMA_REGION_15__INDI_LSB)
+#define RDMA_REGION_15__INDI_SET(x) (((x) << RDMA_REGION_15__INDI_LSB) & RDMA_REGION_15__INDI_MASK)
+#define RDMA_REGION_15__NEXT_MSB 0
+#define RDMA_REGION_15__NEXT_LSB 0
+#define RDMA_REGION_15__NEXT_MASK 0x00000001
+#define RDMA_REGION_15__NEXT_GET(x) (((x) & RDMA_REGION_15__NEXT_MASK) >> RDMA_REGION_15__NEXT_LSB)
+#define RDMA_REGION_15__NEXT_SET(x) (((x) << RDMA_REGION_15__NEXT_LSB) & RDMA_REGION_15__NEXT_MASK)
+
+#define DMA_STATUS_ADDRESS 0x00000060
+#define DMA_STATUS_OFFSET 0x00000060
+#define DMA_STATUS_ERROR_CODE_MSB 14
+#define DMA_STATUS_ERROR_CODE_LSB 4
+#define DMA_STATUS_ERROR_CODE_MASK 0x00007ff0
+#define DMA_STATUS_ERROR_CODE_GET(x) (((x) & DMA_STATUS_ERROR_CODE_MASK) >> DMA_STATUS_ERROR_CODE_LSB)
+#define DMA_STATUS_ERROR_CODE_SET(x) (((x) << DMA_STATUS_ERROR_CODE_LSB) & DMA_STATUS_ERROR_CODE_MASK)
+#define DMA_STATUS_ERROR_MSB 3
+#define DMA_STATUS_ERROR_LSB 3
+#define DMA_STATUS_ERROR_MASK 0x00000008
+#define DMA_STATUS_ERROR_GET(x) (((x) & DMA_STATUS_ERROR_MASK) >> DMA_STATUS_ERROR_LSB)
+#define DMA_STATUS_ERROR_SET(x) (((x) << DMA_STATUS_ERROR_LSB) & DMA_STATUS_ERROR_MASK)
+#define DMA_STATUS_DONE_MSB 2
+#define DMA_STATUS_DONE_LSB 2
+#define DMA_STATUS_DONE_MASK 0x00000004
+#define DMA_STATUS_DONE_GET(x) (((x) & DMA_STATUS_DONE_MASK) >> DMA_STATUS_DONE_LSB)
+#define DMA_STATUS_DONE_SET(x) (((x) << DMA_STATUS_DONE_LSB) & DMA_STATUS_DONE_MASK)
+#define DMA_STATUS_STOPPED_MSB 1
+#define DMA_STATUS_STOPPED_LSB 1
+#define DMA_STATUS_STOPPED_MASK 0x00000002
+#define DMA_STATUS_STOPPED_GET(x) (((x) & DMA_STATUS_STOPPED_MASK) >> DMA_STATUS_STOPPED_LSB)
+#define DMA_STATUS_STOPPED_SET(x) (((x) << DMA_STATUS_STOPPED_LSB) & DMA_STATUS_STOPPED_MASK)
+#define DMA_STATUS_RUNNING_MSB 0
+#define DMA_STATUS_RUNNING_LSB 0
+#define DMA_STATUS_RUNNING_MASK 0x00000001
+#define DMA_STATUS_RUNNING_GET(x) (((x) & DMA_STATUS_RUNNING_MASK) >> DMA_STATUS_RUNNING_LSB)
+#define DMA_STATUS_RUNNING_SET(x) (((x) << DMA_STATUS_RUNNING_LSB) & DMA_STATUS_RUNNING_MASK)
+
+#define DMA_INT_EN_ADDRESS 0x00000064
+#define DMA_INT_EN_OFFSET 0x00000064
+#define DMA_INT_EN_ERROR_ENA_MSB 3
+#define DMA_INT_EN_ERROR_ENA_LSB 3
+#define DMA_INT_EN_ERROR_ENA_MASK 0x00000008
+#define DMA_INT_EN_ERROR_ENA_GET(x) (((x) & DMA_INT_EN_ERROR_ENA_MASK) >> DMA_INT_EN_ERROR_ENA_LSB)
+#define DMA_INT_EN_ERROR_ENA_SET(x) (((x) << DMA_INT_EN_ERROR_ENA_LSB) & DMA_INT_EN_ERROR_ENA_MASK)
+#define DMA_INT_EN_DONE_ENA_MSB 2
+#define DMA_INT_EN_DONE_ENA_LSB 2
+#define DMA_INT_EN_DONE_ENA_MASK 0x00000004
+#define DMA_INT_EN_DONE_ENA_GET(x) (((x) & DMA_INT_EN_DONE_ENA_MASK) >> DMA_INT_EN_DONE_ENA_LSB)
+#define DMA_INT_EN_DONE_ENA_SET(x) (((x) << DMA_INT_EN_DONE_ENA_LSB) & DMA_INT_EN_DONE_ENA_MASK)
+#define DMA_INT_EN_STOPPED_ENA_MSB 1
+#define DMA_INT_EN_STOPPED_ENA_LSB 1
+#define DMA_INT_EN_STOPPED_ENA_MASK 0x00000002
+#define DMA_INT_EN_STOPPED_ENA_GET(x) (((x) & DMA_INT_EN_STOPPED_ENA_MASK) >> DMA_INT_EN_STOPPED_ENA_LSB)
+#define DMA_INT_EN_STOPPED_ENA_SET(x) (((x) << DMA_INT_EN_STOPPED_ENA_LSB) & DMA_INT_EN_STOPPED_ENA_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct rdma_reg_reg_s {
+ volatile unsigned int dma_config;
+ volatile unsigned int dma_control;
+ volatile unsigned int dma_src;
+ volatile unsigned int dma_dest;
+ volatile unsigned int dma_length;
+ volatile unsigned int vmc_base;
+ volatile unsigned int indirect_reg;
+ volatile unsigned int indirect_return;
+ volatile unsigned int rdma_region_0_;
+ volatile unsigned int rdma_region_1_;
+ volatile unsigned int rdma_region_2_;
+ volatile unsigned int rdma_region_3_;
+ volatile unsigned int rdma_region_4_;
+ volatile unsigned int rdma_region_5_;
+ volatile unsigned int rdma_region_6_;
+ volatile unsigned int rdma_region_7_;
+ volatile unsigned int rdma_region_8_;
+ volatile unsigned int rdma_region_9_;
+ volatile unsigned int rdma_region_10_;
+ volatile unsigned int rdma_region_11_;
+ volatile unsigned int rdma_region_12_;
+ volatile unsigned int rdma_region_13_;
+ volatile unsigned int rdma_region_14_;
+ volatile unsigned int rdma_region_15_;
+ volatile unsigned int dma_status;
+ volatile unsigned int dma_int_en;
+} rdma_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _RDMA_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
new file mode 100644
index 000000000000..0855de5f1400
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
@@ -0,0 +1,975 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "rtc_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS
+#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET
+#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB
+#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB
+#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK
+#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x)
+#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x)
+#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB
+#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB
+#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK
+#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x)
+#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x)
+#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB
+#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB
+#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK
+#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x)
+#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x)
+#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB
+#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB
+#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK
+#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x)
+#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x)
+#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB
+#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB
+#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK
+#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x)
+#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x)
+#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB
+#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB
+#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK
+#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x)
+#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x)
+#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB
+#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB
+#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK
+#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x)
+#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x)
+#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB
+#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB
+#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK
+#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x)
+#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x)
+#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB
+#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB
+#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK
+#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x)
+#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x)
+#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB
+#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB
+#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK
+#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x)
+#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x)
+#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB
+#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB
+#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK
+#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x)
+#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x)
+#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB
+#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB
+#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK
+#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x)
+#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x)
+#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB
+#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB
+#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK
+#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x)
+#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x)
+#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB
+#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB
+#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK
+#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x)
+#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x)
+#define XTAL_CONTROL_ADDRESS WLAN_XTAL_CONTROL_ADDRESS
+#define XTAL_CONTROL_OFFSET WLAN_XTAL_CONTROL_OFFSET
+#define XTAL_CONTROL_TCXO_MSB WLAN_XTAL_CONTROL_TCXO_MSB
+#define XTAL_CONTROL_TCXO_LSB WLAN_XTAL_CONTROL_TCXO_LSB
+#define XTAL_CONTROL_TCXO_MASK WLAN_XTAL_CONTROL_TCXO_MASK
+#define XTAL_CONTROL_TCXO_GET(x) WLAN_XTAL_CONTROL_TCXO_GET(x)
+#define XTAL_CONTROL_TCXO_SET(x) WLAN_XTAL_CONTROL_TCXO_SET(x)
+#define TCXO_DETECT_ADDRESS WLAN_TCXO_DETECT_ADDRESS
+#define TCXO_DETECT_OFFSET WLAN_TCXO_DETECT_OFFSET
+#define TCXO_DETECT_PRESENT_MSB WLAN_TCXO_DETECT_PRESENT_MSB
+#define TCXO_DETECT_PRESENT_LSB WLAN_TCXO_DETECT_PRESENT_LSB
+#define TCXO_DETECT_PRESENT_MASK WLAN_TCXO_DETECT_PRESENT_MASK
+#define TCXO_DETECT_PRESENT_GET(x) WLAN_TCXO_DETECT_PRESENT_GET(x)
+#define TCXO_DETECT_PRESENT_SET(x) WLAN_TCXO_DETECT_PRESENT_SET(x)
+#define XTAL_TEST_ADDRESS WLAN_XTAL_TEST_ADDRESS
+#define XTAL_TEST_OFFSET WLAN_XTAL_TEST_OFFSET
+#define XTAL_TEST_NOTCXODET_MSB WLAN_XTAL_TEST_NOTCXODET_MSB
+#define XTAL_TEST_NOTCXODET_LSB WLAN_XTAL_TEST_NOTCXODET_LSB
+#define XTAL_TEST_NOTCXODET_MASK WLAN_XTAL_TEST_NOTCXODET_MASK
+#define XTAL_TEST_NOTCXODET_GET(x) WLAN_XTAL_TEST_NOTCXODET_GET(x)
+#define XTAL_TEST_NOTCXODET_SET(x) WLAN_XTAL_TEST_NOTCXODET_SET(x)
+#define QUADRATURE_ADDRESS WLAN_QUADRATURE_ADDRESS
+#define QUADRATURE_OFFSET WLAN_QUADRATURE_OFFSET
+#define QUADRATURE_ADC_MSB WLAN_QUADRATURE_ADC_MSB
+#define QUADRATURE_ADC_LSB WLAN_QUADRATURE_ADC_LSB
+#define QUADRATURE_ADC_MASK WLAN_QUADRATURE_ADC_MASK
+#define QUADRATURE_ADC_GET(x) WLAN_QUADRATURE_ADC_GET(x)
+#define QUADRATURE_ADC_SET(x) WLAN_QUADRATURE_ADC_SET(x)
+#define QUADRATURE_SEL_MSB WLAN_QUADRATURE_SEL_MSB
+#define QUADRATURE_SEL_LSB WLAN_QUADRATURE_SEL_LSB
+#define QUADRATURE_SEL_MASK WLAN_QUADRATURE_SEL_MASK
+#define QUADRATURE_SEL_GET(x) WLAN_QUADRATURE_SEL_GET(x)
+#define QUADRATURE_SEL_SET(x) WLAN_QUADRATURE_SEL_SET(x)
+#define QUADRATURE_DAC_MSB WLAN_QUADRATURE_DAC_MSB
+#define QUADRATURE_DAC_LSB WLAN_QUADRATURE_DAC_LSB
+#define QUADRATURE_DAC_MASK WLAN_QUADRATURE_DAC_MASK
+#define QUADRATURE_DAC_GET(x) WLAN_QUADRATURE_DAC_GET(x)
+#define QUADRATURE_DAC_SET(x) WLAN_QUADRATURE_DAC_SET(x)
+#define PLL_CONTROL_ADDRESS WLAN_PLL_CONTROL_ADDRESS
+#define PLL_CONTROL_OFFSET WLAN_PLL_CONTROL_OFFSET
+#define PLL_CONTROL_DIG_TEST_CLK_MSB WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB
+#define PLL_CONTROL_DIG_TEST_CLK_LSB WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB
+#define PLL_CONTROL_DIG_TEST_CLK_MASK WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK
+#define PLL_CONTROL_DIG_TEST_CLK_GET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x)
+#define PLL_CONTROL_DIG_TEST_CLK_SET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x)
+#define PLL_CONTROL_MAC_OVERRIDE_MSB WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB
+#define PLL_CONTROL_MAC_OVERRIDE_LSB WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB
+#define PLL_CONTROL_MAC_OVERRIDE_MASK WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK
+#define PLL_CONTROL_MAC_OVERRIDE_GET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x)
+#define PLL_CONTROL_MAC_OVERRIDE_SET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x)
+#define PLL_CONTROL_NOPWD_MSB WLAN_PLL_CONTROL_NOPWD_MSB
+#define PLL_CONTROL_NOPWD_LSB WLAN_PLL_CONTROL_NOPWD_LSB
+#define PLL_CONTROL_NOPWD_MASK WLAN_PLL_CONTROL_NOPWD_MASK
+#define PLL_CONTROL_NOPWD_GET(x) WLAN_PLL_CONTROL_NOPWD_GET(x)
+#define PLL_CONTROL_NOPWD_SET(x) WLAN_PLL_CONTROL_NOPWD_SET(x)
+#define PLL_CONTROL_UPDATING_MSB WLAN_PLL_CONTROL_UPDATING_MSB
+#define PLL_CONTROL_UPDATING_LSB WLAN_PLL_CONTROL_UPDATING_LSB
+#define PLL_CONTROL_UPDATING_MASK WLAN_PLL_CONTROL_UPDATING_MASK
+#define PLL_CONTROL_UPDATING_GET(x) WLAN_PLL_CONTROL_UPDATING_GET(x)
+#define PLL_CONTROL_UPDATING_SET(x) WLAN_PLL_CONTROL_UPDATING_SET(x)
+#define PLL_CONTROL_BYPASS_MSB WLAN_PLL_CONTROL_BYPASS_MSB
+#define PLL_CONTROL_BYPASS_LSB WLAN_PLL_CONTROL_BYPASS_LSB
+#define PLL_CONTROL_BYPASS_MASK WLAN_PLL_CONTROL_BYPASS_MASK
+#define PLL_CONTROL_BYPASS_GET(x) WLAN_PLL_CONTROL_BYPASS_GET(x)
+#define PLL_CONTROL_BYPASS_SET(x) WLAN_PLL_CONTROL_BYPASS_SET(x)
+#define PLL_CONTROL_REFDIV_MSB WLAN_PLL_CONTROL_REFDIV_MSB
+#define PLL_CONTROL_REFDIV_LSB WLAN_PLL_CONTROL_REFDIV_LSB
+#define PLL_CONTROL_REFDIV_MASK WLAN_PLL_CONTROL_REFDIV_MASK
+#define PLL_CONTROL_REFDIV_GET(x) WLAN_PLL_CONTROL_REFDIV_GET(x)
+#define PLL_CONTROL_REFDIV_SET(x) WLAN_PLL_CONTROL_REFDIV_SET(x)
+#define PLL_CONTROL_DIV_MSB WLAN_PLL_CONTROL_DIV_MSB
+#define PLL_CONTROL_DIV_LSB WLAN_PLL_CONTROL_DIV_LSB
+#define PLL_CONTROL_DIV_MASK WLAN_PLL_CONTROL_DIV_MASK
+#define PLL_CONTROL_DIV_GET(x) WLAN_PLL_CONTROL_DIV_GET(x)
+#define PLL_CONTROL_DIV_SET(x) WLAN_PLL_CONTROL_DIV_SET(x)
+#define PLL_SETTLE_ADDRESS WLAN_PLL_SETTLE_ADDRESS
+#define PLL_SETTLE_OFFSET WLAN_PLL_SETTLE_OFFSET
+#define PLL_SETTLE_TIME_MSB WLAN_PLL_SETTLE_TIME_MSB
+#define PLL_SETTLE_TIME_LSB WLAN_PLL_SETTLE_TIME_LSB
+#define PLL_SETTLE_TIME_MASK WLAN_PLL_SETTLE_TIME_MASK
+#define PLL_SETTLE_TIME_GET(x) WLAN_PLL_SETTLE_TIME_GET(x)
+#define PLL_SETTLE_TIME_SET(x) WLAN_PLL_SETTLE_TIME_SET(x)
+#define XTAL_SETTLE_ADDRESS WLAN_XTAL_SETTLE_ADDRESS
+#define XTAL_SETTLE_OFFSET WLAN_XTAL_SETTLE_OFFSET
+#define XTAL_SETTLE_TIME_MSB WLAN_XTAL_SETTLE_TIME_MSB
+#define XTAL_SETTLE_TIME_LSB WLAN_XTAL_SETTLE_TIME_LSB
+#define XTAL_SETTLE_TIME_MASK WLAN_XTAL_SETTLE_TIME_MASK
+#define XTAL_SETTLE_TIME_GET(x) WLAN_XTAL_SETTLE_TIME_GET(x)
+#define XTAL_SETTLE_TIME_SET(x) WLAN_XTAL_SETTLE_TIME_SET(x)
+#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS
+#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET
+#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB
+#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB
+#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK
+#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x)
+#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x)
+#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS
+#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET
+#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB
+#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB
+#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK
+#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x)
+#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x)
+#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS
+#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET
+#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB
+#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB
+#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK
+#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x)
+#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x)
+#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB
+#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB
+#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK
+#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)
+#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)
+#define BIAS_OVERRIDE_ADDRESS WLAN_BIAS_OVERRIDE_ADDRESS
+#define BIAS_OVERRIDE_OFFSET WLAN_BIAS_OVERRIDE_OFFSET
+#define BIAS_OVERRIDE_ON_MSB WLAN_BIAS_OVERRIDE_ON_MSB
+#define BIAS_OVERRIDE_ON_LSB WLAN_BIAS_OVERRIDE_ON_LSB
+#define BIAS_OVERRIDE_ON_MASK WLAN_BIAS_OVERRIDE_ON_MASK
+#define BIAS_OVERRIDE_ON_GET(x) WLAN_BIAS_OVERRIDE_ON_GET(x)
+#define BIAS_OVERRIDE_ON_SET(x) WLAN_BIAS_OVERRIDE_ON_SET(x)
+#define WDT_CONTROL_ADDRESS WLAN_WDT_CONTROL_ADDRESS
+#define WDT_CONTROL_OFFSET WLAN_WDT_CONTROL_OFFSET
+#define WDT_CONTROL_ACTION_MSB WLAN_WDT_CONTROL_ACTION_MSB
+#define WDT_CONTROL_ACTION_LSB WLAN_WDT_CONTROL_ACTION_LSB
+#define WDT_CONTROL_ACTION_MASK WLAN_WDT_CONTROL_ACTION_MASK
+#define WDT_CONTROL_ACTION_GET(x) WLAN_WDT_CONTROL_ACTION_GET(x)
+#define WDT_CONTROL_ACTION_SET(x) WLAN_WDT_CONTROL_ACTION_SET(x)
+#define WDT_STATUS_ADDRESS WLAN_WDT_STATUS_ADDRESS
+#define WDT_STATUS_OFFSET WLAN_WDT_STATUS_OFFSET
+#define WDT_STATUS_INTERRUPT_MSB WLAN_WDT_STATUS_INTERRUPT_MSB
+#define WDT_STATUS_INTERRUPT_LSB WLAN_WDT_STATUS_INTERRUPT_LSB
+#define WDT_STATUS_INTERRUPT_MASK WLAN_WDT_STATUS_INTERRUPT_MASK
+#define WDT_STATUS_INTERRUPT_GET(x) WLAN_WDT_STATUS_INTERRUPT_GET(x)
+#define WDT_STATUS_INTERRUPT_SET(x) WLAN_WDT_STATUS_INTERRUPT_SET(x)
+#define WDT_ADDRESS WLAN_WDT_ADDRESS
+#define WDT_OFFSET WLAN_WDT_OFFSET
+#define WDT_TARGET_MSB WLAN_WDT_TARGET_MSB
+#define WDT_TARGET_LSB WLAN_WDT_TARGET_LSB
+#define WDT_TARGET_MASK WLAN_WDT_TARGET_MASK
+#define WDT_TARGET_GET(x) WLAN_WDT_TARGET_GET(x)
+#define WDT_TARGET_SET(x) WLAN_WDT_TARGET_SET(x)
+#define WDT_COUNT_ADDRESS WLAN_WDT_COUNT_ADDRESS
+#define WDT_COUNT_OFFSET WLAN_WDT_COUNT_OFFSET
+#define WDT_COUNT_VALUE_MSB WLAN_WDT_COUNT_VALUE_MSB
+#define WDT_COUNT_VALUE_LSB WLAN_WDT_COUNT_VALUE_LSB
+#define WDT_COUNT_VALUE_MASK WLAN_WDT_COUNT_VALUE_MASK
+#define WDT_COUNT_VALUE_GET(x) WLAN_WDT_COUNT_VALUE_GET(x)
+#define WDT_COUNT_VALUE_SET(x) WLAN_WDT_COUNT_VALUE_SET(x)
+#define WDT_RESET_ADDRESS WLAN_WDT_RESET_ADDRESS
+#define WDT_RESET_OFFSET WLAN_WDT_RESET_OFFSET
+#define WDT_RESET_VALUE_MSB WLAN_WDT_RESET_VALUE_MSB
+#define WDT_RESET_VALUE_LSB WLAN_WDT_RESET_VALUE_LSB
+#define WDT_RESET_VALUE_MASK WLAN_WDT_RESET_VALUE_MASK
+#define WDT_RESET_VALUE_GET(x) WLAN_WDT_RESET_VALUE_GET(x)
+#define WDT_RESET_VALUE_SET(x) WLAN_WDT_RESET_VALUE_SET(x)
+#define INT_STATUS_ADDRESS WLAN_INT_STATUS_ADDRESS
+#define INT_STATUS_OFFSET WLAN_INT_STATUS_OFFSET
+#define INT_STATUS_HCI_UART_MSB WLAN_INT_STATUS_HCI_UART_MSB
+#define INT_STATUS_HCI_UART_LSB WLAN_INT_STATUS_HCI_UART_LSB
+#define INT_STATUS_HCI_UART_MASK WLAN_INT_STATUS_HCI_UART_MASK
+#define INT_STATUS_HCI_UART_GET(x) WLAN_INT_STATUS_HCI_UART_GET(x)
+#define INT_STATUS_HCI_UART_SET(x) WLAN_INT_STATUS_HCI_UART_SET(x)
+#define INT_STATUS_THERM_MSB WLAN_INT_STATUS_THERM_MSB
+#define INT_STATUS_THERM_LSB WLAN_INT_STATUS_THERM_LSB
+#define INT_STATUS_THERM_MASK WLAN_INT_STATUS_THERM_MASK
+#define INT_STATUS_THERM_GET(x) WLAN_INT_STATUS_THERM_GET(x)
+#define INT_STATUS_THERM_SET(x) WLAN_INT_STATUS_THERM_SET(x)
+#define INT_STATUS_EFUSE_OVERWRITE_MSB WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB
+#define INT_STATUS_EFUSE_OVERWRITE_LSB WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB
+#define INT_STATUS_EFUSE_OVERWRITE_MASK WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK
+#define INT_STATUS_EFUSE_OVERWRITE_GET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x)
+#define INT_STATUS_EFUSE_OVERWRITE_SET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x)
+#define INT_STATUS_UART_MBOX_MSB WLAN_INT_STATUS_UART_MBOX_MSB
+#define INT_STATUS_UART_MBOX_LSB WLAN_INT_STATUS_UART_MBOX_LSB
+#define INT_STATUS_UART_MBOX_MASK WLAN_INT_STATUS_UART_MBOX_MASK
+#define INT_STATUS_UART_MBOX_GET(x) WLAN_INT_STATUS_UART_MBOX_GET(x)
+#define INT_STATUS_UART_MBOX_SET(x) WLAN_INT_STATUS_UART_MBOX_SET(x)
+#define INT_STATUS_GENERIC_MBOX_MSB WLAN_INT_STATUS_GENERIC_MBOX_MSB
+#define INT_STATUS_GENERIC_MBOX_LSB WLAN_INT_STATUS_GENERIC_MBOX_LSB
+#define INT_STATUS_GENERIC_MBOX_MASK WLAN_INT_STATUS_GENERIC_MBOX_MASK
+#define INT_STATUS_GENERIC_MBOX_GET(x) WLAN_INT_STATUS_GENERIC_MBOX_GET(x)
+#define INT_STATUS_GENERIC_MBOX_SET(x) WLAN_INT_STATUS_GENERIC_MBOX_SET(x)
+#define INT_STATUS_RDMA_MSB WLAN_INT_STATUS_RDMA_MSB
+#define INT_STATUS_RDMA_LSB WLAN_INT_STATUS_RDMA_LSB
+#define INT_STATUS_RDMA_MASK WLAN_INT_STATUS_RDMA_MASK
+#define INT_STATUS_RDMA_GET(x) WLAN_INT_STATUS_RDMA_GET(x)
+#define INT_STATUS_RDMA_SET(x) WLAN_INT_STATUS_RDMA_SET(x)
+#define INT_STATUS_BTCOEX_MSB WLAN_INT_STATUS_BTCOEX_MSB
+#define INT_STATUS_BTCOEX_LSB WLAN_INT_STATUS_BTCOEX_LSB
+#define INT_STATUS_BTCOEX_MASK WLAN_INT_STATUS_BTCOEX_MASK
+#define INT_STATUS_BTCOEX_GET(x) WLAN_INT_STATUS_BTCOEX_GET(x)
+#define INT_STATUS_BTCOEX_SET(x) WLAN_INT_STATUS_BTCOEX_SET(x)
+#define INT_STATUS_RTC_POWER_MSB WLAN_INT_STATUS_RTC_POWER_MSB
+#define INT_STATUS_RTC_POWER_LSB WLAN_INT_STATUS_RTC_POWER_LSB
+#define INT_STATUS_RTC_POWER_MASK WLAN_INT_STATUS_RTC_POWER_MASK
+#define INT_STATUS_RTC_POWER_GET(x) WLAN_INT_STATUS_RTC_POWER_GET(x)
+#define INT_STATUS_RTC_POWER_SET(x) WLAN_INT_STATUS_RTC_POWER_SET(x)
+#define INT_STATUS_MAC_MSB WLAN_INT_STATUS_MAC_MSB
+#define INT_STATUS_MAC_LSB WLAN_INT_STATUS_MAC_LSB
+#define INT_STATUS_MAC_MASK WLAN_INT_STATUS_MAC_MASK
+#define INT_STATUS_MAC_GET(x) WLAN_INT_STATUS_MAC_GET(x)
+#define INT_STATUS_MAC_SET(x) WLAN_INT_STATUS_MAC_SET(x)
+#define INT_STATUS_MAILBOX_MSB WLAN_INT_STATUS_MAILBOX_MSB
+#define INT_STATUS_MAILBOX_LSB WLAN_INT_STATUS_MAILBOX_LSB
+#define INT_STATUS_MAILBOX_MASK WLAN_INT_STATUS_MAILBOX_MASK
+#define INT_STATUS_MAILBOX_GET(x) WLAN_INT_STATUS_MAILBOX_GET(x)
+#define INT_STATUS_MAILBOX_SET(x) WLAN_INT_STATUS_MAILBOX_SET(x)
+#define INT_STATUS_RTC_ALARM_MSB WLAN_INT_STATUS_RTC_ALARM_MSB
+#define INT_STATUS_RTC_ALARM_LSB WLAN_INT_STATUS_RTC_ALARM_LSB
+#define INT_STATUS_RTC_ALARM_MASK WLAN_INT_STATUS_RTC_ALARM_MASK
+#define INT_STATUS_RTC_ALARM_GET(x) WLAN_INT_STATUS_RTC_ALARM_GET(x)
+#define INT_STATUS_RTC_ALARM_SET(x) WLAN_INT_STATUS_RTC_ALARM_SET(x)
+#define INT_STATUS_HF_TIMER_MSB WLAN_INT_STATUS_HF_TIMER_MSB
+#define INT_STATUS_HF_TIMER_LSB WLAN_INT_STATUS_HF_TIMER_LSB
+#define INT_STATUS_HF_TIMER_MASK WLAN_INT_STATUS_HF_TIMER_MASK
+#define INT_STATUS_HF_TIMER_GET(x) WLAN_INT_STATUS_HF_TIMER_GET(x)
+#define INT_STATUS_HF_TIMER_SET(x) WLAN_INT_STATUS_HF_TIMER_SET(x)
+#define INT_STATUS_LF_TIMER3_MSB WLAN_INT_STATUS_LF_TIMER3_MSB
+#define INT_STATUS_LF_TIMER3_LSB WLAN_INT_STATUS_LF_TIMER3_LSB
+#define INT_STATUS_LF_TIMER3_MASK WLAN_INT_STATUS_LF_TIMER3_MASK
+#define INT_STATUS_LF_TIMER3_GET(x) WLAN_INT_STATUS_LF_TIMER3_GET(x)
+#define INT_STATUS_LF_TIMER3_SET(x) WLAN_INT_STATUS_LF_TIMER3_SET(x)
+#define INT_STATUS_LF_TIMER2_MSB WLAN_INT_STATUS_LF_TIMER2_MSB
+#define INT_STATUS_LF_TIMER2_LSB WLAN_INT_STATUS_LF_TIMER2_LSB
+#define INT_STATUS_LF_TIMER2_MASK WLAN_INT_STATUS_LF_TIMER2_MASK
+#define INT_STATUS_LF_TIMER2_GET(x) WLAN_INT_STATUS_LF_TIMER2_GET(x)
+#define INT_STATUS_LF_TIMER2_SET(x) WLAN_INT_STATUS_LF_TIMER2_SET(x)
+#define INT_STATUS_LF_TIMER1_MSB WLAN_INT_STATUS_LF_TIMER1_MSB
+#define INT_STATUS_LF_TIMER1_LSB WLAN_INT_STATUS_LF_TIMER1_LSB
+#define INT_STATUS_LF_TIMER1_MASK WLAN_INT_STATUS_LF_TIMER1_MASK
+#define INT_STATUS_LF_TIMER1_GET(x) WLAN_INT_STATUS_LF_TIMER1_GET(x)
+#define INT_STATUS_LF_TIMER1_SET(x) WLAN_INT_STATUS_LF_TIMER1_SET(x)
+#define INT_STATUS_LF_TIMER0_MSB WLAN_INT_STATUS_LF_TIMER0_MSB
+#define INT_STATUS_LF_TIMER0_LSB WLAN_INT_STATUS_LF_TIMER0_LSB
+#define INT_STATUS_LF_TIMER0_MASK WLAN_INT_STATUS_LF_TIMER0_MASK
+#define INT_STATUS_LF_TIMER0_GET(x) WLAN_INT_STATUS_LF_TIMER0_GET(x)
+#define INT_STATUS_LF_TIMER0_SET(x) WLAN_INT_STATUS_LF_TIMER0_SET(x)
+#define INT_STATUS_KEYPAD_MSB WLAN_INT_STATUS_KEYPAD_MSB
+#define INT_STATUS_KEYPAD_LSB WLAN_INT_STATUS_KEYPAD_LSB
+#define INT_STATUS_KEYPAD_MASK WLAN_INT_STATUS_KEYPAD_MASK
+#define INT_STATUS_KEYPAD_GET(x) WLAN_INT_STATUS_KEYPAD_GET(x)
+#define INT_STATUS_KEYPAD_SET(x) WLAN_INT_STATUS_KEYPAD_SET(x)
+#define INT_STATUS_SI_MSB WLAN_INT_STATUS_SI_MSB
+#define INT_STATUS_SI_LSB WLAN_INT_STATUS_SI_LSB
+#define INT_STATUS_SI_MASK WLAN_INT_STATUS_SI_MASK
+#define INT_STATUS_SI_GET(x) WLAN_INT_STATUS_SI_GET(x)
+#define INT_STATUS_SI_SET(x) WLAN_INT_STATUS_SI_SET(x)
+#define INT_STATUS_GPIO_MSB WLAN_INT_STATUS_GPIO_MSB
+#define INT_STATUS_GPIO_LSB WLAN_INT_STATUS_GPIO_LSB
+#define INT_STATUS_GPIO_MASK WLAN_INT_STATUS_GPIO_MASK
+#define INT_STATUS_GPIO_GET(x) WLAN_INT_STATUS_GPIO_GET(x)
+#define INT_STATUS_GPIO_SET(x) WLAN_INT_STATUS_GPIO_SET(x)
+#define INT_STATUS_UART_MSB WLAN_INT_STATUS_UART_MSB
+#define INT_STATUS_UART_LSB WLAN_INT_STATUS_UART_LSB
+#define INT_STATUS_UART_MASK WLAN_INT_STATUS_UART_MASK
+#define INT_STATUS_UART_GET(x) WLAN_INT_STATUS_UART_GET(x)
+#define INT_STATUS_UART_SET(x) WLAN_INT_STATUS_UART_SET(x)
+#define INT_STATUS_ERROR_MSB WLAN_INT_STATUS_ERROR_MSB
+#define INT_STATUS_ERROR_LSB WLAN_INT_STATUS_ERROR_LSB
+#define INT_STATUS_ERROR_MASK WLAN_INT_STATUS_ERROR_MASK
+#define INT_STATUS_ERROR_GET(x) WLAN_INT_STATUS_ERROR_GET(x)
+#define INT_STATUS_ERROR_SET(x) WLAN_INT_STATUS_ERROR_SET(x)
+#define INT_STATUS_WDT_INT_MSB WLAN_INT_STATUS_WDT_INT_MSB
+#define INT_STATUS_WDT_INT_LSB WLAN_INT_STATUS_WDT_INT_LSB
+#define INT_STATUS_WDT_INT_MASK WLAN_INT_STATUS_WDT_INT_MASK
+#define INT_STATUS_WDT_INT_GET(x) WLAN_INT_STATUS_WDT_INT_GET(x)
+#define INT_STATUS_WDT_INT_SET(x) WLAN_INT_STATUS_WDT_INT_SET(x)
+#define LF_TIMER0_ADDRESS WLAN_LF_TIMER0_ADDRESS
+#define LF_TIMER0_OFFSET WLAN_LF_TIMER0_OFFSET
+#define LF_TIMER0_TARGET_MSB WLAN_LF_TIMER0_TARGET_MSB
+#define LF_TIMER0_TARGET_LSB WLAN_LF_TIMER0_TARGET_LSB
+#define LF_TIMER0_TARGET_MASK WLAN_LF_TIMER0_TARGET_MASK
+#define LF_TIMER0_TARGET_GET(x) WLAN_LF_TIMER0_TARGET_GET(x)
+#define LF_TIMER0_TARGET_SET(x) WLAN_LF_TIMER0_TARGET_SET(x)
+#define LF_TIMER_COUNT0_ADDRESS WLAN_LF_TIMER_COUNT0_ADDRESS
+#define LF_TIMER_COUNT0_OFFSET WLAN_LF_TIMER_COUNT0_OFFSET
+#define LF_TIMER_COUNT0_VALUE_MSB WLAN_LF_TIMER_COUNT0_VALUE_MSB
+#define LF_TIMER_COUNT0_VALUE_LSB WLAN_LF_TIMER_COUNT0_VALUE_LSB
+#define LF_TIMER_COUNT0_VALUE_MASK WLAN_LF_TIMER_COUNT0_VALUE_MASK
+#define LF_TIMER_COUNT0_VALUE_GET(x) WLAN_LF_TIMER_COUNT0_VALUE_GET(x)
+#define LF_TIMER_COUNT0_VALUE_SET(x) WLAN_LF_TIMER_COUNT0_VALUE_SET(x)
+#define LF_TIMER_CONTROL0_ADDRESS WLAN_LF_TIMER_CONTROL0_ADDRESS
+#define LF_TIMER_CONTROL0_OFFSET WLAN_LF_TIMER_CONTROL0_OFFSET
+#define LF_TIMER_CONTROL0_ENABLE_MSB WLAN_LF_TIMER_CONTROL0_ENABLE_MSB
+#define LF_TIMER_CONTROL0_ENABLE_LSB WLAN_LF_TIMER_CONTROL0_ENABLE_LSB
+#define LF_TIMER_CONTROL0_ENABLE_MASK WLAN_LF_TIMER_CONTROL0_ENABLE_MASK
+#define LF_TIMER_CONTROL0_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x)
+#define LF_TIMER_CONTROL0_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB
+#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK
+#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x)
+#define LF_TIMER_CONTROL0_RESET_MSB WLAN_LF_TIMER_CONTROL0_RESET_MSB
+#define LF_TIMER_CONTROL0_RESET_LSB WLAN_LF_TIMER_CONTROL0_RESET_LSB
+#define LF_TIMER_CONTROL0_RESET_MASK WLAN_LF_TIMER_CONTROL0_RESET_MASK
+#define LF_TIMER_CONTROL0_RESET_GET(x) WLAN_LF_TIMER_CONTROL0_RESET_GET(x)
+#define LF_TIMER_CONTROL0_RESET_SET(x) WLAN_LF_TIMER_CONTROL0_RESET_SET(x)
+#define LF_TIMER_STATUS0_ADDRESS WLAN_LF_TIMER_STATUS0_ADDRESS
+#define LF_TIMER_STATUS0_OFFSET WLAN_LF_TIMER_STATUS0_OFFSET
+#define LF_TIMER_STATUS0_INTERRUPT_MSB WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB
+#define LF_TIMER_STATUS0_INTERRUPT_LSB WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB
+#define LF_TIMER_STATUS0_INTERRUPT_MASK WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK
+#define LF_TIMER_STATUS0_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x)
+#define LF_TIMER_STATUS0_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x)
+#define LF_TIMER1_ADDRESS WLAN_LF_TIMER1_ADDRESS
+#define LF_TIMER1_OFFSET WLAN_LF_TIMER1_OFFSET
+#define LF_TIMER1_TARGET_MSB WLAN_LF_TIMER1_TARGET_MSB
+#define LF_TIMER1_TARGET_LSB WLAN_LF_TIMER1_TARGET_LSB
+#define LF_TIMER1_TARGET_MASK WLAN_LF_TIMER1_TARGET_MASK
+#define LF_TIMER1_TARGET_GET(x) WLAN_LF_TIMER1_TARGET_GET(x)
+#define LF_TIMER1_TARGET_SET(x) WLAN_LF_TIMER1_TARGET_SET(x)
+#define LF_TIMER_COUNT1_ADDRESS WLAN_LF_TIMER_COUNT1_ADDRESS
+#define LF_TIMER_COUNT1_OFFSET WLAN_LF_TIMER_COUNT1_OFFSET
+#define LF_TIMER_COUNT1_VALUE_MSB WLAN_LF_TIMER_COUNT1_VALUE_MSB
+#define LF_TIMER_COUNT1_VALUE_LSB WLAN_LF_TIMER_COUNT1_VALUE_LSB
+#define LF_TIMER_COUNT1_VALUE_MASK WLAN_LF_TIMER_COUNT1_VALUE_MASK
+#define LF_TIMER_COUNT1_VALUE_GET(x) WLAN_LF_TIMER_COUNT1_VALUE_GET(x)
+#define LF_TIMER_COUNT1_VALUE_SET(x) WLAN_LF_TIMER_COUNT1_VALUE_SET(x)
+#define LF_TIMER_CONTROL1_ADDRESS WLAN_LF_TIMER_CONTROL1_ADDRESS
+#define LF_TIMER_CONTROL1_OFFSET WLAN_LF_TIMER_CONTROL1_OFFSET
+#define LF_TIMER_CONTROL1_ENABLE_MSB WLAN_LF_TIMER_CONTROL1_ENABLE_MSB
+#define LF_TIMER_CONTROL1_ENABLE_LSB WLAN_LF_TIMER_CONTROL1_ENABLE_LSB
+#define LF_TIMER_CONTROL1_ENABLE_MASK WLAN_LF_TIMER_CONTROL1_ENABLE_MASK
+#define LF_TIMER_CONTROL1_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x)
+#define LF_TIMER_CONTROL1_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB
+#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK
+#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x)
+#define LF_TIMER_CONTROL1_RESET_MSB WLAN_LF_TIMER_CONTROL1_RESET_MSB
+#define LF_TIMER_CONTROL1_RESET_LSB WLAN_LF_TIMER_CONTROL1_RESET_LSB
+#define LF_TIMER_CONTROL1_RESET_MASK WLAN_LF_TIMER_CONTROL1_RESET_MASK
+#define LF_TIMER_CONTROL1_RESET_GET(x) WLAN_LF_TIMER_CONTROL1_RESET_GET(x)
+#define LF_TIMER_CONTROL1_RESET_SET(x) WLAN_LF_TIMER_CONTROL1_RESET_SET(x)
+#define LF_TIMER_STATUS1_ADDRESS WLAN_LF_TIMER_STATUS1_ADDRESS
+#define LF_TIMER_STATUS1_OFFSET WLAN_LF_TIMER_STATUS1_OFFSET
+#define LF_TIMER_STATUS1_INTERRUPT_MSB WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB
+#define LF_TIMER_STATUS1_INTERRUPT_LSB WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB
+#define LF_TIMER_STATUS1_INTERRUPT_MASK WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK
+#define LF_TIMER_STATUS1_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x)
+#define LF_TIMER_STATUS1_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x)
+#define LF_TIMER2_ADDRESS WLAN_LF_TIMER2_ADDRESS
+#define LF_TIMER2_OFFSET WLAN_LF_TIMER2_OFFSET
+#define LF_TIMER2_TARGET_MSB WLAN_LF_TIMER2_TARGET_MSB
+#define LF_TIMER2_TARGET_LSB WLAN_LF_TIMER2_TARGET_LSB
+#define LF_TIMER2_TARGET_MASK WLAN_LF_TIMER2_TARGET_MASK
+#define LF_TIMER2_TARGET_GET(x) WLAN_LF_TIMER2_TARGET_GET(x)
+#define LF_TIMER2_TARGET_SET(x) WLAN_LF_TIMER2_TARGET_SET(x)
+#define LF_TIMER_COUNT2_ADDRESS WLAN_LF_TIMER_COUNT2_ADDRESS
+#define LF_TIMER_COUNT2_OFFSET WLAN_LF_TIMER_COUNT2_OFFSET
+#define LF_TIMER_COUNT2_VALUE_MSB WLAN_LF_TIMER_COUNT2_VALUE_MSB
+#define LF_TIMER_COUNT2_VALUE_LSB WLAN_LF_TIMER_COUNT2_VALUE_LSB
+#define LF_TIMER_COUNT2_VALUE_MASK WLAN_LF_TIMER_COUNT2_VALUE_MASK
+#define LF_TIMER_COUNT2_VALUE_GET(x) WLAN_LF_TIMER_COUNT2_VALUE_GET(x)
+#define LF_TIMER_COUNT2_VALUE_SET(x) WLAN_LF_TIMER_COUNT2_VALUE_SET(x)
+#define LF_TIMER_CONTROL2_ADDRESS WLAN_LF_TIMER_CONTROL2_ADDRESS
+#define LF_TIMER_CONTROL2_OFFSET WLAN_LF_TIMER_CONTROL2_OFFSET
+#define LF_TIMER_CONTROL2_ENABLE_MSB WLAN_LF_TIMER_CONTROL2_ENABLE_MSB
+#define LF_TIMER_CONTROL2_ENABLE_LSB WLAN_LF_TIMER_CONTROL2_ENABLE_LSB
+#define LF_TIMER_CONTROL2_ENABLE_MASK WLAN_LF_TIMER_CONTROL2_ENABLE_MASK
+#define LF_TIMER_CONTROL2_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x)
+#define LF_TIMER_CONTROL2_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB
+#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK
+#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x)
+#define LF_TIMER_CONTROL2_RESET_MSB WLAN_LF_TIMER_CONTROL2_RESET_MSB
+#define LF_TIMER_CONTROL2_RESET_LSB WLAN_LF_TIMER_CONTROL2_RESET_LSB
+#define LF_TIMER_CONTROL2_RESET_MASK WLAN_LF_TIMER_CONTROL2_RESET_MASK
+#define LF_TIMER_CONTROL2_RESET_GET(x) WLAN_LF_TIMER_CONTROL2_RESET_GET(x)
+#define LF_TIMER_CONTROL2_RESET_SET(x) WLAN_LF_TIMER_CONTROL2_RESET_SET(x)
+#define LF_TIMER_STATUS2_ADDRESS WLAN_LF_TIMER_STATUS2_ADDRESS
+#define LF_TIMER_STATUS2_OFFSET WLAN_LF_TIMER_STATUS2_OFFSET
+#define LF_TIMER_STATUS2_INTERRUPT_MSB WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB
+#define LF_TIMER_STATUS2_INTERRUPT_LSB WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB
+#define LF_TIMER_STATUS2_INTERRUPT_MASK WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK
+#define LF_TIMER_STATUS2_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x)
+#define LF_TIMER_STATUS2_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x)
+#define LF_TIMER3_ADDRESS WLAN_LF_TIMER3_ADDRESS
+#define LF_TIMER3_OFFSET WLAN_LF_TIMER3_OFFSET
+#define LF_TIMER3_TARGET_MSB WLAN_LF_TIMER3_TARGET_MSB
+#define LF_TIMER3_TARGET_LSB WLAN_LF_TIMER3_TARGET_LSB
+#define LF_TIMER3_TARGET_MASK WLAN_LF_TIMER3_TARGET_MASK
+#define LF_TIMER3_TARGET_GET(x) WLAN_LF_TIMER3_TARGET_GET(x)
+#define LF_TIMER3_TARGET_SET(x) WLAN_LF_TIMER3_TARGET_SET(x)
+#define LF_TIMER_COUNT3_ADDRESS WLAN_LF_TIMER_COUNT3_ADDRESS
+#define LF_TIMER_COUNT3_OFFSET WLAN_LF_TIMER_COUNT3_OFFSET
+#define LF_TIMER_COUNT3_VALUE_MSB WLAN_LF_TIMER_COUNT3_VALUE_MSB
+#define LF_TIMER_COUNT3_VALUE_LSB WLAN_LF_TIMER_COUNT3_VALUE_LSB
+#define LF_TIMER_COUNT3_VALUE_MASK WLAN_LF_TIMER_COUNT3_VALUE_MASK
+#define LF_TIMER_COUNT3_VALUE_GET(x) WLAN_LF_TIMER_COUNT3_VALUE_GET(x)
+#define LF_TIMER_COUNT3_VALUE_SET(x) WLAN_LF_TIMER_COUNT3_VALUE_SET(x)
+#define LF_TIMER_CONTROL3_ADDRESS WLAN_LF_TIMER_CONTROL3_ADDRESS
+#define LF_TIMER_CONTROL3_OFFSET WLAN_LF_TIMER_CONTROL3_OFFSET
+#define LF_TIMER_CONTROL3_ENABLE_MSB WLAN_LF_TIMER_CONTROL3_ENABLE_MSB
+#define LF_TIMER_CONTROL3_ENABLE_LSB WLAN_LF_TIMER_CONTROL3_ENABLE_LSB
+#define LF_TIMER_CONTROL3_ENABLE_MASK WLAN_LF_TIMER_CONTROL3_ENABLE_MASK
+#define LF_TIMER_CONTROL3_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x)
+#define LF_TIMER_CONTROL3_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB
+#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK
+#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x)
+#define LF_TIMER_CONTROL3_RESET_MSB WLAN_LF_TIMER_CONTROL3_RESET_MSB
+#define LF_TIMER_CONTROL3_RESET_LSB WLAN_LF_TIMER_CONTROL3_RESET_LSB
+#define LF_TIMER_CONTROL3_RESET_MASK WLAN_LF_TIMER_CONTROL3_RESET_MASK
+#define LF_TIMER_CONTROL3_RESET_GET(x) WLAN_LF_TIMER_CONTROL3_RESET_GET(x)
+#define LF_TIMER_CONTROL3_RESET_SET(x) WLAN_LF_TIMER_CONTROL3_RESET_SET(x)
+#define LF_TIMER_STATUS3_ADDRESS WLAN_LF_TIMER_STATUS3_ADDRESS
+#define LF_TIMER_STATUS3_OFFSET WLAN_LF_TIMER_STATUS3_OFFSET
+#define LF_TIMER_STATUS3_INTERRUPT_MSB WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB
+#define LF_TIMER_STATUS3_INTERRUPT_LSB WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB
+#define LF_TIMER_STATUS3_INTERRUPT_MASK WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK
+#define LF_TIMER_STATUS3_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x)
+#define LF_TIMER_STATUS3_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x)
+#define HF_TIMER_ADDRESS WLAN_HF_TIMER_ADDRESS
+#define HF_TIMER_OFFSET WLAN_HF_TIMER_OFFSET
+#define HF_TIMER_TARGET_MSB WLAN_HF_TIMER_TARGET_MSB
+#define HF_TIMER_TARGET_LSB WLAN_HF_TIMER_TARGET_LSB
+#define HF_TIMER_TARGET_MASK WLAN_HF_TIMER_TARGET_MASK
+#define HF_TIMER_TARGET_GET(x) WLAN_HF_TIMER_TARGET_GET(x)
+#define HF_TIMER_TARGET_SET(x) WLAN_HF_TIMER_TARGET_SET(x)
+#define HF_TIMER_COUNT_ADDRESS WLAN_HF_TIMER_COUNT_ADDRESS
+#define HF_TIMER_COUNT_OFFSET WLAN_HF_TIMER_COUNT_OFFSET
+#define HF_TIMER_COUNT_VALUE_MSB WLAN_HF_TIMER_COUNT_VALUE_MSB
+#define HF_TIMER_COUNT_VALUE_LSB WLAN_HF_TIMER_COUNT_VALUE_LSB
+#define HF_TIMER_COUNT_VALUE_MASK WLAN_HF_TIMER_COUNT_VALUE_MASK
+#define HF_TIMER_COUNT_VALUE_GET(x) WLAN_HF_TIMER_COUNT_VALUE_GET(x)
+#define HF_TIMER_COUNT_VALUE_SET(x) WLAN_HF_TIMER_COUNT_VALUE_SET(x)
+#define HF_LF_COUNT_ADDRESS WLAN_HF_LF_COUNT_ADDRESS
+#define HF_LF_COUNT_OFFSET WLAN_HF_LF_COUNT_OFFSET
+#define HF_LF_COUNT_VALUE_MSB WLAN_HF_LF_COUNT_VALUE_MSB
+#define HF_LF_COUNT_VALUE_LSB WLAN_HF_LF_COUNT_VALUE_LSB
+#define HF_LF_COUNT_VALUE_MASK WLAN_HF_LF_COUNT_VALUE_MASK
+#define HF_LF_COUNT_VALUE_GET(x) WLAN_HF_LF_COUNT_VALUE_GET(x)
+#define HF_LF_COUNT_VALUE_SET(x) WLAN_HF_LF_COUNT_VALUE_SET(x)
+#define HF_TIMER_CONTROL_ADDRESS WLAN_HF_TIMER_CONTROL_ADDRESS
+#define HF_TIMER_CONTROL_OFFSET WLAN_HF_TIMER_CONTROL_OFFSET
+#define HF_TIMER_CONTROL_ENABLE_MSB WLAN_HF_TIMER_CONTROL_ENABLE_MSB
+#define HF_TIMER_CONTROL_ENABLE_LSB WLAN_HF_TIMER_CONTROL_ENABLE_LSB
+#define HF_TIMER_CONTROL_ENABLE_MASK WLAN_HF_TIMER_CONTROL_ENABLE_MASK
+#define HF_TIMER_CONTROL_ENABLE_GET(x) WLAN_HF_TIMER_CONTROL_ENABLE_GET(x)
+#define HF_TIMER_CONTROL_ENABLE_SET(x) WLAN_HF_TIMER_CONTROL_ENABLE_SET(x)
+#define HF_TIMER_CONTROL_ON_MSB WLAN_HF_TIMER_CONTROL_ON_MSB
+#define HF_TIMER_CONTROL_ON_LSB WLAN_HF_TIMER_CONTROL_ON_LSB
+#define HF_TIMER_CONTROL_ON_MASK WLAN_HF_TIMER_CONTROL_ON_MASK
+#define HF_TIMER_CONTROL_ON_GET(x) WLAN_HF_TIMER_CONTROL_ON_GET(x)
+#define HF_TIMER_CONTROL_ON_SET(x) WLAN_HF_TIMER_CONTROL_ON_SET(x)
+#define HF_TIMER_CONTROL_AUTO_RESTART_MSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB
+#define HF_TIMER_CONTROL_AUTO_RESTART_LSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB
+#define HF_TIMER_CONTROL_AUTO_RESTART_MASK WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK
+#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x)
+#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x)
+#define HF_TIMER_CONTROL_RESET_MSB WLAN_HF_TIMER_CONTROL_RESET_MSB
+#define HF_TIMER_CONTROL_RESET_LSB WLAN_HF_TIMER_CONTROL_RESET_LSB
+#define HF_TIMER_CONTROL_RESET_MASK WLAN_HF_TIMER_CONTROL_RESET_MASK
+#define HF_TIMER_CONTROL_RESET_GET(x) WLAN_HF_TIMER_CONTROL_RESET_GET(x)
+#define HF_TIMER_CONTROL_RESET_SET(x) WLAN_HF_TIMER_CONTROL_RESET_SET(x)
+#define HF_TIMER_STATUS_ADDRESS WLAN_HF_TIMER_STATUS_ADDRESS
+#define HF_TIMER_STATUS_OFFSET WLAN_HF_TIMER_STATUS_OFFSET
+#define HF_TIMER_STATUS_INTERRUPT_MSB WLAN_HF_TIMER_STATUS_INTERRUPT_MSB
+#define HF_TIMER_STATUS_INTERRUPT_LSB WLAN_HF_TIMER_STATUS_INTERRUPT_LSB
+#define HF_TIMER_STATUS_INTERRUPT_MASK WLAN_HF_TIMER_STATUS_INTERRUPT_MASK
+#define HF_TIMER_STATUS_INTERRUPT_GET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x)
+#define HF_TIMER_STATUS_INTERRUPT_SET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x)
+#define RTC_CONTROL_ADDRESS WLAN_RTC_CONTROL_ADDRESS
+#define RTC_CONTROL_OFFSET WLAN_RTC_CONTROL_OFFSET
+#define RTC_CONTROL_ENABLE_MSB WLAN_RTC_CONTROL_ENABLE_MSB
+#define RTC_CONTROL_ENABLE_LSB WLAN_RTC_CONTROL_ENABLE_LSB
+#define RTC_CONTROL_ENABLE_MASK WLAN_RTC_CONTROL_ENABLE_MASK
+#define RTC_CONTROL_ENABLE_GET(x) WLAN_RTC_CONTROL_ENABLE_GET(x)
+#define RTC_CONTROL_ENABLE_SET(x) WLAN_RTC_CONTROL_ENABLE_SET(x)
+#define RTC_CONTROL_LOAD_RTC_MSB WLAN_RTC_CONTROL_LOAD_RTC_MSB
+#define RTC_CONTROL_LOAD_RTC_LSB WLAN_RTC_CONTROL_LOAD_RTC_LSB
+#define RTC_CONTROL_LOAD_RTC_MASK WLAN_RTC_CONTROL_LOAD_RTC_MASK
+#define RTC_CONTROL_LOAD_RTC_GET(x) WLAN_RTC_CONTROL_LOAD_RTC_GET(x)
+#define RTC_CONTROL_LOAD_RTC_SET(x) WLAN_RTC_CONTROL_LOAD_RTC_SET(x)
+#define RTC_CONTROL_LOAD_ALARM_MSB WLAN_RTC_CONTROL_LOAD_ALARM_MSB
+#define RTC_CONTROL_LOAD_ALARM_LSB WLAN_RTC_CONTROL_LOAD_ALARM_LSB
+#define RTC_CONTROL_LOAD_ALARM_MASK WLAN_RTC_CONTROL_LOAD_ALARM_MASK
+#define RTC_CONTROL_LOAD_ALARM_GET(x) WLAN_RTC_CONTROL_LOAD_ALARM_GET(x)
+#define RTC_CONTROL_LOAD_ALARM_SET(x) WLAN_RTC_CONTROL_LOAD_ALARM_SET(x)
+#define RTC_TIME_ADDRESS WLAN_RTC_TIME_ADDRESS
+#define RTC_TIME_OFFSET WLAN_RTC_TIME_OFFSET
+#define RTC_TIME_WEEK_DAY_MSB WLAN_RTC_TIME_WEEK_DAY_MSB
+#define RTC_TIME_WEEK_DAY_LSB WLAN_RTC_TIME_WEEK_DAY_LSB
+#define RTC_TIME_WEEK_DAY_MASK WLAN_RTC_TIME_WEEK_DAY_MASK
+#define RTC_TIME_WEEK_DAY_GET(x) WLAN_RTC_TIME_WEEK_DAY_GET(x)
+#define RTC_TIME_WEEK_DAY_SET(x) WLAN_RTC_TIME_WEEK_DAY_SET(x)
+#define RTC_TIME_HOUR_MSB WLAN_RTC_TIME_HOUR_MSB
+#define RTC_TIME_HOUR_LSB WLAN_RTC_TIME_HOUR_LSB
+#define RTC_TIME_HOUR_MASK WLAN_RTC_TIME_HOUR_MASK
+#define RTC_TIME_HOUR_GET(x) WLAN_RTC_TIME_HOUR_GET(x)
+#define RTC_TIME_HOUR_SET(x) WLAN_RTC_TIME_HOUR_SET(x)
+#define RTC_TIME_MINUTE_MSB WLAN_RTC_TIME_MINUTE_MSB
+#define RTC_TIME_MINUTE_LSB WLAN_RTC_TIME_MINUTE_LSB
+#define RTC_TIME_MINUTE_MASK WLAN_RTC_TIME_MINUTE_MASK
+#define RTC_TIME_MINUTE_GET(x) WLAN_RTC_TIME_MINUTE_GET(x)
+#define RTC_TIME_MINUTE_SET(x) WLAN_RTC_TIME_MINUTE_SET(x)
+#define RTC_TIME_SECOND_MSB WLAN_RTC_TIME_SECOND_MSB
+#define RTC_TIME_SECOND_LSB WLAN_RTC_TIME_SECOND_LSB
+#define RTC_TIME_SECOND_MASK WLAN_RTC_TIME_SECOND_MASK
+#define RTC_TIME_SECOND_GET(x) WLAN_RTC_TIME_SECOND_GET(x)
+#define RTC_TIME_SECOND_SET(x) WLAN_RTC_TIME_SECOND_SET(x)
+#define RTC_DATE_ADDRESS WLAN_RTC_DATE_ADDRESS
+#define RTC_DATE_OFFSET WLAN_RTC_DATE_OFFSET
+#define RTC_DATE_YEAR_MSB WLAN_RTC_DATE_YEAR_MSB
+#define RTC_DATE_YEAR_LSB WLAN_RTC_DATE_YEAR_LSB
+#define RTC_DATE_YEAR_MASK WLAN_RTC_DATE_YEAR_MASK
+#define RTC_DATE_YEAR_GET(x) WLAN_RTC_DATE_YEAR_GET(x)
+#define RTC_DATE_YEAR_SET(x) WLAN_RTC_DATE_YEAR_SET(x)
+#define RTC_DATE_MONTH_MSB WLAN_RTC_DATE_MONTH_MSB
+#define RTC_DATE_MONTH_LSB WLAN_RTC_DATE_MONTH_LSB
+#define RTC_DATE_MONTH_MASK WLAN_RTC_DATE_MONTH_MASK
+#define RTC_DATE_MONTH_GET(x) WLAN_RTC_DATE_MONTH_GET(x)
+#define RTC_DATE_MONTH_SET(x) WLAN_RTC_DATE_MONTH_SET(x)
+#define RTC_DATE_MONTH_DAY_MSB WLAN_RTC_DATE_MONTH_DAY_MSB
+#define RTC_DATE_MONTH_DAY_LSB WLAN_RTC_DATE_MONTH_DAY_LSB
+#define RTC_DATE_MONTH_DAY_MASK WLAN_RTC_DATE_MONTH_DAY_MASK
+#define RTC_DATE_MONTH_DAY_GET(x) WLAN_RTC_DATE_MONTH_DAY_GET(x)
+#define RTC_DATE_MONTH_DAY_SET(x) WLAN_RTC_DATE_MONTH_DAY_SET(x)
+#define RTC_SET_TIME_ADDRESS WLAN_RTC_SET_TIME_ADDRESS
+#define RTC_SET_TIME_OFFSET WLAN_RTC_SET_TIME_OFFSET
+#define RTC_SET_TIME_WEEK_DAY_MSB WLAN_RTC_SET_TIME_WEEK_DAY_MSB
+#define RTC_SET_TIME_WEEK_DAY_LSB WLAN_RTC_SET_TIME_WEEK_DAY_LSB
+#define RTC_SET_TIME_WEEK_DAY_MASK WLAN_RTC_SET_TIME_WEEK_DAY_MASK
+#define RTC_SET_TIME_WEEK_DAY_GET(x) WLAN_RTC_SET_TIME_WEEK_DAY_GET(x)
+#define RTC_SET_TIME_WEEK_DAY_SET(x) WLAN_RTC_SET_TIME_WEEK_DAY_SET(x)
+#define RTC_SET_TIME_HOUR_MSB WLAN_RTC_SET_TIME_HOUR_MSB
+#define RTC_SET_TIME_HOUR_LSB WLAN_RTC_SET_TIME_HOUR_LSB
+#define RTC_SET_TIME_HOUR_MASK WLAN_RTC_SET_TIME_HOUR_MASK
+#define RTC_SET_TIME_HOUR_GET(x) WLAN_RTC_SET_TIME_HOUR_GET(x)
+#define RTC_SET_TIME_HOUR_SET(x) WLAN_RTC_SET_TIME_HOUR_SET(x)
+#define RTC_SET_TIME_MINUTE_MSB WLAN_RTC_SET_TIME_MINUTE_MSB
+#define RTC_SET_TIME_MINUTE_LSB WLAN_RTC_SET_TIME_MINUTE_LSB
+#define RTC_SET_TIME_MINUTE_MASK WLAN_RTC_SET_TIME_MINUTE_MASK
+#define RTC_SET_TIME_MINUTE_GET(x) WLAN_RTC_SET_TIME_MINUTE_GET(x)
+#define RTC_SET_TIME_MINUTE_SET(x) WLAN_RTC_SET_TIME_MINUTE_SET(x)
+#define RTC_SET_TIME_SECOND_MSB WLAN_RTC_SET_TIME_SECOND_MSB
+#define RTC_SET_TIME_SECOND_LSB WLAN_RTC_SET_TIME_SECOND_LSB
+#define RTC_SET_TIME_SECOND_MASK WLAN_RTC_SET_TIME_SECOND_MASK
+#define RTC_SET_TIME_SECOND_GET(x) WLAN_RTC_SET_TIME_SECOND_GET(x)
+#define RTC_SET_TIME_SECOND_SET(x) WLAN_RTC_SET_TIME_SECOND_SET(x)
+#define RTC_SET_DATE_ADDRESS WLAN_RTC_SET_DATE_ADDRESS
+#define RTC_SET_DATE_OFFSET WLAN_RTC_SET_DATE_OFFSET
+#define RTC_SET_DATE_YEAR_MSB WLAN_RTC_SET_DATE_YEAR_MSB
+#define RTC_SET_DATE_YEAR_LSB WLAN_RTC_SET_DATE_YEAR_LSB
+#define RTC_SET_DATE_YEAR_MASK WLAN_RTC_SET_DATE_YEAR_MASK
+#define RTC_SET_DATE_YEAR_GET(x) WLAN_RTC_SET_DATE_YEAR_GET(x)
+#define RTC_SET_DATE_YEAR_SET(x) WLAN_RTC_SET_DATE_YEAR_SET(x)
+#define RTC_SET_DATE_MONTH_MSB WLAN_RTC_SET_DATE_MONTH_MSB
+#define RTC_SET_DATE_MONTH_LSB WLAN_RTC_SET_DATE_MONTH_LSB
+#define RTC_SET_DATE_MONTH_MASK WLAN_RTC_SET_DATE_MONTH_MASK
+#define RTC_SET_DATE_MONTH_GET(x) WLAN_RTC_SET_DATE_MONTH_GET(x)
+#define RTC_SET_DATE_MONTH_SET(x) WLAN_RTC_SET_DATE_MONTH_SET(x)
+#define RTC_SET_DATE_MONTH_DAY_MSB WLAN_RTC_SET_DATE_MONTH_DAY_MSB
+#define RTC_SET_DATE_MONTH_DAY_LSB WLAN_RTC_SET_DATE_MONTH_DAY_LSB
+#define RTC_SET_DATE_MONTH_DAY_MASK WLAN_RTC_SET_DATE_MONTH_DAY_MASK
+#define RTC_SET_DATE_MONTH_DAY_GET(x) WLAN_RTC_SET_DATE_MONTH_DAY_GET(x)
+#define RTC_SET_DATE_MONTH_DAY_SET(x) WLAN_RTC_SET_DATE_MONTH_DAY_SET(x)
+#define RTC_SET_ALARM_ADDRESS WLAN_RTC_SET_ALARM_ADDRESS
+#define RTC_SET_ALARM_OFFSET WLAN_RTC_SET_ALARM_OFFSET
+#define RTC_SET_ALARM_HOUR_MSB WLAN_RTC_SET_ALARM_HOUR_MSB
+#define RTC_SET_ALARM_HOUR_LSB WLAN_RTC_SET_ALARM_HOUR_LSB
+#define RTC_SET_ALARM_HOUR_MASK WLAN_RTC_SET_ALARM_HOUR_MASK
+#define RTC_SET_ALARM_HOUR_GET(x) WLAN_RTC_SET_ALARM_HOUR_GET(x)
+#define RTC_SET_ALARM_HOUR_SET(x) WLAN_RTC_SET_ALARM_HOUR_SET(x)
+#define RTC_SET_ALARM_MINUTE_MSB WLAN_RTC_SET_ALARM_MINUTE_MSB
+#define RTC_SET_ALARM_MINUTE_LSB WLAN_RTC_SET_ALARM_MINUTE_LSB
+#define RTC_SET_ALARM_MINUTE_MASK WLAN_RTC_SET_ALARM_MINUTE_MASK
+#define RTC_SET_ALARM_MINUTE_GET(x) WLAN_RTC_SET_ALARM_MINUTE_GET(x)
+#define RTC_SET_ALARM_MINUTE_SET(x) WLAN_RTC_SET_ALARM_MINUTE_SET(x)
+#define RTC_SET_ALARM_SECOND_MSB WLAN_RTC_SET_ALARM_SECOND_MSB
+#define RTC_SET_ALARM_SECOND_LSB WLAN_RTC_SET_ALARM_SECOND_LSB
+#define RTC_SET_ALARM_SECOND_MASK WLAN_RTC_SET_ALARM_SECOND_MASK
+#define RTC_SET_ALARM_SECOND_GET(x) WLAN_RTC_SET_ALARM_SECOND_GET(x)
+#define RTC_SET_ALARM_SECOND_SET(x) WLAN_RTC_SET_ALARM_SECOND_SET(x)
+#define RTC_CONFIG_ADDRESS WLAN_RTC_CONFIG_ADDRESS
+#define RTC_CONFIG_OFFSET WLAN_RTC_CONFIG_OFFSET
+#define RTC_CONFIG_BCD_MSB WLAN_RTC_CONFIG_BCD_MSB
+#define RTC_CONFIG_BCD_LSB WLAN_RTC_CONFIG_BCD_LSB
+#define RTC_CONFIG_BCD_MASK WLAN_RTC_CONFIG_BCD_MASK
+#define RTC_CONFIG_BCD_GET(x) WLAN_RTC_CONFIG_BCD_GET(x)
+#define RTC_CONFIG_BCD_SET(x) WLAN_RTC_CONFIG_BCD_SET(x)
+#define RTC_CONFIG_TWELVE_HOUR_MSB WLAN_RTC_CONFIG_TWELVE_HOUR_MSB
+#define RTC_CONFIG_TWELVE_HOUR_LSB WLAN_RTC_CONFIG_TWELVE_HOUR_LSB
+#define RTC_CONFIG_TWELVE_HOUR_MASK WLAN_RTC_CONFIG_TWELVE_HOUR_MASK
+#define RTC_CONFIG_TWELVE_HOUR_GET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x)
+#define RTC_CONFIG_TWELVE_HOUR_SET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x)
+#define RTC_CONFIG_DSE_MSB WLAN_RTC_CONFIG_DSE_MSB
+#define RTC_CONFIG_DSE_LSB WLAN_RTC_CONFIG_DSE_LSB
+#define RTC_CONFIG_DSE_MASK WLAN_RTC_CONFIG_DSE_MASK
+#define RTC_CONFIG_DSE_GET(x) WLAN_RTC_CONFIG_DSE_GET(x)
+#define RTC_CONFIG_DSE_SET(x) WLAN_RTC_CONFIG_DSE_SET(x)
+#define RTC_ALARM_STATUS_ADDRESS WLAN_RTC_ALARM_STATUS_ADDRESS
+#define RTC_ALARM_STATUS_OFFSET WLAN_RTC_ALARM_STATUS_OFFSET
+#define RTC_ALARM_STATUS_ENABLE_MSB WLAN_RTC_ALARM_STATUS_ENABLE_MSB
+#define RTC_ALARM_STATUS_ENABLE_LSB WLAN_RTC_ALARM_STATUS_ENABLE_LSB
+#define RTC_ALARM_STATUS_ENABLE_MASK WLAN_RTC_ALARM_STATUS_ENABLE_MASK
+#define RTC_ALARM_STATUS_ENABLE_GET(x) WLAN_RTC_ALARM_STATUS_ENABLE_GET(x)
+#define RTC_ALARM_STATUS_ENABLE_SET(x) WLAN_RTC_ALARM_STATUS_ENABLE_SET(x)
+#define RTC_ALARM_STATUS_INTERRUPT_MSB WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB
+#define RTC_ALARM_STATUS_INTERRUPT_LSB WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB
+#define RTC_ALARM_STATUS_INTERRUPT_MASK WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK
+#define RTC_ALARM_STATUS_INTERRUPT_GET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x)
+#define RTC_ALARM_STATUS_INTERRUPT_SET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x)
+#define UART_WAKEUP_ADDRESS WLAN_UART_WAKEUP_ADDRESS
+#define UART_WAKEUP_OFFSET WLAN_UART_WAKEUP_OFFSET
+#define UART_WAKEUP_ENABLE_MSB WLAN_UART_WAKEUP_ENABLE_MSB
+#define UART_WAKEUP_ENABLE_LSB WLAN_UART_WAKEUP_ENABLE_LSB
+#define UART_WAKEUP_ENABLE_MASK WLAN_UART_WAKEUP_ENABLE_MASK
+#define UART_WAKEUP_ENABLE_GET(x) WLAN_UART_WAKEUP_ENABLE_GET(x)
+#define UART_WAKEUP_ENABLE_SET(x) WLAN_UART_WAKEUP_ENABLE_SET(x)
+#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS
+#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET
+#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB
+#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB
+#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK
+#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x)
+#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x)
+#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS
+#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET
+#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB
+#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB
+#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK
+#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x)
+#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x)
+#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB
+#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB
+#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK
+#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x)
+#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x)
+#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB
+#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB
+#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK
+#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x)
+#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x)
+#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB
+#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB
+#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK
+#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x)
+#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x)
+#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB
+#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB
+#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK
+#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x)
+#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x)
+#define SDIO_WRAPPER_ADDRESS WLAN_SDIO_WRAPPER_ADDRESS
+#define SDIO_WRAPPER_OFFSET WLAN_SDIO_WRAPPER_OFFSET
+#define SDIO_WRAPPER_SLEEP_MSB WLAN_SDIO_WRAPPER_SLEEP_MSB
+#define SDIO_WRAPPER_SLEEP_LSB WLAN_SDIO_WRAPPER_SLEEP_LSB
+#define SDIO_WRAPPER_SLEEP_MASK WLAN_SDIO_WRAPPER_SLEEP_MASK
+#define SDIO_WRAPPER_SLEEP_GET(x) WLAN_SDIO_WRAPPER_SLEEP_GET(x)
+#define SDIO_WRAPPER_SLEEP_SET(x) WLAN_SDIO_WRAPPER_SLEEP_SET(x)
+#define SDIO_WRAPPER_WAKEUP_MSB WLAN_SDIO_WRAPPER_WAKEUP_MSB
+#define SDIO_WRAPPER_WAKEUP_LSB WLAN_SDIO_WRAPPER_WAKEUP_LSB
+#define SDIO_WRAPPER_WAKEUP_MASK WLAN_SDIO_WRAPPER_WAKEUP_MASK
+#define SDIO_WRAPPER_WAKEUP_GET(x) WLAN_SDIO_WRAPPER_WAKEUP_GET(x)
+#define SDIO_WRAPPER_WAKEUP_SET(x) WLAN_SDIO_WRAPPER_WAKEUP_SET(x)
+#define SDIO_WRAPPER_SOC_ON_MSB WLAN_SDIO_WRAPPER_SOC_ON_MSB
+#define SDIO_WRAPPER_SOC_ON_LSB WLAN_SDIO_WRAPPER_SOC_ON_LSB
+#define SDIO_WRAPPER_SOC_ON_MASK WLAN_SDIO_WRAPPER_SOC_ON_MASK
+#define SDIO_WRAPPER_SOC_ON_GET(x) WLAN_SDIO_WRAPPER_SOC_ON_GET(x)
+#define SDIO_WRAPPER_SOC_ON_SET(x) WLAN_SDIO_WRAPPER_SOC_ON_SET(x)
+#define SDIO_WRAPPER_ON_MSB WLAN_SDIO_WRAPPER_ON_MSB
+#define SDIO_WRAPPER_ON_LSB WLAN_SDIO_WRAPPER_ON_LSB
+#define SDIO_WRAPPER_ON_MASK WLAN_SDIO_WRAPPER_ON_MASK
+#define SDIO_WRAPPER_ON_GET(x) WLAN_SDIO_WRAPPER_ON_GET(x)
+#define SDIO_WRAPPER_ON_SET(x) WLAN_SDIO_WRAPPER_ON_SET(x)
+#define MAC_SLEEP_CONTROL_ADDRESS WLAN_MAC_SLEEP_CONTROL_ADDRESS
+#define MAC_SLEEP_CONTROL_OFFSET WLAN_MAC_SLEEP_CONTROL_OFFSET
+#define MAC_SLEEP_CONTROL_ENABLE_MSB WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB
+#define MAC_SLEEP_CONTROL_ENABLE_LSB WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB
+#define MAC_SLEEP_CONTROL_ENABLE_MASK WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK
+#define MAC_SLEEP_CONTROL_ENABLE_GET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x)
+#define MAC_SLEEP_CONTROL_ENABLE_SET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x)
+#define KEEP_AWAKE_ADDRESS WLAN_KEEP_AWAKE_ADDRESS
+#define KEEP_AWAKE_OFFSET WLAN_KEEP_AWAKE_OFFSET
+#define KEEP_AWAKE_COUNT_MSB WLAN_KEEP_AWAKE_COUNT_MSB
+#define KEEP_AWAKE_COUNT_LSB WLAN_KEEP_AWAKE_COUNT_LSB
+#define KEEP_AWAKE_COUNT_MASK WLAN_KEEP_AWAKE_COUNT_MASK
+#define KEEP_AWAKE_COUNT_GET(x) WLAN_KEEP_AWAKE_COUNT_GET(x)
+#define KEEP_AWAKE_COUNT_SET(x) WLAN_KEEP_AWAKE_COUNT_SET(x)
+#define LPO_CAL_TIME_ADDRESS WLAN_LPO_CAL_TIME_ADDRESS
+#define LPO_CAL_TIME_OFFSET WLAN_LPO_CAL_TIME_OFFSET
+#define LPO_CAL_TIME_LENGTH_MSB WLAN_LPO_CAL_TIME_LENGTH_MSB
+#define LPO_CAL_TIME_LENGTH_LSB WLAN_LPO_CAL_TIME_LENGTH_LSB
+#define LPO_CAL_TIME_LENGTH_MASK WLAN_LPO_CAL_TIME_LENGTH_MASK
+#define LPO_CAL_TIME_LENGTH_GET(x) WLAN_LPO_CAL_TIME_LENGTH_GET(x)
+#define LPO_CAL_TIME_LENGTH_SET(x) WLAN_LPO_CAL_TIME_LENGTH_SET(x)
+#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS
+#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET
+#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB
+#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB
+#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK
+#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x)
+#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x)
+#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS
+#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x)
+#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x)
+#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS
+#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET
+#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB
+#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB
+#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK
+#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x)
+#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x)
+#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB
+#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB
+#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK
+#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x)
+#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x)
+#define LPO_CAL_TEST_CONTROL_ADDRESS WLAN_LPO_CAL_TEST_CONTROL_ADDRESS
+#define LPO_CAL_TEST_CONTROL_OFFSET WLAN_LPO_CAL_TEST_CONTROL_OFFSET
+#define LPO_CAL_TEST_CONTROL_ENABLE_MSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB
+#define LPO_CAL_TEST_CONTROL_ENABLE_LSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB
+#define LPO_CAL_TEST_CONTROL_ENABLE_MASK WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK
+#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x)
+#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x)
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x)
+#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x)
+#define LPO_CAL_TEST_STATUS_ADDRESS WLAN_LPO_CAL_TEST_STATUS_ADDRESS
+#define LPO_CAL_TEST_STATUS_OFFSET WLAN_LPO_CAL_TEST_STATUS_OFFSET
+#define LPO_CAL_TEST_STATUS_READY_MSB WLAN_LPO_CAL_TEST_STATUS_READY_MSB
+#define LPO_CAL_TEST_STATUS_READY_LSB WLAN_LPO_CAL_TEST_STATUS_READY_LSB
+#define LPO_CAL_TEST_STATUS_READY_MASK WLAN_LPO_CAL_TEST_STATUS_READY_MASK
+#define LPO_CAL_TEST_STATUS_READY_GET(x) WLAN_LPO_CAL_TEST_STATUS_READY_GET(x)
+#define LPO_CAL_TEST_STATUS_READY_SET(x) WLAN_LPO_CAL_TEST_STATUS_READY_SET(x)
+#define LPO_CAL_TEST_STATUS_COUNT_MSB WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB
+#define LPO_CAL_TEST_STATUS_COUNT_LSB WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB
+#define LPO_CAL_TEST_STATUS_COUNT_MASK WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK
+#define LPO_CAL_TEST_STATUS_COUNT_GET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x)
+#define LPO_CAL_TEST_STATUS_COUNT_SET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x)
+#define CHIP_ID_ADDRESS WLAN_CHIP_ID_ADDRESS
+#define CHIP_ID_OFFSET WLAN_CHIP_ID_OFFSET
+#define CHIP_ID_DEVICE_ID_MSB WLAN_CHIP_ID_DEVICE_ID_MSB
+#define CHIP_ID_DEVICE_ID_LSB WLAN_CHIP_ID_DEVICE_ID_LSB
+#define CHIP_ID_DEVICE_ID_MASK WLAN_CHIP_ID_DEVICE_ID_MASK
+#define CHIP_ID_DEVICE_ID_GET(x) WLAN_CHIP_ID_DEVICE_ID_GET(x)
+#define CHIP_ID_DEVICE_ID_SET(x) WLAN_CHIP_ID_DEVICE_ID_SET(x)
+#define CHIP_ID_CONFIG_ID_MSB WLAN_CHIP_ID_CONFIG_ID_MSB
+#define CHIP_ID_CONFIG_ID_LSB WLAN_CHIP_ID_CONFIG_ID_LSB
+#define CHIP_ID_CONFIG_ID_MASK WLAN_CHIP_ID_CONFIG_ID_MASK
+#define CHIP_ID_CONFIG_ID_GET(x) WLAN_CHIP_ID_CONFIG_ID_GET(x)
+#define CHIP_ID_CONFIG_ID_SET(x) WLAN_CHIP_ID_CONFIG_ID_SET(x)
+#define CHIP_ID_VERSION_ID_MSB WLAN_CHIP_ID_VERSION_ID_MSB
+#define CHIP_ID_VERSION_ID_LSB WLAN_CHIP_ID_VERSION_ID_LSB
+#define CHIP_ID_VERSION_ID_MASK WLAN_CHIP_ID_VERSION_ID_MASK
+#define CHIP_ID_VERSION_ID_GET(x) WLAN_CHIP_ID_VERSION_ID_GET(x)
+#define CHIP_ID_VERSION_ID_SET(x) WLAN_CHIP_ID_VERSION_ID_SET(x)
+#define DERIVED_RTC_CLK_ADDRESS WLAN_DERIVED_RTC_CLK_ADDRESS
+#define DERIVED_RTC_CLK_OFFSET WLAN_DERIVED_RTC_CLK_OFFSET
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x)
+#define DERIVED_RTC_CLK_FORCE_MSB WLAN_DERIVED_RTC_CLK_FORCE_MSB
+#define DERIVED_RTC_CLK_FORCE_LSB WLAN_DERIVED_RTC_CLK_FORCE_LSB
+#define DERIVED_RTC_CLK_FORCE_MASK WLAN_DERIVED_RTC_CLK_FORCE_MASK
+#define DERIVED_RTC_CLK_FORCE_GET(x) WLAN_DERIVED_RTC_CLK_FORCE_GET(x)
+#define DERIVED_RTC_CLK_FORCE_SET(x) WLAN_DERIVED_RTC_CLK_FORCE_SET(x)
+#define DERIVED_RTC_CLK_PERIOD_MSB WLAN_DERIVED_RTC_CLK_PERIOD_MSB
+#define DERIVED_RTC_CLK_PERIOD_LSB WLAN_DERIVED_RTC_CLK_PERIOD_LSB
+#define DERIVED_RTC_CLK_PERIOD_MASK WLAN_DERIVED_RTC_CLK_PERIOD_MASK
+#define DERIVED_RTC_CLK_PERIOD_GET(x) WLAN_DERIVED_RTC_CLK_PERIOD_GET(x)
+#define DERIVED_RTC_CLK_PERIOD_SET(x) WLAN_DERIVED_RTC_CLK_PERIOD_SET(x)
+#define POWER_REG_ADDRESS WLAN_POWER_REG_ADDRESS
+#define POWER_REG_OFFSET WLAN_POWER_REG_OFFSET
+#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB
+#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB
+#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK
+#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x)
+#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x)
+#define POWER_REG_DEBUG_EN_MSB WLAN_POWER_REG_DEBUG_EN_MSB
+#define POWER_REG_DEBUG_EN_LSB WLAN_POWER_REG_DEBUG_EN_LSB
+#define POWER_REG_DEBUG_EN_MASK WLAN_POWER_REG_DEBUG_EN_MASK
+#define POWER_REG_DEBUG_EN_GET(x) WLAN_POWER_REG_DEBUG_EN_GET(x)
+#define POWER_REG_DEBUG_EN_SET(x) WLAN_POWER_REG_DEBUG_EN_SET(x)
+#define POWER_REG_WLAN_BB_PWD_EN_MSB WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB
+#define POWER_REG_WLAN_BB_PWD_EN_LSB WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB
+#define POWER_REG_WLAN_BB_PWD_EN_MASK WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK
+#define POWER_REG_WLAN_BB_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x)
+#define POWER_REG_WLAN_BB_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x)
+#define POWER_REG_WLAN_MAC_PWD_EN_MSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB
+#define POWER_REG_WLAN_MAC_PWD_EN_LSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB
+#define POWER_REG_WLAN_MAC_PWD_EN_MASK WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK
+#define POWER_REG_WLAN_MAC_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x)
+#define POWER_REG_WLAN_MAC_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x)
+#define POWER_REG_VLVL_MSB WLAN_POWER_REG_VLVL_MSB
+#define POWER_REG_VLVL_LSB WLAN_POWER_REG_VLVL_LSB
+#define POWER_REG_VLVL_MASK WLAN_POWER_REG_VLVL_MASK
+#define POWER_REG_VLVL_GET(x) WLAN_POWER_REG_VLVL_GET(x)
+#define POWER_REG_VLVL_SET(x) WLAN_POWER_REG_VLVL_SET(x)
+#define POWER_REG_CPU_INT_ENABLE_MSB WLAN_POWER_REG_CPU_INT_ENABLE_MSB
+#define POWER_REG_CPU_INT_ENABLE_LSB WLAN_POWER_REG_CPU_INT_ENABLE_LSB
+#define POWER_REG_CPU_INT_ENABLE_MASK WLAN_POWER_REG_CPU_INT_ENABLE_MASK
+#define POWER_REG_CPU_INT_ENABLE_GET(x) WLAN_POWER_REG_CPU_INT_ENABLE_GET(x)
+#define POWER_REG_CPU_INT_ENABLE_SET(x) WLAN_POWER_REG_CPU_INT_ENABLE_SET(x)
+#define POWER_REG_WLAN_ISO_DIS_MSB WLAN_POWER_REG_WLAN_ISO_DIS_MSB
+#define POWER_REG_WLAN_ISO_DIS_LSB WLAN_POWER_REG_WLAN_ISO_DIS_LSB
+#define POWER_REG_WLAN_ISO_DIS_MASK WLAN_POWER_REG_WLAN_ISO_DIS_MASK
+#define POWER_REG_WLAN_ISO_DIS_GET(x) WLAN_POWER_REG_WLAN_ISO_DIS_GET(x)
+#define POWER_REG_WLAN_ISO_DIS_SET(x) WLAN_POWER_REG_WLAN_ISO_DIS_SET(x)
+#define POWER_REG_WLAN_ISO_CNTL_MSB WLAN_POWER_REG_WLAN_ISO_CNTL_MSB
+#define POWER_REG_WLAN_ISO_CNTL_LSB WLAN_POWER_REG_WLAN_ISO_CNTL_LSB
+#define POWER_REG_WLAN_ISO_CNTL_MASK WLAN_POWER_REG_WLAN_ISO_CNTL_MASK
+#define POWER_REG_WLAN_ISO_CNTL_GET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x)
+#define POWER_REG_WLAN_ISO_CNTL_SET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x)
+#define POWER_REG_RADIO_PWD_EN_MSB WLAN_POWER_REG_RADIO_PWD_EN_MSB
+#define POWER_REG_RADIO_PWD_EN_LSB WLAN_POWER_REG_RADIO_PWD_EN_LSB
+#define POWER_REG_RADIO_PWD_EN_MASK WLAN_POWER_REG_RADIO_PWD_EN_MASK
+#define POWER_REG_RADIO_PWD_EN_GET(x) WLAN_POWER_REG_RADIO_PWD_EN_GET(x)
+#define POWER_REG_RADIO_PWD_EN_SET(x) WLAN_POWER_REG_RADIO_PWD_EN_SET(x)
+#define POWER_REG_SOC_ISO_EN_MSB WLAN_POWER_REG_SOC_ISO_EN_MSB
+#define POWER_REG_SOC_ISO_EN_LSB WLAN_POWER_REG_SOC_ISO_EN_LSB
+#define POWER_REG_SOC_ISO_EN_MASK WLAN_POWER_REG_SOC_ISO_EN_MASK
+#define POWER_REG_SOC_ISO_EN_GET(x) WLAN_POWER_REG_SOC_ISO_EN_GET(x)
+#define POWER_REG_SOC_ISO_EN_SET(x) WLAN_POWER_REG_SOC_ISO_EN_SET(x)
+#define POWER_REG_WLAN_ISO_EN_MSB WLAN_POWER_REG_WLAN_ISO_EN_MSB
+#define POWER_REG_WLAN_ISO_EN_LSB WLAN_POWER_REG_WLAN_ISO_EN_LSB
+#define POWER_REG_WLAN_ISO_EN_MASK WLAN_POWER_REG_WLAN_ISO_EN_MASK
+#define POWER_REG_WLAN_ISO_EN_GET(x) WLAN_POWER_REG_WLAN_ISO_EN_GET(x)
+#define POWER_REG_WLAN_ISO_EN_SET(x) WLAN_POWER_REG_WLAN_ISO_EN_SET(x)
+#define POWER_REG_WLAN_PWD_EN_MSB WLAN_POWER_REG_WLAN_PWD_EN_MSB
+#define POWER_REG_WLAN_PWD_EN_LSB WLAN_POWER_REG_WLAN_PWD_EN_LSB
+#define POWER_REG_WLAN_PWD_EN_MASK WLAN_POWER_REG_WLAN_PWD_EN_MASK
+#define POWER_REG_WLAN_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_PWD_EN_GET(x)
+#define POWER_REG_WLAN_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_PWD_EN_SET(x)
+#define POWER_REG_POWER_EN_MSB WLAN_POWER_REG_POWER_EN_MSB
+#define POWER_REG_POWER_EN_LSB WLAN_POWER_REG_POWER_EN_LSB
+#define POWER_REG_POWER_EN_MASK WLAN_POWER_REG_POWER_EN_MASK
+#define POWER_REG_POWER_EN_GET(x) WLAN_POWER_REG_POWER_EN_GET(x)
+#define POWER_REG_POWER_EN_SET(x) WLAN_POWER_REG_POWER_EN_SET(x)
+#define CORE_CLK_CTRL_ADDRESS WLAN_CORE_CLK_CTRL_ADDRESS
+#define CORE_CLK_CTRL_OFFSET WLAN_CORE_CLK_CTRL_OFFSET
+#define CORE_CLK_CTRL_DIV_MSB WLAN_CORE_CLK_CTRL_DIV_MSB
+#define CORE_CLK_CTRL_DIV_LSB WLAN_CORE_CLK_CTRL_DIV_LSB
+#define CORE_CLK_CTRL_DIV_MASK WLAN_CORE_CLK_CTRL_DIV_MASK
+#define CORE_CLK_CTRL_DIV_GET(x) WLAN_CORE_CLK_CTRL_DIV_GET(x)
+#define CORE_CLK_CTRL_DIV_SET(x) WLAN_CORE_CLK_CTRL_DIV_SET(x)
+#define GPIO_WAKEUP_CONTROL_ADDRESS WLAN_GPIO_WAKEUP_CONTROL_ADDRESS
+#define GPIO_WAKEUP_CONTROL_OFFSET WLAN_GPIO_WAKEUP_CONTROL_OFFSET
+#define GPIO_WAKEUP_CONTROL_ENABLE_MSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB
+#define GPIO_WAKEUP_CONTROL_ENABLE_LSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB
+#define GPIO_WAKEUP_CONTROL_ENABLE_MASK WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK
+#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x)
+#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x)
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
new file mode 100644
index 000000000000..abf872650054
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
@@ -0,0 +1,2065 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _RTC_WLAN_REG_REG_H_
+#define _RTC_WLAN_REG_REG_H_
+
+#define WLAN_RESET_CONTROL_ADDRESS 0x00000000
+#define WLAN_RESET_CONTROL_OFFSET 0x00000000
+#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB 14
+#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB 14
+#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00004000
+#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB)
+#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK)
+#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB 13
+#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB 13
+#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK 0x00002000
+#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB)
+#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK)
+#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB 12
+#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB 12
+#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK 0x00001000
+#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB)
+#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK)
+#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB 11
+#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB 11
+#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800
+#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB)
+#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK)
+#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB 10
+#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB 10
+#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400
+#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB)
+#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK)
+#define WLAN_RESET_CONTROL_RST_OUT_MSB 9
+#define WLAN_RESET_CONTROL_RST_OUT_LSB 9
+#define WLAN_RESET_CONTROL_RST_OUT_MASK 0x00000200
+#define WLAN_RESET_CONTROL_RST_OUT_GET(x) (((x) & WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB)
+#define WLAN_RESET_CONTROL_RST_OUT_SET(x) (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK)
+#define WLAN_RESET_CONTROL_COLD_RST_MSB 8
+#define WLAN_RESET_CONTROL_COLD_RST_LSB 8
+#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000100
+#define WLAN_RESET_CONTROL_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB)
+#define WLAN_RESET_CONTROL_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK)
+#define WLAN_RESET_CONTROL_WARM_RST_MSB 7
+#define WLAN_RESET_CONTROL_WARM_RST_LSB 7
+#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000080
+#define WLAN_RESET_CONTROL_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB)
+#define WLAN_RESET_CONTROL_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK)
+#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB 6
+#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB 6
+#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
+#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB)
+#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK)
+#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB 5
+#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB 5
+#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020
+#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB)
+#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK)
+#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB 4
+#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB 4
+#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010
+#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB)
+#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK)
+#define WLAN_RESET_CONTROL_MBOX_RST_MSB 2
+#define WLAN_RESET_CONTROL_MBOX_RST_LSB 2
+#define WLAN_RESET_CONTROL_MBOX_RST_MASK 0x00000004
+#define WLAN_RESET_CONTROL_MBOX_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB)
+#define WLAN_RESET_CONTROL_MBOX_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK)
+#define WLAN_RESET_CONTROL_UART_RST_MSB 1
+#define WLAN_RESET_CONTROL_UART_RST_LSB 1
+#define WLAN_RESET_CONTROL_UART_RST_MASK 0x00000002
+#define WLAN_RESET_CONTROL_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB)
+#define WLAN_RESET_CONTROL_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK)
+#define WLAN_RESET_CONTROL_SI0_RST_MSB 0
+#define WLAN_RESET_CONTROL_SI0_RST_LSB 0
+#define WLAN_RESET_CONTROL_SI0_RST_MASK 0x00000001
+#define WLAN_RESET_CONTROL_SI0_RST_GET(x) (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB)
+#define WLAN_RESET_CONTROL_SI0_RST_SET(x) (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK)
+
+#define WLAN_XTAL_CONTROL_ADDRESS 0x00000004
+#define WLAN_XTAL_CONTROL_OFFSET 0x00000004
+#define WLAN_XTAL_CONTROL_TCXO_MSB 0
+#define WLAN_XTAL_CONTROL_TCXO_LSB 0
+#define WLAN_XTAL_CONTROL_TCXO_MASK 0x00000001
+#define WLAN_XTAL_CONTROL_TCXO_GET(x) (((x) & WLAN_XTAL_CONTROL_TCXO_MASK) >> WLAN_XTAL_CONTROL_TCXO_LSB)
+#define WLAN_XTAL_CONTROL_TCXO_SET(x) (((x) << WLAN_XTAL_CONTROL_TCXO_LSB) & WLAN_XTAL_CONTROL_TCXO_MASK)
+
+#define WLAN_TCXO_DETECT_ADDRESS 0x00000008
+#define WLAN_TCXO_DETECT_OFFSET 0x00000008
+#define WLAN_TCXO_DETECT_PRESENT_MSB 0
+#define WLAN_TCXO_DETECT_PRESENT_LSB 0
+#define WLAN_TCXO_DETECT_PRESENT_MASK 0x00000001
+#define WLAN_TCXO_DETECT_PRESENT_GET(x) (((x) & WLAN_TCXO_DETECT_PRESENT_MASK) >> WLAN_TCXO_DETECT_PRESENT_LSB)
+#define WLAN_TCXO_DETECT_PRESENT_SET(x) (((x) << WLAN_TCXO_DETECT_PRESENT_LSB) & WLAN_TCXO_DETECT_PRESENT_MASK)
+
+#define WLAN_XTAL_TEST_ADDRESS 0x0000000c
+#define WLAN_XTAL_TEST_OFFSET 0x0000000c
+#define WLAN_XTAL_TEST_NOTCXODET_MSB 0
+#define WLAN_XTAL_TEST_NOTCXODET_LSB 0
+#define WLAN_XTAL_TEST_NOTCXODET_MASK 0x00000001
+#define WLAN_XTAL_TEST_NOTCXODET_GET(x) (((x) & WLAN_XTAL_TEST_NOTCXODET_MASK) >> WLAN_XTAL_TEST_NOTCXODET_LSB)
+#define WLAN_XTAL_TEST_NOTCXODET_SET(x) (((x) << WLAN_XTAL_TEST_NOTCXODET_LSB) & WLAN_XTAL_TEST_NOTCXODET_MASK)
+
+#define WLAN_QUADRATURE_ADDRESS 0x00000010
+#define WLAN_QUADRATURE_OFFSET 0x00000010
+#define WLAN_QUADRATURE_ADC_MSB 7
+#define WLAN_QUADRATURE_ADC_LSB 4
+#define WLAN_QUADRATURE_ADC_MASK 0x000000f0
+#define WLAN_QUADRATURE_ADC_GET(x) (((x) & WLAN_QUADRATURE_ADC_MASK) >> WLAN_QUADRATURE_ADC_LSB)
+#define WLAN_QUADRATURE_ADC_SET(x) (((x) << WLAN_QUADRATURE_ADC_LSB) & WLAN_QUADRATURE_ADC_MASK)
+#define WLAN_QUADRATURE_SEL_MSB 2
+#define WLAN_QUADRATURE_SEL_LSB 2
+#define WLAN_QUADRATURE_SEL_MASK 0x00000004
+#define WLAN_QUADRATURE_SEL_GET(x) (((x) & WLAN_QUADRATURE_SEL_MASK) >> WLAN_QUADRATURE_SEL_LSB)
+#define WLAN_QUADRATURE_SEL_SET(x) (((x) << WLAN_QUADRATURE_SEL_LSB) & WLAN_QUADRATURE_SEL_MASK)
+#define WLAN_QUADRATURE_DAC_MSB 1
+#define WLAN_QUADRATURE_DAC_LSB 0
+#define WLAN_QUADRATURE_DAC_MASK 0x00000003
+#define WLAN_QUADRATURE_DAC_GET(x) (((x) & WLAN_QUADRATURE_DAC_MASK) >> WLAN_QUADRATURE_DAC_LSB)
+#define WLAN_QUADRATURE_DAC_SET(x) (((x) << WLAN_QUADRATURE_DAC_LSB) & WLAN_QUADRATURE_DAC_MASK)
+
+#define WLAN_PLL_CONTROL_ADDRESS 0x00000014
+#define WLAN_PLL_CONTROL_OFFSET 0x00000014
+#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB 20
+#define WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB 20
+#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK 0x00100000
+#define WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x) (((x) & WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK) >> WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB)
+#define WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x) (((x) << WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB) & WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK)
+#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB 19
+#define WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB 19
+#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK 0x00080000
+#define WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x) (((x) & WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK) >> WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB)
+#define WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x) (((x) << WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB) & WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK)
+#define WLAN_PLL_CONTROL_NOPWD_MSB 18
+#define WLAN_PLL_CONTROL_NOPWD_LSB 18
+#define WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000
+#define WLAN_PLL_CONTROL_NOPWD_GET(x) (((x) & WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB)
+#define WLAN_PLL_CONTROL_NOPWD_SET(x) (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK)
+#define WLAN_PLL_CONTROL_UPDATING_MSB 17
+#define WLAN_PLL_CONTROL_UPDATING_LSB 17
+#define WLAN_PLL_CONTROL_UPDATING_MASK 0x00020000
+#define WLAN_PLL_CONTROL_UPDATING_GET(x) (((x) & WLAN_PLL_CONTROL_UPDATING_MASK) >> WLAN_PLL_CONTROL_UPDATING_LSB)
+#define WLAN_PLL_CONTROL_UPDATING_SET(x) (((x) << WLAN_PLL_CONTROL_UPDATING_LSB) & WLAN_PLL_CONTROL_UPDATING_MASK)
+#define WLAN_PLL_CONTROL_BYPASS_MSB 16
+#define WLAN_PLL_CONTROL_BYPASS_LSB 16
+#define WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000
+#define WLAN_PLL_CONTROL_BYPASS_GET(x) (((x) & WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB)
+#define WLAN_PLL_CONTROL_BYPASS_SET(x) (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK)
+#define WLAN_PLL_CONTROL_REFDIV_MSB 15
+#define WLAN_PLL_CONTROL_REFDIV_LSB 12
+#define WLAN_PLL_CONTROL_REFDIV_MASK 0x0000f000
+#define WLAN_PLL_CONTROL_REFDIV_GET(x) (((x) & WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB)
+#define WLAN_PLL_CONTROL_REFDIV_SET(x) (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK)
+#define WLAN_PLL_CONTROL_DIV_MSB 9
+#define WLAN_PLL_CONTROL_DIV_LSB 0
+#define WLAN_PLL_CONTROL_DIV_MASK 0x000003ff
+#define WLAN_PLL_CONTROL_DIV_GET(x) (((x) & WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB)
+#define WLAN_PLL_CONTROL_DIV_SET(x) (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK)
+
+#define WLAN_PLL_SETTLE_ADDRESS 0x00000018
+#define WLAN_PLL_SETTLE_OFFSET 0x00000018
+#define WLAN_PLL_SETTLE_TIME_MSB 11
+#define WLAN_PLL_SETTLE_TIME_LSB 0
+#define WLAN_PLL_SETTLE_TIME_MASK 0x00000fff
+#define WLAN_PLL_SETTLE_TIME_GET(x) (((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB)
+#define WLAN_PLL_SETTLE_TIME_SET(x) (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK)
+
+#define WLAN_XTAL_SETTLE_ADDRESS 0x0000001c
+#define WLAN_XTAL_SETTLE_OFFSET 0x0000001c
+#define WLAN_XTAL_SETTLE_TIME_MSB 7
+#define WLAN_XTAL_SETTLE_TIME_LSB 0
+#define WLAN_XTAL_SETTLE_TIME_MASK 0x000000ff
+#define WLAN_XTAL_SETTLE_TIME_GET(x) (((x) & WLAN_XTAL_SETTLE_TIME_MASK) >> WLAN_XTAL_SETTLE_TIME_LSB)
+#define WLAN_XTAL_SETTLE_TIME_SET(x) (((x) << WLAN_XTAL_SETTLE_TIME_LSB) & WLAN_XTAL_SETTLE_TIME_MASK)
+
+#define WLAN_CPU_CLOCK_ADDRESS 0x00000020
+#define WLAN_CPU_CLOCK_OFFSET 0x00000020
+#define WLAN_CPU_CLOCK_STANDARD_MSB 1
+#define WLAN_CPU_CLOCK_STANDARD_LSB 0
+#define WLAN_CPU_CLOCK_STANDARD_MASK 0x00000003
+#define WLAN_CPU_CLOCK_STANDARD_GET(x) (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB)
+#define WLAN_CPU_CLOCK_STANDARD_SET(x) (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK)
+
+#define WLAN_CLOCK_OUT_ADDRESS 0x00000024
+#define WLAN_CLOCK_OUT_OFFSET 0x00000024
+#define WLAN_CLOCK_OUT_SELECT_MSB 3
+#define WLAN_CLOCK_OUT_SELECT_LSB 0
+#define WLAN_CLOCK_OUT_SELECT_MASK 0x0000000f
+#define WLAN_CLOCK_OUT_SELECT_GET(x) (((x) & WLAN_CLOCK_OUT_SELECT_MASK) >> WLAN_CLOCK_OUT_SELECT_LSB)
+#define WLAN_CLOCK_OUT_SELECT_SET(x) (((x) << WLAN_CLOCK_OUT_SELECT_LSB) & WLAN_CLOCK_OUT_SELECT_MASK)
+
+#define WLAN_CLOCK_CONTROL_ADDRESS 0x00000028
+#define WLAN_CLOCK_CONTROL_OFFSET 0x00000028
+#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB 2
+#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB 2
+#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004
+#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB)
+#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK)
+#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB 0
+#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB 0
+#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001
+#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB)
+#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK)
+
+#define WLAN_BIAS_OVERRIDE_ADDRESS 0x0000002c
+#define WLAN_BIAS_OVERRIDE_OFFSET 0x0000002c
+#define WLAN_BIAS_OVERRIDE_ON_MSB 0
+#define WLAN_BIAS_OVERRIDE_ON_LSB 0
+#define WLAN_BIAS_OVERRIDE_ON_MASK 0x00000001
+#define WLAN_BIAS_OVERRIDE_ON_GET(x) (((x) & WLAN_BIAS_OVERRIDE_ON_MASK) >> WLAN_BIAS_OVERRIDE_ON_LSB)
+#define WLAN_BIAS_OVERRIDE_ON_SET(x) (((x) << WLAN_BIAS_OVERRIDE_ON_LSB) & WLAN_BIAS_OVERRIDE_ON_MASK)
+
+#define WLAN_WDT_CONTROL_ADDRESS 0x00000030
+#define WLAN_WDT_CONTROL_OFFSET 0x00000030
+#define WLAN_WDT_CONTROL_ACTION_MSB 2
+#define WLAN_WDT_CONTROL_ACTION_LSB 0
+#define WLAN_WDT_CONTROL_ACTION_MASK 0x00000007
+#define WLAN_WDT_CONTROL_ACTION_GET(x) (((x) & WLAN_WDT_CONTROL_ACTION_MASK) >> WLAN_WDT_CONTROL_ACTION_LSB)
+#define WLAN_WDT_CONTROL_ACTION_SET(x) (((x) << WLAN_WDT_CONTROL_ACTION_LSB) & WLAN_WDT_CONTROL_ACTION_MASK)
+
+#define WLAN_WDT_STATUS_ADDRESS 0x00000034
+#define WLAN_WDT_STATUS_OFFSET 0x00000034
+#define WLAN_WDT_STATUS_INTERRUPT_MSB 0
+#define WLAN_WDT_STATUS_INTERRUPT_LSB 0
+#define WLAN_WDT_STATUS_INTERRUPT_MASK 0x00000001
+#define WLAN_WDT_STATUS_INTERRUPT_GET(x) (((x) & WLAN_WDT_STATUS_INTERRUPT_MASK) >> WLAN_WDT_STATUS_INTERRUPT_LSB)
+#define WLAN_WDT_STATUS_INTERRUPT_SET(x) (((x) << WLAN_WDT_STATUS_INTERRUPT_LSB) & WLAN_WDT_STATUS_INTERRUPT_MASK)
+
+#define WLAN_WDT_ADDRESS 0x00000038
+#define WLAN_WDT_OFFSET 0x00000038
+#define WLAN_WDT_TARGET_MSB 21
+#define WLAN_WDT_TARGET_LSB 0
+#define WLAN_WDT_TARGET_MASK 0x003fffff
+#define WLAN_WDT_TARGET_GET(x) (((x) & WLAN_WDT_TARGET_MASK) >> WLAN_WDT_TARGET_LSB)
+#define WLAN_WDT_TARGET_SET(x) (((x) << WLAN_WDT_TARGET_LSB) & WLAN_WDT_TARGET_MASK)
+
+#define WLAN_WDT_COUNT_ADDRESS 0x0000003c
+#define WLAN_WDT_COUNT_OFFSET 0x0000003c
+#define WLAN_WDT_COUNT_VALUE_MSB 21
+#define WLAN_WDT_COUNT_VALUE_LSB 0
+#define WLAN_WDT_COUNT_VALUE_MASK 0x003fffff
+#define WLAN_WDT_COUNT_VALUE_GET(x) (((x) & WLAN_WDT_COUNT_VALUE_MASK) >> WLAN_WDT_COUNT_VALUE_LSB)
+#define WLAN_WDT_COUNT_VALUE_SET(x) (((x) << WLAN_WDT_COUNT_VALUE_LSB) & WLAN_WDT_COUNT_VALUE_MASK)
+
+#define WLAN_WDT_RESET_ADDRESS 0x00000040
+#define WLAN_WDT_RESET_OFFSET 0x00000040
+#define WLAN_WDT_RESET_VALUE_MSB 0
+#define WLAN_WDT_RESET_VALUE_LSB 0
+#define WLAN_WDT_RESET_VALUE_MASK 0x00000001
+#define WLAN_WDT_RESET_VALUE_GET(x) (((x) & WLAN_WDT_RESET_VALUE_MASK) >> WLAN_WDT_RESET_VALUE_LSB)
+#define WLAN_WDT_RESET_VALUE_SET(x) (((x) << WLAN_WDT_RESET_VALUE_LSB) & WLAN_WDT_RESET_VALUE_MASK)
+
+#define WLAN_INT_STATUS_ADDRESS 0x00000044
+#define WLAN_INT_STATUS_OFFSET 0x00000044
+#define WLAN_INT_STATUS_HCI_UART_MSB 21
+#define WLAN_INT_STATUS_HCI_UART_LSB 21
+#define WLAN_INT_STATUS_HCI_UART_MASK 0x00200000
+#define WLAN_INT_STATUS_HCI_UART_GET(x) (((x) & WLAN_INT_STATUS_HCI_UART_MASK) >> WLAN_INT_STATUS_HCI_UART_LSB)
+#define WLAN_INT_STATUS_HCI_UART_SET(x) (((x) << WLAN_INT_STATUS_HCI_UART_LSB) & WLAN_INT_STATUS_HCI_UART_MASK)
+#define WLAN_INT_STATUS_THERM_MSB 20
+#define WLAN_INT_STATUS_THERM_LSB 20
+#define WLAN_INT_STATUS_THERM_MASK 0x00100000
+#define WLAN_INT_STATUS_THERM_GET(x) (((x) & WLAN_INT_STATUS_THERM_MASK) >> WLAN_INT_STATUS_THERM_LSB)
+#define WLAN_INT_STATUS_THERM_SET(x) (((x) << WLAN_INT_STATUS_THERM_LSB) & WLAN_INT_STATUS_THERM_MASK)
+#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB 19
+#define WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB 19
+#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK 0x00080000
+#define WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x) (((x) & WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK) >> WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB)
+#define WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x) (((x) << WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB) & WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK)
+#define WLAN_INT_STATUS_UART_MBOX_MSB 18
+#define WLAN_INT_STATUS_UART_MBOX_LSB 18
+#define WLAN_INT_STATUS_UART_MBOX_MASK 0x00040000
+#define WLAN_INT_STATUS_UART_MBOX_GET(x) (((x) & WLAN_INT_STATUS_UART_MBOX_MASK) >> WLAN_INT_STATUS_UART_MBOX_LSB)
+#define WLAN_INT_STATUS_UART_MBOX_SET(x) (((x) << WLAN_INT_STATUS_UART_MBOX_LSB) & WLAN_INT_STATUS_UART_MBOX_MASK)
+#define WLAN_INT_STATUS_GENERIC_MBOX_MSB 17
+#define WLAN_INT_STATUS_GENERIC_MBOX_LSB 17
+#define WLAN_INT_STATUS_GENERIC_MBOX_MASK 0x00020000
+#define WLAN_INT_STATUS_GENERIC_MBOX_GET(x) (((x) & WLAN_INT_STATUS_GENERIC_MBOX_MASK) >> WLAN_INT_STATUS_GENERIC_MBOX_LSB)
+#define WLAN_INT_STATUS_GENERIC_MBOX_SET(x) (((x) << WLAN_INT_STATUS_GENERIC_MBOX_LSB) & WLAN_INT_STATUS_GENERIC_MBOX_MASK)
+#define WLAN_INT_STATUS_RDMA_MSB 16
+#define WLAN_INT_STATUS_RDMA_LSB 16
+#define WLAN_INT_STATUS_RDMA_MASK 0x00010000
+#define WLAN_INT_STATUS_RDMA_GET(x) (((x) & WLAN_INT_STATUS_RDMA_MASK) >> WLAN_INT_STATUS_RDMA_LSB)
+#define WLAN_INT_STATUS_RDMA_SET(x) (((x) << WLAN_INT_STATUS_RDMA_LSB) & WLAN_INT_STATUS_RDMA_MASK)
+#define WLAN_INT_STATUS_BTCOEX_MSB 15
+#define WLAN_INT_STATUS_BTCOEX_LSB 15
+#define WLAN_INT_STATUS_BTCOEX_MASK 0x00008000
+#define WLAN_INT_STATUS_BTCOEX_GET(x) (((x) & WLAN_INT_STATUS_BTCOEX_MASK) >> WLAN_INT_STATUS_BTCOEX_LSB)
+#define WLAN_INT_STATUS_BTCOEX_SET(x) (((x) << WLAN_INT_STATUS_BTCOEX_LSB) & WLAN_INT_STATUS_BTCOEX_MASK)
+#define WLAN_INT_STATUS_RTC_POWER_MSB 14
+#define WLAN_INT_STATUS_RTC_POWER_LSB 14
+#define WLAN_INT_STATUS_RTC_POWER_MASK 0x00004000
+#define WLAN_INT_STATUS_RTC_POWER_GET(x) (((x) & WLAN_INT_STATUS_RTC_POWER_MASK) >> WLAN_INT_STATUS_RTC_POWER_LSB)
+#define WLAN_INT_STATUS_RTC_POWER_SET(x) (((x) << WLAN_INT_STATUS_RTC_POWER_LSB) & WLAN_INT_STATUS_RTC_POWER_MASK)
+#define WLAN_INT_STATUS_MAC_MSB 13
+#define WLAN_INT_STATUS_MAC_LSB 13
+#define WLAN_INT_STATUS_MAC_MASK 0x00002000
+#define WLAN_INT_STATUS_MAC_GET(x) (((x) & WLAN_INT_STATUS_MAC_MASK) >> WLAN_INT_STATUS_MAC_LSB)
+#define WLAN_INT_STATUS_MAC_SET(x) (((x) << WLAN_INT_STATUS_MAC_LSB) & WLAN_INT_STATUS_MAC_MASK)
+#define WLAN_INT_STATUS_MAILBOX_MSB 12
+#define WLAN_INT_STATUS_MAILBOX_LSB 12
+#define WLAN_INT_STATUS_MAILBOX_MASK 0x00001000
+#define WLAN_INT_STATUS_MAILBOX_GET(x) (((x) & WLAN_INT_STATUS_MAILBOX_MASK) >> WLAN_INT_STATUS_MAILBOX_LSB)
+#define WLAN_INT_STATUS_MAILBOX_SET(x) (((x) << WLAN_INT_STATUS_MAILBOX_LSB) & WLAN_INT_STATUS_MAILBOX_MASK)
+#define WLAN_INT_STATUS_RTC_ALARM_MSB 11
+#define WLAN_INT_STATUS_RTC_ALARM_LSB 11
+#define WLAN_INT_STATUS_RTC_ALARM_MASK 0x00000800
+#define WLAN_INT_STATUS_RTC_ALARM_GET(x) (((x) & WLAN_INT_STATUS_RTC_ALARM_MASK) >> WLAN_INT_STATUS_RTC_ALARM_LSB)
+#define WLAN_INT_STATUS_RTC_ALARM_SET(x) (((x) << WLAN_INT_STATUS_RTC_ALARM_LSB) & WLAN_INT_STATUS_RTC_ALARM_MASK)
+#define WLAN_INT_STATUS_HF_TIMER_MSB 10
+#define WLAN_INT_STATUS_HF_TIMER_LSB 10
+#define WLAN_INT_STATUS_HF_TIMER_MASK 0x00000400
+#define WLAN_INT_STATUS_HF_TIMER_GET(x) (((x) & WLAN_INT_STATUS_HF_TIMER_MASK) >> WLAN_INT_STATUS_HF_TIMER_LSB)
+#define WLAN_INT_STATUS_HF_TIMER_SET(x) (((x) << WLAN_INT_STATUS_HF_TIMER_LSB) & WLAN_INT_STATUS_HF_TIMER_MASK)
+#define WLAN_INT_STATUS_LF_TIMER3_MSB 9
+#define WLAN_INT_STATUS_LF_TIMER3_LSB 9
+#define WLAN_INT_STATUS_LF_TIMER3_MASK 0x00000200
+#define WLAN_INT_STATUS_LF_TIMER3_GET(x) (((x) & WLAN_INT_STATUS_LF_TIMER3_MASK) >> WLAN_INT_STATUS_LF_TIMER3_LSB)
+#define WLAN_INT_STATUS_LF_TIMER3_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER3_LSB) & WLAN_INT_STATUS_LF_TIMER3_MASK)
+#define WLAN_INT_STATUS_LF_TIMER2_MSB 8
+#define WLAN_INT_STATUS_LF_TIMER2_LSB 8
+#define WLAN_INT_STATUS_LF_TIMER2_MASK 0x00000100
+#define WLAN_INT_STATUS_LF_TIMER2_GET(x) (((x) & WLAN_INT_STATUS_LF_TIMER2_MASK) >> WLAN_INT_STATUS_LF_TIMER2_LSB)
+#define WLAN_INT_STATUS_LF_TIMER2_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER2_LSB) & WLAN_INT_STATUS_LF_TIMER2_MASK)
+#define WLAN_INT_STATUS_LF_TIMER1_MSB 7
+#define WLAN_INT_STATUS_LF_TIMER1_LSB 7
+#define WLAN_INT_STATUS_LF_TIMER1_MASK 0x00000080
+#define WLAN_INT_STATUS_LF_TIMER1_GET(x) (((x) & WLAN_INT_STATUS_LF_TIMER1_MASK) >> WLAN_INT_STATUS_LF_TIMER1_LSB)
+#define WLAN_INT_STATUS_LF_TIMER1_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER1_LSB) & WLAN_INT_STATUS_LF_TIMER1_MASK)
+#define WLAN_INT_STATUS_LF_TIMER0_MSB 6
+#define WLAN_INT_STATUS_LF_TIMER0_LSB 6
+#define WLAN_INT_STATUS_LF_TIMER0_MASK 0x00000040
+#define WLAN_INT_STATUS_LF_TIMER0_GET(x) (((x) & WLAN_INT_STATUS_LF_TIMER0_MASK) >> WLAN_INT_STATUS_LF_TIMER0_LSB)
+#define WLAN_INT_STATUS_LF_TIMER0_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER0_LSB) & WLAN_INT_STATUS_LF_TIMER0_MASK)
+#define WLAN_INT_STATUS_KEYPAD_MSB 5
+#define WLAN_INT_STATUS_KEYPAD_LSB 5
+#define WLAN_INT_STATUS_KEYPAD_MASK 0x00000020
+#define WLAN_INT_STATUS_KEYPAD_GET(x) (((x) & WLAN_INT_STATUS_KEYPAD_MASK) >> WLAN_INT_STATUS_KEYPAD_LSB)
+#define WLAN_INT_STATUS_KEYPAD_SET(x) (((x) << WLAN_INT_STATUS_KEYPAD_LSB) & WLAN_INT_STATUS_KEYPAD_MASK)
+#define WLAN_INT_STATUS_SI_MSB 4
+#define WLAN_INT_STATUS_SI_LSB 4
+#define WLAN_INT_STATUS_SI_MASK 0x00000010
+#define WLAN_INT_STATUS_SI_GET(x) (((x) & WLAN_INT_STATUS_SI_MASK) >> WLAN_INT_STATUS_SI_LSB)
+#define WLAN_INT_STATUS_SI_SET(x) (((x) << WLAN_INT_STATUS_SI_LSB) & WLAN_INT_STATUS_SI_MASK)
+#define WLAN_INT_STATUS_GPIO_MSB 3
+#define WLAN_INT_STATUS_GPIO_LSB 3
+#define WLAN_INT_STATUS_GPIO_MASK 0x00000008
+#define WLAN_INT_STATUS_GPIO_GET(x) (((x) & WLAN_INT_STATUS_GPIO_MASK) >> WLAN_INT_STATUS_GPIO_LSB)
+#define WLAN_INT_STATUS_GPIO_SET(x) (((x) << WLAN_INT_STATUS_GPIO_LSB) & WLAN_INT_STATUS_GPIO_MASK)
+#define WLAN_INT_STATUS_UART_MSB 2
+#define WLAN_INT_STATUS_UART_LSB 2
+#define WLAN_INT_STATUS_UART_MASK 0x00000004
+#define WLAN_INT_STATUS_UART_GET(x) (((x) & WLAN_INT_STATUS_UART_MASK) >> WLAN_INT_STATUS_UART_LSB)
+#define WLAN_INT_STATUS_UART_SET(x) (((x) << WLAN_INT_STATUS_UART_LSB) & WLAN_INT_STATUS_UART_MASK)
+#define WLAN_INT_STATUS_ERROR_MSB 1
+#define WLAN_INT_STATUS_ERROR_LSB 1
+#define WLAN_INT_STATUS_ERROR_MASK 0x00000002
+#define WLAN_INT_STATUS_ERROR_GET(x) (((x) & WLAN_INT_STATUS_ERROR_MASK) >> WLAN_INT_STATUS_ERROR_LSB)
+#define WLAN_INT_STATUS_ERROR_SET(x) (((x) << WLAN_INT_STATUS_ERROR_LSB) & WLAN_INT_STATUS_ERROR_MASK)
+#define WLAN_INT_STATUS_WDT_INT_MSB 0
+#define WLAN_INT_STATUS_WDT_INT_LSB 0
+#define WLAN_INT_STATUS_WDT_INT_MASK 0x00000001
+#define WLAN_INT_STATUS_WDT_INT_GET(x) (((x) & WLAN_INT_STATUS_WDT_INT_MASK) >> WLAN_INT_STATUS_WDT_INT_LSB)
+#define WLAN_INT_STATUS_WDT_INT_SET(x) (((x) << WLAN_INT_STATUS_WDT_INT_LSB) & WLAN_INT_STATUS_WDT_INT_MASK)
+
+#define WLAN_LF_TIMER0_ADDRESS 0x00000048
+#define WLAN_LF_TIMER0_OFFSET 0x00000048
+#define WLAN_LF_TIMER0_TARGET_MSB 31
+#define WLAN_LF_TIMER0_TARGET_LSB 0
+#define WLAN_LF_TIMER0_TARGET_MASK 0xffffffff
+#define WLAN_LF_TIMER0_TARGET_GET(x) (((x) & WLAN_LF_TIMER0_TARGET_MASK) >> WLAN_LF_TIMER0_TARGET_LSB)
+#define WLAN_LF_TIMER0_TARGET_SET(x) (((x) << WLAN_LF_TIMER0_TARGET_LSB) & WLAN_LF_TIMER0_TARGET_MASK)
+
+#define WLAN_LF_TIMER_COUNT0_ADDRESS 0x0000004c
+#define WLAN_LF_TIMER_COUNT0_OFFSET 0x0000004c
+#define WLAN_LF_TIMER_COUNT0_VALUE_MSB 31
+#define WLAN_LF_TIMER_COUNT0_VALUE_LSB 0
+#define WLAN_LF_TIMER_COUNT0_VALUE_MASK 0xffffffff
+#define WLAN_LF_TIMER_COUNT0_VALUE_GET(x) (((x) & WLAN_LF_TIMER_COUNT0_VALUE_MASK) >> WLAN_LF_TIMER_COUNT0_VALUE_LSB)
+#define WLAN_LF_TIMER_COUNT0_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT0_VALUE_LSB) & WLAN_LF_TIMER_COUNT0_VALUE_MASK)
+
+#define WLAN_LF_TIMER_CONTROL0_ADDRESS 0x00000050
+#define WLAN_LF_TIMER_CONTROL0_OFFSET 0x00000050
+#define WLAN_LF_TIMER_CONTROL0_ENABLE_MSB 2
+#define WLAN_LF_TIMER_CONTROL0_ENABLE_LSB 2
+#define WLAN_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
+#define WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x) (((x) & WLAN_LF_TIMER_CONTROL0_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL0_ENABLE_LSB)
+#define WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x) (((x) << WLAN_LF_TIMER_CONTROL0_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL0_ENABLE_MASK)
+#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB 1
+#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB 1
+#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002
+#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB)
+#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK)
+#define WLAN_LF_TIMER_CONTROL0_RESET_MSB 0
+#define WLAN_LF_TIMER_CONTROL0_RESET_LSB 0
+#define WLAN_LF_TIMER_CONTROL0_RESET_MASK 0x00000001
+#define WLAN_LF_TIMER_CONTROL0_RESET_GET(x) (((x) & WLAN_LF_TIMER_CONTROL0_RESET_MASK) >> WLAN_LF_TIMER_CONTROL0_RESET_LSB)
+#define WLAN_LF_TIMER_CONTROL0_RESET_SET(x) (((x) << WLAN_LF_TIMER_CONTROL0_RESET_LSB) & WLAN_LF_TIMER_CONTROL0_RESET_MASK)
+
+#define WLAN_LF_TIMER_STATUS0_ADDRESS 0x00000054
+#define WLAN_LF_TIMER_STATUS0_OFFSET 0x00000054
+#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB 0
+#define WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB 0
+#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK 0x00000001
+#define WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x) (((x) & WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB)
+#define WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x) (((x) << WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK)
+
+#define WLAN_LF_TIMER1_ADDRESS 0x00000058
+#define WLAN_LF_TIMER1_OFFSET 0x00000058
+#define WLAN_LF_TIMER1_TARGET_MSB 31
+#define WLAN_LF_TIMER1_TARGET_LSB 0
+#define WLAN_LF_TIMER1_TARGET_MASK 0xffffffff
+#define WLAN_LF_TIMER1_TARGET_GET(x) (((x) & WLAN_LF_TIMER1_TARGET_MASK) >> WLAN_LF_TIMER1_TARGET_LSB)
+#define WLAN_LF_TIMER1_TARGET_SET(x) (((x) << WLAN_LF_TIMER1_TARGET_LSB) & WLAN_LF_TIMER1_TARGET_MASK)
+
+#define WLAN_LF_TIMER_COUNT1_ADDRESS 0x0000005c
+#define WLAN_LF_TIMER_COUNT1_OFFSET 0x0000005c
+#define WLAN_LF_TIMER_COUNT1_VALUE_MSB 31
+#define WLAN_LF_TIMER_COUNT1_VALUE_LSB 0
+#define WLAN_LF_TIMER_COUNT1_VALUE_MASK 0xffffffff
+#define WLAN_LF_TIMER_COUNT1_VALUE_GET(x) (((x) & WLAN_LF_TIMER_COUNT1_VALUE_MASK) >> WLAN_LF_TIMER_COUNT1_VALUE_LSB)
+#define WLAN_LF_TIMER_COUNT1_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT1_VALUE_LSB) & WLAN_LF_TIMER_COUNT1_VALUE_MASK)
+
+#define WLAN_LF_TIMER_CONTROL1_ADDRESS 0x00000060
+#define WLAN_LF_TIMER_CONTROL1_OFFSET 0x00000060
+#define WLAN_LF_TIMER_CONTROL1_ENABLE_MSB 2
+#define WLAN_LF_TIMER_CONTROL1_ENABLE_LSB 2
+#define WLAN_LF_TIMER_CONTROL1_ENABLE_MASK 0x00000004
+#define WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x) (((x) & WLAN_LF_TIMER_CONTROL1_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL1_ENABLE_LSB)
+#define WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x) (((x) << WLAN_LF_TIMER_CONTROL1_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL1_ENABLE_MASK)
+#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB 1
+#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB 1
+#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002
+#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB)
+#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK)
+#define WLAN_LF_TIMER_CONTROL1_RESET_MSB 0
+#define WLAN_LF_TIMER_CONTROL1_RESET_LSB 0
+#define WLAN_LF_TIMER_CONTROL1_RESET_MASK 0x00000001
+#define WLAN_LF_TIMER_CONTROL1_RESET_GET(x) (((x) & WLAN_LF_TIMER_CONTROL1_RESET_MASK) >> WLAN_LF_TIMER_CONTROL1_RESET_LSB)
+#define WLAN_LF_TIMER_CONTROL1_RESET_SET(x) (((x) << WLAN_LF_TIMER_CONTROL1_RESET_LSB) & WLAN_LF_TIMER_CONTROL1_RESET_MASK)
+
+#define WLAN_LF_TIMER_STATUS1_ADDRESS 0x00000064
+#define WLAN_LF_TIMER_STATUS1_OFFSET 0x00000064
+#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB 0
+#define WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB 0
+#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK 0x00000001
+#define WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x) (((x) & WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB)
+#define WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x) (((x) << WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK)
+
+#define WLAN_LF_TIMER2_ADDRESS 0x00000068
+#define WLAN_LF_TIMER2_OFFSET 0x00000068
+#define WLAN_LF_TIMER2_TARGET_MSB 31
+#define WLAN_LF_TIMER2_TARGET_LSB 0
+#define WLAN_LF_TIMER2_TARGET_MASK 0xffffffff
+#define WLAN_LF_TIMER2_TARGET_GET(x) (((x) & WLAN_LF_TIMER2_TARGET_MASK) >> WLAN_LF_TIMER2_TARGET_LSB)
+#define WLAN_LF_TIMER2_TARGET_SET(x) (((x) << WLAN_LF_TIMER2_TARGET_LSB) & WLAN_LF_TIMER2_TARGET_MASK)
+
+#define WLAN_LF_TIMER_COUNT2_ADDRESS 0x0000006c
+#define WLAN_LF_TIMER_COUNT2_OFFSET 0x0000006c
+#define WLAN_LF_TIMER_COUNT2_VALUE_MSB 31
+#define WLAN_LF_TIMER_COUNT2_VALUE_LSB 0
+#define WLAN_LF_TIMER_COUNT2_VALUE_MASK 0xffffffff
+#define WLAN_LF_TIMER_COUNT2_VALUE_GET(x) (((x) & WLAN_LF_TIMER_COUNT2_VALUE_MASK) >> WLAN_LF_TIMER_COUNT2_VALUE_LSB)
+#define WLAN_LF_TIMER_COUNT2_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT2_VALUE_LSB) & WLAN_LF_TIMER_COUNT2_VALUE_MASK)
+
+#define WLAN_LF_TIMER_CONTROL2_ADDRESS 0x00000070
+#define WLAN_LF_TIMER_CONTROL2_OFFSET 0x00000070
+#define WLAN_LF_TIMER_CONTROL2_ENABLE_MSB 2
+#define WLAN_LF_TIMER_CONTROL2_ENABLE_LSB 2
+#define WLAN_LF_TIMER_CONTROL2_ENABLE_MASK 0x00000004
+#define WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x) (((x) & WLAN_LF_TIMER_CONTROL2_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL2_ENABLE_LSB)
+#define WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x) (((x) << WLAN_LF_TIMER_CONTROL2_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL2_ENABLE_MASK)
+#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB 1
+#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB 1
+#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002
+#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB)
+#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK)
+#define WLAN_LF_TIMER_CONTROL2_RESET_MSB 0
+#define WLAN_LF_TIMER_CONTROL2_RESET_LSB 0
+#define WLAN_LF_TIMER_CONTROL2_RESET_MASK 0x00000001
+#define WLAN_LF_TIMER_CONTROL2_RESET_GET(x) (((x) & WLAN_LF_TIMER_CONTROL2_RESET_MASK) >> WLAN_LF_TIMER_CONTROL2_RESET_LSB)
+#define WLAN_LF_TIMER_CONTROL2_RESET_SET(x) (((x) << WLAN_LF_TIMER_CONTROL2_RESET_LSB) & WLAN_LF_TIMER_CONTROL2_RESET_MASK)
+
+#define WLAN_LF_TIMER_STATUS2_ADDRESS 0x00000074
+#define WLAN_LF_TIMER_STATUS2_OFFSET 0x00000074
+#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB 0
+#define WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB 0
+#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK 0x00000001
+#define WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x) (((x) & WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB)
+#define WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x) (((x) << WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK)
+
+#define WLAN_LF_TIMER3_ADDRESS 0x00000078
+#define WLAN_LF_TIMER3_OFFSET 0x00000078
+#define WLAN_LF_TIMER3_TARGET_MSB 31
+#define WLAN_LF_TIMER3_TARGET_LSB 0
+#define WLAN_LF_TIMER3_TARGET_MASK 0xffffffff
+#define WLAN_LF_TIMER3_TARGET_GET(x) (((x) & WLAN_LF_TIMER3_TARGET_MASK) >> WLAN_LF_TIMER3_TARGET_LSB)
+#define WLAN_LF_TIMER3_TARGET_SET(x) (((x) << WLAN_LF_TIMER3_TARGET_LSB) & WLAN_LF_TIMER3_TARGET_MASK)
+
+#define WLAN_LF_TIMER_COUNT3_ADDRESS 0x0000007c
+#define WLAN_LF_TIMER_COUNT3_OFFSET 0x0000007c
+#define WLAN_LF_TIMER_COUNT3_VALUE_MSB 31
+#define WLAN_LF_TIMER_COUNT3_VALUE_LSB 0
+#define WLAN_LF_TIMER_COUNT3_VALUE_MASK 0xffffffff
+#define WLAN_LF_TIMER_COUNT3_VALUE_GET(x) (((x) & WLAN_LF_TIMER_COUNT3_VALUE_MASK) >> WLAN_LF_TIMER_COUNT3_VALUE_LSB)
+#define WLAN_LF_TIMER_COUNT3_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT3_VALUE_LSB) & WLAN_LF_TIMER_COUNT3_VALUE_MASK)
+
+#define WLAN_LF_TIMER_CONTROL3_ADDRESS 0x00000080
+#define WLAN_LF_TIMER_CONTROL3_OFFSET 0x00000080
+#define WLAN_LF_TIMER_CONTROL3_ENABLE_MSB 2
+#define WLAN_LF_TIMER_CONTROL3_ENABLE_LSB 2
+#define WLAN_LF_TIMER_CONTROL3_ENABLE_MASK 0x00000004
+#define WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x) (((x) & WLAN_LF_TIMER_CONTROL3_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL3_ENABLE_LSB)
+#define WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x) (((x) << WLAN_LF_TIMER_CONTROL3_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL3_ENABLE_MASK)
+#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB 1
+#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB 1
+#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002
+#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB)
+#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK)
+#define WLAN_LF_TIMER_CONTROL3_RESET_MSB 0
+#define WLAN_LF_TIMER_CONTROL3_RESET_LSB 0
+#define WLAN_LF_TIMER_CONTROL3_RESET_MASK 0x00000001
+#define WLAN_LF_TIMER_CONTROL3_RESET_GET(x) (((x) & WLAN_LF_TIMER_CONTROL3_RESET_MASK) >> WLAN_LF_TIMER_CONTROL3_RESET_LSB)
+#define WLAN_LF_TIMER_CONTROL3_RESET_SET(x) (((x) << WLAN_LF_TIMER_CONTROL3_RESET_LSB) & WLAN_LF_TIMER_CONTROL3_RESET_MASK)
+
+#define WLAN_LF_TIMER_STATUS3_ADDRESS 0x00000084
+#define WLAN_LF_TIMER_STATUS3_OFFSET 0x00000084
+#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB 0
+#define WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB 0
+#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK 0x00000001
+#define WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x) (((x) & WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB)
+#define WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x) (((x) << WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK)
+
+#define WLAN_HF_TIMER_ADDRESS 0x00000088
+#define WLAN_HF_TIMER_OFFSET 0x00000088
+#define WLAN_HF_TIMER_TARGET_MSB 31
+#define WLAN_HF_TIMER_TARGET_LSB 12
+#define WLAN_HF_TIMER_TARGET_MASK 0xfffff000
+#define WLAN_HF_TIMER_TARGET_GET(x) (((x) & WLAN_HF_TIMER_TARGET_MASK) >> WLAN_HF_TIMER_TARGET_LSB)
+#define WLAN_HF_TIMER_TARGET_SET(x) (((x) << WLAN_HF_TIMER_TARGET_LSB) & WLAN_HF_TIMER_TARGET_MASK)
+
+#define WLAN_HF_TIMER_COUNT_ADDRESS 0x0000008c
+#define WLAN_HF_TIMER_COUNT_OFFSET 0x0000008c
+#define WLAN_HF_TIMER_COUNT_VALUE_MSB 31
+#define WLAN_HF_TIMER_COUNT_VALUE_LSB 12
+#define WLAN_HF_TIMER_COUNT_VALUE_MASK 0xfffff000
+#define WLAN_HF_TIMER_COUNT_VALUE_GET(x) (((x) & WLAN_HF_TIMER_COUNT_VALUE_MASK) >> WLAN_HF_TIMER_COUNT_VALUE_LSB)
+#define WLAN_HF_TIMER_COUNT_VALUE_SET(x) (((x) << WLAN_HF_TIMER_COUNT_VALUE_LSB) & WLAN_HF_TIMER_COUNT_VALUE_MASK)
+
+#define WLAN_HF_LF_COUNT_ADDRESS 0x00000090
+#define WLAN_HF_LF_COUNT_OFFSET 0x00000090
+#define WLAN_HF_LF_COUNT_VALUE_MSB 31
+#define WLAN_HF_LF_COUNT_VALUE_LSB 0
+#define WLAN_HF_LF_COUNT_VALUE_MASK 0xffffffff
+#define WLAN_HF_LF_COUNT_VALUE_GET(x) (((x) & WLAN_HF_LF_COUNT_VALUE_MASK) >> WLAN_HF_LF_COUNT_VALUE_LSB)
+#define WLAN_HF_LF_COUNT_VALUE_SET(x) (((x) << WLAN_HF_LF_COUNT_VALUE_LSB) & WLAN_HF_LF_COUNT_VALUE_MASK)
+
+#define WLAN_HF_TIMER_CONTROL_ADDRESS 0x00000094
+#define WLAN_HF_TIMER_CONTROL_OFFSET 0x00000094
+#define WLAN_HF_TIMER_CONTROL_ENABLE_MSB 3
+#define WLAN_HF_TIMER_CONTROL_ENABLE_LSB 3
+#define WLAN_HF_TIMER_CONTROL_ENABLE_MASK 0x00000008
+#define WLAN_HF_TIMER_CONTROL_ENABLE_GET(x) (((x) & WLAN_HF_TIMER_CONTROL_ENABLE_MASK) >> WLAN_HF_TIMER_CONTROL_ENABLE_LSB)
+#define WLAN_HF_TIMER_CONTROL_ENABLE_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_ENABLE_LSB) & WLAN_HF_TIMER_CONTROL_ENABLE_MASK)
+#define WLAN_HF_TIMER_CONTROL_ON_MSB 2
+#define WLAN_HF_TIMER_CONTROL_ON_LSB 2
+#define WLAN_HF_TIMER_CONTROL_ON_MASK 0x00000004
+#define WLAN_HF_TIMER_CONTROL_ON_GET(x) (((x) & WLAN_HF_TIMER_CONTROL_ON_MASK) >> WLAN_HF_TIMER_CONTROL_ON_LSB)
+#define WLAN_HF_TIMER_CONTROL_ON_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_ON_LSB) & WLAN_HF_TIMER_CONTROL_ON_MASK)
+#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB 1
+#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB 1
+#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK 0x00000002
+#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x) (((x) & WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB)
+#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB) & WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK)
+#define WLAN_HF_TIMER_CONTROL_RESET_MSB 0
+#define WLAN_HF_TIMER_CONTROL_RESET_LSB 0
+#define WLAN_HF_TIMER_CONTROL_RESET_MASK 0x00000001
+#define WLAN_HF_TIMER_CONTROL_RESET_GET(x) (((x) & WLAN_HF_TIMER_CONTROL_RESET_MASK) >> WLAN_HF_TIMER_CONTROL_RESET_LSB)
+#define WLAN_HF_TIMER_CONTROL_RESET_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_RESET_LSB) & WLAN_HF_TIMER_CONTROL_RESET_MASK)
+
+#define WLAN_HF_TIMER_STATUS_ADDRESS 0x00000098
+#define WLAN_HF_TIMER_STATUS_OFFSET 0x00000098
+#define WLAN_HF_TIMER_STATUS_INTERRUPT_MSB 0
+#define WLAN_HF_TIMER_STATUS_INTERRUPT_LSB 0
+#define WLAN_HF_TIMER_STATUS_INTERRUPT_MASK 0x00000001
+#define WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x) (((x) & WLAN_HF_TIMER_STATUS_INTERRUPT_MASK) >> WLAN_HF_TIMER_STATUS_INTERRUPT_LSB)
+#define WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x) (((x) << WLAN_HF_TIMER_STATUS_INTERRUPT_LSB) & WLAN_HF_TIMER_STATUS_INTERRUPT_MASK)
+
+#define WLAN_RTC_CONTROL_ADDRESS 0x0000009c
+#define WLAN_RTC_CONTROL_OFFSET 0x0000009c
+#define WLAN_RTC_CONTROL_ENABLE_MSB 2
+#define WLAN_RTC_CONTROL_ENABLE_LSB 2
+#define WLAN_RTC_CONTROL_ENABLE_MASK 0x00000004
+#define WLAN_RTC_CONTROL_ENABLE_GET(x) (((x) & WLAN_RTC_CONTROL_ENABLE_MASK) >> WLAN_RTC_CONTROL_ENABLE_LSB)
+#define WLAN_RTC_CONTROL_ENABLE_SET(x) (((x) << WLAN_RTC_CONTROL_ENABLE_LSB) & WLAN_RTC_CONTROL_ENABLE_MASK)
+#define WLAN_RTC_CONTROL_LOAD_RTC_MSB 1
+#define WLAN_RTC_CONTROL_LOAD_RTC_LSB 1
+#define WLAN_RTC_CONTROL_LOAD_RTC_MASK 0x00000002
+#define WLAN_RTC_CONTROL_LOAD_RTC_GET(x) (((x) & WLAN_RTC_CONTROL_LOAD_RTC_MASK) >> WLAN_RTC_CONTROL_LOAD_RTC_LSB)
+#define WLAN_RTC_CONTROL_LOAD_RTC_SET(x) (((x) << WLAN_RTC_CONTROL_LOAD_RTC_LSB) & WLAN_RTC_CONTROL_LOAD_RTC_MASK)
+#define WLAN_RTC_CONTROL_LOAD_ALARM_MSB 0
+#define WLAN_RTC_CONTROL_LOAD_ALARM_LSB 0
+#define WLAN_RTC_CONTROL_LOAD_ALARM_MASK 0x00000001
+#define WLAN_RTC_CONTROL_LOAD_ALARM_GET(x) (((x) & WLAN_RTC_CONTROL_LOAD_ALARM_MASK) >> WLAN_RTC_CONTROL_LOAD_ALARM_LSB)
+#define WLAN_RTC_CONTROL_LOAD_ALARM_SET(x) (((x) << WLAN_RTC_CONTROL_LOAD_ALARM_LSB) & WLAN_RTC_CONTROL_LOAD_ALARM_MASK)
+
+#define WLAN_RTC_TIME_ADDRESS 0x000000a0
+#define WLAN_RTC_TIME_OFFSET 0x000000a0
+#define WLAN_RTC_TIME_WEEK_DAY_MSB 26
+#define WLAN_RTC_TIME_WEEK_DAY_LSB 24
+#define WLAN_RTC_TIME_WEEK_DAY_MASK 0x07000000
+#define WLAN_RTC_TIME_WEEK_DAY_GET(x) (((x) & WLAN_RTC_TIME_WEEK_DAY_MASK) >> WLAN_RTC_TIME_WEEK_DAY_LSB)
+#define WLAN_RTC_TIME_WEEK_DAY_SET(x) (((x) << WLAN_RTC_TIME_WEEK_DAY_LSB) & WLAN_RTC_TIME_WEEK_DAY_MASK)
+#define WLAN_RTC_TIME_HOUR_MSB 21
+#define WLAN_RTC_TIME_HOUR_LSB 16
+#define WLAN_RTC_TIME_HOUR_MASK 0x003f0000
+#define WLAN_RTC_TIME_HOUR_GET(x) (((x) & WLAN_RTC_TIME_HOUR_MASK) >> WLAN_RTC_TIME_HOUR_LSB)
+#define WLAN_RTC_TIME_HOUR_SET(x) (((x) << WLAN_RTC_TIME_HOUR_LSB) & WLAN_RTC_TIME_HOUR_MASK)
+#define WLAN_RTC_TIME_MINUTE_MSB 14
+#define WLAN_RTC_TIME_MINUTE_LSB 8
+#define WLAN_RTC_TIME_MINUTE_MASK 0x00007f00
+#define WLAN_RTC_TIME_MINUTE_GET(x) (((x) & WLAN_RTC_TIME_MINUTE_MASK) >> WLAN_RTC_TIME_MINUTE_LSB)
+#define WLAN_RTC_TIME_MINUTE_SET(x) (((x) << WLAN_RTC_TIME_MINUTE_LSB) & WLAN_RTC_TIME_MINUTE_MASK)
+#define WLAN_RTC_TIME_SECOND_MSB 6
+#define WLAN_RTC_TIME_SECOND_LSB 0
+#define WLAN_RTC_TIME_SECOND_MASK 0x0000007f
+#define WLAN_RTC_TIME_SECOND_GET(x) (((x) & WLAN_RTC_TIME_SECOND_MASK) >> WLAN_RTC_TIME_SECOND_LSB)
+#define WLAN_RTC_TIME_SECOND_SET(x) (((x) << WLAN_RTC_TIME_SECOND_LSB) & WLAN_RTC_TIME_SECOND_MASK)
+
+#define WLAN_RTC_DATE_ADDRESS 0x000000a4
+#define WLAN_RTC_DATE_OFFSET 0x000000a4
+#define WLAN_RTC_DATE_YEAR_MSB 23
+#define WLAN_RTC_DATE_YEAR_LSB 16
+#define WLAN_RTC_DATE_YEAR_MASK 0x00ff0000
+#define WLAN_RTC_DATE_YEAR_GET(x) (((x) & WLAN_RTC_DATE_YEAR_MASK) >> WLAN_RTC_DATE_YEAR_LSB)
+#define WLAN_RTC_DATE_YEAR_SET(x) (((x) << WLAN_RTC_DATE_YEAR_LSB) & WLAN_RTC_DATE_YEAR_MASK)
+#define WLAN_RTC_DATE_MONTH_MSB 12
+#define WLAN_RTC_DATE_MONTH_LSB 8
+#define WLAN_RTC_DATE_MONTH_MASK 0x00001f00
+#define WLAN_RTC_DATE_MONTH_GET(x) (((x) & WLAN_RTC_DATE_MONTH_MASK) >> WLAN_RTC_DATE_MONTH_LSB)
+#define WLAN_RTC_DATE_MONTH_SET(x) (((x) << WLAN_RTC_DATE_MONTH_LSB) & WLAN_RTC_DATE_MONTH_MASK)
+#define WLAN_RTC_DATE_MONTH_DAY_MSB 5
+#define WLAN_RTC_DATE_MONTH_DAY_LSB 0
+#define WLAN_RTC_DATE_MONTH_DAY_MASK 0x0000003f
+#define WLAN_RTC_DATE_MONTH_DAY_GET(x) (((x) & WLAN_RTC_DATE_MONTH_DAY_MASK) >> WLAN_RTC_DATE_MONTH_DAY_LSB)
+#define WLAN_RTC_DATE_MONTH_DAY_SET(x) (((x) << WLAN_RTC_DATE_MONTH_DAY_LSB) & WLAN_RTC_DATE_MONTH_DAY_MASK)
+
+#define WLAN_RTC_SET_TIME_ADDRESS 0x000000a8
+#define WLAN_RTC_SET_TIME_OFFSET 0x000000a8
+#define WLAN_RTC_SET_TIME_WEEK_DAY_MSB 26
+#define WLAN_RTC_SET_TIME_WEEK_DAY_LSB 24
+#define WLAN_RTC_SET_TIME_WEEK_DAY_MASK 0x07000000
+#define WLAN_RTC_SET_TIME_WEEK_DAY_GET(x) (((x) & WLAN_RTC_SET_TIME_WEEK_DAY_MASK) >> WLAN_RTC_SET_TIME_WEEK_DAY_LSB)
+#define WLAN_RTC_SET_TIME_WEEK_DAY_SET(x) (((x) << WLAN_RTC_SET_TIME_WEEK_DAY_LSB) & WLAN_RTC_SET_TIME_WEEK_DAY_MASK)
+#define WLAN_RTC_SET_TIME_HOUR_MSB 21
+#define WLAN_RTC_SET_TIME_HOUR_LSB 16
+#define WLAN_RTC_SET_TIME_HOUR_MASK 0x003f0000
+#define WLAN_RTC_SET_TIME_HOUR_GET(x) (((x) & WLAN_RTC_SET_TIME_HOUR_MASK) >> WLAN_RTC_SET_TIME_HOUR_LSB)
+#define WLAN_RTC_SET_TIME_HOUR_SET(x) (((x) << WLAN_RTC_SET_TIME_HOUR_LSB) & WLAN_RTC_SET_TIME_HOUR_MASK)
+#define WLAN_RTC_SET_TIME_MINUTE_MSB 14
+#define WLAN_RTC_SET_TIME_MINUTE_LSB 8
+#define WLAN_RTC_SET_TIME_MINUTE_MASK 0x00007f00
+#define WLAN_RTC_SET_TIME_MINUTE_GET(x) (((x) & WLAN_RTC_SET_TIME_MINUTE_MASK) >> WLAN_RTC_SET_TIME_MINUTE_LSB)
+#define WLAN_RTC_SET_TIME_MINUTE_SET(x) (((x) << WLAN_RTC_SET_TIME_MINUTE_LSB) & WLAN_RTC_SET_TIME_MINUTE_MASK)
+#define WLAN_RTC_SET_TIME_SECOND_MSB 6
+#define WLAN_RTC_SET_TIME_SECOND_LSB 0
+#define WLAN_RTC_SET_TIME_SECOND_MASK 0x0000007f
+#define WLAN_RTC_SET_TIME_SECOND_GET(x) (((x) & WLAN_RTC_SET_TIME_SECOND_MASK) >> WLAN_RTC_SET_TIME_SECOND_LSB)
+#define WLAN_RTC_SET_TIME_SECOND_SET(x) (((x) << WLAN_RTC_SET_TIME_SECOND_LSB) & WLAN_RTC_SET_TIME_SECOND_MASK)
+
+#define WLAN_RTC_SET_DATE_ADDRESS 0x000000ac
+#define WLAN_RTC_SET_DATE_OFFSET 0x000000ac
+#define WLAN_RTC_SET_DATE_YEAR_MSB 23
+#define WLAN_RTC_SET_DATE_YEAR_LSB 16
+#define WLAN_RTC_SET_DATE_YEAR_MASK 0x00ff0000
+#define WLAN_RTC_SET_DATE_YEAR_GET(x) (((x) & WLAN_RTC_SET_DATE_YEAR_MASK) >> WLAN_RTC_SET_DATE_YEAR_LSB)
+#define WLAN_RTC_SET_DATE_YEAR_SET(x) (((x) << WLAN_RTC_SET_DATE_YEAR_LSB) & WLAN_RTC_SET_DATE_YEAR_MASK)
+#define WLAN_RTC_SET_DATE_MONTH_MSB 12
+#define WLAN_RTC_SET_DATE_MONTH_LSB 8
+#define WLAN_RTC_SET_DATE_MONTH_MASK 0x00001f00
+#define WLAN_RTC_SET_DATE_MONTH_GET(x) (((x) & WLAN_RTC_SET_DATE_MONTH_MASK) >> WLAN_RTC_SET_DATE_MONTH_LSB)
+#define WLAN_RTC_SET_DATE_MONTH_SET(x) (((x) << WLAN_RTC_SET_DATE_MONTH_LSB) & WLAN_RTC_SET_DATE_MONTH_MASK)
+#define WLAN_RTC_SET_DATE_MONTH_DAY_MSB 5
+#define WLAN_RTC_SET_DATE_MONTH_DAY_LSB 0
+#define WLAN_RTC_SET_DATE_MONTH_DAY_MASK 0x0000003f
+#define WLAN_RTC_SET_DATE_MONTH_DAY_GET(x) (((x) & WLAN_RTC_SET_DATE_MONTH_DAY_MASK) >> WLAN_RTC_SET_DATE_MONTH_DAY_LSB)
+#define WLAN_RTC_SET_DATE_MONTH_DAY_SET(x) (((x) << WLAN_RTC_SET_DATE_MONTH_DAY_LSB) & WLAN_RTC_SET_DATE_MONTH_DAY_MASK)
+
+#define WLAN_RTC_SET_ALARM_ADDRESS 0x000000b0
+#define WLAN_RTC_SET_ALARM_OFFSET 0x000000b0
+#define WLAN_RTC_SET_ALARM_HOUR_MSB 21
+#define WLAN_RTC_SET_ALARM_HOUR_LSB 16
+#define WLAN_RTC_SET_ALARM_HOUR_MASK 0x003f0000
+#define WLAN_RTC_SET_ALARM_HOUR_GET(x) (((x) & WLAN_RTC_SET_ALARM_HOUR_MASK) >> WLAN_RTC_SET_ALARM_HOUR_LSB)
+#define WLAN_RTC_SET_ALARM_HOUR_SET(x) (((x) << WLAN_RTC_SET_ALARM_HOUR_LSB) & WLAN_RTC_SET_ALARM_HOUR_MASK)
+#define WLAN_RTC_SET_ALARM_MINUTE_MSB 14
+#define WLAN_RTC_SET_ALARM_MINUTE_LSB 8
+#define WLAN_RTC_SET_ALARM_MINUTE_MASK 0x00007f00
+#define WLAN_RTC_SET_ALARM_MINUTE_GET(x) (((x) & WLAN_RTC_SET_ALARM_MINUTE_MASK) >> WLAN_RTC_SET_ALARM_MINUTE_LSB)
+#define WLAN_RTC_SET_ALARM_MINUTE_SET(x) (((x) << WLAN_RTC_SET_ALARM_MINUTE_LSB) & WLAN_RTC_SET_ALARM_MINUTE_MASK)
+#define WLAN_RTC_SET_ALARM_SECOND_MSB 6
+#define WLAN_RTC_SET_ALARM_SECOND_LSB 0
+#define WLAN_RTC_SET_ALARM_SECOND_MASK 0x0000007f
+#define WLAN_RTC_SET_ALARM_SECOND_GET(x) (((x) & WLAN_RTC_SET_ALARM_SECOND_MASK) >> WLAN_RTC_SET_ALARM_SECOND_LSB)
+#define WLAN_RTC_SET_ALARM_SECOND_SET(x) (((x) << WLAN_RTC_SET_ALARM_SECOND_LSB) & WLAN_RTC_SET_ALARM_SECOND_MASK)
+
+#define WLAN_RTC_CONFIG_ADDRESS 0x000000b4
+#define WLAN_RTC_CONFIG_OFFSET 0x000000b4
+#define WLAN_RTC_CONFIG_BCD_MSB 2
+#define WLAN_RTC_CONFIG_BCD_LSB 2
+#define WLAN_RTC_CONFIG_BCD_MASK 0x00000004
+#define WLAN_RTC_CONFIG_BCD_GET(x) (((x) & WLAN_RTC_CONFIG_BCD_MASK) >> WLAN_RTC_CONFIG_BCD_LSB)
+#define WLAN_RTC_CONFIG_BCD_SET(x) (((x) << WLAN_RTC_CONFIG_BCD_LSB) & WLAN_RTC_CONFIG_BCD_MASK)
+#define WLAN_RTC_CONFIG_TWELVE_HOUR_MSB 1
+#define WLAN_RTC_CONFIG_TWELVE_HOUR_LSB 1
+#define WLAN_RTC_CONFIG_TWELVE_HOUR_MASK 0x00000002
+#define WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x) (((x) & WLAN_RTC_CONFIG_TWELVE_HOUR_MASK) >> WLAN_RTC_CONFIG_TWELVE_HOUR_LSB)
+#define WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x) (((x) << WLAN_RTC_CONFIG_TWELVE_HOUR_LSB) & WLAN_RTC_CONFIG_TWELVE_HOUR_MASK)
+#define WLAN_RTC_CONFIG_DSE_MSB 0
+#define WLAN_RTC_CONFIG_DSE_LSB 0
+#define WLAN_RTC_CONFIG_DSE_MASK 0x00000001
+#define WLAN_RTC_CONFIG_DSE_GET(x) (((x) & WLAN_RTC_CONFIG_DSE_MASK) >> WLAN_RTC_CONFIG_DSE_LSB)
+#define WLAN_RTC_CONFIG_DSE_SET(x) (((x) << WLAN_RTC_CONFIG_DSE_LSB) & WLAN_RTC_CONFIG_DSE_MASK)
+
+#define WLAN_RTC_ALARM_STATUS_ADDRESS 0x000000b8
+#define WLAN_RTC_ALARM_STATUS_OFFSET 0x000000b8
+#define WLAN_RTC_ALARM_STATUS_ENABLE_MSB 1
+#define WLAN_RTC_ALARM_STATUS_ENABLE_LSB 1
+#define WLAN_RTC_ALARM_STATUS_ENABLE_MASK 0x00000002
+#define WLAN_RTC_ALARM_STATUS_ENABLE_GET(x) (((x) & WLAN_RTC_ALARM_STATUS_ENABLE_MASK) >> WLAN_RTC_ALARM_STATUS_ENABLE_LSB)
+#define WLAN_RTC_ALARM_STATUS_ENABLE_SET(x) (((x) << WLAN_RTC_ALARM_STATUS_ENABLE_LSB) & WLAN_RTC_ALARM_STATUS_ENABLE_MASK)
+#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB 0
+#define WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB 0
+#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK 0x00000001
+#define WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x) (((x) & WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK) >> WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB)
+#define WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x) (((x) << WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB) & WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK)
+
+#define WLAN_UART_WAKEUP_ADDRESS 0x000000bc
+#define WLAN_UART_WAKEUP_OFFSET 0x000000bc
+#define WLAN_UART_WAKEUP_ENABLE_MSB 0
+#define WLAN_UART_WAKEUP_ENABLE_LSB 0
+#define WLAN_UART_WAKEUP_ENABLE_MASK 0x00000001
+#define WLAN_UART_WAKEUP_ENABLE_GET(x) (((x) & WLAN_UART_WAKEUP_ENABLE_MASK) >> WLAN_UART_WAKEUP_ENABLE_LSB)
+#define WLAN_UART_WAKEUP_ENABLE_SET(x) (((x) << WLAN_UART_WAKEUP_ENABLE_LSB) & WLAN_UART_WAKEUP_ENABLE_MASK)
+
+#define WLAN_RESET_CAUSE_ADDRESS 0x000000c0
+#define WLAN_RESET_CAUSE_OFFSET 0x000000c0
+#define WLAN_RESET_CAUSE_LAST_MSB 2
+#define WLAN_RESET_CAUSE_LAST_LSB 0
+#define WLAN_RESET_CAUSE_LAST_MASK 0x00000007
+#define WLAN_RESET_CAUSE_LAST_GET(x) (((x) & WLAN_RESET_CAUSE_LAST_MASK) >> WLAN_RESET_CAUSE_LAST_LSB)
+#define WLAN_RESET_CAUSE_LAST_SET(x) (((x) << WLAN_RESET_CAUSE_LAST_LSB) & WLAN_RESET_CAUSE_LAST_MASK)
+
+#define WLAN_SYSTEM_SLEEP_ADDRESS 0x000000c4
+#define WLAN_SYSTEM_SLEEP_OFFSET 0x000000c4
+#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB 4
+#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB 4
+#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010
+#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB)
+#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK)
+#define WLAN_SYSTEM_SLEEP_MBOX_MSB 3
+#define WLAN_SYSTEM_SLEEP_MBOX_LSB 3
+#define WLAN_SYSTEM_SLEEP_MBOX_MASK 0x00000008
+#define WLAN_SYSTEM_SLEEP_MBOX_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB)
+#define WLAN_SYSTEM_SLEEP_MBOX_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK)
+#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB 2
+#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB 2
+#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004
+#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB)
+#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK)
+#define WLAN_SYSTEM_SLEEP_LIGHT_MSB 1
+#define WLAN_SYSTEM_SLEEP_LIGHT_LSB 1
+#define WLAN_SYSTEM_SLEEP_LIGHT_MASK 0x00000002
+#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x) (((x) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB)
+#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK)
+#define WLAN_SYSTEM_SLEEP_DISABLE_MSB 0
+#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0
+#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001
+#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x) (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB)
+#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
+
+#define WLAN_SDIO_WRAPPER_ADDRESS 0x000000c8
+#define WLAN_SDIO_WRAPPER_OFFSET 0x000000c8
+#define WLAN_SDIO_WRAPPER_SLEEP_MSB 3
+#define WLAN_SDIO_WRAPPER_SLEEP_LSB 3
+#define WLAN_SDIO_WRAPPER_SLEEP_MASK 0x00000008
+#define WLAN_SDIO_WRAPPER_SLEEP_GET(x) (((x) & WLAN_SDIO_WRAPPER_SLEEP_MASK) >> WLAN_SDIO_WRAPPER_SLEEP_LSB)
+#define WLAN_SDIO_WRAPPER_SLEEP_SET(x) (((x) << WLAN_SDIO_WRAPPER_SLEEP_LSB) & WLAN_SDIO_WRAPPER_SLEEP_MASK)
+#define WLAN_SDIO_WRAPPER_WAKEUP_MSB 2
+#define WLAN_SDIO_WRAPPER_WAKEUP_LSB 2
+#define WLAN_SDIO_WRAPPER_WAKEUP_MASK 0x00000004
+#define WLAN_SDIO_WRAPPER_WAKEUP_GET(x) (((x) & WLAN_SDIO_WRAPPER_WAKEUP_MASK) >> WLAN_SDIO_WRAPPER_WAKEUP_LSB)
+#define WLAN_SDIO_WRAPPER_WAKEUP_SET(x) (((x) << WLAN_SDIO_WRAPPER_WAKEUP_LSB) & WLAN_SDIO_WRAPPER_WAKEUP_MASK)
+#define WLAN_SDIO_WRAPPER_SOC_ON_MSB 1
+#define WLAN_SDIO_WRAPPER_SOC_ON_LSB 1
+#define WLAN_SDIO_WRAPPER_SOC_ON_MASK 0x00000002
+#define WLAN_SDIO_WRAPPER_SOC_ON_GET(x) (((x) & WLAN_SDIO_WRAPPER_SOC_ON_MASK) >> WLAN_SDIO_WRAPPER_SOC_ON_LSB)
+#define WLAN_SDIO_WRAPPER_SOC_ON_SET(x) (((x) << WLAN_SDIO_WRAPPER_SOC_ON_LSB) & WLAN_SDIO_WRAPPER_SOC_ON_MASK)
+#define WLAN_SDIO_WRAPPER_ON_MSB 0
+#define WLAN_SDIO_WRAPPER_ON_LSB 0
+#define WLAN_SDIO_WRAPPER_ON_MASK 0x00000001
+#define WLAN_SDIO_WRAPPER_ON_GET(x) (((x) & WLAN_SDIO_WRAPPER_ON_MASK) >> WLAN_SDIO_WRAPPER_ON_LSB)
+#define WLAN_SDIO_WRAPPER_ON_SET(x) (((x) << WLAN_SDIO_WRAPPER_ON_LSB) & WLAN_SDIO_WRAPPER_ON_MASK)
+
+#define WLAN_MAC_SLEEP_CONTROL_ADDRESS 0x000000cc
+#define WLAN_MAC_SLEEP_CONTROL_OFFSET 0x000000cc
+#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB 1
+#define WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB 0
+#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK 0x00000003
+#define WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x) (((x) & WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK) >> WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB)
+#define WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x) (((x) << WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB) & WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK)
+
+#define WLAN_KEEP_AWAKE_ADDRESS 0x000000d0
+#define WLAN_KEEP_AWAKE_OFFSET 0x000000d0
+#define WLAN_KEEP_AWAKE_COUNT_MSB 7
+#define WLAN_KEEP_AWAKE_COUNT_LSB 0
+#define WLAN_KEEP_AWAKE_COUNT_MASK 0x000000ff
+#define WLAN_KEEP_AWAKE_COUNT_GET(x) (((x) & WLAN_KEEP_AWAKE_COUNT_MASK) >> WLAN_KEEP_AWAKE_COUNT_LSB)
+#define WLAN_KEEP_AWAKE_COUNT_SET(x) (((x) << WLAN_KEEP_AWAKE_COUNT_LSB) & WLAN_KEEP_AWAKE_COUNT_MASK)
+
+#define WLAN_LPO_CAL_TIME_ADDRESS 0x000000d4
+#define WLAN_LPO_CAL_TIME_OFFSET 0x000000d4
+#define WLAN_LPO_CAL_TIME_LENGTH_MSB 13
+#define WLAN_LPO_CAL_TIME_LENGTH_LSB 0
+#define WLAN_LPO_CAL_TIME_LENGTH_MASK 0x00003fff
+#define WLAN_LPO_CAL_TIME_LENGTH_GET(x) (((x) & WLAN_LPO_CAL_TIME_LENGTH_MASK) >> WLAN_LPO_CAL_TIME_LENGTH_LSB)
+#define WLAN_LPO_CAL_TIME_LENGTH_SET(x) (((x) << WLAN_LPO_CAL_TIME_LENGTH_LSB) & WLAN_LPO_CAL_TIME_LENGTH_MASK)
+
+#define WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS 0x000000d8
+#define WLAN_LPO_INIT_DIVIDEND_INT_OFFSET 0x000000d8
+#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB 23
+#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB 0
+#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK 0x00ffffff
+#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x) (((x) & WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB)
+#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x) (((x) << WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK)
+
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS 0x000000dc
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET 0x000000dc
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) (((x) & WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB)
+#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) (((x) << WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK)
+
+#define WLAN_LPO_CAL_ADDRESS 0x000000e0
+#define WLAN_LPO_CAL_OFFSET 0x000000e0
+#define WLAN_LPO_CAL_ENABLE_MSB 20
+#define WLAN_LPO_CAL_ENABLE_LSB 20
+#define WLAN_LPO_CAL_ENABLE_MASK 0x00100000
+#define WLAN_LPO_CAL_ENABLE_GET(x) (((x) & WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB)
+#define WLAN_LPO_CAL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK)
+#define WLAN_LPO_CAL_COUNT_MSB 19
+#define WLAN_LPO_CAL_COUNT_LSB 0
+#define WLAN_LPO_CAL_COUNT_MASK 0x000fffff
+#define WLAN_LPO_CAL_COUNT_GET(x) (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB)
+#define WLAN_LPO_CAL_COUNT_SET(x) (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK)
+
+#define WLAN_LPO_CAL_TEST_CONTROL_ADDRESS 0x000000e4
+#define WLAN_LPO_CAL_TEST_CONTROL_OFFSET 0x000000e4
+#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB 5
+#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB 5
+#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK 0x00000020
+#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x) (((x) & WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB)
+#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB) & WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK)
+#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 4
+#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0
+#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000001f
+#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) (((x) & WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB)
+#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) (((x) << WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK)
+
+#define WLAN_LPO_CAL_TEST_STATUS_ADDRESS 0x000000e8
+#define WLAN_LPO_CAL_TEST_STATUS_OFFSET 0x000000e8
+#define WLAN_LPO_CAL_TEST_STATUS_READY_MSB 16
+#define WLAN_LPO_CAL_TEST_STATUS_READY_LSB 16
+#define WLAN_LPO_CAL_TEST_STATUS_READY_MASK 0x00010000
+#define WLAN_LPO_CAL_TEST_STATUS_READY_GET(x) (((x) & WLAN_LPO_CAL_TEST_STATUS_READY_MASK) >> WLAN_LPO_CAL_TEST_STATUS_READY_LSB)
+#define WLAN_LPO_CAL_TEST_STATUS_READY_SET(x) (((x) << WLAN_LPO_CAL_TEST_STATUS_READY_LSB) & WLAN_LPO_CAL_TEST_STATUS_READY_MASK)
+#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB 15
+#define WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB 0
+#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK 0x0000ffff
+#define WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x) (((x) & WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK) >> WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB)
+#define WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x) (((x) << WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB) & WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK)
+
+#define WLAN_CHIP_ID_ADDRESS 0x000000ec
+#define WLAN_CHIP_ID_OFFSET 0x000000ec
+#define WLAN_CHIP_ID_DEVICE_ID_MSB 31
+#define WLAN_CHIP_ID_DEVICE_ID_LSB 16
+#define WLAN_CHIP_ID_DEVICE_ID_MASK 0xffff0000
+#define WLAN_CHIP_ID_DEVICE_ID_GET(x) (((x) & WLAN_CHIP_ID_DEVICE_ID_MASK) >> WLAN_CHIP_ID_DEVICE_ID_LSB)
+#define WLAN_CHIP_ID_DEVICE_ID_SET(x) (((x) << WLAN_CHIP_ID_DEVICE_ID_LSB) & WLAN_CHIP_ID_DEVICE_ID_MASK)
+#define WLAN_CHIP_ID_CONFIG_ID_MSB 15
+#define WLAN_CHIP_ID_CONFIG_ID_LSB 4
+#define WLAN_CHIP_ID_CONFIG_ID_MASK 0x0000fff0
+#define WLAN_CHIP_ID_CONFIG_ID_GET(x) (((x) & WLAN_CHIP_ID_CONFIG_ID_MASK) >> WLAN_CHIP_ID_CONFIG_ID_LSB)
+#define WLAN_CHIP_ID_CONFIG_ID_SET(x) (((x) << WLAN_CHIP_ID_CONFIG_ID_LSB) & WLAN_CHIP_ID_CONFIG_ID_MASK)
+#define WLAN_CHIP_ID_VERSION_ID_MSB 3
+#define WLAN_CHIP_ID_VERSION_ID_LSB 0
+#define WLAN_CHIP_ID_VERSION_ID_MASK 0x0000000f
+#define WLAN_CHIP_ID_VERSION_ID_GET(x) (((x) & WLAN_CHIP_ID_VERSION_ID_MASK) >> WLAN_CHIP_ID_VERSION_ID_LSB)
+#define WLAN_CHIP_ID_VERSION_ID_SET(x) (((x) << WLAN_CHIP_ID_VERSION_ID_LSB) & WLAN_CHIP_ID_VERSION_ID_MASK)
+
+#define WLAN_DERIVED_RTC_CLK_ADDRESS 0x000000f0
+#define WLAN_DERIVED_RTC_CLK_OFFSET 0x000000f0
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB 20
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB 20
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK 0x00100000
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB)
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK)
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB 18
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB 18
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK 0x00040000
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB)
+#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK)
+#define WLAN_DERIVED_RTC_CLK_FORCE_MSB 17
+#define WLAN_DERIVED_RTC_CLK_FORCE_LSB 16
+#define WLAN_DERIVED_RTC_CLK_FORCE_MASK 0x00030000
+#define WLAN_DERIVED_RTC_CLK_FORCE_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_FORCE_MASK) >> WLAN_DERIVED_RTC_CLK_FORCE_LSB)
+#define WLAN_DERIVED_RTC_CLK_FORCE_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_FORCE_LSB) & WLAN_DERIVED_RTC_CLK_FORCE_MASK)
+#define WLAN_DERIVED_RTC_CLK_PERIOD_MSB 15
+#define WLAN_DERIVED_RTC_CLK_PERIOD_LSB 1
+#define WLAN_DERIVED_RTC_CLK_PERIOD_MASK 0x0000fffe
+#define WLAN_DERIVED_RTC_CLK_PERIOD_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_PERIOD_MASK) >> WLAN_DERIVED_RTC_CLK_PERIOD_LSB)
+#define WLAN_DERIVED_RTC_CLK_PERIOD_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_PERIOD_LSB) & WLAN_DERIVED_RTC_CLK_PERIOD_MASK)
+
+#define MAC_PCU_SLP32_MODE_ADDRESS 0x000000f4
+#define MAC_PCU_SLP32_MODE_OFFSET 0x000000f4
+#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MSB 24
+#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB 24
+#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK 0x01000000
+#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB)
+#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK)
+#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MSB 23
+#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB 23
+#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK 0x00800000
+#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_GET(x) (((x) & MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK) >> MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB)
+#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_SET(x) (((x) << MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB) & MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK)
+#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MSB 22
+#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB 22
+#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK 0x00400000
+#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_GET(x) (((x) & MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK) >> MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB)
+#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_SET(x) (((x) << MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB) & MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK)
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MSB 21
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB 21
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK 0x00200000
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB)
+#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK)
+#define MAC_PCU_SLP32_MODE_ENABLE_MSB 20
+#define MAC_PCU_SLP32_MODE_ENABLE_LSB 20
+#define MAC_PCU_SLP32_MODE_ENABLE_MASK 0x00100000
+#define MAC_PCU_SLP32_MODE_ENABLE_GET(x) (((x) & MAC_PCU_SLP32_MODE_ENABLE_MASK) >> MAC_PCU_SLP32_MODE_ENABLE_LSB)
+#define MAC_PCU_SLP32_MODE_ENABLE_SET(x) (((x) << MAC_PCU_SLP32_MODE_ENABLE_LSB) & MAC_PCU_SLP32_MODE_ENABLE_MASK)
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB 19
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB 0
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) (((x) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB)
+#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK)
+
+#define MAC_PCU_SLP32_WAKE_ADDRESS 0x000000f8
+#define MAC_PCU_SLP32_WAKE_OFFSET 0x000000f8
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB 15
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB 0
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK 0x0000ffff
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x) (((x) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB)
+#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x) (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK)
+
+#define MAC_PCU_SLP32_INC_ADDRESS 0x000000fc
+#define MAC_PCU_SLP32_INC_OFFSET 0x000000fc
+#define MAC_PCU_SLP32_INC_TSF_INC_MSB 19
+#define MAC_PCU_SLP32_INC_TSF_INC_LSB 0
+#define MAC_PCU_SLP32_INC_TSF_INC_MASK 0x000fffff
+#define MAC_PCU_SLP32_INC_TSF_INC_GET(x) (((x) & MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB)
+#define MAC_PCU_SLP32_INC_TSF_INC_SET(x) (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK)
+
+#define MAC_PCU_SLP_MIB1_ADDRESS 0x00000100
+#define MAC_PCU_SLP_MIB1_OFFSET 0x00000100
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB 31
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB 0
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK 0xffffffff
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB)
+#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK)
+
+#define MAC_PCU_SLP_MIB2_ADDRESS 0x00000104
+#define MAC_PCU_SLP_MIB2_OFFSET 0x00000104
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB 31
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB 0
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK 0xffffffff
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB)
+#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK)
+
+#define MAC_PCU_SLP_MIB3_ADDRESS 0x00000108
+#define MAC_PCU_SLP_MIB3_OFFSET 0x00000108
+#define MAC_PCU_SLP_MIB3_PENDING_MSB 1
+#define MAC_PCU_SLP_MIB3_PENDING_LSB 1
+#define MAC_PCU_SLP_MIB3_PENDING_MASK 0x00000002
+#define MAC_PCU_SLP_MIB3_PENDING_GET(x) (((x) & MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB)
+#define MAC_PCU_SLP_MIB3_PENDING_SET(x) (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK)
+#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB 0
+#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB 0
+#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK 0x00000001
+#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x) (((x) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB)
+#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK)
+
+#define WLAN_POWER_REG_ADDRESS 0x0000010c
+#define WLAN_POWER_REG_OFFSET 0x0000010c
+#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB 15
+#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB 15
+#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK 0x00008000
+#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) (((x) & WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK) >> WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB)
+#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) (((x) << WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB) & WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK)
+#define WLAN_POWER_REG_DEBUG_EN_MSB 14
+#define WLAN_POWER_REG_DEBUG_EN_LSB 14
+#define WLAN_POWER_REG_DEBUG_EN_MASK 0x00004000
+#define WLAN_POWER_REG_DEBUG_EN_GET(x) (((x) & WLAN_POWER_REG_DEBUG_EN_MASK) >> WLAN_POWER_REG_DEBUG_EN_LSB)
+#define WLAN_POWER_REG_DEBUG_EN_SET(x) (((x) << WLAN_POWER_REG_DEBUG_EN_LSB) & WLAN_POWER_REG_DEBUG_EN_MASK)
+#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB 13
+#define WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB 13
+#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK 0x00002000
+#define WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x) (((x) & WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB)
+#define WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK)
+#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB 12
+#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB 12
+#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK 0x00001000
+#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x) (((x) & WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB)
+#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK)
+#define WLAN_POWER_REG_VLVL_MSB 11
+#define WLAN_POWER_REG_VLVL_LSB 8
+#define WLAN_POWER_REG_VLVL_MASK 0x00000f00
+#define WLAN_POWER_REG_VLVL_GET(x) (((x) & WLAN_POWER_REG_VLVL_MASK) >> WLAN_POWER_REG_VLVL_LSB)
+#define WLAN_POWER_REG_VLVL_SET(x) (((x) << WLAN_POWER_REG_VLVL_LSB) & WLAN_POWER_REG_VLVL_MASK)
+#define WLAN_POWER_REG_CPU_INT_ENABLE_MSB 7
+#define WLAN_POWER_REG_CPU_INT_ENABLE_LSB 7
+#define WLAN_POWER_REG_CPU_INT_ENABLE_MASK 0x00000080
+#define WLAN_POWER_REG_CPU_INT_ENABLE_GET(x) (((x) & WLAN_POWER_REG_CPU_INT_ENABLE_MASK) >> WLAN_POWER_REG_CPU_INT_ENABLE_LSB)
+#define WLAN_POWER_REG_CPU_INT_ENABLE_SET(x) (((x) << WLAN_POWER_REG_CPU_INT_ENABLE_LSB) & WLAN_POWER_REG_CPU_INT_ENABLE_MASK)
+#define WLAN_POWER_REG_WLAN_ISO_DIS_MSB 6
+#define WLAN_POWER_REG_WLAN_ISO_DIS_LSB 6
+#define WLAN_POWER_REG_WLAN_ISO_DIS_MASK 0x00000040
+#define WLAN_POWER_REG_WLAN_ISO_DIS_GET(x) (((x) & WLAN_POWER_REG_WLAN_ISO_DIS_MASK) >> WLAN_POWER_REG_WLAN_ISO_DIS_LSB)
+#define WLAN_POWER_REG_WLAN_ISO_DIS_SET(x) (((x) << WLAN_POWER_REG_WLAN_ISO_DIS_LSB) & WLAN_POWER_REG_WLAN_ISO_DIS_MASK)
+#define WLAN_POWER_REG_WLAN_ISO_CNTL_MSB 5
+#define WLAN_POWER_REG_WLAN_ISO_CNTL_LSB 5
+#define WLAN_POWER_REG_WLAN_ISO_CNTL_MASK 0x00000020
+#define WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x) (((x) & WLAN_POWER_REG_WLAN_ISO_CNTL_MASK) >> WLAN_POWER_REG_WLAN_ISO_CNTL_LSB)
+#define WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x) (((x) << WLAN_POWER_REG_WLAN_ISO_CNTL_LSB) & WLAN_POWER_REG_WLAN_ISO_CNTL_MASK)
+#define WLAN_POWER_REG_RADIO_PWD_EN_MSB 4
+#define WLAN_POWER_REG_RADIO_PWD_EN_LSB 4
+#define WLAN_POWER_REG_RADIO_PWD_EN_MASK 0x00000010
+#define WLAN_POWER_REG_RADIO_PWD_EN_GET(x) (((x) & WLAN_POWER_REG_RADIO_PWD_EN_MASK) >> WLAN_POWER_REG_RADIO_PWD_EN_LSB)
+#define WLAN_POWER_REG_RADIO_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_RADIO_PWD_EN_LSB) & WLAN_POWER_REG_RADIO_PWD_EN_MASK)
+#define WLAN_POWER_REG_SOC_ISO_EN_MSB 3
+#define WLAN_POWER_REG_SOC_ISO_EN_LSB 3
+#define WLAN_POWER_REG_SOC_ISO_EN_MASK 0x00000008
+#define WLAN_POWER_REG_SOC_ISO_EN_GET(x) (((x) & WLAN_POWER_REG_SOC_ISO_EN_MASK) >> WLAN_POWER_REG_SOC_ISO_EN_LSB)
+#define WLAN_POWER_REG_SOC_ISO_EN_SET(x) (((x) << WLAN_POWER_REG_SOC_ISO_EN_LSB) & WLAN_POWER_REG_SOC_ISO_EN_MASK)
+#define WLAN_POWER_REG_WLAN_ISO_EN_MSB 2
+#define WLAN_POWER_REG_WLAN_ISO_EN_LSB 2
+#define WLAN_POWER_REG_WLAN_ISO_EN_MASK 0x00000004
+#define WLAN_POWER_REG_WLAN_ISO_EN_GET(x) (((x) & WLAN_POWER_REG_WLAN_ISO_EN_MASK) >> WLAN_POWER_REG_WLAN_ISO_EN_LSB)
+#define WLAN_POWER_REG_WLAN_ISO_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_ISO_EN_LSB) & WLAN_POWER_REG_WLAN_ISO_EN_MASK)
+#define WLAN_POWER_REG_WLAN_PWD_EN_MSB 1
+#define WLAN_POWER_REG_WLAN_PWD_EN_LSB 1
+#define WLAN_POWER_REG_WLAN_PWD_EN_MASK 0x00000002
+#define WLAN_POWER_REG_WLAN_PWD_EN_GET(x) (((x) & WLAN_POWER_REG_WLAN_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_PWD_EN_LSB)
+#define WLAN_POWER_REG_WLAN_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_PWD_EN_MASK)
+#define WLAN_POWER_REG_POWER_EN_MSB 0
+#define WLAN_POWER_REG_POWER_EN_LSB 0
+#define WLAN_POWER_REG_POWER_EN_MASK 0x00000001
+#define WLAN_POWER_REG_POWER_EN_GET(x) (((x) & WLAN_POWER_REG_POWER_EN_MASK) >> WLAN_POWER_REG_POWER_EN_LSB)
+#define WLAN_POWER_REG_POWER_EN_SET(x) (((x) << WLAN_POWER_REG_POWER_EN_LSB) & WLAN_POWER_REG_POWER_EN_MASK)
+
+#define WLAN_CORE_CLK_CTRL_ADDRESS 0x00000110
+#define WLAN_CORE_CLK_CTRL_OFFSET 0x00000110
+#define WLAN_CORE_CLK_CTRL_DIV_MSB 2
+#define WLAN_CORE_CLK_CTRL_DIV_LSB 0
+#define WLAN_CORE_CLK_CTRL_DIV_MASK 0x00000007
+#define WLAN_CORE_CLK_CTRL_DIV_GET(x) (((x) & WLAN_CORE_CLK_CTRL_DIV_MASK) >> WLAN_CORE_CLK_CTRL_DIV_LSB)
+#define WLAN_CORE_CLK_CTRL_DIV_SET(x) (((x) << WLAN_CORE_CLK_CTRL_DIV_LSB) & WLAN_CORE_CLK_CTRL_DIV_MASK)
+
+#define WLAN_GPIO_WAKEUP_CONTROL_ADDRESS 0x00000114
+#define WLAN_GPIO_WAKEUP_CONTROL_OFFSET 0x00000114
+#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB 0
+#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB 0
+#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK 0x00000001
+#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x) (((x) & WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB)
+#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x) (((x) << WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB) & WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK)
+
+#define HT_ADDRESS 0x00000118
+#define HT_OFFSET 0x00000118
+#define HT_MODE_MSB 0
+#define HT_MODE_LSB 0
+#define HT_MODE_MASK 0x00000001
+#define HT_MODE_GET(x) (((x) & HT_MODE_MASK) >> HT_MODE_LSB)
+#define HT_MODE_SET(x) (((x) << HT_MODE_LSB) & HT_MODE_MASK)
+
+#define MAC_PCU_TSF_L32_ADDRESS 0x0000011c
+#define MAC_PCU_TSF_L32_OFFSET 0x0000011c
+#define MAC_PCU_TSF_L32_VALUE_MSB 31
+#define MAC_PCU_TSF_L32_VALUE_LSB 0
+#define MAC_PCU_TSF_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF_L32_VALUE_GET(x) (((x) & MAC_PCU_TSF_L32_VALUE_MASK) >> MAC_PCU_TSF_L32_VALUE_LSB)
+#define MAC_PCU_TSF_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF_L32_VALUE_LSB) & MAC_PCU_TSF_L32_VALUE_MASK)
+
+#define MAC_PCU_TSF_U32_ADDRESS 0x00000120
+#define MAC_PCU_TSF_U32_OFFSET 0x00000120
+#define MAC_PCU_TSF_U32_VALUE_MSB 31
+#define MAC_PCU_TSF_U32_VALUE_LSB 0
+#define MAC_PCU_TSF_U32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF_U32_VALUE_GET(x) (((x) & MAC_PCU_TSF_U32_VALUE_MASK) >> MAC_PCU_TSF_U32_VALUE_LSB)
+#define MAC_PCU_TSF_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF_U32_VALUE_LSB) & MAC_PCU_TSF_U32_VALUE_MASK)
+
+#define MAC_PCU_WBTIMER_ADDRESS 0x00000124
+#define MAC_PCU_WBTIMER_OFFSET 0x00000124
+#define MAC_PCU_WBTIMER_VALUE_MSB 31
+#define MAC_PCU_WBTIMER_VALUE_LSB 0
+#define MAC_PCU_WBTIMER_VALUE_MASK 0xffffffff
+#define MAC_PCU_WBTIMER_VALUE_GET(x) (((x) & MAC_PCU_WBTIMER_VALUE_MASK) >> MAC_PCU_WBTIMER_VALUE_LSB)
+#define MAC_PCU_WBTIMER_VALUE_SET(x) (((x) << MAC_PCU_WBTIMER_VALUE_LSB) & MAC_PCU_WBTIMER_VALUE_MASK)
+
+#define MAC_PCU_GENERIC_TIMERS_ADDRESS 0x00000140
+#define MAC_PCU_GENERIC_TIMERS_OFFSET 0x00000140
+#define MAC_PCU_GENERIC_TIMERS_DATA_MSB 31
+#define MAC_PCU_GENERIC_TIMERS_DATA_LSB 0
+#define MAC_PCU_GENERIC_TIMERS_DATA_MASK 0xffffffff
+#define MAC_PCU_GENERIC_TIMERS_DATA_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS_DATA_LSB)
+#define MAC_PCU_GENERIC_TIMERS_DATA_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_DATA_LSB) & MAC_PCU_GENERIC_TIMERS_DATA_MASK)
+
+#define MAC_PCU_GENERIC_TIMERS_MODE_ADDRESS 0x00000180
+#define MAC_PCU_GENERIC_TIMERS_MODE_OFFSET 0x00000180
+#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MSB 15
+#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB 0
+#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK 0x0000ffff
+#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB)
+#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK)
+
+#define MAC_PCU_GENERIC_TIMERS2_ADDRESS 0x000001c0
+#define MAC_PCU_GENERIC_TIMERS2_OFFSET 0x000001c0
+#define MAC_PCU_GENERIC_TIMERS2_DATA_MSB 31
+#define MAC_PCU_GENERIC_TIMERS2_DATA_LSB 0
+#define MAC_PCU_GENERIC_TIMERS2_DATA_MASK 0xffffffff
+#define MAC_PCU_GENERIC_TIMERS2_DATA_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS2_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS2_DATA_LSB)
+#define MAC_PCU_GENERIC_TIMERS2_DATA_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS2_DATA_LSB) & MAC_PCU_GENERIC_TIMERS2_DATA_MASK)
+
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ADDRESS 0x00000200
+#define MAC_PCU_GENERIC_TIMERS_MODE2_OFFSET 0x00000200
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MSB 15
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB 0
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK 0x0000ffff
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB)
+#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK)
+
+#define MAC_PCU_SLP1_ADDRESS 0x00000204
+#define MAC_PCU_SLP1_OFFSET 0x00000204
+#define MAC_PCU_SLP1_ASSUME_DTIM_MSB 19
+#define MAC_PCU_SLP1_ASSUME_DTIM_LSB 19
+#define MAC_PCU_SLP1_ASSUME_DTIM_MASK 0x00080000
+#define MAC_PCU_SLP1_ASSUME_DTIM_GET(x) (((x) & MAC_PCU_SLP1_ASSUME_DTIM_MASK) >> MAC_PCU_SLP1_ASSUME_DTIM_LSB)
+#define MAC_PCU_SLP1_ASSUME_DTIM_SET(x) (((x) << MAC_PCU_SLP1_ASSUME_DTIM_LSB) & MAC_PCU_SLP1_ASSUME_DTIM_MASK)
+#define MAC_PCU_SLP1_CAB_TIMEOUT_MSB 15
+#define MAC_PCU_SLP1_CAB_TIMEOUT_LSB 0
+#define MAC_PCU_SLP1_CAB_TIMEOUT_MASK 0x0000ffff
+#define MAC_PCU_SLP1_CAB_TIMEOUT_GET(x) (((x) & MAC_PCU_SLP1_CAB_TIMEOUT_MASK) >> MAC_PCU_SLP1_CAB_TIMEOUT_LSB)
+#define MAC_PCU_SLP1_CAB_TIMEOUT_SET(x) (((x) << MAC_PCU_SLP1_CAB_TIMEOUT_LSB) & MAC_PCU_SLP1_CAB_TIMEOUT_MASK)
+
+#define MAC_PCU_SLP2_ADDRESS 0x00000208
+#define MAC_PCU_SLP2_OFFSET 0x00000208
+#define MAC_PCU_SLP2_BEACON_TIMEOUT_MSB 15
+#define MAC_PCU_SLP2_BEACON_TIMEOUT_LSB 0
+#define MAC_PCU_SLP2_BEACON_TIMEOUT_MASK 0x0000ffff
+#define MAC_PCU_SLP2_BEACON_TIMEOUT_GET(x) (((x) & MAC_PCU_SLP2_BEACON_TIMEOUT_MASK) >> MAC_PCU_SLP2_BEACON_TIMEOUT_LSB)
+#define MAC_PCU_SLP2_BEACON_TIMEOUT_SET(x) (((x) << MAC_PCU_SLP2_BEACON_TIMEOUT_LSB) & MAC_PCU_SLP2_BEACON_TIMEOUT_MASK)
+
+#define MAC_PCU_RESET_TSF_ADDRESS 0x0000020c
+#define MAC_PCU_RESET_TSF_OFFSET 0x0000020c
+#define MAC_PCU_RESET_TSF_ONE_SHOT2_MSB 25
+#define MAC_PCU_RESET_TSF_ONE_SHOT2_LSB 25
+#define MAC_PCU_RESET_TSF_ONE_SHOT2_MASK 0x02000000
+#define MAC_PCU_RESET_TSF_ONE_SHOT2_GET(x) (((x) & MAC_PCU_RESET_TSF_ONE_SHOT2_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT2_LSB)
+#define MAC_PCU_RESET_TSF_ONE_SHOT2_SET(x) (((x) << MAC_PCU_RESET_TSF_ONE_SHOT2_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT2_MASK)
+#define MAC_PCU_RESET_TSF_ONE_SHOT_MSB 24
+#define MAC_PCU_RESET_TSF_ONE_SHOT_LSB 24
+#define MAC_PCU_RESET_TSF_ONE_SHOT_MASK 0x01000000
+#define MAC_PCU_RESET_TSF_ONE_SHOT_GET(x) (((x) & MAC_PCU_RESET_TSF_ONE_SHOT_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT_LSB)
+#define MAC_PCU_RESET_TSF_ONE_SHOT_SET(x) (((x) << MAC_PCU_RESET_TSF_ONE_SHOT_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT_MASK)
+
+#define MAC_PCU_TSF_ADD_PLL_ADDRESS 0x00000210
+#define MAC_PCU_TSF_ADD_PLL_OFFSET 0x00000210
+#define MAC_PCU_TSF_ADD_PLL_VALUE_MSB 7
+#define MAC_PCU_TSF_ADD_PLL_VALUE_LSB 0
+#define MAC_PCU_TSF_ADD_PLL_VALUE_MASK 0x000000ff
+#define MAC_PCU_TSF_ADD_PLL_VALUE_GET(x) (((x) & MAC_PCU_TSF_ADD_PLL_VALUE_MASK) >> MAC_PCU_TSF_ADD_PLL_VALUE_LSB)
+#define MAC_PCU_TSF_ADD_PLL_VALUE_SET(x) (((x) << MAC_PCU_TSF_ADD_PLL_VALUE_LSB) & MAC_PCU_TSF_ADD_PLL_VALUE_MASK)
+
+#define SLEEP_RETENTION_ADDRESS 0x00000214
+#define SLEEP_RETENTION_OFFSET 0x00000214
+#define SLEEP_RETENTION_TIME_MSB 9
+#define SLEEP_RETENTION_TIME_LSB 2
+#define SLEEP_RETENTION_TIME_MASK 0x000003fc
+#define SLEEP_RETENTION_TIME_GET(x) (((x) & SLEEP_RETENTION_TIME_MASK) >> SLEEP_RETENTION_TIME_LSB)
+#define SLEEP_RETENTION_TIME_SET(x) (((x) << SLEEP_RETENTION_TIME_LSB) & SLEEP_RETENTION_TIME_MASK)
+#define SLEEP_RETENTION_MODE_MSB 1
+#define SLEEP_RETENTION_MODE_LSB 1
+#define SLEEP_RETENTION_MODE_MASK 0x00000002
+#define SLEEP_RETENTION_MODE_GET(x) (((x) & SLEEP_RETENTION_MODE_MASK) >> SLEEP_RETENTION_MODE_LSB)
+#define SLEEP_RETENTION_MODE_SET(x) (((x) << SLEEP_RETENTION_MODE_LSB) & SLEEP_RETENTION_MODE_MASK)
+#define SLEEP_RETENTION_ENABLE_MSB 0
+#define SLEEP_RETENTION_ENABLE_LSB 0
+#define SLEEP_RETENTION_ENABLE_MASK 0x00000001
+#define SLEEP_RETENTION_ENABLE_GET(x) (((x) & SLEEP_RETENTION_ENABLE_MASK) >> SLEEP_RETENTION_ENABLE_LSB)
+#define SLEEP_RETENTION_ENABLE_SET(x) (((x) << SLEEP_RETENTION_ENABLE_LSB) & SLEEP_RETENTION_ENABLE_MASK)
+
+#define BTCOEXCTRL_ADDRESS 0x00000218
+#define BTCOEXCTRL_OFFSET 0x00000218
+#define BTCOEXCTRL_WBTIMER_ENABLE_MSB 26
+#define BTCOEXCTRL_WBTIMER_ENABLE_LSB 26
+#define BTCOEXCTRL_WBTIMER_ENABLE_MASK 0x04000000
+#define BTCOEXCTRL_WBTIMER_ENABLE_GET(x) (((x) & BTCOEXCTRL_WBTIMER_ENABLE_MASK) >> BTCOEXCTRL_WBTIMER_ENABLE_LSB)
+#define BTCOEXCTRL_WBTIMER_ENABLE_SET(x) (((x) << BTCOEXCTRL_WBTIMER_ENABLE_LSB) & BTCOEXCTRL_WBTIMER_ENABLE_MASK)
+#define BTCOEXCTRL_WBSYNC_ON_BEACON_MSB 25
+#define BTCOEXCTRL_WBSYNC_ON_BEACON_LSB 25
+#define BTCOEXCTRL_WBSYNC_ON_BEACON_MASK 0x02000000
+#define BTCOEXCTRL_WBSYNC_ON_BEACON_GET(x) (((x) & BTCOEXCTRL_WBSYNC_ON_BEACON_MASK) >> BTCOEXCTRL_WBSYNC_ON_BEACON_LSB)
+#define BTCOEXCTRL_WBSYNC_ON_BEACON_SET(x) (((x) << BTCOEXCTRL_WBSYNC_ON_BEACON_LSB) & BTCOEXCTRL_WBSYNC_ON_BEACON_MASK)
+#define BTCOEXCTRL_PTA_MODE_MSB 24
+#define BTCOEXCTRL_PTA_MODE_LSB 23
+#define BTCOEXCTRL_PTA_MODE_MASK 0x01800000
+#define BTCOEXCTRL_PTA_MODE_GET(x) (((x) & BTCOEXCTRL_PTA_MODE_MASK) >> BTCOEXCTRL_PTA_MODE_LSB)
+#define BTCOEXCTRL_PTA_MODE_SET(x) (((x) << BTCOEXCTRL_PTA_MODE_LSB) & BTCOEXCTRL_PTA_MODE_MASK)
+#define BTCOEXCTRL_FREQ_TIME_MSB 22
+#define BTCOEXCTRL_FREQ_TIME_LSB 18
+#define BTCOEXCTRL_FREQ_TIME_MASK 0x007c0000
+#define BTCOEXCTRL_FREQ_TIME_GET(x) (((x) & BTCOEXCTRL_FREQ_TIME_MASK) >> BTCOEXCTRL_FREQ_TIME_LSB)
+#define BTCOEXCTRL_FREQ_TIME_SET(x) (((x) << BTCOEXCTRL_FREQ_TIME_LSB) & BTCOEXCTRL_FREQ_TIME_MASK)
+#define BTCOEXCTRL_PRIORITY_TIME_MSB 17
+#define BTCOEXCTRL_PRIORITY_TIME_LSB 12
+#define BTCOEXCTRL_PRIORITY_TIME_MASK 0x0003f000
+#define BTCOEXCTRL_PRIORITY_TIME_GET(x) (((x) & BTCOEXCTRL_PRIORITY_TIME_MASK) >> BTCOEXCTRL_PRIORITY_TIME_LSB)
+#define BTCOEXCTRL_PRIORITY_TIME_SET(x) (((x) << BTCOEXCTRL_PRIORITY_TIME_LSB) & BTCOEXCTRL_PRIORITY_TIME_MASK)
+#define BTCOEXCTRL_SYNC_DET_EN_MSB 11
+#define BTCOEXCTRL_SYNC_DET_EN_LSB 11
+#define BTCOEXCTRL_SYNC_DET_EN_MASK 0x00000800
+#define BTCOEXCTRL_SYNC_DET_EN_GET(x) (((x) & BTCOEXCTRL_SYNC_DET_EN_MASK) >> BTCOEXCTRL_SYNC_DET_EN_LSB)
+#define BTCOEXCTRL_SYNC_DET_EN_SET(x) (((x) << BTCOEXCTRL_SYNC_DET_EN_LSB) & BTCOEXCTRL_SYNC_DET_EN_MASK)
+#define BTCOEXCTRL_IDLE_CNT_EN_MSB 10
+#define BTCOEXCTRL_IDLE_CNT_EN_LSB 10
+#define BTCOEXCTRL_IDLE_CNT_EN_MASK 0x00000400
+#define BTCOEXCTRL_IDLE_CNT_EN_GET(x) (((x) & BTCOEXCTRL_IDLE_CNT_EN_MASK) >> BTCOEXCTRL_IDLE_CNT_EN_LSB)
+#define BTCOEXCTRL_IDLE_CNT_EN_SET(x) (((x) << BTCOEXCTRL_IDLE_CNT_EN_LSB) & BTCOEXCTRL_IDLE_CNT_EN_MASK)
+#define BTCOEXCTRL_FRAME_CNT_EN_MSB 9
+#define BTCOEXCTRL_FRAME_CNT_EN_LSB 9
+#define BTCOEXCTRL_FRAME_CNT_EN_MASK 0x00000200
+#define BTCOEXCTRL_FRAME_CNT_EN_GET(x) (((x) & BTCOEXCTRL_FRAME_CNT_EN_MASK) >> BTCOEXCTRL_FRAME_CNT_EN_LSB)
+#define BTCOEXCTRL_FRAME_CNT_EN_SET(x) (((x) << BTCOEXCTRL_FRAME_CNT_EN_LSB) & BTCOEXCTRL_FRAME_CNT_EN_MASK)
+#define BTCOEXCTRL_CLK_CNT_EN_MSB 8
+#define BTCOEXCTRL_CLK_CNT_EN_LSB 8
+#define BTCOEXCTRL_CLK_CNT_EN_MASK 0x00000100
+#define BTCOEXCTRL_CLK_CNT_EN_GET(x) (((x) & BTCOEXCTRL_CLK_CNT_EN_MASK) >> BTCOEXCTRL_CLK_CNT_EN_LSB)
+#define BTCOEXCTRL_CLK_CNT_EN_SET(x) (((x) << BTCOEXCTRL_CLK_CNT_EN_LSB) & BTCOEXCTRL_CLK_CNT_EN_MASK)
+#define BTCOEXCTRL_GAP_MSB 7
+#define BTCOEXCTRL_GAP_LSB 0
+#define BTCOEXCTRL_GAP_MASK 0x000000ff
+#define BTCOEXCTRL_GAP_GET(x) (((x) & BTCOEXCTRL_GAP_MASK) >> BTCOEXCTRL_GAP_LSB)
+#define BTCOEXCTRL_GAP_SET(x) (((x) << BTCOEXCTRL_GAP_LSB) & BTCOEXCTRL_GAP_MASK)
+
+#define WBSYNC_PRIORITY1_ADDRESS 0x0000021c
+#define WBSYNC_PRIORITY1_OFFSET 0x0000021c
+#define WBSYNC_PRIORITY1_BITMAP_MSB 31
+#define WBSYNC_PRIORITY1_BITMAP_LSB 0
+#define WBSYNC_PRIORITY1_BITMAP_MASK 0xffffffff
+#define WBSYNC_PRIORITY1_BITMAP_GET(x) (((x) & WBSYNC_PRIORITY1_BITMAP_MASK) >> WBSYNC_PRIORITY1_BITMAP_LSB)
+#define WBSYNC_PRIORITY1_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY1_BITMAP_LSB) & WBSYNC_PRIORITY1_BITMAP_MASK)
+
+#define WBSYNC_PRIORITY2_ADDRESS 0x00000220
+#define WBSYNC_PRIORITY2_OFFSET 0x00000220
+#define WBSYNC_PRIORITY2_BITMAP_MSB 31
+#define WBSYNC_PRIORITY2_BITMAP_LSB 0
+#define WBSYNC_PRIORITY2_BITMAP_MASK 0xffffffff
+#define WBSYNC_PRIORITY2_BITMAP_GET(x) (((x) & WBSYNC_PRIORITY2_BITMAP_MASK) >> WBSYNC_PRIORITY2_BITMAP_LSB)
+#define WBSYNC_PRIORITY2_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY2_BITMAP_LSB) & WBSYNC_PRIORITY2_BITMAP_MASK)
+
+#define WBSYNC_PRIORITY3_ADDRESS 0x00000224
+#define WBSYNC_PRIORITY3_OFFSET 0x00000224
+#define WBSYNC_PRIORITY3_BITMAP_MSB 31
+#define WBSYNC_PRIORITY3_BITMAP_LSB 0
+#define WBSYNC_PRIORITY3_BITMAP_MASK 0xffffffff
+#define WBSYNC_PRIORITY3_BITMAP_GET(x) (((x) & WBSYNC_PRIORITY3_BITMAP_MASK) >> WBSYNC_PRIORITY3_BITMAP_LSB)
+#define WBSYNC_PRIORITY3_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY3_BITMAP_LSB) & WBSYNC_PRIORITY3_BITMAP_MASK)
+
+#define BTCOEX0_ADDRESS 0x00000228
+#define BTCOEX0_OFFSET 0x00000228
+#define BTCOEX0_SYNC_DUR_MSB 7
+#define BTCOEX0_SYNC_DUR_LSB 0
+#define BTCOEX0_SYNC_DUR_MASK 0x000000ff
+#define BTCOEX0_SYNC_DUR_GET(x) (((x) & BTCOEX0_SYNC_DUR_MASK) >> BTCOEX0_SYNC_DUR_LSB)
+#define BTCOEX0_SYNC_DUR_SET(x) (((x) << BTCOEX0_SYNC_DUR_LSB) & BTCOEX0_SYNC_DUR_MASK)
+
+#define BTCOEX1_ADDRESS 0x0000022c
+#define BTCOEX1_OFFSET 0x0000022c
+#define BTCOEX1_CLK_THRES_MSB 20
+#define BTCOEX1_CLK_THRES_LSB 0
+#define BTCOEX1_CLK_THRES_MASK 0x001fffff
+#define BTCOEX1_CLK_THRES_GET(x) (((x) & BTCOEX1_CLK_THRES_MASK) >> BTCOEX1_CLK_THRES_LSB)
+#define BTCOEX1_CLK_THRES_SET(x) (((x) << BTCOEX1_CLK_THRES_LSB) & BTCOEX1_CLK_THRES_MASK)
+
+#define BTCOEX2_ADDRESS 0x00000230
+#define BTCOEX2_OFFSET 0x00000230
+#define BTCOEX2_FRAME_THRES_MSB 7
+#define BTCOEX2_FRAME_THRES_LSB 0
+#define BTCOEX2_FRAME_THRES_MASK 0x000000ff
+#define BTCOEX2_FRAME_THRES_GET(x) (((x) & BTCOEX2_FRAME_THRES_MASK) >> BTCOEX2_FRAME_THRES_LSB)
+#define BTCOEX2_FRAME_THRES_SET(x) (((x) << BTCOEX2_FRAME_THRES_LSB) & BTCOEX2_FRAME_THRES_MASK)
+
+#define BTCOEX3_ADDRESS 0x00000234
+#define BTCOEX3_OFFSET 0x00000234
+#define BTCOEX3_CLK_CNT_MSB 20
+#define BTCOEX3_CLK_CNT_LSB 0
+#define BTCOEX3_CLK_CNT_MASK 0x001fffff
+#define BTCOEX3_CLK_CNT_GET(x) (((x) & BTCOEX3_CLK_CNT_MASK) >> BTCOEX3_CLK_CNT_LSB)
+#define BTCOEX3_CLK_CNT_SET(x) (((x) << BTCOEX3_CLK_CNT_LSB) & BTCOEX3_CLK_CNT_MASK)
+
+#define BTCOEX4_ADDRESS 0x00000238
+#define BTCOEX4_OFFSET 0x00000238
+#define BTCOEX4_FRAME_CNT_MSB 7
+#define BTCOEX4_FRAME_CNT_LSB 0
+#define BTCOEX4_FRAME_CNT_MASK 0x000000ff
+#define BTCOEX4_FRAME_CNT_GET(x) (((x) & BTCOEX4_FRAME_CNT_MASK) >> BTCOEX4_FRAME_CNT_LSB)
+#define BTCOEX4_FRAME_CNT_SET(x) (((x) << BTCOEX4_FRAME_CNT_LSB) & BTCOEX4_FRAME_CNT_MASK)
+
+#define BTCOEX5_ADDRESS 0x0000023c
+#define BTCOEX5_OFFSET 0x0000023c
+#define BTCOEX5_IDLE_CNT_MSB 15
+#define BTCOEX5_IDLE_CNT_LSB 0
+#define BTCOEX5_IDLE_CNT_MASK 0x0000ffff
+#define BTCOEX5_IDLE_CNT_GET(x) (((x) & BTCOEX5_IDLE_CNT_MASK) >> BTCOEX5_IDLE_CNT_LSB)
+#define BTCOEX5_IDLE_CNT_SET(x) (((x) << BTCOEX5_IDLE_CNT_LSB) & BTCOEX5_IDLE_CNT_MASK)
+
+#define BTCOEX6_ADDRESS 0x00000240
+#define BTCOEX6_OFFSET 0x00000240
+#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MSB 31
+#define BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB 0
+#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK 0xffffffff
+#define BTCOEX6_IDLE_RESET_LVL_BITMAP_GET(x) (((x) & BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK) >> BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB)
+#define BTCOEX6_IDLE_RESET_LVL_BITMAP_SET(x) (((x) << BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB) & BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK)
+
+#define LOCK_ADDRESS 0x00000244
+#define LOCK_OFFSET 0x00000244
+#define LOCK_TLOCK_SLAVE_MSB 31
+#define LOCK_TLOCK_SLAVE_LSB 24
+#define LOCK_TLOCK_SLAVE_MASK 0xff000000
+#define LOCK_TLOCK_SLAVE_GET(x) (((x) & LOCK_TLOCK_SLAVE_MASK) >> LOCK_TLOCK_SLAVE_LSB)
+#define LOCK_TLOCK_SLAVE_SET(x) (((x) << LOCK_TLOCK_SLAVE_LSB) & LOCK_TLOCK_SLAVE_MASK)
+#define LOCK_TUNLOCK_SLAVE_MSB 23
+#define LOCK_TUNLOCK_SLAVE_LSB 16
+#define LOCK_TUNLOCK_SLAVE_MASK 0x00ff0000
+#define LOCK_TUNLOCK_SLAVE_GET(x) (((x) & LOCK_TUNLOCK_SLAVE_MASK) >> LOCK_TUNLOCK_SLAVE_LSB)
+#define LOCK_TUNLOCK_SLAVE_SET(x) (((x) << LOCK_TUNLOCK_SLAVE_LSB) & LOCK_TUNLOCK_SLAVE_MASK)
+#define LOCK_TLOCK_MASTER_MSB 15
+#define LOCK_TLOCK_MASTER_LSB 8
+#define LOCK_TLOCK_MASTER_MASK 0x0000ff00
+#define LOCK_TLOCK_MASTER_GET(x) (((x) & LOCK_TLOCK_MASTER_MASK) >> LOCK_TLOCK_MASTER_LSB)
+#define LOCK_TLOCK_MASTER_SET(x) (((x) << LOCK_TLOCK_MASTER_LSB) & LOCK_TLOCK_MASTER_MASK)
+#define LOCK_TUNLOCK_MASTER_MSB 7
+#define LOCK_TUNLOCK_MASTER_LSB 0
+#define LOCK_TUNLOCK_MASTER_MASK 0x000000ff
+#define LOCK_TUNLOCK_MASTER_GET(x) (((x) & LOCK_TUNLOCK_MASTER_MASK) >> LOCK_TUNLOCK_MASTER_LSB)
+#define LOCK_TUNLOCK_MASTER_SET(x) (((x) << LOCK_TUNLOCK_MASTER_LSB) & LOCK_TUNLOCK_MASTER_MASK)
+
+#define NOLOCK_PRIORITY_ADDRESS 0x00000248
+#define NOLOCK_PRIORITY_OFFSET 0x00000248
+#define NOLOCK_PRIORITY_BITMAP_MSB 31
+#define NOLOCK_PRIORITY_BITMAP_LSB 0
+#define NOLOCK_PRIORITY_BITMAP_MASK 0xffffffff
+#define NOLOCK_PRIORITY_BITMAP_GET(x) (((x) & NOLOCK_PRIORITY_BITMAP_MASK) >> NOLOCK_PRIORITY_BITMAP_LSB)
+#define NOLOCK_PRIORITY_BITMAP_SET(x) (((x) << NOLOCK_PRIORITY_BITMAP_LSB) & NOLOCK_PRIORITY_BITMAP_MASK)
+
+#define WBSYNC_ADDRESS 0x0000024c
+#define WBSYNC_OFFSET 0x0000024c
+#define WBSYNC_BTCLOCK_MSB 31
+#define WBSYNC_BTCLOCK_LSB 0
+#define WBSYNC_BTCLOCK_MASK 0xffffffff
+#define WBSYNC_BTCLOCK_GET(x) (((x) & WBSYNC_BTCLOCK_MASK) >> WBSYNC_BTCLOCK_LSB)
+#define WBSYNC_BTCLOCK_SET(x) (((x) << WBSYNC_BTCLOCK_LSB) & WBSYNC_BTCLOCK_MASK)
+
+#define WBSYNC1_ADDRESS 0x00000250
+#define WBSYNC1_OFFSET 0x00000250
+#define WBSYNC1_BTCLOCK_MSB 31
+#define WBSYNC1_BTCLOCK_LSB 0
+#define WBSYNC1_BTCLOCK_MASK 0xffffffff
+#define WBSYNC1_BTCLOCK_GET(x) (((x) & WBSYNC1_BTCLOCK_MASK) >> WBSYNC1_BTCLOCK_LSB)
+#define WBSYNC1_BTCLOCK_SET(x) (((x) << WBSYNC1_BTCLOCK_LSB) & WBSYNC1_BTCLOCK_MASK)
+
+#define WBSYNC2_ADDRESS 0x00000254
+#define WBSYNC2_OFFSET 0x00000254
+#define WBSYNC2_BTCLOCK_MSB 31
+#define WBSYNC2_BTCLOCK_LSB 0
+#define WBSYNC2_BTCLOCK_MASK 0xffffffff
+#define WBSYNC2_BTCLOCK_GET(x) (((x) & WBSYNC2_BTCLOCK_MASK) >> WBSYNC2_BTCLOCK_LSB)
+#define WBSYNC2_BTCLOCK_SET(x) (((x) << WBSYNC2_BTCLOCK_LSB) & WBSYNC2_BTCLOCK_MASK)
+
+#define WBSYNC3_ADDRESS 0x00000258
+#define WBSYNC3_OFFSET 0x00000258
+#define WBSYNC3_BTCLOCK_MSB 31
+#define WBSYNC3_BTCLOCK_LSB 0
+#define WBSYNC3_BTCLOCK_MASK 0xffffffff
+#define WBSYNC3_BTCLOCK_GET(x) (((x) & WBSYNC3_BTCLOCK_MASK) >> WBSYNC3_BTCLOCK_LSB)
+#define WBSYNC3_BTCLOCK_SET(x) (((x) << WBSYNC3_BTCLOCK_LSB) & WBSYNC3_BTCLOCK_MASK)
+
+#define WB_TIMER_TARGET_ADDRESS 0x0000025c
+#define WB_TIMER_TARGET_OFFSET 0x0000025c
+#define WB_TIMER_TARGET_VALUE_MSB 31
+#define WB_TIMER_TARGET_VALUE_LSB 0
+#define WB_TIMER_TARGET_VALUE_MASK 0xffffffff
+#define WB_TIMER_TARGET_VALUE_GET(x) (((x) & WB_TIMER_TARGET_VALUE_MASK) >> WB_TIMER_TARGET_VALUE_LSB)
+#define WB_TIMER_TARGET_VALUE_SET(x) (((x) << WB_TIMER_TARGET_VALUE_LSB) & WB_TIMER_TARGET_VALUE_MASK)
+
+#define WB_TIMER_SLOP_ADDRESS 0x00000260
+#define WB_TIMER_SLOP_OFFSET 0x00000260
+#define WB_TIMER_SLOP_VALUE_MSB 9
+#define WB_TIMER_SLOP_VALUE_LSB 0
+#define WB_TIMER_SLOP_VALUE_MASK 0x000003ff
+#define WB_TIMER_SLOP_VALUE_GET(x) (((x) & WB_TIMER_SLOP_VALUE_MASK) >> WB_TIMER_SLOP_VALUE_LSB)
+#define WB_TIMER_SLOP_VALUE_SET(x) (((x) << WB_TIMER_SLOP_VALUE_LSB) & WB_TIMER_SLOP_VALUE_MASK)
+
+#define BTCOEX_INT_EN_ADDRESS 0x00000264
+#define BTCOEX_INT_EN_OFFSET 0x00000264
+#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MSB 11
+#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB 11
+#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK 0x00000800
+#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_GET(x) (((x) & BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB)
+#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_SET(x) (((x) << BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK)
+#define BTCOEX_INT_EN_I2C_TX_FAILED_MSB 10
+#define BTCOEX_INT_EN_I2C_TX_FAILED_LSB 10
+#define BTCOEX_INT_EN_I2C_TX_FAILED_MASK 0x00000400
+#define BTCOEX_INT_EN_I2C_TX_FAILED_GET(x) (((x) & BTCOEX_INT_EN_I2C_TX_FAILED_MASK) >> BTCOEX_INT_EN_I2C_TX_FAILED_LSB)
+#define BTCOEX_INT_EN_I2C_TX_FAILED_SET(x) (((x) << BTCOEX_INT_EN_I2C_TX_FAILED_LSB) & BTCOEX_INT_EN_I2C_TX_FAILED_MASK)
+#define BTCOEX_INT_EN_I2C_MESG_SENT_MSB 9
+#define BTCOEX_INT_EN_I2C_MESG_SENT_LSB 9
+#define BTCOEX_INT_EN_I2C_MESG_SENT_MASK 0x00000200
+#define BTCOEX_INT_EN_I2C_MESG_SENT_GET(x) (((x) & BTCOEX_INT_EN_I2C_MESG_SENT_MASK) >> BTCOEX_INT_EN_I2C_MESG_SENT_LSB)
+#define BTCOEX_INT_EN_I2C_MESG_SENT_SET(x) (((x) << BTCOEX_INT_EN_I2C_MESG_SENT_LSB) & BTCOEX_INT_EN_I2C_MESG_SENT_MASK)
+#define BTCOEX_INT_EN_ST_MESG_RECV_MSB 8
+#define BTCOEX_INT_EN_ST_MESG_RECV_LSB 8
+#define BTCOEX_INT_EN_ST_MESG_RECV_MASK 0x00000100
+#define BTCOEX_INT_EN_ST_MESG_RECV_GET(x) (((x) & BTCOEX_INT_EN_ST_MESG_RECV_MASK) >> BTCOEX_INT_EN_ST_MESG_RECV_LSB)
+#define BTCOEX_INT_EN_ST_MESG_RECV_SET(x) (((x) << BTCOEX_INT_EN_ST_MESG_RECV_LSB) & BTCOEX_INT_EN_ST_MESG_RECV_MASK)
+#define BTCOEX_INT_EN_WB_TIMER_MSB 7
+#define BTCOEX_INT_EN_WB_TIMER_LSB 7
+#define BTCOEX_INT_EN_WB_TIMER_MASK 0x00000080
+#define BTCOEX_INT_EN_WB_TIMER_GET(x) (((x) & BTCOEX_INT_EN_WB_TIMER_MASK) >> BTCOEX_INT_EN_WB_TIMER_LSB)
+#define BTCOEX_INT_EN_WB_TIMER_SET(x) (((x) << BTCOEX_INT_EN_WB_TIMER_LSB) & BTCOEX_INT_EN_WB_TIMER_MASK)
+#define BTCOEX_INT_EN_NOSYNC_MSB 4
+#define BTCOEX_INT_EN_NOSYNC_LSB 4
+#define BTCOEX_INT_EN_NOSYNC_MASK 0x00000010
+#define BTCOEX_INT_EN_NOSYNC_GET(x) (((x) & BTCOEX_INT_EN_NOSYNC_MASK) >> BTCOEX_INT_EN_NOSYNC_LSB)
+#define BTCOEX_INT_EN_NOSYNC_SET(x) (((x) << BTCOEX_INT_EN_NOSYNC_LSB) & BTCOEX_INT_EN_NOSYNC_MASK)
+#define BTCOEX_INT_EN_SYNC_MSB 3
+#define BTCOEX_INT_EN_SYNC_LSB 3
+#define BTCOEX_INT_EN_SYNC_MASK 0x00000008
+#define BTCOEX_INT_EN_SYNC_GET(x) (((x) & BTCOEX_INT_EN_SYNC_MASK) >> BTCOEX_INT_EN_SYNC_LSB)
+#define BTCOEX_INT_EN_SYNC_SET(x) (((x) << BTCOEX_INT_EN_SYNC_LSB) & BTCOEX_INT_EN_SYNC_MASK)
+#define BTCOEX_INT_EN_END_MSB 2
+#define BTCOEX_INT_EN_END_LSB 2
+#define BTCOEX_INT_EN_END_MASK 0x00000004
+#define BTCOEX_INT_EN_END_GET(x) (((x) & BTCOEX_INT_EN_END_MASK) >> BTCOEX_INT_EN_END_LSB)
+#define BTCOEX_INT_EN_END_SET(x) (((x) << BTCOEX_INT_EN_END_LSB) & BTCOEX_INT_EN_END_MASK)
+#define BTCOEX_INT_EN_FRAME_CNT_MSB 1
+#define BTCOEX_INT_EN_FRAME_CNT_LSB 1
+#define BTCOEX_INT_EN_FRAME_CNT_MASK 0x00000002
+#define BTCOEX_INT_EN_FRAME_CNT_GET(x) (((x) & BTCOEX_INT_EN_FRAME_CNT_MASK) >> BTCOEX_INT_EN_FRAME_CNT_LSB)
+#define BTCOEX_INT_EN_FRAME_CNT_SET(x) (((x) << BTCOEX_INT_EN_FRAME_CNT_LSB) & BTCOEX_INT_EN_FRAME_CNT_MASK)
+#define BTCOEX_INT_EN_CLK_CNT_MSB 0
+#define BTCOEX_INT_EN_CLK_CNT_LSB 0
+#define BTCOEX_INT_EN_CLK_CNT_MASK 0x00000001
+#define BTCOEX_INT_EN_CLK_CNT_GET(x) (((x) & BTCOEX_INT_EN_CLK_CNT_MASK) >> BTCOEX_INT_EN_CLK_CNT_LSB)
+#define BTCOEX_INT_EN_CLK_CNT_SET(x) (((x) << BTCOEX_INT_EN_CLK_CNT_LSB) & BTCOEX_INT_EN_CLK_CNT_MASK)
+
+#define BTCOEX_INT_STAT_ADDRESS 0x00000268
+#define BTCOEX_INT_STAT_OFFSET 0x00000268
+#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MSB 11
+#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB 11
+#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK 0x00000800
+#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_GET(x) (((x) & BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB)
+#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_SET(x) (((x) << BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK)
+#define BTCOEX_INT_STAT_I2C_TX_FAILED_MSB 10
+#define BTCOEX_INT_STAT_I2C_TX_FAILED_LSB 10
+#define BTCOEX_INT_STAT_I2C_TX_FAILED_MASK 0x00000400
+#define BTCOEX_INT_STAT_I2C_TX_FAILED_GET(x) (((x) & BTCOEX_INT_STAT_I2C_TX_FAILED_MASK) >> BTCOEX_INT_STAT_I2C_TX_FAILED_LSB)
+#define BTCOEX_INT_STAT_I2C_TX_FAILED_SET(x) (((x) << BTCOEX_INT_STAT_I2C_TX_FAILED_LSB) & BTCOEX_INT_STAT_I2C_TX_FAILED_MASK)
+#define BTCOEX_INT_STAT_I2C_MESG_SENT_MSB 9
+#define BTCOEX_INT_STAT_I2C_MESG_SENT_LSB 9
+#define BTCOEX_INT_STAT_I2C_MESG_SENT_MASK 0x00000200
+#define BTCOEX_INT_STAT_I2C_MESG_SENT_GET(x) (((x) & BTCOEX_INT_STAT_I2C_MESG_SENT_MASK) >> BTCOEX_INT_STAT_I2C_MESG_SENT_LSB)
+#define BTCOEX_INT_STAT_I2C_MESG_SENT_SET(x) (((x) << BTCOEX_INT_STAT_I2C_MESG_SENT_LSB) & BTCOEX_INT_STAT_I2C_MESG_SENT_MASK)
+#define BTCOEX_INT_STAT_I2C_MESG_RECV_MSB 8
+#define BTCOEX_INT_STAT_I2C_MESG_RECV_LSB 8
+#define BTCOEX_INT_STAT_I2C_MESG_RECV_MASK 0x00000100
+#define BTCOEX_INT_STAT_I2C_MESG_RECV_GET(x) (((x) & BTCOEX_INT_STAT_I2C_MESG_RECV_MASK) >> BTCOEX_INT_STAT_I2C_MESG_RECV_LSB)
+#define BTCOEX_INT_STAT_I2C_MESG_RECV_SET(x) (((x) << BTCOEX_INT_STAT_I2C_MESG_RECV_LSB) & BTCOEX_INT_STAT_I2C_MESG_RECV_MASK)
+#define BTCOEX_INT_STAT_WB_TIMER_MSB 7
+#define BTCOEX_INT_STAT_WB_TIMER_LSB 7
+#define BTCOEX_INT_STAT_WB_TIMER_MASK 0x00000080
+#define BTCOEX_INT_STAT_WB_TIMER_GET(x) (((x) & BTCOEX_INT_STAT_WB_TIMER_MASK) >> BTCOEX_INT_STAT_WB_TIMER_LSB)
+#define BTCOEX_INT_STAT_WB_TIMER_SET(x) (((x) << BTCOEX_INT_STAT_WB_TIMER_LSB) & BTCOEX_INT_STAT_WB_TIMER_MASK)
+#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MSB 6
+#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB 6
+#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK 0x00000040
+#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_GET(x) (((x) & BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB)
+#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_SET(x) (((x) << BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB) & BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK)
+#define BTCOEX_INT_STAT_BTPRIORITY_MSB 5
+#define BTCOEX_INT_STAT_BTPRIORITY_LSB 5
+#define BTCOEX_INT_STAT_BTPRIORITY_MASK 0x00000020
+#define BTCOEX_INT_STAT_BTPRIORITY_GET(x) (((x) & BTCOEX_INT_STAT_BTPRIORITY_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_LSB)
+#define BTCOEX_INT_STAT_BTPRIORITY_SET(x) (((x) << BTCOEX_INT_STAT_BTPRIORITY_LSB) & BTCOEX_INT_STAT_BTPRIORITY_MASK)
+#define BTCOEX_INT_STAT_NOSYNC_MSB 4
+#define BTCOEX_INT_STAT_NOSYNC_LSB 4
+#define BTCOEX_INT_STAT_NOSYNC_MASK 0x00000010
+#define BTCOEX_INT_STAT_NOSYNC_GET(x) (((x) & BTCOEX_INT_STAT_NOSYNC_MASK) >> BTCOEX_INT_STAT_NOSYNC_LSB)
+#define BTCOEX_INT_STAT_NOSYNC_SET(x) (((x) << BTCOEX_INT_STAT_NOSYNC_LSB) & BTCOEX_INT_STAT_NOSYNC_MASK)
+#define BTCOEX_INT_STAT_SYNC_MSB 3
+#define BTCOEX_INT_STAT_SYNC_LSB 3
+#define BTCOEX_INT_STAT_SYNC_MASK 0x00000008
+#define BTCOEX_INT_STAT_SYNC_GET(x) (((x) & BTCOEX_INT_STAT_SYNC_MASK) >> BTCOEX_INT_STAT_SYNC_LSB)
+#define BTCOEX_INT_STAT_SYNC_SET(x) (((x) << BTCOEX_INT_STAT_SYNC_LSB) & BTCOEX_INT_STAT_SYNC_MASK)
+#define BTCOEX_INT_STAT_END_MSB 2
+#define BTCOEX_INT_STAT_END_LSB 2
+#define BTCOEX_INT_STAT_END_MASK 0x00000004
+#define BTCOEX_INT_STAT_END_GET(x) (((x) & BTCOEX_INT_STAT_END_MASK) >> BTCOEX_INT_STAT_END_LSB)
+#define BTCOEX_INT_STAT_END_SET(x) (((x) << BTCOEX_INT_STAT_END_LSB) & BTCOEX_INT_STAT_END_MASK)
+#define BTCOEX_INT_STAT_FRAME_CNT_MSB 1
+#define BTCOEX_INT_STAT_FRAME_CNT_LSB 1
+#define BTCOEX_INT_STAT_FRAME_CNT_MASK 0x00000002
+#define BTCOEX_INT_STAT_FRAME_CNT_GET(x) (((x) & BTCOEX_INT_STAT_FRAME_CNT_MASK) >> BTCOEX_INT_STAT_FRAME_CNT_LSB)
+#define BTCOEX_INT_STAT_FRAME_CNT_SET(x) (((x) << BTCOEX_INT_STAT_FRAME_CNT_LSB) & BTCOEX_INT_STAT_FRAME_CNT_MASK)
+#define BTCOEX_INT_STAT_CLK_CNT_MSB 0
+#define BTCOEX_INT_STAT_CLK_CNT_LSB 0
+#define BTCOEX_INT_STAT_CLK_CNT_MASK 0x00000001
+#define BTCOEX_INT_STAT_CLK_CNT_GET(x) (((x) & BTCOEX_INT_STAT_CLK_CNT_MASK) >> BTCOEX_INT_STAT_CLK_CNT_LSB)
+#define BTCOEX_INT_STAT_CLK_CNT_SET(x) (((x) << BTCOEX_INT_STAT_CLK_CNT_LSB) & BTCOEX_INT_STAT_CLK_CNT_MASK)
+
+#define BTPRIORITY_INT_EN_ADDRESS 0x0000026c
+#define BTPRIORITY_INT_EN_OFFSET 0x0000026c
+#define BTPRIORITY_INT_EN_BITMAP_MSB 31
+#define BTPRIORITY_INT_EN_BITMAP_LSB 0
+#define BTPRIORITY_INT_EN_BITMAP_MASK 0xffffffff
+#define BTPRIORITY_INT_EN_BITMAP_GET(x) (((x) & BTPRIORITY_INT_EN_BITMAP_MASK) >> BTPRIORITY_INT_EN_BITMAP_LSB)
+#define BTPRIORITY_INT_EN_BITMAP_SET(x) (((x) << BTPRIORITY_INT_EN_BITMAP_LSB) & BTPRIORITY_INT_EN_BITMAP_MASK)
+
+#define BTPRIORITY_INT_STAT_ADDRESS 0x00000270
+#define BTPRIORITY_INT_STAT_OFFSET 0x00000270
+#define BTPRIORITY_INT_STAT_BITMAP_MSB 31
+#define BTPRIORITY_INT_STAT_BITMAP_LSB 0
+#define BTPRIORITY_INT_STAT_BITMAP_MASK 0xffffffff
+#define BTPRIORITY_INT_STAT_BITMAP_GET(x) (((x) & BTPRIORITY_INT_STAT_BITMAP_MASK) >> BTPRIORITY_INT_STAT_BITMAP_LSB)
+#define BTPRIORITY_INT_STAT_BITMAP_SET(x) (((x) << BTPRIORITY_INT_STAT_BITMAP_LSB) & BTPRIORITY_INT_STAT_BITMAP_MASK)
+
+#define BTPRIORITY_STOMP_INT_EN_ADDRESS 0x00000274
+#define BTPRIORITY_STOMP_INT_EN_OFFSET 0x00000274
+#define BTPRIORITY_STOMP_INT_EN_BITMAP_MSB 31
+#define BTPRIORITY_STOMP_INT_EN_BITMAP_LSB 0
+#define BTPRIORITY_STOMP_INT_EN_BITMAP_MASK 0xffffffff
+#define BTPRIORITY_STOMP_INT_EN_BITMAP_GET(x) (((x) & BTPRIORITY_STOMP_INT_EN_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_EN_BITMAP_LSB)
+#define BTPRIORITY_STOMP_INT_EN_BITMAP_SET(x) (((x) << BTPRIORITY_STOMP_INT_EN_BITMAP_LSB) & BTPRIORITY_STOMP_INT_EN_BITMAP_MASK)
+
+#define BTPRIORITY_STOMP_INT_STAT_ADDRESS 0x00000278
+#define BTPRIORITY_STOMP_INT_STAT_OFFSET 0x00000278
+#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MSB 31
+#define BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB 0
+#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK 0xffffffff
+#define BTPRIORITY_STOMP_INT_STAT_BITMAP_GET(x) (((x) & BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB)
+#define BTPRIORITY_STOMP_INT_STAT_BITMAP_SET(x) (((x) << BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB) & BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK)
+
+#define MAC_PCU_BMISS_TIMEOUT_ADDRESS 0x0000027c
+#define MAC_PCU_BMISS_TIMEOUT_OFFSET 0x0000027c
+#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MSB 24
+#define MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB 24
+#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK 0x01000000
+#define MAC_PCU_BMISS_TIMEOUT_ENABLE_GET(x) (((x) & MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB)
+#define MAC_PCU_BMISS_TIMEOUT_ENABLE_SET(x) (((x) << MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK)
+#define MAC_PCU_BMISS_TIMEOUT_VALUE_MSB 23
+#define MAC_PCU_BMISS_TIMEOUT_VALUE_LSB 0
+#define MAC_PCU_BMISS_TIMEOUT_VALUE_MASK 0x00ffffff
+#define MAC_PCU_BMISS_TIMEOUT_VALUE_GET(x) (((x) & MAC_PCU_BMISS_TIMEOUT_VALUE_MASK) >> MAC_PCU_BMISS_TIMEOUT_VALUE_LSB)
+#define MAC_PCU_BMISS_TIMEOUT_VALUE_SET(x) (((x) << MAC_PCU_BMISS_TIMEOUT_VALUE_LSB) & MAC_PCU_BMISS_TIMEOUT_VALUE_MASK)
+
+#define MAC_PCU_CAB_AWAKE_ADDRESS 0x00000280
+#define MAC_PCU_CAB_AWAKE_OFFSET 0x00000280
+#define MAC_PCU_CAB_AWAKE_ENABLE_MSB 16
+#define MAC_PCU_CAB_AWAKE_ENABLE_LSB 16
+#define MAC_PCU_CAB_AWAKE_ENABLE_MASK 0x00010000
+#define MAC_PCU_CAB_AWAKE_ENABLE_GET(x) (((x) & MAC_PCU_CAB_AWAKE_ENABLE_MASK) >> MAC_PCU_CAB_AWAKE_ENABLE_LSB)
+#define MAC_PCU_CAB_AWAKE_ENABLE_SET(x) (((x) << MAC_PCU_CAB_AWAKE_ENABLE_LSB) & MAC_PCU_CAB_AWAKE_ENABLE_MASK)
+#define MAC_PCU_CAB_AWAKE_DURATION_MSB 15
+#define MAC_PCU_CAB_AWAKE_DURATION_LSB 0
+#define MAC_PCU_CAB_AWAKE_DURATION_MASK 0x0000ffff
+#define MAC_PCU_CAB_AWAKE_DURATION_GET(x) (((x) & MAC_PCU_CAB_AWAKE_DURATION_MASK) >> MAC_PCU_CAB_AWAKE_DURATION_LSB)
+#define MAC_PCU_CAB_AWAKE_DURATION_SET(x) (((x) << MAC_PCU_CAB_AWAKE_DURATION_LSB) & MAC_PCU_CAB_AWAKE_DURATION_MASK)
+
+#define LP_PERF_COUNTER_ADDRESS 0x00000284
+#define LP_PERF_COUNTER_OFFSET 0x00000284
+#define LP_PERF_COUNTER_EN_MSB 0
+#define LP_PERF_COUNTER_EN_LSB 0
+#define LP_PERF_COUNTER_EN_MASK 0x00000001
+#define LP_PERF_COUNTER_EN_GET(x) (((x) & LP_PERF_COUNTER_EN_MASK) >> LP_PERF_COUNTER_EN_LSB)
+#define LP_PERF_COUNTER_EN_SET(x) (((x) << LP_PERF_COUNTER_EN_LSB) & LP_PERF_COUNTER_EN_MASK)
+
+#define LP_PERF_LIGHT_SLEEP_ADDRESS 0x00000288
+#define LP_PERF_LIGHT_SLEEP_OFFSET 0x00000288
+#define LP_PERF_LIGHT_SLEEP_CNT_MSB 31
+#define LP_PERF_LIGHT_SLEEP_CNT_LSB 0
+#define LP_PERF_LIGHT_SLEEP_CNT_MASK 0xffffffff
+#define LP_PERF_LIGHT_SLEEP_CNT_GET(x) (((x) & LP_PERF_LIGHT_SLEEP_CNT_MASK) >> LP_PERF_LIGHT_SLEEP_CNT_LSB)
+#define LP_PERF_LIGHT_SLEEP_CNT_SET(x) (((x) << LP_PERF_LIGHT_SLEEP_CNT_LSB) & LP_PERF_LIGHT_SLEEP_CNT_MASK)
+
+#define LP_PERF_DEEP_SLEEP_ADDRESS 0x0000028c
+#define LP_PERF_DEEP_SLEEP_OFFSET 0x0000028c
+#define LP_PERF_DEEP_SLEEP_CNT_MSB 31
+#define LP_PERF_DEEP_SLEEP_CNT_LSB 0
+#define LP_PERF_DEEP_SLEEP_CNT_MASK 0xffffffff
+#define LP_PERF_DEEP_SLEEP_CNT_GET(x) (((x) & LP_PERF_DEEP_SLEEP_CNT_MASK) >> LP_PERF_DEEP_SLEEP_CNT_LSB)
+#define LP_PERF_DEEP_SLEEP_CNT_SET(x) (((x) << LP_PERF_DEEP_SLEEP_CNT_LSB) & LP_PERF_DEEP_SLEEP_CNT_MASK)
+
+#define LP_PERF_ON_ADDRESS 0x00000290
+#define LP_PERF_ON_OFFSET 0x00000290
+#define LP_PERF_ON_CNT_MSB 31
+#define LP_PERF_ON_CNT_LSB 0
+#define LP_PERF_ON_CNT_MASK 0xffffffff
+#define LP_PERF_ON_CNT_GET(x) (((x) & LP_PERF_ON_CNT_MASK) >> LP_PERF_ON_CNT_LSB)
+#define LP_PERF_ON_CNT_SET(x) (((x) << LP_PERF_ON_CNT_LSB) & LP_PERF_ON_CNT_MASK)
+
+#define ST_64_BIT_ADDRESS 0x00000294
+#define ST_64_BIT_OFFSET 0x00000294
+#define ST_64_BIT_TIMEOUT_MSB 26
+#define ST_64_BIT_TIMEOUT_LSB 9
+#define ST_64_BIT_TIMEOUT_MASK 0x07fffe00
+#define ST_64_BIT_TIMEOUT_GET(x) (((x) & ST_64_BIT_TIMEOUT_MASK) >> ST_64_BIT_TIMEOUT_LSB)
+#define ST_64_BIT_TIMEOUT_SET(x) (((x) << ST_64_BIT_TIMEOUT_LSB) & ST_64_BIT_TIMEOUT_MASK)
+#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MSB 8
+#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB 8
+#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK 0x00000100
+#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_GET(x) (((x) & ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK) >> ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB)
+#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_SET(x) (((x) << ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB) & ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK)
+#define ST_64_BIT_DRIVE_MODE_MSB 7
+#define ST_64_BIT_DRIVE_MODE_LSB 7
+#define ST_64_BIT_DRIVE_MODE_MASK 0x00000080
+#define ST_64_BIT_DRIVE_MODE_GET(x) (((x) & ST_64_BIT_DRIVE_MODE_MASK) >> ST_64_BIT_DRIVE_MODE_LSB)
+#define ST_64_BIT_DRIVE_MODE_SET(x) (((x) << ST_64_BIT_DRIVE_MODE_LSB) & ST_64_BIT_DRIVE_MODE_MASK)
+#define ST_64_BIT_CLOCK_GATE_MSB 6
+#define ST_64_BIT_CLOCK_GATE_LSB 6
+#define ST_64_BIT_CLOCK_GATE_MASK 0x00000040
+#define ST_64_BIT_CLOCK_GATE_GET(x) (((x) & ST_64_BIT_CLOCK_GATE_MASK) >> ST_64_BIT_CLOCK_GATE_LSB)
+#define ST_64_BIT_CLOCK_GATE_SET(x) (((x) << ST_64_BIT_CLOCK_GATE_LSB) & ST_64_BIT_CLOCK_GATE_MASK)
+#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MSB 5
+#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB 1
+#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK 0x0000003e
+#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_GET(x) (((x) & ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK) >> ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB)
+#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_SET(x) (((x) << ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB) & ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK)
+#define ST_64_BIT_MODE_MSB 0
+#define ST_64_BIT_MODE_LSB 0
+#define ST_64_BIT_MODE_MASK 0x00000001
+#define ST_64_BIT_MODE_GET(x) (((x) & ST_64_BIT_MODE_MASK) >> ST_64_BIT_MODE_LSB)
+#define ST_64_BIT_MODE_SET(x) (((x) << ST_64_BIT_MODE_LSB) & ST_64_BIT_MODE_MASK)
+
+#define MESSAGE_WR_ADDRESS 0x00000298
+#define MESSAGE_WR_OFFSET 0x00000298
+#define MESSAGE_WR_TYPE_MSB 31
+#define MESSAGE_WR_TYPE_LSB 0
+#define MESSAGE_WR_TYPE_MASK 0xffffffff
+#define MESSAGE_WR_TYPE_GET(x) (((x) & MESSAGE_WR_TYPE_MASK) >> MESSAGE_WR_TYPE_LSB)
+#define MESSAGE_WR_TYPE_SET(x) (((x) << MESSAGE_WR_TYPE_LSB) & MESSAGE_WR_TYPE_MASK)
+
+#define MESSAGE_WR_P_ADDRESS 0x0000029c
+#define MESSAGE_WR_P_OFFSET 0x0000029c
+#define MESSAGE_WR_P_PARAMETER_MSB 31
+#define MESSAGE_WR_P_PARAMETER_LSB 0
+#define MESSAGE_WR_P_PARAMETER_MASK 0xffffffff
+#define MESSAGE_WR_P_PARAMETER_GET(x) (((x) & MESSAGE_WR_P_PARAMETER_MASK) >> MESSAGE_WR_P_PARAMETER_LSB)
+#define MESSAGE_WR_P_PARAMETER_SET(x) (((x) << MESSAGE_WR_P_PARAMETER_LSB) & MESSAGE_WR_P_PARAMETER_MASK)
+
+#define MESSAGE_RD_ADDRESS 0x000002a0
+#define MESSAGE_RD_OFFSET 0x000002a0
+#define MESSAGE_RD_TYPE_MSB 31
+#define MESSAGE_RD_TYPE_LSB 0
+#define MESSAGE_RD_TYPE_MASK 0xffffffff
+#define MESSAGE_RD_TYPE_GET(x) (((x) & MESSAGE_RD_TYPE_MASK) >> MESSAGE_RD_TYPE_LSB)
+#define MESSAGE_RD_TYPE_SET(x) (((x) << MESSAGE_RD_TYPE_LSB) & MESSAGE_RD_TYPE_MASK)
+
+#define MESSAGE_RD_P_ADDRESS 0x000002a4
+#define MESSAGE_RD_P_OFFSET 0x000002a4
+#define MESSAGE_RD_P_PARAMETER_MSB 31
+#define MESSAGE_RD_P_PARAMETER_LSB 0
+#define MESSAGE_RD_P_PARAMETER_MASK 0xffffffff
+#define MESSAGE_RD_P_PARAMETER_GET(x) (((x) & MESSAGE_RD_P_PARAMETER_MASK) >> MESSAGE_RD_P_PARAMETER_LSB)
+#define MESSAGE_RD_P_PARAMETER_SET(x) (((x) << MESSAGE_RD_P_PARAMETER_LSB) & MESSAGE_RD_P_PARAMETER_MASK)
+
+#define CHIP_MODE_ADDRESS 0x000002a8
+#define CHIP_MODE_OFFSET 0x000002a8
+#define CHIP_MODE_BIT_MSB 1
+#define CHIP_MODE_BIT_LSB 0
+#define CHIP_MODE_BIT_MASK 0x00000003
+#define CHIP_MODE_BIT_GET(x) (((x) & CHIP_MODE_BIT_MASK) >> CHIP_MODE_BIT_LSB)
+#define CHIP_MODE_BIT_SET(x) (((x) << CHIP_MODE_BIT_LSB) & CHIP_MODE_BIT_MASK)
+
+#define CLK_REQ_FALL_EDGE_ADDRESS 0x000002ac
+#define CLK_REQ_FALL_EDGE_OFFSET 0x000002ac
+#define CLK_REQ_FALL_EDGE_EN_MSB 31
+#define CLK_REQ_FALL_EDGE_EN_LSB 31
+#define CLK_REQ_FALL_EDGE_EN_MASK 0x80000000
+#define CLK_REQ_FALL_EDGE_EN_GET(x) (((x) & CLK_REQ_FALL_EDGE_EN_MASK) >> CLK_REQ_FALL_EDGE_EN_LSB)
+#define CLK_REQ_FALL_EDGE_EN_SET(x) (((x) << CLK_REQ_FALL_EDGE_EN_LSB) & CLK_REQ_FALL_EDGE_EN_MASK)
+#define CLK_REQ_FALL_EDGE_DELAY_MSB 7
+#define CLK_REQ_FALL_EDGE_DELAY_LSB 0
+#define CLK_REQ_FALL_EDGE_DELAY_MASK 0x000000ff
+#define CLK_REQ_FALL_EDGE_DELAY_GET(x) (((x) & CLK_REQ_FALL_EDGE_DELAY_MASK) >> CLK_REQ_FALL_EDGE_DELAY_LSB)
+#define CLK_REQ_FALL_EDGE_DELAY_SET(x) (((x) << CLK_REQ_FALL_EDGE_DELAY_LSB) & CLK_REQ_FALL_EDGE_DELAY_MASK)
+
+#define OTP_ADDRESS 0x000002b0
+#define OTP_OFFSET 0x000002b0
+#define OTP_LDO25_EN_MSB 1
+#define OTP_LDO25_EN_LSB 1
+#define OTP_LDO25_EN_MASK 0x00000002
+#define OTP_LDO25_EN_GET(x) (((x) & OTP_LDO25_EN_MASK) >> OTP_LDO25_EN_LSB)
+#define OTP_LDO25_EN_SET(x) (((x) << OTP_LDO25_EN_LSB) & OTP_LDO25_EN_MASK)
+#define OTP_VDD12_EN_MSB 0
+#define OTP_VDD12_EN_LSB 0
+#define OTP_VDD12_EN_MASK 0x00000001
+#define OTP_VDD12_EN_GET(x) (((x) & OTP_VDD12_EN_MASK) >> OTP_VDD12_EN_LSB)
+#define OTP_VDD12_EN_SET(x) (((x) << OTP_VDD12_EN_LSB) & OTP_VDD12_EN_MASK)
+
+#define OTP_STATUS_ADDRESS 0x000002b4
+#define OTP_STATUS_OFFSET 0x000002b4
+#define OTP_STATUS_LDO25_EN_READY_MSB 1
+#define OTP_STATUS_LDO25_EN_READY_LSB 1
+#define OTP_STATUS_LDO25_EN_READY_MASK 0x00000002
+#define OTP_STATUS_LDO25_EN_READY_GET(x) (((x) & OTP_STATUS_LDO25_EN_READY_MASK) >> OTP_STATUS_LDO25_EN_READY_LSB)
+#define OTP_STATUS_LDO25_EN_READY_SET(x) (((x) << OTP_STATUS_LDO25_EN_READY_LSB) & OTP_STATUS_LDO25_EN_READY_MASK)
+#define OTP_STATUS_VDD12_EN_READY_MSB 0
+#define OTP_STATUS_VDD12_EN_READY_LSB 0
+#define OTP_STATUS_VDD12_EN_READY_MASK 0x00000001
+#define OTP_STATUS_VDD12_EN_READY_GET(x) (((x) & OTP_STATUS_VDD12_EN_READY_MASK) >> OTP_STATUS_VDD12_EN_READY_LSB)
+#define OTP_STATUS_VDD12_EN_READY_SET(x) (((x) << OTP_STATUS_VDD12_EN_READY_LSB) & OTP_STATUS_VDD12_EN_READY_MASK)
+
+#define PMU_ADDRESS 0x000002b8
+#define PMU_OFFSET 0x000002b8
+#define PMU_REG_WAKEUP_TIME_SEL_MSB 1
+#define PMU_REG_WAKEUP_TIME_SEL_LSB 0
+#define PMU_REG_WAKEUP_TIME_SEL_MASK 0x00000003
+#define PMU_REG_WAKEUP_TIME_SEL_GET(x) (((x) & PMU_REG_WAKEUP_TIME_SEL_MASK) >> PMU_REG_WAKEUP_TIME_SEL_LSB)
+#define PMU_REG_WAKEUP_TIME_SEL_SET(x) (((x) << PMU_REG_WAKEUP_TIME_SEL_LSB) & PMU_REG_WAKEUP_TIME_SEL_MASK)
+
+#define PMU_CONFIG_ADDRESS 0x000002c0
+#define PMU_CONFIG_OFFSET 0x000002c0
+#define PMU_CONFIG_VALUE_MSB 15
+#define PMU_CONFIG_VALUE_LSB 0
+#define PMU_CONFIG_VALUE_MASK 0x0000ffff
+#define PMU_CONFIG_VALUE_GET(x) (((x) & PMU_CONFIG_VALUE_MASK) >> PMU_CONFIG_VALUE_LSB)
+#define PMU_CONFIG_VALUE_SET(x) (((x) << PMU_CONFIG_VALUE_LSB) & PMU_CONFIG_VALUE_MASK)
+
+#define PMU_BYPASS_ADDRESS 0x000002c8
+#define PMU_BYPASS_OFFSET 0x000002c8
+#define PMU_BYPASS_SWREG_MSB 2
+#define PMU_BYPASS_SWREG_LSB 2
+#define PMU_BYPASS_SWREG_MASK 0x00000004
+#define PMU_BYPASS_SWREG_GET(x) (((x) & PMU_BYPASS_SWREG_MASK) >> PMU_BYPASS_SWREG_LSB)
+#define PMU_BYPASS_SWREG_SET(x) (((x) << PMU_BYPASS_SWREG_LSB) & PMU_BYPASS_SWREG_MASK)
+#define PMU_BYPASS_DREG_MSB 1
+#define PMU_BYPASS_DREG_LSB 1
+#define PMU_BYPASS_DREG_MASK 0x00000002
+#define PMU_BYPASS_DREG_GET(x) (((x) & PMU_BYPASS_DREG_MASK) >> PMU_BYPASS_DREG_LSB)
+#define PMU_BYPASS_DREG_SET(x) (((x) << PMU_BYPASS_DREG_LSB) & PMU_BYPASS_DREG_MASK)
+#define PMU_BYPASS_PAREG_MSB 0
+#define PMU_BYPASS_PAREG_LSB 0
+#define PMU_BYPASS_PAREG_MASK 0x00000001
+#define PMU_BYPASS_PAREG_GET(x) (((x) & PMU_BYPASS_PAREG_MASK) >> PMU_BYPASS_PAREG_LSB)
+#define PMU_BYPASS_PAREG_SET(x) (((x) << PMU_BYPASS_PAREG_LSB) & PMU_BYPASS_PAREG_MASK)
+
+#define MAC_PCU_TSF2_L32_ADDRESS 0x000002cc
+#define MAC_PCU_TSF2_L32_OFFSET 0x000002cc
+#define MAC_PCU_TSF2_L32_VALUE_MSB 31
+#define MAC_PCU_TSF2_L32_VALUE_LSB 0
+#define MAC_PCU_TSF2_L32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF2_L32_VALUE_GET(x) (((x) & MAC_PCU_TSF2_L32_VALUE_MASK) >> MAC_PCU_TSF2_L32_VALUE_LSB)
+#define MAC_PCU_TSF2_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_L32_VALUE_LSB) & MAC_PCU_TSF2_L32_VALUE_MASK)
+
+#define MAC_PCU_TSF2_U32_ADDRESS 0x000002d0
+#define MAC_PCU_TSF2_U32_OFFSET 0x000002d0
+#define MAC_PCU_TSF2_U32_VALUE_MSB 31
+#define MAC_PCU_TSF2_U32_VALUE_LSB 0
+#define MAC_PCU_TSF2_U32_VALUE_MASK 0xffffffff
+#define MAC_PCU_TSF2_U32_VALUE_GET(x) (((x) & MAC_PCU_TSF2_U32_VALUE_MASK) >> MAC_PCU_TSF2_U32_VALUE_LSB)
+#define MAC_PCU_TSF2_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_U32_VALUE_LSB) & MAC_PCU_TSF2_U32_VALUE_MASK)
+
+#define MAC_PCU_GENERIC_TIMERS_MODE3_ADDRESS 0x000002d4
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OFFSET 0x000002d4
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MSB 27
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB 24
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK 0x0f000000
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB)
+#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK)
+#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MSB 19
+#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB 0
+#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK 0x000fffff
+#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB)
+#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK)
+
+#define MAC_PCU_DIRECT_CONNECT_ADDRESS 0x000002d8
+#define MAC_PCU_DIRECT_CONNECT_OFFSET 0x000002d8
+#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MSB 2
+#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB 2
+#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK 0x00000004
+#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB)
+#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK)
+#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MSB 1
+#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB 1
+#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK 0x00000002
+#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB)
+#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK)
+#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MSB 0
+#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB 0
+#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK 0x00000001
+#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB)
+#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB) & MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK)
+
+#define THERM_CTRL1_ADDRESS 0x000002dc
+#define THERM_CTRL1_OFFSET 0x000002dc
+#define THERM_CTRL1_BYPASS_MSB 16
+#define THERM_CTRL1_BYPASS_LSB 16
+#define THERM_CTRL1_BYPASS_MASK 0x00010000
+#define THERM_CTRL1_BYPASS_GET(x) (((x) & THERM_CTRL1_BYPASS_MASK) >> THERM_CTRL1_BYPASS_LSB)
+#define THERM_CTRL1_BYPASS_SET(x) (((x) << THERM_CTRL1_BYPASS_LSB) & THERM_CTRL1_BYPASS_MASK)
+#define THERM_CTRL1_WIDTH_ARBITOR_MSB 15
+#define THERM_CTRL1_WIDTH_ARBITOR_LSB 12
+#define THERM_CTRL1_WIDTH_ARBITOR_MASK 0x0000f000
+#define THERM_CTRL1_WIDTH_ARBITOR_GET(x) (((x) & THERM_CTRL1_WIDTH_ARBITOR_MASK) >> THERM_CTRL1_WIDTH_ARBITOR_LSB)
+#define THERM_CTRL1_WIDTH_ARBITOR_SET(x) (((x) << THERM_CTRL1_WIDTH_ARBITOR_LSB) & THERM_CTRL1_WIDTH_ARBITOR_MASK)
+#define THERM_CTRL1_WIDTH_MSB 11
+#define THERM_CTRL1_WIDTH_LSB 5
+#define THERM_CTRL1_WIDTH_MASK 0x00000fe0
+#define THERM_CTRL1_WIDTH_GET(x) (((x) & THERM_CTRL1_WIDTH_MASK) >> THERM_CTRL1_WIDTH_LSB)
+#define THERM_CTRL1_WIDTH_SET(x) (((x) << THERM_CTRL1_WIDTH_LSB) & THERM_CTRL1_WIDTH_MASK)
+#define THERM_CTRL1_TYPE_MSB 4
+#define THERM_CTRL1_TYPE_LSB 3
+#define THERM_CTRL1_TYPE_MASK 0x00000018
+#define THERM_CTRL1_TYPE_GET(x) (((x) & THERM_CTRL1_TYPE_MASK) >> THERM_CTRL1_TYPE_LSB)
+#define THERM_CTRL1_TYPE_SET(x) (((x) << THERM_CTRL1_TYPE_LSB) & THERM_CTRL1_TYPE_MASK)
+#define THERM_CTRL1_MEASURE_MSB 2
+#define THERM_CTRL1_MEASURE_LSB 2
+#define THERM_CTRL1_MEASURE_MASK 0x00000004
+#define THERM_CTRL1_MEASURE_GET(x) (((x) & THERM_CTRL1_MEASURE_MASK) >> THERM_CTRL1_MEASURE_LSB)
+#define THERM_CTRL1_MEASURE_SET(x) (((x) << THERM_CTRL1_MEASURE_LSB) & THERM_CTRL1_MEASURE_MASK)
+#define THERM_CTRL1_INT_EN_MSB 1
+#define THERM_CTRL1_INT_EN_LSB 1
+#define THERM_CTRL1_INT_EN_MASK 0x00000002
+#define THERM_CTRL1_INT_EN_GET(x) (((x) & THERM_CTRL1_INT_EN_MASK) >> THERM_CTRL1_INT_EN_LSB)
+#define THERM_CTRL1_INT_EN_SET(x) (((x) << THERM_CTRL1_INT_EN_LSB) & THERM_CTRL1_INT_EN_MASK)
+#define THERM_CTRL1_INT_STATUS_MSB 0
+#define THERM_CTRL1_INT_STATUS_LSB 0
+#define THERM_CTRL1_INT_STATUS_MASK 0x00000001
+#define THERM_CTRL1_INT_STATUS_GET(x) (((x) & THERM_CTRL1_INT_STATUS_MASK) >> THERM_CTRL1_INT_STATUS_LSB)
+#define THERM_CTRL1_INT_STATUS_SET(x) (((x) << THERM_CTRL1_INT_STATUS_LSB) & THERM_CTRL1_INT_STATUS_MASK)
+
+#define THERM_CTRL2_ADDRESS 0x000002e0
+#define THERM_CTRL2_OFFSET 0x000002e0
+#define THERM_CTRL2_ADC_OFF_MSB 25
+#define THERM_CTRL2_ADC_OFF_LSB 25
+#define THERM_CTRL2_ADC_OFF_MASK 0x02000000
+#define THERM_CTRL2_ADC_OFF_GET(x) (((x) & THERM_CTRL2_ADC_OFF_MASK) >> THERM_CTRL2_ADC_OFF_LSB)
+#define THERM_CTRL2_ADC_OFF_SET(x) (((x) << THERM_CTRL2_ADC_OFF_LSB) & THERM_CTRL2_ADC_OFF_MASK)
+#define THERM_CTRL2_ADC_ON_MSB 24
+#define THERM_CTRL2_ADC_ON_LSB 24
+#define THERM_CTRL2_ADC_ON_MASK 0x01000000
+#define THERM_CTRL2_ADC_ON_GET(x) (((x) & THERM_CTRL2_ADC_ON_MASK) >> THERM_CTRL2_ADC_ON_LSB)
+#define THERM_CTRL2_ADC_ON_SET(x) (((x) << THERM_CTRL2_ADC_ON_LSB) & THERM_CTRL2_ADC_ON_MASK)
+#define THERM_CTRL2_SAMPLE_MSB 23
+#define THERM_CTRL2_SAMPLE_LSB 16
+#define THERM_CTRL2_SAMPLE_MASK 0x00ff0000
+#define THERM_CTRL2_SAMPLE_GET(x) (((x) & THERM_CTRL2_SAMPLE_MASK) >> THERM_CTRL2_SAMPLE_LSB)
+#define THERM_CTRL2_SAMPLE_SET(x) (((x) << THERM_CTRL2_SAMPLE_LSB) & THERM_CTRL2_SAMPLE_MASK)
+#define THERM_CTRL2_HIGH_MSB 15
+#define THERM_CTRL2_HIGH_LSB 8
+#define THERM_CTRL2_HIGH_MASK 0x0000ff00
+#define THERM_CTRL2_HIGH_GET(x) (((x) & THERM_CTRL2_HIGH_MASK) >> THERM_CTRL2_HIGH_LSB)
+#define THERM_CTRL2_HIGH_SET(x) (((x) << THERM_CTRL2_HIGH_LSB) & THERM_CTRL2_HIGH_MASK)
+#define THERM_CTRL2_LOW_MSB 7
+#define THERM_CTRL2_LOW_LSB 0
+#define THERM_CTRL2_LOW_MASK 0x000000ff
+#define THERM_CTRL2_LOW_GET(x) (((x) & THERM_CTRL2_LOW_MASK) >> THERM_CTRL2_LOW_LSB)
+#define THERM_CTRL2_LOW_SET(x) (((x) << THERM_CTRL2_LOW_LSB) & THERM_CTRL2_LOW_MASK)
+
+#define THERM_CTRL3_ADDRESS 0x000002e4
+#define THERM_CTRL3_OFFSET 0x000002e4
+#define THERM_CTRL3_ADC_GAIN_MSB 16
+#define THERM_CTRL3_ADC_GAIN_LSB 8
+#define THERM_CTRL3_ADC_GAIN_MASK 0x0001ff00
+#define THERM_CTRL3_ADC_GAIN_GET(x) (((x) & THERM_CTRL3_ADC_GAIN_MASK) >> THERM_CTRL3_ADC_GAIN_LSB)
+#define THERM_CTRL3_ADC_GAIN_SET(x) (((x) << THERM_CTRL3_ADC_GAIN_LSB) & THERM_CTRL3_ADC_GAIN_MASK)
+#define THERM_CTRL3_ADC_OFFSET_MSB 7
+#define THERM_CTRL3_ADC_OFFSET_LSB 0
+#define THERM_CTRL3_ADC_OFFSET_MASK 0x000000ff
+#define THERM_CTRL3_ADC_OFFSET_GET(x) (((x) & THERM_CTRL3_ADC_OFFSET_MASK) >> THERM_CTRL3_ADC_OFFSET_LSB)
+#define THERM_CTRL3_ADC_OFFSET_SET(x) (((x) << THERM_CTRL3_ADC_OFFSET_LSB) & THERM_CTRL3_ADC_OFFSET_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct rtc_wlan_reg_reg_s {
+ volatile unsigned int wlan_reset_control;
+ volatile unsigned int wlan_xtal_control;
+ volatile unsigned int wlan_tcxo_detect;
+ volatile unsigned int wlan_xtal_test;
+ volatile unsigned int wlan_quadrature;
+ volatile unsigned int wlan_pll_control;
+ volatile unsigned int wlan_pll_settle;
+ volatile unsigned int wlan_xtal_settle;
+ volatile unsigned int wlan_cpu_clock;
+ volatile unsigned int wlan_clock_out;
+ volatile unsigned int wlan_clock_control;
+ volatile unsigned int wlan_bias_override;
+ volatile unsigned int wlan_wdt_control;
+ volatile unsigned int wlan_wdt_status;
+ volatile unsigned int wlan_wdt;
+ volatile unsigned int wlan_wdt_count;
+ volatile unsigned int wlan_wdt_reset;
+ volatile unsigned int wlan_int_status;
+ volatile unsigned int wlan_lf_timer0;
+ volatile unsigned int wlan_lf_timer_count0;
+ volatile unsigned int wlan_lf_timer_control0;
+ volatile unsigned int wlan_lf_timer_status0;
+ volatile unsigned int wlan_lf_timer1;
+ volatile unsigned int wlan_lf_timer_count1;
+ volatile unsigned int wlan_lf_timer_control1;
+ volatile unsigned int wlan_lf_timer_status1;
+ volatile unsigned int wlan_lf_timer2;
+ volatile unsigned int wlan_lf_timer_count2;
+ volatile unsigned int wlan_lf_timer_control2;
+ volatile unsigned int wlan_lf_timer_status2;
+ volatile unsigned int wlan_lf_timer3;
+ volatile unsigned int wlan_lf_timer_count3;
+ volatile unsigned int wlan_lf_timer_control3;
+ volatile unsigned int wlan_lf_timer_status3;
+ volatile unsigned int wlan_hf_timer;
+ volatile unsigned int wlan_hf_timer_count;
+ volatile unsigned int wlan_hf_lf_count;
+ volatile unsigned int wlan_hf_timer_control;
+ volatile unsigned int wlan_hf_timer_status;
+ volatile unsigned int wlan_rtc_control;
+ volatile unsigned int wlan_rtc_time;
+ volatile unsigned int wlan_rtc_date;
+ volatile unsigned int wlan_rtc_set_time;
+ volatile unsigned int wlan_rtc_set_date;
+ volatile unsigned int wlan_rtc_set_alarm;
+ volatile unsigned int wlan_rtc_config;
+ volatile unsigned int wlan_rtc_alarm_status;
+ volatile unsigned int wlan_uart_wakeup;
+ volatile unsigned int wlan_reset_cause;
+ volatile unsigned int wlan_system_sleep;
+ volatile unsigned int wlan_sdio_wrapper;
+ volatile unsigned int wlan_mac_sleep_control;
+ volatile unsigned int wlan_keep_awake;
+ volatile unsigned int wlan_lpo_cal_time;
+ volatile unsigned int wlan_lpo_init_dividend_int;
+ volatile unsigned int wlan_lpo_init_dividend_fraction;
+ volatile unsigned int wlan_lpo_cal;
+ volatile unsigned int wlan_lpo_cal_test_control;
+ volatile unsigned int wlan_lpo_cal_test_status;
+ volatile unsigned int wlan_chip_id;
+ volatile unsigned int wlan_derived_rtc_clk;
+ volatile unsigned int mac_pcu_slp32_mode;
+ volatile unsigned int mac_pcu_slp32_wake;
+ volatile unsigned int mac_pcu_slp32_inc;
+ volatile unsigned int mac_pcu_slp_mib1;
+ volatile unsigned int mac_pcu_slp_mib2;
+ volatile unsigned int mac_pcu_slp_mib3;
+ volatile unsigned int wlan_power_reg;
+ volatile unsigned int wlan_core_clk_ctrl;
+ volatile unsigned int wlan_gpio_wakeup_control;
+ volatile unsigned int ht;
+ volatile unsigned int mac_pcu_tsf_l32;
+ volatile unsigned int mac_pcu_tsf_u32;
+ volatile unsigned int mac_pcu_wbtimer;
+ unsigned char pad0[24]; /* pad to 0x140 */
+ volatile unsigned int mac_pcu_generic_timers[16];
+ volatile unsigned int mac_pcu_generic_timers_mode;
+ unsigned char pad1[60]; /* pad to 0x1c0 */
+ volatile unsigned int mac_pcu_generic_timers2[16];
+ volatile unsigned int mac_pcu_generic_timers_mode2;
+ volatile unsigned int mac_pcu_slp1;
+ volatile unsigned int mac_pcu_slp2;
+ volatile unsigned int mac_pcu_reset_tsf;
+ volatile unsigned int mac_pcu_tsf_add_pll;
+ volatile unsigned int sleep_retention;
+ volatile unsigned int btcoexctrl;
+ volatile unsigned int wbsync_priority1;
+ volatile unsigned int wbsync_priority2;
+ volatile unsigned int wbsync_priority3;
+ volatile unsigned int btcoex0;
+ volatile unsigned int btcoex1;
+ volatile unsigned int btcoex2;
+ volatile unsigned int btcoex3;
+ volatile unsigned int btcoex4;
+ volatile unsigned int btcoex5;
+ volatile unsigned int btcoex6;
+ volatile unsigned int lock;
+ volatile unsigned int nolock_priority;
+ volatile unsigned int wbsync;
+ volatile unsigned int wbsync1;
+ volatile unsigned int wbsync2;
+ volatile unsigned int wbsync3;
+ volatile unsigned int wb_timer_target;
+ volatile unsigned int wb_timer_slop;
+ volatile unsigned int btcoex_int_en;
+ volatile unsigned int btcoex_int_stat;
+ volatile unsigned int btpriority_int_en;
+ volatile unsigned int btpriority_int_stat;
+ volatile unsigned int btpriority_stomp_int_en;
+ volatile unsigned int btpriority_stomp_int_stat;
+ volatile unsigned int mac_pcu_bmiss_timeout;
+ volatile unsigned int mac_pcu_cab_awake;
+ volatile unsigned int lp_perf_counter;
+ volatile unsigned int lp_perf_light_sleep;
+ volatile unsigned int lp_perf_deep_sleep;
+ volatile unsigned int lp_perf_on;
+ volatile unsigned int st_64_bit;
+ volatile unsigned int message_wr;
+ volatile unsigned int message_wr_p;
+ volatile unsigned int message_rd;
+ volatile unsigned int message_rd_p;
+ volatile unsigned int chip_mode;
+ volatile unsigned int clk_req_fall_edge;
+ volatile unsigned int otp;
+ volatile unsigned int otp_status;
+ volatile unsigned int pmu;
+ unsigned char pad2[4]; /* pad to 0x2c0 */
+ volatile unsigned int pmu_config[2];
+ volatile unsigned int pmu_bypass;
+ volatile unsigned int mac_pcu_tsf2_l32;
+ volatile unsigned int mac_pcu_tsf2_u32;
+ volatile unsigned int mac_pcu_generic_timers_mode3;
+ volatile unsigned int mac_pcu_direct_connect;
+ volatile unsigned int therm_ctrl1;
+ volatile unsigned int therm_ctrl2;
+ volatile unsigned int therm_ctrl3;
+} rtc_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _RTC_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h
new file mode 100644
index 000000000000..2cd2e3cadbbc
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h
@@ -0,0 +1,209 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _SI_REG_REG_H_
+#define _SI_REG_REG_H_
+
+#define SI_CONFIG_ADDRESS 0x00000000
+#define SI_CONFIG_OFFSET 0x00000000
+#define SI_CONFIG_ERR_INT_MSB 19
+#define SI_CONFIG_ERR_INT_LSB 19
+#define SI_CONFIG_ERR_INT_MASK 0x00080000
+#define SI_CONFIG_ERR_INT_GET(x) (((x) & SI_CONFIG_ERR_INT_MASK) >> SI_CONFIG_ERR_INT_LSB)
+#define SI_CONFIG_ERR_INT_SET(x) (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_MSB 18
+#define SI_CONFIG_BIDIR_OD_DATA_LSB 18
+#define SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000
+#define SI_CONFIG_BIDIR_OD_DATA_GET(x) (((x) & SI_CONFIG_BIDIR_OD_DATA_MASK) >> SI_CONFIG_BIDIR_OD_DATA_LSB)
+#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_MSB 16
+#define SI_CONFIG_I2C_LSB 16
+#define SI_CONFIG_I2C_MASK 0x00010000
+#define SI_CONFIG_I2C_GET(x) (((x) & SI_CONFIG_I2C_MASK) >> SI_CONFIG_I2C_LSB)
+#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_MSB 7
+#define SI_CONFIG_POS_SAMPLE_LSB 7
+#define SI_CONFIG_POS_SAMPLE_MASK 0x00000080
+#define SI_CONFIG_POS_SAMPLE_GET(x) (((x) & SI_CONFIG_POS_SAMPLE_MASK) >> SI_CONFIG_POS_SAMPLE_LSB)
+#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_POS_DRIVE_MSB 6
+#define SI_CONFIG_POS_DRIVE_LSB 6
+#define SI_CONFIG_POS_DRIVE_MASK 0x00000040
+#define SI_CONFIG_POS_DRIVE_GET(x) (((x) & SI_CONFIG_POS_DRIVE_MASK) >> SI_CONFIG_POS_DRIVE_LSB)
+#define SI_CONFIG_POS_DRIVE_SET(x) (((x) << SI_CONFIG_POS_DRIVE_LSB) & SI_CONFIG_POS_DRIVE_MASK)
+#define SI_CONFIG_INACTIVE_DATA_MSB 5
+#define SI_CONFIG_INACTIVE_DATA_LSB 5
+#define SI_CONFIG_INACTIVE_DATA_MASK 0x00000020
+#define SI_CONFIG_INACTIVE_DATA_GET(x) (((x) & SI_CONFIG_INACTIVE_DATA_MASK) >> SI_CONFIG_INACTIVE_DATA_LSB)
+#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_INACTIVE_CLK_MSB 4
+#define SI_CONFIG_INACTIVE_CLK_LSB 4
+#define SI_CONFIG_INACTIVE_CLK_MASK 0x00000010
+#define SI_CONFIG_INACTIVE_CLK_GET(x) (((x) & SI_CONFIG_INACTIVE_CLK_MASK) >> SI_CONFIG_INACTIVE_CLK_LSB)
+#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_DIVIDER_MSB 3
+#define SI_CONFIG_DIVIDER_LSB 0
+#define SI_CONFIG_DIVIDER_MASK 0x0000000f
+#define SI_CONFIG_DIVIDER_GET(x) (((x) & SI_CONFIG_DIVIDER_MASK) >> SI_CONFIG_DIVIDER_LSB)
+#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
+
+#define SI_CS_ADDRESS 0x00000004
+#define SI_CS_OFFSET 0x00000004
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_MSB 13
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_LSB 11
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_MASK 0x00003800
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_GET(x) (((x) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) >> SI_CS_BIT_CNT_IN_LAST_BYTE_LSB)
+#define SI_CS_BIT_CNT_IN_LAST_BYTE_SET(x) (((x) << SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK)
+#define SI_CS_DONE_ERR_MSB 10
+#define SI_CS_DONE_ERR_LSB 10
+#define SI_CS_DONE_ERR_MASK 0x00000400
+#define SI_CS_DONE_ERR_GET(x) (((x) & SI_CS_DONE_ERR_MASK) >> SI_CS_DONE_ERR_LSB)
+#define SI_CS_DONE_ERR_SET(x) (((x) << SI_CS_DONE_ERR_LSB) & SI_CS_DONE_ERR_MASK)
+#define SI_CS_DONE_INT_MSB 9
+#define SI_CS_DONE_INT_LSB 9
+#define SI_CS_DONE_INT_MASK 0x00000200
+#define SI_CS_DONE_INT_GET(x) (((x) & SI_CS_DONE_INT_MASK) >> SI_CS_DONE_INT_LSB)
+#define SI_CS_DONE_INT_SET(x) (((x) << SI_CS_DONE_INT_LSB) & SI_CS_DONE_INT_MASK)
+#define SI_CS_START_MSB 8
+#define SI_CS_START_LSB 8
+#define SI_CS_START_MASK 0x00000100
+#define SI_CS_START_GET(x) (((x) & SI_CS_START_MASK) >> SI_CS_START_LSB)
+#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
+#define SI_CS_RX_CNT_MSB 7
+#define SI_CS_RX_CNT_LSB 4
+#define SI_CS_RX_CNT_MASK 0x000000f0
+#define SI_CS_RX_CNT_GET(x) (((x) & SI_CS_RX_CNT_MASK) >> SI_CS_RX_CNT_LSB)
+#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_MSB 3
+#define SI_CS_TX_CNT_LSB 0
+#define SI_CS_TX_CNT_MASK 0x0000000f
+#define SI_CS_TX_CNT_GET(x) (((x) & SI_CS_TX_CNT_MASK) >> SI_CS_TX_CNT_LSB)
+#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
+
+#define SI_TX_DATA0_ADDRESS 0x00000008
+#define SI_TX_DATA0_OFFSET 0x00000008
+#define SI_TX_DATA0_DATA3_MSB 31
+#define SI_TX_DATA0_DATA3_LSB 24
+#define SI_TX_DATA0_DATA3_MASK 0xff000000
+#define SI_TX_DATA0_DATA3_GET(x) (((x) & SI_TX_DATA0_DATA3_MASK) >> SI_TX_DATA0_DATA3_LSB)
+#define SI_TX_DATA0_DATA3_SET(x) (((x) << SI_TX_DATA0_DATA3_LSB) & SI_TX_DATA0_DATA3_MASK)
+#define SI_TX_DATA0_DATA2_MSB 23
+#define SI_TX_DATA0_DATA2_LSB 16
+#define SI_TX_DATA0_DATA2_MASK 0x00ff0000
+#define SI_TX_DATA0_DATA2_GET(x) (((x) & SI_TX_DATA0_DATA2_MASK) >> SI_TX_DATA0_DATA2_LSB)
+#define SI_TX_DATA0_DATA2_SET(x) (((x) << SI_TX_DATA0_DATA2_LSB) & SI_TX_DATA0_DATA2_MASK)
+#define SI_TX_DATA0_DATA1_MSB 15
+#define SI_TX_DATA0_DATA1_LSB 8
+#define SI_TX_DATA0_DATA1_MASK 0x0000ff00
+#define SI_TX_DATA0_DATA1_GET(x) (((x) & SI_TX_DATA0_DATA1_MASK) >> SI_TX_DATA0_DATA1_LSB)
+#define SI_TX_DATA0_DATA1_SET(x) (((x) << SI_TX_DATA0_DATA1_LSB) & SI_TX_DATA0_DATA1_MASK)
+#define SI_TX_DATA0_DATA0_MSB 7
+#define SI_TX_DATA0_DATA0_LSB 0
+#define SI_TX_DATA0_DATA0_MASK 0x000000ff
+#define SI_TX_DATA0_DATA0_GET(x) (((x) & SI_TX_DATA0_DATA0_MASK) >> SI_TX_DATA0_DATA0_LSB)
+#define SI_TX_DATA0_DATA0_SET(x) (((x) << SI_TX_DATA0_DATA0_LSB) & SI_TX_DATA0_DATA0_MASK)
+
+#define SI_TX_DATA1_ADDRESS 0x0000000c
+#define SI_TX_DATA1_OFFSET 0x0000000c
+#define SI_TX_DATA1_DATA7_MSB 31
+#define SI_TX_DATA1_DATA7_LSB 24
+#define SI_TX_DATA1_DATA7_MASK 0xff000000
+#define SI_TX_DATA1_DATA7_GET(x) (((x) & SI_TX_DATA1_DATA7_MASK) >> SI_TX_DATA1_DATA7_LSB)
+#define SI_TX_DATA1_DATA7_SET(x) (((x) << SI_TX_DATA1_DATA7_LSB) & SI_TX_DATA1_DATA7_MASK)
+#define SI_TX_DATA1_DATA6_MSB 23
+#define SI_TX_DATA1_DATA6_LSB 16
+#define SI_TX_DATA1_DATA6_MASK 0x00ff0000
+#define SI_TX_DATA1_DATA6_GET(x) (((x) & SI_TX_DATA1_DATA6_MASK) >> SI_TX_DATA1_DATA6_LSB)
+#define SI_TX_DATA1_DATA6_SET(x) (((x) << SI_TX_DATA1_DATA6_LSB) & SI_TX_DATA1_DATA6_MASK)
+#define SI_TX_DATA1_DATA5_MSB 15
+#define SI_TX_DATA1_DATA5_LSB 8
+#define SI_TX_DATA1_DATA5_MASK 0x0000ff00
+#define SI_TX_DATA1_DATA5_GET(x) (((x) & SI_TX_DATA1_DATA5_MASK) >> SI_TX_DATA1_DATA5_LSB)
+#define SI_TX_DATA1_DATA5_SET(x) (((x) << SI_TX_DATA1_DATA5_LSB) & SI_TX_DATA1_DATA5_MASK)
+#define SI_TX_DATA1_DATA4_MSB 7
+#define SI_TX_DATA1_DATA4_LSB 0
+#define SI_TX_DATA1_DATA4_MASK 0x000000ff
+#define SI_TX_DATA1_DATA4_GET(x) (((x) & SI_TX_DATA1_DATA4_MASK) >> SI_TX_DATA1_DATA4_LSB)
+#define SI_TX_DATA1_DATA4_SET(x) (((x) << SI_TX_DATA1_DATA4_LSB) & SI_TX_DATA1_DATA4_MASK)
+
+#define SI_RX_DATA0_ADDRESS 0x00000010
+#define SI_RX_DATA0_OFFSET 0x00000010
+#define SI_RX_DATA0_DATA3_MSB 31
+#define SI_RX_DATA0_DATA3_LSB 24
+#define SI_RX_DATA0_DATA3_MASK 0xff000000
+#define SI_RX_DATA0_DATA3_GET(x) (((x) & SI_RX_DATA0_DATA3_MASK) >> SI_RX_DATA0_DATA3_LSB)
+#define SI_RX_DATA0_DATA3_SET(x) (((x) << SI_RX_DATA0_DATA3_LSB) & SI_RX_DATA0_DATA3_MASK)
+#define SI_RX_DATA0_DATA2_MSB 23
+#define SI_RX_DATA0_DATA2_LSB 16
+#define SI_RX_DATA0_DATA2_MASK 0x00ff0000
+#define SI_RX_DATA0_DATA2_GET(x) (((x) & SI_RX_DATA0_DATA2_MASK) >> SI_RX_DATA0_DATA2_LSB)
+#define SI_RX_DATA0_DATA2_SET(x) (((x) << SI_RX_DATA0_DATA2_LSB) & SI_RX_DATA0_DATA2_MASK)
+#define SI_RX_DATA0_DATA1_MSB 15
+#define SI_RX_DATA0_DATA1_LSB 8
+#define SI_RX_DATA0_DATA1_MASK 0x0000ff00
+#define SI_RX_DATA0_DATA1_GET(x) (((x) & SI_RX_DATA0_DATA1_MASK) >> SI_RX_DATA0_DATA1_LSB)
+#define SI_RX_DATA0_DATA1_SET(x) (((x) << SI_RX_DATA0_DATA1_LSB) & SI_RX_DATA0_DATA1_MASK)
+#define SI_RX_DATA0_DATA0_MSB 7
+#define SI_RX_DATA0_DATA0_LSB 0
+#define SI_RX_DATA0_DATA0_MASK 0x000000ff
+#define SI_RX_DATA0_DATA0_GET(x) (((x) & SI_RX_DATA0_DATA0_MASK) >> SI_RX_DATA0_DATA0_LSB)
+#define SI_RX_DATA0_DATA0_SET(x) (((x) << SI_RX_DATA0_DATA0_LSB) & SI_RX_DATA0_DATA0_MASK)
+
+#define SI_RX_DATA1_ADDRESS 0x00000014
+#define SI_RX_DATA1_OFFSET 0x00000014
+#define SI_RX_DATA1_DATA7_MSB 31
+#define SI_RX_DATA1_DATA7_LSB 24
+#define SI_RX_DATA1_DATA7_MASK 0xff000000
+#define SI_RX_DATA1_DATA7_GET(x) (((x) & SI_RX_DATA1_DATA7_MASK) >> SI_RX_DATA1_DATA7_LSB)
+#define SI_RX_DATA1_DATA7_SET(x) (((x) << SI_RX_DATA1_DATA7_LSB) & SI_RX_DATA1_DATA7_MASK)
+#define SI_RX_DATA1_DATA6_MSB 23
+#define SI_RX_DATA1_DATA6_LSB 16
+#define SI_RX_DATA1_DATA6_MASK 0x00ff0000
+#define SI_RX_DATA1_DATA6_GET(x) (((x) & SI_RX_DATA1_DATA6_MASK) >> SI_RX_DATA1_DATA6_LSB)
+#define SI_RX_DATA1_DATA6_SET(x) (((x) << SI_RX_DATA1_DATA6_LSB) & SI_RX_DATA1_DATA6_MASK)
+#define SI_RX_DATA1_DATA5_MSB 15
+#define SI_RX_DATA1_DATA5_LSB 8
+#define SI_RX_DATA1_DATA5_MASK 0x0000ff00
+#define SI_RX_DATA1_DATA5_GET(x) (((x) & SI_RX_DATA1_DATA5_MASK) >> SI_RX_DATA1_DATA5_LSB)
+#define SI_RX_DATA1_DATA5_SET(x) (((x) << SI_RX_DATA1_DATA5_LSB) & SI_RX_DATA1_DATA5_MASK)
+#define SI_RX_DATA1_DATA4_MSB 7
+#define SI_RX_DATA1_DATA4_LSB 0
+#define SI_RX_DATA1_DATA4_MASK 0x000000ff
+#define SI_RX_DATA1_DATA4_GET(x) (((x) & SI_RX_DATA1_DATA4_MASK) >> SI_RX_DATA1_DATA4_LSB)
+#define SI_RX_DATA1_DATA4_SET(x) (((x) << SI_RX_DATA1_DATA4_LSB) & SI_RX_DATA1_DATA4_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct si_reg_reg_s {
+ volatile unsigned int si_config;
+ volatile unsigned int si_cs;
+ volatile unsigned int si_tx_data0;
+ volatile unsigned int si_tx_data1;
+ volatile unsigned int si_rx_data0;
+ volatile unsigned int si_rx_data1;
+} si_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _SI_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
new file mode 100644
index 000000000000..a8eccaf6d745
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
@@ -0,0 +1,260 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _UART_REG_REG_H_
+#define _UART_REG_REG_H_
+
+#define UART_DATA_ADDRESS 0x00000000
+#define UART_DATA_OFFSET 0x00000000
+#define UART_DATA_TX_CSR_MSB 9
+#define UART_DATA_TX_CSR_LSB 9
+#define UART_DATA_TX_CSR_MASK 0x00000200
+#define UART_DATA_TX_CSR_GET(x) (((x) & UART_DATA_TX_CSR_MASK) >> UART_DATA_TX_CSR_LSB)
+#define UART_DATA_TX_CSR_SET(x) (((x) << UART_DATA_TX_CSR_LSB) & UART_DATA_TX_CSR_MASK)
+#define UART_DATA_RX_CSR_MSB 8
+#define UART_DATA_RX_CSR_LSB 8
+#define UART_DATA_RX_CSR_MASK 0x00000100
+#define UART_DATA_RX_CSR_GET(x) (((x) & UART_DATA_RX_CSR_MASK) >> UART_DATA_RX_CSR_LSB)
+#define UART_DATA_RX_CSR_SET(x) (((x) << UART_DATA_RX_CSR_LSB) & UART_DATA_RX_CSR_MASK)
+#define UART_DATA_TXRX_DATA_MSB 7
+#define UART_DATA_TXRX_DATA_LSB 0
+#define UART_DATA_TXRX_DATA_MASK 0x000000ff
+#define UART_DATA_TXRX_DATA_GET(x) (((x) & UART_DATA_TXRX_DATA_MASK) >> UART_DATA_TXRX_DATA_LSB)
+#define UART_DATA_TXRX_DATA_SET(x) (((x) << UART_DATA_TXRX_DATA_LSB) & UART_DATA_TXRX_DATA_MASK)
+
+#define UART_CONTROL_ADDRESS 0x00000004
+#define UART_CONTROL_OFFSET 0x00000004
+#define UART_CONTROL_RX_BUSY_MSB 15
+#define UART_CONTROL_RX_BUSY_LSB 15
+#define UART_CONTROL_RX_BUSY_MASK 0x00008000
+#define UART_CONTROL_RX_BUSY_GET(x) (((x) & UART_CONTROL_RX_BUSY_MASK) >> UART_CONTROL_RX_BUSY_LSB)
+#define UART_CONTROL_RX_BUSY_SET(x) (((x) << UART_CONTROL_RX_BUSY_LSB) & UART_CONTROL_RX_BUSY_MASK)
+#define UART_CONTROL_TX_BUSY_MSB 14
+#define UART_CONTROL_TX_BUSY_LSB 14
+#define UART_CONTROL_TX_BUSY_MASK 0x00004000
+#define UART_CONTROL_TX_BUSY_GET(x) (((x) & UART_CONTROL_TX_BUSY_MASK) >> UART_CONTROL_TX_BUSY_LSB)
+#define UART_CONTROL_TX_BUSY_SET(x) (((x) << UART_CONTROL_TX_BUSY_LSB) & UART_CONTROL_TX_BUSY_MASK)
+#define UART_CONTROL_HOST_INT_ENABLE_MSB 13
+#define UART_CONTROL_HOST_INT_ENABLE_LSB 13
+#define UART_CONTROL_HOST_INT_ENABLE_MASK 0x00002000
+#define UART_CONTROL_HOST_INT_ENABLE_GET(x) (((x) & UART_CONTROL_HOST_INT_ENABLE_MASK) >> UART_CONTROL_HOST_INT_ENABLE_LSB)
+#define UART_CONTROL_HOST_INT_ENABLE_SET(x) (((x) << UART_CONTROL_HOST_INT_ENABLE_LSB) & UART_CONTROL_HOST_INT_ENABLE_MASK)
+#define UART_CONTROL_HOST_INT_MSB 12
+#define UART_CONTROL_HOST_INT_LSB 12
+#define UART_CONTROL_HOST_INT_MASK 0x00001000
+#define UART_CONTROL_HOST_INT_GET(x) (((x) & UART_CONTROL_HOST_INT_MASK) >> UART_CONTROL_HOST_INT_LSB)
+#define UART_CONTROL_HOST_INT_SET(x) (((x) << UART_CONTROL_HOST_INT_LSB) & UART_CONTROL_HOST_INT_MASK)
+#define UART_CONTROL_TX_BREAK_MSB 11
+#define UART_CONTROL_TX_BREAK_LSB 11
+#define UART_CONTROL_TX_BREAK_MASK 0x00000800
+#define UART_CONTROL_TX_BREAK_GET(x) (((x) & UART_CONTROL_TX_BREAK_MASK) >> UART_CONTROL_TX_BREAK_LSB)
+#define UART_CONTROL_TX_BREAK_SET(x) (((x) << UART_CONTROL_TX_BREAK_LSB) & UART_CONTROL_TX_BREAK_MASK)
+#define UART_CONTROL_RX_BREAK_MSB 10
+#define UART_CONTROL_RX_BREAK_LSB 10
+#define UART_CONTROL_RX_BREAK_MASK 0x00000400
+#define UART_CONTROL_RX_BREAK_GET(x) (((x) & UART_CONTROL_RX_BREAK_MASK) >> UART_CONTROL_RX_BREAK_LSB)
+#define UART_CONTROL_RX_BREAK_SET(x) (((x) << UART_CONTROL_RX_BREAK_LSB) & UART_CONTROL_RX_BREAK_MASK)
+#define UART_CONTROL_SERIAL_TX_READY_MSB 9
+#define UART_CONTROL_SERIAL_TX_READY_LSB 9
+#define UART_CONTROL_SERIAL_TX_READY_MASK 0x00000200
+#define UART_CONTROL_SERIAL_TX_READY_GET(x) (((x) & UART_CONTROL_SERIAL_TX_READY_MASK) >> UART_CONTROL_SERIAL_TX_READY_LSB)
+#define UART_CONTROL_SERIAL_TX_READY_SET(x) (((x) << UART_CONTROL_SERIAL_TX_READY_LSB) & UART_CONTROL_SERIAL_TX_READY_MASK)
+#define UART_CONTROL_TX_READY_ORIDE_MSB 8
+#define UART_CONTROL_TX_READY_ORIDE_LSB 8
+#define UART_CONTROL_TX_READY_ORIDE_MASK 0x00000100
+#define UART_CONTROL_TX_READY_ORIDE_GET(x) (((x) & UART_CONTROL_TX_READY_ORIDE_MASK) >> UART_CONTROL_TX_READY_ORIDE_LSB)
+#define UART_CONTROL_TX_READY_ORIDE_SET(x) (((x) << UART_CONTROL_TX_READY_ORIDE_LSB) & UART_CONTROL_TX_READY_ORIDE_MASK)
+#define UART_CONTROL_RX_READY_ORIDE_MSB 7
+#define UART_CONTROL_RX_READY_ORIDE_LSB 7
+#define UART_CONTROL_RX_READY_ORIDE_MASK 0x00000080
+#define UART_CONTROL_RX_READY_ORIDE_GET(x) (((x) & UART_CONTROL_RX_READY_ORIDE_MASK) >> UART_CONTROL_RX_READY_ORIDE_LSB)
+#define UART_CONTROL_RX_READY_ORIDE_SET(x) (((x) << UART_CONTROL_RX_READY_ORIDE_LSB) & UART_CONTROL_RX_READY_ORIDE_MASK)
+#define UART_CONTROL_DMA_ENABLE_MSB 6
+#define UART_CONTROL_DMA_ENABLE_LSB 6
+#define UART_CONTROL_DMA_ENABLE_MASK 0x00000040
+#define UART_CONTROL_DMA_ENABLE_GET(x) (((x) & UART_CONTROL_DMA_ENABLE_MASK) >> UART_CONTROL_DMA_ENABLE_LSB)
+#define UART_CONTROL_DMA_ENABLE_SET(x) (((x) << UART_CONTROL_DMA_ENABLE_LSB) & UART_CONTROL_DMA_ENABLE_MASK)
+#define UART_CONTROL_FLOW_ENABLE_MSB 5
+#define UART_CONTROL_FLOW_ENABLE_LSB 5
+#define UART_CONTROL_FLOW_ENABLE_MASK 0x00000020
+#define UART_CONTROL_FLOW_ENABLE_GET(x) (((x) & UART_CONTROL_FLOW_ENABLE_MASK) >> UART_CONTROL_FLOW_ENABLE_LSB)
+#define UART_CONTROL_FLOW_ENABLE_SET(x) (((x) << UART_CONTROL_FLOW_ENABLE_LSB) & UART_CONTROL_FLOW_ENABLE_MASK)
+#define UART_CONTROL_FLOW_INVERT_MSB 4
+#define UART_CONTROL_FLOW_INVERT_LSB 4
+#define UART_CONTROL_FLOW_INVERT_MASK 0x00000010
+#define UART_CONTROL_FLOW_INVERT_GET(x) (((x) & UART_CONTROL_FLOW_INVERT_MASK) >> UART_CONTROL_FLOW_INVERT_LSB)
+#define UART_CONTROL_FLOW_INVERT_SET(x) (((x) << UART_CONTROL_FLOW_INVERT_LSB) & UART_CONTROL_FLOW_INVERT_MASK)
+#define UART_CONTROL_IFC_ENABLE_MSB 3
+#define UART_CONTROL_IFC_ENABLE_LSB 3
+#define UART_CONTROL_IFC_ENABLE_MASK 0x00000008
+#define UART_CONTROL_IFC_ENABLE_GET(x) (((x) & UART_CONTROL_IFC_ENABLE_MASK) >> UART_CONTROL_IFC_ENABLE_LSB)
+#define UART_CONTROL_IFC_ENABLE_SET(x) (((x) << UART_CONTROL_IFC_ENABLE_LSB) & UART_CONTROL_IFC_ENABLE_MASK)
+#define UART_CONTROL_IFC_DCE_MSB 2
+#define UART_CONTROL_IFC_DCE_LSB 2
+#define UART_CONTROL_IFC_DCE_MASK 0x00000004
+#define UART_CONTROL_IFC_DCE_GET(x) (((x) & UART_CONTROL_IFC_DCE_MASK) >> UART_CONTROL_IFC_DCE_LSB)
+#define UART_CONTROL_IFC_DCE_SET(x) (((x) << UART_CONTROL_IFC_DCE_LSB) & UART_CONTROL_IFC_DCE_MASK)
+#define UART_CONTROL_PARITY_ENABLE_MSB 1
+#define UART_CONTROL_PARITY_ENABLE_LSB 1
+#define UART_CONTROL_PARITY_ENABLE_MASK 0x00000002
+#define UART_CONTROL_PARITY_ENABLE_GET(x) (((x) & UART_CONTROL_PARITY_ENABLE_MASK) >> UART_CONTROL_PARITY_ENABLE_LSB)
+#define UART_CONTROL_PARITY_ENABLE_SET(x) (((x) << UART_CONTROL_PARITY_ENABLE_LSB) & UART_CONTROL_PARITY_ENABLE_MASK)
+#define UART_CONTROL_PARITY_EVEN_MSB 0
+#define UART_CONTROL_PARITY_EVEN_LSB 0
+#define UART_CONTROL_PARITY_EVEN_MASK 0x00000001
+#define UART_CONTROL_PARITY_EVEN_GET(x) (((x) & UART_CONTROL_PARITY_EVEN_MASK) >> UART_CONTROL_PARITY_EVEN_LSB)
+#define UART_CONTROL_PARITY_EVEN_SET(x) (((x) << UART_CONTROL_PARITY_EVEN_LSB) & UART_CONTROL_PARITY_EVEN_MASK)
+
+#define UART_CLKDIV_ADDRESS 0x00000008
+#define UART_CLKDIV_OFFSET 0x00000008
+#define UART_CLKDIV_CLK_SCALE_MSB 23
+#define UART_CLKDIV_CLK_SCALE_LSB 16
+#define UART_CLKDIV_CLK_SCALE_MASK 0x00ff0000
+#define UART_CLKDIV_CLK_SCALE_GET(x) (((x) & UART_CLKDIV_CLK_SCALE_MASK) >> UART_CLKDIV_CLK_SCALE_LSB)
+#define UART_CLKDIV_CLK_SCALE_SET(x) (((x) << UART_CLKDIV_CLK_SCALE_LSB) & UART_CLKDIV_CLK_SCALE_MASK)
+#define UART_CLKDIV_CLK_STEP_MSB 15
+#define UART_CLKDIV_CLK_STEP_LSB 0
+#define UART_CLKDIV_CLK_STEP_MASK 0x0000ffff
+#define UART_CLKDIV_CLK_STEP_GET(x) (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB)
+#define UART_CLKDIV_CLK_STEP_SET(x) (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK)
+
+#define UART_INT_ADDRESS 0x0000000c
+#define UART_INT_OFFSET 0x0000000c
+#define UART_INT_TX_EMPTY_INT_MSB 9
+#define UART_INT_TX_EMPTY_INT_LSB 9
+#define UART_INT_TX_EMPTY_INT_MASK 0x00000200
+#define UART_INT_TX_EMPTY_INT_GET(x) (((x) & UART_INT_TX_EMPTY_INT_MASK) >> UART_INT_TX_EMPTY_INT_LSB)
+#define UART_INT_TX_EMPTY_INT_SET(x) (((x) << UART_INT_TX_EMPTY_INT_LSB) & UART_INT_TX_EMPTY_INT_MASK)
+#define UART_INT_RX_FULL_INT_MSB 8
+#define UART_INT_RX_FULL_INT_LSB 8
+#define UART_INT_RX_FULL_INT_MASK 0x00000100
+#define UART_INT_RX_FULL_INT_GET(x) (((x) & UART_INT_RX_FULL_INT_MASK) >> UART_INT_RX_FULL_INT_LSB)
+#define UART_INT_RX_FULL_INT_SET(x) (((x) << UART_INT_RX_FULL_INT_LSB) & UART_INT_RX_FULL_INT_MASK)
+#define UART_INT_RX_BREAK_OFF_INT_MSB 7
+#define UART_INT_RX_BREAK_OFF_INT_LSB 7
+#define UART_INT_RX_BREAK_OFF_INT_MASK 0x00000080
+#define UART_INT_RX_BREAK_OFF_INT_GET(x) (((x) & UART_INT_RX_BREAK_OFF_INT_MASK) >> UART_INT_RX_BREAK_OFF_INT_LSB)
+#define UART_INT_RX_BREAK_OFF_INT_SET(x) (((x) << UART_INT_RX_BREAK_OFF_INT_LSB) & UART_INT_RX_BREAK_OFF_INT_MASK)
+#define UART_INT_RX_BREAK_ON_INT_MSB 6
+#define UART_INT_RX_BREAK_ON_INT_LSB 6
+#define UART_INT_RX_BREAK_ON_INT_MASK 0x00000040
+#define UART_INT_RX_BREAK_ON_INT_GET(x) (((x) & UART_INT_RX_BREAK_ON_INT_MASK) >> UART_INT_RX_BREAK_ON_INT_LSB)
+#define UART_INT_RX_BREAK_ON_INT_SET(x) (((x) << UART_INT_RX_BREAK_ON_INT_LSB) & UART_INT_RX_BREAK_ON_INT_MASK)
+#define UART_INT_RX_PARITY_ERR_INT_MSB 5
+#define UART_INT_RX_PARITY_ERR_INT_LSB 5
+#define UART_INT_RX_PARITY_ERR_INT_MASK 0x00000020
+#define UART_INT_RX_PARITY_ERR_INT_GET(x) (((x) & UART_INT_RX_PARITY_ERR_INT_MASK) >> UART_INT_RX_PARITY_ERR_INT_LSB)
+#define UART_INT_RX_PARITY_ERR_INT_SET(x) (((x) << UART_INT_RX_PARITY_ERR_INT_LSB) & UART_INT_RX_PARITY_ERR_INT_MASK)
+#define UART_INT_TX_OFLOW_ERR_INT_MSB 4
+#define UART_INT_TX_OFLOW_ERR_INT_LSB 4
+#define UART_INT_TX_OFLOW_ERR_INT_MASK 0x00000010
+#define UART_INT_TX_OFLOW_ERR_INT_GET(x) (((x) & UART_INT_TX_OFLOW_ERR_INT_MASK) >> UART_INT_TX_OFLOW_ERR_INT_LSB)
+#define UART_INT_TX_OFLOW_ERR_INT_SET(x) (((x) << UART_INT_TX_OFLOW_ERR_INT_LSB) & UART_INT_TX_OFLOW_ERR_INT_MASK)
+#define UART_INT_RX_OFLOW_ERR_INT_MSB 3
+#define UART_INT_RX_OFLOW_ERR_INT_LSB 3
+#define UART_INT_RX_OFLOW_ERR_INT_MASK 0x00000008
+#define UART_INT_RX_OFLOW_ERR_INT_GET(x) (((x) & UART_INT_RX_OFLOW_ERR_INT_MASK) >> UART_INT_RX_OFLOW_ERR_INT_LSB)
+#define UART_INT_RX_OFLOW_ERR_INT_SET(x) (((x) << UART_INT_RX_OFLOW_ERR_INT_LSB) & UART_INT_RX_OFLOW_ERR_INT_MASK)
+#define UART_INT_RX_FRAMING_ERR_INT_MSB 2
+#define UART_INT_RX_FRAMING_ERR_INT_LSB 2
+#define UART_INT_RX_FRAMING_ERR_INT_MASK 0x00000004
+#define UART_INT_RX_FRAMING_ERR_INT_GET(x) (((x) & UART_INT_RX_FRAMING_ERR_INT_MASK) >> UART_INT_RX_FRAMING_ERR_INT_LSB)
+#define UART_INT_RX_FRAMING_ERR_INT_SET(x) (((x) << UART_INT_RX_FRAMING_ERR_INT_LSB) & UART_INT_RX_FRAMING_ERR_INT_MASK)
+#define UART_INT_TX_READY_INT_MSB 1
+#define UART_INT_TX_READY_INT_LSB 1
+#define UART_INT_TX_READY_INT_MASK 0x00000002
+#define UART_INT_TX_READY_INT_GET(x) (((x) & UART_INT_TX_READY_INT_MASK) >> UART_INT_TX_READY_INT_LSB)
+#define UART_INT_TX_READY_INT_SET(x) (((x) << UART_INT_TX_READY_INT_LSB) & UART_INT_TX_READY_INT_MASK)
+#define UART_INT_RX_VALID_INT_MSB 0
+#define UART_INT_RX_VALID_INT_LSB 0
+#define UART_INT_RX_VALID_INT_MASK 0x00000001
+#define UART_INT_RX_VALID_INT_GET(x) (((x) & UART_INT_RX_VALID_INT_MASK) >> UART_INT_RX_VALID_INT_LSB)
+#define UART_INT_RX_VALID_INT_SET(x) (((x) << UART_INT_RX_VALID_INT_LSB) & UART_INT_RX_VALID_INT_MASK)
+
+#define UART_INT_EN_ADDRESS 0x00000010
+#define UART_INT_EN_OFFSET 0x00000010
+#define UART_INT_EN_TX_EMPTY_INT_EN_MSB 9
+#define UART_INT_EN_TX_EMPTY_INT_EN_LSB 9
+#define UART_INT_EN_TX_EMPTY_INT_EN_MASK 0x00000200
+#define UART_INT_EN_TX_EMPTY_INT_EN_GET(x) (((x) & UART_INT_EN_TX_EMPTY_INT_EN_MASK) >> UART_INT_EN_TX_EMPTY_INT_EN_LSB)
+#define UART_INT_EN_TX_EMPTY_INT_EN_SET(x) (((x) << UART_INT_EN_TX_EMPTY_INT_EN_LSB) & UART_INT_EN_TX_EMPTY_INT_EN_MASK)
+#define UART_INT_EN_RX_FULL_INT_EN_MSB 8
+#define UART_INT_EN_RX_FULL_INT_EN_LSB 8
+#define UART_INT_EN_RX_FULL_INT_EN_MASK 0x00000100
+#define UART_INT_EN_RX_FULL_INT_EN_GET(x) (((x) & UART_INT_EN_RX_FULL_INT_EN_MASK) >> UART_INT_EN_RX_FULL_INT_EN_LSB)
+#define UART_INT_EN_RX_FULL_INT_EN_SET(x) (((x) << UART_INT_EN_RX_FULL_INT_EN_LSB) & UART_INT_EN_RX_FULL_INT_EN_MASK)
+#define UART_INT_EN_RX_BREAK_OFF_INT_EN_MSB 7
+#define UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB 7
+#define UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK 0x00000080
+#define UART_INT_EN_RX_BREAK_OFF_INT_EN_GET(x) (((x) & UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK) >> UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB)
+#define UART_INT_EN_RX_BREAK_OFF_INT_EN_SET(x) (((x) << UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB) & UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK)
+#define UART_INT_EN_RX_BREAK_ON_INT_EN_MSB 6
+#define UART_INT_EN_RX_BREAK_ON_INT_EN_LSB 6
+#define UART_INT_EN_RX_BREAK_ON_INT_EN_MASK 0x00000040
+#define UART_INT_EN_RX_BREAK_ON_INT_EN_GET(x) (((x) & UART_INT_EN_RX_BREAK_ON_INT_EN_MASK) >> UART_INT_EN_RX_BREAK_ON_INT_EN_LSB)
+#define UART_INT_EN_RX_BREAK_ON_INT_EN_SET(x) (((x) << UART_INT_EN_RX_BREAK_ON_INT_EN_LSB) & UART_INT_EN_RX_BREAK_ON_INT_EN_MASK)
+#define UART_INT_EN_RX_PARITY_ERR_INT_EN_MSB 5
+#define UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB 5
+#define UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK 0x00000020
+#define UART_INT_EN_RX_PARITY_ERR_INT_EN_GET(x) (((x) & UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK) >> UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB)
+#define UART_INT_EN_RX_PARITY_ERR_INT_EN_SET(x) (((x) << UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB) & UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK)
+#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_MSB 4
+#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB 4
+#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK 0x00000010
+#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_GET(x) (((x) & UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK) >> UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB)
+#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_SET(x) (((x) << UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB) & UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK)
+#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_MSB 3
+#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB 3
+#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK 0x00000008
+#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_GET(x) (((x) & UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK) >> UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB)
+#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_SET(x) (((x) << UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB) & UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK)
+#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_MSB 2
+#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB 2
+#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK 0x00000004
+#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_GET(x) (((x) & UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK) >> UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB)
+#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_SET(x) (((x) << UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB) & UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK)
+#define UART_INT_EN_TX_READY_INT_EN_MSB 1
+#define UART_INT_EN_TX_READY_INT_EN_LSB 1
+#define UART_INT_EN_TX_READY_INT_EN_MASK 0x00000002
+#define UART_INT_EN_TX_READY_INT_EN_GET(x) (((x) & UART_INT_EN_TX_READY_INT_EN_MASK) >> UART_INT_EN_TX_READY_INT_EN_LSB)
+#define UART_INT_EN_TX_READY_INT_EN_SET(x) (((x) << UART_INT_EN_TX_READY_INT_EN_LSB) & UART_INT_EN_TX_READY_INT_EN_MASK)
+#define UART_INT_EN_RX_VALID_INT_EN_MSB 0
+#define UART_INT_EN_RX_VALID_INT_EN_LSB 0
+#define UART_INT_EN_RX_VALID_INT_EN_MASK 0x00000001
+#define UART_INT_EN_RX_VALID_INT_EN_GET(x) (((x) & UART_INT_EN_RX_VALID_INT_EN_MASK) >> UART_INT_EN_RX_VALID_INT_EN_LSB)
+#define UART_INT_EN_RX_VALID_INT_EN_SET(x) (((x) << UART_INT_EN_RX_VALID_INT_EN_LSB) & UART_INT_EN_RX_VALID_INT_EN_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct uart_reg_reg_s {
+ volatile unsigned int uart_data;
+ volatile unsigned int uart_control;
+ volatile unsigned int uart_clkdiv;
+ volatile unsigned int uart_int;
+ volatile unsigned int uart_int_en;
+} uart_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _UART_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h
new file mode 100644
index 000000000000..b233cbc513bc
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h
@@ -0,0 +1,37 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "umbox_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h
new file mode 100644
index 000000000000..4737a2805b2f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h
@@ -0,0 +1,322 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _UMBOX_WLAN_REG_REG_H_
+#define _UMBOX_WLAN_REG_REG_H_
+
+#define UMBOX_FIFO_ADDRESS 0x00000000
+#define UMBOX_FIFO_OFFSET 0x00000000
+#define UMBOX_FIFO_DATA_MSB 8
+#define UMBOX_FIFO_DATA_LSB 0
+#define UMBOX_FIFO_DATA_MASK 0x000001ff
+#define UMBOX_FIFO_DATA_GET(x) (((x) & UMBOX_FIFO_DATA_MASK) >> UMBOX_FIFO_DATA_LSB)
+#define UMBOX_FIFO_DATA_SET(x) (((x) << UMBOX_FIFO_DATA_LSB) & UMBOX_FIFO_DATA_MASK)
+
+#define UMBOX_FIFO_STATUS_ADDRESS 0x00000008
+#define UMBOX_FIFO_STATUS_OFFSET 0x00000008
+#define UMBOX_FIFO_STATUS_TX_EMPTY_MSB 3
+#define UMBOX_FIFO_STATUS_TX_EMPTY_LSB 3
+#define UMBOX_FIFO_STATUS_TX_EMPTY_MASK 0x00000008
+#define UMBOX_FIFO_STATUS_TX_EMPTY_GET(x) (((x) & UMBOX_FIFO_STATUS_TX_EMPTY_MASK) >> UMBOX_FIFO_STATUS_TX_EMPTY_LSB)
+#define UMBOX_FIFO_STATUS_TX_EMPTY_SET(x) (((x) << UMBOX_FIFO_STATUS_TX_EMPTY_LSB) & UMBOX_FIFO_STATUS_TX_EMPTY_MASK)
+#define UMBOX_FIFO_STATUS_TX_FULL_MSB 2
+#define UMBOX_FIFO_STATUS_TX_FULL_LSB 2
+#define UMBOX_FIFO_STATUS_TX_FULL_MASK 0x00000004
+#define UMBOX_FIFO_STATUS_TX_FULL_GET(x) (((x) & UMBOX_FIFO_STATUS_TX_FULL_MASK) >> UMBOX_FIFO_STATUS_TX_FULL_LSB)
+#define UMBOX_FIFO_STATUS_TX_FULL_SET(x) (((x) << UMBOX_FIFO_STATUS_TX_FULL_LSB) & UMBOX_FIFO_STATUS_TX_FULL_MASK)
+#define UMBOX_FIFO_STATUS_RX_EMPTY_MSB 1
+#define UMBOX_FIFO_STATUS_RX_EMPTY_LSB 1
+#define UMBOX_FIFO_STATUS_RX_EMPTY_MASK 0x00000002
+#define UMBOX_FIFO_STATUS_RX_EMPTY_GET(x) (((x) & UMBOX_FIFO_STATUS_RX_EMPTY_MASK) >> UMBOX_FIFO_STATUS_RX_EMPTY_LSB)
+#define UMBOX_FIFO_STATUS_RX_EMPTY_SET(x) (((x) << UMBOX_FIFO_STATUS_RX_EMPTY_LSB) & UMBOX_FIFO_STATUS_RX_EMPTY_MASK)
+#define UMBOX_FIFO_STATUS_RX_FULL_MSB 0
+#define UMBOX_FIFO_STATUS_RX_FULL_LSB 0
+#define UMBOX_FIFO_STATUS_RX_FULL_MASK 0x00000001
+#define UMBOX_FIFO_STATUS_RX_FULL_GET(x) (((x) & UMBOX_FIFO_STATUS_RX_FULL_MASK) >> UMBOX_FIFO_STATUS_RX_FULL_LSB)
+#define UMBOX_FIFO_STATUS_RX_FULL_SET(x) (((x) << UMBOX_FIFO_STATUS_RX_FULL_LSB) & UMBOX_FIFO_STATUS_RX_FULL_MASK)
+
+#define UMBOX_DMA_POLICY_ADDRESS 0x0000000c
+#define UMBOX_DMA_POLICY_OFFSET 0x0000000c
+#define UMBOX_DMA_POLICY_TX_QUANTUM_MSB 3
+#define UMBOX_DMA_POLICY_TX_QUANTUM_LSB 3
+#define UMBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008
+#define UMBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & UMBOX_DMA_POLICY_TX_QUANTUM_MASK) >> UMBOX_DMA_POLICY_TX_QUANTUM_LSB)
+#define UMBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << UMBOX_DMA_POLICY_TX_QUANTUM_LSB) & UMBOX_DMA_POLICY_TX_QUANTUM_MASK)
+#define UMBOX_DMA_POLICY_TX_ORDER_MSB 2
+#define UMBOX_DMA_POLICY_TX_ORDER_LSB 2
+#define UMBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004
+#define UMBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & UMBOX_DMA_POLICY_TX_ORDER_MASK) >> UMBOX_DMA_POLICY_TX_ORDER_LSB)
+#define UMBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << UMBOX_DMA_POLICY_TX_ORDER_LSB) & UMBOX_DMA_POLICY_TX_ORDER_MASK)
+#define UMBOX_DMA_POLICY_RX_QUANTUM_MSB 1
+#define UMBOX_DMA_POLICY_RX_QUANTUM_LSB 1
+#define UMBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002
+#define UMBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & UMBOX_DMA_POLICY_RX_QUANTUM_MASK) >> UMBOX_DMA_POLICY_RX_QUANTUM_LSB)
+#define UMBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << UMBOX_DMA_POLICY_RX_QUANTUM_LSB) & UMBOX_DMA_POLICY_RX_QUANTUM_MASK)
+#define UMBOX_DMA_POLICY_RX_ORDER_MSB 0
+#define UMBOX_DMA_POLICY_RX_ORDER_LSB 0
+#define UMBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001
+#define UMBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & UMBOX_DMA_POLICY_RX_ORDER_MASK) >> UMBOX_DMA_POLICY_RX_ORDER_LSB)
+#define UMBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << UMBOX_DMA_POLICY_RX_ORDER_LSB) & UMBOX_DMA_POLICY_RX_ORDER_MASK)
+
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000010
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000010
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define UMBOX0_DMA_RX_CONTROL_ADDRESS 0x00000014
+#define UMBOX0_DMA_RX_CONTROL_OFFSET 0x00000014
+#define UMBOX0_DMA_RX_CONTROL_RESUME_MSB 2
+#define UMBOX0_DMA_RX_CONTROL_RESUME_LSB 2
+#define UMBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004
+#define UMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & UMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> UMBOX0_DMA_RX_CONTROL_RESUME_LSB)
+#define UMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << UMBOX0_DMA_RX_CONTROL_RESUME_LSB) & UMBOX0_DMA_RX_CONTROL_RESUME_MASK)
+#define UMBOX0_DMA_RX_CONTROL_START_MSB 1
+#define UMBOX0_DMA_RX_CONTROL_START_LSB 1
+#define UMBOX0_DMA_RX_CONTROL_START_MASK 0x00000002
+#define UMBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & UMBOX0_DMA_RX_CONTROL_START_MASK) >> UMBOX0_DMA_RX_CONTROL_START_LSB)
+#define UMBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << UMBOX0_DMA_RX_CONTROL_START_LSB) & UMBOX0_DMA_RX_CONTROL_START_MASK)
+#define UMBOX0_DMA_RX_CONTROL_STOP_MSB 0
+#define UMBOX0_DMA_RX_CONTROL_STOP_LSB 0
+#define UMBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001
+#define UMBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & UMBOX0_DMA_RX_CONTROL_STOP_MASK) >> UMBOX0_DMA_RX_CONTROL_STOP_LSB)
+#define UMBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << UMBOX0_DMA_RX_CONTROL_STOP_LSB) & UMBOX0_DMA_RX_CONTROL_STOP_MASK)
+
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000018
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000018
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define UMBOX0_DMA_TX_CONTROL_ADDRESS 0x0000001c
+#define UMBOX0_DMA_TX_CONTROL_OFFSET 0x0000001c
+#define UMBOX0_DMA_TX_CONTROL_RESUME_MSB 2
+#define UMBOX0_DMA_TX_CONTROL_RESUME_LSB 2
+#define UMBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004
+#define UMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & UMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> UMBOX0_DMA_TX_CONTROL_RESUME_LSB)
+#define UMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << UMBOX0_DMA_TX_CONTROL_RESUME_LSB) & UMBOX0_DMA_TX_CONTROL_RESUME_MASK)
+#define UMBOX0_DMA_TX_CONTROL_START_MSB 1
+#define UMBOX0_DMA_TX_CONTROL_START_LSB 1
+#define UMBOX0_DMA_TX_CONTROL_START_MASK 0x00000002
+#define UMBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & UMBOX0_DMA_TX_CONTROL_START_MASK) >> UMBOX0_DMA_TX_CONTROL_START_LSB)
+#define UMBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << UMBOX0_DMA_TX_CONTROL_START_LSB) & UMBOX0_DMA_TX_CONTROL_START_MASK)
+#define UMBOX0_DMA_TX_CONTROL_STOP_MSB 0
+#define UMBOX0_DMA_TX_CONTROL_STOP_LSB 0
+#define UMBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001
+#define UMBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & UMBOX0_DMA_TX_CONTROL_STOP_MASK) >> UMBOX0_DMA_TX_CONTROL_STOP_LSB)
+#define UMBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << UMBOX0_DMA_TX_CONTROL_STOP_LSB) & UMBOX0_DMA_TX_CONTROL_STOP_MASK)
+
+#define UMBOX_FIFO_TIMEOUT_ADDRESS 0x00000020
+#define UMBOX_FIFO_TIMEOUT_OFFSET 0x00000020
+#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_MSB 8
+#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB 8
+#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000100
+#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK) >> UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB)
+#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB) & UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK)
+#define UMBOX_FIFO_TIMEOUT_VALUE_MSB 7
+#define UMBOX_FIFO_TIMEOUT_VALUE_LSB 0
+#define UMBOX_FIFO_TIMEOUT_VALUE_MASK 0x000000ff
+#define UMBOX_FIFO_TIMEOUT_VALUE_GET(x) (((x) & UMBOX_FIFO_TIMEOUT_VALUE_MASK) >> UMBOX_FIFO_TIMEOUT_VALUE_LSB)
+#define UMBOX_FIFO_TIMEOUT_VALUE_SET(x) (((x) << UMBOX_FIFO_TIMEOUT_VALUE_LSB) & UMBOX_FIFO_TIMEOUT_VALUE_MASK)
+
+#define UMBOX_INT_STATUS_ADDRESS 0x00000024
+#define UMBOX_INT_STATUS_OFFSET 0x00000024
+#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MSB 9
+#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB 9
+#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK 0x00000200
+#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB)
+#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK)
+#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MSB 8
+#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB 8
+#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK 0x00000100
+#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB)
+#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK)
+#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 7
+#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 7
+#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000080
+#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
+#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
+#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 6
+#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 6
+#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000040
+#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
+#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
+#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 5
+#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 5
+#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000020
+#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
+#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
+#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_MSB 4
+#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB 4
+#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK 0x00000010
+#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_GET(x) (((x) & UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK) >> UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB)
+#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_SET(x) (((x) << UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB) & UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK)
+#define UMBOX_INT_STATUS_TX_OVERFLOW_MSB 3
+#define UMBOX_INT_STATUS_TX_OVERFLOW_LSB 3
+#define UMBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00000008
+#define UMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> UMBOX_INT_STATUS_TX_OVERFLOW_LSB)
+#define UMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_TX_OVERFLOW_LSB) & UMBOX_INT_STATUS_TX_OVERFLOW_MASK)
+#define UMBOX_INT_STATUS_RX_UNDERFLOW_MSB 2
+#define UMBOX_INT_STATUS_RX_UNDERFLOW_LSB 2
+#define UMBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00000004
+#define UMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> UMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
+#define UMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & UMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
+#define UMBOX_INT_STATUS_TX_NOT_EMPTY_MSB 1
+#define UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB 1
+#define UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x00000002
+#define UMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
+#define UMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
+#define UMBOX_INT_STATUS_RX_NOT_FULL_MSB 0
+#define UMBOX_INT_STATUS_RX_NOT_FULL_LSB 0
+#define UMBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000001
+#define UMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & UMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> UMBOX_INT_STATUS_RX_NOT_FULL_LSB)
+#define UMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << UMBOX_INT_STATUS_RX_NOT_FULL_LSB) & UMBOX_INT_STATUS_RX_NOT_FULL_MASK)
+
+#define UMBOX_INT_ENABLE_ADDRESS 0x00000028
+#define UMBOX_INT_ENABLE_OFFSET 0x00000028
+#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MSB 9
+#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB 9
+#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK 0x00000200
+#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB)
+#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK)
+#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MSB 8
+#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB 8
+#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK 0x00000100
+#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB)
+#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK)
+#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 7
+#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 7
+#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000080
+#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
+#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
+#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 6
+#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 6
+#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000040
+#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
+#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
+#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 5
+#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 5
+#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000020
+#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
+#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
+#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MSB 4
+#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB 4
+#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK 0x00000010
+#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_GET(x) (((x) & UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK) >> UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB)
+#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_SET(x) (((x) << UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB) & UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK)
+#define UMBOX_INT_ENABLE_TX_OVERFLOW_MSB 3
+#define UMBOX_INT_ENABLE_TX_OVERFLOW_LSB 3
+#define UMBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00000008
+#define UMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> UMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
+#define UMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & UMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
+#define UMBOX_INT_ENABLE_RX_UNDERFLOW_MSB 2
+#define UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB 2
+#define UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00000004
+#define UMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
+#define UMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
+#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 1
+#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 1
+#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x00000002
+#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
+#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
+#define UMBOX_INT_ENABLE_RX_NOT_FULL_MSB 0
+#define UMBOX_INT_ENABLE_RX_NOT_FULL_LSB 0
+#define UMBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000001
+#define UMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & UMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> UMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
+#define UMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << UMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & UMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
+
+#define UMBOX_DEBUG_ADDRESS 0x0000002c
+#define UMBOX_DEBUG_OFFSET 0x0000002c
+#define UMBOX_DEBUG_SEL_MSB 2
+#define UMBOX_DEBUG_SEL_LSB 0
+#define UMBOX_DEBUG_SEL_MASK 0x00000007
+#define UMBOX_DEBUG_SEL_GET(x) (((x) & UMBOX_DEBUG_SEL_MASK) >> UMBOX_DEBUG_SEL_LSB)
+#define UMBOX_DEBUG_SEL_SET(x) (((x) << UMBOX_DEBUG_SEL_LSB) & UMBOX_DEBUG_SEL_MASK)
+
+#define UMBOX_FIFO_RESET_ADDRESS 0x00000030
+#define UMBOX_FIFO_RESET_OFFSET 0x00000030
+#define UMBOX_FIFO_RESET_INIT_MSB 0
+#define UMBOX_FIFO_RESET_INIT_LSB 0
+#define UMBOX_FIFO_RESET_INIT_MASK 0x00000001
+#define UMBOX_FIFO_RESET_INIT_GET(x) (((x) & UMBOX_FIFO_RESET_INIT_MASK) >> UMBOX_FIFO_RESET_INIT_LSB)
+#define UMBOX_FIFO_RESET_INIT_SET(x) (((x) << UMBOX_FIFO_RESET_INIT_LSB) & UMBOX_FIFO_RESET_INIT_MASK)
+
+#define UMBOX_HCI_FRAMER_ADDRESS 0x00000034
+#define UMBOX_HCI_FRAMER_OFFSET 0x00000034
+#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_MSB 6
+#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB 6
+#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK 0x00000040
+#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_GET(x) (((x) & UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK) >> UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB)
+#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_SET(x) (((x) << UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB) & UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK)
+#define UMBOX_HCI_FRAMER_ENABLE_MSB 5
+#define UMBOX_HCI_FRAMER_ENABLE_LSB 5
+#define UMBOX_HCI_FRAMER_ENABLE_MASK 0x00000020
+#define UMBOX_HCI_FRAMER_ENABLE_GET(x) (((x) & UMBOX_HCI_FRAMER_ENABLE_MASK) >> UMBOX_HCI_FRAMER_ENABLE_LSB)
+#define UMBOX_HCI_FRAMER_ENABLE_SET(x) (((x) << UMBOX_HCI_FRAMER_ENABLE_LSB) & UMBOX_HCI_FRAMER_ENABLE_MASK)
+#define UMBOX_HCI_FRAMER_SYNC_ERROR_MSB 4
+#define UMBOX_HCI_FRAMER_SYNC_ERROR_LSB 4
+#define UMBOX_HCI_FRAMER_SYNC_ERROR_MASK 0x00000010
+#define UMBOX_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & UMBOX_HCI_FRAMER_SYNC_ERROR_MASK) >> UMBOX_HCI_FRAMER_SYNC_ERROR_LSB)
+#define UMBOX_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << UMBOX_HCI_FRAMER_SYNC_ERROR_LSB) & UMBOX_HCI_FRAMER_SYNC_ERROR_MASK)
+#define UMBOX_HCI_FRAMER_UNDERFLOW_MSB 3
+#define UMBOX_HCI_FRAMER_UNDERFLOW_LSB 3
+#define UMBOX_HCI_FRAMER_UNDERFLOW_MASK 0x00000008
+#define UMBOX_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & UMBOX_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_HCI_FRAMER_UNDERFLOW_LSB)
+#define UMBOX_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << UMBOX_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_HCI_FRAMER_UNDERFLOW_MASK)
+#define UMBOX_HCI_FRAMER_OVERFLOW_MSB 2
+#define UMBOX_HCI_FRAMER_OVERFLOW_LSB 2
+#define UMBOX_HCI_FRAMER_OVERFLOW_MASK 0x00000004
+#define UMBOX_HCI_FRAMER_OVERFLOW_GET(x) (((x) & UMBOX_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_HCI_FRAMER_OVERFLOW_LSB)
+#define UMBOX_HCI_FRAMER_OVERFLOW_SET(x) (((x) << UMBOX_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_HCI_FRAMER_OVERFLOW_MASK)
+#define UMBOX_HCI_FRAMER_CONFIG_MODE_MSB 1
+#define UMBOX_HCI_FRAMER_CONFIG_MODE_LSB 0
+#define UMBOX_HCI_FRAMER_CONFIG_MODE_MASK 0x00000003
+#define UMBOX_HCI_FRAMER_CONFIG_MODE_GET(x) (((x) & UMBOX_HCI_FRAMER_CONFIG_MODE_MASK) >> UMBOX_HCI_FRAMER_CONFIG_MODE_LSB)
+#define UMBOX_HCI_FRAMER_CONFIG_MODE_SET(x) (((x) << UMBOX_HCI_FRAMER_CONFIG_MODE_LSB) & UMBOX_HCI_FRAMER_CONFIG_MODE_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct umbox_wlan_reg_reg_s {
+ volatile unsigned int umbox_fifo[2];
+ volatile unsigned int umbox_fifo_status;
+ volatile unsigned int umbox_dma_policy;
+ volatile unsigned int umbox0_dma_rx_descriptor_base;
+ volatile unsigned int umbox0_dma_rx_control;
+ volatile unsigned int umbox0_dma_tx_descriptor_base;
+ volatile unsigned int umbox0_dma_tx_control;
+ volatile unsigned int umbox_fifo_timeout;
+ volatile unsigned int umbox_int_status;
+ volatile unsigned int umbox_int_enable;
+ volatile unsigned int umbox_debug;
+ volatile unsigned int umbox_fifo_reset;
+ volatile unsigned int umbox_hci_framer;
+} umbox_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _UMBOX_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h
new file mode 100644
index 000000000000..c3d8088a5554
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h
@@ -0,0 +1,167 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifdef WLAN_HEADERS
+
+#include "vmc_wlan_reg.h"
+
+
+#ifndef BT_HEADERS
+
+#define MC_BCAM_VALID_ADDRESS WLAN_MC_BCAM_VALID_ADDRESS
+#define MC_BCAM_VALID_OFFSET WLAN_MC_BCAM_VALID_OFFSET
+#define MC_BCAM_VALID_BIT_MSB WLAN_MC_BCAM_VALID_BIT_MSB
+#define MC_BCAM_VALID_BIT_LSB WLAN_MC_BCAM_VALID_BIT_LSB
+#define MC_BCAM_VALID_BIT_MASK WLAN_MC_BCAM_VALID_BIT_MASK
+#define MC_BCAM_VALID_BIT_GET(x) WLAN_MC_BCAM_VALID_BIT_GET(x)
+#define MC_BCAM_VALID_BIT_SET(x) WLAN_MC_BCAM_VALID_BIT_SET(x)
+#define MC_BCAM_COMPARE_ADDRESS WLAN_MC_BCAM_COMPARE_ADDRESS
+#define MC_BCAM_COMPARE_OFFSET WLAN_MC_BCAM_COMPARE_OFFSET
+#define MC_BCAM_COMPARE_KEY_MSB WLAN_MC_BCAM_COMPARE_KEY_MSB
+#define MC_BCAM_COMPARE_KEY_LSB WLAN_MC_BCAM_COMPARE_KEY_LSB
+#define MC_BCAM_COMPARE_KEY_MASK WLAN_MC_BCAM_COMPARE_KEY_MASK
+#define MC_BCAM_COMPARE_KEY_GET(x) WLAN_MC_BCAM_COMPARE_KEY_GET(x)
+#define MC_BCAM_COMPARE_KEY_SET(x) WLAN_MC_BCAM_COMPARE_KEY_SET(x)
+#define MC_BCAM_TARGET_ADDRESS WLAN_MC_BCAM_TARGET_ADDRESS
+#define MC_BCAM_TARGET_OFFSET WLAN_MC_BCAM_TARGET_OFFSET
+#define MC_BCAM_TARGET_INST_MSB WLAN_MC_BCAM_TARGET_INST_MSB
+#define MC_BCAM_TARGET_INST_LSB WLAN_MC_BCAM_TARGET_INST_LSB
+#define MC_BCAM_TARGET_INST_MASK WLAN_MC_BCAM_TARGET_INST_MASK
+#define MC_BCAM_TARGET_INST_GET(x) WLAN_MC_BCAM_TARGET_INST_GET(x)
+#define MC_BCAM_TARGET_INST_SET(x) WLAN_MC_BCAM_TARGET_INST_SET(x)
+#define APB_ADDR_ERROR_CONTROL_ADDRESS WLAN_APB_ADDR_ERROR_CONTROL_ADDRESS
+#define APB_ADDR_ERROR_CONTROL_OFFSET WLAN_APB_ADDR_ERROR_CONTROL_OFFSET
+#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB
+#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB
+#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK
+#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x)
+#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x)
+#define APB_ADDR_ERROR_CONTROL_ENABLE_MSB WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MSB
+#define APB_ADDR_ERROR_CONTROL_ENABLE_LSB WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB
+#define APB_ADDR_ERROR_CONTROL_ENABLE_MASK WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK
+#define APB_ADDR_ERROR_CONTROL_ENABLE_GET(x) WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_GET(x)
+#define APB_ADDR_ERROR_CONTROL_ENABLE_SET(x) WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_SET(x)
+#define APB_ADDR_ERROR_STATUS_ADDRESS WLAN_APB_ADDR_ERROR_STATUS_ADDRESS
+#define APB_ADDR_ERROR_STATUS_OFFSET WLAN_APB_ADDR_ERROR_STATUS_OFFSET
+#define APB_ADDR_ERROR_STATUS_WRITE_MSB WLAN_APB_ADDR_ERROR_STATUS_WRITE_MSB
+#define APB_ADDR_ERROR_STATUS_WRITE_LSB WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB
+#define APB_ADDR_ERROR_STATUS_WRITE_MASK WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK
+#define APB_ADDR_ERROR_STATUS_WRITE_GET(x) WLAN_APB_ADDR_ERROR_STATUS_WRITE_GET(x)
+#define APB_ADDR_ERROR_STATUS_WRITE_SET(x) WLAN_APB_ADDR_ERROR_STATUS_WRITE_SET(x)
+#define APB_ADDR_ERROR_STATUS_ADDRESS_MSB WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MSB
+#define APB_ADDR_ERROR_STATUS_ADDRESS_LSB WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB
+#define APB_ADDR_ERROR_STATUS_ADDRESS_MASK WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK
+#define APB_ADDR_ERROR_STATUS_ADDRESS_GET(x) WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_GET(x)
+#define APB_ADDR_ERROR_STATUS_ADDRESS_SET(x) WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_SET(x)
+#define AHB_ADDR_ERROR_CONTROL_ADDRESS WLAN_AHB_ADDR_ERROR_CONTROL_ADDRESS
+#define AHB_ADDR_ERROR_CONTROL_OFFSET WLAN_AHB_ADDR_ERROR_CONTROL_OFFSET
+#define AHB_ADDR_ERROR_CONTROL_ENABLE_MSB WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MSB
+#define AHB_ADDR_ERROR_CONTROL_ENABLE_LSB WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB
+#define AHB_ADDR_ERROR_CONTROL_ENABLE_MASK WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK
+#define AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x) WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x)
+#define AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x) WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x)
+#define AHB_ADDR_ERROR_STATUS_ADDRESS WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS
+#define AHB_ADDR_ERROR_STATUS_OFFSET WLAN_AHB_ADDR_ERROR_STATUS_OFFSET
+#define AHB_ADDR_ERROR_STATUS_MAC_MSB WLAN_AHB_ADDR_ERROR_STATUS_MAC_MSB
+#define AHB_ADDR_ERROR_STATUS_MAC_LSB WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB
+#define AHB_ADDR_ERROR_STATUS_MAC_MASK WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK
+#define AHB_ADDR_ERROR_STATUS_MAC_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_MAC_GET(x)
+#define AHB_ADDR_ERROR_STATUS_MAC_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_MAC_SET(x)
+#define AHB_ADDR_ERROR_STATUS_MBOX_MSB WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MSB
+#define AHB_ADDR_ERROR_STATUS_MBOX_LSB WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB
+#define AHB_ADDR_ERROR_STATUS_MBOX_MASK WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK
+#define AHB_ADDR_ERROR_STATUS_MBOX_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_MBOX_GET(x)
+#define AHB_ADDR_ERROR_STATUS_MBOX_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_MBOX_SET(x)
+#define AHB_ADDR_ERROR_STATUS_ADDRESS_MSB WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MSB
+#define AHB_ADDR_ERROR_STATUS_ADDRESS_LSB WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB
+#define AHB_ADDR_ERROR_STATUS_ADDRESS_MASK WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK
+#define AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x)
+#define AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x)
+#define BCAM_CONFLICT_ERROR_ADDRESS WLAN_BCAM_CONFLICT_ERROR_ADDRESS
+#define BCAM_CONFLICT_ERROR_OFFSET WLAN_BCAM_CONFLICT_ERROR_OFFSET
+#define BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB
+#define BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB
+#define BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK
+#define BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x) WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x)
+#define BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x) WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x)
+#define BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB
+#define BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB
+#define BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK
+#define BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x) WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x)
+#define BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x) WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x)
+#define CPU_PERF_CNT_ADDRESS WLAN_CPU_PERF_CNT_ADDRESS
+#define CPU_PERF_CNT_OFFSET WLAN_CPU_PERF_CNT_OFFSET
+#define CPU_PERF_CNT_EN_MSB WLAN_CPU_PERF_CNT_EN_MSB
+#define CPU_PERF_CNT_EN_LSB WLAN_CPU_PERF_CNT_EN_LSB
+#define CPU_PERF_CNT_EN_MASK WLAN_CPU_PERF_CNT_EN_MASK
+#define CPU_PERF_CNT_EN_GET(x) WLAN_CPU_PERF_CNT_EN_GET(x)
+#define CPU_PERF_CNT_EN_SET(x) WLAN_CPU_PERF_CNT_EN_SET(x)
+#define CPU_INST_FETCH_ADDRESS WLAN_CPU_INST_FETCH_ADDRESS
+#define CPU_INST_FETCH_OFFSET WLAN_CPU_INST_FETCH_OFFSET
+#define CPU_INST_FETCH_CNT_MSB WLAN_CPU_INST_FETCH_CNT_MSB
+#define CPU_INST_FETCH_CNT_LSB WLAN_CPU_INST_FETCH_CNT_LSB
+#define CPU_INST_FETCH_CNT_MASK WLAN_CPU_INST_FETCH_CNT_MASK
+#define CPU_INST_FETCH_CNT_GET(x) WLAN_CPU_INST_FETCH_CNT_GET(x)
+#define CPU_INST_FETCH_CNT_SET(x) WLAN_CPU_INST_FETCH_CNT_SET(x)
+#define CPU_DATA_FETCH_ADDRESS WLAN_CPU_DATA_FETCH_ADDRESS
+#define CPU_DATA_FETCH_OFFSET WLAN_CPU_DATA_FETCH_OFFSET
+#define CPU_DATA_FETCH_CNT_MSB WLAN_CPU_DATA_FETCH_CNT_MSB
+#define CPU_DATA_FETCH_CNT_LSB WLAN_CPU_DATA_FETCH_CNT_LSB
+#define CPU_DATA_FETCH_CNT_MASK WLAN_CPU_DATA_FETCH_CNT_MASK
+#define CPU_DATA_FETCH_CNT_GET(x) WLAN_CPU_DATA_FETCH_CNT_GET(x)
+#define CPU_DATA_FETCH_CNT_SET(x) WLAN_CPU_DATA_FETCH_CNT_SET(x)
+#define CPU_RAM1_CONFLICT_ADDRESS WLAN_CPU_RAM1_CONFLICT_ADDRESS
+#define CPU_RAM1_CONFLICT_OFFSET WLAN_CPU_RAM1_CONFLICT_OFFSET
+#define CPU_RAM1_CONFLICT_CNT_MSB WLAN_CPU_RAM1_CONFLICT_CNT_MSB
+#define CPU_RAM1_CONFLICT_CNT_LSB WLAN_CPU_RAM1_CONFLICT_CNT_LSB
+#define CPU_RAM1_CONFLICT_CNT_MASK WLAN_CPU_RAM1_CONFLICT_CNT_MASK
+#define CPU_RAM1_CONFLICT_CNT_GET(x) WLAN_CPU_RAM1_CONFLICT_CNT_GET(x)
+#define CPU_RAM1_CONFLICT_CNT_SET(x) WLAN_CPU_RAM1_CONFLICT_CNT_SET(x)
+#define CPU_RAM2_CONFLICT_ADDRESS WLAN_CPU_RAM2_CONFLICT_ADDRESS
+#define CPU_RAM2_CONFLICT_OFFSET WLAN_CPU_RAM2_CONFLICT_OFFSET
+#define CPU_RAM2_CONFLICT_CNT_MSB WLAN_CPU_RAM2_CONFLICT_CNT_MSB
+#define CPU_RAM2_CONFLICT_CNT_LSB WLAN_CPU_RAM2_CONFLICT_CNT_LSB
+#define CPU_RAM2_CONFLICT_CNT_MASK WLAN_CPU_RAM2_CONFLICT_CNT_MASK
+#define CPU_RAM2_CONFLICT_CNT_GET(x) WLAN_CPU_RAM2_CONFLICT_CNT_GET(x)
+#define CPU_RAM2_CONFLICT_CNT_SET(x) WLAN_CPU_RAM2_CONFLICT_CNT_SET(x)
+#define CPU_RAM3_CONFLICT_ADDRESS WLAN_CPU_RAM3_CONFLICT_ADDRESS
+#define CPU_RAM3_CONFLICT_OFFSET WLAN_CPU_RAM3_CONFLICT_OFFSET
+#define CPU_RAM3_CONFLICT_CNT_MSB WLAN_CPU_RAM3_CONFLICT_CNT_MSB
+#define CPU_RAM3_CONFLICT_CNT_LSB WLAN_CPU_RAM3_CONFLICT_CNT_LSB
+#define CPU_RAM3_CONFLICT_CNT_MASK WLAN_CPU_RAM3_CONFLICT_CNT_MASK
+#define CPU_RAM3_CONFLICT_CNT_GET(x) WLAN_CPU_RAM3_CONFLICT_CNT_GET(x)
+#define CPU_RAM3_CONFLICT_CNT_SET(x) WLAN_CPU_RAM3_CONFLICT_CNT_SET(x)
+#define CPU_RAM4_CONFLICT_ADDRESS WLAN_CPU_RAM4_CONFLICT_ADDRESS
+#define CPU_RAM4_CONFLICT_OFFSET WLAN_CPU_RAM4_CONFLICT_OFFSET
+#define CPU_RAM4_CONFLICT_CNT_MSB WLAN_CPU_RAM4_CONFLICT_CNT_MSB
+#define CPU_RAM4_CONFLICT_CNT_LSB WLAN_CPU_RAM4_CONFLICT_CNT_LSB
+#define CPU_RAM4_CONFLICT_CNT_MASK WLAN_CPU_RAM4_CONFLICT_CNT_MASK
+#define CPU_RAM4_CONFLICT_CNT_GET(x) WLAN_CPU_RAM4_CONFLICT_CNT_GET(x)
+#define CPU_RAM4_CONFLICT_CNT_SET(x) WLAN_CPU_RAM4_CONFLICT_CNT_SET(x)
+
+
+#endif
+#endif
+
+
+
diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h
new file mode 100644
index 000000000000..d28de3938b2e
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h
@@ -0,0 +1,195 @@
+// ------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+// ------------------------------------------------------------------
+//===================================================================
+// Author(s): ="Atheros"
+//===================================================================
+
+
+#ifndef _VMC_WLAN_REG_REG_H_
+#define _VMC_WLAN_REG_REG_H_
+
+#define WLAN_MC_BCAM_VALID_ADDRESS 0x00000000
+#define WLAN_MC_BCAM_VALID_OFFSET 0x00000000
+#define WLAN_MC_BCAM_VALID_BIT_MSB 0
+#define WLAN_MC_BCAM_VALID_BIT_LSB 0
+#define WLAN_MC_BCAM_VALID_BIT_MASK 0x00000001
+#define WLAN_MC_BCAM_VALID_BIT_GET(x) (((x) & WLAN_MC_BCAM_VALID_BIT_MASK) >> WLAN_MC_BCAM_VALID_BIT_LSB)
+#define WLAN_MC_BCAM_VALID_BIT_SET(x) (((x) << WLAN_MC_BCAM_VALID_BIT_LSB) & WLAN_MC_BCAM_VALID_BIT_MASK)
+
+#define WLAN_MC_BCAM_COMPARE_ADDRESS 0x00000200
+#define WLAN_MC_BCAM_COMPARE_OFFSET 0x00000200
+#define WLAN_MC_BCAM_COMPARE_KEY_MSB 19
+#define WLAN_MC_BCAM_COMPARE_KEY_LSB 2
+#define WLAN_MC_BCAM_COMPARE_KEY_MASK 0x000ffffc
+#define WLAN_MC_BCAM_COMPARE_KEY_GET(x) (((x) & WLAN_MC_BCAM_COMPARE_KEY_MASK) >> WLAN_MC_BCAM_COMPARE_KEY_LSB)
+#define WLAN_MC_BCAM_COMPARE_KEY_SET(x) (((x) << WLAN_MC_BCAM_COMPARE_KEY_LSB) & WLAN_MC_BCAM_COMPARE_KEY_MASK)
+
+#define WLAN_MC_BCAM_TARGET_ADDRESS 0x00000400
+#define WLAN_MC_BCAM_TARGET_OFFSET 0x00000400
+#define WLAN_MC_BCAM_TARGET_INST_MSB 31
+#define WLAN_MC_BCAM_TARGET_INST_LSB 0
+#define WLAN_MC_BCAM_TARGET_INST_MASK 0xffffffff
+#define WLAN_MC_BCAM_TARGET_INST_GET(x) (((x) & WLAN_MC_BCAM_TARGET_INST_MASK) >> WLAN_MC_BCAM_TARGET_INST_LSB)
+#define WLAN_MC_BCAM_TARGET_INST_SET(x) (((x) << WLAN_MC_BCAM_TARGET_INST_LSB) & WLAN_MC_BCAM_TARGET_INST_MASK)
+
+#define WLAN_APB_ADDR_ERROR_CONTROL_ADDRESS 0x00000600
+#define WLAN_APB_ADDR_ERROR_CONTROL_OFFSET 0x00000600
+#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB 1
+#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB 1
+#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK 0x00000002
+#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) (((x) & WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) >> WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB)
+#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) (((x) << WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) & WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK)
+#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MSB 0
+#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB 0
+#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK 0x00000001
+#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x) & WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK) >> WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB)
+#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB) & WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK)
+
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS 0x00000604
+#define WLAN_APB_ADDR_ERROR_STATUS_OFFSET 0x00000604
+#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_MSB 25
+#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB 25
+#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK 0x02000000
+#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_GET(x) (((x) & WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK) >> WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB)
+#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_SET(x) (((x) << WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB) & WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK)
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MSB 24
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB 0
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK 0x01ffffff
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x) & WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK) >> WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB)
+#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB) & WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK)
+
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ADDRESS 0x00000608
+#define WLAN_AHB_ADDR_ERROR_CONTROL_OFFSET 0x00000608
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MSB 0
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB 0
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK 0x00000001
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK) >> WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB)
+#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB) & WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK)
+
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS 0x0000060c
+#define WLAN_AHB_ADDR_ERROR_STATUS_OFFSET 0x0000060c
+#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_MSB 31
+#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB 31
+#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK 0x80000000
+#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB)
+#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK)
+#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MSB 30
+#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB 30
+#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK 0x40000000
+#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB)
+#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK)
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MSB 23
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB 0
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK 0x00ffffff
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB)
+#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK)
+
+#define WLAN_BCAM_CONFLICT_ERROR_ADDRESS 0x00000610
+#define WLAN_BCAM_CONFLICT_ERROR_OFFSET 0x00000610
+#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB 1
+#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB 1
+#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK 0x00000002
+#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x) (((x) & WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK) >> WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB)
+#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x) (((x) << WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB) & WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK)
+#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB 0
+#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB 0
+#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK 0x00000001
+#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x) (((x) & WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK) >> WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB)
+#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x) (((x) << WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB) & WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK)
+
+#define WLAN_CPU_PERF_CNT_ADDRESS 0x00000614
+#define WLAN_CPU_PERF_CNT_OFFSET 0x00000614
+#define WLAN_CPU_PERF_CNT_EN_MSB 0
+#define WLAN_CPU_PERF_CNT_EN_LSB 0
+#define WLAN_CPU_PERF_CNT_EN_MASK 0x00000001
+#define WLAN_CPU_PERF_CNT_EN_GET(x) (((x) & WLAN_CPU_PERF_CNT_EN_MASK) >> WLAN_CPU_PERF_CNT_EN_LSB)
+#define WLAN_CPU_PERF_CNT_EN_SET(x) (((x) << WLAN_CPU_PERF_CNT_EN_LSB) & WLAN_CPU_PERF_CNT_EN_MASK)
+
+#define WLAN_CPU_INST_FETCH_ADDRESS 0x00000618
+#define WLAN_CPU_INST_FETCH_OFFSET 0x00000618
+#define WLAN_CPU_INST_FETCH_CNT_MSB 31
+#define WLAN_CPU_INST_FETCH_CNT_LSB 0
+#define WLAN_CPU_INST_FETCH_CNT_MASK 0xffffffff
+#define WLAN_CPU_INST_FETCH_CNT_GET(x) (((x) & WLAN_CPU_INST_FETCH_CNT_MASK) >> WLAN_CPU_INST_FETCH_CNT_LSB)
+#define WLAN_CPU_INST_FETCH_CNT_SET(x) (((x) << WLAN_CPU_INST_FETCH_CNT_LSB) & WLAN_CPU_INST_FETCH_CNT_MASK)
+
+#define WLAN_CPU_DATA_FETCH_ADDRESS 0x0000061c
+#define WLAN_CPU_DATA_FETCH_OFFSET 0x0000061c
+#define WLAN_CPU_DATA_FETCH_CNT_MSB 31
+#define WLAN_CPU_DATA_FETCH_CNT_LSB 0
+#define WLAN_CPU_DATA_FETCH_CNT_MASK 0xffffffff
+#define WLAN_CPU_DATA_FETCH_CNT_GET(x) (((x) & WLAN_CPU_DATA_FETCH_CNT_MASK) >> WLAN_CPU_DATA_FETCH_CNT_LSB)
+#define WLAN_CPU_DATA_FETCH_CNT_SET(x) (((x) << WLAN_CPU_DATA_FETCH_CNT_LSB) & WLAN_CPU_DATA_FETCH_CNT_MASK)
+
+#define WLAN_CPU_RAM1_CONFLICT_ADDRESS 0x00000620
+#define WLAN_CPU_RAM1_CONFLICT_OFFSET 0x00000620
+#define WLAN_CPU_RAM1_CONFLICT_CNT_MSB 11
+#define WLAN_CPU_RAM1_CONFLICT_CNT_LSB 0
+#define WLAN_CPU_RAM1_CONFLICT_CNT_MASK 0x00000fff
+#define WLAN_CPU_RAM1_CONFLICT_CNT_GET(x) (((x) & WLAN_CPU_RAM1_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM1_CONFLICT_CNT_LSB)
+#define WLAN_CPU_RAM1_CONFLICT_CNT_SET(x) (((x) << WLAN_CPU_RAM1_CONFLICT_CNT_LSB) & WLAN_CPU_RAM1_CONFLICT_CNT_MASK)
+
+#define WLAN_CPU_RAM2_CONFLICT_ADDRESS 0x00000624
+#define WLAN_CPU_RAM2_CONFLICT_OFFSET 0x00000624
+#define WLAN_CPU_RAM2_CONFLICT_CNT_MSB 11
+#define WLAN_CPU_RAM2_CONFLICT_CNT_LSB 0
+#define WLAN_CPU_RAM2_CONFLICT_CNT_MASK 0x00000fff
+#define WLAN_CPU_RAM2_CONFLICT_CNT_GET(x) (((x) & WLAN_CPU_RAM2_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM2_CONFLICT_CNT_LSB)
+#define WLAN_CPU_RAM2_CONFLICT_CNT_SET(x) (((x) << WLAN_CPU_RAM2_CONFLICT_CNT_LSB) & WLAN_CPU_RAM2_CONFLICT_CNT_MASK)
+
+#define WLAN_CPU_RAM3_CONFLICT_ADDRESS 0x00000628
+#define WLAN_CPU_RAM3_CONFLICT_OFFSET 0x00000628
+#define WLAN_CPU_RAM3_CONFLICT_CNT_MSB 11
+#define WLAN_CPU_RAM3_CONFLICT_CNT_LSB 0
+#define WLAN_CPU_RAM3_CONFLICT_CNT_MASK 0x00000fff
+#define WLAN_CPU_RAM3_CONFLICT_CNT_GET(x) (((x) & WLAN_CPU_RAM3_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM3_CONFLICT_CNT_LSB)
+#define WLAN_CPU_RAM3_CONFLICT_CNT_SET(x) (((x) << WLAN_CPU_RAM3_CONFLICT_CNT_LSB) & WLAN_CPU_RAM3_CONFLICT_CNT_MASK)
+
+#define WLAN_CPU_RAM4_CONFLICT_ADDRESS 0x0000062c
+#define WLAN_CPU_RAM4_CONFLICT_OFFSET 0x0000062c
+#define WLAN_CPU_RAM4_CONFLICT_CNT_MSB 11
+#define WLAN_CPU_RAM4_CONFLICT_CNT_LSB 0
+#define WLAN_CPU_RAM4_CONFLICT_CNT_MASK 0x00000fff
+#define WLAN_CPU_RAM4_CONFLICT_CNT_GET(x) (((x) & WLAN_CPU_RAM4_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM4_CONFLICT_CNT_LSB)
+#define WLAN_CPU_RAM4_CONFLICT_CNT_SET(x) (((x) << WLAN_CPU_RAM4_CONFLICT_CNT_LSB) & WLAN_CPU_RAM4_CONFLICT_CNT_MASK)
+
+
+#ifndef __ASSEMBLER__
+
+typedef struct vmc_wlan_reg_reg_s {
+ volatile unsigned int wlan_mc_bcam_valid[128];
+ volatile unsigned int wlan_mc_bcam_compare[128];
+ volatile unsigned int wlan_mc_bcam_target[128];
+ volatile unsigned int wlan_apb_addr_error_control;
+ volatile unsigned int wlan_apb_addr_error_status;
+ volatile unsigned int wlan_ahb_addr_error_control;
+ volatile unsigned int wlan_ahb_addr_error_status;
+ volatile unsigned int wlan_bcam_conflict_error;
+ volatile unsigned int wlan_cpu_perf_cnt;
+ volatile unsigned int wlan_cpu_inst_fetch;
+ volatile unsigned int wlan_cpu_data_fetch;
+ volatile unsigned int wlan_cpu_ram1_conflict;
+ volatile unsigned int wlan_cpu_ram2_conflict;
+ volatile unsigned int wlan_cpu_ram3_conflict;
+ volatile unsigned int wlan_cpu_ram4_conflict;
+} vmc_wlan_reg_reg_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _VMC_WLAN_REG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h
new file mode 100644
index 000000000000..f2943466339f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/a_hci.h
@@ -0,0 +1,682 @@
+//-
+// Copyright (c) 2009-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+// 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 __A_HCI_H__
+#define __A_HCI_H__
+
+#define HCI_CMD_OGF_MASK 0x3F
+#define HCI_CMD_OGF_SHIFT 10
+#define HCI_CMD_GET_OGF(opcode) ((opcode >> HCI_CMD_OGF_SHIFT) & HCI_CMD_OGF_MASK)
+
+#define HCI_CMD_OCF_MASK 0x3FF
+#define HCI_CMD_OCF_SHIFT 0
+#define HCI_CMD_GET_OCF(opcode) (((opcode) >> HCI_CMD_OCF_SHIFT) & HCI_CMD_OCF_MASK)
+
+#define HCI_FORM_OPCODE(ocf, ogf) ((ocf & HCI_CMD_OCF_MASK) << HCI_CMD_OCF_SHIFT | \
+ (ogf & HCI_CMD_OGF_MASK) << HCI_CMD_OGF_SHIFT)
+
+
+/*======== HCI Opcode groups ===============*/
+#define OGF_NOP 0x00
+#define OGF_LINK_CONTROL 0x01
+#define OGF_LINK_POLICY 0x03
+#define OGF_INFO_PARAMS 0x04
+#define OGF_STATUS 0x05
+#define OGF_TESTING 0x06
+#define OGF_BLUETOOTH 0x3E
+#define OGF_VENDOR_DEBUG 0x3F
+
+
+
+#define OCF_NOP 0x00
+
+
+/*===== Link Control Commands Opcode===================*/
+#define OCF_HCI_Create_Physical_Link 0x35
+#define OCF_HCI_Accept_Physical_Link_Req 0x36
+#define OCF_HCI_Disconnect_Physical_Link 0x37
+#define OCF_HCI_Create_Logical_Link 0x38
+#define OCF_HCI_Accept_Logical_Link 0x39
+#define OCF_HCI_Disconnect_Logical_Link 0x3A
+#define OCF_HCI_Logical_Link_Cancel 0x3B
+#define OCF_HCI_Flow_Spec_Modify 0x3C
+
+
+
+/*===== Link Policy Commands Opcode====================*/
+#define OCF_HCI_Set_Event_Mask 0x01
+#define OCF_HCI_Reset 0x03
+#define OCF_HCI_Read_Conn_Accept_Timeout 0x15
+#define OCF_HCI_Write_Conn_Accept_Timeout 0x16
+#define OCF_HCI_Read_Link_Supervision_Timeout 0x36
+#define OCF_HCI_Write_Link_Supervision_Timeout 0x37
+#define OCF_HCI_Enhanced_Flush 0x5F
+#define OCF_HCI_Read_Logical_Link_Accept_Timeout 0x61
+#define OCF_HCI_Write_Logical_Link_Accept_Timeout 0x62
+#define OCF_HCI_Set_Event_Mask_Page_2 0x63
+#define OCF_HCI_Read_Location_Data 0x64
+#define OCF_HCI_Write_Location_Data 0x65
+#define OCF_HCI_Read_Flow_Control_Mode 0x66
+#define OCF_HCI_Write_Flow_Control_Mode 0x67
+#define OCF_HCI_Read_BE_Flush_Timeout 0x69
+#define OCF_HCI_Write_BE_Flush_Timeout 0x6A
+#define OCF_HCI_Short_Range_Mode 0x6B
+
+
+/*======== Info Commands Opcode========================*/
+#define OCF_HCI_Read_Local_Ver_Info 0x01
+#define OCF_HCI_Read_Local_Supported_Cmds 0x02
+#define OCF_HCI_Read_Data_Block_Size 0x0A
+/*======== Status Commands Opcode======================*/
+#define OCF_HCI_Read_Failed_Contact_Counter 0x01
+#define OCF_HCI_Reset_Failed_Contact_Counter 0x02
+#define OCF_HCI_Read_Link_Quality 0x03
+#define OCF_HCI_Read_RSSI 0x05
+#define OCF_HCI_Read_Local_AMP_Info 0x09
+#define OCF_HCI_Read_Local_AMP_ASSOC 0x0A
+#define OCF_HCI_Write_Remote_AMP_ASSOC 0x0B
+
+
+/*======= AMP_ASSOC Specific TLV tags =================*/
+#define AMP_ASSOC_MAC_ADDRESS_INFO_TYPE 0x1
+#define AMP_ASSOC_PREF_CHAN_LIST 0x2
+#define AMP_ASSOC_CONNECTED_CHAN 0x3
+#define AMP_ASSOC_PAL_CAPABILITIES 0x4
+#define AMP_ASSOC_PAL_VERSION 0x5
+
+
+/*========= PAL Events =================================*/
+#define PAL_COMMAND_COMPLETE_EVENT 0x0E
+#define PAL_COMMAND_STATUS_EVENT 0x0F
+#define PAL_HARDWARE_ERROR_EVENT 0x10
+#define PAL_FLUSH_OCCURRED_EVENT 0x11
+#define PAL_LOOPBACK_EVENT 0x19
+#define PAL_BUFFER_OVERFLOW_EVENT 0x1A
+#define PAL_QOS_VIOLATION_EVENT 0x1E
+#define PAL_ENHANCED_FLUSH_COMPLT_EVENT 0x39
+#define PAL_PHYSICAL_LINK_COMPL_EVENT 0x40
+#define PAL_CHANNEL_SELECT_EVENT 0x41
+#define PAL_DISCONNECT_PHYSICAL_LINK_EVENT 0x42
+#define PAL_PHY_LINK_EARLY_LOSS_WARNING_EVENT 0x43
+#define PAL_PHY_LINK_RECOVERY_EVENT 0x44
+#define PAL_LOGICAL_LINK_COMPL_EVENT 0x45
+#define PAL_DISCONNECT_LOGICAL_LINK_COMPL_EVENT 0x46
+#define PAL_FLOW_SPEC_MODIFY_COMPL_EVENT 0x47
+#define PAL_NUM_COMPL_DATA_BLOCK_EVENT 0x48
+#define PAL_SHORT_RANGE_MODE_CHANGE_COMPL_EVENT 0x4C
+#define PAL_AMP_STATUS_CHANGE_EVENT 0x4D
+/*======== End of PAL events definiton =================*/
+
+
+/*======== Timeouts (not part of HCI cmd, but input to PAL engine) =========*/
+#define Timer_Conn_Accept_TO 0x01
+#define Timer_Link_Supervision_TO 0x02
+
+#define NUM_HCI_COMMAND_PKTS 0x1
+
+
+/*====== NOP Cmd ============================*/
+#define HCI_CMD_NOP HCI_FORM_OPCODE(OCF_NOP, OGF_NOP)
+
+
+/*===== Link Control Commands================*/
+#define HCI_Create_Physical_Link HCI_FORM_OPCODE(OCF_HCI_Create_Physical_Link, OGF_LINK_CONTROL)
+#define HCI_Accept_Physical_Link_Req HCI_FORM_OPCODE(OCF_HCI_Accept_Physical_Link_Req, OGF_LINK_CONTROL)
+#define HCI_Disconnect_Physical_Link HCI_FORM_OPCODE(OCF_HCI_Disconnect_Physical_Link, OGF_LINK_CONTROL)
+#define HCI_Create_Logical_Link HCI_FORM_OPCODE(OCF_HCI_Create_Logical_Link, OGF_LINK_CONTROL)
+#define HCI_Accept_Logical_Link HCI_FORM_OPCODE(OCF_HCI_Accept_Logical_Link, OGF_LINK_CONTROL)
+#define HCI_Disconnect_Logical_Link HCI_FORM_OPCODE(OCF_HCI_Disconnect_Logical_Link, OGF_LINK_CONTROL)
+#define HCI_Logical_Link_Cancel HCI_FORM_OPCODE(OCF_HCI_Logical_Link_Cancel, OGF_LINK_CONTROL)
+#define HCI_Flow_Spec_Modify HCI_FORM_OPCODE(OCF_HCI_Flow_Spec_Modify, OGF_LINK_CONTROL)
+
+
+/*===== Link Policy Commands ================*/
+#define HCI_Set_Event_Mask HCI_FORM_OPCODE(OCF_HCI_Set_Event_Mask, OGF_LINK_POLICY)
+#define HCI_Reset HCI_FORM_OPCODE(OCF_HCI_Reset, OGF_LINK_POLICY)
+#define HCI_Enhanced_Flush HCI_FORM_OPCODE(OCF_HCI_Enhanced_Flush, OGF_LINK_POLICY)
+#define HCI_Read_Conn_Accept_Timeout HCI_FORM_OPCODE(OCF_HCI_Read_Conn_Accept_Timeout, OGF_LINK_POLICY)
+#define HCI_Write_Conn_Accept_Timeout HCI_FORM_OPCODE(OCF_HCI_Write_Conn_Accept_Timeout, OGF_LINK_POLICY)
+#define HCI_Read_Logical_Link_Accept_Timeout HCI_FORM_OPCODE(OCF_HCI_Read_Logical_Link_Accept_Timeout, OGF_LINK_POLICY)
+#define HCI_Write_Logical_Link_Accept_Timeout HCI_FORM_OPCODE(OCF_HCI_Write_Logical_Link_Accept_Timeout, OGF_LINK_POLICY)
+#define HCI_Read_Link_Supervision_Timeout HCI_FORM_OPCODE(OCF_HCI_Read_Link_Supervision_Timeout, OGF_LINK_POLICY)
+#define HCI_Write_Link_Supervision_Timeout HCI_FORM_OPCODE(OCF_HCI_Write_Link_Supervision_Timeout, OGF_LINK_POLICY)
+#define HCI_Read_Location_Data HCI_FORM_OPCODE(OCF_HCI_Read_Location_Data, OGF_LINK_POLICY)
+#define HCI_Write_Location_Data HCI_FORM_OPCODE(OCF_HCI_Write_Location_Data, OGF_LINK_POLICY)
+#define HCI_Set_Event_Mask_Page_2 HCI_FORM_OPCODE(OCF_HCI_Set_Event_Mask_Page_2, OGF_LINK_POLICY)
+#define HCI_Read_Flow_Control_Mode HCI_FORM_OPCODE(OCF_HCI_Read_Flow_Control_Mode, OGF_LINK_POLICY)
+#define HCI_Write_Flow_Control_Mode HCI_FORM_OPCODE(OCF_HCI_Write_Flow_Control_Mode, OGF_LINK_POLICY)
+#define HCI_Write_BE_Flush_Timeout HCI_FORM_OPCODE(OCF_HCI_Write_BE_Flush_Timeout, OGF_LINK_POLICY)
+#define HCI_Read_BE_Flush_Timeout HCI_FORM_OPCODE(OCF_HCI_Read_BE_Flush_Timeout, OGF_LINK_POLICY)
+#define HCI_Short_Range_Mode HCI_FORM_OPCODE(OCF_HCI_Short_Range_Mode, OGF_LINK_POLICY)
+
+
+/*===== Info Commands =====================*/
+#define HCI_Read_Local_Ver_Info HCI_FORM_OPCODE(OCF_HCI_Read_Local_Ver_Info, OGF_INFO_PARAMS)
+#define HCI_Read_Local_Supported_Cmds HCI_FORM_OPCODE(OCF_HCI_Read_Local_Supported_Cmds, OGF_INFO_PARAMS)
+#define HCI_Read_Data_Block_Size HCI_FORM_OPCODE(OCF_HCI_Read_Data_Block_Size, OGF_INFO_PARAMS)
+
+/*===== Status Commands =====================*/
+#define HCI_Read_Link_Quality HCI_FORM_OPCODE(OCF_HCI_Read_Link_Quality, OGF_STATUS)
+#define HCI_Read_RSSI HCI_FORM_OPCODE(OCF_HCI_Read_RSSI, OGF_STATUS)
+#define HCI_Read_Local_AMP_Info HCI_FORM_OPCODE(OCF_HCI_Read_Local_AMP_Info, OGF_STATUS)
+#define HCI_Read_Local_AMP_ASSOC HCI_FORM_OPCODE(OCF_HCI_Read_Local_AMP_ASSOC, OGF_STATUS)
+#define HCI_Write_Remote_AMP_ASSOC HCI_FORM_OPCODE(OCF_HCI_Write_Remote_AMP_ASSOC, OGF_STATUS)
+
+/*====== End of cmd definitions =============*/
+
+
+
+/*===== Timeouts(private - can't come from HCI)=================*/
+#define Conn_Accept_TO HCI_FORM_OPCODE(Timer_Conn_Accept_TO, OGF_VENDOR_DEBUG)
+#define Link_Supervision_TO HCI_FORM_OPCODE(Timer_Link_Supervision_TO, OGF_VENDOR_DEBUG)
+
+/*----- PAL Constants (Sec 6 of Doc)------------------------*/
+#define Max80211_PAL_PDU_Size 1492
+#define Max80211_AMP_ASSOC_Len 672
+#define MinGUserPrio 4
+#define MaxGUserPrio 7
+#define BEUserPrio0 0
+#define BEUserPrio1 3
+#define Max80211BeaconPeriod 2000 /* in millisec */
+#define ShortRangeModePowerMax 4 /* dBm */
+
+/*------ PAL Protocol Identifiers (Sec5.1) ------------------*/
+typedef enum {
+ ACL_DATA = 0x01,
+ ACTIVITY_REPORT,
+ SECURED_FRAMES,
+ LINK_SUPERVISION_REQ,
+ LINK_SUPERVISION_RESP,
+}PAL_PROTOCOL_IDENTIFIERS;
+
+#define HCI_CMD_HDR_SZ 3
+#define HCI_EVENT_HDR_SIZE 2
+#define MAX_EVT_PKT_SZ 255
+#define AMP_ASSOC_MAX_FRAG_SZ 248
+#define AMP_MAX_GUARANTEED_BW 20000
+
+#define DEFAULT_CONN_ACCPT_TO 5000
+#define DEFAULT_LL_ACCPT_TO 5000
+#define DEFAULT_LSTO 10000
+
+#define PACKET_BASED_FLOW_CONTROL_MODE 0x00
+#define DATA_BLK_BASED_FLOW_CONTROL_MODE 0x01
+
+#define SERVICE_TYPE_BEST_EFFORT 0x01
+#define SERVICE_TYPE_GUARANTEED 0x02
+
+#define MAC_ADDR_LEN 6
+#define LINK_KEY_LEN 32
+
+typedef enum {
+ ACL_DATA_PB_1ST_NON_AUTOMATICALLY_FLUSHABLE = 0x00,
+ ACL_DATA_PB_CONTINUING_FRAGMENT = 0x01,
+ ACL_DATA_PB_1ST_AUTOMATICALLY_FLUSHABLE = 0x02,
+ ACL_DATA_PB_COMPLETE_PDU = 0x03,
+} ACL_DATA_PB_FLAGS;
+#define ACL_DATA_PB_FLAGS_SHIFT 12
+
+typedef enum {
+ ACL_DATA_BC_POINT_TO_POINT = 0x00,
+} ACL_DATA_BC_FLAGS;
+#define ACL_DATA_BC_FLAGS_SHIFT 14
+
+/* Command pkt */
+typedef struct hci_cmd_pkt_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 params[255];
+} POSTPACK HCI_CMD_PKT;
+
+#define ACL_DATA_HDR_SIZE 4 /* hdl_and flags + data_len */
+/* Data pkt */
+typedef struct hci_acl_data_pkt_t {
+ A_UINT16 hdl_and_flags;
+ A_UINT16 data_len;
+ A_UINT8 data[Max80211_PAL_PDU_Size];
+} POSTPACK HCI_ACL_DATA_PKT;
+
+/* Event pkt */
+typedef struct hci_event_pkt_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 params[256];
+} POSTPACK HCI_EVENT_PKT;
+
+
+/*============== HCI Command definitions ======================= */
+typedef struct hci_cmd_phy_link_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ A_UINT8 link_key_len;
+ A_UINT8 link_key_type;
+ A_UINT8 link_key[LINK_KEY_LEN];
+} POSTPACK HCI_CMD_PHY_LINK;
+
+typedef struct hci_cmd_write_rem_amp_assoc_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ A_UINT16 len_so_far;
+ A_UINT16 amp_assoc_remaining_len;
+ A_UINT8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ];
+} POSTPACK HCI_CMD_WRITE_REM_AMP_ASSOC;
+
+
+typedef struct hci_cmd_opcode_hdl_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 hdl;
+} POSTPACK HCI_CMD_READ_LINK_QUAL,
+ HCI_CMD_FLUSH,
+ HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT;
+
+typedef struct hci_cmd_read_local_amp_assoc_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ A_UINT16 len_so_far;
+ A_UINT16 max_rem_amp_assoc_len;
+} POSTPACK HCI_CMD_READ_LOCAL_AMP_ASSOC;
+
+
+typedef struct hci_cmd_set_event_mask_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT64 mask;
+}POSTPACK HCI_CMD_SET_EVT_MASK, HCI_CMD_SET_EVT_MASK_PG_2;
+
+
+typedef struct hci_cmd_enhanced_flush_t{
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 hdl;
+ A_UINT8 type;
+} POSTPACK HCI_CMD_ENHANCED_FLUSH;
+
+
+typedef struct hci_cmd_write_timeout_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 timeout;
+} POSTPACK HCI_CMD_WRITE_TIMEOUT;
+
+typedef struct hci_cmd_write_link_supervision_timeout_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 hdl;
+ A_UINT16 timeout;
+} POSTPACK HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT;
+
+typedef struct hci_cmd_write_flow_control_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 mode;
+} POSTPACK HCI_CMD_WRITE_FLOW_CONTROL;
+
+typedef struct location_data_cfg_t {
+ A_UINT8 reg_domain_aware;
+ A_UINT8 reg_domain[3];
+ A_UINT8 reg_options;
+} POSTPACK LOCATION_DATA_CFG;
+
+typedef struct hci_cmd_write_location_data_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ LOCATION_DATA_CFG cfg;
+} POSTPACK HCI_CMD_WRITE_LOCATION_DATA;
+
+
+typedef struct flow_spec_t {
+ A_UINT8 id;
+ A_UINT8 service_type;
+ A_UINT16 max_sdu;
+ A_UINT32 sdu_inter_arrival_time;
+ A_UINT32 access_latency;
+ A_UINT32 flush_timeout;
+} POSTPACK FLOW_SPEC;
+
+
+typedef struct hci_cmd_create_logical_link_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ FLOW_SPEC tx_flow_spec;
+ FLOW_SPEC rx_flow_spec;
+} POSTPACK HCI_CMD_CREATE_LOGICAL_LINK;
+
+typedef struct hci_cmd_flow_spec_modify_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 hdl;
+ FLOW_SPEC tx_flow_spec;
+ FLOW_SPEC rx_flow_spec;
+} POSTPACK HCI_CMD_FLOW_SPEC_MODIFY;
+
+typedef struct hci_cmd_logical_link_cancel_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ A_UINT8 tx_flow_spec_id;
+} POSTPACK HCI_CMD_LOGICAL_LINK_CANCEL;
+
+typedef struct hci_cmd_disconnect_logical_link_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT16 logical_link_hdl;
+} POSTPACK HCI_CMD_DISCONNECT_LOGICAL_LINK;
+
+typedef struct hci_cmd_disconnect_phy_link_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+} POSTPACK HCI_CMD_DISCONNECT_PHY_LINK;
+
+typedef struct hci_cmd_srm_t {
+ A_UINT16 opcode;
+ A_UINT8 param_length;
+ A_UINT8 phy_link_hdl;
+ A_UINT8 mode;
+} POSTPACK HCI_CMD_SHORT_RANGE_MODE;
+/*============== HCI Command definitions end ======================= */
+
+
+
+/*============== HCI Event definitions ============================= */
+
+/* Command complete event */
+typedef struct hci_event_cmd_complete_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 num_hci_cmd_pkts;
+ A_UINT16 opcode;
+ A_UINT8 params[255];
+} POSTPACK HCI_EVENT_CMD_COMPLETE;
+
+
+/* Command status event */
+typedef struct hci_event_cmd_status_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT8 num_hci_cmd_pkts;
+ A_UINT16 opcode;
+} POSTPACK HCI_EVENT_CMD_STATUS;
+
+/* Hardware Error event */
+typedef struct hci_event_hw_err_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 hw_err_code;
+} POSTPACK HCI_EVENT_HW_ERR;
+
+/* Flush occured event */
+/* Qos Violation event */
+typedef struct hci_event_handle_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT16 handle;
+} POSTPACK HCI_EVENT_FLUSH_OCCRD,
+ HCI_EVENT_QOS_VIOLATION;
+
+/* Loopback command event */
+typedef struct hci_loopback_cmd_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 params[252];
+} POSTPACK HCI_EVENT_LOOPBACK_CMD;
+
+/* Data buffer overflow event */
+typedef struct hci_data_buf_overflow_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 link_type;
+} POSTPACK HCI_EVENT_DATA_BUF_OVERFLOW;
+
+/* Enhanced Flush complete event */
+typedef struct hci_enhanced_flush_complt_t{
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT16 hdl;
+} POSTPACK HCI_EVENT_ENHANCED_FLUSH_COMPLT;
+
+/* Channel select event */
+typedef struct hci_event_chan_select_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 phy_link_hdl;
+} POSTPACK HCI_EVENT_CHAN_SELECT;
+
+/* Physical Link Complete event */
+typedef struct hci_event_phy_link_complete_event_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT8 phy_link_hdl;
+} POSTPACK HCI_EVENT_PHY_LINK_COMPLETE;
+
+/* Logical Link complete event */
+typedef struct hci_event_logical_link_complete_event_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT16 logical_link_hdl;
+ A_UINT8 phy_hdl;
+ A_UINT8 tx_flow_id;
+} POSTPACK HCI_EVENT_LOGICAL_LINK_COMPLETE_EVENT;
+
+/* Disconnect Logical Link complete event */
+typedef struct hci_event_disconnect_logical_link_event_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT16 logical_link_hdl;
+ A_UINT8 reason;
+} POSTPACK HCI_EVENT_DISCONNECT_LOGICAL_LINK_EVENT;
+
+/* Disconnect Physical Link complete event */
+typedef struct hci_event_disconnect_phy_link_complete_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT8 phy_link_hdl;
+ A_UINT8 reason;
+} POSTPACK HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE;
+
+typedef struct hci_event_physical_link_loss_early_warning_t{
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 phy_hdl;
+ A_UINT8 reason;
+} POSTPACK HCI_EVENT_PHY_LINK_LOSS_EARLY_WARNING;
+
+typedef struct hci_event_physical_link_recovery_t{
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 phy_hdl;
+} POSTPACK HCI_EVENT_PHY_LINK_RECOVERY;
+
+
+/* Flow spec modify complete event */
+/* Flush event */
+typedef struct hci_event_status_handle_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT16 handle;
+} POSTPACK HCI_EVENT_FLOW_SPEC_MODIFY,
+ HCI_EVENT_FLUSH;
+
+
+/* Num of completed data blocks event */
+typedef struct hci_event_num_of_compl_data_blks_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT16 num_data_blks;
+ A_UINT8 num_handles;
+ A_UINT8 params[255];
+} POSTPACK HCI_EVENT_NUM_COMPL_DATA_BLKS;
+
+/* Short range mode change complete event */
+typedef struct hci_srm_cmpl_t {
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT8 phy_link;
+ A_UINT8 state;
+} POSTPACK HCI_EVENT_SRM_COMPL;
+
+typedef struct hci_event_amp_status_change_t{
+ A_UINT8 event_code;
+ A_UINT8 param_len;
+ A_UINT8 status;
+ A_UINT8 amp_status;
+} POSTPACK HCI_EVENT_AMP_STATUS_CHANGE;
+
+/*============== Event definitions end =========================== */
+
+
+typedef struct local_amp_info_resp_t {
+ A_UINT8 status;
+ A_UINT8 amp_status;
+ A_UINT32 total_bw; /* kbps */
+ A_UINT32 max_guranteed_bw; /* kbps */
+ A_UINT32 min_latency;
+ A_UINT32 max_pdu_size;
+ A_UINT8 amp_type;
+ A_UINT16 pal_capabilities;
+ A_UINT16 amp_assoc_len;
+ A_UINT32 max_flush_timeout; /* in ms */
+ A_UINT32 be_flush_timeout; /* in ms */
+} POSTPACK LOCAL_AMP_INFO;
+
+typedef struct amp_assoc_cmd_resp_t{
+ A_UINT8 status;
+ A_UINT8 phy_hdl;
+ A_UINT16 amp_assoc_len;
+ A_UINT8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ];
+}POSTPACK AMP_ASSOC_CMD_RESP;
+
+
+enum PAL_HCI_CMD_STATUS {
+ PAL_HCI_CMD_PROCESSED,
+ PAL_HCI_CMD_IGNORED
+};
+
+
+/*============= HCI Error Codes =======================*/
+#define HCI_SUCCESS 0x00
+#define HCI_ERR_UNKNOW_CMD 0x01
+#define HCI_ERR_UNKNOWN_CONN_ID 0x02
+#define HCI_ERR_HW_FAILURE 0x03
+#define HCI_ERR_PAGE_TIMEOUT 0x04
+#define HCI_ERR_AUTH_FAILURE 0x05
+#define HCI_ERR_KEY_MISSING 0x06
+#define HCI_ERR_MEM_CAP_EXECED 0x07
+#define HCI_ERR_CON_TIMEOUT 0x08
+#define HCI_ERR_CON_LIMIT_EXECED 0x09
+#define HCI_ERR_ACL_CONN_ALRDY_EXISTS 0x0B
+#define HCI_ERR_COMMAND_DISALLOWED 0x0C
+#define HCI_ERR_CONN_REJ_BY_LIMIT_RES 0x0D
+#define HCI_ERR_CONN_REJ_BY_SEC 0x0E
+#define HCI_ERR_CONN_REJ_BY_BAD_ADDR 0x0F
+#define HCI_ERR_CONN_ACCPT_TIMEOUT 0x10
+#define HCI_ERR_UNSUPPORT_FEATURE 0x11
+#define HCI_ERR_INVALID_HCI_CMD_PARAMS 0x12
+#define HCI_ERR_REMOTE_USER_TERMINATE_CONN 0x13
+#define HCI_ERR_CON_TERM_BY_HOST 0x16
+#define HCI_ERR_UNSPECIFIED_ERROR 0x1F
+#define HCI_ERR_ENCRYPTION_MODE_NOT_SUPPORT 0x25
+#define HCI_ERR_REQUESTED_QOS_NOT_SUPPORT 0x27
+#define HCI_ERR_QOS_UNACCEPTABLE_PARM 0x2C
+#define HCI_ERR_QOS_REJECTED 0x2D
+#define HCI_ERR_CONN_REJ_NO_SUITABLE_CHAN 0x39
+
+/*============= HCI Error Codes End =======================*/
+
+
+/* Following are event return parameters.. part of HCI events
+ */
+typedef struct timeout_read_t {
+ A_UINT8 status;
+ A_UINT16 timeout;
+}POSTPACK TIMEOUT_INFO;
+
+typedef struct link_supervision_timeout_read_t {
+ A_UINT8 status;
+ A_UINT16 hdl;
+ A_UINT16 timeout;
+}POSTPACK LINK_SUPERVISION_TIMEOUT_INFO;
+
+typedef struct status_hdl_t {
+ A_UINT8 status;
+ A_UINT16 hdl;
+}POSTPACK INFO_STATUS_HDL;
+
+typedef struct write_remote_amp_assoc_t{
+ A_UINT8 status;
+ A_UINT8 hdl;
+}POSTPACK WRITE_REMOTE_AMP_ASSOC_INFO;
+
+typedef struct read_loc_info_t {
+ A_UINT8 status;
+ LOCATION_DATA_CFG loc;
+}POSTPACK READ_LOC_INFO;
+
+typedef struct read_flow_ctrl_mode_t {
+ A_UINT8 status;
+ A_UINT8 mode;
+}POSTPACK READ_FLWCTRL_INFO;
+
+typedef struct read_data_blk_size_t {
+ A_UINT8 status;
+ A_UINT16 max_acl_data_pkt_len;
+ A_UINT16 data_block_len;
+ A_UINT16 total_num_data_blks;
+}POSTPACK READ_DATA_BLK_SIZE_INFO;
+
+/* Read Link quality info */
+typedef struct link_qual_t {
+ A_UINT8 status;
+ A_UINT16 hdl;
+ A_UINT8 link_qual;
+} POSTPACK READ_LINK_QUAL_INFO,
+ READ_RSSI_INFO;
+
+typedef struct ll_cancel_resp_t {
+ A_UINT8 status;
+ A_UINT8 phy_link_hdl;
+ A_UINT8 tx_flow_spec_id;
+} POSTPACK LL_CANCEL_RESP;
+
+typedef struct read_local_ver_info_t {
+ A_UINT8 status;
+ A_UINT8 hci_version;
+ A_UINT16 hci_revision;
+ A_UINT8 pal_version;
+ A_UINT16 manf_name;
+ A_UINT16 pal_sub_ver;
+} POSTPACK READ_LOCAL_VER_INFO;
+
+
+#endif /* __A_HCI_H__ */
diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h
new file mode 100644
index 000000000000..b59bfd3af0a5
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/athdefs.h
@@ -0,0 +1,84 @@
+//------------------------------------------------------------------------------
+// <copyright file="athdefs.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef __ATHDEFS_H__
+#define __ATHDEFS_H__
+
+/*
+ * This file contains definitions that may be used across both
+ * Host and Target software. Nothing here is module-dependent
+ * or platform-dependent.
+ */
+
+/*
+ * Generic error codes that can be used by hw, sta, ap, sim, dk
+ * and any other environments. Since these are enums, feel free to
+ * add any more codes that you need.
+ */
+
+typedef enum {
+ A_ERROR = -1, /* Generic error return */
+ A_OK = 0, /* success */
+ /* Following values start at 1 */
+ A_DEVICE_NOT_FOUND, /* not able to find PCI device */
+ A_NO_MEMORY, /* not able to allocate memory, not available */
+ A_MEMORY_NOT_AVAIL, /* memory region is not free for mapping */
+ A_NO_FREE_DESC, /* no free descriptors available */
+ A_BAD_ADDRESS, /* address does not match descriptor */
+ A_WIN_DRIVER_ERROR, /* used in NT_HW version, if problem at init */
+ A_REGS_NOT_MAPPED, /* registers not correctly mapped */
+ A_EPERM, /* Not superuser */
+ A_EACCES, /* Access denied */
+ A_ENOENT, /* No such entry, search failed, etc. */
+ A_EEXIST, /* The object already exists (can't create) */
+ A_EFAULT, /* Bad address fault */
+ A_EBUSY, /* Object is busy */
+ A_EINVAL, /* Invalid parameter */
+ A_EMSGSIZE, /* Inappropriate message buffer length */
+ A_ECANCELED, /* Operation canceled */
+ A_ENOTSUP, /* Operation not supported */
+ A_ECOMM, /* Communication error on send */
+ A_EPROTO, /* Protocol error */
+ A_ENODEV, /* No such device */
+ A_EDEVNOTUP, /* device is not UP */
+ A_NO_RESOURCE, /* No resources for requested operation */
+ A_HARDWARE, /* Hardware failure */
+ A_PENDING, /* Asynchronous routine; will send up results la
+ter (typically in callback) */
+ A_EBADCHANNEL, /* The channel cannot be used */
+ A_DECRYPT_ERROR, /* Decryption error */
+ A_PHY_ERROR, /* RX PHY error */
+ A_CONSUMED /* Object was consumed */
+} A_STATUS;
+
+#define A_SUCCESS(x) (x == A_OK)
+#define A_FAILED(x) (!A_SUCCESS(x))
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif /* __ATHDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h
new file mode 100644
index 000000000000..f9687d325b2f
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/bmi_msg.h
@@ -0,0 +1,241 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef __BMI_MSG_H__
+#define __BMI_MSG_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+/*
+ * Bootloader Messaging Interface (BMI)
+ *
+ * BMI is a very simple messaging interface used during initialization
+ * to read memory, write memory, execute code, and to define an
+ * application entry PC.
+ *
+ * It is used to download an application to AR6K, to provide
+ * patches to code that is already resident on AR6K, and generally
+ * to examine and modify state. The Host has an opportunity to use
+ * BMI only once during bootup. Once the Host issues a BMI_DONE
+ * command, this opportunity ends.
+ *
+ * The Host writes BMI requests to mailbox0, and reads BMI responses
+ * from mailbox0. BMI requests all begin with a command
+ * (see below for specific commands), and are followed by
+ * command-specific data.
+ *
+ * Flow control:
+ * The Host can only issue a command once the Target gives it a
+ * "BMI Command Credit", using AR6K Counter #4. As soon as the
+ * Target has completed a command, it issues another BMI Command
+ * Credit (so the Host can issue the next command).
+ *
+ * BMI handles all required Target-side cache flushing.
+ */
+
+
+/* Maximum data size used for BMI transfers */
+#define BMI_DATASZ_MAX 256
+
+/* BMI Commands */
+
+#define BMI_NO_COMMAND 0
+
+#define BMI_DONE 1
+ /*
+ * Semantics: Host is done using BMI
+ * Request format:
+ * A_UINT32 command (BMI_DONE)
+ * Response format: none
+ */
+
+#define BMI_READ_MEMORY 2
+ /*
+ * Semantics: Host reads AR6K memory
+ * Request format:
+ * A_UINT32 command (BMI_READ_MEMORY)
+ * A_UINT32 address
+ * A_UINT32 length, at most BMI_DATASZ_MAX
+ * Response format:
+ * A_UINT8 data[length]
+ */
+
+#define BMI_WRITE_MEMORY 3
+ /*
+ * Semantics: Host writes AR6K memory
+ * Request format:
+ * A_UINT32 command (BMI_WRITE_MEMORY)
+ * A_UINT32 address
+ * A_UINT32 length, at most BMI_DATASZ_MAX
+ * A_UINT8 data[length]
+ * Response format: none
+ */
+
+#define BMI_EXECUTE 4
+ /*
+ * Semantics: Causes AR6K to execute code
+ * Request format:
+ * A_UINT32 command (BMI_EXECUTE)
+ * A_UINT32 address
+ * A_UINT32 parameter
+ * Response format:
+ * A_UINT32 return value
+ */
+
+#define BMI_SET_APP_START 5
+ /*
+ * Semantics: Set Target application starting address
+ * Request format:
+ * A_UINT32 command (BMI_SET_APP_START)
+ * A_UINT32 address
+ * Response format: none
+ */
+
+#define BMI_READ_SOC_REGISTER 6
+ /*
+ * Semantics: Read a 32-bit Target SOC register.
+ * Request format:
+ * A_UINT32 command (BMI_READ_REGISTER)
+ * A_UINT32 address
+ * Response format:
+ * A_UINT32 value
+ */
+
+#define BMI_WRITE_SOC_REGISTER 7
+ /*
+ * Semantics: Write a 32-bit Target SOC register.
+ * Request format:
+ * A_UINT32 command (BMI_WRITE_REGISTER)
+ * A_UINT32 address
+ * A_UINT32 value
+ *
+ * Response format: none
+ */
+
+#define BMI_GET_TARGET_ID 8
+#define BMI_GET_TARGET_INFO 8
+ /*
+ * Semantics: Fetch the 4-byte Target information
+ * Request format:
+ * A_UINT32 command (BMI_GET_TARGET_ID/INFO)
+ * Response format1 (old firmware):
+ * A_UINT32 TargetVersionID
+ * Response format2 (newer firmware):
+ * A_UINT32 TARGET_VERSION_SENTINAL
+ * struct bmi_target_info;
+ */
+
+PREPACK struct bmi_target_info {
+ A_UINT32 target_info_byte_count; /* size of this structure */
+ A_UINT32 target_ver; /* Target Version ID */
+ A_UINT32 target_type; /* Target type */
+} POSTPACK;
+#define TARGET_VERSION_SENTINAL 0xffffffff
+#define TARGET_TYPE_AR6001 1
+#define TARGET_TYPE_AR6002 2
+#define TARGET_TYPE_AR6003 3
+
+
+#define BMI_ROMPATCH_INSTALL 9
+ /*
+ * Semantics: Install a ROM Patch.
+ * Request format:
+ * A_UINT32 command (BMI_ROMPATCH_INSTALL)
+ * A_UINT32 Target ROM Address
+ * A_UINT32 Target RAM Address or Value (depending on Target Type)
+ * A_UINT32 Size, in bytes
+ * A_UINT32 Activate? 1-->activate;
+ * 0-->install but do not activate
+ * Response format:
+ * A_UINT32 PatchID
+ */
+
+#define BMI_ROMPATCH_UNINSTALL 10
+ /*
+ * Semantics: Uninstall a previously-installed ROM Patch,
+ * automatically deactivating, if necessary.
+ * Request format:
+ * A_UINT32 command (BMI_ROMPATCH_UNINSTALL)
+ * A_UINT32 PatchID
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_ACTIVATE 11
+ /*
+ * Semantics: Activate a list of previously-installed ROM Patches.
+ * Request format:
+ * A_UINT32 command (BMI_ROMPATCH_ACTIVATE)
+ * A_UINT32 rompatch_count
+ * A_UINT32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_DEACTIVATE 12
+ /*
+ * Semantics: Deactivate a list of active ROM Patches.
+ * Request format:
+ * A_UINT32 command (BMI_ROMPATCH_DEACTIVATE)
+ * A_UINT32 rompatch_count
+ * A_UINT32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+
+#define BMI_LZ_STREAM_START 13
+ /*
+ * Semantics: Begin an LZ-compressed stream of input
+ * which is to be uncompressed by the Target to an
+ * output buffer at address. The output buffer must
+ * be sufficiently large to hold the uncompressed
+ * output from the compressed input stream. This BMI
+ * command should be followed by a series of 1 or more
+ * BMI_LZ_DATA commands.
+ * A_UINT32 command (BMI_LZ_STREAM_START)
+ * A_UINT32 address
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#define BMI_LZ_DATA 14
+ /*
+ * Semantics: Host writes AR6K memory with LZ-compressed
+ * data which is uncompressed by the Target. This command
+ * must be preceded by a BMI_LZ_STREAM_START command. A series
+ * of BMI_LZ_DATA commands are considered part of a single
+ * input stream until another BMI_LZ_STREAM_START is issued.
+ * Request format:
+ * A_UINT32 command (BMI_LZ_DATA)
+ * A_UINT32 length (of compressed data),
+ * at most BMI_DATASZ_MAX
+ * A_UINT8 CompressedData[length]
+ * Response format: none
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __BMI_MSG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/btcoexGpio.h b/drivers/staging/ath6kl/include/common/btcoexGpio.h
new file mode 100644
index 000000000000..bc067f557eaa
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/btcoexGpio.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+// 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 BTCOEX_GPIO_H_
+#define BTCOEX_GPIO_H_
+
+
+
+#ifdef FPGA
+#define GPIO_A (15)
+#define GPIO_B (16)
+#define GPIO_C (17)
+#define GPIO_D (18)
+#define GPIO_E (19)
+#define GPIO_F (21)
+#define GPIO_G (21)
+#else
+#define GPIO_A (0)
+#define GPIO_B (5)
+#define GPIO_C (6)
+#define GPIO_D (7)
+#define GPIO_E (7)
+#define GPIO_F (7)
+#define GPIO_G (7)
+#endif
+
+
+
+
+
+#define GPIO_DEBUG_WORD_1 (1<<GPIO_A)
+#define GPIO_DEBUG_WORD_2 (1<<GPIO_B)
+#define GPIO_DEBUG_WORD_3 ((1<<GPIO_B) | (1<<GPIO_A))
+#define GPIO_DEBUG_WORD_4 (1<<GPIO_C)
+#define GPIO_DEBUG_WORD_5 ((1<<GPIO_C) | (1<<GPIO_A))
+#define GPIO_DEBUG_WORD_6 ((1<<GPIO_C) | (1<<GPIO_B))
+#define GPIO_DEBUG_WORD_7 ((1<<GPIO_C) | (1<<GPIO_B) | (1<<GPIO_A))
+
+#define GPIO_DEBUG_WORD_8 (1<<GPIO_D)
+#define GPIO_DEBUG_WORD_9 ((1<<GPIO_D) | GPIO_DEBUG_WORD_1)
+#define GPIO_DEBUG_WORD_10 ((1<<GPIO_D) | GPIO_DEBUG_WORD_2)
+#define GPIO_DEBUG_WORD_11 ((1<<GPIO_D) | GPIO_DEBUG_WORD_3)
+#define GPIO_DEBUG_WORD_12 ((1<<GPIO_D) | GPIO_DEBUG_WORD_4)
+#define GPIO_DEBUG_WORD_13 ((1<<GPIO_D) | GPIO_DEBUG_WORD_5)
+#define GPIO_DEBUG_WORD_14 ((1<<GPIO_D) | GPIO_DEBUG_WORD_6)
+#define GPIO_DEBUG_WORD_15 ((1<<GPIO_D) | GPIO_DEBUG_WORD_7)
+
+#define GPIO_DEBUG_WORD_16 (1<<GPIO_E)
+#define GPIO_DEBUG_WORD_17 ((1<<GPIO_E) | GPIO_DEBUG_WORD_1)
+#define GPIO_DEBUG_WORD_18 ((1<<GPIO_E) | GPIO_DEBUG_WORD_2)
+#define GPIO_DEBUG_WORD_19 ((1<<GPIO_E) | GPIO_DEBUG_WORD_3)
+#define GPIO_DEBUG_WORD_20 ((1<<GPIO_E) | GPIO_DEBUG_WORD_4)
+#define GPIO_DEBUG_WORD_21 ((1<<GPIO_E) | GPIO_DEBUG_WORD_5)
+#define GPIO_DEBUG_WORD_22 ((1<<GPIO_E) | GPIO_DEBUG_WORD_6)
+#define GPIO_DEBUG_WORD_23 ((1<<GPIO_E) | GPIO_DEBUG_WORD_7)
+
+
+
+extern void btcoexDbgPulseWord(A_UINT32 gpioPinMask);
+extern void btcoexDbgPulse(A_UINT32 pin);
+
+#ifdef CONFIG_BTCOEX_ENABLE_GPIO_DEBUG
+#define BTCOEX_DBG_PULSE_WORD(gpioPinMask) (btcoexDbgPulseWord(gpioPinMask))
+#define BTCOEX_DBG_PULSE(pin) (btcoexDbgPulse(pin))
+#else
+#define BTCOEX_DBG_PULSE_WORD(gpioPinMask)
+#define BTCOEX_DBG_PULSE(pin)
+
+#endif
+#endif
+
diff --git a/drivers/staging/ath6kl/include/common/cnxmgmt.h b/drivers/staging/ath6kl/include/common/cnxmgmt.h
new file mode 100644
index 000000000000..7a902cb54831
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/cnxmgmt.h
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+// <copyright file="cnxmgmt.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _CNXMGMT_H_
+#define _CNXMGMT_H_
+
+typedef enum {
+ CM_CONNECT_WITHOUT_SCAN = 0x0001,
+ CM_CONNECT_ASSOC_POLICY_USER = 0x0002,
+ CM_CONNECT_SEND_REASSOC = 0x0004,
+ CM_CONNECT_WITHOUT_ROAMTABLE_UPDATE = 0x0008,
+ CM_CONNECT_DO_WPA_OFFLOAD = 0x0010,
+ CM_CONNECT_DO_NOT_DEAUTH = 0x0020,
+} CM_CONNECT_TYPE;
+
+#endif /* _CNXMGMT_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h
new file mode 100644
index 000000000000..382d9a2dd4eb
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dbglog.h
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+// <copyright file="dbglog.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _DBGLOG_H_
+#define _DBGLOG_H_
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DBGLOG_TIMESTAMP_OFFSET 0
+#define DBGLOG_TIMESTAMP_MASK 0x0000FFFF /* Bit 0-15. Contains bit
+ 8-23 of the LF0 timer */
+#define DBGLOG_DBGID_OFFSET 16
+#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */
+#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */
+
+#define DBGLOG_MODULEID_OFFSET 26
+#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */
+#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */
+
+/*
+ * Please ensure that the definition of any new module intrduced is captured
+ * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The
+ * structure is required for the parser to correctly pick up the values for
+ * different modules.
+ */
+#define DBGLOG_MODULEID_START
+#define DBGLOG_MODULEID_INF 0
+#define DBGLOG_MODULEID_WMI 1
+#define DBGLOG_MODULEID_MISC 2
+#define DBGLOG_MODULEID_PM 3
+#define DBGLOG_MODULEID_TXRX_MGMTBUF 4
+#define DBGLOG_MODULEID_TXRX_TXBUF 5
+#define DBGLOG_MODULEID_TXRX_RXBUF 6
+#define DBGLOG_MODULEID_WOW 7
+#define DBGLOG_MODULEID_WHAL 8
+#define DBGLOG_MODULEID_DC 9
+#define DBGLOG_MODULEID_CO 10
+#define DBGLOG_MODULEID_RO 11
+#define DBGLOG_MODULEID_CM 12
+#define DBGLOG_MODULEID_MGMT 13
+#define DBGLOG_MODULEID_TMR 14
+#define DBGLOG_MODULEID_BTCOEX 15
+#define DBGLOG_MODULEID_END
+
+#define DBGLOG_NUM_ARGS_OFFSET 30
+#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */
+#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */
+
+#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0
+#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF
+
+#define DBGLOG_REPORTING_ENABLED_OFFSET 16
+#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000
+
+#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17
+#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000
+
+#define DBGLOG_REPORT_SIZE_OFFSET 20
+#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000
+
+#define DBGLOG_LOG_BUFFER_SIZE 1500
+#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90
+
+PREPACK struct dbglog_buf_s {
+ struct dbglog_buf_s *next;
+ A_UINT8 *buffer;
+ A_UINT32 bufsize;
+ A_UINT32 length;
+ A_UINT32 count;
+ A_UINT32 free;
+} POSTPACK;
+
+PREPACK struct dbglog_hdr_s {
+ struct dbglog_buf_s *dbuf;
+ A_UINT32 dropped;
+} POSTPACK;
+
+PREPACK struct dbglog_config_s {
+ A_UINT32 cfgvalid; /* Mask with valid config bits */
+ union {
+ /* TODO: Take care of endianness */
+ struct {
+ A_UINT32 mmask:16; /* Mask of modules with logging on */
+ A_UINT32 rep:1; /* Reporting enabled or not */
+ A_UINT32 tsr:3; /* Time stamp resolution. Def: 1 ms */
+ A_UINT32 size:10; /* Report size in number of messages */
+ A_UINT32 reserved:2;
+ } dbglog_config;
+
+ A_UINT32 value;
+ } u;
+} POSTPACK;
+
+#define cfgmmask u.dbglog_config.mmask
+#define cfgrep u.dbglog_config.rep
+#define cfgtsr u.dbglog_config.tsr
+#define cfgsize u.dbglog_config.size
+#define cfgvalue u.value
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* _DBGLOG_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dbglog_id.h b/drivers/staging/ath6kl/include/common/dbglog_id.h
new file mode 100644
index 000000000000..15ef829cab20
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dbglog_id.h
@@ -0,0 +1,558 @@
+//------------------------------------------------------------------------------
+// <copyright file="dbglog_id.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _DBGLOG_ID_H_
+#define _DBGLOG_ID_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The nomenclature for the debug identifiers is MODULE_DESCRIPTION.
+ * Please ensure that the definition of any new debugid introduced is captured
+ * between the <MODULE>_DBGID_DEFINITION_START and
+ * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the
+ * parser to correctly pick up the values for different debug identifiers.
+ */
+
+/* INF debug identifier definitions */
+#define INF_DBGID_DEFINITION_START
+#define INF_ASSERTION_FAILED 1
+#define INF_TARGET_ID 2
+#define INF_DBGID_DEFINITION_END
+
+/* WMI debug identifier definitions */
+#define WMI_DBGID_DEFINITION_START
+#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1
+#define WMI_EXTENDED_CMD_NOT_HANDLED 2
+#define WMI_CMD_RX_PKT_TOO_SHORT 3
+#define WMI_CALLING_WMI_EXTENSION_FN 4
+#define WMI_CMD_NOT_HANDLED 5
+#define WMI_IN_SYNC 6
+#define WMI_TARGET_WMI_SYNC_CMD 7
+#define WMI_SET_SNR_THRESHOLD_PARAMS 8
+#define WMI_SET_RSSI_THRESHOLD_PARAMS 9
+#define WMI_SET_LQ_TRESHOLD_PARAMS 10
+#define WMI_TARGET_CREATE_PSTREAM_CMD 11
+#define WMI_WI_DTM_INUSE 12
+#define WMI_TARGET_DELETE_PSTREAM_CMD 13
+#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14
+#define WMI_TARGET_GET_BIT_RATE_CMD 15
+#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16
+#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17
+#define WMI_TARGET_GET_TX_PWR_CMD 18
+#define WMI_FREE_EVBUF_WMIBUF 19
+#define WMI_FREE_EVBUF_DATABUF 20
+#define WMI_FREE_EVBUF_BADFLAG 21
+#define WMI_HTC_RX_ERROR_DATA_PACKET 22
+#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23
+#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24
+#define WMI_SENDING_READY_EVENT 25
+#define WMI_SETPOWER_MDOE_TO_MAXPERF 26
+#define WMI_SETPOWER_MDOE_TO_REC 27
+#define WMI_BSSINFO_EVENT_FROM 28
+#define WMI_TARGET_GET_STATS_CMD 29
+#define WMI_SENDING_SCAN_COMPLETE_EVENT 30
+#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31
+#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32
+#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33
+#define WMI_SENDING_ERROR_REPORT_EVENT 34
+#define WMI_SENDING_CAC_EVENT 35
+#define WMI_TARGET_GET_ROAM_TABLE_CMD 36
+#define WMI_TARGET_GET_ROAM_DATA_CMD 37
+#define WMI_SENDING_GPIO_INTR_EVENT 38
+#define WMI_SENDING_GPIO_ACK_EVENT 39
+#define WMI_SENDING_GPIO_DATA_EVENT 40
+#define WMI_CMD_RX 41
+#define WMI_CMD_RX_XTND 42
+#define WMI_EVENT_SEND 43
+#define WMI_EVENT_SEND_XTND 44
+#define WMI_CMD_PARAMS_DUMP_START 45
+#define WMI_CMD_PARAMS_DUMP_END 46
+#define WMI_CMD_PARAMS 47
+#define WMI_DBGID_DEFINITION_END
+
+/* MISC debug identifier definitions */
+#define MISC_DBGID_DEFINITION_START
+#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR 1
+#define TLPM_INIT 2
+#define TLPM_FILTER_POWER_STATE 3
+#define TLPM_NOTIFY_NOT_IDLE 4
+#define TLPM_TIMEOUT_IDLE_HANDLER 5
+#define TLPM_TIMEOUT_WAKEUP_HANDLER 6
+#define TLPM_WAKEUP_SIGNAL_HANDLER 7
+#define TLPM_UNEXPECTED_GPIO_INTR_ERROR 8
+#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR 9
+#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR 10
+#define TLPM_ACK_GPIO_INTR 11
+#define TLPM_ON 12
+#define TLPM_OFF 13
+#define TLPM_WAKEUP_FROM_HOST 14
+#define TLPM_WAKEUP_FROM_BT 15
+#define TLPM_TX_BREAK_RECIVED 16
+#define TLPM_IDLE_TIMER_NOT_RUNNING 17
+#define MISC_DBGID_DEFINITION_END
+
+/* TXRX debug identifier definitions */
+#define TXRX_TXBUF_DBGID_DEFINITION_START
+#define TXRX_TXBUF_ALLOCATE_BUF 1
+#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2
+#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3
+#define TXRX_TXBUF_TXQ_DEPTH 4
+#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5
+#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6
+#define TXRX_TXBUF_INITIALIZE_TIMER 7
+#define TXRX_TXBUF_ARM_TIMER 8
+#define TXRX_TXBUF_DISARM_TIMER 9
+#define TXRX_TXBUF_UNINITIALIZE_TIMER 10
+#define TXRX_TXBUF_DBGID_DEFINITION_END
+
+#define TXRX_RXBUF_DBGID_DEFINITION_START
+#define TXRX_RXBUF_ALLOCATE_BUF 1
+#define TXRX_RXBUF_QUEUE_TO_HOST 2
+#define TXRX_RXBUF_QUEUE_TO_WLAN 3
+#define TXRX_RXBUF_ZERO_LEN_BUF 4
+#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5
+#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6
+#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7
+#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8
+#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9
+#define TXRX_RXBUF_REQUEUE_ERROR 10
+#define TXRX_RXBUF_DBGID_DEFINITION_END
+
+#define TXRX_MGMTBUF_DBGID_DEFINITION_START
+#define TXRX_MGMTBUF_ALLOCATE_BUF 1
+#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2
+#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3
+#define TXRX_MGMTBUF_GET_BUF 4
+#define TXRX_MGMTBUF_GET_SM_BUF 5
+#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6
+#define TXRX_MGMTBUF_REAPED_BUF 7
+#define TXRX_MGMTBUF_REAPED_SM_BUF 8
+#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9
+#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10
+#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ 11
+#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ 12
+#define TXRX_MGMTBUF_PAUSE_DATA_TXQ 13
+#define TXRX_MGMTBUF_RESUME_DATA_TXQ 14
+#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15
+#define TXRX_MGMTBUF_DRAINQ 16
+#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17
+#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ 18
+#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ 19
+#define TXRX_MGMTBUF_PAUSE_HW_TXQ 20
+#define TXRX_MGMTBUF_RESUME_HW_TXQ 21
+#define TXRX_MGMTBUF_TEAR_DOWN_BA 22
+#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ 23
+#define TXRX_MGMTBUF_PROCESS_DELBA 24
+#define TXRX_MGMTBUF_PERFORM_BA 25
+#define TXRX_MGMTBUF_WLAN_RESET_ON_ERROR 26
+#define TXRX_MGMTBUF_DBGID_DEFINITION_END
+
+/* PM (Power Module) debug identifier definitions */
+#define PM_DBGID_DEFINITION_START
+#define PM_INIT 1
+#define PM_ENABLE 2
+#define PM_SET_STATE 3
+#define PM_SET_POWERMODE 4
+#define PM_CONN_NOTIFY 5
+#define PM_REF_COUNT_NEGATIVE 6
+#define PM_INFRA_STA_APSD_ENABLE 7
+#define PM_INFRA_STA_UPDATE_APSD_STATE 8
+#define PM_CHAN_OP_REQ 9
+#define PM_SET_MY_BEACON_POLICY 10
+#define PM_SET_ALL_BEACON_POLICY 11
+#define PM_INFRA_STA_SET_PM_PARAMS1 12
+#define PM_INFRA_STA_SET_PM_PARAMS2 13
+#define PM_ADHOC_SET_PM_CAPS_FAIL 14
+#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15
+#define PM_ADHOC_SET_PM_PARAMS 16
+#define PM_ADHOC_STATE1 18
+#define PM_ADHOC_STATE2 19
+#define PM_ADHOC_CONN_MAP 20
+#define PM_FAKE_SLEEP 21
+#define PM_AP_STATE1 22
+#define PM_AP_SET_PM_PARAMS 23
+#define PM_DBGID_DEFINITION_END
+
+/* Wake on Wireless debug identifier definitions */
+#define WOW_DBGID_DEFINITION_START
+#define WOW_INIT 1
+#define WOW_GET_CONFIG_DSET 2
+#define WOW_NO_CONFIG_DSET 3
+#define WOW_INVALID_CONFIG_DSET 4
+#define WOW_USE_DEFAULT_CONFIG 5
+#define WOW_SETUP_GPIO 6
+#define WOW_INIT_DONE 7
+#define WOW_SET_GPIO_PIN 8
+#define WOW_CLEAR_GPIO_PIN 9
+#define WOW_SET_WOW_MODE_CMD 10
+#define WOW_SET_HOST_MODE_CMD 11
+#define WOW_ADD_WOW_PATTERN_CMD 12
+#define WOW_NEW_WOW_PATTERN_AT_INDEX 13
+#define WOW_DEL_WOW_PATTERN_CMD 14
+#define WOW_LIST_CONTAINS_PATTERNS 15
+#define WOW_GET_WOW_LIST_CMD 16
+#define WOW_INVALID_FILTER_ID 17
+#define WOW_INVALID_FILTER_LISTID 18
+#define WOW_NO_VALID_FILTER_AT_ID 19
+#define WOW_NO_VALID_LIST_AT_ID 20
+#define WOW_NUM_PATTERNS_EXCEEDED 21
+#define WOW_NUM_LISTS_EXCEEDED 22
+#define WOW_GET_WOW_STATS 23
+#define WOW_CLEAR_WOW_STATS 24
+#define WOW_WAKEUP_HOST 25
+#define WOW_EVENT_WAKEUP_HOST 26
+#define WOW_EVENT_DISCARD 27
+#define WOW_PATTERN_MATCH 28
+#define WOW_PATTERN_NOT_MATCH 29
+#define WOW_PATTERN_NOT_MATCH_OFFSET 30
+#define WOW_DISABLED_HOST_ASLEEP 31
+#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32
+#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33
+#define WOW_DBGID_DEFINITION_END
+
+/* WHAL debug identifier definitions */
+#define WHAL_DBGID_DEFINITION_START
+#define WHAL_ERROR_ANI_CONTROL 1
+#define WHAL_ERROR_CHIP_TEST1 2
+#define WHAL_ERROR_CHIP_TEST2 3
+#define WHAL_ERROR_EEPROM_CHECKSUM 4
+#define WHAL_ERROR_EEPROM_MACADDR 5
+#define WHAL_ERROR_INTERRUPT_HIU 6
+#define WHAL_ERROR_KEYCACHE_RESET 7
+#define WHAL_ERROR_KEYCACHE_SET 8
+#define WHAL_ERROR_KEYCACHE_TYPE 9
+#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10
+#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11
+#define WHAL_ERROR_PHY_INVALID_CHANNEL 12
+#define WHAL_ERROR_POWER_AWAKE 13
+#define WHAL_ERROR_POWER_SET 14
+#define WHAL_ERROR_RECV_STOPDMA 15
+#define WHAL_ERROR_RECV_STOPPCU 16
+#define WHAL_ERROR_RESET_CHANNF1 17
+#define WHAL_ERROR_RESET_CHANNF2 18
+#define WHAL_ERROR_RESET_PM 19
+#define WHAL_ERROR_RESET_OFFSETCAL 20
+#define WHAL_ERROR_RESET_RFGRANT 21
+#define WHAL_ERROR_RESET_RXFRAME 22
+#define WHAL_ERROR_RESET_STOPDMA 23
+#define WHAL_ERROR_RESET_RECOVER 24
+#define WHAL_ERROR_XMIT_COMPUTE 25
+#define WHAL_ERROR_XMIT_NOQUEUE 26
+#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27
+#define WHAL_ERROR_XMIT_BADTYPE 28
+#define WHAL_ERROR_XMIT_STOPDMA 29
+#define WHAL_ERROR_INTERRUPT_BB_PANIC 30
+#define WHAL_ERROR_RESET_TXIQCAL 31
+#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 32
+#define WHAL_DBGID_DEFINITION_END
+
+/* DC debug identifier definitions */
+#define DC_DBGID_DEFINITION_START
+#define DC_SCAN_CHAN_START 1
+#define DC_SCAN_CHAN_FINISH 2
+#define DC_BEACON_RECEIVE7 3
+#define DC_SSID_PROBE_CB 4
+#define DC_SEND_NEXT_SSID_PROBE 5
+#define DC_START_SEARCH 6
+#define DC_CANCEL_SEARCH_CB 7
+#define DC_STOP_SEARCH 8
+#define DC_END_SEARCH 9
+#define DC_MIN_CHDWELL_TIMEOUT 10
+#define DC_START_SEARCH_CANCELED 11
+#define DC_SET_POWER_MODE 12
+#define DC_INIT 13
+#define DC_SEARCH_OPPORTUNITY 14
+#define DC_RECEIVED_ANY_BEACON 15
+#define DC_RECEIVED_MY_BEACON 16
+#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA 17
+#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT 18
+#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED 19
+#define DC_SET_BEACON_UPDATE 20
+#define DC_BEACON_UPDATE_COMPLETE 21
+#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB 22
+#define DC_BSSINFO_EVENT_DROPPED 23
+#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT 24
+#define DC_DBGID_DEFINITION_END
+
+/* CO debug identifier definitions */
+#define CO_DBGID_DEFINITION_START
+#define CO_INIT 1
+#define CO_ACQUIRE_LOCK 2
+#define CO_START_OP1 3
+#define CO_START_OP2 4
+#define CO_DRAIN_TX_COMPLETE_CB 5
+#define CO_CHANGE_CHANNEL_CB 6
+#define CO_RETURN_TO_HOME_CHANNEL 7
+#define CO_FINISH_OP_TIMEOUT 8
+#define CO_OP_END 9
+#define CO_CANCEL_OP 10
+#define CO_CHANGE_CHANNEL 11
+#define CO_RELEASE_LOCK 12
+#define CO_CHANGE_STATE 13
+#define CO_DBGID_DEFINITION_END
+
+/* RO debug identifier definitions */
+#define RO_DBGID_DEFINITION_START
+#define RO_REFRESH_ROAM_TABLE 1
+#define RO_UPDATE_ROAM_CANDIDATE 2
+#define RO_UPDATE_ROAM_CANDIDATE_CB 3
+#define RO_UPDATE_ROAM_CANDIDATE_FINISH 4
+#define RO_REFRESH_ROAM_TABLE_DONE 5
+#define RO_PERIODIC_SEARCH_CB 6
+#define RO_PERIODIC_SEARCH_TIMEOUT 7
+#define RO_INIT 8
+#define RO_BMISS_STATE1 9
+#define RO_BMISS_STATE2 10
+#define RO_SET_PERIODIC_SEARCH_ENABLE 11
+#define RO_SET_PERIODIC_SEARCH_DISABLE 12
+#define RO_ENABLE_SQ_THRESHOLD 13
+#define RO_DISABLE_SQ_THRESHOLD 14
+#define RO_ADD_BSS_TO_ROAM_TABLE 15
+#define RO_SET_PERIODIC_SEARCH_MODE 16
+#define RO_CONFIGURE_SQ_THRESHOLD1 17
+#define RO_CONFIGURE_SQ_THRESHOLD2 18
+#define RO_CONFIGURE_SQ_PARAMS 19
+#define RO_LOW_SIGNAL_QUALITY_EVENT 20
+#define RO_HIGH_SIGNAL_QUALITY_EVENT 21
+#define RO_REMOVE_BSS_FROM_ROAM_TABLE 22
+#define RO_UPDATE_CONNECTION_STATE_METRIC 23
+#define RO_DBGID_DEFINITION_END
+
+/* CM debug identifier definitions */
+#define CM_DBGID_DEFINITION_START
+#define CM_INITIATE_HANDOFF 1
+#define CM_INITIATE_HANDOFF_CB 2
+#define CM_CONNECT_EVENT 3
+#define CM_DISCONNECT_EVENT 4
+#define CM_INIT 5
+#define CM_HANDOFF_SOURCE 6
+#define CM_SET_HANDOFF_TRIGGERS 7
+#define CM_CONNECT_REQUEST 8
+#define CM_CONNECT_REQUEST_CB 9
+#define CM_CONTINUE_SCAN_CB 10
+#define CM_DBGID_DEFINITION_END
+
+
+/* mgmt debug identifier definitions */
+#define MGMT_DBGID_DEFINITION_START
+#define KEYMGMT_CONNECTION_INIT 1
+#define KEYMGMT_CONNECTION_COMPLETE 2
+#define KEYMGMT_CONNECTION_CLOSE 3
+#define KEYMGMT_ADD_KEY 4
+#define MLME_NEW_STATE 5
+#define MLME_CONN_INIT 6
+#define MLME_CONN_COMPLETE 7
+#define MLME_CONN_CLOSE 8
+#define MGMT_DBGID_DEFINITION_END
+
+/* TMR debug identifier definitions */
+#define TMR_DBGID_DEFINITION_START
+#define TMR_HANG_DETECTED 1
+#define TMR_WDT_TRIGGERED 2
+#define TMR_WDT_RESET 3
+#define TMR_HANDLER_ENTRY 4
+#define TMR_HANDLER_EXIT 5
+#define TMR_SAVED_START 6
+#define TMR_SAVED_END 7
+#define TMR_DBGID_DEFINITION_END
+
+/* BTCOEX debug identifier definitions */
+#define BTCOEX_DBGID_DEFINITION_START
+#define BTCOEX_STATUS_CMD 1
+#define BTCOEX_PARAMS_CMD 2
+#define BTCOEX_ANT_CONFIG 3
+#define BTCOEX_COLOCATED_BT_DEVICE 4
+#define BTCOEX_CLOSE_RANGE_SCO_ON 5
+#define BTCOEX_CLOSE_RANGE_SCO_OFF 6
+#define BTCOEX_CLOSE_RANGE_A2DP_ON 7
+#define BTCOEX_CLOSE_RANGE_A2DP_OFF 8
+#define BTCOEX_A2DP_PROTECT_ON 9
+#define BTCOEX_A2DP_PROTECT_OFF 10
+#define BTCOEX_SCO_PROTECT_ON 11
+#define BTCOEX_SCO_PROTECT_OFF 12
+#define BTCOEX_CLOSE_RANGE_DETECTOR_START 13
+#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP 14
+#define BTCOEX_CLOSE_RANGE_TOGGLE 15
+#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT 16
+#define BTCOEX_CLOSE_RANGE_RSSI_THRESH 17
+#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH 18
+#define BTCOEX_PTA_PRI_INTR_HANDLER 19
+#define BTCOEX_PSPOLL_QUEUED 20
+#define BTCOEX_PSPOLL_COMPLETE 21
+#define BTCOEX_DBG_PM_AWAKE 22
+#define BTCOEX_DBG_PM_SLEEP 23
+#define BTCOEX_DBG_SCO_COEX_ON 24
+#define BTCOEX_SCO_DATARECEIVE 25
+#define BTCOEX_INTR_INIT 26
+#define BTCOEX_PTA_PRI_DIFF 27
+#define BTCOEX_TIM_NOTIFICATION 28
+#define BTCOEX_SCO_WAKEUP_ON_DATA 29
+#define BTCOEX_SCO_SLEEP 30
+#define BTCOEX_SET_WEIGHTS 31
+#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL 32
+#define BTCOEX_SCO_MEASURE_TIME_DIFF 33
+#define BTCOEX_SET_EOL_VAL 34
+#define BTCOEX_OPT_DETECT_HANDLER 35
+#define BTCOEX_SCO_TOGGLE_STATE 36
+#define BTCOEX_SCO_STOMP 37
+#define BTCOEX_NULL_COMP_CALLBACK 38
+#define BTCOEX_RX_INCOMING 39
+#define BTCOEX_RX_INCOMING_CTL 40
+#define BTCOEX_RX_INCOMING_MGMT 41
+#define BTCOEX_RX_INCOMING_DATA 42
+#define BTCOEX_RTS_RECEPTION 43
+#define BTCOEX_FRAME_PRI_LOW_RATE_THRES 44
+#define BTCOEX_PM_FAKE_SLEEP 45
+#define BTCOEX_ACL_COEX_STATUS 46
+#define BTCOEX_ACL_COEX_DETECTION 47
+#define BTCOEX_A2DP_COEX_STATUS 48
+#define BTCOEX_SCO_STATUS 49
+#define BTCOEX_WAKEUP_ON_DATA 50
+#define BTCOEX_DATARECEIVE 51
+#define BTCOEX_GET_MAX_AGGR_SIZE 53
+#define BTCOEX_MAX_AGGR_AVAIL_TIME 54
+#define BTCOEX_DBG_WBTIMER_INTR 55
+#define BTCOEX_DBG_SCO_SYNC 57
+#define BTCOEX_UPLINK_QUEUED_RATE 59
+#define BTCOEX_DBG_UPLINK_ENABLE_EOL 60
+#define BTCOEX_UPLINK_FRAME_DURATION 61
+#define BTCOEX_UPLINK_SET_EOL 62
+#define BTCOEX_DBG_EOL_EXPIRED 63
+#define BTCOEX_DBG_DATA_COMPLETE 64
+#define BTCOEX_UPLINK_QUEUED_TIMESTAMP 65
+#define BTCOEX_DBG_DATA_COMPLETE_TIME 66
+#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE 67
+#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER 68
+#define BTCOEX_DBG_UPLINK_SEQ_NUM 69
+#define BTCOEX_UPLINK_AGGR_SEQ 70
+#define BTCOEX_DBG_TX_COMP_SEQ_NO 71
+#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE 72
+#define BTCOEX_DBG_ACL_TRAFFIC 73
+#define BTCOEX_CURR_AGGR_PROP 74
+#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF 75
+#define BTCOEX_PSPOLL_PROCESS 76
+#define BTCOEX_RETURN_FROM_MAC 77
+#define BTCOEX_FREED_REQUEUED_CNT 78
+#define BTCOEX_DBG_TOGGLE_LOW_RATES 79
+#define BTCOEX_MAC_GOES_TO_SLEEP 80
+#define BTCOEX_DBG_A2DP_NO_SYNC 81
+#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO 82
+#define BTCOEX_RETURN_FROM_MAC_AC 83
+#define BTCOEX_DBG_DTIM_RECV 84
+#define BTCOEX_IS_PRE_UPDATE 86
+#define BTCOEX_ENQUEUED_BIT_MAP 87
+#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS 88
+#define BTCOEX_UPLINK_DESC 89
+#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP 90
+#define BTCOEX_DBG_RECV_ACK 94
+#define BTCOEX_DBG_ADDBA_INDICATION 95
+#define BTCOEX_TX_COMPLETE_EOL_FAILED 96
+#define BTCOEX_DBG_A2DP_USAGE_COMPLETE 97
+#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER 98
+#define BTCOEX_DBG_A2DP_SYNC_INTR 99
+#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION 100
+#define BTCOEX_FORM_AGGR_CURR_AGGR 101
+#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT 102
+#define BTCOEX_DBG_BT_TRAFFIC 103
+#define BTCOEX_DBG_STOMP_BT_TRAFFIC 104
+#define BTCOEX_RECV_NULL 105
+#define BTCOEX_DBG_A2DP_MASTER_BT_END 106
+#define BTCOEX_DBG_A2DP_BT_START 107
+#define BTCOEX_DBG_A2DP_SLAVE_BT_END 108
+#define BTCOEX_DBG_A2DP_STOMP_BT 109
+#define BTCOEX_DBG_GO_TO_SLEEP 110
+#define BTCOEX_DBG_A2DP_PKT 111
+#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV 112
+#define BTCOEX_DBG_A2DP_NULL 113
+#define BTCOEX_DBG_UPLINK_DATA 114
+#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL 115
+#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT 116
+#define BTCOEX_DBG_TXQ_STATE 117
+#define BTCOEX_DBG_ALLOW_SCAN 118
+#define BTCOEX_DBG_SCAN_REQUEST 119
+#define BTCOEX_A2DP_SLEEP 127
+#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT 128
+#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE 129
+#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE 130
+#define BTCOEX_DATARECEIVE_AGGR 131
+#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING 132
+#define BTCOEX_DBG_DATARESP_TIMEOUT 133
+#define BTCOEX_BDG_BMISS 134
+#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM 135
+#define BTCOEX_DBG_SECOND_BMISS 136
+#define BTCOEX_DBG_SET_WLAN_STATE 138
+#define BTCOEX_BDG_FIRST_BMISS 139
+#define BTCOEX_DBG_A2DP_CHAN_OP 140
+#define BTCOEX_DBG_A2DP_INTR 141
+#define BTCOEX_DBG_BT_INQUIRY 142
+#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH 143
+#define BTCOEX_DBG_POST_INQUIRY_FINISH 144
+#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER 145
+#define BTCOEX_DBG_NULL_FRAME_SLEEP 146
+#define BTCOEX_DBG_NULL_FRAME_AWAKE 147
+#define BTCOEX_DBG_SET_AGGR_SIZE 152
+#define BTCOEX_DBG_TEAR_BA_TIMEOUT 153
+#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO 154
+#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI 155
+#define BTCOEX_DBG_COLOCATED_BT_DEV 156
+#define BTCOEX_DBG_FE_ANT_TYPE 157
+#define BTCOEX_DBG_BT_INQUIRY_CMD 158
+#define BTCOEX_DBG_SCO_CONFIG 159
+#define BTCOEX_DBG_SCO_PSPOLL_CONFIG 160
+#define BTCOEX_DBG_SCO_OPTMODE_CONFIG 161
+#define BTCOEX_DBG_A2DP_CONFIG 162
+#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG 163
+#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG 164
+#define BTCOEX_DBG_ACLCOEX_CONFIG 165
+#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG 166
+#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG 167
+#define BTCOEX_DBG_DEBUG_CMD 168
+#define BTCOEX_DBG_SET_BT_OPERATING_STATUS 169
+#define BTCOEX_DBG_GET_CONFIG 170
+#define BTCOEX_DBG_GET_STATS 171
+#define BTCOEX_DBG_BT_OPERATING_STATUS 172
+#define BTCOEX_DBG_PERFORM_RECONNECT 173
+#define BTCOEX_DBG_ACL_WLAN_MED 175
+#define BTCOEX_DBG_ACL_BT_MED 176
+#define BTCOEX_DBG_WLAN_CONNECT 177
+#define BTCOEX_DBG_A2DP_DUAL_START 178
+#define BTCOEX_DBG_PMAWAKE_NOTIFY 179
+#define BTCOEX_DBG_BEACON_SCAN_ENABLE 180
+#define BTCOEX_DBG_BEACON_SCAN_DISABLE 181
+#define BTCOEX_DBG_RX_NOTIFY 182
+#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP 183
+#define BTCOEX_DBG_TXQ_DETAILS 184
+#define BTCOEX_DBG_SCO_STOMP_LOW_PRI 185
+#define BTCOEX_DBG_A2DP_FORCE_SCAN 186
+#define BTCOEX_DBG_DTIM_STOMP_COMP 187
+#define BTCOEX_ACL_PRESENCE_TIMER 188
+#define BTCOEX_DBGID_DEFINITION_END
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DBGLOG_ID_H_ */
diff --git a/drivers/staging/ath6kl/include/common/discovery.h b/drivers/staging/ath6kl/include/common/discovery.h
new file mode 100644
index 000000000000..da1b33245069
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/discovery.h
@@ -0,0 +1,75 @@
+//------------------------------------------------------------------------------
+// <copyright file="discovery.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _DISCOVERY_H_
+#define _DISCOVERY_H_
+
+/*
+ * DC_SCAN_PRIORITY is an 8-bit bitmap of the scan priority of a channel
+ */
+typedef enum {
+ DEFAULT_SCPRI = 0x01,
+ POPULAR_SCPRI = 0x02,
+ SSIDS_SCPRI = 0x04,
+ PROF_SCPRI = 0x08,
+} DC_SCAN_PRIORITY;
+
+/* The following search type construct can be used to manipulate the behavior of the search module based on different bits set */
+typedef enum {
+ SCAN_RESET = 0,
+ SCAN_ALL = (DEFAULT_SCPRI | POPULAR_SCPRI | \
+ SSIDS_SCPRI | PROF_SCPRI),
+
+ SCAN_POPULAR = (POPULAR_SCPRI | SSIDS_SCPRI | PROF_SCPRI),
+ SCAN_SSIDS = (SSIDS_SCPRI | PROF_SCPRI),
+ SCAN_PROF_MASK = (PROF_SCPRI),
+ SCAN_MULTI_CHANNEL = 0x000100,
+ SCAN_DETERMINISTIC = 0x000200,
+ SCAN_PROFILE_MATCH_TERMINATED = 0x000400,
+ SCAN_HOME_CHANNEL_SKIP = 0x000800,
+ SCAN_CHANNEL_LIST_CONTINUE = 0x001000,
+ SCAN_CURRENT_SSID_SKIP = 0x002000,
+ SCAN_ACTIVE_PROBE_DISABLE = 0x004000,
+ SCAN_CHANNEL_HINT_ONLY = 0x008000,
+ SCAN_ACTIVE_CHANNELS_ONLY = 0x010000,
+ SCAN_UNUSED1 = 0x020000, /* unused */
+ SCAN_PERIODIC = 0x040000,
+ SCAN_FIXED_DURATION = 0x080000,
+ SCAN_AP_ASSISTED = 0x100000,
+} DC_SCAN_TYPE;
+
+typedef enum {
+ BSS_REPORTING_DEFAULT = 0x0,
+ EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */
+} DC_BSS_REPORTING_POLICY;
+
+typedef enum {
+ DC_IGNORE_WPAx_GROUP_CIPHER = 0x01,
+ DC_PROFILE_MATCH_DONE = 0x02,
+ DC_IGNORE_AAC_BEACON = 0x04,
+ DC_CSA_FOLLOW_BSS = 0x08,
+} DC_PROFILE_FILTER;
+
+#define DEFAULT_DC_PROFILE_FILTER (DC_CSA_FOLLOW_BSS)
+
+#endif /* _DISCOVERY_H_ */
diff --git a/drivers/staging/ath6kl/include/common/dset_internal.h b/drivers/staging/ath6kl/include/common/dset_internal.h
new file mode 100644
index 000000000000..2460f0ecf12b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dset_internal.h
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <copyright file="dset_internal.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+
+#ifndef __DSET_INTERNAL_H__
+#define __DSET_INTERNAL_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+/*
+ * Internal dset definitions, common for DataSet layer.
+ */
+
+#define DSET_TYPE_STANDARD 0
+#define DSET_TYPE_BPATCHED 1
+#define DSET_TYPE_COMPRESSED 2
+
+/* Dataset descriptor */
+
+typedef PREPACK struct dset_descriptor_s {
+ struct dset_descriptor_s *next; /* List link. NULL only at the last
+ descriptor */
+ A_UINT16 id; /* Dset ID */
+ A_UINT16 size; /* Dset size. */
+ void *DataPtr; /* Pointer to raw data for standard
+ DataSet or pointer to original
+ dset_descriptor for patched
+ DataSet */
+ A_UINT32 data_type; /* DSET_TYPE_*, above */
+
+ void *AuxPtr; /* Additional data that might
+ needed for data_type. For
+ example, pointer to patch
+ Dataset descriptor for BPatch. */
+} POSTPACK dset_descriptor_t;
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __DSET_INTERNAL_H__ */
diff --git a/drivers/staging/ath6kl/include/common/dsetid.h b/drivers/staging/ath6kl/include/common/dsetid.h
new file mode 100644
index 000000000000..d08fdeb39ec3
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/dsetid.h
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+// <copyright file="dsetid.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+
+#ifndef __DSETID_H__
+#define __DSETID_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+/* Well-known DataSet IDs */
+#define DSETID_UNUSED 0x00000000
+#define DSETID_BOARD_DATA 0x00000001 /* Cal and board data */
+#define DSETID_REGDB 0x00000002 /* Regulatory Database */
+#define DSETID_POWER_CONTROL 0x00000003 /* TX Pwr Lim & Ant Gain */
+#define DSETID_USER_CONFIG 0x00000004 /* User Configuration */
+
+#define DSETID_ANALOG_CONTROL_DATA_START 0x00000005
+#define DSETID_ANALOG_CONTROL_DATA_END 0x00000025
+/*
+ * Get DSETID for various reference clock speeds.
+ * For each speed there are three DataSets that correspond
+ * to the three columns of bank6 data (addr, 11a, 11b/g).
+ * This macro returns the dsetid of the first of those
+ * three DataSets.
+ */
+#define ANALOG_CONTROL_DATA_DSETID(refclk) \
+ (DSETID_ANALOG_CONTROL_DATA_START + 3*refclk)
+
+/*
+ * There are TWO STARTUP_PATCH DataSets.
+ * DSETID_STARTUP_PATCH is historical, and was applied before BMI on
+ * earlier systems. On AR6002, it is applied after BMI, just like
+ * DSETID_STARTUP_PATCH2.
+ */
+#define DSETID_STARTUP_PATCH 0x00000026
+#define DSETID_GPIO_CONFIG_PATCH 0x00000027
+#define DSETID_WLANREGS 0x00000028 /* override wlan regs */
+#define DSETID_STARTUP_PATCH2 0x00000029
+
+#define DSETID_WOW_CONFIG 0x00000090 /* WoW Configuration */
+
+/* Add WHAL_INI_DATA_ID to DSETID_INI_DATA for a specific WHAL INI table. */
+#define DSETID_INI_DATA 0x00000100
+/* Reserved for WHAL INI Tables: 0x100..0x11f */
+#define DSETID_INI_DATA_END 0x0000011f
+
+#define DSETID_VENDOR_START 0x00010000 /* Vendor-defined DataSets */
+
+#define DSETID_INDEX_END 0xfffffffe /* Reserved to indicate the
+ end of a memory-based
+ DataSet Index */
+#define DSETID_INDEX_FREE 0xffffffff /* An unused index entry */
+
+/*
+ * PATCH DataSet format:
+ * A list of patches, terminated by a patch with
+ * address=PATCH_END.
+ *
+ * This allows for patches to be stored in flash.
+ */
+PREPACK struct patch_s {
+ A_UINT32 *address;
+ A_UINT32 data;
+} POSTPACK ;
+
+/*
+ * Skip some patches. Can be used to erase a single patch in a
+ * patch DataSet without having to re-write the DataSet. May
+ * also be used to embed information for use by subsequent
+ * patch code. The "data" in a PATCH_SKIP tells how many
+ * bytes of length "patch_s" to skip.
+ */
+#define PATCH_SKIP ((A_UINT32 *)0x00000000)
+
+/*
+ * Execute code at the address specified by "data".
+ * The address of the patch structure is passed as
+ * the one parameter.
+ */
+#define PATCH_CODE_ABS ((A_UINT32 *)0x00000001)
+
+/*
+ * Same as PATCH_CODE_ABS, but treat "data" as an
+ * offset from the start of the patch word.
+ */
+#define PATCH_CODE_REL ((A_UINT32 *)0x00000002)
+
+/* Mark the end of this patch DataSet. */
+#define PATCH_END ((A_UINT32 *)0xffffffff)
+
+/*
+ * A DataSet which contains a Binary Patch to some other DataSet
+ * uses the original dsetid with the DSETID_BPATCH_FLAG bit set.
+ * Such a BPatch DataSet consists of BPatch metadata followed by
+ * the bdiff bytes. BPatch metadata consists of a single 32-bit
+ * word that contains the size of the BPatched final image.
+ *
+ * To create a suitable bdiff DataSet, use bdiff in host/tools/bdiff
+ * to create "diffs":
+ * bdiff -q -O -nooldmd5 -nonewmd5 -d ORIGfile NEWfile diffs
+ * Then add BPatch metadata to the start of "diffs".
+ *
+ * NB: There are some implementation-induced restrictions
+ * on which DataSets can be BPatched.
+ */
+#define DSETID_BPATCH_FLAG 0x80000000
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __DSETID_H__ */
diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h
new file mode 100644
index 000000000000..f8aeb3f657ea
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/epping_test.h
@@ -0,0 +1,120 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//
+
+/* This file contains shared definitions for the host/target endpoint ping test */
+
+#ifndef EPPING_TEST_H_
+#define EPPING_TEST_H_
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+ /* alignment to 4-bytes */
+#define EPPING_ALIGNMENT_PAD (((sizeof(HTC_FRAME_HDR) + 3) & (~0x3)) - sizeof(HTC_FRAME_HDR))
+
+#ifndef A_OFFSETOF
+#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field))
+#endif
+
+#define EPPING_RSVD_FILL 0xCC
+
+#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7
+
+typedef PREPACK struct {
+ A_UINT8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */
+ A_UINT8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */
+ A_UINT8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target)
+ When echoed: StreamEchoSent_t == StreamEcho_h */
+ A_UINT8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */
+ A_UINT8 StreamNo_h; /* stream number to send on (filled by host) */
+ A_UINT8 Magic_h[4]; /* magic number to filter for this packet on the host*/
+ A_UINT8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value
+ since this packet maps to a 14-byte ethernet frame we want
+ to make sure ethertype field is set to something unknown */
+
+ A_UINT8 _pad[2]; /* padding for alignment */
+ A_UINT8 TimeStamp[8]; /* timestamp of packet (host or target) */
+ A_UINT32 HostContext_h; /* 4 byte host context, target echos this back */
+ A_UINT32 SeqNo; /* sequence number (set by host or target) */
+ A_UINT16 Cmd_h; /* ping command (filled by host) */
+ A_UINT16 CmdFlags_h; /* optional flags */
+ A_UINT8 CmdBuffer_h[8]; /* buffer for command (host -> target) */
+ A_UINT8 CmdBuffer_t[8]; /* buffer for command (target -> host) */
+ A_UINT16 DataLength; /* length of data */
+ A_UINT16 DataCRC; /* 16 bit CRC of data */
+ A_UINT16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */
+} POSTPACK EPPING_HEADER;
+
+#define EPPING_PING_MAGIC_0 0xAA
+#define EPPING_PING_MAGIC_1 0x55
+#define EPPING_PING_MAGIC_2 0xCE
+#define EPPING_PING_MAGIC_3 0xEC
+
+
+
+#define IS_EPPING_PACKET(pPkt) (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \
+ ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \
+ ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \
+ ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3))
+
+#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \
+ (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \
+ (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \
+ (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;}
+
+#define CMD_FLAGS_DATA_CRC (1 << 0) /* DataCRC field is valid */
+#define CMD_FLAGS_DELAY_ECHO (1 << 1) /* delay the echo of the packet */
+#define CMD_FLAGS_NO_DROP (1 << 2) /* do not drop at HTC layer no matter what the stream is */
+
+#define IS_EPING_PACKET_NO_DROP(pPkt) ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP)
+
+#define EPPING_CMD_ECHO_PACKET 1 /* echo packet test */
+#define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */
+#define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */
+#define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */
+#define EPPING_CMD_CONT_RX_START 5 /* continous RX packets, parameters are in CmdBuffer_h */
+#define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */
+
+ /* test command parameters may be no more than 8 bytes */
+typedef PREPACK struct {
+ A_UINT16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */
+ A_UINT16 PacketLength; /* length of packet to generate including header */
+ A_UINT16 Flags; /* flags */
+
+#define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */
+#define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */
+#define EPPING_CONT_RX_RANDOM_LEN (1 << 2) /* randomize the packet lengths */
+} POSTPACK EPPING_CONT_RX_PARAMS;
+
+#define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h)
+#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(A_UINT16)))
+
+#define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we
+ can use this to distinguish packets */
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+
+#endif /*EPPING_TEST_H_*/
diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h
new file mode 100644
index 000000000000..4d8d85fd2e7c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/gmboxif.h
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __GMBOXIF_H__
+#define __GMBOXIF_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+/* GMBOX interface definitions */
+
+#define AR6K_GMBOX_CREDIT_COUNTER 1 /* we use credit counter 1 to track credits */
+#define AR6K_GMBOX_CREDIT_SIZE_COUNTER 2 /* credit counter 2 is used to pass the size of each credit */
+
+
+ /* HCI UART transport definitions when used over GMBOX interface */
+#define HCI_UART_COMMAND_PKT 0x01
+#define HCI_UART_ACL_PKT 0x02
+#define HCI_UART_SCO_PKT 0x03
+#define HCI_UART_EVENT_PKT 0x04
+
+ /* definitions for BT HCI packets */
+typedef PREPACK struct {
+ A_UINT16 Flags_ConnHandle;
+ A_UINT16 Length;
+} POSTPACK BT_HCI_ACL_HEADER;
+
+typedef PREPACK struct {
+ A_UINT16 Flags_ConnHandle;
+ A_UINT8 Length;
+} POSTPACK BT_HCI_SCO_HEADER;
+
+typedef PREPACK struct {
+ A_UINT16 OpCode;
+ A_UINT8 ParamLength;
+} POSTPACK BT_HCI_COMMAND_HEADER;
+
+typedef PREPACK struct {
+ A_UINT8 EventCode;
+ A_UINT8 ParamLength;
+} POSTPACK BT_HCI_EVENT_HEADER;
+
+/* MBOX host interrupt signal assignments */
+
+#define MBOX_SIG_HCI_BRIDGE_MAX 8
+#define MBOX_SIG_HCI_BRIDGE_BT_ON 0
+#define MBOX_SIG_HCI_BRIDGE_BT_OFF 1
+#define MBOX_SIG_HCI_BRIDGE_BAUD_SET 2
+#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON 3
+#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF 4
+
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __GMBOXIF_H__ */
+
diff --git a/drivers/staging/ath6kl/include/common/gpio.h b/drivers/staging/ath6kl/include/common/gpio.h
new file mode 100644
index 000000000000..f7230667dd66
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/gpio.h
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#define AR6001_GPIO_PIN_COUNT 18
+#define AR6002_GPIO_PIN_COUNT 18
+#define AR6003_GPIO_PIN_COUNT 28
+
+/*
+ * Possible values for WMIX_GPIO_SET_REGISTER_CMDID.
+ * NB: These match hardware order, so that addresses can
+ * easily be computed.
+ */
+#define GPIO_ID_OUT 0x00000000
+#define GPIO_ID_OUT_W1TS 0x00000001
+#define GPIO_ID_OUT_W1TC 0x00000002
+#define GPIO_ID_ENABLE 0x00000003
+#define GPIO_ID_ENABLE_W1TS 0x00000004
+#define GPIO_ID_ENABLE_W1TC 0x00000005
+#define GPIO_ID_IN 0x00000006
+#define GPIO_ID_STATUS 0x00000007
+#define GPIO_ID_STATUS_W1TS 0x00000008
+#define GPIO_ID_STATUS_W1TC 0x00000009
+#define GPIO_ID_PIN0 0x0000000a
+#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
+
+#define GPIO_LAST_REGISTER_ID GPIO_ID_PIN(17)
+#define GPIO_ID_NONE 0xffffffff
diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h
new file mode 100644
index 000000000000..f96cf7db7e06
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/htc.h
@@ -0,0 +1,236 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __HTC_H__
+#define __HTC_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field))
+
+#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \
+ (((A_UINT16)(((A_UINT8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((A_UINT8 *)(p))[(lowbyte)]))
+
+/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a
+ * structure using only the type and field name.
+ * Use these macros if there is the potential for unaligned buffer accesses. */
+#define A_GET_UINT16_FIELD(p,type,field) \
+ ASSEMBLE_UNALIGNED_UINT16(p,\
+ A_OFFSETOF(type,field) + 1, \
+ A_OFFSETOF(type,field))
+
+#define A_SET_UINT16_FIELD(p,type,field,value) \
+{ \
+ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (A_UINT8)(value); \
+ ((A_UINT8 *)(p))[A_OFFSETOF(type,field) + 1] = (A_UINT8)((value) >> 8); \
+}
+
+#define A_GET_UINT8_FIELD(p,type,field) \
+ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)]
+
+#define A_SET_UINT8_FIELD(p,type,field,value) \
+ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (value)
+
+/****** DANGER DANGER ***************
+ *
+ * The frame header length and message formats defined herein were
+ * selected to accommodate optimal alignment for target processing. This reduces code
+ * size and improves performance.
+ *
+ * Any changes to the header length may alter the alignment and cause exceptions
+ * on the target. When adding to the message structures insure that fields are
+ * properly aligned.
+ *
+ */
+
+/* HTC frame header */
+typedef PREPACK struct _HTC_FRAME_HDR{
+ /* do not remove or re-arrange these fields, these are minimally required
+ * to take advantage of 4-byte lookaheads in some hardware implementations */
+ A_UINT8 EndpointID;
+ A_UINT8 Flags;
+ A_UINT16 PayloadLen; /* length of data (including trailer) that follows the header */
+
+ /***** end of 4-byte lookahead ****/
+
+ A_UINT8 ControlBytes[2];
+
+ /* message payload starts after the header */
+
+} POSTPACK HTC_FRAME_HDR;
+
+/* frame header flags */
+
+ /* send direction */
+#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
+#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */
+ /* receive direction */
+#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */
+#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */
+#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */
+#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */
+#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */
+#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4
+
+#define HTC_HDR_LENGTH (sizeof(HTC_FRAME_HDR))
+#define HTC_MAX_TRAILER_LENGTH 255
+#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(HTC_FRAME_HDR))
+
+/* HTC control message IDs */
+
+#define HTC_MSG_READY_ID 1
+#define HTC_MSG_CONNECT_SERVICE_ID 2
+#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3
+#define HTC_MSG_SETUP_COMPLETE_ID 4
+#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
+
+#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256
+
+/* base message ID header */
+typedef PREPACK struct {
+ A_UINT16 MessageID;
+} POSTPACK HTC_UNKNOWN_MSG;
+
+/* HTC ready message
+ * direction : target-to-host */
+typedef PREPACK struct {
+ A_UINT16 MessageID; /* ID */
+ A_UINT16 CreditCount; /* number of credits the target can offer */
+ A_UINT16 CreditSize; /* size of each credit */
+ A_UINT8 MaxEndpoints; /* maximum number of endpoints the target has resources for */
+ A_UINT8 _Pad1;
+} POSTPACK HTC_READY_MSG;
+
+ /* extended HTC ready message */
+typedef PREPACK struct {
+ HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */
+ /* extended information */
+ A_UINT8 HTCVersion;
+ A_UINT8 MaxMsgsPerHTCBundle;
+} POSTPACK HTC_READY_EX_MSG;
+
+#define HTC_VERSION_2P0 0x00
+#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */
+
+#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
+
+/* connect service
+ * direction : host-to-target */
+typedef PREPACK struct {
+ A_UINT16 MessageID;
+ A_UINT16 ServiceID; /* service ID of the service to connect to */
+ A_UINT16 ConnectionFlags; /* connection flags */
+
+#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when
+ the host needs credits */
+#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3)
+#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0
+#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1
+#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2
+#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3
+
+ A_UINT8 ServiceMetaLength; /* length of meta data that follows */
+ A_UINT8 _Pad1;
+
+ /* service-specific meta data starts after the header */
+
+} POSTPACK HTC_CONNECT_SERVICE_MSG;
+
+/* connect response
+ * direction : target-to-host */
+typedef PREPACK struct {
+ A_UINT16 MessageID;
+ A_UINT16 ServiceID; /* service ID that the connection request was made */
+ A_UINT8 Status; /* service connection status */
+ A_UINT8 EndpointID; /* assigned endpoint ID */
+ A_UINT16 MaxMsgSize; /* maximum expected message size on this endpoint */
+ A_UINT8 ServiceMetaLength; /* length of meta data that follows */
+ A_UINT8 _Pad1;
+
+ /* service-specific meta data starts after the header */
+
+} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG;
+
+typedef PREPACK struct {
+ A_UINT16 MessageID;
+ /* currently, no other fields */
+} POSTPACK HTC_SETUP_COMPLETE_MSG;
+
+ /* extended setup completion message */
+typedef PREPACK struct {
+ A_UINT16 MessageID;
+ A_UINT32 SetupFlags;
+ A_UINT8 MaxMsgsPerBundledRecv;
+ A_UINT8 Rsvd[3];
+} POSTPACK HTC_SETUP_COMPLETE_EX_MSG;
+
+#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0)
+
+/* connect response status codes */
+#define HTC_SERVICE_SUCCESS 0 /* success */
+#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */
+#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */
+#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */
+#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more
+ endpoints */
+
+/* report record IDs */
+
+#define HTC_RECORD_NULL 0
+#define HTC_RECORD_CREDITS 1
+#define HTC_RECORD_LOOKAHEAD 2
+#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
+
+typedef PREPACK struct {
+ A_UINT8 RecordID; /* Record ID */
+ A_UINT8 Length; /* Length of record */
+} POSTPACK HTC_RECORD_HDR;
+
+typedef PREPACK struct {
+ A_UINT8 EndpointID; /* Endpoint that owns these credits */
+ A_UINT8 Credits; /* credits to report since last report */
+} POSTPACK HTC_CREDIT_REPORT;
+
+typedef PREPACK struct {
+ A_UINT8 PreValid; /* pre valid guard */
+ A_UINT8 LookAhead[4]; /* 4 byte lookahead */
+ A_UINT8 PostValid; /* post valid guard */
+
+ /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes.
+ * The PreValid bytes must equal the inverse of the PostValid byte */
+
+} POSTPACK HTC_LOOKAHEAD_REPORT;
+
+typedef PREPACK struct {
+ A_UINT8 LookAhead[4]; /* 4 byte lookahead */
+} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT;
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+
+#endif /* __HTC_H__ */
+
diff --git a/drivers/staging/ath6kl/include/common/htc_services.h b/drivers/staging/ath6kl/include/common/htc_services.h
new file mode 100644
index 000000000000..fb22268a8d84
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/htc_services.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_services.h" company="Atheros">
+// Copyright (c) 2007 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __HTC_SERVICES_H__
+#define __HTC_SERVICES_H__
+
+/* Current service IDs */
+
+typedef enum {
+ RSVD_SERVICE_GROUP = 0,
+ WMI_SERVICE_GROUP = 1,
+
+ HTC_TEST_GROUP = 254,
+ HTC_SERVICE_GROUP_LAST = 255
+}HTC_SERVICE_GROUP_IDS;
+
+#define MAKE_SERVICE_ID(group,index) \
+ (int)(((int)group << 8) | (int)(index))
+
+/* NOTE: service ID of 0x0000 is reserved and should never be used */
+#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1)
+#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0)
+#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1)
+#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2)
+#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3)
+#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4)
+#define WMI_MAX_SERVICES 5
+
+/* raw stream service (i.e. flash, tcmd, calibration apps) */
+#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0)
+
+#endif /*HTC_SERVICES_H_*/
diff --git a/drivers/staging/ath6kl/include/common/ini_dset.h b/drivers/staging/ath6kl/include/common/ini_dset.h
new file mode 100644
index 000000000000..8cf1af834bd0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/ini_dset.h
@@ -0,0 +1,82 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _INI_DSET_H_
+#define _INI_DSET_H_
+
+/*
+ * Each of these represents a WHAL INI table, which consists
+ * of an "address column" followed by 1 or more "value columns".
+ *
+ * Software uses the base WHAL_INI_DATA_ID+column to access a
+ * DataSet that holds a particular column of data.
+ */
+typedef enum {
+#if defined(AR6002_REV4) || defined(AR6003)
+/* Add these definitions for compatability */
+#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA1 WHAL_INI_DATA_ID_BB_RFGAIN
+#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA2 WHAL_INI_DATA_ID_BB_RFGAIN
+ WHAL_INI_DATA_ID_NULL =0,
+ WHAL_INI_DATA_ID_MODE_SPECIFIC =1, /* 2,3,4,5 */
+ WHAL_INI_DATA_ID_COMMON =6, /* 7 */
+ WHAL_INI_DATA_ID_BB_RFGAIN =8, /* 9,10 */
+#ifdef FPGA
+ WHAL_INI_DATA_ID_ANALOG_BANK0 =11, /* 12 */
+ WHAL_INI_DATA_ID_ANALOG_BANK1 =13, /* 14 */
+ WHAL_INI_DATA_ID_ANALOG_BANK2 =15, /* 16 */
+ WHAL_INI_DATA_ID_ANALOG_BANK3 =17, /* 18, 19 */
+ WHAL_INI_DATA_ID_ANALOG_BANK6 =20, /* 21,22 */
+ WHAL_INI_DATA_ID_ANALOG_BANK7 =23, /* 24 */
+ WHAL_INI_DATA_ID_ADDAC =25, /* 26 */
+#else
+ WHAL_INI_DATA_ID_ANALOG_COMMON =11, /* 12 */
+ WHAL_INI_DATA_ID_ANALOG_MODE_SPECIFIC=13, /* 14,15 */
+ WHAL_INI_DATA_ID_ANALOG_BANK6 =16, /* 17,18 */
+ WHAL_INI_DATA_ID_MODE_OVERRIDES =19, /* 20,21,22,23 */
+ WHAL_INI_DATA_ID_COMMON_OVERRIDES =24, /* 25 */
+ WHAL_INI_DATA_ID_ANALOG_OVERRIDES =26, /* 27,28 */
+#endif /* FPGA */
+#else
+ WHAL_INI_DATA_ID_NULL =0,
+ WHAL_INI_DATA_ID_MODE_SPECIFIC =1, /* 2,3 */
+ WHAL_INI_DATA_ID_COMMON =4, /* 5 */
+ WHAL_INI_DATA_ID_BB_RFGAIN =6, /* 7,8 */
+#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA1 WHAL_INI_DATA_ID_BB_RFGAIN
+ WHAL_INI_DATA_ID_ANALOG_BANK1 =9, /* 10 */
+ WHAL_INI_DATA_ID_ANALOG_BANK2 =11, /* 12 */
+ WHAL_INI_DATA_ID_ANALOG_BANK3 =13, /* 14, 15 */
+ WHAL_INI_DATA_ID_ANALOG_BANK6 =16, /* 17, 18 */
+ WHAL_INI_DATA_ID_ANALOG_BANK7 =19, /* 20 */
+ WHAL_INI_DATA_ID_MODE_OVERRIDES =21, /* 22,23 */
+ WHAL_INI_DATA_ID_COMMON_OVERRIDES =24, /* 25 */
+ WHAL_INI_DATA_ID_ANALOG_OVERRIDES =26, /* 27,28 */
+ WHAL_INI_DATA_ID_BB_RFGAIN_LNA2 =29, /* 30,31 */
+#endif
+ WHAL_INI_DATA_ID_MAX =31
+} WHAL_INI_DATA_ID;
+
+typedef PREPACK struct {
+ A_UINT16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common
+ A_UINT16 offset;
+ A_UINT32 newValue;
+} POSTPACK INI_DSET_REG_OVERRIDE;
+
+#endif
diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h
new file mode 100644
index 000000000000..331cc04edada
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/pkt_log.h
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __PKT_LOG_H__
+#define __PKT_LOG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Pkt log info */
+typedef PREPACK struct pkt_log_t {
+ struct info_t {
+ A_UINT16 st;
+ A_UINT16 end;
+ A_UINT16 cur;
+ }info[4096];
+ A_UINT16 last_idx;
+}POSTPACK PACKET_LOG;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PKT_LOG_H__ */
diff --git a/drivers/staging/ath6kl/include/common/regDb.h b/drivers/staging/ath6kl/include/common/regDb.h
new file mode 100644
index 000000000000..f8245f104528
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/regDb.h
@@ -0,0 +1,29 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __REG_DB_H__
+#define __REG_DB_H__
+
+#include "./regulatory/reg_dbschema.h"
+#include "./regulatory/reg_dbvalues.h"
+
+#endif /* __REG_DB_H__ */
diff --git a/drivers/staging/ath6kl/include/common/regdump.h b/drivers/staging/ath6kl/include/common/regdump.h
new file mode 100644
index 000000000000..ff79b4846e69
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/regdump.h
@@ -0,0 +1,59 @@
+//------------------------------------------------------------------------------
+// <copyright file="regdump.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __REGDUMP_H__
+#define __REGDUMP_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#if defined(AR6001)
+#include "AR6001/AR6001_regdump.h"
+#endif
+#if defined(AR6002)
+#include "AR6002/AR6002_regdump.h"
+#endif
+
+#if !defined(__ASSEMBLER__)
+/*
+ * Target CPU state at the time of failure is reflected
+ * in a register dump, which the Host can fetch through
+ * the diagnostic window.
+ */
+PREPACK struct register_dump_s {
+ A_UINT32 target_id; /* Target ID */
+ A_UINT32 assline; /* Line number (if assertion failure) */
+ A_UINT32 pc; /* Program Counter at time of exception */
+ A_UINT32 badvaddr; /* Virtual address causing exception */
+ CPU_exception_frame_t exc_frame; /* CPU-specific exception info */
+
+ /* Could copy top of stack here, too.... */
+} POSTPACK;
+#endif /* __ASSEMBLER__ */
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __REGDUMP_H__ */
diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h
new file mode 100644
index 000000000000..c6844d69fe47
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h
@@ -0,0 +1,237 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __REG_DBSCHEMA_H__
+#define __REG_DBSCHEMA_H__
+
+/*
+ * This file describes the regulatory DB schema, which is common between the
+ * 'generator' and 'parser'. The 'generator' runs on a host(typically a x86
+ * Linux) and spits outs two binary files, which follow the DB file
+ * format(described below). The resultant output "regulatoryData_AG.bin"
+ * is binary file which has information regarding A and G regulatory
+ * information, while the "regulatoryData_G.bin" consists of G-ONLY regulatory
+ * information. This binary file is parsed in the target for extracting
+ * regulatory information.
+ *
+ * The DB values used to populate the regulatory DB are defined in
+ * reg_dbvalues.h
+ *
+ */
+
+/* Binary data file - Representation of Regulatory DB*/
+#define REG_DATA_FILE_AG "./regulatoryData_AG.bin"
+#define REG_DATA_FILE_G "./regulatoryData_G.bin"
+
+
+/* Table tags used to encode different tables in the database */
+enum data_tags_t{
+ REG_DMN_PAIR_MAPPING_TAG = 0,
+ REG_COUNTRY_CODE_TO_ENUM_RD_TAG,
+ REG_DMN_FREQ_BAND_regDmn5GhzFreq_TAG,
+ REG_DMN_FREQ_BAND_regDmn2Ghz11_BG_Freq_TAG,
+ REG_DOMAIN_TAG,
+ MAX_DB_TABLE_TAGS
+ };
+
+
+
+/*
+ ****************************************************************************
+ * Regulatory DB file format :
+ * 4-bytes : "RGDB" (Magic Key)
+ * 4-bytes : version (Default is 5379(my extn))
+ * 4-bytes : length of file
+ * dbType(4)
+ * TAG(4)
+ * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
+ * TAG(4)
+ * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
+ * TAG(4)
+ * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
+ * ...
+ * ...
+ ****************************************************************************
+ *
+ */
+
+/*
+ * Length of the file would be filled in when the file is created and
+ * it would include the header size.
+ */
+
+#define REG_DB_KEY "RGDB" /* Should be EXACTLY 4-bytes */
+#define REG_DB_VER 7802 /* Between 0-9999 */
+/* REG_DB_VER history in reverse chronological order:
+ * 7802: 78 (ASCII code of N) + 02 (minor version number) - updated 10/21/09
+ * 7801: 78 (ASCII code of N) + 01 (minor version number, increment on further changes)
+ * 1178: '11N' = 11 + ASCII code of N(78)
+ * 5379: initial version, no 11N support
+ */
+#define MAGIC_KEY_OFFSET 0
+#define VERSION_OFFSET 4
+#define FILE_SZ_OFFSET 8
+#define DB_TYPE_OFFSET 12
+
+#define MAGIC_KEY_SZ 4
+#define VERSION_SZ 4
+#define FILE_SZ_SZ 4
+#define DB_TYPE_SZ 4
+#define DB_TAG_SZ 4
+
+#define REGDB_GET_MAGICKEY(x) ((char *)x + MAGIC_KEY_OFFSET)
+#define REGDB_GET_VERSION(x) ((char *)x + VERSION_OFFSET)
+#define REGDB_GET_FILESIZE(x) *((unsigned int *)((char *)x + FILE_SZ_OFFSET))
+#define REGDB_GET_DBTYPE(x) *((char *)x + DB_TYPE_OFFSET)
+
+#define REGDB_SET_FILESIZE(x, sz_) *((unsigned int *)((char *)x + FILE_SZ_OFFSET)) = (sz_)
+#define REGDB_IS_EOF(cur, begin) ( REGDB_GET_FILESIZE(begin) > ((cur) - (begin)) )
+
+
+/* A Table can be search based on key as a parameter or accessed directly
+ * by giving its index in to the table.
+ */
+enum searchType {
+ KEY_BASED_TABLE_SEARCH = 1,
+ INDEX_BASED_TABLE_ACCESS
+ };
+
+
+/* Data is organised as different tables. There is a Master table, which
+ * holds information regarding all the tables. It does not have any
+ * knowledge about the attributes of the table it is holding
+ * but has external view of the same(for ex, how many entries, record size,
+ * how to search the table, total table size and reference to the data
+ * instance of table).
+ */
+typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structures */
+ A_UCHAR numOfEntries;
+ A_CHAR entrySize; /* Entry size per table row */
+ A_CHAR searchType; /* Index based access or key based */
+ A_CHAR reserved[3]; /* for alignment */
+ A_UINT16 tableSize; /* Size of this table */
+ A_CHAR *dataPtr; /* Ptr to the actual Table */
+} POSTPACK dbMasterTable; /* Master table - table of tables */
+
+
+/* used to get the number of rows in a table */
+#define REGDB_NUM_OF_ROWS(a) (sizeof (a) / sizeof (a[0]))
+
+/*
+ * Used to set the RegDomain bitmask which chooses which frequency
+ * band specs are used.
+ */
+
+#define BMLEN 2 /* Use 2 32-bit uint for channel bitmask */
+#define BMZERO {0,0} /* BMLEN zeros */
+
+#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \
+ {((((_fa >= 0) && (_fa < 32)) ? (((A_UINT32) 1) << _fa) : 0) | \
+ (((_fb >= 0) && (_fb < 32)) ? (((A_UINT32) 1) << _fb) : 0) | \
+ (((_fc >= 0) && (_fc < 32)) ? (((A_UINT32) 1) << _fc) : 0) | \
+ (((_fd >= 0) && (_fd < 32)) ? (((A_UINT32) 1) << _fd) : 0) | \
+ (((_fe >= 0) && (_fe < 32)) ? (((A_UINT32) 1) << _fe) : 0) | \
+ (((_ff >= 0) && (_ff < 32)) ? (((A_UINT32) 1) << _ff) : 0) | \
+ (((_fg >= 0) && (_fg < 32)) ? (((A_UINT32) 1) << _fg) : 0) | \
+ (((_fh >= 0) && (_fh < 32)) ? (((A_UINT32) 1) << _fh) : 0)), \
+ ((((_fa > 31) && (_fa < 64)) ? (((A_UINT32) 1) << (_fa - 32)) : 0) | \
+ (((_fb > 31) && (_fb < 64)) ? (((A_UINT32) 1) << (_fb - 32)) : 0) | \
+ (((_fc > 31) && (_fc < 64)) ? (((A_UINT32) 1) << (_fc - 32)) : 0) | \
+ (((_fd > 31) && (_fd < 64)) ? (((A_UINT32) 1) << (_fd - 32)) : 0) | \
+ (((_fe > 31) && (_fe < 64)) ? (((A_UINT32) 1) << (_fe - 32)) : 0) | \
+ (((_ff > 31) && (_ff < 64)) ? (((A_UINT32) 1) << (_ff - 32)) : 0) | \
+ (((_fg > 31) && (_fg < 64)) ? (((A_UINT32) 1) << (_fg - 32)) : 0) | \
+ (((_fh > 31) && (_fh < 64)) ? (((A_UINT32) 1) << (_fh - 32)) : 0))}
+
+
+/*
+ * THE following table is the mapping of regdomain pairs specified by
+ * a regdomain value to the individual unitary reg domains
+ */
+
+typedef PREPACK struct reg_dmn_pair_mapping {
+ A_UINT16 regDmnEnum; /* 16 bit reg domain pair */
+ A_UINT16 regDmn5GHz; /* 5GHz reg domain */
+ A_UINT16 regDmn2GHz; /* 2GHz reg domain */
+ A_UINT8 flags5GHz; /* Requirements flags (AdHoc disallow etc) */
+ A_UINT8 flags2GHz; /* Requirements flags (AdHoc disallow etc) */
+ A_UINT32 pscanMask; /* Passive Scan flags which can override unitary domain passive scan
+ flags. This value is used as a mask on the unitary flags*/
+} POSTPACK REG_DMN_PAIR_MAPPING;
+
+#define OFDM_YES (1 << 0)
+#define OFDM_NO (0 << 0)
+#define MCS_HT20_YES (1 << 1)
+#define MCS_HT20_NO (0 << 1)
+#define MCS_HT40_A_YES (1 << 2)
+#define MCS_HT40_A_NO (0 << 2)
+#define MCS_HT40_G_YES (1 << 3)
+#define MCS_HT40_G_NO (0 << 3)
+
+typedef PREPACK struct {
+ A_UINT16 countryCode;
+ A_UINT16 regDmnEnum;
+ A_CHAR isoName[3];
+ A_CHAR allowMode; /* what mode is allowed - bit 0: OFDM; bit 1: MCS_HT20; bit 2: MCS_HT40_A; bit 3: MCS_HT40_G */
+} POSTPACK COUNTRY_CODE_TO_ENUM_RD;
+
+/* lower 16 bits of ht40ChanMask */
+#define NO_FREQ_HT40 0x0 /* no freq is HT40 capable */
+#define F1_TO_F4_HT40 0xF /* freq 1 to 4 in the block is ht40 capable */
+#define F2_TO_F3_HT40 0x6 /* freq 2 to 3 in the block is ht40 capable */
+#define F1_TO_F10_HT40 0x3FF /* freq 1 to 10 in the block is ht40 capable */
+#define F3_TO_F11_HT40 0x7FC /* freq 3 to 11 in the block is ht40 capable */
+#define F3_TO_F9_HT40 0x1FC /* freq 3 to 9 in the block is ht40 capable */
+#define F1_TO_F8_HT40 0xFF /* freq 1 to 8 in the block is ht40 capable */
+#define F1_TO_F4_F9_TO_F10_HT40 0x30F /* freq 1 to 4, 9 to 10 in the block is ht40 capable */
+
+/* upper 16 bits of ht40ChanMask */
+#define FREQ_HALF_RATE 0x10000
+#define FREQ_QUARTER_RATE 0x20000
+
+typedef PREPACK struct RegDmnFreqBand {
+ A_UINT16 lowChannel; /* Low channel center in MHz */
+ A_UINT16 highChannel; /* High Channel center in MHz */
+ A_UINT8 power; /* Max power (dBm) for channel range */
+ A_UINT8 channelSep; /* Channel separation within the band */
+ A_UINT8 useDfs; /* Use DFS in the RegDomain if corresponding bit is set */
+ A_UINT8 mode; /* Mode of operation */
+ A_UINT32 usePassScan; /* Use Passive Scan in the RegDomain if corresponding bit is set */
+ A_UINT32 ht40ChanMask; /* lower 16 bits: indicate which frequencies in the block is HT40 capable
+ upper 16 bits: what rate (half/quarter) the channel is */
+} POSTPACK REG_DMN_FREQ_BAND;
+
+
+
+typedef PREPACK struct regDomain {
+ A_UINT16 regDmnEnum; /* value from EnumRd table */
+ A_UINT8 rdCTL;
+ A_UINT8 maxAntGain;
+ A_UINT8 dfsMask; /* DFS bitmask for 5Ghz tables */
+ A_UINT8 flags; /* Requirement flags (AdHoc disallow etc) */
+ A_UINT16 reserved; /* for alignment */
+ A_UINT32 pscan; /* Bitmask for passive scan */
+ A_UINT32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */
+ A_UINT32 chan11bg[BMLEN];/* 64 bit bitmask for channel/band selection */
+} POSTPACK REG_DOMAIN;
+
+#endif /* __REG_DBSCHEMA_H__ */
diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h
new file mode 100644
index 000000000000..278f90346b5a
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h
@@ -0,0 +1,504 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+
+#ifndef __REG_DBVALUE_H__
+#define __REG_DBVALUE_H__
+
+/*
+ * Numbering from ISO 3166
+ */
+enum CountryCode {
+ CTRY_ALBANIA = 8, /* Albania */
+ CTRY_ALGERIA = 12, /* Algeria */
+ CTRY_ARGENTINA = 32, /* Argentina */
+ CTRY_ARMENIA = 51, /* Armenia */
+ CTRY_ARUBA = 533, /* Aruba */
+ CTRY_AUSTRALIA = 36, /* Australia (for STA) */
+ CTRY_AUSTRALIA_AP = 5000, /* Australia (for AP) */
+ CTRY_AUSTRIA = 40, /* Austria */
+ CTRY_AZERBAIJAN = 31, /* Azerbaijan */
+ CTRY_BAHRAIN = 48, /* Bahrain */
+ CTRY_BANGLADESH = 50, /* Bangladesh */
+ CTRY_BARBADOS = 52, /* Barbados */
+ CTRY_BELARUS = 112, /* Belarus */
+ CTRY_BELGIUM = 56, /* Belgium */
+ CTRY_BELIZE = 84, /* Belize */
+ CTRY_BOLIVIA = 68, /* Bolivia */
+ CTRY_BOSNIA_HERZEGOWANIA = 70, /* Bosnia & Herzegowania */
+ CTRY_BRAZIL = 76, /* Brazil */
+ CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
+ CTRY_BULGARIA = 100, /* Bulgaria */
+ CTRY_CAMBODIA = 116, /* Cambodia */
+ CTRY_CANADA = 124, /* Canada (for STA) */
+ CTRY_CANADA_AP = 5001, /* Canada (for AP) */
+ CTRY_CHILE = 152, /* Chile */
+ CTRY_CHINA = 156, /* People's Republic of China */
+ CTRY_COLOMBIA = 170, /* Colombia */
+ CTRY_COSTA_RICA = 188, /* Costa Rica */
+ CTRY_CROATIA = 191, /* Croatia */
+ CTRY_CYPRUS = 196,
+ CTRY_CZECH = 203, /* Czech Republic */
+ CTRY_DENMARK = 208, /* Denmark */
+ CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
+ CTRY_ECUADOR = 218, /* Ecuador */
+ CTRY_EGYPT = 818, /* Egypt */
+ CTRY_EL_SALVADOR = 222, /* El Salvador */
+ CTRY_ESTONIA = 233, /* Estonia */
+ CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
+ CTRY_FINLAND = 246, /* Finland */
+ CTRY_FRANCE = 250, /* France */
+ CTRY_FRANCE2 = 255, /* France2 */
+ CTRY_GEORGIA = 268, /* Georgia */
+ CTRY_GERMANY = 276, /* Germany */
+ CTRY_GREECE = 300, /* Greece */
+ CTRY_GREENLAND = 304, /* Greenland */
+ CTRY_GRENADA = 308, /* Grenada */
+ CTRY_GUAM = 316, /* Guam */
+ CTRY_GUATEMALA = 320, /* Guatemala */
+ CTRY_HAITI = 332, /* Haiti */
+ CTRY_HONDURAS = 340, /* Honduras */
+ CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
+ CTRY_HUNGARY = 348, /* Hungary */
+ CTRY_ICELAND = 352, /* Iceland */
+ CTRY_INDIA = 356, /* India */
+ CTRY_INDONESIA = 360, /* Indonesia */
+ CTRY_IRAN = 364, /* Iran */
+ CTRY_IRAQ = 368, /* Iraq */
+ CTRY_IRELAND = 372, /* Ireland */
+ CTRY_ISRAEL = 376, /* Israel */
+ CTRY_ITALY = 380, /* Italy */
+ CTRY_JAMAICA = 388, /* Jamaica */
+ CTRY_JAPAN = 392, /* Japan */
+ CTRY_JAPAN1 = 393, /* Japan (JP1) */
+ CTRY_JAPAN2 = 394, /* Japan (JP0) */
+ CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
+ CTRY_JAPAN4 = 396, /* Japan (JE1) */
+ CTRY_JAPAN5 = 397, /* Japan (JE2) */
+ CTRY_JAPAN6 = 399, /* Japan (JP6) */
+ CTRY_JORDAN = 400, /* Jordan */
+ CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
+ CTRY_KENYA = 404, /* Kenya */
+ CTRY_KOREA_NORTH = 408, /* North Korea */
+ CTRY_KOREA_ROC = 410, /* South Korea (for STA) */
+ CTRY_KOREA_ROC2 = 411, /* South Korea */
+ CTRY_KOREA_ROC3 = 412, /* South Korea (for AP) */
+ CTRY_KUWAIT = 414, /* Kuwait */
+ CTRY_LATVIA = 428, /* Latvia */
+ CTRY_LEBANON = 422, /* Lebanon */
+ CTRY_LIBYA = 434, /* Libya */
+ CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
+ CTRY_LITHUANIA = 440, /* Lithuania */
+ CTRY_LUXEMBOURG = 442, /* Luxembourg */
+ CTRY_MACAU = 446, /* Macau */
+ CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */
+ CTRY_MALAYSIA = 458, /* Malaysia */
+ CTRY_MALTA = 470, /* Malta */
+ CTRY_MEXICO = 484, /* Mexico */
+ CTRY_MONACO = 492, /* Principality of Monaco */
+ CTRY_MOROCCO = 504, /* Morocco */
+ CTRY_NEPAL = 524, /* Nepal */
+ CTRY_NETHERLANDS = 528, /* Netherlands */
+ CTRY_NETHERLAND_ANTILLES = 530, /* Netherlands-Antilles */
+ CTRY_NEW_ZEALAND = 554, /* New Zealand */
+ CTRY_NICARAGUA = 558, /* Nicaragua */
+ CTRY_NORWAY = 578, /* Norway */
+ CTRY_OMAN = 512, /* Oman */
+ CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
+ CTRY_PANAMA = 591, /* Panama */
+ CTRY_PARAGUAY = 600, /* Paraguay */
+ CTRY_PERU = 604, /* Peru */
+ CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
+ CTRY_POLAND = 616, /* Poland */
+ CTRY_PORTUGAL = 620, /* Portugal */
+ CTRY_PUERTO_RICO = 630, /* Puerto Rico */
+ CTRY_QATAR = 634, /* Qatar */
+ CTRY_ROMANIA = 642, /* Romania */
+ CTRY_RUSSIA = 643, /* Russia */
+ CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
+ CTRY_MONTENEGRO = 891, /* Montenegro */
+ CTRY_SINGAPORE = 702, /* Singapore */
+ CTRY_SLOVAKIA = 703, /* Slovak Republic */
+ CTRY_SLOVENIA = 705, /* Slovenia */
+ CTRY_SOUTH_AFRICA = 710, /* South Africa */
+ CTRY_SPAIN = 724, /* Spain */
+ CTRY_SRILANKA = 144, /* Sri Lanka */
+ CTRY_SWEDEN = 752, /* Sweden */
+ CTRY_SWITZERLAND = 756, /* Switzerland */
+ CTRY_SYRIA = 760, /* Syria */
+ CTRY_TAIWAN = 158, /* Taiwan */
+ CTRY_THAILAND = 764, /* Thailand */
+ CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
+ CTRY_TUNISIA = 788, /* Tunisia */
+ CTRY_TURKEY = 792, /* Turkey */
+ CTRY_UAE = 784, /* U.A.E. */
+ CTRY_UKRAINE = 804, /* Ukraine */
+ CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
+ CTRY_UNITED_STATES = 840, /* United States (for STA) */
+ CTRY_UNITED_STATES_AP = 841, /* United States (for AP) */
+ CTRY_UNITED_STATES_PS = 842, /* United States - public safety */
+ CTRY_URUGUAY = 858, /* Uruguay */
+ CTRY_UZBEKISTAN = 860, /* Uzbekistan */
+ CTRY_VENEZUELA = 862, /* Venezuela */
+ CTRY_VIET_NAM = 704, /* Viet Nam */
+ CTRY_YEMEN = 887, /* Yemen */
+ CTRY_ZIMBABWE = 716 /* Zimbabwe */
+};
+
+#define CTRY_DEBUG 0
+#define CTRY_DEFAULT 0x1ff
+
+/*
+ * The following regulatory domain definitions are
+ * found in the EEPROM. Each regulatory domain
+ * can operate in either a 5GHz or 2.4GHz wireless mode or
+ * both 5GHz and 2.4GHz wireless modes.
+ * In general, the value holds no special
+ * meaning and is used to decode into either specific
+ * 2.4GHz or 5GHz wireless mode for that particular
+ * regulatory domain.
+ *
+ * Enumerated Regulatory Domain Information 8 bit values indicate that
+ * the regdomain is really a pair of unitary regdomains. 12 bit values
+ * are the real unitary regdomains and are the only ones which have the
+ * frequency bitmasks and flags set.
+ */
+
+enum EnumRd {
+ NO_ENUMRD = 0x00,
+ NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
+ NULL1_ETSIB = 0x07, /* Israel */
+ NULL1_ETSIC = 0x08,
+
+ FCC1_FCCA = 0x10, /* USA */
+ FCC1_WORLD = 0x11, /* Hong Kong */
+ FCC2_FCCA = 0x20, /* Canada */
+ FCC2_WORLD = 0x21, /* Australia & HK */
+ FCC2_ETSIC = 0x22,
+ FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
+ FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
+ FCC4_FCCA = 0x12, /* FCC public safety plus UNII bands */
+ FCC5_FCCA = 0x13, /* US with no DFS */
+ FCC5_WORLD = 0x16, /* US with no DFS */
+ FCC6_FCCA = 0x14, /* Same as FCC2_FCCA but with 5600-5650MHz channels disabled for US & Canada APs */
+ FCC6_WORLD = 0x23, /* Same as FCC2_FCCA but with 5600-5650MHz channels disabled for Australia APs */
+
+ ETSI1_WORLD = 0x37,
+
+ ETSI2_WORLD = 0x35, /* Hungary & others */
+ ETSI3_WORLD = 0x36, /* France & others */
+ ETSI4_WORLD = 0x30,
+ ETSI4_ETSIC = 0x38,
+ ETSI5_WORLD = 0x39,
+ ETSI6_WORLD = 0x34, /* Bulgaria */
+ ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
+ FRANCE_RES = 0x31, /* Legacy France for OEM */
+
+ APL6_WORLD = 0x5B, /* Singapore */
+ APL4_WORLD = 0x42, /* Singapore */
+ APL3_FCCA = 0x50,
+ APL_RESERVED = 0x44, /* Reserved (Do not used) */
+ APL2_WORLD = 0x45, /* Korea */
+ APL2_APLC = 0x46,
+ APL3_WORLD = 0x47,
+ APL2_APLD = 0x49, /* Korea with 2.3G channels */
+ APL2_FCCA = 0x4D, /* Specific Mobile Customer */
+ APL1_WORLD = 0x52, /* Latin America */
+ APL1_FCCA = 0x53,
+ APL1_ETSIC = 0x55,
+ APL2_ETSIC = 0x56, /* Venezuela */
+ APL5_WORLD = 0x58, /* Chile */
+ APL7_FCCA = 0x5C,
+ APL8_WORLD = 0x5D,
+ APL9_WORLD = 0x5E,
+ APL10_WORLD = 0x5F, /* Korea 5GHz for STA */
+
+
+ MKK5_MKKA = 0x99, /* This is a temporary value. MG and DQ have to give official one */
+ MKK5_FCCA = 0x9A, /* This is a temporary value. MG and DQ have to give official one */
+ MKK5_MKKC = 0x88,
+ MKK11_MKKA = 0xD4,
+ MKK11_FCCA = 0xD5,
+ MKK11_MKKC = 0xD7,
+
+ /*
+ * World mode SKUs
+ */
+ WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
+ WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
+ WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
+ WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
+ WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
+ WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
+
+ WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
+ WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
+ EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
+
+ WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
+ WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
+ WORB_WORLD = 0x6B, /* WorldB (WOA SKU) */
+ WORC_WORLD = 0x6C, /* WorldC (WOA SKU) */
+
+ /*
+ * Regulator domains ending in a number (e.g. APL1,
+ * MK1, ETSI4, etc) apply to 5GHz channel and power
+ * information. Regulator domains ending in a letter
+ * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
+ * power information.
+ */
+ APL1 = 0x0150, /* LAT & Asia */
+ APL2 = 0x0250, /* LAT & Asia */
+ APL3 = 0x0350, /* Taiwan */
+ APL4 = 0x0450, /* Jordan */
+ APL5 = 0x0550, /* Chile */
+ APL6 = 0x0650, /* Singapore */
+ APL7 = 0x0750, /* Taiwan */
+ APL8 = 0x0850, /* Malaysia */
+ APL9 = 0x0950, /* Korea */
+ APL10 = 0x1050, /* Korea 5GHz */
+
+ ETSI1 = 0x0130, /* Europe & others */
+ ETSI2 = 0x0230, /* Europe & others */
+ ETSI3 = 0x0330, /* Europe & others */
+ ETSI4 = 0x0430, /* Europe & others */
+ ETSI5 = 0x0530, /* Europe & others */
+ ETSI6 = 0x0630, /* Europe & others */
+ ETSIB = 0x0B30, /* Israel */
+ ETSIC = 0x0C30, /* Latin America */
+
+ FCC1 = 0x0110, /* US & others */
+ FCC2 = 0x0120, /* Canada, Australia & New Zealand */
+ FCC3 = 0x0160, /* US w/new middle band & DFS */
+ FCC4 = 0x0165,
+ FCC5 = 0x0180,
+ FCC6 = 0x0610,
+ FCCA = 0x0A10,
+
+ APLD = 0x0D50, /* South Korea */
+
+ MKK1 = 0x0140, /* Japan */
+ MKK2 = 0x0240, /* Japan Extended */
+ MKK3 = 0x0340, /* Japan new 5GHz */
+ MKK4 = 0x0440, /* Japan new 5GHz */
+ MKK5 = 0x0540, /* Japan new 5GHz */
+ MKK6 = 0x0640, /* Japan new 5GHz */
+ MKK7 = 0x0740, /* Japan new 5GHz */
+ MKK8 = 0x0840, /* Japan new 5GHz */
+ MKK9 = 0x0940, /* Japan new 5GHz */
+ MKK10 = 0x1040, /* Japan new 5GHz */
+ MKK11 = 0x1140, /* Japan new 5GHz */
+ MKK12 = 0x1240, /* Japan new 5GHz */
+
+ MKKA = 0x0A40, /* Japan */
+ MKKC = 0x0A50,
+
+ NULL1 = 0x0198,
+ WORLD = 0x0199,
+ DEBUG_REG_DMN = 0x01ff,
+ UNINIT_REG_DMN = 0x0fff,
+};
+
+enum { /* conformance test limits */
+ FCC = 0x10,
+ MKK = 0x40,
+ ETSI = 0x30,
+ NO_CTL = 0xff,
+ CTL_11B = 1,
+ CTL_11G = 2
+};
+
+
+/*
+ * The following are flags for different requirements per reg domain.
+ * These requirements are either inhereted from the reg domain pair or
+ * from the unitary reg domain if the reg domain pair flags value is
+ * 0
+ */
+
+enum {
+ NO_REQ = 0x00,
+ DISALLOW_ADHOC_11A = 0x01,
+ ADHOC_PER_11D = 0x02,
+ ADHOC_NO_11A = 0x04,
+ DISALLOW_ADHOC_11G = 0x08
+};
+
+
+
+
+/*
+ * The following describe the bit masks for different passive scan
+ * capability/requirements per regdomain.
+ */
+#define NO_PSCAN 0x00000000
+#define PSCAN_FCC 0x00000001
+#define PSCAN_ETSI 0x00000002
+#define PSCAN_MKK 0x00000004
+#define PSCAN_ETSIB 0x00000008
+#define PSCAN_ETSIC 0x00000010
+#define PSCAN_WWR 0x00000020
+#define PSCAN_DEFER 0xFFFFFFFF
+
+/* Bit masks for DFS per regdomain */
+
+enum {
+ NO_DFS = 0x00,
+ DFS_FCC3 = 0x01,
+ DFS_ETSI = 0x02,
+ DFS_MKK = 0x04
+};
+
+
+#define DEF_REGDMN FCC1_FCCA
+
+/*
+ * The following table is the master list for all different freqeuncy
+ * bands with the complete matrix of all possible flags and settings
+ * for each band if it is used in ANY reg domain.
+ *
+ * The table of frequency bands is indexed by a bitmask. The ordering
+ * must be consistent with the enum below. When adding a new
+ * frequency band, be sure to match the location in the enum with the
+ * comments
+ */
+
+/*
+ * These frequency values are as per channel tags and regulatory domain
+ * info. Please update them as database is updated.
+ */
+#define A_FREQ_MIN 4920
+#define A_FREQ_MAX 5825
+
+#define A_CHAN0_FREQ 5000
+#define A_CHAN_MAX ((A_FREQ_MAX - A_CHAN0_FREQ)/5)
+
+#define BG_FREQ_MIN 2412
+#define BG_FREQ_MAX 2484
+
+#define BG_CHAN0_FREQ 2407
+#define BG_CHAN_MIN ((BG_FREQ_MIN - BG_CHAN0_FREQ)/5)
+#define BG_CHAN_MAX 14 /* corresponding to 2484 MHz */
+
+#define A_20MHZ_BAND_FREQ_MAX 5000
+
+
+/*
+ * 5GHz 11A channel tags
+ */
+
+enum {
+ F1_4920_4980,
+ F1_5040_5080,
+
+ F1_5120_5240,
+
+ F1_5180_5240,
+ F2_5180_5240,
+ F3_5180_5240,
+ F4_5180_5240,
+ F5_5180_5240,
+ F6_5180_5240,
+ F7_5180_5240,
+
+ 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_5620,
+
+ F1_5500_5700,
+ F2_5500_5700,
+ F3_5500_5700,
+ F4_5500_5700,
+ F5_5500_5700,
+ F6_5500_5700,
+ F7_5500_5700,
+
+ F1_5745_5805,
+ F2_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,
+};
+
+
+/* 2.4 GHz table - for 11b and 11g info */
+enum {
+ BG1_2312_2372,
+ BG2_2312_2372,
+
+ BG1_2412_2472,
+ BG2_2412_2472,
+ BG3_2412_2472,
+ BG4_2412_2472,
+
+ BG1_2412_2462,
+ BG2_2412_2462,
+
+ BG1_2432_2442,
+
+ BG1_2457_2472,
+
+ BG1_2467_2472,
+
+ BG1_2484_2484, /* No G */
+ BG2_2484_2484, /* No G */
+
+ BG1_2512_2732,
+
+ WBG1_2312_2372,
+ WBG1_2412_2412,
+ WBG1_2417_2432,
+ WBG1_2437_2442,
+ WBG1_2447_2457,
+ WBG1_2462_2462,
+ WBG1_2467_2467,
+ WBG2_2467_2467,
+ WBG1_2472_2472,
+ WBG2_2472_2472,
+ WBG1_2484_2484, /* No G */
+ WBG2_2484_2484, /* No G */
+};
+
+#endif /* __REG_DBVALUE_H__ */
diff --git a/drivers/staging/ath6kl/include/common/roaming.h b/drivers/staging/ath6kl/include/common/roaming.h
new file mode 100644
index 000000000000..8019850a0571
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/roaming.h
@@ -0,0 +1,41 @@
+//------------------------------------------------------------------------------
+// <copyright file="roaming.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef _ROAMING_H_
+#define _ROAMING_H_
+
+/*
+ * The signal quality could be in terms of either snr or rssi. We should
+ * have an enum for both of them. For the time being, we are going to move
+ * it to wmi.h that is shared by both host and the target, since we are
+ * repartitioning the code to the host
+ */
+#define SIGNAL_QUALITY_NOISE_FLOOR -96
+#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
+typedef enum {
+ SIGNAL_QUALITY_METRICS_SNR = 0,
+ SIGNAL_QUALITY_METRICS_RSSI,
+ SIGNAL_QUALITY_METRICS_ALL,
+} SIGNAL_QUALITY_METRICS_TYPE;
+
+#endif /* _ROAMING_H_ */
diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h
new file mode 100644
index 000000000000..e8cf70354d21
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/targaddrs.h
@@ -0,0 +1,245 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef __TARGADDRS_H__
+#define __TARGADDRS_H__
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#if defined(AR6002)
+#include "AR6002/addrs.h"
+#endif
+
+/*
+ * AR6K option bits, to enable/disable various features.
+ * By default, all option bits are 0.
+ * These bits can be set in LOCAL_SCRATCH register 0.
+ */
+#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */
+#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */
+#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */
+#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */
+#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */
+#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */
+#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */
+#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */
+
+/*
+ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
+ * host_interest structure. It must match the address of the _host_interest
+ * symbol (see linker script).
+ *
+ * Host Interest is shared between Host and Target in order to coordinate
+ * between the two, and is intended to remain constant (with additions only
+ * at the end) across software releases.
+ *
+ * All addresses are available here so that it's possible to
+ * write a single binary that works with all Target Types.
+ * May be used in assembler code as well as C.
+ */
+#define AR6002_HOST_INTEREST_ADDRESS 0x00500400
+#define AR6003_HOST_INTEREST_ADDRESS 0x00540600
+
+
+#define HOST_INTEREST_MAX_SIZE 0x100
+
+#if !defined(__ASSEMBLER__)
+struct register_dump_s;
+struct dbglog_hdr_s;
+
+/*
+ * These are items that the Host may need to access
+ * via BMI or via the Diagnostic Window. The position
+ * of items in this structure must remain constant
+ * across firmware revisions!
+ *
+ * Types for each item must be fixed size across
+ * target and host platforms.
+ *
+ * More items may be added at the end.
+ */
+PREPACK struct host_interest_s {
+ /*
+ * Pointer to application-defined area, if any.
+ * Set by Target application during startup.
+ */
+ A_UINT32 hi_app_host_interest; /* 0x00 */
+
+ /* Pointer to register dump area, valid after Target crash. */
+ A_UINT32 hi_failure_state; /* 0x04 */
+
+ /* Pointer to debug logging header */
+ A_UINT32 hi_dbglog_hdr; /* 0x08 */
+
+ /* Indicates whether or not flash is present on Target.
+ * NB: flash_is_present indicator is here not just
+ * because it might be of interest to the Host; but
+ * also because it's set early on by Target's startup
+ * asm code and we need it to have a special RAM address
+ * so that it doesn't get reinitialized with the rest
+ * of data.
+ */
+ A_UINT32 hi_flash_is_present; /* 0x0c */
+
+ /*
+ * General-purpose flag bits, similar to AR6000_OPTION_* flags.
+ * Can be used by application rather than by OS.
+ */
+ A_UINT32 hi_option_flag; /* 0x10 */
+
+ /*
+ * Boolean that determines whether or not to
+ * display messages on the serial port.
+ */
+ A_UINT32 hi_serial_enable; /* 0x14 */
+
+ /* Start address of Flash DataSet index, if any */
+ A_UINT32 hi_dset_list_head; /* 0x18 */
+
+ /* Override Target application start address */
+ A_UINT32 hi_app_start; /* 0x1c */
+
+ /* Clock and voltage tuning */
+ A_UINT32 hi_skip_clock_init; /* 0x20 */
+ A_UINT32 hi_core_clock_setting; /* 0x24 */
+ A_UINT32 hi_cpu_clock_setting; /* 0x28 */
+ A_UINT32 hi_system_sleep_setting; /* 0x2c */
+ A_UINT32 hi_xtal_control_setting; /* 0x30 */
+ A_UINT32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
+ A_UINT32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
+ A_UINT32 hi_ref_voltage_trim_setting; /* 0x3c */
+ A_UINT32 hi_clock_info; /* 0x40 */
+
+ /*
+ * Flash configuration overrides, used only
+ * when firmware is not executing from flash.
+ * (When using flash, modify the global variables
+ * with equivalent names.)
+ */
+ A_UINT32 hi_bank0_addr_value; /* 0x44 */
+ A_UINT32 hi_bank0_read_value; /* 0x48 */
+ A_UINT32 hi_bank0_write_value; /* 0x4c */
+ A_UINT32 hi_bank0_config_value; /* 0x50 */
+
+ /* Pointer to Board Data */
+ A_UINT32 hi_board_data; /* 0x54 */
+ A_UINT32 hi_board_data_initialized; /* 0x58 */
+
+ A_UINT32 hi_dset_RAM_index_table; /* 0x5c */
+
+ A_UINT32 hi_desired_baud_rate; /* 0x60 */
+ A_UINT32 hi_dbglog_config; /* 0x64 */
+ A_UINT32 hi_end_RAM_reserve_sz; /* 0x68 */
+ A_UINT32 hi_mbox_io_block_sz; /* 0x6c */
+
+ A_UINT32 hi_num_bpatch_streams; /* 0x70 -- unused */
+ A_UINT32 hi_mbox_isr_yield_limit; /* 0x74 */
+
+ A_UINT32 hi_refclk_hz; /* 0x78 */
+ A_UINT32 hi_ext_clk_detected; /* 0x7c */
+ A_UINT32 hi_dbg_uart_txpin; /* 0x80 */
+ A_UINT32 hi_dbg_uart_rxpin; /* 0x84 */
+ A_UINT32 hi_hci_uart_baud; /* 0x88 */
+ A_UINT32 hi_hci_uart_pin_assignments; /* 0x8C */
+ /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */
+ A_UINT32 hi_hci_uart_baud_scale_val; /* 0x90 */
+ A_UINT32 hi_hci_uart_baud_step_val; /* 0x94 */
+
+ A_UINT32 hi_allocram_start; /* 0x98 */
+ A_UINT32 hi_allocram_sz; /* 0x9c */
+ A_UINT32 hi_hci_bridge_flags; /* 0xa0 */
+ A_UINT32 hi_hci_uart_support_pins; /* 0xa4 */
+ /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */
+ A_UINT32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
+ /* 0xa8 - [0]: 1 = enable, 0 = disable
+ * [1]: 0 = UART FC active low, 1 = UART FC active high
+ * 0xa9 - [7:0]: wakeup timeout in ms
+ * 0xaa, 0xab - [15:0]: idle timeout in ms
+ */
+ /* Pointer to extended board Data */
+ A_UINT32 hi_board_ext_data; /* 0xac */
+ A_UINT32 hi_board_ext_data_initialized; /* 0xb0 */
+} POSTPACK;
+
+/* Bits defined in hi_option_flag */
+#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */
+#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */
+#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */
+#define HI_OPTION_FW_MODE_LSB 0x08 /* low bit of MODE (see below) */
+#define HI_OPTION_FW_MODE_MSB 0x10 /* high bit of MODE (see below) */
+#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */
+#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */
+#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */
+#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */
+
+/* 2 bits of hi_option_flag are used to represent 3 modes */
+#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */
+#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
+#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */
+
+/* Fw Mode Mask */
+#define HI_OPTION_FW_MODE_MASK 0x3
+#define HI_OPTION_FW_MODE_SHIFT 0x3
+
+/*
+ * Intended for use by Host software, this macro returns the Target RAM
+ * address of any item in the host_interest structure.
+ * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data);
+ */
+#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \
+ (A_UINT32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item)))
+
+#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \
+ (A_UINT32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item)))
+
+#define HOST_INTEREST_DBGLOG_IS_ENABLED() \
+ (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG))
+
+#define HOST_INTEREST_PROFILE_IS_ENABLED() \
+ (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE)
+
+/* Convert a Target virtual address into a Target physical address */
+#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff)
+#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
+#define TARG_VTOP(TargetType, vaddr) \
+ (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr))
+
+/* override REV2 ROM's app start address */
+#define AR6002_REV2_APP_START_OVERRIDE 0x911A00
+#define AR6003_REV1_APP_START_OVERRIDE 0x944c00
+#define AR6003_REV1_OTP_DATA_ADDRESS 0x542800
+#define AR6003_REV2_APP_START_OVERRIDE 0x945000
+#define AR6003_REV2_OTP_DATA_ADDRESS 0x543800
+#define AR6003_BOARD_EXT_DATA_ADDRESS 0x57E600
+
+
+/* # of A_UINT32 entries in targregs, used by DIAG_FETCH_TARG_REGS */
+#define AR6003_FETCH_TARG_REGS_COUNT 64
+
+#endif /* !__ASSEMBLER__ */
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#endif /* __TARGADDRS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h
new file mode 100644
index 000000000000..d6616f0fab7d
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/testcmd.h
@@ -0,0 +1,185 @@
+//------------------------------------------------------------------------------
+// <copyright file="testcmd.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef TESTCMD_H_
+#define TESTCMD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef AR6002_REV2
+#define TCMD_MAX_RATES 12
+#else
+#define TCMD_MAX_RATES 28
+#endif
+
+typedef enum {
+ ZEROES_PATTERN = 0,
+ ONES_PATTERN,
+ REPEATING_10,
+ PN7_PATTERN,
+ PN9_PATTERN,
+ PN15_PATTERN
+}TX_DATA_PATTERN;
+
+/* Continous tx
+ mode : TCMD_CONT_TX_OFF - Disabling continous tx
+ TCMD_CONT_TX_SINE - Enable continuous unmodulated tx
+ TCMD_CONT_TX_FRAME- Enable continuous modulated tx
+ freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g)
+dataRate: 0 - 1 Mbps
+ 1 - 2 Mbps
+ 2 - 5.5 Mbps
+ 3 - 11 Mbps
+ 4 - 6 Mbps
+ 5 - 9 Mbps
+ 6 - 12 Mbps
+ 7 - 18 Mbps
+ 8 - 24 Mbps
+ 9 - 36 Mbps
+ 10 - 28 Mbps
+ 11 - 54 Mbps
+ txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx
+antenna: 1 - one antenna
+ 2 - two antenna
+Note : Enable/disable continuous tx test cmd works only when target is awake.
+*/
+
+typedef enum {
+ TCMD_CONT_TX_OFF = 0,
+ TCMD_CONT_TX_SINE,
+ TCMD_CONT_TX_FRAME,
+ TCMD_CONT_TX_TX99,
+ TCMD_CONT_TX_TX100
+} TCMD_CONT_TX_MODE;
+
+typedef enum {
+ TCMD_WLAN_MODE_NOHT = 0,
+ TCMD_WLAN_MODE_HT20 = 1,
+ TCMD_WLAN_MODE_HT40PLUS = 2,
+ TCMD_WLAN_MODE_HT40MINUS = 3,
+} TCMD_WLAN_MODE;
+
+typedef PREPACK struct {
+ A_UINT32 testCmdId;
+ A_UINT32 mode;
+ A_UINT32 freq;
+ A_UINT32 dataRate;
+ A_INT32 txPwr;
+ A_UINT32 antenna;
+ A_UINT32 enANI;
+ A_UINT32 scramblerOff;
+ A_UINT32 aifsn;
+ A_UINT16 pktSz;
+ A_UINT16 txPattern;
+ A_UINT32 shortGuard;
+ A_UINT32 numPackets;
+ A_UINT32 wlanMode;
+} POSTPACK TCMD_CONT_TX;
+
+#define TCMD_TXPATTERN_ZERONE 0x1
+#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE 0x2
+
+/* Continuous Rx
+ act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames)
+ TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest
+ address equal specified
+ mac address (set via act =3)
+ TCMD_CONT_RX_REPORT off mode (disable cont rx mode and get the
+ report from the last cont
+ Rx test)
+
+ TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the
+ target. This Overrides
+ the default MAC address.)
+
+*/
+typedef enum {
+ TCMD_CONT_RX_PROMIS =0,
+ TCMD_CONT_RX_FILTER,
+ TCMD_CONT_RX_REPORT,
+ TCMD_CONT_RX_SETMAC,
+ TCMD_CONT_RX_SET_ANT_SWITCH_TABLE
+} TCMD_CONT_RX_ACT;
+
+typedef PREPACK struct {
+ A_UINT32 testCmdId;
+ A_UINT32 act;
+ A_UINT32 enANI;
+ PREPACK union {
+ struct PREPACK TCMD_CONT_RX_PARA {
+ A_UINT32 freq;
+ A_UINT32 antenna;
+ A_UINT32 wlanMode;
+ } POSTPACK para;
+ struct PREPACK TCMD_CONT_RX_REPORT {
+ A_UINT32 totalPkt;
+ A_INT32 rssiInDBm;
+ A_UINT32 crcErrPkt;
+ A_UINT32 secErrPkt;
+ A_UINT16 rateCnt[TCMD_MAX_RATES];
+ A_UINT16 rateCntShortGuard[TCMD_MAX_RATES];
+ } POSTPACK report;
+ struct PREPACK TCMD_CONT_RX_MAC {
+ A_UCHAR addr[ATH_MAC_LEN];
+ } POSTPACK mac;
+ struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE {
+ A_UINT32 antswitch1;
+ A_UINT32 antswitch2;
+ }POSTPACK antswitchtable;
+ } POSTPACK u;
+} POSTPACK TCMD_CONT_RX;
+
+/* Force sleep/wake test cmd
+ mode: TCMD_PM_WAKEUP - Wakeup the target
+ TCMD_PM_SLEEP - Force the target to sleep.
+ */
+typedef enum {
+ TCMD_PM_WAKEUP = 1, /* be consistent with target */
+ TCMD_PM_SLEEP,
+ TCMD_PM_DEEPSLEEP
+} TCMD_PM_MODE;
+
+typedef PREPACK struct {
+ A_UINT32 testCmdId;
+ A_UINT32 mode;
+} POSTPACK TCMD_PM;
+
+typedef enum {
+ TCMD_CONT_TX_ID,
+ TCMD_CONT_RX_ID,
+ TCMD_PM_ID
+} TCMD_ID;
+
+typedef PREPACK union {
+ TCMD_CONT_TX contTx;
+ TCMD_CONT_RX contRx;
+ TCMD_PM pm;
+} POSTPACK TEST_CMD;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TESTCMD_H_ */
diff --git a/drivers/staging/ath6kl/include/common/tlpm.h b/drivers/staging/ath6kl/include/common/tlpm.h
new file mode 100644
index 000000000000..659b1c07ba90
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/tlpm.h
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __TLPM_H__
+#define __TLPM_H__
+
+/* idle timeout in 16-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
+#define TLPM_DEFAULT_IDLE_TIMEOUT_MS 1000
+/* hex in LSB and MSB for HCI command */
+#define TLPM_DEFAULT_IDLE_TIMEOUT_LSB 0xE8
+#define TLPM_DEFAULT_IDLE_TIMEOUT_MSB 0x3
+
+/* wakeup timeout in 8-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */
+#define TLPM_DEFAULT_WAKEUP_TIMEOUT_MS 10
+
+/* default UART FC polarity is low */
+#define TLPM_DEFAULT_UART_FC_POLARITY 0
+
+#endif
diff --git a/drivers/staging/ath6kl/include/common/wlan_defs.h b/drivers/staging/ath6kl/include/common/wlan_defs.h
new file mode 100644
index 000000000000..03e4d23788ce
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wlan_defs.h
@@ -0,0 +1,79 @@
+//------------------------------------------------------------------------------
+// <copyright file="wlan_defs.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef __WLAN_DEFS_H__
+#define __WLAN_DEFS_H__
+
+/*
+ * This file contains WLAN definitions that may be used across both
+ * Host and Target software.
+ */
+
+typedef enum {
+ MODE_11A = 0, /* 11a Mode */
+ MODE_11G = 1, /* 11b/g Mode */
+ MODE_11B = 2, /* 11b Mode */
+ MODE_11GONLY = 3, /* 11g only Mode */
+#ifdef SUPPORT_11N
+ MODE_11NA_HT20 = 4, /* 11a HT20 mode */
+ MODE_11NG_HT20 = 5, /* 11g HT20 mode */
+ MODE_11NA_HT40 = 6, /* 11a HT40 mode */
+ MODE_11NG_HT40 = 7, /* 11g HT40 mode */
+ MODE_UNKNOWN = 8,
+ MODE_MAX = 8
+#else
+ MODE_UNKNOWN = 4,
+ MODE_MAX = 4
+#endif
+} WLAN_PHY_MODE;
+
+typedef enum {
+ WLAN_11A_CAPABILITY = 1,
+ WLAN_11G_CAPABILITY = 2,
+ WLAN_11AG_CAPABILITY = 3,
+}WLAN_CAPABILITY;
+
+#ifdef SUPPORT_11N
+typedef unsigned long A_RATEMASK;
+#else
+typedef unsigned short A_RATEMASK;
+#endif
+
+#ifdef SUPPORT_11N
+#define IS_MODE_11A(mode) (((mode) == MODE_11A) || \
+ ((mode) == MODE_11NA_HT20) || \
+ ((mode) == MODE_11NA_HT40))
+#define IS_MODE_11B(mode) ((mode) == MODE_11B)
+#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
+ ((mode) == MODE_11GONLY) || \
+ ((mode) == MODE_11NG_HT20) || \
+ ((mode) == MODE_11NG_HT40))
+#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
+#else
+#define IS_MODE_11A(mode) ((mode) == MODE_11A)
+#define IS_MODE_11B(mode) ((mode) == MODE_11B)
+#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \
+ ((mode) == MODE_11GONLY))
+#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY)
+#endif /* SUPPORT_11N */
+
+#endif /* __WLANDEFS_H__ */
diff --git a/drivers/staging/ath6kl/include/common/wlan_dset.h b/drivers/staging/ath6kl/include/common/wlan_dset.h
new file mode 100644
index 000000000000..864a60cedf10
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wlan_dset.h
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef __WLAN_DSET_H__
+#define __WLAN_DSET_H__
+
+typedef PREPACK struct wow_config_dset {
+
+ A_UINT8 valid_dset;
+ A_UINT8 gpio_enable;
+ A_UINT16 gpio_pin;
+} POSTPACK WOW_CONFIG_DSET;
+
+#endif
diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h
new file mode 100644
index 000000000000..c75d310c37a7
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wmi.h
@@ -0,0 +1,3119 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+/*
+ * This file contains the definitions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI). It includes definitions of all the
+ * commands and events. Commands are messages from the host to the WM.
+ * Events and Replies are messages from the WM to the host.
+ *
+ * Ownership of correctness in regards to commands
+ * belongs to the host driver and the WMI is not required to validate
+ * parameters for value, proper range, or any other checking.
+ *
+ */
+
+#ifndef _WMI_H_
+#define _WMI_H_
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#include "wmix.h"
+#include "wlan_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HTC_PROTOCOL_VERSION 0x0002
+#define HTC_PROTOCOL_REVISION 0x0000
+
+#define WMI_PROTOCOL_VERSION 0x0002
+#define WMI_PROTOCOL_REVISION 0x0000
+
+#define ATH_MAC_LEN 6 /* length of mac in bytes */
+#define WMI_CMD_MAX_LEN 100
+#define WMI_CONTROL_MSG_MAX_LEN 256
+#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536
+#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600)
+#define RFC1042OUI {0x00, 0x00, 0x00}
+
+#define IP_ETHERTYPE 0x0800
+
+#define WMI_IMPLICIT_PSTREAM 0xFF
+#define WMI_MAX_THINSTREAM 15
+
+#ifdef AR6002_REV2
+#define IBSS_MAX_NUM_STA 4
+#else
+#define IBSS_MAX_NUM_STA 8
+#endif
+
+PREPACK struct host_app_area_s {
+ A_UINT32 wmi_protocol_ver;
+} POSTPACK;
+
+/*
+ * Data Path
+ */
+typedef PREPACK struct {
+ A_UINT8 dstMac[ATH_MAC_LEN];
+ A_UINT8 srcMac[ATH_MAC_LEN];
+ A_UINT16 typeOrLen;
+} POSTPACK ATH_MAC_HDR;
+
+typedef PREPACK struct {
+ A_UINT8 dsap;
+ A_UINT8 ssap;
+ A_UINT8 cntl;
+ A_UINT8 orgCode[3];
+ A_UINT16 etherType;
+} POSTPACK ATH_LLC_SNAP_HDR;
+
+typedef enum {
+ DATA_MSGTYPE = 0x0,
+ CNTL_MSGTYPE,
+ SYNC_MSGTYPE,
+ OPT_MSGTYPE,
+} WMI_MSG_TYPE;
+
+
+/*
+ * Macros for operating on WMI_DATA_HDR (info) field
+ */
+
+#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
+#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
+#define WMI_DATA_HDR_UP_MASK 0x07
+#define WMI_DATA_HDR_UP_SHIFT 2
+/* In AP mode, the same bit (b5) is used to indicate Power save state in
+ * the Rx dir and More data bit state in the tx direction.
+ */
+#define WMI_DATA_HDR_PS_MASK 0x1
+#define WMI_DATA_HDR_PS_SHIFT 5
+
+#define WMI_DATA_HDR_MORE_MASK 0x1
+#define WMI_DATA_HDR_MORE_SHIFT 5
+
+typedef enum {
+ WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
+ WMI_DATA_HDR_DATA_TYPE_802_11,
+ WMI_DATA_HDR_DATA_TYPE_ACL,
+} WMI_DATA_HDR_DATA_TYPE;
+
+#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
+#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
+
+#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT))
+
+#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t))
+#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT))
+#define WMI_DATA_HDR_GET_UP(h) (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK)
+#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT))
+
+#define WMI_DATA_HDR_GET_DATA_TYPE(h) (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK)
+#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT))
+
+#define WMI_DATA_HDR_GET_DOT11(h) (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11)
+#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p))
+
+/* Macros for operating on WMI_DATA_HDR (info2) field */
+#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
+#define WMI_DATA_HDR_SEQNO_SHIFT 0
+
+#define WMI_DATA_HDR_AMSDU_MASK 0x1
+#define WMI_DATA_HDR_AMSDU_SHIFT 12
+
+#define WMI_DATA_HDR_META_MASK 0x7
+#define WMI_DATA_HDR_META_SHIFT 13
+
+#define GET_SEQ_NO(_v) ((_v) & WMI_DATA_HDR_SEQNO_MASK)
+#define GET_ISMSDU(_v) ((_v) & WMI_DATA_HDR_AMSDU_MASK)
+
+#define WMI_DATA_HDR_GET_SEQNO(h) GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT)
+#define WMI_DATA_HDR_SET_SEQNO(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT))
+
+#define WMI_DATA_HDR_IS_AMSDU(h) GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT)
+#define WMI_DATA_HDR_SET_AMSDU(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT))
+
+#define WMI_DATA_HDR_GET_META(h) (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK)
+#define WMI_DATA_HDR_SET_META(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT))
+
+typedef PREPACK struct {
+ A_INT8 rssi;
+ A_UINT8 info; /* usage of 'info' field(8-bit):
+ * b1:b0 - WMI_MSG_TYPE
+ * b4:b3:b2 - UP(tid)
+ * b5 - Used in AP mode. More-data in tx dir, PS in rx.
+ * b7:b6 - Dot3 header(0),
+ * Dot11 Header(1),
+ * ACL data(2)
+ */
+
+ A_UINT16 info2; /* usage of 'info2' field(16-bit):
+ * b11:b0 - seq_no
+ * b12 - A-MSDU?
+ * b15:b13 - META_DATA_VERSION 0 - 7
+ */
+ A_UINT16 reserved;
+} POSTPACK WMI_DATA_HDR;
+
+/*
+ * TX META VERSION DEFINITIONS
+ */
+#define WMI_MAX_TX_META_SZ (12)
+#define WMI_MAX_TX_META_VERSION (7)
+#define WMI_META_VERSION_1 (0x01)
+#define WMI_META_VERSION_2 (0X02)
+
+#define WMI_ACL_TO_DOT11_HEADROOM 36
+
+#if 0 /* removed to prevent compile errors for WM.. */
+typedef PREPACK struct {
+/* intentionally empty. Default version is no meta data. */
+} POSTPACK WMI_TX_META_V0;
+#endif
+
+typedef PREPACK struct {
+ A_UINT8 pktID; /* The packet ID to identify the tx request */
+ A_UINT8 ratePolicyID; /* The rate policy to be used for the tx of this frame */
+} POSTPACK WMI_TX_META_V1;
+
+
+#define WMI_CSUM_DIR_TX (0x1)
+#define TX_CSUM_CALC_FILL (0x1)
+typedef PREPACK struct {
+ A_UINT8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */
+ A_UINT8 csumDest; /*Offset from start of WMI header where final csum goes*/
+ A_UINT8 csumFlags; /*number of bytes over which csum is calculated*/
+} POSTPACK WMI_TX_META_V2;
+
+
+/*
+ * RX META VERSION DEFINITIONS
+ */
+/* if RX meta data is present at all then the meta data field
+ * will consume WMI_MAX_RX_META_SZ bytes of space between the
+ * WMI_DATA_HDR and the payload. How much of the available
+ * Meta data is actually used depends on which meta data
+ * version is active. */
+#define WMI_MAX_RX_META_SZ (12)
+#define WMI_MAX_RX_META_VERSION (7)
+
+#define WMI_RX_STATUS_OK 0 /* success */
+#define WMI_RX_STATUS_DECRYPT_ERR 1 /* decrypt error */
+#define WMI_RX_STATUS_MIC_ERR 2 /* tkip MIC error */
+#define WMI_RX_STATUS_ERR 3 /* undefined error */
+
+#define WMI_RX_FLAGS_AGGR 0x0001 /* part of AGGR */
+#define WMI_RX_FlAGS_STBC 0x0002 /* used STBC */
+#define WMI_RX_FLAGS_SGI 0x0004 /* used SGI */
+#define WMI_RX_FLAGS_HT 0x0008 /* is HT packet */
+/* the flags field is also used to store the CRYPTO_TYPE of the frame
+ * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */
+#define WMI_RX_FLAGS_CRYPTO_SHIFT 4
+#define WMI_RX_FLAGS_CRYPTO_MASK 0x1f
+#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK)
+
+#if 0 /* removed to prevent compile errors for WM.. */
+typedef PREPACK struct {
+/* intentionally empty. Default version is no meta data. */
+} POSTPACK WMI_RX_META_VERSION_0;
+#endif
+
+typedef PREPACK struct {
+ A_UINT8 status; /* one of WMI_RX_STATUS_... */
+ A_UINT8 rix; /* rate index mapped to rate at which this packet was received. */
+ A_UINT8 rssi; /* rssi of packet */
+ A_UINT8 channel;/* rf channel during packet reception */
+ A_UINT16 flags; /* a combination of WMI_RX_FLAGS_... */
+} POSTPACK WMI_RX_META_V1;
+
+#define RX_CSUM_VALID_FLAG (0x1)
+typedef PREPACK struct {
+ A_UINT16 csum;
+ A_UINT8 csumFlags;/* bit 0 set -partial csum valid
+ bit 1 set -test mode */
+} POSTPACK WMI_RX_META_V2;
+
+
+
+#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
+
+/*
+ * Control Path
+ */
+typedef PREPACK struct {
+ A_UINT16 commandId;
+/*
+ * info1 - 16 bits
+ * b03:b00 - id
+ * b15:b04 - unused
+ */
+ A_UINT16 info1;
+
+ A_UINT16 reserved; /* For alignment */
+} POSTPACK WMI_CMD_HDR; /* used for commands and events */
+
+/*
+ * List of Commnands
+ */
+typedef enum {
+ WMI_CONNECT_CMDID = 0x0001,
+ WMI_RECONNECT_CMDID,
+ WMI_DISCONNECT_CMDID,
+ WMI_SYNCHRONIZE_CMDID,
+ WMI_CREATE_PSTREAM_CMDID,
+ WMI_DELETE_PSTREAM_CMDID,
+ WMI_START_SCAN_CMDID,
+ WMI_SET_SCAN_PARAMS_CMDID,
+ WMI_SET_BSS_FILTER_CMDID,
+ WMI_SET_PROBED_SSID_CMDID, /* 10 */
+ WMI_SET_LISTEN_INT_CMDID,
+ WMI_SET_BMISS_TIME_CMDID,
+ WMI_SET_DISC_TIMEOUT_CMDID,
+ WMI_GET_CHANNEL_LIST_CMDID,
+ WMI_SET_BEACON_INT_CMDID,
+ WMI_GET_STATISTICS_CMDID,
+ WMI_SET_CHANNEL_PARAMS_CMDID,
+ WMI_SET_POWER_MODE_CMDID,
+ WMI_SET_IBSS_PM_CAPS_CMDID,
+ WMI_SET_POWER_PARAMS_CMDID, /* 20 */
+ WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
+ WMI_ADD_CIPHER_KEY_CMDID,
+ WMI_DELETE_CIPHER_KEY_CMDID,
+ WMI_ADD_KRK_CMDID,
+ WMI_DELETE_KRK_CMDID,
+ WMI_SET_PMKID_CMDID,
+ WMI_SET_TX_PWR_CMDID,
+ WMI_GET_TX_PWR_CMDID,
+ WMI_SET_ASSOC_INFO_CMDID,
+ WMI_ADD_BAD_AP_CMDID, /* 30 */
+ WMI_DELETE_BAD_AP_CMDID,
+ WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+ WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+ WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+ WMI_SET_ACCESS_PARAMS_CMDID,
+ WMI_SET_RETRY_LIMITS_CMDID,
+ WMI_SET_OPT_MODE_CMDID,
+ WMI_OPT_TX_FRAME_CMDID,
+ WMI_SET_VOICE_PKT_SIZE_CMDID,
+ WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
+ WMI_SET_ROAM_CTRL_CMDID,
+ WMI_GET_ROAM_TBL_CMDID,
+ WMI_GET_ROAM_DATA_CMDID,
+ WMI_ENABLE_RM_CMDID,
+ WMI_SET_MAX_OFFHOME_DURATION_CMDID,
+ WMI_EXTENSION_CMDID, /* Non-wireless extensions */
+ WMI_SNR_THRESHOLD_PARAMS_CMDID,
+ WMI_LQ_THRESHOLD_PARAMS_CMDID,
+ WMI_SET_LPREAMBLE_CMDID,
+ WMI_SET_RTS_CMDID, /* 50 */
+ WMI_CLR_RSSI_SNR_CMDID,
+ WMI_SET_FIXRATES_CMDID,
+ WMI_GET_FIXRATES_CMDID,
+ WMI_SET_AUTH_MODE_CMDID,
+ WMI_SET_REASSOC_MODE_CMDID,
+ WMI_SET_WMM_CMDID,
+ WMI_SET_WMM_TXOP_CMDID,
+ WMI_TEST_CMDID,
+ /* COEX AR6002 only*/
+ WMI_SET_BT_STATUS_CMDID,
+ WMI_SET_BT_PARAMS_CMDID, /* 60 */
+
+ WMI_SET_KEEPALIVE_CMDID,
+ WMI_GET_KEEPALIVE_CMDID,
+ WMI_SET_APPIE_CMDID,
+ WMI_GET_APPIE_CMDID,
+ WMI_SET_WSC_STATUS_CMDID,
+
+ /* Wake on Wireless */
+ WMI_SET_HOST_SLEEP_MODE_CMDID,
+ WMI_SET_WOW_MODE_CMDID,
+ WMI_GET_WOW_LIST_CMDID,
+ WMI_ADD_WOW_PATTERN_CMDID,
+ WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
+
+ WMI_SET_FRAMERATES_CMDID,
+ WMI_SET_AP_PS_CMDID,
+ WMI_SET_QOS_SUPP_CMDID,
+ /* WMI_THIN_RESERVED_... mark the start and end
+ * values for WMI_THIN_RESERVED command IDs. These
+ * command IDs can be found in wmi_thin.h */
+ WMI_THIN_RESERVED_START = 0x8000,
+ WMI_THIN_RESERVED_END = 0x8fff,
+ /*
+ * Developer commands starts at 0xF000
+ */
+ WMI_SET_BITRATE_CMDID = 0xF000,
+ WMI_GET_BITRATE_CMDID,
+ WMI_SET_WHALPARAM_CMDID,
+
+
+ /*Should add the new command to the tail for compatible with
+ * etna.
+ */
+ WMI_SET_MAC_ADDRESS_CMDID,
+ WMI_SET_AKMP_PARAMS_CMDID,
+ WMI_SET_PMKID_LIST_CMDID,
+ WMI_GET_PMKID_LIST_CMDID,
+ WMI_ABORT_SCAN_CMDID,
+ WMI_SET_TARGET_EVENT_REPORT_CMDID,
+
+ // Unused
+ WMI_UNUSED1,
+ WMI_UNUSED2,
+
+ /*
+ * AP mode commands
+ */
+ WMI_AP_HIDDEN_SSID_CMDID,
+ WMI_AP_SET_NUM_STA_CMDID,
+ WMI_AP_ACL_POLICY_CMDID,
+ WMI_AP_ACL_MAC_LIST_CMDID,
+ WMI_AP_CONFIG_COMMIT_CMDID,
+ WMI_AP_SET_MLME_CMDID,
+ WMI_AP_SET_PVB_CMDID,
+ WMI_AP_CONN_INACT_CMDID,
+ WMI_AP_PROT_SCAN_TIME_CMDID,
+ WMI_AP_SET_COUNTRY_CMDID,
+ WMI_AP_SET_DTIM_CMDID,
+ WMI_AP_MODE_STAT_CMDID,
+
+ WMI_SET_IP_CMDID,
+ WMI_SET_PARAMS_CMDID,
+ WMI_SET_MCAST_FILTER_CMDID,
+ WMI_DEL_MCAST_FILTER_CMDID,
+
+ WMI_ALLOW_AGGR_CMDID,
+ WMI_ADDBA_REQ_CMDID,
+ WMI_DELBA_REQ_CMDID,
+ WMI_SET_HT_CAP_CMDID,
+ WMI_SET_HT_OP_CMDID,
+ WMI_SET_TX_SELECT_RATES_CMDID,
+ WMI_SET_TX_SGI_PARAM_CMDID,
+ WMI_SET_RATE_POLICY_CMDID,
+
+ WMI_HCI_CMD_CMDID,
+ WMI_RX_FRAME_FORMAT_CMDID,
+ WMI_SET_THIN_MODE_CMDID,
+ WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
+
+ WMI_AP_SET_11BG_RATESET_CMDID,
+ WMI_SET_PMK_CMDID,
+ WMI_MCAST_FILTER_CMDID,
+ /* COEX CMDID AR6003*/
+ WMI_SET_BTCOEX_FE_ANT_CMDID,
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
+ WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
+ WMI_SET_BTCOEX_DEBUG_CMDID,
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
+ WMI_GET_BTCOEX_STATS_CMDID,
+ WMI_GET_BTCOEX_CONFIG_CMDID,
+} WMI_COMMAND_ID;
+
+/*
+ * Frame Types
+ */
+typedef enum {
+ WMI_FRAME_BEACON = 0,
+ WMI_FRAME_PROBE_REQ,
+ WMI_FRAME_PROBE_RESP,
+ WMI_FRAME_ASSOC_REQ,
+ WMI_FRAME_ASSOC_RESP,
+ WMI_NUM_MGMT_FRAME
+} WMI_MGMT_FRAME_TYPE;
+
+/*
+ * Connect Command
+ */
+typedef enum {
+ INFRA_NETWORK = 0x01,
+ ADHOC_NETWORK = 0x02,
+ ADHOC_CREATOR = 0x04,
+ AP_NETWORK = 0x10,
+} NETWORK_TYPE;
+
+typedef enum {
+ OPEN_AUTH = 0x01,
+ SHARED_AUTH = 0x02,
+ LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */
+} DOT11_AUTH_MODE;
+
+typedef enum {
+ NONE_AUTH = 0x01,
+ WPA_AUTH = 0x02,
+ WPA2_AUTH = 0x04,
+ WPA_PSK_AUTH = 0x08,
+ WPA2_PSK_AUTH = 0x10,
+ WPA_AUTH_CCKM = 0x20,
+ WPA2_AUTH_CCKM = 0x40,
+} AUTH_MODE;
+
+typedef enum {
+ NONE_CRYPT = 0x01,
+ WEP_CRYPT = 0x02,
+ TKIP_CRYPT = 0x04,
+ AES_CRYPT = 0x08,
+#ifdef WAPI_ENABLE
+ WAPI_CRYPT = 0x10,
+#endif /*WAPI_ENABLE*/
+} CRYPTO_TYPE;
+
+#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
+#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
+
+#ifdef WAPI_ENABLE
+#undef WMI_MAX_CRYPTO_TYPE
+#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1)
+#endif /* WAPI_ENABLE */
+
+#ifdef WAPI_ENABLE
+#define IW_ENCODE_ALG_SM4 0x20
+#define IW_AUTH_WAPI_ENABLED 0x20
+#endif
+
+#define WMI_MIN_KEY_INDEX 0
+#define WMI_MAX_KEY_INDEX 3
+
+#ifdef WAPI_ENABLE
+#undef WMI_MAX_KEY_INDEX
+#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */
+#endif /* WAPI_ENABLE */
+
+#define WMI_MAX_KEY_LEN 32
+
+#define WMI_MAX_SSID_LEN 32
+
+typedef enum {
+ CONNECT_ASSOC_POLICY_USER = 0x0001,
+ CONNECT_SEND_REASSOC = 0x0002,
+ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
+ CONNECT_PROFILE_MATCH_DONE = 0x0008,
+ CONNECT_IGNORE_AAC_BEACON = 0x0010,
+ CONNECT_CSA_FOLLOW_BSS = 0x0020,
+ CONNECT_DO_WPA_OFFLOAD = 0x0040,
+ CONNECT_DO_NOT_DEAUTH = 0x0080,
+} WMI_CONNECT_CTRL_FLAGS_BITS;
+
+#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS)
+
+typedef PREPACK struct {
+ A_UINT8 networkType;
+ A_UINT8 dot11AuthMode;
+ A_UINT8 authMode;
+ A_UINT8 pairwiseCryptoType;
+ A_UINT8 pairwiseCryptoLen;
+ A_UINT8 groupCryptoType;
+ A_UINT8 groupCryptoLen;
+ A_UINT8 ssidLength;
+ A_UCHAR ssid[WMI_MAX_SSID_LEN];
+ A_UINT16 channel;
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT32 ctrl_flags;
+} POSTPACK WMI_CONNECT_CMD;
+
+/*
+ * WMI_RECONNECT_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT16 channel; /* hint */
+ A_UINT8 bssid[ATH_MAC_LEN]; /* mandatory if set */
+} POSTPACK WMI_RECONNECT_CMD;
+
+#define WMI_PMK_LEN 32
+typedef PREPACK struct {
+ A_UINT8 pmk[WMI_PMK_LEN];
+} POSTPACK WMI_SET_PMK_CMD;
+
+/*
+ * WMI_ADD_CIPHER_KEY_CMDID
+ */
+typedef enum {
+ PAIRWISE_USAGE = 0x00,
+ GROUP_USAGE = 0x01,
+ TX_USAGE = 0x02, /* default Tx Key - Static WEP only */
+} KEY_USAGE;
+
+/*
+ * Bit Flag
+ * Bit 0 - Initialise TSC - default is Initialize
+ */
+#define KEY_OP_INIT_TSC 0x01
+#define KEY_OP_INIT_RSC 0x02
+#ifdef WAPI_ENABLE
+#define KEY_OP_INIT_WAPIPN 0x10
+#endif /* WAPI_ENABLE */
+
+#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */
+#define KEY_OP_VALID_MASK 0x03
+
+typedef PREPACK struct {
+ A_UINT8 keyIndex;
+ A_UINT8 keyType;
+ A_UINT8 keyUsage; /* KEY_USAGE */
+ A_UINT8 keyLength;
+ A_UINT8 keyRSC[8]; /* key replay sequence counter */
+ A_UINT8 key[WMI_MAX_KEY_LEN];
+ A_UINT8 key_op_ctrl; /* Additional Key Control information */
+ A_UINT8 key_macaddr[ATH_MAC_LEN];
+} POSTPACK WMI_ADD_CIPHER_KEY_CMD;
+
+/*
+ * WMI_DELETE_CIPHER_KEY_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 keyIndex;
+} POSTPACK WMI_DELETE_CIPHER_KEY_CMD;
+
+#define WMI_KRK_LEN 16
+/*
+ * WMI_ADD_KRK_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 krk[WMI_KRK_LEN];
+} POSTPACK WMI_ADD_KRK_CMD;
+
+/*
+ * WMI_SET_TKIP_COUNTERMEASURES_CMDID
+ */
+typedef enum {
+ WMI_TKIP_CM_DISABLE = 0x0,
+ WMI_TKIP_CM_ENABLE = 0x1,
+} WMI_TKIP_CM_CONTROL;
+
+typedef PREPACK struct {
+ A_UINT8 cm_en; /* WMI_TKIP_CM_CONTROL */
+} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD;
+
+/*
+ * WMI_SET_PMKID_CMDID
+ */
+
+#define WMI_PMKID_LEN 16
+
+typedef enum {
+ PMKID_DISABLE = 0,
+ PMKID_ENABLE = 1,
+} PMKID_ENABLE_FLG;
+
+typedef PREPACK struct {
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT8 enable; /* PMKID_ENABLE_FLG */
+ A_UINT8 pmkid[WMI_PMKID_LEN];
+} POSTPACK WMI_SET_PMKID_CMD;
+
+/*
+ * WMI_START_SCAN_CMD
+ */
+typedef enum {
+ WMI_LONG_SCAN = 0,
+ WMI_SHORT_SCAN = 1,
+} WMI_SCAN_TYPE;
+
+typedef PREPACK struct {
+ A_BOOL forceFgScan;
+ A_BOOL isLegacy; /* For Legacy Cisco AP compatibility */
+ A_UINT32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */
+ A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/
+ A_UINT8 scanType; /* WMI_SCAN_TYPE */
+ A_UINT8 numChannels; /* how many channels follow */
+ A_UINT16 channelList[1]; /* channels in Mhz */
+} POSTPACK WMI_START_SCAN_CMD;
+
+/*
+ * WMI_SET_SCAN_PARAMS_CMDID
+ */
+#define WMI_SHORTSCANRATIO_DEFAULT 3
+/*
+ * Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD
+ * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS
+ */
+typedef enum {
+ CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */
+ SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */
+ /* already connected to */
+ ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */
+ ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */
+ REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */
+ ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't
+ scan after a disconnect event */
+ ENABLE_SCAN_ABORT_EVENT = 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */
+} WMI_SCAN_CTRL_FLAGS_BITS;
+
+#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS)
+#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS)
+#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS)
+#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS)
+#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS)
+#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS)
+#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT)
+
+#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
+
+
+typedef PREPACK struct {
+ A_UINT16 fg_start_period; /* seconds */
+ A_UINT16 fg_end_period; /* seconds */
+ A_UINT16 bg_period; /* seconds */
+ A_UINT16 maxact_chdwell_time; /* msec */
+ A_UINT16 pas_chdwell_time; /* msec */
+ A_UINT8 shortScanRatio; /* how many shorts scan for one long */
+ A_UINT8 scanCtrlFlags;
+ A_UINT16 minact_chdwell_time; /* msec */
+ A_UINT16 maxact_scan_per_ssid; /* max active scans per ssid */
+ A_UINT32 max_dfsch_act_time; /* msecs */
+} POSTPACK WMI_SCAN_PARAMS_CMD;
+
+/*
+ * WMI_SET_BSS_FILTER_CMDID
+ */
+typedef enum {
+ NONE_BSS_FILTER = 0x0, /* no beacons forwarded */
+ ALL_BSS_FILTER, /* all beacons forwarded */
+ PROFILE_FILTER, /* only beacons matching profile */
+ ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */
+ CURRENT_BSS_FILTER, /* only beacons matching current BSS */
+ ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */
+ PROBED_SSID_FILTER, /* beacons matching probed ssid */
+ LAST_BSS_FILTER, /* marker only */
+} WMI_BSS_FILTER;
+
+typedef PREPACK struct {
+ A_UINT8 bssFilter; /* see WMI_BSS_FILTER */
+ A_UINT8 reserved1; /* For alignment */
+ A_UINT16 reserved2; /* For alignment */
+ A_UINT32 ieMask;
+} POSTPACK WMI_BSS_FILTER_CMD;
+
+/*
+ * WMI_SET_PROBED_SSID_CMDID
+ */
+#define MAX_PROBED_SSID_INDEX 9
+
+typedef enum {
+ DISABLE_SSID_FLAG = 0, /* disables entry */
+ SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */
+ ANY_SSID_FLAG = 0x02, /* probes for any ssid */
+} WMI_SSID_FLAG;
+
+typedef PREPACK struct {
+ A_UINT8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */
+ A_UINT8 flag; /* WMI_SSID_FLG */
+ A_UINT8 ssidLength;
+ A_UINT8 ssid[32];
+} POSTPACK WMI_PROBED_SSID_CMD;
+
+/*
+ * WMI_SET_LISTEN_INT_CMDID
+ * The Listen interval is between 15 and 3000 TUs
+ */
+#define MIN_LISTEN_INTERVAL 15
+#define MAX_LISTEN_INTERVAL 5000
+#define MIN_LISTEN_BEACONS 1
+#define MAX_LISTEN_BEACONS 50
+
+typedef PREPACK struct {
+ A_UINT16 listenInterval;
+ A_UINT16 numBeacons;
+} POSTPACK WMI_LISTEN_INT_CMD;
+
+/*
+ * WMI_SET_BEACON_INT_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT16 beaconInterval;
+} POSTPACK WMI_BEACON_INT_CMD;
+
+/*
+ * WMI_SET_BMISS_TIME_CMDID
+ * valid values are between 1000 and 5000 TUs
+ */
+
+#define MIN_BMISS_TIME 1000
+#define MAX_BMISS_TIME 5000
+#define MIN_BMISS_BEACONS 1
+#define MAX_BMISS_BEACONS 50
+
+typedef PREPACK struct {
+ A_UINT16 bmissTime;
+ A_UINT16 numBeacons;
+} POSTPACK WMI_BMISS_TIME_CMD;
+
+/*
+ * WMI_SET_POWER_MODE_CMDID
+ */
+typedef enum {
+ REC_POWER = 0x01,
+ MAX_PERF_POWER,
+} WMI_POWER_MODE;
+
+typedef PREPACK struct {
+ A_UINT8 powerMode; /* WMI_POWER_MODE */
+} POSTPACK WMI_POWER_MODE_CMD;
+
+typedef PREPACK struct {
+ A_INT8 status; /* WMI_SET_PARAMS_REPLY */
+} POSTPACK WMI_SET_PARAMS_REPLY;
+
+typedef PREPACK struct {
+ A_UINT32 opcode;
+ A_UINT32 length;
+ A_CHAR buffer[1]; /* WMI_SET_PARAMS */
+} POSTPACK WMI_SET_PARAMS_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */
+} POSTPACK WMI_SET_MCAST_FILTER_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 enable; /* WMI_MCAST_FILTER */
+} POSTPACK WMI_MCAST_FILTER_CMD;
+
+/*
+ * WMI_SET_POWER_PARAMS_CMDID
+ */
+typedef enum {
+ IGNORE_DTIM = 0x01,
+ NORMAL_DTIM = 0x02,
+ STICK_DTIM = 0x03,
+ AUTO_DTIM = 0x04,
+} WMI_DTIM_POLICY;
+
+/* Policy to determnine whether TX should wakeup WLAN if sleeping */
+typedef enum {
+ TX_WAKEUP_UPON_SLEEP = 1,
+ TX_DONT_WAKEUP_UPON_SLEEP = 2
+} WMI_TX_WAKEUP_POLICY_UPON_SLEEP;
+
+/*
+ * Policy to determnine whether power save failure event should be sent to
+ * host during scanning
+ */
+typedef enum {
+ SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
+ IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
+} POWER_SAVE_FAIL_EVENT_POLICY;
+
+typedef PREPACK struct {
+ A_UINT16 idle_period; /* msec */
+ A_UINT16 pspoll_number;
+ A_UINT16 dtim_policy;
+ A_UINT16 tx_wakeup_policy;
+ A_UINT16 num_tx_to_wakeup;
+ A_UINT16 ps_fail_event_policy;
+} POSTPACK WMI_POWER_PARAMS_CMD;
+
+/* Adhoc power save types */
+typedef enum {
+ ADHOC_PS_DISABLE=1,
+ ADHOC_PS_ATH=2,
+ ADHOC_PS_IEEE=3,
+ ADHOC_PS_OTHER=4,
+} WMI_ADHOC_PS_TYPE;
+
+typedef PREPACK struct {
+ A_UINT8 power_saving;
+ A_UINT8 ttl; /* number of beacon periods */
+ A_UINT16 atim_windows; /* msec */
+ A_UINT16 timeout_value; /* msec */
+} POSTPACK WMI_IBSS_PM_CAPS_CMD;
+
+/* AP power save types */
+typedef enum {
+ AP_PS_DISABLE=1,
+ AP_PS_ATH=2,
+} WMI_AP_PS_TYPE;
+
+typedef PREPACK struct {
+ A_UINT32 idle_time; /* in msec */
+ A_UINT32 ps_period; /* in usec */
+ A_UINT8 sleep_period; /* in ps periods */
+ A_UINT8 psType;
+} POSTPACK WMI_AP_PS_CMD;
+
+/*
+ * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID
+ */
+typedef enum {
+ IGNORE_TIM_ALL_QUEUES_APSD = 0,
+ PROCESS_TIM_ALL_QUEUES_APSD = 1,
+ IGNORE_TIM_SIMULATED_APSD = 2,
+ PROCESS_TIM_SIMULATED_APSD = 3,
+} APSD_TIM_POLICY;
+
+typedef PREPACK struct {
+ A_UINT16 psPollTimeout; /* msec */
+ A_UINT16 triggerTimeout; /* msec */
+ A_UINT32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */
+ A_UINT32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */
+} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD;
+
+/*
+ * WMI_SET_VOICE_PKT_SIZE_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT16 voicePktSize;
+} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD;
+
+/*
+ * WMI_SET_MAX_SP_LEN_CMDID
+ */
+typedef enum {
+ DELIVER_ALL_PKT = 0x0,
+ DELIVER_2_PKT = 0x1,
+ DELIVER_4_PKT = 0x2,
+ DELIVER_6_PKT = 0x3,
+} APSD_SP_LEN_TYPE;
+
+typedef PREPACK struct {
+ A_UINT8 maxSPLen;
+} POSTPACK WMI_SET_MAX_SP_LEN_CMD;
+
+/*
+ * WMI_SET_DISC_TIMEOUT_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 disconnectTimeout; /* seconds */
+} POSTPACK WMI_DISC_TIMEOUT_CMD;
+
+typedef enum {
+ UPLINK_TRAFFIC = 0,
+ DNLINK_TRAFFIC = 1,
+ BIDIR_TRAFFIC = 2,
+} DIR_TYPE;
+
+typedef enum {
+ DISABLE_FOR_THIS_AC = 0,
+ ENABLE_FOR_THIS_AC = 1,
+ ENABLE_FOR_ALL_AC = 2,
+} VOICEPS_CAP_TYPE;
+
+typedef enum {
+ TRAFFIC_TYPE_APERIODIC = 0,
+ TRAFFIC_TYPE_PERIODIC = 1,
+}TRAFFIC_TYPE;
+
+/*
+ * WMI_SYNCHRONIZE_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 dataSyncMap;
+} POSTPACK WMI_SYNC_CMD;
+
+/*
+ * WMI_CREATE_PSTREAM_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT32 minServiceInt; /* in milli-sec */
+ A_UINT32 maxServiceInt; /* in milli-sec */
+ A_UINT32 inactivityInt; /* in milli-sec */
+ A_UINT32 suspensionInt; /* in milli-sec */
+ A_UINT32 serviceStartTime;
+ A_UINT32 minDataRate; /* in bps */
+ A_UINT32 meanDataRate; /* in bps */
+ A_UINT32 peakDataRate; /* in bps */
+ A_UINT32 maxBurstSize;
+ A_UINT32 delayBound;
+ A_UINT32 minPhyRate; /* in bps */
+ A_UINT32 sba;
+ A_UINT32 mediumTime;
+ A_UINT16 nominalMSDU; /* in octects */
+ A_UINT16 maxMSDU; /* in octects */
+ A_UINT8 trafficClass;
+ A_UINT8 trafficDirection; /* DIR_TYPE */
+ A_UINT8 rxQueueNum;
+ A_UINT8 trafficType; /* TRAFFIC_TYPE */
+ A_UINT8 voicePSCapability; /* VOICEPS_CAP_TYPE */
+ A_UINT8 tsid;
+ A_UINT8 userPriority; /* 802.1D user priority */
+ A_UINT8 nominalPHY; /* nominal phy rate */
+} POSTPACK WMI_CREATE_PSTREAM_CMD;
+
+/*
+ * WMI_DELETE_PSTREAM_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 txQueueNumber;
+ A_UINT8 rxQueueNumber;
+ A_UINT8 trafficDirection;
+ A_UINT8 trafficClass;
+ A_UINT8 tsid;
+} POSTPACK WMI_DELETE_PSTREAM_CMD;
+
+/*
+ * WMI_SET_CHANNEL_PARAMS_CMDID
+ */
+typedef enum {
+ WMI_11A_MODE = 0x1,
+ WMI_11G_MODE = 0x2,
+ WMI_11AG_MODE = 0x3,
+ WMI_11B_MODE = 0x4,
+ WMI_11GONLY_MODE = 0x5,
+} WMI_PHY_MODE;
+
+#define WMI_MAX_CHANNELS 32
+
+typedef PREPACK struct {
+ A_UINT8 reserved1;
+ A_UINT8 scanParam; /* set if enable scan */
+ A_UINT8 phyMode; /* see WMI_PHY_MODE */
+ A_UINT8 numChannels; /* how many channels follow */
+ A_UINT16 channelList[1]; /* channels in Mhz */
+} POSTPACK WMI_CHANNEL_PARAMS_CMD;
+
+
+/*
+ * WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ * Setting the polltime to 0 would disable polling.
+ * Threshold values are in the ascending order, and should agree to:
+ * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
+ * < highThreshold_upperVal)
+ */
+
+typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{
+ A_UINT32 pollTime; /* Polling time as a factor of LI */
+ A_INT16 thresholdAbove1_Val; /* lowest of upper */
+ A_INT16 thresholdAbove2_Val;
+ A_INT16 thresholdAbove3_Val;
+ A_INT16 thresholdAbove4_Val;
+ A_INT16 thresholdAbove5_Val;
+ A_INT16 thresholdAbove6_Val; /* highest of upper */
+ A_INT16 thresholdBelow1_Val; /* lowest of bellow */
+ A_INT16 thresholdBelow2_Val;
+ A_INT16 thresholdBelow3_Val;
+ A_INT16 thresholdBelow4_Val;
+ A_INT16 thresholdBelow5_Val;
+ A_INT16 thresholdBelow6_Val; /* highest of bellow */
+ A_UINT8 weight; /* "alpha" */
+ A_UINT8 reserved[3];
+} POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD;
+
+/*
+ * WMI_SNR_THRESHOLD_PARAMS_CMDID
+ * Setting the polltime to 0 would disable polling.
+ */
+
+typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{
+ A_UINT32 pollTime; /* Polling time as a factor of LI */
+ A_UINT8 weight; /* "alpha" */
+ A_UINT8 thresholdAbove1_Val; /* lowest of uppper*/
+ A_UINT8 thresholdAbove2_Val;
+ A_UINT8 thresholdAbove3_Val;
+ A_UINT8 thresholdAbove4_Val; /* highest of upper */
+ A_UINT8 thresholdBelow1_Val; /* lowest of bellow */
+ A_UINT8 thresholdBelow2_Val;
+ A_UINT8 thresholdBelow3_Val;
+ A_UINT8 thresholdBelow4_Val; /* highest of bellow */
+ A_UINT8 reserved[3];
+} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD;
+
+/*
+ * WMI_LQ_THRESHOLD_PARAMS_CMDID
+ */
+typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS {
+ A_UINT8 enable;
+ A_UINT8 thresholdAbove1_Val;
+ A_UINT8 thresholdAbove2_Val;
+ A_UINT8 thresholdAbove3_Val;
+ A_UINT8 thresholdAbove4_Val;
+ A_UINT8 thresholdBelow1_Val;
+ A_UINT8 thresholdBelow2_Val;
+ A_UINT8 thresholdBelow3_Val;
+ A_UINT8 thresholdBelow4_Val;
+ A_UINT8 reserved[3];
+} POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD;
+
+typedef enum {
+ WMI_LPREAMBLE_DISABLED = 0,
+ WMI_LPREAMBLE_ENABLED
+} WMI_LPREAMBLE_STATUS;
+
+typedef enum {
+ WMI_IGNORE_BARKER_IN_ERP = 0,
+ WMI_DONOT_IGNORE_BARKER_IN_ERP
+} WMI_PREAMBLE_POLICY;
+
+typedef PREPACK struct {
+ A_UINT8 status;
+ A_UINT8 preamblePolicy;
+}POSTPACK WMI_SET_LPREAMBLE_CMD;
+
+typedef PREPACK struct {
+ A_UINT16 threshold;
+}POSTPACK WMI_SET_RTS_CMD;
+
+/*
+ * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
+ * Sets the error reporting event bitmask in target. Target clears it
+ * upon an error. Subsequent errors are counted, but not reported
+ * via event, unless the bitmask is set again.
+ */
+typedef PREPACK struct {
+ A_UINT32 bitmask;
+} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK;
+
+/*
+ * WMI_SET_TX_PWR_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 dbM; /* in dbM units */
+} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY;
+
+/*
+ * WMI_SET_ASSOC_INFO_CMDID
+ *
+ * A maximum of 2 private IEs can be sent in the [Re]Assoc request.
+ * A 3rd one, the CCX version IE can also be set from the host.
+ */
+#define WMI_MAX_ASSOC_INFO_TYPE 2
+#define WMI_CCX_VER_IE 2 /* ieType to set CCX Version IE */
+
+#define WMI_MAX_ASSOC_INFO_LEN 240
+
+typedef PREPACK struct {
+ A_UINT8 ieType;
+ A_UINT8 bufferSize;
+ A_UINT8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */
+} POSTPACK WMI_SET_ASSOC_INFO_CMD;
+
+
+/*
+ * WMI_GET_TX_PWR_CMDID does not take any parameters
+ */
+
+/*
+ * WMI_ADD_BAD_AP_CMDID
+ */
+#define WMI_MAX_BAD_AP_INDEX 1
+
+typedef PREPACK struct {
+ A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
+ A_UINT8 bssid[ATH_MAC_LEN];
+} POSTPACK WMI_ADD_BAD_AP_CMD;
+
+/*
+ * WMI_DELETE_BAD_AP_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */
+} POSTPACK WMI_DELETE_BAD_AP_CMD;
+
+/*
+ * WMI_SET_ACCESS_PARAMS_CMDID
+ */
+#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */
+#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */
+#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */
+#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */
+#define WMI_DEFAULT_AIFSN_ACPARAM 2
+#define WMI_MAX_AIFSN_ACPARAM 15
+typedef PREPACK struct {
+ A_UINT16 txop; /* in units of 32 usec */
+ A_UINT8 eCWmin;
+ A_UINT8 eCWmax;
+ A_UINT8 aifsn;
+ A_UINT8 ac;
+} POSTPACK WMI_SET_ACCESS_PARAMS_CMD;
+
+
+/*
+ * WMI_SET_RETRY_LIMITS_CMDID
+ *
+ * This command is used to customize the number of retries the
+ * wlan device will perform on a given frame.
+ */
+#define WMI_MIN_RETRIES 2
+#define WMI_MAX_RETRIES 13
+typedef enum {
+ MGMT_FRAMETYPE = 0,
+ CONTROL_FRAMETYPE = 1,
+ DATA_FRAMETYPE = 2
+} WMI_FRAMETYPE;
+
+typedef PREPACK struct {
+ A_UINT8 frameType; /* WMI_FRAMETYPE */
+ A_UINT8 trafficClass; /* applies only to DATA_FRAMETYPE */
+ A_UINT8 maxRetries;
+ A_UINT8 enableNotify;
+} POSTPACK WMI_SET_RETRY_LIMITS_CMD;
+
+/*
+ * WMI_SET_ROAM_CTRL_CMDID
+ *
+ * This command is used to influence the Roaming behaviour
+ * Set the host biases of the BSSs before setting the roam mode as bias
+ * based.
+ */
+
+/*
+ * Different types of Roam Control
+ */
+
+typedef enum {
+ WMI_FORCE_ROAM = 1, /* Roam to the specified BSSID */
+ WMI_SET_ROAM_MODE = 2, /* default ,progd bias, no roam */
+ WMI_SET_HOST_BIAS = 3, /* Set the Host Bias */
+ WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */
+} WMI_ROAM_CTRL_TYPE;
+
+#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM
+#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS
+
+/*
+ * ROAM MODES
+ */
+
+typedef enum {
+ WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based ROAM */
+ WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */
+ WMI_LOCK_BSS_MODE = 3 /* Lock to the Current BSS - no Roam */
+} WMI_ROAM_MODE;
+
+/*
+ * BSS HOST BIAS INFO
+ */
+
+typedef PREPACK struct {
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_INT8 bias;
+} POSTPACK WMI_BSS_BIAS;
+
+typedef PREPACK struct {
+ A_UINT8 numBss;
+ WMI_BSS_BIAS bssBias[1];
+} POSTPACK WMI_BSS_BIAS_INFO;
+
+typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS {
+ A_UINT16 lowrssi_scan_period;
+ A_INT16 lowrssi_scan_threshold;
+ A_INT16 lowrssi_roam_threshold;
+ A_UINT8 roam_rssi_floor;
+ A_UINT8 reserved[1]; /* For alignment */
+} POSTPACK WMI_LOWRSSI_SCAN_PARAMS;
+
+typedef PREPACK struct {
+ PREPACK union {
+ A_UINT8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */
+ A_UINT8 roamMode; /* WMI_SET_ROAM_MODE */
+ WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */
+ WMI_LOWRSSI_SCAN_PARAMS lrScanParams;
+ } POSTPACK info;
+ A_UINT8 roamCtrlType ;
+} POSTPACK WMI_SET_ROAM_CTRL_CMD;
+
+/*
+ * WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID
+ */
+typedef enum {
+ BT_WLAN_CONN_PRECDENCE_WLAN=0, /* Default */
+ BT_WLAN_CONN_PRECDENCE_PAL,
+} BT_WLAN_CONN_PRECEDENCE;
+
+typedef PREPACK struct {
+ A_UINT8 precedence;
+} POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE;
+
+/*
+ * WMI_ENABLE_RM_CMDID
+ */
+typedef PREPACK struct {
+ A_BOOL enable_radio_measurements;
+} POSTPACK WMI_ENABLE_RM_CMD;
+
+/*
+ * WMI_SET_MAX_OFFHOME_DURATION_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 max_offhome_duration;
+} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 frequency;
+ A_UINT8 threshold;
+} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD;
+/*---------------------- BTCOEX RELATED -------------------------------------*/
+/*----------------------COMMON to AR6002 and AR6003 -------------------------*/
+typedef enum {
+ BT_STREAM_UNDEF = 0,
+ BT_STREAM_SCO, /* SCO stream */
+ BT_STREAM_A2DP, /* A2DP stream */
+ BT_STREAM_SCAN, /* BT Discovery or Page */
+ BT_STREAM_ESCO,
+ BT_STREAM_MAX
+} BT_STREAM_TYPE;
+
+typedef enum {
+ BT_PARAM_SCO_PSPOLL_LATENCY_ONE_FOURTH =1,
+ BT_PARAM_SCO_PSPOLL_LATENCY_HALF,
+ BT_PARAM_SCO_PSPOLL_LATENCY_THREE_FOURTH,
+} BT_PARAMS_SCO_PSPOLL_LATENCY;
+
+typedef enum {
+ BT_PARAMS_SCO_STOMP_SCO_NEVER =1,
+ BT_PARAMS_SCO_STOMP_SCO_ALWAYS,
+ BT_PARAMS_SCO_STOMP_SCO_IN_LOWRSSI,
+} BT_PARAMS_SCO_STOMP_RULES;
+
+typedef enum {
+ BT_STATUS_UNDEF = 0,
+ BT_STATUS_ON,
+ BT_STATUS_OFF,
+ BT_STATUS_MAX
+} BT_STREAM_STATUS;
+
+typedef PREPACK struct {
+ A_UINT8 streamType;
+ A_UINT8 status;
+} POSTPACK WMI_SET_BT_STATUS_CMD;
+
+typedef enum {
+ BT_ANT_TYPE_UNDEF=0,
+ BT_ANT_TYPE_DUAL,
+ BT_ANT_TYPE_SPLITTER,
+ BT_ANT_TYPE_SWITCH,
+ BT_ANT_TYPE_HIGH_ISO_DUAL
+} BT_ANT_FRONTEND_CONFIG;
+
+typedef enum {
+ BT_COLOCATED_DEV_BTS4020=0,
+ BT_COLCATED_DEV_CSR ,
+ BT_COLOCATED_DEV_VALKYRIE
+} BT_COLOCATED_DEV_TYPE;
+
+/*********************** Applicable to AR6002 ONLY ******************************/
+
+typedef enum {
+ BT_PARAM_SCO = 1, /* SCO stream parameters */
+ BT_PARAM_A2DP ,
+ BT_PARAM_ANTENNA_CONFIG,
+ BT_PARAM_COLOCATED_BT_DEVICE,
+ BT_PARAM_ACLCOEX,
+ BT_PARAM_11A_SEPARATE_ANT,
+ BT_PARAM_MAX
+} BT_PARAM_TYPE;
+
+
+#define BT_SCO_ALLOW_CLOSE_RANGE_OPT (1 << 0)
+#define BT_SCO_FORCE_AWAKE_OPT (1 << 1)
+#define BT_SCO_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
+#define BT_SCO_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
+#define BT_SCO_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
+#define BT_SCO_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
+#define BT_SCO_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
+#define BT_SCO_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
+#define BT_SCO_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
+#define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
+
+typedef PREPACK struct {
+ A_UINT32 numScoCyclesForceTrigger; /* Number SCO cycles after which
+ force a pspoll. default = 10 */
+ A_UINT32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt
+ in response for ps-poll,
+ default = 10 msecs */
+ A_UINT32 stompScoRules;
+ A_UINT32 scoOptFlags; /* SCO Options Flags :
+ bits: meaning:
+ 0 Allow Close Range Optimization
+ 1 Force awake during close range
+ 2 If set use host supplied RSSI for OPT
+ 3 If set use host supplied RTS COUNT for OPT
+ 4..7 Unused
+ 8..15 Low Data Rate Min Cnt
+ 16..23 Low Data Rate Max Cnt
+ */
+
+ A_UINT8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing
+ if stomped */
+ A_UINT8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle
+ gradually uptill this value on need basis*/
+ A_UINT8 psPollLatencyFraction; /* Fraction of idle
+ period, within which
+ additional ps-polls
+ can be queued */
+ A_UINT8 noSCOSlots; /* Number of SCO Tx/Rx slots.
+ HVx, EV3, 2EV3 = 2 */
+ A_UINT8 noIdleSlots; /* Number of Bluetooth idle slots between
+ consecutive SCO Tx/Rx slots
+ HVx, EV3 = 4
+ 2EV3 = 10 */
+ A_UINT8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/
+ A_UINT8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/
+ A_UINT8 scoOptRtsCount;
+} POSTPACK BT_PARAMS_SCO;
+
+#define BT_A2DP_ALLOW_CLOSE_RANGE_OPT (1 << 0)
+#define BT_A2DP_FORCE_AWAKE_OPT (1 << 1)
+#define BT_A2DP_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2))
+#define BT_A2DP_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1)
+#define BT_A2DP_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3))
+#define BT_A2DP_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1)
+#define BT_A2DP_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF)
+#define BT_A2DP_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF)
+#define BT_A2DP_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8)
+#define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16)
+
+typedef PREPACK struct {
+ A_UINT32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for
+ wlan, after it identifies the idle time
+ default (30 msecs) */
+ A_UINT32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames
+ to replenish Wlan Usage limit (default 3) */
+ A_UINT32 a2dpDataRespTimeout;
+ A_UINT32 a2dpOptFlags; /* A2DP Option flags:
+ bits: meaning:
+ 0 Allow Close Range Optimization
+ 1 Force awake during close range
+ 2 If set use host supplied RSSI for OPT
+ 3 If set use host supplied RTS COUNT for OPT
+ 4..7 Unused
+ 8..15 Low Data Rate Min Cnt
+ 16..23 Low Data Rate Max Cnt
+ */
+ A_UINT8 isCoLocatedBtRoleMaster;
+ A_UINT8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/
+ A_UINT8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/
+ A_UINT8 a2dpOptRtsCount;
+}POSTPACK BT_PARAMS_A2DP;
+
+/* During BT ftp/ BT OPP or any another data based acl profile on bluetooth
+ (non a2dp).*/
+typedef PREPACK struct {
+ A_UINT32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp)
+ coexistence (default 30 msecs) */
+ A_UINT32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence
+ (default 30 msecs)*/
+ A_UINT32 aclDataRespTimeout;
+ A_UINT32 aclDetectTimeout; /* ACL coexistence enabled if we get
+ 10 Pkts in X msec(default 100 msecs) */
+ A_UINT32 aclmaxPktCnt; /* No of ACL pkts to receive before
+ enabling ACL coex */
+
+}POSTPACK BT_PARAMS_ACLCOEX;
+
+typedef PREPACK struct {
+ PREPACK union {
+ BT_PARAMS_SCO scoParams;
+ BT_PARAMS_A2DP a2dpParams;
+ BT_PARAMS_ACLCOEX aclCoexParams;
+ A_UINT8 antType; /* 0 -Disabled (default)
+ 1 - BT_ANT_TYPE_DUAL
+ 2 - BT_ANT_TYPE_SPLITTER
+ 3 - BT_ANT_TYPE_SWITCH */
+ A_UINT8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default)
+ 1 - BT_COLCATED_DEV_CSR
+ 2 - BT_COLOCATED_DEV_VALKYRIe
+ */
+ } POSTPACK info;
+ A_UINT8 paramType ;
+} POSTPACK WMI_SET_BT_PARAMS_CMD;
+
+/************************ END AR6002 BTCOEX *******************************/
+/*-----------------------AR6003 BTCOEX -----------------------------------*/
+
+/* ---------------WMI_SET_BTCOEX_FE_ANT_CMDID --------------------------*/
+/* Indicates front end antenna configuration. This command needs to be issued
+ * right after initialization and after WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID.
+ * AR6003 enables coexistence and antenna switching based on the configuration.
+ */
+typedef enum {
+ WMI_BTCOEX_NOT_ENABLED = 0,
+ WMI_BTCOEX_FE_ANT_SINGLE =1,
+ WMI_BTCOEX_FE_ANT_DUAL=2,
+ WMI_BTCOEX_FE_ANT_DUAL_HIGH_ISO=3,
+ WMI_BTCOEX_FE_ANT_TYPE_MAX
+}WMI_BTCOEX_FE_ANT_TYPE;
+
+typedef PREPACK struct {
+ A_UINT8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end
+ 2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end
+ (for isolations less 35dB, for higher isolation there
+ is not need to pass this command).
+ (not implemented)
+ */
+}POSTPACK WMI_SET_BTCOEX_FE_ANT_CMD;
+
+/* -------------WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID ----------------*/
+/* Indicate the bluetooth chip to the firmware. Firmware can have different algorithm based
+ * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used.
+ */
+typedef PREPACK struct {
+ A_UINT8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA)
+ 2 - CSR BT (3 wire PTA)
+ 3 - Atheros 3001 BT (3 wire PTA)
+ 4 - STE bluetooth (4-wire ePTA)
+ 5 - Atheros 3002 BT (4-wire MCI)
+ defaults= 3 (Atheros 3001 BT )
+ */
+}POSTPACK WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD;
+
+/* -------------WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID ------------*/
+/* Configuration parameters during bluetooth inquiry and page. Page configuration
+ * is applicable only on interfaces which can distinguish page (applicable only for ePTA -
+ * STE bluetooth).
+ * Bluetooth inquiry start and end is indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID.
+ * During this the station will be power-save mode.
+ */
+typedef PREPACK struct {
+ A_UINT32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data
+ (via pspoll) is configured by this parameter.
+ "default = 10 ms" */
+
+ A_UINT32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state
+ for configured duration, after inquiry completion
+ . This is to ensure other bluetooth transactions
+ (RDP, SDP profiles, link key exchange ...etc)
+ goes through smoothly without wifi stomping.
+ default = 10 secs*/
+
+ A_UINT32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not
+ used */
+ A_UINT32 btInquiryPageFlag; /* Not used */
+}POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD;
+
+/*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/
+/* Configure SCO parameters. These parameters would be used whenever firmware is indicated
+ * of (e)SCO profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
+ * Configration of BTCOEX_SCO_CONFIG data structure are common configuration and applies
+ * ps-poll mode and opt mode.
+ * Ps-poll Mode - Station is in power-save and retrieves downlink data between sco gaps.
+ * Opt Mode - station is in awake state and access point can send data to station any time.
+ * BTCOEX_PSPOLLMODE_SCO_CONFIG - Configuration applied only during ps-poll mode.
+ * BTCOEX_OPTMODE_SCO_CONFIG - Configuration applied only during opt mode.
+ */
+#define WMI_SCO_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
+#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
+#define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER (1 << 2)
+#define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER (1 << 3)
+typedef PREPACK struct {
+ A_UINT32 scoSlots; /* Number of SCO Tx/Rx slots.
+ HVx, EV3, 2EV3 = 2 */
+ A_UINT32 scoIdleSlots; /* Number of Bluetooth idle slots between
+ consecutive SCO Tx/Rx slots
+ HVx, EV3 = 4
+ 2EV3 = 10
+ */
+ A_UINT32 scoFlags; /* SCO Options Flags :
+ bits: meaning:
+ 0 Allow Close Range Optimization
+ 1 Is EDR capable or Not
+ 2 IS Co-located Bt role Master
+ 3 Firmware determines the periodicity of SCO.
+ */
+
+ A_UINT32 linkId; /* applicable to STE-BT - not used */
+}POSTPACK BTCOEX_SCO_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 scoCyclesForceTrigger; /* Number SCO cycles after which
+ force a pspoll. default = 10 */
+ A_UINT32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt
+ in response for ps-poll,
+ default = 20 msecs */
+
+ A_UINT32 scoStompDutyCyleVal; /* not implemented */
+
+ A_UINT32 scoStompDutyCyleMaxVal; /*Not implemented */
+
+ A_UINT32 scoPsPollLatencyFraction; /* Fraction of idle
+ period, within which
+ additional ps-polls can be queued
+ 1 - 1/4 of idle duration
+ 2 - 1/2 of idle duration
+ 3 - 3/4 of idle duration
+ default =2 (1/2)
+ */
+}POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in
+ opt mode. If exceeds the configured value,
+ switch to ps-poll mode
+ default = 3 */
+
+ A_UINT32 scoContStompMax; /* max number of continous stomp allowed in opt mode.
+ if excedded switch to pspoll mode
+ default = 3 */
+
+ A_UINT32 scoMinlowRateMbps; /* Low rate threshold */
+
+ A_UINT32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms.
+ If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
+ default = 36
+ */
+
+ A_UINT32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
+ ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
+ if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
+ default = 5 (80% of high rates)
+ */
+
+ A_UINT32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
+ max number of aggregates if it was negogiated to higher value
+ default = 1
+ Recommended value Basic rate headsets = 1, EDR (2-EV3) =4.
+ */
+}POSTPACK BTCOEX_OPTMODE_SCO_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 scanInterval;
+ A_UINT32 maxScanStompCnt;
+}POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG;
+
+typedef PREPACK struct {
+ BTCOEX_SCO_CONFIG scoConfig;
+ BTCOEX_PSPOLLMODE_SCO_CONFIG scoPspollConfig;
+ BTCOEX_OPTMODE_SCO_CONFIG scoOptModeConfig;
+ BTCOEX_WLANSCAN_SCO_CONFIG scoWlanScanConfig;
+}POSTPACK WMI_SET_BTCOEX_SCO_CONFIG_CMD;
+
+/* ------------------WMI_SET_BTCOEX_A2DP_CONFIG_CMDID -------------------*/
+/* Configure A2DP profile parameters. These parameters would be used whenver firmware is indicated
+ * of A2DP profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID).
+ * Configuration of BTCOEX_A2DP_CONFIG data structure are common configuration and applies to
+ * ps-poll mode and opt mode.
+ * Ps-poll Mode - Station is in power-save and retrieves downlink data between a2dp data bursts.
+ * Opt Mode - station is in power save during a2dp bursts and awake in the gaps.
+ * BTCOEX_PSPOLLMODE_A2DP_CONFIG - Configuration applied only during ps-poll mode.
+ * BTCOEX_OPTMODE_A2DP_CONFIG - Configuration applied only during opt mode.
+ */
+
+#define WMI_A2DP_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0)
+#define WMI_A2DP_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
+#define WMI_A2DP_CONFIG_FLAG_IS_BT_ROLE_MASTER (1 << 2)
+#define WMI_A2DP_CONFIG_FLAG_IS_A2DP_HIGH_PRI (1 << 3)
+#define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE (1 << 4)
+
+typedef PREPACK struct {
+ A_UINT32 a2dpFlags; /* A2DP Option flags:
+ bits: meaning:
+ 0 Allow Close Range Optimization
+ 1 IS EDR capable
+ 2 IS Co-located Bt role Master
+ 3 a2dp traffic is high priority
+ 4 Fw detect the role of bluetooth.
+ */
+ A_UINT32 linkId; /* Applicable only to STE-BT - not used */
+
+}POSTPACK BTCOEX_A2DP_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for
+ wlan, after it identifies the idle time
+ default (30 msecs) */
+
+ A_UINT32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames
+ to replenish Wlan Usage limit (default 3) */
+
+ A_UINT32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink
+ by stomping on bluetooth
+ after ps-poll is acknowledged.
+ default = 20 ms
+ */
+}POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 a2dpMinlowRateMbps; /* Low rate threshold */
+
+ A_UINT32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms.
+ If exceeded switch/stay to ps-poll mode, lower stay in opt mode.
+ default = 36
+ */
+
+ A_UINT32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/
+ ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms,
+ if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode.
+ default = 5 (80% of high rates)
+ */
+
+ A_UINT32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates
+ max number of aggregates if it was negogiated to higher value
+ default = 1
+ Recommended value Basic rate headsets = 1, EDR (2-EV3) =8.
+ */
+ A_UINT32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst.
+ default = 6*/
+
+}POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG;
+
+typedef PREPACK struct {
+ BTCOEX_A2DP_CONFIG a2dpConfig;
+ BTCOEX_PSPOLLMODE_A2DP_CONFIG a2dppspollConfig;
+ BTCOEX_OPTMODE_A2DP_CONFIG a2dpOptConfig;
+}POSTPACK WMI_SET_BTCOEX_A2DP_CONFIG_CMD;
+
+/*------------ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID---------------------*/
+/* Configure non-A2dp ACL profile parameters.The starts of ACL profile can either be
+ * indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID orenabled via firmware detection
+ * which is configured via "aclCoexFlags".
+ * Configration of BTCOEX_ACLCOEX_CONFIG data structure are common configuration and applies
+ * ps-poll mode and opt mode.
+ * Ps-poll Mode - Station is in power-save and retrieves downlink data during wlan medium.
+ * Opt Mode - station is in power save during bluetooth medium time and awake during wlan duration.
+ * (Not implemented yet)
+ *
+ * BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG - Configuration applied only during ps-poll mode.
+ * BTCOEX_OPTMODE_ACLCOEX_CONFIG - Configuration applied only during opt mode.
+ */
+
+#define WMI_ACLCOEX_FLAGS_ALLOW_OPTIMIZATION (1 << 0)
+#define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1)
+
+typedef PREPACK struct {
+ A_UINT32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp)
+ coexistence (default 30 msecs)
+ */
+
+ A_UINT32 aclBtMediumDur; /* Bt usage time during acl coexistence
+ (default 30 msecs)
+ */
+
+ A_UINT32 aclDetectTimeout; /* BT activity observation time limit.
+ In this time duration, number of bt pkts are counted.
+ If the Cnt reaches "aclPktCntLowerLimit" value
+ for "aclIterToEnableCoex" iteration continuously,
+ firmware gets into ACL coexistence mode.
+ Similarly, if bt traffic count during ACL coexistence
+ has not reached "aclPktCntLowerLimit" continuously
+ for "aclIterToEnableCoex", then ACL coexistence is
+ disabled.
+ -default 100 msecs
+ */
+
+ A_UINT32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of
+ "aclDetectTimeout" for
+ "aclIterForEnDis" times to enabling ACL coex.
+ Similar logic is used to disable acl coexistence.
+ (If "aclPktCntLowerLimit" cnt of acl pkts
+ are not seen by the for "aclIterForEnDis"
+ then acl coexistence is disabled).
+ default = 10
+ */
+
+ A_UINT32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and
+ Disabling Acl Coexistence.
+ default = 3
+ */
+
+ A_UINT32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than
+ "aclPktCntUpperLimit" seen in "aclDetectTimeout",
+ ACL coexistence is enabled right away.
+ - default 15*/
+
+ A_UINT32 aclCoexFlags; /* A2DP Option flags:
+ bits: meaning:
+ 0 Allow Close Range Optimization
+ 1 disable Firmware detection
+ (Currently supported configuration is aclCoexFlags =0)
+ */
+ A_UINT32 linkId; /* Applicable only for STE-BT - not used */
+
+}POSTPACK BTCOEX_ACLCOEX_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 aclDataRespTimeout; /* Max duration firmware waits for downlink
+ by stomping on bluetooth
+ after ps-poll is acknowledged.
+ default = 20 ms */
+
+}POSTPACK BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG;
+
+
+/* Not implemented yet*/
+typedef PREPACK struct {
+ A_UINT32 aclCoexMinlowRateMbps;
+ A_UINT32 aclCoexLowRateCnt;
+ A_UINT32 aclCoexHighPktRatio;
+ A_UINT32 aclCoexMaxAggrSize;
+ A_UINT32 aclPktStompCnt;
+}POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG;
+
+typedef PREPACK struct {
+ BTCOEX_ACLCOEX_CONFIG aclCoexConfig;
+ BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG aclCoexPspollConfig;
+ BTCOEX_OPTMODE_ACLCOEX_CONFIG aclCoexOptConfig;
+}POSTPACK WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD;
+
+/* -----------WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ------------------*/
+typedef enum {
+ WMI_BTCOEX_BT_PROFILE_SCO =1,
+ WMI_BTCOEX_BT_PROFILE_A2DP,
+ WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE,
+ WMI_BTCOEX_BT_PROFILE_ACLCOEX,
+}WMI_BTCOEX_BT_PROFILE;
+
+typedef PREPACK struct {
+ A_UINT32 btProfileType;
+ A_UINT32 btOperatingStatus;
+ A_UINT32 btLinkId;
+}WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD;
+
+/*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/
+/* Used for firmware development and debugging */
+typedef PREPACK struct {
+ A_UINT32 btcoexDbgParam1;
+ A_UINT32 btcoexDbgParam2;
+ A_UINT32 btcoexDbgParam3;
+ A_UINT32 btcoexDbgParam4;
+ A_UINT32 btcoexDbgParam5;
+}WMI_SET_BTCOEX_DEBUG_CMD;
+
+/*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */
+/* Command to firmware to get configuration parameters of the bt profile
+ * reported via WMI_BTCOEX_CONFIG_EVENTID */
+typedef PREPACK struct {
+ A_UINT32 btProfileType; /* 1 - SCO
+ 2 - A2DP
+ 3 - INQUIRY_PAGE
+ 4 - ACLCOEX
+ */
+ A_UINT32 linkId; /* not used */
+}WMI_GET_BTCOEX_CONFIG_CMD;
+
+/*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */
+/* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID
+ * */
+typedef PREPACK struct {
+ A_UINT32 btProfileType;
+ A_UINT32 linkId; /* not used */
+ PREPACK union {
+ WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd;
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd;
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD aclcoexConfig;
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD btinquiryPageConfigCmd;
+ } POSTPACK info;
+} POSTPACK WMI_BTCOEX_CONFIG_EVENT;
+
+/*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/
+/* Used for firmware development and debugging*/
+typedef PREPACK struct {
+ A_UINT32 highRatePktCnt;
+ A_UINT32 firstBmissCnt;
+ A_UINT32 psPollFailureCnt;
+ A_UINT32 nullFrameFailureCnt;
+ A_UINT32 optModeTransitionCnt;
+}BTCOEX_GENERAL_STATS;
+
+typedef PREPACK struct {
+ A_UINT32 scoStompCntAvg;
+ A_UINT32 scoStompIn100ms;
+ A_UINT32 scoMaxContStomp;
+ A_UINT32 scoAvgNoRetries;
+ A_UINT32 scoMaxNoRetriesIn100ms;
+}BTCOEX_SCO_STATS;
+
+typedef PREPACK struct {
+ A_UINT32 a2dpBurstCnt;
+ A_UINT32 a2dpMaxBurstCnt;
+ A_UINT32 a2dpAvgIdletimeIn100ms;
+ A_UINT32 a2dpAvgStompCnt;
+}BTCOEX_A2DP_STATS;
+
+typedef PREPACK struct {
+ A_UINT32 aclPktCntInBtTime;
+ A_UINT32 aclStompCntInWlanTime;
+ A_UINT32 aclPktCntIn100ms;
+}BTCOEX_ACLCOEX_STATS;
+
+typedef PREPACK struct {
+ BTCOEX_GENERAL_STATS coexStats;
+ BTCOEX_SCO_STATS scoStats;
+ BTCOEX_A2DP_STATS a2dpStats;
+ BTCOEX_ACLCOEX_STATS aclCoexStats;
+}WMI_BTCOEX_STATS_EVENT;
+
+
+/*--------------------------END OF BTCOEX -------------------------------------*/
+typedef PREPACK struct {
+ A_UINT32 sleepState;
+}WMI_REPORT_SLEEP_STATE_EVENT;
+
+typedef enum {
+ WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0,
+ WMI_REPORT_SLEEP_STATUS_IS_AWAKE
+} WMI_REPORT_SLEEP_STATUS;
+typedef enum {
+ DISCONN_EVT_IN_RECONN = 0, /* default */
+ NO_DISCONN_EVT_IN_RECONN
+} TARGET_EVENT_REPORT_CONFIG;
+
+typedef PREPACK struct {
+ A_UINT32 evtConfig;
+} POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD;
+
+
+typedef PREPACK struct {
+ A_UINT16 cmd_buf_sz; /* HCI cmd buffer size */
+ A_UINT8 buf[1]; /* Absolute HCI cmd */
+} POSTPACK WMI_HCI_CMD;
+
+/*
+ * Command Replies
+ */
+
+/*
+ * WMI_GET_CHANNEL_LIST_CMDID reply
+ */
+typedef PREPACK struct {
+ A_UINT8 reserved1;
+ A_UINT8 numChannels; /* number of channels in reply */
+ A_UINT16 channelList[1]; /* channel in Mhz */
+} POSTPACK WMI_CHANNEL_LIST_REPLY;
+
+typedef enum {
+ A_SUCCEEDED = A_OK,
+ A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250,
+ A_SUCCEEDED_MODIFY_STREAM=251,
+ A_FAILED_INVALID_STREAM = 252,
+ A_FAILED_MAX_THINSTREAMS = 253,
+ A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254,
+} PSTREAM_REPLY_STATUS;
+
+typedef PREPACK struct {
+ A_UINT8 status; /* PSTREAM_REPLY_STATUS */
+ A_UINT8 txQueueNumber;
+ A_UINT8 rxQueueNumber;
+ A_UINT8 trafficClass;
+ A_UINT8 trafficDirection; /* DIR_TYPE */
+} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY;
+
+typedef PREPACK struct {
+ A_UINT8 status; /* PSTREAM_REPLY_STATUS */
+ A_UINT8 txQueueNumber;
+ A_UINT8 rxQueueNumber;
+ A_UINT8 trafficDirection; /* DIR_TYPE */
+ A_UINT8 trafficClass;
+} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY;
+
+/*
+ * List of Events (target to host)
+ */
+typedef enum {
+ WMI_READY_EVENTID = 0x1001,
+ WMI_CONNECT_EVENTID,
+ WMI_DISCONNECT_EVENTID,
+ WMI_BSSINFO_EVENTID,
+ WMI_CMDERROR_EVENTID,
+ WMI_REGDOMAIN_EVENTID,
+ WMI_PSTREAM_TIMEOUT_EVENTID,
+ WMI_NEIGHBOR_REPORT_EVENTID,
+ WMI_TKIP_MICERR_EVENTID,
+ WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
+ WMI_REPORT_STATISTICS_EVENTID,
+ WMI_RSSI_THRESHOLD_EVENTID,
+ WMI_ERROR_REPORT_EVENTID,
+ WMI_OPT_RX_FRAME_EVENTID,
+ WMI_REPORT_ROAM_TBL_EVENTID,
+ WMI_EXTENSION_EVENTID,
+ WMI_CAC_EVENTID,
+ WMI_SNR_THRESHOLD_EVENTID,
+ WMI_LQ_THRESHOLD_EVENTID,
+ WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
+ WMI_REPORT_ROAM_DATA_EVENTID,
+ WMI_TEST_EVENTID,
+ WMI_APLIST_EVENTID,
+ WMI_GET_WOW_LIST_EVENTID,
+ WMI_GET_PMKID_LIST_EVENTID,
+ WMI_CHANNEL_CHANGE_EVENTID,
+ WMI_PEER_NODE_EVENTID,
+ WMI_PSPOLL_EVENTID,
+ WMI_DTIMEXPIRY_EVENTID,
+ WMI_WLAN_VERSION_EVENTID,
+ WMI_SET_PARAMS_REPLY_EVENTID,
+ WMI_ADDBA_REQ_EVENTID, /*0x1020 */
+ WMI_ADDBA_RESP_EVENTID,
+ WMI_DELBA_REQ_EVENTID,
+ WMI_TX_COMPLETE_EVENTID,
+ WMI_HCI_EVENT_EVENTID,
+ WMI_ACL_DATA_EVENTID,
+ WMI_REPORT_SLEEP_STATE_EVENTID,
+#ifdef WAPI_ENABLE
+ WMI_WAPI_REKEY_EVENTID,
+#endif
+ WMI_REPORT_BTCOEX_STATS_EVENTID,
+ WMI_REPORT_BTCOEX_CONFIG_EVENTID,
+ WMI_ACM_REJECT_EVENTID,
+ WMI_THIN_RESERVED_START_EVENTID = 0x8000,
+ /* Events in this range are reserved for thinmode
+ * See wmi_thin.h for actual definitions */
+ WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
+
+} WMI_EVENT_ID;
+
+
+typedef enum {
+ WMI_11A_CAPABILITY = 1,
+ WMI_11G_CAPABILITY = 2,
+ WMI_11AG_CAPABILITY = 3,
+ WMI_11NA_CAPABILITY = 4,
+ WMI_11NG_CAPABILITY = 5,
+ WMI_11NAG_CAPABILITY = 6,
+ // END CAPABILITY
+ WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY),
+} WMI_PHY_CAPABILITY;
+
+typedef PREPACK struct {
+ A_UINT8 macaddr[ATH_MAC_LEN];
+ A_UINT8 phyCapability; /* WMI_PHY_CAPABILITY */
+} POSTPACK WMI_READY_EVENT_1;
+
+typedef PREPACK struct {
+ A_UINT32 sw_version;
+ A_UINT32 abi_version;
+ A_UINT8 macaddr[ATH_MAC_LEN];
+ A_UINT8 phyCapability; /* WMI_PHY_CAPABILITY */
+} POSTPACK WMI_READY_EVENT_2;
+
+#if defined(ATH_TARGET)
+#ifdef AR6002_REV2
+#define WMI_READY_EVENT WMI_READY_EVENT_1 /* AR6002_REV2 target code */
+#else
+#define WMI_READY_EVENT WMI_READY_EVENT_2 /* AR6001, AR6002_REV4, AR6002_REV5 */
+#endif
+#else
+#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */
+#endif
+
+
+/*
+ * Connect Event
+ */
+typedef PREPACK struct {
+ A_UINT16 channel;
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT16 listenInterval;
+ A_UINT16 beaconInterval;
+ A_UINT32 networkType;
+ A_UINT8 beaconIeLen;
+ A_UINT8 assocReqLen;
+ A_UINT8 assocRespLen;
+ A_UINT8 assocInfo[1];
+} POSTPACK WMI_CONNECT_EVENT;
+
+/*
+ * Disconnect Event
+ */
+typedef enum {
+ NO_NETWORK_AVAIL = 0x01,
+ LOST_LINK = 0x02, /* bmiss */
+ DISCONNECT_CMD = 0x03,
+ BSS_DISCONNECTED = 0x04,
+ AUTH_FAILED = 0x05,
+ ASSOC_FAILED = 0x06,
+ NO_RESOURCES_AVAIL = 0x07,
+ CSERV_DISCONNECT = 0x08,
+ INVALID_PROFILE = 0x0a,
+ DOT11H_CHANNEL_SWITCH = 0x0b,
+ PROFILE_MISMATCH = 0x0c,
+ CONNECTION_EVICTED = 0x0d,
+ IBSS_MERGE = 0xe,
+} WMI_DISCONNECT_REASON;
+
+typedef PREPACK struct {
+ A_UINT16 protocolReasonStatus; /* reason code, see 802.11 spec. */
+ A_UINT8 bssid[ATH_MAC_LEN]; /* set if known */
+ A_UINT8 disconnectReason ; /* see WMI_DISCONNECT_REASON */
+ A_UINT8 assocRespLen;
+ A_UINT8 assocInfo[1];
+} POSTPACK WMI_DISCONNECT_EVENT;
+
+/*
+ * BSS Info Event.
+ * Mechanism used to inform host of the presence and characteristic of
+ * wireless networks present. Consists of bss info header followed by
+ * the beacon or probe-response frame body. The 802.11 header is not included.
+ */
+typedef enum {
+ BEACON_FTYPE = 0x1,
+ PROBERESP_FTYPE,
+ ACTION_MGMT_FTYPE,
+ PROBEREQ_FTYPE,
+} WMI_BI_FTYPE;
+
+enum {
+ BSS_ELEMID_CHANSWITCH = 0x01,
+ BSS_ELEMID_ATHEROS = 0x02,
+};
+
+typedef PREPACK struct {
+ A_UINT16 channel;
+ A_UINT8 frameType; /* see WMI_BI_FTYPE */
+ A_UINT8 snr;
+ A_INT16 rssi;
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT32 ieMask;
+} POSTPACK WMI_BSS_INFO_HDR;
+
+/*
+ * BSS INFO HDR version 2.0
+ * With 6 bytes HTC header and 6 bytes of WMI header
+ * WMI_BSS_INFO_HDR cannot be accomodated in the removed 802.11 management
+ * header space.
+ * - Reduce the ieMask to 2 bytes as only two bit flags are used
+ * - Remove rssi and compute it on the host. rssi = snr - 95
+ */
+typedef PREPACK struct {
+ A_UINT16 channel;
+ A_UINT8 frameType; /* see WMI_BI_FTYPE */
+ A_UINT8 snr;
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT16 ieMask;
+} POSTPACK WMI_BSS_INFO_HDR2;
+
+/*
+ * Command Error Event
+ */
+typedef enum {
+ INVALID_PARAM = 0x01,
+ ILLEGAL_STATE = 0x02,
+ INTERNAL_ERROR = 0x03,
+} WMI_ERROR_CODE;
+
+typedef PREPACK struct {
+ A_UINT16 commandId;
+ A_UINT8 errorCode;
+} POSTPACK WMI_CMD_ERROR_EVENT;
+
+/*
+ * New Regulatory Domain Event
+ */
+typedef PREPACK struct {
+ A_UINT32 regDomain;
+} POSTPACK WMI_REG_DOMAIN_EVENT;
+
+typedef PREPACK struct {
+ A_UINT8 txQueueNumber;
+ A_UINT8 rxQueueNumber;
+ A_UINT8 trafficDirection;
+ A_UINT8 trafficClass;
+} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT;
+
+typedef PREPACK struct {
+ A_UINT8 reserve1;
+ A_UINT8 reserve2;
+ A_UINT8 reserve3;
+ A_UINT8 trafficClass;
+} POSTPACK WMI_ACM_REJECT_EVENT;
+
+/*
+ * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
+ * the host of BSS's it has found that matches the current profile.
+ * It can be used by the host to cache PMKs and/to initiate pre-authentication
+ * if the BSS supports it. The first bssid is always the current associated
+ * BSS.
+ * The bssid and bssFlags information repeats according to the number
+ * or APs reported.
+ */
+typedef enum {
+ WMI_DEFAULT_BSS_FLAGS = 0x00,
+ WMI_PREAUTH_CAPABLE_BSS = 0x01,
+ WMI_PMKID_VALID_BSS = 0x02,
+} WMI_BSS_FLAGS;
+
+typedef PREPACK struct {
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT8 bssFlags; /* see WMI_BSS_FLAGS */
+} POSTPACK WMI_NEIGHBOR_INFO;
+
+typedef PREPACK struct {
+ A_INT8 numberOfAps;
+ WMI_NEIGHBOR_INFO neighbor[1];
+} POSTPACK WMI_NEIGHBOR_REPORT_EVENT;
+
+/*
+ * TKIP MIC Error Event
+ */
+typedef PREPACK struct {
+ A_UINT8 keyid;
+ A_UINT8 ismcast;
+} POSTPACK WMI_TKIP_MICERR_EVENT;
+
+/*
+ * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new)
+ */
+typedef PREPACK struct {
+ A_INT32 status;
+} POSTPACK WMI_SCAN_COMPLETE_EVENT;
+
+#define MAX_OPT_DATA_LEN 1400
+
+/*
+ * WMI_SET_ADHOC_BSSID_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 bssid[ATH_MAC_LEN];
+} POSTPACK WMI_SET_ADHOC_BSSID_CMD;
+
+/*
+ * WMI_SET_OPT_MODE_CMDID
+ */
+typedef enum {
+ SPECIAL_OFF,
+ SPECIAL_ON,
+} OPT_MODE_TYPE;
+
+typedef PREPACK struct {
+ A_UINT8 optMode;
+} POSTPACK WMI_SET_OPT_MODE_CMD;
+
+/*
+ * WMI_TX_OPT_FRAME_CMDID
+ */
+typedef enum {
+ OPT_PROBE_REQ = 0x01,
+ OPT_PROBE_RESP = 0x02,
+ OPT_CPPP_START = 0x03,
+ OPT_CPPP_STOP = 0x04,
+} WMI_OPT_FTYPE;
+
+typedef PREPACK struct {
+ A_UINT16 optIEDataLen;
+ A_UINT8 frmType;
+ A_UINT8 dstAddr[ATH_MAC_LEN];
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT8 reserved; /* For alignment */
+ A_UINT8 optIEData[1];
+} POSTPACK WMI_OPT_TX_FRAME_CMD;
+
+/*
+ * Special frame receive Event.
+ * Mechanism used to inform host of the receiption of the special frames.
+ * Consists of special frame info header followed by special frame body.
+ * The 802.11 header is not included.
+ */
+typedef PREPACK struct {
+ A_UINT16 channel;
+ A_UINT8 frameType; /* see WMI_OPT_FTYPE */
+ A_INT8 snr;
+ A_UINT8 srcAddr[ATH_MAC_LEN];
+ A_UINT8 bssid[ATH_MAC_LEN];
+} POSTPACK WMI_OPT_RX_INFO_HDR;
+
+/*
+ * Reporting statistics.
+ */
+typedef PREPACK struct {
+ A_UINT32 tx_packets;
+ A_UINT32 tx_bytes;
+ A_UINT32 tx_unicast_pkts;
+ A_UINT32 tx_unicast_bytes;
+ A_UINT32 tx_multicast_pkts;
+ A_UINT32 tx_multicast_bytes;
+ A_UINT32 tx_broadcast_pkts;
+ A_UINT32 tx_broadcast_bytes;
+ A_UINT32 tx_rts_success_cnt;
+ A_UINT32 tx_packet_per_ac[4];
+ A_UINT32 tx_errors_per_ac[4];
+
+ A_UINT32 tx_errors;
+ A_UINT32 tx_failed_cnt;
+ A_UINT32 tx_retry_cnt;
+ A_UINT32 tx_mult_retry_cnt;
+ A_UINT32 tx_rts_fail_cnt;
+ A_INT32 tx_unicast_rate;
+}POSTPACK tx_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 rx_packets;
+ A_UINT32 rx_bytes;
+ A_UINT32 rx_unicast_pkts;
+ A_UINT32 rx_unicast_bytes;
+ A_UINT32 rx_multicast_pkts;
+ A_UINT32 rx_multicast_bytes;
+ A_UINT32 rx_broadcast_pkts;
+ A_UINT32 rx_broadcast_bytes;
+ A_UINT32 rx_fragment_pkt;
+
+ A_UINT32 rx_errors;
+ A_UINT32 rx_crcerr;
+ A_UINT32 rx_key_cache_miss;
+ A_UINT32 rx_decrypt_err;
+ A_UINT32 rx_duplicate_frames;
+ A_INT32 rx_unicast_rate;
+}POSTPACK rx_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 tkip_local_mic_failure;
+ A_UINT32 tkip_counter_measures_invoked;
+ A_UINT32 tkip_replays;
+ A_UINT32 tkip_format_errors;
+ A_UINT32 ccmp_format_errors;
+ A_UINT32 ccmp_replays;
+}POSTPACK tkip_ccmp_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 power_save_failure_cnt;
+ A_UINT16 stop_tx_failure_cnt;
+ A_UINT16 atim_tx_failure_cnt;
+ A_UINT16 atim_rx_failure_cnt;
+ A_UINT16 bcn_rx_failure_cnt;
+}POSTPACK pm_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 cs_bmiss_cnt;
+ A_UINT32 cs_lowRssi_cnt;
+ A_UINT16 cs_connect_cnt;
+ A_UINT16 cs_disconnect_cnt;
+ A_INT16 cs_aveBeacon_rssi;
+ A_UINT16 cs_roam_count;
+ A_INT16 cs_rssi;
+ A_UINT8 cs_snr;
+ A_UINT8 cs_aveBeacon_snr;
+ A_UINT8 cs_lastRoam_msec;
+} POSTPACK cserv_stats_t;
+
+typedef PREPACK struct {
+ tx_stats_t tx_stats;
+ rx_stats_t rx_stats;
+ tkip_ccmp_stats_t tkipCcmpStats;
+}POSTPACK wlan_net_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 arp_received;
+ A_UINT32 arp_matched;
+ A_UINT32 arp_replied;
+} POSTPACK arp_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 wow_num_pkts_dropped;
+ A_UINT16 wow_num_events_discarded;
+ A_UINT8 wow_num_host_pkt_wakeups;
+ A_UINT8 wow_num_host_event_wakeups;
+} POSTPACK wlan_wow_stats_t;
+
+typedef PREPACK struct {
+ A_UINT32 lqVal;
+ A_INT32 noise_floor_calibation;
+ pm_stats_t pmStats;
+ wlan_net_stats_t txrxStats;
+ wlan_wow_stats_t wowStats;
+ arp_stats_t arpStats;
+ cserv_stats_t cservStats;
+} POSTPACK WMI_TARGET_STATS;
+
+/*
+ * WMI_RSSI_THRESHOLD_EVENTID.
+ * Indicate the RSSI events to host. Events are indicated when we breach a
+ * thresold value.
+ */
+typedef enum{
+ WMI_RSSI_THRESHOLD1_ABOVE = 0,
+ WMI_RSSI_THRESHOLD2_ABOVE,
+ WMI_RSSI_THRESHOLD3_ABOVE,
+ WMI_RSSI_THRESHOLD4_ABOVE,
+ WMI_RSSI_THRESHOLD5_ABOVE,
+ WMI_RSSI_THRESHOLD6_ABOVE,
+ WMI_RSSI_THRESHOLD1_BELOW,
+ WMI_RSSI_THRESHOLD2_BELOW,
+ WMI_RSSI_THRESHOLD3_BELOW,
+ WMI_RSSI_THRESHOLD4_BELOW,
+ WMI_RSSI_THRESHOLD5_BELOW,
+ WMI_RSSI_THRESHOLD6_BELOW
+}WMI_RSSI_THRESHOLD_VAL;
+
+typedef PREPACK struct {
+ A_INT16 rssi;
+ A_UINT8 range;
+}POSTPACK WMI_RSSI_THRESHOLD_EVENT;
+
+/*
+ * WMI_ERROR_REPORT_EVENTID
+ */
+typedef enum{
+ WMI_TARGET_PM_ERR_FAIL = 0x00000001,
+ WMI_TARGET_KEY_NOT_FOUND = 0x00000002,
+ WMI_TARGET_DECRYPTION_ERR = 0x00000004,
+ WMI_TARGET_BMISS = 0x00000008,
+ WMI_PSDISABLE_NODE_JOIN = 0x00000010,
+ WMI_TARGET_COM_ERR = 0x00000020,
+ WMI_TARGET_FATAL_ERR = 0x00000040
+} WMI_TARGET_ERROR_VAL;
+
+typedef PREPACK struct {
+ A_UINT32 errorVal;
+}POSTPACK WMI_TARGET_ERROR_REPORT_EVENT;
+
+typedef PREPACK struct {
+ A_UINT8 retrys;
+}POSTPACK WMI_TX_RETRY_ERR_EVENT;
+
+typedef enum{
+ WMI_SNR_THRESHOLD1_ABOVE = 1,
+ WMI_SNR_THRESHOLD1_BELOW,
+ WMI_SNR_THRESHOLD2_ABOVE,
+ WMI_SNR_THRESHOLD2_BELOW,
+ WMI_SNR_THRESHOLD3_ABOVE,
+ WMI_SNR_THRESHOLD3_BELOW,
+ WMI_SNR_THRESHOLD4_ABOVE,
+ WMI_SNR_THRESHOLD4_BELOW
+} WMI_SNR_THRESHOLD_VAL;
+
+typedef PREPACK struct {
+ A_UINT8 range; /* WMI_SNR_THRESHOLD_VAL */
+ A_UINT8 snr;
+}POSTPACK WMI_SNR_THRESHOLD_EVENT;
+
+typedef enum{
+ WMI_LQ_THRESHOLD1_ABOVE = 1,
+ WMI_LQ_THRESHOLD1_BELOW,
+ WMI_LQ_THRESHOLD2_ABOVE,
+ WMI_LQ_THRESHOLD2_BELOW,
+ WMI_LQ_THRESHOLD3_ABOVE,
+ WMI_LQ_THRESHOLD3_BELOW,
+ WMI_LQ_THRESHOLD4_ABOVE,
+ WMI_LQ_THRESHOLD4_BELOW
+} WMI_LQ_THRESHOLD_VAL;
+
+typedef PREPACK struct {
+ A_INT32 lq;
+ A_UINT8 range; /* WMI_LQ_THRESHOLD_VAL */
+}POSTPACK WMI_LQ_THRESHOLD_EVENT;
+/*
+ * WMI_REPORT_ROAM_TBL_EVENTID
+ */
+#define MAX_ROAM_TBL_CAND 5
+
+typedef PREPACK struct {
+ A_INT32 roam_util;
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_INT8 rssi;
+ A_INT8 rssidt;
+ A_INT8 last_rssi;
+ A_INT8 util;
+ A_INT8 bias;
+ A_UINT8 reserved; /* For alignment */
+} POSTPACK WMI_BSS_ROAM_INFO;
+
+
+typedef PREPACK struct {
+ A_UINT16 roamMode;
+ A_UINT16 numEntries;
+ WMI_BSS_ROAM_INFO bssRoamInfo[1];
+} POSTPACK WMI_TARGET_ROAM_TBL;
+
+/*
+ * WMI_HCI_EVENT_EVENTID
+ */
+typedef PREPACK struct {
+ A_UINT16 evt_buf_sz; /* HCI event buffer size */
+ A_UINT8 buf[1]; /* HCI event */
+} POSTPACK WMI_HCI_EVENT;
+
+/*
+ * WMI_CAC_EVENTID
+ */
+typedef enum {
+ CAC_INDICATION_ADMISSION = 0x00,
+ CAC_INDICATION_ADMISSION_RESP = 0x01,
+ CAC_INDICATION_DELETE = 0x02,
+ CAC_INDICATION_NO_RESP = 0x03,
+}CAC_INDICATION;
+
+#define WMM_TSPEC_IE_LEN 63
+
+typedef PREPACK struct {
+ A_UINT8 ac;
+ A_UINT8 cac_indication;
+ A_UINT8 statusCode;
+ A_UINT8 tspecSuggestion[WMM_TSPEC_IE_LEN];
+}POSTPACK WMI_CAC_EVENT;
+
+/*
+ * WMI_APLIST_EVENTID
+ */
+
+typedef enum {
+ APLIST_VER1 = 1,
+} APLIST_VER;
+
+typedef PREPACK struct {
+ A_UINT8 bssid[ATH_MAC_LEN];
+ A_UINT16 channel;
+} POSTPACK WMI_AP_INFO_V1;
+
+typedef PREPACK union {
+ WMI_AP_INFO_V1 apInfoV1;
+} POSTPACK WMI_AP_INFO;
+
+typedef PREPACK struct {
+ A_UINT8 apListVer;
+ A_UINT8 numAP;
+ WMI_AP_INFO apList[1];
+} POSTPACK WMI_APLIST_EVENT;
+
+/*
+ * developer commands
+ */
+
+/*
+ * WMI_SET_BITRATE_CMDID
+ *
+ * Get bit rate cmd uses same definition as set bit rate cmd
+ */
+typedef enum {
+ RATE_AUTO = -1,
+ RATE_1Mb = 0,
+ RATE_2Mb = 1,
+ RATE_5_5Mb = 2,
+ RATE_11Mb = 3,
+ RATE_6Mb = 4,
+ RATE_9Mb = 5,
+ RATE_12Mb = 6,
+ RATE_18Mb = 7,
+ RATE_24Mb = 8,
+ RATE_36Mb = 9,
+ RATE_48Mb = 10,
+ RATE_54Mb = 11,
+ RATE_MCS_0_20 = 12,
+ RATE_MCS_1_20 = 13,
+ RATE_MCS_2_20 = 14,
+ RATE_MCS_3_20 = 15,
+ RATE_MCS_4_20 = 16,
+ RATE_MCS_5_20 = 17,
+ RATE_MCS_6_20 = 18,
+ RATE_MCS_7_20 = 19,
+ RATE_MCS_0_40 = 20,
+ RATE_MCS_1_40 = 21,
+ RATE_MCS_2_40 = 22,
+ RATE_MCS_3_40 = 23,
+ RATE_MCS_4_40 = 24,
+ RATE_MCS_5_40 = 25,
+ RATE_MCS_6_40 = 26,
+ RATE_MCS_7_40 = 27,
+} WMI_BIT_RATE;
+
+typedef PREPACK struct {
+ A_INT8 rateIndex; /* see WMI_BIT_RATE */
+ A_INT8 mgmtRateIndex;
+ A_INT8 ctlRateIndex;
+} POSTPACK WMI_BIT_RATE_CMD;
+
+
+typedef PREPACK struct {
+ A_INT8 rateIndex; /* see WMI_BIT_RATE */
+} POSTPACK WMI_BIT_RATE_REPLY;
+
+
+/*
+ * WMI_SET_FIXRATES_CMDID
+ *
+ * Get fix rates cmd uses same definition as set fix rates cmd
+ */
+#define FIX_RATE_1Mb ((A_UINT32)0x1)
+#define FIX_RATE_2Mb ((A_UINT32)0x2)
+#define FIX_RATE_5_5Mb ((A_UINT32)0x4)
+#define FIX_RATE_11Mb ((A_UINT32)0x8)
+#define FIX_RATE_6Mb ((A_UINT32)0x10)
+#define FIX_RATE_9Mb ((A_UINT32)0x20)
+#define FIX_RATE_12Mb ((A_UINT32)0x40)
+#define FIX_RATE_18Mb ((A_UINT32)0x80)
+#define FIX_RATE_24Mb ((A_UINT32)0x100)
+#define FIX_RATE_36Mb ((A_UINT32)0x200)
+#define FIX_RATE_48Mb ((A_UINT32)0x400)
+#define FIX_RATE_54Mb ((A_UINT32)0x800)
+#define FIX_RATE_MCS_0_20 ((A_UINT32)0x1000)
+#define FIX_RATE_MCS_1_20 ((A_UINT32)0x2000)
+#define FIX_RATE_MCS_2_20 ((A_UINT32)0x4000)
+#define FIX_RATE_MCS_3_20 ((A_UINT32)0x8000)
+#define FIX_RATE_MCS_4_20 ((A_UINT32)0x10000)
+#define FIX_RATE_MCS_5_20 ((A_UINT32)0x20000)
+#define FIX_RATE_MCS_6_20 ((A_UINT32)0x40000)
+#define FIX_RATE_MCS_7_20 ((A_UINT32)0x80000)
+#define FIX_RATE_MCS_0_40 ((A_UINT32)0x100000)
+#define FIX_RATE_MCS_1_40 ((A_UINT32)0x200000)
+#define FIX_RATE_MCS_2_40 ((A_UINT32)0x400000)
+#define FIX_RATE_MCS_3_40 ((A_UINT32)0x800000)
+#define FIX_RATE_MCS_4_40 ((A_UINT32)0x1000000)
+#define FIX_RATE_MCS_5_40 ((A_UINT32)0x2000000)
+#define FIX_RATE_MCS_6_40 ((A_UINT32)0x4000000)
+#define FIX_RATE_MCS_7_40 ((A_UINT32)0x8000000)
+
+typedef PREPACK struct {
+ A_UINT32 fixRateMask; /* see WMI_BIT_RATE */
+} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY;
+
+typedef PREPACK struct {
+ A_UINT8 bEnableMask;
+ A_UINT8 frameType; /*type and subtype*/
+ A_UINT32 frameRateMask; /* see WMI_BIT_RATE */
+} POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY;
+
+/*
+ * WMI_SET_RECONNECT_AUTH_MODE_CMDID
+ *
+ * Set authentication mode
+ */
+typedef enum {
+ RECONN_DO_AUTH = 0x00,
+ RECONN_NOT_AUTH = 0x01
+} WMI_AUTH_MODE;
+
+typedef PREPACK struct {
+ A_UINT8 mode;
+} POSTPACK WMI_SET_AUTH_MODE_CMD;
+
+/*
+ * WMI_SET_REASSOC_MODE_CMDID
+ *
+ * Set authentication mode
+ */
+typedef enum {
+ REASSOC_DO_DISASSOC = 0x00,
+ REASSOC_DONOT_DISASSOC = 0x01
+} WMI_REASSOC_MODE;
+
+typedef PREPACK struct {
+ A_UINT8 mode;
+}POSTPACK WMI_SET_REASSOC_MODE_CMD;
+
+typedef enum {
+ ROAM_DATA_TIME = 1, /* Get The Roam Time Data */
+} ROAM_DATA_TYPE;
+
+typedef PREPACK struct {
+ A_UINT32 disassoc_time;
+ A_UINT32 no_txrx_time;
+ A_UINT32 assoc_time;
+ A_UINT32 allow_txrx_time;
+ A_UINT8 disassoc_bssid[ATH_MAC_LEN];
+ A_INT8 disassoc_bss_rssi;
+ A_UINT8 assoc_bssid[ATH_MAC_LEN];
+ A_INT8 assoc_bss_rssi;
+} POSTPACK WMI_TARGET_ROAM_TIME;
+
+typedef PREPACK struct {
+ PREPACK union {
+ WMI_TARGET_ROAM_TIME roamTime;
+ } POSTPACK u;
+ A_UINT8 roamDataType ;
+} POSTPACK WMI_TARGET_ROAM_DATA;
+
+typedef enum {
+ WMI_WMM_DISABLED = 0,
+ WMI_WMM_ENABLED
+} WMI_WMM_STATUS;
+
+typedef PREPACK struct {
+ A_UINT8 status;
+}POSTPACK WMI_SET_WMM_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 status;
+}POSTPACK WMI_SET_QOS_SUPP_CMD;
+
+typedef enum {
+ WMI_TXOP_DISABLED = 0,
+ WMI_TXOP_ENABLED
+} WMI_TXOP_CFG;
+
+typedef PREPACK struct {
+ A_UINT8 txopEnable;
+}POSTPACK WMI_SET_WMM_TXOP_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 keepaliveInterval;
+} POSTPACK WMI_SET_KEEPALIVE_CMD;
+
+typedef PREPACK struct {
+ A_BOOL configured;
+ A_UINT8 keepaliveInterval;
+} POSTPACK WMI_GET_KEEPALIVE_CMD;
+
+/*
+ * Add Application specified IE to a management frame
+ */
+#define WMI_MAX_IE_LEN 255
+
+typedef PREPACK struct {
+ A_UINT8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */
+ A_UINT8 ieLen; /* Length of the IE that should be added to the MGMT frame */
+ A_UINT8 ieInfo[1];
+} POSTPACK WMI_SET_APPIE_CMD;
+
+/*
+ * Notify the WSC registration status to the target
+ */
+#define WSC_REG_ACTIVE 1
+#define WSC_REG_INACTIVE 0
+/* Generic Hal Interface for setting hal paramters. */
+/* Add new Set HAL Param cmdIds here for newer params */
+typedef enum {
+ WHAL_SETCABTO_CMDID = 1,
+}WHAL_CMDID;
+
+typedef PREPACK struct {
+ A_UINT8 cabTimeOut;
+} POSTPACK WHAL_SETCABTO_PARAM;
+
+typedef PREPACK struct {
+ A_UINT8 whalCmdId;
+ A_UINT8 data[1];
+} POSTPACK WHAL_PARAMCMD;
+
+
+#define WOW_MAX_FILTER_LISTS 1 /*4*/
+#define WOW_MAX_FILTERS_PER_LIST 4
+#define WOW_PATTERN_SIZE 64
+#define WOW_MASK_SIZE 64
+
+#define MAC_MAX_FILTERS_PER_LIST 4
+
+typedef PREPACK struct {
+ A_UINT8 wow_valid_filter;
+ A_UINT8 wow_filter_id;
+ A_UINT8 wow_filter_size;
+ A_UINT8 wow_filter_offset;
+ A_UINT8 wow_filter_mask[WOW_MASK_SIZE];
+ A_UINT8 wow_filter_pattern[WOW_PATTERN_SIZE];
+} POSTPACK WOW_FILTER;
+
+
+typedef PREPACK struct {
+ A_UINT8 wow_valid_list;
+ A_UINT8 wow_list_id;
+ A_UINT8 wow_num_filters;
+ A_UINT8 wow_total_list_size;
+ WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST];
+} POSTPACK WOW_FILTER_LIST;
+
+typedef PREPACK struct {
+ A_UINT8 valid_filter;
+ A_UINT8 mac_addr[ATH_MAC_LEN];
+} POSTPACK MAC_FILTER;
+
+
+typedef PREPACK struct {
+ A_UINT8 total_list_size;
+ A_UINT8 enable;
+ MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST];
+} POSTPACK MAC_FILTER_LIST;
+
+#define MAX_IP_ADDRS 2
+typedef PREPACK struct {
+ A_UINT32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */
+} POSTPACK WMI_SET_IP_CMD;
+
+typedef PREPACK struct {
+ A_BOOL awake;
+ A_BOOL asleep;
+} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD;
+
+typedef enum {
+ WOW_FILTER_SSID = 0x1
+} WMI_WOW_FILTER;
+
+typedef PREPACK struct {
+ A_BOOL enable_wow;
+ WMI_WOW_FILTER filter;
+ A_UINT16 hostReqDelay;
+} POSTPACK WMI_SET_WOW_MODE_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 filter_list_id;
+} POSTPACK WMI_GET_WOW_LIST_CMD;
+
+/*
+ * WMI_GET_WOW_LIST_CMD reply
+ */
+typedef PREPACK struct {
+ A_UINT8 num_filters; /* number of patterns in reply */
+ A_UINT8 this_filter_num; /* this is filter # x of total num_filters */
+ A_UINT8 wow_mode;
+ A_UINT8 host_mode;
+ WOW_FILTER wow_filters[1];
+} POSTPACK WMI_GET_WOW_LIST_REPLY;
+
+typedef PREPACK struct {
+ A_UINT8 filter_list_id;
+ A_UINT8 filter_size;
+ A_UINT8 filter_offset;
+ A_UINT8 filter[1];
+} POSTPACK WMI_ADD_WOW_PATTERN_CMD;
+
+typedef PREPACK struct {
+ A_UINT16 filter_list_id;
+ A_UINT16 filter_id;
+} POSTPACK WMI_DEL_WOW_PATTERN_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 macaddr[ATH_MAC_LEN];
+} POSTPACK WMI_SET_MAC_ADDRESS_CMD;
+
+/*
+ * WMI_SET_AKMP_PARAMS_CMD
+ */
+
+#define WMI_AKMP_MULTI_PMKID_EN 0x000001
+
+typedef PREPACK struct {
+ A_UINT32 akmpInfo;
+} POSTPACK WMI_SET_AKMP_PARAMS_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 pmkid[WMI_PMKID_LEN];
+} POSTPACK WMI_PMKID;
+
+/*
+ * WMI_SET_PMKID_LIST_CMD
+ */
+#define WMI_MAX_PMKID_CACHE 8
+
+typedef PREPACK struct {
+ A_UINT32 numPMKID;
+ WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
+} POSTPACK WMI_SET_PMKID_LIST_CMD;
+
+/*
+ * WMI_GET_PMKID_LIST_CMD Reply
+ * Following the Number of PMKIDs is the list of PMKIDs
+ */
+typedef PREPACK struct {
+ A_UINT32 numPMKID;
+ A_UINT8 bssidList[ATH_MAC_LEN][1];
+ WMI_PMKID pmkidList[1];
+} POSTPACK WMI_PMKID_LIST_REPLY;
+
+typedef PREPACK struct {
+ A_UINT16 oldChannel;
+ A_UINT32 newChannel;
+} POSTPACK WMI_CHANNEL_CHANGE_EVENT;
+
+typedef PREPACK struct {
+ A_UINT32 version;
+} POSTPACK WMI_WLAN_VERSION_EVENT;
+
+
+/* WMI_ADDBA_REQ_EVENTID */
+typedef PREPACK struct {
+ A_UINT8 tid;
+ A_UINT8 win_sz;
+ A_UINT16 st_seq_no;
+ A_UINT8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */
+} POSTPACK WMI_ADDBA_REQ_EVENT;
+
+/* WMI_ADDBA_RESP_EVENTID */
+typedef PREPACK struct {
+ A_UINT8 tid;
+ A_UINT8 status; /* OK(0), failure (!=0) */
+ A_UINT16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */
+} POSTPACK WMI_ADDBA_RESP_EVENT;
+
+/* WMI_DELBA_EVENTID
+ * f/w received a DELBA for peer and processed it.
+ * Host is notified of this
+ */
+typedef PREPACK struct {
+ A_UINT8 tid;
+ A_UINT8 is_peer_initiator;
+ A_UINT16 reason_code;
+} POSTPACK WMI_DELBA_EVENT;
+
+
+#ifdef WAPI_ENABLE
+#define WAPI_REKEY_UCAST 1
+#define WAPI_REKEY_MCAST 2
+typedef PREPACK struct {
+ A_UINT8 type;
+ A_UINT8 macAddr[ATH_MAC_LEN];
+} POSTPACK WMI_WAPIREKEY_EVENT;
+#endif
+
+
+/* WMI_ALLOW_AGGR_CMDID
+ * Configures tid's to allow ADDBA negotiations
+ * on each tid, in each direction
+ */
+typedef PREPACK struct {
+ A_UINT16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/
+ A_UINT16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/
+} POSTPACK WMI_ALLOW_AGGR_CMD;
+
+/* WMI_ADDBA_REQ_CMDID
+ * f/w starts performing ADDBA negotiations with peer
+ * on the given tid
+ */
+typedef PREPACK struct {
+ A_UINT8 tid;
+} POSTPACK WMI_ADDBA_REQ_CMD;
+
+/* WMI_DELBA_REQ_CMDID
+ * f/w would teardown BA with peer.
+ * is_send_initiator indicates if it's or tx or rx side
+ */
+typedef PREPACK struct {
+ A_UINT8 tid;
+ A_UINT8 is_sender_initiator;
+
+} POSTPACK WMI_DELBA_REQ_CMD;
+
+#define PEER_NODE_JOIN_EVENT 0x00
+#define PEER_NODE_LEAVE_EVENT 0x01
+#define PEER_FIRST_NODE_JOIN_EVENT 0x10
+#define PEER_LAST_NODE_LEAVE_EVENT 0x11
+typedef PREPACK struct {
+ A_UINT8 eventCode;
+ A_UINT8 peerMacAddr[ATH_MAC_LEN];
+} POSTPACK WMI_PEER_NODE_EVENT;
+
+#define IEEE80211_FRAME_TYPE_MGT 0x00
+#define IEEE80211_FRAME_TYPE_CTL 0x04
+
+/*
+ * Transmit complete event data structure(s)
+ */
+
+
+typedef PREPACK struct {
+#define TX_COMPLETE_STATUS_SUCCESS 0
+#define TX_COMPLETE_STATUS_RETRIES 1
+#define TX_COMPLETE_STATUS_NOLINK 2
+#define TX_COMPLETE_STATUS_TIMEOUT 3
+#define TX_COMPLETE_STATUS_OTHER 4
+
+ A_UINT8 status; /* one of TX_COMPLETE_STATUS_... */
+ A_UINT8 pktID; /* packet ID to identify parent packet */
+ A_UINT8 rateIdx; /* rate index on successful transmission */
+ A_UINT8 ackFailures; /* number of ACK failures in tx attempt */
+#if 0 /* optional params currently ommitted. */
+ A_UINT32 queueDelay; // usec delay measured Tx Start time - host delivery time
+ A_UINT32 mediaDelay; // usec delay measured ACK rx time - host delivery time
+#endif
+} POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */
+
+typedef PREPACK struct {
+ A_UINT8 numMessages; /* number of tx comp msgs following this struct */
+ A_UINT8 msgLen; /* length in bytes for each individual msg following this struct */
+ A_UINT8 msgType; /* version of tx complete msg data following this struct */
+ A_UINT8 reserved; /* individual messages follow this header */
+} POSTPACK WMI_TX_COMPLETE_EVENT;
+
+#define WMI_TXCOMPLETE_VERSION_1 (0x01)
+
+
+/*
+ * ------- AP Mode definitions --------------
+ */
+
+/*
+ * !!! Warning !!!
+ * -Changing the following values needs compilation of both driver and firmware
+ */
+#ifdef AR6002_REV2
+#define AP_MAX_NUM_STA 4
+#else
+#define AP_MAX_NUM_STA 8
+#endif
+#define AP_ACL_SIZE 10
+#define IEEE80211_MAX_IE 256
+#define MCAST_AID 0xFF /* Spl. AID used to set DTIM flag in the beacons */
+#define DEF_AP_COUNTRY_CODE "US "
+#define DEF_AP_WMODE_G WMI_11G_MODE
+#define DEF_AP_WMODE_AG WMI_11AG_MODE
+#define DEF_AP_DTIM 5
+#define DEF_BEACON_INTERVAL 100
+
+/* AP mode disconnect reasons */
+#define AP_DISCONNECT_STA_LEFT 101
+#define AP_DISCONNECT_FROM_HOST 102
+#define AP_DISCONNECT_COMM_TIMEOUT 103
+
+/*
+ * Used with WMI_AP_HIDDEN_SSID_CMDID
+ */
+#define HIDDEN_SSID_FALSE 0
+#define HIDDEN_SSID_TRUE 1
+typedef PREPACK struct {
+ A_UINT8 hidden_ssid;
+} POSTPACK WMI_AP_HIDDEN_SSID_CMD;
+
+/*
+ * Used with WMI_AP_ACL_POLICY_CMDID
+ */
+#define AP_ACL_DISABLE 0x00
+#define AP_ACL_ALLOW_MAC 0x01
+#define AP_ACL_DENY_MAC 0x02
+#define AP_ACL_RETAIN_LIST_MASK 0x80
+typedef PREPACK struct {
+ A_UINT8 policy;
+} POSTPACK WMI_AP_ACL_POLICY_CMD;
+
+/*
+ * Used with WMI_AP_ACL_MAC_LIST_CMDID
+ */
+#define ADD_MAC_ADDR 1
+#define DEL_MAC_ADDR 2
+typedef PREPACK struct {
+ A_UINT8 action;
+ A_UINT8 index;
+ A_UINT8 mac[ATH_MAC_LEN];
+ A_UINT8 wildcard;
+} POSTPACK WMI_AP_ACL_MAC_CMD;
+
+typedef PREPACK struct {
+ A_UINT16 index;
+ A_UINT8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN];
+ A_UINT8 wildcard[AP_ACL_SIZE];
+ A_UINT8 policy;
+} POSTPACK WMI_AP_ACL;
+
+/*
+ * Used with WMI_AP_SET_NUM_STA_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 num_sta;
+} POSTPACK WMI_AP_SET_NUM_STA_CMD;
+
+/*
+ * Used with WMI_AP_SET_MLME_CMDID
+ */
+typedef PREPACK struct {
+ A_UINT8 mac[ATH_MAC_LEN];
+ A_UINT16 reason; /* 802.11 reason code */
+ A_UINT8 cmd; /* operation to perform */
+#define WMI_AP_MLME_ASSOC 1 /* associate station */
+#define WMI_AP_DISASSOC 2 /* disassociate station */
+#define WMI_AP_DEAUTH 3 /* deauthenticate station */
+#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
+#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
+} POSTPACK WMI_AP_SET_MLME_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 period;
+} POSTPACK WMI_AP_CONN_INACT_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 period_min;
+ A_UINT32 dwell_ms;
+} POSTPACK WMI_AP_PROT_SCAN_TIME_CMD;
+
+typedef PREPACK struct {
+ A_BOOL flag;
+ A_UINT16 aid;
+} POSTPACK WMI_AP_SET_PVB_CMD;
+
+#define WMI_DISABLE_REGULATORY_CODE "FF"
+
+typedef PREPACK struct {
+ A_UCHAR countryCode[3];
+} POSTPACK WMI_AP_SET_COUNTRY_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 dtim;
+} POSTPACK WMI_AP_SET_DTIM_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 band; /* specifies which band to apply these values */
+ A_UINT8 enable; /* allows 11n to be disabled on a per band basis */
+ A_UINT8 chan_width_40M_supported;
+ A_UINT8 short_GI_20MHz;
+ A_UINT8 short_GI_40MHz;
+ A_UINT8 intolerance_40MHz;
+ A_UINT8 max_ampdu_len_exp;
+} POSTPACK WMI_SET_HT_CAP_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 sta_chan_width;
+} POSTPACK WMI_SET_HT_OP_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 rateMasks[8];
+} POSTPACK WMI_SET_TX_SELECT_RATES_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 sgiMask;
+ A_UINT8 sgiPERThreshold;
+} POSTPACK WMI_SET_TX_SGI_PARAM_CMD;
+
+#define DEFAULT_SGI_MASK 0x08080000
+#define DEFAULT_SGI_PER 10
+
+typedef PREPACK struct {
+ A_UINT32 rateField; /* 1 bit per rate corresponding to index */
+ A_UINT8 id;
+ A_UINT8 shortTrys;
+ A_UINT8 longTrys;
+ A_UINT8 reserved; /* padding */
+} POSTPACK WMI_SET_RATE_POLICY_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */
+ A_UINT8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 <default> */
+ A_UINT8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target <default> */
+ A_UINT8 reserved[1]; /* alignment */
+} POSTPACK WMI_RX_FRAME_FORMAT_CMD;
+
+
+typedef PREPACK struct {
+ A_UINT8 enable; /* 1 == device operates in thin mode , 0 == normal mode <default> */
+ A_UINT8 reserved[3];
+} POSTPACK WMI_SET_THIN_MODE_CMD;
+
+/* AP mode events */
+/* WMI_PS_POLL_EVENT */
+typedef PREPACK struct {
+ A_UINT16 aid;
+} POSTPACK WMI_PSPOLL_EVENT;
+
+typedef PREPACK struct {
+ A_UINT32 tx_bytes;
+ A_UINT32 tx_pkts;
+ A_UINT32 tx_error;
+ A_UINT32 tx_discard;
+ A_UINT32 rx_bytes;
+ A_UINT32 rx_pkts;
+ A_UINT32 rx_error;
+ A_UINT32 rx_discard;
+ A_UINT32 aid;
+} POSTPACK WMI_PER_STA_STAT;
+
+#define AP_GET_STATS 0
+#define AP_CLEAR_STATS 1
+
+typedef PREPACK struct {
+ A_UINT32 action;
+ WMI_PER_STA_STAT sta[AP_MAX_NUM_STA+1];
+} POSTPACK WMI_AP_MODE_STAT;
+#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(A_UINT32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT)))
+
+#define AP_11BG_RATESET1 1
+#define AP_11BG_RATESET2 2
+#define DEF_AP_11BG_RATESET AP_11BG_RATESET1
+typedef PREPACK struct {
+ A_UINT8 rateset;
+} POSTPACK WMI_AP_SET_11BG_RATESET_CMD;
+/*
+ * End of AP mode definitions
+ */
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_H_ */
diff --git a/drivers/staging/ath6kl/include/common/wmi_thin.h b/drivers/staging/ath6kl/include/common/wmi_thin.h
new file mode 100644
index 000000000000..35391edd20ac
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wmi_thin.h
@@ -0,0 +1,347 @@
+//------------------------------------------------------------------------------
+// <copyright file="wmi_thin.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+/*
+ * This file contains the definitions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI). It includes definitions of all the
+ * commands and events. Commands are messages from the host to the WM.
+ * Events and Replies are messages from the WM to the host.
+ *
+ * Ownership of correctness in regards to WMI commands
+ * belongs to the host driver and the WM is not required to validate
+ * parameters for value, proper range, or any other checking.
+ *
+ */
+
+#ifndef _WMI_THIN_H_
+#define _WMI_THIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum {
+ WMI_THIN_CONFIG_CMDID = 0x8000, // WMI_THIN_RESERVED_START
+ WMI_THIN_SET_MIB_CMDID,
+ WMI_THIN_GET_MIB_CMDID,
+ WMI_THIN_JOIN_CMDID,
+ /* add new CMDID's here */
+ WMI_THIN_RESERVED_END_CMDID = 0x8fff // WMI_THIN_RESERVED_END
+} WMI_THIN_COMMAND_ID;
+
+typedef enum{
+ TEMPLATE_FRM_FIRST = 0,
+ TEMPLATE_FRM_PROBE_REQ =TEMPLATE_FRM_FIRST,
+ TEMPLATE_FRM_BEACON,
+ TEMPLATE_FRM_PROBE_RESP,
+ TEMPLATE_FRM_NULL,
+ TEMPLATE_FRM_QOS_NULL,
+ TEMPLATE_FRM_PSPOLL,
+ TEMPLATE_FRM_MAX
+}WMI_TEMPLATE_FRM_TYPE;
+
+/* TEMPLATE_FRM_LEN... represent the maximum allowable
+ * data lengths (bytes) for each frame type */
+#define TEMPLATE_FRM_LEN_PROBE_REQ (256) /* Symbian dictates a minimum of 256 for these 3 frame types */
+#define TEMPLATE_FRM_LEN_BEACON (256)
+#define TEMPLATE_FRM_LEN_PROBE_RESP (256)
+#define TEMPLATE_FRM_LEN_NULL (32)
+#define TEMPLATE_FRM_LEN_QOS_NULL (32)
+#define TEMPLATE_FRM_LEN_PSPOLL (32)
+#define TEMPLATE_FRM_LEN_SUM (TEMPLATE_FRM_LEN_PROBE_REQ + TEMPLATE_FRM_LEN_BEACON + TEMPLATE_FRM_LEN_PROBE_RESP + \
+ TEMPLATE_FRM_LEN_NULL + TEMPLATE_FRM_LEN_QOS_NULL + TEMPLATE_FRM_LEN_PSPOLL)
+
+
+/* MAC Header Build Rules */
+/* These values allow the host to configure the
+ * target code that is responsible for constructing
+ * the MAC header. In cases where the MAC header
+ * is provided by the host framework, the target
+ * has a diminished responsibility over what fields
+ * it must write. This will vary from framework to framework.
+ * Symbian requires different behavior from MAC80211 which
+ * requires different behavior from MS Native Wifi. */
+#define WMI_WRT_VER_TYPE 0x00000001
+#define WMI_WRT_DURATION 0x00000002
+#define WMI_WRT_DIRECTION 0x00000004
+#define WMI_WRT_POWER 0x00000008
+#define WMI_WRT_WEP 0x00000010
+#define WMI_WRT_MORE 0x00000020
+#define WMI_WRT_BSSID 0x00000040
+#define WMI_WRT_QOS 0x00000080
+#define WMI_WRT_SEQNO 0x00000100
+#define WMI_GUARD_TX 0x00000200 /* prevents TX ops that are not allowed for a current state */
+#define WMI_WRT_DEFAULT_CONFIG (WMI_WRT_VER_TYPE | WMI_WRT_DURATION | WMI_WRT_DIRECTION | \
+ WMI_WRT_POWER | WMI_WRT_MORE | WMI_WRT_WEP | WMI_WRT_BSSID | \
+ WMI_WRT_QOS | WMI_WRT_SEQNO | WMI_GUARD_TX)
+
+/* WMI_THIN_CONFIG_TXCOMPLETE -- Used to configure the params and content for
+ * TX Complete messages the will come from the Target. these messages are
+ * disabled by default but can be enabled using this structure and the
+ * WMI_THIN_CONFIG_CMDID. */
+typedef PREPACK struct {
+ A_UINT8 version; /* the versioned type of messages to use or 0 to disable */
+ A_UINT8 countThreshold; /* msg count threshold triggering a tx complete message */
+ A_UINT16 timeThreshold; /* timeout interval in MSEC triggering a tx complete message */
+} POSTPACK WMI_THIN_CONFIG_TXCOMPLETE;
+
+/* WMI_THIN_CONFIG_DECRYPT_ERR -- Used to configure behavior for received frames
+ * that have decryption errors. The default behavior is to discard the frame
+ * without notification. Alternately, the MAC Header is forwarded to the host
+ * with the failed status. */
+typedef PREPACK struct {
+ A_UINT8 enable; /* 1 == send decrypt errors to the host, 0 == don't */
+ A_UINT8 reserved[3]; /* align padding */
+} POSTPACK WMI_THIN_CONFIG_DECRYPT_ERR;
+
+/* WMI_THIN_CONFIG_TX_MAC_RULES -- Used to configure behavior for transmitted
+ * frames that require partial MAC header construction. These rules
+ * are used by the target to indicate which fields need to be written. */
+typedef PREPACK struct {
+ A_UINT32 rules; /* combination of WMI_WRT_... values */
+} POSTPACK WMI_THIN_CONFIG_TX_MAC_RULES;
+
+/* WMI_THIN_CONFIG_RX_FILTER_RULES -- Used to configure behavior for received
+ * frames as to which frames should get forwarded to the host and which
+ * should get processed internally. */
+typedef PREPACK struct {
+ A_UINT32 rules; /* combination of WMI_FILT_... values */
+} POSTPACK WMI_THIN_CONFIG_RX_FILTER_RULES;
+
+/* WMI_THIN_CONFIG_CMD -- Used to contain some combination of the above
+ * WMI_THIN_CONFIG_... structures. The actual combination is indicated
+ * by the value of cfgField. Each bit in this field corresponds to
+ * one of the above structures. */
+typedef PREPACK struct {
+#define WMI_THIN_CFG_TXCOMP 0x00000001
+#define WMI_THIN_CFG_DECRYPT 0x00000002
+#define WMI_THIN_CFG_MAC_RULES 0x00000004
+#define WMI_THIN_CFG_FILTER_RULES 0x00000008
+ A_UINT32 cfgField; /* combination of WMI_THIN_CFG_... describes contents of config command */
+ A_UINT16 length; /* length in bytes of appended sub-commands */
+ A_UINT8 reserved[2]; /* align padding */
+} POSTPACK WMI_THIN_CONFIG_CMD;
+
+/* MIB Access Identifiers tailored for Symbian. */
+enum {
+ MIB_ID_STA_MAC = 1, // [READONLY]
+ MIB_ID_RX_LIFE_TIME, // [NOT IMPLEMENTED]
+ MIB_ID_SLOT_TIME, // [READ/WRITE]
+ MIB_ID_RTS_THRESHOLD, // [READ/WRITE]
+ MIB_ID_CTS_TO_SELF, // [READ/WRITE]
+ MIB_ID_TEMPLATE_FRAME, // [WRITE ONLY]
+ MIB_ID_RXFRAME_FILTER, // [READ/WRITE]
+ MIB_ID_BEACON_FILTER_TABLE, // [WRITE ONLY]
+ MIB_ID_BEACON_FILTER, // [READ/WRITE]
+ MIB_ID_BEACON_LOST_COUNT, // [WRITE ONLY]
+ MIB_ID_RSSI_THRESHOLD, // [WRITE ONLY]
+ MIB_ID_HT_CAP, // [NOT IMPLEMENTED]
+ MIB_ID_HT_OP, // [NOT IMPLEMENTED]
+ MIB_ID_HT_2ND_BEACON, // [NOT IMPLEMENTED]
+ MIB_ID_HT_BLOCK_ACK, // [NOT IMPLEMENTED]
+ MIB_ID_PREAMBLE, // [READ/WRITE]
+ /*MIB_ID_GROUP_ADDR_TABLE,*/
+ /*MIB_ID_WEP_DEFAULT_KEY_ID */
+ /*MIB_ID_TX_POWER */
+ /*MIB_ID_ARP_IP_TABLE */
+ /*MIB_ID_SLEEP_MODE */
+ /*MIB_ID_WAKE_INTERVAL*/
+ /*MIB_ID_STAT_TABLE*/
+ /*MIB_ID_IBSS_PWR_SAVE*/
+ /*MIB_ID_COUNTERS_TABLE*/
+ /*MIB_ID_ETHERTYPE_FILTER*/
+ /*MIB_ID_BC_UDP_FILTER*/
+
+};
+
+typedef PREPACK struct {
+ A_UINT8 addr[ATH_MAC_LEN];
+} POSTPACK WMI_THIN_MIB_STA_MAC;
+
+typedef PREPACK struct {
+ A_UINT32 time; // units == msec
+} POSTPACK WMI_THIN_MIB_RX_LIFE_TIME;
+
+typedef PREPACK struct {
+ A_UINT8 enable; //1 = on, 0 = off
+} POSTPACK WMI_THIN_MIB_CTS_TO_SELF;
+
+typedef PREPACK struct {
+ A_UINT32 time; // units == usec
+} POSTPACK WMI_THIN_MIB_SLOT_TIME;
+
+typedef PREPACK struct {
+ A_UINT16 length; //units == bytes
+} POSTPACK WMI_THIN_MIB_RTS_THRESHOLD;
+
+typedef PREPACK struct {
+ A_UINT8 type; // type of frame
+ A_UINT8 rate; // tx rate to be used (one of WMI_BIT_RATE)
+ A_UINT16 length; // num bytes following this structure as the template data
+} POSTPACK WMI_THIN_MIB_TEMPLATE_FRAME;
+
+typedef PREPACK struct {
+#define FRAME_FILTER_PROMISCUOUS 0x00000001
+#define FRAME_FILTER_BSSID 0x00000002
+ A_UINT32 filterMask;
+} POSTPACK WMI_THIN_MIB_RXFRAME_FILTER;
+
+
+#define IE_FILTER_TREATMENT_CHANGE 1
+#define IE_FILTER_TREATMENT_APPEAR 2
+
+typedef PREPACK struct {
+ A_UINT8 ie;
+ A_UINT8 treatment;
+} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE;
+
+typedef PREPACK struct {
+ A_UINT8 ie;
+ A_UINT8 treatment;
+ A_UINT8 oui[3];
+ A_UINT8 type;
+ A_UINT16 version;
+} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_OUI;
+
+typedef PREPACK struct {
+ A_UINT16 numElements;
+ A_UINT8 entrySize; // sizeof(WMI_THIN_MIB_BEACON_FILTER_TABLE) on host cpu may be 2 may be 4
+ A_UINT8 reserved;
+} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_HEADER;
+
+typedef PREPACK struct {
+ A_UINT32 count; /* num beacons between deliveries */
+ A_UINT8 enable;
+ A_UINT8 reserved[3];
+} POSTPACK WMI_THIN_MIB_BEACON_FILTER;
+
+typedef PREPACK struct {
+ A_UINT32 count; /* num consec lost beacons after which send event */
+} POSTPACK WMI_THIN_MIB_BEACON_LOST_COUNT;
+
+typedef PREPACK struct {
+ A_UINT8 rssi; /* the low threshold which can trigger an event warning */
+ A_UINT8 tolerance; /* the range above and below the threshold to prevent event flooding to the host. */
+ A_UINT8 count; /* the sample count of consecutive frames necessary to trigger an event. */
+ A_UINT8 reserved[1]; /* padding */
+} POSTPACK WMI_THIN_MIB_RSSI_THRESHOLD;
+
+
+typedef PREPACK struct {
+ A_UINT32 cap;
+ A_UINT32 rxRateField;
+ A_UINT32 beamForming;
+ A_UINT8 addr[ATH_MAC_LEN];
+ A_UINT8 enable;
+ A_UINT8 stbc;
+ A_UINT8 maxAMPDU;
+ A_UINT8 msduSpacing;
+ A_UINT8 mcsFeedback;
+ A_UINT8 antennaSelCap;
+} POSTPACK WMI_THIN_MIB_HT_CAP;
+
+typedef PREPACK struct {
+ A_UINT32 infoField;
+ A_UINT32 basicRateField;
+ A_UINT8 protection;
+ A_UINT8 secondChanneloffset;
+ A_UINT8 channelWidth;
+ A_UINT8 reserved;
+} POSTPACK WMI_THIN_MIB_HT_OP;
+
+typedef PREPACK struct {
+#define SECOND_BEACON_PRIMARY 1
+#define SECOND_BEACON_EITHER 2
+#define SECOND_BEACON_SECONDARY 3
+ A_UINT8 cfg;
+ A_UINT8 reserved[3]; /* padding */
+} POSTPACK WMI_THIN_MIB_HT_2ND_BEACON;
+
+typedef PREPACK struct {
+ A_UINT8 txTIDField;
+ A_UINT8 rxTIDField;
+ A_UINT8 reserved[2]; /* padding */
+} POSTPACK WMI_THIN_MIB_HT_BLOCK_ACK;
+
+typedef PREPACK struct {
+ A_UINT8 enableLong; // 1 == long preamble, 0 == short preamble
+ A_UINT8 reserved[3];
+} POSTPACK WMI_THIN_MIB_PREAMBLE;
+
+typedef PREPACK struct {
+ A_UINT16 length; /* the length in bytes of the appended MIB data */
+ A_UINT8 mibID; /* the ID of the MIB element being set */
+ A_UINT8 reserved; /* align padding */
+} POSTPACK WMI_THIN_SET_MIB_CMD;
+
+typedef PREPACK struct {
+ A_UINT8 mibID; /* the ID of the MIB element being set */
+ A_UINT8 reserved[3]; /* align padding */
+} POSTPACK WMI_THIN_GET_MIB_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 basicRateMask; /* bit mask of basic rates */
+ A_UINT32 beaconIntval; /* TUs */
+ A_UINT16 atimWindow; /* TUs */
+ A_UINT16 channel; /* frequency in Mhz */
+ A_UINT8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */
+ A_UINT8 ssidLength; /* 0 - 32 */
+ A_UINT8 probe; /* != 0 : issue probe req at start */
+ A_UINT8 reserved; /* alignment */
+ A_UCHAR ssid[WMI_MAX_SSID_LEN];
+ A_UINT8 bssid[ATH_MAC_LEN];
+} POSTPACK WMI_THIN_JOIN_CMD;
+
+typedef PREPACK struct {
+ A_UINT16 dtim; /* dtim interval in num beacons */
+ A_UINT16 aid; /* 80211 AID from Assoc resp */
+} POSTPACK WMI_THIN_POST_ASSOC_CMD;
+
+typedef enum {
+ WMI_THIN_EVENTID_RESERVED_START = 0x8000,
+ WMI_THIN_GET_MIB_EVENTID,
+ WMI_THIN_JOIN_EVENTID,
+
+ /* Add new THIN EVENTID's here */
+ WMI_THIN_EVENTID_RESERVED_END = 0x8fff
+} WMI_THIN_EVENT_ID;
+
+/* Possible values for WMI_THIN_JOIN_EVENT.result */
+typedef enum {
+ WMI_THIN_JOIN_RES_SUCCESS = 0, // device has joined the network
+ WMI_THIN_JOIN_RES_FAIL, // device failed for unspecified reason
+ WMI_THIN_JOIN_RES_TIMEOUT, // device failed due to no beacon rx in time limit
+ WMI_THIN_JOIN_RES_BAD_PARAM, // device failed due to bad cmd param.
+}WMI_THIN_JOIN_RESULT;
+
+typedef PREPACK struct {
+ A_UINT8 result; /* the result of the join cmd. one of WMI_THIN_JOIN_RESULT */
+ A_UINT8 reserved[3]; /* alignment */
+} POSTPACK WMI_THIN_JOIN_EVENT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_THIN_H_ */
diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h
new file mode 100644
index 000000000000..87046e364bae
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common/wmix.h
@@ -0,0 +1,279 @@
+//------------------------------------------------------------------------------
+// <copyright file="wmix.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+/*
+ * This file contains extensions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI). It includes definitions of all
+ * extended commands and events. Extensions include useful commands
+ * that are not directly related to wireless activities. They may
+ * be hardware-specific, and they might not be supported on all
+ * implementations.
+ *
+ * Extended WMIX commands are encapsulated in a WMI message with
+ * cmd=WMI_EXTENSION_CMD.
+ */
+
+#ifndef _WMIX_H_
+#define _WMIX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ATH_TARGET
+#include "athstartpack.h"
+#endif
+
+#include "dbglog.h"
+
+/*
+ * Extended WMI commands are those that are needed during wireless
+ * operation, but which are not really wireless commands. This allows,
+ * for instance, platform-specific commands. Extended WMI commands are
+ * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
+ * Extended WMI events are similarly embedded in a WMI event message with
+ * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
+ */
+typedef PREPACK struct {
+ A_UINT32 commandId;
+} POSTPACK WMIX_CMD_HDR;
+
+typedef enum {
+ WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
+ WMIX_DSETDATA_REPLY_CMDID,
+ WMIX_GPIO_OUTPUT_SET_CMDID,
+ WMIX_GPIO_INPUT_GET_CMDID,
+ WMIX_GPIO_REGISTER_SET_CMDID,
+ WMIX_GPIO_REGISTER_GET_CMDID,
+ WMIX_GPIO_INTR_ACK_CMDID,
+ WMIX_HB_CHALLENGE_RESP_CMDID,
+ WMIX_DBGLOG_CFG_MODULE_CMDID,
+ WMIX_PROF_CFG_CMDID, /* 0x200a */
+ WMIX_PROF_ADDR_SET_CMDID,
+ WMIX_PROF_START_CMDID,
+ WMIX_PROF_STOP_CMDID,
+ WMIX_PROF_COUNT_GET_CMDID,
+} WMIX_COMMAND_ID;
+
+typedef enum {
+ WMIX_DSETOPENREQ_EVENTID = 0x3001,
+ WMIX_DSETCLOSE_EVENTID,
+ WMIX_DSETDATAREQ_EVENTID,
+ WMIX_GPIO_INTR_EVENTID,
+ WMIX_GPIO_DATA_EVENTID,
+ WMIX_GPIO_ACK_EVENTID,
+ WMIX_HB_CHALLENGE_RESP_EVENTID,
+ WMIX_DBGLOG_EVENTID,
+ WMIX_PROF_COUNT_EVENTID,
+} WMIX_EVENT_ID;
+
+/*
+ * =============DataSet support=================
+ */
+
+/*
+ * WMIX_DSETOPENREQ_EVENTID
+ * DataSet Open Request Event
+ */
+typedef PREPACK struct {
+ A_UINT32 dset_id;
+ A_UINT32 targ_dset_handle; /* echo'ed, not used by Host, */
+ A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */
+ A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */
+} POSTPACK WMIX_DSETOPENREQ_EVENT;
+
+/*
+ * WMIX_DSETCLOSE_EVENTID
+ * DataSet Close Event
+ */
+typedef PREPACK struct {
+ A_UINT32 access_cookie;
+} POSTPACK WMIX_DSETCLOSE_EVENT;
+
+/*
+ * WMIX_DSETDATAREQ_EVENTID
+ * DataSet Data Request Event
+ */
+typedef PREPACK struct {
+ A_UINT32 access_cookie;
+ A_UINT32 offset;
+ A_UINT32 length;
+ A_UINT32 targ_buf; /* echo'ed, not used by Host, */
+ A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */
+ A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */
+} POSTPACK WMIX_DSETDATAREQ_EVENT;
+
+typedef PREPACK struct {
+ A_UINT32 status;
+ A_UINT32 targ_dset_handle;
+ A_UINT32 targ_reply_fn;
+ A_UINT32 targ_reply_arg;
+ A_UINT32 access_cookie;
+ A_UINT32 size;
+ A_UINT32 version;
+} POSTPACK WMIX_DSETOPEN_REPLY_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 status;
+ A_UINT32 targ_buf;
+ A_UINT32 targ_reply_fn;
+ A_UINT32 targ_reply_arg;
+ A_UINT32 length;
+ A_UINT8 buf[1];
+} POSTPACK WMIX_DSETDATA_REPLY_CMD;
+
+
+/*
+ * =============GPIO support=================
+ * All masks are 18-bit masks with bit N operating on GPIO pin N.
+ */
+
+#include "gpio.h"
+
+/*
+ * Set GPIO pin output state.
+ * In order for output to be driven, a pin must be enabled for output.
+ * This can be done during initialization through the GPIO Configuration
+ * DataSet, or during operation with the enable_mask.
+ *
+ * If a request is made to simultaneously set/clear or set/disable or
+ * clear/disable or disable/enable, results are undefined.
+ */
+typedef PREPACK struct {
+ A_UINT32 set_mask; /* pins to set */
+ A_UINT32 clear_mask; /* pins to clear */
+ A_UINT32 enable_mask; /* pins to enable for output */
+ A_UINT32 disable_mask; /* pins to disable/tristate */
+} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD;
+
+/*
+ * Set a GPIO register. For debug/exceptional cases.
+ * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a
+ * platform-dependent header.
+ */
+typedef PREPACK struct {
+ A_UINT32 gpioreg_id; /* GPIO register ID */
+ A_UINT32 value; /* value to write */
+} POSTPACK WMIX_GPIO_REGISTER_SET_CMD;
+
+/* Get a GPIO register. For debug/exceptional cases. */
+typedef PREPACK struct {
+ A_UINT32 gpioreg_id; /* GPIO register to read */
+} POSTPACK WMIX_GPIO_REGISTER_GET_CMD;
+
+/*
+ * Host acknowledges and re-arms GPIO interrupts. A single
+ * message should be used to acknowledge all interrupts that
+ * were delivered in an earlier WMIX_GPIO_INTR_EVENT message.
+ */
+typedef PREPACK struct {
+ A_UINT32 ack_mask; /* interrupts to acknowledge */
+} POSTPACK WMIX_GPIO_INTR_ACK_CMD;
+
+/*
+ * Target informs Host of GPIO interrupts that have ocurred since the
+ * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information --
+ * the current GPIO input values is provided -- in order to support
+ * use of a GPIO interrupt as a Data Valid signal for other GPIO pins.
+ */
+typedef PREPACK struct {
+ A_UINT32 intr_mask; /* pending GPIO interrupts */
+ A_UINT32 input_values; /* recent GPIO input values */
+} POSTPACK WMIX_GPIO_INTR_EVENT;
+
+/*
+ * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request
+ * using a GPIO_DATA_EVENT with
+ * value set to the mask of GPIO pin inputs and
+ * reg_id set to GPIO_ID_NONE
+ *
+ *
+ * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request
+ * using a GPIO_DATA_EVENT with
+ * value set to the value of the requested register and
+ * reg_id identifying the register (reflects the original request)
+ * NB: reg_id supports the future possibility of unsolicited
+ * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may
+ * simplify Host GPIO support.
+ */
+typedef PREPACK struct {
+ A_UINT32 value;
+ A_UINT32 reg_id;
+} POSTPACK WMIX_GPIO_DATA_EVENT;
+
+/*
+ * =============Error Detection support=================
+ */
+
+/*
+ * WMIX_HB_CHALLENGE_RESP_CMDID
+ * Heartbeat Challenge Response command
+ */
+typedef PREPACK struct {
+ A_UINT32 cookie;
+ A_UINT32 source;
+} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD;
+
+/*
+ * WMIX_HB_CHALLENGE_RESP_EVENTID
+ * Heartbeat Challenge Response Event
+ */
+#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD
+
+typedef PREPACK struct {
+ struct dbglog_config_s config;
+} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD;
+
+/*
+ * =============Target Profiling support=================
+ */
+
+typedef PREPACK struct {
+ A_UINT32 period; /* Time (in 30.5us ticks) between samples */
+ A_UINT32 nbins;
+} POSTPACK WMIX_PROF_CFG_CMD;
+
+typedef PREPACK struct {
+ A_UINT32 addr;
+} POSTPACK WMIX_PROF_ADDR_SET_CMD;
+
+/*
+ * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request
+ * using a WMIX_PROF_COUNT_EVENT with
+ * addr set to the next address
+ * count set to the corresponding count
+ */
+typedef PREPACK struct {
+ A_UINT32 addr;
+ A_UINT32 count;
+} POSTPACK WMIX_PROF_COUNT_EVENT;
+
+#ifndef ATH_TARGET
+#include "athendpack.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMIX_H_ */
diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h
new file mode 100644
index 000000000000..8ebb93d5f3c2
--- /dev/null
+++ b/drivers/staging/ath6kl/include/common_drv.h
@@ -0,0 +1,108 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef COMMON_DRV_H_
+#define COMMON_DRV_H_
+
+#include "hif.h"
+#include "htc_packet.h"
+#include "htc_api.h"
+
+/* structure that is the state information for the default credit distribution callback
+ * drivers should instantiate (zero-init as well) this structure in their driver instance
+ * and pass it as a context to the HTC credit distribution functions */
+typedef struct _COMMON_CREDIT_STATE_INFO {
+ int TotalAvailableCredits; /* total credits in the system at startup */
+ int CurrentFreeCredits; /* credits available in the pool that have not been
+ given out to endpoints */
+ HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */
+} COMMON_CREDIT_STATE_INFO;
+
+typedef struct {
+ A_INT32 (*setupTransport)(void *ar);
+ void (*cleanupTransport)(void *ar);
+} HCI_TRANSPORT_CALLBACKS;
+
+typedef struct {
+ void *netDevice;
+ void *hifDevice;
+ void *htcHandle;
+} HCI_TRANSPORT_MISC_HANDLES;
+
+/* HTC TX packet tagging definitions */
+#define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
+#define AR6K_DATA_PKT_TAG (AR6K_CONTROL_PKT_TAG + 1)
+
+#define AR6002_VERSION_REV1 0x20000086
+#define AR6002_VERSION_REV2 0x20000188
+#define AR6003_VERSION_REV1 0x300002ba
+#define AR6003_VERSION_REV2 0x30000384
+
+#define AR6002_CUST_DATA_SIZE 112
+#define AR6003_CUST_DATA_SIZE 16
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* OS-independent APIs */
+A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo);
+
+A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+
+A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+
+A_STATUS ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length);
+
+A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset);
+
+void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType);
+
+A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 MboxIsrYieldValue,
+ A_UINT8 HtcControlBuffers);
+
+A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 TargetVersion);
+
+A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 Flags);
+
+void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType);
+
+A_UINT8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType);
+
+A_STATUS ar6000_setBTState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
+
+A_STATUS ar6000_setDevicePowerState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
+
+A_STATUS ar6000_setWowMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
+
+A_STATUS ar6000_setHostMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*COMMON_DRV_H_*/
diff --git a/drivers/staging/ath6kl/include/dbglog_api.h b/drivers/staging/ath6kl/include/dbglog_api.h
new file mode 100644
index 000000000000..a53aed316e3b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dbglog_api.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// <copyright file="dbglog_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains host side debug primitives.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _DBGLOG_API_H_
+#define _DBGLOG_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "dbglog.h"
+
+#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE
+
+#define DBGLOG_GET_DBGID(arg) \
+ ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET)
+
+#define DBGLOG_GET_MODULEID(arg) \
+ ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET)
+
+#define DBGLOG_GET_NUMARGS(arg) \
+ ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET)
+
+#define DBGLOG_GET_TIMESTAMP(arg) \
+ ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DBGLOG_API_H_ */
diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h
new file mode 100644
index 000000000000..110e1d8b047d
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dl_list.h
@@ -0,0 +1,153 @@
+//------------------------------------------------------------------------------
+// <copyright file="dl_list.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Double-link list definitions (adapted from Atheros SDIO stack)
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef __DL_LIST_H___
+#define __DL_LIST_H___
+
+#include "a_osapi.h"
+
+#define A_CONTAINING_STRUCT(address, struct_type, field_name)\
+ ((struct_type *)((unsigned long)(address) - (unsigned long)(&((struct_type *)0)->field_name)))
+
+/* list functions */
+/* pointers for the list */
+typedef struct _DL_LIST {
+ struct _DL_LIST *pPrev;
+ struct _DL_LIST *pNext;
+}DL_LIST, *PDL_LIST;
+/*
+ * DL_LIST_INIT , initialize doubly linked list
+*/
+#define DL_LIST_INIT(pList)\
+ {(pList)->pPrev = pList; (pList)->pNext = pList;}
+
+/* faster macro to init list and add a single item */
+#define DL_LIST_INIT_AND_ADD(pList,pItem) \
+{ (pList)->pPrev = (pItem); \
+ (pList)->pNext = (pItem); \
+ (pItem)->pNext = (pList); \
+ (pItem)->pPrev = (pList); \
+}
+
+#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
+#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
+#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
+/*
+ * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
+ * NOT: do not use this function if the items in the list are deleted inside the
+ * iteration loop
+*/
+#define ITERATE_OVER_LIST(pStart, pTemp) \
+ for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
+
+
+/* safe iterate macro that allows the item to be removed from the list
+ * the iteration continues to the next item in the list
+ */
+#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \
+{ \
+ PDL_LIST pTemp; \
+ pTemp = (pStart)->pNext; \
+ while (pTemp != (pStart)) { \
+ (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \
+ pTemp = pTemp->pNext; \
+
+#define ITERATE_END }}
+
+/*
+ * DL_ListInsertTail - insert pAdd to the end of the list
+*/
+static INLINE PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) {
+ /* insert at tail */
+ pAdd->pPrev = pList->pPrev;
+ pAdd->pNext = pList;
+ pList->pPrev->pNext = pAdd;
+ pList->pPrev = pAdd;
+ return pAdd;
+}
+
+/*
+ * DL_ListInsertHead - insert pAdd into the head of the list
+*/
+static INLINE PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) {
+ /* insert at head */
+ pAdd->pPrev = pList;
+ pAdd->pNext = pList->pNext;
+ pList->pNext->pPrev = pAdd;
+ pList->pNext = pAdd;
+ return pAdd;
+}
+
+#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem))
+/*
+ * DL_ListRemove - remove pDel from list
+*/
+static INLINE PDL_LIST DL_ListRemove(PDL_LIST pDel) {
+ pDel->pNext->pPrev = pDel->pPrev;
+ pDel->pPrev->pNext = pDel->pNext;
+ /* point back to itself just to be safe, incase remove is called again */
+ pDel->pNext = pDel;
+ pDel->pPrev = pDel;
+ return pDel;
+}
+
+/*
+ * DL_ListRemoveItemFromHead - get a list item from the head
+*/
+static INLINE PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) {
+ PDL_LIST pItem = NULL;
+ if (pList->pNext != pList) {
+ pItem = pList->pNext;
+ /* remove the first item from head */
+ DL_ListRemove(pItem);
+ }
+ return pItem;
+}
+
+static INLINE PDL_LIST DL_ListRemoveItemFromTail(PDL_LIST pList) {
+ PDL_LIST pItem = NULL;
+ if (pList->pPrev != pList) {
+ pItem = pList->pPrev;
+ /* remove the item from tail */
+ DL_ListRemove(pItem);
+ }
+ return pItem;
+}
+
+/* transfer src list items to the tail of the destination list */
+static INLINE void DL_ListTransferItemsToTail(PDL_LIST pDest, PDL_LIST pSrc) {
+ /* only concatenate if src is not empty */
+ if (!DL_LIST_IS_EMPTY(pSrc)) {
+ /* cut out circular list in src and re-attach to end of dest */
+ pSrc->pPrev->pNext = pDest;
+ pSrc->pNext->pPrev = pDest->pPrev;
+ pDest->pPrev->pNext = pSrc->pNext;
+ pDest->pPrev = pSrc->pPrev;
+ /* terminate src list, it is now empty */
+ pSrc->pPrev = pSrc;
+ pSrc->pNext = pSrc;
+ }
+}
+
+#endif /* __DL_LIST_H___ */
diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h
new file mode 100644
index 000000000000..0cc121fd25a0
--- /dev/null
+++ b/drivers/staging/ath6kl/include/dset_api.h
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+// <copyright file="dset_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Host-side DataSet API.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _DSET_API_H_
+#define _DSET_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Host-side DataSet support is optional, and is not
+ * currently required for correct operation. To disable
+ * Host-side DataSet support, set this to 0.
+ */
+#ifndef CONFIG_HOST_DSET_SUPPORT
+#define CONFIG_HOST_DSET_SUPPORT 1
+#endif
+
+/* Called to send a DataSet Open Reply back to the Target. */
+A_STATUS wmi_dset_open_reply(struct wmi_t *wmip,
+ A_UINT32 status,
+ A_UINT32 access_cookie,
+ A_UINT32 size,
+ A_UINT32 version,
+ A_UINT32 targ_handle,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg);
+
+/* Called to send a DataSet Data Reply back to the Target. */
+A_STATUS wmi_dset_data_reply(struct wmi_t *wmip,
+ A_UINT32 status,
+ A_UINT8 *host_buf,
+ A_UINT32 length,
+ A_UINT32 targ_buf,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* _DSET_API_H_ */
diff --git a/drivers/staging/ath6kl/include/gpio_api.h b/drivers/staging/ath6kl/include/gpio_api.h
new file mode 100644
index 000000000000..96a150383358
--- /dev/null
+++ b/drivers/staging/ath6kl/include/gpio_api.h
@@ -0,0 +1,59 @@
+//------------------------------------------------------------------------------
+// <copyright file="gpio_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Host-side General Purpose I/O API.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _GPIO_API_H_
+#define _GPIO_API_H_
+
+/*
+ * Send a command to the Target in order to change output on GPIO pins.
+ */
+A_STATUS wmi_gpio_output_set(struct wmi_t *wmip,
+ A_UINT32 set_mask,
+ A_UINT32 clear_mask,
+ A_UINT32 enable_mask,
+ A_UINT32 disable_mask);
+
+/*
+ * Send a command to the Target requesting input state of GPIO pins.
+ */
+A_STATUS wmi_gpio_input_get(struct wmi_t *wmip);
+
+/*
+ * Send a command to the Target to change the value of a GPIO register.
+ */
+A_STATUS wmi_gpio_register_set(struct wmi_t *wmip,
+ A_UINT32 gpioreg_id,
+ A_UINT32 value);
+
+/*
+ * Send a command to the Target to fetch the value of a GPIO register.
+ */
+A_STATUS wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id);
+
+/*
+ * Send a command to the Target, acknowledging some GPIO interrupts.
+ */
+A_STATUS wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask);
+
+#endif /* _GPIO_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h
new file mode 100644
index 000000000000..b5157ea5d9e9
--- /dev/null
+++ b/drivers/staging/ath6kl/include/hci_transport_api.h
@@ -0,0 +1,259 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HCI_TRANSPORT_API_H_
+#define _HCI_TRANSPORT_API_H_
+
+ /* Bluetooth HCI packets are stored in HTC packet containers */
+#include "htc_packet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef void *HCI_TRANSPORT_HANDLE;
+
+typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE;
+
+ /* we map each HCI packet class to a static Endpoint ID */
+#define HCI_COMMAND_TYPE ENDPOINT_1
+#define HCI_EVENT_TYPE ENDPOINT_2
+#define HCI_ACL_TYPE ENDPOINT_3
+#define HCI_PACKET_INVALID ENDPOINT_MAX
+
+#define HCI_GET_PACKET_TYPE(pP) (pP)->Endpoint
+#define HCI_SET_PACKET_TYPE(pP,s) (pP)->Endpoint = (s)
+
+/* callback when an HCI packet was completely sent */
+typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, HTC_PACKET *);
+/* callback when an HCI packet is received */
+typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, HTC_PACKET *);
+/* Optional receive buffer re-fill callback,
+ * On some OSes (like Linux) packets are allocated from a global pool and indicated up
+ * to the network stack. The driver never gets the packets back from the OS. For these OSes
+ * a refill callback can be used to allocate and re-queue buffers into HTC.
+ * A refill callback is used for the reception of ACL and EVENT packets. The caller must
+ * set the watermark trigger point to cause a refill.
+ */
+typedef void (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable);
+/* Optional receive packet refill
+ * On some systems packet buffers are an extremely limited resource. Rather than
+ * queue largest-possible-sized buffers to the HCI bridge, some systems would rather
+ * allocate a specific size as the packet is received. The trade off is
+ * slightly more processing (callback invoked for each RX packet)
+ * for the benefit of committing fewer buffer resources into the bridge.
+ *
+ * The callback is provided the length of the pending packet to fetch. This includes the
+ * full transport header, HCI header, plus the length of payload. The callback can return a pointer to
+ * the allocated HTC packet for immediate use.
+ *
+ * NOTE*** This callback is mutually exclusive with the the refill callback above.
+ *
+ * */
+typedef HTC_PACKET *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length);
+
+typedef enum _HCI_SEND_FULL_ACTION {
+ HCI_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
+ HCI_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
+} HCI_SEND_FULL_ACTION;
+
+/* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold,
+ * the callback must return the send full action to take (either DROP or KEEP) */
+typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, HTC_PACKET *);
+
+typedef struct {
+ int HeadRoom; /* number of bytes in front of HCI packet for header space */
+ int TailRoom; /* number of bytes at the end of the HCI packet for tail space */
+ int IOBlockPad; /* I/O block padding required (always a power of 2) */
+} HCI_TRANSPORT_PROPERTIES;
+
+typedef struct _HCI_TRANSPORT_CONFIG_INFO {
+ int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */
+ int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */
+ int MaxSendQueueDepth; /* max number of packets in the single send queue */
+ void *pContext; /* context for all callbacks */
+ void (*TransportFailure)(void *pContext, A_STATUS Status); /* transport failure callback */
+ A_STATUS (*TransportReady)(HCI_TRANSPORT_HANDLE, HCI_TRANSPORT_PROPERTIES *,void *pContext); /* transport is ready */
+ void (*TransportRemoved)(void *pContext); /* transport was removed */
+ /* packet processing callbacks */
+ HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete;
+ HCI_TRANSPORT_RECV_PKT pHCIPktRecv;
+ HCI_TRANSPORT_RECV_REFILL pHCIPktRecvRefill;
+ HCI_TRANSPORT_RECV_ALLOC pHCIPktRecvAlloc;
+ HCI_TRANSPORT_SEND_FULL pHCISendFull;
+} HCI_TRANSPORT_CONFIG_INFO;
+
+/* ------ Function Prototypes ------ */
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Attach to the HCI transport module
+ @function name: HCI_TransportAttach
+ @input: HTCHandle - HTC handle (see HTC apis)
+ pInfo - initialization information
+ @output:
+ @return: HCI_TRANSPORT_HANDLE on success, NULL on failure
+ @notes: The HTC module provides HCI transport services.
+ @example:
+ @see also: HCI_TransportDetach
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Detach from the HCI transport module
+ @function name: HCI_TransportDetach
+ @input: HciTrans - HCI transport handle
+ pInfo - initialization information
+ @output:
+ @return:
+ @notes:
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Add receive packets to the HCI transport
+ @function name: HCI_TransportAddReceivePkts
+ @input: HciTrans - HCI transport handle
+ pQueue - a queue holding one or more packets
+ @output:
+ @return: A_OK on success
+ @notes: user must supply HTC packets for capturing incomming HCI packets. The caller
+ must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
+ macro. Each packet in the queue must be of the same type and length
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Send an HCI packet packet
+ @function name: HCI_TransportSendPkt
+ @input: HciTrans - HCI transport handle
+ pPacket - packet to send
+ Synchronous - send the packet synchronously (blocking)
+ @output:
+ @return: A_OK
+ @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and
+ HCI_SET_PACKET_TYPE() macros to prepare the packet.
+ If Synchronous is set to FALSE the call is fully asynchronous. On error or completion,
+ the registered send complete callback will be called.
+ If Synchronous is set to TRUE, the call will block until the packet is sent, if the
+ interface cannot send the packet within a 2 second timeout, the function will return
+ the failure code : A_EBUSY.
+
+ Synchronous Mode should only be used at start-up to initialize the HCI device using
+ custom HCI commands. It should NOT be mixed with Asynchronous operations. Mixed synchronous
+ and asynchronous operation behavior is undefined.
+
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous);
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Stop HCI transport
+ @function name: HCI_TransportStop
+ @input: HciTrans - hci transport handle
+ @output:
+ @return:
+ @notes: HCI transport communication will be halted. All receive and pending TX packets will
+ be flushed.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Start the HCI transport
+ @function name: HCI_TransportStart
+ @input: HciTrans - hci transport handle
+ @output:
+ @return: A_OK on success
+ @notes: HCI transport communication will begin, the caller can expect the arrival
+ of HCI recv packets as soon as this call returns.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Enable or Disable Asynchronous Recv
+ @function name: HCI_TransportEnableDisableAsyncRecv
+ @input: HciTrans - hci transport handle
+ Enable - enable or disable asynchronous recv
+ @output:
+ @return: A_OK on success
+ @notes: This API must be called when HCI recv is handled synchronously
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Receive an event packet from the HCI transport synchronously using polling
+ @function name: HCI_TransportRecvHCIEventSync
+ @input: HciTrans - hci transport handle
+ pPacket - HTC packet to hold the recv data
+ MaxPollMS - maximum polling duration in Milliseconds;
+ @output:
+ @return: A_OK on success
+ @notes: This API should be used only during HCI device initialization, the caller must call
+ HCI_TransportEnableDisableAsyncRecv with Enable=FALSE prior to using this API.
+ This API will only capture HCI Event packets.
+ @example:
+ @see also: HCI_TransportEnableDisableAsyncRecv
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
+ HTC_PACKET *pPacket,
+ int MaxPollMS);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Set the desired baud rate for the underlying transport layer
+ @function name: HCI_TransportSetBaudRate
+ @input: HciTrans - hci transport handle
+ Baud - baud rate in bps
+ @output:
+ @return: A_OK on success
+ @notes: This API should be used only after HCI device initialization
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Enable/Disable HCI Transport Power Management
+ @function name: HCI_TransportEnablePowerMgmt
+ @input: HciTrans - hci transport handle
+ Enable - 1 = Enable, 0 = Disable
+ @output:
+ @return: A_OK on success
+ @notes:
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HCI_TRANSPORT_API_H_ */
diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h
new file mode 100644
index 000000000000..2a082678512c
--- /dev/null
+++ b/drivers/staging/ath6kl/include/hif.h
@@ -0,0 +1,458 @@
+//------------------------------------------------------------------------------
+// <copyright file="hif.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HIF specific declarations and prototypes
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HIF_H_
+#define _HIF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "dl_list.h"
+
+
+typedef struct htc_callbacks HTC_CALLBACKS;
+typedef struct hif_device HIF_DEVICE;
+
+/*
+ * direction - Direction of transfer (HIF_READ/HIF_WRITE).
+ */
+#define HIF_READ 0x00000001
+#define HIF_WRITE 0x00000002
+#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
+
+/*
+ * type - An interface may support different kind of read/write commands.
+ * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
+ * translates to using different kinds of TPCs. The command type
+ * is thus divided into a basic and an extended command and can
+ * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
+ */
+#define HIF_BASIC_IO 0x00000004
+#define HIF_EXTENDED_IO 0x00000008
+#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
+
+/*
+ * emode - This indicates the whether the command is to be executed in a
+ * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
+ * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
+ * implemented using the asynchronous mode allowing the the bus
+ * driver to indicate the completion of operation through the
+ * registered callback routine. The requirement primarily comes
+ * from the contexts these operations get called from (a driver's
+ * transmit context or the ISR context in case of receive).
+ * Support for both of these modes is essential.
+ */
+#define HIF_SYNCHRONOUS 0x00000010
+#define HIF_ASYNCHRONOUS 0x00000020
+#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
+
+/*
+ * dmode - An interface may support different kinds of commands based on
+ * the tradeoff between the amount of data it can carry and the
+ * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
+ * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
+ * to the nearest block size by padding. The size of the block is
+ * configurable at compile time using the HIF_BLOCK_SIZE and is
+ * negotiated with the target during initialization after the
+ * AR6000 interrupts are enabled.
+ */
+#define HIF_BYTE_BASIS 0x00000040
+#define HIF_BLOCK_BASIS 0x00000080
+#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
+
+/*
+ * amode - This indicates if the address has to be incremented on AR6000
+ * after every read/write operation (HIF?FIXED_ADDRESS/
+ * HIF_INCREMENTAL_ADDRESS).
+ */
+#define HIF_FIXED_ADDRESS 0x00000100
+#define HIF_INCREMENTAL_ADDRESS 0x00000200
+#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BYTE_FIX \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_WR_ASYNC_BYTE_INC \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_ASYNC_BLOCK_INC \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_SYNC_BYTE_FIX \
+ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_WR_SYNC_BYTE_INC \
+ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_SYNC_BLOCK_INC \
+ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_ASYNC_BLOCK_FIX \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_WR_SYNC_BLOCK_FIX \
+ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_RD_SYNC_BYTE_INC \
+ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BYTE_FIX \
+ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BYTE_FIX \
+ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BLOCK_FIX \
+ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BYTE_INC \
+ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_ASYNC_BLOCK_INC \
+ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BLOCK_INC \
+ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BLOCK_FIX \
+ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+
+typedef enum {
+ HIF_DEVICE_POWER_STATE = 0,
+ HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+ HIF_DEVICE_GET_MBOX_ADDR,
+ HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
+ HIF_DEVICE_GET_IRQ_PROC_MODE,
+ HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
+ HIF_DEVICE_POWER_STATE_CHANGE,
+ HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
+ HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT,
+ HIF_DEVICE_GET_OS_DEVICE,
+ HIF_DEVICE_DEBUG_BUS_STATE,
+} HIF_DEVICE_CONFIG_OPCODE;
+
+/*
+ * HIF CONFIGURE definitions:
+ *
+ * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
+ * input : none
+ * output : array of 4 A_UINT32s
+ * notes: block size is returned for each mailbox (4)
+ *
+ * HIF_DEVICE_GET_MBOX_ADDR
+ * input : none
+ * output : HIF_DEVICE_MBOX_INFO
+ * notes:
+ *
+ * HIF_DEVICE_GET_PENDING_EVENTS_FUNC
+ * input : none
+ * output: HIF_PENDING_EVENTS_FUNC function pointer
+ * notes: this is optional for the HIF layer, if the request is
+ * not handled then it indicates that the upper layer can use
+ * the standard device methods to get pending events (IRQs, mailbox messages etc..)
+ * otherwise it can call the function pointer to check pending events.
+ *
+ * HIF_DEVICE_GET_IRQ_PROC_MODE
+ * input : none
+ * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode)
+ * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF
+ * layer can report whether IRQ processing is requires synchronous behavior or
+ * can be processed using asynchronous bus requests (typically faster).
+ *
+ * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC
+ * input :
+ * output : HIF_MASK_UNMASK_RECV_EVENT function pointer
+ * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism
+ * to mask receive message events. The upper layer can call this pointer when it needs
+ * to mask/unmask receive events (in case it runs out of buffers).
+ *
+ * HIF_DEVICE_POWER_STATE_CHANGE
+ *
+ * input : HIF_DEVICE_POWER_CHANGE_TYPE
+ * output : none
+ * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change
+ * requests in an interconnect specific way. This is highly OS and bus driver dependent.
+ * The caller must guarantee that no HIF read/write requests will be made after the device
+ * is powered down.
+ *
+ * HIF_DEVICE_GET_IRQ_YIELD_PARAMS
+ *
+ * input : none
+ * output : HIF_DEVICE_IRQ_YIELD_PARAMS
+ * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler.
+ * The DSR callback handler will exit after a fixed number of RX packets or events are processed.
+ * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY.
+ * The HIF implementation can ignore this command if it does not desire the DSR callback to yield.
+ * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the
+ * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is
+ * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning.
+ * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared
+ * to process interrupts again.
+ *
+ * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT
+ * input : none
+ * output : HIF_DEVICE_SCATTER_SUPPORT_INFO
+ * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests
+ * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for
+ * multi-message transfers that can better utilize the bus interconnect.
+ *
+ *
+ * HIF_DEVICE_GET_OS_DEVICE
+ * intput : none
+ * output : HIF_DEVICE_OS_DEVICE_INFO;
+ * note: On some operating systems, the HIF layer has a parent device object for the bus. This object
+ * may be required to register certain types of logical devices.
+ *
+ * HIF_DEVICE_DEBUG_BUS_STATE
+ * input : none
+ * output : none
+ * note: This configure option triggers the HIF interface to dump as much bus interface state. This
+ * configuration request is optional (No-OP on some HIF implementations)
+ *
+ */
+
+typedef struct {
+ A_UINT32 ExtendedAddress; /* extended address for larger writes */
+ A_UINT32 ExtendedSize;
+} HIF_MBOX_PROPERTIES;
+
+#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */
+
+typedef enum _MBOX_BUF_IF_TYPE {
+ MBOX_BUS_IF_SDIO = 0,
+ MBOX_BUS_IF_SPI = 1,
+} MBOX_BUF_IF_TYPE;
+
+typedef struct {
+ A_UINT32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in
+ and ARRAY of 32-bit words */
+
+ /* the following describe extended mailbox properties */
+ HIF_MBOX_PROPERTIES MboxProp[4];
+ /* if the HIF supports the GMbox extended address region it can report it
+ * here, some interfaces cannot support the GMBOX address range and not set this */
+ A_UINT32 GMboxAddress;
+ A_UINT32 GMboxSize;
+ A_UINT32 Flags; /* flags to describe mbox behavior or usage */
+ MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */
+} HIF_DEVICE_MBOX_INFO;
+
+typedef enum {
+ HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all
+ interrupts before returning */
+ HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts
+ using ASYNC I/O (that is HIFAckInterrupt can be called at a
+ later time */
+} HIF_DEVICE_IRQ_PROCESSING_MODE;
+
+typedef enum {
+ HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */
+ HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */
+ HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures
+ to completely power-off the module and associated hardware (i.e. cut power supplies)
+ */
+} HIF_DEVICE_POWER_CHANGE_TYPE;
+
+typedef struct {
+ int RecvPacketYieldCount; /* max number of packets to force DSR to return */
+} HIF_DEVICE_IRQ_YIELD_PARAMS;
+
+
+typedef struct _HIF_SCATTER_ITEM {
+ A_UINT8 *pBuffer; /* CPU accessible address of buffer */
+ int Length; /* length of transfer to/from this buffer */
+ void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */
+} HIF_SCATTER_ITEM;
+
+struct _HIF_SCATTER_REQ;
+
+typedef void ( *HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *);
+
+typedef enum _HIF_SCATTER_METHOD {
+ HIF_SCATTER_NONE = 0,
+ HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */
+ HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */
+} HIF_SCATTER_METHOD;
+
+typedef struct _HIF_SCATTER_REQ {
+ DL_LIST ListLink; /* link management */
+ A_UINT32 Address; /* address for the read/write operation */
+ A_UINT32 Request; /* request flags */
+ A_UINT32 TotalLength; /* total length of entire transfer */
+ A_UINT32 CallerFlags; /* caller specific flags can be stored here */
+ HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */
+ A_STATUS CompletionStatus; /* status of completion */
+ void *Context; /* caller context for this request */
+ int ValidScatterEntries; /* number of valid entries set by caller */
+ HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */
+ void *HIFPrivate[4]; /* HIF private area */
+ A_UINT8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */
+ HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */
+} HIF_SCATTER_REQ;
+
+typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device);
+typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
+typedef A_STATUS ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
+
+typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO {
+ /* information returned from HIF layer */
+ HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc;
+ HIF_FREE_SCATTER_REQUEST pFreeReqFunc;
+ HIF_READWRITE_SCATTER pReadWriteScatterFunc;
+ int MaxScatterEntries;
+ int MaxTransferSizePerScatterReq;
+} HIF_DEVICE_SCATTER_SUPPORT_INFO;
+
+typedef struct {
+ void *pOSDevice;
+} HIF_DEVICE_OS_DEVICE_INFO;
+
+#define HIF_MAX_DEVICES 1
+
+struct htc_callbacks {
+ void *context; /* context to pass to the dsrhandler
+ note : rwCompletionHandler is provided the context passed to HIFReadWrite */
+ A_STATUS (* rwCompletionHandler)(void *rwContext, A_STATUS status);
+ A_STATUS (* dsrHandler)(void *context);
+};
+
+typedef struct osdrv_callbacks {
+ void *context; /* context to pass for all callbacks except deviceRemovedHandler
+ the deviceRemovedHandler is only called if the device is claimed */
+ A_STATUS (* deviceInsertedHandler)(void *context, void *hif_handle);
+ A_STATUS (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
+ A_STATUS (* deviceSuspendHandler)(void *context);
+ A_STATUS (* deviceResumeHandler)(void *context);
+ A_STATUS (* deviceWakeupHandler)(void *context);
+ A_STATUS (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config);
+} OSDRV_CALLBACKS;
+
+#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host
+ needs to read the register table to figure out what */
+#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */
+
+typedef struct _HIF_PENDING_EVENTS_INFO {
+ A_UINT32 Events;
+ A_UINT32 LookAhead;
+ A_UINT32 AvailableRecvBytes;
+#ifdef THREAD_X
+ A_UINT32 Polling;
+ A_UINT32 INT_CAUSE_REG;
+#endif
+} HIF_PENDING_EVENTS_INFO;
+
+ /* function to get pending events , some HIF modules use special mechanisms
+ * to detect packet available and other interrupts */
+typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device,
+ HIF_PENDING_EVENTS_INFO *pEvents,
+ void *AsyncContext);
+
+#define HIF_MASK_RECV TRUE
+#define HIF_UNMASK_RECV FALSE
+ /* function to mask recv events */
+typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device,
+ A_BOOL Mask,
+ void *AsyncContext);
+
+
+/*
+ * This API is used to perform any global initialization of the HIF layer
+ * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
+ *
+ */
+A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks);
+
+/* This API claims the HIF device and provides a context for handling removal.
+ * The device removal callback is only called when the OSDRV layer claims
+ * a device. The claimed context must be non-NULL */
+void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext);
+/* release the claimed device */
+void HIFReleaseDevice(HIF_DEVICE *device);
+
+/* This API allows the HTC layer to attach to the HIF device */
+A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks);
+/* This API detaches the HTC layer from the HIF device */
+void HIFDetachHTC(HIF_DEVICE *device);
+
+/*
+ * This API is used to provide the read/write interface over the specific bus
+ * interface.
+ * address - Starting address in the AR6000's address space. For mailbox
+ * writes, it refers to the start of the mbox boundary. It should
+ * be ensured that the last byte falls on the mailbox's EOM. For
+ * mailbox reads, it refers to the end of the mbox boundary.
+ * buffer - Pointer to the buffer containg the data to be transmitted or
+ * received.
+ * length - Amount of data to be transmitted or received.
+ * request - Characterizes the attributes of the command.
+ */
+A_STATUS
+HIFReadWrite(HIF_DEVICE *device,
+ A_UINT32 address,
+ A_UCHAR *buffer,
+ A_UINT32 length,
+ A_UINT32 request,
+ void *context);
+
+/*
+ * This can be initiated from the unload driver context when the OSDRV layer has no more use for
+ * the device.
+ */
+void HIFShutDownDevice(HIF_DEVICE *device);
+
+/*
+ * This should translate to an acknowledgment to the bus driver indicating that
+ * the previous interrupt request has been serviced and the all the relevant
+ * sources have been cleared. HTC is ready to process more interrupts.
+ * This should prevent the bus driver from raising an interrupt unless the
+ * previous one has been serviced and acknowledged using the previous API.
+ */
+void HIFAckInterrupt(HIF_DEVICE *device);
+
+void HIFMaskInterrupt(HIF_DEVICE *device);
+
+void HIFUnMaskInterrupt(HIF_DEVICE *device);
+
+#ifdef THREAD_X
+/*
+ * This set of functions are to be used by the bus driver to notify
+ * the HIF module about various events.
+ * These are not implemented if the bus driver provides an alternative
+ * way for this notification though callbacks for instance.
+ */
+int HIFInsertEventNotify(void);
+
+int HIFRemoveEventNotify(void);
+
+int HIFIRQEventNotify(void);
+
+int HIFRWCompleteEventNotify(void);
+#endif
+
+A_STATUS
+HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
+ void *config, A_UINT32 configLen);
+
+/*
+ * This API wait for the remaining MBOX messages to be drained
+ * This should be moved to HTC AR6K layer
+ */
+A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HIF_H_ */
diff --git a/drivers/staging/ath6kl/include/host_version.h b/drivers/staging/ath6kl/include/host_version.h
new file mode 100644
index 000000000000..74f1982c681b
--- /dev/null
+++ b/drivers/staging/ath6kl/include/host_version.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// <copyright file="host_version.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains version information for the sample host driver for the
+// AR6000 chip
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HOST_VERSION_H_
+#define _HOST_VERSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <AR6002/AR6K_version.h>
+
+/*
+ * The version number is made up of major, minor, patch and build
+ * numbers. These are 16 bit numbers. The build and release script will
+ * set the build number using a Perforce counter. Here the build number is
+ * set to 9999 so that builds done without the build-release script are easily
+ * identifiable.
+ */
+
+#define ATH_SW_VER_MAJOR __VER_MAJOR_
+#define ATH_SW_VER_MINOR __VER_MINOR_
+#define ATH_SW_VER_PATCH __VER_PATCH_
+#define ATH_SW_VER_BUILD __BUILD_NUMBER_
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HOST_VERSION_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h
new file mode 100644
index 000000000000..b007051e0551
--- /dev/null
+++ b/drivers/staging/ath6kl/include/htc_api.h
@@ -0,0 +1,575 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_api.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HTC_API_H_
+#define _HTC_API_H_
+
+#include "htc_packet.h"
+#include <htc.h>
+#include <htc_services.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* TODO.. for BMI */
+#define ENDPOINT1 0
+// TODO -remove me, but we have to fix BMI first
+#define HTC_MAILBOX_NUM_MAX 4
+
+/* this is the amount of header room required by users of HTC */
+#define HTC_HEADER_LEN HTC_HDR_LENGTH
+
+typedef void *HTC_HANDLE;
+
+typedef A_UINT16 HTC_SERVICE_ID;
+
+typedef struct _HTC_INIT_INFO {
+ void *pContext; /* context for target failure notification */
+ void (*TargetFailure)(void *Instance, A_STATUS Status);
+} HTC_INIT_INFO;
+
+/* per service connection send completion */
+typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *);
+/* per service connection callback when a plurality of packets have been sent
+ * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback)
+ * to hold a list of completed send packets.
+ * If the handler cannot fully traverse the packet queue before returning, it should
+ * transfer the items of the queue into the caller's private queue using:
+ * HTC_PACKET_ENQUEUE() */
+typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,HTC_PACKET_QUEUE *);
+/* per service connection pkt received */
+typedef void (*HTC_EP_RECV_PKT)(void *,HTC_PACKET *);
+/* per service connection callback when a plurality of packets are received
+ * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback)
+ * to hold a list of recv packets.
+ * If the handler cannot fully traverse the packet queue before returning, it should
+ * transfer the items of the queue into the caller's private queue using:
+ * HTC_PACKET_ENQUEUE() */
+typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,HTC_PACKET_QUEUE *);
+
+/* Optional per service connection receive buffer re-fill callback,
+ * On some OSes (like Linux) packets are allocated from a global pool and indicated up
+ * to the network stack. The driver never gets the packets back from the OS. For these OSes
+ * a refill callback can be used to allocate and re-queue buffers into HTC.
+ *
+ * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and
+ * the driver can re-queue these buffers into HTC. In this regard a refill callback is
+ * unnecessary */
+typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint);
+
+/* Optional per service connection receive buffer allocation callback.
+ * On some systems packet buffers are an extremely limited resource. Rather than
+ * queue largest-possible-sized buffers to HTC, some systems would rather
+ * allocate a specific size as the packet is received. The trade off is
+ * slightly more processing (callback invoked for each RX packet)
+ * for the benefit of committing fewer buffer resources into HTC.
+ *
+ * The callback is provided the length of the pending packet to fetch. This includes the
+ * HTC header length plus the length of payload. The callback can return a pointer to
+ * the allocated HTC packet for immediate use.
+ *
+ * Alternatively a variant of this handler can be used to allocate large receive packets as needed.
+ * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to
+ * handle the case where a large packet buffer is required. This can significantly reduce the
+ * amount of "committed" memory used to receive packets.
+ *
+ * */
+typedef HTC_PACKET *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length);
+
+typedef enum _HTC_SEND_FULL_ACTION {
+ HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */
+ HTC_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */
+} HTC_SEND_FULL_ACTION;
+
+/* Optional per service connection callback when a send queue is full. This can occur if the
+ * host continues queueing up TX packets faster than credits can arrive
+ * To prevent the host (on some Oses like Linux) from continuously queueing packets
+ * and consuming resources, this callback is provided so that that the host
+ * can disable TX in the subsystem (i.e. network stack).
+ * This callback is invoked for each packet that "overflows" the HTC queue. The callback can
+ * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or
+ * dropped (HTC_SEND_FULL_DROP). If a packet is dropped, the EpTxComplete handler will be called
+ * and the packet's status field will be set to A_NO_RESOURCE.
+ * Other OSes require a "per-packet" indication for each completed TX packet, this
+ * closed loop mechanism will prevent the network stack from overunning the NIC
+ * The packet to keep or drop is passed for inspection to the registered handler the handler
+ * must ONLY inspect the packet, it may not free or reclaim the packet. */
+typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_PACKET *pPacket);
+
+typedef struct _HTC_EP_CALLBACKS {
+ void *pContext; /* context for each callback */
+ HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */
+ HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */
+ HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */
+ HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */
+ HTC_EP_RECV_ALLOC EpRecvAlloc; /* OPTIONAL recv allocation callback */
+ HTC_EP_RECV_ALLOC EpRecvAllocThresh; /* OPTIONAL recv allocation callback based on a threshold */
+ HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete
+ indications (EpTxComplete must be NULL) */
+ HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple
+ recv packet indications (EpRecv must be NULL) */
+ int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the
+ threshold value to the current recv packet length and invoke
+ the EpRecvAllocThresh callback to acquire a packet buffer */
+ int RecvRefillWaterMark; /* if a EpRecvRefill handler is provided, this value
+ can be used to set a trigger refill callback
+ when the recv queue drops below this value
+ if set to 0, the refill is only called when packets
+ are empty */
+} HTC_EP_CALLBACKS;
+
+/* service connection information */
+typedef struct _HTC_SERVICE_CONNECT_REQ {
+ HTC_SERVICE_ID ServiceID; /* service ID to connect to */
+ A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */
+ A_UINT8 *pMetaData; /* ptr to optional service-specific meta-data */
+ A_UINT8 MetaDataLength; /* optional meta data length */
+ HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */
+ int MaxSendQueueDepth; /* maximum depth of any send queue */
+ A_UINT32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */
+ unsigned int MaxSendMsgSize; /* override max message size in send direction */
+} HTC_SERVICE_CONNECT_REQ;
+
+#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */
+
+/* service connection response information */
+typedef struct _HTC_SERVICE_CONNECT_RESP {
+ A_UINT8 *pMetaData; /* caller supplied buffer to optional meta-data */
+ A_UINT8 BufferLength; /* length of caller supplied buffer */
+ A_UINT8 ActualLength; /* actual length of meta data */
+ HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */
+ unsigned int MaxMsgLength; /* max length of all messages over this endpoint */
+ A_UINT8 ConnectRespCode; /* connect response code from target */
+} HTC_SERVICE_CONNECT_RESP;
+
+/* endpoint distribution structure */
+typedef struct _HTC_ENDPOINT_CREDIT_DIST {
+ struct _HTC_ENDPOINT_CREDIT_DIST *pNext;
+ struct _HTC_ENDPOINT_CREDIT_DIST *pPrev;
+ HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */
+ HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */
+ A_UINT32 DistFlags; /* distribution flags, distribution function can
+ set default activity using SET_EP_ACTIVE() macro */
+ int TxCreditsNorm; /* credits for normal operation, anything above this
+ indicates the endpoint is over-subscribed, this field
+ is only relevant to the credit distribution function */
+ int TxCreditsMin; /* floor for credit distribution, this field is
+ only relevant to the credit distribution function */
+ int TxCreditsAssigned; /* number of credits assigned to this EP, this field
+ is only relevant to the credit dist function */
+ int TxCredits; /* current credits available, this field is used by
+ HTC to determine whether a message can be sent or
+ must be queued */
+ int TxCreditsToDist; /* pending credits to distribute on this endpoint, this
+ is set by HTC when credit reports arrive.
+ The credit distribution functions sets this to zero
+ when it distributes the credits */
+ int TxCreditsSeek; /* this is the number of credits that the current pending TX
+ packet needs to transmit. This is set by HTC when
+ and endpoint needs credits in order to transmit */
+ int TxCreditSize; /* size in bytes of each credit (set by HTC) */
+ int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */
+ void *pHTCReserved; /* reserved for HTC use */
+ int TxQueueDepth; /* current depth of TX queue , i.e. messages waiting for credits
+ This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
+ or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
+ that has non-zero credits to recover
+ */
+} HTC_ENDPOINT_CREDIT_DIST;
+
+#define HTC_EP_ACTIVE ((A_UINT32) (1u << 31))
+
+/* macro to check if an endpoint has gone active, useful for credit
+ * distributions */
+#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE)
+#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE
+
+ /* credit distibution code that is passed into the distrbution function,
+ * there are mandatory and optional codes that must be handled */
+typedef enum _HTC_CREDIT_DIST_REASON {
+ HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed
+ send operations (MANDATORY) resulting in credit reports */
+ HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occured (OPTIONAL) */
+ HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */
+ HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by
+ the distribution function */
+} HTC_CREDIT_DIST_REASON;
+
+typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPList,
+ HTC_CREDIT_DIST_REASON Reason);
+
+typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPList,
+ int TotalCredits);
+
+ /* endpoint statistics action */
+typedef enum _HTC_ENDPOINT_STAT_ACTION {
+ HTC_EP_STAT_SAMPLE = 0, /* only read statistics */
+ HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */
+ HTC_EP_STAT_CLEAR /* clear only */
+} HTC_ENDPOINT_STAT_ACTION;
+
+ /* endpoint statistics */
+typedef struct _HTC_ENDPOINT_STATS {
+ A_UINT32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on
+ this endpoint */
+ A_UINT32 TxIssued; /* running count of total TX packets issued */
+ A_UINT32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */
+ A_UINT32 TxBundles; /* running count of TX bundles that were issued */
+ A_UINT32 TxDropped; /* tx packets that were dropped */
+ A_UINT32 TxCreditRpts; /* running count of total credit reports received for this endpoint */
+ A_UINT32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */
+ A_UINT32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */
+ A_UINT32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */
+ A_UINT32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */
+ A_UINT32 TxCreditsFromOther; /* count of credits received via another endpoint */
+ A_UINT32 TxCreditsFromEp0; /* count of credits received via another endpoint */
+ A_UINT32 TxCreditsConsummed; /* count of consummed credits */
+ A_UINT32 TxCreditsReturned; /* count of credits returned */
+ A_UINT32 RxReceived; /* count of RX packets received */
+ A_UINT32 RxLookAheads; /* count of lookahead records
+ found in messages received on this endpoint */
+ A_UINT32 RxPacketsBundled; /* count of recv packets received in a bundle */
+ A_UINT32 RxBundleLookAheads; /* count of number of bundled lookaheads */
+ A_UINT32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */
+ A_UINT32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */
+ A_UINT32 RxAllocThreshBytes; /* total number of bytes */
+} HTC_ENDPOINT_STATS;
+
+/* ------ Function Prototypes ------ */
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Create an instance of HTC over the underlying HIF device
+ @function name: HTCCreate
+ @input: HifDevice - hif device handle,
+ pInfo - initialization information
+ @output:
+ @return: HTC_HANDLE on success, NULL on failure
+ @notes:
+ @example:
+ @see also: HTCDestroy
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+HTC_HANDLE HTCCreate(void *HifDevice, HTC_INIT_INFO *pInfo);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Get the underlying HIF device handle
+ @function name: HTCGetHifDevice
+ @input: HTCHandle - handle passed into the AddInstance callback
+ @output:
+ @return: opaque HIF device handle usable in HIF API calls.
+ @notes:
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void *HTCGetHifDevice(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Set credit distribution parameters
+ @function name: HTCSetCreditDistribution
+ @input: HTCHandle - HTC handle
+ pCreditDistCont - caller supplied context to pass into distribution functions
+ CreditDistFunc - Distribution function callback
+ CreditDistInit - Credit Distribution initialization callback
+ ServicePriorityOrder - Array containing list of service IDs, lowest index is highest
+ priority
+ ListLength - number of elements in ServicePriorityOrder
+ @output:
+ @return:
+ @notes: The user can set a custom credit distribution function to handle special requirements
+ for each endpoint. A default credit distribution routine can be used by setting
+ CreditInitFunc to NULL. The default credit distribution is only provided for simple
+ "fair" credit distribution without regard to any prioritization.
+
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCSetCreditDistribution(HTC_HANDLE HTCHandle,
+ void *pCreditDistContext,
+ HTC_CREDIT_DIST_CALLBACK CreditDistFunc,
+ HTC_CREDIT_INIT_CALLBACK CreditInitFunc,
+ HTC_SERVICE_ID ServicePriorityOrder[],
+ int ListLength);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Wait for the target to indicate the HTC layer is ready
+ @function name: HTCWaitTarget
+ @input: HTCHandle - HTC handle
+ @output:
+ @return:
+ @notes: This API blocks until the target responds with an HTC ready message.
+ The caller should not connect services until the target has indicated it is
+ ready.
+ @example:
+ @see also: HTCConnectService
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Start target service communications
+ @function name: HTCStart
+ @input: HTCHandle - HTC handle
+ @output:
+ @return:
+ @notes: This API indicates to the target that the service connection phase is complete
+ and the target can freely start all connected services. This API should only be
+ called AFTER all service connections have been made. TCStart will issue a
+ SETUP_COMPLETE message to the target to indicate that all service connections
+ have been made and the target can start communicating over the endpoints.
+ @example:
+ @see also: HTCConnectService
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCStart(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Add receive packet to HTC
+ @function name: HTCAddReceivePkt
+ @input: HTCHandle - HTC handle
+ pPacket - HTC receive packet to add
+ @output:
+ @return: A_OK on success
+ @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
+ must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
+ macro.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Connect to an HTC service
+ @function name: HTCConnectService
+ @input: HTCHandle - HTC handle
+ pReq - connection details
+ @output: pResp - connection response
+ @return:
+ @notes: Service connections must be performed before HTCStart. User provides callback handlers
+ for various endpoint events.
+ @example:
+ @see also: HTCStart
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCConnectService(HTC_HANDLE HTCHandle,
+ HTC_SERVICE_CONNECT_REQ *pReq,
+ HTC_SERVICE_CONNECT_RESP *pResp);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Send an HTC packet
+ @function name: HTCSendPkt
+ @input: HTCHandle - HTC handle
+ pPacket - packet to send
+ @output:
+ @return: A_OK
+ @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro.
+ This interface is fully asynchronous. On error, HTC SendPkt will
+ call the registered Endpoint callback to cleanup the packet.
+ @example:
+ @see also: HTCFlushEndpoint
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Stop HTC service communications
+ @function name: HTCStop
+ @input: HTCHandle - HTC handle
+ @output:
+ @return:
+ @notes: HTC communications is halted. All receive and pending TX packets will
+ be flushed.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCStop(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Destory HTC service
+ @function name: HTCDestroy
+ @input: HTCHandle
+ @output:
+ @return:
+ @notes: This cleans up all resources allocated by HTCCreate().
+ @example:
+ @see also: HTCCreate
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCDestroy(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Flush pending TX packets
+ @function name: HTCFlushEndpoint
+ @input: HTCHandle - HTC handle
+ Endpoint - Endpoint to flush
+ Tag - flush tag
+ @output:
+ @return:
+ @notes: The Tag parameter is used to selectively flush packets with matching tags.
+ The value of 0 forces all packets to be flush regardless of tag.
+ @example:
+ @see also: HTCSendPkt
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Dump credit distribution state
+ @function name: HTCDumpCreditStates
+ @input: HTCHandle - HTC handle
+ @output:
+ @return:
+ @notes: This dumps all credit distribution information to the debugger
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCDumpCreditStates(HTC_HANDLE HTCHandle);
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Indicate a traffic activity change on an endpoint
+ @function name: HTCIndicateActivityChange
+ @input: HTCHandle - HTC handle
+ Endpoint - endpoint in which activity has changed
+ Active - TRUE if active, FALSE if it has become inactive
+ @output:
+ @return:
+ @notes: This triggers the registered credit distribution function to
+ re-adjust credits for active/inactive endpoints.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCIndicateActivityChange(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint,
+ A_BOOL Active);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Get endpoint statistics
+ @function name: HTCGetEndpointStatistics
+ @input: HTCHandle - HTC handle
+ Endpoint - Endpoint identifier
+ Action - action to take with statistics
+ @output:
+ pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR)
+
+ @return: TRUE if statistics profiling is enabled, otherwise FALSE.
+
+ @notes: Statistics is a compile-time option and this function may return FALSE
+ if HTC is not compiled with profiling.
+
+ The caller can specify the statistic "action" to take when sampling
+ the statistics. This includes:
+
+ HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values.
+ HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics
+ are cleared.
+ HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for
+ pStats
+
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint,
+ HTC_ENDPOINT_STAT_ACTION Action,
+ HTC_ENDPOINT_STATS *pStats);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Unblock HTC message reception
+ @function name: HTCUnblockRecv
+ @input: HTCHandle - HTC handle
+ @output:
+ @return:
+ @notes:
+ HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet.
+ The caller can use this API to indicate to HTC when resources (buffers) are available
+ such that the receiver can be unblocked and HTC may re-attempt fetching the pending message.
+
+ This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket()
+ API to recycle or provide receive packets to HTC.
+
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+void HTCUnblockRecv(HTC_HANDLE HTCHandle);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: send a series of HTC packets
+ @function name: HTCSendPktsMultiple
+ @input: HTCHandle - HTC handle
+ pPktQueue - local queue holding packets to send
+ @output:
+ @return: A_OK
+ @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro.
+ The queue must only contain packets directed at the same endpoint.
+ Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the TX packets in FIFO order.
+ This API will remove the packets from the pkt queue and place them into the HTC Tx Queue
+ and bundle messages where possible.
+ The caller may allocate the pkt queue on the stack to hold the packets.
+ This interface is fully asynchronous. On error, HTCSendPkts will
+ call the registered Endpoint callback to cleanup the packet.
+ @example:
+ @see also: HTCFlushEndpoint
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Add multiple receive packets to HTC
+ @function name: HTCAddReceivePktMultiple
+ @input: HTCHandle - HTC handle
+ pPktQueue - HTC receive packet queue holding packets to add
+ @output:
+ @return: A_OK on success
+ @notes: user must supply HTC packets for capturing incomming HTC frames. The caller
+ must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL()
+ macro. The queue must only contain recv packets for the same endpoint.
+ Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the recv packet.
+ This API will remove the packets from the pkt queue and place them into internal
+ recv packet list.
+ The caller may allocate the pkt queue on the stack to hold the packets.
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue);
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Check if an endpoint is marked active
+ @function name: HTCIsEndpointActive
+ @input: HTCHandle - HTC handle
+ Endpoint - endpoint to check for active state
+ @output:
+ @return: returns TRUE if Endpoint is Active
+ @notes:
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint);
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @desc: Get the number of recv buffers currently queued into an HTC endpoint
+ @function name: HTCGetNumRecvBuffers
+ @input: HTCHandle - HTC handle
+ Endpoint - endpoint to check
+ @output:
+ @return: returns number of buffers in queue
+ @notes:
+ @example:
+ @see also:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle,
+ HTC_ENDPOINT_ID Endpoint);
+
+/* internally used functions for testing... */
+void HTCEnableRecv(HTC_HANDLE HTCHandle);
+void HTCDisableRecv(HTC_HANDLE HTCHandle);
+A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
+ A_UINT32 TimeoutInMs,
+ A_BOOL *pbIsRecvPending);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTC_API_H_ */
diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h
new file mode 100644
index 000000000000..15175cff2f28
--- /dev/null
+++ b/drivers/staging/ath6kl/include/htc_packet.h
@@ -0,0 +1,227 @@
+//------------------------------------------------------------------------------
+// <copyright file="htc_packet.h" company="Atheros">
+// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef HTC_PACKET_H_
+#define HTC_PACKET_H_
+
+
+#include "dl_list.h"
+
+/* ------ Endpoint IDS ------ */
+typedef enum
+{
+ ENDPOINT_UNUSED = -1,
+ ENDPOINT_0 = 0,
+ ENDPOINT_1 = 1,
+ ENDPOINT_2 = 2,
+ ENDPOINT_3,
+ ENDPOINT_4,
+ ENDPOINT_5,
+ ENDPOINT_6,
+ ENDPOINT_7,
+ ENDPOINT_8,
+ ENDPOINT_MAX,
+} HTC_ENDPOINT_ID;
+
+struct _HTC_PACKET;
+
+typedef void (* HTC_PACKET_COMPLETION)(void *,struct _HTC_PACKET *);
+
+typedef A_UINT16 HTC_TX_TAG;
+
+typedef struct _HTC_TX_PACKET_INFO {
+ HTC_TX_TAG Tag; /* tag used to selective flush packets */
+ int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */
+ A_UINT8 SendFlags; /* send flags (HTC internal) */
+ int SeqNo; /* internal seq no for debugging (HTC internal) */
+} HTC_TX_PACKET_INFO;
+
+#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */
+#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */
+#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */
+
+typedef struct _HTC_RX_PACKET_INFO {
+ A_UINT32 ExpectedHdr; /* HTC internal use */
+ A_UINT32 HTCRxFlags; /* HTC internal use */
+ A_UINT32 IndicationFlags; /* indication flags set on each RX packet indication */
+} HTC_RX_PACKET_INFO;
+
+#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */
+
+/* wrapper around endpoint-specific packets */
+typedef struct _HTC_PACKET {
+ DL_LIST ListLink; /* double link */
+ void *pPktContext; /* caller's per packet specific context */
+
+ A_UINT8 *pBufferStart; /* the true buffer start , the caller can
+ store the real buffer start here. In
+ receive callbacks, the HTC layer sets pBuffer
+ to the start of the payload past the header. This
+ field allows the caller to reset pBuffer when it
+ recycles receive packets back to HTC */
+ /*
+ * Pointer to the start of the buffer. In the transmit
+ * direction this points to the start of the payload. In the
+ * receive direction, however, the buffer when queued up
+ * points to the start of the HTC header but when returned
+ * to the caller points to the start of the payload
+ */
+ A_UINT8 *pBuffer; /* payload start (RX/TX) */
+ A_UINT32 BufferLength; /* length of buffer */
+ A_UINT32 ActualLength; /* actual length of payload */
+ HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */
+ A_STATUS Status; /* completion status */
+ union {
+ HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */
+ HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */
+ } PktInfo;
+
+ /* the following fields are for internal HTC use */
+ HTC_PACKET_COMPLETION Completion; /* completion */
+ void *pContext; /* HTC private completion context */
+} HTC_PACKET;
+
+
+
+#define COMPLETE_HTC_PACKET(p,status) \
+{ \
+ (p)->Status = (status); \
+ (p)->Completion((p)->pContext,(p)); \
+}
+
+#define INIT_HTC_PACKET_INFO(p,b,len) \
+{ \
+ (p)->pBufferStart = (b); \
+ (p)->BufferLength = (len); \
+}
+
+/* macro to set an initial RX packet for refilling HTC */
+#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \
+{ \
+ (p)->pPktContext = (c); \
+ (p)->pBuffer = (b); \
+ (p)->pBufferStart = (b); \
+ (p)->BufferLength = (len); \
+ (p)->Endpoint = (ep); \
+}
+
+/* fast macro to recycle an RX packet that will be re-queued to HTC */
+#define HTC_PACKET_RESET_RX(p) \
+ { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; }
+
+/* macro to set packet parameters for TX */
+#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \
+{ \
+ (p)->pPktContext = (c); \
+ (p)->pBuffer = (b); \
+ (p)->ActualLength = (len); \
+ (p)->Endpoint = (ep); \
+ (p)->PktInfo.AsTx.Tag = (tag); \
+}
+
+/* HTC Packet Queueing Macros */
+typedef struct _HTC_PACKET_QUEUE {
+ DL_LIST QueueHead;
+ int Depth;
+} HTC_PACKET_QUEUE;
+
+/* initialize queue */
+#define INIT_HTC_PACKET_QUEUE(pQ) \
+{ \
+ DL_LIST_INIT(&(pQ)->QueueHead); \
+ (pQ)->Depth = 0; \
+}
+
+/* enqueue HTC packet to the tail of the queue */
+#define HTC_PACKET_ENQUEUE(pQ,p) \
+{ DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \
+ (pQ)->Depth++; \
+}
+
+/* enqueue HTC packet to the tail of the queue */
+#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p) \
+{ DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \
+ (pQ)->Depth++; \
+}
+/* test if a queue is empty */
+#define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0)
+/* get packet at head without removing it */
+static INLINE HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) {
+ if (queue->Depth == 0) {
+ return NULL;
+ }
+ return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),HTC_PACKET,ListLink);
+}
+/* remove a packet from a queue, where-ever it is in the queue */
+#define HTC_PACKET_REMOVE(pQ,p) \
+{ \
+ DL_ListRemove(&(p)->ListLink); \
+ (pQ)->Depth--; \
+}
+
+/* dequeue an HTC packet from the head of the queue */
+static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) {
+ DL_LIST *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead);
+ if (pItem != NULL) {
+ queue->Depth--;
+ return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink);
+ }
+ return NULL;
+}
+
+/* dequeue an HTC packet from the tail of the queue */
+static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) {
+ DL_LIST *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead);
+ if (pItem != NULL) {
+ queue->Depth--;
+ return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink);
+ }
+ return NULL;
+}
+
+#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth
+
+
+#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint
+#define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag
+
+ /* transfer the packets from one queue to the tail of another queue */
+#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \
+{ \
+ DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \
+ (pQDest)->Depth += (pQSrc)->Depth; \
+ (pQSrc)->Depth = 0; \
+}
+
+ /* fast version to init and add a single packet to a queue */
+#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \
+{ \
+ DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink) \
+ (pQ)->Depth = 1; \
+}
+
+#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \
+ ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), HTC_PACKET, ListLink)
+
+#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
+
+#endif /*HTC_PACKET_H_*/
diff --git a/drivers/staging/ath6kl/include/target_reg_table.h b/drivers/staging/ath6kl/include/target_reg_table.h
new file mode 100644
index 000000000000..901f923bee34
--- /dev/null
+++ b/drivers/staging/ath6kl/include/target_reg_table.h
@@ -0,0 +1,244 @@
+//------------------------------------------------------------------------------
+// <copyright file="target_reg_table.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Target register table macros and structure definitions
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifndef TARGET_REG_TABLE_H_
+#define TARGET_REG_TABLE_H_
+
+#include "targaddrs.h"
+
+/*** WARNING : Add to the end of the TABLE! do not change the order ****/
+typedef struct targetdef_s {
+ A_UINT32 d_RTC_BASE_ADDRESS;
+ A_UINT32 d_SYSTEM_SLEEP_OFFSET;
+ A_UINT32 d_SYSTEM_SLEEP_DISABLE_LSB;
+ A_UINT32 d_SYSTEM_SLEEP_DISABLE_MASK;
+ A_UINT32 d_CLOCK_CONTROL_OFFSET;
+ A_UINT32 d_CLOCK_CONTROL_SI0_CLK_MASK;
+ A_UINT32 d_RESET_CONTROL_OFFSET;
+ A_UINT32 d_RESET_CONTROL_SI0_RST_MASK;
+ A_UINT32 d_GPIO_BASE_ADDRESS;
+ A_UINT32 d_GPIO_PIN0_OFFSET;
+ A_UINT32 d_GPIO_PIN1_OFFSET;
+ A_UINT32 d_GPIO_PIN0_CONFIG_MASK;
+ A_UINT32 d_GPIO_PIN1_CONFIG_MASK;
+ A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_LSB;
+ A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_MASK;
+ A_UINT32 d_SI_CONFIG_I2C_LSB;
+ A_UINT32 d_SI_CONFIG_I2C_MASK;
+ A_UINT32 d_SI_CONFIG_POS_SAMPLE_LSB;
+ A_UINT32 d_SI_CONFIG_POS_SAMPLE_MASK;
+ A_UINT32 d_SI_CONFIG_INACTIVE_CLK_LSB;
+ A_UINT32 d_SI_CONFIG_INACTIVE_CLK_MASK;
+ A_UINT32 d_SI_CONFIG_INACTIVE_DATA_LSB;
+ A_UINT32 d_SI_CONFIG_INACTIVE_DATA_MASK;
+ A_UINT32 d_SI_CONFIG_DIVIDER_LSB;
+ A_UINT32 d_SI_CONFIG_DIVIDER_MASK;
+ A_UINT32 d_SI_BASE_ADDRESS;
+ A_UINT32 d_SI_CONFIG_OFFSET;
+ A_UINT32 d_SI_TX_DATA0_OFFSET;
+ A_UINT32 d_SI_TX_DATA1_OFFSET;
+ A_UINT32 d_SI_RX_DATA0_OFFSET;
+ A_UINT32 d_SI_RX_DATA1_OFFSET;
+ A_UINT32 d_SI_CS_OFFSET;
+ A_UINT32 d_SI_CS_DONE_ERR_MASK;
+ A_UINT32 d_SI_CS_DONE_INT_MASK;
+ A_UINT32 d_SI_CS_START_LSB;
+ A_UINT32 d_SI_CS_START_MASK;
+ A_UINT32 d_SI_CS_RX_CNT_LSB;
+ A_UINT32 d_SI_CS_RX_CNT_MASK;
+ A_UINT32 d_SI_CS_TX_CNT_LSB;
+ A_UINT32 d_SI_CS_TX_CNT_MASK;
+ A_UINT32 d_BOARD_DATA_SZ;
+ A_UINT32 d_BOARD_EXT_DATA_SZ;
+} TARGET_REGISTER_TABLE;
+
+#define BOARD_DATA_SZ_MAX 2048
+
+#if defined(MY_TARGET_DEF) /* { */
+
+#ifdef ATH_REG_TABLE_DIRECT_ASSIGN
+
+static struct targetdef_s my_target_def = {
+ RTC_BASE_ADDRESS,
+ SYSTEM_SLEEP_OFFSET,
+ SYSTEM_SLEEP_DISABLE_LSB,
+ SYSTEM_SLEEP_DISABLE_MASK,
+ CLOCK_CONTROL_OFFSET,
+ CLOCK_CONTROL_SI0_CLK_MASK,
+ RESET_CONTROL_OFFSET,
+ RESET_CONTROL_SI0_RST_MASK,
+ GPIO_BASE_ADDRESS,
+ GPIO_PIN0_OFFSET,
+ GPIO_PIN0_CONFIG_MASK,
+ GPIO_PIN1_OFFSET,
+ GPIO_PIN1_CONFIG_MASK,
+ SI_CONFIG_BIDIR_OD_DATA_LSB,
+ SI_CONFIG_BIDIR_OD_DATA_MASK,
+ SI_CONFIG_I2C_LSB,
+ SI_CONFIG_I2C_MASK,
+ SI_CONFIG_POS_SAMPLE_LSB,
+ SI_CONFIG_POS_SAMPLE_MASK,
+ SI_CONFIG_INACTIVE_CLK_LSB,
+ SI_CONFIG_INACTIVE_CLK_MASK,
+ SI_CONFIG_INACTIVE_DATA_LSB,
+ SI_CONFIG_INACTIVE_DATA_MASK,
+ SI_CONFIG_DIVIDER_LSB,
+ SI_CONFIG_DIVIDER_MASK,
+ SI_BASE_ADDRESS,
+ SI_CONFIG_OFFSET,
+ SI_TX_DATA0_OFFSET,
+ SI_TX_DATA1_OFFSET,
+ SI_RX_DATA0_OFFSET,
+ SI_RX_DATA1_OFFSET,
+ SI_CS_OFFSET,
+ SI_CS_DONE_ERR_MASK,
+ SI_CS_DONE_INT_MASK,
+ SI_CS_START_LSB,
+ SI_CS_START_MASK,
+ SI_CS_RX_CNT_LSB,
+ SI_CS_RX_CNT_MASK,
+ SI_CS_TX_CNT_LSB,
+ SI_CS_TX_CNT_MASK,
+ MY_TARGET_BOARD_DATA_SZ,
+ MY_TARGET_BOARD_EXT_DATA_SZ,
+};
+
+#else
+
+static struct targetdef_s my_target_def = {
+ .d_RTC_BASE_ADDRESS = RTC_BASE_ADDRESS,
+ .d_SYSTEM_SLEEP_OFFSET = SYSTEM_SLEEP_OFFSET,
+ .d_SYSTEM_SLEEP_DISABLE_LSB = SYSTEM_SLEEP_DISABLE_LSB,
+ .d_SYSTEM_SLEEP_DISABLE_MASK = SYSTEM_SLEEP_DISABLE_MASK,
+ .d_CLOCK_CONTROL_OFFSET = CLOCK_CONTROL_OFFSET,
+ .d_CLOCK_CONTROL_SI0_CLK_MASK = CLOCK_CONTROL_SI0_CLK_MASK,
+ .d_RESET_CONTROL_OFFSET = RESET_CONTROL_OFFSET,
+ .d_RESET_CONTROL_SI0_RST_MASK = RESET_CONTROL_SI0_RST_MASK,
+ .d_GPIO_BASE_ADDRESS = GPIO_BASE_ADDRESS,
+ .d_GPIO_PIN0_OFFSET = GPIO_PIN0_OFFSET,
+ .d_GPIO_PIN0_CONFIG_MASK = GPIO_PIN0_CONFIG_MASK,
+ .d_GPIO_PIN1_OFFSET = GPIO_PIN1_OFFSET,
+ .d_GPIO_PIN1_CONFIG_MASK = GPIO_PIN1_CONFIG_MASK,
+ .d_SI_CONFIG_BIDIR_OD_DATA_LSB = SI_CONFIG_BIDIR_OD_DATA_LSB,
+ .d_SI_CONFIG_BIDIR_OD_DATA_MASK = SI_CONFIG_BIDIR_OD_DATA_MASK,
+ .d_SI_CONFIG_I2C_LSB = SI_CONFIG_I2C_LSB,
+ .d_SI_CONFIG_I2C_MASK = SI_CONFIG_I2C_MASK,
+ .d_SI_CONFIG_POS_SAMPLE_LSB = SI_CONFIG_POS_SAMPLE_LSB,
+ .d_SI_CONFIG_POS_SAMPLE_MASK = SI_CONFIG_POS_SAMPLE_MASK,
+ .d_SI_CONFIG_INACTIVE_CLK_LSB = SI_CONFIG_INACTIVE_CLK_LSB,
+ .d_SI_CONFIG_INACTIVE_CLK_MASK = SI_CONFIG_INACTIVE_CLK_MASK,
+ .d_SI_CONFIG_INACTIVE_DATA_LSB = SI_CONFIG_INACTIVE_DATA_LSB,
+ .d_SI_CONFIG_INACTIVE_DATA_MASK = SI_CONFIG_INACTIVE_DATA_MASK,
+ .d_SI_CONFIG_DIVIDER_LSB = SI_CONFIG_DIVIDER_LSB,
+ .d_SI_CONFIG_DIVIDER_MASK = SI_CONFIG_DIVIDER_MASK,
+ .d_SI_BASE_ADDRESS = SI_BASE_ADDRESS,
+ .d_SI_CONFIG_OFFSET = SI_CONFIG_OFFSET,
+ .d_SI_TX_DATA0_OFFSET = SI_TX_DATA0_OFFSET,
+ .d_SI_TX_DATA1_OFFSET = SI_TX_DATA1_OFFSET,
+ .d_SI_RX_DATA0_OFFSET = SI_RX_DATA0_OFFSET,
+ .d_SI_RX_DATA1_OFFSET = SI_RX_DATA1_OFFSET,
+ .d_SI_CS_OFFSET = SI_CS_OFFSET,
+ .d_SI_CS_DONE_ERR_MASK = SI_CS_DONE_ERR_MASK,
+ .d_SI_CS_DONE_INT_MASK = SI_CS_DONE_INT_MASK,
+ .d_SI_CS_START_LSB = SI_CS_START_LSB,
+ .d_SI_CS_START_MASK = SI_CS_START_MASK,
+ .d_SI_CS_RX_CNT_LSB = SI_CS_RX_CNT_LSB,
+ .d_SI_CS_RX_CNT_MASK = SI_CS_RX_CNT_MASK,
+ .d_SI_CS_TX_CNT_LSB = SI_CS_TX_CNT_LSB,
+ .d_SI_CS_TX_CNT_MASK = SI_CS_TX_CNT_MASK,
+ .d_BOARD_DATA_SZ = MY_TARGET_BOARD_DATA_SZ,
+ .d_BOARD_EXT_DATA_SZ = MY_TARGET_BOARD_EXT_DATA_SZ,
+};
+
+#endif
+
+#if MY_TARGET_BOARD_DATA_SZ > BOARD_DATA_SZ_MAX
+#error "BOARD_DATA_SZ_MAX is too small"
+#endif
+
+struct targetdef_s *MY_TARGET_DEF = &my_target_def;
+
+#else /* } { */
+
+#define RTC_BASE_ADDRESS (targetdef->d_RTC_BASE_ADDRESS)
+#define SYSTEM_SLEEP_OFFSET (targetdef->d_SYSTEM_SLEEP_OFFSET)
+#define SYSTEM_SLEEP_DISABLE_LSB (targetdef->d_SYSTEM_SLEEP_DISABLE_LSB)
+#define SYSTEM_SLEEP_DISABLE_MASK (targetdef->d_SYSTEM_SLEEP_DISABLE_MASK)
+#define CLOCK_CONTROL_OFFSET (targetdef->d_CLOCK_CONTROL_OFFSET)
+#define CLOCK_CONTROL_SI0_CLK_MASK (targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK)
+#define RESET_CONTROL_OFFSET (targetdef->d_RESET_CONTROL_OFFSET)
+#define RESET_CONTROL_SI0_RST_MASK (targetdef->d_RESET_CONTROL_SI0_RST_MASK)
+#define GPIO_BASE_ADDRESS (targetdef->d_GPIO_BASE_ADDRESS)
+#define GPIO_PIN0_OFFSET (targetdef->d_GPIO_PIN0_OFFSET)
+#define GPIO_PIN0_CONFIG_MASK (targetdef->d_GPIO_PIN0_CONFIG_MASK)
+#define GPIO_PIN1_OFFSET (targetdef->d_GPIO_PIN1_OFFSET)
+#define GPIO_PIN1_CONFIG_MASK (targetdef->d_GPIO_PIN1_CONFIG_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_LSB (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB)
+#define SI_CONFIG_BIDIR_OD_DATA_MASK (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_LSB (targetdef->d_SI_CONFIG_I2C_LSB)
+#define SI_CONFIG_I2C_MASK (targetdef->d_SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_LSB (targetdef->d_SI_CONFIG_POS_SAMPLE_LSB)
+#define SI_CONFIG_POS_SAMPLE_MASK (targetdef->d_SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_INACTIVE_CLK_LSB (targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB)
+#define SI_CONFIG_INACTIVE_CLK_MASK (targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_INACTIVE_DATA_LSB (targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB)
+#define SI_CONFIG_INACTIVE_DATA_MASK (targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_DIVIDER_LSB (targetdef->d_SI_CONFIG_DIVIDER_LSB)
+#define SI_CONFIG_DIVIDER_MASK (targetdef->d_SI_CONFIG_DIVIDER_MASK)
+#define SI_BASE_ADDRESS (targetdef->d_SI_BASE_ADDRESS)
+#define SI_CONFIG_OFFSET (targetdef->d_SI_CONFIG_OFFSET)
+#define SI_TX_DATA0_OFFSET (targetdef->d_SI_TX_DATA0_OFFSET)
+#define SI_TX_DATA1_OFFSET (targetdef->d_SI_TX_DATA1_OFFSET)
+#define SI_RX_DATA0_OFFSET (targetdef->d_SI_RX_DATA0_OFFSET)
+#define SI_RX_DATA1_OFFSET (targetdef->d_SI_RX_DATA1_OFFSET)
+#define SI_CS_OFFSET (targetdef->d_SI_CS_OFFSET)
+#define SI_CS_DONE_ERR_MASK (targetdef->d_SI_CS_DONE_ERR_MASK)
+#define SI_CS_DONE_INT_MASK (targetdef->d_SI_CS_DONE_INT_MASK)
+#define SI_CS_START_LSB (targetdef->d_SI_CS_START_LSB)
+#define SI_CS_START_MASK (targetdef->d_SI_CS_START_MASK)
+#define SI_CS_RX_CNT_LSB (targetdef->d_SI_CS_RX_CNT_LSB)
+#define SI_CS_RX_CNT_MASK (targetdef->d_SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_LSB (targetdef->d_SI_CS_TX_CNT_LSB)
+#define SI_CS_TX_CNT_MASK (targetdef->d_SI_CS_TX_CNT_MASK)
+#define EEPROM_SZ (targetdef->d_BOARD_DATA_SZ)
+#define EEPROM_EXT_SZ (targetdef->d_BOARD_EXT_DATA_SZ)
+
+/* SET macros */
+#define SYSTEM_SLEEP_DISABLE_SET(x) (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK)
+#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
+#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
+#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
+#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
+#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
+#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
+#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
+#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
+#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
+
+#endif /* } */
+
+#endif /*TARGET_REG_TABLE_H_*/
+
+
diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h
new file mode 100644
index 000000000000..f55a6454a6b4
--- /dev/null
+++ b/drivers/staging/ath6kl/include/wlan_api.h
@@ -0,0 +1,128 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the API for the host wlan module
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HOST_WLAN_API_H_
+#define _HOST_WLAN_API_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <a_osapi.h>
+
+struct ieee80211_node_table;
+struct ieee80211_frame;
+
+struct ieee80211_common_ie {
+ A_UINT16 ie_chan;
+ A_UINT8 *ie_tstamp;
+ A_UINT8 *ie_ssid;
+ A_UINT8 *ie_rates;
+ A_UINT8 *ie_xrates;
+ A_UINT8 *ie_country;
+ A_UINT8 *ie_wpa;
+ A_UINT8 *ie_rsn;
+ A_UINT8 *ie_wmm;
+ A_UINT8 *ie_ath;
+ A_UINT16 ie_capInfo;
+ A_UINT16 ie_beaconInt;
+ A_UINT8 *ie_tim;
+ A_UINT8 *ie_chswitch;
+ A_UINT8 ie_erp;
+ A_UINT8 *ie_wsc;
+ A_UINT8 *ie_htcap;
+ A_UINT8 *ie_htop;
+#ifdef WAPI_ENABLE
+ A_UINT8 *ie_wapi;
+#endif
+};
+
+typedef struct bss {
+ A_UINT8 ni_macaddr[6];
+ A_UINT8 ni_snr;
+ A_INT16 ni_rssi;
+ struct bss *ni_list_next;
+ struct bss *ni_list_prev;
+ struct bss *ni_hash_next;
+ struct bss *ni_hash_prev;
+ struct ieee80211_common_ie ni_cie;
+ A_UINT8 *ni_buf;
+ A_UINT16 ni_framelen;
+ struct ieee80211_node_table *ni_table;
+ A_UINT32 ni_refcnt;
+ int ni_scangen;
+
+ A_UINT32 ni_tstamp;
+ A_UINT32 ni_actcnt;
+#ifdef OS_ROAM_MANAGEMENT
+ A_UINT32 ni_si_gen;
+#endif
+} bss_t;
+
+typedef void wlan_node_iter_func(void *arg, bss_t *);
+
+bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size);
+void wlan_node_free(bss_t *ni);
+void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
+ const A_UINT8 *macaddr);
+bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr);
+void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
+void wlan_free_allnodes(struct ieee80211_node_table *nt);
+void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
+ void *arg);
+
+void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt);
+void wlan_node_table_reset(struct ieee80211_node_table *nt);
+void wlan_node_table_cleanup(struct ieee80211_node_table *nt);
+
+A_STATUS wlan_parse_beacon(A_UINT8 *buf, int framelen,
+ struct ieee80211_common_ie *cie);
+
+A_UINT16 wlan_ieee2freq(int chan);
+A_UINT32 wlan_freq2ieee(A_UINT16 freq);
+
+void wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge);
+
+void
+wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt);
+
+bss_t *
+wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID);
+
+void
+wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni);
+
+bss_t *wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid);
+
+bss_t *
+wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_UINT32 dot11AuthMode, A_UINT32 authMode,
+ A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HOST_WLAN_API_H_ */
diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h
new file mode 100644
index 000000000000..4a9154316a35
--- /dev/null
+++ b/drivers/staging/ath6kl/include/wmi_api.h
@@ -0,0 +1,441 @@
+//------------------------------------------------------------------------------
+// <copyright file="wmi_api.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the definitions for the Wireless Module Interface (WMI).
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _WMI_API_H_
+#define _WMI_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* WMI converts a dix frame with an ethernet payload (up to 1500 bytes)
+ * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */
+#define WMI_MAX_TX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
+
+ /* A normal WMI data frame */
+#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
+
+ /* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
+#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH (3840 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR))
+
+/*
+ * IP QoS Field definitions according to 802.1p
+ */
+#define BEST_EFFORT_PRI 0
+#define BACKGROUND_PRI 1
+#define EXCELLENT_EFFORT_PRI 3
+#define CONTROLLED_LOAD_PRI 4
+#define VIDEO_PRI 5
+#define VOICE_PRI 6
+#define NETWORK_CONTROL_PRI 7
+#define MAX_NUM_PRI 8
+
+#define UNDEFINED_PRI (0xff)
+
+#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */
+
+#define A_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+
+typedef enum {
+ ATHEROS_COMPLIANCE = 0x1,
+}TSPEC_PARAM_COMPLIANCE;
+
+struct wmi_t;
+
+void *wmi_init(void *devt);
+
+void wmi_qos_state_init(struct wmi_t *wmip);
+void wmi_shutdown(struct wmi_t *wmip);
+HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip);
+void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid);
+A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8);
+A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS);
+A_STATUS wmi_dot3_2_dix(void *osbuf);
+
+A_STATUS wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode);
+
+A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_syncpoint(struct wmi_t *wmip);
+A_STATUS wmi_syncpoint_reset(struct wmi_t *wmip);
+A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled);
+
+A_UINT8 wmi_determine_userPriority (A_UINT8 *pkt, A_UINT32 layer2Pri);
+
+A_STATUS wmi_control_rx(struct wmi_t *wmip, void *osbuf);
+void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg);
+void wmi_free_allnodes(struct wmi_t *wmip);
+bss_t *wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr);
+void wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr);
+
+
+typedef enum {
+ NO_SYNC_WMIFLAG = 0,
+ SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */
+ SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */
+ SYNC_BOTH_WMIFLAG,
+ END_WMIFLAG /* end marker */
+} WMI_SYNC_FLAG;
+
+A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
+ WMI_SYNC_FLAG flag);
+
+A_STATUS wmi_connect_cmd(struct wmi_t *wmip,
+ NETWORK_TYPE netType,
+ DOT11_AUTH_MODE dot11AuthMode,
+ AUTH_MODE authMode,
+ CRYPTO_TYPE pairwiseCrypto,
+ A_UINT8 pairwiseCryptoLen,
+ CRYPTO_TYPE groupCrypto,
+ A_UINT8 groupCryptoLen,
+ int ssidLength,
+ A_UCHAR *ssid,
+ A_UINT8 *bssid,
+ A_UINT16 channel,
+ A_UINT32 ctrl_flags);
+
+A_STATUS wmi_reconnect_cmd(struct wmi_t *wmip,
+ A_UINT8 *bssid,
+ A_UINT16 channel);
+A_STATUS wmi_disconnect_cmd(struct wmi_t *wmip);
+A_STATUS wmi_getrev_cmd(struct wmi_t *wmip);
+A_STATUS wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
+ A_BOOL forceFgScan, A_BOOL isLegacy,
+ A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
+ A_INT8 numChan, A_UINT16 *channelList);
+A_STATUS wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
+ A_UINT16 fg_end_sec, A_UINT16 bg_sec,
+ A_UINT16 minact_chdw_msec,
+ A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec,
+ A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
+ A_UINT32 max_dfsch_act_time,
+ A_UINT16 maxact_scan_per_ssid);
+A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask);
+A_STATUS wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
+ A_UINT8 ssidLength, A_UCHAR *ssid);
+A_STATUS wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons);
+A_STATUS wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons);
+A_STATUS wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
+ A_UINT8 ieLen, A_UINT8 *ieInfo);
+A_STATUS wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode);
+A_STATUS wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
+ A_UINT16 atim_windows, A_UINT16 timeout_value);
+A_STATUS wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time,
+ A_UINT32 ps_period, A_UINT8 sleep_period);
+A_STATUS wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
+ A_UINT16 psPollNum, A_UINT16 dtimPolicy,
+ A_UINT16 wakup_tx_policy, A_UINT16 num_tx_to_wakeup,
+ A_UINT16 ps_fail_event_policy);
+A_STATUS wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout);
+A_STATUS wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber);
+A_STATUS wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
+A_STATUS wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID);
+A_STATUS wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask);
+A_STATUS wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate);
+A_STATUS wmi_get_bitrate_cmd(struct wmi_t *wmip);
+A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx);
+A_STATUS wmi_get_regDomain_cmd(struct wmi_t *wmip);
+A_STATUS wmi_get_channelList_cmd(struct wmi_t *wmip);
+A_STATUS wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
+ WMI_PHY_MODE mode, A_INT8 numChan,
+ A_UINT16 *channelList);
+
+A_STATUS wmi_set_snr_threshold_params(struct wmi_t *wmip,
+ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
+A_STATUS wmi_set_rssi_threshold_params(struct wmi_t *wmip,
+ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
+A_STATUS wmi_clr_rssi_snr(struct wmi_t *wmip);
+A_STATUS wmi_set_lq_threshold_params(struct wmi_t *wmip,
+ WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd);
+A_STATUS wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold);
+A_STATUS wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy);
+
+A_STATUS wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask);
+
+A_STATUS wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie,
+ A_UINT32 source);
+
+A_STATUS wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
+ A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
+ A_UINT32 valid);
+
+A_STATUS wmi_get_stats_cmd(struct wmi_t *wmip);
+
+A_STATUS wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex,
+ CRYPTO_TYPE keyType, A_UINT8 keyUsage,
+ A_UINT8 keyLength,A_UINT8 *keyRSC,
+ A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *mac,
+ WMI_SYNC_FLAG sync_flag);
+A_STATUS wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk);
+A_STATUS wmi_delete_krk_cmd(struct wmi_t *wmip);
+A_STATUS wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex);
+A_STATUS wmi_set_akmp_params_cmd(struct wmi_t *wmip,
+ WMI_SET_AKMP_PARAMS_CMD *akmpParams);
+A_STATUS wmi_get_pmkid_list_cmd(struct wmi_t *wmip);
+A_STATUS wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
+ WMI_SET_PMKID_LIST_CMD *pmkInfo);
+A_STATUS wmi_abort_scan_cmd(struct wmi_t *wmip);
+A_STATUS wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM);
+A_STATUS wmi_get_txPwr_cmd(struct wmi_t *wmip);
+A_STATUS wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid);
+A_STATUS wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex);
+A_STATUS wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en);
+A_STATUS wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
+ A_BOOL set);
+A_STATUS wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop,
+ A_UINT8 eCWmin, A_UINT8 eCWmax,
+ A_UINT8 aifsn);
+A_STATUS wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
+ A_UINT8 trafficClass, A_UINT8 maxRetries,
+ A_UINT8 enableNotify);
+
+void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid);
+
+A_STATUS wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
+A_STATUS wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType);
+A_STATUS wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
+ A_UINT8 size);
+A_STATUS wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
+ WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
+ A_UINT8 size);
+
+A_STATUS wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode);
+A_STATUS wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
+ A_UINT8 frmType,
+ A_UINT8 *dstMacAddr,
+ A_UINT8 *bssid,
+ A_UINT16 optIEDataLen,
+ A_UINT8 *optIEData);
+
+A_STATUS wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl);
+A_STATUS wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize);
+A_STATUS wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen);
+A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority);
+A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
+A_STATUS wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance);
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+A_STATUS wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len);
+#endif
+
+A_STATUS wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status);
+A_STATUS wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd);
+
+A_STATUS wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd);
+
+A_STATUS wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd);
+
+A_STATUS wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd);
+
+A_STATUS wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd);
+
+A_STATUS wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd);
+
+
+A_STATUS wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd);
+
+A_STATUS wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd);
+
+A_STATUS wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd);
+
+A_STATUS wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd);
+
+A_STATUS wmi_get_btcoex_stats_cmd(struct wmi_t * wmip);
+
+A_STATUS wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold);
+
+/*
+ * This function is used to configure the fix rates mask to the target.
+ */
+A_STATUS wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask);
+A_STATUS wmi_get_ratemask_cmd(struct wmi_t *wmip);
+
+A_STATUS wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode);
+
+A_STATUS wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode);
+
+A_STATUS wmi_set_qos_supp_cmd(struct wmi_t *wmip,A_UINT8 status);
+A_STATUS wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status);
+A_STATUS wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable);
+A_STATUS wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode);
+
+A_STATUS wmi_get_keepalive_configured(struct wmi_t *wmip);
+A_UINT8 wmi_get_keepalive_cmd(struct wmi_t *wmip);
+A_STATUS wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval);
+
+A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType,
+ A_UINT8 ieLen,A_UINT8 *ieInfo);
+
+A_STATUS wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen);
+
+A_INT32 wmi_get_rate(A_INT8 rateindex);
+
+A_STATUS wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd);
+
+/*Wake on Wireless WMI commands*/
+A_STATUS wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd);
+A_STATUS wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd);
+A_STATUS wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd);
+A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
+ WMI_ADD_WOW_PATTERN_CMD *cmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size);
+A_STATUS wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
+ WMI_DEL_WOW_PATTERN_CMD *cmd);
+A_STATUS wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status);
+
+A_STATUS
+wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer);
+
+A_STATUS
+wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4);
+
+A_STATUS
+wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4);
+
+A_STATUS
+wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable);
+
+bss_t *
+wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID);
+
+
+void
+wmi_node_return (struct wmi_t *wmip, bss_t *bss);
+
+void
+wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge);
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+A_STATUS wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins);
+A_STATUS wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr);
+A_STATUS wmi_prof_start_cmd(struct wmi_t *wmip);
+A_STATUS wmi_prof_stop_cmd(struct wmi_t *wmip);
+A_STATUS wmi_prof_count_get_cmd(struct wmi_t *wmip);
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+#ifdef OS_ROAM_MANAGEMENT
+void wmi_scan_indication (struct wmi_t *wmip);
+#endif
+
+A_STATUS
+wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd);
+
+bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id);
+A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss);
+
+
+/*
+ * AP mode
+ */
+A_STATUS
+wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p);
+
+A_STATUS
+wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid);
+
+A_STATUS
+wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta);
+
+A_STATUS
+wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy);
+
+A_STATUS
+wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a);
+
+A_UINT8
+acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl);
+
+A_STATUS
+wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason);
+
+A_STATUS
+wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag);
+
+A_STATUS
+wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period);
+
+A_STATUS
+wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell);
+
+A_STATUS
+wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim);
+
+A_STATUS
+wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset);
+
+A_STATUS
+wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
+
+A_STATUS
+wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width);
+
+A_STATUS
+wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz);
+
+A_STATUS
+wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray);
+
+A_STATUS
+wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid);
+
+A_STATUS
+wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink);
+
+A_STATUS
+wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask);
+
+A_STATUS
+wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_BOOL rxDot11Hdr, A_BOOL defragOnHost);
+
+A_STATUS
+wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode);
+
+A_STATUS
+wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence);
+
+A_STATUS
+wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk);
+
+A_UINT16
+wmi_ieee2freq (int chan);
+
+A_UINT32
+wmi_freq2ieee (A_UINT16 freq);
+
+bss_t *
+wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
+ A_UINT32 ssidLength,
+ A_UINT32 dot11AuthMode, A_UINT32 authMode,
+ A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_API_H_ */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
new file mode 100644
index 000000000000..83bc5be3ef1b
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
@@ -0,0 +1,566 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// AR3K configuration implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#define ATH_MODULE_NAME misc
+#include "a_debug.h"
+#include "common_drv.h"
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+#include "export_hci_transport.h"
+#else
+#include "hci_transport_api.h"
+#endif
+#include "ar3kconfig.h"
+#include "tlpm.h"
+
+#define BAUD_CHANGE_COMMAND_STATUS_OFFSET 5
+#define HCI_EVENT_RESP_TIMEOUTMS 3000
+#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET 0
+#define HCI_CMD_OPCODE_BYTE_HI_OFFSET 1
+#define HCI_EVENT_OPCODE_BYTE_LOW 3
+#define HCI_EVENT_OPCODE_BYTE_HI 4
+#define HCI_CMD_COMPLETE_EVENT_CODE 0xE
+#define HCI_MAX_EVT_RECV_LENGTH 257
+#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5
+
+A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev);
+
+static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig,
+ A_UINT8 *pBuffer,
+ int Length)
+{
+ HTC_PACKET *pPacket = NULL;
+ A_STATUS status = A_OK;
+
+ do {
+
+ pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
+ if (NULL == pPacket) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_MEMZERO(pPacket,sizeof(HTC_PACKET));
+ SET_HTC_PACKET_INFO_TX(pPacket,
+ NULL,
+ pBuffer,
+ Length,
+ HCI_COMMAND_TYPE,
+ AR6K_CONTROL_PKT_TAG);
+
+ /* issue synchronously */
+ status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,TRUE);
+
+ } while (FALSE);
+
+ if (pPacket != NULL) {
+ A_FREE(pPacket);
+ }
+
+ return status;
+}
+
+static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig,
+ A_UINT8 *pBuffer,
+ int *pLength)
+{
+ A_STATUS status = A_OK;
+ HTC_PACKET *pRecvPacket = NULL;
+
+ do {
+
+ pRecvPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
+ if (NULL == pRecvPacket) {
+ status = A_NO_MEMORY;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
+ break;
+ }
+
+ A_MEMZERO(pRecvPacket,sizeof(HTC_PACKET));
+
+ SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
+
+ status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
+ pRecvPacket,
+ HCI_EVENT_RESP_TIMEOUTMS);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ *pLength = pRecvPacket->ActualLength;
+
+ } while (FALSE);
+
+ if (pRecvPacket != NULL) {
+ A_FREE(pRecvPacket);
+ }
+
+ return status;
+}
+
+A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
+ A_UINT8 *pHCICommand,
+ int CmdLength,
+ A_UINT8 **ppEventBuffer,
+ A_UINT8 **ppBufferToFree)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 *pBuffer = NULL;
+ A_UINT8 *pTemp;
+ int length;
+ A_BOOL commandComplete = FALSE;
+ A_UINT8 opCodeBytes[2];
+
+ do {
+
+ length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
+ length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
+ length += pConfig->pHCIProps->IOBlockPad;
+
+ pBuffer = (A_UINT8 *)A_MALLOC(length);
+ if (NULL == pBuffer) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ /* get the opcodes to check the command complete event */
+ opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
+ opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];
+
+ /* copy HCI command */
+ A_MEMCPY(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);
+ /* send command */
+ status = SendHCICommand(pConfig,
+ pBuffer + pConfig->pHCIProps->HeadRoom,
+ CmdLength);
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
+ AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
+ break;
+ }
+
+ /* reuse buffer to capture command complete event */
+ A_MEMZERO(pBuffer,length);
+ status = RecvHCIEvent(pConfig,pBuffer,&length);
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
+ AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
+ break;
+ }
+
+ pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;
+ if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
+ if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
+ (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
+ commandComplete = TRUE;
+ }
+ }
+
+ if (!commandComplete) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
+ AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
+ status = A_ECOMM;
+ break;
+ }
+
+ if (ppEventBuffer != NULL) {
+ /* caller wants to look at the event */
+ *ppEventBuffer = pTemp;
+ if (ppBufferToFree == NULL) {
+ status = A_EINVAL;
+ break;
+ }
+ /* caller must free the buffer */
+ *ppBufferToFree = pBuffer;
+ pBuffer = NULL;
+ }
+
+ } while (FALSE);
+
+ if (pBuffer != NULL) {
+ A_FREE(pBuffer);
+ }
+
+ return status;
+}
+
+static A_STATUS AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0};
+ A_UINT16 baudVal;
+ A_UINT8 *pEvent = NULL;
+ A_UINT8 *pBufferToFree = NULL;
+
+ do {
+
+ if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
+ baudVal = (A_UINT16)(pConfig->AR3KBaudRate / 100);
+ hciBaudChangeCommand[3] = (A_UINT8)baudVal;
+ hciBaudChangeCommand[4] = (A_UINT8)(baudVal >> 8);
+
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ hciBaudChangeCommand,
+ sizeof(hciBaudChangeCommand),
+ &pEvent,
+ &pBufferToFree);
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n"));
+ break;
+ }
+
+ if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("AR3K Config: Baud change command event status failed: %d \n",
+ pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET]));
+ status = A_ECOMM;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate));
+ }
+
+ if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) {
+ /* some versions of AR3K do not switch baud immediately, up to 300MS */
+ A_MDELAY(325);
+ }
+
+ if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) {
+ /* Tell target to change UART baud rate for AR6K */
+ status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("AR3K Config: failed to set scale and step values: %d \n", status));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
+ ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate));
+ }
+
+ } while (FALSE);
+
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+
+ return status;
+}
+
+static A_STATUS AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig)
+{
+ A_STATUS status;
+ A_CHAR exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00};
+ A_UINT8 *pEvent = NULL;
+ A_UINT8 *pBufferToFree = NULL;
+
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ exitMinBootCmd,
+ sizeof(exitMinBootCmd),
+ &pEvent,
+ &pBufferToFree);
+
+ if (A_SUCCESS(status)) {
+ if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("AR3K Config: MinBoot exit command event status failed: %d \n",
+ pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET]));
+ status = A_ECOMM;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("AR3K Config: MinBoot Exit Command Complete (Success) \n"));
+ A_MDELAY(1);
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n"));
+ }
+
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+
+ return status;
+}
+
+static A_STATUS AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig)
+{
+ A_STATUS status = A_OK;
+ A_UINT8 hciResetCommand[] = {0x03,0x0c,0x0};
+ A_UINT8 *pEvent = NULL;
+ A_UINT8 *pBufferToFree = NULL;
+
+ status = SendHCICommandWaitCommandComplete( pConfig,
+ hciResetCommand,
+ sizeof(hciResetCommand),
+ &pEvent,
+ &pBufferToFree );
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
+ }
+
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+
+ return status;
+}
+
+static A_STATUS AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig)
+{
+ A_STATUS status;
+ /* AR3K vendor specific command for Host Wakeup Config */
+ A_CHAR hostWakeupConfig[] = {0x31,0xFC,0x18,
+ 0x02,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,
+ TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
+ 0x00,0x00,0x00,0x00,
+ TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
+ 0x00,0x00,0x00,0x00};
+ /* AR3K vendor specific command for Target Wakeup Config */
+ A_CHAR targetWakeupConfig[] = {0x31,0xFC,0x18,
+ 0x04,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,
+ TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms
+ 0x00,0x00,0x00,0x00,
+ TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms
+ 0x00,0x00,0x00,0x00};
+ /* AR3K vendor specific command for Host Wakeup Enable */
+ A_CHAR hostWakeupEnable[] = {0x31,0xFC,0x4,
+ 0x01,0x00,0x00,0x00};
+ /* AR3K vendor specific command for Target Wakeup Enable */
+ A_CHAR targetWakeupEnable[] = {0x31,0xFC,0x4,
+ 0x06,0x00,0x00,0x00};
+ /* AR3K vendor specific command for Sleep Enable */
+ A_CHAR sleepEnable[] = {0x4,0xFC,0x1,
+ 0x1};
+ A_UINT8 *pEvent = NULL;
+ A_UINT8 *pBufferToFree = NULL;
+
+ if (0 != pConfig->IdleTimeout) {
+ A_UINT8 idle_lsb = pConfig->IdleTimeout & 0xFF;
+ A_UINT8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8;
+ hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb;
+ hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb;
+ }
+
+ if (0 != pConfig->WakeupTimeout) {
+ hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF);
+ }
+
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ hostWakeupConfig,
+ sizeof(hostWakeupConfig),
+ &pEvent,
+ &pBufferToFree);
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));
+ return status;
+ }
+
+ pEvent = NULL;
+ pBufferToFree = NULL;
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ targetWakeupConfig,
+ sizeof(targetWakeupConfig),
+ &pEvent,
+ &pBufferToFree);
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));
+ return status;
+ }
+
+ pEvent = NULL;
+ pBufferToFree = NULL;
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ hostWakeupEnable,
+ sizeof(hostWakeupEnable),
+ &pEvent,
+ &pBufferToFree);
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));
+ return status;
+ }
+
+ pEvent = NULL;
+ pBufferToFree = NULL;
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ targetWakeupEnable,
+ sizeof(targetWakeupEnable),
+ &pEvent,
+ &pBufferToFree);
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));
+ return status;
+ }
+
+ pEvent = NULL;
+ pBufferToFree = NULL;
+ status = SendHCICommandWaitCommandComplete(pConfig,
+ sleepEnable,
+ sizeof(sleepEnable),
+ &pEvent,
+ &pBufferToFree);
+ if (pBufferToFree != NULL) {
+ A_FREE(pBufferToFree);
+ }
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status));
+
+ return status;
+}
+
+A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfig)
+{
+ A_STATUS status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n"));
+
+ do {
+
+ if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
+ status = A_EINVAL;
+ break;
+ }
+
+ /* disable asynchronous recv while we issue commands and receive events synchronously */
+ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
+ status = AR3KExitMinBoot(pConfig);
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+
+
+ /* Load patching and PST file if available*/
+ if (A_OK != AthPSInitialize(pConfig)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
+ }
+
+ /* Send HCI reset to make PS tags take effect*/
+ AR3KConfigureSendHCIReset(pConfig);
+
+ if (pConfig->Flags &
+ (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
+ status = AR3KConfigureHCIBaud(pConfig);
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+
+
+
+ if (pConfig->PwrMgmtEnabled) {
+ /* the delay is required after the previous HCI reset before further
+ * HCI commands can be issued
+ */
+ A_MDELAY(200);
+ AR3KEnableTLPM(pConfig);
+ }
+
+ /* re-enable asynchronous recv */
+ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+
+ } while (FALSE);
+
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
+
+ return status;
+}
+
+A_STATUS AR3KConfigureExit(void *config)
+{
+ A_STATUS status = A_OK;
+ AR3K_CONFIG_INFO *pConfig = (AR3K_CONFIG_INFO *)config;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n"));
+
+ do {
+
+ if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
+ status = A_EINVAL;
+ break;
+ }
+
+ /* disable asynchronous recv while we issue commands and receive events synchronously */
+ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pConfig->Flags &
+ (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
+ status = AR3KConfigureHCIBaud(pConfig);
+ if (A_FAILED(status)) {
+ break;
+ }
+ }
+
+ /* re-enable asynchronous recv */
+ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+
+ } while (FALSE);
+
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
+
+ return status;
+}
+
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
new file mode 100644
index 000000000000..0e298dba9fc8
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
+ * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
+ * defined.
+ *
+ *
+ * ar3kcpsconfig.c
+ *
+ *
+ *
+ * The software source and binaries included in this development package are
+ * licensed, not sold. You, or your company, received the package under one
+ * or more license agreements. The rights granted to you are specifically
+ * listed in these license agreement(s). All other rights remain with Atheros
+ * Communications, Inc., its subsidiaries, or the respective owner including
+ * those listed on the included copyright notices.. Distribution of any
+ * portion of this package must be in strict compliance with the license
+ * agreement(s) terms.
+ *
+ *
+ *
+ */
+
+
+
+#include "ar3kpsconfig.h"
+#ifndef HCI_TRANSPORT_SDIO
+#include "hci_ath.h"
+#include "hci_uart.h"
+#endif /* #ifndef HCI_TRANSPORT_SDIO */
+
+#define MAX_FW_PATH_LEN 50
+#define MAX_BDADDR_FORMAT_LENGTH 30
+
+/*
+ * Structure used to send HCI packet, hci packet length and device info
+ * together as parameter to PSThread.
+ */
+typedef struct {
+
+ PSCmdPacket *HciCmdList;
+ A_UINT32 num_packets;
+ AR3K_CONFIG_INFO *dev;
+}HciCommandListParam;
+
+A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
+ A_UINT8 *pHCICommand,
+ int CmdLength,
+ A_UINT8 **ppEventBuffer,
+ A_UINT8 **ppBufferToFree);
+
+A_UINT32 Rom_Version;
+A_UINT32 Build_Version;
+extern A_BOOL BDADDR;
+
+A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code);
+A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig);
+#ifndef HCI_TRANSPORT_SDIO
+
+DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
+DECLARE_WAIT_QUEUE_HEAD(HciEvent);
+A_UCHAR *HciEventpacket;
+rwlock_t syncLock;
+wait_queue_t Eventwait;
+
+int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len);
+extern char *bdaddr;
+#endif /* HCI_TRANSPORT_SDIO */
+
+A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type);
+
+int PSSendOps(void *arg);
+
+#ifdef BT_PS_DEBUG
+void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 len)
+{
+ int i;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
+ for (i = 0; i < len; i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
+}
+#else
+#define Hci_log(string,data,len)
+#endif /* BT_PS_DEBUG */
+
+
+
+
+A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev)
+{
+ A_STATUS status = A_OK;
+ if(hdev == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
+ return A_ERROR;
+ }
+
+#ifndef HCI_TRANSPORT_SDIO
+ DECLARE_WAITQUEUE(wait, current);
+#endif /* HCI_TRANSPORT_SDIO */
+
+
+#ifdef HCI_TRANSPORT_SDIO
+ status = PSSendOps((void*)hdev);
+#else
+ if(InitPSState(hdev) == -1) {
+ return A_ERROR;
+ }
+ allow_signal(SIGKILL);
+ add_wait_queue(&PsCompleteEvent,&wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
+ remove_wait_queue(&PsCompleteEvent,&wait);
+ return A_ERROR;
+ }
+ wait_event_interruptible(PsCompleteEvent,(PSTagMode == FALSE));
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&PsCompleteEvent,&wait);
+
+#endif /* HCI_TRANSPORT_SDIO */
+
+
+ return status;
+
+}
+
+int PSSendOps(void *arg)
+{
+ int i;
+ int status = 0;
+ PSCmdPacket *HciCmdList; /* List storing the commands */
+ const struct firmware* firmware;
+ A_UINT32 numCmds;
+ A_UINT8 *event;
+ A_UINT8 *bufferToFree;
+ struct hci_dev *device;
+ A_UCHAR *buffer;
+ A_UINT32 len;
+ A_UINT32 DevType;
+ A_UCHAR *PsFileName;
+ A_UCHAR *patchFileName;
+ A_UCHAR *path = NULL;
+ A_UCHAR *config_path = NULL;
+ A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
+ AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg;
+ struct device *firmwareDev = NULL;
+ status = 0;
+ HciCmdList = NULL;
+#ifdef HCI_TRANSPORT_SDIO
+ device = hdev->pBtStackHCIDev;
+ firmwareDev = device->parent;
+#else
+ device = hdev;
+ firmwareDev = &device->dev;
+ AthEnableSyncCommandOp(TRUE);
+#endif /* HCI_TRANSPORT_SDIO */
+ /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
+ */
+
+ path =(A_UCHAR *)A_MALLOC(MAX_FW_PATH_LEN);
+ if(path == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
+ goto complete;
+ }
+ config_path = (A_UCHAR *) A_MALLOC(MAX_FW_PATH_LEN);
+ if(config_path == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
+ goto complete;
+ }
+
+ if(A_ERROR == getDeviceType(hdev,&DevType)) {
+ status = 1;
+ goto complete;
+ }
+ if(A_ERROR == ReadVersionInfo(hdev)) {
+ status = 1;
+ goto complete;
+ }
+
+ patchFileName = PATCH_FILE;
+ snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
+ if(DevType){
+ if(DevType == 0xdeadc0de){
+ PsFileName = PS_ASIC_FILE;
+ } else{
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version));
+ if((Rom_Version == 0x99999999) && (Build_Version == 1)){
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
+ patchFileName = NULL;
+ }
+ PsFileName = PS_FPGA_FILE;
+ }
+ }
+ else{
+ PsFileName = PS_ASIC_FILE;
+ }
+
+ snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
+ /* Read the PS file to a dynamically allocated buffer */
+ if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
+ status = 1;
+ goto complete;
+
+ }
+ if(NULL == firmware || firmware->size == 0) {
+ status = 1;
+ goto complete;
+ }
+ buffer = (A_UCHAR *)A_MALLOC(firmware->size);
+ if(buffer != NULL) {
+ /* Copy the read file to a local Dynamic buffer */
+ memcpy(buffer,firmware->data,firmware->size);
+ len = firmware->size;
+ A_RELEASE_FIRMWARE(firmware);
+ /* Parse the PS buffer to a global variable */
+ status = AthDoParsePS(buffer,len);
+ A_FREE(buffer);
+ } else {
+ A_RELEASE_FIRMWARE(firmware);
+ }
+
+
+ /* Read the patch file to a dynamically allocated buffer */
+ if(patchFileName != NULL)
+ snprintf(config_path,
+ MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
+ else {
+ status = 0;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
+ if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
+ /*
+ * It is not necessary that Patch file be available, continue with PS Operations if.
+ * failed.
+ */
+ status = 0;
+
+ } else {
+ if(NULL == firmware || firmware->size == 0) {
+ status = 0;
+ } else {
+ buffer = (A_UCHAR *)A_MALLOC(firmware->size);
+ if(buffer != NULL) {
+ /* Copy the read file to a local Dynamic buffer */
+ memcpy(buffer,firmware->data,firmware->size);
+ len = firmware->size;
+ A_RELEASE_FIRMWARE(firmware);
+ /* parse and store the Patch file contents to a global variables */
+ status = AthDoParsePatch(buffer,len);
+ A_FREE(buffer);
+ } else {
+ A_RELEASE_FIRMWARE(firmware);
+ }
+ }
+ }
+
+ /* Create an HCI command list from the parsed PS and patch information */
+ AthCreateCommandList(&HciCmdList,&numCmds);
+
+ /* Form the parameter for PSSendOps() API */
+
+
+ /*
+ * First Send the CRC packet,
+ * We have to continue with the PS operations only if the CRC packet has been replied with
+ * a Command complete event with status Error.
+ */
+
+ if(SendHCICommandWaitCommandComplete
+ (hdev,
+ HciCmdList[0].Hcipacket,
+ HciCmdList[0].packetLen,
+ &event,
+ &bufferToFree) == A_OK) {
+ if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+
+#ifndef HCI_TRANSPORT_SDIO
+ if(bdaddr && bdaddr[0] !='\0') {
+ write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
+ }
+#endif
+ status = 1;
+ goto complete;
+ }
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ } else {
+ status = 0;
+ goto complete;
+ }
+
+ for(i = 1; i <numCmds; i++) {
+
+ if(SendHCICommandWaitCommandComplete
+ (hdev,
+ HciCmdList[i].Hcipacket,
+ HciCmdList[i].packetLen,
+ &event,
+ &bufferToFree) == A_OK) {
+ if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ status = 1;
+ goto complete;
+ }
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ } else {
+ status = 0;
+ goto complete;
+ }
+ }
+#ifdef HCI_TRANSPORT_SDIO
+ if(BDADDR == FALSE)
+ if(hdev->bdaddr[0] !=0x00 ||
+ hdev->bdaddr[1] !=0x00 ||
+ hdev->bdaddr[2] !=0x00 ||
+ hdev->bdaddr[3] !=0x00 ||
+ hdev->bdaddr[4] !=0x00 ||
+ hdev->bdaddr[5] !=0x00)
+ write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);
+
+#ifndef HCI_TRANSPORT_SDIO
+
+ if(bdaddr && bdaddr[0] != '\0') {
+ write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
+ } else
+#endif /* HCI_TRANSPORT_SDIO */
+ /* Write BDADDR Read from OTP here */
+
+
+
+#endif
+
+ {
+ /* Read Contents of BDADDR file if user has not provided any option */
+ snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
+ if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
+ status = 1;
+ goto complete;
+ }
+ if(NULL == firmware || firmware->size == 0) {
+ status = 1;
+ goto complete;
+ }
+ len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size;
+ memcpy(config_bdaddr, firmware->data,len);
+ config_bdaddr[len] = '\0';
+ write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
+ A_RELEASE_FIRMWARE(firmware);
+ }
+complete:
+#ifndef HCI_TRANSPORT_SDIO
+ AthEnableSyncCommandOp(FALSE);
+ PSTagMode = FALSE;
+ wake_up_interruptible(&PsCompleteEvent);
+#endif /* HCI_TRANSPORT_SDIO */
+ if(NULL != HciCmdList) {
+ AthFreeCommandList(&HciCmdList,numCmds);
+ }
+ if(path) {
+ A_FREE(path);
+ }
+ if(config_path) {
+ A_FREE(config_path);
+ }
+ return status;
+}
+#ifndef HCI_TRANSPORT_SDIO
+/*
+ * This API is used to send the HCI command to controller and return
+ * with a HCI Command Complete event.
+ * For HCI SDIO transport, this will be internally defined.
+ */
+A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
+ A_UINT8 *pHCICommand,
+ int CmdLength,
+ A_UINT8 **ppEventBuffer,
+ A_UINT8 **ppBufferToFree)
+{
+ if(CmdLength == 0) {
+ return A_ERROR;
+ }
+ Hci_log("COM Write -->",pHCICommand,CmdLength);
+ PSAcked = FALSE;
+ if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
+ /* If the controller is not available, return Error */
+ return A_ERROR;
+ }
+ //add_timer(&psCmdTimer);
+ wait_event_interruptible(HciEvent,(PSAcked == TRUE));
+ if(NULL != HciEventpacket) {
+ *ppEventBuffer = HciEventpacket;
+ *ppBufferToFree = HciEventpacket;
+ } else {
+ /* Did not get an event from controller. return error */
+ *ppBufferToFree = NULL;
+ return A_ERROR;
+ }
+
+ return A_OK;
+}
+#endif /* HCI_TRANSPORT_SDIO */
+
+A_STATUS ReadPSEvent(A_UCHAR* Data){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
+
+ if(Data[4] == 0xFC && Data[5] == 0x00)
+ {
+ switch(Data[3]){
+ case 0x0B:
+ return A_OK;
+ break;
+ case 0x0C:
+ /* Change Baudrate */
+ return A_OK;
+ break;
+ case 0x04:
+ return A_OK;
+ break;
+ case 0x1E:
+ Rom_Version = Data[9];
+ Rom_Version = ((Rom_Version << 8) |Data[8]);
+ Rom_Version = ((Rom_Version << 8) |Data[7]);
+ Rom_Version = ((Rom_Version << 8) |Data[6]);
+
+ Build_Version = Data[13];
+ Build_Version = ((Build_Version << 8) |Data[12]);
+ Build_Version = ((Build_Version << 8) |Data[11]);
+ Build_Version = ((Build_Version << 8) |Data[10]);
+ return A_OK;
+ break;
+
+
+ }
+ }
+
+ return A_ERROR;
+}
+int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
+{
+ unsigned char bdbyte[3];
+ unsigned char *str_byte = str_bdaddr;
+ int i,j;
+ unsigned char colon_present = 0;
+
+ if(NULL != strstr(str_bdaddr,":")) {
+ colon_present = 1;
+ }
+
+
+ bdbyte[2] = '\0';
+
+ for( i = 0,j = 5; i < 6; i++, j--) {
+ bdbyte[0] = str_byte[0];
+ bdbyte[1] = str_byte[1];
+ bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
+ if(colon_present == 1) {
+ str_byte+=3;
+ } else {
+ str_byte+=2;
+ }
+ }
+ return 0;
+}
+
+A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type)
+{
+ A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ A_UINT8 *event;
+ A_UINT8 *bufferToFree = NULL;
+ A_STATUS result = A_ERROR;
+ int inc,outc;
+
+ if (type == BDADDR_TYPE_STRING)
+ str2ba(bdaddr,&bdaddr_cmd[7]);
+ else {
+ /* Bdaddr has to be sent as LAP first */
+ for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
+ bdaddr_cmd[outc] = bdaddr[inc];
+ }
+
+ if(A_OK == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
+ sizeof(bdaddr_cmd),
+ &event,&bufferToFree)) {
+
+ if(event[4] == 0xFC && event[5] == 0x00){
+ if(event[3] == 0x0B){
+ result = A_OK;
+ }
+ }
+
+ }
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ return result;
+
+}
+A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig)
+{
+ A_UINT8 hciCommand[] = {0x1E,0xfc,0x00};
+ A_UINT8 *event;
+ A_UINT8 *bufferToFree = NULL;
+ A_STATUS result = A_ERROR;
+ if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
+ result = ReadPSEvent(event);
+
+ }
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ return result;
+}
+A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code)
+{
+ A_UINT8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
+ A_UINT8 *event;
+ A_UINT8 *bufferToFree = NULL;
+ A_UINT32 reg;
+ A_STATUS result = A_ERROR;
+ *code = 0;
+ hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF);
+ hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF);
+ hciCommand[5] = (A_UINT8)((FPGA_REGISTER >> 16) & 0xFF);
+ hciCommand[6] = (A_UINT8)((FPGA_REGISTER >> 24) & 0xFF);
+ if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
+
+ if(event[4] == 0xFC && event[5] == 0x00){
+ switch(event[3]){
+ case 0x05:
+ reg = event[9];
+ reg = ((reg << 8) |event[8]);
+ reg = ((reg << 8) |event[7]);
+ reg = ((reg << 8) |event[6]);
+ *code = reg;
+ result = A_OK;
+
+ break;
+ case 0x06:
+ //Sleep(500);
+ break;
+ }
+ }
+
+ }
+ if(bufferToFree != NULL) {
+ A_FREE(bufferToFree);
+ }
+ return result;
+}
+
+
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
new file mode 100644
index 000000000000..4358834f6d71
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file defines the symbols exported by Atheros PS and patch download module.
+ * define the constant HCI_TRANSPORT_SDIO if the module is being used for HCI SDIO transport.
+ * defined.
+ *
+ *
+ * ar3kcpsconfig.h
+ *
+ *
+ *
+ * The software source and binaries included in this development package are
+ * licensed, not sold. You, or your company, received the package under one
+ * or more license agreements. The rights granted to you are specifically
+ * listed in these license agreement(s). All other rights remain with Atheros
+ * Communications, Inc., its subsidiaries, or the respective owner including
+ * those listed on the included copyright notices.. Distribution of any
+ * portion of this package must be in strict compliance with the license
+ * agreement(s) terms.
+ *
+ *
+ *
+ */
+
+
+
+#ifndef __AR3KPSCONFIG_H
+#define __AR3KPSCONFIG_H
+
+/*
+ * Define the flag HCI_TRANSPORT_SDIO and undefine HCI_TRANSPORT_UART if the transport being used is SDIO.
+ */
+#undef HCI_TRANSPORT_UART
+
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/timer.h>
+
+
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+#include <linux/firmware.h>
+#include <linux/wait.h>
+
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "ar3kpsparser.h"
+
+#define FPGA_REGISTER 0x4FFC
+#define BDADDR_TYPE_STRING 0
+#define BDADDR_TYPE_HEX 1
+#define CONFIG_PATH "ar3k"
+
+#define PS_ASIC_FILE "PS_ASIC.pst"
+#define PS_FPGA_FILE "PS_FPGA.pst"
+
+#define PATCH_FILE "RamPatch.txt"
+#define BDADDR_FILE "ar3kbdaddr.pst"
+
+#define ROM_VER_AR3001_3_1_0 30000
+#define ROM_VER_AR3001_3_1_1 30101
+
+
+#ifndef HCI_TRANSPORT_SDIO
+#define AR3K_CONFIG_INFO struct hci_dev
+extern wait_queue_head_t HciEvent;
+extern wait_queue_t Eventwait;
+extern A_UCHAR *HciEventpacket;
+#endif /* #ifndef HCI_TRANSPORT_SDIO */
+
+A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev);
+A_STATUS ReadPSEvent(A_UCHAR* Data);
+#endif /* __AR3KPSCONFIG_H */
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
new file mode 100644
index 000000000000..8dce0542282b
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file implements the Atheros PS and patch parser.
+ * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
+ *
+ *
+ *
+ * ar3kpsparser.c
+ *
+ *
+ *
+ * The software source and binaries included in this development package are
+ * licensed, not sold. You, or your company, received the package under one
+ * or more license agreements. The rights granted to you are specifically
+ * listed in these license agreement(s). All other rights remain with Atheros
+ * Communications, Inc., its subsidiaries, or the respective owner including
+ * those listed on the included copyright notices.. Distribution of any
+ * portion of this package must be in strict compliance with the license
+ * agreement(s) terms.
+ *
+ *
+ *
+ */
+
+
+#include "ar3kpsparser.h"
+
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+
+#define BD_ADDR_SIZE 6
+#define WRITE_PATCH 8
+#define ENABLE_PATCH 11
+#define PS_RESET 2
+#define PS_WRITE 1
+#define PS_VERIFY_CRC 9
+#define CHANGE_BDADDR 15
+
+#define HCI_COMMAND_HEADER 7
+
+#define HCI_EVENT_SIZE 7
+
+#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5
+
+#define PS_RAM_SIZE 2048
+
+#define RAM_PS_REGION (1<<0)
+#define RAM_PATCH_REGION (1<<1)
+#define RAMPS_MAX_PS_DATA_PER_TAG 20000
+#define MAX_RADIO_CFG_TABLE_SIZE 244
+#define RAMPS_MAX_PS_TAGS_PER_FILE 50
+
+#define PS_MAX_LEN 500
+#define LINE_SIZE_MAX (PS_MAX_LEN *2)
+
+/* Constant values used by parser */
+#define BYTES_OF_PS_DATA_PER_LINE 16
+#define RAMPS_MAX_PS_DATA_PER_TAG 20000
+
+
+/* Number pf PS/Patch entries in an HCI packet */
+#define MAX_BYTE_LENGTH 244
+
+#define SKIP_BLANKS(str) while (*str == ' ') str++
+
+enum MinBootFileFormatE
+{
+ MB_FILEFORMAT_RADIOTBL,
+ MB_FILEFORMAT_PATCH,
+ MB_FILEFORMAT_COEXCONFIG
+};
+
+enum RamPsSection
+{
+ RAM_PS_SECTION,
+ RAM_PATCH_SECTION,
+ RAM_DYN_MEM_SECTION
+};
+
+enum eType {
+ eHex,
+ edecimal
+};
+
+
+typedef struct tPsTagEntry
+{
+ A_UINT32 TagId;
+ A_UINT32 TagLen;
+ A_UINT8 *TagData;
+} tPsTagEntry, *tpPsTagEntry;
+
+typedef struct tRamPatch
+{
+ A_UINT16 Len;
+ A_UINT8 * Data;
+} tRamPatch, *ptRamPatch;
+
+
+
+typedef struct ST_PS_DATA_FORMAT {
+ enum eType eDataType;
+ A_BOOL bIsArray;
+}ST_PS_DATA_FORMAT;
+
+typedef struct ST_READ_STATUS {
+ unsigned uTagID;
+ unsigned uSection;
+ unsigned uLineCount;
+ unsigned uCharCount;
+ unsigned uByteCount;
+}ST_READ_STATUS;
+
+
+/* Stores the number of PS Tags */
+static A_UINT32 Tag_Count = 0;
+
+/* Stores the number of patch commands */
+static A_UINT32 Patch_Count = 0;
+static A_UINT32 Total_tag_lenght = 0;
+A_BOOL BDADDR = FALSE;
+A_UINT32 StartTagId;
+
+tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
+tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY];
+
+
+A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat);
+char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos);
+char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos);
+static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index);
+
+/* Function to reads the next character from the input buffer */
+char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos)
+{
+ char Ch;
+ if(buffer == NULL || *pos >=len )
+ {
+ return '\0';
+ } else {
+ Ch = buffer[*pos];
+ (*pos)++;
+ return Ch;
+ }
+}
+/* PS parser helper function */
+unsigned int uGetInputDataFormat(char* pCharLine, ST_PS_DATA_FORMAT *pstFormat)
+{
+ if(pCharLine[0] != '[') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ return 0;
+ }
+ switch(pCharLine[1]) {
+ case 'H':
+ case 'h':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
+ return 1;
+ }
+ }
+ if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = false;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A
+ return 1;
+ }
+ }
+ else if(pCharLine[3] == ']') { //[H:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[H:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n"));
+ return 1;
+ }
+ break;
+
+ case 'A':
+ case 'a':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H
+ return 1;
+ }
+ }
+ else if(pCharLine[3]== ']') { //[A:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[A:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n"));
+ return 1;
+ }
+ break;
+
+ case 'S':
+ case 's':
+ if(pCharLine[2]==':') {
+ if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) {
+ if(pCharLine[4] == ']') {
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 5;
+ return 0;
+ }
+ else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H
+ return 1;
+ }
+ }
+ else if(pCharLine[3]== ']') { //[A:]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 4;
+ return 0;
+ }
+ else { //[A:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n"));
+ return 1;
+ }
+ }
+ else if(pCharLine[2]==']') { //[H]
+ pstFormat->eDataType = eHex;
+ pstFormat->bIsArray = true;
+ pCharLine += 3;
+ return 0;
+ }
+ else { //[H
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n"));
+ return 1;
+ }
+ break;
+
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n"));
+ return 1;
+ }
+}
+
+unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataFormat)
+{
+ char *pTokenPtr = pCharLine;
+
+ if(pTokenPtr[0] == '[') {
+ while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') {
+ pTokenPtr++;
+ }
+ if(pTokenPtr[0] == '\0') {
+ return (0x0FFF);
+ }
+ pTokenPtr++;
+
+
+ }
+ if(stPS_DataFormat.eDataType == eHex) {
+ if(stPS_DataFormat.bIsArray == true) {
+ //Not implemented
+ return (0x0FFF);
+ }
+ else {
+ return (A_STRTOL(pTokenPtr, NULL, 16));
+ }
+ }
+ else {
+ //Not implemented
+ return (0x0FFF);
+ }
+}
+A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat)
+{
+ char *Buffer;
+ char *pCharLine;
+ A_UINT8 TagCount;
+ A_UINT16 ByteCount;
+ A_UINT8 ParseSection=RAM_PS_SECTION;
+ A_UINT32 pos;
+
+
+
+ int uReadCount;
+ ST_PS_DATA_FORMAT stPS_DataFormat;
+ ST_READ_STATUS stReadStatus = {0, 0, 0,0};
+ pos = 0;
+ Buffer = NULL;
+
+ if (srcbuffer == NULL || srclen == 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n"));
+ return A_ERROR;
+ }
+ TagCount = 0;
+ ByteCount = 0;
+ Buffer = A_MALLOC(LINE_SIZE_MAX + 1);
+ if(NULL == Buffer) {
+ return A_ERROR;
+ }
+ if (FileFormat == MB_FILEFORMAT_PATCH)
+ {
+ int LineRead = 0;
+ while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL)
+ {
+
+ SKIP_BLANKS(pCharLine);
+
+ // Comment line or empty line
+ if ((pCharLine[0] == '/') && (pCharLine[1] == '/'))
+ {
+ continue;
+ }
+
+ if ((pCharLine[0] == '#')) {
+ if (stReadStatus.uSection != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ else {
+ stReadStatus.uSection = 1;
+ continue;
+ }
+ }
+ if ((pCharLine[0] == '/') && (pCharLine[1] == '*'))
+ {
+ pCharLine+=2;
+ SKIP_BLANKS(pCharLine);
+
+ if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2))
+ ParseSection=RAM_PATCH_SECTION;
+
+ if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2))
+ ParseSection=RAM_DYN_MEM_SECTION;
+
+ if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2))
+ ParseSection=RAM_PS_SECTION;
+
+ LineRead = 0;
+ stReadStatus.uSection = 0;
+
+ continue;
+ }
+
+ switch(ParseSection)
+ {
+ case RAM_PS_SECTION:
+ {
+ if (stReadStatus.uSection == 1) //TagID
+ {
+ SKIP_BLANKS(pCharLine);
+ if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId));
+
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId);
+ if (TagCount == 0)
+ {
+ StartTagId = PsTagEntry[TagCount].TagId;
+ }
+ stReadStatus.uSection = 2;
+ }
+ else if (stReadStatus.uSection == 2) //TagLength
+ {
+
+ if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat);
+
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount));
+ if (ByteCount > LINE_SIZE_MAX/2)
+ {
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ PsTagEntry[TagCount].TagLen = ByteCount;
+ PsTagEntry[TagCount].TagData = (A_UINT8*)A_MALLOC(ByteCount);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount));
+ stReadStatus.uSection = 3;
+ stReadStatus.uLineCount = 0;
+ }
+ else if( stReadStatus.uSection == 3) { //Data
+
+ if(stReadStatus.uLineCount == 0) {
+ if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ //pCharLine +=5;
+ }
+ SKIP_BLANKS(pCharLine);
+ stReadStatus.uCharCount = 0;
+ if(pCharLine[stReadStatus.uCharCount] == '[') {
+ while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) {
+ stReadStatus.uCharCount++;
+ }
+ if(pCharLine[stReadStatus.uCharCount] == ']' ) {
+ stReadStatus.uCharCount++;
+ } else {
+ stReadStatus.uCharCount = 0;
+ }
+ }
+ uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount;
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" "));
+ if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) {
+ while(uReadCount > 0) {
+ PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] =
+ (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4)
+ | (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1]));
+
+ PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
+ (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4)
+ | (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4]));
+
+ stReadStatus.uCharCount += 6; // read two bytes, plus a space;
+ stReadStatus.uByteCount += 2;
+ uReadCount -= 2;
+ }
+ if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) {
+ ByteCount -= BYTES_OF_PS_DATA_PER_LINE;
+ }
+ else {
+ ByteCount = 0;
+ }
+ }
+ else {
+ //to be implemented
+ }
+
+ stReadStatus.uLineCount++;
+
+ if(ByteCount == 0) {
+ stReadStatus.uSection = 0;
+ stReadStatus.uCharCount = 0;
+ stReadStatus.uLineCount = 0;
+ stReadStatus.uByteCount = 0;
+ }
+ else {
+ stReadStatus.uCharCount = 0;
+ }
+
+ if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ //Sleep (3000);
+ //exit(1);
+ }
+
+ }
+ }
+
+ break;
+ default:
+ {
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+ break;
+ }
+ LineRead++;
+ }
+ Tag_Count = TagCount;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count));
+ }
+
+
+ if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE)
+ {
+
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_ERROR;
+ }
+
+ if(Buffer != NULL) {
+ A_FREE(Buffer);
+ }
+ return A_OK;
+
+}
+
+
+
+/********************/
+
+
+A_STATUS GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer)
+{
+ unsigned char ch;
+
+ ch = AthReadChar(srcbuffer,len,pos);
+ if(ch != '\0' && isxdigit(ch)) {
+ buffer[0] = ch;
+ } else
+ {
+ return A_ERROR;
+ }
+ ch = AthReadChar(srcbuffer,len,pos);
+ if(ch != '\0' && isxdigit(ch)) {
+ buffer[1] = ch;
+ } else
+ {
+ return A_ERROR;
+ }
+ return A_OK;
+}
+
+A_STATUS AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen)
+{
+
+ char Byte[3];
+ char Line[MAX_BYTE_LENGTH + 1];
+ int ByteCount,ByteCount_Org;
+ int count;
+ int i,j,k;
+ int data;
+ A_UINT32 filepos;
+ Byte[2] = '\0';
+ j = 0;
+ filepos = 0;
+ Patch_Count = 0;
+
+ while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
+ if(strlen(Line) <= 1 || !isxdigit(Line[0])) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ ByteCount = A_STRTOL(Line, NULL, 16);
+ ByteCount_Org = ByteCount;
+
+ while(ByteCount > MAX_BYTE_LENGTH){
+
+ /* Handle case when the number of patch buffer is more than the 20K */
+ if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
+ for(i = 0; i < Patch_Count; i++) {
+ A_FREE(RamPatch[i].Data);
+ }
+ return A_ERROR;
+ }
+ RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
+ RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(MAX_BYTE_LENGTH);
+ Patch_Count ++;
+
+
+ ByteCount= ByteCount - MAX_BYTE_LENGTH;
+ }
+
+ RamPatch[Patch_Count].Len= (ByteCount & 0xFF);
+ if(ByteCount != 0) {
+ RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(ByteCount);
+ Patch_Count ++;
+ }
+ count = 0;
+ while(ByteCount_Org > MAX_BYTE_LENGTH){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
+ for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) {
+ if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
+ return A_ERROR;
+ }
+ data = A_STRTOUL(&Byte[0], NULL, 16);
+ RamPatch[j].Data[k] = (data & 0xFF);
+
+
+ }
+ j++;
+ ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH;
+ }
+ if(j == 0){
+ j++;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j));
+ for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) {
+ if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) {
+ return A_ERROR;
+ }
+ data = A_STRTOUL(Byte, NULL, 16);
+ RamPatch[j].Data[k] = (data & 0xFF);
+
+
+ }
+ return A_OK;
+}
+
+
+/********************/
+A_STATUS AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen)
+{
+ A_STATUS status;
+ int i;
+ A_BOOL BDADDR_Present = A_ERROR;
+
+ Tag_Count = 0;
+
+ Total_tag_lenght = 0;
+ BDADDR = FALSE;
+
+
+ status = A_ERROR;
+
+ if(NULL != srcbuffer && srclen != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n"));
+
+ status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH);
+ }
+
+
+
+ if(Tag_Count == 0){
+ Total_tag_lenght = 10;
+
+ }
+ else{
+ for(i=0; i<Tag_Count; i++){
+ if(PsTagEntry[i].TagId == 1){
+ BDADDR_Present = A_OK;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n"));
+
+ }
+ if(PsTagEntry[i].TagLen % 2 == 1){
+ Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1;
+ }
+ else{
+ Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen;
+ }
+
+ }
+ }
+
+ if(Tag_Count > 0 && !BDADDR_Present){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n"));
+ Total_tag_lenght=Total_tag_lenght + 10;
+ }
+ Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght));
+
+
+ return status;
+}
+char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos)
+{
+
+ int count;
+ static short flag;
+ char CharRead;
+ count = 0;
+ flag = A_ERROR;
+
+ do
+ {
+ CharRead = AthReadChar(srcbuffer,len,pos);
+ if( CharRead == '\0' ) {
+ buffer[count+1] = '\0';
+ if(count == 0) {
+ return NULL;
+ }
+ else {
+ return buffer;
+ }
+ }
+
+ if(CharRead == 13) {
+ } else if(CharRead == 10) {
+ buffer[count] ='\0';
+ flag = A_ERROR;
+ return buffer;
+ }else {
+ buffer[count++] = CharRead;
+ }
+
+ }
+ while(count < maxlen-1 && CharRead != '\0');
+ buffer[count] = '\0';
+
+ return buffer;
+}
+
+static void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int index){
+
+ HCI_PS_Command[0]= 0x0B;
+ HCI_PS_Command[1]= 0xFC;
+ HCI_PS_Command[2]= length + 4;
+ HCI_PS_Command[3]= opcode;
+ HCI_PS_Command[4]= (index & 0xFF);
+ HCI_PS_Command[5]= ((index>>8) & 0xFF);
+ HCI_PS_Command[6]= length;
+}
+
+/////////////////////////
+//
+int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets)
+{
+
+ A_UINT8 count;
+ A_UINT32 NumcmdEntry = 0;
+
+ A_UINT32 Crc = 0;
+ *numPackets = 0;
+
+
+ if(Patch_Count > 0)
+ Crc |= RAM_PATCH_REGION;
+ if(Tag_Count > 0)
+ Crc |= RAM_PS_REGION;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d Tag Count %d \n",Crc,Patch_Count,Tag_Count));
+
+ if(Patch_Count || Tag_Count ){
+ NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet + Patch List + PS List*/
+ if(Patch_Count > 0) {
+ NumcmdEntry++; /* Patch Enable Command */
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(A_UINT32)sizeof(PSCmdPacket) * NumcmdEntry));
+ (*HciPacketList) = A_MALLOC(sizeof(PSCmdPacket) * NumcmdEntry);
+ if(NULL == *HciPacketList) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n"));
+ }
+ AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets);
+ if(Patch_Count > 0){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n"));
+ AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n"));
+ AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** %d[0x%x] \r\n",PS_RAM_SIZE,PS_RAM_SIZE));
+ AthPSCreateHCICommand(PS_RESET,PS_RAM_SIZE,*HciPacketList,numPackets);
+ if(Tag_Count > 0){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n"));
+ AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets);
+ }
+ }
+ if(!BDADDR){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n"));
+
+ }
+ for(count = 0; count < Patch_Count; count++) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
+ A_FREE(RamPatch[Patch_Count].Data);
+ }
+
+ for(count = 0; count < Tag_Count; count++) {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
+ A_FREE(PsTagEntry[count].TagData);
+ }
+
+/*
+ * SDIO Transport uses synchronous mode of data transfer
+ * So, AthPSOperations() call returns only after receiving the
+ * command complete event.
+ */
+ return *numPackets;
+}
+
+
+////////////////////////
+
+/////////////
+static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index)
+{
+ A_UCHAR *HCI_PS_Command;
+ A_UINT32 Length;
+ int i,j;
+
+ switch(Opcode)
+ {
+ case WRITE_PATCH:
+
+
+ for(i=0;i< Param1;i++){
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER));
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i);
+ for(j=0;j<RamPatch[i].Len;j++){
+ HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j];
+ }
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER;
+ (*index)++;
+
+
+ }
+
+ break;
+
+ case ENABLE_PATCH:
+
+
+ Length = 0;
+ i= 0;
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,i);
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case PS_RESET:
+ Length = 0x06;
+ i=0;
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,i);
+ HCI_PS_Command[7]= 0x00;
+ HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF);
+ HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >> 8) & 0xFF);
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case PS_WRITE:
+ for(i=0;i< Param1;i++){
+ if(PsTagEntry[i].TagId ==1)
+ BDADDR = TRUE;
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+
+ memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId);
+
+ for(j=0;j<PsTagEntry[i].TagLen;j++){
+ HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j];
+ }
+
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ }
+
+ break;
+
+
+ case PS_VERIFY_CRC:
+ Length = 0x0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index));
+
+ HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER);
+ if(HCI_PS_Command == NULL){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n"));
+ return A_ERROR;
+ }
+ memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER);
+ LoadHeader(HCI_PS_Command,Opcode,Length,Param1);
+
+ PSPatchPacket[*index].Hcipacket = HCI_PS_Command;
+ PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER;
+ (*index)++;
+
+ break;
+
+ case CHANGE_BDADDR:
+ break;
+ }
+ return A_OK;
+}
+A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets)
+{
+ int i;
+ if(*HciPacketList == NULL) {
+ return A_ERROR;
+ }
+ for(i = 0; i < numPackets;i++) {
+ A_FREE((*HciPacketList)[i].Hcipacket);
+ }
+ A_FREE(*HciPacketList);
+ return A_OK;
+}
diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
new file mode 100644
index 000000000000..007b0eb950d2
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
@@ -0,0 +1,127 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//
+// This file is the include file for Atheros PS and patch parser.
+// It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands.
+//
+
+#ifndef __AR3KPSPARSER_H
+#define __AR3KPSPARSER_H
+
+
+
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include "athdefs.h"
+#ifdef HCI_TRANSPORT_SDIO
+#include "a_config.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#define ATH_MODULE_NAME misc
+#include "a_debug.h"
+#include "common_drv.h"
+#include "hci_transport_api.h"
+#include "ar3kconfig.h"
+#else
+#ifndef A_PRINTF
+#define A_PRINTF(args...) printk(KERN_ALERT args)
+#endif /* A_PRINTF */
+#include "debug_linux.h"
+
+/* Helper data type declaration */
+
+#ifndef A_UINT32
+#define A_UCHAR unsigned char
+#define A_UINT32 unsigned long
+#define A_UINT16 unsigned short
+#define A_UINT8 unsigned char
+#define A_BOOL unsigned char
+#endif /* A_UINT32 */
+
+#define ATH_DEBUG_ERR (1 << 0)
+#define ATH_DEBUG_WARN (1 << 1)
+#define ATH_DEBUG_INFO (1 << 2)
+
+
+
+#define FALSE 0
+#define TRUE 1
+
+#ifndef A_MALLOC
+#define A_MALLOC(size) kmalloc((size),GFP_KERNEL)
+#endif /* A_MALLOC */
+
+
+#ifndef A_FREE
+#define A_FREE(addr) kfree((addr))
+#endif /* A_MALLOC */
+#endif /* HCI_TRANSPORT_UART */
+
+/* String manipulation APIs */
+#ifndef A_STRTOUL
+#define A_STRTOUL simple_strtoul
+#endif /* A_STRTOL */
+
+#ifndef A_STRTOL
+#define A_STRTOL simple_strtol
+#endif /* A_STRTOL */
+
+
+/* The maximum number of bytes possible in a patch entry */
+#define MAX_PATCH_SIZE 20000
+
+/* Maximum HCI packets that will be formed from the Patch file */
+#define MAX_NUM_PATCH_ENTRY (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1
+
+
+
+
+
+
+
+typedef struct PSCmdPacket
+{
+ A_UCHAR *Hcipacket;
+ int packetLen;
+} PSCmdPacket;
+
+/* Parses a Patch information buffer and store it in global structure */
+A_STATUS AthDoParsePatch(A_UCHAR *, A_UINT32);
+
+/* parses a PS information buffer and stores it in a global structure */
+A_STATUS AthDoParsePS(A_UCHAR *, A_UINT32);
+
+/*
+ * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with
+ * all the PS and patch commands.
+ * The list will have the below mentioned commands in order.
+ * CRC command packet
+ * Download patch command(s)
+ * Enable patch Command
+ * PS Reset Command
+ * PS Tag Command(s)
+ *
+ */
+int AthCreateCommandList(PSCmdPacket **, A_UINT32 *);
+
+/* Cleanup the dynamically allicated HCI command list */
+A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets);
+#endif /* __AR3KPSPARSER_H */
diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c
new file mode 100644
index 000000000000..6754fde467de
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/common_drv.c
@@ -0,0 +1,1027 @@
+//------------------------------------------------------------------------------
+// <copyright file="common_drv.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+
+#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "AR6002/hw2.0/hw/apb_map.h"
+#include "AR6002/hw2.0/hw/si_reg.h"
+#include "AR6002/hw2.0/hw/gpio_reg.h"
+#include "AR6002/hw2.0/hw/rtc_reg.h"
+#include "AR6002/hw2.0/hw/vmc_reg.h"
+#include "AR6002/hw2.0/hw/mbox_reg.h"
+
+#include "a_osapi.h"
+#include "targaddrs.h"
+#include "hif.h"
+#include "htc_api.h"
+#include "wmi.h"
+#include "bmi.h"
+#include "bmi_msg.h"
+#include "common_drv.h"
+#define ATH_MODULE_NAME misc
+#include "a_debug.h"
+#include "ar6000_diag.h"
+
+static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
+static A_MUTEX_T g_ModuleListLock;
+static A_BOOL g_ModuleDebugInit = FALSE;
+
+#ifdef ATH_DEBUG_MODULE
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
+ "misc",
+ "Common and misc APIs",
+ ATH_DEBUG_MASK_DEFAULTS,
+ 0,
+ NULL);
+
+#endif
+
+#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
+ ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
+ (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)))
+
+
+#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
+#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
+#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
+#define CPU_DBG_SEL_ADDRESS 0x00000483
+#define CPU_DBG_ADDRESS 0x00000484
+
+static A_UINT8 custDataAR6002[AR6002_CUST_DATA_SIZE];
+static A_UINT8 custDataAR6003[AR6003_CUST_DATA_SIZE];
+
+/* Compile the 4BYTE version of the window register setup routine,
+ * This mitigates host interconnect issues with non-4byte aligned bus requests, some
+ * interconnects use bus adapters that impose strict limitations.
+ * Since diag window access is not intended for performance critical operations, the 4byte mode should
+ * be satisfactory even though it generates 4X the bus activity. */
+
+#ifdef USE_4BYTE_REGISTER_ACCESS
+
+ /* set the window address register (using 4-byte register access ). */
+A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
+{
+ A_STATUS status;
+ A_UINT8 addrValue[4];
+ A_INT32 i;
+
+ /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
+ * last to initiate the access cycle */
+
+ for (i = 1; i <= 3; i++) {
+ /* fill the buffer with the address byte value we want to hit 4 times*/
+ addrValue[0] = ((A_UINT8 *)&Address)[i];
+ addrValue[1] = addrValue[0];
+ addrValue[2] = addrValue[0];
+ addrValue[3] = addrValue[0];
+
+ /* hit each byte of the register address with a 4-byte write operation to the same address,
+ * this is a harmless operation */
+ status = HIFReadWrite(hifDevice,
+ RegisterAddr+i,
+ addrValue,
+ 4,
+ HIF_WR_SYNC_BYTE_FIX,
+ NULL);
+ if (status != A_OK) {
+ break;
+ }
+ }
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
+ Address, RegisterAddr));
+ return status;
+ }
+
+ /* write the address register again, this time write the whole 4-byte value.
+ * The effect here is that the LSB write causes the cycle to start, the extra
+ * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
+ status = HIFReadWrite(hifDevice,
+ RegisterAddr,
+ (A_UCHAR *)(&Address),
+ 4,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
+ Address, RegisterAddr));
+ return status;
+ }
+
+ return A_OK;
+
+
+
+}
+
+
+#else
+
+ /* set the window address register */
+A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
+{
+ A_STATUS status;
+
+ /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
+ * last to initiate the access cycle */
+ status = HIFReadWrite(hifDevice,
+ RegisterAddr+1, /* write upper 3 bytes */
+ ((A_UCHAR *)(&Address))+1,
+ sizeof(A_UINT32)-1,
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
+ RegisterAddr, Address));
+ return status;
+ }
+
+ /* write the LSB of the register, this initiates the operation */
+ status = HIFReadWrite(hifDevice,
+ RegisterAddr,
+ (A_UCHAR *)(&Address),
+ sizeof(A_UINT8),
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
+ RegisterAddr, Address));
+ return status;
+ }
+
+ return A_OK;
+}
+
+#endif
+
+/*
+ * Read from the AR6000 through its diagnostic window.
+ * No cooperation from the Target is required for this.
+ */
+A_STATUS
+ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
+{
+ A_STATUS status;
+
+ /* set window register to start read cycle */
+ status = ar6000_SetAddressWindowRegister(hifDevice,
+ WINDOW_READ_ADDR_ADDRESS,
+ *address);
+
+ if (status != A_OK) {
+ return status;
+ }
+
+ /* read the data */
+ status = HIFReadWrite(hifDevice,
+ WINDOW_DATA_ADDRESS,
+ (A_UCHAR *)data,
+ sizeof(A_UINT32),
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
+ return status;
+ }
+
+ return status;
+}
+
+
+/*
+ * Write to the AR6000 through its diagnostic window.
+ * No cooperation from the Target is required for this.
+ */
+A_STATUS
+ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
+{
+ A_STATUS status;
+
+ /* set write data */
+ status = HIFReadWrite(hifDevice,
+ WINDOW_DATA_ADDRESS,
+ (A_UCHAR *)data,
+ sizeof(A_UINT32),
+ HIF_WR_SYNC_BYTE_INC,
+ NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
+ return status;
+ }
+
+ /* set window register, which starts the write cycle */
+ return ar6000_SetAddressWindowRegister(hifDevice,
+ WINDOW_WRITE_ADDR_ADDRESS,
+ *address);
+ }
+
+A_STATUS
+ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
+ A_UCHAR *data, A_UINT32 length)
+{
+ A_UINT32 count;
+ A_STATUS status = A_OK;
+
+ for (count = 0; count < length; count += 4, address += 4) {
+ if ((status = ar6000_ReadRegDiag(hifDevice, &address,
+ (A_UINT32 *)&data[count])) != A_OK)
+ {
+ break;
+ }
+ }
+
+ return status;
+}
+
+A_STATUS
+ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
+ A_UCHAR *data, A_UINT32 length)
+{
+ A_UINT32 count;
+ A_STATUS status = A_OK;
+
+ for (count = 0; count < length; count += 4, address += 4) {
+ if ((status = ar6000_WriteRegDiag(hifDevice, &address,
+ (A_UINT32 *)&data[count])) != A_OK)
+ {
+ break;
+ }
+ }
+
+ return status;
+}
+
+A_STATUS
+ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval)
+{
+ A_STATUS status;
+ A_UCHAR vals[4];
+ A_UCHAR register_selection[4];
+
+ register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
+ status = HIFReadWrite(hifDevice,
+ CPU_DBG_SEL_ADDRESS,
+ register_selection,
+ 4,
+ HIF_WR_SYNC_BYTE_FIX,
+ NULL);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
+ return status;
+ }
+
+ status = HIFReadWrite(hifDevice,
+ CPU_DBG_ADDRESS,
+ (A_UCHAR *)vals,
+ sizeof(vals),
+ HIF_RD_SYNC_BYTE_INC,
+ NULL);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
+ return status;
+ }
+
+ *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;
+
+ return status;
+}
+
+void
+ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs)
+{
+ int i;
+ A_UINT32 val;
+
+ for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
+ val=0xffffffff;
+ (void)ar6k_ReadTargetRegister(hifDevice, i, &val);
+ targregs[i] = val;
+ }
+}
+
+#if 0
+static A_STATUS
+_do_write_diag(HIF_DEVICE *hifDevice, A_UINT32 addr, A_UINT32 value)
+{
+ A_STATUS status;
+
+ status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
+ if (status != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
+ }
+
+ return status;
+}
+#endif
+
+
+/*
+ * Delay up to wait_msecs millisecs to allow Target to enter BMI phase,
+ * which is a good sign that it's alive and well. This is used after
+ * explicitly forcing the Target to reset.
+ *
+ * The wait_msecs time should be sufficiently long to cover any reasonable
+ * boot-time delay. For instance, AR6001 firmware allow one second for a
+ * low frequency crystal to settle before it calibrates the refclk frequency.
+ *
+ * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE.
+ */
+#if 0
+static A_STATUS
+_delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, A_UINT32 TargetType)
+{
+ A_INT32 actual_wait;
+ A_INT32 i;
+ A_UINT32 address;
+
+ actual_wait = 0;
+
+ /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */
+ if (TargetType == TARGET_TYPE_AR6002) {
+ address = AR6002_LOCAL_COUNT_ADDRESS;
+ } else if (TargetType == TARGET_TYPE_AR6003) {
+ address = AR6003_LOCAL_COUNT_ADDRESS;
+ } else {
+ A_ASSERT(0);
+ }
+ address += 0x10;
+ for (i=0; actual_wait < wait_msecs; i++) {
+ A_UINT32 data;
+
+ A_MDELAY(100);
+ actual_wait += 100;
+
+ data = 0;
+ if (ar6000_ReadRegDiag(hifDevice, &address, &data) != A_OK) {
+ return A_ERROR;
+ }
+
+ if (data != 0) {
+ /* No need to wait longer -- we have a BMI credit */
+ return A_OK;
+ }
+ }
+ return A_ERROR; /* timed out */
+}
+#endif
+
+#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
+#define AR6002_RESET_CONTROL_ADDRESS 0x00004000
+#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
+/* reset device */
+A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset)
+{
+ A_STATUS status = A_OK;
+ A_UINT32 address;
+ A_UINT32 data;
+
+ do {
+// Workaround BEGIN
+ // address = RESET_CONTROL_ADDRESS;
+
+ if (coldReset) {
+ data = RESET_CONTROL_COLD_RST_MASK;
+ }
+ else {
+ data = RESET_CONTROL_MBOX_RST_MASK;
+ }
+
+ /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
+ if (TargetType == TARGET_TYPE_AR6002) {
+ address = AR6002_RESET_CONTROL_ADDRESS;
+ } else if (TargetType == TARGET_TYPE_AR6003) {
+ address = AR6003_RESET_CONTROL_ADDRESS;
+ } else {
+ A_ASSERT(0);
+ }
+
+
+ status = ar6000_WriteRegDiag(hifDevice, &address, &data);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (!waitForCompletion) {
+ break;
+ }
+
+#if 0
+ /* Up to 2 second delay to allow things to settle down */
+ (void)_delay_until_target_alive(hifDevice, 2000, TargetType);
+
+ /*
+ * Read back the RESET CAUSE register to ensure that the cold reset
+ * went through.
+ */
+
+ // address = RESET_CAUSE_ADDRESS;
+ /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
+ if (TargetType == TARGET_TYPE_AR6002) {
+ address = 0x000040C0;
+ } else if (TargetType == TARGET_TYPE_AR6003) {
+ address = 0x000040C0;
+ } else {
+ A_ASSERT(0);
+ }
+
+ data = 0;
+ status = ar6000_ReadRegDiag(hifDevice, &address, &data);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
+ data &= RESET_CAUSE_LAST_MASK;
+ if (data != 2) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
+ }
+#endif
+// Workaroud END
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
+ }
+
+ return A_OK;
+}
+
+/* This should be called in BMI phase after firmware is downloaded */
+void
+ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
+{
+ A_UINT32 eepHeaderAddr;
+ A_UINT8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
+ A_INT32 i;
+
+ if (BMIReadMemory(hifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
+ (A_UCHAR *)&eepHeaderAddr,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
+ return;
+ }
+
+ if (TargetType == TARGET_TYPE_AR6003) {
+ eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */
+
+ for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
+ if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&AR6003CustDataShadow[i])!= A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
+ return ;
+ }
+ eepHeaderAddr +=4;
+ }
+
+ memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
+ }
+
+ if (TargetType == TARGET_TYPE_AR6002) {
+ eepHeaderAddr += 64; /* AR6002 customer data sectioin offset is 64 */
+
+ for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
+ if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&custDataAR6002[i])!= A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
+ return ;
+ }
+ eepHeaderAddr +=4;
+ }
+ }
+
+ return;
+}
+
+/* This is the function to call when need to use the cust data */
+A_UINT8 *
+ar6000_get_cust_data_buffer(A_UINT32 TargetType)
+{
+ if (TargetType == TARGET_TYPE_AR6003)
+ return custDataAR6003;
+
+ if (TargetType == TARGET_TYPE_AR6002)
+ return custDataAR6002;
+
+ return NULL;
+}
+
+#define REG_DUMP_COUNT_AR6001 38 /* WORDs, derived from AR600x_regdump.h */
+#define REG_DUMP_COUNT_AR6002 60
+#define REG_DUMP_COUNT_AR6003 60
+#define REGISTER_DUMP_LEN_MAX 60
+#if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX
+#error "REG_DUMP_COUNT_AR6001 too large"
+#endif
+#if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX
+#error "REG_DUMP_COUNT_AR6002 too large"
+#endif
+#if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX
+#error "REG_DUMP_COUNT_AR6003 too large"
+#endif
+
+
+void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
+{
+ A_UINT32 address;
+ A_UINT32 regDumpArea = 0;
+ A_STATUS status;
+ A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX];
+ A_UINT32 regDumpCount = 0;
+ A_UINT32 i;
+
+ do {
+
+ /* the reg dump pointer is copied to the host interest area */
+ address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
+ address = TARG_VTOP(TargetType, address);
+
+ if (TargetType == TARGET_TYPE_AR6002) {
+ regDumpCount = REG_DUMP_COUNT_AR6002;
+ } else if (TargetType == TARGET_TYPE_AR6003) {
+ regDumpCount = REG_DUMP_COUNT_AR6003;
+ } else {
+ A_ASSERT(0);
+ }
+
+ /* read RAM location through diagnostic window */
+ status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));
+
+ if (regDumpArea == 0) {
+ /* no reg dump */
+ break;
+ }
+
+ regDumpArea = TARG_VTOP(TargetType, regDumpArea);
+
+ /* fetch register dump data */
+ status = ar6000_ReadDataDiag(hifDevice,
+ regDumpArea,
+ (A_UCHAR *)&regDumpValues[0],
+ regDumpCount * (sizeof(A_UINT32)));
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));
+
+ for (i = 0; i < regDumpCount; i++) {
+ //ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i]));
+
+#ifdef UNDER_CE
+ /*
+ * For Every logPrintf() Open the File so that in case of Crashes
+ * We will have until the Last Message Flushed on to the File
+ * So use logPrintf Sparingly..!!
+ */
+ tgtassertPrintf (ATH_DEBUG_TRC," %d: 0x%8.8X \n",i, regDumpValues[i]);
+#endif
+ }
+
+ } while (FALSE);
+
+}
+
+/* set HTC/Mbox operational parameters, this can only be called when the target is in the
+ * BMI phase */
+A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 MboxIsrYieldValue,
+ A_UINT8 HtcControlBuffers)
+{
+ A_STATUS status;
+ A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];
+
+ do {
+ /* get the block sizes */
+ status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+ blocksizes, sizeof(blocksizes));
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
+ break;
+ }
+ /* note: we actually get the block size for mailbox 1, for SDIO the block
+ * size on mailbox 0 is artificially set to 1 */
+ /* must be a power of 2 */
+ A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
+
+ if (HtcControlBuffers != 0) {
+ /* set override for number of control buffers to use */
+ blocksizes[1] |= ((A_UINT32)HtcControlBuffers) << 16;
+ }
+
+ /* set the host interest area for the block size */
+ status = BMIWriteMemory(hifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
+ (A_UCHAR *)&blocksizes[1],
+ 4);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
+ blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));
+
+ if (MboxIsrYieldValue != 0) {
+ /* set the host interest area for the mbox ISR yield limit */
+ status = BMIWriteMemory(hifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
+ (A_UCHAR *)&MboxIsrYieldValue,
+ 4);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
+ break;
+ }
+ }
+
+ } while (FALSE);
+
+ return status;
+}
+
+
+static A_STATUS prepare_ar6002(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
+{
+ A_STATUS status = A_OK;
+
+ /* placeholder */
+
+ return status;
+}
+
+static A_STATUS prepare_ar6003(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
+{
+ A_STATUS status = A_OK;
+
+ /* placeholder */
+
+ return status;
+}
+
+/* this function assumes the caller has already initialized the BMI APIs */
+A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 TargetVersion)
+{
+ if (TargetType == TARGET_TYPE_AR6002) {
+ /* do any preparations for AR6002 devices */
+ return prepare_ar6002(hifDevice,TargetVersion);
+ } else if (TargetType == TARGET_TYPE_AR6003) {
+ return prepare_ar6003(hifDevice,TargetVersion);
+ }
+
+ return A_OK;
+}
+
+#if defined(CONFIG_AR6002_REV1_FORCE_HOST)
+/*
+ * Call this function just before the call to BMIInit
+ * in order to force* AR6002 rev 1.x firmware to detect a Host.
+ * THIS IS FOR USE ONLY WITH AR6002 REV 1.x.
+ * TBDXXX: Remove this function when REV 1.x is desupported.
+ */
+A_STATUS
+ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice)
+{
+ A_INT32 i;
+ struct forceROM_s {
+ A_UINT32 addr;
+ A_UINT32 data;
+ };
+ struct forceROM_s *ForceROM;
+ A_INT32 szForceROM;
+ A_STATUS status = A_OK;
+ A_UINT32 address;
+ A_UINT32 data;
+
+ /* Force AR6002 REV1.x to recognize Host presence.
+ *
+ * Note: Use RAM at 0x52df80..0x52dfa0 with ROM Remap entry 0
+ * so that this workaround functions with AR6002.war1.sh. We
+ * could fold that entire workaround into this one, but it's not
+ * worth the effort at this point. This workaround cannot be
+ * merged into the other workaround because this must be done
+ * before BMI.
+ */
+
+ static struct forceROM_s ForceROM_NEW[] = {
+ {0x52df80, 0x20f31c07},
+ {0x52df84, 0x92374420},
+ {0x52df88, 0x1d120c03},
+ {0x52df8c, 0xff8216f0},
+ {0x52df90, 0xf01d120c},
+ {0x52df94, 0x81004136},
+ {0x52df98, 0xbc9100bd},
+ {0x52df9c, 0x00bba100},
+
+ {0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */
+ {0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380},
+ {0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000},
+ {0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001},
+
+ {0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */
+
+ {0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
+ };
+
+ address = 0x004ed4b0; /* REV1 target software ID is stored here */
+ status = ar6000_ReadRegDiag(hifDevice, &address, &data);
+ if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) {
+ return A_ERROR; /* Not AR6002 REV1 */
+ }
+
+ ForceROM = ForceROM_NEW;
+ szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM);
+
+ ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n"));
+ for (i = 0; i < szForceROM; i++)
+ {
+ if (ar6000_WriteRegDiag(hifDevice,
+ &ForceROM[i].addr,
+ &ForceROM[i].data) != A_OK)
+ {
+ ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n"));
+ return A_ERROR;
+ }
+ }
+
+ A_MDELAY(1000);
+
+ return A_OK;
+}
+
+#endif /* CONFIG_AR6002_REV1_FORCE_HOST */
+
+void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription)
+{
+ A_CHAR stream[60];
+ A_CHAR byteOffsetStr[10];
+ A_UINT32 i;
+ A_UINT16 offset, count, byteOffset;
+
+ A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);
+
+ count = 0;
+ offset = 0;
+ byteOffset = 0;
+ for(i = 0; i < length; i++) {
+ A_SPRINTF(stream + offset, "%2.2X ", buffer[i]);
+ count ++;
+ offset += 3;
+
+ if(count == 16) {
+ count = 0;
+ offset = 0;
+ A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
+ A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
+ A_MEMZERO(stream, 60);
+ byteOffset += 16;
+ }
+ }
+
+ if(offset != 0) {
+ A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
+ A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
+ }
+
+ A_PRINTF("<------------------------------------------------->\n");
+}
+
+void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
+{
+ int i;
+ ATH_DEBUG_MASK_DESCRIPTION *pDesc;
+
+ if (pInfo == NULL) {
+ return;
+ }
+
+ pDesc = pInfo->pMaskDescriptions;
+
+ A_PRINTF("========================================================\n\n");
+ A_PRINTF("Module Debug Info => Name : %s \n", pInfo->ModuleName);
+ A_PRINTF(" => Descr. : %s \n", pInfo->ModuleDescription);
+ A_PRINTF("\n Current mask => 0x%8.8X \n", pInfo->CurrentMask);
+ A_PRINTF("\n Avail. Debug Masks :\n\n");
+
+ for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) {
+ A_PRINTF(" => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description);
+ }
+
+ if (0 == i) {
+ A_PRINTF(" => * none defined * \n");
+ }
+
+ A_PRINTF("\n Standard Debug Masks :\n\n");
+ /* print standard masks */
+ A_PRINTF(" => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR);
+ A_PRINTF(" => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN);
+ A_PRINTF(" => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO);
+ A_PRINTF(" => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC);
+ A_PRINTF("\n========================================================\n");
+
+}
+
+
+static ATH_DEBUG_MODULE_DBG_INFO *FindModule(A_CHAR *module_name)
+{
+ ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
+
+ if (!g_ModuleDebugInit) {
+ return NULL;
+ }
+
+ while (pInfo != NULL) {
+ /* TODO: need to use something other than strlen */
+ if (A_MEMCMP(pInfo->ModuleName,module_name,strlen(module_name)) == 0) {
+ break;
+ }
+ pInfo = pInfo->pNext;
+ }
+
+ return pInfo;
+}
+
+
+void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
+{
+ if (!g_ModuleDebugInit) {
+ return;
+ }
+
+ A_MUTEX_LOCK(&g_ModuleListLock);
+
+ if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
+ if (g_pModuleInfoHead == NULL) {
+ g_pModuleInfoHead = pInfo;
+ } else {
+ pInfo->pNext = g_pModuleInfoHead;
+ g_pModuleInfoHead = pInfo;
+ }
+ pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
+ }
+
+ A_MUTEX_UNLOCK(&g_ModuleListLock);
+}
+
+void a_dump_module_debug_info_by_name(A_CHAR *module_name)
+{
+ ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
+
+ if (!g_ModuleDebugInit) {
+ return;
+ }
+
+ if (A_MEMCMP(module_name,"all",3) == 0) {
+ /* dump all */
+ while (pInfo != NULL) {
+ a_dump_module_debug_info(pInfo);
+ pInfo = pInfo->pNext;
+ }
+ return;
+ }
+
+ pInfo = FindModule(module_name);
+
+ if (pInfo != NULL) {
+ a_dump_module_debug_info(pInfo);
+ }
+
+}
+
+A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask)
+{
+ ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
+
+ if (NULL == pInfo) {
+ return A_ERROR;
+ }
+
+ *pMask = pInfo->CurrentMask;
+ return A_OK;
+}
+
+A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask)
+{
+ ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
+
+ if (NULL == pInfo) {
+ return A_ERROR;
+ }
+
+ pInfo->CurrentMask = Mask;
+ A_PRINTF("Module %s, new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask);
+ return A_OK;
+}
+
+
+void a_module_debug_support_init(void)
+{
+ if (g_ModuleDebugInit) {
+ return;
+ }
+ A_MUTEX_INIT(&g_ModuleListLock);
+ g_pModuleInfoHead = NULL;
+ g_ModuleDebugInit = TRUE;
+ A_REGISTER_MODULE_DEBUG_INFO(misc);
+}
+
+void a_module_debug_support_cleanup(void)
+{
+ ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
+ ATH_DEBUG_MODULE_DBG_INFO *pCur;
+
+ if (!g_ModuleDebugInit) {
+ return;
+ }
+
+ g_ModuleDebugInit = FALSE;
+
+ A_MUTEX_LOCK(&g_ModuleListLock);
+
+ while (pInfo != NULL) {
+ pCur = pInfo;
+ pInfo = pInfo->pNext;
+ pCur->pNext = NULL;
+ /* clear registered flag */
+ pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
+ }
+
+ A_MUTEX_UNLOCK(&g_ModuleListLock);
+
+ A_MUTEX_DELETE(&g_ModuleListLock);
+ g_pModuleInfoHead = NULL;
+}
+
+ /* can only be called during bmi init stage */
+A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice,
+ A_UINT32 TargetType,
+ A_UINT32 Flags)
+{
+ A_STATUS status = A_OK;
+
+ do {
+
+ if (TargetType != TARGET_TYPE_AR6003) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
+ TargetType));
+ break;
+ }
+
+ /* set hci bridge flags */
+ status = BMIWriteMemory(hifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
+ (A_UCHAR *)&Flags,
+ 4);
+
+
+ } while (FALSE);
+
+ return status;
+}
+
diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c
new file mode 100644
index 000000000000..91316e0b109e
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c
@@ -0,0 +1,418 @@
+//------------------------------------------------------------------------------
+// <copyright file="credit_dist.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#define ATH_MODULE_NAME misc
+#include "a_debug.h"
+#include "htc_api.h"
+#include "common_drv.h"
+
+/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/
+
+#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */
+#define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1
+
+#ifdef NO_VO_SERVICE
+#define DATA_SVCS_USED 3
+#else
+#define DATA_SVCS_USED 4
+#endif
+
+static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDistList);
+
+static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDistList);
+
+/* reduce an ep's credits back to a set limit */
+static INLINE void ReduceCredits(COMMON_CREDIT_STATE_INFO *pCredInfo,
+ HTC_ENDPOINT_CREDIT_DIST *pEpDist,
+ int Limit)
+{
+ int credits;
+
+ /* set the new limit */
+ pEpDist->TxCreditsAssigned = Limit;
+
+ if (pEpDist->TxCredits <= Limit) {
+ return;
+ }
+
+ /* figure out how much to take away */
+ credits = pEpDist->TxCredits - Limit;
+ /* take them away */
+ pEpDist->TxCredits -= credits;
+ pCredInfo->CurrentFreeCredits += credits;
+}
+
+/* give an endpoint some credits from the free credit pool */
+#define GiveCredits(pCredInfo,pEpDist,credits) \
+{ \
+ (pEpDist)->TxCredits += (credits); \
+ (pEpDist)->TxCreditsAssigned += (credits); \
+ (pCredInfo)->CurrentFreeCredits -= (credits); \
+}
+
+
+/* default credit init callback.
+ * This function is called in the context of HTCStart() to setup initial (application-specific)
+ * credit distributions */
+static void ar6000_credit_init(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPList,
+ int TotalCredits)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
+ int count;
+ COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context;
+
+ pCredInfo->CurrentFreeCredits = TotalCredits;
+ pCredInfo->TotalAvailableCredits = TotalCredits;
+
+ pCurEpDist = pEPList;
+
+ /* run through the list and initialize */
+ while (pCurEpDist != NULL) {
+
+ /* set minimums for each endpoint */
+ pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg;
+
+#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
+
+ if (TotalCredits > 4)
+ {
+ if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)){
+ /* assign at least min credits to lower than VO priority services */
+ GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
+ /* force active */
+ SET_EP_ACTIVE(pCurEpDist);
+ }
+ }
+
+#endif
+
+ if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
+ /* give control service some credits */
+ GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin);
+ /* control service is always marked active, it never goes inactive EVER */
+ SET_EP_ACTIVE(pCurEpDist);
+ } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) {
+ /* this is the lowest priority data endpoint, save this off for easy access */
+ pCredInfo->pLowestPriEpDist = pCurEpDist;
+ }
+
+ /* Streams have to be created (explicit | implicit)for all kinds
+ * of traffic. BE endpoints are also inactive in the beginning.
+ * When BE traffic starts it creates implicit streams that
+ * redistributes credits.
+ */
+
+ /* note, all other endpoints have minimums set but are initially given NO credits.
+ * Credits will be distributed as traffic activity demands */
+ pCurEpDist = pCurEpDist->pNext;
+ }
+
+ if (pCredInfo->CurrentFreeCredits <= 0) {
+ AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits));
+ A_ASSERT(FALSE);
+ return;
+ }
+
+ /* reset list */
+ pCurEpDist = pEPList;
+ /* now run through the list and set max operating credit limits for everyone */
+ while (pCurEpDist != NULL) {
+ if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) {
+ /* control service max is just 1 max message */
+ pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg;
+ } else {
+ /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are
+ * the same.
+ * We use a simple calculation here, we take the remaining credits and
+ * determine how many max messages this can cover and then set each endpoint's
+ * normal value equal to 3/4 this amount.
+ * */
+ count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg;
+ count = (count * 3) >> 2;
+ count = max(count,pCurEpDist->TxCreditsPerMaxMsg);
+ /* set normal */
+ pCurEpDist->TxCreditsNorm = count;
+
+ }
+ pCurEpDist = pCurEpDist->pNext;
+ }
+
+}
+
+
+/* default credit distribution callback
+ * This callback is invoked whenever endpoints require credit distributions.
+ * A lock is held while this function is invoked, this function shall NOT block.
+ * The pEPDistList is a list of distribution structures in prioritized order as
+ * defined by the call to the HTCSetCreditDistribution() api.
+ *
+ */
+static void ar6000_credit_distribute(void *Context,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDistList,
+ HTC_CREDIT_DIST_REASON Reason)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
+ COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context;
+
+ switch (Reason) {
+ case HTC_CREDIT_DIST_SEND_COMPLETE :
+ pCurEpDist = pEPDistList;
+ /* we are given the start of the endpoint distribution list.
+ * There may be one or more endpoints to service.
+ * Run through the list and distribute credits */
+ while (pCurEpDist != NULL) {
+
+ if (pCurEpDist->TxCreditsToDist > 0) {
+ /* return the credits back to the endpoint */
+ pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist;
+ /* always zero out when we are done */
+ pCurEpDist->TxCreditsToDist = 0;
+
+ if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) {
+ /* reduce to the assigned limit, previous credit reductions
+ * could have caused the limit to change */
+ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned);
+ }
+
+ if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) {
+ /* oversubscribed endpoints need to reduce back to normal */
+ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm);
+ }
+
+ if (!IS_EP_ACTIVE(pCurEpDist)) {
+ /* endpoint is inactive, now check for messages waiting for credits */
+ if (pCurEpDist->TxQueueDepth == 0) {
+ /* EP is inactive and there are no pending messages,
+ * reduce credits back to zero to recover credits */
+ ReduceCredits(pCredInfo, pCurEpDist, 0);
+ }
+ }
+ }
+
+ pCurEpDist = pCurEpDist->pNext;
+ }
+
+ break;
+
+ case HTC_CREDIT_DIST_ACTIVITY_CHANGE :
+ RedistributeCredits(pCredInfo,pEPDistList);
+ break;
+ case HTC_CREDIT_DIST_SEEK_CREDITS :
+ SeekCredits(pCredInfo,pEPDistList);
+ break;
+ case HTC_DUMP_CREDIT_STATE :
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Credit Distribution, total : %d, free : %d\n",
+ pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits));
+ break;
+ default:
+ break;
+
+ }
+
+ /* sanity checks done after each distribution action */
+ A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits);
+ A_ASSERT(pCredInfo->CurrentFreeCredits >= 0);
+
+}
+
+/* redistribute credits based on activity change */
+static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDistList)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList;
+
+ /* walk through the list and remove credits from inactive endpoints */
+ while (pCurEpDist != NULL) {
+
+#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
+
+ if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)) {
+ /* force low priority streams to always be active to retain their minimum credit distribution */
+ SET_EP_ACTIVE(pCurEpDist);
+ }
+#endif
+
+ if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) {
+ if (!IS_EP_ACTIVE(pCurEpDist)) {
+ if (pCurEpDist->TxQueueDepth == 0) {
+ /* EP is inactive and there are no pending messages, reduce credits back to zero */
+ ReduceCredits(pCredInfo, pCurEpDist, 0);
+ } else {
+ /* we cannot zero the credits assigned to this EP, but to keep
+ * the credits available for these leftover packets, reduce to
+ * a minimum */
+ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMin);
+ }
+ }
+ }
+
+ /* NOTE in the active case, we do not need to do anything further,
+ * when an EP goes active and needs credits, HTC will call into
+ * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS */
+
+ pCurEpDist = pCurEpDist->pNext;
+ }
+
+}
+
+/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */
+static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo,
+ HTC_ENDPOINT_CREDIT_DIST *pEPDist)
+{
+ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist;
+ int credits = 0;
+ int need;
+
+ do {
+
+ if (pEPDist->ServiceID == WMI_CONTROL_SVC) {
+ /* we never oversubscribe on the control service, this is not
+ * a high performance path and the target never holds onto control
+ * credits for too long */
+ break;
+ }
+
+#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS
+ if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
+ if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
+ /* limit VI service from oversubscribing */
+ break;
+ }
+ }
+
+ if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
+ if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) {
+ /* limit VO service from oversubscribing */
+ break;
+ }
+ }
+#else
+ if (pEPDist->ServiceID == WMI_DATA_VI_SVC) {
+ if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
+ (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
+ /* limit VI service from oversubscribing */
+ /* at least one free credit will not be used by VI */
+ break;
+ }
+ }
+
+ if (pEPDist->ServiceID == WMI_DATA_VO_SVC) {
+ if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) ||
+ (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) {
+ /* limit VO service from oversubscribing */
+ /* at least one free credit will not be used by VO */
+ break;
+ }
+ }
+#endif
+
+ /* for all other services, we follow a simple algorithm of
+ * 1. checking the free pool for credits
+ * 2. checking lower priority endpoints for credits to take */
+
+ /* give what we can */
+ credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
+
+ if (credits >= pEPDist->TxCreditsSeek) {
+ /* we found some to fullfill the seek request */
+ break;
+ }
+
+ /* we don't have enough in the free pool, try taking away from lower priority services
+ *
+ * The rule for taking away credits:
+ * 1. Only take from lower priority endpoints
+ * 2. Only take what is allocated above the minimum (never starve an endpoint completely)
+ * 3. Only take what you need.
+ *
+ * */
+
+ /* starting at the lowest priority */
+ pCurEpDist = pCredInfo->pLowestPriEpDist;
+
+ /* work backwards until we hit the endpoint again */
+ while (pCurEpDist != pEPDist) {
+ /* calculate how many we need so far */
+ need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits;
+
+ if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) {
+ /* the current one has been allocated more than it's minimum and it
+ * has enough credits assigned above it's minimum to fullfill our need
+ * try to take away just enough to fullfill our need */
+ ReduceCredits(pCredInfo,
+ pCurEpDist,
+ pCurEpDist->TxCreditsAssigned - need);
+
+ if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) {
+ /* we have enough */
+ break;
+ }
+ }
+
+ pCurEpDist = pCurEpDist->pPrev;
+ }
+
+ /* return what we can get */
+ credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek);
+
+ } while (FALSE);
+
+ /* did we find some credits? */
+ if (credits) {
+ /* give what we can */
+ GiveCredits(pCredInfo, pEPDist, credits);
+ }
+
+}
+
+/* initialize and setup credit distribution */
+A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo)
+{
+ HTC_SERVICE_ID servicepriority[5];
+
+ A_MEMZERO(pCredInfo,sizeof(COMMON_CREDIT_STATE_INFO));
+
+ servicepriority[0] = WMI_CONTROL_SVC; /* highest */
+ servicepriority[1] = WMI_DATA_VO_SVC;
+ servicepriority[2] = WMI_DATA_VI_SVC;
+ servicepriority[3] = WMI_DATA_BE_SVC;
+ servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
+
+ /* set callbacks and priority list */
+ HTCSetCreditDistribution(HTCHandle,
+ pCredInfo,
+ ar6000_credit_distribute,
+ ar6000_credit_init,
+ servicepriority,
+ 5);
+
+ return A_OK;
+}
+
diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h
new file mode 100644
index 000000000000..ae24b728c4ad
--- /dev/null
+++ b/drivers/staging/ath6kl/miscdrv/miscdrv.h
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <copyright file="miscdrv.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _MISCDRV_H
+#define _MISCDRV_H
+
+
+#define HOST_INTEREST_ITEM_ADDRESS(target, item) \
+ AR6002_HOST_INTEREST_ITEM_ADDRESS(item)
+
+A_UINT32 ar6kRev2Array[][128] = {
+ {0xFFFF, 0xFFFF}, // No Patches
+ };
+
+#define CFG_REV2_ITEMS 0 // no patches so far
+#define AR6K_RESET_ADDR 0x4000
+#define AR6K_RESET_VAL 0x100
+
+#define EEPROM_SZ 768
+#define EEPROM_WAIT_LIMIT 4
+
+#endif
+
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c
new file mode 100644
index 000000000000..a588825b9dab
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c
@@ -0,0 +1,413 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+#include "ar6000_drv.h"
+#include "htc.h"
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+A_BOOL enable_mmc_host_detect_change = 0;
+static void ar6000_enable_mmchost_detect_change(int enable);
+
+
+char fwpath[256] = "/system/wifi";
+int wowledon;
+unsigned int enablelogcat;
+
+extern int bmienable;
+extern struct net_device *ar6000_devices[];
+extern char ifname[];
+
+#ifdef CONFIG_HAS_WAKELOCK
+extern struct wake_lock ar6k_wow_wake_lock;
+struct wake_lock ar6k_init_wake_lock;
+#endif
+
+const char def_ifname[] = "wlan0";
+module_param_string(fwpath, fwpath, sizeof(fwpath), 0644);
+module_param(enablelogcat, uint, 0644);
+module_param(wowledon, int, 0644);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static int screen_is_off;
+static struct early_suspend ar6k_early_suspend;
+#endif
+
+static A_STATUS (*ar6000_avail_ev_p)(void *, void *);
+
+#if defined(CONFIG_ANDROID_LOGGER) && (!defined(CONFIG_MMC_MSM))
+int logger_write(const enum logidx index,
+ const unsigned char prio,
+ const char __kernel * const tag,
+ const char __kernel * const fmt,
+ ...)
+{
+ int ret = 0;
+ va_list vargs;
+ struct file *filp = (struct file *)-ENOENT;
+ mm_segment_t oldfs;
+ struct iovec vec[3];
+ int tag_bytes = strlen(tag) + 1, msg_bytes;
+ char *msg;
+ va_start(vargs, fmt);
+ msg = kvasprintf(GFP_ATOMIC, fmt, vargs);
+ va_end(vargs);
+ if (!msg)
+ return -ENOMEM;
+ if (in_interrupt()) {
+ /* we have no choice since aio_write may be blocked */
+ printk(KERN_ALERT "%s", msg);
+ goto out_free_message;
+ }
+ msg_bytes = strlen(msg) + 1;
+ if (msg_bytes <= 1) /* empty message? */
+ goto out_free_message; /* don't bother, then */
+ if ((msg_bytes + tag_bytes + 1) > 2048) {
+ ret = -E2BIG;
+ goto out_free_message;
+ }
+
+ vec[0].iov_base = (unsigned char *) &prio;
+ vec[0].iov_len = 1;
+ vec[1].iov_base = (void *) tag;
+ vec[1].iov_len = strlen(tag) + 1;
+ vec[2].iov_base = (void *) msg;
+ vec[2].iov_len = strlen(msg) + 1;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ do {
+ filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR);
+ if (IS_ERR(filp) || !filp->f_op) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: filp_open /dev/log/main error\n", __FUNCTION__));
+ ret = -ENOENT;
+ break;
+ }
+
+ if (filp->f_op->aio_write) {
+ int nr_segs = sizeof(vec) / sizeof(vec[0]);
+ int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len;
+ struct kiocb kiocb;
+ init_sync_kiocb(&kiocb, filp);
+ kiocb.ki_pos = 0;
+ kiocb.ki_left = len;
+ kiocb.ki_nbytes = len;
+ ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos);
+ }
+
+ } while (0);
+
+ if (!IS_ERR(filp)) {
+ filp_close(filp, NULL);
+ }
+ set_fs(oldfs);
+out_free_message:
+ if (msg) {
+ kfree(msg);
+ }
+ return ret;
+}
+#endif
+
+int android_logger_lv(void *module, int mask)
+{
+ switch (mask) {
+ case ATH_DEBUG_ERR:
+ return 6;
+ case ATH_DEBUG_INFO:
+ return 4;
+ case ATH_DEBUG_WARN:
+ return 5;
+ case ATH_DEBUG_TRC:
+ return 3;
+ default:
+#ifdef DEBUG
+ if (!module) {
+ return 3;
+ } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(driver)) {
+ return (mask <=ATH_DEBUG_MAKE_MODULE_MASK(3)) ? 3 : 2;
+ } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(htc)) {
+ return 2;
+ } else {
+ return 3;
+ }
+#else
+ return 3; /* DEBUG */
+#endif
+ }
+}
+
+static int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length)
+{
+ int ret = 0;
+ struct file *filp = (struct file *)-ENOENT;
+ mm_segment_t oldfs;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ do {
+ int mode = (wbuf) ? O_RDWR : O_RDONLY;
+ filp = filp_open(filename, mode, S_IRUSR);
+ if (IS_ERR(filp) || !filp->f_op) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: file %s filp_open error\n", __FUNCTION__, filename));
+ ret = -ENOENT;
+ break;
+ }
+
+ if (length==0) {
+ /* Read the length of the file only */
+ struct inode *inode;
+
+ inode = GET_INODE_FROM_FILEP(filp);
+ if (!inode) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Get inode from %s failed\n", __FUNCTION__, filename));
+ ret = -ENOENT;
+ break;
+ }
+ ret = i_size_read(inode->i_mapping->host);
+ break;
+ }
+
+ if (wbuf) {
+ if ( (ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Write %u bytes to file %s error %d\n", __FUNCTION__,
+ length, filename, ret));
+ break;
+ }
+ } else {
+ if ( (ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Read %u bytes from file %s error %d\n", __FUNCTION__,
+ length, filename, ret));
+ break;
+ }
+ }
+ } while (0);
+
+ if (!IS_ERR(filp)) {
+ filp_close(filp, NULL);
+ }
+ set_fs(oldfs);
+
+ return ret;
+}
+
+int android_request_firmware(const struct firmware **firmware_p, const char *name,
+ struct device *device)
+{
+ int ret = 0;
+ struct firmware *firmware;
+ char filename[256];
+ const char *raw_filename = name;
+ *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
+ if (!firmware)
+ return -ENOMEM;
+ sprintf(filename, "%s/%s", fwpath, raw_filename);
+ do {
+ size_t length, bufsize, bmisize;
+
+ if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
+ break;
+ } else {
+ length = ret;
+ }
+
+ bufsize = ALIGN(length, PAGE_SIZE);
+ bmisize = A_ROUND_UP(length, 4);
+ bufsize = max(bmisize, bufsize);
+ firmware->data = vmalloc(bufsize);
+ firmware->size = length;
+ if (!firmware->data) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__));
+ ret = -ENOMEM;
+ break;
+ }
+
+ if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length));
+ ret = -1;
+ break;
+ }
+
+ } while (0);
+
+ if (ret<0) {
+ if (firmware) {
+ if (firmware->data)
+ vfree(firmware->data);
+ kfree(firmware);
+ }
+ *firmware_p = NULL;
+ } else {
+ ret = 0;
+ }
+ return ret;
+}
+
+void android_release_firmware(const struct firmware *firmware)
+{
+ if (firmware) {
+ if (firmware->data)
+ vfree(firmware->data);
+ kfree(firmware);
+ }
+}
+
+static A_STATUS ar6000_android_avail_ev(void *context, void *hif_handle)
+{
+ A_STATUS ret;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock(&ar6k_init_wake_lock);
+#endif
+ ar6000_enable_mmchost_detect_change(0);
+ ret = ar6000_avail_ev_p(context, hif_handle);
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_unlock(&ar6k_init_wake_lock);
+#endif
+ return ret;
+}
+
+/* Useful for qualcom platform to detect our wlan card for mmc stack */
+static void ar6000_enable_mmchost_detect_change(int enable)
+{
+#ifdef CONFIG_MMC_MSM
+#define MMC_MSM_DEV "msm_sdcc.1"
+ char buf[3];
+ int length;
+
+ if (!enable_mmc_host_detect_change) {
+ return;
+ }
+ length = snprintf(buf, sizeof(buf), "%d\n", enable ? 1 : 0);
+ if (android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/detect_change",
+ NULL, buf, length) < 0) {
+ /* fall back to polling */
+ android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
+ }
+#endif
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void android_early_suspend(struct early_suspend *h)
+{
+ screen_is_off = 1;
+}
+
+static void android_late_resume(struct early_suspend *h)
+{
+ screen_is_off = 0;
+}
+#endif
+
+void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks)
+{
+ bmienable = 1;
+ if (ifname[0] == '\0')
+ strcpy(ifname, def_ifname);
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_init(&ar6k_init_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_init");
+#endif
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ ar6k_early_suspend.suspend = android_early_suspend;
+ ar6k_early_suspend.resume = android_late_resume;
+ ar6k_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ register_early_suspend(&ar6k_early_suspend);
+#endif
+
+ ar6000_avail_ev_p = osdrvCallbacks->deviceInsertedHandler;
+ osdrvCallbacks->deviceInsertedHandler = ar6000_android_avail_ev;
+
+ ar6000_enable_mmchost_detect_change(1);
+}
+
+void android_module_exit(void)
+{
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ar6k_early_suspend);
+#endif
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_destroy(&ar6k_init_wake_lock);
+#endif
+ ar6000_enable_mmchost_detect_change(1);
+}
+
+#ifdef CONFIG_PM
+void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent)
+{
+ if (
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ screen_is_off &&
+#endif
+ skb && ar->arConnected) {
+ A_BOOL needWake = FALSE;
+ if (isEvent) {
+ if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) {
+ A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb);
+ switch (cmd) {
+ case WMI_CONNECT_EVENTID:
+ case WMI_DISCONNECT_EVENTID:
+ needWake = TRUE;
+ break;
+ default:
+ /* dont wake lock the system for other event */
+ break;
+ }
+ }
+ } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
+ ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
+ if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
+ switch (A_BE2CPU16(datap->typeOrLen)) {
+ case 0x0800: /* IP */
+ case 0x888e: /* EAPOL */
+ case 0x88c7: /* RSN_PREAUTH */
+ case 0x88b4: /* WAPI */
+ needWake = TRUE;
+ break;
+ case 0x0806: /* ARP is not important to hold wake lock */
+ default:
+ break;
+ }
+ }
+ }
+ if (needWake) {
+ /* keep host wake up if there is any event and packate comming in*/
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ);
+#endif
+ if (wowledon) {
+ char buf[32];
+ int len = sprintf(buf, "on");
+ android_readwrite_file("/sys/power/state", NULL, buf, len);
+
+ len = sprintf(buf, "%d", 127);
+ android_readwrite_file("/sys/class/leds/lcd-backlight/brightness",
+ NULL, buf,len);
+ }
+ }
+ }
+}
+#endif /* CONFIG_PM */
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
new file mode 100644
index 000000000000..ff7976e9a5ca
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
@@ -0,0 +1,6453 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+/*
+ * This driver is a pseudo ethernet driver to access the Atheros AR6000
+ * WLAN Device
+ */
+
+#include "ar6000_drv.h"
+#ifdef ATH6K_CONFIG_CFG80211
+#include "cfg80211.h"
+#endif /* ATH6K_CONFIG_CFG80211 */
+#include "htc.h"
+#include "wmi_filter_linux.h"
+#include "epping_test.h"
+#include "wlan_config.h"
+#include "ar3kconfig.h"
+#include "ar6k_pal.h"
+#include "AR6002/addrs.h"
+
+
+/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When
+ * the meta data was added to the header it was found that linux did not correctly provide
+ * enough headroom. However when more headroom was requested beyond what was truly needed
+ * Linux gave the requested headroom. Therefore to get the necessary headroom from Linux
+ * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */
+#define LINUX_HACK_FUDGE_FACTOR 16
+#define BDATA_BDADDR_OFFSET 28
+
+A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+#ifdef DEBUG
+
+#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
+#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
+#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
+#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
+#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
+#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
+#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
+
+static ATH_DEBUG_MASK_DESCRIPTION driver_debug_desc[] = {
+ { ATH_DEBUG_DBG_LOG , "Target Debug Logs"},
+ { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"},
+ { ATH_DEBUG_WLAN_SCAN , "WLAN scan"},
+ { ATH_DEBUG_WLAN_TX , "WLAN Tx"},
+ { ATH_DEBUG_WLAN_RX , "WLAN Rx"},
+ { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"},
+ { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"},
+ { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"},
+ { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver,
+ "driver",
+ "Linux Driver Interface",
+ ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN |
+ ATH_DEBUG_HCI_BRIDGE,
+ ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc),
+ driver_debug_desc);
+
+#endif
+
+
+#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0)
+#define IS_MAC_BCAST(mac) (*mac==0xff)
+
+#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_)
+
+MODULE_AUTHOR("Atheros Communications, Inc.");
+MODULE_DESCRIPTION(DESCRIPTION);
+MODULE_LICENSE("Dual BSD/GPL");
+
+#ifndef REORG_APTC_HEURISTICS
+#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+#endif /* REORG_APTC_HEURISTICS */
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */
+#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */
+#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */
+
+typedef struct aptc_traffic_record {
+ A_BOOL timerScheduled;
+ struct timeval samplingTS;
+ unsigned long bytesReceived;
+ unsigned long bytesTransmitted;
+} APTC_TRAFFIC_RECORD;
+
+A_TIMER aptcTimer;
+APTC_TRAFFIC_RECORD aptcTR;
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+// callbacks registered by HCI transport driver
+HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks = { NULL };
+#endif
+
+unsigned int processDot11Hdr = 0;
+int bmienable = BMIENABLE_DEFAULT;
+
+char ifname[IFNAMSIZ] = {0,};
+
+int wlaninitmode = WLAN_INIT_MODE_DEFAULT;
+unsigned int bypasswmi = 0;
+unsigned int debuglevel = 0;
+int tspecCompliance = ATHEROS_COMPLIANCE;
+unsigned int busspeedlow = 0;
+unsigned int onebitmode = 0;
+unsigned int skipflash = 0;
+unsigned int wmitimeout = 2;
+unsigned int wlanNodeCaching = 1;
+unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
+unsigned int logWmiRawMsgs = 0;
+unsigned int enabletimerwar = 0;
+unsigned int fwmode = 1;
+unsigned int mbox_yield_limit = 99;
+unsigned int enablerssicompensation = 0;
+int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF;
+int allow_trace_signal = 0;
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+unsigned int testmode =0;
+#endif
+
+unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC;
+unsigned int panic_on_assert = 1;
+unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
+
+unsigned int setuphci = SETUPHCI_DEFAULT;
+unsigned int setuphcipal = SETUPHCIPAL_DEFAULT;
+unsigned int loghci = 0;
+unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT;
+unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
+unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
+#endif
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+unsigned int csumOffload=0;
+unsigned int csumOffloadTest=0;
+#endif
+unsigned int eppingtest=0;
+
+module_param_string(ifname, ifname, sizeof(ifname), 0644);
+module_param(wlaninitmode, int, 0644);
+module_param(bmienable, int, 0644);
+module_param(bypasswmi, uint, 0644);
+module_param(debuglevel, uint, 0644);
+module_param(tspecCompliance, int, 0644);
+module_param(onebitmode, uint, 0644);
+module_param(busspeedlow, uint, 0644);
+module_param(skipflash, uint, 0644);
+module_param(wmitimeout, uint, 0644);
+module_param(wlanNodeCaching, uint, 0644);
+module_param(logWmiRawMsgs, uint, 0644);
+module_param(enableuartprint, uint, 0644);
+module_param(enabletimerwar, uint, 0644);
+module_param(fwmode, uint, 0644);
+module_param(mbox_yield_limit, uint, 0644);
+module_param(reduce_credit_dribble, int, 0644);
+module_param(allow_trace_signal, int, 0644);
+module_param(enablerssicompensation, uint, 0644);
+module_param(processDot11Hdr, uint, 0644);
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+module_param(csumOffload, uint, 0644);
+#endif
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+module_param(testmode, uint, 0644);
+#endif
+module_param(irqprocmode, uint, 0644);
+module_param(nohifscattersupport, uint, 0644);
+module_param(panic_on_assert, uint, 0644);
+module_param(setuphci, uint, 0644);
+module_param(setuphcipal, uint, 0644);
+module_param(loghci, uint, 0644);
+module_param(setupbtdev, uint, 0644);
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+module_param(ar3khcibaud, uint, 0644);
+module_param(hciuartscale, uint, 0644);
+module_param(hciuartstep, uint, 0644);
+#endif
+module_param(eppingtest, uint, 0644);
+
+/* in 2.6.10 and later this is now a pointer to a uint */
+unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX;
+#define mboxnum &_mboxnum
+
+#ifdef DEBUG
+A_UINT32 g_dbg_flags = DBG_DEFAULTS;
+unsigned int debugflags = 0;
+int debugdriver = 0;
+unsigned int debughtc = 0;
+unsigned int debugbmi = 0;
+unsigned int debughif = 0;
+unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0};
+module_param(debugflags, uint, 0644);
+module_param(debugdriver, int, 0644);
+module_param(debughtc, uint, 0644);
+module_param(debugbmi, uint, 0644);
+module_param(debughif, uint, 0644);
+module_param_array(txcreditsavailable, uint, mboxnum, 0644);
+module_param_array(txcreditsconsumed, uint, mboxnum, 0644);
+module_param_array(txcreditintrenable, uint, mboxnum, 0644);
+module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644);
+
+#endif /* DEBUG */
+
+unsigned int resetok = 1;
+unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int hifBusRequestNumMax = 40;
+unsigned int war23838_disabled = 0;
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+unsigned int enableAPTCHeuristics = 1;
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+module_param_array(tx_attempt, uint, mboxnum, 0644);
+module_param_array(tx_post, uint, mboxnum, 0644);
+module_param_array(tx_complete, uint, mboxnum, 0644);
+module_param(hifBusRequestNumMax, uint, 0644);
+module_param(war23838_disabled, uint, 0644);
+module_param(resetok, uint, 0644);
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+module_param(enableAPTCHeuristics, uint, 0644);
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+#ifdef BLOCK_TX_PATH_FLAG
+int blocktx = 0;
+module_param(blocktx, int, 0644);
+#endif /* BLOCK_TX_PATH_FLAG */
+
+typedef struct user_rssi_compensation_t {
+ A_UINT16 customerID;
+ union {
+ A_UINT16 a_enable;
+ A_UINT16 bg_enable;
+ A_UINT16 enable;
+ };
+ A_INT16 bg_param_a;
+ A_INT16 bg_param_b;
+ A_INT16 a_param_a;
+ A_INT16 a_param_b;
+ A_UINT32 reserved;
+} USER_RSSI_CPENSATION;
+
+static USER_RSSI_CPENSATION rssi_compensation_param;
+
+static A_INT16 rssi_compensation_table[96];
+
+int reconnect_flag = 0;
+static ar6k_pal_config_t ar6k_pal_config_g;
+
+/* Function declarations */
+static int ar6000_init_module(void);
+static void ar6000_cleanup_module(void);
+
+int ar6000_init(struct net_device *dev);
+static int ar6000_open(struct net_device *dev);
+static int ar6000_close(struct net_device *dev);
+static void ar6000_init_control_info(AR_SOFTC_T *ar);
+static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
+
+void ar6000_destroy(struct net_device *dev, unsigned int unregister);
+static void ar6000_detect_error(unsigned long ptr);
+static void ar6000_set_multicast_list(struct net_device *dev);
+static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
+static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev);
+
+static void disconnect_timer_handler(unsigned long ptr);
+
+void read_rssi_compensation_param(AR_SOFTC_T *ar);
+
+ /* for android builds we call external APIs that handle firmware download and configuration */
+#ifdef ANDROID_ENV
+/* !!!! Interim android support to make it easier to patch the default driver for
+ * android use. You must define an external source file ar6000_android.c that handles the following
+ * APIs */
+extern void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks);
+extern void android_module_exit(void);
+#endif
+/*
+ * HTC service connection handlers
+ */
+static A_STATUS ar6000_avail_ev(void *context, void *hif_handle);
+
+static A_STATUS ar6000_unavail_ev(void *context, void *hif_handle);
+
+A_STATUS ar6000_configure_target(AR_SOFTC_T *ar);
+
+static void ar6000_target_failure(void *Instance, A_STATUS Status);
+
+static void ar6000_rx(void *Context, HTC_PACKET *pPacket);
+
+static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint);
+
+static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets);
+
+static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket);
+
+#ifdef ATH_AR6K_11N_SUPPORT
+static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num);
+#endif
+static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
+//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
+
+static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length);
+
+static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count);
+
+static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar);
+
+static ssize_t
+ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count);
+
+static ssize_t
+ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count);
+
+static A_STATUS
+ar6000_sysfs_bmi_init(AR_SOFTC_T *ar);
+
+/* HCI PAL callback function declarations */
+A_STATUS ar6k_setup_hci_pal(AR_SOFTC_T *ar);
+void ar6k_cleanup_hci_pal(AR_SOFTC_T *ar);
+
+static void
+ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar);
+
+A_STATUS
+ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode);
+
+/*
+ * Static variables
+ */
+
+struct net_device *ar6000_devices[MAX_AR6000];
+static int is_netdev_registered;
+extern struct iw_handler_def ath_iw_handler_def;
+DECLARE_WAIT_QUEUE_HEAD(arEvent);
+static void ar6000_cookie_init(AR_SOFTC_T *ar);
+static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);
+static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);
+static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);
+
+#ifdef USER_KEYS
+static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl);
+#endif
+
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+struct net_device *arApNetDev;
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+
+static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
+
+#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
+ (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
+
+
+static struct net_device_ops ar6000_netdev_ops = {
+ .ndo_init = NULL,
+ .ndo_open = ar6000_open,
+ .ndo_stop = ar6000_close,
+ .ndo_get_stats = ar6000_get_stats,
+ .ndo_do_ioctl = ar6000_ioctl,
+ .ndo_start_xmit = ar6000_data_tx,
+ .ndo_set_multicast_list = ar6000_set_multicast_list,
+};
+
+/* Debug log support */
+
+/*
+ * Flag to govern whether the debug logs should be parsed in the kernel
+ * or reported to the application.
+ */
+#define REPORT_DEBUG_LOGS_TO_APP
+
+A_STATUS
+ar6000_set_host_app_area(AR_SOFTC_T *ar)
+{
+ A_UINT32 address, data;
+ struct host_app_area_s host_app_area;
+
+ /* Fetch the address of the host_app_area_s instance in the host interest area */
+ address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest));
+ if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) {
+ return A_ERROR;
+ }
+ address = TARG_VTOP(ar->arTargetType, data);
+ host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
+ if (ar6000_WriteDataDiag(ar->arHifDevice, address,
+ (A_UCHAR *)&host_app_area,
+ sizeof(struct host_app_area_s)) != A_OK)
+ {
+ return A_ERROR;
+ }
+
+ return A_OK;
+}
+
+A_UINT32
+dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar)
+{
+ A_UINT32 param;
+ A_UINT32 address;
+ A_STATUS status;
+
+ address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr));
+ if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address,
+ (A_UCHAR *)&param, 4)) != A_OK)
+ {
+ param = 0;
+ }
+
+ return param;
+}
+
+/*
+ * The dbglog module has been initialized. Its ok to access the relevant
+ * data stuctures over the diagnostic window.
+ */
+void
+ar6000_dbglog_init_done(AR_SOFTC_T *ar)
+{
+ ar->dbglog_init_done = TRUE;
+}
+
+A_UINT32
+dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit)
+{
+ A_INT32 *buffer;
+ A_UINT32 count;
+ A_UINT32 numargs;
+ A_UINT32 length;
+ A_UINT32 fraglen;
+
+ count = fraglen = 0;
+ buffer = (A_INT32 *)datap;
+ length = (limit >> 2);
+
+ if (len <= limit) {
+ fraglen = len;
+ } else {
+ while (count < length) {
+ numargs = DBGLOG_GET_NUMARGS(buffer[count]);
+ fraglen = (count << 2);
+ count += numargs + 1;
+ }
+ }
+
+ return fraglen;
+}
+
+void
+dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len)
+{
+ A_INT32 *buffer;
+ A_UINT32 count;
+ A_UINT32 timestamp;
+ A_UINT32 debugid;
+ A_UINT32 moduleid;
+ A_UINT32 numargs;
+ A_UINT32 length;
+
+ count = 0;
+ buffer = (A_INT32 *)datap;
+ length = (len >> 2);
+ while (count < length) {
+ debugid = DBGLOG_GET_DBGID(buffer[count]);
+ moduleid = DBGLOG_GET_MODULEID(buffer[count]);
+ numargs = DBGLOG_GET_NUMARGS(buffer[count]);
+ timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);
+ switch (numargs) {
+ case 0:
+ AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp));
+ break;
+
+ case 1:
+ AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid,
+ timestamp, buffer[count+1]));
+ break;
+
+ case 2:
+ AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,
+ timestamp, buffer[count+1], buffer[count+2]));
+ break;
+
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs));
+ }
+ count += numargs + 1;
+ }
+}
+
+int
+ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar)
+{
+ A_UINT32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */
+ A_UINT32 address;
+ A_UINT32 length;
+ A_UINT32 dropped;
+ A_UINT32 firstbuf;
+ A_UINT32 debug_hdr_ptr;
+
+ if (!ar->dbglog_init_done) return A_ERROR;
+
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ if (ar->dbgLogFetchInProgress) {
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ return A_EBUSY;
+ }
+
+ /* block out others */
+ ar->dbgLogFetchInProgress = TRUE;
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);
+ printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);
+
+ /* Get the contents of the ring buffer */
+ if (debug_hdr_ptr) {
+ address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr);
+ length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */;
+ A_MEMZERO(data, sizeof(data));
+ ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)data, length);
+ address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */);
+ firstbuf = address;
+ dropped = data[1]; /* dropped */
+ length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
+ A_MEMZERO(data, sizeof(data));
+ ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&data, length);
+
+ do {
+ address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/);
+ length = data[3]; /* length */
+ if ((length) && (length <= data[2] /* bufsize*/)) {
+ /* Rewind the index if it is about to overrun the buffer */
+ if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {
+ ar->log_cnt = 0;
+ }
+ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
+ (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length))
+ {
+ break;
+ }
+ ar6000_dbglog_event(ar, dropped, (A_INT8*)&ar->log_buffer[ar->log_cnt], length);
+ ar->log_cnt += length;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n",
+ data[3], data[2]));
+ }
+
+ address = TARG_VTOP(ar->arTargetType, data[0] /* next */);
+ length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */;
+ A_MEMZERO(data, sizeof(data));
+ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,
+ (A_UCHAR *)&data, length))
+ {
+ break;
+ }
+
+ } while (address != firstbuf);
+ }
+
+ ar->dbgLogFetchInProgress = FALSE;
+
+ return A_OK;
+}
+
+void
+ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped,
+ A_INT8 *buffer, A_UINT32 length)
+{
+#ifdef REPORT_DEBUG_LOGS_TO_APP
+ #define MAX_WIRELESS_EVENT_SIZE 252
+ /*
+ * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.
+ * There seems to be a limitation on the length of message that could be
+ * transmitted to the user app via this mechanism.
+ */
+ A_UINT32 send, sent;
+
+ sent = 0;
+ send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
+ MAX_WIRELESS_EVENT_SIZE);
+ while (send) {
+ ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (A_UINT8*)&buffer[sent], send);
+ sent += send;
+ send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
+ MAX_WIRELESS_EVENT_SIZE);
+ }
+#else
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n",
+ dropped, length));
+
+ /* Interpret the debug logs */
+ dbglog_parse_debug_logs((A_INT8*)buffer, length);
+#endif /* REPORT_DEBUG_LOGS_TO_APP */
+}
+
+
+static int __init
+ar6000_init_module(void)
+{
+ static int probed = 0;
+ A_STATUS status;
+ OSDRV_CALLBACKS osdrvCallbacks;
+
+ a_module_debug_support_init();
+
+#ifdef DEBUG
+ /* check for debug mask overrides */
+ if (debughtc != 0) {
+ ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc);
+ }
+ if (debugbmi != 0) {
+ ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi);
+ }
+ if (debughif != 0) {
+ ATH_DEBUG_SET_DEBUG_MASK(hif,debughif);
+ }
+ if (debugdriver != 0) {
+ ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver);
+ }
+
+#endif
+
+ A_REGISTER_MODULE_DEBUG_INFO(driver);
+
+ A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
+ osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev;
+ osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev;
+#ifdef CONFIG_PM
+ osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev;
+ osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev;
+ osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
+#endif
+
+ ar6000_pm_init();
+
+#ifdef ANDROID_ENV
+ android_module_init(&osdrvCallbacks);
+#endif
+
+#ifdef DEBUG
+ /* Set the debug flags if specified at load time */
+ if(debugflags != 0)
+ {
+ g_dbg_flags = debugflags;
+ }
+#endif
+
+ if (probed) {
+ return -ENODEV;
+ }
+ probed++;
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+ memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+ ar6000_gpio_init();
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+ status = HIFInit(&osdrvCallbacks);
+ if(status != A_OK)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void __exit
+ar6000_cleanup_module(void)
+{
+ int i = 0;
+ struct net_device *ar6000_netdev;
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+ /* Delete the Adaptive Power Control timer */
+ if (timer_pending(&aptcTimer)) {
+ del_timer_sync(&aptcTimer);
+ }
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+ for (i=0; i < MAX_AR6000; i++) {
+ if (ar6000_devices[i] != NULL) {
+ ar6000_netdev = ar6000_devices[i];
+ ar6000_devices[i] = NULL;
+ ar6000_destroy(ar6000_netdev, 1);
+ }
+ }
+
+ HIFShutDownDevice(NULL);
+
+ a_module_debug_support_cleanup();
+
+ ar6000_pm_exit();
+
+#ifdef ANDROID_ENV
+ android_module_exit();
+#endif
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
+}
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+void
+aptcTimerHandler(unsigned long arg)
+{
+ A_UINT32 numbytes;
+ A_UINT32 throughput;
+ AR_SOFTC_T *ar;
+ A_STATUS status;
+
+ ar = (AR_SOFTC_T *)arg;
+ A_ASSERT(ar != NULL);
+ A_ASSERT(!timer_pending(&aptcTimer));
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ /* Get the number of bytes transferred */
+ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
+ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
+
+ /* Calculate and decide based on throughput thresholds */
+ throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */
+ if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {
+ /* Enable Sleep and delete the timer */
+ A_ASSERT(ar->arWmiReady == TRUE);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ status = wmi_powermode_cmd(ar->arWmi, REC_POWER);
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ A_ASSERT(status == A_OK);
+ aptcTR.timerScheduled = FALSE;
+ } else {
+ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+}
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+#ifdef ATH_AR6K_11N_SUPPORT
+static void
+ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num)
+{
+ void * osbuf;
+
+ while(num) {
+ if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) {
+ A_NETBUF_ENQUEUE(q, osbuf);
+ } else {
+ break;
+ }
+ num--;
+ }
+
+ if(num) {
+ A_PRINTF("%s(), allocation of netbuf failed", __func__);
+ }
+}
+#endif
+
+static struct bin_attribute bmi_attr = {
+ .attr = {.name = "bmi", .mode = 0600},
+ .read = ar6000_sysfs_bmi_read,
+ .write = ar6000_sysfs_bmi_write,
+};
+
+static ssize_t
+ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count)
+{
+ int index;
+ AR_SOFTC_T *ar;
+ HIF_DEVICE_OS_DEVICE_INFO *osDevInfo;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (A_UINT32)count));
+ for (index=0; index < MAX_AR6000; index++) {
+ ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
+ osDevInfo = &ar->osDevInfo;
+ if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
+ break;
+ }
+ }
+
+ if (index == MAX_AR6000) return 0;
+
+ if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, TRUE)) != A_OK) {
+ return 0;
+ }
+
+ return count;
+}
+
+static ssize_t
+ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count)
+{
+ int index;
+ AR_SOFTC_T *ar;
+ HIF_DEVICE_OS_DEVICE_INFO *osDevInfo;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (A_UINT32)count));
+ for (index=0; index < MAX_AR6000; index++) {
+ ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]);
+ osDevInfo = &ar->osDevInfo;
+ if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) {
+ break;
+ }
+ }
+
+ if (index == MAX_AR6000) return 0;
+
+ if ((BMIRawWrite(ar->arHifDevice, (A_UCHAR*)buf, count)) != A_OK) {
+ return 0;
+ }
+
+ return count;
+}
+
+static A_STATUS
+ar6000_sysfs_bmi_init(AR_SOFTC_T *ar)
+{
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n"));
+ A_MEMZERO(&ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO));
+
+ /* Get the underlying OS device */
+ status = HIFConfigureDevice(ar->arHifDevice,
+ HIF_DEVICE_GET_OS_DEVICE,
+ &ar->osDevInfo,
+ sizeof(HIF_DEVICE_OS_DEVICE_INFO));
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n"));
+ return A_ERROR;
+ }
+
+ /* Create a bmi entry in the sysfs filesystem */
+ if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n"));
+ return A_ERROR;
+ }
+
+ return A_OK;
+}
+
+static void
+ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n"));
+
+ sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr);
+}
+
+#define bmifn(fn) do { \
+ if ((fn) < A_OK) { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \
+ return A_ERROR; \
+ } \
+} while(0)
+
+#ifdef INIT_MODE_DRV_ENABLED
+
+#ifdef SOFTMAC_FILE_USED
+#define AR6002_MAC_ADDRESS_OFFSET 0x0A
+#define AR6003_MAC_ADDRESS_OFFSET 0x16
+static
+void calculate_crc(A_UINT32 TargetType, A_UCHAR *eeprom_data)
+{
+ A_UINT16 *ptr_crc;
+ A_UINT16 *ptr16_eeprom;
+ A_UINT16 checksum;
+ A_UINT32 i;
+ A_UINT32 eeprom_size;
+
+ if (TargetType == TARGET_TYPE_AR6001)
+ {
+ eeprom_size = 512;
+ ptr_crc = (A_UINT16 *)eeprom_data;
+ }
+ else if (TargetType == TARGET_TYPE_AR6003)
+ {
+ eeprom_size = 1024;
+ ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04);
+ }
+ else
+ {
+ eeprom_size = 768;
+ ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04);
+ }
+
+
+ // Clear the crc
+ *ptr_crc = 0;
+
+ // Recalculate new CRC
+ checksum = 0;
+ ptr16_eeprom = (A_UINT16 *)eeprom_data;
+ for (i = 0;i < eeprom_size; i += 2)
+ {
+ checksum = checksum ^ (*ptr16_eeprom);
+ ptr16_eeprom++;
+ }
+ checksum = 0xFFFF ^ checksum;
+ *ptr_crc = checksum;
+}
+
+static void
+ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size)
+{
+ const char *source = "random generated";
+ const struct firmware *softmac_entry;
+ A_UCHAR *ptr_mac;
+ switch (ar->arTargetType) {
+ case TARGET_TYPE_AR6002:
+ ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET);
+ break;
+ case TARGET_TYPE_AR6003:
+ ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET);
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Target Type \n"));
+ return;
+ }
+ printk("MAC from EEPROM %02X:%02X:%02X:%02X:%02X:%02X\n",
+ ptr_mac[0], ptr_mac[1], ptr_mac[2],
+ ptr_mac[3], ptr_mac[4], ptr_mac[5]);
+
+ /* create a random MAC in case we cannot read file from system */
+ ptr_mac[0] = 0;
+ ptr_mac[1] = 0x03;
+ ptr_mac[2] = 0x7F;
+ ptr_mac[3] = random32() & 0xff;
+ ptr_mac[4] = random32() & 0xff;
+ ptr_mac[5] = random32() & 0xff;
+ if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0)
+ {
+ A_CHAR *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1);
+ if (macbuf) {
+ unsigned int softmac[6];
+ memcpy(macbuf, softmac_entry->data, softmac_entry->size);
+ macbuf[softmac_entry->size] = '\0';
+ if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x",
+ &softmac[0], &softmac[1], &softmac[2],
+ &softmac[3], &softmac[4], &softmac[5])==6) {
+ int i;
+ for (i=0; i<6; ++i) {
+ ptr_mac[i] = softmac[i] & 0xff;
+ }
+ source = "softmac file";
+ }
+ A_FREE(macbuf);
+ }
+ A_RELEASE_FIRMWARE(softmac_entry);
+ }
+ printk("MAC from %s %02X:%02X:%02X:%02X:%02X:%02X\n", source,
+ ptr_mac[0], ptr_mac[1], ptr_mac[2],
+ ptr_mac[3], ptr_mac[4], ptr_mac[5]);
+ calculate_crc(ar->arTargetType, eeprom_data);
+}
+#endif /* SOFTMAC_FILE_USED */
+
+static A_STATUS
+ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A_BOOL compressed)
+{
+ A_STATUS status;
+ const char *filename;
+ const struct firmware *fw_entry;
+ A_UINT32 fw_entry_size;
+
+ switch (file) {
+ case AR6K_OTP_FILE:
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_OTP_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_OTP_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ break;
+
+ case AR6K_FIRMWARE_FILE:
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_FIRMWARE_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_FIRMWARE_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+
+ if (eppingtest) {
+ bypasswmi = TRUE;
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n",
+ ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ compressed = 0;
+ }
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ if(testmode) {
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ compressed = 0;
+ }
+#endif
+#ifdef HTC_RAW_INTERFACE
+ if (!eppingtest && bypasswmi) {
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_ART_FIRMWARE_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_ART_FIRMWARE_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ compressed = 0;
+ }
+#endif
+ break;
+
+ case AR6K_PATCH_FILE:
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_PATCH_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_PATCH_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ break;
+
+ case AR6K_BOARD_DATA_FILE:
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ filename = AR6003_REV1_BOARD_DATA_FILE;
+ } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ filename = AR6003_REV2_BOARD_DATA_FILE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
+ return A_ERROR;
+ }
+ break;
+
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
+ return A_ERROR;
+ }
+ if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
+ return A_ENOENT;
+ }
+
+#ifdef SOFTMAC_FILE_USED
+ if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) {
+ ar6000_softmac_update(ar, (A_UCHAR *)fw_entry->data, fw_entry->size);
+ }
+#endif
+
+
+ fw_entry_size = fw_entry->size;
+
+ /* Load extended board data for AR6003 */
+ if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) {
+ A_UINT32 board_ext_address;
+ A_UINT32 board_ext_data_size;
+ A_UINT32 board_data_size;
+
+ board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0));
+
+ board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0));
+
+ /* Determine where in Target RAM to write Board Data */
+ bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (A_UCHAR *)&board_ext_address, 4));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
+
+ /* check whether the target has allocated memory for extended board data and file contains extended board data */
+ if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) {
+ A_UINT32 param;
+
+ status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(((A_UINT32)fw_entry->data) + board_data_size), board_ext_data_size);
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
+ A_RELEASE_FIRMWARE(fw_entry);
+ return A_ERROR;
+ }
+
+ /* Record the fact that extended board Data IS initialized */
+ param = 1;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (A_UCHAR *)&param, 4));
+ }
+ fw_entry_size = board_data_size;
+ }
+
+ if (compressed) {
+ status = BMIFastDownload(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size);
+ } else {
+ status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size);
+ }
+
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
+ A_RELEASE_FIRMWARE(fw_entry);
+ return A_ERROR;
+ }
+ A_RELEASE_FIRMWARE(fw_entry);
+ return A_OK;
+}
+#endif /* INIT_MODE_DRV_ENABLED */
+
+A_STATUS
+ar6000_update_bdaddr(AR_SOFTC_T *ar)
+{
+
+ if (setupbtdev != 0) {
+ A_UINT32 address;
+
+ if (BMIReadMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n"));
+ return A_ERROR;
+ }
+
+ if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (A_UCHAR *)ar->bdaddr, 6) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n"));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0],
+ ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3],
+ ar->bdaddr[4], ar->bdaddr[5]));
+ }
+
+return A_OK;
+}
+
+A_STATUS
+ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n"));
+
+ if (mode == WLAN_INIT_MODE_UDEV) {
+ A_CHAR version[16];
+ const struct firmware *fw_entry;
+
+ /* Get config using udev through a script in user space */
+ sprintf(version, "%2.2x", ar->arVersion.target_ver);
+ if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version));
+ return A_ERROR;
+ }
+
+ A_RELEASE_FIRMWARE(fw_entry);
+#ifdef INIT_MODE_DRV_ENABLED
+ } else {
+ /* The config is contained within the driver itself */
+ A_STATUS status;
+ A_UINT32 param, options, sleep, address;
+
+ /* Temporarily disable system sleep */
+ address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+ bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
+ options = param;
+ param |= AR6K_OPTION_SLEEP_DISABLE;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+ bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
+ sleep = param;
+ param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1);
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep));
+
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ /* Program analog PLL register */
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001));
+ /* Run at 80/88MHz by default */
+ param = CPU_CLOCK_STANDARD_SET(1);
+ } else {
+ /* Run at 40/44MHz by default */
+ param = CPU_CLOCK_STANDARD_SET(0);
+ }
+ address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ param = 0;
+ if (ar->arTargetType == TARGET_TYPE_AR6002) {
+ bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)&param, 4));
+ }
+
+ /* LPO_CAL.ENABLE = 1 if no external clk is detected */
+ if (param != 1) {
+ address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
+ param = LPO_CAL_ENABLE_SET(1);
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+ }
+
+ /* Venus2.0: Lower SDIO pad drive strength,
+ * temporary WAR to avoid SDIO CRC error */
+ if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n"));
+ param = 0x20;
+ address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+ }
+
+#ifdef FORCE_INTERNAL_CLOCK
+ /* Ignore external clock, if any, and force use of internal clock */
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ /* hi_ext_clk_detected = 0 */
+ param = 0;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)&param, 4));
+
+ /* CLOCK_CONTROL &= ~LF_CLK32 */
+ address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS;
+ bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
+ param &= (~CLOCK_CONTROL_LF_CLK32_SET(1));
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+ }
+#endif /* FORCE_INTERNAL_CLOCK */
+
+ /* Transfer Board Data from Target EEPROM to Target RAM */
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ /* Determine where in Target RAM to write Board Data */
+ bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address));
+
+ /* Write EEPROM data to Target RAM */
+ if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, FALSE)) != A_OK) {
+ return A_ERROR;
+ }
+
+ /* Record the fact that Board Data IS initialized */
+ param = 1;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (A_UCHAR *)&param, 4));
+
+ /* Transfer One time Programmable data */
+ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
+ status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, TRUE);
+ if (status == A_OK) {
+ /* Execute the OTP code */
+ param = 0;
+ AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
+ bmifn(BMIExecute(ar->arHifDevice, address, &param));
+ } else if (status != A_ENOENT) {
+ return A_ERROR;
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType));
+ return A_ERROR;
+ }
+
+ /* Download Target firmware */
+ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
+ if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, TRUE)) != A_OK) {
+ return A_ERROR;
+ }
+
+ /* Set starting address for firmware */
+ AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
+ bmifn(BMISetAppStart(ar->arHifDevice, address));
+
+ /* Apply the patches */
+ AR6K_PATCH_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
+ if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, FALSE)) != A_OK) {
+ return A_ERROR;
+ }
+
+ param = address;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), (A_UCHAR *)&param, 4));
+
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
+ /* Reserve 5.5K of RAM */
+ param = 5632;
+ } else { /* AR6003_REV2_VERSION */
+ /* Reserve 6.5K of RAM */
+ param = 6656;
+ }
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (A_UCHAR *)&param, 4));
+ }
+
+ /* Restore system sleep */
+ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep));
+
+ address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+ param = options | 0x20;
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ /* Configure GPIO AR6003 UART */
+#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN
+#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
+#endif
+ param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (A_UCHAR *)&param, 4));
+
+#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23)
+ {
+ address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS;
+ bmifn(BMIReadSOCRegister(ar->arHifDevice, address, &param));
+ param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1);
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param));
+ }
+#endif
+
+ /* Configure GPIO for BT Reset */
+#ifdef ATH6KL_CONFIG_GPIO_BT_RESET
+#define CONFIG_AR600x_BT_RESET_PIN 0x16
+ param = CONFIG_AR600x_BT_RESET_PIN;
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (A_UCHAR *)&param, 4));
+#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */
+
+ /* Configure UART flow control polarity */
+#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY
+#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0
+#endif
+
+#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1)
+ if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+ param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2);
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (A_UCHAR *)&param, 4));
+ }
+#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */
+ }
+
+#ifdef HTC_RAW_INTERFACE
+ if (!eppingtest && bypasswmi) {
+ /* Don't run BMIDone for ART mode and force resetok=0 */
+ resetok = 0;
+ msleep(1000);
+ }
+#endif /* HTC_RAW_INTERFACE */
+
+#endif /* INIT_MODE_DRV_ENABLED */
+ }
+
+ return A_OK;
+}
+
+A_STATUS
+ar6000_configure_target(AR_SOFTC_T *ar)
+{
+ A_UINT32 param;
+ if (enableuartprint) {
+ param = 1;
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable),
+ (A_UCHAR *)&param,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n"));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n"));
+ }
+
+ /* Tell target which HTC version it is used*/
+ param = HTC_PROTOCOL_VERSION;
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest),
+ (A_UCHAR *)&param,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n"));
+ return A_ERROR;
+ }
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ if(testmode) {
+ ar->arTargetMode = AR6000_TCMD_MODE;
+ }else {
+ ar->arTargetMode = AR6000_WLAN_MODE;
+ }
+#endif
+ if (enabletimerwar) {
+ A_UINT32 param;
+
+ if (BMIReadMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n"));
+ return A_ERROR;
+ }
+
+ param |= HI_OPTION_TIMER_WAR;
+
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n"));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n"));
+ }
+
+ /* set the firmware mode to STA/IBSS/AP */
+ {
+ A_UINT32 param;
+
+ if (BMIReadMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n"));
+ return A_ERROR;
+ }
+
+ param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
+
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n"));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
+ }
+
+#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS
+ {
+ A_UINT32 param;
+
+ if (BMIReadMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4)!= A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n"));
+ return A_ERROR;
+ }
+
+ param |= HI_OPTION_DISABLE_DBGLOG;
+
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
+ (A_UCHAR *)&param,
+ 4) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n"));
+ return A_ERROR;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n"));
+ }
+#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */
+
+ /*
+ * Hardcode the address use for the extended board data
+ * Ideally this should be pre-allocate by the OS at boot time
+ * But since it is a new feature and board data is loaded
+ * at init time, we have to workaround this from host.
+ * It is difficult to patch the firmware boot code,
+ * but possible in theory.
+ */
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ param = AR6003_BOARD_EXT_DATA_ADDRESS;
+ if (BMIWriteMemory(ar->arHifDevice,
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
+ (A_UCHAR *)&param,
+ 4) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n"));
+ return A_ERROR;
+ }
+ }
+
+
+ /* since BMIInit is called in the driver layer, we have to set the block
+ * size here for the target */
+
+ if (A_FAILED(ar6000_set_htc_params(ar->arHifDevice,
+ ar->arTargetType,
+ mbox_yield_limit,
+ 0 /* use default number of control buffers */
+ ))) {
+ return A_ERROR;
+ }
+
+ if (setupbtdev != 0) {
+ if (A_FAILED(ar6000_set_hci_bridge_flags(ar->arHifDevice,
+ ar->arTargetType,
+ setupbtdev))) {
+ return A_ERROR;
+ }
+ }
+ return A_OK;
+}
+
+static void
+init_netdev(struct net_device *dev, char *name)
+{
+ dev->netdev_ops = &ar6000_netdev_ops;
+ dev->watchdog_timeo = AR6000_TX_TIMEOUT;
+ dev->wireless_handlers = &ath_iw_handler_def;
+
+ ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
+
+ /*
+ * We need the OS to provide us with more headroom in order to
+ * perform dix to 802.3, WMI header encap, and the HTC header
+ */
+ if (processDot11Hdr) {
+ dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
+ } else {
+ dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) +
+ sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR;
+ }
+
+ if (name[0])
+ {
+ strcpy(dev->name, name);
+ }
+
+#ifdef SET_MODULE_OWNER
+ SET_MODULE_OWNER(dev);
+#endif
+
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ if(csumOffload){
+ dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
+ }
+#endif
+
+ return;
+}
+
+/*
+ * HTC Event handlers
+ */
+static A_STATUS
+ar6000_avail_ev(void *context, void *hif_handle)
+{
+ int i;
+ struct net_device *dev;
+ void *ar_netif;
+ AR_SOFTC_T *ar;
+ int device_index = 0;
+ HTC_INIT_INFO htcInfo;
+#ifdef ATH6K_CONFIG_CFG80211
+ struct wireless_dev *wdev;
+#endif /* ATH6K_CONFIG_CFG80211 */
+ A_STATUS init_status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n"));
+
+ for (i=0; i < MAX_AR6000; i++) {
+ if (ar6000_devices[i] == NULL) {
+ break;
+ }
+ }
+
+ if (i == MAX_AR6000) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n"));
+ return A_ERROR;
+ }
+
+ /* Save this. It gives a bit better readability especially since */
+ /* we use another local "i" variable below. */
+ device_index = i;
+
+#ifdef ATH6K_CONFIG_CFG80211
+ wdev = ar6k_cfg80211_init(NULL);
+ if (IS_ERR(wdev)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
+ return A_ERROR;
+ }
+ ar_netif = wdev_priv(wdev);
+#else
+ dev = alloc_etherdev(sizeof(AR_SOFTC_T));
+ if (dev == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n"));
+ return A_ERROR;
+ }
+ ether_setup(dev);
+ ar_netif = ar6k_priv(dev);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ if (ar_netif == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
+ return A_ERROR;
+ }
+
+ A_MEMZERO(ar_netif, sizeof(AR_SOFTC_T));
+ ar = (AR_SOFTC_T *)ar_netif;
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar->wdev = wdev;
+ wdev->iftype = NL80211_IFTYPE_STATION;
+
+ dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1);
+ if (!dev) {
+ printk(KERN_CRIT "AR6K: no memory for network device instance\n");
+ ar6k_cfg80211_deinit(ar);
+ return A_ERROR;
+ }
+
+ dev->ieee80211_ptr = wdev;
+ SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+ wdev->netdev = dev;
+ ar->arNetworkType = INFRA_NETWORK;
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ init_netdev(dev, ifname);
+
+#ifdef SET_NETDEV_DEV
+ if (ar_netif) {
+ HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
+ A_MEMZERO(&osDevInfo, sizeof(osDevInfo));
+ if ( A_SUCCESS( HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE,
+ &osDevInfo, sizeof(osDevInfo))) ) {
+ SET_NETDEV_DEV(dev, osDevInfo.pOSDevice);
+ }
+ }
+#endif
+
+ ar->arNetDev = dev;
+ ar->arHifDevice = hif_handle;
+ ar->arWlanState = WLAN_ENABLED;
+ ar->arDeviceIndex = device_index;
+
+ ar->arWlanPowerState = WLAN_POWER_STATE_ON;
+ ar->arWlanOff = FALSE; /* We are in ON state */
+#ifdef CONFIG_PM
+ ar->arWowState = WLAN_WOW_STATE_NONE;
+ ar->arBTOff = TRUE; /* BT chip assumed to be OFF */
+ ar->arBTSharing = WLAN_CONFIG_BT_SHARING;
+ ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF;
+ ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND;
+ ar->arWow2Config = WLAN_CONFIG_PM_WOW2;
+#endif /* CONFIG_PM */
+
+ A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);
+ ar->arHBChallengeResp.seqNum = 0;
+ ar->arHBChallengeResp.outstanding = FALSE;
+ ar->arHBChallengeResp.missCnt = 0;
+ ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;
+ ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;
+
+ ar6000_init_control_info(ar);
+ init_waitqueue_head(&arEvent);
+ sema_init(&ar->arSem, 1);
+ ar->bIsDestroyProgress = FALSE;
+
+ INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue);
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+ A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+ A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev);
+
+ BMIInit();
+
+ if (bmienable) {
+ ar6000_sysfs_bmi_init(ar);
+ }
+
+ {
+ struct bmi_target_info targ_info;
+
+ if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) {
+ init_status = A_ERROR;
+ goto avail_ev_failed;
+ }
+
+ ar->arVersion.target_ver = targ_info.target_ver;
+ ar->arTargetType = targ_info.target_type;
+
+ /* do any target-specific preparation that can be done through BMI */
+ if (ar6000_prepare_target(ar->arHifDevice,
+ targ_info.target_type,
+ targ_info.target_ver) != A_OK) {
+ init_status = A_ERROR;
+ goto avail_ev_failed;
+ }
+
+ }
+
+ if (ar6000_configure_target(ar) != A_OK) {
+ init_status = A_ERROR;
+ goto avail_ev_failed;
+ }
+
+ A_MEMZERO(&htcInfo,sizeof(htcInfo));
+ htcInfo.pContext = ar;
+ htcInfo.TargetFailure = ar6000_target_failure;
+
+ ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
+
+ if (ar->arHtcTarget == NULL) {
+ init_status = A_ERROR;
+ goto avail_ev_failed;
+ }
+
+ spin_lock_init(&ar->arLock);
+
+#ifdef WAPI_ENABLE
+ ar->arWapiEnable = 0;
+#endif
+
+
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ if(csumOffload){
+ /*if external frame work is also needed, change and use an extended rxMetaVerion*/
+ ar->rxMetaVersion=WMI_META_VERSION_2;
+ }
+#endif
+
+#ifdef ATH_AR6K_11N_SUPPORT
+ if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
+ init_status = A_ERROR;
+ goto avail_ev_failed;
+ }
+
+ aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
+#endif
+
+ HIFClaimDevice(ar->arHifDevice, ar);
+
+ /* We only register the device in the global list if we succeed. */
+ /* If the device is in the global list, it will be destroyed */
+ /* when the module is unloaded. */
+ ar6000_devices[device_index] = dev;
+
+ /* Don't install the init function if BMI is requested */
+ if (!bmienable) {
+ ar6000_netdev_ops.ndo_init = ar6000_init;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
+ if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
+ (wlaninitmode == WLAN_INIT_MODE_DRV))
+ {
+ A_STATUS status = A_OK;
+ do {
+ if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
+ break;
+ }
+#ifdef HTC_RAW_INTERFACE
+ break; /* Don't call ar6000_init for ART */
+#endif
+ rtnl_lock();
+ status = (ar6000_init(dev)==0) ? A_OK : A_ERROR;
+ rtnl_unlock();
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
+ }
+ } while (FALSE);
+
+ if (status != A_OK) {
+ init_status = status;
+ goto avail_ev_failed;
+ }
+ }
+ }
+
+ /* This runs the init function if registered */
+ if (register_netdev(dev)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
+ ar6000_destroy(dev, 0);
+ return A_ERROR;
+ }
+
+ is_netdev_registered = 1;
+
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+ arApNetDev = NULL;
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n",
+ dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index,
+ (unsigned long)ar));
+
+avail_ev_failed :
+ if (A_FAILED(init_status)) {
+ if (bmienable) {
+ ar6000_sysfs_bmi_deinit(ar);
+ }
+ }
+
+ return init_status;
+}
+
+static void ar6000_target_failure(void *Instance, A_STATUS Status)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
+ WMI_TARGET_ERROR_REPORT_EVENT errEvent;
+ static A_BOOL sip = FALSE;
+
+ if (Status != A_OK) {
+
+ printk(KERN_ERR "ar6000_target_failure: target asserted \n");
+
+ if (timer_pending(&ar->arHBChallengeResp.timer)) {
+ A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
+ }
+
+ /* try dumping target assertion information (if any) */
+ ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType);
+
+ /*
+ * Fetch the logs from the target via the diagnostic
+ * window.
+ */
+ ar6000_dbglog_get_debug_logs(ar);
+
+ /* Report the error only once */
+ if (!sip) {
+ sip = TRUE;
+ errEvent.errorVal = WMI_TARGET_COM_ERR |
+ WMI_TARGET_FATAL_ERR;
+ ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
+ (A_UINT8 *)&errEvent,
+ sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
+ }
+ }
+}
+
+static A_STATUS
+ar6000_unavail_ev(void *context, void *hif_handle)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
+ /* NULL out it's entry in the global list */
+ ar6000_devices[ar->arDeviceIndex] = NULL;
+ ar6000_destroy(ar->arNetDev, 1);
+
+ return A_OK;
+}
+
+void
+ar6000_restart_endpoint(struct net_device *dev)
+{
+ A_STATUS status = A_OK;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ BMIInit();
+ do {
+ if ( (status=ar6000_configure_target(ar))!=A_OK)
+ break;
+ if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
+ break;
+ }
+ rtnl_lock();
+ status = (ar6000_init(dev)==0) ? A_OK : A_ERROR;
+ rtnl_unlock();
+
+ if (status!=A_OK) {
+ break;
+ }
+ if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) {
+ ar6000_connect_to_ap(ar);
+ }
+ } while (0);
+
+ if (status==A_OK) {
+ return;
+ }
+
+ ar6000_devices[ar->arDeviceIndex] = NULL;
+ ar6000_destroy(ar->arNetDev, 1);
+}
+
+void
+ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ /* Stop the transmit queues */
+ netif_stop_queue(dev);
+
+ /* Disable the target and the interrupts associated with it */
+ if (ar->arWmiReady == TRUE)
+ {
+ if (!bypasswmi)
+ {
+ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__));
+ if (!keepprofile) {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar6000_init_profile_info(ar);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+ wmi_disconnect_cmd(ar->arWmi);
+ }
+
+ A_UNTIMEOUT(&ar->disconnect_timer);
+
+ if (getdbglogs) {
+ ar6000_dbglog_get_debug_logs(ar);
+ }
+
+ ar->arWmiReady = FALSE;
+ wmi_shutdown(ar->arWmi);
+ ar->arWmiEnabled = FALSE;
+ ar->arWmi = NULL;
+ /*
+ * After wmi_shudown all WMI events will be dropped.
+ * We need to cleanup the buffers allocated in AP mode
+ * and give disconnect notification to stack, which usually
+ * happens in the disconnect_event.
+ * Simulate the disconnect_event by calling the function directly.
+ * Sometimes disconnect_event will be received when the debug logs
+ * are collected.
+ */
+ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
+ if(ar->arNetworkType & AP_NETWORK) {
+ ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0);
+ } else {
+ ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
+ }
+ ar->arConnected = FALSE;
+ ar->arConnectPending = FALSE;
+ }
+#ifdef USER_KEYS
+ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
+ ar->user_key_ctrl = 0;
+#endif
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
+ }
+ else
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n",
+ __func__, (unsigned long) ar, (unsigned long) ar->arWmi));
+
+ /* Shut down WMI if we have started it */
+ if(ar->arWmiEnabled == TRUE)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__));
+ wmi_shutdown(ar->arWmi);
+ ar->arWmiEnabled = FALSE;
+ ar->arWmi = NULL;
+ }
+ }
+
+ if (ar->arHtcTarget != NULL) {
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ if (NULL != ar6kHciTransCallbacks.cleanupTransport) {
+ ar6kHciTransCallbacks.cleanupTransport(NULL);
+ }
+#else
+ // FIXME: workaround to reset BT's UART baud rate to default
+ if (NULL != ar->exitCallback) {
+ AR3K_CONFIG_INFO ar3kconfig;
+ A_STATUS status;
+
+ A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
+ ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig);
+ status = ar->exitCallback(&ar3kconfig);
+ if (A_OK != status) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n"));
+ }
+ }
+ // END workaround
+ if (setuphci)
+ ar6000_cleanup_hci(ar);
+#endif
+#ifdef EXPORT_HCI_PAL_INTERFACE
+ if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.cleanupTransport)) {
+ ar6kHciPalCallbacks_g.cleanupTransport(ar);
+ }
+#else
+ /* cleanup hci pal driver data structures */
+ if(setuphcipal)
+ ar6k_cleanup_hci_pal(ar);
+#endif
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
+ /* stop HTC */
+ HTCStop(ar->arHtcTarget);
+ }
+
+ if (resetok) {
+ /* try to reset the device if we can
+ * The driver may have been configure NOT to reset the target during
+ * a debug session */
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n"));
+ if (ar->arHifDevice != NULL) {
+ A_BOOL coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? TRUE: FALSE;
+ ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, coldReset);
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n"));
+ }
+ /* Done with cookies */
+ ar6000_cookie_cleanup(ar);
+}
+/*
+ * We need to differentiate between the surprise and planned removal of the
+ * device because of the following consideration:
+ * - In case of surprise removal, the hcd already frees up the pending
+ * for the device and hence there is no need to unregister the function
+ * driver inorder to get these requests. For planned removal, the function
+ * driver has to explictly unregister itself to have the hcd return all the
+ * pending requests before the data structures for the devices are freed up.
+ * Note that as per the current implementation, the function driver will
+ * end up releasing all the devices since there is no API to selectively
+ * release a particular device.
+ * - Certain commands issued to the target can be skipped for surprise
+ * removal since they will anyway not go through.
+ */
+void
+ar6000_destroy(struct net_device *dev, unsigned int unregister)
+{
+ AR_SOFTC_T *ar;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n"));
+
+ if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__));
+ return;
+ }
+
+ ar->bIsDestroyProgress = TRUE;
+
+ if (down_interruptible(&ar->arSem)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__));
+ return;
+ }
+
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
+ /* only stop endpoint if we are not stop it in suspend_ev */
+ ar6000_stop_endpoint(dev, FALSE, TRUE);
+ } else {
+ /* clear up the platform power state before rmmod */
+ plat_setup_power(1,0);
+ }
+
+ ar->arWlanState = WLAN_DISABLED;
+ if (ar->arHtcTarget != NULL) {
+ /* destroy HTC */
+ HTCDestroy(ar->arHtcTarget);
+ }
+ if (ar->arHifDevice != NULL) {
+ /*release the device so we do not get called back on remove incase we
+ * we're explicity destroyed by module unload */
+ HIFReleaseDevice(ar->arHifDevice);
+ HIFShutDownDevice(ar->arHifDevice);
+ }
+#ifdef ATH_AR6K_11N_SUPPORT
+ aggr_module_destroy(ar->aggr_cntxt);
+#endif
+
+ /* Done with cookies */
+ ar6000_cookie_cleanup(ar);
+
+ /* cleanup any allocated AMSDU buffers */
+ ar6000_cleanup_amsdu_rxbufs(ar);
+
+ if (bmienable) {
+ ar6000_sysfs_bmi_deinit(ar);
+ }
+
+ /* Cleanup BMI */
+ BMICleanup();
+
+ /* Clear the tx counters */
+ memset(tx_attempt, 0, sizeof(tx_attempt));
+ memset(tx_post, 0, sizeof(tx_post));
+ memset(tx_complete, 0, sizeof(tx_complete));
+
+#ifdef HTC_RAW_INTERFACE
+ if (ar->arRawHtc) {
+ A_FREE(ar->arRawHtc);
+ ar->arRawHtc = NULL;
+ }
+#endif
+ /* Free up the device data structure */
+ if (unregister && is_netdev_registered) {
+ unregister_netdev(dev);
+ is_netdev_registered = 0;
+ }
+#ifndef free_netdev
+ kfree(dev);
+#else
+ free_netdev(dev);
+#endif
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar6k_cfg80211_deinit(ar);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
+ ar6000_remove_ap_interface();
+#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
+}
+
+static void disconnect_timer_handler(unsigned long ptr)
+{
+ struct net_device *dev = (struct net_device *)ptr;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ A_UNTIMEOUT(&ar->disconnect_timer);
+
+ ar6000_init_profile_info(ar);
+ wmi_disconnect_cmd(ar->arWmi);
+}
+
+static void ar6000_detect_error(unsigned long ptr)
+{
+ struct net_device *dev = (struct net_device *)ptr;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_TARGET_ERROR_REPORT_EVENT errEvent;
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ if (ar->arHBChallengeResp.outstanding) {
+ ar->arHBChallengeResp.missCnt++;
+ } else {
+ ar->arHBChallengeResp.missCnt = 0;
+ }
+
+ if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) {
+ /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */
+ ar->arHBChallengeResp.missCnt = 0;
+ ar->arHBChallengeResp.seqNum = 0;
+ errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
+ (A_UINT8 *)&errEvent,
+ sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
+ return;
+ }
+
+ /* Generate the sequence number for the next challenge */
+ ar->arHBChallengeResp.seqNum++;
+ ar->arHBChallengeResp.outstanding = TRUE;
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ /* Send the challenge on the control channel */
+ if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n"));
+ }
+
+
+ /* Reschedule the timer for the next challenge */
+ A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
+}
+
+void ar6000_init_profile_info(AR_SOFTC_T *ar)
+{
+ ar->arSsidLen = 0;
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+
+ switch(fwmode) {
+ case HI_OPTION_FW_MODE_IBSS:
+ ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK;
+ break;
+ case HI_OPTION_FW_MODE_BSS_STA:
+ ar->arNetworkType = ar->arNextMode = INFRA_NETWORK;
+ break;
+ case HI_OPTION_FW_MODE_AP:
+ ar->arNetworkType = ar->arNextMode = AP_NETWORK;
+ break;
+ }
+
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arAuthMode = NONE_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+ ar->arBssChannel = 0;
+ ar->arConnected = FALSE;
+}
+
+static void
+ar6000_init_control_info(AR_SOFTC_T *ar)
+{
+ ar->arWmiEnabled = FALSE;
+ ar6000_init_profile_info(ar);
+ ar->arDefTxKeyIndex = 0;
+ A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
+ ar->arChannelHint = 0;
+ ar->arListenIntervalT = A_DEFAULT_LISTEN_INTERVAL;
+ ar->arListenIntervalB = 0;
+ ar->arVersion.host_ver = AR6K_SW_VERSION;
+ ar->arRssi = 0;
+ ar->arTxPwr = 0;
+ ar->arTxPwrSet = FALSE;
+ ar->arSkipScan = 0;
+ ar->arBeaconInterval = 0;
+ ar->arBitRate = 0;
+ ar->arMaxRetries = 0;
+ ar->arWmmEnabled = TRUE;
+ ar->intra_bss = 1;
+ ar->scan_triggered = 0;
+ A_MEMZERO(&ar->scParams, sizeof(ar->scParams));
+ ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT;
+ ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS;
+
+ /* Initialize the AP mode state info */
+ {
+ A_UINT8 ctr;
+ A_MEMZERO((A_UINT8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t));
+
+ /* init the Mutexes */
+ A_MUTEX_INIT(&ar->mcastpsqLock);
+
+ /* Init the PS queues */
+ for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) {
+ A_MUTEX_INIT(&ar->sta_list[ctr].psqLock);
+ A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq);
+ }
+
+ ar->ap_profile_flag = 0;
+ A_NETBUF_QUEUE_INIT(&ar->mcastpsq);
+
+ A_MEMCPY(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+ ar->ap_wmode = DEF_AP_WMODE_G;
+ ar->ap_dtim_period = DEF_AP_DTIM;
+ ar->ap_beacon_interval = DEF_BEACON_INTERVAL;
+ }
+}
+
+static int
+ar6000_open(struct net_device *dev)
+{
+ unsigned long flags;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ spin_lock_irqsave(&ar->arLock, flags);
+
+#ifdef ATH6K_CONFIG_CFG80211
+ if(ar->arWlanState == WLAN_DISABLED) {
+ ar->arWlanState = WLAN_ENABLED;
+ }
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ if( ar->arConnected || bypasswmi) {
+ netif_carrier_on(dev);
+ /* Wake up the queues */
+ netif_wake_queue(dev);
+ }
+ else
+ netif_carrier_off(dev);
+
+ spin_unlock_irqrestore(&ar->arLock, flags);
+ return 0;
+}
+
+static int
+ar6000_close(struct net_device *dev)
+{
+#ifdef ATH6K_CONFIG_CFG80211
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+#endif /* ATH6K_CONFIG_CFG80211 */
+ netif_stop_queue(dev);
+
+#ifdef ATH6K_CONFIG_CFG80211
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ wmi_disconnect_cmd(ar->arWmi);
+ } else {
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+
+ if(ar->arWmiReady == TRUE) {
+ if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0) != A_OK) {
+ return -EIO;
+ }
+ ar->arWlanState = WLAN_DISABLED;
+ }
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ return 0;
+}
+
+/* connect to a service */
+static A_STATUS ar6000_connectservice(AR_SOFTC_T *ar,
+ HTC_SERVICE_CONNECT_REQ *pConnect,
+ char *pDesc)
+{
+ A_STATUS status;
+ HTC_SERVICE_CONNECT_RESP response;
+
+ do {
+
+ A_MEMZERO(&response,sizeof(response));
+
+ status = HTCConnectService(ar->arHtcTarget,
+ pConnect,
+ &response);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n",
+ pDesc, status));
+ break;
+ }
+ switch (pConnect->ServiceID) {
+ case WMI_CONTROL_SVC :
+ if (ar->arWmiEnabled) {
+ /* set control endpoint for WMI use */
+ wmi_set_control_ep(ar->arWmi, response.Endpoint);
+ }
+ /* save EP for fast lookup */
+ ar->arControlEp = response.Endpoint;
+ break;
+ case WMI_DATA_BE_SVC :
+ arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint);
+ break;
+ case WMI_DATA_BK_SVC :
+ arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint);
+ break;
+ case WMI_DATA_VI_SVC :
+ arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint);
+ break;
+ case WMI_DATA_VO_SVC :
+ arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint);
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID));
+ status = A_EINVAL;
+ break;
+ }
+
+ } while (FALSE);
+
+ return status;
+}
+
+void ar6000_TxDataCleanup(AR_SOFTC_T *ar)
+{
+ /* flush all the data (non-control) streams
+ * we only flush packets that are tagged as data, we leave any control packets that
+ * were in the TX queues alone */
+ HTCFlushEndpoint(ar->arHtcTarget,
+ arAc2EndpointID(ar, WMM_AC_BE),
+ AR6K_DATA_PKT_TAG);
+ HTCFlushEndpoint(ar->arHtcTarget,
+ arAc2EndpointID(ar, WMM_AC_BK),
+ AR6K_DATA_PKT_TAG);
+ HTCFlushEndpoint(ar->arHtcTarget,
+ arAc2EndpointID(ar, WMM_AC_VI),
+ AR6K_DATA_PKT_TAG);
+ HTCFlushEndpoint(ar->arHtcTarget,
+ arAc2EndpointID(ar, WMM_AC_VO),
+ AR6K_DATA_PKT_TAG);
+}
+
+HTC_ENDPOINT_ID
+ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
+ return(arAc2EndpointID(ar, ac));
+}
+
+A_UINT8
+ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep )
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *) devt;
+ return(arEndpoint2Ac(ar, ep ));
+}
+
+/* This function does one time initialization for the lifetime of the device */
+int ar6000_init(struct net_device *dev)
+{
+ AR_SOFTC_T *ar;
+ A_STATUS status;
+ A_INT32 timeleft;
+ A_INT16 i;
+ int ret = 0;
+#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
+ WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
+#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
+
+ if((ar = ar6k_priv(dev)) == NULL)
+ {
+ return -EIO;
+ }
+
+ if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) {
+
+ ar6000_update_bdaddr(ar);
+
+ if (enablerssicompensation) {
+ ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType);
+ read_rssi_compensation_param(ar);
+ for (i=-95; i<=0; i++) {
+ rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i);
+ }
+ }
+ }
+
+ dev_hold(dev);
+ rtnl_unlock();
+
+ /* Do we need to finish the BMI phase */
+ if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) &&
+ (BMIDone(ar->arHifDevice) != A_OK))
+ {
+ ret = -EIO;
+ goto ar6000_init_done;
+ }
+
+ if (!bypasswmi)
+ {
+#if 0 /* TBDXXX */
+ if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
+ A_PRINTF("WARNING: Host version 0x%x does not match Target "
+ " version 0x%x!\n",
+ ar->arVersion.host_ver, ar->arVersion.target_ver);
+ }
+#endif
+
+ /* Indicate that WMI is enabled (although not ready yet) */
+ ar->arWmiEnabled = TRUE;
+ if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__));
+ ret = -EIO;
+ goto ar6000_init_done;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__,
+ (unsigned long) ar->arWmi));
+ }
+
+ do {
+ HTC_SERVICE_CONNECT_REQ connect;
+
+ /* the reason we have to wait for the target here is that the driver layer
+ * has to init BMI in order to set the host block size,
+ */
+ status = HTCWaitTarget(ar->arHtcTarget);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ A_MEMZERO(&connect,sizeof(connect));
+ /* meta data is unused for now */
+ connect.pMetaData = NULL;
+ connect.MetaDataLength = 0;
+ /* these fields are the same for all service endpoints */
+ connect.EpCallbacks.pContext = ar;
+ connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete;
+ connect.EpCallbacks.EpRecv = ar6000_rx;
+ connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill;
+ connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full;
+ /* set the max queue depth so that our ar6000_tx_queue_full handler gets called.
+ * Linux has the peculiarity of not providing flow control between the
+ * NIC and the network stack. There is no API to indicate that a TX packet
+ * was sent which could provide some back pressure to the network stack.
+ * Under linux you would have to wait till the network stack consumed all sk_buffs
+ * before any back-flow kicked in. Which isn't very friendly.
+ * So we have to manage this ourselves */
+ connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
+ connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */
+ if (0 == connect.EpCallbacks.RecvRefillWaterMark) {
+ connect.EpCallbacks.RecvRefillWaterMark++;
+ }
+ /* connect to control service */
+ connect.ServiceID = WMI_CONTROL_SVC;
+ status = ar6000_connectservice(ar,
+ &connect,
+ "WMI CONTROL");
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING;
+ /* limit the HTC message size on the send path, although we can receive A-MSDU frames of
+ * 4K, we will only send ethernet-sized (802.3) frames on the send path. */
+ connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH;
+
+ /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold
+ * mechanism for larger packets */
+ connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE;
+ connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf;
+
+ /* for the remaining data services set the connection flag to reduce dribbling,
+ * if configured to do so */
+ if (reduce_credit_dribble) {
+ connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE;
+ /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value
+ * of 0-3 */
+ connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
+ connect.ConnectionFlags |=
+ ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK;
+ }
+ /* connect to best-effort service */
+ connect.ServiceID = WMI_DATA_BE_SVC;
+
+ status = ar6000_connectservice(ar,
+ &connect,
+ "WMI DATA BE");
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* connect to back-ground
+ * map this to WMI LOW_PRI */
+ connect.ServiceID = WMI_DATA_BK_SVC;
+ status = ar6000_connectservice(ar,
+ &connect,
+ "WMI DATA BK");
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* connect to Video service, map this to
+ * to HI PRI */
+ connect.ServiceID = WMI_DATA_VI_SVC;
+ status = ar6000_connectservice(ar,
+ &connect,
+ "WMI DATA VI");
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* connect to VO service, this is currently not
+ * mapped to a WMI priority stream due to historical reasons.
+ * WMI originally defined 3 priorities over 3 mailboxes
+ * We can change this when WMI is reworked so that priorities are not
+ * dependent on mailboxes */
+ connect.ServiceID = WMI_DATA_VO_SVC;
+ status = ar6000_connectservice(ar,
+ &connect,
+ "WMI DATA VO");
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0);
+ A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0);
+ A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0);
+ A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0);
+
+ /* setup access class priority mappings */
+ ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */
+ ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */
+ ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */
+ ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) {
+ HCI_TRANSPORT_MISC_HANDLES hciHandles;
+
+ hciHandles.netDevice = ar->arNetDev;
+ hciHandles.hifDevice = ar->arHifDevice;
+ hciHandles.htcHandle = ar->arHtcTarget;
+ status = (A_STATUS)(ar6kHciTransCallbacks.setupTransport(&hciHandles));
+ }
+#else
+ if (setuphci) {
+ /* setup HCI */
+ status = ar6000_setup_hci(ar);
+ }
+#endif
+#ifdef EXPORT_HCI_PAL_INTERFACE
+ if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.setupTransport))
+ status = ar6kHciPalCallbacks_g.setupTransport(ar);
+#else
+ if(setuphcipal)
+ status = ar6k_setup_hci_pal(ar);
+#endif
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ ret = -EIO;
+ goto ar6000_init_done;
+ }
+
+ /*
+ * give our connected endpoints some buffers
+ */
+
+ ar6000_rx_refill(ar, ar->arControlEp);
+ ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE));
+
+ /*
+ * We will post the receive buffers only for SPE or endpoint ping testing so we are
+ * making it conditional on the 'bypasswmi' flag.
+ */
+ if (bypasswmi) {
+ ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK));
+ ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI));
+ ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO));
+ }
+
+ /* allocate some buffers that handle larger AMSDU frames */
+ ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS);
+
+ /* setup credit distribution */
+ ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo);
+
+ /* Since cookies are used for HTC transports, they should be */
+ /* initialized prior to enabling HTC. */
+ ar6000_cookie_init(ar);
+
+ /* start HTC */
+ status = HTCStart(ar->arHtcTarget);
+
+ if (status != A_OK) {
+ if (ar->arWmiEnabled == TRUE) {
+ wmi_shutdown(ar->arWmi);
+ ar->arWmiEnabled = FALSE;
+ ar->arWmi = NULL;
+ }
+ ar6000_cookie_cleanup(ar);
+ ret = -EIO;
+ goto ar6000_init_done;
+ }
+
+ if (!bypasswmi) {
+ /* Wait for Wmi event to be ready */
+ timeleft = wait_event_interruptible_timeout(arEvent,
+ (ar->arWmiReady == TRUE), wmitimeout * HZ);
+
+ if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver));
+#ifndef ATH6K_SKIP_ABI_VERSION_CHECK
+ ret = -EIO;
+ goto ar6000_init_done;
+#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */
+ }
+
+ if(!timeleft || signal_pending(current))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n"));
+ ret = -EIO;
+ goto ar6000_init_done;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__));
+
+ /* Communicate the wmi protocol verision to the target */
+ if ((ar6000_set_host_app_area(ar)) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n"));
+ }
+
+ /* configure the device for rx dot11 header rules 0,0 are the default values
+ * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required
+ if checksum offload is needed. Set RxMetaVersion to 2*/
+ if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n"));
+ }
+
+#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
+ /* Configure the type of BT collocated with WLAN */
+ A_MEMZERO(&sbcb_cmd, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
+#ifdef CONFIG_AR600x_BT_QCOM
+ sbcb_cmd.btcoexCoLocatedBTdev = 1;
+#elif defined(CONFIG_AR600x_BT_CSR)
+ sbcb_cmd.btcoexCoLocatedBTdev = 2;
+#elif defined(CONFIG_AR600x_BT_AR3001)
+ sbcb_cmd.btcoexCoLocatedBTdev = 3;
+#else
+#error Unsupported Bluetooth Type
+#endif /* Collocated Bluetooth Type */
+
+ if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n"));
+ }
+
+ /* Configure the type of BT collocated with WLAN */
+ A_MEMZERO(&sbfa_cmd, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
+#ifdef CONFIG_AR600x_DUAL_ANTENNA
+ sbfa_cmd.btcoexFeAntType = 2;
+#elif defined(CONFIG_AR600x_SINGLE_ANTENNA)
+ sbfa_cmd.btcoexFeAntType = 1;
+#else
+#error Unsupported Front-End Antenna Configuration
+#endif /* AR600x Front-End Antenna Configuration */
+
+ if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n"));
+ }
+#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
+ }
+
+ ar->arNumDataEndPts = 1;
+
+ if (bypasswmi) {
+ /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise
+ * the data path through a raw socket is disabled */
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x01;
+ dev->dev_addr[2] = 0x02;
+ dev->dev_addr[3] = 0xAA;
+ dev->dev_addr[4] = 0xBB;
+ dev->dev_addr[5] = 0xCC;
+ }
+
+ar6000_init_done:
+ rtnl_lock();
+ dev_put(dev);
+
+ return ret;
+}
+
+
+void
+ar6000_bitrate_rx(void *devt, A_INT32 rateKbps)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ ar->arBitRate = rateKbps;
+ wake_up(&arEvent);
+}
+
+void
+ar6000_ratemask_rx(void *devt, A_UINT32 ratemask)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ ar->arRateMask = ratemask;
+ wake_up(&arEvent);
+}
+
+void
+ar6000_txPwr_rx(void *devt, A_UINT8 txPwr)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ ar->arTxPwr = txPwr;
+ wake_up(&arEvent);
+}
+
+
+void
+ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16));
+ ar->arNumChannels = numChan;
+
+ wake_up(&arEvent);
+}
+
+A_UINT8
+ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT8 *datap;
+ ATH_MAC_HDR *macHdr;
+ A_UINT32 i, eptMap;
+
+ (*mapNo) = 0;
+ datap = A_NETBUF_DATA(skb);
+ macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
+ if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
+ return ENDPOINT_2;
+ }
+
+ eptMap = -1;
+ for (i = 0; i < ar->arNodeNum; i ++) {
+ if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
+ (*mapNo) = i + 1;
+ ar->arNodeMap[i].txPending ++;
+ return ar->arNodeMap[i].epId;
+ }
+
+ if ((eptMap == -1) && !ar->arNodeMap[i].txPending) {
+ eptMap = i;
+ }
+ }
+
+ if (eptMap == -1) {
+ eptMap = ar->arNodeNum;
+ ar->arNodeNum ++;
+ A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
+ }
+
+ A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
+
+ for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) {
+ if (!ar->arTxPending[i]) {
+ ar->arNodeMap[eptMap].epId = i;
+ break;
+ }
+ // No free endpoint is available, start redistribution on the inuse endpoints.
+ if (i == ENDPOINT_5) {
+ ar->arNodeMap[eptMap].epId = ar->arNexEpId;
+ ar->arNexEpId ++;
+ if (ar->arNexEpId > ENDPOINT_5) {
+ ar->arNexEpId = ENDPOINT_2;
+ }
+ }
+ }
+
+ (*mapNo) = eptMap + 1;
+ ar->arNodeMap[eptMap].txPending ++;
+
+ return ar->arNodeMap[eptMap].epId;
+}
+
+#ifdef DEBUG
+static void ar6000_dump_skb(struct sk_buff *skb)
+{
+ u_char *ch;
+ for (ch = A_NETBUF_DATA(skb);
+ (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) +
+ A_NETBUF_LEN(skb)); ch++)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n"));
+}
+#endif
+
+#ifdef HTC_TEST_SEND_PKTS
+static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb);
+#endif
+
+static int
+ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
+{
+#define AC_NOT_MAPPED 99
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT8 ac = AC_NOT_MAPPED;
+ HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
+ A_UINT32 mapNo = 0;
+ int len;
+ struct ar_cookie *cookie;
+ A_BOOL checkAdHocPsMapping = FALSE,bMoreData = FALSE;
+ HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
+ A_UINT8 dot11Hdr = processDot11Hdr;
+#ifdef CONFIG_PM
+ if (ar->arWowState != WLAN_WOW_STATE_NONE) {
+ A_NETBUF_FREE(skb);
+ return 0;
+ }
+#endif /* CONFIG_PM */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n",
+ (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb),
+ A_NETBUF_LEN(skb)));
+
+ /* If target is not associated */
+ if( (!ar->arConnected && !bypasswmi)
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ /* TCMD doesnt support any data, free the buf and return */
+ || (ar->arTargetMode == AR6000_TCMD_MODE)
+#endif
+ ) {
+ A_NETBUF_FREE(skb);
+ return 0;
+ }
+
+ do {
+
+ if (ar->arWmiReady == FALSE && bypasswmi == 0) {
+ break;
+ }
+
+#ifdef BLOCK_TX_PATH_FLAG
+ if (blocktx) {
+ break;
+ }
+#endif /* BLOCK_TX_PATH_FLAG */
+
+ /* AP mode Power save processing */
+ /* If the dst STA is in sleep state, queue the pkt in its PS queue */
+
+ if (ar->arNetworkType == AP_NETWORK) {
+ ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
+ sta_t *conn = NULL;
+
+ /* If the dstMac is a Multicast address & atleast one of the
+ * associated STA is in PS mode, then queue the pkt to the
+ * mcastq
+ */
+ if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
+ A_UINT8 ctr=0;
+ A_BOOL qMcast=FALSE;
+
+
+ for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) {
+ if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) {
+ qMcast = TRUE;
+ }
+ }
+ if(qMcast) {
+
+ /* If this transmit is not because of a Dtim Expiry q it */
+ if (ar->DTIMExpired == FALSE) {
+ A_BOOL isMcastqEmpty = FALSE;
+
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
+ A_NETBUF_ENQUEUE(&ar->mcastpsq, skb);
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+
+ /* If this is the first Mcast pkt getting queued
+ * indicate to the target to set the BitmapControl LSB
+ * of the TIM IE.
+ */
+ if (isMcastqEmpty) {
+ wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1);
+ }
+ return 0;
+ } else {
+ /* This transmit is because of Dtim expiry. Determine if
+ * MoreData bit has to be set.
+ */
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
+ bMoreData = TRUE;
+ }
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+ }
+ }
+ } else {
+ conn = ieee80211_find_conn(ar, datap->dstMac);
+ if (conn) {
+ if (STA_IS_PWR_SLEEP(conn)) {
+ /* If this transmit is not because of a PsPoll q it*/
+ if (!STA_IS_PS_POLLED(conn)) {
+ A_BOOL isPsqEmpty = FALSE;
+ /* Queue the frames if the STA is sleeping */
+ A_MUTEX_LOCK(&conn->psqLock);
+ isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
+ A_NETBUF_ENQUEUE(&conn->psq, skb);
+ A_MUTEX_UNLOCK(&conn->psqLock);
+
+ /* If this is the first pkt getting queued
+ * for this STA, update the PVB for this STA
+ */
+ if (isPsqEmpty) {
+ wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1);
+ }
+
+ return 0;
+ } else {
+ /* This tx is because of a PsPoll. Determine if
+ * MoreData bit has to be set
+ */
+ A_MUTEX_LOCK(&conn->psqLock);
+ if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
+ bMoreData = TRUE;
+ }
+ A_MUTEX_UNLOCK(&conn->psqLock);
+ }
+ }
+ } else {
+
+ /* non existent STA. drop the frame */
+ A_NETBUF_FREE(skb);
+ return 0;
+ }
+ }
+ }
+
+ if (ar->arWmiEnabled) {
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ A_UINT8 csumStart=0;
+ A_UINT8 csumDest=0;
+ A_UINT8 csum=skb->ip_summed;
+ if(csumOffload && (csum==CHECKSUM_PARTIAL)){
+ csumStart=skb->csum_start-(skb->network_header-skb->head)+sizeof(ATH_LLC_SNAP_HDR);
+ csumDest=skb->csum_offset+csumStart;
+ }
+#endif
+ if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
+ struct sk_buff *newbuf;
+
+ /*
+ * We really should have gotten enough headroom but sometimes
+ * we still get packets with not enough headroom. Copy the packet.
+ */
+ len = A_NETBUF_LEN(skb);
+ newbuf = A_NETBUF_ALLOC(len);
+ if (newbuf == NULL) {
+ break;
+ }
+ A_NETBUF_PUT(newbuf, len);
+ A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len);
+ A_NETBUF_FREE(skb);
+ skb = newbuf;
+ /* fall through and assemble header */
+ }
+
+ if (dot11Hdr) {
+ if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n"));
+ break;
+ }
+ } else {
+ if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n"));
+ break;
+ }
+ }
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
+ WMI_TX_META_V2 metaV2;
+ metaV2.csumStart =csumStart;
+ metaV2.csumDest = csumDest;
+ metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/
+ if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,
+ WMI_META_VERSION_2,&metaV2) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
+ break;
+ }
+
+ }
+ else
+#endif
+ {
+ if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
+ break;
+ }
+ }
+
+
+ if ((ar->arNetworkType == ADHOC_NETWORK) &&
+ ar->arIbssPsEnable && ar->arConnected) {
+ /* flag to check adhoc mapping once we take the lock below: */
+ checkAdHocPsMapping = TRUE;
+
+ } else {
+ /* get the stream mapping */
+ ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled);
+ }
+
+ } else {
+ EPPING_HEADER *eppingHdr;
+
+ eppingHdr = A_NETBUF_DATA(skb);
+
+ if (IS_EPPING_PACKET(eppingHdr)) {
+ /* the stream ID is mapped to an access class */
+ ac = eppingHdr->StreamNo_h;
+ /* some EPPING packets cannot be dropped no matter what access class it was
+ * sent on. We can change the packet tag to guarantee it will not get dropped */
+ if (IS_EPING_PACKET_NO_DROP(eppingHdr)) {
+ htc_tag = AR6K_CONTROL_PKT_TAG;
+ }
+
+ if (ac == HCI_TRANSPORT_STREAM_NUM) {
+ /* pass this to HCI */
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+ if (A_SUCCESS(hci_test_send(ar,skb))) {
+ return 0;
+ }
+#endif
+ /* set AC to discard this skb */
+ ac = AC_NOT_MAPPED;
+ } else {
+ /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition
+ * of the HTC header will mis-align the start of the HTC frame, so we add some
+ * padding which will be stripped off in the target */
+ if (EPPING_ALIGNMENT_PAD > 0) {
+ A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
+ }
+ }
+
+ } else {
+ /* not a ping packet, drop it */
+ ac = AC_NOT_MAPPED;
+ }
+ }
+
+ } while (FALSE);
+
+ /* did we succeed ? */
+ if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) {
+ /* cleanup and exit */
+ A_NETBUF_FREE(skb);
+ AR6000_STAT_INC(ar, tx_dropped);
+ AR6000_STAT_INC(ar, tx_aborted_errors);
+ return 0;
+ }
+
+ cookie = NULL;
+
+ /* take the lock to protect driver data */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ do {
+
+ if (checkAdHocPsMapping) {
+ eid = ar6000_ibss_map_epid(skb, dev, &mapNo);
+ }else {
+ eid = arAc2EndpointID (ar, ac);
+ }
+ /* validate that the endpoint is connected */
+ if (eid == 0 || eid == ENDPOINT_UNUSED ) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid));
+ break;
+ }
+ /* allocate resource for this packet */
+ cookie = ar6000_alloc_cookie(ar);
+
+ if (cookie != NULL) {
+ /* update counts while the lock is held */
+ ar->arTxPending[eid]++;
+ ar->arTotalTxDataPending++;
+ }
+
+ } while (FALSE);
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (cookie != NULL) {
+ cookie->arc_bp[0] = (unsigned long)skb;
+ cookie->arc_bp[1] = mapNo;
+ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
+ cookie,
+ A_NETBUF_DATA(skb),
+ A_NETBUF_LEN(skb),
+ eid,
+ htc_tag);
+
+#ifdef DEBUG
+ if (debugdriver >= 3) {
+ ar6000_dump_skb(skb);
+ }
+#endif
+#ifdef HTC_TEST_SEND_PKTS
+ DoHTCSendPktsTest(ar,mapNo,eid,skb);
+#endif
+ /* HTC interface is asynchronous, if this fails, cleanup will happen in
+ * the ar6000_tx_complete callback */
+ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
+ } else {
+ /* no packet to send, cleanup */
+ A_NETBUF_FREE(skb);
+ AR6000_STAT_INC(ar, tx_dropped);
+ AR6000_STAT_INC(ar, tx_aborted_errors);
+ }
+
+ return 0;
+}
+
+int
+ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct ar_cookie *cookie;
+ HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
+
+ cookie = NULL;
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ /* For now we send ACL on BE endpoint: We can also have a dedicated EP */
+ eid = arAc2EndpointID (ar, 0);
+ /* allocate resource for this packet */
+ cookie = ar6000_alloc_cookie(ar);
+
+ if (cookie != NULL) {
+ /* update counts while the lock is held */
+ ar->arTxPending[eid]++;
+ ar->arTotalTxDataPending++;
+ }
+
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (cookie != NULL) {
+ cookie->arc_bp[0] = (unsigned long)skb;
+ cookie->arc_bp[1] = 0;
+ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
+ cookie,
+ A_NETBUF_DATA(skb),
+ A_NETBUF_LEN(skb),
+ eid,
+ AR6K_DATA_PKT_TAG);
+
+ /* HTC interface is asynchronous, if this fails, cleanup will happen in
+ * the ar6000_tx_complete callback */
+ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
+ } else {
+ /* no packet to send, cleanup */
+ A_NETBUF_FREE(skb);
+ AR6000_STAT_INC(ar, tx_dropped);
+ AR6000_STAT_INC(ar, tx_aborted_errors);
+ }
+ return 0;
+}
+
+
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+static void
+tvsub(register struct timeval *out, register struct timeval *in)
+{
+ if((out->tv_usec -= in->tv_usec) < 0) {
+ out->tv_sec--;
+ out->tv_usec += 1000000;
+ }
+ out->tv_sec -= in->tv_sec;
+}
+
+void
+applyAPTCHeuristics(AR_SOFTC_T *ar)
+{
+ A_UINT32 duration;
+ A_UINT32 numbytes;
+ A_UINT32 throughput;
+ struct timeval ts;
+ A_STATUS status;
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {
+ do_gettimeofday(&ts);
+ tvsub(&ts, &aptcTR.samplingTS);
+ duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */
+ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;
+
+ if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {
+ /* Initialize the time stamp and byte count */
+ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;
+ do_gettimeofday(&aptcTR.samplingTS);
+
+ /* Calculate and decide based on throughput thresholds */
+ throughput = ((numbytes * 8) / duration);
+ if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {
+ /* Disable Sleep and schedule a timer */
+ A_ASSERT(ar->arWmiReady == TRUE);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);
+ aptcTR.timerScheduled = TRUE;
+ }
+ }
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+}
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP;
+ A_BOOL stopNet = FALSE;
+ HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket);
+
+ do {
+
+ if (bypasswmi) {
+ int accessClass;
+
+ if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
+ /* don't drop special control packets */
+ break;
+ }
+
+ accessClass = arEndpoint2Ac(ar,Endpoint);
+ /* for endpoint ping testing drop Best Effort and Background */
+ if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) {
+ action = HTC_SEND_FULL_DROP;
+ stopNet = FALSE;
+ } else {
+ /* keep but stop the netqueues */
+ stopNet = TRUE;
+ }
+ break;
+ }
+
+ if (Endpoint == ar->arControlEp) {
+ /* under normal WMI if this is getting full, then something is running rampant
+ * the host should not be exhausting the WMI queue with too many commands
+ * the only exception to this is during testing using endpointping */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ /* set flag to handle subsequent messages */
+ ar->arWMIControlEpFull = TRUE;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n"));
+ /* no need to stop the network */
+ stopNet = FALSE;
+ break;
+ }
+
+ /* if we get here, we are dealing with data endpoints getting full */
+
+ if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) {
+ /* don't drop control packets issued on ANY data endpoint */
+ break;
+ }
+
+ if (ar->arNetworkType == ADHOC_NETWORK) {
+ /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to
+ * continue, however we should stop the network */
+ stopNet = TRUE;
+ break;
+ }
+ /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest
+ * active stream */
+ if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri &&
+ ar->arCookieCount <= MAX_HI_COOKIE_NUM) {
+ /* this stream's priority is less than the highest active priority, we
+ * give preference to the highest priority stream by directing
+ * HTC to drop the packet that overflowed */
+ action = HTC_SEND_FULL_DROP;
+ /* since we are dropping packets, no need to stop the network */
+ stopNet = FALSE;
+ break;
+ }
+
+ } while (FALSE);
+
+ if (stopNet) {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar->arNetQueueStopped = TRUE;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ /* one of the data endpoints queues is getting full..need to stop network stack
+ * the queue will resume in ar6000_tx_complete() */
+ netif_stop_queue(ar->arNetDev);
+ }
+
+ return action;
+}
+
+
+static void
+ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ A_UINT32 mapNo = 0;
+ A_STATUS status;
+ struct ar_cookie * ar_cookie;
+ HTC_ENDPOINT_ID eid;
+ A_BOOL wakeEvent = FALSE;
+ struct sk_buff_head skb_queue;
+ HTC_PACKET *pPacket;
+ struct sk_buff *pktSkb;
+ A_BOOL flushing = FALSE;
+
+ skb_queue_head_init(&skb_queue);
+
+ /* lock the driver as we update internal state */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ /* reap completed packets */
+ while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
+
+ pPacket = HTC_PACKET_DEQUEUE(pPacketQueue);
+
+ ar_cookie = (struct ar_cookie *)pPacket->pPktContext;
+ A_ASSERT(ar_cookie);
+
+ status = pPacket->Status;
+ pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0];
+ eid = pPacket->Endpoint;
+ mapNo = ar_cookie->arc_bp[1];
+
+ A_ASSERT(pktSkb);
+ A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb));
+
+ /* add this to the list, use faster non-lock API */
+ __skb_queue_tail(&skb_queue,pktSkb);
+
+ if (A_SUCCESS(status)) {
+ A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb));
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ",
+ (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer,
+ pPacket->ActualLength,
+ eid));
+
+ ar->arTxPending[eid]--;
+
+ if ((eid != ar->arControlEp) || bypasswmi) {
+ ar->arTotalTxDataPending--;
+ }
+
+ if (eid == ar->arControlEp)
+ {
+ if (ar->arWMIControlEpFull) {
+ /* since this packet completed, the WMI EP is no longer full */
+ ar->arWMIControlEpFull = FALSE;
+ }
+
+ if (ar->arTxPending[eid] == 0) {
+ wakeEvent = TRUE;
+ }
+ }
+
+ if (A_FAILED(status)) {
+ if (status == A_ECANCELED) {
+ /* a packet was flushed */
+ flushing = TRUE;
+ }
+ AR6000_STAT_INC(ar, tx_errors);
+ if (status != A_NO_RESOURCE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__,
+ status));
+ }
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n"));
+ flushing = FALSE;
+ AR6000_STAT_INC(ar, tx_packets);
+ ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb);
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+ aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb);
+ applyAPTCHeuristics(ar);
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+ }
+
+ // TODO this needs to be looked at
+ if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
+ && (eid != ar->arControlEp) && mapNo)
+ {
+ mapNo --;
+ ar->arNodeMap[mapNo].txPending --;
+
+ if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
+ A_UINT32 i;
+ for (i = ar->arNodeNum; i > 0; i --) {
+ if (!ar->arNodeMap[i - 1].txPending) {
+ A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
+ ar->arNodeNum --;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ ar6000_free_cookie(ar, ar_cookie);
+
+ if (ar->arNetQueueStopped) {
+ ar->arNetQueueStopped = FALSE;
+ }
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ /* lock is released, we can freely call other kernel APIs */
+
+ /* free all skbs in our local list */
+ while (!skb_queue_empty(&skb_queue)) {
+ /* use non-lock version */
+ pktSkb = __skb_dequeue(&skb_queue);
+ A_NETBUF_FREE(pktSkb);
+ }
+
+ if ((ar->arConnected == TRUE) || (bypasswmi)) {
+ if (!flushing) {
+ /* don't wake the queue if we are flushing, other wise it will just
+ * keep queueing packets, which will keep failing */
+ netif_wake_queue(ar->arNetDev);
+ }
+ }
+
+ if (wakeEvent) {
+ wake_up(&arEvent);
+ }
+
+}
+
+sta_t *
+ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr)
+{
+ sta_t *conn = NULL;
+ A_UINT8 i, max_conn;
+
+ switch(ar->arNetworkType) {
+ case AP_NETWORK:
+ max_conn = AP_MAX_NUM_STA;
+ break;
+ default:
+ max_conn=0;
+ break;
+ }
+
+ for (i = 0; i < max_conn; i++) {
+ if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) {
+ conn = &ar->sta_list[i];
+ break;
+ }
+ }
+
+ return conn;
+}
+
+sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid)
+{
+ sta_t *conn = NULL;
+ A_UINT8 ctr;
+
+ for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+ if (ar->sta_list[ctr].aid == aid) {
+ conn = &ar->sta_list[ctr];
+ break;
+ }
+ }
+ return conn;
+}
+
+/*
+ * Receive event handler. This is called by HTC when a packet is received
+ */
+int pktcount;
+static void
+ar6000_rx(void *Context, HTC_PACKET *pPacket)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;
+ int minHdrLen;
+ A_UINT8 containsDot11Hdr = 0;
+ A_STATUS status = pPacket->Status;
+ HTC_ENDPOINT_ID ept = pPacket->Endpoint;
+
+ A_ASSERT((status != A_OK) ||
+ (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d",
+ (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer,
+ pPacket->ActualLength, status));
+ if (status != A_OK) {
+ if (status != A_ECANCELED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status));
+ }
+ }
+
+ /* take lock to protect buffer counts
+ * and adaptive power throughput state */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ if (A_SUCCESS(status)) {
+ AR6000_STAT_INC(ar, rx_packets);
+ ar->arNetStats.rx_bytes += pPacket->ActualLength;
+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL
+ aptcTR.bytesReceived += a_netbuf_to_len(skb);
+ applyAPTCHeuristics(ar);
+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
+
+ A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);
+ A_NETBUF_PULL(skb, HTC_HEADER_LEN);
+
+#ifdef DEBUG
+ if (debugdriver >= 2) {
+ ar6000_dump_skb(skb);
+ }
+#endif /* DEBUG */
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ skb->dev = ar->arNetDev;
+ if (status != A_OK) {
+ AR6000_STAT_INC(ar, rx_errors);
+ A_NETBUF_FREE(skb);
+ } else if (ar->arWmiEnabled == TRUE) {
+ if (ept == ar->arControlEp) {
+ /*
+ * this is a wmi control msg
+ */
+#ifdef CONFIG_PM
+ ar6000_check_wow_status(ar, skb, TRUE);
+#endif /* CONFIG_PM */
+ wmi_control_rx(ar->arWmi, skb);
+ } else {
+ WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
+ A_UINT8 is_amsdu, tid, is_acl_data_frame;
+ is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL;
+#ifdef CONFIG_PM
+ ar6000_check_wow_status(ar, NULL, FALSE);
+#endif /* CONFIG_PM */
+ /*
+ * this is a wmi data packet
+ */
+ // NWF
+
+ if (processDot11Hdr) {
+ minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR);
+ } else {
+ minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
+ sizeof(ATH_LLC_SNAP_HDR);
+ }
+
+ /* In the case of AP mode we may receive NULL data frames
+ * that do not have LLC hdr. They are 16 bytes in size.
+ * Allow these frames in the AP mode.
+ * ACL data frames don't follow ethernet frame bounds for
+ * min length
+ */
+ if (ar->arNetworkType != AP_NETWORK && !is_acl_data_frame &&
+ ((pPacket->ActualLength < minHdrLen) ||
+ (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
+ {
+ /*
+ * packet is too short or too long
+ */
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n"));
+ AR6000_STAT_INC(ar, rx_errors);
+ AR6000_STAT_INC(ar, rx_length_errors);
+ A_NETBUF_FREE(skb);
+ } else {
+ A_UINT16 seq_no;
+ A_UINT8 meta_type;
+
+#if 0
+ /* Access RSSI values here */
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n",
+ ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi));
+#endif
+ /* Get the Power save state of the STA */
+ if (ar->arNetworkType == AP_NETWORK) {
+ sta_t *conn = NULL;
+ A_UINT8 psState=0,prevPsState;
+ ATH_MAC_HDR *datap=NULL;
+ A_UINT16 offset;
+
+ meta_type = WMI_DATA_HDR_GET_META(dhdr);
+
+ psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info
+ >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK;
+
+ offset = sizeof(WMI_DATA_HDR);
+
+ switch (meta_type) {
+ case 0:
+ break;
+ case WMI_META_VERSION_1:
+ offset += sizeof(WMI_RX_META_V1);
+ break;
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ case WMI_META_VERSION_2:
+ offset += sizeof(WMI_RX_META_V2);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset);
+ conn = ieee80211_find_conn(ar, datap->srcMac);
+
+ if (conn) {
+ /* if there is a change in PS state of the STA,
+ * take appropriate steps.
+ * 1. If Sleep-->Awake, flush the psq for the STA
+ * Clear the PVB for the STA.
+ * 2. If Awake-->Sleep, Starting queueing frames
+ * the STA.
+ */
+ prevPsState = STA_IS_PWR_SLEEP(conn);
+ if (psState) {
+ STA_SET_PWR_SLEEP(conn);
+ } else {
+ STA_CLR_PWR_SLEEP(conn);
+ }
+
+ if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) {
+
+ if (!STA_IS_PWR_SLEEP(conn)) {
+
+ A_MUTEX_LOCK(&conn->psqLock);
+ while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) {
+ struct sk_buff *skb=NULL;
+
+ skb = A_NETBUF_DEQUEUE(&conn->psq);
+ A_MUTEX_UNLOCK(&conn->psqLock);
+ ar6000_data_tx(skb,ar->arNetDev);
+ A_MUTEX_LOCK(&conn->psqLock);
+ }
+ A_MUTEX_UNLOCK(&conn->psqLock);
+ /* Clear the PVB for this STA */
+ wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
+ }
+ }
+ } else {
+ /* This frame is from a STA that is not associated*/
+ A_ASSERT(FALSE);
+ }
+
+ /* Drop NULL data frames here */
+ if((pPacket->ActualLength < minHdrLen) ||
+ (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) {
+ A_NETBUF_FREE(skb);
+ goto rx_done;
+ }
+ }
+
+ is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr);
+ tid = WMI_DATA_HDR_GET_UP(dhdr);
+ seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr);
+ meta_type = WMI_DATA_HDR_GET_META(dhdr);
+ containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr);
+
+ wmi_data_hdr_remove(ar->arWmi, skb);
+
+ switch (meta_type) {
+ case WMI_META_VERSION_1:
+ {
+ WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb);
+ A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags);
+ A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
+ break;
+ }
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ case WMI_META_VERSION_2:
+ {
+ WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
+ if(pMeta->csumFlags & 0x1){
+ skb->ip_summed=CHECKSUM_COMPLETE;
+ skb->csum=(pMeta->csum);
+ }
+ A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+
+ A_ASSERT(status == A_OK);
+
+ /* NWF: print the 802.11 hdr bytes */
+ if(containsDot11Hdr) {
+ status = wmi_dot11_hdr_remove(ar->arWmi,skb);
+ } else if(!is_amsdu && !is_acl_data_frame) {
+ status = wmi_dot3_2_dix(skb);
+ }
+
+ if (status != A_OK) {
+ /* Drop frames that could not be processed (lack of memory, etc.) */
+ A_NETBUF_FREE(skb);
+ goto rx_done;
+ }
+
+ if (is_acl_data_frame) {
+ A_NETBUF_PUSH(skb, sizeof(int));
+ *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID;
+ /* send the data packet to PAL driver */
+ if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) {
+ if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == TRUE)
+ goto rx_done;
+ }
+ }
+
+ if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
+ if (ar->arNetworkType == AP_NETWORK) {
+ struct sk_buff *skb1 = NULL;
+ ATH_MAC_HDR *datap;
+
+ datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
+ if (IEEE80211_IS_MULTICAST(datap->dstMac)) {
+ /* Bcast/Mcast frames should be sent to the OS
+ * stack as well as on the air.
+ */
+ skb1 = skb_copy(skb,GFP_ATOMIC);
+ } else {
+ /* Search for a connected STA with dstMac as
+ * the Mac address. If found send the frame to
+ * it on the air else send the frame up the
+ * stack
+ */
+ sta_t *conn = NULL;
+ conn = ieee80211_find_conn(ar, datap->dstMac);
+
+ if (conn && ar->intra_bss) {
+ skb1 = skb;
+ skb = NULL;
+ } else if(conn && !ar->intra_bss) {
+ A_NETBUF_FREE(skb);
+ skb = NULL;
+ }
+ }
+ if (skb1) {
+ ar6000_data_tx(skb1, ar->arNetDev);
+ }
+ }
+ }
+#ifdef ATH_AR6K_11N_SUPPORT
+ aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
+#endif
+ ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
+ }
+ }
+ } else {
+ if (EPPING_ALIGNMENT_PAD > 0) {
+ A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD);
+ }
+ ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb);
+ }
+
+rx_done:
+
+ return;
+}
+
+static void
+ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf)
+{
+ struct sk_buff *skb = (struct sk_buff *)osbuf;
+
+ if(skb) {
+ skb->dev = dev;
+ if ((skb->dev->flags & IFF_UP) == IFF_UP) {
+#ifdef CONFIG_PM
+ ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, FALSE);
+#endif /* CONFIG_PM */
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ /*
+ * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ)
+ * or tasklet use the netif_rx to deliver the packet to the stack
+ * netif_rx will queue the packet onto the receive queue and mark
+ * the softirq thread has a pending action to complete. Kernel will
+ * schedule the softIrq kernel thread after processing the DSR.
+ *
+ * If this routine is called on a process context, use netif_rx_ni
+ * which will schedle the softIrq kernel thread after queuing the packet.
+ */
+ if (in_interrupt()) {
+ netif_rx(skb);
+ } else {
+ netif_rx_ni(skb);
+ }
+ } else {
+ A_NETBUF_FREE(skb);
+ }
+ }
+}
+
+#if 0
+static void
+ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf)
+{
+ struct sk_buff *skb = (struct sk_buff *)osbuf;
+
+ if(skb) {
+ skb->dev = dev;
+ if ((skb->dev->flags & IFF_UP) == IFF_UP) {
+ skb->protocol = htons(ETH_P_CONTROL);
+ netif_rx(skb);
+ } else {
+ A_NETBUF_FREE(skb);
+ }
+ }
+}
+#endif
+
+static void
+ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ void *osBuf;
+ int RxBuffers;
+ int buffersToRefill;
+ HTC_PACKET *pPacket;
+ HTC_PACKET_QUEUE queue;
+
+ buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
+ HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint);
+
+ if (buffersToRefill <= 0) {
+ /* fast return, nothing to fill */
+ return;
+ }
+
+ INIT_HTC_PACKET_QUEUE(&queue);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
+ buffersToRefill, Endpoint));
+
+ for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
+ osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE);
+ if (NULL == osBuf) {
+ break;
+ }
+ /* the HTC packet wrapper is at the head of the reserved area
+ * in the skb */
+ pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
+ /* set re-fill info */
+ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint);
+ /* add to queue */
+ HTC_PACKET_ENQUEUE(&queue,pPacket);
+ }
+
+ if (!HTC_QUEUE_EMPTY(&queue)) {
+ /* add packets */
+ HTCAddReceivePktMultiple(ar->arHtcTarget, &queue);
+ }
+
+}
+
+ /* clean up our amsdu buffer list */
+static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar)
+{
+ HTC_PACKET *pPacket;
+ void *osBuf;
+
+ /* empty AMSDU buffer queue and free OS bufs */
+ while (TRUE) {
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (NULL == pPacket) {
+ break;
+ }
+
+ osBuf = pPacket->pPktContext;
+ if (NULL == osBuf) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ A_NETBUF_FREE(osBuf);
+ }
+
+}
+
+
+ /* refill the amsdu buffer list */
+static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count)
+{
+ HTC_PACKET *pPacket;
+ void *osBuf;
+
+ while (Count > 0) {
+ osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE);
+ if (NULL == osBuf) {
+ break;
+ }
+ /* the HTC packet wrapper is at the head of the reserved area
+ * in the skb */
+ pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf));
+ /* set re-fill info */
+ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0);
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ /* put it in the list */
+ HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ Count--;
+ }
+
+}
+
+ /* callback to allocate a large receive buffer for a pending packet. This function is called when
+ * an HTC packet arrives whose length exceeds a threshold value
+ *
+ * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to
+ * keep the allocation size the same to optimize cached-slab allocations.
+ *
+ * */
+static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length)
+{
+ HTC_PACKET *pPacket = NULL;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ int refillCount = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length));
+
+ do {
+
+ if (Length <= AR6000_BUFFER_SIZE) {
+ /* shouldn't be getting called on normal sized packets */
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ if (Length > AR6000_AMSDU_BUFFER_SIZE) {
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ /* allocate a packet from the list */
+ pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue);
+ /* see if we need to refill again */
+ refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (NULL == pPacket) {
+ break;
+ }
+ /* set actual endpoint ID */
+ pPacket->Endpoint = Endpoint;
+
+ } while (FALSE);
+
+ if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) {
+ ar6000_refill_amsdu_rxbufs(ar,refillCount);
+ }
+
+ return pPacket;
+}
+
+static void
+ar6000_set_multicast_list(struct net_device *dev)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n"));
+}
+
+static struct net_device_stats *
+ar6000_get_stats(struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ return &ar->arNetStats;
+}
+
+static struct iw_statistics *
+ar6000_get_iwstats(struct net_device * dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ TARGET_STATS *pStats = &ar->arTargetStats;
+ struct iw_statistics * pIwStats = &ar->arIwStats;
+ int rtnllocked;
+
+ if (ar->bIsDestroyProgress || ar->arWmiReady == FALSE || ar->arWlanState == WLAN_DISABLED)
+ {
+ pIwStats->status = 0;
+ pIwStats->qual.qual = 0;
+ pIwStats->qual.level =0;
+ pIwStats->qual.noise = 0;
+ pIwStats->discard.code =0;
+ pIwStats->discard.retries=0;
+ pIwStats->miss.beacon =0;
+ return pIwStats;
+ }
+
+ /*
+ * The in_atomic function is used to determine if the scheduling is
+ * allowed in the current context or not. This was introduced in 2.6
+ * From what I have read on the differences between 2.4 and 2.6, the
+ * 2.4 kernel did not support preemption and so this check might not
+ * be required for 2.4 kernels.
+ */
+ if (in_atomic())
+ {
+ wmi_get_stats_cmd(ar->arWmi);
+
+ pIwStats->status = 1 ;
+ pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
+ pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
+ pIwStats->qual.noise = pStats->noise_floor_calibation;
+ pIwStats->discard.code = pStats->rx_decrypt_err;
+ pIwStats->discard.retries = pStats->tx_retry_cnt;
+ pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
+ return pIwStats;
+ }
+
+ dev_hold(dev);
+ rtnllocked = rtnl_is_locked();
+ if (rtnllocked) {
+ rtnl_unlock();
+ }
+ pIwStats->status = 0;
+
+ if (down_interruptible(&ar->arSem)) {
+ goto err_exit;
+ }
+
+ do {
+
+ if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
+ break;
+ }
+
+ ar->statsUpdatePending = TRUE;
+
+ if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+ break;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
+ if (signal_pending(current)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n"));
+ break;
+ }
+ pIwStats->status = 1 ;
+ pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
+ pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
+ pIwStats->qual.noise = pStats->noise_floor_calibation;
+ pIwStats->discard.code = pStats->rx_decrypt_err;
+ pIwStats->discard.retries = pStats->tx_retry_cnt;
+ pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
+ } while (0);
+ up(&ar->arSem);
+
+err_exit:
+ if (rtnllocked) {
+ rtnl_lock();
+ }
+ dev_put(dev);
+ return pIwStats;
+}
+
+void
+ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+ struct net_device *dev = ar->arNetDev;
+
+ ar->arWmiReady = TRUE;
+ wake_up(&arEvent);
+ A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN);
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ dev->dev_addr[0], dev->dev_addr[1],
+ dev->dev_addr[2], dev->dev_addr[3],
+ dev->dev_addr[4], dev->dev_addr[5]));
+
+ ar->arPhyCapability = phyCap;
+ ar->arVersion.wlan_ver = sw_ver;
+ ar->arVersion.abi_ver = abi_ver;
+
+#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
+ wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN);
+#endif
+#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
+ wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP);
+#endif
+ wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL);
+#if WLAN_CONFIG_DISABLE_11N
+ {
+ WMI_SET_HT_CAP_CMD htCap;
+
+ A_MEMZERO(&htCap, sizeof(WMI_SET_HT_CAP_CMD));
+ htCap.band = 0;
+ wmi_set_ht_cap_cmd(ar->arWmi, &htCap);
+
+ htCap.band = 1;
+ wmi_set_ht_cap_cmd(ar->arWmi, &htCap);
+ }
+#endif /* WLAN_CONFIG_DISABLE_11N */
+
+#ifdef ATH6K_CONFIG_OTA_MODE
+ wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);
+#endif
+ wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT);
+}
+
+void
+add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie,
+ A_UINT8 ielen, A_UINT8 keymgmt, A_UINT8 ucipher, A_UINT8 auth)
+{
+ A_UINT8 free_slot=aid-1;
+
+ A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN);
+ A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen);
+ ar->sta_list[free_slot].aid = aid;
+ ar->sta_list[free_slot].keymgmt = keymgmt;
+ ar->sta_list[free_slot].ucipher = ucipher;
+ ar->sta_list[free_slot].auth = auth;
+ ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
+ ar->arAPStats.sta[free_slot].aid = aid;
+}
+
+void
+ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
+ A_UINT16 listenInterval, A_UINT16 beaconInterval,
+ NETWORK_TYPE networkType, A_UINT8 beaconIeLen,
+ A_UINT8 assocReqLen, A_UINT8 assocRespLen,
+ A_UINT8 *assocInfo)
+{
+ union iwreq_data wrqu;
+ int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
+ static const char *tag1 = "ASSOCINFO(ReqIEs=";
+ static const char *tag2 = "ASSOCRESPIE=";
+ static const char *beaconIetag = "BEACONIE=";
+ char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1];
+ char *pos;
+ A_UINT8 key_op_ctrl;
+ unsigned long flags;
+ struct ieee80211req_key *ik;
+ CRYPTO_TYPE keyType = NONE_CRYPT;
+
+ if(ar->arNetworkType & AP_NETWORK) {
+ struct net_device *dev = ar->arNetDev;
+ if(A_MEMCMP(dev->dev_addr, bssid, ATH_MAC_LEN)==0) {
+ ar->arACS = channel;
+ ik = &ar->ap_mode_bkey;
+
+ switch(ar->arAuthMode) {
+ case NONE_AUTH:
+ if(ar->arPairwiseCrypto == WEP_CRYPT) {
+ ar6000_install_static_wep_keys(ar);
+ }
+#ifdef WAPI_ENABLE
+ else if(ar->arPairwiseCrypto == WAPI_CRYPT) {
+ ap_set_wapi_key(ar, ik);
+ }
+#endif
+ break;
+ case WPA_PSK_AUTH:
+ case WPA2_PSK_AUTH:
+ case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
+ switch (ik->ik_type) {
+ case IEEE80211_CIPHER_TKIP:
+ keyType = TKIP_CRYPT;
+ break;
+ case IEEE80211_CIPHER_AES_CCM:
+ keyType = AES_CRYPT;
+ break;
+ default:
+ goto skip_key;
+ }
+ wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE,
+ ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
+ ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
+ SYNC_BOTH_WMIFLAG);
+
+ break;
+ }
+skip_key:
+ ar->arConnected = TRUE;
+ return;
+ }
+
+ A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n "
+ " AID=%d \n", bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5], channel);
+ switch ((listenInterval>>8)&0xFF) {
+ case OPEN_AUTH:
+ A_PRINTF("AUTH: OPEN\n");
+ break;
+ case SHARED_AUTH:
+ A_PRINTF("AUTH: SHARED\n");
+ break;
+ default:
+ A_PRINTF("AUTH: Unknown\n");
+ break;
+ };
+ switch (listenInterval&0xFF) {
+ case WPA_PSK_AUTH:
+ A_PRINTF("KeyMgmt: WPA-PSK\n");
+ break;
+ case WPA2_PSK_AUTH:
+ A_PRINTF("KeyMgmt: WPA2-PSK\n");
+ break;
+ default:
+ A_PRINTF("KeyMgmt: NONE\n");
+ break;
+ };
+ switch (beaconInterval) {
+ case AES_CRYPT:
+ A_PRINTF("Cipher: AES\n");
+ break;
+ case TKIP_CRYPT:
+ A_PRINTF("Cipher: TKIP\n");
+ break;
+ case WEP_CRYPT:
+ A_PRINTF("Cipher: WEP\n");
+ break;
+#ifdef WAPI_ENABLE
+ case WAPI_CRYPT:
+ A_PRINTF("Cipher: WAPI\n");
+ break;
+#endif
+ default:
+ A_PRINTF("Cipher: NONE\n");
+ break;
+ };
+
+ add_new_sta(ar, bssid, channel /*aid*/,
+ assocInfo /* WPA IE */, assocRespLen /* IE len */,
+ listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */,
+ (listenInterval>>8)&0xFF /* auth alg */);
+
+ /* Send event to application */
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
+ wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL);
+ /* In case the queue is stopped when we switch modes, this will
+ * wake it up
+ */
+ netif_wake_queue(ar->arNetDev);
+ return;
+ }
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar6k_cfg80211_connect_event(ar, channel, bssid,
+ listenInterval, beaconInterval,
+ networkType, beaconIeLen,
+ assocReqLen, assocRespLen,
+ assocInfo);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid));
+ ar->arBssChannel = channel;
+
+ A_PRINTF("AR6000 connected event on freq %d ", channel);
+ A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+ " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d"
+ " assocRespLen =%d\n",
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5],
+ listenInterval, beaconInterval,
+ beaconIeLen, assocReqLen, assocRespLen);
+ if (networkType & ADHOC_NETWORK) {
+ if (networkType & ADHOC_CREATOR) {
+ A_PRINTF("Network: Adhoc (Creator)\n");
+ } else {
+ A_PRINTF("Network: Adhoc (Joiner)\n");
+ }
+ } else {
+ A_PRINTF("Network: Infrastructure\n");
+ }
+
+ if ((ar->arNetworkType == INFRA_NETWORK)) {
+ wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
+ }
+
+ if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= "));
+
+ beacon_ie_pos = 0;
+ A_MEMZERO(buf, sizeof(buf));
+ sprintf(buf, "%s", beaconIetag);
+ pos = buf + 9;
+ for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
+ sprintf(pos, "%2.2x", assocInfo[i]);
+ pos += 2;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+ }
+
+ if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
+ {
+ assoc_resp_ie_pos = beaconIeLen + assocReqLen +
+ sizeof(A_UINT16) + /* capinfo*/
+ sizeof(A_UINT16) + /* status Code */
+ sizeof(A_UINT16) ; /* associd */
+ A_MEMZERO(buf, sizeof(buf));
+ sprintf(buf, "%s", tag2);
+ pos = buf + 12;
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= "));
+ /*
+ * The Association Response Frame w.o. the WLAN header is delivered to
+ * the host, so skip over to the IEs
+ */
+ for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
+ sprintf(pos, "%2.2x", assocInfo[i]);
+ pos += 2;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+ }
+
+ if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
+ /*
+ * assoc Request includes capability and listen interval. Skip these.
+ */
+ assoc_req_ie_pos = beaconIeLen +
+ sizeof(A_UINT16) + /* capinfo*/
+ sizeof(A_UINT16); /* listen interval */
+
+ A_MEMZERO(buf, sizeof(buf));
+ sprintf(buf, "%s", tag1);
+ pos = buf + 17;
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= "));
+ for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
+ sprintf(pos, "%2.2x", assocInfo[i]);
+ pos += 2;;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+ }
+
+#ifdef USER_KEYS
+ if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
+ ar->user_saved_keys.keyOk == TRUE)
+ {
+ key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC;
+
+ if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) {
+ key_op_ctrl &= ~KEY_OP_INIT_RSC;
+ } else {
+ key_op_ctrl |= KEY_OP_INIT_RSC;
+ }
+ ar6000_reinstall_keys(ar, key_op_ctrl);
+ }
+#endif /* USER_KEYS */
+
+ netif_wake_queue(ar->arNetDev);
+
+ /* For CFG80211 the key configuration and the default key comes in after connect so no point in plumbing invalid keys */
+#ifndef ATH6K_CONFIG_CFG80211
+ if ((networkType & ADHOC_NETWORK) &&
+ (OPEN_AUTH == ar->arDot11AuthMode) &&
+ (NONE_AUTH == ar->arAuthMode) &&
+ (WEP_CRYPT == ar->arPairwiseCrypto))
+ {
+ if (!ar->arConnected) {
+ wmi_addKey_cmd(ar->arWmi,
+ ar->arDefTxKeyIndex,
+ WEP_CRYPT,
+ GROUP_USAGE | TX_USAGE,
+ ar->arWepKeyList[ar->arDefTxKeyIndex].arKeyLen,
+ NULL,
+ ar->arWepKeyList[ar->arDefTxKeyIndex].arKey, KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+ }
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ /* Update connect & link status atomically */
+ spin_lock_irqsave(&ar->arLock, flags);
+ ar->arConnected = TRUE;
+ ar->arConnectPending = FALSE;
+ netif_carrier_on(ar->arNetDev);
+ spin_unlock_irqrestore(&ar->arLock, flags);
+ /* reset the rx aggr state */
+ aggr_reset_state(ar->aggr_cntxt);
+ reconnect_flag = 0;
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
+ wrqu.addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
+ if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
+ A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
+ ar->arNodeNum = 0;
+ ar->arNexEpId = ENDPOINT_2;
+ }
+ if (!ar->arUserBssFilter) {
+ wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
+ }
+
+}
+
+void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num)
+{
+ A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
+ ar->arNumDataEndPts = num;
+}
+
+void
+sta_cleanup(AR_SOFTC_T *ar, A_UINT8 i)
+{
+ struct sk_buff *skb;
+
+ /* empty the queued pkts in the PS queue if any */
+ A_MUTEX_LOCK(&ar->sta_list[i].psqLock);
+ while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) {
+ skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq);
+ A_NETBUF_FREE(skb);
+ }
+ A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock);
+
+ /* Zero out the state fields */
+ A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT));
+ A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN);
+ A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE);
+ ar->sta_list[i].aid = 0;
+ ar->sta_list[i].flags = 0;
+
+ ar->sta_list_index = ar->sta_list_index & ~(1 << i);
+
+}
+
+A_UINT8
+remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason)
+{
+ A_UINT8 i, removed=0;
+
+ if(IS_MAC_NULL(mac)) {
+ return removed;
+ }
+
+ if(IS_MAC_BCAST(mac)) {
+ A_PRINTF("DEL ALL STA\n");
+ for(i=0; i < AP_MAX_NUM_STA; i++) {
+ if(!IS_MAC_NULL(ar->sta_list[i].mac)) {
+ sta_cleanup(ar, i);
+ removed = 1;
+ }
+ }
+ } else {
+ for(i=0; i < AP_MAX_NUM_STA; i++) {
+ if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) {
+ A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+ " aid=%d REASON=%d\n", mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason);
+
+ sta_cleanup(ar, i);
+ removed = 1;
+ break;
+ }
+ }
+ }
+ return removed;
+}
+
+void
+ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid,
+ A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
+{
+ A_UINT8 i;
+ unsigned long flags;
+ union iwreq_data wrqu;
+
+ if(ar->arNetworkType & AP_NETWORK) {
+ union iwreq_data wrqu;
+ struct sk_buff *skb;
+
+ if(!remove_sta(ar, bssid, protocolReasonStatus)) {
+ return;
+ }
+
+ /* If there are no more associated STAs, empty the mcast PS q */
+ if (ar->sta_list_index == 0) {
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
+ skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
+ A_NETBUF_FREE(skb);
+ }
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+
+ /* Clear the LSB of the BitMapCtl field of the TIM IE */
+ if (ar->arWmiReady) {
+ wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
+ }
+ }
+
+ if(!IS_MAC_BCAST(bssid)) {
+ /* Send event to application */
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN);
+ wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL);
+ }
+ return;
+ }
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar6k_cfg80211_disconnect_event(ar, reason, bssid,
+ assocRespLen, assocInfo,
+ protocolReasonStatus);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ /* Send disconnect event to supplicant */
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
+
+ /* it is necessary to clear the host-side rx aggregation state */
+ aggr_reset_state(ar->aggr_cntxt);
+
+ A_UNTIMEOUT(&ar->disconnect_timer);
+
+ A_PRINTF("AR6000 disconnected");
+ if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
+ A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
+ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason));
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus));
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s",
+ assocRespLen ? " " : "NULL"));
+ for (i = 0; i < assocRespLen; i++) {
+ if (!(i % 0x10)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
+ /*
+ * If the event is due to disconnect cmd from the host, only they the target
+ * would stop trying to connect. Under any other condition, target would
+ * keep trying to connect.
+ *
+ */
+ if( reason == DISCONNECT_CMD)
+ {
+ ar->arConnectPending = FALSE;
+ if ((!ar->arUserBssFilter) && (ar->arWmiReady)) {
+ wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
+ }
+ } else {
+ ar->arConnectPending = TRUE;
+ if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) ||
+ ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) {
+ ar->arConnected = TRUE;
+ return;
+ }
+ }
+
+ if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady))
+ {
+ bss_t *pWmiSsidnode = NULL;
+
+ /* remove the current associated bssid node */
+ wmi_free_node (ar->arWmi, bssid);
+
+ /*
+ * In case any other same SSID nodes are present
+ * remove it, since those nodes also not available now
+ */
+ do
+ {
+ /*
+ * Find the nodes based on SSID and remove it
+ * NOTE :: This case will not work out for Hidden-SSID
+ */
+ pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, FALSE, TRUE);
+
+ if (pWmiSsidnode)
+ {
+ wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr);
+ }
+
+ } while (pWmiSsidnode);
+ }
+
+ /* Update connect & link status atomically */
+ spin_lock_irqsave(&ar->arLock, flags);
+ ar->arConnected = FALSE;
+ netif_carrier_off(ar->arNetDev);
+ spin_unlock_irqrestore(&ar->arLock, flags);
+
+ if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) {
+ reconnect_flag = 0;
+ }
+
+#ifdef USER_KEYS
+ if (reason != CSERV_DISCONNECT)
+ {
+ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
+ ar->user_key_ctrl = 0;
+ }
+#endif /* USER_KEYS */
+
+ netif_stop_queue(ar->arNetDev);
+ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+ ar->arBssChannel = 0;
+ ar->arBeaconInterval = 0;
+
+ ar6000_TxDataCleanup(ar);
+}
+
+void
+ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode)
+{
+ A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
+ ar->arRegCode = regCode;
+}
+
+#ifdef ATH_AR6K_11N_SUPPORT
+void
+ar6000_aggr_rcv_addba_req_evt(AR_SOFTC_T *ar, WMI_ADDBA_REQ_EVENT *evt)
+{
+ if(evt->status == 0) {
+ aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz);
+ }
+}
+
+void
+ar6000_aggr_rcv_addba_resp_evt(AR_SOFTC_T *ar, WMI_ADDBA_RESP_EVENT *evt)
+{
+ A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz);
+ if(evt->status == 0) {
+ }
+}
+
+void
+ar6000_aggr_rcv_delba_req_evt(AR_SOFTC_T *ar, WMI_DELBA_EVENT *evt)
+{
+ aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
+}
+#endif
+
+void register_pal_cb(ar6k_pal_config_t *palConfig_p)
+{
+ ar6k_pal_config_g = *palConfig_p;
+}
+
+void
+ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd)
+{
+ void *osbuf = NULL;
+ A_INT8 i;
+ A_UINT8 size, *buf;
+ A_STATUS ret = A_OK;
+
+ size = cmd->evt_buf_sz + 4;
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ ret = A_NO_MEMORY;
+ A_PRINTF("Error in allocating netbuf \n");
+ return;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+ buf = (A_UINT8 *)A_NETBUF_DATA(osbuf);
+ /* First 2-bytes carry HCI event/ACL data type
+ * the next 2 are free
+ */
+ *((short *)buf) = WMI_HCI_EVENT_EVENTID;
+ buf += sizeof(int);
+ A_MEMCPY(buf, cmd->buf, cmd->evt_buf_sz);
+
+ if(ar6k_pal_config_g.fpar6k_pal_recv_pkt)
+ {
+ /* pass the cmd packet to PAL driver */
+ if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == TRUE)
+ return;
+ }
+ ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
+ if(loghci) {
+ A_PRINTF_LOG("HCI Event From PAL <-- \n");
+ for(i = 0; i < cmd->evt_buf_sz; i++) {
+ A_PRINTF_LOG("0x%02x ", cmd->buf[i]);
+ if((i % 10) == 0) {
+ A_PRINTF_LOG("\n");
+ }
+ }
+ A_PRINTF_LOG("\n");
+ A_PRINTF_LOG("==================================\n");
+ }
+}
+
+void
+ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info)
+{
+#if WIRELESS_EXT >= 18
+ struct iw_pmkid_cand *pmkcand;
+#else /* WIRELESS_EXT >= 18 */
+ static const char *tag = "PRE-AUTH";
+ char buf[128];
+#endif /* WIRELESS_EXT >= 18 */
+
+ union iwreq_data wrqu;
+ int i;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n"));
+ for (i=0; i < numAps; info++, i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
+ info->bssid[0], info->bssid[1], info->bssid[2],
+ info->bssid[3], info->bssid[4], info->bssid[5]));
+ if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap"));
+ }
+ if (info->bssFlags & WMI_PMKID_VALID_BSS) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n"));
+ continue; /* we skip bss if the pmkid is already valid */
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n"));
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+#if WIRELESS_EXT >= 18
+ pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand));
+ A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand));
+ pmkcand->index = i;
+ pmkcand->flags = info->bssFlags;
+ A_MEMCPY(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
+ wrqu.data.length = sizeof(struct iw_pmkid_cand);
+ wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
+ A_FREE(pmkcand);
+#else /* WIRELESS_EXT >= 18 */
+ snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
+ tag,
+ info->bssid[0], info->bssid[1], info->bssid[2],
+ info->bssid[3], info->bssid[4], info->bssid[5],
+ i, info->bssFlags);
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+#endif /* WIRELESS_EXT >= 18 */
+ }
+}
+
+void
+ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
+{
+ static const char *tag = "MLME-MICHAELMICFAILURE.indication";
+ char buf[128];
+ union iwreq_data wrqu;
+
+ /*
+ * For AP case, keyid will have aid of STA which sent pkt with
+ * MIC error. Use this aid to get MAC & send it to hostapd.
+ */
+ if (ar->arNetworkType == AP_NETWORK) {
+ sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2));
+ if(!s){
+ A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid);
+ return;
+ }
+ A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid);
+ snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
+ } else {
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
+ keyid & 0x3, ismcast ? "multi": "uni");
+ snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3,
+ ismcast ? "mult" : "un");
+ }
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+}
+
+void
+ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
+{
+
+#ifdef ATH6K_CONFIG_CFG80211
+ ar6k_cfg80211_scanComplete_event(ar, status);
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+ if (!ar->arUserBssFilter) {
+ wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
+ }
+ if (ar->scan_triggered) {
+ if (status==A_OK) {
+ union iwreq_data wrqu;
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL);
+ }
+ ar->scan_triggered = 0;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status));
+}
+
+void
+ar6000_targetStats_event(AR_SOFTC_T *ar, A_UINT8 *ptr, A_UINT32 len)
+{
+ A_UINT8 ac;
+
+ if(ar->arNetworkType == AP_NETWORK) {
+ WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr;
+ WMI_AP_MODE_STAT *ap = &ar->arAPStats;
+
+ if (len < sizeof(*p)) {
+ return;
+ }
+
+ for(ac=0;ac<AP_MAX_NUM_STA;ac++) {
+ ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes;
+ ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts;
+ ap->sta[ac].tx_error += p->sta[ac].tx_error;
+ ap->sta[ac].tx_discard += p->sta[ac].tx_discard;
+ ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes;
+ ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts;
+ ap->sta[ac].rx_error += p->sta[ac].rx_error;
+ ap->sta[ac].rx_discard += p->sta[ac].rx_discard;
+ }
+
+ } else {
+ WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr;
+ TARGET_STATS *pStats = &ar->arTargetStats;
+
+ if (len < sizeof(*pTarget)) {
+ return;
+ }
+
+ // Update the RSSI of the connected bss.
+ if (ar->arConnected) {
+ bss_t *pConnBss = NULL;
+
+ pConnBss = wmi_find_node(ar->arWmi,ar->arBssid);
+ if (pConnBss)
+ {
+ pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
+ pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr;
+ wmi_node_return(ar->arWmi, pConnBss);
+ }
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n"));
+ pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets;
+ pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes;
+ pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
+ pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
+ pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
+ pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
+ pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
+ pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
+ pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
+ for(ac = 0; ac < WMM_NUM_AC; ac++)
+ pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
+ pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors;
+ pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt;
+ pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt;
+ pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt;
+ pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
+ pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate);
+
+ pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets;
+ pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes;
+ pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
+ pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
+ pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
+ pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
+ pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
+ pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
+ pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
+ pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors;
+ pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr;
+ pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
+ pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err;
+ pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
+ pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate);
+
+
+ pStats->tkip_local_mic_failure
+ += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
+ pStats->tkip_counter_measures_invoked
+ += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
+ pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
+ pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
+ pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
+ pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
+
+ pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
+ pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
+
+ pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt;
+ pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt;
+ pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt;
+ pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt;
+ pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr;
+ pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi;
+
+ if (enablerssicompensation) {
+ pStats->cs_aveBeacon_rssi =
+ rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi);
+ }
+ pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec;
+ pStats->cs_snr = pTarget->cservStats.cs_snr;
+ pStats->cs_rssi = pTarget->cservStats.cs_rssi;
+
+ pStats->lq_val = pTarget->lqVal;
+
+ pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped;
+ pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups;
+ pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups;
+ pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded;
+ pStats->arp_received += pTarget->arpStats.arp_received;
+ pStats->arp_matched += pTarget->arpStats.arp_matched;
+ pStats->arp_replied += pTarget->arpStats.arp_replied;
+
+ if (ar->statsUpdatePending) {
+ ar->statsUpdatePending = FALSE;
+ wake_up(&arEvent);
+ }
+ }
+}
+
+void
+ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi)
+{
+ USER_RSSI_THOLD userRssiThold;
+
+ rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR;
+
+ if (enablerssicompensation) {
+ rssi = rssi_compensation_calc(ar, rssi);
+ }
+
+ /* Send an event to the app */
+ userRssiThold.tag = ar->rssi_map[newThreshold].tag;
+ userRssiThold.rssi = rssi;
+ A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold,
+ userRssiThold.tag, userRssiThold.rssi);
+
+ ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssiThold, sizeof(USER_RSSI_THOLD));
+}
+
+
+void
+ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source)
+{
+ if (source == APP_HB_CHALLENGE) {
+ /* Report it to the app in case it wants a positive acknowledgement */
+ ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID,
+ (A_UINT8 *)&cookie, sizeof(cookie));
+ } else {
+ /* This would ignore the replys that come in after their due time */
+ if (cookie == ar->arHBChallengeResp.seqNum) {
+ ar->arHBChallengeResp.outstanding = FALSE;
+ }
+ }
+}
+
+
+void
+ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal)
+{
+ char *errString[] = {
+ [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL",
+ [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND",
+ [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR",
+ [WMI_TARGET_BMISS] "WMI_TARGET_BMISS",
+ [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN"
+ };
+
+ A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
+
+ /* One error is reported at a time, and errorval is a bitmask */
+ if(errorVal & (errorVal - 1))
+ return;
+
+ A_PRINTF("AR6000 Error type = ");
+ switch(errorVal)
+ {
+ case WMI_TARGET_PM_ERR_FAIL:
+ case WMI_TARGET_KEY_NOT_FOUND:
+ case WMI_TARGET_DECRYPTION_ERR:
+ case WMI_TARGET_BMISS:
+ case WMI_PSDISABLE_NODE_JOIN:
+ A_PRINTF("%s\n", errString[errorVal]);
+ break;
+ default:
+ A_PRINTF("INVALID\n");
+ break;
+ }
+
+}
+
+
+void
+ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication,
+ A_UINT8 statusCode, A_UINT8 *tspecSuggestion)
+{
+ WMM_TSPEC_IE *tspecIe;
+
+ /*
+ * This is the TSPEC IE suggestion from AP.
+ * Suggestion provided by AP under some error
+ * cases, could be helpful for the host app.
+ * Check documentation.
+ */
+ tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
+
+ /*
+ * What do we do, if we get TSPEC rejection? One thought
+ * that comes to mind is implictly delete the pstream...
+ */
+ A_PRINTF("AR6000 CAC notification. "
+ "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
+ ac, cacIndication, statusCode);
+}
+
+void
+ar6000_channel_change_event(AR_SOFTC_T *ar, A_UINT16 oldChannel,
+ A_UINT16 newChannel)
+{
+ A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n",
+ oldChannel, newChannel);
+}
+
+#define AR6000_PRINT_BSSID(_pBss) do { \
+ A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
+ (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
+ (_pBss)[4],(_pBss)[5]); \
+} while(0)
+
+void
+ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl)
+{
+ A_UINT8 i;
+
+ A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
+ pTbl->numEntries, pTbl->roamMode);
+ for (i= 0; i < pTbl->numEntries; i++) {
+ A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
+ pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
+ pTbl->bssRoamInfo[i].bssid[2],
+ pTbl->bssRoamInfo[i].bssid[3],
+ pTbl->bssRoamInfo[i].bssid[4],
+ pTbl->bssRoamInfo[i].bssid[5]);
+ A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
+ " BIAS %d\n",
+ pTbl->bssRoamInfo[i].rssi,
+ pTbl->bssRoamInfo[i].rssidt,
+ pTbl->bssRoamInfo[i].last_rssi,
+ pTbl->bssRoamInfo[i].util,
+ pTbl->bssRoamInfo[i].roam_util,
+ pTbl->bssRoamInfo[i].bias);
+ }
+}
+
+void
+ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply)
+{
+ A_UINT8 i,j;
+
+ /*Each event now contains exactly one filter, see bug 26613*/
+ A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters);
+ A_PRINTF("wow mode = %s host mode = %s\n",
+ (wow_reply->wow_mode == 0? "disabled":"enabled"),
+ (wow_reply->host_mode == 1 ? "awake":"asleep"));
+
+
+ /*If there are no patterns, the reply will only contain generic
+ WoW information. Pattern information will exist only if there are
+ patterns present. Bug 26716*/
+
+ /* If this event contains pattern information, display it*/
+ if (wow_reply->this_filter_num) {
+ i=0;
+ A_PRINTF("id=%d size=%d offset=%d\n",
+ wow_reply->wow_filters[i].wow_filter_id,
+ wow_reply->wow_filters[i].wow_filter_size,
+ wow_reply->wow_filters[i].wow_filter_offset);
+ A_PRINTF("wow pattern = ");
+ for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
+ A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]);
+ }
+
+ A_PRINTF("\nwow mask = ");
+ for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) {
+ A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]);
+ }
+ A_PRINTF("\n");
+ }
+}
+
+/*
+ * Report the Roaming related data collected on the target
+ */
+void
+ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
+{
+ A_PRINTF("Disconnect Data : BSSID: ");
+ AR6000_PRINT_BSSID(p->disassoc_bssid);
+ A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
+ p->disassoc_bss_rssi,p->disassoc_time,
+ p->no_txrx_time);
+ A_PRINTF("Connect Data: BSSID: ");
+ AR6000_PRINT_BSSID(p->assoc_bssid);
+ A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
+ p->assoc_bss_rssi,p->assoc_time,
+ p->allow_txrx_time);
+}
+
+void
+ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p)
+{
+ switch (p->roamDataType) {
+ case ROAM_DATA_TIME:
+ ar6000_display_roam_time(&p->u.roamTime);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len)
+{
+ struct sk_buff *skb;
+ WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap;
+
+
+ if (!ar->arMgmtFilter) {
+ return;
+ }
+ if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) &&
+ (bih->frameType != BEACON_FTYPE)) ||
+ ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) &&
+ (bih->frameType != PROBERESP_FTYPE)))
+ {
+ return;
+ }
+
+ if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) {
+
+ A_NETBUF_PUT(skb, len);
+ A_MEMCPY(A_NETBUF_DATA(skb), datap, len);
+ skb->dev = ar->arNetDev;
+ A_MEMCPY(skb_mac_header(skb), A_NETBUF_DATA(skb), 6);
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = __constant_htons(0x0019);
+ netif_rx(skb);
+ }
+}
+
+A_UINT32 wmiSendCmdNum;
+
+A_STATUS
+ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+ A_STATUS status = A_OK;
+ struct ar_cookie *cookie = NULL;
+ int i;
+#ifdef CONFIG_PM
+ if (ar->arWowState != WLAN_WOW_STATE_NONE) {
+ A_NETBUF_FREE(osbuf);
+ return A_EACCES;
+ }
+#endif /* CONFIG_PM */
+ /* take lock to protect ar6000_alloc_cookie() */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ do {
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n",
+ (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid));
+
+ if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) {
+ /* control endpoint is full, don't allocate resources, we
+ * are just going to drop this packet */
+ cookie = NULL;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n",
+ (unsigned long)osbuf, A_NETBUF_LEN(osbuf)));
+ } else {
+ cookie = ar6000_alloc_cookie(ar);
+ }
+
+ if (cookie == NULL) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ if(logWmiRawMsgs) {
+ A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum);
+ for(i = 0; i < a_netbuf_to_len(osbuf); i++)
+ A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]);
+ A_PRINTF("\n");
+ }
+
+ wmiSendCmdNum++;
+
+ } while (FALSE);
+
+ if (cookie != NULL) {
+ /* got a structure to send it out on */
+ ar->arTxPending[eid]++;
+
+ if (eid != ar->arControlEp) {
+ ar->arTotalTxDataPending++;
+ }
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (cookie != NULL) {
+ cookie->arc_bp[0] = (unsigned long)osbuf;
+ cookie->arc_bp[1] = 0;
+ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
+ cookie,
+ A_NETBUF_DATA(osbuf),
+ A_NETBUF_LEN(osbuf),
+ eid,
+ AR6K_CONTROL_PKT_TAG);
+ /* this interface is asynchronous, if there is an error, cleanup will happen in the
+ * TX completion callback */
+ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);
+ status = A_OK;
+ }
+
+ if (status != A_OK) {
+ A_NETBUF_FREE(osbuf);
+ }
+ return status;
+}
+
+/* indicate tx activity or inactivity on a WMI stream */
+void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+ HTC_ENDPOINT_ID eid ;
+ int i;
+
+ if (ar->arWmiEnabled) {
+ eid = arAc2EndpointID(ar, TrafficClass);
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+ ar->arAcStreamActive[TrafficClass] = Active;
+
+ if (Active) {
+ /* when a stream goes active, keep track of the active stream with the highest priority */
+
+ if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) {
+ /* set the new highest active priority */
+ ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass];
+ }
+
+ } else {
+ /* when a stream goes inactive, we may have to search for the next active stream
+ * that is the highest priority */
+
+ if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) {
+
+ /* the highest priority stream just went inactive */
+
+ /* reset and search for the "next" highest "active" priority stream */
+ ar->arHiAcStreamActivePri = 0;
+ for (i = 0; i < WMM_NUM_AC; i++) {
+ if (ar->arAcStreamActive[i]) {
+ if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) {
+ /* set the new highest active priority */
+ ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i];
+ }
+ }
+ }
+ }
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ } else {
+ /* for mbox ping testing, the traffic class is mapped directly as a stream ID,
+ * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c
+ * convert the stream ID to a endpoint */
+ eid = arAc2EndpointID(ar, TrafficClass);
+ }
+
+ /* notify HTC, this may cause credit distribution changes */
+
+ HTCIndicateActivityChange(ar->arHtcTarget,
+ eid,
+ Active);
+
+}
+
+void
+ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len)
+{
+
+ WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr;
+ WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
+
+ A_PRINTF("received config event\n");
+ pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType;
+ pArbtcoexConfig->linkId = pBtcoexConfig->linkId;
+
+ switch (pBtcoexConfig->btProfileType) {
+ case WMI_BTCOEX_BT_PROFILE_SCO:
+ A_MEMCPY(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd,
+ sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
+ break;
+ case WMI_BTCOEX_BT_PROFILE_A2DP:
+ A_MEMCPY(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd,
+ sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
+ break;
+ case WMI_BTCOEX_BT_PROFILE_ACLCOEX:
+ A_MEMCPY(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig,
+ sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
+ break;
+ case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE:
+ A_MEMCPY(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd,
+ sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
+ break;
+ }
+ if (ar->statsUpdatePending) {
+ ar->statsUpdatePending = FALSE;
+ wake_up(&arEvent);
+ }
+}
+
+void
+ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len)
+{
+ WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n"));
+
+ A_MEMCPY(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT));
+
+ if (ar->statsUpdatePending) {
+ ar->statsUpdatePending = FALSE;
+ wake_up(&arEvent);
+ }
+
+}
+module_init(ar6000_init_module);
+module_exit(ar6000_cleanup_module);
+
+/* Init cookie queue */
+static void
+ar6000_cookie_init(AR_SOFTC_T *ar)
+{
+ A_UINT32 i;
+
+ ar->arCookieList = NULL;
+ ar->arCookieCount = 0;
+
+ A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
+
+ for (i = 0; i < MAX_COOKIE_NUM; i++) {
+ ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
+ }
+}
+
+/* cleanup cookie queue */
+static void
+ar6000_cookie_cleanup(AR_SOFTC_T *ar)
+{
+ /* It is gone .... */
+ ar->arCookieList = NULL;
+ ar->arCookieCount = 0;
+}
+
+/* Init cookie queue */
+static void
+ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie)
+{
+ /* Insert first */
+ A_ASSERT(ar != NULL);
+ A_ASSERT(cookie != NULL);
+
+ cookie->arc_list_next = ar->arCookieList;
+ ar->arCookieList = cookie;
+ ar->arCookieCount++;
+}
+
+/* cleanup cookie queue */
+static struct ar_cookie *
+ar6000_alloc_cookie(AR_SOFTC_T *ar)
+{
+ struct ar_cookie *cookie;
+
+ cookie = ar->arCookieList;
+ if(cookie != NULL)
+ {
+ ar->arCookieList = cookie->arc_list_next;
+ ar->arCookieCount--;
+ }
+
+ return cookie;
+}
+
+#ifdef SEND_EVENT_TO_APP
+/*
+ * This function is used to send event which come from taget to
+ * the application. The buf which send to application is include
+ * the event ID and event content.
+ */
+#define EVENT_ID_LEN 2
+void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
+ A_UINT8 *datap, int len)
+{
+
+#if (WIRELESS_EXT >= 15)
+
+/* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
+
+ char *buf;
+ A_UINT16 size;
+ union iwreq_data wrqu;
+
+ size = len + EVENT_ID_LEN;
+
+ if (size > IW_CUSTOM_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
+ eventId, size, IW_CUSTOM_MAX));
+ return;
+ }
+
+ buf = A_MALLOC_NOWAIT(size);
+ if (NULL == buf){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
+ return;
+ }
+
+ A_MEMZERO(buf, size);
+ A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
+ A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
+
+ //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(A_UINT16*)buf, size));
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = size;
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+ A_FREE(buf);
+#endif
+
+
+}
+
+/*
+ * This function is used to send events larger than 256 bytes
+ * to the application. The buf which is sent to application
+ * includes the event ID and event content.
+ */
+void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId,
+ A_UINT8 *datap, int len)
+{
+
+#if (WIRELESS_EXT >= 18)
+
+/* IWEVGENIE exists in wireless extensions version 18 onwards */
+
+ char *buf;
+ A_UINT16 size;
+ union iwreq_data wrqu;
+
+ size = len + EVENT_ID_LEN;
+
+ if (size > IW_GENERIC_IE_MAX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVGENIE (max=%d) \n",
+ eventId, size, IW_GENERIC_IE_MAX));
+ return;
+ }
+
+ buf = A_MALLOC_NOWAIT(size);
+ if (NULL == buf){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
+ return;
+ }
+
+ A_MEMZERO(buf, size);
+ A_MEMCPY(buf, &eventId, EVENT_ID_LEN);
+ A_MEMCPY(buf+EVENT_ID_LEN, datap, len);
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = size;
+ wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf);
+
+ A_FREE(buf);
+
+#endif /* (WIRELESS_EXT >= 18) */
+
+}
+#endif /* SEND_EVENT_TO_APP */
+
+
+void
+ar6000_tx_retry_err_event(void *devt)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n"));
+}
+
+void
+ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UINT8 snr)
+{
+ WMI_SNR_THRESHOLD_EVENT event;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ event.range = newThreshold;
+ event.snr = snr;
+
+ ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (A_UINT8 *)&event,
+ sizeof(WMI_SNR_THRESHOLD_EVENT));
+}
+
+void
+ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT8 lq)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq));
+}
+
+
+
+A_UINT32
+a_copy_to_user(void *to, const void *from, A_UINT32 n)
+{
+ return(copy_to_user(to, from, n));
+}
+
+A_UINT32
+a_copy_from_user(void *to, const void *from, A_UINT32 n)
+{
+ return(copy_from_user(to, from, n));
+}
+
+
+A_STATUS
+ar6000_get_driver_cfg(struct net_device *dev,
+ A_UINT16 cfgParam,
+ void *result)
+{
+
+ A_STATUS ret = 0;
+
+ switch(cfgParam)
+ {
+ case AR6000_DRIVER_CFG_GET_WLANNODECACHING:
+ *((A_UINT32 *)result) = wlanNodeCaching;
+ break;
+ case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS:
+ *((A_UINT32 *)result) = logWmiRawMsgs;
+ break;
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+void
+ar6000_keepalive_rx(void *devt, A_UINT8 configured)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+ ar->arKeepaliveConfigured = configured;
+ wake_up(&arEvent);
+}
+
+void
+ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList,
+ A_UINT8 *bssidList)
+{
+ A_UINT8 i, j;
+
+ A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID);
+
+ for (i = 0; i < numPMKID; i++) {
+ A_PRINTF("\nBSSID %d ", i);
+ for (j = 0; j < ATH_MAC_LEN; j++) {
+ A_PRINTF("%2.2x", bssidList[j]);
+ }
+ bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN);
+ A_PRINTF("\nPMKID %d ", i);
+ for (j = 0; j < WMI_PMKID_LEN; j++) {
+ A_PRINTF("%2.2x", pmkidList->pmkid[j]);
+ }
+ pmkidList = (WMI_PMKID *)((A_UINT8 *)pmkidList + ATH_MAC_LEN +
+ WMI_PMKID_LEN);
+ }
+}
+
+void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid)
+{
+ sta_t *conn=NULL;
+ A_BOOL isPsqEmpty = FALSE;
+
+ conn = ieee80211_find_conn_for_aid(ar, aid);
+
+ /* If the PS q for this STA is not empty, dequeue and send a pkt from
+ * the head of the q. Also update the More data bit in the WMI_DATA_HDR
+ * if there are more pkts for this STA in the PS q. If there are no more
+ * pkts for this STA, update the PVB for this STA.
+ */
+ A_MUTEX_LOCK(&conn->psqLock);
+ isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
+ A_MUTEX_UNLOCK(&conn->psqLock);
+
+ if (isPsqEmpty) {
+ /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
+ } else {
+ struct sk_buff *skb = NULL;
+
+ A_MUTEX_LOCK(&conn->psqLock);
+ skb = A_NETBUF_DEQUEUE(&conn->psq);
+ A_MUTEX_UNLOCK(&conn->psqLock);
+ /* Set the STA flag to PSPolled, so that the frame will go out */
+ STA_SET_PS_POLLED(conn);
+ ar6000_data_tx(skb, ar->arNetDev);
+ STA_CLR_PS_POLLED(conn);
+
+ /* Clear the PVB for this STA if the queue has become empty */
+ A_MUTEX_LOCK(&conn->psqLock);
+ isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq);
+ A_MUTEX_UNLOCK(&conn->psqLock);
+
+ if (isPsqEmpty) {
+ wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
+ }
+ }
+}
+
+void ar6000_dtimexpiry_event(AR_SOFTC_T *ar)
+{
+ A_BOOL isMcastQueued = FALSE;
+ struct sk_buff *skb = NULL;
+
+ /* If there are no associated STAs, ignore the DTIM expiry event.
+ * There can be potential race conditions where the last associated
+ * STA may disconnect & before the host could clear the 'Indicate DTIM'
+ * request to the firmware, the firmware would have just indicated a DTIM
+ * expiry event. The race is between 'clear DTIM expiry cmd' going
+ * from the host to the firmware & the DTIM expiry event happening from
+ * the firmware to the host.
+ */
+ if (ar->sta_list_index == 0) {
+ return;
+ }
+
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+
+ A_ASSERT(isMcastQueued == FALSE);
+
+ /* Flush the mcast psq to the target */
+ /* Set the STA flag to DTIMExpired, so that the frame will go out */
+ ar->DTIMExpired = TRUE;
+
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
+ skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+
+ ar6000_data_tx(skb, ar->arNetDev);
+
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ }
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+
+ /* Reset the DTIMExpired flag back to 0 */
+ ar->DTIMExpired = FALSE;
+
+ /* Clear the LSB of the BitMapCtl field of the TIM IE */
+ wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
+}
+
+void
+read_rssi_compensation_param(AR_SOFTC_T *ar)
+{
+ A_UINT8 *cust_data_ptr;
+
+//#define RSSICOMPENSATION_PRINT
+
+#ifdef RSSICOMPENSATION_PRINT
+ A_INT16 i;
+ cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
+ for (i=0; i<16; i++) {
+ A_PRINTF("cust_data_%d = %x \n", i, *(A_UINT8 *)cust_data_ptr);
+ cust_data_ptr += 1;
+ }
+#endif
+
+ cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType);
+
+ rssi_compensation_param.customerID = *(A_UINT16 *)cust_data_ptr & 0xffff;
+ rssi_compensation_param.enable = *(A_UINT16 *)(cust_data_ptr+2) & 0xffff;
+ rssi_compensation_param.bg_param_a = *(A_UINT16 *)(cust_data_ptr+4) & 0xffff;
+ rssi_compensation_param.bg_param_b = *(A_UINT16 *)(cust_data_ptr+6) & 0xffff;
+ rssi_compensation_param.a_param_a = *(A_UINT16 *)(cust_data_ptr+8) & 0xffff;
+ rssi_compensation_param.a_param_b = *(A_UINT16 *)(cust_data_ptr+10) &0xffff;
+ rssi_compensation_param.reserved = *(A_UINT32 *)(cust_data_ptr+12);
+
+#ifdef RSSICOMPENSATION_PRINT
+ A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID);
+ A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable);
+ A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a);
+ A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b);
+ A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a);
+ A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b);
+ A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved);
+#endif
+
+ if (rssi_compensation_param.enable != 0x1) {
+ rssi_compensation_param.enable = 0;
+ }
+
+ return;
+}
+
+A_INT32
+rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt)
+{
+
+ if (freq > 5000)
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
+ rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b;
+ rssi = (rssi-50) /100;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
+ }
+ }
+ else
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt));
+ rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b;
+ rssi = (rssi-50) /100;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
+ }
+ }
+
+ return rssi;
+}
+
+A_INT16
+rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi)
+{
+ if (ar->arBssChannel > 5000)
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
+ rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b;
+ rssi = (rssi-50) /100;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
+ }
+ }
+ else
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi));
+ rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b;
+ rssi = (rssi-50) /100;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi));
+ }
+ }
+
+ return rssi;
+}
+
+A_INT16
+rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, A_BOOL Above)
+{
+ A_INT16 i;
+
+ if (ar->arBssChannel > 5000)
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
+ rssi = rssi * 100;
+ rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
+ }
+ }
+ else
+ {
+ if (rssi_compensation_param.enable)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n"));
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi));
+
+ if (Above) {
+ for (i=95; i>=0; i--) {
+ if (rssi <= rssi_compensation_table[i]) {
+ rssi = 0 - i;
+ break;
+ }
+ }
+ } else {
+ for (i=0; i<=95; i++) {
+ if (rssi >= rssi_compensation_table[i]) {
+ rssi = 0 - i;
+ break;
+ }
+ }
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi));
+ }
+ }
+
+ return rssi;
+}
+
+#ifdef WAPI_ENABLE
+void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac)
+{
+ union iwreq_data wrqu;
+ A_CHAR buf[20];
+
+ A_MEMZERO(buf, sizeof(buf));
+
+ strcpy(buf, "WAPI_REKEY");
+ buf[10] = type;
+ A_MEMCPY(&buf[11], mac, ATH_MAC_LEN);
+
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = 10+1+ATH_MAC_LEN;
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+
+ A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]);
+}
+#endif
+
+#ifdef USER_KEYS
+static A_STATUS
+
+ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl)
+{
+ A_STATUS status = A_OK;
+ struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik;
+ struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik;
+ CRYPTO_TYPE keyType = ar->user_saved_keys.keyType;
+
+ if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) {
+ if (NONE_CRYPT == keyType) {
+ goto _reinstall_keys_out;
+ }
+
+ if (uik->ik_keylen) {
+ status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix,
+ ar->user_saved_keys.keyType, PAIRWISE_USAGE,
+ uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc,
+ uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG);
+ }
+
+ } else {
+ status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata);
+ }
+
+ if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) {
+ if (NONE_CRYPT == keyType) {
+ goto _reinstall_keys_out;
+ }
+
+ if (bik->ik_keylen) {
+ status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix,
+ ar->user_saved_keys.keyType, GROUP_USAGE,
+ bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc,
+ bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG);
+ }
+ } else {
+ status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata);
+ }
+
+_reinstall_keys_out:
+ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
+ ar->user_key_ctrl = 0;
+
+ return status;
+}
+#endif /* USER_KEYS */
+
+
+void
+ar6000_dset_open_req(
+ void *context,
+ A_UINT32 id,
+ A_UINT32 targHandle,
+ A_UINT32 targReplyFn,
+ A_UINT32 targReplyArg)
+{
+}
+
+void
+ar6000_dset_close(
+ void *context,
+ A_UINT32 access_cookie)
+{
+ return;
+}
+
+void
+ar6000_dset_data_req(
+ void *context,
+ A_UINT32 accessCookie,
+ A_UINT32 offset,
+ A_UINT32 length,
+ A_UINT32 targBuf,
+ A_UINT32 targReplyFn,
+ A_UINT32 targReplyArg)
+{
+}
+
+int
+ar6000_ap_mode_profile_commit(struct ar6_softc *ar)
+{
+ WMI_CONNECT_CMD p;
+ unsigned long flags;
+
+ /* No change in AP's profile configuration */
+ if(ar->ap_profile_flag==0) {
+ A_PRINTF("COMMIT: No change in profile!!!\n");
+ return -ENODATA;
+ }
+
+ if(!ar->arSsidLen) {
+ A_PRINTF("SSID not set!!!\n");
+ return -ECHRNG;
+ }
+
+ switch(ar->arAuthMode) {
+ case NONE_AUTH:
+ if((ar->arPairwiseCrypto != NONE_CRYPT) &&
+#ifdef WAPI_ENABLE
+ (ar->arPairwiseCrypto != WAPI_CRYPT) &&
+#endif
+ (ar->arPairwiseCrypto != WEP_CRYPT)) {
+ A_PRINTF("Cipher not supported in AP mode Open auth\n");
+ return -EOPNOTSUPP;
+ }
+ break;
+ case WPA_PSK_AUTH:
+ case WPA2_PSK_AUTH:
+ case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
+ break;
+ default:
+ A_PRINTF("This key mgmt type not supported in AP mode\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* Update the arNetworkType */
+ ar->arNetworkType = ar->arNextMode;
+
+ A_MEMZERO(&p,sizeof(p));
+ p.ssidLength = ar->arSsidLen;
+ A_MEMCPY(p.ssid,ar->arSsid,p.ssidLength);
+ p.channel = ar->arChannelHint;
+ p.networkType = ar->arNetworkType;
+
+ p.dot11AuthMode = ar->arDot11AuthMode;
+ p.authMode = ar->arAuthMode;
+ p.pairwiseCryptoType = ar->arPairwiseCrypto;
+ p.pairwiseCryptoLen = ar->arPairwiseCryptoLen;
+ p.groupCryptoType = ar->arGroupCrypto;
+ p.groupCryptoLen = ar->arGroupCryptoLen;
+ p.ctrl_flags = ar->arConnectCtrlFlags;
+
+ ar->arConnected = FALSE;
+
+ wmi_ap_profile_commit(ar->arWmi, &p);
+ spin_lock_irqsave(&ar->arLock, flags);
+ ar->arConnected = TRUE;
+ netif_carrier_on(ar->arNetDev);
+ spin_unlock_irqrestore(&ar->arLock, flags);
+ ar->ap_profile_flag = 0;
+ return 0;
+}
+
+A_STATUS
+ar6000_connect_to_ap(struct ar6_softc *ar)
+{
+ /* The ssid length check prevents second "essid off" from the user,
+ to be treated as a connect cmd. The second "essid off" is ignored.
+ */
+ if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK)
+ {
+ A_STATUS status;
+ if((ADHOC_NETWORK != ar->arNetworkType) &&
+ (NONE_AUTH==ar->arAuthMode) &&
+ (WEP_CRYPT==ar->arPairwiseCrypto)) {
+ ar6000_install_static_wep_keys(ar);
+ }
+
+ if (!ar->arUserBssFilter) {
+ if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
+ return -EIO;
+ }
+ }
+#ifdef WAPI_ENABLE
+ if (ar->arWapiEnable) {
+ ar->arPairwiseCrypto = WAPI_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = WAPI_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ ar->arAuthMode = NONE_AUTH;
+ ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER;
+ }
+#endif
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\
+ " PW crypto %d PW crypto Len %d GRP crypto %d"\
+ " GRP crypto Len %d\n",
+ ar->arAuthMode, ar->arDot11AuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto, ar->arGroupCryptoLen));
+ reconnect_flag = 0;
+ /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn.
+ later set it back locally at the STA to 100/1000 TUs depending on the power mode */
+ if ((ar->arNetworkType == INFRA_NETWORK)) {
+ wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (A_UINT16)A_MAX_WOW_LISTEN_INTERVAL), 0);
+ }
+ status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
+ ar->arDot11AuthMode, ar->arAuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto,ar->arGroupCryptoLen,
+ ar->arSsidLen, ar->arSsid,
+ ar->arReqBssid, ar->arChannelHint,
+ ar->arConnectCtrlFlags);
+ if (status != A_OK) {
+ wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB);
+ if (!ar->arUserBssFilter) {
+ wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
+ }
+ return status;
+ }
+
+ if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
+ ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
+ {
+ A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
+ }
+
+ ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
+
+ ar->arConnectPending = TRUE;
+ return status;
+ }
+ return A_ERROR;
+}
+
+A_STATUS
+ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie)
+{
+ sta_t *conn = NULL;
+ conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr);
+
+ A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE);
+ A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE);
+
+ if(conn) {
+ A_MEMCPY(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE);
+ }
+
+ return 0;
+}
+
+A_STATUS
+is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd)
+{
+ if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) {
+ cmd -= SIOCSIWCOMMIT;
+ if(sioctl_filter[cmd] == 0xFF) return A_OK;
+ if(sioctl_filter[cmd] & mode) return A_OK;
+ } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) {
+ cmd -= SIOCIWFIRSTPRIV;
+ if(pioctl_filter[cmd] == 0xFF) return A_OK;
+ if(pioctl_filter[cmd] & mode) return A_OK;
+ } else {
+ return A_ERROR;
+ }
+ return A_ENOTSUP;
+}
+
+A_STATUS
+is_xioctl_allowed(A_UINT8 mode, int cmd)
+{
+ if(sizeof(xioctl_filter)-1 < cmd) {
+ A_PRINTF("Filter for this cmd=%d not defined\n",cmd);
+ return 0;
+ }
+ if(xioctl_filter[cmd] == 0xFF) return A_OK;
+ if(xioctl_filter[cmd] & mode) return A_OK;
+ return A_ERROR;
+}
+
+#ifdef WAPI_ENABLE
+int
+ap_set_wapi_key(struct ar6_softc *ar, void *ikey)
+{
+ struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey;
+ KEY_USAGE keyUsage = 0;
+ A_STATUS status;
+
+ if (A_MEMCMP(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) {
+ keyUsage = GROUP_USAGE;
+ } else {
+ keyUsage = PAIRWISE_USAGE;
+ }
+ A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n",
+ keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5],
+ ik->ik_keylen);
+
+ status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage,
+ ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
+ ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
+ SYNC_BOTH_WMIFLAG);
+
+ if (A_OK != status) {
+ return -EIO;
+ }
+ return 0;
+}
+#endif
+
+void ar6000_peer_event(
+ void *context,
+ A_UINT8 eventCode,
+ A_UINT8 *macAddr)
+{
+ A_UINT8 pos;
+
+ for (pos=0;pos<6;pos++)
+ printk("%02x: ",*(macAddr+pos));
+ printk("\n");
+}
+
+#ifdef HTC_TEST_SEND_PKTS
+#define HTC_TEST_DUPLICATE 8
+static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb)
+{
+ struct ar_cookie *cookie;
+ struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE];
+ struct sk_buff *new_skb;
+ int i;
+ int pkts = 0;
+ HTC_PACKET_QUEUE pktQueue;
+ EPPING_HEADER *eppingHdr;
+
+ eppingHdr = A_NETBUF_DATA(dupskb);
+
+ if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) {
+ /* skip test if this is already a tx perf test */
+ return;
+ }
+
+ for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ cookie = ar6000_alloc_cookie(ar);
+ if (cookie != NULL) {
+ ar->arTxPending[eid]++;
+ ar->arTotalTxDataPending++;
+ }
+
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+ if (NULL == cookie) {
+ break;
+ }
+
+ new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb));
+
+ if (new_skb == NULL) {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar6000_free_cookie(ar,cookie);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ break;
+ }
+
+ A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb));
+ cookie->arc_bp[0] = (unsigned long)new_skb;
+ cookie->arc_bp[1] = MapNo;
+ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
+ cookie,
+ A_NETBUF_DATA(new_skb),
+ A_NETBUF_LEN(new_skb),
+ eid,
+ AR6K_DATA_PKT_TAG);
+
+ cookieArray[i] = cookie;
+
+ {
+ EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb);
+ pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */
+ }
+ }
+
+ if (pkts == 0) {
+ return;
+ }
+
+ INIT_HTC_PACKET_QUEUE(&pktQueue);
+
+ for (i = 0; i < pkts; i++) {
+ HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt);
+ }
+
+ HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue);
+
+}
+#endif
+
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+/*
+ * Add support for adding and removing a virtual adapter for soft AP.
+ * Some OS requires different adapters names for station and soft AP mode.
+ * To support these requirement, create and destory a netdevice instance
+ * when the AP mode is operational. A full fledged support for virual device
+ * is not implemented. Rather a virtual interface is created and is linked
+ * with the existing physical device instance during the operation of the
+ * AP mode.
+ */
+
+A_STATUS ar6000_start_ap_interface(AR_SOFTC_T *ar)
+{
+ AR_VIRTUAL_INTERFACE_T *arApDev;
+
+ /* Change net_device to point to AP instance */
+ arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev;
+ ar->arNetDev = arApDev->arNetDev;
+
+ return A_OK;
+}
+
+A_STATUS ar6000_stop_ap_interface(AR_SOFTC_T *ar)
+{
+ AR_VIRTUAL_INTERFACE_T *arApDev;
+
+ /* Change net_device to point to sta instance */
+ arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev;
+ if (arApDev) {
+ ar->arNetDev = arApDev->arStaNetDev;
+ }
+
+ return A_OK;
+}
+
+
+A_STATUS ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname)
+{
+ struct net_device *dev;
+ AR_VIRTUAL_INTERFACE_T *arApDev;
+
+ dev = alloc_etherdev(sizeof(AR_VIRTUAL_INTERFACE_T));
+ if (dev == NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n"));
+ return A_ERROR;
+ }
+
+ ether_setup(dev);
+ init_netdev(dev, ap_ifname);
+
+ if (register_netdev(dev)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
+ return A_ERROR;
+ }
+
+ arApDev = netdev_priv(dev);
+ arApDev->arDev = ar;
+ arApDev->arNetDev = dev;
+ arApDev->arStaNetDev = ar->arNetDev;
+
+ ar->arApDev = arApDev;
+ arApNetDev = dev;
+
+ /* Copy the MAC address */
+ A_MEMCPY(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN);
+
+ return A_OK;
+}
+
+A_STATUS ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname)
+{
+ /* Interface already added, need not proceed further */
+ if (ar->arApDev != NULL) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n"));
+ return A_OK;
+ }
+
+ if (ar6000_create_ap_interface(ar, ap_ifname) != A_OK) {
+ return A_ERROR;
+ }
+
+ A_PRINTF("Add AP interface %s \n",ap_ifname);
+
+ return ar6000_start_ap_interface(ar);
+}
+
+A_STATUS ar6000_remove_ap_interface(AR_SOFTC_T *ar)
+{
+ if (arApNetDev) {
+ ar6000_stop_ap_interface(ar);
+
+ unregister_netdev(arApNetDev);
+#ifndef free_netdev
+ kfree(arApNetDev);
+#else
+ free_netdev(apApNetDev);
+#endif
+
+ A_PRINTF("Remove AP interface\n");
+ }
+ ar->arApDev = NULL;
+ arApNetDev = NULL;
+
+
+ return A_OK;
+}
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+EXPORT_SYMBOL(setupbtdev);
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
new file mode 100644
index 000000000000..b937df9c0cb5
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c
@@ -0,0 +1,731 @@
+/*
+ *
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ *
+//
+// 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.
+//
+//
+ *
+ */
+
+/*
+ * Implementation of system power management
+ */
+
+#include "ar6000_drv.h"
+#include <linux/inetdevice.h>
+#include <linux/platform_device.h>
+#include "wlan_config.h"
+
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+
+#define WOW_ENABLE_MAX_INTERVAL 0
+#define WOW_SET_SCAN_PARAMS 0
+
+extern unsigned int wmitimeout;
+extern wait_queue_head_t arEvent;
+
+#ifdef CONFIG_PM
+#ifdef CONFIG_HAS_WAKELOCK
+struct wake_lock ar6k_suspend_wake_lock;
+struct wake_lock ar6k_wow_wake_lock;
+#endif
+#endif /* CONFIG_PM */
+
+#ifdef ANDROID_ENV
+extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent);
+#endif
+#undef ATH_MODULE_NAME
+#define ATH_MODULE_NAME pm
+#define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0)
+
+#ifdef DEBUG
+static ATH_DEBUG_MASK_DESCRIPTION pm_debug_desc[] = {
+ { ATH_DEBUG_PM , "System power management"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm,
+ "pm",
+ "System Power Management",
+ ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM,
+ ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc),
+ pm_debug_desc);
+
+#endif /* DEBUG */
+
+A_STATUS ar6000_exit_cut_power_state(AR_SOFTC_T *ar);
+
+#ifdef CONFIG_PM
+static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, A_BOOL asleep)
+{
+ char buf[128];
+ union iwreq_data wrqu;
+
+ snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake");
+ A_MEMZERO(&wrqu, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+}
+
+static void ar6000_wow_resume(AR_SOFTC_T *ar)
+{
+ if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
+ A_UINT16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
+ A_UINT16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period;
+ WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {TRUE, FALSE};
+ ar->arWowState = WLAN_WOW_STATE_NONE;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ);
+#endif
+ if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n"));
+ }
+#if WOW_SET_SCAN_PARAMS
+ wmi_scanparams_cmd(ar->arWmi, fg_start_period,
+ ar->scParams.fg_end_period,
+ bg_period,
+ ar->scParams.minact_chdwell_time,
+ ar->scParams.maxact_chdwell_time,
+ ar->scParams.pas_chdwell_time,
+ ar->scParams.shortScanRatio,
+ ar->scParams.scanCtrlFlags,
+ ar->scParams.max_dfsch_act_time,
+ ar->scParams.maxact_scan_per_ssid);
+#else
+ (void)fg_start_period;
+ (void)bg_period;
+#endif
+
+
+#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
+ if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == A_OK) {
+ }
+#endif
+ ar6k_send_asleep_event_to_app(ar, FALSE);
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n"));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume"));
+ }
+ ar->arWlanPowerState = WLAN_POWER_STATE_ON;
+}
+
+static void ar6000_wow_suspend(AR_SOFTC_T *ar)
+{
+#define WOW_LIST_ID 1
+ if (ar->arNetworkType != AP_NETWORK) {
+ /* Setup WoW for unicast & Arp request for our own IP
+ disable background scan. Set listen interval into 1000 TUs
+ Enable keepliave for 110 seconds
+ */
+ struct in_ifaddr **ifap = NULL;
+ struct in_ifaddr *ifa = NULL;
+ struct in_device *in_dev;
+ A_UINT8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ A_STATUS status;
+ WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } };
+ WMI_DEL_WOW_PATTERN_CMD delWowCmd;
+ WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {FALSE, TRUE};
+ WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = TRUE,
+ .hostReqDelay = 500 };/*500 ms delay*/
+
+ if (ar->arWowState!= WLAN_WOW_STATE_NONE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n"));
+ return;
+ }
+
+ ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/
+
+#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */
+ if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == A_OK) {
+ }
+#endif
+
+#if WOW_SET_SCAN_PARAMS
+ status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0);
+#endif
+ /* clear up our WoW pattern first */
+ delWowCmd.filter_list_id = WOW_LIST_ID;
+ delWowCmd.filter_id = 0;
+ wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd);
+
+ /* setup unicast packet pattern for WoW */
+ if (ar->arNetDev->dev_addr[1]) {
+ addWowCmd.filter_list_id = WOW_LIST_ID;
+ addWowCmd.filter_size = 6; /* MAC address */
+ addWowCmd.filter_offset = 0;
+ status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n"));
+ }
+ }
+ /* setup ARP request for our own IP */
+ if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) {
+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) {
+ if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) {
+ break; /* found */
+ }
+ }
+ }
+ if (ifa && ifa->ifa_local) {
+ WMI_SET_IP_CMD ipCmd;
+ memset(&ipCmd, 0, sizeof(ipCmd));
+ ipCmd.ips[0] = ifa->ifa_local;
+ status = wmi_set_ip_cmd(ar->arWmi, &ipCmd);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n"));
+ }
+ }
+
+#ifndef ATH6K_CONFIG_OTA_MODE
+ wmi_powermode_cmd(ar->arWmi, REC_POWER);
+#endif
+
+ status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n"));
+ }
+ ar6k_send_asleep_event_to_app(ar, TRUE);
+
+ status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n"));
+ }
+
+ ar->arWowState = WLAN_WOW_STATE_SUSPENDING;
+ if (ar->arTxPending[ar->arControlEp]) {
+ A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent,
+ ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
+ if (!timeleft || signal_pending(current)) {
+ /* what can I do? wow resume at once */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp]));
+ }
+ }
+
+ status = hifWaitForPendingRecv(ar->arHifDevice);
+
+ ar->arWowState = WLAN_WOW_STATE_SUSPENDED;
+ ar->arWlanPowerState = WLAN_POWER_STATE_WOW;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n"));
+ }
+}
+
+A_STATUS ar6000_suspend_ev(void *context)
+{
+ A_STATUS status = A_OK;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
+ A_INT16 pmmode = ar->arSuspendConfig;
+wow_not_connected:
+ switch (pmmode) {
+ case WLAN_SUSPEND_WOW:
+ if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) {
+ ar6000_wow_suspend(ar);
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState));
+ } else {
+ pmmode = ar->arWow2Config;
+ goto wow_not_connected;
+ }
+ break;
+ case WLAN_SUSPEND_CUT_PWR:
+ /* fall through */
+ case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF:
+ /* fall through */
+ case WLAN_SUSPEND_DEEP_SLEEP:
+ /* fall through */
+ default:
+ status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, TRUE);
+ if (ar->arWlanPowerState==WLAN_POWER_STATE_ON ||
+ ar->arWlanPowerState==WLAN_POWER_STATE_WOW) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState));
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status));
+ status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? A_OK : A_EBUSY;
+ break;
+ }
+
+ ar->scan_triggered = 0;
+ return status;
+}
+
+A_STATUS ar6000_resume_ev(void *context)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
+ A_UINT16 powerState = ar->arWlanPowerState;
+
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock(&ar6k_suspend_wake_lock);
+#endif
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState));
+ switch (powerState) {
+ case WLAN_POWER_STATE_WOW:
+ ar6000_wow_resume(ar);
+ break;
+ case WLAN_POWER_STATE_CUT_PWR:
+ /* fall through */
+ case WLAN_POWER_STATE_DEEP_SLEEP:
+ ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, TRUE);
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState));
+ break;
+ case WLAN_POWER_STATE_ON:
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n"));
+ break;
+ }
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_unlock(&ar6k_suspend_wake_lock);
+#endif
+ return A_OK;
+}
+
+void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent)
+{
+ if (ar->arWowState!=WLAN_WOW_STATE_NONE) {
+ if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__));
+ return;
+ }
+ /* Wow resume from irq interrupt */
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
+ ar6000_wow_resume(ar);
+ } else {
+#ifdef ANDROID_ENV
+ android_ar6k_check_wow_status(ar, skb, isEvent);
+#endif
+ }
+}
+
+A_STATUS ar6000_power_change_ev(void *context, A_UINT32 config)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)context;
+ A_STATUS status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config));
+ switch (config) {
+ case HIF_DEVICE_POWER_UP:
+ ar6000_restart_endpoint(ar->arNetDev);
+ status = A_OK;
+ break;
+ case HIF_DEVICE_POWER_DOWN:
+ case HIF_DEVICE_POWER_CUT:
+ status = A_OK;
+ break;
+ }
+ return status;
+}
+
+static int ar6000_pm_probe(struct platform_device *pdev)
+{
+ plat_setup_power(1,1);
+ return 0;
+}
+
+static int ar6000_pm_remove(struct platform_device *pdev)
+{
+ plat_setup_power(0,1);
+ return 0;
+}
+
+static int ar6000_pm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int ar6000_pm_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver ar6000_pm_device = {
+ .probe = ar6000_pm_probe,
+ .remove = ar6000_pm_remove,
+ .suspend = ar6000_pm_suspend,
+ .resume = ar6000_pm_resume,
+ .driver = {
+ .name = "wlan_ar6000_pm",
+ },
+};
+#endif /* CONFIG_PM */
+
+A_STATUS
+ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
+{
+ A_STATUS status = A_OK;
+ HIF_DEVICE_POWER_CHANGE_TYPE config;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState));
+#ifdef CONFIG_PM
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
+#endif
+ do {
+ if (state == WLAN_ENABLED) {
+ /* Not in cut power state.. exit */
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
+ break;
+ }
+
+ plat_setup_power(1,0);
+
+ /* Change the state to ON */
+ ar->arWlanPowerState = WLAN_POWER_STATE_ON;
+
+
+ /* Indicate POWER_UP to HIF */
+ config = HIF_DEVICE_POWER_UP;
+ status = HIFConfigureDevice(ar->arHifDevice,
+ HIF_DEVICE_POWER_STATE_CHANGE,
+ &config,
+ sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
+
+ if (status == A_PENDING) {
+#ifdef ANDROID_ENV
+ /* Wait for WMI ready event */
+ A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent,
+ (ar->arWmiReady == TRUE), wmitimeout * HZ);
+ if (!timeleft || signal_pending(current)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : Failed to get wmi ready \n"));
+ status = A_ERROR;
+ break;
+ }
+#endif
+ status = A_OK;
+ } else if (status == A_OK) {
+ ar6000_restart_endpoint(ar->arNetDev);
+ status = A_OK;
+ }
+ } else if (state == WLAN_DISABLED) {
+
+
+ /* Already in cut power state.. exit */
+ if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
+ break;
+ }
+ ar6000_stop_endpoint(ar->arNetDev, TRUE, FALSE);
+
+ config = HIF_DEVICE_POWER_CUT;
+ status = HIFConfigureDevice(ar->arHifDevice,
+ HIF_DEVICE_POWER_STATE_CHANGE,
+ &config,
+ sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
+
+ plat_setup_power(0,0);
+
+ ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
+ }
+ } while (0);
+
+ return status;
+}
+
+A_STATUS
+ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
+{
+ A_STATUS status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState));
+#ifdef CONFIG_PM
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff));
+#endif
+ do {
+ WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode;
+
+ if (state == WLAN_ENABLED) {
+ A_UINT16 fg_start_period;
+
+ /* Not in deep sleep state.. exit */
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState));
+ }
+ break;
+ }
+
+ fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period;
+ hostSleepMode.awake = TRUE;
+ hostSleepMode.asleep = FALSE;
+
+ if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != A_OK) {
+ break;
+ }
+
+ /* Change the state to ON */
+ ar->arWlanPowerState = WLAN_POWER_STATE_ON;
+
+ /* Enable foreground scanning */
+ if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period,
+ ar->scParams.fg_end_period,
+ ar->scParams.bg_period,
+ ar->scParams.minact_chdwell_time,
+ ar->scParams.maxact_chdwell_time,
+ ar->scParams.pas_chdwell_time,
+ ar->scParams.shortScanRatio,
+ ar->scParams.scanCtrlFlags,
+ ar->scParams.max_dfsch_act_time,
+ ar->scParams.maxact_scan_per_ssid)) != A_OK)
+ {
+ break;
+ }
+
+ if (ar->arNetworkType != AP_NETWORK)
+ {
+ if (ar->arSsidLen) {
+ if (ar6000_connect_to_ap(ar) != A_OK) {
+ /* no need to report error if connection failed */
+ break;
+ }
+ }
+ }
+ } else if (state == WLAN_DISABLED){
+ WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = FALSE };
+
+ /* Already in deep sleep state.. exit */
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) {
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState));
+ }
+ break;
+ }
+
+ if (ar->arNetworkType != AP_NETWORK)
+ {
+ /* Disconnect from the AP and disable foreground scanning */
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ wmi_disconnect_cmd(ar->arWmi);
+ } else {
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+ }
+
+ ar->scan_triggered = 0;
+
+ if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != A_OK) {
+ break;
+ }
+
+ /* make sure we disable wow for deep sleep */
+ if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!=A_OK)
+ {
+ break;
+ }
+
+ ar6000_TxDataCleanup(ar);
+#ifndef ATH6K_CONFIG_OTA_MODE
+ wmi_powermode_cmd(ar->arWmi, REC_POWER);
+#endif
+
+ hostSleepMode.awake = FALSE;
+ hostSleepMode.asleep = TRUE;
+ if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!=A_OK) {
+ break;
+ }
+ if (ar->arTxPending[ar->arControlEp]) {
+ A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent,
+ ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ);
+ if (!timeleft || signal_pending(current)) {
+ status = A_ERROR;
+ break;
+ }
+ }
+ status = hifWaitForPendingRecv(ar->arHifDevice);
+
+ ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP;
+ }
+ } while (0);
+
+ if (status!=A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state));
+ }
+
+ return status;
+}
+
+A_STATUS
+ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL pmEvent)
+{
+ A_STATUS status = A_OK;
+ A_UINT16 powerState, oldPowerState;
+ AR6000_WLAN_STATE oldstate = ar->arWlanState;
+ A_BOOL wlanOff = ar->arWlanOff;
+#ifdef CONFIG_PM
+ A_BOOL btOff = ar->arBTOff;
+#endif /* CONFIG_PM */
+
+ if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) {
+ return A_ERROR;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return A_EBUSY;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return A_ERROR;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ return A_EBUSY;
+ }
+
+ ar->arWlanState = wlanOff ? WLAN_DISABLED : state;
+ oldPowerState = ar->arWlanPowerState;
+ if (state == WLAN_ENABLED) {
+ powerState = ar->arWlanPowerState;
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n"));
+ if (!wlanOff) {
+ if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
+ status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED);
+ } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
+ status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
+ }
+ }
+#ifdef CONFIG_PM
+ else if (pmEvent && wlanOff) {
+ A_BOOL allowCutPwr = ((!ar->arBTSharing) || btOff);
+ if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) {
+ /* Come out of cut power */
+ ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
+ status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
+ }
+ }
+#endif /* CONFIG_PM */
+ } else if (state == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n"));
+ powerState = WLAN_POWER_STATE_DEEP_SLEEP;
+#ifdef CONFIG_PM
+ if (pmEvent) { /* disable due to suspend */
+ A_BOOL suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR ||
+ (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
+ ar->arWow2Config==WLAN_SUSPEND_CUT_PWR));
+ A_BOOL suspendCutIfBtOff = ((ar->arSuspendConfig ==
+ WLAN_SUSPEND_CUT_PWR_IF_BT_OFF ||
+ (ar->arSuspendConfig == WLAN_SUSPEND_WOW &&
+ ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) &&
+ (!ar->arBTSharing || btOff));
+ if ((suspendCutPwr) ||
+ (suspendCutIfBtOff) ||
+ (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR))
+ {
+ powerState = WLAN_POWER_STATE_CUT_PWR;
+ }
+ } else {
+ if ((wlanOff) &&
+ (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) &&
+ (!ar->arBTSharing || btOff))
+ {
+ /* For BT clock sharing designs, CUT_POWER depend on BT state */
+ powerState = WLAN_POWER_STATE_CUT_PWR;
+ }
+ }
+#endif /* CONFIG_PM */
+
+ if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) {
+ if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n"));
+ ar6000_setup_cut_power_state(ar, WLAN_ENABLED);
+ }
+ status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED);
+ } else if (powerState == WLAN_POWER_STATE_CUT_PWR) {
+ status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED);
+ }
+
+ }
+
+ if (status!=A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState));
+ ar->arWlanState = oldstate;
+ } else if (status == A_OK) {
+ WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL;
+ if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) {
+ wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
+ pSleepEvent = &wmiSleepEvent;
+ } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) {
+ wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
+ pSleepEvent = &wmiSleepEvent;
+ }
+ if (pSleepEvent) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
+ ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)pSleepEvent,
+ sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
+ }
+ }
+ up(&ar->arSem);
+ return status;
+}
+
+A_STATUS
+ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 enable)
+{
+#ifdef CONFIG_PM
+ A_BOOL off = (enable == 0);
+ A_STATUS status;
+ if (ar->arBTOff == off) {
+ return A_OK;
+ }
+ ar->arBTOff = off;
+ status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, FALSE);
+ return status;
+#else
+ return A_OK;
+#endif
+}
+
+A_STATUS
+ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state)
+{
+ A_STATUS status;
+ A_BOOL off = (state == WLAN_DISABLED);
+ if (ar->arWlanOff == off) {
+ return A_OK;
+ }
+ ar->arWlanOff = off;
+ status = ar6000_update_wlan_pwr_state(ar, state, FALSE);
+ return status;
+}
+
+void ar6000_pm_init()
+{
+ A_REGISTER_MODULE_DEBUG_INFO(pm);
+#ifdef CONFIG_PM
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_init(&ar6k_suspend_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_suspend");
+ wake_lock_init(&ar6k_wow_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_wow");
+#endif
+ /*
+ * Register ar6000_pm_device into system.
+ * We should also add platform_device into the first item of array
+ * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c
+ */
+ if (platform_driver_register(&ar6000_pm_device)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: fail to register the power control driver.\n"));
+ }
+#endif /* CONFIG_PM */
+}
+
+void ar6000_pm_exit()
+{
+#ifdef CONFIG_PM
+ platform_driver_unregister(&ar6000_pm_device);
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_destroy(&ar6k_suspend_wake_lock);
+ wake_lock_destroy(&ar6k_wow_wake_lock);
+#endif
+#endif /* CONFIG_PM */
+}
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
new file mode 100644
index 000000000000..c196098f0859
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
@@ -0,0 +1,455 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#include "ar6000_drv.h"
+
+#ifdef HTC_RAW_INTERFACE
+
+static void
+ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ raw_htc_buffer *busy;
+ HTC_RAW_STREAM_ID streamID;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+
+ busy = (raw_htc_buffer *)pPacket->pPktContext;
+ A_ASSERT(busy != NULL);
+
+ if (pPacket->Status == A_ECANCELED) {
+ /*
+ * HTC provides A_ECANCELED status when it doesn't want to be refilled
+ * (probably due to a shutdown)
+ */
+ return;
+ }
+
+ streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
+ A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
+
+#ifdef CF
+ if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
+#else
+ if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
+#endif /* CF */
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
+ }
+
+ A_ASSERT((pPacket->Status != A_OK) ||
+ (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
+
+ busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
+ busy->currPtr = HTC_HEADER_LEN;
+ arRaw->read_buffer_available[streamID] = TRUE;
+ //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
+ up(&arRaw->raw_htc_read_sem[streamID]);
+
+ /* Signal the waiting process */
+ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
+ wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
+}
+
+static void
+ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
+ raw_htc_buffer *free;
+ HTC_RAW_STREAM_ID streamID;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+
+ free = (raw_htc_buffer *)pPacket->pPktContext;
+ A_ASSERT(free != NULL);
+
+ if (pPacket->Status == A_ECANCELED) {
+ /*
+ * HTC provides A_ECANCELED status when it doesn't want to be refilled
+ * (probably due to a shutdown)
+ */
+ return;
+ }
+
+ streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
+ A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
+
+#ifdef CF
+ if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
+#else
+ if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
+#endif
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
+ }
+
+ A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
+
+ free->length = 0;
+ arRaw->write_buffer_available[streamID] = TRUE;
+ up(&arRaw->raw_htc_write_sem[streamID]);
+
+ /* Signal the waiting process */
+ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
+ wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
+}
+
+/* connect to a service */
+static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar,
+ HTC_RAW_STREAM_ID StreamID)
+{
+ A_STATUS status;
+ HTC_SERVICE_CONNECT_RESP response;
+ A_UINT8 streamNo;
+ HTC_SERVICE_CONNECT_REQ connect;
+
+ do {
+
+ A_MEMZERO(&connect,sizeof(connect));
+ /* pass the stream ID as meta data to the RAW streams service */
+ streamNo = (A_UINT8)StreamID;
+ connect.pMetaData = &streamNo;
+ connect.MetaDataLength = sizeof(A_UINT8);
+ /* these fields are the same for all endpoints */
+ connect.EpCallbacks.pContext = ar;
+ connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
+ connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
+ /* simple interface, we don't need these optional callbacks */
+ connect.EpCallbacks.EpRecvRefill = NULL;
+ connect.EpCallbacks.EpSendFull = NULL;
+ connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
+
+ /* connect to the raw streams service, we may be able to get 1 or more
+ * connections, depending on WHAT is running on the target */
+ connect.ServiceID = HTC_RAW_STREAMS_SVC;
+
+ A_MEMZERO(&response,sizeof(response));
+
+ /* try to connect to the raw stream, it is okay if this fails with
+ * status HTC_SERVICE_NO_MORE_EP */
+ status = HTCConnectService(ar->arHtcTarget,
+ &connect,
+ &response);
+
+ if (A_FAILED(status)) {
+ if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
+ status = A_OK;
+ }
+ break;
+ }
+
+ /* set endpoint mapping for the RAW HTC streams */
+ arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
+ StreamID, arRawStream2EndpointID(ar,StreamID)));
+
+ } while (FALSE);
+
+ return status;
+}
+
+int ar6000_htc_raw_open(AR_SOFTC_T *ar)
+{
+ A_STATUS status;
+ int streamID, endPt, count2;
+ raw_htc_buffer *buffer;
+ HTC_SERVICE_ID servicepriority;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+ if (!arRaw) {
+ arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
+ if (arRaw) {
+ A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
+ }
+ }
+ A_ASSERT(ar->arHtcTarget != NULL);
+ if (!arRaw) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
+ return -ENOMEM;
+ }
+ /* wait for target */
+ status = HTCWaitTarget(ar->arHtcTarget);
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
+ return -ENODEV;
+ }
+
+ for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
+ arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
+ }
+
+ for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
+ /* Initialize the data structures */
+ init_MUTEX(&arRaw->raw_htc_read_sem[streamID]);
+ init_MUTEX(&arRaw->raw_htc_write_sem[streamID]);
+ init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
+ init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
+
+ /* try to connect to the raw service */
+ status = ar6000_connect_raw_service(ar,streamID);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (arRawStream2EndpointID(ar,streamID) == 0) {
+ break;
+ }
+
+ for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
+ /* Initialize the receive buffers */
+ buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
+ memset(buffer, 0, sizeof(raw_htc_buffer));
+ buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
+ memset(buffer, 0, sizeof(raw_htc_buffer));
+
+ SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
+ buffer,
+ buffer->data,
+ HTC_RAW_BUFFER_SIZE,
+ arRawStream2EndpointID(ar,streamID));
+
+ /* Queue buffers to HTC for receive */
+ if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK)
+ {
+ BMIInit();
+ return -EIO;
+ }
+ }
+
+ for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
+ /* Initialize the receive buffers */
+ buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
+ memset(buffer, 0, sizeof(raw_htc_buffer));
+ }
+
+ arRaw->read_buffer_available[streamID] = FALSE;
+ arRaw->write_buffer_available[streamID] = TRUE;
+ }
+
+ if (A_FAILED(status)) {
+ return -EIO;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
+
+ servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
+
+ /* set callbacks and priority list */
+ HTCSetCreditDistribution(ar->arHtcTarget,
+ ar,
+ NULL, /* use default */
+ NULL, /* use default */
+ &servicepriority,
+ 1);
+
+ /* Start the HTC component */
+ if ((status = HTCStart(ar->arHtcTarget)) != A_OK) {
+ BMIInit();
+ return -EIO;
+ }
+
+ (ar)->arRawIfInit = TRUE;
+
+ return 0;
+}
+
+int ar6000_htc_raw_close(AR_SOFTC_T *ar)
+{
+ A_PRINTF("ar6000_htc_raw_close called \n");
+ HTCStop(ar->arHtcTarget);
+
+ /* reset the device */
+ ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, FALSE);
+ /* Initialize the BMI component */
+ BMIInit();
+
+ return 0;
+}
+
+raw_htc_buffer *
+get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID)
+{
+ int count;
+ raw_htc_buffer *busy;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+
+ /* Check for data */
+ for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
+ busy = &arRaw->raw_htc_read_buffer[StreamID][count];
+ if (busy->length) {
+ break;
+ }
+ }
+ if (busy->length) {
+ arRaw->read_buffer_available[StreamID] = TRUE;
+ } else {
+ arRaw->read_buffer_available[StreamID] = FALSE;
+ }
+
+ return busy;
+}
+
+ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID,
+ char __user *buffer, size_t length)
+{
+ int readPtr;
+ raw_htc_buffer *busy;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+
+ if (arRawStream2EndpointID(ar,StreamID) == 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
+ return -EFAULT;
+ }
+
+ if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
+ return -ERESTARTSYS;
+ }
+
+ busy = get_filled_buffer(ar,StreamID);
+ while (!arRaw->read_buffer_available[StreamID]) {
+ up(&arRaw->raw_htc_read_sem[StreamID]);
+
+ /* Wait for the data */
+ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
+ if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
+ arRaw->read_buffer_available[StreamID]))
+ {
+ return -EINTR;
+ }
+ if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
+ return -ERESTARTSYS;
+ }
+ busy = get_filled_buffer(ar,StreamID);
+ }
+
+ /* Read the data */
+ readPtr = busy->currPtr;
+ if (length > busy->length - HTC_HEADER_LEN) {
+ length = busy->length - HTC_HEADER_LEN;
+ }
+ if (copy_to_user(buffer, &busy->data[readPtr], length)) {
+ up(&arRaw->raw_htc_read_sem[StreamID]);
+ return -EFAULT;
+ }
+
+ busy->currPtr += length;
+
+ if (busy->currPtr == busy->length)
+ {
+ busy->currPtr = 0;
+ busy->length = 0;
+ HTC_PACKET_RESET_RX(&busy->HTCPacket);
+ //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint));
+ HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
+ }
+ arRaw->read_buffer_available[StreamID] = FALSE;
+ up(&arRaw->raw_htc_read_sem[StreamID]);
+
+ return length;
+}
+
+static raw_htc_buffer *
+get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID)
+{
+ int count;
+ raw_htc_buffer *free;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+
+ free = NULL;
+ for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
+ free = &arRaw->raw_htc_write_buffer[StreamID][count];
+ if (free->length == 0) {
+ break;
+ }
+ }
+ if (!free->length) {
+ arRaw->write_buffer_available[StreamID] = TRUE;
+ } else {
+ arRaw->write_buffer_available[StreamID] = FALSE;
+ }
+
+ return free;
+}
+
+ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID,
+ char __user *buffer, size_t length)
+{
+ int writePtr;
+ raw_htc_buffer *free;
+ AR_RAW_HTC_T *arRaw = ar->arRawHtc;
+ if (arRawStream2EndpointID(ar,StreamID) == 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
+ return -EFAULT;
+ }
+
+ if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
+ return -ERESTARTSYS;
+ }
+
+ /* Search for a free buffer */
+ free = get_free_buffer(ar,StreamID);
+
+ /* Check if there is space to write else wait */
+ while (!arRaw->write_buffer_available[StreamID]) {
+ up(&arRaw->raw_htc_write_sem[StreamID]);
+
+ /* Wait for buffer to become free */
+ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
+ if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
+ arRaw->write_buffer_available[StreamID]))
+ {
+ return -EINTR;
+ }
+ if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
+ return -ERESTARTSYS;
+ }
+ free = get_free_buffer(ar,StreamID);
+ }
+
+ /* Send the data */
+ writePtr = HTC_HEADER_LEN;
+ if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
+ length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
+ }
+
+ if (copy_from_user(&free->data[writePtr], buffer, length)) {
+ up(&arRaw->raw_htc_read_sem[StreamID]);
+ return -EFAULT;
+ }
+
+ free->length = length;
+
+ SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
+ free,
+ &free->data[writePtr],
+ length,
+ arRawStream2EndpointID(ar,StreamID),
+ AR6K_DATA_PKT_TAG);
+
+ HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
+
+ arRaw->write_buffer_available[StreamID] = FALSE;
+ up(&arRaw->raw_htc_write_sem[StreamID]);
+
+ return length;
+}
+#endif /* HTC_RAW_INTERFACE */
diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c
new file mode 100644
index 000000000000..6c98a8817aed
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c
@@ -0,0 +1,481 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#include "ar6000_drv.h"
+#ifdef AR6K_ENABLE_HCI_PAL
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <ar6k_pal.h>
+
+extern unsigned int setupbtdev;
+#define bt_check_bit(val, bit) (val & bit)
+#define bt_set_bit(val, bit) (val |= bit)
+#define bt_clear_bit(val, bit) (val &= ~bit)
+
+/* export ATH_AR6K_DEBUG_HCI_PAL=yes in host/localmake.linux.inc
+ * to enable debug information */
+#ifdef HCIPAL_DEBUG
+#define PRIN_LOG(format, args...) printk(KERN_ALERT "%s:%d - %s Msg:" format "\n",__FUNCTION__, __LINE__, __FILE__, ## args)
+#else
+#define PRIN_LOG(format, args...)
+#endif
+
+/**********************************
+ * HCI PAL private info structure
+ *********************************/
+typedef struct ar6k_hci_pal_info_s{
+
+ unsigned long ulFlags;
+#define HCI_NORMAL_MODE (1)
+#define HCI_REGISTERED (1<<1)
+ struct hci_dev *hdev; /* BT Stack HCI dev */
+ AR_SOFTC_T *ar;
+
+}ar6k_hci_pal_info_t;
+
+/*** BT Stack Entrypoints *******/
+/***************************************
+ * bt_open - open a handle to the device
+ ***************************************/
+static int bt_open(struct hci_dev *hdev)
+{
+ PRIN_LOG("HCI PAL: bt_open - enter - x\n");
+ set_bit(HCI_RUNNING, &hdev->flags);
+ set_bit(HCI_UP, &hdev->flags);
+ set_bit(HCI_INIT, &hdev->flags);
+ return 0;
+}
+
+/***************************************
+ * bt_close - close handle to the device
+ ***************************************/
+static int bt_close(struct hci_dev *hdev)
+{
+ PRIN_LOG("HCI PAL: bt_close - enter\n");
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ return 0;
+}
+
+/*****************************
+ * bt_ioctl - ioctl processing
+ *****************************/
+static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ PRIN_LOG("HCI PAL: bt_ioctl - enter\n");
+ return -ENOIOCTLCMD;
+}
+
+/**************************************
+ * bt_flush - flush outstanding packets
+ **************************************/
+static int bt_flush(struct hci_dev *hdev)
+{
+ PRIN_LOG("HCI PAL: bt_flush - enter\n");
+ return 0;
+}
+
+/***************
+ * bt_destruct
+ ***************/
+static void bt_destruct(struct hci_dev *hdev)
+{
+ PRIN_LOG("HCI PAL: bt_destruct - enter\n");
+ /* nothing to do here */
+}
+
+/****************************************************
+ * Invoked from bluetooth stack via hdev->send()
+ * to send the packet out via ar6k to PAL firmware.
+ *
+ * For HCI command packet wmi_send_hci_cmd() is invoked.
+ * wmi_send_hci_cmd adds WMI_CMD_HDR and sends the packet
+ * to PAL firmware.
+ *
+ * For HCI ACL data packet wmi_data_hdr_add is invoked
+ * to add WMI_DATA_HDR to the packet. ar6000_acl_data_tx
+ * is then invoked to send the packet to PAL firmware.
+ ******************************************************/
+static int btpal_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *)skb->dev;
+ HCI_TRANSPORT_PACKET_TYPE type;
+ ar6k_hci_pal_info_t *pHciPalInfo;
+ A_STATUS status = A_OK;
+ struct sk_buff *txSkb = NULL;
+ AR_SOFTC_T *ar;
+
+ if (!hdev) {
+ PRIN_LOG("HCI PAL: btpal_send_frame - no device\n");
+ return -ENODEV;
+ }
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+ PRIN_LOG("HCI PAL: btpal_send_frame - not open\n");
+ return -EBUSY;
+ }
+
+ pHciPalInfo = (ar6k_hci_pal_info_t *)hdev->driver_data;
+ A_ASSERT(pHciPalInfo != NULL);
+ ar = pHciPalInfo->ar;
+
+ PRIN_LOG("+btpal_send_frame type: %d \n",bt_cb(skb)->pkt_type);
+ type = HCI_COMMAND_TYPE;
+
+ switch (bt_cb(skb)->pkt_type) {
+ case HCI_COMMAND_PKT:
+ type = HCI_COMMAND_TYPE;
+ hdev->stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ type = HCI_ACL_TYPE;
+ hdev->stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ /* we don't support SCO over the pal */
+ kfree_skb(skb);
+ return 0;
+ default:
+ A_ASSERT(FALSE);
+ kfree_skb(skb);
+ return 0;
+ }
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
+ A_PRINTF(">>> Send HCI %s packet len: %d\n",
+ (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
+ skb->len);
+ if (type == HCI_COMMAND_TYPE) {
+ PRIN_LOG(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
+ HCI_GET_OP_CODE(skb-data) >> 10, HCI_GET_OP_CODE(skb-data) & 0x3FF);
+ }
+ AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
+ }
+
+ do {
+ if(type == HCI_COMMAND_TYPE)
+ {
+ PRIN_LOG("HCI command");
+
+ if (ar->arWmiReady == FALSE)
+ {
+ PRIN_LOG("WMI not ready ");
+ break;
+ }
+
+ if (wmi_send_hci_cmd(ar->arWmi, skb->data, skb->len) != A_OK)
+ {
+ PRIN_LOG("send hci cmd error");
+ break;
+ }
+ }
+ else if(type == HCI_ACL_TYPE)
+ {
+ void *osbuf;
+
+ PRIN_LOG("ACL data");
+ if (ar->arWmiReady == FALSE)
+ {
+ PRIN_LOG("WMI not ready");
+ break;
+ }
+
+ /* need to add WMI header so allocate a skb with more space */
+ txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ +
+ sizeof(WMI_DATA_HDR) + skb->len,
+ GFP_ATOMIC);
+
+ if (txSkb == NULL) {
+ status = A_NO_MEMORY;
+ PRIN_LOG("No memory");
+ break;
+ }
+
+ bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
+ txSkb->dev = (void *)pHciPalInfo->hdev;
+ skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + sizeof(WMI_DATA_HDR));
+ A_MEMCPY(txSkb->data, skb->data, skb->len);
+ skb_put(txSkb,skb->len);
+ /* Add WMI packet type */
+ osbuf = (void *)txSkb;
+
+ if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) {
+ PRIN_LOG("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n");
+ } else {
+ /* Send data buffer over HTC */
+ PRIN_LOG("acl data tx");
+ ar6000_acl_data_tx(osbuf, ar->arNetDev);
+ }
+ txSkb = NULL;
+ }
+ } while (FALSE);
+
+ if (txSkb != NULL) {
+ PRIN_LOG("Free skb");
+ kfree_skb(txSkb);
+ }
+ kfree_skb(skb);
+ return 0;
+}
+
+
+/***********************************************
+ * Unregister HCI device and free HCI device info
+ ***********************************************/
+static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo)
+{
+ int err;
+
+ if (bt_check_bit(pHciPalInfo->ulFlags, HCI_REGISTERED)) {
+ bt_clear_bit(pHciPalInfo->ulFlags, HCI_REGISTERED);
+ clear_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags);
+ clear_bit(HCI_UP, &pHciPalInfo->hdev->flags);
+ clear_bit(HCI_INIT, &pHciPalInfo->hdev->flags);
+ A_ASSERT(pHciPalInfo->hdev != NULL);
+ /* unregister */
+ PRIN_LOG("Unregister PAL device");
+ if ((err = hci_unregister_dev(pHciPalInfo->hdev)) < 0) {
+ PRIN_LOG("HCI PAL: failed to unregister with bluetooth %d\n",err);
+ }
+ }
+
+ if (pHciPalInfo->hdev != NULL) {
+ kfree(pHciPalInfo->hdev);
+ pHciPalInfo->hdev = NULL;
+ }
+}
+
+/*********************************************************
+ * Allocate HCI device and store in PAL private info structure.
+ *********************************************************/
+static A_STATUS bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo)
+{
+ A_STATUS status = A_OK;
+ struct hci_dev *pHciDev = NULL;
+
+ if (!setupbtdev) {
+ return A_OK;
+ }
+
+ do {
+ /* allocate a BT HCI struct for this device */
+ pHciDev = hci_alloc_dev();
+ if (NULL == pHciDev) {
+ PRIN_LOG("HCI PAL driver - failed to allocate BT HCI struct \n");
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ /* save the device, we'll register this later */
+ pHciPalInfo->hdev = pHciDev;
+ SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_80211);
+ pHciDev->driver_data = pHciPalInfo;
+ pHciDev->open = bt_open;
+ pHciDev->close = bt_close;
+ pHciDev->send = btpal_send_frame;
+ pHciDev->ioctl = bt_ioctl;
+ pHciDev->flush = bt_flush;
+ pHciDev->destruct = bt_destruct;
+ pHciDev->owner = THIS_MODULE;
+ /* driver is running in normal BT mode */
+ PRIN_LOG("Normal mode enabled");
+ bt_set_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE);
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ bt_cleanup_hci_pal(pHciPalInfo);
+ }
+ return status;
+}
+
+/**********************************************
+ * Cleanup HCI device and free HCI PAL private info
+ *********************************************/
+void ar6k_cleanup_hci_pal(void *ar_p)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p;
+ ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)ar->hcipal_info;
+
+ if (pHciPalInfo != NULL) {
+ bt_cleanup_hci_pal(pHciPalInfo);
+ A_FREE(pHciPalInfo);
+ ar->hcipal_info = NULL;
+ }
+}
+
+/****************************
+ * Register HCI device
+ ****************************/
+static A_BOOL ar6k_pal_transport_ready(void *pHciPal)
+{
+ ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal;
+
+ PRIN_LOG("HCI device transport ready");
+ if(pHciPalInfo == NULL)
+ return FALSE;
+
+ if (hci_register_dev(pHciPalInfo->hdev) < 0) {
+ PRIN_LOG("Can't register HCI device");
+ hci_free_dev(pHciPalInfo->hdev);
+ return FALSE;
+ }
+ PRIN_LOG("HCI device registered");
+ pHciPalInfo->ulFlags |= HCI_REGISTERED;
+ return TRUE;
+}
+
+/**************************************************
+ * Called from ar6k driver when command or ACL data
+ * packet is received. Pass the packet to bluetooth
+ * stack via hci_recv_frame.
+ **************************************************/
+A_BOOL ar6k_pal_recv_pkt(void *pHciPal, void *osbuf)
+{
+ struct sk_buff *skb = (struct sk_buff *)osbuf;
+ ar6k_hci_pal_info_t *pHciPalInfo;
+ A_BOOL success = FALSE;
+ A_UINT8 btType = 0;
+ pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal;
+
+ do {
+
+ /* if normal mode is not enabled pass on to the stack
+ * by returning failure */
+ if(!(pHciPalInfo->ulFlags & HCI_NORMAL_MODE))
+ {
+ PRIN_LOG("Normal mode not enabled");
+ break;
+ }
+
+ if (!test_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags)) {
+ PRIN_LOG("HCI PAL: HCI - not running\n");
+ break;
+ }
+
+ if(*((short *)A_NETBUF_DATA(skb)) == WMI_ACL_DATA_EVENTID)
+ btType = HCI_ACLDATA_PKT;
+ else
+ btType = HCI_EVENT_PKT;
+ /* pull 4 bytes which contains WMI packet type */
+ A_NETBUF_PULL(skb, sizeof(int));
+ bt_cb(skb)->pkt_type = btType;
+ skb->dev = (void *)pHciPalInfo->hdev;
+
+ /* pass the received event packet up the stack */
+ if (hci_recv_frame(skb) != 0) {
+ PRIN_LOG("HCI PAL: hci_recv_frame failed \n");
+ break;
+ } else {
+ PRIN_LOG("HCI PAL: Indicated RCV of type:%d, Length:%d \n",HCI_EVENT_PKT, skb->len);
+ }
+ PRIN_LOG("hci recv success");
+ success = TRUE;
+ }while(FALSE);
+ return success;
+}
+
+/**********************************************************
+ * HCI PAL init function called from ar6k when it is loaded..
+ * Allocates PAL private info, stores the same in ar6k private info.
+ * Registers a HCI device.
+ * Registers packet receive callback function with ar6k
+ **********************************************************/
+A_STATUS ar6k_setup_hci_pal(void *ar_p)
+{
+ A_STATUS status = A_OK;
+ ar6k_hci_pal_info_t *pHciPalInfo;
+ ar6k_pal_config_t ar6k_pal_config;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p;
+
+ do {
+
+ pHciPalInfo = (ar6k_hci_pal_info_t *)A_MALLOC(sizeof(ar6k_hci_pal_info_t));
+
+ if (NULL == pHciPalInfo) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_MEMZERO(pHciPalInfo, sizeof(ar6k_hci_pal_info_t));
+ ar->hcipal_info = pHciPalInfo;
+ pHciPalInfo->ar = ar;
+
+ status = bt_setup_hci_pal(pHciPalInfo);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if(bt_check_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE))
+ PRIN_LOG("HCI PAL: running in normal mode... \n");
+ else
+ PRIN_LOG("HCI PAL: running in test mode... \n");
+
+ ar6k_pal_config.fpar6k_pal_recv_pkt = ar6k_pal_recv_pkt;
+ register_pal_cb(&ar6k_pal_config);
+ ar6k_pal_transport_ready(ar->hcipal_info);
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ ar6k_cleanup_hci_pal(ar);
+ }
+ return status;
+}
+#else /* AR6K_ENABLE_HCI_PAL */
+A_STATUS ar6k_setup_hci_pal(void *ar_p)
+{
+ return A_OK;
+}
+void ar6k_cleanup_hci_pal(void *ar_p)
+{
+}
+#endif /* AR6K_ENABLE_HCI_PAL */
+
+#ifdef EXPORT_HCI_PAL_INTERFACE
+/*****************************************************
+ * Register init and callback function with ar6k
+ * when PAL driver is a separate kernel module.
+ ****************************************************/
+A_STATUS ar6k_register_hci_pal(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks);
+static int __init pal_init_module(void)
+{
+ HCI_TRANSPORT_CALLBACKS hciTransCallbacks;
+
+ hciTransCallbacks.setupTransport = ar6k_setup_hci_pal;
+ hciTransCallbacks.cleanupTransport = ar6k_cleanup_hci_pal;
+
+ if(ar6k_register_hci_pal(&hciTransCallbacks) != A_OK)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void __exit pal_cleanup_module(void)
+{
+}
+
+module_init(pal_init_module);
+module_exit(pal_cleanup_module);
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
new file mode 100644
index 000000000000..7a3784d59f2f
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/cfg80211.c
@@ -0,0 +1,1478 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+
+#include "ar6000_drv.h"
+
+
+extern A_WAITQUEUE_HEAD arEvent;
+extern unsigned int wmitimeout;
+extern int reconnect_flag;
+
+
+#define RATETAB_ENT(_rate, _rateid, _flags) { \
+ .bitrate = (_rate), \
+ .flags = (_flags), \
+ .hw_value = (_rateid), \
+}
+
+#define CHAN2G(_channel, _freq, _flags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .hw_value = (_channel), \
+ .center_freq = (_freq), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_channel, _flags) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .hw_value = (_channel), \
+ .center_freq = 5000 + (5 * (_channel)), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+static struct
+ieee80211_rate ar6k_rates[] = {
+ RATETAB_ENT(10, 0x1, 0),
+ RATETAB_ENT(20, 0x2, 0),
+ RATETAB_ENT(55, 0x4, 0),
+ RATETAB_ENT(110, 0x8, 0),
+ RATETAB_ENT(60, 0x10, 0),
+ RATETAB_ENT(90, 0x20, 0),
+ RATETAB_ENT(120, 0x40, 0),
+ RATETAB_ENT(180, 0x80, 0),
+ RATETAB_ENT(240, 0x100, 0),
+ RATETAB_ENT(360, 0x200, 0),
+ RATETAB_ENT(480, 0x400, 0),
+ RATETAB_ENT(540, 0x800, 0),
+};
+
+#define ar6k_a_rates (ar6k_rates + 4)
+#define ar6k_a_rates_size 8
+#define ar6k_g_rates (ar6k_rates + 0)
+#define ar6k_g_rates_size 12
+
+static struct
+ieee80211_channel ar6k_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+ CHAN2G(2, 2417, 0),
+ CHAN2G(3, 2422, 0),
+ CHAN2G(4, 2427, 0),
+ CHAN2G(5, 2432, 0),
+ CHAN2G(6, 2437, 0),
+ CHAN2G(7, 2442, 0),
+ CHAN2G(8, 2447, 0),
+ CHAN2G(9, 2452, 0),
+ CHAN2G(10, 2457, 0),
+ CHAN2G(11, 2462, 0),
+ CHAN2G(12, 2467, 0),
+ CHAN2G(13, 2472, 0),
+ CHAN2G(14, 2484, 0),
+};
+
+static struct
+ieee80211_channel ar6k_5ghz_a_channels[] = {
+ CHAN5G(34, 0), CHAN5G(36, 0),
+ CHAN5G(38, 0), CHAN5G(40, 0),
+ CHAN5G(42, 0), CHAN5G(44, 0),
+ CHAN5G(46, 0), CHAN5G(48, 0),
+ CHAN5G(52, 0), CHAN5G(56, 0),
+ CHAN5G(60, 0), CHAN5G(64, 0),
+ CHAN5G(100, 0), CHAN5G(104, 0),
+ CHAN5G(108, 0), CHAN5G(112, 0),
+ CHAN5G(116, 0), CHAN5G(120, 0),
+ CHAN5G(124, 0), CHAN5G(128, 0),
+ CHAN5G(132, 0), CHAN5G(136, 0),
+ CHAN5G(140, 0), CHAN5G(149, 0),
+ CHAN5G(153, 0), CHAN5G(157, 0),
+ CHAN5G(161, 0), CHAN5G(165, 0),
+ CHAN5G(184, 0), CHAN5G(188, 0),
+ CHAN5G(192, 0), CHAN5G(196, 0),
+ CHAN5G(200, 0), CHAN5G(204, 0),
+ CHAN5G(208, 0), CHAN5G(212, 0),
+ CHAN5G(216, 0),
+};
+
+static struct
+ieee80211_supported_band ar6k_band_2ghz = {
+ .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
+ .channels = ar6k_2ghz_channels,
+ .n_bitrates = ar6k_g_rates_size,
+ .bitrates = ar6k_g_rates,
+};
+
+static struct
+ieee80211_supported_band ar6k_band_5ghz = {
+ .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
+ .channels = ar6k_5ghz_a_channels,
+ .n_bitrates = ar6k_a_rates_size,
+ .bitrates = ar6k_a_rates,
+};
+
+static int
+ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
+
+ if (!wpa_version) {
+ ar->arAuthMode = NONE_AUTH;
+ } else if (wpa_version & NL80211_WPA_VERSION_1) {
+ ar->arAuthMode = WPA_AUTH;
+ } else if (wpa_version & NL80211_WPA_VERSION_2) {
+ ar->arAuthMode = WPA2_AUTH;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: %u not spported\n", __func__, wpa_version));
+ return -ENOTSUPP;
+ }
+
+ return A_OK;
+}
+
+static int
+ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
+
+ switch (auth_type) {
+ case NL80211_AUTHTYPE_OPEN_SYSTEM:
+ ar->arDot11AuthMode = OPEN_AUTH;
+ break;
+ case NL80211_AUTHTYPE_SHARED_KEY:
+ ar->arDot11AuthMode = SHARED_AUTH;
+ break;
+ case NL80211_AUTHTYPE_NETWORK_EAP:
+ ar->arDot11AuthMode = LEAP_AUTH;
+ break;
+ default:
+ ar->arDot11AuthMode = OPEN_AUTH;
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: 0x%x not spported\n", __func__, auth_type));
+ return -ENOTSUPP;
+ }
+
+ return A_OK;
+}
+
+static int
+ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, A_BOOL ucast)
+{
+ A_UINT8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
+ &ar->arGroupCrypto;
+ A_UINT8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
+ &ar->arGroupCryptoLen;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
+
+ switch (cipher) {
+ case 0:
+ case IW_AUTH_CIPHER_NONE:
+ *ar_cipher = NONE_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ *ar_cipher = WEP_CRYPT;
+ *ar_cipher_len = 5;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ *ar_cipher = WEP_CRYPT;
+ *ar_cipher_len = 13;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ *ar_cipher = TKIP_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ *ar_cipher = AES_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: cipher 0x%x not supported\n", __func__, cipher));
+ return -ENOTSUPP;
+ }
+
+ return A_OK;
+}
+
+static void
+ar6k_set_key_mgmt(AR_SOFTC_T *ar, A_UINT32 key_mgmt)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
+
+ if (WLAN_AKM_SUITE_PSK == key_mgmt) {
+ if (WPA_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA_PSK_AUTH;
+ } else if (WPA2_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA2_PSK_AUTH;
+ }
+ } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
+ ar->arAuthMode = NONE_AUTH;
+ }
+}
+
+static int
+ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ AR_SOFTC_T *ar = ar6k_priv(dev);
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->bIsDestroyProgress) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
+ return -EBUSY;
+ }
+
+ if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
+ return -EINVAL;
+ }
+
+ if(ar->arSkipScan == TRUE &&
+ ((sme->channel && sme->channel->center_freq == 0) ||
+ (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
+ !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
+ return -EINVAL;
+ }
+
+ if(down_interruptible(&ar->arSem)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
+ return -ERESTARTSYS;
+ }
+
+ if(ar->bIsDestroyProgress) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
+ /*
+ * sleep until the command queue drains
+ */
+ wait_event_interruptible_timeout(arEvent,
+ ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
+ if (signal_pending(current)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
+ up(&ar->arSem);
+ return -EINTR;
+ }
+ }
+
+ if(ar->arConnected == TRUE &&
+ ar->arSsidLen == sme->ssid_len &&
+ !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
+ reconnect_flag = TRUE;
+ status = wmi_reconnect_cmd(ar->arWmi,
+ ar->arReqBssid,
+ ar->arChannelHint);
+
+ up(&ar->arSem);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
+ return -EIO;
+ }
+ return 0;
+ } else if(ar->arSsidLen == sme->ssid_len &&
+ !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
+ wmi_disconnect_cmd(ar->arWmi);
+ }
+
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = sme->ssid_len;
+ A_MEMCPY(ar->arSsid, sme->ssid, sme->ssid_len);
+
+ if(sme->channel){
+ ar->arChannelHint = sme->channel->center_freq;
+ }
+
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ if(sme->bssid){
+ if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
+ A_MEMCPY(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
+ }
+ }
+
+ ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
+ ar6k_set_auth_type(ar, sme->auth_type);
+
+ if(sme->crypto.n_ciphers_pairwise) {
+ ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
+ } else {
+ ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
+ }
+ ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
+
+ if(sme->crypto.n_akm_suites) {
+ ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
+ }
+
+ if((sme->key_len) &&
+ (NONE_AUTH == ar->arAuthMode) &&
+ (WEP_CRYPT == ar->arPairwiseCrypto)) {
+ struct ar_key *key = NULL;
+
+ if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
+ up(&ar->arSem);
+ return -ENOENT;
+ }
+
+ key = &ar->keys[sme->key_idx];
+ key->key_len = sme->key_len;
+ A_MEMCPY(key->key, sme->key, key->key_len);
+ key->cipher = ar->arPairwiseCrypto;
+ ar->arDefTxKeyIndex = sme->key_idx;
+
+ wmi_addKey_cmd(ar->arWmi, sme->key_idx,
+ ar->arPairwiseCrypto,
+ GROUP_USAGE | TX_USAGE,
+ key->key_len,
+ NULL,
+ key->key, KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+
+ if (!ar->arUserBssFilter) {
+ if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
+ up(&ar->arSem);
+ return -EIO;
+ }
+ }
+
+ ar->arNetworkType = ar->arNextMode;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
+ " PW crypto %d PW crypto Len %d GRP crypto %d"\
+ " GRP crypto Len %d channel hint %u\n",
+ __func__, ar->arAuthMode, ar->arDot11AuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
+
+ reconnect_flag = 0;
+ status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
+ ar->arDot11AuthMode, ar->arAuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto,ar->arGroupCryptoLen,
+ ar->arSsidLen, ar->arSsid,
+ ar->arReqBssid, ar->arChannelHint,
+ ar->arConnectCtrlFlags);
+
+ up(&ar->arSem);
+
+ if (A_EINVAL == status) {
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
+ return -ENOENT;
+ } else if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
+ return -EIO;
+ }
+
+ if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
+ ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
+ {
+ A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
+ }
+
+ ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
+ ar->arConnectPending = TRUE;
+
+ return 0;
+}
+
+void
+ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel,
+ A_UINT8 *bssid, A_UINT16 listenInterval,
+ A_UINT16 beaconInterval,NETWORK_TYPE networkType,
+ A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
+ A_UINT8 assocRespLen, A_UINT8 *assocInfo)
+{
+ A_UINT16 size = 0;
+ A_UINT16 capability = 0;
+ struct cfg80211_bss *bss = NULL;
+ struct ieee80211_mgmt *mgmt = NULL;
+ struct ieee80211_channel *ibss_channel = NULL;
+ s32 signal = 50 * 100;
+ A_UINT8 ie_buf_len = 0;
+ unsigned char ie_buf[256];
+ unsigned char *ptr_ie_buf = ie_buf;
+ unsigned char *ieeemgmtbuf = NULL;
+ A_UINT8 source_mac[ATH_MAC_LEN];
+
+ A_UINT8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/
+ sizeof(A_UINT16); /* listen interval */
+ A_UINT8 assocRespIeOffset = sizeof(A_UINT16) + /* capinfo*/
+ sizeof(A_UINT16) + /* status Code */
+ sizeof(A_UINT16); /* associd */
+ A_UINT8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
+ A_UINT8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ assocReqLen -= assocReqIeOffset;
+ assocRespLen -= assocRespIeOffset;
+
+ if((ADHOC_NETWORK & networkType)) {
+ if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: ath6k not in ibss mode\n", __func__));
+ return;
+ }
+ }
+
+ if((INFRA_NETWORK & networkType)) {
+ if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: ath6k not in station mode\n", __func__));
+ return;
+ }
+ }
+
+ /* Before informing the join/connect event, make sure that
+ * bss entry is present in scan list, if it not present
+ * construct and insert into scan list, otherwise that
+ * event will be dropped on the way by cfg80211, due to
+ * this keys will not be plumbed in case of WEP and
+ * application will not be aware of join/connect status. */
+ bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
+ ar->wdev->ssid, ar->wdev->ssid_len,
+ ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
+ ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
+
+ if(!bss) {
+ if (ADHOC_NETWORK & networkType) {
+ /* construct 802.11 mgmt beacon */
+ if(ptr_ie_buf) {
+ *ptr_ie_buf++ = WLAN_EID_SSID;
+ *ptr_ie_buf++ = ar->arSsidLen;
+ A_MEMCPY(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
+ ptr_ie_buf +=ar->arSsidLen;
+
+ *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
+ *ptr_ie_buf++ = 2; /* length */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+
+ /* TODO: update ibss params and include supported rates,
+ * DS param set, extened support rates, wmm. */
+
+ ie_buf_len = ptr_ie_buf - ie_buf;
+ }
+
+ capability |= IEEE80211_CAPINFO_IBSS;
+ if(WEP_CRYPT == ar->arPairwiseCrypto) {
+ capability |= IEEE80211_CAPINFO_PRIVACY;
+ }
+ A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
+ ptr_ie_buf = ie_buf;
+ } else {
+ capability = *(A_UINT16 *)(&assocInfo[beaconIeLen]);
+ A_MEMCPY(source_mac, bssid, ATH_MAC_LEN);
+ ptr_ie_buf = assocReqIe;
+ ie_buf_len = assocReqLen;
+ }
+
+ size = offsetof(struct ieee80211_mgmt, u)
+ + sizeof(mgmt->u.beacon)
+ + ie_buf_len;
+
+ ieeemgmtbuf = A_MALLOC_NOWAIT(size);
+ if(!ieeemgmtbuf) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: ieeeMgmtbuf alloc error\n", __func__));
+ return;
+ }
+
+ A_MEMZERO(ieeemgmtbuf, size);
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+ A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
+ A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN);
+ A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN);
+ mgmt->u.beacon.beacon_int = beaconInterval;
+ mgmt->u.beacon.capab_info = capability;
+ A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
+
+ ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: inform bss with bssid %02x:%02x:%02x:%02x:%02x:%02x "\
+ "channel %d beaconInterval %d capability 0x%x\n",
+ __func__,
+ mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2],
+ mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5],
+ ibss_channel->hw_value, beaconInterval, capability));
+
+ bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
+ ibss_channel, mgmt,
+ le16_to_cpu(size),
+ signal, GFP_KERNEL);
+ A_FREE(ieeemgmtbuf);
+ cfg80211_put_bss(bss);
+ }
+
+ if((ADHOC_NETWORK & networkType)) {
+ cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
+ return;
+ }
+
+ if (FALSE == ar->arConnected) {
+ /* inform connect result to cfg80211 */
+ cfg80211_connect_result(ar->arNetDev, bssid,
+ assocReqIe, assocReqLen,
+ assocRespIe, assocRespLen,
+ WLAN_STATUS_SUCCESS, GFP_KERNEL);
+ } else {
+ /* inform roam event to cfg80211 */
+ cfg80211_roamed(ar->arNetDev, bssid,
+ assocReqIe, assocReqLen,
+ assocRespIe, assocRespLen,
+ GFP_KERNEL);
+ }
+}
+
+static int
+ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+ A_UINT16 reason_code)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->bIsDestroyProgress) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
+ return -EBUSY;
+ }
+
+ if(down_interruptible(&ar->arSem)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
+ return -ERESTARTSYS;
+ }
+
+ reconnect_flag = 0;
+ wmi_disconnect_cmd(ar->arWmi);
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+
+ if (ar->arSkipScan == FALSE) {
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ }
+
+ up(&ar->arSem);
+
+ return 0;
+}
+
+void
+ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason,
+ A_UINT8 *bssid, A_UINT8 assocRespLen,
+ A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
+
+ if((ADHOC_NETWORK & ar->arNetworkType)) {
+ if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: ath6k not in ibss mode\n", __func__));
+ return;
+ }
+ A_MEMZERO(bssid, ETH_ALEN);
+ cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
+ return;
+ }
+
+ if((INFRA_NETWORK & ar->arNetworkType)) {
+ if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: ath6k not in station mode\n", __func__));
+ return;
+ }
+ }
+
+ if(FALSE == ar->arConnected) {
+ if(NO_NETWORK_AVAIL == reason) {
+ /* connect cmd failed */
+ cfg80211_connect_result(ar->arNetDev, bssid,
+ NULL, 0,
+ NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ }
+ } else {
+ /* connection loss due to disconnect cmd or low rssi */
+ cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
+ }
+}
+
+void
+ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
+{
+ struct wiphy *wiphy = (struct wiphy *)arg;
+ A_UINT16 size;
+ unsigned char *ieeemgmtbuf = NULL;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ struct ieee80211_common_ie *cie;
+ s32 signal;
+ int freq;
+
+ cie = &ni->ni_cie;
+
+#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
+ if(CHAN_IS_11A(cie->ie_chan)) {
+ /* 11a */
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ } else if((cie->ie_erp) || (cie->ie_xrates)) {
+ /* 11g */
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ } else {
+ /* 11b */
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ }
+
+ size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
+ ieeemgmtbuf = A_MALLOC_NOWAIT(size);
+ if(!ieeemgmtbuf)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
+ return;
+ }
+
+ /* Note:
+ TODO: Update target to include 802.11 mac header while sending bss info.
+ Target removes 802.11 mac header while sending the bss info to host,
+ cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
+ */
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
+ A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
+ A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
+ A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
+ ni->ni_buf, ni->ni_framelen);
+
+ freq = cie->ie_chan;
+ channel = ieee80211_get_channel(wiphy, freq);
+ signal = ni->ni_snr * 100;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: bssid %02x:%02x:%02x:%02x:%02x:%02x channel %d freq %d size %d\n",
+ __func__,
+ mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2],
+ mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5],
+ channel->hw_value, freq, size));
+ cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ le16_to_cpu(size),
+ signal, GFP_KERNEL);
+
+ A_FREE (ieeemgmtbuf);
+}
+
+static int
+ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+ int ret = 0;
+ A_BOOL forceFgScan = FALSE;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if (!ar->arUserBssFilter) {
+ if (wmi_bssfilter_cmd(ar->arWmi,
+ (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
+ 0) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
+ return -EIO;
+ }
+ }
+
+ if(request->n_ssids &&
+ request->ssids[0].ssid_len) {
+ A_UINT8 i;
+
+ if(request->n_ssids > MAX_PROBED_SSID_INDEX) {
+ request->n_ssids = MAX_PROBED_SSID_INDEX;
+ }
+
+ for (i = 0; i < request->n_ssids; i++) {
+ wmi_probedSsid_cmd(ar->arWmi, i, SPECIFIC_SSID_FLAG,
+ request->ssids[i].ssid_len,
+ request->ssids[i].ssid);
+ }
+ }
+
+ if(ar->arConnected) {
+ forceFgScan = TRUE;
+ }
+
+ if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \
+ 0, 0, 0, NULL) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
+ ret = -EIO;
+ }
+
+ ar->scan_request = request;
+
+ return ret;
+}
+
+void
+ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
+
+ if(ar->scan_request)
+ {
+ /* Translate data to cfg80211 mgmt format */
+ wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
+
+ cfg80211_scan_done(ar->scan_request,
+ (status & A_ECANCELED) ? true : false);
+
+ if(ar->scan_request->n_ssids &&
+ ar->scan_request->ssids[0].ssid_len) {
+ A_UINT8 i;
+
+ for (i = 0; i < ar->scan_request->n_ssids; i++) {
+ wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG,
+ 0, NULL);
+ }
+ }
+ ar->scan_request = NULL;
+ }
+}
+
+static int
+ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
+ A_UINT8 key_index, const A_UINT8 *mac_addr,
+ struct key_params *params)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+ struct ar_key *key = NULL;
+ A_UINT8 key_usage;
+ A_UINT8 key_type;
+ A_STATUS status = 0;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: key index %d out of bounds\n", __func__, key_index));
+ return -ENOENT;
+ }
+
+ key = &ar->keys[key_index];
+ A_MEMZERO(key, sizeof(struct ar_key));
+
+ if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
+ key_usage = GROUP_USAGE;
+ } else {
+ key_usage = PAIRWISE_USAGE;
+ }
+
+ if(params) {
+ if(params->key_len > WLAN_MAX_KEY_LEN ||
+ params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
+ return -EINVAL;
+
+ key->key_len = params->key_len;
+ A_MEMCPY(key->key, params->key, key->key_len);
+ key->seq_len = params->seq_len;
+ A_MEMCPY(key->seq, params->seq, key->seq_len);
+ key->cipher = params->cipher;
+ }
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ key_type = WEP_CRYPT;
+ break;
+
+ case WLAN_CIPHER_SUITE_TKIP:
+ key_type = TKIP_CRYPT;
+ break;
+
+ case WLAN_CIPHER_SUITE_CCMP:
+ key_type = AES_CRYPT;
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
+ (GROUP_USAGE & key_usage))
+ {
+ A_UNTIMEOUT(&ar->disconnect_timer);
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: index %d, key_len %d, key_type 0x%x,"\
+ " key_usage 0x%x, seq_len %d\n",
+ __func__, key_index, key->key_len, key_type,
+ key_usage, key->seq_len));
+
+ ar->arDefTxKeyIndex = key_index;
+ status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
+ key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
+ (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG);
+
+
+ if(status != A_OK) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
+ A_UINT8 key_index, const A_UINT8 *mac_addr)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: key index %d out of bounds\n", __func__, key_index));
+ return -ENOENT;
+ }
+
+ if(!ar->keys[key_index].key_len) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
+ return 0;
+ }
+
+ ar->keys[key_index].key_len = 0;
+
+ return wmi_deleteKey_cmd(ar->arWmi, key_index);
+}
+
+
+static int
+ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
+ A_UINT8 key_index, const A_UINT8 *mac_addr, void *cookie,
+ void (*callback)(void *cookie, struct key_params*))
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+ struct ar_key *key = NULL;
+ struct key_params params;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: key index %d out of bounds\n", __func__, key_index));
+ return -ENOENT;
+ }
+
+ key = &ar->keys[key_index];
+ A_MEMZERO(&params, sizeof(params));
+ params.cipher = key->cipher;
+ params.key_len = key->key_len;
+ params.seq_len = key->seq_len;
+ params.seq = key->seq;
+ params.key = key->key;
+
+ callback(cookie, &params);
+
+ return key->key_len ? 0 : -ENOENT;
+}
+
+
+static int
+ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
+ A_UINT8 key_index)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+ struct ar_key *key = NULL;
+ A_STATUS status = A_OK;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: key index %d out of bounds\n",
+ __func__, key_index));
+ return -ENOENT;
+ }
+
+ if(!ar->keys[key_index].key_len) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
+ __func__, key_index));
+ return -EINVAL;
+ }
+
+ ar->arDefTxKeyIndex = key_index;
+ key = &ar->keys[ar->arDefTxKeyIndex];
+ status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
+ ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
+ key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
+ NULL, SYNC_BOTH_WMIFLAG);
+ if (status != A_OK) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
+ A_UINT8 key_index)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
+ return -ENOTSUPP;
+}
+
+void
+ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+ ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
+
+ cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
+ (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
+ keyid, NULL, GFP_KERNEL);
+}
+
+static int
+ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+ if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != A_OK){
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
+ const A_UINT8 *peer,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
+ return -EIO;
+}
+
+/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
+static int
+ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
+ A_UINT8 ar_dbm;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ ar->arTxPwrSet = FALSE;
+ switch(type) {
+ case NL80211_TX_POWER_AUTOMATIC:
+ return 0;
+ case NL80211_TX_POWER_LIMITED:
+ ar->arTxPwr = ar_dbm = dbm;
+ ar->arTxPwrSet = TRUE;
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
+ return -EOPNOTSUPP;
+ }
+
+ wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if((ar->arConnected == TRUE)) {
+ ar->arTxPwr = 0;
+
+ if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
+
+ if(signal_pending(current)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
+ return -EINTR;
+ }
+ }
+
+ *dbm = ar->arTxPwr;
+ return 0;
+}
+
+static int
+ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ struct net_device *dev,
+ bool pmgmt, int timeout)
+{
+ AR_SOFTC_T *ar = ar6k_priv(dev);
+ WMI_POWER_MODE_CMD pwrMode;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(pmgmt) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
+ pwrMode.powerMode = MAX_PERF_POWER;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
+ pwrMode.powerMode = REC_POWER;
+ }
+
+ if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
+
+ /* Multiple virtual interface is not supported.
+ * The default interface supports STA and IBSS type
+ */
+ return -EOPNOTSUPP;
+}
+
+static int
+ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
+
+ /* Multiple virtual interface is not supported.
+ * The default interface supports STA and IBSS type
+ */
+ return -EOPNOTSUPP;
+}
+
+static int
+ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ AR_SOFTC_T *ar = ar6k_priv(ndev);
+ struct wireless_dev *wdev = ar->wdev;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ ar->arNextMode = INFRA_NETWORK;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ar->arNextMode = ADHOC_NETWORK;
+ break;
+ default:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
+ return -EOPNOTSUPP;
+ }
+
+ wdev->iftype = type;
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *ibss_param)
+{
+ AR_SOFTC_T *ar = ar6k_priv(dev);
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
+ return -EINVAL;
+ }
+
+ ar->arSsidLen = ibss_param->ssid_len;
+ A_MEMCPY(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
+
+ if(ibss_param->channel) {
+ ar->arChannelHint = ibss_param->channel->center_freq;
+ }
+
+ if(ibss_param->channel_fixed) {
+ /* TODO: channel_fixed: The channel should be fixed, do not search for
+ * IBSSs to join on other channels. Target firmware does not support this
+ * feature, needs to be updated.*/
+ }
+
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ if(ibss_param->bssid) {
+ if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
+ A_MEMCPY(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
+ }
+ }
+
+ ar6k_set_wpa_version(ar, 0);
+ ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
+
+ if(ibss_param->privacy) {
+ ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
+ ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
+ } else {
+ ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
+ ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
+ }
+
+ ar->arNetworkType = ar->arNextMode;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
+ " PW crypto %d PW crypto Len %d GRP crypto %d"\
+ " GRP crypto Len %d channel hint %u\n",
+ __func__, ar->arAuthMode, ar->arDot11AuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
+
+ status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
+ ar->arDot11AuthMode, ar->arAuthMode,
+ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+ ar->arGroupCrypto,ar->arGroupCryptoLen,
+ ar->arSsidLen, ar->arSsid,
+ ar->arReqBssid, ar->arChannelHint,
+ ar->arConnectCtrlFlags);
+
+ return 0;
+}
+
+static int
+ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->arWmiReady == FALSE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
+ return -EIO;
+ }
+
+ if(ar->arWlanState == WLAN_DISABLED) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
+ return -EIO;
+ }
+
+ wmi_disconnect_cmd(ar->arWmi);
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+
+ return 0;
+}
+
+
+static const
+A_UINT32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+};
+
+static struct
+cfg80211_ops ar6k_cfg80211_ops = {
+ .change_virtual_intf = ar6k_cfg80211_change_iface,
+ .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
+ .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
+ .scan = ar6k_cfg80211_scan,
+ .connect = ar6k_cfg80211_connect,
+ .disconnect = ar6k_cfg80211_disconnect,
+ .add_key = ar6k_cfg80211_add_key,
+ .get_key = ar6k_cfg80211_get_key,
+ .del_key = ar6k_cfg80211_del_key,
+ .set_default_key = ar6k_cfg80211_set_default_key,
+ .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
+ .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
+ .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
+ .set_tx_power = ar6k_cfg80211_set_txpower,
+ .get_tx_power = ar6k_cfg80211_get_txpower,
+ .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
+ .join_ibss = ar6k_cfg80211_join_ibss,
+ .leave_ibss = ar6k_cfg80211_leave_ibss,
+};
+
+struct wireless_dev *
+ar6k_cfg80211_init(struct device *dev)
+{
+ int ret = 0;
+ struct wireless_dev *wdev;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+ if(!wdev) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: Couldn't allocate wireless device\n", __func__));
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* create a new wiphy for use with cfg80211 */
+ wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(AR_SOFTC_T));
+ if(!wdev->wiphy) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: Couldn't allocate wiphy device\n", __func__));
+ kfree(wdev);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* set device pointer for wiphy */
+ set_wiphy_dev(wdev->wiphy, dev);
+
+ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ /* max num of ssids that can be probed during scanning */
+ wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
+ wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ wdev->wiphy->cipher_suites = cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+ ret = wiphy_register(wdev->wiphy);
+ if(ret < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: Couldn't register wiphy device\n", __func__));
+ wiphy_free(wdev->wiphy);
+ return ERR_PTR(ret);
+ }
+
+ return wdev;
+}
+
+void
+ar6k_cfg80211_deinit(AR_SOFTC_T *ar)
+{
+ struct wireless_dev *wdev = ar->wdev;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+
+ if(ar->scan_request) {
+ cfg80211_scan_done(ar->scan_request, true);
+ ar->scan_request = NULL;
+ }
+
+ if(!wdev)
+ return;
+
+ wiphy_unregister(wdev->wiphy);
+ wiphy_free(wdev->wiphy);
+ kfree(wdev);
+}
+
+
+
+
+
+
+
diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c
new file mode 100644
index 000000000000..be77fb87ebf5
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/eeprom.c
@@ -0,0 +1,574 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+
+#include "ar6000_drv.h"
+#include "htc.h"
+#include <linux/fs.h>
+
+#include "AR6002/hw2.0/hw/gpio_reg.h"
+#include "AR6002/hw2.0/hw/si_reg.h"
+
+//
+// defines
+//
+
+#define MAX_FILENAME 1023
+#define EEPROM_WAIT_LIMIT 16
+
+#define HOST_INTEREST_ITEM_ADDRESS(item) \
+ (AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
+
+#define EEPROM_SZ 768
+
+/* soft mac */
+#define ATH_MAC_LEN 6
+#define ATH_SOFT_MAC_TMP_BUF_LEN 64
+unsigned char mac_addr[ATH_MAC_LEN];
+unsigned char soft_mac_tmp_buf[ATH_SOFT_MAC_TMP_BUF_LEN];
+char *p_mac = NULL;
+/* soft mac */
+
+//
+// static variables
+//
+
+static A_UCHAR eeprom_data[EEPROM_SZ];
+static A_UINT32 sys_sleep_reg;
+static HIF_DEVICE *p_bmi_device;
+
+//
+// Functions
+//
+
+/* soft mac */
+static int
+wmic_ether_aton(const char *orig, A_UINT8 *eth)
+{
+ const char *bufp;
+ int i;
+
+ i = 0;
+ for(bufp = orig; *bufp != '\0'; ++bufp) {
+ unsigned int val;
+ int h, l;
+
+ h = hex_to_bin(*bufp++);
+
+ if (h < 0) {
+ printk("%s: MAC value is invalid\n", __FUNCTION__);
+ break;
+ }
+
+ l = hex_to_bin(*bufp++);
+ if (l < 0) {
+ printk("%s: MAC value is invalid\n", __FUNCTION__);
+ break;
+ }
+
+ val = (h << 4) | l;
+
+ eth[i] = (unsigned char) (val & 0377);
+ if(++i == ATH_MAC_LEN) {
+ /* That's it. Any trailing junk? */
+ if (*bufp != '\0') {
+ return 0;
+ }
+ return 1;
+ }
+ if (*bufp != ':')
+ break;
+ }
+ return 0;
+}
+
+static void
+update_mac(unsigned char* eeprom, int size, unsigned char* macaddr)
+{
+ int i;
+ A_UINT16* ptr = (A_UINT16*)(eeprom+4);
+ A_UINT16 checksum = 0;
+
+ memcpy(eeprom+10,macaddr,6);
+
+ *ptr = 0;
+ ptr = (A_UINT16*)eeprom;
+
+ for (i=0; i<size; i+=2) {
+ checksum ^= *ptr++;
+ }
+ checksum = ~checksum;
+
+ ptr = (A_UINT16*)(eeprom+4);
+ *ptr = checksum;
+ return;
+}
+/* soft mac */
+
+/* Read a Target register and return its value. */
+inline void
+BMI_read_reg(A_UINT32 address, A_UINT32 *pvalue)
+{
+ BMIReadSOCRegister(p_bmi_device, address, pvalue);
+}
+
+/* Write a value to a Target register. */
+inline void
+BMI_write_reg(A_UINT32 address, A_UINT32 value)
+{
+ BMIWriteSOCRegister(p_bmi_device, address, value);
+}
+
+/* Read Target memory word and return its value. */
+inline void
+BMI_read_mem(A_UINT32 address, A_UINT32 *pvalue)
+{
+ BMIReadMemory(p_bmi_device, address, (A_UCHAR*)(pvalue), 4);
+}
+
+/* Write a word to a Target memory. */
+inline void
+BMI_write_mem(A_UINT32 address, A_UINT8 *p_data, A_UINT32 sz)
+{
+ BMIWriteMemory(p_bmi_device, address, (A_UCHAR*)(p_data), sz);
+}
+
+/*
+ * Enable and configure the Target's Serial Interface
+ * so we can access the EEPROM.
+ */
+static void
+enable_SI(HIF_DEVICE *p_device)
+{
+ A_UINT32 regval;
+
+ printk("%s\n", __FUNCTION__);
+
+ p_bmi_device = p_device;
+
+ BMI_read_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, &sys_sleep_reg);
+ BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, SYSTEM_SLEEP_DISABLE_SET(1)); //disable system sleep temporarily
+
+ BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, &regval);
+ regval &= ~CLOCK_CONTROL_SI0_CLK_MASK;
+ BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);
+
+ BMI_read_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, &regval);
+ regval &= ~RESET_CONTROL_SI0_RST_MASK;
+ BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, regval);
+
+
+ BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, &regval);
+ regval &= ~GPIO_PIN0_CONFIG_MASK;
+ BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, regval);
+
+ BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, &regval);
+ regval &= ~GPIO_PIN1_CONFIG_MASK;
+ BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, regval);
+
+ /* SI_CONFIG = 0x500a6; */
+ regval = SI_CONFIG_BIDIR_OD_DATA_SET(1) |
+ SI_CONFIG_I2C_SET(1) |
+ SI_CONFIG_POS_SAMPLE_SET(1) |
+ SI_CONFIG_INACTIVE_CLK_SET(1) |
+ SI_CONFIG_INACTIVE_DATA_SET(1) |
+ SI_CONFIG_DIVIDER_SET(6);
+ BMI_write_reg(SI_BASE_ADDRESS+SI_CONFIG_OFFSET, regval);
+
+}
+
+static void
+disable_SI(void)
+{
+ A_UINT32 regval;
+
+ printk("%s\n", __FUNCTION__);
+
+ BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, RESET_CONTROL_SI0_RST_MASK);
+ BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, &regval);
+ regval |= CLOCK_CONTROL_SI0_CLK_MASK;
+ BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);//Gate SI0 clock
+ BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, sys_sleep_reg); //restore system sleep setting
+}
+
+/*
+ * Tell the Target to start an 8-byte read from EEPROM,
+ * putting the results in Target RX_DATA registers.
+ */
+static void
+request_8byte_read(int offset)
+{
+ A_UINT32 regval;
+
+// printk("%s: request_8byte_read from offset 0x%x\n", __FUNCTION__, offset);
+
+
+ /* SI_TX_DATA0 = read from offset */
+ regval =(0xa1<<16)|
+ ((offset & 0xff)<<8) |
+ (0xa0 | ((offset & 0xff00)>>7));
+
+ BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
+
+ regval = SI_CS_START_SET(1) |
+ SI_CS_RX_CNT_SET(8) |
+ SI_CS_TX_CNT_SET(3);
+ BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
+}
+
+/*
+ * Tell the Target to start a 4-byte write to EEPROM,
+ * writing values from Target TX_DATA registers.
+ */
+static void
+request_4byte_write(int offset, A_UINT32 data)
+{
+ A_UINT32 regval;
+
+ printk("%s: request_4byte_write (0x%x) to offset 0x%x\n", __FUNCTION__, data, offset);
+
+ /* SI_TX_DATA0 = write data to offset */
+ regval = ((data & 0xffff) <<16) |
+ ((offset & 0xff)<<8) |
+ (0xa0 | ((offset & 0xff00)>>7));
+ BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
+
+ regval = data >> 16;
+ BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA1_OFFSET, regval);
+
+ regval = SI_CS_START_SET(1) |
+ SI_CS_RX_CNT_SET(0) |
+ SI_CS_TX_CNT_SET(6);
+ BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
+}
+
+/*
+ * Check whether or not an EEPROM request that was started
+ * earlier has completed yet.
+ */
+static A_BOOL
+request_in_progress(void)
+{
+ A_UINT32 regval;
+
+ /* Wait for DONE_INT in SI_CS */
+ BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, &regval);
+
+// printk("%s: request in progress SI_CS=0x%x\n", __FUNCTION__, regval);
+ if (regval & SI_CS_DONE_ERR_MASK) {
+ printk("%s: EEPROM signaled ERROR (0x%x)\n", __FUNCTION__, regval);
+ }
+
+ return (!(regval & SI_CS_DONE_INT_MASK));
+}
+
+/*
+ * try to detect the type of EEPROM,16bit address or 8bit address
+ */
+
+static void eeprom_type_detect(void)
+{
+ A_UINT32 regval;
+ A_UINT8 i = 0;
+
+ request_8byte_read(0x100);
+ /* Wait for DONE_INT in SI_CS */
+ do{
+ BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, &regval);
+ if (regval & SI_CS_DONE_ERR_MASK) {
+ printk("%s: ERROR : address type was wrongly set\n", __FUNCTION__);
+ break;
+ }
+ if (i++ == EEPROM_WAIT_LIMIT) {
+ printk("%s: EEPROM not responding\n", __FUNCTION__);
+ }
+ } while(!(regval & SI_CS_DONE_INT_MASK));
+}
+
+/*
+ * Extract the results of a completed EEPROM Read request
+ * and return them to the caller.
+ */
+inline void
+read_8byte_results(A_UINT32 *data)
+{
+ /* Read SI_RX_DATA0 and SI_RX_DATA1 */
+ BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA0_OFFSET, &data[0]);
+ BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA1_OFFSET, &data[1]);
+}
+
+
+/*
+ * Wait for a previously started command to complete.
+ * Timeout if the command is takes "too long".
+ */
+static void
+wait_for_eeprom_completion(void)
+{
+ int i=0;
+
+ while (request_in_progress()) {
+ if (i++ == EEPROM_WAIT_LIMIT) {
+ printk("%s: EEPROM not responding\n", __FUNCTION__);
+ }
+ }
+}
+
+/*
+ * High-level function which starts an 8-byte read,
+ * waits for it to complete, and returns the result.
+ */
+static void
+fetch_8bytes(int offset, A_UINT32 *data)
+{
+ request_8byte_read(offset);
+ wait_for_eeprom_completion();
+ read_8byte_results(data);
+
+ /* Clear any pending intr */
+ BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, SI_CS_DONE_INT_MASK);
+}
+
+/*
+ * High-level function which starts a 4-byte write,
+ * and waits for it to complete.
+ */
+inline void
+commit_4bytes(int offset, A_UINT32 data)
+{
+ request_4byte_write(offset, data);
+ wait_for_eeprom_completion();
+}
+/* ATHENV */
+#ifdef ANDROID_ENV
+void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac)
+{
+ A_UINT32 first_word;
+ A_UINT32 board_data_addr;
+ int i;
+
+ printk("%s: Enter\n", __FUNCTION__);
+
+ enable_SI(device);
+ eeprom_type_detect();
+
+ if (fake_file) {
+ /*
+ * Transfer from file to Target RAM.
+ * Fetch source data from file.
+ */
+ mm_segment_t oldfs;
+ struct file *filp;
+ struct inode *inode = NULL;
+ int length;
+
+ /* open file */
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open(fake_file, O_RDONLY, S_IRUSR);
+
+ if (IS_ERR(filp)) {
+ printk("%s: file %s filp_open error\n", __FUNCTION__, fake_file);
+ set_fs(oldfs);
+ return;
+ }
+
+ if (!filp->f_op) {
+ printk("%s: File Operation Method Error\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ inode = GET_INODE_FROM_FILEP(filep);
+ if (!inode) {
+ printk("%s: Get inode from filp failed\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
+
+ /* file's size */
+ length = i_size_read(inode->i_mapping->host);
+ printk("%s: length=%d\n", __FUNCTION__, length);
+ if (length != EEPROM_SZ) {
+ printk("%s: The file's size is not as expected\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ /* read data */
+ if (filp->f_op->read(filp, eeprom_data, length, &filp->f_pos) != length) {
+ printk("%s: file read error\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ /* read data out successfully */
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ } else {
+ /*
+ * Read from EEPROM to file OR transfer from EEPROM to Target RAM.
+ * Fetch EEPROM_SZ Bytes of Board Data, 8 bytes at a time.
+ */
+
+ fetch_8bytes(0, (A_UINT32 *)(&eeprom_data[0]));
+
+ /* Check the first word of EEPROM for validity */
+ first_word = *((A_UINT32 *)eeprom_data);
+
+ if ((first_word == 0) || (first_word == 0xffffffff)) {
+ printk("Did not find EEPROM with valid Board Data.\n");
+ }
+
+ for (i=8; i<EEPROM_SZ; i+=8) {
+ fetch_8bytes(i, (A_UINT32 *)(&eeprom_data[i]));
+ }
+ }
+
+ /* soft mac */
+ if (p_mac) {
+
+ mm_segment_t oldfs;
+ struct file *filp;
+ struct inode *inode = NULL;
+ int length;
+
+ /* open file */
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ filp = filp_open(p_mac, O_RDONLY, S_IRUSR);
+
+ printk("%s try to open file %s\n", __FUNCTION__, p_mac);
+
+ if (IS_ERR(filp)) {
+ printk("%s: file %s filp_open error\n", __FUNCTION__, p_mac);
+ set_fs(oldfs);
+ return;
+ }
+
+ if (!filp->f_op) {
+ printk("%s: File Operation Method Error\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ inode = GET_INODE_FROM_FILEP(filep);
+ if (!inode) {
+ printk("%s: Get inode from filp failed\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
+
+ /* file's size */
+ length = i_size_read(inode->i_mapping->host);
+ printk("%s: length=%d\n", __FUNCTION__, length);
+ if (length > ATH_SOFT_MAC_TMP_BUF_LEN) {
+ printk("%s: MAC file's size is not as expected\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+ /* read data */
+ if (filp->f_op->read(filp, soft_mac_tmp_buf, length, &filp->f_pos) != length) {
+ printk("%s: file read error\n", __FUNCTION__);
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+ return;
+ }
+
+#if 0
+ /* the data we just read */
+ printk("%s: mac address from the file:\n", __FUNCTION__);
+ for (i = 0; i < length; i++)
+ printk("[%c(0x%x)],", soft_mac_tmp_buf[i], soft_mac_tmp_buf[i]);
+ printk("\n");
+#endif
+
+ /* read data out successfully */
+ filp_close(filp, NULL);
+ set_fs(oldfs);
+
+ /* convert mac address */
+ if (!wmic_ether_aton(soft_mac_tmp_buf, mac_addr)) {
+ printk("%s: convert mac value fail\n", __FUNCTION__);
+ return;
+ }
+
+#if 0
+ /* the converted mac address */
+ printk("%s: the converted mac value\n", __FUNCTION__);
+ for (i = 0; i < ATH_MAC_LEN; i++)
+ printk("[0x%x],", mac_addr[i]);
+ printk("\n");
+#endif
+ }
+ /* soft mac */
+
+ /* Determine where in Target RAM to write Board Data */
+ BMI_read_mem( HOST_INTEREST_ITEM_ADDRESS(hi_board_data), &board_data_addr);
+ if (board_data_addr == 0) {
+ printk("hi_board_data is zero\n");
+ }
+
+ /* soft mac */
+#if 1
+ /* Update MAC address in RAM */
+ if (p_mac) {
+ update_mac(eeprom_data, EEPROM_SZ, mac_addr);
+ }
+#endif
+#if 0
+ /* mac address in eeprom array */
+ printk("%s: mac values in eeprom array\n", __FUNCTION__);
+ for (i = 10; i < 10 + 6; i++)
+ printk("[0x%x],", eeprom_data[i]);
+ printk("\n");
+#endif
+ /* soft mac */
+
+ /* Write EEPROM data to Target RAM */
+ BMI_write_mem(board_data_addr, ((A_UINT8 *)eeprom_data), EEPROM_SZ);
+
+ /* Record the fact that Board Data IS initialized */
+ {
+ A_UINT32 one = 1;
+ BMI_write_mem(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized),
+ (A_UINT8 *)&one, sizeof(A_UINT32));
+ }
+
+ disable_SI();
+}
+#endif
+/* ATHENV */
+
diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
new file mode 100644
index 000000000000..ffbf3d229a5e
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c
@@ -0,0 +1,125 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HCI bridge implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include <a_config.h>
+#include <athdefs.h>
+#include "a_types.h"
+#include "a_osapi.h"
+#include "htc_api.h"
+#include "a_drv.h"
+#include "hif.h"
+#include "common_drv.h"
+#include "a_debug.h"
+#include "hci_transport_api.h"
+
+#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h"
+#include "AR6002/hw4.0/hw/uart_reg.h"
+#include "AR6002/hw4.0/hw/rtc_wlan_reg.h"
+
+HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo);
+void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
+A_STATUS (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue);
+A_STATUS (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous);
+void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
+A_STATUS (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
+A_STATUS (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+A_STATUS (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
+ HTC_PACKET *pPacket,
+ int MaxPollMS);
+A_STATUS (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud);
+A_STATUS (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+
+extern HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks;
+
+A_STATUS ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks)
+{
+ ar6kHciTransCallbacks = *hciTransCallbacks;
+
+ _HCI_TransportAttach = HCI_TransportAttach;
+ _HCI_TransportDetach = HCI_TransportDetach;
+ _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts;
+ _HCI_TransportSendPkt = HCI_TransportSendPkt;
+ _HCI_TransportStop = HCI_TransportStop;
+ _HCI_TransportStart = HCI_TransportStart;
+ _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv;
+ _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync;
+ _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate;
+ _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt;
+
+ return A_OK;
+}
+
+A_STATUS
+ar6000_get_hif_dev(HIF_DEVICE *device, void *config)
+{
+ A_STATUS status;
+
+ status = HIFConfigureDevice(device,
+ HIF_DEVICE_GET_OS_DEVICE,
+ (HIF_DEVICE_OS_DEVICE_INFO *)config,
+ sizeof(HIF_DEVICE_OS_DEVICE_INFO));
+ return status;
+}
+
+A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice,
+ A_UINT32 scale,
+ A_UINT32 step)
+{
+ A_UINT32 regAddress;
+ A_UINT32 regVal;
+ A_STATUS status;
+
+ regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
+ regVal = ((A_UINT32)scale << 16) | step;
+ /* change the HCI UART scale/step values through the diagnostic window */
+ status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);
+
+ return status;
+}
+
+A_STATUS ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data)
+{
+ A_UINT32 regAddress;
+ A_STATUS status;
+
+ regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS;
+ /* read CPU clock settings*/
+ status = ar6000_ReadRegDiag(hifDevice, &regAddress, data);
+
+ return status;
+}
+
+EXPORT_SYMBOL(ar6000_register_hci_transport);
+EXPORT_SYMBOL(ar6000_get_hif_dev);
+EXPORT_SYMBOL(ar6000_set_uart_config);
+EXPORT_SYMBOL(ar6000_get_core_clock_config);
+EXPORT_SYMBOL(_HCI_TransportAttach);
+EXPORT_SYMBOL(_HCI_TransportDetach);
+EXPORT_SYMBOL(_HCI_TransportAddReceivePkts);
+EXPORT_SYMBOL(_HCI_TransportSendPkt);
+EXPORT_SYMBOL(_HCI_TransportStop);
+EXPORT_SYMBOL(_HCI_TransportStart);
+EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv);
+EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync);
+EXPORT_SYMBOL(_HCI_TransportSetBaudRate);
+EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt);
diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c
new file mode 100644
index 000000000000..5cdc3b85a6f6
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c
@@ -0,0 +1,1144 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HCI bridge implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+#include <linux/etherdevice.h>
+#include <a_config.h>
+#include <athdefs.h>
+#include "a_types.h"
+#include "a_osapi.h"
+#include "htc_api.h"
+#include "wmi.h"
+#include "a_drv.h"
+#include "hif.h"
+#include "common_drv.h"
+#include "a_debug.h"
+#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
+#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
+#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
+#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
+#else
+#include "ar6000_drv.h"
+#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
+
+#ifdef ATH_AR6K_ENABLE_GMBOX
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+#include "export_hci_transport.h"
+#else
+#include "hci_transport_api.h"
+#endif
+#include "epping_test.h"
+#include "gmboxif.h"
+#include "ar3kconfig.h"
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+ /* only build on newer kernels which have BT configured */
+#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT)
+#define CONFIG_BLUEZ_HCI_BRIDGE
+#endif
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+unsigned int ar3khcibaud = 0;
+unsigned int hciuartscale = 0;
+unsigned int hciuartstep = 0;
+
+module_param(ar3khcibaud, int, 0644);
+module_param(hciuartscale, int, 0644);
+module_param(hciuartstep, int, 0644);
+#else
+extern unsigned int ar3khcibaud;
+extern unsigned int hciuartscale;
+extern unsigned int hciuartstep;
+#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
+
+typedef struct {
+ void *pHCIDev; /* HCI bridge device */
+ HCI_TRANSPORT_PROPERTIES HCIProps; /* HCI bridge props */
+ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
+ A_BOOL HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/
+ A_BOOL HciRegistered; /* HCI device registered with stack */
+ HTC_PACKET_QUEUE HTCPacketStructHead;
+ A_UINT8 *pHTCStructAlloc;
+ spinlock_t BridgeLock;
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ HCI_TRANSPORT_MISC_HANDLES HCITransHdl;
+#else
+ AR_SOFTC_T *ar;
+#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
+} AR6K_HCI_BRIDGE_INFO;
+
+#define MAX_ACL_RECV_BUFS 16
+#define MAX_EVT_RECV_BUFS 8
+#define MAX_HCI_WRITE_QUEUE_DEPTH 32
+#define MAX_ACL_RECV_LENGTH 1200
+#define MAX_EVT_RECV_LENGTH 257
+#define TX_PACKET_RSV_OFFSET 32
+#define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2)
+
+#define HCI_GET_OP_CODE(p) (((A_UINT16)((p)[1])) << 8) | ((A_UINT16)((p)[0]))
+
+extern unsigned int setupbtdev;
+AR3K_CONFIG_INFO ar3kconfig;
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo;
+#endif
+
+static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
+static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
+static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo);
+static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
+ HCI_TRANSPORT_PACKET_TYPE Type,
+ struct sk_buff *skb);
+static struct sk_buff *bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length);
+static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb);
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+A_STATUS ar6000_setup_hci(void *ar);
+void ar6000_cleanup_hci(void *ar);
+A_STATUS hci_test_send(void *ar, struct sk_buff *skb);
+#else
+A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar);
+void ar6000_cleanup_hci(AR_SOFTC_T *ar);
+/* HCI bridge testing */
+A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb);
+#endif /* EXPORT_HCI_BRIDGE_INTERFACE */
+
+#define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
+#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
+
+static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, void *osbuf)
+{
+ if (pHcidevInfo->HciNormalMode) {
+ bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
+ } else {
+ /* in test mode, these are just ordinary netbuf allocations */
+ A_NETBUF_FREE(osbuf);
+ }
+}
+
+static void FreeHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HTC_PACKET *pPacket)
+{
+ LOCK_BRIDGE(pHcidevInfo);
+ HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
+ UNLOCK_BRIDGE(pHcidevInfo);
+}
+
+static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ HTC_PACKET *pPacket = NULL;
+ LOCK_BRIDGE(pHcidevInfo);
+ pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
+ UNLOCK_BRIDGE(pHcidevInfo);
+ return pPacket;
+}
+
+#define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
+
+static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
+ HCI_TRANSPORT_PACKET_TYPE Type,
+ int NumBuffers)
+{
+ int length, i;
+ void *osBuf = NULL;
+ HTC_PACKET_QUEUE queue;
+ HTC_PACKET *pPacket;
+
+ INIT_HTC_PACKET_QUEUE(&queue);
+
+ if (Type == HCI_ACL_TYPE) {
+ if (pHcidevInfo->HciNormalMode) {
+ length = HCI_MAX_FRAME_SIZE;
+ } else {
+ length = MAX_ACL_RECV_LENGTH;
+ }
+ } else {
+ length = MAX_EVT_RECV_LENGTH;
+ }
+
+ /* add on transport head and tail room */
+ length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom;
+ /* round up to the required I/O padding */
+ length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad);
+
+ for (i = 0; i < NumBuffers; i++) {
+
+ if (pHcidevInfo->HciNormalMode) {
+ osBuf = bt_alloc_buffer(pHcidevInfo,length);
+ } else {
+ osBuf = A_NETBUF_ALLOC(length);
+ }
+
+ if (NULL == osBuf) {
+ break;
+ }
+
+ pPacket = AllocHTCStruct(pHcidevInfo);
+ if (NULL == pPacket) {
+ FreeBtOsBuf(pHcidevInfo,osBuf);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
+ break;
+ }
+
+ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
+ /* add to queue */
+ HTC_PACKET_ENQUEUE(&queue,pPacket);
+ }
+
+ if (i > 0) {
+ HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
+ }
+}
+
+#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \
+ (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))
+static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle,
+ HCI_TRANSPORT_PROPERTIES *pProps,
+ void *pContext)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+ A_STATUS status;
+ A_UINT32 address, hci_uart_pwr_mgmt_params;
+// AR3K_CONFIG_INFO ar3kconfig;
+
+ pHcidevInfo->pHCIDev = HCIHandle;
+
+ A_MEMCPY(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n",
+ (unsigned long)HCIHandle,
+ pHcidevInfo->HCIProps.HeadRoom,
+ pHcidevInfo->HCIProps.TailRoom,
+ pHcidevInfo->HCIProps.IOBlockPad));
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
+#else
+ A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
+#endif
+
+ /* provide buffers */
+ RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
+ RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
+
+ do {
+ /* start transport */
+ status = HCI_TransportStart(pHcidevInfo->pHCIDev);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (!pHcidevInfo->HciNormalMode) {
+ /* in test mode, no need to go any further */
+ break;
+ }
+
+ // The delay is required when AR6K is driving the BT reset line
+ // where time is needed after the BT chip is out of reset (HCI_TransportStart)
+ // and before the first HCI command is issued (AR3KConfigure)
+ // FIXME
+ // The delay should be configurable and be only applied when AR6K driving the BT
+ // reset line. This could be done by some module parameter or based on some HW config
+ // info. For now apply 100ms delay blindly
+ A_MDELAY(100);
+
+ A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
+ ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
+ ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ ar3kconfig.pHIFDevice = (HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice);
+#else
+ ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
+#endif
+ ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
+
+ if (ar3khcibaud != 0) {
+ /* user wants ar3k baud rate change */
+ ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
+ ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
+ ar3kconfig.AR3KBaudRate = ar3khcibaud;
+ }
+
+ if ((hciuartscale != 0) || (hciuartstep != 0)) {
+ /* user wants to tune HCI bridge UART scale/step values */
+ ar3kconfig.AR6KScale = (A_UINT16)hciuartscale;
+ ar3kconfig.AR6KStep = (A_UINT16)hciuartstep;
+ ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
+ }
+
+ /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
+ address = TARG_VTOP(pHcidevInfo->ar->arTargetType,
+ HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
+ status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
+ if (A_OK == status) {
+ ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
+ ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
+ ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
+ }
+ /* configure the AR3K device */
+ memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
+ status = AR3KConfigure(&ar3kconfig);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /* Make sure both AR6K and AR3K have power management enabled */
+ if (ar3kconfig.PwrMgmtEnabled) {
+ status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, TRUE);
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
+ }
+ }
+
+ status = bt_register_hci(pHcidevInfo);
+
+ } while (FALSE);
+
+ return status;
+}
+
+static void ar6000_hci_transport_failure(void *pContext, A_STATUS Status)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
+
+ if (pHcidevInfo->HciNormalMode) {
+ /* TODO .. */
+ }
+}
+
+static void ar6000_hci_transport_removed(void *pContext)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
+
+ A_ASSERT(pHcidevInfo->pHCIDev != NULL);
+
+ HCI_TransportDetach(pHcidevInfo->pHCIDev);
+ bt_cleanup_hci(pHcidevInfo);
+ pHcidevInfo->pHCIDev = NULL;
+}
+
+static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+ void *osbuf = pPacket->pPktContext;
+ A_ASSERT(osbuf != NULL);
+ A_ASSERT(pHcidevInfo != NULL);
+
+ if (A_FAILED(pPacket->Status)) {
+ if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status));
+ }
+ }
+
+ FreeHTCStruct(pHcidevInfo,pPacket);
+ FreeBtOsBuf(pHcidevInfo,osbuf);
+
+}
+
+static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+ struct sk_buff *skb;
+
+ A_ASSERT(pHcidevInfo != NULL);
+ skb = (struct sk_buff *)pPacket->pPktContext;
+ A_ASSERT(skb != NULL);
+
+ do {
+
+ if (A_FAILED(pPacket->Status)) {
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
+ ("HCI Bridge, packet received type : %d len:%d \n",
+ HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength));
+
+ /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set
+ * to fill the front of the buffer */
+ A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom);
+ A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom);
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n",
+ (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL",
+ skb->len));
+ AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
+ }
+
+ if (pHcidevInfo->HciNormalMode) {
+ /* indicate the packet */
+ if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) {
+ /* bt stack accepted the packet */
+ skb = NULL;
+ }
+ break;
+ }
+
+ /* for testing, indicate packet to the network stack */
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice);
+ if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) {
+ skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice));
+#else
+ skb->dev = pHcidevInfo->ar->arNetDev;
+ if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) {
+ skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev);
+#endif
+ netif_rx(skb);
+ skb = NULL;
+ }
+
+ } while (FALSE);
+
+ FreeHTCStruct(pHcidevInfo,pPacket);
+
+ if (skb != NULL) {
+ /* packet was not accepted, free it */
+ FreeBtOsBuf(pHcidevInfo,skb);
+ }
+
+}
+
+static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+ int refillCount;
+
+ if (Type == HCI_ACL_TYPE) {
+ refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
+ } else {
+ refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
+ }
+
+ if (refillCount > 0) {
+ RefillRecvBuffers(pHcidevInfo,Type,refillCount);
+ }
+
+}
+
+static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET *pPacket)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
+ HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
+
+ if (!pHcidevInfo->HciNormalMode) {
+ /* for epping testing, check packet tag, some epping packets are
+ * special and cannot be dropped */
+ if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) {
+ action = HCI_SEND_FULL_DROP;
+ }
+ }
+
+ return action;
+}
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+A_STATUS ar6000_setup_hci(void *ar)
+#else
+A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
+#endif
+{
+ HCI_TRANSPORT_CONFIG_INFO config;
+ A_STATUS status = A_OK;
+ int i;
+ HTC_PACKET *pPacket;
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
+
+
+ do {
+
+ pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO));
+
+ if (NULL == pHcidevInfo) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO));
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ g_pHcidevInfo = pHcidevInfo;
+ pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar;
+#else
+ ar->hcidev_info = pHcidevInfo;
+ pHcidevInfo->ar = ar;
+#endif
+ spin_lock_init(&pHcidevInfo->BridgeLock);
+ INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
+
+ ar->exitCallback = AR3KConfigureExit;
+
+ status = bt_setup_hci(pHcidevInfo);
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ if (pHcidevInfo->HciNormalMode) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
+ }
+
+ pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS);
+
+ if (NULL == pHcidevInfo->pHTCStructAlloc) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc;
+ for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
+ FreeHTCStruct(pHcidevInfo,pPacket);
+ }
+
+ A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO));
+ config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
+ config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
+ config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
+ config.pContext = pHcidevInfo;
+ config.TransportFailure = ar6000_hci_transport_failure;
+ config.TransportReady = ar6000_hci_transport_ready;
+ config.TransportRemoved = ar6000_hci_transport_removed;
+ config.pHCISendComplete = ar6000_hci_send_complete;
+ config.pHCIPktRecv = ar6000_hci_pkt_recv;
+ config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
+ config.pHCISendFull = ar6000_hci_pkt_send_full;
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
+#else
+ pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
+#endif
+
+ if (NULL == pHcidevInfo->pHCIDev) {
+ status = A_ERROR;
+ }
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ if (pHcidevInfo != NULL) {
+ if (NULL == pHcidevInfo->pHCIDev) {
+ /* GMBOX may not be present in older chips */
+ /* just return success */
+ status = A_OK;
+ }
+ }
+ ar6000_cleanup_hci(ar);
+ }
+
+ return status;
+}
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+void ar6000_cleanup_hci(void *ar)
+#else
+void ar6000_cleanup_hci(AR_SOFTC_T *ar)
+#endif
+{
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
+#else
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
+#endif
+
+ if (pHcidevInfo != NULL) {
+ bt_cleanup_hci(pHcidevInfo);
+
+ if (pHcidevInfo->pHCIDev != NULL) {
+ HCI_TransportStop(pHcidevInfo->pHCIDev);
+ HCI_TransportDetach(pHcidevInfo->pHCIDev);
+ pHcidevInfo->pHCIDev = NULL;
+ }
+
+ if (pHcidevInfo->pHTCStructAlloc != NULL) {
+ A_FREE(pHcidevInfo->pHTCStructAlloc);
+ pHcidevInfo->pHTCStructAlloc = NULL;
+ }
+
+ A_FREE(pHcidevInfo);
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+ ar->hcidev_info = NULL;
+#endif
+ }
+
+
+}
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+A_STATUS hci_test_send(void *ar, struct sk_buff *skb)
+#else
+A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
+#endif
+{
+ int status = A_OK;
+ int length;
+ EPPING_HEADER *pHeader;
+ HTC_PACKET *pPacket;
+ HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
+#else
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
+#endif
+
+ do {
+
+ if (NULL == pHcidevInfo) {
+ status = A_ERROR;
+ break;
+ }
+
+ if (NULL == pHcidevInfo->pHCIDev) {
+ status = A_ERROR;
+ break;
+ }
+
+ if (pHcidevInfo->HciNormalMode) {
+ /* this interface cannot run when normal WMI is running */
+ status = A_ERROR;
+ break;
+ }
+
+ pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
+
+ if (!IS_EPPING_PACKET(pHeader)) {
+ status = A_EINVAL;
+ break;
+ }
+
+ if (IS_EPING_PACKET_NO_DROP(pHeader)) {
+ htc_tag = AR6K_CONTROL_PKT_TAG;
+ }
+
+ length = sizeof(EPPING_HEADER) + pHeader->DataLength;
+
+ pPacket = AllocHTCStruct(pHcidevInfo);
+ if (NULL == pPacket) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ SET_HTC_PACKET_INFO_TX(pPacket,
+ skb,
+ A_NETBUF_DATA(skb),
+ length,
+ HCI_ACL_TYPE, /* send every thing out as ACL */
+ htc_tag);
+
+ HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE);
+ pPacket = NULL;
+
+ } while (FALSE);
+
+ return status;
+}
+
+void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
+ AR3K_CONFIG_INFO *config = (AR3K_CONFIG_INFO *)ar3kconfig;
+
+ config->pHCIDev = pHcidevInfo->pHCIDev;
+ config->pHCIProps = &pHcidevInfo->HCIProps;
+ config->pHIFDevice = ar->arHifDevice;
+ config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
+ config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
+ config->AR3KBaudRate = 115200;
+}
+
+#ifdef CONFIG_BLUEZ_HCI_BRIDGE
+/*** BT Stack Entrypoints *******/
+
+/*
+ * bt_open - open a handle to the device
+*/
+static int bt_open(struct hci_dev *hdev)
+{
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n"));
+ set_bit(HCI_RUNNING, &hdev->flags);
+ set_bit(HCI_UP, &hdev->flags);
+ set_bit(HCI_INIT, &hdev->flags);
+ return 0;
+}
+
+/*
+ * bt_close - close handle to the device
+*/
+static int bt_close(struct hci_dev *hdev)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ return 0;
+}
+
+/*
+ * bt_send_frame - send data frames
+*/
+static int bt_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *)skb->dev;
+ HCI_TRANSPORT_PACKET_TYPE type;
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
+ HTC_PACKET *pPacket;
+ A_STATUS status = A_OK;
+ struct sk_buff *txSkb = NULL;
+
+ if (!hdev) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
+ return -ENODEV;
+ }
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
+ return -EBUSY;
+ }
+
+ pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
+ A_ASSERT(pHcidevInfo != NULL);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
+ type = HCI_COMMAND_TYPE;
+
+ switch (bt_cb(skb)->pkt_type) {
+ case HCI_COMMAND_PKT:
+ type = HCI_COMMAND_TYPE;
+ hdev->stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ type = HCI_ACL_TYPE;
+ hdev->stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ /* we don't support SCO over the bridge */
+ kfree_skb(skb);
+ return 0;
+ default:
+ A_ASSERT(FALSE);
+ kfree_skb(skb);
+ return 0;
+ }
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
+ (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
+ skb->len));
+ if (type == HCI_COMMAND_TYPE) {
+ A_UINT16 opcode = HCI_GET_OP_CODE(skb->data);
+ AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n",
+ opcode >> 10, opcode & 0x3FF));
+ }
+ AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
+ }
+
+ do {
+
+ txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom +
+ pHcidevInfo->HCIProps.TailRoom + skb->len,
+ GFP_ATOMIC);
+
+ if (txSkb == NULL) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
+ txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
+ skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom);
+ A_MEMCPY(txSkb->data, skb->data, skb->len);
+ skb_put(txSkb,skb->len);
+
+ pPacket = AllocHTCStruct(pHcidevInfo);
+ if (NULL == pPacket) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ /* HCI packet length here doesn't include the 1-byte transport header which
+ * will be handled by the HCI transport layer. Enough headroom has already
+ * been reserved above for the transport header
+ */
+ SET_HTC_PACKET_INFO_TX(pPacket,
+ txSkb,
+ txSkb->data,
+ txSkb->len,
+ type,
+ AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb));
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n",
+ type, txSkb->len));
+
+ status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE);
+ pPacket = NULL;
+ txSkb = NULL;
+
+ } while (FALSE);
+
+ if (txSkb != NULL) {
+ kfree_skb(txSkb);
+ }
+
+ kfree_skb(skb);
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
+ return 0;
+}
+
+/*
+ * bt_ioctl - ioctl processing
+*/
+static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
+ return -ENOIOCTLCMD;
+}
+
+/*
+ * bt_flush - flush outstandingbpackets
+*/
+static int bt_flush(struct hci_dev *hdev)
+{
+ AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
+
+ pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
+
+ /* TODO??? */
+
+ return 0;
+}
+
+
+/*
+ * bt_destruct -
+*/
+static void bt_destruct(struct hci_dev *hdev)
+{
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
+ /* nothing to do here */
+}
+
+static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ A_STATUS status = A_OK;
+ struct hci_dev *pHciDev = NULL;
+ HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
+
+ if (!setupbtdev) {
+ return A_OK;
+ }
+
+ do {
+
+ A_MEMZERO(&osDevInfo,sizeof(osDevInfo));
+ /* get the underlying OS device */
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+ status = ar6000_get_hif_dev((HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice),
+ &osDevInfo);
+#else
+ status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
+ HIF_DEVICE_GET_OS_DEVICE,
+ &osDevInfo,
+ sizeof(osDevInfo));
+#endif
+
+ if (A_FAILED(status)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
+ break;
+ }
+
+ /* allocate a BT HCI struct for this device */
+ pHciDev = hci_alloc_dev();
+ if (NULL == pHciDev) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n"));
+ status = A_NO_MEMORY;
+ break;
+ }
+ /* save the device, we'll register this later */
+ pHcidevInfo->pBtStackHCIDev = pHciDev;
+ SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice);
+ SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR);
+ pHciDev->driver_data = pHcidevInfo;
+ pHciDev->open = bt_open;
+ pHciDev->close = bt_close;
+ pHciDev->send = bt_send_frame;
+ pHciDev->ioctl = bt_ioctl;
+ pHciDev->flush = bt_flush;
+ pHciDev->destruct = bt_destruct;
+ pHciDev->owner = THIS_MODULE;
+ /* driver is running in normal BT mode */
+ pHcidevInfo->HciNormalMode = TRUE;
+
+ } while (FALSE);
+
+ if (A_FAILED(status)) {
+ bt_cleanup_hci(pHcidevInfo);
+ }
+
+ return status;
+}
+
+static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ int err;
+
+ if (pHcidevInfo->HciRegistered) {
+ pHcidevInfo->HciRegistered = FALSE;
+ clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags);
+ clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags);
+ clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags);
+ A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
+ /* unregister */
+ if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err));
+ }
+ }
+
+ if (pHcidevInfo->pBtStackHCIDev != NULL) {
+ kfree(pHcidevInfo->pBtStackHCIDev);
+ pHcidevInfo->pBtStackHCIDev = NULL;
+ }
+}
+
+static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ int err;
+ A_STATUS status = A_OK;
+
+ do {
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n"));
+ A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL);
+ /* mark that we are registered */
+ pHcidevInfo->HciRegistered = TRUE;
+ if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err));
+ pHcidevInfo->HciRegistered = FALSE;
+ status = A_ERROR;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
+
+ } while (FALSE);
+
+ return status;
+}
+
+static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
+ HCI_TRANSPORT_PACKET_TYPE Type,
+ struct sk_buff *skb)
+{
+ A_UINT8 btType;
+ int len;
+ A_BOOL success = FALSE;
+ BT_HCI_EVENT_HEADER *pEvent;
+
+ do {
+
+ if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
+ break;
+ }
+
+ switch (Type) {
+ case HCI_ACL_TYPE:
+ btType = HCI_ACLDATA_PKT;
+ break;
+ case HCI_EVENT_TYPE:
+ btType = HCI_EVENT_PKT;
+ break;
+ default:
+ btType = 0;
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ if (0 == btType) {
+ break;
+ }
+
+ /* set the final type */
+ bt_cb(skb)->pkt_type = btType;
+ /* set dev */
+ skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
+ len = skb->len;
+
+ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) {
+ if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
+ pEvent = (BT_HCI_EVENT_HEADER *)skb->data;
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n",
+ pEvent->EventCode, pEvent->ParamLength));
+ }
+ }
+
+ /* pass receive packet up the stack */
+ if (hci_recv_frame(skb) != 0) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n"));
+ break;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
+ ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
+ }
+
+ success = TRUE;
+
+ } while (FALSE);
+
+ return success;
+}
+
+static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length)
+{
+ struct sk_buff *skb;
+ /* in normal HCI mode we need to alloc from the bt core APIs */
+ skb = bt_skb_alloc(Length, GFP_ATOMIC);
+ if (NULL == skb) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
+ }
+ return skb;
+}
+
+static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb)
+{
+ kfree_skb(skb);
+}
+
+#else // { CONFIG_BLUEZ_HCI_BRIDGE
+
+ /* stubs when we only want to test the HCI bridging Interface without the HT stack */
+static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ return A_OK;
+}
+static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+
+}
+static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
+{
+ A_ASSERT(FALSE);
+ return A_ERROR;
+}
+
+static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
+ HCI_TRANSPORT_PACKET_TYPE Type,
+ struct sk_buff *skb)
+{
+ A_ASSERT(FALSE);
+ return FALSE;
+}
+
+static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length)
+{
+ A_ASSERT(FALSE);
+ return NULL;
+}
+static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb)
+{
+ A_ASSERT(FALSE);
+}
+
+#endif // } CONFIG_BLUEZ_HCI_BRIDGE
+
+#else // { ATH_AR6K_ENABLE_GMBOX
+
+ /* stubs when GMBOX support is not needed */
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+A_STATUS ar6000_setup_hci(void *ar)
+#else
+A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
+#endif
+{
+ return A_OK;
+}
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+void ar6000_cleanup_hci(void *ar)
+#else
+void ar6000_cleanup_hci(AR_SOFTC_T *ar)
+#endif
+{
+ return;
+}
+
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
+{
+ return;
+}
+#endif
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+int hci_test_send(void *ar, struct sk_buff *skb)
+#else
+int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
+#endif
+{
+ return -EOPNOTSUPP;
+}
+
+#endif // } ATH_AR6K_ENABLE_GMBOX
+
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+static int __init
+hcibridge_init_module(void)
+{
+ A_STATUS status;
+ HCI_TRANSPORT_CALLBACKS hciTransCallbacks;
+
+ hciTransCallbacks.setupTransport = ar6000_setup_hci;
+ hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
+
+ status = ar6000_register_hci_transport(&hciTransCallbacks);
+ if(status != A_OK)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void __exit
+hcibridge_cleanup_module(void)
+{
+}
+
+module_init(hcibridge_init_module);
+module_exit(hcibridge_cleanup_module);
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
new file mode 100644
index 000000000000..8be4f553ab8e
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
@@ -0,0 +1,770 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _AR6000_H_
+#define _AR6000_H_
+
+#include <linux/version.h>
+
+
+#include <generated/autoconf.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/iw_handler.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#include <linux/semaphore.h>
+#include <linux/wireless.h>
+#ifdef ATH6K_CONFIG_CFG80211
+#include <net/cfg80211.h>
+#endif /* ATH6K_CONFIG_CFG80211 */
+#include <linux/module.h>
+#include <asm/io.h>
+
+#include <a_config.h>
+#include <athdefs.h>
+#include "a_types.h"
+#include "a_osapi.h"
+#include "htc_api.h"
+#include "wmi.h"
+#include "a_drv.h"
+#include "bmi.h"
+#include <ieee80211.h>
+#include <ieee80211_ioctl.h>
+#include <wlan_api.h>
+#include <wmi_api.h>
+#include "gpio_api.h"
+#include "gpio.h"
+#include "pkt_log.h"
+#include "aggr_recv_api.h"
+#include <host_version.h>
+#include <linux/rtnetlink.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include "ar6000_api.h"
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+#include <testcmd.h>
+#endif
+#include <linux/firmware.h>
+
+#include "targaddrs.h"
+#include "dbglog_api.h"
+#include "ar6000_diag.h"
+#include "common_drv.h"
+#include "roaming.h"
+#include "hci_transport_api.h"
+#define ATH_MODULE_NAME driver
+#include "a_debug.h"
+#include "hw/apb_map.h"
+#include "hw/rtc_reg.h"
+#include "hw/mbox_reg.h"
+#include "hw/gpio_reg.h"
+
+#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0)
+#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1)
+#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2)
+#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3)
+#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4)
+#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5)
+#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6)
+#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7)
+#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8)
+#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9)
+
+#ifndef __dev_put
+#define __dev_put(dev) dev_put(dev)
+#endif
+
+
+#ifdef USER_KEYS
+
+#define USER_SAVEDKEYS_STAT_INIT 0
+#define USER_SAVEDKEYS_STAT_RUN 1
+
+// TODO this needs to move into the AR_SOFTC struct
+struct USER_SAVEDKEYS {
+ struct ieee80211req_key ucast_ik;
+ struct ieee80211req_key bcast_ik;
+ CRYPTO_TYPE keyType;
+ A_BOOL keyOk;
+};
+#endif
+
+#define DBG_INFO 0x00000001
+#define DBG_ERROR 0x00000002
+#define DBG_WARNING 0x00000004
+#define DBG_SDIO 0x00000008
+#define DBG_HIF 0x00000010
+#define DBG_HTC 0x00000020
+#define DBG_WMI 0x00000040
+#define DBG_WMI2 0x00000080
+#define DBG_DRIVER 0x00000100
+
+#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING)
+
+
+A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_AR6000 1
+#define AR6000_MAX_RX_BUFFERS 16
+#define AR6000_BUFFER_SIZE 1664
+#define AR6000_MAX_AMSDU_RX_BUFFERS 4
+#define AR6000_AMSDU_REFILL_THRESHOLD 3
+#define AR6000_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
+#define AR6000_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))
+
+#define AR6000_TX_TIMEOUT 10
+#define AR6000_ETH_ADDR_LEN 6
+#define AR6000_MAX_ENDPOINTS 4
+#define MAX_NODE_NUM 15
+/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
+#define MAX_DEF_COOKIE_NUM 180
+#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
+#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
+
+/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the
+ * WMM send queues. If a queue exceeds this depth htc will query back to the
+ * OS specific layer by calling EpSendFull(). This gives the OS layer the
+ * opportunity to drop the packet if desired. Therefore changing
+ * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but
+ * does impact the threshold used to identify if a packet should be
+ * dropped. */
+#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
+
+#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1
+#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1
+#define A_DISCONNECT_TIMER_INTERVAL 10 * 1000
+#define A_DEFAULT_LISTEN_INTERVAL 100
+#define A_MAX_WOW_LISTEN_INTERVAL 1000
+
+enum {
+ DRV_HB_CHALLENGE = 0,
+ APP_HB_CHALLENGE
+};
+
+enum {
+ WLAN_INIT_MODE_NONE = 0,
+ WLAN_INIT_MODE_USR,
+ WLAN_INIT_MODE_UDEV,
+ WLAN_INIT_MODE_DRV
+};
+
+/* Suspend - configuration */
+enum {
+ WLAN_SUSPEND_CUT_PWR = 0,
+ WLAN_SUSPEND_DEEP_SLEEP,
+ WLAN_SUSPEND_WOW,
+ WLAN_SUSPEND_CUT_PWR_IF_BT_OFF
+};
+
+/* WiFi OFF - configuration */
+enum {
+ WLAN_OFF_CUT_PWR = 0,
+ WLAN_OFF_DEEP_SLEEP,
+};
+
+/* WLAN low power state */
+enum {
+ WLAN_POWER_STATE_ON = 0,
+ WLAN_POWER_STATE_CUT_PWR = 1,
+ WLAN_POWER_STATE_DEEP_SLEEP,
+ WLAN_POWER_STATE_WOW
+};
+
+/* WLAN WoW State */
+enum {
+ WLAN_WOW_STATE_NONE = 0,
+ WLAN_WOW_STATE_SUSPENDED,
+ WLAN_WOW_STATE_SUSPENDING
+};
+
+
+typedef enum _AR6K_BIN_FILE {
+ AR6K_OTP_FILE,
+ AR6K_FIRMWARE_FILE,
+ AR6K_PATCH_FILE,
+ AR6K_BOARD_DATA_FILE,
+} AR6K_BIN_FILE;
+
+#ifdef SETUPHCI_ENABLED
+#define SETUPHCI_DEFAULT 1
+#else
+#define SETUPHCI_DEFAULT 0
+#endif /* SETUPHCI_ENABLED */
+
+#ifdef SETUPHCIPAL_ENABLED
+#define SETUPHCIPAL_DEFAULT 1
+#else
+#define SETUPHCIPAL_DEFAULT 0
+#endif /* SETUPHCIPAL_ENABLED */
+
+#ifdef SETUPBTDEV_ENABLED
+#define SETUPBTDEV_DEFAULT 1
+#else
+#define SETUPBTDEV_DEFAULT 0
+#endif /* SETUPBTDEV_ENABLED */
+
+#ifdef BMIENABLE_SET
+#define BMIENABLE_DEFAULT 1
+#else
+#define BMIENABLE_DEFAULT 0
+#endif /* BMIENABLE_SET */
+
+#ifdef ENABLEUARTPRINT_SET
+#define ENABLEUARTPRINT_DEFAULT 1
+#else
+#define ENABLEUARTPRINT_DEFAULT 0
+#endif /* ENABLEARTPRINT_SET */
+
+#ifdef ATH6K_CONFIG_HIF_VIRTUAL_SCATTER
+#define NOHIFSCATTERSUPPORT_DEFAULT 1
+#else /* ATH6K_CONFIG_HIF_VIRTUAL_SCATTER */
+#define NOHIFSCATTERSUPPORT_DEFAULT 0
+#endif /* ATH6K_CONFIG_HIF_VIRTUAL_SCATTER */
+
+#ifdef AR600x_BT_AR3001
+#define AR3KHCIBAUD_DEFAULT 3000000
+#define HCIUARTSCALE_DEFAULT 1
+#define HCIUARTSTEP_DEFAULT 8937
+#else
+#define AR3KHCIBAUD_DEFAULT 0
+#define HCIUARTSCALE_DEFAULT 0
+#define HCIUARTSTEP_DEFAULT 0
+#endif /* AR600x_BT_AR3001 */
+
+#ifdef INIT_MODE_DRV_ENABLED
+#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV
+#else
+#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_USR
+#endif /* INIT_MODE_DRV_ENABLED */
+
+#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
+ if ((_ver) == AR6003_REV1_VERSION) { \
+ (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \
+ } else if ((_ver) == AR6003_REV2_VERSION) { \
+ (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \
+ } else { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+ A_ASSERT(0); \
+ } \
+} while (0)
+
+#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \
+ if ((_ver) == AR6003_REV1_VERSION) { \
+ (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \
+ } else if ((_ver) == AR6003_REV2_VERSION) { \
+ (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \
+ } else { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+ A_ASSERT(0); \
+ } \
+} while (0)
+
+#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
+ if ((_ver) == AR6003_REV1_VERSION) { \
+ (_param) = AR6003_REV1_APP_START_OVERRIDE; \
+ } else if ((_ver) == AR6003_REV2_VERSION) { \
+ (_param) = AR6003_REV2_APP_START_OVERRIDE; \
+ } else { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+ A_ASSERT(0); \
+ } \
+} while (0)
+
+/* AR6003 1.0 definitions */
+#define AR6003_REV1_VERSION 0x300002ba
+#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS AR6003_REV1_OTP_DATA_ADDRESS
+#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS 0x57ea6c
+#define AR6003_REV1_OTP_FILE "ath6k/AR6003/hw1.0/otp.bin.z77"
+#define AR6003_REV1_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athwlan.bin.z77"
+#define AR6003_REV1_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athtcmd_ram.bin"
+#define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin"
+#define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin"
+#define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin"
+#ifdef AR600x_SD31_XXX
+#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin"
+#elif defined(AR600x_SD32_XXX)
+#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin"
+#elif defined(AR600x_WB31_XXX)
+#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin"
+#else
+#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin"
+#endif /* Board Data File */
+
+/* AR6003 2.0 definitions */
+#define AR6003_REV2_VERSION 0x30000384
+#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS AR6003_REV2_OTP_DATA_ADDRESS
+#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
+#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
+#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
+#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
+#define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin"
+#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
+#define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin"
+#ifdef AR600x_SD31_XXX
+#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
+#elif defined(AR600x_SD32_XXX)
+#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin"
+#elif defined(AR600x_WB31_XXX)
+#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin"
+#else
+#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin"
+#endif /* Board Data File */
+
+/* Power states */
+enum {
+ WLAN_PWR_CTRL_UP = 0,
+ WLAN_PWR_CTRL_CUT_PWR,
+ WLAN_PWR_CTRL_DEEP_SLEEP,
+ WLAN_PWR_CTRL_WOW,
+ WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED
+};
+
+/* HTC RAW streams */
+typedef enum _HTC_RAW_STREAM_ID {
+ HTC_RAW_STREAM_NOT_MAPPED = -1,
+ HTC_RAW_STREAM_0 = 0,
+ HTC_RAW_STREAM_1 = 1,
+ HTC_RAW_STREAM_2 = 2,
+ HTC_RAW_STREAM_3 = 3,
+ HTC_RAW_STREAM_NUM_MAX
+} HTC_RAW_STREAM_ID;
+
+#define RAW_HTC_READ_BUFFERS_NUM 4
+#define RAW_HTC_WRITE_BUFFERS_NUM 4
+
+#define HTC_RAW_BUFFER_SIZE 1664
+
+typedef struct {
+ int currPtr;
+ int length;
+ unsigned char data[HTC_RAW_BUFFER_SIZE];
+ HTC_PACKET HTCPacket;
+} raw_htc_buffer;
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+/*
+ * add TCMD_MODE besides wmi and bypasswmi
+ * in TCMD_MODE, only few TCMD releated wmi commands
+ * counld be hanlder
+ */
+enum {
+ AR6000_WMI_MODE = 0,
+ AR6000_BYPASS_MODE,
+ AR6000_TCMD_MODE,
+ AR6000_WLAN_MODE
+};
+#endif /* CONFIG_HOST_TCMD_SUPPORT */
+
+struct ar_wep_key {
+ A_UINT8 arKeyIndex;
+ A_UINT8 arKeyLen;
+ A_UINT8 arKey[64];
+} ;
+
+#ifdef ATH6K_CONFIG_CFG80211
+struct ar_key {
+ A_UINT8 key[WLAN_MAX_KEY_LEN];
+ A_UINT8 key_len;
+ A_UINT8 seq[IW_ENCODE_SEQ_MAX_SIZE];
+ A_UINT8 seq_len;
+ A_UINT32 cipher;
+};
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+
+struct ar_node_mapping {
+ A_UINT8 macAddress[6];
+ A_UINT8 epId;
+ A_UINT8 txPending;
+};
+
+struct ar_cookie {
+ unsigned long arc_bp[2]; /* Must be first field */
+ HTC_PACKET HtcPkt; /* HTC packet wrapper */
+ struct ar_cookie *arc_list_next;
+};
+
+struct ar_hb_chlng_resp {
+ A_TIMER timer;
+ A_UINT32 frequency;
+ A_UINT32 seqNum;
+ A_BOOL outstanding;
+ A_UINT8 missCnt;
+ A_UINT8 missThres;
+};
+
+/* Per STA data, used in AP mode */
+/*TODO: All this should move to OS independent dir */
+
+#define STA_PWR_MGMT_MASK 0x1
+#define STA_PWR_MGMT_SHIFT 0x0
+#define STA_PWR_MGMT_AWAKE 0x0
+#define STA_PWR_MGMT_SLEEP 0x1
+
+#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
+#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT))
+#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK)
+
+#define STA_PS_POLLED_MASK 0x1
+#define STA_PS_POLLED_SHIFT 0x1
+#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
+#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
+#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT))
+
+typedef struct {
+ A_UINT16 flags;
+ A_UINT8 mac[ATH_MAC_LEN];
+ A_UINT8 aid;
+ A_UINT8 keymgmt;
+ A_UINT8 ucipher;
+ A_UINT8 auth;
+ A_UINT8 wpa_ie[IEEE80211_MAX_IE];
+ A_NETBUF_QUEUE_T psq; /* power save q */
+ A_MUTEX_T psqLock;
+} sta_t;
+
+typedef struct ar6_raw_htc {
+ HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX];
+ HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX];
+ struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX];
+ struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX];
+ wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX];
+ wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX];
+ raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
+ raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
+ A_BOOL write_buffer_available[HTC_RAW_STREAM_NUM_MAX];
+ A_BOOL read_buffer_available[HTC_RAW_STREAM_NUM_MAX];
+} AR_RAW_HTC_T;
+
+typedef struct ar6_softc {
+ struct net_device *arNetDev; /* net_device pointer */
+ void *arWmi;
+ int arTxPending[ENDPOINT_MAX];
+ int arTotalTxDataPending;
+ A_UINT8 arNumDataEndPts;
+ A_BOOL arWmiEnabled;
+ A_BOOL arWmiReady;
+ A_BOOL arConnected;
+ HTC_HANDLE arHtcTarget;
+ void *arHifDevice;
+ spinlock_t arLock;
+ struct semaphore arSem;
+ int arSsidLen;
+ u_char arSsid[32];
+ A_UINT8 arNextMode;
+ A_UINT8 arNetworkType;
+ A_UINT8 arDot11AuthMode;
+ A_UINT8 arAuthMode;
+ A_UINT8 arPairwiseCrypto;
+ A_UINT8 arPairwiseCryptoLen;
+ A_UINT8 arGroupCrypto;
+ A_UINT8 arGroupCryptoLen;
+ A_UINT8 arDefTxKeyIndex;
+ struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1];
+ A_UINT8 arBssid[6];
+ A_UINT8 arReqBssid[6];
+ A_UINT16 arChannelHint;
+ A_UINT16 arBssChannel;
+ A_UINT16 arListenIntervalB;
+ A_UINT16 arListenIntervalT;
+ struct ar6000_version arVersion;
+ A_UINT32 arTargetType;
+ A_INT8 arRssi;
+ A_UINT8 arTxPwr;
+ A_BOOL arTxPwrSet;
+ A_INT32 arBitRate;
+ struct net_device_stats arNetStats;
+ struct iw_statistics arIwStats;
+ A_INT8 arNumChannels;
+ A_UINT16 arChannelList[32];
+ A_UINT32 arRegCode;
+ A_BOOL statsUpdatePending;
+ TARGET_STATS arTargetStats;
+ A_INT8 arMaxRetries;
+ A_UINT8 arPhyCapability;
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ A_UINT8 tcmdRxReport;
+ A_UINT32 tcmdRxTotalPkt;
+ A_INT32 tcmdRxRssi;
+ A_UINT32 tcmdPm;
+ A_UINT32 arTargetMode;
+ A_UINT32 tcmdRxcrcErrPkt;
+ A_UINT32 tcmdRxsecErrPkt;
+ A_UINT16 tcmdRateCnt[TCMD_MAX_RATES];
+ A_UINT16 tcmdRateCntShortGuard[TCMD_MAX_RATES];
+#endif
+ AR6000_WLAN_STATE arWlanState;
+ struct ar_node_mapping arNodeMap[MAX_NODE_NUM];
+ A_UINT8 arIbssPsEnable;
+ A_UINT8 arNodeNum;
+ A_UINT8 arNexEpId;
+ struct ar_cookie *arCookieList;
+ A_UINT32 arCookieCount;
+ A_UINT32 arRateMask;
+ A_UINT8 arSkipScan;
+ A_UINT16 arBeaconInterval;
+ A_BOOL arConnectPending;
+ A_BOOL arWmmEnabled;
+ struct ar_hb_chlng_resp arHBChallengeResp;
+ A_UINT8 arKeepaliveConfigured;
+ A_UINT32 arMgmtFilter;
+ HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC];
+ A_BOOL arAcStreamActive[WMM_NUM_AC];
+ A_UINT8 arAcStreamPriMap[WMM_NUM_AC];
+ A_UINT8 arHiAcStreamActivePri;
+ A_UINT8 arEp2AcMapping[ENDPOINT_MAX];
+ HTC_ENDPOINT_ID arControlEp;
+#ifdef HTC_RAW_INTERFACE
+ AR_RAW_HTC_T *arRawHtc;
+#endif
+ A_BOOL arNetQueueStopped;
+ A_BOOL arRawIfInit;
+ int arDeviceIndex;
+ COMMON_CREDIT_STATE_INFO arCreditStateInfo;
+ A_BOOL arWMIControlEpFull;
+ A_BOOL dbgLogFetchInProgress;
+ A_UCHAR log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE];
+ A_UINT32 log_cnt;
+ A_UINT32 dbglog_init_done;
+ A_UINT32 arConnectCtrlFlags;
+#ifdef USER_KEYS
+ A_INT32 user_savedkeys_stat;
+ A_UINT32 user_key_ctrl;
+ struct USER_SAVEDKEYS user_saved_keys;
+#endif
+ USER_RSSI_THOLD rssi_map[12];
+ A_UINT8 arUserBssFilter;
+ A_UINT16 ap_profile_flag; /* AP mode */
+ WMI_AP_ACL g_acl; /* AP mode */
+ sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */
+ A_UINT8 sta_list_index; /* AP mode */
+ struct ieee80211req_key ap_mode_bkey; /* AP mode */
+ A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */
+ A_MUTEX_T mcastpsqLock;
+ A_BOOL DTIMExpired; /* flag to indicate DTIM expired */
+ A_UINT8 intra_bss; /* enable/disable intra bss data forward */
+ void *aggr_cntxt;
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+ void *hcidev_info;
+#endif
+ void *hcipal_info;
+ WMI_AP_MODE_STAT arAPStats;
+ A_UINT8 ap_hidden_ssid;
+ A_UINT8 ap_country_code[3];
+ A_UINT8 ap_wmode;
+ A_UINT8 ap_dtim_period;
+ A_UINT16 ap_beacon_interval;
+ A_UINT16 arRTS;
+ A_UINT16 arACS; /* AP mode - Auto Channel Selection */
+ HTC_PACKET_QUEUE amsdu_rx_buffer_queue;
+ A_BOOL bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */
+ A_TIMER disconnect_timer;
+ A_UINT8 rxMetaVersion;
+#ifdef WAPI_ENABLE
+ A_UINT8 arWapiEnable;
+#endif
+ WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig;
+ WMI_BTCOEX_STATS_EVENT arBtcoexStats;
+ A_INT32 (*exitCallback)(void *config); /* generic callback at AR6K exit */
+ HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
+#ifdef ATH6K_CONFIG_CFG80211
+ struct wireless_dev *wdev;
+ struct cfg80211_scan_request *scan_request;
+ struct ar_key keys[WMI_MAX_KEY_INDEX + 1];
+#endif /* ATH6K_CONFIG_CFG80211 */
+ A_UINT16 arWlanPowerState;
+ A_BOOL arWlanOff;
+#ifdef CONFIG_PM
+ A_UINT16 arWowState;
+ A_BOOL arBTOff;
+ A_BOOL arBTSharing;
+ A_UINT16 arSuspendConfig;
+ A_UINT16 arWlanOffConfig;
+ A_UINT16 arWow2Config;
+#endif
+ A_UINT8 scan_triggered;
+ WMI_SCAN_PARAMS_CMD scParams;
+#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
+ A_UINT8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE];
+ A_UINT8 bdaddr[6];
+ A_BOOL scanSpecificSsid;
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+ void *arApDev;
+#endif
+} AR_SOFTC_T;
+
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+typedef struct {
+ struct net_device *arNetDev; /* net_device pointer */
+ AR_SOFTC_T *arDev; /* ar device pointer */
+ struct net_device *arStaNetDev; /* net_device pointer */
+} AR_VIRTUAL_INTERFACE_T;
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+
+#ifdef ATH6K_CONFIG_CFG80211
+static inline void *ar6k_priv(struct net_device *dev)
+{
+ return (wdev_priv(dev->ieee80211_ptr));
+}
+#else
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+static inline void *ar6k_priv(struct net_device *dev)
+{
+ extern struct net_device *arApNetDev;
+
+ if (arApNetDev == dev) {
+ /* return arDev saved in virtual interface context */
+ AR_VIRTUAL_INTERFACE_T *arVirDev;
+ arVirDev = netdev_priv(dev);
+ return arVirDev->arDev;
+ } else {
+ return netdev_priv(dev);
+ }
+}
+#else
+#define ar6k_priv netdev_priv
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+#endif /* ATH6K_CONFIG_CFG80211 */
+
+#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
+ (pHciDev)->bus = (__bus); \
+ (pHciDev)->dev_type = (__type); \
+} while(0)
+
+#define GET_INODE_FROM_FILEP(filp) \
+ (filp)->f_path.dentry->d_inode
+
+#define arAc2EndpointID(ar,ac) (ar)->arAc2EpMapping[(ac)]
+#define arSetAc2EndpointIDMap(ar,ac,ep) \
+{ (ar)->arAc2EpMapping[(ac)] = (ep); \
+ (ar)->arEp2AcMapping[(ep)] = (ac); }
+#define arEndpoint2Ac(ar,ep) (ar)->arEp2AcMapping[(ep)]
+
+#define arRawIfEnabled(ar) (ar)->arRawIfInit
+#define arRawStream2EndpointID(ar,raw) (ar)->arRawHtc->arRaw2EpMapping[(raw)]
+#define arSetRawStream2EndpointIDMap(ar,raw,ep) \
+{ (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \
+ (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); }
+#define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)]
+
+struct ar_giwscan_param {
+ char *current_ev;
+ char *end_buf;
+ A_UINT32 bytes_needed;
+ struct iw_request_info *info;
+};
+
+#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++)
+
+#define AR6000_SPIN_LOCK(lock, param) do { \
+ if (irqs_disabled()) { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n")); \
+ } \
+ spin_lock_bh(lock); \
+} while (0)
+
+#define AR6000_SPIN_UNLOCK(lock, param) do { \
+ if (irqs_disabled()) { \
+ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n")); \
+ } \
+ spin_unlock_bh(lock); \
+} while (0)
+
+int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+int ar6000_ioctl_dispatcher(struct net_device *dev, struct ifreq *rq, int cmd);
+void ar6000_gpio_init(void);
+void ar6000_init_profile_info(AR_SOFTC_T *ar);
+void ar6000_install_static_wep_keys(AR_SOFTC_T *ar);
+int ar6000_init(struct net_device *dev);
+int ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar);
+void ar6000_TxDataCleanup(AR_SOFTC_T *ar);
+int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev);
+void ar6000_restart_endpoint(struct net_device *dev);
+void ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs);
+
+#ifdef HTC_RAW_INTERFACE
+
+#ifndef __user
+#define __user
+#endif
+
+int ar6000_htc_raw_open(AR_SOFTC_T *ar);
+int ar6000_htc_raw_close(AR_SOFTC_T *ar);
+ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar,
+ HTC_RAW_STREAM_ID StreamID,
+ char __user *buffer, size_t count);
+ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar,
+ HTC_RAW_STREAM_ID StreamID,
+ char __user *buffer, size_t count);
+
+#endif /* HTC_RAW_INTERFACE */
+
+/* AP mode */
+/*TODO: These routines should be moved to a file that is common across OS */
+sta_t *
+ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr);
+
+sta_t *
+ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid);
+
+A_UINT8
+remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason);
+
+/* HCI support */
+
+#ifndef EXPORT_HCI_BRIDGE_INTERFACE
+A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar);
+void ar6000_cleanup_hci(AR_SOFTC_T *ar);
+void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig);
+
+/* HCI bridge testing */
+A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb);
+#endif
+
+ATH_DEBUG_DECLARE_EXTERN(htc);
+ATH_DEBUG_DECLARE_EXTERN(wmi);
+ATH_DEBUG_DECLARE_EXTERN(bmi);
+ATH_DEBUG_DECLARE_EXTERN(hif);
+ATH_DEBUG_DECLARE_EXTERN(wlan);
+ATH_DEBUG_DECLARE_EXTERN(misc);
+
+extern A_UINT8 bcast_mac[];
+extern A_UINT8 null_mac[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AR6000_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
new file mode 100644
index 000000000000..a9a29a624a10
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+// The software source and binaries included in this development package are
+// licensed, not sold. You, or your company, received the package under one
+// or more license agreements. The rights granted to you are specifically
+// listed in these license agreement(s). All other rights remain with Atheros
+// Communications, Inc., its subsidiaries, or the respective owner including
+// those listed on the included copyright notices. Distribution of any
+// portion of this package must be in strict compliance with the license
+// agreement(s) terms.
+// </copyright>
+//
+// <summary>
+// PAL driver for AR6003
+// </summary>
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _AR6K_PAL_H_
+#define _AR6K_PAL_H_
+#define HCI_GET_OP_CODE(p) (((A_UINT16)((p)[1])) << 8) | ((A_UINT16)((p)[0]))
+
+/* transmit packet reserve offset */
+#define TX_PACKET_RSV_OFFSET 32
+/* pal specific config structure */
+typedef A_BOOL (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb);
+typedef struct ar6k_pal_config_s
+{
+ ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt;
+}ar6k_pal_config_t;
+
+void register_pal_cb(ar6k_pal_config_t *palConfig_p);
+#endif /* _AR6K_PAL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
new file mode 100644
index 000000000000..ea2d181dcfe2
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
@@ -0,0 +1,197 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _AR6XAPI_LINUX_H
+#define _AR6XAPI_LINUX_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ar6_softc;
+
+void ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap,
+ A_UINT32 sw_ver, A_UINT32 abi_ver);
+A_STATUS ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid);
+void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel,
+ A_UINT8 *bssid, A_UINT16 listenInterval,
+ A_UINT16 beaconInterval, NETWORK_TYPE networkType,
+ A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
+ A_UINT8 assocRespLen,A_UINT8 *assocInfo);
+void ar6000_disconnect_event(struct ar6_softc *ar, A_UINT8 reason,
+ A_UINT8 *bssid, A_UINT8 assocRespLen,
+ A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus);
+void ar6000_tkip_micerr_event(struct ar6_softc *ar, A_UINT8 keyid,
+ A_BOOL ismcast);
+void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps);
+void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList);
+void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode);
+void ar6000_txPwr_rx(void *devt, A_UINT8 txPwr);
+void ar6000_keepalive_rx(void *devt, A_UINT8 configured);
+void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
+ WMI_NEIGHBOR_INFO *info);
+void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num);
+void ar6000_scanComplete_event(struct ar6_softc *ar, A_STATUS status);
+void ar6000_targetStats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len);
+void ar6000_rssiThreshold_event(struct ar6_softc *ar,
+ WMI_RSSI_THRESHOLD_VAL newThreshold,
+ A_INT16 rssi);
+void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
+void ar6000_cac_event(struct ar6_softc *ar, A_UINT8 ac, A_UINT8 cac_indication,
+ A_UINT8 statusCode, A_UINT8 *tspecSuggestion);
+void ar6000_channel_change_event(struct ar6_softc *ar, A_UINT16 oldChannel, A_UINT16 newChannel);
+void ar6000_hbChallengeResp_event(struct ar6_softc *, A_UINT32 cookie, A_UINT32 source);
+void
+ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
+
+void
+ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p);
+
+void
+ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters,
+ WMI_GET_WOW_LIST_REPLY *wow_reply);
+
+void ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID,
+ WMI_PMKID *pmkidList, A_UINT8 *bssidList);
+
+void ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values);
+void ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value);
+void ar6000_gpio_ack_rx(void);
+
+A_INT32 rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt);
+A_INT16 rssi_compensation_calc(struct ar6_softc *ar, A_INT16 rssi);
+A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, A_BOOL Above);
+
+void ar6000_dbglog_init_done(struct ar6_softc *ar);
+
+#ifdef SEND_EVENT_TO_APP
+void ar6000_send_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, A_UINT8 *datap, int len);
+void ar6000_send_generic_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, A_UINT8 *datap, int len);
+#endif
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+void ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len);
+#endif
+
+void ar6000_tx_retry_err_event(void *devt);
+
+void ar6000_snrThresholdEvent_rx(void *devt,
+ WMI_SNR_THRESHOLD_VAL newThreshold,
+ A_UINT8 snr);
+
+void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, A_UINT8 lqVal);
+
+
+void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask);
+
+A_STATUS ar6000_get_driver_cfg(struct net_device *dev,
+ A_UINT16 cfgParam,
+ void *result);
+void ar6000_bssInfo_event_rx(struct ar6_softc *ar, A_UINT8 *data, int len);
+
+void ar6000_dbglog_event(struct ar6_softc *ar, A_UINT32 dropped,
+ A_INT8 *buffer, A_UINT32 length);
+
+int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar);
+
+void ar6000_peer_event(void *devt, A_UINT8 eventCode, A_UINT8 *bssid);
+
+void ar6000_indicate_tx_activity(void *devt, A_UINT8 trafficClass, A_BOOL Active);
+HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac);
+A_UINT8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep );
+
+void ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len);
+
+void ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) ;
+
+void ar6000_dset_open_req(void *devt,
+ A_UINT32 id,
+ A_UINT32 targ_handle,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg);
+void ar6000_dset_close(void *devt, A_UINT32 access_cookie);
+void ar6000_dset_data_req(void *devt,
+ A_UINT32 access_cookie,
+ A_UINT32 offset,
+ A_UINT32 length,
+ A_UINT32 targ_buf,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg);
+
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+void prof_count_rx(unsigned int addr, unsigned int count);
+#endif
+
+A_UINT32 ar6000_getnodeAge (void);
+
+A_UINT32 ar6000_getclkfreq (void);
+
+int ar6000_ap_mode_profile_commit(struct ar6_softc *ar);
+
+struct ieee80211req_wpaie;
+A_STATUS
+ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie);
+
+A_STATUS is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd);
+
+A_STATUS is_xioctl_allowed(A_UINT8 mode, int cmd);
+
+void ar6000_pspoll_event(struct ar6_softc *ar,A_UINT8 aid);
+
+void ar6000_dtimexpiry_event(struct ar6_softc *ar);
+
+void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd);
+void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd);
+void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd);
+void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd);
+
+#ifdef WAPI_ENABLE
+int ap_set_wapi_key(struct ar6_softc *ar, void *ik);
+void ap_wapi_rekey_event(struct ar6_softc *ar, A_UINT8 type, A_UINT8 *mac);
+#endif
+
+A_STATUS ar6000_connect_to_ap(struct ar6_softc *ar);
+A_STATUS ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL suspending);
+A_STATUS ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state);
+A_STATUS ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state);
+
+#ifdef CONFIG_PM
+A_STATUS ar6000_suspend_ev(void *context);
+A_STATUS ar6000_resume_ev(void *context);
+A_STATUS ar6000_power_change_ev(void *context, A_UINT32 config);
+void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, A_BOOL isEvent);
+#endif
+
+void ar6000_pm_init(void);
+void ar6000_pm_exit(void);
+
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+A_STATUS ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
+A_STATUS ar6000_remove_ap_interface(struct ar6_softc *ar);
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
new file mode 100644
index 000000000000..53bbb4837d30
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
@@ -0,0 +1,1219 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _ATHDRV_LINUX_H
+#define _ATHDRV_LINUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * There are two types of ioctl's here: Standard ioctls and
+ * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed
+ * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The
+ * arguments for every XIOCTL starts with a 32-bit command word
+ * that is used to select which extended ioctl is in use. After
+ * the command word are command-specific arguments.
+ */
+
+/* Linux standard Wireless Extensions, private ioctl interfaces */
+#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
+#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1)
+#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2)
+#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3)
+#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4)
+#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5)
+//#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+6)
+//#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+7)
+//#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+8)
+//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+9)
+//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10)
+#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10)
+
+
+
+/* ====WMI Ioctls==== */
+/*
+ *
+ * Many ioctls simply provide WMI services to application code:
+ * an application makes such an ioctl call with a set of arguments
+ * that are packaged into the corresponding WMI message, and sent
+ * to the Target.
+ */
+
+#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11)
+/*
+ * arguments:
+ * ar6000_version *revision
+ */
+
+#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12)
+/*
+ * arguments:
+ * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
+ * uses: WMI_SET_POWER_MODE_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13)
+/*
+ * arguments:
+ * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
+ * uses: WMI_SET_SCAN_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14)
+/*
+ * arguments:
+ * UINT32 listenInterval
+ * uses: WMI_SET_LISTEN_INT_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15)
+/*
+ * arguments:
+ * WMI_BSS_FILTER filter (see include/wmi.h)
+ * uses: WMI_SET_BSS_FILTER_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16)
+/*
+ * arguments:
+ * WMI_CHANNEL_PARAMS_CMD chParams
+ * uses: WMI_SET_CHANNEL_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17)
+/*
+ * arguments:
+ * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
+ * uses: WMI_SETPROBED_SSID_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18)
+/*
+ * arguments:
+ * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
+ * uses: WMI_SET_POWER_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19)
+/*
+ * arguments:
+ * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
+ * uses: WMI_ADD_BAD_AP_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20)
+/*
+ * arguments:
+ * ar6000_queuereq queueRequest (see below)
+ */
+
+#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21)
+/*
+ * arguments:
+ * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
+ * uses: WMI_CREATE_PSTREAM_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22)
+/*
+ * arguments:
+ * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
+ * uses: WMI_DELETE_PSTREAM_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23)
+/*
+ * arguments:
+ * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
+ * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
+/*
+ * arguments:
+ * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
+ * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25)
+/*
+ * arguments:
+ * TARGET_STATS *targetStats (see below)
+ * uses: WMI_GET_STATISTICS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26)
+/*
+ * arguments:
+ * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
+ * uses: WMI_SET_ASSOC_INFO_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27)
+/*
+ * arguments:
+ * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
+ * uses: WMI_SET_ACCESS_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28)
+/*
+ * arguments:
+ * UINT32 beaconMissTime
+ * uses: WMI_SET_BMISS_TIME_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29)
+/*
+ * arguments:
+ * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
+ * uses: WMI_SET_DISC_TIMEOUT_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30)
+/*
+ * arguments:
+ * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
+ * uses: WMI_SET_IBSS_PM_CAPS_CMDID
+ */
+
+/*
+ * There is a very small space available for driver-private
+ * wireless ioctls. In order to circumvent this limitation,
+ * we multiplex a bunch of ioctls (XIOCTLs) on top of a
+ * single AR6000_IOCTL_EXTENDED ioctl.
+ */
+#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31)
+
+
+/* ====BMI Extended Ioctls==== */
+
+#define AR6000_XIOCTL_BMI_DONE 1
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
+ * uses: BMI_DONE
+ */
+
+#define AR6000_XIOCTL_BMI_READ_MEMORY 2
+/*
+ * arguments:
+ * union {
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
+ * UINT32 address
+ * UINT32 length
+ * }
+ * char results[length]
+ * }
+ * uses: BMI_READ_MEMORY
+ */
+
+#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
+ * UINT32 address
+ * UINT32 length
+ * char data[length]
+ * uses: BMI_WRITE_MEMORY
+ */
+
+#define AR6000_XIOCTL_BMI_EXECUTE 4
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
+ * UINT32 TargetAddress
+ * UINT32 parameter
+ * uses: BMI_EXECUTE
+ */
+
+#define AR6000_XIOCTL_BMI_SET_APP_START 5
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
+ * UINT32 TargetAddress
+ * uses: BMI_SET_APP_START
+ */
+
+#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6
+/*
+ * arguments:
+ * union {
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
+ * UINT32 TargetAddress, 32-bit aligned
+ * }
+ * UINT32 result
+ * }
+ * uses: BMI_READ_SOC_REGISTER
+ */
+
+#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7
+/*
+ * arguments:
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
+ * UINT32 TargetAddress, 32-bit aligned
+ * UINT32 newValue
+ * }
+ * uses: BMI_WRITE_SOC_REGISTER
+ */
+
+#define AR6000_XIOCTL_BMI_TEST 8
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
+ * UINT32 address
+ * UINT32 length
+ * UINT32 count
+ */
+
+
+
+/* Historical Host-side DataSet support */
+#define AR6000_XIOCTL_UNUSED9 9
+#define AR6000_XIOCTL_UNUSED10 10
+#define AR6000_XIOCTL_UNUSED11 11
+
+/* ====Misc Extended Ioctls==== */
+
+#define AR6000_XIOCTL_FORCE_TARGET_RESET 12
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
+ */
+
+
+#ifdef HTC_RAW_INTERFACE
+/* HTC Raw Interface Ioctls */
+#define AR6000_XIOCTL_HTC_RAW_OPEN 13
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_CLOSE 14
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_READ 15
+/*
+ * arguments:
+ * union {
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
+ * UINT32 mailboxID
+ * UINT32 length
+ * }
+ * results[length]
+ * }
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_WRITE 16
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
+ * UINT32 mailboxID
+ * UINT32 length
+ * char buffer[length]
+ */
+#endif /* HTC_RAW_INTERFACE */
+
+#define AR6000_XIOCTL_CHECK_TARGET_READY 17
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
+ */
+
+
+
+/* ====GPIO (General Purpose I/O) Extended Ioctls==== */
+
+#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
+ * ar6000_gpio_output_set_cmd_s (see below)
+ * uses: WMIX_GPIO_OUTPUT_SET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INPUT_GET 19
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
+ * uses: WMIX_GPIO_INPUT_GET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_REGISTER_SET 20
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
+ * ar6000_gpio_register_cmd_s (see below)
+ * uses: WMIX_GPIO_REGISTER_SET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_REGISTER_GET 21
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
+ * ar6000_gpio_register_cmd_s (see below)
+ * uses: WMIX_GPIO_REGISTER_GET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INTR_ACK 22
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
+ * ar6000_cpio_intr_ack_cmd_s (see below)
+ * uses: WMIX_GPIO_INTR_ACK_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INTR_WAIT 23
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
+ */
+
+
+
+/* ====more wireless commands==== */
+
+#define AR6000_XIOCTL_SET_ADHOC_BSSID 24
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
+ * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
+ */
+
+#define AR6000_XIOCTL_SET_OPT_MODE 25
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
+ * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
+ * uses: WMI_SET_OPT_MODE_CMDID
+ */
+
+#define AR6000_XIOCTL_OPT_SEND_FRAME 26
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
+ * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
+ * uses: WMI_OPT_TX_FRAME_CMDID
+ */
+
+#define AR6000_XIOCTL_SET_BEACON_INTVAL 27
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL)
+ * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
+ * uses: WMI_SET_BEACON_INT_CMDID
+ */
+
+
+#define IEEE80211_IOCTL_SETAUTHALG 28
+
+
+#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
+ * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
+ * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
+ */
+
+
+#define AR6000_XIOCTL_SET_MAX_SP 30
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
+ * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
+ * uses: WMI_SET_MAX_SP_LEN_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31
+
+#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32
+
+#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33
+
+
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
+ * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
+ * WMI_SET_POWERSAVE_TIMERS_CMDID
+ */
+
+#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
+ */
+
+#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35
+typedef enum {
+ WLAN_DISABLED,
+ WLAN_ENABLED
+} AR6000_WLAN_STATE;
+/*
+ * arguments:
+ * enable/disable
+ */
+
+#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36
+
+#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37
+/*
+ * arguments:
+ * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd
+ * uses: WMI_SET_RETRY_LIMITS_CMDID
+ */
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+/* ====extended commands for radio test ==== */
+
+#define AR6000_XIOCTL_TCMD_CONT_TX 38
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX)
+ * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h)
+ * uses: WMI_TCMD_CONT_TX_CMDID
+ */
+
+#define AR6000_XIOCTL_TCMD_CONT_RX 39
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX)
+ * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h)
+ * uses: WMI_TCMD_CONT_RX_CMDID
+ */
+
+#define AR6000_XIOCTL_TCMD_PM 40
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_TCMD_PM)
+ * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h)
+ * uses: WMI_TCMD_PM_CMDID
+ */
+
+#endif /* CONFIG_HOST_TCMD_SUPPORT */
+
+#define AR6000_XIOCTL_WMI_STARTSCAN 41
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN)
+ * UINT8 scanType
+ * UINT8 scanConnected
+ * A_BOOL forceFgScan
+ * uses: WMI_START_SCAN_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SETFIXRATES 42
+
+#define AR6000_XIOCTL_WMI_GETFIXRATES 43
+
+
+#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44
+/*
+ * arguments:
+ * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
+ * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45
+/*
+ * arguments:
+ * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h)
+ * uses: WMI_CLR_RSSISNR_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46
+/*
+ * arguments:
+ * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
+ * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SET_RTS 47
+/*
+ * arguments:
+ * WMI_SET_RTS_MODE_CMD (see include/wmi.h)
+ * uses: WMI_SET_RTS_MODE_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48
+
+#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE)
+ * UINT8 mode
+ * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50
+
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM)
+ * UINT8 mode
+ * uses: WMI_SET_WMM_CMDID
+ */
+#define AR6000_XIOCTL_WMI_SET_WMM 51
+
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS)
+ * UINT32 frequency
+ * UINT8 threshold
+ */
+#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52
+
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP)
+ * UINT32 cookie
+ */
+#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53
+
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD)
+ * UINT32 regDomain
+ */
+#define AR6000_XIOCTL_WMI_GET_RD 54
+
+#define AR6000_XIOCTL_DIAG_READ 55
+
+#define AR6000_XIOCTL_DIAG_WRITE 56
+
+/*
+ * arguments cmd (AR6000_XIOCTL_SET_TXOP)
+ * WMI_TXOP_CFG txopEnable
+ */
+#define AR6000_XIOCTL_WMI_SET_TXOP 57
+
+#ifdef USER_KEYS
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
+ * UINT32 keyOpCtrl
+ * uses AR6000_USER_SETKEYS_INFO
+ */
+#define AR6000_XIOCTL_USER_SETKEYS 58
+#endif /* USER_KEYS */
+
+#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59
+/*
+ * arguments:
+ * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE)
+ * UINT8 keepaliveInterval
+ * uses: WMI_SET_KEEPALIVE_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60
+/*
+ * arguments:
+ * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE)
+ * UINT8 keepaliveInterval
+ * A_BOOL configured
+ * uses: WMI_GET_KEEPALIVE_CMDID
+ */
+
+/* ====ROM Patching Extended Ioctls==== */
+
+#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61
+/*
+ * arguments:
+ * union {
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL)
+ * UINT32 ROM Address
+ * UINT32 RAM Address
+ * UINT32 number of bytes
+ * UINT32 activate? (0 or 1)
+ * }
+ * A_UINT32 resulting rompatch ID
+ * }
+ * uses: BMI_ROMPATCH_INSTALL
+ */
+
+#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62
+/*
+ * arguments:
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL)
+ * UINT32 rompatch ID
+ * }
+ * uses: BMI_ROMPATCH_UNINSTALL
+ */
+
+#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63
+/*
+ * arguments:
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE)
+ * UINT32 rompatch count
+ * UINT32 rompatch IDs[rompatch count]
+ * }
+ * uses: BMI_ROMPATCH_ACTIVATE
+ */
+
+#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64
+/*
+ * arguments:
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE)
+ * UINT32 rompatch count
+ * UINT32 rompatch IDs[rompatch count]
+ * }
+ * uses: BMI_ROMPATCH_DEACTIVATE
+ */
+
+#define AR6000_XIOCTL_WMI_SET_APPIE 65
+/*
+ * arguments:
+ * struct {
+ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE)
+ * UINT32 app_frmtype;
+ * UINT32 app_buflen;
+ * UINT8 app_buf[];
+ * }
+ */
+#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66
+/*
+ * arguments:
+ * A_UINT32 filter_type;
+ */
+
+#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67
+
+#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68
+
+#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70
+/*
+ * arguments:
+ * A_UINT32 wsc_status;
+ * (WSC_REG_INACTIVE or WSC_REG_ACTIVE)
+ */
+
+/*
+ * arguments:
+ * struct {
+ * A_UINT8 streamType;
+ * A_UINT8 status;
+ * }
+ * uses: WMI_SET_BT_STATUS_CMDID
+ */
+#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71
+
+/*
+ * arguments:
+ * struct {
+ * A_UINT8 paramType;
+ * union {
+ * A_UINT8 noSCOPkts;
+ * BT_PARAMS_A2DP a2dpParams;
+ * BT_COEX_REGS regs;
+ * };
+ * }
+ * uses: WMI_SET_BT_PARAM_CMDID
+ */
+#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72
+
+#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73
+#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74
+#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75
+#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76
+#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77
+
+
+
+#define AR6000_XIOCTL_TARGET_INFO 78
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO)
+ * A_UINT32 TargetVersion (returned)
+ * A_UINT32 TargetType (returned)
+ * (See also bmi_msg.h target_ver and target_type)
+ */
+
+#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79
+/*
+ * arguments:
+ * none
+ */
+
+#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80
+/*
+ * This ioctl is used to emulate traffic activity
+ * timeouts. Activity/inactivity will trigger the driver
+ * to re-balance credits.
+ *
+ * arguments:
+ * ar6000_traffic_activity_change
+ */
+
+#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81
+/*
+ * This ioctl is used to set the connect control flags
+ *
+ * arguments:
+ * A_UINT32 connectCtrlFlags
+ */
+
+#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82
+/*
+ * This IOCTL sets any Authentication,Key Management and Protection
+ * related parameters. This is used along with the information set in
+ * Connect Command.
+ * Currently this enables Multiple PMKIDs to an AP.
+ *
+ * arguments:
+ * struct {
+ * A_UINT32 akmpInfo;
+ * }
+ * uses: WMI_SET_AKMP_PARAMS_CMD
+ */
+
+#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83
+
+#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84
+/*
+ * This IOCTL is used to set a list of PMKIDs. This list of
+ * PMKIDs is used in the [Re]AssocReq Frame. This list is used
+ * only if the MultiPMKID option is enabled via the
+ * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL.
+ *
+ * arguments:
+ * struct {
+ * A_UINT32 numPMKID;
+ * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE];
+ * }
+ * uses: WMI_SET_PMKIDLIST_CMD
+ */
+
+#define AR6000_XIOCTL_WMI_SET_PARAMS 85
+#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER 86
+#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER 87
+
+
+/* Historical DSETPATCH support for INI patches */
+#define AR6000_XIOCTL_UNUSED90 90
+
+
+/* Support LZ-compressed firmware download */
+#define AR6000_XIOCTL_BMI_LZ_STREAM_START 91
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START)
+ * UINT32 address
+ * uses: BMI_LZ_STREAM_START
+ */
+
+#define AR6000_XIOCTL_BMI_LZ_DATA 92
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA)
+ * UINT32 length
+ * char data[length]
+ * uses: BMI_LZ_DATA
+ */
+
+#define AR6000_XIOCTL_PROF_CFG 93
+/*
+ * arguments:
+ * A_UINT32 period
+ * A_UINT32 nbins
+ */
+
+#define AR6000_XIOCTL_PROF_ADDR_SET 94
+/*
+ * arguments:
+ * A_UINT32 Target address
+ */
+
+#define AR6000_XIOCTL_PROF_START 95
+
+#define AR6000_XIOCTL_PROF_STOP 96
+
+#define AR6000_XIOCTL_PROF_COUNT_GET 97
+
+#define AR6000_XIOCTL_WMI_ABORT_SCAN 98
+
+/*
+ * AP mode
+ */
+#define AR6000_XIOCTL_AP_GET_STA_LIST 99
+
+#define AR6000_XIOCTL_AP_HIDDEN_SSID 100
+
+#define AR6000_XIOCTL_AP_SET_NUM_STA 101
+
+#define AR6000_XIOCTL_AP_SET_ACL_MAC 102
+
+#define AR6000_XIOCTL_AP_GET_ACL_LIST 103
+
+#define AR6000_XIOCTL_AP_COMMIT_CONFIG 104
+
+#define IEEE80211_IOCTL_GETWPAIE 105
+
+#define AR6000_XIOCTL_AP_CONN_INACT_TIME 106
+
+#define AR6000_XIOCTL_AP_PROT_SCAN_TIME 107
+
+#define AR6000_XIOCTL_AP_SET_COUNTRY 108
+
+#define AR6000_XIOCTL_AP_SET_DTIM 109
+
+
+
+
+#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110
+
+#define AR6000_XIOCTL_SET_IP 111
+
+#define AR6000_XIOCTL_AP_SET_ACL_POLICY 112
+
+#define AR6000_XIOCTL_AP_INTRA_BSS_COMM 113
+
+#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114
+
+#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115
+
+#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116
+
+#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117
+
+#define AR6000_XIOCTL_SET_HT_CAP 118
+
+#define AR6000_XIOCTL_SET_HT_OP 119
+
+#define AR6000_XIOCTL_AP_GET_STAT 120
+
+#define AR6000_XIOCTL_SET_TX_SELECT_RATES 121
+
+#define AR6000_XIOCTL_SETUP_AGGR 122
+
+#define AR6000_XIOCTL_ALLOW_AGGR 123
+
+#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124
+
+#define AR6000_XIOCTL_AP_GET_COUNTRY 125
+
+#define AR6000_XIOCTL_AP_GET_WMODE 126
+
+#define AR6000_XIOCTL_AP_GET_DTIM 127
+
+#define AR6000_XIOCTL_AP_GET_BINTVL 128
+
+#define AR6000_XIOCTL_AP_GET_RTS 129
+
+#define AR6000_XIOCTL_DELE_AGGR 130
+
+#define AR6000_XIOCTL_FETCH_TARGET_REGS 131
+
+#define AR6000_XIOCTL_HCI_CMD 132
+
+#define AR6000_XIOCTL_ACL_DATA 133
+
+#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134
+
+#define AR6000_XIOCTL_AP_SET_11BG_RATESET 135
+
+/*
+ * arguments:
+ * WMI_AP_PS_CMD apPsCmd
+ * uses: WMI_AP_PS_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_SET_AP_PS 136
+
+#define AR6000_XIOCTL_WMI_MCAST_FILTER 137
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143
+
+#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144
+
+#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145
+
+#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146
+
+#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS 147
+/*
+ * arguments:
+ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP)
+ * UINT8 mode
+ * uses: WMI_SET_QOS_SUPP_CMDID
+ */
+#define AR6000_XIOCTL_WMI_SET_QOS_SUPP 148
+
+#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149
+
+#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150
+
+#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151
+
+#define AR6000_XIOCTL_ADD_AP_INTERFACE 152
+
+#define AR6000_XIOCTL_REMOVE_AP_INTERFACE 153
+
+#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154
+
+
+/* used by AR6000_IOCTL_WMI_GETREV */
+struct ar6000_version {
+ A_UINT32 host_ver;
+ A_UINT32 target_ver;
+ A_UINT32 wlan_ver;
+ A_UINT32 abi_ver;
+};
+
+/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
+struct ar6000_queuereq {
+ A_UINT8 trafficClass;
+ A_UINT16 activeTsids;
+};
+
+/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
+typedef struct targetStats_t {
+ A_UINT64 tx_packets;
+ A_UINT64 tx_bytes;
+ A_UINT64 tx_unicast_pkts;
+ A_UINT64 tx_unicast_bytes;
+ A_UINT64 tx_multicast_pkts;
+ A_UINT64 tx_multicast_bytes;
+ A_UINT64 tx_broadcast_pkts;
+ A_UINT64 tx_broadcast_bytes;
+ A_UINT64 tx_rts_success_cnt;
+ A_UINT64 tx_packet_per_ac[4];
+
+ A_UINT64 tx_errors;
+ A_UINT64 tx_failed_cnt;
+ A_UINT64 tx_retry_cnt;
+ A_UINT64 tx_mult_retry_cnt;
+ A_UINT64 tx_rts_fail_cnt;
+
+ A_UINT64 rx_packets;
+ A_UINT64 rx_bytes;
+ A_UINT64 rx_unicast_pkts;
+ A_UINT64 rx_unicast_bytes;
+ A_UINT64 rx_multicast_pkts;
+ A_UINT64 rx_multicast_bytes;
+ A_UINT64 rx_broadcast_pkts;
+ A_UINT64 rx_broadcast_bytes;
+ A_UINT64 rx_fragment_pkt;
+
+ A_UINT64 rx_errors;
+ A_UINT64 rx_crcerr;
+ A_UINT64 rx_key_cache_miss;
+ A_UINT64 rx_decrypt_err;
+ A_UINT64 rx_duplicate_frames;
+
+ A_UINT64 tkip_local_mic_failure;
+ A_UINT64 tkip_counter_measures_invoked;
+ A_UINT64 tkip_replays;
+ A_UINT64 tkip_format_errors;
+ A_UINT64 ccmp_format_errors;
+ A_UINT64 ccmp_replays;
+
+ A_UINT64 power_save_failure_cnt;
+
+ A_UINT64 cs_bmiss_cnt;
+ A_UINT64 cs_lowRssi_cnt;
+ A_UINT64 cs_connect_cnt;
+ A_UINT64 cs_disconnect_cnt;
+
+ A_INT32 tx_unicast_rate;
+ A_INT32 rx_unicast_rate;
+
+ A_UINT32 lq_val;
+
+ A_UINT32 wow_num_pkts_dropped;
+ A_UINT16 wow_num_events_discarded;
+
+ A_INT16 noise_floor_calibation;
+ A_INT16 cs_rssi;
+ A_INT16 cs_aveBeacon_rssi;
+ A_UINT8 cs_aveBeacon_snr;
+ A_UINT8 cs_lastRoam_msec;
+ A_UINT8 cs_snr;
+
+ A_UINT8 wow_num_host_pkt_wakeups;
+ A_UINT8 wow_num_host_event_wakeups;
+
+ A_UINT32 arp_received;
+ A_UINT32 arp_matched;
+ A_UINT32 arp_replied;
+}TARGET_STATS;
+
+typedef struct targetStats_cmd_t {
+ TARGET_STATS targetStats;
+ int clearStats;
+} TARGET_STATS_CMD;
+
+/* used by AR6000_XIOCTL_USER_SETKEYS */
+
+/*
+ * Setting this bit to 1 doesnot initialize the RSC on the firmware
+ */
+#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1
+#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002
+
+typedef struct {
+ A_UINT32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */
+} AR6000_USER_SETKEYS_INFO;
+
+
+/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
+struct ar6000_gpio_output_set_cmd_s {
+ A_UINT32 set_mask;
+ A_UINT32 clear_mask;
+ A_UINT32 enable_mask;
+ A_UINT32 disable_mask;
+};
+
+/*
+ * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
+ */
+struct ar6000_gpio_register_cmd_s {
+ A_UINT32 gpioreg_id;
+ A_UINT32 value;
+};
+
+/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
+struct ar6000_gpio_intr_ack_cmd_s {
+ A_UINT32 ack_mask;
+};
+
+/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
+struct ar6000_gpio_intr_wait_cmd_s {
+ A_UINT32 intr_mask;
+ A_UINT32 input_values;
+};
+
+/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */
+typedef struct ar6000_dbglog_module_config_s {
+ A_UINT32 valid;
+ A_UINT16 mmask;
+ A_UINT16 tsr;
+ A_BOOL rep;
+ A_UINT16 size;
+} DBGLOG_MODULE_CONFIG;
+
+typedef struct user_rssi_thold_t {
+ A_INT16 tag;
+ A_INT16 rssi;
+} USER_RSSI_THOLD;
+
+typedef struct user_rssi_params_t {
+ A_UINT8 weight;
+ A_UINT32 pollTime;
+ USER_RSSI_THOLD tholds[12];
+} USER_RSSI_PARAMS;
+
+typedef struct ar6000_get_btcoex_config_cmd_t{
+ A_UINT32 btProfileType;
+ A_UINT32 linkId;
+ }AR6000_GET_BTCOEX_CONFIG_CMD;
+
+typedef struct ar6000_btcoex_config_t {
+ AR6000_GET_BTCOEX_CONFIG_CMD configCmd;
+ A_UINT32 * configEvent;
+} AR6000_BTCOEX_CONFIG;
+
+typedef struct ar6000_btcoex_stats_t {
+ A_UINT32 * statsEvent;
+ }AR6000_BTCOEX_STATS;
+/*
+ * Host driver may have some config parameters. Typically, these
+ * config params are one time config parameters. These could
+ * correspond to any of the underlying modules. Host driver exposes
+ * an api for the underlying modules to get this config.
+ */
+#define AR6000_DRIVER_CFG_BASE 0x8000
+
+/* Should driver perform wlan node caching? */
+#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001
+/*Should we log raw WMI msgs */
+#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002
+
+/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */
+struct ar6000_diag_window_cmd_s {
+ unsigned int addr;
+ unsigned int value;
+};
+
+
+struct ar6000_traffic_activity_change {
+ A_UINT32 StreamID; /* stream ID to indicate activity change */
+ A_UINT32 Active; /* active (1) or inactive (0) */
+};
+
+/* Used with AR6000_XIOCTL_PROF_COUNT_GET */
+struct prof_count_s {
+ A_UINT32 addr; /* bin start address */
+ A_UINT32 count; /* hit count */
+};
+
+
+/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */
+/* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */
+/* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */
+struct drv_debug_module_s {
+ A_CHAR modulename[128]; /* name of module */
+ A_UINT32 mask; /* new mask to set .. or .. current mask */
+};
+
+
+/* All HCI related rx events are sent up to the host app
+ * via a wmi event id. It can contain ACL data or HCI event,
+ * based on which it will be de-multiplexed.
+ */
+typedef enum {
+ PAL_HCI_EVENT = 0,
+ PAL_HCI_RX_DATA,
+} WMI_PAL_EVENT_INFO;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h
diff --git a/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h
diff --git a/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h
new file mode 100644
index 000000000000..9d9ecbb2a4d7
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------
+//
+// This file contains the definitions of the basic atheros data types.
+// It is used to map the data types in atheros files to a platform specific
+// type.
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _ATHTYPES_LINUX_H_
+#define _ATHTYPES_LINUX_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+
+typedef int8_t A_INT8;
+typedef int16_t A_INT16;
+typedef int32_t A_INT32;
+typedef int64_t A_INT64;
+
+typedef u_int8_t A_UINT8;
+typedef u_int16_t A_UINT16;
+typedef u_int32_t A_UINT32;
+typedef u_int64_t A_UINT64;
+
+typedef int A_BOOL;
+typedef char A_CHAR;
+typedef unsigned char A_UCHAR;
+typedef unsigned long A_ATH_TIMER;
+
+
+#endif /* _ATHTYPES_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
new file mode 100644
index 000000000000..b60e8acf4931
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _AR6K_CFG80211_H_
+#define _AR6K_CFG80211_H_
+
+struct wireless_dev *ar6k_cfg80211_init(struct device *dev);
+void ar6k_cfg80211_deinit(AR_SOFTC_T *ar);
+
+void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status);
+
+void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel,
+ A_UINT8 *bssid, A_UINT16 listenInterval,
+ A_UINT16 beaconInterval,NETWORK_TYPE networkType,
+ A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
+ A_UINT8 assocRespLen, A_UINT8 *assocInfo);
+
+void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason,
+ A_UINT8 *bssid, A_UINT8 assocRespLen,
+ A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus);
+
+void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast);
+
+#endif /* _AR6K_CFG80211_H_ */
+
+
+
+
+
+
diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h
new file mode 100644
index 000000000000..50f53d361049
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/config_linux.h
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _CONFIG_LINUX_H_
+#define _CONFIG_LINUX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/version.h>
+
+/*
+ * Host-side GPIO support is optional.
+ * If run-time access to GPIO pins is not required, then
+ * this should be changed to #undef.
+ */
+#define CONFIG_HOST_GPIO_SUPPORT
+
+/*
+ * Host side Test Command support
+ */
+#define CONFIG_HOST_TCMD_SUPPORT
+
+#define USE_4BYTE_REGISTER_ACCESS
+
+/* Host-side support for Target-side profiling */
+#undef CONFIG_TARGET_PROFILE_SUPPORT
+
+/* IP/TCP checksum offload */
+/* Checksum offload is currently not supported for 64 bit platforms */
+#ifndef __LP64__
+#define CONFIG_CHECKSUM_OFFLOAD
+#endif /* __LP64__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
new file mode 100644
index 000000000000..b8dba52badce
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/debug_linux.h
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _DEBUG_LINUX_H_
+#define _DEBUG_LINUX_H_
+
+ /* macro to remove parens */
+#define ATH_PRINTX_ARG(arg...) arg
+
+#ifdef DEBUG
+ /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros
+ * which may be compiler dependent. */
+#define AR_DEBUG_PRINTF(mask, args) do { \
+ if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \
+ A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \
+ } \
+} while (0)
+#else
+ /* on non-debug builds, keep in error and warning messages in the driver, all other
+ * message tracing will get compiled out */
+#define AR_DEBUG_PRINTF(mask, args) \
+ if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); }
+
+#endif
+
+ /* compile specific macro to get the function name string */
+#define _A_FUNCNAME_ __func__
+
+
+#endif /* _DEBUG_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
new file mode 100644
index 000000000000..c1506805a4d5
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h
@@ -0,0 +1,76 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// HCI bridge implementation
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "hci_transport_api.h"
+#include "common_drv.h"
+
+extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo);
+extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans);
+extern A_STATUS (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue);
+extern A_STATUS (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous);
+extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans);
+extern A_STATUS (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans);
+extern A_STATUS (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+extern A_STATUS (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans,
+ HTC_PACKET *pPacket,
+ int MaxPollMS);
+extern A_STATUS (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud);
+extern A_STATUS (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
+
+
+#define HCI_TransportAttach(HTCHandle, pInfo) \
+ _HCI_TransportAttach((HTCHandle), (pInfo))
+#define HCI_TransportDetach(HciTrans) \
+ _HCI_TransportDetach(HciTrans)
+#define HCI_TransportAddReceivePkts(HciTrans, pQueue) \
+ _HCI_TransportAddReceivePkts((HciTrans), (pQueue))
+#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous) \
+ _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous))
+#define HCI_TransportStop(HciTrans) \
+ _HCI_TransportStop((HciTrans))
+#define HCI_TransportStart(HciTrans) \
+ _HCI_TransportStart((HciTrans))
+#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable) \
+ _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable))
+#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS) \
+ _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS))
+#define HCI_TransportSetBaudRate(HciTrans, Baud) \
+ _HCI_TransportSetBaudRate((HciTrans), (Baud))
+#define HCI_TransportEnablePowerMgmt(HciTrans, Enable) \
+ _HCI_TransportEnablePowerMgmt((HciTrans), (Enable))
+
+
+extern A_STATUS ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks);
+
+extern A_STATUS ar6000_get_hif_dev(HIF_DEVICE *device, void *config);
+
+extern A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT32 step);
+
+/* get core clock register settings
+ * data: 0 - 40/44MHz
+ * 1 - 80/88MHz
+ * where (5G band/2.4G band)
+ * assume 2.4G band for now
+ */
+extern A_STATUS ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data);
diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
new file mode 100644
index 000000000000..769a48014313
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h
@@ -0,0 +1,179 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _IEEE80211_IOCTL_H_
+#define _IEEE80211_IOCTL_H_
+
+#include <linux/version.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
+ */
+
+/*
+ * WPA/RSN get/set key request. Specify the key/cipher
+ * type and whether the key is to be used for sending and/or
+ * receiving. The key index should be set only when working
+ * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
+ * Otherwise a unicast/pairwise key is specified by the bssid
+ * (on a station) or mac address (on an ap). They key length
+ * must include any MIC key data; otherwise it should be no
+ more than IEEE80211_KEYBUF_SIZE.
+ */
+struct ieee80211req_key {
+ u_int8_t ik_type; /* key/cipher type */
+ u_int8_t ik_pad;
+ u_int16_t ik_keyix; /* key index */
+ u_int8_t ik_keylen; /* key length in bytes */
+ u_int8_t ik_flags;
+#define IEEE80211_KEY_XMIT 0x01
+#define IEEE80211_KEY_RECV 0x02
+#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
+ u_int8_t ik_macaddr[IEEE80211_ADDR_LEN];
+ u_int64_t ik_keyrsc; /* key receive sequence counter */
+ u_int64_t ik_keytsc; /* key transmit sequence counter */
+ u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
+};
+/*
+ * Delete a key either by index or address. Set the index
+ * to IEEE80211_KEYIX_NONE when deleting a unicast key.
+ */
+struct ieee80211req_del_key {
+ u_int8_t idk_keyix; /* key index */
+ u_int8_t idk_macaddr[IEEE80211_ADDR_LEN];
+};
+/*
+ * MLME state manipulation request. IEEE80211_MLME_ASSOC
+ * only makes sense when operating as a station. The other
+ * requests can be used when operating as a station or an
+ * ap (to effect a station).
+ */
+struct ieee80211req_mlme {
+ u_int8_t im_op; /* operation to perform */
+#define IEEE80211_MLME_ASSOC 1 /* associate station */
+#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */
+#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */
+#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */
+#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */
+ u_int16_t im_reason; /* 802.11 reason code */
+ u_int8_t im_macaddr[IEEE80211_ADDR_LEN];
+};
+
+struct ieee80211req_addpmkid {
+ u_int8_t pi_bssid[IEEE80211_ADDR_LEN];
+ u_int8_t pi_enable;
+ u_int8_t pi_pmkid[16];
+};
+
+#define AUTH_ALG_OPEN_SYSTEM 0x01
+#define AUTH_ALG_SHARED_KEY 0x02
+#define AUTH_ALG_LEAP 0x04
+
+struct ieee80211req_authalg {
+ u_int8_t auth_alg;
+};
+
+/*
+ * Request to add an IE to a Management Frame
+ */
+enum{
+ IEEE80211_APPIE_FRAME_BEACON = 0,
+ IEEE80211_APPIE_FRAME_PROBE_REQ = 1,
+ IEEE80211_APPIE_FRAME_PROBE_RESP = 2,
+ IEEE80211_APPIE_FRAME_ASSOC_REQ = 3,
+ IEEE80211_APPIE_FRAME_ASSOC_RESP = 4,
+ IEEE80211_APPIE_NUM_OF_FRAME = 5
+};
+
+/*
+ * The Maximum length of the IE that can be added to a Management frame
+ */
+#define IEEE80211_APPIE_FRAME_MAX_LEN 200
+
+struct ieee80211req_getset_appiebuf {
+ u_int32_t app_frmtype; /* management frame type for which buffer is added */
+ u_int32_t app_buflen; /*application supplied buffer length */
+ u_int8_t app_buf[];
+};
+
+/*
+ * The following definitions are used by an application to set filter
+ * for receiving management frames
+ */
+enum {
+ IEEE80211_FILTER_TYPE_BEACON = 0x1,
+ IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2,
+ IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4,
+ IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8,
+ IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10,
+ IEEE80211_FILTER_TYPE_AUTH = 0x20,
+ IEEE80211_FILTER_TYPE_DEAUTH = 0x40,
+ IEEE80211_FILTER_TYPE_DISASSOC = 0x80,
+ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */
+};
+
+struct ieee80211req_set_filter {
+ u_int32_t app_filterype; /* management frame filter type */
+};
+
+enum {
+ IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */
+ IEEE80211_PARAM_MCASTCIPHER = 5,
+ IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */
+ IEEE80211_PARAM_UCASTCIPHER = 8,
+ IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */
+ IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */
+ IEEE80211_PARAM_ROAMING = 12, /* roaming mode */
+ IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */
+ IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */
+ IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */
+ IEEE80211_PARAM_WAPI = 16, /* WAPI policy from wapid */
+};
+
+/*
+ * Values for IEEE80211_PARAM_WPA
+ */
+#define WPA_MODE_WPA1 1
+#define WPA_MODE_WPA2 2
+#define WPA_MODE_AUTO 3
+#define WPA_MODE_NONE 4
+
+struct ieee80211req_wpaie {
+ u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN];
+ u_int8_t wpa_ie[IEEE80211_MAX_IE];
+ u_int8_t rsn_ie[IEEE80211_MAX_IE];
+};
+
+#ifndef IW_ENCODE_ALG_PMK
+#define IW_ENCODE_ALG_PMK 4
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IEEE80211_IOCTL_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
new file mode 100644
index 000000000000..ef7cc827cfb4
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
@@ -0,0 +1,387 @@
+//------------------------------------------------------------------------------
+// This file contains the definitions of the basic atheros data types.
+// It is used to map the data types in atheros files to a platform specific
+// type.
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _OSAPI_LINUX_H_
+#define _OSAPI_LINUX_H_
+
+#ifdef __KERNEL__
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+
+#include <linux/cache.h>
+
+#ifdef __GNUC__
+#define __ATTRIB_PACK __attribute__ ((packed))
+#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
+#define __ATTRIB_NORETURN __attribute__ ((noreturn))
+#ifndef INLINE
+#define INLINE __inline__
+#endif
+#else /* Not GCC */
+#define __ATTRIB_PACK
+#define __ATTRIB_PRINTF
+#define __ATTRIB_NORETURN
+#ifndef INLINE
+#define INLINE __inline
+#endif
+#endif /* End __GNUC__ */
+
+#define PREPACK
+#define POSTPACK __ATTRIB_PACK
+
+/*
+ * Endianes macros
+ */
+#define A_BE2CPU8(x) ntohb(x)
+#define A_BE2CPU16(x) ntohs(x)
+#define A_BE2CPU32(x) ntohl(x)
+
+#define A_LE2CPU8(x) (x)
+#define A_LE2CPU16(x) (x)
+#define A_LE2CPU32(x) (x)
+
+#define A_CPU2BE8(x) htonb(x)
+#define A_CPU2BE16(x) htons(x)
+#define A_CPU2BE32(x) htonl(x)
+
+#define A_MEMCPY(dst, src, len) memcpy((A_UINT8 *)(dst), (src), (len))
+#define A_MEMZERO(addr, len) memset(addr, 0, len)
+#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len))
+#define A_MALLOC(size) kmalloc((size), GFP_KERNEL)
+#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC)
+#define A_FREE(addr) kfree(addr)
+
+#if defined(ANDROID_ENV) && defined(CONFIG_ANDROID_LOGGER)
+extern unsigned int enablelogcat;
+extern int android_logger_lv(void* module, int mask);
+enum logidx { LOG_MAIN_IDX = 0 };
+extern int logger_write(const enum logidx idx,
+ const unsigned char prio,
+ const char __kernel * const tag,
+ const char __kernel * const fmt,
+ ...);
+#define A_ANDROID_PRINTF(mask, module, tags, args...) do { \
+ if (enablelogcat) \
+ logger_write(LOG_MAIN_IDX, android_logger_lv(module, mask), tags, args); \
+ else \
+ printk(KERN_ALERT args); \
+} while (0)
+#ifdef DEBUG
+#define A_LOGGER_MODULE_NAME(x) #x
+#define A_LOGGER(mask, mod, args...) \
+ A_ANDROID_PRINTF(mask, &GET_ATH_MODULE_DEBUG_VAR_NAME(mod), "ar6k_" A_LOGGER_MODULE_NAME(mod), args);
+#endif
+#define A_PRINTF(args...) A_ANDROID_PRINTF(ATH_DEBUG_INFO, NULL, "ar6k_driver", args)
+#else
+#define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args)
+#define A_PRINTF(args...) printk(KERN_ALERT args)
+#endif /* ANDROID */
+#define A_PRINTF_LOG(args...) printk(args)
+#define A_SPRINTF(buf, args...) sprintf (buf, args)
+
+/* Mutual Exclusion */
+typedef spinlock_t A_MUTEX_T;
+#define A_MUTEX_INIT(mutex) spin_lock_init(mutex)
+#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex)
+#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex)
+#define A_IS_MUTEX_VALID(mutex) TRUE /* okay to return true, since A_MUTEX_DELETE does nothing */
+#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */
+
+/* Get current time in ms adding a constant offset (in ms) */
+#define A_GET_MS(offset) \
+ (jiffies + ((offset) / 1000) * HZ)
+
+/*
+ * Timer Functions
+ */
+#define A_MDELAY(msecs) mdelay(msecs)
+typedef struct timer_list A_TIMER;
+
+#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \
+ init_timer(pTimer); \
+ (pTimer)->function = (pFunction); \
+ (pTimer)->data = (unsigned long)(pArg); \
+} while (0)
+
+/*
+ * Start a Timer that elapses after 'periodMSec' milli-seconds
+ * Support is provided for a one-shot timer. The 'repeatFlag' is
+ * ignored.
+ */
+#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \
+ if (repeatFlag) { \
+ printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \
+ panic("Timer Repeat"); \
+ } \
+ mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \
+} while (0)
+
+/*
+ * Cancel the Timer.
+ */
+#define A_UNTIMEOUT(pTimer) do { \
+ del_timer((pTimer)); \
+} while (0)
+
+#define A_DELETE_TIMER(pTimer) do { \
+} while (0)
+
+/*
+ * Wait Queue related functions
+ */
+typedef wait_queue_head_t A_WAITQUEUE_HEAD;
+#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head)
+#ifndef wait_event_interruptible_timeout
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ ret = schedule_timeout(ret); \
+ if (!ret) \
+ break; \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ if (!(condition)) \
+ __wait_event_interruptible_timeout(wq, condition, __ret); \
+ __ret; \
+})
+#endif /* wait_event_interruptible_timeout */
+
+#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
+ wait_event_interruptible_timeout(head, condition, timeout); \
+} while (0)
+
+#define A_WAKE_UP(head) wake_up(head)
+
+#ifdef DEBUG
+extern unsigned int panic_on_assert;
+#define A_ASSERT(expr) \
+ if (!(expr)) { \
+ printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \
+ if (panic_on_assert) panic(#expr); \
+ }
+#else
+#define A_ASSERT(expr)
+#endif /* DEBUG */
+
+#ifdef ANDROID_ENV
+struct firmware;
+int android_request_firmware(const struct firmware **firmware_p, const char *filename,
+ struct device *device);
+void android_release_firmware(const struct firmware *firmware);
+#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) android_request_firmware(_ppf, _pfile, _dev)
+#define A_RELEASE_FIRMWARE(_pf) android_release_firmware(_pf)
+#else
+#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev)
+#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
+#endif
+
+/*
+ * Initialization of the network buffer subsystem
+ */
+#define A_NETBUF_INIT()
+
+/*
+ * Network buffer queue support
+ */
+typedef struct sk_buff_head A_NETBUF_QUEUE_T;
+
+#define A_NETBUF_QUEUE_INIT(q) \
+ a_netbuf_queue_init(q)
+
+#define A_NETBUF_ENQUEUE(q, pkt) \
+ a_netbuf_enqueue((q), (pkt))
+#define A_NETBUF_PREQUEUE(q, pkt) \
+ a_netbuf_prequeue((q), (pkt))
+#define A_NETBUF_DEQUEUE(q) \
+ (a_netbuf_dequeue(q))
+#define A_NETBUF_QUEUE_SIZE(q) \
+ a_netbuf_queue_size(q)
+#define A_NETBUF_QUEUE_EMPTY(q) \
+ a_netbuf_queue_empty(q)
+
+/*
+ * Network buffer support
+ */
+#define A_NETBUF_ALLOC(size) \
+ a_netbuf_alloc(size)
+#define A_NETBUF_ALLOC_RAW(size) \
+ a_netbuf_alloc_raw(size)
+#define A_NETBUF_FREE(bufPtr) \
+ a_netbuf_free(bufPtr)
+#define A_NETBUF_DATA(bufPtr) \
+ a_netbuf_to_data(bufPtr)
+#define A_NETBUF_LEN(bufPtr) \
+ a_netbuf_to_len(bufPtr)
+#define A_NETBUF_PUSH(bufPtr, len) \
+ a_netbuf_push(bufPtr, len)
+#define A_NETBUF_PUT(bufPtr, len) \
+ a_netbuf_put(bufPtr, len)
+#define A_NETBUF_TRIM(bufPtr,len) \
+ a_netbuf_trim(bufPtr, len)
+#define A_NETBUF_PULL(bufPtr, len) \
+ a_netbuf_pull(bufPtr, len)
+#define A_NETBUF_HEADROOM(bufPtr)\
+ a_netbuf_headroom(bufPtr)
+#define A_NETBUF_SETLEN(bufPtr,len) \
+ a_netbuf_setlen(bufPtr, len)
+
+/* Add data to end of a buffer */
+#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \
+ a_netbuf_put_data(bufPtr, srcPtr, len)
+
+/* Add data to start of the buffer */
+#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \
+ a_netbuf_push_data(bufPtr, srcPtr, len)
+
+/* Remove data at start of the buffer */
+#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \
+ a_netbuf_pull_data(bufPtr, dstPtr, len)
+
+/* Remove data from the end of the buffer */
+#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \
+ a_netbuf_trim_data(bufPtr, dstPtr, len)
+
+/* View data as "size" contiguous bytes of type "t" */
+#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \
+ (t )( ((struct skbuf *)(bufPtr))->data)
+
+/* return the beginning of the headroom for the buffer */
+#define A_NETBUF_HEAD(bufPtr) \
+ ((((struct sk_buff *)(bufPtr))->head))
+
+/*
+ * OS specific network buffer access routines
+ */
+void *a_netbuf_alloc(int size);
+void *a_netbuf_alloc_raw(int size);
+void a_netbuf_free(void *bufPtr);
+void *a_netbuf_to_data(void *bufPtr);
+A_UINT32 a_netbuf_to_len(void *bufPtr);
+A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len);
+A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len);
+A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len);
+A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len);
+A_STATUS a_netbuf_setlen(void *bufPtr, A_INT32 len);
+A_INT32 a_netbuf_headroom(void *bufPtr);
+void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt);
+void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt);
+void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
+int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q);
+void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q);
+
+/*
+ * Kernel v.s User space functions
+ */
+A_UINT32 a_copy_to_user(void *to, const void *from, A_UINT32 n);
+A_UINT32 a_copy_from_user(void *to, const void *from, A_UINT32 n);
+
+/* In linux, WLAN Rx and Tx run in different contexts, so no need to check
+ * for any commands/data queued for WLAN */
+#define A_CHECK_DRV_TX()
+
+#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES
+
+#define A_CACHE_LINE_PAD 128
+
+static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) {
+ return (void *)L1_CACHE_ALIGN((unsigned long)ptr);
+}
+
+#else /* __KERNEL__ */
+
+#ifdef __GNUC__
+#define __ATTRIB_PACK __attribute__ ((packed))
+#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
+#define __ATTRIB_NORETURN __attribute__ ((noreturn))
+#ifndef INLINE
+#define INLINE __inline__
+#endif
+#else /* Not GCC */
+#define __ATTRIB_PACK
+#define __ATTRIB_PRINTF
+#define __ATTRIB_NORETURN
+#ifndef INLINE
+#define INLINE __inline
+#endif
+#endif /* End __GNUC__ */
+
+#define PREPACK
+#define POSTPACK __ATTRIB_PACK
+
+#define A_MEMCPY(dst, src, len) memcpy((dst), (src), (len))
+#define A_MEMZERO(addr, len) memset((addr), 0, (len))
+#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len))
+#define A_MALLOC(size) malloc(size)
+#define A_FREE(addr) free(addr)
+
+#ifdef ANDROID
+#ifndef err
+#include <errno.h>
+#define err(_s, args...) do { \
+ fprintf(stderr, "%s: line %d ", __FILE__, __LINE__); \
+ fprintf(stderr, args); fprintf(stderr, ": %d\n", errno); \
+ exit(_s); } while (0)
+#endif
+#else
+#include <err.h>
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _OSAPI_LINUX_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
new file mode 100644
index 000000000000..f7d048722226
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h
@@ -0,0 +1,111 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains the tunable configuration items for the WLAN module
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _HOST_WLAN_CONFIG_H_
+#define _HOST_WLAN_CONFIG_H_
+
+/* Include definitions here that can be used to tune the WLAN module behavior.
+ * Different customers can tune the behavior as per their needs, here.
+ */
+
+/* This configuration item when defined will consider the barker preamble
+ * mentioned in the ERP IE of the beacons from the AP to determine the short
+ * preamble support sent in the (Re)Assoc request frames.
+ */
+#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0
+
+/* This config item when defined will not send the power module state transition
+ * failure events that happen during scan, to the host.
+ */
+#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0
+
+/*
+ * This configuration item enable/disable keepalive support.
+ * Keepalive support: In the absence of any data traffic to AP, null
+ * frames will be sent to the AP at periodic interval, to keep the association
+ * active. This configuration item defines the periodic interval.
+ * Use value of zero to disable keepalive support
+ * Default: 60 seconds
+ */
+#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
+
+/*
+ * This configuration item sets the value of disconnect timeout
+ * Firmware delays sending the disconnec event to the host for this
+ * timeout after is gets disconnected from the current AP.
+ * If the firmware successly roams within the disconnect timeout
+ * it sends a new connect event
+ */
+#ifdef ANDROID_ENV
+#define WLAN_CONFIG_DISCONNECT_TIMEOUT 3
+#else
+#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
+#endif /* ANDROID_ENV */
+
+/*
+ * This configuration item disables 11n support.
+ * 0 - Enable
+ * 1 - Disable
+ */
+#define WLAN_CONFIG_DISABLE_11N 0
+
+/*
+ * This configuration item enable BT clock sharing support
+ * 1 - Enable
+ * 0 - Disable (Default)
+ */
+#define WLAN_CONFIG_BT_SHARING 0
+
+/*
+ * This configuration item sets WIFI OFF policy
+ * 0 - CUT_POWER
+ * 1 - DEEP_SLEEP (Default)
+ */
+#define WLAN_CONFIG_WLAN_OFF 1
+
+/*
+ * This configuration item sets suspend policy
+ * 0 - CUT_POWER (Default)
+ * 1 - DEEP_SLEEP
+ * 2 - WoW
+ * 3 - CUT_POWER if BT OFF (clock sharing designs only)
+ */
+#define WLAN_CONFIG_PM_SUSPEND 0
+
+/*
+ * This configuration item sets suspend policy to use if PM_SUSPEND is
+ * set to WoW and device is not connected at the time of suspend
+ * 0 - CUT_POWER (Default)
+ * 1 - DEEP_SLEEP
+ * 2 - WoW
+ * 3 - CUT_POWER if BT OFF (clock sharing designs only)
+ */
+#define WLAN_CONFIG_PM_WOW2 0
+
+/*
+ * Platform specific function to power ON/OFF AR6000
+ * and enable/disable SDIO card detection
+ */
+#define plat_setup_power(on, detect)
+
+#endif /* _HOST_WLAN_CONFIG_H_ */
diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
new file mode 100644
index 000000000000..77e4ec6fea3a
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
@@ -0,0 +1,293 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#ifndef _WMI_FILTER_LINUX_H_
+#define _WMI_FILTER_LINUX_H_
+
+/*
+ * sioctl_filter - Standard ioctl
+ * pioctl_filter - Priv ioctl
+ * xioctl_filter - eXtended ioctl
+ *
+ * ---- Possible values for the WMI filter ---------------
+ * (0) - Block this cmd always (or) not implemented
+ * (INFRA_NETWORK) - Allow this cmd only in STA mode
+ * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode
+ * (AP_NETWORK) - Allow this cmd only in AP mode
+ * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode
+ * (ADHOC_NETWORK | AP_NETWORK) - Block this cmd in STA mode
+ * (INFRA_NETWORK | AP_NETWORK) - Block this cmd in IBSS mode
+ * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set
+ * (0xFF) - Allow this cmd always irrespective of mode
+ */
+
+A_UINT8 sioctl_filter[] = {
+(AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */
+(0xFF), /* SIOCGIWNAME 0x8B01 */
+(0), /* SIOCSIWNWID 0x8B02 */
+(0), /* SIOCGIWNWID 0x8B03 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWFREQ 0x8B04 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWFREQ 0x8B05 */
+(0xFF), /* SIOCSIWMODE 0x8B06 */
+(0xFF), /* SIOCGIWMODE 0x8B07 */
+(0), /* SIOCSIWSENS 0x8B08 */
+(0), /* SIOCGIWSENS 0x8B09 */
+(0), /* SIOCSIWRANGE 0x8B0A */
+(0xFF), /* SIOCGIWRANGE 0x8B0B */
+(0), /* SIOCSIWPRIV 0x8B0C */
+(0), /* SIOCGIWPRIV 0x8B0D */
+(0), /* SIOCSIWSTATS 0x8B0E */
+(0), /* SIOCGIWSTATS 0x8B0F */
+(0), /* SIOCSIWSPY 0x8B10 */
+(0), /* SIOCGIWSPY 0x8B11 */
+(0), /* SIOCSIWTHRSPY 0x8B12 */
+(0), /* SIOCGIWTHRSPY 0x8B13 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWAP 0x8B14 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWAP 0x8B15 */
+#if (WIRELESS_EXT >= 18)
+(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWMLME 0X8B16 */
+#else
+(0), /* Dummy 0 */
+#endif /* WIRELESS_EXT */
+(0), /* SIOCGIWAPLIST 0x8B17 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWSCAN 0x8B18 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWSCAN 0x8B19 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWESSID 0x8B1A */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWESSID 0x8B1B */
+(0), /* SIOCSIWNICKN 0x8B1C */
+(0), /* SIOCGIWNICKN 0x8B1D */
+(0), /* Dummy 0 */
+(0), /* Dummy 0 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWRATE 0x8B20 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWRATE 0x8B21 */
+(0), /* SIOCSIWRTS 0x8B22 */
+(0), /* SIOCGIWRTS 0x8B23 */
+(0), /* SIOCSIWFRAG 0x8B24 */
+(0), /* SIOCGIWFRAG 0x8B25 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWTXPOW 0x8B26 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWTXPOW 0x8B27 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWRETRY 0x8B28 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWRETRY 0x8B29 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWENCODE 0x8B2A */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWENCODE 0x8B2B */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWPOWER 0x8B2C */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWPOWER 0x8B2D */
+};
+
+
+
+A_UINT8 pioctl_filter[] = {
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */
+(AP_NETWORK), /* IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) */
+(INFRA_NETWORK), /* IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) */
+(0), /* IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) */
+(0), /* (SIOCIWFIRSTPRIV+6) */
+(0), /* (SIOCIWFIRSTPRIV+7) */
+(0), /* (SIOCIWFIRSTPRIV+8) */
+(0), /* (SIOCIWFIRSTPRIV+9) */
+(0), /* IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) */
+(0xFF), /* AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) */
+(INFRA_NETWORK), /* AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/
+(0xFF), /* AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) */
+(ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) */
+};
+
+
+
+A_UINT8 xioctl_filter[] = {
+(0xFF), /* Dummy 0 */
+(0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */
+(0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */
+(0xFF), /* AR6000_XIOCTL_BMI_WRITE_MEMORY 3 */
+(0xFF), /* AR6000_XIOCTL_BMI_EXECUTE 4 */
+(0xFF), /* AR6000_XIOCTL_BMI_SET_APP_START 5 */
+(0xFF), /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 */
+(0xFF), /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 */
+(0xFF), /* AR6000_XIOCTL_BMI_TEST 8 */
+(0xFF), /* AR6000_XIOCTL_UNUSED9 9 */
+(0xFF), /* AR6000_XIOCTL_UNUSED10 10 */
+(0xFF), /* AR6000_XIOCTL_UNUSED11 11 */
+(0xFF), /* AR6000_XIOCTL_FORCE_TARGET_RESET 12 */
+(0xFF), /* AR6000_XIOCTL_HTC_RAW_OPEN 13 */
+(0xFF), /* AR6000_XIOCTL_HTC_RAW_CLOSE 14 */
+(0xFF), /* AR6000_XIOCTL_HTC_RAW_READ 15 */
+(0xFF), /* AR6000_XIOCTL_HTC_RAW_WRITE 16 */
+(0xFF), /* AR6000_XIOCTL_CHECK_TARGET_READY 17 */
+(0xFF), /* AR6000_XIOCTL_GPIO_OUTPUT_SET 18 */
+(0xFF), /* AR6000_XIOCTL_GPIO_INPUT_GET 19 */
+(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_SET 20 */
+(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_GET 21 */
+(0xFF), /* AR6000_XIOCTL_GPIO_INTR_ACK 22 */
+(0xFF), /* AR6000_XIOCTL_GPIO_INTR_WAIT 23 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_ADHOC_BSSID 24 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_OPT_MODE 25 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_OPT_SEND_FRAME 26 */
+(ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_SET_BEACON_INTVAL 27 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETAUTHALG 28 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_MAX_SP 30 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 */
+(0xFF), /* AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 */
+(0xFF), /* AR6000_XIOCTL_TCMD_CONT_TX 38 */
+(0xFF), /* AR6000_XIOCTL_TCMD_CONT_RX 39 */
+(0xFF), /* AR6000_XIOCTL_TCMD_PM 40 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_STARTSCAN 41 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SETFIXRATES 42 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GETFIXRATES 43 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_CLR_RSSISNR 45 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_RTS 47 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_AUTHMODE 49 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WMM 51 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 */
+(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GET_RD 54 */
+(0xFF), /* AR6000_XIOCTL_DIAG_READ 55 */
+(0xFF), /* AR6000_XIOCTL_DIAG_WRITE 56 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_TXOP 57 */
+(INFRA_NETWORK), /* AR6000_XIOCTL_USER_SETKEYS 58 */
+(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 */
+(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 */
+(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 */
+(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 */
+(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 */
+(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 */
+(0xFF), /* AR6000_XIOCTL_WMI_SET_APPIE 65 */
+(0xFF), /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 */
+(0xFF), /* AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 */
+(0xFF), /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 */
+(0xFF), /* Dummy 69 */
+(0xFF), /* AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_STATUS 71 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WOW_MODE 74 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_WOW_LIST 75 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 */
+(0xFF), /* AR6000_XIOCTL_TARGET_INFO 78 */
+(0xFF), /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 */
+(0xFF), /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 */
+(0xFF), /* Dummy 85 */
+(0xFF), /* Dummy 86 */
+(0xFF), /* Dummy 87 */
+(0xFF), /* Dummy 88 */
+(0xFF), /* Dummy 89 */
+(0xFF), /* AR6000_XIOCTL_UNUSED90 90 */
+(0xFF), /* AR6000_XIOCTL_BMI_LZ_STREAM_START 91 */
+(0xFF), /* AR6000_XIOCTL_BMI_LZ_DATA 92 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_CFG 93 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_ADDR_SET 94 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_START 95 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_STOP 96 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_COUNT_GET 97 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ABORT_SCAN 98 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STA_LIST 99 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_HIDDEN_SSID 100 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_NUM_STA 101 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_MAC 102 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_ACL_LIST 103 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_COMMIT_CONFIG 104 */
+(AP_NETWORK), /* IEEE80211_IOCTL_GETWPAIE 105 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_CONN_INACT_TIME 106 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 */
+(AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_COUNTRY 108 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_DTIM 109 */
+(0xFF), /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_IP 111 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_POLICY 112 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 */
+(0xFF), /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 */
+(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 */
+(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 */
+(0xFF), /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 */
+(0xFF), /* AR6000_XIOCTL_SET_HT_CAP 118 */
+(0xFF), /* AR6000_XIOCTL_SET_HT_OP 119 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STAT 120 */
+(0xFF), /* AR6000_XIOCTL_SET_TX_SELECT_RATES 121 */
+(0xFF), /* AR6000_XIOCTL_SETUP_AGGR 122 */
+(0xFF), /* AR6000_XIOCTL_ALLOW_AGGR 123 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_COUNTRY 125 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_WMODE 126 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_DTIM 127 */
+(AP_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_AP_GET_BINTVL 128 */
+(0xFF), /* AR6000_XIOCTL_AP_GET_RTS 129 */
+(0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */
+(0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */
+(0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */
+(0xFF), /* AR6000_XIOCTL_ACL_DATA 133 */
+(0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */
+(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */
+(0xFF),
+(0xFF),
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 */
+(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS 147 */
+(0xFF), /* AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 */
+(0xFF), /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 */
+(0xFF), /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 */
+(0xFF), /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 */
+(0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */
+(0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */
+(0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */
+};
+
+#endif /*_WMI_FILTER_LINUX_H_*/
diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c
new file mode 100644
index 000000000000..d5f7ac08ab96
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/ioctl.c
@@ -0,0 +1,4733 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#include "ar6000_drv.h"
+#include "ieee80211_ioctl.h"
+#include "ar6kap_common.h"
+#include "targaddrs.h"
+#include "a_hci.h"
+#include "wlan_config.h"
+
+extern int enablerssicompensation;
+A_UINT32 tcmdRxFreq;
+extern unsigned int wmitimeout;
+extern A_WAITQUEUE_HEAD arEvent;
+extern int tspecCompliance;
+extern int bmienable;
+extern int bypasswmi;
+extern int loghci;
+
+static int
+ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+
+ /* currently assume only roam times are required */
+ if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) {
+ return -EIO;
+ }
+
+
+ return 0;
+}
+
+static int
+ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_ROAM_CTRL_CMD cmd;
+ A_UINT8 size = sizeof(cmd);
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+
+ if (copy_from_user(&cmd, userdata, size)) {
+ return -EFAULT;
+ }
+
+ if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) {
+ if (cmd.info.bssBiasInfo.numBss > 1) {
+ size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS);
+ }
+ }
+
+ if (copy_from_user(&cmd, userdata, size)) {
+ return -EFAULT;
+ }
+
+ if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_POWERSAVE_TIMERS_POLICY_CMD cmd;
+ A_UINT8 size = sizeof(cmd);
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, size)) {
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&cmd, userdata, size)) {
+ return -EFAULT;
+ }
+
+ if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int
+ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_QOS_SUPP_CMD cmd;
+ A_STATUS ret;
+
+ if ((dev->flags & IFF_UP) != IFF_UP) {
+ return -EIO;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
+ sizeof(cmd)))
+ {
+ return -EFAULT;
+ }
+
+ ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int
+ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_WMM_CMD cmd;
+ A_STATUS ret;
+
+ if ((dev->flags & IFF_UP) != IFF_UP) {
+ return -EIO;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
+ sizeof(cmd)))
+ {
+ return -EFAULT;
+ }
+
+ if (cmd.status == WMI_WMM_ENABLED) {
+ ar->arWmmEnabled = TRUE;
+ } else {
+ ar->arWmmEnabled = FALSE;
+ }
+
+ ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int
+ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_WMM_TXOP_CMD cmd;
+ A_STATUS ret;
+
+ if ((dev->flags & IFF_UP) != IFF_UP) {
+ return -EIO;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
+ sizeof(cmd)))
+ {
+ return -EFAULT;
+ }
+
+ ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int
+ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_STATUS ret = 0;
+
+ if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1),
+ &ar->arRegCode, sizeof(ar->arRegCode)))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_AP_SET_COUNTRY_CMD cmd;
+ A_STATUS ret;
+
+ if ((dev->flags & IFF_UP) != IFF_UP) {
+ return -EIO;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
+ sizeof(cmd)))
+ {
+ return -EFAULT;
+ }
+
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+
+ ret = wmi_set_country(ar->arWmi, cmd.countryCode);
+ A_MEMCPY(ar->ap_country_code, cmd.countryCode, 3);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+
+/* Get power mode command */
+static int
+ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_POWER_MODE_CMD power_mode;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi);
+ if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) {
+ ret = -EFAULT;
+ }
+
+ return ret;
+}
+
+
+static int
+ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_CHANNEL_PARAMS_CMD cmd, *cmdp;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if( (ar->arNextMode == AP_NETWORK) && (cmd.numChannels || cmd.scanParam) ) {
+ A_PRINTF("ERROR: Only wmode is allowed in AP mode\n");
+ return -EIO;
+ }
+
+ if (cmd.numChannels > 1) {
+ cmdp = A_MALLOC(130);
+ if (copy_from_user(cmdp, rq->ifr_data,
+ sizeof (*cmdp) +
+ ((cmd.numChannels - 1) * sizeof(A_UINT16))))
+ {
+ kfree(cmdp);
+ return -EFAULT;
+ }
+ } else {
+ cmdp = &cmd;
+ }
+
+ if ((ar->arPhyCapability == WMI_11G_CAPABILITY) &&
+ ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE)))
+ {
+ ret = -EINVAL;
+ }
+
+ if (!ret &&
+ (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode,
+ cmdp->numChannels, cmdp->channelList)
+ != A_OK))
+ {
+ ret = -EIO;
+ }
+
+ if (cmd.numChannels > 1) {
+ kfree(cmdp);
+ }
+
+ ar->ap_wmode = cmdp->phyMode;
+ /* Set the profile change flag to allow a commit cmd */
+ ar->ap_profile_flag = 1;
+
+ return ret;
+}
+
+
+static int
+ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq)
+{
+
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != A_OK ) {
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq)
+{
+#define SWAP_THOLD(thold1, thold2) do { \
+ USER_RSSI_THOLD tmpThold; \
+ tmpThold.tag = thold1.tag; \
+ tmpThold.rssi = thold1.rssi; \
+ thold1.tag = thold2.tag; \
+ thold1.rssi = thold2.rssi; \
+ thold2.tag = tmpThold.tag; \
+ thold2.rssi = tmpThold.rssi; \
+} while (0)
+
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
+ USER_RSSI_PARAMS rssiParams;
+ A_INT32 i, j;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(USER_RSSI_PARAMS))) {
+ return -EFAULT;
+ }
+ cmd.weight = rssiParams.weight;
+ cmd.pollTime = rssiParams.pollTime;
+
+ A_MEMCPY(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map));
+ /*
+ * only 6 elements, so use bubble sorting, in ascending order
+ */
+ for (i = 5; i > 0; i--) {
+ for (j = 0; j < i; j++) { /* above tholds */
+ if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
+ SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
+ } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
+ return EFAULT;
+ }
+ }
+ }
+ for (i = 11; i > 6; i--) {
+ for (j = 6; j < i; j++) { /* below tholds */
+ if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
+ SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
+ } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
+ return EFAULT;
+ }
+ }
+ }
+
+#ifdef DEBUG
+ for (i = 0; i < 12; i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("thold[%d].tag: %d, thold[%d].rssi: %d \n",
+ i, ar->rssi_map[i].tag, i, ar->rssi_map[i].rssi));
+ }
+#endif
+
+ if (enablerssicompensation) {
+ for (i = 0; i < 6; i++)
+ ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, TRUE);
+ for (i = 6; i < 12; i++)
+ ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, FALSE);
+ }
+
+ cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi;
+ cmd.thresholdAbove2_Val = ar->rssi_map[1].rssi;
+ cmd.thresholdAbove3_Val = ar->rssi_map[2].rssi;
+ cmd.thresholdAbove4_Val = ar->rssi_map[3].rssi;
+ cmd.thresholdAbove5_Val = ar->rssi_map[4].rssi;
+ cmd.thresholdAbove6_Val = ar->rssi_map[5].rssi;
+ cmd.thresholdBelow1_Val = ar->rssi_map[6].rssi;
+ cmd.thresholdBelow2_Val = ar->rssi_map[7].rssi;
+ cmd.thresholdBelow3_Val = ar->rssi_map[8].rssi;
+ cmd.thresholdBelow4_Val = ar->rssi_map[9].rssi;
+ cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi;
+ cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi;
+
+ if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != A_OK ) {
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq)
+{
+
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_LQ_THRESHOLD_PARAMS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != A_OK ) {
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+
+static int
+ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_PROBED_SSID_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength,
+ cmd.ssid) != A_OK)
+ {
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_ADD_BAD_AP_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) {
+ return -EIO;
+ }
+
+ if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) {
+ /*
+ * This is a delete badAP.
+ */
+ if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) {
+ ret = -EIO;
+ }
+ } else {
+ if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) {
+ ret = -EIO;
+ }
+ }
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_CREATE_PSTREAM_CMD cmd;
+ A_STATUS ret;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ ret = wmi_verify_tspec_params(&cmd, tspecCompliance);
+ if (ret == A_OK)
+ ret = wmi_create_pstream_cmd(ar->arWmi, &cmd);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int
+ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_DELETE_PSTREAM_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid);
+
+ switch (ret) {
+ case A_OK:
+ return 0;
+ case A_EBUSY :
+ return -EBUSY;
+ case A_NO_MEMORY:
+ return -ENOMEM;
+ case A_EINVAL:
+ default:
+ return -EFAULT;
+ }
+}
+
+static int
+ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct ar6000_queuereq qreq;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if( copy_from_user(&qreq, rq->ifr_data,
+ sizeof(struct ar6000_queuereq)))
+ return -EFAULT;
+
+ qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass);
+
+ if (copy_to_user(rq->ifr_data, &qreq,
+ sizeof(struct ar6000_queuereq)))
+ {
+ ret = -EFAULT;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+static A_STATUS
+ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev,
+ struct ifreq *rq, A_UINT8 *data, A_UINT32 len)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT32 buf[4+TCMD_MAX_RATES];
+ int ret = 0;
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ ar->tcmdRxReport = 0;
+ if (wmi_test_cmd(ar->arWmi, data, len) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ buf[0] = ar->tcmdRxTotalPkt;
+ buf[1] = ar->tcmdRxRssi;
+ buf[2] = ar->tcmdRxcrcErrPkt;
+ buf[3] = ar->tcmdRxsecErrPkt;
+ A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt));
+ A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(A_UINT16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
+
+ if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) {
+ ret = -EFAULT;
+ }
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+void
+ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+ TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results;
+
+ if (enablerssicompensation) {
+ rx_rep->u.report.rssiInDBm = rssi_compensation_calc_tcmd(tcmdRxFreq, rx_rep->u.report.rssiInDBm,rx_rep->u.report.totalPkt);
+ }
+
+
+ ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt;
+ ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm;
+ ar->tcmdRxcrcErrPkt = rx_rep->u.report.crcErrPkt;
+ ar->tcmdRxsecErrPkt = rx_rep->u.report.secErrPkt;
+ ar->tcmdRxReport = 1;
+ A_MEMZERO(ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt));
+ A_MEMZERO(ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
+ A_MEMCPY(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt));
+ A_MEMCPY(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
+
+ wake_up(&arEvent);
+}
+#endif /* CONFIG_HOST_TCMD_SUPPORT*/
+
+static int
+ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_TARGET_ERROR_REPORT_BITMASK cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask);
+
+ return (ret==0 ? ret : -EINVAL);
+}
+
+static int
+ar6000_clear_target_stats(struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ TARGET_STATS *pStats = &ar->arTargetStats;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ A_MEMZERO(pStats, sizeof(TARGET_STATS));
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ return ret;
+}
+
+static int
+ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ TARGET_STATS_CMD cmd;
+ TARGET_STATS *pStats = &ar->arTargetStats;
+ int ret = 0;
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ ar->statsUpdatePending = TRUE;
+
+ if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
+ ret = -EFAULT;
+ }
+
+ if (cmd.clearStats == 1) {
+ ret = ar6000_clear_target_stats(dev);
+ }
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */
+ WMI_AP_MODE_STAT *pStats = &ar->arAPStats;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1),
+ sizeof(A_UINT32)))
+ {
+ return -EFAULT;
+ }
+ if (action == AP_CLEAR_STATS) {
+ A_UINT8 i;
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ for(i = 0; i < AP_MAX_NUM_STA; i++) {
+ pStats->sta[i].tx_bytes = 0;
+ pStats->sta[i].tx_pkts = 0;
+ pStats->sta[i].tx_error = 0;
+ pStats->sta[i].tx_discard = 0;
+ pStats->sta[i].rx_bytes = 0;
+ pStats->sta[i].rx_pkts = 0;
+ pStats->sta[i].rx_error = 0;
+ pStats->sta[i].rx_discard = 0;
+ }
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ return ret;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ ar->statsUpdatePending = TRUE;
+
+ if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
+ ret = -EFAULT;
+ }
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+static int
+ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_ACCESS_PARAMS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_access_params_cmd(ar->arWmi, cmd.ac, cmd.txop, cmd.eCWmin, cmd.eCWmax,
+ cmd.aifsn) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return (ret);
+}
+
+static int
+ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_DISC_TIMEOUT_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return (ret);
+}
+
+static int
+ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_VOICE_PKT_SIZE_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+
+ return (ret);
+}
+
+static int
+ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_MAX_SP_LEN_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return (ret);
+}
+
+
+static int
+ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BT_STATUS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return (ret);
+}
+
+static int
+ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BT_PARAMS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return (ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_FE_ANT_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev,
+ char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_DEBUG_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return(ret);
+}
+
+static int
+ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * userdata)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd;
+ int ret = 0;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ return -EFAULT;
+ }
+
+ if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == A_OK)
+ {
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+ return(ret);
+}
+
+static int
+ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata,
+ struct ifreq *rq)
+{
+
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ AR6000_BTCOEX_CONFIG btcoexConfig;
+ WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig;
+
+ int ret = 0;
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
+ return -EFAULT;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != A_OK)
+ {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ ar->statsUpdatePending = TRUE;
+
+ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret && copy_to_user(btcoexConfig.configEvent, pbtcoexConfigEv, sizeof(WMI_BTCOEX_CONFIG_EVENT))) {
+ ret = -EFAULT;
+ }
+ up(&ar->arSem);
+ return ret;
+}
+
+static int
+ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, struct ifreq *rq)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ AR6000_BTCOEX_STATS btcoexStats;
+ WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats;
+ int ret = 0;
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (copy_from_user(&btcoexStats.statsEvent, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
+ return -EFAULT;
+ }
+
+ if (wmi_get_btcoex_stats_cmd(ar->arWmi) != A_OK)
+ {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ ar->statsUpdatePending = TRUE;
+
+ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret && copy_to_user(btcoexStats.statsEvent, pbtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT))) {
+ ret = -EFAULT;
+ }
+
+
+ up(&ar->arSem);
+
+ return(ret);
+}
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results;
+/* gpio_reg_results and gpio_data_available are protected by arSem */
+static struct ar6000_gpio_register_cmd_s gpio_reg_results;
+static A_BOOL gpio_data_available; /* Requested GPIO data available */
+static A_BOOL gpio_intr_available; /* GPIO interrupt info available */
+static A_BOOL gpio_ack_received; /* GPIO ack was received */
+
+/* Host-side initialization for General Purpose I/O support */
+void ar6000_gpio_init(void)
+{
+ gpio_intr_available = FALSE;
+ gpio_data_available = FALSE;
+ gpio_ack_received = FALSE;
+}
+
+/*
+ * Called when a GPIO interrupt is received from the Target.
+ * intr_values shows which GPIO pins have interrupted.
+ * input_values shows a recent value of GPIO pins.
+ */
+void
+ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values)
+{
+ gpio_intr_results.intr_mask = intr_mask;
+ gpio_intr_results.input_values = input_values;
+ *((volatile A_BOOL *)&gpio_intr_available) = TRUE;
+ wake_up(&arEvent);
+}
+
+/*
+ * This is called when a response is received from the Target
+ * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get
+ * call.
+ */
+void
+ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value)
+{
+ gpio_reg_results.gpioreg_id = reg_id;
+ gpio_reg_results.value = value;
+ *((volatile A_BOOL *)&gpio_data_available) = TRUE;
+ wake_up(&arEvent);
+}
+
+/*
+ * This is called when an acknowledgement is received from the Target
+ * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set
+ * call.
+ */
+void
+ar6000_gpio_ack_rx(void)
+{
+ gpio_ack_received = TRUE;
+ wake_up(&arEvent);
+}
+
+A_STATUS
+ar6000_gpio_output_set(struct net_device *dev,
+ A_UINT32 set_mask,
+ A_UINT32 clear_mask,
+ A_UINT32 enable_mask,
+ A_UINT32 disable_mask)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ gpio_ack_received = FALSE;
+ return wmi_gpio_output_set(ar->arWmi,
+ set_mask, clear_mask, enable_mask, disable_mask);
+}
+
+static A_STATUS
+ar6000_gpio_input_get(struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ *((volatile A_BOOL *)&gpio_data_available) = FALSE;
+ return wmi_gpio_input_get(ar->arWmi);
+}
+
+static A_STATUS
+ar6000_gpio_register_set(struct net_device *dev,
+ A_UINT32 gpioreg_id,
+ A_UINT32 value)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ gpio_ack_received = FALSE;
+ return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value);
+}
+
+static A_STATUS
+ar6000_gpio_register_get(struct net_device *dev,
+ A_UINT32 gpioreg_id)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ *((volatile A_BOOL *)&gpio_data_available) = FALSE;
+ return wmi_gpio_register_get(ar->arWmi, gpioreg_id);
+}
+
+static A_STATUS
+ar6000_gpio_intr_ack(struct net_device *dev,
+ A_UINT32 ack_mask)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ gpio_intr_available = FALSE;
+ return wmi_gpio_intr_ack(ar->arWmi, ack_mask);
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+static struct prof_count_s prof_count_results;
+static A_BOOL prof_count_available; /* Requested GPIO data available */
+
+static A_STATUS
+prof_count_get(struct net_device *dev)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ *((volatile A_BOOL *)&prof_count_available) = FALSE;
+ return wmi_prof_count_get_cmd(ar->arWmi);
+}
+
+/*
+ * This is called when a response is received from the Target
+ * for a previous prof_count_get call.
+ */
+void
+prof_count_rx(A_UINT32 addr, A_UINT32 count)
+{
+ prof_count_results.addr = addr;
+ prof_count_results.count = count;
+ *((volatile A_BOOL *)&prof_count_available) = TRUE;
+ wake_up(&arEvent);
+}
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+
+
+static A_STATUS
+ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p_osbuf)
+{
+ void *osbuf = NULL;
+ A_UINT8 tmp_space[8];
+ HCI_ACL_DATA_PKT *acl;
+ A_UINT8 hdr_size, *datap=NULL;
+ A_STATUS ret = A_OK;
+
+ /* ACL is in data path. There is a need to create pool
+ * mechanism for allocating and freeing NETBUFs - ToDo later.
+ */
+
+ *p_osbuf = NULL;
+ acl = (HCI_ACL_DATA_PKT *)tmp_space;
+ hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len);
+
+ do {
+ if (a_copy_from_user(acl, userdata, hdr_size)) {
+ ret = A_EFAULT;
+ break;
+ }
+
+ osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len);
+ if (osbuf == NULL) {
+ ret = A_NO_MEMORY;
+ break;
+ }
+ A_NETBUF_PUT(osbuf, hdr_size + acl->data_len);
+ datap = (A_UINT8 *)A_NETBUF_DATA(osbuf);
+
+ /* Real copy to osbuf */
+ acl = (HCI_ACL_DATA_PKT *)(datap);
+ A_MEMCPY(acl, tmp_space, hdr_size);
+ if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) {
+ ret = A_EFAULT;
+ break;
+ }
+ } while(FALSE);
+
+ if (ret == A_OK) {
+ *p_osbuf = osbuf;
+ } else {
+ A_NETBUF_FREE(osbuf);
+ }
+ return ret;
+}
+
+
+
+int
+ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value)
+{
+ int ret=0;
+
+ switch(param) {
+ case IEEE80211_PARAM_WPA:
+ switch (value) {
+ case WPA_MODE_WPA1:
+ ar->arAuthMode = WPA_AUTH;
+ break;
+ case WPA_MODE_WPA2:
+ ar->arAuthMode = WPA2_AUTH;
+ break;
+ case WPA_MODE_AUTO:
+ ar->arAuthMode = WPA_AUTH | WPA2_AUTH;
+ break;
+ case WPA_MODE_NONE:
+ ar->arAuthMode = NONE_AUTH;
+ break;
+ }
+ break;
+ case IEEE80211_PARAM_AUTHMODE:
+ if(value == IEEE80211_AUTH_WPA_PSK) {
+ if (WPA_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA_PSK_AUTH;
+ } else if (WPA2_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA2_PSK_AUTH;
+ } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) {
+ ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\
+ "mode when WPA param was set to %d\n",
+ ar->arAuthMode));
+ ret = -EIO;
+ }
+ }
+ break;
+ case IEEE80211_PARAM_UCASTCIPHER:
+ ar->arPairwiseCrypto = 0;
+ if(value & (1<<IEEE80211_CIPHER_AES_CCM)) {
+ ar->arPairwiseCrypto |= AES_CRYPT;
+ }
+ if(value & (1<<IEEE80211_CIPHER_TKIP)) {
+ ar->arPairwiseCrypto |= TKIP_CRYPT;
+ }
+ if(!ar->arPairwiseCrypto) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("Error - Invalid cipher in WPA \n"));
+ ret = -EIO;
+ }
+ break;
+ case IEEE80211_PARAM_PRIVACY:
+ if(value == 0) {
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arAuthMode = NONE_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ }
+ break;
+#ifdef WAPI_ENABLE
+ case IEEE80211_PARAM_WAPI:
+ A_PRINTF("WAPI Policy: %d\n", value);
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arAuthMode = NONE_AUTH;
+ if(value & 0x1) {
+ ar->arPairwiseCrypto = WAPI_CRYPT;
+ ar->arGroupCrypto = WAPI_CRYPT;
+ } else {
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arGroupCrypto = NONE_CRYPT;
+ }
+ break;
+#endif
+ }
+ return ret;
+}
+
+int
+ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value)
+{
+ A_BOOL profChanged = FALSE;
+ int ret=0;
+
+ if(ar->arNextMode == AP_NETWORK) {
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ switch (param) {
+ case IEEE80211_PARAM_WPA:
+ case IEEE80211_PARAM_AUTHMODE:
+ case IEEE80211_PARAM_UCASTCIPHER:
+ case IEEE80211_PARAM_PRIVACY:
+ case IEEE80211_PARAM_WAPI:
+ ret = ar6000_ioctl_ap_setparam(ar, param, value);
+ return ret;
+ }
+ }
+
+ switch (param) {
+ case IEEE80211_PARAM_WPA:
+ switch (value) {
+ case WPA_MODE_WPA1:
+ ar->arAuthMode = WPA_AUTH;
+ profChanged = TRUE;
+ break;
+ case WPA_MODE_WPA2:
+ ar->arAuthMode = WPA2_AUTH;
+ profChanged = TRUE;
+ break;
+ case WPA_MODE_NONE:
+ ar->arAuthMode = NONE_AUTH;
+ profChanged = TRUE;
+ break;
+ }
+ break;
+ case IEEE80211_PARAM_AUTHMODE:
+ switch(value) {
+ case IEEE80211_AUTH_WPA_PSK:
+ if (WPA_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA_PSK_AUTH;
+ profChanged = TRUE;
+ } else if (WPA2_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA2_PSK_AUTH;
+ profChanged = TRUE;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\
+ "mode when WPA param was set to %d\n",
+ ar->arAuthMode));
+ ret = -EIO;
+ }
+ break;
+ case IEEE80211_AUTH_WPA_CCKM:
+ if (WPA2_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA2_AUTH_CCKM;
+ } else {
+ ar->arAuthMode = WPA_AUTH_CCKM;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case IEEE80211_PARAM_UCASTCIPHER:
+ switch (value) {
+ case IEEE80211_CIPHER_AES_CCM:
+ ar->arPairwiseCrypto = AES_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_TKIP:
+ ar->arPairwiseCrypto = TKIP_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_WEP:
+ ar->arPairwiseCrypto = WEP_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_NONE:
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ profChanged = TRUE;
+ break;
+ }
+ break;
+ case IEEE80211_PARAM_UCASTKEYLEN:
+ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
+ ret = -EIO;
+ } else {
+ ar->arPairwiseCryptoLen = value;
+ }
+ break;
+ case IEEE80211_PARAM_MCASTCIPHER:
+ switch (value) {
+ case IEEE80211_CIPHER_AES_CCM:
+ ar->arGroupCrypto = AES_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_TKIP:
+ ar->arGroupCrypto = TKIP_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_WEP:
+ ar->arGroupCrypto = WEP_CRYPT;
+ profChanged = TRUE;
+ break;
+ case IEEE80211_CIPHER_NONE:
+ ar->arGroupCrypto = NONE_CRYPT;
+ profChanged = TRUE;
+ break;
+ }
+ break;
+ case IEEE80211_PARAM_MCASTKEYLEN:
+ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
+ ret = -EIO;
+ } else {
+ ar->arGroupCryptoLen = value;
+ }
+ break;
+ case IEEE80211_PARAM_COUNTERMEASURES:
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
+ break;
+ default:
+ break;
+ }
+ if ((ar->arNextMode != AP_NETWORK) && (profChanged == TRUE)) {
+ /*
+ * profile has changed. Erase ssid to signal change
+ */
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ }
+
+ return ret;
+}
+
+int
+ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik)
+{
+ KEY_USAGE keyUsage;
+ A_STATUS status;
+ CRYPTO_TYPE keyType = NONE_CRYPT;
+
+#ifdef USER_KEYS
+ ar->user_saved_keys.keyOk = FALSE;
+#endif
+ if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) ||
+ (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) {
+ keyUsage = GROUP_USAGE;
+ if(ar->arNextMode == AP_NETWORK) {
+ A_MEMCPY(&ar->ap_mode_bkey, ik,
+ sizeof(struct ieee80211req_key));
+#ifdef WAPI_ENABLE
+ if(ar->arPairwiseCrypto == WAPI_CRYPT) {
+ return ap_set_wapi_key(ar, ik);
+ }
+#endif
+ }
+#ifdef USER_KEYS
+ A_MEMCPY(&ar->user_saved_keys.bcast_ik, ik,
+ sizeof(struct ieee80211req_key));
+#endif
+ } else {
+ keyUsage = PAIRWISE_USAGE;
+#ifdef USER_KEYS
+ A_MEMCPY(&ar->user_saved_keys.ucast_ik, ik,
+ sizeof(struct ieee80211req_key));
+#endif
+#ifdef WAPI_ENABLE
+ if(ar->arNextMode == AP_NETWORK) {
+ if(ar->arPairwiseCrypto == WAPI_CRYPT) {
+ return ap_set_wapi_key(ar, ik);
+ }
+ }
+#endif
+ }
+
+ switch (ik->ik_type) {
+ case IEEE80211_CIPHER_WEP:
+ keyType = WEP_CRYPT;
+ break;
+ case IEEE80211_CIPHER_TKIP:
+ keyType = TKIP_CRYPT;
+ break;
+ case IEEE80211_CIPHER_AES_CCM:
+ keyType = AES_CRYPT;
+ break;
+ default:
+ break;
+ }
+#ifdef USER_KEYS
+ ar->user_saved_keys.keyType = keyType;
+#endif
+ if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
+ if (NONE_CRYPT == keyType) {
+ return -EIO;
+ }
+
+ if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) {
+ int index = ik->ik_keyix;
+
+ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) {
+ return -EIO;
+ }
+
+ A_MEMZERO(ar->arWepKeyList[index].arKey,
+ sizeof(ar->arWepKeyList[index].arKey));
+ A_MEMCPY(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen);
+ ar->arWepKeyList[index].arKeyLen = ik->ik_keylen;
+
+ if(ik->ik_flags & IEEE80211_KEY_DEFAULT){
+ ar->arDefTxKeyIndex = index;
+ }
+
+ return 0;
+ }
+
+ if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
+ (GROUP_USAGE & keyUsage))
+ {
+ A_UNTIMEOUT(&ar->disconnect_timer);
+ }
+
+ status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
+ ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
+ ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
+ SYNC_BOTH_WMIFLAG);
+
+ if (status != A_OK) {
+ return -EIO;
+ }
+ } else {
+ status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
+ }
+
+#ifdef USER_KEYS
+ ar->user_saved_keys.keyOk = TRUE;
+#endif
+
+ return 0;
+}
+
+int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ HIF_DEVICE *hifDevice = ar->arHifDevice;
+ int ret = 0, param;
+ unsigned int address = 0;
+ unsigned int length = 0;
+ unsigned char *buffer;
+ char *userdata;
+ A_UINT32 connectCtrlFlags;
+
+
+ WMI_SET_AKMP_PARAMS_CMD akmpParams;
+ WMI_SET_PMKID_LIST_CMD pmkidInfo;
+
+ WMI_SET_HT_CAP_CMD htCap;
+ WMI_SET_HT_OP_CMD htOp;
+
+ /*
+ * ioctl operations may have to wait for the Target, so we cannot hold rtnl.
+ * Prevent the device from disappearing under us and release the lock during
+ * the ioctl operation.
+ */
+ dev_hold(dev);
+ rtnl_unlock();
+
+ if (cmd == AR6000_IOCTL_EXTENDED) {
+ /*
+ * This allows for many more wireless ioctls than would otherwise
+ * be available. Applications embed the actual ioctl command in
+ * the first word of the parameter block, and use the command
+ * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
+ */
+ if (get_user(cmd, (int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
+ if(is_xioctl_allowed(ar->arNextMode, cmd) != A_OK) {
+ A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd);
+ ret = -EOPNOTSUPP;
+ goto ioctl_done;
+ }
+ } else {
+ A_STATUS ret = is_iwioctl_allowed(ar->arNextMode, cmd);
+ if(ret == A_ENOTSUP) {
+ A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd);
+ ret = -EOPNOTSUPP;
+ goto ioctl_done;
+ } else if (ret == A_ERROR) {
+ /* It is not our ioctl (out of range ioctl) */
+ ret = -EOPNOTSUPP;
+ goto ioctl_done;
+ }
+ userdata = (char *)rq->ifr_data;
+ }
+
+ if ((ar->arWlanState == WLAN_DISABLED) &&
+ ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) &&
+ (cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) &&
+ (cmd != AR6000_XIOCTL_DIAG_READ) &&
+ (cmd != AR6000_XIOCTL_DIAG_WRITE) &&
+ (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) &&
+ (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) &&
+ (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) &&
+ (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) &&
+ (cmd != AR6000_IOCTL_WMI_GETREV)))
+ {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ ret = 0;
+ switch(cmd)
+ {
+ case IEEE80211_IOCTL_SETPARAM:
+ {
+ int param, value;
+ int *ptr = (int *)rq->ifr_ifru.ifru_newname;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else {
+ param = *ptr++;
+ value = *ptr;
+ ret = ar6000_ioctl_setparam(ar,param,value);
+ }
+ break;
+ }
+ case IEEE80211_IOCTL_SETKEY:
+ {
+ struct ieee80211req_key keydata;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&keydata, userdata,
+ sizeof(struct ieee80211req_key))) {
+ ret = -EFAULT;
+ } else {
+ ar6000_ioctl_setkey(ar, &keydata);
+ }
+ break;
+ }
+ case IEEE80211_IOCTL_DELKEY:
+ case IEEE80211_IOCTL_SETOPTIE:
+ {
+ //ret = -EIO;
+ break;
+ }
+ case IEEE80211_IOCTL_SETMLME:
+ {
+ struct ieee80211req_mlme mlme;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&mlme, userdata,
+ sizeof(struct ieee80211req_mlme))) {
+ ret = -EFAULT;
+ } else {
+ switch (mlme.im_op) {
+ case IEEE80211_MLME_AUTHORIZE:
+ A_PRINTF("setmlme AUTHORIZE %02X:%02X\n",
+ mlme.im_macaddr[4], mlme.im_macaddr[5]);
+ break;
+ case IEEE80211_MLME_UNAUTHORIZE:
+ A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n",
+ mlme.im_macaddr[4], mlme.im_macaddr[5]);
+ break;
+ case IEEE80211_MLME_DEAUTH:
+ A_PRINTF("setmlme DEAUTH %02X:%02X\n",
+ mlme.im_macaddr[4], mlme.im_macaddr[5]);
+ //remove_sta(ar, mlme.im_macaddr);
+ break;
+ case IEEE80211_MLME_DISASSOC:
+ A_PRINTF("setmlme DISASSOC %02X:%02X\n",
+ mlme.im_macaddr[4], mlme.im_macaddr[5]);
+ //remove_sta(ar, mlme.im_macaddr);
+ break;
+ default:
+ ret = 0;
+ goto ioctl_done;
+ }
+
+ wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr,
+ mlme.im_reason);
+ }
+ break;
+ }
+ case IEEE80211_IOCTL_ADDPMKID:
+ {
+ struct ieee80211req_addpmkid req;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) {
+ ret = -EFAULT;
+ } else {
+ A_STATUS status;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
+ req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2],
+ req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5],
+ req.pi_enable));
+
+ status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid,
+ req.pi_enable);
+
+ if (status != A_OK) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ }
+ break;
+ }
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ case AR6000_XIOCTL_TCMD_CONT_TX:
+ {
+ TCMD_CONT_TX txCmd;
+
+ if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
+ (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
+ {
+ A_PRINTF("Can NOT send tx tcmd when target is asleep! \n");
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+
+ if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ } else {
+ wmi_test_cmd(ar->arWmi,(A_UINT8 *)&txCmd, sizeof(TCMD_CONT_TX));
+ }
+ }
+ break;
+ case AR6000_XIOCTL_TCMD_CONT_RX:
+ {
+ TCMD_CONT_RX rxCmd;
+
+ if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
+ (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
+ {
+ A_PRINTF("Can NOT send rx tcmd when target is asleep! \n");
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+
+ switch(rxCmd.act)
+ {
+ case TCMD_CONT_RX_PROMIS:
+ case TCMD_CONT_RX_FILTER:
+ case TCMD_CONT_RX_SETMAC:
+ case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE:
+ wmi_test_cmd(ar->arWmi,(A_UINT8 *)&rxCmd,
+ sizeof(TCMD_CONT_RX));
+ tcmdRxFreq = rxCmd.u.para.freq;
+ break;
+ case TCMD_CONT_RX_REPORT:
+ ar6000_ioctl_tcmd_get_rx_report(dev, rq,
+ (A_UINT8 *)&rxCmd, sizeof(TCMD_CONT_RX));
+ break;
+ default:
+ A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act);
+ ret = -EINVAL;
+ goto ioctl_done;
+ }
+ }
+ break;
+ case AR6000_XIOCTL_TCMD_PM:
+ {
+ TCMD_PM pmCmd;
+
+ if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ ar->tcmdPm = pmCmd.mode;
+ wmi_test_cmd(ar->arWmi, (A_UINT8*)&pmCmd, sizeof(TCMD_PM));
+ }
+ break;
+#endif /* CONFIG_HOST_TCMD_SUPPORT */
+
+ case AR6000_XIOCTL_BMI_DONE:
+ if(bmienable)
+ {
+ rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */
+ ret = ar6000_init(dev);
+ rtnl_unlock();
+ }
+ else
+ {
+ ret = BMIDone(hifDevice);
+ }
+ break;
+
+ case AR6000_XIOCTL_BMI_READ_MEMORY:
+ if (get_user(address, (unsigned int *)userdata) ||
+ get_user(length, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n",
+ address, length));
+ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+ A_MEMZERO(buffer, length);
+ ret = BMIReadMemory(hifDevice, address, buffer, length);
+ if (copy_to_user(rq->ifr_data, buffer, length)) {
+ ret = -EFAULT;
+ }
+ A_FREE(buffer);
+ } else {
+ ret = -ENOMEM;
+ }
+ break;
+
+ case AR6000_XIOCTL_BMI_WRITE_MEMORY:
+ if (get_user(address, (unsigned int *)userdata) ||
+ get_user(length, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n",
+ address, length));
+ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+ A_MEMZERO(buffer, length);
+ if (copy_from_user(buffer, &userdata[sizeof(address) +
+ sizeof(length)], length))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = BMIWriteMemory(hifDevice, address, buffer, length);
+ }
+ A_FREE(buffer);
+ } else {
+ ret = -ENOMEM;
+ }
+ break;
+
+ case AR6000_XIOCTL_BMI_TEST:
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n"));
+ ret = -EOPNOTSUPP;
+ break;
+
+ case AR6000_XIOCTL_BMI_EXECUTE:
+ if (get_user(address, (unsigned int *)userdata) ||
+ get_user(param, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n",
+ address, param));
+ ret = BMIExecute(hifDevice, address, (A_UINT32*)&param);
+ /* return value */
+ if (put_user(param, (unsigned int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+
+ case AR6000_XIOCTL_BMI_SET_APP_START:
+ if (get_user(address, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address));
+ ret = BMISetAppStart(hifDevice, address);
+ break;
+
+ case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
+ if (get_user(address, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = BMIReadSOCRegister(hifDevice, address, (A_UINT32*)&param);
+ /* return value */
+ if (put_user(param, (unsigned int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+
+ case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
+ if (get_user(address, (unsigned int *)userdata) ||
+ get_user(param, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = BMIWriteSOCRegister(hifDevice, address, param);
+ break;
+
+#ifdef HTC_RAW_INTERFACE
+ case AR6000_XIOCTL_HTC_RAW_OPEN:
+ ret = A_OK;
+ if (!arRawIfEnabled(ar)) {
+ /* make sure block size is set in case the target was reset since last
+ * BMI phase (i.e. flashup downloads) */
+ ret = ar6000_set_htc_params(ar->arHifDevice,
+ ar->arTargetType,
+ 0, /* use default yield */
+ 0 /* use default number of HTC ctrl buffers */
+ );
+ if (A_FAILED(ret)) {
+ break;
+ }
+ /* Terminate the BMI phase */
+ ret = BMIDone(hifDevice);
+ if (ret == A_OK) {
+ ret = ar6000_htc_raw_open(ar);
+ }
+ }
+ break;
+
+ case AR6000_XIOCTL_HTC_RAW_CLOSE:
+ if (arRawIfEnabled(ar)) {
+ ret = ar6000_htc_raw_close(ar);
+ arRawIfEnabled(ar) = FALSE;
+ } else {
+ ret = A_ERROR;
+ }
+ break;
+
+ case AR6000_XIOCTL_HTC_RAW_READ:
+ if (arRawIfEnabled(ar)) {
+ unsigned int streamID;
+ if (get_user(streamID, (unsigned int *)userdata) ||
+ get_user(length, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ buffer = (unsigned char*)rq->ifr_data + sizeof(length);
+ ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID,
+ (char*)buffer, length);
+ if (put_user(ret, (unsigned int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ break;
+ }
+ } else {
+ ret = A_ERROR;
+ }
+ break;
+
+ case AR6000_XIOCTL_HTC_RAW_WRITE:
+ if (arRawIfEnabled(ar)) {
+ unsigned int streamID;
+ if (get_user(streamID, (unsigned int *)userdata) ||
+ get_user(length, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length);
+ ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID,
+ (char*)buffer, length);
+ if (put_user(ret, (unsigned int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ break;
+ }
+ } else {
+ ret = A_ERROR;
+ }
+ break;
+#endif /* HTC_RAW_INTERFACE */
+
+ case AR6000_XIOCTL_BMI_LZ_STREAM_START:
+ if (get_user(address, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address));
+ ret = BMILZStreamStart(hifDevice, address);
+ break;
+
+ case AR6000_XIOCTL_BMI_LZ_DATA:
+ if (get_user(length, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length));
+ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+ A_MEMZERO(buffer, length);
+ if (copy_from_user(buffer, &userdata[sizeof(length)], length))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = BMILZData(hifDevice, buffer, length);
+ }
+ A_FREE(buffer);
+ } else {
+ ret = -ENOMEM;
+ }
+ break;
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+ /*
+ * Optional support for Target-side profiling.
+ * Not needed in production.
+ */
+
+ /* Configure Target-side profiling */
+ case AR6000_XIOCTL_PROF_CFG:
+ {
+ A_UINT32 period;
+ A_UINT32 nbins;
+ if (get_user(period, (unsigned int *)userdata) ||
+ get_user(nbins, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != A_OK) {
+ ret = -EIO;
+ }
+
+ break;
+ }
+
+ /* Start a profiling bucket/bin at the specified address */
+ case AR6000_XIOCTL_PROF_ADDR_SET:
+ {
+ A_UINT32 addr;
+ if (get_user(addr, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != A_OK) {
+ ret = -EIO;
+ }
+
+ break;
+ }
+
+ /* START Target-side profiling */
+ case AR6000_XIOCTL_PROF_START:
+ wmi_prof_start_cmd(ar->arWmi);
+ break;
+
+ /* STOP Target-side profiling */
+ case AR6000_XIOCTL_PROF_STOP:
+ wmi_prof_stop_cmd(ar->arWmi);
+ break;
+ case AR6000_XIOCTL_PROF_COUNT_GET:
+ {
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ prof_count_available = FALSE;
+ ret = prof_count_get(dev);
+ if (ret != A_OK) {
+ up(&ar->arSem);
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ /* Wait for Target to respond. */
+ wait_event_interruptible(arEvent, prof_count_available);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else {
+ if (copy_to_user(userdata, &prof_count_results,
+ sizeof(prof_count_results)))
+ {
+ ret = -EFAULT;
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+
+ case AR6000_IOCTL_WMI_GETREV:
+ {
+ if (copy_to_user(rq->ifr_data, &ar->arVersion,
+ sizeof(ar->arVersion)))
+ {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SETPWR:
+ {
+ WMI_POWER_MODE_CMD pwrModeCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&pwrModeCmd, userdata,
+ sizeof(pwrModeCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
+ != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
+ {
+ WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&ibssPmCaps, userdata,
+ sizeof(ibssPmCaps)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl,
+ ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK)
+ {
+ ret = -EIO;
+ }
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar->arIbssPsEnable = ibssPmCaps.power_saving;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_AP_PS:
+ {
+ WMI_AP_PS_CMD apPsCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&apPsCmd, userdata,
+ sizeof(apPsCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time,
+ apPsCmd.ps_period, apPsCmd.sleep_period) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_PMPARAMS:
+ {
+ WMI_POWER_PARAMS_CMD pmParams;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&pmParams, userdata,
+ sizeof(pmParams)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
+ pmParams.pspoll_number,
+ pmParams.dtim_policy,
+ pmParams.tx_wakeup_policy,
+ pmParams.num_tx_to_wakeup,
+#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
+ IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
+#else
+ SEND_POWER_SAVE_FAIL_EVENT_ALWAYS
+#endif
+ ) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SETSCAN:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&ar->scParams, userdata,
+ sizeof(ar->scParams)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) {
+ ar->arSkipScan = FALSE;
+ } else {
+ ar->arSkipScan = TRUE;
+ }
+
+ if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period,
+ ar->scParams.fg_end_period,
+ ar->scParams.bg_period,
+ ar->scParams.minact_chdwell_time,
+ ar->scParams.maxact_chdwell_time,
+ ar->scParams.pas_chdwell_time,
+ ar->scParams.shortScanRatio,
+ ar->scParams.scanCtrlFlags,
+ ar->scParams.max_dfsch_act_time,
+ ar->scParams.maxact_scan_per_ssid) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SETLISTENINT:
+ {
+ WMI_LISTEN_INT_CMD listenCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&listenCmd, userdata,
+ sizeof(listenCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) {
+ ret = -EIO;
+ } else {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar->arListenIntervalT = listenCmd.listenInterval;
+ ar->arListenIntervalB = listenCmd.numBeacons;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_BMISS_TIME:
+ {
+ WMI_BMISS_TIME_CMD bmissCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&bmissCmd, userdata,
+ sizeof(bmissCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SETBSSFILTER:
+ {
+ WMI_BSS_FILTER_CMD filt;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&filt, userdata,
+ sizeof(filt)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask)
+ != A_OK) {
+ ret = -EIO;
+ } else {
+ ar->arUserBssFilter = param;
+ }
+ }
+ break;
+ }
+
+ case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD:
+ {
+ ret = ar6000_ioctl_set_snr_threshold(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD:
+ {
+ ret = ar6000_ioctl_set_rssi_threshold(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_CLR_RSSISNR:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ }
+ ret = wmi_clr_rssi_snr(ar->arWmi);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD:
+ {
+ ret = ar6000_ioctl_set_lq_threshold(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_LPREAMBLE:
+ {
+ WMI_SET_LPREAMBLE_CMD setLpreambleCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setLpreambleCmd, userdata,
+ sizeof(setLpreambleCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status,
+#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP
+ WMI_DONOT_IGNORE_BARKER_IN_ERP
+#else
+ WMI_IGNORE_BARKER_IN_ERP
+#endif
+ ) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_RTS:
+ {
+ WMI_SET_RTS_CMD rtsCmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&rtsCmd, userdata,
+ sizeof(rtsCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ ar->arRTS = rtsCmd.threshold;
+ if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold)
+ != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_WMM:
+ {
+ ret = ar6000_ioctl_set_wmm(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_QOS_SUPP:
+ {
+ ret = ar6000_ioctl_set_qos_supp(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_TXOP:
+ {
+ ret = ar6000_ioctl_set_txop(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_GET_RD:
+ {
+ ret = ar6000_ioctl_get_rd(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
+ {
+ ret = ar6000_ioctl_set_channelParams(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_PROBEDSSID:
+ {
+ ret = ar6000_ioctl_set_probedSsid(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_BADAP:
+ {
+ ret = ar6000_ioctl_set_badAp(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_CREATE_QOS:
+ {
+ ret = ar6000_ioctl_create_qos(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_DELETE_QOS:
+ {
+ ret = ar6000_ioctl_delete_qos(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
+ {
+ ret = ar6000_ioctl_get_qos_queue(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_GET_TARGET_STATS:
+ {
+ ret = ar6000_ioctl_get_target_stats(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
+ {
+ ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
+ {
+ WMI_SET_ASSOC_INFO_CMD cmd;
+ A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ break;
+ }
+
+ if (get_user(cmd.ieType, userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
+ ret = -EIO;
+ break;
+ }
+
+ if (get_user(cmd.bufferSize, userdata + 1) ||
+ (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) ||
+ copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) {
+ ret = -EFAULT;
+ break;
+ }
+ if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
+ cmd.bufferSize, assocInfo) != A_OK) {
+ ret = -EIO;
+ break;
+ }
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
+ {
+ ret = ar6000_ioctl_set_access_params(dev, rq);
+ break;
+ }
+ case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
+ {
+ ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_FORCE_TARGET_RESET:
+ {
+ if (ar->arHtcTarget)
+ {
+// HTCForceReset(htcTarget);
+ }
+ else
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt reset.\n"));
+ }
+ break;
+ }
+ case AR6000_XIOCTL_TARGET_INFO:
+ case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */
+ {
+ /* If we made it to here, then the Target exists and is ready. */
+
+ if (cmd == AR6000_XIOCTL_TARGET_INFO) {
+ if (copy_to_user((A_UINT32 *)rq->ifr_data, &ar->arVersion.target_ver,
+ sizeof(ar->arVersion.target_ver)))
+ {
+ ret = -EFAULT;
+ }
+ if (copy_to_user(((A_UINT32 *)rq->ifr_data)+1, &ar->arTargetType,
+ sizeof(ar->arTargetType)))
+ {
+ ret = -EFAULT;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS:
+ {
+ WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam;
+
+ if (copy_from_user(&hbparam, userdata, sizeof(hbparam)))
+ {
+ ret = -EFAULT;
+ } else {
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ /* Start a cyclic timer with the parameters provided. */
+ if (hbparam.frequency) {
+ ar->arHBChallengeResp.frequency = hbparam.frequency;
+ }
+ if (hbparam.threshold) {
+ ar->arHBChallengeResp.missThres = hbparam.threshold;
+ }
+
+ /* Delete the pending timer and start a new one */
+ if (timer_pending(&ar->arHBChallengeResp.timer)) {
+ A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
+ }
+ A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP:
+ {
+ A_UINT32 cookie;
+
+ if (copy_from_user(&cookie, userdata, sizeof(cookie))) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+
+ /* Send the challenge on the control channel */
+ if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != A_OK) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ break;
+ }
+#ifdef USER_KEYS
+ case AR6000_XIOCTL_USER_SETKEYS:
+ {
+
+ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN;
+
+ if (copy_from_user(&ar->user_key_ctrl, userdata,
+ sizeof(ar->user_key_ctrl)))
+ {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+
+ A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl);
+ break;
+ }
+#endif /* USER_KEYS */
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+ case AR6000_XIOCTL_GPIO_OUTPUT_SET:
+ {
+ struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
+
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ if (copy_from_user(&gpio_output_set_cmd, userdata,
+ sizeof(gpio_output_set_cmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = ar6000_gpio_output_set(dev,
+ gpio_output_set_cmd.set_mask,
+ gpio_output_set_cmd.clear_mask,
+ gpio_output_set_cmd.enable_mask,
+ gpio_output_set_cmd.disable_mask);
+ if (ret != A_OK) {
+ ret = EIO;
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+ case AR6000_XIOCTL_GPIO_INPUT_GET:
+ {
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ ret = ar6000_gpio_input_get(dev);
+ if (ret != A_OK) {
+ up(&ar->arSem);
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ /* Wait for Target to respond. */
+ wait_event_interruptible(arEvent, gpio_data_available);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else {
+ A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
+
+ if (copy_to_user(userdata, &gpio_reg_results.value,
+ sizeof(gpio_reg_results.value)))
+ {
+ ret = -EFAULT;
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+ case AR6000_XIOCTL_GPIO_REGISTER_SET:
+ {
+ struct ar6000_gpio_register_cmd_s gpio_register_cmd;
+
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ if (copy_from_user(&gpio_register_cmd, userdata,
+ sizeof(gpio_register_cmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = ar6000_gpio_register_set(dev,
+ gpio_register_cmd.gpioreg_id,
+ gpio_register_cmd.value);
+ if (ret != A_OK) {
+ ret = EIO;
+ }
+
+ /* Wait for acknowledgement from Target */
+ wait_event_interruptible(arEvent, gpio_ack_received);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+ case AR6000_XIOCTL_GPIO_REGISTER_GET:
+ {
+ struct ar6000_gpio_register_cmd_s gpio_register_cmd;
+
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ if (copy_from_user(&gpio_register_cmd, userdata,
+ sizeof(gpio_register_cmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id);
+ if (ret != A_OK) {
+ up(&ar->arSem);
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ /* Wait for Target to respond. */
+ wait_event_interruptible(arEvent, gpio_data_available);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else {
+ A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id);
+ if (copy_to_user(userdata, &gpio_reg_results,
+ sizeof(gpio_reg_results)))
+ {
+ ret = -EFAULT;
+ }
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+ case AR6000_XIOCTL_GPIO_INTR_ACK:
+ {
+ struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
+
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+
+ if (copy_from_user(&gpio_intr_ack_cmd, userdata,
+ sizeof(gpio_intr_ack_cmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
+ if (ret != A_OK) {
+ ret = EIO;
+ }
+ }
+ up(&ar->arSem);
+ break;
+ }
+ case AR6000_XIOCTL_GPIO_INTR_WAIT:
+ {
+ /* Wait for Target to report an interrupt. */
+ wait_event_interruptible(arEvent, gpio_intr_available);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else {
+ if (copy_to_user(userdata, &gpio_intr_results,
+ sizeof(gpio_intr_results)))
+ {
+ ret = -EFAULT;
+ }
+ }
+ break;
+ }
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+ case AR6000_XIOCTL_DBGLOG_CFG_MODULE:
+ {
+ struct ar6000_dbglog_module_config_s config;
+
+ if (copy_from_user(&config, userdata, sizeof(config))) {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+
+ /* Send the challenge on the control channel */
+ if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask,
+ config.tsr, config.rep,
+ config.size, config.valid) != A_OK)
+ {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS:
+ {
+ /* Send the challenge on the control channel */
+ if (ar6000_dbglog_get_debug_logs(ar) != A_OK)
+ {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_SET_ADHOC_BSSID:
+ {
+ WMI_SET_ADHOC_BSSID_CMD adhocBssid;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&adhocBssid, userdata,
+ sizeof(adhocBssid)))
+ {
+ ret = -EFAULT;
+ } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac,
+ AR6000_ETH_ADDR_LEN) == 0)
+ {
+ ret = -EFAULT;
+ } else {
+
+ A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid));
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_SET_OPT_MODE:
+ {
+ WMI_SET_OPT_MODE_CMD optModeCmd;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&optModeCmd, userdata,
+ sizeof(optModeCmd)))
+ {
+ ret = -EFAULT;
+ } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
+ ret = -EFAULT;
+
+ } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
+ != A_OK)
+ {
+ ret = -EIO;
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_OPT_SEND_FRAME:
+ {
+ WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
+ A_UINT8 data[MAX_OPT_DATA_LEN];
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&optTxFrmCmd, userdata,
+ sizeof(optTxFrmCmd)))
+ {
+ ret = -EFAULT;
+ } else if (copy_from_user(data,
+ userdata+sizeof(WMI_OPT_TX_FRAME_CMD)-1,
+ optTxFrmCmd.optIEDataLen))
+ {
+ ret = -EFAULT;
+ } else {
+ ret = wmi_opt_tx_frame_cmd(ar->arWmi,
+ optTxFrmCmd.frmType,
+ optTxFrmCmd.dstAddr,
+ optTxFrmCmd.bssid,
+ optTxFrmCmd.optIEDataLen,
+ data);
+ }
+
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SETRETRYLIMITS:
+ {
+ WMI_SET_RETRY_LIMITS_CMD setRetryParams;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setRetryParams, userdata,
+ sizeof(setRetryParams)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType,
+ setRetryParams.trafficClass,
+ setRetryParams.maxRetries,
+ setRetryParams.enableNotify) != A_OK)
+ {
+ ret = -EIO;
+ }
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar->arMaxRetries = setRetryParams.maxRetries;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_SET_BEACON_INTVAL:
+ {
+ WMI_BEACON_INT_CMD bIntvlCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&bIntvlCmd, userdata,
+ sizeof(bIntvlCmd)))
+ {
+ ret = -EFAULT;
+ } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval)
+ != A_OK)
+ {
+ ret = -EIO;
+ }
+ if(ret == 0) {
+ ar->ap_beacon_interval = bIntvlCmd.beaconInterval;
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ }
+ break;
+ }
+ case IEEE80211_IOCTL_SETAUTHALG:
+ {
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct ieee80211req_authalg req;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&req, userdata,
+ sizeof(struct ieee80211req_authalg)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) {
+ ar->arDot11AuthMode |= OPEN_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arGroupCrypto = NONE_CRYPT;
+ }
+ if (req.auth_alg & AUTH_ALG_SHARED_KEY) {
+ ar->arDot11AuthMode |= SHARED_AUTH;
+ ar->arPairwiseCrypto = WEP_CRYPT;
+ ar->arGroupCrypto = WEP_CRYPT;
+ ar->arAuthMode = NONE_AUTH;
+ }
+ if (req.auth_alg == AUTH_ALG_LEAP) {
+ ar->arDot11AuthMode = LEAP_AUTH;
+ }
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
+ ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_SET_MAX_SP:
+ ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
+ ret = ar6000_ioctl_get_roam_tbl(dev, rq);
+ break;
+ case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
+ ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
+ break;
+ case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
+ ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
+ break;
+ case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
+ ret = ar6000_ioctl_get_power_mode(dev, rq);
+ break;
+ case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
+ {
+ AR6000_WLAN_STATE state;
+ if (get_user(state, (unsigned int *)userdata))
+ ret = -EFAULT;
+ else if (ar6000_set_wlan_state(ar, state) != A_OK)
+ ret = -EIO;
+ break;
+ }
+ case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
+ ret = ar6000_ioctl_get_roam_data(dev, rq);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BT_STATUS:
+ ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BT_PARAMS:
+ ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT:
+ ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV:
+ ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG:
+ ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG:
+ ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG:
+ ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG:
+ ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG:
+ ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS:
+ ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(dev, userdata);
+ break;
+
+ case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG:
+ ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq);
+ break;
+
+ case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS:
+ ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq);
+ break;
+
+ case AR6000_XIOCTL_WMI_STARTSCAN:
+ {
+ WMI_START_SCAN_CMD setStartScanCmd, *cmdp;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setStartScanCmd, userdata,
+ sizeof(setStartScanCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (setStartScanCmd.numChannels > 1) {
+ cmdp = A_MALLOC(130);
+ if (copy_from_user(cmdp, userdata,
+ sizeof (*cmdp) +
+ ((setStartScanCmd.numChannels - 1) *
+ sizeof(A_UINT16))))
+ {
+ kfree(cmdp);
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ } else {
+ cmdp = &setStartScanCmd;
+ }
+
+ if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType,
+ cmdp->forceFgScan,
+ cmdp->isLegacy,
+ cmdp->homeDwellTime,
+ cmdp->forceScanInterval,
+ cmdp->numChannels,
+ cmdp->channelList) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SETFIXRATES:
+ {
+ WMI_FIX_RATES_CMD setFixRatesCmd;
+ A_STATUS returnStatus;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setFixRatesCmd, userdata,
+ sizeof(setFixRatesCmd)))
+ {
+ ret = -EFAULT;
+ } else {
+ returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask);
+ if (returnStatus == A_EINVAL) {
+ ret = -EINVAL;
+ } else if(returnStatus != A_OK) {
+ ret = -EIO;
+ } else {
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ }
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_WMI_GETFIXRATES:
+ {
+ WMI_FIX_RATES_CMD getFixRatesCmd;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ int ret = 0;
+
+ if (ar->bIsDestroyProgress) {
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ /* Used copy_from_user/copy_to_user to access user space data */
+ if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) {
+ ret = -EFAULT;
+ } else {
+ ar->arRateMask = 0xFFFFFFFF;
+
+ if (wmi_get_ratemask_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ ret = -EIO;
+ goto ioctl_done;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFFFFFF, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret) {
+ getFixRatesCmd.fixRateMask = ar->arRateMask;
+ }
+
+ if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) {
+ ret = -EFAULT;
+ }
+
+ up(&ar->arSem);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_AUTHMODE:
+ {
+ WMI_SET_AUTH_MODE_CMD setAuthMode;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setAuthMode, userdata,
+ sizeof(setAuthMode)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_REASSOCMODE:
+ {
+ WMI_SET_REASSOC_MODE_CMD setReassocMode;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setReassocMode, userdata,
+ sizeof(setReassocMode)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_DIAG_READ:
+ {
+ A_UINT32 addr, data;
+ if (get_user(addr, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ addr = TARG_VTOP(ar->arTargetType, addr);
+ if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
+ ret = -EIO;
+ }
+ if (put_user(data, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_DIAG_WRITE:
+ {
+ A_UINT32 addr, data;
+ if (get_user(addr, (unsigned int *)userdata) ||
+ get_user(data, (unsigned int *)userdata + 1)) {
+ ret = -EFAULT;
+ break;
+ }
+ addr = TARG_VTOP(ar->arTargetType, addr);
+ if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
+ ret = -EIO;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_KEEPALIVE:
+ {
+ WMI_SET_KEEPALIVE_CMD setKeepAlive;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&setKeepAlive, userdata,
+ sizeof(setKeepAlive))){
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_PARAMS:
+ {
+ WMI_SET_PARAMS_CMD cmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&cmd, userdata,
+ sizeof(cmd))){
+ ret = -EFAULT;
+ } else if (copy_from_user(&cmd, userdata,
+ sizeof(cmd) + cmd.length))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_MCAST_FILTER:
+ {
+ WMI_SET_MCAST_FILTER_CMD cmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&cmd, userdata,
+ sizeof(cmd))){
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
+ cmd.multicast_mac[1],
+ cmd.multicast_mac[2],
+ cmd.multicast_mac[3]) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER:
+ {
+ WMI_SET_MCAST_FILTER_CMD cmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&cmd, userdata,
+ sizeof(cmd))){
+ ret = -EFAULT;
+ } else {
+ if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
+ cmd.multicast_mac[1],
+ cmd.multicast_mac[2],
+ cmd.multicast_mac[3]) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_MCAST_FILTER:
+ {
+ WMI_MCAST_FILTER_CMD cmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&cmd, userdata,
+ sizeof(cmd))){
+ ret = -EFAULT;
+ } else {
+ if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_GET_KEEPALIVE:
+ {
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_GET_KEEPALIVE_CMD getKeepAlive;
+ int ret = 0;
+ if (ar->bIsDestroyProgress) {
+ ret =-EBUSY;
+ goto ioctl_done;
+ }
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (down_interruptible(&ar->arSem)) {
+ ret = -ERESTARTSYS;
+ goto ioctl_done;
+ }
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ ret = -EBUSY;
+ goto ioctl_done;
+ }
+ if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) {
+ ret = -EFAULT;
+ } else {
+ getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi);
+ ar->arKeepaliveConfigured = 0xFF;
+ if (wmi_get_keepalive_configured(ar->arWmi) != A_OK){
+ up(&ar->arSem);
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+
+ if (!ret) {
+ getKeepAlive.configured = ar->arKeepaliveConfigured;
+ }
+ if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) {
+ ret = -EFAULT;
+ }
+ up(&ar->arSem);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_APPIE:
+ {
+ WMI_SET_APPIE_CMD appIEcmd;
+ A_UINT8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN];
+ A_UINT32 fType,ieLen;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ }
+ if (get_user(fType, (A_UINT32 *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ appIEcmd.mgmtFrmType = fType;
+ if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) {
+ ret = -EIO;
+ } else {
+ if (get_user(ieLen, (A_UINT32 *)(userdata + 4))) {
+ ret = -EFAULT;
+ break;
+ }
+ appIEcmd.ieLen = ieLen;
+ A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen);
+ if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) {
+ ret = -EIO;
+ break;
+ }
+ if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType,
+ appIEcmd.ieLen, appIeInfo) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER:
+ {
+ WMI_BSS_FILTER_CMD cmd;
+ A_UINT32 filterType;
+
+ if (copy_from_user(&filterType, userdata, sizeof(A_UINT32)))
+ {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ if (filterType & (IEEE80211_FILTER_TYPE_BEACON |
+ IEEE80211_FILTER_TYPE_PROBE_RESP))
+ {
+ cmd.bssFilter = ALL_BSS_FILTER;
+ } else {
+ cmd.bssFilter = NONE_BSS_FILTER;
+ }
+ if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != A_OK) {
+ ret = -EIO;
+ } else {
+ ar->arUserBssFilter = cmd.bssFilter;
+ }
+
+ AR6000_SPIN_LOCK(&ar->arLock, 0);
+ ar->arMgmtFilter = filterType;
+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_WSC_STATUS:
+ {
+ A_UINT32 wsc_status;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ goto ioctl_done;
+ } else if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32)))
+ {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != A_OK) {
+ ret = -EIO;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL:
+ {
+ A_UINT32 ROM_addr;
+ A_UINT32 RAM_addr;
+ A_UINT32 nbytes;
+ A_UINT32 do_activate;
+ A_UINT32 rompatch_id;
+
+ if (get_user(ROM_addr, (A_UINT32 *)userdata) ||
+ get_user(RAM_addr, (A_UINT32 *)userdata + 1) ||
+ get_user(nbytes, (A_UINT32 *)userdata + 2) ||
+ get_user(do_activate, (A_UINT32 *)userdata + 3)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x length: %d\n",
+ ROM_addr, RAM_addr, nbytes));
+ ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr,
+ nbytes, do_activate, &rompatch_id);
+ if (ret == A_OK) {
+ /* return value */
+ if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) {
+ ret = -EFAULT;
+ break;
+ }
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL:
+ {
+ A_UINT32 rompatch_id;
+
+ if (get_user(rompatch_id, (A_UINT32 *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id));
+ ret = BMIrompatchUninstall(hifDevice, rompatch_id);
+ break;
+ }
+
+ case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE:
+ case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE:
+ {
+ A_UINT32 rompatch_count;
+
+ if (get_user(rompatch_count, (A_UINT32 *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count));
+ length = sizeof(A_UINT32) * rompatch_count;
+ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+ A_MEMZERO(buffer, length);
+ if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length))
+ {
+ ret = -EFAULT;
+ } else {
+ if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) {
+ ret = BMIrompatchActivate(hifDevice, rompatch_count, (A_UINT32 *)buffer);
+ } else {
+ ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (A_UINT32 *)buffer);
+ }
+ }
+ A_FREE(buffer);
+ } else {
+ ret = -ENOMEM;
+ }
+
+ break;
+ }
+ case AR6000_XIOCTL_SET_IP:
+ {
+ WMI_SET_IP_CMD setIP;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setIP, userdata,
+ sizeof(setIP)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_ip_cmd(ar->arWmi,
+ &setIP) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE:
+ {
+ WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setHostSleepMode, userdata,
+ sizeof(setHostSleepMode)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_host_sleep_mode_cmd(ar->arWmi,
+ &setHostSleepMode) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_SET_WOW_MODE:
+ {
+ WMI_SET_WOW_MODE_CMD setWowMode;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&setWowMode, userdata,
+ sizeof(setWowMode)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_wow_mode_cmd(ar->arWmi,
+ &setWowMode) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_GET_WOW_LIST:
+ {
+ WMI_GET_WOW_LIST_CMD getWowList;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&getWowList, userdata,
+ sizeof(getWowList)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_get_wow_list_cmd(ar->arWmi,
+ &getWowList) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN:
+ {
+#define WOW_PATTERN_SIZE 64
+#define WOW_MASK_SIZE 64
+
+ WMI_ADD_WOW_PATTERN_CMD cmd;
+ A_UINT8 mask_data[WOW_PATTERN_SIZE]={0};
+ A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0};
+
+ do {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ break;
+ }
+ if(copy_from_user(&cmd, userdata,
+ sizeof(WMI_ADD_WOW_PATTERN_CMD)))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ if (copy_from_user(pattern_data,
+ userdata + 3,
+ cmd.filter_size))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ if (copy_from_user(mask_data,
+ (userdata + 3 + cmd.filter_size),
+ cmd.filter_size))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ if (wmi_add_wow_pattern_cmd(ar->arWmi,
+ &cmd, pattern_data, mask_data, cmd.filter_size) != A_OK)
+ {
+ ret = -EIO;
+ }
+ } while(FALSE);
+#undef WOW_PATTERN_SIZE
+#undef WOW_MASK_SIZE
+ break;
+ }
+ case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN:
+ {
+ WMI_DEL_WOW_PATTERN_CMD delWowPattern;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&delWowPattern, userdata,
+ sizeof(delWowPattern)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_del_wow_pattern_cmd(ar->arWmi,
+ &delWowPattern) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE:
+ if (ar->arHtcTarget != NULL) {
+#ifdef ATH_DEBUG_MODULE
+ HTCDumpCreditStates(ar->arHtcTarget);
+#endif /* ATH_DEBUG_MODULE */
+#ifdef HTC_EP_STAT_PROFILING
+ {
+ HTC_ENDPOINT_STATS stats;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ if (HTCGetEndpointStatistics(ar->arHtcTarget,
+ i,
+ HTC_EP_STAT_SAMPLE_AND_CLEAR,
+ &stats)) {
+ A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i);
+ A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications);
+ A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssued);
+ A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropped);
+ A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats.TxPacketsBundled);
+ A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBundles);
+ A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxCreditRpts);
+ A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", stats.TxCreditRptsFromRx);
+ A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther);
+ A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", stats.TxCreditRptsFromEp0);
+ A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats.TxCreditsFromRx);
+ A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", stats.TxCreditsFromOther);
+ A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats.TxCreditsFromEp0);
+ A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", stats.TxCreditsConsummed);
+ A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stats.TxCreditsReturned);
+ A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxReceived);
+ A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats.RxPacketsBundled);
+ A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxLookAheads);
+ A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", stats.RxBundleLookAheads);
+ A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", stats.RxBundleIndFromHdr);
+ A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats.RxAllocThreshHit);
+ A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", stats.RxAllocThreshBytes);
+ A_PRINTF(KERN_ALERT"---- \n");
+
+ }
+ }
+ }
+#endif
+ }
+ break;
+ case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE:
+ if (ar->arHtcTarget != NULL) {
+ struct ar6000_traffic_activity_change data;
+
+ if (copy_from_user(&data, userdata, sizeof(data)))
+ {
+ ret = -EFAULT;
+ goto ioctl_done;
+ }
+ /* note, this is used for testing (mbox ping testing), indicate activity
+ * change using the stream ID as the traffic class */
+ ar6000_indicate_tx_activity(ar,
+ (A_UINT8)data.StreamID,
+ data.Active ? TRUE : FALSE);
+ }
+ break;
+ case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS:
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&connectCtrlFlags, userdata,
+ sizeof(connectCtrlFlags)))
+ {
+ ret = -EFAULT;
+ } else {
+ ar->arConnectCtrlFlags = connectCtrlFlags;
+ }
+ break;
+ case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS:
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&akmpParams, userdata,
+ sizeof(WMI_SET_AKMP_PARAMS_CMD)))
+ {
+ ret = -EFAULT;
+ } else {
+ if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ case AR6000_XIOCTL_WMI_SET_PMKID_LIST:
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else {
+ if (copy_from_user(&pmkidInfo.numPMKID, userdata,
+ sizeof(pmkidInfo.numPMKID)))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ if (copy_from_user(&pmkidInfo.pmkidList,
+ userdata + sizeof(pmkidInfo.numPMKID),
+ pmkidInfo.numPMKID * sizeof(WMI_PMKID)))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ case AR6000_XIOCTL_WMI_GET_PMKID_LIST:
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else {
+ if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ case AR6000_XIOCTL_WMI_ABORT_SCAN:
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ }
+ ret = wmi_abort_scan_cmd(ar->arWmi);
+ break;
+ case AR6000_XIOCTL_AP_HIDDEN_SSID:
+ {
+ A_UINT8 hidden_ssid;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) {
+ ret = -EFAULT;
+ } else {
+ wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid);
+ ar->ap_hidden_ssid = hidden_ssid;
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_STA_LIST:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else {
+ A_UINT8 i;
+ ap_get_sta_t temp;
+ A_MEMZERO(&temp, sizeof(temp));
+ for(i=0;i<AP_MAX_NUM_STA;i++) {
+ A_MEMCPY(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN);
+ temp.sta[i].aid = ar->sta_list[i].aid;
+ temp.sta[i].keymgmt = ar->sta_list[i].keymgmt;
+ temp.sta[i].ucipher = ar->sta_list[i].ucipher;
+ temp.sta[i].auth = ar->sta_list[i].auth;
+ }
+ if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp,
+ sizeof(ar->sta_list))) {
+ ret = -EFAULT;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_NUM_STA:
+ {
+ A_UINT8 num_sta;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) {
+ ret = -EFAULT;
+ } else if(num_sta > AP_MAX_NUM_STA) {
+ /* value out of range */
+ ret = -EINVAL;
+ } else {
+ wmi_ap_set_num_sta(ar->arWmi, num_sta);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_ACL_POLICY:
+ {
+ A_UINT8 policy;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&policy, userdata, sizeof(policy))) {
+ ret = -EFAULT;
+ } else if(policy == ar->g_acl.policy) {
+ /* No change in policy */
+ } else {
+ if(!(policy & AP_ACL_RETAIN_LIST_MASK)) {
+ /* clear ACL list */
+ memset(&ar->g_acl,0,sizeof(WMI_AP_ACL));
+ }
+ ar->g_acl.policy = policy;
+ wmi_ap_set_acl_policy(ar->arWmi, policy);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_ACL_MAC:
+ {
+ WMI_AP_ACL_MAC_CMD acl;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&acl, userdata, sizeof(acl))) {
+ ret = -EFAULT;
+ } else {
+ if(acl_add_del_mac(&ar->g_acl, &acl)) {
+ wmi_ap_acl_mac_list(ar->arWmi, &acl);
+ } else {
+ A_PRINTF("ACL list error\n");
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_ACL_LIST:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl,
+ sizeof(WMI_AP_ACL))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_COMMIT_CONFIG:
+ {
+ ret = ar6000_ap_mode_profile_commit(ar);
+ break;
+ }
+ case IEEE80211_IOCTL_GETWPAIE:
+ {
+ struct ieee80211req_wpaie wpaie;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) {
+ ret = -EFAULT;
+ } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) {
+ ret = -EFAULT;
+ } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_CONN_INACT_TIME:
+ {
+ A_UINT32 period;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&period, userdata, sizeof(period))) {
+ ret = -EFAULT;
+ } else {
+ wmi_ap_conn_inact_time(ar->arWmi, period);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_PROT_SCAN_TIME:
+ {
+ WMI_AP_PROT_SCAN_TIME_CMD bgscan;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) {
+ ret = -EFAULT;
+ } else {
+ wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_COUNTRY:
+ {
+ ret = ar6000_ioctl_set_country(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_DTIM:
+ {
+ WMI_AP_SET_DTIM_CMD d;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&d, userdata, sizeof(d))) {
+ ret = -EFAULT;
+ } else {
+ if(d.dtim > 0 && d.dtim < 11) {
+ ar->ap_dtim_period = d.dtim;
+ wmi_ap_set_dtim(ar->arWmi, d.dtim);
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ } else {
+ A_PRINTF("DTIM out of range. Valid range is [1-10]\n");
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT:
+ {
+ WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ }
+ if (copy_from_user(&evtCfgCmd, userdata,
+ sizeof(evtCfgCmd))) {
+ ret = -EFAULT;
+ break;
+ }
+ ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd);
+ break;
+ }
+ case AR6000_XIOCTL_AP_INTRA_BSS_COMM:
+ {
+ A_UINT8 intra=0;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&intra, userdata, sizeof(intra))) {
+ ret = -EFAULT;
+ } else {
+ ar->intra_bss = (intra?1:0);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO:
+ {
+ struct drv_debug_module_s moduleinfo;
+
+ if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ a_dump_module_debug_info_by_name(moduleinfo.modulename);
+ ret = 0;
+ break;
+ }
+ case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK:
+ {
+ struct drv_debug_module_s moduleinfo;
+
+ if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (A_FAILED(a_set_module_mask(moduleinfo.modulename, moduleinfo.mask))) {
+ ret = -EFAULT;
+ }
+
+ break;
+ }
+ case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK:
+ {
+ struct drv_debug_module_s moduleinfo;
+
+ if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (A_FAILED(a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ break;
+ }
+#ifdef ATH_AR6K_11N_SUPPORT
+ case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS:
+ {
+ PACKET_LOG *copy_of_pkt_log;
+
+ aggr_dump_stats(ar->aggr_cntxt, &copy_of_pkt_log);
+ if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_SETUP_AGGR:
+ {
+ WMI_ADDBA_REQ_CMD cmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ ret = -EFAULT;
+ } else {
+ wmi_setup_aggr_cmd(ar->arWmi, cmd.tid);
+ }
+ }
+ break;
+
+ case AR6000_XIOCTL_DELE_AGGR:
+ {
+ WMI_DELBA_REQ_CMD cmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ ret = -EFAULT;
+ } else {
+ wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator);
+ }
+ }
+ break;
+
+ case AR6000_XIOCTL_ALLOW_AGGR:
+ {
+ WMI_ALLOW_AGGR_CMD cmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ ret = -EFAULT;
+ } else {
+ wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_aggr);
+ }
+ }
+ break;
+
+ case AR6000_XIOCTL_SET_HT_CAP:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&htCap, userdata,
+ sizeof(htCap)))
+ {
+ ret = -EFAULT;
+ } else {
+
+ if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_SET_HT_OP:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&htOp, userdata,
+ sizeof(htOp)))
+ {
+ ret = -EFAULT;
+ } else {
+
+ if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+#endif
+ case AR6000_XIOCTL_ACL_DATA:
+ {
+ void *osbuf = NULL;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (ar6000_create_acl_data_osbuf(dev, (A_UINT8*)userdata, &osbuf) != A_OK) {
+ ret = -EIO;
+ } else {
+ if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"));
+ } else {
+ /* Send data buffer over HTC */
+ ar6000_acl_data_tx(osbuf, ar->arNetDev);
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_HCI_CMD:
+ {
+ char tmp_buf[512];
+ A_INT8 i;
+ WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf;
+ A_UINT8 size;
+
+ size = sizeof(cmd->cmd_buf_sz);
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(cmd, userdata, size)) {
+ ret = -EFAULT;
+ } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) {
+ ret = -EFAULT;
+ } else {
+ if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != A_OK) {
+ ret = -EIO;
+ }else if(loghci) {
+ A_PRINTF_LOG("HCI Command To PAL --> \n");
+ for(i = 0; i < cmd->cmd_buf_sz; i++) {
+ A_PRINTF_LOG("0x%02x ",cmd->buf[i]);
+ if((i % 10) == 0) {
+ A_PRINTF_LOG("\n");
+ }
+ }
+ A_PRINTF_LOG("\n");
+ A_PRINTF_LOG("==================================\n");
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE:
+ {
+ WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+ ret = -EFAULT;
+ } else {
+ if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN ||
+ cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) {
+ if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != A_OK) {
+ ret = -EIO;
+ }
+ } else {
+ ret = -EINVAL;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_STAT:
+ {
+ ret = ar6000_ioctl_get_ap_stats(dev, rq);
+ break;
+ }
+ case AR6000_XIOCTL_SET_TX_SELECT_RATES:
+ {
+ WMI_SET_TX_SELECT_RATES_CMD masks;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&masks, userdata,
+ sizeof(masks)))
+ {
+ ret = -EFAULT;
+ } else {
+
+ if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != A_OK)
+ {
+ ret = -EIO;
+ }
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_HIDDEN_SSID:
+ {
+ WMI_AP_HIDDEN_SSID_CMD ssid;
+ ssid.hidden_ssid = ar->ap_hidden_ssid;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data,
+ &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_COUNTRY:
+ {
+ WMI_AP_SET_COUNTRY_CMD cty;
+ A_MEMCPY(cty.countryCode, ar->ap_country_code, 3);
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data,
+ &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_WMODE:
+ {
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((A_UINT8 *)rq->ifr_data,
+ &ar->ap_wmode, sizeof(A_UINT8))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_DTIM:
+ {
+ WMI_AP_SET_DTIM_CMD dtim;
+ dtim.dtim = ar->ap_dtim_period;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data,
+ &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_BINTVL:
+ {
+ WMI_BEACON_INT_CMD bi;
+ bi.beaconInterval = ar->ap_beacon_interval;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data,
+ &bi, sizeof(WMI_BEACON_INT_CMD))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_GET_RTS:
+ {
+ WMI_SET_RTS_CMD rts;
+ rts.threshold = ar->arRTS;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data,
+ &rts, sizeof(WMI_SET_RTS_CMD))) {
+ ret = -EFAULT;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_FETCH_TARGET_REGS:
+ {
+ A_UINT32 targregs[AR6003_FETCH_TARG_REGS_COUNT];
+
+ if (ar->arTargetType == TARGET_TYPE_AR6003) {
+ ar6k_FetchTargetRegs(hifDevice, targregs);
+ if (copy_to_user((A_UINT32 *)rq->ifr_data, &targregs, sizeof(targregs)))
+ {
+ ret = -EFAULT;
+ }
+ } else {
+ ret = -EOPNOTSUPP;
+ }
+ break;
+ }
+ case AR6000_XIOCTL_AP_SET_11BG_RATESET:
+ {
+ WMI_AP_SET_11BG_RATESET_CMD rate;
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&rate, userdata, sizeof(rate))) {
+ ret = -EFAULT;
+ } else {
+ wmi_ap_set_rateset(ar->arWmi, rate.rateset);
+ }
+ break;
+ }
+ case AR6000_XIOCTL_GET_WLAN_SLEEP_STATE:
+ {
+ WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent ;
+
+ if (ar->arWlanState == WLAN_ENABLED) {
+ wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
+ } else {
+ wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
+ }
+ rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */
+
+ ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent,
+ sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
+ break;
+ }
+#ifdef CONFIG_PM
+ case AR6000_XIOCTL_SET_BT_HW_POWER_STATE:
+ {
+ unsigned int state;
+ if (get_user(state, (unsigned int *)userdata)) {
+ ret = -EFAULT;
+ break;
+ }
+ if (ar6000_set_bt_hw_state(ar, state)!=A_OK) {
+ ret = -EIO;
+ }
+ }
+ break;
+ case AR6000_XIOCTL_GET_BT_HW_POWER_STATE:
+ rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */
+ break;
+#endif
+
+ case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM:
+ {
+ WMI_SET_TX_SGI_PARAM_CMD SGICmd;
+
+ if (ar->arWmiReady == FALSE) {
+ ret = -EIO;
+ } else if (copy_from_user(&SGICmd, userdata,
+ sizeof(SGICmd))){
+ ret = -EFAULT;
+ } else{
+ if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != A_OK) {
+ ret = -EIO;
+ }
+
+ }
+ break;
+ }
+
+ case AR6000_XIOCTL_ADD_AP_INTERFACE:
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+ {
+ char ap_ifname[IFNAMSIZ] = {0,};
+ if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) {
+ ret = -EFAULT;
+ } else {
+ if (ar6000_add_ap_interface(ar, ap_ifname) != A_OK) {
+ ret = -EIO;
+ }
+ }
+ }
+#else
+ ret = -EOPNOTSUPP;
+#endif
+ break;
+ case AR6000_XIOCTL_REMOVE_AP_INTERFACE:
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
+ if (ar6000_remove_ap_interface(ar) != A_OK) {
+ ret = -EIO;
+ }
+#else
+ ret = -EOPNOTSUPP;
+#endif
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ioctl_done:
+ rtnl_lock(); /* restore rtnl state */
+ dev_put(dev);
+
+ return ret;
+}
+
+A_UINT8 mac_cmp_wild(A_UINT8 *mac, A_UINT8 *new_mac, A_UINT8 wild, A_UINT8 new_wild)
+{
+ A_UINT8 i;
+
+ for(i=0;i<ATH_MAC_LEN;i++) {
+ if((wild & 1<<i) && (new_wild & 1<<i)) continue;
+ if(mac[i] != new_mac[i]) return 1;
+ }
+ if((A_MEMCMP(new_mac, null_mac, 6)==0) && new_wild &&
+ (wild != new_wild)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+A_UINT8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl)
+{
+ A_INT8 already_avail=-1, free_slot=-1, i;
+
+ /* To check whether this mac is already there in our list */
+ for(i=AP_ACL_SIZE-1;i>=0;i--)
+ {
+ if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i],
+ acl->wildcard)==0)
+ already_avail = i;
+
+ if(!((1 << i) & a->index))
+ free_slot = i;
+ }
+
+ if(acl->action == ADD_MAC_ADDR)
+ {
+ /* Dont add mac if it is already available */
+ if((already_avail >= 0) || (free_slot == -1))
+ return 0;
+
+ A_MEMCPY(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN);
+ a->index = a->index | (1 << free_slot);
+ acl->index = free_slot;
+ a->wildcard[free_slot] = acl->wildcard;
+ return 1;
+ }
+ else if(acl->action == DEL_MAC_ADDR)
+ {
+ if(acl->index > AP_ACL_SIZE)
+ return 0;
+
+ if(!(a->index & (1 << acl->index)))
+ return 0;
+
+ A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN);
+ a->index = a->index & ~(1 << acl->index);
+ a->wildcard[acl->index] = 0;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c
new file mode 100644
index 000000000000..63fa49c8567a
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/netbuf.c
@@ -0,0 +1,236 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <a_config.h>
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include "htc_packet.h"
+
+#define AR6000_DATA_OFFSET 64
+
+void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt)
+{
+ skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt);
+}
+
+void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt)
+{
+ skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt);
+}
+
+void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q)
+{
+ return((void *) skb_dequeue((struct sk_buff_head *) q));
+}
+
+int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q)
+{
+ return(skb_queue_len((struct sk_buff_head *) q));
+}
+
+int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q)
+{
+ return(skb_queue_empty((struct sk_buff_head *) q));
+}
+
+void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q)
+{
+ skb_queue_head_init((struct sk_buff_head *) q);
+}
+
+void *
+a_netbuf_alloc(int size)
+{
+ struct sk_buff *skb;
+ size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */
+ skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + size);
+ skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + A_GET_CACHE_LINE_BYTES());
+ return ((void *)skb);
+}
+
+/*
+ * Allocate an SKB w.o. any encapsulation requirement.
+ */
+void *
+a_netbuf_alloc_raw(int size)
+{
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(size);
+
+ return ((void *)skb);
+}
+
+void
+a_netbuf_free(void *bufPtr)
+{
+ struct sk_buff *skb = (struct sk_buff *)bufPtr;
+
+ dev_kfree_skb(skb);
+}
+
+A_UINT32
+a_netbuf_to_len(void *bufPtr)
+{
+ return (((struct sk_buff *)bufPtr)->len);
+}
+
+void *
+a_netbuf_to_data(void *bufPtr)
+{
+ return (((struct sk_buff *)bufPtr)->data);
+}
+
+/*
+ * Add len # of bytes to the beginning of the network buffer
+ * pointed to by bufPtr
+ */
+A_STATUS
+a_netbuf_push(void *bufPtr, A_INT32 len)
+{
+ skb_push((struct sk_buff *)bufPtr, len);
+
+ return A_OK;
+}
+
+/*
+ * Add len # of bytes to the beginning of the network buffer
+ * pointed to by bufPtr and also fill with data
+ */
+A_STATUS
+a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len)
+{
+ skb_push((struct sk_buff *) bufPtr, len);
+ A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len);
+
+ return A_OK;
+}
+
+/*
+ * Add len # of bytes to the end of the network buffer
+ * pointed to by bufPtr
+ */
+A_STATUS
+a_netbuf_put(void *bufPtr, A_INT32 len)
+{
+ skb_put((struct sk_buff *)bufPtr, len);
+
+ return A_OK;
+}
+
+/*
+ * Add len # of bytes to the end of the network buffer
+ * pointed to by bufPtr and also fill with data
+ */
+A_STATUS
+a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len)
+{
+ char *start = (char*)(((struct sk_buff *)bufPtr)->data +
+ ((struct sk_buff *)bufPtr)->len);
+ skb_put((struct sk_buff *)bufPtr, len);
+ A_MEMCPY(start, srcPtr, len);
+
+ return A_OK;
+}
+
+
+/*
+ * Trim the network buffer pointed to by bufPtr to len # of bytes
+ */
+A_STATUS
+a_netbuf_setlen(void *bufPtr, A_INT32 len)
+{
+ skb_trim((struct sk_buff *)bufPtr, len);
+
+ return A_OK;
+}
+
+/*
+ * Chop of len # of bytes from the end of the buffer.
+ */
+A_STATUS
+a_netbuf_trim(void *bufPtr, A_INT32 len)
+{
+ skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
+
+ return A_OK;
+}
+
+/*
+ * Chop of len # of bytes from the end of the buffer and return the data.
+ */
+A_STATUS
+a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len)
+{
+ char *start = (char*)(((struct sk_buff *)bufPtr)->data +
+ (((struct sk_buff *)bufPtr)->len - len));
+
+ A_MEMCPY(dstPtr, start, len);
+ skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len);
+
+ return A_OK;
+}
+
+
+/*
+ * Returns the number of bytes available to a a_netbuf_push()
+ */
+A_INT32
+a_netbuf_headroom(void *bufPtr)
+{
+ return (skb_headroom((struct sk_buff *)bufPtr));
+}
+
+/*
+ * Removes specified number of bytes from the beginning of the buffer
+ */
+A_STATUS
+a_netbuf_pull(void *bufPtr, A_INT32 len)
+{
+ skb_pull((struct sk_buff *)bufPtr, len);
+
+ return A_OK;
+}
+
+/*
+ * Removes specified number of bytes from the beginning of the buffer
+ * and return the data
+ */
+A_STATUS
+a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len)
+{
+ A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len);
+ skb_pull((struct sk_buff *)bufPtr, len);
+
+ return A_OK;
+}
+
+#ifdef EXPORT_HCI_BRIDGE_INTERFACE
+EXPORT_SYMBOL(a_netbuf_to_data);
+EXPORT_SYMBOL(a_netbuf_put);
+EXPORT_SYMBOL(a_netbuf_pull);
+EXPORT_SYMBOL(a_netbuf_alloc);
+EXPORT_SYMBOL(a_netbuf_free);
+#endif
diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c
new file mode 100644
index 000000000000..bb6de0f404fe
--- /dev/null
+++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c
@@ -0,0 +1,2725 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Communications Inc.
+// All rights reserved.
+//
+//
+//
+// 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.
+//
+//
+//
+// Author(s): ="Atheros"
+//------------------------------------------------------------------------------
+
+#include "ar6000_drv.h"
+
+#define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \
+ iwe_stream_add_event((p1), (p2), (p3), (p4), (p5))
+
+#define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \
+ iwe_stream_add_point((p1), (p2), (p3), (p4), (p5))
+
+#define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \
+ iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6))
+
+static void ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi);
+extern unsigned int wmitimeout;
+extern A_WAITQUEUE_HEAD arEvent;
+
+#if WIRELESS_EXT > 14
+/*
+ * Encode a WPA or RSN information element as a custom
+ * element using the hostap format.
+ */
+static u_int
+encode_ie(void *buf, size_t bufsize,
+ const u_int8_t *ie, size_t ielen,
+ const char *leader, size_t leader_len)
+{
+ u_int8_t *p;
+ int i;
+
+ if (bufsize < leader_len)
+ return 0;
+ p = buf;
+ memcpy(p, leader, leader_len);
+ bufsize -= leader_len;
+ p += leader_len;
+ for (i = 0; i < ielen && bufsize > 2; i++)
+ {
+ p += sprintf((char*)p, "%02x", ie[i]);
+ bufsize -= 2;
+ }
+ return (i == ielen ? p - (u_int8_t *)buf : 0);
+}
+#endif /* WIRELESS_EXT > 14 */
+
+static A_UINT8
+get_bss_phy_capability(bss_t *bss)
+{
+ A_UINT8 capability = 0;
+ struct ieee80211_common_ie *cie = &bss->ni_cie;
+#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
+ if (CHAN_IS_11A(cie->ie_chan)) {
+ if (cie->ie_htcap) {
+ capability = WMI_11NA_CAPABILITY;
+ } else {
+ capability = WMI_11A_CAPABILITY;
+ }
+ } else if ((cie->ie_erp) || (cie->ie_xrates)) {
+ if (cie->ie_htcap) {
+ capability = WMI_11NG_CAPABILITY;
+ } else {
+ capability = WMI_11G_CAPABILITY;
+ }
+ }
+ return capability;
+}
+
+void
+ar6000_scan_node(void *arg, bss_t *ni)
+{
+ struct iw_event iwe;
+#if WIRELESS_EXT > 14
+ char buf[256];
+#endif
+ struct ar_giwscan_param *param;
+ A_CHAR *current_ev;
+ A_CHAR *end_buf;
+ struct ieee80211_common_ie *cie;
+ A_CHAR *current_val;
+ A_INT32 j;
+ A_UINT32 rate_len, data_len = 0;
+
+ param = (struct ar_giwscan_param *)arg;
+
+ current_ev = param->current_ev;
+ end_buf = param->end_buf;
+
+ cie = &ni->ni_cie;
+
+ if ((end_buf - current_ev) > IW_EV_ADDR_LEN)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6);
+ current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
+ }
+ param->bytes_needed += IW_EV_ADDR_LEN;
+
+ data_len = cie->ie_ssid[1] + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ iwe.u.data.length = cie->ie_ssid[1];
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
+ &iwe, (char*)&cie->ie_ssid[2]);
+ }
+ param->bytes_needed += data_len;
+
+ if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
+ if ((end_buf - current_ev) > IW_EV_UINT_LEN)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWMODE;
+ iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ?
+ IW_MODE_MASTER : IW_MODE_ADHOC;
+ current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
+ }
+ param->bytes_needed += IW_EV_UINT_LEN;
+ }
+
+ if ((end_buf - current_ev) > IW_EV_FREQ_LEN)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = cie->ie_chan * 100000;
+ iwe.u.freq.e = 1;
+ current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+ }
+ param->bytes_needed += IW_EV_FREQ_LEN;
+
+ if ((end_buf - current_ev) > IW_EV_QUAL_LEN)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVQUAL;
+ ar6000_set_quality(&iwe.u.qual, ni->ni_snr);
+ current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+ }
+ param->bytes_needed += IW_EV_QUAL_LEN;
+
+ if ((end_buf - current_ev) > IW_EV_POINT_LEN)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWENCODE;
+ if (cie->ie_capInfo & IEEE80211_CAPINFO_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(param->info, current_ev, end_buf,
+ &iwe, "");
+ }
+ param->bytes_needed += IW_EV_POINT_LEN;
+
+ /* supported bit rate */
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWRATE;
+ iwe.u.bitrate.fixed = 0;
+ iwe.u.bitrate.disabled = 0;
+ iwe.u.bitrate.value = 0;
+ current_val = current_ev + IW_EV_LCP_LEN;
+ param->bytes_needed += IW_EV_LCP_LEN;
+
+ if (cie->ie_rates != NULL) {
+ rate_len = cie->ie_rates[1];
+ data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
+ if ((end_buf - current_ev) > data_len)
+ {
+ for (j = 0; j < rate_len; j++) {
+ unsigned char val;
+ val = cie->ie_rates[2 + j];
+ iwe.u.bitrate.value =
+ (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
+ current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+
+ if (cie->ie_xrates != NULL) {
+ rate_len = cie->ie_xrates[1];
+ data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
+ if ((end_buf - current_ev) > data_len)
+ {
+ for (j = 0; j < rate_len; j++) {
+ unsigned char val;
+ val = cie->ie_xrates[2 + j];
+ iwe.u.bitrate.value =
+ (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
+ current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+ /* remove fixed header if no rates were added */
+ if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ current_ev = current_val;
+
+#if WIRELESS_EXT >= 18
+ /* IE */
+ if (cie->ie_wpa != NULL) {
+ data_len = cie->ie_wpa[1] + 2 + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = cie->ie_wpa[1] + 2;
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
+ &iwe, (char*)cie->ie_wpa);
+ }
+ param->bytes_needed += data_len;
+ }
+
+ if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
+ data_len = cie->ie_rsn[1] + 2 + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = cie->ie_rsn[1] + 2;
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
+ &iwe, (char*)cie->ie_rsn);
+ }
+ param->bytes_needed += data_len;
+ }
+
+#endif /* WIRELESS_EXT >= 18 */
+
+ if ((end_buf - current_ev) > IW_EV_CHAR_LEN)
+ {
+ /* protocol */
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = SIOCGIWNAME;
+ switch (get_bss_phy_capability(ni)) {
+ case WMI_11A_CAPABILITY:
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
+ break;
+ case WMI_11G_CAPABILITY:
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
+ break;
+ case WMI_11NA_CAPABILITY:
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11na");
+ break;
+ case WMI_11NG_CAPABILITY:
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11ng");
+ break;
+ default:
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
+ break;
+ }
+ current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
+ &iwe, IW_EV_CHAR_LEN);
+ }
+ param->bytes_needed += IW_EV_CHAR_LEN;
+
+#if WIRELESS_EXT > 14
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt);
+ data_len = iwe.u.data.length + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
+ &iwe, buf);
+ }
+ param->bytes_needed += data_len;
+
+#if WIRELESS_EXT < 18
+ if (cie->ie_wpa != NULL) {
+ static const char wpa_leader[] = "wpa_ie=";
+ data_len = (sizeof(wpa_leader) - 1) + ((cie->ie_wpa[1]+2) * 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
+ cie->ie_wpa[1]+2,
+ wpa_leader, sizeof(wpa_leader)-1);
+
+ if (iwe.u.data.length != 0) {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
+ end_buf, &iwe, buf);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+
+ if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
+ static const char rsn_leader[] = "rsn_ie=";
+ data_len = (sizeof(rsn_leader) - 1) + ((cie->ie_rsn[1]+2) * 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn,
+ cie->ie_rsn[1]+2,
+ rsn_leader, sizeof(rsn_leader)-1);
+
+ if (iwe.u.data.length != 0) {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
+ end_buf, &iwe, buf);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+#endif /* WIRELESS_EXT < 18 */
+
+ if (cie->ie_wmm != NULL) {
+ static const char wmm_leader[] = "wmm_ie=";
+ data_len = (sizeof(wmm_leader) - 1) + ((cie->ie_wmm[1]+2) * 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm,
+ cie->ie_wmm[1]+2,
+ wmm_leader, sizeof(wmm_leader)-1);
+ if (iwe.u.data.length != 0) {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
+ end_buf, &iwe, buf);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+
+ if (cie->ie_ath != NULL) {
+ static const char ath_leader[] = "ath_ie=";
+ data_len = (sizeof(ath_leader) - 1) + ((cie->ie_ath[1]+2) * 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath,
+ cie->ie_ath[1]+2,
+ ath_leader, sizeof(ath_leader)-1);
+ if (iwe.u.data.length != 0) {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
+ end_buf, &iwe, buf);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+
+#ifdef WAPI_ENABLE
+ if (cie->ie_wapi != NULL) {
+ static const char wapi_leader[] = "wapi_ie=";
+ data_len = (sizeof(wapi_leader) - 1) + ((cie->ie_wapi[1] + 2) * 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len) {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wapi,
+ cie->ie_wapi[1] + 2,
+ wapi_leader, sizeof(wapi_leader) - 1);
+ if (iwe.u.data.length != 0) {
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
+ end_buf, &iwe, buf);
+ }
+ }
+ param->bytes_needed += data_len;
+ }
+#endif /* WAPI_ENABLE */
+
+#endif /* WIRELESS_EXT > 14 */
+
+#if WIRELESS_EXT >= 18
+ if (cie->ie_wsc != NULL) {
+ data_len = (cie->ie_wsc[1] + 2) + IW_EV_POINT_LEN;
+ if ((end_buf - current_ev) > data_len)
+ {
+ A_MEMZERO(&iwe, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = cie->ie_wsc[1] + 2;
+ current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
+ &iwe, (char*)cie->ie_wsc);
+ }
+ param->bytes_needed += data_len;
+ }
+#endif /* WIRELESS_EXT >= 18 */
+
+ param->current_ev = current_ev;
+}
+
+int
+ar6000_ioctl_giwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct ar_giwscan_param param;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ param.current_ev = extra;
+ param.end_buf = extra + data->length;
+ param.bytes_needed = 0;
+ param.info = info;
+
+ /* Translate data to WE format */
+ wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, &param);
+
+ /* check if bytes needed is greater than bytes consumed */
+ if (param.bytes_needed > (param.current_ev - extra))
+ {
+ /* Request one byte more than needed, because when "data->length" equals bytes_needed,
+ it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
+ checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
+ data->length = param.bytes_needed + 1;
+
+ return -E2BIG;
+ }
+
+ return 0;
+}
+
+extern int reconnect_flag;
+/* SIOCSIWESSID */
+static int
+ar6000_ioctl_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *ssid)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_STATUS status;
+ A_UINT8 arNetworkType;
+ A_UINT8 prevMode = ar->arNetworkType;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+#if defined(WIRELESS_EXT)
+ if (WIRELESS_EXT >= 20) {
+ data->length += 1;
+ }
+#endif
+
+ /*
+ * iwconfig passes a null terminated string with length including this
+ * so we need to account for this
+ */
+ if (data->flags && (!data->length || (data->length == 1) ||
+ ((data->length - 1) > sizeof(ar->arSsid))))
+ {
+ /*
+ * ssid is invalid
+ */
+ return -EINVAL;
+ }
+
+ if (ar->arNextMode == AP_NETWORK) {
+ /* SSID change for AP network - Will take effect on commit */
+ if(A_MEMCMP(ar->arSsid,ssid,32) != 0) {
+ ar->arSsidLen = data->length - 1;
+ A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ }
+ return 0;
+ } else if(ar->arNetworkType == AP_NETWORK) {
+ A_UINT8 ctr;
+ struct sk_buff *skb;
+
+ /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
+ for (ctr=0; ctr < AP_MAX_NUM_STA; ctr++) {
+ remove_sta(ar, ar->sta_list[ctr].mac, 0);
+ }
+ A_MUTEX_LOCK(&ar->mcastpsqLock);
+ while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
+ skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
+ A_NETBUF_FREE(skb);
+ }
+ A_MUTEX_UNLOCK(&ar->mcastpsqLock);
+ }
+
+ /* Added for bug 25178, return an IOCTL error instead of target returning
+ Illegal parameter error when either the BSSID or channel is missing
+ and we cannot scan during connect.
+ */
+ if (data->flags) {
+ if (ar->arSkipScan == TRUE &&
+ (ar->arChannelHint == 0 ||
+ (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] &&
+ !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5])))
+ {
+ return -EINVAL;
+ }
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ if (ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
+ /*
+ * sleep until the command queue drains
+ */
+ wait_event_interruptible_timeout(arEvent,
+ ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
+ if (signal_pending(current)) {
+ return -EINTR;
+ }
+ }
+
+ if (!data->flags) {
+ arNetworkType = ar->arNetworkType;
+#ifdef ATH6K_CONFIG_CFG80211
+ if (ar->arConnected) {
+#endif /* ATH6K_CONFIG_CFG80211 */
+ ar6000_init_profile_info(ar);
+#ifdef ATH6K_CONFIG_CFG80211
+ }
+#endif /* ATH6K_CONFIG_CFG80211 */
+ ar->arNetworkType = arNetworkType;
+ }
+
+ /* Update the arNetworkType */
+ ar->arNetworkType = ar->arNextMode;
+
+
+ if ((prevMode != AP_NETWORK) &&
+ ((ar->arSsidLen) || ((ar->arSsidLen == 0) && ar->arConnected) || (!data->flags)))
+ {
+ if ((!data->flags) ||
+ (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) ||
+ (ar->arSsidLen != (data->length - 1)))
+ {
+ /*
+ * SSID set previously or essid off has been issued.
+ *
+ * Disconnect Command is issued in two cases after wmi is ready
+ * (1) ssid is different from the previous setting
+ * (2) essid off has been issued
+ *
+ */
+ if (ar->arWmiReady == TRUE) {
+ reconnect_flag = 0;
+ status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
+ status = wmi_disconnect_cmd(ar->arWmi);
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ if (ar->arSkipScan == FALSE) {
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ }
+ if (!data->flags) {
+ up(&ar->arSem);
+ return 0;
+ }
+ } else {
+ up(&ar->arSem);
+ }
+ }
+ else
+ {
+ /*
+ * SSID is same, so we assume profile hasn't changed.
+ * If the interface is up and wmi is ready, we issue
+ * a reconnect cmd. Issue a reconnect only we are already
+ * connected.
+ */
+ if((ar->arConnected == TRUE) && (ar->arWmiReady == TRUE))
+ {
+ reconnect_flag = TRUE;
+ status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid,
+ ar->arChannelHint);
+ up(&ar->arSem);
+ if (status != A_OK) {
+ return -EIO;
+ }
+ return 0;
+ }
+ else{
+ /*
+ * Dont return if connect is pending.
+ */
+ if(!(ar->arConnectPending)) {
+ up(&ar->arSem);
+ return 0;
+ }
+ }
+ }
+ }
+
+ ar->arSsidLen = data->length - 1;
+ A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
+
+ if (ar6000_connect_to_ap(ar)!= A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }else{
+ up(&ar->arSem);
+ }
+ return 0;
+}
+
+/* SIOCGIWESSID */
+static int
+ar6000_ioctl_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (!ar->arSsidLen) {
+ return -EINVAL;
+ }
+
+ data->flags = 1;
+ data->length = ar->arSsidLen;
+ A_MEMCPY(essid, ar->arSsid, ar->arSsidLen);
+
+ return 0;
+}
+
+
+void ar6000_install_static_wep_keys(AR_SOFTC_T *ar)
+{
+ A_UINT8 index;
+ A_UINT8 keyUsage;
+
+ for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+ if (ar->arWepKeyList[index].arKeyLen) {
+ keyUsage = GROUP_USAGE;
+ if (index == ar->arDefTxKeyIndex) {
+ keyUsage |= TX_USAGE;
+ }
+ wmi_addKey_cmd(ar->arWmi,
+ index,
+ WEP_CRYPT,
+ keyUsage,
+ ar->arWepKeyList[index].arKeyLen,
+ NULL,
+ ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+ }
+}
+
+/*
+ * SIOCSIWRATE
+ */
+int
+ar6000_ioctl_siwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT32 kbps;
+ A_INT8 rate_idx;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (rrq->fixed) {
+ kbps = rrq->value / 1000; /* rrq->value is in bps */
+ } else {
+ kbps = -1; /* -1 indicates auto rate */
+ }
+ if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != A_OK)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps));
+ return -EINVAL;
+ }
+ ar->arBitRate = kbps;
+ if(ar->arWmiReady == TRUE)
+ {
+ if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != A_OK) {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+/*
+ * SIOCGIWRATE
+ */
+int
+ar6000_ioctl_giwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ int ret = 0;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == FALSE) {
+ rrq->value = 1000 * 1000;
+ return 0;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ ar->arBitRate = 0xFFFF;
+ if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+ wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+ /* If the interface is down or wmi is not ready or the target is not
+ connected - return the value stored in the device structure */
+ if (!ret) {
+ if (ar->arBitRate == -1) {
+ rrq->fixed = TRUE;
+ rrq->value = 0;
+ } else {
+ rrq->value = ar->arBitRate * 1000;
+ }
+ }
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+/*
+ * SIOCSIWTXPOW
+ */
+static int
+ar6000_ioctl_siwtxpow(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT8 dbM;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (rrq->disabled) {
+ return -EOPNOTSUPP;
+ }
+
+ if (rrq->fixed) {
+ if (rrq->flags != IW_TXPOW_DBM) {
+ return -EOPNOTSUPP;
+ }
+ ar->arTxPwr= dbM = rrq->value;
+ ar->arTxPwrSet = TRUE;
+ } else {
+ ar->arTxPwr = dbM = 0;
+ ar->arTxPwrSet = FALSE;
+ }
+ if(ar->arWmiReady == TRUE)
+ {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM));
+ wmi_set_txPwr_cmd(ar->arWmi, dbM);
+ }
+ return 0;
+}
+
+/*
+ * SIOCGIWTXPOW
+ */
+int
+ar6000_ioctl_giwtxpow(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ int ret = 0;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ if((ar->arWmiReady == TRUE) && (ar->arConnected == TRUE))
+ {
+ ar->arTxPwr = 0;
+
+ if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ }
+ }
+ /* If the interace is down or wmi is not ready or target is not connected
+ then return value stored in the device structure */
+
+ if (!ret) {
+ if (ar->arTxPwrSet == TRUE) {
+ rrq->fixed = TRUE;
+ }
+ rrq->value = ar->arTxPwr;
+ rrq->flags = IW_TXPOW_DBM;
+ //
+ // IWLIST need this flag to get TxPower
+ //
+ rrq->disabled = 0;
+ }
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+/*
+ * SIOCSIWRETRY
+ * since iwconfig only provides us with one max retry value, we use it
+ * to apply to data frames of the BE traffic class.
+ */
+static int
+ar6000_ioctl_siwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (rrq->disabled) {
+ return -EOPNOTSUPP;
+ }
+
+ if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) {
+ return -EOPNOTSUPP;
+ }
+
+ if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) {
+ return - EINVAL;
+ }
+ if(ar->arWmiReady == TRUE)
+ {
+ if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE,
+ rrq->value, 0) != A_OK){
+ return -EINVAL;
+ }
+ }
+ ar->arMaxRetries = rrq->value;
+ return 0;
+}
+
+/*
+ * SIOCGIWRETRY
+ */
+static int
+ar6000_ioctl_giwretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ rrq->disabled = 0;
+ switch (rrq->flags & IW_RETRY_TYPE) {
+ case IW_RETRY_LIFETIME:
+ return -EOPNOTSUPP;
+ break;
+ case IW_RETRY_LIMIT:
+ rrq->flags = IW_RETRY_LIMIT;
+ switch (rrq->flags & IW_RETRY_MODIFIER) {
+ case IW_RETRY_MIN:
+ rrq->flags |= IW_RETRY_MIN;
+ rrq->value = WMI_MIN_RETRIES;
+ break;
+ case IW_RETRY_MAX:
+ rrq->flags |= IW_RETRY_MAX;
+ rrq->value = ar->arMaxRetries;
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+/*
+ * SIOCSIWENCODE
+ */
+static int
+ar6000_ioctl_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *keybuf)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ int index;
+ A_INT32 auth = 0;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if(ar->arNextMode != AP_NETWORK) {
+ /*
+ * Static WEP Keys should be configured before setting the SSID
+ */
+ if (ar->arSsid[0] && erq->length) {
+ return -EIO;
+ }
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ index = erq->flags & IW_ENCODE_INDEX;
+
+ if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
+ ((index - 1) > WMI_MAX_KEY_INDEX)))
+ {
+ return -EIO;
+ }
+
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ /*
+ * Encryption disabled
+ */
+ if (index) {
+ /*
+ * If key index was specified then clear the specified key
+ */
+ index--;
+ A_MEMZERO(ar->arWepKeyList[index].arKey,
+ sizeof(ar->arWepKeyList[index].arKey));
+ ar->arWepKeyList[index].arKeyLen = 0;
+ }
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arAuthMode = NONE_AUTH;
+ } else {
+ /*
+ * Enabling WEP encryption
+ */
+ if (index) {
+ index--; /* keyindex is off base 1 in iwconfig */
+ }
+
+ if (erq->flags & IW_ENCODE_OPEN) {
+ auth |= OPEN_AUTH;
+ ar->arDefTxKeyIndex = index;
+ }
+ if (erq->flags & IW_ENCODE_RESTRICTED) {
+ auth |= SHARED_AUTH;
+ }
+
+ if (!auth) {
+ auth = OPEN_AUTH;
+ }
+
+ if (erq->length) {
+ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) {
+ return -EIO;
+ }
+
+ A_MEMZERO(ar->arWepKeyList[index].arKey,
+ sizeof(ar->arWepKeyList[index].arKey));
+ A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length);
+ ar->arWepKeyList[index].arKeyLen = erq->length;
+ ar->arDot11AuthMode = auth;
+ } else {
+ if (ar->arWepKeyList[index].arKeyLen == 0) {
+ return -EIO;
+ }
+ ar->arDefTxKeyIndex = index;
+
+ if(ar->arSsidLen && ar->arWepKeyList[index].arKeyLen) {
+ wmi_addKey_cmd(ar->arWmi,
+ index,
+ WEP_CRYPT,
+ GROUP_USAGE | TX_USAGE,
+ ar->arWepKeyList[index].arKeyLen,
+ NULL,
+ ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+ }
+
+ ar->arPairwiseCrypto = WEP_CRYPT;
+ ar->arGroupCrypto = WEP_CRYPT;
+ ar->arAuthMode = NONE_AUTH;
+ }
+
+ if(ar->arNextMode != AP_NETWORK) {
+ /*
+ * profile has changed. Erase ssid to signal change
+ */
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ }
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+ return 0;
+}
+
+static int
+ar6000_ioctl_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT8 keyIndex;
+ struct ar_wep_key *wk;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arPairwiseCrypto == NONE_CRYPT) {
+ erq->length = 0;
+ erq->flags = IW_ENCODE_DISABLED;
+ } else {
+ if (ar->arPairwiseCrypto == WEP_CRYPT) {
+ /* get the keyIndex */
+ keyIndex = erq->flags & IW_ENCODE_INDEX;
+ if (0 == keyIndex) {
+ keyIndex = ar->arDefTxKeyIndex;
+ } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) ||
+ (keyIndex - 1 > WMI_MAX_KEY_INDEX))
+ {
+ keyIndex = WMI_MIN_KEY_INDEX;
+ } else {
+ keyIndex--;
+ }
+ erq->flags = keyIndex + 1;
+ erq->flags &= ~IW_ENCODE_DISABLED;
+ wk = &ar->arWepKeyList[keyIndex];
+ if (erq->length > wk->arKeyLen) {
+ erq->length = wk->arKeyLen;
+ }
+ if (wk->arKeyLen) {
+ A_MEMCPY(key, wk->arKey, erq->length);
+ }
+ } else {
+ erq->flags &= ~IW_ENCODE_DISABLED;
+ if (ar->user_saved_keys.keyOk) {
+ erq->length = ar->user_saved_keys.ucast_ik.ik_keylen;
+ if (erq->length) {
+ A_MEMCPY(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length);
+ }
+ } else {
+ erq->length = 1; // not really printing any key but let iwconfig know enc is on
+ }
+ }
+
+ if (ar->arDot11AuthMode & OPEN_AUTH) {
+ erq->flags |= IW_ENCODE_OPEN;
+ }
+ if (ar->arDot11AuthMode & SHARED_AUTH) {
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ }
+ }
+
+ return 0;
+}
+
+#if WIRELESS_EXT >= 18
+/*
+ * SIOCSIWGENIE
+ */
+static int
+ar6000_ioctl_siwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+#ifdef WAPI_ENABLE
+ A_UINT8 *ie = erq->pointer;
+ A_UINT8 ie_type = ie[0];
+ A_UINT16 ie_length = erq->length;
+ A_UINT8 wapi_ie[128];
+#endif
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+#ifdef WAPI_ENABLE
+ if (ie_type == IEEE80211_ELEMID_WAPI) {
+ if (ie_length > 0) {
+ if (copy_from_user(wapi_ie, ie, ie_length)) {
+ return -EIO;
+ }
+ }
+ wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
+ } else if (ie_length == 0) {
+ wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
+ }
+#endif
+ return 0;
+}
+
+
+/*
+ * SIOCGIWGENIE
+ */
+static int
+ar6000_ioctl_giwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+ erq->length = 0;
+ erq->flags = 0;
+
+ return 0;
+}
+
+/*
+ * SIOCSIWAUTH
+ */
+static int
+ar6000_ioctl_siwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ A_BOOL profChanged;
+ A_UINT16 param;
+ A_INT32 ret;
+ A_INT32 value;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ param = data->flags & IW_AUTH_INDEX;
+ value = data->value;
+ profChanged = TRUE;
+ ret = 0;
+
+ switch (param) {
+ case IW_AUTH_WPA_VERSION:
+ if (value & IW_AUTH_WPA_VERSION_DISABLED) {
+ ar->arAuthMode = NONE_AUTH;
+ } else if (value & IW_AUTH_WPA_VERSION_WPA) {
+ ar->arAuthMode = WPA_AUTH;
+ } else if (value & IW_AUTH_WPA_VERSION_WPA2) {
+ ar->arAuthMode = WPA2_AUTH;
+ } else {
+ ret = -1;
+ profChanged = FALSE;
+ }
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ if (value & IW_AUTH_CIPHER_NONE) {
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_WEP40) {
+ ar->arPairwiseCrypto = WEP_CRYPT;
+ ar->arPairwiseCryptoLen = 5;
+ } else if (value & IW_AUTH_CIPHER_TKIP) {
+ ar->arPairwiseCrypto = TKIP_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_CCMP) {
+ ar->arPairwiseCrypto = AES_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_WEP104) {
+ ar->arPairwiseCrypto = WEP_CRYPT;
+ ar->arPairwiseCryptoLen = 13;
+ } else {
+ ret = -1;
+ profChanged = FALSE;
+ }
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ if (value & IW_AUTH_CIPHER_NONE) {
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_WEP40) {
+ ar->arGroupCrypto = WEP_CRYPT;
+ ar->arGroupCryptoLen = 5;
+ } else if (value & IW_AUTH_CIPHER_TKIP) {
+ ar->arGroupCrypto = TKIP_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_CCMP) {
+ ar->arGroupCrypto = AES_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ } else if (value & IW_AUTH_CIPHER_WEP104) {
+ ar->arGroupCrypto = WEP_CRYPT;
+ ar->arGroupCryptoLen = 13;
+ } else {
+ ret = -1;
+ profChanged = FALSE;
+ }
+ break;
+ case IW_AUTH_KEY_MGMT:
+ if (value & IW_AUTH_KEY_MGMT_PSK) {
+ if (WPA_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA_PSK_AUTH;
+ } else if (WPA2_AUTH == ar->arAuthMode) {
+ ar->arAuthMode = WPA2_PSK_AUTH;
+ } else {
+ ret = -1;
+ }
+ } else if (!(value & IW_AUTH_KEY_MGMT_802_1X)) {
+ ar->arAuthMode = NONE_AUTH;
+ }
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
+ profChanged = FALSE;
+ break;
+ case IW_AUTH_DROP_UNENCRYPTED:
+ profChanged = FALSE;
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ ar->arDot11AuthMode = 0;
+ if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
+ ar->arDot11AuthMode |= OPEN_AUTH;
+ }
+ if (value & IW_AUTH_ALG_SHARED_KEY) {
+ ar->arDot11AuthMode |= SHARED_AUTH;
+ }
+ if (value & IW_AUTH_ALG_LEAP) {
+ ar->arDot11AuthMode = LEAP_AUTH;
+ }
+ if(ar->arDot11AuthMode == 0) {
+ ret = -1;
+ profChanged = FALSE;
+ }
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ if (!value) {
+ ar->arAuthMode = NONE_AUTH;
+ /* when the supplicant is stopped, it calls this
+ * handler with value=0. The followings need to be
+ * reset if the STA were to connect again
+ * without security
+ */
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ }
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ profChanged = FALSE;
+ break;
+ case IW_AUTH_ROAMING_CONTROL:
+ profChanged = FALSE;
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ if (!value) {
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ }
+ break;
+#ifdef WAPI_ENABLE
+ case IW_AUTH_WAPI_ENABLED:
+ ar->arWapiEnable = value;
+ break;
+#endif
+ default:
+ ret = -1;
+ profChanged = FALSE;
+ break;
+ }
+
+ if (profChanged == TRUE) {
+ /*
+ * profile has changed. Erase ssid to signal change
+ */
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ }
+
+ return ret;
+}
+
+
+/*
+ * SIOCGIWAUTH
+ */
+static int
+ar6000_ioctl_giwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_UINT16 param;
+ A_INT32 ret;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ param = data->flags & IW_AUTH_INDEX;
+ ret = 0;
+ data->value = 0;
+
+
+ switch (param) {
+ case IW_AUTH_WPA_VERSION:
+ if (ar->arAuthMode == NONE_AUTH) {
+ data->value |= IW_AUTH_WPA_VERSION_DISABLED;
+ } else if (ar->arAuthMode == WPA_AUTH) {
+ data->value |= IW_AUTH_WPA_VERSION_WPA;
+ } else if (ar->arAuthMode == WPA2_AUTH) {
+ data->value |= IW_AUTH_WPA_VERSION_WPA2;
+ } else {
+ ret = -1;
+ }
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ if (ar->arPairwiseCrypto == NONE_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_NONE;
+ } else if (ar->arPairwiseCrypto == WEP_CRYPT) {
+ if (ar->arPairwiseCryptoLen == 13) {
+ data->value |= IW_AUTH_CIPHER_WEP104;
+ } else {
+ data->value |= IW_AUTH_CIPHER_WEP40;
+ }
+ } else if (ar->arPairwiseCrypto == TKIP_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_TKIP;
+ } else if (ar->arPairwiseCrypto == AES_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_CCMP;
+ } else {
+ ret = -1;
+ }
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ if (ar->arGroupCrypto == NONE_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_NONE;
+ } else if (ar->arGroupCrypto == WEP_CRYPT) {
+ if (ar->arGroupCryptoLen == 13) {
+ data->value |= IW_AUTH_CIPHER_WEP104;
+ } else {
+ data->value |= IW_AUTH_CIPHER_WEP40;
+ }
+ } else if (ar->arGroupCrypto == TKIP_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_TKIP;
+ } else if (ar->arGroupCrypto == AES_CRYPT) {
+ data->value |= IW_AUTH_CIPHER_CCMP;
+ } else {
+ ret = -1;
+ }
+ break;
+ case IW_AUTH_KEY_MGMT:
+ if ((ar->arAuthMode == WPA_PSK_AUTH) ||
+ (ar->arAuthMode == WPA2_PSK_AUTH)) {
+ data->value |= IW_AUTH_KEY_MGMT_PSK;
+ } else if ((ar->arAuthMode == WPA_AUTH) ||
+ (ar->arAuthMode == WPA2_AUTH)) {
+ data->value |= IW_AUTH_KEY_MGMT_802_1X;
+ }
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ // TODO. Save countermeassure enable/disable
+ data->value = 0;
+ break;
+ case IW_AUTH_DROP_UNENCRYPTED:
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ if (ar->arDot11AuthMode == OPEN_AUTH) {
+ data->value |= IW_AUTH_ALG_OPEN_SYSTEM;
+ } else if (ar->arDot11AuthMode == SHARED_AUTH) {
+ data->value |= IW_AUTH_ALG_SHARED_KEY;
+ } else if (ar->arDot11AuthMode == LEAP_AUTH) {
+ data->value |= IW_AUTH_ALG_LEAP;
+ } else {
+ ret = -1;
+ }
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ if (ar->arAuthMode == NONE_AUTH) {
+ data->value = 0;
+ } else {
+ data->value = 1;
+ }
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ break;
+ case IW_AUTH_ROAMING_CONTROL:
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ if (ar->arPairwiseCrypto == NONE_CRYPT) {
+ data->value = 0;
+ } else {
+ data->value = 1;
+ }
+ break;
+#ifdef WAPI_ENABLE
+ case IW_AUTH_WAPI_ENABLED:
+ data->value = ar->arWapiEnable;
+ break;
+#endif
+ default:
+ ret = -1;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * SIOCSIWPMKSA
+ */
+static int
+ar6000_ioctl_siwpmksa(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_INT32 ret;
+ A_STATUS status;
+ struct iw_pmksa *pmksa;
+
+ pmksa = (struct iw_pmksa *)extra;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ ret = 0;
+ status = A_OK;
+
+ switch (pmksa->cmd) {
+ case IW_PMKSA_ADD:
+ status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, TRUE);
+ break;
+ case IW_PMKSA_REMOVE:
+ status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, FALSE);
+ break;
+ case IW_PMKSA_FLUSH:
+ if (ar->arConnected == TRUE) {
+ status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
+ }
+ break;
+ default:
+ ret=-1;
+ break;
+ }
+ if (status != A_OK) {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+#ifdef WAPI_ENABLE
+
+#define PN_INIT 0x5c365c36
+
+static int ar6000_set_wapi_key(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ KEY_USAGE keyUsage = 0;
+ A_INT32 keyLen;
+ A_UINT8 *keyData;
+ A_INT32 index;
+ A_UINT32 *PN;
+ A_INT32 i;
+ A_STATUS status;
+ A_UINT8 wapiKeyRsc[16];
+ CRYPTO_TYPE keyType = WAPI_CRYPT;
+ const A_UINT8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ index = erq->flags & IW_ENCODE_INDEX;
+ if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
+ ((index - 1) > WMI_MAX_KEY_INDEX))) {
+ return -EIO;
+ }
+
+ index--;
+ if (index < 0 || index > 4) {
+ return -EIO;
+ }
+ keyData = (A_UINT8 *)(ext + 1);
+ keyLen = erq->length - sizeof(struct iw_encode_ext);
+ A_MEMCPY(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc));
+
+ if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) {
+ keyUsage |= GROUP_USAGE;
+ PN = (A_UINT32 *)wapiKeyRsc;
+ for (i = 0; i < 4; i++) {
+ PN[i] = PN_INIT;
+ }
+ } else {
+ keyUsage |= PAIRWISE_USAGE;
+ }
+ status = wmi_addKey_cmd(ar->arWmi,
+ index,
+ keyType,
+ keyUsage,
+ keyLen,
+ wapiKeyRsc,
+ keyData,
+ KEY_OP_INIT_WAPIPN,
+ NULL,
+ SYNC_BEFORE_WMIFLAG);
+ if (A_OK != status) {
+ return -EIO;
+ }
+ return 0;
+}
+
+#endif
+
+/*
+ * SIOCSIWENCODEEXT
+ */
+static int
+ar6000_ioctl_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ A_INT32 index;
+ struct iw_encode_ext *ext;
+ KEY_USAGE keyUsage;
+ A_INT32 keyLen;
+ A_UINT8 *keyData;
+ A_UINT8 keyRsc[8];
+ A_STATUS status;
+ CRYPTO_TYPE keyType;
+#ifdef USER_KEYS
+ struct ieee80211req_key ik;
+#endif /* USER_KEYS */
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+#ifdef USER_KEYS
+ ar->user_saved_keys.keyOk = FALSE;
+#endif /* USER_KEYS */
+
+ index = erq->flags & IW_ENCODE_INDEX;
+
+ if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
+ ((index - 1) > WMI_MAX_KEY_INDEX)))
+ {
+ return -EIO;
+ }
+
+ ext = (struct iw_encode_ext *)extra;
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ /*
+ * Encryption disabled
+ */
+ if (index) {
+ /*
+ * If key index was specified then clear the specified key
+ */
+ index--;
+ A_MEMZERO(ar->arWepKeyList[index].arKey,
+ sizeof(ar->arWepKeyList[index].arKey));
+ ar->arWepKeyList[index].arKeyLen = 0;
+ }
+ } else {
+ /*
+ * Enabling WEP encryption
+ */
+ if (index) {
+ index--; /* keyindex is off base 1 in iwconfig */
+ }
+
+ keyUsage = 0;
+ keyLen = erq->length - sizeof(struct iw_encode_ext);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ keyUsage = TX_USAGE;
+ ar->arDefTxKeyIndex = index;
+ // Just setting the key index
+ if (keyLen == 0) {
+ return 0;
+ }
+ }
+
+ if (keyLen <= 0) {
+ return -EIO;
+ }
+
+ /* key follows iw_encode_ext */
+ keyData = (A_UINT8 *)(ext + 1);
+
+ switch (ext->alg) {
+ case IW_ENCODE_ALG_WEP:
+ keyType = WEP_CRYPT;
+#ifdef USER_KEYS
+ ik.ik_type = IEEE80211_CIPHER_WEP;
+#endif /* USER_KEYS */
+ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen)) {
+ return -EIO;
+ }
+
+ /* Check whether it is static wep. */
+ if (!ar->arConnected) {
+ A_MEMZERO(ar->arWepKeyList[index].arKey,
+ sizeof(ar->arWepKeyList[index].arKey));
+ A_MEMCPY(ar->arWepKeyList[index].arKey, keyData, keyLen);
+ ar->arWepKeyList[index].arKeyLen = keyLen;
+
+ return 0;
+ }
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ keyType = TKIP_CRYPT;
+#ifdef USER_KEYS
+ ik.ik_type = IEEE80211_CIPHER_TKIP;
+#endif /* USER_KEYS */
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ keyType = AES_CRYPT;
+#ifdef USER_KEYS
+ ik.ik_type = IEEE80211_CIPHER_AES_CCM;
+#endif /* USER_KEYS */
+ break;
+#ifdef WAPI_ENABLE
+ case IW_ENCODE_ALG_SM4:
+ if (ar->arWapiEnable) {
+ return ar6000_set_wapi_key(dev, info, erq, extra);
+ } else {
+ return -EIO;
+ }
+#endif
+ case IW_ENCODE_ALG_PMK:
+ ar->arConnectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD;
+ return wmi_set_pmk_cmd(ar->arWmi, keyData);
+ default:
+ return -EIO;
+ }
+
+
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ keyUsage |= GROUP_USAGE;
+ } else {
+ keyUsage |= PAIRWISE_USAGE;
+ }
+
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ A_MEMCPY(keyRsc, ext->rx_seq, sizeof(keyRsc));
+ } else {
+ A_MEMZERO(keyRsc, sizeof(keyRsc));
+ }
+
+ if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
+ (GROUP_USAGE & keyUsage))
+ {
+ A_UNTIMEOUT(&ar->disconnect_timer);
+ }
+
+ status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage,
+ keyLen, keyRsc,
+ keyData, KEY_OP_INIT_VAL,
+ (A_UINT8*)ext->addr.sa_data,
+ SYNC_BOTH_WMIFLAG);
+ if (status != A_OK) {
+ return -EIO;
+ }
+
+#ifdef USER_KEYS
+ ik.ik_keyix = index;
+ ik.ik_keylen = keyLen;
+ memcpy(ik.ik_keydata, keyData, keyLen);
+ memcpy(&ik.ik_keyrsc, keyRsc, sizeof(keyRsc));
+ memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN);
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ memcpy(&ar->user_saved_keys.bcast_ik, &ik,
+ sizeof(struct ieee80211req_key));
+ } else {
+ memcpy(&ar->user_saved_keys.ucast_ik, &ik,
+ sizeof(struct ieee80211req_key));
+ }
+ ar->user_saved_keys.keyOk = TRUE;
+#endif /* USER_KEYS */
+ }
+
+
+ return 0;
+}
+
+/*
+ * SIOCGIWENCODEEXT
+ */
+static int
+ar6000_ioctl_giwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arPairwiseCrypto == NONE_CRYPT) {
+ erq->length = 0;
+ erq->flags = IW_ENCODE_DISABLED;
+ } else {
+ erq->length = 0;
+ }
+
+ return 0;
+}
+#endif // WIRELESS_EXT >= 18
+
+#if WIRELESS_EXT > 20
+static int ar6000_ioctl_siwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+#ifndef ATH6K_CONFIG_OTA_MODE
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_POWER_MODE power_mode;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (wrqu->power.disabled)
+ power_mode = MAX_PERF_POWER;
+ else
+ power_mode = REC_POWER;
+
+ if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0)
+ return -EIO;
+#endif
+ return 0;
+}
+
+static int ar6000_ioctl_giwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ WMI_POWER_MODE power_mode;
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ power_mode = wmi_get_power_mode_cmd(ar->arWmi);
+
+ if (power_mode == MAX_PERF_POWER)
+ wrqu->power.disabled = 1;
+ else
+ wrqu->power.disabled = 0;
+
+ return 0;
+}
+#endif // WIRELESS_EXT > 20
+
+/*
+ * SIOCGIWNAME
+ */
+int
+ar6000_ioctl_giwname(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ A_UINT8 capability;
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ capability = ar->arPhyCapability;
+ if(ar->arNetworkType == INFRA_NETWORK && ar->arConnected) {
+ bss_t *bss = wmi_find_node(ar->arWmi, ar->arBssid);
+ if (bss) {
+ capability = get_bss_phy_capability(bss);
+ wmi_node_return(ar->arWmi, bss);
+ }
+ }
+ switch (capability) {
+ case (WMI_11A_CAPABILITY):
+ strncpy(name, "AR6000 802.11a", IFNAMSIZ);
+ break;
+ case (WMI_11G_CAPABILITY):
+ strncpy(name, "AR6000 802.11g", IFNAMSIZ);
+ break;
+ case (WMI_11AG_CAPABILITY):
+ strncpy(name, "AR6000 802.11ag", IFNAMSIZ);
+ break;
+ case (WMI_11NA_CAPABILITY):
+ strncpy(name, "AR6000 802.11na", IFNAMSIZ);
+ break;
+ case (WMI_11NG_CAPABILITY):
+ strncpy(name, "AR6000 802.11ng", IFNAMSIZ);
+ break;
+ case (WMI_11NAG_CAPABILITY):
+ strncpy(name, "AR6000 802.11nag", IFNAMSIZ);
+ break;
+ default:
+ strncpy(name, "AR6000 802.11b", IFNAMSIZ);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * SIOCSIWFREQ
+ */
+int
+ar6000_ioctl_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ /*
+ * We support limiting the channels via wmiconfig.
+ *
+ * We use this command to configure the channel hint for the connect cmd
+ * so it is possible the target will end up connecting to a different
+ * channel.
+ */
+ if (freq->e > 1) {
+ return -EINVAL;
+ } else if (freq->e == 1) {
+ ar->arChannelHint = freq->m / 100000;
+ } else {
+ if(freq->m) {
+ ar->arChannelHint = wlan_ieee2freq(freq->m);
+ } else {
+ /* Auto Channel Selection */
+ ar->arChannelHint = 0;
+ }
+ }
+
+ ar->ap_profile_flag = 1; /* There is a change in profile */
+
+ A_PRINTF("channel hint set to %d\n", ar->arChannelHint);
+ return 0;
+}
+
+/*
+ * SIOCGIWFREQ
+ */
+int
+ar6000_ioctl_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arNetworkType == AP_NETWORK) {
+ if(ar->arChannelHint) {
+ freq->m = ar->arChannelHint * 100000;
+ } else if(ar->arACS) {
+ freq->m = ar->arACS * 100000;
+ } else {
+ return -EINVAL;
+ }
+ } else {
+ if (ar->arConnected != TRUE) {
+ return -EINVAL;
+ } else {
+ freq->m = ar->arBssChannel * 100000;
+ }
+ }
+
+ freq->e = 1;
+
+ return 0;
+}
+
+/*
+ * SIOCSIWMODE
+ */
+int
+ar6000_ioctl_siwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ /*
+ * clear SSID during mode switch in connected state
+ */
+ if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == TRUE) ){
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ }
+
+ switch (*mode) {
+ case IW_MODE_INFRA:
+ ar->arNextMode = INFRA_NETWORK;
+ break;
+ case IW_MODE_ADHOC:
+ ar->arNextMode = ADHOC_NETWORK;
+ break;
+ case IW_MODE_MASTER:
+ ar->arNextMode = AP_NETWORK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clear all shared parameters between AP and STA|IBSS modes when we
+ * switch between them. Switch between STA & IBSS modes does'nt clear
+ * the shared profile. This is as per the original design for switching
+ * between STA & IBSS.
+ */
+ if (ar->arNetworkType == AP_NETWORK || ar->arNextMode == AP_NETWORK) {
+ ar->arDot11AuthMode = OPEN_AUTH;
+ ar->arAuthMode = NONE_AUTH;
+ ar->arPairwiseCrypto = NONE_CRYPT;
+ ar->arPairwiseCryptoLen = 0;
+ ar->arGroupCrypto = NONE_CRYPT;
+ ar->arGroupCryptoLen = 0;
+ ar->arChannelHint = 0;
+ ar->arBssChannel = 0;
+ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ }
+
+ /* SSID has to be cleared to trigger a profile change while switching
+ * between STA & IBSS modes having the same SSID
+ */
+ if (ar->arNetworkType != ar->arNextMode) {
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * SIOCGIWMODE
+ */
+int
+ar6000_ioctl_giwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ switch (ar->arNetworkType) {
+ case INFRA_NETWORK:
+ *mode = IW_MODE_INFRA;
+ break;
+ case ADHOC_NETWORK:
+ *mode = IW_MODE_ADHOC;
+ break;
+ case AP_NETWORK:
+ *mode = IW_MODE_MASTER;
+ break;
+ default:
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * SIOCSIWSENS
+ */
+int
+ar6000_ioctl_siwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *sens, char *extra)
+{
+ return 0;
+}
+
+/*
+ * SIOCGIWSENS
+ */
+int
+ar6000_ioctl_giwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *sens, char *extra)
+{
+ sens->value = 0;
+ sens->fixed = 1;
+
+ return 0;
+}
+
+/*
+ * SIOCGIWRANGE
+ */
+int
+ar6000_ioctl_giwrange(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ struct iw_range *range = (struct iw_range *) extra;
+ int i, ret = 0;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ up(&ar->arSem);
+ return -EBUSY;
+ }
+
+ ar->arNumChannels = -1;
+ A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList));
+
+ if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) {
+ up(&ar->arSem);
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ);
+
+ if (signal_pending(current)) {
+ up(&ar->arSem);
+ return -EINTR;
+ }
+
+ data->length = sizeof(struct iw_range);
+ A_MEMZERO(range, sizeof(struct iw_range));
+
+ range->txpower_capa = 0;
+
+ range->min_pmp = 1 * 1024;
+ range->max_pmp = 65535 * 1024;
+ range->min_pmt = 1 * 1024;
+ range->max_pmt = 1000 * 1024;
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = 0;
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 13;
+
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->min_retry = 0;
+ range->max_retry = 255;
+
+ range->num_frequency = range->num_channels = ar->arNumChannels;
+ for (i = 0; i < ar->arNumChannels; i++) {
+ range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]);
+ range->freq[i].m = ar->arChannelList[i] * 100000;
+ range->freq[i].e = 1;
+ /*
+ * Linux supports max of 32 channels, bail out once you
+ * reach the max.
+ */
+ if (i == IW_MAX_FREQUENCIES) {
+ break;
+ }
+ }
+
+ /* Max quality is max field value minus noise floor */
+ range->max_qual.qual = 0xff - 161;
+
+ /*
+ * In order to use dBm measurements, 'level' must be lower
+ * than any possible measurement (see iw_print_stats() in
+ * wireless tools). It's unclear how this is meant to be
+ * done, but setting zero in these values forces dBm and
+ * the actual numbers are not used.
+ */
+ range->max_qual.level = 0;
+ range->max_qual.noise = 0;
+
+ range->sensitivity = 3;
+
+ range->max_encoding_tokens = 4;
+ /* XXX query driver to find out supported key sizes */
+ range->num_encoding_sizes = 3;
+ range->encoding_size[0] = 5; /* 40-bit */
+ range->encoding_size[1] = 13; /* 104-bit */
+ range->encoding_size[2] = 16; /* 128-bit */
+
+ range->num_bitrates = 0;
+
+ /* estimated maximum TCP throughput values (bps) */
+ range->throughput = 22000000;
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ up(&ar->arSem);
+
+ return ret;
+}
+
+
+/*
+ * SIOCSIWAP
+ * This ioctl is used to set the desired bssid for the connect command.
+ */
+int
+ar6000_ioctl_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ap_addr->sa_family != ARPHRD_ETHER) {
+ return -EIO;
+ }
+
+ if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) {
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ } else {
+ A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid));
+ }
+
+ return 0;
+}
+
+/*
+ * SIOCGIWAP
+ */
+int
+ar6000_ioctl_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arNetworkType == AP_NETWORK) {
+ A_MEMCPY(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN);
+ ap_addr->sa_family = ARPHRD_ETHER;
+ return 0;
+ }
+
+ if (ar->arConnected != TRUE) {
+ return -EINVAL;
+ }
+
+ A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid));
+ ap_addr->sa_family = ARPHRD_ETHER;
+
+ return 0;
+}
+
+#if (WIRELESS_EXT >= 18)
+/*
+ * SIOCSIWMLME
+ */
+int
+ar6000_ioctl_siwmlme(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->bIsDestroyProgress) {
+ return -EBUSY;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (down_interruptible(&ar->arSem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (data->pointer && data->length == sizeof(struct iw_mlme)) {
+
+ A_UINT8 arNetworkType;
+ struct iw_mlme mlme;
+
+ if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme)))
+ return -EIO;
+
+ switch (mlme.cmd) {
+
+ case IW_MLME_DEAUTH:
+ /* fall through */
+ case IW_MLME_DISASSOC:
+ if ((ar->arConnected != TRUE) ||
+ (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) {
+
+ up(&ar->arSem);
+ return -EINVAL;
+ }
+ wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
+ arNetworkType = ar->arNetworkType;
+ ar6000_init_profile_info(ar);
+ ar->arNetworkType = arNetworkType;
+ reconnect_flag = 0;
+ wmi_disconnect_cmd(ar->arWmi);
+ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+ ar->arSsidLen = 0;
+ if (ar->arSkipScan == FALSE) {
+ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+ }
+ break;
+
+ case IW_MLME_AUTH:
+ /* fall through */
+ case IW_MLME_ASSOC:
+ /* fall through */
+ default:
+ up(&ar->arSem);
+ return -EOPNOTSUPP;
+ }
+ }
+
+ up(&ar->arSem);
+ return 0;
+}
+#endif /* WIRELESS_EXT >= 18 */
+
+/*
+ * SIOCGIWAPLIST
+ */
+int
+ar6000_ioctl_iwaplist(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ return -EIO; /* for now */
+}
+
+/*
+ * SIOCSIWSCAN
+ */
+int
+ar6000_ioctl_siwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+#define ACT_DWELLTIME_DEFAULT 105
+#define HOME_TXDRAIN_TIME 100
+#define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+ int ret = 0;
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ /* If scan is issued in the middle of ongoing scan or connect,
+ dont issue another one */
+ if ( ar->scan_triggered > 0 ) {
+ ++ar->scan_triggered;
+ if (ar->scan_triggered < 5) {
+ return 0;
+ } else {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("Scan request is triggered over 5 times. Not scan complete event\n"));
+ }
+ }
+
+ if (!ar->arUserBssFilter) {
+ if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
+ return -EIO;
+ }
+ }
+
+ if (ar->arConnected) {
+ if (wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+ return -EIO;
+ }
+ }
+
+#ifdef ANDROID_ENV
+#if WIRELESS_EXT >= 18
+ if (data->pointer && (data->length == sizeof(struct iw_scan_req)))
+ {
+ if ((data->flags & IW_SCAN_THIS_ESSID) == IW_SCAN_THIS_ESSID)
+ {
+ struct iw_scan_req req;
+ if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req)))
+ return -EIO;
+ if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK)
+ return -EIO;
+ ar->scanSpecificSsid = 1;
+ }
+ else
+ {
+ if (ar->scanSpecificSsid) {
+ if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
+ return -EIO;
+ ar->scanSpecificSsid = 0;
+ }
+ }
+ }
+ else
+ {
+ if (ar->scanSpecificSsid) {
+ if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
+ return -EIO;
+ ar->scanSpecificSsid = 0;
+ }
+ }
+#endif
+#endif /* ANDROID_ENV */
+
+ if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, FALSE, FALSE, \
+ 0, 0, 0, NULL) != A_OK) {
+ ret = -EIO;
+ }
+
+ if (ret == 0) {
+ ar->scan_triggered = 1;
+ }
+
+ return ret;
+#undef ACT_DWELLTIME_DEFAULT
+#undef HOME_TXDRAIN_TIME
+#undef SCAN_INT
+}
+
+
+/*
+ * Units are in db above the noise floor. That means the
+ * rssi values reported in the tx/rx descriptors in the
+ * driver are the SNR expressed in db.
+ *
+ * If you assume that the noise floor is -95, which is an
+ * excellent assumption 99.5 % of the time, then you can
+ * derive the absolute signal level (i.e. -95 + rssi).
+ * There are some other slight factors to take into account
+ * depending on whether the rssi measurement is from 11b,
+ * 11g, or 11a. These differences are at most 2db and
+ * can be documented.
+ *
+ * NB: various calculations are based on the orinoco/wavelan
+ * drivers for compatibility
+ */
+static void
+ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi)
+{
+ if (rssi < 0) {
+ iq->qual = 0;
+ } else {
+ iq->qual = rssi;
+ }
+
+ /* NB: max is 94 because noise is hardcoded to 161 */
+ if (iq->qual > 94)
+ iq->qual = 94;
+
+ iq->noise = 161; /* -95dBm */
+ iq->level = iq->noise + iq->qual;
+ iq->updated = 7;
+}
+
+
+int
+ar6000_ioctl_siwcommit(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
+
+ if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
+ A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
+ return -EOPNOTSUPP;
+ }
+
+ if (ar->arWmiReady == FALSE) {
+ return -EIO;
+ }
+
+ if (ar->arWlanState == WLAN_DISABLED) {
+ return -EIO;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
+ " PW crypto %d GRP crypto %d\n",
+ ar->arSsid, ar->arChannelHint,
+ ar->arAuthMode, ar->arDot11AuthMode,
+ ar->arPairwiseCrypto, ar->arGroupCrypto));
+
+ ar6000_ap_mode_profile_commit(ar);
+
+ /* if there is a profile switch from STA|IBSS mode to AP mode,
+ * update the host driver association state for the STA|IBSS mode.
+ */
+ if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) {
+ ar->arConnectPending = FALSE;
+ ar->arConnected = FALSE;
+ /* Stop getting pkts from upper stack */
+ netif_stop_queue(ar->arNetDev);
+ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+ ar->arBssChannel = 0;
+ ar->arBeaconInterval = 0;
+
+ /* Flush the Tx queues */
+ ar6000_TxDataCleanup(ar);
+
+ /* Start getting pkts from upper stack */
+ netif_wake_queue(ar->arNetDev);
+ }
+
+ return 0;
+}
+
+#define W_PROTO(_x) wait_ ## _x
+#define WAIT_HANDLER_IMPL(_x, type) \
+int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
+ int ret; \
+ dev_hold(dev); \
+ rtnl_unlock(); \
+ ret = _x(dev, info, wrqu, extra); \
+ rtnl_lock(); \
+ dev_put(dev); \
+ return ret;\
+}
+
+WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid, struct iw_point *)
+WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate, struct iw_param *)
+WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow, struct iw_param *)
+WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange, struct iw_point*)
+
+/* Structures to export the Wireless Handlers */
+static const iw_handler ath_handlers[] = {
+ (iw_handler) ar6000_ioctl_siwcommit, /* SIOCSIWCOMMIT */
+ (iw_handler) ar6000_ioctl_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) ar6000_ioctl_siwmode, /* SIOCSIWMODE */
+ (iw_handler) ar6000_ioctl_giwmode, /* SIOCGIWMODE */
+ (iw_handler) ar6000_ioctl_siwsens, /* SIOCSIWSENS */
+ (iw_handler) ar6000_ioctl_giwsens, /* SIOCGIWSENS */
+ (iw_handler) NULL /* not _used */, /* SIOCSIWRANGE */
+ (iw_handler) W_PROTO(ar6000_ioctl_giwrange),/* SIOCGIWRANGE */
+ (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
+ (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+ (iw_handler) ar6000_ioctl_siwap, /* SIOCSIWAP */
+ (iw_handler) ar6000_ioctl_giwap, /* SIOCGIWAP */
+#if (WIRELESS_EXT >= 18)
+ (iw_handler) ar6000_ioctl_siwmlme, /* SIOCSIWMLME */
+#else
+ (iw_handler) NULL, /* -- hole -- */
+#endif /* WIRELESS_EXT >= 18 */
+ (iw_handler) ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */
+ (iw_handler) ar6000_ioctl_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) ar6000_ioctl_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) W_PROTO(ar6000_ioctl_siwessid),/* SIOCSIWESSID */
+ (iw_handler) ar6000_ioctl_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) NULL, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) ar6000_ioctl_siwrate, /* SIOCSIWRATE */
+ (iw_handler) W_PROTO(ar6000_ioctl_giwrate), /* SIOCGIWRATE */
+ (iw_handler) NULL, /* SIOCSIWRTS */
+ (iw_handler) NULL, /* SIOCGIWRTS */
+ (iw_handler) NULL, /* SIOCSIWFRAG */
+ (iw_handler) NULL, /* SIOCGIWFRAG */
+ (iw_handler) ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */
+ (iw_handler) W_PROTO(ar6000_ioctl_giwtxpow),/* SIOCGIWTXPOW */
+ (iw_handler) ar6000_ioctl_siwretry, /* SIOCSIWRETRY */
+ (iw_handler) ar6000_ioctl_giwretry, /* SIOCGIWRETRY */
+ (iw_handler) ar6000_ioctl_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) ar6000_ioctl_giwencode, /* SIOCGIWENCODE */
+#if WIRELESS_EXT > 20
+ (iw_handler) ar6000_ioctl_siwpower, /* SIOCSIWPOWER */
+ (iw_handler) ar6000_ioctl_giwpower, /* SIOCGIWPOWER */
+#endif // WIRELESS_EXT > 20
+#if WIRELESS_EXT >= 18
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */
+ (iw_handler) ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */
+ (iw_handler) ar6000_ioctl_siwauth, /* SIOCSIWAUTH */
+ (iw_handler) ar6000_ioctl_giwauth, /* SIOCGIWAUTH */
+ (iw_handler) ar6000_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) ar6000_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) ar6000_ioctl_siwpmksa, /* SIOCSIWPMKSA */
+#endif // WIRELESS_EXT >= 18
+};
+
+struct iw_handler_def ath_iw_handler_def = {
+ .standard = (iw_handler *)ath_handlers,
+ .num_standard = ARRAY_SIZE(ath_handlers),
+ .private = NULL,
+ .num_private = 0,
+};
diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
new file mode 100644
index 000000000000..5dbf8f86f713
--- /dev/null
+++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ *
+//
+// 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 __AGGR_RX_INTERNAL_H__
+#define __AGGR_RX_INTERNAL_H__
+
+#include "a_osapi.h"
+#include "aggr_recv_api.h"
+
+#define AGGR_WIN_IDX(x, y) ((x) % (y))
+#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x)+1), (y))
+#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x)-1), (y))
+#define IEEE80211_MAX_SEQ_NO 0xFFF
+#define IEEE80211_NEXT_SEQ_NO(x) (((x) + 1) & IEEE80211_MAX_SEQ_NO)
+
+
+#define NUM_OF_TIDS 8
+#define AGGR_SZ_DEFAULT 8
+
+#define AGGR_WIN_SZ_MIN 2
+#define AGGR_WIN_SZ_MAX 8
+/* TID Window sz is double of what is negotiated. Derive TID_WINDOW_SZ from win_sz, per tid */
+#define TID_WINDOW_SZ(_x) ((_x) << 1)
+
+#define AGGR_NUM_OF_FREE_NETBUFS 16
+
+#define AGGR_GET_RXTID_STATS(_p, _x) (&(_p->stat[(_x)]))
+#define AGGR_GET_RXTID(_p, _x) (&(_p->RxTid[(_x)]))
+
+/* Hold q is a function of win_sz, which is negotiated per tid */
+#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(OSBUF_HOLD_Q))
+/* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be
+ * delivered out of order and a (too) large value can cause undesirable latency in
+ * certain situations. */
+#define AGGR_RX_TIMEOUT 400 /* Timeout(in ms) for delivery of frames, if they are stuck */
+
+typedef enum {
+ ALL_SEQNO = 0,
+ CONTIGUOUS_SEQNO = 1,
+}DELIVERY_ORDER;
+
+typedef struct {
+ void *osbuf;
+ A_BOOL is_amsdu;
+ A_UINT16 seq_no;
+}OSBUF_HOLD_Q;
+
+
+#if 0
+typedef struct {
+ A_UINT16 seqno_st;
+ A_UINT16 seqno_end;
+}WINDOW_SNAPSHOT;
+#endif
+
+typedef struct {
+ A_BOOL aggr; /* is it ON or OFF */
+ A_BOOL progress; /* TRUE when frames have arrived after a timer start */
+ A_BOOL timerMon; /* TRUE if the timer started for the sake of this TID */
+ A_UINT16 win_sz; /* negotiated window size */
+ A_UINT16 seq_next; /* Next seq no, in current window */
+ A_UINT32 hold_q_sz; /* Num of frames that can be held in hold q */
+ OSBUF_HOLD_Q *hold_q; /* Hold q for re-order */
+#if 0
+ WINDOW_SNAPSHOT old_win; /* Sliding window snapshot - for timeout */
+#endif
+ A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */
+ A_MUTEX_T lock;
+}RXTID;
+
+typedef struct {
+ A_UINT32 num_into_aggr; /* hitting at the input of this module */
+ A_UINT32 num_dups; /* duplicate */
+ A_UINT32 num_oow; /* out of window */
+ A_UINT32 num_mpdu; /* single payload 802.3/802.11 frame */
+ A_UINT32 num_amsdu; /* AMSDU */
+ A_UINT32 num_delivered; /* frames delivered to IP stack */
+ A_UINT32 num_timeouts; /* num of timeouts, during which frames delivered */
+ A_UINT32 num_hole; /* frame not present, when window moved over */
+ A_UINT32 num_bar; /* num of resets of seq_num, via BAR */
+}RXTID_STATS;
+
+typedef struct {
+ A_UINT8 aggr_sz; /* config value of aggregation size */
+ A_UINT8 timerScheduled;
+ A_TIMER timer; /* timer for returning held up pkts in re-order que */
+ void *dev; /* dev handle */
+ RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */
+ RXTID RxTid[NUM_OF_TIDS]; /* Per tid window */
+ ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */
+ A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */
+ RXTID_STATS stat[NUM_OF_TIDS]; /* Tid based statistics */
+ PACKET_LOG pkt_log; /* Log info of the packets */
+}AGGR_INFO;
+
+#endif /* __AGGR_RX_INTERNAL_H__ */
diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c
new file mode 100644
index 000000000000..092bb3007c5d
--- /dev/null
+++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c
@@ -0,0 +1,666 @@
+/*
+ *
+ * Copyright (c) 2010 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ *
+//
+// 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.
+//
+//
+ *
+ */
+
+#ifdef ATH_AR6K_11N_SUPPORT
+
+#include <a_config.h>
+#include <athdefs.h>
+#include <a_types.h>
+#include <a_osapi.h>
+#include <a_debug.h>
+#include "pkt_log.h"
+#include "aggr_recv_api.h"
+#include "aggr_rx_internal.h"
+#include "wmi.h"
+
+extern A_STATUS
+wmi_dot3_2_dix(void *osbuf);
+
+static void
+aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf);
+
+static void
+aggr_timeout(A_ATH_TIMER arg);
+
+static void
+aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order);
+
+static void
+aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q);
+
+static void *
+aggr_get_osbuf(AGGR_INFO *p_aggr);
+
+void *
+aggr_init(ALLOC_NETBUFS netbuf_allocator)
+{
+ AGGR_INFO *p_aggr = NULL;
+ RXTID *rxtid;
+ A_UINT8 i;
+ A_STATUS status = A_OK;
+
+ A_PRINTF("In aggr_init..\n");
+
+ do {
+ p_aggr = A_MALLOC(sizeof(AGGR_INFO));
+ if(!p_aggr) {
+ A_PRINTF("Failed to allocate memory for aggr_node\n");
+ status = A_ERROR;
+ break;
+ }
+
+ /* Init timer and data structures */
+ A_MEMZERO(p_aggr, sizeof(AGGR_INFO));
+ p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
+ A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr);
+ p_aggr->timerScheduled = FALSE;
+ A_NETBUF_QUEUE_INIT(&p_aggr->freeQ);
+
+ p_aggr->netbuf_allocator = netbuf_allocator;
+ p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
+
+ for(i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = AGGR_GET_RXTID(p_aggr, i);
+ rxtid->aggr = FALSE;
+ rxtid->progress = FALSE;
+ rxtid->timerMon = FALSE;
+ A_NETBUF_QUEUE_INIT(&rxtid->q);
+ A_MUTEX_INIT(&rxtid->lock);
+ }
+ }while(FALSE);
+
+ A_PRINTF("going out of aggr_init..status %s\n",
+ (status == A_OK) ? "OK":"Error");
+
+ if(status != A_OK) {
+ /* Cleanup */
+ aggr_module_destroy(p_aggr);
+ }
+ return ((status == A_OK) ? p_aggr : NULL);
+}
+
+/* utility function to clear rx hold_q for a tid */
+static void
+aggr_delete_tid_state(AGGR_INFO *p_aggr, A_UINT8 tid)
+{
+ RXTID *rxtid;
+ RXTID_STATS *stats;
+
+ A_ASSERT(tid < NUM_OF_TIDS && p_aggr);
+
+ rxtid = AGGR_GET_RXTID(p_aggr, tid);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
+
+ if(rxtid->aggr) {
+ aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
+ }
+
+ rxtid->aggr = FALSE;
+ rxtid->progress = FALSE;
+ rxtid->timerMon = FALSE;
+ rxtid->win_sz = 0;
+ rxtid->seq_next = 0;
+ rxtid->hold_q_sz = 0;
+
+ if(rxtid->hold_q) {
+ A_FREE(rxtid->hold_q);
+ rxtid->hold_q = NULL;
+ }
+
+ A_MEMZERO(stats, sizeof(RXTID_STATS));
+}
+
+void
+aggr_module_destroy(void *cntxt)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID *rxtid;
+ A_UINT8 i, k;
+ A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr);
+ A_ASSERT(p_aggr);
+
+ if(p_aggr) {
+ if(p_aggr->timerScheduled) {
+ A_UNTIMEOUT(&p_aggr->timer);
+ p_aggr->timerScheduled = FALSE;
+ }
+
+ for(i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = AGGR_GET_RXTID(p_aggr, i);
+ /* Free the hold q contents and hold_q*/
+ if(rxtid->hold_q) {
+ for(k = 0; k< rxtid->hold_q_sz; k++) {
+ if(rxtid->hold_q[k].osbuf) {
+ A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
+ }
+ }
+ A_FREE(rxtid->hold_q);
+ }
+ /* Free the dispatch q contents*/
+ while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
+ A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q));
+ }
+ if (A_IS_MUTEX_VALID(&rxtid->lock)) {
+ A_MUTEX_DELETE(&rxtid->lock);
+ }
+ }
+ /* free the freeQ and its contents*/
+ while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
+ A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
+ }
+ A_FREE(p_aggr);
+ }
+ A_PRINTF("out aggr_module_destroy\n");
+}
+
+
+void
+aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+
+ A_ASSERT(p_aggr && fn && dev);
+
+ p_aggr->rx_fn = fn;
+ p_aggr->dev = dev;
+}
+
+
+void
+aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID_STATS *stats;
+
+ A_ASSERT(p_aggr);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
+ stats->num_bar++;
+
+ aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO);
+}
+
+
+void
+aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_sz)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID *rxtid;
+ RXTID_STATS *stats;
+
+ A_ASSERT(p_aggr);
+ rxtid = AGGR_GET_RXTID(p_aggr, tid);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
+
+ A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr);
+ if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) {
+ A_PRINTF("win_sz %d, tid %d\n", win_sz, tid);
+ }
+
+ if(rxtid->aggr) {
+ /* Just go and deliver all the frames up from this
+ * queue, as if we got DELBA and re-initialize the queue
+ */
+ aggr_delete_tid_state(p_aggr, tid);
+ }
+
+ rxtid->seq_next = seq_no;
+ /* create these queues, only upon receiving of ADDBA for a
+ * tid, reducing memory requirement
+ */
+ rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz));
+ if((rxtid->hold_q == NULL)) {
+ A_PRINTF("Failed to allocate memory, tid = %d\n", tid);
+ A_ASSERT(0);
+ }
+ A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz));
+
+ /* Update rxtid for the window sz */
+ rxtid->win_sz = win_sz;
+ /* hold_q_sz inicates the depth of holding q - which is
+ * a factor of win_sz. Compute once, as it will be used often
+ */
+ rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
+ /* There should be no frames on q - even when second ADDBA comes in.
+ * If aggr was previously ON on this tid, we would have cleaned up
+ * the q
+ */
+ if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) {
+ A_PRINTF("ERROR: Frames still on queue ?\n");
+ A_ASSERT(0);
+ }
+
+ rxtid->aggr = TRUE;
+}
+
+void
+aggr_recv_delba_req_evt(void *cntxt, A_UINT8 tid)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID *rxtid;
+
+ A_ASSERT(p_aggr);
+ A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid);
+
+ rxtid = AGGR_GET_RXTID(p_aggr, tid);
+
+ if(rxtid->aggr) {
+ aggr_delete_tid_state(p_aggr, tid);
+ }
+}
+
+static void
+aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order)
+{
+ RXTID *rxtid;
+ OSBUF_HOLD_Q *node;
+ A_UINT16 idx, idx_end, seq_end;
+ RXTID_STATS *stats;
+
+ A_ASSERT(p_aggr);
+ rxtid = AGGR_GET_RXTID(p_aggr, tid);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
+
+ /* idx is absolute location for first frame */
+ idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+
+ /* idx_end is typically the last possible frame in the window,
+ * but changes to 'the' seq_no, when BAR comes. If seq_no
+ * is non-zero, we will go up to that and stop.
+ * Note: last seq no in current window will occupy the same
+ * index position as index that is just previous to start.
+ * An imp point : if win_sz is 7, for seq_no space of 4095,
+ * then, there would be holes when sequence wrap around occurs.
+ * Target should judiciously choose the win_sz, based on
+ * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
+ * 2, 4, 8, 16 win_sz works fine).
+ * We must deque from "idx" to "idx_end", including both.
+ */
+ seq_end = (seq_no) ? seq_no : rxtid->seq_next;
+ idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
+
+ /* Critical section begins */
+ A_MUTEX_LOCK(&rxtid->lock);
+ do {
+
+ node = &rxtid->hold_q[idx];
+
+ if((order == CONTIGUOUS_SEQNO) && (!node->osbuf))
+ break;
+
+ /* chain frames and deliver frames bcos:
+ * 1. either the frames are in order and window is contiguous, OR
+ * 2. we need to deque frames, irrespective of holes
+ */
+ if(node->osbuf) {
+ if(node->is_amsdu) {
+ aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf);
+ } else {
+ A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf);
+ }
+ node->osbuf = NULL;
+ } else {
+ stats->num_hole++;
+ }
+
+ /* window is moving */
+ rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next);
+ idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+ } while(idx != idx_end);
+ /* Critical section ends */
+ A_MUTEX_UNLOCK(&rxtid->lock);
+
+ stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q);
+ aggr_dispatch_frames(p_aggr, &rxtid->q);
+}
+
+static void *
+aggr_get_osbuf(AGGR_INFO *p_aggr)
+{
+ void *buf = NULL;
+
+ /* Starving for buffers? get more from OS
+ * check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) :
+ * re-allocate bufs if so
+ * allocate a free buf from freeQ
+ */
+ if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) {
+ p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS);
+ }
+
+ if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
+ buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ);
+ }
+
+ return buf;
+}
+
+
+static void
+aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf)
+{
+ void *new_buf;
+ A_UINT16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
+ A_UINT8 *framep;
+
+ /* Frame format at this point:
+ * [DIX hdr | 802.3 | 802.3 | ... | 802.3]
+ *
+ * Strip the DIX header.
+ * Iterate through the osbuf and do:
+ * grab a free netbuf from freeQ
+ * find the start and end of a frame
+ * copy it to netbuf(Vista can do better here)
+ * convert all msdu's(802.3) frames to upper layer format - os routine
+ * -for now lets convert from 802.3 to dix
+ * enque this to dispatch q of tid
+ * repeat
+ * free the osbuf - to OS. It's been sliced.
+ */
+
+ mac_hdr_len = sizeof(ATH_MAC_HDR);
+ framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len;
+ amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len;
+
+ while(amsdu_len > mac_hdr_len) {
+ /* Begin of a 802.3 frame */
+ payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen);
+#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
+#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
+ if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
+ A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len);
+ break;
+ }
+ frame_8023_len = payload_8023_len + mac_hdr_len;
+ new_buf = aggr_get_osbuf(p_aggr);
+ if(new_buf == NULL) {
+ A_PRINTF("No buffer available \n");
+ break;
+ }
+
+ A_MEMCPY(A_NETBUF_DATA(new_buf), framep, frame_8023_len);
+ A_NETBUF_PUT(new_buf, frame_8023_len);
+ if (wmi_dot3_2_dix(new_buf) != A_OK) {
+ A_PRINTF("dot3_2_dix err..\n");
+ A_NETBUF_FREE(new_buf);
+ break;
+ }
+
+ A_NETBUF_ENQUEUE(&rxtid->q, new_buf);
+
+ /* Is this the last subframe within this aggregate ? */
+ if ((amsdu_len - frame_8023_len) == 0) {
+ break;
+ }
+
+ /* Add the length of A-MSDU subframe padding bytes -
+ * Round to nearest word.
+ */
+ frame_8023_len = ((frame_8023_len + 3) & ~3);
+
+ framep += frame_8023_len;
+ amsdu_len -= frame_8023_len;
+ }
+
+ A_NETBUF_FREE(*osbuf);
+ *osbuf = NULL;
+}
+
+void
+aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID *rxtid;
+ RXTID_STATS *stats;
+ A_UINT16 idx, st, cur, end;
+ A_UINT16 *log_idx;
+ OSBUF_HOLD_Q *node;
+ PACKET_LOG *log;
+
+ A_ASSERT(p_aggr);
+ A_ASSERT(tid < NUM_OF_TIDS);
+
+ rxtid = AGGR_GET_RXTID(p_aggr, tid);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, tid);
+
+ stats->num_into_aggr++;
+
+ if(!rxtid->aggr) {
+ if(is_amsdu) {
+ aggr_slice_amsdu(p_aggr, rxtid, osbuf);
+ stats->num_amsdu++;
+ aggr_dispatch_frames(p_aggr, &rxtid->q);
+ }
+ return;
+ }
+
+ /* Check the incoming sequence no, if it's in the window */
+ st = rxtid->seq_next;
+ cur = seq_no;
+ end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
+ /* Log the pkt info for future analysis */
+ log = &p_aggr->pkt_log;
+ log_idx = &log->last_idx;
+ log->info[*log_idx].cur = cur;
+ log->info[*log_idx].st = st;
+ log->info[*log_idx].end = end;
+ *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx);
+
+ if(((st < end) && (cur < st || cur > end)) ||
+ ((st > end) && (cur > end) && (cur < st))) {
+ /* the cur frame is outside the window. Since we know
+ * our target would not do this without reason it must
+ * be assumed that the window has moved for some valid reason.
+ * Therefore, we dequeue all frames and start fresh.
+ */
+ A_UINT16 extended_end;
+
+ extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO;
+
+ if(((end < extended_end) && (cur < end || cur > extended_end)) ||
+ ((end > extended_end) && (cur > extended_end) && (cur < end))) {
+ // dequeue all frames in queue and shift window to new frame
+ aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO);
+ //set window start so that new frame is last frame in window
+ if(cur >= rxtid->hold_q_sz-1) {
+ rxtid->seq_next = cur - (rxtid->hold_q_sz-1);
+ }else{
+ rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
+ }
+ } else {
+ // dequeue only those frames that are outside the new shifted window
+ if(cur >= rxtid->hold_q_sz-1) {
+ st = cur - (rxtid->hold_q_sz-1);
+ }else{
+ st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur);
+ }
+
+ aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO);
+ }
+
+ stats->num_oow++;
+ }
+
+ idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
+
+ /*enque the frame, in hold_q */
+ node = &rxtid->hold_q[idx];
+
+ A_MUTEX_LOCK(&rxtid->lock);
+ if(node->osbuf) {
+ /* Is the cur frame duplicate or something beyond our
+ * window(hold_q -> which is 2x, already)?
+ * 1. Duplicate is easy - drop incoming frame.
+ * 2. Not falling in current sliding window.
+ * 2a. is the frame_seq_no preceding current tid_seq_no?
+ * -> drop the frame. perhaps sender did not get our ACK.
+ * this is taken care of above.
+ * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
+ * -> Taken care of it above, by moving window forward.
+ *
+ */
+ A_NETBUF_FREE(node->osbuf);
+ stats->num_dups++;
+ }
+
+ node->osbuf = *osbuf;
+ node->is_amsdu = is_amsdu;
+ node->seq_no = seq_no;
+ if(node->is_amsdu) {
+ stats->num_amsdu++;
+ } else {
+ stats->num_mpdu++;
+ }
+ A_MUTEX_UNLOCK(&rxtid->lock);
+
+ *osbuf = NULL;
+ aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO);
+
+ if(p_aggr->timerScheduled) {
+ rxtid->progress = TRUE;
+ }else{
+ for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) {
+ if(rxtid->hold_q[idx].osbuf) {
+ /* there is a frame in the queue and no timer so
+ * start a timer to ensure that the frame doesn't remain
+ * stuck forever. */
+ p_aggr->timerScheduled = TRUE;
+ A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
+ rxtid->progress = FALSE;
+ rxtid->timerMon = TRUE;
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate
+ * hold Q state. Examples include when a Connect event or disconnect event is
+ * received.
+ */
+void
+aggr_reset_state(void *cntxt)
+{
+ A_UINT8 tid;
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+
+ A_ASSERT(p_aggr);
+
+ for(tid=0 ; tid<NUM_OF_TIDS ; tid++) {
+ aggr_delete_tid_state(p_aggr, tid);
+ }
+}
+
+
+static void
+aggr_timeout(A_ATH_TIMER arg)
+{
+ A_UINT8 i,j;
+ AGGR_INFO *p_aggr = (AGGR_INFO *)arg;
+ RXTID *rxtid;
+ RXTID_STATS *stats;
+ /*
+ * If the q for which the timer was originally started has
+ * not progressed then it is necessary to dequeue all the
+ * contained frames so that they are not held forever.
+ */
+ for(i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = AGGR_GET_RXTID(p_aggr, i);
+ stats = AGGR_GET_RXTID_STATS(p_aggr, i);
+
+ if(rxtid->aggr == FALSE ||
+ rxtid->timerMon == FALSE ||
+ rxtid->progress == TRUE) {
+ continue;
+ }
+ // dequeue all frames in for this tid
+ stats->num_timeouts++;
+ A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO));
+ aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO);
+ }
+
+ p_aggr->timerScheduled = FALSE;
+ // determine whether a new timer should be started.
+ for(i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = AGGR_GET_RXTID(p_aggr, i);
+
+ if(rxtid->aggr == TRUE && rxtid->hold_q) {
+ for(j = 0 ; j < rxtid->hold_q_sz ; j++)
+ {
+ if(rxtid->hold_q[j].osbuf)
+ {
+ p_aggr->timerScheduled = TRUE;
+ rxtid->timerMon = TRUE;
+ rxtid->progress = FALSE;
+ break;
+ }
+ }
+
+ if(j >= rxtid->hold_q_sz) {
+ rxtid->timerMon = FALSE;
+ }
+ }
+ }
+
+ if(p_aggr->timerScheduled) {
+ /* Rearm the timer*/
+ A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0);
+ }
+
+}
+
+static void
+aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q)
+{
+ void *osbuf;
+
+ while((osbuf = A_NETBUF_DEQUEUE(q))) {
+ p_aggr->rx_fn(p_aggr->dev, osbuf);
+ }
+}
+
+void
+aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf)
+{
+ AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt;
+ RXTID *rxtid;
+ RXTID_STATS *stats;
+ A_UINT8 i;
+
+ *log_buf = &p_aggr->pkt_log;
+ A_PRINTF("\n\n================================================\n");
+ A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n");
+ for(i = 0; i < NUM_OF_TIDS; i++) {
+ stats = AGGR_GET_RXTID_STATS(p_aggr, i);
+ rxtid = AGGR_GET_RXTID(p_aggr, i);
+ A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups,
+ stats->num_oow, stats->num_mpdu,
+ stats->num_amsdu, stats->num_delivered, stats->num_timeouts,
+ stats->num_hole, stats->num_bar,
+ rxtid->seq_next);
+ }
+ A_PRINTF("================================================\n\n");
+
+}
+
+#endif /* ATH_AR6K_11N_SUPPORT */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h
new file mode 100644
index 000000000000..c4fd13fe0a91
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h
@@ -0,0 +1,401 @@
+//------------------------------------------------------------------------------
+// <copyright file="ieee80211.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _NET80211_IEEE80211_H_
+#define _NET80211_IEEE80211_H_
+
+#include "athstartpack.h"
+
+/*
+ * 802.11 protocol definitions.
+ */
+#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
+#define IEEE80211_WEP_IVLEN 3 /* 24bit */
+#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
+#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
+#define IEEE80211_WEP_NKID 4 /* number of key ids */
+
+/*
+ * 802.11i defines an extended IV for use with non-WEP ciphers.
+ * When the EXTIV bit is set in the key id byte an additional
+ * 4 bytes immediately follow the IV for TKIP. For CCMP the
+ * EXTIV bit is likewise set but the 8 bytes represent the
+ * CCMP header rather than IV+extended-IV.
+ */
+#define IEEE80211_WEP_EXTIV 0x20
+#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */
+#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */
+
+#define IEEE80211_CRC_LEN 4
+
+#ifdef WAPI_ENABLE
+#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */
+#endif /* WAPI ENABLE */
+
+
+#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
+/* is 802.11 address multicast/broadcast? */
+#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
+#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF)
+#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
+#define WEP_TRAILER IEEE80211_WEP_CRCLEN
+#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
+ IEEE80211_WEP_EXTIVLEN)
+#define CCMP_TRAILER IEEE80211_WEP_MICLEN
+#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \
+ IEEE80211_WEP_EXTIVLEN)
+#define TKIP_TRAILER IEEE80211_WEP_CRCLEN
+#define TKIP_MICLEN IEEE80211_WEP_MICLEN
+
+
+#define IEEE80211_ADDR_EQ(addr1, addr2) \
+ (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
+
+#define IEEE80211_ADDR_COPY(dst,src) A_MEMCPY(dst,src,IEEE80211_ADDR_LEN)
+
+#define IEEE80211_KEYBUF_SIZE 16
+#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */
+
+/*
+ * NB: these values are ordered carefully; there are lots of
+ * of implications in any reordering. In particular beware
+ * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
+ */
+#define IEEE80211_CIPHER_WEP 0
+#define IEEE80211_CIPHER_TKIP 1
+#define IEEE80211_CIPHER_AES_OCB 2
+#define IEEE80211_CIPHER_AES_CCM 3
+#define IEEE80211_CIPHER_CKIP 5
+#define IEEE80211_CIPHER_CCKM_KRK 6
+#define IEEE80211_CIPHER_NONE 7 /* pseudo value */
+
+#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
+
+#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
+ (((len) == 5) || ((len) == 13) || ((len) == 16))
+
+
+
+/*
+ * generic definitions for IEEE 802.11 frames
+ */
+PREPACK struct ieee80211_frame {
+ A_UINT8 i_fc[2];
+ A_UINT8 i_dur[2];
+ A_UINT8 i_addr1[IEEE80211_ADDR_LEN];
+ A_UINT8 i_addr2[IEEE80211_ADDR_LEN];
+ A_UINT8 i_addr3[IEEE80211_ADDR_LEN];
+ A_UINT8 i_seq[2];
+ /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
+ /* see below */
+} POSTPACK;
+
+PREPACK struct ieee80211_qosframe {
+ A_UINT8 i_fc[2];
+ A_UINT8 i_dur[2];
+ A_UINT8 i_addr1[IEEE80211_ADDR_LEN];
+ A_UINT8 i_addr2[IEEE80211_ADDR_LEN];
+ A_UINT8 i_addr3[IEEE80211_ADDR_LEN];
+ A_UINT8 i_seq[2];
+ A_UINT8 i_qos[2];
+} POSTPACK;
+
+#define IEEE80211_FC0_VERSION_MASK 0x03
+#define IEEE80211_FC0_VERSION_SHIFT 0
+#define IEEE80211_FC0_VERSION_0 0x00
+#define IEEE80211_FC0_TYPE_MASK 0x0c
+#define IEEE80211_FC0_TYPE_SHIFT 2
+#define IEEE80211_FC0_TYPE_MGT 0x00
+#define IEEE80211_FC0_TYPE_CTL 0x04
+#define IEEE80211_FC0_TYPE_DATA 0x08
+
+#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
+#define IEEE80211_FC0_SUBTYPE_SHIFT 4
+/* for TYPE_MGT */
+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
+#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
+#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
+#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
+#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
+#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
+/* for TYPE_CTL */
+#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
+#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
+#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
+#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
+#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
+#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
+/* for TYPE_DATA (bit combination) */
+#define IEEE80211_FC0_SUBTYPE_DATA 0x00
+#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
+#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
+#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
+#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
+#define IEEE80211_FC0_SUBTYPE_CFACK 0x50
+#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60
+#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
+#define IEEE80211_FC0_SUBTYPE_QOS 0x80
+#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
+
+#define IEEE80211_FC1_DIR_MASK 0x03
+#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
+#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
+#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
+#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
+
+#define IEEE80211_FC1_MORE_FRAG 0x04
+#define IEEE80211_FC1_RETRY 0x08
+#define IEEE80211_FC1_PWR_MGT 0x10
+#define IEEE80211_FC1_MORE_DATA 0x20
+#define IEEE80211_FC1_WEP 0x40
+#define IEEE80211_FC1_ORDER 0x80
+
+#define IEEE80211_SEQ_FRAG_MASK 0x000f
+#define IEEE80211_SEQ_FRAG_SHIFT 0
+#define IEEE80211_SEQ_SEQ_MASK 0xfff0
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+
+#define IEEE80211_NWID_LEN 32
+
+/*
+ * 802.11 rate set.
+ */
+#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
+#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
+
+#define WMM_NUM_AC 4 /* 4 AC categories */
+
+#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */
+#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */
+#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */
+#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */
+#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */
+#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */
+#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */
+#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */
+
+#define WMM_AC_TO_TID(_ac) ( \
+ ((_ac) == WMM_AC_VO) ? 6 : \
+ ((_ac) == WMM_AC_VI) ? 5 : \
+ ((_ac) == WMM_AC_BK) ? 1 : \
+ 0)
+
+#define TID_TO_WMM_AC(_tid) ( \
+ ((_tid) < 1) ? WMM_AC_BE : \
+ ((_tid) < 3) ? WMM_AC_BK : \
+ ((_tid) < 6) ? WMM_AC_VI : \
+ WMM_AC_VO)
+/*
+ * Management information element payloads.
+ */
+
+enum {
+ IEEE80211_ELEMID_SSID = 0,
+ IEEE80211_ELEMID_RATES = 1,
+ IEEE80211_ELEMID_FHPARMS = 2,
+ IEEE80211_ELEMID_DSPARMS = 3,
+ IEEE80211_ELEMID_CFPARMS = 4,
+ IEEE80211_ELEMID_TIM = 5,
+ IEEE80211_ELEMID_IBSSPARMS = 6,
+ IEEE80211_ELEMID_COUNTRY = 7,
+ IEEE80211_ELEMID_CHALLENGE = 16,
+ /* 17-31 reserved for challenge text extension */
+ IEEE80211_ELEMID_PWRCNSTR = 32,
+ IEEE80211_ELEMID_PWRCAP = 33,
+ IEEE80211_ELEMID_TPCREQ = 34,
+ IEEE80211_ELEMID_TPCREP = 35,
+ IEEE80211_ELEMID_SUPPCHAN = 36,
+ IEEE80211_ELEMID_CHANSWITCH = 37,
+ IEEE80211_ELEMID_MEASREQ = 38,
+ IEEE80211_ELEMID_MEASREP = 39,
+ IEEE80211_ELEMID_QUIET = 40,
+ IEEE80211_ELEMID_IBSSDFS = 41,
+ IEEE80211_ELEMID_ERP = 42,
+ IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */
+ IEEE80211_ELEMID_RSN = 48,
+ IEEE80211_ELEMID_XRATES = 50,
+ IEEE80211_ELEMID_HTINFO_ANA = 61,
+#ifdef WAPI_ENABLE
+ IEEE80211_ELEMID_WAPI = 68,
+#endif
+ IEEE80211_ELEMID_TPC = 150,
+ IEEE80211_ELEMID_CCKM = 156,
+ IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
+};
+
+#define ATH_OUI 0x7f0300 /* Atheros OUI */
+#define ATH_OUI_TYPE 0x01
+#define ATH_OUI_SUBTYPE 0x01
+#define ATH_OUI_VERSION 0x00
+
+#define WPA_OUI 0xf25000
+#define WPA_OUI_TYPE 0x01
+#define WPA_VERSION 1 /* current supported version */
+
+#define WPA_CSE_NULL 0x00
+#define WPA_CSE_WEP40 0x01
+#define WPA_CSE_TKIP 0x02
+#define WPA_CSE_CCMP 0x04
+#define WPA_CSE_WEP104 0x05
+
+#define WPA_ASE_NONE 0x00
+#define WPA_ASE_8021X_UNSPEC 0x01
+#define WPA_ASE_8021X_PSK 0x02
+
+#define RSN_OUI 0xac0f00
+#define RSN_VERSION 1 /* current supported version */
+
+#define RSN_CSE_NULL 0x00
+#define RSN_CSE_WEP40 0x01
+#define RSN_CSE_TKIP 0x02
+#define RSN_CSE_WRAP 0x03
+#define RSN_CSE_CCMP 0x04
+#define RSN_CSE_WEP104 0x05
+
+#define RSN_ASE_NONE 0x00
+#define RSN_ASE_8021X_UNSPEC 0x01
+#define RSN_ASE_8021X_PSK 0x02
+
+#define RSN_CAP_PREAUTH 0x01
+
+#define WMM_OUI 0xf25000
+#define WMM_OUI_TYPE 0x02
+#define WMM_INFO_OUI_SUBTYPE 0x00
+#define WMM_PARAM_OUI_SUBTYPE 0x01
+#define WMM_VERSION 1
+
+/* WMM stream classes */
+#define WMM_NUM_AC 4
+#define WMM_AC_BE 0 /* best effort */
+#define WMM_AC_BK 1 /* background */
+#define WMM_AC_VI 2 /* video */
+#define WMM_AC_VO 3 /* voice */
+
+/* TSPEC related */
+#define ACTION_CATEGORY_CODE_TSPEC 17
+#define ACTION_CODE_TSPEC_ADDTS 0
+#define ACTION_CODE_TSPEC_ADDTS_RESP 1
+#define ACTION_CODE_TSPEC_DELTS 2
+
+typedef enum {
+ TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
+ TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
+ TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
+ TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
+ TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
+ TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
+ TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
+ TSPEC_STATUS_CODE_DELTS_SENT = 0x30,
+ TSPEC_STATUS_CODE_DELTS_RECV = 0x31,
+} TSPEC_STATUS_CODE;
+
+#define TSPEC_TSID_MASK 0xF
+#define TSPEC_TSID_S 1
+
+/*
+ * WMM/802.11e Tspec Element
+ */
+typedef PREPACK struct wmm_tspec_ie_t {
+ A_UINT8 elementId;
+ A_UINT8 len;
+ A_UINT8 oui[3];
+ A_UINT8 ouiType;
+ A_UINT8 ouiSubType;
+ A_UINT8 version;
+ A_UINT16 tsInfo_info;
+ A_UINT8 tsInfo_reserved;
+ A_UINT16 nominalMSDU;
+ A_UINT16 maxMSDU;
+ A_UINT32 minServiceInt;
+ A_UINT32 maxServiceInt;
+ A_UINT32 inactivityInt;
+ A_UINT32 suspensionInt;
+ A_UINT32 serviceStartTime;
+ A_UINT32 minDataRate;
+ A_UINT32 meanDataRate;
+ A_UINT32 peakDataRate;
+ A_UINT32 maxBurstSize;
+ A_UINT32 delayBound;
+ A_UINT32 minPhyRate;
+ A_UINT16 sba;
+ A_UINT16 mediumTime;
+} POSTPACK WMM_TSPEC_IE;
+
+
+/*
+ * BEACON management packets
+ *
+ * octet timestamp[8]
+ * octet beacon interval[2]
+ * octet capability information[2]
+ * information element
+ * octet elemid
+ * octet length
+ * octet information[length]
+ */
+
+#define IEEE80211_BEACON_INTERVAL(beacon) \
+ ((beacon)[8] | ((beacon)[9] << 8))
+#define IEEE80211_BEACON_CAPABILITY(beacon) \
+ ((beacon)[10] | ((beacon)[11] << 8))
+
+#define IEEE80211_CAPINFO_ESS 0x0001
+#define IEEE80211_CAPINFO_IBSS 0x0002
+#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004
+#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008
+#define IEEE80211_CAPINFO_PRIVACY 0x0010
+#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020
+#define IEEE80211_CAPINFO_PBCC 0x0040
+#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080
+/* bits 8-9 are reserved */
+#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400
+#define IEEE80211_CAPINFO_APSD 0x0800
+/* bit 12 is reserved */
+#define IEEE80211_CAPINFO_DSSSOFDM 0x2000
+/* bits 14-15 are reserved */
+
+/*
+ * Authentication Modes
+ */
+
+enum ieee80211_authmode {
+ IEEE80211_AUTH_NONE = 0,
+ IEEE80211_AUTH_OPEN = 1,
+ IEEE80211_AUTH_SHARED = 2,
+ IEEE80211_AUTH_8021X = 3,
+ IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */
+ /* NB: these are used only for ioctls */
+ IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */
+ IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */
+ IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */
+};
+
+#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/
+
+#include "athendpack.h"
+
+#endif /* _NET80211_IEEE80211_H_ */
diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
new file mode 100644
index 000000000000..683deec87b2d
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h
@@ -0,0 +1,93 @@
+//------------------------------------------------------------------------------
+// <copyright file="ieee80211_node.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _IEEE80211_NODE_H_
+#define _IEEE80211_NODE_H_
+
+/*
+ * Node locking definitions.
+ */
+#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \
+ A_MUTEX_DELETE(&(_nt)->nt_nodelock); }
+
+#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_ASSERT(_nt)
+
+/*
+ * Node reference counting definitions.
+ *
+ * ieee80211_node_initref initialize the reference count to 1
+ * ieee80211_node_incref add a reference
+ * ieee80211_node_decref remove a reference
+ * ieee80211_node_dectestref remove a reference and return 1 if this
+ * is the last reference, otherwise 0
+ * ieee80211_node_refcnt reference count for printing (only)
+ */
+#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1)
+#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++)
+#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--)
+#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 1)
+#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt)
+
+#define IEEE80211_NODE_HASHSIZE 32
+/* simple hash is enough for variation of macaddr */
+#define IEEE80211_NODE_HASH(addr) \
+ (((const A_UINT8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
+ IEEE80211_NODE_HASHSIZE)
+
+/*
+ * Table of ieee80211_node instances. Each ieee80211com
+ * has at least one for holding the scan candidates.
+ * When operating as an access point or in ibss mode there
+ * is a second table for associated stations or neighbors.
+ */
+struct ieee80211_node_table {
+ void *nt_wmip; /* back reference */
+ A_MUTEX_T nt_nodelock; /* on node table */
+ struct bss *nt_node_first; /* information of all nodes */
+ struct bss *nt_node_last; /* information of all nodes */
+ struct bss *nt_hash[IEEE80211_NODE_HASHSIZE];
+ const char *nt_name; /* for debugging */
+ A_UINT32 nt_scangen; /* gen# for timeout scan */
+#ifdef THREAD_X
+ A_TIMER nt_inact_timer;
+ A_UINT8 isTimerArmed; /* is the node timer armed */
+#endif
+ A_UINT32 nt_nodeAge; /* node aging time */
+#ifdef OS_ROAM_MANAGEMENT
+ A_UINT32 nt_si_gen; /* gen# for scan indication*/
+#endif
+};
+
+#ifdef THREAD_X
+#define WLAN_NODE_INACT_TIMEOUT_MSEC 20000
+#else
+#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
+#endif
+
+#define WLAN_NODE_INACT_CNT 4
+
+#endif /* _IEEE80211_NODE_H_ */
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c
new file mode 100644
index 000000000000..6ec4e48eb2fd
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c
@@ -0,0 +1,636 @@
+//------------------------------------------------------------------------------
+// <copyright file="wlan_node.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// IEEE 802.11 node handling support.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include <a_config.h>
+#include <athdefs.h>
+#include <a_types.h>
+#include <a_osapi.h>
+#define ATH_MODULE_NAME wlan
+#include <a_debug.h>
+#include "htc.h"
+#include "htc_api.h"
+#include <wmi.h>
+#include <ieee80211.h>
+#include <wlan_api.h>
+#include <wmi_api.h>
+#include <ieee80211_node.h>
+
+#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0)
+
+#ifdef ATH_DEBUG_MODULE
+
+static ATH_DEBUG_MASK_DESCRIPTION wlan_debug_desc[] = {
+ { ATH_DEBUG_WLAN , "General WLAN Node Tracing"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan,
+ "wlan",
+ "WLAN Node Management",
+ ATH_DEBUG_MASK_DEFAULTS,
+ ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc),
+ wlan_debug_desc);
+
+#endif
+
+#ifdef THREAD_X
+static void wlan_node_timeout(A_ATH_TIMER arg);
+#endif
+
+static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
+ const A_UINT8 *macaddr);
+
+bss_t *
+wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
+{
+ bss_t *ni;
+
+ ni = A_MALLOC_NOWAIT(sizeof(bss_t));
+
+ if (ni != NULL) {
+ if (wh_size)
+ {
+ ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
+ if (ni->ni_buf == NULL) {
+ A_FREE(ni);
+ ni = NULL;
+ return ni;
+ }
+ }
+ } else {
+ return ni;
+ }
+
+ /* Make sure our lists are clean */
+ ni->ni_list_next = NULL;
+ ni->ni_list_prev = NULL;
+ ni->ni_hash_next = NULL;
+ ni->ni_hash_prev = NULL;
+
+ //
+ // ni_scangen never initialized before and during suspend/resume of winmobile,
+ // that some junk has been stored in this, due to this scan list didn't properly updated
+ //
+ ni->ni_scangen = 0;
+
+#ifdef OS_ROAM_MANAGEMENT
+ ni->ni_si_gen = 0;
+#endif
+
+ return ni;
+}
+
+void
+wlan_node_free(bss_t *ni)
+{
+ if (ni->ni_buf != NULL) {
+ A_FREE(ni->ni_buf);
+ }
+ A_FREE(ni);
+}
+
+void
+wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
+ const A_UINT8 *macaddr)
+{
+ int hash;
+ A_UINT32 timeoutValue = 0;
+
+ A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
+ hash = IEEE80211_NODE_HASH (macaddr);
+ ieee80211_node_initref (ni); /* mark referenced */
+
+ timeoutValue = nt->nt_nodeAge;
+
+ ni->ni_tstamp = A_GET_MS (timeoutValue);
+ ni->ni_actcnt = WLAN_NODE_INACT_CNT;
+
+ IEEE80211_NODE_LOCK_BH(nt);
+
+ /* Insert at the end of the node list */
+ ni->ni_list_next = NULL;
+ ni->ni_list_prev = nt->nt_node_last;
+ if(nt->nt_node_last != NULL)
+ {
+ nt->nt_node_last->ni_list_next = ni;
+ }
+ nt->nt_node_last = ni;
+ if(nt->nt_node_first == NULL)
+ {
+ nt->nt_node_first = ni;
+ }
+
+ /* Insert into the hash list i.e. the bucket */
+ if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
+ {
+ nt->nt_hash[hash]->ni_hash_prev = ni;
+ }
+ ni->ni_hash_prev = NULL;
+ nt->nt_hash[hash] = ni;
+
+#ifdef THREAD_X
+ if (!nt->isTimerArmed) {
+ A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0);
+ nt->isTimerArmed = TRUE;
+ }
+#endif
+
+ IEEE80211_NODE_UNLOCK_BH(nt);
+}
+
+static bss_t *
+_ieee80211_find_node(struct ieee80211_node_table *nt,
+ const A_UINT8 *macaddr)
+{
+ bss_t *ni;
+ int hash;
+
+ IEEE80211_NODE_LOCK_ASSERT(nt);
+
+ hash = IEEE80211_NODE_HASH(macaddr);
+ for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
+ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
+ ieee80211_node_incref(ni); /* mark referenced */
+ return ni;
+ }
+ }
+ return NULL;
+}
+
+bss_t *
+wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr)
+{
+ bss_t *ni;
+
+ IEEE80211_NODE_LOCK(nt);
+ ni = _ieee80211_find_node(nt, macaddr);
+ IEEE80211_NODE_UNLOCK(nt);
+ return ni;
+}
+
+/*
+ * Reclaim a node. If this is the last reference count then
+ * do the normal free work. Otherwise remove it from the node
+ * table and mark it gone by clearing the back-reference.
+ */
+void
+wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
+{
+ IEEE80211_NODE_LOCK(nt);
+
+ if(ni->ni_list_prev == NULL)
+ {
+ /* First in list so fix the list head */
+ nt->nt_node_first = ni->ni_list_next;
+ }
+ else
+ {
+ ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+ }
+
+ if(ni->ni_list_next == NULL)
+ {
+ /* Last in list so fix list tail */
+ nt->nt_node_last = ni->ni_list_prev;
+ }
+ else
+ {
+ ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+ }
+
+ if(ni->ni_hash_prev == NULL)
+ {
+ /* First in list so fix the list head */
+ int hash;
+ hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
+ nt->nt_hash[hash] = ni->ni_hash_next;
+ }
+ else
+ {
+ ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+ }
+
+ if(ni->ni_hash_next != NULL)
+ {
+ ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+ }
+ wlan_node_free(ni);
+
+ IEEE80211_NODE_UNLOCK(nt);
+}
+
+static void
+wlan_node_dec_free(bss_t *ni)
+{
+ if (ieee80211_node_dectestref(ni)) {
+ wlan_node_free(ni);
+ }
+}
+
+void
+wlan_free_allnodes(struct ieee80211_node_table *nt)
+{
+ bss_t *ni;
+
+ while ((ni = nt->nt_node_first) != NULL) {
+ wlan_node_reclaim(nt, ni);
+ }
+}
+
+void
+wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
+ void *arg)
+{
+ bss_t *ni;
+ A_UINT32 gen;
+
+ gen = ++nt->nt_scangen;
+
+ IEEE80211_NODE_LOCK(nt);
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+ if (ni->ni_scangen != gen) {
+ ni->ni_scangen = gen;
+ (void) ieee80211_node_incref(ni);
+ (*f)(arg, ni);
+ wlan_node_dec_free(ni);
+ }
+ }
+ IEEE80211_NODE_UNLOCK(nt);
+}
+
+/*
+ * Node table support.
+ */
+void
+wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
+{
+ int i;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt));
+ IEEE80211_NODE_LOCK_INIT(nt);
+
+ A_REGISTER_MODULE_DEBUG_INFO(wlan);
+
+ nt->nt_node_first = nt->nt_node_last = NULL;
+ for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
+ {
+ nt->nt_hash[i] = NULL;
+ }
+
+#ifdef THREAD_X
+ A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
+ nt->isTimerArmed = FALSE;
+#endif
+ nt->nt_wmip = wmip;
+ nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC;
+
+ //
+ // nt_scangen never initialized before and during suspend/resume of winmobile,
+ // that some junk has been stored in this, due to this scan list didn't properly updated
+ //
+ nt->nt_scangen = 0;
+
+#ifdef OS_ROAM_MANAGEMENT
+ nt->nt_si_gen = 0;
+#endif
+}
+
+void
+wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge)
+{
+ nt->nt_nodeAge = nodeAge;
+ return;
+}
+void
+wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt)
+{
+#ifdef THREAD_X
+ bss_t *bss, *nextBss;
+ A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE;
+
+ wmi_get_current_bssid(nt->nt_wmip, myBssid);
+
+ bss = nt->nt_node_first;
+ while (bss != NULL)
+ {
+ nextBss = bss->ni_list_next;
+ if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
+ {
+ /*
+ * free up all but the current bss - if set
+ */
+ wlan_node_reclaim(nt, bss);
+
+ }
+ bss = nextBss;
+ }
+#else
+ bss_t *bss, *nextBss;
+ A_UINT8 myBssid[IEEE80211_ADDR_LEN];
+ A_UINT32 timeoutValue = 0;
+ A_UINT32 now = A_GET_MS(0);
+ timeoutValue = nt->nt_nodeAge;
+
+ wmi_get_current_bssid(nt->nt_wmip, myBssid);
+
+ bss = nt->nt_node_first;
+ while (bss != NULL)
+ {
+ nextBss = bss->ni_list_next;
+ if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
+ {
+
+ if (bss->ni_tstamp <= now || --bss->ni_actcnt == 0)
+ {
+ /*
+ * free up all but the current bss - if set
+ */
+ wlan_node_reclaim(nt, bss);
+ }
+ }
+ bss = nextBss;
+ }
+#endif
+}
+
+#ifdef THREAD_X
+static void
+wlan_node_timeout (A_ATH_TIMER arg)
+{
+ struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
+ bss_t *bss, *nextBss;
+ A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE;
+ A_UINT32 timeoutValue = 0;
+
+ timeoutValue = nt->nt_nodeAge;
+
+ wmi_get_current_bssid(nt->nt_wmip, myBssid);
+
+ bss = nt->nt_node_first;
+ while (bss != NULL)
+ {
+ nextBss = bss->ni_list_next;
+ if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0)
+ {
+
+ if (bss->ni_tstamp <= A_GET_MS(0))
+ {
+ /*
+ * free up all but the current bss - if set
+ */
+ wlan_node_reclaim(nt, bss);
+ }
+ else
+ {
+ /*
+ * Re-arm timer, only when we have a bss other than
+ * current bss AND it is not aged-out.
+ */
+ reArmTimer = TRUE;
+ }
+ }
+ bss = nextBss;
+ }
+
+ if (reArmTimer)
+ A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0);
+
+ nt->isTimerArmed = reArmTimer;
+}
+#endif
+
+void
+wlan_node_table_cleanup(struct ieee80211_node_table *nt)
+{
+#ifdef THREAD_X
+ A_UNTIMEOUT(&nt->nt_inact_timer);
+ A_DELETE_TIMER(&nt->nt_inact_timer);
+#endif
+ wlan_free_allnodes(nt);
+ IEEE80211_NODE_LOCK_DESTROY(nt);
+}
+
+bss_t *
+wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
+{
+ bss_t *ni = NULL;
+ A_UCHAR *pIESsid = NULL;
+
+ IEEE80211_NODE_LOCK (nt);
+
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+ pIESsid = ni->ni_cie.ie_ssid;
+ if (pIESsid[1] <= 32) {
+
+ // Step 1 : Check SSID
+ if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
+
+ //
+ // Step 2.1 : Check MatchSSID is TRUE, if so, return Matched SSID
+ // Profile, otherwise check whether WPA2 or WPA
+ //
+ if (TRUE == bMatchSSID) {
+ ieee80211_node_incref (ni); /* mark referenced */
+ IEEE80211_NODE_UNLOCK (nt);
+ return ni;
+ }
+
+ // Step 2 : if SSID matches, check WPA or WPA2
+ if (TRUE == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) {
+ ieee80211_node_incref (ni); /* mark referenced */
+ IEEE80211_NODE_UNLOCK (nt);
+ return ni;
+ }
+ if (FALSE == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) {
+ ieee80211_node_incref(ni); /* mark referenced */
+ IEEE80211_NODE_UNLOCK (nt);
+ return ni;
+ }
+ }
+ }
+ }
+
+ IEEE80211_NODE_UNLOCK (nt);
+
+ return NULL;
+}
+
+void
+wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni)
+{
+ IEEE80211_NODE_LOCK (nt);
+ wlan_node_dec_free (ni);
+ IEEE80211_NODE_UNLOCK (nt);
+}
+
+void
+wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni)
+{
+ if(ni->ni_list_prev == NULL)
+ {
+ /* First in list so fix the list head */
+ nt->nt_node_first = ni->ni_list_next;
+ }
+ else
+ {
+ ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+ }
+
+ if(ni->ni_list_next == NULL)
+ {
+ /* Last in list so fix list tail */
+ nt->nt_node_last = ni->ni_list_prev;
+ }
+ else
+ {
+ ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+ }
+
+ if(ni->ni_hash_prev == NULL)
+ {
+ /* First in list so fix the list head */
+ int hash;
+ hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
+ nt->nt_hash[hash] = ni->ni_hash_next;
+ }
+ else
+ {
+ ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+ }
+
+ if(ni->ni_hash_next != NULL)
+ {
+ ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+ }
+}
+
+bss_t *
+wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid)
+{
+ bss_t *bss, *nextBss;
+
+ IEEE80211_NODE_LOCK(nt);
+
+ bss = nt->nt_node_first;
+
+ while (bss != NULL)
+ {
+ nextBss = bss->ni_list_next;
+
+ if (A_MEMCMP(bssid, bss->ni_macaddr, 6) == 0)
+ {
+ wlan_node_remove_core (nt, bss);
+ IEEE80211_NODE_UNLOCK(nt);
+ return bss;
+ }
+
+ bss = nextBss;
+ }
+
+ IEEE80211_NODE_UNLOCK(nt);
+ return NULL;
+}
+
+bss_t *
+wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_UINT32 dot11AuthMode, A_UINT32 authMode,
+ A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp)
+{
+ bss_t *ni = NULL;
+ bss_t *best_ni = NULL;
+ A_UCHAR *pIESsid = NULL;
+
+ IEEE80211_NODE_LOCK (nt);
+
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+ pIESsid = ni->ni_cie.ie_ssid;
+ if (pIESsid[1] <= 32) {
+
+ // Step 1 : Check SSID
+ if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) {
+
+ if (ni->ni_cie.ie_capInfo & 0x10)
+ {
+
+ if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode))
+ {
+ /* WPA2 */
+ if (NULL == best_ni)
+ {
+ best_ni = ni;
+ }
+ else if (ni->ni_rssi > best_ni->ni_rssi)
+ {
+ best_ni = ni;
+ }
+ }
+ else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode))
+ {
+ /* WPA */
+ if (NULL == best_ni)
+ {
+ best_ni = ni;
+ }
+ else if (ni->ni_rssi > best_ni->ni_rssi)
+ {
+ best_ni = ni;
+ }
+ }
+ else if (WEP_CRYPT == pairwiseCryptoType)
+ {
+ /* WEP */
+ if (NULL == best_ni)
+ {
+ best_ni = ni;
+ }
+ else if (ni->ni_rssi > best_ni->ni_rssi)
+ {
+ best_ni = ni;
+ }
+ }
+ }
+ else
+ {
+ /* open AP */
+ if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType))
+ {
+ if (NULL == best_ni)
+ {
+ best_ni = ni;
+ }
+ else if (ni->ni_rssi > best_ni->ni_rssi)
+ {
+ best_ni = ni;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ IEEE80211_NODE_UNLOCK (nt);
+
+ return best_ni;
+}
+
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
new file mode 100644
index 000000000000..f4926f215bbd
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
@@ -0,0 +1,200 @@
+//------------------------------------------------------------------------------
+// <copyright file="wlan_recv_beacon.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// IEEE 802.11 input handling.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include "a_config.h"
+#include "athdefs.h"
+#include "a_types.h"
+#include "a_osapi.h"
+#include <wmi.h>
+#include <ieee80211.h>
+#include <wlan_api.h>
+
+#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
+ if ((_len) < (_minlen)) { \
+ return A_EINVAL; \
+ } \
+} while (0)
+
+#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
+ if ((__elem) == NULL) { \
+ return A_EINVAL; \
+ } \
+ if ((__elem)[1] > (__maxlen)) { \
+ return A_EINVAL; \
+ } \
+} while (0)
+
+
+/* unaligned little endian access */
+#define LE_READ_2(p) \
+ ((A_UINT16) \
+ ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8)))
+
+#define LE_READ_4(p) \
+ ((A_UINT32) \
+ ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
+ (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
+
+
+static int __inline
+iswpaoui(const A_UINT8 *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
+}
+
+static int __inline
+iswmmoui(const A_UINT8 *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
+}
+
+/* unused functions for now */
+#if 0
+static int __inline
+iswmmparam(const A_UINT8 *frm)
+{
+ return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
+}
+
+static int __inline
+iswmminfo(const A_UINT8 *frm)
+{
+ return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
+}
+#endif
+
+static int __inline
+isatherosoui(const A_UINT8 *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
+}
+
+static int __inline
+iswscoui(const A_UINT8 *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
+}
+
+A_STATUS
+wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie)
+{
+ A_UINT8 *frm, *efrm;
+ A_UINT8 elemid_ssid = FALSE;
+
+ frm = buf;
+ efrm = (A_UINT8 *) (frm + framelen);
+
+ /*
+ * beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] country information
+ * [tlv] parameter set (FH/DS)
+ * [tlv] erp information
+ * [tlv] extended supported rates
+ * [tlv] WMM
+ * [tlv] WPA or RSN
+ * [tlv] Atheros Advanced Capabilities
+ */
+ IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
+ A_MEMZERO(cie, sizeof(*cie));
+
+ cie->ie_tstamp = frm; frm += 8;
+ cie->ie_beaconInt = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2;
+ cie->ie_capInfo = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2;
+ cie->ie_chan = 0;
+
+ while (frm < efrm) {
+ switch (*frm) {
+ case IEEE80211_ELEMID_SSID:
+ if (!elemid_ssid) {
+ cie->ie_ssid = frm;
+ elemid_ssid = TRUE;
+ }
+ break;
+ case IEEE80211_ELEMID_RATES:
+ cie->ie_rates = frm;
+ break;
+ case IEEE80211_ELEMID_COUNTRY:
+ cie->ie_country = frm;
+ break;
+ case IEEE80211_ELEMID_FHPARMS:
+ break;
+ case IEEE80211_ELEMID_DSPARMS:
+ cie->ie_chan = frm[2];
+ break;
+ case IEEE80211_ELEMID_TIM:
+ cie->ie_tim = frm;
+ break;
+ case IEEE80211_ELEMID_IBSSPARMS:
+ break;
+ case IEEE80211_ELEMID_XRATES:
+ cie->ie_xrates = frm;
+ break;
+ case IEEE80211_ELEMID_ERP:
+ if (frm[1] != 1) {
+ //A_PRINTF("Discarding ERP Element - Bad Len\n");
+ return A_EINVAL;
+ }
+ cie->ie_erp = frm[2];
+ break;
+ case IEEE80211_ELEMID_RSN:
+ cie->ie_rsn = frm;
+ break;
+ case IEEE80211_ELEMID_HTCAP_ANA:
+ cie->ie_htcap = frm;
+ break;
+ case IEEE80211_ELEMID_HTINFO_ANA:
+ cie->ie_htop = frm;
+ break;
+#ifdef WAPI_ENABLE
+ case IEEE80211_ELEMID_WAPI:
+ cie->ie_wapi = frm;
+ break;
+#endif
+ case IEEE80211_ELEMID_VENDOR:
+ if (iswpaoui(frm)) {
+ cie->ie_wpa = frm;
+ } else if (iswmmoui(frm)) {
+ cie->ie_wmm = frm;
+ } else if (isatherosoui(frm)) {
+ cie->ie_ath = frm;
+ } else if(iswscoui(frm)) {
+ cie->ie_wsc = frm;
+ }
+ break;
+ default:
+ break;
+ }
+ frm += frm[1] + 2;
+ }
+ IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
+ IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
+
+ return A_OK;
+}
diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
new file mode 100644
index 000000000000..1eee7bab3e50
--- /dev/null
+++ b/drivers/staging/ath6kl/wlan/src/wlan_utils.c
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// <copyright file="wlan_utils.c" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This module implements frequently used wlan utilies
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#include <a_config.h>
+#include <athdefs.h>
+#include <a_types.h>
+#include <a_osapi.h>
+
+/*
+ * converts ieee channel number to frequency
+ */
+A_UINT16
+wlan_ieee2freq(int chan)
+{
+ if (chan == 14) {
+ return 2484;
+ }
+ if (chan < 14) { /* 0-13 */
+ return (2407 + (chan*5));
+ }
+ if (chan < 27) { /* 15-26 */
+ return (2512 + ((chan-15)*20));
+ }
+ return (5000 + (chan*5));
+}
+
+/*
+ * Converts MHz frequency to IEEE channel number.
+ */
+A_UINT32
+wlan_freq2ieee(A_UINT16 freq)
+{
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return (freq - 2407) / 5;
+ if (freq < 5000)
+ return 15 + ((freq - 2512) / 20);
+ return (freq - 5000) / 5;
+}
diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c
new file mode 100644
index 000000000000..d14bad28bdfb
--- /dev/null
+++ b/drivers/staging/ath6kl/wmi/wmi.c
@@ -0,0 +1,6672 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This module implements the hardware independent layer of the
+// Wireless Module Interface (WMI) protocol.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+
+#include <a_config.h>
+#include <athdefs.h>
+#include <a_types.h>
+#include <a_osapi.h>
+#include "htc.h"
+#include "htc_api.h"
+#include "wmi.h"
+#include <wlan_api.h>
+#include <wmi_api.h>
+#include <ieee80211.h>
+#include <ieee80211_node.h>
+#include "dset_api.h"
+#include "gpio_api.h"
+#include "wmi_host.h"
+#include "a_drv.h"
+#include "a_drv_api.h"
+#define ATH_MODULE_NAME wmi
+#include "a_debug.h"
+#include "dbglog_api.h"
+#include "roaming.h"
+
+#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
+
+#ifdef ATH_DEBUG_MODULE
+
+static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = {
+ { ATH_DEBUG_WMI , "General WMI Tracing"},
+};
+
+ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
+ "wmi",
+ "Wireless Module Interface",
+ ATH_DEBUG_MASK_DEFAULTS,
+ ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
+ wmi_debug_desc);
+
+#endif
+
+#ifndef REXOS
+#define DBGARG _A_FUNCNAME_
+#define DBGFMT "%s() : "
+#define DBG_WMI ATH_DEBUG_WMI
+#define DBG_ERROR ATH_DEBUG_ERR
+#define DBG_WMI2 ATH_DEBUG_WMI
+#define A_DPRINTF AR_DEBUG_PRINTF
+#endif
+
+static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+
+static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_sync_point(struct wmi_t *wmip);
+
+static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+
+static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+#ifdef CONFIG_HOST_DSET_SUPPORT
+static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+
+static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS
+wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
+
+static A_STATUS
+wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
+
+static A_STATUS
+wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+static A_STATUS
+wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+#endif
+
+static A_STATUS
+wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS
+wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS
+wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_BOOL
+wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex);
+
+static A_STATUS
+wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS
+wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+A_STATUS wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
+ WMI_SYNC_FLAG syncflag);
+
+A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
+A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
+
+void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
+void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
+static A_STATUS wmi_send_rssi_threshold_params(struct wmi_t *wmip,
+ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
+static A_STATUS wmi_send_snr_threshold_params(struct wmi_t *wmip,
+ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+static A_STATUS
+wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+
+static A_STATUS wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+static A_STATUS wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+
+static A_STATUS wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+#ifdef ATH_AR6K_11N_SUPPORT
+static A_STATUS wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
+static A_STATUS wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int);
+static A_STATUS wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
+static A_STATUS wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+#endif
+static A_STATUS wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int);
+
+#ifdef WAPI_ENABLE
+static A_STATUS wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+ int len);
+#endif
+
+#if defined(UNDER_CE)
+#if defined(NDIS51_MINIPORT)
+unsigned int processDot11Hdr = 0;
+#else
+unsigned int processDot11Hdr = 1;
+#endif
+#else
+extern unsigned int processDot11Hdr;
+#endif
+
+int wps_enable;
+static const A_INT32 wmi_rateTable[][2] = {
+ //{W/O SGI, with SGI}
+ {1000, 1000},
+ {2000, 2000},
+ {5500, 5500},
+ {11000, 11000},
+ {6000, 6000},
+ {9000, 9000},
+ {12000, 12000},
+ {18000, 18000},
+ {24000, 24000},
+ {36000, 36000},
+ {48000, 48000},
+ {54000, 54000},
+ {6500, 7200},
+ {13000, 14400},
+ {19500, 21700},
+ {26000, 28900},
+ {39000, 43300},
+ {52000, 57800},
+ {58500, 65000},
+ {65000, 72200},
+ {13500, 15000},
+ {27000, 30000},
+ {40500, 45000},
+ {54000, 60000},
+ {81000, 90000},
+ {108000, 120000},
+ {121500, 135000},
+ {135000, 150000},
+ {0, 0}};
+
+#define MODE_A_SUPPORT_RATE_START ((A_INT32) 4)
+#define MODE_A_SUPPORT_RATE_STOP ((A_INT32) 11)
+
+#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
+#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
+
+#define MODE_B_SUPPORT_RATE_START ((A_INT32) 0)
+#define MODE_B_SUPPORT_RATE_STOP ((A_INT32) 3)
+
+#define MODE_G_SUPPORT_RATE_START ((A_INT32) 0)
+#define MODE_G_SUPPORT_RATE_STOP ((A_INT32) 11)
+
+#define MODE_GHT20_SUPPORT_RATE_START ((A_INT32) 0)
+#define MODE_GHT20_SUPPORT_RATE_STOP ((A_INT32) 19)
+
+#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
+
+/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
+const A_UINT8 up_to_ac[]= {
+ WMM_AC_BE,
+ WMM_AC_BK,
+ WMM_AC_BK,
+ WMM_AC_BE,
+ WMM_AC_VI,
+ WMM_AC_VI,
+ WMM_AC_VO,
+ WMM_AC_VO,
+ };
+
+#include "athstartpack.h"
+
+/* This stuff is used when we want a simple layer-3 visibility */
+typedef PREPACK struct _iphdr {
+ A_UINT8 ip_ver_hdrlen; /* version and hdr length */
+ A_UINT8 ip_tos; /* type of service */
+ A_UINT16 ip_len; /* total length */
+ A_UINT16 ip_id; /* identification */
+ A_INT16 ip_off; /* fragment offset field */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ A_UINT8 ip_ttl; /* time to live */
+ A_UINT8 ip_p; /* protocol */
+ A_UINT16 ip_sum; /* checksum */
+ A_UINT8 ip_src[4]; /* source and dest address */
+ A_UINT8 ip_dst[4];
+} POSTPACK iphdr;
+
+#include "athendpack.h"
+
+static A_INT16 rssi_event_value = 0;
+static A_INT16 snr_event_value = 0;
+
+A_BOOL is_probe_ssid = FALSE;
+
+void *
+wmi_init(void *devt)
+{
+ struct wmi_t *wmip;
+
+ A_REGISTER_MODULE_DEBUG_INFO(wmi);
+
+ wmip = A_MALLOC (sizeof(struct wmi_t));
+ if (wmip == NULL) {
+ return (NULL);
+ }
+ A_MEMZERO(wmip, sizeof(struct wmi_t ));
+#ifdef THREAD_X
+ INIT_WMI_LOCK(wmip);
+#else
+ A_MUTEX_INIT(&wmip->wmi_lock);
+#endif
+ wmip->wmi_devt = devt;
+ wlan_node_table_init(wmip, &wmip->wmi_scan_table);
+ wmi_qos_state_init(wmip);
+
+ wmip->wmi_powerMode = REC_POWER;
+ wmip->wmi_phyMode = WMI_11G_MODE;
+
+ wmip->wmi_pair_crypto_type = NONE_CRYPT;
+ wmip->wmi_grp_crypto_type = NONE_CRYPT;
+
+ wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
+ wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
+
+ return (wmip);
+}
+
+void
+wmi_qos_state_init(struct wmi_t *wmip)
+{
+ A_UINT8 i;
+
+ if (wmip == NULL) {
+ return;
+ }
+ LOCK_WMI(wmip);
+
+ /* Initialize QoS States */
+ wmip->wmi_numQoSStream = 0;
+
+ wmip->wmi_fatPipeExists = 0;
+
+ for (i=0; i < WMM_NUM_AC; i++) {
+ wmip->wmi_streamExistsForAC[i]=0;
+ }
+
+ UNLOCK_WMI(wmip);
+
+ A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
+}
+
+void
+wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
+{
+ A_ASSERT( eid != ENDPOINT_UNUSED);
+ wmip->wmi_endpoint_id = eid;
+}
+
+HTC_ENDPOINT_ID
+wmi_get_control_ep(struct wmi_t * wmip)
+{
+ return(wmip->wmi_endpoint_id);
+}
+
+void
+wmi_shutdown(struct wmi_t *wmip)
+{
+ if (wmip != NULL) {
+ wlan_node_table_cleanup(&wmip->wmi_scan_table);
+ if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
+#ifdef THREAD_X
+ DELETE_WMI_LOCK(&wmip);
+#else
+ A_MUTEX_DELETE(&wmip->wmi_lock);
+#endif
+ }
+ A_FREE(wmip);
+ }
+}
+
+/*
+ * performs DIX to 802.3 encapsulation for transmit packets.
+ * uses passed in buffer. Returns buffer or NULL if failed.
+ * Assumes the entire DIX header is contigous and that there is
+ * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
+ */
+A_STATUS
+wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
+{
+ A_UINT8 *datap;
+ A_UINT16 typeorlen;
+ ATH_MAC_HDR macHdr;
+ ATH_LLC_SNAP_HDR *llcHdr;
+
+ A_ASSERT(osbuf != NULL);
+
+ if (A_NETBUF_HEADROOM(osbuf) <
+ (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
+ {
+ return A_NO_MEMORY;
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+
+ typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
+
+ if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
+ /*
+ * packet is already in 802.3 format - return success
+ */
+ A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
+ return (A_OK);
+ }
+
+ /*
+ * Save mac fields and length to be inserted later
+ */
+ A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
+ A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
+ macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
+ sizeof(ATH_LLC_SNAP_HDR));
+
+ /*
+ * Make room for LLC+SNAP headers
+ */
+ if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
+ return A_NO_MEMORY;
+ }
+ datap = A_NETBUF_DATA(osbuf);
+
+ A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
+
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
+ llcHdr->dsap = 0xAA;
+ llcHdr->ssap = 0xAA;
+ llcHdr->cntl = 0x03;
+ llcHdr->orgCode[0] = 0x0;
+ llcHdr->orgCode[1] = 0x0;
+ llcHdr->orgCode[2] = 0x0;
+ llcHdr->etherType = typeorlen;
+
+ return (A_OK);
+}
+
+A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMetaS)
+{
+ switch(*pVersion){
+ case 0:
+ return (A_OK);
+ case WMI_META_VERSION_1:
+ {
+ WMI_TX_META_V1 *pV1= NULL;
+ A_ASSERT(osbuf != NULL);
+ if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) {
+ return A_NO_MEMORY;
+ }
+
+ pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
+ /* the pktID is used in conjunction with txComplete messages
+ * allowing the target to notify which tx requests have been
+ * completed and how. */
+ pV1->pktID = 0;
+ /* the ratePolicyID allows the host to specify which rate policy
+ * to use for transmitting this packet. 0 means use default behavior. */
+ pV1->ratePolicyID = 0;
+ A_ASSERT(pVersion != NULL);
+ /* the version must be used to populate the meta field of the WMI_DATA_HDR */
+ *pVersion = WMI_META_VERSION_1;
+ return (A_OK);
+ }
+#ifdef CONFIG_CHECKSUM_OFFLOAD
+ case WMI_META_VERSION_2:
+ {
+ WMI_TX_META_V2 *pV2 ;
+ A_ASSERT(osbuf != NULL);
+ if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) {
+ return A_NO_MEMORY;
+ }
+ pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
+ A_MEMCPY(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
+ return (A_OK);
+ }
+#endif
+ default:
+ return (A_OK);
+ }
+}
+
+/* Adds a WMI data header */
+A_STATUS
+wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData,
+ WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS)
+{
+ WMI_DATA_HDR *dtHdr;
+// A_UINT8 metaVersion = 0;
+ A_STATUS status;
+
+ A_ASSERT(osbuf != NULL);
+
+ /* adds the meta data field after the wmi data hdr. If metaVersion
+ * is returns 0 then no meta field was added. */
+ if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != A_OK) {
+ return status;
+ }
+
+ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
+ return A_NO_MEMORY;
+ }
+
+ dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
+ A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
+
+ WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
+ WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
+
+ if (bMoreData) {
+ WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
+ }
+
+ WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
+ //dtHdr->rssi = 0;
+
+ return (A_OK);
+}
+
+
+A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled)
+{
+ A_UINT8 *datap;
+ A_UINT8 trafficClass = WMM_AC_BE;
+ A_UINT16 ipType = IP_ETHERTYPE;
+ WMI_DATA_HDR *dtHdr;
+ A_BOOL streamExists = FALSE;
+ A_UINT8 userPriority;
+ A_UINT32 hdrsize, metasize;
+ ATH_LLC_SNAP_HDR *llcHdr;
+
+ WMI_CREATE_PSTREAM_CMD cmd;
+
+ A_ASSERT(osbuf != NULL);
+
+ //
+ // Initialize header size
+ //
+ hdrsize = 0;
+
+ datap = A_NETBUF_DATA(osbuf);
+ dtHdr = (WMI_DATA_HDR *)datap;
+ metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
+
+ if (!wmmEnabled)
+ {
+ /* If WMM is disabled all traffic goes as BE traffic */
+ userPriority = 0;
+ }
+ else
+ {
+ if (processDot11Hdr)
+ {
+ hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
+ hdrsize);
+
+
+ }
+ else
+ {
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
+ sizeof(ATH_MAC_HDR));
+ }
+
+ if (llcHdr->etherType == A_CPU2BE16(ipType))
+ {
+ /* Extract the endpoint info from the TOS field in the IP header */
+
+ userPriority = wmi_determine_userPriority (((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
+ }
+ else
+ {
+ userPriority = layer2Priority & 0x7;
+ }
+ }
+
+
+ /* workaround for WMM S5 */
+ if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
+ {
+ userPriority = 1;
+ }
+
+ trafficClass = convert_userPriority_to_trafficClass(userPriority);
+
+ WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
+ /* lower 3-bits are 802.1d priority */
+ //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
+
+ LOCK_WMI(wmip);
+ streamExists = wmip->wmi_fatPipeExists;
+ UNLOCK_WMI(wmip);
+
+ if (!(streamExists & (1 << trafficClass)))
+ {
+
+ A_MEMZERO(&cmd, sizeof(cmd));
+ cmd.trafficClass = trafficClass;
+ cmd.userPriority = userPriority;
+ cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
+ /* Implicit streams are created with TSID 0xFF */
+
+ cmd.tsid = WMI_IMPLICIT_PSTREAM;
+ wmi_create_pstream_cmd(wmip, &cmd);
+ }
+
+ return trafficClass;
+}
+
+A_STATUS
+wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
+{
+ A_UINT8 *datap;
+ A_UINT16 typeorlen;
+ ATH_MAC_HDR macHdr;
+ ATH_LLC_SNAP_HDR *llcHdr;
+ struct ieee80211_frame *wh;
+ A_UINT32 hdrsize;
+
+ A_ASSERT(osbuf != NULL);
+
+ if (A_NETBUF_HEADROOM(osbuf) <
+ (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
+ {
+ return A_NO_MEMORY;
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+
+ typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
+
+ if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
+/*
+ * packet is already in 802.3 format - return success
+ */
+ A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
+ goto AddDot11Hdr;
+ }
+
+ /*
+ * Save mac fields and length to be inserted later
+ */
+ A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
+ A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
+ macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
+ sizeof(ATH_LLC_SNAP_HDR));
+
+ // Remove the Ethernet hdr
+ A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
+ /*
+ * Make room for LLC+SNAP headers
+ */
+ if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
+ return A_NO_MEMORY;
+ }
+ datap = A_NETBUF_DATA(osbuf);
+
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
+ llcHdr->dsap = 0xAA;
+ llcHdr->ssap = 0xAA;
+ llcHdr->cntl = 0x03;
+ llcHdr->orgCode[0] = 0x0;
+ llcHdr->orgCode[1] = 0x0;
+ llcHdr->orgCode[2] = 0x0;
+ llcHdr->etherType = typeorlen;
+
+AddDot11Hdr:
+ /* Make room for 802.11 hdr */
+ if (wmip->wmi_is_wmm_enabled)
+ {
+ hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
+ if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
+ {
+ return A_NO_MEMORY;
+ }
+ wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
+ wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
+ }
+ else
+ {
+ hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(A_UINT32));
+ if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
+ {
+ return A_NO_MEMORY;
+ }
+ wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
+ wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
+ }
+ /* Setup the SA & DA */
+ IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
+
+ if (mode == INFRA_NETWORK) {
+ IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
+ }
+ else if (mode == ADHOC_NETWORK) {
+ IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
+ }
+
+ return (A_OK);
+}
+
+A_STATUS
+wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
+{
+ A_UINT8 *datap;
+ struct ieee80211_frame *pwh,wh;
+ A_UINT8 type,subtype;
+ ATH_LLC_SNAP_HDR *llcHdr;
+ ATH_MAC_HDR macHdr;
+ A_UINT32 hdrsize;
+
+ A_ASSERT(osbuf != NULL);
+ datap = A_NETBUF_DATA(osbuf);
+
+ pwh = (struct ieee80211_frame *)datap;
+ type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ A_MEMCPY((A_UINT8 *)&wh, datap, sizeof(struct ieee80211_frame));
+
+ /* strip off the 802.11 hdr*/
+ if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
+ hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
+ A_NETBUF_PULL(osbuf, hdrsize);
+ } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
+ A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
+
+ macHdr.typeOrLen = llcHdr->etherType;
+ A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
+ A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
+
+ switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+ case IEEE80211_FC1_DIR_NODS:
+ IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
+ IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
+ break;
+ case IEEE80211_FC1_DIR_TODS:
+ IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
+ IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
+ break;
+ case IEEE80211_FC1_DIR_FROMDS:
+ IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
+ IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
+ break;
+ case IEEE80211_FC1_DIR_DSTODS:
+ break;
+ }
+
+ // Remove the LLC Hdr.
+ A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
+
+ // Insert the ATH MAC hdr.
+
+ A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
+ datap = A_NETBUF_DATA(osbuf);
+
+ A_MEMCPY (datap, &macHdr, sizeof(ATH_MAC_HDR));
+
+ return A_OK;
+}
+
+/*
+ * performs 802.3 to DIX encapsulation for received packets.
+ * Assumes the entire 802.3 header is contigous.
+ */
+A_STATUS
+wmi_dot3_2_dix(void *osbuf)
+{
+ A_UINT8 *datap;
+ ATH_MAC_HDR macHdr;
+ ATH_LLC_SNAP_HDR *llcHdr;
+
+ A_ASSERT(osbuf != NULL);
+ datap = A_NETBUF_DATA(osbuf);
+
+ A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR));
+ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
+ macHdr.typeOrLen = llcHdr->etherType;
+
+ if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
+ return A_NO_MEMORY;
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+
+ A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
+
+ return (A_OK);
+}
+
+/*
+ * Removes a WMI data header
+ */
+A_STATUS
+wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
+{
+ A_ASSERT(osbuf != NULL);
+
+ return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
+}
+
+void
+wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
+{
+ wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
+}
+
+/*
+ * WMI Extended Event received from Target.
+ */
+A_STATUS
+wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
+{
+ WMIX_CMD_HDR *cmd;
+ A_UINT16 id;
+ A_UINT8 *datap;
+ A_UINT32 len;
+ A_STATUS status = A_OK;
+
+ if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
+ wmip->wmi_stats.cmd_len_err++;
+ return A_ERROR;
+ }
+
+ cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
+ id = cmd->commandId;
+
+ if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
+ wmip->wmi_stats.cmd_len_err++;
+ return A_ERROR;
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+ len = A_NETBUF_LEN(osbuf);
+
+ switch (id) {
+ case (WMIX_DSETOPENREQ_EVENTID):
+ status = wmi_dset_open_req_rx(wmip, datap, len);
+ break;
+#ifdef CONFIG_HOST_DSET_SUPPORT
+ case (WMIX_DSETCLOSE_EVENTID):
+ status = wmi_dset_close_rx(wmip, datap, len);
+ break;
+ case (WMIX_DSETDATAREQ_EVENTID):
+ status = wmi_dset_data_req_rx(wmip, datap, len);
+ break;
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+ case (WMIX_GPIO_INTR_EVENTID):
+ wmi_gpio_intr_rx(wmip, datap, len);
+ break;
+ case (WMIX_GPIO_DATA_EVENTID):
+ wmi_gpio_data_rx(wmip, datap, len);
+ break;
+ case (WMIX_GPIO_ACK_EVENTID):
+ wmi_gpio_ack_rx(wmip, datap, len);
+ break;
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+ case (WMIX_HB_CHALLENGE_RESP_EVENTID):
+ wmi_hbChallengeResp_rx(wmip, datap, len);
+ break;
+ case (WMIX_DBGLOG_EVENTID):
+ wmi_dbglog_event_rx(wmip, datap, len);
+ break;
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+ case (WMIX_PROF_COUNT_EVENTID):
+ wmi_prof_count_rx(wmip, datap, len);
+ break;
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+ default:
+ A_DPRINTF(DBG_WMI|DBG_ERROR,
+ (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
+ wmip->wmi_stats.cmd_id_err++;
+ status = A_ERROR;
+ break;
+ }
+
+ return status;
+}
+
+/*
+ * Control Path
+ */
+A_UINT32 cmdRecvNum;
+
+A_STATUS
+wmi_control_rx(struct wmi_t *wmip, void *osbuf)
+{
+ WMI_CMD_HDR *cmd;
+ A_UINT16 id;
+ A_UINT8 *datap;
+ A_UINT32 len, i, loggingReq;
+ A_STATUS status = A_OK;
+
+ A_ASSERT(osbuf != NULL);
+ if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
+ A_NETBUF_FREE(osbuf);
+ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
+ wmip->wmi_stats.cmd_len_err++;
+ return A_ERROR;
+ }
+
+ cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
+ id = cmd->commandId;
+
+ if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
+ A_NETBUF_FREE(osbuf);
+ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
+ wmip->wmi_stats.cmd_len_err++;
+ return A_ERROR;
+ }
+
+ datap = A_NETBUF_DATA(osbuf);
+ len = A_NETBUF_LEN(osbuf);
+
+ loggingReq = 0;
+
+ ar6000_get_driver_cfg(wmip->wmi_devt,
+ AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
+ &loggingReq);
+
+ if(loggingReq) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
+ for(i = 0; i < len; i++)
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
+ }
+
+ LOCK_WMI(wmip);
+ cmdRecvNum++;
+ UNLOCK_WMI(wmip);
+
+ switch (id) {
+ case (WMI_GET_BITRATE_CMDID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
+ status = wmi_bitrate_reply_rx(wmip, datap, len);
+ break;
+ case (WMI_GET_CHANNEL_LIST_CMDID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
+ status = wmi_channelList_reply_rx(wmip, datap, len);
+ break;
+ case (WMI_GET_TX_PWR_CMDID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
+ status = wmi_txPwr_reply_rx(wmip, datap, len);
+ break;
+ case (WMI_READY_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
+ status = wmi_ready_event_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
+ break;
+ case (WMI_CONNECT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
+ status = wmi_connect_event_rx(wmip, datap, len);
+ A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_DISCONNECT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
+ status = wmi_disconnect_event_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_PEER_NODE_EVENTID):
+ A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
+ status = wmi_peer_node_event_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_TKIP_MICERR_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
+ status = wmi_tkip_micerr_event_rx(wmip, datap, len);
+ break;
+ case (WMI_BSSINFO_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
+ {
+ /*
+ * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
+ * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
+ * and reconstruct the WMI_BSS_INFO_HDR in its place
+ */
+ WMI_BSS_INFO_HDR2 bih2;
+ WMI_BSS_INFO_HDR *bih;
+ A_MEMCPY(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
+
+ A_NETBUF_PUSH(osbuf, 4);
+ datap = A_NETBUF_DATA(osbuf);
+ len = A_NETBUF_LEN(osbuf);
+ bih = (WMI_BSS_INFO_HDR *)datap;
+
+ bih->channel = bih2.channel;
+ bih->frameType = bih2.frameType;
+ bih->snr = bih2.snr;
+ bih->rssi = bih2.snr - 95;
+ bih->ieMask = bih2.ieMask;
+ A_MEMCPY(bih->bssid, bih2.bssid, ATH_MAC_LEN);
+
+ status = wmi_bssInfo_event_rx(wmip, datap, len);
+ A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ }
+ break;
+ case (WMI_REGDOMAIN_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
+ status = wmi_regDomain_event_rx(wmip, datap, len);
+ break;
+ case (WMI_PSTREAM_TIMEOUT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
+ status = wmi_pstream_timeout_event_rx(wmip, datap, len);
+ /* pstreams are fatpipe abstractions that get implicitly created.
+ * User apps only deal with thinstreams. creation of a thinstream
+ * by the user or data traffic flow in an AC triggers implicit
+ * pstream creation. Do we need to send this event to App..?
+ * no harm in sending it.
+ */
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_NEIGHBOR_REPORT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
+ status = wmi_neighborReport_event_rx(wmip, datap, len);
+ break;
+ case (WMI_SCAN_COMPLETE_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
+ status = wmi_scanComplete_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_CMDERROR_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
+ status = wmi_errorEvent_rx(wmip, datap, len);
+ break;
+ case (WMI_REPORT_STATISTICS_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
+ status = wmi_statsEvent_rx(wmip, datap, len);
+ break;
+ case (WMI_RSSI_THRESHOLD_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
+ status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
+ break;
+ case (WMI_ERROR_REPORT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
+ status = wmi_reportErrorEvent_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_OPT_RX_FRAME_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
+ status = wmi_opt_frame_event_rx(wmip, datap, len);
+ break;
+ case (WMI_REPORT_ROAM_TBL_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
+ status = wmi_roam_tbl_event_rx(wmip, datap, len);
+ break;
+ case (WMI_EXTENSION_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
+ status = wmi_control_rx_xtnd(wmip, osbuf);
+ break;
+ case (WMI_CAC_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
+ status = wmi_cac_event_rx(wmip, datap, len);
+ break;
+ case (WMI_CHANNEL_CHANGE_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
+ status = wmi_channel_change_event_rx(wmip, datap, len);
+ break;
+ case (WMI_REPORT_ROAM_DATA_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
+ status = wmi_roam_data_event_rx(wmip, datap, len);
+ break;
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+ case (WMI_TEST_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
+ status = wmi_tcmd_test_report_rx(wmip, datap, len);
+ break;
+#endif
+ case (WMI_GET_FIXRATES_CMDID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
+ status = wmi_ratemask_reply_rx(wmip, datap, len);
+ break;
+ case (WMI_TX_RETRY_ERR_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
+ status = wmi_txRetryErrEvent_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_SNR_THRESHOLD_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
+ status = wmi_snrThresholdEvent_rx(wmip, datap, len);
+ break;
+ case (WMI_LQ_THRESHOLD_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
+ status = wmi_lqThresholdEvent_rx(wmip, datap, len);
+ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
+ break;
+ case (WMI_APLIST_EVENTID):
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
+ status = wmi_aplistEvent_rx(wmip, datap, len);
+ break;
+ case (WMI_GET_KEEPALIVE_CMDID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
+ status = wmi_keepalive_reply_rx(wmip, datap, len);
+ break;
+ case (WMI_GET_WOW_LIST_EVENTID):
+ status = wmi_get_wow_list_event_rx(wmip, datap, len);
+ break;
+ case (WMI_GET_PMKID_LIST_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
+ status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
+ break;
+ case (WMI_PSPOLL_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
+ status = wmi_pspoll_event_rx(wmip, datap, len);
+ break;
+ case (WMI_DTIMEXPIRY_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
+ status = wmi_dtimexpiry_event_rx(wmip, datap, len);
+ break;
+ case (WMI_SET_PARAMS_REPLY_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
+ status = wmi_set_params_event_rx(wmip, datap, len);
+ break;
+ case (WMI_ACM_REJECT_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
+ status = wmi_acm_reject_event_rx(wmip, datap, len);
+ break;
+#ifdef ATH_AR6K_11N_SUPPORT
+ case (WMI_ADDBA_REQ_EVENTID):
+ status = wmi_addba_req_event_rx(wmip, datap, len);
+ break;
+ case (WMI_ADDBA_RESP_EVENTID):
+ status = wmi_addba_resp_event_rx(wmip, datap, len);
+ break;
+ case (WMI_DELBA_REQ_EVENTID):
+ status = wmi_delba_req_event_rx(wmip, datap, len);
+ break;
+ case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
+ status = wmi_btcoex_config_event_rx(wmip, datap, len);
+ break;
+ case (WMI_REPORT_BTCOEX_STATS_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
+ status = wmi_btcoex_stats_event_rx(wmip, datap, len);
+ break;
+#endif
+ case (WMI_TX_COMPLETE_EVENTID):
+ {
+ int index;
+ TX_COMPLETE_MSG_V1 *pV1;
+ WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
+ A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
+
+ for(index = 0 ; index < pEv->numMessages ; index++) {
+ pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
+ A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
+ }
+ }
+ break;
+ case (WMI_HCI_EVENT_EVENTID):
+ status = wmi_hci_event_rx(wmip, datap, len);
+ break;
+#ifdef WAPI_ENABLE
+ case (WMI_WAPI_REKEY_EVENTID):
+ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
+ status = wmi_wapi_rekey_event_rx(wmip, datap, len);
+ break;
+#endif
+ default:
+ A_DPRINTF(DBG_WMI|DBG_ERROR,
+ (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
+ wmip->wmi_stats.cmd_id_err++;
+ status = A_ERROR;
+ break;
+ }
+
+ A_NETBUF_FREE(osbuf);
+
+ return status;
+}
+
+/* Send a "simple" wmi command -- one with no arguments */
+static A_STATUS
+wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
+{
+ void *osbuf;
+
+ osbuf = A_NETBUF_ALLOC(0);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
+}
+
+/* Send a "simple" extended wmi command -- one with no arguments.
+ Enabling this command only if GPIO or profiling support is enabled.
+ This is to suppress warnings on some platforms */
+#if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT)
+static A_STATUS
+wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
+{
+ void *osbuf;
+
+ osbuf = A_NETBUF_ALLOC(0);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
+}
+#endif
+
+static A_STATUS
+wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
+
+ if (len < sizeof(WMI_READY_EVENT)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+ wmip->wmi_ready = TRUE;
+ A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
+ ev->sw_version, ev->abi_version);
+
+ return A_OK;
+}
+
+#define LE_READ_4(p) \
+ ((A_UINT32) \
+ ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
+ (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
+
+static int __inline
+iswmmoui(const A_UINT8 *frm)
+{
+ return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
+}
+
+static int __inline
+iswmmparam(const A_UINT8 *frm)
+{
+ return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
+}
+
+
+static A_STATUS
+wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_CONNECT_EVENT *ev;
+ A_UINT8 *pie,*peie;
+
+ if (len < sizeof(WMI_CONNECT_EVENT))
+ {
+ return A_EINVAL;
+ }
+ ev = (WMI_CONNECT_EVENT *)datap;
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ DBGARG, ev->channel,
+ ev->bssid[0], ev->bssid[1], ev->bssid[2],
+ ev->bssid[3], ev->bssid[4], ev->bssid[5]));
+
+ A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
+
+ /* initialize pointer to start of assoc rsp IEs */
+ pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
+ sizeof(A_UINT16) + /* capinfo*/
+ sizeof(A_UINT16) + /* status Code */
+ sizeof(A_UINT16) ; /* associd */
+
+ /* initialize pointer to end of assoc rsp IEs */
+ peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
+
+ while (pie < peie)
+ {
+ switch (*pie)
+ {
+ case IEEE80211_ELEMID_VENDOR:
+ if (iswmmoui(pie))
+ {
+ if(iswmmparam (pie))
+ {
+ wmip->wmi_is_wmm_enabled = TRUE;
+ }
+ }
+ break;
+ }
+
+ if (wmip->wmi_is_wmm_enabled)
+ {
+ break;
+ }
+ pie += pie[1] + 2;
+ }
+
+ A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
+ ev->listenInterval, ev->beaconInterval,
+ (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
+ ev->assocReqLen, ev->assocRespLen,
+ ev->assocInfo);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_REG_DOMAIN_EVENT *ev;
+
+ if (len < sizeof(*ev)) {
+ return A_EINVAL;
+ }
+ ev = (WMI_REG_DOMAIN_EVENT *)datap;
+
+ A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_NEIGHBOR_REPORT_EVENT *ev;
+ int numAps;
+
+ if (len < sizeof(*ev)) {
+ return A_EINVAL;
+ }
+ ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
+ numAps = ev->numberOfAps;
+
+ if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
+ return A_EINVAL;
+ }
+
+ A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_DISCONNECT_EVENT *ev;
+ wmip->wmi_traffic_class = 100;
+
+ if (len < sizeof(WMI_DISCONNECT_EVENT)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ ev = (WMI_DISCONNECT_EVENT *)datap;
+
+ A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
+
+ wmip->wmi_is_wmm_enabled = FALSE;
+ wmip->wmi_pair_crypto_type = NONE_CRYPT;
+ wmip->wmi_grp_crypto_type = NONE_CRYPT;
+
+ A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
+ ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_PEER_NODE_EVENT *ev;
+
+ if (len < sizeof(WMI_PEER_NODE_EVENT)) {
+ return A_EINVAL;
+ }
+ ev = (WMI_PEER_NODE_EVENT *)datap;
+ if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
+ A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
+ } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
+ A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
+ }
+
+ A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_TKIP_MICERR_EVENT *ev;
+
+ if (len < sizeof(*ev)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ ev = (WMI_TKIP_MICERR_EVENT *)datap;
+ A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ bss_t *bss = NULL;
+ WMI_BSS_INFO_HDR *bih;
+ A_UINT8 *buf;
+ A_UINT32 nodeCachingAllowed = 1;
+ A_UCHAR cached_ssid_len = 0;
+ A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
+ A_UINT8 beacon_ssid_len = 0;
+
+ if (len <= sizeof(WMI_BSS_INFO_HDR)) {
+ return A_EINVAL;
+ }
+
+ bih = (WMI_BSS_INFO_HDR *)datap;
+ bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
+
+ if (bih->rssi > 0) {
+ if (NULL == bss)
+ return A_OK; //no node found in the table, just drop the node with incorrect RSSI
+ else
+ bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
+ }
+
+ A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
+ /* What is driver config for wlan node caching? */
+ if(ar6000_get_driver_cfg(wmip->wmi_devt,
+ AR6000_DRIVER_CFG_GET_WLANNODECACHING,
+ &nodeCachingAllowed) != A_OK) {
+ wmi_node_return(wmip, bss);
+ return A_EINVAL;
+ }
+
+ if(!nodeCachingAllowed) {
+ wmi_node_return(wmip, bss);
+ return A_OK;
+ }
+
+ buf = datap + sizeof(WMI_BSS_INFO_HDR);
+ len -= sizeof(WMI_BSS_INFO_HDR);
+
+ A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
+ "bssid \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG,
+ bih->channel, (unsigned char) bih->rssi, bih->bssid[0],
+ bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4],
+ bih->bssid[5]));
+
+ if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
+ wmi_node_return(wmip, bss);
+ return A_OK;
+ }
+
+ if (bss != NULL) {
+ /*
+ * Free up the node. Not the most efficient process given
+ * we are about to allocate a new node but it is simple and should be
+ * adequate.
+ */
+
+ /* In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so cache the probe-resp-ssid if already present. */
+ if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
+ {
+ A_UCHAR *ie_ssid;
+
+ ie_ssid = bss->ni_cie.ie_ssid;
+ if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
+ {
+ cached_ssid_len = ie_ssid[1];
+ memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
+ }
+ }
+
+ /*
+ * Use the current average rssi of associated AP base on assumpiton
+ * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
+ * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
+ * The average value of RSSI give end-user better feeling for instance value of scan result
+ * It also sync up RSSI info in GUI between scan result and RSSI signal icon
+ */
+ if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
+ bih->rssi = bss->ni_rssi;
+ bih->snr = bss->ni_snr;
+ }
+
+ wlan_node_reclaim(&wmip->wmi_scan_table, bss);
+ }
+
+ /* beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid */
+ beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
+
+ /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
+ if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
+ (0 != cached_ssid_len) &&
+ (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
+ {
+ len += (cached_ssid_len - beacon_ssid_len);
+ }
+
+ bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
+ if (bss == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ bss->ni_snr = bih->snr;
+ bss->ni_rssi = bih->rssi;
+ A_ASSERT(bss->ni_buf != NULL);
+
+ /* In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so place the cached-ssid(probe-resp) in the bssinfo. */
+ if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
+ (0 != cached_ssid_len) &&
+ (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
+ {
+ A_UINT8 *ni_buf = bss->ni_buf;
+ int buf_len = len;
+
+ /* copy the first 14 bytes such as
+ * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
+ A_MEMCPY(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
+
+ ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
+ ni_buf += (SSID_IE_LEN_INDEX + 1);
+
+ buf += (SSID_IE_LEN_INDEX + 1);
+ buf_len -= (SSID_IE_LEN_INDEX + 1);
+
+ /* copy the cached ssid */
+ A_MEMCPY(ni_buf, cached_ssid_buf, cached_ssid_len);
+ ni_buf += cached_ssid_len;
+
+ buf += beacon_ssid_len;
+ buf_len -= beacon_ssid_len;
+
+ if (cached_ssid_len > beacon_ssid_len)
+ buf_len -= (cached_ssid_len - beacon_ssid_len);
+
+ /* now copy the rest of bytes */
+ A_MEMCPY(ni_buf, buf, buf_len);
+ }
+ else
+ A_MEMCPY(bss->ni_buf, buf, len);
+
+ bss->ni_framelen = len;
+ if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
+ wlan_node_free(bss);
+ return A_EINVAL;
+ }
+
+ /*
+ * Update the frequency in ie_chan, overwriting of channel number
+ * which is done in wlan_parse_beacon
+ */
+ bss->ni_cie.ie_chan = bih->channel;
+ wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ bss_t *bss;
+ WMI_OPT_RX_INFO_HDR *bih;
+ A_UINT8 *buf;
+
+ if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
+ return A_EINVAL;
+ }
+
+ bih = (WMI_OPT_RX_INFO_HDR *)datap;
+ buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
+ len -= sizeof(WMI_OPT_RX_INFO_HDR);
+
+ A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
+ bih->bssid[4], bih->bssid[5]));
+
+ bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
+ if (bss != NULL) {
+ /*
+ * Free up the node. Not the most efficient process given
+ * we are about to allocate a new node but it is simple and should be
+ * adequate.
+ */
+ wlan_node_reclaim(&wmip->wmi_scan_table, bss);
+ }
+
+ bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
+ if (bss == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ bss->ni_snr = bih->snr;
+ bss->ni_cie.ie_chan = bih->channel;
+ A_ASSERT(bss->ni_buf != NULL);
+ A_MEMCPY(bss->ni_buf, buf, len);
+ wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
+
+ return A_OK;
+}
+
+ /* This event indicates inactivity timeout of a fatpipe(pstream)
+ * at the target
+ */
+static A_STATUS
+wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_PSTREAM_TIMEOUT_EVENT *ev;
+
+ if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
+ return A_EINVAL;
+ }
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
+
+ ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
+
+ /* When the pstream (fat pipe == AC) timesout, it means there were no
+ * thinStreams within this pstream & it got implicitly created due to
+ * data flow on this AC. We start the inactivity timer only for
+ * implicitly created pstream. Just reset the host state.
+ */
+ /* Set the activeTsids for this AC to 0 */
+ LOCK_WMI(wmip);
+ wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
+ wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
+ UNLOCK_WMI(wmip);
+
+ /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
+ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_BIT_RATE_REPLY *reply;
+ A_INT32 rate;
+ A_UINT32 sgi,index;
+ /* 54149:
+ * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
+ * since there is difference in the length and to avoid returning
+ * error value.
+ */
+ if (len < sizeof(WMI_BIT_RATE_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_BIT_RATE_REPLY *)datap;
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
+
+ if (reply->rateIndex == (A_INT8) RATE_AUTO) {
+ rate = RATE_AUTO;
+ } else {
+ // the SGI state is stored as the MSb of the rateIndex
+ index = reply->rateIndex & 0x7f;
+ sgi = (reply->rateIndex & 0x80)? 1:0;
+ rate = wmi_rateTable[index][sgi];
+ }
+
+ A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
+ return A_OK;
+}
+
+static A_STATUS
+wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_FIX_RATES_REPLY *reply;
+
+ if (len < sizeof(WMI_FIX_RATES_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_FIX_RATES_REPLY *)datap;
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
+
+ A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_CHANNEL_LIST_REPLY *reply;
+
+ if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_CHANNEL_LIST_REPLY *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
+ reply->channelList);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_TX_PWR_REPLY *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_TX_PWR_REPLY *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
+
+ return A_OK;
+}
+static A_STATUS
+wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_GET_KEEPALIVE_CMD *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_GET_KEEPALIVE_CMD *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
+
+ return A_OK;
+}
+
+
+static A_STATUS
+wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_DSETOPENREQ_EVENT *dsetopenreq;
+
+ if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
+ return A_EINVAL;
+ }
+ dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
+ A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
+ dsetopenreq->dset_id,
+ dsetopenreq->targ_dset_handle,
+ dsetopenreq->targ_reply_fn,
+ dsetopenreq->targ_reply_arg);
+
+ return A_OK;
+}
+
+#ifdef CONFIG_HOST_DSET_SUPPORT
+static A_STATUS
+wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_DSETCLOSE_EVENT *dsetclose;
+
+ if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
+ A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_DSETDATAREQ_EVENT *dsetdatareq;
+
+ if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
+ A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
+ dsetdatareq->access_cookie,
+ dsetdatareq->offset,
+ dsetdatareq->length,
+ dsetdatareq->targ_buf,
+ dsetdatareq->targ_reply_fn,
+ dsetdatareq->targ_reply_arg);
+
+ return A_OK;
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+static A_STATUS
+wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_SCAN_COMPLETE_EVENT *ev;
+
+ ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
+ if ((A_STATUS)ev->status == A_OK) {
+ wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
+ }
+ A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status);
+ is_probe_ssid = FALSE;
+
+ return A_OK;
+}
+
+/*
+ * Target is reporting a programming error. This is for
+ * developer aid only. Target only checks a few common violations
+ * and it is responsibility of host to do all error checking.
+ * Behavior of target after wmi error event is undefined.
+ * A reset is recommended.
+ */
+static A_STATUS
+wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_CMD_ERROR_EVENT *ev;
+
+ ev = (WMI_CMD_ERROR_EVENT *)datap;
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
+ switch (ev->errorCode) {
+ case (INVALID_PARAM):
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
+ break;
+ case (ILLEGAL_STATE):
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
+ break;
+ case (INTERNAL_ERROR):
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
+ break;
+ }
+
+ return A_OK;
+}
+
+
+static A_STATUS
+wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_RSSI_THRESHOLD_EVENT *reply;
+ WMI_RSSI_THRESHOLD_VAL newThreshold;
+ WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
+ SQ_THRESHOLD_PARAMS *sq_thresh =
+ &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
+ A_UINT8 upper_rssi_threshold, lower_rssi_threshold;
+ A_INT16 rssi;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+ newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
+ rssi = reply->rssi;
+
+ /*
+ * Identify the threshold breached and communicate that to the app. After
+ * that install a new set of thresholds based on the signal quality
+ * reported by the target
+ */
+ if (newThreshold) {
+ /* Upper threshold breached */
+ if (rssi < sq_thresh->upper_threshold[0]) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
+ " %d\n", DBGARG, rssi));
+ } else if ((rssi < sq_thresh->upper_threshold[1]) &&
+ (rssi >= sq_thresh->upper_threshold[0]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[2]) &&
+ (rssi >= sq_thresh->upper_threshold[1]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[3]) &&
+ (rssi >= sq_thresh->upper_threshold[2]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[4]) &&
+ (rssi >= sq_thresh->upper_threshold[3]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[5]) &&
+ (rssi >= sq_thresh->upper_threshold[4]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
+ } else if (rssi >= sq_thresh->upper_threshold[5]) {
+ newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
+ }
+ } else {
+ /* Lower threshold breached */
+ if (rssi > sq_thresh->lower_threshold[0]) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
+ "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
+ } else if ((rssi > sq_thresh->lower_threshold[1]) &&
+ (rssi <= sq_thresh->lower_threshold[0]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[2]) &&
+ (rssi <= sq_thresh->lower_threshold[1]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[3]) &&
+ (rssi <= sq_thresh->lower_threshold[2]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[4]) &&
+ (rssi <= sq_thresh->lower_threshold[3]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[5]) &&
+ (rssi <= sq_thresh->lower_threshold[4]))
+ {
+ newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
+ } else if (rssi <= sq_thresh->lower_threshold[5]) {
+ newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
+ }
+ }
+ /* Calculate and install the next set of thresholds */
+ lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+ upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+ /* Issue a wmi command to install the thresholds */
+ cmd.thresholdAbove1_Val = upper_rssi_threshold;
+ cmd.thresholdBelow1_Val = lower_rssi_threshold;
+ cmd.weight = sq_thresh->weight;
+ cmd.pollTime = sq_thresh->polling_interval;
+
+ rssi_event_value = rssi;
+
+ if (wmi_send_rssi_threshold_params(wmip, &cmd) != A_OK) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
+ DBGARG));
+ }
+
+ A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
+
+ return A_OK;
+}
+
+
+static A_STATUS
+wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_TARGET_ERROR_REPORT_EVENT *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_CAC_EVENT *reply;
+ WMM_TSPEC_IE *tspec_ie;
+ A_UINT16 activeTsids;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_CAC_EVENT *)datap;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
+ (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
+ tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
+
+ wmi_delete_pstream_cmd(wmip, reply->ac,
+ (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
+ }
+ else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
+ A_UINT8 i;
+
+ /* following assumes that there is only one outstanding ADDTS request
+ when this event is received */
+ LOCK_WMI(wmip);
+ activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
+ UNLOCK_WMI(wmip);
+
+ for (i = 0; i < sizeof(activeTsids) * 8; i++) {
+ if ((activeTsids >> i) & 1) {
+ break;
+ }
+ }
+ if (i < (sizeof(activeTsids) * 8)) {
+ wmi_delete_pstream_cmd(wmip, reply->ac, i);
+ }
+ }
+ /*
+ * Ev#72990: Clear active tsids and Add missing handling
+ * for delete qos stream from AP
+ */
+ else if (reply->cac_indication == CAC_INDICATION_DELETE) {
+ A_UINT8 tsid = 0;
+
+ tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
+ tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
+ LOCK_WMI(wmip);
+ wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
+ activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
+ UNLOCK_WMI(wmip);
+
+
+ /* Indicate stream inactivity to driver layer only if all tsids
+ * within this AC are deleted.
+ */
+ if (!activeTsids) {
+ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
+ wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
+ }
+ }
+
+ A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
+ reply->cac_indication, reply->statusCode,
+ reply->tspecSuggestion);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_CHANNEL_CHANGE_EVENT *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
+ reply->newChannel);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_HB_CHALLENGE_RESP_EVENT *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
+
+ A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_TARGET_ROAM_TBL *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_TARGET_ROAM_TBL *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_TARGET_ROAM_DATA *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_TARGET_ROAM_DATA *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
+ return A_EINVAL;
+ }
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_SNR_THRESHOLD_EVENT *reply;
+ SQ_THRESHOLD_PARAMS *sq_thresh =
+ &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
+ WMI_SNR_THRESHOLD_VAL newThreshold;
+ WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
+ A_UINT8 upper_snr_threshold, lower_snr_threshold;
+ A_INT16 snr;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
+ snr = reply->snr;
+ /*
+ * Identify the threshold breached and communicate that to the app. After
+ * that install a new set of thresholds based on the signal quality
+ * reported by the target
+ */
+ if (newThreshold) {
+ /* Upper threshold breached */
+ if (snr < sq_thresh->upper_threshold[0]) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
+ "%d\n", DBGARG, snr));
+ } else if ((snr < sq_thresh->upper_threshold[1]) &&
+ (snr >= sq_thresh->upper_threshold[0]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
+ } else if ((snr < sq_thresh->upper_threshold[2]) &&
+ (snr >= sq_thresh->upper_threshold[1]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
+ } else if ((snr < sq_thresh->upper_threshold[3]) &&
+ (snr >= sq_thresh->upper_threshold[2]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
+ } else if (snr >= sq_thresh->upper_threshold[3]) {
+ newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
+ }
+ } else {
+ /* Lower threshold breached */
+ if (snr > sq_thresh->lower_threshold[0]) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
+ "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
+ } else if ((snr > sq_thresh->lower_threshold[1]) &&
+ (snr <= sq_thresh->lower_threshold[0]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD4_BELOW;
+ } else if ((snr > sq_thresh->lower_threshold[2]) &&
+ (snr <= sq_thresh->lower_threshold[1]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD3_BELOW;
+ } else if ((snr > sq_thresh->lower_threshold[3]) &&
+ (snr <= sq_thresh->lower_threshold[2]))
+ {
+ newThreshold = WMI_SNR_THRESHOLD2_BELOW;
+ } else if (snr <= sq_thresh->lower_threshold[3]) {
+ newThreshold = WMI_SNR_THRESHOLD1_BELOW;
+ }
+ }
+
+ /* Calculate and install the next set of thresholds */
+ lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+ upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+
+ /* Issue a wmi command to install the thresholds */
+ cmd.thresholdAbove1_Val = upper_snr_threshold;
+ cmd.thresholdBelow1_Val = lower_snr_threshold;
+ cmd.weight = sq_thresh->weight;
+ cmd.pollTime = sq_thresh->polling_interval;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
+ ,DBGARG, snr, newThreshold, lower_snr_threshold,
+ upper_snr_threshold));
+
+ snr_event_value = snr;
+
+ if (wmi_send_snr_threshold_params(wmip, &cmd) != A_OK) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
+ DBGARG));
+ }
+ A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_LQ_THRESHOLD_EVENT *reply;
+
+ if (len < sizeof(*reply)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
+ (WMI_LQ_THRESHOLD_VAL) reply->range,
+ reply->lq);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ A_UINT16 ap_info_entry_size;
+ WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
+ WMI_AP_INFO_V1 *ap_info_v1;
+ A_UINT8 i;
+
+ if (len < sizeof(WMI_APLIST_EVENT)) {
+ return A_EINVAL;
+ }
+
+ if (ev->apListVer == APLIST_VER1) {
+ ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
+ ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
+ } else {
+ return A_EINVAL;
+ }
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
+ if (len < (int)(sizeof(WMI_APLIST_EVENT) +
+ (ev->numAP - 1) * ap_info_entry_size))
+ {
+ return A_EINVAL;
+ }
+
+ /*
+ * AP List Ver1 Contents
+ */
+ for (i = 0; i < ev->numAP; i++) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
+ "Channel %d\n", i,
+ ap_info_v1->bssid[0], ap_info_v1->bssid[1],
+ ap_info_v1->bssid[2], ap_info_v1->bssid[3],
+ ap_info_v1->bssid[4], ap_info_v1->bssid[5],
+ ap_info_v1->channel));
+ ap_info_v1++;
+ }
+ return A_OK;
+}
+
+static A_STATUS
+wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ A_UINT32 dropped;
+
+ dropped = *((A_UINT32 *)datap);
+ datap += sizeof(dropped);
+ len -= sizeof(dropped);
+ A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len);
+ return A_OK;
+}
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+static A_STATUS
+wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
+ gpio_intr->intr_mask, gpio_intr->input_values));
+
+ A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
+ gpio_data->reg_id, gpio_data->value));
+
+ A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_GPIO_ACK_RX();
+
+ return A_OK;
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+/*
+ * Called to send a wmi command. Command specific data is already built
+ * on osbuf and current osbuf->data points to it.
+ */
+A_STATUS
+wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
+ WMI_SYNC_FLAG syncflag)
+{
+ A_STATUS status;
+#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
+ WMI_CMD_HDR *cHdr;
+ HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
+
+ A_ASSERT(osbuf != NULL);
+
+ if (syncflag >= END_WMIFLAG) {
+ A_NETBUF_FREE(osbuf);
+ return A_EINVAL;
+ }
+
+ if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
+ /*
+ * We want to make sure all data currently queued is transmitted before
+ * the cmd execution. Establish a new sync point.
+ */
+ wmi_sync_point(wmip);
+ }
+
+ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
+ A_NETBUF_FREE(osbuf);
+ return A_NO_MEMORY;
+ }
+
+ cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
+ cHdr->commandId = (A_UINT16) cmdId;
+ cHdr->info1 = 0; // added for virtual interface
+
+ /*
+ * Only for OPT_TX_CMD, use BE endpoint.
+ */
+ if (IS_OPT_TX_CMD(cmdId)) {
+ if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, FALSE, FALSE,0,NULL)) != A_OK) {
+ A_NETBUF_FREE(osbuf);
+ return status;
+ }
+ eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
+ }
+ A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
+
+ if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
+ /*
+ * We want to make sure all new data queued waits for the command to
+ * execute. Establish a new sync point.
+ */
+ wmi_sync_point(wmip);
+ }
+ return (A_OK);
+#undef IS_OPT_TX_CMD
+}
+
+A_STATUS
+wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
+ WMI_SYNC_FLAG syncflag)
+{
+ WMIX_CMD_HDR *cHdr;
+
+ if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
+ A_NETBUF_FREE(osbuf);
+ return A_NO_MEMORY;
+ }
+
+ cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
+ cHdr->commandId = (A_UINT32) cmdId;
+
+ return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
+}
+
+A_STATUS
+wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
+ DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
+ CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen,
+ CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen,
+ int ssidLength, A_UCHAR *ssid,
+ A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags)
+{
+ void *osbuf;
+ WMI_CONNECT_CMD *cc;
+ wmip->wmi_traffic_class = 100;
+
+ if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
+ return A_EINVAL;
+ }
+ if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
+
+ cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cc, sizeof(*cc));
+
+ if (ssidLength)
+ {
+ A_MEMCPY(cc->ssid, ssid, ssidLength);
+ }
+
+ cc->ssidLength = ssidLength;
+ cc->networkType = netType;
+ cc->dot11AuthMode = dot11AuthMode;
+ cc->authMode = authMode;
+ cc->pairwiseCryptoType = pairwiseCrypto;
+ cc->pairwiseCryptoLen = pairwiseCryptoLen;
+ cc->groupCryptoType = groupCrypto;
+ cc->groupCryptoLen = groupCryptoLen;
+ cc->channel = channel;
+ cc->ctrl_flags = ctrl_flags;
+
+ if (bssid != NULL) {
+ A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
+ }
+
+ wmip->wmi_pair_crypto_type = pairwiseCrypto;
+ wmip->wmi_grp_crypto_type = groupCrypto;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
+{
+ void *osbuf;
+ WMI_RECONNECT_CMD *cc;
+ wmip->wmi_traffic_class = 100;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
+
+ cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cc, sizeof(*cc));
+
+ cc->channel = channel;
+
+ if (bssid != NULL) {
+ A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_disconnect_cmd(struct wmi_t *wmip)
+{
+ A_STATUS status;
+ wmip->wmi_traffic_class = 100;
+
+ /* Bug fix for 24817(elevator bug) - the disconnect command does not
+ need to do a SYNC before.*/
+ status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
+
+ return status;
+}
+
+A_STATUS
+wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
+ A_BOOL forceFgScan, A_BOOL isLegacy,
+ A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
+ A_INT8 numChan, A_UINT16 *channelList)
+{
+ void *osbuf;
+ WMI_START_SCAN_CMD *sc;
+ A_INT8 size;
+
+ size = sizeof (*sc);
+
+ if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
+ return A_EINVAL;
+ }
+
+ if (numChan) {
+ if (numChan > WMI_MAX_CHANNELS) {
+ return A_EINVAL;
+ }
+ size += sizeof(A_UINT16) * (numChan - 1);
+ }
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
+ sc->scanType = scanType;
+ sc->forceFgScan = forceFgScan;
+ sc->isLegacy = isLegacy;
+ sc->homeDwellTime = homeDwellTime;
+ sc->forceScanInterval = forceScanInterval;
+ sc->numChannels = numChan;
+ if (numChan) {
+ A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16));
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
+ A_UINT16 fg_end_sec, A_UINT16 bg_sec,
+ A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec,
+ A_UINT16 pas_chdw_msec,
+ A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
+ A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid)
+{
+ void *osbuf;
+ WMI_SCAN_PARAMS_CMD *sc;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*sc));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*sc));
+
+ sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(sc, sizeof(*sc));
+ sc->fg_start_period = fg_start_sec;
+ sc->fg_end_period = fg_end_sec;
+ sc->bg_period = bg_sec;
+ sc->minact_chdwell_time = minact_chdw_msec;
+ sc->maxact_chdwell_time = maxact_chdw_msec;
+ sc->pas_chdwell_time = pas_chdw_msec;
+ sc->shortScanRatio = shScanRatio;
+ sc->scanCtrlFlags = scanCtrlFlags;
+ sc->max_dfsch_act_time = max_dfsch_act_time;
+ sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask)
+{
+ void *osbuf;
+ WMI_BSS_FILTER_CMD *cmd;
+
+ if (filter >= LAST_BSS_FILTER) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->bssFilter = filter;
+ cmd->ieMask = ieMask;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
+ A_UINT8 ssidLength, A_UCHAR *ssid)
+{
+ void *osbuf;
+ WMI_PROBED_SSID_CMD *cmd;
+
+ if (index > MAX_PROBED_SSID_INDEX) {
+ return A_EINVAL;
+ }
+ if (ssidLength > sizeof(cmd->ssid)) {
+ return A_EINVAL;
+ }
+ if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
+ return A_EINVAL;
+ }
+ if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
+ return A_EINVAL;
+ }
+
+ if (flag & SPECIFIC_SSID_FLAG) {
+ is_probe_ssid = TRUE;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->entryIndex = index;
+ cmd->flag = flag;
+ cmd->ssidLength = ssidLength;
+ A_MEMCPY(cmd->ssid, ssid, ssidLength);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons)
+{
+ void *osbuf;
+ WMI_LISTEN_INT_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->listenInterval = listenInterval;
+ cmd->numBeacons = listenBeacons;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons)
+{
+ void *osbuf;
+ WMI_BMISS_TIME_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->bmissTime = bmissTime;
+ cmd->numBeacons = bmissBeacons;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
+ A_UINT8 ieLen, A_UINT8 *ieInfo)
+{
+ void *osbuf;
+ WMI_SET_ASSOC_INFO_CMD *cmd;
+ A_UINT16 cmdLen;
+
+ cmdLen = sizeof(*cmd) + ieLen - 1;
+ osbuf = A_NETBUF_ALLOC(cmdLen);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, cmdLen);
+
+ cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, cmdLen);
+ cmd->ieType = ieType;
+ cmd->bufferSize = ieLen;
+ A_MEMCPY(cmd->assocInfo, ieInfo, ieLen);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode)
+{
+ void *osbuf;
+ WMI_POWER_MODE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->powerMode = powerMode;
+ wmip->wmi_powerMode = powerMode;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
+ A_UINT16 atim_windows, A_UINT16 timeout_value)
+{
+ void *osbuf;
+ WMI_IBSS_PM_CAPS_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->power_saving = pmEnable;
+ cmd->ttl = ttl;
+ cmd->atim_windows = atim_windows;
+ cmd->timeout_value = timeout_value;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time,
+ A_UINT32 ps_period, A_UINT8 sleep_period)
+{
+ void *osbuf;
+ WMI_AP_PS_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->psType = psType;
+ cmd->idle_time = idle_time;
+ cmd->ps_period = ps_period;
+ cmd->sleep_period = sleep_period;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
+ A_UINT16 psPollNum, A_UINT16 dtimPolicy,
+ A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup,
+ A_UINT16 ps_fail_event_policy)
+{
+ void *osbuf;
+ WMI_POWER_PARAMS_CMD *pm;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*pm));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*pm));
+
+ pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(pm, sizeof(*pm));
+ pm->idle_period = idlePeriod;
+ pm->pspoll_number = psPollNum;
+ pm->dtim_policy = dtimPolicy;
+ pm->tx_wakeup_policy = tx_wakeup_policy;
+ pm->num_tx_to_wakeup = num_tx_to_wakeup;
+ pm->ps_fail_event_policy = ps_fail_event_policy;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout)
+{
+ void *osbuf;
+ WMI_DISC_TIMEOUT_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->disconnectTimeout = timeout;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
+ A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
+ A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr,
+ WMI_SYNC_FLAG sync_flag)
+{
+ void *osbuf;
+ WMI_ADD_CIPHER_KEY_CMD *cmd;
+
+ if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
+ (keyMaterial == NULL))
+ {
+ return A_EINVAL;
+ }
+
+ if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->keyIndex = keyIndex;
+ cmd->keyType = keyType;
+ cmd->keyUsage = keyUsage;
+ cmd->keyLength = keyLength;
+ A_MEMCPY(cmd->key, keyMaterial, keyLength);
+#ifdef WAPI_ENABLE
+ if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
+#else
+ if (NULL != keyRSC) {
+#endif // WAPI_ENABLE
+ A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
+ }
+ cmd->key_op_ctrl = key_op_ctrl;
+
+ if(macAddr) {
+ A_MEMCPY(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
+}
+
+A_STATUS
+wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk)
+{
+ void *osbuf;
+ WMI_ADD_KRK_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_delete_krk_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
+}
+
+A_STATUS
+wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex)
+{
+ void *osbuf;
+ WMI_DELETE_CIPHER_KEY_CMD *cmd;
+
+ if (keyIndex > WMI_MAX_KEY_INDEX) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->keyIndex = keyIndex;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
+ A_BOOL set)
+{
+ void *osbuf;
+ WMI_SET_PMKID_CMD *cmd;
+
+ if (bssid == NULL) {
+ return A_EINVAL;
+ }
+
+ if ((set == TRUE) && (pmkId == NULL)) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+ if (set == TRUE) {
+ A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
+ cmd->enable = PMKID_ENABLE;
+ } else {
+ A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
+ cmd->enable = PMKID_DISABLE;
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
+{
+ void *osbuf;
+ WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_akmp_params_cmd(struct wmi_t *wmip,
+ WMI_SET_AKMP_PARAMS_CMD *akmpParams)
+{
+ void *osbuf;
+ WMI_SET_AKMP_PARAMS_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->akmpInfo = akmpParams->akmpInfo;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
+ WMI_SET_PMKID_LIST_CMD *pmkInfo)
+{
+ void *osbuf;
+ WMI_SET_PMKID_LIST_CMD *cmd;
+ A_UINT16 cmdLen;
+ A_UINT8 i;
+
+ cmdLen = sizeof(pmkInfo->numPMKID) +
+ pmkInfo->numPMKID * sizeof(WMI_PMKID);
+
+ osbuf = A_NETBUF_ALLOC(cmdLen);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, cmdLen);
+ cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->numPMKID = pmkInfo->numPMKID;
+
+ for (i = 0; i < cmd->numPMKID; i++) {
+ A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
+ WMI_PMKID_LEN);
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
+}
+
+A_STATUS
+wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
+{
+ WMI_DATA_HDR *dtHdr;
+
+ A_ASSERT( eid != wmip->wmi_endpoint_id);
+ A_ASSERT(osbuf != NULL);
+
+ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
+ return A_NO_MEMORY;
+ }
+
+ dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
+ dtHdr->info =
+ (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
+
+ return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
+}
+
+typedef struct _WMI_DATA_SYNC_BUFS {
+ A_UINT8 trafficClass;
+ void *osbuf;
+}WMI_DATA_SYNC_BUFS;
+
+static A_STATUS
+wmi_sync_point(struct wmi_t *wmip)
+{
+ void *cmd_osbuf;
+ WMI_SYNC_CMD *cmd;
+ WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
+ A_UINT8 i,numPriStreams=0;
+ A_STATUS status = A_OK;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ memset(dataSyncBufs,0,sizeof(dataSyncBufs));
+
+ /* lock out while we walk through the priority list and assemble our local array */
+ LOCK_WMI(wmip);
+
+ for (i=0; i < WMM_NUM_AC ; i++) {
+ if (wmip->wmi_fatPipeExists & (1 << i)) {
+ numPriStreams++;
+ dataSyncBufs[numPriStreams-1].trafficClass = i;
+ }
+ }
+
+ UNLOCK_WMI(wmip);
+
+ /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
+
+ do {
+ /*
+ * We allocate all network buffers needed so we will be able to
+ * send all required frames.
+ */
+ cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (cmd_osbuf == NULL) {
+ status = A_NO_MEMORY;
+ break;
+ }
+
+ A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
+ * eps on which the Data Sync will be sent
+ */
+ cmd->dataSyncMap = wmip->wmi_fatPipeExists;
+
+ for (i=0; i < numPriStreams ; i++) {
+ dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
+ if (dataSyncBufs[i].osbuf == NULL) {
+ status = A_NO_MEMORY;
+ break;
+ }
+ } //end for
+
+ /* if Buffer allocation for any of the dataSync fails, then do not
+ * send the Synchronize cmd on the control ep
+ */
+ if (A_FAILED(status)) {
+ break;
+ }
+
+ /*
+ * Send sync cmd followed by sync data messages on all endpoints being
+ * used
+ */
+ status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* cmd buffer sent, we no longer own it */
+ cmd_osbuf = NULL;
+
+ for(i=0; i < numPriStreams; i++) {
+ A_ASSERT(dataSyncBufs[i].osbuf != NULL);
+ status = wmi_dataSync_send(wmip,
+ dataSyncBufs[i].osbuf,
+ A_WMI_Ac2EndpointID(wmip->wmi_devt,
+ dataSyncBufs[i].
+ trafficClass)
+ );
+
+ if (A_FAILED(status)) {
+ break;
+ }
+ /* we don't own this buffer anymore, NULL it out of the array so it
+ * won't get cleaned up */
+ dataSyncBufs[i].osbuf = NULL;
+ } //end for
+
+ } while(FALSE);
+
+ /* free up any resources left over (possibly due to an error) */
+
+ if (cmd_osbuf != NULL) {
+ A_NETBUF_FREE(cmd_osbuf);
+ }
+
+ for (i = 0; i < numPriStreams; i++) {
+ if (dataSyncBufs[i].osbuf != NULL) {
+ A_NETBUF_FREE(dataSyncBufs[i].osbuf);
+ }
+ }
+
+ return (status);
+}
+
+A_STATUS
+wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
+{
+ void *osbuf;
+ WMI_CREATE_PSTREAM_CMD *cmd;
+ A_UINT8 fatPipeExistsForAC=0;
+ A_INT32 minimalPHY = 0;
+ A_INT32 nominalPHY = 0;
+
+ /* Validate all the parameters. */
+ if( !((params->userPriority < 8) &&
+ (params->userPriority <= 0x7) &&
+ (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
+ (params->trafficDirection == UPLINK_TRAFFIC ||
+ params->trafficDirection == DNLINK_TRAFFIC ||
+ params->trafficDirection == BIDIR_TRAFFIC) &&
+ (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
+ params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
+ (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
+ params->voicePSCapability == ENABLE_FOR_THIS_AC ||
+ params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
+ (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
+ {
+ return A_EINVAL;
+ }
+
+ //
+ // check nominal PHY rate is >= minimalPHY, so that DUT
+ // can allow TSRS IE
+ //
+
+ // get the physical rate
+ minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
+
+ // check minimal phy < nominal phy rate
+ //
+ if (params->nominalPHY >= minimalPHY)
+ {
+ nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
+ minimalPHY, nominalPHY));
+
+ params->nominalPHY = nominalPHY;
+ }
+ else
+ {
+ params->nominalPHY = 0;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
+ params->trafficClass, params->tsid));
+
+ cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ A_MEMCPY(cmd, params, sizeof(*cmd));
+
+ /* this is an implicitly created Fat pipe */
+ if ((A_UINT32)params->tsid == (A_UINT32)WMI_IMPLICIT_PSTREAM) {
+ LOCK_WMI(wmip);
+ fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
+ wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
+ UNLOCK_WMI(wmip);
+ } else {
+ /* this is an explicitly created thin stream within a fat pipe */
+ LOCK_WMI(wmip);
+ fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
+ wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
+ /* if a thinstream becomes active, the fat pipe automatically
+ * becomes active
+ */
+ wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
+ UNLOCK_WMI(wmip);
+ }
+
+ /* Indicate activty change to driver layer only if this is the
+ * first TSID to get created in this AC explicitly or an implicit
+ * fat pipe is getting created.
+ */
+ if (!fatPipeExistsForAC) {
+ A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
+ }
+
+ /* mike: should be SYNC_BEFORE_WMIFLAG */
+ return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid)
+{
+ void *osbuf;
+ WMI_DELETE_PSTREAM_CMD *cmd;
+ A_STATUS status;
+ A_UINT16 activeTsids=0;
+
+ /* validate the parameters */
+ if (trafficClass > 3) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->trafficClass = trafficClass;
+ cmd->tsid = tsid;
+
+ LOCK_WMI(wmip);
+ activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
+ UNLOCK_WMI(wmip);
+
+ /* Check if the tsid was created & exists */
+ if (!(activeTsids & (1<<tsid))) {
+
+ A_NETBUF_FREE(osbuf);
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
+ /* TODO: return a more appropriate err code */
+ return A_ERROR;
+ }
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
+
+ status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
+ SYNC_BEFORE_WMIFLAG));
+
+ LOCK_WMI(wmip);
+ wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
+ activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
+ UNLOCK_WMI(wmip);
+
+
+ /* Indicate stream inactivity to driver layer only if all tsids
+ * within this AC are deleted.
+ */
+ if(!activeTsids) {
+ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
+ wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
+ }
+
+ return status;
+}
+
+A_STATUS
+wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask)
+{
+ void *osbuf;
+ WMI_FRAME_RATES_CMD *cmd;
+ A_UINT8 frameType;
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
+
+ if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
+ (subType > 15)){
+
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ frameType = (A_UINT8)((subType << 4) | type);
+
+ cmd->bEnableMask = bEnable;
+ cmd->frameType = frameType;
+ cmd->frameRateMask = rateMask;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * used to set the bit rate. rate is in Kbps. If rate == -1
+ * then auto selection is used.
+ */
+A_STATUS
+wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate)
+{
+ void *osbuf;
+ WMI_BIT_RATE_CMD *cmd;
+ A_INT8 drix, mrix, crix, ret_val;
+
+ if (dataRate != -1) {
+ ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
+ if(ret_val == A_EINVAL){
+ return A_EINVAL;
+ }
+ } else {
+ drix = -1;
+ }
+
+ if (mgmtRate != -1) {
+ ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
+ if(ret_val == A_EINVAL){
+ return A_EINVAL;
+ }
+ } else {
+ mrix = -1;
+ }
+ if (ctlRate != -1) {
+ ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
+ if(ret_val == A_EINVAL){
+ return A_EINVAL;
+ }
+ } else {
+ crix = -1;
+ }
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->rateIndex = drix;
+ cmd->mgmtRateIndex = mrix;
+ cmd->ctlRateIndex = crix;
+
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_bitrate_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
+}
+
+/*
+ * Returns TRUE iff the given rate index is legal in the current PHY mode.
+ */
+A_BOOL
+wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
+{
+ WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
+ A_BOOL isValid = TRUE;
+ switch(phyMode) {
+ case WMI_11A_MODE:
+ if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
+ if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ } else {
+ if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ }
+ break;
+
+ case WMI_11B_MODE:
+ if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ break;
+
+ case WMI_11GONLY_MODE:
+ if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
+ if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ } else {
+ if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ }
+ break;
+
+ case WMI_11G_MODE:
+ case WMI_11AG_MODE:
+ if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
+ if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ } else {
+ if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
+ isValid = FALSE;
+ }
+ }
+ break;
+ default:
+ A_ASSERT(FALSE);
+ break;
+ }
+
+ return isValid;
+}
+
+A_INT8
+wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx)
+{
+ A_INT8 i;
+
+ for (i=0;;i++)
+ {
+ if (wmi_rateTable[(A_UINT32) i][0] == 0) {
+ return A_EINVAL;
+ }
+ if (wmi_rateTable[(A_UINT32) i][0] == rate) {
+ break;
+ }
+ }
+
+ if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) {
+ return A_EINVAL;
+ }
+
+ *rate_idx = i;
+ return A_OK;
+}
+
+A_STATUS
+wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask)
+{
+ void *osbuf;
+ WMI_FIX_RATES_CMD *cmd;
+#if 0
+ A_INT32 rateIndex;
+/* This check does not work for AR6003 as the HT modes are enabled only when
+ * the STA is connected to a HT_BSS and is not based only on channel. It is
+ * safe to skip this check however because rate control will only use rates
+ * that are permitted by the valid rate mask and the fix rate mask. Meaning
+ * the fix rate mask is not sufficient by itself to cause an invalid rate
+ * to be used. */
+ /* Make sure all rates in the mask are valid in the current PHY mode */
+ for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
+ if((1 << rateIndex) & (A_UINT32)fixRatesMask) {
+ if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
+ return A_EINVAL;
+ }
+ }
+ }
+#endif
+
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->fixRateMask = fixRatesMask;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_ratemask_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
+}
+
+A_STATUS
+wmi_get_channelList_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
+}
+
+/*
+ * used to generate a wmi sey channel Parameters cmd.
+ * mode should always be specified and corresponds to the phy mode of the
+ * wlan.
+ * numChan should alway sbe specified. If zero indicates that all available
+ * channels should be used.
+ * channelList is an array of channel frequencies (in Mhz) which the radio
+ * should limit its operation to. It should be NULL if numChan == 0. Size of
+ * array should correspond to numChan entries.
+ */
+A_STATUS
+wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
+ WMI_PHY_MODE mode, A_INT8 numChan,
+ A_UINT16 *channelList)
+{
+ void *osbuf;
+ WMI_CHANNEL_PARAMS_CMD *cmd;
+ A_INT8 size;
+
+ size = sizeof (*cmd);
+
+ if (numChan) {
+ if (numChan > WMI_MAX_CHANNELS) {
+ return A_EINVAL;
+ }
+ size += sizeof(A_UINT16) * (numChan - 1);
+ }
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+
+ wmip->wmi_phyMode = mode;
+ cmd->scanParam = scanParam;
+ cmd->phyMode = mode;
+ cmd->numChannels = numChan;
+ A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+void
+wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
+{
+ SQ_THRESHOLD_PARAMS *sq_thresh =
+ &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
+ /*
+ * Parse the command and store the threshold values here. The checks
+ * for valid values can be put here
+ */
+ sq_thresh->weight = rssiCmd->weight;
+ sq_thresh->polling_interval = rssiCmd->pollTime;
+
+ sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->upper_threshold_valid_count = 6;
+
+ /* List sorted in descending order */
+ sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
+ sq_thresh->lower_threshold_valid_count = 6;
+
+ if (!rssi_event_value) {
+ /*
+ * Configuring the thresholds to their extremes allows the host to get an
+ * event from the target which is used for the configuring the correct
+ * thresholds
+ */
+ rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
+ rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
+ } else {
+ /*
+ * In case the user issues multiple times of rssi_threshold_setting,
+ * we should not use the extreames anymore, the target does not expect that.
+ */
+ rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+ rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+}
+}
+
+A_STATUS
+wmi_set_rssi_threshold_params(struct wmi_t *wmip,
+ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
+{
+
+ /* Check these values are in ascending order */
+ if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
+ rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
+ rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
+ rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
+ rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
+ rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
+ rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
+ rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
+ rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
+ rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
+ {
+ return A_EINVAL;
+ }
+
+ wmi_cache_configure_rssithreshold(wmip, rssiCmd);
+
+ return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
+}
+
+A_STATUS
+wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
+{
+ void *osbuf;
+ WMI_SET_IP_CMD *cmd;
+
+ /* Multicast address are not valid */
+ if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) ||
+ (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
+ cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
+ WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
+ A_UINT16 activeTsids=0;
+ A_UINT8 streamExists=0;
+ A_UINT8 i;
+
+ if( hostModeCmd->awake == hostModeCmd->asleep) {
+ return A_EINVAL;
+ }
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
+
+ if(hostModeCmd->asleep) {
+ /*
+ * Relinquish credits from all implicitly created pstreams since when we
+ * go to sleep. If user created explicit thinstreams exists with in a
+ * fatpipe leave them intact for the user to delete
+ */
+ LOCK_WMI(wmip);
+ streamExists = wmip->wmi_fatPipeExists;
+ UNLOCK_WMI(wmip);
+
+ for(i=0;i< WMM_NUM_AC;i++) {
+ if (streamExists & (1<<i)) {
+ LOCK_WMI(wmip);
+ activeTsids = wmip->wmi_streamExistsForAC[i];
+ UNLOCK_WMI(wmip);
+ /* If there are no user created thin streams delete the fatpipe */
+ if(!activeTsids) {
+ streamExists &= ~(1<<i);
+ /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
+ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
+ }
+ }
+ }
+
+ /* Update the fatpipes that exists*/
+ LOCK_WMI(wmip);
+ wmip->wmi_fatPipeExists = streamExists;
+ UNLOCK_WMI(wmip);
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_wow_mode_cmd(struct wmi_t *wmip,
+ WMI_SET_WOW_MODE_CMD *wowModeCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_SET_WOW_MODE_CMD *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_get_wow_list_cmd(struct wmi_t *wmip,
+ WMI_GET_WOW_LIST_CMD *wowListCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_GET_WOW_LIST_CMD *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+static A_STATUS
+wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_GET_WOW_LIST_REPLY *reply;
+
+ if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_GET_WOW_LIST_REPLY *)datap;
+
+ A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
+ reply);
+
+ return A_OK;
+}
+
+A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
+ WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
+ A_UINT8* pattern, A_UINT8* mask,
+ A_UINT8 pattern_size)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_ADD_WOW_PATTERN_CMD *cmd;
+ A_UINT8 *filter_mask = NULL;
+
+ size = sizeof (*cmd);
+
+ size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8));
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->filter_list_id = addWowCmd->filter_list_id;
+ cmd->filter_offset = addWowCmd->filter_offset;
+ cmd->filter_size = addWowCmd->filter_size;
+
+ A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size);
+
+ filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size);
+ A_MEMCPY(filter_mask, mask, addWowCmd->filter_size);
+
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
+ WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_DEL_WOW_PATTERN_CMD *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+void
+wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
+{
+ SQ_THRESHOLD_PARAMS *sq_thresh =
+ &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
+ /*
+ * Parse the command and store the threshold values here. The checks
+ * for valid values can be put here
+ */
+ sq_thresh->weight = snrCmd->weight;
+ sq_thresh->polling_interval = snrCmd->pollTime;
+
+ sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
+ sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
+ sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
+ sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
+ sq_thresh->upper_threshold_valid_count = 4;
+
+ /* List sorted in descending order */
+ sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
+ sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
+ sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
+ sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
+ sq_thresh->lower_threshold_valid_count = 4;
+
+ if (!snr_event_value) {
+ /*
+ * Configuring the thresholds to their extremes allows the host to get an
+ * event from the target which is used for the configuring the correct
+ * thresholds
+ */
+ snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0];
+ snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0];
+ } else {
+ /*
+ * In case the user issues multiple times of snr_threshold_setting,
+ * we should not use the extreames anymore, the target does not expect that.
+ */
+ snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+ snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+ }
+
+}
+A_STATUS
+wmi_set_snr_threshold_params(struct wmi_t *wmip,
+ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
+{
+ if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
+ snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
+ snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
+ snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
+ snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
+ snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
+ {
+ return A_EINVAL;
+ }
+ wmi_cache_configure_snrthreshold(wmip, snrCmd);
+ return (wmi_send_snr_threshold_params(wmip, snrCmd));
+}
+
+A_STATUS
+wmi_clr_rssi_snr(struct wmi_t *wmip)
+{
+ void *osbuf;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(int));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_lq_threshold_params(struct wmi_t *wmip,
+ WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
+ /* These values are in ascending order */
+ if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
+ lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
+ lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
+ lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
+ lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
+ lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
+
+ return A_EINVAL;
+ }
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+
+ cmd->bitmask = mask;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source)
+{
+ void *osbuf;
+ WMIX_HB_CHALLENGE_RESP_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->cookie = cookie;
+ cmd->source = source;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
+ A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
+ A_UINT32 valid)
+{
+ void *osbuf;
+ WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->config.cfgmmask = mmask;
+ cmd->config.cfgtsr = tsr;
+ cmd->config.cfgrep = rep;
+ cmd->config.cfgsize = size;
+ cmd->config.cfgvalid = valid;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_stats_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
+}
+
+A_STATUS
+wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
+{
+ void *osbuf;
+ WMI_ADD_BAD_AP_CMD *cmd;
+
+ if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->badApIndex = apIndex;
+ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
+}
+
+A_STATUS
+wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
+{
+ void *osbuf;
+ WMI_DELETE_BAD_AP_CMD *cmd;
+
+ if (apIndex > WMI_MAX_BAD_AP_INDEX) {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->badApIndex = apIndex;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_abort_scan_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
+}
+
+A_STATUS
+wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
+{
+ void *osbuf;
+ WMI_SET_TX_PWR_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->dbM = dbM;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_txPwr_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
+}
+
+A_UINT16
+wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass)
+{
+ A_UINT16 activeTsids=0;
+
+ LOCK_WMI(wmip);
+ activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
+ UNLOCK_WMI(wmip);
+
+ return activeTsids;
+}
+
+A_STATUS
+wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
+}
+
+A_STATUS
+wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
+{
+ void *osbuf;
+ A_UINT32 size = sizeof(A_UINT8);
+ WMI_TARGET_ROAM_DATA *cmd;
+
+ osbuf = A_NETBUF_ALLOC(size); /* no payload */
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
+ cmd->roamDataType = roamDataType;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
+ A_UINT8 size)
+{
+ void *osbuf;
+ WMI_SET_ROAM_CTRL_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+
+ A_MEMCPY(cmd, p, size);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
+ WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
+ A_UINT8 size)
+{
+ void *osbuf;
+ WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
+
+ /* These timers can't be zero */
+ if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
+ !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
+ pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
+ !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
+ pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
+ return A_EINVAL;
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+
+ A_MEMCPY(cmd, pCmd, size);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+#ifdef CONFIG_HOST_GPIO_SUPPORT
+/* Send a command to Target to change GPIO output pins. */
+A_STATUS
+wmi_gpio_output_set(struct wmi_t *wmip,
+ A_UINT32 set_mask,
+ A_UINT32 clear_mask,
+ A_UINT32 enable_mask,
+ A_UINT32 disable_mask)
+{
+ void *osbuf;
+ WMIX_GPIO_OUTPUT_SET_CMD *output_set;
+ int size;
+
+ size = sizeof(*output_set);
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
+ set_mask, clear_mask, enable_mask, disable_mask));
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, size);
+ output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
+
+ output_set->set_mask = set_mask;
+ output_set->clear_mask = clear_mask;
+ output_set->enable_mask = enable_mask;
+ output_set->disable_mask = disable_mask;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target requesting state of the GPIO input pins */
+A_STATUS
+wmi_gpio_input_get(struct wmi_t *wmip)
+{
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
+}
+
+/* Send a command to the Target that changes the value of a GPIO register. */
+A_STATUS
+wmi_gpio_register_set(struct wmi_t *wmip,
+ A_UINT32 gpioreg_id,
+ A_UINT32 value)
+{
+ void *osbuf;
+ WMIX_GPIO_REGISTER_SET_CMD *register_set;
+ int size;
+
+ size = sizeof(*register_set);
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, size);
+ register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
+
+ register_set->gpioreg_id = gpioreg_id;
+ register_set->value = value;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target to fetch the value of a GPIO register. */
+A_STATUS
+wmi_gpio_register_get(struct wmi_t *wmip,
+ A_UINT32 gpioreg_id)
+{
+ void *osbuf;
+ WMIX_GPIO_REGISTER_GET_CMD *register_get;
+ int size;
+
+ size = sizeof(*register_get);
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, size);
+ register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
+
+ register_get->gpioreg_id = gpioreg_id;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target acknowledging some GPIO interrupts. */
+A_STATUS
+wmi_gpio_intr_ack(struct wmi_t *wmip,
+ A_UINT32 ack_mask)
+{
+ void *osbuf;
+ WMIX_GPIO_INTR_ACK_CMD *intr_ack;
+ int size;
+
+ size = sizeof(*intr_ack);
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, size);
+ intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
+
+ intr_ack->ack_mask = ack_mask;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+A_STATUS
+wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin,
+ A_UINT8 eCWmax, A_UINT8 aifsn)
+{
+ void *osbuf;
+ WMI_SET_ACCESS_PARAMS_CMD *cmd;
+
+ if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
+ (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
+ {
+ return A_EINVAL;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->txop = txop;
+ cmd->eCWmin = eCWmin;
+ cmd->eCWmax = eCWmax;
+ cmd->aifsn = aifsn;
+ cmd->ac = ac;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
+ A_UINT8 trafficClass, A_UINT8 maxRetries,
+ A_UINT8 enableNotify)
+{
+ void *osbuf;
+ WMI_SET_RETRY_LIMITS_CMD *cmd;
+
+ if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
+ (frameType != DATA_FRAMETYPE))
+ {
+ return A_EINVAL;
+ }
+
+ if (maxRetries > WMI_MAX_RETRIES) {
+ return A_EINVAL;
+ }
+
+ if (frameType != DATA_FRAMETYPE) {
+ trafficClass = 0;
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->frameType = frameType;
+ cmd->trafficClass = trafficClass;
+ cmd->maxRetries = maxRetries;
+ cmd->enableNotify = enableNotify;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+void
+wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
+{
+ if (bssid != NULL) {
+ A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
+ }
+}
+
+A_STATUS
+wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
+{
+ void *osbuf;
+ WMI_SET_OPT_MODE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->optMode = optMode;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
+ SYNC_BOTH_WMIFLAG));
+}
+
+A_STATUS
+wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
+ A_UINT8 frmType,
+ A_UINT8 *dstMacAddr,
+ A_UINT8 *bssid,
+ A_UINT16 optIEDataLen,
+ A_UINT8 *optIEData)
+{
+ void *osbuf;
+ WMI_OPT_TX_FRAME_CMD *cmd;
+ osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
+
+ cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
+
+ cmd->frmType = frmType;
+ cmd->optIEDataLen = optIEDataLen;
+ //cmd->optIEData = (A_UINT8 *)((int)cmd + sizeof(*cmd));
+ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+ A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
+ A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
+{
+ void *osbuf;
+ WMI_BEACON_INT_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->beaconInterval = intvl;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
+{
+ void *osbuf;
+ WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->voicePktSize = voicePktSize;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
+{
+ void *osbuf;
+ WMI_SET_MAX_SP_LEN_CMD *cmd;
+
+ /* maxSPLen is a two-bit value. If user trys to set anything
+ * other than this, then its invalid
+ */
+ if(maxSPLen & ~0x03)
+ return A_EINVAL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->maxSPLen = maxSPLen;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_UINT8
+wmi_determine_userPriority(
+ A_UINT8 *pkt,
+ A_UINT32 layer2Pri)
+{
+ A_UINT8 ipPri;
+ iphdr *ipHdr = (iphdr *)pkt;
+
+ /* Determine IPTOS priority */
+ /*
+ * IP Tos format :
+ * (Refer Pg 57 WMM-test-plan-v1.2)
+ * IP-TOS - 8bits
+ * : DSCP(6-bits) ECN(2-bits)
+ * : DSCP - P2 P1 P0 X X X
+ * where (P2 P1 P0) form 802.1D
+ */
+ ipPri = ipHdr->ip_tos >> 5;
+ ipPri &= 0x7;
+
+ if ((layer2Pri & 0x7) > ipPri)
+ return ((A_UINT8)layer2Pri & 0x7);
+ else
+ return ipPri;
+}
+
+A_UINT8
+convert_userPriority_to_trafficClass(A_UINT8 userPriority)
+{
+ return (up_to_ac[userPriority & 0x7]);
+}
+
+A_UINT8
+wmi_get_power_mode_cmd(struct wmi_t *wmip)
+{
+ return wmip->wmi_powerMode;
+}
+
+A_STATUS
+wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
+{
+ A_STATUS ret = A_OK;
+
+#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
+#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
+#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
+#define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
+#define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
+#define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
+
+ /* Verify TSPEC params for ATHEROS compliance */
+ if(tspecCompliance == ATHEROS_COMPLIANCE) {
+ if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
+ (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
+ (pCmd->minDataRate != pCmd->meanDataRate) ||
+ (pCmd->minDataRate != pCmd->peakDataRate) ||
+ (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
+ (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
+ (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
+ (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
+ //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
+ ret = A_EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+static A_STATUS
+wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
+
+ return A_OK;
+}
+
+#endif /* CONFIG_HOST_TCMD_SUPPORT*/
+
+A_STATUS
+wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
+{
+ void *osbuf;
+ WMI_SET_AUTH_MODE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->mode = mode;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
+{
+ void *osbuf;
+ WMI_SET_REASSOC_MODE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->mode = mode;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy)
+{
+ void *osbuf;
+ WMI_SET_LPREAMBLE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->status = status;
+ cmd->preamblePolicy = preamblePolicy;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold)
+{
+ void *osbuf;
+ WMI_SET_RTS_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->threshold = threshold;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
+{
+ void *osbuf;
+ WMI_SET_WMM_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->status = status;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status)
+{
+ void *osbuf;
+ WMI_SET_QOS_SUPP_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->status = status;
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
+{
+ void *osbuf;
+ WMI_SET_WMM_TXOP_CMD *cmd;
+
+ if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
+ return A_EINVAL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->txopEnable = cfg;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode)
+{
+ void *osbuf;
+ WMI_AP_SET_COUNTRY_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ A_MEMCPY(cmd->countryCode,countryCode,3);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+#ifdef CONFIG_HOST_TCMD_SUPPORT
+/* WMI layer doesn't need to know the data type of the test cmd.
+ This would be beneficial for customers like Qualcomm, who might
+ have different test command requirements from differnt manufacturers
+ */
+A_STATUS
+wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len)
+{
+ void *osbuf;
+ char *data;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ osbuf= A_NETBUF_ALLOC(len);
+ if(osbuf == NULL)
+ {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, len);
+ data = A_NETBUF_DATA(osbuf);
+ A_MEMCPY(data, buf, len);
+
+ return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+#endif
+
+A_STATUS
+wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status)
+{
+ void *osbuf;
+ WMI_SET_BT_STATUS_CMD *cmd;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->streamType = streamType;
+ cmd->status = status;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
+{
+ void *osbuf;
+ WMI_SET_BT_PARAMS_CMD* alloc_cmd;
+
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
+
+ if (cmd->paramType == BT_PARAM_SCO) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
+ cmd->info.scoParams.dataResponseTimeout,
+ cmd->info.scoParams.stompScoRules,
+ cmd->info.scoParams.scoOptFlags,
+ cmd->info.scoParams.stompDutyCyleVal,
+ cmd->info.scoParams.stompDutyCyleMaxVal,
+ cmd->info.scoParams.psPollLatencyFraction,
+ cmd->info.scoParams.noSCOSlots,
+ cmd->info.scoParams.noIdleSlots,
+ cmd->info.scoParams.scoOptOffRssi,
+ cmd->info.scoParams.scoOptOnRssi,
+ cmd->info.scoParams.scoOptRtsCount));
+ }
+ else if (cmd->paramType == BT_PARAM_A2DP) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
+ cmd->info.a2dpParams.a2dpBurstCntMin,
+ cmd->info.a2dpParams.a2dpDataRespTimeout,
+ cmd->info.a2dpParams.a2dpOptFlags,
+ cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
+ cmd->info.a2dpParams.a2dpOptOffRssi,
+ cmd->info.a2dpParams.a2dpOptOnRssi,
+ cmd->info.a2dpParams.a2dpOptRtsCount));
+ }
+ else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
+ }
+ else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
+ }
+ else if (cmd->paramType == BT_PARAM_ACLCOEX) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
+ cmd->info.aclCoexParams.aclBtMediumUsageTime,
+ cmd->info.aclCoexParams.aclDataRespTimeout));
+ }
+ else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
+ A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
+ }
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+
+A_STATUS
+wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
+ A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
+{
+ void *osbuf;
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
+{
+ void *osbuf;
+ WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
+ return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
+ NO_SYNC_WMIFLAG));
+
+}
+
+A_STATUS
+wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
+{
+
+ return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
+
+}
+
+A_STATUS
+wmi_get_keepalive_configured(struct wmi_t *wmip)
+{
+ void *osbuf;
+ WMI_GET_KEEPALIVE_CMD *cmd;
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+ cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_UINT8
+wmi_get_keepalive_cmd(struct wmi_t *wmip)
+{
+ return wmip->wmi_keepaliveInterval;
+}
+
+A_STATUS
+wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval)
+{
+ void *osbuf;
+ WMI_SET_KEEPALIVE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->keepaliveInterval = keepaliveInterval;
+ wmip->wmi_keepaliveInterval = keepaliveInterval;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer)
+{
+ void *osbuf;
+ WMI_SET_PARAMS_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
+
+ cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->opcode = opcode;
+ cmd->length = length;
+ A_MEMCPY(cmd->buffer, buffer, length);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
+{
+ void *osbuf;
+ WMI_SET_MCAST_FILTER_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->multicast_mac[0] = 0x01;
+ cmd->multicast_mac[1] = 0x00;
+ cmd->multicast_mac[2] = 0x5e;
+ cmd->multicast_mac[3] = dot2&0x7F;
+ cmd->multicast_mac[4] = dot3;
+ cmd->multicast_mac[5] = dot4;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
+{
+ void *osbuf;
+ WMI_SET_MCAST_FILTER_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->multicast_mac[0] = 0x01;
+ cmd->multicast_mac[1] = 0x00;
+ cmd->multicast_mac[2] = 0x5e;
+ cmd->multicast_mac[3] = dot2&0x7F;
+ cmd->multicast_mac[4] = dot3;
+ cmd->multicast_mac[5] = dot4;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable)
+{
+ void *osbuf;
+ WMI_MCAST_FILTER_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->enable = enable;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,
+ A_UINT8 *ieInfo)
+{
+ void *osbuf;
+ WMI_SET_APPIE_CMD *cmd;
+ A_UINT16 cmdLen;
+
+ cmdLen = sizeof(*cmd) + ieLen - 1;
+ osbuf = A_NETBUF_ALLOC(cmdLen);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, cmdLen);
+
+ cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, cmdLen);
+
+ cmd->mgmtFrmType = mgmtFrmType;
+ cmd->ieLen = ieLen;
+ A_MEMCPY(cmd->ieInfo, ieInfo, ieLen);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen)
+{
+ void *osbuf;
+ A_UINT8 *data;
+
+ osbuf = A_NETBUF_ALLOC(dataLen);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, dataLen);
+
+ data = A_NETBUF_DATA(osbuf);
+
+ A_MEMCPY(data, cmd, dataLen);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_INT32
+wmi_get_rate(A_INT8 rateindex)
+{
+ if (rateindex == RATE_AUTO) {
+ return 0;
+ } else {
+ return(wmi_rateTable[(A_UINT32) rateindex][0]);
+ }
+}
+
+void
+wmi_node_return (struct wmi_t *wmip, bss_t *bss)
+{
+ if (NULL != bss)
+ {
+ wlan_node_return (&wmip->wmi_scan_table, bss);
+ }
+}
+
+void
+wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge)
+{
+ wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
+}
+
+bss_t *
+wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
+ A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
+{
+ bss_t *node = NULL;
+ node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
+ ssidLength, bIsWPA2, bMatchSSID);
+ return node;
+}
+
+
+#ifdef THREAD_X
+void
+wmi_refresh_scan_table (struct wmi_t *wmip)
+{
+ wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
+}
+#endif
+
+void
+wmi_free_allnodes(struct wmi_t *wmip)
+{
+ wlan_free_allnodes(&wmip->wmi_scan_table);
+}
+
+bss_t *
+wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
+{
+ bss_t *ni=NULL;
+ ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
+ return ni;
+}
+
+void
+wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
+{
+ bss_t *ni=NULL;
+
+ ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
+ if (ni != NULL) {
+ wlan_node_reclaim(&wmip->wmi_scan_table, ni);
+ }
+
+ return;
+}
+
+A_STATUS
+wmi_dset_open_reply(struct wmi_t *wmip,
+ A_UINT32 status,
+ A_UINT32 access_cookie,
+ A_UINT32 dset_size,
+ A_UINT32 dset_version,
+ A_UINT32 targ_handle,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg)
+{
+ void *osbuf;
+ WMIX_DSETOPEN_REPLY_CMD *open_reply;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*open_reply));
+ open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
+
+ open_reply->status = status;
+ open_reply->targ_dset_handle = targ_handle;
+ open_reply->targ_reply_fn = targ_reply_fn;
+ open_reply->targ_reply_arg = targ_reply_arg;
+ open_reply->access_cookie = access_cookie;
+ open_reply->size = dset_size;
+ open_reply->version = dset_version;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+static A_STATUS
+wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
+{
+ WMI_PMKID_LIST_REPLY *reply;
+ A_UINT32 expected_len;
+
+ if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_PMKID_LIST_REPLY *)datap;
+ expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
+
+ if (len < expected_len) {
+ return A_EINVAL;
+ }
+
+ A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
+ reply->pmkidList, reply->bssidList[0]);
+
+ return A_OK;
+}
+
+
+static A_STATUS
+wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
+{
+ WMI_SET_PARAMS_REPLY *reply;
+
+ if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
+ return A_EINVAL;
+ }
+ reply = (WMI_SET_PARAMS_REPLY *)datap;
+
+ if (A_OK == reply->status)
+ {
+
+ }
+ else
+ {
+
+ }
+
+ return A_OK;
+}
+
+
+
+static A_STATUS
+wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
+{
+ WMI_ACM_REJECT_EVENT *ev;
+
+ ev = (WMI_ACM_REJECT_EVENT *)datap;
+ wmip->wmi_traffic_class = ev->trafficClass;
+ printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
+ return A_OK;
+}
+
+
+#ifdef CONFIG_HOST_DSET_SUPPORT
+A_STATUS
+wmi_dset_data_reply(struct wmi_t *wmip,
+ A_UINT32 status,
+ A_UINT8 *user_buf,
+ A_UINT32 length,
+ A_UINT32 targ_buf,
+ A_UINT32 targ_reply_fn,
+ A_UINT32 targ_reply_arg)
+{
+ void *osbuf;
+ WMIX_DSETDATA_REPLY_CMD *data_reply;
+ A_UINT32 size;
+
+ size = sizeof(*data_reply) + length;
+
+ if (size <= length) {
+ return A_ERROR;
+ }
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+ A_NETBUF_PUT(osbuf, size);
+ data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
+
+ data_reply->status = status;
+ data_reply->targ_buf = targ_buf;
+ data_reply->targ_reply_fn = targ_reply_fn;
+ data_reply->targ_reply_arg = targ_reply_arg;
+ data_reply->length = length;
+
+ if (status == A_OK) {
+ if (a_copy_from_user(data_reply->buf, user_buf, length)) {
+ A_NETBUF_FREE(osbuf);
+ return A_ERROR;
+ }
+ }
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+A_STATUS
+wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status)
+{
+ void *osbuf;
+ char *cmd;
+
+ wps_enable = status;
+
+ osbuf = a_netbuf_alloc(sizeof(1));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ a_netbuf_put(osbuf, sizeof(1));
+
+ cmd = (char *)(a_netbuf_to_data(osbuf));
+
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd[0] = (status?1:0);
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
+A_STATUS
+wmi_prof_cfg_cmd(struct wmi_t *wmip,
+ A_UINT32 period,
+ A_UINT32 nbins)
+{
+ void *osbuf;
+ WMIX_PROF_CFG_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->period = period;
+ cmd->nbins = nbins;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr)
+{
+ void *osbuf;
+ WMIX_PROF_ADDR_SET_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->addr = addr;
+
+ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_prof_start_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
+}
+
+A_STATUS
+wmi_prof_stop_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
+}
+
+A_STATUS
+wmi_prof_count_get_cmd(struct wmi_t *wmip)
+{
+ return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
+}
+
+/* Called to handle WMIX_PROF_CONT_EVENTID */
+static A_STATUS
+wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
+
+ A_DPRINTF(DBG_WMI,
+ (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
+ prof_data->addr, prof_data->count));
+
+ A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
+
+ return A_OK;
+}
+#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
+
+#ifdef OS_ROAM_MANAGEMENT
+
+#define ETHERNET_MAC_ADDRESS_LENGTH 6
+
+void
+wmi_scan_indication (struct wmi_t *wmip)
+{
+ struct ieee80211_node_table *nt;
+ A_UINT32 gen;
+ A_UINT32 size;
+ A_UINT32 bsssize;
+ bss_t *bss;
+ A_UINT32 numbss;
+ PNDIS_802_11_BSSID_SCAN_INFO psi;
+ PBYTE pie;
+ NDIS_802_11_FIXED_IEs *pFixed;
+ NDIS_802_11_VARIABLE_IEs *pVar;
+ A_UINT32 RateSize;
+
+ struct ar6kScanIndication
+ {
+ NDIS_802_11_STATUS_INDICATION ind;
+ NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
+ } *pAr6kScanIndEvent;
+
+ nt = &wmip->wmi_scan_table;
+
+ ++nt->nt_si_gen;
+
+
+ gen = nt->nt_si_gen;
+
+ size = offsetof(struct ar6kScanIndication, slist) +
+ offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
+
+ numbss = 0;
+
+ IEEE80211_NODE_LOCK(nt);
+
+ //calc size
+ for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
+ if (bss->ni_si_gen != gen) {
+ bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
+ bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
+
+#ifdef SUPPORT_WPA2
+ if (bss->ni_cie.ie_rsn) {
+ bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
+ }
+#endif
+ if (bss->ni_cie.ie_wpa) {
+ bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
+ }
+
+ // bsssize must be a multiple of 4 to maintain alignment.
+ bsssize = (bsssize + 3) & ~3;
+
+ size += bsssize;
+
+ numbss++;
+ }
+ }
+
+ if (0 == numbss)
+ {
+// RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
+ ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
+ IEEE80211_NODE_UNLOCK (nt);
+ return;
+ }
+
+ pAr6kScanIndEvent = A_MALLOC(size);
+
+ if (NULL == pAr6kScanIndEvent)
+ {
+ IEEE80211_NODE_UNLOCK(nt);
+ return;
+ }
+
+ A_MEMZERO(pAr6kScanIndEvent, size);
+
+ //copy data
+ pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
+ pAr6kScanIndEvent->slist.Version = 1;
+ pAr6kScanIndEvent->slist.NumItems = numbss;
+
+ psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
+
+ for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
+ if (bss->ni_si_gen != gen) {
+
+ bss->ni_si_gen = gen;
+
+ //Set scan time
+ psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
+
+ // Copy data to bssid_ex
+ bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
+ bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
+
+#ifdef SUPPORT_WPA2
+ if (bss->ni_cie.ie_rsn) {
+ bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
+ }
+#endif
+ if (bss->ni_cie.ie_wpa) {
+ bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
+ }
+
+ // bsssize must be a multiple of 4 to maintain alignment.
+ bsssize = (bsssize + 3) & ~3;
+
+ psi->Bssid.Length = bsssize;
+
+ memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
+
+
+//if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
+// ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
+// RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
+
+ psi->Bssid.Ssid.SsidLength = 0;
+ pie = bss->ni_cie.ie_ssid;
+
+ if (pie) {
+ // Format of SSID IE is:
+ // Type (1 octet)
+ // Length (1 octet)
+ // SSID (Length octets)
+ //
+ // Validation of the IE should have occurred within WMI.
+ //
+ if (pie[1] <= 32) {
+ psi->Bssid.Ssid.SsidLength = pie[1];
+ memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
+ }
+ }
+ psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
+
+ //Post the RSSI value relative to the Standard Noise floor value.
+ psi->Bssid.Rssi = bss->ni_rssi;
+
+ if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
+
+ if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
+ psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
+ }
+ else {
+ psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
+ }
+ }
+ else {
+ psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
+ }
+
+ psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
+ psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
+ psi->Bssid.Configuration.ATIMWindow = 0;
+ psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
+ psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
+
+ RateSize = 0;
+ pie = bss->ni_cie.ie_rates;
+ if (pie) {
+ RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
+ memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
+ }
+ pie = bss->ni_cie.ie_xrates;
+ if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
+ memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
+ (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
+ }
+
+ // Copy the fixed IEs
+ psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
+
+ pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
+ memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
+ pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
+ pFixed->Capabilities = bss->ni_cie.ie_capInfo;
+
+ // Copy selected variable IEs
+
+ pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
+
+#ifdef SUPPORT_WPA2
+ // Copy the WPAv2 IE
+ if (bss->ni_cie.ie_rsn) {
+ pie = bss->ni_cie.ie_rsn;
+ psi->Bssid.IELength += pie[1] + 2;
+ memcpy(pVar, pie, pie[1] + 2);
+ pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
+ }
+#endif
+ // Copy the WPAv1 IE
+ if (bss->ni_cie.ie_wpa) {
+ pie = bss->ni_cie.ie_wpa;
+ psi->Bssid.IELength += pie[1] + 2;
+ memcpy(pVar, pie, pie[1] + 2);
+ pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
+ }
+
+ // Advance buffer pointer
+ psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
+ }
+ }
+
+ IEEE80211_NODE_UNLOCK(nt);
+
+// wmi_free_allnodes(wmip);
+
+// RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
+
+ ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
+
+ A_FREE(pAr6kScanIndEvent);
+}
+#endif
+
+A_UINT8
+ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
+ A_UINT32 size)
+{
+ A_UINT32 index;
+ A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1];
+
+ /* The list is already in sorted order. Get the next lower value */
+ for (index = 0; index < size; index ++) {
+ if (rssi < sq_thresh->upper_threshold[index]) {
+ threshold = (A_UINT8)sq_thresh->upper_threshold[index];
+ break;
+ }
+ }
+
+ return threshold;
+}
+
+A_UINT8
+ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
+ A_UINT32 size)
+{
+ A_UINT32 index;
+ A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1];
+
+ /* The list is already in sorted order. Get the next lower value */
+ for (index = 0; index < size; index ++) {
+ if (rssi > sq_thresh->lower_threshold[index]) {
+ threshold = (A_UINT8)sq_thresh->lower_threshold[index];
+ break;
+ }
+ }
+
+ return threshold;
+}
+static A_STATUS
+wmi_send_rssi_threshold_params(struct wmi_t *wmip,
+ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+
+ cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+static A_STATUS
+wmi_send_snr_threshold_params(struct wmi_t *wmip,
+ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
+{
+ void *osbuf;
+ A_INT8 size;
+ WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
+
+ size = sizeof (*cmd);
+
+ osbuf = A_NETBUF_ALLOC(size);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, size);
+ cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, size);
+ A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
+{
+ void *osbuf;
+ WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(alloc_cmd, sizeof(*cmd));
+ A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id)
+{
+ wmi_get_current_bssid (wmip, id);
+ return wlan_node_remove (&wmip->wmi_scan_table, id);
+}
+
+A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss)
+{
+ wlan_setup_node (&wmip->wmi_scan_table, bss, id);
+ return A_OK;
+}
+
+#ifdef ATH_AR6K_11N_SUPPORT
+static A_STATUS
+wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
+
+ A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
+
+ return A_OK;
+}
+
+
+static A_STATUS
+wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
+
+ A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
+
+ return A_OK;
+}
+
+static A_STATUS
+wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
+
+ A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
+
+ return A_OK;
+}
+
+A_STATUS
+wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
+
+ return A_OK;
+}
+
+
+A_STATUS
+wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len)
+{
+ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
+
+ A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
+
+ return A_OK;
+
+}
+#endif
+
+static A_STATUS
+wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
+ A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
+
+ return A_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// ////
+//// AP mode functions ////
+//// ////
+////////////////////////////////////////////////////////////////////////////////
+/*
+ * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
+ *
+ * When AR6K in AP mode, This command will be called after
+ * changing ssid, channel etc. It will pass the profile to
+ * target with a flag which will indicate which parameter changed,
+ * also if this flag is 0, there was no change in parametes, so
+ * commit cmd will not be sent to target. Without calling this IOCTL
+ * the changes will not take effect.
+ */
+A_STATUS
+wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
+{
+ void *osbuf;
+ WMI_CONNECT_CMD *cm;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cm));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cm));
+ cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cm, sizeof(*cm));
+
+ A_MEMCPY(cm,p,sizeof(*cm));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
+ *
+ * This command will be used to enable/disable hidden ssid functioanlity of
+ * beacon. If it is enabled, ssid will be NULL in beacon.
+ */
+A_STATUS
+wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid)
+{
+ void *osbuf;
+ WMI_AP_HIDDEN_SSID_CMD *hs;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
+ hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(hs, sizeof(*hs));
+
+ hs->hidden_ssid = hidden_ssid;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
+ *
+ * This command is used to limit max num of STA that can connect
+ * with this AP. This value should not exceed AP_MAX_NUM_STA (this
+ * is max num of STA supported by AP). Value was already validated
+ * in ioctl.c
+ */
+A_STATUS
+wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta)
+{
+ void *osbuf;
+ WMI_AP_SET_NUM_STA_CMD *ns;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
+ ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(ns, sizeof(*ns));
+
+ ns->num_sta = num_sta;
+
+ A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
+ *
+ * This command is used to send list of mac of STAs which will
+ * be allowed to connect with this AP. When this list is empty
+ * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
+ */
+A_STATUS
+wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
+{
+ void *osbuf;
+ WMI_AP_ACL_MAC_CMD *a;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
+ a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(a, sizeof(*a));
+ A_MEMCPY(a,acl,sizeof(*acl));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * IOCTL: AR6000_XIOCTL_AP_SET_MLME
+ *
+ * This command is used to send list of mac of STAs which will
+ * be allowed to connect with this AP. When this list is empty
+ * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
+ */
+A_STATUS
+wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason)
+{
+ void *osbuf;
+ WMI_AP_SET_MLME_CMD *mlme;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
+ mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(mlme, sizeof(*mlme));
+
+ mlme->cmd = cmd;
+ A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN);
+ mlme->reason = reason;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
+}
+
+static A_STATUS
+wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+ WMI_PSPOLL_EVENT *ev;
+
+ if (len < sizeof(WMI_PSPOLL_EVENT)) {
+ return A_EINVAL;
+ }
+ ev = (WMI_PSPOLL_EVENT *)datap;
+
+ A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
+ return A_OK;
+}
+
+static A_STATUS
+wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
+{
+ A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
+ return A_OK;
+}
+
+#ifdef WAPI_ENABLE
+static A_STATUS
+wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
+{
+ A_UINT8 *ev;
+
+ if (len < 7) {
+ return A_EINVAL;
+ }
+ ev = (A_UINT8 *)datap;
+
+ A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
+ return A_OK;
+}
+#endif
+
+A_STATUS
+wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag)
+{
+ WMI_AP_SET_PVB_CMD *cmd;
+ void *osbuf = NULL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
+ cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->aid = aid;
+ cmd->flag = flag;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period)
+{
+ WMI_AP_CONN_INACT_CMD *cmd;
+ void *osbuf = NULL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
+ cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->period = period;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell)
+{
+ WMI_AP_PROT_SCAN_TIME_CMD *cmd;
+ void *osbuf = NULL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
+ cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->period_min = period;
+ cmd->dwell_ms = dwell;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim)
+{
+ WMI_AP_SET_DTIM_CMD *cmd;
+ void *osbuf = NULL;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
+ cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+
+ cmd->dtim = dtim;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
+}
+
+/*
+ * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
+ *
+ * This command is used to set ACL policay. While changing policy, if you
+ * want to retain the existing MAC addresses in the ACL list, policy should be
+ * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
+ * If there is no chage in policy, the list will be intact.
+ */
+A_STATUS
+wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy)
+{
+ void *osbuf;
+ WMI_AP_ACL_POLICY_CMD *po;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+}
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
+ po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(po, sizeof(*po));
+
+ po->policy = policy;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset)
+{
+ void *osbuf;
+ WMI_AP_SET_11BG_RATESET_CMD *rs;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
+ rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(rs, sizeof(*rs));
+
+ rs->rateset = rateset;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
+}
+
+#ifdef ATH_AR6K_11N_SUPPORT
+A_STATUS
+wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
+{
+ void *osbuf;
+ WMI_SET_HT_CAP_CMD *htCap;
+ A_UINT8 band;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*htCap));
+
+ band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
+ wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
+
+ htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(htCap, sizeof(*htCap));
+ A_MEMCPY(htCap, cmd, sizeof(*htCap));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width)
+{
+ void *osbuf;
+ WMI_SET_HT_OP_CMD *htInfo;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*htInfo));
+
+ htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(htInfo, sizeof(*htInfo));
+ htInfo->sta_chan_width = sta_chan_width;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+#endif
+
+A_STATUS
+wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray)
+{
+ void *osbuf;
+ WMI_SET_TX_SELECT_RATES_CMD *pData;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*pData));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*pData));
+
+ pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMCPY(pData, pMaskArray, sizeof(*pData));
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz)
+{
+ void *osbuf;
+ WMI_HCI_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
+ cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
+
+ cmd->cmd_buf_sz = sz;
+ A_MEMCPY(cmd->buf, buf, sz);
+ return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
+}
+
+#ifdef ATH_AR6K_11N_SUPPORT
+A_STATUS
+wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask)
+{
+ void *osbuf;
+ WMI_ALLOW_AGGR_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->tx_allow_aggr = tx_tidmask;
+ cmd->rx_allow_aggr = rx_tidmask;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid)
+{
+ void *osbuf;
+ WMI_ADDBA_REQ_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->tid = tid;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink)
+{
+ void *osbuf;
+ WMI_DELBA_REQ_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->tid = tid;
+ cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
+
+ /* Delete the local aggr state, on host */
+ return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
+}
+#endif
+
+A_STATUS
+wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion,
+ A_BOOL rxDot11Hdr, A_BOOL defragOnHost)
+{
+ void *osbuf;
+ WMI_RX_FRAME_FORMAT_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0;
+ cmd->defragOnHost = (defragOnHost==TRUE)? 1:0;
+ cmd->metaVersion = rxMetaVersion; /* */
+
+ /* Delete the local aggr state, on host */
+ return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode)
+{
+ void *osbuf;
+ WMI_SET_THIN_MODE_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
+ cmd->enable = (bThinMode==TRUE)? 1:0;
+
+ /* Delete the local aggr state, on host */
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
+{
+ void *osbuf;
+ WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->precedence = precedence;
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk)
+{
+ void *osbuf;
+ WMI_SET_PMK_CMD *p;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
+
+ p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(p, sizeof(*p));
+
+ A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN);
+
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold)
+{
+ void *osbuf;
+ WMI_SET_TX_SGI_PARAM_CMD *cmd;
+
+ osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
+ if (osbuf == NULL) {
+ return A_NO_MEMORY ;
+ }
+
+ A_NETBUF_PUT(osbuf, sizeof(*cmd));
+
+ cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
+ A_MEMZERO(cmd, sizeof(*cmd));
+ cmd->sgiMask = sgiMask;
+ cmd->sgiPERThreshold = sgiPERThreshold;
+ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
+ NO_SYNC_WMIFLAG));
+}
+
+bss_t *
+wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
+ A_UINT32 ssidLength,
+ A_UINT32 dot11AuthMode, A_UINT32 authMode,
+ A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp)
+{
+ bss_t *node = NULL;
+ node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
+ ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
+
+ return node;
+}
+
+A_UINT16
+wmi_ieee2freq (int chan)
+{
+ A_UINT16 freq = 0;
+ freq = wlan_ieee2freq (chan);
+ return freq;
+
+}
+
+A_UINT32
+wmi_freq2ieee (A_UINT16 freq)
+{
+ A_UINT16 chan = 0;
+ chan = wlan_freq2ieee (freq);
+ return chan;
+}
diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h
new file mode 100644
index 000000000000..5c7f7d3c3ce1
--- /dev/null
+++ b/drivers/staging/ath6kl/wmi/wmi_host.h
@@ -0,0 +1,102 @@
+//------------------------------------------------------------------------------
+// <copyright file="wmi_host.h" company="Atheros">
+// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
+//
+//
+// 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.
+//
+//
+//------------------------------------------------------------------------------
+//==============================================================================
+// This file contains local definitios for the wmi host module.
+//
+// Author(s): ="Atheros"
+//==============================================================================
+#ifndef _WMI_HOST_H_
+#define _WMI_HOST_H_
+
+#include "roaming.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct wmi_stats {
+ A_UINT32 cmd_len_err;
+ A_UINT32 cmd_id_err;
+};
+
+#define SSID_IE_LEN_INDEX 13
+
+/* Host side link management data structures */
+#define SIGNAL_QUALITY_THRESHOLD_LEVELS 6
+#define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
+#define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS
+typedef struct sq_threshold_params_s {
+ A_INT16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS];
+ A_INT16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS];
+ A_UINT32 upper_threshold_valid_count;
+ A_UINT32 lower_threshold_valid_count;
+ A_UINT32 polling_interval;
+ A_UINT8 weight;
+ A_UINT8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target.
+ A_UINT8 last_rssi_poll_event; //Not sure if it belongs to host or target
+} SQ_THRESHOLD_PARAMS;
+
+/*
+ * These constants are used with A_WLAN_BAND_SET.
+ */
+#define A_BAND_24GHZ 0
+#define A_BAND_5GHZ 1
+#define A_NUM_BANDS 2
+
+struct wmi_t {
+ A_BOOL wmi_ready;
+ A_BOOL wmi_numQoSStream;
+ A_UINT16 wmi_streamExistsForAC[WMM_NUM_AC];
+ A_UINT8 wmi_fatPipeExists;
+ void *wmi_devt;
+ struct wmi_stats wmi_stats;
+ struct ieee80211_node_table wmi_scan_table;
+ A_UINT8 wmi_bssid[ATH_MAC_LEN];
+ A_UINT8 wmi_powerMode;
+ A_UINT8 wmi_phyMode;
+ A_UINT8 wmi_keepaliveInterval;
+#ifdef THREAD_X
+ A_CSECT_T wmi_lock;
+#else
+ A_MUTEX_T wmi_lock;
+#endif
+ HTC_ENDPOINT_ID wmi_endpoint_id;
+ SQ_THRESHOLD_PARAMS wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX];
+ CRYPTO_TYPE wmi_pair_crypto_type;
+ CRYPTO_TYPE wmi_grp_crypto_type;
+ A_BOOL wmi_is_wmm_enabled;
+ A_UINT8 wmi_ht_allowed[A_NUM_BANDS];
+ A_UINT8 wmi_traffic_class;
+};
+
+#ifdef THREAD_X
+#define INIT_WMI_LOCK(w) A_CSECT_INIT(&(w)->wmi_lock)
+#define LOCK_WMI(w) A_CSECT_ENTER(&(w)->wmi_lock);
+#define UNLOCK_WMI(w) A_CSECT_LEAVE(&(w)->wmi_lock);
+#define DELETE_WMI_LOCK(w) A_CSECT_DELETE(&(w)->wmi_lock);
+#else
+#define LOCK_WMI(w) A_MUTEX_LOCK(&(w)->wmi_lock);
+#define UNLOCK_WMI(w) A_MUTEX_UNLOCK(&(w)->wmi_lock);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_HOST_H_ */
diff --git a/drivers/staging/batman-adv/CHANGELOG b/drivers/staging/batman-adv/CHANGELOG
deleted file mode 100644
index 86450b4f7d76..000000000000
--- a/drivers/staging/batman-adv/CHANGELOG
+++ /dev/null
@@ -1,63 +0,0 @@
-batman-adv 2010.0.0:
-
-* support latest kernels (2.6.21 - 2.6.35)
-* further code refactoring and cleaning for coding style
-* move from procfs based configuration to sysfs
-* reorganized sequence number handling
-* limit queue lengths for batman and broadcast packets
-* many bugs (endless loop and rogue packets on shutdown, wrong tcpdump output,
- missing frees in error situations, sleeps in atomic contexts) squashed
-
- -- Fri, 18 Jun 2010 21:34:26 +0200
-
-batman-adv 0.2.1:
-
-* support latest kernels (2.6.20 - 2.6.33)
-* receive packets directly using skbs, remove old sockets and threads
-* fix various regressions in the vis server
-* don't disable interrupts while sending
-* replace internal logging mechanism with standard kernel logging
-* move vis formats into userland, one general format remains in the kernel
-* allow MAC address to be set, correctly initialize them
-* code refactoring and cleaning for coding style
-* many bugs (null pointers, locking, hash iterators) squashed
-
- -- Sun, 21 Mar 2010 20:46:47 +0100
-
-batman-adv 0.2:
-
-* support latest kernels (2.6.20 - 2.6.31)
-* temporary routing loops / TTL code bug / ghost entries in originator table fixed
-* internal packet queue for packet aggregation & transmission retry (ARQ)
- for payload broadcasts added
-* interface detection converted to event based handling to avoid timers
-* major linux coding style adjustments applied
-* all kernel version compatibility functions has been moved to compat.h
-* use random ethernet address generator from the kernel
-* /sys/module/batman_adv/version to export kernel module version
-* vis: secondary interface export for dot draw format + JSON output format added
-* many bugs (alignment issues, race conditions, deadlocks, etc) squashed
-
- -- Sat, 07 Nov 2009 15:44:31 +0100
-
-batman-adv 0.1:
-
-* support latest kernels (2.6.20 - 2.6.28)
-* LOTS of cleanup: locking, stack usage, memory leaks
-* Change Ethertype from 0x0842 to 0x4305
- unregistered at IEEE, if you want to sponsor an official Ethertype ($2500)
- please contact us
-
- -- Sun, 28 Dec 2008 00:44:31 +0100
-
-batman-adv 0.1-beta:
-
-* layer 2 meshing based on BATMAN TQ algorithm in kernelland
-* operates on any ethernet like interface
-* supports IPv4, IPv6, DHCP, etc
-* is controlled via /proc/net/batman-adv/
-* bridging via brctl is supported
-* interface watchdog (interfaces can be (de)activated dynamically)
-* offers integrated vis server which meshes/syncs with other vis servers in range
-
- -- Mon, 05 May 2008 14:10:04 +0200
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile
index e9817b5a614c..4b5c4349cdc5 100644
--- a/drivers/staging/batman-adv/Makefile
+++ b/drivers/staging/batman-adv/Makefile
@@ -19,4 +19,4 @@
#
obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
-batman-adv-objs := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
+batman-adv-objs := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o unicast.o
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README
index 7192b7fa2183..3a975fcb8ae5 100644
--- a/drivers/staging/batman-adv/README
+++ b/drivers/staging/batman-adv/README
@@ -1,4 +1,4 @@
-[state: 12-06-2010]
+[state: 04-09-2010]
BATMAN-ADV
----------
@@ -67,15 +67,21 @@ All mesh wide settings can be found in batman's own interface
folder:
# ls /sys/class/net/bat0/mesh/
-# aggregate_ogm originators transtable_global vis_mode
-# orig_interval transtable_local vis_data
+# aggregated_ogms bonding orig_interval vis_mode
+
+
+There is a special folder for debugging informations:
+
+# ls /sys/kernel/debug/batman_adv/bat0/
+# originators socket transtable_global transtable_local
+# vis_data
Some of the files contain all sort of status information regard-
ing the mesh network. For example, you can view the table of
originators (mesh participants) with:
-# cat /sys/class/net/bat0/mesh/originators
+# cat /sys/kernel/debug/batman_adv/bat0/originators
Other files allow to change batman's behaviour to better fit your
requirements. For instance, you can check the current originator
@@ -83,7 +89,7 @@ interval (value in milliseconds which determines how often batman
sends its broadcast packets):
# cat /sys/class/net/bat0/mesh/orig_interval
-# status: 1000
+# 1000
and also change its value:
@@ -137,7 +143,7 @@ at least very similar) data.
When configured as server, you can get a topology snapshot of
your mesh:
-# cat /sys/class/net/bat0/mesh/vis_data
+# cat /sys/kernel/debug/batman_adv/bat0/vis_data
This raw output is intended to be easily parsable and convertable
with other tools. Have a look at the batctl README if you want a
@@ -181,32 +187,25 @@ enabled when compiling the batman-adv module. When building bat-
man-adv as part of kernel, use "make menuconfig" and enable the
option "B.A.T.M.A.N. debugging".
+Those additional debug messages can be accessed using a special
+file in debugfs
+
+# cat /sys/kernel/debug/batman_adv/bat0/log
+
The additional debug output is by default disabled. It can be en-
-abled either at kernel modules load time or during run time. To
-enable debug output at module load time, add the module parameter
-debug=<value>. <value> can take one of four values.
+abled during run time. Following log_levels are defined:
0 - All debug output disabled
1 - Enable messages related to routing / flooding / broadcasting
2 - Enable route or hna added / changed / deleted
3 - Enable all messages
-e.g.
-
-# modprobe batman-adv debug=2
-
-will load the module and enable debug messages for when routes or
-HNAs change.
-
-The debug output can also be changed at runtime using the file
-/sys/module/batman-adv/parameters/debug. e.g.
-
-# echo 2 > /sys/module/batman-adv/parameters/debug
+The debug output can be changed at runtime using the file
+/sys/class/net/bat0/mesh/log_level. e.g.
-enables debug messages for when routes or HNAs
+# echo 2 > /sys/class/net/bat0/mesh/log_level
-The debug output is sent to the kernel logs. So try dmesg, lo-
-gread, etc to see the debug messages.
+will enable debug messages for when routes or HNAs change.
BATCTL
diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO
index 9c5aea20be15..3af8028d9594 100644
--- a/drivers/staging/batman-adv/TODO
+++ b/drivers/staging/batman-adv/TODO
@@ -1,6 +1,8 @@
- * Use hweight* for hamming weight calculation
- * Save/cache packets direktly as skb instead of using a normal memory region
- and copying it in a skb using send_raw_packet and similar functions
+ * Rework usage of RCU
+ - don't leak pointers from rcu out of rcu critical area which may
+ get freed
+ - check were synchronize_rcu must be used
+ - go through Documentation/RCU/checklist.txt
* Request a new review
* Process the comments from the review
* Move into mainline proper
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c
index 9862d16bbdc8..46b9c2b89ddb 100644
--- a/drivers/staging/batman-adv/aggregation.c
+++ b/drivers/staging/batman-adv/aggregation.c
@@ -39,7 +39,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
struct forw_packet *forw_packet)
{
struct batman_packet *batman_packet =
- (struct batman_packet *)forw_packet->packet_buff;
+ (struct batman_packet *)forw_packet->skb->data;
int aggregated_bytes = forw_packet->packet_len + packet_len;
/**
@@ -97,21 +97,19 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* create a new aggregated packet and add this packet to it */
-static void new_aggregated_packet(unsigned char *packet_buff,
- int packet_len,
- unsigned long send_time,
- bool direct_link,
- struct batman_if *if_incoming,
- int own_packet)
+static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
+ unsigned long send_time, bool direct_link,
+ struct batman_if *if_incoming,
+ int own_packet)
{
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct forw_packet *forw_packet_aggr;
unsigned long flags;
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ unsigned char *skb_buff;
/* own packet should always be scheduled */
if (!own_packet) {
- if (!atomic_dec_not_zero(&batman_queue_left)) {
+ if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv,
"batman packet queue full\n");
return;
@@ -121,27 +119,26 @@ static void new_aggregated_packet(unsigned char *packet_buff,
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
if (!forw_packet_aggr) {
if (!own_packet)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
return;
}
- forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
- GFP_ATOMIC);
- if (!forw_packet_aggr->packet_buff) {
+ forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
+ sizeof(struct ethhdr));
+ if (!forw_packet_aggr->skb) {
if (!own_packet)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
return;
}
+ skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
INIT_HLIST_NODE(&forw_packet_aggr->list);
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
forw_packet_aggr->packet_len = packet_len;
- memcpy(forw_packet_aggr->packet_buff,
- packet_buff,
- forw_packet_aggr->packet_len);
+ memcpy(skb_buff, packet_buff, packet_len);
- forw_packet_aggr->skb = NULL;
forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->num_packets = 0;
@@ -153,9 +150,9 @@ static void new_aggregated_packet(unsigned char *packet_buff,
forw_packet_aggr->direct_link_flags |= 1;
/* add new packet to packet list */
- spin_lock_irqsave(&forw_bat_list_lock, flags);
- hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
+ hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
/* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
@@ -171,8 +168,10 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
int packet_len,
bool direct_link)
{
- memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len),
- packet_buff, packet_len);
+ unsigned char *skb_buff;
+
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
+ memcpy(skb_buff, packet_buff, packet_len);
forw_packet_aggr->packet_len += packet_len;
forw_packet_aggr->num_packets++;
@@ -199,11 +198,11 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
unsigned long flags;
/* find position for the packet in the forward queue */
- spin_lock_irqsave(&forw_bat_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
/* own packets are not to be aggregated */
if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) {
- hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
- list) {
+ hlist_for_each_entry(forw_packet_pos, tmp_node,
+ &bat_priv->forw_bat_list, list) {
if (can_aggregate_with(batman_packet,
packet_len,
send_time,
@@ -220,7 +219,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
* suitable aggregation packet found */
if (forw_packet_aggr == NULL) {
/* the following section can run without the lock */
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
/**
* if we could not aggregate this packet with one of the others
@@ -238,7 +237,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
aggregate(forw_packet_aggr,
packet_buff, packet_len,
direct_link);
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
}
}
diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c
index 507da68054c7..fb704e1f845c 100644
--- a/drivers/staging/batman-adv/bat_debugfs.c
+++ b/drivers/staging/batman-adv/bat_debugfs.c
@@ -174,6 +174,7 @@ static const struct file_operations log_fops = {
.release = log_release,
.read = log_read,
.poll = log_poll,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static int debug_log_setup(struct bat_priv *bat_priv)
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c
index 05ca15a6c9f8..06101696d313 100644
--- a/drivers/staging/batman-adv/bat_sysfs.c
+++ b/drivers/staging/batman-adv/bat_sysfs.c
@@ -134,6 +134,56 @@ static ssize_t store_bond(struct kobject *kobj, struct attribute *attr,
return count;
}
+static ssize_t show_frag(struct kobject *kobj, struct attribute *attr,
+ char *buff)
+{
+ struct device *dev = to_dev(kobj->parent);
+ struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
+ int frag_status = atomic_read(&bat_priv->frag_enabled);
+
+ return sprintf(buff, "%s\n",
+ frag_status == 0 ? "disabled" : "enabled");
+}
+
+static ssize_t store_frag(struct kobject *kobj, struct attribute *attr,
+ char *buff, size_t count)
+{
+ struct device *dev = to_dev(kobj->parent);
+ struct net_device *net_dev = to_net_dev(dev);
+ struct bat_priv *bat_priv = netdev_priv(net_dev);
+ int frag_enabled_tmp = -1;
+
+ if (((count == 2) && (buff[0] == '1')) ||
+ (strncmp(buff, "enable", 6) == 0))
+ frag_enabled_tmp = 1;
+
+ if (((count == 2) && (buff[0] == '0')) ||
+ (strncmp(buff, "disable", 7) == 0))
+ frag_enabled_tmp = 0;
+
+ if (frag_enabled_tmp < 0) {
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+
+ bat_err(net_dev,
+ "Invalid parameter for 'fragmentation' setting on mesh"
+ "received: %s\n", buff);
+ return -EINVAL;
+ }
+
+ if (atomic_read(&bat_priv->frag_enabled) == frag_enabled_tmp)
+ return count;
+
+ bat_info(net_dev, "Changing fragmentation from: %s to: %s\n",
+ atomic_read(&bat_priv->frag_enabled) == 1 ?
+ "enabled" : "disabled",
+ frag_enabled_tmp == 1 ? "enabled" : "disabled");
+
+ atomic_set(&bat_priv->frag_enabled, (unsigned)frag_enabled_tmp);
+ update_min_mtu(net_dev);
+ return count;
+}
+
static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
char *buff)
{
@@ -279,6 +329,7 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR,
show_aggr_ogms, store_aggr_ogms);
static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
+static BAT_ATTR(fragmentation, S_IRUGO | S_IWUSR, show_frag, store_frag);
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
show_orig_interval, store_orig_interval);
@@ -289,6 +340,7 @@ static BAT_ATTR(log_level, S_IRUGO | S_IWUSR, show_log_level, store_log_level);
static struct bat_attribute *mesh_attrs[] = {
&bat_attr_aggregated_ogms,
&bat_attr_bonding,
+ &bat_attr_fragmentation,
&bat_attr_vis_mode,
&bat_attr_orig_interval,
#ifdef CONFIG_BATMAN_ADV_DEBUG
@@ -304,17 +356,6 @@ int sysfs_add_meshif(struct net_device *dev)
struct bat_attribute **bat_attr;
int err;
- /* FIXME: should be done in the general mesh setup
- routine as soon as we have it */
- atomic_set(&bat_priv->aggregation_enabled, 1);
- atomic_set(&bat_priv->bonding_enabled, 0);
- atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
- atomic_set(&bat_priv->orig_interval, 1000);
- atomic_set(&bat_priv->log_level, 0);
-
- bat_priv->primary_if = NULL;
- bat_priv->num_ifaces = 0;
-
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
batif_kobject);
if (!bat_priv->mesh_obj) {
@@ -370,7 +411,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
return sprintf(buff, "%s\n",
batman_if->if_status == IF_NOT_IN_USE ?
- "none" : "bat0");
+ "none" : batman_if->soft_iface->name);
}
static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
@@ -384,32 +425,39 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
if (!batman_if)
return count;
- if (strncmp(buff, "none", 4) == 0)
- status_tmp = IF_NOT_IN_USE;
-
- if (strncmp(buff, "bat0", 4) == 0)
- status_tmp = IF_I_WANT_YOU;
-
- if (status_tmp < 0) {
- if (buff[count - 1] == '\n')
- buff[count - 1] = '\0';
+ if (buff[count - 1] == '\n')
+ buff[count - 1] = '\0';
+ if (strlen(buff) >= IFNAMSIZ) {
pr_err("Invalid parameter for 'mesh_iface' setting received: "
- "%s\n", buff);
+ "interface name too long '%s'\n", buff);
return -EINVAL;
}
- if ((batman_if->if_status == status_tmp) ||
- ((status_tmp == IF_I_WANT_YOU) &&
- (batman_if->if_status != IF_NOT_IN_USE)))
+ if (strncmp(buff, "none", 4) == 0)
+ status_tmp = IF_NOT_IN_USE;
+ else
+ status_tmp = IF_I_WANT_YOU;
+
+ if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) &&
+ (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0)))
return count;
- if (status_tmp == IF_I_WANT_YOU)
- status_tmp = hardif_enable_interface(batman_if);
- else
+ if (status_tmp == IF_NOT_IN_USE) {
+ rtnl_lock();
+ hardif_disable_interface(batman_if);
+ rtnl_unlock();
+ return count;
+ }
+
+ /* if the interface already is in use */
+ if (batman_if->if_status != IF_NOT_IN_USE) {
+ rtnl_lock();
hardif_disable_interface(batman_if);
+ rtnl_unlock();
+ }
- return (status_tmp < 0 ? status_tmp : count);
+ return hardif_enable_interface(batman_if, buff);
}
static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c
index dd4193c99d4e..814274fbaa2f 100644
--- a/drivers/staging/batman-adv/bitarray.c
+++ b/drivers/staging/batman-adv/bitarray.c
@@ -22,6 +22,8 @@
#include "main.h"
#include "bitarray.h"
+#include <linux/bitops.h>
+
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
@@ -125,11 +127,10 @@ static void bit_reset_window(TYPE_OF_WORD *seq_bits)
* 1 if the window was moved (either new or very old)
* 0 if the window was not moved/shifted.
*/
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
- int8_t set_mark)
+char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits,
+ int32_t seq_num_diff, int8_t set_mark)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = (struct bat_priv *)priv;
/* sequence number is slightly older. We already got a sequence number
* higher than this one, so we just mark it. */
@@ -187,21 +188,14 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
}
/* count the hamming weight, how many good packets did we receive? just count
- * the 1's. The inner loop uses the Kernighan algorithm, see
- * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
+ * the 1's.
*/
int bit_packet_count(TYPE_OF_WORD *seq_bits)
{
int i, hamming = 0;
- TYPE_OF_WORD word;
- for (i = 0; i < NUM_WORDS; i++) {
- word = seq_bits[i];
+ for (i = 0; i < NUM_WORDS; i++)
+ hamming += hweight_long(seq_bits[i]);
- while (word) {
- word &= word-1;
- hamming++;
- }
- }
return hamming;
}
diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h
index 01897d6962d0..77b1e61847e8 100644
--- a/drivers/staging/batman-adv/bitarray.h
+++ b/drivers/staging/batman-adv/bitarray.h
@@ -22,7 +22,8 @@
#ifndef _NET_BATMAN_ADV_BITARRAY_H_
#define _NET_BATMAN_ADV_BITARRAY_H_
-/* you should choose something big, if you don't want to waste cpu */
+/* you should choose something big, if you don't want to waste cpu
+ * and keep the type in sync with bit_packet_count */
#define TYPE_OF_WORD unsigned long
#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)
@@ -37,8 +38,8 @@ void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
/* receive and process one packet, returns 1 if received seq_num is considered
* new, 0 if old */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
- int8_t set_mark);
+char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits,
+ int32_t seq_num_diff, int8_t set_mark);
/* count the hamming weight, how many good packets did we receive? */
int bit_packet_count(TYPE_OF_WORD *seq_bits);
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index baa8b05b9e8d..a587da9c827e 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -30,7 +30,6 @@
#include "hash.h"
#include <linux/if_arp.h>
-#include <linux/netfilter_bridge.h>
#define MIN(x, y) ((x) < (y) ? (x) : (y))
@@ -78,13 +77,15 @@ static int is_valid_iface(struct net_device *net_dev)
return 1;
}
-static struct batman_if *get_active_batman_if(void)
+static struct batman_if *get_active_batman_if(struct net_device *soft_iface)
{
struct batman_if *batman_if;
- /* TODO: should check interfaces belonging to bat_priv */
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
if (batman_if->if_status == IF_ACTIVE)
goto out;
}
@@ -100,23 +101,29 @@ static void set_primary_if(struct bat_priv *bat_priv,
struct batman_if *batman_if)
{
struct batman_packet *batman_packet;
+ struct vis_packet *vis_packet;
bat_priv->primary_if = batman_if;
if (!bat_priv->primary_if)
return;
- set_main_if_addr(batman_if->net_dev->dev_addr);
-
batman_packet = (struct batman_packet *)(batman_if->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
batman_packet->ttl = TTL;
+ vis_packet = (struct vis_packet *)
+ bat_priv->my_vis_info->skb_packet->data;
+ memcpy(vis_packet->vis_orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(vis_packet->sender_orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+
/***
* hacky trick to make sure that we send the HNA information via
* our new primary interface
*/
- atomic_set(&hna_local_changed, 1);
+ atomic_set(&bat_priv->hna_local_changed, 1);
}
static bool hardif_is_iface_up(struct batman_if *batman_if)
@@ -129,9 +136,6 @@ static bool hardif_is_iface_up(struct batman_if *batman_if)
static void update_mac_addresses(struct batman_if *batman_if)
{
- if (!batman_if || !batman_if->packet_buff)
- return;
-
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -154,49 +158,60 @@ static void check_known_mac_addr(uint8_t *addr)
continue;
pr_warning("The newly added mac address (%pM) already exists "
- "on: %s\n", addr, batman_if->dev);
+ "on: %s\n", addr, batman_if->net_dev->name);
pr_warning("It is strongly recommended to keep mac addresses "
"unique to avoid problems!\n");
}
rcu_read_unlock();
}
-int hardif_min_mtu(void)
+int hardif_min_mtu(struct net_device *soft_iface)
{
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct batman_if *batman_if;
/* allow big frames if all devices are capable to do so
* (have MTU > 1500 + BAT_HEADER_LEN) */
int min_mtu = ETH_DATA_LEN;
+ if (atomic_read(&bat_priv->frag_enabled))
+ goto out;
+
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
- if ((batman_if->if_status == IF_ACTIVE) ||
- (batman_if->if_status == IF_TO_BE_ACTIVATED))
- min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
- min_mtu);
+ if ((batman_if->if_status != IF_ACTIVE) &&
+ (batman_if->if_status != IF_TO_BE_ACTIVATED))
+ continue;
+
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
+ min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
+ min_mtu);
}
rcu_read_unlock();
-
+out:
return min_mtu;
}
/* adjusts the MTU if a new interface with a smaller MTU appeared. */
-void update_min_mtu(void)
+void update_min_mtu(struct net_device *soft_iface)
{
int min_mtu;
- min_mtu = hardif_min_mtu();
- if (soft_device->mtu != min_mtu)
- soft_device->mtu = min_mtu;
+ min_mtu = hardif_min_mtu(soft_iface);
+ if (soft_iface->mtu != min_mtu)
+ soft_iface->mtu = min_mtu;
}
-static void hardif_activate_interface(struct net_device *net_dev,
- struct bat_priv *bat_priv,
- struct batman_if *batman_if)
+static void hardif_activate_interface(struct batman_if *batman_if)
{
+ struct bat_priv *bat_priv;
+
if (batman_if->if_status != IF_INACTIVE)
return;
+ bat_priv = netdev_priv(batman_if->soft_iface);
+
update_mac_addresses(batman_if);
batman_if->if_status = IF_TO_BE_ACTIVATED;
@@ -207,17 +222,14 @@ static void hardif_activate_interface(struct net_device *net_dev,
if (!bat_priv->primary_if)
set_primary_if(bat_priv, batman_if);
- bat_info(net_dev, "Interface activated: %s\n", batman_if->dev);
+ bat_info(batman_if->soft_iface, "Interface activated: %s\n",
+ batman_if->net_dev->name);
- if (atomic_read(&module_state) == MODULE_INACTIVE)
- activate_module();
-
- update_min_mtu();
+ update_min_mtu(batman_if->soft_iface);
return;
}
-static void hardif_deactivate_interface(struct net_device *net_dev,
- struct batman_if *batman_if)
+static void hardif_deactivate_interface(struct batman_if *batman_if)
{
if ((batman_if->if_status != IF_ACTIVE) &&
(batman_if->if_status != IF_TO_BE_ACTIVATED))
@@ -225,26 +237,39 @@ static void hardif_deactivate_interface(struct net_device *net_dev,
batman_if->if_status = IF_INACTIVE;
- bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
+ bat_info(batman_if->soft_iface, "Interface deactivated: %s\n",
+ batman_if->net_dev->name);
- update_min_mtu();
+ update_min_mtu(batman_if->soft_iface);
}
-int hardif_enable_interface(struct batman_if *batman_if)
+int hardif_enable_interface(struct batman_if *batman_if, char *iface_name)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv;
struct batman_packet *batman_packet;
if (batman_if->if_status != IF_NOT_IN_USE)
goto out;
+ batman_if->soft_iface = dev_get_by_name(&init_net, iface_name);
+
+ if (!batman_if->soft_iface) {
+ batman_if->soft_iface = softif_create(iface_name);
+
+ if (!batman_if->soft_iface)
+ goto err;
+
+ /* dev_get_by_name() increases the reference counter for us */
+ dev_hold(batman_if->soft_iface);
+ }
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
batman_if->packet_len = BAT_PACKET_LEN;
batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
if (!batman_if->packet_buff) {
- bat_err(soft_device, "Can't add interface packet (%s): "
- "out of memory\n", batman_if->dev);
+ bat_err(batman_if->soft_iface, "Can't add interface packet "
+ "(%s): out of memory\n", batman_if->net_dev->name);
goto err;
}
@@ -261,15 +286,43 @@ int hardif_enable_interface(struct batman_if *batman_if)
batman_if->if_status = IF_INACTIVE;
orig_hash_add_if(batman_if, bat_priv->num_ifaces);
+ batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN);
+ batman_if->batman_adv_ptype.func = batman_skb_recv;
+ batman_if->batman_adv_ptype.dev = batman_if->net_dev;
+ dev_add_pack(&batman_if->batman_adv_ptype);
+
atomic_set(&batman_if->seqno, 1);
- bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
+ atomic_set(&batman_if->frag_seqno, 1);
+ bat_info(batman_if->soft_iface, "Adding interface: %s\n",
+ batman_if->net_dev->name);
+
+ if (atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu <
+ ETH_DATA_LEN + BAT_HEADER_LEN)
+ bat_info(batman_if->soft_iface,
+ "The MTU of interface %s is too small (%i) to handle "
+ "the transport of batman-adv packets. Packets going "
+ "over this interface will be fragmented on layer2 "
+ "which could impact the performance. Setting the MTU "
+ "to %zi would solve the problem.\n",
+ batman_if->net_dev->name, batman_if->net_dev->mtu,
+ ETH_DATA_LEN + BAT_HEADER_LEN);
+
+ if (!atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu <
+ ETH_DATA_LEN + BAT_HEADER_LEN)
+ bat_info(batman_if->soft_iface,
+ "The MTU of interface %s is too small (%i) to handle "
+ "the transport of batman-adv packets. If you experience"
+ " problems getting traffic through try increasing the "
+ "MTU to %zi.\n",
+ batman_if->net_dev->name, batman_if->net_dev->mtu,
+ ETH_DATA_LEN + BAT_HEADER_LEN);
if (hardif_is_iface_up(batman_if))
- hardif_activate_interface(soft_device, bat_priv, batman_if);
+ hardif_activate_interface(batman_if);
else
- bat_err(soft_device, "Not using interface %s "
+ bat_err(batman_if->soft_iface, "Not using interface %s "
"(retrying later): interface not active\n",
- batman_if->dev);
+ batman_if->net_dev->name);
/* begin scheduling originator messages on that interface */
schedule_own_packet(batman_if);
@@ -283,29 +336,39 @@ err:
void hardif_disable_interface(struct batman_if *batman_if)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
if (batman_if->if_status == IF_ACTIVE)
- hardif_deactivate_interface(soft_device, batman_if);
+ hardif_deactivate_interface(batman_if);
if (batman_if->if_status != IF_INACTIVE)
return;
- bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
+ bat_info(batman_if->soft_iface, "Removing interface: %s\n",
+ batman_if->net_dev->name);
+ dev_remove_pack(&batman_if->batman_adv_ptype);
+
bat_priv->num_ifaces--;
orig_hash_del_if(batman_if, bat_priv->num_ifaces);
if (batman_if == bat_priv->primary_if)
- set_primary_if(bat_priv, get_active_batman_if());
+ set_primary_if(bat_priv,
+ get_active_batman_if(batman_if->soft_iface));
kfree(batman_if->packet_buff);
batman_if->packet_buff = NULL;
batman_if->if_status = IF_NOT_IN_USE;
- if ((atomic_read(&module_state) == MODULE_ACTIVE) &&
- (bat_priv->num_ifaces == 0))
- deactivate_module();
+ /* delete all references to this batman_if */
+ purge_orig_ref(bat_priv);
+ purge_outstanding_packets(bat_priv, batman_if);
+ dev_put(batman_if->soft_iface);
+
+ /* nobody uses this interface anymore */
+ if (!bat_priv->num_ifaces)
+ softif_destroy(batman_if->soft_iface);
+
+ batman_if->soft_iface = NULL;
}
static struct batman_if *hardif_add_interface(struct net_device *net_dev)
@@ -326,26 +389,20 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
goto release_dev;
}
- batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
- if (!batman_if->dev)
- goto free_if;
-
ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev);
if (ret)
- goto free_dev;
+ goto free_if;
batman_if->if_num = -1;
batman_if->net_dev = net_dev;
+ batman_if->soft_iface = NULL;
batman_if->if_status = IF_NOT_IN_USE;
- batman_if->packet_buff = NULL;
INIT_LIST_HEAD(&batman_if->list);
check_known_mac_addr(batman_if->net_dev->dev_addr);
list_add_tail_rcu(&batman_if->list, &if_list);
return batman_if;
-free_dev:
- kfree(batman_if->dev);
free_if:
kfree(batman_if);
release_dev:
@@ -358,11 +415,6 @@ static void hardif_free_interface(struct rcu_head *rcu)
{
struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
- /* delete all references to this batman_if */
- purge_orig(NULL);
- purge_outstanding_packets(batman_if);
-
- kfree(batman_if->dev);
kfree(batman_if);
}
@@ -386,8 +438,11 @@ void hardif_remove_interfaces(void)
{
struct batman_if *batman_if, *batman_if_tmp;
- list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list)
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
+ rtnl_lock();
hardif_remove_interface(batman_if);
+ rtnl_unlock();
+ }
}
static int hard_if_event(struct notifier_block *this,
@@ -395,8 +450,7 @@ static int hard_if_event(struct notifier_block *this,
{
struct net_device *net_dev = (struct net_device *)ptr;
struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv;
if (!batman_if && event == NETDEV_REGISTER)
batman_if = hardif_add_interface(net_dev);
@@ -406,20 +460,27 @@ static int hard_if_event(struct notifier_block *this,
switch (event) {
case NETDEV_UP:
- hardif_activate_interface(soft_device, bat_priv, batman_if);
+ hardif_activate_interface(batman_if);
break;
case NETDEV_GOING_DOWN:
case NETDEV_DOWN:
- hardif_deactivate_interface(soft_device, batman_if);
+ hardif_deactivate_interface(batman_if);
break;
case NETDEV_UNREGISTER:
hardif_remove_interface(batman_if);
break;
- case NETDEV_CHANGENAME:
+ case NETDEV_CHANGEMTU:
+ if (batman_if->soft_iface)
+ update_min_mtu(batman_if->soft_iface);
break;
case NETDEV_CHANGEADDR:
+ if (batman_if->if_status == IF_NOT_IN_USE)
+ goto out;
+
check_known_mac_addr(batman_if->net_dev->dev_addr);
update_mac_addresses(batman_if);
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
if (batman_if == bat_priv->primary_if)
set_primary_if(bat_priv, batman_if);
break;
@@ -431,40 +492,25 @@ out:
return NOTIFY_DONE;
}
-static int batman_skb_recv_finish(struct sk_buff *skb)
-{
- return NF_ACCEPT;
-}
-
/* receive a packet with the batman ethertype coming on a hard
* interface */
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv;
struct batman_packet *batman_packet;
struct batman_if *batman_if;
int ret;
+ batman_if = container_of(ptype, struct batman_if, batman_adv_ptype);
skb = skb_share_check(skb, GFP_ATOMIC);
/* skb was released by skb_share_check() */
if (!skb)
goto err_out;
- if (atomic_read(&module_state) != MODULE_ACTIVE)
- goto err_free;
-
- /* if netfilter/ebtables wants to block incoming batman
- * packets then give them a chance to do so here */
- ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
- batman_skb_recv_finish);
- if (ret != 1)
- goto err_out;
-
/* packet should hold at least type and version */
- if (unlikely(skb_headlen(skb) < 2))
+ if (unlikely(!pskb_may_pull(skb, 2)))
goto err_free;
/* expect a valid ethernet header here. */
@@ -472,8 +518,12 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|| !skb_mac_header(skb)))
goto err_free;
- batman_if = get_batman_if_by_netdev(skb->dev);
- if (!batman_if)
+ if (!batman_if->soft_iface)
+ goto err_free;
+
+ bat_priv = netdev_priv(batman_if->soft_iface);
+
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto err_free;
/* discard frames on not active interfaces */
@@ -500,7 +550,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
/* batman icmp packet */
case BAT_ICMP:
- ret = recv_icmp_packet(skb);
+ ret = recv_icmp_packet(skb, batman_if);
break;
/* unicast packet */
@@ -508,14 +558,19 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
ret = recv_unicast_packet(skb, batman_if);
break;
+ /* fragmented unicast packet */
+ case BAT_UNICAST_FRAG:
+ ret = recv_ucast_frag_packet(skb, batman_if);
+ break;
+
/* broadcast packet */
case BAT_BCAST:
- ret = recv_bcast_packet(skb);
+ ret = recv_bcast_packet(skb, batman_if);
break;
/* vis packet */
case BAT_VIS:
- ret = recv_vis_packet(skb);
+ ret = recv_vis_packet(skb, batman_if);
break;
default:
ret = NET_RX_DROP;
diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h
index d5640b045cb3..4b49527f57ad 100644
--- a/drivers/staging/batman-adv/hard-interface.h
+++ b/drivers/staging/batman-adv/hard-interface.h
@@ -32,14 +32,14 @@
extern struct notifier_block hard_if_notifier;
struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev);
-int hardif_enable_interface(struct batman_if *batman_if);
+int hardif_enable_interface(struct batman_if *batman_if, char *iface_name);
void hardif_disable_interface(struct batman_if *batman_if);
void hardif_remove_interfaces(void);
int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev);
-int hardif_min_mtu(void);
-void update_min_mtu(void);
+int hardif_min_mtu(struct net_device *soft_iface);
+void update_min_mtu(struct net_device *soft_iface);
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c
index 1286f8ff44f4..8ef26eb4949d 100644
--- a/drivers/staging/batman-adv/hash.c
+++ b/drivers/staging/batman-adv/hash.c
@@ -36,7 +36,7 @@ static void hash_init(struct hashtable_t *hash)
/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
* called to remove the elements inside of the hash. if you don't remove the
* elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb)
+void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg)
{
struct element_t *bucket, *last_bucket;
int i;
@@ -46,7 +46,7 @@ void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb)
while (bucket != NULL) {
if (free_cb != NULL)
- free_cb(bucket->data);
+ free_cb(bucket->data, arg);
last_bucket = bucket;
bucket = bucket->next;
@@ -300,7 +300,7 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, int size)
/* remove hash and eventual overflow buckets but not the content
* itself. */
- hash_delete(hash, NULL);
+ hash_delete(hash, NULL, NULL);
return new_hash;
}
diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h
index c483e1129fc0..2c8e1762389f 100644
--- a/drivers/staging/batman-adv/hash.h
+++ b/drivers/staging/batman-adv/hash.h
@@ -30,7 +30,7 @@
typedef int (*hashdata_compare_cb)(void *, void *);
typedef int (*hashdata_choose_cb)(void *, int);
-typedef void (*hashdata_free_cb)(void *);
+typedef void (*hashdata_free_cb)(void *, void *);
struct element_t {
void *data; /* pointer to the data */
@@ -70,7 +70,7 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t);
/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
* called to remove the elements inside of the hash. if you don't remove the
* elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb);
+void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg);
/* free only the hashtable and the hash itself. */
void hash_destroy(struct hashtable_t *hash);
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c
index 3ae7dd2d2d4d..db7160e76d9d 100644
--- a/drivers/staging/batman-adv/icmp_socket.c
+++ b/drivers/staging/batman-adv/icmp_socket.c
@@ -154,7 +154,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
{
struct socket_client *socket_client = file->private_data;
struct bat_priv *bat_priv = socket_client->bat_priv;
- struct icmp_packet_rr icmp_packet;
+ struct sk_buff *skb;
+ struct icmp_packet_rr *icmp_packet;
+
struct orig_node *orig_node;
struct batman_if *batman_if;
size_t packet_len = sizeof(struct icmp_packet);
@@ -174,40 +176,54 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
- if (!access_ok(VERIFY_READ, buff, packet_len))
- return -EFAULT;
+ skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
+ if (!skb)
+ return -ENOMEM;
- if (__copy_from_user(&icmp_packet, buff, packet_len))
- return -EFAULT;
+ skb_reserve(skb, sizeof(struct ethhdr));
+ icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
+
+ if (!access_ok(VERIFY_READ, buff, packet_len)) {
+ len = -EFAULT;
+ goto free_skb;
+ }
- if (icmp_packet.packet_type != BAT_ICMP) {
+ if (__copy_from_user(icmp_packet, buff, packet_len)) {
+ len = -EFAULT;
+ goto free_skb;
+ }
+
+ if (icmp_packet->packet_type != BAT_ICMP) {
bat_dbg(DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: "
"got bogus packet type (expected: BAT_ICMP)\n");
- return -EINVAL;
+ len = -EINVAL;
+ goto free_skb;
}
- if (icmp_packet.msg_type != ECHO_REQUEST) {
+ if (icmp_packet->msg_type != ECHO_REQUEST) {
bat_dbg(DBG_BATMAN, bat_priv,
"Error - can't send packet from char device: "
"got bogus message type (expected: ECHO_REQUEST)\n");
- return -EINVAL;
+ len = -EINVAL;
+ goto free_skb;
}
- icmp_packet.uid = socket_client->index;
+ icmp_packet->uid = socket_client->index;
- if (icmp_packet.version != COMPAT_VERSION) {
- icmp_packet.msg_type = PARAMETER_PROBLEM;
- icmp_packet.ttl = COMPAT_VERSION;
- bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
- goto out;
+ if (icmp_packet->version != COMPAT_VERSION) {
+ icmp_packet->msg_type = PARAMETER_PROBLEM;
+ icmp_packet->ttl = COMPAT_VERSION;
+ bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+ goto free_skb;
}
- if (atomic_read(&module_state) != MODULE_ACTIVE)
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto dst_unreach;
- spin_lock_irqsave(&orig_hash_lock, flags);
- orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ icmp_packet->dst));
if (!orig_node)
goto unlock;
@@ -218,7 +234,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
if (!batman_if)
goto dst_unreach;
@@ -226,22 +242,24 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if (batman_if->if_status != IF_ACTIVE)
goto dst_unreach;
- memcpy(icmp_packet.orig,
+ memcpy(icmp_packet->orig,
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
- memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN);
+
- send_raw_packet((unsigned char *)&icmp_packet,
- packet_len, batman_if, dstaddr);
+ send_skb_packet(skb, batman_if, dstaddr);
goto out;
unlock:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
dst_unreach:
- icmp_packet.msg_type = DESTINATION_UNREACHABLE;
- bat_socket_add_packet(socket_client, &icmp_packet, packet_len);
+ icmp_packet->msg_type = DESTINATION_UNREACHABLE;
+ bat_socket_add_packet(socket_client, icmp_packet, packet_len);
+free_skb:
+ kfree_skb(skb);
out:
return len;
}
@@ -265,6 +283,7 @@ static const struct file_operations fops = {
.read = bat_socket_read,
.write = bat_socket_write,
.poll = bat_socket_poll,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
int bat_socket_setup(struct bat_priv *bat_priv)
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index ef7c20ae7979..78ceebf75449 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -34,43 +34,14 @@
#include "hash.h"
struct list_head if_list;
-struct hlist_head forw_bat_list;
-struct hlist_head forw_bcast_list;
-struct hashtable_t *orig_hash;
-
-DEFINE_SPINLOCK(orig_hash_lock);
-DEFINE_SPINLOCK(forw_bat_list_lock);
-DEFINE_SPINLOCK(forw_bcast_list_lock);
-
-atomic_t bcast_queue_left;
-atomic_t batman_queue_left;
-
-int16_t num_hna;
-
-struct net_device *soft_device;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-atomic_t module_state;
-
-static struct packet_type batman_adv_packet_type __read_mostly = {
- .type = __constant_htons(ETH_P_BATMAN),
- .func = batman_skb_recv,
-};
struct workqueue_struct *bat_event_workqueue;
static int __init batman_init(void)
{
- int retval;
-
INIT_LIST_HEAD(&if_list);
- INIT_HLIST_HEAD(&forw_bat_list);
- INIT_HLIST_HEAD(&forw_bcast_list);
-
- atomic_set(&module_state, MODULE_INACTIVE);
-
- atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
- atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/ */
@@ -82,126 +53,86 @@ static int __init batman_init(void)
bat_socket_init();
debugfs_init();
- /* initialize layer 2 interface */
- soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
- interface_setup);
-
- if (!soft_device) {
- pr_err("Unable to allocate the batman interface\n");
- goto end;
- }
-
- retval = register_netdev(soft_device);
-
- if (retval < 0) {
- pr_err("Unable to register the batman interface: %i\n", retval);
- goto free_soft_device;
- }
-
- retval = sysfs_add_meshif(soft_device);
-
- if (retval < 0)
- goto unreg_soft_device;
-
- retval = debugfs_add_meshif(soft_device);
-
- if (retval < 0)
- goto unreg_sysfs;
-
register_netdevice_notifier(&hard_if_notifier);
- dev_add_pack(&batman_adv_packet_type);
pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
"loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
COMPAT_VERSION);
return 0;
-
-unreg_sysfs:
- sysfs_del_meshif(soft_device);
-unreg_soft_device:
- unregister_netdev(soft_device);
- soft_device = NULL;
- return -ENOMEM;
-
-free_soft_device:
- free_netdev(soft_device);
- soft_device = NULL;
-end:
- return -ENOMEM;
}
static void __exit batman_exit(void)
{
- deactivate_module();
-
debugfs_destroy();
unregister_netdevice_notifier(&hard_if_notifier);
hardif_remove_interfaces();
- if (soft_device) {
- debugfs_del_meshif(soft_device);
- sysfs_del_meshif(soft_device);
- unregister_netdev(soft_device);
- soft_device = NULL;
- }
-
- dev_remove_pack(&batman_adv_packet_type);
-
+ flush_workqueue(bat_event_workqueue);
destroy_workqueue(bat_event_workqueue);
bat_event_workqueue = NULL;
+
+ synchronize_net();
}
-/* activates the module, starts timer ... */
-void activate_module(void)
+int mesh_init(struct net_device *soft_iface)
{
- if (originator_init() < 1)
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+
+ spin_lock_init(&bat_priv->orig_hash_lock);
+ spin_lock_init(&bat_priv->forw_bat_list_lock);
+ spin_lock_init(&bat_priv->forw_bcast_list_lock);
+ spin_lock_init(&bat_priv->hna_lhash_lock);
+ spin_lock_init(&bat_priv->hna_ghash_lock);
+ spin_lock_init(&bat_priv->vis_hash_lock);
+ spin_lock_init(&bat_priv->vis_list_lock);
+
+ INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
+ INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
+
+ if (originator_init(bat_priv) < 1)
goto err;
- if (hna_local_init() < 1)
+ if (hna_local_init(bat_priv) < 1)
goto err;
- if (hna_global_init() < 1)
+ if (hna_global_init(bat_priv) < 1)
goto err;
- hna_local_add(soft_device->dev_addr);
+ hna_local_add(soft_iface, soft_iface->dev_addr);
- if (vis_init() < 1)
+ if (vis_init(bat_priv) < 1)
goto err;
- update_min_mtu();
- atomic_set(&module_state, MODULE_ACTIVE);
+ atomic_set(&bat_priv->mesh_state, MESH_ACTIVE);
goto end;
err:
pr_err("Unable to allocate memory for mesh information structures: "
"out of mem ?\n");
- deactivate_module();
+ mesh_free(soft_iface);
+ return -1;
+
end:
- return;
+ return 0;
}
-/* shuts down the whole module.*/
-void deactivate_module(void)
+void mesh_free(struct net_device *soft_iface)
{
- atomic_set(&module_state, MODULE_DEACTIVATING);
-
- purge_outstanding_packets(NULL);
- flush_workqueue(bat_event_workqueue);
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
- vis_quit();
+ atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING);
- /* TODO: unregister BATMAN pack */
+ purge_outstanding_packets(bat_priv, NULL);
- originator_free();
+ vis_quit(bat_priv);
- hna_local_free();
- hna_global_free();
+ originator_free(bat_priv);
- synchronize_net();
+ hna_local_free(bat_priv);
+ hna_global_free(bat_priv);
- synchronize_rcu();
- atomic_set(&module_state, MODULE_INACTIVE);
+ atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
}
void inc_module_count(void)
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h
index 8513261b8a77..ca97589f6826 100644
--- a/drivers/staging/batman-adv/main.h
+++ b/drivers/staging/batman-adv/main.h
@@ -30,7 +30,7 @@
#define DRIVER_DESC "B.A.T.M.A.N. advanced"
#define DRIVER_DEVICE "batman-adv"
-#define SOURCE_VERSION "maint"
+#define SOURCE_VERSION "next"
/* B.A.T.M.A.N. parameters */
@@ -76,9 +76,9 @@
#define EXPECTED_SEQNO_RANGE 65536
/* don't reset again within 30 seconds */
-#define MODULE_INACTIVE 0
-#define MODULE_ACTIVE 1
-#define MODULE_DEACTIVATING 2
+#define MESH_INACTIVE 0
+#define MESH_ACTIVE 1
+#define MESH_DEACTIVATING 2
#define BCAST_QUEUE_LEN 256
#define BATMAN_QUEUE_LEN 256
@@ -128,26 +128,12 @@
#endif
extern struct list_head if_list;
-extern struct hlist_head forw_bat_list;
-extern struct hlist_head forw_bcast_list;
-extern struct hashtable_t *orig_hash;
-
-extern spinlock_t orig_hash_lock;
-extern spinlock_t forw_bat_list_lock;
-extern spinlock_t forw_bcast_list_lock;
-
-extern atomic_t bcast_queue_left;
-extern atomic_t batman_queue_left;
-extern int16_t num_hna;
-
-extern struct net_device *soft_device;
extern unsigned char broadcast_addr[];
-extern atomic_t module_state;
extern struct workqueue_struct *bat_event_workqueue;
-void activate_module(void);
-void deactivate_module(void);
+int mesh_init(struct net_device *soft_iface);
+void mesh_free(struct net_device *soft_iface);
void inc_module_count(void);
void dec_module_count(void);
int addr_to_string(char *buff, uint8_t *addr);
@@ -158,7 +144,7 @@ int is_bcast(uint8_t *addr);
int is_mcast(uint8_t *addr);
#ifdef CONFIG_BATMAN_ADV_DEBUG
-extern int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
+int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
#define bat_dbg(type, bat_priv, fmt, arg...) \
do { \
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
index de5a8c1a8104..f25d7fdfe811 100644
--- a/drivers/staging/batman-adv/originator.c
+++ b/drivers/staging/batman-adv/originator.c
@@ -27,32 +27,34 @@
#include "translation-table.h"
#include "routing.h"
#include "hard-interface.h"
+#include "unicast.h"
-static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
+static void purge_orig(struct work_struct *work);
-static void start_purge_timer(void)
+static void start_purge_timer(struct bat_priv *bat_priv)
{
- queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
+ INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ);
}
-int originator_init(void)
+int originator_init(struct bat_priv *bat_priv)
{
unsigned long flags;
- if (orig_hash)
+ if (bat_priv->orig_hash)
return 1;
- spin_lock_irqsave(&orig_hash_lock, flags);
- orig_hash = hash_new(128, compare_orig, choose_orig);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ bat_priv->orig_hash = hash_new(128, compare_orig, choose_orig);
- if (!orig_hash)
+ if (!bat_priv->orig_hash)
goto err;
- spin_unlock_irqrestore(&orig_hash_lock, flags);
- start_purge_timer();
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
+ start_purge_timer(bat_priv);
return 1;
err:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return 0;
}
@@ -60,8 +62,7 @@ struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct neigh_node *neigh_node;
bat_dbg(DBG_BATMAN, bat_priv,
@@ -81,11 +82,12 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
return neigh_node;
}
-static void free_orig_node(void *data)
+static void free_orig_node(void *data, void *arg)
{
struct list_head *list_pos, *list_pos_tmp;
struct neigh_node *neigh_node;
struct orig_node *orig_node = (struct orig_node *)data;
+ struct bat_priv *bat_priv = (struct bat_priv *)arg;
/* for all neighbors towards this originator ... */
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
@@ -95,41 +97,40 @@ static void free_orig_node(void *data)
kfree(neigh_node);
}
- hna_global_del_orig(orig_node, "originator timed out");
+ frag_list_free(&orig_node->frag_list);
+ hna_global_del_orig(bat_priv, orig_node, "originator timed out");
kfree(orig_node->bcast_own);
kfree(orig_node->bcast_own_sum);
kfree(orig_node);
}
-void originator_free(void)
+void originator_free(struct bat_priv *bat_priv)
{
unsigned long flags;
- if (!orig_hash)
+ if (!bat_priv->orig_hash)
return;
- cancel_delayed_work_sync(&purge_orig_wq);
+ cancel_delayed_work_sync(&bat_priv->orig_work);
- spin_lock_irqsave(&orig_hash_lock, flags);
- hash_delete(orig_hash, free_orig_node);
- orig_hash = NULL;
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv);
+ bat_priv->orig_hash = NULL;
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
}
/* this function finds or creates an originator entry for the given
* address if it does not exits */
-struct orig_node *get_orig_node(uint8_t *addr)
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct hashtable_t *swaphash;
int size;
- orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, addr));
- if (orig_node != NULL)
+ if (orig_node)
return orig_node;
bat_dbg(DBG_BATMAN, bat_priv,
@@ -157,20 +158,25 @@ struct orig_node *get_orig_node(uint8_t *addr)
size = bat_priv->num_ifaces * sizeof(uint8_t);
orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
+
+ INIT_LIST_HEAD(&orig_node->frag_list);
+ orig_node->last_frag_packet = 0;
+
if (!orig_node->bcast_own_sum)
goto free_bcast_own;
- if (hash_add(orig_hash, orig_node) < 0)
+ if (hash_add(bat_priv->orig_hash, orig_node) < 0)
goto free_bcast_own_sum;
- if (orig_hash->elements * 4 > orig_hash->size) {
- swaphash = hash_resize(orig_hash, orig_hash->size * 2);
+ if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) {
+ swaphash = hash_resize(bat_priv->orig_hash,
+ bat_priv->orig_hash->size * 2);
- if (swaphash == NULL)
- bat_err(soft_device,
+ if (!swaphash)
+ bat_dbg(DBG_BATMAN, bat_priv,
"Couldn't resize orig hash table\n");
else
- orig_hash = swaphash;
+ bat_priv->orig_hash = swaphash;
}
return orig_node;
@@ -183,11 +189,10 @@ free_orig_node:
return NULL;
}
-static bool purge_orig_neighbors(struct orig_node *orig_node,
+static bool purge_orig_neighbors(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
struct neigh_node **best_neigh_node)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct list_head *list_pos, *list_pos_tmp;
struct neigh_node *neigh_node;
bool neigh_purged = false;
@@ -200,8 +205,8 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
if ((time_after(jiffies,
neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
- (neigh_node->if_incoming->if_status ==
- IF_TO_BE_REMOVED)) {
+ (neigh_node->if_incoming->if_status == IF_INACTIVE) ||
+ (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
if (neigh_node->if_incoming->if_status ==
IF_TO_BE_REMOVED)
@@ -209,7 +214,7 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
"neighbor purge: originator %pM, "
"neighbor: %pM, iface: %s\n",
orig_node->orig, neigh_node->addr,
- neigh_node->if_incoming->dev);
+ neigh_node->if_incoming->net_dev->name);
else
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor timeout: originator %pM, "
@@ -229,10 +234,9 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
return neigh_purged;
}
-static bool purge_orig_node(struct orig_node *orig_node)
+static bool purge_orig_node(struct bat_priv *bat_priv,
+ struct orig_node *orig_node)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct neigh_node *best_neigh_node;
if (time_after(jiffies,
@@ -243,8 +247,10 @@ static bool purge_orig_node(struct orig_node *orig_node)
orig_node->orig, (orig_node->last_valid / HZ));
return true;
} else {
- if (purge_orig_neighbors(orig_node, &best_neigh_node)) {
- update_routes(orig_node, best_neigh_node,
+ if (purge_orig_neighbors(bat_priv, orig_node,
+ &best_neigh_node)) {
+ update_routes(bat_priv, orig_node,
+ best_neigh_node,
orig_node->hna_buff,
orig_node->hna_buff_len);
/* update bonding candidates, we could have lost
@@ -256,29 +262,46 @@ static bool purge_orig_node(struct orig_node *orig_node)
return false;
}
-void purge_orig(struct work_struct *work)
+static void _purge_orig(struct bat_priv *bat_priv)
{
HASHIT(hashit);
struct orig_node *orig_node;
unsigned long flags;
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
/* for all origins... */
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
- if (purge_orig_node(orig_node)) {
- hash_remove_bucket(orig_hash, &hashit);
- free_orig_node(orig_node);
+
+ if (purge_orig_node(bat_priv, orig_node)) {
+ hash_remove_bucket(bat_priv->orig_hash, &hashit);
+ free_orig_node(orig_node, bat_priv);
}
+
+ if (time_after(jiffies, (orig_node->last_frag_packet +
+ msecs_to_jiffies(FRAG_TIMEOUT))))
+ frag_list_free(&orig_node->frag_list);
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
- /* if work == NULL we were not called by the timer
- * and thus do not need to re-arm the timer */
- if (work)
- start_purge_timer();
+}
+
+static void purge_orig(struct work_struct *work)
+{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, orig_work);
+
+ _purge_orig(bat_priv);
+ start_purge_timer(bat_priv);
+}
+
+void purge_orig_ref(struct bat_priv *bat_priv)
+{
+ _purge_orig(bat_priv);
}
int orig_seq_print_text(struct seq_file *seq, void *offset)
@@ -309,16 +332,16 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
rcu_read_lock();
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
- net_dev->name);
+ bat_priv->primary_if->net_dev->name,
+ bat_priv->primary_if->addr_str, net_dev->name);
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", "Potential nexthops");
rcu_read_unlock();
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -338,7 +361,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%-17s %4i.%03is (%3i) %17s [%10s]:",
orig_str, last_seen_secs, last_seen_msecs,
orig_node->router->tq_avg, router_str,
- orig_node->router->if_incoming->dev);
+ orig_node->router->if_incoming->net_dev->name);
list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
addr_to_string(orig_str, neigh_node->addr);
@@ -350,7 +373,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
batman_count++;
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
if ((batman_count == 0))
seq_printf(seq, "No batman nodes in range ...\n");
@@ -390,26 +413,27 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
struct orig_node *orig_node;
unsigned long flags;
HASHIT(hashit);
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
if (orig_node_add_if(orig_node, max_if_num) == -1)
goto err;
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return 0;
err:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return -ENOMEM;
}
@@ -467,6 +491,7 @@ free_own_sum:
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
struct batman_if *batman_if_tmp;
struct orig_node *orig_node;
unsigned long flags;
@@ -475,9 +500,9 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
ret = orig_node_del_if(orig_node, max_if_num,
@@ -496,16 +521,19 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
if (batman_if == batman_if_tmp)
continue;
+ if (batman_if->soft_iface != batman_if_tmp->soft_iface)
+ continue;
+
if (batman_if_tmp->if_num > batman_if->if_num)
batman_if_tmp->if_num--;
}
rcu_read_unlock();
batman_if->if_num = -1;
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return 0;
err:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return -ENOMEM;
}
diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h
index e88411d9db71..a97c4004776a 100644
--- a/drivers/staging/batman-adv/originator.h
+++ b/drivers/staging/batman-adv/originator.h
@@ -22,10 +22,10 @@
#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
#define _NET_BATMAN_ADV_ORIGINATOR_H_
-int originator_init(void);
-void originator_free(void);
-void purge_orig(struct work_struct *work);
-struct orig_node *get_orig_node(uint8_t *addr);
+int originator_init(struct bat_priv *bat_priv);
+void originator_free(struct bat_priv *bat_priv);
+void purge_orig_ref(struct bat_priv *bat_priv);
+struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr);
struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming);
diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h
index abb5e460f23e..44de1bfb0b0c 100644
--- a/drivers/staging/batman-adv/packet.h
+++ b/drivers/staging/batman-adv/packet.h
@@ -24,14 +24,15 @@
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
-#define BAT_PACKET 0x01
-#define BAT_ICMP 0x02
-#define BAT_UNICAST 0x03
-#define BAT_BCAST 0x04
-#define BAT_VIS 0x05
+#define BAT_PACKET 0x01
+#define BAT_ICMP 0x02
+#define BAT_UNICAST 0x03
+#define BAT_BCAST 0x04
+#define BAT_VIS 0x05
+#define BAT_UNICAST_FRAG 0x06
/* this file is included by batctl which needs these defines */
-#define COMPAT_VERSION 11
+#define COMPAT_VERSION 13
#define DIRECTLINK 0x40
#define VIS_SERVER 0x20
#define PRIMARIES_FIRST_HOP 0x10
@@ -47,6 +48,9 @@
#define VIS_TYPE_SERVER_SYNC 0
#define VIS_TYPE_CLIENT_UPDATE 1
+/* fragmentation defines */
+#define UNI_FRAG_HEAD 0x01
+
struct batman_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
@@ -96,6 +100,16 @@ struct unicast_packet {
uint8_t ttl;
} __attribute__((packed));
+struct unicast_frag_packet {
+ uint8_t packet_type;
+ uint8_t version; /* batman version field */
+ uint8_t dest[6];
+ uint8_t ttl;
+ uint8_t flags;
+ uint8_t orig[6];
+ uint16_t seqno;
+} __attribute__((packed));
+
struct bcast_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index 032195e6de94..2cf8cf98a299 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -32,31 +32,31 @@
#include "ring_buffer.h"
#include "vis.h"
#include "aggregation.h"
-
-static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
+#include "unicast.h"
void slide_own_bcast_window(struct batman_if *batman_if)
{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
HASHIT(hashit);
struct orig_node *orig_node;
TYPE_OF_WORD *word;
unsigned long flags;
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
- bit_get_packet(word, 1, 0);
+ bit_get_packet(bat_priv, word, 1, 0);
orig_node->bcast_own_sum[batman_if->if_num] =
bit_packet_count(word);
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
}
-static void update_HNA(struct orig_node *orig_node,
+static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
unsigned char *hna_buff, int hna_buff_len)
{
if ((hna_buff_len != orig_node->hna_buff_len) ||
@@ -65,27 +65,27 @@ static void update_HNA(struct orig_node *orig_node,
(memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
if (orig_node->hna_buff_len > 0)
- hna_global_del_orig(orig_node,
+ hna_global_del_orig(bat_priv, orig_node,
"originator changed hna");
if ((hna_buff_len > 0) && (hna_buff != NULL))
- hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
+ hna_global_add_orig(bat_priv, orig_node,
+ hna_buff, hna_buff_len);
}
}
-static void update_route(struct orig_node *orig_node,
+static void update_route(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
struct neigh_node *neigh_node,
unsigned char *hna_buff, int hna_buff_len)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
-
/* route deleted */
if ((orig_node->router != NULL) && (neigh_node == NULL)) {
bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
orig_node->orig);
- hna_global_del_orig(orig_node, "originator timed out");
+ hna_global_del_orig(bat_priv, orig_node,
+ "originator timed out");
/* route added */
} else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
@@ -93,7 +93,8 @@ static void update_route(struct orig_node *orig_node,
bat_dbg(DBG_ROUTES, bat_priv,
"Adding route towards: %pM (via %pM)\n",
orig_node->orig, neigh_node->addr);
- hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
+ hna_global_add_orig(bat_priv, orig_node,
+ hna_buff, hna_buff_len);
/* route changed */
} else {
@@ -108,19 +109,20 @@ static void update_route(struct orig_node *orig_node,
}
-void update_routes(struct orig_node *orig_node,
- struct neigh_node *neigh_node,
- unsigned char *hna_buff, int hna_buff_len)
+void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ struct neigh_node *neigh_node, unsigned char *hna_buff,
+ int hna_buff_len)
{
if (orig_node == NULL)
return;
if (orig_node->router != neigh_node)
- update_route(orig_node, neigh_node, hna_buff, hna_buff_len);
+ update_route(bat_priv, orig_node, neigh_node,
+ hna_buff, hna_buff_len);
/* may be just HNA changed */
else
- update_HNA(orig_node, hna_buff, hna_buff_len);
+ update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len);
}
static int is_bidirectional_neigh(struct orig_node *orig_node,
@@ -128,8 +130,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
struct batman_packet *batman_packet,
struct batman_if *if_incoming)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
unsigned char total_count;
@@ -233,14 +234,14 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
return 0;
}
-static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
+static void update_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
struct batman_if *if_incoming,
unsigned char *hna_buff, int hna_buff_len,
char is_duplicate)
{
- /* FIXME: get bat_priv */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
int tmp_hna_buff_len;
@@ -266,12 +267,11 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
if (!neigh_node) {
struct orig_node *orig_tmp;
- orig_tmp = get_orig_node(ethhdr->h_source);
+ orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
if (!orig_tmp)
return;
- neigh_node = create_neighbor(orig_node,
- orig_tmp,
+ neigh_node = create_neighbor(orig_node, orig_tmp,
ethhdr->h_source, if_incoming);
if (!neigh_node)
return;
@@ -313,11 +313,13 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
>= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
goto update_hna;
- update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
+ update_routes(bat_priv, orig_node, neigh_node,
+ hna_buff, tmp_hna_buff_len);
return;
update_hna:
- update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
+ update_routes(bat_priv, orig_node, orig_node->router,
+ hna_buff, tmp_hna_buff_len);
}
/* checks whether the host restarted and is in the protection time.
@@ -325,12 +327,10 @@ update_hna:
* 0 if the packet is to be accepted
* 1 if the packet is to be ignored.
*/
-static int window_protected(int32_t seq_num_diff,
- unsigned long *last_reset)
+static int window_protected(struct bat_priv *bat_priv,
+ int32_t seq_num_diff,
+ unsigned long *last_reset)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
-
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
if (time_after(jiffies, *last_reset +
@@ -359,8 +359,7 @@ static char count_real_packets(struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
struct batman_if *if_incoming)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct orig_node *orig_node;
struct neigh_node *tmp_neigh_node;
char is_duplicate = 0;
@@ -368,14 +367,15 @@ static char count_real_packets(struct ethhdr *ethhdr,
int need_update = 0;
int set_mark;
- orig_node = get_orig_node(batman_packet->orig);
+ orig_node = get_orig_node(bat_priv, batman_packet->orig);
if (orig_node == NULL)
return 0;
seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
/* signalize caller that the packet is to be dropped. */
- if (window_protected(seq_diff, &orig_node->batman_seqno_reset))
+ if (window_protected(bat_priv, seq_diff,
+ &orig_node->batman_seqno_reset))
return -1;
list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
@@ -391,8 +391,9 @@ static char count_real_packets(struct ethhdr *ethhdr,
set_mark = 0;
/* if the window moved, set the update flag. */
- need_update |= bit_get_packet(tmp_neigh_node->real_bits,
- seq_diff, set_mark);
+ need_update |= bit_get_packet(bat_priv,
+ tmp_neigh_node->real_bits,
+ seq_diff, set_mark);
tmp_neigh_node->real_packet_count =
bit_packet_count(tmp_neigh_node->real_bits);
@@ -520,8 +521,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
unsigned char *hna_buff, int hna_buff_len,
struct batman_if *if_incoming)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct batman_if *batman_if;
struct orig_node *orig_neigh_node, *orig_node;
char has_directlink_flag;
@@ -557,15 +557,19 @@ void receive_bat_packet(struct ethhdr *ethhdr,
"Received BATMAN packet via NB: %pM, IF: %s [%s] "
"(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, "
"TTL %d, V %d, IDF %d)\n",
- ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
- batman_packet->orig, batman_packet->prev_sender,
- batman_packet->seqno, batman_packet->tq, batman_packet->ttl,
- batman_packet->version, has_directlink_flag);
+ ethhdr->h_source, if_incoming->net_dev->name,
+ if_incoming->addr_str, batman_packet->orig,
+ batman_packet->prev_sender, batman_packet->seqno,
+ batman_packet->tq, batman_packet->ttl, batman_packet->version,
+ has_directlink_flag);
list_for_each_entry_rcu(batman_if, &if_list, list) {
if (batman_if->if_status != IF_ACTIVE)
continue;
+ if (batman_if->soft_iface != if_incoming->soft_iface)
+ continue;
+
if (compare_orig(ethhdr->h_source,
batman_if->net_dev->dev_addr))
is_my_addr = 1;
@@ -608,7 +612,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
TYPE_OF_WORD *word;
int offset;
- orig_neigh_node = get_orig_node(ethhdr->h_source);
+ orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
if (!orig_neigh_node)
return;
@@ -640,7 +644,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
return;
}
- orig_node = get_orig_node(batman_packet->orig);
+ orig_node = get_orig_node(bat_priv, batman_packet->orig);
if (orig_node == NULL)
return;
@@ -676,7 +680,8 @@ void receive_bat_packet(struct ethhdr *ethhdr,
/* if sender is a direct neighbor the sender mac equals
* originator mac */
orig_neigh_node = (is_single_hop_neigh ?
- orig_node : get_orig_node(ethhdr->h_source));
+ orig_node :
+ get_orig_node(bat_priv, ethhdr->h_source));
if (orig_neigh_node == NULL)
return;
@@ -698,7 +703,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
(!is_duplicate ||
((orig_node->last_real_seqno == batman_packet->seqno) &&
(orig_node->last_ttl - 3 <= batman_packet->ttl))))
- update_orig(orig_node, ethhdr, batman_packet,
+ update_orig(bat_priv, orig_node, ethhdr, batman_packet,
if_incoming, hna_buff, hna_buff_len, is_duplicate);
mark_bonding_address(bat_priv, orig_node,
@@ -736,15 +741,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
0, hna_buff_len, if_incoming);
}
-int recv_bat_packet(struct sk_buff *skb,
- struct batman_if *batman_if)
+int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
{
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
struct ethhdr *ethhdr;
unsigned long flags;
- struct sk_buff *skb_old;
/* drop packet if it has not necessary minimum size */
- if (skb_headlen(skb) < sizeof(struct batman_packet))
+ if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet))))
return NET_RX_DROP;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
@@ -757,38 +761,33 @@ int recv_bat_packet(struct sk_buff *skb,
if (is_bcast(ethhdr->h_source))
return NET_RX_DROP;
- /* TODO: we use headlen instead of "length", because
- * only this data is paged in. */
-
/* create a copy of the skb, if needed, to modify it. */
- if (!skb_clone_writable(skb, skb_headlen(skb))) {
- skb_old = skb;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return NET_RX_DROP;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
- kfree_skb(skb_old);
- }
+ if (skb_cow(skb, 0) < 0)
+ return NET_RX_DROP;
+
+ /* keep skb linear */
+ if (skb_linearize(skb) < 0)
+ return NET_RX_DROP;
+
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
receive_aggr_bat_packet(ethhdr,
skb->data,
skb_headlen(skb),
batman_if);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
kfree_skb(skb);
return NET_RX_SUCCESS;
}
-static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
+static int recv_my_icmp_packet(struct bat_priv *bat_priv,
+ struct sk_buff *skb, size_t icmp_len)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
- struct sk_buff *skb_old;
struct batman_if *batman_if;
int ret;
unsigned long flags;
@@ -808,8 +807,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
/* answer echo request (ping) */
/* get routing information */
- spin_lock_irqsave(&orig_hash_lock, flags);
- orig_node = ((struct orig_node *)hash_find(orig_hash,
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
icmp_packet->orig));
ret = NET_RX_DROP;
@@ -820,19 +819,14 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
* copy the required data before sending */
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
/* create a copy of the skb, if needed, to modify it. */
- skb_old = NULL;
- if (!skb_clone_writable(skb, icmp_len)) {
- skb_old = skb;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return NET_RX_DROP;
- icmp_packet = (struct icmp_packet_rr *)skb->data;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
- kfree_skb(skb_old);
- }
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig,
@@ -844,19 +838,17 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
ret = NET_RX_SUCCESS;
} else
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return ret;
}
-static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
+static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
+ struct sk_buff *skb, size_t icmp_len)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet *icmp_packet;
struct ethhdr *ethhdr;
- struct sk_buff *skb_old;
struct batman_if *batman_if;
int ret;
unsigned long flags;
@@ -867,9 +859,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
/* send TTL exceeded if packet is an echo request (traceroute) */
if (icmp_packet->msg_type != ECHO_REQUEST) {
- pr_warning("Warning - can't forward icmp packet from %pM to "
- "%pM: ttl exceeded\n", icmp_packet->orig,
- icmp_packet->dst);
+ pr_debug("Warning - can't forward icmp packet from %pM to "
+ "%pM: ttl exceeded\n", icmp_packet->orig,
+ icmp_packet->dst);
return NET_RX_DROP;
}
@@ -877,9 +869,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
return NET_RX_DROP;
/* get routing information */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
orig_node = ((struct orig_node *)
- hash_find(orig_hash, icmp_packet->orig));
+ hash_find(bat_priv->orig_hash, icmp_packet->orig));
ret = NET_RX_DROP;
if ((orig_node != NULL) &&
@@ -889,18 +881,14 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
* copy the required data before sending */
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
/* create a copy of the skb, if needed, to modify it. */
- if (!skb_clone_writable(skb, icmp_len)) {
- skb_old = skb;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return NET_RX_DROP;
- icmp_packet = (struct icmp_packet *) skb->data;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
- kfree_skb(skb_old);
- }
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet *) skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
memcpy(icmp_packet->orig,
@@ -912,18 +900,18 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
ret = NET_RX_SUCCESS;
} else
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return ret;
}
-int recv_icmp_packet(struct sk_buff *skb)
+int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
struct orig_node *orig_node;
- struct sk_buff *skb_old;
struct batman_if *batman_if;
int hdr_size = sizeof(struct icmp_packet);
int ret;
@@ -933,11 +921,11 @@ int recv_icmp_packet(struct sk_buff *skb)
/**
* we truncate all incoming icmp packets if they don't match our size
*/
- if (skb_headlen(skb) >= sizeof(struct icmp_packet_rr))
+ if (skb->len >= sizeof(struct icmp_packet_rr))
hdr_size = sizeof(struct icmp_packet_rr);
/* drop packet if it has not necessary minimum size */
- if (skb_headlen(skb) < hdr_size)
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
return NET_RX_DROP;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
@@ -966,18 +954,18 @@ int recv_icmp_packet(struct sk_buff *skb)
/* packet for me */
if (is_my_mac(icmp_packet->dst))
- return recv_my_icmp_packet(skb, hdr_size);
+ return recv_my_icmp_packet(bat_priv, skb, hdr_size);
/* TTL exceeded */
if (icmp_packet->ttl < 2)
- return recv_icmp_ttl_exceeded(skb, hdr_size);
+ return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size);
ret = NET_RX_DROP;
/* get routing information */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
orig_node = ((struct orig_node *)
- hash_find(orig_hash, icmp_packet->dst));
+ hash_find(bat_priv->orig_hash, icmp_packet->dst));
if ((orig_node != NULL) &&
(orig_node->router != NULL)) {
@@ -986,18 +974,14 @@ int recv_icmp_packet(struct sk_buff *skb)
* copy the required data before sending */
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
/* create a copy of the skb, if needed, to modify it. */
- if (!skb_clone_writable(skb, hdr_size)) {
- skb_old = skb;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return NET_RX_DROP;
- icmp_packet = (struct icmp_packet_rr *)skb->data;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
- kfree_skb(skb_old);
- }
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* decrement ttl */
icmp_packet->ttl--;
@@ -1007,7 +991,7 @@ int recv_icmp_packet(struct sk_buff *skb)
ret = NET_RX_SUCCESS;
} else
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return ret;
}
@@ -1015,10 +999,9 @@ int recv_icmp_packet(struct sk_buff *skb)
/* find a suitable router for this originator, and use
* bonding if possible. */
struct neigh_node *find_router(struct orig_node *orig_node,
- struct batman_if *recv_if)
+ struct batman_if *recv_if)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv;
struct orig_node *primary_orig_node;
struct orig_node *router_orig;
struct neigh_node *router, *first_candidate, *best_router;
@@ -1034,9 +1017,14 @@ struct neigh_node *find_router(struct orig_node *orig_node,
/* without bonding, the first node should
* always choose the default router. */
+ if (!recv_if)
+ return orig_node->router;
+
+ bat_priv = netdev_priv(recv_if->soft_iface);
bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
- if (!bonding_enabled && (recv_if == NULL))
- return orig_node->router;
+
+ if (!bonding_enabled)
+ return orig_node->router;
router_orig = orig_node->router->orig_node;
@@ -1052,8 +1040,9 @@ struct neigh_node *find_router(struct orig_node *orig_node,
router_orig->orig, ETH_ALEN) == 0) {
primary_orig_node = router_orig;
} else {
- primary_orig_node = hash_find(orig_hash,
+ primary_orig_node = hash_find(bat_priv->orig_hash,
router_orig->primary_addr);
+
if (!primary_orig_node)
return orig_node->router;
}
@@ -1105,61 +1094,68 @@ struct neigh_node *find_router(struct orig_node *orig_node,
return router;
}
-int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
+static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
{
- struct unicast_packet *unicast_packet;
- struct orig_node *orig_node;
- struct neigh_node *router;
struct ethhdr *ethhdr;
- struct batman_if *batman_if;
- struct sk_buff *skb_old;
- uint8_t dstaddr[ETH_ALEN];
- int hdr_size = sizeof(struct unicast_packet);
- unsigned long flags;
/* drop packet if it has not necessary minimum size */
- if (skb_headlen(skb) < hdr_size)
- return NET_RX_DROP;
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return -1;
- ethhdr = (struct ethhdr *) skb_mac_header(skb);
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* packet with unicast indication but broadcast recipient */
if (is_bcast(ethhdr->h_dest))
- return NET_RX_DROP;
+ return -1;
/* packet with broadcast sender address */
if (is_bcast(ethhdr->h_source))
- return NET_RX_DROP;
+ return -1;
/* not for me */
if (!is_my_mac(ethhdr->h_dest))
- return NET_RX_DROP;
+ return -1;
+
+ return 0;
+}
+
+static int route_unicast_packet(struct sk_buff *skb,
+ struct batman_if *recv_if, int hdr_size)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct orig_node *orig_node;
+ struct neigh_node *router;
+ struct batman_if *batman_if;
+ uint8_t dstaddr[ETH_ALEN];
+ unsigned long flags;
+ struct unicast_packet *unicast_packet;
+ struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
- unicast_packet = (struct unicast_packet *) skb->data;
+ unicast_packet = (struct unicast_packet *)skb->data;
/* packet for me */
if (is_my_mac(unicast_packet->dest)) {
- interface_rx(skb, hdr_size);
+ interface_rx(recv_if->soft_iface, skb, hdr_size);
return NET_RX_SUCCESS;
}
/* TTL exceeded */
if (unicast_packet->ttl < 2) {
- pr_warning("Warning - can't forward unicast packet from %pM to "
- "%pM: ttl exceeded\n", ethhdr->h_source,
- unicast_packet->dest);
+ pr_debug("Warning - can't forward unicast packet from %pM to "
+ "%pM: ttl exceeded\n", ethhdr->h_source,
+ unicast_packet->dest);
return NET_RX_DROP;
}
/* get routing information */
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
orig_node = ((struct orig_node *)
- hash_find(orig_hash, unicast_packet->dest));
+ hash_find(bat_priv->orig_hash, unicast_packet->dest));
router = find_router(orig_node, recv_if);
if (!router) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return NET_RX_DROP;
}
@@ -1169,18 +1165,14 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
batman_if = router->if_incoming;
memcpy(dstaddr, router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
/* create a copy of the skb, if needed, to modify it. */
- if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
- skb_old = skb;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return NET_RX_DROP;
- unicast_packet = (struct unicast_packet *) skb->data;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
- kfree_skb(skb_old);
- }
+ if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* decrement ttl */
unicast_packet->ttl--;
@@ -1191,8 +1183,90 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
return NET_RX_SUCCESS;
}
-int recv_bcast_packet(struct sk_buff *skb)
+int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct unicast_packet *unicast_packet;
+ int hdr_size = sizeof(struct unicast_packet);
+
+ if (check_unicast_packet(skb, hdr_size) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ /* packet for me */
+ if (is_my_mac(unicast_packet->dest)) {
+ interface_rx(recv_if->soft_iface, skb, hdr_size);
+ return NET_RX_SUCCESS;
+ }
+
+ return route_unicast_packet(skb, recv_if, hdr_size);
+}
+
+int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
+ struct unicast_frag_packet *unicast_packet;
+ struct orig_node *orig_node;
+ struct frag_packet_list_entry *tmp_frag_entry;
+ int hdr_size = sizeof(struct unicast_frag_packet);
+ unsigned long flags;
+
+ if (check_unicast_packet(skb, hdr_size) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct unicast_frag_packet *)skb->data;
+
+ /* packet for me */
+ if (is_my_mac(unicast_packet->dest)) {
+
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(bat_priv->orig_hash, unicast_packet->orig));
+
+ if (!orig_node) {
+ pr_debug("couldn't find orig node for fragmentation\n");
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
+ flags);
+ return NET_RX_DROP;
+ }
+
+ orig_node->last_frag_packet = jiffies;
+
+ if (list_empty(&orig_node->frag_list) &&
+ create_frag_buffer(&orig_node->frag_list)) {
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
+ flags);
+ return NET_RX_DROP;
+ }
+
+ tmp_frag_entry =
+ search_frag_packet(&orig_node->frag_list,
+ unicast_packet);
+
+ if (!tmp_frag_entry) {
+ create_frag_entry(&orig_node->frag_list, skb);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
+ flags);
+ return NET_RX_SUCCESS;
+ }
+
+ skb = merge_frag_packet(&orig_node->frag_list,
+ tmp_frag_entry, skb);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
+ if (!skb)
+ return NET_RX_DROP;
+
+ interface_rx(recv_if->soft_iface, skb, hdr_size);
+ return NET_RX_SUCCESS;
+ }
+
+ return route_unicast_packet(skb, recv_if, hdr_size);
+}
+
+
+int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
+{
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct orig_node *orig_node;
struct bcast_packet *bcast_packet;
struct ethhdr *ethhdr;
@@ -1201,7 +1275,7 @@ int recv_bcast_packet(struct sk_buff *skb)
unsigned long flags;
/* drop packet if it has not necessary minimum size */
- if (skb_headlen(skb) < hdr_size)
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
return NET_RX_DROP;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
@@ -1227,12 +1301,12 @@ int recv_bcast_packet(struct sk_buff *skb)
if (bcast_packet->ttl < 2)
return NET_RX_DROP;
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
orig_node = ((struct orig_node *)
- hash_find(orig_hash, bcast_packet->orig));
+ hash_find(bat_priv->orig_hash, bcast_packet->orig));
if (orig_node == NULL) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return NET_RX_DROP;
}
@@ -1240,44 +1314,49 @@ int recv_bcast_packet(struct sk_buff *skb)
if (get_bit_status(orig_node->bcast_bits,
orig_node->last_bcast_seqno,
ntohl(bcast_packet->seqno))) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return NET_RX_DROP;
}
seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
/* check whether the packet is old and the host just restarted. */
- if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ if (window_protected(bat_priv, seq_diff,
+ &orig_node->bcast_seqno_reset)) {
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
return NET_RX_DROP;
}
/* mark broadcast in flood history, update window position
* if required. */
- if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1))
+ if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
/* rebroadcast packet */
- add_bcast_packet_to_list(skb);
+ add_bcast_packet_to_list(bat_priv, skb);
/* broadcast for me */
- interface_rx(skb, hdr_size);
+ interface_rx(recv_if->soft_iface, skb, hdr_size);
return NET_RX_SUCCESS;
}
-int recv_vis_packet(struct sk_buff *skb)
+int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if)
{
struct vis_packet *vis_packet;
struct ethhdr *ethhdr;
- struct bat_priv *bat_priv;
+ struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
int hdr_size = sizeof(struct vis_packet);
- if (skb_headlen(skb) < hdr_size)
+ /* keep skb linear */
+ if (skb_linearize(skb) < 0)
return NET_RX_DROP;
- vis_packet = (struct vis_packet *) skb->data;
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
+ return NET_RX_DROP;
+
+ vis_packet = (struct vis_packet *)skb->data;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* not for me */
@@ -1291,18 +1370,13 @@ int recv_vis_packet(struct sk_buff *skb)
if (is_my_mac(vis_packet->sender_orig))
return NET_RX_DROP;
- /* FIXME: each batman_if will be attached to a softif */
- bat_priv = netdev_priv(soft_device);
-
switch (vis_packet->vis_type) {
case VIS_TYPE_SERVER_SYNC:
- /* TODO: handle fragmented skbs properly */
receive_server_sync_packet(bat_priv, vis_packet,
skb_headlen(skb));
break;
case VIS_TYPE_CLIENT_UPDATE:
- /* TODO: handle fragmented skbs properly */
receive_client_update_packet(bat_priv, vis_packet,
skb_headlen(skb));
break;
diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h
index 3eac64e3cf9b..06ea99df3706 100644
--- a/drivers/staging/batman-adv/routing.h
+++ b/drivers/staging/batman-adv/routing.h
@@ -29,15 +29,15 @@ void receive_bat_packet(struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
unsigned char *hna_buff, int hna_buff_len,
struct batman_if *if_incoming);
-void update_routes(struct orig_node *orig_node,
- struct neigh_node *neigh_node,
- unsigned char *hna_buff, int hna_buff_len);
-int recv_icmp_packet(struct sk_buff *skb);
+void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
+ struct neigh_node *neigh_node, unsigned char *hna_buff,
+ int hna_buff_len);
+int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if);
int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
-int recv_bcast_packet(struct sk_buff *skb);
-int recv_vis_packet(struct sk_buff *skb);
-int recv_bat_packet(struct sk_buff *skb,
- struct batman_if *batman_if);
+int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if);
+int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if);
struct neigh_node *find_router(struct orig_node *orig_node,
struct batman_if *recv_if);
void update_bonding_candidates(struct bat_priv *bat_priv,
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index 055edee7b4e4..5d57ef5120b0 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -29,7 +29,6 @@
#include "vis.h"
#include "aggregation.h"
-#include <linux/netfilter_bridge.h>
static void send_outstanding_bcast_packet(struct work_struct *work);
@@ -69,12 +68,12 @@ int send_skb_packet(struct sk_buff *skb,
if (!(batman_if->net_dev->flags & IFF_UP)) {
pr_warning("Interface %s is not up - can't send packet via "
- "that interface!\n", batman_if->dev);
+ "that interface!\n", batman_if->net_dev->name);
goto send_skb_err;
}
/* push to the ethernet header. */
- if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
+ if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0)
goto send_skb_err;
skb_reset_mac_header(skb);
@@ -92,52 +91,31 @@ int send_skb_packet(struct sk_buff *skb,
/* dev_queue_xmit() returns a negative result on error. However on
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
- * (which is > 0). This will not be treated as an error.
- * Also, if netfilter/ebtables wants to block outgoing batman
- * packets then giving them a chance to do so here */
+ * (which is > 0). This will not be treated as an error. */
- return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
- dev_queue_xmit);
+ return dev_queue_xmit(skb);
send_skb_err:
kfree_skb(skb);
return NET_XMIT_DROP;
}
-/* sends a raw packet. */
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
- struct batman_if *batman_if, uint8_t *dst_addr)
-{
- struct sk_buff *skb;
- char *data;
-
- skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
- if (!skb)
- return;
- data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
- memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
- /* pull back to the batman "network header" */
- skb_pull(skb, sizeof(struct ethhdr));
- send_skb_packet(skb, batman_if, dst_addr);
-}
-
/* Send a packet to a given interface */
static void send_packet_to_if(struct forw_packet *forw_packet,
struct batman_if *batman_if)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
char *fwd_str;
uint8_t packet_num;
int16_t buff_pos;
struct batman_packet *batman_packet;
+ struct sk_buff *skb;
if (batman_if->if_status != IF_ACTIVE)
return;
packet_num = 0;
buff_pos = 0;
- batman_packet = (struct batman_packet *)
- (forw_packet->packet_buff);
+ batman_packet = (struct batman_packet *)forw_packet->skb->data;
/* adjust all flags and log packets */
while (aggregated_packet(buff_pos,
@@ -163,28 +141,29 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
batman_packet->tq, batman_packet->ttl,
(batman_packet->flags & DIRECTLINK ?
"on" : "off"),
- batman_if->dev, batman_if->addr_str);
+ batman_if->net_dev->name, batman_if->addr_str);
buff_pos += sizeof(struct batman_packet) +
(batman_packet->num_hna * ETH_ALEN);
packet_num++;
batman_packet = (struct batman_packet *)
- (forw_packet->packet_buff + buff_pos);
+ (forw_packet->skb->data + buff_pos);
}
- send_raw_packet(forw_packet->packet_buff,
- forw_packet->packet_len,
- batman_if, broadcast_addr);
+ /* create clone because function is called more than once */
+ skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, broadcast_addr);
}
/* send a batman packet */
static void send_packet(struct forw_packet *forw_packet)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_if *batman_if;
+ struct net_device *soft_iface = forw_packet->if_incoming->soft_iface;
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct batman_packet *batman_packet =
- (struct batman_packet *)(forw_packet->packet_buff);
+ (struct batman_packet *)(forw_packet->skb->data);
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
@@ -207,30 +186,38 @@ static void send_packet(struct forw_packet *forw_packet)
"on interface %s [%s]\n",
(forw_packet->own ? "Sending own" : "Forwarding"),
batman_packet->orig, ntohl(batman_packet->seqno),
- batman_packet->ttl, forw_packet->if_incoming->dev,
+ batman_packet->ttl,
+ forw_packet->if_incoming->net_dev->name,
forw_packet->if_incoming->addr_str);
- send_raw_packet(forw_packet->packet_buff,
- forw_packet->packet_len,
- forw_packet->if_incoming,
+ /* skb is only used once and than forw_packet is free'd */
+ send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
broadcast_addr);
+ forw_packet->skb = NULL;
+
return;
}
/* broadcast on every interface */
rcu_read_lock();
- list_for_each_entry_rcu(batman_if, &if_list, list)
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
send_packet_to_if(forw_packet, batman_if);
+ }
rcu_read_unlock();
}
-static void rebuild_batman_packet(struct batman_if *batman_if)
+static void rebuild_batman_packet(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
{
int new_len;
unsigned char *new_buff;
struct batman_packet *batman_packet;
- new_len = sizeof(struct batman_packet) + (num_hna * ETH_ALEN);
+ new_len = sizeof(struct batman_packet) +
+ (bat_priv->num_local_hna * ETH_ALEN);
new_buff = kmalloc(new_len, GFP_ATOMIC);
/* keep old buffer if kmalloc should fail */
@@ -239,9 +226,9 @@ static void rebuild_batman_packet(struct batman_if *batman_if)
sizeof(struct batman_packet));
batman_packet = (struct batman_packet *)new_buff;
- batman_packet->num_hna = hna_local_fill_buffer(
- new_buff + sizeof(struct batman_packet),
- new_len - sizeof(struct batman_packet));
+ batman_packet->num_hna = hna_local_fill_buffer(bat_priv,
+ new_buff + sizeof(struct batman_packet),
+ new_len - sizeof(struct batman_packet));
kfree(batman_if->packet_buff);
batman_if->packet_buff = new_buff;
@@ -251,8 +238,7 @@ static void rebuild_batman_packet(struct batman_if *batman_if)
void schedule_own_packet(struct batman_if *batman_if)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
unsigned long send_time;
struct batman_packet *batman_packet;
int vis_server;
@@ -274,9 +260,9 @@ void schedule_own_packet(struct batman_if *batman_if)
batman_if->if_status = IF_ACTIVE;
/* if local hna has changed and interface is a primary interface */
- if ((atomic_read(&hna_local_changed)) &&
+ if ((atomic_read(&bat_priv->hna_local_changed)) &&
(batman_if == bat_priv->primary_if))
- rebuild_batman_packet(batman_if);
+ rebuild_batman_packet(bat_priv, batman_if);
/**
* NOTE: packet_buff might just have been re-allocated in
@@ -309,8 +295,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
uint8_t directlink, int hna_buff_len,
struct batman_if *if_incoming)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
unsigned char in_tq, in_ttl, tq_avg = 0;
unsigned long send_time;
@@ -370,20 +355,20 @@ static void forw_packet_free(struct forw_packet *forw_packet)
{
if (forw_packet->skb)
kfree_skb(forw_packet->skb);
- kfree(forw_packet->packet_buff);
kfree(forw_packet);
}
-static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
+static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
+ struct forw_packet *forw_packet,
unsigned long send_time)
{
unsigned long flags;
INIT_HLIST_NODE(&forw_packet->list);
/* add new packet to packet list */
- spin_lock_irqsave(&forw_bcast_list_lock, flags);
- hlist_add_head(&forw_packet->list, &forw_bcast_list);
- spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
+ hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list);
+ spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
/* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet->delayed_work,
@@ -401,18 +386,19 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
*
* The skb is not consumed, so the caller should make sure that the
* skb is freed. */
-int add_bcast_packet_to_list(struct sk_buff *skb)
+int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
{
struct forw_packet *forw_packet;
struct bcast_packet *bcast_packet;
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
- if (!atomic_dec_not_zero(&bcast_queue_left)) {
+ if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
goto out;
}
+ if (!bat_priv->primary_if)
+ goto out;
+
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
if (!forw_packet)
@@ -429,18 +415,18 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
skb_reset_mac_header(skb);
forw_packet->skb = skb;
- forw_packet->packet_buff = NULL;
+ forw_packet->if_incoming = bat_priv->primary_if;
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
- _add_bcast_packet_to_list(forw_packet, 1);
+ _add_bcast_packet_to_list(bat_priv, forw_packet, 1);
return NETDEV_TX_OK;
packet_free:
kfree(forw_packet);
out_and_inc:
- atomic_inc(&bcast_queue_left);
+ atomic_inc(&bat_priv->bcast_queue_left);
out:
return NETDEV_TX_BUSY;
}
@@ -454,22 +440,26 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
container_of(delayed_work, struct forw_packet, delayed_work);
unsigned long flags;
struct sk_buff *skb1;
+ struct net_device *soft_iface = forw_packet->if_incoming->soft_iface;
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
- spin_lock_irqsave(&forw_bcast_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
hlist_del(&forw_packet->list);
- spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
- if (atomic_read(&module_state) == MODULE_DEACTIVATING)
+ if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
goto out;
/* rebroadcast packet */
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
+ if (batman_if->soft_iface != soft_iface)
+ continue;
+
/* send a copy of the saved skb */
- skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
+ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb1)
- send_skb_packet(skb1,
- batman_if, broadcast_addr);
+ send_skb_packet(skb1, batman_if, broadcast_addr);
}
rcu_read_unlock();
@@ -477,13 +467,14 @@ static void send_outstanding_bcast_packet(struct work_struct *work)
/* if we still have some more bcasts to send */
if (forw_packet->num_packets < 3) {
- _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
+ _add_bcast_packet_to_list(bat_priv, forw_packet,
+ ((5 * HZ) / 1000));
return;
}
out:
forw_packet_free(forw_packet);
- atomic_inc(&bcast_queue_left);
+ atomic_inc(&bat_priv->bcast_queue_left);
}
void send_outstanding_bat_packet(struct work_struct *work)
@@ -493,12 +484,14 @@ void send_outstanding_bat_packet(struct work_struct *work)
struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work);
unsigned long flags;
+ struct bat_priv *bat_priv;
- spin_lock_irqsave(&forw_bat_list_lock, flags);
+ bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
+ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
hlist_del(&forw_packet->list);
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
- if (atomic_read(&module_state) == MODULE_DEACTIVATING)
+ if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
goto out;
send_packet(forw_packet);
@@ -514,15 +507,14 @@ void send_outstanding_bat_packet(struct work_struct *work)
out:
/* don't count own packet */
if (!forw_packet->own)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
forw_packet_free(forw_packet);
}
-void purge_outstanding_packets(struct batman_if *batman_if)
+void purge_outstanding_packets(struct bat_priv *bat_priv,
+ struct batman_if *batman_if)
{
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
unsigned long flags;
@@ -530,15 +522,15 @@ void purge_outstanding_packets(struct batman_if *batman_if)
if (batman_if)
bat_dbg(DBG_BATMAN, bat_priv,
"purge_outstanding_packets(): %s\n",
- batman_if->dev);
+ batman_if->net_dev->name);
else
bat_dbg(DBG_BATMAN, bat_priv,
"purge_outstanding_packets()\n");
/* free bcast list */
- spin_lock_irqsave(&forw_bcast_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &forw_bcast_list, list) {
+ &bat_priv->forw_bcast_list, list) {
/**
* if purge_outstanding_packets() was called with an argmument
@@ -548,21 +540,21 @@ void purge_outstanding_packets(struct batman_if *batman_if)
(forw_packet->if_incoming != batman_if))
continue;
- spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
/**
* send_outstanding_bcast_packet() will lock the list to
* delete the item from the list
*/
cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_irqsave(&forw_bcast_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
}
- spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
/* free batman packet list */
- spin_lock_irqsave(&forw_bat_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &forw_bat_list, list) {
+ &bat_priv->forw_bat_list, list) {
/**
* if purge_outstanding_packets() was called with an argmument
@@ -572,14 +564,14 @@ void purge_outstanding_packets(struct batman_if *batman_if)
(forw_packet->if_incoming != batman_if))
continue;
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
/**
* send_outstanding_bat_packet() will lock the list to
* delete the item from the list
*/
cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_irqsave(&forw_bat_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
}
- spin_unlock_irqrestore(&forw_bat_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
}
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h
index b64c62783fec..c4cefa8e4f85 100644
--- a/drivers/staging/batman-adv/send.h
+++ b/drivers/staging/batman-adv/send.h
@@ -27,16 +27,15 @@
int send_skb_packet(struct sk_buff *skb,
struct batman_if *batman_if,
uint8_t *dst_addr);
-void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
- struct batman_if *batman_if, uint8_t *dst_addr);
void schedule_own_packet(struct batman_if *batman_if);
void schedule_forward_packet(struct orig_node *orig_node,
struct ethhdr *ethhdr,
struct batman_packet *batman_packet,
uint8_t directlink, int hna_buff_len,
struct batman_if *if_outgoing);
-int add_bcast_packet_to_list(struct sk_buff *skb);
+int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
void send_outstanding_bat_packet(struct work_struct *work);
-void purge_outstanding_packets(struct batman_if *batman_if);
+void purge_outstanding_packets(struct bat_priv *bat_priv,
+ struct batman_if *batman_if);
#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index 2ea97de435ce..3904db9ce7b1 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -24,19 +24,18 @@
#include "hard-interface.h"
#include "routing.h"
#include "send.h"
+#include "bat_debugfs.h"
#include "translation-table.h"
#include "types.h"
#include "hash.h"
+#include "send.h"
+#include "bat_sysfs.h"
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
+#include "unicast.h"
-static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
- * broadcast storms */
-static int32_t skb_packets;
-static int32_t skb_bad_packets;
-unsigned char main_if_addr[ETH_ALEN];
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
static void bat_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info);
@@ -56,23 +55,21 @@ static const struct ethtool_ops bat_ethtool_ops = {
.set_rx_csum = bat_set_rx_csum
};
-void set_main_if_addr(uint8_t *addr)
-{
- memcpy(main_if_addr, addr, ETH_ALEN);
-}
-
-int my_skb_push(struct sk_buff *skb, unsigned int len)
+int my_skb_head_push(struct sk_buff *skb, unsigned int len)
{
- int result = 0;
-
- skb_packets++;
- if (skb_headroom(skb) < len) {
- skb_bad_packets++;
- result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
-
- if (result < 0)
- return result;
- }
+ int result;
+
+ /**
+ * TODO: We must check if we can release all references to non-payload
+ * data using skb_header_release in our skbs to allow skb_cow_header to
+ * work optimally. This means that those skbs are not allowed to read
+ * or write any data which is before the current position of skb->data
+ * after that call and thus allow other skbs with the same data buffer
+ * to write freely in that area.
+ */
+ result = skb_cow_head(skb, len);
+ if (result < 0)
+ return result;
skb_push(skb, len);
return 0;
@@ -92,21 +89,23 @@ static int interface_release(struct net_device *dev)
static struct net_device_stats *interface_stats(struct net_device *dev)
{
- struct bat_priv *priv = netdev_priv(dev);
- return &priv->stats;
+ struct bat_priv *bat_priv = netdev_priv(dev);
+ return &bat_priv->stats;
}
static int interface_set_mac_addr(struct net_device *dev, void *p)
{
+ struct bat_priv *bat_priv = netdev_priv(dev);
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
/* only modify hna-table if it has been initialised before */
- if (atomic_read(&module_state) == MODULE_ACTIVE) {
- hna_local_remove(dev->dev_addr, "mac address changed");
- hna_local_add(addr->sa_data);
+ if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
+ hna_local_remove(bat_priv, dev->dev_addr,
+ "mac address changed");
+ hna_local_add(dev, addr->sa_data);
}
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -117,7 +116,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
static int interface_change_mtu(struct net_device *dev, int new_mtu)
{
/* check ranges */
- if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
+ if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev)))
return -EINVAL;
dev->mtu = new_mtu;
@@ -125,34 +124,27 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-int interface_tx(struct sk_buff *skb, struct net_device *dev)
+int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
{
- struct unicast_packet *unicast_packet;
- struct bcast_packet *bcast_packet;
- struct orig_node *orig_node;
- struct neigh_node *router;
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
- struct bat_priv *priv = netdev_priv(dev);
- struct batman_if *batman_if;
- struct bat_priv *bat_priv;
- uint8_t dstaddr[6];
- int data_len = skb->len;
- unsigned long flags;
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
+ struct bcast_packet *bcast_packet;
+ int data_len = skb->len, ret;
- if (atomic_read(&module_state) != MODULE_ACTIVE)
+ if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
goto dropped;
- /* FIXME: each batman_if will be attached to a softif */
- bat_priv = netdev_priv(soft_device);
+ soft_iface->trans_start = jiffies;
- dev->trans_start = jiffies;
/* TODO: check this for locks */
- hna_local_add(ethhdr->h_source);
+ hna_local_add(soft_iface, ethhdr->h_source);
/* ethernet packet should be broadcasted */
if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
+ if (!bat_priv->primary_if)
+ goto dropped;
- if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0)
+ if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
goto dropped;
bcast_packet = (struct bcast_packet *)skb->data;
@@ -164,14 +156,14 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
- memcpy(bcast_packet->orig, main_if_addr, ETH_ALEN);
+ memcpy(bcast_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */
- bcast_packet->seqno = htonl(bcast_seqno);
+ bcast_packet->seqno =
+ htonl(atomic_inc_return(&bat_priv->bcast_seqno));
- /* broadcast packet. on success, increase seqno. */
- if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
- bcast_seqno++;
+ add_bcast_packet_to_list(bat_priv, skb);
/* a copy is stored in the bcast list, therefore removing
* the original skb. */
@@ -179,64 +171,27 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
/* unicast packet */
} else {
- spin_lock_irqsave(&orig_hash_lock, flags);
- /* get routing information */
- orig_node = ((struct orig_node *)hash_find(orig_hash,
- ethhdr->h_dest));
-
- /* check for hna host */
- if (!orig_node)
- orig_node = transtable_search(ethhdr->h_dest);
-
- router = find_router(orig_node, NULL);
-
- if (!router)
- goto unlock;
-
- /* don't lock while sending the packets ... we therefore
- * copy the required data before sending */
-
- batman_if = router->if_incoming;
- memcpy(dstaddr, router->addr, ETH_ALEN);
-
- spin_unlock_irqrestore(&orig_hash_lock, flags);
-
- if (batman_if->if_status != IF_ACTIVE)
- goto dropped;
-
- if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
- goto dropped;
-
- unicast_packet = (struct unicast_packet *)skb->data;
-
- unicast_packet->version = COMPAT_VERSION;
- /* batman packet type: unicast */
- unicast_packet->packet_type = BAT_UNICAST;
- /* set unicast ttl */
- unicast_packet->ttl = TTL;
- /* copy the destination for faster routing */
- memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
-
- send_skb_packet(skb, batman_if, dstaddr);
+ ret = unicast_send_skb(skb, bat_priv);
+ if (ret != 0)
+ goto dropped_freed;
}
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += data_len;
+ bat_priv->stats.tx_packets++;
+ bat_priv->stats.tx_bytes += data_len;
goto end;
-unlock:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
dropped:
- priv->stats.tx_dropped++;
kfree_skb(skb);
+dropped_freed:
+ bat_priv->stats.tx_dropped++;
end:
return NETDEV_TX_OK;
}
-void interface_rx(struct sk_buff *skb, int hdr_size)
+void interface_rx(struct net_device *soft_iface,
+ struct sk_buff *skb, int hdr_size)
{
- struct net_device *dev = soft_device;
- struct bat_priv *priv = netdev_priv(dev);
+ struct bat_priv *priv = netdev_priv(soft_iface);
/* check if enough space is available for pulling, and pull */
if (!pskb_may_pull(skb, hdr_size)) {
@@ -246,8 +201,8 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
skb_pull_rcsum(skb, hdr_size);
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
+ /* skb->dev & skb->pkt_type are set here */
+ skb->protocol = eth_type_trans(skb, soft_iface);
/* should not be neccesary anymore as we use skb_pull_rcsum()
* TODO: please verify this and remove this TODO
@@ -255,13 +210,10 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
- /* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST,
- * PACKET_OTHERHOST or PACKET_HOST */
-
priv->stats.rx_packets++;
- priv->stats.rx_bytes += skb->len;
+ priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
- dev->last_rx = jiffies;
+ soft_iface->last_rx = jiffies;
netif_rx(skb);
}
@@ -278,7 +230,7 @@ static const struct net_device_ops bat_netdev_ops = {
};
#endif
-void interface_setup(struct net_device *dev)
+static void interface_setup(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
char dev_addr[ETH_ALEN];
@@ -297,7 +249,11 @@ void interface_setup(struct net_device *dev)
#endif
dev->destructor = free_netdev;
- dev->mtu = hardif_min_mtu();
+ /**
+ * can't call min_mtu, because the needed variables
+ * have not been initialized yet
+ */
+ dev->mtu = ETH_DATA_LEN;
dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
* skbuff for our header */
@@ -310,6 +266,81 @@ void interface_setup(struct net_device *dev)
memset(priv, 0, sizeof(struct bat_priv));
}
+struct net_device *softif_create(char *name)
+{
+ struct net_device *soft_iface;
+ struct bat_priv *bat_priv;
+ int ret;
+
+ soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
+ interface_setup);
+
+ if (!soft_iface) {
+ pr_err("Unable to allocate the batman interface: %s\n", name);
+ goto out;
+ }
+
+ ret = register_netdev(soft_iface);
+ if (ret < 0) {
+ pr_err("Unable to register the batman interface '%s': %i\n",
+ name, ret);
+ goto free_soft_iface;
+ }
+
+ bat_priv = netdev_priv(soft_iface);
+
+ atomic_set(&bat_priv->aggregation_enabled, 1);
+ atomic_set(&bat_priv->bonding_enabled, 0);
+ atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
+ atomic_set(&bat_priv->orig_interval, 1000);
+ atomic_set(&bat_priv->log_level, 0);
+ atomic_set(&bat_priv->frag_enabled, 1);
+ atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
+ atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
+
+ atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
+ atomic_set(&bat_priv->bcast_seqno, 1);
+ atomic_set(&bat_priv->hna_local_changed, 0);
+
+ bat_priv->primary_if = NULL;
+ bat_priv->num_ifaces = 0;
+
+ ret = sysfs_add_meshif(soft_iface);
+ if (ret < 0)
+ goto unreg_soft_iface;
+
+ ret = debugfs_add_meshif(soft_iface);
+ if (ret < 0)
+ goto unreg_sysfs;
+
+ ret = mesh_init(soft_iface);
+ if (ret < 0)
+ goto unreg_debugfs;
+
+ return soft_iface;
+
+unreg_debugfs:
+ debugfs_del_meshif(soft_iface);
+unreg_sysfs:
+ sysfs_del_meshif(soft_iface);
+unreg_soft_iface:
+ unregister_netdev(soft_iface);
+ return NULL;
+
+free_soft_iface:
+ free_netdev(soft_iface);
+out:
+ return NULL;
+}
+
+void softif_destroy(struct net_device *soft_iface)
+{
+ debugfs_del_meshif(soft_iface);
+ sysfs_del_meshif(soft_iface);
+ mesh_free(soft_iface);
+ unregister_netdevice(soft_iface);
+}
+
/* ethtool */
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h
index 636485439009..843a7ec082fe 100644
--- a/drivers/staging/batman-adv/soft-interface.h
+++ b/drivers/staging/batman-adv/soft-interface.h
@@ -22,12 +22,11 @@
#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
-void set_main_if_addr(uint8_t *addr);
-void interface_setup(struct net_device *dev);
-int interface_tx(struct sk_buff *skb, struct net_device *dev);
-void interface_rx(struct sk_buff *skb, int hdr_size);
-int my_skb_push(struct sk_buff *skb, unsigned int len);
-
-extern unsigned char main_if_addr[];
+int my_skb_head_push(struct sk_buff *skb, unsigned int len);
+int interface_tx(struct sk_buff *skb, struct net_device *soft_iface);
+void interface_rx(struct net_device *soft_iface,
+ struct sk_buff *skb, int hdr_size);
+struct net_device *softif_create(char *name);
+void softif_destroy(struct net_device *soft_iface);
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c
index b233377d7568..12b23259c385 100644
--- a/drivers/staging/batman-adv/translation-table.c
+++ b/drivers/staging/batman-adv/translation-table.c
@@ -25,54 +25,48 @@
#include "types.h"
#include "hash.h"
-struct hashtable_t *hna_local_hash;
-static struct hashtable_t *hna_global_hash;
-atomic_t hna_local_changed;
-
-DEFINE_SPINLOCK(hna_local_hash_lock);
-static DEFINE_SPINLOCK(hna_global_hash_lock);
-
static void hna_local_purge(struct work_struct *work);
-static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);
-static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+static void _hna_global_del_orig(struct bat_priv *bat_priv,
+ struct hna_global_entry *hna_global_entry,
char *message);
-static void hna_local_start_timer(void)
+static void hna_local_start_timer(struct bat_priv *bat_priv)
{
- queue_delayed_work(bat_event_workqueue, &hna_local_purge_wq, 10 * HZ);
+ INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ);
}
-int hna_local_init(void)
+int hna_local_init(struct bat_priv *bat_priv)
{
- if (hna_local_hash)
+ if (bat_priv->hna_local_hash)
return 1;
- hna_local_hash = hash_new(128, compare_orig, choose_orig);
+ bat_priv->hna_local_hash = hash_new(128, compare_orig, choose_orig);
- if (!hna_local_hash)
+ if (!bat_priv->hna_local_hash)
return 0;
- atomic_set(&hna_local_changed, 0);
- hna_local_start_timer();
+ atomic_set(&bat_priv->hna_local_changed, 0);
+ hna_local_start_timer(bat_priv);
return 1;
}
-void hna_local_add(uint8_t *addr)
+void hna_local_add(struct net_device *soft_iface, uint8_t *addr)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
+ struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct hna_local_entry *hna_local_entry;
struct hna_global_entry *hna_global_entry;
struct hashtable_t *swaphash;
unsigned long flags;
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
hna_local_entry =
- ((struct hna_local_entry *)hash_find(hna_local_hash, addr));
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash,
+ addr));
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
- if (hna_local_entry != NULL) {
+ if (hna_local_entry) {
hna_local_entry->last_seen = jiffies;
return;
}
@@ -80,8 +74,9 @@ void hna_local_add(uint8_t *addr)
/* only announce as many hosts as possible in the batman-packet and
space in batman_packet->num_hna That also should give a limit to
MAC-flooding. */
- if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
- (num_hna + 1 > 255)) {
+ if ((bat_priv->num_local_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN)
+ / ETH_ALEN) ||
+ (bat_priv->num_local_hna + 1 > 255)) {
bat_dbg(DBG_ROUTES, bat_priv,
"Can't add new local hna entry (%pM): "
"number of local hna entries exceeds packet size\n",
@@ -100,51 +95,54 @@ void hna_local_add(uint8_t *addr)
hna_local_entry->last_seen = jiffies;
/* the batman interface mac address should never be purged */
- if (compare_orig(addr, soft_device->dev_addr))
+ if (compare_orig(addr, soft_iface->dev_addr))
hna_local_entry->never_purge = 1;
else
hna_local_entry->never_purge = 0;
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
- hash_add(hna_local_hash, hna_local_entry);
- num_hna++;
- atomic_set(&hna_local_changed, 1);
+ hash_add(bat_priv->hna_local_hash, hna_local_entry);
+ bat_priv->num_local_hna++;
+ atomic_set(&bat_priv->hna_local_changed, 1);
- if (hna_local_hash->elements * 4 > hna_local_hash->size) {
- swaphash = hash_resize(hna_local_hash,
- hna_local_hash->size * 2);
+ if (bat_priv->hna_local_hash->elements * 4 >
+ bat_priv->hna_local_hash->size) {
+ swaphash = hash_resize(bat_priv->hna_local_hash,
+ bat_priv->hna_local_hash->size * 2);
- if (swaphash == NULL)
+ if (!swaphash)
pr_err("Couldn't resize local hna hash table\n");
else
- hna_local_hash = swaphash;
+ bat_priv->hna_local_hash = swaphash;
}
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
/* remove address from global hash if present */
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
- hna_global_entry =
- ((struct hna_global_entry *)hash_find(hna_global_hash, addr));
+ hna_global_entry = ((struct hna_global_entry *)
+ hash_find(bat_priv->hna_global_hash, addr));
- if (hna_global_entry != NULL)
- _hna_global_del_orig(hna_global_entry, "local hna received");
+ if (hna_global_entry)
+ _hna_global_del_orig(bat_priv, hna_global_entry,
+ "local hna received");
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
}
-int hna_local_fill_buffer(unsigned char *buff, int buff_len)
+int hna_local_fill_buffer(struct bat_priv *bat_priv,
+ unsigned char *buff, int buff_len)
{
struct hna_local_entry *hna_local_entry;
HASHIT(hashit);
int i = 0;
unsigned long flags;
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
- while (hash_iterate(hna_local_hash, &hashit)) {
+ while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
if (buff_len < (i + 1) * ETH_ALEN)
break;
@@ -156,11 +154,10 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
}
/* if we did not get all new local hnas see you next time ;-) */
- if (i == num_hna)
- atomic_set(&hna_local_changed, 0);
-
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ if (i == bat_priv->num_local_hna)
+ atomic_set(&bat_priv->hna_local_changed, 0);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
return i;
}
@@ -185,119 +182,126 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
"announced via HNA:\n",
net_dev->name);
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
- while (hash_iterate(hna_local_hash, &hashit_count))
+ while (hash_iterate(bat_priv->hna_local_hash, &hashit_count))
buf_size += 21;
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
pos = 0;
- while (hash_iterate(hna_local_hash, &hashit)) {
+ while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
hna_local_entry = hashit.bucket->data;
pos += snprintf(buff + pos, 22, " * %pM\n",
hna_local_entry->addr);
}
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
seq_printf(seq, "%s", buff);
kfree(buff);
return 0;
}
-static void _hna_local_del(void *data)
+static void _hna_local_del(void *data, void *arg)
{
+ struct bat_priv *bat_priv = (struct bat_priv *)arg;
+
kfree(data);
- num_hna--;
- atomic_set(&hna_local_changed, 1);
+ bat_priv->num_local_hna--;
+ atomic_set(&bat_priv->hna_local_changed, 1);
}
-static void hna_local_del(struct hna_local_entry *hna_local_entry,
+static void hna_local_del(struct bat_priv *bat_priv,
+ struct hna_local_entry *hna_local_entry,
char *message)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
hna_local_entry->addr, message);
- hash_remove(hna_local_hash, hna_local_entry->addr);
- _hna_local_del(hna_local_entry);
+ hash_remove(bat_priv->hna_local_hash, hna_local_entry->addr);
+ _hna_local_del(hna_local_entry, bat_priv);
}
-void hna_local_remove(uint8_t *addr, char *message)
+void hna_local_remove(struct bat_priv *bat_priv,
+ uint8_t *addr, char *message)
{
struct hna_local_entry *hna_local_entry;
unsigned long flags;
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
hna_local_entry = (struct hna_local_entry *)
- hash_find(hna_local_hash, addr);
+ hash_find(bat_priv->hna_local_hash, addr);
if (hna_local_entry)
- hna_local_del(hna_local_entry, message);
+ hna_local_del(bat_priv, hna_local_entry, message);
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
}
static void hna_local_purge(struct work_struct *work)
{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, hna_work);
struct hna_local_entry *hna_local_entry;
HASHIT(hashit);
unsigned long flags;
unsigned long timeout;
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
- while (hash_iterate(hna_local_hash, &hashit)) {
+ while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
hna_local_entry = hashit.bucket->data;
timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ;
+
if ((!hna_local_entry->never_purge) &&
time_after(jiffies, timeout))
- hna_local_del(hna_local_entry, "address timed out");
+ hna_local_del(bat_priv, hna_local_entry,
+ "address timed out");
}
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
- hna_local_start_timer();
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
+ hna_local_start_timer(bat_priv);
}
-void hna_local_free(void)
+void hna_local_free(struct bat_priv *bat_priv)
{
- if (!hna_local_hash)
+ if (!bat_priv->hna_local_hash)
return;
- cancel_delayed_work_sync(&hna_local_purge_wq);
- hash_delete(hna_local_hash, _hna_local_del);
- hna_local_hash = NULL;
+ cancel_delayed_work_sync(&bat_priv->hna_work);
+ hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv);
+ bat_priv->hna_local_hash = NULL;
}
-int hna_global_init(void)
+int hna_global_init(struct bat_priv *bat_priv)
{
- if (hna_global_hash)
+ if (bat_priv->hna_global_hash)
return 1;
- hna_global_hash = hash_new(128, compare_orig, choose_orig);
+ bat_priv->hna_global_hash = hash_new(128, compare_orig, choose_orig);
- if (!hna_global_hash)
+ if (!bat_priv->hna_global_hash)
return 0;
return 1;
}
-void hna_global_add_orig(struct orig_node *orig_node,
+void hna_global_add_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
unsigned char *hna_buff, int hna_buff_len)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct hna_global_entry *hna_global_entry;
struct hna_local_entry *hna_local_entry;
struct hashtable_t *swaphash;
@@ -306,14 +310,15 @@ void hna_global_add_orig(struct orig_node *orig_node,
unsigned char *hna_ptr;
while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
hna_global_entry = (struct hna_global_entry *)
- hash_find(hna_global_hash, hna_ptr);
+ hash_find(bat_priv->hna_global_hash, hna_ptr);
- if (hna_global_entry == NULL) {
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ if (!hna_global_entry) {
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock,
+ flags);
hna_global_entry =
kmalloc(sizeof(struct hna_global_entry),
@@ -329,25 +334,26 @@ void hna_global_add_orig(struct orig_node *orig_node,
"%pM (via %pM)\n",
hna_global_entry->addr, orig_node->orig);
- spin_lock_irqsave(&hna_global_hash_lock, flags);
- hash_add(hna_global_hash, hna_global_entry);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
+ hash_add(bat_priv->hna_global_hash, hna_global_entry);
}
hna_global_entry->orig_node = orig_node;
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
/* remove address from local hash if present */
- spin_lock_irqsave(&hna_local_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
hna_local_entry = (struct hna_local_entry *)
- hash_find(hna_local_hash, hna_ptr);
+ hash_find(bat_priv->hna_local_hash, hna_ptr);
- if (hna_local_entry != NULL)
- hna_local_del(hna_local_entry, "global hna received");
+ if (hna_local_entry)
+ hna_local_del(bat_priv, hna_local_entry,
+ "global hna received");
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
hna_buff_count++;
}
@@ -364,19 +370,20 @@ void hna_global_add_orig(struct orig_node *orig_node,
}
}
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
- if (hna_global_hash->elements * 4 > hna_global_hash->size) {
- swaphash = hash_resize(hna_global_hash,
- hna_global_hash->size * 2);
+ if (bat_priv->hna_global_hash->elements * 4 >
+ bat_priv->hna_global_hash->size) {
+ swaphash = hash_resize(bat_priv->hna_global_hash,
+ bat_priv->hna_global_hash->size * 2);
- if (swaphash == NULL)
+ if (!swaphash)
pr_err("Couldn't resize global hna hash table\n");
else
- hna_global_hash = swaphash;
+ bat_priv->hna_global_hash = swaphash;
}
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
}
int hna_global_seq_print_text(struct seq_file *seq, void *offset)
@@ -399,22 +406,22 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
net_dev->name);
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
- while (hash_iterate(hna_global_hash, &hashit_count))
+ while (hash_iterate(bat_priv->hna_global_hash, &hashit_count))
buf_size += 43;
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
pos = 0;
- while (hash_iterate(hna_global_hash, &hashit)) {
+ while (hash_iterate(bat_priv->hna_global_hash, &hashit)) {
hna_global_entry = hashit.bucket->data;
pos += snprintf(buff + pos, 44,
@@ -422,28 +429,28 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
hna_global_entry->orig_node->orig);
}
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
seq_printf(seq, "%s", buff);
kfree(buff);
return 0;
}
-static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
+static void _hna_global_del_orig(struct bat_priv *bat_priv,
+ struct hna_global_entry *hna_global_entry,
char *message)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
bat_dbg(DBG_ROUTES, bat_priv,
"Deleting global hna entry %pM (via %pM): %s\n",
hna_global_entry->addr, hna_global_entry->orig_node->orig,
message);
- hash_remove(hna_global_hash, hna_global_entry->addr);
+ hash_remove(bat_priv->hna_global_hash, hna_global_entry->addr);
kfree(hna_global_entry);
}
-void hna_global_del_orig(struct orig_node *orig_node, char *message)
+void hna_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, char *message)
{
struct hna_global_entry *hna_global_entry;
int hna_buff_count = 0;
@@ -453,52 +460,53 @@ void hna_global_del_orig(struct orig_node *orig_node, char *message)
if (orig_node->hna_buff_len == 0)
return;
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
hna_global_entry = (struct hna_global_entry *)
- hash_find(hna_global_hash, hna_ptr);
+ hash_find(bat_priv->hna_global_hash, hna_ptr);
- if ((hna_global_entry != NULL) &&
+ if ((hna_global_entry) &&
(hna_global_entry->orig_node == orig_node))
- _hna_global_del_orig(hna_global_entry, message);
+ _hna_global_del_orig(bat_priv, hna_global_entry,
+ message);
hna_buff_count++;
}
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
orig_node->hna_buff_len = 0;
kfree(orig_node->hna_buff);
orig_node->hna_buff = NULL;
}
-static void hna_global_del(void *data)
+static void hna_global_del(void *data, void *arg)
{
kfree(data);
}
-void hna_global_free(void)
+void hna_global_free(struct bat_priv *bat_priv)
{
- if (!hna_global_hash)
+ if (!bat_priv->hna_global_hash)
return;
- hash_delete(hna_global_hash, hna_global_del);
- hna_global_hash = NULL;
+ hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL);
+ bat_priv->hna_global_hash = NULL;
}
-struct orig_node *transtable_search(uint8_t *addr)
+struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
{
struct hna_global_entry *hna_global_entry;
unsigned long flags;
- spin_lock_irqsave(&hna_global_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
hna_global_entry = (struct hna_global_entry *)
- hash_find(hna_global_hash, addr);
- spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ hash_find(bat_priv->hna_global_hash, addr);
+ spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
- if (hna_global_entry == NULL)
+ if (!hna_global_entry)
return NULL;
return hna_global_entry->orig_node;
diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h
index fa93e37d0951..10c4c5c319b6 100644
--- a/drivers/staging/batman-adv/translation-table.h
+++ b/drivers/staging/batman-adv/translation-table.h
@@ -24,22 +24,22 @@
#include "types.h"
-int hna_local_init(void);
-void hna_local_add(uint8_t *addr);
-void hna_local_remove(uint8_t *addr, char *message);
-int hna_local_fill_buffer(unsigned char *buff, int buff_len);
+int hna_local_init(struct bat_priv *bat_priv);
+void hna_local_add(struct net_device *soft_iface, uint8_t *addr);
+void hna_local_remove(struct bat_priv *bat_priv,
+ uint8_t *addr, char *message);
+int hna_local_fill_buffer(struct bat_priv *bat_priv,
+ unsigned char *buff, int buff_len);
int hna_local_seq_print_text(struct seq_file *seq, void *offset);
-void hna_local_free(void);
-int hna_global_init(void);
-void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
- int hna_buff_len);
+void hna_local_free(struct bat_priv *bat_priv);
+int hna_global_init(struct bat_priv *bat_priv);
+void hna_global_add_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node,
+ unsigned char *hna_buff, int hna_buff_len);
int hna_global_seq_print_text(struct seq_file *seq, void *offset);
-void hna_global_del_orig(struct orig_node *orig_node, char *message);
-void hna_global_free(void);
-struct orig_node *transtable_search(uint8_t *addr);
-
-extern spinlock_t hna_local_hash_lock;
-extern struct hashtable_t *hna_local_hash;
-extern atomic_t hna_local_changed;
+void hna_global_del_orig(struct bat_priv *bat_priv,
+ struct orig_node *orig_node, char *message);
+void hna_global_free(struct bat_priv *bat_priv);
+struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
index 9aa9d369c752..9d744d864028 100644
--- a/drivers/staging/batman-adv/types.h
+++ b/drivers/staging/batman-adv/types.h
@@ -36,31 +36,32 @@
struct batman_if {
struct list_head list;
int16_t if_num;
- char *dev;
char if_status;
char addr_str[ETH_STR_LEN];
struct net_device *net_dev;
atomic_t seqno;
+ atomic_t frag_seqno;
unsigned char *packet_buff;
int packet_len;
struct kobject *hardif_obj;
struct rcu_head rcu;
-
+ struct packet_type batman_adv_ptype;
+ struct net_device *soft_iface;
};
/**
- * orig_node - structure for orig_list maintaining nodes of mesh
- * @primary_addr: hosts primary interface address
- * @last_valid: when last packet from this node was received
- * @bcast_seqno_reset: time when the broadcast seqno window was reset
- * @batman_seqno_reset: time when the batman seqno window was reset
- * @flags: for now only VIS_SERVER flag
- * @last_real_seqno: last and best known squence number
- * @last_ttl: ttl of last received packet
- * @last_bcast_seqno: last broadcast sequence number received by this host
- *
- * @candidates: how many candidates are available
- * @selected: next bonding candidate
+ * orig_node - structure for orig_list maintaining nodes of mesh
+ * @primary_addr: hosts primary interface address
+ * @last_valid: when last packet from this node was received
+ * @bcast_seqno_reset: time when the broadcast seqno window was reset
+ * @batman_seqno_reset: time when the batman seqno window was reset
+ * @flags: for now only VIS_SERVER flag
+ * @last_real_seqno: last and best known squence number
+ * @last_ttl: ttl of last received packet
+ * @last_bcast_seqno: last broadcast sequence number received by this host
+ *
+ * @candidates: how many candidates are available
+ * @selected: next bonding candidate
*/
struct orig_node {
uint8_t orig[ETH_ALEN];
@@ -81,6 +82,8 @@ struct orig_node {
TYPE_OF_WORD bcast_bits[NUM_WORDS];
uint32_t last_bcast_seqno;
struct list_head neigh_list;
+ struct list_head frag_list;
+ unsigned long last_frag_packet;
struct {
uint8_t candidates;
struct neigh_node *selected;
@@ -88,8 +91,8 @@ struct orig_node {
};
/**
- * neigh_node
- * @last_valid: when last packet via this neighbor was received
+ * neigh_node
+ * @last_valid: when last packet via this neighbor was received
*/
struct neigh_node {
struct list_head list;
@@ -107,17 +110,42 @@ struct neigh_node {
};
struct bat_priv {
+ atomic_t mesh_state;
struct net_device_stats stats;
atomic_t aggregation_enabled;
atomic_t bonding_enabled;
+ atomic_t frag_enabled;
atomic_t vis_mode;
atomic_t orig_interval;
atomic_t log_level;
+ atomic_t bcast_seqno;
+ atomic_t bcast_queue_left;
+ atomic_t batman_queue_left;
char num_ifaces;
struct debug_log *debug_log;
struct batman_if *primary_if;
struct kobject *mesh_obj;
struct dentry *debug_dir;
+ struct hlist_head forw_bat_list;
+ struct hlist_head forw_bcast_list;
+ struct list_head vis_send_list;
+ struct hashtable_t *orig_hash;
+ struct hashtable_t *hna_local_hash;
+ struct hashtable_t *hna_global_hash;
+ struct hashtable_t *vis_hash;
+ spinlock_t orig_hash_lock;
+ spinlock_t forw_bat_list_lock;
+ spinlock_t forw_bcast_list_lock;
+ spinlock_t hna_lhash_lock;
+ spinlock_t hna_ghash_lock;
+ spinlock_t vis_hash_lock;
+ spinlock_t vis_list_lock;
+ int16_t num_local_hna;
+ atomic_t hna_local_changed;
+ struct delayed_work hna_work;
+ struct delayed_work orig_work;
+ struct delayed_work vis_work;
+ struct vis_info *my_vis_info;
};
struct socket_client {
@@ -147,15 +175,14 @@ struct hna_global_entry {
};
/**
- * forw_packet - structure for forw_list maintaining packets to be
- * send/forwarded
+ * forw_packet - structure for forw_list maintaining packets to be
+ * send/forwarded
*/
struct forw_packet {
struct hlist_node list;
unsigned long send_time;
uint8_t own;
struct sk_buff *skb;
- unsigned char *packet_buff;
uint16_t packet_len;
uint32_t direct_link_flags;
uint8_t num_packets;
@@ -181,4 +208,34 @@ struct debug_log {
wait_queue_head_t queue_wait;
};
+struct frag_packet_list_entry {
+ struct list_head list;
+ uint16_t seqno;
+ struct sk_buff *skb;
+};
+
+struct vis_info {
+ unsigned long first_seen;
+ struct list_head recv_list;
+ /* list of server-neighbors we received a vis-packet
+ * from. we should not reply to them. */
+ struct list_head send_list;
+ struct kref refcount;
+ struct bat_priv *bat_priv;
+ /* this packet might be part of the vis send queue. */
+ struct sk_buff *skb_packet;
+ /* vis_info may follow here*/
+} __attribute__((packed));
+
+struct vis_info_entry {
+ uint8_t src[ETH_ALEN];
+ uint8_t dest[ETH_ALEN];
+ uint8_t quality; /* quality = 0 means HNA */
+} __attribute__((packed));
+
+struct recvlist_node {
+ struct list_head list;
+ uint8_t mac[ETH_ALEN];
+};
+
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c
new file mode 100644
index 000000000000..0dac50d69c03
--- /dev/null
+++ b/drivers/staging/batman-adv/unicast.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Andreas Langer
+ *
+ * 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-1301, USA
+ *
+ */
+
+#include "main.h"
+#include "unicast.h"
+#include "send.h"
+#include "soft-interface.h"
+#include "hash.h"
+#include "translation-table.h"
+#include "routing.h"
+#include "hard-interface.h"
+
+
+struct sk_buff *merge_frag_packet(struct list_head *head,
+ struct frag_packet_list_entry *tfp,
+ struct sk_buff *skb)
+{
+ struct unicast_frag_packet *up =
+ (struct unicast_frag_packet *)skb->data;
+ struct sk_buff *tmp_skb;
+
+ /* set skb to the first part and tmp_skb to the second part */
+ if (up->flags & UNI_FRAG_HEAD) {
+ tmp_skb = tfp->skb;
+ } else {
+ tmp_skb = skb;
+ skb = tfp->skb;
+ }
+
+ skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
+ if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) {
+ /* free buffered skb, skb will be freed later */
+ kfree_skb(tfp->skb);
+ return NULL;
+ }
+
+ /* move free entry to end */
+ tfp->skb = NULL;
+ tfp->seqno = 0;
+ list_move_tail(&tfp->list, head);
+
+ memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len);
+ kfree_skb(tmp_skb);
+ return skb;
+}
+
+void create_frag_entry(struct list_head *head, struct sk_buff *skb)
+{
+ struct frag_packet_list_entry *tfp;
+ struct unicast_frag_packet *up =
+ (struct unicast_frag_packet *)skb->data;
+
+ /* free and oldest packets stand at the end */
+ tfp = list_entry((head)->prev, typeof(*tfp), list);
+ kfree_skb(tfp->skb);
+
+ tfp->seqno = ntohs(up->seqno);
+ tfp->skb = skb;
+ list_move(&tfp->list, head);
+ return;
+}
+
+int create_frag_buffer(struct list_head *head)
+{
+ int i;
+ struct frag_packet_list_entry *tfp;
+
+ for (i = 0; i < FRAG_BUFFER_SIZE; i++) {
+ tfp = kmalloc(sizeof(struct frag_packet_list_entry),
+ GFP_ATOMIC);
+ if (!tfp) {
+ frag_list_free(head);
+ return -ENOMEM;
+ }
+ tfp->skb = NULL;
+ tfp->seqno = 0;
+ INIT_LIST_HEAD(&tfp->list);
+ list_add(&tfp->list, head);
+ }
+
+ return 0;
+}
+
+struct frag_packet_list_entry *search_frag_packet(struct list_head *head,
+ struct unicast_frag_packet *up)
+{
+ struct frag_packet_list_entry *tfp;
+ struct unicast_frag_packet *tmp_up = NULL;
+ uint16_t search_seqno;
+
+ if (up->flags & UNI_FRAG_HEAD)
+ search_seqno = ntohs(up->seqno)+1;
+ else
+ search_seqno = ntohs(up->seqno)-1;
+
+ list_for_each_entry(tfp, head, list) {
+
+ if (!tfp->skb)
+ continue;
+
+ if (tfp->seqno == ntohs(up->seqno))
+ goto mov_tail;
+
+ tmp_up = (struct unicast_frag_packet *)tfp->skb->data;
+
+ if (tfp->seqno == search_seqno) {
+
+ if ((tmp_up->flags & UNI_FRAG_HEAD) !=
+ (up->flags & UNI_FRAG_HEAD))
+ return tfp;
+ else
+ goto mov_tail;
+ }
+ }
+ return NULL;
+
+mov_tail:
+ list_move_tail(&tfp->list, head);
+ return NULL;
+}
+
+void frag_list_free(struct list_head *head)
+{
+ struct frag_packet_list_entry *pf, *tmp_pf;
+
+ if (!list_empty(head)) {
+
+ list_for_each_entry_safe(pf, tmp_pf, head, list) {
+ kfree_skb(pf->skb);
+ list_del(&pf->list);
+ kfree(pf);
+ }
+ }
+ return;
+}
+
+static int unicast_send_frag_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
+ struct batman_if *batman_if, uint8_t dstaddr[],
+ struct orig_node *orig_node)
+{
+ struct unicast_frag_packet *ucast_frag1, *ucast_frag2;
+ int hdr_len = sizeof(struct unicast_frag_packet);
+ struct sk_buff *frag_skb;
+ int data_len = skb->len;
+
+ if (!bat_priv->primary_if)
+ goto dropped;
+
+ frag_skb = dev_alloc_skb(data_len - (data_len / 2) + hdr_len);
+ skb_split(skb, frag_skb, data_len / 2);
+
+ if (my_skb_head_push(frag_skb, hdr_len) < 0 ||
+ my_skb_head_push(skb, hdr_len) < 0)
+ goto drop_frag;
+
+ ucast_frag1 = (struct unicast_frag_packet *)skb->data;
+ ucast_frag2 = (struct unicast_frag_packet *)frag_skb->data;
+
+ ucast_frag1->version = COMPAT_VERSION;
+ ucast_frag1->packet_type = BAT_UNICAST_FRAG;
+ ucast_frag1->ttl = TTL;
+ memcpy(ucast_frag1->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(ucast_frag1->dest, orig_node->orig, ETH_ALEN);
+
+ memcpy(ucast_frag2, ucast_frag1, sizeof(struct unicast_frag_packet));
+
+ ucast_frag1->flags |= UNI_FRAG_HEAD;
+ ucast_frag2->flags &= ~UNI_FRAG_HEAD;
+
+ ucast_frag1->seqno = htons((uint16_t)atomic_inc_return(
+ &batman_if->frag_seqno));
+
+ ucast_frag2->seqno = htons((uint16_t)atomic_inc_return(
+ &batman_if->frag_seqno));
+
+ send_skb_packet(skb, batman_if, dstaddr);
+ send_skb_packet(frag_skb, batman_if, dstaddr);
+ return 0;
+
+drop_frag:
+ kfree_skb(frag_skb);
+dropped:
+ kfree_skb(skb);
+ return 1;
+}
+
+int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
+{
+ struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+ struct unicast_packet *unicast_packet;
+ struct orig_node *orig_node;
+ struct batman_if *batman_if;
+ struct neigh_node *router;
+ int data_len = skb->len;
+ uint8_t dstaddr[6];
+ unsigned long flags;
+
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+
+ /* get routing information */
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ ethhdr->h_dest));
+
+ /* check for hna host */
+ if (!orig_node)
+ orig_node = transtable_search(bat_priv, ethhdr->h_dest);
+
+ router = find_router(orig_node, NULL);
+
+ if (!router)
+ goto unlock;
+
+ /* don't lock while sending the packets ... we therefore
+ * copy the required data before sending */
+
+ batman_if = router->if_incoming;
+ memcpy(dstaddr, router->addr, ETH_ALEN);
+
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
+
+ if (batman_if->if_status != IF_ACTIVE)
+ goto dropped;
+
+ if (atomic_read(&bat_priv->frag_enabled) &&
+ data_len + sizeof(struct unicast_packet) > batman_if->net_dev->mtu)
+ return unicast_send_frag_skb(skb, bat_priv, batman_if,
+ dstaddr, orig_node);
+
+ if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0)
+ goto dropped;
+
+ unicast_packet = (struct unicast_packet *)skb->data;
+
+ unicast_packet->version = COMPAT_VERSION;
+ /* batman packet type: unicast */
+ unicast_packet->packet_type = BAT_UNICAST;
+ /* set unicast ttl */
+ unicast_packet->ttl = TTL;
+ /* copy the destination for faster routing */
+ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
+
+ send_skb_packet(skb, batman_if, dstaddr);
+ return 0;
+
+unlock:
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
+dropped:
+ kfree_skb(skb);
+ return 1;
+}
diff --git a/drivers/staging/batman-adv/unicast.h b/drivers/staging/batman-adv/unicast.h
new file mode 100644
index 000000000000..797369771900
--- /dev/null
+++ b/drivers/staging/batman-adv/unicast.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 B.A.T.M.A.N. contributors:
+ *
+ * Andreas Langer
+ *
+ * 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-1301, USA
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_UNICAST_H_
+#define _NET_BATMAN_ADV_UNICAST_H_
+
+#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */
+#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
+
+struct sk_buff *merge_frag_packet(struct list_head *head,
+ struct frag_packet_list_entry *tfp,
+ struct sk_buff *skb);
+
+void create_frag_entry(struct list_head *head, struct sk_buff *skb);
+int create_frag_buffer(struct list_head *head);
+struct frag_packet_list_entry *search_frag_packet(struct list_head *head,
+ struct unicast_frag_packet *up);
+void frag_list_free(struct list_head *head);
+int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
+
+#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
index 4b6a5045f057..b2cec8e28969 100644
--- a/drivers/staging/batman-adv/vis.c
+++ b/drivers/staging/batman-adv/vis.c
@@ -27,6 +27,8 @@
#include "hard-interface.h"
#include "hash.h"
+#define MAX_VIS_PACKET_SIZE 1000
+
/* Returns the smallest signed integer in two's complement with the sizeof x */
#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
@@ -43,38 +45,37 @@
_dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)
-static struct hashtable_t *vis_hash;
-static DEFINE_SPINLOCK(vis_hash_lock);
-static DEFINE_SPINLOCK(recv_list_lock);
-static struct vis_info *my_vis_info;
-static struct list_head send_list; /* always locked with vis_hash_lock */
-
-static void start_vis_timer(void);
+static void start_vis_timer(struct bat_priv *bat_priv);
/* free the info */
static void free_info(struct kref *ref)
{
struct vis_info *info = container_of(ref, struct vis_info, refcount);
+ struct bat_priv *bat_priv = info->bat_priv;
struct recvlist_node *entry, *tmp;
unsigned long flags;
list_del_init(&info->send_list);
- spin_lock_irqsave(&recv_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
list_del(&entry->list);
kfree(entry);
}
- spin_unlock_irqrestore(&recv_list_lock, flags);
- kfree(info);
+
+ spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
+ kfree_skb(info->skb_packet);
}
/* Compare two vis packets, used by the hashing algorithm */
static int vis_info_cmp(void *data1, void *data2)
{
struct vis_info *d1, *d2;
+ struct vis_packet *p1, *p2;
d1 = data1;
d2 = data2;
- return compare_orig(d1->packet.vis_orig, d2->packet.vis_orig);
+ p1 = (struct vis_packet *)d1->skb_packet->data;
+ p2 = (struct vis_packet *)d2->skb_packet->data;
+ return compare_orig(p1->vis_orig, p2->vis_orig);
}
/* hash function to choose an entry in a hash table of given size */
@@ -82,11 +83,13 @@ static int vis_info_cmp(void *data1, void *data2)
static int vis_info_choose(void *data, int size)
{
struct vis_info *vis_info = data;
+ struct vis_packet *packet;
unsigned char *key;
uint32_t hash = 0;
size_t i;
- key = vis_info->packet.vis_orig;
+ packet = (struct vis_packet *)vis_info->skb_packet->data;
+ key = packet->vis_orig;
for (i = 0; i < ETH_ALEN; i++) {
hash += key[i];
hash += (hash << 10);
@@ -179,6 +182,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
HASHIT(hashit);
HASHIT(hashit_count);
struct vis_info *info;
+ struct vis_packet *packet;
struct vis_info_entry *entries;
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
@@ -198,25 +202,25 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buf_size = 1;
/* Estimate length */
- spin_lock_irqsave(&vis_hash_lock, flags);
- while (hash_iterate(vis_hash, &hashit_count)) {
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
+ while (hash_iterate(bat_priv->vis_hash, &hashit_count)) {
info = hashit_count.bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
+ ((char *)packet + sizeof(struct vis_packet));
- for (i = 0; i < info->packet.entries; i++) {
+ for (i = 0; i < packet->entries; i++) {
if (entries[i].quality == 0)
continue;
vis_data_insert_interface(entries[i].src, &vis_if_list,
- compare_orig(entries[i].src,
- info->packet.vis_orig));
+ compare_orig(entries[i].src, packet->vis_orig));
}
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
- buf_size += 18 + 26 * info->packet.entries;
+ buf_size += 18 + 26 * packet->entries;
/* add primary/secondary records */
- if (compare_orig(entry->addr, info->packet.vis_orig))
+ if (compare_orig(entry->addr, packet->vis_orig))
buf_size +=
vis_data_count_prim_sec(&vis_if_list);
@@ -231,23 +235,23 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
buff_pos = 0;
- while (hash_iterate(vis_hash, &hashit)) {
+ while (hash_iterate(bat_priv->vis_hash, &hashit)) {
info = hashit.bucket->data;
+ packet = (struct vis_packet *)info->skb_packet->data;
entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
+ ((char *)packet + sizeof(struct vis_packet));
- for (i = 0; i < info->packet.entries; i++) {
+ for (i = 0; i < packet->entries; i++) {
if (entries[i].quality == 0)
continue;
vis_data_insert_interface(entries[i].src, &vis_if_list,
- compare_orig(entries[i].src,
- info->packet.vis_orig));
+ compare_orig(entries[i].src, packet->vis_orig));
}
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
@@ -255,14 +259,14 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
buff_pos += sprintf(buff + buff_pos, "%s,",
tmp_addr_str);
- for (i = 0; i < info->packet.entries; i++)
+ for (i = 0; i < packet->entries; i++)
buff_pos += vis_data_read_entry(buff + buff_pos,
&entries[i],
entry->addr,
entry->primary);
/* add primary/secondary records */
- if (compare_orig(entry->addr, info->packet.vis_orig))
+ if (compare_orig(entry->addr, packet->vis_orig))
buff_pos +=
vis_data_read_prim_sec(buff + buff_pos,
&vis_if_list);
@@ -276,7 +280,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
}
}
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
seq_printf(seq, "%s", buff);
kfree(buff);
@@ -286,11 +290,11 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
/* add the info packet to the send list, if it was not
* already linked in. */
-static void send_list_add(struct vis_info *info)
+static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info)
{
if (list_empty(&info->send_list)) {
kref_get(&info->refcount);
- list_add_tail(&info->send_list, &send_list);
+ list_add_tail(&info->send_list, &bat_priv->vis_send_list);
}
}
@@ -305,7 +309,8 @@ static void send_list_del(struct vis_info *info)
}
/* tries to add one entry to the receive list. */
-static void recv_list_add(struct list_head *recv_list, char *mac)
+static void recv_list_add(struct bat_priv *bat_priv,
+ struct list_head *recv_list, char *mac)
{
struct recvlist_node *entry;
unsigned long flags;
@@ -315,52 +320,65 @@ static void recv_list_add(struct list_head *recv_list, char *mac)
return;
memcpy(entry->mac, mac, ETH_ALEN);
- spin_lock_irqsave(&recv_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
list_add_tail(&entry->list, recv_list);
- spin_unlock_irqrestore(&recv_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
}
/* returns 1 if this mac is in the recv_list */
-static int recv_list_is_in(struct list_head *recv_list, char *mac)
+static int recv_list_is_in(struct bat_priv *bat_priv,
+ struct list_head *recv_list, char *mac)
{
struct recvlist_node *entry;
unsigned long flags;
- spin_lock_irqsave(&recv_list_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
list_for_each_entry(entry, recv_list, list) {
if (memcmp(entry->mac, mac, ETH_ALEN) == 0) {
- spin_unlock_irqrestore(&recv_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_list_lock,
+ flags);
return 1;
}
}
- spin_unlock_irqrestore(&recv_list_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
return 0;
}
/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
* broken.. ). vis hash must be locked outside. is_new is set when the packet
* is newer than old entries in the hash. */
-static struct vis_info *add_packet(struct vis_packet *vis_packet,
+static struct vis_info *add_packet(struct bat_priv *bat_priv,
+ struct vis_packet *vis_packet,
int vis_info_len, int *is_new,
int make_broadcast)
{
struct vis_info *info, *old_info;
+ struct vis_packet *search_packet, *old_packet;
struct vis_info search_elem;
+ struct vis_packet *packet;
*is_new = 0;
/* sanity check */
- if (vis_hash == NULL)
+ if (!bat_priv->vis_hash)
return NULL;
/* see if the packet is already in vis_hash */
- memcpy(search_elem.packet.vis_orig, vis_packet->vis_orig, ETH_ALEN);
- old_info = hash_find(vis_hash, &search_elem);
+ search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
+ if (!search_elem.skb_packet)
+ return NULL;
+ search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
+ sizeof(struct vis_packet));
+
+ memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
+ old_info = hash_find(bat_priv->vis_hash, &search_elem);
+ kfree_skb(search_elem.skb_packet);
if (old_info != NULL) {
+ old_packet = (struct vis_packet *)old_info->skb_packet->data;
if (!seq_after(ntohl(vis_packet->seqno),
- ntohl(old_info->packet.seqno))) {
- if (old_info->packet.seqno == vis_packet->seqno) {
- recv_list_add(&old_info->recv_list,
+ ntohl(old_packet->seqno))) {
+ if (old_packet->seqno == vis_packet->seqno) {
+ recv_list_add(bat_priv, &old_info->recv_list,
vis_packet->sender_orig);
return old_info;
} else {
@@ -369,38 +387,48 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
}
}
/* remove old entry */
- hash_remove(vis_hash, old_info);
+ hash_remove(bat_priv->vis_hash, old_info);
send_list_del(old_info);
kref_put(&old_info->refcount, free_info);
}
- info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
- if (info == NULL)
+ info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
+ if (!info)
return NULL;
+ info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
+ vis_info_len + sizeof(struct ethhdr));
+ if (!info->skb_packet) {
+ kfree(info);
+ return NULL;
+ }
+ skb_reserve(info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(info->skb_packet,
+ sizeof(struct vis_packet) +
+ vis_info_len);
+
kref_init(&info->refcount);
INIT_LIST_HEAD(&info->send_list);
INIT_LIST_HEAD(&info->recv_list);
info->first_seen = jiffies;
- memcpy(&info->packet, vis_packet,
- sizeof(struct vis_packet) + vis_info_len);
+ info->bat_priv = bat_priv;
+ memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
/* initialize and add new packet. */
*is_new = 1;
/* Make it a broadcast packet, if required */
if (make_broadcast)
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
/* repair if entries is longer than packet. */
- if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
- info->packet.entries = vis_info_len /
- sizeof(struct vis_info_entry);
+ if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len)
+ packet->entries = vis_info_len / sizeof(struct vis_info_entry);
- recv_list_add(&info->recv_list, info->packet.sender_orig);
+ recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
/* try to add it */
- if (hash_add(vis_hash, info) < 0) {
+ if (hash_add(bat_priv->vis_hash, info) < 0) {
/* did not work (for some reason) */
kref_put(&old_info->refcount, free_info);
info = NULL;
@@ -421,17 +449,18 @@ void receive_server_sync_packet(struct bat_priv *bat_priv,
make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
- spin_lock_irqsave(&vis_hash_lock, flags);
- info = add_packet(vis_packet, vis_info_len, &is_new, make_broadcast);
- if (info == NULL)
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
+ info = add_packet(bat_priv, vis_packet, vis_info_len,
+ &is_new, make_broadcast);
+ if (!info)
goto end;
/* only if we are server ourselves and packet is newer than the one in
* hash.*/
if (vis_server == VIS_TYPE_SERVER_SYNC && is_new)
- send_list_add(info);
+ send_list_add(bat_priv, info);
end:
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
}
/* handle an incoming client update packet and schedule forward if needed. */
@@ -440,6 +469,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
int vis_info_len)
{
struct vis_info *info;
+ struct vis_packet *packet;
int is_new;
unsigned long flags;
int vis_server = atomic_read(&bat_priv->vis_mode);
@@ -454,45 +484,51 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
is_my_mac(vis_packet->target_orig))
are_target = 1;
- spin_lock_irqsave(&vis_hash_lock, flags);
- info = add_packet(vis_packet, vis_info_len, &is_new, are_target);
- if (info == NULL)
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
+ info = add_packet(bat_priv, vis_packet, vis_info_len,
+ &is_new, are_target);
+
+ if (!info)
goto end;
/* note that outdated packets will be dropped at this point. */
+ packet = (struct vis_packet *)info->skb_packet->data;
/* send only if we're the target server or ... */
if (are_target && is_new) {
- info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
- send_list_add(info);
+ packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
+ send_list_add(bat_priv, info);
/* ... we're not the recipient (and thus need to forward). */
- } else if (!is_my_mac(info->packet.target_orig)) {
- send_list_add(info);
+ } else if (!is_my_mac(packet->target_orig)) {
+ send_list_add(bat_priv, info);
}
+
end:
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
}
/* Walk the originators and find the VIS server with the best tq. Set the packet
* address to its address and return the best_tq.
*
* Must be called with the originator hash locked */
-static int find_best_vis_server(struct vis_info *info)
+static int find_best_vis_server(struct bat_priv *bat_priv,
+ struct vis_info *info)
{
HASHIT(hashit);
struct orig_node *orig_node;
+ struct vis_packet *packet;
int best_tq = -1;
- while (hash_iterate(orig_hash, &hashit)) {
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
- if ((orig_node != NULL) &&
- (orig_node->router != NULL) &&
+ if ((orig_node) && (orig_node->router) &&
(orig_node->flags & VIS_SERVER) &&
(orig_node->router->tq_avg > best_tq)) {
best_tq = orig_node->router->tq_avg;
- memcpy(info->packet.target_orig, orig_node->orig,
- ETH_ALEN);
+ memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
}
}
return best_tq;
@@ -501,8 +537,11 @@ static int find_best_vis_server(struct vis_info *info)
/* Return true if the vis packet is full. */
static bool vis_packet_full(struct vis_info *info)
{
- if (info->packet.entries + 1 >
- (1000 - sizeof(struct vis_info)) / sizeof(struct vis_info_entry))
+ struct vis_packet *packet;
+ packet = (struct vis_packet *)info->skb_packet->data;
+
+ if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
+ < packet->entries + 1)
return true;
return false;
}
@@ -514,109 +553,128 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
HASHIT(hashit_local);
HASHIT(hashit_global);
struct orig_node *orig_node;
- struct vis_info *info = (struct vis_info *)my_vis_info;
- struct vis_info_entry *entry, *entry_array;
+ struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
+ struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
+ struct vis_info_entry *entry;
struct hna_local_entry *hna_local_entry;
int best_tq = -1;
unsigned long flags;
info->first_seen = jiffies;
- info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
+ packet->vis_type = atomic_read(&bat_priv->vis_mode);
+
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
+ packet->ttl = TTL;
+ packet->seqno = htonl(ntohl(packet->seqno) + 1);
+ packet->entries = 0;
+ skb_trim(info->skb_packet, sizeof(struct vis_packet));
- spin_lock_irqsave(&orig_hash_lock, flags);
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
- info->packet.ttl = TTL;
- info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
- info->packet.entries = 0;
+ if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
+ best_tq = find_best_vis_server(bat_priv, info);
- if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
- best_tq = find_best_vis_server(info);
if (best_tq < 0) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
+ flags);
return -1;
}
}
- entry_array = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
-
- while (hash_iterate(orig_hash, &hashit_global)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit_global)) {
orig_node = hashit_global.bucket->data;
- if (orig_node->router != NULL
- && compare_orig(orig_node->router->addr,
- orig_node->orig)
- && (orig_node->router->if_incoming->if_status ==
- IF_ACTIVE)
- && orig_node->router->tq_avg > 0) {
-
- /* fill one entry into buffer. */
- entry = &entry_array[info->packet.entries];
- memcpy(entry->src,
- orig_node->router->if_incoming->net_dev->dev_addr,
- ETH_ALEN);
- memcpy(entry->dest, orig_node->orig, ETH_ALEN);
- entry->quality = orig_node->router->tq_avg;
- info->packet.entries++;
-
- if (vis_packet_full(info)) {
- spin_unlock_irqrestore(&orig_hash_lock, flags);
- return 0;
- }
+
+ if (!orig_node->router)
+ continue;
+
+ if (!compare_orig(orig_node->router->addr, orig_node->orig))
+ continue;
+
+ if (orig_node->router->if_incoming->if_status != IF_ACTIVE)
+ continue;
+
+ if (orig_node->router->tq_avg < 1)
+ continue;
+
+ /* fill one entry into buffer. */
+ entry = (struct vis_info_entry *)
+ skb_put(info->skb_packet, sizeof(*entry));
+ memcpy(entry->src,
+ orig_node->router->if_incoming->net_dev->dev_addr,
+ ETH_ALEN);
+ memcpy(entry->dest, orig_node->orig, ETH_ALEN);
+ entry->quality = orig_node->router->tq_avg;
+ packet->entries++;
+
+ if (vis_packet_full(info)) {
+ spin_unlock_irqrestore(
+ &bat_priv->orig_hash_lock, flags);
+ return 0;
}
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
- spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (hash_iterate(hna_local_hash, &hashit_local)) {
+ spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
+ while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) {
hna_local_entry = hashit_local.bucket->data;
- entry = &entry_array[info->packet.entries];
+ entry = (struct vis_info_entry *)skb_put(info->skb_packet,
+ sizeof(*entry));
memset(entry->src, 0, ETH_ALEN);
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
entry->quality = 0; /* 0 means HNA */
- info->packet.entries++;
+ packet->entries++;
if (vis_packet_full(info)) {
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock,
+ flags);
return 0;
}
}
- spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+
+ spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
return 0;
}
/* free old vis packets. Must be called with this vis_hash_lock
* held */
-static void purge_vis_packets(void)
+static void purge_vis_packets(struct bat_priv *bat_priv)
{
HASHIT(hashit);
struct vis_info *info;
- while (hash_iterate(vis_hash, &hashit)) {
+ while (hash_iterate(bat_priv->vis_hash, &hashit)) {
info = hashit.bucket->data;
- if (info == my_vis_info) /* never purge own data. */
+
+ /* never purge own data. */
+ if (info == bat_priv->my_vis_info)
continue;
+
if (time_after(jiffies,
info->first_seen + VIS_TIMEOUT * HZ)) {
- hash_remove_bucket(vis_hash, &hashit);
+ hash_remove_bucket(bat_priv->vis_hash, &hashit);
send_list_del(info);
kref_put(&info->refcount, free_info);
}
}
}
-static void broadcast_vis_packet(struct vis_info *info, int packet_length)
+static void broadcast_vis_packet(struct bat_priv *bat_priv,
+ struct vis_info *info)
{
HASHIT(hashit);
struct orig_node *orig_node;
+ struct vis_packet *packet;
+ struct sk_buff *skb;
unsigned long flags;
struct batman_if *batman_if;
uint8_t dstaddr[ETH_ALEN];
- spin_lock_irqsave(&orig_hash_lock, flags);
+
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ packet = (struct vis_packet *)info->skb_packet->data;
/* send to all routers in range. */
- while (hash_iterate(orig_hash, &hashit)) {
+ while (hash_iterate(bat_priv->orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
/* if it's a vis server and reachable, send it. */
@@ -626,34 +684,40 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
continue;
/* don't send it if we already received the packet from
* this node. */
- if (recv_list_is_in(&info->recv_list, orig_node->orig))
+ if (recv_list_is_in(bat_priv, &info->recv_list,
+ orig_node->orig))
continue;
- memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN);
+ memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
- send_raw_packet((unsigned char *)&info->packet,
- packet_length, batman_if, dstaddr);
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
- spin_lock_irqsave(&orig_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
}
- spin_unlock_irqrestore(&orig_hash_lock, flags);
- memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
+
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
}
-static void unicast_vis_packet(struct vis_info *info, int packet_length)
+static void unicast_vis_packet(struct bat_priv *bat_priv,
+ struct vis_info *info)
{
struct orig_node *orig_node;
+ struct sk_buff *skb;
+ struct vis_packet *packet;
unsigned long flags;
struct batman_if *batman_if;
uint8_t dstaddr[ETH_ALEN];
- spin_lock_irqsave(&orig_hash_lock, flags);
- orig_node = ((struct orig_node *)
- hash_find(orig_hash, info->packet.target_orig));
+ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
+ packet = (struct vis_packet *)info->skb_packet->data;
+ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
+ packet->target_orig));
if ((!orig_node) || (!orig_node->router))
goto out;
@@ -662,129 +726,148 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
* copy the required data before sending */
batman_if = orig_node->router->if_incoming;
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
+
+ skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+ if (skb)
+ send_skb_packet(skb, batman_if, dstaddr);
- send_raw_packet((unsigned char *)&info->packet,
- packet_length, batman_if, dstaddr);
return;
out:
- spin_unlock_irqrestore(&orig_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
}
/* only send one vis packet. called from send_vis_packets() */
-static void send_vis_packet(struct vis_info *info)
+static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
{
- int packet_length;
+ struct vis_packet *packet;
- if (info->packet.ttl < 2) {
- pr_warning("Error - can't send vis packet: ttl exceeded\n");
+ packet = (struct vis_packet *)info->skb_packet->data;
+ if (packet->ttl < 2) {
+ pr_debug("Error - can't send vis packet: ttl exceeded\n");
return;
}
- memcpy(info->packet.sender_orig, main_if_addr, ETH_ALEN);
- info->packet.ttl--;
-
- packet_length = sizeof(struct vis_packet) +
- info->packet.entries * sizeof(struct vis_info_entry);
+ memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
+ ETH_ALEN);
+ packet->ttl--;
- if (is_bcast(info->packet.target_orig))
- broadcast_vis_packet(info, packet_length);
+ if (is_bcast(packet->target_orig))
+ broadcast_vis_packet(bat_priv, info);
else
- unicast_vis_packet(info, packet_length);
- info->packet.ttl++; /* restore TTL */
+ unicast_vis_packet(bat_priv, info);
+ packet->ttl++; /* restore TTL */
}
/* called from timer; send (and maybe generate) vis packet. */
static void send_vis_packets(struct work_struct *work)
{
+ struct delayed_work *delayed_work =
+ container_of(work, struct delayed_work, work);
+ struct bat_priv *bat_priv =
+ container_of(delayed_work, struct bat_priv, vis_work);
struct vis_info *info, *temp;
unsigned long flags;
- /* FIXME: each batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
- spin_lock_irqsave(&vis_hash_lock, flags);
-
- purge_vis_packets();
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
+ purge_vis_packets(bat_priv);
if (generate_vis_packet(bat_priv) == 0) {
/* schedule if generation was successful */
- send_list_add(my_vis_info);
+ send_list_add(bat_priv, bat_priv->my_vis_info);
}
- list_for_each_entry_safe(info, temp, &send_list, send_list) {
+ list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list,
+ send_list) {
kref_get(&info->refcount);
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
- send_vis_packet(info);
+ if (bat_priv->primary_if)
+ send_vis_packet(bat_priv, info);
- spin_lock_irqsave(&vis_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
send_list_del(info);
kref_put(&info->refcount, free_info);
}
- spin_unlock_irqrestore(&vis_hash_lock, flags);
- start_vis_timer();
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
+ start_vis_timer(bat_priv);
}
-static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
/* init the vis server. this may only be called when if_list is already
* initialized (e.g. bat0 is initialized, interfaces have been added) */
-int vis_init(void)
+int vis_init(struct bat_priv *bat_priv)
{
+ struct vis_packet *packet;
unsigned long flags;
- if (vis_hash)
+
+ if (bat_priv->vis_hash)
return 1;
- spin_lock_irqsave(&vis_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
- vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
- if (!vis_hash) {
+ bat_priv->vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
+ if (!bat_priv->vis_hash) {
pr_err("Can't initialize vis_hash\n");
goto err;
}
- my_vis_info = kmalloc(1000, GFP_ATOMIC);
- if (!my_vis_info) {
+ bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
+ if (!bat_priv->my_vis_info) {
pr_err("Can't initialize vis packet\n");
goto err;
}
+ bat_priv->my_vis_info->skb_packet = dev_alloc_skb(
+ sizeof(struct vis_packet) +
+ MAX_VIS_PACKET_SIZE +
+ sizeof(struct ethhdr));
+ if (!bat_priv->my_vis_info->skb_packet)
+ goto free_info;
+
+ skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
+ packet = (struct vis_packet *)skb_put(
+ bat_priv->my_vis_info->skb_packet,
+ sizeof(struct vis_packet));
+
/* prefill the vis info */
- my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
- INIT_LIST_HEAD(&my_vis_info->recv_list);
- INIT_LIST_HEAD(&my_vis_info->send_list);
- kref_init(&my_vis_info->refcount);
- my_vis_info->packet.version = COMPAT_VERSION;
- my_vis_info->packet.packet_type = BAT_VIS;
- my_vis_info->packet.ttl = TTL;
- my_vis_info->packet.seqno = 0;
- my_vis_info->packet.entries = 0;
-
- INIT_LIST_HEAD(&send_list);
-
- memcpy(my_vis_info->packet.vis_orig, main_if_addr, ETH_ALEN);
- memcpy(my_vis_info->packet.sender_orig, main_if_addr, ETH_ALEN);
-
- if (hash_add(vis_hash, my_vis_info) < 0) {
+ bat_priv->my_vis_info->first_seen = jiffies -
+ msecs_to_jiffies(VIS_INTERVAL);
+ INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list);
+ INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list);
+ kref_init(&bat_priv->my_vis_info->refcount);
+ bat_priv->my_vis_info->bat_priv = bat_priv;
+ packet->version = COMPAT_VERSION;
+ packet->packet_type = BAT_VIS;
+ packet->ttl = TTL;
+ packet->seqno = 0;
+ packet->entries = 0;
+
+ INIT_LIST_HEAD(&bat_priv->vis_send_list);
+
+ if (hash_add(bat_priv->vis_hash, bat_priv->my_vis_info) < 0) {
pr_err("Can't add own vis packet into hash\n");
/* not in hash, need to remove it manually. */
- kref_put(&my_vis_info->refcount, free_info);
+ kref_put(&bat_priv->my_vis_info->refcount, free_info);
goto err;
}
- spin_unlock_irqrestore(&vis_hash_lock, flags);
- start_vis_timer();
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
+ start_vis_timer(bat_priv);
return 1;
+free_info:
+ kfree(bat_priv->my_vis_info);
+ bat_priv->my_vis_info = NULL;
err:
- spin_unlock_irqrestore(&vis_hash_lock, flags);
- vis_quit();
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
+ vis_quit(bat_priv);
return 0;
}
/* Decrease the reference count on a hash item info */
-static void free_info_ref(void *data)
+static void free_info_ref(void *data, void *arg)
{
struct vis_info *info = data;
@@ -793,25 +876,26 @@ static void free_info_ref(void *data)
}
/* shutdown vis-server */
-void vis_quit(void)
+void vis_quit(struct bat_priv *bat_priv)
{
unsigned long flags;
- if (!vis_hash)
+ if (!bat_priv->vis_hash)
return;
- cancel_delayed_work_sync(&vis_timer_wq);
+ cancel_delayed_work_sync(&bat_priv->vis_work);
- spin_lock_irqsave(&vis_hash_lock, flags);
+ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
/* properly remove, kill timers ... */
- hash_delete(vis_hash, free_info_ref);
- vis_hash = NULL;
- my_vis_info = NULL;
- spin_unlock_irqrestore(&vis_hash_lock, flags);
+ hash_delete(bat_priv->vis_hash, free_info_ref, NULL);
+ bat_priv->vis_hash = NULL;
+ bat_priv->my_vis_info = NULL;
+ spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
}
/* schedule packets for (re)transmission */
-static void start_vis_timer(void)
+static void start_vis_timer(struct bat_priv *bat_priv)
{
- queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
- (VIS_INTERVAL * HZ) / 1000);
+ INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets);
+ queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work,
+ msecs_to_jiffies(VIS_INTERVAL));
}
diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h
index bb13bf1a3f49..2c3b33089a9b 100644
--- a/drivers/staging/batman-adv/vis.h
+++ b/drivers/staging/batman-adv/vis.h
@@ -24,29 +24,6 @@
#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */
-struct vis_info {
- unsigned long first_seen;
- struct list_head recv_list;
- /* list of server-neighbors we received a vis-packet
- * from. we should not reply to them. */
- struct list_head send_list;
- struct kref refcount;
- /* this packet might be part of the vis send queue. */
- struct vis_packet packet;
- /* vis_info may follow here*/
-} __attribute__((packed));
-
-struct vis_info_entry {
- uint8_t src[ETH_ALEN];
- uint8_t dest[ETH_ALEN];
- uint8_t quality; /* quality = 0 means HNA */
-} __attribute__((packed));
-
-struct recvlist_node {
- struct list_head list;
- uint8_t mac[ETH_ALEN];
-};
-
int vis_seq_print_text(struct seq_file *seq, void *offset);
void receive_server_sync_packet(struct bat_priv *bat_priv,
struct vis_packet *vis_packet,
@@ -54,7 +31,7 @@ void receive_server_sync_packet(struct bat_priv *bat_priv,
void receive_client_update_packet(struct bat_priv *bat_priv,
struct vis_packet *vis_packet,
int vis_info_len);
-int vis_init(void);
-void vis_quit(void);
+int vis_init(struct bat_priv *bat_priv);
+void vis_quit(struct bat_priv *bat_priv);
#endif /* _NET_BATMAN_ADV_VIS_H_ */
diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h
new file mode 100644
index 000000000000..a7c0ce9e7fa7
--- /dev/null
+++ b/drivers/staging/bcm/Adapter.h
@@ -0,0 +1,714 @@
+/***********************************
+* Adapter.h
+************************************/
+#ifndef __ADAPTER_H__
+#define __ADAPTER_H__
+
+#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256
+#include "Debug.h"
+
+typedef struct _LIST_ENTRY{
+ struct _LIST_ENTRY *next;
+ struct _LIST_ENTRY *prev;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+typedef struct _BCM_LIST_ENTRY {
+
+ LIST_ENTRY Link;
+
+} BCM_LIST_ENTRY, *PBCM_LIST_ENTRY;
+
+typedef enum _RCB_STATUS
+{
+ DRIVER_PROCESSED=1,
+ APPLICATION_PROCESSED
+} RCB_STATUS, *PRCB_STATUS;
+
+#define fFILLED 1
+#define fEMPTY 0
+
+struct _BCM_CB
+{
+ // The network packet that this RCB is receiving
+ PVOID pv_packet;
+ // Describes the length of the packet .
+ UINT ui_packet_length;
+ // Pointer to the first buffer in the packet (only one buffer for Rx)
+ PUCHAR buffer;
+ atomic_t status;
+ UINT filled;
+} __attribute__((packed));
+typedef struct _BCM_CB BCM_CB,*PBCM_CB;
+
+typedef BCM_CB BCM_RCB, *PBCM_RCB;
+typedef BCM_CB BCM_TCB, *PBCM_TCB;
+
+/* This is to be stored in the "pvOsDepData" of ADAPTER */
+typedef struct LINUX_DEP_DATA
+{
+ struct net_device *virtualdev; /* Our Interface (veth0) */
+ struct net_device *actualdev; /* True Interface (eth0) */
+ struct net_device_stats netstats; /* Net statistics */
+ struct fasync_struct *async_queue; /* For asynchronus notification */
+
+} LINUX_DEP_DATA, *PLINUX_DEP_DATA;
+
+
+struct _LEADER
+{
+ USHORT Vcid;
+ USHORT PLength;
+ UCHAR Status;
+ UCHAR Unused[3];
+}__attribute__((packed));
+typedef struct _LEADER LEADER,*PLEADER;
+
+struct _PACKETTOSEND
+{
+ LEADER Leader;
+ UCHAR ucPayload;
+}__attribute__((packed));
+typedef struct _PACKETTOSEND PACKETTOSEND, *PPACKETTOSEND;
+
+
+struct _CONTROL_PACKET
+{
+ PVOID ControlBuff;
+ UINT ControlBuffLen;
+ struct _CONTROL_PACKET* next;
+}__attribute__((packed));
+typedef struct _CONTROL_PACKET CONTROL_PACKET,*PCONTROL_PACKET;
+
+
+struct link_request
+{
+ LEADER Leader;
+ UCHAR szData[4];
+}__attribute__((packed));
+typedef struct link_request LINK_REQUEST, *PLINK_REQUEST;
+
+
+//classification extension is added
+typedef struct _ADD_CONNECTION
+{
+ ULONG SrcIpAddressCount;
+ ULONG SrcIpAddress[MAX_CONNECTIONS];
+ ULONG SrcIpMask[MAX_CONNECTIONS];
+
+ ULONG DestIpAddressCount;
+ ULONG DestIpAddress[MAX_CONNECTIONS];
+ ULONG DestIpMask[MAX_CONNECTIONS];
+
+ USHORT SrcPortBegin;
+ USHORT SrcPortEnd;
+
+ USHORT DestPortBegin;
+ USHORT DestPortEnd;
+
+ UCHAR SrcTOS;
+ UCHAR SrcProtocol;
+} ADD_CONNECTION,*PADD_CONNECTION;
+
+
+typedef struct _CLASSIFICATION_RULE
+{
+ UCHAR ucIPSrcAddrLen;
+ UCHAR ucIPSrcAddr[32];
+ UCHAR ucIPDestAddrLen;
+ UCHAR ucIPDestAddr[32];
+ UCHAR ucSrcPortRangeLen;
+ UCHAR ucSrcPortRange[4];
+ UCHAR ucDestPortRangeLen;
+ UCHAR ucDestPortRange[4];
+ USHORT usVcid;
+} CLASSIFICATION_RULE,*PCLASSIFICATION_RULE;
+
+typedef struct _CLASSIFICATION_ONLY
+{
+ USHORT usVcid;
+ ULONG DestIpAddress;
+ ULONG DestIpMask;
+ USHORT usPortLo;
+ USHORT usPortHi;
+ BOOLEAN bIpVersion;
+ UCHAR ucDestinationAddress[16];
+} CLASSIFICATION_ONLY, *PCLASSIFICATION_ONLY;
+
+
+#define MAX_IP_RANGE_LENGTH 4
+#define MAX_PORT_RANGE 4
+#define MAX_PROTOCOL_LENGTH 32
+#define IPV6_ADDRESS_SIZEINBYTES 0x10
+
+typedef union _U_IP_ADDRESS
+{
+ struct
+ {
+ ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH];//Source Ip Address Range
+ ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH];//Source Ip Mask Address Range
+ };
+ struct
+ {
+ ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4];//Source Ip Address Range
+ ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4];//Source Ip Mask Address Range
+
+ };
+ struct
+ {
+ UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS];
+ UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS];
+ };
+ struct
+ {
+ UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES];
+ UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES];
+ };
+}U_IP_ADDRESS;
+struct _packet_info;
+
+typedef struct _S_HDR_SUPRESSION_CONTEXTINFO
+{
+
+ UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; //Intermediate buffer to accumulate pkt Header for PHS
+ UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; //Intermediate buffer containing pkt Header after PHS
+
+}S_HDR_SUPRESSION_CONTEXTINFO;
+
+
+typedef struct _S_CLASSIFIER_RULE
+{
+ ULONG ulSFID;
+ UCHAR ucReserved[2];
+ B_UINT16 uiClassifierRuleIndex;
+ BOOLEAN bUsed;
+ USHORT usVCID_Value;
+ B_UINT8 u8ClassifierRulePriority; //This field detemines the Classifier Priority
+ U_IP_ADDRESS stSrcIpAddress;
+ UCHAR ucIPSourceAddressLength;//Ip Source Address Length
+
+ U_IP_ADDRESS stDestIpAddress;
+ UCHAR ucIPDestinationAddressLength;//Ip Destination Address Length
+ UCHAR ucIPTypeOfServiceLength;//Type of service Length
+ UCHAR ucTosLow;//Tos Low
+ UCHAR ucTosHigh;//Tos High
+ UCHAR ucTosMask;//Tos Mask
+
+ UCHAR ucProtocolLength;//protocol Length
+ UCHAR ucProtocol[MAX_PROTOCOL_LENGTH];//protocol Length
+ USHORT usSrcPortRangeLo[MAX_PORT_RANGE];
+ USHORT usSrcPortRangeHi[MAX_PORT_RANGE];
+ UCHAR ucSrcPortRangeLength;
+
+ USHORT usDestPortRangeLo[MAX_PORT_RANGE];
+ USHORT usDestPortRangeHi[MAX_PORT_RANGE];
+ UCHAR ucDestPortRangeLength;
+
+ BOOLEAN bProtocolValid;
+ BOOLEAN bTOSValid;
+ BOOLEAN bDestIpValid;
+ BOOLEAN bSrcIpValid;
+
+ //For IPv6 Addressing
+ UCHAR ucDirection;
+ BOOLEAN bIpv6Protocol;
+ UINT32 u32PHSRuleID;
+ S_PHS_RULE sPhsRule;
+ UCHAR u8AssociatedPHSI;
+
+ //Classification fields for ETH CS
+ UCHAR ucEthCSSrcMACLen;
+ UCHAR au8EThCSSrcMAC[MAC_ADDRESS_SIZE];
+ UCHAR au8EThCSSrcMACMask[MAC_ADDRESS_SIZE];
+ UCHAR ucEthCSDestMACLen;
+ UCHAR au8EThCSDestMAC[MAC_ADDRESS_SIZE];
+ UCHAR au8EThCSDestMACMask[MAC_ADDRESS_SIZE];
+ UCHAR ucEtherTypeLen;
+ UCHAR au8EthCSEtherType[NUM_ETHERTYPE_BYTES];
+ UCHAR usUserPriority[2];
+ USHORT usVLANID;
+ USHORT usValidityBitMap;
+}S_CLASSIFIER_RULE;
+//typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE;
+
+typedef struct _S_FRAGMENTED_PACKET_INFO
+{
+ BOOLEAN bUsed;
+ ULONG ulSrcIpAddress;
+ USHORT usIpIdentification;
+ S_CLASSIFIER_RULE *pstMatchedClassifierEntry;
+ BOOLEAN bOutOfOrderFragment;
+}S_FRAGMENTED_PACKET_INFO,*PS_FRAGMENTED_PACKET_INFO;
+
+struct _packet_info
+{
+ //classification extension Rule
+ ULONG ulSFID;
+ USHORT usVCID_Value;
+ UINT uiThreshold;
+ // This field determines the priority of the SF Queues
+ B_UINT8 u8TrafficPriority;
+
+ BOOLEAN bValid;
+ BOOLEAN bActive;
+ BOOLEAN bActivateRequestSent;
+
+ B_UINT8 u8QueueType;//BE or rtPS
+
+ UINT uiMaxBucketSize;//maximum size of the bucket for the queue
+ UINT uiCurrentQueueDepthOnTarget;
+ UINT uiCurrentBytesOnHost;
+ UINT uiCurrentPacketsOnHost;
+ UINT uiDroppedCountBytes;
+ UINT uiDroppedCountPackets;
+ UINT uiSentBytes;
+ UINT uiSentPackets;
+ UINT uiCurrentDrainRate;
+ UINT uiThisPeriodSentBytes;
+ LARGE_INTEGER liDrainCalculated;
+ UINT uiCurrentTokenCount;
+ LARGE_INTEGER liLastUpdateTokenAt;
+ UINT uiMaxAllowedRate;
+ UINT NumOfPacketsSent;
+ UCHAR ucDirection;
+ USHORT usCID;
+ S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
+ UINT uiCurrentRxRate;
+ UINT uiThisPeriodRxBytes;
+ UINT uiTotalRxBytes;
+ UINT uiTotalTxBytes;
+ UINT uiPendedLast;
+ UCHAR ucIpVersion;
+
+ union
+ {
+ struct
+ {
+ struct sk_buff* FirstTxQueue;
+ struct sk_buff* LastTxQueue;
+ };
+ struct
+ {
+ struct sk_buff* ControlHead;
+ struct sk_buff* ControlTail;
+ };
+ };
+ BOOLEAN bProtocolValid;
+ BOOLEAN bTOSValid;
+ BOOLEAN bDestIpValid;
+ BOOLEAN bSrcIpValid;
+
+ BOOLEAN bActiveSet;
+ BOOLEAN bAdmittedSet;
+ BOOLEAN bAuthorizedSet;
+ BOOLEAN bClassifierPriority;
+ UCHAR ucServiceClassName[MAX_CLASS_NAME_LENGTH];
+ BOOLEAN bHeaderSuppressionEnabled;
+ spinlock_t SFQueueLock;
+ void *pstSFIndication;
+ struct timeval stLastUpdateTokenAt;
+ atomic_t uiPerSFTxResourceCount;
+ UINT uiMaxLatency;
+ UCHAR bIPCSSupport;
+ UCHAR bEthCSSupport;
+};
+typedef struct _packet_info PacketInfo;
+
+
+typedef struct _PER_TARANG_DATA
+{
+ struct _PER_TARANG_DATA * next;
+ struct _MINI_ADAPTER * Adapter;
+ struct sk_buff* RxAppControlHead;
+ struct sk_buff* RxAppControlTail;
+ volatile INT AppCtrlQueueLen;
+ BOOLEAN MacTracingEnabled;
+ BOOLEAN bApplicationToExit;
+ S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
+ ULONG RxCntrlMsgBitMask;
+} PER_TARANG_DATA, *PPER_TARANG_DATA;
+
+
+#ifdef REL_4_1
+typedef struct _TARGET_PARAMS
+{
+ B_UINT32 m_u32CfgVersion;
+
+ // Scanning Related Params
+ B_UINT32 m_u32CenterFrequency;
+ B_UINT32 m_u32BandAScan;
+ B_UINT32 m_u32BandBScan;
+ B_UINT32 m_u32BandCScan;
+
+ // QoS Params
+ B_UINT32 m_u32minGrantsize; // size of minimum grant is 0 or 6
+ B_UINT32 m_u32PHSEnable;
+
+ // HO Params
+ B_UINT32 m_u32HoEnable;
+ B_UINT32 m_u32HoReserved1;
+ B_UINT32 m_u32HoReserved2;
+
+ // Power Control Params
+ B_UINT32 m_u32MimoEnable;
+ B_UINT32 m_u32SecurityEnable;
+ /*
+ * bit 1: 1 Idlemode enable;
+ * bit 2: 1 Sleepmode Enable
+ */
+ B_UINT32 m_u32PowerSavingModesEnable;
+ /* PowerSaving Mode Options:
+ bit 0 = 1: CPE mode - to keep pcmcia if alive;
+ bit 1 = 1: CINR reporing in Idlemode Msg
+ bit 2 = 1: Default PSC Enable in sleepmode*/
+ B_UINT32 m_u32PowerSavingModeOptions;
+
+ B_UINT32 m_u32ArqEnable;
+
+ // From Version #3, the HARQ section renamed as general
+ B_UINT32 m_u32HarqEnable;
+ // EEPROM Param Location
+ B_UINT32 m_u32EEPROMFlag;
+ /* BINARY TYPE - 4th MSByte:
+ * Interface Type - 3rd MSByte:
+ * Vendor Type - 2nd MSByte
+ */
+ // Unused - LSByte
+ B_UINT32 m_u32Customize;
+ B_UINT32 m_u32ConfigBW; /* In Hz */
+ B_UINT32 m_u32ShutDownTimer;
+
+
+ B_UINT32 m_u32RadioParameter;
+ B_UINT32 m_u32PhyParameter1;
+ B_UINT32 m_u32PhyParameter2;
+ B_UINT32 m_u32PhyParameter3;
+
+ /* in eval mode only;
+ * lower 16bits = basic cid for testing;
+ * then bit 16 is test cqich,
+ * bit 17 test init rang;
+ * bit 18 test periodic rang
+ * bit 19 is test harq ack/nack
+ */
+ B_UINT32 m_u32TestOptions;
+
+ B_UINT32 m_u32MaxMACDataperDLFrame;
+ B_UINT32 m_u32MaxMACDataperULFrame;
+
+ B_UINT32 m_u32Corr2MacFlags;
+
+ //adding driver params.
+ B_UINT32 HostDrvrConfig1;
+ B_UINT32 HostDrvrConfig2;
+ B_UINT32 HostDrvrConfig3;
+ B_UINT32 HostDrvrConfig4;
+ B_UINT32 HostDrvrConfig5;
+ B_UINT32 HostDrvrConfig6;
+ B_UINT32 m_u32SegmentedPUSCenable;
+
+ // BAMC enable - but 4.x does not support this feature
+ // This is added just to sync 4.x and 5.x CFGs
+ B_UINT32 m_u32BandAMCEnable;
+} STARGETPARAMS, *PSTARGETPARAMS;
+#endif
+
+typedef struct _STTARGETDSXBUFFER
+{
+ ULONG ulTargetDsxBuffer;
+ B_UINT16 tid;
+ BOOLEAN valid;
+}STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER;
+
+typedef INT (*FP_FLASH_WRITE)(struct _MINI_ADAPTER*,UINT,PVOID);
+
+typedef INT (*FP_FLASH_WRITE_STATUS)(struct _MINI_ADAPTER*,UINT,PVOID);
+
+/**
+Driver adapter data structure
+*/
+struct _MINI_ADAPTER
+{
+ struct _MINI_ADAPTER *next;
+ PVOID pvOsDepData;
+ CHAR *caDsxReqResp;
+ atomic_t ApplicationRunning;
+ volatile INT CtrlQueueLen;
+ atomic_t AppCtrlQueueLen;
+ BOOLEAN AppCtrlQueueOverFlow;
+ atomic_t CurrentApplicationCount;
+ atomic_t RegisteredApplicationCount;
+ BOOLEAN TimerActive;
+ ULONG StatisticsPointer;
+ struct sk_buff *RxControlHead;
+ struct sk_buff *RxControlTail;
+// spinlock_t RxControlQueuelock;
+ struct semaphore RxAppControlQueuelock;
+ struct semaphore fw_download_sema;
+
+ PPER_TARANG_DATA pTarangs;
+ spinlock_t control_queue_lock;
+ wait_queue_head_t process_read_wait_queue;
+ ULONG bcm_jiffies; /* Store Jiffies value */
+
+ // the pointer to the first packet we have queued in send
+ // deserialized miniport support variables
+ atomic_t TotalPacketCount;
+ atomic_t TxPktAvail;
+
+ // this to keep track of the Tx and Rx MailBox Registers.
+ atomic_t CurrNumFreeTxDesc;
+ // to keep track the no of byte recieved
+ atomic_t RxRollOverCount;
+ USHORT PrevNumRecvDescs;
+ USHORT CurrNumRecvDescs;
+ atomic_t GoodRxByteCount;
+ atomic_t GoodRxPktCount;
+ atomic_t BadRxByteCount;
+ atomic_t RxPacketDroppedCount;
+ atomic_t GoodTxByteCount;
+ atomic_t TxTotalPacketCount;
+ atomic_t TxDroppedPacketCount;
+ ULONG LinkUpStatus;
+ BOOLEAN TransferMode;
+ UINT u32TotalDSD;
+ PacketInfo PackInfo[NO_OF_QUEUES];
+ S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS];
+
+ /*************** qos ******************/
+ UINT bETHCSEnabled;
+
+ ULONG BEBucketSize;
+ ULONG rtPSBucketSize;
+ UCHAR LinkStatus;
+ BOOLEAN AutoLinkUp;
+ BOOLEAN AutoSyncup;
+
+ struct net_device *dev;
+ UINT major;
+ UINT minor;
+ wait_queue_head_t tx_packet_wait_queue;
+ wait_queue_head_t process_rx_cntrlpkt;
+ atomic_t process_waiting;
+ BOOLEAN fw_download_done;
+
+ unsigned int ctrlpkt_present;
+ BOOLEAN packets_given_to_all;
+ char *txctlpacket[MAX_CNTRL_PKTS];
+ atomic_t cntrlpktCnt ;
+ atomic_t index_app_read_cntrlpkt;
+ atomic_t index_wr_txcntrlpkt;
+ atomic_t index_rd_txcntrlpkt;
+ UINT index_datpkt;
+ struct semaphore rdmwrmsync;
+
+ STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS];
+ ULONG ulFreeTargetBufferCnt;
+ ULONG ulCurrentTargetBuffer;
+ ULONG ulTotalTargetBuffersAvailable;
+ unsigned int timeout;
+ int irq;
+ unsigned long chip_id;
+ unsigned int bFlashBoot;
+ unsigned int if_up;
+// spinlock_t sleeper_lock;
+ atomic_t rdm_wrm_access;
+ atomic_t tx_rx_access;
+ wait_queue_head_t lowpower_mode_wait_queue;
+ atomic_t bAbortedByHost;
+ BOOLEAN bBinDownloaded;
+ BOOLEAN bCfgDownloaded;
+ USHORT usBestEffortQueueIndex;
+ BOOLEAN bSyncUpRequestSent;
+// struct semaphore data_packet_queue_lock;
+ wait_queue_head_t ioctl_fw_dnld_wait_queue;
+ BOOLEAN waiting_to_fw_download_done;
+ pid_t fw_download_process_pid;
+ PSTARGETPARAMS pstargetparams;
+ BOOLEAN device_removed;
+ BOOLEAN DeviceAccess;
+ INT DDRSetting;
+ BOOLEAN bDDRInitDone;
+ ULONG ulPowerSaveMode;
+ BOOLEAN bIsAutoCorrectEnabled;
+ spinlock_t txtransmitlock;
+ B_UINT8 txtransmit_running;
+ /* Thread for control packet handling */
+ struct task_struct *control_packet_handler;
+ /* thread for transmitting packets. */
+ struct task_struct *transmit_packet_thread;
+
+ /* LED Related Structures */
+ LED_INFO_STRUCT LEDInfo;
+
+ /* Driver State for LED Blinking */
+ LedEventInfo_t DriverState;
+ /* Interface Specific */
+ PVOID pvInterfaceAdapter;
+ int (*bcm_file_download)( PVOID,
+ struct file *,
+ unsigned int);
+ int (*bcm_file_readback_from_chip)( PVOID,
+ struct file *,
+ unsigned int);
+ INT (*interface_rdm)(PVOID,
+ UINT ,
+ PVOID ,
+ INT);
+ INT (*interface_wrm)(PVOID,
+ UINT ,
+ PVOID ,
+ INT);
+ int (*interface_transmit)(PVOID, PVOID , UINT);
+ BOOLEAN IdleMode;
+ BOOLEAN bDregRequestSentInIdleMode;
+ BOOLEAN bTriedToWakeUpFromlowPowerMode;
+ BOOLEAN bShutStatus;
+ BOOLEAN bWakeUpDevice;
+ unsigned int usIdleModePattern;
+ //BOOLEAN bTriedToWakeUpFromShutdown;
+ BOOLEAN bLinkDownRequested;
+ unsigned int check_for_hang;
+ int downloadDDR;
+ PHS_DEVICE_EXTENSION stBCMPhsContext;
+ S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo;
+ uint8_t ucaPHSPktRestoreBuf[2048];
+ uint8_t bPHSEnabled;
+ int AutoFirmDld;
+ BOOLEAN bMipsConfig;
+ BOOLEAN bDPLLConfig;
+ UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+ UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+ S_FRAGMENTED_PACKET_INFO astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES];
+ atomic_t uiMBupdate;
+ UINT32 PmuMode;
+ NVM_TYPE eNVMType;
+ UINT uiSectorSize;
+ UINT uiSectorSizeInCFG;
+ BOOLEAN bSectorSizeOverride;
+ BOOLEAN bStatusWrite;
+ UINT uiNVMDSDSize;
+ UINT uiVendorExtnFlag;
+ //it will always represent choosed DSD at any point of time.
+ // Generally it is Active DSD but in case of NVM RD/WR it might be different.
+ UINT ulFlashCalStart;
+ ULONG ulFlashControlSectionStart;
+ ULONG ulFlashWriteSize;
+ ULONG ulFlashID;
+ FP_FLASH_WRITE fpFlashWrite;
+ FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck;
+
+
+ struct semaphore NVMRdmWrmLock;
+ BOOLEAN bNetworkInterfaceRegistered;
+ BOOLEAN bNetdeviceNotifierRegistered;
+ struct device *pstCreatedClassDevice;
+ BOOLEAN bUsbClassDriverRegistered;
+// BOOLEAN InterfaceUpStatus;
+ PFLASH2X_CS_INFO psFlash2xCSInfo;
+ PFLASH_CS_INFO psFlashCSInfo ;
+ PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo;
+ UINT uiFlashBaseAdd; //Flash start address
+ UINT uiActiveISOOffset; //Active ISO offset choosen before f/w download
+ FLASH2X_SECTION_VAL eActiveISO; //Active ISO section val
+ FLASH2X_SECTION_VAL eActiveDSD; //Active DSD val choosen before f/w download
+ UINT uiActiveDSDOffsetAtFwDld; //For accessing Active DSD choosen before f/w download
+ UINT uiFlashLayoutMajorVersion ;
+ UINT uiFlashLayoutMinorVersion;
+ BOOLEAN bAllDSDWriteAllow ;
+ BOOLEAN bSigCorrupted ;
+ //this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately.
+ BOOLEAN bHeaderChangeAllowed ;
+ INT SelectedChip ;
+ BOOLEAN bEndPointHalted;
+ //while bFlashRawRead will be true, Driver ignore map lay out and consider flash as of without any map.
+ BOOLEAN bFlashRawRead;
+ BOOLEAN bPreparingForLowPowerMode ;
+ BOOLEAN bDoSuspend ;
+ UINT syscfgBefFwDld ;
+ BOOLEAN StopAllXaction ;
+ UINT32 liTimeSinceLastNetEntry; //Used to Support extended CAPI requirements from
+ struct semaphore LowPowerModeSync;
+ ULONG liDrainCalculated;
+ UINT gpioBitMap;
+ S_BCM_DEBUG_STATE stDebugState;
+
+};
+typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER;
+
+
+typedef struct _DEVICE_EXTENSION
+{
+ PMINI_ADAPTER pAdapt;
+}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
+
+
+struct _ETH_HEADER_STRUC {
+ UCHAR au8DestinationAddress[6];
+ UCHAR au8SourceAddress[6];
+ USHORT u16Etype;
+}__attribute__((packed));
+typedef struct _ETH_HEADER_STRUC ETH_HEADER_STRUC, *PETH_HEADER_STRUC;
+
+
+typedef struct FirmwareInfo
+{
+ PVOID pvMappedFirmwareAddress;
+ ULONG u32FirmwareLength;
+ ULONG u32StartingAddress;
+}__attribute__((packed)) FIRMWARE_INFO, *PFIRMWARE_INFO;
+
+// holds the value of net_device structure..
+extern struct net_device *gblpnetdev;
+typedef struct _cntl_pkt{
+ PMINI_ADAPTER Adapter;
+ PLEADER PLeader;
+}cntl_pkt;
+typedef LINK_REQUEST CONTROL_MESSAGE;
+
+typedef struct _DDR_SETTING
+{
+ ULONG ulRegAddress;
+ ULONG ulRegValue;
+}DDR_SETTING, *PDDR_SETTING;
+typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE;
+INT
+InitAdapter(PMINI_ADAPTER psAdapter);
+
+// =====================================================================
+// Beceem vendor request codes for EP0
+// =====================================================================
+
+#define BCM_REQUEST_READ 0x2
+#define BCM_REQUEST_WRITE 0x1
+#define EP2_MPS_REG 0x0F0110A0
+#define EP2_MPS 0x40
+
+#define EP2_CFG_REG 0x0F0110A8
+#define EP2_CFG_INT 0x27
+#define EP2_CFG_BULK 0x25
+
+#define EP4_MPS_REG 0x0F0110F0
+#define EP4_MPS 0x8C
+
+#define EP4_CFG_REG 0x0F0110F8
+
+#define ISO_MPS_REG 0x0F0110C8
+#define ISO_MPS 0x00000000
+
+
+#define EP1 0
+#define EP2 1
+#define EP3 2
+#define EP4 3
+#define EP5 4
+#define EP6 5
+
+
+typedef enum eInterface_setting
+{
+ DEFAULT_SETTING_0 = 0,
+ ALTERNATE_SETTING_1 = 1,
+}INTERFACE_SETTING;
+
+#endif //__ADAPTER_H__
+
diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c
new file mode 100644
index 000000000000..d60d8593d2ef
--- /dev/null
+++ b/drivers/staging/bcm/Arp.c
@@ -0,0 +1,94 @@
+
+/*
+ * File Name: Arp.c
+ * Abstract: This file contains the routines for handling ARP PACKETS
+ */
+#include "headers.h"
+#define ARP_PKT_SIZE 60
+
+/* =========================================================================
+ * Function - reply_to_arp_request()
+ *
+ * Description - When this host tries to broadcast ARP request packet through
+ * the virtual interface (veth0), reply directly to upper layer.
+ * This function allocates a new skb for ARP reply packet,
+ * fills in the fields of the packet and then sends it to
+ * upper layer.
+ *
+ * Parameters - skb: Pointer to sk_buff structure of the ARP request pkt.
+ *
+ * Returns - None
+ * =========================================================================*/
+
+VOID
+reply_to_arp_request(struct sk_buff *skb)
+{
+ PMINI_ADAPTER Adapter;
+ struct ArpHeader *pArpHdr = NULL;
+ struct ethhdr *pethhdr = NULL;
+ UCHAR uiIPHdr[4];
+ /* Check for valid skb */
+ if(skb == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
+ return;
+ }
+
+
+ Adapter = GET_BCM_ADAPTER(skb->dev);
+ /* Print the ARP Request Packet */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
+
+ /*
+ * Extract the Ethernet Header and Arp Payload including Header
+ */
+ pethhdr = (struct ethhdr *)skb->data;
+ pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN);
+
+ if(Adapter->bETHCSEnabled)
+ {
+ if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
+ {
+ bcm_kfree_skb(skb);
+ return;
+ }
+ }
+
+ // Set the Ethernet Header First.
+ memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
+ if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
+ {
+ pethhdr->h_source[5]++;
+ }
+
+ /* Set the reply to ARP Reply */
+ pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);
+
+ /* Set the HW Address properly */
+ memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
+ memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);
+
+ // Swapping the IP Adddress
+ memcpy(uiIPHdr,pArpHdr->ar_sip,4);
+ memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
+ memcpy(pArpHdr->ar_tip,uiIPHdr,4);
+
+ /* Print the ARP Reply Packet */
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");
+
+ /* Send the Packet to upper layer */
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
+
+ skb->protocol = eth_type_trans(skb,skb->dev);
+ skb->pkt_type = PACKET_HOST;
+
+// skb->mac.raw=skb->data+LEADER_SIZE;
+ skb_set_mac_header (skb, LEADER_SIZE);
+ netif_rx(skb);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
+ return;
+}
+
+
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
new file mode 100644
index 000000000000..489487a6edb6
--- /dev/null
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -0,0 +1,2420 @@
+#include "headers.h"
+/***************************************************************
+* Function - bcm_char_open()
+*
+* Description - This is the "open" entry point for the character
+* driver.
+*
+* Parameters - inode: Pointer to the Inode structure of char device
+* filp : File pointer of the char device
+*
+* Returns - Zero(Success)
+****************************************************************/
+static struct class *bcm_class = NULL;
+static int bcm_char_open(struct inode *inode, struct file * filp)
+{
+ PMINI_ADAPTER Adapter = NULL;
+ PPER_TARANG_DATA pTarang = NULL;
+
+ Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL);
+ if (!pTarang)
+ return -ENOMEM;
+
+ memset (pTarang, 0, sizeof(PER_TARANG_DATA));
+ pTarang->Adapter = Adapter;
+ pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB) ;
+
+ down(&Adapter->RxAppControlQueuelock);
+ pTarang->next = Adapter->pTarangs;
+ Adapter->pTarangs = pTarang;
+ up(&Adapter->RxAppControlQueuelock);
+
+ /* Store the Adapter structure */
+ filp->private_data = pTarang;
+
+ /*Start Queuing the control response Packets*/
+ atomic_inc(&Adapter->ApplicationRunning);
+ return 0;
+}
+static int bcm_char_release(struct inode *inode, struct file *filp)
+{
+ PPER_TARANG_DATA pTarang, tmp, ptmp;
+ PMINI_ADAPTER Adapter=NULL;
+ struct sk_buff * pkt, * npkt;
+
+ pTarang = (PPER_TARANG_DATA)filp->private_data;
+
+ if(pTarang == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ptarang is null\n");
+ return 0;
+ }
+
+ Adapter = pTarang->Adapter;
+
+ down( &Adapter->RxAppControlQueuelock);
+
+ tmp = Adapter->pTarangs;
+ for ( ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next )
+ {
+ if ( tmp == pTarang )
+ break;
+ }
+
+ if ( tmp )
+ {
+ if ( !ptmp )
+ Adapter->pTarangs = tmp->next;
+ else
+ ptmp->next = tmp->next;
+ }
+
+ else
+ {
+ up( &Adapter->RxAppControlQueuelock);
+ return 0;
+ }
+
+ pkt = pTarang->RxAppControlHead;
+ while ( pkt )
+ {
+ npkt = pkt->next;
+ kfree_skb(pkt);
+ pkt = npkt;
+ }
+
+ up( &Adapter->RxAppControlQueuelock);
+
+ /*Stop Queuing the control response Packets*/
+ atomic_dec(&Adapter->ApplicationRunning);
+
+ bcm_kfree(pTarang);
+
+ /* remove this filp from the asynchronously notified filp's */
+ filp->private_data = NULL;
+ return 0;
+}
+
+static int bcm_char_read(struct file *filp, PCHAR buf, size_t size, loff_t *f_pos)
+{
+ PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data;
+ PMINI_ADAPTER Adapter = pTarang->Adapter;
+ struct sk_buff* Packet = NULL;
+ UINT PktLen = 0;
+ int wait_ret_val=0;
+
+ wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
+ (pTarang->RxAppControlHead || Adapter->device_removed));
+ if((wait_ret_val == -ERESTARTSYS))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Exiting as i've been asked to exit!!!\n");
+ return wait_ret_val;
+ }
+
+ if(Adapter->device_removed)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device Removed... Killing the Apps...\n");
+ return -ENODEV;
+ }
+
+ if(FALSE == Adapter->fw_download_done)
+ return -EACCES;
+
+ down( &Adapter->RxAppControlQueuelock);
+
+ if(pTarang->RxAppControlHead)
+ {
+ Packet = pTarang->RxAppControlHead;
+ DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
+ pTarang->AppCtrlQueueLen--;
+ }
+
+ up(&Adapter->RxAppControlQueuelock);
+
+ if(Packet)
+ {
+ PktLen = Packet->len;
+ if(copy_to_user(buf, Packet->data, PktLen))
+ {
+ bcm_kfree_skb(Packet);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n");
+ return -EFAULT;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid);
+ bcm_kfree_skb(Packet);
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n");
+ return PktLen;
+}
+
+static INT bcm_char_ioctl(struct inode *inode, struct file *filp,
+ UINT cmd, ULONG arg)
+{
+ PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data;
+ PMINI_ADAPTER Adapter = pTarang->Adapter;
+ INT Status = STATUS_FAILURE;
+ IOCTL_BUFFER IoBuffer={0};
+#ifndef BCM_SHM_INTERFACE
+ int timeout = 0;
+#endif
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
+
+ if(_IOC_TYPE(cmd) != BCM_IOCTL)
+ return -EFAULT;
+ if(_IOC_DIR(cmd) & _IOC_READ)
+ Status = !access_ok(VERIFY_WRITE, (PVOID)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ Status = !access_ok(VERIFY_READ, (PVOID)arg, _IOC_SIZE(cmd));
+ else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
+ Status = STATUS_SUCCESS;
+
+ if(Status)
+ return -EFAULT;
+
+ if(Adapter->device_removed)
+ {
+ return -EFAULT;
+ }
+
+ if(FALSE == Adapter->fw_download_done)
+ {
+ switch (cmd)
+ {
+ case IOCTL_MAC_ADDR_REQ:
+ case IOCTL_LINK_REQ:
+ case IOCTL_CM_REQUEST:
+ case IOCTL_SS_INFO_REQ:
+ case IOCTL_SEND_CONTROL_MESSAGE:
+ case IOCTL_IDLE_REQ:
+ case IOCTL_BCM_GPIO_SET_REQUEST:
+ case IOCTL_BCM_GPIO_STATUS_REQUEST:
+ return -EACCES;
+ default:
+ break;
+ }
+ }
+
+ Status = vendorextnIoctl(Adapter, cmd, arg);
+ if(Status != CONTINUE_COMMON_PATH )
+ {
+ return Status;
+ }
+
+ switch(cmd){
+ // Rdms for Swin Idle...
+ case IOCTL_BCM_REGISTER_READ_PRIVATE:
+ {
+ RDM_BUFFER sRdmBuffer = {0};
+ PCHAR temp_buff = NULL;
+ UINT Bufflen = 0;
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4;
+ temp_buff = (PCHAR)kmalloc(Bufflen, GFP_KERNEL);
+ if(!temp_buff)
+ {
+ return STATUS_FAILURE;
+ }
+ if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
+ (PUINT)temp_buff, Bufflen);
+ if(Status != STATUS_SUCCESS)
+ {
+ bcm_kfree(temp_buff);
+ return Status;
+ }
+ if(copy_to_user((PCHAR)IoBuffer.OutputBuffer,
+ (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength))
+ {
+ Status = -EFAULT;
+ }
+ bcm_kfree(temp_buff);
+ break;
+ }
+ case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
+ {
+ WRM_BUFFER sWrmBuffer = {0};
+ UINT uiTempVar=0;
+ /* Copy Ioctl Buffer structure */
+
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ /* Get WrmBuffer structure */
+ if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
+ if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
+ ((uiTempVar == EEPROM_REJECT_REG_1)||
+ (uiTempVar == EEPROM_REJECT_REG_2) ||
+ (uiTempVar == EEPROM_REJECT_REG_3) ||
+ (uiTempVar == EEPROM_REJECT_REG_4)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
+ Status = -EFAULT;
+ break;
+ }
+ Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
+ (PUINT)sWrmBuffer.Data, sizeof(ULONG));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
+ Status = -EFAULT;
+ }
+ break;
+ }
+
+ case IOCTL_BCM_REGISTER_READ:
+ case IOCTL_BCM_EEPROM_REGISTER_READ:
+ {
+ RDM_BUFFER sRdmBuffer = {0};
+ PCHAR temp_buff = NULL;
+ UINT uiTempVar = 0;
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
+ Status = -EACCES;
+ break;
+ }
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
+ if(!temp_buff)
+ {
+ return STATUS_FAILURE;
+ }
+ if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ if(
+#if !defined(BCM_SHM_INTERFACE)
+ (((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+#endif
+ ((ULONG)sRdmBuffer.Register & 0x3)
+ )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
+ (int)sRdmBuffer.Register);
+ Status = -EINVAL;
+ break;
+ }
+
+ uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
+ Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
+ (PUINT)temp_buff, IoBuffer.OutputLength);
+ if(Status != STATUS_SUCCESS)
+ {
+ bcm_kfree(temp_buff);
+ return Status;
+ }
+ if(copy_to_user((PCHAR)IoBuffer.OutputBuffer,
+ (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength))
+ {
+ Status = -EFAULT;
+ }
+ bcm_kfree(temp_buff);
+ break;
+ }
+ case IOCTL_BCM_REGISTER_WRITE:
+ case IOCTL_BCM_EEPROM_REGISTER_WRITE:
+ {
+ WRM_BUFFER sWrmBuffer = {0};
+ UINT uiTempVar=0;
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
+ Status = -EACCES;
+ break;
+ }
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ /* Get WrmBuffer structure */
+ if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(
+#if !defined(BCM_SHM_INTERFACE)
+
+ (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+#endif
+ ((ULONG)sWrmBuffer.Register & 0x3)
+ )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n",
+ (int)sWrmBuffer.Register);
+ Status = -EINVAL;
+ break;
+ }
+ uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
+ if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
+ ((uiTempVar == EEPROM_REJECT_REG_1)||
+ (uiTempVar == EEPROM_REJECT_REG_2) ||
+ (uiTempVar == EEPROM_REJECT_REG_3) ||
+ (uiTempVar == EEPROM_REJECT_REG_4)) &&
+ (cmd == IOCTL_BCM_REGISTER_WRITE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
+ (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
+ Status = -EFAULT;
+ }
+ break;
+ }
+ case IOCTL_BCM_GPIO_SET_REQUEST:
+ {
+ UCHAR ucResetValue[4];
+ UINT value =0;
+ UINT uiBit = 0;
+ UINT uiOperation = 0;
+
+ GPIO_INFO gpio_info = {0};
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
+ Status = -EACCES;
+ break;
+ }
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ uiBit = gpio_info.uiGpioNumber;
+ uiOperation = gpio_info.uiGpioValue;
+
+ value= (1<<uiBit);
+
+ if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value);
+ Status = -EINVAL;
+ break;
+ }
+
+
+ if(uiOperation)//Set - setting 1
+ {
+ //Set the gpio output register
+ Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG ,
+ (PUINT)(&value), sizeof(UINT));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit);
+ break;
+ }
+ }
+ else//Unset - setting 0
+ {
+ //Set the gpio output register
+ Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG ,
+ (PUINT)(&value), sizeof(UINT));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit);
+ break;
+ }
+ }
+
+ Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
+ (PUINT)ucResetValue, sizeof(UINT));
+ if (STATUS_SUCCESS != Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed");
+ break;
+ }
+ //Set the gpio mode register to output
+ *(UINT*)ucResetValue |= (1<<uiBit);
+ Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER ,
+ (PUINT)ucResetValue, sizeof(UINT));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
+ break;
+ }
+ }
+ break;
+ case BCM_LED_THREAD_STATE_CHANGE_REQ:
+ {
+
+ USER_THREAD_REQ threadReq = {0};
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive");
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
+ Status = -EACCES;
+ break;
+ }
+ Status =copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
+ break;
+ }
+
+ Status= copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the InputBuffer from user space err:%d",Status);
+ break;
+ }
+ //if LED thread is running(Actively or Inactively) set it state to make inactive
+ if(Adapter->LEDInfo.led_thread_running)
+ {
+ if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req");
+ Adapter->DriverState = LED_THREAD_ACTIVE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req.....");
+ Adapter->DriverState = LED_THREAD_INACTIVE;
+ }
+
+ //signal thread.
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+
+ }
+ }
+ break;
+ case IOCTL_BCM_GPIO_STATUS_REQUEST:
+ {
+ ULONG uiBit = 0;
+ UCHAR ucRead[4];
+ GPIO_INFO gpio_info = {0};
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ Status = -EACCES;
+ break;
+ }
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ uiBit = gpio_info.uiGpioNumber;
+ //Set the gpio output register
+ Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
+ (PUINT)ucRead, sizeof(UINT));
+ if(Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
+ return Status;
+ }
+
+ }
+ break;
+ case IOCTL_BCM_GPIO_MULTI_REQUEST:
+ {
+ UCHAR ucResetValue[4];
+ GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
+ PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;
+
+ memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO));
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ Status = -EINVAL;
+ break;
+ }
+ Status = copy_from_user( (PCHAR)&IoBuffer, ( PCHAR)arg, sizeof( IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
+ break;
+ }
+
+ Status = copy_from_user( &gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status);
+ break;
+ }
+ if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap);
+ Status = -EINVAL;
+ break;
+ }
+
+ /* Set the gpio output register */
+
+ if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
+ ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand))
+ {
+ /* Set 1's in GPIO OUTPUT REGISTER */
+ *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
+ pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
+ pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
+
+ if( *(UINT*) ucResetValue)
+ Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG));
+
+ if( Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
+ return Status;
+ }
+
+ /* Clear to 0's in GPIO OUTPUT REGISTER */
+ *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
+ pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
+ ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
+
+ if( *(UINT*) ucResetValue)
+ Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG));
+
+ if( Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." );
+ return Status;
+ }
+ }
+
+ if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask)
+ {
+ Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
+
+ if(Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed.");
+ return Status;
+ }
+
+ pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue &
+ pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
+ }
+
+ Status = copy_to_user( (PCHAR)IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
+ break;
+ }
+ }
+ break;
+ case IOCTL_BCM_GPIO_MODE_REQUEST:
+ {
+ UCHAR ucResetValue[4];
+ GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
+ PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode;
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ Status = -EINVAL;
+ break;
+ }
+ Status = copy_from_user( (PCHAR)&IoBuffer, ( PCHAR)arg, sizeof( IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
+ break;
+ }
+
+ Status = copy_from_user( &gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status);
+ break;
+ }
+
+ Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT));
+ if( STATUS_SUCCESS != Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed");
+ return Status;
+ }
+
+ //Validating the request
+ if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap);
+ Status = -EINVAL;
+ break;
+ }
+
+ if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)
+ {
+ /* write all OUT's (1's) */
+ *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
+ pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
+ /* write all IN's (0's) */
+ *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
+ pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
+
+ /* Currently implemented return the modes of all GPIO's
+ * else needs to bit AND with mask
+ * */
+ pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue;
+
+ Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG));
+ if( Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed");
+ Status = -EFAULT;
+ break;
+ }
+ }
+ else /* if uiGPIOMask is 0 then return mode register configuration */
+ {
+ pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue;
+ }
+ Status = copy_to_user( (PCHAR)IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
+ break;
+ }
+ }
+ break;
+
+ case IOCTL_MAC_ADDR_REQ:
+ case IOCTL_LINK_REQ:
+ case IOCTL_CM_REQUEST:
+ case IOCTL_SS_INFO_REQ:
+ case IOCTL_SEND_CONTROL_MESSAGE:
+ case IOCTL_IDLE_REQ:
+ {
+ PVOID pvBuffer=NULL;
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL);
+ if(!pvBuffer)
+ {
+ return -ENOMEM;
+ }
+
+ if(copy_from_user(pvBuffer, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ Status = -EFAULT;
+ bcm_kfree(pvBuffer);
+ break;
+ }
+
+ down(&Adapter->LowPowerModeSync);
+ Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
+ !Adapter->bPreparingForLowPowerMode,
+ (1 * HZ));
+ if(Status == -ERESTARTSYS)
+ goto cntrlEnd;
+
+ if(Adapter->bPreparingForLowPowerMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n");
+ Status = STATUS_FAILURE ;
+ goto cntrlEnd ;
+ }
+ Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
+ cntrlEnd:
+ up(&Adapter->LowPowerModeSync);
+ bcm_kfree(pvBuffer);
+ break;
+ }
+#ifndef BCM_SHM_INTERFACE
+ case IOCTL_BCM_BUFFER_DOWNLOAD_START:
+ {
+ INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ;
+ if(NVMAccess)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
+ return -EACCES;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
+ if(!down_trylock(&Adapter->fw_download_sema))
+ {
+ Adapter->bBinDownloaded=FALSE;
+ Adapter->fw_download_process_pid=current->pid;
+ Adapter->bCfgDownloaded=FALSE;
+ Adapter->fw_download_done=FALSE;
+ netif_carrier_off(Adapter->dev);
+ netif_stop_queue(Adapter->dev);
+ Status = reset_card_proc(Adapter);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "reset_card_proc Failed!\n");
+ up(&Adapter->fw_download_sema);
+ up(&Adapter->NVMRdmWrmLock);
+ break;
+ }
+ mdelay(10);
+ }
+ else
+ {
+
+ Status = -EBUSY;
+
+ }
+ up(&Adapter->NVMRdmWrmLock);
+ break;
+ }
+ case IOCTL_BCM_BUFFER_DOWNLOAD:
+ {
+ FIRMWARE_INFO *psFwInfo=NULL;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
+ do{
+ if(!down_trylock(&Adapter->fw_download_sema))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n");
+ Status=-EINVAL;
+ break;
+ }
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
+ Status = -EFAULT;
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n",
+ IoBuffer.InputLength);
+ psFwInfo=kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
+ if(!psFwInfo)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Failed to allocate buffer!!!!\n");
+ Status = -ENOMEM;
+ break;
+ }
+ if(copy_from_user(psFwInfo, IoBuffer.InputBuffer,
+ IoBuffer.InputLength))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from_user 2 failed\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ if(!psFwInfo->pvMappedFirmwareAddress ||
+ (psFwInfo->u32FirmwareLength == 0))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
+ psFwInfo->u32FirmwareLength);
+ Status = -EINVAL;
+ break;
+ }
+ Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
+ if(Status != STATUS_SUCCESS)
+ {
+ if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n");
+ }
+ //up(&Adapter->fw_download_sema);
+
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = DRIVER_INIT;
+ Adapter->LEDInfo.bLedInitDone = FALSE;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+ }
+ break ;
+ }while(0);
+
+ if(Status != STATUS_SUCCESS)
+ up(&Adapter->fw_download_sema);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
+ bcm_kfree(psFwInfo);
+ break;
+ }
+ case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
+ {
+ INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+ if(NVMAccess)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n");
+ up(&Adapter->fw_download_sema);
+ return -EACCES;
+ }
+ if(down_trylock(&Adapter->fw_download_sema))
+ {
+ Adapter->bBinDownloaded=TRUE;
+ Adapter->bCfgDownloaded=TRUE;
+ atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+ atomic_set(&Adapter->RxRollOverCount, 0);
+ Adapter->CurrNumRecvDescs=0;
+ Adapter->downloadDDR = 0;
+
+ //setting the Mips to Run
+ Status = run_card_proc(Adapter);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
+ up(&Adapter->fw_download_sema);
+ up(&Adapter->NVMRdmWrmLock);
+ break;
+ }
+ else
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n");
+ mdelay(10);
+ /* Wait for MailBox Interrupt */
+ if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
+ }
+ timeout = 5*HZ;
+ Adapter->waiting_to_fw_download_done = FALSE;
+ wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
+ Adapter->waiting_to_fw_download_done, timeout);
+ Adapter->fw_download_process_pid=INVALID_PID;
+ Adapter->fw_download_done=TRUE;
+ atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+ Adapter->CurrNumRecvDescs = 0;
+ Adapter->PrevNumRecvDescs = 0;
+ atomic_set(&Adapter->cntrlpktCnt,0);
+ Adapter->LinkUpStatus = 0;
+ Adapter->LinkStatus = 0;
+
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = FW_DOWNLOAD_DONE;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+
+ if(!timeout)
+ {
+ Status = -ENODEV;
+ }
+ }
+ else
+ {
+ Status = -EINVAL;
+ }
+ up(&Adapter->fw_download_sema);
+ up(&Adapter->NVMRdmWrmLock);
+ break;
+ }
+#endif
+ case IOCTL_BE_BUCKET_SIZE:
+ Adapter->BEBucketSize = *(PULONG)arg;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_RTPS_BUCKET_SIZE:
+ Adapter->rtPSBucketSize = *(PULONG)arg;
+ Status = STATUS_SUCCESS;
+ break;
+ case IOCTL_CHIP_RESET:
+ {
+ INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+ if(NVMAccess)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
+ return -EACCES;
+ }
+ down(&Adapter->RxAppControlQueuelock);
+ Status = reset_card_proc(Adapter);
+ flushAllAppQ();
+ up(&Adapter->RxAppControlQueuelock);
+ up(&Adapter->NVMRdmWrmLock);
+ ResetCounters(Adapter);
+ break;
+ }
+ case IOCTL_QOS_THRESHOLD:
+ {
+ USHORT uiLoopIndex;
+ for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++)
+ {
+ Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg;
+ }
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case IOCTL_DUMP_PACKET_INFO:
+
+ DumpPackInfo(Adapter);
+ DumpPhsRules(&Adapter->stBCMPhsContext);
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_GET_PACK_INFO:
+ if(copy_to_user((PCHAR)arg, &Adapter->PackInfo,
+ sizeof(PacketInfo)*NO_OF_QUEUES))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ Status = STATUS_SUCCESS;
+ break;
+ case IOCTL_BCM_SWITCH_TRANSFER_MODE:
+ {
+ UINT uiData = 0;
+ if(copy_from_user(&uiData, (PUINT)arg, sizeof(UINT)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(uiData) /* Allow All Packets */
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
+ Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
+ }
+ else /* Allow IP only Packets */
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
+ Adapter->TransferMode = IP_PACKET_ONLY_MODE;
+ }
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ case IOCTL_BCM_GET_DRIVER_VERSION:
+ {
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer,
+ (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(copy_to_user((PUCHAR)IoBuffer.OutputBuffer,
+ VER_FILEVERSION_STR, (UINT)IoBuffer.OutputLength))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ case IOCTL_BCM_GET_CURRENT_STATUS:
+ {
+ LINK_STATE *plink_state = NULL;
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer,
+ (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
+ Status = -EFAULT;
+ break;
+ }
+ plink_state = (LINK_STATE*)arg;
+ plink_state->bIdleMode = (UCHAR)Adapter->IdleMode;
+ plink_state->bShutdownMode = Adapter->bShutStatus;
+ plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus;
+ if(copy_to_user((PUCHAR)IoBuffer.OutputBuffer,
+ (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
+ Status = -EFAULT;
+ break;
+ }
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ case IOCTL_BCM_SET_MAC_TRACING:
+ {
+ UINT tracing_flag;
+ /* copy ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer,
+ (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if(copy_from_user((PCHAR)&tracing_flag,
+ (PCHAR)IoBuffer.InputBuffer,sizeof(UINT)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+ if (tracing_flag)
+ Adapter->pTarangs->MacTracingEnabled = TRUE;
+ else
+ Adapter->pTarangs->MacTracingEnabled = FALSE;
+ break;
+ }
+ case IOCTL_BCM_GET_DSX_INDICATION:
+ {
+ ULONG ulSFId=0;
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg,
+ sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid IO buffer!!!" );
+ Status = -EFAULT;
+ break;
+ }
+ if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%x!!!",
+ IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
+ return -EINVAL;
+ }
+ if(copy_from_user((PCHAR)&ulSFId, (PCHAR)IoBuffer.InputBuffer,
+ sizeof(ulSFId)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid SFID!!! %lu", ulSFId );
+ Status = -EFAULT;
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId );
+ get_dsx_sf_data_to_application(Adapter, ulSFId,
+ IoBuffer.OutputBuffer);
+ Status=STATUS_SUCCESS;
+ }
+ break;
+ case IOCTL_BCM_GET_HOST_MIBS:
+ {
+ PCHAR temp_buff;
+
+ if(copy_from_user((PCHAR)&IoBuffer,
+ (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from user for IoBuff failed\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length Check failed %lu %d\n", IoBuffer.OutputLength,
+ sizeof(S_MIBS_HOST_STATS_MIBS));
+ return -EINVAL;
+ }
+
+ temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
+
+ if(!temp_buff)
+ {
+ return STATUS_FAILURE;
+ }
+
+ Status = ProcessGetHostMibs(Adapter,
+ (PUCHAR)temp_buff, IoBuffer.OutputLength);
+
+ Status = GetDroppedAppCntrlPktMibs((PVOID)temp_buff,
+ (PPER_TARANG_DATA)filp->private_data);
+
+ if(copy_to_user((PCHAR)IoBuffer.OutputBuffer,(PCHAR)temp_buff,
+ sizeof(S_MIBS_HOST_STATS_MIBS)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n");
+ bcm_kfree(temp_buff);
+ return -EFAULT;
+ }
+
+ bcm_kfree(temp_buff);
+ break;
+ }
+
+ case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
+ if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode))
+ {
+ Adapter->usIdleModePattern = ABORT_IDLE_MODE;
+ Adapter->bWakeUpDevice = TRUE;
+ wake_up(&Adapter->process_rx_cntrlpkt);
+ #if 0
+ Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
+ InterfaceAbortIdlemode (Adapter, Adapter->usIdleModePattern);
+ #endif
+ }
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IOCTL_BCM_BULK_WRM:
+ {
+ PBULKWRM_BUFFER pBulkBuffer;
+ UINT uiTempVar=0;
+ PCHAR pvBuffer = NULL;
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n");
+ Status = -EACCES;
+ break;
+ }
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL);
+ if(!pvBuffer)
+ {
+ return -ENOMEM;
+ break;
+ }
+
+ /* Get WrmBuffer structure */
+ if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+ {
+ bcm_kfree(pvBuffer);
+ Status = -EFAULT;
+ break;
+ }
+
+ pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
+
+ if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
+ ((ULONG)pBulkBuffer->Register & 0x3))
+ {
+ bcm_kfree(pvBuffer);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register);
+ Status = -EINVAL;
+ break;
+ }
+
+
+ uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
+ if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE)
+ && ((uiTempVar == EEPROM_REJECT_REG_1)||
+ (uiTempVar == EEPROM_REJECT_REG_2) ||
+ (uiTempVar == EEPROM_REJECT_REG_3) ||
+ (uiTempVar == EEPROM_REJECT_REG_4)) &&
+ (cmd == IOCTL_BCM_REGISTER_WRITE))
+ {
+ bcm_kfree(pvBuffer);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ if(pBulkBuffer->SwapEndian == FALSE)
+ Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
+ else
+ Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
+
+ if(Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
+ }
+
+ bcm_kfree(pvBuffer);
+ break;
+ }
+
+ case IOCTL_BCM_GET_NVM_SIZE:
+ {
+
+ if(copy_from_user((unsigned char *)&IoBuffer,
+ (unsigned char *)arg, sizeof(IOCTL_BUFFER)))
+ {
+ //IOLog("failed NVM first");
+ Status = -EFAULT;
+ break;
+ }
+ if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
+ if(copy_to_user(IoBuffer.OutputBuffer,
+ (unsigned char *)&Adapter->uiNVMDSDSize, (UINT)sizeof(UINT)))
+ {
+ Status = -EFAULT;
+ return Status;
+ }
+ }
+
+ Status = STATUS_SUCCESS ;
+ }
+ break;
+
+ case IOCTL_BCM_CAL_INIT :
+
+ {
+ UINT uiSectorSize = 0 ;
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status);
+ return Status;
+ }
+ uiSectorSize = *((PUINT)(IoBuffer.InputBuffer));
+ if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
+ {
+
+ Status = copy_to_user(IoBuffer.OutputBuffer,
+ (unsigned char *)&Adapter->uiSectorSize ,
+ (UINT)sizeof(UINT));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status);
+ return Status;
+ }
+ }
+ else
+ {
+ if(IsFlash2x(Adapter))
+ {
+ Status = copy_to_user(IoBuffer.OutputBuffer,
+ (unsigned char *)&Adapter->uiSectorSize ,
+ (UINT)sizeof(UINT));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status);
+ return Status;
+ }
+
+ }
+ else
+ {
+ if((TRUE == Adapter->bShutStatus) ||
+ (TRUE == Adapter->IdleMode))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n");
+ return -EACCES;
+ }
+
+ Adapter->uiSectorSize = uiSectorSize ;
+ BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize);
+ }
+ }
+ Status = STATUS_SUCCESS ;
+ }
+ else
+ {
+ Status = STATUS_FAILURE;
+ }
+ }
+ break;
+ case IOCTL_BCM_SET_DEBUG :
+ {
+ USER_BCM_DBG_STATE sUserDebugState;
+
+// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG );
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy from user failed\n");
+ break;
+ }
+ Status = copy_from_user(&sUserDebugState,(USER_BCM_DBG_STATE *)IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IoBuffer.InputBuffer failed");
+ return Status;
+ }
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
+ sUserDebugState.OnOff, sUserDebugState.Type);
+ //sUserDebugState.Subtype <<= 1;
+ sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype);
+
+ // Update new 'DebugState' in the Adapter
+ Adapter->stDebugState.type |= sUserDebugState.Type;
+ /* Subtype: A bitmap of 32 bits for Subtype per Type.
+ * Valid indexes in 'subtype' array: 1,2,4,8
+ * corresponding to valid Type values. Hence we can use the 'Type' field
+ * as the index value, ignoring the array entries 0,3,5,6,7 !
+ */
+ if (sUserDebugState.OnOff)
+ Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype;
+ else
+ Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype;
+
+ BCM_SHOW_DEBUG_BITMAP(Adapter);
+
+ }
+ break;
+ case IOCTL_BCM_NVM_READ:
+ case IOCTL_BCM_NVM_WRITE:
+ {
+
+ NVM_READWRITE stNVMReadWrite = {0};
+ PUCHAR pReadData = NULL;
+ PUCHAR pBuffertobeCopied = NULL;
+ ULONG ulDSDMagicNumInUsrBuff = 0 ;
+ struct timeval tv0, tv1;
+ memset(&tv0,0,sizeof(struct timeval));
+ memset(&tv1,0,sizeof(struct timeval));
+ if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0))
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ if(IsFlash2x(Adapter))
+ {
+ if((Adapter->eActiveDSD != DSD0) &&
+ (Adapter->eActiveDSD != DSD1) &&
+ (Adapter->eActiveDSD != DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked");
+ return STATUS_FAILURE ;
+ }
+ }
+
+ /* Copy Ioctl Buffer structure */
+
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copy_from_user failed\n");
+ Status = -EFAULT;
+ break;
+ }
+ if(IOCTL_BCM_NVM_READ == cmd)
+ pBuffertobeCopied = IoBuffer.OutputBuffer;
+ else
+ pBuffertobeCopied = IoBuffer.InputBuffer;
+
+ if(copy_from_user(&stNVMReadWrite, pBuffertobeCopied,sizeof(NVM_READWRITE)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ //
+ // Deny the access if the offset crosses the cal area limit.
+ //
+ if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize)
+ {
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset ,
+// stNVMReadWrite.uiNumBytes);
+ Status = STATUS_FAILURE;
+ break;
+ }
+
+ pReadData =(PCHAR)kmalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
+
+ if(!pReadData)
+ return -ENOMEM;
+
+ memset(pReadData,0,stNVMReadWrite.uiNumBytes);
+
+ if(copy_from_user(pReadData, stNVMReadWrite.pBuffer,
+ stNVMReadWrite.uiNumBytes))
+ {
+ Status = -EFAULT;
+ bcm_kfree(pReadData);
+ break;
+ }
+
+ do_gettimeofday(&tv0);
+ if(IOCTL_BCM_NVM_READ == cmd)
+ {
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadData);
+ return -EACCES;
+ }
+
+ Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
+ stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
+
+ up(&Adapter->NVMRdmWrmLock);
+
+ if(Status != STATUS_SUCCESS)
+ {
+ bcm_kfree(pReadData);
+ return Status;
+ }
+ if(copy_to_user((PCHAR)stNVMReadWrite.pBuffer,
+ (PCHAR)pReadData, (UINT)stNVMReadWrite.uiNumBytes))
+ {
+ bcm_kfree(pReadData);
+ Status = -EFAULT;
+ }
+ }
+ else
+ {
+
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadData);
+ return -EACCES;
+ }
+
+ Adapter->bHeaderChangeAllowed = TRUE ;
+ if(IsFlash2x(Adapter))
+ {
+ /*
+ New Requirement:-
+ DSD section updation will be allowed in two case:-
+ 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
+ 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
+ corrupted then user space program first modify the DSD header with valid DSD sig so
+ that this as well as further write may be worthwhile.
+
+ This restriction has been put assuming that if DSD sig is corrupted, DSD
+ data won't be considered valid.
+
+
+ */
+ Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD);
+ if(Status != STATUS_SUCCESS)
+ {
+ if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) ||
+ (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadData);
+ return Status;
+ }
+
+ ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
+ if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadData);
+ return Status;
+ }
+ }
+ }
+ Status = BeceemNVMWrite(Adapter, (PUINT )pReadData,
+ stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
+ if(IsFlash2x(Adapter))
+ BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD);
+
+ Adapter->bHeaderChangeAllowed = FALSE ;
+
+ up(&Adapter->NVMRdmWrmLock);
+
+
+ if(Status != STATUS_SUCCESS)
+ {
+ bcm_kfree(pReadData);
+ return Status;
+ }
+ }
+ do_gettimeofday(&tv1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000);
+
+
+ bcm_kfree(pReadData);
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ case IOCTL_BCM_FLASH2X_SECTION_READ :
+ {
+
+ FLASH2X_READWRITE sFlash2xRead = {0};
+ PUCHAR pReadBuff = NULL ;
+ UINT NOB = 0;
+ UINT BuffSize = 0;
+ UINT ReadBytes = 0;
+ UINT ReadOffset = 0;
+ PUCHAR OutPutBuff = NULL;
+
+ if(IsFlash2x(Adapter) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
+ return -EINVAL;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ return Status ;
+ }
+
+ //Reading FLASH 2.x READ structure
+ Status = copy_from_user((PUCHAR)&sFlash2xRead, (PUCHAR)IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Input Buffer failed");
+ return Status ;
+ }
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify);
+
+ //This was internal to driver for raw read. now it has ben exposed to user space app.
+ if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE)
+ return STATUS_FAILURE ;
+
+ NOB = sFlash2xRead.numOfBytes;
+ if(NOB > Adapter->uiSectorSize )
+ BuffSize = Adapter->uiSectorSize;
+ else
+ BuffSize = NOB ;
+
+ ReadOffset = sFlash2xRead.offset ;
+ OutPutBuff = (PUCHAR)(IoBuffer.OutputBuffer) ;
+
+
+ pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
+ if(pReadBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
+ return -ENOMEM;
+ }
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadBuff);
+ return -EACCES;
+ }
+
+ while(NOB)
+ {
+
+ if(NOB > Adapter->uiSectorSize )
+ ReadBytes = Adapter->uiSectorSize;
+ else
+ ReadBytes = NOB;
+
+
+ //Reading the data from Flash 2.x
+
+ Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status);
+ break ;
+ }
+
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
+
+ Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status);
+ break;
+ }
+ NOB = NOB - ReadBytes;
+ if(NOB)
+ {
+ ReadOffset = ReadOffset + ReadBytes ;
+ OutPutBuff = OutPutBuff + ReadBytes ;
+ }
+
+ }
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadBuff);
+
+ }
+ break ;
+ case IOCTL_BCM_FLASH2X_SECTION_WRITE :
+ {
+ FLASH2X_READWRITE sFlash2xWrite = {0};
+ PUCHAR pWriteBuff = NULL;
+ PUCHAR InputAddr = NULL;
+ UINT NOB = 0;
+ UINT BuffSize = 0;
+ UINT WriteOffset = 0;
+ UINT WriteBytes = 0;
+
+ if(IsFlash2x(Adapter) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
+ return -EINVAL;
+ }
+
+ //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite
+ Adapter->bAllDSDWriteAllow = FALSE;
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ return Status;
+ }
+
+ //Reading FLASH 2.x READ structure
+ Status = copy_from_user((PCHAR)&sFlash2xWrite, (PCHAR)IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reading of output Buffer from IOCTL buffer fails");
+ return Status;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify);
+ #if 0
+ if((sFlash2xWrite.Section == ISO_IMAGE1) ||(sFlash2xWrite.Section == ISO_IMAGE2) ||
+ (sFlash2xWrite.Section == DSD0) || (sFlash2xWrite.Section == DSD1) || (sFlash2xWrite.Section == DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"ISO/DSD Image write is not allowed.... ");
+ return STATUS_FAILURE ;
+ }
+ #endif
+ if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) &&
+ (sFlash2xWrite.Section != VSA2) )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed");
+ return -EINVAL;
+ }
+
+ if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE)
+ return STATUS_FAILURE ;
+
+ InputAddr = (PCHAR)(sFlash2xWrite.pDataBuff) ;
+ WriteOffset = sFlash2xWrite.offset ;
+ NOB = sFlash2xWrite.numOfBytes;
+
+ if(NOB > Adapter->uiSectorSize )
+ BuffSize = Adapter->uiSectorSize;
+ else
+ BuffSize = NOB ;
+
+ pWriteBuff = (PCHAR)kmalloc(BuffSize, GFP_KERNEL);
+ if(pWriteBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
+ return -ENOMEM;
+ }
+
+ //extracting the remainder of the given offset.
+ WriteBytes = Adapter->uiSectorSize ;
+ if(WriteOffset % Adapter->uiSectorSize)
+ WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
+ if(NOB < WriteBytes)
+ WriteBytes = NOB;
+
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pWriteBuff);
+ return -EACCES;
+ }
+
+ BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section);
+ do
+ {
+ Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status);
+ break ;
+ }
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes);
+ //Writing the data from Flash 2.x
+ Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
+ break ;
+ }
+
+ NOB = NOB - WriteBytes;
+ if(NOB)
+ {
+ WriteOffset = WriteOffset + WriteBytes ;
+ InputAddr = InputAddr + WriteBytes ;
+ if(NOB > Adapter->uiSectorSize )
+ WriteBytes = Adapter->uiSectorSize;
+ else
+ WriteBytes = NOB;
+ }
+
+
+ } while(NOB > 0);
+ BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section);
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pWriteBuff);
+ }
+ break ;
+ case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP :
+ {
+
+ PFLASH2X_BITMAP psFlash2xBitMap = NULL ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ return Status;
+ }
+ if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Structure size mismatch Lib :0x%lx Driver :0x%x ",IoBuffer.OutputLength, sizeof(FLASH2X_BITMAP));
+ break;
+ }
+
+ psFlash2xBitMap = (PFLASH2X_BITMAP)kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
+ if(psFlash2xBitMap == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available");
+ return -ENOMEM ;
+ }
+ //Reading the Flash Sectio Bit map
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(psFlash2xBitMap);
+ return -EACCES;
+ }
+
+ BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
+ up(&Adapter->NVMRdmWrmLock);
+ Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)psFlash2xBitMap, sizeof(FLASH2X_BITMAP));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed");
+ bcm_kfree(psFlash2xBitMap);
+ return Status;
+ }
+ bcm_kfree(psFlash2xBitMap);
+ }
+ break ;
+ case IOCTL_BCM_SET_ACTIVE_SECTION :
+ {
+ FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
+
+ if(IsFlash2x(Adapter) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
+ return -EINVAL;
+ }
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ return Status;
+ }
+
+ Status = copy_from_user((PCHAR)&eFlash2xSectionVal,(PCHAR)IoBuffer.InputBuffer, sizeof(INT));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
+ return Status;
+ }
+
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ return -EACCES;
+ }
+
+ Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status);
+ }
+ up(&Adapter->NVMRdmWrmLock);
+ }
+ break ;
+ case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION :
+ {
+ //Right Now we are taking care of only DSD
+ Adapter->bAllDSDWriteAllow = FALSE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
+
+ #if 0
+ SECTION_TYPE section = 0 ;
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION Called");
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of IOCTL BUFFER failed");
+ return Status;
+ }
+ Status = copy_from_user((PCHAR)section,(PCHAR)&IoBuffer, sizeof(INT));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of section type failed failed");
+ return Status;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", section);
+ if(section == DSD)
+ Adapter->ulFlashCalStart = Adapter->uiActiveDSDOffsetAtFwDld ;
+ else
+ Status = STATUS_FAILURE ;
+ #endif
+ Status = STATUS_SUCCESS ;
+ }
+ break ;
+ case IOCTL_BCM_COPY_SECTION :
+ {
+ FLASH2X_COPY_SECTION sCopySectStrut = {0};
+ Status = STATUS_SUCCESS;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called");
+
+ Adapter->bAllDSDWriteAllow = FALSE ;
+ if(IsFlash2x(Adapter) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
+ return -EINVAL;
+ }
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
+ return Status;
+ }
+
+ Status = copy_from_user((PCHAR)&sCopySectStrut,(PCHAR)IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
+ return Status;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes);
+
+
+ if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection);
+ return -EINVAL;
+ }
+
+ if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection);
+ return -EINVAL;
+ }
+
+ if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different");
+ return -EINVAL;
+ }
+
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ up(&Adapter->NVMRdmWrmLock);
+ return -EACCES;
+ }
+
+ if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2)
+ {
+ if(IsNonCDLessDevice(Adapter))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!");
+ Status = -EINVAL ;
+ }
+ else if(sCopySectStrut.numOfBytes == 0)
+ {
+ Status = BcmCopyISO(Adapter,sCopySectStrut);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed..");
+ Status = STATUS_FAILURE ;
+ }
+ up(&Adapter->NVMRdmWrmLock);
+ return Status;
+ }
+
+ Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
+ sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes);
+ up(&Adapter->NVMRdmWrmLock);
+ }
+ break ;
+ case IOCTL_BCM_GET_FLASH_CS_INFO :
+ {
+ Status = STATUS_SUCCESS;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ break;
+ }
+ if(Adapter->eNVMType != NVM_FLASH)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash");
+ Status = -EINVAL;
+ break;
+ }
+ if(IsFlash2x(Adapter) == TRUE)
+ {
+
+ if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. \nRequired size :0x%x ",IoBuffer.OutputLength, sizeof(FLASH2X_CS_INFO));
+ Status = -EINVAL;
+ break;
+ }
+
+ Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x cs info failed");
+ break;
+ }
+ }
+ else
+ {
+ if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. Required size :0x%u ",IoBuffer.OutputLength, sizeof(FLASH_CS_INFO));
+ Status = -EINVAL;
+ break;
+ }
+ Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash CS info failed");
+ break;
+ }
+
+ }
+ }
+ break ;
+ case IOCTL_BCM_SELECT_DSD :
+ {
+ UINT SectOfset = 0;
+ FLASH2X_SECTION_VAL eFlash2xSectionVal;
+ eFlash2xSectionVal = NO_SECTION_VAL ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called");
+
+ if(IsFlash2x(Adapter) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
+ return -EINVAL;
+ }
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ return Status;
+ }
+ Status = copy_from_user((PCHAR)&eFlash2xSectionVal,(PCHAR)IoBuffer.InputBuffer, sizeof(INT));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
+ return Status;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal);
+ if((eFlash2xSectionVal != DSD0) &&
+ (eFlash2xSectionVal != DSD1) &&
+ (eFlash2xSectionVal != DSD2) )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal);
+ return STATUS_FAILURE ;
+ }
+
+ SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
+ if(SectOfset == INVALID_OFFSET)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal);
+ return -EINVAL;
+ }
+
+ Adapter->bAllDSDWriteAllow = TRUE ;
+
+ Adapter->ulFlashCalStart = SectOfset ;
+ Adapter->eActiveDSD = eFlash2xSectionVal;
+ }
+ Status = STATUS_SUCCESS ;
+ break;
+
+ case IOCTL_BCM_NVM_RAW_READ :
+ {
+
+ NVM_READWRITE stNVMRead = {0};
+ INT NOB ;
+ INT BuffSize ;
+ INT ReadOffset = 0;
+ UINT ReadBytes = 0 ;
+ PUCHAR pReadBuff = NULL ;
+ PUCHAR OutPutBuff = NULL ;
+
+ if(Adapter->eNVMType != NVM_FLASH)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash ");
+ return -EINVAL ;
+ }
+
+ /* Copy Ioctl Buffer structure */
+ if(copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
+ Status = -EFAULT;
+ break;
+ }
+
+ if(copy_from_user(&stNVMRead, (PUCHAR)IoBuffer.OutputBuffer,sizeof(NVM_READWRITE)))
+ {
+ Status = -EFAULT;
+ break;
+ }
+
+ NOB = stNVMRead.uiNumBytes;
+ //In Raw-Read max Buff size : 64MB
+
+ if(NOB > DEFAULT_BUFF_SIZE)
+ BuffSize = DEFAULT_BUFF_SIZE;
+ else
+ BuffSize = NOB ;
+
+ ReadOffset = stNVMRead.uiOffset ;
+ OutPutBuff = (PUCHAR)(stNVMRead.pBuffer) ;
+
+
+ pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
+ if(pReadBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
+ Status = -ENOMEM;
+ break;
+ }
+ down(&Adapter->NVMRdmWrmLock);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
+ bcm_kfree(pReadBuff);
+ up(&Adapter->NVMRdmWrmLock);
+ return -EACCES;
+ }
+
+ Adapter->bFlashRawRead = TRUE ;
+ while(NOB)
+ {
+ if(NOB > DEFAULT_BUFF_SIZE )
+ ReadBytes = DEFAULT_BUFF_SIZE;
+ else
+ ReadBytes = NOB;
+
+ //Reading the data from Flash 2.x
+ Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
+ break;
+ }
+
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
+
+ Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status);
+ break;
+ }
+ NOB = NOB - ReadBytes;
+ if(NOB)
+ {
+ ReadOffset = ReadOffset + ReadBytes ;
+ OutPutBuff = OutPutBuff + ReadBytes ;
+ }
+
+ }
+ Adapter->bFlashRawRead = FALSE ;
+ up(&Adapter->NVMRdmWrmLock);
+ bcm_kfree(pReadBuff);
+ break ;
+ }
+
+ case IOCTL_BCM_CNTRLMSG_MASK:
+ {
+ ULONG RxCntrlMsgBitMask = 0 ;
+
+ /* Copy Ioctl Buffer structure */
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space");
+ break;
+ }
+
+ Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space");
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
+ pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ;
+ }
+ break;
+ case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
+ {
+ DEVICE_DRIVER_INFO DevInfo;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
+
+ DevInfo.MaxRDMBufferSize = BUFFER_4K;
+ DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
+ DevInfo.u32RxAlignmentCorrection = 0;
+ DevInfo.u32NVMType = Adapter->eNVMType;
+ DevInfo.u32InterfaceType = BCM_USB;
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ break;
+ }
+ if(IoBuffer.OutputLength < sizeof(DevInfo))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length is less than actural buffer size");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"user passed buffer size :0x%lX, expected size :0x%x",IoBuffer.OutputLength, sizeof(DevInfo));
+ Status = -EINVAL;
+ break;
+ }
+ Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)&DevInfo, sizeof(DevInfo));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying Dev info structure to user space buffer failed");
+ break;
+ }
+ }
+ break ;
+
+ case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
+ {
+ ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
+ struct timeval tv = {0} ;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
+
+ Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+ break;
+ }
+ if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length:0x%lx is less than expected buff size :0x%X",IoBuffer.OutputLength,sizeof(ST_TIME_ELAPSED));
+ Status = -EINVAL;
+ break;
+ }
+
+ //stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = Adapter->liTimeSinceLastNetEntry;
+ do_gettimeofday(&tv);
+ stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = tv.tv_sec - Adapter->liTimeSinceLastNetEntry;
+
+ Status = copy_to_user((PCHAR)IoBuffer.OutputBuffer, (PCHAR)&stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying ST_TIME_ELAPSED structure to user space buffer failed");
+ break;
+ }
+
+ }
+ break;
+
+ default:
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "wrong input %x",cmd);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In default ioctl %d\n", cmd);
+ Status = STATUS_FAILURE;
+
+ break;
+ }
+ return Status;
+}
+
+
+static struct file_operations bcm_fops = {
+ .owner = THIS_MODULE,
+ .open = bcm_char_open,
+ .release = bcm_char_release,
+ .read = bcm_char_read,
+ .unlocked_ioctl = bcm_char_ioctl,
+};
+
+
+int register_control_device_interface(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->major>0)
+ return Adapter->major;
+ Adapter->major = register_chrdev(0, "tarang", &bcm_fops);
+ if(Adapter->major < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "register_chrdev:Failed to registering WiMax control char device!");
+ return Adapter->major;
+ }
+
+ bcm_class = NULL;
+ bcm_class = class_create (THIS_MODULE, "tarang");
+ if(IS_ERR (bcm_class))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unable to create class\n");
+ unregister_chrdev(Adapter->major, "tarang");
+ Adapter->major = 0;
+ return -ENODEV;
+ }
+ Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL,
+ MKDEV(Adapter->major, 0),
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
+ NULL ,
+#endif
+ "tarang");
+
+ if(IS_ERR(Adapter->pstCreatedClassDevice))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "class device did not get created : %ld", PTR_ERR(Adapter->pstCreatedClassDevice) );
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Got Major No: %d", Adapter->major);
+ return 0;
+}
+
+void unregister_control_device_interface(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->major > 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying class device");
+ device_destroy (bcm_class, MKDEV(Adapter->major, 0));
+ }
+ if(!IS_ERR(bcm_class))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying created class ");
+ class_destroy (bcm_class);
+ bcm_class = NULL;
+ }
+ if(Adapter->major > 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"unregistering character interface");
+ unregister_chrdev(Adapter->major, "tarang");
+ }
+
+}
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c
new file mode 100644
index 000000000000..d4f4800ca5dd
--- /dev/null
+++ b/drivers/staging/bcm/Bcmnet.c
@@ -0,0 +1,266 @@
+#include "headers.h"
+
+static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev)
+{
+ struct net_device *ndev = (struct net_device*)dev;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ //PMINI_ADAPTER Adapter = (PMINI_ADAPTER)ndev->priv;
+ if(strncmp(ndev->name,gblpnetdev->name,5)==0)
+ {
+ switch(event)
+ {
+ case NETDEV_CHANGEADDR:
+ case NETDEV_GOING_DOWN:
+ /*ignore this */
+ break;
+ case NETDEV_DOWN:
+ break;
+
+ case NETDEV_UP:
+ break;
+
+ case NETDEV_REGISTER:
+ /* Increment the Reference Count for "veth0" */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n",
+ atomic_read(&ndev->refcnt));
+ atomic_inc(&ndev->refcnt);
+ break;
+
+ case NETDEV_UNREGISTER:
+ /* Decrement the Reference Count for "veth0" */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n",
+ atomic_read(&ndev->refcnt));
+ atomic_dec(&ndev->refcnt);
+ if((int)atomic_read(&ndev->refcnt) < 0)
+ atomic_set(&ndev->refcnt, 0);
+ break;
+ };
+ }
+ return NOTIFY_DONE;
+}
+
+/* Notifier block to receive netdevice events */
+static struct notifier_block bcm_notifier_block =
+{
+ .notifier_call = bcm_notify_event,
+};
+
+struct net_device *gblpnetdev;
+/***************************************************************************************/
+/* proto-type of lower function */
+#ifdef BCM_SHM_INTERFACE
+const char *bcmVirtDeviceName="bcmeth";
+#endif
+
+static INT bcm_open(struct net_device *dev)
+{
+ PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
+ Adapter = GET_BCM_ADAPTER(dev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
+ if(Adapter->fw_download_done==FALSE)
+ return -EINVAL;
+ Adapter->if_up=1;
+ if(Adapter->LinkUpStatus == 1){
+ if(netif_queue_stopped(Adapter->dev)){
+ netif_carrier_on(Adapter->dev);
+ netif_start_queue(Adapter->dev);
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
+ return 0;
+}
+
+static INT bcm_close(struct net_device *dev)
+{
+ PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
+ Adapter = GET_BCM_ADAPTER(dev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
+ Adapter->if_up=0;
+ if(!netif_queue_stopped(dev)) {
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
+ return 0;
+}
+
+static struct net_device_stats *bcm_get_stats(struct net_device *dev)
+{
+ PLINUX_DEP_DATA pLinuxData=NULL;
+ PMINI_ADAPTER Adapter = NULL ;// gpadapter ;
+ Adapter = GET_BCM_ADAPTER(dev);
+ pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData);
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData);
+ pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs;
+ pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount);
+ pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount);
+ pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount);
+ pLinuxData->netstats.rx_length_errors=0;
+ pLinuxData->netstats.rx_frame_errors=0;
+ pLinuxData->netstats.rx_crc_errors=0;
+ pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount);
+ pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount);
+ pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount);
+
+ return &(pLinuxData->netstats);
+}
+/**
+@ingroup init_functions
+Register other driver entry points with the kernel
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+struct net_device_ops bcmNetDevOps = {
+ .ndo_open = bcm_open,
+ .ndo_stop = bcm_close,
+ .ndo_get_stats = bcm_get_stats,
+ .ndo_start_xmit = bcm_transmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+#endif
+
+int register_networkdev(PMINI_ADAPTER Adapter)
+{
+ int result=0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ int *temp = NULL ;
+#endif
+ Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER));
+ if(!Adapter->dev)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev");
+ return -ENOMEM;
+ }
+ gblpnetdev = Adapter->dev;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+ Adapter->dev->priv = Adapter;
+#else
+ temp = netdev_priv(Adapter->dev);
+ *temp = (UINT)Adapter;
+#endif
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ Adapter->dev->netdev_ops = &bcmNetDevOps;
+#else
+ Adapter->dev->open = bcm_open;
+ Adapter->dev->stop = bcm_close;
+ Adapter->dev->get_stats = bcm_get_stats;
+ Adapter->dev->hard_start_xmit = bcm_transmit;
+ Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE;
+#endif
+
+#ifndef BCM_SHM_INTERFACE
+ Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */
+ /* Read the MAC Address from EEPROM */
+ ReadMacAddressFromNVM(Adapter);
+
+
+ /* Register the notifier block for getting netdevice events */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n");
+ result = register_netdevice_notifier(&bcm_notifier_block);
+ if(result)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered");
+ Adapter->bNetdeviceNotifierRegistered = FALSE;
+ return result;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered");
+ Adapter->bNetdeviceNotifierRegistered = TRUE;
+ }
+
+#else
+
+ Adapter->dev->mtu = CPE_MTU_SIZE;
+
+#if 0
+ //for CPE - harcode the virtual mac address
+ Adapter->dev->dev_addr[0] = MII_WIMAX_MACADDRESS[0];
+ Adapter->dev->dev_addr[1] = MII_WIMAX_MACADDRESS[1];
+ Adapter->dev->dev_addr[2] = MII_WIMAX_MACADDRESS[2];
+ Adapter->dev->dev_addr[3] = MII_WIMAX_MACADDRESS[3];
+ Adapter->dev->dev_addr[4] = MII_WIMAX_MACADDRESS[4];
+ Adapter->dev->dev_addr[5] = MII_WIMAX_MACADDRESS[5];
+#else
+ ReadMacAddressFromNVM(Adapter);
+#endif
+ strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name
+
+#endif
+
+ result = register_netdev(Adapter->dev);
+ if (!result)
+ {
+ Adapter->bNetworkInterfaceRegistered = TRUE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!");
+ Adapter->bNetworkInterfaceRegistered = FALSE ;
+ return result;
+ }
+
+#if 0
+ Adapter->stDebugState.debug_level = DBG_LVL_CURR;
+ Adapter->stDebugState.type =(UINT)0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff;
+
+ printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]);
+#endif
+
+ return 0;
+}
+
+void bcm_unregister_networkdev(PMINI_ADAPTER Adapter)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n");
+ if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
+ unregister_netdev(Adapter->dev);
+ /* Unregister the notifier block */
+ if(Adapter->bNetdeviceNotifierRegistered == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
+ unregister_netdevice_notifier(&bcm_notifier_block);
+ }
+}
+
+static int bcm_init(void)
+{
+ int result;
+ result = InterfaceInitialize();
+ if(result)
+ {
+ printk("Initialisation failed for usbbcm");
+ }
+ else
+ {
+ printk("Initialised usbbcm");
+ }
+ return result;
+}
+
+
+static void bcm_exit(void)
+{
+ printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
+ InterfaceExit();
+ printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
+}
+
+module_init(bcm_init);
+module_exit(bcm_exit);
+MODULE_LICENSE ("GPL");
+
+
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
new file mode 100644
index 000000000000..d1a668339982
--- /dev/null
+++ b/drivers/staging/bcm/CmHost.c
@@ -0,0 +1,2443 @@
+/************************************************************
+* CMHOST.C
+* This file contains the routines for handling Connnection
+* Management.
+************************************************************/
+
+//#define CONN_MSG
+#include "headers.h"
+
+typedef enum _E_CLASSIFIER_ACTION
+{
+ eInvalidClassifierAction,
+ eAddClassifier,
+ eReplaceClassifier,
+ eDeleteClassifier
+}E_CLASSIFIER_ACTION;
+
+
+/************************************************************
+* Function - SearchSfid
+*
+* Description - This routinue would search QOS queues having
+* specified SFID as input parameter.
+*
+* Parameters - Adapter: Pointer to the Adapter structure
+* uiSfid : Given SFID for matching
+*
+* Returns - Queue index for this SFID(If matched)
+ Else Invalid Queue Index(If Not matched)
+************************************************************/
+__inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
+{
+ INT iIndex=0;
+ for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--)
+ if(Adapter->PackInfo[iIndex].ulSFID==uiSfid)
+ return iIndex;
+ return NO_OF_QUEUES+1;
+}
+
+/***************************************************************
+* Function - SearchFreeSfid
+*
+* Description - This routinue would search Free available SFID.
+*
+* Parameter - Adapter: Pointer to the Adapter structure
+*
+* Returns - Queue index for the free SFID
+* Else returns Invalid Index.
+****************************************************************/
+__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter)
+{
+ UINT uiIndex=0;
+ for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
+ if(Adapter->PackInfo[uiIndex].ulSFID==0)
+ return uiIndex;
+ return NO_OF_QUEUES+1;
+}
+
+__inline int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
+{
+ int iIndex=0;
+ for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
+ if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
+ return iIndex;
+ return NO_OF_QUEUES+1;
+
+}
+
+
+/*
+Function: SearchClsid
+Description: This routinue would search Classifier having specified ClassifierID as input parameter
+Input parameters: PMINI_ADAPTER Adapter - Adapter Context
+ unsigned int uiSfid - The SF in which the classifier is to searched
+ B_UINT16 uiClassifierID - The classifier ID to be searched
+Return: int :Classifier table index of matching entry
+*/
+
+__inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID)
+{
+ unsigned int uiClassifierIndex = 0;
+ for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
+ {
+ if((Adapter->astClassifierTable[uiClassifierIndex].bUsed) &&
+ (Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID)&&
+ (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == ulSFID))
+ return uiClassifierIndex;
+ }
+ return MAX_CLASSIFIERS+1;
+}
+
+/**
+@ingroup ctrl_pkt_functions
+This routinue would search Free available Classifier entry in classifier table.
+@return free Classifier Entry index in classifier table for specified SF
+*/
+static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
+ )
+{
+ unsigned int uiClassifierIndex = 0;
+ for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
+ {
+ if(!Adapter->astClassifierTable[uiClassifierIndex].bUsed)
+ return uiClassifierIndex;
+ }
+ return MAX_CLASSIFIERS+1;
+}
+
+VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
+{
+ //deleting all the packet held in the SF
+ flush_queue(Adapter,uiSearchRuleIndex);
+
+ //Deleting the all classifiers for this SF
+ DeleteAllClassifiersForSF(Adapter,uiSearchRuleIndex);
+
+ //Resetting only MIBS related entries in the SF
+ memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE));
+}
+
+static inline VOID
+CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry ,
+ B_UINT8 u8IpAddressLen , B_UINT8 *pu8IpAddressMaskSrc ,
+ BOOLEAN bIpVersion6 , E_IPADDR_CONTEXT eIpAddrContext)
+{
+ UINT ucLoopIndex=0;
+ UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS;
+ UCHAR *ptrClassifierIpAddress = NULL;
+ UCHAR *ptrClassifierIpMask = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ if(bIpVersion6)
+ {
+ nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES;
+ }
+ //Destination Ip Address
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Address Range Length:0x%X ",
+ u8IpAddressLen);
+ if((bIpVersion6?(IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2):
+ (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen)
+ {
+ /*
+ //checking both the mask and address togethor in Classification.
+ //So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2
+ //(nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask)
+ */
+ if(eIpAddrContext == eDestIpAddress)
+ {
+ pstClassifierEntry->ucIPDestinationAddressLength =
+ u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
+ if(bIpVersion6)
+ {
+ ptrClassifierIpAddress =
+ pstClassifierEntry->stDestIpAddress.ucIpv6Address;
+ ptrClassifierIpMask =
+ pstClassifierEntry->stDestIpAddress.ucIpv6Mask;
+ }
+ else
+ {
+ ptrClassifierIpAddress =
+ pstClassifierEntry->stDestIpAddress.ucIpv4Address;
+ ptrClassifierIpMask =
+ pstClassifierEntry->stDestIpAddress.ucIpv4Mask;
+ }
+ }
+ else if(eIpAddrContext == eSrcIpAddress)
+ {
+ pstClassifierEntry->ucIPSourceAddressLength =
+ u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
+ if(bIpVersion6)
+ {
+ ptrClassifierIpAddress =
+ pstClassifierEntry->stSrcIpAddress.ucIpv6Address;
+ ptrClassifierIpMask =
+ pstClassifierEntry->stSrcIpAddress.ucIpv6Mask;
+ }
+ else
+ {
+ ptrClassifierIpAddress =
+ pstClassifierEntry->stSrcIpAddress.ucIpv4Address;
+ ptrClassifierIpMask =
+ pstClassifierEntry->stSrcIpAddress.ucIpv4Mask;
+ }
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Address Length:0x%X \n",
+ pstClassifierEntry->ucIPDestinationAddressLength);
+ while((u8IpAddressLen>= nSizeOfIPAddressInBytes) &&
+ (ucLoopIndex < MAX_IP_RANGE_LENGTH))
+ {
+ memcpy(ptrClassifierIpAddress +
+ (ucLoopIndex * nSizeOfIPAddressInBytes),
+ (pu8IpAddressMaskSrc+(ucLoopIndex*nSizeOfIPAddressInBytes*2)),
+ nSizeOfIPAddressInBytes);
+ if(!bIpVersion6)
+ {
+ if(eIpAddrContext == eSrcIpAddress)
+ {
+ pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]=
+ ntohl(pstClassifierEntry->stSrcIpAddress.
+ ulIpv4Addr[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]);
+ }
+ else if(eIpAddrContext == eDestIpAddress)
+ {
+ pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress.
+ ulIpv4Addr[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]);
+ }
+ }
+ u8IpAddressLen-=nSizeOfIPAddressInBytes;
+ if(u8IpAddressLen >= nSizeOfIPAddressInBytes)
+ {
+ memcpy(ptrClassifierIpMask +
+ (ucLoopIndex * nSizeOfIPAddressInBytes),
+ (pu8IpAddressMaskSrc+nSizeOfIPAddressInBytes +
+ (ucLoopIndex*nSizeOfIPAddressInBytes*2)),
+ nSizeOfIPAddressInBytes);
+ if(!bIpVersion6)
+ {
+ if(eIpAddrContext == eSrcIpAddress)
+ {
+ pstClassifierEntry->stSrcIpAddress.
+ ulIpv4Mask[ucLoopIndex]=
+ ntohl(pstClassifierEntry->stSrcIpAddress.
+ ulIpv4Mask[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Mask Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]);
+ }
+ else if(eIpAddrContext == eDestIpAddress)
+ {
+ pstClassifierEntry->stDestIpAddress.
+ ulIpv4Mask[ucLoopIndex] =
+ ntohl(pstClassifierEntry->stDestIpAddress.
+ ulIpv4Mask[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Mask Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]);
+ }
+ }
+ u8IpAddressLen-=nSizeOfIPAddressInBytes;
+ }
+ if(0==u8IpAddressLen)
+ {
+ pstClassifierEntry->bDestIpValid=TRUE;
+ }
+ ucLoopIndex++;
+ }
+ if(bIpVersion6)
+ {
+ //Restore EndianNess of Struct
+ for(ucLoopIndex =0 ; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4 ;
+ ucLoopIndex++)
+ {
+ if(eIpAddrContext == eSrcIpAddress)
+ {
+ pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]=
+ ntohl(pstClassifierEntry->stSrcIpAddress.
+ ulIpv6Addr[ucLoopIndex]);
+ pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stSrcIpAddress.
+ ulIpv6Mask[ucLoopIndex]);
+ }
+ else if(eIpAddrContext == eDestIpAddress)
+ {
+ pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress.
+ ulIpv6Addr[ucLoopIndex]);
+ pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress.
+ ulIpv6Mask[ucLoopIndex]);
+ }
+ }
+ }
+ }
+}
+
+
+void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll)
+{
+ ULONG ulIndex;
+ for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++)
+ {
+ if(Adapter->astTargetDsxBuffer[ulIndex].valid)
+ continue;
+ if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)){
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n",
+ TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer);
+ Adapter->astTargetDsxBuffer[ulIndex].valid=1;
+ Adapter->astTargetDsxBuffer[ulIndex].tid=0;
+ Adapter->ulFreeTargetBufferCnt++;
+ }
+ }
+}
+
+/**
+@ingroup ctrl_pkt_functions
+copy classifier rule into the specified SF index
+*/
+static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLTypes *psfCSType,UINT uiSearchRuleIndex,UINT nClassifierIndex)
+{
+ S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
+ //VOID *pvPhsContext = NULL;
+ UINT ucLoopIndex=0;
+ //UCHAR ucProtocolLength=0;
+ //ULONG ulPhsStatus;
+
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 ||
+ nClassifierIndex > (MAX_CLASSIFIERS-1))
+ return;
+
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Storing Classifier Rule Index : %X",ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex));
+
+ if(nClassifierIndex > MAX_CLASSIFIERS-1)
+ return;
+
+ pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
+ if(pstClassifierEntry)
+ {
+ //Store if Ipv6
+ pstClassifierEntry->bIpv6Protocol =
+ (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE;
+
+ //Destinaiton Port
+ pstClassifierEntry->ucDestPortRangeLength=psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength/4;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Length:0x%X ",pstClassifierEntry->ucDestPortRangeLength);
+ if( MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength)
+ {
+ for(ucLoopIndex=0;ucLoopIndex<(pstClassifierEntry->ucDestPortRangeLength);ucLoopIndex++)
+ {
+ pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] =
+ *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex));
+ pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] =
+ *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+ucLoopIndex));
+ pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Lo:0x%X ",pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]);
+ pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]);
+ }
+ }
+ else
+ {
+ pstClassifierEntry->ucDestPortRangeLength=0;
+ }
+ //Source Port
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Length:0x%X ",psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+ if(MAX_PORT_RANGE >=
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength)
+ {
+ pstClassifierEntry->ucSrcPortRangeLength =
+ psfCSType->cCPacketClassificationRule.
+ u8ProtocolSourcePortRangeLength/4;
+ for(ucLoopIndex = 0; ucLoopIndex <
+ (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++)
+ {
+ pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] =
+ *((PUSHORT)(psfCSType->cCPacketClassificationRule.
+ u8ProtocolSourcePortRange+ucLoopIndex));
+ pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] =
+ *((PUSHORT)(psfCSType->cCPacketClassificationRule.
+ u8ProtocolSourcePortRange+2+ucLoopIndex));
+ pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] =
+ ntohs(pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Lo:0x%X ",pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]);
+ pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]);
+ }
+ }
+ //Destination Ip Address and Mask
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Destination Parameters : ");
+
+ CopyIpAddrToClassifier(pstClassifierEntry,
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength,
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddress,
+ (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?
+ TRUE:FALSE, eDestIpAddress);
+
+ //Source Ip Address and Mask
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Source Parameters : ");
+
+ CopyIpAddrToClassifier(pstClassifierEntry,
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength,
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress,
+ (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE,
+ eSrcIpAddress);
+
+ //TOS
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"TOS Length:0x%X ",psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+ if(3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength)
+ {
+ pstClassifierEntry->ucIPTypeOfServiceLength =
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength;
+ pstClassifierEntry->ucTosLow =
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0];
+ pstClassifierEntry->ucTosHigh =
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1];
+ pstClassifierEntry->ucTosMask =
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2];
+ pstClassifierEntry->bTOSValid = TRUE;
+ }
+ if(psfCSType->cCPacketClassificationRule.u8Protocol == 0)
+ {
+ //we didnt get protocol field filled in by the BS
+ pstClassifierEntry->ucProtocolLength=0;
+ }
+ else
+ {
+ pstClassifierEntry->ucProtocolLength=1;// 1 valid protocol
+ }
+
+ pstClassifierEntry->ucProtocol[0] =
+ psfCSType->cCPacketClassificationRule.u8Protocol;
+
+ pstClassifierEntry->u8ClassifierRulePriority =
+ psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority;
+
+ //store the classifier rule ID and set this classifier entry as valid
+ pstClassifierEntry->ucDirection =
+ Adapter->PackInfo[uiSearchRuleIndex].ucDirection;
+ pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType->
+ cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+ pstClassifierEntry->usVCID_Value =
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
+ pstClassifierEntry->ulSFID =
+ Adapter->PackInfo[uiSearchRuleIndex].ulSFID;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n",
+ uiSearchRuleIndex, pstClassifierEntry->ucDirection,
+ pstClassifierEntry->uiClassifierRuleIndex,
+ pstClassifierEntry->usVCID_Value);
+
+ if(psfCSType->cCPacketClassificationRule.u8AssociatedPHSI)
+ {
+ pstClassifierEntry->u8AssociatedPHSI = psfCSType->cCPacketClassificationRule.u8AssociatedPHSI;
+ }
+
+ //Copy ETH CS Parameters
+ pstClassifierEntry->ucEthCSSrcMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddressLength);
+ memcpy(pstClassifierEntry->au8EThCSSrcMAC,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress,MAC_ADDRESS_SIZE);
+ memcpy(pstClassifierEntry->au8EThCSSrcMACMask,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE);
+ pstClassifierEntry->ucEthCSDestMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+ memcpy(pstClassifierEntry->au8EThCSDestMAC,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress,MAC_ADDRESS_SIZE);
+ memcpy(pstClassifierEntry->au8EThCSDestMACMask,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE);
+ pstClassifierEntry->ucEtherTypeLen = (psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+ memcpy(pstClassifierEntry->au8EthCSEtherType,psfCSType->cCPacketClassificationRule.u8Ethertype,NUM_ETHERTYPE_BYTES);
+ memcpy(pstClassifierEntry->usUserPriority, &psfCSType->cCPacketClassificationRule.u16UserPriority, 2);
+ pstClassifierEntry->usVLANID = ntohs(psfCSType->cCPacketClassificationRule.u16VLANID);
+ pstClassifierEntry->usValidityBitMap = ntohs(psfCSType->cCPacketClassificationRule.u16ValidityBitMap);
+
+ pstClassifierEntry->bUsed = TRUE;
+ }
+}
+
+
+/**
+@ingroup ctrl_pkt_functions
+*/
+static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex,UINT nClassifierIndex)
+{
+ S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
+ B_UINT16 u16PacketClassificationRuleIndex;
+ USHORT usVCID;
+ //VOID *pvPhsContext = NULL;
+ //ULONG ulPhsStatus;
+
+ usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
+
+ if(nClassifierIndex > MAX_CLASSIFIERS-1)
+ return;
+
+ if(usVCID == 0)
+ return;
+
+ u16PacketClassificationRuleIndex = Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex;
+
+
+ pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
+ if(pstClassifierEntry)
+ {
+ pstClassifierEntry->bUsed = FALSE;
+ pstClassifierEntry->uiClassifierRuleIndex = 0;
+ memset(pstClassifierEntry,0,sizeof(S_CLASSIFIER_RULE));
+
+ //Delete the PHS Rule for this classifier
+ PhsDeleteClassifierRule(
+ &Adapter->stBCMPhsContext,
+ usVCID,
+ u16PacketClassificationRuleIndex);
+ }
+}
+
+/**
+@ingroup ctrl_pkt_functions
+*/
+VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex)
+{
+ S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
+ UINT nClassifierIndex;
+ //B_UINT16 u16PacketClassificationRuleIndex;
+ USHORT ulVCID;
+ //VOID *pvPhsContext = NULL;
+ //ULONG ulPhsStatus;
+
+ ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
+
+ if(ulVCID == 0)
+ return;
+
+
+ for(nClassifierIndex =0 ; nClassifierIndex < MAX_CLASSIFIERS ; nClassifierIndex++)
+ {
+ if(Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID)
+ {
+ pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
+ if(pstClassifierEntry->bUsed)
+ {
+ DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex);
+ }
+ }
+ }
+
+ //Delete All Phs Rules Associated with this SF
+ PhsDeleteSFRules(
+ &Adapter->stBCMPhsContext,
+ ulVCID);
+
+}
+
+
+/**
+This routinue copies the Connection Management
+related data into the Adapter structure.
+@ingroup ctrl_pkt_functions
+*/
+
+static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
+ register pstServiceFlowParamSI psfLocalSet, /**<Pointer to the ServiceFlowParamSI structure*/
+ register UINT uiSearchRuleIndex, /**<Index of Queue, to which this data belongs*/
+ register UCHAR ucDsxType,
+ stLocalSFAddIndicationAlt *pstAddIndication)
+{
+ //UCHAR ucProtocolLength=0;
+ ULONG ulSFID;
+ UINT nClassifierIndex = 0;
+ E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction;
+ B_UINT16 u16PacketClassificationRuleIndex=0;
+ UINT nIndex=0;
+ stConvergenceSLTypes *psfCSType = NULL;
+ S_PHS_RULE sPhsRule;
+ USHORT uVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
+ UINT UGIValue = 0;
+
+
+ Adapter->PackInfo[uiSearchRuleIndex].bValid=TRUE;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s: SFID= %x ",__FUNCTION__, ntohl(psfLocalSet->u32SFID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Updating Queue %d",uiSearchRuleIndex);
+
+ ulSFID = ntohl(psfLocalSet->u32SFID);
+ //Store IP Version used
+ //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF
+
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = 0;
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0;
+
+ /*Enable IP/ETh CS Support As Required*/
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : u8CSSpecification : %X\n",psfLocalSet->u8CSSpecification);
+ switch(psfLocalSet->u8CSSpecification)
+ {
+ case eCSPacketIPV4:
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+ break;
+ }
+ case eCSPacketIPV6:
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
+ break;
+ }
+
+ case eCS802_3PacketEthernet:
+ case eCS802_1QPacketVLAN:
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+ break;
+ }
+
+ case eCSPacketIPV4Over802_1QVLAN:
+ case eCSPacketIPV4Over802_3Ethernet:
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+ break;
+ }
+
+ case eCSPacketIPV6Over802_1QVLAN:
+ case eCSPacketIPV6Over802_3Ethernet:
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+ break;
+ }
+
+ default:
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error in value of CS Classification.. setting default to IP CS\n");
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+ break;
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X \n",
+ uiSearchRuleIndex,
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport,
+ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport);
+
+ //Store IP Version used
+ //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF
+ if(Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV6;
+ }
+ else
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV4;
+ }
+
+ /* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */
+ if(!Adapter->bETHCSEnabled)
+ Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0;
+
+ if(psfLocalSet->u8ServiceClassNameLength > 0 &&
+ psfLocalSet->u8ServiceClassNameLength < 32)
+ {
+ memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName,
+ psfLocalSet->u8ServiceClassName,
+ psfLocalSet->u8ServiceClassNameLength);
+ }
+ Adapter->PackInfo[uiSearchRuleIndex].u8QueueType =
+ psfLocalSet->u8ServiceFlowSchedulingType;
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].u8QueueType==BE &&
+ Adapter->PackInfo[uiSearchRuleIndex].ucDirection)
+ {
+ Adapter->usBestEffortQueueIndex=uiSearchRuleIndex;
+ }
+
+ Adapter->PackInfo[uiSearchRuleIndex].ulSFID = ntohl(psfLocalSet->u32SFID);
+
+ Adapter->PackInfo[uiSearchRuleIndex].u8TrafficPriority = psfLocalSet->u8TrafficPriority;
+
+ //copy all the classifier in the Service Flow param structure
+ for(nIndex=0; nIndex<psfLocalSet->u8TotalClassifiers; nIndex++)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex);
+ psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex];
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex);
+
+ if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE;
+ }
+
+ if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE;
+ }
+
+
+ if(ucDsxType== DSA_ACK)
+ {
+ eClassifierAction = eAddClassifier;
+ }
+ else if(ucDsxType == DSC_ACK)
+ {
+ switch(psfCSType->u8ClassfierDSCAction)
+ {
+ case 0://DSC Add Classifier
+ {
+ eClassifierAction = eAddClassifier;
+ }
+ break;
+ case 1://DSC Replace Classifier
+ {
+ eClassifierAction = eReplaceClassifier;
+ }
+ break;
+ case 2://DSC Delete Classifier
+ {
+ eClassifierAction = eDeleteClassifier;
+
+ }
+ break;
+ default:
+ {
+ eClassifierAction = eInvalidClassifierAction;
+ }
+ }
+ }
+
+ u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+ switch(eClassifierAction)
+ {
+ case eAddClassifier:
+ {
+ //Get a Free Classifier Index From Classifier table for this SF to add the Classifier
+ //Contained in this message
+ nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
+
+ if(nClassifierIndex > MAX_CLASSIFIERS)
+ {
+ nClassifierIndex = SearchFreeClsid(Adapter);
+ if(nClassifierIndex > MAX_CLASSIFIERS)
+ {
+ //Failed To get a free Entry
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Failed To get a free Classifier Entry");
+ break;
+ }
+ //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF.
+ CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex);
+ }
+
+ else
+ {
+ //This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Error The Specified Classifier Already Exists \
+ and attempted To Add Classifier with Same PCRI : 0x%x\n", u16PacketClassificationRuleIndex);
+ }
+ }
+ break;
+
+ case eReplaceClassifier:
+ {
+ //Get the Classifier Index From Classifier table for this SF and replace existing Classifier
+ //with the new classifier Contained in this message
+ nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
+ if(nClassifierIndex > MAX_CLASSIFIERS)
+ {
+ //Failed To search the classifier
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be replaced failed");
+ break;
+ }
+ //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF.
+ CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex);
+ }
+ break;
+
+ case eDeleteClassifier:
+ {
+ //Get the Classifier Index From Classifier table for this SF and replace existing Classifier
+ //with the new classifier Contained in this message
+ nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
+ if(nClassifierIndex > MAX_CLASSIFIERS)
+ {
+ //Failed To search the classifier
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be deleted failed");
+ break;
+ }
+
+ //Delete This classifier
+ DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex);
+ }
+ break;
+
+ default:
+ {
+ //Invalid Action for classifier
+ break;
+ }
+ }
+ }
+
+ //Repeat parsing Classification Entries to process PHS Rules
+ for(nIndex=0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++)
+ {
+ psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex];
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n",
+ psfCSType->u8PhsDSCAction );
+
+ switch (psfCSType->u8PhsDSCAction)
+ {
+ case eDeleteAllPHSRules:
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Deleting All PHS Rules For VCID: 0x%X\n",uVCID);
+
+ //Delete All the PHS rules for this Service flow
+
+ PhsDeleteSFRules(
+ &Adapter->stBCMPhsContext,
+ uVCID);
+
+ break;
+ }
+ case eDeletePHSRule:
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"PHS DSC Action = Delete PHS Rule \n");
+
+ if(psfCSType->cPhsRule.u8PHSI)
+ {
+ PhsDeletePHSRule(
+ &Adapter->stBCMPhsContext,
+ uVCID,
+ psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+ }
+ else
+ {
+ //BCM_DEBUG_PRINT(CONN_MSG,("Error CPHSRule.PHSI is ZERO \n"));
+ }
+ break;
+ }
+ default :
+ {
+ if(ucDsxType == DSC_ACK)
+ {
+ //BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC \n",psfCSType->cPhsRule.u8PHSI));
+ break; //FOr DSC ACK Case PHS DSC Action must be in valid set
+ }
+ }
+ //Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified
+ //No Break Here . Intentionally!
+
+ case eAddPHSRule:
+ case eSetPHSRule:
+ {
+ if(psfCSType->cPhsRule.u8PHSI)
+ {
+ //Apply This PHS Rule to all classifiers whose Associated PHSI Match
+ unsigned int uiClassifierIndex = 0;
+ if(pstAddIndication->u8Direction == UPLINK_DIR )
+ {
+ for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
+ {
+ if((Adapter->astClassifierTable[uiClassifierIndex].bUsed) &&
+ (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) &&
+ (Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adding PHS Rule For Classifier : 0x%x cPhsRule.u8PHSI : 0x%x\n",
+ Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex,
+ psfCSType->cPhsRule.u8PHSI);
+ //Update The PHS Rule for this classifier as Associated PHSI id defined
+
+ //Copy the PHS Rule
+ sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI;
+ sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength;
+ sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength;
+ sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS;
+ sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV;
+ memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS);
+ memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS);
+ sPhsRule.u8RefCnt = 0;
+ sPhsRule.bUnclassifiedPHSRule = FALSE;
+ sPhsRule.PHSModifiedBytes = 0;
+ sPhsRule.PHSModifiedNumPackets = 0;
+ sPhsRule.PHSErrorNumPackets = 0;
+
+ //bPHSRuleAssociated = TRUE;
+ //Store The PHS Rule for this classifier
+
+ PhsUpdateClassifierRule(
+ &Adapter->stBCMPhsContext,
+ uVCID,
+ Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex,
+ &sPhsRule,
+ Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI);
+
+ //Update PHS Rule For the Classifier
+ if(sPhsRule.u8PHSI)
+ {
+ Adapter->astClassifierTable[uiClassifierIndex].u32PHSRuleID = sPhsRule.u8PHSI;
+ memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule,&sPhsRule,sizeof(S_PHS_RULE));
+ }
+
+ }
+ }
+ }
+ else
+ {
+ //Error PHS Rule specified in signaling could not be applied to any classifier
+
+ //Copy the PHS Rule
+ sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI;
+ sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength;
+ sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength;
+ sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS;
+ sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV;
+ memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS);
+ memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS);
+ sPhsRule.u8RefCnt = 0;
+ sPhsRule.bUnclassifiedPHSRule = TRUE;
+ sPhsRule.PHSModifiedBytes = 0;
+ sPhsRule.PHSModifiedNumPackets = 0;
+ sPhsRule.PHSErrorNumPackets = 0;
+ //Store The PHS Rule for this classifier
+
+ /*
+ Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule,
+ clsid will be zero hence we cant have multiple PHS rules for the same SF.
+ To support multiple PHS rule, passing u8PHSI.
+ */
+
+ PhsUpdateClassifierRule(
+ &Adapter->stBCMPhsContext,
+ uVCID,
+ sPhsRule.u8PHSI,
+ &sPhsRule,
+ sPhsRule.u8PHSI);
+
+ }
+
+ }
+ }
+ break;
+ }
+ }
+
+ if(psfLocalSet->u32MaxSustainedTrafficRate == 0 )
+ {
+ //No Rate Limit . Set Max Sustained Traffic Rate to Maximum
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
+ WIMAX_MAX_ALLOWED_RATE;
+
+ }
+ else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) >
+ WIMAX_MAX_ALLOWED_RATE)
+ {
+ //Too large Allowed Rate specified. Limiting to Wi Max Allowed rate
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
+ WIMAX_MAX_ALLOWED_RATE;
+ }
+ else
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
+ ntohl(psfLocalSet->u32MaxSustainedTrafficRate);
+ }
+
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency);
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = MAX_LATENCY_ALLOWED;
+
+
+ if(( Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS ||
+ Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS ) )
+ UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval);
+
+ if(UGIValue == 0)
+ UGIValue = DEFAULT_UG_INTERVAL;
+
+ /*
+ For UGI based connections...
+ DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host...
+ The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput...
+ In case of non-UGI based connection, 200 frames worth of data is the max token count at host...
+ */
+
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize =
+ (DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8)
+ {
+ UINT UGIFactor = 0;
+ /* Special Handling to ensure the biggest size of packet can go out from host to FW as follows:
+ 1. Any packet from Host to FW can go out in different packet size.
+ 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped.
+ 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer
+ */
+ UGIFactor = (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency/UGIValue + 1);
+
+ if(UGIFactor > DEFAULT_UGI_FACTOR)
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize =
+ (UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8)
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = WIMAX_MAX_MTU*8;
+ }
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"LAT: %d, UGI: %d \n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x",
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate,
+ ntohl(psfLocalSet->u32MaxSustainedTrafficRate),
+ Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize);
+
+ //copy the extended SF Parameters to Support MIBS
+ CopyMIBSExtendedSFParameters(Adapter,psfLocalSet,uiSearchRuleIndex);
+
+ //store header suppression enabled flag per SF
+ Adapter->PackInfo[uiSearchRuleIndex].bHeaderSuppressionEnabled =
+ !(psfLocalSet->u8RequesttransmissionPolicy &
+ MASK_DISABLE_HEADER_SUPPRESSION);
+
+ if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication)
+ {
+ bcm_kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
+ Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL;
+ }
+ Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication;
+
+ //Re Sort the SF list in PackInfo according to Traffic Priority
+ SortPackInfo(Adapter);
+
+ /* Re Sort the Classifier Rules table and re - arrange
+ according to Classifier Rule Priority */
+ SortClassifiers(Adapter);
+
+ DumpPhsRules(&Adapter->stBCMPhsContext);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s <=====", __FUNCTION__);
+}
+
+
+/***********************************************************************
+* Function - DumpCmControlPacket
+*
+* Description - This routinue Dumps the Contents of the AddIndication
+* Structure in the Connection Management Control Packet
+*
+* Parameter - pvBuffer: Pointer to the buffer containing the
+* AddIndication data.
+*
+* Returns - None
+*************************************************************************/
+VOID DumpCmControlPacket(PVOID pvBuffer)
+{
+ UINT uiLoopIndex;
+ UINT nIndex;
+ stLocalSFAddIndicationAlt *pstAddIndication;
+ UINT nCurClassifierCnt;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>");
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type : 0x%X",pstAddIndication->u8Type);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction : 0x%X",pstAddIndication->u8Direction);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",ntohs(pstAddIndication->u16CID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID));
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->");
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",htonl(pstAddIndication->sfAuthorizedSet.u32SFID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",htons(pstAddIndication->sfAuthorizedSet.u16CID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0],
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1],
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2],
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[3],
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4],
+ pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8MBSService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8QosParamSet);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%X, %p",
+ pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%X 0x%p",
+ pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate,
+ &pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32MinimumTolerableTrafficRate);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32RequesttransmissionPolicy);
+#endif
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32ToleratedJitter);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u32MaximumLatency);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8SDUSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16TargetSAID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8ARQEnable);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQWindowSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16ARQBlockSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8CSSpecification);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16TimeBase);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8PagingPreference);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X",
+ pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignmentLength);
+ for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X",
+ pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
+#endif
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ",
+ *(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
+ *(unsigned int*)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4],
+ *(USHORT*) &pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%X",
+ pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers);
+
+ nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers;
+
+ if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
+ {
+ nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead);
+ if(!pstAddIndication->sfAuthorizedSet.bValid)
+ pstAddIndication->sfAuthorizedSet.bValid=1;
+ for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
+ {
+ stConvergenceSLTypes *psfCSType = NULL;
+ psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex];
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>");
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+#if 0
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u8ProtocolLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolLength);
+#endif
+
+ for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8Protocol);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+ for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+ for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X ,0x%02X ,0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16UserPriority);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16VLANID);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+#ifdef VERSION_D5
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+#endif
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%02X",pstAddIndication->sfAuthorizedSet.bValid);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->");
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfAdmittedSet.u32SFID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfAdmittedSet.u16CID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X",
+ pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X",
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[0],
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[1],
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[2],
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[3],
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[4],
+ pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8MBSService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8QosParamSet);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8TrafficPriority);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X",
+ ntohl(pstAddIndication->sfAdmittedSet.u32MaxSustainedTrafficRate));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32MinimumTolerableTrafficRate);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32RequesttransmissionPolicy);
+#endif
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32ToleratedJitter);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X",
+ pstAddIndication->sfAdmittedSet.u32MaximumLatency);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8SDUSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u16TargetSAID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8ARQEnable);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQWindowSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16ARQBlockSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8CSSpecification);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X",
+ pstAddIndication->sfAdmittedSet.u16TimeBase);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X",
+ pstAddIndication->sfAdmittedSet.u8PagingPreference);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X",
+ pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignmentLength);
+ for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X",
+ pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
+#endif
+
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X",
+ pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers);
+
+ nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers;
+
+ if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
+ {
+ nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
+ }
+
+
+ for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
+ {
+
+ stConvergenceSLTypes *psfCSType = NULL;
+ psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex];
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%02X",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+#if 0
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolLength :0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolLength);
+#endif
+ for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8Protocol);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+ for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+ for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4] : 0x %02X %02X %02X %02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4] : 0x %02X %02X %02X %02X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X %02X %02X",
+ psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16UserPriority);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16VLANID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%02X",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+#ifdef VERSION_D5
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+#endif
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%X",pstAddIndication->sfAdmittedSet.bValid);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->");
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfActiveSet.u32SFID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfActiveSet.u16CID);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X",
+ pstAddIndication->sfActiveSet.u8ServiceClassNameLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X",
+ pstAddIndication->sfActiveSet.u8ServiceClassName[0],
+ pstAddIndication->sfActiveSet.u8ServiceClassName[1],
+ pstAddIndication->sfActiveSet.u8ServiceClassName[2],
+ pstAddIndication->sfActiveSet.u8ServiceClassName[3],
+ pstAddIndication->sfActiveSet.u8ServiceClassName[4],
+ pstAddIndication->sfActiveSet.u8ServiceClassName[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X",
+ pstAddIndication->sfActiveSet.u8MBSService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X",
+ pstAddIndication->sfActiveSet.u8QosParamSet);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
+ pstAddIndication->sfActiveSet.u8TrafficPriority);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X",
+ ntohl(pstAddIndication->sfActiveSet.u32MaxSustainedTrafficRate));
+#endif
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
+ pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
+ pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
+ pstAddIndication->sfActiveSet.u32MinimumTolerableTrafficRate);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
+ pstAddIndication->sfActiveSet.u32RequesttransmissionPolicy);
+#endif
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X",
+ pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X",
+ pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X",
+ pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X",
+ pstAddIndication->sfActiveSet.u32ToleratedJitter);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X",
+ pstAddIndication->sfActiveSet.u32MaximumLatency);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
+ pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X",
+ pstAddIndication->sfActiveSet.u8SDUSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID : 0x%X",
+ pstAddIndication->sfActiveSet.u16TargetSAID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable : 0x%X",
+ pstAddIndication->sfActiveSet.u8ARQEnable);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQWindowSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQBlockLifeTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder : 0x%X",
+ pstAddIndication->sfActiveSet.u8ARQDeliverInOrder);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize : 0x%X",
+ pstAddIndication->sfActiveSet.u16ARQBlockSize);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification : 0x%X",
+ pstAddIndication->sfActiveSet.u8CSSpecification);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService : 0x%X",
+ pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime : 0x%X",
+ pstAddIndication->sfActiveSet.u16SDUInterArrivalTime);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase : 0x%X",
+ pstAddIndication->sfActiveSet.u16TimeBase);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X",
+ pstAddIndication->sfActiveSet.u8PagingPreference);
+#if 0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignmentLength : 0x%X",
+ pstAddIndication->sfActiveSet.MBSZoneIdentifierassignmentLength);
+ for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignment : 0x%X",
+ pstAddIndication->sfActiveSet.MBSZoneIdentifierassignment[uiLoopIndex]);
+#endif
+
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X",
+ pstAddIndication->sfActiveSet.u8TrafficIndicationPreference);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers);
+
+ nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers;
+
+ if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
+ {
+ nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
+ }
+
+ for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
+ {
+
+ stConvergenceSLTypes *psfCSType = NULL;
+ psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex];
+
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ClassifierRulePriority :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfServiceLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+ psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+#if 0
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " u8ProtocolLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolLength);
+#endif
+ for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ",
+ psfCSType->cCPacketClassificationRule.u8Protocol);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+ for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+ for(uiLoopIndex=0;uiLoopIndex<32;uiLoopIndex++)
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPDestinationAddress[32]:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRangeLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRangeLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+ psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddressLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetSourceMACAddressLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+ psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthertypeLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Ethertype[3] :0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+ psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16UserPriority :0x%X ",
+ psfCSType->cCPacketClassificationRule.u16UserPriority);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16VLANID :0x%X ",
+ psfCSType->cCPacketClassificationRule.u16VLANID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8AssociatedPHSI :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16PacketClassificationRuleIndex:0x%X ",
+ psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParamLength:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParam[1]:0x%X ",
+ psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+#ifdef VERSION_D5
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLableLength :0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLable[6] :0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ",
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+ psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+#endif
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid : 0x%X",pstAddIndication->sfActiveSet.bValid);
+
+}
+
+static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet,PUCHAR pucDestBuffer)
+{
+ UINT nBytesToRead = sizeof(stServiceFlowParamSI);
+
+ if(ulAddrSFParamSet == 0 || NULL == pucDestBuffer)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!");
+ return 0;
+ }
+ ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " RestoreSFParam: Total Words of DSX Message To Read: 0x%x From Target At : 0x%lx ",
+ nBytesToRead/sizeof(ULONG),ulAddrSFParamSet);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "sizeof(stServiceFlowParamSI) = %x", sizeof(stServiceFlowParamSI));
+
+ //Read out the SF Param Set At the indicated Location
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "nBytesToRead = %x", nBytesToRead);
+ if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
+ return STATUS_FAILURE;
+
+ return 1;
+}
+
+
+static __inline ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet)
+{
+ UINT nBytesToWrite = sizeof(stServiceFlowParamSI);
+ UINT uiRetVal =0;
+
+ if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
+ {
+ return 0;
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " StoreSFParam: Total Words of DSX Message To Write: 0x%X To Target At : 0x%lX ",(nBytesToWrite/sizeof(ULONG)),ulAddrSFParamSet);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "WRM with %x bytes",nBytesToWrite);
+
+ uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite);
+ if(uiRetVal < 0) {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__);
+ return uiRetVal;
+ }
+ return 1;
+}
+
+ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength)
+{
+ stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;
+ stLocalSFAddIndication * pstAddIndication = NULL;
+ stLocalSFDeleteRequest *pstDeletionRequest;
+ UINT uiSearchRuleIndex;
+ ULONG ulSFID;
+
+ pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer);
+
+ /*
+ * In case of DSD Req By MS, we should immediately delete this SF so that
+ * we can stop the further classifying the pkt for this SF.
+ */
+ if(pstAddIndicationAlt->u8Type == DSD_REQ)
+ {
+ pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer;
+
+ ulSFID = ntohl(pstDeletionRequest->u32SFID);
+ uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
+
+ if(uiSearchRuleIndex < NO_OF_QUEUES)
+ {
+ deleteSFBySfid(Adapter,uiSearchRuleIndex);
+ Adapter->u32TotalDSD++;
+ }
+ return 1;
+ }
+
+
+ if( (pstAddIndicationAlt->u8Type == DSD_RSP) ||
+ (pstAddIndicationAlt->u8Type == DSD_ACK))
+ {
+ //No Special handling send the message as it is
+ return 1;
+ }
+ // For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver!
+
+ pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
+ if(NULL==pstAddIndication)
+ return 0;
+
+ /* AUTHORIZED SET */
+ pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)
+ GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
+ if(!pstAddIndication->psfAuthorizedSet)
+ return 0;
+
+ if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet,
+ (ULONG)pstAddIndication->psfAuthorizedSet)!= 1)
+ return 0;
+
+ pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)
+ ntohl((ULONG)pstAddIndication->psfAuthorizedSet);
+
+ if(pstAddIndicationAlt->u8Type == DSA_REQ)
+ {
+ stLocalSFAddRequest AddRequest;
+
+ AddRequest.u8Type = pstAddIndicationAlt->u8Type;
+ AddRequest.eConnectionDir = pstAddIndicationAlt->u8Direction;
+ AddRequest.u16TID = pstAddIndicationAlt->u16TID;
+ AddRequest.u16CID = pstAddIndicationAlt->u16CID;
+ AddRequest.u16VCID = pstAddIndicationAlt->u16VCID;
+ AddRequest.psfParameterSet =pstAddIndication->psfAuthorizedSet ;
+ (*puBufferLength) = sizeof(stLocalSFAddRequest);
+ memcpy(pvBuffer,&AddRequest,sizeof(stLocalSFAddRequest));
+ return 1;
+ }
+
+ // Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt
+
+ //We need to extract the structure from the buffer and pack it differently
+
+ pstAddIndication->u8Type = pstAddIndicationAlt->u8Type;
+ pstAddIndication->eConnectionDir= pstAddIndicationAlt->u8Direction ;
+ pstAddIndication->u16TID = pstAddIndicationAlt->u16TID;
+ pstAddIndication->u16CID = pstAddIndicationAlt->u16CID;
+ pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID;
+ pstAddIndication->u8CC = pstAddIndicationAlt->u8CC;
+
+ /* ADMITTED SET */
+ pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)
+ GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
+ if(!pstAddIndication->psfAdmittedSet)
+ return 0;
+ if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAdmittedSet,(ULONG)pstAddIndication->psfAdmittedSet) != 1)
+ return 0;
+
+ pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet);
+
+
+ /* ACTIVE SET */
+ pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)
+ GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
+ if(!pstAddIndication->psfActiveSet)
+ return 0;
+ if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfActiveSet,(ULONG)pstAddIndication->psfActiveSet) != 1)
+ return 0;
+
+ pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet);
+
+ (*puBufferLength) = sizeof(stLocalSFAddIndication);
+ *(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;
+ bcm_kfree(pstAddIndication);
+ return 1;
+}
+
+
+static inline stLocalSFAddIndicationAlt
+*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter,register PVOID pvBuffer)
+{
+ ULONG ulStatus=0;
+ stLocalSFAddIndication *pstAddIndication = NULL;
+ stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;
+ pstAddIndication = (stLocalSFAddIndication *)(pvBuffer);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>" );
+ if ((pstAddIndication->u8Type == DSD_REQ) ||
+ (pstAddIndication->u8Type == DSD_RSP) ||
+ (pstAddIndication->u8Type == DSD_ACK))
+ {
+ return (stLocalSFAddIndicationAlt *)pvBuffer;
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
+ /*
+ //Need to Allocate memory to contain the SUPER Large structures
+ //Our driver cant create these structures on Stack :(
+ */
+ pstAddIndicationDest=kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL);
+
+ if(pstAddIndicationDest)
+ {
+ memset(pstAddIndicationDest,0,sizeof(stLocalSFAddIndicationAlt));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure ");
+ return NULL;
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Type : 0x%X",pstAddIndication->u8Type);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Direction : 0x%X",pstAddIndication->eConnectionDir);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8TID : 0x%X",ntohs(pstAddIndication->u16TID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8CID : 0x%X",ntohs(pstAddIndication->u16CID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-autorized set loc : 0x%x",ntohl(pstAddIndication->psfAuthorizedSet));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-admitted set loc : 0x%x",ntohl(pstAddIndication->psfAdmittedSet));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-Active set loc : 0x%x",ntohl(pstAddIndication->psfActiveSet));
+
+ pstAddIndicationDest->u8Type = pstAddIndication->u8Type;
+ pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir;
+ pstAddIndicationDest->u16TID = pstAddIndication->u16TID;
+ pstAddIndicationDest->u16CID = pstAddIndication->u16CID;
+ pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID;
+ pstAddIndicationDest->u8CC = pstAddIndication->u8CC;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Active Set ");
+ ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet);
+ if(ulStatus != 1)
+ {
+ goto failed_restore_sf_param;
+ }
+ if(pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+ pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Admitted Set ");
+ ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAdmittedSet,(PUCHAR)&pstAddIndicationDest->sfAdmittedSet);
+ if(ulStatus != 1)
+ {
+ goto failed_restore_sf_param;
+ }
+ if(pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+ pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Authorized Set ");
+ ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAuthorizedSet,(PUCHAR)&pstAddIndicationDest->sfAuthorizedSet);
+ if(ulStatus != 1)
+ {
+ goto failed_restore_sf_param;
+ }
+ if(pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+ pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet");
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size %x %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest);
+ //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
+ return pstAddIndicationDest;
+failed_restore_sf_param:
+ bcm_kfree(pstAddIndicationDest);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
+ return NULL;
+}
+
+ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter)
+{
+ ULONG ulTargetDsxBuffersBase = 0;
+ ULONG ulCntTargetBuffers;
+ ULONG ulIndex=0;
+ int Status;
+
+ if(Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer)
+ return 1;
+
+ if(NULL == Adapter)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adapter was NULL!!!");
+ return 0;
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %x ",sizeof(stServiceFlowParamSI));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ",DSX_MESSAGE_EXCHANGE_BUFFER);
+
+ Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER,
+ (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT));
+ if(Status < 0)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!");
+ return 0;
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx",ulTargetDsxBuffersBase);
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :",ulTargetDsxBuffersBase);
+
+ ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE/sizeof(stServiceFlowParamSI);
+
+ Adapter->ulTotalTargetBuffersAvailable =
+ ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ?
+ MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ",Adapter->ulTotalTargetBuffersAvailable);
+
+ for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable ; ulIndex++)
+ {
+ Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer = ulTargetDsxBuffersBase;
+ Adapter->astTargetDsxBuffer[ulIndex].valid=1;
+ Adapter->astTargetDsxBuffer[ulIndex].tid=0;
+ ulTargetDsxBuffersBase+=sizeof(stServiceFlowParamSI);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx",
+ ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer);
+ }
+ Adapter->ulCurrentTargetBuffer = 0;
+ Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable;
+ return 1;
+}
+
+ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
+{
+ ULONG ulTargetDSXBufferAddress;
+ ULONG ulTargetDsxBufferIndexToUse,ulMaxTry;
+
+ if((Adapter->ulTotalTargetBuffersAvailable == 0)||
+ (Adapter->ulFreeTargetBufferCnt == 0))
+ {
+ ClearTargetDSXBuffer(Adapter,tid,FALSE);
+ return 0;
+ }
+
+ ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer;
+ ulMaxTry = Adapter->ulTotalTargetBuffersAvailable;
+ while((ulMaxTry)&&(Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1))
+ {
+ ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%
+ Adapter->ulTotalTargetBuffersAvailable;
+ ulMaxTry--;
+ }
+
+ if(ulMaxTry==0)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ",Adapter->ulFreeTargetBufferCnt);
+ ClearTargetDSXBuffer(Adapter,tid,FALSE);
+ return 0;
+ }
+
+
+ ulTargetDSXBufferAddress =
+ Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer;
+ Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid=0;
+ Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid=tid;
+ Adapter->ulFreeTargetBufferCnt--;
+
+
+ ulTargetDsxBufferIndexToUse =
+ (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable;
+ Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n",
+ ulTargetDSXBufferAddress,tid);
+ return ulTargetDSXBufferAddress;
+}
+
+
+INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter)
+{
+ /*
+ //Need to Allocate memory to contain the SUPER Large structures
+ //Our driver cant create these structures on Stack
+ */
+ Adapter->caDsxReqResp=kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL);
+ if(!Adapter->caDsxReqResp)
+ return -ENOMEM;
+ return 0;
+}
+
+INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->caDsxReqResp)
+ {
+ bcm_kfree(Adapter->caDsxReqResp);
+ }
+ return 0;
+
+}
+/**
+@ingroup ctrl_pkt_functions
+This routinue would process the Control responses
+for the Connection Management.
+@return - Queue index for the free SFID else returns Invalid Index.
+*/
+BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
+ PVOID pvBuffer /**Starting Address of the Buffer, that contains the AddIndication Data*/
+ )
+{
+ stServiceFlowParamSI *psfLocalSet=NULL;
+ stLocalSFAddIndicationAlt *pstAddIndication = NULL;
+ stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;
+ PLEADER pLeader=NULL;
+ /*
+ //Otherwise the message contains a target address from where we need to
+ //read out the rest of the service flow param structure
+ */
+ if((pstAddIndication = RestoreCmControlResponseMessage(Adapter,pvBuffer))
+ == NULL)
+ {
+ ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndication *)pvBuffer)->u16TID, FALSE);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");
+ return FALSE;
+ }
+
+ DumpCmControlPacket(pstAddIndication);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>");
+ pLeader = (PLEADER)Adapter->caDsxReqResp;
+
+ pLeader->Status =CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ;
+ pLeader->Vcid = 0;
+
+ ClearTargetDSXBuffer(Adapter,pstAddIndication->u16TID,FALSE);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n",pstAddIndication->u16TID);
+ switch(pstAddIndication->u8Type)
+ {
+ case DSA_REQ:
+ {
+ pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength );
+ *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+ = *pstAddIndication;
+ ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
+ CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
+ bcm_kfree(pstAddIndication);
+ }
+ break;
+ case DSA_RSP:
+ {
+ pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
+ pLeader->PLength);
+ *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+ = *pstAddIndication;
+ ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
+
+ }//no break here..we should go down.
+ case DSA_ACK:
+ {
+ UINT uiSearchRuleIndex=0;
+ struct timeval tv = {0};
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
+ ntohs(pstAddIndication->u16VCID));
+ uiSearchRuleIndex=SearchFreeSfid(Adapter);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiSearchRuleIndex:0x%X ",
+ uiSearchRuleIndex);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Direction:0x%X ",
+ pstAddIndication->u8Direction);
+ if((uiSearchRuleIndex< NO_OF_QUEUES) )
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].ucDirection =
+ pstAddIndication->u8Direction;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ",
+ pstAddIndication->sfActiveSet.bValid);
+ if(pstAddIndication->sfActiveSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE;
+ }
+ if(pstAddIndication->sfAuthorizedSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE;
+ }
+ if(pstAddIndication->sfAdmittedSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE;
+ }
+ if(FALSE == pstAddIndication->sfActiveSet.bValid)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+ if(pstAddIndication->sfAdmittedSet.bValid)
+ {
+ psfLocalSet = &pstAddIndication->sfAdmittedSet;
+ }
+ else if(pstAddIndication->sfAuthorizedSet.bValid)
+ {
+ psfLocalSet = &pstAddIndication->sfAuthorizedSet;
+ }
+ }
+ else
+ {
+ psfLocalSet = &pstAddIndication->sfActiveSet;
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
+ }
+
+ if(!psfLocalSet)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No set is valid\n");
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
+ bcm_kfree(pstAddIndication);
+ }
+
+ else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK");
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value =
+ ntohs(pstAddIndication->u16VCID);
+ Adapter->PackInfo[uiSearchRuleIndex].usCID =
+ ntohs(pstAddIndication->u16CID);
+
+ if(UPLINK_DIR == pstAddIndication->u8Direction)
+ atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT);
+ CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex,
+ DSA_ACK, pstAddIndication);
+ // don't free pstAddIndication
+
+ /* Inside CopyToAdapter, Sorting of all the SFs take place.
+ Hence any access to the newly added SF through uiSearchRuleIndex is invalid.
+ SHOULD BE STRICTLY AVOIDED.
+ */
+// *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID;
+ memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4);
+
+ if(pstAddIndication->sfActiveSet.bValid == TRUE)
+ {
+ if(UPLINK_DIR == pstAddIndication->u8Direction)
+ {
+ if(!Adapter->LinkUpStatus)
+ {
+ netif_carrier_on(Adapter->dev);
+ netif_start_queue(Adapter->dev);
+ Adapter->LinkUpStatus = 1;
+ do_gettimeofday(&tv);
+
+ atomic_set(&Adapter->TxPktAvail, 1);
+ wake_up(&Adapter->tx_packet_wait_queue);
+ Adapter->liTimeSinceLastNetEntry = tv.tv_sec;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!");
+ }
+ }
+ }
+ }
+
+ else
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
+ bcm_kfree(pstAddIndication);
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
+ bcm_kfree(pstAddIndication);
+ return FALSE;
+ }
+ }
+ break;
+ case DSC_REQ:
+ {
+ pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
+ pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
+
+ *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+ ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
+
+ CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
+ bcm_kfree(pstAddIndication);
+ }
+ break;
+ case DSC_RSP:
+ {
+ pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
+ pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
+ *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+ ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
+ }
+ case DSC_ACK:
+ {
+ UINT uiSearchRuleIndex=0;
+
+ pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+ uiSearchRuleIndex=SearchSfid(Adapter,ntohl(pstChangeIndication->sfActiveSet.u32SFID));
+ if(uiSearchRuleIndex > NO_OF_QUEUES-1)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
+ }
+ if((uiSearchRuleIndex < NO_OF_QUEUES))
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction;
+ if(pstChangeIndication->sfActiveSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE;
+ }
+ if(pstChangeIndication->sfAuthorizedSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE;
+ }
+ if(pstChangeIndication->sfAdmittedSet.bValid==TRUE)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE;
+ }
+
+ if(FALSE==pstChangeIndication->sfActiveSet.bValid)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+ Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+ if(pstChangeIndication->sfAdmittedSet.bValid)
+ {
+ psfLocalSet = &pstChangeIndication->sfAdmittedSet;
+ }
+ else if(pstChangeIndication->sfAuthorizedSet.bValid)
+ {
+ psfLocalSet = &pstChangeIndication->sfAuthorizedSet;
+ }
+ }
+
+ else
+ {
+ psfLocalSet = &pstChangeIndication->sfActiveSet;
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
+ }
+ if(psfLocalSet->bValid && (pstChangeIndication->u8CC == 0))
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value =
+ ntohs(pstChangeIndication->u16VCID);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n",
+ pstChangeIndication->u8CC, psfLocalSet->bValid);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID));
+ Adapter->PackInfo[uiSearchRuleIndex].usCID =
+ ntohs(pstChangeIndication->u16CID);
+ CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex,
+ DSC_ACK, pstAddIndication);
+
+ *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID;
+ }
+ else if(pstChangeIndication->u8CC == 6)
+ {
+ deleteSFBySfid(Adapter,uiSearchRuleIndex);
+ bcm_kfree(pstAddIndication);
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
+ bcm_kfree(pstAddIndication);
+ return FALSE;
+ }
+ }
+ break;
+ case DSD_REQ:
+ {
+ UINT uiSearchRuleIndex;
+ ULONG ulSFID;
+
+ pLeader->PLength = sizeof(stLocalSFDeleteIndication);
+ *((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication*)pstAddIndication);
+
+ ulSFID = ntohl(((stLocalSFDeleteIndication*)pstAddIndication)->u32SFID);
+ uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x",uiSearchRuleIndex);
+
+ if(uiSearchRuleIndex < NO_OF_QUEUES)
+ {
+ //Delete All Classifiers Associated with this SFID
+ deleteSFBySfid(Adapter,uiSearchRuleIndex);
+ Adapter->u32TotalDSD++;
+ }
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");
+ ((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;
+ CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
+ }
+ case DSD_RSP:
+ {
+ //Do nothing as SF has already got Deleted
+ }
+ break;
+ case DSD_ACK:
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
+ break;
+ default:
+ bcm_kfree(pstAddIndication);
+ return FALSE ;
+ }
+ return TRUE;
+}
+
+int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, PUCHAR user_buffer)
+{
+ int status = 0;
+ struct _packet_info *psSfInfo=NULL;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status);
+ status = SearchSfid(Adapter, uiSFId);
+ if(status>NO_OF_QUEUES)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId );
+ return -EINVAL;
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status);
+ psSfInfo=&Adapter->PackInfo[status];
+ if(psSfInfo->pstSFIndication && copy_to_user((PCHAR)user_buffer,
+ (PCHAR)psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId );
+ status = -EFAULT;
+ return status;
+ }
+ return STATUS_SUCCESS;
+}
+
+VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer)
+{
+ B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1));
+ stIM_SFHostNotify *pHostInfo = NULL;
+ UINT uiSearchRuleIndex = 0;
+ ULONG ulSFID = 0;
+
+ puiBuffer+=2;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n",u32NumofSFsinMsg);
+
+ while(u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES)
+ {
+ u32NumofSFsinMsg--;
+ pHostInfo = (stIM_SFHostNotify *)puiBuffer;
+ puiBuffer = (PUINT)(pHostInfo + 1);
+
+ ulSFID = ntohl(pHostInfo->SFID);
+ uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"SFID: 0x%lx\n",ulSFID);
+
+ if(uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID);
+ continue;
+ }
+
+ if(pHostInfo->RetainSF == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Going to Delete SF");
+ deleteSFBySfid(Adapter,uiSearchRuleIndex);
+ }
+ else
+ {
+
+ Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pHostInfo->VCID);
+ Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pHostInfo->newCID);
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"pHostInfo->QoSParamSet: 0x%x\n",pHostInfo->QoSParamSet);
+
+ if(pHostInfo->QoSParamSet & 0x1)
+ Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet =TRUE;
+ if(pHostInfo->QoSParamSet & 0x2)
+ Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet =TRUE;
+ if(pHostInfo->QoSParamSet & 0x4)
+ {
+ Adapter->PackInfo[uiSearchRuleIndex].bActiveSet =TRUE;
+ Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
+ }
+ }
+ }
+}
+
+
+
diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h
new file mode 100644
index 000000000000..847782c3765b
--- /dev/null
+++ b/drivers/staging/bcm/CmHost.h
@@ -0,0 +1,166 @@
+/// **************************************************************************
+/// (c) Beceem Communications Inc.
+/// All Rights Reserved
+///
+/// \file : CmHost.h
+/// \author : Rajeev Tirumala
+/// \date : September 8 , 2006
+/// \brief : Definitions for Connection Management Requests structure
+/// which we will use to setup our connection structures.Its high
+/// time we had a header file for CmHost.cpp to isolate the way
+/// f/w sends DSx messages and the way we interpret them in code.
+/// Revision History
+///
+/// Date Author Version Description
+/// 08-Sep-06 Rajeev 0.1 Created
+/// **************************************************************************
+#ifndef _CM_HOST_H
+#define _CM_HOST_H
+
+#pragma once
+#pragma pack (push,4)
+
+#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 // This contains the pointer
+#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 // 24 K Bytes
+
+/// \brief structure stLocalSFAddRequest
+typedef struct stLocalSFAddRequestAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+
+
+ /// \brief structure ParameterSet
+ stServiceFlowParamSI sfParameterSet;
+
+ //USE_MEMORY_MANAGER();
+}stLocalSFAddRequestAlt;
+
+/// \brief structure stLocalSFAddIndication
+typedef struct stLocalSFAddIndicationAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ActiveSet
+ stServiceFlowParamSI sfActiveSet;
+
+ B_UINT8 u8CC; /**< Confirmation Code*/
+ B_UINT8 u8Padd; /**< 8-bit Padding */
+ B_UINT16 u16Padd; /**< 16 bit Padding */
+// USE_MEMORY_MANAGER();
+}stLocalSFAddIndicationAlt;
+
+/// \brief structure stLocalSFAddConfirmation
+typedef struct stLocalSFAddConfirmationAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ActiveSet
+ stServiceFlowParamSI sfActiveSet;
+}stLocalSFAddConfirmationAlt;
+
+
+/// \brief structure stLocalSFChangeRequest
+typedef struct stLocalSFChangeRequestAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+ /*
+ //Pointer location at which following Service Flow param Structure can be read
+ //from the target. We get only the address location and we need to read out the
+ //entire SF param structure at the given location on target
+ */
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ParameterSet
+ stServiceFlowParamSI sfActiveSet;
+
+ B_UINT8 u8CC; /**< Confirmation Code*/
+ B_UINT8 u8Padd; /**< 8-bit Padding */
+ B_UINT16 u16Padd; /**< 16 bit */
+
+}stLocalSFChangeRequestAlt;
+
+/// \brief structure stLocalSFChangeConfirmation
+typedef struct stLocalSFChangeConfirmationAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ActiveSet
+ stServiceFlowParamSI sfActiveSet;
+
+}stLocalSFChangeConfirmationAlt;
+
+/// \brief structure stLocalSFChangeIndication
+typedef struct stLocalSFChangeIndicationAlt{
+ B_UINT8 u8Type;
+ B_UINT8 u8Direction;
+ B_UINT16 u16TID;
+ /// \brief 16bitCID
+ B_UINT16 u16CID;
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID;
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ActiveSet
+ stServiceFlowParamSI sfActiveSet;
+
+ B_UINT8 u8CC; /**< Confirmation Code*/
+ B_UINT8 u8Padd; /**< 8-bit Padding */
+ B_UINT16 u16Padd; /**< 16 bit */
+
+}stLocalSFChangeIndicationAlt;
+
+ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength);
+
+ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
+
+INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
+
+INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
+ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter);
+
+BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer);
+
+VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex);
+
+#pragma pack (pop)
+
+#endif
diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c
new file mode 100644
index 000000000000..8907e211d483
--- /dev/null
+++ b/drivers/staging/bcm/DDRInit.c
@@ -0,0 +1,1302 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+
+#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
+#define MIPS_CLOCK_REG 0x0f000820
+
+ //DDR INIT-133Mhz
+#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 //index for 0x0F007000
+static DDR_SET_NODE asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting
+ {0x0F000800,0x00007212},
+ {0x0f000820,0x07F13FFF},
+ {0x0f000810,0x00000F95},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF1B00},
+ {0x0f000870,0x00000002},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00a04C,0x0000000C},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x02000007},
+ {0x0F007028,0x02020202},
+ {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x05000000},
+ {0x0F007034,0x00000003},
+ {0x0F007038,0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x02101010},//ROB - 0x02101010,//0x02101018},
+ {0x0F007040,0x45751200},//ROB - 0x45751200,//0x450f1200},
+ {0x0F007044,0x110a0d00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x081b0306},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0000001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x0010246c},
+ {0x0F007064,0x00000010},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00007000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00000104},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+ };
+//80Mhz
+#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 //index for 0x0F007000
+static DDR_SET_NODE asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x07f1ffff},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00a000,0x00000016},
+ {0x0F00a04C,0x0000000C},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01000000},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020000},
+ {0x0F007020,0x04020107},
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x02020201},
+ {0x0F00702c,0x0204040a},
+ {0x0F007030,0x04000000},
+ {0x0F007034,0x00000002},
+ {0x0F007038,0x1F060200},
+ {0x0F00703C,0x1C22221F},
+ {0x0F007040,0x8A006600},
+ {0x0F007044,0x221a0800},
+ {0x0F007048,0x02690204},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0000001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x000A15D6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00004000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007094,0x00000104},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+ };
+//100Mhz
+#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 //index for 0x0F007000
+static DDR_SET_NODE asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting
+ {0x0F000800,0x00007008},
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x07F13E3F},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ //0x0f000840,0x0FFF1800,
+ {0x0f000840,0x0FFF1B00},
+ {0x0f000870,0x00000002},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00a04C,0x0000000C},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020001}, // POP - 0x00020000 Normal 0x01020000
+ {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x01020201},
+ {0x0F00702c,0x0204040A},
+ {0x0F007030,0x06000000},
+ {0x0F007034,0x00000004},
+ {0x0F007038,0x20080200},
+ {0x0F00703C,0x02030320},
+ {0x0F007040,0x6E7F1200},
+ {0x0F007044,0x01190A00},
+ {0x0F007048,0x06120305},//0x02690204 // 0x06120305
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0000001C},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x00082ED6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00005000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00000104},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+ };
+
+//Net T3B DDR Settings
+//DDR INIT-133Mhz
+static DDR_SET_NODE asDPLL_266MHZ[] = {
+ {0x0F000800,0x00007212},
+ {0x0f000820,0x07F13FFF},
+ {0x0f000810,0x00000F95},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF1B00},
+ {0x0f000870,0x00000002}
+ };
+#if 0
+static DDR_SET_NODE asDPLL_800MHZ[] = {
+ {0x0f000810,0x00000F95},
+ {0x0f000810,0x00000F95},
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x03F1365B},
+ {0x0f000840,0x0FFF0000},
+ {0x0f000880,0x000003DD},
+ {0x0f000860,0x00000000}
+ };
+#endif
+
+#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000
+static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting
+ {0x0f000810,0x00000F95},
+ {0x0f000810,0x00000F95},
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x07F13652},
+ {0x0f000840,0x0FFF0800},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000880,0x000003DD},
+ {0x0f000860,0x00000000},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x02000007},
+ {0x0F007028,0x02020202},
+ {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x05000000},
+ {0x0F007034,0x00000003},
+ {0x0F007038,0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x02101012},//ROB - 0x02101010,//0x02101018},
+ {0x0F007040,0x457D1200},//ROB - 0x45751200,//0x450f1200},
+ {0x0F007044,0x11130d00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x040D0306},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0000001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x0010246c},
+ {0x0F007064,0x00000012},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00007000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00000104},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000},
+ };
+
+#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000
+static DDR_SET_NODE asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x07F13FFF},
+ {0x0f000840,0x0FFF1F00},
+ {0x0f000880,0x000003DD},
+ {0x0f000860,0x00000000},
+
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00a000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01000000},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020000},
+ {0x0F007020,0x04020107},
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x02020201},
+ {0x0F00702c,0x0204040a},
+ {0x0F007030,0x04000000},
+ {0x0F007034,0x02000002},
+ {0x0F007038,0x1F060202},
+ {0x0F00703C,0x1C22221F},
+ {0x0F007040,0x8A006600},
+ {0x0F007044,0x221a0800},
+ {0x0F007048,0x02690204},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x000A15D6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00004000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007094,0x00000104},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+ };
+
+//100Mhz
+#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 //index for 0x0F007000
+static DDR_SET_NODE asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting
+ {0x0f000810,0x00000F95},
+ {0x0f000820,0x07F1369B},
+ {0x0f000840,0x0FFF0800},
+ {0x0f000880,0x000003DD},
+ {0x0f000860,0x00000000},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020000}, // POP - 0x00020000 Normal 0x01020000
+ {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x01020201},
+ {0x0F00702c,0x0204040A},
+ {0x0F007030,0x06000000},
+ {0x0F007034,0x02000004},
+ {0x0F007038,0x20080200},
+ {0x0F00703C,0x02030320},
+ {0x0F007040,0x6E7F1200},
+ {0x0F007044,0x01190A00},
+ {0x0F007048,0x06120305},//0x02690204 // 0x06120305
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001C},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x00082ED6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00005000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00000104},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+ };
+
+
+#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 //index for 0x0F007000
+static DDR_SET_NODE asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting
+ {0x0f000820,0x03F1365B},
+ {0x0f000810,0x00002F95},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF0000},
+ {0x0f000860,0x00000000},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00A000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x02000007},
+ {0x0F007028,0x02020200},
+ {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x05000000},
+ {0x0F007034,0x00000003},
+ {0x0F007038,0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x02101020},//ROB - 0x02101010,//0x02101018,
+ {0x0F007040,0x45711200},//ROB - 0x45751200,//0x450f1200,
+ {0x0F007044,0x110D0D00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x04080306},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x0010245F},
+ {0x0F007064,0x00000010},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00007000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007088,0x01000001},
+ {0x0F00708c,0x00000101},
+ {0x0F007090,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00040000},
+ {0x0F007098,0x00000000},
+ {0x0F0070c8,0x00000104},
+ //# Enable 2 ports within X-bar
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+};
+
+#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 //index for 0x0F007000
+static DDR_SET_NODE asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting
+ {0x0f000810,0x00002F95},
+ {0x0f000820,0x03F1369B},
+ {0x0f000840,0x0fff0000},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF0000},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x01020200},
+ {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x06000000},
+ {0x0F007034,0x00000004},
+ {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018,
+ {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200,
+ {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x03000305},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x00082ED6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00005000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007088,0x01000001},
+ {0x0F00708c,0x00000101},
+ {0x0F007090,0x00000000},
+ {0x0F007094,0x00010000},
+ {0x0F007098,0x00000000},
+ {0x0F0070C8,0x00000104},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+};
+
+#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000
+static DDR_SET_NODE asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting
+ {0x0f000820,0x07F13FFF},
+ {0x0f000810,0x00002F95},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ {0x0f000840,0x0FFF1F00},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0F00a084,0x1Cffffff},
+ {0x0F00a080,0x1C000000},
+ {0x0F00A000,0x00000016},
+ {0x0f007000,0x00010001},
+ {0x0f007004,0x01000000},
+ {0x0f007008,0x01000001},
+ {0x0f00700c,0x00000000},
+ {0x0f007010,0x01000000},
+ {0x0f007014,0x01000100},
+ {0x0f007018,0x01000000},
+ {0x0f00701c,0x01020000},
+ {0x0f007020,0x04020107},
+ {0x0f007024,0x00000007},
+ {0x0f007028,0x02020200},
+ {0x0f00702c,0x0204040a},
+ {0x0f007030,0x04000000},
+ {0x0f007034,0x00000002},
+ {0x0f007038,0x1d060200},
+ {0x0f00703c,0x1c22221d},
+ {0x0f007040,0x8A116600},
+ {0x0f007044,0x222d0800},
+ {0x0f007048,0x02690204},
+ {0x0f00704c,0x00000000},
+ {0x0f007050,0x0100001c},
+ {0x0f007054,0x00000000},
+ {0x0f007058,0x00000000},
+ {0x0f00705c,0x00000000},
+ {0x0f007060,0x000A15D6},
+ {0x0f007064,0x0000000A},
+ {0x0f007068,0x00000000},
+ {0x0f00706c,0x00000001},
+ {0x0f007070,0x00004000},
+ {0x0f007074,0x00000000},
+ {0x0f007078,0x00000000},
+ {0x0f00707c,0x00000000},
+ {0x0f007080,0x00000000},
+ {0x0f007084,0x00000000},
+ {0x0f007088,0x01000001},
+ {0x0f00708c,0x00000101},
+ {0x0f007090,0x00000000},
+ {0x0f007094,0x00010000},
+ {0x0f007098,0x00000000},
+ {0x0F0070C8,0x00000104},
+ {0x0F007018,0x01010000}
+};
+
+
+
+
+///T3 LP-B (UMA-B)
+
+#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 //index for 0x0F007000
+static DDR_SET_NODE asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting
+
+ {0x0f000820,0x03F137DB},
+ {0x0f000810,0x01842795},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ {0x0f000840,0x0FFF0400},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0f003050,0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz
+ {0x0F00a084,0x1Cffffff},//Now dump from her in internal memory
+ {0x0F00a080,0x1C000000},
+ {0x0F00A000,0x00000016},
+ {0x0f007000,0x00010001},
+ {0x0f007004,0x01000001},
+ {0x0f007008,0x01000101},
+ {0x0f00700c,0x00000000},
+ {0x0f007010,0x01000100},
+ {0x0f007014,0x01000100},
+ {0x0f007018,0x01000000},
+ {0x0f00701c,0x01020000},
+ {0x0f007020,0x04030107},
+ {0x0f007024,0x02000007},
+ {0x0f007028,0x02020200},
+ {0x0f00702c,0x0206060a},
+ {0x0f007030,0x050d0d00},
+ {0x0f007034,0x00000003},
+ {0x0f007038,0x170a0200},
+ {0x0f00703c,0x02101012},
+ {0x0f007040,0x45161200},
+ {0x0f007044,0x11250c00},
+ {0x0f007048,0x04da0307},
+ {0x0f00704c,0x00000000},
+ {0x0f007050,0x0000001c},
+ {0x0f007054,0x00000000},
+ {0x0f007058,0x00000000},
+ {0x0f00705c,0x00000000},
+ {0x0f007060,0x00142bb6},
+ {0x0f007064,0x20430014},
+ {0x0f007068,0x00000000},
+ {0x0f00706c,0x00000001},
+ {0x0f007070,0x00009000},
+ {0x0f007074,0x00000000},
+ {0x0f007078,0x00000000},
+ {0x0f00707c,0x00000000},
+ {0x0f007080,0x00000000},
+ {0x0f007084,0x00000000},
+ {0x0f007088,0x01000001},
+ {0x0f00708c,0x00000101},
+ {0x0f007090,0x00000000},
+ {0x0f007094,0x00040000},
+ {0x0f007098,0x00000000},
+ {0x0F0070C8,0x00000104},
+ {0x0F007018,0x01010000}
+};
+
+
+#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 //index for 0x0F007000
+static DDR_SET_NODE asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting
+ {0x0f000820,0x03F1365B},
+ {0x0f000810,0x00002F95},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF0000},
+ {0x0f000860,0x00000000},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+ {0x0F00a084,0x1Cffffff},//dump from here in internal memory
+ {0x0F00a080,0x1C000000},
+ {0x0F00A000,0x00000016},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x02000007},
+ {0x0F007028,0x02020200},
+ {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x05000000},
+ {0x0F007034,0x00000003},
+ {0x0F007038,0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x02101017},//ROB - 0x02101010,//0x02101018,
+ {0x0F007040,0x45171200},//ROB - 0x45751200,//0x450f1200,
+ {0x0F007044,0x11290D00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x04080306},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x0010245F},
+ {0x0F007064,0x00000010},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00007000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007088,0x01000001},
+ {0x0F00708c,0x00000101},
+ {0x0F007090,0x00000000},
+ //# Enable BW improvement within memory controller
+ {0x0F007094,0x00040000},
+ {0x0F007098,0x00000000},
+ {0x0F0070c8,0x00000104},
+ //# Enable 2 ports within X-bar
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+};
+
+#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 //index for 0x0F007000
+static DDR_SET_NODE asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting
+ {0x0f000810,0x00002F95},
+ {0x0f000820,0x03F1369B},
+ {0x0f000840,0x0fff0000},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ // Changed source for X-bar and MIPS clock to APLL
+ {0x0f000840,0x0FFF0000},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+ {0x0F00a084,0x1Cffffff}, //dump from here in internal memory
+ {0x0F00a080,0x1C000000},
+ //Memcontroller Default values
+ {0x0F007000,0x00010001},
+ {0x0F007004,0x01010100},
+ {0x0F007008,0x01000001},
+ {0x0F00700c,0x00000000},
+ {0x0F007010,0x01000000},
+ {0x0F007014,0x01000100},
+ {0x0F007018,0x01000000},
+ {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001
+ {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107
+ {0x0F007024,0x00000007},
+ {0x0F007028,0x01020200},
+ {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a
+ {0x0F007030,0x06000000},
+ {0x0F007034,0x00000004},
+ {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200
+ {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018,
+ {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200,
+ {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00
+ {0x0F007048,0x03000305},
+ {0x0F00704c,0x00000000},
+ {0x0F007050,0x0100001c},
+ {0x0F007054,0x00000000},
+ {0x0F007058,0x00000000},
+ {0x0F00705c,0x00000000},
+ {0x0F007060,0x00082ED6},
+ {0x0F007064,0x0000000A},
+ {0x0F007068,0x00000000},
+ {0x0F00706c,0x00000001},
+ {0x0F007070,0x00005000},
+ {0x0F007074,0x00000000},
+ {0x0F007078,0x00000000},
+ {0x0F00707C,0x00000000},
+ {0x0F007080,0x00000000},
+ {0x0F007084,0x00000000},
+ {0x0F007088,0x01000001},
+ {0x0F00708c,0x00000101},
+ {0x0F007090,0x00000000},
+ {0x0F007094,0x00010000},
+ {0x0F007098,0x00000000},
+ {0x0F0070C8,0x00000104},
+ //# Enable 2 ports within X-bar
+ {0x0F00A000,0x00000016},
+ //# Enable start bit within memory controller
+ {0x0F007018,0x01010000}
+};
+
+#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 //index for 0x0F007000
+static DDR_SET_NODE asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting
+ {0x0f000820,0x07F13FFF},
+ {0x0f000810,0x00002F95},
+ {0x0f000860,0x00000000},
+ {0x0f000880,0x000003DD},
+ {0x0f000840,0x0FFF1F00},
+ {0x0F00a044,0x1fffffff},
+ {0x0F00a040,0x1f000000},
+ {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz
+ {0x0F00a084,0x1Cffffff},// dump from here in internal memory
+ {0x0F00a080,0x1C000000},
+ {0x0F00A000,0x00000016},
+ {0x0f007000,0x00010001},
+ {0x0f007004,0x01000000},
+ {0x0f007008,0x01000001},
+ {0x0f00700c,0x00000000},
+ {0x0f007010,0x01000000},
+ {0x0f007014,0x01000100},
+ {0x0f007018,0x01000000},
+ {0x0f00701c,0x01020000},
+ {0x0f007020,0x04020107},
+ {0x0f007024,0x00000007},
+ {0x0f007028,0x02020200},
+ {0x0f00702c,0x0204040a},
+ {0x0f007030,0x04000000},
+ {0x0f007034,0x00000002},
+ {0x0f007038,0x1d060200},
+ {0x0f00703c,0x1c22221d},
+ {0x0f007040,0x8A116600},
+ {0x0f007044,0x222d0800},
+ {0x0f007048,0x02690204},
+ {0x0f00704c,0x00000000},
+ {0x0f007050,0x0100001c},
+ {0x0f007054,0x00000000},
+ {0x0f007058,0x00000000},
+ {0x0f00705c,0x00000000},
+ {0x0f007060,0x000A15D6},
+ {0x0f007064,0x0000000A},
+ {0x0f007068,0x00000000},
+ {0x0f00706c,0x00000001},
+ {0x0f007070,0x00004000},
+ {0x0f007074,0x00000000},
+ {0x0f007078,0x00000000},
+ {0x0f00707c,0x00000000},
+ {0x0f007080,0x00000000},
+ {0x0f007084,0x00000000},
+ {0x0f007088,0x01000001},
+ {0x0f00708c,0x00000101},
+ {0x0f007090,0x00000000},
+ {0x0f007094,0x00010000},
+ {0x0f007098,0x00000000},
+ {0x0F0070C8,0x00000104},
+ {0x0F007018,0x01010000}
+};
+
+
+int ddr_init(MINI_ADAPTER *Adapter)
+{
+ PDDR_SETTING psDDRSetting=NULL;
+ ULONG RegCount=0;
+ ULONG value = 0;
+ UINT uiResetValue = 0;
+ UINT uiClockSetting = 0;
+ int retval = STATUS_SUCCESS;
+
+ switch (Adapter->chip_id)
+ {
+ case 0xbece3200:
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting=asT3LP_DDRSetting80MHz;
+ RegCount=(sizeof(asT3LP_DDRSetting80MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting=asT3LP_DDRSetting100MHz;
+ RegCount=(sizeof(asT3LP_DDRSetting100MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_133_MHZ:
+ psDDRSetting=asT3LP_DDRSetting133MHz;
+ RegCount=(sizeof(asT3LP_DDRSetting133MHz)/
+ sizeof(DDR_SETTING));
+ if(Adapter->bMipsConfig == MIPS_200_MHZ)
+ {
+ uiClockSetting = 0x03F13652;
+ }
+ else
+ {
+ uiClockSetting = 0x03F1365B;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ break;
+ case T3LPB:
+ case BCS220_2:
+ case BCS220_2BC:
+ case BCS250_BC:
+ case BCS220_3 :
+ /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive
+ * (please check current value and additionally set these bits)
+ */
+ if( (Adapter->chip_id != BCS220_2) &&
+ (Adapter->chip_id != BCS220_2BC) &&
+ (Adapter->chip_id != BCS220_3) )
+ {
+ retval= rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue |= 0x44;
+ retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, WRM, DBG_LVL_ALL, "%s:%d WRM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ }
+ switch(Adapter->DDRSetting)
+ {
+
+
+
+ case DDR_80_MHZ:
+ psDDRSetting = asT3LPB_DDRSetting80MHz;
+ RegCount=(sizeof(asT3B_DDRSetting80MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting=asT3LPB_DDRSetting100MHz;
+ RegCount=(sizeof(asT3B_DDRSetting100MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_133_MHZ:
+ psDDRSetting = asT3LPB_DDRSetting133MHz;
+ RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+ sizeof(DDR_SETTING));
+
+ if(Adapter->bMipsConfig == MIPS_200_MHZ)
+ {
+ uiClockSetting = 0x03F13652;
+ }
+ else
+ {
+ uiClockSetting = 0x03F1365B;
+ }
+ break;
+
+ case DDR_160_MHZ:
+ psDDRSetting = asT3LPB_DDRSetting160MHz;
+ RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SETTING);
+
+ if(Adapter->bMipsConfig == MIPS_200_MHZ)
+ {
+ uiClockSetting = 0x03F137D2;
+ }
+ else
+ {
+ uiClockSetting = 0x03F137DB;
+ }
+ }
+ break;
+
+ case 0xbece0110:
+ case 0xbece0120:
+ case 0xbece0121:
+ case 0xbece0130:
+ case 0xbece0300:
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3_DDRSetting80MHz;
+ RegCount = (sizeof(asT3_DDRSetting80MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting = asT3_DDRSetting100MHz;
+ RegCount = (sizeof(asT3_DDRSetting100MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_133_MHZ:
+ psDDRSetting = asT3_DDRSetting133MHz;
+ RegCount = (sizeof(asT3_DDRSetting133MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ default:
+ return -EINVAL;
+ }
+ case 0xbece0310:
+ {
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3B_DDRSetting80MHz;
+ RegCount=(sizeof(asT3B_DDRSetting80MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting=asT3B_DDRSetting100MHz;
+ RegCount=(sizeof(asT3B_DDRSetting100MHz)/
+ sizeof(DDR_SETTING));
+ break;
+ case DDR_133_MHZ:
+
+ if(Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected.
+ {
+ memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ,
+ sizeof(asDPLL_266MHZ));
+ psDDRSetting = asT3B_DDRSetting133MHz;
+ RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+ sizeof(DDR_SETTING));
+ }
+ else
+ {
+ psDDRSetting = asT3B_DDRSetting133MHz;
+ RegCount=(sizeof(asT3B_DDRSetting133MHz)/
+ sizeof(DDR_SETTING));
+ if(Adapter->bMipsConfig == MIPS_200_MHZ)
+ {
+ uiClockSetting = 0x07F13652;
+ }
+ else
+ {
+ uiClockSetting = 0x07F1365B;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ }
+ default:
+ return -EINVAL;
+ }
+
+ value=0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount);
+ while(RegCount && !retval)
+ {
+ if(uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
+ {
+ value = uiClockSetting;
+ }
+ else
+ {
+ value = psDDRSetting->ulRegValue;
+ }
+ retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value));
+ if(STATUS_SUCCESS != retval) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
+ break;
+ }
+
+ RegCount--;
+ psDDRSetting++;
+ }
+
+ if(Adapter->chip_id >= 0xbece3300 )
+ {
+
+ mdelay(3);
+ if( (Adapter->chip_id != BCS220_2)&&
+ (Adapter->chip_id != BCS220_2BC)&&
+ (Adapter->chip_id != BCS220_3))
+ {
+ /* drive MDDR to half in case of UMA-B: */
+ uiResetValue = 0x01010001;
+ retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x00040020;
+ retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x01020101;
+ retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x01010000;
+ retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ }
+ mdelay(3);
+
+ /* DC/DC standby change...
+ * This is to be done only for Hybrid PMU mode.
+ * with the current h/w there is no way to detect this.
+ * and since we dont have internal PMU lets do it under UMA-B chip id.
+ * we will change this when we will have internal PMU.
+ */
+ if(Adapter->PmuMode == HYBRID_MODE_7C)
+ {
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x1322a8;
+ retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x132296;
+ retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ }
+ else if(Adapter->PmuMode == HYBRID_MODE_6 )
+ {
+
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x6003229a;
+ retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ uiResetValue = 0x1322a8;
+ retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+ }
+
+ }
+ Adapter->bDDRInitDone = TRUE;
+ return retval;
+}
+
+int download_ddr_settings(PMINI_ADAPTER Adapter)
+{
+ PDDR_SET_NODE psDDRSetting=NULL;
+ ULONG RegCount=0;
+ unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY;
+ UINT value = 0;
+ int retval = STATUS_SUCCESS;
+ BOOLEAN bOverrideSelfRefresh = FALSE;
+
+ switch (Adapter->chip_id)
+ {
+ case 0xbece3200:
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3LP_DDRSetting80MHz;
+ RegCount = (sizeof(asT3LP_DDRSetting80MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+ psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting = asT3LP_DDRSetting100MHz;
+ RegCount = (sizeof(asT3LP_DDRSetting100MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+ psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
+ break;
+ case DDR_133_MHZ:
+ bOverrideSelfRefresh = TRUE;
+ psDDRSetting = asT3LP_DDRSetting133MHz;
+ RegCount = (sizeof(asT3LP_DDRSetting133MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+ psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ case T3LPB:
+ case BCS220_2:
+ case BCS220_2BC:
+ case BCS250_BC:
+ case BCS220_3 :
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3LPB_DDRSetting80MHz;
+ RegCount=(sizeof(asT3LPB_DDRSetting80MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+ psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting = asT3LPB_DDRSetting100MHz;
+ RegCount = (sizeof(asT3LPB_DDRSetting100MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+ psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
+ break;
+ case DDR_133_MHZ:
+ bOverrideSelfRefresh = TRUE;
+ psDDRSetting = asT3LPB_DDRSetting133MHz;
+ RegCount = (sizeof(asT3LPB_DDRSetting133MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+ psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
+ break;
+
+ case DDR_160_MHZ:
+ bOverrideSelfRefresh = TRUE;
+ psDDRSetting = asT3LPB_DDRSetting160MHz;
+ RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SET_NODE);
+ RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ;
+ psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case 0xbece0300:
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3_DDRSetting80MHz;
+ RegCount = (sizeof(asT3_DDRSetting80MHz)/sizeof(DDR_SET_NODE));
+ RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+ psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting = asT3_DDRSetting100MHz;
+ RegCount = (sizeof(asT3_DDRSetting100MHz)/sizeof(DDR_SET_NODE));
+ RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+ psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
+ break;
+ case DDR_133_MHZ:
+ psDDRSetting = asT3_DDRSetting133MHz;
+ RegCount = (sizeof(asT3_DDRSetting133MHz)/sizeof(DDR_SET_NODE));
+ RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+ psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case 0xbece0310:
+ {
+ switch (Adapter->DDRSetting)
+ {
+ case DDR_80_MHZ:
+ psDDRSetting = asT3B_DDRSetting80MHz;
+ RegCount = (sizeof(asT3B_DDRSetting80MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ;
+ psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ;
+ break;
+ case DDR_100_MHZ:
+ psDDRSetting = asT3B_DDRSetting100MHz;
+ RegCount = (sizeof(asT3B_DDRSetting100MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ;
+ psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ;
+ break;
+ case DDR_133_MHZ:
+ bOverrideSelfRefresh = TRUE;
+ psDDRSetting = asT3B_DDRSetting133MHz;
+ RegCount = (sizeof(asT3B_DDRSetting133MHz)/sizeof(DDR_SET_NODE));
+ RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ;
+ psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ;
+ break;
+ }
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+ //total number of Register that has to be dumped
+ value =RegCount ;
+ retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
+
+ return retval;
+ }
+ ul_ddr_setting_load_addr+=sizeof(ULONG);
+ /*signature */
+ value =(0x1d1e0dd0);
+ retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
+ return retval;
+ }
+
+ ul_ddr_setting_load_addr+=sizeof(ULONG);
+ RegCount*=(sizeof(DDR_SETTING)/sizeof(ULONG));
+
+ while(RegCount && !retval)
+ {
+ value = psDDRSetting->ulRegAddress ;
+ retval = wrmalt( Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ ul_ddr_setting_load_addr+=sizeof(ULONG);
+ if(!retval)
+ {
+ if(bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018))
+ {
+ value = (psDDRSetting->ulRegValue |(1<<8));
+ if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr,
+ &value, sizeof(value))){
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
+ break;
+ }
+ }
+ else
+ {
+ value = psDDRSetting->ulRegValue;
+
+ if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr ,
+ &value, sizeof(value))){
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
+ break;
+ }
+ }
+ }
+ ul_ddr_setting_load_addr+=sizeof(ULONG);
+ RegCount--;
+ psDDRSetting++;
+ }
+ return retval;
+}
+
+#endif
+
diff --git a/drivers/staging/bcm/DDRInit.h b/drivers/staging/bcm/DDRInit.h
new file mode 100644
index 000000000000..550e260df539
--- /dev/null
+++ b/drivers/staging/bcm/DDRInit.h
@@ -0,0 +1,9 @@
+#ifndef _DDR_INIT_H_
+#define _DDR_INIT_H_
+
+
+
+int ddr_init(PMINI_ADAPTER psAdapter);
+int download_ddr_settings(PMINI_ADAPTER psAdapter);
+
+#endif
diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c
new file mode 100644
index 000000000000..213f4bcc5dfc
--- /dev/null
+++ b/drivers/staging/bcm/Debug.c
@@ -0,0 +1,40 @@
+#include "headers.h"
+
+char *buff_dump_base[]={"DEC", "HEX", "OCT", "BIN" };
+
+static UINT current_debug_level=BCM_SCREAM;
+
+int bcm_print_buffer( UINT debug_level, const char *function_name,
+ char *file_name, int line_number, unsigned char *buffer, int bufferlen, unsigned int base)
+{
+ if(debug_level>=current_debug_level)
+ {
+ int i=0;
+ printk("\n%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", file_name, function_name, line_number, bufferlen, buff_dump_base[1]);
+ for(;i<bufferlen;i++)
+ {
+ if(i && !(i%16) )
+ printk("\n");
+ switch(base)
+ {
+ case BCM_BASE_TYPE_DEC:
+ printk("%03d ", buffer[i]);
+ break;
+ case BCM_BASE_TYPE_OCT:
+ printk("%0x03o ", buffer[i]);
+ break;
+ case BCM_BASE_TYPE_BIN:
+ printk("%02x ", buffer[i]);
+ break;
+ case BCM_BASE_TYPE_HEX:
+ default:
+ printk("%02X ", buffer[i]);
+ break;
+ }
+ }
+ printk("\n");
+ }
+ return 0;
+}
+
+
diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h
new file mode 100644
index 000000000000..3d788b59ab57
--- /dev/null
+++ b/drivers/staging/bcm/Debug.h
@@ -0,0 +1,297 @@
+/*
+ * Debug.h
+ *
+ * Dynamic (runtime) debug framework implementation.
+ * -kaiwan.
+ */
+#ifndef _DEBUG_H
+#define _DEBUG_H
+#include <linux/string.h>
+#define NONE 0xFFFF
+
+typedef enum _BASE_TYPE
+{
+ BCM_BASE_TYPE_DEC,
+ BCM_BASE_TYPE_OCT,
+ BCM_BASE_TYPE_BIN,
+ BCM_BASE_TYPE_HEX,
+ BCM_BASE_TYPE_NONE,
+} BASE_TYPE, *PBASE_TYPE;
+
+int bcm_print_buffer( UINT debug_level, const char *function_name,
+ char *file_name, int line_number, unsigned char *buffer, int bufferlen, BASE_TYPE base);
+
+#ifdef BCM_SHM_INTERFACE
+#define CPE_VIRTUAL_ERROR_CODE_BASE_ADDR (0xBFC02E00 + 0x4C)
+// ERROR codes for debugging
+extern unsigned char u32ErrorCounter ;
+#define ERROR_DEVICE_REMOVED 0x1
+#define ERROR_LEADER_LENGTH_ZERO 0x2
+#define ERROR_LEADER_LENGTH_CORRUPTED 0x3
+#define ERROR_NO_SKBUFF 0x4
+
+#define ERROR_DL_MODULE 0xaa000000
+extern void CPE_ERROR_LOG(unsigned int module,unsigned int code);
+
+#endif
+
+
+
+
+//--------------------------------------------------------------------------------
+
+/* TYPE and SUBTYPE
+ * Define valid TYPE (or category or code-path, however you like to think of it)
+ * and SUBTYPE s.
+ * Type and SubType are treated as bitmasks.
+ */
+/*-----------------BEGIN TYPEs------------------------------------------*/
+#define DBG_TYPE_INITEXIT (1 << 0) // 1
+#define DBG_TYPE_TX (1 << 1) // 2
+#define DBG_TYPE_RX (1 << 2) // 4
+#define DBG_TYPE_OTHERS (1 << 3) // 8
+/*-----------------END TYPEs------------------------------------------*/
+#define NUMTYPES 4 // careful!
+
+/*-----------------BEGIN SUBTYPEs---------------------------------------*/
+
+/*-SUBTYPEs for TX : TYPE is DBG_TYPE_TX -----//
+ Transmit.c ,Arp.c, LeakyBucket.c, And Qos.c
+ total 17 macros */
+// Transmit.c
+#define TX 1
+#define MP_SEND (TX<<0)
+#define NEXT_SEND (TX<<1)
+#define TX_FIFO (TX<<2)
+#define TX_CONTROL (TX<<3)
+
+// Arp.c
+#define IP_ADDR (TX<<4)
+#define ARP_REQ (TX<<5)
+#define ARP_RESP (TX<<6)
+
+// dhcp.c
+//#define DHCP TX
+//#define DHCP_REQ (DHCP<<7)
+
+// Leakybucket.c
+#define TOKEN_COUNTS (TX<<8)
+#define CHECK_TOKENS (TX<<9)
+#define TX_PACKETS (TX<<10)
+#define TIMER (TX<<11)
+
+// Qos.c
+#define QOS TX
+#define QUEUE_INDEX (QOS<<12)
+#define IPV4_DBG (QOS<<13)
+#define IPV6_DBG (QOS<<14)
+#define PRUNE_QUEUE (QOS<<15)
+#define SEND_QUEUE (QOS<<16)
+
+//TX_Misc
+#define TX_OSAL_DBG (TX<<17)
+
+
+//--SUBTYPEs for ------INIT & EXIT---------------------
+/*------------ TYPE is DBG_TYPE_INITEXIT -----//
+DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c */
+#define MP 1
+#define DRV_ENTRY (MP<<0)
+#define MP_INIT (MP<<1)
+#define READ_REG (MP<<3)
+#define DISPATCH (MP<<2)
+#define CLAIM_ADAP (MP<<4)
+#define REG_IO_PORT (MP<<5)
+#define INIT_DISP (MP<<6)
+#define RX_INIT (MP<<7)
+
+
+//-SUBTYPEs for --RX----------------------------------
+//------------RX : TYPE is DBG_TYPE_RX -----//
+// Receive.c
+#define RX 1
+#define RX_DPC (RX<<0)
+#define RX_CTRL (RX<<3)
+#define RX_DATA (RX<<4)
+#define MP_RETURN (RX<<1)
+#define LINK_MSG (RX<<2)
+
+
+//-SUBTYPEs for ----OTHER ROUTINES------------------
+//------------OTHERS : TYPE is DBG_TYPE_OTHER -----//
+// HaltnReset,CheckForHang,PnP,Misc,CmHost
+// total 12 macros
+#define OTHERS 1
+// ??ISR.C
+
+#define ISR OTHERS
+#define MP_DPC (ISR<<0)
+
+// HaltnReset.c
+#define HALT OTHERS
+#define MP_HALT (HALT<<1)
+#define CHECK_HANG (HALT<<2)
+#define MP_RESET (HALT<<3)
+#define MP_SHUTDOWN (HALT<<4)
+
+// pnp.c
+#define PNP OTHERS
+#define MP_PNP (PNP<<5)
+
+// Misc.c
+#define MISC OTHERS
+#define DUMP_INFO (MISC<<6)
+#define CLASSIFY (MISC<<7)
+#define LINK_UP_MSG (MISC<<8)
+#define CP_CTRL_PKT (MISC<<9)
+#define DUMP_CONTROL (MISC<<10)
+#define LED_DUMP_INFO (MISC<<11)
+
+// CmHost.c
+#define CMHOST OTHERS
+
+
+#define SERIAL (OTHERS<<12)
+#define IDLE_MODE (OTHERS<<13)
+
+#define WRM (OTHERS<<14)
+#define RDM (OTHERS<<15)
+
+// TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ?
+#define PHS_SEND (OTHERS<<16)
+#define PHS_RECIEVE (OTHERS<<17)
+#define PHS_MODULE (OTHERS<<18)
+
+#define INTF_INIT (OTHERS<<19)
+#define INTF_ERR (OTHERS<<20)
+#define INTF_WARN (OTHERS<<21)
+#define INTF_NORM (OTHERS<<22)
+
+#define IRP_COMPLETION (OTHERS<<23)
+#define SF_DESCRIPTOR_CNTS (OTHERS<<24)
+#define PHS_DISPATCH (OTHERS << 25)
+#define OSAL_DBG (OTHERS << 26)
+#define NVM_RW (OTHERS << 27)
+
+#define HOST_MIBS (OTHERS << 28)
+#define CONN_MSG (CMHOST << 29)
+//#define OTHERS_MISC (OTHERS << 29) // ProcSupport.c
+/*-----------------END SUBTYPEs------------------------------------------*/
+
+
+/* Debug level
+ * We have 8 debug levels, in (numerical) increasing order of verbosity.
+ * IMP: Currently implementing ONLY DBG_LVL_ALL , i.e. , all debug prints will
+ * appear (of course, iff global debug flag is ON and we match the Type and SubType).
+ * Finer granularity debug levels are currently not in use, although the feature exists.
+ *
+ * Another way to say this:
+ * All the debug prints currently have 'debug_level' set to DBG_LVL_ALL .
+ * You can compile-time change that to any of the below, if you wish to. However, as of now, there's
+ * no dynamic facility to have the userspace 'TestApp' set debug_level. Slated for future expansion.
+ */
+#define BCM_ALL 7
+#define BCM_LOW 6
+#define BCM_PRINT 5
+#define BCM_NORMAL 4
+#define BCM_MEDIUM 3
+#define BCM_SCREAM 2
+#define BCM_ERR 1
+/* Not meant for developer in debug prints.
+ * To be used to disable all prints by setting the DBG_LVL_CURR to this value */
+#define BCM_NONE 0
+
+/* The current driver logging level.
+ * Everything at this level and (numerically) lower (meaning higher prio)
+ * is logged.
+* Replace 'BCM_ALL' in the DBG_LVL_CURR macro with the logging level desired.
+ * For eg. to set the logging level to 'errors only' use:
+ * #define DBG_LVL_CURR (BCM_ERR)
+ */
+
+#define DBG_LVL_CURR (BCM_ALL)
+#define DBG_LVL_ALL BCM_ALL
+
+/*---Userspace mapping of Debug State.
+ * Delibrately matches that of the Windows driver..
+ * The TestApp's ioctl passes this struct to us.
+ */
+typedef struct
+{
+ unsigned int Subtype, Type;
+ unsigned int OnOff;
+// unsigned int debug_level; /* future expansion */
+} __attribute__((packed)) USER_BCM_DBG_STATE;
+
+//---Kernel-space mapping of Debug State
+typedef struct _S_BCM_DEBUG_STATE {
+ UINT type;
+ /* A bitmap of 32 bits for Subtype per Type.
+ * Valid indexes in 'subtype' array are *only* 1,2,4 and 8,
+ * corresponding to valid Type values. Hence we use the 'Type' field
+ * as the index value, ignoring the array entries 0,3,5,6,7 !
+ */
+ UINT subtype[(NUMTYPES*2)+1];
+ UINT debug_level;
+} S_BCM_DEBUG_STATE;
+/* Instantiated in the Adapter structure */
+/* We'll reuse the debug level parameter to include a bit (the MSB) to indicate whether or not
+ * we want the function's name printed. */
+#define DBG_NO_FUNC_PRINT 1 << 31
+#define DBG_LVL_BITMASK 0xFF
+
+//--- Only for direct printk's; "hidden" to API.
+#define DBG_TYPE_PRINTK 3
+#define PRINTKS_ON 1 // "hidden" from API, set to 0 to turn off all printk's
+
+#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) do { \
+ if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
+ printk ("%s:" string, __FUNCTION__, ##args); \
+ printk("\n"); \
+ } else if (!Adapter) \
+ ; \
+ else { \
+ if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
+ ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
+ if (dbg_level & DBG_NO_FUNC_PRINT) \
+ printk (string, ##args); \
+ else \
+ { \
+ printk ("%s:" string, __FUNCTION__, ##args); \
+ printk("\n"); \
+ } \
+ } \
+ } \
+} while (0)
+
+#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \
+ if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
+ bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
+ } else if (!Adapter) \
+ ; \
+ else { \
+ if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
+ ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
+ if (dbg_level & DBG_NO_FUNC_PRINT) \
+ bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
+ else \
+ bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
+ } \
+ } \
+ } while (0)
+
+
+#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \
+ int i; \
+ for (i=0; i<(NUMTYPES*2)+1; i++) { \
+ if ((i == 1) || (i == 2) || (i == 4) || (i == 8)) { \
+ /* CAUTION! Forcefully turn on ALL debug paths and subpaths! \
+ Adapter->stDebugState.subtype[i] = 0xffffffff; */ \
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "subtype[%d] = 0x%08x\n", \
+ i, Adapter->stDebugState.subtype[i]); \
+ } \
+ } \
+} while (0)
+
+#endif
+
diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c
new file mode 100644
index 000000000000..849951345ab2
--- /dev/null
+++ b/drivers/staging/bcm/HandleControlPacket.c
@@ -0,0 +1,247 @@
+/**
+@file HandleControlPacket.c
+This file contains the routines to deal with
+sending and receiving of control packets.
+*/
+#include "headers.h"
+
+/**
+When a control packet is received, analyze the
+"status" and call appropriate response function.
+Enqueue the control packet for Application.
+@return None
+*/
+VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
+ struct sk_buff *skb) /**<Pointer to the socket buffer*/
+{
+ PPER_TARANG_DATA pTarang = NULL;
+ BOOLEAN HighPriorityMessage = FALSE;
+ struct sk_buff * newPacket = NULL;
+ CHAR cntrl_msg_mask_bit = 0;
+ BOOLEAN drop_pkt_flag = TRUE ;
+ USHORT usStatus = *(PUSHORT)(skb->data);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "=====>");
+ /* Get the Leader field */
+
+ switch(usStatus)
+ {
+ case CM_RESPONSES: // 0xA0
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
+ HighPriorityMessage = TRUE ;
+ break;
+ case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
+ HighPriorityMessage = TRUE ;
+ if(Adapter->LinkStatus==LINKUP_DONE)
+ {
+ CmControlResponseMessage(Adapter,(skb->data +sizeof(USHORT)));
+ }
+ break;
+ case LINK_CONTROL_RESP: //0xA2
+ case STATUS_RSP: //0xA1
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"LINK_CONTROL_RESP");
+ HighPriorityMessage = TRUE ;
+ LinkControlResponseMessage(Adapter,(skb->data + sizeof(USHORT)));
+ break;
+ case STATS_POINTER_RESP: //0xA6
+ HighPriorityMessage = TRUE ;
+ StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
+ break;
+ case IDLE_MODE_STATUS: //0xA3
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"IDLE_MODE_STATUS Type Message Got from F/W");
+ InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
+ sizeof(USHORT)));
+ HighPriorityMessage = TRUE ;
+ break;
+
+ case AUTH_SS_HOST_MSG:
+ HighPriorityMessage = TRUE ;
+ break;
+
+ default:
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"Got Default Response");
+ /* Let the Application Deal with This Packet */
+ break;
+ }
+
+ //Queue The Control Packet to The Application Queues
+ down(&Adapter->RxAppControlQueuelock);
+
+ for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next)
+ {
+ if(Adapter->device_removed)
+ {
+ break;
+ }
+
+ drop_pkt_flag = TRUE ;
+ /*
+ There are cntrl msg from A0 to AC. It has been mapped to 0 to C bit in the cntrl mask.
+ Also, by default AD to BF has been masked to the rest of the bits... which wil be ON by default.
+ if mask bit is enable to particular pkt status, send it out to app else stop it.
+ */
+ cntrl_msg_mask_bit = (usStatus & 0x1F);
+ //printk("\ninew msg mask bit which is disable in mask:%X", cntrl_msg_mask_bit);
+ if(pTarang->RxCntrlMsgBitMask & (1<<cntrl_msg_mask_bit))
+ drop_pkt_flag = FALSE;
+
+ if ((drop_pkt_flag == TRUE) || (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN) ||
+ ((pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN/2) && (HighPriorityMessage == FALSE)))
+ {
+ /*
+ Assumption:-
+ 1. every tarang manages it own dropped pkt statitistics
+ 2. Total packet dropped per tarang will be equal to the sum of all types of dropped
+ pkt by that tarang only.
+
+ */
+ switch(*(PUSHORT)skb->data)
+ {
+ case CM_RESPONSES:
+ pTarang->stDroppedAppCntrlMsgs.cm_responses++;
+ break;
+ case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
+ pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
+ break;
+ case LINK_CONTROL_RESP:
+ pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
+ break;
+ case STATUS_RSP:
+ pTarang->stDroppedAppCntrlMsgs.status_rsp++;
+ break;
+ case STATS_POINTER_RESP:
+ pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
+ break;
+ case IDLE_MODE_STATUS:
+ pTarang->stDroppedAppCntrlMsgs.idle_mode_status++ ;
+ break;
+ case AUTH_SS_HOST_MSG:
+ pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++ ;
+ break;
+ default:
+ pTarang->stDroppedAppCntrlMsgs.low_priority_message++ ;
+ break;
+ }
+
+ continue;
+ }
+
+ newPacket = skb_clone(skb, GFP_KERNEL);
+ if (!newPacket)
+ break;
+ ENQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail,
+ newPacket);
+ pTarang->AppCtrlQueueLen++;
+ }
+ up(&Adapter->RxAppControlQueuelock);
+ wake_up(&Adapter->process_read_wait_queue);
+ bcm_kfree_skb(skb);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible");
+}
+
+/**
+@ingroup ctrl_pkt_functions
+Thread to handle control pkt reception
+*/
+int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter object*/
+ )
+{
+ struct sk_buff *ctrl_packet= NULL;
+ unsigned long flags = 0;
+ //struct timeval tv ;
+ //int *puiBuffer = NULL ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Entering to make thread wait on control packet event!");
+ while(1)
+ {
+ wait_event_interruptible(Adapter->process_rx_cntrlpkt,
+ atomic_read(&Adapter->cntrlpktCnt) ||
+ Adapter->bWakeUpDevice ||
+ kthread_should_stop()
+ );
+
+
+ if(kthread_should_stop())
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Exiting \n");
+ return 0;
+ }
+ if(TRUE == Adapter->bWakeUpDevice)
+ {
+ Adapter->bWakeUpDevice = FALSE;
+ if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) &&
+ ((TRUE == Adapter->IdleMode)|| (TRUE == Adapter->bShutStatus)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Calling InterfaceAbortIdlemode\n");
+ // Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
+ InterfaceIdleModeWakeup (Adapter);
+ }
+ continue;
+ }
+
+ while(atomic_read(&Adapter->cntrlpktCnt))
+ {
+ spin_lock_irqsave(&Adapter->control_queue_lock, flags);
+ ctrl_packet = Adapter->RxControlHead;
+ if(ctrl_packet)
+ {
+ DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
+// Adapter->RxControlHead=ctrl_packet->next;
+ ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_packets++;
+ ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_bytes+=
+ ((PLEADER)ctrl_packet->data)->PLength;
+ }
+ #if 0 //Idle mode debug profiling...
+ if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS)
+ {
+ puiBuffer = (PUINT)(ctrl_packet->data +sizeof(USHORT));
+ if((ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD))
+ {
+ memset(&tv, 0, sizeof(tv));
+ do_gettimeofday(&tv);
+ if((ntohl(*(puiBuffer+1)) == 0))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode Wake-up Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode req Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
+ }
+ }
+ else if((ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "GOT IDLE_MODE_SF_UPDATE MSG at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
+ }
+ }
+ #endif
+
+ spin_unlock_irqrestore (&Adapter->control_queue_lock, flags);
+ handle_rx_control_packet(Adapter, ctrl_packet);
+ atomic_dec(&Adapter->cntrlpktCnt);
+ }
+
+ SetUpTargetDsxBuffers(Adapter);
+ }
+ return STATUS_SUCCESS;
+}
+
+INT flushAllAppQ()
+{
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ PPER_TARANG_DATA pTarang = NULL;
+ struct sk_buff *PacketToDrop = NULL;
+ for(pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next)
+ {
+ while(pTarang->RxAppControlHead != NULL)
+ {
+ PacketToDrop=pTarang->RxAppControlHead;
+ DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
+ bcm_kfree_skb(PacketToDrop);
+ }
+ pTarang->AppCtrlQueueLen = 0;
+ //dropped contrl packet statistics also should be reset.
+ memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+
+ }
+ return STATUS_SUCCESS ;
+}
+
+
diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h
new file mode 100644
index 000000000000..f17a4f13474c
--- /dev/null
+++ b/drivers/staging/bcm/HostMIBSInterface.h
@@ -0,0 +1,230 @@
+
+
+#ifndef _HOST_MIBSINTERFACE_H
+#define _HOST_MIBSINTERFACE_H
+
+/*
+ * Copyright (c) 2007 Beceem Communications Pvt. Ltd
+ * File Name: HostMIBSInterface.h
+ * Abstract: This file contains DS used by the Host to update the Host
+ * statistics used for the MIBS.
+ */
+
+#define MIBS_MAX_CLASSIFIERS 100
+#define MIBS_MAX_PHSRULES 100
+#define MIBS_MAX_SERVICEFLOWS 17
+#define MIBS_MAX_IP_RANGE_LENGTH 4
+#define MIBS_MAX_PORT_RANGE 4
+#define MIBS_MAX_PROTOCOL_LENGTH 32
+#define MIBS_MAX_PHS_LENGTHS 255
+#define MIBS_IPV6_ADDRESS_SIZEINBYTES 0x10
+#define MIBS_IP_LENGTH_OF_ADDRESS 4
+#define MIBS_MAX_HIST_ENTRIES 12
+#define MIBS_PKTSIZEHIST_RANGE 128
+
+typedef union _U_MIBS_IP_ADDRESS
+{
+ struct
+ {
+ //Source Ip Address Range
+ ULONG ulIpv4Addr[MIBS_MAX_IP_RANGE_LENGTH];
+ //Source Ip Mask Address Range
+ ULONG ulIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH];
+ };
+ struct
+ {
+ //Source Ip Address Range
+ ULONG ulIpv6Addr[MIBS_MAX_IP_RANGE_LENGTH * 4];
+ //Source Ip Mask Address Range
+ ULONG ulIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * 4];
+
+ };
+ struct
+ {
+ UCHAR ucIpv4Address[MIBS_MAX_IP_RANGE_LENGTH *
+ MIBS_IP_LENGTH_OF_ADDRESS];
+ UCHAR ucIpv4Mask[MIBS_MAX_IP_RANGE_LENGTH *
+ MIBS_IP_LENGTH_OF_ADDRESS];
+ };
+ struct
+ {
+ UCHAR ucIpv6Address[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
+ UCHAR ucIpv6Mask[MIBS_MAX_IP_RANGE_LENGTH * MIBS_IPV6_ADDRESS_SIZEINBYTES];
+ };
+}U_MIBS_IP_ADDRESS;
+
+
+typedef struct _S_MIBS_HOST_INFO
+{
+ ULONG64 GoodTransmits;
+ ULONG64 GoodReceives;
+ // this to keep track of the Tx and Rx MailBox Registers.
+ ULONG NumDesUsed;
+ ULONG CurrNumFreeDesc;
+ ULONG PrevNumFreeDesc;
+ // to keep track the no of byte recieved
+ ULONG PrevNumRcevBytes;
+ ULONG CurrNumRcevBytes;
+
+ /* QOS Related */
+ ULONG BEBucketSize;
+ ULONG rtPSBucketSize;
+ ULONG LastTxQueueIndex;
+ BOOLEAN TxOutofDescriptors;
+ BOOLEAN TimerActive;
+ UINT32 u32TotalDSD;
+ UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+ UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
+}S_MIBS_HOST_INFO;
+
+typedef struct _S_MIBS_CLASSIFIER_RULE
+{
+ ULONG ulSFID;
+ UCHAR ucReserved[2];
+ B_UINT16 uiClassifierRuleIndex;
+ BOOLEAN bUsed;
+ USHORT usVCID_Value;
+ // This field detemines the Classifier Priority
+ B_UINT8 u8ClassifierRulePriority;
+ U_MIBS_IP_ADDRESS stSrcIpAddress;
+ /*IP Source Address Length*/
+ UCHAR ucIPSourceAddressLength;
+
+ U_MIBS_IP_ADDRESS stDestIpAddress;
+ /* IP Destination Address Length */
+ UCHAR ucIPDestinationAddressLength;
+ UCHAR ucIPTypeOfServiceLength;//Type of service Length
+ UCHAR ucTosLow;//Tos Low
+ UCHAR ucTosHigh;//Tos High
+ UCHAR ucTosMask;//Tos Mask
+ UCHAR ucProtocolLength;//protocol Length
+ UCHAR ucProtocol[MIBS_MAX_PROTOCOL_LENGTH];//protocol Length
+ USHORT usSrcPortRangeLo[MIBS_MAX_PORT_RANGE];
+ USHORT usSrcPortRangeHi[MIBS_MAX_PORT_RANGE];
+ UCHAR ucSrcPortRangeLength;
+ USHORT usDestPortRangeLo[MIBS_MAX_PORT_RANGE];
+ USHORT usDestPortRangeHi[MIBS_MAX_PORT_RANGE];
+ UCHAR ucDestPortRangeLength;
+ BOOLEAN bProtocolValid;
+ BOOLEAN bTOSValid;
+ BOOLEAN bDestIpValid;
+ BOOLEAN bSrcIpValid;
+ UCHAR ucDirection;
+ BOOLEAN bIpv6Protocol;
+ UINT32 u32PHSRuleID;
+}S_MIBS_CLASSIFIER_RULE;
+
+
+typedef struct _S_MIBS_PHS_RULE
+{
+ ULONG ulSFID;
+ /// brief 8bit PHSI Of The Service Flow
+ B_UINT8 u8PHSI;
+ /// brief PHSF Of The Service Flow
+ B_UINT8 u8PHSFLength;
+ B_UINT8 u8PHSF[MIBS_MAX_PHS_LENGTHS];
+ /// brief PHSM Of The Service Flow
+ B_UINT8 u8PHSMLength;
+ B_UINT8 u8PHSM[MIBS_MAX_PHS_LENGTHS];
+ /// brief 8bit PHSS Of The Service Flow
+ B_UINT8 u8PHSS;
+ /// brief 8bit PHSV Of The Service Flow
+ B_UINT8 u8PHSV;
+ // Reserved bytes are 5, so that it is similar to S_PHS_RULE structure.
+ B_UINT8 reserved[5];
+
+ LONG PHSModifiedBytes;
+ ULONG PHSModifiedNumPackets;
+ ULONG PHSErrorNumPackets;
+}S_MIBS_PHS_RULE;
+
+typedef struct _S_MIBS_EXTSERVICEFLOW_PARAMETERS
+{
+ UINT32 wmanIfSfid;
+ UINT32 wmanIfCmnCpsSfState;
+ UINT32 wmanIfCmnCpsMaxSustainedRate;
+ UINT32 wmanIfCmnCpsMaxTrafficBurst;
+ UINT32 wmanIfCmnCpsMinReservedRate;
+ UINT32 wmanIfCmnCpsToleratedJitter;
+ UINT32 wmanIfCmnCpsMaxLatency;
+ UINT32 wmanIfCmnCpsFixedVsVariableSduInd;
+ UINT32 wmanIfCmnCpsSduSize;
+ UINT32 wmanIfCmnCpsSfSchedulingType;
+ UINT32 wmanIfCmnCpsArqEnable;
+ UINT32 wmanIfCmnCpsArqWindowSize;
+ UINT32 wmanIfCmnCpsArqBlockLifetime;
+ UINT32 wmanIfCmnCpsArqSyncLossTimeout;
+ UINT32 wmanIfCmnCpsArqDeliverInOrder;
+ UINT32 wmanIfCmnCpsArqRxPurgeTimeout;
+ UINT32 wmanIfCmnCpsArqBlockSize;
+ UINT32 wmanIfCmnCpsMinRsvdTolerableRate;
+ UINT32 wmanIfCmnCpsReqTxPolicy;
+ UINT32 wmanIfCmnSfCsSpecification;
+ UINT32 wmanIfCmnCpsTargetSaid;
+
+}S_MIBS_EXTSERVICEFLOW_PARAMETERS;
+
+
+typedef struct _S_MIBS_SERVICEFLOW_TABLE
+{
+ //classification extension Rule
+ ULONG ulSFID;
+ USHORT usVCID_Value;
+ UINT uiThreshold;
+ // This field determines the priority of the SF Queues
+ B_UINT8 u8TrafficPriority;
+
+ BOOLEAN bValid;
+ BOOLEAN bActive;
+ BOOLEAN bActivateRequestSent;
+ //BE or rtPS
+ B_UINT8 u8QueueType;
+ //maximum size of the bucket for the queue
+ UINT uiMaxBucketSize;
+ UINT uiCurrentQueueDepthOnTarget;
+ UINT uiCurrentBytesOnHost;
+ UINT uiCurrentPacketsOnHost;
+ UINT uiDroppedCountBytes;
+ UINT uiDroppedCountPackets;
+ UINT uiSentBytes;
+ UINT uiSentPackets;
+ UINT uiCurrentDrainRate;
+ UINT uiThisPeriodSentBytes;
+ LARGE_INTEGER liDrainCalculated;
+ UINT uiCurrentTokenCount;
+ LARGE_INTEGER liLastUpdateTokenAt;
+ UINT uiMaxAllowedRate;
+ UINT NumOfPacketsSent;
+ UCHAR ucDirection;
+ USHORT usCID;
+ S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable;
+ UINT uiCurrentRxRate;
+ UINT uiThisPeriodRxBytes;
+ UINT uiTotalRxBytes;
+ UINT uiTotalTxBytes;
+}S_MIBS_SERVICEFLOW_TABLE;
+
+typedef struct _S_MIBS_DROPPED_APP_CNTRL_MESSAGES
+{
+ ULONG cm_responses;
+ ULONG cm_control_newdsx_multiclassifier_resp;
+ ULONG link_control_resp;
+ ULONG status_rsp;
+ ULONG stats_pointer_resp;
+ ULONG idle_mode_status;
+ ULONG auth_ss_host_msg;
+ ULONG low_priority_message;
+
+}S_MIBS_DROPPED_APP_CNTRL_MESSAGES;
+
+typedef struct _S_MIBS_HOST_STATS_MIBS
+{
+ S_MIBS_HOST_INFO stHostInfo;
+ S_MIBS_CLASSIFIER_RULE astClassifierTable[MIBS_MAX_CLASSIFIERS];
+ S_MIBS_SERVICEFLOW_TABLE astSFtable[MIBS_MAX_SERVICEFLOWS];
+ S_MIBS_PHS_RULE astPhsRulesTable[MIBS_MAX_PHSRULES];
+ S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs;
+}S_MIBS_HOST_STATS_MIBS;
+#endif
+
+
diff --git a/drivers/staging/bcm/HostMibs.h b/drivers/staging/bcm/HostMibs.h
new file mode 100644
index 000000000000..28a578311378
--- /dev/null
+++ b/drivers/staging/bcm/HostMibs.h
@@ -0,0 +1,7 @@
+#ifndef _HOST_MIBS_H
+#define _HOST_MIBS_H
+
+INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
+ PVOID ioBuffer,
+ ULONG inputBufferLength);
+#endif
diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c
new file mode 100644
index 000000000000..cb4ca9a44c88
--- /dev/null
+++ b/drivers/staging/bcm/IPv6Protocol.c
@@ -0,0 +1,400 @@
+#include "headers.h"
+
+UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength)
+{
+ UCHAR *pucRetHeaderPtr = NULL;
+ UCHAR *pucPayloadPtr = NULL;
+ USHORT usNextHeaderOffset = 0 ;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone))
+ {
+ *bParseDone = TRUE;
+ return NULL;
+
+ }
+
+ pucRetHeaderPtr = *ppucPayload;
+ pucPayloadPtr = *ppucPayload;
+
+ if(!pucRetHeaderPtr || !pucPayloadPtr)
+ {
+ *bParseDone = TRUE;
+ return NULL;
+ }
+
+ //Get the Nextt Header Type
+ *bParseDone = FALSE;
+
+
+
+ switch(*pucNextHeader)
+ {
+ case IPV6HDR_TYPE_HOPBYHOP:
+ {
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header");
+ usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader);
+ }
+ break;
+
+ case IPV6HDR_TYPE_ROUTING:
+ {
+ IPV6RoutingHeader *pstIpv6RoutingHeader;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header");
+ pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr;
+ usNextHeaderOffset += sizeof(IPV6RoutingHeader);
+ usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES;
+
+ }
+ break;
+ case IPV6HDR_TYPE_FRAGMENTATION:
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header");
+ usNextHeaderOffset+= sizeof(IPV6FragmentHeader);
+
+ }
+ break;
+ case IPV6HDR_TYPE_DESTOPTS:
+ {
+ IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr;
+ int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header");
+ usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader);
+ usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ;
+
+ }
+ break;
+ case IPV6HDR_TYPE_AUTHENTICATION:
+ {
+ IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr;
+ int nHdrLen = pstIpv6AuthHdr->ucLength;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header");
+ usNextHeaderOffset+= nHdrLen * 4;
+ }
+ break;
+ case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header");
+ *bParseDone = TRUE;
+
+ }
+ break;
+ case IPV6_ICMP_HDR_TYPE:
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header");
+ *bParseDone = TRUE;
+ }
+ break;
+ case TCP_HEADER_TYPE:
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header");
+ *bParseDone = TRUE;
+ }
+ break;
+ case UDP_HEADER_TYPE:
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header");
+ *bParseDone = TRUE;
+ }
+ break;
+ default :
+ {
+ *bParseDone = TRUE;
+
+ }
+ break;
+
+
+ }
+
+ if(*bParseDone == FALSE)
+ {
+ if(*pusPayloadLength <= usNextHeaderOffset)
+ {
+ *bParseDone = TRUE;
+ }
+ else
+ {
+ *pucNextHeader = *pucPayloadPtr;
+ pucPayloadPtr+=usNextHeaderOffset;
+ (*pusPayloadLength)-=usNextHeaderOffset;
+ }
+
+ }
+
+
+
+ *ppucPayload = pucPayloadPtr;
+ return pucRetHeaderPtr;
+}
+
+
+UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader)
+{
+ UCHAR *pIpv6HdrScanContext = pucPayload;
+ BOOLEAN bDone = FALSE;
+ UCHAR ucHeaderType =0;
+ UCHAR *pucNextHeader = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ if( !pucPayload || (usPayloadLength == 0))
+ {
+ return 0;
+ }
+
+ *pusSrcPort = *pusDestPort = 0;
+ ucHeaderType = ucNextHeader;
+ while(!bDone)
+ {
+ pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength);
+ if(bDone)
+ {
+ if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE))
+ {
+ *pusSrcPort=*((PUSHORT)(pucNextHeader));
+ *pusDestPort=*((PUSHORT)(pucNextHeader+2));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort));
+ }
+ break;
+
+ }
+ }
+ return ucHeaderType;
+}
+
+
+
+USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
+ PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
+ S_CLASSIFIER_RULE *pstClassifierRule )
+{
+ USHORT ushDestPort = 0;
+ USHORT ushSrcPort = 0;
+ UCHAR ucNextProtocolAboveIP =0;
+ IPV6Header *pstIpv6Header = NULL;
+ BOOLEAN bClassificationSucceed = FALSE;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n");
+
+ pstIpv6Header = (IPV6Header *)pcIpHeader;
+
+ DumpIpv6Header(pstIpv6Header);
+
+ //Try to get the next higher layer protocol and the Ports Nos if TCP or UDP
+ ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)),
+ &ushSrcPort,
+ &ushDestPort,
+ pstIpv6Header->usPayloadLength,
+ pstIpv6Header->ucNextHeader);
+
+ do
+ {
+ if(0 == pstClassifierRule->ucDirection)
+ {
+ //cannot be processed for classification.
+ // it is a down link connection
+ break;
+ }
+
+ if(!pstClassifierRule->bIpv6Protocol)
+ {
+ //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one.
+ break;
+ }
+
+ bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header);
+ if(!bClassificationSucceed)
+ break;
+
+ bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header);
+ if(!bClassificationSucceed)
+ break;
+
+ //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers
+ bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP);
+ if(!bClassificationSucceed)
+ break;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched");
+
+ if((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE))
+ {
+ //Match Src Port
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort));
+ bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort));
+ if(!bClassificationSucceed)
+ break;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched");
+
+ //Match Dest Port
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort));
+ bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort));
+ if(!bClassificationSucceed)
+ break;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched");
+ }
+ }while(0);
+
+ if(TRUE==bClassificationSucceed)
+ {
+ INT iMatchedSFQueueIndex = 0;
+ iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID);
+ if(iMatchedSFQueueIndex >= NO_OF_QUEUES)
+ {
+ bClassificationSucceed = FALSE;
+ }
+ else
+ {
+ if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
+ {
+ bClassificationSucceed = FALSE;
+ }
+ }
+ }
+
+ return bClassificationSucceed;
+}
+
+
+BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
+{
+ UINT uiLoopIndex=0;
+ UINT uiIpv6AddIndex=0;
+ UINT uiIpv6AddrNoLongWords = 4;
+ ULONG aulSrcIP[4];
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ /*
+ //This is the no. of Src Addresses ie Range of IP Addresses contained
+ //in the classifier rule for which we need to match
+ */
+ UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength;
+
+
+ if(0 == uiCountIPSrcAddresses)
+ return TRUE;
+
+
+ //First Convert the Ip Address in the packet to Host Endian order
+ for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
+ {
+ aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
+ }
+
+ for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Recieved Packet : \n ");
+ DumpIpv6Address(aulSrcIP);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n");
+ DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n");
+ DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]);
+
+ for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
+ {
+ if((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex])
+ != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex])
+ {
+ //Match failed for current Ipv6 Address.Try next Ipv6 Address
+ break;
+ }
+
+ if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1)
+ {
+ //Match Found
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n");
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
+{
+ UINT uiLoopIndex=0;
+ UINT uiIpv6AddIndex=0;
+ UINT uiIpv6AddrNoLongWords = 4;
+ ULONG aulDestIP[4];
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ /*
+ //This is the no. of Destination Addresses ie Range of IP Addresses contained
+ //in the classifier rule for which we need to match
+ */
+ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength;
+
+
+ if(0 == uiCountIPDestinationAddresses)
+ return TRUE;
+
+
+ //First Convert the Ip Address in the packet to Host Endian order
+ for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
+ {
+ aulDestIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
+ }
+
+ for(uiLoopIndex=0;uiLoopIndex<uiCountIPDestinationAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Recieved Packet : \n ");
+ DumpIpv6Address(aulDestIP);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n");
+ DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n");
+ DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]);
+
+ for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
+ {
+ if((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex])
+ != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex])
+ {
+ //Match failed for current Ipv6 Address.Try next Ipv6 Address
+ break;
+ }
+
+ if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1)
+ {
+ //Match Found
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n");
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+
+}
+
+VOID DumpIpv6Address(ULONG *puIpv6Address)
+{
+ UINT uiIpv6AddrNoLongWords = 4;
+ UINT uiIpv6AddIndex=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]);
+ }
+
+}
+
+VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
+{
+ UCHAR ucVersion;
+ UCHAR ucPrio ;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---");
+ ucVersion = pstIpv6Header->ucVersionPrio & 0xf0;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion);
+ ucPrio = pstIpv6Header->ucVersionPrio & 0x0f;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio);
+ //BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength));
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n");
+ DumpIpv6Address(pstIpv6Header->ulSrcIpAddress);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n");
+ DumpIpv6Address(pstIpv6Header->ulDestIpAddress);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---");
+
+
+}
diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h
new file mode 100644
index 000000000000..b93f7902e283
--- /dev/null
+++ b/drivers/staging/bcm/IPv6ProtocolHdr.h
@@ -0,0 +1,119 @@
+#ifndef _IPV6_PROTOCOL_DEFINES_
+#define _IPV6_PROTOCOL_DEFINES_
+
+
+#define IPV6HDR_TYPE_HOPBYHOP 0x0
+#define IPV6HDR_TYPE_ROUTING 0x2B
+#define IPV6HDR_TYPE_FRAGMENTATION 0x2C
+#define IPV6HDR_TYPE_DESTOPTS 0x3c
+#define IPV6HDR_TYPE_AUTHENTICATION 0x33
+#define IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD 0x34
+#define MASK_IPV6_CS_SPEC 0x2
+
+
+#define TCP_HEADER_TYPE 0x6
+#define UDP_HEADER_TYPE 0x11
+#define IPV6_ICMP_HDR_TYPE 0x2
+#define IPV6_FLOWLABEL_BITOFFSET 9
+
+#define IPV6_MAX_CHAINEDHDR_BUFFBYTES 0x64
+/*
+// Size of Dest Options field of Destinations Options Header
+// in bytes.
+*/
+#define IPV6_DESTOPTS_HDR_OPTIONSIZE 0x8
+
+//typedef unsigned char UCHAR;
+//typedef unsigned short USHORT;
+//typedef unsigned long int ULONG;
+
+typedef struct IPV6HeaderFormatTag
+{
+ UCHAR ucVersionPrio;
+ UCHAR aucFlowLabel[3];
+ USHORT usPayloadLength;
+ UCHAR ucNextHeader;
+ UCHAR ucHopLimit;
+ ULONG ulSrcIpAddress[4];
+ ULONG ulDestIpAddress[4];
+}IPV6Header;
+
+typedef struct IPV6RoutingHeaderFormatTag
+{
+ UCHAR ucNextHeader;
+ UCHAR ucRoutingType;
+ UCHAR ucNumAddresses;
+ UCHAR ucNextAddress;
+ ULONG ulReserved;
+ //UCHAR aucAddressList[0];
+
+}IPV6RoutingHeader;
+
+typedef struct IPV6FragmentHeaderFormatTag
+{
+ UCHAR ucNextHeader;
+ UCHAR ucReserved;
+ USHORT usFragmentOffset;
+ ULONG ulIdentification;
+}IPV6FragmentHeader;
+
+typedef struct IPV6DestOptionsHeaderFormatTag
+{
+ UCHAR ucNextHeader;
+ UCHAR ucHdrExtLen;
+ UCHAR ucDestOptions[6];
+ //UCHAR udExtDestOptions[0];
+}IPV6DestOptionsHeader;
+
+typedef struct IPV6HopByHopOptionsHeaderFormatTag
+{
+ UCHAR ucNextHeader;
+ UCHAR ucMisc[3];
+ ULONG ulJumboPayloadLen;
+}IPV6HopByHopOptionsHeader;
+
+typedef struct IPV6AuthenticationHeaderFormatTag
+{
+ UCHAR ucNextHeader;
+ UCHAR ucLength;
+ USHORT usReserved;
+ ULONG ulSecurityParametersIndex;
+ //UCHAR ucAuthenticationData[0];
+
+}IPV6AuthenticationHeader;
+
+typedef struct IPV6IcmpHeaderFormatTag
+{
+ UCHAR ucType;
+ UCHAR ucCode;
+ USHORT usChecksum;
+ //UCHAR ucIcmpMsg[0];
+
+}IPV6IcmpHeader;
+
+typedef enum _E_IPADDR_CONTEXT
+{
+ eSrcIpAddress,
+ eDestIpAddress
+
+}E_IPADDR_CONTEXT;
+
+
+
+//Function Prototypes
+BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
+BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
+
+USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
+ PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
+ S_CLASSIFIER_RULE *pstClassifierRule );
+
+VOID DumpIpv6Address(ULONG *puIpv6Address);
+VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
+
+extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
+extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
+extern BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
+
+
+#endif
diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h
new file mode 100644
index 000000000000..6397c20f4f6a
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceAdapter.h
@@ -0,0 +1,97 @@
+#ifndef _INTERFACE_ADAPTER_H
+#define _INTERFACE_ADAPTER_H
+
+typedef struct _BULK_ENDP_IN
+{
+ PCHAR bulk_in_buffer;
+ size_t bulk_in_size;
+ UCHAR bulk_in_endpointAddr;
+ UINT bulk_in_pipe;
+}BULK_ENDP_IN, *PBULK_ENDP_IN;
+
+
+typedef struct _BULK_ENDP_OUT
+{
+ UCHAR bulk_out_buffer;
+ size_t bulk_out_size;
+ UCHAR bulk_out_endpointAddr;
+ UINT bulk_out_pipe;
+ //this is used when int out endpoint is used as bulk out end point
+ UCHAR int_out_interval;
+}BULK_ENDP_OUT, *PBULK_ENDP_OUT;
+
+typedef struct _INTR_ENDP_IN
+{
+ PCHAR int_in_buffer;
+ size_t int_in_size;
+ UCHAR int_in_endpointAddr;
+ UCHAR int_in_interval;
+ UINT int_in_pipe;
+}INTR_ENDP_IN, *PINTR_ENDP_IN;
+
+typedef struct _INTR_ENDP_OUT
+{
+ PCHAR int_out_buffer;
+ size_t int_out_size;
+ UCHAR int_out_endpointAddr;
+ UCHAR int_out_interval;
+ UINT int_out_pipe;
+}INTR_ENDP_OUT, *PINTR_ENDP_OUT;
+
+
+typedef struct _USB_TCB
+{
+ struct urb *urb;
+ PVOID psIntfAdapter;
+ BOOLEAN bUsed;
+}USB_TCB, *PUSB_TCB;
+
+
+typedef struct _USB_RCB
+{
+ struct urb *urb;
+ PVOID psIntfAdapter;
+ BOOLEAN bUsed;
+}USB_RCB, *PUSB_RCB;
+
+/*
+//This is the interface specific Sub-Adapter
+//Structure.
+*/
+typedef struct _S_INTERFACE_ADAPTER
+{
+ struct usb_device * udev;
+ struct usb_interface * interface;
+
+ /* Bulk endpoint in info */
+ BULK_ENDP_IN sBulkIn;
+ /* Bulk endpoint out info */
+ BULK_ENDP_OUT sBulkOut;
+ /* Interrupt endpoint in info */
+ INTR_ENDP_IN sIntrIn;
+ /* Interrupt endpoint out info */
+ INTR_ENDP_OUT sIntrOut;
+
+
+
+ ULONG ulInterruptData[2];
+
+ struct urb *psInterruptUrb;
+
+ USB_TCB asUsbTcb[MAXIMUM_USB_TCB];
+ USB_RCB asUsbRcb[MAXIMUM_USB_RCB];
+ atomic_t uNumTcbUsed;
+ atomic_t uCurrTcb;
+ atomic_t uNumRcbUsed;
+ atomic_t uCurrRcb;
+
+ PMINI_ADAPTER psAdapter;
+ BOOLEAN bFlashBoot;
+ BOOLEAN bHighSpeedDevice ;
+
+ BOOLEAN bSuspended;
+ BOOLEAN bPreparingForBusSuspend;
+ struct work_struct usbSuspendWork;
+}S_INTERFACE_ADAPTER,*PS_INTERFACE_ADAPTER;
+
+#endif
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
new file mode 100644
index 000000000000..f9761dbd5e48
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -0,0 +1,509 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+int InterfaceFileDownload( PVOID arg,
+ struct file *flp,
+ unsigned int on_chip_loc)
+{
+ char *buff=NULL;
+ // unsigned int reg=0;
+ mm_segment_t oldfs={0};
+ int errno=0, len=0 /*,is_config_file = 0*/;
+ loff_t pos=0;
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+ //PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
+
+ buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+ if(!buff)
+ {
+ return -ENOMEM;
+ }
+ while(1)
+ {
+ oldfs=get_fs(); set_fs(get_ds());
+ len=vfs_read(flp, buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
+ set_fs(oldfs);
+ if(len<=0)
+ {
+ if(len<0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
+ errno=len;
+ }
+ else
+ {
+ errno = 0;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
+ }
+ break;
+ }
+ //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB);
+ errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len) ;
+ if(errno)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno);
+ break;
+
+ }
+ on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
+ }/* End of for(;;)*/
+
+ bcm_kfree(buff);
+ return errno;
+}
+
+int InterfaceFileReadbackFromChip( PVOID arg,
+ struct file *flp,
+ unsigned int on_chip_loc)
+{
+ char *buff=NULL, *buff_readback=NULL;
+ unsigned int reg=0;
+ mm_segment_t oldfs={0};
+ int errno=0, len=0, is_config_file = 0;
+ loff_t pos=0;
+ static int fw_down = 0;
+ INT Status = STATUS_SUCCESS;
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+
+ buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
+ buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
+ if(!buff || !buff_readback)
+ {
+ bcm_kfree(buff);
+ bcm_kfree(buff_readback);
+
+ return -ENOMEM;
+ }
+
+ is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR)? 1:0;
+
+ memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
+ memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
+ while(1)
+ {
+ oldfs=get_fs(); set_fs(get_ds());
+ len=vfs_read(flp, buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
+ set_fs(oldfs);
+ fw_down++;
+ if(len<=0)
+ {
+ if(len<0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
+ errno=len;
+ }
+ else
+ {
+ errno = 0;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
+ }
+ break;
+ }
+
+
+ Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
+ goto exit;
+ }
+ reg++;
+ if((len-sizeof(unsigned int))<4)
+ {
+ if(memcmp(buff_readback, buff, len))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL,"Length is: %d",len);
+ Status = -EIO;
+ goto exit;
+ }
+ }
+ else
+ {
+ len-=4;
+ while(len)
+ {
+ if(*(unsigned int*)&buff_readback[len] != *(unsigned int *)&buff[len])
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
+ Status = -EIO;
+ goto exit;
+ }
+ len-=4;
+ }
+ }
+ on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
+ }/* End of while(1)*/
+exit:
+ bcm_kfree(buff);
+ bcm_kfree(buff_readback);
+ return Status;
+}
+
+static int bcm_download_config_file(PMINI_ADAPTER Adapter,
+ FIRMWARE_INFO *psFwInfo)
+{
+ int retval = STATUS_SUCCESS;
+ B_UINT32 value = 0;
+
+ if(Adapter->pstargetparams == NULL)
+ {
+ if((Adapter->pstargetparams =
+ kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
+ {
+ return -ENOMEM;
+ }
+ }
+ if(psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS))
+ {
+ return -EIO;
+ }
+ retval = copy_from_user(Adapter->pstargetparams,
+ psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
+ if(retval)
+ {
+ bcm_kfree (Adapter->pstargetparams);
+ Adapter->pstargetparams = NULL;
+ return retval;
+ }
+ /* Parse the structure and then Download the Firmware */
+ beceem_parse_target_struct(Adapter);
+
+ //Initializing the NVM.
+ BcmInitNVM(Adapter);
+
+ retval = InitLedSettings (Adapter);
+
+ if(retval)
+ {
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
+ return retval;
+ }
+
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->LEDInfo.bLedInitDone = FALSE;
+ Adapter->DriverState = DRIVER_INIT;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = FW_DOWNLOAD;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+
+ /* Initialize the DDR Controller */
+ retval = ddr_init(Adapter);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
+ return retval;
+ }
+
+ value = 0;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
+
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ retval = PropagateCalParamsFromFlashToMemory(Adapter);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"propagaion of cal param failed with status :%d", retval);
+ return retval;
+ }
+ }
+
+
+ retval =buffDnldVerify(Adapter,(PUCHAR)Adapter->pstargetparams,sizeof(STARGETPARAMS),CONFIG_BEGIN_ADDR);
+
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
+ }
+ else
+ Adapter->bCfgDownloaded = TRUE;
+
+
+ return retval;
+}
+#if 0
+static int bcm_download_buffer(PMINI_ADAPTER Adapter,
+ unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress)
+{
+ char *buff=NULL;
+ unsigned int len = 0;
+ int retval = STATUS_SUCCESS;
+ buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+
+ len = u32FirmwareLength;
+
+ while(u32FirmwareLength)
+ {
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+ if(STATUS_SUCCESS != (retval = copy_from_user(buff,
+ (unsigned char *)mappedbuffer, len)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
+ break;
+ }
+ retval = wrm (Adapter, u32StartingAddress, buff, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n");
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }
+ bcm_kfree(buff);
+ return retval;
+}
+#endif
+static int bcm_compare_buff_contents(unsigned char *readbackbuff,
+ unsigned char *buff,unsigned int len)
+{
+ int retval = STATUS_SUCCESS;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if((len-sizeof(unsigned int))<4)
+ {
+ if(memcmp(readbackbuff , buff, len))
+ {
+ retval=-EINVAL;
+ }
+ }
+ else
+ {
+ len-=4;
+ while(len)
+ {
+ if(*(unsigned int*)&readbackbuff[len] !=
+ *(unsigned int *)&buff[len])
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
+ retval=-EINVAL;
+ break;
+ }
+ len-=4;
+ }
+ }
+ return retval;
+}
+#if 0
+static int bcm_buffer_readback(PMINI_ADAPTER Adapter,
+ unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress)
+{
+ unsigned char *buff = NULL;
+ unsigned char *readbackbuff = NULL;
+ unsigned int len = u32FirmwareLength;
+ int retval = STATUS_SUCCESS;
+
+ buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+ if(NULL == buff)
+ return -ENOMEM;
+ readbackbuff = (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,
+ GFP_KERNEL);
+ if(NULL == readbackbuff)
+ {
+ bcm_kfree(buff);
+ return -ENOMEM;
+ }
+ while (u32FirmwareLength && !retval)
+ {
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+
+ /* read from the appl buff and then read from the target, compare */
+ if(STATUS_SUCCESS != (retval = copy_from_user(buff,
+ (unsigned char *)mappedbuffer, len)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
+ break;
+ }
+ retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n");
+ break;
+ }
+
+ if (STATUS_SUCCESS !=
+ (retval = bcm_compare_buff_contents (readbackbuff, buff, len)))
+ {
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }/* end of while (u32FirmwareLength && !retval) */
+ bcm_kfree(buff);
+ bcm_kfree(readbackbuff);
+ return retval;
+}
+#endif
+int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
+{
+ int retval = STATUS_SUCCESS;
+ PUCHAR buff = NULL;
+
+ /* Config File is needed for the Driver to download the Config file and
+ Firmware. Check for the Config file to be first to be sent from the
+ Application
+ */
+ atomic_set (&Adapter->uiMBupdate, FALSE);
+ if(!Adapter->bCfgDownloaded &&
+ psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR)
+ {
+ /*Can't Download Firmware.*/
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n");
+ return -EINVAL;
+ }
+
+ /* If Config File, Finish the DDR Settings and then Download CFG File */
+ if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
+ {
+ retval = bcm_download_config_file (Adapter, psFwInfo);
+ }
+ else
+ {
+
+ buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
+ if(buff==NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
+ return -ENOMEM;
+ }
+ retval = copy_from_user(buff,(PUCHAR)psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
+ goto error ;
+ }
+
+ #if 0
+ retval = bcm_download_buffer(Adapter,
+ (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
+ psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails....");
+ }
+ retval = bcm_buffer_readback (Adapter,
+ (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
+ psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
+
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ....");
+ }
+ #endif
+ retval = buffDnldVerify(Adapter,
+ buff,
+ psFwInfo->u32FirmwareLength,
+ psFwInfo->u32StartingAddress);
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval);
+ goto error;
+ }
+ }
+error:
+ bcm_kfree(buff);
+ return retval;
+}
+
+static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength,
+ ULONG u32StartingAddress)
+{
+
+ unsigned int len = 0;
+ int retval = STATUS_SUCCESS;
+ len = u32FirmwareLength;
+
+ while(u32FirmwareLength)
+ {
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+ retval = wrm (Adapter, u32StartingAddress, mappedbuffer, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }
+ return retval;
+
+}
+
+static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
+ PUCHAR mappedbuffer, UINT u32FirmwareLength,
+ ULONG u32StartingAddress)
+{
+ PUCHAR readbackbuff = NULL;
+ UINT len = u32FirmwareLength;
+ INT retval = STATUS_SUCCESS;
+
+ readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
+ if(NULL == readbackbuff)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
+ return -ENOMEM;
+ }
+ while (u32FirmwareLength && !retval)
+ {
+
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+
+ retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d" ,retval);
+ break;
+ }
+
+ if (STATUS_SUCCESS != (retval = bcm_compare_buff_contents (readbackbuff, mappedbuffer, len)))
+ {
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }/* end of while (u32FirmwareLength && !retval) */
+ bcm_kfree(readbackbuff);
+ return retval;
+}
+
+INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress)
+{
+ INT status = STATUS_SUCCESS;
+
+ status = buffDnld(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer download failed");
+ goto error;
+ }
+
+ status= buffRdbkVerify(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer readback verifier failed");
+ goto error;
+ }
+error:
+ return status;
+}
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c
new file mode 100644
index 000000000000..d99fc7c31a11
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIdleMode.c
@@ -0,0 +1,318 @@
+#include "headers.h"
+
+/*
+Function: InterfaceIdleModeWakeup
+
+Description: This is the hardware specific Function for waking up HW device from Idle mode.
+ A software abort pattern is written to the device to wake it and necessary power state
+ transitions from host are performed here.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful.
+ Other - If an error occured.
+*/
+
+
+/*
+Function: InterfaceIdleModeRespond
+
+Description: This is the hardware specific Function for responding to Idle mode request from target.
+ Necessary power state transitions from host for idle mode or other device specific
+ initializations are performed here.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful.
+ Other - If an error occured.
+*/
+
+/*
+"dmem bfc02f00 100" tells how many time device went in Idle mode.
+this value will be at address bfc02fa4.just before value d0ea1dle.
+
+Set time value by writing at bfc02f98 7d0
+
+checking the Ack timer expire on kannon by running command
+d qcslog .. if it shows e means host has not send response to f/w with in 200 ms. Response should be
+send to f/w with in 200 ms after the Idle/Shutdown req issued
+
+*/
+
+
+int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter,int* puiBuffer)
+{
+ int status = STATUS_SUCCESS;
+ unsigned int uiRegRead = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"SubType of Message :0x%X", ntohl(*puiBuffer));
+
+ if(ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL," Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype");
+ if(ntohl(*(puiBuffer+1)) == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Got IDLE MODE WAKE UP Response From F/W");
+
+ status = wrmalt (Adapter,SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg");
+ return status;
+ }
+
+ if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
+ {
+ uiRegRead = 0x00000000 ;
+ status = wrmalt (Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg");
+ return status;
+ }
+ }
+ //Below Register should not br read in case of Manual and Protocol Idle mode.
+ else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
+ {
+ //clear on read Register
+ status = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0");
+ return status;
+ }
+ //clear on read Register
+ status = rdmalt (Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg1");
+ return status;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode");
+
+ // Set Idle Mode Flag to False and Clear IdleMode reg.
+ Adapter->IdleMode = FALSE;
+ Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
+
+ wake_up(&Adapter->lowpower_mode_wait_queue);
+ #if 0
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"LED Thread is Running. Hence Setting the LED Event as IDLEMODE_EXIT");
+ Adapter->DriverState = IDLEMODE_EXIT;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+ #endif
+
+ }
+ else
+ {
+ if(TRUE == Adapter->IdleMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Device is already in Idle mode....");
+ return status ;
+ }
+
+ uiRegRead = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n");
+
+ if (Adapter->chip_id== BCS220_2 ||
+ Adapter->chip_id == BCS220_2BC ||
+ Adapter->chip_id== BCS250_BC ||
+ Adapter->chip_id== BCS220_3)
+ {
+
+ status = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n");
+ return status;
+ }
+
+
+ uiRegRead |= (1<<17);
+
+ status = wrmalt (Adapter,HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n");
+ return status;
+ }
+
+ }
+ SendIdleModeResponse(Adapter);
+ }
+ }
+ else if(ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params");
+ OverrideServiceFlowParams(Adapter,puiBuffer);
+ }
+ return status;
+}
+
+
+VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter)
+{
+/* BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
+ BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
+ BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);
+ BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);*/
+ return;
+}
+
+int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
+{
+ int status = STATUS_SUCCESS;
+ unsigned int value;
+ unsigned int chip_id ;
+ unsigned long timeout = 0 ,itr = 0;
+
+ int lenwritten = 0;
+ unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+ PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter;
+
+ //Abort Bus suspend if its already suspended
+ if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))
+ {
+ status = usb_autopm_get_interface(psInterfaceAdapter->interface);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Bus got wakeup..Aborting Idle mode... status:%d \n",status);
+
+ }
+
+ if((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
+ ||
+ (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE))
+ {
+ //write the SW abort pattern.
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern);
+ status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
+ return status;
+ }
+ }
+
+ if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
+ {
+ value = 0x80000000;
+ status = wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed");
+ return status;
+ }
+ }
+ else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
+ {
+ /*
+ * Get a Interrupt Out URB and send 8 Bytes Down
+ * To be Done in Thread Context.
+ * Not using Asynchronous Mechanism.
+ */
+ status = usb_interrupt_msg (psInterfaceAdapter->udev,
+ usb_sndintpipe(psInterfaceAdapter->udev,
+ psInterfaceAdapter->sIntrOut.int_out_endpointAddr),
+ aucAbortPattern,
+ 8,
+ &lenwritten,
+ 5000);
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n",status);
+ return status;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten);
+ }
+
+ //mdelay(25);
+
+ timeout= jiffies + msecs_to_jiffies(50) ;
+ while( timeout > jiffies )
+ {
+ itr++ ;
+ rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT));
+ if(0xbece3200==(chip_id&~(0xF0)))
+ {
+ chip_id = chip_id&~(0xF0);
+ }
+ if(chip_id == Adapter->chip_id)
+ break;
+ }
+ if(timeout < jiffies )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Not able to read chip-id even after 25 msec");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Number of completed iteration to read chip-id :%lu", itr);
+ }
+
+ status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status));
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
+ return status;
+ }
+ }
+ return status;
+}
+int InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter)
+{
+ ULONG Status = 0;
+ if(Adapter->bTriedToWakeUpFromlowPowerMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Writing Low Power Mode Abort pattern to the Device\n");
+ Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
+ InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern);
+
+ }
+ return Status;
+}
+
+void InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter)
+{
+ unsigned int uiRegVal = 0;
+ INT Status = 0;
+ if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
+ {
+ // clear idlemode interrupt.
+ uiRegVal = 0;
+ Status =wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status);
+ return;
+ }
+ }
+
+ else
+ {
+
+ //clear Interrupt EP registers.
+ Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status);
+ return;
+ }
+
+ Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status);
+ return;
+ }
+ }
+}
+
diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h
new file mode 100644
index 000000000000..f87c132989f9
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIdleMode.h
@@ -0,0 +1,16 @@
+#ifndef _INTERFACE_IDLEMODE_H
+#define _INTERFACE_IDLEMODE_H
+
+INT InterfaceIdleModeWakeup(PMINI_ADAPTER Adapter);
+
+INT InterfaceIdleModeRespond(PMINI_ADAPTER Adapter,PINT puiBuffer);
+
+VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter);
+
+INT InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern);
+
+INT InterfaceWakeUp(PMINI_ADAPTER Adapter);
+
+VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter);
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
new file mode 100644
index 000000000000..e06f168a52bd
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -0,0 +1,868 @@
+#include "headers.h"
+
+static struct usb_device_id InterfaceUsbtable[] = {
+ { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
+ { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
+ {}
+};
+
+VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ INT i = 0;
+ // Wake up the wait_queue...
+ if(psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ psIntfAdapter->psAdapter->DriverState = DRIVER_HALT;
+ wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event);
+ }
+ reset_card_proc(psIntfAdapter->psAdapter);
+
+ //worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms
+ //to accertain the device is not being accessed. After this No RDM/WRM should be made.
+ while(psIntfAdapter->psAdapter->DeviceAccess)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Device is being Accessed \n");
+ msleep(100);
+ }
+ /* Free interrupt URB */
+ //psIntfAdapter->psAdapter->device_removed = TRUE;
+ if(psIntfAdapter->psInterruptUrb)
+ {
+ usb_free_urb(psIntfAdapter->psInterruptUrb);
+ }
+
+ /* Free transmit URBs */
+ for(i = 0; i < MAXIMUM_USB_TCB; i++)
+ {
+ if(psIntfAdapter->asUsbTcb[i].urb != NULL)
+ {
+ usb_free_urb(psIntfAdapter->asUsbTcb[i].urb);
+ psIntfAdapter->asUsbTcb[i].urb = NULL;
+ }
+ }
+ /* Free receive URB and buffers */
+ for(i = 0; i < MAXIMUM_USB_RCB; i++)
+ {
+ if (psIntfAdapter->asUsbRcb[i].urb != NULL)
+ {
+ bcm_kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer);
+ usb_free_urb(psIntfAdapter->asUsbRcb[i].urb);
+ psIntfAdapter->asUsbRcb[i].urb = NULL;
+ }
+ }
+ AdapterFree(psIntfAdapter->psAdapter);
+}
+
+
+
+static int usbbcm_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int usbbcm_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t usbbcm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+ return 0;
+}
+
+static ssize_t usbbcm_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
+{
+ return 0;
+}
+
+
+VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
+{
+ ULONG ulReg = 0;
+
+// Program EP2 MAX_PKT_SIZE
+ ulReg = ntohl(EP2_MPS_REG);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x128,4,TRUE);
+ ulReg = ntohl(EP2_MPS);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x12C,4,TRUE);
+
+ ulReg = ntohl(EP2_CFG_REG);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x132,4,TRUE);
+ if(((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE)
+ {
+ ulReg = ntohl(EP2_CFG_INT);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE);
+ }
+ else
+ {
+// USE BULK EP as TX in FS mode.
+ ulReg = ntohl(EP2_CFG_BULK);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE);
+ }
+
+
+// Program EP4 MAX_PKT_SIZE.
+ ulReg = ntohl(EP4_MPS_REG);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x13C,4,TRUE);
+ ulReg = ntohl(EP4_MPS);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x140,4,TRUE);
+
+// Program TX EP as interrupt (Alternate Setting)
+ if( rdmalt(Adapter,0x0F0110F8, (PUINT)&ulReg,4))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing");
+ return ;
+ }
+ ulReg |= 0x6;
+
+ ulReg = ntohl(ulReg);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1CC,4,TRUE);
+
+ ulReg = ntohl(EP4_CFG_REG);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C8,4,TRUE);
+// Program ISOCHRONOUS EP size to zero.
+ ulReg = ntohl(ISO_MPS_REG);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D2,4,TRUE);
+ ulReg = ntohl(ISO_MPS);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D6,4,TRUE);
+
+// Update EEPROM Version.
+// Read 4 bytes from 508 and modify 511 and 510.
+//
+ ReadBeceemEEPROM(Adapter,0x1FC,(PUINT)&ulReg);
+ ulReg &= 0x0101FFFF;
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1FC,4,TRUE);
+//
+//Update length field if required. Also make the string NULL terminated.
+//
+ ReadBeceemEEPROM(Adapter,0xA8,(PUINT)&ulReg);
+ if((ulReg&0x00FF0000)>>16 > 0x30)
+ {
+ ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0xA8,4,TRUE);
+ }
+ ReadBeceemEEPROM(Adapter,0x148,(PUINT)&ulReg);
+ if((ulReg&0x00FF0000)>>16 > 0x30)
+ {
+ ulReg = (ulReg&0xFF00FFFF)|(0x30<<16);
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x148,4,TRUE);
+ }
+ ulReg = 0;
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x122,4,TRUE);
+ ulReg = 0;
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C2,4,TRUE);
+
+}
+
+static struct file_operations usbbcm_fops = {
+ .open = usbbcm_open,
+ .release = usbbcm_release,
+ .read = usbbcm_read,
+ .write = usbbcm_write,
+ .owner = THIS_MODULE,
+};
+
+static struct usb_class_driver usbbcm_class = {
+ .name = "usbbcm",
+ .fops = &usbbcm_fops,
+ .minor_base = BCM_USB_MINOR_BASE,
+};
+
+static int
+usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ int retval =0 ;
+ PMINI_ADAPTER psAdapter = NULL;
+ PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
+ struct usb_device *udev = NULL;
+
+// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!");
+ if((intf == NULL) || (id == NULL))
+ {
+ // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL");
+ return -EINVAL;
+ }
+
+ /* Allocate Adapter structure */
+ if((psAdapter = kmalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL)
+ {
+ //BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory");
+ return -ENOMEM;
+ }
+
+ memset(psAdapter, 0, sizeof(MINI_ADAPTER));
+
+ /* Init default driver debug state */
+
+ psAdapter->stDebugState.debug_level = DBG_LVL_CURR;
+ psAdapter->stDebugState.type = DBG_TYPE_INITEXIT;
+ memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype));
+
+ /* Technically, one can start using BCM_DEBUG_PRINT after this point.
+ * However, realize that by default the Type/Subtype bitmaps are all zero now;
+ * so no prints will actually appear until the TestApp turns on debug paths via
+ * the ioctl(); so practically speaking, in early init, no logging happens.
+ *
+ * A solution (used below): we explicitly set the bitmaps to 1 for Type=DBG_TYPE_INITEXIT
+ * and ALL subtype's of the same. Now all bcm debug statements get logged, enabling debug
+ * during early init.
+ * Further, we turn this OFF once init_module() completes.
+ */
+
+ psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff;
+ BCM_SHOW_DEBUG_BITMAP(psAdapter);
+
+ retval = InitAdapter(psAdapter);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n");
+ AdapterFree(psAdapter);
+ return retval;
+ }
+
+ /* Allocate interface adapter structure */
+ if((psAdapter->pvInterfaceAdapter =
+ kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory");
+ AdapterFree (psAdapter);
+ return -ENOMEM;
+ }
+ memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER));
+
+ psIntfAdapter = InterfaceAdapterGet(psAdapter);
+ psIntfAdapter->psAdapter = psAdapter;
+
+ /* Store usb interface in Interface Adapter */
+ psIntfAdapter->interface = intf;
+ usb_set_intfdata(intf, psIntfAdapter);
+
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter);
+ retval = InterfaceAdapterInit(psIntfAdapter);
+ if(retval)
+ {
+ /* If the Firmware/Cfg File is not present
+ * then return success, let the application
+ * download the files.
+ */
+ if(-ENOENT == retval){
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n");
+ return STATUS_SUCCESS;
+ }
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n");
+ usb_set_intfdata(intf, NULL);
+ udev = interface_to_usbdev (intf);
+ usb_put_dev(udev);
+ if(psAdapter->bUsbClassDriverRegistered == TRUE)
+ usb_deregister_dev (intf, &usbbcm_class);
+ InterfaceAdapterFree(psIntfAdapter);
+ return retval ;
+ }
+ if(psAdapter->chip_id > T3)
+ {
+ uint32_t uiNackZeroLengthInt=4;
+ if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt)))
+ {
+ return -EIO;;
+ }
+ }
+
+ udev = interface_to_usbdev (intf);
+ /* Check whether the USB-Device Supports remote Wake-Up */
+ if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes)
+ {
+ /* If Suspend then only support dynamic suspend */
+ if(psAdapter->bDoSuspend)
+ {
+ udev->autosuspend_delay = 0;
+ intf->needs_remote_wakeup = 1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+ udev->autosuspend_disabled = 0;
+#else
+ usb_enable_autosuspend(udev);
+#endif
+ device_init_wakeup(&intf->dev,1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
+ usb_autopm_disable(intf);
+#endif
+ INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend);
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n");
+ }
+ else
+ {
+ intf->needs_remote_wakeup = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+ udev->autosuspend_disabled = 1;
+#else
+ usb_disable_autosuspend(udev);
+#endif
+ }
+ }
+
+ psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0;
+ return retval;
+}
+
+static void usbbcm_disconnect (struct usb_interface *intf)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
+ PMINI_ADAPTER psAdapter = NULL;
+ struct usb_device *udev = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected");
+ if(intf == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL");
+ return;
+ }
+ psIntfAdapter = usb_get_intfdata(intf);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%x",(unsigned int)psIntfAdapter);
+ if(psIntfAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL");
+ return;
+ }
+ psAdapter = psIntfAdapter->psAdapter;
+ if(psAdapter->bDoSuspend)
+ intf->needs_remote_wakeup = 0;
+
+ psAdapter->device_removed = TRUE ;
+ usb_set_intfdata(intf, NULL);
+ InterfaceAdapterFree(psIntfAdapter);
+ udev = interface_to_usbdev (intf);
+ usb_put_dev(udev);
+ usb_deregister_dev (intf, &usbbcm_class);
+}
+
+
+static __inline int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ int i = 0;
+ for(i = 0; i < MAXIMUM_USB_TCB; i++)
+ {
+ if((psIntfAdapter->asUsbTcb[i].urb =
+ usb_alloc_urb(0, GFP_KERNEL)) == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i);
+ return -ENOMEM;
+ }
+ }
+
+ for(i = 0; i < MAXIMUM_USB_RCB; i++)
+ {
+ if ((psIntfAdapter->asUsbRcb[i].urb =
+ usb_alloc_urb(0, GFP_KERNEL)) == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i);
+ return -ENOMEM;
+ }
+ if((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer =
+ kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i);
+ return -ENOMEM;
+ }
+ psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE;
+ }
+ return 0;
+}
+
+
+
+static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ INT value = 0;
+ UINT status = STATUS_SUCCESS;
+
+ status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter);
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n");
+ return status;
+ }
+ if(TRUE == psIntfAdapter->psAdapter->fw_download_done)
+ {
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......");
+ if(StartInterruptUrb(psIntfAdapter))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB");
+ }
+ //now register the cntrl interface.
+ //after downloading the f/w waiting for 5 sec to get the mailbox interrupt.
+
+ psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE;
+ value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
+ psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ);
+
+ if(value == 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver..");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n ");
+ }
+ if(register_control_device_interface(psIntfAdapter->psAdapter) < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed...");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+#if 0
+static void print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface);
+}
+static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor *usb_ep_desc)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** ENDPOINT DESCRIPTOR *********************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength :%x ", usb_ep_desc->bLength);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType :%x ", usb_ep_desc->bDescriptorType);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bEndpointAddress :%x ", usb_ep_desc->bEndpointAddress);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bmAttributes :%x ", usb_ep_desc->bmAttributes);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "wMaxPacketSize :%x ",usb_ep_desc->wMaxPacketSize);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterval :%x ",usb_ep_desc->bInterval);
+}
+
+#endif
+
+static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
+{
+ return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+}
+
+static inline int bcm_usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
+{
+ return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+static inline int bcm_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
+}
+
+static inline int bcm_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
+}
+
+static inline int bcm_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_BULK);
+}
+
+static inline int bcm_usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_CONTROL);
+}
+
+static inline int bcm_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_INT);
+}
+
+static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
+{
+ return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_ISOC);
+}
+
+static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd));
+}
+
+static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd));
+}
+
+static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd));
+}
+
+static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd));
+}
+
+static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd));
+}
+
+static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
+{
+ return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd));
+}
+
+INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ size_t buffer_size;
+ ULONG value;
+ INT retval = 0;
+ INT usedIntOutForBulkTransfer = 0 ;
+ BOOLEAN bBcm16 = FALSE;
+ UINT uiData = 0;
+
+ if(psIntfAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface Adapter is NULL");
+ return -EINVAL;
+ }
+ /* Store the usb dev into interface adapter */
+ psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(
+ psIntfAdapter->interface));
+
+ if((psIntfAdapter->udev->speed == USB_SPEED_HIGH))
+ {
+ psIntfAdapter->bHighSpeedDevice = TRUE ;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO HIGH_SPEED ");
+ }
+ else
+ {
+ psIntfAdapter->bHighSpeedDevice = FALSE ;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO FULL_SPEED ");
+ }
+
+ psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
+ psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
+
+ if(rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n");
+ return STATUS_FAILURE;
+ }
+ if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0)))
+ {
+ psIntfAdapter->psAdapter->chip_id=(psIntfAdapter->psAdapter->chip_id&~(0xF0));
+ }
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "First RDM Chip ID 0x%lx\n", psIntfAdapter->psAdapter->chip_id);
+
+ iface_desc = psIntfAdapter->interface->cur_altsetting;
+ //print_usb_interface_desc(&(iface_desc->desc));
+
+ if(psIntfAdapter->psAdapter->chip_id == T3B)
+ {
+
+ //
+ //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not.
+ //
+ BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4);
+ if(uiData == BECM)
+ {
+ bBcm16 = TRUE;
+ }
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Number of Altsetting aviailable for This Modem 0x%x\n", psIntfAdapter->interface->num_altsetting);
+ if(bBcm16 == TRUE)
+ {
+ //selecting alternate setting one as a default setting for High Speed modem.
+ if(psIntfAdapter->bHighSpeedDevice)
+ retval= usb_set_interface(psIntfAdapter->udev,DEFAULT_SETTING_0,ALTERNATE_SETTING_1);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle");
+ if(retval || (psIntfAdapter->bHighSpeedDevice == FALSE))
+ {
+ usedIntOutForBulkTransfer = EP2 ;
+ endpoint = &iface_desc->endpoint[EP2].desc;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n");
+ /*
+ If Modem is high speed device EP2 should be INT OUT End point
+ If Mode is FS then EP2 should be bulk end point
+ */
+ if(((psIntfAdapter->bHighSpeedDevice ==TRUE ) && (bcm_usb_endpoint_is_int_out(endpoint)== FALSE))
+ ||((psIntfAdapter->bHighSpeedDevice == FALSE)&& (bcm_usb_endpoint_is_bulk_out(endpoint)== FALSE)))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Configuring the EEPROM ");
+ //change the EP2, EP4 to INT OUT end point
+ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
+
+ /*
+ It resets the device and if any thing gets changed in USB descriptor it will show fail and
+ re-enumerate the device
+ */
+ retval = usb_reset_device(psIntfAdapter->udev);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n");
+ return retval ;
+ }
+
+ }
+ if((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint))
+ {
+ // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail.
+ UINT uiData = ntohl(EP2_CFG_INT);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Reverting Bulk to INT as it is FS MODE");
+ BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter,(PUCHAR)&uiData,0x136,4,TRUE);
+ }
+ }
+ else
+ {
+ usedIntOutForBulkTransfer = EP4 ;
+ endpoint = &iface_desc->endpoint[EP4].desc;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting");
+ if( bcm_usb_endpoint_is_int_out(endpoint) == FALSE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix");
+ //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting
+ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter);
+
+ /*
+ It resets the device and if any thing gets changed in USB descriptor it will show fail and
+ re-enumerate the device
+ */
+ retval = usb_reset_device(psIntfAdapter->udev);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n");
+ return retval ;
+ }
+
+ }
+ }
+ }
+ }
+
+ iface_desc = psIntfAdapter->interface->cur_altsetting;
+ //print_usb_interface_desc(&(iface_desc->desc));
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Current number of endpoints :%x \n", iface_desc->desc.bNumEndpoints);
+ for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value)
+ {
+ endpoint = &iface_desc->endpoint[value].desc;
+ //print_usb_endpoint_descriptor(endpoint);
+
+ if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint))
+ {
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ psIntfAdapter->sBulkIn.bulk_in_size = buffer_size;
+ psIntfAdapter->sBulkIn.bulk_in_endpointAddr =
+ endpoint->bEndpointAddress;
+ psIntfAdapter->sBulkIn.bulk_in_pipe =
+ usb_rcvbulkpipe(psIntfAdapter->udev,
+ psIntfAdapter->sBulkIn.bulk_in_endpointAddr);
+ }
+
+ if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint))
+ {
+
+ psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
+ endpoint->bEndpointAddress;
+ psIntfAdapter->sBulkOut.bulk_out_pipe =
+ usb_sndbulkpipe(psIntfAdapter->udev,
+ psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
+ }
+
+ if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint))
+ {
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ psIntfAdapter->sIntrIn.int_in_size = buffer_size;
+ psIntfAdapter->sIntrIn.int_in_endpointAddr =
+ endpoint->bEndpointAddress;
+ psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval;
+ psIntfAdapter->sIntrIn.int_in_buffer =
+ kmalloc(buffer_size, GFP_KERNEL);
+ if (!psIntfAdapter->sIntrIn.int_in_buffer) {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_in_buffer");
+ return -EINVAL;
+ }
+ //psIntfAdapter->sIntrIn.int_in_pipe =
+ }
+
+ if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint))
+ {
+
+ if( !psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
+ (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer))
+ {
+ //use first intout end point as a bulk out end point
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ psIntfAdapter->sBulkOut.bulk_out_size = buffer_size;
+ //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1);
+ psIntfAdapter->sBulkOut.bulk_out_endpointAddr =
+ endpoint->bEndpointAddress;
+ psIntfAdapter->sBulkOut.bulk_out_pipe =
+ usb_sndintpipe(psIntfAdapter->udev,
+ psIntfAdapter->sBulkOut.bulk_out_endpointAddr);
+ psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval;
+
+ }
+ else if(value == EP6)
+ {
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ psIntfAdapter->sIntrOut.int_out_size = buffer_size;
+ psIntfAdapter->sIntrOut.int_out_endpointAddr =
+ endpoint->bEndpointAddress;
+ psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval;
+ psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size,
+ GFP_KERNEL);
+ if (!psIntfAdapter->sIntrOut.int_out_buffer)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_out_buffer");
+ return -EINVAL;
+ }
+ }
+ }
+ }
+ usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter);
+ retval = usb_register_dev(psIntfAdapter->interface, &usbbcm_class);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb register dev failed = %d", retval);
+ psIntfAdapter->psAdapter->bUsbClassDriverRegistered = FALSE;
+ return retval;
+ }
+ else
+ {
+ psIntfAdapter->psAdapter->bUsbClassDriverRegistered = TRUE;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb dev registered");
+ }
+
+ psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
+ psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
+ InterfaceFileReadbackFromChip;
+ psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket;
+
+ retval = CreateInterruptUrb(psIntfAdapter);
+
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb");
+ return retval;
+ }
+
+ retval = AllocUsbCb(psIntfAdapter);
+ if(retval)
+ {
+ return retval;
+ }
+
+
+ retval = device_run(psIntfAdapter);
+ if(retval)
+ {
+ return retval;
+ }
+
+
+ return 0;
+}
+int InterfaceSuspend (struct usb_interface *intf, pm_message_t message)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n");
+ //Bcm_kill_all_URBs(psIntfAdapter);
+ psIntfAdapter->bSuspended = TRUE;
+
+ if(TRUE == psIntfAdapter->bPreparingForBusSuspend)
+ {
+ psIntfAdapter->bPreparingForBusSuspend = FALSE;
+
+ if(psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE)
+ {
+ psIntfAdapter->psAdapter->IdleMode = TRUE ;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode..");
+ }
+ else
+ {
+ psIntfAdapter->psAdapter->bShutStatus = TRUE;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode..");
+ }
+ }
+ psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE;
+
+ //Signaling the control pkt path
+ wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue);
+
+ return 0;
+}
+int InterfaceResume (struct usb_interface *intf)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+ printk("=================================\n");
+ mdelay(100);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
+ intf->pm_usage_cnt =1 ;
+#endif
+ psIntfAdapter->bSuspended = FALSE;
+
+ StartInterruptUrb(psIntfAdapter);
+ InterfaceRx(psIntfAdapter);
+ return 0;
+}
+int InterfacePreReset(struct usb_interface *intf)
+{
+ printk("====================>");
+ return STATUS_SUCCESS;
+}
+int InterfacePostReset(struct usb_interface *intf)
+{
+ printk("Do Post chip reset setting here if it is required");
+ return STATUS_SUCCESS;
+}
+static struct usb_driver usbbcm_driver = {
+ .name = "usbbcm",
+ .probe = usbbcm_device_probe,
+ .disconnect = usbbcm_disconnect,
+ .suspend = InterfaceSuspend,
+ .resume = InterfaceResume,
+ .pre_reset=InterfacePreReset,
+ .post_reset=InterfacePostReset,
+ .id_table = InterfaceUsbtable,
+ .supports_autosuspend = 1,
+};
+
+
+/*
+Function: InterfaceInitialize
+
+Description: This is the hardware specific initialization Function.
+ Registering the driver with NDIS , other device specific NDIS
+ and hardware initializations are done here.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If Initialization of the
+ HW Interface was successful.
+ Other - If an error occured.
+*/
+INT InterfaceInitialize(void)
+{
+// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!");
+ return usb_register(&usbbcm_driver);
+}
+
+INT InterfaceExit(void)
+{
+ //PMINI_ADAPTER psAdapter = NULL;
+ int status = 0;
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!");
+ usb_deregister(&usbbcm_driver);
+ return status;
+}
+MODULE_LICENSE ("GPL");
diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h
new file mode 100644
index 000000000000..e7a96e5c5c50
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceInit.h
@@ -0,0 +1,51 @@
+#ifndef _INTERFACE_INIT_H
+#define _INTERFACE_INIT_H
+
+#define BCM_USB_VENDOR_ID_T3 0x198f
+#define BCM_USB_VENDOR_ID_FOXCONN 0x0489
+#define BCM_USB_VENDOR_ID_ZTE 0x19d2
+
+#define BCM_USB_PRODUCT_ID_T3 0x0300
+#define BCM_USB_PRODUCT_ID_T3B 0x0210
+#define BCM_USB_PRODUCT_ID_T3L 0x0220
+#define BCM_USB_PRODUCT_ID_SYM 0x15E
+#define BCM_USB_PRODUCT_ID_1901 0xe017
+#define BCM_USB_PRODUCT_ID_226 0x0132
+
+#define BCM_USB_MINOR_BASE 192
+
+
+INT InterfaceInitialize(void);
+
+INT InterfaceExit(void);
+
+#ifndef BCM_SHM_INTERFACE
+INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
+
+INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
+
+VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter);
+
+#else
+INT InterfaceAdapterInit(PMINI_ADAPTER Adapter);
+#endif
+
+
+#if 0
+
+ULONG InterfaceClaimAdapter(PMINI_ADAPTER Adapter);
+
+VOID InterfaceDDRControllerInit(PMINI_ADAPTER Adapter);
+
+ULONG InterfaceReset(PMINI_ADAPTER Adapter);
+
+ULONG InterfaceRegisterResources(PMINI_ADAPTER Adapter);
+
+VOID InterfaceUnRegisterResources(PMINI_ADAPTER Adapter);
+
+ULONG InterfaceFirmwareDownload(PMINI_ADAPTER Adapter);
+
+#endif
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
new file mode 100644
index 000000000000..f928fe4d564d
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -0,0 +1,203 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
+{
+ int status = urb->status;
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
+ PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ;
+
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed.");
+ return ;
+ }
+
+ if(((Adapter->bPreparingForLowPowerMode == TRUE) && (Adapter->bDoSuspend == TRUE)) ||
+ psIntfAdapter->bSuspended ||
+ psIntfAdapter->bPreparingForBusSuspend)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt call back is called while suspending the device");
+ return ;
+ }
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "interrupt urb status %d", status);
+ switch (status) {
+ /* success */
+ case STATUS_SUCCESS:
+ if ( urb->actual_length )
+ {
+
+ if(psIntfAdapter->ulInterruptData[1] & 0xFF)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Got USIM interrupt");
+ }
+
+ if(psIntfAdapter->ulInterruptData[1] & 0xFF00)
+ {
+ atomic_set(&Adapter->CurrNumFreeTxDesc,
+ (psIntfAdapter->ulInterruptData[1] & 0xFF00) >> 8);
+ atomic_set (&Adapter->uiMBupdate, TRUE);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "TX mailbox contains %d",
+ atomic_read(&Adapter->CurrNumFreeTxDesc));
+ }
+ if(psIntfAdapter->ulInterruptData[1] >> 16)
+ {
+ Adapter->CurrNumRecvDescs=
+ (psIntfAdapter->ulInterruptData[1] >> 16);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"RX mailbox contains %d",
+ Adapter->CurrNumRecvDescs);
+ InterfaceRx(psIntfAdapter);
+ }
+ if(Adapter->fw_download_done &&
+ !Adapter->downloadDDR &&
+ atomic_read(&Adapter->CurrNumFreeTxDesc))
+ {
+ psIntfAdapter->psAdapter->downloadDDR +=1;
+ wake_up(&Adapter->tx_packet_wait_queue);
+ }
+ if(FALSE == Adapter->waiting_to_fw_download_done)
+ {
+ Adapter->waiting_to_fw_download_done = TRUE;
+ wake_up(&Adapter->ioctl_fw_dnld_wait_queue);
+ }
+ if(!atomic_read(&Adapter->TxPktAvail))
+ {
+ atomic_set(&Adapter->TxPktAvail, 1);
+ wake_up(&Adapter->tx_packet_wait_queue);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Firing interrupt in URB");
+ }
+ break;
+ case -ENOENT :
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"URB has got disconnected ....");
+ return ;
+ }
+ case -EINPROGRESS:
+ {
+ //This situation may happend when URBunlink is used. for detail check usb_unlink_urb documentation.
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occured... something very bad is going on");
+ break ;
+ //return;
+ }
+ case -EPIPE:
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint has got halted/stalled...need to clear this");
+ Adapter->bEndPointHalted = TRUE ;
+ wake_up(&Adapter->tx_packet_wait_queue);
+ urb->status = STATUS_SUCCESS ;;
+ return;
+ }
+ /* software-driven interface shutdown */
+ case -ECONNRESET: //URB got unlinked.
+ case -ESHUTDOWN: // hardware gone. this is the serious problem.
+ //Occurs only when something happens with the host controller device
+ case -ENODEV : //Device got removed
+ case -EINVAL : //Some thing very bad happened with the URB. No description is available.
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"interrupt urb error %d", status);
+ urb->status = STATUS_SUCCESS ;
+ break ;
+ //return;
+ default:
+ //This is required to check what is the defaults conditions when it occurs..
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", status);
+ break;
+ }
+
+ StartInterruptUrb(psIntfAdapter);
+
+
+}
+
+int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!psIntfAdapter->psInterruptUrb)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot allocate interrupt urb");
+ return -ENOMEM;
+ }
+ psIntfAdapter->psInterruptUrb->transfer_buffer =
+ psIntfAdapter->ulInterruptData;
+ psIntfAdapter->psInterruptUrb->transfer_buffer_length =
+ sizeof(psIntfAdapter->ulInterruptData);
+
+ psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev,
+ psIntfAdapter->sIntrIn.int_in_endpointAddr);
+
+ usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev,
+ psIntfAdapter->sIntrIn.int_in_pipe,
+ psIntfAdapter->psInterruptUrb->transfer_buffer,
+ psIntfAdapter->psInterruptUrb->transfer_buffer_length,
+ read_int_callback, psIntfAdapter,
+ psIntfAdapter->sIntrIn.int_in_interval);
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt Interval: %d\n",
+ psIntfAdapter->sIntrIn.int_in_interval);
+ return 0;
+}
+
+
+INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ INT status = 0;
+
+ if( FALSE == psIntfAdapter->psAdapter->device_removed &&
+ FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
+ FALSE == psIntfAdapter->bSuspended &&
+ FALSE == psIntfAdapter->bPreparingForBusSuspend &&
+ FALSE == psIntfAdapter->psAdapter->StopAllXaction)
+ {
+ status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
+ if (status)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot send int urb %d\n", status);
+ if(status == -EPIPE)
+ {
+ psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
+ wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
+ }
+ }
+ }
+ return status;
+}
+
+/*
+Function: InterfaceEnableInterrupt
+
+Description: This is the hardware specific Function for configuring
+ and enabling the interrupts on the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful.
+ Other - If an error occured.
+*/
+
+void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter)
+{
+
+}
+
+/*
+Function: InterfaceDisableInterrupt
+
+Description: This is the hardware specific Function for disabling the interrupts on the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful.
+ Other - If an error occured.
+*/
+
+void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter)
+{
+
+}
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h
new file mode 100644
index 000000000000..6065a7141bca
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIsr.h
@@ -0,0 +1,15 @@
+#ifndef _INTERFACE_ISR_H
+#define _INTERFACE_ISR_H
+
+int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
+
+
+INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter);
+
+
+VOID InterfaceEnableInterrupt(PMINI_ADAPTER Adapter);
+
+VOID InterfaceDisableInterrupt(PMINI_ADAPTER Adapter);
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceMacros.h b/drivers/staging/bcm/InterfaceMacros.h
new file mode 100644
index 000000000000..7001caff9e26
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceMacros.h
@@ -0,0 +1,18 @@
+#ifndef _INTERFACE_MACROS_H
+#define _INTERFACE_MACROS_H
+
+#define BCM_USB_MAX_READ_LENGTH 2048
+
+#define MAXIMUM_USB_TCB 128
+#define MAXIMUM_USB_RCB 128
+
+#define MAX_BUFFERS_PER_QUEUE 256
+
+#define MAX_DATA_BUFFER_SIZE 2048
+
+//Num of Asynchronous reads pending
+#define NUM_RX_DESC 64
+
+#define SYS_CFG 0x0F000C00
+
+#endif
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
new file mode 100644
index 000000000000..8fc893b37fe4
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -0,0 +1,290 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+PS_INTERFACE_ADAPTER
+InterfaceAdapterGet(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ return NULL;
+ }
+ return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter);
+}
+
+INT
+InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ int retval = 0;
+ USHORT usRetries = 0 ;
+ if(psIntfAdapter == NULL )
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL");
+ return -EINVAL ;
+ }
+
+ if(psIntfAdapter->psAdapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
+ return -ENODEV;
+ }
+
+ if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus");
+ return -EACCES;
+ }
+
+ if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
+ return -EACCES;
+ }
+ psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
+ do {
+ retval = usb_control_msg(psIntfAdapter->udev,
+ usb_rcvctrlpipe(psIntfAdapter->udev,0),
+ 0x02,
+ 0xC2,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
+
+ usRetries++ ;
+ if(-ENODEV == retval)
+ {
+ psIntfAdapter->psAdapter->device_removed =TRUE;
+ break;
+ }
+
+ }while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) );
+
+ if(retval < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return retval;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return STATUS_SUCCESS;
+ }
+}
+
+INT
+InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ int retval = 0;
+ USHORT usRetries = 0 ;
+
+ if(psIntfAdapter == NULL )
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
+ return -EINVAL;
+ }
+ if(psIntfAdapter->psAdapter->device_removed == TRUE)
+ {
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
+ return -ENODEV;
+ }
+
+ if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
+ return EACCES;
+ }
+
+ if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
+ return -EACCES;
+ }
+ psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
+ do{
+ retval = usb_control_msg(psIntfAdapter->udev,
+ usb_sndctrlpipe(psIntfAdapter->udev,0),
+ 0x01,
+ 0x42,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
+
+ usRetries++ ;
+ if(-ENODEV == retval)
+ {
+ psIntfAdapter->psAdapter->device_removed = TRUE ;
+ break;
+ }
+
+ }while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES));
+
+ if(retval < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return retval;
+ }
+ else
+ {
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
+ return STATUS_SUCCESS;
+
+ }
+
+}
+
+INT
+BcmRDM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+}
+
+INT
+BcmWRM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+}
+
+
+
+INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
+ INT status = STATUS_SUCCESS ;
+
+ /*
+ usb_clear_halt - tells device to clear endpoint halt/stall condition
+ @dev: device whose endpoint is halted
+ @pipe: endpoint "pipe" being cleared
+ @ Context: !in_interrupt ()
+
+ usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
+ This is used to clear halt conditions for bulk and interrupt endpoints only.
+ Control and isochronous endpoints never halts.
+
+ Any URBs queued for such an endpoint should normally be unlinked by the driver
+ before clearing the halt condition.
+
+ */
+
+ //Killing all the submitted urbs to different end points.
+ Bcm_kill_all_URBs(psIntfAdapter);
+
+
+ //clear the halted/stalled state for every end point
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
+
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
+
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
+
+ return status ;
+}
+
+
+VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ struct urb *tempUrb = NULL;
+ UINT i;
+
+ /**
+ * usb_kill_urb - cancel a transfer request and wait for it to finish
+ * @urb: pointer to URB describing a previously submitted request,
+ * returns nothing as it is void returned API.
+ *
+ * This routine cancels an in-progress request. It is guaranteed that
+ * upon return all completion handlers will have finished and the URB
+ * will be totally idle and available for reuse
+
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
+ *
+ **/
+
+ /* Cancel submitted Interrupt-URB's */
+ if(psIntfAdapter->psInterruptUrb != NULL)
+ {
+ if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
+ usb_kill_urb(psIntfAdapter->psInterruptUrb);
+ }
+
+ /* Cancel All submitted TX URB's */
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n");
+
+ for(i = 0; i < MAXIMUM_USB_TCB; i++)
+ {
+ tempUrb = psIntfAdapter->asUsbTcb[i].urb;
+ if(tempUrb)
+ {
+ if(tempUrb->status == -EINPROGRESS)
+ usb_kill_urb(tempUrb);
+ }
+ }
+
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n");
+
+ for(i = 0; i < MAXIMUM_USB_RCB; i++)
+ {
+ tempUrb = psIntfAdapter->asUsbRcb[i].urb;
+ if(tempUrb)
+ {
+ if(tempUrb->status == -EINPROGRESS)
+ usb_kill_urb(tempUrb);
+ }
+ }
+
+
+ atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
+ atomic_set(&psIntfAdapter->uCurrTcb, 0);
+
+ atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
+ atomic_set(&psIntfAdapter->uCurrRcb, 0);
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb));
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb));
+
+}
+
+VOID putUsbSuspend(struct work_struct *work)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = NULL ;
+ struct usb_interface *intf = NULL ;
+ psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork);
+ intf=psIntfAdapter->interface ;
+
+ if(psIntfAdapter->bSuspended == FALSE)
+ usb_autopm_put_interface(intf);
+ else
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n");
+
+}
+
+#endif
diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h
new file mode 100644
index 000000000000..74c81d45cff4
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceMisc.h
@@ -0,0 +1,45 @@
+#ifndef __INTERFACE_MISC_H
+#define __INTERFACE_MISC_H
+
+PS_INTERFACE_ADAPTER
+InterfaceAdapterGet(PMINI_ADAPTER psAdapter);
+
+INT
+InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len);
+
+INT
+InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len);
+
+
+int InterfaceFileDownload( PVOID psIntfAdapter,
+ struct file *flp,
+ unsigned int on_chip_loc);
+
+int InterfaceFileReadbackFromChip( PVOID psIntfAdapter,
+ struct file *flp,
+ unsigned int on_chip_loc);
+
+
+int BcmRDM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len);
+
+int BcmWRM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len);
+
+INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter);
+
+VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter);
+
+#define DISABLE_USB_ZERO_LEN_INT 0x0F011878
+
+#endif // __INTERFACE_MISC_H
diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c
new file mode 100644
index 000000000000..6fee9684f2ef
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceRx.c
@@ -0,0 +1,256 @@
+#include "headers.h"
+extern int SearchVcid(PMINI_ADAPTER , unsigned short);
+
+
+static PUSB_RCB
+GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ PUSB_RCB pRcb = NULL;
+ UINT index = 0;
+
+ if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) &&
+ (psIntfAdapter->psAdapter->StopAllXaction == FALSE))
+ {
+ index = atomic_read(&psIntfAdapter->uCurrRcb);
+ pRcb = &psIntfAdapter->asUsbRcb[index];
+ pRcb->bUsed = TRUE;
+ pRcb->psIntfAdapter= psIntfAdapter;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d",
+ index, atomic_read(&psIntfAdapter->uNumRcbUsed));
+ index = (index + 1) % MAXIMUM_USB_RCB;
+ atomic_set(&psIntfAdapter->uCurrRcb, index);
+ atomic_inc(&psIntfAdapter->uNumRcbUsed);
+ }
+ return pRcb;
+}
+
+/*this is receive call back - when pkt avilable for receive (BULK IN- end point)*/
+static void read_bulk_callback(struct urb *urb)
+{
+ struct sk_buff *skb = NULL;
+ BOOLEAN bHeaderSupressionEnabled = FALSE;
+ int QueueIndex = NO_OF_QUEUES + 1;
+ UINT uiIndex=0;
+ int process_done = 1;
+ //int idleflag = 0 ;
+ PUSB_RCB pRcb = (PUSB_RCB)urb->context;
+ PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter;
+ PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
+ PLEADER pLeader = urb->transfer_buffer;
+
+
+ #if 0
+ int *puiBuffer = NULL;
+ struct timeval tv;
+ memset(&tv, 0, sizeof(tv));
+ do_gettimeofday(&tv);
+ #endif
+
+ if((Adapter->device_removed == TRUE) ||
+ (TRUE == Adapter->bEndPointHalted) ||
+ (0 == urb->actual_length)
+ )
+ {
+ pRcb->bUsed = FALSE;
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+ return;
+ }
+
+ if(urb->status != STATUS_SUCCESS)
+ {
+ if(urb->status == -EPIPE)
+ {
+ Adapter->bEndPointHalted = TRUE ;
+ wake_up(&Adapter->tx_packet_wait_queue);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status);
+ }
+ pRcb->bUsed = FALSE;
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+ urb->status = STATUS_SUCCESS ;
+ return ;
+ }
+
+ if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"device is going in low power mode while PMU option selected..hence rx packet should not be process");
+ return ;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength);
+ if(!pLeader->PLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0");
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+ return;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid);
+ if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n",
+ pLeader->PLength);
+ atomic_inc(&Adapter->RxPacketDroppedCount);
+ atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+ return;
+ }
+
+ QueueIndex = SearchVcid( Adapter,pLeader->Vcid);
+ if(QueueIndex < NO_OF_QUEUES)
+ {
+ bHeaderSupressionEnabled =
+ Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
+ bHeaderSupressionEnabled =
+ bHeaderSupressionEnabled & Adapter->bPHSEnabled;
+ }
+
+ skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment
+ if(!skb)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet");
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+ return;
+ }
+ /* If it is a control Packet, then call handle_bcm_packet ()*/
+ if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) ||
+ (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F)))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Recived control pkt...");
+ *(PUSHORT)skb->data = pLeader->Status;
+ memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
+ (sizeof(LEADER)), pLeader->PLength);
+ skb->len = pLeader->PLength + sizeof(USHORT);
+
+ spin_lock(&Adapter->control_queue_lock);
+ ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb);
+ spin_unlock(&Adapter->control_queue_lock);
+
+ atomic_inc(&Adapter->cntrlpktCnt);
+ wake_up(&Adapter->process_rx_cntrlpkt);
+ }
+ else
+ {
+ /*
+ * Data Packet, Format a proper Ethernet Header
+ * and give it to the stack
+ */
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt...");
+ skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
+ memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength);
+ skb->dev = Adapter->dev;
+
+ /* currently skb->len has extra ETH_HLEN bytes in the beginning */
+ skb_put (skb, pLeader->PLength + ETH_HLEN);
+ Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
+ Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
+ atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength);
+
+ if(Adapter->if_up)
+ {
+ /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
+ skb_pull(skb, ETH_HLEN);
+ PHSRecieve(Adapter, pLeader->Vcid, skb, &skb->len,
+ NULL,bHeaderSupressionEnabled);
+
+ if(!Adapter->PackInfo[QueueIndex].bEthCSSupport)
+ {
+ skb_push(skb, ETH_HLEN);
+
+ memcpy(skb->data, skb->dev->dev_addr, 6);
+ memcpy(skb->data+6, skb->dev->dev_addr, 6);
+ (*(skb->data+11))++;
+ *(skb->data+12) = 0x08;
+ *(skb->data+13) = 0x00;
+ pLeader->PLength+=ETH_HLEN;
+ }
+
+ skb->protocol = eth_type_trans(skb, Adapter->dev);
+ process_done = netif_rx(skb);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
+ bcm_kfree_skb(skb);
+ }
+ atomic_inc(&Adapter->GoodRxPktCount);
+ for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
+ {
+ if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
+ && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
+ Adapter->aRxPktSizeHist[uiIndex]++;
+ }
+ }
+ Adapter->PrevNumRecvDescs++;
+ pRcb->bUsed = FALSE;
+ atomic_dec(&psIntfAdapter->uNumRcbUsed);
+}
+
+static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
+{
+ struct urb *urb = pRcb->urb;
+ int retval = 0;
+
+ usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe(
+ psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
+ urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback,
+ pRcb);
+ if(FALSE == psIntfAdapter->psAdapter->device_removed &&
+ FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
+ FALSE == psIntfAdapter->bSuspended &&
+ FALSE == psIntfAdapter->bPreparingForBusSuspend)
+ {
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval);
+ //if this return value is because of pipe halt. need to clear this.
+ if(retval == -EPIPE)
+ {
+ psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
+ wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
+ }
+
+ }
+ }
+ return retval;
+}
+
+/*
+Function: InterfaceRx
+
+Description: This is the hardware specific Function for Recieveing
+ data packet/control packets from the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+
+Return: TRUE - If Rx was successful.
+ Other - If an error occured.
+*/
+
+BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
+ PUSB_RCB pRcb = NULL;
+
+// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs -
+// psIntfAdapter->psAdapter->PrevNumRecvDescs;
+ while(RxDescCount)
+ {
+ pRcb = GetBulkInRcb(psIntfAdapter);
+ if(pRcb == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
+ return FALSE;
+ }
+ //atomic_inc(&psIntfAdapter->uNumRcbUsed);
+ ReceiveRcb(psIntfAdapter, pRcb);
+ RxDescCount--;
+ }
+ return TRUE;
+}
+
diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h
new file mode 100644
index 000000000000..96e81a1d37b8
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceRx.h
@@ -0,0 +1,7 @@
+#ifndef _INTERFACE_RX_H
+#define _INTERFACE_RX_H
+
+BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter);
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c
new file mode 100644
index 000000000000..771f7b34d2ec
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceTx.c
@@ -0,0 +1,259 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+/*
+Function: InterfaceTxDataPacket
+
+Description: This is the hardware specific Function for Transmitting
+ data packet to the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+ PVOID Packet - Packet Containing the data to be transmitted
+ USHORT usVcid - VCID on which data packet is to be sent
+
+
+Return: BCM_STATUS_SUCCESS - If Tx was successful.
+ Other - If an error occured.
+*/
+
+ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid)
+{
+ ULONG Status = 0;
+ return Status;
+}
+
+/*
+Function: InterfaceTxControlPacket
+
+Description: This is the hardware specific Function for Transmitting
+ control packet to the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+ PVOID pvBuffer - Buffer containg control packet
+ UINT uiBufferLength - Buffer Length
+
+Return: BCM_STATUS_SUCCESS - If control packet transmit was successful.
+ Other - If an error occured.
+*/
+
+ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength)
+{
+ ULONG Status = 0;
+
+
+
+ return Status;
+}
+/*this is transmit call-back(BULK OUT)*/
+static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
+{
+ PUSB_TCB pTcb= (PUSB_TCB)urb->context;
+ PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter;
+ CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer;
+ PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ;
+ BOOLEAN bpowerDownMsg = FALSE ;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+#if 0
+ struct timeval tv;
+ UINT time_ms = 0;
+#endif
+ if(urb->status != STATUS_SUCCESS)
+ {
+ if(urb->status == -EPIPE)
+ {
+ psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
+ wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status);
+ }
+ }
+
+ pTcb->bUsed = FALSE;
+ atomic_dec(&psIntfAdapter->uNumTcbUsed);
+
+
+
+ if(TRUE == psAdapter->bPreparingForLowPowerMode)
+ {
+ #if 0
+ do_gettimeofday(&tv);
+ time_ms = tv.tv_sec *1000 + tv.tv_usec/1000;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms);
+ #endif
+
+ if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
+ (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
+
+ {
+ bpowerDownMsg = TRUE ;
+ //This covers the bus err while Idle Request msg sent down.
+ if(urb->status != STATUS_SUCCESS)
+ {
+ psAdapter->bPreparingForLowPowerMode = FALSE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem");
+ //Signalling the cntrl pkt path in Ioctl
+ wake_up(&psAdapter->lowpower_mode_wait_queue);
+ StartInterruptUrb(psIntfAdapter);
+ goto err_exit;
+ }
+
+ if(psAdapter->bDoSuspend == FALSE)
+ {
+ psAdapter->IdleMode = TRUE;
+ //since going in Idle mode completed hence making this var false;
+ psAdapter->bPreparingForLowPowerMode = FALSE ;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State...");
+ //Signalling the cntrl pkt path in Ioctl
+ wake_up(&psAdapter->lowpower_mode_wait_queue);
+ }
+
+ }
+ else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) &&
+ (pControlMsg->szData[0] == LINK_UP_ACK) &&
+ (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) &&
+ (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER))
+ {
+ //This covers the bus err while shutdown Request msg sent down.
+ if(urb->status != STATUS_SUCCESS)
+ {
+ psAdapter->bPreparingForLowPowerMode = FALSE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem");
+ //Signalling the cntrl pkt path in Ioctl
+ wake_up(&psAdapter->lowpower_mode_wait_queue);
+ StartInterruptUrb(psIntfAdapter);
+ goto err_exit;
+ }
+
+ bpowerDownMsg = TRUE ;
+ if(psAdapter->bDoSuspend == FALSE)
+ {
+ psAdapter->bShutStatus = TRUE;
+ //since going in shutdown mode completed hence making this var false;
+ psAdapter->bPreparingForLowPowerMode = FALSE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State...");
+ //Signalling the cntrl pkt path in Ioctl
+ wake_up(&psAdapter->lowpower_mode_wait_queue);
+ }
+ }
+
+ if(psAdapter->bDoSuspend && bpowerDownMsg)
+ {
+ //issuing bus suspend request
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack");
+ psIntfAdapter->bPreparingForBusSuspend = TRUE;
+ schedule_work(&psIntfAdapter->usbSuspendWork);
+
+ }
+
+ }
+
+err_exit :
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+ usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+#else
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+#endif
+}
+
+
+static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ PUSB_TCB pTcb = NULL;
+ UINT index = 0;
+
+ if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) &&
+ (psIntfAdapter->psAdapter->StopAllXaction ==FALSE))
+ {
+ index = atomic_read(&psIntfAdapter->uCurrTcb);
+ pTcb = &psIntfAdapter->asUsbTcb[index];
+ pTcb->bUsed = TRUE;
+ pTcb->psIntfAdapter= psIntfAdapter;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d",
+ index, atomic_read(&psIntfAdapter->uNumTcbUsed));
+ index = (index + 1) % MAXIMUM_USB_TCB;
+ atomic_set(&psIntfAdapter->uCurrTcb, index);
+ atomic_inc(&psIntfAdapter->uNumTcbUsed);
+ }
+ return pTcb;
+}
+
+static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
+{
+
+ struct urb *urb = pTcb->urb;
+ int retval = 0;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+ urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len,
+ GFP_ATOMIC, &urb->transfer_dma);
+#else
+ urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
+ GFP_ATOMIC, &urb->transfer_dma);
+#endif
+
+ if (!urb->transfer_buffer)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
+ return -ENOMEM;
+ }
+ memcpy(urb->transfer_buffer, data, len);
+ urb->transfer_buffer_length = len;
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n");
+ //For T3B,INT OUT end point will be used as bulk out end point
+ if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE))
+ {
+ usb_fill_int_urb(urb, psIntfAdapter->udev,
+ psIntfAdapter->sBulkOut.bulk_out_pipe,
+ urb->transfer_buffer, len, write_bulk_callback, pTcb,
+ psIntfAdapter->sBulkOut.int_out_interval);
+ }
+ else
+ {
+ usb_fill_bulk_urb(urb, psIntfAdapter->udev,
+ psIntfAdapter->sBulkOut.bulk_out_pipe,
+ urb->transfer_buffer, len, write_bulk_callback, pTcb);
+ }
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */
+
+ if(FALSE == psIntfAdapter->psAdapter->device_removed &&
+ FALSE == psIntfAdapter->psAdapter->bEndPointHalted &&
+ FALSE == psIntfAdapter->bSuspended &&
+ FALSE == psIntfAdapter->bPreparingForBusSuspend)
+ {
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval);
+ if(retval == -EPIPE)
+ {
+ psIntfAdapter->psAdapter->bEndPointHalted = TRUE ;
+ wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
+ }
+ }
+ }
+ return retval;
+}
+
+int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
+{
+ PUSB_TCB pTcb= NULL;
+
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+ pTcb= GetBulkOutTcb(psIntfAdapter);
+ if(pTcb == NULL)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet");
+ return -EFAULT;
+ }
+ return TransmitTcb(psIntfAdapter, pTcb, data, len);
+}
+
+#endif
+
diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h
new file mode 100644
index 000000000000..053f631e2042
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceTx.h
@@ -0,0 +1,13 @@
+#ifndef _INTERFACE_TX_H
+#define _INTERFACE_TX_H
+
+INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len);
+
+
+ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid);
+
+ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength);
+
+
+#endif
+
diff --git a/drivers/staging/bcm/Interfacemain.h b/drivers/staging/bcm/Interfacemain.h
new file mode 100644
index 000000000000..e0db563c5e0f
--- /dev/null
+++ b/drivers/staging/bcm/Interfacemain.h
@@ -0,0 +1,10 @@
+#ifndef _MAIN_
+#define _MAIN_
+#if 0
+typedef struct _MINI_ADAPTER
+{
+ S_INTERFACE_ADAPTER stInterfaceAdapter;
+}MINI_ADAPTER,*PMINI_ADAPTER;
+
+#endif
+#endif
diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h
new file mode 100644
index 000000000000..2651fc2432ce
--- /dev/null
+++ b/drivers/staging/bcm/Ioctl.h
@@ -0,0 +1,360 @@
+#ifndef _IOCTL_H_
+#define _IOCTL_H_
+
+typedef struct rdmbuffer
+{
+ ULONG Register;
+ ULONG Length;
+}__attribute__((packed)) RDM_BUFFER, *PRDM_BUFFER;
+
+
+typedef struct wrmbuffer
+{
+ ULONG Register;
+ ULONG Length;
+ UCHAR Data[4];
+}__attribute__((packed)) WRM_BUFFER, *PWRM_BUFFER;
+
+
+typedef struct ioctlbuffer
+{
+ PVOID InputBuffer;
+ ULONG InputLength;
+ PVOID OutputBuffer;
+ ULONG OutputLength;
+}__attribute__((packed)) IOCTL_BUFFER, *PIOCTL_BUFFER;
+
+typedef struct stGPIOInfo
+{
+ UINT uiGpioNumber ; /* valid numbers 0-15 */
+ UINT uiGpioValue; /* 1 set ; 0 not set */
+}__attribute__((packed))GPIO_INFO,*PGPIO_INFO;
+typedef struct stUserThreadReq
+{
+ //0->Inactivate LED thread.
+ //1->Activate the LED thread
+ UINT ThreadState;
+}__attribute__((packed))USER_THREAD_REQ,*PUSER_THREAD_REQ;
+#define LED_THREAD_ACTIVATION_REQ 1
+
+
+////********** ioctl codes ***********////
+
+#define BCM_IOCTL 'k'
+
+//1.Control code for CONTROL MESSAGES
+
+#define IOCTL_SEND_CONTROL_MESSAGE _IOW(BCM_IOCTL, 0x801,int)
+
+//2.Control code to write a particular value to a particular register
+#define IOCTL_BCM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x802, int) //
+
+//3.
+#define IOCTL_BCM_REGISTER_READ _IOR(BCM_IOCTL, 0x803, int) //
+
+//4.Control code to write x number of bytes to common memory
+//starting from address y
+#define IOCTL_BCM_COMMON_MEMORY_WRITE _IOW(BCM_IOCTL, 0x804, int)//
+
+//5.Control code to write x number of bytes to common memory
+//starting from address y
+#define IOCTL_BCM_COMMON_MEMORY_READ _IOR(BCM_IOCTL, 0x805, int)//
+
+//6.Control code for CONTROL MESSAGES
+#define IOCTL_GET_CONTROL_MESSAGE _IOR(BCM_IOCTL, 0x806, int)//
+
+//7.Control code for FIRMWARE DOWNLOAD
+#define IOCTL_BCM_FIRMWARE_DOWNLOAD _IOW(BCM_IOCTL, 0x807, int)//
+
+#define IOCTL_BCM_SET_SEND_VCID _IOW(BCM_IOCTL, 0x808, int)
+
+//9.Control code for TRANSFER MODE SWITCHING
+#define IOCTL_BCM_SWITCH_TRANSFER_MODE _IOW(BCM_IOCTL, 0x809, int)
+//10.Control code for LINK UP
+#define IOCTL_LINK_REQ _IOW(BCM_IOCTL, 0x80A, int)
+
+//11.Control code for RSSI Level Request
+#define IOCTL_RSSI_LEVEL_REQ _IOW(BCM_IOCTL, 0x80B, int)
+//12.Control code for IDLE MODE CONTROL
+#define IOCTL_IDLE_REQ _IOW(BCM_IOCTL, 0x80C, int)
+//13.Control code for SS/BS info
+#define IOCTL_SS_INFO_REQ _IOW(BCM_IOCTL, 0x80D, int)
+
+#define IOCTL_GET_STATISTICS_POINTER _IOW(BCM_IOCTL, 0x80E, int)
+
+#define IOCTL_CM_REQUEST _IOW(BCM_IOCTL, 0x80F, int)
+
+#define IOCTL_INIT_PARAM_REQ _IOW(BCM_IOCTL, 0x810, int)
+
+#define IOCTL_MAC_ADDR_REQ _IOW(BCM_IOCTL, 0x811, int)
+
+#define IOCTL_MAC_ADDR_RESP _IOWR(BCM_IOCTL, 0x812, int)
+
+#define IOCTL_CLASSIFICATION_RULE _IOW(BCM_IOCTL, 0x813, char)
+
+#define IOCTL_CLOSE_NOTIFICATION _IO(BCM_IOCTL, 0x814)
+
+#define IOCTL_LINK_UP _IO(BCM_IOCTL, 0x815)
+
+#define IOCTL_LINK_DOWN _IO(BCM_IOCTL, 0x816, IOCTL_BUFFER)
+
+#define IOCTL_CHIP_RESET _IO(BCM_IOCTL, 0x816)
+
+#define IOCTL_CINR_LEVEL_REQ _IOW(BCM_IOCTL, 0x817, char)
+
+#define IOCTL_WTM_CONTROL_REQ _IOW(BCM_IOCTL, 0x817,char)
+
+#define IOCTL_BE_BUCKET_SIZE _IOW(BCM_IOCTL, 0x818, unsigned long)
+
+#define IOCTL_RTPS_BUCKET_SIZE _IOW(BCM_IOCTL, 0x819, unsigned long)
+
+#define IOCTL_QOS_THRESHOLD _IOW(BCM_IOCTL, 0x820, unsigned long)
+
+#define IOCTL_DUMP_PACKET_INFO _IO(BCM_IOCTL, 0x821)
+
+#define IOCTL_GET_PACK_INFO _IOR(BCM_IOCTL, 0x823, int)
+
+#define IOCTL_BCM_GET_DRIVER_VERSION _IOR(BCM_IOCTL, 0x829, int)
+
+#define IOCTL_BCM_GET_CURRENT_STATUS _IOW(BCM_IOCTL, 0x828, int)
+
+#define IOCTL_BCM_GPIO_SET_REQUEST _IOW(BCM_IOCTL, 0x82A, int)
+
+#define IOCTL_BCM_GPIO_STATUS_REQUEST _IOW(BCM_IOCTL, 0x82b, int)
+
+#define IOCTL_BCM_GET_DSX_INDICATION _IOR(BCM_IOCTL, 0x854, int)
+
+#define IOCTL_BCM_BUFFER_DOWNLOAD_START _IOW(BCM_IOCTL, 0x855, int)
+
+#define IOCTL_BCM_BUFFER_DOWNLOAD _IOW(BCM_IOCTL, 0x856, int)
+
+#define IOCTL_BCM_BUFFER_DOWNLOAD_STOP _IOW(BCM_IOCTL, 0x857, int)
+
+#define IOCTL_BCM_REGISTER_WRITE_PRIVATE _IOW(BCM_IOCTL, 0x826, char)
+
+#define IOCTL_BCM_REGISTER_READ_PRIVATE _IOW(BCM_IOCTL, 0x827, char)
+
+#define IOCTL_BCM_SET_DEBUG _IOW(BCM_IOCTL, 0x824, IOCTL_BUFFER)
+
+#define IOCTL_BCM_EEPROM_REGISTER_WRITE _IOW(BCM_IOCTL, 0x858, int)
+
+#define IOCTL_BCM_EEPROM_REGISTER_READ _IOR(BCM_IOCTL, 0x859, int)
+
+#define IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE _IOR(BCM_IOCTL, 0x860, int)
+
+#define IOCTL_BCM_SET_MAC_TRACING _IOW(BCM_IOCTL, 0x82c, int)
+
+#define IOCTL_BCM_GET_HOST_MIBS _IOW(BCM_IOCTL, 0x853, int)
+
+#define IOCTL_BCM_NVM_READ _IOR(BCM_IOCTL, 0x861, int)
+
+#define IOCTL_BCM_NVM_WRITE _IOW(BCM_IOCTL, 0x862, int)
+
+#define IOCTL_BCM_GET_NVM_SIZE _IOR(BCM_IOCTL, 0x863, int)
+
+#define IOCTL_BCM_CAL_INIT _IOR(BCM_IOCTL, 0x864, int)
+
+#define IOCTL_BCM_BULK_WRM _IOW(BCM_IOCTL, 0x90B, int)
+
+#define IOCTL_BCM_FLASH2X_SECTION_READ _IOR(BCM_IOCTL, 0x865, int)
+
+#define IOCTL_BCM_FLASH2X_SECTION_WRITE _IOW(BCM_IOCTL, 0x866, int)
+
+#define IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP _IOR(BCM_IOCTL,0x867, int)
+
+#define IOCTL_BCM_SET_ACTIVE_SECTION _IOW(BCM_IOCTL,0x868, int)
+
+#define IOCTL_BCM_IDENTIFY_ACTIVE_SECTION _IO(BCM_IOCTL,0x869)
+
+#define IOCTL_BCM_COPY_SECTION _IOW(BCM_IOCTL, 0x870,int)
+
+#define IOCTL_BCM_GET_FLASH_CS_INFO _IOR(BCM_IOCTL, 0x871, int)
+
+#define IOCTL_BCM_SELECT_DSD _IOW(BCM_IOCTL, 0x872, int)
+
+#define IOCTL_BCM_NVM_RAW_READ _IOR(BCM_IOCTL, 0x875, int)
+
+#define IOCTL_BCM_CNTRLMSG_MASK _IOW(BCM_IOCTL, 0x874, int)
+
+#define IOCTL_BCM_GET_DEVICE_DRIVER_INFO _IOR(BCM_IOCTL, 0x877, int)
+
+#define IOCTL_BCM_TIME_SINCE_NET_ENTRY _IOR(BCM_IOCTL, 0x876, int)
+
+#define BCM_LED_THREAD_STATE_CHANGE_REQ _IOW(BCM_IOCTL, 0x878, int)
+
+#define IOCTL_BCM_GPIO_MULTI_REQUEST _IOW(BCM_IOCTL, 0x82D, IOCTL_BUFFER)
+#define IOCTL_BCM_GPIO_MODE_REQUEST _IOW(BCM_IOCTL, 0x82E, IOCTL_BUFFER)
+
+
+
+typedef enum _BCM_INTERFACE_TYPE
+{
+ BCM_MII,
+ BCM_CARDBUS,
+ BCM_USB,
+ BCM_SDIO,
+ BCM_PCMCIA
+}BCM_INTERFACE_TYPE;
+
+typedef struct _DEVICE_DRIVER_INFO
+{
+ NVM_TYPE u32NVMType;
+ UINT MaxRDMBufferSize;
+ BCM_INTERFACE_TYPE u32InterfaceType;
+ UINT u32DSDStartOffset;
+ UINT u32RxAlignmentCorrection;
+ UINT u32Reserved[10];
+} DEVICE_DRIVER_INFO;
+
+typedef struct _NVM_READWRITE
+{
+
+ void *pBuffer;
+// Data to be written from|read to. Memory should be allocated by the caller.
+
+ uint32_t uiOffset;
+// offset at which data should be written to or read from.
+
+ uint32_t uiNumBytes;
+// No. of bytes to be written or read.
+
+ bool bVerify;
+// Applicable only for write. If set verification of written data will be done.
+
+} NVM_READWRITE,*PNVM_READWRITE;
+typedef struct bulkwrmbuffer
+{
+ ULONG Register;
+ ULONG SwapEndian;
+ ULONG Values[1];
+
+}BULKWRM_BUFFER,*PBULKWRM_BUFFER;
+
+
+/***********Structure used for FlashMap2.x *******************************/
+
+/*
+* These are Sction present inside the Flash.
+* There is sectional RD/WR for flash Map 2.x.
+* hence these section will be used in read/write API.
+*/
+
+typedef enum _FLASH2X_SECTION_VAL
+{
+ NO_SECTION_VAL = 0, //no section is choosen when absolute offset is given for RD/WR
+ ISO_IMAGE1,
+ ISO_IMAGE2,
+ DSD0,
+ DSD1,
+ DSD2,
+ VSA0,
+ VSA1,
+ VSA2,
+ SCSI,
+ CONTROL_SECTION,
+ ISO_IMAGE1_PART2,
+ ISO_IMAGE1_PART3,
+ ISO_IMAGE2_PART2,
+ ISO_IMAGE2_PART3,
+ TOTAL_SECTIONS
+}FLASH2X_SECTION_VAL;
+
+/*
+* Structure used for READ/WRITE Flash Map2.x
+*/
+typedef struct _FLASH2X_READWRITE
+{
+
+ FLASH2X_SECTION_VAL Section; //which section has to be read/written
+ B_UINT32 offset; //Offset within Section.
+ B_UINT32 numOfBytes; //NOB from the offset
+ B_UINT32 bVerify;
+ PVOID pDataBuff; //Buffer for reading/writing
+
+}FLASH2X_READWRITE, *PFLASH2X_READWRITE;
+/*
+* This structure is used for coping one section to other.
+* there are two ways to copy one section to other.
+* it NOB =0, complete section will be copied on to other.
+* if NOB !=0, only NOB will be copied from the given offset.
+*/
+
+typedef struct _FLASH2X_COPY_SECTION
+{
+ //Src Section from which Data has to be copied to DstSection
+ FLASH2X_SECTION_VAL SrcSection;
+
+ //Destination Section from where Data has to be coppied.
+ FLASH2X_SECTION_VAL DstSection;
+
+ //Offset within Section. if NOB =0 it will be ignored and data will be coped from offset 0.
+ B_UINT32 offset;
+
+ //NOB from the offset. if NOB = 0 complete src section will be copied to Destination section.
+ B_UINT32 numOfBytes;
+} FLASH2X_COPY_SECTION, *PFLASH2X_COPY_SECTION;
+
+
+typedef enum _SECTION_TYPE
+{
+ ISO = 0,
+ VSA = 1,
+ DSD = 2
+} SECTION_TYPE, *PSECTION_TYPE;
+
+/*
+* This section provide the complete bitmap of the Flash.
+* using this map lib/APP will isssue read/write command.
+ Fields are defined as :
+ Bit [0] = section is present //1:present, 0: Not present
+* Bit [1] = section is valid //1: valid, 0: not valid
+* Bit [2] = Section is R/W //0: RW, 1: RO
+* Bit [3] = Section is Active or not 1 means Active, 0->inactive
+* Bit [7...3] = Reserved
+*/
+
+typedef struct _FLASH2X_BITMAP
+{
+ UCHAR ISO_IMAGE1;
+ UCHAR ISO_IMAGE2;
+ UCHAR DSD0;
+ UCHAR DSD1;
+ UCHAR DSD2;
+ UCHAR VSA0;
+ UCHAR VSA1;
+ UCHAR VSA2;
+ UCHAR SCSI;
+ UCHAR CONTROL_SECTION;
+ //Reserved for future use
+ UCHAR Reserved0;
+ UCHAR Reserved1;
+ UCHAR Reserved2;
+}FLASH2X_BITMAP, *PFLASH2X_BITMAP;
+
+//for net entry time check
+typedef struct _ST_TIME_ELAPSED_
+{
+ ULONG64 ul64TimeElapsedSinceNetEntry;
+ UINT32 uiReserved[4]; //By chance if required for future proofing
+}ST_TIME_ELAPSED,*PST_TIME_ELAPSED;
+
+enum {
+ WIMAX_IDX=0, /*To access WiMAX chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
+ HOST_IDX, /*To access Host chip GPIO's for GPIO_MULTI_INFO or GPIO_MULTI_MODE*/
+ MAX_IDX
+};
+typedef struct stGPIOMultiInfo
+{
+ UINT uiGPIOCommand; /* 1 for set and 0 for get*/
+ UINT uiGPIOMask; /* set the correspondig bit to 1 to access GPIO*/
+ UINT uiGPIOValue; /* 0 or 1; value to be set when command is 1.*/
+}__attribute__((packed))GPIO_MULTI_INFO , *PGPIO_MULTI_INFO;
+
+typedef struct stGPIOMultiMode
+{
+ UINT uiGPIOMode; /* 1 for OUT mode, 0 for IN mode*/
+ UINT uiGPIOMask; /* GPIO mask to set mode*/
+}__attribute__((packed))GPIO_MULTI_MODE, *PGPIO_MULTI_MODE;
+
+
+#endif
diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig
new file mode 100644
index 000000000000..96adb1026c4f
--- /dev/null
+++ b/drivers/staging/bcm/Kconfig
@@ -0,0 +1,7 @@
+config BCM_WIMAX
+ tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support"
+ depends on USB && NET && EXPERIMENTAL
+ default N
+ help
+ This is an experimental driver for the Beceem WIMAX chipset used
+ by Sprint 4G.
diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c
new file mode 100644
index 000000000000..1875c8289010
--- /dev/null
+++ b/drivers/staging/bcm/LeakyBucket.c
@@ -0,0 +1,399 @@
+/**********************************************************************
+* LEAKYBUCKET.C
+* This file contains the routines related to Leaky Bucket Algorithm.
+***********************************************************************/
+#include "headers.h"
+
+/*********************************************************************
+* Function - UpdateTokenCount()
+*
+* Description - This function calculates the token count for each
+* channel and updates the same in Adapter strucuture.
+*
+* Parameters - Adapter: Pointer to the Adapter structure.
+*
+* Returns - None
+**********************************************************************/
+
+VOID UpdateTokenCount(register PMINI_ADAPTER Adapter)
+{
+ ULONG liCurrentTime;
+ INT i = 0;
+ struct timeval tv;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
+ if(NULL == Adapter)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
+ return;
+ }
+
+ do_gettimeofday(&tv);
+ for(i = 0; i < NO_OF_QUEUES; i++)
+ {
+ if(TRUE == Adapter->PackInfo[i].bValid &&
+ (1 == Adapter->PackInfo[i].ucDirection))
+ {
+ liCurrentTime = ((tv.tv_sec-
+ Adapter->PackInfo[i].stLastUpdateTokenAt.tv_sec)*1000 +
+ (tv.tv_usec-Adapter->PackInfo[i].stLastUpdateTokenAt.tv_usec)/
+ 1000);
+ if(0!=liCurrentTime)
+ {
+ Adapter->PackInfo[i].uiCurrentTokenCount += (ULONG)
+ ((Adapter->PackInfo[i].uiMaxAllowedRate) *
+ ((ULONG)((liCurrentTime)))/1000);
+ memcpy(&Adapter->PackInfo[i].stLastUpdateTokenAt,
+ &tv, sizeof(struct timeval));
+ Adapter->PackInfo[i].liLastUpdateTokenAt = liCurrentTime;
+ if((Adapter->PackInfo[i].uiCurrentTokenCount) >=
+ Adapter->PackInfo[i].uiMaxBucketSize)
+ {
+ Adapter->PackInfo[i].uiCurrentTokenCount =
+ Adapter->PackInfo[i].uiMaxBucketSize;
+ }
+ }
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n");
+ return;
+
+}
+
+
+/*********************************************************************
+* Function - IsPacketAllowedForFlow()
+*
+* Description - This function checks whether the given packet from the
+* specified queue can be allowed for transmission by
+* checking the token count.
+*
+* Parameters - Adapter : Pointer to the Adpater structure.
+* - iQIndex : The queue Identifier.
+* - ulPacketLength: Number of bytes to be transmitted.
+*
+* Returns - The number of bytes allowed for transmission.
+*
+***********************************************************************/
+static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
+ /* Validate the parameters */
+ if(NULL == Adapter || (psSF < Adapter->PackInfo &&
+ (UINT)psSF > (UINT) &Adapter->PackInfo[HiPriority]))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %d\n", Adapter, (psSF-Adapter->PackInfo));
+ return 0;
+ }
+
+ if(FALSE != psSF->bValid && psSF->ucDirection)
+ {
+ if(0 != psSF->uiCurrentTokenCount)
+ {
+ return psSF->uiCurrentTokenCount;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %d Available %u\n",
+ psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
+ psSF->uiPendedLast = 1;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %d not valid\n", psSF-Adapter->PackInfo);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
+ return 0;
+}
+
+static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet)
+{
+ struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL;
+ psQueueCurrent = pPackInfo->FirstTxQueue;
+ while(psQueueCurrent)
+ {
+ if((UINT)Packet == (UINT)psQueueCurrent)
+ {
+ if((UINT)psQueueCurrent == (UINT)pPackInfo->FirstTxQueue)
+ {
+ pPackInfo->FirstTxQueue=psQueueCurrent->next;
+ if((UINT)psQueueCurrent==(UINT)pPackInfo->LastTxQueue)
+ pPackInfo->LastTxQueue=NULL;
+ }
+ else
+ {
+ psLastQueueNode->next=psQueueCurrent->next;
+ }
+ break;
+ }
+ psLastQueueNode = psQueueCurrent;
+ psQueueCurrent=psQueueCurrent->next;
+ }
+}
+/**
+@ingroup tx_functions
+This function despatches packet from the specified queue.
+@return Zero(success) or Negative value(failure)
+*/
+static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
+ PacketInfo *psSF, /**<Queue identifier*/
+ struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
+{
+ INT Status=STATUS_FAILURE;
+ UINT uiIndex =0,PktLen = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>");
+ if(!Adapter || !Packet || !psSF)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet");
+ return -EINVAL;
+ }
+
+ if(psSF->liDrainCalculated==0)
+ {
+ psSF->liDrainCalculated = jiffies;
+ }
+ ///send the packet to the fifo..
+ PktLen = Packet->len;
+ Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value);
+ if(Status == 0)
+ {
+ for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
+ { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
+ Adapter->aTxPktSizeHist[uiIndex]++;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<=====");
+ return Status;
+}
+
+/************************************************************************
+* Function - CheckAndSendPacketFromIndex()
+*
+* Description - This function dequeues the data/control packet from the
+* specified queue for transmission.
+*
+* Parameters - Adapter : Pointer to the driver control structure.
+* - iQIndex : The queue Identifier.
+*
+* Returns - None.
+*
+****************************************************************************/
+static __inline VOID CheckAndSendPacketFromIndex
+(PMINI_ADAPTER Adapter, PacketInfo *psSF)
+{
+ struct sk_buff *QueuePacket=NULL;
+ char *pControlPacket = NULL;
+ INT Status=0;
+ int iPacketLen=0;
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%d ====>", (psSF-Adapter->PackInfo));
+ if(((UINT)psSF != (UINT)&Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet
+ {
+ if(!psSF->ucDirection )
+ return;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
+ if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
+ return;
+ }
+ // Check for Free Descriptors
+ if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..",atomic_read(&Adapter->CurrNumFreeTxDesc));
+ return ;
+ }
+
+#if 0
+ PruneQueue(Adapter,(psSF-Adapter->PackInfo));
+#endif
+ spin_lock_bh(&psSF->SFQueueLock);
+ QueuePacket=psSF->FirstTxQueue;
+
+ if(QueuePacket)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet");
+
+ if(psSF->bEthCSSupport)
+ iPacketLen = QueuePacket->len;
+ else
+ iPacketLen = QueuePacket->len-ETH_HLEN;
+
+ iPacketLen<<=3;
+ if(iPacketLen <= GetSFTokenCount(Adapter, psSF))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d",
+ (iPacketLen >> 3));
+
+ DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue);
+ psSF->uiCurrentBytesOnHost -= (QueuePacket->len);
+ psSF->uiCurrentPacketsOnHost--;
+ atomic_dec(&Adapter->TotalPacketCount);
+ spin_unlock_bh(&psSF->SFQueueLock);
+
+ Status = SendPacketFromQueue(Adapter, psSF, QueuePacket);
+ psSF->uiPendedLast = FALSE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %d\n", psSF-Adapter->PackInfo);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
+ psSF->uiCurrentTokenCount, iPacketLen);
+ //this part indicates that becuase of non-availability of the tokens
+ //pkt has not been send out hence setting the pending flag indicating the host to send it out
+ //first next iteration .
+ psSF->uiPendedLast = TRUE;
+ spin_unlock_bh(&psSF->SFQueueLock);
+ }
+ }
+ else
+ {
+ spin_unlock_bh(&psSF->SFQueueLock);
+ }
+ }
+ else
+ {
+
+ if((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0 ) &&
+ (atomic_read(&Adapter->index_rd_txcntrlpkt) !=
+ atomic_read(&Adapter->index_wr_txcntrlpkt))
+ )
+ {
+ pControlPacket = Adapter->txctlpacket
+ [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
+ if(pControlPacket)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet");
+ Status = SendControlPacket(Adapter, pControlPacket);
+ if(STATUS_SUCCESS==Status)
+ {
+ spin_lock_bh(&psSF->SFQueueLock);
+ psSF->NumOfPacketsSent++;
+ psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength;
+ psSF->uiSentPackets++;
+ atomic_dec(&Adapter->TotalPacketCount);
+ psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength;
+ psSF->uiCurrentPacketsOnHost--;
+ atomic_inc(&Adapter->index_rd_txcntrlpkt);
+ spin_unlock_bh(&psSF->SFQueueLock);
+ }
+ else
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong....");
+ }
+ }
+ }
+
+ if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed
+ {
+ if(Adapter->bcm_jiffies == 0)
+ Adapter->bcm_jiffies = jiffies;
+ }
+ else
+ {
+ Adapter->bcm_jiffies = 0;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<=====");
+}
+
+
+/*******************************************************************
+* Function - transmit_packets()
+*
+* Description - This function transmits the packets from different
+* queues, if free descriptors are available on target.
+*
+* Parameters - Adapter: Pointer to the Adapter structure.
+*
+* Returns - None.
+********************************************************************/
+VOID transmit_packets(PMINI_ADAPTER Adapter)
+{
+ UINT uiPrevTotalCount = 0;
+ int iIndex = 0;
+
+ BOOLEAN exit_flag = TRUE ;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>");
+
+ if(NULL == Adapter)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX,TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter");
+ return;
+ }
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed");
+ return;
+ }
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n");
+
+ UpdateTokenCount(Adapter);
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n");
+
+ PruneQueueAllSF(Adapter);
+
+ uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount);
+
+ for(iIndex=HiPriority;iIndex>=0;iIndex--)
+ {
+ if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
+ break;
+
+ if(Adapter->PackInfo[iIndex].bValid &&
+ Adapter->PackInfo[iIndex].uiPendedLast &&
+ Adapter->PackInfo[iIndex].uiCurrentBytesOnHost)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
+ CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
+ uiPrevTotalCount--;
+ }
+ }
+
+ while(uiPrevTotalCount > 0 && !Adapter->device_removed)
+ {
+ exit_flag = TRUE ;
+ //second iteration to parse non-pending queues
+ for(iIndex=HiPriority;iIndex>=0;iIndex--)
+ {
+ if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
+ break;
+
+ if(Adapter->PackInfo[iIndex].bValid &&
+ Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
+ !Adapter->PackInfo[iIndex].uiPendedLast )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
+ CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
+ uiPrevTotalCount--;
+ exit_flag = FALSE;
+ }
+ }
+
+ if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n");
+ break;
+ }
+ if(exit_flag == TRUE )
+ break ;
+ }/* end of inner while loop */
+ if(Adapter->bcm_jiffies == 0 &&
+ atomic_read(&Adapter->TotalPacketCount) != 0 &&
+ uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount))
+ {
+ Adapter->bcm_jiffies = jiffies;
+ }
+ update_per_cid_rx (Adapter);
+ Adapter->txtransmit_running = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");
+}
diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h
new file mode 100644
index 000000000000..f559b599bd25
--- /dev/null
+++ b/drivers/staging/bcm/Macros.h
@@ -0,0 +1,399 @@
+/*************************************
+* Macros.h
+**************************************/
+#ifndef __MACROS_H__
+#define __MACROS_H__
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define kthread_run(threadfn,data,datafmt)(struct task_struct *)kernel_thread(threadfn,data,0)
+#endif
+
+#define TX_TIMER_PERIOD 10 //10 msec
+#define MAX_CLASSIFIERS 100
+//#define MAX_CLASSIFIERS_PER_SF 20
+#define MAX_TARGET_DSX_BUFFERS 24
+
+#define MAX_CNTRL_PKTS 100
+#define MAX_DATA_PKTS 200
+#define MAX_ETH_SIZE 1536
+#define MAX_CNTL_PKT_SIZE 2048
+/* TIMER RELATED */
+#define JIFFIES_2_QUADPART() (ULONG)(jiffies * 10000) // jiffies(1msec) to Quadpart(100nsec)
+
+#define MTU_SIZE 1400
+
+#define MAC_ADDR_REGISTER 0xbf60d000
+
+
+///////////Quality of Service///////////////////////////
+#define NO_OF_QUEUES 17
+#define HiPriority NO_OF_QUEUES-1
+#define LowPriority 0
+#define BE 2
+#define rtPS 4
+#define ERTPS 5
+#define UGS 6
+
+#define BE_BUCKET_SIZE 1024*1024*100 //32kb
+#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb
+#define MAX_ALLOWED_RATE 1024*1024*100
+#define TX_PACKET_THRESHOLD 10
+#define XSECONDS 1*HZ
+#define DSC_ACTIVATE_REQUEST 248
+#define QUEUE_DEPTH_OFFSET 0x1fc01000
+#define MAX_DEVICE_DESC_SIZE 2040
+#define MAX_CTRL_QUEUE_LEN 100
+#define MAX_APP_QUEUE_LEN 200
+#define MAX_LATENCY_ALLOWED 0xFFFFFFFF
+#define DEFAULT_UG_INTERVAL 250
+#define DEFAULT_UGI_FACTOR 4
+
+#define DEFAULT_PERSFCOUNT 60
+#define MAX_CONNECTIONS 10
+#define MAX_CLASS_NAME_LENGTH 32
+
+#define ETH_LENGTH_OF_ADDRESS 6
+#define MAX_MULTICAST_ADDRESSES 32
+#define IP_LENGTH_OF_ADDRESS 4
+
+#define IP_PACKET_ONLY_MODE 0
+#define ETH_PACKET_TUNNELING_MODE 1
+
+////////////Link Request//////////////
+#define SET_MAC_ADDRESS_REQUEST 0
+#define SYNC_UP_REQUEST 1
+#define SYNCED_UP 2
+#define LINK_UP_REQUEST 3
+#define LINK_CONNECTED 4
+#define SYNC_UP_NOTIFICATION 2
+#define LINK_UP_NOTIFICATION 4
+
+
+#define LINK_NET_ENTRY 0x0002
+#define HMC_STATUS 0x0004
+#define LINK_UP_CONTROL_REQ 0x83
+
+#define STATS_POINTER_REQ_STATUS 0x86
+#define NETWORK_ENTRY_REQ_PAYLOAD 198
+#define LINK_DOWN_REQ_PAYLOAD 226
+#define SYNC_UP_REQ_PAYLOAD 228
+#define STATISTICS_POINTER_REQ 237
+#define LINK_UP_REQ_PAYLOAD 245
+#define LINK_UP_ACK 246
+
+#define STATS_MSG_SIZE 4
+#define INDEX_TO_DATA 4
+
+#define GO_TO_IDLE_MODE_PAYLOAD 210
+#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211
+#define IDLE_MODE_SF_UPDATE_MSG 187
+
+#define SKB_RESERVE_ETHERNET_HEADER 16
+#define SKB_RESERVE_PHS_BYTES 32
+
+#define IP_PACKET_ONLY_MODE 0
+#define ETH_PACKET_TUNNELING_MODE 1
+
+#define ETH_CS_802_3 1
+#define ETH_CS_802_1Q_VLAN 3
+#define IPV4_CS 1
+#define IPV6_CS 2
+#define ETH_CS_MASK 0x3f
+
+/** \brief Validity bit maps for TLVs in packet classification rule */
+
+#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0
+#define PKT_CLASSIFICATION_VLANID_VALID 1
+
+#ifndef MIN
+#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b))
+#endif
+
+
+/*Leader related terms */
+#define LEADER_STATUS 0x00
+#define LEADER_STATUS_TCP_ACK 0x1
+#define LEADER_SIZE sizeof(LEADER)
+#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND)
+#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND)
+#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest)
+#define IDLE_REQ_SIZE sizeof(PACKETTOSEND)
+
+
+#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024
+
+#define GET_MAILBOX1_REG_REQUEST 0x87
+#define GET_MAILBOX1_REG_RESPONSE 0x67
+#define VCID_CONTROL_PACKET 0x00
+
+#define TRANSMIT_NETWORK_DATA 0x00
+#define RECEIVED_NETWORK_DATA 0x20
+
+#define CM_RESPONSES 0xA0
+#define STATUS_RSP 0xA1
+#define LINK_CONTROL_RESP 0xA2
+#define IDLE_MODE_STATUS 0xA3
+#define STATS_POINTER_RESP 0xA6
+#define MGMT_MSG_INFO_SW_STATUS 0xA7
+#define AUTH_SS_HOST_MSG 0xA8
+
+#define CM_DSA_ACK_PAYLOAD 247
+#define CM_DSC_ACK_PAYLOAD 248
+#define CM_DSD_ACK_PAYLOAD 249
+#define CM_DSDEACTVATE 250
+#define TOTAL_MASKED_ADDRESS_IN_BYTES 32
+
+#define MAC_REQ 0
+#define LINK_RESP 1
+#define RSSI_INDICATION 2
+
+#define SS_INFO 4
+#define STATISTICS_INFO 5
+#define CM_INDICATION 6
+#define PARAM_RESP 7
+#define BUFFER_1K 1024
+#define BUFFER_2K BUFFER_1K*2
+#define BUFFER_4K BUFFER_2K*2
+#define BUFFER_8K BUFFER_4K*2
+#define BUFFER_16K BUFFER_8K*2
+#define DOWNLINK_DIR 0
+#define UPLINK_DIR 1
+
+#define BCM_SIGNATURE "BECEEM"
+
+
+#define GPIO_OUTPUT_REGISTER 0x0F00003C
+#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040
+#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044
+#define GPIO_MODE_REGISTER 0x0F000034
+#define GPIO_PIN_STATE_REGISTER 0x0F000038
+
+
+typedef struct _LINK_STATE {
+ UCHAR ucLinkStatus;
+ UCHAR bIdleMode;
+ UCHAR bShutdownMode;
+}LINK_STATE, *PLINK_STATE;
+
+
+enum enLinkStatus {
+ WAIT_FOR_SYNC = 1,
+ PHY_SYNC_ACHIVED = 2,
+ LINKUP_IN_PROGRESS = 3,
+ LINKUP_DONE = 4,
+ DREG_RECIEVED = 5,
+ LINK_STATUS_RESET_RECIEVED = 6,
+ PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7,
+ LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8,
+ COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9
+};
+
+typedef enum _E_PHS_DSC_ACTION
+{
+ eAddPHSRule=0,
+ eSetPHSRule,
+ eDeletePHSRule,
+ eDeleteAllPHSRules
+}E_PHS_DSC_ACTION;
+
+
+#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac
+#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host
+#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000
+#define MINIMUM_PENDING_DESCRIPTORS 5
+
+#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC
+#define SHUTDOWN_ACK_FROM_DRIVER 0x1
+#define SHUTDOWN_NACK_FROM_DRIVER 0x2
+
+#define LINK_SYNC_UP_SUBTYPE 0x0001
+#define LINK_SYNC_DOWN_SUBTYPE 0x0001
+
+
+
+#define CONT_MODE 1
+#define SINGLE_DESCRIPTOR 1
+
+
+#define DESCRIPTOR_LENGTH 0x30
+#define FIRMWARE_DESCS_ADDRESS 0x1F100000
+
+
+#define CLOCK_RESET_CNTRL_REG_1 0x0F00000C
+#define CLOCK_RESET_CNTRL_REG_2 0x0F000840
+
+
+
+#define TX_DESCRIPTOR_HEAD_REGISTER 0x0F010034
+#define RX_DESCRIPTOR_HEAD_REGISTER 0x0F010094
+
+#define STATISTICS_BEGIN_ADDR 0xbf60f02c
+
+#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10)
+
+#define WIMAX_MAX_MTU MTU_SIZE + ETH_HLEN
+#define AUTO_LINKUP_ENABLE 0x2
+#define AUTO_SYNC_DISABLE 0x1
+#define AUTO_FIRM_DOWNLOAD 0x1
+#define SETTLE_DOWN_TIME 50
+
+#define HOST_BUS_SUSPEND_BIT 16
+
+#define IDLE_MESSAGE 0x81
+
+#define MIPS_CLOCK_133MHz 1
+
+#define TARGET_CAN_GO_TO_IDLE_MODE 2
+#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3
+#define IDLE_MODE_PAYLOAD_LENGTH 8
+
+#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer))
+#define IPV4 4
+#define IP_VERSION(byte) (((byte&0xF0)>>4))
+
+#define SET_MAC_ADDRESS 193
+#define SET_MAC_ADDRESS_RESPONSE 236
+
+#define IDLE_MODE_WAKEUP_PATTERN 0xd0ea1d1e
+#define IDLE_MODE_WAKEUP_NOTIFIER_ADDRESS 0x1FC02FA8
+#define IDLE_MODE_MAX_RETRY_COUNT 1000
+
+#ifdef REL_4_1
+#define CONFIG_BEGIN_ADDR 0xBF60B004
+#else
+#define CONFIG_BEGIN_ADDR 0xBF60B000
+#endif
+
+#define FIRMWARE_BEGIN_ADDR 0xBFC00000
+
+#define INVALID_QUEUE_INDEX (USHORT)-1
+
+#define INVALID_PID (pid_t)-1
+#define DDR_80_MHZ 0
+#define DDR_100_MHZ 1
+#define DDR_120_MHZ 2 // Additional Frequency for T3LP
+#define DDR_133_MHZ 3
+#define DDR_140_MHZ 4 // Not Used (Reserved for future)
+#define DDR_160_MHZ 5 // Additional Frequency for T3LP
+#define DDR_180_MHZ 6 // Not Used (Reserved for future)
+#define DDR_200_MHZ 7 // Not Used (Reserved for future)
+
+#define MIPS_200_MHZ 0
+#define MIPS_160_MHZ 1
+
+#define PLL_800_MHZ 0
+#define PLL_266_MHZ 1
+
+#define DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING 0
+#define DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING 1
+#define DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN 2
+#define DEVICE_POWERSAVE_MODE_AS_RESERVED 3
+#define DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE 4
+
+
+#define EEPROM_REJECT_REG_1 0x0f003018
+#define EEPROM_REJECT_REG_2 0x0f00301c
+#define EEPROM_REJECT_REG_3 0x0f003008
+#define EEPROM_REJECT_REG_4 0x0f003020
+#define EEPROM_REJECT_MASK 0x0fffffff
+#define VSG_MODE 0x3
+
+/* Idle Mode Related Registers */
+#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
+#ifdef BCM_SHM_INTERFACE
+#define SW_ABORT_IDLEMODE_LOC 0xbfc02f9c
+#define CPE_VIRTUAL_MAILBOX_REG 0xBFC02E58
+#else
+#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
+#endif
+
+#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
+#define DEVICE_INT_OUT_EP_REG0 0x0F011870
+#define DEVICE_INT_OUT_EP_REG1 0x0F011874
+
+#define BIN_FILE "/lib/firmware/macxvi200.bin"
+#define CFG_FILE "/lib/firmware/macxvi.cfg"
+#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128
+#define MIN_VAL(x,y) ((x)<(y)?(x):(y))
+#define MAC_ADDRESS_SIZE 6
+#define EEPROM_COMMAND_Q_REG 0x0F003018
+#define EEPROM_READ_DATA_Q_REG 0x0F003020
+#define CHIP_ID_REG 0x0F000000
+#define GPIO_MODE_REG 0x0F000034
+#define GPIO_OUTPUT_REG 0x0F00003C
+#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50
+
+#define T3 0xbece0300
+#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400
+
+#define RWM_READ 0
+#define RWM_WRITE 1
+
+#define T3LPB 0xbece3300
+#define BCS220_2 0xbece3311
+#define BCS220_2BC 0xBECE3310
+#define BCS250_BC 0xbece3301
+#define BCS220_3 0xbece3321
+
+
+#define HPM_CONFIG_LDO145 0x0F000D54
+#define HPM_CONFIG_MSW 0x0F000D58
+
+#define T3B 0xbece0310
+typedef enum eNVM_TYPE
+{
+ NVM_AUTODETECT = 0,
+ NVM_EEPROM,
+ NVM_FLASH,
+ NVM_UNKNOWN
+}NVM_TYPE;
+
+typedef enum ePMU_MODES
+{
+ HYBRID_MODE_7C = 0,
+ INTERNAL_MODE_6 = 1,
+ HYBRID_MODE_6 = 2
+}PMU_MODE;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+#define MAX_RDM_WRM_RETIRES 16
+#else
+#define MAX_RDM_WRM_RETIRES 1
+#endif
+
+
+enum eAbortPattern {
+ ABORT_SHUTDOWN_MODE = 1,
+ ABORT_IDLE_REG = 1,
+ ABORT_IDLE_MODE = 2,
+ ABORT_IDLE_SYNCDOWN = 3
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+ #define GET_BCM_ADAPTER(net_dev) ({\
+ PMINI_ADAPTER __Adapter = NULL; \
+ if (net_dev) { \
+ __Adapter = (PMINI_ADAPTER)(net_dev->priv); \
+ } \
+ else { \
+ __Adapter = NULL; \
+ }__Adapter;} )
+#else
+ #define GET_BCM_ADAPTER(net_dev) ({\
+ PMINI_ADAPTER __Adapter = NULL; \
+ if (net_dev) { \
+ __Adapter = (PMINI_ADAPTER)(*((UINT *)netdev_priv(net_dev))); \
+ } \
+ else { \
+ __Adapter = NULL; \
+ }__Adapter;})
+
+
+#endif
+
+/* Offsets used by driver in skb cb variable */
+#define SKB_CB_CLASSIFICATION_OFFSET 0
+#define SKB_CB_LATENCY_OFFSET 1
+#define SKB_CB_TCPACK_OFFSET 2
+
+#endif //__MACROS_H__
diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile
new file mode 100644
index 000000000000..3fdec2ea0c49
--- /dev/null
+++ b/drivers/staging/bcm/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for Beceem USB Wimax card
+#
+
+obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o
+
+bcm_wimax-objs := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \
+ InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \
+ Arp.o CmHost.o Debug.o IPv6Protocol.o Qos.o Transmit.o\
+ Bcmnet.o DDRInit.o HandleControlPacket.o\
+ LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\
+ Osal_Misc.o led_control.o nvm.o vendorspecificextn.o
diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c
new file mode 100644
index 000000000000..5ed58a863ebd
--- /dev/null
+++ b/drivers/staging/bcm/Misc.c
@@ -0,0 +1,2239 @@
+#include "headers.h"
+
+static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter)
+{
+
+ UINT uiLoopIndex;
+
+ for(uiLoopIndex=0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++)
+ {
+ Adapter->PackInfo[uiLoopIndex].uiThreshold=TX_PACKET_THRESHOLD;
+ Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate=MAX_ALLOWED_RATE;
+ Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize=20*1024*1024;
+ }
+
+ Adapter->BEBucketSize=BE_BUCKET_SIZE;
+ Adapter->rtPSBucketSize=rtPS_BUCKET_SIZE;
+ Adapter->LinkStatus=SYNC_UP_REQUEST;
+ Adapter->TransferMode=IP_PACKET_ONLY_MODE;
+ Adapter->usBestEffortQueueIndex=-1;
+ return;
+}
+
+
+INT
+InitAdapter(PMINI_ADAPTER psAdapter)
+{
+ int i = 0;
+ INT Status = STATUS_SUCCESS ;
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = 0x%x",(unsigned int) psAdapter);
+
+ if(psAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL");
+ return -EINVAL;
+ }
+
+ sema_init(&psAdapter->NVMRdmWrmLock,1);
+// psAdapter->ulFlashCalStart = FLASH_AUTO_INIT_BASE_ADDR;
+
+ sema_init(&psAdapter->rdmwrmsync, 1);
+ spin_lock_init(&psAdapter->control_queue_lock);
+ spin_lock_init(&psAdapter->txtransmitlock);
+ sema_init(&psAdapter->RxAppControlQueuelock, 1);
+// sema_init(&psAdapter->data_packet_queue_lock, 1);
+ sema_init(&psAdapter->fw_download_sema, 1);
+ sema_init(&psAdapter->LowPowerModeSync,1);
+
+ // spin_lock_init(&psAdapter->sleeper_lock);
+
+ for(i=0;i<NO_OF_QUEUES; i++)
+ spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock);
+ i=0;
+
+ init_waitqueue_head(&psAdapter->process_rx_cntrlpkt);
+ init_waitqueue_head(&psAdapter->tx_packet_wait_queue);
+ init_waitqueue_head(&psAdapter->process_read_wait_queue);
+ init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue);
+ init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue);
+ psAdapter->waiting_to_fw_download_done = TRUE;
+ //init_waitqueue_head(&psAdapter->device_wake_queue);
+ psAdapter->fw_download_done=FALSE;
+
+ psAdapter->pvOsDepData = (PLINUX_DEP_DATA) kmalloc(sizeof(LINUX_DEP_DATA),
+ GFP_KERNEL);
+
+ if(psAdapter->pvOsDepData == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Linux Specific Data allocation failed");
+ return -ENOMEM;
+ }
+ memset(psAdapter->pvOsDepData, 0, sizeof(LINUX_DEP_DATA));
+
+ default_wimax_protocol_initialize(psAdapter);
+ for (i=0;i<MAX_CNTRL_PKTS;i++)
+ {
+ psAdapter->txctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE,
+ GFP_KERNEL);
+ if(!psAdapter->txctlpacket[i])
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
+ return -ENOMEM;
+ }
+ }
+ if(AllocAdapterDsxBuffer(psAdapter))
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers");
+ return -EINVAL;
+ }
+
+ //Initialize PHS interface
+ if(phs_init(&psAdapter->stBCMPhsContext,psAdapter)!=0)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __FUNCTION__, __LINE__);
+ return -ENOMEM;
+ }
+
+ Status = BcmAllocFlashCSStructure(psAdapter);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Memory Allocation for Flash structure failed");
+ return Status ;
+ }
+
+ Status = vendorextnInit(psAdapter);
+
+ if(STATUS_SUCCESS != Status)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Vendor Init Failed");
+ return Status ;
+ }
+
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised");
+
+
+ return STATUS_SUCCESS;
+}
+
+VOID AdapterFree(PMINI_ADAPTER Adapter)
+{
+ INT count = 0;
+
+ beceem_protocol_reset(Adapter);
+
+ vendorextnExit(Adapter);
+
+ if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
+ kthread_stop (Adapter->control_packet_handler);
+ if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
+ kthread_stop (Adapter->transmit_packet_thread);
+ wake_up(&Adapter->process_read_wait_queue);
+ if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
+ kthread_stop (Adapter->LEDInfo.led_cntrl_threadid);
+ bcm_unregister_networkdev(Adapter);
+ while(atomic_read(&Adapter->ApplicationRunning))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning));
+ msleep(100);
+ }
+ unregister_control_device_interface(Adapter);
+ if(Adapter->dev && !IS_ERR(Adapter->dev))
+ free_netdev(Adapter->dev);
+ if(Adapter->pstargetparams != NULL)
+ {
+ bcm_kfree(Adapter->pstargetparams);
+ }
+ for (count =0;count < MAX_CNTRL_PKTS;count++)
+ {
+ if(Adapter->txctlpacket[count])
+ bcm_kfree(Adapter->txctlpacket[count]);
+ }
+ FreeAdapterDsxBuffer(Adapter);
+ if(Adapter->pvOsDepData)
+ bcm_kfree (Adapter->pvOsDepData);
+ if(Adapter->pvInterfaceAdapter)
+ bcm_kfree(Adapter->pvInterfaceAdapter);
+
+ //Free the PHS Interface
+ PhsCleanup(&Adapter->stBCMPhsContext);
+
+#ifndef BCM_SHM_INTERFACE
+ BcmDeAllocFlashCSStructure(Adapter);
+#endif
+
+ bcm_kfree (Adapter);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n");
+}
+
+
+int create_worker_threads(PMINI_ADAPTER psAdapter)
+{
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads...");
+ // Rx Control Packets Processing
+ psAdapter->control_packet_handler = kthread_run((int (*)(void *))
+ control_packet_handler, psAdapter, "CtrlPktHdlr");
+ if(IS_ERR(psAdapter->control_packet_handler))
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n");
+ return PTR_ERR(psAdapter->control_packet_handler);
+ }
+ // Tx Thread
+ psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
+ tx_pkt_handler, psAdapter, "TxPktThread");
+ if(IS_ERR (psAdapter->transmit_packet_thread))
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success");
+ kthread_stop(psAdapter->control_packet_handler);
+ return PTR_ERR(psAdapter->transmit_packet_thread);
+ }
+ return 0;
+}
+
+
+static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
+{
+ struct file *flp=NULL;
+ mm_segment_t oldfs;
+ oldfs=get_fs();
+ set_fs(get_ds());
+ flp=filp_open(path, O_RDONLY, S_IRWXU);
+ set_fs(oldfs);
+ if(IS_ERR(flp))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err %lx",
+ path, PTR_ERR(flp));
+ flp = NULL;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!",
+ path);
+ }
+ if(Adapter->device_removed)
+ {
+ flp = NULL;
+ }
+
+ return flp;
+}
+
+
+int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
+ char *path, /**< path to image file */
+ unsigned int loc /**< Download Address on the chip*/
+ )
+{
+ int errorno=0;
+ struct file *flp=NULL;
+ mm_segment_t oldfs;
+ struct timeval tv={0};
+
+ flp=open_firmware_file(Adapter, path);
+ if(!flp)
+ {
+ errorno = -ENOENT;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path);
+ goto exit_download;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path,(unsigned long)flp->f_dentry->d_inode->i_size, loc);
+ do_gettimeofday(&tv);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) +
+ (tv.tv_usec/1000)));
+ if(Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error\
+ %x!!!", -EIO);
+ errorno=-EIO;
+ goto exit_download;
+ }
+ oldfs=get_fs();set_fs(get_ds());
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ vfs_llseek(flp, 0, 0);
+#endif
+ set_fs(oldfs);
+ if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter,
+ flp, loc))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!");
+ errorno=-EIO;
+ goto exit_download;
+ }
+
+exit_download:
+ oldfs=get_fs();set_fs(get_ds());
+ if(flp && !(IS_ERR(flp)))
+ filp_close(flp, current->files);
+ set_fs(oldfs);
+ do_gettimeofday(&tv);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "file download done at %lx", ((tv.tv_sec * 1000) +
+ (tv.tv_usec/1000)));
+ return errorno;
+}
+
+
+void bcm_kfree_skb(struct sk_buff *skb)
+{
+ if(skb)
+ {
+ kfree_skb(skb);
+ }
+ skb = NULL ;
+}
+
+VOID bcm_kfree(VOID *ptr)
+{
+ if(ptr)
+ {
+ kfree(ptr);
+ }
+ ptr = NULL ;
+}
+
+/**
+@ingroup ctrl_pkt_functions
+This function copies the contents of given buffer
+to the control packet and queues it for transmission.
+@note Do not acquire the spinock, as it it already acquired.
+@return SUCCESS/FAILURE.
+*/
+INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
+ PVOID ioBuffer/**<Control Packet Buffer*/
+ )
+{
+ PLEADER pLeader=NULL;
+ INT Status=0;
+ unsigned char *ctrl_buff=NULL;
+ UINT pktlen=0;
+ PLINK_REQUEST pLinkReq = NULL;
+ PUCHAR pucAddIndication = NULL;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>");
+ if(!ioBuffer)
+ {
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Got Null Buffer\n");
+ return -EINVAL;
+ }
+
+ pLinkReq = (PLINK_REQUEST)ioBuffer;
+ pLeader=(PLEADER)ioBuffer; //ioBuffer Contains sw_Status and Payload
+
+ if(Adapter->bShutStatus == TRUE &&
+ pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD &&
+ pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)
+ {
+ //Got sync down in SHUTDOWN..we could not process this.
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n");
+ return STATUS_FAILURE;
+ }
+
+ if((pLeader->Status == LINK_UP_CONTROL_REQ) &&
+ ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD &&
+ (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) ||//Sync Up Command
+ pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) //Net Entry Command
+ {
+ if(Adapter->LinkStatus > PHY_SYNC_ACHIVED)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"LinkStatus is Greater than PHY_SYN_ACHIEVED");
+ return STATUS_FAILURE;
+ }
+ if(TRUE == Adapter->bShutStatus)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n");
+ if(Adapter->bTriedToWakeUpFromlowPowerMode == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Waking up for the First Time..\n");
+ Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; // change it to 1 for current support.
+ Adapter->bWakeUpDevice = TRUE;
+ wake_up(&Adapter->process_rx_cntrlpkt);
+
+ Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
+ !Adapter->bShutStatus, (5 * HZ));
+
+ if(Status == -ERESTARTSYS)
+ return Status;
+
+ if(Adapter->bShutStatus)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n");
+ return STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Wakeup has been tried already...\n");
+ }
+ }
+
+ }
+ if(TRUE == Adapter->IdleMode)
+ {
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence \n");
+ if(pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 ||
+ pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ )
+
+ {
+ if((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0]==LINK_DOWN_REQ_PAYLOAD))
+ {
+ if((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Link Down Sent in Idle Mode\n");
+ Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN;//LINK DOWN sent in Idle Mode
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n");
+ Adapter->usIdleModePattern = ABORT_IDLE_REG;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n");
+ Adapter->usIdleModePattern = ABORT_IDLE_MODE;
+ }
+
+ /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
+ the wake up from idlemode is from host*/
+ //Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE;
+#if 0
+ if(STATUS_SUCCESS != InterfaceIdleModeWakeup(Adapter))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Wake up Failed\n");
+ return STATUS_FAILURE;
+ }
+#endif
+ Adapter->bWakeUpDevice = TRUE;
+ wake_up(&Adapter->process_rx_cntrlpkt);
+
+
+
+ if(LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0])
+ {
+ // We should not send DREG message down while in idlemode.
+ return STATUS_SUCCESS;
+ }
+
+ Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
+ !Adapter->IdleMode, (5 * HZ));
+
+ if(Status == -ERESTARTSYS)
+ return Status;
+
+ if(Adapter->IdleMode)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n");
+ return STATUS_FAILURE;
+ }
+ }
+ else
+ return STATUS_SUCCESS;
+ }
+ //The Driver has to send control messages with a particular VCID
+ pLeader->Vcid = VCID_CONTROL_PACKET;//VCID for control packet.
+
+ /* Allocate skb for Control Packet */
+ pktlen = pLeader->PLength;
+ ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS];
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x",
+ atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen);
+ if(ctrl_buff)
+ {
+ if(pLeader)
+ {
+ if((pLeader->Status == 0x80) ||
+ (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ))
+ {
+ /*
+ //Restructure the DSX message to handle Multiple classifier Support
+ // Write the Service Flow param Structures directly to the target
+ //and embed the pointers in the DSX messages sent to target.
+ */
+ //Lets store the current length of the control packet we are transmitting
+ pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE;
+ pktlen = pLeader->PLength;
+ Status = StoreCmControlResponseMessage(Adapter,pucAddIndication, &pktlen);
+ if(Status != 1)
+ {
+ ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly ");
+ return STATUS_FAILURE;
+ }
+ /*
+ //update the leader to use the new length
+ //The length of the control packet is length of message being sent + Leader length
+ */
+ pLeader->PLength = pktlen;
+ }
+ }
+ memset(ctrl_buff, 0, pktlen+LEADER_SIZE);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength);
+ *(PLEADER)ctrl_buff=*pLeader;
+ memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet");
+
+ /*Update the statistics counters */
+ spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
+ Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost+=pLeader->PLength;
+ Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++;
+ atomic_inc(&Adapter->TotalPacketCount);
+ spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock);
+
+ Adapter->PackInfo[HiPriority].bValid = TRUE;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x",
+ Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost,
+ Adapter->PackInfo[HiPriority].bValid);
+ Status=STATUS_SUCCESS;
+ /*Queue the packet for transmission */
+ atomic_inc(&Adapter->index_wr_txcntrlpkt);
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
+ atomic_set(&Adapter->TxPktAvail, 1);
+#ifdef BCM_SHM_INTERFACE
+ virtual_mail_box_interrupt();
+#endif
+ wake_up(&Adapter->tx_packet_wait_queue);
+ }
+ else
+ {
+ Status=-ENOMEM;
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed");
+ }
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<====");
+ return Status;
+}
+
+/*****************************************************************
+* Function - SendStatisticsPointerRequest()
+*
+* Description - This function builds and forwards the Statistics
+* Pointer Request control Packet.
+*
+* Parameters - Adapter : Pointer to Adapter structure.
+* - pstStatisticsPtrRequest : Pointer to link request.
+*
+* Returns - None.
+*****************************************************************/
+VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter,
+ PLINK_REQUEST pstStatisticsPtrRequest)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>");
+ pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS;
+ pstStatisticsPtrRequest->Leader.PLength = sizeof(ULONG);//minimum 4 bytes
+ pstStatisticsPtrRequest->szData[0] = STATISTICS_POINTER_REQ;
+
+ CopyBufferToControlPacket(Adapter,pstStatisticsPtrRequest);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "<=====");
+ return;
+}
+
+
+
+void SendLinkDown(PMINI_ADAPTER Adapter)
+{
+ LINK_REQUEST stLinkDownRequest;
+ memset(&stLinkDownRequest, 0, sizeof(LINK_REQUEST));
+ stLinkDownRequest.Leader.Status=LINK_UP_CONTROL_REQ;
+ stLinkDownRequest.Leader.PLength=sizeof(ULONG);//minimum 4 bytes
+ stLinkDownRequest.szData[0]=LINK_DOWN_REQ_PAYLOAD;
+ Adapter->bLinkDownRequested = TRUE;
+
+ CopyBufferToControlPacket(Adapter,&stLinkDownRequest);
+}
+
+/******************************************************************
+* Function - LinkMessage()
+*
+* Description - This function builds the Sync-up and Link-up request
+* packet messages depending on the device Link status.
+*
+* Parameters - Adapter: Pointer to the Adapter structure.
+*
+* Returns - None.
+*******************************************************************/
+__inline VOID LinkMessage(PMINI_ADAPTER Adapter)
+{
+ PLINK_REQUEST pstLinkRequest=NULL;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
+ if(Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup)
+ {
+ pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC);
+ if(!pstLinkRequest)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
+ return;
+ }
+ memset(pstLinkRequest,0,sizeof(LINK_REQUEST));
+ //sync up request...
+ Adapter->LinkStatus = WAIT_FOR_SYNC;// current link status
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp...");
+ pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD;
+ pstLinkRequest->szData[1]=LINK_SYNC_UP_SUBTYPE;
+ pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ;
+ pstLinkRequest->Leader.PLength=sizeof(ULONG);
+ Adapter->bSyncUpRequestSent = TRUE;
+ }
+ else if(Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp)
+ {
+ pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC);
+ if(!pstLinkRequest)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!");
+ return;
+ }
+ memset(pstLinkRequest,0,sizeof(LINK_REQUEST));
+ //LINK_UP_REQUEST
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp...");
+ pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD;
+ pstLinkRequest->szData[1]=LINK_NET_ENTRY;
+ pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ;
+ pstLinkRequest->Leader.PLength=sizeof(ULONG);
+ }
+ if(pstLinkRequest)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
+ CopyBufferToControlPacket(Adapter, pstLinkRequest);
+ bcm_kfree(pstLinkRequest);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
+ return;
+}
+
+
+/**********************************************************************
+* Function - StatisticsResponse()
+*
+* Description - This function handles the Statistics response packet.
+*
+* Parameters - Adapter : Pointer to the Adapter structure.
+* - pvBuffer: Starting address of Statistic response data.
+*
+* Returns - None.
+************************************************************************/
+VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
+ Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__);
+ return;
+}
+
+
+/**********************************************************************
+* Function - LinkControlResponseMessage()
+*
+* Description - This function handles the Link response packets.
+*
+* Parameters - Adapter : Pointer to the Adapter structure.
+* - pucBuffer: Starting address of Link response data.
+*
+* Returns - None.
+***********************************************************************/
+VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>");
+
+ if(*pucBuffer==LINK_UP_ACK)
+ {
+ switch(*(pucBuffer+1))
+ {
+ case PHY_SYNC_ACHIVED: //SYNCed UP
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED");
+
+ if(Adapter->LinkStatus == LINKUP_DONE)
+ {
+ beceem_protocol_reset(Adapter);
+ }
+
+ Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ;
+ Adapter->LinkStatus=PHY_SYNC_ACHIVED;
+
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = NO_NETWORK_ENTRY;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+
+ LinkMessage(Adapter);
+ break;
+
+ case LINKUP_DONE:
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE");
+ Adapter->LinkStatus=LINKUP_DONE;
+ Adapter->bPHSEnabled = *(pucBuffer+3);
+ Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Recieved In LinkUp Ack : %x \n",Adapter->bPHSEnabled);
+ if((FALSE == Adapter->bShutStatus)&&
+ (FALSE == Adapter->IdleMode))
+ {
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = NORMAL_OPERATION;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+ }
+ LinkMessage(Adapter);
+ break;
+ case WAIT_FOR_SYNC:
+
+ /*
+ * Driver to ignore the DREG_RECEIVED
+ * WiMAX Application should handle this Message
+ */
+ //Adapter->liTimeSinceLastNetEntry = 0;
+ Adapter->LinkUpStatus = 0;
+ Adapter->LinkStatus = 0;
+ Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ;
+ Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
+ Adapter->IdleMode = FALSE;
+ beceem_protocol_reset(Adapter);
+
+ break;
+ case LINK_SHUTDOWN_REQ_FROM_FIRMWARE:
+ case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW:
+ {
+ HandleShutDownModeRequest(Adapter, pucBuffer);
+ }
+ break;
+ default:
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x",*(pucBuffer+1));
+ break;
+ }
+ }
+ else if(SET_MAC_ADDRESS_RESPONSE==*pucBuffer)
+ {
+ PUCHAR puMacAddr = (pucBuffer + 1);
+ Adapter->LinkStatus=SYNC_UP_REQUEST;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP");
+ LinkMessage(Adapter);
+ memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====",__FUNCTION__);
+ return;
+}
+
+void SendIdleModeResponse(PMINI_ADAPTER Adapter)
+{
+ INT status = 0, NVMAccess = 0,lowPwrAbortMsg = 0;
+ struct timeval tv;
+ CONTROL_MESSAGE stIdleResponse = {{0}};
+ memset(&tv, 0, sizeof(tv));
+ stIdleResponse.Leader.Status = IDLE_MESSAGE;
+ stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH;
+ stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL," ============>");
+
+ /*********************************
+ **down_trylock -
+ ** if [ semaphore is available ]
+ ** acquire semaphone and return value 0 ;
+ ** else
+ ** return non-zero value ;
+ **
+ ***********************************/
+
+ NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+
+ lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync);
+
+
+ if((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) &&
+ (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) )
+ {
+ if(!NVMAccess)
+ up(&Adapter->NVMRdmWrmLock);
+
+ if(!lowPwrAbortMsg)
+ up(&Adapter->LowPowerModeSync);
+
+ stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on.
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!");
+ Adapter->bPreparingForLowPowerMode = FALSE;
+ }
+ else
+ {
+ stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; //2;//Idle ACK
+ Adapter->StatisticsPointer = 0;
+
+ /* Wait for the LED to TURN OFF before sending ACK response */
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ INT iRetVal = 0;
+
+ /* Wake the LED Thread with IDLEMODE_ENTER State */
+ Adapter->DriverState = LOWPOWER_MODE_ENTER;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+
+ /* Wait for 1 SEC for LED to OFF */
+ iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, \
+ Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));
+
+
+ /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
+ if(iRetVal <= 0)
+ {
+ stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on.
+ Adapter->DriverState = NORMAL_OPERATION;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!");
+ }
+ }
+ if(stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"ACKING IDLE MODE !!!!!!!!!");
+ down(&Adapter->rdmwrmsync);
+ Adapter->bPreparingForLowPowerMode = TRUE;
+ up(&Adapter->rdmwrmsync);
+#ifndef BCM_SHM_INTERFACE
+ //Killing all URBS.
+ if(Adapter->bDoSuspend == TRUE)
+ Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+
+#endif
+ }
+ else
+ {
+ Adapter->bPreparingForLowPowerMode = FALSE;
+ }
+
+ if(!NVMAccess)
+ up(&Adapter->NVMRdmWrmLock);
+
+ if(!lowPwrAbortMsg)
+ up(&Adapter->LowPowerModeSync);
+
+ }
+ status = CopyBufferToControlPacket(Adapter,&stIdleResponse);
+ if((status != STATUS_SUCCESS))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n");
+ Adapter->bPreparingForLowPowerMode = FALSE;
+#ifndef BCM_SHM_INTERFACE
+ StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+#endif
+ }
+ do_gettimeofday(&tv);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
+
+}
+
+/******************************************************************
+* Function - DumpPackInfo()
+*
+* Description - This function dumps the all Queue(PackInfo[]) details.
+*
+* Parameters - Adapter: Pointer to the Adapter structure.
+*
+* Returns - None.
+*******************************************************************/
+VOID DumpPackInfo(PMINI_ADAPTER Adapter)
+{
+
+ UINT uiLoopIndex = 0;
+ UINT uiIndex = 0;
+ UINT uiClsfrIndex = 0;
+ S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
+
+ for(uiLoopIndex=0;uiLoopIndex<NO_OF_QUEUES;uiLoopIndex++)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"*********** Showing Details Of Queue %d***** ******",uiLoopIndex);
+ if(FALSE == Adapter->PackInfo[uiLoopIndex].bValid)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid is FALSE for %X index\n",uiLoopIndex);
+ continue;
+ }
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," Dumping SF Rule Entry For SFID %lX \n",Adapter->PackInfo[uiLoopIndex].ulSFID);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," ucDirection %X \n",Adapter->PackInfo[uiLoopIndex].ucDirection);
+ if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv6 Service Flow \n");
+ }
+ else
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv4 Service Flow \n");
+ }
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," SF Traffic Priority %X \n",Adapter->PackInfo[uiLoopIndex].u8TrafficPriority);
+
+ for(uiClsfrIndex=0;uiClsfrIndex<MAX_CLASSIFIERS;uiClsfrIndex++)
+ {
+ pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex];
+ if(!pstClassifierEntry->bUsed)
+ continue;
+
+ if(pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID)
+ continue;
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n",uiClsfrIndex,pstClassifierEntry->uiClassifierRuleIndex);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n",uiClsfrIndex,pstClassifierEntry->usVCID_Value);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n",uiClsfrIndex,pstClassifierEntry->bProtocolValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n",uiClsfrIndex,pstClassifierEntry->bTOSValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bDestIpValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bSrcIpValid);
+
+
+ for(uiIndex=0;uiIndex<MAX_PORT_RANGE;uiIndex++)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeLo:%X\n",pstClassifierEntry->usSrcPortRangeLo[uiIndex]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeHi:%X\n",pstClassifierEntry->usSrcPortRangeHi[uiIndex]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeLo:%X\n",pstClassifierEntry->usDestPortRangeLo[uiIndex]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeHi:%X\n",pstClassifierEntry->usDestPortRangeHi[uiIndex]);
+ }
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," \tucIPSourceAddressLength : 0x%x\n",pstClassifierEntry->ucIPSourceAddressLength);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucIPDestinationAddressLength : 0x%x\n",pstClassifierEntry->ucIPDestinationAddressLength);
+ for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPSourceAddressLength;uiIndex++)
+ {
+ if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpAddr :\n");
+ DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpMask :\n");
+ DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpAddr:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpMask:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]);
+ }
+ }
+ for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPDestinationAddressLength;uiIndex++)
+ {
+ if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpAddr :\n");
+ DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpMask :\n");
+ DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask);
+
+ }
+ else
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpAddr:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpMask:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]);
+ }
+ }
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucProtocol:0x%X\n",pstClassifierEntry->ucProtocol[0]);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tu8ClassifierRulePriority:%X\n",pstClassifierEntry->u8ClassifierRulePriority);
+
+
+ }
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ulSFID:%lX\n",Adapter->PackInfo[uiLoopIndex].ulSFID);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"usVCID_Value:%X\n",Adapter->PackInfo[uiLoopIndex].usVCID_Value);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"PhsEnabled: 0x%X\n",Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThreshold:%X\n",Adapter->PackInfo[uiLoopIndex].uiThreshold);
+
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid:%X\n",Adapter->PackInfo[uiLoopIndex].bValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bActive:%X\n",Adapter->PackInfo[uiLoopIndex].bActive);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"u8QueueType:%X\n",Adapter->PackInfo[uiLoopIndex].u8QueueType);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxBucketSize:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPerSFTxResourceCount:%X\n",atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount));
+ //DumpDebug(DUMP_INFO,(" bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport));
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentBytesOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentPacketsOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentBytes);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentPackets);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentDrainRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThisPeriodSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liDrainCalculated:%llX\n",Adapter->PackInfo[uiLoopIndex].liDrainCalculated);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentTokenCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liLastUpdateTokenAt:%llX\n",Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxAllowedRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPendedLast:%X\n",Adapter->PackInfo[uiLoopIndex].uiPendedLast);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"NumOfPacketsSent:%X\n",Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet);
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n",Adapter->PackInfo[uiLoopIndex].uiMaxLatency);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n",Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]);
+// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled);
+// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes);
+// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes);
+// DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount));
+ }
+
+ for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++)
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aRxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aRxPktSizeHist[uiLoopIndex]);
+
+ for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++)
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aTxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aTxPktSizeHist[uiLoopIndex]);
+
+
+
+ return;
+
+
+}
+
+
+__inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
+{
+ int retval = STATUS_SUCCESS;
+
+#ifndef BCM_SHM_INTERFACE
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
+ unsigned int value = 0, uiResetValue = 0;
+
+ psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)) ;
+
+ ps_adapter->bDDRInitDone = FALSE;
+
+ if(ps_adapter->chip_id >= T3LPB)
+ {
+ //SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before
+ rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value));
+ rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value));
+
+ //making bit[6...5] same as was before f/w download. this setting force the h/w to
+ //re-populated the SP RAM area with the string descriptor .
+ value = value | (ps_adapter->syscfgBefFwDld & 0x00000060) ;
+ wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
+ }
+
+#ifndef BCM_SHM_INTERFACE
+ //killing all submitted URBs.
+ psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
+ Bcm_kill_all_URBs(psIntfAdapter);
+#endif
+ /* Reset the UMA-B Device */
+ if(ps_adapter->chip_id >= T3LPB)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B \n");
+ retval = usb_reset_device(psIntfAdapter->udev);
+
+ psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
+
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval);
+ goto err_exit;
+ }
+ if (ps_adapter->chip_id == BCS220_2 ||
+ ps_adapter->chip_id == BCS220_2BC ||
+ ps_adapter->chip_id == BCS250_BC ||
+ ps_adapter->chip_id == BCS220_3)
+ {
+ retval = rdmalt(ps_adapter,HPM_CONFIG_LDO145, &value, sizeof(value));
+ if( retval < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval);
+ goto err_exit;
+ }
+ //setting 0th bit
+ value |= (1<<0);
+ retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
+ if( retval < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
+ goto err_exit;
+ }
+ }
+
+ }
+ else
+ {
+ retval = rdmalt(ps_adapter,0x0f007018, &value, sizeof(value));
+ if( retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval);
+ goto err_exit;
+ }
+ value&=(~(1<<16));
+ retval= wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)) ;
+ if( retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
+ goto err_exit;
+ }
+
+ // Toggling the GPIO 8, 9
+ value = 0;
+ retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value));
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
+ goto err_exit;
+ }
+ value = 0x300;
+ retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)) ;
+ if(retval < 0) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval);
+ goto err_exit;
+ }
+ mdelay(50);
+ }
+
+ //ps_adapter->downloadDDR = false;
+
+ if(ps_adapter->bFlashBoot)
+ {
+ //In flash boot mode MIPS state register has reverse polarity.
+ // So just or with setting bit 30.
+ //Make the MIPS in Reset state.
+ rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));
+
+ uiResetValue |=(1<<30);
+ wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue));
+ }
+
+ if(ps_adapter->chip_id >= T3LPB)
+ {
+ uiResetValue = 0;
+ //
+ // WA for SYSConfig Issue.
+ // Read SYSCFG Twice to make it writable.
+ //
+ rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));
+ if(uiResetValue & (1<<4))
+ {
+ uiResetValue = 0;
+ rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));//2nd read to make it writable.
+ uiResetValue &= (~(1<<4));
+ wrmalt(ps_adapter,SYS_CFG, &uiResetValue, sizeof(uiResetValue));
+ }
+
+ }
+ uiResetValue = 0;
+ wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue));
+
+err_exit :
+ psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
+#endif
+ return retval;
+}
+
+__inline int run_card_proc(PMINI_ADAPTER ps_adapter )
+{
+ unsigned int value=0;
+ {
+
+ if(rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__);
+ return STATUS_FAILURE;
+ }
+
+ if(ps_adapter->bFlashBoot)
+ {
+
+ value&=(~(1<<30));
+ }
+ else
+ {
+ value |=(1<<30);
+ }
+
+ if(wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__);
+ return STATUS_FAILURE;
+ }
+ }
+ return STATUS_SUCCESS;
+}
+
+int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
+{
+
+ UINT status = STATUS_SUCCESS;
+ UINT value = 0;
+#ifdef BCM_SHM_INTERFACE
+ unsigned char *pConfigFileAddr = (unsigned char *)CPE_MACXVI_CFG_ADDR;
+#endif
+ /*
+ * Create the threads first and then download the
+ * Firm/DDR Settings..
+ */
+
+ if((status = create_worker_threads(ps_adapter))<0)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread");
+ return status;
+ }
+ /*
+ * For Downloading the Firm, parse the cfg file first.
+ */
+ status = bcm_parse_target_params (ps_adapter);
+ if(status){
+ return status;
+ }
+
+#ifndef BCM_SHM_INTERFACE
+ if(ps_adapter->chip_id >= T3LPB)
+ {
+ rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
+ ps_adapter->syscfgBefFwDld = value ;
+ if((value & 0x60)== 0)
+ {
+ ps_adapter->bFlashBoot = TRUE;
+ }
+ }
+
+ reset_card_proc(ps_adapter);
+
+ //Initializing the NVM.
+ BcmInitNVM(ps_adapter);
+ status = ddr_init(ps_adapter);
+ if(status)
+ {
+ BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "ddr_init Failed\n");
+ return status;
+ }
+
+ /* Download cfg file */
+ status = buffDnldVerify(ps_adapter,
+ (PUCHAR)ps_adapter->pstargetparams,
+ sizeof(STARGETPARAMS),
+ CONFIG_BEGIN_ADDR);
+ if(status)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
+ goto OUT;
+ }
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded");
+
+ if(register_networkdev(ps_adapter))
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
+ return -EIO;
+ }
+
+ if(FALSE == ps_adapter->AutoFirmDld)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n");
+ //If Auto f/w download is disable, register the control interface,
+ //register the control interface after the mailbox.
+ if(register_control_device_interface(ps_adapter) < 0)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
+ return -EIO;
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ /*
+ * Do the LED Settings here. It will be used by the Firmware Download
+ * Thread.
+ */
+
+ /*
+ * 1. If the LED Settings fails, do not stop and do the Firmware download.
+ * 2. This init would happend only if the cfg file is present, else
+ * call from the ioctl context.
+ */
+
+ status = InitLedSettings (ps_adapter);
+
+ if(status)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n");
+ return status;
+ }
+ if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ ps_adapter->DriverState = DRIVER_INIT;
+ wake_up(&ps_adapter->LEDInfo.notify_led_event);
+ }
+
+ if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ ps_adapter->DriverState = FW_DOWNLOAD;
+ wake_up(&ps_adapter->LEDInfo.notify_led_event);
+ }
+
+ value = 0;
+ wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
+ wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
+
+ if(ps_adapter->eNVMType == NVM_FLASH)
+ {
+ status = PropagateCalParamsFromFlashToMemory(ps_adapter);
+ if(status)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propogation of Cal param failed .." );
+ goto OUT;
+ }
+ }
+#if 0
+ else if(psAdapter->eNVMType == NVM_EEPROM)
+ {
+ PropagateCalParamsFromEEPROMToMemory();
+ }
+#endif
+
+ /* Download Firmare */
+ if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present... \n");
+ goto OUT;
+ }
+
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded");
+ status = run_card_proc(ps_adapter);
+ if(status)
+ {
+ BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n");
+ goto OUT;
+ }
+
+
+ ps_adapter->fw_download_done = TRUE;
+ mdelay(10);
+
+OUT:
+ if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ ps_adapter->DriverState = FW_DOWNLOAD_DONE;
+ wake_up(&ps_adapter->LEDInfo.notify_led_event);
+ }
+
+#else
+
+ ps_adapter->bDDRInitDone = TRUE;
+ //Initializing the NVM.
+ BcmInitNVM(ps_adapter);
+
+ //Propagating the cal param from Flash to DDR
+ value = 0;
+ wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
+ wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
+
+ if(ps_adapter->eNVMType == NVM_FLASH)
+ {
+ status = PropagateCalParamsFromFlashToMemory(ps_adapter);
+ if(status)
+ {
+ printk("\nPropogation of Cal param from flash to DDR failed ..\n" );
+ }
+ }
+
+ //Copy config file param to DDR.
+ memcpy(pConfigFileAddr,ps_adapter->pstargetparams, sizeof(STARGETPARAMS));
+
+ if(register_networkdev(ps_adapter))
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
+ return -EIO;
+ }
+
+
+ status = InitLedSettings (ps_adapter);
+ if(status)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n");
+ return status;
+ }
+
+
+ if(register_control_device_interface(ps_adapter) < 0)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
+ return -EIO;
+ }
+
+ ps_adapter->fw_download_done = TRUE;
+#endif
+ return status;
+}
+
+
+int bcm_parse_target_params(PMINI_ADAPTER Adapter)
+{
+#ifdef BCM_SHM_INTERFACE
+ extern void read_cfg_file(PMINI_ADAPTER Adapter);
+#endif
+ struct file *flp=NULL;
+ mm_segment_t oldfs={0};
+ char *buff = NULL;
+ int len = 0;
+ loff_t pos = 0;
+
+ buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL);
+ if(!buff)
+ {
+ return -ENOMEM;
+ }
+ if((Adapter->pstargetparams =
+ kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
+ {
+ bcm_kfree(buff);
+ return -ENOMEM;
+ }
+ flp=open_firmware_file(Adapter, CFG_FILE);
+ if(!flp) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE);
+ bcm_kfree(buff);
+ bcm_kfree(Adapter->pstargetparams);
+ Adapter->pstargetparams = NULL;
+ return -ENOENT;
+ }
+ oldfs=get_fs(); set_fs(get_ds());
+ len=vfs_read(flp, buff, BUFFER_1K, &pos);
+ set_fs(oldfs);
+
+ if(len != sizeof(STARGETPARAMS))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
+ bcm_kfree(buff);
+ bcm_kfree(Adapter->pstargetparams);
+ Adapter->pstargetparams = NULL;
+ filp_close(flp, current->files);
+ return -ENOENT;
+ }
+ filp_close(flp, current->files);
+
+ /* Check for autolink in config params */
+ /*
+ * Values in Adapter->pstargetparams are in network byte order
+ */
+ memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
+ bcm_kfree (buff);
+ beceem_parse_target_struct(Adapter);
+#ifdef BCM_SHM_INTERFACE
+ read_cfg_file(Adapter);
+
+#endif
+ return STATUS_SUCCESS;
+}
+
+void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
+{
+ UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;;
+
+ if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Disabled\n");
+ Adapter->AutoSyncup = FALSE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Enabled\n");
+ Adapter->AutoSyncup = TRUE;
+ }
+ if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling autolink up");
+ Adapter->AutoLinkUp = TRUE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling autolink up");
+ Adapter->AutoLinkUp = FALSE;
+ }
+ // Setting the DDR Setting..
+ Adapter->DDRSetting =
+ (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >>8)&0x0F;
+ Adapter->ulPowerSaveMode =
+ (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n",
+ Adapter->ulPowerSaveMode);
+ if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling Auto Firmware Download\n");
+ Adapter->AutoFirmDld = TRUE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling Auto Firmware Download\n");
+ Adapter->AutoFirmDld = FALSE;
+ }
+ uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
+ Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"MIPSConfig : 0x%X\n",Adapter->bMipsConfig);
+ //used for backward compatibility.
+ Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
+
+ Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "PMU MODE: %x", Adapter->PmuMode);
+
+ if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01))
+ {
+ Adapter->bDoSuspend = TRUE;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Making DoSuspend TRUE as per configFile");
+ }
+
+ uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "uiEEPROMFlag : 0x%X\n",uiEEPROMFlag);
+ Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3);
+
+
+ Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
+ //printk(("bStatusWrite : 0x%X\n", Adapter->bStatusWrite));
+
+ Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
+ //printk(("uiSectorSize : 0x%X\n", Adapter->uiSectorSizeInCFG));
+
+ Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;
+ //printk(MP_INIT,("bSectorSizeOverride : 0x%X\n",Adapter->bSectorSizeOverride));
+
+ if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01)
+ Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
+ //autocorrection part
+ if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
+ doPowerAutoCorrection(Adapter);
+
+}
+
+VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
+{
+ UINT reporting_mode = 0;
+
+ reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ;
+ psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
+
+ if(reporting_mode == TRUE)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"can't do suspen/resume as reporting mode is enable");
+ psAdapter->bDoSuspend = FALSE;
+ }
+
+ if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
+ {
+ //If reporting mode is enable, switch PMU to PMC
+ #if 0
+ if(reporting_mode == FALSE)
+ {
+ psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN;
+ psAdapter->bDoSuspend = TRUE;
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMU selected ....");
+
+ }
+ else
+ #endif
+ {
+ psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
+ psAdapter->bDoSuspend =FALSE;
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMC selected..");
+
+ }
+
+ //clearing space bit[15..12]
+ psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12)));
+ //placing the power save mode option
+ psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12));
+
+ }
+ else if (psAdapter->bIsAutoCorrectEnabled == FALSE)
+ {
+
+ // remove the autocorrect disable bit set before dumping.
+ psAdapter->ulPowerSaveMode &= ~(1 << 3);
+ psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15));
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode);
+ }
+}
+unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
+{
+ unsigned char *pucmacaddr = NULL;
+ int status = 0, i=0;
+ unsigned int temp =0;
+
+
+ pucmacaddr = (unsigned char *)kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
+ if(!pucmacaddr)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
+ return NULL;
+ }
+
+ dwAddress |= 0x5b000000;
+ status = wrmalt(Adapter, EEPROM_COMMAND_Q_REG,
+ (PUINT)&dwAddress, sizeof(UINT));
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
+ bcm_kfree(pucmacaddr);
+ pucmacaddr = NULL;
+ goto OUT;
+ }
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+ status = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp,sizeof(temp));
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
+ bcm_kfree(pucmacaddr);
+ pucmacaddr = NULL;
+ goto OUT;
+ }
+ pucmacaddr[i] = temp & 0xff;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"%x \n", pucmacaddr[i]);
+ }
+OUT:
+ return pucmacaddr;
+}
+
+#if 0
+INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter)
+{
+ unsigned char *puMacAddr = NULL;
+ int i =0;
+
+ puMacAddr = ReadMacAddrEEPROM(Adapter,0x200);
+ if(!puMacAddr)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Couldn't retrieve the Mac Address\n");
+ return STATUS_FAILURE;
+ }
+ else
+ {
+ if((puMacAddr[0] == 0x0 && puMacAddr[1] == 0x0 &&
+ puMacAddr[2] == 0x0 && puMacAddr[3] == 0x0 &&
+ puMacAddr[4] == 0x0 && puMacAddr[5] == 0x0) ||
+ (puMacAddr[0] == 0xFF && puMacAddr[1] == 0xFF &&
+ puMacAddr[2] == 0xFF && puMacAddr[3] == 0xFF &&
+ puMacAddr[4] == 0xFF && puMacAddr[5] == 0xFF))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Invalid Mac Address\n");
+ bcm_kfree(puMacAddr);
+ return STATUS_FAILURE;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "The Mac Address received is: \n");
+ memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%02x ", Adapter->dev->dev_addr[i]);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n");
+ bcm_kfree(puMacAddr);
+ }
+ return STATUS_SUCCESS;
+}
+#endif
+
+void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
+{
+ UINT uiIndex = 0;
+
+ if(RWM_WRITE == rwFlag) {
+ for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) {
+ puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]);
+ }
+ } else {
+ for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) {
+ puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]);
+ }
+ }
+}
+
+#define CACHE_ADDRESS_MASK 0x80000000
+#define UNCACHE_ADDRESS_MASK 0xa0000000
+
+int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+{
+ INT uiRetVal =0;
+
+#ifndef BCM_SHM_INTERFACE
+ uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
+ uiAddress, pucBuff, sSize);
+
+ if(uiRetVal < 0)
+ return uiRetVal;
+
+#else
+ int indx;
+ uiRetVal = STATUS_SUCCESS;
+ if(uiAddress & 0x10000000) {
+ // DDR Memory Access
+ uiAddress |= CACHE_ADDRESS_MASK;
+ memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
+ }
+ else {
+ // Register, SPRAM, Flash
+ uiAddress |= UNCACHE_ADDRESS_MASK;
+ if ((uiAddress & FLASH_ADDR_MASK) == (FLASH_CONTIGIOUS_START_ADDR_BCS350 & FLASH_ADDR_MASK))
+ {
+ #if defined(FLASH_DIRECT_ACCESS)
+ memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
+ #else
+ printk("\nInvalid GSPI ACCESS :Addr :%#X", uiAddress);
+ uiRetVal = STATUS_FAILURE;
+ #endif
+ }
+ else if(((unsigned int )uiAddress & 0x3) ||
+ ((unsigned int )pucBuff & 0x3) ||
+ ((unsigned int )sSize & 0x3)) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"rdmalt :unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
+ uiRetVal = STATUS_FAILURE;
+ }
+ else {
+ for (indx=0;indx<sSize;indx+=4){
+ *(PUINT)(pucBuff + indx) = *(PUINT)(uiAddress + indx);
+ }
+ }
+ }
+#endif
+ return uiRetVal;
+}
+int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+{
+ int iRetVal;
+
+#ifndef BCM_SHM_INTERFACE
+ iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
+ uiAddress, pucBuff, sSize);
+
+#else
+ int indx;
+ if(uiAddress & 0x10000000) {
+ // DDR Memory Access
+ uiAddress |= CACHE_ADDRESS_MASK;
+ memcpy((unsigned char *)(uiAddress),pucBuff,sSize);
+ }
+ else {
+ // Register, SPRAM, Flash
+ uiAddress |= UNCACHE_ADDRESS_MASK;
+
+ if(((unsigned int )uiAddress & 0x3) ||
+ ((unsigned int )pucBuff & 0x3) ||
+ ((unsigned int )sSize & 0x3)) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrmalt: unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
+ iRetVal = STATUS_FAILURE;
+ }
+ else {
+ for (indx=0;indx<sSize;indx+=4) {
+ *(PUINT)(uiAddress + indx) = *(PUINT)(pucBuff + indx);
+ }
+ }
+ }
+ iRetVal = STATUS_SUCCESS;
+#endif
+
+ return iRetVal;
+}
+
+int wrmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+{
+ convertEndian(RWM_WRITE, pucBuff, size);
+ return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size);
+}
+
+int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+{
+ INT uiRetVal =0;
+
+ uiRetVal = rdm(Adapter,uiAddress,(PUCHAR)pucBuff,size);
+ convertEndian(RWM_READ, (PUINT)pucBuff, size);
+
+ return uiRetVal;
+}
+
+int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+{
+
+ INT status = STATUS_SUCCESS ;
+ down(&Adapter->rdmwrmsync);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ status = -EACCES;
+ goto exit;
+ }
+
+ status = rdm(Adapter, uiAddress, pucBuff, sSize);
+
+exit:
+ up(&Adapter->rdmwrmsync);
+ return status ;
+}
+int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
+{
+ INT status = STATUS_SUCCESS ;
+ down(&Adapter->rdmwrmsync);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ status = -EACCES;
+ goto exit;
+ }
+
+ status =wrm(Adapter, uiAddress, pucBuff, sSize);
+
+exit:
+ up(&Adapter->rdmwrmsync);
+ return status ;
+}
+
+int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+{
+ int iRetVal = STATUS_SUCCESS;
+
+ down(&Adapter->rdmwrmsync);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ iRetVal = -EACCES;
+ goto exit;
+ }
+
+ iRetVal = wrmalt(Adapter,uiAddress,pucBuff,size);
+
+exit:
+ up(&Adapter->rdmwrmsync);
+ return iRetVal;
+}
+
+int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
+{
+ INT uiRetVal =STATUS_SUCCESS;
+
+ down(&Adapter->rdmwrmsync);
+
+ if((Adapter->IdleMode == TRUE) ||
+ (Adapter->bShutStatus ==TRUE) ||
+ (Adapter->bPreparingForLowPowerMode ==TRUE))
+ {
+ uiRetVal = -EACCES;
+ goto exit;
+ }
+
+ uiRetVal = rdmalt(Adapter,uiAddress, pucBuff, size);
+
+exit:
+ up(&Adapter->rdmwrmsync);
+ return uiRetVal;
+}
+
+
+VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter)
+{
+ int clear_abort_pattern = 0,Status = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
+ //target has woken up From Shut Down
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
+ Status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status);
+ return;
+ }
+ if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
+ {
+ msleep(100);
+ InterfaceHandleShutdownModeWakeup(Adapter);
+ msleep(100);
+ }
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ Adapter->DriverState = NO_NETWORK_ENTRY;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+
+ Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
+ Adapter->bShutStatus = FALSE;
+ wake_up(&Adapter->lowpower_mode_wait_queue);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
+}
+
+VOID SendShutModeResponse(PMINI_ADAPTER Adapter)
+{
+ CONTROL_MESSAGE stShutdownResponse;
+ UINT NVMAccess = 0,lowPwrAbortMsg = 0;
+ UINT Status = 0;
+
+ memset (&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE));
+ stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ;
+ stShutdownResponse.Leader.PLength = 8;//8 bytes;
+ stShutdownResponse.szData[0] = LINK_UP_ACK;
+ stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE;
+
+ /*********************************
+ **down_trylock -
+ ** if [ semaphore is available ]
+ ** acquire semaphone and return value 0 ;
+ ** else
+ ** return non-zero value ;
+ **
+ ***********************************/
+
+ NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+
+ lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync);
+
+
+ if(NVMAccess || lowPwrAbortMsg|| atomic_read(&Adapter->TotalPacketCount))
+ {
+ if(!NVMAccess)
+ up(&Adapter->NVMRdmWrmLock);
+
+ if(!lowPwrAbortMsg)
+ up(&Adapter->LowPowerModeSync);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n");
+ stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on.
+ Adapter->bPreparingForLowPowerMode = FALSE;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n");
+ stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER;//ShutDown ACK
+
+ /* Wait for the LED to TURN OFF before sending ACK response */
+ if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
+ {
+ INT iRetVal = 0;
+
+ /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */
+ Adapter->DriverState = LOWPOWER_MODE_ENTER;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+
+ /* Wait for 1 SEC for LED to OFF */
+ iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent,\
+ Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000));
+
+ /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */
+ if(iRetVal <= 0)
+ {
+ stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on.
+
+ Adapter->DriverState = NO_NETWORK_ENTRY;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ }
+ }
+
+ if(stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ACKING SHUTDOWN MODE !!!!!!!!!");
+ down(&Adapter->rdmwrmsync);
+ Adapter->bPreparingForLowPowerMode = TRUE;
+ up(&Adapter->rdmwrmsync);
+ //Killing all URBS.
+#ifndef BCM_SHM_INTERFACE
+ if(Adapter->bDoSuspend == TRUE)
+ Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+#endif
+ }
+ else
+ {
+ Adapter->bPreparingForLowPowerMode = FALSE;
+ }
+
+ if(!NVMAccess)
+ up(&Adapter->NVMRdmWrmLock);
+
+ if(!lowPwrAbortMsg)
+ up(&Adapter->LowPowerModeSync);
+ }
+ Status = CopyBufferToControlPacket(Adapter,&stShutdownResponse);
+ if((Status != STATUS_SUCCESS))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n");
+ Adapter->bPreparingForLowPowerMode = FALSE;
+
+#ifndef BCM_SHM_INTERFACE
+ StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+#endif
+ }
+}
+
+
+void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
+{
+ B_UINT32 uiResetValue = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
+
+ if(*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW)
+ {
+ HandleShutDownModeWakeup(Adapter);
+ }
+ else if(*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE)
+ {
+ //Target wants to go to Shut Down Mode
+ //InterfacePrepareForShutdown(Adapter);
+ if(Adapter->chip_id == BCS220_2 ||
+ Adapter->chip_id == BCS220_2BC ||
+ Adapter->chip_id == BCS250_BC ||
+ Adapter->chip_id == BCS220_3)
+ {
+ rdmalt(Adapter,HPM_CONFIG_MSW, &uiResetValue, 4);
+ uiResetValue |= (1<<17);
+ wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4);
+ }
+
+ SendShutModeResponse(Adapter);
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n");
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
+ return;
+
+}
+
+VOID ResetCounters(PMINI_ADAPTER Adapter)
+{
+
+ beceem_protocol_reset(Adapter);
+
+ Adapter->CurrNumRecvDescs = 0;
+ Adapter->PrevNumRecvDescs = 0;
+ Adapter->LinkUpStatus = 0;
+ Adapter->LinkStatus = 0;
+ atomic_set(&Adapter->cntrlpktCnt,0);
+ atomic_set (&Adapter->TotalPacketCount,0);
+ Adapter->fw_download_done=FALSE;
+ Adapter->LinkStatus = 0;
+ Adapter->AutoLinkUp = FALSE;
+ Adapter->IdleMode = FALSE;
+ Adapter->bShutStatus = FALSE;
+
+}
+S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP)
+{
+ UINT uiIndex=0;
+ for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
+ {
+ if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&&
+ (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&&
+ (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIP)&&
+ !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment)
+ return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry;
+ }
+ return NULL;
+}
+
+void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo)
+{
+ UINT uiIndex=0;
+ for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
+ {
+ if(!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)
+ {
+ memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex],psFragPktInfo,sizeof(S_FRAGMENTED_PACKET_INFO));
+ break;
+ }
+ }
+
+}
+
+void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp)
+{
+ UINT uiIndex=0;
+ for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++)
+ {
+ if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&&
+ (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&&
+ (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIp))
+ memset(&Adapter->astFragmentedPktClassifierTable[uiIndex],0,sizeof(S_FRAGMENTED_PACKET_INFO));
+ }
+}
+
+void update_per_cid_rx (PMINI_ADAPTER Adapter)
+{
+ UINT qindex = 0;
+
+ if((jiffies - Adapter->liDrainCalculated) < XSECONDS)
+ return;
+
+ for(qindex = 0; qindex < HiPriority; qindex++)
+ {
+ if(Adapter->PackInfo[qindex].ucDirection == 0)
+ {
+ Adapter->PackInfo[qindex].uiCurrentRxRate =
+ (Adapter->PackInfo[qindex].uiCurrentRxRate +
+ Adapter->PackInfo[qindex].uiThisPeriodRxBytes)/2;
+
+ Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0;
+ }
+ else
+ {
+ Adapter->PackInfo[qindex].uiCurrentDrainRate =
+ (Adapter->PackInfo[qindex].uiCurrentDrainRate +
+ Adapter->PackInfo[qindex].uiThisPeriodSentBytes)/2;
+
+ Adapter->PackInfo[qindex].uiThisPeriodSentBytes=0;
+ }
+ }
+ Adapter->liDrainCalculated=jiffies;
+}
+void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
+{
+ INT iIndex = 0;
+ u32 uibuff[MAX_TARGET_DSX_BUFFERS];
+
+ if(!atomic_read (&Adapter->uiMBupdate))
+ return;
+
+#ifdef BCM_SHM_INTERFACE
+ if(rdmalt(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
+#else
+ if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
+#endif
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
+ return;
+ }
+ for(iIndex = 0;iIndex < HiPriority; iIndex++)
+ {
+ if(Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection)
+ {
+ if(Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS)
+ {
+ atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x \n",
+ Adapter->PackInfo[iIndex].usVCID_Value);
+ }
+ }
+ }
+ atomic_set (&Adapter->uiMBupdate, FALSE);
+}
+
+void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
+{
+ struct sk_buff* PacketToDrop=NULL;
+ struct net_device_stats* netstats=NULL;
+
+ netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
+
+ spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
+
+ while(Adapter->PackInfo[iQIndex].FirstTxQueue &&
+ atomic_read(&Adapter->TotalPacketCount))
+ {
+ PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
+ if(PacketToDrop && PacketToDrop->len)
+ {
+ netstats->tx_dropped++;
+ DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, \
+ Adapter->PackInfo[iQIndex].LastTxQueue);
+
+ Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--;
+ Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len;
+
+ //Adding dropped statistics
+ Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
+ Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
+
+ bcm_kfree_skb(PacketToDrop);
+ atomic_dec(&Adapter->TotalPacketCount);
+ atomic_inc(&Adapter->TxDroppedPacketCount);
+
+ }
+ }
+ spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
+
+}
+
+void beceem_protocol_reset (PMINI_ADAPTER Adapter)
+{
+ int i =0;
+
+ if(NULL != Adapter->dev)
+ {
+ netif_carrier_off(Adapter->dev);
+ netif_stop_queue(Adapter->dev);
+ }
+
+ Adapter->IdleMode = FALSE;
+ Adapter->LinkUpStatus = FALSE;
+ ClearTargetDSXBuffer(Adapter,0, TRUE);
+ //Delete All Classifier Rules
+
+ for(i = 0;i<HiPriority;i++)
+ {
+ DeleteAllClassifiersForSF(Adapter,i);
+ }
+
+ flush_all_queues(Adapter);
+
+ if(Adapter->TimerActive == TRUE)
+ Adapter->TimerActive = FALSE;
+
+ memset(Adapter->astFragmentedPktClassifierTable, 0,
+ sizeof(S_FRAGMENTED_PACKET_INFO) *
+ MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
+
+ for(i = 0;i<HiPriority;i++)
+ {
+ //resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF.
+ // It is same between MIBs and SF.
+ memset((PVOID)&Adapter->PackInfo[i],0,sizeof(S_MIBS_SERVICEFLOW_TABLE));
+ }
+}
+
+
+
+#ifdef BCM_SHM_INTERFACE
+
+
+#define GET_GTB_DIFF(start, end) \
+( (start) < (end) )? ( (end) - (start) ) : ( ~0x0 - ( (start) - (end)) +1 )
+
+void usdelay ( unsigned int a) {
+ unsigned int start= *(unsigned int *)0xaf8051b4;
+ unsigned int end = start+1;
+ unsigned int diff = 0;
+
+ while(1) {
+ end = *(unsigned int *)0xaf8051b4;
+ diff = (GET_GTB_DIFF(start,end))/80;
+ if (diff >= a)
+ break;
+ }
+}
+void read_cfg_file(PMINI_ADAPTER Adapter) {
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Config File Version = 0x%x \n",Adapter->pstargetparams->m_u32CfgVersion );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Center Frequency = 0x%x \n",Adapter->pstargetparams->m_u32CenterFrequency );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band A Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandAScan );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band B Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandBScan );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band C Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandCScan );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ERTPS Options = 0x%x \n",Adapter->pstargetparams->m_u32ErtpsOptions );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PHS Enable = 0x%x \n",Adapter->pstargetparams->m_u32PHSEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Handoff Enable = 0x%x \n",Adapter->pstargetparams->m_u32HoEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved1 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved1 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved2 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved2 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MIMO Enable = 0x%x \n",Adapter->pstargetparams->m_u32MimoEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PKMv2 Enable = 0x%x \n",Adapter->pstargetparams->m_u32SecurityEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Powersaving Modes Enable = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModesEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Power Saving Mode Options = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModeOptions );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ARQ Enable = 0x%x \n",Adapter->pstargetparams->m_u32ArqEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Harq Enable = 0x%x \n",Adapter->pstargetparams->m_u32HarqEnable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"EEPROM Flag = 0x%x \n",Adapter->pstargetparams->m_u32EEPROMFlag );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Customize = 0x%x \n",Adapter->pstargetparams->m_u32Customize );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Bandwidth = 0x%x \n",Adapter->pstargetparams->m_u32ConfigBW );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ShutDown Timer Value = 0x%x \n",Adapter->pstargetparams->m_u32ShutDownInitThresholdTimer );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RadioParameter = 0x%x \n",Adapter->pstargetparams->m_u32RadioParameter );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter1 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter1 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter2 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter2 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter3 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter3 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"m_u32TestOptions = 0x%x \n",Adapter->pstargetparams->m_u32TestOptions );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperDLFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperDLFrame );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperULFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperULFrame );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corr2MacFlags = 0x%x \n",Adapter->pstargetparams->m_u32Corr2MacFlags );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig1 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig1 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig2 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig2 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig3 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig3 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig4 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig4 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig5 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig5 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig6 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig6 );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Segmented PUSC Enable = 0x%x \n",Adapter->pstargetparams->m_u32SegmentedPUSCenable );
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BamcEnable = 0x%x \n",Adapter->pstargetparams->m_u32BandAMCEnable );
+}
+
+#endif
+
+
diff --git a/drivers/staging/bcm/Osal_Misc.c b/drivers/staging/bcm/Osal_Misc.c
new file mode 100644
index 000000000000..feefd20a5291
--- /dev/null
+++ b/drivers/staging/bcm/Osal_Misc.c
@@ -0,0 +1,27 @@
+ /*++
+
+ Copyright (c) Beceem Communications Inc.
+
+ Module Name:
+ WIN_Misc.c
+
+ Abstract:
+ Implements the Miscelanneous OS Construts
+ Linked Lists
+ Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
+ Files
+
+ Revision History:
+ Who When What
+ -------- -------- ----------------------------------------------
+ Name Date Created/reviewed/modified
+ Rajeev 24/1/08 Created
+ Notes:
+
+ --*/
+#include "headers.h"
+
+bool OsalMemCompare(void *dest, void *src, UINT len)
+{
+ return (memcmp(src, dest, len));
+}
diff --git a/drivers/staging/bcm/PHSDefines.h b/drivers/staging/bcm/PHSDefines.h
new file mode 100644
index 000000000000..9889a993ad5b
--- /dev/null
+++ b/drivers/staging/bcm/PHSDefines.h
@@ -0,0 +1,125 @@
+#ifndef BCM_PHS_DEFINES_H
+#define BCM_PHS_DEFINES_H
+
+#define PHS_INVALID_TABLE_INDEX 0xffffffff
+
+/************************* MACROS **********************************************/
+#define PHS_MEM_TAG '_SHP'
+
+
+
+//PHS Defines
+#define STATUS_PHS_COMPRESSED 0xa1
+#define STATUS_PHS_NOCOMPRESSION 0xa2
+#define APPLY_PHS 1
+#define MAX_NO_BIT 7
+#define ZERO_PHSI 0
+#define VERIFY 0
+#define SIZE_MULTIPLE_32 4
+#define UNCOMPRESSED_PACKET 0
+#define DYNAMIC 0
+#define SUPPRESS 0x80
+#define NO_CLASSIFIER_MATCH 0
+#define SEND_PACKET_UNCOMPRESSED 0
+#define PHSI_IS_ZERO 0
+#define PHSI_LEN 1
+#define ERROR_LEN 0
+#define PHS_BUFFER_SIZE 1532
+
+
+//#define MAX_PHS_LENGTHS 100
+#define MAX_PHSRULE_PER_SF 20
+#define MAX_SERVICEFLOWS 17
+
+//PHS Error Defines
+#define PHS_SUCCESS 0
+#define ERR_PHS_INVALID_DEVICE_EXETENSION 0x800
+#define ERR_PHS_INVALID_PHS_RULE 0x801
+#define ERR_PHS_RULE_ALREADY_EXISTS 0x802
+#define ERR_SF_MATCH_FAIL 0x803
+#define ERR_INVALID_CLASSIFIERTABLE_FOR_SF 0x804
+#define ERR_SFTABLE_FULL 0x805
+#define ERR_CLSASSIFIER_TABLE_FULL 0x806
+#define ERR_PHSRULE_MEMALLOC_FAIL 0x807
+#define ERR_CLSID_MATCH_FAIL 0x808
+#define ERR_PHSRULE_MATCH_FAIL 0x809
+
+typedef struct _S_PHS_RULE
+{
+ /// brief 8bit PHSI Of The Service Flow
+ B_UINT8 u8PHSI;
+ /// brief PHSF Of The Service Flow
+ B_UINT8 u8PHSFLength;
+ B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
+ /// brief PHSM Of The Service Flow
+ B_UINT8 u8PHSMLength;
+ B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
+ /// brief 8bit PHSS Of The Service Flow
+ B_UINT8 u8PHSS;
+ /// brief 8bit PHSV Of The Service Flow
+ B_UINT8 u8PHSV;
+ //Reference Count for this PHS Rule
+ B_UINT8 u8RefCnt;
+ //Flag to Store Unclassified PHS rules only in DL
+ B_UINT8 bUnclassifiedPHSRule;
+
+ B_UINT8 u8Reserved[3];
+
+ LONG PHSModifiedBytes;
+ ULONG PHSModifiedNumPackets;
+ ULONG PHSErrorNumPackets;
+}S_PHS_RULE;
+
+
+typedef enum _E_CLASSIFIER_ENTRY_CONTEXT
+{
+ eActiveClassifierRuleContext,
+ eOldClassifierRuleContext
+}E_CLASSIFIER_ENTRY_CONTEXT;
+
+typedef struct _S_CLASSIFIER_ENTRY
+{
+ B_UINT8 bUsed;
+ B_UINT16 uiClassifierRuleId;
+ B_UINT8 u8PHSI;
+ S_PHS_RULE *pstPhsRule;
+ B_UINT8 bUnclassifiedPHSRule;
+
+}S_CLASSIFIER_ENTRY;
+
+
+typedef struct _S_CLASSIFIER_TABLE
+{
+ B_UINT16 uiTotalClassifiers;
+ S_CLASSIFIER_ENTRY stActivePhsRulesList[MAX_PHSRULE_PER_SF];
+ S_CLASSIFIER_ENTRY stOldPhsRulesList[MAX_PHSRULE_PER_SF];
+ B_UINT16 uiOldestPhsRuleIndex;
+
+}S_CLASSIFIER_TABLE;
+
+
+typedef struct _S_SERVICEFLOW_ENTRY
+{
+ B_UINT8 bUsed;
+ B_UINT16 uiVcid;
+ S_CLASSIFIER_TABLE *pstClassifierTable;
+}S_SERVICEFLOW_ENTRY;
+
+typedef struct _S_SERVICEFLOW_TABLE
+{
+ B_UINT16 uiTotalServiceFlows;
+ S_SERVICEFLOW_ENTRY stSFList[MAX_SERVICEFLOWS];
+
+}S_SERVICEFLOW_TABLE;
+
+
+typedef struct _PHS_DEVICE_EXTENSION
+{
+ /* PHS Specific data*/
+ S_SERVICEFLOW_TABLE *pstServiceFlowPhsRulesTable;
+ void *CompressedTxBuffer;
+ void *UnCompressedRxBuffer;
+}PHS_DEVICE_EXTENSION,*PPHS_DEVICE_EXTENSION;
+
+
+#endif
diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c
new file mode 100644
index 000000000000..8ba8489afc2c
--- /dev/null
+++ b/drivers/staging/bcm/PHSModule.c
@@ -0,0 +1,1641 @@
+#include "headers.h"
+
+#define IN
+#define OUT
+
+void DumpDataPacketHeader(PUCHAR pPkt);
+
+/*
+Function: PHSTransmit
+
+Description: This routine handle PHS(Payload Header Suppression for Tx path.
+ It extracts a fragment of the NDIS_PACKET containing the header
+ to be suppressed.It then supresses the header by invoking PHS exported compress routine.
+ The header data after supression is copied back to the NDIS_PACKET.
+
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+ IN Packet - NDIS packet containing data to be transmitted
+ IN USHORT Vcid - vcid pertaining to connection on which the packet is being sent.Used to
+ identify PHS rule to be applied.
+ B_UINT16 uiClassifierRuleID - Classifier Rule ID
+ BOOLEAN bHeaderSuppressionEnabled - indicates if header suprression is enabled for SF.
+
+Return: STATUS_SUCCESS - If the send was successful.
+ Other - If an error occured.
+*/
+
+int PHSTransmit(PMINI_ADAPTER Adapter,
+ struct sk_buff **pPacket,
+ USHORT Vcid,
+ B_UINT16 uiClassifierRuleID,
+ BOOLEAN bHeaderSuppressionEnabled,
+ UINT *PacketLen,
+ UCHAR bEthCSSupport)
+{
+
+ //PHS Sepcific
+ UINT unPHSPktHdrBytesCopied = 0;
+ UINT unPhsOldHdrSize = 0;
+ UINT unPHSNewPktHeaderLen = 0;
+ /* Pointer to PHS IN Hdr Buffer */
+ PUCHAR pucPHSPktHdrInBuf =
+ Adapter->stPhsTxContextInfo.ucaHdrSupressionInBuf;
+ /* Pointer to PHS OUT Hdr Buffer */
+ PUCHAR pucPHSPktHdrOutBuf =
+ Adapter->stPhsTxContextInfo.ucaHdrSupressionOutBuf;
+ UINT usPacketType;
+ UINT BytesToRemove=0;
+ BOOLEAN bPHSI = 0;
+ LONG ulPhsStatus = 0;
+ UINT numBytesCompressed = 0;
+ struct sk_buff *newPacket = NULL;
+ struct sk_buff *Packet = *pPacket;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
+
+ if(!bEthCSSupport)
+ BytesToRemove=ETH_HLEN;
+ /*
+ Accumulate the header upto the size we support supression
+ from NDIS packet
+ */
+
+ usPacketType=((struct ethhdr *)(Packet->data))->h_proto;
+
+
+ pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
+ //considering data after ethernet header
+ if((*PacketLen - BytesToRemove) < MAX_PHS_LENGTHS)
+ {
+
+ unPHSPktHdrBytesCopied = (*PacketLen - BytesToRemove);
+ }
+ else
+ {
+ unPHSPktHdrBytesCopied = MAX_PHS_LENGTHS;
+ }
+
+ if( (unPHSPktHdrBytesCopied > 0 ) &&
+ (unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS))
+ {
+
+
+ //DumpDataPacketHeader(pucPHSPktHdrInBuf);
+
+ // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
+ // Suppress only if IP Header and PHS Enabled For the Service Flow
+ if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
+ (usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
+ (bHeaderSuppressionEnabled))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nTrying to PHS Compress Using Classifier rule 0x%X",uiClassifierRuleID);
+
+
+ unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
+ ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
+ Vcid,
+ uiClassifierRuleID,
+ pucPHSPktHdrInBuf,
+ pucPHSPktHdrOutBuf,
+ &unPhsOldHdrSize,
+ &unPHSNewPktHeaderLen);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nPHS Old header Size : %d New Header Size %d\n",unPhsOldHdrSize,unPHSNewPktHeaderLen);
+
+ if(unPHSNewPktHeaderLen == unPhsOldHdrSize)
+ {
+ if( ulPhsStatus == STATUS_PHS_COMPRESSED)
+ bPHSI = *pucPHSPktHdrOutBuf;
+ ulPhsStatus = STATUS_PHS_NOCOMPRESSION;
+ }
+
+ if( ulPhsStatus == STATUS_PHS_COMPRESSED)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHS Sending packet Compressed");
+
+ if(skb_cloned(Packet))
+ {
+ newPacket = skb_copy(Packet, GFP_ATOMIC);
+
+ if(newPacket == NULL)
+ return STATUS_FAILURE;
+
+ bcm_kfree_skb(Packet);
+ *pPacket = Packet = newPacket;
+ pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
+ }
+
+ numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
+
+ OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
+ OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
+ skb_pull(Packet, numBytesCompressed);
+
+ return STATUS_SUCCESS;
+ }
+
+ else
+ {
+ //if one byte headroom is not available, increase it through skb_cow
+ if(!(skb_headroom(Packet) > 0))
+ {
+ if(skb_cow(Packet, 1))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
+ return STATUS_FAILURE;
+ }
+ }
+ skb_push(Packet, 1);
+
+ // CAUTION: The MAC Header is getting corrupted here for IP CS - can be saved by copying 14 Bytes. not needed .... hence corrupting it.
+ *(Packet->data + BytesToRemove) = bPHSI;
+ return STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ if(!bHeaderSuppressionEnabled)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nHeader Suppression Disabled For SF: No PHS\n");
+ }
+
+ return STATUS_SUCCESS;
+ }
+ }
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS");
+ return STATUS_SUCCESS;
+}
+
+int PHSRecieve(PMINI_ADAPTER Adapter,
+ USHORT usVcid,
+ struct sk_buff *packet,
+ UINT *punPacketLen,
+ UCHAR *pucEthernetHdr,
+ UINT bHeaderSuppressionEnabled)
+{
+ u32 nStandardPktHdrLen = 0;
+ u32 nTotalsupressedPktHdrBytes = 0;
+ int ulPhsStatus = 0;
+ PUCHAR pucInBuff = NULL ;
+ UINT TotalBytesAdded = 0;
+ if(!bHeaderSuppressionEnabled)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
+ return ulPhsStatus;
+ }
+
+ pucInBuff = packet->data;
+
+ //Restore PHS suppressed header
+ nStandardPktHdrLen = packet->len;
+ ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
+ usVcid,
+ pucInBuff,
+ Adapter->ucaPHSPktRestoreBuf,
+ &nTotalsupressedPktHdrBytes,
+ &nStandardPktHdrLen);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
+ nTotalsupressedPktHdrBytes,nStandardPktHdrLen);
+
+ if(ulPhsStatus != STATUS_PHS_COMPRESSED)
+ {
+ skb_pull(packet, 1);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ TotalBytesAdded = nStandardPktHdrLen - nTotalsupressedPktHdrBytes - PHSI_LEN;
+ if(TotalBytesAdded)
+ {
+ if(skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
+ skb_push(packet, TotalBytesAdded);
+ else
+ {
+ if(skb_cow(packet, skb_headroom(packet) + TotalBytesAdded))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
+ return STATUS_FAILURE;
+ }
+
+ skb_push(packet, TotalBytesAdded);
+ }
+ }
+
+ OsalMemMove(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+void DumpDataPacketHeader(PUCHAR pPkt)
+{
+ struct iphdr *iphd = (struct iphdr*)pPkt;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src IP : %x \n",iphd->saddr);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr);
+
+}
+
+void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
+{
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"Dumping Data Packet");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,pBuf,nPktLen);
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: phs_init
+//
+// Description: This routine is responsible for allocating memory for classifier and
+// PHS rules.
+//
+// Arguments:
+// pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
+//
+// Returns:
+// TRUE(1) -If allocation of memory was success full.
+// FALSE -If allocation of memory fails.
+//-----------------------------------------------------------------------------
+int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
+{
+ int i;
+ S_SERVICEFLOW_TABLE *pstServiceFlowTable;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function ");
+
+ if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
+ return -EINVAL;
+
+ pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
+ (S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE),
+ PHS_MEM_TAG);
+
+ if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
+ {
+ OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable,
+ sizeof(S_SERVICEFLOW_TABLE));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
+ return -ENOMEM;
+ }
+
+ pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
+ for(i=0;i<MAX_SERVICEFLOWS;i++)
+ {
+ S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
+ sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc(
+ sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG);
+ if(sServiceFlow.pstClassifierTable)
+ {
+ OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE));
+ pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ free_phs_serviceflow_rules(pPhsdeviceExtension->
+ pstServiceFlowPhsRulesTable);
+ pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
+ return -ENOMEM;
+ }
+ }
+
+
+ pPhsdeviceExtension->CompressedTxBuffer =
+ OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
+
+ if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
+ pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
+ return -ENOMEM;
+ }
+
+ pPhsdeviceExtension->UnCompressedRxBuffer =
+ OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
+ if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE);
+ free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
+ pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
+ return -ENOMEM;
+ }
+
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successfull");
+ return STATUS_SUCCESS;
+}
+
+
+int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
+{
+ if(pPHSDeviceExt->pstServiceFlowPhsRulesTable)
+ {
+ free_phs_serviceflow_rules(pPHSDeviceExt->pstServiceFlowPhsRulesTable);
+ pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
+ }
+
+ if(pPHSDeviceExt->CompressedTxBuffer)
+ {
+ OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE);
+ pPHSDeviceExt->CompressedTxBuffer = NULL;
+ }
+ if(pPHSDeviceExt->UnCompressedRxBuffer)
+ {
+ OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE);
+ pPHSDeviceExt->UnCompressedRxBuffer = NULL;
+ }
+
+ return 0;
+}
+
+
+
+//PHS functions
+/*++
+PhsUpdateClassifierRule
+
+Routine Description:
+ Exported function to add or modify a PHS Rule.
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context
+ IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
+ IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
+ IN S_PHS_RULE *psPhsRule - The PHS Rule strcuture to be added to the PHS Rule table.
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+ULONG PhsUpdateClassifierRule(IN void* pvContext,
+ IN B_UINT16 uiVcid ,
+ IN B_UINT16 uiClsId ,
+ IN S_PHS_RULE *psPhsRule,
+ IN B_UINT8 u8AssociatedPHSI)
+{
+ ULONG lStatus =0;
+ UINT nSFIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+
+
+ PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS With Corr2 Changes \n");
+
+ if(pDeviceExtension == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Invalid Device Extension\n");
+ return ERR_PHS_INVALID_DEVICE_EXETENSION;
+ }
+
+
+ if(u8AssociatedPHSI == 0)
+ {
+ return ERR_PHS_INVALID_PHS_RULE;
+ }
+
+ /* Retrieve the SFID Entry Index for requested Service Flow */
+
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid,&pstServiceFlowEntry);
+
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ /* This is a new SF. Create a mapping entry for this */
+ lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
+ pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
+ return lStatus;
+ }
+
+ /* SF already Exists Add PHS Rule to existing SF */
+ lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
+ pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
+
+ return lStatus;
+}
+
+/*++
+PhsDeletePHSRule
+
+Routine Description:
+ Deletes the specified phs Rule within Vcid
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context
+ IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
+ IN B_UINT8 u8PHSI - the PHS Index identifying PHS rule to be deleted.
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+
+ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
+{
+ ULONG lStatus =0;
+ UINT nSFIndex =0, nClsidIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+
+ PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
+
+ if(pDeviceExtension)
+ {
+
+ //Retrieve the SFID Entry Index for requested Service Flow
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension
+ ->pstServiceFlowPhsRulesTable,uiVcid,&pstServiceFlowEntry);
+
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
+ return ERR_SF_MATCH_FAIL;
+ }
+
+ pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
+ if(pstClassifierRulesTable)
+ {
+ for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule->u8PHSI == u8PHSI)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
+ ->u8RefCnt)
+ pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
+ ->u8RefCnt--;
+ if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt)
+ OsalMemFree(pstClassifierRulesTable
+ ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
+ sizeof(S_PHS_RULE));
+ OsalZeroMemory(&pstClassifierRulesTable
+ ->stActivePhsRulesList[nClsidIndex],
+ sizeof(S_CLASSIFIER_ENTRY));
+ }
+ }
+ }
+ }
+
+ }
+ return lStatus;
+}
+
+/*++
+PhsDeleteClassifierRule
+
+Routine Description:
+ Exported function to Delete a PHS Rule for the SFID,CLSID Pair.
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context
+ IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rule applies
+ IN B_UINT16 uiClsId - The Classifier ID within the Service Flow for which the PHS rule applies.
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 uiClsId)
+{
+ ULONG lStatus =0;
+ UINT nSFIndex =0, nClsidIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
+
+ if(pDeviceExtension)
+ {
+ //Retrieve the SFID Entry Index for requested Service Flow
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension
+ ->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"SFID Match Failed\n");
+ return ERR_SF_MATCH_FAIL;
+ }
+
+ nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
+ uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
+ if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
+ {
+ if(pstClassifierEntry->pstPhsRule)
+ {
+ if(pstClassifierEntry->pstPhsRule->u8RefCnt)
+ pstClassifierEntry->pstPhsRule->u8RefCnt--;
+ if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
+ OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
+
+ }
+ OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
+ }
+
+ nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
+ uiClsId,eOldClassifierRuleContext,&pstClassifierEntry);
+
+ if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
+ {
+ if(pstClassifierEntry->pstPhsRule)
+ //Delete the classifier entry
+ OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
+ OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
+ }
+ }
+ return lStatus;
+}
+
+/*++
+PhsDeleteSFRules
+
+Routine Description:
+ Exported function to Delete a all PHS Rules for the SFID.
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context
+ IN B_UINT16 uiVcid - The Service Flow ID for which the PHS rules need to be deleted
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
+{
+
+ ULONG lStatus =0;
+ UINT nSFIndex =0, nClsidIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_CLASSIFIER_TABLE *pstClassifierRulesTable = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"====> \n");
+
+ if(pDeviceExtension)
+ {
+ //Retrieve the SFID Entry Index for requested Service Flow
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid,&pstServiceFlowEntry);
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
+ return ERR_SF_MATCH_FAIL;
+ }
+
+ pstClassifierRulesTable=pstServiceFlowEntry->pstClassifierTable;
+ if(pstClassifierRulesTable)
+ {
+ for(nClsidIndex=0;nClsidIndex<MAX_PHSRULE_PER_SF;nClsidIndex++)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt)
+ pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt--;
+ if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt)
+ OsalMemFree(pstClassifierRulesTable
+ ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
+ sizeof(S_PHS_RULE));
+ pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
+ .pstPhsRule = NULL;
+ }
+ OsalZeroMemory(&pstClassifierRulesTable
+ ->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY));
+ if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
+ {
+ if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt)
+ pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt--;
+ if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
+ .pstPhsRule->u8RefCnt)
+ OsalMemFree(pstClassifierRulesTable
+ ->stOldPhsRulesList[nClsidIndex].pstPhsRule,
+ sizeof(S_PHS_RULE));
+ pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
+ .pstPhsRule = NULL;
+ }
+ OsalZeroMemory(&pstClassifierRulesTable
+ ->stOldPhsRulesList[nClsidIndex],
+ sizeof(S_CLASSIFIER_ENTRY));
+ }
+ }
+ pstServiceFlowEntry->bUsed = FALSE;
+ pstServiceFlowEntry->uiVcid = 0;
+
+ }
+
+ return lStatus;
+}
+
+
+/*++
+PhsCompress
+
+Routine Description:
+ Exported function to compress the data using PHS.
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context.
+ IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
+ IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
+ IN void *pvInputBuffer - The Input buffer containg packet header data
+ IN void *pvOutputBuffer - The output buffer returned by this function after PHS
+ IN UINT *pOldHeaderSize - The actual size of the header before PHS
+ IN UINT *pNewHeaderSize - The new size of the header after applying PHS
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+ULONG PhsCompress(IN void* pvContext,
+ IN B_UINT16 uiVcid,
+ IN B_UINT16 uiClsId,
+ IN void *pvInputBuffer,
+ OUT void *pvOutputBuffer,
+ OUT UINT *pOldHeaderSize,
+ OUT UINT *pNewHeaderSize )
+{
+ UINT nSFIndex =0, nClsidIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
+ S_PHS_RULE *pstPhsRule = NULL;
+ ULONG lStatus =0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+
+
+ PPHS_DEVICE_EXTENSION pDeviceExtension= (PPHS_DEVICE_EXTENSION)pvContext;
+
+
+ if(pDeviceExtension == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Invalid Device Extension\n");
+ lStatus = STATUS_PHS_NOCOMPRESSION ;
+ return lStatus;
+
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Suppressing header \n");
+
+
+ //Retrieve the SFID Entry Index for requested Service Flow
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid,&pstServiceFlowEntry);
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"SFID Match Failed\n");
+ lStatus = STATUS_PHS_NOCOMPRESSION ;
+ return lStatus;
+ }
+
+ nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
+ uiClsId,eActiveClassifierRuleContext,&pstClassifierEntry);
+
+ if(nClsidIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"No PHS Rule Defined For Classifier\n");
+ lStatus = STATUS_PHS_NOCOMPRESSION ;
+ return lStatus;
+ }
+
+
+ //get rule from SF id,Cls ID pair and proceed
+ pstPhsRule = pstClassifierEntry->pstPhsRule;
+
+ if(!ValidatePHSRuleComplete(pstPhsRule))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"PHS Rule Defined For Classifier But Not Complete\n");
+ lStatus = STATUS_PHS_NOCOMPRESSION ;
+ return lStatus;
+ }
+
+ //Compress Packet
+ lStatus = phs_compress(pstPhsRule,(PUCHAR)pvInputBuffer,
+ (PUCHAR)pvOutputBuffer, pOldHeaderSize,pNewHeaderSize);
+
+ if(lStatus == STATUS_PHS_COMPRESSED)
+ {
+ pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
+ pstPhsRule->PHSModifiedNumPackets++;
+ }
+ else
+ pstPhsRule->PHSErrorNumPackets++;
+
+ return lStatus;
+}
+
+/*++
+PhsDeCompress
+
+Routine Description:
+ Exported function to restore the packet header in Rx path.
+
+Arguments:
+ IN void* pvContext - PHS Driver Specific Context.
+ IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
+ IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
+ OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
+ OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
+
+Return Value:
+
+ 0 if successful,
+ >0 Error.
+
+--*/
+ULONG PhsDeCompress(IN void* pvContext,
+ IN B_UINT16 uiVcid,
+ IN void *pvInputBuffer,
+ OUT void *pvOutputBuffer,
+ OUT UINT *pInHeaderSize,
+ OUT UINT *pOutHeaderSize )
+{
+ UINT nSFIndex =0, nPhsRuleIndex =0 ;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_PHS_RULE *pstPhsRule = NULL;
+ UINT phsi;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ PPHS_DEVICE_EXTENSION pDeviceExtension=
+ (PPHS_DEVICE_EXTENSION)pvContext;
+
+ *pInHeaderSize = 0;
+
+ if(pDeviceExtension == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
+ return ERR_PHS_INVALID_DEVICE_EXETENSION;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
+
+ phsi = *((unsigned char *)(pvInputBuffer));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
+ if(phsi == UNCOMPRESSED_PACKET )
+ {
+ return STATUS_PHS_NOCOMPRESSION;
+ }
+
+ //Retrieve the SFID Entry Index for requested Service Flow
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid,&pstServiceFlowEntry);
+ if(nSFIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
+ return ERR_SF_MATCH_FAIL;
+ }
+
+ nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,phsi,
+ eActiveClassifierRuleContext,&pstPhsRule);
+ if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ //Phs Rule does not exist in active rules table. Lets try in the old rules table.
+ nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
+ phsi,eOldClassifierRuleContext,&pstPhsRule);
+ if(nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ return ERR_PHSRULE_MATCH_FAIL;
+ }
+
+ }
+
+ *pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
+ (PUCHAR)pvOutputBuffer,pstPhsRule,pOutHeaderSize);
+
+ pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
+
+ pstPhsRule->PHSModifiedNumPackets++;
+ return STATUS_PHS_COMPRESSED;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: free_phs_serviceflow_rules
+//
+// Description: This routine is responsible for freeing memory allocated for PHS rules.
+//
+// Arguments:
+// rules - ptr to S_SERVICEFLOW_TABLE structure.
+//
+// Returns:
+// Does not return any value.
+//-----------------------------------------------------------------------------
+
+void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
+{
+ int i,j;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
+ if(psServiceFlowRulesTable)
+ {
+ for(i=0;i<MAX_SERVICEFLOWS;i++)
+ {
+ S_SERVICEFLOW_ENTRY stServiceFlowEntry =
+ psServiceFlowRulesTable->stSFList[i];
+ S_CLASSIFIER_TABLE *pstClassifierRulesTable =
+ stServiceFlowEntry.pstClassifierTable;
+
+ if(pstClassifierRulesTable)
+ {
+ for(j=0;j<MAX_PHSRULE_PER_SF;j++)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule)
+ {
+ if(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
+ ->u8RefCnt)
+ pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
+ ->u8RefCnt--;
+ if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
+ ->u8RefCnt)
+ OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j].
+ pstPhsRule, sizeof(S_PHS_RULE));
+ pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
+ }
+ if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
+ {
+ if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
+ ->u8RefCnt)
+ pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
+ ->u8RefCnt--;
+ if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
+ ->u8RefCnt)
+ OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j]
+ .pstPhsRule,sizeof(S_PHS_RULE));
+ pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
+ }
+ }
+ OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE));
+ stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
+ }
+ }
+ }
+
+ OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE));
+ psServiceFlowRulesTable = NULL;
+}
+
+
+
+BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
+{
+ if(psPhsRule)
+ {
+ if(!psPhsRule->u8PHSI)
+ {
+ // PHSI is not valid
+ return FALSE;
+ }
+
+ if(!psPhsRule->u8PHSS)
+ {
+ //PHSS Is Undefined
+ return FALSE;
+ }
+
+ //Check if PHSF is defines for the PHS Rule
+ if(!psPhsRule->u8PHSFLength) // If any part of PHSF is valid then Rule contains valid PHSF
+ {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+UINT GetServiceFlowEntry(IN S_SERVICEFLOW_TABLE *psServiceFlowTable,
+ IN B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry)
+{
+ int i;
+ for(i=0;i<MAX_SERVICEFLOWS;i++)
+ {
+ if(psServiceFlowTable->stSFList[i].bUsed)
+ {
+ if(psServiceFlowTable->stSFList[i].uiVcid == uiVcid)
+ {
+ *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
+ return i;
+ }
+ }
+ }
+
+ *ppstServiceFlowEntry = NULL;
+ return PHS_INVALID_TABLE_INDEX;
+}
+
+
+UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
+ IN B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
+ OUT S_CLASSIFIER_ENTRY **ppstClassifierEntry)
+{
+ int i;
+ S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
+ for(i=0;i<MAX_PHSRULE_PER_SF;i++)
+ {
+
+ if(eClsContext == eActiveClassifierRuleContext)
+ {
+ psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
+ }
+ else
+ {
+ psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
+ }
+
+ if(psClassifierRules->bUsed)
+ {
+ if(psClassifierRules->uiClassifierRuleId == uiClsid)
+ {
+ *ppstClassifierEntry = psClassifierRules;
+ return i;
+ }
+ }
+
+ }
+
+ *ppstClassifierEntry = NULL;
+ return PHS_INVALID_TABLE_INDEX;
+}
+
+UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
+ IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
+ OUT S_PHS_RULE **ppstPhsRule)
+{
+ int i;
+ S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
+ for(i=0;i<MAX_PHSRULE_PER_SF;i++)
+ {
+ if(eClsContext == eActiveClassifierRuleContext)
+ {
+ pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
+ }
+ else
+ {
+ pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
+ }
+ if(pstClassifierRule->bUsed)
+ {
+ if(pstClassifierRule->u8PHSI == uiPHSI)
+ {
+ *ppstPhsRule = pstClassifierRule->pstPhsRule;
+ return i;
+ }
+ }
+
+ }
+
+ *ppstPhsRule = NULL;
+ return PHS_INVALID_TABLE_INDEX;
+}
+
+UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,IN B_UINT16 uiClsId,
+ IN S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,
+ B_UINT8 u8AssociatedPHSI)
+{
+
+ S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
+ UINT uiStatus = 0;
+ int iSfIndex;
+ BOOLEAN bFreeEntryFound =FALSE;
+ //Check for a free entry in SFID table
+ for(iSfIndex=0;iSfIndex < MAX_SERVICEFLOWS;iSfIndex++)
+ {
+ if(!psServiceFlowTable->stSFList[iSfIndex].bUsed)
+ {
+ bFreeEntryFound = TRUE;
+ break;
+ }
+ }
+
+ if(!bFreeEntryFound)
+ return ERR_SFTABLE_FULL;
+
+
+ psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
+ uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,psPhsRule,
+ eActiveClassifierRuleContext,u8AssociatedPHSI);
+ if(uiStatus == PHS_SUCCESS)
+ {
+ //Add entry at free index to the SF
+ psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
+ psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
+ }
+
+ return uiStatus;
+
+}
+
+UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
+ IN B_UINT16 uiClsId,IN S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,
+ S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI)
+{
+ S_CLASSIFIER_ENTRY *pstClassifierEntry = NULL;
+ UINT uiStatus =PHS_SUCCESS;
+ UINT nClassifierIndex = 0;
+ S_CLASSIFIER_TABLE *psaClassifiertable = NULL;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
+
+ /* Check if the supplied Classifier already exists */
+ nClassifierIndex =GetClassifierEntry(
+ pstServiceFlowEntry->pstClassifierTable,uiClsId,
+ eActiveClassifierRuleContext,&pstClassifierEntry);
+ if(nClassifierIndex == PHS_INVALID_TABLE_INDEX)
+ {
+ /*
+ The Classifier doesn't exist. So its a new classifier being added.
+ Add new entry to associate PHS Rule to the Classifier
+ */
+
+ uiStatus = CreateClassifierPHSRule(uiClsId,psaClassifiertable,
+ psPhsRule,eActiveClassifierRuleContext,u8AssociatedPHSI);
+ return uiStatus;
+ }
+
+ /*
+ The Classifier exists.The PHS Rule for this classifier
+ is being modified
+ */
+ if(pstClassifierEntry->u8PHSI == psPhsRule->u8PHSI)
+ {
+ if(pstClassifierEntry->pstPhsRule == NULL)
+ return ERR_PHS_INVALID_PHS_RULE;
+
+ /*
+ This rule already exists if any fields are changed for this PHS
+ rule update them.
+ */
+ /* If any part of PHSF is valid then we update PHSF */
+ if(psPhsRule->u8PHSFLength)
+ {
+ //update PHSF
+ OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF,
+ psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
+ }
+ if(psPhsRule->u8PHSFLength)
+ {
+ //update PHSFLen
+ pstClassifierEntry->pstPhsRule->u8PHSFLength =
+ psPhsRule->u8PHSFLength;
+ }
+ if(psPhsRule->u8PHSMLength)
+ {
+ //update PHSM
+ OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM,
+ psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
+ }
+ if(psPhsRule->u8PHSMLength)
+ {
+ //update PHSM Len
+ pstClassifierEntry->pstPhsRule->u8PHSMLength =
+ psPhsRule->u8PHSMLength;
+ }
+ if(psPhsRule->u8PHSS)
+ {
+ //update PHSS
+ pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
+ }
+
+ //update PHSV
+ pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
+
+ }
+ else
+ {
+ /*
+ A new rule is being set for this classifier.
+ */
+ uiStatus=UpdateClassifierPHSRule( uiClsId, pstClassifierEntry,
+ psaClassifiertable, psPhsRule, u8AssociatedPHSI);
+ }
+
+
+
+ return uiStatus;
+}
+
+UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
+ S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
+ E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
+{
+ UINT iClassifierIndex = 0;
+ BOOLEAN bFreeEntryFound = FALSE;
+ S_CLASSIFIER_ENTRY *psClassifierRules = NULL;
+ UINT nStatus = PHS_SUCCESS;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,"Inside CreateClassifierPHSRule");
+ if(psaClassifiertable == NULL)
+ {
+ return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
+ }
+
+ if(eClsContext == eOldClassifierRuleContext)
+ {
+ /* If An Old Entry for this classifier ID already exists in the
+ old rules table replace it. */
+
+ iClassifierIndex =
+ GetClassifierEntry(psaClassifiertable, uiClsId,
+ eClsContext,&psClassifierRules);
+ if(iClassifierIndex != PHS_INVALID_TABLE_INDEX)
+ {
+ /*
+ The Classifier already exists in the old rules table
+ Lets replace the old classifier with the new one.
+ */
+ bFreeEntryFound = TRUE;
+ }
+ }
+
+ if(!bFreeEntryFound)
+ {
+ /*
+ Continue to search for a free location to add the rule
+ */
+ for(iClassifierIndex = 0; iClassifierIndex <
+ MAX_PHSRULE_PER_SF; iClassifierIndex++)
+ {
+ if(eClsContext == eActiveClassifierRuleContext)
+ {
+ psClassifierRules =
+ &psaClassifiertable->stActivePhsRulesList[iClassifierIndex];
+ }
+ else
+ {
+ psClassifierRules =
+ &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
+ }
+
+ if(!psClassifierRules->bUsed)
+ {
+ bFreeEntryFound = TRUE;
+ break;
+ }
+ }
+ }
+
+ if(!bFreeEntryFound)
+ {
+ if(eClsContext == eActiveClassifierRuleContext)
+ {
+ return ERR_CLSASSIFIER_TABLE_FULL;
+ }
+ else
+ {
+ //Lets replace the oldest rule if we are looking in old Rule table
+ if(psaClassifiertable->uiOldestPhsRuleIndex >=
+ MAX_PHSRULE_PER_SF)
+ {
+ psaClassifiertable->uiOldestPhsRuleIndex =0;
+ }
+
+ iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
+ psClassifierRules =
+ &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
+
+ (psaClassifiertable->uiOldestPhsRuleIndex)++;
+ }
+ }
+
+ if(eClsContext == eOldClassifierRuleContext)
+ {
+ if(psClassifierRules->pstPhsRule == NULL)
+ {
+ psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc
+ (sizeof(S_PHS_RULE),PHS_MEM_TAG);
+
+ if(NULL == psClassifierRules->pstPhsRule)
+ return ERR_PHSRULE_MEMALLOC_FAIL;
+ }
+
+ psClassifierRules->bUsed = TRUE;
+ psClassifierRules->uiClassifierRuleId = uiClsId;
+ psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
+ psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
+
+ /* Update The PHS rule */
+ OsalMemMove(psClassifierRules->pstPhsRule,
+ psPhsRule, sizeof(S_PHS_RULE));
+ }
+ else
+ {
+ nStatus = UpdateClassifierPHSRule(uiClsId,psClassifierRules,
+ psaClassifiertable,psPhsRule,u8AssociatedPHSI);
+ }
+ return nStatus;
+}
+
+
+UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
+ IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
+ S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
+ B_UINT8 u8AssociatedPHSI)
+{
+ S_PHS_RULE *pstAddPhsRule = NULL;
+ UINT nPhsRuleIndex = 0;
+ BOOLEAN bPHSRuleOrphaned = FALSE;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ psPhsRule->u8RefCnt =0;
+
+ /* Step 1 Deref Any Exisiting PHS Rule in this classifier Entry*/
+ bPHSRuleOrphaned = DerefPhsRule( uiClsId, psaClassifiertable,
+ pstClassifierEntry->pstPhsRule);
+
+ //Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF
+ nPhsRuleIndex =GetPhsRuleEntry(psaClassifiertable,u8AssociatedPHSI,
+ eActiveClassifierRuleContext, &pstAddPhsRule);
+ if(PHS_INVALID_TABLE_INDEX == nPhsRuleIndex)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
+
+ if(psPhsRule->u8PHSI == 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
+ return ERR_PHS_INVALID_PHS_RULE;
+ }
+ //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
+ if(FALSE == bPHSRuleOrphaned)
+ {
+ pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG);
+ if(NULL == pstClassifierEntry->pstPhsRule)
+ {
+ return ERR_PHSRULE_MEMALLOC_FAIL;
+ }
+ }
+ OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
+
+ }
+ else
+ {
+ //Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
+ if(bPHSRuleOrphaned)
+ {
+ if(pstClassifierEntry->pstPhsRule)
+ {
+ //Just Free the PHS Rule as Ref Count is Zero
+ OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
+ pstClassifierEntry->pstPhsRule = NULL;
+
+ }
+
+ }
+ pstClassifierEntry->pstPhsRule = pstAddPhsRule;
+
+ }
+ pstClassifierEntry->bUsed = TRUE;
+ pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
+ pstClassifierEntry->uiClassifierRuleId = uiClsId;
+ pstClassifierEntry->pstPhsRule->u8RefCnt++;
+ pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
+
+ return PHS_SUCCESS;
+
+}
+
+BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
+{
+ if(pstPhsRule==NULL)
+ return FALSE;
+ if(pstPhsRule->u8RefCnt)
+ pstPhsRule->u8RefCnt--;
+ if(0==pstPhsRule->u8RefCnt)
+ {
+ /*if(pstPhsRule->u8PHSI)
+ //Store the currently active rule into the old rules list
+ CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);*/
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void DumpBuffer(PVOID BuffVAddress, int xferSize)
+{
+ int i;
+ int iPrintLength;
+ PUCHAR temp=(PUCHAR)BuffVAddress;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ iPrintLength=(xferSize<32?xferSize:32);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
+
+ for (i=0;i < iPrintLength;i++) {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
+}
+
+
+void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
+{
+ int i,j,k,l;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules : \n");
+ for(i=0;i<MAX_SERVICEFLOWS;i++)
+ {
+ S_SERVICEFLOW_ENTRY stServFlowEntry =
+ pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
+ if(stServFlowEntry.bUsed)
+ {
+ for(j=0;j<MAX_PHSRULE_PER_SF;j++)
+ {
+ for(l=0;l<2;l++)
+ {
+ S_CLASSIFIER_ENTRY stClsEntry;
+ if(l==0)
+ {
+ stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
+ if(stClsEntry.bUsed)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule : \n");
+ }
+ else
+ {
+ stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
+ if(stClsEntry.bUsed)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule : \n");
+ }
+ if(stClsEntry.bUsed)
+ {
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X",stServFlowEntry.uiVcid);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X",stClsEntry.uiClassifierRuleId);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X",stClsEntry.u8PHSI);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X",stClsEntry.pstPhsRule->u8PHSI);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ",stClsEntry.pstPhsRule->u8PHSFLength);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
+ for(k=0;k<stClsEntry.pstPhsRule->u8PHSFLength;k++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSF[k]);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X",stClsEntry.pstPhsRule->u8PHSMLength);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
+ for(k=0;k<stClsEntry.pstPhsRule->u8PHSMLength;k++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ",stClsEntry.pstPhsRule->u8PHSM[k]);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ",stClsEntry.pstPhsRule->u8PHSS);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X",stClsEntry.pstPhsRule->u8PHSV);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: phs_decompress
+//
+// Description: This routine restores the static fields within the packet.
+//
+// Arguments:
+// in_buf - ptr to incoming packet buffer.
+// out_buf - ptr to output buffer where the suppressed header is copied.
+// decomp_phs_rules - ptr to PHS rule.
+// header_size - ptr to field which holds the phss or phsf_length.
+//
+// Returns:
+// size -The number of bytes of dynamic fields present with in the incoming packet
+// header.
+// 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
+//-----------------------------------------------------------------------------
+
+int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
+ S_PHS_RULE *decomp_phs_rules,UINT *header_size)
+{
+ int phss,size=0;
+ S_PHS_RULE *tmp_memb;
+ int bit,i=0;
+ unsigned char *phsf,*phsm;
+ int in_buf_len = *header_size-1;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ in_buf++;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
+ *header_size = 0;
+
+ if((decomp_phs_rules == NULL ))
+ return 0;
+
+
+ tmp_memb = decomp_phs_rules;
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
+ //*header_size = tmp_memb->u8PHSFLength;
+ phss = tmp_memb->u8PHSS;
+ phsf = tmp_memb->u8PHSF;
+ phsm = tmp_memb->u8PHSM;
+
+ if(phss > MAX_PHS_LENGTHS)
+ phss = MAX_PHS_LENGTHS;
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
+ while((phss > 0) && (size < in_buf_len))
+ {
+ bit = ((*phsm << i)& SUPPRESS);
+
+ if(bit == SUPPRESS)
+ {
+ *out_buf = *phsf;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
+ phss,*phsf,*out_buf);
+ }
+ else
+ {
+ *out_buf = *in_buf;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
+ phss,*in_buf,*out_buf);
+ in_buf++;
+ size++;
+ }
+ out_buf++;
+ phsf++;
+ phss--;
+ i++;
+ *header_size=*header_size + 1;
+
+ if(i > MAX_NO_BIT)
+ {
+ i=0;
+ phsm++;
+ }
+ }
+ return size;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Procedure: phs_compress
+//
+// Description: This routine suppresses the static fields within the packet.Before
+// that it will verify the fields to be suppressed with the corresponding fields in the
+// phsf. For verification it checks the phsv field of PHS rule. If set and verification
+// succeeds it suppresses the field.If any one static field is found different none of
+// the static fields are suppressed then the packet is sent as uncompressed packet with
+// phsi=0.
+//
+// Arguments:
+// phs_rule - ptr to PHS rule.
+// in_buf - ptr to incoming packet buffer.
+// out_buf - ptr to output buffer where the suppressed header is copied.
+// header_size - ptr to field which holds the phss.
+//
+// Returns:
+// size-The number of bytes copied into the output buffer i.e dynamic fields
+// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
+//-----------------------------------------------------------------------------
+int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
+ ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
+{
+ unsigned char *old_addr = out_buf;
+ int supress = 0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if(phs_rule == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nphs_compress(): phs_rule null!");
+ *out_buf = ZERO_PHSI;
+ return STATUS_PHS_NOCOMPRESSION;
+ }
+
+
+ if(phs_rule->u8PHSS <= *new_header_size)
+ {
+ *header_size = phs_rule->u8PHSS;
+ }
+ else
+ {
+ *header_size = *new_header_size;
+ }
+ //To copy PHSI
+ out_buf++;
+ supress = verify_suppress_phsf(in_buf,out_buf,phs_rule->u8PHSF,
+ phs_rule->u8PHSM, phs_rule->u8PHSS, phs_rule->u8PHSV,new_header_size);
+
+ if(supress == STATUS_PHS_COMPRESSED)
+ {
+ *old_addr = (unsigned char)phs_rule->u8PHSI;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress phsi %d",phs_rule->u8PHSI);
+ }
+ else
+ {
+ *old_addr = ZERO_PHSI;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In phs_compress PHSV Verification failed");
+ }
+ return supress;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: verify_suppress_phsf
+//
+// Description: This routine verifies the fields of the packet and if all the
+// static fields are equal it adds the phsi of that PHS rule.If any static
+// field differs it woun't suppress any field.
+//
+// Arguments:
+// rules_set - ptr to classifier_rules.
+// in_buffer - ptr to incoming packet buffer.
+// out_buffer - ptr to output buffer where the suppressed header is copied.
+// phsf - ptr to phsf.
+// phsm - ptr to phsm.
+// phss - variable holding phss.
+//
+// Returns:
+// size-The number of bytes copied into the output buffer i.e dynamic fields.
+// 0 -Packet has failed the verification.
+//-----------------------------------------------------------------------------
+
+ int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
+ unsigned char *phsf,unsigned char *phsm,unsigned int phss,
+ unsigned int phsv,UINT* new_header_size)
+{
+ unsigned int size=0;
+ int bit,i=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf PHSM - 0x%X",*phsm);
+
+
+ if(phss>(*new_header_size))
+ {
+ phss=*new_header_size;
+ }
+ while(phss > 0)
+ {
+ bit = ((*phsm << i)& SUPPRESS);
+ if(bit == SUPPRESS)
+ {
+
+ if(*in_buffer != *phsf)
+ {
+ if(phsv == VERIFY)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf failed for field %d buf %d phsf %d",phss,*in_buffer,*phsf);
+ return STATUS_PHS_NOCOMPRESSION;
+ }
+ }
+ else
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success for field %d buf %d phsf %d",phss,*in_buffer,*phsf);
+ }
+ else
+ {
+ *out_buffer = *in_buffer;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In copying_header input %d out %d",*in_buffer,*out_buffer);
+ out_buffer++;
+ size++;
+ }
+ in_buffer++;
+ phsf++;
+ phss--;
+ i++;
+ if(i > MAX_NO_BIT)
+ {
+ i=0;
+ phsm++;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"\nCOMP:In verify_phsf success");
+ *new_header_size = size;
+ return STATUS_PHS_COMPRESSED;
+}
+
+
+
+
+
+
diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h
new file mode 100644
index 000000000000..bf2b5763252c
--- /dev/null
+++ b/drivers/staging/bcm/PHSModule.h
@@ -0,0 +1,95 @@
+#ifndef BCM_MINIPORT_PHSMODULE_H
+#define BCM_MINIPORT_PHSMODULE_H
+
+int PHSTransmit(PMINI_ADAPTER Adapter,
+ struct sk_buff **pPacket,
+ USHORT Vcid,
+ B_UINT16 uiClassifierRuleID,
+ BOOLEAN bHeaderSuppressionEnabled,
+ PUINT PacketLen,
+ UCHAR bEthCSSupport);
+
+int PHSRecieve(PMINI_ADAPTER Adapter,
+ USHORT usVcid,
+ struct sk_buff *packet,
+ UINT *punPacketLen,
+ UCHAR *pucEthernetHdr,
+ UINT
+ );
+
+
+void DumpDataPacketHeader(PUCHAR pPkt);
+
+void DumpFullPacket(UCHAR *pBuf,UINT nPktLen);
+
+void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
+
+
+int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter);
+
+void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
+
+int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
+ unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
+
+
+int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
+ unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
+
+int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
+ S_PHS_RULE *phs_rules,UINT *header_size);
+
+
+int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt);
+
+//Utility Functions
+ULONG PhsUpdateClassifierRule(void* pvContext,B_UINT16 uiVcid,B_UINT16 uiClsId,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI );
+
+ULONG PhsDeletePHSRule(void* pvContext,B_UINT16 uiVcid,B_UINT8 u8PHSI);
+
+ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsId);
+
+ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
+
+
+ULONG PhsCompress(void* pvContext,
+ B_UINT16 uiVcid,
+ B_UINT16 uiClsId,
+ void *pvInputBuffer,
+ void *pvOutputBuffer,
+ UINT *pOldHeaderSize,
+ UINT *pNewHeaderSize );
+
+ULONG PhsDeCompress(void* pvContext,
+ B_UINT16 uiVcid,
+ void *pvInputBuffer,
+ void *pvOutputBuffer,
+ UINT *pInHeaderSize,
+ UINT *pOutHeaderSize);
+
+
+BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule);
+
+BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
+
+UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry);
+
+UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
+
+UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
+
+
+UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
+
+UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
+
+void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
+
+
+#endif
diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h
new file mode 100644
index 000000000000..00f1cc12356a
--- /dev/null
+++ b/drivers/staging/bcm/Protocol.h
@@ -0,0 +1,151 @@
+/************************************
+* Protocol.h
+*************************************/
+#ifndef __PROTOCOL_H__
+#define __PROTOCOL_H__
+
+
+#define IPV4 4
+#define IPV6 6
+
+
+struct ArpHeader {
+ struct arphdr arp;
+ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
+ unsigned char ar_sip[4]; /* sender IP address */
+ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
+ unsigned char ar_tip[4]; /* target IP address */
+}/*__attribute__((packed))*/;
+
+
+struct TransportHeaderT
+{
+ union
+ {
+ struct udphdr uhdr;
+ struct tcphdr thdr;
+ };
+} __attribute__((packed));
+typedef struct TransportHeaderT xporthdr;
+
+
+typedef enum _E_NWPKT_IPFRAME_TYPE
+{
+ eNonIPPacket,
+ eIPv4Packet,
+ eIPv6Packet
+}E_NWPKT_IPFRAME_TYPE;
+
+typedef enum _E_NWPKT_ETHFRAME_TYPE
+{
+ eEthUnsupportedFrame,
+ eEth802LLCFrame,
+ eEth802LLCSNAPFrame,
+ eEth802QVLANFrame,
+ eEthOtherFrame
+} E_NWPKT_ETHFRAME_TYPE;
+
+typedef struct _S_ETHCS_PKT_INFO
+{
+ E_NWPKT_IPFRAME_TYPE eNwpktIPFrameType;
+ E_NWPKT_ETHFRAME_TYPE eNwpktEthFrameType;
+ USHORT usEtherType;
+ UCHAR ucDSAP;
+}S_ETHCS_PKT_INFO,*PS_ETHCS_PKT_INFO;
+
+typedef struct _ETH_CS_802_Q_FRAME
+{
+ ETH_HEADER_STRUC EThHdr;
+ USHORT UserPriority:3;
+ USHORT CFI:1;
+ USHORT VLANID:12;
+ USHORT EthType;
+} __attribute__((packed)) ETH_CS_802_Q_FRAME;
+
+typedef struct _ETH_CS_802_LLC_FRAME
+{
+ ETH_HEADER_STRUC EThHdr;
+ unsigned char DSAP;
+ unsigned char SSAP;
+ unsigned char Control;
+}__attribute__((packed)) ETH_CS_802_LLC_FRAME;
+
+typedef struct _ETH_CS_802_LLC_SNAP_FRAME
+{
+ ETH_HEADER_STRUC EThHdr;
+ unsigned char DSAP;
+ unsigned char SSAP;
+ unsigned char Control;
+ unsigned char OUI[3];
+ unsigned short usEtherType;
+} __attribute__((packed)) ETH_CS_802_LLC_SNAP_FRAME;
+
+typedef struct _ETH_CS_ETH2_FRAME
+{
+ ETH_HEADER_STRUC EThHdr;
+} __attribute__((packed)) ETH_CS_ETH2_FRAME;
+
+
+#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800)
+#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd)
+#define ETHERNET_FRAMETYPE_802QVLAN 0x8100
+//Per SF CS Specification Encodings
+typedef enum _E_SERVICEFLOW_CS_SPEC_
+{
+ eCSSpecUnspecified =0,
+ eCSPacketIPV4,
+ eCSPacketIPV6,
+ eCS802_3PacketEthernet,
+ eCS802_1QPacketVLAN,
+ eCSPacketIPV4Over802_3Ethernet,
+ eCSPacketIPV6Over802_3Ethernet,
+ eCSPacketIPV4Over802_1QVLAN,
+ eCSPacketIPV6Over802_1QVLAN,
+ eCSPacketUnsupported
+}E_SERVICEFLOW_CS_SPEC;
+
+
+#define IP6_HEADER_LEN 40
+
+#define IP_VERSION(byte) (((byte&0xF0)>>4))
+
+
+
+#define MAC_ADDRESS_SIZE 6
+#define ETH_AND_IP_HEADER_LEN 14 + 20
+#define L4_SRC_PORT_LEN 2
+#define L4_DEST_PORT_LEN 2
+
+
+
+#define CTRL_PKT_LEN 8 + ETH_AND_IP_HEADER_LEN
+
+#define ETH_ARP_FRAME 0x806
+#define ETH_IPV4_FRAME 0x800
+#define ETH_IPV6_FRAME 0x86DD
+#define UDP 0x11
+#define TCP 0x06
+
+#define ARP_OP_REQUEST 0x01
+#define ARP_OP_REPLY 0x02
+#define ARP_PKT_SIZE 60
+
+// This is the format for the TCP packet header
+typedef struct _TCP_HEADER
+{
+ USHORT usSrcPort;
+ USHORT usDestPort;
+ ULONG ulSeqNumber;
+ ULONG ulAckNumber;
+ UCHAR HeaderLength;
+ UCHAR ucFlags;
+ USHORT usWindowsSize;
+ USHORT usChkSum;
+ USHORT usUrgetPtr;
+} TCP_HEADER,*PTCP_HEADER;
+#define TCP_HEADER_LEN sizeof(TCP_HEADER)
+#define TCP_ACK 0x10 //Bit 4 in tcpflags field.
+#define GET_TCP_HEADER_LEN(byte) ((byte&0xF0)>>4)
+
+
+#endif //__PROTOCOL_H__
diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h
new file mode 100644
index 000000000000..7718937c5bd9
--- /dev/null
+++ b/drivers/staging/bcm/Prototypes.h
@@ -0,0 +1,323 @@
+#ifndef _PROTOTYPES_H_
+#define _PROTOTYPES_H_
+
+int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
+ char *path, /**< path to image file */
+ unsigned int loc /**< Download Address on the chip*/
+ );
+VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer);
+
+VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer);
+
+VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer);
+
+void bcm_kfree_skb(struct sk_buff *skb);
+VOID bcm_kfree(VOID *ptr);
+
+
+VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
+ struct sk_buff *skb); /**<Pointer to the socket buffer*/
+
+int control_packet_handler (PMINI_ADAPTER Adapter);
+
+VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
+
+VOID flush_all_queues(PMINI_ADAPTER Adapter);
+
+int register_control_device_interface(PMINI_ADAPTER ps_adapter);
+
+void unregister_control_device_interface(PMINI_ADAPTER Adapter);
+
+INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
+ PVOID ioBuffer/**<Control Packet Buffer*/
+ );
+
+VOID SortPackInfo(PMINI_ADAPTER Adapter);
+
+VOID SortClassifiers(PMINI_ADAPTER Adapter);
+
+VOID flush_all_queues(PMINI_ADAPTER Adapter);
+
+USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
+ struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
+ S_CLASSIFIER_RULE *pstClassifierRule );
+
+VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
+ INT iIndex/**<Queue Index*/
+ );
+
+VOID PruneQueueAllSF(PMINI_ADAPTER Adapter);
+
+INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
+
+USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
+ struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
+ );
+
+VOID
+reply_to_arp_request(struct sk_buff *skb /**<sk_buff of ARP request*/
+ );
+
+INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
+ struct sk_buff *Packet, /**<data buffer*/
+ USHORT Vcid) ;
+
+VOID LinkMessage(PMINI_ADAPTER Adapter);
+
+VOID transmit_packets(PMINI_ADAPTER Adapter);
+
+INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
+ char *pControlPacket/**<Control Packet*/
+ );
+
+INT bcm_transmit(struct sk_buff *skb, /**< skb */
+ struct net_device *dev /**< net device pointer */
+ );
+
+int register_networkdev(PMINI_ADAPTER Adapter);
+
+INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
+
+VOID AdapterFree(PMINI_ADAPTER Adapter);
+
+INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
+
+int create_worker_threads(PMINI_ADAPTER psAdapter);
+
+int tx_pkt_handler(PMINI_ADAPTER Adapter);
+
+int reset_card_proc(PMINI_ADAPTER Adapter );
+
+int run_card_proc(PMINI_ADAPTER Adapter );
+
+int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter);
+
+int bcm_parse_target_params(PMINI_ADAPTER Adapter);
+
+INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter);
+
+int register_control_device_interface(PMINI_ADAPTER ps_adapter);
+
+void DumpPackInfo(PMINI_ADAPTER Adapter);
+
+int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
+
+int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
+
+int wrmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+
+int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+
+int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId,
+ PUCHAR user_buffer);
+
+void SendLinkDown(PMINI_ADAPTER Adapter);
+
+void SendIdleModeResponse(PMINI_ADAPTER Adapter);
+
+void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
+
+int ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer,
+ ULONG inputBufferLength);
+
+int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang);
+void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
+
+void doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
+
+int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo);
+
+void bcm_unregister_networkdev(PMINI_ADAPTER Adapter);
+
+int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid);
+
+void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
+ CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);
+
+VOID ResetCounters(PMINI_ADAPTER Adapter);
+
+int InitLedSettings(PMINI_ADAPTER Adapter);
+
+S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP);
+
+void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo);
+
+void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp);
+
+void update_per_cid_rx (PMINI_ADAPTER Adapter);
+
+void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter);
+
+void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
+
+void beceem_protocol_reset (PMINI_ADAPTER Adapter);
+
+void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
+
+
+INT flushAllAppQ(VOID);
+
+
+INT BeceemEEPROMBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+
+INT BeceemFlashBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
+
+INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData);
+
+UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
+
+UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
+
+INT BeceemFlashBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
+
+INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
+
+
+INT BeceemEEPROMBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUCHAR pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+
+INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
+
+INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
+
+NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
+
+INT BeceemNVMRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+INT BeceemNVMWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
+
+INT BcmInitNVM(PMINI_ADAPTER Adapter);
+
+INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
+
+INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
+
+VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
+
+VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter);
+
+INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
+INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd);
+INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
+INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage);
+INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
+B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
+INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
+
+INT BcmFlash2xBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlashSectionVal,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ UINT bVerify);
+
+INT BcmFlash2xBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlashSectionVal,
+ UINT uiOffsetWithinSectionVal,
+ UINT uiNumBytes);
+INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
+
+INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
+
+INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal);
+INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter);
+INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter);
+
+INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut);
+INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
+INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
+INT IsFlash2x(PMINI_ADAPTER Adapter);
+INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
+INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
+INT BcmCopySection(PMINI_ADAPTER Adapter,
+ FLASH2X_SECTION_VAL SrcSection,
+ FLASH2X_SECTION_VAL DstSection,
+ UINT offset,
+ UINT numOfBytes);
+
+INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
+INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset);
+INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
+INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
+FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
+INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
+INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
+FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
+INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
+ PUINT pBuff,
+ FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ UINT uiOffset,
+ UINT uiNumBytes
+ );
+
+//UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType);
+BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
+INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
+INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter);
+
+
+VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer);
+
+int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
+
+int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
+int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
+INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress);
+
+
+VOID putUsbSuspend(struct work_struct *work);
+BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios);
+
+#ifdef BCM_SHM_INTERFACE
+INT beceem_virtual_device_init(void);
+VOID virtual_mail_box_interrupt(void);
+INT beceem_virtual_device_exit(void);
+#endif
+
+#endif
+
+
+
+
diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c
new file mode 100644
index 000000000000..000382511e6c
--- /dev/null
+++ b/drivers/staging/bcm/Qos.c
@@ -0,0 +1,893 @@
+/**
+@file Qos.C
+This file contains the routines related to Quality of Service.
+*/
+#include "headers.h"
+
+BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP);
+BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService);
+BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
+BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort);
+BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
+BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP);
+USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
+void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
+BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
+
+/*******************************************************************
+* Function - MatchSrcIpAddress()
+*
+* Description - Checks whether the Source IP address from the packet
+* matches with that of Queue.
+*
+* Parameters - pstClassifierRule: Pointer to the packet info structure.
+* - ulSrcIP : Source IP address from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL .
+*********************************************************************/
+BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP)
+{
+ UCHAR ucLoopIndex=0;
+
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ ulSrcIP=ntohl(ulSrcIP);
+ if(0 == pstClassifierRule->ucIPSourceAddressLength)
+ return TRUE;
+ for(ucLoopIndex=0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);ucLoopIndex++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT)pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)ulSrcIP, (UINT)pstClassifierRule->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]);
+ if((pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] & ulSrcIP)==
+ (pstClassifierRule->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] ))
+ {
+ return TRUE;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched");
+ return FALSE;
+}
+
+
+/*******************************************************************
+* Function - MatchDestIpAddress()
+*
+* Description - Checks whether the Destination IP address from the packet
+* matches with that of Queue.
+*
+* Parameters - pstClassifierRule: Pointer to the packet info structure.
+* - ulDestIP : Destination IP address from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL .
+*********************************************************************/
+BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP)
+{
+ UCHAR ucLoopIndex=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ ulDestIP=ntohl(ulDestIP);
+ if(0 == pstClassifierRule->ucIPDestinationAddressLength)
+ return TRUE;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT)ulDestIP, (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex]);
+
+ for(ucLoopIndex=0;ucLoopIndex<(pstClassifierRule->ucIPDestinationAddressLength);ucLoopIndex++)
+ {
+ if((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP)==
+ (pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex]))
+ {
+ return TRUE;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched");
+ return FALSE;
+}
+
+
+/************************************************************************
+* Function - MatchTos()
+*
+* Description - Checks the TOS from the packet matches with that of queue.
+*
+* Parameters - pstClassifierRule : Pointer to the packet info structure.
+* - ucTypeOfService: TOS from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL.
+**************************************************************************/
+BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService)
+{
+
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if( 3 != pstClassifierRule->ucIPTypeOfServiceLength )
+ return TRUE;
+
+ if(((pstClassifierRule->ucTosMask & ucTypeOfService)<=pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService)>=pstClassifierRule->ucTosLow))
+ {
+ return TRUE;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched");
+ return FALSE;
+}
+
+
+/***************************************************************************
+* Function - MatchProtocol()
+*
+* Description - Checks the protocol from the packet matches with that of queue.
+*
+* Parameters - pstClassifierRule: Pointer to the packet info structure.
+* - ucProtocol : Protocol from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL.
+****************************************************************************/
+BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol)
+{
+ UCHAR ucLoopIndex=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if(0 == pstClassifierRule->ucProtocolLength)
+ return TRUE;
+ for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucProtocolLength;ucLoopIndex++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol:0x%X Classification Protocol:0x%X",ucProtocol,pstClassifierRule->ucProtocol[ucLoopIndex]);
+ if(pstClassifierRule->ucProtocol[ucLoopIndex]==ucProtocol)
+ {
+ return TRUE;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched");
+ return FALSE;
+}
+
+
+/***********************************************************************
+* Function - MatchSrcPort()
+*
+* Description - Checks, Source port from the packet matches with that of queue.
+*
+* Parameters - pstClassifierRule: Pointer to the packet info structure.
+* - ushSrcPort : Source port from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL.
+***************************************************************************/
+BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort)
+{
+ UCHAR ucLoopIndex=0;
+
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+
+ if(0 == pstClassifierRule->ucSrcPortRangeLength)
+ return TRUE;
+ for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucSrcPortRangeLength;ucLoopIndex++)
+ {
+ if(ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
+ ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
+ {
+ return TRUE;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ",ushSrcPort);
+ return FALSE;
+}
+
+
+/***********************************************************************
+* Function - MatchDestPort()
+*
+* Description - Checks, Destination port from packet matches with that of queue.
+*
+* Parameters - pstClassifierRule: Pointer to the packet info structure.
+* - ushDestPort : Destination port from the packet.
+*
+* Returns - TRUE(If address matches) else FAIL.
+***************************************************************************/
+BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort)
+{
+ UCHAR ucLoopIndex=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ if(0 == pstClassifierRule->ucDestPortRangeLength)
+ return TRUE;
+
+ for(ucLoopIndex=0;ucLoopIndex<pstClassifierRule->ucDestPortRangeLength;ucLoopIndex++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Matching Port:0x%X 0x%X 0x%X",ushDestPort,pstClassifierRule->usDestPortRangeLo[ucLoopIndex],pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
+
+ if(ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
+ ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
+ {
+ return TRUE;
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched",ushDestPort);
+ return FALSE;
+}
+/**
+@ingroup tx_functions
+Compares IPV4 Ip address and port number
+@return Queue Index.
+*/
+USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
+ struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
+ S_CLASSIFIER_RULE *pstClassifierRule )
+{
+ //IPHeaderFormat *pIpHeader=NULL;
+ xporthdr *xprt_hdr=NULL;
+ BOOLEAN bClassificationSucceed=FALSE;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>");
+
+ xprt_hdr=(xporthdr *)((PUCHAR)iphd + sizeof(struct iphdr));
+
+ do {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to see Direction = %d %d",
+ pstClassifierRule->ucDirection,
+ pstClassifierRule->usVCID_Value);
+
+ //Checking classifier validity
+ if(!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR)
+ {
+ bClassificationSucceed = FALSE;
+ break;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!");
+ if(pstClassifierRule->bIpv6Protocol)
+ break;
+
+ //**************Checking IP header parameter**************************//
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address");
+ if(FALSE == (bClassificationSucceed =
+ MatchSrcIpAddress(pstClassifierRule, iphd->saddr)))
+ break;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched");
+
+ if(FALSE == (bClassificationSucceed =
+ MatchDestIpAddress(pstClassifierRule, iphd->daddr)))
+ break;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched");
+
+ if(FALSE == (bClassificationSucceed =
+ MatchTos(pstClassifierRule, iphd->tos)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n");
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched");
+
+ if(FALSE == (bClassificationSucceed =
+ MatchProtocol(pstClassifierRule,iphd->protocol)))
+ break;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched");
+
+ //if protocol is not TCP or UDP then no need of comparing source port and destination port
+ if(iphd->protocol!=TCP && iphd->protocol!=UDP)
+ break;
+#if 0
+ //check if memory is available of src and Dest port
+ if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len)
+ {
+ //This is not an erroneous condition and pkt will be checked for next classification.
+ bClassificationSucceed = FALSE;
+ break;
+ }
+#endif
+ //******************Checking Transport Layer Header field if present *****************//
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
+ (iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source);
+
+ if(FALSE == (bClassificationSucceed =
+ MatchSrcPort(pstClassifierRule,
+ ntohs((iphd->protocol == UDP)?
+ xprt_hdr->uhdr.source:xprt_hdr->thdr.source))))
+ break;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched");
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x",
+ (iphd->protocol==UDP)?xprt_hdr->uhdr.dest:
+ xprt_hdr->thdr.dest);
+ if(FALSE == (bClassificationSucceed =
+ MatchDestPort(pstClassifierRule,
+ ntohs((iphd->protocol == UDP)?
+ xprt_hdr->uhdr.dest:xprt_hdr->thdr.dest))))
+ break;
+ } while(0);
+
+ if(TRUE==bClassificationSucceed)
+ {
+ INT iMatchedSFQueueIndex = 0;
+ iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID);
+ if(iMatchedSFQueueIndex >= NO_OF_QUEUES)
+ {
+ bClassificationSucceed = FALSE;
+ }
+ else
+ {
+ if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
+ {
+ bClassificationSucceed = FALSE;
+ }
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <==========");
+
+ return bClassificationSucceed;
+}
+/**
+@ingroup tx_functions
+@return Queue Index based on priority.
+*/
+USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
+ struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
+ )
+{
+ USHORT usIndex=-1;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "=====>");
+
+ if(NULL==Adapter || NULL==Packet)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======");
+ return -1;
+ }
+
+ usIndex = ClassifyPacket(Adapter,Packet);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <==============");
+ return usIndex;
+}
+
+VOID PruneQueueAllSF(PMINI_ADAPTER Adapter)
+{
+ UINT iIndex = 0;
+
+ for(iIndex = 0; iIndex < HiPriority; iIndex++)
+ {
+ if(!Adapter->PackInfo[iIndex].bValid)
+ continue;
+
+ PruneQueue(Adapter, iIndex);
+ }
+}
+
+
+/**
+@ingroup tx_functions
+This function checks if the max queue size for a queue
+is less than number of bytes in the queue. If so -
+drops packets from the Head till the number of bytes is
+less than or equal to max queue size for the queue.
+*/
+VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
+ INT iIndex/**<Queue Index*/
+ )
+{
+ struct sk_buff* PacketToDrop=NULL;
+ struct net_device_stats* netstats=NULL;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex);
+
+ if(iIndex == HiPriority)
+ return;
+
+ if(!Adapter || (iIndex < 0) || (iIndex > HiPriority))
+ return;
+
+ /* To Store the netdevice statistic */
+ netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
+
+ spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
+
+ while(1)
+// while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost >
+// SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
+ Adapter->PackInfo[iIndex].uiCurrentBytesOnHost,
+ Adapter->PackInfo[iIndex].uiMaxBucketSize);
+
+ PacketToDrop = Adapter->PackInfo[iIndex].FirstTxQueue;
+
+ if(PacketToDrop == NULL)
+ break;
+ if((Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost < SF_MAX_ALLOWED_PACKETS_TO_BACKUP) &&
+ ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb)+SKB_CB_LATENCY_OFFSET))/HZ) <= Adapter->PackInfo[iIndex].uiMaxLatency))
+ break;
+
+ if(PacketToDrop)
+ {
+ if(netstats)
+ netstats->tx_dropped++;
+ atomic_inc(&Adapter->TxDroppedPacketCount);
+ DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
+ Adapter->PackInfo[iIndex].LastTxQueue);
+ /// update current bytes and packets count
+ Adapter->PackInfo[iIndex].uiCurrentBytesOnHost -=
+ PacketToDrop->len;
+ Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost--;
+ /// update dropped bytes and packets counts
+ Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
+ Adapter->PackInfo[iIndex].uiDroppedCountPackets++;
+ bcm_kfree_skb(PacketToDrop);
+
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x",
+ Adapter->PackInfo[iIndex].uiDroppedCountBytes,
+ Adapter->PackInfo[iIndex].uiDroppedCountPackets);
+
+ atomic_dec(&Adapter->TotalPacketCount);
+ Adapter->bcm_jiffies = jiffies;
+ }
+
+ spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "TotalPacketCount:%x",
+ atomic_read(&Adapter->TotalPacketCount));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "<=====");
+}
+
+VOID flush_all_queues(PMINI_ADAPTER Adapter)
+{
+ INT iQIndex;
+ UINT uiTotalPacketLength;
+ struct sk_buff* PacketToDrop=NULL;
+ struct net_device_stats* netstats=NULL;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
+ /* To Store the netdevice statistic */
+ netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
+
+// down(&Adapter->data_packet_queue_lock);
+ for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++)
+ {
+ spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
+ while(Adapter->PackInfo[iQIndex].FirstTxQueue)
+ {
+ PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
+ if(PacketToDrop)
+ {
+ uiTotalPacketLength = PacketToDrop->len;
+ netstats->tx_dropped++;
+ atomic_inc(&Adapter->TxDroppedPacketCount);
+ }
+ else
+ uiTotalPacketLength = 0;
+
+ DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue,
+ Adapter->PackInfo[iQIndex].LastTxQueue);
+
+ /* Free the skb */
+ bcm_kfree_skb(PacketToDrop);
+
+ /// update current bytes and packets count
+ Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength;
+ Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--;
+
+ /// update dropped bytes and packets counts
+ Adapter->PackInfo[iQIndex].uiDroppedCountBytes += uiTotalPacketLength;
+ Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x",
+ Adapter->PackInfo[iQIndex].uiDroppedCountBytes,
+ Adapter->PackInfo[iQIndex].uiDroppedCountPackets);
+ atomic_dec(&Adapter->TotalPacketCount);
+ }
+ spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
+ }
+// up(&Adapter->data_packet_queue_lock);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<=====");
+}
+
+USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb)
+{
+ INT uiLoopIndex=0;
+ S_CLASSIFIER_RULE *pstClassifierRule = NULL;
+ S_ETHCS_PKT_INFO stEthCsPktInfo;
+ PVOID pvEThPayload = NULL;
+ struct iphdr *pIpHeader = NULL;
+ INT uiSfIndex=0;
+ USHORT usIndex=Adapter->usBestEffortQueueIndex;
+ BOOLEAN bFragmentedPkt=FALSE,bClassificationSucceed=FALSE;
+ USHORT usCurrFragment =0;
+
+ PTCP_HEADER pTcpHeader;
+ UCHAR IpHeaderLength;
+ UCHAR TcpHeaderLength;
+
+ pvEThPayload = skb->data;
+ *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = 0;
+ EThCSGetPktInfo(Adapter,pvEThPayload,&stEthCsPktInfo);
+
+ switch(stEthCsPktInfo.eNwpktEthFrameType)
+ {
+ case eEth802LLCFrame:
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLCFrame\n");
+ pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_FRAME);
+ break;
+ }
+
+ case eEth802LLCSNAPFrame:
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLC SNAP Frame\n");
+ pIpHeader = pvEThPayload + sizeof(ETH_CS_802_LLC_SNAP_FRAME);
+ break;
+ }
+ case eEth802QVLANFrame:
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802.1Q VLANFrame\n");
+ pIpHeader = pvEThPayload + sizeof(ETH_CS_802_Q_FRAME);
+ break;
+ }
+ case eEthOtherFrame:
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : ETH Other Frame\n");
+ pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME);
+ break;
+ }
+ default:
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Unrecognized ETH Frame\n");
+ pIpHeader = pvEThPayload + sizeof(ETH_CS_ETH2_FRAME);
+ break;
+ }
+ }
+
+ if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
+ {
+ usCurrFragment = (ntohs(pIpHeader->frag_off) & IP_OFFSET);
+ if((ntohs(pIpHeader->frag_off) & IP_MF) || usCurrFragment)
+ bFragmentedPkt = TRUE;
+
+ if(bFragmentedPkt)
+ {
+ //Fragmented Packet. Get Frag Classifier Entry.
+ pstClassifierRule = GetFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr);
+ if(pstClassifierRule)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"It is next Fragmented pkt");
+ bClassificationSucceed=TRUE;
+ }
+ if(!(ntohs(pIpHeader->frag_off) & IP_MF))
+ {
+ //Fragmented Last packet . Remove Frag Classifier Entry
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,"This is the last fragmented Pkt");
+ DelFragIPClsEntry(Adapter,pIpHeader->id, pIpHeader->saddr);
+ }
+ }
+ }
+
+ for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--)
+ {
+ if (Adapter->device_removed)
+ {
+ bClassificationSucceed = FALSE;
+ break;
+ }
+
+ if(bClassificationSucceed)
+ break;
+ //Iterate through all classifiers which are already in order of priority
+ //to classify the packet until match found
+ do
+ {
+ if(FALSE==Adapter->astClassifierTable[uiLoopIndex].bUsed)
+ {
+ bClassificationSucceed=FALSE;
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n",uiLoopIndex);
+
+ if(0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection)
+ {
+ bClassificationSucceed=FALSE;//cannot be processed for classification.
+ break; // it is a down link connection
+ }
+
+ pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
+
+ uiSfIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID);
+ if(uiSfIndex > NO_OF_QUEUES)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Queue Not Valid. SearchSfid for this classifier Failed\n");
+ break;
+ }
+
+ if(Adapter->PackInfo[uiSfIndex].bEthCSSupport)
+ {
+
+ if(eEthUnsupportedFrame==stEthCsPktInfo.eNwpktEthFrameType)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame \n");
+ bClassificationSucceed = FALSE;
+ break;
+ }
+
+
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",pstClassifierRule->uiClassifierRuleIndex,Adapter->PackInfo[uiSfIndex].ulSFID);
+ bClassificationSucceed = EThCSClassifyPkt(Adapter,skb,&stEthCsPktInfo,pstClassifierRule, Adapter->PackInfo[uiSfIndex].bEthCSSupport);
+
+ if(!bClassificationSucceed)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n");
+ break;
+ }
+ }
+
+ else // No ETH Supported on this SF
+ {
+ if(eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF \n");
+ bClassificationSucceed = FALSE;
+ break;
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification");
+
+ if(Adapter->PackInfo[uiSfIndex].bIPCSSupport)
+ {
+
+ if(stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet \n");
+ bClassificationSucceed = FALSE;
+ break;
+ }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header : \n");
+ DumpFullPacket((PUCHAR)pIpHeader,20);
+
+ if(stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
+ bClassificationSucceed = IpVersion4(Adapter,pIpHeader,pstClassifierRule);
+ else if(stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
+ bClassificationSucceed = IpVersion6(Adapter,pIpHeader,pstClassifierRule);
+ }
+
+ }while(0);
+ }
+
+ if(bClassificationSucceed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu",pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID);
+
+ //Store The matched Classifier in SKB
+ *((UINT32*)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = pstClassifierRule->uiClassifierRuleIndex;
+ if((TCP == pIpHeader->protocol ) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len) )
+ {
+ IpHeaderLength = pIpHeader->ihl;
+ pTcpHeader = (PTCP_HEADER)(((PUCHAR)pIpHeader)+(IpHeaderLength*4));
+ TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
+
+ if((pTcpHeader->ucFlags & TCP_ACK) &&
+ (ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4)))
+ {
+ *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET ) = TCP_ACK;
+ }
+ }
+
+ usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex);
+
+ //If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt.
+ if(bFragmentedPkt && (usCurrFragment == 0))
+ {
+ //First Fragment of Fragmented Packet. Create Frag CLS Entry
+ S_FRAGMENTED_PACKET_INFO stFragPktInfo;
+ stFragPktInfo.bUsed = TRUE;
+ stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
+ stFragPktInfo.usIpIdentification = pIpHeader->id;
+ stFragPktInfo.pstMatchedClassifierEntry = pstClassifierRule;
+ stFragPktInfo.bOutOfOrderFragment = FALSE;
+ AddFragIPClsEntry(Adapter,&stFragPktInfo);
+ }
+
+
+ }
+
+ if(bClassificationSucceed)
+ return usIndex;
+ else
+ return INVALID_QUEUE_INDEX;
+}
+
+BOOLEAN EthCSMatchSrcMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac)
+{
+ UINT i=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if(pstClassifierRule->ucEthCSSrcMACLen==0)
+ return TRUE;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__);
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSSrcMAC[i],pstClassifierRule->au8EThCSSrcMACMask[i]);
+ if((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i])!=
+ (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOLEAN EthCSMatchDestMACAddress(S_CLASSIFIER_RULE *pstClassifierRule,PUCHAR Mac)
+{
+ UINT i=0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if(pstClassifierRule->ucEthCSDestMACLen==0)
+ return TRUE;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s \n",__FUNCTION__);
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",i,Mac[i],pstClassifierRule->au8EThCSDestMAC[i],pstClassifierRule->au8EThCSDestMACMask[i]);
+ if((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i])!=
+ (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOLEAN EthCSMatchEThTypeSAP(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo)
+{
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ if((pstClassifierRule->ucEtherTypeLen==0)||
+ (pstClassifierRule->au8EthCSEtherType[0] == 0))
+ return TRUE;
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s SrcEtherType:%x CLS EtherType[0]:%x\n",__FUNCTION__,pstEthCsPktInfo->usEtherType,pstClassifierRule->au8EthCSEtherType[0]);
+ if(pstClassifierRule->au8EthCSEtherType[0] == 1)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS EtherType[1]:%x EtherType[2]:%x\n",__FUNCTION__,pstClassifierRule->au8EthCSEtherType[1],pstClassifierRule->au8EthCSEtherType[2]);
+
+ if(memcmp(&pstEthCsPktInfo->usEtherType,&pstClassifierRule->au8EthCSEtherType[1],2)==0)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if(pstClassifierRule->au8EthCSEtherType[0] == 2)
+ {
+ if(eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
+ return FALSE;
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s EthCS DSAP:%x EtherType[2]:%x\n",__FUNCTION__,pstEthCsPktInfo->ucDSAP,pstClassifierRule->au8EthCSEtherType[2]);
+ if(pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2])
+ return TRUE;
+ else
+ return FALSE;
+
+ }
+
+ return FALSE;
+
+}
+
+BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo)
+{
+ BOOLEAN bClassificationSucceed = FALSE;
+ USHORT usVLANID;
+ B_UINT8 uPriority = 0;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__,ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),pstClassifierRule->usVLANID);
+
+ /* In case FW didn't recieve the TLV, the priority field should be ignored */
+ if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID))
+ {
+ if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame)
+ return FALSE;
+
+ uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xF000) >> 13;
+
+ if((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1]))
+ bClassificationSucceed = TRUE;
+
+ if(!bClassificationSucceed)
+ return FALSE;
+ }
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 D User Priority Rule Matched\n");
+
+ bClassificationSucceed = FALSE;
+
+ if(pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID))
+ {
+ if(pstEthCsPktInfo->eNwpktEthFrameType!=eEth802QVLANFrame)
+ return FALSE;
+
+ usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(ETH_HEADER_STRUC))) & 0xFFF;
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n",__FUNCTION__,usVLANID, uPriority);
+
+ if(usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4))
+ bClassificationSucceed = TRUE;
+
+ if(!bClassificationSucceed)
+ return FALSE;
+ }
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 Q VLAN ID Rule Matched\n");
+
+ return TRUE;
+}
+
+
+BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport)
+{
+ BOOLEAN bClassificationSucceed = FALSE;
+ bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress);
+ if(!bClassificationSucceed)
+ return FALSE;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n");
+
+ bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,((ETH_HEADER_STRUC*)(skb->data))->au8DestinationAddress);
+ if(!bClassificationSucceed)
+ return FALSE;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n");
+
+ //classify on ETHType/802.2SAP TLV
+ bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,skb,pstEthCsPktInfo);
+ if(!bClassificationSucceed)
+ return FALSE;
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS EthType/802.2SAP Matched\n");
+
+ //classify on 802.1VLAN Header Parameters
+
+ bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,skb,pstEthCsPktInfo);
+ if(!bClassificationSucceed)
+ return FALSE;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 VLAN Rules Matched\n");
+
+ return bClassificationSucceed;
+}
+
+void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo)
+{
+ USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype);
+ if(u16Etype > 0x5dc)
+ {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame \n");
+ //ETH2 Frame
+ if(u16Etype == ETHERNET_FRAMETYPE_802QVLAN)
+ {
+ //802.1Q VLAN Header
+ pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame;
+ u16Etype = ((ETH_CS_802_Q_FRAME*)pvEthPayload)->EthType;
+ //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
+ }
+ else
+ {
+ pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
+ u16Etype = ntohs(u16Etype);
+ }
+
+ }
+ else
+ {
+ //802.2 LLC
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "802.2 LLC Frame \n");
+ pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame;
+ pstEthCsPktInfo->ucDSAP = ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->DSAP;
+ if(pstEthCsPktInfo->ucDSAP == 0xAA && ((ETH_CS_802_LLC_FRAME*)pvEthPayload)->SSAP == 0xAA)
+ {
+ //SNAP Frame
+ pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
+ u16Etype = ((ETH_CS_802_LLC_SNAP_FRAME*)pvEthPayload)->usEtherType;
+ }
+ }
+ if(u16Etype == ETHERNET_FRAMETYPE_IPV4)
+ pstEthCsPktInfo->eNwpktIPFrameType = eIPv4Packet;
+ else if(u16Etype == ETHERNET_FRAMETYPE_IPV6)
+ pstEthCsPktInfo->eNwpktIPFrameType = eIPv6Packet;
+ else
+ pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket;
+
+ pstEthCsPktInfo->usEtherType = ((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype;
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktIPFrameType : %x\n",pstEthCsPktInfo->eNwpktIPFrameType);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktEthFrameType : %x\n",pstEthCsPktInfo->eNwpktEthFrameType);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->usEtherType : %x\n",pstEthCsPktInfo->usEtherType);
+}
+
+
+
diff --git a/drivers/staging/bcm/Queue.h b/drivers/staging/bcm/Queue.h
new file mode 100644
index 000000000000..e1f1da2bb6d4
--- /dev/null
+++ b/drivers/staging/bcm/Queue.h
@@ -0,0 +1,31 @@
+/*************************************
+* Queue.h
+**************************************/
+#ifndef __QUEUE_H__
+#define __QUEUE_H__
+
+
+
+#define ENQUEUEPACKET(_Head, _Tail,_Packet) \
+do \
+{ \
+ if (!_Head) { \
+ _Head = _Packet; \
+ } \
+ else { \
+ (_Tail)->next = _Packet; \
+ } \
+ (_Packet)->next = NULL; \
+ _Tail = _Packet; \
+}while(0)
+#define DEQUEUEPACKET(Head, Tail ) \
+do \
+{ if(Head) \
+ { \
+ if (!Head->next) { \
+ Tail = NULL; \
+ } \
+ Head = Head->next; \
+ } \
+}while(0)
+#endif //__QUEUE_H__
diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO
new file mode 100644
index 000000000000..366634be5fe1
--- /dev/null
+++ b/drivers/staging/bcm/TODO
@@ -0,0 +1,15 @@
+TODO:
+ - fix non-standard kernel style
+ - sparse warnings
+ - checkpatch warnings
+ - remove compatiablity code for older kernels
+ - remove #ifdef's
+ - fix bogus device nameing and reference counting (see bcm_notify_event)
+ - fix use of file I/O to load config
+ - request firmware
+ - update to current network device API
+ - merge some files together
+ - cleanup/eliminate debug messages
+
+ - integrate with existing Wimax stack?
+
diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c
new file mode 100644
index 000000000000..9a076b54324f
--- /dev/null
+++ b/drivers/staging/bcm/Transmit.c
@@ -0,0 +1,553 @@
+/**
+@file Transmit.c
+@defgroup tx_functions Transmission
+@section Queueing
+@dot
+digraph transmit1 {
+node[shape=box]
+edge[weight=5;color=red]
+bcm_transmit->reply_to_arp_request[label="ARP"]
+bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
+GetPacketQueueIndex->IpVersion4[label="IPV4"]
+GetPacketQueueIndex->IpVersion6[label="IPV6"]
+}
+
+@enddot
+
+@section De-Queueing
+@dot
+digraph transmit2 {
+node[shape=box]
+edge[weight=5;color=red]
+interrupt_service_thread->transmit_packets
+tx_pkt_hdler->transmit_packets
+transmit_packets->CheckAndSendPacketFromIndex
+transmit_packets->UpdateTokenCount
+CheckAndSendPacketFromIndex->PruneQueue
+CheckAndSendPacketFromIndex->IsPacketAllowedForFlow
+CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"]
+SendControlPacket->bcm_cmd53
+CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"]
+SendPacketFromQueue->SetupNextSend->bcm_cmd53
+}
+@enddot
+*/
+
+#include "headers.h"
+
+/*******************************************************************
+* Function - bcm_transmit()
+*
+* Description - This is the main transmit function for our virtual
+* interface(veth0). It handles the ARP packets. It
+* clones this packet and then Queue it to a suitable
+* Queue. Then calls the transmit_packet().
+*
+* Parameter - skb - Pointer to the socket buffer structure
+* dev - Pointer to the virtual net device structure
+*
+* Returns - zero (success) or -ve value (failure)
+*
+*********************************************************************/
+
+INT bcm_transmit(struct sk_buff *skb, /**< skb */
+ struct net_device *dev /**< net device pointer */
+ )
+{
+ PMINI_ADAPTER Adapter = NULL;
+ USHORT qindex=0;
+ struct timeval tv;
+ UINT pkt_type = 0;
+ UINT calltransmit = 0;
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
+
+ memset(&tv, 0, sizeof(tv));
+ /* Check for valid parameters */
+ if(skb == NULL || dev==NULL)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
+ return -EINVAL;
+ }
+
+ Adapter = GET_BCM_ADAPTER(dev);
+ if(!Adapter)
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
+ return -EINVAL;
+ }
+ if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
+ {
+ if(!netif_queue_stopped(dev)) {
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
+ }
+ return STATUS_FAILURE;
+ }
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
+
+ /*Add Ethernet CS check here*/
+ if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
+ {
+ pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
+ /* Get the queue index where the packet is to be queued */
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
+
+ qindex = GetPacketQueueIndex(Adapter,skb);
+
+ if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
+ {
+ if(pkt_type == ETH_ARP_FRAME)
+ {
+ /*
+ Reply directly to ARP request packet
+ ARP Spoofing only if NO ETH CS rule matches for it
+ */
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",
+
+ (*(PUCHAR)(skb->data + 21)));
+
+ reply_to_arp_request(skb);
+
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
+
+ }
+ else
+ {
+ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
+ "Invalid queue index, dropping pkt\n");
+
+ bcm_kfree_skb(skb);
+ }
+ return STATUS_SUCCESS;
+ }
+
+ if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
+ {
+ atomic_inc(&Adapter->TxDroppedPacketCount);
+ bcm_kfree_skb(skb);
+ return STATUS_SUCCESS;
+ }
+
+ /* Now Enqueue the packet */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
+ spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
+ Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
+ Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
+
+ *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
+ ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
+ Adapter->PackInfo[qindex].LastTxQueue, skb);
+ atomic_inc(&Adapter->TotalPacketCount);
+ spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
+ do_gettimeofday(&tv);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
+ (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);
+
+#ifdef BCM_SHM_INTERFACE
+ spin_lock(&Adapter->txtransmitlock);
+ if(Adapter->txtransmit_running == 0)
+ {
+ Adapter->txtransmit_running = 1;
+ calltransmit = 1;
+ }
+ else
+ calltransmit = 0;
+
+ spin_unlock(&Adapter->txtransmitlock);
+#endif
+ if(calltransmit == 1)
+ transmit_packets(Adapter);
+ else
+ {
+ if(!atomic_read(&Adapter->TxPktAvail))
+ {
+ atomic_set(&Adapter->TxPktAvail, 1);
+#ifdef BCM_SHM_INTERFACE
+ virtual_mail_box_interrupt();
+#endif
+ wake_up(&Adapter->tx_packet_wait_queue);
+ }
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
+ }
+ else
+ bcm_kfree_skb(skb);
+
+ return STATUS_SUCCESS;
+}
+
+
+/**
+@ingroup ctrl_pkt_functions
+This function dispatches control packet to the h/w interface
+@return zero(success) or -ve value(failure)
+*/
+INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
+ char *pControlPacket/**<Control Packet*/
+ )
+{
+ PLEADER PLeader = NULL;
+ struct timeval tv;
+ memset(&tv, 0, sizeof(tv));
+
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
+
+ PLeader=(PLEADER)pControlPacket;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
+ if(!pControlPacket || !Adapter)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter");
+ return STATUS_FAILURE;
+ }
+ if((atomic_read( &Adapter->CurrNumFreeTxDesc ) <
+ ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
+ if(Adapter->bcm_jiffies == 0)
+ {
+ Adapter->bcm_jiffies = jiffies;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
+ Adapter->bcm_jiffies);
+ }
+ return STATUS_FAILURE;
+ }
+
+ /* Update the netdevice statistics */
+ /* Dump Packet */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x",PLeader->Vcid);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
+ if(Adapter->device_removed)
+ return 0;
+#ifndef BCM_SHM_INTERFACE
+ Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
+ pControlPacket, (PLeader->PLength + LEADER_SIZE));
+#else
+ tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1);
+
+ if(PLeader->Status==IDLE_MESSAGE)
+ {
+ if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD &&
+ ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n");
+ do_gettimeofday(&tv);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
+ if(Adapter->bDoSuspend != TRUE)
+ {
+ Adapter->IdleMode = TRUE;
+ Adapter->bPreparingForLowPowerMode = FALSE ;
+ }
+ }
+ }
+ if((PLeader->Status == LINK_UP_CONTROL_REQ) &&
+ ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK &&
+ ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] ==
+ LINK_SHUTDOWN_REQ_FROM_FIRMWARE &&
+ ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n");
+ if(Adapter->bDoSuspend != TRUE)
+ {
+ Adapter->bShutStatus = TRUE;
+ Adapter->bPreparingForLowPowerMode = FALSE;
+ Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
+ }
+
+ }
+#endif
+
+ ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++;
+ ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+=
+ PLeader->PLength;
+ atomic_dec(&Adapter->CurrNumFreeTxDesc);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
+ return STATUS_SUCCESS;
+}
+static LEADER Leader={0};
+/**
+@ingroup tx_functions
+This function despatches the IP packets with the given vcid
+to the target via the host h/w interface.
+@return zero(success) or -ve value(failure)
+*/
+INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
+ struct sk_buff *Packet, /**<data buffer*/
+ USHORT Vcid) /**<VCID for this packet*/
+{
+ int status=0;
+ int dontfree = 0;
+ BOOLEAN bHeaderSupressionEnabled = FALSE;
+ B_UINT16 uiClassifierRuleID;
+ int QueueIndex = NO_OF_QUEUES + 1;
+
+ if(!Adapter || !Packet)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
+ return -EINVAL;
+ }
+ if(Packet->len > MAX_DEVICE_DESC_SIZE)
+ {
+ status = STATUS_FAILURE;
+ goto errExit;
+ }
+
+ /* Get the Classifier Rule ID */
+ uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
+ QueueIndex = SearchVcid( Adapter,Vcid);
+ if(QueueIndex < NO_OF_QUEUES)
+ {
+ bHeaderSupressionEnabled =
+ Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
+ bHeaderSupressionEnabled =
+ bHeaderSupressionEnabled & Adapter->bPHSEnabled;
+ }
+ if(Adapter->device_removed)
+ {
+ status = STATUS_FAILURE;
+ goto errExit;
+ }
+
+ status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
+ (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
+
+ if(status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n");
+ goto errExit;
+ }
+
+ Leader.Vcid = Vcid;
+
+ if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
+ Leader.Status = LEADER_STATUS_TCP_ACK;
+ }
+ else
+ {
+ Leader.Status = LEADER_STATUS;
+ }
+
+ if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
+ {
+ Leader.PLength = Packet->len;
+ if(skb_headroom(Packet) < LEADER_SIZE)
+ {
+ if((status = skb_cow(Packet,LEADER_SIZE)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"bcm_transmit : Failed To Increase headRoom\n");
+ goto errExit;
+ }
+ }
+ skb_push(Packet, LEADER_SIZE);
+ memcpy(Packet->data, &Leader, LEADER_SIZE);
+ }
+
+ else
+ {
+ Leader.PLength = Packet->len - ETH_HLEN;
+ memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);
+
+#ifndef BCM_SHM_INTERFACE
+ status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
+ Packet->data, (Leader.PLength + LEADER_SIZE));
+#else
+ status = tx_pkts_to_firmware(Packet,Packet->len,0);
+#endif
+ if(status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
+ }
+ else
+ {
+ Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
+ atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
+ atomic_inc(&Adapter->TxTotalPacketCount);
+#ifdef GDMA_INTERFACE
+ dontfree = 1;
+#endif
+ }
+
+ atomic_dec(&Adapter->CurrNumFreeTxDesc);
+
+errExit:
+
+ if(STATUS_SUCCESS == status)
+ {
+ Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
+ Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
+ Adapter->PackInfo[QueueIndex].uiSentPackets++;
+ Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
+
+ atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
+#ifdef BCM_SHM_INTERFACE
+ if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
+ {
+ atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
+ }
+#endif
+ Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
+ }
+
+
+#ifdef GDMA_INTERFACE
+ if(!dontfree){
+ bcm_kfree_skb(Packet);
+ }
+#else
+ bcm_kfree_skb(Packet);
+#endif
+ return status;
+}
+
+/**
+@ingroup tx_functions
+Transmit thread
+*/
+int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
+ )
+{
+#ifndef BCM_SHM_INTERFACE
+ int status = 0;
+#endif
+
+ UINT calltransmit = 1;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = 0x%x",(unsigned int) Adapter);
+
+
+ while(1)
+ {
+ if(Adapter->LinkUpStatus){
+ wait_event_timeout(Adapter->tx_packet_wait_queue,
+ ((atomic_read(&Adapter->TxPktAvail) &&
+ (MINIMUM_PENDING_DESCRIPTORS <
+ atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
+ (Adapter->device_removed == FALSE))) ||
+ (1 == Adapter->downloadDDR) || kthread_should_stop()
+#ifndef BCM_SHM_INTERFACE
+ || (TRUE == Adapter->bEndPointHalted)
+#endif
+ , msecs_to_jiffies(10));
+ }
+ else{
+ wait_event(Adapter->tx_packet_wait_queue,
+ ((atomic_read(&Adapter->TxPktAvail) &&
+ (MINIMUM_PENDING_DESCRIPTORS <
+ atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
+ (Adapter->device_removed == FALSE))) ||
+ (1 == Adapter->downloadDDR) || kthread_should_stop()
+#ifndef BCM_SHM_INTERFACE
+ || (TRUE == Adapter->bEndPointHalted)
+#endif
+ );
+ }
+
+ if(kthread_should_stop() || Adapter->device_removed)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
+ Adapter->transmit_packet_thread = NULL;
+ return 0;
+ }
+
+#ifndef BCM_SHM_INTERFACE
+
+ if(Adapter->downloadDDR == 1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n");
+ Adapter->downloadDDR +=1;
+ status = download_ddr_settings(Adapter);
+ if(status)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n");
+ continue;
+ }
+
+ //Check end point for halt/stall.
+ if(Adapter->bEndPointHalted == TRUE)
+ {
+ Bcm_clear_halt_of_endpoints(Adapter);
+ Adapter->bEndPointHalted = FALSE;
+ StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
+ }
+
+ if(Adapter->LinkUpStatus && !Adapter->IdleMode)
+ {
+ if(atomic_read(&Adapter->TotalPacketCount))
+ {
+ update_per_sf_desc_cnts(Adapter);
+ }
+ }
+#endif
+
+ if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
+ Adapter->LinkStatus == SYNC_UP_REQUEST &&
+ !Adapter->bSyncUpRequestSent)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage");
+ LinkMessage(Adapter);
+ }
+
+ if((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up");
+ Adapter->usIdleModePattern = ABORT_IDLE_MODE;
+ Adapter->bWakeUpDevice = TRUE;
+ wake_up(&Adapter->process_rx_cntrlpkt);
+ }
+
+#ifdef BCM_SHM_INTERFACE
+ spin_lock_bh(&Adapter->txtransmitlock);
+ if(Adapter->txtransmit_running == 0)
+ {
+ Adapter->txtransmit_running = 1;
+ calltransmit = 1;
+ }
+ else
+ calltransmit = 0;
+ spin_unlock_bh(&Adapter->txtransmitlock);
+#endif
+
+ if(calltransmit)
+ transmit_packets(Adapter);
+
+ atomic_set(&Adapter->TxPktAvail, 0);
+ }
+ return 0;
+}
+
+#ifdef BCM_SHM_INTERFACE
+extern PMINI_ADAPTER psAdaptertest;
+void virtual_mail_box_interrupt(void)
+{
+
+#ifndef GDMA_INTERFACE
+ PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG;
+ UINT intval = (UINT)((*ptr & 0xFF00) >> 8);
+ if (intval != 0)
+ {
+ atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval);
+ atomic_set (&psAdaptertest->uiMBupdate, TRUE);
+
+ //make it to 0
+ *ptr = *ptr & 0xffff00ff;
+ }
+#endif
+}
+unsigned int total_tx_pkts_pending(void)
+{
+ return atomic_read(&psAdaptertest->TotalPacketCount);
+}
+
+#endif
+
+
diff --git a/drivers/staging/bcm/Typedefs.h b/drivers/staging/bcm/Typedefs.h
new file mode 100644
index 000000000000..a985abf194fd
--- /dev/null
+++ b/drivers/staging/bcm/Typedefs.h
@@ -0,0 +1,47 @@
+/****************************
+* Typedefs.h
+****************************/
+#ifndef __TYPEDEFS_H__
+#define __TYPEDEFS_H__
+#define STATUS_SUCCESS 0
+#define STATUS_FAILURE -1
+
+#define FALSE 0
+#define TRUE 1
+
+typedef char BOOLEAN;
+typedef char CHAR;
+typedef int INT;
+typedef short SHORT;
+typedef long LONG;
+typedef void VOID;
+
+typedef unsigned char UCHAR;
+typedef unsigned char B_UINT8;
+typedef unsigned short USHORT;
+typedef unsigned short B_UINT16;
+typedef unsigned int UINT;
+typedef unsigned int B_UINT32;
+typedef unsigned long ULONG;
+typedef unsigned long DWORD;
+
+typedef char* PCHAR;
+typedef short* PSHORT;
+typedef int* PINT;
+typedef long* PLONG;
+typedef void* PVOID;
+
+typedef unsigned char* PUCHAR;
+typedef unsigned short* PUSHORT;
+typedef unsigned int* PUINT;
+typedef unsigned long* PULONG;
+typedef unsigned long long ULONG64;
+typedef unsigned long long LARGE_INTEGER;
+typedef unsigned int UINT32;
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+#endif //__TYPEDEFS_H__
+
diff --git a/drivers/staging/bcm/Version.h b/drivers/staging/bcm/Version.h
new file mode 100644
index 000000000000..a07b956b9ff5
--- /dev/null
+++ b/drivers/staging/bcm/Version.h
@@ -0,0 +1,35 @@
+
+/*Copyright (c) 2005 Beceem Communications Inc.
+
+Module Name:
+
+ Version.h
+
+Abstract:
+
+
+--*/
+
+#ifndef VERSION_H
+#define VERSION_H
+
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_NETWORK
+
+
+#define VER_FILEVERSION 5.2.45
+#define VER_FILEVERSION_STR "5.2.45"
+
+#undef VER_PRODUCTVERSION
+#define VER_PRODUCTVERSION VER_FILEVERSION
+
+#undef VER_PRODUCTVERSION_STR
+#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
+
+
+
+
+//#include "common.ver"
+
+#endif //VERSION_H
diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h
new file mode 100644
index 000000000000..4cbe30022248
--- /dev/null
+++ b/drivers/staging/bcm/cntrl_SignalingInterface.h
@@ -0,0 +1,677 @@
+#ifndef CNTRL_SIGNALING_INTERFACE_
+#define CNTRL_SIGNALING_INTERFACE_
+
+
+#ifdef BECEEM_TARGET
+
+#include <mac_common.h>
+#include <msg_Dsa.h>
+#include <msg_Dsc.h>
+#include <msg_Dsd.h>
+#include <sch_definitions.h>
+using namespace Beceem;
+#ifdef ENABLE_CORRIGENDUM2_UPDATE
+extern B_UINT32 g_u32Corr2MacFlags;
+#endif
+
+#else
+
+
+#define DSA_REQ 11
+#define DSA_RSP 12
+#define DSA_ACK 13
+#define DSC_REQ 14
+#define DSC_RSP 15
+#define DSC_ACK 16
+#define DSD_REQ 17
+#define DSD_RSP 18
+#define DSD_ACK 19
+#define MAX_CLASSIFIERS_IN_SF 4
+
+#endif
+
+#define MAX_STRING_LEN 20
+#define MAX_PHS_LENGTHS 255
+#define VENDOR_PHS_PARAM_LENGTH 10
+#define MAX_NUM_ACTIVE_BS 10
+#define AUTH_TOKEN_LENGTH 10
+#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accomodate all HARQ channels
+#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it
+#define VENDOR_SPECIF_QOS_PARAM 1
+#define VENDOR_PHS_PARAM_LENGTH 10
+#define MBS_CONTENTS_ID_LENGTH 10
+#define GLOBAL_SF_CLASSNAME_LENGTH 6
+
+#define TYPE_OF_SERVICE_LENGTH 3
+#define IP_MASKED_SRC_ADDRESS_LENGTH 32
+#define IP_MASKED_DEST_ADDRESS_LENGTH 32
+#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4
+#define PROTOCOL_DEST_PORT_RANGE_LENGTH 4
+#define ETHERNET_DEST_MAC_ADDR_LENGTH 12
+#define ETHERNET_SRC_MAC_ADDR_LENGTH 12
+#define NUM_ETHERTYPE_BYTES 3
+#define NUM_IPV6_FLOWLABLE_BYTES 3
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////structure Definitions///////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/// \brief class cCPacketClassificationRule
+#ifdef BECEEM_TARGET
+class CCPacketClassificationRuleSI{
+ public:
+ /// \brief Constructor for the class
+ CCPacketClassificationRuleSI():
+ u8ClassifierRulePriority(mClassifierRulePriority),
+ u8IPTypeOfServiceLength(mIPTypeOfService),
+ u8Protocol(mProtocol),
+ u8IPMaskedSourceAddressLength(0),
+ u8IPDestinationAddressLength(0),
+ u8ProtocolSourcePortRangeLength(0),
+ u8ProtocolDestPortRangeLength(0),
+ u8EthernetDestMacAddressLength(0),
+ u8EthernetSourceMACAddressLength(0),
+ u8EthertypeLength(0),
+ u16UserPriority(mUserPriority),
+ u16VLANID(mVLANID),
+ u8AssociatedPHSI(mAssociatedPHSI),
+ u16PacketClassificationRuleIndex(mPacketClassifierRuleIndex),
+ u8VendorSpecificClassifierParamLength(mVendorSpecificClassifierParamLength),
+ u8IPv6FlowLableLength(mIPv6FlowLableLength),
+ u8ClassifierActionRule(mClassifierActionRule)
+
+ {}
+ void Reset()
+ {
+ CCPacketClassificationRuleSI();
+ }
+#else
+struct _stCPacketClassificationRuleSI{
+#endif
+
+ /** 16bit UserPriority Of The Service Flow*/
+ B_UINT16 u16UserPriority;
+ /** 16bit VLANID Of The Service Flow*/
+ B_UINT16 u16VLANID;
+ /** 16bit Packet Classification RuleIndex Of The Service Flow*/
+ B_UINT16 u16PacketClassificationRuleIndex;
+ /** 8bit Classifier Rule Priority Of The Service Flow*/
+ B_UINT8 u8ClassifierRulePriority;
+ /** Length of IP TypeOfService field*/
+ B_UINT8 u8IPTypeOfServiceLength;
+ /** 3bytes IP TypeOfService */
+ B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
+ /** Protocol used in classification of Service Flow*/
+ B_UINT8 u8Protocol;
+ /** Length of IP Masked Source Address */
+ B_UINT8 u8IPMaskedSourceAddressLength;
+ /** IP Masked Source Address used in classification for the Service Flow*/
+ B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
+ /** Length of IP Destination Address */
+ B_UINT8 u8IPDestinationAddressLength;
+ /** IP Destination Address used in classification for the Service Flow*/
+ B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
+ /** Length of Protocol Source Port Range */
+ B_UINT8 u8ProtocolSourcePortRangeLength;
+ /** Protocol Source Port Range used in the Service Flow*/
+ B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
+ /** Length of Protocol Dest Port Range */
+ B_UINT8 u8ProtocolDestPortRangeLength;
+ /** Protocol Dest Port Range used in the Service Flow*/
+ B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
+ /** Length of Ethernet Destination MAC Address */
+ B_UINT8 u8EthernetDestMacAddressLength;
+ /** Ethernet Destination MAC Address used in classification of the Service Flow*/
+ B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
+ /** Length of Ethernet Source MAC Address */
+ B_UINT8 u8EthernetSourceMACAddressLength;
+ /** Ethernet Source MAC Address used in classification of the Service Flow*/
+ B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
+ /** Length of Ethertype */
+ B_UINT8 u8EthertypeLength;
+ /** 3bytes Ethertype Of The Service Flow*/
+ B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];
+ /** 8bit Associated PHSI Of The Service Flow*/
+ B_UINT8 u8AssociatedPHSI;
+ /** Length of Vendor Specific Classifier Param length Of The Service Flow*/
+ B_UINT8 u8VendorSpecificClassifierParamLength;
+ /** Vendor Specific Classifier Param Of The Service Flow*/
+ B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
+ /** Length Of IPv6 Flow Lable of the Service Flow*/
+ B_UINT8 u8IPv6FlowLableLength;
+ /** IPv6 Flow Lable Of The Service Flow*/
+ B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
+ /** Action associated with the classifier rule*/
+ B_UINT8 u8ClassifierActionRule;
+ B_UINT16 u16ValidityBitMap;
+};
+#ifndef BECEEM_TARGET
+typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
+#endif
+
+/// \brief class CPhsRuleSI
+#ifdef BECEEM_TARGET
+class CPhsRuleSI{
+ public:
+ /// \brief Constructor for the class
+ CPhsRuleSI():
+ u8PHSI(mPHSI),
+ u8PHSFLength(0),
+ u8PHSMLength(0),
+ u8PHSS(mPHSS),
+ u8PHSV(mPHSV),
+ u8VendorSpecificPHSParamsLength(mVendorSpecificPHSParamLength){}
+ void Reset()
+ {
+ CPhsRuleSI();
+ }
+#else
+typedef struct _stPhsRuleSI {
+#endif
+ /** 8bit PHS Index Of The Service Flow*/
+ B_UINT8 u8PHSI;
+ /** PHSF Length Of The Service Flow*/
+ B_UINT8 u8PHSFLength;
+ /** String of bytes containing header information to be supressed by the sending CS and reconstructed by the receiving CS*/
+ B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
+ /** PHSM Length Of The Service Flow*/
+ B_UINT8 u8PHSMLength;
+ /** PHS Mask for the SF*/
+ B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
+ /** 8bit Total number of bytes to be supressed for the Service Flow*/
+ B_UINT8 u8PHSS;
+ /** 8bit Indicates whether or not Packet Header contents need to be verified prior to supression */
+ B_UINT8 u8PHSV;
+ /** Vendor Specific PHS param Length Of The Service Flow*/
+ B_UINT8 u8VendorSpecificPHSParamsLength;
+ /** Vendor Specific PHS param Of The Service Flow*/
+ B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
+
+ B_UINT8 u8Padding[2];
+#ifdef BECEEM_TARGET
+};
+#else
+}stPhsRuleSI,*pstPhsRuleSI;
+typedef stPhsRuleSI CPhsRuleSI;
+#endif
+
+/// \brief structure cConvergenceSLTypes
+#ifdef BECEEM_TARGET
+class CConvergenceSLTypes{
+ public:
+ /// \brief Constructor for the class
+ CConvergenceSLTypes():
+ u8ClassfierDSCAction(mClassifierDSCAction),
+ u8PhsDSCAction (mPhsDSCAction)
+ {}
+ void Reset()
+ {
+ CConvergenceSLTypes();
+ cCPacketClassificationRule.Reset();
+ cPhsRule.Reset();
+ }
+#else
+struct _stConvergenceSLTypes{
+#endif
+ /** 8bit Phs Classfier Action Of The Service Flow*/
+ B_UINT8 u8ClassfierDSCAction;
+ /** 8bit Phs DSC Action Of The Service Flow*/
+ B_UINT8 u8PhsDSCAction;
+ /** 16bit Padding */
+ B_UINT8 u8Padding[2];
+ /// \brief class cCPacketClassificationRule
+#ifdef BECEEM_TARGET
+ CCPacketClassificationRuleSI cCPacketClassificationRule;
+#else
+ stCPacketClassificationRuleSI cCPacketClassificationRule;
+#endif
+ /// \brief class CPhsRuleSI
+#ifdef BECEEM_TARGET
+ CPhsRuleSI cPhsRule;
+#else
+ struct _stPhsRuleSI cPhsRule;
+#endif
+};
+#ifndef BECEEM_TARGET
+typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
+#endif
+
+
+/// \brief structure CServiceFlowParamSI
+#ifdef BECEEM_TARGET
+class CServiceFlowParamSI{
+ public:
+ /// \brief Constructor for the class
+ CServiceFlowParamSI():
+ u32SFID(mSFid),
+ u16CID(mCid),
+ u8ServiceClassNameLength(mServiceClassNameLength),
+ u8MBSService(mMBSService),
+ u8QosParamSet(mQosParamSetType),
+ u8TrafficPriority(mTrafficPriority),
+ u32MaxSustainedTrafficRate(mMaximumSustainedTrafficRate),
+ u32MaxTrafficBurst(mMaximumTrafficBurst),
+ u32MinReservedTrafficRate(mMinimumReservedTrafficRate),
+ u8ServiceFlowSchedulingType(mServiceFlowSchedulingType),
+ u8RequesttransmissionPolicy(mRequestTransmissionPolicy),
+ u32ToleratedJitter(mToleratedJitter),
+ u32MaximumLatency(mMaximumLatency),
+ u8FixedLengthVSVariableLengthSDUIndicator
+ (mFixedLengthVSVariableLength),
+ u8SDUSize(mSDUSize),
+ u16TargetSAID(mTargetSAID),
+ u8ARQEnable(mARQEnable),
+ u16ARQWindowSize(mARQWindowSize),
+ u16ARQBlockLifeTime(mARQBlockLifeTime),
+ u16ARQSyncLossTimeOut(mARQSyncLossTimeOut),
+ u8ARQDeliverInOrder(mARQDeliverInOrder),
+ u16ARQRxPurgeTimeOut(mARQRXPurgeTimeOut),
+ //Add ARQ BLOCK SIZE, ARQ TX and RX delay initializations here
+ //after we move to only CORR2
+ u8RxARQAckProcessingTime(mRxARQAckProcessingTime),
+ u8CSSpecification(mCSSpecification),
+ u8TypeOfDataDeliveryService(mTypeOfDataDeliveryService),
+ u16SDUInterArrivalTime(mSDUInterArrivalTime),
+ u16TimeBase(mTimeBase),
+ u8PagingPreference(mPagingPreference),
+ u8MBSZoneIdentifierassignment(mMBSZoneIdentifierassignmentLength),
+ u8TrafficIndicationPreference(mTrafficIndicationPreference),
+ u8GlobalServicesClassNameLength(mGlobalServicesClassNameLength),
+ u8SNFeedbackEnabled(mSNFeedbackEnabled),
+ u8FSNSize(mFSNSize),
+ u8CIDAllocation4activeBSsLength(mCIDAllocation4activeBSsLength),
+ u16UnsolicitedGrantInterval(mUnsolicitedGrantInterval),
+ u16UnsolicitedPollingInterval(mUnsolicitedPollingInterval),
+ u8PDUSNExtendedSubheader4HarqReordering(mPDUSNExtendedSubheader4HarqReordering),
+ u8MBSContentsIDLength(mMBSContentsIDLength),
+ u8HARQServiceFlows(mHARQServiceFlows),
+ u8AuthTokenLength(mAuthTokenLength),
+ u8HarqChannelMappingLength(mHarqChannelMappingLength),
+ u8VendorSpecificQoSParamLength(mVendorSpecificQoSParamLength),
+ bValid(FALSE),
+ u8TotalClassifiers()
+{
+//Remove the bolck after we move to Corr2 only code
+#ifdef ENABLE_CORRIGENDUM2_UPDATE
+ if((g_u32Corr2MacFlags & CORR_2_DSX) || (g_u32Corr2MacFlags & CORR_2_ARQ))
+ {
+ /* IEEE Comment #627 / MTG Comment #426 */
+ u16ARQBlockSize = mARQBlockSize;
+ if(g_u32Corr2MacFlags & CORR_2_ARQ) {
+ u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelay;
+ if(g_u32VENDOR_TYPE == VENDOR_ALCATEL) {
+ u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay_ALU;
+ } else {
+ u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay;
+ }
+ }
+ else
+ {
+ u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
+ u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
+ }
+ }
+ else
+#endif
+ {
+ u16ARQBlockSize = mARQBlockSizeCorr1;
+ u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
+ u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
+ }
+}
+
+ void ComputeMacOverhead(B_UINT8 u8SecOvrhead);
+ B_UINT16 GetMacOverhead() { return u16MacOverhead; }
+#else
+typedef struct _stServiceFlowParamSI{
+#endif //end of ifdef BECEEM_TARGET
+
+ /** 32bitSFID Of The Service Flow*/
+ B_UINT32 u32SFID;
+
+ /** 32bit Maximum Sustained Traffic Rate of the Service Flow*/
+ B_UINT32 u32MaxSustainedTrafficRate;
+
+ /** 32bit Maximum Traffic Burst allowed for the Service Flow*/
+ B_UINT32 u32MaxTrafficBurst;
+
+ /** 32bit Minimum Reserved Traffic Rate of the Service Flow*/
+ B_UINT32 u32MinReservedTrafficRate;
+
+ /** 32bit Tolerated Jitter of the Service Flow*/
+ B_UINT32 u32ToleratedJitter;
+
+ /** 32bit Maximum Latency of the Service Flow*/
+ B_UINT32 u32MaximumLatency;
+
+ /** 16bitCID Of The Service Flow*/
+ B_UINT16 u16CID;
+
+ /** 16bit SAID on which the service flow being set up shall be mapped*/
+ B_UINT16 u16TargetSAID;
+
+ /** 16bit ARQ window size negotiated*/
+ B_UINT16 u16ARQWindowSize;
+
+ /** 16bit Total Tx delay incl sending, receiving & processing delays */
+ B_UINT16 u16ARQRetryTxTimeOut;
+
+ /** 16bit Total Rx delay incl sending, receiving & processing delays */
+ B_UINT16 u16ARQRetryRxTimeOut;
+
+ /** 16bit ARQ block lifetime */
+ B_UINT16 u16ARQBlockLifeTime;
+
+ /** 16bit ARQ Sync loss timeout*/
+ B_UINT16 u16ARQSyncLossTimeOut;
+
+ /** 16bit ARQ Purge timeout */
+ B_UINT16 u16ARQRxPurgeTimeOut;
+#if 0 //def ENABLE_CORRIGENDUM2_UPDATE
+/* IEEE Comment #627 / MTG Comment #426 */
+ /// \brief Size of an ARQ block, changed from 2 bytes to 1
+ B_UINT8 u8ARQBlockSize;
+#endif
+//TODO::Remove this once we move to a new CORR2 driver
+ /// \brief Size of an ARQ block
+ B_UINT16 u16ARQBlockSize;
+
+//#endif
+ /** 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/
+ B_UINT16 u16SDUInterArrivalTime;
+
+ /** 16bit Specifies the time base for rate measurement */
+ B_UINT16 u16TimeBase;
+
+ /** 16bit Interval b/w Successive Grant oppurtunities*/
+ B_UINT16 u16UnsolicitedGrantInterval;
+
+ /** 16bit Interval b/w Successive Polling grant oppurtunities*/
+ B_UINT16 u16UnsolicitedPollingInterval;
+
+ /** internal var to get the overhead */
+ B_UINT16 u16MacOverhead;
+
+ /** MBS contents Identifier*/
+ B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
+
+ /** MBS contents Identifier length*/
+ B_UINT8 u8MBSContentsIDLength;
+
+ /** ServiceClassName Length Of The Service Flow*/
+ B_UINT8 u8ServiceClassNameLength;
+
+ /** 32bytes ServiceClassName Of The Service Flow*/
+ B_UINT8 u8ServiceClassName[32];
+
+ /** 8bit Indicates whether or not MBS service is requested for this Serivce Flow*/
+ B_UINT8 u8MBSService;
+
+ /** 8bit QOS Parameter Set specifies proper application of QoS paramters to Provisioned, Admitted and Active sets*/
+ B_UINT8 u8QosParamSet;
+
+ /** 8bit Traffic Priority Of the Service Flow */
+ B_UINT8 u8TrafficPriority;
+
+ /** 8bit Uplink Grant Scheduling Type of The Service Flow */
+ B_UINT8 u8ServiceFlowSchedulingType;
+
+ /** 8bit Request transmission Policy of the Service Flow*/
+ B_UINT8 u8RequesttransmissionPolicy;
+
+ /** 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
+ B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
+
+ /** 8bit Length of the SDU for a fixed length SDU service flow*/
+ B_UINT8 u8SDUSize;
+
+ /** 8bit Indicates whether or not ARQ is requested for this connection*/
+ B_UINT8 u8ARQEnable;
+
+ /**< 8bit Indicates whether or not data has tobe delivered in order to higher layer*/
+ B_UINT8 u8ARQDeliverInOrder;
+
+ /** 8bit Receiver ARQ ACK processing time */
+ B_UINT8 u8RxARQAckProcessingTime;
+
+ /** 8bit Convergence Sublayer Specification Of The Service Flow*/
+ B_UINT8 u8CSSpecification;
+
+ /** 8 bit Type of data delivery service*/
+ B_UINT8 u8TypeOfDataDeliveryService;
+
+ /** 8bit Specifies whether a service flow may generate Paging */
+ B_UINT8 u8PagingPreference;
+
+ /** 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
+ B_UINT8 u8MBSZoneIdentifierassignment;
+
+ /** 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/
+ B_UINT8 u8TrafficIndicationPreference;
+
+ /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
+ B_UINT8 u8GlobalServicesClassNameLength;
+
+ /** 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
+ B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
+
+ /** 8bit Indicates whether or not SN feedback is enabled for the conn */
+ B_UINT8 u8SNFeedbackEnabled;
+
+ /** Indicates the size of the Fragment Sequence Number for the connection */
+ B_UINT8 u8FSNSize;
+
+ /** 8bit Number of CIDs in active BS list */
+ B_UINT8 u8CIDAllocation4activeBSsLength;
+
+ /** CIDs of BS in the active list */
+ B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
+
+ /** Specifies if PDU extended subheader should be applied on every PDU on this conn*/
+ B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
+
+ /** 8bit Specifies whether the connection uses HARQ or not */
+ B_UINT8 u8HARQServiceFlows;
+
+ /** Specifies the length of Authorization token*/
+ B_UINT8 u8AuthTokenLength;
+
+ /** Specifies the Authorization token*/
+ B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
+
+ /** specifes Number of HARQ channels used to carry data length*/
+ B_UINT8 u8HarqChannelMappingLength;
+
+ /** specifes HARQ channels used to carry data*/
+ B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
+
+ /** 8bit Length of Vendor Specific QoS Params */
+ B_UINT8 u8VendorSpecificQoSParamLength;
+
+ /** 1byte Vendor Specific QoS Param Of The Service Flow*/
+ B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
+
+ // indicates total classifiers in the SF
+ B_UINT8 u8TotalClassifiers; /**< Total number of valid classifiers*/
+ B_UINT8 bValid; /**< Validity flag */
+ B_UINT8 u8Padding; /**< Padding byte*/
+
+#ifdef BECEEM_TARGET
+/**
+Structure for Convergence SubLayer Types with a maximum of 4 classifiers
+*/
+ CConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
+#else
+/**
+Structure for Convergence SubLayer Types with a maximum of 4 classifiers
+*/
+ stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
+#endif
+
+#ifdef BECEEM_TARGET
+};
+#else
+} stServiceFlowParamSI, *pstServiceFlowParamSI;
+typedef stServiceFlowParamSI CServiceFlowParamSI;
+#endif
+
+/**
+structure stLocalSFAddRequest
+*/
+typedef struct _stLocalSFAddRequest{
+#ifdef BECEEM_TARGET
+ _stLocalSFAddRequest( ) :
+ u8Type(0x00), eConnectionDir(0x00),
+ u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000)
+ {}
+#endif
+
+ B_UINT8 u8Type; /**< Type*/
+ B_UINT8 eConnectionDir; /**< Connection direction*/
+ /// \brief 16 bit TID
+ B_UINT16 u16TID; /**< 16bit TID*/
+ /// \brief 16bitCID
+ B_UINT16 u16CID; /**< 16bit CID*/
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID; /**< 16bit VCID*/
+ /// \brief structure ParameterSet
+#ifdef BECEEM_SIGNALLING_INTERFACE_API
+ CServiceFlowParamSI sfParameterSet;
+#endif
+
+#ifdef BECEEM_TARGET
+ CServiceFlowParamSI *psfParameterSet;
+#else
+ stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/
+#endif
+
+#ifdef USING_VXWORKS
+ USE_DATA_MEMORY_MANAGER();
+#endif
+}stLocalSFAddRequest, *pstLocalSFAddRequest;
+
+
+/**
+structure stLocalSFAddIndication
+*/
+typedef struct _stLocalSFAddIndication{
+#ifdef BECEEM_TARGET
+ _stLocalSFAddIndication( ) :
+ u8Type(0x00), eConnectionDir(0x00),
+ u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000)
+ {}
+#endif
+
+ B_UINT8 u8Type; /**< Type*/
+ B_UINT8 eConnectionDir; /**< Connection Direction*/
+ /// \brief 16 bit TID
+ B_UINT16 u16TID; /**< TID*/
+ /// \brief 16bitCID
+ B_UINT16 u16CID; /**< 16bitCID*/
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID; /**< 16bitVCID*/
+
+#ifdef BECEEM_SIGNALLING_INTERFACE_API
+ CServiceFlowParamSI sfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ CServiceFlowParamSI sfAdmittedSet;
+ /// \brief structure ActiveSet
+ CServiceFlowParamSI sfActiveSet;
+#endif
+
+ /// \brief structure AuthorizedSet
+#ifdef BECEEM_TARGET
+ CServiceFlowParamSI *psfAuthorizedSet;
+ /// \brief structure AdmittedSet
+ CServiceFlowParamSI *psfAdmittedSet;
+ /// \brief structure ActiveSet
+ CServiceFlowParamSI *psfActiveSet;
+#else
+ /// \brief structure AuthorizedSet
+ stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/
+ /// \brief structure AdmittedSet
+ stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/
+ /// \brief structure ActiveSet
+ stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/
+#endif
+ B_UINT8 u8CC; /**< Confirmation Code*/
+ B_UINT8 u8Padd; /**< 8-bit Padding */
+
+ B_UINT16 u16Padd; /**< 16 bit Padding */
+
+#ifdef USING_VXWORKS
+ USE_DATA_MEMORY_MANAGER();
+#endif
+}stLocalSFAddIndication;
+
+
+typedef struct _stLocalSFAddIndication *pstLocalSFAddIndication;
+/**
+structure stLocalSFChangeRequest is same as structure stLocalSFAddIndication
+*/
+typedef struct _stLocalSFAddIndication stLocalSFChangeRequest, *pstLocalSFChangeRequest;
+/**
+structure stLocalSFChangeIndication is same as structure stLocalSFAddIndication
+*/
+typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFChangeIndication;
+
+/**
+structure stLocalSFDeleteRequest
+*/
+typedef struct _stLocalSFDeleteRequest{
+#ifdef BECEEM_TARGET
+ _stLocalSFDeleteRequest( ) :
+ u8Type(0x00), u8Padding(0x00),
+ u16TID(0x0000), u32SFID (0x00000000)
+ {}
+#endif
+ B_UINT8 u8Type; /**< Type*/
+ B_UINT8 u8Padding; /**< Padding byte*/
+ B_UINT16 u16TID; /**< TID*/
+ /// \brief 32bitSFID
+ B_UINT32 u32SFID; /**< SFID*/
+#ifdef USING_VXWORKS
+ USE_DATA_MEMORY_MANAGER();
+#endif
+}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
+
+/**
+structure stLocalSFDeleteIndication
+*/
+typedef struct stLocalSFDeleteIndication{
+#ifdef BECEEM_TARGET
+ stLocalSFDeleteIndication( ) :
+ u8Type(0x00), u8Padding(0x00),
+ u16TID(0x0000), u16CID(0x0000),
+ u16VCID(0x0000),u32SFID (0x00000000)
+ {}
+#endif
+ B_UINT8 u8Type; /**< Type */
+ B_UINT8 u8Padding; /**< Padding */
+ B_UINT16 u16TID; /**< TID */
+ /// \brief 16bitCID
+ B_UINT16 u16CID; /**< CID */
+ /// \brief 16bitVCID
+ B_UINT16 u16VCID; /**< VCID */
+ /// \brief 32bitSFID
+ B_UINT32 u32SFID; /**< SFID */
+ /// \brief 8bit Confirmation code
+ B_UINT8 u8ConfirmationCode; /**< Confirmation code */
+ B_UINT8 u8Padding1[3]; /**< 3 byte Padding */
+#ifdef USING_VXWORKS
+ USE_DATA_MEMORY_MANAGER();
+#endif
+}stLocalSFDeleteIndication;
+
+typedef struct _stIM_SFHostNotify
+{
+ B_UINT32 SFID; //SFID of the service flow
+ B_UINT16 newCID; //the new/changed CID
+ B_UINT16 VCID; //Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid
+ B_UINT8 RetainSF; //Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete
+ B_UINT8 QoSParamSet; //QoS paramset of the retained SF
+ B_UINT16 u16reserved; //For byte alignment
+
+} stIM_SFHostNotify;
+
+#endif
diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h
new file mode 100644
index 000000000000..9d4e3aca1b34
--- /dev/null
+++ b/drivers/staging/bcm/headers.h
@@ -0,0 +1,109 @@
+
+/*******************************************************************
+* Headers.h
+*******************************************************************/
+#ifndef __HEADERS_H__
+#define __HEADERS_H__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/if_arp.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+#include <net/ip.h>
+#include <linux/wait.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+
+#include <linux/version.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/unistd.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <asm/uaccess.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <linux/kthread.h>
+#endif
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#ifndef BCM_SHM_INTERFACE
+#include <linux/usb.h>
+#endif
+#ifdef BECEEM_TARGET
+
+#include <mac_common.h>
+#include <msg_Dsa.h>
+#include <msg_Dsc.h>
+#include <msg_Dsd.h>
+#include <sch_definitions.h>
+using namespace Beceem;
+#ifdef ENABLE_CORRIGENDUM2_UPDATE
+extern B_UINT32 g_u32Corr2MacFlags;
+#endif
+#endif
+
+#include "Typedefs.h"
+#include "Version.h"
+#include "Macros.h"
+#include "HostMIBSInterface.h"
+#include "cntrl_SignalingInterface.h"
+#include "PHSDefines.h"
+#include "led_control.h"
+#include "Ioctl.h"
+#include "nvm.h"
+#include "target_params.h"
+#include "Adapter.h"
+#include "CmHost.h"
+#include "DDRInit.h"
+#include "Debug.h"
+#include "HostMibs.h"
+#include "IPv6ProtocolHdr.h"
+#include "osal_misc.h"
+#include "PHSModule.h"
+#include "Protocol.h"
+#include "Prototypes.h"
+#include "Queue.h"
+#include "vendorspecificextn.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+#include "InterfaceMacros.h"
+#include "InterfaceAdapter.h"
+#include "InterfaceIsr.h"
+#include "Interfacemain.h"
+#include "InterfaceMisc.h"
+#include "InterfaceRx.h"
+#include "InterfaceTx.h"
+#endif
+#include "InterfaceIdleMode.h"
+#include "InterfaceInit.h"
+
+#ifdef BCM_SHM_INTERFACE
+#include <linux/cpe_config.h>
+
+#ifdef GDMA_INTERFACE
+#include "GdmaInterface.h"
+#include "symphony.h"
+#else
+#include "virtual_interface.h"
+
+#endif
+
+#endif
+
+#endif
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
new file mode 100644
index 000000000000..e9da513b3c24
--- /dev/null
+++ b/drivers/staging/bcm/hostmibs.c
@@ -0,0 +1,164 @@
+
+/*
+ * File Name: hostmibs.c
+ *
+ * Author: Beceem Communications Pvt. Ltd
+ *
+ * Abstract: This file contains the routines to copy the statistics used by
+ * the driver to the Host MIBS structure and giving the same to Application.
+ *
+ */
+#include "headers.h"
+
+INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
+ PVOID ioBuffer,
+ ULONG inputBufferLength)
+{
+
+ S_MIBS_HOST_STATS_MIBS *pstHostMibs = NULL;
+ S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+ S_PHS_RULE *pstPhsRule = NULL;
+ S_CLASSIFIER_TABLE *pstClassifierTable = NULL;
+ S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
+ PPHS_DEVICE_EXTENSION pDeviceExtension = (PPHS_DEVICE_EXTENSION)&Adapter->stBCMPhsContext;
+
+ UINT nClassifierIndex = 0, nPhsTableIndex = 0,nSfIndex = 0, uiIndex = 0;
+
+ if(pDeviceExtension == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, HOST_MIBS, DBG_LVL_ALL, "Invalid Device Extension\n");
+ return STATUS_FAILURE;
+ }
+
+ if(ioBuffer == NULL)
+ {
+ return -EINVAL;
+ }
+ memset(ioBuffer,0,sizeof(S_MIBS_HOST_STATS_MIBS));
+
+ pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
+
+
+ //Copy the classifier Table
+ for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
+ nClassifierIndex++)
+ {
+ if(Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE)
+ memcpy((PVOID)&pstHostMibs->astClassifierTable[nClassifierIndex],
+ (PVOID)&Adapter->astClassifierTable[nClassifierIndex],
+ sizeof(S_MIBS_CLASSIFIER_RULE));
+ }
+
+ //Copy the SF Table
+ for(nSfIndex=0; nSfIndex < NO_OF_QUEUES ; nSfIndex++)
+ {
+ if(Adapter->PackInfo[nSfIndex].bValid)
+ {
+ OsalMemMove((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
+ }
+ else
+ {
+ //if index in not valid, don't process this for the PHS table. Go For the next entry.
+ continue ;
+ }
+
+ //Retrieve the SFID Entry Index for requested Service Flow
+ if(PHS_INVALID_TABLE_INDEX == GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ Adapter->PackInfo[nSfIndex].usVCID_Value ,&pstServiceFlowEntry))
+ {
+
+ continue;
+ }
+
+ pstClassifierTable = pstServiceFlowEntry->pstClassifierTable;
+
+
+ for(uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++)
+ {
+ pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[uiIndex];
+
+ if(pstClassifierRule->bUsed)
+ {
+ pstPhsRule = pstClassifierRule->pstPhsRule;
+
+ pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
+
+ OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
+ &pstPhsRule->u8PHSI,
+ sizeof(S_PHS_RULE));
+ nPhsTableIndex++;
+
+ }
+
+ }
+
+ }
+
+
+
+ //copy other Host Statistics parameters
+ pstHostMibs->stHostInfo.GoodTransmits =
+ atomic_read(&Adapter->TxTotalPacketCount);
+ pstHostMibs->stHostInfo.GoodReceives =
+ atomic_read(&Adapter->GoodRxPktCount);
+ pstHostMibs->stHostInfo.CurrNumFreeDesc =
+ atomic_read(&Adapter->CurrNumFreeTxDesc);
+ pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
+ pstHostMibs->stHostInfo.rtPSBucketSize = Adapter->rtPSBucketSize;
+ pstHostMibs->stHostInfo.TimerActive = Adapter->TimerActive;
+ pstHostMibs->stHostInfo.u32TotalDSD = Adapter->u32TotalDSD;
+
+ memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist,Adapter->aTxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES);
+ memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist,Adapter->aRxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES);
+
+ return STATUS_SUCCESS;
+}
+
+
+INT GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang)
+{
+ S_MIBS_HOST_STATS_MIBS *pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
+
+ memcpy((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+
+ return STATUS_SUCCESS ;
+}
+
+
+VOID CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
+ CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex)
+{
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfSfid = psfLocalSet->u32SFID;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = psfLocalSet->u8ServiceFlowSchedulingType;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohs(psfLocalSet->u16ARQBlockLifeTime);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohs(psfLocalSet->u16ARQSyncLossTimeOut);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohs(psfLocalSet->u16ARQRxPurgeTimeOut);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification;
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID);
+ Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid);
+
+}
diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c
new file mode 100644
index 000000000000..0d07664e10f9
--- /dev/null
+++ b/drivers/staging/bcm/led_control.c
@@ -0,0 +1,1006 @@
+#include "headers.h"
+
+#define STATUS_IMAGE_CHECKSUM_MISMATCH -199
+#define EVENT_SIGNALED 1
+
+static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
+{
+ B_UINT16 u16CheckSum=0;
+ while(u32Size--) {
+ u16CheckSum += (B_UINT8)~(*pu8Buffer);
+ pu8Buffer++;
+ }
+ return u16CheckSum;
+}
+BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios)
+{
+ INT Status ;
+ Status = (Adapter->gpioBitMap & gpios) ^ gpios ;
+ if(Status)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
+{
+ int Status = STATUS_SUCCESS;
+ BOOLEAN bInfinite = FALSE;
+
+ /*Check if num_of_time is -ve. If yes, blink led in infinite loop*/
+ if(num_of_time < 0)
+ {
+ bInfinite = TRUE;
+ num_of_time = 1;
+ }
+ while(num_of_time)
+ {
+
+ if(currdriverstate == Adapter->DriverState)
+ TURN_ON_LED(GPIO_Num, uiLedIndex);
+
+ /*Wait for timeout after setting on the LED*/
+ Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
+ currdriverstate != Adapter->DriverState || kthread_should_stop(),
+ msecs_to_jiffies(timeout));
+
+ if(kthread_should_stop())
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
+ Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
+ TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ Status=EVENT_SIGNALED;
+ break;
+ }
+ if(Status)
+ {
+ TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ Status=EVENT_SIGNALED;
+ break;
+ }
+
+ TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
+ currdriverstate!= Adapter->DriverState || kthread_should_stop(),
+ msecs_to_jiffies(timeout));
+ if(bInfinite == FALSE)
+ num_of_time--;
+ }
+ return Status;
+}
+
+INT ScaleRateofTransfer(ULONG rate)
+{
+ if(rate <= 3)
+ return rate;
+ else if((rate > 3) && (rate <= 100))
+ return 5;
+ else if((rate > 100) && (rate <= 200))
+ return 6;
+ else if((rate > 200) && (rate <= 300))
+ return 7;
+ else if((rate > 300) && (rate <= 400))
+ return 8;
+ else if((rate > 400) && (rate <= 500))
+ return 9;
+ else if((rate > 500) && (rate <= 600))
+ return 10;
+ else
+ return MAX_NUM_OF_BLINKS;
+}
+
+
+
+INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
+ UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate)
+{
+ /* Initial values of TX and RX packets*/
+ ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
+ /*values of TX and RX packets after 1 sec*/
+ ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
+ /*Rate of transfer of Tx and Rx in 1 sec*/
+ ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
+ int Status = STATUS_SUCCESS;
+ INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
+ UINT remDelay = 0;
+ BOOLEAN bBlinkBothLED = TRUE;
+ //UINT GPIO_num = DISABLE_GPIO_NUM;
+ ulong timeout = 0;
+
+ /*Read initial value of packets sent/received */
+ Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
+ Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
+ /*Scale the rate of transfer to no of blinks.*/
+ num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
+ num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
+
+ while((Adapter->device_removed == FALSE))
+ {
+ #if 0
+ if(0 == num_of_time_tx && 0 == num_of_time_rx)
+ {
+ timeout = 1000;
+ Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
+ currdriverstate!= Adapter->DriverState || kthread_should_stop(),
+ msecs_to_jiffies (timeout));
+ if(kthread_should_stop())
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
+ Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
+ return EVENT_SIGNALED;
+ }
+ if(Status)
+ return EVENT_SIGNALED;
+
+ }
+ #endif
+
+ timeout = 50;
+ #if 0
+ /*Turn on LED if Tx is high bandwidth*/
+ if(num_of_time_tx > MAX_NUM_OF_BLINKS)
+ {
+ TURN_ON_LED(1<<GPIO_Num_tx, uiTxLedIndex);
+ num_of_time_tx = 0;
+ bBlinkBothLED = FALSE;
+ num_of_time = num_of_time_rx;
+ }
+ /*Turn on LED if Rx is high bandwidth*/
+ if(num_of_time_rx > MAX_NUM_OF_BLINKS)
+ {
+ TURN_ON_LED(1<<GPIO_Num_rx, uiRxLedIndex);
+ num_of_time_rx = 0;
+ bBlinkBothLED = FALSE;
+ num_of_time = num_of_time_tx;
+ }
+ #endif
+ /*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
+ if(bBlinkBothLED)
+ {
+ /*Assign minimum number of blinks of either Tx or Rx.*/
+ if(num_of_time_tx > num_of_time_rx)
+ num_of_time = num_of_time_rx;
+ else
+ num_of_time = num_of_time_tx;
+ if(num_of_time > 0)
+ {
+ /*Blink both Tx and Rx LEDs*/
+ if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
+ == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+ if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout, num_of_time,currdriverstate)
+ == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+
+ }
+
+ if(num_of_time == num_of_time_tx)
+ {
+ /*Blink pending rate of Rx*/
+ if(LED_Blink(Adapter, (1 << GPIO_Num_rx), uiRxLedIndex, timeout,
+ num_of_time_rx-num_of_time,currdriverstate) == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+ num_of_time = num_of_time_rx;
+ }
+ else
+ {
+ /*Blink pending rate of Tx*/
+ if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout,
+ num_of_time_tx-num_of_time,currdriverstate) == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+ num_of_time = num_of_time_tx;
+ }
+ }
+ else
+ {
+ if(num_of_time == num_of_time_tx)
+ {
+ /*Blink pending rate of Rx*/
+ if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
+ == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+ }
+ else
+ {
+ /*Blink pending rate of Tx*/
+ if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout,
+ num_of_time,currdriverstate) == EVENT_SIGNALED)
+ {
+ return EVENT_SIGNALED;
+ }
+ }
+ }
+ /* If Tx/Rx rate is less than maximum blinks per second,
+ * wait till delay completes to 1 second
+ */
+ remDelay = MAX_NUM_OF_BLINKS - num_of_time;
+ if(remDelay > 0)
+ {
+ timeout= 100 * remDelay;
+ Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
+ currdriverstate!= Adapter->DriverState ||kthread_should_stop() ,
+ msecs_to_jiffies (timeout));
+
+ if(kthread_should_stop())
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
+ Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
+ return EVENT_SIGNALED;
+ }
+ if(Status)
+ return EVENT_SIGNALED;
+ }
+
+ /*Turn off both Tx and Rx LEDs before next second*/
+ TURN_OFF_LED(1<<GPIO_Num_tx, uiTxLedIndex);
+ TURN_OFF_LED(1<<GPIO_Num_rx, uiTxLedIndex);
+
+ /*
+ * Read the Tx & Rx packets transmission after 1 second and
+ * calculate rate of transfer
+ */
+ Final_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
+ rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
+ Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
+ rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
+
+ /*Read initial value of packets sent/received */
+ Initial_num_of_packts_tx = Final_num_of_packts_tx;
+ Initial_num_of_packts_rx = Final_num_of_packts_rx ;
+
+ /*Scale the rate of transfer to no of blinks.*/
+ num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
+ num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
+
+ }
+ return Status;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: ValidateDSDParamsChecksum
+//
+// Description: Reads DSD Params and validates checkusm.
+//
+// Arguments:
+// Adapter - Pointer to Adapter structure.
+// ulParamOffset - Start offset of the DSD parameter to be read and validated.
+// usParamLen - Length of the DSD Parameter.
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+INT ValidateDSDParamsChecksum(
+ PMINI_ADAPTER Adapter,
+ ULONG ulParamOffset,
+ USHORT usParamLen )
+{
+ INT Status = STATUS_SUCCESS;
+ PUCHAR puBuffer = NULL;
+ USHORT usChksmOrg = 0;
+ USHORT usChecksumCalculated = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
+
+ puBuffer = OsalMemAlloc(usParamLen,'!MEM');
+ if(!puBuffer)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
+ return -ENOMEM;
+
+ }
+
+ //
+ // Read the DSD data from the parameter offset.
+ //
+ if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)puBuffer,ulParamOffset,usParamLen))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+ Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
+ goto exit;
+ }
+
+ //
+ // Calculate the checksum of the data read from the DSD parameter.
+ //
+ usChecksumCalculated = CFG_CalculateChecksum(puBuffer,usParamLen);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated);
+
+ //
+ // End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated
+ // Checksum.
+ //
+ if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)&usChksmOrg,ulParamOffset+usParamLen,2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+ Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
+ goto exit;
+ }
+ usChksmOrg = ntohs(usChksmOrg);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usChksmOrg = 0x%x", usChksmOrg);
+
+ //
+ // Compare the checksum calculated with the checksum read from DSD section
+ //
+ if(usChecksumCalculated ^ usChksmOrg)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
+ Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
+ goto exit;
+ }
+
+exit:
+ if(puBuffer)
+ {
+ OsalMemFree(puBuffer, usParamLen);
+ }
+ return Status;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: ValidateHWParmStructure
+//
+// Description: Validates HW Parameters.
+//
+// Arguments:
+// Adapter - Pointer to Adapter structure.
+// ulHwParamOffset - Start offset of the HW parameter Section to be read and validated.
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset)
+{
+
+ INT Status = STATUS_SUCCESS ;
+ USHORT HwParamLen = 0;
+ // Add DSD start offset to the hwParamOffset to get the actual address.
+ ulHwParamOffset += DSD_START_OFFSET;
+
+ /*Read the Length of HW_PARAM structure*/
+ BeceemNVMRead(Adapter,(PUINT)&HwParamLen,ulHwParamOffset,2);
+ HwParamLen = ntohs(HwParamLen);
+ if(0==HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
+ {
+ return STATUS_IMAGE_CHECKSUM_MISMATCH;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen);
+ Status =ValidateDSDParamsChecksum(Adapter,ulHwParamOffset,HwParamLen);
+ return Status;
+} /* ValidateHWParmStructure() */
+
+int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[])
+{
+ int Status = STATUS_SUCCESS;
+
+ ULONG dwReadValue = 0;
+ USHORT usHwParamData = 0;
+ USHORT usEEPROMVersion = 0;
+ UCHAR ucIndex = 0;
+ UCHAR ucGPIOInfo[32] = {0};
+
+ BeceemNVMRead(Adapter,(PUINT)&usEEPROMVersion,EEPROM_VERSION_OFFSET,2);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"usEEPROMVersion: Minor:0x%X Major:0x%x",usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
+
+
+ if(((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION)
+ {
+ BeceemNVMRead(Adapter,(PUINT)&usHwParamData,EEPROM_HW_PARAM_POINTER_ADDRESS,2);
+ usHwParamData = ntohs(usHwParamData);
+ dwReadValue = usHwParamData;
+ }
+ else
+ {
+ //
+ // Validate Compatibility section and then read HW param if compatibility section is valid.
+ //
+ Status = ValidateDSDParamsChecksum(Adapter,
+ DSD_START_OFFSET,
+ COMPATIBILITY_SECTION_LENGTH_MAP5);
+
+ if(Status != STATUS_SUCCESS)
+ {
+ return Status;
+ }
+ BeceemNVMRead(Adapter,(PUINT)&dwReadValue,EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5,4);
+ dwReadValue = ntohl(dwReadValue);
+ }
+
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Start address of HW_PARAM structure = 0x%lx",dwReadValue);
+
+ //
+ // Validate if the address read out is within the DSD.
+ // Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
+ // lower limit should be above DSD_START_OFFSET and
+ // upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
+ //
+ if(dwReadValue < DSD_START_OFFSET ||
+ dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
+ {
+ return STATUS_IMAGE_CHECKSUM_MISMATCH;
+ }
+
+ Status = ValidateHWParmStructure(Adapter, dwReadValue);
+ if(Status){
+ return Status;
+ }
+
+ /*
+ Add DSD_START_OFFSET to the offset read from the EEPROM.
+ This will give the actual start HW Parameters start address.
+ To read GPIO section, add GPIO offset further.
+ */
+
+ dwReadValue += DSD_START_OFFSET; // = start address of hw param section.
+ dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section.
+
+ /* Read the GPIO values for 32 GPIOs from EEPROM and map the function
+ * number to GPIO pin number to GPIO_Array
+ */
+ BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo,dwReadValue,32);
+ for(ucIndex = 0; ucIndex < 32; ucIndex++)
+ {
+
+ switch(ucGPIOInfo[ucIndex])
+ {
+ case RED_LED:
+ {
+ GPIO_Array[RED_LED] = ucIndex;
+ Adapter->gpioBitMap |= (1<<ucIndex);
+ break;
+ }
+ case BLUE_LED:
+ {
+ GPIO_Array[BLUE_LED] = ucIndex;
+ Adapter->gpioBitMap |= (1<<ucIndex);
+ break;
+ }
+ case YELLOW_LED:
+ {
+ GPIO_Array[YELLOW_LED] = ucIndex;
+ Adapter->gpioBitMap |= (1<<ucIndex);
+ break;
+ }
+ case GREEN_LED:
+ {
+ GPIO_Array[GREEN_LED] = ucIndex;
+ Adapter->gpioBitMap |= (1<<ucIndex);
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"GPIO's bit map correspond to LED :0x%X",Adapter->gpioBitMap);
+ return Status;
+}
+
+
+int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread)
+{
+ int Status = STATUS_SUCCESS;
+ UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
+#ifndef BCM_SHM_INTERFACE
+ UINT uiIndex = 0;
+ UINT uiNum_of_LED_Type = 0;
+ PUCHAR puCFGData = NULL;
+ UCHAR bData = 0;
+#endif
+ memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
+
+ if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
+ {
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n");
+ return -ENOENT;
+ }
+
+ /*Populate GPIO_Array with GPIO numbers for LED functions*/
+ /*Read the GPIO numbers from EEPROM*/
+ Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
+ if(Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
+ {
+ *bEnableThread = FALSE;
+ return STATUS_SUCCESS;
+ }
+ else if(Status)
+ {
+ *bEnableThread = FALSE;
+ return Status;
+ }
+#ifdef BCM_SHM_INTERFACE
+ *bEnableThread = FALSE;
+ return Status ;
+#else
+ /*
+ * CONFIG file read successfully. Deallocate the memory of
+ * uiFileNameBufferSize
+ */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Config file read successfully\n");
+ puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
+
+ /*
+ * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
+ * will have the information of LED type, LED on state for different
+ * driver state and LED blink state.
+ */
+
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+ bData = *puCFGData;
+
+ /*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/
+ if(bData & 0x80)
+ {
+ Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
+ /*unset the bit 8*/
+ bData = bData & 0x7f;
+ }
+
+ Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
+ if(bData <= NUM_OF_LEDS)
+ Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData];
+ else
+ Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM;
+
+ puCFGData++;
+ bData = *puCFGData;
+ Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
+ puCFGData++;
+ bData = *puCFGData;
+ Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State= bData;
+ puCFGData++;
+ }
+
+ /*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/
+ for(uiIndex = 0; uiIndex<NUM_OF_LEDS; uiIndex++)
+ {
+ if((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
+ (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
+ (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
+ uiNum_of_LED_Type++;
+ }
+ if(uiNum_of_LED_Type >= NUM_OF_LEDS)
+ *bEnableThread = FALSE;
+#endif
+
+#if 0
+ for(uiIndex=0; uiIndex<NUM_OF_LEDS; uiIndex++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Type = %x\n", uiIndex,
+ Adapter->LEDInfo.LEDState[uiIndex].LED_Type);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex,
+ Adapter->LEDInfo.LEDState[uiIndex].LED_On_State);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex,
+ Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex,
+ Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n",
+ Adapter->LEDInfo.BitPolarty);
+#endif
+ return Status;
+}
+//--------------------------------------------------------------------------
+// Procedure: LedGpioInit
+//
+// Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the
+// initial state to be OFF.
+//
+// Arguments:
+// Adapter - Pointer to MINI_ADAPTER structure.
+//
+// Returns: VOID
+//
+//-----------------------------------------------------------------------------
+
+VOID LedGpioInit(PMINI_ADAPTER Adapter)
+{
+ UINT uiResetValue = 0;
+ UINT uiIndex = 0;
+
+ /* Set all LED GPIO Mode to output mode */
+ if(rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) <0)
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: RDM Failed\n");
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+ uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
+ TURN_OFF_LED(1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,uiIndex);
+ }
+ if(wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
+ BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: WRM Failed\n");
+
+ Adapter->LEDInfo.bIdle_led_off = FALSE;
+}
+//-----------------------------------------------------------------------------
+
+INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx ,UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,LedEventInfo_t currdriverstate)
+{
+ UINT uiIndex = 0;
+
+ *GPIO_num_tx = DISABLE_GPIO_NUM;
+ *GPIO_num_rx = DISABLE_GPIO_NUM;
+
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+
+ if((currdriverstate == NORMAL_OPERATION)||
+ (currdriverstate == IDLEMODE_EXIT)||
+ (currdriverstate == FW_DOWNLOAD))
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+ {
+ if(*GPIO_num_tx == DISABLE_GPIO_NUM)
+ {
+ *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
+ *uiLedTxIndex = uiIndex;
+ }
+ else
+ {
+ *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
+ *uiLedRxIndex = uiIndex;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+ {
+ *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
+ *uiLedTxIndex = uiIndex;
+ }
+ }
+ }
+ }
+ return STATUS_SUCCESS ;
+}
+VOID LEDControlThread(PMINI_ADAPTER Adapter)
+{
+ UINT uiIndex = 0;
+ UCHAR GPIO_num = 0;
+ UCHAR uiLedIndex = 0 ;
+ UINT uiResetValue = 0;
+ LedEventInfo_t currdriverstate = 0;
+ ulong timeout = 0;
+
+ INT Status = 0;
+
+ UCHAR dummyGPIONum = 0;
+ UCHAR dummyIndex = 0;
+
+ //currdriverstate = Adapter->DriverState;
+ Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
+
+ /*Wait till event is triggered*/
+ //wait_event(Adapter->LEDInfo.notify_led_event,
+ // currdriverstate!= Adapter->DriverState);
+
+ GPIO_num = DISABLE_GPIO_NUM ;
+
+ while(TRUE)
+ {
+ /*Wait till event is triggered*/
+ if( (GPIO_num == DISABLE_GPIO_NUM)
+ ||
+ ((currdriverstate != FW_DOWNLOAD) &&
+ (currdriverstate != NORMAL_OPERATION) &&
+ (currdriverstate != LOWPOWER_MODE_ENTER))
+ ||
+ (currdriverstate == LED_THREAD_INACTIVE) )
+ {
+ Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event,
+ currdriverstate != Adapter->DriverState || kthread_should_stop());
+ }
+
+ if(kthread_should_stop() || Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
+ TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
+ return ;//STATUS_FAILURE;
+ }
+ #if 0
+ if(Adapter->device_removed)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread..");
+ return ; //-ENODEV;
+ }
+ #endif
+ #if 0
+ if((GPIO_num != DISABLE_GPIO_NUM) &&
+ ((currdriverstate != FW_DOWNLOAD) &&
+ (currdriverstate != NORMAL_OPERATION) &&
+ (currdriverstate != IDLEMODE_EXIT)))
+ TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
+ #endif
+
+ if(GPIO_num != DISABLE_GPIO_NUM)
+ {
+ TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
+ }
+
+ if(Adapter->LEDInfo.bLedInitDone == FALSE)
+ {
+ LedGpioInit(Adapter);
+ Adapter->LEDInfo.bLedInitDone = TRUE;
+ }
+
+ switch(Adapter->DriverState)
+ {
+ case DRIVER_INIT:
+ {
+ currdriverstate = DRIVER_INIT;//Adapter->DriverState;
+ #if 0
+ LedGpioInit(Adapter);
+ Adapter->LEDInfo.bLedInitDone = TRUE;
+ #endif
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
+
+ if(GPIO_num != DISABLE_GPIO_NUM)
+ {
+ TURN_ON_LED(1<<GPIO_num, uiLedIndex);
+ }
+ }
+ break;
+ case FW_DOWNLOAD:
+ {
+ //BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
+ currdriverstate = FW_DOWNLOAD;
+ #if 0
+ if(Adapter->LEDInfo.bLedInitDone == FALSE)
+ {
+ LedGpioInit(Adapter);
+ Adapter->LEDInfo.bLedInitDone = TRUE;
+ }
+ #endif
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
+
+ if(GPIO_num != DISABLE_GPIO_NUM)
+ {
+ timeout = 50;
+ LED_Blink(Adapter, 1<<GPIO_num, uiLedIndex, timeout, -1,currdriverstate);
+ }
+ }
+ break;
+ case FW_DOWNLOAD_DONE:
+ {
+ currdriverstate = FW_DOWNLOAD_DONE;
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex,currdriverstate);
+ if(GPIO_num != DISABLE_GPIO_NUM)
+ {
+ TURN_ON_LED(1<<GPIO_num, uiLedIndex);
+ }
+ }
+ break;
+
+ case SHUTDOWN_EXIT:
+ #if 0
+ if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN)
+ {
+ LedGpioInit(Adapter);
+ }
+ #endif
+ //no break, continue to NO_NETWORK_ENTRY state as well.
+
+ case NO_NETWORK_ENTRY:
+ {
+ currdriverstate = NO_NETWORK_ENTRY;
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex,&dummyGPIONum,currdriverstate);
+ if(GPIO_num != DISABLE_GPIO_NUM)
+ {
+ TURN_ON_LED(1<<GPIO_num, uiLedIndex);
+ }
+ }
+ break;
+ case NORMAL_OPERATION:
+ {
+ UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
+ UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
+ UCHAR uiLEDTx = 0;
+ UCHAR uiLEDRx = 0;
+ currdriverstate = NORMAL_OPERATION;
+ Adapter->LEDInfo.bIdle_led_off = FALSE;
+
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx,&uiLEDRx,currdriverstate);
+ if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
+ {
+ GPIO_num = DISABLE_GPIO_NUM ;
+ }
+ else
+ {
+ /*If single LED is selected, use same for both Tx and Rx*/
+ if(GPIO_num_tx == DISABLE_GPIO_NUM)
+ {
+ GPIO_num_tx = GPIO_num_rx;
+ uiLEDTx = uiLEDRx;
+ }
+ else if(GPIO_num_rx == DISABLE_GPIO_NUM)
+ {
+ GPIO_num_rx = GPIO_num_tx;
+ uiLEDRx = uiLEDTx;
+ }
+ /*Blink the LED in proportionate to Tx and Rx transmissions.*/
+ LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx,currdriverstate);
+ }
+ }
+ break;
+ case LOWPOWER_MODE_ENTER:
+ {
+ currdriverstate = LOWPOWER_MODE_ENTER;
+ if( DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode)
+ {
+ /* Turn OFF all the LED */
+ uiResetValue = 0;
+ for(uiIndex =0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+ TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
+ }
+
+ }
+ /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
+ Adapter->LEDInfo.bLedInitDone = FALSE;
+ Adapter->LEDInfo.bIdle_led_off = TRUE;
+ wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
+ GPIO_num = DISABLE_GPIO_NUM;
+ break;
+ }
+ case IDLEMODE_CONTINUE:
+ {
+ currdriverstate = IDLEMODE_CONTINUE;
+ GPIO_num = DISABLE_GPIO_NUM;
+ }
+ break;
+ case IDLEMODE_EXIT:
+ {
+#if 0
+ UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
+ UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
+ UCHAR uiTxLedIndex = 0;
+ UCHAR uiRxLedIndex = 0;
+
+ currdriverstate = IDLEMODE_EXIT;
+ if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode)
+ {
+ LedGpioInit(Adapter);
+ }
+ BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate);
+
+ Adapter->LEDInfo.bIdle_led_off = FALSE;
+
+ if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
+ {
+ GPIO_num = DISABLE_GPIO_NUM ;
+ }
+ else
+ {
+ timeout = 50;
+ if(Adapter->LEDInfo.bIdleMode_tx_from_host)
+ LED_Blink(Adapter, 1<<GPIO_num_tx, uiTxLedIndex, timeout, -1,currdriverstate);
+ else
+ LED_Blink(Adapter, 1<<GPIO_num_rx, uiRxLedIndex, timeout, -1,currdriverstate);
+ }
+#endif
+ }
+ break;
+ case DRIVER_HALT:
+ {
+ currdriverstate = DRIVER_HALT;
+ GPIO_num = DISABLE_GPIO_NUM;
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
+ DISABLE_GPIO_NUM)
+ TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
+ }
+ //Adapter->DriverState = DRIVER_INIT;
+ }
+ break;
+ case LED_THREAD_INACTIVE :
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"InActivating LED thread...");
+ currdriverstate = LED_THREAD_INACTIVE;
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY ;
+ Adapter->LEDInfo.bLedInitDone = FALSE ;
+ //disable ALL LED
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
+ {
+ if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
+ DISABLE_GPIO_NUM)
+ TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
+ }
+ }
+ break;
+ case LED_THREAD_ACTIVE :
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Activating LED thread again...");
+ if(Adapter->LinkUpStatus == FALSE)
+ Adapter->DriverState = NO_NETWORK_ENTRY;
+ else
+ Adapter->DriverState = NORMAL_OPERATION;
+
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY ;
+ }
+ break;
+ //return;
+ default:
+ break;
+ }
+ }
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
+}
+
+int InitLedSettings(PMINI_ADAPTER Adapter)
+{
+ int Status = STATUS_SUCCESS;
+ BOOLEAN bEnableThread = TRUE;
+ UCHAR uiIndex = 0;
+
+ /*Initially set BitPolarity to normal polarity. The bit 8 of LED type
+ * is used to change the polarity of the LED.*/
+
+ for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+ Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
+ }
+
+ /*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/
+ Status = ReadConfigFileStructure(Adapter, &bEnableThread);
+ if(STATUS_SUCCESS != Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FAILED in ReadConfigFileStructure\n");
+ return Status;
+ }
+
+ if(Adapter->LEDInfo.led_thread_running)
+ {
+ if(bEnableThread)
+ ;
+ else
+ {
+ Adapter->DriverState = DRIVER_HALT;
+ wake_up(&Adapter->LEDInfo.notify_led_event);
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
+ }
+
+ }
+
+ else if(bEnableThread)
+ {
+ /*Create secondary thread to handle the LEDs*/
+ init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
+ init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
+ Adapter->LEDInfo.bIdle_led_off = FALSE;
+ Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *))
+ LEDControlThread, Adapter, "led_control_thread");
+ if(IS_ERR(Adapter->LEDInfo.led_cntrl_threadid))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n");
+ Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
+ return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
+ }
+ }
+ return Status;
+}
diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h
new file mode 100644
index 000000000000..0711ac20f6fc
--- /dev/null
+++ b/drivers/staging/bcm/led_control.h
@@ -0,0 +1,106 @@
+#ifndef _LED_CONTROL_H
+#define _LED_CONTROL_H
+
+/*************************TYPE DEF**********************/
+#define NUM_OF_LEDS 4
+
+#define DSD_START_OFFSET 0x0200
+#define EEPROM_VERSION_OFFSET 0x020E
+#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218
+#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220
+#define GPIO_SECTION_START_OFFSET 0x03
+
+#define COMPATIBILITY_SECTION_LENGTH 42
+#define COMPATIBILITY_SECTION_LENGTH_MAP5 84
+
+
+#define EEPROM_MAP5_MAJORVERSION 5
+#define EEPROM_MAP5_MINORVERSION 0
+
+
+#define MAX_NUM_OF_BLINKS 10
+#define NUM_OF_GPIO_PINS 16
+
+#define DISABLE_GPIO_NUM 0xFF
+#define EVENT_SIGNALED 1
+
+#define MAX_FILE_NAME_BUFFER_SIZE 100
+
+#define TURN_ON_LED(GPIO, index) do{ \
+ UINT gpio_val = GPIO; \
+ (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
+ wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG, &gpio_val ,sizeof(gpio_val)) : \
+ wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
+ }while(0);
+
+#define TURN_OFF_LED(GPIO, index) do { \
+ UINT gpio_val = GPIO; \
+ (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
+ wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG,&gpio_val ,sizeof(gpio_val)) : \
+ wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG,&gpio_val ,sizeof(gpio_val)); \
+ }while(0);
+
+#define B_ULONG32 unsigned long
+
+/*******************************************************/
+
+
+typedef enum _LEDColors{
+ RED_LED = 1,
+ BLUE_LED = 2,
+ YELLOW_LED = 3,
+ GREEN_LED = 4
+} LEDColors; /*Enumerated values of different LED types*/
+
+typedef enum LedEvents {
+ SHUTDOWN_EXIT = 0x00,
+ DRIVER_INIT = 0x1,
+ FW_DOWNLOAD = 0x2,
+ FW_DOWNLOAD_DONE = 0x4,
+ NO_NETWORK_ENTRY = 0x8,
+ NORMAL_OPERATION = 0x10,
+ LOWPOWER_MODE_ENTER = 0x20,
+ IDLEMODE_CONTINUE = 0x40,
+ IDLEMODE_EXIT = 0x80,
+ LED_THREAD_INACTIVE = 0x100, //Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold.
+ LED_THREAD_ACTIVE = 0x200 //Makes the LED Thread Active back.
+} LedEventInfo_t; /*Enumerated values of different driver states*/
+
+#define DRIVER_HALT 0xff
+
+
+/*Structure which stores the information of different LED types
+ * and corresponding LED state information of driver states*/
+typedef struct LedStateInfo_t
+{
+ UCHAR LED_Type; /* specify GPIO number - use 0xFF if not used */
+ UCHAR LED_On_State; /* Bits set or reset for different states */
+ UCHAR LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */
+ UCHAR GPIO_Num;
+ UCHAR BitPolarity; /*To represent whether H/W is normal polarity or reverse
+ polarity*/
+}LEDStateInfo, *pLEDStateInfo;
+
+
+typedef struct _LED_INFO_STRUCT
+{
+ LEDStateInfo LEDState[NUM_OF_LEDS];
+ BOOLEAN bIdleMode_tx_from_host; /*Variable to notify whether driver came out
+ from idlemode due to Host or target*/
+ BOOLEAN bIdle_led_off;
+ wait_queue_head_t notify_led_event;
+ wait_queue_head_t idleModeSyncEvent;
+ struct task_struct *led_cntrl_threadid;
+ int led_thread_running;
+ BOOLEAN bLedInitDone;
+
+} LED_INFO_STRUCT, *PLED_INFO_STRUCT;
+//LED Thread state.
+#define BCM_LED_THREAD_DISABLED 0 //LED Thread is not running.
+#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 //LED thread is running.
+#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 //LED thread has been put on hold
+
+
+
+#endif
+
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
new file mode 100644
index 000000000000..35ff4e761f73
--- /dev/null
+++ b/drivers/staging/bcm/nvm.c
@@ -0,0 +1,5614 @@
+#include "headers.h"
+
+#define DWORD unsigned int
+// Procedure: ReadEEPROMStatusRegister
+//
+// Description: Reads the standard EEPROM Status Register.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter )
+{
+ UCHAR uiData = 0;
+ DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UINT value = 0;
+ UINT value1 = 0;
+
+ /* Read the EEPROM status register */
+ value = EEPROM_READ_STATUS_REGISTER ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
+
+ while ( dwRetries != 0 )
+ {
+ value=0;
+ uiStatus = 0 ;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus));
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
+ break;
+ }
+
+ /* Wait for Avail bit to be set. */
+ if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 )
+ {
+ /* Clear the Avail/Full bits - which ever is set. */
+ value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+ uiData = (UCHAR)value;
+
+ break;
+ }
+
+ dwRetries-- ;
+ if ( dwRetries == 0 )
+ {
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
+ return uiData;
+ }
+ if( !(dwRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ uiStatus = 0 ;
+ }
+ return uiData;
+} /* ReadEEPROMStatusRegister */
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROMBulk
+//
+// Description: This routine reads 16Byte data from EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// dwAddress - EEPROM Offset to read the data from.
+// pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter,
+ DWORD dwAddress,
+ DWORD *pdwData,
+ DWORD dwNumWords
+ )
+{
+ DWORD dwIndex = 0;
+ DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UINT value= 0;
+ UINT value1 = 0;
+ UCHAR *pvalue;
+
+ /* Flush the read and cmd queue. */
+ value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH );
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+ value=0;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+
+ /* Clear the Avail/Full bits. */
+ value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+
+ value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ );
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
+
+ while ( dwRetries != 0 )
+ {
+
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
+ return -ENODEV;
+ }
+
+ /* If we are reading 16 bytes we want to be sure that the queue
+ * is full before we read. In the other cases we are ok if the
+ * queue has data available */
+ if ( dwNumWords == 4 )
+ {
+ if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 )
+ {
+ /* Clear the Avail/Full bits - which ever is set. */
+ value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ break;
+ }
+ }
+ else if ( dwNumWords == 1 )
+ {
+
+ if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 )
+ {
+ /* We just got Avail and we have to read 32bits so we
+ * need this sleep for Cardbus kind of devices. */
+ if (Adapter->chip_id == 0xBECE0210 )
+ udelay(800);
+
+ /* Clear the Avail/Full bits - which ever is set. */
+ value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ break;
+ }
+ }
+
+ uiStatus = 0;
+
+ dwRetries--;
+ if(dwRetries == 0)
+ {
+ value=0;
+ value1=0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", dwNumWords, value, value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
+ return STATUS_FAILURE;
+ }
+ if( !(dwRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ }
+
+ for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ )
+ {
+ /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
+ pvalue = (PUCHAR)(pdwData + dwIndex);
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[0] = value;
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[1] = value;
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[2] = value;
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[3] = value;
+ }
+
+ return STATUS_SUCCESS;
+} /* ReadBeceemEEPROMBulk() */
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROM
+//
+// Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
+// reads to do this operation.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - EEPROM Offset to read the data from.
+// pBuffer - Pointer to word where data needs to be stored in.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter,
+ DWORD uiOffset,
+ DWORD *pBuffer
+ )
+{
+ UINT uiData[8] = {0};
+ UINT uiByteOffset = 0;
+ UINT uiTempOffset = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> ");
+
+ uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
+ uiByteOffset = uiOffset - uiTempOffset;
+
+ ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
+
+ /* A word can overlap at most over 2 pages. In that case we read the
+ * next page too. */
+ if ( uiByteOffset > 12 )
+ {
+ ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
+ }
+
+ OsalMemMove( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
+
+ return STATUS_SUCCESS;
+} /* ReadBeceemEEPROM() */
+
+
+#if 0
+//-----------------------------------------------------------------------------
+// Procedure: IsEEPROMWriteDone
+//
+// Description: Reads the SPI status to see the status of previous write.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// BOOLEAN - TRUE - write went through
+// - FALSE - Write Failed.
+//-----------------------------------------------------------------------------
+
+BOOLEAN IsEEPROMWriteDone(PMINI_ADAPTER Adapter)
+{
+ UINT uiRetries = 16;
+ //UINT uiStatus = 0;
+ UINT value;
+
+ //sleep for 1.2ms ..worst case EEPROM write can take up to 1.2ms.
+ mdelay(2);
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ while(((value >> 14) & 1) == 1)
+ {
+ // EEPROM_SPI_Q_STATUS1_REG will be cleared only if write back to that.
+ value = (0x1 << 14);
+ wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ udelay(1000);
+ uiRetries--;
+ if(uiRetries == 0)
+ {
+ return FALSE;
+ }
+ value = 0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+ }
+ return TRUE;
+
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROMBulk
+//
+// Description: This routine reads 16Byte data from EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// dwAddress - EEPROM Offset to read the data from.
+// pdwData - Pointer to double word where data needs to be stored in.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
+{
+ DWORD dwRetries = 16;
+ DWORD dwIndex = 0;
+ UINT value, tmpVal;
+
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
+
+ //read 0x0f003020 untill bit 1 of 0x0f003008 is set.
+ while(((value >> 1) & 1) == 0)
+ {
+
+ rdmalt (Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
+ dwRetries--;
+ if(dwRetries == 0)
+ {
+ return -1;
+ }
+ value = 0;
+ rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
+ }
+
+ value = dwAddress | 0xfb000000;
+ wrmalt (Adapter, 0x0f003018, &value, sizeof(value));
+
+ udelay(1000);
+ value = 0;
+ for(dwIndex = 0;dwIndex < 4 ; dwIndex++)
+ {
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] = value;
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 8);
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 16);
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 24);
+
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROM
+//
+// Description: This routine reads 4Byte data from EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// dwAddress - EEPROM Offset to read the data from.
+// pdwData - Pointer to double word where data needs to be stored in.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
+{
+
+ DWORD dwReadValue = 0;
+ DWORD dwRetries = 16, dwCompleteWord = 0;
+ UINT value, tmpVal;
+
+ rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
+ while (((value >> 1) & 1) == 0) {
+ rdmalt(Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
+
+ if (dwRetries == 0) {
+ return -1;
+ }
+ rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
+ }
+
+
+ //wrm (0x0f003018, 0xNbXXXXXX) // N is the number of bytes u want to read (0 means 1, f means 16, b is the opcode for page read)
+ // Follow it up by N executions of rdm(0x0f003020) to read the rxed bytes from rx queue.
+ dwAddress |= 0x3b000000;
+ wrmalt(Adapter, 0x0f003018,&dwAddress,4);
+ mdelay(10);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord=dwReadValue;
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<8);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<16);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<24);
+
+ *pdwData = dwCompleteWord;
+
+ return 0;
+}
+#endif
+
+INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
+{
+ INT Status=0, i;
+ unsigned char puMacAddr[6] = {0};
+ INT AllZeroMac = 0;
+ INT AllFFMac = 0;
+
+ Status = BeceemNVMRead(Adapter,
+ (PUINT)&puMacAddr[0],
+ INIT_PARAMS_1_MACADDRESS_ADDRESS,
+ MAC_ADDRESS_SIZE);
+
+ if(Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Error in Reading the mac Addres with status :%d", Status);
+ return Status;
+ }
+
+ memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Modem MAC Addr :");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_PRINTK, 0, DBG_LVL_ALL,&Adapter->dev->dev_addr[0],MAC_ADDRESS_SIZE);
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+
+ if(Adapter->dev->dev_addr[i] == 0x00)
+ AllZeroMac++;
+ if(Adapter->dev->dev_addr[i] == 0xFF)
+ AllFFMac++;
+
+ }
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\n");
+ if(AllZeroMac == MAC_ADDRESS_SIZE)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all 00's");
+ if(AllFFMac == MAC_ADDRESS_SIZE)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all FF's");
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMBulkRead
+//
+// Description: Reads the EEPROM and returns the Data.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from EEPROM
+// uiOffset - Offset of EEPROM from where data should be read
+// uiNumBytes - Number of bytes to be read from the EEPROM.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if EEPROM read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemEEPROMBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiData[4] = {0};
+ //UINT uiAddress = 0;
+ UINT uiBytesRemaining = uiNumBytes;
+ UINT uiIndex = 0;
+ UINT uiTempOffset = 0;
+ UINT uiExtraBytes = 0;
+ UINT uiFailureRetries = 0;
+ PUCHAR pcBuff = (PUCHAR)pBuffer;
+
+
+ if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining)
+ {
+ uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
+ uiExtraBytes = uiOffset-uiTempOffset;
+ ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
+ if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
+ {
+ OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);
+
+ uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
+ uiIndex += (MAX_RW_SIZE - uiExtraBytes);
+ uiOffset += (MAX_RW_SIZE - uiExtraBytes);
+ }
+ else
+ {
+ OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
+ uiIndex += uiBytesRemaining;
+ uiOffset += uiBytesRemaining;
+ uiBytesRemaining = 0;
+ }
+
+
+ }
+
+
+ while(uiBytesRemaining && uiFailureRetries != 128)
+ {
+ if(Adapter->device_removed )
+ {
+ return -1;
+ }
+
+ if(uiBytesRemaining >= MAX_RW_SIZE)
+ {
+ /* For the requests more than or equal to 16 bytes, use bulk
+ * read function to make the access faster.
+ * We read 4 Dwords of data */
+ if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
+ {
+ OsalMemMove(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
+ uiOffset += MAX_RW_SIZE;
+ uiBytesRemaining -= MAX_RW_SIZE;
+ uiIndex += MAX_RW_SIZE;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+ else if(uiBytesRemaining >= 4)
+ {
+ if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
+ {
+ OsalMemMove(pcBuff+uiIndex,&uiData[0],4);
+ uiOffset += 4;
+ uiBytesRemaining -= 4;
+ uiIndex +=4;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+ else
+ { // Handle the reads less than 4 bytes...
+ PUCHAR pCharBuff = (PUCHAR)pBuffer;
+ pCharBuff += uiIndex;
+ if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
+ {
+ OsalMemMove(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
+ uiBytesRemaining = 0;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkRead
+//
+// Description: Reads the FLASH and returns the Data.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from FLASH
+// uiOffset - Offset of FLASH from where data should be read
+// uiNumBytes - Number of bytes to be read from the FLASH.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if FLASH read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemFlashBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiIndex = 0;
+ UINT uiBytesToRead = uiNumBytes;
+ INT Status = 0;
+ UINT uiPartOffset = 0;
+
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed ");
+ return -ENODEV;
+ }
+
+ //Adding flash Base address
+// uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
+ return Status;
+#endif
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+
+ if(uiOffset % MAX_RW_SIZE)
+ {
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
+ uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);
+
+ if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
+ {
+ Status = -1;
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+ }
+
+ uiIndex += uiBytesToRead;
+ uiOffset += uiBytesToRead;
+ uiNumBytes -= uiBytesToRead;
+ }
+
+ while(uiNumBytes)
+ {
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);
+
+ if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
+ {
+ Status = -1;
+ break;
+ }
+
+
+ uiIndex += uiBytesToRead;
+ uiOffset += uiBytesToRead;
+ uiNumBytes -= uiBytesToRead;
+
+ }
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashSize
+//
+// Description: Finds the size of FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - size of the FLASH Storage.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
+{
+#if 0
+ if(Adapter->bDDRInitDone)
+ {
+ return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT|FLASH_SIZE_ADDR);
+ }
+
+ return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT|FLASH_SIZE_ADDR);
+#endif
+ if(IsFlash2x(Adapter))
+ return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
+ else
+ return 32*1024;
+
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetEEPROMSize
+//
+// Description: Finds the size of EEPROM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - size of the EEPROM Storage.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
+{
+ UINT uiData = 0;
+ UINT uiIndex = 0;
+
+//
+// if EEPROM is present and already Calibrated,it will have
+// 'BECM' string at 0th offset.
+// To find the EEPROM size read the possible boundaries of the
+// EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
+// result in wrap around. So when we get the End of the EEPROM we will
+// get 'BECM' string which is indeed at offset 0.
+//
+ BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
+ if(uiData == BECM)
+ {
+ for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
+ {
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
+ if(uiData == BECM)
+ {
+ return uiIndex*1024;
+ }
+ }
+ }
+ else
+ {
+//
+// EEPROM may not be present or not programmed
+//
+
+ uiData = 0xBABEFACE;
+ if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE))
+ {
+ uiData = 0;
+ for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
+ {
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
+ if(uiData == 0xBABEFACE)
+ {
+ return uiIndex*1024;
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+#if 0
+/***********************************************************************************/
+//
+// WriteBeceemEEPROM: Writes 4 byte data to EEPROM offset.
+//
+// uiEEPROMOffset - Offset to be written to.
+// uiData - Data to be written.
+//
+/***********************************************************************************/
+
+INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData)
+{
+ INT Status = 0;
+ ULONG ulRdBk = 0;
+ ULONG ulRetryCount = 3;
+ UINT value;
+
+ if(uiEEPROMOffset > EEPROM_END)
+ {
+
+ return -1;
+ }
+
+ uiData = htonl(uiData);
+ while(ulRetryCount--)
+ {
+ value = 0x06000000;
+ wrmalt(Adapter, 0x0F003018,&value, sizeof(value));//flush the EEPROM FIFO.
+ wrmalt(Adapter, 0x0F00301C,&uiData, sizeof(uiData));
+ value = 0x3A000000 | uiEEPROMOffset;
+ wrmalt(Adapter, 0x0F003018,&value, sizeof(value));
+ __udelay(100000);
+ //read back and verify.
+ Status = ReadBeceemEEPROM(Adapter,uiEEPROMOffset,(UINT *)&ulRdBk);
+ if(Status == 0)
+ {
+ if(ulRdBk == uiData)
+ {
+ return Status;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback does not match\n");
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback failed\n");
+ }
+ }
+
+ return 0;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Procedure: FlashSectorErase
+//
+// Description: Finds the sector size of the FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// addr - sector start address
+// numOfSectors - number of sectors to be erased.
+//
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+
+INT FlashSectorErase(PMINI_ADAPTER Adapter,
+ UINT addr,
+ UINT numOfSectors)
+{
+ UINT iIndex = 0, iRetries = 0;
+ UINT uiStatus = 0;
+ UINT value;
+
+ for(iIndex=0;iIndex<numOfSectors;iIndex++)
+ {
+ value = 0x06000000;
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+
+ value = (0xd8000000 | (addr & 0xFFFFFF));
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ iRetries = 0;
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries++;
+ //After every try lets make the CPU free for 10 ms. generally time taken by the
+ //the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
+ //won't hamper performance in any case.
+ msleep(10);
+ }while((uiStatus & 0x1) && (iRetries < 400));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"iRetries crossing the limit of 80000\n");
+ return STATUS_FAILURE;
+ }
+
+ addr += Adapter->uiSectorSize;
+ }
+ return 0;
+}
+//-----------------------------------------------------------------------------
+// Procedure: flashByteWrite
+//
+// Description: Performs Byte by Byte write to flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT flashByteWrite(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+
+ UINT value;
+ ULONG ulData = *(PUCHAR)pData;
+
+//
+// need not write 0xFF because write requires an erase and erase will
+// make whole sector 0xFF.
+//
+
+ if(0xFF == ulData)
+ {
+ return STATUS_SUCCESS;
+ }
+
+// DumpDebug(NVM_RW,("flashWrite ====>\n"));
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ value = (0x02000000 | (uiOffset & 0xFFFFFF));
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ //__udelay(950);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries--;
+ if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+
+ }while((uiStatus & 0x1) && (iRetries >0) );
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Procedure: flashWrite
+//
+// Description: Performs write to flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT flashWrite(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+
+{
+ //UINT uiStatus = 0;
+ //INT iRetries = 0;
+ //UINT uiReadBack = 0;
+
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+
+ UINT value;
+ UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+ if (!OsalMemCompare(pData, uiErasePattern, MAX_RW_SIZE))
+ {
+ return 0;
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
+ return STATUS_FAILURE;
+ }
+
+ //__udelay(950);
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ iRetries--;
+ //this will ensure that in there will be no changes in the current path.
+ //currently one rdm/wrm takes 125 us.
+ //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
+ //Hence current implementation cycle will intoduce no delay in current path
+ if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries > 0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: flashByteWriteStatus
+//
+// Description: Performs byte by byte write to flash with write done status check
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of the Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+INT flashByteWriteStatus(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+ ULONG ulData = *(PUCHAR)pData;
+ UINT value;
+
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+
+ if(0xFF == ulData)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ // DumpDebug(NVM_RW,("flashWrite ====>\n"));
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
+ return STATUS_SUCCESS;
+ }
+ if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ value = (0x02000000 | (uiOffset & 0xFFFFFF));
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ //msleep(1);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ iRetries--;
+ if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries > 0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+
+}
+//-----------------------------------------------------------------------------
+// Procedure: flashWriteStatus
+//
+// Description: Performs write to flash with write done status check
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of the Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT flashWriteStatus(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+ //UINT uiReadBack = 0;
+ UINT value;
+ UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+ if (!OsalMemCompare(pData,uiErasePattern,MAX_RW_SIZE))
+ {
+ return 0;
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
+ return STATUS_FAILURE;
+ }
+ // __udelay(1);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries--;
+ //this will ensure that in there will be no changes in the current path.
+ //currently one rdm/wrm takes 125 us.
+ //Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
+ //Hence current implementation cycle will intoduce no delay in current path
+ if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries >0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmRestoreBlockProtectStatus
+//
+// Description: Restores the original block protection status.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// ulWriteStatus -Original status
+// Returns:
+// <VOID>
+//
+//-----------------------------------------------------------------------------
+
+VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus)
+{
+ UINT value;
+ value = (FLASH_CMD_WRITE_ENABLE<< 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+
+ udelay(20);
+ value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+}
+//-----------------------------------------------------------------------------
+// Procedure: BcmFlashUnProtectBlock
+//
+// Description: UnProtects appropriate blocks for writing.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
+// Returns:
+// ULONG - Status value before UnProtect.
+//
+//-----------------------------------------------------------------------------
+ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength)
+{
+ ULONG ulStatus = 0;
+ ULONG ulWriteStatus = 0;
+ UINT value;
+ uiOffset = uiOffset&0x000FFFFF;
+
+//
+// Implemented only for 1MB Flash parts.
+//
+ if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
+ {
+ //
+ // Get Current BP status.
+ //
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(10);
+ //
+ // Read status will be WWXXYYZZ. We have to take only WW.
+ //
+ rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
+ ulStatus >>= 24;
+ ulWriteStatus = ulStatus;
+
+ //
+ // Bits [5-2] give current block level protection status.
+ // Bit5: BP3 - DONT CARE
+ // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
+ // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
+ //
+
+ if(ulStatus)
+ {
+ if((uiOffset+uiLength) <= 0x80000)
+ {
+ //
+ // Offset comes in lower half of 1MB. Protect the upper half.
+ // Clear BP1 and BP0 and set BP2.
+ //
+ ulWriteStatus |= (0x4<<2);
+ ulWriteStatus &= ~(0x3<<2);
+ }
+ else if((uiOffset+uiLength) <= 0xC0000)
+ {
+ //
+ // Offset comes below Upper 1/4. Upper 1/4 can be protected.
+ // Clear BP2 and set BP1 and BP0.
+ //
+ ulWriteStatus |= (0x3<<2);
+ ulWriteStatus &= ~(0x1<<4);
+ }
+ else if((uiOffset+uiLength) <= 0xE0000)
+ {
+ //
+ // Offset comes below Upper 1/8. Upper 1/8 can be protected.
+ // Clear BP2 and BP0 and set BP1
+ //
+ ulWriteStatus |= (0x1<<3);
+ ulWriteStatus &= ~(0x5<<2);
+
+ }
+ else if((uiOffset+uiLength) <= 0xF0000)
+ {
+ //
+ // Offset comes below Upper 1/16. Only upper 1/16 can be protected.
+ // Set BP0 and Clear BP2,BP1.
+ //
+ ulWriteStatus |= (0x1<<2);
+ ulWriteStatus &= ~(0x3<<3);
+ }
+ else
+ {
+ //
+ // Unblock all.
+ // Clear BP2,BP1 and BP0.
+ //
+ ulWriteStatus &= ~(0x7<<2);
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE<< 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+ value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+
+ }
+
+ }
+ return ulStatus;
+}
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkWrite
+//
+// Description: Performs write to the flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemFlashBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ PCHAR pTempBuff = NULL;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;
+ UINT uiIndex = 0;
+ UINT uiOffsetFromSectStart = 0;
+ UINT uiSectAlignAddr = 0;
+ UINT uiCurrSectOffsetAddr = 0;
+ UINT uiSectBoundary = 0;
+ UINT uiNumSectTobeRead = 0;
+ UCHAR ucReadBk[16] = {0};
+ ULONG ulStatus = 0;
+ INT Status = STATUS_SUCCESS;
+ UINT uiTemp = 0;
+ UINT index = 0;
+ UINT uiPartOffset = 0;
+ #if 0
+ struct timeval tv1 = {0};
+ struct timeval tv2 = {0};
+
+ struct timeval tr = {0};
+ struct timeval te = {0};
+ struct timeval tw = {0};
+ struct timeval twv = {0};
+ #endif
+
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
+ return Status;
+#endif
+
+ uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
+
+ //Adding flash Base address
+// uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
+
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
+ uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
+ uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
+
+ //pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
+ pTempBuff = OsalMemAlloc(Adapter->uiSectorSize ,'!MVN');
+ if(NULL == pTempBuff)
+ {
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+//
+// check if the data to be written is overlapped accross sectors
+//
+ if(uiOffset+uiNumBytes < uiSectBoundary)
+ {
+ uiNumSectTobeRead = 1;
+ }
+ else
+ {
+ // Number of sectors = Last sector start address/First sector start address
+ uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
+ if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
+ {
+ uiNumSectTobeRead++;
+ }
+ }
+ #if 1
+ //Check whether Requested sector is writable or not in case of flash2x write. But if write call is
+ // for DSD calibration, allow it without checking of sector permission
+
+ if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
+ {
+ index = 0;
+ uiTemp = uiNumSectTobeRead ;
+ while(uiTemp)
+ {
+ if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable",
+ (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
+ Status = SECTOR_IS_NOT_WRITABLE;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ uiTemp = uiTemp - 1;
+ index = index + 1 ;
+ }
+ }
+ #endif
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ while(uiNumSectTobeRead)
+ {
+ //do_gettimeofday(&tv1);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000));
+ uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ BcmDoChipSelect(Adapter,uiSectAlignAddr);
+
+ if(0 != BeceemFlashBulkRead(Adapter,
+ (PUINT)pTempBuff,
+ uiOffsetFromSectStart,
+ Adapter->uiSectorSize))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+
+ //do_gettimeofday(&tr);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
+
+ ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
+
+
+ if(uiNumSectTobeRead > 1)
+ {
+
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
+ uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ }
+ else
+ {
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
+ }
+
+ if(IsFlash2x(Adapter))
+ {
+ SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
+ }
+
+ FlashSectorErase(Adapter,uiPartOffset,1);
+ //do_gettimeofday(&te);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000));
+
+ for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
+ {
+ if(Adapter->device_removed)
+ {
+ Status = -1;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex])))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ }
+
+ //do_gettimeofday(&tw);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000));
+ for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
+ {
+ if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
+ {
+ if(Adapter->ulFlashWriteSize == 1)
+ {
+ UINT uiReadIndex = 0;
+ for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++)
+ {
+ if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex])
+ {
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex]))
+ {
+ Status = STATUS_FAILURE;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
+ {
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
+ {
+ Status = STATUS_FAILURE;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ }
+ }
+ }
+ }
+ //do_gettimeofday(&twv);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000));
+
+
+ if(ulStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,ulStatus);
+ ulStatus = 0;
+ }
+
+ uiCurrSectOffsetAddr = 0;
+ uiSectAlignAddr = uiSectBoundary;
+ uiSectBoundary += Adapter->uiSectorSize;
+ uiOffsetFromSectStart += Adapter->uiSectorSize;
+ uiNumSectTobeRead--;
+ }
+ //do_gettimeofday(&tv2);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
+//
+// Cleanup.
+//
+BeceemFlashBulkWrite_EXIT:
+ if(ulStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,ulStatus);
+ }
+ if(pTempBuff)
+ {
+ OsalMemFree(pTempBuff,Adapter->uiSectorSize);
+ }
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkWriteStatus
+//
+// Description: Writes to Flash. Checks the SPI status after each write.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemFlashBulkWriteStatus(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ PCHAR pTempBuff = NULL;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;
+ UINT uiIndex = 0;
+ UINT uiOffsetFromSectStart = 0;
+ UINT uiSectAlignAddr = 0;
+ UINT uiCurrSectOffsetAddr = 0;
+ UINT uiSectBoundary = 0;
+ UINT uiNumSectTobeRead = 0;
+ UCHAR ucReadBk[16] = {0};
+ ULONG ulStatus = 0;
+ UINT Status = STATUS_SUCCESS;
+ UINT uiTemp = 0;
+ UINT index = 0;
+ UINT uiPartOffset = 0;
+
+ uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
+
+ //uiOffset += Adapter->ulFlashCalStart;
+ //Adding flash Base address
+// uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
+
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
+ uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
+ uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
+
+
+
+// pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
+ pTempBuff = OsalMemAlloc(Adapter->uiSectorSize,'!MVN');
+ if(NULL == pTempBuff)
+ {
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+//
+// check if the data to be written is overlapped accross sectors
+//
+ if(uiOffset+uiNumBytes < uiSectBoundary)
+ {
+ uiNumSectTobeRead = 1;
+ }
+ else
+ {
+// Number of sectors = Last sector start address/First sector start address
+ uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
+ if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
+ {
+ uiNumSectTobeRead++;
+ }
+ }
+
+ if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
+ {
+ index = 0;
+ uiTemp = uiNumSectTobeRead ;
+ while(uiTemp)
+ {
+ if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable",
+ (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
+ Status = SECTOR_IS_NOT_WRITABLE;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+ uiTemp = uiTemp - 1;
+ index = index + 1 ;
+ }
+ }
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ while(uiNumSectTobeRead)
+ {
+ uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ BcmDoChipSelect(Adapter,uiSectAlignAddr);
+ if(0 != BeceemFlashBulkRead(Adapter,
+ (PUINT)pTempBuff,
+ uiOffsetFromSectStart,
+ Adapter->uiSectorSize))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+
+ ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize);
+
+ if(uiNumSectTobeRead > 1)
+ {
+
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
+ uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ }
+ else
+ {
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
+ }
+
+ if(IsFlash2x(Adapter))
+ {
+ SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
+ }
+
+ FlashSectorErase(Adapter,uiPartOffset,1);
+
+ for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
+
+ {
+ if(Adapter->device_removed)
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+ }
+
+ if(bVerify)
+ {
+ for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
+ {
+#if 0
+ if(0 == BeceemFlashBulkRead(Adapter,uiReadBk,uiOffsetFromSectStart+uiIndex + Adapter->ulFlashCalStart ,MAX_RW_SIZE))
+ {
+ for(uiReadIndex = 0;uiReadIndex < 4; uiReadIndex++)
+ {
+ if(*((PUINT)&pTempBuff[uiIndex+uiReadIndex*4]) != uiReadBk[uiReadIndex])
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+
+ }
+ }
+
+ }
+#endif
+
+ if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
+ {
+ if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
+ {
+ Status = STATUS_FAILURE;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+
+ }
+
+ }
+ }
+
+ if(ulStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,ulStatus);
+ ulStatus = 0;
+ }
+
+ uiCurrSectOffsetAddr = 0;
+ uiSectAlignAddr = uiSectBoundary;
+ uiSectBoundary += Adapter->uiSectorSize;
+ uiOffsetFromSectStart += Adapter->uiSectorSize;
+ uiNumSectTobeRead--;
+ }
+//
+// Cleanup.
+//
+BeceemFlashBulkWriteStatus_EXIT:
+ if(ulStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,ulStatus);
+ }
+ if(pTempBuff)
+ {
+ OsalMemFree(pTempBuff,Adapter->uiSectorSize);
+ }
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: PropagateCalParamsFromEEPROMToMemory
+//
+// Description: Dumps the calibration section of EEPROM to DDR.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+
+INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
+{
+ PCHAR pBuff = OsalMemAlloc(BUFFER_4K,'3MVN');
+ UINT uiEepromSize = 0;
+ UINT uiIndex = 0;
+ UINT uiBytesToCopy = 0;
+ UINT uiCalStartAddr = EEPROM_CALPARAM_START;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT value;
+ INT Status = 0;
+ if(pBuff == NULL)
+ {
+ return -1;
+ }
+
+ if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
+ {
+
+ OsalMemFree(pBuff,BUFFER_4K);
+ return -1;
+ }
+
+ uiEepromSize >>= 16;
+ if(uiEepromSize > 1024*1024)
+ {
+ OsalMemFree(pBuff,BUFFER_4K);
+ return -1;
+ }
+
+
+ uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
+
+ while(uiBytesToCopy)
+ {
+ if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy))
+ {
+ Status = -1;
+ break;
+ }
+ wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy);
+ uiMemoryLoc += uiBytesToCopy;
+ uiEepromSize -= uiBytesToCopy;
+ uiCalStartAddr += uiBytesToCopy;
+ uiIndex += uiBytesToCopy/4;
+ uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
+
+ }
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value));
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value));
+ OsalMemFree(pBuff,MAX_RW_SIZE);
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: PropagateCalParamsFromFlashToMemory
+//
+// Description: Dumps the calibration section of EEPROM to DDR.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter)
+{
+ PCHAR pBuff, pPtr;
+ UINT uiEepromSize = 0;
+ UINT uiBytesToCopy = 0;
+ //UINT uiIndex = 0;
+ UINT uiCalStartAddr = EEPROM_CALPARAM_START;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT value;
+ INT Status = 0;
+//
+// Write the signature first. This will ensure firmware does not access EEPROM.
+//
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
+
+ if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4))
+ {
+ return -1;
+ }
+ uiEepromSize = ntohl(uiEepromSize);
+ uiEepromSize >>= 16;
+
+//
+// subtract the auto init section size
+//
+ uiEepromSize -= EEPROM_CALPARAM_START;
+
+ if(uiEepromSize > 1024*1024)
+ {
+ return -1;
+ }
+
+ pBuff = OsalMemAlloc(uiEepromSize, 0);
+
+ if ( pBuff == NULL )
+ {
+ return -1;
+ }
+
+ if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
+ {
+ OsalMemFree(pBuff, 0);
+ return -1;
+ }
+
+ pPtr = pBuff;
+
+ uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
+
+ while(uiBytesToCopy)
+ {
+ Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status);
+ break;
+ }
+
+ pPtr += uiBytesToCopy;
+ uiEepromSize -= uiBytesToCopy;
+ uiMemoryLoc += uiBytesToCopy;
+ uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
+ }
+
+ OsalMemFree(pBuff, 0);
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMReadBackandVerify
+//
+// Description: Read back the data written and verifies.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemEEPROMReadBackandVerify(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiRdbk = 0;
+ UINT uiIndex = 0;
+ UINT uiData = 0;
+ UINT auiData[4] = {0};
+
+ while(uiNumBytes)
+ {
+ if(Adapter->device_removed )
+ {
+ return -1;
+ }
+
+ if(uiNumBytes >= MAX_RW_SIZE)
+ {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
+ BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
+
+ if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
+ {
+ // re-write
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE);
+ mdelay(3);
+ BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
+
+ if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
+ {
+ return -1;
+ }
+ }
+ uiOffset += MAX_RW_SIZE;
+ uiNumBytes -= MAX_RW_SIZE;
+ uiIndex += 4;
+
+ }
+ else if(uiNumBytes >= 4)
+ {
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
+ if(uiData != pBuffer[uiIndex])
+ {
+ //re-write
+ BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE);
+ mdelay(3);
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
+ if(uiData != pBuffer[uiIndex])
+ {
+ return -1;
+ }
+ }
+ uiOffset += 4;
+ uiNumBytes -= 4;
+ uiIndex++;
+
+ }
+ else
+ { // Handle the reads less than 4 bytes...
+ uiData = 0;
+ OsalMemMove(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
+ BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);
+
+ if(memcmp(&uiData, &uiRdbk, uiNumBytes))
+ return -1;
+
+ uiNumBytes = 0;
+ }
+
+ }
+
+ return 0;
+}
+
+VOID BcmSwapWord(UINT *ptr1) {
+
+ UINT tempval = (UINT)*ptr1;
+ char *ptr2 = (char *)&tempval;
+ char *ptr = (char *)ptr1;
+
+ ptr[0] = ptr2[3];
+ ptr[1] = ptr2[2];
+ ptr[2] = ptr2[1];
+ ptr[3] = ptr2[0];
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMWritePage
+//
+// Description: Performs page write (16bytes) to the EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiData - Data to be written.
+// uiOffset - Offset of the EEPROM where data needs to be written to.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset )
+{
+ UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UCHAR uiEpromStatus = 0;
+ UINT value =0 ;
+
+ /* Flush the Write/Read/Cmd queues. */
+ value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH );
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+ value = 0 ;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+
+ /* Clear the Empty/Avail/Full bits. After this it has been confirmed
+ * that the bit was cleared by reading back the register. See NOTE below.
+ * We also clear the Read queues as we do a EEPROM status register read
+ * later. */
+ value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+
+ /* Enable write */
+ value = EEPROM_WRITE_ENABLE ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) );
+
+ /* We can write back to back 8bits * 16 into the queue and as we have
+ * checked for the queue to be empty we can write in a burst. */
+
+ value = uiData[0];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[1];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[2];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[3];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
+ * shows that we see 7 for the EEPROM data write. Which means that
+ * queue got full, also space is available as well as the queue is empty.
+ * This may happen in sequence. */
+ value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) );
+
+ /* Ideally we should loop here without tries and eventually succeed.
+ * What we are checking if the previous write has completed, and this
+ * may take time. We should wait till the Empty bit is set. */
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+ while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
+ {
+ uiRetries--;
+ if ( uiRetries == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
+ return STATUS_FAILURE ;
+ }
+
+ if( !(uiRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
+ return -ENODEV;
+ }
+
+ }
+
+ if ( uiRetries != 0 )
+ {
+ /* Clear the ones that are set - either, Empty/Full/Avail bits */
+ value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+ }
+
+ /* Here we should check if the EEPROM status register is correct before
+ * proceeding. Bit 0 in the EEPROM Status register should be 0 before
+ * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
+ * with the previous write. Note also that issuing this read finally
+ * means the previous write to the EEPROM has completed. */
+ uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ uiEpromStatus = 0;
+ while ( uiRetries != 0 )
+ {
+ uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ;
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
+ return -ENODEV;
+ }
+ if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) );
+ return STATUS_SUCCESS ;
+ }
+ uiRetries--;
+ if ( uiRetries == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
+ return STATUS_FAILURE ;
+ }
+ uiEpromStatus = 0;
+ if( !(uiRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ }
+
+ return STATUS_SUCCESS ;
+} /* BeceemEEPROMWritePage */
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMBulkWrite
+//
+// Description: Performs write to the EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the EEPROM where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemEEPROMBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUCHAR pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ UINT uiBytesToCopy = uiNumBytes;
+ //UINT uiRdbk = 0;
+ UINT uiData[4] = {0};
+ UINT uiIndex = 0;
+ UINT uiTempOffset = 0;
+ UINT uiExtraBytes = 0;
+ //PUINT puiBuffer = (PUINT)pBuffer;
+ //INT value;
+
+ if(uiOffset%MAX_RW_SIZE && uiBytesToCopy)
+ {
+ uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
+ uiExtraBytes = uiOffset-uiTempOffset;
+
+
+ BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE);
+
+ if(uiBytesToCopy >= (16 -uiExtraBytes))
+ {
+ OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);
+
+ if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
+ return STATUS_FAILURE;
+
+ uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
+ uiIndex += (MAX_RW_SIZE - uiExtraBytes);
+ uiOffset += (MAX_RW_SIZE - uiExtraBytes);
+ }
+ else
+ {
+ OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);
+
+ if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
+ return STATUS_FAILURE;
+
+ uiIndex += uiBytesToCopy;
+ uiOffset += uiBytesToCopy;
+ uiBytesToCopy = 0;
+ }
+
+
+ }
+
+ while(uiBytesToCopy)
+ {
+ if(Adapter->device_removed)
+ {
+ return -1;
+ }
+
+ if(uiBytesToCopy >= MAX_RW_SIZE)
+ {
+
+ if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) )
+ return STATUS_FAILURE;
+
+ uiIndex += MAX_RW_SIZE;
+ uiOffset += MAX_RW_SIZE;
+ uiBytesToCopy -= MAX_RW_SIZE;
+ }
+ else
+ {
+ //
+ // To program non 16byte aligned data, read 16byte and then update.
+ //
+ BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16);
+ OsalMemMove(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
+
+
+ if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
+ return STATUS_FAILURE;
+ uiBytesToCopy = 0;
+ }
+
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemNVMRead
+//
+// Description: Reads n number of bytes from NVM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from NVM
+// uiOffset - Offset of NVM from where data should be read
+// uiNumBytes - Number of bytes to be read from the NVM.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemNVMRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ INT Status = 0;
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT uiTemp = 0, value;
+#endif
+
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ if(Adapter->bFlashRawRead == FALSE)
+ {
+ if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
+ return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes);
+ uiOffset = uiOffset+ Adapter->ulFlashCalStart ;
+ }
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
+#else
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+ Status = BeceemFlashBulkRead(Adapter,
+ pBuffer,
+ uiOffset,
+ uiNumBytes);
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+#endif
+ }
+ else if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Status = BeceemEEPROMBulkRead(Adapter,
+ pBuffer,
+ uiOffset,
+ uiNumBytes);
+ }
+ else
+ {
+ Status = -1;
+ }
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemNVMWrite
+//
+// Description: Writes n number of bytes to NVM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer contains the data to be written.
+// uiOffset - Offset of NVM where data to be written to.
+// uiNumBytes - Number of bytes to be written..
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM write is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemNVMWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ INT Status = 0;
+ UINT uiTemp = 0;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT uiIndex = 0;
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT value;
+#endif
+ UINT uiFlashOffset = 0;
+
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
+ Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify);
+ else
+ {
+ uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
+
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes);
+#else
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
+
+ if(Adapter->bStatusWrite == TRUE)
+ {
+ Status = BeceemFlashBulkWriteStatus(Adapter,
+ pBuffer,
+ uiFlashOffset,
+ uiNumBytes ,
+ bVerify);
+ }
+ else
+ {
+
+ Status = BeceemFlashBulkWrite(Adapter,
+ pBuffer,
+ uiFlashOffset,
+ uiNumBytes,
+ bVerify);
+ }
+#endif
+ }
+
+
+ if(uiOffset >= EEPROM_CALPARAM_START)
+ {
+ uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
+ while(uiNumBytes)
+ {
+ if(uiNumBytes > BUFFER_4K)
+ {
+ wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K);
+ uiNumBytes -= BUFFER_4K;
+ uiIndex += BUFFER_4K;
+ }
+ else
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes);
+ uiNumBytes = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START)
+ {
+ ULONG ulBytesTobeSkipped = 0;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases.
+ uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
+ ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
+ uiOffset += (EEPROM_CALPARAM_START - uiOffset);
+ while(uiNumBytes)
+ {
+ if(uiNumBytes > BUFFER_4K)
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K);
+ uiNumBytes -= BUFFER_4K;
+ uiIndex += BUFFER_4K;
+ }
+ else
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes);
+ uiNumBytes = 0;
+ break;
+ }
+ }
+
+ }
+ }
+
+ // restore the values.
+ wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp));
+ }
+ else if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Status = BeceemEEPROMBulkWrite(Adapter,
+ (PUCHAR)pBuffer,
+ uiOffset,
+ uiNumBytes,
+ bVerify);
+ if(bVerify)
+ {
+ Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes);
+ }
+ }
+ else
+ {
+ Status = -1;
+ }
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmUpdateSectorSize
+//
+// Description: Updates the sector size to FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiSectorSize - sector size
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM write is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize)
+{
+ INT Status = -1;
+ FLASH_CS_INFO sFlashCsInfo = {0};
+ UINT uiTemp = 0;
+
+ UINT uiSectorSig = 0;
+ UINT uiCurrentSectorSize = 0;
+
+ UINT value;
+
+
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+//
+// Before updating the sector size in the reserved area, check if already present.
+//
+ BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo));
+ uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
+ uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
+
+ if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
+ {
+
+ if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE))
+ {
+ if(uiSectorSize == uiCurrentSectorSize)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash");
+ Status = STATUS_SUCCESS;
+ goto Restore ;
+ }
+ }
+ }
+
+ if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE))
+ {
+
+ sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
+ sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
+
+ Status = BeceemFlashBulkWrite(Adapter,
+ (PUINT)&sFlashCsInfo,
+ Adapter->ulFlashControlSectionStart,
+ sizeof(sFlashCsInfo),
+ TRUE);
+
+
+ }
+
+ Restore :
+ // restore the values.
+ wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp));
+
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashSectorSize
+//
+// Description: Finds the sector size of the FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - sector size.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
+{
+ UINT uiSectorSize = 0;
+ UINT uiSectorSig = 0;
+
+ if(Adapter->bSectorSizeOverride &&
+ (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE))
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ else
+ {
+
+ uiSectorSig = FlashSectorSizeSig;
+
+ if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
+ {
+ uiSectorSize = FlashSectorSize;
+ //
+ // If the sector size stored in the FLASH makes sense then use it.
+ //
+ if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = uiSectorSize;
+ }
+ //No valid size in FLASH, check if Config file has it.
+ else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ // Init to Default, if none of the above works.
+ else
+ {
+ Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
+ }
+
+ }
+ else
+ {
+ if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ else
+ {
+ Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
+ }
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x \n", Adapter->uiSectorSize);
+ return Adapter->uiSectorSize;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmInitEEPROMQueues
+//
+// Description: Initialization of EEPROM queues.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter)
+{
+ UINT value = 0;
+ /* CHIP Bug : Clear the Avail bits on the Read queue. The default
+ * value on this register is supposed to be 0x00001102.
+ * But we get 0x00001122. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" );
+ value = EEPROM_READ_DATA_AVAIL;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ /* Flush the all the EEPROM queues. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
+ value =EEPROM_ALL_QUEUE_FLUSH ;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+
+ value = 0;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+
+ /* Read the EEPROM Status Register. Just to see, no real purpose. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) );
+
+ return STATUS_SUCCESS;
+} /* BcmInitEEPROMQueues() */
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmInitNVM
+//
+// Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
+{
+#ifdef BCM_SHM_INTERFACE
+#ifdef FLASH_DIRECT_ACCESS
+ unsigned int data,data1,data2 = 1;
+ wrm(ps_adapter, PAD_SELECT_REGISTER, &data2, 4);
+ data1 = rdm(ps_adapter,SYS_CFG,&data,4);
+ data1 = rdm(ps_adapter,SYS_CFG,&data,4);
+ data2 = (data | 0x80 | 0x8000);
+ wrm(ps_adapter,SYS_CFG, &data2,4); // over-write as Flash boot mode
+#endif
+ ps_adapter->eNVMType = NVM_FLASH;
+#else
+ BcmValidateNvmType(ps_adapter);
+ BcmInitEEPROMQueues(ps_adapter);
+#endif
+
+ if(ps_adapter->eNVMType == NVM_AUTODETECT)
+ {
+ ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
+ if(ps_adapter->eNVMType == NVM_UNKNOWN)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
+ }
+ }
+ else if(ps_adapter->eNVMType == NVM_FLASH)
+ {
+ BcmGetFlashCSInfo(ps_adapter);
+ }
+
+ BcmGetNvmSize(ps_adapter);
+
+ return STATUS_SUCCESS;
+}
+/***************************************************************************/
+/*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
+*
+*Input Parameter:
+* Adapter data structure
+*Return Value :
+* 0. means sucess;
+*/
+/***************************************************************************/
+
+INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
+ }
+ else if(Adapter->eNVMType == NVM_FLASH)
+ {
+ Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmValidateNvm
+//
+// Description: Validates the NVM Type option selected against the device
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <VOID>
+//-----------------------------------------------------------------------------
+VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
+{
+
+ //
+ // if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
+ // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
+ // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
+ //
+
+ if(Adapter->eNVMType == NVM_FLASH &&
+ Adapter->chip_id < 0xBECE3300)
+ {
+ Adapter->eNVMType = NVM_AUTODETECT;
+ }
+}
+//-----------------------------------------------------------------------------
+// Procedure: BcmReadFlashRDID
+//
+// Description: Reads ID from Serial Flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// Flash ID
+//-----------------------------------------------------------------------------
+ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
+{
+ ULONG ulRDID = 0;
+ UINT value;
+//
+// Read ID Instruction.
+//
+ value = (FLASH_CMD_READ_ID<<24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));
+
+//Delay
+ udelay(10);
+//
+// Read SPI READQ REG. The output will be WWXXYYZZ.
+// The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
+//
+ rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));
+
+ return (ulRDID >>8);
+
+
+}
+
+INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
+ return -EINVAL;
+ }
+ psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
+ if(psAdapter->psFlashCSInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
+ return -ENOMEM;
+ }
+
+ psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
+ if(psAdapter->psFlash2xCSInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ return -ENOMEM;
+ }
+
+ psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
+ if(psAdapter->psFlash2xVendorInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ bcm_kfree(psAdapter->psFlash2xCSInfo);
+ return -ENOMEM;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
+ return -EINVAL;
+ }
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ bcm_kfree(psAdapter->psFlash2xCSInfo);
+ bcm_kfree(psAdapter->psFlash2xVendorInfo);
+ return STATUS_SUCCESS ;
+}
+
+INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
+{
+ UINT Index = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
+ for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
+ (psFlash2xCSInfo->SectorAccessBitMap[Index]));
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
+{
+ UINT Index = 0;
+ psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
+ psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
+ //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
+ psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
+ psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
+ psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
+ psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
+ psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
+ psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
+ psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
+ psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
+ psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
+ psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
+ psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
+ psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
+ psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
+ psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
+ psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
+ psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
+ psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
+ psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
+ psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
+ psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
+ psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
+ psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
+ psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
+ psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
+ psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
+ psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
+ psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
+ psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
+ psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
+ psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
+ psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
+ psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
+ psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
+ psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
+ psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
+ psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
+ psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
+ psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
+ psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
+ psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
+ psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
+ psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
+ for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
+ {
+ psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
+ }
+ return STATUS_SUCCESS;
+}
+
+INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
+{
+ //UINT Index = 0;
+ psFlashCSInfo->MagicNumber =ntohl(psFlashCSInfo->MagicNumber);
+ psFlashCSInfo->FlashLayoutVersion =ntohl(psFlashCSInfo->FlashLayoutVersion);
+ psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
+ //won't convert according to old assumption
+ psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);
+
+ psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
+ psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
+ psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
+ psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
+ psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
+ psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
+ psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
+ psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
+ psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
+ psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
+ psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
+ psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
+ psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
+ psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
+ psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
+ psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
+ psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
+ psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
+ psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
+ psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
+
+ return STATUS_SUCCESS;
+}
+
+INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
+{
+ return ( Adapter->uiVendorExtnFlag &&
+ (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
+ (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
+}
+
+VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
+{
+ B_UINT32 i = 0;
+ UINT uiSizeSection = 0;
+
+ Adapter->uiVendorExtnFlag = FALSE;
+
+ for(i = 0;i < TOTAL_SECTIONS;i++)
+ Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
+
+ if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
+ return;
+
+ i = 0;
+ while(i < TOTAL_SECTIONS)
+ {
+ if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
+ {
+ i++;
+ continue;
+ }
+
+ Adapter->uiVendorExtnFlag = TRUE;
+ uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
+ Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
+
+ switch(i)
+ {
+ case DSD0:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
+ break;
+
+ case DSD1:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
+ break;
+
+ case DSD2:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
+ break;
+ case VSA0:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
+ break;
+
+ case VSA1:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
+ break;
+ case VSA2:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
+ break;
+
+ default:
+ break;
+ }
+ i++;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashCSInfo
+//
+// Description: Reads control structure and gets Cal section addresses.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <VOID>
+//-----------------------------------------------------------------------------
+
+INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
+{
+ //FLASH_CS_INFO sFlashCsInfo = {0};
+
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT value;
+#endif
+ UINT uiFlashLayoutMajorVersion;
+ Adapter->uiFlashLayoutMinorVersion = 0;
+ Adapter->uiFlashLayoutMajorVersion = 0;
+ Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
+
+
+ Adapter->uiFlashBaseAdd = 0;
+ Adapter->ulFlashCalStart = 0;
+ memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
+ memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
+
+#ifndef BCM_SHM_INTERFACE
+ if(!Adapter->bDDRInitDone)
+ {
+ {
+ value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
+ }
+ }
+
+#endif
+
+ // Reading first 8 Bytes to get the Flash Layout
+ // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
+ BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8);
+
+ Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
+
+ if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber))
+ {
+ uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
+ Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
+ }
+ else
+ {
+ Adapter->uiFlashLayoutMinorVersion = 0;
+ uiFlashLayoutMajorVersion = 0;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
+
+ if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER)
+ {
+ BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO));
+ ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
+ Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
+
+ if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
+ {
+ Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
+ }
+
+ if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
+ (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
+ (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
+ (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize)))
+ {
+ Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
+ Adapter->fpFlashWrite = flashByteWrite;
+ Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
+ }
+ else
+ {
+ Adapter->ulFlashWriteSize = MAX_RW_SIZE;
+ Adapter->fpFlashWrite = flashWrite;
+ Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
+ }
+
+ BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
+ (Adapter->psFlashCSInfo->FlashSectorSize));
+
+
+ Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
+
+
+ }
+ else
+ {
+ if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL,
+ Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n");
+ return STATUS_FAILURE;
+ }
+ ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
+#ifndef BCM_SHM_INTERFACE
+ BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
+#endif
+ if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
+ (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
+ (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
+ (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize))
+ {
+ Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
+ Adapter->fpFlashWrite = flashByteWrite;
+ Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
+ }
+ else
+ {
+ Adapter->ulFlashWriteSize = MAX_RW_SIZE;
+ Adapter->fpFlashWrite = flashWrite;
+ Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
+ }
+
+ BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
+ Adapter->psFlash2xCSInfo->FlashSectorSize);
+
+ UpdateVendorInfo(Adapter);
+
+ BcmGetActiveDSD(Adapter);
+ BcmGetActiveISO(Adapter);
+ Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
+ Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
+
+ }
+ /*
+ Concerns: what if CS sector size does not match with this sector size ???
+ what is the indication of AccessBitMap in CS in flash 2.x ????
+ */
+#ifndef BCM_SHM_INTERFACE
+ Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
+#endif
+
+ Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
+
+ #if 0
+ if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
+ {
+ //
+ // 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS.
+ //
+ Adapter->uiSectorSize = 0x10000;
+ }
+ #endif
+
+ return STATUS_SUCCESS ;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetNvmType
+//
+// Description: Finds the type of NVM used.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// NVM_TYPE
+//
+//-----------------------------------------------------------------------------
+
+NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
+{
+ UINT uiData = 0;
+
+ BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
+ if(uiData == BECM)
+ {
+ return NVM_EEPROM;
+ }
+ //
+ // Read control struct and get cal addresses before accessing the flash
+ //
+ BcmGetFlashCSInfo(Adapter);
+
+ BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
+ if(uiData == BECM)
+ {
+ return NVM_FLASH;
+ }
+//
+// even if there is no valid signature on EEPROM/FLASH find out if they really exist.
+// if exist select it.
+//
+ if(BcmGetEEPROMSize(Adapter))
+ {
+ return NVM_EEPROM;
+ }
+
+//TBD for Flash.
+
+
+ return NVM_UNKNOWN;
+}
+
+/**
+* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
+* @Adapter : Drivers Private Data structure
+* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+*
+* Return value:-
+* On success it return the start offset of the provided section val
+* On Failure -returns STATUS_FAILURE
+**/
+
+INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+{
+ /*
+ * Considering all the section for which end offset can be calculated or directly given
+ * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
+ * endoffset can't be calculated or given in CS Stucture.
+ */
+
+ INT SectStartOffset = 0 ;
+
+ SectStartOffset = INVALID_OFFSET ;
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
+ {
+ return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
+ }
+
+ switch(eFlashSectionVal)
+ {
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
+ break;
+ case CONTROL_SECTION :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
+ break;
+ case ISO_IMAGE1_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
+ break;
+ case ISO_IMAGE1_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+ break;
+ case ISO_IMAGE2_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
+ break;
+ case ISO_IMAGE2_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+ break;
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
+ SectStartOffset = INVALID_OFFSET;
+ }
+ return SectStartOffset;
+}
+
+/**
+* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
+* @Adapter : Drivers Private Data structure
+* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+*
+* Return value:-
+* On success it return the end offset of the provided section val
+* On Failure -returns STATUS_FAILURE
+**/
+
+INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+ INT SectEndOffset = 0 ;
+ SectEndOffset = INVALID_OFFSET;
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ {
+ return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
+ }
+
+ switch(eFlash2xSectionVal)
+ {
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
+ (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
+ break;
+ case CONTROL_SECTION :
+ //Not Clear So Putting failure. confirm and fix it.
+ SectEndOffset = STATUS_FAILURE;
+ case ISO_IMAGE1_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
+ break;
+ case ISO_IMAGE1_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
+ break;
+ case ISO_IMAGE2_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
+ break;
+ case ISO_IMAGE2_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
+ break;
+
+ default :
+ SectEndOffset = INVALID_OFFSET;
+ }
+ return SectEndOffset ;
+}
+
+/*
+* BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
+* @Adapter :Driver Private Data Structure
+* @pBuffer : Buffer where data has to be put after reading
+* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+* @uiOffsetWithinSectionVal :- Offset with in provided section
+* @uiNumBytes : Number of Bytes for Read
+*
+* Return value:-
+* return true on sucess and STATUS_FAILURE on fail.
+*/
+
+INT BcmFlash2xBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ UINT uiOffsetWithinSectionVal,
+ UINT uiNumBytes)
+{
+
+ INT Status = STATUS_SUCCESS;
+ INT SectionStartOffset = 0;
+ UINT uiAbsoluteOffset = 0 ;
+ UINT uiTemp =0, value =0 ;
+ if(Adapter == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
+ return -EINVAL;
+ }
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
+ return -ENODEV;
+ }
+
+ //NO_SECTION_VAL means absolute offset is given.
+ if(eFlash2xSectionVal == NO_SECTION_VAL)
+ SectionStartOffset = 0;
+ else
+ SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
+
+ if(SectionStartOffset == STATUS_FAILURE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
+ return -EINVAL;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
+
+ //calculating the absolute offset from FLASH;
+ uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;
+
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
+ return Status ;
+ }
+
+ return Status;
+}
+
+/*
+* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
+* @Adapter :Driver Private Data Structure
+* @pBuffer : Buffer From where data has to taken for writing
+* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+* @uiOffsetWithinSectionVal :- Offset with in provided section
+* @uiNumBytes : Number of Bytes for Write
+*
+* Return value:-
+* return true on sucess and STATUS_FAILURE on fail.
+*
+*/
+
+INT BcmFlash2xBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlash2xSectVal,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ UINT bVerify)
+{
+
+ INT Status = STATUS_SUCCESS;
+ UINT FlashSectValStartOffset = 0;
+ UINT uiTemp = 0, value = 0;
+ if(Adapter == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
+ return -EINVAL;
+ }
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
+ return -ENODEV;
+ }
+
+ //NO_SECTION_VAL means absolute offset is given.
+ if(eFlash2xSectVal == NO_SECTION_VAL)
+ FlashSectValStartOffset = 0;
+ else
+ FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);
+
+ if(FlashSectValStartOffset == STATUS_FAILURE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
+ return -EINVAL;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
+ return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
+
+ //calculating the absolute offset from FLASH;
+ uiOffset = uiOffset + FlashSectValStartOffset;
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);
+
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
+ return Status ;
+ }
+
+ return Status;
+
+}
+
+/**
+* ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument.
+* @Adapter : Beceem Private Data Structure
+* @psDSDHeader :Pointer of the buffer where header has to be read
+* @dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2
+*
+* Return Value:-
+* if suceeds return STATUS_SUCCESS or negative error code.
+**/
+INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd)
+{
+ INT Status = STATUS_SUCCESS;
+
+ Status =BcmFlash2xBulkRead(Adapter,
+ (PUINT)psDSDHeader,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader,
+ sizeof(DSD_HEADER));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status);
+ }
+
+ return Status;
+}
+
+/**
+* BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
+* @Adapter :-Drivers private Data Structure
+*
+* Return Value:-
+* Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
+*
+**/
+INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
+{
+ FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
+
+ uiHighestPriDSD = getHighestPriDSD(Adapter);
+ Adapter->eActiveDSD = uiHighestPriDSD;
+
+ if(DSD0 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
+ if(DSD1 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
+ if(DSD2 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
+ if(Adapter->eActiveDSD)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
+ if(Adapter->eActiveDSD == 0)
+ {
+ //if No DSD gets Active, Make Active the DSD with WR permission
+ if(IsSectionWritable(Adapter,DSD2))
+ {
+ Adapter->eActiveDSD = DSD2;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
+ }
+ else if(IsSectionWritable(Adapter,DSD1))
+ {
+ Adapter->eActiveDSD = DSD1;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
+ }
+ else if(IsSectionWritable(Adapter,DSD0))
+ {
+ Adapter->eActiveDSD = DSD0;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument.
+* @Adapter : Driver Private Data Structure
+* @psISOHeader :Pointer of the location where header has to be read
+* @IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2
+*
+* Return Value:-
+* if suceeds return STATUS_SUCCESS or negative error code.
+**/
+
+INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage)
+{
+ INT Status = STATUS_SUCCESS;
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)psISOHeader,
+ IsoImage,
+ 0,
+ sizeof(ISO_HEADER));
+
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed");
+ }
+ return Status;
+}
+
+/**
+* BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
+* @Adapter : Driver private Data Structure
+*
+* Return Value:-
+* Sucsess:- STATUS_SUCESS
+* Failure- : negative erro code
+*
+**/
+
+INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
+{
+
+ INT HighestPriISO = 0 ;
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ Adapter->eActiveISO = HighestPriISO ;
+ if(Adapter->eActiveISO == ISO_IMAGE2)
+ Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ else if(Adapter->eActiveISO == ISO_IMAGE1)
+ Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
+
+ if(Adapter->eActiveISO)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* IsOffsetWritable :- it will tell the access permission of the sector having passed offset
+* @Adapter : Drivers Private Data Structure
+* @uiOffset : Offset provided in the Flash
+*
+* Return Value:-
+* Sucess:-TRUE , offset is writable
+* Failure:-FALSE, offset is RO
+*
+**/
+B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
+{
+ UINT uiSectorNum = 0;
+ UINT uiWordOfSectorPermission =0;
+ UINT uiBitofSectorePermission = 0;
+ B_UINT32 permissionBits = 0;
+ uiSectorNum = uiOffset/Adapter->uiSectorSize;
+
+ //calculating the word having this Sector Access permission from SectorAccessBitMap Array
+ uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];
+
+ //calculating the bit index inside the word for this sector
+ uiBitofSectorePermission = 2*(15 - uiSectorNum %16);
+
+ //Setting Access permission
+ permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
+ permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
+ if(permissionBits == SECTOR_READWRITE_PERMISSION)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
+{
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0 :0X%x", psFlash2xBitMap->DSD0);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1 :0X%x", psFlash2xBitMap->DSD1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2 :0X%x", psFlash2xBitMap->DSD2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0 :0X%x", psFlash2xBitMap->VSA0);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1 :0X%x", psFlash2xBitMap->VSA1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2 :0X%x", psFlash2xBitMap->VSA2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI :0X%x", psFlash2xBitMap->SCSI);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
+* 8bit has been assigned to every section.
+ bit[0] :Section present or not
+ bit[1] :section is valid or not
+ bit[2] : Secton is read only or has write permission too.
+ bit[3] : Active Section -
+ bit[7...4] = Reserved .
+
+ @Adapter:-Driver private Data Structure
+*
+* Return value:-
+* Sucess:- STATUS_SUCESS
+* Failure:- negative error code
+**/
+
+INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
+{
+
+
+ PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
+ FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
+ FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
+ BOOLEAN SetActiveDSDDone = FALSE ;
+ BOOLEAN SetActiveISODone = FALSE ;
+
+ //For 1.x map all the section except DSD0 will be shown as not present
+ //This part will be used by calibration tool to detect the number of DSD present in Flash.
+ if(IsFlash2x(Adapter) == FALSE)
+ {
+ psFlash2xBitMap->ISO_IMAGE2 = 0;
+ psFlash2xBitMap->ISO_IMAGE1 = 0;
+ psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present)
+ psFlash2xBitMap->DSD1 = 0 ;
+ psFlash2xBitMap->DSD2 = 0 ;
+ psFlash2xBitMap->VSA0 = 0 ;
+ psFlash2xBitMap->VSA1 = 0 ;
+ psFlash2xBitMap->VSA2 = 0 ;
+ psFlash2xBitMap->CONTROL_SECTION = 0 ;
+ psFlash2xBitMap->SCSI= 0 ;
+ psFlash2xBitMap->Reserved0 = 0 ;
+ psFlash2xBitMap->Reserved1 = 0 ;
+ psFlash2xBitMap->Reserved2 = 0 ;
+ return STATUS_SUCCESS ;
+
+ }
+
+ uiHighestPriDSD = getHighestPriDSD(Adapter);
+ uiHighestPriISO = getHighestPriISO(Adapter);
+
+ ///
+ // IS0 IMAGE 2
+ ///
+ if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
+
+
+ if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
+
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
+
+ if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
+ {
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
+ SetActiveISODone = TRUE;
+ }
+
+ }
+
+ ///
+ // IS0 IMAGE 1
+ ///
+ if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
+
+ // Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
+
+ if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
+ {
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
+ SetActiveISODone = TRUE;
+ }
+ }
+
+
+
+ ///
+ // DSD2
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, DSD2) == FALSE)
+ {
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
+
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
+ {
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+ }
+
+ ///
+ // DSD 1
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
+
+
+ if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, DSD1) == FALSE)
+ {
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
+ {
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+
+ }
+
+ ///
+ //For DSD 0
+ //
+ if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
+
+ //Setting Access permission
+ if(IsSectionWritable(Adapter, DSD0) == FALSE)
+ {
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
+ {
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+ }
+
+ ///
+ // VSA 0
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, VSA0) == FALSE)
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // VSA 1
+ ///
+
+ if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, VSA1) == FALSE)
+ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // VSA 2
+ ///
+
+ if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, VSA2) == FALSE)
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
+ }
+
+ ///
+ // SCSI Section
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, SCSI) == FALSE)
+ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // Control Section
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;
+
+ }
+
+ ///
+ // For Reserved Sections
+ ///
+ psFlash2xBitMap->Reserved0 = 0;
+ psFlash2xBitMap->Reserved0 = 0;
+ psFlash2xBitMap->Reserved0 = 0;
+
+ BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
+
+ return STATUS_SUCCESS ;
+
+}
+/**
+BcmSetActiveSection :- Set Active section is used to make priority field highest over other
+ section of same type.
+
+@Adapater :- Bcm Driver Private Data Structure
+@eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
+
+Return Value:- Make the priorit highest else return erorr code
+
+**/
+INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
+{
+ INT SectImagePriority = 0;
+ INT Status =STATUS_SUCCESS;
+
+ //DSD_HEADER sDSD = {0};
+ //ISO_HEADER sISO = {0};
+ INT HighestPriDSD = 0 ;
+ INT HighestPriISO = 0;
+
+
+
+ Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
+ if(Status != TRUE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
+ return STATUS_FAILURE;
+ }
+
+ Adapter->bHeaderChangeAllowed = TRUE ;
+ switch(eFlash2xSectVal)
+ {
+ case ISO_IMAGE1 :
+ case ISO_IMAGE2 :
+ if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
+ {
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ if(HighestPriISO == eFlash2xSectVal )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
+
+ if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
+ {
+ // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
+ // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
+ // by user
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
+ SectImagePriority = htonl(0x1);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriISO,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ Status = STATUS_FAILURE;
+ break ;
+ }
+
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ if(HighestPriISO == eFlash2xSectVal )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = 2;
+ }
+
+
+ SectImagePriority = htonl(SectImagePriority);
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ eFlash2xSectVal,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ break ;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
+ Status = STATUS_FAILURE ;
+ break;
+ }
+ break;
+ case DSD0 :
+ case DSD1 :
+ case DSD2 :
+ if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
+ {
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already has highest priority", eFlash2xSectVal);
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
+ if(SectImagePriority <= 0)
+ {
+ // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
+ // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
+ // by user
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
+ SectImagePriority = htonl(0x1);
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriDSD,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
+ break ;
+ }
+
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = htonl(0x2);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriDSD,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
+ break ;
+ }
+
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+ SectImagePriority = 3 ;
+
+ }
+ SectImagePriority = htonl(SectImagePriority);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ eFlash2xSectVal,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE ,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ Status = STATUS_FAILURE ;
+ break ;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
+ Status = STATUS_FAILURE ;
+ break;
+ }
+ break;
+ case VSA0 :
+ case VSA1 :
+ case VSA2 :
+ //Has to be decided
+ break ;
+ default :
+ Status = STATUS_FAILURE ;
+ break;
+
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE ;
+ return Status;
+
+}
+
+/**
+BcmCopyISO - Used only for copying the ISO section
+@Adapater :- Bcm Driver Private Data Structure
+@sCopySectStrut :- Section copy structure
+
+Return value:- SUCCESS if copies successfully else negative error code
+
+**/
+INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
+{
+
+ PCHAR Buff = NULL;
+ FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
+ UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
+ UINT uiTotalDataToCopy = 0;
+ BOOLEAN IsThisHeaderSector = FALSE ;
+ UINT sigOffset = 0;
+ UINT ISOLength = 0;
+ UINT Status = STATUS_SUCCESS;
+ UINT SigBuff[MAX_RW_SIZE];
+ UINT i = 0;
+
+ if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ &ISOLength,
+ sCopySectStrut.SrcSection,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
+ 4);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
+ return Status;
+ }
+
+ ISOLength = htonl(ISOLength);
+
+ if(ISOLength % Adapter->uiSectorSize)
+ {
+ ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
+ }
+
+ sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
+
+ Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
+
+ if(Buff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
+ return -ENOMEM;
+ }
+
+ if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
+ {
+ eISOReadPart = ISO_IMAGE1 ;
+ eISOWritePart = ISO_IMAGE2 ;
+ uiReadOffsetWithinPart = 0;
+ uiWriteOffsetWithinPart = 0 ;
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy = ISOLength;
+
+ CorruptISOSig(Adapter,ISO_IMAGE2);
+
+ while(uiTotalDataToCopy)
+ {
+ if(uiTotalDataToCopy == Adapter->uiSectorSize)
+ {
+ //Setting for write of first sector. First sector is assumed to be written in last
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
+ eISOReadPart = ISO_IMAGE1 ;
+ uiReadOffsetWithinPart = 0;
+ eISOWritePart = ISO_IMAGE2;
+ uiWriteOffsetWithinPart = 0 ;
+ IsThisHeaderSector = TRUE ;
+
+ }
+ else
+ {
+ uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
+ uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
+
+ if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
+ {
+ eISOReadPart = ISO_IMAGE1_PART2 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
+ {
+ eISOReadPart = ISO_IMAGE1_PART3 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
+ {
+ eISOWritePart = ISO_IMAGE2_PART2 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
+ {
+ eISOWritePart = ISO_IMAGE2_PART3 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)Buff,
+ eISOReadPart,
+ uiReadOffsetWithinPart,
+ Adapter->uiSectorSize
+ );
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
+ break;
+ }
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
+ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+
+ for(i = 0; i < MAX_RW_SIZE;i++)
+ *(Buff + sigOffset + i) = 0xFF;
+ }
+ Adapter->bHeaderChangeAllowed = TRUE ;
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ (PUINT)Buff,
+ eISOWritePart,
+ uiWriteOffsetWithinPart,
+ Adapter->uiSectorSize,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
+ break;
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE;
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ WriteToFlashWithoutSectorErase(Adapter,
+ SigBuff,
+ eISOWritePart,
+ sigOffset,
+ MAX_RW_SIZE);
+ IsThisHeaderSector = FALSE ;
+ }
+ //substracting the written Data
+ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
+ }
+
+
+ }
+
+ if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
+ {
+ eISOReadPart = ISO_IMAGE2 ;
+ eISOWritePart = ISO_IMAGE1 ;
+ uiReadOffsetWithinPart = 0;
+ uiWriteOffsetWithinPart = 0 ;
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy = ISOLength;
+
+ CorruptISOSig(Adapter,ISO_IMAGE1);
+
+ while(uiTotalDataToCopy)
+ {
+ if(uiTotalDataToCopy == Adapter->uiSectorSize)
+ {
+ //Setting for write of first sector. First sector is assumed to be written in last
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
+ eISOReadPart = ISO_IMAGE2 ;
+ uiReadOffsetWithinPart = 0;
+ eISOWritePart = ISO_IMAGE1;
+ uiWriteOffsetWithinPart = 0 ;
+ IsThisHeaderSector = TRUE;
+
+ }
+ else
+ {
+ uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
+ uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
+
+ if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
+ {
+ eISOReadPart = ISO_IMAGE2_PART2 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
+ {
+ eISOReadPart = ISO_IMAGE2_PART3 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
+ {
+ eISOWritePart = ISO_IMAGE1_PART2 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
+ {
+ eISOWritePart = ISO_IMAGE1_PART3 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)Buff,
+ eISOReadPart,
+ uiReadOffsetWithinPart,
+ Adapter->uiSectorSize
+ );
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
+ break;
+ }
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
+ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+
+ for(i = 0; i < MAX_RW_SIZE;i++)
+ *(Buff + sigOffset + i) = 0xFF;
+
+ }
+ Adapter->bHeaderChangeAllowed = TRUE ;
+ Status = BcmFlash2xBulkWrite(Adapter,
+ (PUINT)Buff,
+ eISOWritePart,
+ uiWriteOffsetWithinPart,
+ Adapter->uiSectorSize,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
+ break;
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE ;
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ WriteToFlashWithoutSectorErase(Adapter,
+ SigBuff,
+ eISOWritePart,
+ sigOffset,
+ MAX_RW_SIZE);
+ IsThisHeaderSector = FALSE ;
+ }
+
+ //substracting the written Data
+ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
+ }
+
+
+ }
+
+ bcm_kfree(Buff);
+
+ return Status;
+}
+/**
+BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
+ It will corrupt the sig, if Section is writable, by making first bytes as zero.
+@Adapater :- Bcm Driver Private Data Structure
+@eFlash2xSectionVal :- Flash section val which has header
+
+Return Value :-
+ Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
+ Failure :-Return negative error code
+
+
+**/
+INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ INT Status = STATUS_SUCCESS ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);
+
+ if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
+ {
+ Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
+ }
+ else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
+ {
+ Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
+ return STATUS_SUCCESS;
+ }
+ return Status;
+}
+/**
+BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
+ header and Write Permission.
+@Adapater :- Bcm Driver Private Data Structure
+@eFlashSectionVal :- Flash section val which has header
+
+Return Value :-
+ Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS
+ Failure :-Return negative error code
+
+**/
+INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+{
+
+ UINT uiSignature = 0 ;
+ UINT uiOffset = 0;
+ //DSD_HEADER dsdHeader = {0};
+
+ if(Adapter->bSigCorrupted == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
+ return STATUS_SUCCESS;
+ }
+ if(Adapter->bAllDSDWriteAllow == FALSE)
+ {
+ if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+ }
+ if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
+ {
+ uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
+ uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;
+
+ uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);
+
+ if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
+ return STATUS_FAILURE;
+ }
+
+ }
+ else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
+ {
+ uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
+ //uiOffset = 0;
+ uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
+ if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
+ return STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
+ return STATUS_FAILURE;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");
+
+
+ Adapter->bHeaderChangeAllowed = TRUE;
+ Adapter->bSigCorrupted = FALSE;
+ BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
+ Adapter->bHeaderChangeAllowed = FALSE;
+
+
+
+ return STATUS_SUCCESS;
+}
+/**
+validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
+ if requested Bytes goes beyond the Requested section, it reports error.
+@Adapater :- Bcm Driver Private Data Structure
+@psFlash2xReadWrite :-Flash2x Read/write structure pointer
+
+Return values:-Return TRUE is request is valid else FALSE.
+
+
+**/
+INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
+{
+ UINT uiNumOfBytes = 0 ;
+ UINT uiSectStartOffset = 0 ;
+ UINT uiSectEndOffset = 0;
+ uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
+
+ if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
+ return FALSE;
+ }
+ uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
+ if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
+ {
+ if(psFlash2xReadWrite->Section == ISO_IMAGE1)
+ {
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
+ }
+ else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
+ {
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);
+
+ }
+
+ //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
+ //it should be added in startoffset. so that check done in last of this function can be valued.
+ uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
+ }
+ else
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);
+
+ //Checking the boundary condition
+ if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
+ return TRUE;
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
+ return FALSE;
+ }
+
+}
+
+/**
+IsFlash2x :- check for Flash 2.x
+@Adapater :- Bcm Driver Private Data Structure
+
+Return value:-
+ return TRUE if flah2.x of hgher version else return false.
+**/
+
+INT IsFlash2x(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
+ return TRUE ;
+ else
+ return FALSE;
+}
+/**
+GetFlashBaseAddr :- Calculate the Flash Base address
+@Adapater :- Bcm Driver Private Data Structure
+
+Return Value:-
+ Success :- Base Address of the Flash
+**/
+
+INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
+{
+
+ UINT uiBaseAddr = 0;
+
+ if(Adapter->bDDRInitDone)
+ {
+ /*
+ For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
+ In case of Raw Read... use the default value
+ */
+ if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+ !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
+ )
+ uiBaseAddr = Adapter->uiFlashBaseAdd ;
+ else
+ uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
+ }
+ else
+ {
+ /*
+ For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
+ In case of Raw Read... use the default value
+ */
+ if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+ !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
+ )
+ uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ else
+ uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ }
+
+ return uiBaseAddr ;
+}
+/**
+BcmCopySection :- This API is used to copy the One section in another. Both section should
+ be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
+
+@Adapater :- Bcm Driver Private Data Structure
+@SrcSection :- Source section From where data has to be copied
+@DstSection :- Destination section to which data has to be copied
+@offset :- Offset from/to where data has to be copied from one section to another.
+@numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
+ in case of numofBytes equal zero complete section will be copied.
+
+Return Values-
+ Sucess : Return STATUS_SUCCESS
+ Faillure :- return negative error code
+
+**/
+
+INT BcmCopySection(PMINI_ADAPTER Adapter,
+ FLASH2X_SECTION_VAL SrcSection,
+ FLASH2X_SECTION_VAL DstSection,
+ UINT offset,
+ UINT numOfBytes)
+{
+ UINT BuffSize = 0 ;
+ UINT BytesToBeCopied = 0;
+ PUCHAR pBuff = NULL ;
+ INT Status = STATUS_SUCCESS ;
+ if(SrcSection == DstSection)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
+ return -EINVAL;
+ }
+ if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
+ return -EINVAL;
+ }
+ if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
+ return -EINVAL;
+ }
+
+ #if 0
+ else
+ {
+ if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2))
+ {
+ if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type");
+ return -EINVAL;
+ }
+ }
+
+ }
+ #endif
+ //if offset zero means have to copy complete secton
+
+ if(numOfBytes == 0)
+ {
+ numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
+ - BcmGetSectionValStartOffset(Adapter,SrcSection);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
+ }
+
+ if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
+ - BcmGetSectionValStartOffset(Adapter,SrcSection))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
+ offset, numOfBytes);
+ return -EINVAL;
+ }
+
+ if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
+ - BcmGetSectionValStartOffset(Adapter,DstSection))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
+ offset, numOfBytes);
+ return -EINVAL;
+ }
+
+
+ if(numOfBytes > Adapter->uiSectorSize )
+ BuffSize = Adapter->uiSectorSize;
+ else
+ BuffSize = numOfBytes ;
+
+ pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
+ return -ENOMEM;
+ }
+
+
+ BytesToBeCopied = Adapter->uiSectorSize ;
+ if(offset % Adapter->uiSectorSize)
+ BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
+ if(BytesToBeCopied > numOfBytes)
+ BytesToBeCopied = numOfBytes ;
+
+
+
+ Adapter->bHeaderChangeAllowed = TRUE;
+
+ do
+ {
+ Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
+ break;
+ }
+ Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
+ break;
+ }
+ offset = offset + BytesToBeCopied;
+ numOfBytes = numOfBytes - BytesToBeCopied ;
+ if(numOfBytes)
+ {
+ if(numOfBytes > Adapter->uiSectorSize )
+ BytesToBeCopied = Adapter->uiSectorSize;
+ else
+ BytesToBeCopied = numOfBytes;
+ }
+ }while(numOfBytes > 0) ;
+ bcm_kfree(pBuff);
+ Adapter->bHeaderChangeAllowed = FALSE ;
+ return Status;
+}
+
+/**
+SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
+@Adapater :- Bcm Driver Private Data Structure
+@pBuff :- Data buffer that has to be written in sector having the header map.
+@uiOffset :- Flash offset that has to be written.
+
+Return value :-
+ Sucess :- On sucess return STATUS_SUCCESS
+ Faillure :- Return negative error code
+
+**/
+
+INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
+{
+ UINT offsetToProtect = 0,HeaderSizeToProtect =0;
+ BOOLEAN bHasHeader = FALSE ;
+ PUCHAR pTempBuff =NULL;
+ UINT uiSectAlignAddr = 0;
+ UINT sig = 0;
+
+ #if 0
+ //if Chenges in Header is allowed, Return back
+ if(Adapter->bHeaderChangeAllowed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed");
+ return STATUS_SUCCESS ;
+ }
+ #endif
+ //making the offset sector alligned
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
+
+
+ if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
+ (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
+ (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
+ {
+
+ //offset from the sector boundry having the header map
+ offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
+ HeaderSizeToProtect = sizeof(DSD_HEADER);
+ bHasHeader = TRUE ;
+ }
+
+ if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
+ uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
+ {
+ offsetToProtect = 0;
+ HeaderSizeToProtect = sizeof(ISO_HEADER);
+ bHasHeader = TRUE;
+ }
+ //If Header is present overwrite passed buffer with this
+ if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
+ {
+ pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
+ if(pTempBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
+ return -ENOMEM;
+ }
+ //Read header
+ BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
+ //Replace Buffer content with Header
+ memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
+
+ bcm_kfree(pTempBuff);
+ }
+ if(bHasHeader && Adapter->bSigCorrupted)
+ {
+ sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)));
+ sig = ntohl(sig);
+ if((sig & 0xFF000000) != CORRUPTED_PATTERN)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore");
+ Adapter->bSigCorrupted = FALSE;
+ return STATUS_SUCCESS;
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig);
+ *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only");
+ Adapter->bSigCorrupted = FALSE;
+ }
+
+ return STATUS_SUCCESS ;
+}
+INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset)
+{
+ UINT GPIOConfig = 0 ;
+
+
+ if(Adapter->bFlashRawRead == FALSE)
+ {
+ //Applicable for Flash2.x
+ if(IsFlash2x(Adapter) == FALSE)
+ return STATUS_SUCCESS;
+ }
+
+ if(offset/FLASH_PART_SIZE)
+ {
+ //bit[14..12] -> will select make Active CS1, CS2 or CS3
+ // Select CS1, CS2 and CS3 (CS0 is dedicated pin)
+ rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ GPIOConfig |= (7 << 12);
+ wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ }
+
+ return STATUS_SUCCESS ;
+}
+/**
+BcmDoChipSelect : This will selcet the appropriate chip for writing.
+@Adapater :- Bcm Driver Private Data Structure
+
+OutPut:-
+ Select the Appropriate chip and retrn status Sucess
+**/
+INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
+{
+ UINT FlashConfig = 0;
+ INT ChipNum = 0;
+ UINT GPIOConfig = 0;
+ UINT PartNum = 0;
+
+ ChipNum = offset / FLASH_PART_SIZE ;
+
+ //
+ // Chip Select mapping to enable flash0.
+ // To select flash 0, we have to OR with (0<<12).
+ // ORing 0 will have no impact so not doing that part.
+ // In future if Chip select value changes from 0 to non zero,
+ // That needs be taken care with backward comaptibility. No worries for now.
+ //
+
+ /*
+ SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
+ if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
+ Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
+ power down modes (Idle mode/shutdown mode), the values in the register will be different.
+ */
+
+ if(Adapter->SelectedChip == ChipNum)
+ return STATUS_SUCCESS;
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
+ Adapter->SelectedChip = ChipNum ;
+
+ //bit[13..12] will select the appropriate chip
+ rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
+ rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+
+ {
+ switch(ChipNum)
+ {
+ case 0:
+ PartNum = 0;
+ break;
+ case 1:
+ PartNum = 3;
+ GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
+ break;
+ case 2:
+ PartNum = 1;
+ GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
+ break;
+ case 3:
+ PartNum = 2;
+ GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
+ break;
+ }
+ }
+ /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
+ nothing to do... can return immediately.
+ ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
+ Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
+ These values are not written by host other than during CHIP_SELECT.
+ */
+ if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
+ return STATUS_SUCCESS;
+
+ //clearing the bit[13..12]
+ FlashConfig &= 0xFFFFCFFF;
+ FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00
+
+ wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ udelay(100);
+
+ wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
+ udelay(100);
+
+ return STATUS_SUCCESS;
+
+}
+INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
+{
+ UINT uiDSDsig = 0;
+ //UINT sigoffsetInMap = 0;
+ //DSD_HEADER dsdHeader = {0};
+
+
+ //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
+
+ if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
+ return STATUS_FAILURE;
+ }
+ BcmFlash2xBulkRead(Adapter,
+ &uiDSDsig,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
+ SIGNATURE_SIZE);
+
+ uiDSDsig = ntohl(uiDSDsig);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);
+
+ return uiDSDsig ;
+}
+INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
+{
+ //UINT priOffsetInMap = 0 ;
+ INT uiDSDPri = STATUS_FAILURE;
+ //DSD_HEADER dsdHeader = {0};
+ //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
+ if(IsSectionWritable(Adapter,dsd))
+ {
+ if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
+ {
+ BcmFlash2xBulkRead(Adapter,
+ &uiDSDPri,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ 4);
+
+ uiDSDPri = ntohl(uiDSDPri);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);
+
+ }
+ }
+ return uiDSDPri;
+}
+FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
+{
+ INT DSDHighestPri = STATUS_FAILURE;
+ INT DsdPri= 0 ;
+ FLASH2X_SECTION_VAL HighestPriDSD = 0 ;
+
+ if(IsSectionWritable(Adapter,DSD2))
+ {
+ DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
+ HighestPriDSD = DSD2 ;
+ }
+ if(IsSectionWritable(Adapter,DSD1))
+ {
+ DsdPri = ReadDSDPriority(Adapter,DSD1);
+ if(DSDHighestPri < DsdPri)
+ {
+ DSDHighestPri = DsdPri ;
+ HighestPriDSD = DSD1;
+ }
+ }
+ if(IsSectionWritable(Adapter,DSD0))
+ {
+ DsdPri = ReadDSDPriority(Adapter,DSD0);
+ if(DSDHighestPri < DsdPri)
+ {
+ DSDHighestPri = DsdPri ;
+ HighestPriDSD = DSD0;
+ }
+ }
+ if(HighestPriDSD)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
+ return HighestPriDSD ;
+}
+
+INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
+{
+ UINT uiISOsig = 0;
+ //UINT sigoffsetInMap = 0;
+ //ISO_HEADER ISOHeader = {0};
+
+
+ //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
+
+ if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
+ return STATUS_FAILURE;
+ }
+ BcmFlash2xBulkRead(Adapter,
+ &uiISOsig,
+ iso,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
+ SIGNATURE_SIZE);
+
+ uiISOsig = ntohl(uiISOsig);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);
+
+ return uiISOsig ;
+}
+INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
+{
+
+ INT ISOPri = STATUS_FAILURE;
+ if(IsSectionWritable(Adapter,iso))
+ {
+ if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
+ {
+ BcmFlash2xBulkRead(Adapter,
+ &ISOPri,
+ iso,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ 4);
+
+ ISOPri = ntohl(ISOPri);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);
+
+ }
+ }
+ return ISOPri;
+}
+FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
+{
+ INT ISOHighestPri = STATUS_FAILURE;
+ INT ISOPri= 0 ;
+ FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;
+
+ if(IsSectionWritable(Adapter,ISO_IMAGE2))
+ {
+ ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
+ HighestPriISO = ISO_IMAGE2 ;
+ }
+ if(IsSectionWritable(Adapter,ISO_IMAGE1))
+ {
+ ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
+ if(ISOHighestPri < ISOPri)
+ {
+ ISOHighestPri = ISOPri ;
+ HighestPriISO = ISO_IMAGE1;
+ }
+ }
+ if(HighestPriISO)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
+ return HighestPriISO ;
+}
+INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
+ PUINT pBuff,
+ FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ UINT uiOffset,
+ UINT uiNumBytes
+ )
+{
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT uiTemp = 0, value = 0 ;
+ UINT i = 0;
+ UINT uiPartOffset = 0;
+#endif
+ UINT uiStartOffset = 0;
+ //Adding section start address
+ INT Status = STATUS_SUCCESS;
+ PUCHAR pcBuff = (PUCHAR)pBuff;
+
+ if(uiNumBytes % Adapter->ulFlashWriteSize)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
+ return STATUS_FAILURE;
+ }
+
+ uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ {
+ return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
+ }
+
+ uiOffset = uiOffset + uiStartOffset;
+
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
+#else
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
+ {
+ if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
+ Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
+ else
+ Status = flashWrite(Adapter,uiPartOffset, pcBuff);
+
+ if(Status != STATUS_SUCCESS)
+ break;
+
+ pcBuff = pcBuff + Adapter->ulFlashWriteSize;
+ uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
+ }
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+#endif
+
+ return Status;
+}
+
+#if 0
+UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType)
+{
+
+ UINT numOfWRSubSec = 0;
+ switch(secType)
+ {
+ case ISO :
+ if(IsSectionWritable(Adapter,ISO_IMAGE1))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,ISO_IMAGE2))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ break;
+
+ case DSD :
+ if(IsSectionWritable(Adapter,DSD2))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,DSD1))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,DSD0))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ break ;
+
+ case VSA :
+ //for VSA Add code Here
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\
+ numOfWRSubSec = 0;
+
+ }
+ return numOfWRSubSec;
+}
+#endif
+BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
+{
+
+ BOOLEAN SectionPresent = FALSE ;
+
+ switch(section)
+ {
+
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectionPresent = TRUE ;
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectionPresent = TRUE ;
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case CONTROL_SECTION :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
+ SectionPresent = FALSE;
+ }
+ return SectionPresent ;
+}
+INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
+{
+ INT offset = STATUS_FAILURE;
+ INT Status = FALSE;
+ if(IsSectionExistInFlash(Adapter,Section) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
+ return FALSE;
+ }
+ offset = BcmGetSectionValStartOffset(Adapter,Section);
+ if(offset == INVALID_OFFSET)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
+ return FALSE;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,Section))
+ {
+ return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
+ }
+
+ Status = IsOffsetWritable(Adapter,offset);
+ return Status ;
+}
+
+INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ PUCHAR pBuff = 0 ;
+ UINT sig = 0;
+ UINT uiOffset = 0;
+ UINT BlockStatus = 0;
+ UINT uiSectAlignAddr = 0;
+
+ Adapter->bSigCorrupted = FALSE;
+
+ if(Adapter->bAllDSDWriteAllow == FALSE)
+ {
+ if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+ }
+
+ pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
+ return -ENOMEM ;
+ }
+
+ uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
+ uiOffset -= MAX_RW_SIZE ;
+
+ BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);
+
+
+ sig = *((PUINT)(pBuff +12));
+ sig =ntohl(sig);
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
+ //Now corrupting the sig by corrupting 4th last Byte.
+ *(pBuff + 12) = 0;
+
+ if(sig == DSD_IMAGE_MAGIC_NUMBER)
+ {
+ Adapter->bSigCorrupted = TRUE;
+ if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
+ {
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
+ BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
+
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
+ (uiOffset + 12),BYTE_WRITE_SUPPORT);
+ if(BlockStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
+ BlockStatus = 0;
+ }
+ }
+ else
+ {
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
+ uiOffset ,MAX_RW_SIZE);
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
+ bcm_kfree(pBuff);
+ return STATUS_FAILURE;
+ }
+
+ bcm_kfree(pBuff);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
+ return STATUS_SUCCESS ;
+}
+
+INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ PUCHAR pBuff = 0 ;
+ UINT sig = 0;
+ UINT uiOffset = 0;
+
+ Adapter->bSigCorrupted = FALSE;
+
+ if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+
+ pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
+ return -ENOMEM ;
+ }
+
+ uiOffset = 0;
+
+ BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);
+
+ sig = *((PUINT)pBuff);
+ sig =ntohl(sig);
+
+ //corrupt signature
+ *pBuff = 0;
+
+ if(sig == ISO_IMAGE_MAGIC_NUMBER)
+ {
+ Adapter->bSigCorrupted = TRUE;
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
+ uiOffset ,Adapter->ulFlashWriteSize);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
+ bcm_kfree(pBuff);
+ return STATUS_FAILURE;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
+
+ bcm_kfree(pBuff);
+ return STATUS_SUCCESS ;
+}
+
+BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
+ return TRUE;
+ else
+ return FALSE ;
+}
+
diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h
new file mode 100644
index 000000000000..6ec6ca85b501
--- /dev/null
+++ b/drivers/staging/bcm/nvm.h
@@ -0,0 +1,489 @@
+/***************************************************************************************
+//
+// Copyright (c) Beceem Communications Inc.
+//
+// Module Name:
+// NVM.h
+//
+// Abstract:
+// This file has the prototypes,preprocessors and definitions various NVM libraries.
+//
+//
+// Revision History:
+// Who When What
+// -------- -------- ----------------------------------------------
+// Name Date Created/reviewed/modified
+//
+// Notes:
+//
+****************************************************************************************/
+
+
+#ifndef _NVM_H_
+#define _NVM_H_
+
+typedef struct _FLASH_SECTOR_INFO
+{
+ UINT uiSectorSig;
+ UINT uiSectorSize;
+
+}FLASH_SECTOR_INFO,*PFLASH_SECTOR_INFO;
+
+typedef struct _FLASH_CS_INFO
+{
+ B_UINT32 MagicNumber;
+// let the magic number be 0xBECE-F1A5 - F1A5 for "flas-h"
+
+ B_UINT32 FlashLayoutVersion ;
+
+ // ISO Image/Format/BuildTool versioning
+ B_UINT32 ISOImageVersion;
+
+ // SCSI/Flash BootLoader versioning
+ B_UINT32 SCSIFirmwareVersion;
+
+
+ B_UINT32 OffsetFromZeroForPart1ISOImage;
+// typically 0
+
+ B_UINT32 OffsetFromZeroForScsiFirmware;
+//typically at 12MB
+
+ B_UINT32 SizeOfScsiFirmware ;
+//size of the firmware - depends on binary size
+
+ B_UINT32 OffsetFromZeroForPart2ISOImage;
+// typically at first Word Aligned offset 12MB + sizeOfScsiFirmware.
+
+ B_UINT32 OffsetFromZeroForCalibrationStart;
+// typically at 15MB
+
+ B_UINT32 OffsetFromZeroForCalibrationEnd;
+
+// VSA0 offsets
+ B_UINT32 OffsetFromZeroForVSAStart;
+ B_UINT32 OffsetFromZeroForVSAEnd;
+
+// Control Section offsets
+ B_UINT32 OffsetFromZeroForControlSectionStart;
+ B_UINT32 OffsetFromZeroForControlSectionData;
+
+// NO Data Activity timeout to switch from MSC to NW Mode
+ B_UINT32 CDLessInactivityTimeout;
+
+// New ISO Image Signature
+ B_UINT32 NewImageSignature;
+
+// Signature to validate the sector size.
+ B_UINT32 FlashSectorSizeSig;
+
+// Sector Size
+ B_UINT32 FlashSectorSize;
+
+// Write Size Support
+ B_UINT32 FlashWriteSupportSize;
+
+// Total Flash Size
+ B_UINT32 TotalFlashSize;
+
+// Flash Base Address for offset specified
+ B_UINT32 FlashBaseAddr;
+
+// Flash Part Max Size
+ B_UINT32 FlashPartMaxSize;
+
+// Is CDLess or Flash Bootloader
+ B_UINT32 IsCDLessDeviceBootSig;
+
+// MSC Timeout after reset to switch from MSC to NW Mode
+ B_UINT32 MassStorageTimeout;
+
+
+}FLASH_CS_INFO,*PFLASH_CS_INFO;
+
+#define FLASH2X_TOTAL_SIZE (64*1024*1024)
+#define DEFAULT_SECTOR_SIZE (64*1024)
+
+typedef struct _FLASH_2X_CS_INFO
+{
+
+ // magic number as 0xBECE-F1A5 - F1A5 for "flas-h"
+ B_UINT32 MagicNumber;
+
+ B_UINT32 FlashLayoutVersion ;
+
+ // ISO Image/Format/BuildTool versioning
+ B_UINT32 ISOImageVersion;
+
+ // SCSI/Flash BootLoader versioning
+ B_UINT32 SCSIFirmwareVersion;
+
+ // ISO Image1 Part1/SCSI Firmware/Flash Bootloader Start offset, size
+ B_UINT32 OffsetFromZeroForPart1ISOImage;
+ B_UINT32 OffsetFromZeroForScsiFirmware;
+ B_UINT32 SizeOfScsiFirmware ;
+
+ // ISO Image1 Part2 start offset
+ B_UINT32 OffsetFromZeroForPart2ISOImage;
+
+
+ // DSD0 offset
+ B_UINT32 OffsetFromZeroForDSDStart;
+ B_UINT32 OffsetFromZeroForDSDEnd;
+
+ // VSA0 offset
+ B_UINT32 OffsetFromZeroForVSAStart;
+ B_UINT32 OffsetFromZeroForVSAEnd;
+
+ // Control Section offset
+ B_UINT32 OffsetFromZeroForControlSectionStart;
+ B_UINT32 OffsetFromZeroForControlSectionData;
+
+ // NO Data Activity timeout to switch from MSC to NW Mode
+ B_UINT32 CDLessInactivityTimeout;
+
+ // New ISO Image Signature
+ B_UINT32 NewImageSignature;
+
+ B_UINT32 FlashSectorSizeSig; // Sector Size Signature
+ B_UINT32 FlashSectorSize; // Sector Size
+ B_UINT32 FlashWriteSupportSize; // Write Size Support
+
+ B_UINT32 TotalFlashSize; // Total Flash Size
+
+ // Flash Base Address for offset specified
+ B_UINT32 FlashBaseAddr;
+ B_UINT32 FlashPartMaxSize; // Flash Part Max Size
+
+ // Is CDLess or Flash Bootloader
+ B_UINT32 IsCDLessDeviceBootSig;
+
+ // MSC Timeout after reset to switch from MSC to NW Mode
+ B_UINT32 MassStorageTimeout;
+
+ /* Flash Map 2.0 Field */
+ B_UINT32 OffsetISOImage1Part1Start; // ISO Image1 Part1 offset
+ B_UINT32 OffsetISOImage1Part1End;
+ B_UINT32 OffsetISOImage1Part2Start; // ISO Image1 Part2 offset
+ B_UINT32 OffsetISOImage1Part2End;
+ B_UINT32 OffsetISOImage1Part3Start; // ISO Image1 Part3 offset
+ B_UINT32 OffsetISOImage1Part3End;
+
+ B_UINT32 OffsetISOImage2Part1Start; // ISO Image2 Part1 offset
+ B_UINT32 OffsetISOImage2Part1End;
+ B_UINT32 OffsetISOImage2Part2Start; // ISO Image2 Part2 offset
+ B_UINT32 OffsetISOImage2Part2End;
+ B_UINT32 OffsetISOImage2Part3Start; // ISO Image2 Part3 offset
+ B_UINT32 OffsetISOImage2Part3End;
+
+
+ // DSD Header offset from start of DSD
+ B_UINT32 OffsetFromDSDStartForDSDHeader;
+ B_UINT32 OffsetFromZeroForDSD1Start; // DSD 1 offset
+ B_UINT32 OffsetFromZeroForDSD1End;
+ B_UINT32 OffsetFromZeroForDSD2Start; // DSD 2 offset
+ B_UINT32 OffsetFromZeroForDSD2End;
+
+ B_UINT32 OffsetFromZeroForVSA1Start; // VSA 1 offset
+ B_UINT32 OffsetFromZeroForVSA1End;
+ B_UINT32 OffsetFromZeroForVSA2Start; // VSA 2 offset
+ B_UINT32 OffsetFromZeroForVSA2End;
+
+ /*
+* ACCESS_BITS_PER_SECTOR 2
+* ACCESS_RW 0
+* ACCESS_RO 1
+* ACCESS_RESVD 2
+* ACCESS_RESVD 3
+* */
+ B_UINT32 SectorAccessBitMap[FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)];
+
+// All expansions to the control data structure should add here
+
+}FLASH2X_CS_INFO,*PFLASH2X_CS_INFO;
+
+typedef struct _VENDOR_SECTION_INFO
+{
+ B_UINT32 OffsetFromZeroForSectionStart;
+ B_UINT32 OffsetFromZeroForSectionEnd;
+ B_UINT32 AccessFlags;
+ B_UINT32 Reserved[16];
+
+} VENDOR_SECTION_INFO, *PVENDOR_SECTION_INFO;
+
+typedef struct _FLASH2X_VENDORSPECIFIC_INFO
+{
+ VENDOR_SECTION_INFO VendorSection[TOTAL_SECTIONS];
+ B_UINT32 Reserved[16];
+
+} FLASH2X_VENDORSPECIFIC_INFO, *PFLASH2X_VENDORSPECIFIC_INFO;
+
+typedef struct _DSD_HEADER
+{
+ B_UINT32 DSDImageSize;
+ B_UINT32 DSDImageCRC;
+ B_UINT32 DSDImagePriority;
+ //We should not consider right now. Reading reserve is worthless.
+ B_UINT32 Reserved[252]; // Resvd for DSD Header
+ B_UINT32 DSDImageMagicNumber;
+
+}DSD_HEADER, *PDSD_HEADER;
+
+typedef struct _ISO_HEADER
+{
+ B_UINT32 ISOImageMagicNumber;
+ B_UINT32 ISOImageSize;
+ B_UINT32 ISOImageCRC;
+ B_UINT32 ISOImagePriority;
+ //We should not consider right now. Reading reserve is worthless.
+ B_UINT32 Reserved[60]; //Resvd for ISO Header extension
+
+}ISO_HEADER, *PISO_HEADER;
+
+#define EEPROM_BEGIN_CIS (0)
+#define EEPROM_BEGIN_NON_CIS (0x200)
+#define EEPROM_END (0x2000)
+
+#define INIT_PARAMS_SIGNATURE (0x95a7a597)
+
+#define MAX_INIT_PARAMS_LENGTH (2048)
+
+
+#define MAC_ADDRESS_OFFSET 0x200
+
+
+#define INIT_PARAMS_1_SIGNATURE_ADDRESS EEPROM_BEGIN_NON_CIS
+#define INIT_PARAMS_1_DATA_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+16)
+#define INIT_PARAMS_1_MACADDRESS_ADDRESS (MAC_ADDRESS_OFFSET)
+#define INIT_PARAMS_1_LENGTH_ADDRESS (INIT_PARAMS_1_SIGNATURE_ADDRESS+4)
+
+#define INIT_PARAMS_2_SIGNATURE_ADDRESS (EEPROM_BEGIN_NON_CIS+2048+16)
+#define INIT_PARAMS_2_DATA_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+16)
+#define INIT_PARAMS_2_MACADDRESS_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+8)
+#define INIT_PARAMS_2_LENGTH_ADDRESS (INIT_PARAMS_2_SIGNATURE_ADDRESS+4)
+
+#define EEPROM_SPI_DEV_CONFIG_REG 0x0F003000
+#define EEPROM_SPI_Q_STATUS1_REG 0x0F003004
+#define EEPROM_SPI_Q_STATUS1_MASK_REG 0x0F00300C
+
+#define EEPROM_SPI_Q_STATUS_REG 0x0F003008
+#define EEPROM_CMDQ_SPI_REG 0x0F003018
+#define EEPROM_WRITE_DATAQ_REG 0x0F00301C
+#define EEPROM_READ_DATAQ_REG 0x0F003020
+#define SPI_FLUSH_REG 0x0F00304C
+
+#define EEPROM_WRITE_ENABLE 0x06000000
+#define EEPROM_READ_STATUS_REGISTER 0x05000000
+#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000
+#define EEPROM_WRITE_QUEUE_EMPTY 0x00001000
+#define EEPROM_WRITE_QUEUE_AVAIL 0x00002000
+#define EEPROM_WRITE_QUEUE_FULL 0x00004000
+#define EEPROM_16_BYTE_PAGE_READ 0xFB000000
+#define EEPROM_4_BYTE_PAGE_READ 0x3B000000
+
+#define EEPROM_CMD_QUEUE_FLUSH 0x00000001
+#define EEPROM_WRITE_QUEUE_FLUSH 0x00000002
+#define EEPROM_READ_QUEUE_FLUSH 0x00000004
+#define EEPROM_ETH_QUEUE_FLUSH 0x00000008
+#define EEPROM_ALL_QUEUE_FLUSH 0x0000000f
+#define EEPROM_READ_ENABLE 0x06000000
+#define EEPROM_16_BYTE_PAGE_WRITE 0xFA000000
+#define EEPROM_READ_DATA_FULL 0x00000010
+#define EEPROM_READ_DATA_AVAIL 0x00000020
+#define EEPROM_READ_QUEUE_EMPTY 0x00000002
+#define EEPROM_CMD_QUEUE_EMPTY 0x00000100
+#define EEPROM_CMD_QUEUE_AVAIL 0x00000200
+#define EEPROM_CMD_QUEUE_FULL 0x00000400
+
+/* Most EEPROM status register bit 0 indicates if the EEPROM is busy
+ * with a write if set 1. See the details of the EEPROM Status Register
+ * in the EEPROM data sheet. */
+#define EEPROM_STATUS_REG_WRITE_BUSY 0x00000001
+
+// We will have 1 mSec for every RETRIES_PER_DELAY count and have a max attempts of MAX_EEPROM_RETRIES
+// This will give us 80 mSec minimum of delay = 80mSecs
+#define MAX_EEPROM_RETRIES 80
+#define RETRIES_PER_DELAY 64
+
+
+#define MAX_RW_SIZE 0x10
+#define MAX_READ_SIZE 0x10
+#define MAX_SECTOR_SIZE (512*1024)
+#define MIN_SECTOR_SIZE (1024)
+#define FLASH_SECTOR_SIZE_OFFSET 0xEFFFC
+#define FLASH_SECTOR_SIZE_SIG_OFFSET 0xEFFF8
+#define FLASH_SECTOR_SIZE_SIG 0xCAFEBABE
+#define FLASH_CS_INFO_START_ADDR 0xFF0000
+#define FLASH_CONTROL_STRUCT_SIGNATURE 0xBECEF1A5
+#define SCSI_FIRMWARE_MAJOR_VERSION 0x1
+#define SCSI_FIRMWARE_MINOR_VERSION 0x5
+#define BYTE_WRITE_SUPPORT 0x1
+
+#define FLASH_AUTO_INIT_BASE_ADDR 0xF00000
+
+
+
+#ifdef BCM_SHM_INTERFACE
+
+#define FLASH_ADDR_MASK 0x1F000000
+extern int bcmflash_raw_read(unsigned int flash_id, unsigned int offset, unsigned char *inbuf, unsigned int len);
+extern int bcmflash_raw_write(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
+extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
+
+
+#endif
+
+#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000
+#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000
+
+#define FLASH_CONTIGIOUS_START_ADDR_BCS350 0x08000000
+#define FLASH_CONTIGIOUS_END_ADDR_BCS350 0x08FFFFFF
+
+
+
+#define FLASH_SIZE_ADDR 0xFFFFEC
+
+#define FLASH_SPI_CMDQ_REG 0xAF003040
+#define FLASH_SPI_WRITEQ_REG 0xAF003044
+#define FLASH_SPI_READQ_REG 0xAF003048
+#define FLASH_CONFIG_REG 0xAF003050
+#define FLASH_GPIO_CONFIG_REG 0xAF000030
+
+#define FLASH_CMD_WRITE_ENABLE 0x06
+#define FLASH_CMD_READ_ENABLE 0x03
+#define FLASH_CMD_RESET_WRITE_ENABLE 0x04
+#define FLASH_CMD_STATUS_REG_READ 0x05
+#define FLASH_CMD_STATUS_REG_WRITE 0x01
+#define FLASH_CMD_READ_ID 0x9F
+
+#define PAD_SELECT_REGISTER 0xAF000410
+
+#define FLASH_PART_SST25VF080B 0xBF258E
+
+#define EEPROM_CAL_DATA_INTERNAL_LOC 0xbFB00008
+
+#define EEPROM_CALPARAM_START 0x200
+#define EEPROM_SIZE_OFFSET 524
+
+//As Read/Write time vaires from 1.5 to 3.0 ms.
+//so After Ignoring the rdm/wrm time(that is dependent on many factor like interface etc.),
+//here time calculated meets the worst case delay, 3.0 ms
+#define MAX_FLASH_RETRIES 4
+#define FLASH_PER_RETRIES_DELAY 16
+
+
+#define EEPROM_MAX_CAL_AREA_SIZE 0xF0000
+
+
+
+#define BECM ntohl(0x4245434d)
+
+#define FLASH_2X_MAJOR_NUMBER 0x2
+#define DSD_IMAGE_MAGIC_NUMBER 0xBECE0D5D
+#define ISO_IMAGE_MAGIC_NUMBER 0xBECE0150
+#define NON_CDLESS_DEVICE_BOOT_SIG 0xBECEB007
+#define MINOR_VERSION(x) ((x >>16) & 0xFFFF)
+#define MAJOR_VERSION(x) (x & 0xFFFF)
+#define CORRUPTED_PATTERN 0x0
+#define UNINIT_PTR_IN_CS 0xBBBBDDDD
+
+#define VENDOR_PTR_IN_CS 0xAAAACCCC
+
+
+#define FLASH2X_SECTION_PRESENT 1<<0
+#define FLASH2X_SECTION_VALID 1<<1
+#define FLASH2X_SECTION_RO 1<<2
+#define FLASH2X_SECTION_ACT 1<<3
+#define SECTOR_IS_NOT_WRITABLE STATUS_FAILURE
+#define INVALID_OFFSET STATUS_FAILURE
+#define INVALID_SECTION STATUS_FAILURE
+#define SECTOR_1K 1024
+#define SECTOR_64K (64 *SECTOR_1K)
+#define SECTOR_128K (2 * SECTOR_64K)
+#define SECTOR_256k (2 * SECTOR_128K)
+#define SECTOR_512K (2 * SECTOR_256k)
+#define FLASH_PART_SIZE (16 * 1024 * 1024)
+#define RESET_CHIP_SELECT -1
+#define CHIP_SELECT_BIT12 12
+
+#define SECTOR_READWRITE_PERMISSION 0
+#define SECTOR_READONLY 1
+#define SIGNATURE_SIZE 4
+#define DEFAULT_BUFF_SIZE 0x10000
+
+
+#define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL))
+
+#if 0
+INT BeceemEEPROMBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+
+INT BeceemFlashBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
+
+UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
+
+UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter);
+
+
+
+INT BeceemFlashBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
+
+INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
+
+
+INT BeceemEEPROMBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUCHAR pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+
+INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
+
+NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
+
+INT BeceemNVMRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes);
+
+INT BeceemNVMWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify);
+
+INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter);
+
+INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
+
+INT BcmInitNVM(PMINI_ADAPTER Adapter);
+
+VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
+
+VOID BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
+
+#endif
+
+#endif
+
diff --git a/drivers/staging/bcm/osal_misc.h b/drivers/staging/bcm/osal_misc.h
new file mode 100644
index 000000000000..ff4adde17cd8
--- /dev/null
+++ b/drivers/staging/bcm/osal_misc.h
@@ -0,0 +1,49 @@
+ /*++
+
+ Copyright (c) Beceem Communications Inc.
+
+ Module Name:
+ OSAL_Misc.h
+
+ Abstract:
+ Provides the OS Abstracted macros to access:
+ Linked Lists
+ Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
+ Files
+
+
+ Revision History:
+ Who When What
+ -------- -------- ----------------------------------------------
+ Name Date Created/reviewed/modified
+ Rajeev 24/1/08 Created
+ Notes:
+
+ --*/
+#ifndef _OSAL_MISC_H_
+#define _OSAL_MISC_H_
+//OSAL Macros
+//OSAL Primitives
+typedef PUCHAR POSAL_NW_PACKET ; //Nw packets
+
+
+#define OsalMemAlloc(n,t) kmalloc(n,GFP_KERNEL)
+
+#define OsalMemFree(x,n) bcm_kfree(x)
+
+#define OsalMemMove(dest, src, len) \
+{ \
+ memcpy(dest,src, len); \
+}
+
+#define OsalZeroMemory(pDest, Len) \
+{ \
+ memset(pDest,0,Len); \
+}
+
+//#define OsalMemSet(pSrc,Char,Len) memset(pSrc,Char,Len)
+
+bool OsalMemCompare(void *dest, void *src, UINT len);
+
+#endif
+
diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c
new file mode 100644
index 000000000000..fc5d07aec3d2
--- /dev/null
+++ b/drivers/staging/bcm/sort.c
@@ -0,0 +1,63 @@
+#include "headers.h"
+
+/*
+ * File Name: sort.c
+ *
+ * Author: Beceem Communications Pvt. Ltd
+ *
+ * Abstract: This file contains the routines sorting the classification rules.
+ *
+ * Copyright (c) 2007 Beceem Communications Pvt. Ltd
+ */
+
+VOID SortPackInfo(PMINI_ADAPTER Adapter)
+{
+ UINT nIndex1;
+ UINT nIndex2;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=======");
+
+ for(nIndex1 = 0; nIndex1 < NO_OF_QUEUES -2 ; nIndex1++)
+ {
+ for(nIndex2 = nIndex1 + 1 ; nIndex2 < NO_OF_QUEUES -1 ; nIndex2++)
+ {
+ if(Adapter->PackInfo[nIndex1].bValid && Adapter->PackInfo[nIndex2].bValid)
+ {
+ if(Adapter->PackInfo[nIndex2].u8TrafficPriority <
+ Adapter->PackInfo[nIndex1].u8TrafficPriority)
+ {
+ PacketInfo stTemppackInfo = Adapter->PackInfo[nIndex2];
+ Adapter->PackInfo[nIndex2] = Adapter->PackInfo[nIndex1];
+ Adapter->PackInfo[nIndex1] = stTemppackInfo;
+
+ }
+ }
+ }
+ }
+}
+
+VOID SortClassifiers(PMINI_ADAPTER Adapter)
+{
+ UINT nIndex1;
+ UINT nIndex2;
+
+ BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=======");
+
+ for(nIndex1 = 0; nIndex1 < MAX_CLASSIFIERS -1 ; nIndex1++)
+ {
+ for(nIndex2 = nIndex1 + 1 ; nIndex2 < MAX_CLASSIFIERS ; nIndex2++)
+ {
+ if(Adapter->astClassifierTable[nIndex1].bUsed && Adapter->astClassifierTable[nIndex2].bUsed)
+ {
+ if(Adapter->astClassifierTable[nIndex2].u8ClassifierRulePriority <
+ Adapter->astClassifierTable[nIndex1].u8ClassifierRulePriority)
+ {
+ S_CLASSIFIER_RULE stTempClassifierRule = Adapter->astClassifierTable[nIndex2];
+ Adapter->astClassifierTable[nIndex2] = Adapter->astClassifierTable[nIndex1];
+ Adapter->astClassifierTable[nIndex1] = stTempClassifierRule;
+
+ }
+ }
+ }
+ }
+}
diff --git a/drivers/staging/bcm/target_params.h b/drivers/staging/bcm/target_params.h
new file mode 100644
index 000000000000..2d8b8a367b38
--- /dev/null
+++ b/drivers/staging/bcm/target_params.h
@@ -0,0 +1,81 @@
+#ifndef TARGET_PARAMS_H
+#define TARGET_PARAMS_H
+
+typedef struct _TARGET_PARAMS
+{
+ B_UINT32 m_u32CfgVersion;
+
+ // Scanning Related Params
+ B_UINT32 m_u32CenterFrequency;
+ B_UINT32 m_u32BandAScan;
+ B_UINT32 m_u32BandBScan;
+ B_UINT32 m_u32BandCScan;
+
+
+ // QoS Params
+ B_UINT32 m_u32ErtpsOptions;
+
+ B_UINT32 m_u32PHSEnable;
+
+
+ // HO Params
+ B_UINT32 m_u32HoEnable;
+
+ B_UINT32 m_u32HoReserved1;
+ B_UINT32 m_u32HoReserved2;
+ // Power Control Params
+
+ B_UINT32 m_u32MimoEnable;
+
+ B_UINT32 m_u32SecurityEnable;
+
+ B_UINT32 m_u32PowerSavingModesEnable; //bit 1: 1 Idlemode enable; bit2: 1 Sleepmode Enable
+ /* PowerSaving Mode Options:
+ bit 0 = 1: CPE mode - to keep pcmcia if alive;
+ bit 1 = 1: CINR reporing in Idlemode Msg
+ bit 2 = 1: Default PSC Enable in sleepmode*/
+ B_UINT32 m_u32PowerSavingModeOptions;
+
+ B_UINT32 m_u32ArqEnable;
+
+ // From Version #3, the HARQ section renamed as general
+ B_UINT32 m_u32HarqEnable;
+ // EEPROM Param Location
+ B_UINT32 m_u32EEPROMFlag;
+ // BINARY TYPE - 4th MSByte: Interface Type - 3rd MSByte: Vendor Type - 2nd MSByte
+ // Unused - LSByte
+ B_UINT32 m_u32Customize;
+ B_UINT32 m_u32ConfigBW; /* In Hz */
+ B_UINT32 m_u32ShutDownInitThresholdTimer;
+
+ B_UINT32 m_u32RadioParameter;
+ B_UINT32 m_u32PhyParameter1;
+ B_UINT32 m_u32PhyParameter2;
+ B_UINT32 m_u32PhyParameter3;
+
+ B_UINT32 m_u32TestOptions; // in eval mode only; lower 16bits = basic cid for testing; then bit 16 is test cqich,bit 17 test init rang; bit 18 test periodic rang and bit 19 is test harq ack/nack
+
+ B_UINT32 m_u32MaxMACDataperDLFrame;
+ B_UINT32 m_u32MaxMACDataperULFrame;
+
+ B_UINT32 m_u32Corr2MacFlags;
+
+ //adding driver params.
+ B_UINT32 HostDrvrConfig1;
+ B_UINT32 HostDrvrConfig2;
+ B_UINT32 HostDrvrConfig3;
+ B_UINT32 HostDrvrConfig4;
+ B_UINT32 HostDrvrConfig5;
+ B_UINT32 HostDrvrConfig6;
+ B_UINT32 m_u32SegmentedPUSCenable;
+
+ // removed SHUT down related 'unused' params from here to sync 4.x and 5.x CFG files..
+
+ //BAMC Related Parameters
+ //Bit 0-15 Band AMC signaling configuration: Bit 1 = 1 – Enable Band AMC signaling.
+ //bit 16-31 Band AMC Data configuration: Bit 16 = 1 – Band AMC 2x3 support.
+ B_UINT32 m_u32BandAMCEnable;
+
+} stTargetParams,TARGET_PARAMS,*PTARGET_PARAMS, STARGETPARAMS, *PSTARGETPARAMS;
+
+#endif
diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c
new file mode 100644
index 000000000000..4178cd161da3
--- /dev/null
+++ b/drivers/staging/bcm/vendorspecificextn.c
@@ -0,0 +1,146 @@
+#include "headers.h"
+//-----------------------------------------------------------------------------
+// Procedure: vendorextnGetSectionInfo
+//
+// Description: Finds the type of NVM used.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pNVMType - ptr to NVM type.
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//-----------------------------------------------------------------------------
+INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendorInfo)
+{
+ return STATUS_FAILURE;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: vendorextnInit
+//
+// Description: Initializing the vendor extension NVM interface
+//
+// Arguments:
+// Adapter - Pointer to MINI Adapter Structure.
+
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//-----------------------------------------------------------------------------
+INT vendorextnInit(PMINI_ADAPTER Adapter)
+{
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: vendorextnExit
+//
+// Description: Free the resource associated with vendor extension NVM interface
+//
+// Arguments:
+// Adapter - Pointer to MINI Adapter Structure.
+
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//-----------------------------------------------------------------------------
+INT vendorextnExit(PMINI_ADAPTER Adapter)
+{
+ return STATUS_SUCCESS;
+}
+
+//------------------------------------------------------------------------
+// Procedure: vendorextnIoctl
+//
+// Description: execute the vendor extension specific ioctl
+//
+//Arguments:
+// Adapter -Beceem private Adapter Structure
+// cmd -vendor extension specific Ioctl commad
+// arg -input parameter sent by vendor
+//
+// Returns:
+// CONTINUE_COMMON_PATH in case it is not meant to be processed by vendor ioctls
+// STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value
+//
+//--------------------------------------------------------------------------
+INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg)
+{
+ return CONTINUE_COMMON_PATH;
+}
+
+
+
+//------------------------------------------------------------------
+// Procedure: vendorextnReadSection
+//
+// Description: Reads from a section of NVM
+//
+// Arguments:
+// pContext - ptr to Adapter object instance
+// pBuffer - Read the data from Vendor Area to this buffer
+// SectionVal - Value of type of Section
+// Offset - Read from the Offset of the Vendor Section.
+// numOfBytes - Read numOfBytes from the Vendor section to Buffer
+//
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//------------------------------------------------------------------
+
+INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes)
+{
+ return STATUS_FAILURE;
+}
+
+
+
+//------------------------------------------------------------------
+// Procedure: vendorextnWriteSection
+//
+// Description: Write to a Section of NVM
+//
+// Arguments:
+// pContext - ptr to Adapter object instance
+// pBuffer - Write the data provided in the buffer
+// SectionVal - Value of type of Section
+// Offset - Writes to the Offset of the Vendor Section.
+// numOfBytes - Write num Bytes after reading from pBuffer.
+// bVerify - the Buffer Written should be verified.
+//
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//------------------------------------------------------------------
+INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes, BOOLEAN bVerify)
+{
+ return STATUS_FAILURE;
+}
+
+
+
+//------------------------------------------------------------------
+// Procedure: vendorextnWriteSectionWithoutErase
+//
+// Description: Write to a Section of NVM without erasing the sector
+//
+// Arguments:
+// pContext - ptr to Adapter object instance
+// pBuffer - Write the data provided in the buffer
+// SectionVal - Value of type of Section
+// Offset - Writes to the Offset of the Vendor Section.
+// numOfBytes - Write num Bytes after reading from pBuffer.
+//
+// Returns:
+// STATUS_SUCCESS/STATUS_FAILURE
+//
+//------------------------------------------------------------------
+INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes)
+{
+ return STATUS_FAILURE;
+}
+
diff --git a/drivers/staging/bcm/vendorspecificextn.h b/drivers/staging/bcm/vendorspecificextn.h
new file mode 100644
index 000000000000..7ff14951f0ca
--- /dev/null
+++ b/drivers/staging/bcm/vendorspecificextn.h
@@ -0,0 +1,18 @@
+
+#ifndef __VENDOR_EXTN_NVM_H__
+#define __VENDOR_EXTN_NVM_H__
+
+#define CONTINUE_COMMON_PATH 0xFFFF
+
+INT vendorextnGetSectionInfo(PVOID pContext,PFLASH2X_VENDORSPECIFIC_INFO pVendorInfo);
+INT vendorextnExit(PMINI_ADAPTER Adapter);
+INT vendorextnInit(PMINI_ADAPTER Adapter);
+INT vendorextnIoctl(PMINI_ADAPTER Adapter, UINT cmd, ULONG arg);
+INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes);
+INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes, BOOLEAN bVerify);
+INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, FLASH2X_SECTION_VAL SectionVal,
+ UINT offset, UINT numOfBytes);
+
+#endif /* */
diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig
new file mode 100644
index 000000000000..6b74685a331f
--- /dev/null
+++ b/drivers/staging/brcm80211/Kconfig
@@ -0,0 +1,14 @@
+menuconfig BRCM80211
+ tristate "Broadcom 802.11 WLAN driver for bcm43xx chips"
+ depends on PCI && WLAN
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ default N
+ help
+ If built as a module, it will be called brcm80211.ko.
+
+config BRCM80211_PCI
+ bool "Broadcom 802.11 WLAN NIC driver"
+ depends on BRCM80211
+ default y
+
diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile
new file mode 100644
index 000000000000..05a4103fe0a5
--- /dev/null
+++ b/drivers/staging/brcm80211/Makefile
@@ -0,0 +1,65 @@
+#
+# Makefile fragment for Broadcom 802.11n Networking Device Driver
+#
+# Copyright (c) 2010 Broadcom Corporation
+#
+# 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.
+
+EXTRA_CFLAGS := -DBCMDBG -DWLC_HIGH -DSTA -DWME -DWL11N -DDBAND -DBCMDMA32 -DBCMNVRAMR -Idrivers/staging/brcm80211/sys -Idrivers/staging/brcm80211/phy -Idrivers/staging/brcm80211/util -Idrivers/staging/brcm80211/include -Wall -Wstrict-prototypes -Werror -Wmissing-prototypes
+
+PCI_CFLAGS := -DWLC_LOW
+
+BRCM80211_OFILES := \
+ util/siutils.o \
+ util/aiutils.o \
+ util/bcmotp.o \
+ util/bcmsrom.o \
+ util/bcmutils.o \
+ util/bcmwifi.o \
+ util/bcmwpa.o \
+ util/hndpmu.o \
+ util/linux_osl.o \
+ sys/wlc_alloc.o \
+ sys/wlc_antsel.o \
+ sys/wlc_channel.o \
+ sys/wlc_event.o \
+ sys/wlc_mac80211.o \
+ sys/wlc_rate.o \
+ sys/wlc_stf.o \
+ sys/wl_mac80211.o \
+ sys/wlc_ampdu.o
+
+PCIFILES := \
+ phy/wlc_phy_cmn.o \
+ phy/wlc_phy_lcn.o \
+ phy/wlc_phy_n.o \
+ phy/wlc_phytbl_lcn.o \
+ phy/wlc_phytbl_n.o \
+ sys/wlc_bmac.o \
+ sys/wlc_phy_shim.o \
+ sys/wl_ucode_loader.o \
+ util/hnddma.o \
+ util/nicpci.o \
+ util/nvram/nvram_ro.o \
+ util/qmath.o
+
+MODULEPFX := brcm80211
+
+obj-m += $(MODULEPFX).o
+
+# PCI driver
+ifeq ($(CONFIG_BRCM80211_PCI),y)
+EXTRA_CFLAGS += $(PCI_CFLAGS)
+$(MODULEPFX)-objs = $(BRCM80211_OFILES) $(PCIFILES)
+endif
+
diff --git a/drivers/staging/brcm80211/Module.symvers b/drivers/staging/brcm80211/Module.symvers
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/staging/brcm80211/Module.symvers
diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
new file mode 100644
index 000000000000..c3ba9bb9b116
--- /dev/null
+++ b/drivers/staging/brcm80211/README
@@ -0,0 +1,94 @@
+Broadcom Mac80211 driver
+
+This is a driver in progress. It has features still to be implemented well as
+bugs in current code.
+
+
+What's here and not here
+=======================
+- Completely open source host driver, no binary object files
+- Features Broadcom's OneDriver architecture (single source base for
+ supported chips and architectures)
+- On-chip firmware loaded using standard request_firmware()
+- Support for BCM43224, BCM43225, BCM4313 (PCIe NIC)
+- Framework for supporting new chips, including mac80211-aware embedded chips
+- Does not support older PCI/PCIe chips with SSB backplane
+- Driver includes BMAC interface for transparent dongle support
+- Uses minstrel_ht rate algorithm
+- HW based encryption not enabled yet
+
+
+What's done
+==========
+- Integration with mac80211 stack
+- A-MPDU single & dual stream rates
+- BCM43224: Dualband, Dual stream, 20MHz channels
+ Throughput (in chamber): ~85-90 Mbits/sec (in both 2.4 & 5 GHz bands)
+- BCM43225: 2.4 GHz, Dual Stream, 20MHz channels
+ Throughput (in chamber): ~85-90 Mbits/sec
+- BCM4313: 2.4 GHz, Single Stream
+ Throughput (in chamber): ~40 Mbits/sec
+
+
+Things To Be Done
+=================
+See the TODO file
+
+
+Firmware installation
+======================
+Firmware is available from the Linux firmware repository at:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
+ http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+ https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+
+For all chips, copy brcm/bcm43xx-0-610-809-0.fw and
+brcm/bcm43xx_hdr-0-610-809-0.fw to /lib/firmware/brcm (or wherever firmware is
+normally installed on the system). In the /lib/firmware/brcm directory, then
+create the following symlinks:
+
+ ln -s bcm43xx-0-610-809-0.fw bcm43xx-0.fw
+ ln -s bcm43xx_hdr-0-610-809-0.fw bcm43xx_hdr-0.fw
+
+
+Currently supported chips
+==============
+PCI
+Name Device ID
+BCM4313 0x4727
+BCM43224 0x4353
+BCM43225 0x4357
+
+
+Bugs/Problems
+==============
+- Driver can get confused while scanning during high throughput, can cause
+ burping, hanging, and possible crashing.
+- Occasional hangs & burps with BCM43224 on 2.4 GHz with dual stream rates.
+- Occasional crashes with BCM43224 on multicore machines.
+
+
+Note on Regulatory Implementation
+================================
+This generation of chips contain additional regulatory support independent of
+the driver. The devices use a single worldwide regulatory domain, with channels
+12-14 (2.4 GHz band) and channels 52-64 and 100-140 (5 GHz band) restricted to
+passive operation. Transmission on those channels is suppressed until
+appropriate other traffic is observed on those channels.
+
+Within the driver, we use the ficticious country code "X2" to represent this
+worldwide regulatory domain. There is currently no interface to configure a
+different domain.
+
+The driver reads the SROM country code from the chip and hands it up to
+mac80211 as the regulatory hint, however this information is otherwise unused
+with the driver.
+
+
+Contact Info:
+=============
+Brett Rudley brudley@broadcom.com
+Henry Ptasinski henryp@broadcom.com
+Nohee Ko noheek@broadcom.com
+
diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
new file mode 100644
index 000000000000..f4bb28d237ea
--- /dev/null
+++ b/drivers/staging/brcm80211/TODO
@@ -0,0 +1,47 @@
+To Do List for Broadcom Mac80211 driver
+
+Features to be added
+=====================
+- 40 MHz channels
+- Power Save
+- AP
+- IBSS
+- HW-based encryption
+- LED support
+- RFKILL
+- Debugfs and debugability
+
+Code cleanup
+============
+- Use proper kernel coding standards
+- Remove overlap with system header files. (ie much of include/proto/*.h should
+ be removed)
+- Purge unused variables/data structs/functions BUT keep code related to
+ features that are being added (ie AP mode, 40 Mhz channels, IBSS etc).
+- Replace proprietary utility functions with public kernel versions.
+
+Bugs
+====
+- Various occasional asserts/hangs
+- Scanning during data transfer sometimes causes major slowdowns. Sometimes
+ revcovers when scan is done, other times not.
+- Mac80211 API not completely implemented (ie ops_bss_info_changed,
+ ops_get_stats, etc)
+
+Other
+=====
+- wlc_mac80211.[ch], wl_mac80211.[ch] and linux_osl.c all need to be refactored
+ and combined.
+- Replace driver's proprietary ssb interface with generic kernel ssb module
+ (only used when compiling for SDIO).
+- PCI and SDIO support are currently #ifdef'ed exclusive of each other, which
+ leads to a separate wl.ko for each. This should be changed to runtime
+ handling of different interfaces so that a single binary driver can be built.
+- Add support for new chips (obviously an ongoing item).
+
+Contact
+=====
+Brett Rudley <brudley@broadcom.com>
+Henry Ptasinski <henryp@broadcom.com>
+Nohee Ko <noheek@broadcom.com>
+
diff --git a/drivers/staging/brcm80211/include/aidmp.h b/drivers/staging/brcm80211/include/aidmp.h
new file mode 100644
index 000000000000..e64dd0345693
--- /dev/null
+++ b/drivers/staging/brcm80211/include/aidmp.h
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _AIDMP_H
+#define _AIDMP_H
+
+/* Manufacturer Ids */
+#define MFGID_ARM 0x43b
+#define MFGID_BRCM 0x4bf
+#define MFGID_MIPS 0x4a7
+
+/* Component Classes */
+#define CC_SIM 0
+#define CC_EROM 1
+#define CC_CORESIGHT 9
+#define CC_VERIF 0xb
+#define CC_OPTIMO 0xd
+#define CC_GEN 0xe
+#define CC_PRIMECELL 0xf
+
+/* Enumeration ROM registers */
+#define ER_EROMENTRY 0x000
+#define ER_REMAPCONTROL 0xe00
+#define ER_REMAPSELECT 0xe04
+#define ER_MASTERSELECT 0xe10
+#define ER_ITCR 0xf00
+#define ER_ITIP 0xf04
+
+/* Erom entries */
+#define ER_TAG 0xe
+#define ER_TAG1 0x6
+#define ER_VALID 1
+#define ER_CI 0
+#define ER_MP 2
+#define ER_ADD 4
+#define ER_END 0xe
+#define ER_BAD 0xffffffff
+
+/* EROM CompIdentA */
+#define CIA_MFG_MASK 0xfff00000
+#define CIA_MFG_SHIFT 20
+#define CIA_CID_MASK 0x000fff00
+#define CIA_CID_SHIFT 8
+#define CIA_CCL_MASK 0x000000f0
+#define CIA_CCL_SHIFT 4
+
+/* EROM CompIdentB */
+#define CIB_REV_MASK 0xff000000
+#define CIB_REV_SHIFT 24
+#define CIB_NSW_MASK 0x00f80000
+#define CIB_NSW_SHIFT 19
+#define CIB_NMW_MASK 0x0007c000
+#define CIB_NMW_SHIFT 14
+#define CIB_NSP_MASK 0x00003e00
+#define CIB_NSP_SHIFT 9
+#define CIB_NMP_MASK 0x000001f0
+#define CIB_NMP_SHIFT 4
+
+/* EROM MasterPortDesc */
+#define MPD_MUI_MASK 0x0000ff00
+#define MPD_MUI_SHIFT 8
+#define MPD_MP_MASK 0x000000f0
+#define MPD_MP_SHIFT 4
+
+/* EROM AddrDesc */
+#define AD_ADDR_MASK 0xfffff000
+#define AD_SP_MASK 0x00000f00
+#define AD_SP_SHIFT 8
+#define AD_ST_MASK 0x000000c0
+#define AD_ST_SHIFT 6
+#define AD_ST_SLAVE 0x00000000
+#define AD_ST_BRIDGE 0x00000040
+#define AD_ST_SWRAP 0x00000080
+#define AD_ST_MWRAP 0x000000c0
+#define AD_SZ_MASK 0x00000030
+#define AD_SZ_SHIFT 4
+#define AD_SZ_4K 0x00000000
+#define AD_SZ_8K 0x00000010
+#define AD_SZ_16K 0x00000020
+#define AD_SZ_SZD 0x00000030
+#define AD_AG32 0x00000008
+#define AD_ADDR_ALIGN 0x00000fff
+#define AD_SZ_BASE 0x00001000 /* 4KB */
+
+/* EROM SizeDesc */
+#define SD_SZ_MASK 0xfffff000
+#define SD_SG32 0x00000008
+#define SD_SZ_ALIGN 0x00000fff
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+typedef volatile struct _aidmp {
+ uint32 oobselina30; /* 0x000 */
+ uint32 oobselina74; /* 0x004 */
+ uint32 PAD[6];
+ uint32 oobselinb30; /* 0x020 */
+ uint32 oobselinb74; /* 0x024 */
+ uint32 PAD[6];
+ uint32 oobselinc30; /* 0x040 */
+ uint32 oobselinc74; /* 0x044 */
+ uint32 PAD[6];
+ uint32 oobselind30; /* 0x060 */
+ uint32 oobselind74; /* 0x064 */
+ uint32 PAD[38];
+ uint32 oobselouta30; /* 0x100 */
+ uint32 oobselouta74; /* 0x104 */
+ uint32 PAD[6];
+ uint32 oobseloutb30; /* 0x120 */
+ uint32 oobseloutb74; /* 0x124 */
+ uint32 PAD[6];
+ uint32 oobseloutc30; /* 0x140 */
+ uint32 oobseloutc74; /* 0x144 */
+ uint32 PAD[6];
+ uint32 oobseloutd30; /* 0x160 */
+ uint32 oobseloutd74; /* 0x164 */
+ uint32 PAD[38];
+ uint32 oobsynca; /* 0x200 */
+ uint32 oobseloutaen; /* 0x204 */
+ uint32 PAD[6];
+ uint32 oobsyncb; /* 0x220 */
+ uint32 oobseloutben; /* 0x224 */
+ uint32 PAD[6];
+ uint32 oobsyncc; /* 0x240 */
+ uint32 oobseloutcen; /* 0x244 */
+ uint32 PAD[6];
+ uint32 oobsyncd; /* 0x260 */
+ uint32 oobseloutden; /* 0x264 */
+ uint32 PAD[38];
+ uint32 oobaextwidth; /* 0x300 */
+ uint32 oobainwidth; /* 0x304 */
+ uint32 oobaoutwidth; /* 0x308 */
+ uint32 PAD[5];
+ uint32 oobbextwidth; /* 0x320 */
+ uint32 oobbinwidth; /* 0x324 */
+ uint32 oobboutwidth; /* 0x328 */
+ uint32 PAD[5];
+ uint32 oobcextwidth; /* 0x340 */
+ uint32 oobcinwidth; /* 0x344 */
+ uint32 oobcoutwidth; /* 0x348 */
+ uint32 PAD[5];
+ uint32 oobdextwidth; /* 0x360 */
+ uint32 oobdinwidth; /* 0x364 */
+ uint32 oobdoutwidth; /* 0x368 */
+ uint32 PAD[37];
+ uint32 ioctrlset; /* 0x400 */
+ uint32 ioctrlclear; /* 0x404 */
+ uint32 ioctrl; /* 0x408 */
+ uint32 PAD[61];
+ uint32 iostatus; /* 0x500 */
+ uint32 PAD[127];
+ uint32 ioctrlwidth; /* 0x700 */
+ uint32 iostatuswidth; /* 0x704 */
+ uint32 PAD[62];
+ uint32 resetctrl; /* 0x800 */
+ uint32 resetstatus; /* 0x804 */
+ uint32 resetreadid; /* 0x808 */
+ uint32 resetwriteid; /* 0x80c */
+ uint32 PAD[60];
+ uint32 errlogctrl; /* 0x900 */
+ uint32 errlogdone; /* 0x904 */
+ uint32 errlogstatus; /* 0x908 */
+ uint32 errlogaddrlo; /* 0x90c */
+ uint32 errlogaddrhi; /* 0x910 */
+ uint32 errlogid; /* 0x914 */
+ uint32 errloguser; /* 0x918 */
+ uint32 errlogflags; /* 0x91c */
+ uint32 PAD[56];
+ uint32 intstatus; /* 0xa00 */
+ uint32 PAD[127];
+ uint32 config; /* 0xe00 */
+ uint32 PAD[63];
+ uint32 itcr; /* 0xf00 */
+ uint32 PAD[3];
+ uint32 itipooba; /* 0xf10 */
+ uint32 itipoobb; /* 0xf14 */
+ uint32 itipoobc; /* 0xf18 */
+ uint32 itipoobd; /* 0xf1c */
+ uint32 PAD[4];
+ uint32 itipoobaout; /* 0xf30 */
+ uint32 itipoobbout; /* 0xf34 */
+ uint32 itipoobcout; /* 0xf38 */
+ uint32 itipoobdout; /* 0xf3c */
+ uint32 PAD[4];
+ uint32 itopooba; /* 0xf50 */
+ uint32 itopoobb; /* 0xf54 */
+ uint32 itopoobc; /* 0xf58 */
+ uint32 itopoobd; /* 0xf5c */
+ uint32 PAD[4];
+ uint32 itopoobain; /* 0xf70 */
+ uint32 itopoobbin; /* 0xf74 */
+ uint32 itopoobcin; /* 0xf78 */
+ uint32 itopoobdin; /* 0xf7c */
+ uint32 PAD[4];
+ uint32 itopreset; /* 0xf90 */
+ uint32 PAD[15];
+ uint32 peripherialid4; /* 0xfd0 */
+ uint32 peripherialid5; /* 0xfd4 */
+ uint32 peripherialid6; /* 0xfd8 */
+ uint32 peripherialid7; /* 0xfdc */
+ uint32 peripherialid0; /* 0xfe0 */
+ uint32 peripherialid1; /* 0xfe4 */
+ uint32 peripherialid2; /* 0xfe8 */
+ uint32 peripherialid3; /* 0xfec */
+ uint32 componentid0; /* 0xff0 */
+ uint32 componentid1; /* 0xff4 */
+ uint32 componentid2; /* 0xff8 */
+ uint32 componentid3; /* 0xffc */
+} aidmp_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* Out-of-band Router registers */
+#define OOB_BUSCONFIG 0x020
+#define OOB_STATUSA 0x100
+#define OOB_STATUSB 0x104
+#define OOB_STATUSC 0x108
+#define OOB_STATUSD 0x10c
+#define OOB_ENABLEA0 0x200
+#define OOB_ENABLEA1 0x204
+#define OOB_ENABLEA2 0x208
+#define OOB_ENABLEA3 0x20c
+#define OOB_ENABLEB0 0x280
+#define OOB_ENABLEB1 0x284
+#define OOB_ENABLEB2 0x288
+#define OOB_ENABLEB3 0x28c
+#define OOB_ENABLEC0 0x300
+#define OOB_ENABLEC1 0x304
+#define OOB_ENABLEC2 0x308
+#define OOB_ENABLEC3 0x30c
+#define OOB_ENABLED0 0x380
+#define OOB_ENABLED1 0x384
+#define OOB_ENABLED2 0x388
+#define OOB_ENABLED3 0x38c
+#define OOB_ITCR 0xf00
+#define OOB_ITIPOOBA 0xf10
+#define OOB_ITIPOOBB 0xf14
+#define OOB_ITIPOOBC 0xf18
+#define OOB_ITIPOOBD 0xf1c
+#define OOB_ITOPOOBA 0xf30
+#define OOB_ITOPOOBB 0xf34
+#define OOB_ITOPOOBC 0xf38
+#define OOB_ITOPOOBD 0xf3c
+
+/* DMP wrapper registers */
+#define AI_OOBSELINA30 0x000
+#define AI_OOBSELINA74 0x004
+#define AI_OOBSELINB30 0x020
+#define AI_OOBSELINB74 0x024
+#define AI_OOBSELINC30 0x040
+#define AI_OOBSELINC74 0x044
+#define AI_OOBSELIND30 0x060
+#define AI_OOBSELIND74 0x064
+#define AI_OOBSELOUTA30 0x100
+#define AI_OOBSELOUTA74 0x104
+#define AI_OOBSELOUTB30 0x120
+#define AI_OOBSELOUTB74 0x124
+#define AI_OOBSELOUTC30 0x140
+#define AI_OOBSELOUTC74 0x144
+#define AI_OOBSELOUTD30 0x160
+#define AI_OOBSELOUTD74 0x164
+#define AI_OOBSYNCA 0x200
+#define AI_OOBSELOUTAEN 0x204
+#define AI_OOBSYNCB 0x220
+#define AI_OOBSELOUTBEN 0x224
+#define AI_OOBSYNCC 0x240
+#define AI_OOBSELOUTCEN 0x244
+#define AI_OOBSYNCD 0x260
+#define AI_OOBSELOUTDEN 0x264
+#define AI_OOBAEXTWIDTH 0x300
+#define AI_OOBAINWIDTH 0x304
+#define AI_OOBAOUTWIDTH 0x308
+#define AI_OOBBEXTWIDTH 0x320
+#define AI_OOBBINWIDTH 0x324
+#define AI_OOBBOUTWIDTH 0x328
+#define AI_OOBCEXTWIDTH 0x340
+#define AI_OOBCINWIDTH 0x344
+#define AI_OOBCOUTWIDTH 0x348
+#define AI_OOBDEXTWIDTH 0x360
+#define AI_OOBDINWIDTH 0x364
+#define AI_OOBDOUTWIDTH 0x368
+
+#if defined(IL_BIGENDIAN) && defined(BCMHND74K)
+/* Selective swapped defines for those registers we need in
+ * big-endian code.
+ */
+#define AI_IOCTRLSET 0x404
+#define AI_IOCTRLCLEAR 0x400
+#define AI_IOCTRL 0x40c
+#define AI_IOSTATUS 0x504
+#define AI_RESETCTRL 0x804
+#define AI_RESETSTATUS 0x800
+
+#else /* !IL_BIGENDIAN || !BCMHND74K */
+
+#define AI_IOCTRLSET 0x400
+#define AI_IOCTRLCLEAR 0x404
+#define AI_IOCTRL 0x408
+#define AI_IOSTATUS 0x500
+#define AI_RESETCTRL 0x800
+#define AI_RESETSTATUS 0x804
+
+#endif /* IL_BIGENDIAN && BCMHND74K */
+
+#define AI_IOCTRLWIDTH 0x700
+#define AI_IOSTATUSWIDTH 0x704
+
+#define AI_RESETREADID 0x808
+#define AI_RESETWRITEID 0x80c
+#define AI_ERRLOGCTRL 0xa00
+#define AI_ERRLOGDONE 0xa04
+#define AI_ERRLOGSTATUS 0xa08
+#define AI_ERRLOGADDRLO 0xa0c
+#define AI_ERRLOGADDRHI 0xa10
+#define AI_ERRLOGID 0xa14
+#define AI_ERRLOGUSER 0xa18
+#define AI_ERRLOGFLAGS 0xa1c
+#define AI_INTSTATUS 0xa00
+#define AI_CONFIG 0xe00
+#define AI_ITCR 0xf00
+#define AI_ITIPOOBA 0xf10
+#define AI_ITIPOOBB 0xf14
+#define AI_ITIPOOBC 0xf18
+#define AI_ITIPOOBD 0xf1c
+#define AI_ITIPOOBAOUT 0xf30
+#define AI_ITIPOOBBOUT 0xf34
+#define AI_ITIPOOBCOUT 0xf38
+#define AI_ITIPOOBDOUT 0xf3c
+#define AI_ITOPOOBA 0xf50
+#define AI_ITOPOOBB 0xf54
+#define AI_ITOPOOBC 0xf58
+#define AI_ITOPOOBD 0xf5c
+#define AI_ITOPOOBAIN 0xf70
+#define AI_ITOPOOBBIN 0xf74
+#define AI_ITOPOOBCIN 0xf78
+#define AI_ITOPOOBDIN 0xf7c
+#define AI_ITOPRESET 0xf90
+#define AI_PERIPHERIALID4 0xfd0
+#define AI_PERIPHERIALID5 0xfd4
+#define AI_PERIPHERIALID6 0xfd8
+#define AI_PERIPHERIALID7 0xfdc
+#define AI_PERIPHERIALID0 0xfe0
+#define AI_PERIPHERIALID1 0xfe4
+#define AI_PERIPHERIALID2 0xfe8
+#define AI_PERIPHERIALID3 0xfec
+#define AI_COMPONENTID0 0xff0
+#define AI_COMPONENTID1 0xff4
+#define AI_COMPONENTID2 0xff8
+#define AI_COMPONENTID3 0xffc
+
+/* resetctrl */
+#define AIRC_RESET 1
+
+/* config */
+#define AICFG_OOB 0x00000020
+#define AICFG_IOS 0x00000010
+#define AICFG_IOC 0x00000008
+#define AICFG_TO 0x00000004
+#define AICFG_ERRL 0x00000002
+#define AICFG_RST 0x00000001
+
+#endif /* _AIDMP_H */
diff --git a/drivers/staging/brcm80211/include/bcm_rpc.h b/drivers/staging/brcm80211/include/bcm_rpc.h
new file mode 100644
index 000000000000..eb989ee5ecac
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcm_rpc.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCM_RPC_H_
+#define _BCM_RPC_H_
+
+#include <typedefs.h>
+#include <rpc_osl.h>
+
+typedef struct rpc_info rpc_info_t;
+typedef struct rpc_buf rpc_buf_t;
+struct rpc_transport_info;
+typedef void (*rpc_dispatch_cb_t) (void *ctx, struct rpc_buf *buf);
+typedef void (*rpc_resync_cb_t) (void *ctx);
+typedef void (*rpc_down_cb_t) (void *ctx);
+typedef void (*rpc_txdone_cb_t) (void *ctx, struct rpc_buf *buf);
+extern struct rpc_info *bcm_rpc_attach(void *pdev, osl_t *osh,
+ struct rpc_transport_info *rpc_th);
+
+extern void bcm_rpc_detach(struct rpc_info *rpc);
+extern void bcm_rpc_down(struct rpc_info *rpc);
+extern void bcm_rpc_watchdog(struct rpc_info *rpc);
+
+extern struct rpc_buf *bcm_rpc_buf_alloc(struct rpc_info *rpc, int len);
+extern void bcm_rpc_buf_free(struct rpc_info *rpc, struct rpc_buf *b);
+/* get rpc transport handle */
+extern struct rpc_transport_info *bcm_rpc_tp_get(struct rpc_info *rpc);
+
+/* callback for: data_rx, down, resync */
+extern void bcm_rpc_rxcb_init(struct rpc_info *rpc, void *ctx,
+ rpc_dispatch_cb_t cb, void *dnctx,
+ rpc_down_cb_t dncb, rpc_resync_cb_t resync_cb,
+ rpc_txdone_cb_t);
+extern void bcm_rpc_rxcb_deinit(struct rpc_info *rpci);
+
+/* HOST or CLIENT rpc call, requiring no return value */
+extern int bcm_rpc_call(struct rpc_info *rpc, struct rpc_buf *b);
+
+/* HOST rpc call, demanding return.
+ * The thread may be suspended and control returns back to OS
+ * The thread will resume(waked up) on either the return signal received or timeout
+ * The implementation details depend on OS
+ */
+extern struct rpc_buf *bcm_rpc_call_with_return(struct rpc_info *rpc,
+ struct rpc_buf *b);
+
+/* CLIENT rpc call to respond to bcm_rpc_call_with_return, requiring no return value */
+extern int bcm_rpc_call_return(struct rpc_info *rpc, struct rpc_buf *retb);
+
+extern uint bcm_rpc_buf_header_len(struct rpc_info *rpci);
+
+#define RPC_PKTLOG_SIZE 50 /* Depth of the history */
+#define RPC_PKTLOG_RD_LEN 3
+#define RPC_PKTLOG_DUMP_SIZE 150 /* dump size should be more than the product of above two */
+extern int bcm_rpc_pktlog_get(struct rpc_info *rpci, uint32 *buf,
+ uint buf_size, bool send);
+extern int bcm_rpc_dump(rpc_info_t *rpci, struct bcmstrbuf *b);
+
+/* HIGH/BMAC: bit 15-8: RPC module, bit 7-0: TP module */
+#define RPC_ERROR_VAL 0x0001
+#define RPC_TRACE_VAL 0x0002
+#define RPC_PKTTRACE_VAL 0x0004
+#define RPC_PKTLOG_VAL 0x0008
+extern void bcm_rpc_msglevel_set(struct rpc_info *rpci, uint16 msglevel,
+ bool high_low);
+
+#endif /* _BCM_RPC_H_ */
diff --git a/drivers/staging/brcm80211/include/bcm_rpc_tp.h b/drivers/staging/brcm80211/include/bcm_rpc_tp.h
new file mode 100644
index 000000000000..c0ea7bba3d83
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcm_rpc_tp.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcm_rpc_tp_h_
+#define _bcm_rpc_tp_h_
+#include <bcm_rpc.h>
+
+#define DBUS_RX_BUFFER_SIZE_RPC (2100) /* rxbufsize for dbus_attach, linux only for now */
+
+#define BCM_RPC_TP_ENCAP_LEN 4 /* TP header is 4 bytes */
+
+#define BCM_RPC_TP_HOST_AGG_MASK 0xffff0000
+#define BCM_RPC_TP_HOST_AGG_SHIFT 16
+#define BCM_RPC_TP_HOST_AGG_AMPDU 0x00010000 /* HOST->DNGL ampdu aggregation */
+#define BCM_RPC_TP_HOST_AGG_TEST 0x00100000 /* HOST->DNGL test aggregation */
+#define BCM_RPC_TP_DNGL_AGG_MASK 0x0000ffff
+#define BCM_RPC_TP_DNGL_AGG_DPC 0x00000001 /* DNGL->HOST data aggregation */
+#define BCM_RPC_TP_DNGL_AGG_FLOWCTL 0x00000002 /* DNGL->HOST tx flowcontrol agg */
+#define BCM_RPC_TP_DNGL_AGG_TEST 0x00000010 /* DNGL->HOST test agg */
+
+#define BCM_RPC_TP_DNGL_AGG_MAX_SFRAME 3 /* max agg subframes, must be <= USB_NTXD */
+#define BCM_RPC_TP_DNGL_AGG_MAX_BYTE 4000 /* max agg bytes */
+
+#define BCM_RPC_TP_HOST_AGG_MAX_SFRAME 3 /* max agg subframes, AMPDU only, 3 is enough */
+#define BCM_RPC_TP_HOST_AGG_MAX_BYTE 3400 /* max agg bytes; to fit 2+ tcp/udp pkts. Each one:
+ * 802.3pkt + 802.11 hdr + rpc hdr + tp hdr < 1700B
+ * Need to be in sync with dongle usb rx dma
+ * rxbufsize(USBBULK_RXBUF_GIANT in usbdev_sb.c)
+ */
+/* TP-DBUS pkts flowcontrol */
+#define BCM_RPC_TP_DBUS_NTXQ 50 /* queue size for TX on bulk OUT, aggregation possible */
+#define BCM_RPC_TP_DBUS_NRXQ 50 /* queue size for RX on bulk IN, aggregation possible */
+#define BCM_RPC_TP_DBUS_NRXQ_CTRL 1 /* queue size for RX on ctl EP0 */
+
+#define BCM_RPC_TP_DBUS_NRXQ_PKT (BCM_RPC_TP_DBUS_NRXQ * BCM_RPC_TP_DNGL_AGG_MAX_SFRAME)
+#define BCM_RPC_TP_DBUS_NTXQ_PKT (BCM_RPC_TP_DBUS_NTXQ * BCM_RPC_TP_HOST_AGG_MAX_SFRAME)
+
+typedef struct rpc_transport_info rpc_tp_info_t;
+
+typedef void (*rpc_tx_complete_fn_t) (void *, rpc_buf_t *, int status);
+typedef void (*rpc_rx_fn_t) (void *, rpc_buf_t *);
+
+#ifdef WLC_LOW
+typedef void (*rpc_txflowctl_cb_t) (void *ctx, bool on);
+#endif
+
+extern rpc_tp_info_t *bcm_rpc_tp_attach(osl_t *osh, void *bus);
+extern void bcm_rpc_tp_detach(rpc_tp_info_t *rpcb);
+extern void bcm_rpc_tp_down(rpc_tp_info_t *rpcb);
+extern void bcm_rpc_tp_watchdog(rpc_tp_info_t *rpcb);
+
+extern int bcm_rpc_tp_buf_send(rpc_tp_info_t *rpcb, rpc_buf_t *buf);
+
+/* callback for tx_complete, rx_pkt */
+extern void bcm_rpc_tp_register_cb(rpc_tp_info_t *rpcb,
+ rpc_tx_complete_fn_t txcmplt,
+ void *tx_context, rpc_rx_fn_t rxpkt,
+ void *rx_context, rpc_osl_t *rpc_osh);
+extern void bcm_rpc_tp_deregister_cb(rpc_tp_info_t *rpcb);
+
+/* Buffer manipulation */
+extern uint bcm_rpc_buf_tp_header_len(rpc_tp_info_t *rpcb);
+extern rpc_buf_t *bcm_rpc_tp_buf_alloc(rpc_tp_info_t *rpcb, int len);
+extern void bcm_rpc_tp_buf_free(rpc_tp_info_t *rpcb, rpc_buf_t *buf);
+extern int bcm_rpc_buf_len_get(rpc_tp_info_t *rpcb, rpc_buf_t *b);
+extern int bcm_rpc_buf_len_set(rpc_tp_info_t *rpcb, rpc_buf_t *b, uint len);
+extern rpc_buf_t *bcm_rpc_buf_next_get(rpc_tp_info_t *rpcb, rpc_buf_t *b);
+extern void bcm_rpc_buf_next_set(rpc_tp_info_t *rpcb, rpc_buf_t *b,
+ rpc_buf_t *nextb);
+extern unsigned char *bcm_rpc_buf_data(rpc_tp_info_t *rpcb, rpc_buf_t *b);
+extern unsigned char *bcm_rpc_buf_push(rpc_tp_info_t *rpcb, rpc_buf_t *b,
+ uint delta);
+extern unsigned char *bcm_rpc_buf_pull(rpc_tp_info_t *rpcb, rpc_buf_t *b,
+ uint delta);
+extern void bcm_rpc_tp_buf_release(rpc_tp_info_t *rpcb, rpc_buf_t *buf);
+extern void bcm_rpc_tp_buf_cnt_adjust(rpc_tp_info_t *rpcb, int adjust);
+/* RPC call_with_return */
+extern int bcm_rpc_tp_recv_rtn(rpc_tp_info_t *rpcb);
+extern int bcm_rpc_tp_get_device_speed(rpc_tp_info_t *rpc_th);
+#ifdef BCMDBG
+extern int bcm_rpc_tp_dump(rpc_tp_info_t *rpcb, struct bcmstrbuf *b);
+#endif
+
+#ifdef WLC_LOW
+/* intercept USB pkt to parse RPC header: USB driver rx-> wl_send -> this -> wl driver */
+extern void bcm_rpc_tp_rx_from_dnglbus(rpc_tp_info_t *rpc_th, struct lbuf *lb);
+
+/* RPC callreturn pkt, go to USB driver tx */
+extern int bcm_rpc_tp_send_callreturn(rpc_tp_info_t *rpc_th, rpc_buf_t *b);
+
+extern void bcm_rpc_tp_dump(rpc_tp_info_t *rpcb);
+extern void bcm_rpc_tp_txflowctl(rpc_tp_info_t *rpcb, bool state, int prio);
+extern void bcm_rpc_tp_txflowctlcb_init(rpc_tp_info_t *rpc_th, void *ctx,
+ rpc_txflowctl_cb_t cb);
+extern void bcm_rpc_tp_txflowctlcb_deinit(rpc_tp_info_t *rpc_th);
+extern void bcm_rpc_tp_txq_wm_set(rpc_tp_info_t *rpc_th, uint8 hiwm,
+ uint8 lowm);
+extern void bcm_rpc_tp_txq_wm_get(rpc_tp_info_t *rpc_th, uint8 *hiwm,
+ uint8 *lowm);
+#endif /* WLC_LOW */
+
+extern void bcm_rpc_tp_agg_set(rpc_tp_info_t *rpcb, uint32 reason, bool set);
+extern void bcm_rpc_tp_agg_limit_set(rpc_tp_info_t *rpc_th, uint8 sf,
+ uint16 bytes);
+extern void bcm_rpc_tp_agg_limit_get(rpc_tp_info_t *rpc_th, uint8 *sf,
+ uint16 *bytes);
+
+#define BCM_RPC_TP_MSG_LEVEL_MASK 0x00ff
+/* dongle msg level */
+#define RPC_TP_MSG_DNGL_ERR_VAL 0x0001 /* DNGL TP error msg */
+#define RPC_TP_MSG_DNGL_DBG_VAL 0x0002 /* DNGL TP dbg msg */
+#define RPC_TP_MSG_DNGL_AGG_VAL 0x0004 /* DNGL TP agg msg */
+#define RPC_TP_MSG_DNGL_DEA_VAL 0x0008 /* DNGL TP deag msg */
+
+/* host msg level */
+#define RPC_TP_MSG_HOST_ERR_VAL 0x0001 /* DNGL TP error msg */
+#define RPC_TP_MSG_HOST_DBG_VAL 0x0002 /* DNGL TP dbg msg */
+#define RPC_TP_MSG_HOST_AGG_VAL 0x0004 /* DNGL TP agg msg */
+#define RPC_TP_MSG_HOST_DEA_VAL 0x0008 /* DNGL TP deag msg */
+
+extern void bcm_rpc_tp_msglevel_set(rpc_tp_info_t *rpc_th, uint8 msglevel,
+ bool high_low);
+
+#endif /* _bcm_rpc_tp_h_ */
diff --git a/drivers/staging/brcm80211/include/bcm_xdr.h b/drivers/staging/brcm80211/include/bcm_xdr.h
new file mode 100644
index 000000000000..dd1ccc202a1d
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcm_xdr.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCM_XDR_H
+#define _BCM_XDR_H
+
+/*
+ * bcm_xdr_buf_t
+ * Structure used for bookkeeping of a buffer being packed or unpacked.
+ * Keeps a current read/write pointer and size as well as
+ * the original buffer pointer and size.
+ *
+ */
+typedef struct {
+ uint8 *buf; /* pointer to current position in origbuf */
+ uint size; /* current (residual) size in bytes */
+ uint8 *origbuf; /* unmodified pointer to orignal buffer */
+ uint origsize; /* unmodified orignal buffer size in bytes */
+} bcm_xdr_buf_t;
+
+void bcm_xdr_buf_init(bcm_xdr_buf_t *b, void *buf, size_t len);
+
+int bcm_xdr_pack_uint32(bcm_xdr_buf_t *b, uint32 val);
+int bcm_xdr_unpack_uint32(bcm_xdr_buf_t *b, uint32 *pval);
+int bcm_xdr_pack_int32(bcm_xdr_buf_t *b, int32 val);
+int bcm_xdr_unpack_int32(bcm_xdr_buf_t *b, int32 *pval);
+int bcm_xdr_pack_int8(bcm_xdr_buf_t *b, int8 val);
+int bcm_xdr_unpack_int8(bcm_xdr_buf_t *b, int8 *pval);
+int bcm_xdr_pack_opaque(bcm_xdr_buf_t *b, uint len, void *data);
+int bcm_xdr_unpack_opaque(bcm_xdr_buf_t *b, uint len, void **pdata);
+int bcm_xdr_unpack_opaque_cpy(bcm_xdr_buf_t *b, uint len, void *data);
+int bcm_xdr_pack_opaque_varlen(bcm_xdr_buf_t *b, uint len, void *data);
+int bcm_xdr_unpack_opaque_varlen(bcm_xdr_buf_t *b, uint *plen, void **pdata);
+int bcm_xdr_pack_string(bcm_xdr_buf_t *b, char *str);
+int bcm_xdr_unpack_string(bcm_xdr_buf_t *b, uint *plen, char **pstr);
+
+int bcm_xdr_pack_uint8_vec(bcm_xdr_buf_t *, uint8 *vec, uint32 elems);
+int bcm_xdr_unpack_uint8_vec(bcm_xdr_buf_t *, uint8 *vec, uint32 elems);
+int bcm_xdr_pack_uint16_vec(bcm_xdr_buf_t *b, uint len, void *vec);
+int bcm_xdr_unpack_uint16_vec(bcm_xdr_buf_t *b, uint len, void *vec);
+int bcm_xdr_pack_uint32_vec(bcm_xdr_buf_t *b, uint len, void *vec);
+int bcm_xdr_unpack_uint32_vec(bcm_xdr_buf_t *b, uint len, void *vec);
+
+int bcm_xdr_pack_opaque_raw(bcm_xdr_buf_t *b, uint len, void *data);
+int bcm_xdr_pack_opaque_pad(bcm_xdr_buf_t *b);
+
+#endif /* _BCM_XDR_H */
diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h
new file mode 100644
index 000000000000..caa96b1823a1
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmdefs.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmdefs_h_
+#define _bcmdefs_h_
+
+/*
+ * One doesn't need to include this file explicitly, gets included automatically if
+ * typedefs.h is included.
+ */
+
+/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function
+ * arguments or local variables.
+ */
+#define BCM_REFERENCE(data) ((void)data)
+
+/* Reclaiming text and data :
+ * The following macros specify special linker sections that can be reclaimed
+ * after a system is considered 'up'.
+ * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN,
+ * as in most cases, the attach function calls the detach function to clean up on error).
+ */
+
+#define bcmreclaimed 0
+#define BCMATTACHDATA(_data) _data
+#define BCMATTACHFN(_fn) _fn
+#define BCMPREATTACHDATA(_data) _data
+#define BCMPREATTACHFN(_fn) _fn
+#define BCMINITDATA(_data) _data
+#define BCMINITFN(_fn) _fn
+#define BCMUNINITFN(_fn) _fn
+#define BCMNMIATTACHFN(_fn) _fn
+#define BCMNMIATTACHDATA(_data) _data
+#define BCMOVERLAY0DATA(_sym) _sym
+#define BCMOVERLAY0FN(_fn) _fn
+#define BCMOVERLAY1DATA(_sym) _sym
+#define BCMOVERLAY1FN(_fn) _fn
+#define BCMOVERLAYERRFN(_fn) _fn
+#define CONST const
+#ifdef mips
+#define BCMFASTPATH __attribute__ ((__section__(".text.fastpath")))
+#else
+#define BCMFASTPATH
+#endif
+
+/* Put some library data/code into ROM to reduce RAM requirements */
+#define BCMROMDATA(_data) _data
+#define BCMROMDAT_NAME(_data) _data
+#define BCMROMFN(_fn) _fn
+#define BCMROMFN_NAME(_fn) _fn
+#define STATIC static
+#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data)
+#define BCMROMDAT_SIZEOF(data) sizeof(data)
+#define BCMROMDAT_APATCH(data)
+#define BCMROMDAT_SPATCH(data)
+
+/* Bus types */
+#define SI_BUS 0 /* SOC Interconnect */
+#define PCI_BUS 1 /* PCI target */
+#define SDIO_BUS 3 /* SDIO target */
+#define JTAG_BUS 4 /* JTAG */
+#define USB_BUS 5 /* USB (does not support R/W REG) */
+#define SPI_BUS 6 /* gSPI target */
+#define RPC_BUS 7 /* RPC target */
+
+/* Allows size optimization for single-bus image */
+#ifdef BCMBUSTYPE
+#define BUSTYPE(bus) (BCMBUSTYPE)
+#else
+#define BUSTYPE(bus) (bus)
+#endif
+
+/* Allows size optimization for single-backplane image */
+#ifdef BCMCHIPTYPE
+#define CHIPTYPE(bus) (BCMCHIPTYPE)
+#else
+#define CHIPTYPE(bus) (bus)
+#endif
+
+/* Allows size optimization for SPROM support */
+#define SPROMBUS (PCI_BUS)
+
+/* Allows size optimization for single-chip image */
+#ifdef BCMCHIPID
+#define CHIPID(chip) (BCMCHIPID)
+#else
+#define CHIPID(chip) (chip)
+#endif
+
+#ifdef BCMCHIPREV
+#define CHIPREV(rev) (BCMCHIPREV)
+#else
+#define CHIPREV(rev) (rev)
+#endif
+
+/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
+#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
+#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
+#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
+
+#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
+#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
+#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
+#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
+
+#ifdef BCMDMA64OSL
+typedef struct {
+ uint32 loaddr;
+ uint32 hiaddr;
+} dma64addr_t;
+
+typedef dma64addr_t dmaaddr_t;
+#define PHYSADDRHI(_pa) ((_pa).hiaddr)
+#define PHYSADDRHISET(_pa, _val) \
+ do { \
+ (_pa).hiaddr = (_val); \
+ } while (0)
+#define PHYSADDRLO(_pa) ((_pa).loaddr)
+#define PHYSADDRLOSET(_pa, _val) \
+ do { \
+ (_pa).loaddr = (_val); \
+ } while (0)
+
+#else
+typedef unsigned long dmaaddr_t;
+#define PHYSADDRHI(_pa) (0)
+#define PHYSADDRHISET(_pa, _val)
+#define PHYSADDRLO(_pa) ((_pa))
+#define PHYSADDRLOSET(_pa, _val) \
+ do { \
+ (_pa) = (_val); \
+ } while (0)
+#endif /* BCMDMA64OSL */
+
+/* One physical DMA segment */
+typedef struct {
+ dmaaddr_t addr;
+ uint32 length;
+} hnddma_seg_t;
+
+#define MAX_DMA_SEGS 4
+
+typedef struct {
+ void *oshdmah; /* Opaque handle for OSL to store its information */
+ uint origsize; /* Size of the virtual packet */
+ uint nsegs;
+ hnddma_seg_t segs[MAX_DMA_SEGS];
+} hnddma_seg_map_t;
+
+/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
+ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
+ * There is a compile time check in wlc.c which ensure that this value is at least as big
+ * as TXOFF. This value is used in dma_rxfill (hnddma.c).
+ */
+
+#define BCMEXTRAHDROOM 172
+
+/* Headroom required for dongle-to-host communication. Packets allocated
+ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
+ * leave this much room in front for low-level message headers which may
+ * be needed to get across the dongle bus to the host. (These messages
+ * don't go over the network, so room for the full WL header above would
+ * be a waste.).
+*/
+#define BCMDONGLEHDRSZ 12
+#define BCMDONGLEPADSZ 16
+
+#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
+
+#ifdef BCMDBG
+
+#define BCMDBG_ERR
+
+#ifndef BCMDBG_ASSERT
+#define BCMDBG_ASSERT
+#endif /* BCMDBG_ASSERT */
+
+#endif /* BCMDBG */
+
+#if defined(BCMDBG_ASSERT)
+#define BCMASSERT_SUPPORT
+#endif
+
+/* Macros for doing definition and get/set of bitfields
+ * Usage example, e.g. a three-bit field (bits 4-6):
+ * #define <NAME>_M BITFIELD_MASK(3)
+ * #define <NAME>_S 4
+ * ...
+ * regval = R_REG(osh, &regs->regfoo);
+ * field = GFIELD(regval, <NAME>);
+ * regval = SFIELD(regval, <NAME>, 1);
+ * W_REG(osh, &regs->regfoo, regval);
+ */
+#define BITFIELD_MASK(width) \
+ (((unsigned)1 << (width)) - 1)
+#define GFIELD(val, field) \
+ (((val) >> field ## _S) & field ## _M)
+#define SFIELD(val, field, bits) \
+ (((val) & (~(field ## _M << field ## _S))) | \
+ ((unsigned)(bits) << field ## _S))
+
+/* define BCMSMALL to remove misc features for memory-constrained environments */
+#define BCMSPACE
+#define bcmspace TRUE /* if (bcmspace) code is retained */
+
+/* Max. nvram variable table size */
+#define MAXSZ_NVRAM_VARS 4096
+
+#define LOCATOR_EXTERN static
+
+#endif /* _bcmdefs_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h
new file mode 100644
index 000000000000..7d3a97a3fec1
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmdevs.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCMDEVS_H
+#define _BCMDEVS_H
+
+/* PCI vendor IDs */
+#define VENDOR_BROADCOM 0x14e4
+
+/* DONGLE VID/PIDs */
+#define BCM_DNGL_VID 0x0a5c
+#define BCM_DNGL_BDC_PID 0x0bdc
+
+#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */
+#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
+#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
+
+#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
+#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
+#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
+
+#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
+#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
+
+#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
+#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
+#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */
+
+#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */
+#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
+#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */
+#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */
+#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */
+#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */
+#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */
+#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
+#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */
+#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */
+
+/* Chip IDs */
+#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
+#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
+
+#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
+#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
+#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */
+#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */
+#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
+#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
+#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
+#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
+#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
+#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
+#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
+#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
+
+/* these are router chips */
+#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
+#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
+#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
+#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */
+#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */
+
+/* Package IDs */
+#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
+#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
+#define BCM4716_PKG_ID 8 /* 4716 package id */
+#define BCM4717_PKG_ID 9 /* 4717 package id */
+#define BCM4718_PKG_ID 10 /* 4718 package id */
+#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */
+#define BCM5358U_PKG_ID 8 /* 5358U package id */
+#define BCM5358_PKG_ID 9 /* 5358 package id */
+#define BCM47186_PKG_ID 10 /* 47186 package id */
+#define BCM5357_PKG_ID 11 /* 5357 package id */
+#define BCM5356U_PKG_ID 12 /* 5356U package id */
+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
+#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */
+#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
+#define BCM4336_WLBGA_PKG_ID 0x8
+
+/* boardflags */
+#define BFL_RESERVED1 0x00000001
+#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */
+#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication */
+#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */
+#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */
+#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
+#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */
+#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */
+#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */
+#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
+#define BFL_FEM 0x00000800 /* Board supports the Front End Module */
+#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
+#define BFL_HGPA 0x00002000 /* Board has a high gain PA */
+#define BFL_RESERVED2 0x00004000
+#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */
+#define BFL_NOPA 0x00010000 /* Board has no PA */
+#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */
+#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */
+#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */
+#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */
+#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */
+#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */
+#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */
+#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */
+#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */
+#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */
+#define BFL_FASTPWR 0x08000000
+#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */
+#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
+#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */
+#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */
+#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field
+ * when this flag is set
+ */
+
+/* boardflags2 */
+#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */
+#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
+#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */
+#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */
+#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */
+#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */
+#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */
+#define BFL2_LEGACY 0x00000080
+#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */
+#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */
+#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */
+#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */
+#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
+#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */
+#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */
+#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* using 40Mhz LPF for 20Mhz bandedge channels */
+#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */
+#define BFL2_IPALVLSHIFT_3P3 0x00020000
+#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */
+#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON"
+ * Most drivers will turn it off without this flag
+ * to save power.
+ */
+
+/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
+#define BOARD_GPIO_RESERVED1 0x010
+#define BOARD_GPIO_RESERVED2 0x020
+#define BOARD_GPIO_RESERVED3 0x080
+#define BOARD_GPIO_RESERVED4 0x100
+#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
+#define BOARD_GPIO_12 0x1000 /* gpio 12 */
+#define BOARD_GPIO_13 0x2000 /* gpio 13 */
+#define BOARD_GPIO_RESERVED5 0x0800
+#define BOARD_GPIO_RESERVED6 0x2000
+#define BOARD_GPIO_RESERVED7 0x4000
+#define BOARD_GPIO_RESERVED8 0x8000
+
+#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
+#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
+#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */
+#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */
+
+/* power control defines */
+#define PLL_DELAY 150 /* us pll on delay */
+#define FREF_DELAY 200 /* us fref change delay */
+#define MIN_SLOW_CLK 32 /* us Slow clock period */
+#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
+
+/* # of GPIO pins */
+#define GPIO_NUMPINS 16
+
+/* Reference board types */
+#define SPI_BOARD 0x0402
+
+#endif /* _BCMDEVS_H */
diff --git a/drivers/staging/brcm80211/include/bcmendian.h b/drivers/staging/brcm80211/include/bcmendian.h
new file mode 100644
index 000000000000..fe4313b13029
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmendian.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCMENDIAN_H_
+#define _BCMENDIAN_H_
+
+#include <typedefs.h>
+
+/* Reverse the bytes in a 16-bit value */
+#define BCMSWAP16(val) \
+ ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \
+ (((uint16)(val) & (uint16)0xff00U) >> 8)))
+
+/* Reverse the bytes in a 32-bit value */
+#define BCMSWAP32(val) \
+ ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \
+ (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \
+ (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \
+ (((uint32)(val) & (uint32)0xff000000U) >> 24)))
+
+/* Reverse the two 16-bit halves of a 32-bit value */
+#define BCMSWAP32BY16(val) \
+ ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \
+ (((uint32)(val) & (uint32)0xffff0000U) >> 16)))
+
+/* Byte swapping macros
+ * Host <=> Network (Big Endian) for 16- and 32-bit values
+ * Host <=> Little-Endian for 16- and 32-bit values
+ */
+#ifndef hton16
+#ifndef IL_BIGENDIAN
+#define HTON16(i) BCMSWAP16(i)
+#define hton16(i) bcmswap16(i)
+#define HTON32(i) BCMSWAP32(i)
+#define hton32(i) bcmswap32(i)
+#define NTOH16(i) BCMSWAP16(i)
+#define ntoh16(i) bcmswap16(i)
+#define NTOH32(i) BCMSWAP32(i)
+#define ntoh32(i) bcmswap32(i)
+#define LTOH16(i) (i)
+#define ltoh16(i) (i)
+#define LTOH32(i) (i)
+#define ltoh32(i) (i)
+#define HTOL16(i) (i)
+#define htol16(i) (i)
+#define HTOL32(i) (i)
+#define htol32(i) (i)
+#else /* IL_BIGENDIAN */
+#define HTON16(i) (i)
+#define hton16(i) (i)
+#define HTON32(i) (i)
+#define hton32(i) (i)
+#define NTOH16(i) (i)
+#define ntoh16(i) (i)
+#define NTOH32(i) (i)
+#define ntoh32(i) (i)
+#define LTOH16(i) BCMSWAP16(i)
+#define ltoh16(i) bcmswap16(i)
+#define LTOH32(i) BCMSWAP32(i)
+#define ltoh32(i) bcmswap32(i)
+#define HTOL16(i) BCMSWAP16(i)
+#define htol16(i) bcmswap16(i)
+#define HTOL32(i) BCMSWAP32(i)
+#define htol32(i) bcmswap32(i)
+#endif /* IL_BIGENDIAN */
+#endif /* hton16 */
+
+#ifndef IL_BIGENDIAN
+#define ltoh16_buf(buf, i)
+#define htol16_buf(buf, i)
+#else
+#define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i))
+#define htol16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i))
+#endif /* IL_BIGENDIAN */
+
+/* Unaligned loads and stores in host byte order */
+#ifndef IL_BIGENDIAN
+#define load32_ua(a) ltoh32_ua(a)
+#define store32_ua(a, v) htol32_ua_store(v, a)
+#define load16_ua(a) ltoh16_ua(a)
+#define store16_ua(a, v) htol16_ua_store(v, a)
+#else
+#define load32_ua(a) ntoh32_ua(a)
+#define store32_ua(a, v) hton32_ua_store(v, a)
+#define load16_ua(a) ntoh16_ua(a)
+#define store16_ua(a, v) hton16_ua_store(v, a)
+#endif /* IL_BIGENDIAN */
+
+#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8))
+#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
+#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1])
+#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
+
+#define ltoh_ua(ptr) \
+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
+ sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \
+ sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \
+ *(uint8 *)0)
+
+#define ntoh_ua(ptr) \
+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
+ sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \
+ sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \
+ *(uint8 *)0)
+
+#ifdef __GNUC__
+
+/* GNU macro versions avoid referencing the argument multiple times, while also
+ * avoiding the -fno-inline used in ROM builds.
+ */
+
+#define bcmswap16(val) ({ \
+ uint16 _val = (val); \
+ BCMSWAP16(_val); \
+})
+
+#define bcmswap32(val) ({ \
+ uint32 _val = (val); \
+ BCMSWAP32(_val); \
+})
+
+#define bcmswap32by16(val) ({ \
+ uint32 _val = (val); \
+ BCMSWAP32BY16(_val); \
+})
+
+#define bcmswap16_buf(buf, len) ({ \
+ uint16 *_buf = (uint16 *)(buf); \
+ uint _wds = (len) / 2; \
+ while (_wds--) { \
+ *_buf = bcmswap16(*_buf); \
+ _buf++; \
+ } \
+})
+
+#define htol16_ua_store(val, bytes) ({ \
+ uint16 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val & 0xff; \
+ _bytes[1] = _val >> 8; \
+})
+
+#define htol32_ua_store(val, bytes) ({ \
+ uint32 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val & 0xff; \
+ _bytes[1] = (_val >> 8) & 0xff; \
+ _bytes[2] = (_val >> 16) & 0xff; \
+ _bytes[3] = _val >> 24; \
+})
+
+#define hton16_ua_store(val, bytes) ({ \
+ uint16 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val >> 8; \
+ _bytes[1] = _val & 0xff; \
+})
+
+#define hton32_ua_store(val, bytes) ({ \
+ uint32 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val >> 24; \
+ _bytes[1] = (_val >> 16) & 0xff; \
+ _bytes[2] = (_val >> 8) & 0xff; \
+ _bytes[3] = _val & 0xff; \
+})
+
+#define ltoh16_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _LTOH16_UA(_bytes); \
+})
+
+#define ltoh32_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _LTOH32_UA(_bytes); \
+})
+
+#define ntoh16_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _NTOH16_UA(_bytes); \
+})
+
+#define ntoh32_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _NTOH32_UA(_bytes); \
+})
+
+#else /* !__GNUC__ */
+
+/* Inline versions avoid referencing the argument multiple times */
+static INLINE uint16 bcmswap16(uint16 val)
+{
+ return BCMSWAP16(val);
+}
+
+static INLINE uint32 bcmswap32(uint32 val)
+{
+ return BCMSWAP32(val);
+}
+
+static INLINE uint32 bcmswap32by16(uint32 val)
+{
+ return BCMSWAP32BY16(val);
+}
+
+/* Reverse pairs of bytes in a buffer (not for high-performance use) */
+/* buf - start of buffer of shorts to swap */
+/* len - byte length of buffer */
+static INLINE void bcmswap16_buf(uint16 *buf, uint len)
+{
+ len = len / 2;
+
+ while (len--) {
+ *buf = bcmswap16(*buf);
+ buf++;
+ }
+}
+
+/*
+ * Store 16-bit value to unaligned little-endian byte array.
+ */
+static INLINE void htol16_ua_store(uint16 val, uint8 *bytes)
+{
+ bytes[0] = val & 0xff;
+ bytes[1] = val >> 8;
+}
+
+/*
+ * Store 32-bit value to unaligned little-endian byte array.
+ */
+static INLINE void htol32_ua_store(uint32 val, uint8 *bytes)
+{
+ bytes[0] = val & 0xff;
+ bytes[1] = (val >> 8) & 0xff;
+ bytes[2] = (val >> 16) & 0xff;
+ bytes[3] = val >> 24;
+}
+
+/*
+ * Store 16-bit value to unaligned network-(big-)endian byte array.
+ */
+static INLINE void hton16_ua_store(uint16 val, uint8 *bytes)
+{
+ bytes[0] = val >> 8;
+ bytes[1] = val & 0xff;
+}
+
+/*
+ * Store 32-bit value to unaligned network-(big-)endian byte array.
+ */
+static INLINE void hton32_ua_store(uint32 val, uint8 *bytes)
+{
+ bytes[0] = val >> 24;
+ bytes[1] = (val >> 16) & 0xff;
+ bytes[2] = (val >> 8) & 0xff;
+ bytes[3] = val & 0xff;
+}
+
+/*
+ * Load 16-bit value from unaligned little-endian byte array.
+ */
+static INLINE uint16 ltoh16_ua(const void *bytes)
+{
+ return _LTOH16_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 32-bit value from unaligned little-endian byte array.
+ */
+static INLINE uint32 ltoh32_ua(const void *bytes)
+{
+ return _LTOH32_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 16-bit value from unaligned big-(network-)endian byte array.
+ */
+static INLINE uint16 ntoh16_ua(const void *bytes)
+{
+ return _NTOH16_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 32-bit value from unaligned big-(network-)endian byte array.
+ */
+static INLINE uint32 ntoh32_ua(const void *bytes)
+{
+ return _NTOH32_UA((const uint8 *)bytes);
+}
+
+#endif /* !__GNUC__ */
+#endif /* !_BCMENDIAN_H_ */
diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h
new file mode 100644
index 000000000000..53a146378b86
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmnvram.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmnvram_h_
+#define _bcmnvram_h_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+
+struct nvram_header {
+ uint32 magic;
+ uint32 len;
+ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
+ uint32 config_ncdl; /* ncdl values for memc */
+};
+
+struct nvram_tuple {
+ char *name;
+ char *value;
+ struct nvram_tuple *next;
+};
+
+/*
+ * Get default value for an NVRAM variable
+ */
+extern char *nvram_default_get(const char *name);
+
+/*
+ * Initialize NVRAM access. May be unnecessary or undefined on certain
+ * platforms.
+ */
+extern int nvram_init(void *sih);
+
+/*
+ * Append a chunk of nvram variables to the global list
+ */
+extern int nvram_append(void *si, char *vars, uint varsz);
+
+/*
+ * Check for reset button press for restoring factory defaults.
+ */
+extern int nvram_reset(void *sih);
+
+/*
+ * Disable NVRAM access. May be unnecessary or undefined on certain
+ * platforms.
+ */
+extern void nvram_exit(void *sih);
+
+/*
+ * Get the value of an NVRAM variable. The pointer returned may be
+ * invalid after a set.
+ * @param name name of variable to get
+ * @return value of variable or NULL if undefined
+ */
+extern char *nvram_get(const char *name);
+
+/*
+ * Read the reset GPIO value from the nvram and set the GPIO
+ * as input
+ */
+extern int BCMINITFN(nvram_resetgpio_init) (void *sih);
+
+/*
+ * Get the value of an NVRAM variable.
+ * @param name name of variable to get
+ * @return value of variable or NUL if undefined
+ */
+#define nvram_safe_get(name) (nvram_get(name) ? : "")
+
+/*
+ * Match an NVRAM variable.
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is string equal
+ * to match or FALSE otherwise
+ */
+static INLINE int nvram_match(char *name, char *match)
+{
+ const char *value = nvram_get(name);
+ return value && !strcmp(value, match);
+}
+
+/*
+ * Inversely match an NVRAM variable.
+ * @param name name of variable to match
+ * @param match value to compare against value of variable
+ * @return TRUE if variable is defined and its value is not string
+ * equal to invmatch or FALSE otherwise
+ */
+static INLINE int nvram_invmatch(char *name, char *invmatch)
+{
+ const char *value = nvram_get(name);
+ return value && strcmp(value, invmatch);
+}
+
+/*
+ * Set the value of an NVRAM variable. The name and value strings are
+ * copied into private storage. Pointers to previously set values
+ * may become invalid. The new value may be immediately
+ * retrieved but will not be permanently stored until a commit.
+ * @param name name of variable to set
+ * @param value value of variable
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_set(const char *name, const char *value);
+
+/*
+ * Unset an NVRAM variable. Pointers to previously set values
+ * remain valid until a set.
+ * @param name name of variable to unset
+ * @return 0 on success and errno on failure
+ * NOTE: use nvram_commit to commit this change to flash.
+ */
+extern int nvram_unset(const char *name);
+
+/*
+ * Commit NVRAM variables to permanent storage. All pointers to values
+ * may be invalid after a commit.
+ * NVRAM values are undefined after a commit.
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_commit(void);
+
+/*
+ * Get all NVRAM variables (format name=value\0 ... \0\0).
+ * @param buf buffer to store variables
+ * @param count size of buffer in bytes
+ * @return 0 on success and errno on failure
+ */
+extern int nvram_getall(char *nvram_buf, int count);
+
+/*
+ * returns the crc value of the nvram
+ * @param nvh nvram header pointer
+ */
+uint8 nvram_calc_crc(struct nvram_header *nvh);
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* The NVRAM version number stored as an NVRAM variable */
+#define NVRAM_SOFTWARE_VERSION "1"
+
+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
+#define NVRAM_CLEAR_MAGIC 0x0
+#define NVRAM_INVALID_MAGIC 0xFFFFFFFF
+#define NVRAM_VERSION 1
+#define NVRAM_HEADER_SIZE 20
+#define NVRAM_SPACE 0x8000
+
+#define NVRAM_MAX_VALUE_LEN 255
+#define NVRAM_MAX_PARAM_LEN 64
+
+#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */
+#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */
+
+#endif /* _bcmnvram_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmotp.h b/drivers/staging/brcm80211/include/bcmotp.h
new file mode 100644
index 000000000000..e011261fdff4
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmotp.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmotp_h_
+#define _bcmotp_h_
+
+/* OTP regions */
+#define OTP_HW_RGN 1
+#define OTP_SW_RGN 2
+#define OTP_CI_RGN 4
+#define OTP_FUSE_RGN 8
+#define OTP_ALL_RGN 0xf /* From h/w region to end of OTP including checksum */
+
+/* OTP Size */
+#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
+
+/* Fixed size subregions sizes in words */
+#define OTPGU_CI_SZ 2
+
+/* OTP usage */
+#define OTP4325_FM_DISABLED_OFFSET 188
+
+/* Exported functions */
+extern int otp_status(void *oh);
+extern int otp_size(void *oh);
+extern uint16 otp_read_bit(void *oh, uint offset);
+extern void *otp_init(si_t *sih);
+extern int otp_read_region(si_t *sih, int region, uint16 *data, uint *wlen);
+extern int otp_nvread(void *oh, char *data, uint *len);
+
+#endif /* _bcmotp_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsdbus.h b/drivers/staging/brcm80211/include/bcmsdbus.h
new file mode 100644
index 000000000000..dbb33ef7311b
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsdbus.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _sdio_api_h_
+#define _sdio_api_h_
+
+#define SDIOH_API_RC_SUCCESS (0x00)
+#define SDIOH_API_RC_FAIL (0x01)
+#define SDIOH_API_SUCCESS(status) (status == 0)
+
+#define SDIOH_READ 0 /* Read request */
+#define SDIOH_WRITE 1 /* Write request */
+
+#define SDIOH_DATA_FIX 0 /* Fixed addressing */
+#define SDIOH_DATA_INC 1 /* Incremental addressing */
+
+#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
+#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
+#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
+
+#define SDIOH_DATA_PIO 0 /* PIO mode */
+#define SDIOH_DATA_DMA 1 /* DMA mode */
+
+typedef int SDIOH_API_RC;
+
+/* SDio Host structure */
+typedef struct sdioh_info sdioh_info_t;
+
+/* callback function, taking one arg */
+typedef void (*sdioh_cb_fn_t) (void *);
+
+/* attach, return handler on success, NULL if failed.
+ * The handler shall be provided by all subsequent calls. No local cache
+ * cfghdl points to the starting address of pci device mapped memory
+ */
+extern sdioh_info_t *sdioh_attach(osl_t *osh, void *cfghdl, uint irq);
+extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si);
+extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si,
+ sdioh_cb_fn_t fn, void *argh);
+extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si);
+
+/* query whether SD interrupt is enabled or not */
+extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff);
+
+/* enable or disable SD interrupt */
+extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable);
+
+#if defined(BCMDBG)
+extern bool sdioh_interrupt_pending(sdioh_info_t *si);
+#endif
+
+extern int sdioh_claim_host_and_lock(sdioh_info_t *si);
+extern int sdioh_release_host_and_unlock(sdioh_info_t *si);
+
+/* read or write one byte using cmd52 */
+extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc,
+ uint addr, uint8 *byte);
+
+/* read or write 2/4 bytes using cmd53 */
+extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type,
+ uint rw, uint fnc, uint addr,
+ uint32 *word, uint nbyte);
+
+/* read or write any buffer using cmd53 */
+extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma,
+ uint fix_inc, uint rw, uint fnc_num,
+ uint32 addr, uint regwidth,
+ uint32 buflen, uint8 *buffer,
+ void *pkt);
+
+/* get cis data */
+extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis,
+ uint32 length);
+
+extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr,
+ uint8 *data);
+extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr,
+ uint8 *data);
+
+/* query number of io functions */
+extern uint sdioh_query_iofnum(sdioh_info_t *si);
+
+/* handle iovars */
+extern int sdioh_iovar_op(sdioh_info_t *si, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+
+/* Issue abort to the specified function and clear controller as needed */
+extern int sdioh_abort(sdioh_info_t *si, uint fnc);
+
+/* Start and Stop SDIO without re-enumerating the SD card. */
+extern int sdioh_start(sdioh_info_t *si, int stage);
+extern int sdioh_stop(sdioh_info_t *si);
+
+/* Reset and re-initialize the device */
+extern int sdioh_sdio_reset(sdioh_info_t *si);
+
+/* Helper function */
+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+
+#endif /* _sdio_api_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h
new file mode 100644
index 000000000000..77a984af2a90
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsdh.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmsdh_h_
+#define _bcmsdh_h_
+
+#define BCMSDH_ERROR_VAL 0x0001 /* Error */
+#define BCMSDH_INFO_VAL 0x0002 /* Info */
+extern const uint bcmsdh_msglevel;
+
+#ifdef BCMDBG
+#define BCMSDH_ERROR(x) do { if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0)
+#define BCMSDH_INFO(x) do { if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) printf x; } while (0)
+#else /* BCMDBG */
+#define BCMSDH_ERROR(x)
+#define BCMSDH_INFO(x)
+#endif /* BCMDBG */
+
+/* forward declarations */
+typedef struct bcmsdh_info bcmsdh_info_t;
+typedef void (*bcmsdh_cb_fn_t) (void *);
+
+/* Attach and build an interface to the underlying SD host driver.
+ * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh.
+ * - Returns the bcmsdh handle and virtual address base for register access.
+ * The returned handle should be used in all subsequent calls, but the bcmsh
+ * implementation may maintain a single "default" handle (e.g. the first or
+ * most recent one) to enable single-instance implementations to pass NULL.
+ */
+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva,
+ uint irq);
+
+/* Detach - freeup resources allocated in attach */
+extern int bcmsdh_detach(osl_t *osh, void *sdh);
+
+/* Query if SD device interrupts are enabled */
+extern bool bcmsdh_intr_query(void *sdh);
+
+/* Enable/disable SD interrupt */
+extern int bcmsdh_intr_enable(void *sdh);
+extern int bcmsdh_intr_disable(void *sdh);
+
+/* Register/deregister device interrupt handler. */
+extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+extern int bcmsdh_intr_dereg(void *sdh);
+
+#if defined(BCMDBG)
+/* Query pending interrupt status from the host controller */
+extern bool bcmsdh_intr_pending(void *sdh);
+#endif
+extern int bcmsdh_claim_host_and_lock(void *sdh);
+extern int bcmsdh_release_host_and_unlock(void *sdh);
+
+/* Register a callback to be called if and when bcmsdh detects
+ * device removal. No-op in the case of non-removable/hardwired devices.
+ */
+extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+
+/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
+ * fn: function number
+ * addr: unmodified SDIO-space address
+ * data: data byte to write
+ * err: pointer to error code (or NULL)
+ */
+extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err);
+extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data,
+ int *err);
+
+/* Read/Write 4bytes from/to cfg space */
+extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr,
+ int *err);
+extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr,
+ uint32 data, int *err);
+
+/* Read CIS content for specified function.
+ * fn: function whose CIS is being requested (0 is common CIS)
+ * cis: pointer to memory location to place results
+ * length: number of bytes to read
+ * Internally, this routine uses the values from the cis base regs (0x9-0xB)
+ * to form an SDIO-space address to read the data from.
+ */
+extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length);
+
+/* Synchronous access to device (client) core registers via CMD53 to F1.
+ * addr: backplane address (i.e. >= regsva from attach)
+ * size: register width in bytes (2 or 4)
+ * data: data for register write
+ */
+extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size);
+extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data);
+
+/* Indicate if last reg read/write failed */
+extern bool bcmsdh_regfail(void *sdh);
+
+/* Buffer transfer to/from device (client) core via cmd53.
+ * fn: function number
+ * addr: backplane address (i.e. >= regsva from attach)
+ * flags: backplane width, address increment, sync/async
+ * buf: pointer to memory data buffer
+ * nbytes: number of bytes to transfer to/from buf
+ * pkt: pointer to packet associated with buf (if any)
+ * complete: callback function for command completion (async only)
+ * handle: handle for completion callback (first arg in callback)
+ * Returns 0 or error code.
+ * NOTE: Async operation is not currently supported.
+ */
+typedef void (*bcmsdh_cmplt_fn_t) (void *handle, int status, bool sync_waiting);
+extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete, void *handle);
+extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete, void *handle);
+
+/* Flags bits */
+#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */
+#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */
+#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */
+
+/* Pending (non-error) return code */
+#define BCME_PENDING 1
+
+/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
+ * rw: read or write (0/1)
+ * addr: direct SDIO address
+ * buf: pointer to memory data buffer
+ * nbytes: number of bytes to transfer to/from buf
+ * Returns 0 or error code.
+ */
+extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf,
+ uint nbytes);
+
+/* Issue an abort to the specified function */
+extern int bcmsdh_abort(void *sdh, uint fn);
+
+/* Start SDIO Host Controller communication */
+extern int bcmsdh_start(void *sdh, int stage);
+
+/* Stop SDIO Host Controller communication */
+extern int bcmsdh_stop(void *sdh);
+
+/* Returns the "Device ID" of target device on the SDIO bus. */
+extern int bcmsdh_query_device(void *sdh);
+
+/* Returns the number of IO functions reported by the device */
+extern uint bcmsdh_query_iofnum(void *sdh);
+
+/* Miscellaneous knob tweaker. */
+extern int bcmsdh_iovar_op(void *sdh, const char *name,
+ void *params, int plen, void *arg, int len,
+ bool set);
+
+/* Reset and reinitialize the device */
+extern int bcmsdh_reset(bcmsdh_info_t *sdh);
+
+/* helper functions */
+
+extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+
+/* callback functions */
+typedef struct {
+ /* attach to device */
+ void *(*attach) (uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot,
+ uint16 func, uint bustype, void *regsva, osl_t *osh,
+ void *param);
+ /* detach from device */
+ void (*detach) (void *ch);
+} bcmsdh_driver_t;
+
+/* platform specific/high level functions */
+extern int bcmsdh_register(bcmsdh_driver_t *driver);
+extern void bcmsdh_unregister(void);
+extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device);
+extern void bcmsdh_device_remove(void *sdh);
+
+/* Function to pass device-status bits to DHD. */
+extern uint32 bcmsdh_get_dstatus(void *sdh);
+
+/* Function to return current window addr */
+extern uint32 bcmsdh_cur_sbwad(void *sdh);
+
+/* Function to pass chipid and rev to lower layers for controlling pr's */
+extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev);
+
+#endif /* _bcmsdh_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h
new file mode 100644
index 000000000000..e32c909d8b47
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 __BCMSDH_SDMMC_H__
+#define __BCMSDH_SDMMC_H__
+
+#ifdef BCMDBG
+#define sd_err(x) do { if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0)
+#define sd_trace(x) do { if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) printf x; } while (0)
+#define sd_info(x) do { if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) printf x; } while (0)
+#define sd_debug(x) do { if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) printf x; } while (0)
+#define sd_data(x) do { if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) printf x; } while (0)
+#define sd_ctrl(x) do { if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) printf x; } while (0)
+#else
+#define sd_err(x)
+#define sd_trace(x)
+#define sd_info(x)
+#define sd_debug(x)
+#define sd_data(x)
+#define sd_ctrl(x)
+#endif
+
+/* Allocate/init/free per-OS private data */
+extern int sdioh_sdmmc_osinit(sdioh_info_t *sd);
+extern void sdioh_sdmmc_osfree(sdioh_info_t *sd);
+
+#define BLOCK_SIZE_64 64
+#define BLOCK_SIZE_512 512
+
+/* internal return code */
+#define SUCCESS 0
+#define ERROR 1
+
+/* private bus modes */
+#define SDIOH_MODE_SD4 2
+#define CLIENT_INTR 0x100 /* Get rid of this! */
+
+struct sdioh_info {
+ osl_t *osh; /* osh handler */
+ bool client_intr_enabled; /* interrupt connnected flag */
+ bool intr_handler_valid; /* client driver interrupt handler valid */
+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
+ void *intr_handler_arg; /* argument to call interrupt handler */
+ uint16 intmask; /* Current active interrupts */
+ void *sdos_info; /* Pointer to per-OS private data */
+
+ uint irq; /* Client irq */
+ int intrcount; /* Client interrupts */
+ bool sd_use_dma; /* DMA on CMD53 */
+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
+ /* Must be on for sd_multiblock to be effective */
+ bool use_client_ints; /* If this is false, make sure to restore */
+ int sd_mode; /* SD1/SD4/SPI */
+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
+ uint8 num_funcs; /* Supported funcs on client */
+ uint32 com_cis_ptr;
+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+ uint max_dma_len;
+ uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */
+ /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */
+};
+
+/************************************************************
+ * Internal interfaces: per-port references into bcmsdh_sdmmc.c
+ */
+
+/* Global message bits */
+extern uint sd_msglevel;
+
+/* OS-independent interrupt handler */
+extern bool check_client_intr(sdioh_info_t *sd);
+
+/* Core interrupt enable/disable of device interrupts */
+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+
+/**************************************************************
+ * Internal interfaces: bcmsdh_sdmmc.c references to per-port code
+ */
+
+/* Register mapping routines */
+extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size);
+extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size);
+
+/* Interrupt (de)registration routines */
+extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq);
+extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd);
+
+typedef struct _BCMSDH_SDMMC_INSTANCE {
+ sdioh_info_t *sd;
+ struct sdio_func *func[SDIOD_MAX_IOFUNCS];
+ uint32 host_claimed;
+} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE;
+
+#endif /* __BCMSDH_SDMMC_H__ */
diff --git a/drivers/staging/brcm80211/include/bcmsdpcm.h b/drivers/staging/brcm80211/include/bcmsdpcm.h
new file mode 100644
index 000000000000..cd495545a691
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsdpcm.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmsdpcm_h_
+#define _bcmsdpcm_h_
+
+/*
+ * Software allocation of To SB Mailbox resources
+ */
+
+/* intstatus bits */
+#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */
+#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */
+#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */
+#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */
+
+#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT)
+
+/* tosbmailbox bits corresponding to intstatus bits */
+#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */
+#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */
+#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */
+#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */
+#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */
+
+/* tosbmailboxdata */
+#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */
+#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */
+
+/*
+ * Software allocation of To Host Mailbox resources
+ */
+
+/* intstatus bits */
+#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */
+#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */
+#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */
+#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */
+
+#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT)
+
+/* tohostmailbox bits corresponding to intstatus bits */
+#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */
+#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */
+#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */
+#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */
+#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */
+
+/* tohostmailboxdata */
+#define HMB_DATA_NAKHANDLED 1 /* we're ready to retransmit NAK'd frame to host */
+#define HMB_DATA_DEVREADY 2 /* we're ready to to talk to host after enable */
+#define HMB_DATA_FC 4 /* per prio flowcontrol update flag to host */
+#define HMB_DATA_FWREADY 8 /* firmware is ready for protocol activity */
+
+#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */
+#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */
+
+#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */
+#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */
+
+/*
+ * Software-defined protocol header
+ */
+
+/* Current protocol version */
+#define SDPCM_PROT_VERSION 4
+
+/* SW frame header */
+#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */
+#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */
+
+#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */
+#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */
+#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */
+
+#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */
+#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */
+#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */
+
+/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */
+#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */
+#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */
+#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */
+#define SDPCM_NEXTLEN_OFFSET 2
+
+/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
+#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
+#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
+#define SDPCM_DOFFSET_MASK 0xff000000
+#define SDPCM_DOFFSET_SHIFT 24
+
+#define SDPCM_FCMASK_OFFSET 4 /* Flow control */
+#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
+#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
+#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
+#define SDPCM_VERSION_OFFSET 6 /* Version # */
+#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff)
+#define SDPCM_UNUSED_OFFSET 7 /* Spare */
+#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff)
+
+#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
+
+/* logical channel numbers */
+#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */
+#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
+#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
+#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */
+#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
+#define SDPCM_MAX_CHANNEL 15
+
+#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */
+
+#define SDPCM_FLAG_RESVD0 0x01
+#define SDPCM_FLAG_RESVD1 0x02
+#define SDPCM_FLAG_GSPI_TXENAB 0x04
+#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */
+
+/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */
+#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT)
+
+#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80)
+
+/* For TEST_CHANNEL packets, define another 4-byte header */
+#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2);
+ * Semantics of Ext byte depend on command.
+ * Len is current or requested frame length, not
+ * including test header; sent little-endian.
+ */
+#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */
+#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */
+#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */
+#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */
+#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */
+
+/* Handy macro for filling in datagen packets with a pattern */
+#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno))
+
+/*
+ * Software counters (first part matches hardware counters)
+ */
+
+typedef volatile struct {
+ uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */
+ uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */
+ uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */
+ uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */
+ uint32 abort; /* AbortCount, SDIO: aborts */
+ uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */
+ uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */
+ uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */
+ uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */
+ uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */
+ uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */
+ uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */
+ uint32 rxdescuflo; /* receive descriptor underflows */
+ uint32 rxfifooflo; /* receive fifo overflows */
+ uint32 txfifouflo; /* transmit fifo underflows */
+ uint32 runt; /* runt (too short) frames recv'd from bus */
+ uint32 badlen; /* frame's rxh len does not match its hw tag len */
+ uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */
+ uint32 seqbreak; /* break in sequence # space from one rx frame to the next */
+ uint32 rxfcrc; /* frame rx header indicates crc error */
+ uint32 rxfwoos; /* frame rx header indicates write out of sync */
+ uint32 rxfwft; /* frame rx header indicates write frame termination */
+ uint32 rxfabort; /* frame rx header indicates frame aborted */
+ uint32 woosint; /* write out of sync interrupt */
+ uint32 roosint; /* read out of sync interrupt */
+ uint32 rftermint; /* read frame terminate interrupt */
+ uint32 wftermint; /* write frame terminate interrupt */
+} sdpcmd_cnt_t;
+
+/*
+ * Register Access Macros
+ */
+
+#define SDIODREV_IS(var, val) ((var) == (val))
+#define SDIODREV_GE(var, val) ((var) >= (val))
+#define SDIODREV_GT(var, val) ((var) > (val))
+#define SDIODREV_LT(var, val) ((var) < (val))
+#define SDIODREV_LE(var, val) ((var) <= (val))
+
+#define SDIODDMAREG32(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv))
+
+#define SDIODDMAREG64(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv))
+
+#define SDIODDMAREG(h, dir, chnl) \
+ (SDIODREV_LT((h)->corerev, 1) ? \
+ SDIODDMAREG32((h), (dir), (chnl)) : \
+ SDIODDMAREG64((h), (dir), (chnl)))
+
+#define PCMDDMAREG(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv))
+
+#define SDPCMDMAREG(h, dir, chnl, coreid) \
+ ((coreid) == SDIOD_CORE_ID ? \
+ SDIODDMAREG(h, dir, chnl) : \
+ PCMDDMAREG(h, dir, chnl))
+
+#define SDIODFIFOREG(h, corerev) \
+ (SDIODREV_LT((corerev), 1) ? \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo)))
+
+#define PCMDFIFOREG(h) \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo))
+
+#define SDPCMFIFOREG(h, coreid, corerev) \
+ ((coreid) == SDIOD_CORE_ID ? \
+ SDIODFIFOREG(h, corerev) : \
+ PCMDFIFOREG(h))
+
+/*
+ * Shared structure between dongle and the host.
+ * The structure contains pointers to trap or assert information.
+ */
+#define SDPCM_SHARED_VERSION 0x0001
+#define SDPCM_SHARED_VERSION_MASK 0x00FF
+#define SDPCM_SHARED_ASSERT_BUILT 0x0100
+#define SDPCM_SHARED_ASSERT 0x0200
+#define SDPCM_SHARED_TRAP 0x0400
+
+typedef struct {
+ uint32 flags;
+ uint32 trap_addr;
+ uint32 assert_exp_addr;
+ uint32 assert_file_addr;
+ uint32 assert_line;
+ uint32 console_addr; /* Address of hndrte_cons_t */
+ uint32 msgtrace_addr;
+} sdpcm_shared_t;
+
+extern sdpcm_shared_t sdpcm_shared;
+
+#endif /* _bcmsdpcm_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/include/bcmsrom.h
new file mode 100644
index 000000000000..45429c7a5590
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsrom.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmsrom_h_
+#define _bcmsrom_h_
+
+#include <bcmsrom_fmt.h>
+
+/* Prototypes */
+extern int srom_var_init(si_t *sih, uint bus, void *curmap, osl_t *osh,
+ char **vars, uint *count);
+
+extern int srom_read(si_t *sih, uint bus, void *curmap, osl_t *osh,
+ uint byteoff, uint nbytes, uint16 *buf, bool check_crc);
+
+/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
+ * and extract from it into name=value pairs
+ */
+extern int srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt,
+ char **vars, uint *count);
+#endif /* _bcmsrom_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h
new file mode 100644
index 000000000000..5ce6143bcab4
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsrom_fmt.h
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmsrom_fmt_h_
+#define _bcmsrom_fmt_h_
+
+/* Maximum srom: 6 Kilobits == 768 bytes */
+#define SROM_MAX 768
+#define SROM_MAXW 384
+#define VARS_MAX 4096
+
+/* PCI fields */
+#define PCI_F0DEVID 48
+
+#define SROM_WORDS 64
+
+#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */
+
+#define SROM_SSID 2
+
+#define SROM_WL1LHMAXP 29
+
+#define SROM_WL1LPAB0 30
+#define SROM_WL1LPAB1 31
+#define SROM_WL1LPAB2 32
+
+#define SROM_WL1HPAB0 33
+#define SROM_WL1HPAB1 34
+#define SROM_WL1HPAB2 35
+
+#define SROM_MACHI_IL0 36
+#define SROM_MACMID_IL0 37
+#define SROM_MACLO_IL0 38
+#define SROM_MACHI_ET0 39
+#define SROM_MACMID_ET0 40
+#define SROM_MACLO_ET0 41
+#define SROM_MACHI_ET1 42
+#define SROM_MACMID_ET1 43
+#define SROM_MACLO_ET1 44
+#define SROM3_MACHI 37
+#define SROM3_MACMID 38
+#define SROM3_MACLO 39
+
+#define SROM_BXARSSI2G 40
+#define SROM_BXARSSI5G 41
+
+#define SROM_TRI52G 42
+#define SROM_TRI5GHL 43
+
+#define SROM_RXPO52G 45
+
+#define SROM2_ENETPHY 45
+
+#define SROM_AABREV 46
+/* Fields in AABREV */
+#define SROM_BR_MASK 0x00ff
+#define SROM_CC_MASK 0x0f00
+#define SROM_CC_SHIFT 8
+#define SROM_AA0_MASK 0x3000
+#define SROM_AA0_SHIFT 12
+#define SROM_AA1_MASK 0xc000
+#define SROM_AA1_SHIFT 14
+
+#define SROM_WL0PAB0 47
+#define SROM_WL0PAB1 48
+#define SROM_WL0PAB2 49
+
+#define SROM_LEDBH10 50
+#define SROM_LEDBH32 51
+
+#define SROM_WL10MAXP 52
+
+#define SROM_WL1PAB0 53
+#define SROM_WL1PAB1 54
+#define SROM_WL1PAB2 55
+
+#define SROM_ITT 56
+
+#define SROM_BFL 57
+#define SROM_BFL2 28
+#define SROM3_BFL2 61
+
+#define SROM_AG10 58
+
+#define SROM_CCODE 59
+
+#define SROM_OPO 60
+
+#define SROM3_LEDDC 62
+
+#define SROM_CRCREV 63
+
+/* SROM Rev 4: Reallocate the software part of the srom to accomodate
+ * MIMO features. It assumes up to two PCIE functions and 440 bytes
+ * of useable srom i.e. the useable storage in chips with OTP that
+ * implements hardware redundancy.
+ */
+
+#define SROM4_WORDS 220
+
+#define SROM4_SIGN 32
+#define SROM4_SIGNATURE 0x5372
+
+#define SROM4_BREV 33
+
+#define SROM4_BFL0 34
+#define SROM4_BFL1 35
+#define SROM4_BFL2 36
+#define SROM4_BFL3 37
+#define SROM5_BFL0 37
+#define SROM5_BFL1 38
+#define SROM5_BFL2 39
+#define SROM5_BFL3 40
+
+#define SROM4_MACHI 38
+#define SROM4_MACMID 39
+#define SROM4_MACLO 40
+#define SROM5_MACHI 41
+#define SROM5_MACMID 42
+#define SROM5_MACLO 43
+
+#define SROM4_CCODE 41
+#define SROM4_REGREV 42
+#define SROM5_CCODE 34
+#define SROM5_REGREV 35
+
+#define SROM4_LEDBH10 43
+#define SROM4_LEDBH32 44
+#define SROM5_LEDBH10 59
+#define SROM5_LEDBH32 60
+
+#define SROM4_LEDDC 45
+#define SROM5_LEDDC 45
+
+#define SROM4_AA 46
+#define SROM4_AA2G_MASK 0x00ff
+#define SROM4_AA2G_SHIFT 0
+#define SROM4_AA5G_MASK 0xff00
+#define SROM4_AA5G_SHIFT 8
+
+#define SROM4_AG10 47
+#define SROM4_AG32 48
+
+#define SROM4_TXPID2G 49
+#define SROM4_TXPID5G 51
+#define SROM4_TXPID5GL 53
+#define SROM4_TXPID5GH 55
+
+#define SROM4_TXRXC 61
+#define SROM4_TXCHAIN_MASK 0x000f
+#define SROM4_TXCHAIN_SHIFT 0
+#define SROM4_RXCHAIN_MASK 0x00f0
+#define SROM4_RXCHAIN_SHIFT 4
+#define SROM4_SWITCH_MASK 0xff00
+#define SROM4_SWITCH_SHIFT 8
+
+/* Per-path fields */
+#define MAX_PATH_SROM 4
+#define SROM4_PATH0 64
+#define SROM4_PATH1 87
+#define SROM4_PATH2 110
+#define SROM4_PATH3 133
+
+#define SROM4_2G_ITT_MAXP 0
+#define SROM4_2G_PA 1
+#define SROM4_5G_ITT_MAXP 5
+#define SROM4_5GLH_MAXP 6
+#define SROM4_5G_PA 7
+#define SROM4_5GL_PA 11
+#define SROM4_5GH_PA 15
+
+/* Fields in the ITT_MAXP and 5GLH_MAXP words */
+#define B2G_MAXP_MASK 0xff
+#define B2G_ITT_SHIFT 8
+#define B5G_MAXP_MASK 0xff
+#define B5G_ITT_SHIFT 8
+#define B5GH_MAXP_MASK 0xff
+#define B5GL_MAXP_SHIFT 8
+
+/* All the miriad power offsets */
+#define SROM4_2G_CCKPO 156
+#define SROM4_2G_OFDMPO 157
+#define SROM4_5G_OFDMPO 159
+#define SROM4_5GL_OFDMPO 161
+#define SROM4_5GH_OFDMPO 163
+#define SROM4_2G_MCSPO 165
+#define SROM4_5G_MCSPO 173
+#define SROM4_5GL_MCSPO 181
+#define SROM4_5GH_MCSPO 189
+#define SROM4_CDDPO 197
+#define SROM4_STBCPO 198
+#define SROM4_BW40PO 199
+#define SROM4_BWDUPPO 200
+
+#define SROM4_CRCREV 219
+
+/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
+ * This is acombined srom for both MIMO and SISO boards, usable in
+ * the .130 4Kilobit OTP with hardware redundancy.
+ */
+
+#define SROM8_SIGN 64
+
+#define SROM8_BREV 65
+
+#define SROM8_BFL0 66
+#define SROM8_BFL1 67
+#define SROM8_BFL2 68
+#define SROM8_BFL3 69
+
+#define SROM8_MACHI 70
+#define SROM8_MACMID 71
+#define SROM8_MACLO 72
+
+#define SROM8_CCODE 73
+#define SROM8_REGREV 74
+
+#define SROM8_LEDBH10 75
+#define SROM8_LEDBH32 76
+
+#define SROM8_LEDDC 77
+
+#define SROM8_AA 78
+
+#define SROM8_AG10 79
+#define SROM8_AG32 80
+
+#define SROM8_TXRXC 81
+
+#define SROM8_BXARSSI2G 82
+#define SROM8_BXARSSI5G 83
+#define SROM8_TRI52G 84
+#define SROM8_TRI5GHL 85
+#define SROM8_RXPO52G 86
+
+#define SROM8_FEM2G 87
+#define SROM8_FEM5G 88
+#define SROM8_FEM_ANTSWLUT_MASK 0xf800
+#define SROM8_FEM_ANTSWLUT_SHIFT 11
+#define SROM8_FEM_TR_ISO_MASK 0x0700
+#define SROM8_FEM_TR_ISO_SHIFT 8
+#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
+#define SROM8_FEM_PDET_RANGE_SHIFT 3
+#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
+#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
+#define SROM8_FEM_TSSIPOS_MASK 0x0001
+#define SROM8_FEM_TSSIPOS_SHIFT 0
+
+#define SROM8_THERMAL 89
+
+/* Temp sense related entries */
+#define SROM8_MPWR_RAWTS 90
+#define SROM8_TS_SLP_OPT_CORRX 91
+/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
+#define SROM8_FOC_HWIQ_IQSWP 92
+
+/* Temperature delta for PHY calibration */
+#define SROM8_PHYCAL_TEMPDELTA 93
+
+/* Per-path offsets & fields */
+#define SROM8_PATH0 96
+#define SROM8_PATH1 112
+#define SROM8_PATH2 128
+#define SROM8_PATH3 144
+
+#define SROM8_2G_ITT_MAXP 0
+#define SROM8_2G_PA 1
+#define SROM8_5G_ITT_MAXP 4
+#define SROM8_5GLH_MAXP 5
+#define SROM8_5G_PA 6
+#define SROM8_5GL_PA 9
+#define SROM8_5GH_PA 12
+
+/* All the miriad power offsets */
+#define SROM8_2G_CCKPO 160
+
+#define SROM8_2G_OFDMPO 161
+#define SROM8_5G_OFDMPO 163
+#define SROM8_5GL_OFDMPO 165
+#define SROM8_5GH_OFDMPO 167
+
+#define SROM8_2G_MCSPO 169
+#define SROM8_5G_MCSPO 177
+#define SROM8_5GL_MCSPO 185
+#define SROM8_5GH_MCSPO 193
+
+#define SROM8_CDDPO 201
+#define SROM8_STBCPO 202
+#define SROM8_BW40PO 203
+#define SROM8_BWDUPPO 204
+
+/* SISO PA parameters are in the path0 spaces */
+#define SROM8_SISO 96
+
+/* Legacy names for SISO PA paramters */
+#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
+#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
+#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
+#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
+#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
+#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
+#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
+#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
+#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
+#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
+#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
+#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
+#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
+#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
+#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
+
+#define SROM8_CRCREV 219
+
+/* SROM REV 9 */
+#define SROM9_2GPO_CCKBW20 160
+#define SROM9_2GPO_CCKBW20UL 161
+#define SROM9_2GPO_LOFDMBW20 162
+#define SROM9_2GPO_LOFDMBW20UL 164
+
+#define SROM9_5GLPO_LOFDMBW20 166
+#define SROM9_5GLPO_LOFDMBW20UL 168
+#define SROM9_5GMPO_LOFDMBW20 170
+#define SROM9_5GMPO_LOFDMBW20UL 172
+#define SROM9_5GHPO_LOFDMBW20 174
+#define SROM9_5GHPO_LOFDMBW20UL 176
+
+#define SROM9_2GPO_MCSBW20 178
+#define SROM9_2GPO_MCSBW20UL 180
+#define SROM9_2GPO_MCSBW40 182
+
+#define SROM9_5GLPO_MCSBW20 184
+#define SROM9_5GLPO_MCSBW20UL 186
+#define SROM9_5GLPO_MCSBW40 188
+#define SROM9_5GMPO_MCSBW20 190
+#define SROM9_5GMPO_MCSBW20UL 192
+#define SROM9_5GMPO_MCSBW40 194
+#define SROM9_5GHPO_MCSBW20 196
+#define SROM9_5GHPO_MCSBW20UL 198
+#define SROM9_5GHPO_MCSBW40 200
+
+#define SROM9_PO_MCS32 202
+#define SROM9_PO_LOFDM40DUP 203
+
+#define SROM9_REV_CRC 219
+
+typedef struct {
+ uint8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */
+ uint8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
+ uint8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */
+ uint8 triso; /* TR switch isolation */
+ uint8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */
+} srom_fem_t;
+
+#endif /* _bcmsrom_fmt_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmsrom_tbl.h b/drivers/staging/brcm80211/include/bcmsrom_tbl.h
new file mode 100644
index 000000000000..646126f01fe5
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmsrom_tbl.h
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmsrom_tbl_h_
+#define _bcmsrom_tbl_h_
+
+#include "sbpcmcia.h"
+#include "wlioctl.h"
+
+typedef struct {
+ const char *name;
+ uint32 revmask;
+ uint32 flags;
+ uint16 off;
+ uint16 mask;
+} sromvar_t;
+
+#define SRFL_MORE 1 /* value continues as described by the next entry */
+#define SRFL_NOFFS 2 /* value bits can't be all one's */
+#define SRFL_PRHEX 4 /* value is in hexdecimal format */
+#define SRFL_PRSIGN 8 /* value is in signed decimal format */
+#define SRFL_CCODE 0x10 /* value is in country code format */
+#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
+#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
+#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */
+
+/* Assumptions:
+ * - Ethernet address spans across 3 consective words
+ *
+ * Table rules:
+ * - Add multiple entries next to each other if a value spans across multiple words
+ * (even multiple fields in the same word) with each entry except the last having
+ * it's SRFL_MORE bit set.
+ * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
+ * bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
+ * - The last entry's name field must be NULL to indicate the end of the table. Other
+ * entries must have non-NULL name.
+ */
+
+static const sromvar_t pci_sromvars[] = {
+ {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
+ {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
+ {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
+ {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
+ {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
+ {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+ {"", 0, 0, SROM_BFL2, 0xffff},
+ {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+ {"", 0, 0, SROM3_BFL2, 0xffff},
+ {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
+ {"", 0, 0, SROM4_BFL1, 0xffff},
+ {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
+ {"", 0, 0, SROM5_BFL1, 0xffff},
+ {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
+ {"", 0, 0, SROM8_BFL1, 0xffff},
+ {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
+ {"", 0, 0, SROM4_BFL3, 0xffff},
+ {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
+ {"", 0, 0, SROM5_BFL3, 0xffff},
+ {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
+ {"", 0, 0, SROM8_BFL3, 0xffff},
+ {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
+ {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
+ {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
+ {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
+ {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
+ {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
+ {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
+ {"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
+ {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
+ {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
+ {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
+ {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
+ {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
+ {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
+ {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
+ {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
+ {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
+ {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
+ {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
+ {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
+ {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
+ {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
+ {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
+ {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
+ {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
+ {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
+ {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
+ {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
+ {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
+ {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
+ {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
+ {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
+ {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
+ {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
+ {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
+ {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
+ {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
+ {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
+ {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
+ {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
+ {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
+ {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
+ {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
+ {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
+ {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
+ {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
+ {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
+ {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
+ {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
+ {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
+ {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
+ {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
+ {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
+ {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
+ {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
+ {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
+ {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
+ {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
+ {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
+ {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
+ {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
+ {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
+ {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
+ {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
+ {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
+ {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
+ {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
+ {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
+ {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
+ {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
+ {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
+ {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
+ {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
+ {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
+ {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
+ {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
+ {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
+ {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
+ {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
+ {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
+ {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
+ {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
+ {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
+ {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
+ {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
+ {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
+ {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
+ {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
+ {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
+ {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
+ {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
+ {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
+ {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
+ {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
+ {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
+ {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
+ {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
+ {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
+ {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
+ {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
+ {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
+ {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
+ {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
+ {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
+ {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
+ {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
+ {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
+ {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
+ {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
+ {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
+ {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
+ {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
+ {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
+ {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
+ {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
+ {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
+ {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
+ {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
+ {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
+ {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
+ {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
+ {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
+ {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
+ {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
+ {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
+ {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
+ {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
+ {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
+ {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
+ {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
+ {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
+ {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
+ {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
+ {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
+ {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
+ {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
+ {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
+ {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
+ {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
+ {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
+ {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
+ {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
+ {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
+
+ {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
+ {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
+ {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
+ {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
+ {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
+ {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
+ {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
+ {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
+ {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
+ {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
+ {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
+ {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
+ {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
+ {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
+ {"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
+ {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
+ {"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+ 0x00ff},
+ {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
+ {"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+ 0x0300},
+ {"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
+ 0x000f},
+ {"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
+ {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
+ {"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
+
+ {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
+ {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
+ {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
+ {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
+ {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
+ {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
+ {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
+ {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
+ {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
+ {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
+ {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
+ {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
+ {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
+ {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
+ {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
+ {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
+ {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
+ {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
+ {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
+ {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
+ {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
+ {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
+ {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
+ {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
+ {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
+ {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
+ {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
+ {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
+ {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
+ {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
+ {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
+ {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
+ {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
+ {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
+ {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
+ {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
+ {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
+ {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
+ {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
+ {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
+ {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
+ {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
+ {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
+ {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
+ {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
+ {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
+ {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
+ {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
+ {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
+ {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
+ {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
+ {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
+ {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
+ {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
+ {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
+ {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
+ {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
+ {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
+ {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
+ {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
+ {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
+ {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
+ {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
+ {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
+ {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
+ {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
+ {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
+ {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
+ {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
+ {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
+ {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
+ {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
+ {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
+ {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
+ {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
+ {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
+ {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
+ {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
+ {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
+ {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
+ {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
+ {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
+
+ /* power per rate from sromrev 9 */
+ {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
+ {"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
+ {"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
+ 0xffff},
+ {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
+ {"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
+ {"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
+ 0xffff},
+ {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
+ {"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
+ {"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
+ 0xffff},
+ {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
+ {"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
+ {"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
+ 0xffff},
+ {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
+ {"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
+ {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
+ {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
+ {"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
+ {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
+ {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
+ {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
+ {"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
+ {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
+ {"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
+ {"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
+ {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
+ {"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
+ {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
+ {"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
+ {"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
+ {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
+ {"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
+ {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
+ {"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
+ 0xffff},
+ {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
+ {"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
+ {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
+ {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
+ {"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
+
+ {NULL, 0, 0, 0, 0}
+};
+
+static const sromvar_t perpath_pci_sromvars[] = {
+ {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
+ {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
+ {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
+ {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
+ {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
+ {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
+ {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
+ {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
+ {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
+ {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
+ {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
+ {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
+ {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
+ {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
+ {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
+ {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
+ {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
+ {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
+ {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
+ {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
+ {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
+ {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
+ {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
+ {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
+ {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
+ {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
+ {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
+ {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
+ {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
+ {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
+ {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
+ {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
+ {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
+ {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
+ {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
+ {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
+ {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
+ {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
+ {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
+ {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
+ {NULL, 0, 0, 0, 0}
+};
+
+#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
+#define PHY_TYPE_N 4 /* N-Phy value */
+#define PHY_TYPE_LP 5 /* LP-Phy value */
+#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
+#if !defined(PHY_TYPE_NULL)
+#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
+#endif /* !defined(PHY_TYPE_NULL) */
+
+typedef struct {
+ uint16 phy_type;
+ uint16 bandrange;
+ uint16 chain;
+ const char *vars;
+} pavars_t;
+
+static const pavars_t pavars[] = {
+ /* NPHY */
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0,
+ "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1,
+ "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0,
+ "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1,
+ "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
+ /* LPPHY */
+ {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
+ {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
+ {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
+ {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
+ {PHY_TYPE_NULL, 0, 0, ""}
+};
+
+typedef struct {
+ uint16 phy_type;
+ uint16 bandrange;
+ const char *vars;
+} povars_t;
+
+static const povars_t povars[] = {
+ /* NPHY */
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
+ "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
+ "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
+ "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
+ "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
+ "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
+ "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
+ {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
+ "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
+ "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
+ {PHY_TYPE_NULL, 0, ""}
+};
+
+typedef struct {
+ uint8 tag; /* Broadcom subtag name */
+ uint8 len; /* Length field of the tuple, note that it includes the
+ * subtag name (1 byte): 1 + tuple content length
+ */
+ const char *params;
+} cis_tuple_t;
+
+#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */
+#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */
+#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */
+#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */
+
+static const cis_tuple_t cis_hnbuvars[] = {
+ {OTP_RAW1, 0, ""}, /* special case */
+ {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */
+ {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */
+ {HNBU_SROMREV, 2, "1sromrev"},
+ /* NOTE: subdevid is also written to boardtype.
+ * Need to write HNBU_BOARDTYPE to change it if it is different.
+ */
+ {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
+ {HNBU_BOARDREV, 3, "2boardrev"},
+ {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
+ {HNBU_AA, 3, "1aa2g 1aa5g"},
+ {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */
+ {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"},
+ {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"},
+ {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
+ {HNBU_CCODE, 4, "2ccode 1cctl"},
+ {HNBU_CCKPO, 3, "2cckpo"},
+ {HNBU_OFDMPO, 5, "4ofdmpo"},
+ {HNBU_RDLID, 3, "2rdlid"},
+ {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */
+ {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */
+ {HNBU_XTALFREQ, 5, "4xtalfreq"},
+ {HNBU_TRI2G, 2, "1tri2g"},
+ {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"},
+ {HNBU_RXPO2G, 2, "1rxpo2g"},
+ {HNBU_RXPO5G, 2, "1rxpo5g"},
+ {HNBU_BOARDNUM, 3, "2boardnum"},
+ {HNBU_MACADDR, 7, "6macaddr"}, /* special case */
+ {HNBU_RDLSN, 3, "2rdlsn"},
+ {HNBU_BOARDTYPE, 3, "2boardtype"},
+ {HNBU_LEDDC, 3, "2leddc"},
+ {HNBU_RDLRNDIS, 2, "1rdlndis"},
+ {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"},
+ {HNBU_REGREV, 2, "1regrev"},
+ {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */
+ {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
+ "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 "
+ "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 "
+ "2pa5ghw1a0 2pa5ghw2a0"},
+ {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
+ "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 "
+ "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 "
+ "2pa5ghw1a1 2pa5ghw2a1"},
+ {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
+ "4ofdm5ghpo"},
+ {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
+ "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"},
+ {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
+ "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"},
+ {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
+ "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 "
+ "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 "
+ "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"},
+ {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"},
+ {HNBU_PO_CDD, 3, "2cddpo"},
+ {HNBU_PO_STBC, 3, "2stbcpo"},
+ {HNBU_PO_40M, 3, "2bw40po"},
+ {HNBU_PO_40MDUP, 3, "2bwduppo"},
+ {HNBU_RDLRWU, 2, "1rdlrwu"},
+ {HNBU_WPS, 3, "1wpsgpio 1wpsled"},
+ {HNBU_USBFS, 2, "1usbfs"},
+ {HNBU_CUSTOM1, 5, "4customvar1"},
+ {OTP_RAW, 0, ""}, /* special case */
+ {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
+ {HNBU_USBEPNUM, 3, "2usbepnum"},
+ {0xFF, 0, ""}
+};
+
+#endif /* _bcmsrom_tbl_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h
new file mode 100644
index 000000000000..321071b53727
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmutils.h
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmutils_h_
+#define _bcmutils_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ctype replacement */
+#define _BCM_U 0x01 /* upper */
+#define _BCM_L 0x02 /* lower */
+#define _BCM_D 0x04 /* digit */
+#define _BCM_C 0x08 /* cntrl */
+#define _BCM_P 0x10 /* punct */
+#define _BCM_S 0x20 /* white space (space/lf/tab) */
+#define _BCM_X 0x40 /* hex digit */
+#define _BCM_SP 0x80 /* hard space (0x20) */
+
+ extern const unsigned char bcm_ctype[];
+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
+
+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
+#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c))
+
+/* Buffer structure for collecting string-formatted data
+* using bcm_bprintf() API.
+* Use bcm_binit() to initialize before use
+*/
+
+ struct bcmstrbuf {
+ char *buf; /* pointer to current position in origbuf */
+ unsigned int size; /* current (residual) size in bytes */
+ char *origbuf; /* unmodified pointer to orignal buffer */
+ unsigned int origsize; /* unmodified orignal buffer size in bytes */
+ };
+
+/* ** driver-only section ** */
+#include <osl.h>
+
+#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
+
+/*
+ * Spin at most 'us' microseconds while 'exp' is true.
+ * Caller should explicitly test 'exp' when this completes
+ * and take appropriate error action if 'exp' is still true.
+ */
+#define SPINWAIT(exp, us) { \
+ uint countdown = (us) + 9; \
+ while ((exp) && (countdown >= 10)) {\
+ OSL_DELAY(10); \
+ countdown -= 10; \
+ } \
+}
+
+/* osl multi-precedence packet queue */
+#ifndef PKTQ_LEN_DEFAULT
+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
+#endif
+#ifndef PKTQ_MAX_PREC
+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
+#endif
+
+ typedef struct pktq_prec {
+ void *head; /* first packet to dequeue */
+ void *tail; /* last packet to dequeue */
+ uint16 len; /* number of queued packets */
+ uint16 max; /* maximum number of queued packets */
+ } pktq_prec_t;
+
+/* multi-priority pkt queue */
+ struct pktq {
+ uint16 num_prec; /* number of precedences in use */
+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
+ uint16 max; /* total max packets */
+ uint16 len; /* total number of packets */
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[PKTQ_MAX_PREC];
+ };
+
+/* simple, non-priority pkt queue */
+ struct spktq {
+ uint16 num_prec; /* number of precedences in use (always 1) */
+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
+ uint16 max; /* total max packets */
+ uint16 len; /* total number of packets */
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[1];
+ };
+
+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
+
+/* fn(pkt, arg). return true if pkt belongs to if */
+ typedef bool(*ifpkt_cb_t) (void *, int);
+
+/* forward definition of ether_addr structure used by some function prototypes */
+
+ struct ether_addr;
+
+ extern int ether_isbcast(const void *ea);
+ extern int ether_isnulladdr(const void *ea);
+
+/* operations on a specific precedence in packet queue */
+
+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
+#define pktq_plen(pq, prec) ((pq)->q[prec].len)
+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
+
+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
+
+ extern void *pktq_penq(struct pktq *pq, int prec, void *p);
+ extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
+ extern void *pktq_pdeq(struct pktq *pq, int prec);
+ extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
+/* Empty the queue at particular precedence level */
+ extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec,
+ bool dir, ifpkt_cb_t fn, int arg);
+/* Remove a specified packet from its queue */
+ extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
+
+/* operations on a set of precedences in packet queue */
+
+ extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
+ extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
+
+/* operations on packet queue as a whole */
+
+#define pktq_len(pq) ((int)(pq)->len)
+#define pktq_max(pq) ((int)(pq)->max)
+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
+#define pktq_full(pq) ((pq)->len >= (pq)->max)
+#define pktq_empty(pq) ((pq)->len == 0)
+
+/* operations for single precedence queues */
+#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p))
+#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p))
+#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0)
+#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0)
+#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len)
+
+ extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
+/* prec_out may be NULL if caller is not interested in return value */
+ extern void *pktq_deq(struct pktq *pq, int *prec_out);
+ extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
+ extern void *pktq_peek(struct pktq *pq, int *prec_out);
+ extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
+ extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir,
+ ifpkt_cb_t fn, int arg);
+
+/* externs */
+/* packet */
+ extern uint pktcopy(osl_t *osh, void *p, uint offset, int len,
+ uchar *buf);
+ extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len,
+ uchar *buf);
+ extern uint pkttotlen(osl_t *osh, void *p);
+ extern void *pktlast(osl_t *osh, void *p);
+ extern uint pktsegcnt(osl_t *osh, void *p);
+
+/* Get priority from a packet and pass it back in scb (or equiv) */
+ extern uint pktsetprio(void *pkt, bool update_vtag);
+#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */
+#define PKTPRIO_VLAN 0x200 /* VLAN prio found */
+#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */
+#define PKTPRIO_DSCP 0x800 /* DSCP prio found */
+
+/* string */
+ extern int BCMROMFN(bcm_atoi) (char *s);
+ extern ulong BCMROMFN(bcm_strtoul) (char *cp, char **endp, uint base);
+ extern char *BCMROMFN(bcmstrstr) (char *haystack, char *needle);
+ extern char *BCMROMFN(bcmstrcat) (char *dest, const char *src);
+ extern char *BCMROMFN(bcmstrncat) (char *dest, const char *src,
+ uint size);
+ extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen,
+ ulong abuflen);
+ char *bcmstrtok(char **string, const char *delimiters, char *tokdelim);
+ int bcmstricmp(const char *s1, const char *s2);
+ int bcmstrnicmp(const char *s1, const char *s2, int cnt);
+
+/* ethernet address */
+ extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf);
+ extern int BCMROMFN(bcm_ether_atoe) (char *p, struct ether_addr *ea);
+
+/* ip address */
+ struct ipv4_addr;
+ extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
+
+/* delay */
+ extern void bcm_mdelay(uint ms);
+/* variable access */
+ extern char *getvar(char *vars, const char *name);
+ extern int getintvar(char *vars, const char *name);
+ extern int getintvararray(char *vars, const char *name, uint8 index);
+ extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
+#ifdef BCMDBG
+ extern void prpkt(const char *msg, osl_t *osh, void *p0);
+#endif /* BCMDBG */
+#define bcm_perf_enable()
+#define bcmstats(fmt)
+#define bcmlog(fmt, a1, a2)
+#define bcmdumplog(buf, size) (*buf = '\0')
+#define bcmdumplogent(buf, idx) -1
+
+#define bcmtslog(tstamp, fmt, a1, a2)
+#define bcmprinttslogs()
+#define bcmprinttstamp(us)
+
+ extern char *bcm_nvram_vars(uint *length);
+ extern int bcm_nvram_cache(void *sih);
+
+/* Support for sharing code across in-driver iovar implementations.
+ * The intent is that a driver use this structure to map iovar names
+ * to its (private) iovar identifiers, and the lookup function to
+ * find the entry. Macros are provided to map ids and get/set actions
+ * into a single number space for a switch statement.
+ */
+
+/* iovar structure */
+ typedef struct bcm_iovar {
+ const char *name; /* name for lookup and display */
+ uint16 varid; /* id for switch */
+ uint16 flags; /* driver-specific flag bits */
+ uint16 type; /* base type of argument */
+ uint16 minlen; /* min length for buffer vars */
+ } bcm_iovar_t;
+
+/* varid definitions are per-driver, may use these get/set bits */
+
+/* IOVar action bits for id mapping */
+#define IOV_GET 0 /* Get an iovar */
+#define IOV_SET 1 /* Set an iovar */
+
+/* Varid to actionid mapping */
+#define IOV_GVAL(id) ((id)*2)
+#define IOV_SVAL(id) (((id)*2)+IOV_SET)
+#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
+#define IOV_ID(actionid) (actionid >> 1)
+
+/* flags are per-driver based on driver attributes */
+
+ extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table,
+ const char *name);
+ extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg,
+ int len, bool set);
+#if defined(BCMDBG)
+ extern int bcm_format_ssid(char *buf, const uchar ssid[],
+ uint ssid_len);
+#endif
+
+/* Base type definitions */
+#define IOVT_VOID 0 /* no value (implictly set only) */
+#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
+#define IOVT_INT8 2 /* integer values are range-checked */
+#define IOVT_UINT8 3 /* unsigned int 8 bits */
+#define IOVT_INT16 4 /* int 16 bits */
+#define IOVT_UINT16 5 /* unsigned int 16 bits */
+#define IOVT_INT32 6 /* int 32 bits */
+#define IOVT_UINT32 7 /* unsigned int 32 bits */
+#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
+#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
+
+/* Initializer for IOV type strings */
+#define BCM_IOV_TYPE_INIT { \
+ "void", \
+ "bool", \
+ "int8", \
+ "uint8", \
+ "int16", \
+ "uint16", \
+ "int32", \
+ "uint32", \
+ "buffer", \
+ "" }
+
+#define BCM_IOVT_IS_INT(type) (\
+ (type == IOVT_BOOL) || \
+ (type == IOVT_INT8) || \
+ (type == IOVT_UINT8) || \
+ (type == IOVT_INT16) || \
+ (type == IOVT_UINT16) || \
+ (type == IOVT_INT32) || \
+ (type == IOVT_UINT32))
+
+/* ** driver/apps-shared section ** */
+
+#define BCME_STRLEN 64 /* Max string length for BCM errors */
+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
+
+/*
+ * error codes could be added but the defined ones shouldn't be changed/deleted
+ * these error codes are exposed to the user code
+ * when ever a new error code is added to this list
+ * please update errorstring table with the related error string and
+ * update osl files with os specific errorcode map
+*/
+
+#define BCME_OK 0 /* Success */
+#define BCME_ERROR -1 /* Error generic */
+#define BCME_BADARG -2 /* Bad Argument */
+#define BCME_BADOPTION -3 /* Bad option */
+#define BCME_NOTUP -4 /* Not up */
+#define BCME_NOTDOWN -5 /* Not down */
+#define BCME_NOTAP -6 /* Not AP */
+#define BCME_NOTSTA -7 /* Not STA */
+#define BCME_BADKEYIDX -8 /* BAD Key Index */
+#define BCME_RADIOOFF -9 /* Radio Off */
+#define BCME_NOTBANDLOCKED -10 /* Not band locked */
+#define BCME_NOCLK -11 /* No Clock */
+#define BCME_BADRATESET -12 /* BAD Rate valueset */
+#define BCME_BADBAND -13 /* BAD Band */
+#define BCME_BUFTOOSHORT -14 /* Buffer too short */
+#define BCME_BUFTOOLONG -15 /* Buffer too long */
+#define BCME_BUSY -16 /* Busy */
+#define BCME_NOTASSOCIATED -17 /* Not Associated */
+#define BCME_BADSSIDLEN -18 /* Bad SSID len */
+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
+#define BCME_BADCHAN -20 /* Bad Channel */
+#define BCME_BADADDR -21 /* Bad Address */
+#define BCME_NORESOURCE -22 /* Not Enough Resources */
+#define BCME_UNSUPPORTED -23 /* Unsupported */
+#define BCME_BADLEN -24 /* Bad length */
+#define BCME_NOTREADY -25 /* Not Ready */
+#define BCME_EPERM -26 /* Not Permitted */
+#define BCME_NOMEM -27 /* No Memory */
+#define BCME_ASSOCIATED -28 /* Associated */
+#define BCME_RANGE -29 /* Not In Range */
+#define BCME_NOTFOUND -30 /* Not Found */
+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
+#define BCME_VERSION -37 /* Incorrect version */
+#define BCME_TXFAIL -38 /* TX failure */
+#define BCME_RXFAIL -39 /* RX failure */
+#define BCME_NODEVICE -40 /* Device not present */
+#define BCME_NMODE_DISABLED -41 /* NMODE disabled */
+#define BCME_NONRESIDENT -42 /* access to nonresident overlay */
+#define BCME_LAST BCME_NONRESIDENT
+
+/* These are collection of BCME Error strings */
+#define BCMERRSTRINGTABLE { \
+ "OK", \
+ "Undefined error", \
+ "Bad Argument", \
+ "Bad Option", \
+ "Not up", \
+ "Not down", \
+ "Not AP", \
+ "Not STA", \
+ "Bad Key Index", \
+ "Radio Off", \
+ "Not band locked", \
+ "No clock", \
+ "Bad Rate valueset", \
+ "Bad Band", \
+ "Buffer too short", \
+ "Buffer too long", \
+ "Busy", \
+ "Not Associated", \
+ "Bad SSID len", \
+ "Out of Range Channel", \
+ "Bad Channel", \
+ "Bad Address", \
+ "Not Enough Resources", \
+ "Unsupported", \
+ "Bad length", \
+ "Not Ready", \
+ "Not Permitted", \
+ "No Memory", \
+ "Associated", \
+ "Not In Range", \
+ "Not Found", \
+ "WME Not Enabled", \
+ "TSPEC Not Found", \
+ "ACM Not Supported", \
+ "Not WME Association", \
+ "SDIO Bus Error", \
+ "Dongle Not Accessible", \
+ "Incorrect version", \
+ "TX Failure", \
+ "RX Failure", \
+ "Device Not Present", \
+ "NMODE Disabled", \
+ "Nonresident overlay access", \
+}
+
+#ifndef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+#endif /* ABS */
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif /* MIN */
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif /* MAX */
+
+#define CEIL(x, y) (((x) + ((y)-1)) / (y))
+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
+#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \
+ & ~((boundary) - 1))
+#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
+#define VALID_MASK(mask) (!((mask) & ((mask) + 1)))
+#ifndef OFFSETOF
+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
+#endif /* OFFSETOF */
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+/* bit map related macros */
+#ifndef setbit
+#ifndef NBBY /* the BSD family defines NBBY */
+#define NBBY 8 /* 8 bits per byte */
+#endif /* #ifndef NBBY */
+#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+#endif /* setbit */
+
+#define NBITS(type) (sizeof(type) * 8)
+#define NBITVAL(nbits) (1 << (nbits))
+#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
+#define NBITMASK(nbits) MAXBITVAL(nbits)
+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
+
+/* basic mux operation - can be optimized on several architectures */
+#define MUX(pred, true, false) ((pred) ? (true) : (false))
+
+/* modulo inc/dec - assumes x E [0, bound - 1] */
+#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
+#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
+
+/* modulo inc/dec, bound = 2^k */
+#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
+#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
+
+/* modulo add/sub - assumes x, y E [0, bound - 1] */
+#define MODADD(x, y, bound) \
+ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
+#define MODSUB(x, y, bound) \
+ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
+
+/* module add/sub, bound = 2^k */
+#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
+#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
+
+/* crc defines */
+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
+
+/* bcm_format_flags() bit description structure */
+ typedef struct bcm_bit_desc {
+ uint32 bit;
+ const char *name;
+ } bcm_bit_desc_t;
+
+/* tag_ID/length/value_buffer tuple */
+ typedef struct bcm_tlv {
+ uint8 id;
+ uint8 len;
+ uint8 data[1];
+ } bcm_tlv_t;
+
+/* Check that bcm_tlv_t fits into the given buflen */
+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
+
+/* buffer length for ethernet address from bcm_ether_ntoa() */
+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
+
+/* crypto utility function */
+/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */
+ static INLINE void
+ xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) {
+ if (
+#ifdef __i386__
+ 1 ||
+#endif
+ (((uintptr) src1 | (uintptr) src2 | (uintptr) dst) &
+ 3) == 0) {
+ /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */
+ /* x86 supports unaligned. This version runs 6x-9x faster on x86. */
+ ((uint32 *) dst)[0] =
+ ((const uint32 *)src1)[0] ^ ((const uint32 *)
+ src2)[0];
+ ((uint32 *) dst)[1] =
+ ((const uint32 *)src1)[1] ^ ((const uint32 *)
+ src2)[1];
+ ((uint32 *) dst)[2] =
+ ((const uint32 *)src1)[2] ^ ((const uint32 *)
+ src2)[2];
+ ((uint32 *) dst)[3] =
+ ((const uint32 *)src1)[3] ^ ((const uint32 *)
+ src2)[3];
+ } else {
+ /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */
+ int k;
+ for (k = 0; k < 16; k++)
+ dst[k] = src1[k] ^ src2[k];
+ }
+ }
+
+/* externs */
+/* crc */
+ extern uint8 BCMROMFN(hndcrc8) (uint8 *p, uint nbytes, uint8 crc);
+ extern uint16 BCMROMFN(hndcrc16) (uint8 *p, uint nbytes, uint16 crc);
+/* format/print */
+#if defined(BCMDBG)
+ extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags,
+ char *buf, int len);
+ extern int bcm_format_hex(char *str, const void *bytes, int len);
+#endif
+#ifdef BCMDBG
+ extern void deadbeef(void *p, uint len);
+#endif
+ extern const char *bcm_crypto_algo_name(uint algo);
+ extern char *bcm_chipname(uint chipid, char *buf, uint len);
+ extern char *bcm_brev_str(uint32 brev, char *buf);
+ extern void printbig(char *buf);
+ extern void prhex(const char *msg, uchar *buf, uint len);
+
+/* IE parsing */
+ extern bcm_tlv_t *BCMROMFN(bcm_next_tlv) (bcm_tlv_t *elt, int *buflen);
+ extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs) (void *buf, int buflen,
+ uint key);
+ extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs) (void *buf,
+ int buflen,
+ uint key);
+
+/* bcmerror */
+ extern const char *bcmerrorstr(int bcmerror);
+
+/* multi-bool data type: set of bools, mbool is true if any is set */
+ typedef uint32 mbool;
+#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
+#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
+#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */
+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
+
+/* power conversion */
+ extern uint16 BCMROMFN(bcm_qdbm_to_mw) (uint8 qdbm);
+ extern uint8 BCMROMFN(bcm_mw_to_qdbm) (uint16 mw);
+
+/* generic datastruct to help dump routines */
+ struct fielddesc {
+ const char *nameandfmt;
+ uint32 offset;
+ uint32 len;
+ };
+
+ extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
+ extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
+ extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount);
+ extern int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes);
+ extern void bcm_print_bytes(char *name, const uchar *cdata, int len);
+
+ typedef uint32(*bcmutl_rdreg_rtn) (void *arg0, uint arg1,
+ uint32 offset);
+ extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0,
+ uint arg1, struct fielddesc *str, char *buf,
+ uint32 bufsize);
+
+ extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf,
+ uint len);
+ extern uint BCMROMFN(bcm_bitcount) (uint8 *bitmap, uint bytelength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _bcmutils_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h
new file mode 100644
index 000000000000..80c48f6e2919
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmwifi.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _bcmwifi_h_
+#define _bcmwifi_h_
+
+/* A chanspec holds the channel number, band, bandwidth and control sideband */
+typedef uint16 chanspec_t;
+
+/* channel defines */
+#define CH_UPPER_SB 0x01
+#define CH_LOWER_SB 0x02
+#define CH_EWA_VALID 0x04
+#define CH_20MHZ_APART 4
+#define CH_10MHZ_APART 2
+#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
+#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
+#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */
+#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216,
+ * this is that + 1 rounded up to a multiple of NBBY (8).
+ * DO NOT MAKE it > 255: channels are uint8's all over
+ */
+
+#define WL_CHANSPEC_CHAN_MASK 0x00ff
+#define WL_CHANSPEC_CHAN_SHIFT 0
+
+#define WL_CHANSPEC_CTL_SB_MASK 0x0300
+#define WL_CHANSPEC_CTL_SB_SHIFT 8
+#define WL_CHANSPEC_CTL_SB_LOWER 0x0100
+#define WL_CHANSPEC_CTL_SB_UPPER 0x0200
+#define WL_CHANSPEC_CTL_SB_NONE 0x0300
+
+#define WL_CHANSPEC_BW_MASK 0x0C00
+#define WL_CHANSPEC_BW_SHIFT 10
+#define WL_CHANSPEC_BW_10 0x0400
+#define WL_CHANSPEC_BW_20 0x0800
+#define WL_CHANSPEC_BW_40 0x0C00
+
+#define WL_CHANSPEC_BAND_MASK 0xf000
+#define WL_CHANSPEC_BAND_SHIFT 12
+#define WL_CHANSPEC_BAND_5G 0x1000
+#define WL_CHANSPEC_BAND_2G 0x2000
+#define INVCHANSPEC 255
+
+/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
+#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
+#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
+#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
+
+/* channel defines */
+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
+ ((channel) + CH_10MHZ_APART) : 0)
+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
+ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
+ ((channel) + CH_20MHZ_APART) : 0)
+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
+ WL_CHANSPEC_BAND_5G))
+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
+
+#ifdef WL11N_20MHZONLY
+
+#define CHSPEC_CTL_SB(chspec) WL_CHANSPEC_CTL_SB_NONE
+#define CHSPEC_BW(chspec) WL_CHANSPEC_BW_20
+#define CHSPEC_IS10(chspec) 0
+#define CHSPEC_IS20(chspec) 1
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) 0
+#endif
+
+#else /* !WL11N_20MHZONLY */
+
+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
+#endif
+
+#endif /* !WL11N_20MHZONLY */
+
+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
+#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
+#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
+#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
+#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \
+ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
+ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
+
+#define CHANSPEC_STR_LEN 8
+
+/* defined rate in 500kbps */
+#define WLC_MAXRATE 108 /* in 500kbps units */
+#define WLC_RATE_1M 2 /* in 500kbps units */
+#define WLC_RATE_2M 4 /* in 500kbps units */
+#define WLC_RATE_5M5 11 /* in 500kbps units */
+#define WLC_RATE_11M 22 /* in 500kbps units */
+#define WLC_RATE_6M 12 /* in 500kbps units */
+#define WLC_RATE_9M 18 /* in 500kbps units */
+#define WLC_RATE_12M 24 /* in 500kbps units */
+#define WLC_RATE_18M 36 /* in 500kbps units */
+#define WLC_RATE_24M 48 /* in 500kbps units */
+#define WLC_RATE_36M 72 /* in 500kbps units */
+#define WLC_RATE_48M 96 /* in 500kbps units */
+#define WLC_RATE_54M 108 /* in 500kbps units */
+
+#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
+
+/*
+ * Convert chanspec to ascii string
+ * @param chspec chanspec format
+ * @param buf ascii string of chanspec
+ * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes
+ */
+extern char *wf_chspec_ntoa(chanspec_t chspec, char *buf);
+
+/*
+ * Convert ascii string to chanspec
+ * @param a pointer to input string
+ * @return >= 0 if successful or 0 otherwise
+ */
+extern chanspec_t wf_chspec_aton(char *a);
+
+/*
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, ctl_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good.
+ */
+extern bool wf_chspec_malformed(chanspec_t chanspec);
+
+/*
+ * This function returns the channel number that control traffic is being sent on, for legacy
+ * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+ * sideband depending on the chanspec selected
+ */
+extern uint8 wf_chspec_ctlchan(chanspec_t chspec);
+
+/*
+ * This function returns the chanspec that control traffic is being sent on, for legacy
+ * channels this is just the chanspec, for 40MHZ channels it is the upper or lowre 20MHZ
+ * sideband depending on the chanspec selected
+ */
+extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec);
+
+/*
+ * Return the channel number for a given frequency and base frequency.
+ * The returned channel number is relative to the given base frequency.
+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+ *
+ * Frequency is specified in MHz.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ *
+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+ * and [0, 200] otherwise.
+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+extern int wf_mhz2channel(uint freq, uint start_factor);
+
+/*
+ * Return the center frequency in MHz of the given channel and base frequency.
+ * The channel number is interpreted relative to the given base frequency.
+ *
+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ * The channel range of [1, 14] is only checked for a start_factor of
+ * WF_CHAN_FACTOR_2_4_G (4814).
+ * Odd start_factors produce channels on .5 MHz boundaries, in which case
+ * the answer is rounded down to an integral MHz.
+ * -1 is returned for an out of range channel.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+extern int wf_channel2mhz(uint channel, uint start_factor);
+
+#endif /* _bcmwifi_h_ */
diff --git a/drivers/staging/brcm80211/include/bcmwpa.h b/drivers/staging/brcm80211/include/bcmwpa.h
new file mode 100644
index 000000000000..d384bd66ff42
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bcmwpa.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCMWPA_H_
+#define _BCMWPA_H_
+
+#include <proto/wpa.h>
+#include <proto/802.11.h>
+#include <wlioctl.h>
+
+/* Field sizes for WPA key hierarchy */
+#define WPA_MIC_KEY_LEN 16
+#define WPA_ENCR_KEY_LEN 16
+#define WPA_TEMP_ENCR_KEY_LEN 16
+#define WPA_TEMP_TX_KEY_LEN 8
+#define WPA_TEMP_RX_KEY_LEN 8
+
+#define PMK_LEN 32
+#define TKIP_PTK_LEN 64
+#define TKIP_TK_LEN 32
+#define AES_PTK_LEN 48
+#define AES_TK_LEN 16
+
+/* limits for pre-shared key lengths */
+#define WPA_MIN_PSK_LEN 8
+#define WPA_MAX_PSK_LEN 64
+
+#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \
+ ((bsscfg)->wsec & WSEC_SWFLAG)))
+
+#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED)
+#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED)
+#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED)
+#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED)
+#define IS_WPA_AUTH(auth) ((auth) == WPA_AUTH_NONE || \
+ (auth) == WPA_AUTH_UNSPECIFIED || \
+ (auth) == WPA_AUTH_PSK)
+#define INCLUDES_WPA_AUTH(auth) \
+ ((auth) & (WPA_AUTH_NONE | WPA_AUTH_UNSPECIFIED | WPA_AUTH_PSK))
+
+#define IS_WPA2_AUTH(auth) ((auth) == WPA2_AUTH_UNSPECIFIED || \
+ (auth) == WPA2_AUTH_PSK)(
+#define INCLUDES_WPA2_AUTH(auth) \
+ ((auth) & (WPA2_AUTH_UNSPECIFIED | \
+ WPA2_AUTH_PSK))
+
+#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
+ (akm) == RSN_AKM_UNSPECIFIED || \
+ (akm) == RSN_AKM_PSK)
+#define IS_WPA2_AKM(akm) ((akm) == RSN_AKM_UNSPECIFIED || \
+ (akm) == RSN_AKM_PSK)
+
+#define MAX_ARRAY 1
+#define MIN_ARRAY 0
+
+/* convert wsec to WPA mcast cipher. algo is needed only when WEP is enabled. */
+#define WPA_MCAST_CIPHER(wsec, algo) (WSEC_WEP_ENABLED(wsec) ? \
+ ((algo) == CRYPTO_ALGO_WEP128 ? WPA_CIPHER_WEP_104 : WPA_CIPHER_WEP_40) : \
+ WSEC_TKIP_ENABLED(wsec) ? WPA_CIPHER_TKIP : \
+ WSEC_AES_ENABLED(wsec) ? WPA_CIPHER_AES_CCM : \
+ WPA_CIPHER_NONE)
+
+/* Look for a WPA IE; return it's address if found, NULL otherwise */
+extern wpa_ie_fixed_t *BCMROMFN(bcm_find_wpaie) (uint8 *parse, uint len);
+
+/* Check whether the given IE looks like WFA IE with the specific type. */
+extern bool bcm_is_wfa_ie(uint8 *ie, uint8 **tlvs, uint *tlvs_len,
+ uint8 type);
+/* Check whether pointed-to IE looks like WPA. */
+#define bcm_is_wpa_ie(ie, tlvs, len) bcm_is_wfa_ie(ie, tlvs, len, WFA_OUI_TYPE_WPA)
+
+#endif /* _BCMWPA_H_ */
diff --git a/drivers/staging/brcm80211/include/bitfuncs.h b/drivers/staging/brcm80211/include/bitfuncs.h
new file mode 100644
index 000000000000..28940d905306
--- /dev/null
+++ b/drivers/staging/brcm80211/include/bitfuncs.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BITFUNCS_H
+#define _BITFUNCS_H
+
+#include <typedefs.h>
+
+/* local prototypes */
+static INLINE uint32 find_msbit(uint32 x);
+
+/*
+ * find_msbit: returns index of most significant set bit in x, with index
+ * range defined as 0-31. NOTE: returns zero if input is zero.
+ */
+
+#if defined(USE_PENTIUM_BSR) && defined(__GNUC__)
+
+/*
+ * Implementation for Pentium processors and gcc. Note that this
+ * instruction is actually very slow on some processors (e.g., family 5,
+ * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic
+ * implementation instead.
+ */
+static INLINE uint32 find_msbit(uint32 x)
+{
+ uint msbit;
+ __asm__("bsrl %1,%0" : "=r"(msbit)
+ : "r"(x));
+ return msbit;
+}
+
+#else /* !USE_PENTIUM_BSR || !__GNUC__ */
+
+/*
+ * Generic Implementation
+ */
+
+#define DB_POW_MASK16 0xffff0000
+#define DB_POW_MASK8 0x0000ff00
+#define DB_POW_MASK4 0x000000f0
+#define DB_POW_MASK2 0x0000000c
+#define DB_POW_MASK1 0x00000002
+
+static INLINE uint32 find_msbit(uint32 x)
+{
+ uint32 temp_x = x;
+ uint msbit = 0;
+ if (temp_x & DB_POW_MASK16) {
+ temp_x >>= 16;
+ msbit = 16;
+ }
+ if (temp_x & DB_POW_MASK8) {
+ temp_x >>= 8;
+ msbit += 8;
+ }
+ if (temp_x & DB_POW_MASK4) {
+ temp_x >>= 4;
+ msbit += 4;
+ }
+ if (temp_x & DB_POW_MASK2) {
+ temp_x >>= 2;
+ msbit += 2;
+ }
+ if (temp_x & DB_POW_MASK1) {
+ msbit += 1;
+ }
+ return msbit;
+}
+
+#endif /* USE_PENTIUM_BSR && __GNUC__ */
+
+#endif /* _BITFUNCS_H */
diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h
new file mode 100644
index 000000000000..f17ea8cba07b
--- /dev/null
+++ b/drivers/staging/brcm80211/include/d11.h
@@ -0,0 +1,1778 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _D11_H
+#define _D11_H
+
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <proto/802.11.h>
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+#ifndef WL_RSSI_ANT_MAX
+#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
+#elif WL_RSSI_ANT_MAX != 4
+#error "WL_RSSI_ANT_MAX does not match"
+#endif
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif
+
+#define BCN_TMPL_LEN 512 /* length of the BCN template area */
+
+/* RX FIFO numbers */
+#define RX_FIFO 0 /* data and ctl frames */
+#define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */
+
+/* TX FIFO numbers using WME Access Classes */
+#define TX_AC_BK_FIFO 0 /* Access Category Background TX FIFO */
+#define TX_AC_BE_FIFO 1 /* Access Category Best-Effort TX FIFO */
+#define TX_AC_VI_FIFO 2 /* Access Class Video TX FIFO */
+#define TX_AC_VO_FIFO 3 /* Access Class Voice TX FIFO */
+#define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */
+#define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */
+
+/* Addr is byte address used by SW; offset is word offset used by uCode */
+
+/* Per AC TX limit settings */
+#define M_AC_TXLMT_BASE_ADDR (0x180 * 2)
+#define M_AC_TXLMT_ADDR(_ac) (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
+
+/* Legacy TX FIFO numbers */
+#define TX_DATA_FIFO TX_AC_BE_FIFO
+#define TX_CTL_FIFO TX_AC_VO_FIFO
+
+typedef volatile struct {
+ uint32 intstatus;
+ uint32 intmask;
+} intctrlregs_t;
+
+/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
+ * write: only low 16b-it half can be written
+ */
+typedef volatile union {
+ uint32 pmqhostdata; /* read only! */
+ struct {
+ uint16 pmqctrlstatus; /* read/write */
+ uint16 PAD;
+ } w;
+} pmqreg_t;
+
+/* pio register set 2/4 bytes union for d11 fifo */
+typedef volatile union {
+ pio2regp_t b2; /* < corerev 8 */
+ pio4regp_t b4; /* >= corerev 8 */
+} u_pioreg_t;
+
+/* dma/pio corerev < 11 */
+typedef volatile struct {
+ dma32regp_t dmaregs[8]; /* 0x200 - 0x2fc */
+ u_pioreg_t pioregs[8]; /* 0x300 */
+} fifo32_t;
+
+/* dma/pio corerev >= 11 */
+typedef volatile struct {
+ dma64regs_t dmaxmt; /* dma tx */
+ pio4regs_t piotx; /* pio tx */
+ dma64regs_t dmarcv; /* dma rx */
+ pio4regs_t piorx; /* pio rx */
+} fifo64_t;
+
+/*
+ * Host Interface Registers
+ * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h
+ * - but definitely not complete
+ */
+typedef volatile struct _d11regs {
+ /* Device Control ("semi-standard host registers") */
+ uint32 PAD[3]; /* 0x0 - 0x8 */
+ uint32 biststatus; /* 0xC */
+ uint32 biststatus2; /* 0x10 */
+ uint32 PAD; /* 0x14 */
+ uint32 gptimer; /* 0x18 *//* for corerev >= 3 */
+ uint32 usectimer; /* 0x1c *//* for corerev >= 26 */
+
+ /* Interrupt Control *//* 0x20 */
+ intctrlregs_t intctrlregs[8];
+
+ uint32 PAD[40]; /* 0x60 - 0xFC */
+
+ /* tx fifos 6-7 and rx fifos 1-3 removed in corerev 5 */
+ uint32 intrcvlazy[4]; /* 0x100 - 0x10C */
+
+ uint32 PAD[4]; /* 0x110 - 0x11c */
+
+ uint32 maccontrol; /* 0x120 */
+ uint32 maccommand; /* 0x124 */
+ uint32 macintstatus; /* 0x128 */
+ uint32 macintmask; /* 0x12C */
+
+ /* Transmit Template Access */
+ uint32 tplatewrptr; /* 0x130 */
+ uint32 tplatewrdata; /* 0x134 */
+ uint32 PAD[2]; /* 0x138 - 0x13C */
+
+ /* PMQ registers */
+ pmqreg_t pmqreg; /* 0x140 */
+ uint32 pmqpatl; /* 0x144 */
+ uint32 pmqpath; /* 0x148 */
+ uint32 PAD; /* 0x14C */
+
+ uint32 chnstatus; /* 0x150 */
+ uint32 psmdebug; /* 0x154 *//* for corerev >= 3 */
+ uint32 phydebug; /* 0x158 *//* for corerev >= 3 */
+ uint32 machwcap; /* 0x15C *//* Corerev >= 13 */
+
+ /* Extended Internal Objects */
+ uint32 objaddr; /* 0x160 */
+ uint32 objdata; /* 0x164 */
+ uint32 PAD[2]; /* 0x168 - 0x16c */
+
+ /* New txstatus registers on corerev >= 5 */
+ uint32 frmtxstatus; /* 0x170 */
+ uint32 frmtxstatus2; /* 0x174 */
+ uint32 PAD[2]; /* 0x178 - 0x17c */
+
+ /* New TSF host access on corerev >= 3 */
+
+ uint32 tsf_timerlow; /* 0x180 */
+ uint32 tsf_timerhigh; /* 0x184 */
+ uint32 tsf_cfprep; /* 0x188 */
+ uint32 tsf_cfpstart; /* 0x18c */
+ uint32 tsf_cfpmaxdur32; /* 0x190 */
+ uint32 PAD[3]; /* 0x194 - 0x19c */
+
+ uint32 maccontrol1; /* 0x1a0 */
+ uint32 machwcap1; /* 0x1a4 */
+ uint32 PAD[14]; /* 0x1a8 - 0x1dc */
+
+ /* Clock control and hardware workarounds (corerev >= 13) */
+ uint32 clk_ctl_st; /* 0x1e0 */
+ uint32 hw_war;
+ uint32 d11_phypllctl; /* 0x1e8 (corerev == 16), the phypll request/avail bits are
+ * moved to clk_ctl_st for corerev >= 17
+ */
+ uint32 PAD[5]; /* 0x1ec - 0x1fc */
+
+ /* 0x200-0x37F dma/pio registers */
+ volatile union {
+ fifo32_t f32regs; /* tx fifos 6-7 and rx fifos 1-3 (corerev < 5) */
+ fifo64_t f64regs[6]; /* on corerev >= 11 */
+ } fifo;
+
+ /* FIFO diagnostic port access */
+ dma32diag_t dmafifo; /* 0x380 - 0x38C */
+
+ uint32 aggfifocnt; /* 0x390 */
+ uint32 aggfifodata; /* 0x394 */
+ uint32 PAD[16]; /* 0x398 - 0x3d4 */
+ uint16 radioregaddr; /* 0x3d8 */
+ uint16 radioregdata; /* 0x3da */
+
+ /* time delay between the change on rf disable input and radio shutdown corerev 10 */
+ uint32 rfdisabledly; /* 0x3DC */
+
+ /* PHY register access */
+ uint16 phyversion; /* 0x3e0 - 0x0 */
+ uint16 phybbconfig; /* 0x3e2 - 0x1 */
+ uint16 phyadcbias; /* 0x3e4 - 0x2 Bphy only */
+ uint16 phyanacore; /* 0x3e6 - 0x3 pwwrdwn on aphy */
+ uint16 phyrxstatus0; /* 0x3e8 - 0x4 */
+ uint16 phyrxstatus1; /* 0x3ea - 0x5 */
+ uint16 phycrsth; /* 0x3ec - 0x6 */
+ uint16 phytxerror; /* 0x3ee - 0x7 */
+ uint16 phychannel; /* 0x3f0 - 0x8 */
+ uint16 PAD[1]; /* 0x3f2 - 0x9 */
+ uint16 phytest; /* 0x3f4 - 0xa */
+ uint16 phy4waddr; /* 0x3f6 - 0xb */
+ uint16 phy4wdatahi; /* 0x3f8 - 0xc */
+ uint16 phy4wdatalo; /* 0x3fa - 0xd */
+ uint16 phyregaddr; /* 0x3fc - 0xe */
+ uint16 phyregdata; /* 0x3fe - 0xf */
+
+ /* IHR *//* 0x400 - 0x7FE */
+
+ /* RXE Block */
+ uint16 PAD[3]; /* 0x400 - 0x406 */
+ uint16 rcv_fifo_ctl; /* 0x406 */
+ uint16 PAD; /* 0x408 - 0x40a */
+ uint16 rcv_frm_cnt; /* 0x40a */
+ uint16 PAD[4]; /* 0x40a - 0x414 */
+ uint16 rssi; /* 0x414 */
+ uint16 PAD[5]; /* 0x414 - 0x420 */
+ uint16 rcm_ctl; /* 0x420 */
+ uint16 rcm_mat_data; /* 0x422 */
+ uint16 rcm_mat_mask; /* 0x424 */
+ uint16 rcm_mat_dly; /* 0x426 */
+ uint16 rcm_cond_mask_l; /* 0x428 */
+ uint16 rcm_cond_mask_h; /* 0x42A */
+ uint16 rcm_cond_dly; /* 0x42C */
+ uint16 PAD[1]; /* 0x42E */
+ uint16 ext_ihr_addr; /* 0x430 */
+ uint16 ext_ihr_data; /* 0x432 */
+ uint16 rxe_phyrs_2; /* 0x434 */
+ uint16 rxe_phyrs_3; /* 0x436 */
+ uint16 phy_mode; /* 0x438 */
+ uint16 rcmta_ctl; /* 0x43a */
+ uint16 rcmta_size; /* 0x43c */
+ uint16 rcmta_addr0; /* 0x43e */
+ uint16 rcmta_addr1; /* 0x440 */
+ uint16 rcmta_addr2; /* 0x442 */
+ uint16 PAD[30]; /* 0x444 - 0x480 */
+
+ /* PSM Block *//* 0x480 - 0x500 */
+
+ uint16 PAD; /* 0x480 */
+ uint16 psm_maccontrol_h; /* 0x482 */
+ uint16 psm_macintstatus_l; /* 0x484 */
+ uint16 psm_macintstatus_h; /* 0x486 */
+ uint16 psm_macintmask_l; /* 0x488 */
+ uint16 psm_macintmask_h; /* 0x48A */
+ uint16 PAD; /* 0x48C */
+ uint16 psm_maccommand; /* 0x48E */
+ uint16 psm_brc; /* 0x490 */
+ uint16 psm_phy_hdr_param; /* 0x492 */
+ uint16 psm_postcard; /* 0x494 */
+ uint16 psm_pcard_loc_l; /* 0x496 */
+ uint16 psm_pcard_loc_h; /* 0x498 */
+ uint16 psm_gpio_in; /* 0x49A */
+ uint16 psm_gpio_out; /* 0x49C */
+ uint16 psm_gpio_oe; /* 0x49E */
+
+ uint16 psm_bred_0; /* 0x4A0 */
+ uint16 psm_bred_1; /* 0x4A2 */
+ uint16 psm_bred_2; /* 0x4A4 */
+ uint16 psm_bred_3; /* 0x4A6 */
+ uint16 psm_brcl_0; /* 0x4A8 */
+ uint16 psm_brcl_1; /* 0x4AA */
+ uint16 psm_brcl_2; /* 0x4AC */
+ uint16 psm_brcl_3; /* 0x4AE */
+ uint16 psm_brpo_0; /* 0x4B0 */
+ uint16 psm_brpo_1; /* 0x4B2 */
+ uint16 psm_brpo_2; /* 0x4B4 */
+ uint16 psm_brpo_3; /* 0x4B6 */
+ uint16 psm_brwk_0; /* 0x4B8 */
+ uint16 psm_brwk_1; /* 0x4BA */
+ uint16 psm_brwk_2; /* 0x4BC */
+ uint16 psm_brwk_3; /* 0x4BE */
+
+ uint16 psm_base_0; /* 0x4C0 */
+ uint16 psm_base_1; /* 0x4C2 */
+ uint16 psm_base_2; /* 0x4C4 */
+ uint16 psm_base_3; /* 0x4C6 */
+ uint16 psm_base_4; /* 0x4C8 */
+ uint16 psm_base_5; /* 0x4CA */
+ uint16 psm_base_6; /* 0x4CC */
+ uint16 psm_pc_reg_0; /* 0x4CE */
+ uint16 psm_pc_reg_1; /* 0x4D0 */
+ uint16 psm_pc_reg_2; /* 0x4D2 */
+ uint16 psm_pc_reg_3; /* 0x4D4 */
+ uint16 PAD[0xD]; /* 0x4D6 - 0x4DE */
+ uint16 psm_corectlsts; /* 0x4f0 *//* Corerev >= 13 */
+ uint16 PAD[0x7]; /* 0x4f2 - 0x4fE */
+
+ /* TXE0 Block *//* 0x500 - 0x580 */
+ uint16 txe_ctl; /* 0x500 */
+ uint16 txe_aux; /* 0x502 */
+ uint16 txe_ts_loc; /* 0x504 */
+ uint16 txe_time_out; /* 0x506 */
+ uint16 txe_wm_0; /* 0x508 */
+ uint16 txe_wm_1; /* 0x50A */
+ uint16 txe_phyctl; /* 0x50C */
+ uint16 txe_status; /* 0x50E */
+ uint16 txe_mmplcp0; /* 0x510 */
+ uint16 txe_mmplcp1; /* 0x512 */
+ uint16 txe_phyctl1; /* 0x514 */
+
+ uint16 PAD[0x05]; /* 0x510 - 0x51E */
+
+ /* Transmit control */
+ uint16 xmtfifodef; /* 0x520 */
+ uint16 xmtfifo_frame_cnt; /* 0x522 *//* Corerev >= 16 */
+ uint16 xmtfifo_byte_cnt; /* 0x524 *//* Corerev >= 16 */
+ uint16 xmtfifo_head; /* 0x526 *//* Corerev >= 16 */
+ uint16 xmtfifo_rd_ptr; /* 0x528 *//* Corerev >= 16 */
+ uint16 xmtfifo_wr_ptr; /* 0x52A *//* Corerev >= 16 */
+ uint16 xmtfifodef1; /* 0x52C *//* Corerev >= 16 */
+
+ uint16 PAD[0x09]; /* 0x52E - 0x53E */
+
+ uint16 xmtfifocmd; /* 0x540 */
+ uint16 xmtfifoflush; /* 0x542 */
+ uint16 xmtfifothresh; /* 0x544 */
+ uint16 xmtfifordy; /* 0x546 */
+ uint16 xmtfifoprirdy; /* 0x548 */
+ uint16 xmtfiforqpri; /* 0x54A */
+ uint16 xmttplatetxptr; /* 0x54C */
+ uint16 PAD; /* 0x54E */
+ uint16 xmttplateptr; /* 0x550 */
+ uint16 smpl_clct_strptr; /* 0x552 *//* Corerev >= 22 */
+ uint16 smpl_clct_stpptr; /* 0x554 *//* Corerev >= 22 */
+ uint16 smpl_clct_curptr; /* 0x556 *//* Corerev >= 22 */
+ uint16 PAD[0x04]; /* 0x558 - 0x55E */
+ uint16 xmttplatedatalo; /* 0x560 */
+ uint16 xmttplatedatahi; /* 0x562 */
+
+ uint16 PAD[2]; /* 0x564 - 0x566 */
+
+ uint16 xmtsel; /* 0x568 */
+ uint16 xmttxcnt; /* 0x56A */
+ uint16 xmttxshmaddr; /* 0x56C */
+
+ uint16 PAD[0x09]; /* 0x56E - 0x57E */
+
+ /* TXE1 Block */
+ uint16 PAD[0x40]; /* 0x580 - 0x5FE */
+
+ /* TSF Block */
+ uint16 PAD[0X02]; /* 0x600 - 0x602 */
+ uint16 tsf_cfpstrt_l; /* 0x604 */
+ uint16 tsf_cfpstrt_h; /* 0x606 */
+ uint16 PAD[0X05]; /* 0x608 - 0x610 */
+ uint16 tsf_cfppretbtt; /* 0x612 */
+ uint16 PAD[0XD]; /* 0x614 - 0x62C */
+ uint16 tsf_clk_frac_l; /* 0x62E */
+ uint16 tsf_clk_frac_h; /* 0x630 */
+ uint16 PAD[0X14]; /* 0x632 - 0x658 */
+ uint16 tsf_random; /* 0x65A */
+ uint16 PAD[0x05]; /* 0x65C - 0x664 */
+ /* GPTimer 2 registers are corerev >= 3 */
+ uint16 tsf_gpt2_stat; /* 0x666 */
+ uint16 tsf_gpt2_ctr_l; /* 0x668 */
+ uint16 tsf_gpt2_ctr_h; /* 0x66A */
+ uint16 tsf_gpt2_val_l; /* 0x66C */
+ uint16 tsf_gpt2_val_h; /* 0x66E */
+ uint16 tsf_gptall_stat; /* 0x670 */
+ uint16 PAD[0x07]; /* 0x672 - 0x67E */
+
+ /* IFS Block */
+ uint16 ifs_sifs_rx_tx_tx; /* 0x680 */
+ uint16 ifs_sifs_nav_tx; /* 0x682 */
+ uint16 ifs_slot; /* 0x684 */
+ uint16 PAD; /* 0x686 */
+ uint16 ifs_ctl; /* 0x688 */
+ uint16 PAD[0x3]; /* 0x68a - 0x68F */
+ uint16 ifsstat; /* 0x690 */
+ uint16 ifsmedbusyctl; /* 0x692 */
+ uint16 iftxdur; /* 0x694 */
+ uint16 PAD[0x3]; /* 0x696 - 0x69b */
+ /* EDCF support in dot11macs with corerevs >= 16 */
+ uint16 ifs_aifsn; /* 0x69c */
+ uint16 ifs_ctl1; /* 0x69e */
+
+ /* New slow clock registers on corerev >= 5 */
+ uint16 scc_ctl; /* 0x6a0 */
+ uint16 scc_timer_l; /* 0x6a2 */
+ uint16 scc_timer_h; /* 0x6a4 */
+ uint16 scc_frac; /* 0x6a6 */
+ uint16 scc_fastpwrup_dly; /* 0x6a8 */
+ uint16 scc_per; /* 0x6aa */
+ uint16 scc_per_frac; /* 0x6ac */
+ uint16 scc_cal_timer_l; /* 0x6ae */
+ uint16 scc_cal_timer_h; /* 0x6b0 */
+ uint16 PAD; /* 0x6b2 */
+
+ uint16 PAD[0x26];
+
+ /* NAV Block */
+ uint16 nav_ctl; /* 0x700 */
+ uint16 navstat; /* 0x702 */
+ uint16 PAD[0x3e]; /* 0x702 - 0x77E */
+
+ /* WEP/PMQ Block *//* 0x780 - 0x7FE */
+ uint16 PAD[0x20]; /* 0x780 - 0x7BE */
+
+ uint16 wepctl; /* 0x7C0 */
+ uint16 wepivloc; /* 0x7C2 */
+ uint16 wepivkey; /* 0x7C4 */
+ uint16 wepwkey; /* 0x7C6 */
+
+ uint16 PAD[4]; /* 0x7C8 - 0x7CE */
+ uint16 pcmctl; /* 0X7D0 */
+ uint16 pcmstat; /* 0X7D2 */
+ uint16 PAD[6]; /* 0x7D4 - 0x7DE */
+
+ uint16 pmqctl; /* 0x7E0 */
+ uint16 pmqstatus; /* 0x7E2 */
+ uint16 pmqpat0; /* 0x7E4 */
+ uint16 pmqpat1; /* 0x7E6 */
+ uint16 pmqpat2; /* 0x7E8 */
+
+ uint16 pmqdat; /* 0x7EA */
+ uint16 pmqdator; /* 0x7EC */
+ uint16 pmqhst; /* 0x7EE */
+ uint16 pmqpath0; /* 0x7F0 */
+ uint16 pmqpath1; /* 0x7F2 */
+ uint16 pmqpath2; /* 0x7F4 */
+ uint16 pmqdath; /* 0x7F6 */
+
+ uint16 PAD[0x04]; /* 0x7F8 - 0x7FE */
+
+ /* SHM *//* 0x800 - 0xEFE */
+ uint16 PAD[0x380]; /* 0x800 - 0xEFE */
+
+ /* SB configuration registers: 0xF00 */
+ sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */
+} d11regs_t;
+
+#define PIHR_BASE 0x0400 /* byte address of packed IHR region */
+
+/* biststatus */
+#define BT_DONE (1U << 31) /* bist done */
+#define BT_B2S (1 << 30) /* bist2 ram summary bit */
+
+/* intstatus and intmask */
+#define I_PC (1 << 10) /* pci descriptor error */
+#define I_PD (1 << 11) /* pci data error */
+#define I_DE (1 << 12) /* descriptor protocol error */
+#define I_RU (1 << 13) /* receive descriptor underflow */
+#define I_RO (1 << 14) /* receive fifo overflow */
+#define I_XU (1 << 15) /* transmit fifo underflow */
+#define I_RI (1 << 16) /* receive interrupt */
+#define I_XI (1 << 24) /* transmit interrupt */
+
+/* interrupt receive lazy */
+#define IRL_TO_MASK 0x00ffffff /* timeout */
+#define IRL_FC_MASK 0xff000000 /* frame count */
+#define IRL_FC_SHIFT 24 /* frame count */
+
+/* maccontrol register */
+#define MCTL_GMODE (1U << 31)
+#define MCTL_DISCARD_PMQ (1 << 30)
+#define MCTL_WAKE (1 << 26)
+#define MCTL_HPS (1 << 25)
+#define MCTL_PROMISC (1 << 24)
+#define MCTL_KEEPBADFCS (1 << 23)
+#define MCTL_KEEPCONTROL (1 << 22)
+#define MCTL_PHYLOCK (1 << 21)
+#define MCTL_BCNS_PROMISC (1 << 20)
+#define MCTL_LOCK_RADIO (1 << 19)
+#define MCTL_AP (1 << 18)
+#define MCTL_INFRA (1 << 17)
+#define MCTL_BIGEND (1 << 16)
+#define MCTL_GPOUT_SEL_MASK (3 << 14)
+#define MCTL_GPOUT_SEL_SHIFT 14
+#define MCTL_EN_PSMDBG (1 << 13)
+#define MCTL_IHR_EN (1 << 10)
+#define MCTL_SHM_UPPER (1 << 9)
+#define MCTL_SHM_EN (1 << 8)
+#define MCTL_PSM_JMP_0 (1 << 2)
+#define MCTL_PSM_RUN (1 << 1)
+#define MCTL_EN_MAC (1 << 0)
+
+/* maccommand register */
+#define MCMD_BCN0VLD (1 << 0)
+#define MCMD_BCN1VLD (1 << 1)
+#define MCMD_DIRFRMQVAL (1 << 2)
+#define MCMD_CCA (1 << 3)
+#define MCMD_BG_NOISE (1 << 4)
+#define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */
+#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */
+
+/* macintstatus/macintmask */
+#define MI_MACSSPNDD (1 << 0) /* MAC has gracefully suspended */
+#define MI_BCNTPL (1 << 1) /* beacon template available */
+#define MI_TBTT (1 << 2) /* TBTT indication */
+#define MI_BCNSUCCESS (1 << 3) /* beacon successfully tx'd */
+#define MI_BCNCANCLD (1 << 4) /* beacon canceled (IBSS) */
+#define MI_ATIMWINEND (1 << 5) /* end of ATIM-window (IBSS) */
+#define MI_PMQ (1 << 6) /* PMQ entries available */
+#define MI_NSPECGEN_0 (1 << 7) /* non-specific gen-stat bits that are set by PSM */
+#define MI_NSPECGEN_1 (1 << 8) /* non-specific gen-stat bits that are set by PSM */
+#define MI_MACTXERR (1 << 9) /* MAC level Tx error */
+#define MI_NSPECGEN_3 (1 << 10) /* non-specific gen-stat bits that are set by PSM */
+#define MI_PHYTXERR (1 << 11) /* PHY Tx error */
+#define MI_PME (1 << 12) /* Power Management Event */
+#define MI_GP0 (1 << 13) /* General-purpose timer0 */
+#define MI_GP1 (1 << 14) /* General-purpose timer1 */
+#define MI_DMAINT (1 << 15) /* (ORed) DMA-interrupts */
+#define MI_TXSTOP (1 << 16) /* MAC has completed a TX FIFO Suspend/Flush */
+#define MI_CCA (1 << 17) /* MAC has completed a CCA measurement */
+#define MI_BG_NOISE (1 << 18) /* MAC has collected background noise samples */
+#define MI_DTIM_TBTT (1 << 19) /* MBSS DTIM TBTT indication */
+#define MI_PRQ (1 << 20) /* Probe response queue needs attention */
+#define MI_PWRUP (1 << 21) /* Radio/PHY has been powered back up. */
+#define MI_RESERVED3 (1 << 22)
+#define MI_RESERVED2 (1 << 23)
+#define MI_RESERVED1 (1 << 25)
+#define MI_RFDISABLE (1 << 28) /* MAC detected a change on RF Disable input
+ * (corerev >= 10)
+ */
+#define MI_TFS (1 << 29) /* MAC has completed a TX (corerev >= 5) */
+#define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */
+#define MI_TO (1U << 31) /* general purpose timeout (corerev >= 3) */
+
+/* Mac capabilities registers */
+/* machwcap */
+#define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */
+
+/* pmqhost data */
+#define PMQH_DATA_MASK 0xffff0000 /* data entry of head pmq entry */
+#define PMQH_BSSCFG 0x00100000 /* PM entry for BSS config */
+#define PMQH_PMOFF 0x00010000 /* PM Mode OFF: power save off */
+#define PMQH_PMON 0x00020000 /* PM Mode ON: power save on */
+#define PMQH_DASAT 0x00040000 /* Dis-associated or De-authenticated */
+#define PMQH_ATIMFAIL 0x00080000 /* ATIM not acknowledged */
+#define PMQH_DEL_ENTRY 0x00000001 /* delete head entry */
+#define PMQH_DEL_MULT 0x00000002 /* delete head entry to cur read pointer -1 */
+#define PMQH_OFLO 0x00000004 /* pmq overflow indication */
+#define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */
+
+/* phydebug (corerev >= 3) */
+#define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */
+#define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */
+#define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */
+#define PDBG_TXE (1 << 3) /* phy is signalling a transmit Error to the mac */
+#define PDBG_RXF (1 << 4) /* phy detected the end of a valid frame preamble */
+#define PDBG_RXS (1 << 5) /* phy detected the end of a valid PLCP header */
+#define PDBG_RXFRG (1 << 6) /* rx start not asserted */
+#define PDBG_RXV (1 << 7) /* mac is taking receive byte from phy this cycle */
+#define PDBG_RFD (1 << 16) /* RF portion of the radio is disabled */
+
+/* objaddr register */
+#define OBJADDR_SEL_MASK 0x000F0000
+#define OBJADDR_UCM_SEL 0x00000000
+#define OBJADDR_SHM_SEL 0x00010000
+#define OBJADDR_SCR_SEL 0x00020000
+#define OBJADDR_IHR_SEL 0x00030000
+#define OBJADDR_RCMTA_SEL 0x00040000
+#define OBJADDR_SRCHM_SEL 0x00060000
+#define OBJADDR_WINC 0x01000000
+#define OBJADDR_RINC 0x02000000
+#define OBJADDR_AUTO_INC 0x03000000
+
+#define WEP_PCMADDR 0x07d4
+#define WEP_PCMDATA 0x07d6
+
+/* frmtxstatus */
+#define TXS_V (1 << 0) /* valid bit */
+#define TXS_STATUS_MASK 0xffff
+/* sw mask to map txstatus for corerevs <= 4 to be the same as for corerev > 4 */
+#define TXS_COMPAT_MASK 0x3
+#define TXS_COMPAT_SHIFT 1
+#define TXS_FID_MASK 0xffff0000
+#define TXS_FID_SHIFT 16
+
+/* frmtxstatus2 */
+#define TXS_SEQ_MASK 0xffff
+#define TXS_PTX_MASK 0xff0000
+#define TXS_PTX_SHIFT 16
+#define TXS_MU_MASK 0x01000000
+#define TXS_MU_SHIFT 24
+
+/* clk_ctl_st, corerev >= 17 */
+#define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */
+#define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */
+#define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */
+#define CCS_ERSRC_AVAIL_PHYPLL 0x02000000 /* PHY pll available */
+
+/* HT Cloclk Ctrl and Clock Avail for 4313 */
+#define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */
+#define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */
+
+/* d11_pwrctl, corerev16 only */
+#define D11_PHYPLL_AVAIL_REQ 0x000010000 /* request PHY PLL resource */
+#define D11_PHYPLL_AVAIL_STS 0x001000000 /* PHY PLL is available */
+
+/* tsf_cfprep register */
+#define CFPREP_CBI_MASK 0xffffffc0
+#define CFPREP_CBI_SHIFT 6
+#define CFPREP_CFPP 0x00000001
+
+/* tx fifo sizes for corerev >= 9 */
+/* tx fifo sizes values are in terms of 256 byte blocks */
+#define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */
+#define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */
+#define TXFIFO_FIFOTOP_SHIFT 8 /* fifo start */
+
+#define TXFIFO_START_BLK16 65 /* Base address + 32 * 512 B/P */
+#define TXFIFO_START_BLK 6 /* Base address + 6 * 256 B */
+#define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */
+#define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */
+
+/* phy versions, PhyVersion:Revision field */
+#define PV_AV_MASK 0xf000 /* analog block version */
+#define PV_AV_SHIFT 12 /* analog block version bitfield offset */
+#define PV_PT_MASK 0x0f00 /* phy type */
+#define PV_PT_SHIFT 8 /* phy type bitfield offset */
+#define PV_PV_MASK 0x000f /* phy version */
+#define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT)
+
+/* phy types, PhyVersion:PhyType field */
+#define PHY_TYPE_N 4 /* N-Phy value */
+#define PHY_TYPE_SSN 6 /* SSLPN-Phy value */
+#define PHY_TYPE_LCN 8 /* LCN-Phy value */
+#define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */
+#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
+
+/* analog types, PhyVersion:AnalogType field */
+#define ANA_11N_013 5
+
+/* 802.11a PLCP header def */
+typedef struct ofdm_phy_hdr ofdm_phy_hdr_t;
+BWL_PRE_PACKED_STRUCT struct ofdm_phy_hdr {
+ uint8 rlpt[3]; /* rate, length, parity, tail */
+ uint16 service;
+ uint8 pad;
+} BWL_POST_PACKED_STRUCT;
+
+#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f)
+#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01)
+#define D11A_PHY_HDR_GLENGTH(phdr) (((uint32 *)((phdr)->rlpt) >> 5) & 0x0fff)
+#define D11A_PHY_HDR_GPARITY(phdr) (((phdr)->rlpt[3] >> 1) & 0x01)
+#define D11A_PHY_HDR_GTAIL(phdr) (((phdr)->rlpt[3] >> 2) & 0x3f)
+
+/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
+#define D11A_PHY_HDR_SRATE(phdr, rate) \
+ ((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
+/* set reserved field to zero */
+#define D11A_PHY_HDR_SRES(phdr) ((phdr)->rlpt[0] &= 0xef)
+/* length is number of octets in PSDU */
+#define D11A_PHY_HDR_SLENGTH(phdr, length) \
+ (*(uint32 *)((phdr)->rlpt) = *(uint32 *)((phdr)->rlpt) | \
+ (((length) & 0x0fff) << 5))
+/* set the tail to all zeros */
+#define D11A_PHY_HDR_STAIL(phdr) ((phdr)->rlpt[3] &= 0x03)
+
+#define D11A_PHY_HDR_LEN_L 3 /* low-rate part of PLCP header */
+#define D11A_PHY_HDR_LEN_R 2 /* high-rate part of PLCP header */
+
+#define D11A_PHY_TX_DELAY (2) /* 2.1 usec */
+
+#define D11A_PHY_HDR_TIME (4) /* low-rate part of PLCP header */
+#define D11A_PHY_PRE_TIME (16)
+#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
+
+/* 802.11b PLCP header def */
+typedef struct cck_phy_hdr cck_phy_hdr_t;
+BWL_PRE_PACKED_STRUCT struct cck_phy_hdr {
+ uint8 signal;
+ uint8 service;
+ uint16 length;
+ uint16 crc;
+} BWL_POST_PACKED_STRUCT;
+
+#define D11B_PHY_HDR_LEN 6
+
+#define D11B_PHY_TX_DELAY (3) /* 3.4 usec */
+
+#define D11B_PHY_LHDR_TIME (D11B_PHY_HDR_LEN << 3)
+#define D11B_PHY_LPRE_TIME (144)
+#define D11B_PHY_LPREHDR_TIME (D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
+
+#define D11B_PHY_SHDR_TIME (D11B_PHY_LHDR_TIME >> 1)
+#define D11B_PHY_SPRE_TIME (D11B_PHY_LPRE_TIME >> 1)
+#define D11B_PHY_SPREHDR_TIME (D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
+
+#define D11B_PLCP_SIGNAL_LOCKED (1 << 2)
+#define D11B_PLCP_SIGNAL_LE (1 << 7)
+
+#define MIMO_PLCP_MCS_MASK 0x7f /* mcs index */
+#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */
+#define MIMO_PLCP_AMPDU 0x08 /* ampdu */
+
+#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
+#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
+#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \
+ do { \
+ plcp[1] = len & 0xff; \
+ plcp[2] = ((len >> 8) & 0xff); \
+ } while (0);
+
+#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
+#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
+#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
+
+/* The dot11a PLCP header is 5 bytes. To simplify the software (so that we
+ * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has
+ * padding added in the ucode.
+ */
+#define D11_PHY_HDR_LEN 6
+
+/* TX DMA buffer header */
+typedef struct d11txh d11txh_t;
+BWL_PRE_PACKED_STRUCT struct d11txh {
+ uint16 MacTxControlLow; /* 0x0 */
+ uint16 MacTxControlHigh; /* 0x1 */
+ uint16 MacFrameControl; /* 0x2 */
+ uint16 TxFesTimeNormal; /* 0x3 */
+ uint16 PhyTxControlWord; /* 0x4 */
+ uint16 PhyTxControlWord_1; /* 0x5 */
+ uint16 PhyTxControlWord_1_Fbr; /* 0x6 */
+ uint16 PhyTxControlWord_1_Rts; /* 0x7 */
+ uint16 PhyTxControlWord_1_FbrRts; /* 0x8 */
+ uint16 MainRates; /* 0x9 */
+ uint16 XtraFrameTypes; /* 0xa */
+ uint8 IV[16]; /* 0x0b - 0x12 */
+ uint8 TxFrameRA[6]; /* 0x13 - 0x15 */
+ uint16 TxFesTimeFallback; /* 0x16 */
+ uint8 RTSPLCPFallback[6]; /* 0x17 - 0x19 */
+ uint16 RTSDurFallback; /* 0x1a */
+ uint8 FragPLCPFallback[6]; /* 0x1b - 1d */
+ uint16 FragDurFallback; /* 0x1e */
+ uint16 MModeLen; /* 0x1f */
+ uint16 MModeFbrLen; /* 0x20 */
+ uint16 TstampLow; /* 0x21 */
+ uint16 TstampHigh; /* 0x22 */
+ uint16 ABI_MimoAntSel; /* 0x23 */
+ uint16 PreloadSize; /* 0x24 */
+ uint16 AmpduSeqCtl; /* 0x25 */
+ uint16 TxFrameID; /* 0x26 */
+ uint16 TxStatus; /* 0x27 */
+ uint16 MaxNMpdus; /* 0x28 corerev >=16 */
+ uint16 MaxABytes_MRT; /* 0x29 corerev >=16 */
+ uint16 MaxABytes_FBR; /* 0x2a corerev >=16 */
+ uint16 MinMBytes; /* 0x2b corerev >=16 */
+ uint8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */
+ struct dot11_rts_frame rts_frame; /* 0x2f - 0x36 */
+ uint16 PAD; /* 0x37 */
+} BWL_POST_PACKED_STRUCT;
+
+#define D11_TXH_LEN 112 /* bytes */
+
+/* Frame Types */
+#define FT_CCK 0
+#define FT_OFDM 1
+#define FT_HT 2
+#define FT_N 3
+
+/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */
+#define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */
+#define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */
+#define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */
+#define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */
+#define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */
+
+/* MacTxControlLow */
+#define TXC_AMIC 0x8000
+#define TXC_SENDCTS 0x0800
+#define TXC_AMPDU_MASK 0x0600
+#define TXC_BW_40 0x0100
+#define TXC_FREQBAND_5G 0x0080
+#define TXC_DFCS 0x0040
+#define TXC_IGNOREPMQ 0x0020
+#define TXC_HWSEQ 0x0010
+#define TXC_STARTMSDU 0x0008
+#define TXC_SENDRTS 0x0004
+#define TXC_LONGFRAME 0x0002
+#define TXC_IMMEDACK 0x0001
+
+/* MacTxControlHigh */
+#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 /* RTS fallback preamble type 1 = SHORT 0 = LONG */
+#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 /* RTS main rate preamble type 1 = SHORT 0 = LONG */
+#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 /* Main fallback rate preamble type
+ * 1 = SHORT for OFDM/GF for MIMO
+ * 0 = LONG for CCK/MM for MIMO
+ */
+/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
+#define TXC_AMPDU_FBR 0x1000 /* use fallback rate for this AMPDU */
+#define TXC_SECKEY_MASK 0x0FF0
+#define TXC_SECKEY_SHIFT 4
+#define TXC_ALT_TXPWR 0x0008 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
+#define TXC_SECTYPE_MASK 0x0007
+#define TXC_SECTYPE_SHIFT 0
+
+/* Null delimiter for Fallback rate */
+#define AMPDU_FBR_NULL_DELIM 5 /* Location of Null delimiter count for AMPDU */
+
+/* PhyTxControl for Mimophy */
+#define PHY_TXC_PWR_MASK 0xFC00
+#define PHY_TXC_PWR_SHIFT 10
+#define PHY_TXC_ANT_MASK 0x03C0 /* bit 6, 7, 8, 9 */
+#define PHY_TXC_ANT_SHIFT 6
+#define PHY_TXC_ANT_0_1 0x00C0 /* auto, last rx */
+#define PHY_TXC_LCNPHY_ANT_LAST 0x0000
+#define PHY_TXC_ANT_3 0x0200 /* virtual antenna 3 */
+#define PHY_TXC_ANT_2 0x0100 /* virtual antenna 2 */
+#define PHY_TXC_ANT_1 0x0080 /* virtual antenna 1 */
+#define PHY_TXC_ANT_0 0x0040 /* virtual antenna 0 */
+#define PHY_TXC_SHORT_HDR 0x0010
+
+#define PHY_TXC_OLD_ANT_0 0x0000
+#define PHY_TXC_OLD_ANT_1 0x0100
+#define PHY_TXC_OLD_ANT_LAST 0x0300
+
+/* PhyTxControl_1 for Mimophy */
+#define PHY_TXC1_BW_MASK 0x0007
+#define PHY_TXC1_BW_10MHZ 0
+#define PHY_TXC1_BW_10MHZ_UP 1
+#define PHY_TXC1_BW_20MHZ 2
+#define PHY_TXC1_BW_20MHZ_UP 3
+#define PHY_TXC1_BW_40MHZ 4
+#define PHY_TXC1_BW_40MHZ_DUP 5
+#define PHY_TXC1_MODE_SHIFT 3
+#define PHY_TXC1_MODE_MASK 0x0038
+#define PHY_TXC1_MODE_SISO 0
+#define PHY_TXC1_MODE_CDD 1
+#define PHY_TXC1_MODE_STBC 2
+#define PHY_TXC1_MODE_SDM 3
+
+/* PhyTxControl for HTphy that are different from Mimophy */
+#define PHY_TXC_HTANT_MASK 0x3fC0 /* bit 6, 7, 8, 9, 10, 11, 12, 13 */
+
+/* XtraFrameTypes */
+#define XFTS_RTS_FT_SHIFT 2
+#define XFTS_FBRRTS_FT_SHIFT 4
+#define XFTS_CHANNEL_SHIFT 8
+
+/* Antenna diversity bit in ant_wr_settle */
+#define PHY_AWS_ANTDIV 0x2000
+
+/* IFS ctl */
+#define IFS_USEEDCF (1 << 2)
+
+/* IFS ctl1 */
+#define IFS_CTL1_EDCRS (1 << 3)
+#define IFS_CTL1_EDCRS_20L (1 << 4)
+#define IFS_CTL1_EDCRS_40 (1 << 5)
+
+/* ABI_MimoAntSel */
+#define ABI_MAS_ADDR_BMP_IDX_MASK 0x0f00
+#define ABI_MAS_ADDR_BMP_IDX_SHIFT 8
+#define ABI_MAS_FBR_ANT_PTN_MASK 0x00f0
+#define ABI_MAS_FBR_ANT_PTN_SHIFT 4
+#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f
+
+/* tx status packet */
+typedef struct tx_status tx_status_t;
+BWL_PRE_PACKED_STRUCT struct tx_status {
+ uint16 framelen;
+ uint16 PAD;
+ uint16 frameid;
+ uint16 status;
+ uint16 lasttxtime;
+ uint16 sequence;
+ uint16 phyerr;
+ uint16 ackphyrxsh;
+} BWL_POST_PACKED_STRUCT;
+
+#define TXSTATUS_LEN 16
+
+/* status field bit definitions */
+#define TX_STATUS_FRM_RTX_MASK 0xF000
+#define TX_STATUS_FRM_RTX_SHIFT 12
+#define TX_STATUS_RTS_RTX_MASK 0x0F00
+#define TX_STATUS_RTS_RTX_SHIFT 8
+#define TX_STATUS_MASK 0x00FE
+#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */
+#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */
+#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */
+#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */
+#define TX_STATUS_SUPR_SHIFT 2
+#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */
+#define TX_STATUS_VALID (1 << 0) /* Tx status valid (corerev >= 5) */
+#define TX_STATUS_NO_ACK 0
+
+/* suppress status reason codes */
+#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */
+#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */
+#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */
+#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe response supr for TBTT */
+#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */
+#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */
+#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */
+
+/* Unexpected tx status for rate update */
+#define TX_STATUS_UNEXP(status) \
+ ((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
+ TX_STATUS_UNEXP_AMPDU(status))
+
+/* Unexpected tx status for A-MPDU rate update */
+#define TX_STATUS_UNEXP_AMPDU(status) \
+ ((((status) & TX_STATUS_SUPR_MASK) != 0) && \
+ (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
+
+#define TX_STATUS_BA_BMAP03_MASK 0xF000 /* ba bitmap 0:3 in 1st pkg */
+#define TX_STATUS_BA_BMAP03_SHIFT 12 /* ba bitmap 0:3 in 1st pkg */
+#define TX_STATUS_BA_BMAP47_MASK 0x001E /* ba bitmap 4:7 in 2nd pkg */
+#define TX_STATUS_BA_BMAP47_SHIFT 3 /* ba bitmap 4:7 in 2nd pkg */
+
+/* RXE (Receive Engine) */
+
+/* RCM_CTL */
+#define RCM_INC_MASK_H 0x0080
+#define RCM_INC_MASK_L 0x0040
+#define RCM_INC_DATA 0x0020
+#define RCM_INDEX_MASK 0x001F
+#define RCM_SIZE 15
+
+#define RCM_MAC_OFFSET 0 /* current MAC address */
+#define RCM_BSSID_OFFSET 3 /* current BSSID address */
+#define RCM_F_BSSID_0_OFFSET 6 /* foreign BSS CFP tracking */
+#define RCM_F_BSSID_1_OFFSET 9 /* foreign BSS CFP tracking */
+#define RCM_F_BSSID_2_OFFSET 12 /* foreign BSS CFP tracking */
+
+#define RCM_WEP_TA0_OFFSET 16
+#define RCM_WEP_TA1_OFFSET 19
+#define RCM_WEP_TA2_OFFSET 22
+#define RCM_WEP_TA3_OFFSET 25
+
+/* PSM Block */
+
+/* psm_phy_hdr_param bits */
+#define MAC_PHY_RESET 1
+#define MAC_PHY_CLOCK_EN 2
+#define MAC_PHY_FORCE_CLK 4
+
+/* WEP Block */
+
+/* WEP_WKEY */
+#define WKEY_START (1 << 8)
+#define WKEY_SEL_MASK 0x1F
+
+/* WEP data formats */
+
+/* the number of RCMTA entries */
+#define RCMTA_SIZE 50
+
+#define M_ADDR_BMP_BLK (0x37e * 2)
+#define M_ADDR_BMP_BLK_SZ 12
+
+#define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */
+#define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */
+#define ADDR_BMP_BSSID (1 << 2) /* BSSID */
+#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point (AP) */
+#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station (STA) */
+#define ADDR_BMP_RESERVED1 (1 << 5)
+#define ADDR_BMP_RESERVED2 (1 << 6)
+#define ADDR_BMP_RESERVED3 (1 << 7)
+#define ADDR_BMP_BSS_IDX_MASK (3 << 8) /* BSS control block index */
+#define ADDR_BMP_BSS_IDX_SHIFT 8
+
+#define WSEC_MAX_RCMTA_KEYS 54
+
+/* max keys in M_TKMICKEYS_BLK */
+#define WSEC_MAX_TKMIC_ENGINE_KEYS 12 /* 8 + 4 default */
+
+/* max RXE match registers */
+#define WSEC_MAX_RXE_KEYS 4
+
+/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
+/* SKL (Security Key Lookup) */
+#define SKL_ALGO_MASK 0x0007
+#define SKL_ALGO_SHIFT 0
+#define SKL_KEYID_MASK 0x0008
+#define SKL_KEYID_SHIFT 3
+#define SKL_INDEX_MASK 0x03F0
+#define SKL_INDEX_SHIFT 4
+#define SKL_GRP_ALGO_MASK 0x1c00
+#define SKL_GRP_ALGO_SHIFT 10
+
+/* additional bits defined for IBSS group key support */
+#define SKL_IBSS_INDEX_MASK 0x01F0
+#define SKL_IBSS_INDEX_SHIFT 4
+#define SKL_IBSS_KEYID1_MASK 0x0600
+#define SKL_IBSS_KEYID1_SHIFT 9
+#define SKL_IBSS_KEYID2_MASK 0x1800
+#define SKL_IBSS_KEYID2_SHIFT 11
+#define SKL_IBSS_KEYALGO_MASK 0xE000
+#define SKL_IBSS_KEYALGO_SHIFT 13
+
+#define WSEC_MODE_OFF 0
+#define WSEC_MODE_HW 1
+#define WSEC_MODE_SW 2
+
+#define WSEC_ALGO_OFF 0
+#define WSEC_ALGO_WEP1 1
+#define WSEC_ALGO_TKIP 2
+#define WSEC_ALGO_AES 3
+#define WSEC_ALGO_WEP128 4
+#define WSEC_ALGO_AES_LEGACY 5
+#define WSEC_ALGO_NALG 6
+
+#define AES_MODE_NONE 0
+#define AES_MODE_CCM 1
+
+/* WEP_CTL (Rev 0) */
+#define WECR0_KEYREG_SHIFT 0
+#define WECR0_KEYREG_MASK 0x7
+#define WECR0_DECRYPT (1 << 3)
+#define WECR0_IVINLINE (1 << 4)
+#define WECR0_WEPALG_SHIFT 5
+#define WECR0_WEPALG_MASK (0x7 << 5)
+#define WECR0_WKEYSEL_SHIFT 8
+#define WECR0_WKEYSEL_MASK (0x7 << 8)
+#define WECR0_WKEYSTART (1 << 11)
+#define WECR0_WEPINIT (1 << 14)
+#define WECR0_ICVERR (1 << 15)
+
+/* Frame template map byte offsets */
+#define T_ACTS_TPL_BASE (0)
+#define T_NULL_TPL_BASE (0xc * 2)
+#define T_QNULL_TPL_BASE (0x1c * 2)
+#define T_RR_TPL_BASE (0x2c * 2)
+#define T_BCN0_TPL_BASE (0x34 * 2)
+#define T_PRS_TPL_BASE (0x134 * 2)
+#define T_BCN1_TPL_BASE (0x234 * 2)
+#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
+
+#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */
+
+#define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */
+
+/* Shared Mem byte offsets */
+
+/* Location where the ucode expects the corerev */
+#define M_MACHW_VER (0x00b * 2)
+
+/* Location where the ucode expects the MAC capabilities */
+#define M_MACHW_CAP_L (0x060 * 2)
+#define M_MACHW_CAP_H (0x061 * 2)
+
+/* WME shared memory */
+#define M_EDCF_STATUS_OFF (0x007 * 2)
+#define M_TXF_CUR_INDEX (0x018 * 2)
+#define M_EDCF_QINFO (0x120 * 2)
+
+/* PS-mode related parameters */
+#define M_DOT11_SLOT (0x008 * 2)
+#define M_DOT11_DTIMPERIOD (0x009 * 2)
+#define M_NOSLPZNATDTIM (0x026 * 2)
+
+/* Beacon-related parameters */
+#define M_BCN0_FRM_BYTESZ (0x00c * 2) /* Bcn 0 template length */
+#define M_BCN1_FRM_BYTESZ (0x00d * 2) /* Bcn 1 template length */
+#define M_BCN_TXTSF_OFFSET (0x00e * 2)
+#define M_TIMBPOS_INBEACON (0x00f * 2)
+#define M_SFRMTXCNTFBRTHSD (0x022 * 2)
+#define M_LFRMTXCNTFBRTHSD (0x023 * 2)
+#define M_BCN_PCTLWD (0x02a * 2)
+#define M_BCN_LI (0x05b * 2) /* beacon listen interval */
+
+/* MAX Rx Frame len */
+#define M_MAXRXFRM_LEN (0x010 * 2)
+
+/* ACK/CTS related params */
+#define M_RSP_PCTLWD (0x011 * 2)
+
+/* Hardware Power Control */
+#define M_TXPWR_N (0x012 * 2)
+#define M_TXPWR_TARGET (0x013 * 2)
+#define M_TXPWR_MAX (0x014 * 2)
+#define M_TXPWR_CUR (0x019 * 2)
+
+/* Rx-related parameters */
+#define M_RX_PAD_DATA_OFFSET (0x01a * 2)
+
+/* WEP Shared mem data */
+#define M_SEC_DEFIVLOC (0x01e * 2)
+#define M_SEC_VALNUMSOFTMCHTA (0x01f * 2)
+#define M_PHYVER (0x028 * 2)
+#define M_PHYTYPE (0x029 * 2)
+#define M_SECRXKEYS_PTR (0x02b * 2)
+#define M_TKMICKEYS_PTR (0x059 * 2)
+#define M_SECKINDXALGO_BLK (0x2ea * 2)
+#define M_SECKINDXALGO_BLK_SZ 54
+#define M_SECPSMRXTAMCH_BLK (0x2fa * 2)
+#define M_TKIP_TSC_TTAK (0x18c * 2)
+#define D11_MAX_KEY_SIZE 16
+
+#define M_MAX_ANTCNT (0x02e * 2) /* antenna swap threshold */
+
+/* Probe response related parameters */
+#define M_SSIDLEN (0x024 * 2)
+#define M_PRB_RESP_FRM_LEN (0x025 * 2)
+#define M_PRS_MAXTIME (0x03a * 2)
+#define M_SSID (0xb0 * 2)
+#define M_CTXPRS_BLK (0xc0 * 2)
+#define C_CTX_PCTLWD_POS (0x4 * 2)
+
+/* Delta between OFDM and CCK power in CCK power boost mode */
+#define M_OFDM_OFFSET (0x027 * 2)
+
+/* TSSI for last 4 11b/g CCK packets transmitted */
+#define M_B_TSSI_0 (0x02c * 2)
+#define M_B_TSSI_1 (0x02d * 2)
+
+/* Host flags to turn on ucode options */
+#define M_HOST_FLAGS1 (0x02f * 2)
+#define M_HOST_FLAGS2 (0x030 * 2)
+#define M_HOST_FLAGS3 (0x031 * 2)
+#define M_HOST_FLAGS4 (0x03c * 2)
+#define M_HOST_FLAGS5 (0x06a * 2)
+#define M_HOST_FLAGS_SZ 16
+
+#define M_RADAR_REG (0x033 * 2)
+
+/* TSSI for last 4 11a OFDM packets transmitted */
+#define M_A_TSSI_0 (0x034 * 2)
+#define M_A_TSSI_1 (0x035 * 2)
+
+/* noise interference measurement */
+#define M_NOISE_IF_COUNT (0x034 * 2)
+#define M_NOISE_IF_TIMEOUT (0x035 * 2)
+
+#define M_RF_RX_SP_REG1 (0x036 * 2)
+
+/* TSSI for last 4 11g OFDM packets transmitted */
+#define M_G_TSSI_0 (0x038 * 2)
+#define M_G_TSSI_1 (0x039 * 2)
+
+/* Background noise measure */
+#define M_JSSI_0 (0x44 * 2)
+#define M_JSSI_1 (0x45 * 2)
+#define M_JSSI_AUX (0x46 * 2)
+
+#define M_CUR_2050_RADIOCODE (0x47 * 2)
+
+/* TX fifo sizes */
+#define M_FIFOSIZE0 (0x4c * 2)
+#define M_FIFOSIZE1 (0x4d * 2)
+#define M_FIFOSIZE2 (0x4e * 2)
+#define M_FIFOSIZE3 (0x4f * 2)
+#define D11_MAX_TX_FRMS 32 /* max frames allowed in tx fifo */
+
+/* Current channel number plus upper bits */
+#define M_CURCHANNEL (0x50 * 2)
+#define D11_CURCHANNEL_5G 0x0100;
+#define D11_CURCHANNEL_40 0x0200;
+#define D11_CURCHANNEL_MAX 0x00FF;
+
+/* last posted frameid on the bcmc fifo */
+#define M_BCMC_FID (0x54 * 2)
+#define INVALIDFID 0xffff
+
+/* extended beacon phyctl bytes for 11N */
+#define M_BCN_PCTL1WD (0x058 * 2)
+
+/* idle busy ratio to duty_cycle requirement */
+#define M_TX_IDLE_BUSY_RATIO_X_16_CCK (0x52 * 2)
+#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
+
+/* CW RSSI for LCNPHY */
+#define M_LCN_RSSI_0 0x1332
+#define M_LCN_RSSI_1 0x1338
+#define M_LCN_RSSI_2 0x133e
+#define M_LCN_RSSI_3 0x1344
+
+/* SNR for LCNPHY */
+#define M_LCN_SNR_A_0 0x1334
+#define M_LCN_SNR_B_0 0x1336
+
+#define M_LCN_SNR_A_1 0x133a
+#define M_LCN_SNR_B_1 0x133c
+
+#define M_LCN_SNR_A_2 0x1340
+#define M_LCN_SNR_B_2 0x1342
+
+#define M_LCN_SNR_A_3 0x1346
+#define M_LCN_SNR_B_3 0x1348
+
+#define M_LCN_LAST_RESET (81*2)
+#define M_LCN_LAST_LOC (63*2)
+#define M_LCNPHY_RESET_STATUS (4902)
+#define M_LCNPHY_DSC_TIME (0x98d*2)
+#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
+#define M_LCNPHY_RESET_CNT (0x98c*2)
+
+/* Rate table offsets */
+#define M_RT_DIRMAP_A (0xe0 * 2)
+#define M_RT_BBRSMAP_A (0xf0 * 2)
+#define M_RT_DIRMAP_B (0x100 * 2)
+#define M_RT_BBRSMAP_B (0x110 * 2)
+
+/* Rate table entry offsets */
+#define M_RT_PRS_PLCP_POS 10
+#define M_RT_PRS_DUR_POS 16
+#define M_RT_OFDM_PCTL1_POS 18
+
+#define M_20IN40_IQ (0x380 * 2)
+
+/* SHM locations where ucode stores the current power index */
+#define M_CURR_IDX1 (0x384 * 2)
+#define M_CURR_IDX2 (0x387 * 2)
+
+#define M_BSCALE_ANT0 (0x5e * 2)
+#define M_BSCALE_ANT1 (0x5f * 2)
+
+/* Antenna Diversity Testing */
+#define M_MIMO_ANTSEL_RXDFLT (0x63 * 2)
+#define M_ANTSEL_CLKDIV (0x61 * 2)
+#define M_MIMO_ANTSEL_TXDFLT (0x64 * 2)
+
+#define M_MIMO_MAXSYM (0x5d * 2)
+#define MIMO_MAXSYM_DEF 0x8000 /* 32k */
+#define MIMO_MAXSYM_MAX 0xffff /* 64k */
+
+#define M_WATCHDOG_8TU (0x1e * 2)
+#define WATCHDOG_8TU_DEF 5
+#define WATCHDOG_8TU_MAX 10
+
+/* Manufacturing Test Variables */
+#define M_PKTENG_CTRL (0x6c * 2) /* PER test mode */
+#define M_PKTENG_IFS (0x6d * 2) /* IFS for TX mode */
+#define M_PKTENG_FRMCNT_LO (0x6e * 2) /* Lower word of tx frmcnt/rx lostcnt */
+#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Upper word of tx frmcnt/rx lostcnt */
+
+/* Index variation in vbat ripple */
+#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */
+#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */
+
+/* M_PKTENG_CTRL bit definitions */
+#define M_PKTENG_MODE_TX 0x0001
+#define M_PKTENG_MODE_TX_RIFS 0x0004
+#define M_PKTENG_MODE_TX_CTS 0x0008
+#define M_PKTENG_MODE_RX 0x0002
+#define M_PKTENG_MODE_RX_WITH_ACK 0x0402
+#define M_PKTENG_MODE_MASK 0x0003
+#define M_PKTENG_FRMCNT_VLD 0x0100 /* TX frames indicated in the frmcnt reg */
+
+/* Sample Collect parameters (bitmap and type) */
+#define M_SMPL_COL_BMP (0x37d * 2) /* Trigger bitmap for sample collect */
+#define M_SMPL_COL_CTL (0x3b2 * 2) /* Sample collect type */
+
+#define ANTSEL_CLKDIV_4MHZ 6
+#define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */
+#define MIMO_ANTSEL_SEL 0x8000 /* bit 15 write the value */
+#define MIMO_ANTSEL_WAIT 50 /* 50us wait */
+#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */
+
+typedef struct shm_acparams shm_acparams_t;
+BWL_PRE_PACKED_STRUCT struct shm_acparams {
+ uint16 txop;
+ uint16 cwmin;
+ uint16 cwmax;
+ uint16 cwcur;
+ uint16 aifs;
+ uint16 bslots;
+ uint16 reggap;
+ uint16 status;
+ uint16 rsvd[8];
+} BWL_POST_PACKED_STRUCT;
+#define M_EDCF_QLEN (16 * 2)
+
+#define WME_STATUS_NEWAC (1 << 8)
+
+/* M_HOST_FLAGS */
+#define MHFMAX 5 /* Number of valid hostflag half-word (uint16) */
+#define MHF1 0 /* Hostflag 1 index */
+#define MHF2 1 /* Hostflag 2 index */
+#define MHF3 2 /* Hostflag 3 index */
+#define MHF4 3 /* Hostflag 4 index */
+#define MHF5 4 /* Hostflag 5 index */
+
+/* Flags in M_HOST_FLAGS */
+#define MHF1_ANTDIV 0x0001 /* Enable ucode antenna diversity help */
+#define MHF1_EDCF 0x0100 /* Enable EDCF access control */
+#define MHF1_IQSWAP_WAR 0x0200
+#define MHF1_FORCEFASTCLK 0x0400 /* Disable Slow clock request, for corerev < 11 */
+
+/* Flags in M_HOST_FLAGS2 */
+#define MHF2_PCISLOWCLKWAR 0x0008 /* PR16165WAR : Enable ucode PCI slow clock WAR */
+#define MHF2_TXBCMC_NOW 0x0040 /* Flush BCMC FIFO immediately */
+#define MHF2_HWPWRCTL 0x0080 /* Enable ucode/hw power control */
+#define MHF2_NPHY40MHZ_WAR 0x0800
+
+/* Flags in M_HOST_FLAGS3 */
+#define MHF3_ANTSEL_EN 0x0001 /* enabled mimo antenna selection */
+#define MHF3_ANTSEL_MODE 0x0002 /* antenna selection mode: 0: 2x3, 1: 2x4 */
+#define MHF3_RESERVED1 0x0004
+#define MHF3_RESERVED2 0x0008
+#define MHF3_NPHY_MLADV_WAR 0x0010
+
+/* Flags in M_HOST_FLAGS4 */
+#define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */
+#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */
+
+/* Flags in M_HOST_FLAGS5 */
+#define MHF5_4313_GPIOCTRL 0x0001
+#define MHF5_RESERVED1 0x0002
+#define MHF5_RESERVED2 0x0004
+/* Radio power setting for ucode */
+#define M_RADIO_PWR (0x32 * 2)
+
+/* phy noise recorded by ucode right after tx */
+#define M_PHY_NOISE (0x037 * 2)
+#define PHY_NOISE_MASK 0x00ff
+
+/* Receive Frame Data Header for 802.11b DCF-only frames */
+typedef struct d11rxhdr d11rxhdr_t;
+BWL_PRE_PACKED_STRUCT struct d11rxhdr {
+ uint16 RxFrameSize; /* Actual byte length of the frame data received */
+ uint16 PAD;
+ uint16 PhyRxStatus_0; /* PhyRxStatus 15:0 */
+ uint16 PhyRxStatus_1; /* PhyRxStatus 31:16 */
+ uint16 PhyRxStatus_2; /* PhyRxStatus 47:32 */
+ uint16 PhyRxStatus_3; /* PhyRxStatus 63:48 */
+ uint16 PhyRxStatus_4; /* PhyRxStatus 79:64 */
+ uint16 PhyRxStatus_5; /* PhyRxStatus 95:80 */
+ uint16 RxStatus1; /* MAC Rx Status */
+ uint16 RxStatus2; /* extended MAC Rx status */
+ uint16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
+ uint16 RxChan; /* gain code, channel radio code, and phy type */
+} BWL_POST_PACKED_STRUCT;
+
+#define RXHDR_LEN 24 /* sizeof d11rxhdr_t */
+#define FRAMELEN(h) ((h)->RxFrameSize)
+
+typedef struct wlc_d11rxhdr wlc_d11rxhdr_t;
+BWL_PRE_PACKED_STRUCT struct wlc_d11rxhdr {
+ d11rxhdr_t rxhdr;
+ uint32 tsf_l; /* TSF_L reading */
+ int8 rssi; /* computed instanteneous rssi in BMAC */
+ int8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+ int8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+ int8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */
+ int8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */
+} BWL_POST_PACKED_STRUCT;
+
+/* PhyRxStatus_0: */
+#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */
+#define PRXS0_CLIP_MASK 0x000C /* NPHY only: clip count adjustment steps by AGC */
+#define PRXS0_CLIP_SHIFT 2
+#define PRXS0_UNSRATE 0x0010 /* PHY received a frame with unsupported rate */
+#define PRXS0_RXANT_UPSUBBAND 0x0020 /* GPHY: rx ant, NPHY: upper sideband */
+#define PRXS0_LCRS 0x0040 /* CCK frame only: lost crs during cck frame reception */
+#define PRXS0_SHORTH 0x0080 /* Short Preamble */
+#define PRXS0_PLCPFV 0x0100 /* PLCP violation */
+#define PRXS0_PLCPHCF 0x0200 /* PLCP header integrity check failed */
+#define PRXS0_GAIN_CTL 0x4000 /* legacy PHY gain control */
+#define PRXS0_ANTSEL_MASK 0xF000 /* NPHY: Antennas used for received frame, bitmask */
+#define PRXS0_ANTSEL_SHIFT 0x12
+
+/* subfield PRXS0_FT_MASK */
+#define PRXS0_CCK 0x0000
+#define PRXS0_OFDM 0x0001 /* valid only for G phy, use rxh->RxChan for A phy */
+#define PRXS0_PREN 0x0002
+#define PRXS0_STDN 0x0003
+
+/* subfield PRXS0_ANTSEL_MASK */
+#define PRXS0_ANTSEL_0 0x0 /* antenna 0 is used */
+#define PRXS0_ANTSEL_1 0x2 /* antenna 1 is used */
+#define PRXS0_ANTSEL_2 0x4 /* antenna 2 is used */
+#define PRXS0_ANTSEL_3 0x8 /* antenna 3 is used */
+
+/* PhyRxStatus_1: */
+#define PRXS1_JSSI_MASK 0x00FF
+#define PRXS1_JSSI_SHIFT 0
+#define PRXS1_SQ_MASK 0xFF00
+#define PRXS1_SQ_SHIFT 8
+
+/* nphy PhyRxStatus_1: */
+#define PRXS1_nphy_PWR0_MASK 0x00FF
+#define PRXS1_nphy_PWR1_MASK 0xFF00
+
+/* HTPHY Rx Status defines */
+/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
+#define PRXS0_BAND 0x0400 /* 0 = 2.4G, 1 = 5G */
+#define PRXS0_RSVD 0x0800 /* reserved; set to 0 */
+#define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */
+
+/* htphy PhyRxStatus_1: */
+#define PRXS1_HTPHY_CORE_MASK 0x000F /* core enables for {3..0}, 0=disabled, 1=enabled */
+#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 /* antenna configation */
+#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* Mixmode PLCP Length low byte mask */
+
+/* htphy PhyRxStatus_2: */
+#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F /* Mixmode PLCP Length high byte maskw */
+#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 /* Mixmode PLCP rate mask */
+#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* Rx power on core 0 */
+
+/* htphy PhyRxStatus_3: */
+#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF /* Rx power on core 1 */
+#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* Rx power on core 2 */
+
+/* htphy PhyRxStatus_4: */
+#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF /* Rx power on core 3 */
+#define PRXS4_HTPHY_CFO 0xFF00 /* Coarse frequency offset */
+
+/* htphy PhyRxStatus_5: */
+#define PRXS5_HTPHY_FFO 0x00FF /* Fine frequency offset */
+#define PRXS5_HTPHY_AR 0xFF00 /* Advance Retard */
+
+#define HTPHY_MMPLCPLen(rxs) ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
+ (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
+/* Get Rx power on core 0 */
+#define HTPHY_RXPWR_ANT0(rxs) ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
+/* Get Rx power on core 1 */
+#define HTPHY_RXPWR_ANT1(rxs) (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
+/* Get Rx power on core 2 */
+#define HTPHY_RXPWR_ANT2(rxs) ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
+
+/* ucode RxStatus1: */
+#define RXS_BCNSENT 0x8000
+#define RXS_SECKINDX_MASK 0x07e0
+#define RXS_SECKINDX_SHIFT 5
+#define RXS_DECERR (1 << 4)
+#define RXS_DECATMPT (1 << 3)
+#define RXS_PBPRES (1 << 2) /* PAD bytes to make IP data 4 bytes aligned */
+#define RXS_RESPFRAMETX (1 << 1)
+#define RXS_FCSERR (1 << 0)
+
+/* ucode RxStatus2: */
+#define RXS_AMSDU_MASK 1
+#define RXS_AGGTYPE_MASK 0x6
+#define RXS_AGGTYPE_SHIFT 1
+#define RXS_PHYRXST_VALID (1 << 8)
+#define RXS_RXANT_MASK 0x3
+#define RXS_RXANT_SHIFT 12
+
+/* RxChan */
+#define RXS_CHAN_40 0x1000
+#define RXS_CHAN_5G 0x0800
+#define RXS_CHAN_ID_MASK 0x07f8
+#define RXS_CHAN_ID_SHIFT 3
+#define RXS_CHAN_PHYTYPE_MASK 0x0007
+#define RXS_CHAN_PHYTYPE_SHIFT 0
+
+/* Index of attenuations used during ucode power control. */
+#define M_PWRIND_BLKS (0x184 * 2)
+#define M_PWRIND_MAP0 (M_PWRIND_BLKS + 0x0)
+#define M_PWRIND_MAP1 (M_PWRIND_BLKS + 0x2)
+#define M_PWRIND_MAP2 (M_PWRIND_BLKS + 0x4)
+#define M_PWRIND_MAP3 (M_PWRIND_BLKS + 0x6)
+/* M_PWRIND_MAP(core) macro */
+#define M_PWRIND_MAP(core) (M_PWRIND_BLKS + ((core)<<1))
+
+/* PSM SHM variable offsets */
+#define M_PSM_SOFT_REGS 0x0
+#define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0)
+#define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2)
+#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
+#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
+
+#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */
+#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */
+#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */
+#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
+#define M_PRETBTT (0x4b * 2)
+
+#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) /* offset to the target txpwr */
+#define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2))
+#define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2))
+#define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2))
+
+/* PKTENG Rx Stats Block */
+#define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2))
+
+/* ucode debug status codes */
+#define DBGST_INACTIVE 0 /* not valid really */
+#define DBGST_INIT 1 /* after zeroing SHM, before suspending at init */
+#define DBGST_ACTIVE 2 /* "normal" state */
+#define DBGST_SUSPENDED 3 /* suspended */
+#define DBGST_ASLEEP 4 /* asleep (PS mode) */
+
+/* Scratch Reg defs */
+typedef enum {
+ S_RSV0 = 0,
+ S_RSV1,
+ S_RSV2,
+
+ /* scratch registers for Dot11-contants */
+ S_DOT11_CWMIN, /* CW-minimum 0x03 */
+ S_DOT11_CWMAX, /* CW-maximum 0x04 */
+ S_DOT11_CWCUR, /* CW-current 0x05 */
+ S_DOT11_SRC_LMT, /* short retry count limit 0x06 */
+ S_DOT11_LRC_LMT, /* long retry count limit 0x07 */
+ S_DOT11_DTIMCOUNT, /* DTIM-count 0x08 */
+
+ /* Tx-side scratch registers */
+ S_SEQ_NUM, /* hardware sequence number reg 0x09 */
+ S_SEQ_NUM_FRAG, /* seq-num for frags (Set at the start os MSDU 0x0A */
+ S_FRMRETX_CNT, /* frame retx count 0x0B */
+ S_SSRC, /* Station short retry count 0x0C */
+ S_SLRC, /* Station long retry count 0x0D */
+ S_EXP_RSP, /* Expected response frame 0x0E */
+ S_OLD_BREM, /* Remaining backoff ctr 0x0F */
+ S_OLD_CWWIN, /* saved-off CW-cur 0x10 */
+ S_TXECTL, /* TXE-Ctl word constructed in scr-pad 0x11 */
+ S_CTXTST, /* frm type-subtype as read from Tx-descr 0x12 */
+
+ /* Rx-side scratch registers */
+ S_RXTST, /* Type and subtype in Rxframe 0x13 */
+
+ /* Global state register */
+ S_STREG, /* state storage actual bit maps below 0x14 */
+
+ S_TXPWR_SUM, /* Tx power control: accumulator 0x15 */
+ S_TXPWR_ITER, /* Tx power control: iteration 0x16 */
+ S_RX_FRMTYPE, /* Rate and PHY type for frames 0x17 */
+ S_THIS_AGG, /* Size of this AGG (A-MSDU) 0x18 */
+
+ S_KEYINDX, /* 0x19 */
+ S_RXFRMLEN, /* Receive MPDU length in bytes 0x1A */
+
+ /* Receive TSF time stored in SCR */
+ S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx 0x1B */
+ S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx 0x1C */
+ S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx 0x1D */
+ S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx 0x1E */
+ S_RXSSN, /* Received start seq number for A-MPDU BA 0x1F */
+ S_RXQOSFLD, /* Rx-QoS field (if present) 0x20 */
+
+ /* Scratch pad regs used in microcode as temp storage */
+ S_TMP0, /* stmp0 0x21 */
+ S_TMP1, /* stmp1 0x22 */
+ S_TMP2, /* stmp2 0x23 */
+ S_TMP3, /* stmp3 0x24 */
+ S_TMP4, /* stmp4 0x25 */
+ S_TMP5, /* stmp5 0x26 */
+ S_PRQPENALTY_CTR, /* Probe response queue penalty counter 0x27 */
+ S_ANTCNT, /* unsuccessful attempts on current ant. 0x28 */
+ S_SYMBOL, /* flag for possible symbol ctl frames 0x29 */
+ S_RXTP, /* rx frame type 0x2A */
+ S_STREG2, /* extra state storage 0x2B */
+ S_STREG3, /* even more extra state storage 0x2C */
+ S_STREG4, /* ... 0x2D */
+ S_STREG5, /* remember to initialize it to zero 0x2E */
+
+ S_ADJPWR_IDX,
+ S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table 0x32 */
+ S_REVID4, /* 0x33 */
+ S_INDX, /* 0x34 */
+ S_ADDR0, /* 0x35 */
+ S_ADDR1, /* 0x36 */
+ S_ADDR2, /* 0x37 */
+ S_ADDR3, /* 0x38 */
+ S_ADDR4, /* 0x39 */
+ S_ADDR5, /* 0x3A */
+ S_TMP6, /* 0x3B */
+ S_KEYINDX_BU, /* Backup for Key index 0x3C */
+ S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */
+ S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */
+ S_STREG6, /* 0x3F */
+} ePsmScratchPadRegDefinitions;
+
+#define S_BEACON_INDX S_OLD_BREM
+#define S_PRS_INDX S_OLD_CWWIN
+#define S_PHYTYPE S_SSRC
+#define S_PHYVER S_SLRC
+
+/* IHR SLOW_CTRL values */
+#define SLOW_CTRL_PDE (1 << 0)
+#define SLOW_CTRL_FD (1 << 8)
+
+/* ucode mac statistic counters in shared memory */
+typedef struct macstat {
+ uint16 txallfrm; /* 0x80 */
+ uint16 txrtsfrm; /* 0x82 */
+ uint16 txctsfrm; /* 0x84 */
+ uint16 txackfrm; /* 0x86 */
+ uint16 txdnlfrm; /* 0x88 */
+ uint16 txbcnfrm; /* 0x8a */
+ uint16 txfunfl[8]; /* 0x8c - 0x9b */
+ uint16 txtplunfl; /* 0x9c */
+ uint16 txphyerr; /* 0x9e */
+ uint16 pktengrxducast; /* 0xa0 */
+ uint16 pktengrxdmcast; /* 0xa2 */
+ uint16 rxfrmtoolong; /* 0xa4 */
+ uint16 rxfrmtooshrt; /* 0xa6 */
+ uint16 rxinvmachdr; /* 0xa8 */
+ uint16 rxbadfcs; /* 0xaa */
+ uint16 rxbadplcp; /* 0xac */
+ uint16 rxcrsglitch; /* 0xae */
+ uint16 rxstrt; /* 0xb0 */
+ uint16 rxdfrmucastmbss; /* 0xb2 */
+ uint16 rxmfrmucastmbss; /* 0xb4 */
+ uint16 rxcfrmucast; /* 0xb6 */
+ uint16 rxrtsucast; /* 0xb8 */
+ uint16 rxctsucast; /* 0xba */
+ uint16 rxackucast; /* 0xbc */
+ uint16 rxdfrmocast; /* 0xbe */
+ uint16 rxmfrmocast; /* 0xc0 */
+ uint16 rxcfrmocast; /* 0xc2 */
+ uint16 rxrtsocast; /* 0xc4 */
+ uint16 rxctsocast; /* 0xc6 */
+ uint16 rxdfrmmcast; /* 0xc8 */
+ uint16 rxmfrmmcast; /* 0xca */
+ uint16 rxcfrmmcast; /* 0xcc */
+ uint16 rxbeaconmbss; /* 0xce */
+ uint16 rxdfrmucastobss; /* 0xd0 */
+ uint16 rxbeaconobss; /* 0xd2 */
+ uint16 rxrsptmout; /* 0xd4 */
+ uint16 bcntxcancl; /* 0xd6 */
+ uint16 PAD;
+ uint16 rxf0ovfl; /* 0xda */
+ uint16 rxf1ovfl; /* 0xdc */
+ uint16 rxf2ovfl; /* 0xde */
+ uint16 txsfovfl; /* 0xe0 */
+ uint16 pmqovfl; /* 0xe2 */
+ uint16 rxcgprqfrm; /* 0xe4 */
+ uint16 rxcgprsqovfl; /* 0xe6 */
+ uint16 txcgprsfail; /* 0xe8 */
+ uint16 txcgprssuc; /* 0xea */
+ uint16 prs_timeout; /* 0xec */
+ uint16 rxnack;
+ uint16 frmscons;
+ uint16 txnack;
+ uint16 txglitch_nack;
+ uint16 txburst; /* 0xf6 # tx bursts */
+ uint16 bphy_rxcrsglitch; /* bphy rx crs glitch */
+ uint16 phywatchdog; /* 0xfa # of phy watchdog events */
+ uint16 PAD;
+ uint16 bphy_badplcp; /* bphy bad plcp */
+} macstat_t;
+
+/* dot11 core-specific control flags */
+#define SICF_PCLKE 0x0004 /* PHY clock enable */
+#define SICF_PRST 0x0008 /* PHY reset */
+#define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */
+#define SICF_FREF 0x0020 /* PLL FreqRefSelect (corerev >= 5) */
+/* NOTE: the following bw bits only apply when the core is attached
+ * to a NPHY (and corerev >= 11 which it will always be for NPHYs).
+ */
+#define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */
+#define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */
+#define SICF_BW20 0x0040 /* 20MHz BW (80MHz phyclk) */
+#define SICF_BW10 0x0000 /* 10MHz BW (40MHz phyclk) */
+#define SICF_GMODE 0x2000 /* gmode enable */
+
+/* dot11 core-specific status flags */
+#define SISF_2G_PHY 0x0001 /* 2.4G capable phy (corerev >= 5) */
+#define SISF_5G_PHY 0x0002 /* 5G capable phy (corerev >= 5) */
+#define SISF_FCLKA 0x0004 /* FastClkAvailable (corerev >= 5) */
+#define SISF_DB_PHY 0x0008 /* Dualband phy (corerev >= 11) */
+
+/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */
+
+#define BPHY_REG_OFT_BASE 0x0
+/* offsets for indirect access to bphy registers */
+#define BPHY_BB_CONFIG 0x01
+#define BPHY_ADCBIAS 0x02
+#define BPHY_ANACORE 0x03
+#define BPHY_PHYCRSTH 0x06
+#define BPHY_TEST 0x0a
+#define BPHY_PA_TX_TO 0x10
+#define BPHY_SYNTH_DC_TO 0x11
+#define BPHY_PA_TX_TIME_UP 0x12
+#define BPHY_RX_FLTR_TIME_UP 0x13
+#define BPHY_TX_POWER_OVERRIDE 0x14
+#define BPHY_RF_OVERRIDE 0x15
+#define BPHY_RF_TR_LOOKUP1 0x16
+#define BPHY_RF_TR_LOOKUP2 0x17
+#define BPHY_COEFFS 0x18
+#define BPHY_PLL_OUT 0x19
+#define BPHY_REFRESH_MAIN 0x1a
+#define BPHY_REFRESH_TO0 0x1b
+#define BPHY_REFRESH_TO1 0x1c
+#define BPHY_RSSI_TRESH 0x20
+#define BPHY_IQ_TRESH_HH 0x21
+#define BPHY_IQ_TRESH_H 0x22
+#define BPHY_IQ_TRESH_L 0x23
+#define BPHY_IQ_TRESH_LL 0x24
+#define BPHY_GAIN 0x25
+#define BPHY_LNA_GAIN_RANGE 0x26
+#define BPHY_JSSI 0x27
+#define BPHY_TSSI_CTL 0x28
+#define BPHY_TSSI 0x29
+#define BPHY_TR_LOSS_CTL 0x2a
+#define BPHY_LO_LEAKAGE 0x2b
+#define BPHY_LO_RSSI_ACC 0x2c
+#define BPHY_LO_IQMAG_ACC 0x2d
+#define BPHY_TX_DC_OFF1 0x2e
+#define BPHY_TX_DC_OFF2 0x2f
+#define BPHY_PEAK_CNT_THRESH 0x30
+#define BPHY_FREQ_OFFSET 0x31
+#define BPHY_DIVERSITY_CTL 0x32
+#define BPHY_PEAK_ENERGY_LO 0x33
+#define BPHY_PEAK_ENERGY_HI 0x34
+#define BPHY_SYNC_CTL 0x35
+#define BPHY_TX_PWR_CTRL 0x36
+#define BPHY_TX_EST_PWR 0x37
+#define BPHY_STEP 0x38
+#define BPHY_WARMUP 0x39
+#define BPHY_LMS_CFF_READ 0x3a
+#define BPHY_LMS_COEFF_I 0x3b
+#define BPHY_LMS_COEFF_Q 0x3c
+#define BPHY_SIG_POW 0x3d
+#define BPHY_RFDC_CANCEL_CTL 0x3e
+#define BPHY_HDR_TYPE 0x40
+#define BPHY_SFD_TO 0x41
+#define BPHY_SFD_CTL 0x42
+#define BPHY_DEBUG 0x43
+#define BPHY_RX_DELAY_COMP 0x44
+#define BPHY_CRS_DROP_TO 0x45
+#define BPHY_SHORT_SFD_NZEROS 0x46
+#define BPHY_DSSS_COEFF1 0x48
+#define BPHY_DSSS_COEFF2 0x49
+#define BPHY_CCK_COEFF1 0x4a
+#define BPHY_CCK_COEFF2 0x4b
+#define BPHY_TR_CORR 0x4c
+#define BPHY_ANGLE_SCALE 0x4d
+#define BPHY_TX_PWR_BASE_IDX 0x4e
+#define BPHY_OPTIONAL_MODES2 0x4f
+#define BPHY_CCK_LMS_STEP 0x50
+#define BPHY_BYPASS 0x51
+#define BPHY_CCK_DELAY_LONG 0x52
+#define BPHY_CCK_DELAY_SHORT 0x53
+#define BPHY_PPROC_CHAN_DELAY 0x54
+#define BPHY_DDFS_ENABLE 0x58
+#define BPHY_PHASE_SCALE 0x59
+#define BPHY_FREQ_CONTROL 0x5a
+#define BPHY_LNA_GAIN_RANGE_10 0x5b
+#define BPHY_LNA_GAIN_RANGE_32 0x5c
+#define BPHY_OPTIONAL_MODES 0x5d
+#define BPHY_RX_STATUS2 0x5e
+#define BPHY_RX_STATUS3 0x5f
+#define BPHY_DAC_CONTROL 0x60
+#define BPHY_ANA11G_FILT_CTRL 0x62
+#define BPHY_REFRESH_CTRL 0x64
+#define BPHY_RF_OVERRIDE2 0x65
+#define BPHY_SPUR_CANCEL_CTRL 0x66
+#define BPHY_FINE_DIGIGAIN_CTRL 0x67
+#define BPHY_RSSI_LUT 0x88
+#define BPHY_RSSI_LUT_END 0xa7
+#define BPHY_TSSI_LUT 0xa8
+#define BPHY_TSSI_LUT_END 0xc7
+#define BPHY_TSSI2PWR_LUT 0x380
+#define BPHY_TSSI2PWR_LUT_END 0x39f
+#define BPHY_LOCOMP_LUT 0x3a0
+#define BPHY_LOCOMP_LUT_END 0x3bf
+#define BPHY_TXGAIN_LUT 0x3c0
+#define BPHY_TXGAIN_LUT_END 0x3ff
+
+/* Bits in BB_CONFIG: */
+#define PHY_BBC_ANT_MASK 0x0180
+#define PHY_BBC_ANT_SHIFT 7
+#define BB_DARWIN 0x1000
+#define BBCFG_RESETCCA 0x4000
+#define BBCFG_RESETRX 0x8000
+
+/* Bits in phytest(0x0a): */
+#define TST_DDFS 0x2000
+#define TST_TXFILT1 0x0800
+#define TST_UNSCRAM 0x0400
+#define TST_CARR_SUPP 0x0200
+#define TST_DC_COMP_LOOP 0x0100
+#define TST_LOOPBACK 0x0080
+#define TST_TXFILT0 0x0040
+#define TST_TXTEST_ENABLE 0x0020
+#define TST_TXTEST_RATE 0x0018
+#define TST_TXTEST_PHASE 0x0007
+
+/* phytest txTestRate values */
+#define TST_TXTEST_RATE_1MBPS 0
+#define TST_TXTEST_RATE_2MBPS 1
+#define TST_TXTEST_RATE_5_5MBPS 2
+#define TST_TXTEST_RATE_11MBPS 3
+#define TST_TXTEST_RATE_SHIFT 3
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#define SHM_BYT_CNT 0x2 /* IHR location */
+#define MAX_BYT_CNT 0x600 /* Maximum frame len */
+
+#endif /* _D11_H */
diff --git a/drivers/staging/brcm80211/include/dbus.h b/drivers/staging/brcm80211/include/dbus.h
new file mode 100644
index 000000000000..d0e374554eb8
--- /dev/null
+++ b/drivers/staging/brcm80211/include/dbus.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 __DBUS_H__
+#define __DBUS_H__
+
+#include "typedefs.h"
+
+#ifdef BCMDBG
+#define DBUSERR(args) do { if (net_ratelimit()) printf args; } while (0)
+#define DBUSTRACE(args)
+#define DBUSDBGLOCK(args)
+
+#else
+#define DBUSTRACE(args)
+#define DBUSERR(args)
+#define DBUSDBGLOCK(args)
+#endif
+
+enum {
+ DBUS_OK = 0,
+ DBUS_ERR = -200,
+ DBUS_ERR_TIMEOUT,
+ DBUS_ERR_DISCONNECT,
+ DBUS_ERR_NODEVICE,
+ DBUS_ERR_UNSUPPORTED,
+ DBUS_ERR_PENDING,
+ DBUS_ERR_NOMEM,
+ DBUS_ERR_TXFAIL,
+ DBUS_ERR_TXTIMEOUT,
+ DBUS_ERR_TXDROP,
+ DBUS_ERR_RXFAIL,
+ DBUS_ERR_RXDROP,
+ DBUS_ERR_TXCTLFAIL,
+ DBUS_ERR_RXCTLFAIL,
+ DBUS_ERR_REG_PARAM,
+ DBUS_STATUS_CANCELLED
+};
+
+#define ERR_CBMASK_TXFAIL 0x00000001
+#define ERR_CBMASK_RXFAIL 0x00000002
+#define ERR_CBMASK_ALL 0xFFFFFFFF
+
+#define DBUS_CBCTL_WRITE 0
+#define DBUS_CBCTL_READ 1
+
+#define DBUS_TX_RETRY_LIMIT 3 /* retries for failed txirb */
+#define DBUS_TX_TIMEOUT_INTERVAL 250 /* timeout for txirb complete, in ms */
+
+#define DBUS_BUFFER_SIZE_TX 5000
+#define DBUS_BUFFER_SIZE_RX 5000
+
+#define DBUS_BUFFER_SIZE_TX_NOAGG 2048
+#define DBUS_BUFFER_SIZE_RX_NOAGG 2048
+
+/* DBUS types */
+enum {
+ DBUS_USB,
+ DBUS_SDIO,
+ DBUS_SPI,
+ DBUS_UNKNOWN
+};
+
+enum dbus_state {
+ DBUS_STATE_DL_PENDING,
+ DBUS_STATE_DL_DONE,
+ DBUS_STATE_UP,
+ DBUS_STATE_DOWN,
+ DBUS_STATE_PNP_FWDL,
+ DBUS_STATE_DISCONNECT
+};
+
+enum dbus_pnp_state {
+ DBUS_PNP_DISCONNECT,
+ DBUS_PNP_SLEEP,
+ DBUS_PNP_RESUME
+};
+
+typedef enum _DEVICE_SPEED {
+ INVALID_SPEED = -1,
+ LOW_SPEED = 1, /* USB 1.1: 1.5 Mbps */
+ FULL_SPEED, /* USB 1.1: 12 Mbps */
+ HIGH_SPEED, /* USB 2.0: 480 Mbps */
+ SUPER_SPEED, /* USB 3.0: 4.8 Gbps */
+} DEVICE_SPEED;
+
+typedef struct {
+ int bustype;
+ int vid;
+ int pid;
+ int devid;
+ int chiprev; /* chip revsion number */
+ int mtu;
+ int nchan; /* Data Channels */
+} dbus_attrib_t;
+
+/* FIX: Account for errors related to DBUS;
+ * Let upper layer account for packets/bytes
+ */
+typedef struct {
+ uint32 rx_errors;
+ uint32 tx_errors;
+ uint32 rx_dropped;
+ uint32 tx_dropped;
+} dbus_stats_t;
+
+/*
+ * Configurable BUS parameters
+ */
+typedef struct {
+ bool rxctl_deferrespok;
+} dbus_config_t;
+
+struct dbus_callbacks;
+struct exec_parms;
+
+typedef void *(*probe_cb_t) (void *arg, const char *desc, uint32 bustype,
+ uint32 hdrlen);
+typedef void (*disconnect_cb_t) (void *arg);
+typedef void *(*exec_cb_t) (struct exec_parms *args);
+
+/* Client callbacks registered during dbus_attach() */
+typedef struct dbus_callbacks {
+ void (*send_complete) (void *cbarg, void *info, int status);
+ void (*recv_buf) (void *cbarg, uint8 *buf, int len);
+ void (*recv_pkt) (void *cbarg, void *pkt);
+ void (*txflowcontrol) (void *cbarg, bool onoff);
+ void (*errhandler) (void *cbarg, int err);
+ void (*ctl_complete) (void *cbarg, int type, int status);
+ void (*state_change) (void *cbarg, int state);
+ void *(*pktget) (void *cbarg, uint len, bool send);
+ void (*pktfree) (void *cbarg, void *p, bool send);
+} dbus_callbacks_t;
+
+struct dbus_pub;
+struct bcmstrbuf;
+struct dbus_irb;
+struct dbus_irb_rx;
+struct dbus_irb_tx;
+struct dbus_intf_callbacks;
+
+typedef struct {
+ void *(*attach) (struct dbus_pub *pub, void *cbarg,
+ struct dbus_intf_callbacks *cbs);
+ void (*detach) (struct dbus_pub *pub, void *bus);
+
+ int (*up) (void *bus);
+ int (*down) (void *bus);
+ int (*send_irb) (void *bus, struct dbus_irb_tx *txirb);
+ int (*recv_irb) (void *bus, struct dbus_irb_rx *rxirb);
+ int (*cancel_irb) (void *bus, struct dbus_irb_tx *txirb);
+ int (*send_ctl) (void *bus, uint8 *buf, int len);
+ int (*recv_ctl) (void *bus, uint8 *buf, int len);
+ int (*get_stats) (void *bus, dbus_stats_t *stats);
+ int (*get_attrib) (void *bus, dbus_attrib_t *attrib);
+
+ int (*pnp) (void *bus, int event);
+ int (*remove) (void *bus);
+ int (*resume) (void *bus);
+ int (*suspend) (void *bus);
+ int (*stop) (void *bus);
+ int (*reset) (void *bus);
+
+ /* Access to bus buffers directly */
+ void *(*pktget) (void *bus, int len);
+ void (*pktfree) (void *bus, void *pkt);
+
+ int (*iovar_op) (void *bus, const char *name, void *params, int plen,
+ void *arg, int len, bool set);
+ void (*dump) (void *bus, struct bcmstrbuf *strbuf);
+ int (*set_config) (void *bus, dbus_config_t *config);
+ int (*get_config) (void *bus, dbus_config_t *config);
+
+ bool(*device_exists) (void *bus);
+ bool(*dlneeded) (void *bus);
+ int (*dlstart) (void *bus, uint8 *fw, int len);
+ int (*dlrun) (void *bus);
+ bool(*recv_needed) (void *bus);
+
+ void *(*exec_rxlock) (void *bus, exec_cb_t func,
+ struct exec_parms *args);
+ void *(*exec_txlock) (void *bus, exec_cb_t func,
+ struct exec_parms *args);
+
+ int (*tx_timer_init) (void *bus);
+ int (*tx_timer_start) (void *bus, uint timeout);
+ int (*tx_timer_stop) (void *bus);
+
+ int (*sched_dpc) (void *bus);
+ int (*lock) (void *bus);
+ int (*unlock) (void *bus);
+ int (*sched_probe_cb) (void *bus);
+
+ int (*shutdown) (void *bus);
+
+ int (*recv_stop) (void *bus);
+ int (*recv_resume) (void *bus);
+
+ /* Add from the bottom */
+} dbus_intf_t;
+
+typedef struct dbus_pub {
+ struct osl_info *osh;
+ dbus_stats_t stats;
+ dbus_attrib_t attrib;
+ enum dbus_state busstate;
+ DEVICE_SPEED device_speed;
+ int ntxq, nrxq, rxsize;
+ void *bus;
+ struct shared_info *sh;
+} dbus_pub_t;
+
+#define BUS_INFO(bus, type) (((type *) bus)->pub->bus)
+
+/*
+ * Public Bus Function Interface
+ */
+extern int dbus_register(int vid, int pid, probe_cb_t prcb,
+ disconnect_cb_t discb, void *prarg, void *param1,
+ void *param2);
+extern int dbus_deregister(void);
+
+extern const dbus_pub_t *dbus_attach(struct osl_info *osh, int rxsize, int nrxq,
+ int ntxq, void *cbarg,
+ dbus_callbacks_t *cbs,
+ struct shared_info *sh);
+extern void dbus_detach(const dbus_pub_t *pub);
+
+extern int dbus_up(const dbus_pub_t *pub);
+extern int dbus_down(const dbus_pub_t *pub);
+extern int dbus_stop(const dbus_pub_t *pub);
+extern int dbus_shutdown(const dbus_pub_t *pub);
+extern void dbus_flowctrl_rx(const dbus_pub_t *pub, bool on);
+
+extern int dbus_send_buf(const dbus_pub_t *pub, uint8 *buf, int len,
+ void *info);
+extern int dbus_send_pkt(const dbus_pub_t *pub, void *pkt, void *info);
+extern int dbus_send_ctl(const dbus_pub_t *pub, uint8 *buf, int len);
+extern int dbus_recv_ctl(const dbus_pub_t *pub, uint8 *buf, int len);
+
+extern int dbus_get_stats(const dbus_pub_t *pub, dbus_stats_t *stats);
+extern int dbus_get_attrib(const dbus_pub_t *pub, dbus_attrib_t *attrib);
+extern int dbus_get_device_speed(const dbus_pub_t *pub);
+extern int dbus_set_config(const dbus_pub_t *pub, dbus_config_t *config);
+extern int dbus_get_config(const dbus_pub_t *pub, dbus_config_t *config);
+
+extern void *dbus_pktget(const dbus_pub_t *pub, int len);
+extern void dbus_pktfree(const dbus_pub_t *pub, void *pkt);
+
+extern int dbus_set_errmask(const dbus_pub_t *pub, uint32 mask);
+extern int dbus_pnp_sleep(const dbus_pub_t *pub);
+extern int dbus_pnp_resume(const dbus_pub_t *pub, int *fw_reload);
+extern int dbus_pnp_disconnect(const dbus_pub_t *pub);
+
+extern int dbus_iovar_op(const dbus_pub_t *pub, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+#ifdef BCMDBG
+extern void dbus_hist_dump(const dbus_pub_t *pub, struct bcmstrbuf *b);
+#endif /* BCMDBG */
+/*
+ * Private Common Bus Interface
+ */
+
+/* IO Request Block (IRB) */
+typedef struct dbus_irb {
+ struct dbus_irb *next; /* it's casted from dbus_irb_tx or dbus_irb_rx struct */
+} dbus_irb_t;
+
+typedef struct dbus_irb_rx {
+ struct dbus_irb irb; /* Must be first */
+ uint8 *buf;
+ int buf_len;
+ int actual_len;
+ void *pkt;
+ void *info;
+ void *arg;
+} dbus_irb_rx_t;
+
+typedef struct dbus_irb_tx {
+ struct dbus_irb irb; /* Must be first */
+ uint8 *buf;
+ int len;
+ void *pkt;
+ int retry_count;
+ void *info;
+ void *arg;
+} dbus_irb_tx_t;
+
+/* DBUS interface callbacks are different from user callbacks
+ * so, internally, different info can be passed to upper layer
+ */
+typedef struct dbus_intf_callbacks {
+ void (*send_irb_timeout) (void *cbarg, dbus_irb_tx_t *txirb);
+ void (*send_irb_complete) (void *cbarg, dbus_irb_tx_t *txirb,
+ int status);
+ void (*recv_irb_complete) (void *cbarg, dbus_irb_rx_t *rxirb,
+ int status);
+ void (*errhandler) (void *cbarg, int err);
+ void (*ctl_complete) (void *cbarg, int type, int status);
+ void (*state_change) (void *cbarg, int state);
+ bool(*isr) (void *cbarg, bool *wantdpc);
+ bool(*dpc) (void *cbarg, bool bounded);
+ void (*watchdog) (void *cbarg);
+ void *(*pktget) (void *cbarg, uint len, bool send);
+ void (*pktfree) (void *cbarg, void *p, bool send);
+ struct dbus_irb *(*getirb) (void *cbarg, bool send);
+ void (*rxerr_indicate) (void *cbarg, bool on);
+} dbus_intf_callbacks_t;
+
+/*
+ * Porting: To support new bus, port these functions below
+ */
+
+/*
+ * Bus specific Interface
+ * Implemented by dbus_usb.c/dbus_sdio.c
+ */
+extern int dbus_bus_register(int vid, int pid, probe_cb_t prcb,
+ disconnect_cb_t discb, void *prarg,
+ dbus_intf_t **intf, void *param1, void *param2);
+extern int dbus_bus_deregister(void);
+
+/*
+ * Bus-specific and OS-specific Interface
+ * Implemented by dbus_usb_[linux/ndis].c/dbus_sdio_[linux/ndis].c
+ */
+extern int dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb,
+ disconnect_cb_t discb, void *prarg,
+ dbus_intf_t **intf, void *param1,
+ void *param2);
+extern int dbus_bus_osl_deregister(void);
+
+/*
+ * Bus-specific, OS-specific, HW-specific Interface
+ * Mainly for SDIO Host HW controller
+ */
+extern int dbus_bus_osl_hw_register(int vid, int pid, probe_cb_t prcb,
+ disconnect_cb_t discb, void *prarg,
+ dbus_intf_t **intf);
+extern int dbus_bus_osl_hw_deregister(void);
+
+#endif /* __DBUS_H__ */
diff --git a/drivers/staging/brcm80211/include/epivers.h b/drivers/staging/brcm80211/include/epivers.h
new file mode 100644
index 000000000000..2e6b5190ad6c
--- /dev/null
+++ b/drivers/staging/brcm80211/include/epivers.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _epivers_h_
+#define _epivers_h_
+
+#define EPI_MAJOR_VERSION 5
+
+#define EPI_MINOR_VERSION 75
+
+#define EPI_RC_NUMBER 11
+
+#define EPI_INCREMENTAL_NUMBER 0
+
+#define EPI_BUILD_NUMBER 1
+
+#define EPI_VERSION { 5, 75, 11, 0 }
+
+#ifdef BCMSDIO
+/* EPI_VERSION_NUM must match FW version */
+#define EPI_VERSION_NUM 0x054b0c00
+#else
+#define EPI_VERSION_NUM 0x054b0b00
+#endif
+
+#define EPI_VERSION_DEV 5.75.11
+
+/* Driver Version String, ASCII, 32 chars max */
+#define EPI_VERSION_STR "5.75.11"
+
+#endif /* _epivers_h_ */
diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h
new file mode 100644
index 000000000000..1a35f3e7670e
--- /dev/null
+++ b/drivers/staging/brcm80211/include/hnddma.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _hnddma_h_
+#define _hnddma_h_
+
+#ifndef _hnddma_pub_
+#define _hnddma_pub_
+typedef const struct hnddma_pub hnddma_t;
+#endif /* _hnddma_pub_ */
+
+/* range param for dma_getnexttxp() and dma_txreclaim */
+typedef enum txd_range {
+ HNDDMA_RANGE_ALL = 1,
+ HNDDMA_RANGE_TRANSMITTED,
+ HNDDMA_RANGE_TRANSFERED
+} txd_range_t;
+
+/* dma function type */
+typedef void (*di_detach_t) (hnddma_t *dmah);
+typedef bool(*di_txreset_t) (hnddma_t *dmah);
+typedef bool(*di_rxreset_t) (hnddma_t *dmah);
+typedef bool(*di_rxidle_t) (hnddma_t *dmah);
+typedef void (*di_txinit_t) (hnddma_t *dmah);
+typedef bool(*di_txenabled_t) (hnddma_t *dmah);
+typedef void (*di_rxinit_t) (hnddma_t *dmah);
+typedef void (*di_txsuspend_t) (hnddma_t *dmah);
+typedef void (*di_txresume_t) (hnddma_t *dmah);
+typedef bool(*di_txsuspended_t) (hnddma_t *dmah);
+typedef bool(*di_txsuspendedidle_t) (hnddma_t *dmah);
+typedef int (*di_txfast_t) (hnddma_t *dmah, void *p, bool commit);
+typedef int (*di_txunframed_t) (hnddma_t *dmah, void *p, uint len,
+ bool commit);
+typedef void *(*di_getpos_t) (hnddma_t *di, bool direction);
+typedef void (*di_fifoloopbackenable_t) (hnddma_t *dmah);
+typedef bool(*di_txstopped_t) (hnddma_t *dmah);
+typedef bool(*di_rxstopped_t) (hnddma_t *dmah);
+typedef bool(*di_rxenable_t) (hnddma_t *dmah);
+typedef bool(*di_rxenabled_t) (hnddma_t *dmah);
+typedef void *(*di_rx_t) (hnddma_t *dmah);
+typedef bool(*di_rxfill_t) (hnddma_t *dmah);
+typedef void (*di_txreclaim_t) (hnddma_t *dmah, txd_range_t range);
+typedef void (*di_rxreclaim_t) (hnddma_t *dmah);
+typedef uintptr(*di_getvar_t) (hnddma_t *dmah, const char *name);
+typedef void *(*di_getnexttxp_t) (hnddma_t *dmah, txd_range_t range);
+typedef void *(*di_getnextrxp_t) (hnddma_t *dmah, bool forceall);
+typedef void *(*di_peeknexttxp_t) (hnddma_t *dmah);
+typedef void *(*di_peeknextrxp_t) (hnddma_t *dmah);
+typedef void (*di_rxparam_get_t) (hnddma_t *dmah, uint16 *rxoffset,
+ uint16 *rxbufsize);
+typedef void (*di_txblock_t) (hnddma_t *dmah);
+typedef void (*di_txunblock_t) (hnddma_t *dmah);
+typedef uint(*di_txactive_t) (hnddma_t *dmah);
+typedef void (*di_txrotate_t) (hnddma_t *dmah);
+typedef void (*di_counterreset_t) (hnddma_t *dmah);
+typedef uint(*di_ctrlflags_t) (hnddma_t *dmah, uint mask, uint flags);
+typedef char *(*di_dump_t) (hnddma_t *dmah, struct bcmstrbuf *b,
+ bool dumpring);
+typedef char *(*di_dumptx_t) (hnddma_t *dmah, struct bcmstrbuf *b,
+ bool dumpring);
+typedef char *(*di_dumprx_t) (hnddma_t *dmah, struct bcmstrbuf *b,
+ bool dumpring);
+typedef uint(*di_rxactive_t) (hnddma_t *dmah);
+typedef uint(*di_txpending_t) (hnddma_t *dmah);
+typedef uint(*di_txcommitted_t) (hnddma_t *dmah);
+
+/* dma opsvec */
+typedef struct di_fcn_s {
+ di_detach_t detach;
+ di_txinit_t txinit;
+ di_txreset_t txreset;
+ di_txenabled_t txenabled;
+ di_txsuspend_t txsuspend;
+ di_txresume_t txresume;
+ di_txsuspended_t txsuspended;
+ di_txsuspendedidle_t txsuspendedidle;
+ di_txfast_t txfast;
+ di_txunframed_t txunframed;
+ di_getpos_t getpos;
+ di_txstopped_t txstopped;
+ di_txreclaim_t txreclaim;
+ di_getnexttxp_t getnexttxp;
+ di_peeknexttxp_t peeknexttxp;
+ di_txblock_t txblock;
+ di_txunblock_t txunblock;
+ di_txactive_t txactive;
+ di_txrotate_t txrotate;
+
+ di_rxinit_t rxinit;
+ di_rxreset_t rxreset;
+ di_rxidle_t rxidle;
+ di_rxstopped_t rxstopped;
+ di_rxenable_t rxenable;
+ di_rxenabled_t rxenabled;
+ di_rx_t rx;
+ di_rxfill_t rxfill;
+ di_rxreclaim_t rxreclaim;
+ di_getnextrxp_t getnextrxp;
+ di_peeknextrxp_t peeknextrxp;
+ di_rxparam_get_t rxparam_get;
+
+ di_fifoloopbackenable_t fifoloopbackenable;
+ di_getvar_t d_getvar;
+ di_counterreset_t counterreset;
+ di_ctrlflags_t ctrlflags;
+ di_dump_t dump;
+ di_dumptx_t dumptx;
+ di_dumprx_t dumprx;
+ di_rxactive_t rxactive;
+ di_txpending_t txpending;
+ di_txcommitted_t txcommitted;
+ uint endnum;
+} di_fcn_t;
+
+/*
+ * Exported data structure (read-only)
+ */
+/* export structure */
+struct hnddma_pub {
+ const di_fcn_t *di_fn; /* DMA function pointers */
+ uint txavail; /* # free tx descriptors */
+ uint dmactrlflags; /* dma control flags */
+
+ /* rx error counters */
+ uint rxgiants; /* rx giant frames */
+ uint rxnobuf; /* rx out of dma descriptors */
+ /* tx error counters */
+ uint txnobuf; /* tx out of dma descriptors */
+};
+
+extern hnddma_t *dma_attach(osl_t *osh, char *name, si_t *sih,
+ void *dmaregstx, void *dmaregsrx, uint ntxd,
+ uint nrxd, uint rxbufsize, int rxextheadroom,
+ uint nrxpost, uint rxoffset, uint *msg_level);
+#ifdef BCMDMA32
+
+#define dma_detach(di) ((di)->di_fn->detach(di))
+#define dma_txreset(di) ((di)->di_fn->txreset(di))
+#define dma_rxreset(di) ((di)->di_fn->rxreset(di))
+#define dma_rxidle(di) ((di)->di_fn->rxidle(di))
+#define dma_txinit(di) ((di)->di_fn->txinit(di))
+#define dma_txenabled(di) ((di)->di_fn->txenabled(di))
+#define dma_rxinit(di) ((di)->di_fn->rxinit(di))
+#define dma_txsuspend(di) ((di)->di_fn->txsuspend(di))
+#define dma_txresume(di) ((di)->di_fn->txresume(di))
+#define dma_txsuspended(di) ((di)->di_fn->txsuspended(di))
+#define dma_txsuspendedidle(di) ((di)->di_fn->txsuspendedidle(di))
+#define dma_txfast(di, p, commit) ((di)->di_fn->txfast(di, p, commit))
+#define dma_fifoloopbackenable(di) ((di)->di_fn->fifoloopbackenable(di))
+#define dma_txstopped(di) ((di)->di_fn->txstopped(di))
+#define dma_rxstopped(di) ((di)->di_fn->rxstopped(di))
+#define dma_rxenable(di) ((di)->di_fn->rxenable(di))
+#define dma_rxenabled(di) ((di)->di_fn->rxenabled(di))
+#define dma_rx(di) ((di)->di_fn->rx(di))
+#define dma_rxfill(di) ((di)->di_fn->rxfill(di))
+#define dma_txreclaim(di, range) ((di)->di_fn->txreclaim(di, range))
+#define dma_rxreclaim(di) ((di)->di_fn->rxreclaim(di))
+#define dma_getvar(di, name) ((di)->di_fn->d_getvar(di, name))
+#define dma_getnexttxp(di, range) ((di)->di_fn->getnexttxp(di, range))
+#define dma_getnextrxp(di, forceall) ((di)->di_fn->getnextrxp(di, forceall))
+#define dma_peeknexttxp(di) ((di)->di_fn->peeknexttxp(di))
+#define dma_peeknextrxp(di) ((di)->di_fn->peeknextrxp(di))
+#define dma_rxparam_get(di, off, bufs) ((di)->di_fn->rxparam_get(di, off, bufs))
+
+#define dma_txblock(di) ((di)->di_fn->txblock(di))
+#define dma_txunblock(di) ((di)->di_fn->txunblock(di))
+#define dma_txactive(di) ((di)->di_fn->txactive(di))
+#define dma_rxactive(di) ((di)->di_fn->rxactive(di))
+#define dma_txrotate(di) ((di)->di_fn->txrotate(di))
+#define dma_counterreset(di) ((di)->di_fn->counterreset(di))
+#define dma_ctrlflags(di, mask, flags) ((di)->di_fn->ctrlflags((di), (mask), (flags)))
+#define dma_txpending(di) ((di)->di_fn->txpending(di))
+#define dma_txcommitted(di) ((di)->di_fn->txcommitted(di))
+
+#else /* BCMDMA32 */
+extern const di_fcn_t dma64proc;
+
+#define dma_detach(di) (dma64proc.detach(di))
+#define dma_txreset(di) (dma64proc.txreset(di))
+#define dma_rxreset(di) (dma64proc.rxreset(di))
+#define dma_rxidle(di) (dma64proc.rxidle(di))
+#define dma_txinit(di) (dma64proc.txinit(di))
+#define dma_txenabled(di) (dma64proc.txenabled(di))
+#define dma_rxinit(di) (dma64proc.rxinit(di))
+#define dma_txsuspend(di) (dma64proc.txsuspend(di))
+#define dma_txresume(di) (dma64proc.txresume(di))
+#define dma_txsuspended(di) (dma64proc.txsuspended(di))
+#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di))
+#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit))
+#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
+#define dma_getpos(di, dir) (dma64proc.getpos(di, dir))
+#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di))
+#define dma_txstopped(di) (dma64proc.txstopped(di))
+#define dma_rxstopped(di) (dma64proc.rxstopped(di))
+#define dma_rxenable(di) (dma64proc.rxenable(di))
+#define dma_rxenabled(di) (dma64proc.rxenabled(di))
+#define dma_rx(di) (dma64proc.rx(di))
+#define dma_rxfill(di) (dma64proc.rxfill(di))
+#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range))
+#define dma_rxreclaim(di) (dma64proc.rxreclaim(di))
+#define dma_getvar(di, name) (dma64proc.d_getvar(di, name))
+#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range))
+#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall))
+#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di))
+#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di))
+#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs))
+
+#define dma_txblock(di) (dma64proc.txblock(di))
+#define dma_txunblock(di) (dma64proc.txunblock(di))
+#define dma_txactive(di) (dma64proc.txactive(di))
+#define dma_rxactive(di) (dma64proc.rxactive(di))
+#define dma_txrotate(di) (dma64proc.txrotate(di))
+#define dma_counterreset(di) (dma64proc.counterreset(di))
+#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags)))
+#define dma_txpending(di) (dma64proc.txpending(di))
+#define dma_txcommitted(di) (dma64proc.txcommitted(di))
+
+#endif /* BCMDMA32 */
+
+/* return addresswidth allowed
+ * This needs to be done after SB attach but before dma attach.
+ * SB attach provides ability to probe backplane and dma core capabilities
+ * This info is needed by DMA_ALLOC_CONSISTENT in dma attach
+ */
+extern uint dma_addrwidth(si_t *sih, void *dmaregs);
+
+/* pio helpers */
+extern void dma_txpioloopback(osl_t *osh, dma32regs_t *);
+
+#endif /* _hnddma_h_ */
diff --git a/drivers/staging/brcm80211/include/hndpmu.h b/drivers/staging/brcm80211/include/hndpmu.h
new file mode 100644
index 000000000000..24f6dd6b5ac7
--- /dev/null
+++ b/drivers/staging/brcm80211/include/hndpmu.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _hndpmu_h_
+#define _hndpmu_h_
+
+#define SET_LDO_VOLTAGE_LDO1 1
+#define SET_LDO_VOLTAGE_LDO2 2
+#define SET_LDO_VOLTAGE_LDO3 3
+#define SET_LDO_VOLTAGE_PAREF 4
+#define SET_LDO_VOLTAGE_CLDO_PWM 5
+#define SET_LDO_VOLTAGE_CLDO_BURST 6
+#define SET_LDO_VOLTAGE_CBUCK_PWM 7
+#define SET_LDO_VOLTAGE_CBUCK_BURST 8
+#define SET_LDO_VOLTAGE_LNLDO1 9
+#define SET_LDO_VOLTAGE_LNLDO2_SEL 10
+
+extern void si_pmu_init(si_t *sih, osl_t *osh);
+extern void si_pmu_chip_init(si_t *sih, osl_t *osh);
+extern void si_pmu_pll_init(si_t *sih, osl_t *osh, uint32 xtalfreq);
+extern void si_pmu_res_init(si_t *sih, osl_t *osh);
+extern void si_pmu_swreg_init(si_t *sih, osl_t *osh);
+
+extern uint32 si_pmu_force_ilp(si_t *sih, osl_t *osh, bool force);
+
+extern uint32 si_pmu_si_clock(si_t *sih, osl_t *osh);
+extern uint32 si_pmu_cpu_clock(si_t *sih, osl_t *osh);
+extern uint32 si_pmu_mem_clock(si_t *sih, osl_t *osh);
+extern uint32 si_pmu_alp_clock(si_t *sih, osl_t *osh);
+extern uint32 si_pmu_ilp_clock(si_t *sih, osl_t *osh);
+
+extern void si_pmu_set_switcher_voltage(si_t *sih, osl_t *osh,
+ uint8 bb_voltage, uint8 rf_voltage);
+extern void si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, uint8 ldo,
+ uint8 voltage);
+extern uint16 si_pmu_fast_pwrup_delay(si_t *sih, osl_t *osh);
+extern void si_pmu_rcal(si_t *sih, osl_t *osh);
+extern void si_pmu_pllupd(si_t *sih);
+extern void si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid);
+
+extern bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh);
+extern uint32 si_pmu_measure_alpclk(si_t *sih, osl_t *osh);
+
+extern uint32 si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val);
+extern uint32 si_pmu_regcontrol(si_t *sih, uint reg, uint32 mask, uint32 val);
+extern uint32 si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val);
+extern void si_pmu_pllupd(si_t *sih);
+extern void si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable);
+
+extern void si_pmu_radio_enable(si_t *sih, bool enable);
+extern uint32 si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh,
+ uint32 clk, uint32 delay);
+
+extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on);
+extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh,
+ uint32 drivestrength);
+
+#endif /* _hndpmu_h_ */
diff --git a/drivers/staging/brcm80211/include/hndsoc.h b/drivers/staging/brcm80211/include/hndsoc.h
new file mode 100644
index 000000000000..9747cc46ca96
--- /dev/null
+++ b/drivers/staging/brcm80211/include/hndsoc.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _HNDSOC_H
+#define _HNDSOC_H
+
+/* Include the soci specific files */
+#include <sbconfig.h>
+#include <aidmp.h>
+
+/*
+ * SOC Interconnect Address Map.
+ * All regions may not exist on all chips.
+ */
+#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */
+#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */
+#define SI_PCI_MEM_SZ (64 * 1024 * 1024)
+#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */
+#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
+#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */
+
+#ifdef SI_ENUM_BASE_VARIABLE
+#define SI_ENUM_BASE (sii->pub.si_enum_base)
+#else
+#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
+#endif /* SI_ENUM_BASE_VARIABLE */
+
+#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */
+#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */
+#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software
+ * convenience and could be changed if we
+ * make any larger chips
+ */
+
+#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */
+#define SI_FASTRAM_SWAPPED 0x19800000
+
+#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
+#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
+#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */
+#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */
+#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */
+#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */
+#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */
+#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */
+#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */
+#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */
+
+#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
+#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2
+ * (2 ZettaBytes), low 32 bits
+ */
+#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2
+ * (2 ZettaBytes), high 32 bits
+ */
+
+/* core codes */
+#define NODEV_CORE_ID 0x700 /* Invalid coreid */
+#define CC_CORE_ID 0x800 /* chipcommon core */
+#define ILINE20_CORE_ID 0x801 /* iline20 core */
+#define SRAM_CORE_ID 0x802 /* sram core */
+#define SDRAM_CORE_ID 0x803 /* sdram core */
+#define PCI_CORE_ID 0x804 /* pci core */
+#define MIPS_CORE_ID 0x805 /* mips core */
+#define ENET_CORE_ID 0x806 /* enet mac core */
+#define CODEC_CORE_ID 0x807 /* v90 codec core */
+#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
+#define ADSL_CORE_ID 0x809 /* ADSL core */
+#define ILINE100_CORE_ID 0x80a /* iline100 core */
+#define IPSEC_CORE_ID 0x80b /* ipsec core */
+#define UTOPIA_CORE_ID 0x80c /* utopia core */
+#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
+#define SOCRAM_CORE_ID 0x80e /* internal memory core */
+#define MEMC_CORE_ID 0x80f /* memc sdram core */
+#define OFDM_CORE_ID 0x810 /* OFDM phy core */
+#define EXTIF_CORE_ID 0x811 /* external interface core */
+#define D11_CORE_ID 0x812 /* 802.11 MAC core */
+#define APHY_CORE_ID 0x813 /* 802.11a phy core */
+#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
+#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
+#define MIPS33_CORE_ID 0x816 /* mips3302 core */
+#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
+#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
+#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
+#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
+#define SDIOH_CORE_ID 0x81b /* sdio host core */
+#define ROBO_CORE_ID 0x81c /* roboswitch core */
+#define ATA100_CORE_ID 0x81d /* parallel ATA core */
+#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
+#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
+#define PCIE_CORE_ID 0x820 /* pci express core */
+#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
+#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
+#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
+#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
+#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
+#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
+#define PMU_CORE_ID 0x827 /* PMU core */
+#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
+#define SDIOD_CORE_ID 0x829 /* SDIO device core */
+#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
+#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
+#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
+#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
+#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
+#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
+#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
+#define SC_CORE_ID 0x831 /* shared common core */
+#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
+#define SPIH_CORE_ID 0x833 /* SPI host core */
+#define I2S_CORE_ID 0x834 /* I2S core */
+#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
+#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
+#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
+#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all
+ * unused address ranges
+ */
+
+/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+ * and chipcommon being the first core:
+ */
+#define SI_CC_IDX 0
+
+/* SOC Interconnect types (aka chip types) */
+#define SOCI_AI 1
+
+/* Common core control flags */
+#define SICF_BIST_EN 0x8000
+#define SICF_PME_EN 0x4000
+#define SICF_CORE_BITS 0x3ffc
+#define SICF_FGC 0x0002
+#define SICF_CLOCK_EN 0x0001
+
+/* Common core status flags */
+#define SISF_BIST_DONE 0x8000
+#define SISF_BIST_ERROR 0x4000
+#define SISF_GATED_CLK 0x2000
+#define SISF_DMA64 0x1000
+#define SISF_CORE_BITS 0x0fff
+
+/* A register that is common to all cores to
+ * communicate w/PMU regarding clock control.
+ */
+#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
+
+/* clk_ctl_st register */
+#define CCS_FORCEALP 0x00000001 /* force ALP request */
+#define CCS_FORCEHT 0x00000002 /* force HT request */
+#define CCS_FORCEILP 0x00000004 /* force ILP request */
+#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
+#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
+#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
+#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
+#define CCS_ERSRC_REQ_SHIFT 8
+#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
+#define CCS_HTAVAIL 0x00020000 /* HT is available */
+#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */
+#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */
+#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
+#define CCS_ERSRC_STS_SHIFT 24
+
+#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */
+#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */
+
+/* Not really related to SOC Interconnect, but a couple of software
+ * conventions for the use the flash space:
+ */
+
+/* Minumum amount of flash we support */
+#define FLASH_MIN 0x00020000 /* Minimum flash size */
+
+/* A boot/binary may have an embedded block that describes its size */
+#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
+#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */
+#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
+#define BISZ_TXTST_IDX 1 /* 1: text start */
+#define BISZ_TXTEND_IDX 2 /* 2: text end */
+#define BISZ_DATAST_IDX 3 /* 3: data start */
+#define BISZ_DATAEND_IDX 4 /* 4: data end */
+#define BISZ_BSSST_IDX 5 /* 5: bss start */
+#define BISZ_BSSEND_IDX 6 /* 6: bss end */
+#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */
+
+#endif /* _HNDSOC_H */
diff --git a/drivers/staging/brcm80211/include/hndtcam.h b/drivers/staging/brcm80211/include/hndtcam.h
new file mode 100644
index 000000000000..575456e6764c
--- /dev/null
+++ b/drivers/staging/brcm80211/include/hndtcam.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _hndtcam_h_
+#define _hndtcam_h_
+
+/*
+ * 0 - 1
+ * 1 - 2 Consecutive locations are patched
+ * 2 - 4 Consecutive locations are patched
+ * 3 - 8 Consecutive locations are patched
+ * 4 - 16 Consecutive locations are patched
+ * Define default to patch 2 locations
+ */
+
+#define PATCHCOUNT 0
+#define SRPC_PATCHCOUNT PATCHCOUNT
+
+/* N Consecutive location to patch */
+#define SRPC_PATCHNLOC (1 << (SRPC_PATCHCOUNT))
+
+/* patch values and address structure */
+typedef struct patchaddrvalue {
+ uint32 addr;
+ uint32 value;
+} patchaddrvalue_t;
+
+extern void hnd_patch_init(void *srp);
+extern void hnd_tcam_write(void *srp, uint16 index, uint32 data);
+extern void hnd_tcam_read(void *srp, uint16 index, uint32 * content);
+void *hnd_tcam_init(void *srp, uint no_addrs);
+extern void hnd_tcam_disablepatch(void *srp);
+extern void hnd_tcam_enablepatch(void *srp);
+extern void hnd_tcam_load(void *srp, const patchaddrvalue_t * patchtbl);
+#endif /* _hndtcam_h_ */
diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h
new file mode 100644
index 000000000000..0e61de1b5fc1
--- /dev/null
+++ b/drivers/staging/brcm80211/include/linux_osl.h
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _linux_osl_h_
+#define _linux_osl_h_
+
+#include <typedefs.h>
+
+/* Linux Kernel: File Operations: start */
+extern void *osl_os_open_image(char *filename);
+extern int osl_os_get_image_block(char *buf, int len, void *image);
+extern void osl_os_close_image(void *image);
+/* Linux Kernel: File Operations: end */
+
+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
+extern void osl_detach(osl_t *osh);
+
+extern uint32 g_assert_type;
+
+#if defined(BCMDBG_ASSERT)
+#define ASSERT(exp) \
+ do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
+extern void osl_assert(char *exp, char *file, int line);
+#else
+#ifdef __GNUC__
+#define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION > 30100
+#define ASSERT(exp) do {} while (0)
+#else
+ /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */
+#define ASSERT(exp)
+#endif /* GCC_VERSION > 30100 */
+#endif /* __GNUC__ */
+#endif /* defined(BCMDBG_ASSERT) */
+
+#define OSL_DELAY(usec) osl_delay(usec)
+extern void osl_delay(uint usec);
+
+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
+ osl_pcmcia_read_attr((osh), (offset), (buf), (size))
+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
+ osl_pcmcia_write_attr((osh), (offset), (buf), (size))
+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf,
+ int size);
+
+/* PCI configuration space access macros */
+#define OSL_PCI_READ_CONFIG(osh, offset, size) \
+ osl_pci_read_config((osh), (offset), (size))
+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
+ osl_pci_write_config((osh), (offset), (size), (val))
+extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size);
+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
+
+/* PCI device bus # and slot # */
+#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
+extern uint osl_pci_bus(osl_t *osh);
+extern uint osl_pci_slot(osl_t *osh);
+
+/* Pkttag flag should be part of public information */
+typedef struct {
+ bool pkttag;
+ uint pktalloced; /* Number of allocated packet buffers */
+ bool mmbus; /* Bus supports memory-mapped register accesses */
+ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
+ void *tx_ctx; /* Context to the callback function */
+#ifdef BCMSDIO
+ osl_rreg_fn_t rreg_fn; /* Read Register function */
+ osl_wreg_fn_t wreg_fn; /* Write Register function */
+ void *reg_ctx; /* Context to the reg callback functions */
+#endif
+} osl_pubinfo_t;
+
+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
+ do { \
+ ((osl_pubinfo_t *)osh)->tx_fn = _tx_fn; \
+ ((osl_pubinfo_t *)osh)->tx_ctx = _tx_ctx; \
+ } while (0)
+
+#ifdef BCMSDIO
+#define REGOPSSET(osh, rreg, wreg, ctx) \
+ do { \
+ ((osl_pubinfo_t *)osh)->rreg_fn = rreg; \
+ ((osl_pubinfo_t *)osh)->wreg_fn = wreg; \
+ ((osl_pubinfo_t *)osh)->reg_ctx = ctx; \
+ } while (0)
+#endif
+
+#define BUS_SWAP32(v) (v)
+
+#define MALLOC(osh, size) osl_malloc((osh), (size))
+#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
+#define MALLOCED(osh) osl_malloced((osh))
+extern void *osl_malloc(osl_t *osh, uint size);
+extern void osl_mfree(osl_t *osh, void *addr, uint size);
+extern uint osl_malloced(osl_t *osh);
+
+#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC)
+#define NATIVE_MFREE(osh, addr, size) kfree(addr)
+#define MALLOC_FAILED(osh) osl_malloc_failed((osh))
+extern uint osl_malloc_failed(osl_t *osh);
+
+/* allocate/free shared (dma-able) consistent memory */
+#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align()
+#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \
+ osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap))
+#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
+ osl_dma_free_consistent((osh), (void *)(va), (size), (pa))
+extern uint osl_dma_consistent_align(void);
+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align,
+ uint *tot, ulong *pap);
+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
+
+/* map/unmap direction */
+#define DMA_TX 1 /* TX direction for DMA */
+#define DMA_RX 2 /* RX direction for DMA */
+
+/* map/unmap shared (dma-able) memory */
+#define DMA_MAP(osh, va, size, direction, p, dmah) \
+ osl_dma_map((osh), (va), (size), (direction))
+#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
+ osl_dma_unmap((osh), (pa), (size), (direction))
+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
+
+/* API for DMA addressing capability */
+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
+
+/* register access macros */
+#if defined(BCMSDIO)
+#include <bcmsdh.h>
+#define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v)))
+#define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r))))
+#endif
+
+#if defined(BCMSDIO)
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t *)(osh))->mmbus) \
+ mmap_op else bus_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t *)(osh))->mmbus) ? \
+ mmap_op : bus_op
+#else
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
+#endif
+
+#define OSL_ERROR(bcmerror) osl_error(bcmerror)
+extern int osl_error(int bcmerror);
+
+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
+#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
+
+#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ))
+#define printf(fmt, args...) printk(fmt , ## args)
+#include <linux/kernel.h> /* for vsn/printf's */
+#include <linux/string.h> /* for mem*, str* */
+/* bcopy's: Linux kernel doesn't provide these (anymore) */
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
+#define bzero(b, len) memset((b), '\0', (len))
+
+/* register access macros */
+#if defined(OSLREGOPS)
+#else
+#ifndef IL_BIGENDIAN
+#ifndef __mips__
+#define R_REG(osh, r) (\
+ SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
+ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
+ readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \
+)
+#else /* __mips__ */
+#define R_REG(osh, r) (\
+ SELECT_BUS_READ(osh, \
+ ({ \
+ __typeof(*(r)) __osl_v; \
+ __asm__ __volatile__("sync"); \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): \
+ __osl_v = readb((volatile uint8*)(r)); \
+ break; \
+ case sizeof(uint16): \
+ __osl_v = readw((volatile uint16*)(r)); \
+ break; \
+ case sizeof(uint32): \
+ __osl_v = \
+ readl((volatile uint32*)(r)); \
+ break; \
+ } \
+ __asm__ __volatile__("sync"); \
+ __osl_v; \
+ }), \
+ ({ \
+ __typeof(*(r)) __osl_v; \
+ __asm__ __volatile__("sync"); \
+ __osl_v = OSL_READ_REG(osh, r); \
+ __asm__ __volatile__("sync"); \
+ __osl_v; \
+ })) \
+)
+#endif /* __mips__ */
+
+#define W_REG(osh, r, v) do { \
+ SELECT_BUS_WRITE(osh, \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): \
+ writeb((uint8)(v), (volatile uint8*)(r)); break; \
+ case sizeof(uint16): \
+ writew((uint16)(v), (volatile uint16*)(r)); break; \
+ case sizeof(uint32): \
+ writel((uint32)(v), (volatile uint32*)(r)); break; \
+ }, \
+ (OSL_WRITE_REG(osh, r, v))); \
+ } while (0)
+#else /* IL_BIGENDIAN */
+#define R_REG(osh, r) (\
+ SELECT_BUS_READ(osh, \
+ ({ \
+ __typeof(*(r)) __osl_v; \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): \
+ __osl_v = \
+ readb((volatile uint8*)((uintptr)(r)^3)); \
+ break; \
+ case sizeof(uint16): \
+ __osl_v = \
+ readw((volatile uint16*)((uintptr)(r)^2)); \
+ break; \
+ case sizeof(uint32): \
+ __osl_v = readl((volatile uint32*)(r)); \
+ break; \
+ } \
+ __osl_v; \
+ }), \
+ OSL_READ_REG(osh, r)) \
+)
+#define W_REG(osh, r, v) do { \
+ SELECT_BUS_WRITE(osh, \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): \
+ writeb((uint8)(v), \
+ (volatile uint8*)((uintptr)(r)^3)); break; \
+ case sizeof(uint16): \
+ writew((uint16)(v), \
+ (volatile uint16*)((uintptr)(r)^2)); break; \
+ case sizeof(uint32): \
+ writel((uint32)(v), \
+ (volatile uint32*)(r)); break; \
+ }, \
+ (OSL_WRITE_REG(osh, r, v))); \
+ } while (0)
+#endif /* IL_BIGENDIAN */
+
+#endif /* OSLREGOPS */
+
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+
+/* bcopy, bcmp, and bzero functions */
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
+#define bzero(b, len) memset((b), '\0', (len))
+
+/* uncached/cached virtual address */
+#ifdef __mips__
+#include <asm/addrspace.h>
+#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va)))
+#define OSL_CACHED(va) ((void *)KSEG0ADDR((va)))
+#else
+#define OSL_UNCACHED(va) ((void *)va)
+#define OSL_CACHED(va) ((void *)va)
+#endif /* mips */
+
+#if defined(mips)
+#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
+#elif defined(__i386__)
+#define OSL_GETCYCLES(x) rdtscl((x))
+#else
+#define OSL_GETCYCLES(x) ((x) = 0)
+#endif /* defined(mips) */
+
+/* dereference an address that may cause a bus exception */
+#ifdef mips
+#define BUSPROBE(val, addr) get_dbe((val), (addr))
+#include <asm/paccess.h>
+#else
+#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
+#endif /* mips */
+
+/* map/unmap physical to virtual I/O */
+#if !defined(CONFIG_MMC_MSM7X00A)
+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#else
+#define REG_MAP(pa, size) (void *)(0)
+#endif /* !defined(CONFIG_MMC_MSM7X00A */
+#define REG_UNMAP(va) iounmap((va))
+
+#define R_SM(r) (*(r))
+#define W_SM(r, v) (*(r) = (v))
+#define BZERO_SM(r, len) memset((r), '\0', (len))
+
+#include <linuxver.h> /* use current 2.4.x calling conventions */
+
+/* packet primitives */
+#define PKTGET(osh, len, send) osl_pktget((osh), (len))
+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
+#define PKTDATA(skb) (((struct sk_buff *)(skb))->data)
+#define PKTLEN(skb) (((struct sk_buff *)(skb))->len)
+#define PKTHEADROOM(skb) (PKTDATA(skb)-(((struct sk_buff *)(skb))->head))
+#define PKTTAILROOM(skb) ((((struct sk_buff *)(skb))->end)-(((struct sk_buff *)(skb))->tail))
+#define PKTNEXT(skb) (((struct sk_buff *)(skb))->next)
+#define PKTSETNEXT(skb, x) (((struct sk_buff *)(skb))->next = (struct sk_buff*)(x))
+#define PKTSETLEN(skb, len) __skb_trim((struct sk_buff *)(skb), (len))
+#define PKTPUSH(skb, bytes) skb_push((struct sk_buff *)(skb), (bytes))
+#define PKTPULL(skb, bytes) skb_pull((struct sk_buff *)(skb), (bytes))
+#define PKTTAG(skb) ((void *)(((struct sk_buff *)(skb))->cb))
+#define PKTALLOCED(osh) (((osl_pubinfo_t *)(osh))->pktalloced)
+#define PKTSETPOOL(osh, skb, x, y) do {} while (0)
+#define PKTPOOL(osh, skb) FALSE
+
+#define PKTUNALLOC(osh) (((osl_pubinfo_t *)(osh))->pktalloced--)
+
+#define PKTSETSKIPCT(osh, skb)
+#define PKTCLRSKIPCT(osh, skb)
+#define PKTSKIPCT(osh, skb)
+
+extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+
+extern void *osl_pktget(osl_t *osh, uint len);
+extern void *osl_pktdup(osl_t *osh, void *skb);
+
+#define PKTLINK(skb) (((struct sk_buff *)(skb))->prev)
+#define PKTSETLINK(skb, x) (((struct sk_buff *)(skb))->prev = (struct sk_buff*)(x))
+#define PKTPRIO(skb) (((struct sk_buff *)(skb))->priority)
+#define PKTSETPRIO(skb, x) (((struct sk_buff *)(skb))->priority = (x))
+#define PKTSUMNEEDED(skb) (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_HW)
+#define PKTSETSUMGOOD(skb, x) (((struct sk_buff *)(skb))->ip_summed = \
+ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
+#define PKTSHARED(skb) (((struct sk_buff *)(skb))->cloned)
+
+#ifdef BCMSDIO
+#define RPC_READ_REG(osh, r) (\
+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \
+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \
+ osl_readl((osh), (volatile uint32*)(r)) \
+)
+#define RPC_WRITE_REG(osh, r, v) do { \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): \
+ osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); \
+ break; \
+ case sizeof(uint16): \
+ osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); \
+ break; \
+ case sizeof(uint32): \
+ osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); \
+ break; \
+ } \
+} while (0)
+
+extern uint8 osl_readb(osl_t *osh, volatile uint8 *r);
+extern uint16 osl_readw(osl_t *osh, volatile uint16 *r);
+extern uint32 osl_readl(osl_t *osh, volatile uint32 *r);
+extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v);
+extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v);
+extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v);
+#endif /* BCMSDIO */
+
+#endif /* _linux_osl_h_ */
diff --git a/drivers/staging/brcm80211/include/linuxver.h b/drivers/staging/brcm80211/include/linuxver.h
new file mode 100644
index 000000000000..98768d310ff2
--- /dev/null
+++ b/drivers/staging/brcm80211/include/linuxver.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _linuxver_h_
+#define _linuxver_h_
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/slab.h>
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#undef IP_TOS
+#include <asm/io.h>
+
+#include <linux/workqueue.h>
+
+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func)
+
+typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs * ptregs);
+
+#include <linux/sched.h>
+#include <linux/ieee80211.h>
+
+#ifndef __exit
+#define __exit
+#endif
+#ifndef __devexit
+#define __devexit
+#endif
+#ifndef __devinit
+#define __devinit __init
+#endif
+#ifndef __devinitdata
+#define __devinitdata
+#endif
+#ifndef __devexit_p
+#define __devexit_p(x) x
+#endif
+
+#define pci_module_init pci_register_driver
+
+#define netif_down(dev)
+
+/* Power management related macro & routines */
+#define PCI_SAVE_STATE(a, b) pci_save_state(a)
+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a)
+
+/* Module refcount handled internally in 2.6.x */
+#ifndef SET_MODULE_OWNER
+#define SET_MODULE_OWNER(dev) do {} while (0)
+#endif
+#ifndef MOD_INC_USE_COUNT
+#define MOD_INC_USE_COUNT do {} while (0)
+#endif
+#ifndef MOD_DEC_USE_COUNT
+#define MOD_DEC_USE_COUNT do {} while (0)
+#endif
+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
+
+#ifndef SET_NETDEV_DEV
+#define SET_NETDEV_DEV(net, pdev) do {} while (0)
+#endif
+
+#ifndef HAVE_FREE_NETDEV
+#define free_netdev(dev) kfree(dev)
+#endif
+
+/* suspend args */
+#define DRV_SUSPEND_STATE_TYPE pm_message_t
+
+#define CHECKSUM_HW CHECKSUM_PARTIAL
+
+#include <linux/time.h>
+#include <linux/wait.h>
+
+#define KILL_PROC(nr, sig) \
+ do { \
+ struct task_struct *tsk; \
+ struct pid *pid; \
+ pid = find_get_pid((pid_t)nr); \
+ tsk = pid_task(pid, PIDTYPE_PID); \
+ if (tsk) \
+ send_sig(sig, tsk, 1); \
+ } while (0)
+
+#define WL_DEV_IF(dev) ((wl_if_t *)netdev_priv(dev))
+
+#endif /* _linuxver_h_ */
diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h
new file mode 100644
index 000000000000..1abbe3f9ab4a
--- /dev/null
+++ b/drivers/staging/brcm80211/include/nicpci.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _NICPCI_H
+#define _NICPCI_H
+
+#if defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS))
+#define pcicore_find_pci_capability(a, b, c, d) (0)
+#define pcie_readreg(a, b, c, d) (0)
+#define pcie_writereg(a, b, c, d, e) (0)
+
+#define pcie_clkreq(a, b, c) (0)
+#define pcie_lcreg(a, b, c) (0)
+
+#define pcicore_init(a, b, c) (0x0dadbeef)
+#define pcicore_deinit(a) do { } while (0)
+#define pcicore_attach(a, b, c) do { } while (0)
+#define pcicore_hwup(a) do { } while (0)
+#define pcicore_up(a, b) do { } while (0)
+#define pcicore_sleep(a) do { } while (0)
+#define pcicore_down(a, b) do { } while (0)
+
+#define pcie_war_ovr_aspm_update(a, b) do { } while (0)
+
+#define pcicore_pcieserdesreg(a, b, c, d, e) (0)
+#define pcicore_pciereg(a, b, c, d, e) (0)
+
+#define pcicore_pmecap_fast(a) (FALSE)
+#define pcicore_pmeen(a) do { } while (0)
+#define pcicore_pmeclr(a) do { } while (0)
+#define pcicore_pmestat(a) (FALSE)
+#else
+struct sbpcieregs;
+
+extern uint8 pcicore_find_pci_capability(osl_t *osh, uint8 req_cap_id,
+ uchar *buf, uint32 *buflen);
+extern uint pcie_readreg(osl_t *osh, struct sbpcieregs *pcieregs,
+ uint addrtype, uint offset);
+extern uint pcie_writereg(osl_t *osh, struct sbpcieregs *pcieregs,
+ uint addrtype, uint offset, uint val);
+
+extern uint8 pcie_clkreq(void *pch, uint32 mask, uint32 val);
+extern uint32 pcie_lcreg(void *pch, uint32 mask, uint32 val);
+
+extern void *pcicore_init(si_t *sih, osl_t *osh, void *regs);
+extern void pcicore_deinit(void *pch);
+extern void pcicore_attach(void *pch, char *pvars, int state);
+extern void pcicore_hwup(void *pch);
+extern void pcicore_up(void *pch, int state);
+extern void pcicore_sleep(void *pch);
+extern void pcicore_down(void *pch, int state);
+
+extern void pcie_war_ovr_aspm_update(void *pch, uint8 aspm);
+extern uint32 pcicore_pcieserdesreg(void *pch, uint32 mdioslave, uint32 offset,
+ uint32 mask, uint32 val);
+
+extern uint32 pcicore_pciereg(void *pch, uint32 offset, uint32 mask,
+ uint32 val, uint type);
+
+extern bool pcicore_pmecap_fast(osl_t *osh);
+extern void pcicore_pmeen(void *pch);
+extern void pcicore_pmeclr(void *pch);
+extern bool pcicore_pmestat(void *pch);
+#endif /* defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)) */
+
+#endif /* _NICPCI_H */
diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h
new file mode 100644
index 000000000000..cd09f3c09b9b
--- /dev/null
+++ b/drivers/staging/brcm80211/include/osl.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _osl_h_
+#define _osl_h_
+
+/* osl handle type forward declaration */
+typedef struct osl_info osl_t;
+typedef struct osl_dmainfo osldma_t;
+
+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */
+
+/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */
+typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status);
+
+#ifdef BCMSDIO
+/* Drivers use REGOPSSET() to register register read/write funcitons */
+typedef unsigned int (*osl_rreg_fn_t) (void *ctx, void *reg, unsigned int size);
+typedef void (*osl_wreg_fn_t) (void *ctx, void *reg, unsigned int val,
+ unsigned int size);
+#endif
+
+#include <linux_osl.h>
+
+/* --------------------------------------------------------------------------
+** Register manipulation macros.
+*/
+
+#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val)))
+
+#ifndef AND_REG
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#endif /* !AND_REG */
+
+#ifndef OR_REG
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+#endif /* !OR_REG */
+
+#if !defined(OSL_SYSUPTIME)
+#define OSL_SYSUPTIME() (0)
+#define OSL_SYSUPTIME_SUPPORT FALSE
+#else
+#define OSL_SYSUPTIME_SUPPORT TRUE
+#endif /* OSL_SYSUPTIME */
+
+#endif /* _osl_h_ */
diff --git a/drivers/staging/brcm80211/include/packed_section_end.h b/drivers/staging/brcm80211/include/packed_section_end.h
new file mode 100644
index 000000000000..04c7d43e1286
--- /dev/null
+++ b/drivers/staging/brcm80211/include/packed_section_end.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h
+ * and undefined in packed_section_end.h. If it is NOT defined at this
+ * point, then there is a missing include of packed_section_start.h.
+ */
+#ifdef BWL_PACKED_SECTION
+#undef BWL_PACKED_SECTION
+#else
+#error "BWL_PACKED_SECTION is NOT defined!"
+#endif
+
+/* Compiler-specific directives for structure packing are declared in
+ * packed_section_start.h. This marks the end of the structure packing section,
+ * so, undef them here.
+ */
+#undef BWL_PRE_PACKED_STRUCT
+#undef BWL_POST_PACKED_STRUCT
diff --git a/drivers/staging/brcm80211/include/packed_section_start.h b/drivers/staging/brcm80211/include/packed_section_start.h
new file mode 100644
index 000000000000..60e862a0c213
--- /dev/null
+++ b/drivers/staging/brcm80211/include/packed_section_start.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h
+ * and undefined in packed_section_end.h. If it is already defined at this
+ * point, then there is a missing include of packed_section_end.h.
+ */
+#ifdef BWL_PACKED_SECTION
+#error "BWL_PACKED_SECTION is already defined!"
+#else
+#define BWL_PACKED_SECTION
+#endif
+
+/* Declare compiler-specific directives for structure packing. */
+#if defined(__GNUC__)
+#define BWL_PRE_PACKED_STRUCT
+#define BWL_POST_PACKED_STRUCT __attribute__((packed))
+#elif defined(__CC_ARM)
+#define BWL_PRE_PACKED_STRUCT __packed
+#define BWL_POST_PACKED_STRUCT
+#else
+#error "Unknown compiler!"
+#endif
diff --git a/drivers/staging/brcm80211/include/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h
new file mode 100644
index 000000000000..d0fe4c3ffa86
--- /dev/null
+++ b/drivers/staging/brcm80211/include/pci_core.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _PCI_CORE_H_
+#define _PCI_CORE_H_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif
+
+/* Sonics side: PCI core and host control registers */
+typedef struct sbpciregs {
+ uint32 control; /* PCI control */
+ uint32 PAD[3];
+ uint32 arbcontrol; /* PCI arbiter control */
+ uint32 clkrun; /* Clkrun Control (>=rev11) */
+ uint32 PAD[2];
+ uint32 intstatus; /* Interrupt status */
+ uint32 intmask; /* Interrupt mask */
+ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */
+ uint32 PAD[9];
+ uint32 bcastaddr; /* Sonics broadcast address */
+ uint32 bcastdata; /* Sonics broadcast data */
+ uint32 PAD[2];
+ uint32 gpioin; /* ro: gpio input (>=rev2) */
+ uint32 gpioout; /* rw: gpio output (>=rev2) */
+ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */
+ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */
+ uint32 PAD[36];
+ uint32 sbtopci0; /* Sonics to PCI translation 0 */
+ uint32 sbtopci1; /* Sonics to PCI translation 1 */
+ uint32 sbtopci2; /* Sonics to PCI translation 2 */
+ uint32 PAD[189];
+ uint32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
+ uint16 sprom[36]; /* SPROM shadow Area */
+ uint32 PAD[46];
+} sbpciregs_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* PCI control */
+#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
+#define PCI_RST 0x02 /* Value driven out to pin */
+#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */
+#define PCI_CLK 0x08 /* Gate for clock driven out to pin */
+
+/* PCI arbiter control */
+#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */
+#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */
+/* ParkID - for PCI corerev >= 8 */
+#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */
+#define PCI_PARKID_SHIFT 2
+#define PCI_PARKID_EXT0 0 /* External master 0 */
+#define PCI_PARKID_EXT1 1 /* External master 1 */
+#define PCI_PARKID_EXT2 2 /* External master 2 */
+#define PCI_PARKID_EXT3 3 /* External master 3 (rev >= 11) */
+#define PCI_PARKID_INT 3 /* Internal master (rev < 11) */
+#define PCI11_PARKID_INT 4 /* Internal master (rev >= 11) */
+#define PCI_PARKID_LAST 4 /* Last active master (rev < 11) */
+#define PCI11_PARKID_LAST 5 /* Last active master (rev >= 11) */
+
+#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
+
+/* Interrupt status/mask */
+#define PCI_INTA 0x01 /* PCI INTA# is asserted */
+#define PCI_INTB 0x02 /* PCI INTB# is asserted */
+#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */
+#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */
+#define PCI_PME 0x10 /* PCI PME# is asserted */
+
+/* (General) PCI/SB mailbox interrupts, two bits per pci function */
+#define MAILBOX_F0_0 0x100 /* function 0, int 0 */
+#define MAILBOX_F0_1 0x200 /* function 0, int 1 */
+#define MAILBOX_F1_0 0x400 /* function 1, int 0 */
+#define MAILBOX_F1_1 0x800 /* function 1, int 1 */
+#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */
+#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */
+#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */
+#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */
+
+/* Sonics broadcast address */
+#define BCAST_ADDR_MASK 0xff /* Broadcast register address */
+
+/* Sonics to PCI translation types */
+#define SBTOPCI0_MASK 0xfc000000
+#define SBTOPCI1_MASK 0xfc000000
+#define SBTOPCI2_MASK 0xc0000000
+#define SBTOPCI_MEM 0
+#define SBTOPCI_IO 1
+#define SBTOPCI_CFG0 2
+#define SBTOPCI_CFG1 3
+#define SBTOPCI_PREF 0x4 /* prefetch enable */
+#define SBTOPCI_BURST 0x8 /* burst enable */
+#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */
+#define SBTOPCI_RC_READ 0x00 /* memory read */
+#define SBTOPCI_RC_READLINE 0x10 /* memory read line */
+#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
+
+/* PCI core index in SROM shadow area */
+#define SRSH_PI_OFFSET 0 /* first word */
+#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
+#define SRSH_PI_SHIFT 12 /* bit 15:12 */
+
+#endif /* _PCI_CORE_H_ */
diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h
new file mode 100644
index 000000000000..caddca5fa4af
--- /dev/null
+++ b/drivers/staging/brcm80211/include/pcicfg.h
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _h_pcicfg_
+#define _h_pcicfg_
+
+/* The following inside ifndef's so we don't collide with NTDDK.H */
+#ifndef PCI_MAX_BUS
+#define PCI_MAX_BUS 0x100
+#endif
+#ifndef PCI_MAX_DEVICES
+#define PCI_MAX_DEVICES 0x20
+#endif
+#ifndef PCI_MAX_FUNCTION
+#define PCI_MAX_FUNCTION 0x8
+#endif
+
+#ifndef PCI_INVALID_VENDORID
+#define PCI_INVALID_VENDORID 0xffff
+#endif
+#ifndef PCI_INVALID_DEVICEID
+#define PCI_INVALID_DEVICEID 0xffff
+#endif
+
+/* Convert between bus-slot-function-register and config addresses */
+
+#define PCICFG_BUS_SHIFT 16 /* Bus shift */
+#define PCICFG_SLOT_SHIFT 11 /* Slot shift */
+#define PCICFG_FUN_SHIFT 8 /* Function shift */
+#define PCICFG_OFF_SHIFT 0 /* Register shift */
+
+#define PCICFG_BUS_MASK 0xff /* Bus mask */
+#define PCICFG_SLOT_MASK 0x1f /* Slot mask */
+#define PCICFG_FUN_MASK 7 /* Function mask */
+#define PCICFG_OFF_MASK 0xff /* Bus mask */
+
+#define PCI_CONFIG_ADDR(b, s, f, o) \
+ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \
+ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \
+ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \
+ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT))
+
+#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK)
+#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK)
+#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK)
+#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK)
+
+/* PCIE Config space accessing MACROS */
+
+#define PCIECFG_BUS_SHIFT 24 /* Bus shift */
+#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */
+#define PCIECFG_FUN_SHIFT 16 /* Function shift */
+#define PCIECFG_OFF_SHIFT 0 /* Register shift */
+
+#define PCIECFG_BUS_MASK 0xff /* Bus mask */
+#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */
+#define PCIECFG_FUN_MASK 7 /* Function mask */
+#define PCIECFG_OFF_MASK 0xfff /* Register mask */
+
+#define PCIE_CONFIG_ADDR(b, s, f, o) \
+ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \
+ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \
+ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \
+ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT))
+
+#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK)
+#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK)
+#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK)
+#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK)
+
+/* The actual config space */
+
+#define PCI_BAR_MAX 6
+
+#define PCI_ROM_BAR 8
+
+#define PCR_RSVDA_MAX 2
+
+/* Bits in PCI bars' flags */
+
+#define PCIBAR_FLAGS 0xf
+#define PCIBAR_IO 0x1
+#define PCIBAR_MEM1M 0x2
+#define PCIBAR_MEM64 0x4
+#define PCIBAR_PREFETCH 0x8
+#define PCIBAR_MEM32_MASK 0xFFFFFF80
+
+/* pci config status reg has a bit to indicate that capability ptr is present */
+
+#define PCI_CAPPTR_PRESENT 0x0010
+
+typedef struct _pci_config_regs {
+ uint16 vendor;
+ uint16 device;
+ uint16 command;
+ uint16 status;
+ uint8 rev_id;
+ uint8 prog_if;
+ uint8 sub_class;
+ uint8 base_class;
+ uint8 cache_line_size;
+ uint8 latency_timer;
+ uint8 header_type;
+ uint8 bist;
+ uint32 base[PCI_BAR_MAX];
+ uint32 cardbus_cis;
+ uint16 subsys_vendor;
+ uint16 subsys_id;
+ uint32 baserom;
+ uint32 rsvd_a[PCR_RSVDA_MAX];
+ uint8 int_line;
+ uint8 int_pin;
+ uint8 min_gnt;
+ uint8 max_lat;
+ uint8 dev_dep[192];
+} pci_config_regs;
+
+#define SZPCR (sizeof (pci_config_regs))
+#define MINSZPCR 64 /* offsetof (dev_dep[0] */
+
+/* A structure for the config registers is nice, but in most
+ * systems the config space is not memory mapped, so we need
+ * field offsetts. :-(
+ */
+#define PCI_CFG_VID 0
+#define PCI_CFG_DID 2
+#define PCI_CFG_CMD 4
+#define PCI_CFG_STAT 6
+#define PCI_CFG_REV 8
+#define PCI_CFG_PROGIF 9
+#define PCI_CFG_SUBCL 0xa
+#define PCI_CFG_BASECL 0xb
+#define PCI_CFG_CLSZ 0xc
+#define PCI_CFG_LATTIM 0xd
+#define PCI_CFG_HDR 0xe
+#define PCI_CFG_BIST 0xf
+#define PCI_CFG_BAR0 0x10
+#define PCI_CFG_BAR1 0x14
+#define PCI_CFG_BAR2 0x18
+#define PCI_CFG_BAR3 0x1c
+#define PCI_CFG_BAR4 0x20
+#define PCI_CFG_BAR5 0x24
+#define PCI_CFG_CIS 0x28
+#define PCI_CFG_SVID 0x2c
+#define PCI_CFG_SSID 0x2e
+#define PCI_CFG_ROMBAR 0x30
+#define PCI_CFG_CAPPTR 0x34
+#define PCI_CFG_INT 0x3c
+#define PCI_CFG_PIN 0x3d
+#define PCI_CFG_MINGNT 0x3e
+#define PCI_CFG_MAXLAT 0x3f
+
+/* Classes and subclasses */
+
+typedef enum {
+ PCI_CLASS_OLD = 0,
+ PCI_CLASS_DASDI,
+ PCI_CLASS_NET,
+ PCI_CLASS_DISPLAY,
+ PCI_CLASS_MMEDIA,
+ PCI_CLASS_MEMORY,
+ PCI_CLASS_BRIDGE,
+ PCI_CLASS_COMM,
+ PCI_CLASS_BASE,
+ PCI_CLASS_INPUT,
+ PCI_CLASS_DOCK,
+ PCI_CLASS_CPU,
+ PCI_CLASS_SERIAL,
+ PCI_CLASS_INTELLIGENT = 0xe,
+ PCI_CLASS_SATELLITE,
+ PCI_CLASS_CRYPT,
+ PCI_CLASS_DSP,
+ PCI_CLASS_XOR = 0xfe
+} pci_classes;
+
+typedef enum {
+ PCI_DASDI_SCSI,
+ PCI_DASDI_IDE,
+ PCI_DASDI_FLOPPY,
+ PCI_DASDI_IPI,
+ PCI_DASDI_RAID,
+ PCI_DASDI_OTHER = 0x80
+} pci_dasdi_subclasses;
+
+typedef enum {
+ PCI_NET_ETHER,
+ PCI_NET_TOKEN,
+ PCI_NET_FDDI,
+ PCI_NET_ATM,
+ PCI_NET_OTHER = 0x80
+} pci_net_subclasses;
+
+typedef enum {
+ PCI_DISPLAY_VGA,
+ PCI_DISPLAY_XGA,
+ PCI_DISPLAY_3D,
+ PCI_DISPLAY_OTHER = 0x80
+} pci_display_subclasses;
+
+typedef enum {
+ PCI_MMEDIA_VIDEO,
+ PCI_MMEDIA_AUDIO,
+ PCI_MMEDIA_PHONE,
+ PCI_MEDIA_OTHER = 0x80
+} pci_mmedia_subclasses;
+
+typedef enum {
+ PCI_MEMORY_RAM,
+ PCI_MEMORY_FLASH,
+ PCI_MEMORY_OTHER = 0x80
+} pci_memory_subclasses;
+
+typedef enum {
+ PCI_BRIDGE_HOST,
+ PCI_BRIDGE_ISA,
+ PCI_BRIDGE_EISA,
+ PCI_BRIDGE_MC,
+ PCI_BRIDGE_PCI,
+ PCI_BRIDGE_PCMCIA,
+ PCI_BRIDGE_NUBUS,
+ PCI_BRIDGE_CARDBUS,
+ PCI_BRIDGE_RACEWAY,
+ PCI_BRIDGE_OTHER = 0x80
+} pci_bridge_subclasses;
+
+typedef enum {
+ PCI_COMM_UART,
+ PCI_COMM_PARALLEL,
+ PCI_COMM_MULTIUART,
+ PCI_COMM_MODEM,
+ PCI_COMM_OTHER = 0x80
+} pci_comm_subclasses;
+
+typedef enum {
+ PCI_BASE_PIC,
+ PCI_BASE_DMA,
+ PCI_BASE_TIMER,
+ PCI_BASE_RTC,
+ PCI_BASE_PCI_HOTPLUG,
+ PCI_BASE_OTHER = 0x80
+} pci_base_subclasses;
+
+typedef enum {
+ PCI_INPUT_KBD,
+ PCI_INPUT_PEN,
+ PCI_INPUT_MOUSE,
+ PCI_INPUT_SCANNER,
+ PCI_INPUT_GAMEPORT,
+ PCI_INPUT_OTHER = 0x80
+} pci_input_subclasses;
+
+typedef enum {
+ PCI_DOCK_GENERIC,
+ PCI_DOCK_OTHER = 0x80
+} pci_dock_subclasses;
+
+typedef enum {
+ PCI_CPU_386,
+ PCI_CPU_486,
+ PCI_CPU_PENTIUM,
+ PCI_CPU_ALPHA = 0x10,
+ PCI_CPU_POWERPC = 0x20,
+ PCI_CPU_MIPS = 0x30,
+ PCI_CPU_COPROC = 0x40,
+ PCI_CPU_OTHER = 0x80
+} pci_cpu_subclasses;
+
+typedef enum {
+ PCI_SERIAL_IEEE1394,
+ PCI_SERIAL_ACCESS,
+ PCI_SERIAL_SSA,
+ PCI_SERIAL_USB,
+ PCI_SERIAL_FIBER,
+ PCI_SERIAL_SMBUS,
+ PCI_SERIAL_OTHER = 0x80
+} pci_serial_subclasses;
+
+typedef enum {
+ PCI_INTELLIGENT_I2O
+} pci_intelligent_subclasses;
+
+typedef enum {
+ PCI_SATELLITE_TV,
+ PCI_SATELLITE_AUDIO,
+ PCI_SATELLITE_VOICE,
+ PCI_SATELLITE_DATA,
+ PCI_SATELLITE_OTHER = 0x80
+} pci_satellite_subclasses;
+
+typedef enum {
+ PCI_CRYPT_NETWORK,
+ PCI_CRYPT_ENTERTAINMENT,
+ PCI_CRYPT_OTHER = 0x80
+} pci_crypt_subclasses;
+
+typedef enum {
+ PCI_DSP_DPIO,
+ PCI_DSP_OTHER = 0x80
+} pci_dsp_subclasses;
+
+typedef enum {
+ PCI_XOR_QDMA,
+ PCI_XOR_OTHER = 0x80
+} pci_xor_subclasses;
+
+/* Header types */
+#define PCI_HEADER_MULTI 0x80
+#define PCI_HEADER_MASK 0x7f
+typedef enum {
+ PCI_HEADER_NORMAL,
+ PCI_HEADER_BRIDGE,
+ PCI_HEADER_CARDBUS
+} pci_header_types;
+
+/* Overlay for a PCI-to-PCI bridge */
+
+#define PPB_RSVDA_MAX 2
+#define PPB_RSVDD_MAX 8
+
+typedef struct _ppb_config_regs {
+ uint16 vendor;
+ uint16 device;
+ uint16 command;
+ uint16 status;
+ uint8 rev_id;
+ uint8 prog_if;
+ uint8 sub_class;
+ uint8 base_class;
+ uint8 cache_line_size;
+ uint8 latency_timer;
+ uint8 header_type;
+ uint8 bist;
+ uint32 rsvd_a[PPB_RSVDA_MAX];
+ uint8 prim_bus;
+ uint8 sec_bus;
+ uint8 sub_bus;
+ uint8 sec_lat;
+ uint8 io_base;
+ uint8 io_lim;
+ uint16 sec_status;
+ uint16 mem_base;
+ uint16 mem_lim;
+ uint16 pf_mem_base;
+ uint16 pf_mem_lim;
+ uint32 pf_mem_base_hi;
+ uint32 pf_mem_lim_hi;
+ uint16 io_base_hi;
+ uint16 io_lim_hi;
+ uint16 subsys_vendor;
+ uint16 subsys_id;
+ uint32 rsvd_b;
+ uint8 rsvd_c;
+ uint8 int_pin;
+ uint16 bridge_ctrl;
+ uint8 chip_ctrl;
+ uint8 diag_ctrl;
+ uint16 arb_ctrl;
+ uint32 rsvd_d[PPB_RSVDD_MAX];
+ uint8 dev_dep[192];
+} ppb_config_regs;
+
+/* PCI CAPABILITY DEFINES */
+#define PCI_CAP_POWERMGMTCAP_ID 0x01
+#define PCI_CAP_MSICAP_ID 0x05
+#define PCI_CAP_VENDSPEC_ID 0x09
+#define PCI_CAP_PCIECAP_ID 0x10
+
+/* Data structure to define the Message Signalled Interrupt facility
+ * Valid for PCI and PCIE configurations
+ */
+typedef struct _pciconfig_cap_msi {
+ uint8 capID;
+ uint8 nextptr;
+ uint16 msgctrl;
+ uint32 msgaddr;
+} pciconfig_cap_msi;
+
+/* Data structure to define the Power managment facility
+ * Valid for PCI and PCIE configurations
+ */
+typedef struct _pciconfig_cap_pwrmgmt {
+ uint8 capID;
+ uint8 nextptr;
+ uint16 pme_cap;
+ uint16 pme_sts_ctrl;
+ uint8 pme_bridge_ext;
+ uint8 data;
+} pciconfig_cap_pwrmgmt;
+
+#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */
+#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */
+#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */
+#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */
+
+/* Data structure to define the PCIE capability */
+typedef struct _pciconfig_cap_pcie {
+ uint8 capID;
+ uint8 nextptr;
+ uint16 pcie_cap;
+ uint32 dev_cap;
+ uint16 dev_ctrl;
+ uint16 dev_status;
+ uint32 link_cap;
+ uint16 link_ctrl;
+ uint16 link_status;
+ uint32 slot_cap;
+ uint16 slot_ctrl;
+ uint16 slot_status;
+ uint16 root_ctrl;
+ uint16 root_cap;
+ uint32 root_status;
+} pciconfig_cap_pcie;
+
+/* PCIE Enhanced CAPABILITY DEFINES */
+#define PCIE_EXTCFG_OFFSET 0x100
+#define PCIE_ADVERRREP_CAPID 0x0001
+#define PCIE_VC_CAPID 0x0002
+#define PCIE_DEVSNUM_CAPID 0x0003
+#define PCIE_PWRBUDGET_CAPID 0x0004
+
+/* PCIE Extended configuration */
+#define PCIE_ADV_CORR_ERR_MASK 0x114
+#define CORR_ERR_RE (1 << 0) /* Receiver */
+#define CORR_ERR_BT (1 << 6) /* Bad TLP */
+#define CORR_ERR_BD (1 << 7) /* Bad DLLP */
+#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */
+#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */
+#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \
+ CORR_ERR_RR | CORR_ERR_RT)
+
+/* PCIE Root Control Register bits (Host mode only) */
+#define PCIE_RC_CORR_SERR_EN 0x0001
+#define PCIE_RC_NONFATAL_SERR_EN 0x0002
+#define PCIE_RC_FATAL_SERR_EN 0x0004
+#define PCIE_RC_PME_INT_EN 0x0008
+#define PCIE_RC_CRS_EN 0x0010
+
+/* PCIE Root Capability Register bits (Host mode only) */
+#define PCIE_RC_CRS_VISIBILITY 0x0001
+
+/* Header to define the PCIE specific capabilities in the extended config space */
+typedef struct _pcie_enhanced_caphdr {
+ uint16 capID;
+ uint16 cap_ver:4;
+ uint16 next_ptr:12;
+} pcie_enhanced_caphdr;
+
+/* Everything below is BRCM HND proprietary */
+
+/* Brcm PCI configuration registers */
+#define cap_list rsvd_a[0]
+#define bar0_window dev_dep[0x80 - 0x40]
+#define bar1_window dev_dep[0x84 - 0x40]
+#define sprom_control dev_dep[0x88 - 0x40]
+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */
+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */
+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */
+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */
+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */
+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */
+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */
+#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */
+#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */
+#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */
+#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */
+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */
+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */
+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */
+
+#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */
+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */
+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */
+#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the
+ * 8KB window, so their address is the "regular"
+ * address plus 4K
+ */
+#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */
+/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
+#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */
+#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */
+#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */
+
+/* On AI chips we have a second window to map DMP regs are mapped: */
+#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */
+
+/* PCI_INT_STATUS */
+#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */
+
+/* PCI_INT_MASK */
+#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */
+#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */
+#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
+
+/* PCI_SPROM_CONTROL */
+#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */
+#define SPROM_LOCKED 0x08 /* SPROM Locked */
+#define SPROM_BLANK 0x04 /* indicating a blank SPROM */
+#define SPROM_WRITEEN 0x10 /* SPROM write enable */
+#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
+#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */
+#define SPROM_OTPIN_USE 0x80 /* device OTP In use */
+
+/* Bits in PCI command and status regs */
+#define PCI_CMD_IO 0x00000001 /* I/O enable */
+#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */
+#define PCI_CMD_MASTER 0x00000004 /* Master enable */
+#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */
+#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */
+#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */
+#define PCI_STAT_TA 0x08000000 /* target abort status */
+#endif /* _h_pcicfg_ */
diff --git a/drivers/staging/brcm80211/include/pcie_core.h b/drivers/staging/brcm80211/include/pcie_core.h
new file mode 100644
index 000000000000..0f835c15821f
--- /dev/null
+++ b/drivers/staging/brcm80211/include/pcie_core.h
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _PCIE_CORE_H
+#define _PCIE_CORE_H
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif
+
+/* PCIE Enumeration space offsets */
+#define PCIE_CORE_CONFIG_OFFSET 0x0
+#define PCIE_FUNC0_CONFIG_OFFSET 0x400
+#define PCIE_FUNC1_CONFIG_OFFSET 0x500
+#define PCIE_FUNC2_CONFIG_OFFSET 0x600
+#define PCIE_FUNC3_CONFIG_OFFSET 0x700
+#define PCIE_SPROM_SHADOW_OFFSET 0x800
+#define PCIE_SBCONFIG_OFFSET 0xE00
+
+/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */
+#define PCIE_DEV_BAR0_SIZE 0x4000
+#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0
+#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000
+#define PCIE_BAR0_PCIECORE_OFFSET 0x2000
+#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000
+
+/* different register spaces to access thr'u pcie indirect access */
+#define PCIE_CONFIGREGS 1 /* Access to config space */
+#define PCIE_PCIEREGS 2 /* Access to pcie registers */
+
+/* SB side: PCIE core and host control registers */
+typedef struct sbpcieregs {
+ uint32 control; /* host mode only */
+ uint32 PAD[2];
+ uint32 biststatus; /* bist Status: 0x00C */
+ uint32 gpiosel; /* PCIE gpio sel: 0x010 */
+ uint32 gpioouten; /* PCIE gpio outen: 0x14 */
+ uint32 PAD[2];
+ uint32 intstatus; /* Interrupt status: 0x20 */
+ uint32 intmask; /* Interrupt mask: 0x24 */
+ uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
+ uint32 PAD[53];
+ uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
+ uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
+ uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
+ uint32 PAD[5];
+
+ /* pcie core supports in direct access to config space */
+ uint32 configaddr; /* pcie config space access: Address field: 0x120 */
+ uint32 configdata; /* pcie config space access: Data field: 0x124 */
+
+ /* mdio access to serdes */
+ uint32 mdiocontrol; /* controls the mdio access: 0x128 */
+ uint32 mdiodata; /* Data to the mdio access: 0x12c */
+
+ /* pcie protocol phy/dllp/tlp register indirect access mechanism */
+ uint32 pcieindaddr; /* indirect access to the internal register: 0x130 */
+ uint32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
+
+ uint32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
+ uint32 PAD[177];
+ uint32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
+ uint16 sprom[64]; /* SPROM shadow Area */
+} sbpcieregs_t;
+
+/* PCI control */
+#define PCIE_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
+#define PCIE_RST 0x02 /* Value driven out to pin */
+
+#define PCIE_CFGADDR 0x120 /* offsetof(configaddr) */
+#define PCIE_CFGDATA 0x124 /* offsetof(configdata) */
+
+/* Interrupt status/mask */
+#define PCIE_INTA 0x01 /* PCIE INTA message is received */
+#define PCIE_INTB 0x02 /* PCIE INTB message is received */
+#define PCIE_INTFATAL 0x04 /* PCIE INTFATAL message is received */
+#define PCIE_INTNFATAL 0x08 /* PCIE INTNONFATAL message is received */
+#define PCIE_INTCORR 0x10 /* PCIE INTCORR message is received */
+#define PCIE_INTPME 0x20 /* PCIE INTPME message is received */
+
+/* SB to PCIE translation masks */
+#define SBTOPCIE0_MASK 0xfc000000
+#define SBTOPCIE1_MASK 0xfc000000
+#define SBTOPCIE2_MASK 0xc0000000
+
+/* Access type bits (0:1) */
+#define SBTOPCIE_MEM 0
+#define SBTOPCIE_IO 1
+#define SBTOPCIE_CFG0 2
+#define SBTOPCIE_CFG1 3
+
+/* Prefetch enable bit 2 */
+#define SBTOPCIE_PF 4
+
+/* Write Burst enable for memory write bit 3 */
+#define SBTOPCIE_WR_BURST 8
+
+/* config access */
+#define CONFIGADDR_FUNC_MASK 0x7000
+#define CONFIGADDR_FUNC_SHF 12
+#define CONFIGADDR_REG_MASK 0x0FFF
+#define CONFIGADDR_REG_SHF 0
+
+#define PCIE_CONFIG_INDADDR(f, r) \
+ ((((f) & CONFIGADDR_FUNC_MASK) << CONFIGADDR_FUNC_SHF) | \
+ (((r) & CONFIGADDR_REG_MASK) << CONFIGADDR_REG_SHF))
+
+/* PCIE protocol regs Indirect Address */
+#define PCIEADDR_PROT_MASK 0x300
+#define PCIEADDR_PROT_SHF 8
+#define PCIEADDR_PL_TLP 0
+#define PCIEADDR_PL_DLLP 1
+#define PCIEADDR_PL_PLP 2
+
+/* PCIE protocol PHY diagnostic registers */
+#define PCIE_PLP_MODEREG 0x200 /* Mode */
+#define PCIE_PLP_STATUSREG 0x204 /* Status */
+#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */
+#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */
+#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */
+#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */
+#define PCIE_PLP_ATTNREG 0x218 /* Attention */
+#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */
+#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */
+#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */
+#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */
+#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg */
+#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */
+#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */
+#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */
+#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */
+
+/* PCIE protocol DLLP diagnostic registers */
+#define PCIE_DLLP_LCREG 0x100 /* Link Control */
+#define PCIE_DLLP_LSREG 0x104 /* Link Status */
+#define PCIE_DLLP_LAREG 0x108 /* Link Attention */
+#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */
+#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */
+#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */
+#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */
+#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */
+#define PCIE_DLLP_LRREG 0x120 /* Link Replay */
+#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */
+#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
+#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */
+#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */
+#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */
+#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */
+#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */
+#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */
+#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter */
+#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */
+#define PCIE_DLLP_TESTREG 0x14C /* Test */
+#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST */
+#define PCIE_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */
+
+#define PCIE_DLLP_LSREG_LINKUP (1 << 16)
+
+/* PCIE protocol TLP diagnostic registers */
+#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */
+#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
+#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address */
+#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address */
+#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req */
+#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address */
+#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address */
+#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req */
+#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address */
+#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address */
+#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req */
+#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len */
+#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs */
+#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req */
+#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len */
+#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0 */
+#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1 */
+#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2 */
+#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */
+#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */
+#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */
+#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len */
+#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0 */
+#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1 */
+#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func */
+#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter */
+#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value */
+#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1 */
+#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2 */
+#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3 */
+#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4 */
+
+/* MDIO control */
+#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
+#define MDIOCTL_DIVISOR_VAL 0x2
+#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
+#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */
+
+/* MDIO Data */
+#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
+#define MDIODATA_TA 0x00020000 /* Turnaround */
+#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */
+#define MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */
+#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */
+#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
+#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
+#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
+#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
+#define MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */
+#define MDIODATA_WRITE 0x10000000 /* write Transaction */
+#define MDIODATA_READ 0x20000000 /* Read Transaction */
+#define MDIODATA_START 0x40000000 /* start of Transaction */
+
+#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
+#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
+
+/* MDIO devices (SERDES modules)
+ * unlike old pcie cores (rev < 10), rev10 pcie serde organizes registers into a few blocks.
+ * two layers mapping (blockidx, register offset) is required
+ */
+#define MDIO_DEV_IEEE0 0x000
+#define MDIO_DEV_IEEE1 0x001
+#define MDIO_DEV_BLK0 0x800
+#define MDIO_DEV_BLK1 0x801
+#define MDIO_DEV_BLK2 0x802
+#define MDIO_DEV_BLK3 0x803
+#define MDIO_DEV_BLK4 0x804
+#define MDIO_DEV_TXPLL 0x808 /* TXPLL register block idx */
+#define MDIO_DEV_TXCTRL0 0x820
+#define MDIO_DEV_SERDESID 0x831
+#define MDIO_DEV_RXCTRL0 0x840
+
+/* serdes regs (rev < 10) */
+#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
+#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
+#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
+ /* SERDES RX registers */
+#define SERDES_RX_CTRL 1 /* Rx cntrl */
+#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
+#define SERDES_RX_CDR 6 /* CDR */
+#define SERDES_RX_CDRBW 7 /* CDR BW */
+
+ /* SERDES RX control register */
+#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
+#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
+
+ /* SERDES PLL registers */
+#define SERDES_PLL_CTRL 1 /* PLL control reg */
+#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
+
+/* Power management threshold */
+#define PCIE_L0THRESHOLDTIME_MASK 0xFF00 /* bits 0 - 7 */
+#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
+#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
+#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
+#define PCIE_ASPMTIMER_EXTEND 0x01000000 /* > rev7: enable extend ASPM timer */
+
+/* SPROM offsets */
+#define SRSH_ASPM_OFFSET 4 /* word 4 */
+#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
+#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
+#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
+#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
+#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
+#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
+#define SRSH_CLKREQ_OFFSET_REV8 52 /* word 52 for srom rev 8 */
+#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
+#define SRSH_BD_OFFSET 6 /* word 6 */
+#define SRSH_AUTOINIT_OFFSET 18 /* auto initialization enable */
+
+/* Linkcontrol reg offset in PCIE Cap */
+#define PCIE_CAP_LINKCTRL_OFFSET 16 /* linkctrl offset in pcie cap */
+#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
+#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
+#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
+
+#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
+#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
+#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
+#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
+
+/* Status reg PCIE_PLP_STATUSREG */
+#define PCIE_PLP_POLARITYINV_STAT 0x10
+#endif /* _PCIE_CORE_H */
diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h
new file mode 100644
index 000000000000..a0f7de969f23
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/802.11.h
@@ -0,0 +1,1436 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _802_11_H_
+#define _802_11_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#ifndef _NET_ETHERNET_H_
+#include <proto/ethernet.h>
+#endif
+
+#include <proto/wpa.h>
+
+#include <packed_section_start.h>
+
+#define DOT11_TU_TO_US 1024
+
+#define DOT11_A3_HDR_LEN 24
+#define DOT11_A4_HDR_LEN 30
+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN
+#define DOT11_FCS_LEN 4
+#define DOT11_ICV_LEN 4
+#define DOT11_ICV_AES_LEN 8
+#define DOT11_QOS_LEN 2
+#define DOT11_HTC_LEN 4
+
+#define DOT11_KEY_INDEX_SHIFT 6
+#define DOT11_IV_LEN 4
+#define DOT11_IV_TKIP_LEN 8
+#define DOT11_IV_AES_OCB_LEN 4
+#define DOT11_IV_AES_CCM_LEN 8
+#define DOT11_IV_MAX_LEN 8
+
+#define DOT11_MAX_MPDU_BODY_LEN 2304
+
+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \
+ DOT11_QOS_LEN + \
+ DOT11_IV_AES_CCM_LEN + \
+ DOT11_MAX_MPDU_BODY_LEN + \
+ DOT11_ICV_LEN + \
+ DOT11_FCS_LEN)
+
+#define DOT11_MAX_SSID_LEN 32
+
+#define DOT11_DEFAULT_RTS_LEN 2347
+#define DOT11_MAX_RTS_LEN 2347
+
+#define DOT11_MIN_FRAG_LEN 256
+#define DOT11_MAX_FRAG_LEN 2346
+#define DOT11_DEFAULT_FRAG_LEN 2346
+
+#define DOT11_MIN_BEACON_PERIOD 1
+#define DOT11_MAX_BEACON_PERIOD 0xFFFF
+
+#define DOT11_MIN_DTIM_PERIOD 1
+#define DOT11_MAX_DTIM_PERIOD 0xFF
+
+#define DOT11_LLC_SNAP_HDR_LEN 8
+#define DOT11_OUI_LEN 3
+BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header {
+ uint8 dsap;
+ uint8 ssap;
+ uint8 ctl;
+ uint8 oui[DOT11_OUI_LEN];
+ uint16 type;
+} BWL_POST_PACKED_STRUCT;
+
+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN)
+
+BWL_PRE_PACKED_STRUCT struct dot11_header {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr a1;
+ struct ether_addr a2;
+ struct ether_addr a3;
+ uint16 seq;
+ struct ether_addr a4;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_rts_frame {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr ra;
+ struct ether_addr ta;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_RTS_LEN 16
+
+BWL_PRE_PACKED_STRUCT struct dot11_cts_frame {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr ra;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CTS_LEN 10
+
+BWL_PRE_PACKED_STRUCT struct dot11_ack_frame {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr ra;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACK_LEN 10
+
+BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr bssid;
+ struct ether_addr ta;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_PS_POLL_LEN 16
+
+BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr ra;
+ struct ether_addr bssid;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CS_END_LEN 16
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific {
+ uint8 category;
+ uint8 OUI[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 data[1040];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_action_wifi_vendor_specific
+ dot11_action_wifi_vendor_specific_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr {
+ uint8 category;
+ uint8 OUI[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t;
+#define DOT11_ACTION_VS_HDR_LEN 6
+
+#define BCM_ACTION_OUI_BYTE0 0x00
+#define BCM_ACTION_OUI_BYTE1 0x90
+#define BCM_ACTION_OUI_BYTE2 0x4c
+
+#define DOT11_BA_CTL_POLICY_NORMAL 0x0000
+#define DOT11_BA_CTL_POLICY_NOACK 0x0001
+#define DOT11_BA_CTL_POLICY_MASK 0x0001
+
+#define DOT11_BA_CTL_MTID 0x0002
+#define DOT11_BA_CTL_COMPRESSED 0x0004
+
+#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0
+#define DOT11_BA_CTL_NUMMSDU_SHIFT 6
+
+#define DOT11_BA_CTL_TID_MASK 0xF000
+#define DOT11_BA_CTL_TID_SHIFT 12
+
+BWL_PRE_PACKED_STRUCT struct dot11_ctl_header {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr ra;
+ struct ether_addr ta;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CTL_HDR_LEN 16
+
+BWL_PRE_PACKED_STRUCT struct dot11_bar {
+ uint16 bar_control;
+ uint16 seqnum;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BAR_LEN 4
+
+#define DOT11_BA_BITMAP_LEN 128
+#define DOT11_BA_CMP_BITMAP_LEN 8
+
+BWL_PRE_PACKED_STRUCT struct dot11_ba {
+ uint16 ba_control;
+ uint16 seqnum;
+ uint8 bitmap[DOT11_BA_BITMAP_LEN];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BA_LEN 4
+
+BWL_PRE_PACKED_STRUCT struct dot11_management_header {
+ uint16 fc;
+ uint16 durid;
+ struct ether_addr da;
+ struct ether_addr sa;
+ struct ether_addr bssid;
+ uint16 seq;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_MGMT_HDR_LEN 24
+
+BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb {
+ uint32 timestamp[2];
+ uint16 beacon_interval;
+ uint16 capability;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BCN_PRB_LEN 12
+#define DOT11_BCN_PRB_FIXED_LEN 12
+
+BWL_PRE_PACKED_STRUCT struct dot11_auth {
+ uint16 alg;
+ uint16 seq;
+ uint16 status;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_AUTH_FIXED_LEN 6
+
+BWL_PRE_PACKED_STRUCT struct dot11_assoc_req {
+ uint16 capability;
+ uint16 listen;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ASSOC_REQ_FIXED_LEN 4
+
+BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req {
+ uint16 capability;
+ uint16 listen;
+ struct ether_addr ap;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_REASSOC_REQ_FIXED_LEN 10
+
+BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp {
+ uint16 capability;
+ uint16 status;
+ uint16 aid;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ASSOC_RESP_FIXED_LEN 6
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_measure {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACTION_MEASURE_LEN 3
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width {
+ uint8 category;
+ uint8 action;
+ uint8 ch_width;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops {
+ uint8 category;
+ uint8 action;
+ uint8 control;
+} BWL_POST_PACKED_STRUCT;
+
+#define SM_PWRSAVE_ENABLE 1
+#define SM_PWRSAVE_MODE 2
+
+BWL_PRE_PACKED_STRUCT struct dot11_power_cnst {
+ uint8 id;
+ uint8 len;
+ uint8 power;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_power_cnst dot11_power_cnst_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_power_cap {
+ uint8 min;
+ uint8 max;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_power_cap dot11_power_cap_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep {
+ uint8 id;
+ uint8 len;
+ uint8 tx_pwr;
+ uint8 margin;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_tpc_rep dot11_tpc_rep_t;
+#define DOT11_MNG_IE_TPC_REPORT_LEN 2
+
+BWL_PRE_PACKED_STRUCT struct dot11_supp_channels {
+ uint8 id;
+ uint8 len;
+ uint8 first_channel;
+ uint8 num_channels;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_supp_channels dot11_supp_channels_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_extch {
+ uint8 id;
+ uint8 len;
+ uint8 extch;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extch dot11_extch_ie_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch {
+ uint8 id;
+ uint8 len;
+ uint8 oui[3];
+ uint8 type;
+ uint8 extch;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t;
+
+#define DOT11_EXTCH_IE_LEN 1
+#define DOT11_EXT_CH_MASK 0x03
+#define DOT11_EXT_CH_UPPER 0x01
+#define DOT11_EXT_CH_LOWER 0x03
+#define DOT11_EXT_CH_NONE 0x00
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr {
+ uint8 category;
+ uint8 action;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACTION_FRMHDR_LEN 2
+
+BWL_PRE_PACKED_STRUCT struct dot11_channel_switch {
+ uint8 id;
+ uint8 len;
+ uint8 mode;
+ uint8 channel;
+ uint8 count;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_channel_switch dot11_chan_switch_ie_t;
+
+#define DOT11_SWITCH_IE_LEN 3
+
+#define DOT11_CSA_MODE_ADVISORY 0
+#define DOT11_CSA_MODE_NO_TX 1
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel {
+ uint8 category;
+ uint8 action;
+ dot11_chan_switch_ie_t chan_switch_ie;
+ dot11_brcm_extch_ie_t extch_ie;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_csa_body {
+ uint8 mode;
+ uint8 reg;
+ uint8 channel;
+ uint8 count;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_ext_csa {
+ uint8 id;
+ uint8 len;
+ struct dot11_csa_body b;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ext_csa dot11_ext_csa_ie_t;
+#define DOT11_EXT_CSA_IE_LEN 4
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa {
+ uint8 category;
+ uint8 action;
+ dot11_ext_csa_ie_t chan_switch_ie;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa {
+ uint8 category;
+ uint8 action;
+ struct dot11_csa_body b;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_coex {
+ uint8 id;
+ uint8 len;
+ uint8 info;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_coex dot11_obss_coex_t;
+#define DOT11_OBSS_COEXINFO_LEN 1
+
+#define DOT11_OBSS_COEX_INFO_REQ 0x01
+#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02
+#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist {
+ uint8 id;
+ uint8 len;
+ uint8 regclass;
+ uint8 chanlist[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_chanlist dot11_obss_chanlist_t;
+#define DOT11_OBSS_CHANLIST_FIXED_LEN 1
+
+BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie {
+ uint8 id;
+ uint8 len;
+ uint8 cap;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extcap_ie dot11_extcap_ie_t;
+#define DOT11_EXTCAP_LEN 1
+
+#define DOT11_MEASURE_TYPE_BASIC 0
+#define DOT11_MEASURE_TYPE_CCA 1
+#define DOT11_MEASURE_TYPE_RPI 2
+#define DOT11_MEASURE_TYPE_CHLOAD 3
+#define DOT11_MEASURE_TYPE_NOISE 4
+#define DOT11_MEASURE_TYPE_BEACON 5
+#define DOT11_MEASURE_TYPE_FRAME 6
+#define DOT11_MEASURE_TYPE_STATS 7
+#define DOT11_MEASURE_TYPE_LCI 8
+#define DOT11_MEASURE_TYPE_TXSTREAM 9
+#define DOT11_MEASURE_TYPE_PAUSE 255
+
+#define DOT11_MEASURE_MODE_PARALLEL (1<<0)
+#define DOT11_MEASURE_MODE_ENABLE (1<<1)
+#define DOT11_MEASURE_MODE_REQUEST (1<<2)
+#define DOT11_MEASURE_MODE_REPORT (1<<3)
+#define DOT11_MEASURE_MODE_DUR (1<<4)
+
+#define DOT11_MEASURE_MODE_LATE (1<<0)
+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1)
+#define DOT11_MEASURE_MODE_REFUSED (1<<2)
+
+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0))
+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1))
+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2))
+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3))
+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4))
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_req {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_req dot11_meas_req_t;
+#define DOT11_MNG_IE_MREQ_LEN 14
+
+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ BWL_PRE_PACKED_STRUCT union {
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+ } BWL_POST_PACKED_STRUCT basic;
+ uint8 data[1];
+ } BWL_POST_PACKED_STRUCT rep;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_rep dot11_meas_rep_t;
+
+#define DOT11_MNG_IE_MREP_FIXED_LEN 3
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t;
+#define DOT11_MEASURE_BASIC_REP_LEN 12
+
+BWL_PRE_PACKED_STRUCT struct dot11_quiet {
+ uint8 id;
+ uint8 len;
+ uint8 count;
+ uint8 period;
+ uint16 duration;
+ uint16 offset;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_quiet dot11_quiet_t;
+
+BWL_PRE_PACKED_STRUCT struct chan_map_tuple {
+ uint8 channel;
+ uint8 map;
+} BWL_POST_PACKED_STRUCT;
+typedef struct chan_map_tuple chan_map_tuple_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs {
+ uint8 id;
+ uint8 len;
+ uint8 eaddr[ETHER_ADDR_LEN];
+ uint8 interval;
+ chan_map_tuple_t map[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ibss_dfs dot11_ibss_dfs_t;
+
+#define WME_OUI "\x00\x50\xf2"
+#define WME_VER 1
+#define WME_TYPE 2
+#define WME_SUBTYPE_IE 0
+#define WME_SUBTYPE_PARAM_IE 1
+#define WME_SUBTYPE_TSPEC 2
+
+#define AC_BE 0
+#define AC_BK 1
+#define AC_VI 2
+#define AC_VO 3
+#define AC_COUNT 4
+
+typedef uint8 ac_bitmap_t;
+
+#define AC_BITMAP_NONE 0x0
+#define AC_BITMAP_ALL 0xf
+#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0)
+#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac))))
+#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac))))
+
+BWL_PRE_PACKED_STRUCT struct wme_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+} BWL_POST_PACKED_STRUCT;
+typedef struct wme_ie wme_ie_t;
+#define WME_IE_LEN 7
+
+BWL_PRE_PACKED_STRUCT struct edcf_acparam {
+ uint8 ACI;
+ uint8 ECW;
+ uint16 TXOP;
+} BWL_POST_PACKED_STRUCT;
+typedef struct edcf_acparam edcf_acparam_t;
+
+BWL_PRE_PACKED_STRUCT struct wme_param_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+ uint8 rsvd;
+ edcf_acparam_t acparam[AC_COUNT];
+} BWL_POST_PACKED_STRUCT;
+typedef struct wme_param_ie wme_param_ie_t;
+#define WME_PARAM_IE_LEN 24
+
+#define WME_QI_AP_APSD_MASK 0x80
+#define WME_QI_AP_APSD_SHIFT 7
+#define WME_QI_AP_COUNT_MASK 0x0f
+#define WME_QI_AP_COUNT_SHIFT 0
+
+#define WME_QI_STA_MAXSPLEN_MASK 0x60
+#define WME_QI_STA_MAXSPLEN_SHIFT 5
+#define WME_QI_STA_APSD_ALL_MASK 0xf
+#define WME_QI_STA_APSD_ALL_SHIFT 0
+#define WME_QI_STA_APSD_BE_MASK 0x8
+#define WME_QI_STA_APSD_BE_SHIFT 3
+#define WME_QI_STA_APSD_BK_MASK 0x4
+#define WME_QI_STA_APSD_BK_SHIFT 2
+#define WME_QI_STA_APSD_VI_MASK 0x2
+#define WME_QI_STA_APSD_VI_SHIFT 1
+#define WME_QI_STA_APSD_VO_MASK 0x1
+#define WME_QI_STA_APSD_VO_SHIFT 0
+
+#define EDCF_AIFSN_MIN 1
+#define EDCF_AIFSN_MAX 15
+#define EDCF_AIFSN_MASK 0x0f
+#define EDCF_ACM_MASK 0x10
+#define EDCF_ACI_MASK 0x60
+#define EDCF_ACI_SHIFT 5
+#define EDCF_AIFSN_SHIFT 12
+
+#define EDCF_ECW_MIN 0
+#define EDCF_ECW_MAX 15
+#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
+#define EDCF_ECWMIN_MASK 0x0f
+#define EDCF_ECWMAX_MASK 0xf0
+#define EDCF_ECWMAX_SHIFT 4
+
+#define EDCF_TXOP_MIN 0
+#define EDCF_TXOP_MAX 65535
+#define EDCF_TXOP2USEC(txop) ((txop) << 5)
+
+#define NON_EDCF_AC_BE_ACI_STA 0x02
+
+#define EDCF_AC_BE_ACI_STA 0x03
+#define EDCF_AC_BE_ECW_STA 0xA4
+#define EDCF_AC_BE_TXOP_STA 0x0000
+#define EDCF_AC_BK_ACI_STA 0x27
+#define EDCF_AC_BK_ECW_STA 0xA4
+#define EDCF_AC_BK_TXOP_STA 0x0000
+#define EDCF_AC_VI_ACI_STA 0x42
+#define EDCF_AC_VI_ECW_STA 0x43
+#define EDCF_AC_VI_TXOP_STA 0x005e
+#define EDCF_AC_VO_ACI_STA 0x62
+#define EDCF_AC_VO_ECW_STA 0x32
+#define EDCF_AC_VO_TXOP_STA 0x002f
+
+#define EDCF_AC_BE_ACI_AP 0x03
+#define EDCF_AC_BE_ECW_AP 0x64
+#define EDCF_AC_BE_TXOP_AP 0x0000
+#define EDCF_AC_BK_ACI_AP 0x27
+#define EDCF_AC_BK_ECW_AP 0xA4
+#define EDCF_AC_BK_TXOP_AP 0x0000
+#define EDCF_AC_VI_ACI_AP 0x41
+#define EDCF_AC_VI_ECW_AP 0x43
+#define EDCF_AC_VI_TXOP_AP 0x005e
+#define EDCF_AC_VO_ACI_AP 0x61
+#define EDCF_AC_VO_ECW_AP 0x32
+#define EDCF_AC_VO_TXOP_AP 0x002f
+
+BWL_PRE_PACKED_STRUCT struct edca_param_ie {
+ uint8 qosinfo;
+ uint8 rsvd;
+ edcf_acparam_t acparam[AC_COUNT];
+} BWL_POST_PACKED_STRUCT;
+typedef struct edca_param_ie edca_param_ie_t;
+#define EDCA_PARAM_IE_LEN 18
+
+BWL_PRE_PACKED_STRUCT struct qos_cap_ie {
+ uint8 qosinfo;
+} BWL_POST_PACKED_STRUCT;
+typedef struct qos_cap_ie qos_cap_ie_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie {
+ uint8 id;
+ uint8 length;
+ uint16 station_count;
+ uint8 channel_utilization;
+ uint16 aac;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t;
+
+#define FIXED_MSDU_SIZE 0x8000
+#define MSDU_SIZE_MASK 0x7fff
+
+#define INTEGER_SHIFT 13
+#define FRACTION_MASK 0x1FFF
+
+BWL_PRE_PACKED_STRUCT struct dot11_management_notification {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 status;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_MGMT_NOTIFICATION_LEN 4
+
+#define WME_ADDTS_REQUEST 0
+#define WME_ADDTS_RESPONSE 1
+#define WME_DELTS_REQUEST 2
+
+#define WME_ADMISSION_ACCEPTED 0
+#define WME_INVALID_PARAMETERS 1
+#define WME_ADMISSION_REFUSED 3
+
+#define BCN_PRB_SSID(body) ((char *)(body) + DOT11_BCN_PRB_LEN)
+
+#define DOT11_OPEN_SYSTEM 0
+#define DOT11_SHARED_KEY 1
+#define DOT11_OPEN_SHARED 2
+#define DOT11_CHALLENGE_LEN 128
+
+#define FC_PVER_MASK 0x3
+#define FC_PVER_SHIFT 0
+#define FC_TYPE_MASK 0xC
+#define FC_TYPE_SHIFT 2
+#define FC_SUBTYPE_MASK 0xF0
+#define FC_SUBTYPE_SHIFT 4
+#define FC_TODS 0x100
+#define FC_TODS_SHIFT 8
+#define FC_FROMDS 0x200
+#define FC_FROMDS_SHIFT 9
+#define FC_MOREFRAG 0x400
+#define FC_MOREFRAG_SHIFT 10
+#define FC_RETRY 0x800
+#define FC_RETRY_SHIFT 11
+#define FC_PM 0x1000
+#define FC_PM_SHIFT 12
+#define FC_MOREDATA 0x2000
+#define FC_MOREDATA_SHIFT 13
+#define FC_WEP 0x4000
+#define FC_WEP_SHIFT 14
+#define FC_ORDER 0x8000
+#define FC_ORDER_SHIFT 15
+
+#define SEQNUM_SHIFT 4
+#define SEQNUM_MAX 0x1000
+#define FRAGNUM_MASK 0xF
+
+#define FC_TYPE_MNG 0
+#define FC_TYPE_CTL 1
+#define FC_TYPE_DATA 2
+
+#define FC_SUBTYPE_ASSOC_REQ 0
+#define FC_SUBTYPE_ASSOC_RESP 1
+#define FC_SUBTYPE_REASSOC_REQ 2
+#define FC_SUBTYPE_REASSOC_RESP 3
+#define FC_SUBTYPE_PROBE_REQ 4
+#define FC_SUBTYPE_PROBE_RESP 5
+#define FC_SUBTYPE_BEACON 8
+#define FC_SUBTYPE_ATIM 9
+#define FC_SUBTYPE_DISASSOC 10
+#define FC_SUBTYPE_AUTH 11
+#define FC_SUBTYPE_DEAUTH 12
+#define FC_SUBTYPE_ACTION 13
+#define FC_SUBTYPE_ACTION_NOACK 14
+
+#define FC_SUBTYPE_CTL_WRAPPER 7
+#define FC_SUBTYPE_BLOCKACK_REQ 8
+#define FC_SUBTYPE_BLOCKACK 9
+#define FC_SUBTYPE_PS_POLL 10
+#define FC_SUBTYPE_RTS 11
+#define FC_SUBTYPE_CTS 12
+#define FC_SUBTYPE_ACK 13
+#define FC_SUBTYPE_CF_END 14
+#define FC_SUBTYPE_CF_END_ACK 15
+
+#define FC_SUBTYPE_DATA 0
+#define FC_SUBTYPE_DATA_CF_ACK 1
+#define FC_SUBTYPE_DATA_CF_POLL 2
+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3
+#define FC_SUBTYPE_NULL 4
+#define FC_SUBTYPE_CF_ACK 5
+#define FC_SUBTYPE_CF_POLL 6
+#define FC_SUBTYPE_CF_ACK_POLL 7
+#define FC_SUBTYPE_QOS_DATA 8
+#define FC_SUBTYPE_QOS_DATA_CF_ACK 9
+#define FC_SUBTYPE_QOS_DATA_CF_POLL 10
+#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11
+#define FC_SUBTYPE_QOS_NULL 12
+#define FC_SUBTYPE_QOS_CF_POLL 14
+#define FC_SUBTYPE_QOS_CF_ACK_POLL 15
+
+#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0)
+#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0)
+#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0)
+#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0)
+
+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK)
+
+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT))
+
+#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT)
+#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT)
+
+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ)
+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP)
+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ)
+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP)
+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ)
+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP)
+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON)
+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC)
+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH)
+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH)
+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION)
+#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK)
+
+#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER)
+#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ)
+#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK)
+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL)
+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS)
+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS)
+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK)
+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END)
+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK)
+
+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA)
+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL)
+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK)
+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA)
+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL)
+
+#define QOS_PRIO_SHIFT 0
+#define QOS_PRIO_MASK 0x0007
+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT)
+
+#define QOS_TID_SHIFT 0
+#define QOS_TID_MASK 0x000f
+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT)
+
+#define QOS_EOSP_SHIFT 4
+#define QOS_EOSP_MASK 0x0010
+#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT)
+
+#define QOS_ACK_NORMAL_ACK 0
+#define QOS_ACK_NO_ACK 1
+#define QOS_ACK_NO_EXP_ACK 2
+#define QOS_ACK_BLOCK_ACK 3
+#define QOS_ACK_SHIFT 5
+#define QOS_ACK_MASK 0x0060
+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT)
+
+#define QOS_AMSDU_SHIFT 7
+#define QOS_AMSDU_MASK 0x0080
+
+#define DOT11_MNG_AUTH_ALGO_LEN 2
+#define DOT11_MNG_AUTH_SEQ_LEN 2
+#define DOT11_MNG_BEACON_INT_LEN 2
+#define DOT11_MNG_CAP_LEN 2
+#define DOT11_MNG_AP_ADDR_LEN 6
+#define DOT11_MNG_LISTEN_INT_LEN 2
+#define DOT11_MNG_REASON_LEN 2
+#define DOT11_MNG_AID_LEN 2
+#define DOT11_MNG_STATUS_LEN 2
+#define DOT11_MNG_TIMESTAMP_LEN 8
+
+#define DOT11_AID_MASK 0x3fff
+
+#define DOT11_RC_RESERVED 0
+#define DOT11_RC_UNSPECIFIED 1
+#define DOT11_RC_AUTH_INVAL 2
+#define DOT11_RC_DEAUTH_LEAVING 3
+#define DOT11_RC_INACTIVITY 4
+#define DOT11_RC_BUSY 5
+#define DOT11_RC_INVAL_CLASS_2 6
+#define DOT11_RC_INVAL_CLASS_3 7
+#define DOT11_RC_DISASSOC_LEAVING 8
+#define DOT11_RC_NOT_AUTH 9
+#define DOT11_RC_BAD_PC 10
+#define DOT11_RC_BAD_CHANNELS 11
+
+#define DOT11_RC_UNSPECIFIED_QOS 32
+#define DOT11_RC_INSUFFCIENT_BW 33
+#define DOT11_RC_EXCESSIVE_FRAMES 34
+#define DOT11_RC_TX_OUTSIDE_TXOP 35
+#define DOT11_RC_LEAVING_QBSS 36
+#define DOT11_RC_BAD_MECHANISM 37
+#define DOT11_RC_SETUP_NEEDED 38
+#define DOT11_RC_TIMEOUT 39
+
+#define DOT11_RC_MAX 23
+
+#define DOT11_SC_SUCCESS 0
+#define DOT11_SC_FAILURE 1
+#define DOT11_SC_CAP_MISMATCH 10
+#define DOT11_SC_REASSOC_FAIL 11
+#define DOT11_SC_ASSOC_FAIL 12
+#define DOT11_SC_AUTH_MISMATCH 13
+#define DOT11_SC_AUTH_SEQ 14
+#define DOT11_SC_AUTH_CHALLENGE_FAIL 15
+#define DOT11_SC_AUTH_TIMEOUT 16
+#define DOT11_SC_ASSOC_BUSY_FAIL 17
+#define DOT11_SC_ASSOC_RATE_MISMATCH 18
+#define DOT11_SC_ASSOC_SHORT_REQUIRED 19
+#define DOT11_SC_ASSOC_PBCC_REQUIRED 20
+#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21
+#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22
+#define DOT11_SC_ASSOC_BAD_POWER_CAP 23
+#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24
+#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25
+#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26
+#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27
+
+#define DOT11_SC_DECLINED 37
+#define DOT11_SC_INVALID_PARAMS 38
+
+#define DOT11_MNG_DS_PARAM_LEN 1
+#define DOT11_MNG_IBSS_PARAM_LEN 2
+
+#define DOT11_MNG_TIM_FIXED_LEN 3
+#define DOT11_MNG_TIM_DTIM_COUNT 0
+#define DOT11_MNG_TIM_DTIM_PERIOD 1
+#define DOT11_MNG_TIM_BITMAP_CTL 2
+#define DOT11_MNG_TIM_PVB 3
+
+#define TLV_TAG_OFF 0
+#define TLV_LEN_OFF 1
+#define TLV_HDR_LEN 2
+#define TLV_BODY_OFF 2
+
+#define DOT11_MNG_SSID_ID 0
+#define DOT11_MNG_RATES_ID 1
+#define DOT11_MNG_FH_PARMS_ID 2
+#define DOT11_MNG_DS_PARMS_ID 3
+#define DOT11_MNG_CF_PARMS_ID 4
+#define DOT11_MNG_TIM_ID 5
+#define DOT11_MNG_IBSS_PARMS_ID 6
+#define DOT11_MNG_COUNTRY_ID 7
+#define DOT11_MNG_HOPPING_PARMS_ID 8
+#define DOT11_MNG_HOPPING_TABLE_ID 9
+#define DOT11_MNG_REQUEST_ID 10
+#define DOT11_MNG_QBSS_LOAD_ID 11
+#define DOT11_MNG_EDCA_PARAM_ID 12
+#define DOT11_MNG_CHALLENGE_ID 16
+#define DOT11_MNG_PWR_CONSTRAINT_ID 32
+#define DOT11_MNG_PWR_CAP_ID 33
+#define DOT11_MNG_TPC_REQUEST_ID 34
+#define DOT11_MNG_TPC_REPORT_ID 35
+#define DOT11_MNG_SUPP_CHANNELS_ID 36
+#define DOT11_MNG_CHANNEL_SWITCH_ID 37
+#define DOT11_MNG_MEASURE_REQUEST_ID 38
+#define DOT11_MNG_MEASURE_REPORT_ID 39
+#define DOT11_MNG_QUIET_ID 40
+#define DOT11_MNG_IBSS_DFS_ID 41
+#define DOT11_MNG_ERP_ID 42
+#define DOT11_MNG_TS_DELAY_ID 43
+#define DOT11_MNG_HT_CAP 45
+#define DOT11_MNG_QOS_CAP_ID 46
+#define DOT11_MNG_NONERP_ID 47
+#define DOT11_MNG_RSN_ID 48
+#define DOT11_MNG_EXT_RATES_ID 50
+#define DOT11_MNG_AP_CHREP_ID 51
+#define DOT11_MNG_NBR_REP_ID 52
+#define DOT11_MNG_REGCLASS_ID 59
+#define DOT11_MNG_EXT_CSA_ID 60
+#define DOT11_MNG_HT_ADD 61
+#define DOT11_MNG_EXT_CHANNEL_OFFSET 62
+
+#define DOT11_MNG_RRM_CAP_ID 70
+#define DOT11_MNG_HT_BSS_COEXINFO_ID 72
+#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73
+#define DOT11_MNG_HT_OBSS_ID 74
+#define DOT11_MNG_EXT_CAP 127
+#define DOT11_MNG_WPA_ID 221
+#define DOT11_MNG_PROPR_ID 221
+
+#define DOT11_MNG_VS_ID 221
+
+#define DOT11_RATE_BASIC 0x80
+#define DOT11_RATE_MASK 0x7F
+
+#define DOT11_MNG_ERP_LEN 1
+#define DOT11_MNG_NONERP_PRESENT 0x01
+#define DOT11_MNG_USE_PROTECTION 0x02
+#define DOT11_MNG_BARKER_PREAMBLE 0x04
+
+#define DOT11_MGN_TS_DELAY_LEN 4
+#define TS_DELAY_FIELD_SIZE 4
+
+#define DOT11_CAP_ESS 0x0001
+#define DOT11_CAP_IBSS 0x0002
+#define DOT11_CAP_POLLABLE 0x0004
+#define DOT11_CAP_POLL_RQ 0x0008
+#define DOT11_CAP_PRIVACY 0x0010
+#define DOT11_CAP_SHORT 0x0020
+#define DOT11_CAP_PBCC 0x0040
+#define DOT11_CAP_AGILITY 0x0080
+#define DOT11_CAP_SPECTRUM 0x0100
+#define DOT11_CAP_SHORTSLOT 0x0400
+#define DOT11_CAP_RRM 0x1000
+#define DOT11_CAP_CCK_OFDM 0x2000
+
+#define DOT11_OBSS_COEX_MNG_SUPPORT 0x01
+
+#define DOT11_ACTION_HDR_LEN 2
+
+#define DOT11_ACTION_CAT_ERR_MASK 0x80
+#define DOT11_ACTION_CAT_MASK 0x7F
+#define DOT11_ACTION_CAT_SPECT_MNG 0
+#define DOT11_ACTION_CAT_QOS 1
+#define DOT11_ACTION_CAT_DLS 2
+#define DOT11_ACTION_CAT_BLOCKACK 3
+#define DOT11_ACTION_CAT_PUBLIC 4
+#define DOT11_ACTION_CAT_RRM 5
+#define DOT11_ACTION_CAT_HT 7
+#define DOT11_ACTION_NOTIFICATION 17
+#define DOT11_ACTION_CAT_VS 127
+
+#define DOT11_SM_ACTION_M_REQ 0
+#define DOT11_SM_ACTION_M_REP 1
+#define DOT11_SM_ACTION_TPC_REQ 2
+#define DOT11_SM_ACTION_TPC_REP 3
+#define DOT11_SM_ACTION_CHANNEL_SWITCH 4
+#define DOT11_SM_ACTION_EXT_CSA 5
+
+#define DOT11_ACTION_ID_HT_CH_WIDTH 0
+#define DOT11_ACTION_ID_HT_MIMO_PS 1
+
+#define DOT11_PUB_ACTION_BSS_COEX_MNG 0
+#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4
+
+#define DOT11_BA_ACTION_ADDBA_REQ 0
+#define DOT11_BA_ACTION_ADDBA_RESP 1
+#define DOT11_BA_ACTION_DELBA 2
+
+#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001
+#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002
+#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1
+#define DOT11_ADDBA_PARAM_TID_MASK 0x003c
+#define DOT11_ADDBA_PARAM_TID_SHIFT 2
+#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0
+#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6
+
+#define DOT11_ADDBA_POLICY_DELAYED 0
+#define DOT11_ADDBA_POLICY_IMMEDIATE 1
+
+BWL_PRE_PACKED_STRUCT struct dot11_addba_req {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint16 addba_param_set;
+ uint16 timeout;
+ uint16 start_seqnum;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_addba_req dot11_addba_req_t;
+#define DOT11_ADDBA_REQ_LEN 9
+
+BWL_PRE_PACKED_STRUCT struct dot11_addba_resp {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint16 status;
+ uint16 addba_param_set;
+ uint16 timeout;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_addba_resp dot11_addba_resp_t;
+#define DOT11_ADDBA_RESP_LEN 9
+
+#define DOT11_DELBA_PARAM_INIT_MASK 0x0800
+#define DOT11_DELBA_PARAM_INIT_SHIFT 11
+#define DOT11_DELBA_PARAM_TID_MASK 0xf000
+#define DOT11_DELBA_PARAM_TID_SHIFT 12
+
+BWL_PRE_PACKED_STRUCT struct dot11_delba {
+ uint8 category;
+ uint8 action;
+ uint16 delba_param_set;
+ uint16 reason;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_delba dot11_delba_t;
+#define DOT11_DELBA_LEN 6
+
+#define DOT11_RRM_CAP_LEN 5
+BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie {
+ uint8 cap[DOT11_RRM_CAP_LEN];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t;
+
+#define DOT11_RRM_CAP_LINK 0
+#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1
+#define DOT11_RRM_CAP_PARALLEL 2
+#define DOT11_RRM_CAP_REPEATED 3
+#define DOT11_RRM_CAP_BCN_PASSIVE 4
+#define DOT11_RRM_CAP_BCN_ACTIVE 5
+#define DOT11_RRM_CAP_BCN_TABLE 6
+#define DOT11_RRM_CAP_BCN_REP_COND 7
+#define DOT11_RRM_CAP_AP_CHANREP 16
+
+#define DOT11_RM_ACTION_RM_REQ 0
+#define DOT11_RM_ACTION_RM_REP 1
+#define DOT11_RM_ACTION_LM_REQ 2
+#define DOT11_RM_ACTION_LM_REP 3
+#define DOT11_RM_ACTION_NR_REQ 4
+#define DOT11_RM_ACTION_NR_REP 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_rm_action {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rm_action dot11_rm_action_t;
+#define DOT11_RM_ACTION_LEN 3
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmreq {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint16 reps;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmreq dot11_rmreq_t;
+#define DOT11_RMREQ_LEN 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_rm_ie {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rm_ie dot11_rm_ie_t;
+#define DOT11_RM_IE_LEN 5
+
+#define DOT11_RMREQ_MODE_PARALLEL 1
+#define DOT11_RMREQ_MODE_ENABLE 2
+#define DOT11_RMREQ_MODE_REQUEST 4
+#define DOT11_RMREQ_MODE_REPORT 8
+#define DOT11_RMREQ_MODE_DURMAND 0x10
+
+#define DOT11_RMREP_MODE_LATE 1
+#define DOT11_RMREP_MODE_INCAPABLE 2
+#define DOT11_RMREP_MODE_REFUSED 4
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 reg;
+ uint8 channel;
+ uint16 interval;
+ uint16 duration;
+ uint8 bcn_mode;
+ struct ether_addr bssid;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t;
+#define DOT11_RMREQ_BCN_LEN 18
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn {
+ uint8 reg;
+ uint8 channel;
+ uint32 starttime[2];
+ uint16 duration;
+ uint8 frame_info;
+ uint8 rcpi;
+ uint8 rsni;
+ struct ether_addr bssid;
+ uint8 antenna_id;
+ uint32 parent_tsf;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t;
+#define DOT11_RMREP_BCN_LEN 26
+
+#define DOT11_RMREQ_BCN_PASSIVE 0
+#define DOT11_RMREQ_BCN_ACTIVE 1
+#define DOT11_RMREQ_BCN_TABLE 2
+
+#define DOT11_RMREQ_BCN_SSID_ID 0
+#define DOT11_RMREQ_BCN_REPINFO_ID 1
+#define DOT11_RMREQ_BCN_REPDET_ID 2
+#define DOT11_RMREQ_BCN_REQUEST_ID 10
+#define DOT11_RMREQ_BCN_APCHREP_ID 51
+
+#define DOT11_RMREQ_BCN_REPDET_FIXED 0
+#define DOT11_RMREQ_BCN_REPDET_REQUEST 1
+#define DOT11_RMREQ_BCN_REPDET_ALL 2
+
+#define DOT11_RMREP_BCN_FRM_BODY 1
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr {
+ struct ether_addr bssid;
+ uint32 bssid_info;
+ uint8 reg;
+ uint8 channel;
+ uint8 phytype;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t;
+#define DOT11_RMREP_NBR_LEN 13
+
+#define DOT11_BSSTYPE_INFRASTRUCTURE 0
+#define DOT11_BSSTYPE_INDEPENDENT 1
+#define DOT11_BSSTYPE_ANY 2
+#define DOT11_SCANTYPE_ACTIVE 0
+#define DOT11_SCANTYPE_PASSIVE 1
+
+BWL_PRE_PACKED_STRUCT struct dot11_lmreq {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 txpwr;
+ uint8 maxtxpwr;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_lmreq dot11_lmreq_t;
+#define DOT11_LMREQ_LEN 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_lmrep {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ dot11_tpc_rep_t tpc;
+ uint8 rxant;
+ uint8 txant;
+ uint8 rcpi;
+ uint8 rsni;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_lmrep dot11_lmrep_t;
+#define DOT11_LMREP_LEN 11
+
+#define PREN_PREAMBLE 24
+#define PREN_MM_EXT 12
+#define PREN_PREAMBLE_EXT 4
+
+#define RIFS_11N_TIME 2
+
+#define APHY_SLOT_TIME 9
+#define APHY_SIFS_TIME 16
+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME))
+#define APHY_PREAMBLE_TIME 16
+#define APHY_SIGNAL_TIME 4
+#define APHY_SYMBOL_TIME 4
+#define APHY_SERVICE_NBITS 16
+#define APHY_TAIL_NBITS 6
+#define APHY_CWMIN 15
+
+#define BPHY_SLOT_TIME 20
+#define BPHY_SIFS_TIME 10
+#define BPHY_DIFS_TIME 50
+#define BPHY_PLCP_TIME 192
+#define BPHY_PLCP_SHORT_TIME 96
+#define BPHY_CWMIN 31
+
+#define DOT11_OFDM_SIGNAL_EXTENSION 6
+
+#define PHY_CWMAX 1023
+
+#define DOT11_MAXNUMFRAGS 16
+
+typedef struct d11cnt {
+ uint32 txfrag;
+ uint32 txmulti;
+ uint32 txfail;
+ uint32 txretry;
+ uint32 txretrie;
+ uint32 rxdup;
+ uint32 txrts;
+ uint32 txnocts;
+ uint32 txnoack;
+ uint32 rxfrag;
+ uint32 rxmulti;
+ uint32 rxcrc;
+ uint32 txfrmsnt;
+ uint32 rxundec;
+} d11cnt_t;
+
+#define AB_GUARDCOUNT 10
+
+BWL_PRE_PACKED_STRUCT struct vndr_ie {
+ uchar id;
+ uchar len;
+ uchar oui[3];
+ uchar data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct vndr_ie vndr_ie_t;
+
+#define VNDR_IE_HDR_LEN 2
+#define VNDR_IE_MIN_LEN 3
+#define VNDR_IE_MAX_LEN 256
+
+#define MCSSET_LEN 16
+#define MAX_MCS_NUM (128)
+
+BWL_PRE_PACKED_STRUCT struct ht_cap_ie {
+ uint16 cap;
+ uint8 params;
+ uint8 supp_mcs[MCSSET_LEN];
+ uint16 ext_htcap;
+ uint32 txbf_cap;
+ uint8 as_cap;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_cap_ie ht_cap_ie_t;
+
+#define HT_CAP_IE_LEN 26
+#define HT_CAP_IE_TYPE 51
+
+#define HT_CAP_LDPC_CODING 0x0001
+#define HT_CAP_40MHZ 0x0002
+#define HT_CAP_MIMO_PS_MASK 0x000C
+#define HT_CAP_MIMO_PS_SHIFT 0x0002
+#define HT_CAP_MIMO_PS_OFF 0x0003
+#define HT_CAP_MIMO_PS_RTS 0x0001
+#define HT_CAP_MIMO_PS_ON 0x0000
+#define HT_CAP_GF 0x0010
+#define HT_CAP_SHORT_GI_20 0x0020
+#define HT_CAP_SHORT_GI_40 0x0040
+#define HT_CAP_TX_STBC 0x0080
+#define HT_CAP_RX_STBC_MASK 0x0300
+#define HT_CAP_RX_STBC_SHIFT 8
+#define HT_CAP_DELAYED_BA 0x0400
+#define HT_CAP_MAX_AMSDU 0x0800
+#define HT_CAP_DSSS_CCK 0x1000
+#define HT_CAP_PSMP 0x2000
+#define HT_CAP_40MHZ_INTOLERANT 0x4000
+#define HT_CAP_LSIG_TXOP 0x8000
+
+#define HT_CAP_RX_STBC_NO 0x0
+#define HT_CAP_RX_STBC_ONE_STREAM 0x1
+#define HT_CAP_RX_STBC_TWO_STREAM 0x2
+#define HT_CAP_RX_STBC_THREE_STREAM 0x3
+
+#define HT_MAX_AMSDU 7935
+#define HT_MIN_AMSDU 3835
+
+#define HT_PARAMS_RX_FACTOR_MASK 0x03
+#define HT_PARAMS_DENSITY_MASK 0x1C
+#define HT_PARAMS_DENSITY_SHIFT 2
+
+#define AMPDU_MAX_MPDU_DENSITY 7
+#define AMPDU_RX_FACTOR_8K 0
+#define AMPDU_RX_FACTOR_16K 1
+#define AMPDU_RX_FACTOR_32K 2
+#define AMPDU_RX_FACTOR_64K 3
+#define AMPDU_RX_FACTOR_BASE (8*1024)
+
+#define AMPDU_DELIMITER_LEN 4
+
+BWL_PRE_PACKED_STRUCT struct ht_add_ie {
+ uint8 ctl_ch;
+ uint8 byte1;
+ uint16 opmode;
+ uint16 misc_bits;
+ uint8 basic_mcs[MCSSET_LEN];
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_add_ie ht_add_ie_t;
+
+#define HT_ADD_IE_LEN 22
+#define HT_ADD_IE_TYPE 52
+
+#define HT_BW_ANY 0x04
+#define HT_RIFS_PERMITTED 0x08
+
+#define HT_OPMODE_MASK 0x0003
+#define HT_OPMODE_SHIFT 0
+#define HT_OPMODE_PURE 0x0000
+#define HT_OPMODE_OPTIONAL 0x0001
+#define HT_OPMODE_HT20IN40 0x0002
+#define HT_OPMODE_MIXED 0x0003
+#define HT_OPMODE_NONGF 0x0004
+#define DOT11N_TXBURST 0x0008
+#define DOT11N_OBSS_NONHT 0x0010
+
+#define HT_BASIC_STBC_MCS 0x007f
+#define HT_DUAL_STBC_PROT 0x0080
+#define HT_SECOND_BCN 0x0100
+#define HT_LSIG_TXOP 0x0200
+#define HT_PCO_ACTIVE 0x0400
+#define HT_PCO_PHASE 0x0800
+
+#define DOT11N_2G_TXBURST_LIMIT 6160
+#define DOT11N_5G_TXBURST_LIMIT 3080
+
+#define GET_HT_OPMODE(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) >> HT_OPMODE_SHIFT)
+#define HT_MIXEDMODE_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) == HT_OPMODE_MIXED)
+#define HT_HT20_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) == HT_OPMODE_HT20IN40)
+#define HT_OPTIONAL_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) == HT_OPMODE_OPTIONAL)
+#define HT_USE_PROTECTION(add_ie) \
+ (HT_HT20_PRESENT((add_ie)) || HT_MIXEDMODE_PRESENT((add_ie)))
+#define HT_NONGF_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) == HT_OPMODE_NONGF)
+#define DOT11N_TXBURST_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) == DOT11N_TXBURST)
+#define DOT11N_OBSS_NONHT_PRESENT(add_ie) \
+ ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) == DOT11N_OBSS_NONHT)
+
+BWL_PRE_PACKED_STRUCT struct obss_params {
+ uint16 passive_dwell;
+ uint16 active_dwell;
+ uint16 bss_widthscan_interval;
+ uint16 passive_total;
+ uint16 active_total;
+ uint16 chanwidth_transition_dly;
+ uint16 activity_threshold;
+} BWL_POST_PACKED_STRUCT;
+typedef struct obss_params obss_params_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_ie {
+ uint8 id;
+ uint8 len;
+ obss_params_t obss_params;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_ie dot11_obss_ie_t;
+#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t)
+
+#define HT_CTRL_LA_TRQ 0x00000002
+#define HT_CTRL_LA_MAI 0x0000003C
+#define HT_CTRL_LA_MAI_SHIFT 2
+#define HT_CTRL_LA_MAI_MRQ 0x00000004
+#define HT_CTRL_LA_MAI_MSI 0x00000038
+#define HT_CTRL_LA_MFSI 0x000001C0
+#define HT_CTRL_LA_MFSI_SHIFT 6
+#define HT_CTRL_LA_MFB_ASELC 0x0000FE00
+#define HT_CTRL_LA_MFB_ASELC_SH 9
+#define HT_CTRL_LA_ASELC_CMD 0x00000C00
+#define HT_CTRL_LA_ASELC_DATA 0x0000F000
+#define HT_CTRL_CAL_POS 0x00030000
+#define HT_CTRL_CAL_SEQ 0x000C0000
+#define HT_CTRL_CSI_STEERING 0x00C00000
+#define HT_CTRL_CSI_STEER_SHIFT 22
+#define HT_CTRL_CSI_STEER_NFB 0
+#define HT_CTRL_CSI_STEER_CSI 1
+#define HT_CTRL_CSI_STEER_NCOM 2
+#define HT_CTRL_CSI_STEER_COM 3
+#define HT_CTRL_NDP_ANNOUNCE 0x01000000
+#define HT_CTRL_AC_CONSTRAINT 0x40000000
+#define HT_CTRL_RDG_MOREPPDU 0x80000000
+
+#define HT_OPMODE_OPTIONAL 0x0001
+#define HT_OPMODE_HT20IN40 0x0002
+#define HT_OPMODE_MIXED 0x0003
+#define HT_OPMODE_NONGF 0x0004
+#define DOT11N_TXBURST 0x0008
+#define DOT11N_OBSS_NONHT 0x0010
+
+#define WPA_VERSION 1
+#define WPA_OUI "\x00\x50\xF2"
+
+#define WPA2_VERSION 1
+#define WPA2_VERSION_LEN 2
+#define WPA2_OUI "\x00\x0F\xAC"
+
+#define WPA_OUI_LEN 3
+
+#define WFA_OUI "\x00\x50\xF2"
+#define WFA_OUI_LEN 3
+
+#define WFA_OUI_TYPE_WPA 1
+#define WFA_OUI_TYPE_WPS 4
+#define WFA_OUI_TYPE_P2P 9
+
+#define RSN_AKM_NONE 0
+#define RSN_AKM_UNSPECIFIED 1
+#define RSN_AKM_PSK 2
+
+#define DOT11_MAX_DEFAULT_KEYS 4
+#define DOT11_MAX_KEY_SIZE 32
+#define DOT11_MAX_IV_SIZE 16
+#define DOT11_EXT_IV_FLAG (1<<5)
+#define DOT11_WPA_KEY_RSC_LEN 8
+
+#define WEP1_KEY_SIZE 5
+#define WEP1_KEY_HEX_SIZE 10
+#define WEP128_KEY_SIZE 13
+#define WEP128_KEY_HEX_SIZE 26
+#define TKIP_MIC_SIZE 8
+#define TKIP_EOM_SIZE 7
+#define TKIP_EOM_FLAG 0x5a
+#define TKIP_KEY_SIZE 32
+#define TKIP_MIC_AUTH_TX 16
+#define TKIP_MIC_AUTH_RX 24
+#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX
+#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX
+#define AES_KEY_SIZE 16
+#define AES_MIC_SIZE 8
+
+#define WCN_OUI "\x00\x50\xf2"
+#define WCN_TYPE 4
+
+#include <packed_section_end.h>
+
+#endif /* _802_11_H_ */
diff --git a/drivers/staging/brcm80211/include/proto/802.11e.h b/drivers/staging/brcm80211/include/proto/802.11e.h
new file mode 100644
index 000000000000..f331e6d6413a
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/802.11e.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _802_11e_H_
+#define _802_11e_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#include <packed_section_start.h>
+
+#define WME_TSPEC_HDR_LEN 2
+#define WME_TSPEC_BODY_OFF 2
+
+#define WME_CATEGORY_CODE_OFFSET 0
+#define WME_ACTION_CODE_OFFSET 1
+#define WME_TOKEN_CODE_OFFSET 2
+#define WME_STATUS_CODE_OFFSET 3
+
+BWL_PRE_PACKED_STRUCT struct tsinfo {
+ uint8 octets[3];
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct tsinfo tsinfo_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct tspec {
+ uint8 oui[DOT11_OUI_LEN];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ tsinfo_t tsinfo;
+ uint16 nom_msdu_size;
+ uint16 max_msdu_size;
+ uint32 min_srv_interval;
+ uint32 max_srv_interval;
+ uint32 inactivity_interval;
+ uint32 suspension_interval;
+ uint32 srv_start_time;
+ uint32 min_data_rate;
+ uint32 mean_data_rate;
+ uint32 peak_data_rate;
+ uint32 max_burst_size;
+ uint32 delay_bound;
+ uint32 min_phy_rate;
+ uint16 surplus_bw;
+ uint16 medium_time;
+} BWL_POST_PACKED_STRUCT tspec_t;
+
+#define WME_TSPEC_LEN (sizeof(tspec_t))
+
+#define TS_INFO_TID_SHIFT 1
+#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT)
+#define TS_INFO_CONTENTION_SHIFT 7
+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT)
+#define TS_INFO_DIRECTION_SHIFT 5
+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_PSB_SHIFT 2
+#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT)
+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT)
+#define TS_INFO_USER_PRIO_SHIFT 3
+#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT)
+
+#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & \
+ TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT)
+#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \
+ TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT)
+#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & \
+ TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT)
+#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \
+ TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT)
+
+#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \
+ ((id) << TS_INFO_TID_SHIFT))
+#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & \
+ (~TS_INFO_USER_PRIO_MASK)) | ((prio) << TS_INFO_USER_PRIO_SHIFT))
+
+#define QBSS_LOAD_IE_LEN 5
+#define QBSS_LOAD_AAC_OFF 3
+
+#define CAC_ADDTS_RESP_TIMEOUT 300
+
+#define DOT11E_STATUS_ADMISSION_ACCEPTED 0
+#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1
+#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3
+#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47
+
+#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36
+#define DOT11E_STATUS_END_TS 37
+#define DOT11E_STATUS_UNKNOWN_TS 38
+#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39
+
+#include <packed_section_end.h>
+
+#endif /* _802_11e_H_ */
diff --git a/drivers/staging/brcm80211/include/proto/802.1d.h b/drivers/staging/brcm80211/include/proto/802.1d.h
new file mode 100644
index 000000000000..9802d8776628
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/802.1d.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _802_1_D_
+#define _802_1_D_
+
+#define PRIO_8021D_NONE 2
+#define PRIO_8021D_BK 1
+#define PRIO_8021D_BE 0
+#define PRIO_8021D_EE 3
+#define PRIO_8021D_CL 4
+#define PRIO_8021D_VI 5
+#define PRIO_8021D_VO 6
+#define PRIO_8021D_NC 7
+#define MAXPRIO 7
+#define NUMPRIO (MAXPRIO + 1)
+
+#define ALLPRIO -1
+
+#define PRIO2PREC(prio) \
+ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \
+ ((prio^2)) : (prio))
+
+#endif /* _802_1_D_ */
diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h
new file mode 100644
index 000000000000..37257f9727cb
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/bcmevent.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCMEVENT_H_
+#define _BCMEVENT_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#include <packed_section_start.h>
+
+#define BCM_EVENT_MSG_VERSION 1
+#define BCM_MSG_IFNAME_MAX 16
+
+#define WLC_EVENT_MSG_LINK 0x01
+#define WLC_EVENT_MSG_FLUSHTXQ 0x02
+#define WLC_EVENT_MSG_GROUP 0x04
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint16 version;
+ uint16 flags;
+ uint32 event_type;
+ uint32 status;
+ uint32 reason;
+ uint32 auth_type;
+ uint32 datalen;
+ struct ether_addr addr;
+ char ifname[BCM_MSG_IFNAME_MAX];
+} BWL_POST_PACKED_STRUCT wl_event_msg_t;
+
+#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - \
+ sizeof(struct ether_header))
+
+#define WLC_E_SET_SSID 0
+#define WLC_E_JOIN 1
+#define WLC_E_START 2
+#define WLC_E_AUTH 3
+#define WLC_E_AUTH_IND 4
+#define WLC_E_DEAUTH 5
+#define WLC_E_DEAUTH_IND 6
+#define WLC_E_ASSOC 7
+#define WLC_E_ASSOC_IND 8
+#define WLC_E_REASSOC 9
+#define WLC_E_REASSOC_IND 10
+#define WLC_E_DISASSOC 11
+#define WLC_E_DISASSOC_IND 12
+#define WLC_E_QUIET_START 13
+#define WLC_E_QUIET_END 14
+#define WLC_E_BEACON_RX 15
+#define WLC_E_LINK 16
+#define WLC_E_MIC_ERROR 17
+#define WLC_E_NDIS_LINK 18
+#define WLC_E_ROAM 19
+#define WLC_E_TXFAIL 20
+#define WLC_E_PMKID_CACHE 21
+#define WLC_E_RETROGRADE_TSF 22
+#define WLC_E_PRUNE 23
+#define WLC_E_AUTOAUTH 24
+#define WLC_E_EAPOL_MSG 25
+#define WLC_E_SCAN_COMPLETE 26
+#define WLC_E_ADDTS_IND 27
+#define WLC_E_DELTS_IND 28
+#define WLC_E_BCNSENT_IND 29
+#define WLC_E_BCNRX_MSG 30
+#define WLC_E_BCNLOST_MSG 31
+#define WLC_E_ROAM_PREP 32
+#define WLC_E_PFN_NET_FOUND 33
+#define WLC_E_PFN_NET_LOST 34
+#define WLC_E_RESET_COMPLETE 35
+#define WLC_E_JOIN_START 36
+#define WLC_E_ROAM_START 37
+#define WLC_E_ASSOC_START 38
+#define WLC_E_IBSS_ASSOC 39
+#define WLC_E_RADIO 40
+#define WLC_E_PSM_WATCHDOG 41
+#define WLC_E_PROBREQ_MSG 44
+#define WLC_E_SCAN_CONFIRM_IND 45
+#define WLC_E_PSK_SUP 46
+#define WLC_E_COUNTRY_CODE_CHANGED 47
+#define WLC_E_EXCEEDED_MEDIUM_TIME 48
+#define WLC_E_ICV_ERROR 49
+#define WLC_E_UNICAST_DECODE_ERROR 50
+#define WLC_E_MULTICAST_DECODE_ERROR 51
+#define WLC_E_TRACE 52
+#define WLC_E_IF 54
+#define WLC_E_RSSI 56
+#define WLC_E_PFN_SCAN_COMPLETE 57
+#define WLC_E_EXTLOG_MSG 58
+#define WLC_E_ACTION_FRAME 59
+#define WLC_E_ACTION_FRAME_COMPLETE 60
+#define WLC_E_PRE_ASSOC_IND 61
+#define WLC_E_PRE_REASSOC_IND 62
+#define WLC_E_CHANNEL_ADOPTED 63
+#define WLC_E_AP_STARTED 64
+#define WLC_E_DFS_AP_STOP 65
+#define WLC_E_DFS_AP_RESUME 66
+#define WLC_E_RESERVED1 67
+#define WLC_E_RESERVED2 68
+#define WLC_E_ESCAN_RESULT 69
+#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
+#define WLC_E_DCS_REQUEST 73
+
+#define WLC_E_FIFO_CREDIT_MAP 74
+
+#define WLC_E_LAST 75
+
+typedef struct {
+ uint event;
+ const char *name;
+} bcmevent_name_t;
+
+extern const bcmevent_name_t bcmevent_names[];
+extern const int bcmevent_names_size;
+
+#define WLC_E_STATUS_SUCCESS 0
+#define WLC_E_STATUS_FAIL 1
+#define WLC_E_STATUS_TIMEOUT 2
+#define WLC_E_STATUS_NO_NETWORKS 3
+#define WLC_E_STATUS_ABORT 4
+#define WLC_E_STATUS_NO_ACK 5
+#define WLC_E_STATUS_UNSOLICITED 6
+#define WLC_E_STATUS_ATTEMPT 7
+#define WLC_E_STATUS_PARTIAL 8
+#define WLC_E_STATUS_NEWSCAN 9
+#define WLC_E_STATUS_NEWASSOC 10
+#define WLC_E_STATUS_11HQUIET 11
+#define WLC_E_STATUS_SUPPRESS 12
+#define WLC_E_STATUS_NOCHANS 13
+#define WLC_E_STATUS_CS_ABORT 15
+#define WLC_E_STATUS_ERROR 16
+
+#define WLC_E_REASON_INITIAL_ASSOC 0
+#define WLC_E_REASON_LOW_RSSI 1
+#define WLC_E_REASON_DEAUTH 2
+#define WLC_E_REASON_DISASSOC 3
+#define WLC_E_REASON_BCNS_LOST 4
+#define WLC_E_REASON_MINTXRATE 9
+#define WLC_E_REASON_TXFAIL 10
+
+#define WLC_E_REASON_FAST_ROAM_FAILED 5
+#define WLC_E_REASON_DIRECTED_ROAM 6
+#define WLC_E_REASON_TSPEC_REJECTED 7
+#define WLC_E_REASON_BETTER_AP 8
+
+#define WLC_E_PRUNE_ENCR_MISMATCH 1
+#define WLC_E_PRUNE_BCAST_BSSID 2
+#define WLC_E_PRUNE_MAC_DENY 3
+#define WLC_E_PRUNE_MAC_NA 4
+#define WLC_E_PRUNE_REG_PASSV 5
+#define WLC_E_PRUNE_SPCT_MGMT 6
+#define WLC_E_PRUNE_RADAR 7
+#define WLC_E_RSN_MISMATCH 8
+#define WLC_E_PRUNE_NO_COMMON_RATES 9
+#define WLC_E_PRUNE_BASIC_RATES 10
+#define WLC_E_PRUNE_CIPHER_NA 12
+#define WLC_E_PRUNE_KNOWN_STA 13
+#define WLC_E_PRUNE_WDS_PEER 15
+#define WLC_E_PRUNE_QBSS_LOAD 16
+#define WLC_E_PRUNE_HOME_AP 17
+
+#define WLC_E_SUP_OTHER 0
+#define WLC_E_SUP_DECRYPT_KEY_DATA 1
+#define WLC_E_SUP_BAD_UCAST_WEP128 2
+#define WLC_E_SUP_BAD_UCAST_WEP40 3
+#define WLC_E_SUP_UNSUP_KEY_LEN 4
+#define WLC_E_SUP_PW_KEY_CIPHER 5
+#define WLC_E_SUP_MSG3_TOO_MANY_IE 6
+#define WLC_E_SUP_MSG3_IE_MISMATCH 7
+#define WLC_E_SUP_NO_INSTALL_FLAG 8
+#define WLC_E_SUP_MSG3_NO_GTK 9
+#define WLC_E_SUP_GRP_KEY_CIPHER 10
+#define WLC_E_SUP_GRP_MSG1_NO_GTK 11
+#define WLC_E_SUP_GTK_DECRYPT_FAIL 12
+#define WLC_E_SUP_SEND_FAIL 13
+#define WLC_E_SUP_DEAUTH 14
+
+typedef struct wl_event_data_if {
+ uint8 ifidx;
+ uint8 opcode;
+ uint8 reserved;
+ uint8 bssidx;
+ uint8 role;
+} wl_event_data_if_t;
+
+#define WLC_E_IF_ADD 1
+#define WLC_E_IF_DEL 2
+#define WLC_E_IF_CHANGE 3
+
+#define WLC_E_IF_ROLE_STA 0
+#define WLC_E_IF_ROLE_AP 1
+#define WLC_E_IF_ROLE_WDS 2
+
+#define WLC_E_LINK_BCN_LOSS 1
+#define WLC_E_LINK_DISASSOC 2
+#define WLC_E_LINK_ASSOC_REC 3
+#define WLC_E_LINK_BSSCFG_DIS 4
+
+#include <packed_section_end.h>
+
+#endif /* _BCMEVENT_H_ */
diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h
new file mode 100644
index 000000000000..9ce8de8cd44c
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/ethernet.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _NET_ETHERNET_H_
+#define _NET_ETHERNET_H_
+
+#ifndef _TYPEDEFS_H_
+#include "typedefs.h"
+#endif
+#include <packed_section_start.h>
+
+#define ETHER_ADDR_LEN 6
+#define ETHER_TYPE_LEN 2
+#define ETHER_CRC_LEN 4
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
+#define ETHER_MIN_LEN 64
+#define ETHER_MIN_DATA 46
+#define ETHER_MAX_LEN 1518
+#define ETHER_MAX_DATA 1500
+
+#define ETHER_TYPE_MIN 0x0600
+#define ETHER_TYPE_IP 0x0800
+#define ETHER_TYPE_ARP 0x0806
+#define ETHER_TYPE_8021Q 0x8100
+#define ETHER_TYPE_BRCM 0x886c
+#define ETHER_TYPE_802_1X 0x888e
+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7
+
+#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN)
+#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN)
+#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN)
+
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \
+ ((uint8 *)ea)[0] = 0x01; \
+ ((uint8 *)ea)[1] = 0x00; \
+ ((uint8 *)ea)[2] = 0x5e; \
+ ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \
+ ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \
+ ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \
+}
+
+BWL_PRE_PACKED_STRUCT struct ether_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 ether_type;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct ether_addr {
+ uint8 octet[ETHER_ADDR_LEN];
+} BWL_POST_PACKED_STRUCT;
+
+#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2))
+#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2)
+#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = \
+ (((uint8 *)(ea))[0] & 0xd))
+#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = \
+ (((uint8 *)(ea))[0] ^ 2))
+
+#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1))
+
+#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1)
+
+#define ether_cmp(a, b) (!(((short *)a)[0] == ((short *)b)[0]) | \
+ !(((short *)a)[1] == ((short *)b)[1]) | \
+ !(((short *)a)[2] == ((short *)b)[2]))
+
+#define ether_copy(s, d) { \
+ ((short *)d)[0] = ((short *)s)[0]; \
+ ((short *)d)[1] = ((short *)s)[1]; \
+ ((short *)d)[2] = ((short *)s)[2]; }
+
+static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} };
+static const struct ether_addr ether_null = { {0, 0, 0, 0, 0, 0} };
+
+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \
+ ((uint8 *)(ea))[1] & \
+ ((uint8 *)(ea))[2] & \
+ ((uint8 *)(ea))[3] & \
+ ((uint8 *)(ea))[4] & \
+ ((uint8 *)(ea))[5]) == 0xff)
+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \
+ ((uint8 *)(ea))[1] | \
+ ((uint8 *)(ea))[2] | \
+ ((uint8 *)(ea))[3] | \
+ ((uint8 *)(ea))[4] | \
+ ((uint8 *)(ea))[5]) == 0)
+
+#define ETHER_MOVE_HDR(d, s) \
+do { \
+ struct ether_header t; \
+ t = *(struct ether_header *)(s); \
+ *(struct ether_header *)(d) = t; \
+} while (0)
+
+#include <packed_section_end.h>
+
+#endif /* _NET_ETHERNET_H_ */
diff --git a/drivers/staging/brcm80211/include/proto/wpa.h b/drivers/staging/brcm80211/include/proto/wpa.h
new file mode 100644
index 000000000000..7512e1a1cd9c
--- /dev/null
+++ b/drivers/staging/brcm80211/include/proto/wpa.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _proto_wpa_h_
+#define _proto_wpa_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+
+#include <packed_section_start.h>
+
+#define DOT11_RC_INVALID_WPA_IE 13
+#define DOT11_RC_MIC_FAILURE 14
+#define DOT11_RC_4WH_TIMEOUT 15
+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16
+#define DOT11_RC_WPA_IE_MISMATCH 17
+#define DOT11_RC_INVALID_MC_CIPHER 18
+#define DOT11_RC_INVALID_UC_CIPHER 19
+#define DOT11_RC_INVALID_AKMP 20
+#define DOT11_RC_BAD_WPA_VERSION 21
+#define DOT11_RC_INVALID_WPA_CAP 22
+#define DOT11_RC_8021X_AUTH_FAIL 23
+
+#define WPA2_PMKID_LEN 16
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 tag;
+ uint8 length;
+ uint8 oui[3];
+ uint8 oui_type;
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT version;
+} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t;
+#define WPA_IE_OUITYPE_LEN 4
+#define WPA_IE_FIXED_LEN 8
+#define WPA_IE_TAG_FIXED_LEN 6
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 tag;
+ uint8 length;
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT version;
+} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t;
+#define WPA_RSN_IE_FIXED_LEN 4
+#define WPA_RSN_IE_TAG_FIXED_LEN 2
+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN];
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 oui[3];
+ uint8 type;
+} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t;
+#define WPA_SUITE_LEN 4
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT count;
+ wpa_suite_t list[1];
+} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t;
+#define WPA_IE_SUITE_COUNT_LEN 2
+typedef BWL_PRE_PACKED_STRUCT struct {
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT count;
+ wpa_pmkid_t list[1];
+} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t;
+
+#define WPA_CIPHER_NONE 0
+#define WPA_CIPHER_WEP_40 1
+#define WPA_CIPHER_TKIP 2
+#define WPA_CIPHER_AES_OCB 3
+#define WPA_CIPHER_AES_CCM 4
+#define WPA_CIPHER_WEP_104 5
+
+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \
+ (cipher) == WPA_CIPHER_WEP_40 || \
+ (cipher) == WPA_CIPHER_WEP_104 || \
+ (cipher) == WPA_CIPHER_TKIP || \
+ (cipher) == WPA_CIPHER_AES_OCB || \
+ (cipher) == WPA_CIPHER_AES_CCM)
+
+#define WPA_TKIP_CM_DETECT 60
+#define WPA_TKIP_CM_BLOCK 60
+
+#define RSN_CAP_LEN 2
+
+#define RSN_CAP_PREAUTH 0x0001
+#define RSN_CAP_NOPAIRWISE 0x0002
+#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
+#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2
+#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030
+#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4
+#define RSN_CAP_1_REPLAY_CNTR 0
+#define RSN_CAP_2_REPLAY_CNTRS 1
+#define RSN_CAP_4_REPLAY_CNTRS 2
+#define RSN_CAP_16_REPLAY_CNTRS 3
+
+#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS
+#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS
+#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT
+#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK
+
+#define WPA_CAP_LEN RSN_CAP_LEN
+
+#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH
+
+#include <packed_section_end.h>
+
+#endif /* _proto_wpa_h_ */
diff --git a/drivers/staging/brcm80211/include/qmath.h b/drivers/staging/brcm80211/include/qmath.h
new file mode 100644
index 000000000000..ec43121c8eb8
--- /dev/null
+++ b/drivers/staging/brcm80211/include/qmath.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 __QMATH_H__
+#define __QMATH_H__
+
+#include <typedefs.h>
+
+int16 qm_sat32(int32 op);
+
+int32 qm_mul321616(int16 op1, int16 op2);
+
+int16 qm_mul16(int16 op1, int16 op2);
+
+int32 qm_muls321616(int16 op1, int16 op2);
+
+uint16 qm_mulu16(uint16 op1, uint16 op2);
+
+int16 qm_muls16(int16 op1, int16 op2);
+
+int32 qm_add32(int32 op1, int32 op2);
+
+int16 qm_add16(int16 op1, int16 op2);
+
+int16 qm_sub16(int16 op1, int16 op2);
+
+int32 qm_sub32(int32 op1, int32 op2);
+
+int32 qm_mac321616(int32 acc, int16 op1, int16 op2);
+
+int32 qm_shl32(int32 op, int shift);
+
+int32 qm_shr32(int32 op, int shift);
+
+int16 qm_shl16(int16 op, int shift);
+
+int16 qm_shr16(int16 op, int shift);
+
+int16 qm_norm16(int16 op);
+
+int16 qm_norm32(int32 op);
+
+int16 qm_div_s(int16 num, int16 denom);
+
+int16 qm_abs16(int16 op);
+
+int16 qm_div16(int16 num, int16 denom, int16 *qQuotient);
+
+int32 qm_abs32(int32 op);
+
+int16 qm_div163232(int32 num, int32 denom, int16 *qquotient);
+
+int32 qm_mul323216(int32 op1, int16 op2);
+
+int32 qm_mulsu321616(int16 op1, uint16 op2);
+
+int32 qm_muls323216(int32 op1, int16 op2);
+
+int32 qm_mul32(int32 a, int32 b);
+
+int32 qm_muls32(int32 a, int32 b);
+
+void qm_log10(int32 N, int16 qN, int16 *log10N, int16 *qLog10N);
+
+void qm_1byN(int32 N, int16 qN, int32 *result, int16 *qResult);
+
+#endif /* #ifndef __QMATH_H__ */
diff --git a/drivers/staging/brcm80211/include/rpc_osl.h b/drivers/staging/brcm80211/include/rpc_osl.h
new file mode 100644
index 000000000000..4a2648001bf0
--- /dev/null
+++ b/drivers/staging/brcm80211/include/rpc_osl.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _rpcosl_h_
+#define _rpcosl_h_
+
+typedef struct rpc_osl rpc_osl_t;
+extern rpc_osl_t *rpc_osl_attach(osl_t *osh);
+extern void rpc_osl_detach(rpc_osl_t *rpc_osh);
+
+#define RPC_OSL_LOCK(rpc_osh) rpc_osl_lock((rpc_osh))
+#define RPC_OSL_UNLOCK(rpc_osh) rpc_osl_unlock((rpc_osh))
+#define RPC_OSL_WAIT(rpc_osh, to, ptimedout) rpc_osl_wait((rpc_osh), (to), (ptimedout))
+#define RPC_OSL_WAKE(rpc_osh) rpc_osl_wake((rpc_osh))
+extern void rpc_osl_lock(rpc_osl_t *rpc_osh);
+extern void rpc_osl_unlock(rpc_osl_t *rpc_osh);
+extern int rpc_osl_wait(rpc_osl_t *rpc_osh, uint ms, bool *ptimedout);
+extern void rpc_osl_wake(rpc_osl_t *rpc_osh);
+
+#endif /* _rpcosl_h_ */
diff --git a/drivers/staging/brcm80211/include/sbchipc.h b/drivers/staging/brcm80211/include/sbchipc.h
new file mode 100644
index 000000000000..7fada3f68002
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbchipc.h
@@ -0,0 +1,1588 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SBCHIPC_H
+#define _SBCHIPC_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+typedef volatile struct {
+ uint32 chipid; /* 0x0 */
+ uint32 capabilities;
+ uint32 corecontrol; /* corerev >= 1 */
+ uint32 bist;
+
+ /* OTP */
+ uint32 otpstatus; /* 0x10, corerev >= 10 */
+ uint32 otpcontrol;
+ uint32 otpprog;
+ uint32 otplayout; /* corerev >= 23 */
+
+ /* Interrupt control */
+ uint32 intstatus; /* 0x20 */
+ uint32 intmask;
+
+ /* Chip specific regs */
+ uint32 chipcontrol; /* 0x28, rev >= 11 */
+ uint32 chipstatus; /* 0x2c, rev >= 11 */
+
+ /* Jtag Master */
+ uint32 jtagcmd; /* 0x30, rev >= 10 */
+ uint32 jtagir;
+ uint32 jtagdr;
+ uint32 jtagctrl;
+
+ /* serial flash interface registers */
+ uint32 flashcontrol; /* 0x40 */
+ uint32 flashaddress;
+ uint32 flashdata;
+ uint32 PAD[1];
+
+ /* Silicon backplane configuration broadcast control */
+ uint32 broadcastaddress; /* 0x50 */
+ uint32 broadcastdata;
+
+ /* gpio - cleared only by power-on-reset */
+ uint32 gpiopullup; /* 0x58, corerev >= 20 */
+ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */
+ uint32 gpioin; /* 0x60 */
+ uint32 gpioout; /* 0x64 */
+ uint32 gpioouten; /* 0x68 */
+ uint32 gpiocontrol; /* 0x6C */
+ uint32 gpiointpolarity; /* 0x70 */
+ uint32 gpiointmask; /* 0x74 */
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioevent;
+ uint32 gpioeventintmask;
+
+ /* Watchdog timer */
+ uint32 watchdog; /* 0x80 */
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioeventintpolarity;
+
+ /* GPIO based LED powersave registers corerev >= 16 */
+ uint32 gpiotimerval; /* 0x88 */
+ uint32 gpiotimeroutmask;
+
+ /* clock control */
+ uint32 clockcontrol_n; /* 0x90 */
+ uint32 clockcontrol_sb; /* aka m0 */
+ uint32 clockcontrol_pci; /* aka m1 */
+ uint32 clockcontrol_m2; /* mii/uart/mipsref */
+ uint32 clockcontrol_m3; /* cpu */
+ uint32 clkdiv; /* corerev >= 3 */
+ uint32 gpiodebugsel; /* corerev >= 28 */
+ uint32 capabilities_ext; /* 0xac */
+
+ /* pll delay registers (corerev >= 4) */
+ uint32 pll_on_delay; /* 0xb0 */
+ uint32 fref_sel_delay;
+ uint32 slow_clk_ctl; /* 5 < corerev < 10 */
+ uint32 PAD;
+
+ /* Instaclock registers (corerev >= 10) */
+ uint32 system_clk_ctl; /* 0xc0 */
+ uint32 clkstatestretch;
+ uint32 PAD[2];
+
+ /* Indirect backplane access (corerev >= 22) */
+ uint32 bp_addrlow; /* 0xd0 */
+ uint32 bp_addrhigh;
+ uint32 bp_data;
+ uint32 PAD;
+ uint32 bp_indaccess;
+ uint32 PAD[3];
+
+ /* More clock dividers (corerev >= 32) */
+ uint32 clkdiv2;
+ uint32 PAD[2];
+
+ /* In AI chips, pointer to erom */
+ uint32 eromptr; /* 0xfc */
+
+ /* ExtBus control registers (corerev >= 3) */
+ uint32 pcmcia_config; /* 0x100 */
+ uint32 pcmcia_memwait;
+ uint32 pcmcia_attrwait;
+ uint32 pcmcia_iowait;
+ uint32 ide_config;
+ uint32 ide_memwait;
+ uint32 ide_attrwait;
+ uint32 ide_iowait;
+ uint32 prog_config;
+ uint32 prog_waitcount;
+ uint32 flash_config;
+ uint32 flash_waitcount;
+ uint32 SECI_config; /* 0x130 SECI configuration */
+ uint32 PAD[3];
+
+ /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
+ uint32 eci_output; /* 0x140 */
+ uint32 eci_control;
+ uint32 eci_inputlo;
+ uint32 eci_inputmi;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolaritymi;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskmi;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventmi;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskmi;
+ uint32 eci_eventmaskhi;
+ uint32 PAD[3];
+
+ /* SROM interface (corerev >= 32) */
+ uint32 sromcontrol; /* 0x190 */
+ uint32 sromaddress;
+ uint32 sromdata;
+ uint32 PAD[17];
+
+ /* Clock control and hardware workarounds (corerev >= 20) */
+ uint32 clk_ctl_st; /* 0x1e0 */
+ uint32 hw_war;
+ uint32 PAD[70];
+
+ /* UARTs */
+ uint8 uart0data; /* 0x300 */
+ uint8 uart0imr;
+ uint8 uart0fcr;
+ uint8 uart0lcr;
+ uint8 uart0mcr;
+ uint8 uart0lsr;
+ uint8 uart0msr;
+ uint8 uart0scratch;
+ uint8 PAD[248]; /* corerev >= 1 */
+
+ uint8 uart1data; /* 0x400 */
+ uint8 uart1imr;
+ uint8 uart1fcr;
+ uint8 uart1lcr;
+ uint8 uart1mcr;
+ uint8 uart1lsr;
+ uint8 uart1msr;
+ uint8 uart1scratch;
+ uint32 PAD[126];
+
+ /* PMU registers (corerev >= 20) */
+ uint32 pmucontrol; /* 0x600 */
+ uint32 pmucapabilities;
+ uint32 pmustatus;
+ uint32 res_state;
+ uint32 res_pending;
+ uint32 pmutimer;
+ uint32 min_res_mask;
+ uint32 max_res_mask;
+ uint32 res_table_sel;
+ uint32 res_dep_mask;
+ uint32 res_updn_timer;
+ uint32 res_timer;
+ uint32 clkstretch;
+ uint32 pmuwatchdog;
+ uint32 gpiosel; /* 0x638, rev >= 1 */
+ uint32 gpioenable; /* 0x63c, rev >= 1 */
+ uint32 res_req_timer_sel;
+ uint32 res_req_timer;
+ uint32 res_req_mask;
+ uint32 PAD;
+ uint32 chipcontrol_addr; /* 0x650 */
+ uint32 chipcontrol_data; /* 0x654 */
+ uint32 regcontrol_addr;
+ uint32 regcontrol_data;
+ uint32 pllcontrol_addr;
+ uint32 pllcontrol_data;
+ uint32 pmustrapopt; /* 0x668, corerev >= 28 */
+ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */
+ uint32 PAD[100];
+ uint16 sromotp[768];
+} chipcregs_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#if defined(IL_BIGENDIAN) && defined(BCMHND74K)
+/* Selective swapped defines for those registers we need in
+ * big-endian code.
+ */
+#define CC_CHIPID 4
+#define CC_CAPABILITIES 0
+#define CC_CHIPST 0x28
+#define CC_EROMPTR 0xf8
+
+#else /* !IL_BIGENDIAN || !BCMHND74K */
+
+#define CC_CHIPID 0
+#define CC_CAPABILITIES 4
+#define CC_CHIPST 0x2c
+#define CC_EROMPTR 0xfc
+
+#endif /* IL_BIGENDIAN && BCMHND74K */
+
+#define CC_OTPST 0x10
+#define CC_JTAGCMD 0x30
+#define CC_JTAGIR 0x34
+#define CC_JTAGDR 0x38
+#define CC_JTAGCTRL 0x3c
+#define CC_GPIOPU 0x58
+#define CC_GPIOPD 0x5c
+#define CC_GPIOIN 0x60
+#define CC_GPIOOUT 0x64
+#define CC_GPIOOUTEN 0x68
+#define CC_GPIOCTRL 0x6c
+#define CC_GPIOPOL 0x70
+#define CC_GPIOINTM 0x74
+#define CC_WATCHDOG 0x80
+#define CC_CLKC_N 0x90
+#define CC_CLKC_M0 0x94
+#define CC_CLKC_M1 0x98
+#define CC_CLKC_M2 0x9c
+#define CC_CLKC_M3 0xa0
+#define CC_CLKDIV 0xa4
+#define CC_SYS_CLK_CTL 0xc0
+#define CC_CLK_CTL_ST SI_CLK_CTL_ST
+#define PMU_CTL 0x600
+#define PMU_CAP 0x604
+#define PMU_ST 0x608
+#define PMU_RES_STATE 0x60c
+#define PMU_TIMER 0x614
+#define PMU_MIN_RES_MASK 0x618
+#define PMU_MAX_RES_MASK 0x61c
+#define CC_CHIPCTL_ADDR 0x650
+#define CC_CHIPCTL_DATA 0x654
+#define PMU_REG_CONTROL_ADDR 0x658
+#define PMU_REG_CONTROL_DATA 0x65C
+#define PMU_PLL_CONTROL_ADDR 0x660
+#define PMU_PLL_CONTROL_DATA 0x664
+#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
+
+/* chipid */
+#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
+#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
+#define CID_REV_SHIFT 16 /* Chip Revision shift */
+#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
+#define CID_PKG_SHIFT 20 /* Package Option shift */
+#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
+#define CID_CC_SHIFT 24
+#define CID_TYPE_MASK 0xf0000000 /* Chip Type */
+#define CID_TYPE_SHIFT 28
+
+/* capabilities */
+#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
+#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
+#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
+#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
+#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */
+#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
+#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
+#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
+#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
+#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
+#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
+#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
+#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
+#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
+#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
+#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
+#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
+#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
+#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
+#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */
+#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */
+
+#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */
+#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */
+
+/* PLL type */
+#define PLL_NONE 0x00000000
+#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */
+#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */
+#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */
+#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */
+#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */
+#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */
+#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */
+
+/* ILP clock */
+#define ILP_CLOCK 32000
+
+/* ALP clock on pre-PMU chips */
+#define ALP_CLOCK 20000000
+
+/* HT clock */
+#define HT_CLOCK 80000000
+
+/* corecontrol */
+#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */
+#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
+#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */
+
+/* chipcontrol */
+#define CHIPCTRL_4321A0_DEFAULT 0x3a4
+#define CHIPCTRL_4321A1_DEFAULT 0x0a4
+#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */
+
+/* Fields in the otpstatus register in rev >= 21 */
+#define OTPS_OL_MASK 0x000000ff
+#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */
+#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */
+#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */
+#define OTPS_OL_GU 0x00000008 /* general use region is locked */
+#define OTPS_GUP_MASK 0x00000f00
+#define OTPS_GUP_SHIFT 8
+#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
+#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
+#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
+#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
+#define OTPS_READY 0x00001000
+#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */
+#define OTPS_RV_MASK 0x0fff0000
+
+/* Fields in the otpcontrol register in rev >= 21 */
+#define OTPC_PROGSEL 0x00000001
+#define OTPC_PCOUNT_MASK 0x0000000e
+#define OTPC_PCOUNT_SHIFT 1
+#define OTPC_VSEL_MASK 0x000000f0
+#define OTPC_VSEL_SHIFT 4
+#define OTPC_TMM_MASK 0x00000700
+#define OTPC_TMM_SHIFT 8
+#define OTPC_ODM 0x00000800
+#define OTPC_PROGEN 0x80000000
+
+/* Fields in otpprog in rev >= 21 and HND OTP */
+#define OTPP_COL_MASK 0x000000ff
+#define OTPP_COL_SHIFT 0
+#define OTPP_ROW_MASK 0x0000ff00
+#define OTPP_ROW_SHIFT 8
+#define OTPP_OC_MASK 0x0f000000
+#define OTPP_OC_SHIFT 24
+#define OTPP_READERR 0x10000000
+#define OTPP_VALUE_MASK 0x20000000
+#define OTPP_VALUE_SHIFT 29
+#define OTPP_START_BUSY 0x80000000
+#define OTPP_READ 0x40000000 /* HND OTP */
+
+/* otplayout reg corerev >= 36 */
+#define OTP_CISFORMAT_NEW 0x80000000
+
+/* Opcodes for OTPP_OC field */
+#define OTPPOC_READ 0
+#define OTPPOC_BIT_PROG 1
+#define OTPPOC_VERIFY 3
+#define OTPPOC_INIT 4
+#define OTPPOC_SET 5
+#define OTPPOC_RESET 6
+#define OTPPOC_OCST 7
+#define OTPPOC_ROW_LOCK 8
+#define OTPPOC_PRESCN_TEST 9
+
+/* Jtagm characteristics that appeared at a given corerev */
+#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */
+#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */
+#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */
+
+/* jtagcmd */
+#define JCMD_START 0x80000000
+#define JCMD_BUSY 0x80000000
+#define JCMD_STATE_MASK 0x60000000
+#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */
+#define JCMD_STATE_PIR 0x20000000 /* Pause IR */
+#define JCMD_STATE_PDR 0x40000000 /* Pause DR */
+#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */
+#define JCMD0_ACC_MASK 0x0000f000
+#define JCMD0_ACC_IRDR 0x00000000
+#define JCMD0_ACC_DR 0x00001000
+#define JCMD0_ACC_IR 0x00002000
+#define JCMD0_ACC_RESET 0x00003000
+#define JCMD0_ACC_IRPDR 0x00004000
+#define JCMD0_ACC_PDR 0x00005000
+#define JCMD0_IRW_MASK 0x00000f00
+#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */
+#define JCMD_ACC_IRDR 0x00000000
+#define JCMD_ACC_DR 0x00010000
+#define JCMD_ACC_IR 0x00020000
+#define JCMD_ACC_RESET 0x00030000
+#define JCMD_ACC_IRPDR 0x00040000
+#define JCMD_ACC_PDR 0x00050000
+#define JCMD_ACC_PIR 0x00060000
+#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */
+#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */
+#define JCMD_IRW_MASK 0x00001f00
+#define JCMD_IRW_SHIFT 8
+#define JCMD_DRW_MASK 0x0000003f
+
+/* jtagctrl */
+#define JCTRL_FORCE_CLK 4 /* Force clock */
+#define JCTRL_EXT_EN 2 /* Enable external targets */
+#define JCTRL_EN 1 /* Enable Jtag master */
+
+/* Fields in clkdiv */
+#define CLKD_SFLASH 0x0f000000
+#define CLKD_SFLASH_SHIFT 24
+#define CLKD_OTP 0x000f0000
+#define CLKD_OTP_SHIFT 16
+#define CLKD_JTAG 0x00000f00
+#define CLKD_JTAG_SHIFT 8
+#define CLKD_UART 0x000000ff
+
+#define CLKD2_SROM 0x00000003
+
+/* intstatus/intmask */
+#define CI_GPIO 0x00000001 /* gpio intr */
+#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */
+#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */
+#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */
+#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */
+#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */
+#define CI_WDRESET 0x80000000 /* watchdog reset occurred */
+
+/* slow_clk_ctl */
+#define SCC_SS_MASK 0x00000007 /* slow clock source mask */
+#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */
+#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */
+#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */
+#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
+#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled,
+ * 0: LPO is enabled
+ */
+#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock,
+ * 0: power logic control
+ */
+#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors
+ * PLL clock disable requests from core
+ */
+#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't
+ * disable crystal when appropriate
+ */
+#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
+#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
+#define SCC_CD_SHIFT 16
+
+/* system_clk_ctl */
+#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */
+#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */
+#define SYCC_FP 0x00000004 /* ForcePLLOn */
+#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */
+#define SYCC_HR 0x00000010 /* Force HT */
+#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
+#define SYCC_CD_SHIFT 16
+
+/* Indirect backplane access */
+#define BPIA_BYTEEN 0x0000000f
+#define BPIA_SZ1 0x00000001
+#define BPIA_SZ2 0x00000003
+#define BPIA_SZ4 0x00000007
+#define BPIA_SZ8 0x0000000f
+#define BPIA_WRITE 0x00000100
+#define BPIA_START 0x00000200
+#define BPIA_BUSY 0x00000200
+#define BPIA_ERROR 0x00000400
+
+/* pcmcia/prog/flash_config */
+#define CF_EN 0x00000001 /* enable */
+#define CF_EM_MASK 0x0000000e /* mode */
+#define CF_EM_SHIFT 1
+#define CF_EM_FLASH 0 /* flash/asynchronous mode */
+#define CF_EM_SYNC 2 /* synchronous mode */
+#define CF_EM_PCMCIA 4 /* pcmcia mode */
+#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */
+#define CF_BS 0x00000020 /* byteswap */
+#define CF_CD_MASK 0x000000c0 /* clock divider */
+#define CF_CD_SHIFT 6
+#define CF_CD_DIV2 0x00000000 /* backplane/2 */
+#define CF_CD_DIV3 0x00000040 /* backplane/3 */
+#define CF_CD_DIV4 0x00000080 /* backplane/4 */
+#define CF_CE 0x00000100 /* clock enable */
+#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */
+
+/* pcmcia_memwait */
+#define PM_W0_MASK 0x0000003f /* waitcount0 */
+#define PM_W1_MASK 0x00001f00 /* waitcount1 */
+#define PM_W1_SHIFT 8
+#define PM_W2_MASK 0x001f0000 /* waitcount2 */
+#define PM_W2_SHIFT 16
+#define PM_W3_MASK 0x1f000000 /* waitcount3 */
+#define PM_W3_SHIFT 24
+
+/* pcmcia_attrwait */
+#define PA_W0_MASK 0x0000003f /* waitcount0 */
+#define PA_W1_MASK 0x00001f00 /* waitcount1 */
+#define PA_W1_SHIFT 8
+#define PA_W2_MASK 0x001f0000 /* waitcount2 */
+#define PA_W2_SHIFT 16
+#define PA_W3_MASK 0x1f000000 /* waitcount3 */
+#define PA_W3_SHIFT 24
+
+/* pcmcia_iowait */
+#define PI_W0_MASK 0x0000003f /* waitcount0 */
+#define PI_W1_MASK 0x00001f00 /* waitcount1 */
+#define PI_W1_SHIFT 8
+#define PI_W2_MASK 0x001f0000 /* waitcount2 */
+#define PI_W2_SHIFT 16
+#define PI_W3_MASK 0x1f000000 /* waitcount3 */
+#define PI_W3_SHIFT 24
+
+/* prog_waitcount */
+#define PW_W0_MASK 0x0000001f /* waitcount0 */
+#define PW_W1_MASK 0x00001f00 /* waitcount1 */
+#define PW_W1_SHIFT 8
+#define PW_W2_MASK 0x001f0000 /* waitcount2 */
+#define PW_W2_SHIFT 16
+#define PW_W3_MASK 0x1f000000 /* waitcount3 */
+#define PW_W3_SHIFT 24
+
+#define PW_W0 0x0000000c
+#define PW_W1 0x00000a00
+#define PW_W2 0x00020000
+#define PW_W3 0x01000000
+
+/* flash_waitcount */
+#define FW_W0_MASK 0x0000003f /* waitcount0 */
+#define FW_W1_MASK 0x00001f00 /* waitcount1 */
+#define FW_W1_SHIFT 8
+#define FW_W2_MASK 0x001f0000 /* waitcount2 */
+#define FW_W2_SHIFT 16
+#define FW_W3_MASK 0x1f000000 /* waitcount3 */
+#define FW_W3_SHIFT 24
+
+/* When Srom support present, fields in sromcontrol */
+#define SRC_START 0x80000000
+#define SRC_BUSY 0x80000000
+#define SRC_OPCODE 0x60000000
+#define SRC_OP_READ 0x00000000
+#define SRC_OP_WRITE 0x20000000
+#define SRC_OP_WRDIS 0x40000000
+#define SRC_OP_WREN 0x60000000
+#define SRC_OTPSEL 0x00000010
+#define SRC_LOCK 0x00000008
+#define SRC_SIZE_MASK 0x00000006
+#define SRC_SIZE_1K 0x00000000
+#define SRC_SIZE_4K 0x00000002
+#define SRC_SIZE_16K 0x00000004
+#define SRC_SIZE_SHIFT 1
+#define SRC_PRESENT 0x00000001
+
+/* Fields in pmucontrol */
+#define PCTL_ILP_DIV_MASK 0xffff0000
+#define PCTL_ILP_DIV_SHIFT 16
+#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
+#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
+#define PCTL_HT_REQ_EN 0x00000100
+#define PCTL_ALP_REQ_EN 0x00000080
+#define PCTL_XTALFREQ_MASK 0x0000007c
+#define PCTL_XTALFREQ_SHIFT 2
+#define PCTL_ILP_DIV_EN 0x00000002
+#define PCTL_LPO_SEL 0x00000001
+
+/* Fields in clkstretch */
+#define CSTRETCH_HT 0xffff0000
+#define CSTRETCH_ALP 0x0000ffff
+
+/* gpiotimerval */
+#define GPIO_ONTIME_SHIFT 16
+
+/* clockcontrol_n */
+#define CN_N1_MASK 0x3f /* n1 control */
+#define CN_N2_MASK 0x3f00 /* n2 control */
+#define CN_N2_SHIFT 8
+#define CN_PLLC_MASK 0xf0000 /* pll control */
+#define CN_PLLC_SHIFT 16
+
+/* clockcontrol_sb/pci/uart */
+#define CC_M1_MASK 0x3f /* m1 control */
+#define CC_M2_MASK 0x3f00 /* m2 control */
+#define CC_M2_SHIFT 8
+#define CC_M3_MASK 0x3f0000 /* m3 control */
+#define CC_M3_SHIFT 16
+#define CC_MC_MASK 0x1f000000 /* mux control */
+#define CC_MC_SHIFT 24
+
+/* N3M Clock control magic field values */
+#define CC_F6_2 0x02 /* A factor of 2 in */
+#define CC_F6_3 0x03 /* 6-bit fields like */
+#define CC_F6_4 0x05 /* N1, M1 or M3 */
+#define CC_F6_5 0x09
+#define CC_F6_6 0x11
+#define CC_F6_7 0x21
+
+#define CC_F5_BIAS 5 /* 5-bit fields get this added */
+
+#define CC_MC_BYPASS 0x08
+#define CC_MC_M1 0x04
+#define CC_MC_M1M2 0x02
+#define CC_MC_M1M2M3 0x01
+#define CC_MC_M1M3 0x11
+
+/* Type 2 Clock control magic field values */
+#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
+#define CC_T2M2_BIAS 3 /* m2 bias */
+
+#define CC_T2MC_M1BYP 1
+#define CC_T2MC_M2BYP 2
+#define CC_T2MC_M3BYP 4
+
+/* Type 6 Clock control magic field values */
+#define CC_T6_MMASK 1 /* bits of interest in m */
+#define CC_T6_M0 120000000 /* sb clock for m = 0 */
+#define CC_T6_M1 100000000 /* sb clock for m = 1 */
+#define SB2MIPS_T6(sb) (2 * (sb))
+
+/* Common clock base */
+#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */
+#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */
+
+/* Clock control values for 200MHz in 5350 */
+#define CLKC_5350_N 0x0311
+#define CLKC_5350_M 0x04020009
+
+/* Flash types in the chipcommon capabilities register */
+#define FLASH_NONE 0x000 /* No flash */
+#define SFLASH_ST 0x100 /* ST serial flash */
+#define SFLASH_AT 0x200 /* Atmel serial flash */
+#define PFLASH 0x700 /* Parallel flash */
+
+/* Bits in the ExtBus config registers */
+#define CC_CFG_EN 0x0001 /* Enable */
+#define CC_CFG_EM_MASK 0x000e /* Extif Mode */
+#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */
+#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */
+#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */
+#define CC_CFG_EM_IDE 0x0006 /* IDE */
+#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
+#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */
+#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */
+#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */
+#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */
+
+/* ExtBus address space */
+#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */
+#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */
+#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */
+#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */
+#define CC_EB_IDE 0x1a800000 /* IDE memory base */
+#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */
+#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */
+#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */
+#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */
+
+/* Start/busy bit in flashcontrol */
+#define SFLASH_OPCODE 0x000000ff
+#define SFLASH_ACTION 0x00000700
+#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */
+#define SFLASH_START 0x80000000
+#define SFLASH_BUSY SFLASH_START
+
+/* flashcontrol action codes */
+#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */
+#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */
+#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */
+#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */
+#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */
+#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */
+#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */
+
+/* flashcontrol action+opcodes for ST flashes */
+#define SFLASH_ST_WREN 0x0006 /* Write Enable */
+#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */
+#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */
+#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */
+#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */
+#define SFLASH_ST_PP 0x0302 /* Page Program */
+#define SFLASH_ST_SE 0x02d8 /* Sector Erase */
+#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */
+#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */
+#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */
+#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */
+#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */
+
+/* Status register bits for ST flashes */
+#define SFLASH_ST_WIP 0x01 /* Write In Progress */
+#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */
+#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */
+#define SFLASH_ST_BP_SHIFT 2
+#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */
+
+/* flashcontrol action+opcodes for Atmel flashes */
+#define SFLASH_AT_READ 0x07e8
+#define SFLASH_AT_PAGE_READ 0x07d2
+#define SFLASH_AT_BUF1_READ
+#define SFLASH_AT_BUF2_READ
+#define SFLASH_AT_STATUS 0x01d7
+#define SFLASH_AT_BUF1_WRITE 0x0384
+#define SFLASH_AT_BUF2_WRITE 0x0387
+#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283
+#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286
+#define SFLASH_AT_BUF1_PROGRAM 0x0288
+#define SFLASH_AT_BUF2_PROGRAM 0x0289
+#define SFLASH_AT_PAGE_ERASE 0x0281
+#define SFLASH_AT_BLOCK_ERASE 0x0250
+#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382
+#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385
+#define SFLASH_AT_BUF1_LOAD 0x0253
+#define SFLASH_AT_BUF2_LOAD 0x0255
+#define SFLASH_AT_BUF1_COMPARE 0x0260
+#define SFLASH_AT_BUF2_COMPARE 0x0261
+#define SFLASH_AT_BUF1_REPROGRAM 0x0258
+#define SFLASH_AT_BUF2_REPROGRAM 0x0259
+
+/* Status register bits for Atmel flashes */
+#define SFLASH_AT_READY 0x80
+#define SFLASH_AT_MISMATCH 0x40
+#define SFLASH_AT_ID_MASK 0x38
+#define SFLASH_AT_ID_SHIFT 3
+
+/*
+ * These are the UART port assignments, expressed as offsets from the base
+ * register. These assignments should hold for any serial port based on
+ * a 8250, 16450, or 16550(A).
+ */
+
+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
+#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */
+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
+#define UART_IIR 2 /* In: Interrupt Identity Register */
+#define UART_FCR 2 /* Out: FIFO Control Register */
+#define UART_LCR 3 /* Out: Line Control Register */
+#define UART_MCR 4 /* Out: Modem Control Register */
+#define UART_LSR 5 /* In: Line Status Register */
+#define UART_MSR 6 /* In: Modem Status Register */
+#define UART_SCR 7 /* I/O: Scratch Register */
+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
+#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */
+#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */
+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
+#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */
+#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BREAK 0x10 /* Break interrupt */
+#define UART_LSR_FRAMING 0x08 /* Framing error */
+#define UART_LSR_PARITY 0x04 /* Parity error */
+#define UART_LSR_OVERRUN 0x02 /* Overrun error */
+#define UART_LSR_RXRDY 0x01 /* Receiver ready */
+#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */
+
+/* Interrupt Identity Register (IIR) bits */
+#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */
+#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */
+#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */
+#define UART_IIR_NOINT 0x1 /* No interrupt pending */
+#define UART_IIR_THRE 0x2 /* THR empty */
+#define UART_IIR_RCVD_DATA 0x4 /* Received data available */
+#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */
+#define UART_IIR_CHAR_TIME 0xc /* Character time */
+
+/* Interrupt Enable Register (IER) bits */
+#define UART_IER_EDSSI 8 /* enable modem status interrupt */
+#define UART_IER_ELSI 4 /* enable receiver line status interrupt */
+#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */
+#define UART_IER_ERBFI 1 /* enable data available interrupt */
+
+/* pmustatus */
+#define PST_EXTLPOAVAIL 0x0100
+#define PST_WDRESET 0x0080
+#define PST_INTPEND 0x0040
+#define PST_SBCLKST 0x0030
+#define PST_SBCLKST_ILP 0x0010
+#define PST_SBCLKST_ALP 0x0020
+#define PST_SBCLKST_HT 0x0030
+#define PST_ALPAVAIL 0x0008
+#define PST_HTAVAIL 0x0004
+#define PST_RESINIT 0x0003
+
+/* pmucapabilities */
+#define PCAP_REV_MASK 0x000000ff
+#define PCAP_RC_MASK 0x00001f00
+#define PCAP_RC_SHIFT 8
+#define PCAP_TC_MASK 0x0001e000
+#define PCAP_TC_SHIFT 13
+#define PCAP_PC_MASK 0x001e0000
+#define PCAP_PC_SHIFT 17
+#define PCAP_VC_MASK 0x01e00000
+#define PCAP_VC_SHIFT 21
+#define PCAP_CC_MASK 0x1e000000
+#define PCAP_CC_SHIFT 25
+#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */
+#define PCAP5_PC_SHIFT 17
+#define PCAP5_VC_MASK 0x07c00000
+#define PCAP5_VC_SHIFT 22
+#define PCAP5_CC_MASK 0xf8000000
+#define PCAP5_CC_SHIFT 27
+
+/* PMU Resource Request Timer registers */
+/* This is based on PmuRev0 */
+#define PRRT_TIME_MASK 0x03ff
+#define PRRT_INTEN 0x0400
+#define PRRT_REQ_ACTIVE 0x0800
+#define PRRT_ALP_REQ 0x1000
+#define PRRT_HT_REQ 0x2000
+
+/* PMU resource bit position */
+#define PMURES_BIT(bit) (1 << (bit))
+
+/* PMU resource number limit */
+#define PMURES_MAX_RESNUM 30
+
+/* PMU chip control0 register */
+#define PMU_CHIPCTL0 0
+
+/* PMU chip control1 register */
+#define PMU_CHIPCTL1 1
+#define PMU_CC1_RXC_DLL_BYPASS 0x00010000
+
+#define PMU_CC1_IF_TYPE_MASK 0x00000030
+#define PMU_CC1_IF_TYPE_RMII 0x00000000
+#define PMU_CC1_IF_TYPE_MII 0x00000010
+#define PMU_CC1_IF_TYPE_RGMII 0x00000020
+
+#define PMU_CC1_SW_TYPE_MASK 0x000000c0
+#define PMU_CC1_SW_TYPE_EPHY 0x00000000
+#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040
+#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080
+#define PMU_CC1_SW_TYPE_RGMII 0x000000c0
+
+/* PMU corerev and chip specific PLL controls.
+ * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
+ * to differentiate different PLLs controlled by the same PMU rev.
+ */
+/* pllcontrol registers */
+/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
+#define PMU0_PLL0_PLLCTL0 0
+#define PMU0_PLL0_PC0_PDIV_MASK 1
+#define PMU0_PLL0_PC0_PDIV_FREQ 25000
+#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038
+#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3
+#define PMU0_PLL0_PC0_DIV_ARM_BASE 8
+
+/* PC0_DIV_ARM for PLLOUT_ARM */
+#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0
+#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1
+#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2
+#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */
+#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4
+#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5
+#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6
+#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7
+
+/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
+#define PMU0_PLL0_PLLCTL1 1
+#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000
+#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28
+#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00
+#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8
+#define PMU0_PLL0_PC1_STOP_MOD 0x00000040
+
+/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
+#define PMU0_PLL0_PLLCTL2 2
+#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf
+#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4
+
+/* pllcontrol registers */
+/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+#define PMU1_PLL0_PLLCTL0 0
+#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000
+#define PMU1_PLL0_PC0_P1DIV_SHIFT 20
+#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000
+#define PMU1_PLL0_PC0_P2DIV_SHIFT 24
+
+/* m<x>div */
+#define PMU1_PLL0_PLLCTL1 1
+#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC1_M1DIV_SHIFT 0
+#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC1_M2DIV_SHIFT 8
+#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000
+#define PMU1_PLL0_PC1_M3DIV_SHIFT 16
+#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000
+#define PMU1_PLL0_PC1_M4DIV_SHIFT 24
+
+#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8
+#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+
+/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+#define PMU1_PLL0_PLLCTL2 2
+#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC2_M5DIV_SHIFT 0
+#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC2_M6DIV_SHIFT 8
+#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000
+#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17
+#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1
+#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */
+#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
+#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
+
+/* ndiv_frac */
+#define PMU1_PLL0_PLLCTL3 3
+#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff
+#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0
+
+/* pll_ctrl */
+#define PMU1_PLL0_PLLCTL4 4
+
+/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+#define PMU1_PLL0_PLLCTL5 5
+#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
+#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
+
+/* PMU rev 2 control words */
+#define PMU2_PHY_PLL_PLLCTL 4
+#define PMU2_SI_PLL_PLLCTL 10
+
+/* PMU rev 2 */
+/* pllcontrol registers */
+/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+#define PMU2_PLL_PLLCTL0 0
+#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000
+#define PMU2_PLL_PC0_P1DIV_SHIFT 20
+#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000
+#define PMU2_PLL_PC0_P2DIV_SHIFT 24
+
+/* m<x>div */
+#define PMU2_PLL_PLLCTL1 1
+#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff
+#define PMU2_PLL_PC1_M1DIV_SHIFT 0
+#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00
+#define PMU2_PLL_PC1_M2DIV_SHIFT 8
+#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000
+#define PMU2_PLL_PC1_M3DIV_SHIFT 16
+#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000
+#define PMU2_PLL_PC1_M4DIV_SHIFT 24
+
+/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+#define PMU2_PLL_PLLCTL2 2
+#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff
+#define PMU2_PLL_PC2_M5DIV_SHIFT 0
+#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00
+#define PMU2_PLL_PC2_M6DIV_SHIFT 8
+#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000
+#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17
+#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000
+#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20
+
+/* ndiv_frac */
+#define PMU2_PLL_PLLCTL3 3
+#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff
+#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0
+
+/* pll_ctrl */
+#define PMU2_PLL_PLLCTL4 4
+
+/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+#define PMU2_PLL_PLLCTL5 5
+#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00
+#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8
+#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000
+#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12
+#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000
+#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16
+#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000
+#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20
+#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000
+#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24
+#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000
+#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28
+
+/* PMU rev 5 (& 6) */
+#define PMU5_PLL_P1P2_OFF 0
+#define PMU5_PLL_P1_MASK 0x0f000000
+#define PMU5_PLL_P1_SHIFT 24
+#define PMU5_PLL_P2_MASK 0x00f00000
+#define PMU5_PLL_P2_SHIFT 20
+#define PMU5_PLL_M14_OFF 1
+#define PMU5_PLL_MDIV_MASK 0x000000ff
+#define PMU5_PLL_MDIV_WIDTH 8
+#define PMU5_PLL_NM5_OFF 2
+#define PMU5_PLL_NDIV_MASK 0xfff00000
+#define PMU5_PLL_NDIV_SHIFT 20
+#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000
+#define PMU5_PLL_NDIV_MODE_SHIFT 17
+#define PMU5_PLL_FMAB_OFF 3
+#define PMU5_PLL_MRAT_MASK 0xf0000000
+#define PMU5_PLL_MRAT_SHIFT 28
+#define PMU5_PLL_ABRAT_MASK 0x08000000
+#define PMU5_PLL_ABRAT_SHIFT 27
+#define PMU5_PLL_FDIV_MASK 0x07ffffff
+#define PMU5_PLL_PLLCTL_OFF 4
+#define PMU5_PLL_PCHI_OFF 5
+#define PMU5_PLL_PCHI_MASK 0x0000003f
+
+/* pmu XtalFreqRatio */
+#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
+#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
+#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
+
+/* Divider allocation in 4716/47162/5356/5357 */
+#define PMU5_MAINPLL_CPU 1
+#define PMU5_MAINPLL_MEM 2
+#define PMU5_MAINPLL_SI 3
+
+#define PMU7_PLL_PLLCTL7 7
+#define PMU7_PLL_PLLCTL8 8
+#define PMU7_PLL_PLLCTL11 11
+
+/* PLL usage in 4716/47162 */
+#define PMU4716_MAINPLL_PLL0 12
+
+/* PLL usage in 5356/5357 */
+#define PMU5356_MAINPLL_PLL0 0
+#define PMU5357_MAINPLL_PLL0 0
+
+/* 4716/47162 resources */
+#define RES4716_PROC_PLL_ON 0x00000040
+#define RES4716_PROC_HT_AVAIL 0x00000080
+
+/* 4716/4717/4718 Chip specific ChipControl register bits */
+#define CCTRL471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared with pflash */
+
+/* 5354 resources */
+#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES5354_ILP_REQUEST 4 /* 0x00010 */
+#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES5354_ROM_SWITCH 7 /* 0x00080 */
+#define RES5354_PA_REF_LDO 8 /* 0x00100 */
+#define RES5354_RADIO_LDO 9 /* 0x00200 */
+#define RES5354_AFE_LDO 10 /* 0x00400 */
+#define RES5354_PLL_LDO 11 /* 0x00800 */
+#define RES5354_BG_FILTBYP 12 /* 0x01000 */
+#define RES5354_TX_FILTBYP 13 /* 0x02000 */
+#define RES5354_RX_FILTBYP 14 /* 0x04000 */
+#define RES5354_XTAL_PU 15 /* 0x08000 */
+#define RES5354_XTAL_EN 16 /* 0x10000 */
+#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES5354_BB_PLL_PU 19 /* 0x80000 */
+
+/* 5357 Chip specific ChipControl register bits */
+#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */
+#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */
+
+/* 4328 resources */
+#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES4328_ILP_REQUEST 4 /* 0x00010 */
+#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES4328_ROM_SWITCH 7 /* 0x00080 */
+#define RES4328_PA_REF_LDO 8 /* 0x00100 */
+#define RES4328_RADIO_LDO 9 /* 0x00200 */
+#define RES4328_AFE_LDO 10 /* 0x00400 */
+#define RES4328_PLL_LDO 11 /* 0x00800 */
+#define RES4328_BG_FILTBYP 12 /* 0x01000 */
+#define RES4328_TX_FILTBYP 13 /* 0x02000 */
+#define RES4328_RX_FILTBYP 14 /* 0x04000 */
+#define RES4328_XTAL_PU 15 /* 0x08000 */
+#define RES4328_XTAL_EN 16 /* 0x10000 */
+#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES4328_BB_PLL_PU 19 /* 0x80000 */
+
+/* 4325 A0/A1 resources */
+#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */
+#define RES4325_CBUCK_BURST 1 /* 0x00000002 */
+#define RES4325_CBUCK_PWM 2 /* 0x00000004 */
+#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */
+#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */
+#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */
+#define RES4325_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4325_ABUCK_BURST 7 /* 0x00000080 */
+#define RES4325_ABUCK_PWM 8 /* 0x00000100 */
+#define RES4325_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4325_OTP_PU 10 /* 0x00000400 */
+#define RES4325_LNLDO3_PU 11 /* 0x00000800 */
+#define RES4325_LNLDO4_PU 12 /* 0x00001000 */
+#define RES4325_XTAL_PU 13 /* 0x00002000 */
+#define RES4325_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4325_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4325 B0/C0 resources */
+#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4325B0_CLDO_PU 4 /* 0x00000010 */
+
+/* 4325 C1 resources */
+#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */
+
+/* 4325 chip-specific ChipStatus register bits */
+#define CST4325_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
+#define CST4325_SDIO_USB_MODE_MASK 0x00000004
+#define CST4325_SDIO_USB_MODE_SHIFT 2
+#define CST4325_RCAL_VALID_MASK 0x00000008
+#define CST4325_RCAL_VALID_SHIFT 3
+#define CST4325_RCAL_VALUE_MASK 0x000001f0
+#define CST4325_RCAL_VALUE_SHIFT 4
+#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */
+#define CST4325_PMUTOP_2B_SHIFT 9
+
+#define RES4329_RESERVED0 0 /* 0x00000001 */
+#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4329_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4329_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4329_CLDO_PU 4 /* 0x00000010 */
+#define RES4329_PALDO_PU 5 /* 0x00000020 */
+#define RES4329_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4329_RESERVED7 7 /* 0x00000080 */
+#define RES4329_RESERVED8 8 /* 0x00000100 */
+#define RES4329_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4329_OTP_PU 10 /* 0x00000400 */
+#define RES4329_RESERVED11 11 /* 0x00000800 */
+#define RES4329_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4329_XTAL_PU 13 /* 0x00002000 */
+#define RES4329_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4329_HT_AVAIL 21 /* 0x00200000 */
+
+#define CST4329_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
+#define CST4329_SPI_SDIO_MODE_MASK 0x00000004
+#define CST4329_SPI_SDIO_MODE_SHIFT 2
+
+/* 4312 chip-specific ChipStatus register bits */
+#define CST4312_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */
+
+/* 4312 resources (all PMU chips with little memory constraint) */
+#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */
+#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */
+#define RES4312_PA_REF_LDO 2 /* 0x00000004 */
+#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */
+#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */
+#define RES4312_RADIO_LDO 5 /* 0x00000020 */
+#define RES4312_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4312_BG_FILTBYP 7 /* 0x00000080 */
+#define RES4312_TX_FILTBYP 8 /* 0x00000100 */
+#define RES4312_RX_FILTBYP 9 /* 0x00000200 */
+#define RES4312_XTAL_PU 10 /* 0x00000400 */
+#define RES4312_ALP_AVAIL 11 /* 0x00000800 */
+#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */
+#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */
+#define RES4312_HT_AVAIL 14 /* 0x00004000 */
+
+/* 4322 resources */
+#define RES4322_RF_LDO 0
+#define RES4322_ILP_REQUEST 1
+#define RES4322_XTAL_PU 2
+#define RES4322_ALP_AVAIL 3
+#define RES4322_SI_PLL_ON 4
+#define RES4322_HT_SI_AVAIL 5
+#define RES4322_PHY_PLL_ON 6
+#define RES4322_HT_PHY_AVAIL 7
+#define RES4322_OTP_PU 8
+
+/* 4322 chip-specific ChipStatus register bits */
+#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020
+#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0
+#define CST4322_SPROM_OTP_SEL_SHIFT 6
+#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */
+#define CST4322_SPROM_PRESENT 1 /* SPROM is present */
+#define CST4322_OTP_PRESENT 2 /* OTP is present */
+#define CST4322_PCI_OR_USB 0x00000100
+#define CST4322_BOOT_MASK 0x00000600
+#define CST4322_BOOT_SHIFT 9
+#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
+#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */
+#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */
+#define CST4322_BOOT_FROM_INVALID 3
+#define CST4322_ILP_DIV_EN 0x00000800
+#define CST4322_FLASH_TYPE_MASK 0x00001000
+#define CST4322_FLASH_TYPE_SHIFT 12
+#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */
+#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */
+#define CST4322_ARM_TAP_SEL 0x00002000
+#define CST4322_RES_INIT_MODE_MASK 0x0000c000
+#define CST4322_RES_INIT_MODE_SHIFT 14
+#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */
+#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */
+#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */
+#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */
+#define CST4322_PCIPLLCLK_GATING 0x00010000
+#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000
+#define CST4322_PCI_CARDBUS_MODE 0x00040000
+
+/* 43224 chip-specific ChipControl register bits */
+#define CCTRL43224_GPIO_TOGGLE 0x8000
+#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */
+#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */
+
+/* 43236 resources */
+#define RES43236_REGULATOR 0
+#define RES43236_ILP_REQUEST 1
+#define RES43236_XTAL_PU 2
+#define RES43236_ALP_AVAIL 3
+#define RES43236_SI_PLL_ON 4
+#define RES43236_HT_SI_AVAIL 5
+
+/* 43236 chip-specific ChipControl register bits */
+#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */
+#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
+#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */
+#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */
+#define CCTRL43236_GSIO (1<<4) /* 0 disable */
+
+/* 43236 Chip specific ChipStatus register bits */
+#define CST43236_SFLASH_MASK 0x00000040
+#define CST43236_OTP_MASK 0x00000080
+#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */
+#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */
+#define CST43236_BOOT_MASK 0x00001800
+#define CST43236_BOOT_SHIFT 11
+#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
+#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */
+#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */
+#define CST43236_BOOT_FROM_INVALID 3
+
+/* 4331 resources */
+#define RES4331_REGULATOR 0
+#define RES4331_ILP_REQUEST 1
+#define RES4331_XTAL_PU 2
+#define RES4331_ALP_AVAIL 3
+#define RES4331_SI_PLL_ON 4
+#define RES4331_HT_SI_AVAIL 5
+
+/* 4331 chip-specific ChipControl register bits */
+#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */
+#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
+#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */
+#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */
+#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */
+#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */
+#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */
+#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */
+#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */
+#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */
+#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */
+#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */
+#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */
+#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */
+
+/* 4331 Chip specific ChipStatus register bits */
+#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */
+#define CST4331_SPROM_PRESENT 0x00000002
+#define CST4331_OTP_PRESENT 0x00000004
+#define CST4331_LDO_RF 0x00000008
+#define CST4331_LDO_PAR 0x00000010
+
+/* 4315 resources */
+#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4315_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4315_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4315_CLDO_PU 4 /* 0x00000010 */
+#define RES4315_PALDO_PU 5 /* 0x00000020 */
+#define RES4315_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4315_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4315_OTP_PU 10 /* 0x00000400 */
+#define RES4315_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4315_XTAL_PU 13 /* 0x00002000 */
+#define RES4315_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4315_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4315 chip-specific ChipStatus register bits */
+#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */
+#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */
+#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */
+#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */
+#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */
+#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */
+#define CST4315_RCAL_VALID 0x00000008
+#define CST4315_RCAL_VALUE_MASK 0x000001f0
+#define CST4315_RCAL_VALUE_SHIFT 4
+#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */
+#define CST4315_CBUCK_MODE_MASK 0x00000c00
+#define CST4315_CBUCK_MODE_BURST 0x00000400
+#define CST4315_CBUCK_MODE_LPBURST 0x00000c00
+
+/* 4319 resources */
+#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4319_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4319_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4319_CLDO_PU 4 /* 0x00000010 */
+#define RES4319_PALDO_PU 5 /* 0x00000020 */
+#define RES4319_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4319_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4319_OTP_PU 10 /* 0x00000400 */
+#define RES4319_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4319_XTAL_PU 13 /* 0x00002000 */
+#define RES4319_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4319_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4319 chip-specific ChipStatus register bits */
+#define CST4319_SPI_CPULESSUSB 0x00000001
+#define CST4319_SPI_CLK_POL 0x00000002
+#define CST4319_SPI_CLK_PH 0x00000008
+#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */
+#define CST4319_SPROM_OTP_SEL_SHIFT 6
+#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */
+#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */
+#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */
+#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */
+#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */
+#define CST4319_REMAP_SEL_MASK 0x00000600
+#define CST4319_ILPDIV_EN 0x00000800
+#define CST4319_XTAL_PD_POL 0x00001000
+#define CST4319_LPO_SEL 0x00002000
+#define CST4319_RES_INIT_MODE 0x0000c000
+#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */
+#define CST4319_CBUCK_MODE_MASK 0x00060000
+#define CST4319_CBUCK_MODE_BURST 0x00020000
+#define CST4319_CBUCK_MODE_LPBURST 0x00060000
+#define CST4319_RCAL_VALID 0x01000000
+#define CST4319_RCAL_VALUE_MASK 0x3e000000
+#define CST4319_RCAL_VALUE_SHIFT 25
+
+#define PMU1_PLL0_CHIPCTL0 0
+#define PMU1_PLL0_CHIPCTL1 1
+#define PMU1_PLL0_CHIPCTL2 2
+#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000
+#define CCTL_4319USB_XTAL_SEL_SHIFT 19
+#define CCTL_4319USB_48MHZ_PLL_SEL 1
+#define CCTL_4319USB_24MHZ_PLL_SEL 2
+
+/* PMU resources for 4336 */
+#define RES4336_CBUCK_LPOM 0
+#define RES4336_CBUCK_BURST 1
+#define RES4336_CBUCK_LP_PWM 2
+#define RES4336_CBUCK_PWM 3
+#define RES4336_CLDO_PU 4
+#define RES4336_DIS_INT_RESET_PD 5
+#define RES4336_ILP_REQUEST 6
+#define RES4336_LNLDO_PU 7
+#define RES4336_LDO3P3_PU 8
+#define RES4336_OTP_PU 9
+#define RES4336_XTAL_PU 10
+#define RES4336_ALP_AVAIL 11
+#define RES4336_RADIO_PU 12
+#define RES4336_BG_PU 13
+#define RES4336_VREG1p4_PU_PU 14
+#define RES4336_AFE_PWRSW_PU 15
+#define RES4336_RX_PWRSW_PU 16
+#define RES4336_TX_PWRSW_PU 17
+#define RES4336_BB_PWRSW_PU 18
+#define RES4336_SYNTH_PWRSW_PU 19
+#define RES4336_MISC_PWRSW_PU 20
+#define RES4336_LOGEN_PWRSW_PU 21
+#define RES4336_BBPLL_PWRSW_PU 22
+#define RES4336_MACPHY_CLKAVAIL 23
+#define RES4336_HT_AVAIL 24
+#define RES4336_RSVD 25
+
+/* 4336 chip-specific ChipStatus register bits */
+#define CST4336_SPI_MODE_MASK 0x00000001
+#define CST4336_SPROM_PRESENT 0x00000002
+#define CST4336_OTP_PRESENT 0x00000004
+#define CST4336_ARMREMAP_0 0x00000008
+#define CST4336_ILPDIV_EN_MASK 0x00000010
+#define CST4336_ILPDIV_EN_SHIFT 4
+#define CST4336_XTAL_PD_POL_MASK 0x00000020
+#define CST4336_XTAL_PD_POL_SHIFT 5
+#define CST4336_LPO_SEL_MASK 0x00000040
+#define CST4336_LPO_SEL_SHIFT 6
+#define CST4336_RES_INIT_MODE_MASK 0x00000180
+#define CST4336_RES_INIT_MODE_SHIFT 7
+#define CST4336_CBUCK_MODE_MASK 0x00000600
+#define CST4336_CBUCK_MODE_SHIFT 9
+
+/* 4330 resources */
+#define RES4330_CBUCK_LPOM 0
+#define RES4330_CBUCK_BURST 1
+#define RES4330_CBUCK_LP_PWM 2
+#define RES4330_CBUCK_PWM 3
+#define RES4330_CLDO_PU 4
+#define RES4330_DIS_INT_RESET_PD 5
+#define RES4330_ILP_REQUEST 6
+#define RES4330_LNLDO_PU 7
+#define RES4330_LDO3P3_PU 8
+#define RES4330_OTP_PU 9
+#define RES4330_XTAL_PU 10
+#define RES4330_ALP_AVAIL 11
+#define RES4330_RADIO_PU 12
+#define RES4330_BG_PU 13
+#define RES4330_VREG1p4_PU_PU 14
+#define RES4330_AFE_PWRSW_PU 15
+#define RES4330_RX_PWRSW_PU 16
+#define RES4330_TX_PWRSW_PU 17
+#define RES4330_BB_PWRSW_PU 18
+#define RES4330_SYNTH_PWRSW_PU 19
+#define RES4330_MISC_PWRSW_PU 20
+#define RES4330_LOGEN_PWRSW_PU 21
+#define RES4330_BBPLL_PWRSW_PU 22
+#define RES4330_MACPHY_CLKAVAIL 23
+#define RES4330_HT_AVAIL 24
+#define RES4330_5gRX_PWRSW_PU 25
+#define RES4330_5gTX_PWRSW_PU 26
+#define RES4330_5g_LOGEN_PWRSW_PU 27
+
+/* 4330 chip-specific ChipStatus register bits */
+#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */
+#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */
+#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */
+#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */
+#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */
+#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */
+#define CST4330_OTP_PRESENT 0x00000010
+#define CST4330_LPO_AUTODET_EN 0x00000020
+#define CST4330_ARMREMAP_0 0x00000040
+#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */
+#define CST4330_ILPDIV_EN 0x00000100
+#define CST4330_LPO_SEL 0x00000200
+#define CST4330_RES_INIT_MODE_SHIFT 10
+#define CST4330_RES_INIT_MODE_MASK 0x00000c00
+#define CST4330_CBUCK_MODE_SHIFT 12
+#define CST4330_CBUCK_MODE_MASK 0x00003000
+#define CST4330_CBUCK_POWER_OK 0x00004000
+#define CST4330_BB_PLL_LOCKED 0x00008000
+#define SOCDEVRAM_4330_BP_ADDR 0x1E000000
+#define SOCDEVRAM_4330_ARM_ADDR 0x00800000
+
+/* 4313 resources */
+#define RES4313_BB_PU_RSRC 0
+#define RES4313_ILP_REQ_RSRC 1
+#define RES4313_XTAL_PU_RSRC 2
+#define RES4313_ALP_AVAIL_RSRC 3
+#define RES4313_RADIO_PU_RSRC 4
+#define RES4313_BG_PU_RSRC 5
+#define RES4313_VREG1P4_PU_RSRC 6
+#define RES4313_AFE_PWRSW_RSRC 7
+#define RES4313_RX_PWRSW_RSRC 8
+#define RES4313_TX_PWRSW_RSRC 9
+#define RES4313_BB_PWRSW_RSRC 10
+#define RES4313_SYNTH_PWRSW_RSRC 11
+#define RES4313_MISC_PWRSW_RSRC 12
+#define RES4313_BB_PLL_PWRSW_RSRC 13
+#define RES4313_HT_AVAIL_RSRC 14
+#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
+
+/* 4313 chip-specific ChipStatus register bits */
+#define CST4313_SPROM_PRESENT 1
+#define CST4313_OTP_PRESENT 2
+#define CST4313_SPROM_OTP_SEL_MASK 0x00000002
+#define CST4313_SPROM_OTP_SEL_SHIFT 0
+
+/* 4313 Chip specific ChipControl register bits */
+#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */
+
+/* 43228 resources */
+#define RES43228_NOT_USED 0
+#define RES43228_ILP_REQUEST 1
+#define RES43228_XTAL_PU 2
+#define RES43228_ALP_AVAIL 3
+#define RES43228_PLL_EN 4
+#define RES43228_HT_PHY_AVAIL 5
+
+/* 43228 chipstatus reg bits */
+#define CST43228_ILP_DIV_EN 0x1
+#define CST43228_OTP_PRESENT 0x2
+#define CST43228_SERDES_REFCLK_PADSEL 0x4
+#define CST43228_SDIO_MODE 0x8
+
+#define CST43228_SDIO_OTP_PRESENT 0x10
+#define CST43228_SDIO_RESET 0x20
+
+/*
+* Maximum delay for the PMU state transition in us.
+* This is an upper bound intended for spinwaits etc.
+*/
+#define PMU_MAX_TRANSITION_DLY 15000
+
+/* PMU resource up transition time in ILP cycles */
+#define PMURES_UP_TRANSITION 2
+
+/*
+* Register eci_inputlo bitfield values.
+* - BT packet type information bits [7:0]
+*/
+/* [3:0] - Task (link) type */
+#define BT_ACL 0x00
+#define BT_SCO 0x01
+#define BT_eSCO 0x02
+#define BT_A2DP 0x03
+#define BT_SNIFF 0x04
+#define BT_PAGE_SCAN 0x05
+#define BT_INQUIRY_SCAN 0x06
+#define BT_PAGE 0x07
+#define BT_INQUIRY 0x08
+#define BT_MSS 0x09
+#define BT_PARK 0x0a
+#define BT_RSSISCAN 0x0b
+#define BT_MD_ACL 0x0c
+#define BT_MD_eSCO 0x0d
+#define BT_SCAN_WITH_SCO_LINK 0x0e
+#define BT_SCAN_WITHOUT_SCO_LINK 0x0f
+/* [7:4] = packet duration code */
+/* [8] - Master / Slave */
+#define BT_MASTER 0
+#define BT_SLAVE 1
+/* [11:9] - multi-level priority */
+#define BT_LOWEST_PRIO 0x0
+#define BT_HIGHEST_PRIO 0x3
+
+/* WLAN - number of antenna */
+#define WLAN_NUM_ANT1 TXANT_0
+#define WLAN_NUM_ANT2 TXANT_1
+
+#endif /* _SBCHIPC_H */
diff --git a/drivers/staging/brcm80211/include/sbconfig.h b/drivers/staging/brcm80211/include/sbconfig.h
new file mode 100644
index 000000000000..c296f60eef9c
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbconfig.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SBCONFIG_H
+#define _SBCONFIG_H
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif
+
+/* enumeration in SB is based on the premise that cores are contiguos in the
+ * enumeration space.
+ */
+#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */
+#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE)
+#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */
+
+/*
+ * Sonics Configuration Space Registers.
+ */
+#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */
+#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */
+
+#define SBIPSFLAG 0x08
+#define SBTPSFLAG 0x18
+#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */
+#define SBTMERRLOG 0x50 /* sonics >= 2.3 */
+#define SBADMATCH3 0x60
+#define SBADMATCH2 0x68
+#define SBADMATCH1 0x70
+#define SBIMSTATE 0x90
+#define SBINTVEC 0x94
+#define SBTMSTATELOW 0x98
+#define SBTMSTATEHIGH 0x9c
+#define SBBWA0 0xa0
+#define SBIMCONFIGLOW 0xa8
+#define SBIMCONFIGHIGH 0xac
+#define SBADMATCH0 0xb0
+#define SBTMCONFIGLOW 0xb8
+#define SBTMCONFIGHIGH 0xbc
+#define SBBCONFIG 0xc0
+#define SBBSTATE 0xc8
+#define SBACTCNFG 0xd8
+#define SBFLAGST 0xe8
+#define SBIDLOW 0xf8
+#define SBIDHIGH 0xfc
+
+/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have
+ * a few registers *below* that line. I think it would be very confusing to try
+ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here,
+ */
+
+#define SBIMERRLOGA 0xea8
+#define SBIMERRLOG 0xeb0
+#define SBTMPORTCONNID0 0xed8
+#define SBTMPORTLOCK0 0xef8
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+typedef volatile struct _sbconfig {
+ uint32 PAD[2];
+ uint32 sbipsflag; /* initiator port ocp slave flag */
+ uint32 PAD[3];
+ uint32 sbtpsflag; /* target port ocp slave flag */
+ uint32 PAD[11];
+ uint32 sbtmerrloga; /* (sonics >= 2.3) */
+ uint32 PAD;
+ uint32 sbtmerrlog; /* (sonics >= 2.3) */
+ uint32 PAD[3];
+ uint32 sbadmatch3; /* address match3 */
+ uint32 PAD;
+ uint32 sbadmatch2; /* address match2 */
+ uint32 PAD;
+ uint32 sbadmatch1; /* address match1 */
+ uint32 PAD[7];
+ uint32 sbimstate; /* initiator agent state */
+ uint32 sbintvec; /* interrupt mask */
+ uint32 sbtmstatelow; /* target state */
+ uint32 sbtmstatehigh; /* target state */
+ uint32 sbbwa0; /* bandwidth allocation table0 */
+ uint32 PAD;
+ uint32 sbimconfiglow; /* initiator configuration */
+ uint32 sbimconfighigh; /* initiator configuration */
+ uint32 sbadmatch0; /* address match0 */
+ uint32 PAD;
+ uint32 sbtmconfiglow; /* target configuration */
+ uint32 sbtmconfighigh; /* target configuration */
+ uint32 sbbconfig; /* broadcast configuration */
+ uint32 PAD;
+ uint32 sbbstate; /* broadcast state */
+ uint32 PAD[3];
+ uint32 sbactcnfg; /* activate configuration */
+ uint32 PAD[3];
+ uint32 sbflagst; /* current sbflags */
+ uint32 PAD[3];
+ uint32 sbidlow; /* identification */
+ uint32 sbidhigh; /* identification */
+} sbconfig_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* sbipsflag */
+#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */
+#define SBIPS_INT1_SHIFT 0
+#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */
+#define SBIPS_INT2_SHIFT 8
+#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */
+#define SBIPS_INT3_SHIFT 16
+#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */
+#define SBIPS_INT4_SHIFT 24
+
+/* sbtpsflag */
+#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */
+#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */
+
+/* sbtmerrlog */
+#define SBTMEL_CM 0x00000007 /* command */
+#define SBTMEL_CI 0x0000ff00 /* connection id */
+#define SBTMEL_EC 0x0f000000 /* error code */
+#define SBTMEL_ME 0x80000000 /* multiple error */
+
+/* sbimstate */
+#define SBIM_PC 0xf /* pipecount */
+#define SBIM_AP_MASK 0x30 /* arbitration policy */
+#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */
+#define SBIM_AP_TS 0x10 /* use timesliaces only */
+#define SBIM_AP_TK 0x20 /* use token only */
+#define SBIM_AP_RSV 0x30 /* reserved */
+#define SBIM_IBE 0x20000 /* inbanderror */
+#define SBIM_TO 0x40000 /* timeout */
+#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
+#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
+
+/* sbtmstatelow */
+#define SBTML_RESET 0x0001 /* reset */
+#define SBTML_REJ_MASK 0x0006 /* reject field */
+#define SBTML_REJ 0x0002 /* reject */
+#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */
+
+#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */
+
+/* sbtmstatehigh */
+#define SBTMH_SERR 0x0001 /* serror */
+#define SBTMH_INT 0x0002 /* interrupt */
+#define SBTMH_BUSY 0x0004 /* busy */
+#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */
+
+#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */
+
+/* sbbwa0 */
+#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */
+#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */
+#define SBBWA_TAB1_SHIFT 16
+
+/* sbimconfiglow */
+#define SBIMCL_STO_MASK 0x7 /* service timeout */
+#define SBIMCL_RTO_MASK 0x70 /* request timeout */
+#define SBIMCL_RTO_SHIFT 4
+#define SBIMCL_CID_MASK 0xff0000 /* connection id */
+#define SBIMCL_CID_SHIFT 16
+
+/* sbimconfighigh */
+#define SBIMCH_IEM_MASK 0xc /* inband error mode */
+#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */
+#define SBIMCH_TEM_SHIFT 4
+#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */
+#define SBIMCH_BEM_SHIFT 6
+
+/* sbadmatch0 */
+#define SBAM_TYPE_MASK 0x3 /* address type */
+#define SBAM_AD64 0x4 /* reserved */
+#define SBAM_ADINT0_MASK 0xf8 /* type0 size */
+#define SBAM_ADINT0_SHIFT 3
+#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */
+#define SBAM_ADINT1_SHIFT 3
+#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */
+#define SBAM_ADINT2_SHIFT 3
+#define SBAM_ADEN 0x400 /* enable */
+#define SBAM_ADNEG 0x800 /* negative decode */
+#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */
+#define SBAM_BASE0_SHIFT 8
+#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */
+#define SBAM_BASE1_SHIFT 12
+#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */
+#define SBAM_BASE2_SHIFT 16
+
+/* sbtmconfiglow */
+#define SBTMCL_CD_MASK 0xff /* clock divide */
+#define SBTMCL_CO_MASK 0xf800 /* clock offset */
+#define SBTMCL_CO_SHIFT 11
+#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */
+#define SBTMCL_IF_SHIFT 18
+#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */
+#define SBTMCL_IM_SHIFT 24
+
+/* sbtmconfighigh */
+#define SBTMCH_BM_MASK 0x3 /* busy mode */
+#define SBTMCH_RM_MASK 0x3 /* retry mode */
+#define SBTMCH_RM_SHIFT 2
+#define SBTMCH_SM_MASK 0x30 /* stop mode */
+#define SBTMCH_SM_SHIFT 4
+#define SBTMCH_EM_MASK 0x300 /* sb error mode */
+#define SBTMCH_EM_SHIFT 8
+#define SBTMCH_IM_MASK 0xc00 /* int mode */
+#define SBTMCH_IM_SHIFT 10
+
+/* sbbconfig */
+#define SBBC_LAT_MASK 0x3 /* sb latency */
+#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */
+#define SBBC_MAX0_SHIFT 16
+#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */
+#define SBBC_MAX1_SHIFT 20
+
+/* sbbstate */
+#define SBBS_SRD 0x1 /* st reg disable */
+#define SBBS_HRD 0x2 /* hold reg disable */
+
+/* sbidlow */
+#define SBIDL_CS_MASK 0x3 /* config space */
+#define SBIDL_AR_MASK 0x38 /* # address ranges supported */
+#define SBIDL_AR_SHIFT 3
+#define SBIDL_SYNCH 0x40 /* sync */
+#define SBIDL_INIT 0x80 /* initiator */
+#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */
+#define SBIDL_MINLAT_SHIFT 8
+#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */
+#define SBIDL_MAXLAT_SHIFT 12
+#define SBIDL_FIRST 0x10000 /* this initiator is first */
+#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */
+#define SBIDL_CW_SHIFT 18
+#define SBIDL_TP_MASK 0xf00000 /* target ports */
+#define SBIDL_TP_SHIFT 20
+#define SBIDL_IP_MASK 0xf000000 /* initiator ports */
+#define SBIDL_IP_SHIFT 24
+#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */
+#define SBIDL_RV_SHIFT 28
+#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */
+#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */
+
+/* sbidhigh */
+#define SBIDH_RC_MASK 0x000f /* revision code */
+#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
+#define SBIDH_RCE_SHIFT 8
+#define SBCOREREV(sbidh) \
+ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
+#define SBIDH_CC_MASK 0x8ff0 /* core code */
+#define SBIDH_CC_SHIFT 4
+#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
+#define SBIDH_VC_SHIFT 16
+
+#define SB_COMMIT 0xfd8 /* update buffered registers value */
+
+/* vendor codes */
+#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */
+
+#endif /* _SBCONFIG_H */
diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h
new file mode 100644
index 000000000000..598d68b7f88a
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbhnddma.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _sbhnddma_h_
+#define _sbhnddma_h_
+
+/* DMA structure:
+ * support two DMA engines: 32 bits address or 64 bit addressing
+ * basic DMA register set is per channel(transmit or receive)
+ * a pair of channels is defined for convenience
+ */
+
+/* 32 bits addressing */
+
+/* dma registers per channel(xmt or rcv) */
+typedef volatile struct {
+ uint32 control; /* enable, et al */
+ uint32 addr; /* descriptor ring base address (4K aligned) */
+ uint32 ptr; /* last descriptor posted to chip */
+ uint32 status; /* current active descriptor, et al */
+} dma32regs_t;
+
+typedef volatile struct {
+ dma32regs_t xmt; /* dma tx channel */
+ dma32regs_t rcv; /* dma rx channel */
+} dma32regp_t;
+
+typedef volatile struct { /* diag access */
+ uint32 fifoaddr; /* diag address */
+ uint32 fifodatalow; /* low 32bits of data */
+ uint32 fifodatahigh; /* high 32bits of data */
+ uint32 pad; /* reserved */
+} dma32diag_t;
+
+/*
+ * DMA Descriptor
+ * Descriptors are only read by the hardware, never written back.
+ */
+typedef volatile struct {
+ uint32 ctrl; /* misc control bits & bufcount */
+ uint32 addr; /* data buffer address */
+} dma32dd_t;
+
+/*
+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
+ */
+#define D32RINGALIGN_BITS 12
+#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS)
+#define D32RINGALIGN (1 << D32RINGALIGN_BITS)
+
+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t))
+
+/* transmit channel control */
+#define XC_XE ((uint32)1 << 0) /* transmit enable */
+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */
+#define XC_LE ((uint32)1 << 2) /* loopback enable */
+#define XC_FL ((uint32)1 << 4) /* flush request */
+#define XC_PD ((uint32)1 << 11) /* parity check disable */
+#define XC_AE ((uint32)3 << 16) /* address extension bits */
+#define XC_AE_SHIFT 16
+
+/* transmit descriptor table pointer */
+#define XP_LD_MASK 0xfff /* last valid descriptor */
+
+/* transmit channel status */
+#define XS_CD_MASK 0x0fff /* current descriptor pointer */
+#define XS_XS_MASK 0xf000 /* transmit state */
+#define XS_XS_SHIFT 12
+#define XS_XS_DISABLED 0x0000 /* disabled */
+#define XS_XS_ACTIVE 0x1000 /* active */
+#define XS_XS_IDLE 0x2000 /* idle wait */
+#define XS_XS_STOPPED 0x3000 /* stopped */
+#define XS_XS_SUSP 0x4000 /* suspend pending */
+#define XS_XE_MASK 0xf0000 /* transmit errors */
+#define XS_XE_SHIFT 16
+#define XS_XE_NOERR 0x00000 /* no error */
+#define XS_XE_DPE 0x10000 /* descriptor protocol error */
+#define XS_XE_DFU 0x20000 /* data fifo underrun */
+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */
+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */
+#define XS_AD_MASK 0xfff00000 /* active descriptor */
+#define XS_AD_SHIFT 20
+
+/* receive channel control */
+#define RC_RE ((uint32)1 << 0) /* receive enable */
+#define RC_RO_MASK 0xfe /* receive frame offset */
+#define RC_RO_SHIFT 1
+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */
+#define RC_SH ((uint32)1 << 9) /* separate rx header descriptor enable */
+#define RC_OC ((uint32)1 << 10) /* overflow continue */
+#define RC_PD ((uint32)1 << 11) /* parity check disable */
+#define RC_AE ((uint32)3 << 16) /* address extension bits */
+#define RC_AE_SHIFT 16
+
+/* receive descriptor table pointer */
+#define RP_LD_MASK 0xfff /* last valid descriptor */
+
+/* receive channel status */
+#define RS_CD_MASK 0x0fff /* current descriptor pointer */
+#define RS_RS_MASK 0xf000 /* receive state */
+#define RS_RS_SHIFT 12
+#define RS_RS_DISABLED 0x0000 /* disabled */
+#define RS_RS_ACTIVE 0x1000 /* active */
+#define RS_RS_IDLE 0x2000 /* idle wait */
+#define RS_RS_STOPPED 0x3000 /* reserved */
+#define RS_RE_MASK 0xf0000 /* receive errors */
+#define RS_RE_SHIFT 16
+#define RS_RE_NOERR 0x00000 /* no error */
+#define RS_RE_DPE 0x10000 /* descriptor protocol error */
+#define RS_RE_DFO 0x20000 /* data fifo overflow */
+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */
+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */
+#define RS_AD_MASK 0xfff00000 /* active descriptor */
+#define RS_AD_SHIFT 20
+
+/* fifoaddr */
+#define FA_OFF_MASK 0xffff /* offset */
+#define FA_SEL_MASK 0xf0000 /* select */
+#define FA_SEL_SHIFT 16
+#define FA_SEL_XDD 0x00000 /* transmit dma data */
+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */
+#define FA_SEL_RDD 0x40000 /* receive dma data */
+#define FA_SEL_RDP 0x50000 /* receive dma pointers */
+#define FA_SEL_XFD 0x80000 /* transmit fifo data */
+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */
+#define FA_SEL_RFD 0xc0000 /* receive fifo data */
+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */
+#define FA_SEL_RSD 0xe0000 /* receive frame status data */
+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
+
+/* descriptor control flags */
+#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */
+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
+#define CTRL_AE_SHIFT 16
+#define CTRL_PARITY ((uint32)3 << 18) /* parity bit */
+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */
+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */
+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */
+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */
+
+/* control flags in the range [27:20] are core-specific and not defined here */
+#define CTRL_CORE_MASK 0x0ff00000
+
+/* 64 bits addressing */
+
+/* dma registers per channel(xmt or rcv) */
+typedef volatile struct {
+ uint32 control; /* enable, et al */
+ uint32 ptr; /* last descriptor posted to chip */
+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
+ uint32 status0; /* current descriptor, xmt state */
+ uint32 status1; /* active descriptor, xmt error */
+} dma64regs_t;
+
+typedef volatile struct {
+ dma64regs_t tx; /* dma64 tx channel */
+ dma64regs_t rx; /* dma64 rx channel */
+} dma64regp_t;
+
+typedef volatile struct { /* diag access */
+ uint32 fifoaddr; /* diag address */
+ uint32 fifodatalow; /* low 32bits of data */
+ uint32 fifodatahigh; /* high 32bits of data */
+ uint32 pad; /* reserved */
+} dma64diag_t;
+
+/*
+ * DMA Descriptor
+ * Descriptors are only read by the hardware, never written back.
+ */
+typedef volatile struct {
+ uint32 ctrl1; /* misc control bits & bufcount */
+ uint32 ctrl2; /* buffer count and address extension */
+ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */
+ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */
+} dma64dd_t;
+
+/*
+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
+ */
+#define D64RINGALIGN_BITS 13
+#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS)
+#define D64RINGALIGN (1 << D64RINGALIGN_BITS)
+
+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
+
+/* transmit channel control */
+#define D64_XC_XE 0x00000001 /* transmit enable */
+#define D64_XC_SE 0x00000002 /* transmit suspend request */
+#define D64_XC_LE 0x00000004 /* loopback enable */
+#define D64_XC_FL 0x00000010 /* flush request */
+#define D64_XC_PD 0x00000800 /* parity check disable */
+#define D64_XC_AE 0x00030000 /* address extension bits */
+#define D64_XC_AE_SHIFT 16
+
+/* transmit descriptor table pointer */
+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
+
+/* transmit channel status */
+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
+#define D64_XS0_XS_SHIFT 28
+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
+
+#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */
+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
+#define D64_XS1_XE_SHIFT 28
+#define D64_XS1_XE_NOERR 0x00000000 /* no error */
+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
+#define D64_XS1_XE_COREE 0x50000000 /* core error */
+
+/* receive channel control */
+#define D64_RC_RE 0x00000001 /* receive enable */
+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
+#define D64_RC_RO_SHIFT 1
+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
+#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */
+#define D64_RC_OC 0x00000400 /* overflow continue */
+#define D64_RC_PD 0x00000800 /* parity check disable */
+#define D64_RC_AE 0x00030000 /* address extension bits */
+#define D64_RC_AE_SHIFT 16
+
+/* flags for dma controller */
+#define DMA_CTRL_PEN (1 << 0) /* partity enable */
+#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */
+#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */
+#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */
+
+/* receive descriptor table pointer */
+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
+
+/* receive channel status */
+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
+#define D64_RS0_RS_SHIFT 28
+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
+
+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
+#define D64_RS1_RE_SHIFT 28
+#define D64_RS1_RE_NOERR 0x00000000 /* no error */
+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
+#define D64_RS1_RE_COREE 0x50000000 /* core error */
+
+/* fifoaddr */
+#define D64_FA_OFF_MASK 0xffff /* offset */
+#define D64_FA_SEL_MASK 0xf0000 /* select */
+#define D64_FA_SEL_SHIFT 16
+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
+
+/* descriptor control flags 1 */
+#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */
+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
+
+/* descriptor control flags 2 */
+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */
+#define D64_CTRL2_AE 0x00030000 /* address extension bits */
+#define D64_CTRL2_AE_SHIFT 16
+#define D64_CTRL2_PARITY 0x00040000 /* parity bit */
+
+/* control flags in the range [27:20] are core-specific and not defined here */
+#define D64_CTRL_CORE_MASK 0x0ff00000
+
+#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */
+#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */
+#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */
+#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */
+
+/* receive frame status */
+typedef volatile struct {
+ uint16 len;
+ uint16 flags;
+} dma_rxh_t;
+
+#endif /* _sbhnddma_h_ */
diff --git a/drivers/staging/brcm80211/include/sbhndpio.h b/drivers/staging/brcm80211/include/sbhndpio.h
new file mode 100644
index 000000000000..e64f6aaef3c6
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbhndpio.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _sbhndpio_h_
+#define _sbhndpio_h_
+
+/* PIO structure,
+ * support two PIO format: 2 bytes access and 4 bytes access
+ * basic FIFO register set is per channel(transmit or receive)
+ * a pair of channels is defined for convenience
+ */
+
+/* 2byte-wide pio register set per channel(xmt or rcv) */
+typedef volatile struct {
+ uint16 fifocontrol;
+ uint16 fifodata;
+ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */
+ uint16 PAD;
+} pio2regs_t;
+
+/* a pair of pio channels(tx and rx) */
+typedef volatile struct {
+ pio2regs_t tx;
+ pio2regs_t rx;
+} pio2regp_t;
+
+/* 4byte-wide pio register set per channel(xmt or rcv) */
+typedef volatile struct {
+ uint32 fifocontrol;
+ uint32 fifodata;
+} pio4regs_t;
+
+/* a pair of pio channels(tx and rx) */
+typedef volatile struct {
+ pio4regs_t tx;
+ pio4regs_t rx;
+} pio4regp_t;
+
+#endif /* _sbhndpio_h_ */
diff --git a/drivers/staging/brcm80211/include/sbpcmcia.h b/drivers/staging/brcm80211/include/sbpcmcia.h
new file mode 100644
index 000000000000..6b9923f551a9
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbpcmcia.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SBPCMCIA_H
+#define _SBPCMCIA_H
+
+/* All the addresses that are offsets in attribute space are divided
+ * by two to account for the fact that odd bytes are invalid in
+ * attribute space and our read/write routines make the space appear
+ * as if they didn't exist. Still we want to show the original numbers
+ * as documented in the hnd_pcmcia core manual.
+ */
+
+/* PCMCIA Function Configuration Registers */
+#define PCMCIA_FCR (0x700 / 2)
+
+#define FCR0_OFF 0
+#define FCR1_OFF (0x40 / 2)
+#define FCR2_OFF (0x80 / 2)
+#define FCR3_OFF (0xc0 / 2)
+
+#define PCMCIA_FCR0 (0x700 / 2)
+#define PCMCIA_FCR1 (0x740 / 2)
+#define PCMCIA_FCR2 (0x780 / 2)
+#define PCMCIA_FCR3 (0x7c0 / 2)
+
+/* Standard PCMCIA FCR registers */
+
+#define PCMCIA_COR 0
+
+#define COR_RST 0x80
+#define COR_LEV 0x40
+#define COR_IRQEN 0x04
+#define COR_BLREN 0x01
+#define COR_FUNEN 0x01
+
+#define PCICIA_FCSR (2 / 2)
+#define PCICIA_PRR (4 / 2)
+#define PCICIA_SCR (6 / 2)
+#define PCICIA_ESR (8 / 2)
+
+#define PCM_MEMOFF 0x0000
+#define F0_MEMOFF 0x1000
+#define F1_MEMOFF 0x2000
+#define F2_MEMOFF 0x3000
+#define F3_MEMOFF 0x4000
+
+/* Memory base in the function fcr's */
+#define MEM_ADDR0 (0x728 / 2)
+#define MEM_ADDR1 (0x72a / 2)
+#define MEM_ADDR2 (0x72c / 2)
+
+/* PCMCIA base plus Srom access in fcr0: */
+#define PCMCIA_ADDR0 (0x072e / 2)
+#define PCMCIA_ADDR1 (0x0730 / 2)
+#define PCMCIA_ADDR2 (0x0732 / 2)
+
+#define MEM_SEG (0x0734 / 2)
+#define SROM_CS (0x0736 / 2)
+#define SROM_DATAL (0x0738 / 2)
+#define SROM_DATAH (0x073a / 2)
+#define SROM_ADDRL (0x073c / 2)
+#define SROM_ADDRH (0x073e / 2)
+#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */
+#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */
+
+/* Values for srom_cs: */
+#define SROM_IDLE 0
+#define SROM_WRITE 1
+#define SROM_READ 2
+#define SROM_WEN 4
+#define SROM_WDS 7
+#define SROM_DONE 8
+
+/* Fields in srom_info: */
+#define SRI_SZ_MASK 0x03
+#define SRI_BLANK 0x04
+#define SRI_OTP 0x80
+
+#if !defined(ESTA_POSTMOGRIFY_REMOVAL)
+/* CIS stuff */
+
+/* The CIS stops where the FCRs start */
+#define CIS_SIZE PCMCIA_FCR
+
+/* CIS tuple length field max */
+#define CIS_TUPLE_LEN_MAX 0xff
+
+/* Standard tuples we know about */
+
+#define CISTPL_NULL 0x00
+#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */
+#define CISTPL_MANFID 0x20 /* Manufacturer and device id */
+#define CISTPL_FUNCID 0x21 /* Function identification */
+#define CISTPL_FUNCE 0x22 /* Function extensions */
+#define CISTPL_CFTABLE 0x1b /* Config table entry */
+#define CISTPL_END 0xff /* End of the CIS tuple chain */
+
+/* Function identifier provides context for the function extentions tuple */
+#define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */
+
+/* Function extensions for LANs (assumed for extensions other than SDIO) */
+#define LAN_TECH 1 /* Technology type */
+#define LAN_SPEED 2 /* Raw bit rate */
+#define LAN_MEDIA 3 /* Transmission media */
+#define LAN_NID 4 /* Node identification (aka MAC addr) */
+#define LAN_CONN 5 /* Connector standard */
+
+/* CFTable */
+#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */
+#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */
+#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */
+
+/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll
+ * take one for HNBU, and use "extensions" (a la FUNCE) within it.
+ */
+
+#define CISTPL_BRCM_HNBU 0x80
+
+/* Subtypes of BRCM_HNBU: */
+
+#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */
+#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */
+#define HNBU_BOARDREV 0x02 /* One byte board revision */
+#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1)
+ * or 9 (sromrev > 1) bytes
+ */
+#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */
+#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */
+#define HNBU_AA 0x06 /* Antennas available */
+#define HNBU_AG 0x07 /* Antenna gain */
+#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */
+#define HNBU_LEDS 0x09 /* LED set */
+#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl)
+ * in rev 2
+ */
+#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */
+#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */
+#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */
+#define HNBU_PAPARMS5G 0x0e /* 5G PA params */
+#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */
+#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */
+#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch,
+ * 2 bytes, rev 3.
+ */
+#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch,
+ * 2 bytes, rev 3.
+ */
+#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */
+#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */
+#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */
+#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */
+#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */
+#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */
+#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */
+#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */
+#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */
+#define HNBU_LEDDC 0x1c /* 2 bytes; LED duty cycle */
+#define HNBU_HNBUCIS 0x1d /* what follows is proprietary HNBU CIS format */
+#define HNBU_PAPARMS_SSLPNPHY 0x1e /* SSLPNPHY PA params */
+#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f /* SSLPNPHY RSSI mid pt sel & board switch arch */
+#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */
+#define HNBU_CHAINSWITCH 0x21 /* 2 byte; txchain, rxchain */
+#define HNBU_REGREV 0x22 /* 1 byte; */
+#define HNBU_FEM 0x23 /* 2 or 4 byte: 11n frontend specification */
+#define HNBU_PAPARMS_C0 0x24 /* 8 or 30 bytes: 11n pa paramater for chain 0 */
+#define HNBU_PAPARMS_C1 0x25 /* 8 or 30 bytes: 11n pa paramater for chain 1 */
+#define HNBU_PAPARMS_C2 0x26 /* 8 or 30 bytes: 11n pa paramater for chain 2 */
+#define HNBU_PAPARMS_C3 0x27 /* 8 or 30 bytes: 11n pa paramater for chain 3 */
+#define HNBU_PO_CCKOFDM 0x28 /* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */
+#define HNBU_PO_MCS2G 0x29 /* 8 bytes: mcs2g power offset */
+#define HNBU_PO_MCS5GM 0x2a /* 8 bytes: mcs5g mid band power offset */
+#define HNBU_PO_MCS5GLH 0x2b /* 16 bytes: mcs5g low-high band power offset */
+#define HNBU_PO_CDD 0x2c /* 2 bytes: cdd2g/5g power offset */
+#define HNBU_PO_STBC 0x2d /* 2 bytes: stbc2g/5g power offset */
+#define HNBU_PO_40M 0x2e /* 2 bytes: 40Mhz channel 2g/5g power offset */
+#define HNBU_PO_40MDUP 0x2f /* 2 bytes: 40Mhz channel dup 2g/5g power offset */
+
+#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */
+#define HNBU_WPS 0x31 /* 1 byte; GPIO pin for WPS button */
+#define HNBU_USBFS 0x32 /* 1 byte; 1 = USB advertises FS mode only */
+#define HNBU_BRMIN 0x33 /* 4 byte bootloader min resource mask */
+#define HNBU_BRMAX 0x34 /* 4 byte bootloader max resource mask */
+#define HNBU_PATCH 0x35 /* bootloader patch addr(2b) & data(4b) pair */
+#define HNBU_CCKFILTTYPE 0x36 /* CCK digital filter selection options */
+#define HNBU_OFDMPO5G 0x37 /* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */
+
+#define HNBU_USBEPNUM 0x40 /* USB endpoint numbers */
+#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8
+ * plus extra info appended.
+ */
+#define HNBU_RESERVED 0x81 /* Reserved for non-BRCM post-mfg additions */
+#define HNBU_CUSTOM1 0x82 /* 4 byte; For non-BRCM post-mfg additions */
+#define HNBU_CUSTOM2 0x83 /* Reserved; For non-BRCM post-mfg additions */
+#endif /* !defined(ESTA_POSTMOGRIFY_REMOVAL) */
+
+/* sbtmstatelow */
+#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */
+#define SBTML_INT_EN 0x20000 /* enable sb interrupt */
+
+/* sbtmstatehigh */
+#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */
+
+#endif /* _SBPCMCIA_H */
diff --git a/drivers/staging/brcm80211/include/sbsdio.h b/drivers/staging/brcm80211/include/sbsdio.h
new file mode 100644
index 000000000000..6afdbbe67e19
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbsdio.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SBSDIO_H
+#define _SBSDIO_H
+
+#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */
+
+/* function 1 miscellaneous registers */
+#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */
+#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */
+#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */
+#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */
+#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */
+#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */
+#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */
+#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */
+#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */
+#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
+
+/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
+#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */
+#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */
+#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */
+#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */
+#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */
+#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */
+#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */
+#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */
+#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */
+#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */
+
+#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
+#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
+
+/* SBSDIO_SPROM_CS */
+#define SBSDIO_SPROM_IDLE 0
+#define SBSDIO_SPROM_WRITE 1
+#define SBSDIO_SPROM_READ 2
+#define SBSDIO_SPROM_WEN 4
+#define SBSDIO_SPROM_WDS 7
+#define SBSDIO_SPROM_DONE 8
+
+/* SBSDIO_SPROM_INFO */
+#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */
+#define SROM_BLANK 0x04 /* depreciated in corerev 6 */
+#define SROM_OTP 0x80 /* OTP present */
+
+/* SBSDIO_CHIP_CTRL */
+#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu,
+ * 1: power on oscillator
+ * (for 4318 only)
+ */
+/* SBSDIO_WATERMARK */
+#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device
+ * to wait before sending data to host
+ */
+
+/* SBSDIO_DEVICE_CTL */
+#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when
+ * receiving CMD53
+ */
+#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is
+ * synchronous to the sdio clock
+ */
+#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host
+ * except the chipActive (rev 8)
+ */
+#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put
+ * external pads in tri-state; requires
+ * sdio bus power cycle to clear (rev 9)
+ */
+#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */
+#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */
+#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */
+#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */
+
+/* SBSDIO_FUNC1_CHIPCLKCSR */
+#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */
+#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */
+#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */
+#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */
+#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */
+#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */
+#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */
+#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */
+/* In rev8, actual avail bits followed original docs */
+#define SBSDIO_Rev8_HT_AVAIL 0x40
+#define SBSDIO_Rev8_ALP_AVAIL 0x80
+
+#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
+#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
+#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
+#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
+#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \
+ (alponly ? 1 : SBSDIO_HTAV(regval)))
+
+/* SBSDIO_FUNC1_SDIOPULLUP */
+#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */
+#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */
+#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */
+#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */
+#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */
+
+/* function 1 OCP space */
+#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */
+#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
+#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */
+
+/* some duplication with sbsdpcmdev.h here */
+/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
+#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
+#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
+#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */
+
+/* direct(mapped) cis space */
+#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */
+#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */
+#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */
+
+#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */
+
+#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple,
+ * link bytes
+ */
+
+/* indirect cis access (in sprom) */
+#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from
+ * 8th byte
+ */
+
+#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one
+ * data comamnd
+ */
+
+#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */
+
+#endif /* _SBSDIO_H */
diff --git a/drivers/staging/brcm80211/include/sbsdpcmdev.h b/drivers/staging/brcm80211/include/sbsdpcmdev.h
new file mode 100644
index 000000000000..d07a13cd5513
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbsdpcmdev.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _sbsdpcmdev_h_
+#define _sbsdpcmdev_h_
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+typedef volatile struct {
+ dma64regs_t xmt; /* dma tx */
+ uint32 PAD[2];
+ dma64regs_t rcv; /* dma rx */
+ uint32 PAD[2];
+} dma64p_t;
+
+/* dma64 sdiod corerev >= 1 */
+typedef volatile struct {
+ dma64p_t dma64regs[2];
+ dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */
+ uint32 PAD[92];
+} sdiodma64_t;
+
+/* dma32 sdiod corerev == 0 */
+typedef volatile struct {
+ dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */
+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */
+ uint32 PAD[108];
+} sdiodma32_t;
+
+/* dma32 regs for pcmcia core */
+typedef volatile struct {
+ dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */
+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */
+ uint32 PAD[116];
+} pcmdma32_t;
+
+/* core registers */
+typedef volatile struct {
+ uint32 corecontrol; /* CoreControl, 0x000, rev8 */
+ uint32 corestatus; /* CoreStatus, 0x004, rev8 */
+ uint32 PAD[1];
+ uint32 biststatus; /* BistStatus, 0x00c, rev8 */
+
+ /* PCMCIA access */
+ uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */
+ uint16 PAD[1];
+
+ /* interrupt */
+ uint32 intstatus; /* IntStatus, 0x020, rev8 */
+ uint32 hostintmask; /* IntHostMask, 0x024, rev8 */
+ uint32 intmask; /* IntSbMask, 0x028, rev8 */
+ uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */
+ uint32 sbintmask; /* SBIntMask, 0x030, rev8 */
+ uint32 funcintmask; /* SDIO Function Interrupt Mask, SDIO rev4 */
+ uint32 PAD[2];
+ uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */
+ uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */
+ uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */
+ uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */
+
+ /* synchronized access to registers in SDIO clock domain */
+ uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */
+ uint32 PAD[3];
+
+ /* PCMCIA frame control */
+ uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */
+ uint8 PAD[3];
+ uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */
+ uint8 PAD[155];
+
+ /* interrupt batching control */
+ uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */
+ uint32 PAD[3];
+
+ /* counters */
+ uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */
+ uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */
+ uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */
+ uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */
+ uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */
+ uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */
+ uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */
+ uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */
+ uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */
+ uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */
+ uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */
+ uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */
+ uint32 PAD[40];
+ uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */
+ uint32 PAD[7];
+
+ /* DMA engines */
+ volatile union {
+ pcmdma32_t pcm32;
+ sdiodma32_t sdiod32;
+ sdiodma64_t sdiod64;
+ } dma;
+
+ /* SDIO/PCMCIA CIS region */
+ char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */
+
+ /* PCMCIA function control registers */
+ char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */
+ uint16 PAD[55];
+
+ /* PCMCIA backplane access */
+ uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */
+ uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */
+ uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */
+ uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */
+ uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */
+ uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */
+ uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */
+ uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */
+ uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */
+ uint16 PAD[31];
+
+ /* sprom "size" & "blank" info */
+ uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */
+ uint32 PAD[464];
+
+ /* Sonics SiliconBackplane registers */
+ sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */
+} sdpcmd_regs_t;
+
+/* corecontrol */
+#define CC_CISRDY (1 << 0) /* CIS Ready */
+#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */
+#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */
+#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */
+#define CC_XMTDATAAVAIL_MODE (1 << 4) /* data avail generates an interrupt */
+#define CC_XMTDATAAVAIL_CTRL (1 << 5) /* data avail interrupt ctrl */
+
+/* corestatus */
+#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */
+#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */
+#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */
+
+#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */
+#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */
+#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */
+#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */
+
+/* intstatus */
+#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
+#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
+#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */
+#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */
+#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */
+#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */
+#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */
+#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */
+#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */
+#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */
+#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */
+#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */
+#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */
+#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */
+#define I_PC (1 << 10) /* descriptor error */
+#define I_PD (1 << 11) /* data error */
+#define I_DE (1 << 12) /* Descriptor protocol Error */
+#define I_RU (1 << 13) /* Receive descriptor Underflow */
+#define I_RO (1 << 14) /* Receive fifo Overflow */
+#define I_XU (1 << 15) /* Transmit fifo Underflow */
+#define I_RI (1 << 16) /* Receive Interrupt */
+#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */
+#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
+#define I_XI (1 << 24) /* Transmit Interrupt */
+#define I_RF_TERM (1 << 25) /* Read Frame Terminate */
+#define I_WF_TERM (1 << 26) /* Write Frame Terminate */
+#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */
+#define I_SBINT (1 << 28) /* sbintstatus Interrupt */
+#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */
+#define I_SRESET (1 << 30) /* CCCR RES interrupt */
+#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */
+#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */
+#define I_DMA (I_RI | I_XI | I_ERRORS)
+
+/* sbintstatus */
+#define I_SB_SERR (1 << 8) /* Backplane SError (write) */
+#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */
+#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */
+
+/* sdioaccess */
+#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */
+#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */
+#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */
+#define SDA_WRITE 0x01000000 /* Write bit */
+#define SDA_READ 0x00000000 /* Write bit cleared for Read */
+#define SDA_BUSY 0x80000000 /* Busy bit */
+
+/* sdioaccess-accessible register address spaces */
+#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */
+#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */
+#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */
+#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */
+
+/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */
+#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */
+#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */
+#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */
+#define SDA_DEVICECONTROL 0x009 /* DeviceControl */
+#define SDA_SBADDRLOW 0x00a /* SbAddrLow */
+#define SDA_SBADDRMID 0x00b /* SbAddrMid */
+#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */
+#define SDA_FRAMECTRL 0x00d /* FrameCtrl */
+#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */
+#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */
+#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */
+#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */
+#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */
+#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */
+
+/* SDA_F2WATERMARK */
+#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */
+
+/* SDA_SBADDRLOW */
+#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */
+
+/* SDA_SBADDRMID */
+#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */
+
+/* SDA_SBADDRHIGH */
+#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */
+
+/* SDA_FRAMECTRL */
+#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
+#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
+#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */
+#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */
+
+/* pcmciaframectrl */
+#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */
+#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */
+
+/* intrcvlazy */
+#define IRL_TO_MASK 0x00ffffff /* timeout */
+#define IRL_FC_MASK 0xff000000 /* frame count */
+#define IRL_FC_SHIFT 24 /* frame count */
+
+/* rx header */
+typedef volatile struct {
+ uint16 len;
+ uint16 flags;
+} sdpcmd_rxh_t;
+
+/* rx header flags */
+#define RXF_CRC 0x0001 /* CRC error detected */
+#define RXF_WOOS 0x0002 /* write frame out of sync */
+#define RXF_WF_TERM 0x0004 /* write frame terminated */
+#define RXF_ABORT 0x0008 /* write frame aborted */
+#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */
+
+/* HW frame tag */
+#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */
+
+#endif /* _sbsdpcmdev_h_ */
diff --git a/drivers/staging/brcm80211/include/sbsocram.h b/drivers/staging/brcm80211/include/sbsocram.h
new file mode 100644
index 000000000000..7b09be9d58b6
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sbsocram.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SBSOCRAM_H
+#define _SBSOCRAM_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+/* Memcsocram core registers */
+typedef volatile struct sbsocramregs {
+ uint32 coreinfo;
+ uint32 bwalloc;
+ uint32 extracoreinfo;
+ uint32 biststat;
+ uint32 bankidx;
+ uint32 standbyctrl;
+
+ uint32 errlogstatus; /* rev 6 */
+ uint32 errlogaddr; /* rev 6 */
+ /* used for patching rev 3 & 5 */
+ uint32 cambankidx;
+ uint32 cambankstandbyctrl;
+ uint32 cambankpatchctrl;
+ uint32 cambankpatchtblbaseaddr;
+ uint32 cambankcmdreg;
+ uint32 cambankdatareg;
+ uint32 cambankmaskreg;
+ uint32 PAD[1];
+ uint32 bankinfo; /* corev 8 */
+ uint32 PAD[15];
+ uint32 extmemconfig;
+ uint32 extmemparitycsr;
+ uint32 extmemparityerrdata;
+ uint32 extmemparityerrcnt;
+ uint32 extmemwrctrlandsize;
+ uint32 PAD[84];
+ uint32 workaround;
+ uint32 pwrctl; /* corerev >= 2 */
+} sbsocramregs_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* Register offsets */
+#define SR_COREINFO 0x00
+#define SR_BWALLOC 0x04
+#define SR_BISTSTAT 0x0c
+#define SR_BANKINDEX 0x10
+#define SR_BANKSTBYCTL 0x14
+#define SR_PWRCTL 0x1e8
+
+/* Coreinfo register */
+#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */
+#define SRCI_PT_SHIFT 16
+/* port types : SRCI_PT_<processorPT>_<backplanePT> */
+#define SRCI_PT_OCP_OCP 0
+#define SRCI_PT_AXI_OCP 1
+#define SRCI_PT_ARM7AHB_OCP 2
+#define SRCI_PT_CM3AHB_OCP 3
+#define SRCI_PT_AXI_AXI 4
+#define SRCI_PT_AHB_AXI 5
+/* corerev >= 3 */
+#define SRCI_LSS_MASK 0x00f00000
+#define SRCI_LSS_SHIFT 20
+#define SRCI_LRS_MASK 0x0f000000
+#define SRCI_LRS_SHIFT 24
+
+/* In corerev 0, the memory size is 2 to the power of the
+ * base plus 16 plus to the contents of the memsize field plus 1.
+ */
+#define SRCI_MS0_MASK 0xf
+#define SR_MS0_BASE 16
+
+/*
+ * In corerev 1 the bank size is 2 ^ the bank size field plus 14,
+ * the memory size is number of banks times bank size.
+ * The same applies to rom size.
+ */
+#define SRCI_ROMNB_MASK 0xf000
+#define SRCI_ROMNB_SHIFT 12
+#define SRCI_ROMBSZ_MASK 0xf00
+#define SRCI_ROMBSZ_SHIFT 8
+#define SRCI_SRNB_MASK 0xf0
+#define SRCI_SRNB_SHIFT 4
+#define SRCI_SRBSZ_MASK 0xf
+#define SRCI_SRBSZ_SHIFT 0
+
+#define SR_BSZ_BASE 14
+
+/* Standby control register */
+#define SRSC_SBYOVR_MASK 0x80000000
+#define SRSC_SBYOVR_SHIFT 31
+#define SRSC_SBYOVRVAL_MASK 0x60000000
+#define SRSC_SBYOVRVAL_SHIFT 29
+#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */
+#define SRSC_SBYEN_SHIFT 24
+
+/* Power control register */
+#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */
+#define SRPC_PMU_STBYDIS_SHIFT 4
+#define SRPC_STBYOVRVAL_MASK 0x00000008
+#define SRPC_STBYOVRVAL_SHIFT 3
+#define SRPC_STBYOVR_MASK 0x00000007
+#define SRPC_STBYOVR_SHIFT 0
+
+/* Extra core capability register */
+#define SRECC_NUM_BANKS_MASK 0x000000F0
+#define SRECC_NUM_BANKS_SHIFT 4
+#define SRECC_BANKSIZE_MASK 0x0000000F
+#define SRECC_BANKSIZE_SHIFT 0
+
+#define SRECC_BANKSIZE(value) (1 << (value))
+
+/* CAM bank patch control */
+#define SRCBPC_PATCHENABLE 0x80000000
+
+#define SRP_ADDRESS 0x0001FFFC
+#define SRP_VALID 0x8000
+
+/* CAM bank command reg */
+#define SRCMD_WRITE 0x00020000
+#define SRCMD_READ 0x00010000
+#define SRCMD_DONE 0x80000000
+
+#define SRCMD_DONE_DLY 1000
+
+/* bankidx and bankinfo reg defines corerev >= 8 */
+#define SOCRAM_BANKINFO_SZMASK 0x3f
+#define SOCRAM_BANKIDX_ROM_MASK 0x100
+
+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8
+/* socram bankinfo memtype */
+#define SOCRAM_MEMTYPE_RAM 0
+#define SOCRAM_MEMTYPE_R0M 1
+#define SOCRAM_MEMTYPE_DEVRAM 2
+
+#define SOCRAM_BANKINFO_REG 0x40
+#define SOCRAM_BANKIDX_REG 0x10
+#define SOCRAM_BANKINFO_STDBY_MASK 0x400
+#define SOCRAM_BANKINFO_STDBY_TIMER 0x800
+
+/* bankinfo rev >= 10 */
+#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13
+#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000
+#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14
+#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000
+
+/* extracoreinfo register */
+#define SOCRAM_DEVRAMBANK_MASK 0xF000
+#define SOCRAM_DEVRAMBANK_SHIFT 12
+
+/* bank info to calculate bank size */
+#define SOCRAM_BANKINFO_SZBASE 8192
+#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */
+
+#endif /* _SBSOCRAM_H */
diff --git a/drivers/staging/brcm80211/include/sdio.h b/drivers/staging/brcm80211/include/sdio.h
new file mode 100644
index 000000000000..8769c45d4d1f
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sdio.h
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SDIO_H
+#define _SDIO_H
+
+#ifdef BCMSDIO
+
+/* CCCR structure for function 0 */
+typedef volatile struct {
+ uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */
+ uint8 sd_rev; /* RO, sd spec revision */
+ uint8 io_en; /* I/O enable */
+ uint8 io_rdy; /* I/O ready reg */
+ uint8 intr_ctl; /* Master and per function interrupt enable control */
+ uint8 intr_status; /* RO, interrupt pending status */
+ uint8 io_abort; /* read/write abort or reset all functions */
+ uint8 bus_inter; /* bus interface control */
+ uint8 capability; /* RO, card capability */
+
+ uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */
+ uint8 cis_base_mid;
+ uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */
+
+ /* suspend/resume registers */
+ uint8 bus_suspend; /* 0xC */
+ uint8 func_select; /* 0xD */
+ uint8 exec_flag; /* 0xE */
+ uint8 ready_flag; /* 0xF */
+
+ uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */
+
+ uint8 power_control; /* 0x12 (SDIO version 1.10) */
+
+ uint8 speed_control; /* 0x13 */
+} sdio_regs_t;
+
+/* SDIO Device CCCR offsets */
+#define SDIOD_CCCR_REV 0x00
+#define SDIOD_CCCR_SDREV 0x01
+#define SDIOD_CCCR_IOEN 0x02
+#define SDIOD_CCCR_IORDY 0x03
+#define SDIOD_CCCR_INTEN 0x04
+#define SDIOD_CCCR_INTPEND 0x05
+#define SDIOD_CCCR_IOABORT 0x06
+#define SDIOD_CCCR_BICTRL 0x07
+#define SDIOD_CCCR_CAPABLITIES 0x08
+#define SDIOD_CCCR_CISPTR_0 0x09
+#define SDIOD_CCCR_CISPTR_1 0x0A
+#define SDIOD_CCCR_CISPTR_2 0x0B
+#define SDIOD_CCCR_BUSSUSP 0x0C
+#define SDIOD_CCCR_FUNCSEL 0x0D
+#define SDIOD_CCCR_EXECFLAGS 0x0E
+#define SDIOD_CCCR_RDYFLAGS 0x0F
+#define SDIOD_CCCR_BLKSIZE_0 0x10
+#define SDIOD_CCCR_BLKSIZE_1 0x11
+#define SDIOD_CCCR_POWER_CONTROL 0x12
+#define SDIOD_CCCR_SPEED_CONTROL 0x13
+
+/* Broadcom extensions (corerev >= 1) */
+#define SDIOD_CCCR_BRCM_SEPINT 0xf2
+
+/* cccr_sdio_rev */
+#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */
+#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */
+
+/* sd_rev */
+#define SD_REV_PHY_MASK 0x0f /* SD format version number */
+
+/* io_en */
+#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */
+#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */
+
+/* io_rdys */
+#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */
+#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */
+
+/* intr_ctl */
+#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */
+#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */
+#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */
+
+/* intr_status */
+#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */
+#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */
+
+/* io_abort */
+#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */
+#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */
+
+/* bus_inter */
+#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */
+#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */
+#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */
+#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */
+#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */
+#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */
+
+/* capability */
+#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */
+#define SDIO_CAP_LSC 0x40 /* low speed card */
+#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */
+#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */
+#define SDIO_CAP_SBS 0x08 /* support suspend/resume */
+#define SDIO_CAP_SRW 0x04 /* support read wait */
+#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */
+#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */
+
+/* power_control */
+#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */
+#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */
+
+/* speed_control (control device entry into high-speed clocking mode) */
+#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */
+#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */
+
+/* brcm sepint */
+#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */
+#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */
+#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */
+
+/* FBR structure for function 1-7, FBR addresses and register offsets */
+typedef volatile struct {
+ uint8 devctr; /* device interface, CSA control */
+ uint8 ext_dev; /* extended standard I/O device type code */
+ uint8 pwr_sel; /* power selection support */
+ uint8 PAD[6]; /* reserved */
+
+ uint8 cis_low; /* CIS LSB */
+ uint8 cis_mid;
+ uint8 cis_high; /* CIS MSB */
+ uint8 csa_low; /* code storage area, LSB */
+ uint8 csa_mid;
+ uint8 csa_high; /* code storage area, MSB */
+ uint8 csa_dat_win; /* data access window to function */
+
+ uint8 fnx_blk_size[2]; /* block size, little endian */
+} sdio_fbr_t;
+
+/* Maximum number of I/O funcs */
+#define SDIOD_MAX_IOFUNCS 7
+
+/* SDIO Device FBR Start Address */
+#define SDIOD_FBR_STARTADDR 0x100
+
+/* SDIO Device FBR Size */
+#define SDIOD_FBR_SIZE 0x100
+
+/* Macro to calculate FBR register base */
+#define SDIOD_FBR_BASE(n) ((n) * 0x100)
+
+/* Function register offsets */
+#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */
+#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */
+#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */
+
+/* SDIO Function CIS ptr offset */
+#define SDIOD_FBR_CISPTR_0 0x09
+#define SDIOD_FBR_CISPTR_1 0x0A
+#define SDIOD_FBR_CISPTR_2 0x0B
+
+/* Code Storage Area pointer */
+#define SDIOD_FBR_CSA_ADDR_0 0x0C
+#define SDIOD_FBR_CSA_ADDR_1 0x0D
+#define SDIOD_FBR_CSA_ADDR_2 0x0E
+#define SDIOD_FBR_CSA_DATA 0x0F
+
+/* SDIO Function I/O Block Size */
+#define SDIOD_FBR_BLKSIZE_0 0x10
+#define SDIOD_FBR_BLKSIZE_1 0x11
+
+/* devctr */
+#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */
+#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */
+#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */
+/* interface codes */
+#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */
+#define SDIOD_DIC_UART 1
+#define SDIOD_DIC_BLUETOOTH_A 2
+#define SDIOD_DIC_BLUETOOTH_B 3
+#define SDIOD_DIC_GPS 4
+#define SDIOD_DIC_CAMERA 5
+#define SDIOD_DIC_PHS 6
+#define SDIOD_DIC_WLAN 7
+#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */
+
+/* pwr_sel */
+#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */
+#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */
+
+/* misc defines */
+#define SDIO_FUNC_0 0
+#define SDIO_FUNC_1 1
+#define SDIO_FUNC_2 2
+#define SDIO_FUNC_3 3
+#define SDIO_FUNC_4 4
+#define SDIO_FUNC_5 5
+#define SDIO_FUNC_6 6
+#define SDIO_FUNC_7 7
+
+#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */
+#define SD_CARD_TYPE_IO 1 /* IO only card */
+#define SD_CARD_TYPE_MEMORY 2 /* memory only card */
+#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */
+
+#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */
+#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */
+
+/* Card registers: status bit position */
+#define CARDREG_STATUS_BIT_OUTOFRANGE 31
+#define CARDREG_STATUS_BIT_COMCRCERROR 23
+#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22
+#define CARDREG_STATUS_BIT_ERROR 19
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9
+#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4
+
+#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */
+#define SD_CMD_SEND_OPCOND 1
+#define SD_CMD_MMC_SET_RCA 3
+#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */
+#define SD_CMD_SELECT_DESELECT_CARD 7
+#define SD_CMD_SEND_CSD 9
+#define SD_CMD_SEND_CID 10
+#define SD_CMD_STOP_TRANSMISSION 12
+#define SD_CMD_SEND_STATUS 13
+#define SD_CMD_GO_INACTIVE_STATE 15
+#define SD_CMD_SET_BLOCKLEN 16
+#define SD_CMD_READ_SINGLE_BLOCK 17
+#define SD_CMD_READ_MULTIPLE_BLOCK 18
+#define SD_CMD_WRITE_BLOCK 24
+#define SD_CMD_WRITE_MULTIPLE_BLOCK 25
+#define SD_CMD_PROGRAM_CSD 27
+#define SD_CMD_SET_WRITE_PROT 28
+#define SD_CMD_CLR_WRITE_PROT 29
+#define SD_CMD_SEND_WRITE_PROT 30
+#define SD_CMD_ERASE_WR_BLK_START 32
+#define SD_CMD_ERASE_WR_BLK_END 33
+#define SD_CMD_ERASE 38
+#define SD_CMD_LOCK_UNLOCK 42
+#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */
+#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */
+#define SD_CMD_APP_CMD 55
+#define SD_CMD_GEN_CMD 56
+#define SD_CMD_READ_OCR 58
+#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */
+#define SD_ACMD_SD_STATUS 13
+#define SD_ACMD_SEND_NUM_WR_BLOCKS 22
+#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23
+#define SD_ACMD_SD_SEND_OP_COND 41
+#define SD_ACMD_SET_CLR_CARD_DETECT 42
+#define SD_ACMD_SEND_SCR 51
+
+/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */
+#define SD_IO_OP_READ 0 /* Read_Write: Read */
+#define SD_IO_OP_WRITE 1 /* Read_Write: Write */
+#define SD_IO_RW_NORMAL 0 /* no RAW */
+#define SD_IO_RW_RAW 1 /* RAW */
+#define SD_IO_BYTE_MODE 0 /* Byte Mode */
+#define SD_IO_BLOCK_MODE 1 /* BlockMode */
+#define SD_IO_FIXED_ADDRESS 0 /* fix Address */
+#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */
+
+/* build SD_CMD_IO_RW_DIRECT Argument */
+#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \
+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \
+ (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF))
+
+/* build SD_CMD_IO_RW_EXTENDED Argument */
+#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \
+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \
+ (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF))
+
+/* SDIO response parameters */
+#define SD_RSP_NO_NONE 0
+#define SD_RSP_NO_1 1
+#define SD_RSP_NO_2 2
+#define SD_RSP_NO_3 3
+#define SD_RSP_NO_4 4
+#define SD_RSP_NO_5 5
+#define SD_RSP_NO_6 6
+
+ /* Modified R6 response (to CMD3) */
+#define SD_RSP_MR6_COM_CRC_ERROR 0x8000
+#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000
+#define SD_RSP_MR6_ERROR 0x2000
+
+ /* Modified R1 in R4 Response (to CMD5) */
+#define SD_RSP_MR1_SBIT 0x80
+#define SD_RSP_MR1_PARAMETER_ERROR 0x40
+#define SD_RSP_MR1_RFU5 0x20
+#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10
+#define SD_RSP_MR1_COM_CRC_ERROR 0x08
+#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04
+#define SD_RSP_MR1_RFU1 0x02
+#define SD_RSP_MR1_IDLE_STATE 0x01
+
+ /* R5 response (to CMD52 and CMD53) */
+#define SD_RSP_R5_COM_CRC_ERROR 0x80
+#define SD_RSP_R5_ILLEGAL_COMMAND 0x40
+#define SD_RSP_R5_IO_CURRENTSTATE1 0x20
+#define SD_RSP_R5_IO_CURRENTSTATE0 0x10
+#define SD_RSP_R5_ERROR 0x08
+#define SD_RSP_R5_RFU 0x04
+#define SD_RSP_R5_FUNC_NUM_ERROR 0x02
+#define SD_RSP_R5_OUT_OF_RANGE 0x01
+
+#define SD_RSP_R5_ERRBITS 0xCB
+
+/* ------------------------------------------------
+ * SDIO Commands and responses
+ *
+ * I/O only commands are:
+ * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+ * ------------------------------------------------
+ */
+
+/* SDIO Commands */
+#define SDIOH_CMD_0 0
+#define SDIOH_CMD_3 3
+#define SDIOH_CMD_5 5
+#define SDIOH_CMD_7 7
+#define SDIOH_CMD_15 15
+#define SDIOH_CMD_52 52
+#define SDIOH_CMD_53 53
+#define SDIOH_CMD_59 59
+
+/* SDIO Command Responses */
+#define SDIOH_RSP_NONE 0
+#define SDIOH_RSP_R1 1
+#define SDIOH_RSP_R2 2
+#define SDIOH_RSP_R3 3
+#define SDIOH_RSP_R4 4
+#define SDIOH_RSP_R5 5
+#define SDIOH_RSP_R6 6
+
+/*
+ * SDIO Response Error flags
+ */
+#define SDIOH_RSP5_ERROR_FLAGS 0xCB
+
+/* ------------------------------------------------
+ * SDIO Command structures. I/O only commands are:
+ *
+ * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+ * ------------------------------------------------
+ */
+
+#define CMD5_OCR_M BITFIELD_MASK(24)
+#define CMD5_OCR_S 0
+
+#define CMD7_RCA_M BITFIELD_MASK(16)
+#define CMD7_RCA_S 16
+
+#define CMD_15_RCA_M BITFIELD_MASK(16)
+#define CMD_15_RCA_S 16
+
+#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52
+ */
+#define CMD52_DATA_S 0
+#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */
+#define CMD52_REG_ADDR_S 9
+#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */
+#define CMD52_RAW_S 27
+#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */
+#define CMD52_FUNCTION_S 28
+#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */
+#define CMD52_RW_FLAG_S 31
+
+#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */
+#define CMD53_BYTE_BLK_CNT_S 0
+#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */
+#define CMD53_REG_ADDR_S 9
+#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */
+#define CMD53_OP_CODE_S 26
+#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */
+#define CMD53_BLK_MODE_S 27
+#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */
+#define CMD53_FUNCTION_S 28
+#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */
+#define CMD53_RW_FLAG_S 31
+
+/* ------------------------------------------------------
+ * SDIO Command Response structures for SD1 and SD4 modes
+ * -----------------------------------------------------
+ */
+#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */
+#define RSP4_IO_OCR_S 0
+#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */
+#define RSP4_STUFF_S 24
+#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */
+#define RSP4_MEM_PRESENT_S 27
+#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */
+#define RSP4_NUM_FUNCS_S 28
+#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */
+#define RSP4_CARD_READY_S 31
+
+#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0]
+ */
+#define RSP6_STATUS_S 0
+#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */
+#define RSP6_IO_RCA_S 16
+
+#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */
+#define RSP1_AKE_SEQ_ERROR_S 3
+#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */
+#define RSP1_APP_CMD_S 5
+#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */
+#define RSP1_READY_FOR_DATA_S 8
+#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card
+ * when Cmd was received
+ */
+#define RSP1_CURR_STATE_S 9
+#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */
+#define RSP1_EARSE_RESET_S 13
+#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */
+#define RSP1_CARD_ECC_DISABLE_S 14
+#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */
+#define RSP1_WP_ERASE_SKIP_S 15
+#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits
+ * of CSD
+ */
+#define RSP1_CID_CSD_OVERW_S 16
+#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */
+#define RSP1_ERROR_S 19
+#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */
+#define RSP1_CC_ERROR_S 20
+#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed
+ * to correct data
+ */
+#define RSP1_CARD_ECC_FAILED_S 21
+#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */
+#define RSP1_ILLEGAL_CMD_S 22
+#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed
+ */
+#define RSP1_COM_CRC_ERROR_S 23
+#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */
+#define RSP1_LOCK_UNLOCK_FAIL_S 24
+#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */
+#define RSP1_CARD_LOCKED_S 25
+#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program
+ * write-protected blocks
+ */
+#define RSP1_WP_VIOLATION_S 26
+#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */
+#define RSP1_ERASE_PARAM_S 27
+#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */
+#define RSP1_ERASE_SEQ_ERR_S 28
+#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */
+#define RSP1_BLK_LEN_ERR_S 29
+#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */
+#define RSP1_ADDR_ERR_S 30
+#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */
+#define RSP1_OUT_OF_RANGE_S 31
+
+#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */
+#define RSP5_DATA_S 0
+#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */
+#define RSP5_FLAGS_S 8
+#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */
+#define RSP5_STUFF_S 16
+
+/* ----------------------------------------------
+ * SDIO Command Response structures for SPI mode
+ * ----------------------------------------------
+ */
+#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */
+#define SPIRSP4_IO_OCR_S 0
+#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */
+#define SPIRSP4_STUFF_S 16
+#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */
+#define SPIRSP4_MEM_PRESENT_S 19
+#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */
+#define SPIRSP4_NUM_FUNCS_S 20
+#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */
+#define SPIRSP4_CARD_READY_S 23
+#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */
+#define SPIRSP4_IDLE_STATE_S 24
+#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */
+#define SPIRSP4_ILLEGAL_CMD_S 26
+#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */
+#define SPIRSP4_COM_CRC_ERROR_S 27
+#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error
+ */
+#define SPIRSP4_FUNC_NUM_ERROR_S 28
+#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */
+#define SPIRSP4_PARAM_ERROR_S 30
+#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */
+#define SPIRSP4_START_BIT_S 31
+
+#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */
+#define SPIRSP5_DATA_S 16
+#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */
+#define SPIRSP5_IDLE_STATE_S 24
+#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */
+#define SPIRSP5_ILLEGAL_CMD_S 26
+#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */
+#define SPIRSP5_COM_CRC_ERROR_S 27
+#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error
+ */
+#define SPIRSP5_FUNC_NUM_ERROR_S 28
+#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */
+#define SPIRSP5_PARAM_ERROR_S 30
+#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */
+#define SPIRSP5_START_BIT_S 31
+
+/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */
+#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error
+ */
+#define RSP6STAT_AKE_SEQ_ERROR_S 3
+#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */
+#define RSP6STAT_APP_CMD_S 5
+#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data
+ * (buff empty)
+ */
+#define RSP6STAT_READY_FOR_DATA_S 8
+#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at
+ * Cmd reception
+ */
+#define RSP6STAT_CURR_STATE_S 9
+#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19
+ */
+#define RSP6STAT_ERROR_S 13
+#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for
+ * card state Bit 22
+ */
+#define RSP6STAT_ILLEGAL_CMD_S 14
+#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command
+ * failed Bit 23
+ */
+#define RSP6STAT_COM_CRC_ERROR_S 15
+
+#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ
+#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE
+
+#endif /* def BCMSDIO */
+#endif /* _SDIO_H */
diff --git a/drivers/staging/brcm80211/include/sdioh.h b/drivers/staging/brcm80211/include/sdioh.h
new file mode 100644
index 000000000000..f96aaf9cec74
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sdioh.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SDIOH_H
+#define _SDIOH_H
+
+#define SD_SysAddr 0x000
+#define SD_BlockSize 0x004
+#define SD_BlockCount 0x006
+#define SD_Arg0 0x008
+#define SD_Arg1 0x00A
+#define SD_TransferMode 0x00C
+#define SD_Command 0x00E
+#define SD_Response0 0x010
+#define SD_Response1 0x012
+#define SD_Response2 0x014
+#define SD_Response3 0x016
+#define SD_Response4 0x018
+#define SD_Response5 0x01A
+#define SD_Response6 0x01C
+#define SD_Response7 0x01E
+#define SD_BufferDataPort0 0x020
+#define SD_BufferDataPort1 0x022
+#define SD_PresentState 0x024
+#define SD_HostCntrl 0x028
+#define SD_PwrCntrl 0x029
+#define SD_BlockGapCntrl 0x02A
+#define SD_WakeupCntrl 0x02B
+#define SD_ClockCntrl 0x02C
+#define SD_TimeoutCntrl 0x02E
+#define SD_SoftwareReset 0x02F
+#define SD_IntrStatus 0x030
+#define SD_ErrorIntrStatus 0x032
+#define SD_IntrStatusEnable 0x034
+#define SD_ErrorIntrStatusEnable 0x036
+#define SD_IntrSignalEnable 0x038
+#define SD_ErrorIntrSignalEnable 0x03A
+#define SD_CMD12ErrorStatus 0x03C
+#define SD_Capabilities 0x040
+#define SD_Capabilities_Reserved 0x044
+#define SD_MaxCurCap 0x048
+#define SD_MaxCurCap_Reserved 0x04C
+#define SD_ADMA_SysAddr 0x58
+#define SD_SlotInterruptStatus 0x0FC
+#define SD_HostControllerVersion 0x0FE
+
+/* SD specific registers in PCI config space */
+#define SD_SlotInfo 0x40
+
+#endif /* _SDIOH_H */
diff --git a/drivers/staging/brcm80211/include/sdiovar.h b/drivers/staging/brcm80211/include/sdiovar.h
new file mode 100644
index 000000000000..2112cb6f901b
--- /dev/null
+++ b/drivers/staging/brcm80211/include/sdiovar.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _sdiovar_h_
+#define _sdiovar_h_
+
+#include <typedefs.h>
+
+/* require default structure packing */
+#define BWL_DEFAULT_PACKING
+#include <packed_section_start.h>
+
+typedef struct sdreg {
+ int func;
+ int offset;
+ int value;
+} sdreg_t;
+
+/* Common msglevel constants */
+#define SDH_ERROR_VAL 0x0001 /* Error */
+#define SDH_TRACE_VAL 0x0002 /* Trace */
+#define SDH_INFO_VAL 0x0004 /* Info */
+#define SDH_DEBUG_VAL 0x0008 /* Debug */
+#define SDH_DATA_VAL 0x0010 /* Data */
+#define SDH_CTRL_VAL 0x0020 /* Control Regs */
+#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */
+#define SDH_DMA_VAL 0x0080 /* DMA */
+
+#define NUM_PREV_TRANSACTIONS 16
+
+#include <packed_section_end.h>
+
+#endif /* _sdiovar_h_ */
diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h
new file mode 100644
index 000000000000..afdaf84819d7
--- /dev/null
+++ b/drivers/staging/brcm80211/include/siutils.h
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _siutils_h_
+#define _siutils_h_
+
+#include <hndsoc.h>
+
+#if !defined(WLC_LOW)
+#include "bcm_rpc.h"
+#endif
+/*
+ * Data structure to export all chip specific common variables
+ * public (read-only) portion of siutils handle returned by si_attach()
+ */
+struct si_pub {
+ uint socitype; /* SOCI_SB, SOCI_AI */
+
+ uint bustype; /* SI_BUS, PCI_BUS */
+ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+ uint buscorerev; /* buscore rev */
+ uint buscoreidx; /* buscore index */
+ int ccrev; /* chip common core rev */
+ uint32 cccaps; /* chip common capabilities */
+ uint32 cccaps_ext; /* chip common capabilities extension */
+ int pmurev; /* pmu core rev */
+ uint32 pmucaps; /* pmu capabilities */
+ uint boardtype; /* board type */
+ uint boardvendor; /* board vendor */
+ uint boardflags; /* board flags */
+ uint boardflags2; /* board flags2 */
+ uint chip; /* chip number */
+ uint chiprev; /* chip revision */
+ uint chippkg; /* chip package option */
+ uint32 chipst; /* chip status */
+ bool issim; /* chip is in simulation or emulation */
+ uint socirev; /* SOC interconnect rev */
+ bool pci_pr32414;
+
+#if !defined(WLC_LOW)
+ rpc_info_t *rpc;
+#endif
+};
+
+/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver
+ * for monolithic driver, it is readonly to prevent accident change
+ */
+#if !defined(WLC_LOW)
+typedef struct si_pub si_t;
+#else
+typedef const struct si_pub si_t;
+#endif
+
+/*
+ * Many of the routines below take an 'sih' handle as their first arg.
+ * Allocate this by calling si_attach(). Free it by calling si_detach().
+ * At any one time, the sih is logically focused on one particular si core
+ * (the "current core").
+ * Use si_setcore() or si_setcoreidx() to change the association to another core.
+ */
+
+#define BADIDX (SI_MAXCORES + 1)
+
+/* clkctl xtal what flags */
+#define XTAL 0x1 /* primary crystal oscillator (2050) */
+#define PLL 0x2 /* main chip pll */
+
+/* clkctl clk mode */
+#define CLK_FAST 0 /* force fast (pll) clock */
+#define CLK_DYNAMIC 2 /* enable dynamic clock control */
+
+/* GPIO usage priorities */
+#define GPIO_DRV_PRIORITY 0 /* Driver */
+#define GPIO_APP_PRIORITY 1 /* Application */
+#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */
+
+/* GPIO pull up/down */
+#define GPIO_PULLUP 0
+#define GPIO_PULLDN 1
+
+/* GPIO event regtype */
+#define GPIO_REGEVT 0 /* GPIO register event */
+#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
+#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
+
+/* device path */
+#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
+
+/* SI routine enumeration: to be used by update function with multiple hooks */
+#define SI_DOATTACH 1
+#define SI_PCIDOWN 2
+#define SI_PCIUP 3
+
+#define ISSIM_ENAB(sih) 0
+
+/* PMU clock/power control */
+#if defined(BCMPMUCTL)
+#define PMUCTL_ENAB(sih) (BCMPMUCTL)
+#else
+#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU)
+#endif
+
+/* chipcommon clock/power control (exclusive with PMU's) */
+#if defined(BCMPMUCTL) && BCMPMUCTL
+#define CCCTL_ENAB(sih) (0)
+#define CCPLL_ENAB(sih) (0)
+#else
+#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL)
+#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK)
+#endif
+
+typedef void (*gpio_handler_t) (uint32 stat, void *arg);
+
+/* External PA enable mask */
+#define GPIO_CTRL_EPA_EN_MASK 0x40
+
+/* === exported functions === */
+extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
+ void *sdh, char **vars, uint *varsz);
+
+extern void si_detach(si_t *sih);
+extern bool si_pci_war16165(si_t *sih);
+
+extern uint si_corelist(si_t *sih, uint coreid[]);
+extern uint si_coreid(si_t *sih);
+extern uint si_flag(si_t *sih);
+extern uint si_intflag(si_t *sih);
+extern uint si_coreidx(si_t *sih);
+extern uint si_coreunit(si_t *sih);
+extern uint si_corevendor(si_t *sih);
+extern uint si_corerev(si_t *sih);
+extern void *si_osh(si_t *sih);
+extern void si_setosh(si_t *sih, osl_t *osh);
+extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+ uint val);
+extern void *si_coreregs(si_t *sih);
+extern void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val);
+extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val);
+extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val);
+extern bool si_iscoreup(si_t *sih);
+extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit);
+#ifndef BCMSDIO
+extern void *si_setcoreidx(si_t *sih, uint coreidx);
+#endif
+extern void *si_setcore(si_t *sih, uint coreid, uint coreunit);
+extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx,
+ uint *intr_val);
+extern void si_restore_core(si_t *sih, uint coreid, uint intr_val);
+extern int si_numaddrspaces(si_t *sih);
+extern uint32 si_addrspace(si_t *sih, uint asidx);
+extern uint32 si_addrspacesize(si_t *sih, uint asidx);
+extern int si_corebist(si_t *sih);
+extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void si_core_disable(si_t *sih, uint32 bits);
+extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m);
+extern uint32 si_clock(si_t *sih);
+extern uint32 si_alp_clock(si_t *sih);
+extern uint32 si_ilp_clock(si_t *sih);
+extern void si_pci_setup(si_t *sih, uint coremask);
+extern void si_setint(si_t *sih, int siflag);
+extern bool si_backplane64(si_t *sih);
+extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn,
+ void *intrsrestore_fn,
+ void *intrsenabled_fn, void *intr_arg);
+extern void si_deregister_intr_callback(si_t *sih);
+extern void si_clkctl_init(si_t *sih);
+extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih);
+extern bool si_clkctl_cc(si_t *sih, uint mode);
+extern int si_clkctl_xtal(si_t *sih, uint what, bool on);
+extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val);
+extern bool si_deviceremoved(si_t *sih);
+extern uint32 si_socram_size(si_t *sih);
+extern uint32 si_socdevram_size(si_t *sih);
+extern void si_socdevram(si_t *sih, bool set, uint8 *ennable,
+ uint8 *protect);
+extern bool si_socdevram_pkg(si_t *sih);
+
+extern void si_watchdog(si_t *sih, uint ticks);
+extern void si_watchdog_ms(si_t *sih, uint32 ms);
+extern void *si_gpiosetcore(si_t *sih);
+extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val,
+ uint8 priority);
+extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioin(si_t *sih);
+extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val,
+ uint8 priority);
+extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val,
+ uint8 priority);
+extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority);
+extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority);
+extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val);
+extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val);
+extern uint32 si_gpio_int_enable(si_t *sih, bool enable);
+
+/* GPIO event handlers */
+extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev,
+ gpio_handler_t cb, void *arg);
+extern void si_gpio_handler_unregister(si_t *sih, void *gpioh);
+extern void si_gpio_handler_process(si_t *sih);
+
+/* Wake-on-wireless-LAN (WOWL) */
+extern bool si_pci_pmecap(si_t *sih);
+struct osl_info;
+extern bool si_pci_fastpmecap(struct osl_info *osh);
+extern bool si_pci_pmestat(si_t *sih);
+extern void si_pci_pmeclr(si_t *sih);
+extern void si_pci_pmeen(si_t *sih);
+extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset);
+
+#ifdef BCMSDIO
+extern void si_sdio_init(si_t *sih);
+#endif
+
+extern uint16 si_d11_devid(si_t *sih);
+
+#define si_eci(sih) 0
+#define si_eci_init(sih) (0)
+#define si_eci_notify_bt(sih, type, val) (0)
+#define si_seci(sih) 0
+static INLINE void *si_seci_init(si_t *sih, uint8 use_seci)
+{
+ return NULL;
+}
+
+/* OTP status */
+extern bool si_is_otp_disabled(si_t *sih);
+extern bool si_is_otp_powered(si_t *sih);
+extern void si_otp_power(si_t *sih, bool on);
+
+/* SPROM availability */
+extern bool si_is_sprom_available(si_t *sih);
+extern bool si_is_sprom_enabled(si_t *sih);
+extern void si_sprom_enable(si_t *sih, bool enable);
+#ifdef SI_SPROM_PROBE
+extern void si_sprom_init(si_t *sih);
+#endif /* SI_SPROM_PROBE */
+
+/* OTP/SROM CIS stuff */
+extern int si_cis_source(si_t *sih);
+#define CIS_DEFAULT 0
+#define CIS_SROM 1
+#define CIS_OTP 2
+
+/* Fab-id information */
+#define DEFAULT_FAB 0x0 /* Original/first fab used for this chip */
+#define CSM_FAB7 0x1 /* CSM Fab7 chip */
+#define TSMC_FAB12 0x2 /* TSMC Fab12/Fab14 chip */
+#define SMIC_FAB4 0x3 /* SMIC Fab4 chip */
+
+#define SI_ERROR(args)
+
+#ifdef BCMDBG
+#define SI_MSG(args) printf args
+#else
+#define SI_MSG(args)
+#endif /* BCMDBG */
+
+/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
+#define SI_VMSG(args)
+
+#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
+
+typedef uint32(*si_intrsoff_t) (void *intr_arg);
+typedef void (*si_intrsrestore_t) (void *intr_arg, uint32 arg);
+typedef bool(*si_intrsenabled_t) (void *intr_arg);
+
+typedef struct gpioh_item {
+ void *arg;
+ bool level;
+ gpio_handler_t handler;
+ uint32 event;
+ struct gpioh_item *next;
+} gpioh_item_t;
+
+/* misc si info needed by some of the routines */
+typedef struct si_info {
+ struct si_pub pub; /* back plane public state (must be first field) */
+ void *osh; /* osl os handle */
+ void *sdh; /* bcmsdh handle */
+ uint dev_coreid; /* the core provides driver functions */
+ void *intr_arg; /* interrupt callback function arg */
+ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
+ si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+ si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+
+ void *pch; /* PCI/E core handle */
+
+ gpioh_item_t *gpioh_head; /* GPIO event handlers list */
+
+ bool memseg; /* flag to toggle MEM_SEG register */
+
+ char *vars;
+ uint varsz;
+
+ void *curmap; /* current regs va */
+ void *regs[SI_MAXCORES]; /* other regs va */
+
+ uint curidx; /* current core index */
+ uint numcores; /* # discovered cores */
+ uint coreid[SI_MAXCORES]; /* id of each core */
+ uint32 coresba[SI_MAXCORES]; /* backplane address of each core */
+ void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */
+ uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */
+ uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */
+ uint32 coresba2_size[SI_MAXCORES]; /* second address space size */
+
+ void *curwrap; /* current wrapper va */
+ void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
+ uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
+
+ uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */
+ uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */
+ uint32 oob_router; /* oob router registers for axi */
+} si_info_t;
+
+#define SI_INFO(sih) (si_info_t *)(uintptr)sih
+
+#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
+ ISALIGNED((x), SI_CORE_SIZE))
+#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE))
+#define BADCOREADDR 0
+#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES)
+#define NOREV -1 /* Invalid rev */
+
+/* Newer chips can access PCI/PCIE and CC core without requiring to change
+ * PCI BAR0 WIN
+ */
+#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \
+ (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13))
+
+#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
+#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
+
+/*
+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
+ * before after core switching to avoid invalid register accesss inside ISR.
+ */
+#define INTR_OFF(si, intr_val) \
+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
+#define INTR_RESTORE(si, intr_val) \
+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
+
+/* dynamic clock control defines */
+#define LPOMINFREQ 25000 /* low power oscillator min */
+#define LPOMAXFREQ 43000 /* low power oscillator max */
+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
+#define PCIMINFREQ 25000000 /* 25 MHz */
+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
+
+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
+
+#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \
+ ((si)->pub.buscoretype == PCI_CORE_ID))
+#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \
+ ((si)->pub.buscoretype == PCIE_CORE_ID))
+#define PCI_FORCEHT(si) \
+ (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
+
+/* GPIO Based LED powersave defines */
+#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
+#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
+
+#ifndef DEFAULT_GPIOTIMERVAL
+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
+#endif
+
+/*
+ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
+ * The returned path is NULL terminated and has trailing '/'.
+ * Return 0 on success, nonzero otherwise.
+ */
+extern int si_devpath(si_t *sih, char *path, int size);
+/* Read variable with prepending the devpath to the name */
+extern char *si_getdevpathvar(si_t *sih, const char *name);
+extern int si_getdevpathintvar(si_t *sih, const char *name);
+
+extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val);
+extern void si_war42780_clkreq(si_t *sih, bool clkreq);
+extern void si_pci_sleep(si_t *sih);
+extern void si_pci_down(si_t *sih);
+extern void si_pci_up(si_t *sih);
+extern void si_pcie_war_ovr_update(si_t *sih, uint8 aspm);
+extern void si_pcie_extendL1timer(si_t *sih, bool extend);
+extern int si_pci_fixcfg(si_t *sih);
+extern void si_chippkg_set(si_t *sih, uint);
+
+extern void si_chipcontrl_epa4331(si_t *sih, bool on);
+/* Enable Ex-PA for 4313 */
+extern void si_epa_4313war(si_t *sih);
+
+/* === debug routines === */
+extern uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val,
+ uint type);
+extern uint32 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset,
+ uint32 mask, uint32 val);
+
+char *si_getnvramflvar(si_t *sih, const char *name);
+
+/* AMBA Interconnect exported externs */
+extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
+ void *sdh, char **vars, uint *varsz);
+extern si_t *ai_kattach(osl_t *osh);
+extern void ai_scan(si_t *sih, void *regs, uint devid);
+
+extern uint ai_flag(si_t *sih);
+extern void ai_setint(si_t *sih, int siflag);
+extern uint ai_coreidx(si_t *sih);
+extern uint ai_corevendor(si_t *sih);
+extern uint ai_corerev(si_t *sih);
+extern bool ai_iscoreup(si_t *sih);
+extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val);
+extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val);
+extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val);
+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+ uint val);
+extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void ai_core_disable(si_t *sih, uint32 bits);
+extern int ai_numaddrspaces(si_t *sih);
+extern uint32 ai_addrspace(si_t *sih, uint asidx);
+extern uint32 ai_addrspacesize(si_t *sih, uint asidx);
+extern void ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val);
+
+#ifdef BCMDBG
+extern void ai_view(si_t *sih, bool verbose);
+#endif
+
+#ifdef BCMSDIO
+#define si_setcoreidx(sih, idx) sb_setcoreidx(sih, idx)
+#define si_coreid(sih) sb_coreid(sih)
+#define si_corerev(sih) sb_corerev(sih)
+#endif
+
+#endif /* _siutils_h_ */
diff --git a/drivers/staging/brcm80211/include/spid.h b/drivers/staging/brcm80211/include/spid.h
new file mode 100644
index 000000000000..9cf4e0b280c4
--- /dev/null
+++ b/drivers/staging/brcm80211/include/spid.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _SPI_H
+#define _SPI_H
+
+/*
+ * Brcm SPI Device Register Map.
+ *
+ */
+
+typedef volatile struct {
+ uint8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */
+ uint8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */
+ uint8 status_enable; /* 0x02, status-enable, intr with status, response_delay
+ * function selection, command/data error check
+ */
+ uint8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */
+ uint16 intr_reg; /* 0x04, Intr status register */
+ uint16 intr_en_reg; /* 0x06, Intr mask register */
+ uint32 status_reg; /* 0x08, RO, Status bits of last spi transfer */
+ uint16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */
+ uint16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */
+ uint16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */
+ uint32 test_read; /* 0x14, RO 0xfeedbead signature */
+ uint32 test_rw; /* 0x18, RW */
+ uint8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */
+ uint8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */
+ uint8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */
+ uint8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */
+} spi_regs_t;
+
+/* SPI device register offsets */
+#define SPID_CONFIG 0x00
+#define SPID_RESPONSE_DELAY 0x01
+#define SPID_STATUS_ENABLE 0x02
+#define SPID_RESET_BP 0x03 /* (corerev >= 1) */
+#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */
+#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */
+#define SPID_STATUS_REG 0x08 /* 32 bits */
+#define SPID_F1_INFO_REG 0x0C /* 16 bits */
+#define SPID_F2_INFO_REG 0x0E /* 16 bits */
+#define SPID_F3_INFO_REG 0x10 /* 16 bits */
+#define SPID_TEST_READ 0x14 /* 32 bits */
+#define SPID_TEST_RW 0x18 /* 32 bits */
+#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */
+#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */
+#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */
+#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */
+
+/* Bit masks for SPID_CONFIG device register */
+#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */
+#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */
+#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */
+#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */
+#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */
+#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */
+#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */
+
+/* Bit mask for SPID_RESPONSE_DELAY device register */
+#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */
+
+/* Bit mask for SPID_STATUS_ENABLE device register */
+#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */
+#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */
+#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */
+#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */
+#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */
+#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */
+
+/* Bit mask for SPID_RESET_BP device register */
+#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */
+#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */
+#define RESET_SPI 0x80 /* reset the above enabled logic */
+
+/* Bit mask for SPID_INTR_REG device register */
+#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */
+#define F2_F3_FIFO_RD_UNDERFLOW 0x0002
+#define F2_F3_FIFO_WR_OVERFLOW 0x0004
+#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */
+#define DATA_ERROR 0x0010 /* Cleared by writing 1 */
+#define F2_PACKET_AVAILABLE 0x0020
+#define F3_PACKET_AVAILABLE 0x0040
+#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */
+#define MISC_INTR0 0x0100
+#define MISC_INTR1 0x0200
+#define MISC_INTR2 0x0400
+#define MISC_INTR3 0x0800
+#define MISC_INTR4 0x1000
+#define F1_INTR 0x2000
+#define F2_INTR 0x4000
+#define F3_INTR 0x8000
+
+/* Bit mask for 32bit SPID_STATUS_REG device register */
+#define STATUS_DATA_NOT_AVAILABLE 0x00000001
+#define STATUS_UNDERFLOW 0x00000002
+#define STATUS_OVERFLOW 0x00000004
+#define STATUS_F2_INTR 0x00000008
+#define STATUS_F3_INTR 0x00000010
+#define STATUS_F2_RX_READY 0x00000020
+#define STATUS_F3_RX_READY 0x00000040
+#define STATUS_HOST_CMD_DATA_ERR 0x00000080
+#define STATUS_F2_PKT_AVAILABLE 0x00000100
+#define STATUS_F2_PKT_LEN_MASK 0x000FFE00
+#define STATUS_F2_PKT_LEN_SHIFT 9
+#define STATUS_F3_PKT_AVAILABLE 0x00100000
+#define STATUS_F3_PKT_LEN_MASK 0xFFE00000
+#define STATUS_F3_PKT_LEN_SHIFT 21
+
+/* Bit mask for 16 bits SPID_F1_INFO_REG device register */
+#define F1_ENABLED 0x0001
+#define F1_RDY_FOR_DATA_TRANSFER 0x0002
+#define F1_MAX_PKT_SIZE 0x01FC
+
+/* Bit mask for 16 bits SPID_F2_INFO_REG device register */
+#define F2_ENABLED 0x0001
+#define F2_RDY_FOR_DATA_TRANSFER 0x0002
+#define F2_MAX_PKT_SIZE 0x3FFC
+
+/* Bit mask for 16 bits SPID_F3_INFO_REG device register */
+#define F3_ENABLED 0x0001
+#define F3_RDY_FOR_DATA_TRANSFER 0x0002
+#define F3_MAX_PKT_SIZE 0x3FFC
+
+/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */
+#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD
+
+/* Maximum number of I/O funcs */
+#define SPI_MAX_IOFUNCS 4
+
+#define SPI_MAX_PKT_LEN (2048*4)
+
+/* Misc defines */
+#define SPI_FUNC_0 0
+#define SPI_FUNC_1 1
+#define SPI_FUNC_2 2
+#define SPI_FUNC_3 3
+
+#define WAIT_F2RXFIFORDY 100
+#define WAIT_F2RXFIFORDY_DELAY 20
+
+#endif /* _SPI_H */
diff --git a/drivers/staging/brcm80211/include/typedefs.h b/drivers/staging/brcm80211/include/typedefs.h
new file mode 100644
index 000000000000..45a56b4967ee
--- /dev/null
+++ b/drivers/staging/brcm80211/include/typedefs.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _TYPEDEFS_H_
+#define _TYPEDEFS_H_
+
+/*
+ * Infer the compile environment based on preprocessor symbols and pragmas.
+ * Override type definitions as needed, and include configuration-dependent
+ * header files to define types.
+ */
+
+#if defined(__x86_64__)
+#define TYPEDEF_UINTPTR
+typedef unsigned long long int uintptr;
+#endif
+
+#if defined(_NEED_SIZE_T_)
+typedef long unsigned int size_t;
+#endif
+
+#define TYPEDEF_UINT
+#define TYPEDEF_USHORT
+#define TYPEDEF_ULONG
+#include <linux/version.h>
+#define TYPEDEF_BOOL
+
+/* Do not support the (u)int64 types with strict ansi for GNU C */
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+#define TYPEDEF_INT64
+#define TYPEDEF_UINT64
+#endif
+
+#include <linux/types.h>
+
+/*
+ * Default Typedefs
+ */
+#ifndef TYPEDEF_BOOL
+typedef /* @abstract@ */ unsigned char bool;
+#endif
+
+/* define uchar, ushort, uint, ulong */
+
+#ifndef TYPEDEF_UCHAR
+typedef unsigned char uchar;
+#endif
+
+#ifndef TYPEDEF_USHORT
+typedef unsigned short ushort;
+#endif
+
+#ifndef TYPEDEF_UINT
+typedef unsigned int uint;
+#endif
+
+#ifndef TYPEDEF_ULONG
+typedef unsigned long ulong;
+#endif
+
+/* define [u]int8/16/32/64, uintptr */
+
+#ifndef TYPEDEF_UINT8
+typedef unsigned char uint8;
+#endif
+
+#ifndef TYPEDEF_UINT16
+typedef unsigned short uint16;
+#endif
+
+#ifndef TYPEDEF_UINT32
+typedef unsigned int uint32;
+#endif
+
+#ifndef TYPEDEF_UINT64
+typedef unsigned long long uint64;
+#endif
+
+#ifndef TYPEDEF_UINTPTR
+typedef unsigned int uintptr;
+#endif
+
+#ifndef TYPEDEF_INT8
+typedef signed char int8;
+#endif
+
+#ifndef TYPEDEF_INT16
+typedef signed short int16;
+#endif
+
+#ifndef TYPEDEF_INT32
+typedef signed int int32;
+#endif
+
+#ifndef TYPEDEF_INT64
+typedef signed long long int64;
+#endif
+
+/* define float32/64, float_t */
+
+#ifndef TYPEDEF_FLOAT32
+typedef float float32;
+#endif
+
+#ifndef TYPEDEF_FLOAT64
+typedef double float64;
+#endif
+
+/*
+ * abstracted floating point type allows for compile time selection of
+ * single or double precision arithmetic. Compiling with -DFLOAT32
+ * selects single precision; the default is double precision.
+ */
+
+#ifndef TYPEDEF_FLOAT_T
+
+#if defined(FLOAT32)
+typedef float32 float_t;
+#else /* default to double precision floating point */
+typedef float64 float_t;
+#endif
+
+#endif /* TYPEDEF_FLOAT_T */
+
+/* define macro values */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1 /* TRUE */
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef OFF
+#define OFF 0
+#endif
+
+#ifndef ON
+#define ON 1 /* ON = 1 */
+#endif
+
+#define AUTO (-1) /* Auto = -1 */
+
+/* define PTRSZ, INLINE */
+
+#ifndef PTRSZ
+#define PTRSZ sizeof(char *)
+#endif
+
+/* Detect compiler type. */
+#if defined(__GNUC__)
+#define BWL_COMPILER_GNU
+#elif defined(__CC_ARM) && __CC_ARM
+#define BWL_COMPILER_ARMCC
+#else
+#error "Unknown compiler!"
+#endif
+
+#ifndef INLINE
+#if defined(BWL_COMPILER_GNU)
+#define INLINE __inline__
+#elif defined(BWL_COMPILER_ARMCC)
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+#endif /* INLINE */
+
+#undef TYPEDEF_BOOL
+#undef TYPEDEF_UCHAR
+#undef TYPEDEF_USHORT
+#undef TYPEDEF_UINT
+#undef TYPEDEF_ULONG
+#undef TYPEDEF_UINT8
+#undef TYPEDEF_UINT16
+#undef TYPEDEF_UINT32
+#undef TYPEDEF_UINT64
+#undef TYPEDEF_UINTPTR
+#undef TYPEDEF_INT8
+#undef TYPEDEF_INT16
+#undef TYPEDEF_INT32
+#undef TYPEDEF_INT64
+#undef TYPEDEF_FLOAT32
+#undef TYPEDEF_FLOAT64
+#undef TYPEDEF_FLOAT_T
+
+/* Suppress unused parameter warning */
+#define UNUSED_PARAMETER(x) (void)(x)
+
+/*
+ * Including the bcmdefs.h here, to make sure everyone including typedefs.h
+ * gets this automatically
+*/
+#include <bcmdefs.h>
+
+#endif /* _TYPEDEFS_H_ */
diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h
new file mode 100644
index 000000000000..970573ba8aa8
--- /dev/null
+++ b/drivers/staging/brcm80211/include/wlioctl.h
@@ -0,0 +1,2007 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlioctl_h_
+#define _wlioctl_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <proto/bcmevent.h>
+#include <proto/802.11.h>
+#include <bcmwifi.h>
+
+#ifndef INTF_NAME_SIZ
+#define INTF_NAME_SIZ 16
+#endif
+
+/* require default structure packing */
+#define BWL_DEFAULT_PACKING
+#include <packed_section_start.h>
+
+/* Legacy structure to help keep backward compatible wl tool and tray app */
+
+#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */
+
+typedef struct wl_bss_info_107 {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ uint8 channel; /* Channel no. */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+ uint32 ie_length; /* byte length of Information Elements */
+ /* variable length Information Elements */
+} wl_bss_info_107_t;
+
+/*
+ * Per-BSS information structure.
+ */
+
+#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */
+
+/* BSS info structure
+ * Applications MUST CHECK ie_offset field and length field to access IEs and
+ * next bss_info structure in a vector (in wl_scan_results_t)
+ */
+typedef struct wl_bss_info_108 {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ chanspec_t chanspec; /* chanspec for bss */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+
+ uint8 n_cap; /* BSS is 802.11N Capable */
+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */
+ uint8 ctl_ch; /* 802.11N BSS control channel number */
+ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */
+ uint8 flags; /* flags */
+ uint8 reserved[3]; /* Reserved for expansion of BSS properties */
+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
+
+ uint16 ie_offset; /* offset at which IEs start, from beginning */
+ uint32 ie_length; /* byte length of Information Elements */
+ /* Add new fields here */
+ /* variable length Information Elements */
+} wl_bss_info_108_t;
+
+#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */
+
+/* BSS info structure
+ * Applications MUST CHECK ie_offset field and length field to access IEs and
+ * next bss_info structure in a vector (in wl_scan_results_t)
+ */
+typedef struct wl_bss_info {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ chanspec_t chanspec; /* chanspec for bss */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+
+ uint8 n_cap; /* BSS is 802.11N Capable */
+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */
+ uint8 ctl_ch; /* 802.11N BSS control channel number */
+ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */
+ uint8 flags; /* flags */
+ uint8 reserved[3]; /* Reserved for expansion of BSS properties */
+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
+
+ uint16 ie_offset; /* offset at which IEs start, from beginning */
+ uint32 ie_length; /* byte length of Information Elements */
+ int16 SNR; /* average SNR of during frame reception */
+ /* Add new fields here */
+ /* variable length Information Elements */
+} wl_bss_info_t;
+
+typedef struct wlc_ssid {
+ uint32 SSID_len;
+ uchar SSID[32];
+} wlc_ssid_t;
+
+typedef struct chan_scandata {
+ uint8 txpower;
+ uint8 pad;
+ chanspec_t channel; /* Channel num, bw, ctrl_sb and band */
+ uint32 channel_mintime;
+ uint32 channel_maxtime;
+} chan_scandata_t;
+
+typedef enum wl_scan_type {
+ EXTDSCAN_FOREGROUND_SCAN,
+ EXTDSCAN_BACKGROUND_SCAN,
+ EXTDSCAN_FORCEDBACKGROUND_SCAN
+} wl_scan_type_t;
+
+#define WLC_EXTDSCAN_MAX_SSID 5
+
+#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */
+#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */
+#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */
+
+typedef struct wl_extdscan_params {
+ int8 nprobes; /* 0, passive, otherwise active */
+ int8 split_scan; /* split scan */
+ int8 band; /* band */
+ int8 pad;
+ wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */
+ uint32 tx_rate; /* in 500ksec units */
+ wl_scan_type_t scan_type; /* enum */
+ int32 channel_num;
+ chan_scandata_t channel_list[1]; /* list of chandata structs */
+} wl_extdscan_params_t;
+
+#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t))
+
+#define WL_BSSTYPE_INFRA 1
+#define WL_BSSTYPE_INDEP 0
+#define WL_BSSTYPE_ANY 2
+
+/* Bitmask for scan_type */
+#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */
+#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */
+#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */
+
+typedef struct wl_scan_params {
+ wlc_ssid_t ssid; /* default: {0, ""} */
+ struct ether_addr bssid; /* default: bcast */
+ int8 bss_type; /* default: any,
+ * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
+ */
+ uint8 scan_type; /* flags, 0 use default */
+ int32 nprobes; /* -1 use default, number of probes per channel */
+ int32 active_time; /* -1 use default, dwell time per channel for
+ * active scanning
+ */
+ int32 passive_time; /* -1 use default, dwell time per channel
+ * for passive scanning
+ */
+ int32 home_time; /* -1 use default, dwell time for the home channel
+ * between channel scans
+ */
+ int32 channel_num; /* count of channels and ssids that follow
+ *
+ * low half is count of channels in channel_list, 0
+ * means default (use all available channels)
+ *
+ * high half is entries in wlc_ssid_t array that
+ * follows channel_list, aligned for int32 (4 bytes)
+ * meaning an odd channel count implies a 2-byte pad
+ * between end of channel_list and first ssid
+ *
+ * if ssid count is zero, single ssid in the fixed
+ * parameter portion is assumed, otherwise ssid in
+ * the fixed portion is ignored
+ */
+ uint16 channel_list[1]; /* list of chanspecs */
+} wl_scan_params_t;
+
+/* size of wl_scan_params not including variable length array */
+#define WL_SCAN_PARAMS_FIXED_SIZE 64
+
+/* masks for channel and ssid count */
+#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff
+#define WL_SCAN_PARAMS_NSSID_SHIFT 16
+
+#define WL_SCAN_ACTION_START 1
+#define WL_SCAN_ACTION_CONTINUE 2
+#define WL_SCAN_ACTION_ABORT 3
+
+#define ISCAN_REQ_VERSION 1
+
+/* incremental scan struct */
+typedef struct wl_iscan_params {
+ uint32 version;
+ uint16 action;
+ uint16 scan_duration;
+ wl_scan_params_t params;
+} wl_iscan_params_t;
+
+/* 3 fields + size of wl_scan_params, not including variable length array */
+#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t))
+
+typedef struct wl_scan_results {
+ uint32 buflen;
+ uint32 version;
+ uint32 count;
+ wl_bss_info_t bss_info[1];
+} wl_scan_results_t;
+
+/* size of wl_scan_results not including variable length array */
+#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t))
+
+/* wl_iscan_results status values */
+#define WL_SCAN_RESULTS_SUCCESS 0
+#define WL_SCAN_RESULTS_PARTIAL 1
+#define WL_SCAN_RESULTS_PENDING 2
+#define WL_SCAN_RESULTS_ABORTED 3
+
+#define ESCAN_REQ_VERSION 1
+
+typedef struct wl_escan_params {
+ uint32 version;
+ uint16 action;
+ uint16 sync_id;
+ wl_scan_params_t params;
+} wl_escan_params_t;
+
+#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t))
+
+typedef struct wl_escan_result {
+ uint32 buflen;
+ uint32 version;
+ uint16 sync_id;
+ uint16 bss_count;
+ wl_bss_info_t bss_info[1];
+} wl_escan_result_t;
+
+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t))
+
+/* incremental scan results struct */
+typedef struct wl_iscan_results {
+ uint32 status;
+ wl_scan_results_t results;
+} wl_iscan_results_t;
+
+/* size of wl_iscan_results not including variable length array */
+#define WL_ISCAN_RESULTS_FIXED_SIZE \
+ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results))
+
+typedef struct wl_probe_params {
+ wlc_ssid_t ssid;
+ struct ether_addr bssid;
+ struct ether_addr mac;
+} wl_probe_params_t;
+
+#define WL_NUMRATES 16 /* max # of rates in a rateset */
+typedef struct wl_rateset {
+ uint32 count; /* # rates in this set */
+ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */
+} wl_rateset_t;
+
+typedef struct wl_rateset_args {
+ uint32 count; /* # rates in this set */
+ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */
+ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
+} wl_rateset_args_t;
+
+/* uint32 list */
+typedef struct wl_uint32_list {
+ /* in - # of elements, out - # of entries */
+ uint32 count;
+ /* variable length uint32 list */
+ uint32 element[1];
+} wl_uint32_list_t;
+
+/* used for association with a specific BSSID and chanspec list */
+typedef struct wl_assoc_params {
+ struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */
+ int32 chanspec_num; /* 0: all available channels,
+ * otherwise count of chanspecs in chanspec_list
+ */
+ chanspec_t chanspec_list[1]; /* list of chanspecs */
+} wl_assoc_params_t;
+#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t))
+
+/* used for reassociation/roam to a specific BSSID and channel */
+typedef wl_assoc_params_t wl_reassoc_params_t;
+#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE
+
+/* used for join with or without a specific bssid and channel list */
+typedef struct wl_join_params {
+ wlc_ssid_t ssid;
+ wl_assoc_params_t params; /* optional field, but it must include the fixed portion
+ * of the wl_assoc_params_t struct when it does present.
+ */
+} wl_join_params_t;
+#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t))
+
+/* defines used by the nrate iovar */
+#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */
+#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */
+#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */
+#define NRATE_STF_SHIFT 8 /* stf mode shift */
+#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
+#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */
+#define NRATE_SGI_MASK 0x00800000 /* sgi mode */
+#define NRATE_SGI_SHIFT 23 /* sgi mode */
+#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
+#define NRATE_LDPC_SHIFT 22 /* ldpc shift */
+
+#define NRATE_STF_SISO 0 /* stf mode SISO */
+#define NRATE_STF_CDD 1 /* stf mode CDD */
+#define NRATE_STF_STBC 2 /* stf mode STBC */
+#define NRATE_STF_SDM 3 /* stf mode SDM */
+
+#define ANTENNA_NUM_1 1 /* total number of antennas to be used */
+#define ANTENNA_NUM_2 2
+#define ANTENNA_NUM_3 3
+#define ANTENNA_NUM_4 4
+
+#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
+#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
+#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */
+#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
+#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
+#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
+#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
+
+#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
+
+typedef struct {
+ uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
+ uint8 num_antcfg; /* number of available antenna configurations */
+} wlc_antselcfg_t;
+
+#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */
+
+#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */
+#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */
+
+#define IBSS_MED 15 /* Mediom in-bss congestion percentage */
+#define IBSS_HI 25 /* Hi in-bss congestion percentage */
+#define OBSS_MED 12
+#define OBSS_HI 25
+#define INTERFER_MED 5
+#define INTERFER_HI 10
+
+#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */
+#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */
+#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */
+#define CCA_FLAGS_PREFER_1_6_11 0x10
+#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */
+
+#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */
+#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */
+#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */
+#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */
+#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */
+
+typedef struct {
+ uint32 duration; /* millisecs spent sampling this channel */
+ uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */
+ /* move if cur bss moves channels) */
+ uint32 congest_obss; /* traffic not in our bss */
+ uint32 interference; /* millisecs detecting a non 802.11 interferer. */
+ uint32 timestamp; /* second timestamp */
+} cca_congest_t;
+
+typedef struct {
+ chanspec_t chanspec; /* Which channel? */
+ uint8 num_secs; /* How many secs worth of data */
+ cca_congest_t secs[1]; /* Data */
+} cca_congest_channel_req_t;
+
+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */
+
+typedef struct wl_country {
+ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in
+ * the Country IE
+ */
+ int32 rev; /* revision specifier for ccode
+ * on set, -1 indicates unspecified.
+ * on get, rev >= 0
+ */
+ char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code.
+ * variable length, but fixed size in
+ * struct allows simple allocation for
+ * expected country strings <= 3 chars.
+ */
+} wl_country_t;
+
+typedef struct wl_channels_in_country {
+ uint32 buflen;
+ uint32 band;
+ char country_abbrev[WLC_CNTRY_BUF_SZ];
+ uint32 count;
+ uint32 channel[1];
+} wl_channels_in_country_t;
+
+typedef struct wl_country_list {
+ uint32 buflen;
+ uint32 band_set;
+ uint32 band;
+ uint32 count;
+ char country_abbrev[1];
+} wl_country_list_t;
+
+#define WL_NUM_RPI_BINS 8
+#define WL_RM_TYPE_BASIC 1
+#define WL_RM_TYPE_CCA 2
+#define WL_RM_TYPE_RPI 3
+
+#define WL_RM_FLAG_PARALLEL (1<<0)
+
+#define WL_RM_FLAG_LATE (1<<1)
+#define WL_RM_FLAG_INCAPABLE (1<<2)
+#define WL_RM_FLAG_REFUSED (1<<3)
+
+typedef struct wl_rm_req_elt {
+ int8 type;
+ int8 flags;
+ chanspec_t chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+} wl_rm_req_elt_t;
+
+typedef struct wl_rm_req {
+ uint32 token; /* overall measurement set token */
+ uint32 count; /* number of measurement requests */
+ void *cb; /* completion callback function: may be NULL */
+ void *cb_arg; /* arg to completion callback function */
+ wl_rm_req_elt_t req[1]; /* variable length block of requests */
+} wl_rm_req_t;
+#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req)
+
+typedef struct wl_rm_rep_elt {
+ int8 type;
+ int8 flags;
+ chanspec_t chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+ uint32 len; /* byte length of data block */
+ uint8 data[1]; /* variable length data block */
+} wl_rm_rep_elt_t;
+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */
+
+#define WL_RPI_REP_BIN_NUM 8
+typedef struct wl_rm_rpi_rep {
+ uint8 rpi[WL_RPI_REP_BIN_NUM];
+ int8 rpi_max[WL_RPI_REP_BIN_NUM];
+} wl_rm_rpi_rep_t;
+
+typedef struct wl_rm_rep {
+ uint32 token; /* overall measurement set token */
+ uint32 len; /* length of measurement report block */
+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */
+} wl_rm_rep_t;
+#define WL_RM_REP_FIXED_LEN 8
+
+/* Enumerate crypto algorithms */
+#define CRYPTO_ALGO_OFF 0
+#define CRYPTO_ALGO_WEP1 1
+#define CRYPTO_ALGO_TKIP 2
+#define CRYPTO_ALGO_WEP128 3
+#define CRYPTO_ALGO_AES_CCM 4
+#define CRYPTO_ALGO_AES_RESERVED1 5
+#define CRYPTO_ALGO_AES_RESERVED2 6
+#define CRYPTO_ALGO_NALG 7
+
+#define WSEC_GEN_MIC_ERROR 0x0001
+#define WSEC_GEN_REPLAY 0x0002
+#define WSEC_GEN_ICV_ERROR 0x0004
+
+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */
+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */
+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */
+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */
+#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */
+
+typedef struct wl_wsec_key {
+ uint32 index; /* key index */
+ uint32 len; /* key length */
+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */
+ uint32 pad_1[18];
+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+ uint32 flags; /* misc flags */
+ uint32 pad_2[2];
+ int pad_3;
+ int iv_initialized; /* has IV been initialized already? */
+ int pad_4;
+ /* Rx IV */
+ struct {
+ uint32 hi; /* upper 32 bits of IV */
+ uint16 lo; /* lower 16 bits of IV */
+ } rxiv;
+ uint32 pad_5[2];
+ struct ether_addr ea; /* per station */
+} wl_wsec_key_t;
+
+#define WSEC_MIN_PSK_LEN 8
+#define WSEC_MAX_PSK_LEN 64
+
+/* Flag for key material needing passhash'ing */
+#define WSEC_PASSPHRASE (1<<0)
+
+/* receptacle for WLC_SET_WSEC_PMK parameter */
+typedef struct {
+ ushort key_len; /* octets in key material */
+ ushort flags; /* key handling qualification */
+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */
+} wsec_pmk_t;
+
+/* wireless security bitvec */
+#define WEP_ENABLED 0x0001
+#define TKIP_ENABLED 0x0002
+#define AES_ENABLED 0x0004
+#define WSEC_SWFLAG 0x0008
+#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */
+
+/* WPA authentication mode bitvec */
+#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
+#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */
+#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */
+#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */
+#define WPA_AUTH_RESERVED1 0x0008
+#define WPA_AUTH_RESERVED2 0x0010
+ /* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */
+#define WPA2_AUTH_RESERVED1 0x0020
+#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */
+#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */
+#define WPA2_AUTH_RESERVED3 0x0200
+#define WPA2_AUTH_RESERVED4 0x0400
+#define WPA2_AUTH_RESERVED5 0x0800
+
+/* pmkid */
+#define MAXPMKID 16
+
+typedef struct _pmkid {
+ struct ether_addr BSSID;
+ uint8 PMKID[WPA2_PMKID_LEN];
+} pmkid_t;
+
+typedef struct _pmkid_list {
+ uint32 npmkid;
+ pmkid_t pmkid[1];
+} pmkid_list_t;
+
+typedef struct _pmkid_cand {
+ struct ether_addr BSSID;
+ uint8 preauth;
+} pmkid_cand_t;
+
+typedef struct _pmkid_cand_list {
+ uint32 npmkid_cand;
+ pmkid_cand_t pmkid_cand[1];
+} pmkid_cand_list_t;
+
+typedef struct wl_led_info {
+ uint32 index; /* led index */
+ uint32 behavior;
+ uint8 activehi;
+} wl_led_info_t;
+
+typedef struct wl_assoc_info {
+ uint32 req_len;
+ uint32 resp_len;
+ uint32 flags;
+ struct dot11_assoc_req req;
+ struct ether_addr reassoc_bssid; /* used in reassoc's */
+ struct dot11_assoc_resp resp;
+} wl_assoc_info_t;
+
+/* flags */
+#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */
+
+/* srom read/write struct passed through ioctl */
+typedef struct {
+ uint byteoff; /* byte offset */
+ uint nbytes; /* number of bytes */
+ uint16 buf[1];
+} srom_rw_t;
+
+/* similar cis (srom or otp) struct [iovar: may not be aligned] */
+typedef struct {
+ uint32 source; /* cis source */
+ uint32 byteoff; /* byte offset */
+ uint32 nbytes; /* number of bytes */
+ /* data follows here */
+} cis_rw_t;
+
+#define WLC_CIS_DEFAULT 0 /* built-in default */
+#define WLC_CIS_SROM 1 /* source is sprom */
+#define WLC_CIS_OTP 2 /* source is otp */
+
+/* R_REG and W_REG struct passed through ioctl */
+typedef struct {
+ uint32 byteoff; /* byte offset of the field in d11regs_t */
+ uint32 val; /* read/write value of the field */
+ uint32 size; /* sizeof the field */
+ uint band; /* band (optional) */
+} rw_reg_t;
+
+/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */
+/* PCL - Power Control Loop */
+/* current gain setting is replaced by user input */
+#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */
+#define WL_ATTEN_PCL_ON 1 /* turn on PCL */
+/* current gain setting is maintained */
+#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */
+
+typedef struct {
+ uint16 auto_ctrl; /* WL_ATTEN_XX */
+ uint16 bb; /* Baseband attenuation */
+ uint16 radio; /* Radio attenuation */
+ uint16 txctl1; /* Radio TX_CTL1 value */
+} atten_t;
+
+/* Per-AC retry parameters */
+struct wme_tx_params_s {
+ uint8 short_retry;
+ uint8 short_fallback;
+ uint8 long_retry;
+ uint8 long_fallback;
+ uint16 max_rate; /* In units of 512 Kbps */
+};
+
+typedef struct wme_tx_params_s wme_tx_params_t;
+
+#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT)
+
+/* defines used by poweridx iovar - it controls power in a-band */
+/* current gain setting is maintained */
+#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */
+#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */
+#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */
+#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */
+/* value >= 0 causes
+ * - input to be set to that value
+ * - PCL to be off
+ */
+
+/* Used to get specific link/ac parameters */
+typedef struct {
+ int ac;
+ uint8 val;
+ struct ether_addr ea;
+} link_val_t;
+
+#define BCM_MAC_STATUS_INDICATION (0x40010200L)
+
+typedef struct {
+ uint16 ver; /* version of this struct */
+ uint16 len; /* length in bytes of this structure */
+ uint16 cap; /* sta's advertised capabilities */
+ uint32 flags; /* flags defined below */
+ uint32 idle; /* time since data pkt rx'd from sta */
+ struct ether_addr ea; /* Station address */
+ wl_rateset_t rateset; /* rateset in use */
+ uint32 in; /* seconds elapsed since associated */
+ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */
+ uint32 tx_pkts; /* # of packets transmitted */
+ uint32 tx_failures; /* # of packets failed */
+ uint32 rx_ucast_pkts; /* # of unicast packets received */
+ uint32 rx_mcast_pkts; /* # of multicast packets received */
+ uint32 tx_rate; /* Rate of last successful tx frame */
+ uint32 rx_rate; /* Rate of last successful rx frame */
+ uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
+ uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */
+} sta_info_t;
+
+#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts)
+
+#define WL_STA_VER 3
+
+/* Flags for sta_info_t indicating properties of STA */
+#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */
+#define WL_STA_WME 0x2 /* WMM association */
+#define WL_STA_ABCAP 0x4
+#define WL_STA_AUTHE 0x8 /* Authenticated */
+#define WL_STA_ASSOC 0x10 /* Associated */
+#define WL_STA_AUTHO 0x20 /* Authorized */
+#define WL_STA_WDS 0x40 /* Wireless Distribution System */
+#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */
+#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */
+#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */
+#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */
+#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */
+#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */
+#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */
+#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */
+
+#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */
+
+/* Used to get specific STA parameters */
+typedef struct {
+ uint32 val;
+ struct ether_addr ea;
+} scb_val_t;
+
+/* channel encoding */
+typedef struct channel_info {
+ int hw_channel;
+ int target_channel;
+ int scan_channel;
+} channel_info_t;
+
+/* For ioctls that take a list of MAC addresses */
+struct maclist {
+ uint count; /* number of MAC addresses */
+ struct ether_addr ea[1]; /* variable length array of MAC addresses */
+};
+
+/* get pkt count struct passed through ioctl */
+typedef struct get_pktcnt {
+ uint rx_good_pkt;
+ uint rx_bad_pkt;
+ uint tx_good_pkt;
+ uint tx_bad_pkt;
+ uint rx_ocast_good_pkt; /* unicast packets destined for others */
+} get_pktcnt_t;
+
+/* Linux network driver ioctl encoding */
+typedef struct wl_ioctl {
+ uint cmd; /* common ioctl definition */
+ void *buf; /* pointer to user buffer */
+ uint len; /* length of user buffer */
+ uint8 set; /* get or set request (optional) */
+ uint used; /* bytes read or written (optional) */
+ uint needed; /* bytes needed (optional) */
+} wl_ioctl_t;
+
+/* reference to wl_ioctl_t struct used by usermode driver */
+#define ioctl_subtype set /* subtype param */
+#define ioctl_pid used /* pid param */
+#define ioctl_status needed /* status param */
+
+/*
+ * Structure for passing hardware and software
+ * revision info up from the driver.
+ */
+typedef struct wlc_rev_info {
+ uint vendorid; /* PCI vendor id */
+ uint deviceid; /* device id of chip */
+ uint radiorev; /* radio revision */
+ uint chiprev; /* chip revision */
+ uint corerev; /* core revision */
+ uint boardid; /* board identifier (usu. PCI sub-device id) */
+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */
+ uint boardrev; /* board revision */
+ uint driverrev; /* driver version */
+ uint ucoderev; /* microcode version */
+ uint bus; /* bus type */
+ uint chipnum; /* chip number */
+ uint phytype; /* phy type */
+ uint phyrev; /* phy revision */
+ uint anarev; /* anacore rev */
+ uint chippkg; /* chip package info */
+} wlc_rev_info_t;
+
+#define WL_REV_INFO_LEGACY_LENGTH 48
+
+#define WL_BRAND_MAX 10
+typedef struct wl_instance_info {
+ uint instance;
+ char brand[WL_BRAND_MAX];
+} wl_instance_info_t;
+
+/* structure to change size of tx fifo */
+typedef struct wl_txfifo_sz {
+ uint16 magic;
+ uint16 fifo;
+ uint16 size;
+} wl_txfifo_sz_t;
+/* magic pattern used for mismatch driver and wl */
+#define WL_TXFIFO_SZ_MAGIC 0xa5a5
+
+/* Transfer info about an IOVar from the driver */
+/* Max supported IOV name size in bytes, + 1 for nul termination */
+#define WLC_IOV_NAME_LEN 30
+typedef struct wlc_iov_trx_s {
+ uint8 module;
+ uint8 type;
+ char name[WLC_IOV_NAME_LEN];
+} wlc_iov_trx_t;
+
+/* check this magic number */
+#define WLC_IOCTL_MAGIC 0x14e46c77
+
+#define PROC_ENTRY_NAME "brcm_debug"
+/* bump this number if you change the ioctl interface */
+#define WLC_IOCTL_VERSION 1
+
+#define WLC_IOCTL_MAXLEN 3072 /* max length ioctl buffer required */
+#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */
+#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */
+#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */
+
+/* common ioctl definitions */
+#define WLC_GET_MAGIC 0
+#define WLC_GET_VERSION 1
+#define WLC_UP 2
+#define WLC_DOWN 3
+#define WLC_GET_LOOP 4
+#define WLC_SET_LOOP 5
+#define WLC_DUMP 6
+#define WLC_GET_MSGLEVEL 7
+#define WLC_SET_MSGLEVEL 8
+#define WLC_GET_PROMISC 9
+#define WLC_SET_PROMISC 10
+#define WLC_OVERLAY_IOCTL 11
+#define WLC_GET_RATE 12
+ /* #define WLC_SET_RATE 13 *//* no longer supported */
+#define WLC_GET_INSTANCE 14
+ /* #define WLC_GET_FRAG 15 *//* no longer supported */
+ /* #define WLC_SET_FRAG 16 *//* no longer supported */
+ /* #define WLC_GET_RTS 17 *//* no longer supported */
+ /* #define WLC_SET_RTS 18 *//* no longer supported */
+#define WLC_GET_INFRA 19
+#define WLC_SET_INFRA 20
+#define WLC_GET_AUTH 21
+#define WLC_SET_AUTH 22
+#define WLC_GET_BSSID 23
+#define WLC_SET_BSSID 24
+#define WLC_GET_SSID 25
+#define WLC_SET_SSID 26
+#define WLC_RESTART 27
+ /* #define WLC_DUMP_SCB 28 *//* no longer supported */
+#define WLC_GET_CHANNEL 29
+#define WLC_SET_CHANNEL 30
+#define WLC_GET_SRL 31
+#define WLC_SET_SRL 32
+#define WLC_GET_LRL 33
+#define WLC_SET_LRL 34
+#define WLC_GET_PLCPHDR 35
+#define WLC_SET_PLCPHDR 36
+#define WLC_GET_RADIO 37
+#define WLC_SET_RADIO 38
+#define WLC_GET_PHYTYPE 39
+#define WLC_DUMP_RATE 40
+#define WLC_SET_RATE_PARAMS 41
+#define WLC_GET_FIXRATE 42
+#define WLC_SET_FIXRATE 43
+ /* #define WLC_GET_WEP 42 *//* no longer supported */
+ /* #define WLC_SET_WEP 43 *//* no longer supported */
+#define WLC_GET_KEY 44
+#define WLC_SET_KEY 45
+#define WLC_GET_REGULATORY 46
+#define WLC_SET_REGULATORY 47
+#define WLC_GET_PASSIVE_SCAN 48
+#define WLC_SET_PASSIVE_SCAN 49
+#define WLC_SCAN 50
+#define WLC_SCAN_RESULTS 51
+#define WLC_DISASSOC 52
+#define WLC_REASSOC 53
+#define WLC_GET_ROAM_TRIGGER 54
+#define WLC_SET_ROAM_TRIGGER 55
+#define WLC_GET_ROAM_DELTA 56
+#define WLC_SET_ROAM_DELTA 57
+#define WLC_GET_ROAM_SCAN_PERIOD 58
+#define WLC_SET_ROAM_SCAN_PERIOD 59
+#define WLC_EVM 60 /* diag */
+#define WLC_GET_TXANT 61
+#define WLC_SET_TXANT 62
+#define WLC_GET_ANTDIV 63
+#define WLC_SET_ANTDIV 64
+ /* #define WLC_GET_TXPWR 65 *//* no longer supported */
+ /* #define WLC_SET_TXPWR 66 *//* no longer supported */
+#define WLC_GET_CLOSED 67
+#define WLC_SET_CLOSED 68
+#define WLC_GET_MACLIST 69
+#define WLC_SET_MACLIST 70
+#define WLC_GET_RATESET 71
+#define WLC_SET_RATESET 72
+ /* #define WLC_GET_LOCALE 73 *//* no longer supported */
+#define WLC_LONGTRAIN 74
+#define WLC_GET_BCNPRD 75
+#define WLC_SET_BCNPRD 76
+#define WLC_GET_DTIMPRD 77
+#define WLC_SET_DTIMPRD 78
+#define WLC_GET_SROM 79
+#define WLC_SET_SROM 80
+#define WLC_GET_WEP_RESTRICT 81
+#define WLC_SET_WEP_RESTRICT 82
+#define WLC_GET_COUNTRY 83
+#define WLC_SET_COUNTRY 84
+#define WLC_GET_PM 85
+#define WLC_SET_PM 86
+#define WLC_GET_WAKE 87
+#define WLC_SET_WAKE 88
+ /* #define WLC_GET_D11CNTS 89 *//* -> "counters" iovar */
+#define WLC_GET_FORCELINK 90 /* ndis only */
+#define WLC_SET_FORCELINK 91 /* ndis only */
+#define WLC_FREQ_ACCURACY 92 /* diag */
+#define WLC_CARRIER_SUPPRESS 93 /* diag */
+#define WLC_GET_PHYREG 94
+#define WLC_SET_PHYREG 95
+#define WLC_GET_RADIOREG 96
+#define WLC_SET_RADIOREG 97
+#define WLC_GET_REVINFO 98
+#define WLC_GET_UCANTDIV 99
+#define WLC_SET_UCANTDIV 100
+#define WLC_R_REG 101
+#define WLC_W_REG 102
+/* #define WLC_DIAG_LOOPBACK 103 old tray diag */
+ /* #define WLC_RESET_D11CNTS 104 *//* -> "reset_d11cnts" iovar */
+#define WLC_GET_MACMODE 105
+#define WLC_SET_MACMODE 106
+#define WLC_GET_MONITOR 107
+#define WLC_SET_MONITOR 108
+#define WLC_GET_GMODE 109
+#define WLC_SET_GMODE 110
+#define WLC_GET_LEGACY_ERP 111
+#define WLC_SET_LEGACY_ERP 112
+#define WLC_GET_RX_ANT 113
+#define WLC_GET_CURR_RATESET 114 /* current rateset */
+#define WLC_GET_SCANSUPPRESS 115
+#define WLC_SET_SCANSUPPRESS 116
+#define WLC_GET_AP 117
+#define WLC_SET_AP 118
+#define WLC_GET_EAP_RESTRICT 119
+#define WLC_SET_EAP_RESTRICT 120
+#define WLC_SCB_AUTHORIZE 121
+#define WLC_SCB_DEAUTHORIZE 122
+#define WLC_GET_WDSLIST 123
+#define WLC_SET_WDSLIST 124
+#define WLC_GET_ATIM 125
+#define WLC_SET_ATIM 126
+#define WLC_GET_RSSI 127
+#define WLC_GET_PHYANTDIV 128
+#define WLC_SET_PHYANTDIV 129
+#define WLC_AP_RX_ONLY 130
+#define WLC_GET_TX_PATH_PWR 131
+#define WLC_SET_TX_PATH_PWR 132
+#define WLC_GET_WSEC 133
+#define WLC_SET_WSEC 134
+#define WLC_GET_PHY_NOISE 135
+#define WLC_GET_BSS_INFO 136
+#define WLC_GET_PKTCNTS 137
+#define WLC_GET_LAZYWDS 138
+#define WLC_SET_LAZYWDS 139
+#define WLC_GET_BANDLIST 140
+#define WLC_GET_BAND 141
+#define WLC_SET_BAND 142
+#define WLC_SCB_DEAUTHENTICATE 143
+#define WLC_GET_SHORTSLOT 144
+#define WLC_GET_SHORTSLOT_OVERRIDE 145
+#define WLC_SET_SHORTSLOT_OVERRIDE 146
+#define WLC_GET_SHORTSLOT_RESTRICT 147
+#define WLC_SET_SHORTSLOT_RESTRICT 148
+#define WLC_GET_GMODE_PROTECTION 149
+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150
+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151
+#define WLC_UPGRADE 152
+ /* #define WLC_GET_MRATE 153 *//* no longer supported */
+ /* #define WLC_SET_MRATE 154 *//* no longer supported */
+#define WLC_GET_IGNORE_BCNS 155
+#define WLC_SET_IGNORE_BCNS 156
+#define WLC_GET_SCB_TIMEOUT 157
+#define WLC_SET_SCB_TIMEOUT 158
+#define WLC_GET_ASSOCLIST 159
+#define WLC_GET_CLK 160
+#define WLC_SET_CLK 161
+#define WLC_GET_UP 162
+#define WLC_OUT 163
+#define WLC_GET_WPA_AUTH 164
+#define WLC_SET_WPA_AUTH 165
+#define WLC_GET_UCFLAGS 166
+#define WLC_SET_UCFLAGS 167
+#define WLC_GET_PWRIDX 168
+#define WLC_SET_PWRIDX 169
+#define WLC_GET_TSSI 170
+#define WLC_GET_SUP_RATESET_OVERRIDE 171
+#define WLC_SET_SUP_RATESET_OVERRIDE 172
+ /* #define WLC_SET_FAST_TIMER 173 *//* no longer supported */
+ /* #define WLC_GET_FAST_TIMER 174 *//* no longer supported */
+ /* #define WLC_SET_SLOW_TIMER 175 *//* no longer supported */
+ /* #define WLC_GET_SLOW_TIMER 176 *//* no longer supported */
+ /* #define WLC_DUMP_PHYREGS 177 *//* no longer supported */
+#define WLC_GET_PROTECTION_CONTROL 178
+#define WLC_SET_PROTECTION_CONTROL 179
+#define WLC_GET_PHYLIST 180
+#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */
+#define WLC_DECRYPT_STATUS 182 /* ndis only */
+#define WLC_GET_KEY_SEQ 183
+#define WLC_GET_SCAN_CHANNEL_TIME 184
+#define WLC_SET_SCAN_CHANNEL_TIME 185
+#define WLC_GET_SCAN_UNASSOC_TIME 186
+#define WLC_SET_SCAN_UNASSOC_TIME 187
+#define WLC_GET_SCAN_HOME_TIME 188
+#define WLC_SET_SCAN_HOME_TIME 189
+#define WLC_GET_SCAN_NPROBES 190
+#define WLC_SET_SCAN_NPROBES 191
+#define WLC_GET_PRB_RESP_TIMEOUT 192
+#define WLC_SET_PRB_RESP_TIMEOUT 193
+#define WLC_GET_ATTEN 194
+#define WLC_SET_ATTEN 195
+#define WLC_GET_SHMEM 196 /* diag */
+#define WLC_SET_SHMEM 197 /* diag */
+ /* #define WLC_GET_GMODE_PROTECTION_CTS 198 *//* no longer supported */
+ /* #define WLC_SET_GMODE_PROTECTION_CTS 199 *//* no longer supported */
+#define WLC_SET_WSEC_TEST 200
+#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201
+#define WLC_TKIP_COUNTERMEASURES 202
+#define WLC_GET_PIOMODE 203
+#define WLC_SET_PIOMODE 204
+#define WLC_SET_ASSOC_PREFER 205
+#define WLC_GET_ASSOC_PREFER 206
+#define WLC_SET_ROAM_PREFER 207
+#define WLC_GET_ROAM_PREFER 208
+#define WLC_SET_LED 209
+#define WLC_GET_LED 210
+#define WLC_RESERVED6 211
+#define WLC_RESERVED7 212
+#define WLC_GET_CHANNEL_QA 213
+#define WLC_START_CHANNEL_QA 214
+#define WLC_GET_CHANNEL_SEL 215
+#define WLC_START_CHANNEL_SEL 216
+#define WLC_GET_VALID_CHANNELS 217
+#define WLC_GET_FAKEFRAG 218
+#define WLC_SET_FAKEFRAG 219
+#define WLC_GET_PWROUT_PERCENTAGE 220
+#define WLC_SET_PWROUT_PERCENTAGE 221
+#define WLC_SET_BAD_FRAME_PREEMPT 222
+#define WLC_GET_BAD_FRAME_PREEMPT 223
+#define WLC_SET_LEAP_LIST 224
+#define WLC_GET_LEAP_LIST 225
+#define WLC_GET_CWMIN 226
+#define WLC_SET_CWMIN 227
+#define WLC_GET_CWMAX 228
+#define WLC_SET_CWMAX 229
+#define WLC_GET_WET 230
+#define WLC_SET_WET 231
+#define WLC_GET_PUB 232
+ /* #define WLC_SET_GLACIAL_TIMER 233 *//* no longer supported */
+ /* #define WLC_GET_GLACIAL_TIMER 234 *//* no longer supported */
+#define WLC_GET_KEY_PRIMARY 235
+#define WLC_SET_KEY_PRIMARY 236
+ /* #define WLC_DUMP_RADIOREGS 237 *//* no longer supported */
+#define WLC_RESERVED4 238
+#define WLC_RESERVED5 239
+#define WLC_UNSET_CALLBACK 240
+#define WLC_SET_CALLBACK 241
+#define WLC_GET_RADAR 242
+#define WLC_SET_RADAR 243
+#define WLC_SET_SPECT_MANAGMENT 244
+#define WLC_GET_SPECT_MANAGMENT 245
+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */
+#define WLC_WDS_GET_WPA_SUP 247
+#define WLC_SET_CS_SCAN_TIMER 248
+#define WLC_GET_CS_SCAN_TIMER 249
+#define WLC_MEASURE_REQUEST 250
+#define WLC_INIT 251
+#define WLC_SEND_QUIET 252
+#define WLC_KEEPALIVE 253
+#define WLC_SEND_PWR_CONSTRAINT 254
+#define WLC_UPGRADE_STATUS 255
+#define WLC_CURRENT_PWR 256
+#define WLC_GET_SCAN_PASSIVE_TIME 257
+#define WLC_SET_SCAN_PASSIVE_TIME 258
+#define WLC_LEGACY_LINK_BEHAVIOR 259
+#define WLC_GET_CHANNELS_IN_COUNTRY 260
+#define WLC_GET_COUNTRY_LIST 261
+#define WLC_GET_VAR 262 /* get value of named variable */
+#define WLC_SET_VAR 263 /* set named variable to value */
+#define WLC_NVRAM_GET 264 /* deprecated */
+#define WLC_NVRAM_SET 265
+#define WLC_NVRAM_DUMP 266
+#define WLC_REBOOT 267
+#define WLC_SET_WSEC_PMK 268
+#define WLC_GET_AUTH_MODE 269
+#define WLC_SET_AUTH_MODE 270
+#define WLC_GET_WAKEENTRY 271
+#define WLC_SET_WAKEENTRY 272
+#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */
+#define WLC_NVOTPW 274
+#define WLC_OTPW 275
+#define WLC_IOV_BLOCK_GET 276
+#define WLC_IOV_MODULES_GET 277
+#define WLC_SOFT_RESET 278
+#define WLC_GET_ALLOW_MODE 279
+#define WLC_SET_ALLOW_MODE 280
+#define WLC_GET_DESIRED_BSSID 281
+#define WLC_SET_DESIRED_BSSID 282
+#define WLC_DISASSOC_MYAP 283
+#define WLC_GET_RESERVED10 284
+#define WLC_GET_RESERVED11 285
+#define WLC_GET_RESERVED12 286
+#define WLC_GET_RESERVED13 287
+#define WLC_GET_RESERVED14 288
+#define WLC_SET_RESERVED15 289
+#define WLC_SET_RESERVED16 290
+#define WLC_GET_RESERVED17 291
+#define WLC_GET_RESERVED18 292
+#define WLC_GET_RESERVED19 293
+#define WLC_SET_RESERVED1A 294
+#define WLC_GET_RESERVED1B 295
+#define WLC_GET_RESERVED1C 296
+#define WLC_GET_RESERVED1D 297
+#define WLC_SET_RESERVED1E 298
+#define WLC_GET_RESERVED1F 299
+#define WLC_GET_RESERVED20 300
+#define WLC_GET_RESERVED21 301
+#define WLC_GET_RESERVED22 302
+#define WLC_GET_RESERVED23 303
+#define WLC_GET_RESERVED24 304
+#define WLC_SET_RESERVED25 305
+#define WLC_GET_RESERVED26 306
+#define WLC_NPHY_SAMPLE_COLLECT 307 /* Nphy sample collect mode */
+#define WLC_UM_PRIV 308 /* for usermode driver private ioctl */
+#define WLC_GET_CMD 309
+ /* #define WLC_LAST 310 *//* Never used - can be reused */
+#define WLC_RESERVED8 311
+#define WLC_RESERVED9 312
+#define WLC_RESERVED1 313
+#define WLC_RESERVED2 314
+#define WLC_RESERVED3 315
+#define WLC_LAST 316
+
+#ifndef EPICTRL_COOKIE
+#define EPICTRL_COOKIE 0xABADCEDE
+#endif
+
+#define WL_DECRYPT_STATUS_SUCCESS 1
+#define WL_DECRYPT_STATUS_FAILURE 2
+#define WL_DECRYPT_STATUS_UNKNOWN 3
+
+/* allows user-mode app to poll the status of USB image upgrade */
+#define WLC_UPGRADE_SUCCESS 0
+#define WLC_UPGRADE_PENDING 1
+
+/* WLC_GET_AUTH, WLC_SET_AUTH values */
+#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */
+#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
+#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */
+
+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
+#define WL_RADIO_SW_DISABLE (1<<0)
+#define WL_RADIO_HW_DISABLE (1<<1)
+#define WL_RADIO_MPC_DISABLE (1<<2)
+#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */
+
+#define WL_SPURAVOID_OFF 0
+#define WL_SPURAVOID_ON1 1
+#define WL_SPURAVOID_ON2 2
+
+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */
+#define WL_TXPWR_OVERRIDE (1U<<31)
+
+#define WL_PHY_PAVARS_LEN 6 /* Phy type, Band range, chain, a1, b0, b1 */
+
+typedef struct wl_po {
+ uint16 phy_type; /* Phy type */
+ uint16 band;
+ uint16 cckpo;
+ uint32 ofdmpo;
+ uint16 mcspo[8];
+} wl_po_t;
+
+/* a large TX Power as an init value to factor out of MIN() calculations,
+ * keep low enough to fit in an int8, units are .25 dBm
+ */
+#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
+
+/* "diag" iovar argument and error code */
+#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */
+#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */
+#define WL_DIAG_MEMORY 3 /* d11 memory test */
+#define WL_DIAG_LED 4 /* LED test */
+#define WL_DIAG_REG 5 /* d11/phy register test */
+#define WL_DIAG_SROM 6 /* srom read/crc test */
+#define WL_DIAG_DMA 7 /* DMA test */
+
+#define WL_DIAGERR_SUCCESS 0
+#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */
+#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */
+#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */
+#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */
+#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */
+#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */
+#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */
+#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */
+#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */
+#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */
+
+#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */
+#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */
+
+/* band types */
+#define WLC_BAND_AUTO 0 /* auto-select */
+#define WLC_BAND_5G 1 /* 5 Ghz */
+#define WLC_BAND_2G 2 /* 2.4 Ghz */
+#define WLC_BAND_ALL 3 /* all bands */
+
+/* band range returned by band_range iovar */
+#define WL_CHAN_FREQ_RANGE_2G 0
+#define WL_CHAN_FREQ_RANGE_5GL 1
+#define WL_CHAN_FREQ_RANGE_5GM 2
+#define WL_CHAN_FREQ_RANGE_5GH 3
+
+/* phy types (returned by WLC_GET_PHYTPE) */
+#define WLC_PHY_TYPE_A 0
+#define WLC_PHY_TYPE_B 1
+#define WLC_PHY_TYPE_G 2
+#define WLC_PHY_TYPE_N 4
+#define WLC_PHY_TYPE_LP 5
+#define WLC_PHY_TYPE_SSN 6
+#define WLC_PHY_TYPE_HT 7
+#define WLC_PHY_TYPE_LCN 8
+#define WLC_PHY_TYPE_NULL 0xf
+
+/* MAC list modes */
+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */
+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */
+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */
+
+/*
+ * 54g modes (basic bits may still be overridden)
+ *
+ * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11
+ * Preamble: Long
+ * Shortslot: Off
+ * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+ * Extended Rateset: 6, 9, 12, 48
+ * Preamble: Long
+ * Shortslot: Auto
+ * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
+ * Extended Rateset: 6b, 9, 12b, 48
+ * Preamble: Short required
+ * Shortslot: Auto
+ * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+ * Extended Rateset: 6, 9, 12, 48
+ * Preamble: Long
+ * Shortslot: On
+ * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
+ * Preamble: Short required
+ * Shortslot: On and required
+ * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b
+ * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
+ * Preamble: Long
+ * Shortslot: Auto
+ */
+#define GMODE_LEGACY_B 0
+#define GMODE_AUTO 1
+#define GMODE_ONLY 2
+#define GMODE_B_DEFERRED 3
+#define GMODE_PERFORMANCE 4
+#define GMODE_LRS 5
+#define GMODE_MAX 6
+
+/* values for PLCPHdr_override */
+#define WLC_PLCP_AUTO -1
+#define WLC_PLCP_SHORT 0
+#define WLC_PLCP_LONG 1
+
+/* values for g_protection_override and n_protection_override */
+#define WLC_PROTECTION_AUTO -1
+#define WLC_PROTECTION_OFF 0
+#define WLC_PROTECTION_ON 1
+#define WLC_PROTECTION_MMHDR_ONLY 2
+#define WLC_PROTECTION_CTS_ONLY 3
+
+/* values for g_protection_control and n_protection_control */
+#define WLC_PROTECTION_CTL_OFF 0
+#define WLC_PROTECTION_CTL_LOCAL 1
+#define WLC_PROTECTION_CTL_OVERLAP 2
+
+/* values for n_protection */
+#define WLC_N_PROTECTION_OFF 0
+#define WLC_N_PROTECTION_OPTIONAL 1
+#define WLC_N_PROTECTION_20IN40 2
+#define WLC_N_PROTECTION_MIXEDMODE 3
+
+/* values for n_preamble_type */
+#define WLC_N_PREAMBLE_MIXEDMODE 0
+#define WLC_N_PREAMBLE_GF 1
+#define WLC_N_PREAMBLE_GF_BRCM 2
+
+/* values for band specific 40MHz capabilities */
+#define WLC_N_BW_20ALL 0
+#define WLC_N_BW_40ALL 1
+#define WLC_N_BW_20IN2G_40IN5G 2
+
+/* values to force tx/rx chain */
+#define WLC_N_TXRX_CHAIN0 0
+#define WLC_N_TXRX_CHAIN1 1
+
+/* bitflags for SGI support (sgi_rx iovar) */
+#define WLC_N_SGI_20 0x01
+#define WLC_N_SGI_40 0x02
+
+/* Values for PM */
+#define PM_OFF 0
+#define PM_MAX 1
+
+/* interference mitigation options */
+#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */
+#define INTERFERE_NONE 0 /* off */
+#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */
+#define WLAN_MANUAL 2 /* ACI: no auto detection */
+#define WLAN_AUTO 3 /* ACI: auto detect */
+#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */
+#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */
+
+#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */
+#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
+#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
+#define WL_ANT_IDX_1 0 /* antenna index 1 */
+#define WL_ANT_IDX_2 1 /* antenna index 2 */
+
+#ifndef WL_RSSI_ANT_MAX
+#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
+#elif WL_RSSI_ANT_MAX != 4
+#error "WL_RSSI_ANT_MAX does not match"
+#endif
+
+/* RSSI per antenna */
+typedef struct {
+ uint32 version; /* version field */
+ uint32 count; /* number of valid antenna rssi */
+ int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */
+} wl_rssi_ant_t;
+
+#define NUM_PWRCTRL_RATES 12
+
+typedef struct {
+ uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */
+ uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */
+ uint8 txpwr_local_max; /* local max according to the AP */
+ uint8 txpwr_local_constraint; /* local constraint according to the AP */
+ uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */
+ uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */
+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
+ uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */
+ uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */
+ uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */
+ uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */
+ int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
+} tx_power_legacy_t;
+
+#define WL_TX_POWER_RATES_LEGACY 45
+#define WL_TX_POWER_MCS20_FIRST 12
+#define WL_TX_POWER_MCS20_NUM 16
+#define WL_TX_POWER_MCS40_FIRST 28
+#define WL_TX_POWER_MCS40_NUM 17
+
+typedef struct {
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 local_max; /* local max according to the AP */
+ uint8 local_constraint; /* local constraint according to the AP */
+ int8 antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 rf_cores; /* count of RF Cores being reported */
+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF
+ * chain without adjustment
+ */
+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */
+ uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */
+ uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */
+ uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */
+ uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */
+} tx_power_legacy2_t;
+
+#define WL_TX_POWER_RATES 101
+#define WL_TX_POWER_CCK_FIRST 0
+#define WL_TX_POWER_CCK_NUM 4
+#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */
+#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */
+#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */
+#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */
+#define WL_TX_POWER_OFDM_NUM 8
+#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */
+#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */
+#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */
+#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */
+#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */
+#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */
+#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */
+#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */
+#define WL_TX_POWER_MCS_1_STREAM_NUM 8
+#define WL_TX_POWER_MCS_2_STREAM_NUM 8
+#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */
+#define WL_TX_POWER_MCS_32_NUM 1
+
+/* sslpnphy specifics */
+#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */
+
+/* tx_power_t.flags bits */
+#define WL_TX_POWER_F_ENABLED 1
+#define WL_TX_POWER_F_HW 2
+#define WL_TX_POWER_F_MIMO 4
+#define WL_TX_POWER_F_SISO 8
+
+typedef struct {
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 local_max; /* local max according to the AP */
+ uint8 local_constraint; /* local constraint according to the AP */
+ int8 antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 rf_cores; /* count of RF Cores being reported */
+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
+ * without adjustment
+ */
+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */
+ uint8 tx_power_max[4]; /* Maximum target power among all rates */
+ uint8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
+ uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */
+ uint8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */
+ uint8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */
+ uint8 target[WL_TX_POWER_RATES]; /* Latest target power */
+} tx_power_t;
+
+typedef struct tx_inst_power {
+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
+} tx_inst_power_t;
+
+/* Message levels */
+#define WL_ERROR_VAL 0x00000001
+#define WL_TRACE_VAL 0x00000002
+#define WL_AMPDU_VAL 0x20000000
+#define WL_FFPLD_VAL 0x40000000
+
+/* maximum channels returned by the get valid channels iovar */
+#define WL_NUMCHANNELS 64
+#define WL_NUMCHANSPECS 100
+
+struct tsinfo_arg {
+ uint8 octets[3];
+};
+
+#define NFIFO 6 /* # tx/rx fifopairs */
+
+#define WL_CNT_T_VERSION 7 /* current version of wl_cnt_t struct */
+
+typedef struct {
+ uint16 version; /* see definition of WL_CNT_T_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txframe; /* tx data frames */
+ uint32 txbyte; /* tx data bytes */
+ uint32 txretrans; /* tx mac retransmits */
+ uint32 txerror; /* tx data errors (derived: sum of others) */
+ uint32 txctl; /* tx management frames */
+ uint32 txprshort; /* tx short preamble frames */
+ uint32 txserr; /* tx status errors */
+ uint32 txnobuf; /* tx out of buffers errors */
+ uint32 txnoassoc; /* tx discard because we're not associated */
+ uint32 txrunt; /* tx runt frames */
+ uint32 txchit; /* tx header cache hit (fastpath) */
+ uint32 txcmiss; /* tx header cache miss (slowpath) */
+ uint32 ieee_tx_status; /* calls to ieee80211_tx_status */
+ uint32 ieee_tx; /* tx calls frm mac0211 */
+ uint32 ieee_rx; /* calls to ieee_rx */
+
+ /* transmit chip error counters */
+ uint32 txuflo; /* tx fifo underflows */
+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */
+ uint32 txphycrs;
+
+ /* receive stat counters */
+ uint32 rxframe; /* rx data frames */
+ uint32 rxbyte; /* rx data bytes */
+ uint32 rxerror; /* rx data errors (derived: sum of others) */
+ uint32 rxctl; /* rx management frames */
+ uint32 rxnobuf; /* rx out of buffers errors */
+ uint32 rxnondata; /* rx non data frames in the data channel errors */
+ uint32 rxbadds; /* rx bad DS errors */
+ uint32 rxbadcm; /* rx bad control or management frames */
+ uint32 rxfragerr; /* rx fragmentation errors */
+ uint32 rxrunt; /* rx runt frames */
+ uint32 rxgiant; /* rx giant frames */
+ uint32 rxnoscb; /* rx no scb error */
+ uint32 rxbadproto; /* rx invalid frames */
+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */
+ uint32 rxbadda; /* rx frames tossed for invalid da */
+ uint32 rxfilter; /* rx frames filtered out */
+
+ /* receive chip error counters */
+ uint32 rxoflo; /* rx fifo overflow errors */
+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */
+
+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */
+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */
+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */
+
+ /* misc counters */
+ uint32 dmade; /* tx/rx dma descriptor errors */
+ uint32 dmada; /* tx/rx dma data errors */
+ uint32 dmape; /* tx/rx dma descriptor protocol errors */
+ uint32 reset; /* reset count */
+ uint32 tbtt; /* cnts the TBTT int's */
+ uint32 txdmawar;
+ uint32 pkt_callback_reg_fail; /* callbacks register failure */
+
+ /* MAC counters: 32-bit version of d11.h's macstat_t */
+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS,
+ * Control Management (includes retransmissions)
+ */
+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */
+ uint32 txctsfrm; /* number of CTS sent out by the MAC */
+ uint32 txackfrm; /* number of ACK frames sent out */
+ uint32 txdnlfrm; /* Not used */
+ uint32 txbcnfrm; /* beacons transmitted */
+ uint32 txfunfl[8]; /* per-fifo tx underflows */
+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS
+ * or BCN)
+ */
+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for
+ * driver enqueued frames
+ */
+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */
+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */
+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not
+ * data/control/management
+ */
+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */
+ uint32 rxbadplcp; /* parity check of the PLCP header failed */
+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */
+ uint32 rxstrt; /* Number of received frames with a good PLCP
+ * (i.e. passing parity check)
+ */
+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */
+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */
+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */
+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */
+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */
+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */
+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */
+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */
+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */
+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */
+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */
+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */
+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */
+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC
+ * (unlikely to see these)
+ */
+ uint32 rxbeaconmbss; /* beacons received from member of BSS */
+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from
+ * other BSS (WDS FRAME)
+ */
+ uint32 rxbeaconobss; /* beacons received from other BSS */
+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames
+ * expecting a response
+ */
+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */
+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */
+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */
+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */
+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */
+ uint32 pmqovfl; /* Number of PMQ overflows */
+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into
+ * the PRQ fifo
+ */
+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */
+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did
+ * not get ACK
+ */
+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */
+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ
+ * fifo because a probe response could not be sent out within
+ * the time limit defined in M_PRS_MAXTIME
+ */
+ uint32 rxnack;
+ uint32 frmscons;
+ uint32 txnack;
+ uint32 txglitch_nack; /* obsolete */
+ uint32 txburst; /* obsolete */
+
+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay; /* TKIPReplays */
+ uint32 ccmpfmterr; /* CCMPFormatErrors */
+ uint32 ccmpreplay; /* CCMPReplays */
+ uint32 ccmpundec; /* CCMPDecryptErrors */
+ uint32 fourwayfail; /* FourWayHandshakeFailures */
+ uint32 wepundec; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr; /* dot11WEPICVErrorCount */
+ uint32 decsuccess; /* DecryptSuccessCount */
+ uint32 tkipicverr; /* TKIPICVErrorCount */
+ uint32 wepexcluded; /* dot11WEPExcludedCount */
+
+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay_mcst; /* TKIPReplays */
+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */
+ uint32 ccmpreplay_mcst; /* CCMPReplays */
+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */
+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */
+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */
+ uint32 decsuccess_mcst; /* DecryptSuccessCount */
+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */
+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */
+
+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */
+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */
+ uint32 psmwds; /* Count PSM watchdogs */
+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */
+
+ /* MBSS counters, AP only */
+ uint32 prq_entries_handled; /* PRQ entries read in */
+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */
+ uint32 prq_bad_entries; /* which could not be translated to info */
+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */
+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */
+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */
+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */
+
+ /* per-rate receive stat counters */
+ uint32 rx1mbps; /* packets rx at 1Mbps */
+ uint32 rx2mbps; /* packets rx at 2Mbps */
+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */
+ uint32 rx6mbps; /* packets rx at 6Mbps */
+ uint32 rx9mbps; /* packets rx at 9Mbps */
+ uint32 rx11mbps; /* packets rx at 11Mbps */
+ uint32 rx12mbps; /* packets rx at 12Mbps */
+ uint32 rx18mbps; /* packets rx at 18Mbps */
+ uint32 rx24mbps; /* packets rx at 24Mbps */
+ uint32 rx36mbps; /* packets rx at 36Mbps */
+ uint32 rx48mbps; /* packets rx at 48Mbps */
+ uint32 rx54mbps; /* packets rx at 54Mbps */
+ uint32 rx108mbps; /* packets rx at 108mbps */
+ uint32 rx162mbps; /* packets rx at 162mbps */
+ uint32 rx216mbps; /* packets rx at 216 mbps */
+ uint32 rx270mbps; /* packets rx at 270 mbps */
+ uint32 rx324mbps; /* packets rx at 324 mbps */
+ uint32 rx378mbps; /* packets rx at 378 mbps */
+ uint32 rx432mbps; /* packets rx at 432 mbps */
+ uint32 rx486mbps; /* packets rx at 486 mbps */
+ uint32 rx540mbps; /* packets rx at 540 mbps */
+
+ /* pkteng rx frame stats */
+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */
+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */
+
+ uint32 rfdisable; /* count of radio disables */
+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */
+
+ uint32 txmpdu_sgi; /* count for sgi transmit */
+ uint32 rxmpdu_sgi; /* count for sgi received */
+ uint32 txmpdu_stbc; /* count for stbc transmit */
+ uint32 rxmpdu_stbc; /* count for stbc received */
+} wl_cnt_t;
+
+#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */
+
+typedef struct {
+ uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txframe; /* tx data frames */
+ uint32 txbyte; /* tx data bytes */
+ uint32 txretrans; /* tx mac retransmits */
+ uint32 txfail; /* tx failures */
+
+ /* receive stat counters */
+ uint32 rxframe; /* rx data frames */
+ uint32 rxbyte; /* rx data bytes */
+
+ /* per-rate receive stat counters */
+ uint32 rx1mbps; /* packets rx at 1Mbps */
+ uint32 rx2mbps; /* packets rx at 2Mbps */
+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */
+ uint32 rx6mbps; /* packets rx at 6Mbps */
+ uint32 rx9mbps; /* packets rx at 9Mbps */
+ uint32 rx11mbps; /* packets rx at 11Mbps */
+ uint32 rx12mbps; /* packets rx at 12Mbps */
+ uint32 rx18mbps; /* packets rx at 18Mbps */
+ uint32 rx24mbps; /* packets rx at 24Mbps */
+ uint32 rx36mbps; /* packets rx at 36Mbps */
+ uint32 rx48mbps; /* packets rx at 48Mbps */
+ uint32 rx54mbps; /* packets rx at 54Mbps */
+ uint32 rx108mbps; /* packets rx at 108mbps */
+ uint32 rx162mbps; /* packets rx at 162mbps */
+ uint32 rx216mbps; /* packets rx at 216 mbps */
+ uint32 rx270mbps; /* packets rx at 270 mbps */
+ uint32 rx324mbps; /* packets rx at 324 mbps */
+ uint32 rx378mbps; /* packets rx at 378 mbps */
+ uint32 rx432mbps; /* packets rx at 432 mbps */
+ uint32 rx486mbps; /* packets rx at 486 mbps */
+ uint32 rx540mbps; /* packets rx at 540 mbps */
+} wl_delta_stats_t;
+
+#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */
+
+typedef struct {
+ uint32 packets;
+ uint32 bytes;
+} wl_traffic_stats_t;
+
+typedef struct {
+ uint16 version; /* see definition of WL_WME_CNT_VERSION */
+ uint16 length; /* length of entire structure */
+
+ wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */
+ wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */
+ wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */
+ wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */
+
+ wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */
+
+ wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */
+
+} wl_wme_cnt_t;
+
+struct wl_msglevel2 {
+ uint32 low;
+ uint32 high;
+};
+
+#ifdef WLBA
+
+#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */
+
+/* block ack related stats */
+typedef struct wlc_ba_cnt {
+ uint16 version; /* WLC_BA_CNT_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txpdu; /* pdus sent */
+ uint32 txsdu; /* sdus sent */
+ uint32 txfc; /* tx side flow controlled packets */
+ uint32 txfci; /* tx side flow control initiated */
+ uint32 txretrans; /* retransmitted pdus */
+ uint32 txbatimer; /* ba resend due to timer */
+ uint32 txdrop; /* dropped packets */
+ uint32 txaddbareq; /* addba req sent */
+ uint32 txaddbaresp; /* addba resp sent */
+ uint32 txdelba; /* delba sent */
+ uint32 txba; /* ba sent */
+ uint32 txbar; /* bar sent */
+ uint32 txpad[4]; /* future */
+
+ /* receive side counters */
+ uint32 rxpdu; /* pdus recd */
+ uint32 rxqed; /* pdus buffered before sending up */
+ uint32 rxdup; /* duplicate pdus */
+ uint32 rxnobuf; /* pdus discarded due to no buf */
+ uint32 rxaddbareq; /* addba req recd */
+ uint32 rxaddbaresp; /* addba resp recd */
+ uint32 rxdelba; /* delba recd */
+ uint32 rxba; /* ba recd */
+ uint32 rxbar; /* bar recd */
+ uint32 rxinvba; /* invalid ba recd */
+ uint32 rxbaholes; /* ba recd with holes */
+ uint32 rxunexp; /* unexpected packets */
+ uint32 rxpad[4]; /* future */
+} wlc_ba_cnt_t;
+#endif /* WLBA */
+
+/* structure for per-tid ampdu control */
+struct ampdu_tid_control {
+ uint8 tid; /* tid */
+ uint8 enable; /* enable/disable */
+};
+
+/* structure for identifying ea/tid for sending addba/delba */
+struct ampdu_ea_tid {
+ struct ether_addr ea; /* Station address */
+ uint8 tid; /* tid */
+};
+/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */
+struct ampdu_retry_tid {
+ uint8 tid; /* tid */
+ uint8 retry; /* retry value */
+};
+
+/* structure for addts arguments */
+/* For ioctls that take a list of TSPEC */
+struct tslist {
+ int count; /* number of tspecs */
+ struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */
+};
+
+/* structure for addts/delts arguments */
+typedef struct tspec_arg {
+ uint16 version; /* see definition of TSPEC_ARG_VERSION */
+ uint16 length; /* length of entire structure */
+ uint flag; /* bit field */
+ /* TSPEC Arguments */
+ struct tsinfo_arg tsinfo; /* TS Info bit field */
+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
+ uint min_srv_interval; /* Minimum Service Interval (us) */
+ uint max_srv_interval; /* Maximum Service Interval (us) */
+ uint inactivity_interval; /* Inactivity Interval (us) */
+ uint suspension_interval; /* Suspension Interval (us) */
+ uint srv_start_time; /* Service Start Time (us) */
+ uint min_data_rate; /* Minimum Data Rate (bps) */
+ uint mean_data_rate; /* Mean Data Rate (bps) */
+ uint peak_data_rate; /* Peak Data Rate (bps) */
+ uint max_burst_size; /* Maximum Burst Size (bytes) */
+ uint delay_bound; /* Delay Bound (us) */
+ uint min_phy_rate; /* Minimum PHY Rate (bps) */
+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */
+ uint16 medium_time; /* Medium Time (32 us/s periods) */
+ uint8 dialog_token; /* dialog token */
+} tspec_arg_t;
+
+/* tspec arg for desired station */
+typedef struct tspec_per_sta_arg {
+ struct ether_addr ea;
+ struct tspec_arg ts;
+} tspec_per_sta_arg_t;
+
+/* structure for max bandwidth for each access category */
+typedef struct wme_max_bandwidth {
+ uint32 ac[AC_COUNT]; /* max bandwidth for each access category */
+} wme_max_bandwidth_t;
+
+#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t))
+
+/* current version of wl_tspec_arg_t struct */
+#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */
+#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */
+#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */
+#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */
+
+/* define for flag */
+#define TSPEC_PENDING 0 /* TSPEC pending */
+#define TSPEC_ACCEPTED 1 /* TSPEC accepted */
+#define TSPEC_REJECTED 2 /* TSPEC rejected */
+#define TSPEC_UNKNOWN 3 /* TSPEC unknown */
+#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */
+
+/* Software feature flag defines used by wlfeatureflag */
+#define WL_SWFL_NOHWRADIO 0x0004
+#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */
+#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */
+
+#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */
+
+/*
+ * Dongle pattern matching filter.
+ */
+
+/* Packet filter types. Currently, only pattern matching is supported. */
+typedef enum wl_pkt_filter_type {
+ WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */
+} wl_pkt_filter_type_t;
+
+#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t
+
+/* Pattern matching filter. Specifies an offset within received packets to
+ * start matching, the pattern to match, the size of the pattern, and a bitmask
+ * that indicates which bits within the pattern should be matched.
+ */
+typedef struct wl_pkt_filter_pattern {
+ uint32 offset; /* Offset within received packet to start pattern matching.
+ * Offset '0' is the first byte of the ethernet header.
+ */
+ uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */
+ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts
+ * at offset 0. Pattern immediately follows mask.
+ */
+} wl_pkt_filter_pattern_t;
+
+/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
+typedef struct wl_pkt_filter {
+ uint32 id; /* Unique filter id, specified by app. */
+ uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+ uint32 negate_match; /* Negate the result of filter matches */
+ union { /* Filter definitions */
+ wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */
+ } u;
+} wl_pkt_filter_t;
+
+#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u)
+#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern)
+
+/* IOVAR "pkt_filter_enable" parameter. */
+typedef struct wl_pkt_filter_enable {
+ uint32 id; /* Unique filter id */
+ uint32 enable; /* Enable/disable bool */
+} wl_pkt_filter_enable_t;
+
+/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */
+typedef struct wl_pkt_filter_list {
+ uint32 num; /* Number of installed packet filters */
+ wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */
+} wl_pkt_filter_list_t;
+
+#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter)
+
+/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */
+typedef struct wl_pkt_filter_stats {
+ uint32 num_pkts_matched; /* # filter matches for specified filter id */
+ uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */
+ uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */
+} wl_pkt_filter_stats_t;
+
+typedef struct wl_pkteng {
+ uint32 flags;
+ uint32 delay; /* Inter-packet delay */
+ uint32 nframes; /* Number of frames */
+ uint32 length; /* Packet length */
+ uint8 seqno; /* Enable/disable sequence no. */
+ struct ether_addr dest; /* Destination address */
+ struct ether_addr src; /* Source address */
+} wl_pkteng_t;
+
+#define WLC_RSSI_INVALID 0 /* invalid RSSI value */
+
+/* require default structure packing */
+#include <packed_section_end.h>
+
+/* n-mode support capability */
+/* 2x2 includes both 1x1 & 2x2 devices
+ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
+ * control it independently
+ */
+#define WL_11N_2x2 1
+#define WL_11N_3x3 3
+#define WL_11N_4x4 4
+
+/* define 11n feature disable flags */
+#define WLFEATURE_DISABLE_11N 0x00000001
+#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002
+#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004
+#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008
+#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010
+#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020
+#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040
+#define WLFEATURE_DISABLE_11N_GF 0x00000080
+
+#endif /* _wlioctl_h_ */
diff --git a/drivers/staging/brcm80211/phy/phy_version.h b/drivers/staging/brcm80211/phy/phy_version.h
new file mode 100644
index 000000000000..51a223880bcf
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/phy_version.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 phy_version_h_
+#define phy_version_h_
+
+#define PHY_MAJOR_VERSION 1
+
+#define PHY_MINOR_VERSION 82
+
+#define PHY_RC_NUMBER 8
+
+#define PHY_INCREMENTAL_NUMBER 0
+
+#define PHY_BUILD_NUMBER 0
+
+#define PHY_VERSION { 1, 82, 8, 0 }
+
+#define PHY_VERSION_NUM 0x01520800
+
+#define PHY_VERSION_STR "1.82.8.0"
+
+#endif /* phy_version_h_ */
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c
new file mode 100644
index 000000000000..f2e504eddcdd
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c
@@ -0,0 +1,3454 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+
+#include <osl.h>
+#include <bcmendian.h>
+#include <bcmnvram.h>
+#include <sbchipc.h>
+
+#include <wlc_phy_int.h>
+#include <wlc_phyreg_n.h>
+#include <wlc_phy_radio.h>
+#include <wlc_phy_lcn.h>
+
+uint32 phyhal_msg_level = PHYHAL_ERROR;
+
+typedef struct _chan_info_basic {
+ uint16 chan;
+ uint16 freq;
+} chan_info_basic_t;
+
+static chan_info_basic_t chan_info_all[] = {
+
+ {1, 2412},
+ {2, 2417},
+ {3, 2422},
+ {4, 2427},
+ {5, 2432},
+ {6, 2437},
+ {7, 2442},
+ {8, 2447},
+ {9, 2452},
+ {10, 2457},
+ {11, 2462},
+ {12, 2467},
+ {13, 2472},
+ {14, 2484},
+
+ {34, 5170},
+ {38, 5190},
+ {42, 5210},
+ {46, 5230},
+
+ {36, 5180},
+ {40, 5200},
+ {44, 5220},
+ {48, 5240},
+ {52, 5260},
+ {56, 5280},
+ {60, 5300},
+ {64, 5320},
+
+ {100, 5500},
+ {104, 5520},
+ {108, 5540},
+ {112, 5560},
+ {116, 5580},
+ {120, 5600},
+ {124, 5620},
+ {128, 5640},
+ {132, 5660},
+ {136, 5680},
+ {140, 5700},
+
+ {149, 5745},
+ {153, 5765},
+ {157, 5785},
+ {161, 5805},
+ {165, 5825},
+
+ {184, 4920},
+ {188, 4940},
+ {192, 4960},
+ {196, 4980},
+ {200, 5000},
+ {204, 5020},
+ {208, 5040},
+ {212, 5060},
+ {216, 50800}
+};
+
+uint16 ltrn_list[PHY_LTRN_LIST_LEN] = {
+ 0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc,
+ 0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010,
+ 0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc,
+ 0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318,
+ 0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312,
+ 0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc,
+ 0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01,
+ 0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff,
+ 0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec,
+ 0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814,
+ 0x0507, 0x0fea, 0xe4f2, 0xf6e6
+};
+
+const uint8 ofdm_rate_lookup[] = {
+
+ WLC_RATE_48M,
+ WLC_RATE_24M,
+ WLC_RATE_12M,
+ WLC_RATE_6M,
+ WLC_RATE_54M,
+ WLC_RATE_36M,
+ WLC_RATE_18M,
+ WLC_RATE_9M
+};
+
+#define PHY_WREG_LIMIT 24
+
+static void wlc_set_phy_uninitted(phy_info_t *pi);
+static uint32 wlc_phy_get_radio_ver(phy_info_t *pi);
+static void wlc_phy_timercb_phycal(void *arg);
+
+static bool wlc_phy_noise_calc_phy(phy_info_t *pi, uint32 *cmplx_pwr,
+ int8 *pwr_ant);
+
+static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay);
+static void wlc_phy_noise_cb(phy_info_t *pi, uint8 channel, int8 noise_dbm);
+static void wlc_phy_noise_sample_request(wlc_phy_t *pih, uint8 reason,
+ uint8 ch);
+
+static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi,
+ struct txpwr_limits *tp, chanspec_t);
+static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi);
+
+static int8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan,
+ uint32 band, uint8 rate);
+static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, uint32 band);
+static int8 wlc_phy_env_measure_vbat(phy_info_t *pi);
+static int8 wlc_phy_env_measure_temperature(phy_info_t *pi);
+
+char *phy_getvar(phy_info_t *pi, const char *name)
+{
+ char *vars = pi->vars;
+ char *s;
+ int len;
+
+ ASSERT(pi->vars != (char *)&pi->vars);
+
+ if (!name)
+ return NULL;
+
+ len = strlen(name);
+ if (len == 0)
+ return NULL;
+
+ for (s = vars; s && *s;) {
+ if ((bcmp(s, name, len) == 0) && (s[len] == '='))
+ return &s[len + 1];
+
+ while (*s++)
+ ;
+ }
+
+ return nvram_get(name);
+}
+
+int phy_getintvar(phy_info_t *pi, const char *name)
+{
+ char *val;
+
+ val = PHY_GETVAR(pi, name);
+ if (val == NULL)
+ return 0;
+
+ return bcm_strtoul(val, NULL, 0);
+}
+
+void wlc_phyreg_enter(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
+}
+
+void wlc_phyreg_exit(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
+}
+
+void wlc_radioreg_enter(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
+
+ OSL_DELAY(10);
+}
+
+void wlc_radioreg_exit(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ volatile uint16 dummy;
+
+ dummy = R_REG(pi->sh->osh, &pi->regs->phyversion);
+ pi->phy_wreg = 0;
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
+}
+
+uint16 read_radio_reg(phy_info_t *pi, uint16 addr)
+{
+ uint16 data;
+
+ if ((addr == RADIO_IDCODE))
+ return 0xffff;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return NORADIO_IDCODE & 0xffff;
+
+ switch (pi->pubpi.phy_type) {
+ case PHY_TYPE_N:
+ CASECHECK(PHYTYPE, PHY_TYPE_N);
+ if (NREV_GE(pi->pubpi.phy_rev, 7))
+ addr |= RADIO_2057_READ_OFF;
+ else
+ addr |= RADIO_2055_READ_OFF;
+ break;
+
+ case PHY_TYPE_LCN:
+ CASECHECK(PHYTYPE, PHY_TYPE_LCN);
+ addr |= RADIO_2064_READ_OFF;
+ break;
+
+ default:
+ ASSERT(VALID_PHYTYPE(pi->pubpi.phy_type));
+ }
+
+ if ((D11REV_GE(pi->sh->corerev, 24)) ||
+ (D11REV_IS(pi->sh->corerev, 22)
+ && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+ W_REG(pi->sh->osh, &pi->regs->radioregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr);
+#endif
+ data = R_REG(pi->sh->osh, &pi->regs->radioregdata);
+ } else {
+ W_REG(pi->sh->osh, &pi->regs->phy4waddr, addr);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr);
+#endif
+
+#ifdef __ARM_ARCH_4T__
+ __asm__(" .align 4 ");
+ __asm__(" nop ");
+ data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo);
+#else
+ data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo);
+#endif
+
+ }
+ pi->phy_wreg = 0;
+
+ return data;
+}
+
+void write_radio_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ osl_t *osh;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ osh = pi->sh->osh;
+
+ if ((D11REV_GE(pi->sh->corerev, 24)) ||
+ (D11REV_IS(pi->sh->corerev, 22)
+ && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+
+ W_REG(osh, &pi->regs->radioregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &pi->regs->radioregaddr);
+#endif
+ W_REG(osh, &pi->regs->radioregdata, val);
+ } else {
+ W_REG(osh, &pi->regs->phy4waddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &pi->regs->phy4waddr);
+#endif
+ W_REG(osh, &pi->regs->phy4wdatalo, val);
+ }
+
+ if (BUSTYPE(pi->sh->bustype) == PCI_BUS) {
+ if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+ (void)R_REG(osh, &pi->regs->maccontrol);
+ pi->phy_wreg = 0;
+ }
+ }
+}
+
+static uint32 read_radio_id(phy_info_t *pi)
+{
+ uint32 id;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return NORADIO_IDCODE;
+
+ if (D11REV_GE(pi->sh->corerev, 24)) {
+ uint32 b0, b1, b2;
+
+ W_REG(pi->sh->osh, &pi->regs->radioregaddr, 0);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr);
+#endif
+ b0 = (uint32) R_REG(pi->sh->osh, &pi->regs->radioregdata);
+ W_REG(pi->sh->osh, &pi->regs->radioregaddr, 1);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr);
+#endif
+ b1 = (uint32) R_REG(pi->sh->osh, &pi->regs->radioregdata);
+ W_REG(pi->sh->osh, &pi->regs->radioregaddr, 2);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr);
+#endif
+ b2 = (uint32) R_REG(pi->sh->osh, &pi->regs->radioregdata);
+
+ id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
+ & 0xf);
+ } else {
+ W_REG(pi->sh->osh, &pi->regs->phy4waddr, RADIO_IDCODE);
+#ifdef __mips__
+ (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr);
+#endif
+ id = (uint32) R_REG(pi->sh->osh, &pi->regs->phy4wdatalo);
+ id |= (uint32) R_REG(pi->sh->osh, &pi->regs->phy4wdatahi) << 16;
+ }
+ pi->phy_wreg = 0;
+ return id;
+}
+
+void and_radio_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ uint16 rval;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ rval = read_radio_reg(pi, addr);
+ write_radio_reg(pi, addr, (rval & val));
+}
+
+void or_radio_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ uint16 rval;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ rval = read_radio_reg(pi, addr);
+ write_radio_reg(pi, addr, (rval | val));
+}
+
+void xor_radio_reg(phy_info_t *pi, uint16 addr, uint16 mask)
+{
+ uint16 rval;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ rval = read_radio_reg(pi, addr);
+ write_radio_reg(pi, addr, (rval ^ mask));
+}
+
+void mod_radio_reg(phy_info_t *pi, uint16 addr, uint16 mask, uint16 val)
+{
+ uint16 rval;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ rval = read_radio_reg(pi, addr);
+ write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
+}
+
+void write_phy_channel_reg(phy_info_t *pi, uint val)
+{
+ W_REG(pi->sh->osh, &pi->regs->phychannel, val);
+}
+
+#if defined(BCMDBG)
+static bool wlc_phy_war41476(phy_info_t *pi)
+{
+ uint32 mc = R_REG(pi->sh->osh, &pi->regs->maccontrol);
+
+ return ((mc & MCTL_EN_MAC) == 0)
+ || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK);
+}
+#endif
+
+uint16 read_phy_reg(phy_info_t *pi, uint16 addr)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = pi->sh->osh;
+ regs = pi->regs;
+
+ W_REG(osh, &regs->phyregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &regs->phyregaddr);
+#endif
+
+ ASSERT(!
+ (D11REV_IS(pi->sh->corerev, 11)
+ || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
+
+ pi->phy_wreg = 0;
+ return R_REG(osh, &regs->phyregdata);
+}
+
+void write_phy_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = pi->sh->osh;
+ regs = pi->regs;
+
+#ifdef __mips__
+ W_REG(osh, &regs->phyregaddr, addr);
+ (void)R_REG(osh, &regs->phyregaddr);
+ W_REG(osh, &regs->phyregdata, val);
+ if (addr == 0x72)
+ (void)R_REG(osh, &regs->phyregdata);
+#else
+ W_REG(osh, (volatile uint32 *)(uintptr) (&regs->phyregaddr),
+ addr | (val << 16));
+ if (BUSTYPE(pi->sh->bustype) == PCI_BUS) {
+ if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+ pi->phy_wreg = 0;
+ (void)R_REG(osh, &regs->phyversion);
+ }
+ }
+#endif
+}
+
+void and_phy_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = pi->sh->osh;
+ regs = pi->regs;
+
+ W_REG(osh, &regs->phyregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &regs->phyregaddr);
+#endif
+
+ ASSERT(!
+ (D11REV_IS(pi->sh->corerev, 11)
+ || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
+
+ W_REG(osh, &regs->phyregdata, (R_REG(osh, &regs->phyregdata) & val));
+ pi->phy_wreg = 0;
+}
+
+void or_phy_reg(phy_info_t *pi, uint16 addr, uint16 val)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = pi->sh->osh;
+ regs = pi->regs;
+
+ W_REG(osh, &regs->phyregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &regs->phyregaddr);
+#endif
+
+ ASSERT(!
+ (D11REV_IS(pi->sh->corerev, 11)
+ || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
+
+ W_REG(osh, &regs->phyregdata, (R_REG(osh, &regs->phyregdata) | val));
+ pi->phy_wreg = 0;
+}
+
+void mod_phy_reg(phy_info_t *pi, uint16 addr, uint16 mask, uint16 val)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = pi->sh->osh;
+ regs = pi->regs;
+
+ W_REG(osh, &regs->phyregaddr, addr);
+#ifdef __mips__
+ (void)R_REG(osh, &regs->phyregaddr);
+#endif
+
+ ASSERT(!
+ (D11REV_IS(pi->sh->corerev, 11)
+ || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
+
+ W_REG(osh, &regs->phyregdata,
+ ((R_REG(osh, &regs->phyregdata) & ~mask) | (val & mask)));
+ pi->phy_wreg = 0;
+}
+
+static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi)
+{
+ int i, j;
+
+ pi->initialized = FALSE;
+
+ pi->tx_vos = 0xffff;
+ pi->nrssi_table_delta = 0x7fffffff;
+ pi->rc_cal = 0xffff;
+ pi->mintxbias = 0xffff;
+ pi->txpwridx = -1;
+ if (ISNPHY(pi)) {
+ pi->phy_spuravoid = SPURAVOID_DISABLE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)
+ && NREV_LT(pi->pubpi.phy_rev, 7))
+ pi->phy_spuravoid = SPURAVOID_AUTO;
+
+ pi->nphy_papd_skip = 0;
+ pi->nphy_papd_epsilon_offset[0] = 0xf588;
+ pi->nphy_papd_epsilon_offset[1] = 0xf588;
+ pi->nphy_txpwr_idx[0] = 128;
+ pi->nphy_txpwr_idx[1] = 128;
+ pi->nphy_txpwrindex[0].index_internal = 40;
+ pi->nphy_txpwrindex[1].index_internal = 40;
+ pi->phy_pabias = 0;
+ } else {
+ pi->phy_spuravoid = SPURAVOID_AUTO;
+ }
+ pi->radiopwr = 0xffff;
+ for (i = 0; i < STATIC_NUM_RF; i++) {
+ for (j = 0; j < STATIC_NUM_BB; j++) {
+ pi->stats_11b_txpower[i][j] = -1;
+ }
+ }
+}
+
+shared_phy_t *BCMATTACHFN(wlc_phy_shared_attach) (shared_phy_params_t *shp)
+{
+ shared_phy_t *sh;
+
+ sh = (shared_phy_t *) MALLOC(shp->osh, sizeof(shared_phy_t));
+ if (sh == NULL) {
+ return NULL;
+ }
+ bzero((char *)sh, sizeof(shared_phy_t));
+
+ sh->osh = shp->osh;
+ sh->sih = shp->sih;
+ sh->physhim = shp->physhim;
+ sh->unit = shp->unit;
+ sh->corerev = shp->corerev;
+
+ sh->vid = shp->vid;
+ sh->did = shp->did;
+ sh->chip = shp->chip;
+ sh->chiprev = shp->chiprev;
+ sh->chippkg = shp->chippkg;
+ sh->sromrev = shp->sromrev;
+ sh->boardtype = shp->boardtype;
+ sh->boardrev = shp->boardrev;
+ sh->boardvendor = shp->boardvendor;
+ sh->boardflags = shp->boardflags;
+ sh->boardflags2 = shp->boardflags2;
+ sh->bustype = shp->bustype;
+ sh->buscorerev = shp->buscorerev;
+
+ sh->fast_timer = PHY_SW_TIMER_FAST;
+ sh->slow_timer = PHY_SW_TIMER_SLOW;
+ sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
+
+ sh->rssi_mode = RSSI_ANT_MERGE_MAX;
+
+ return sh;
+}
+
+void BCMATTACHFN(wlc_phy_shared_detach) (shared_phy_t *phy_sh)
+{
+ osl_t *osh;
+
+ if (phy_sh) {
+ osh = phy_sh->osh;
+
+ if (phy_sh->phy_head) {
+ ASSERT(!phy_sh->phy_head);
+ }
+ MFREE(osh, phy_sh, sizeof(shared_phy_t));
+ }
+}
+
+wlc_phy_t *BCMATTACHFN(wlc_phy_attach) (shared_phy_t *sh, void *regs,
+ int bandtype, char *vars) {
+ phy_info_t *pi;
+ uint32 sflags = 0;
+ uint phyversion;
+ int i;
+ osl_t *osh;
+
+ osh = sh->osh;
+
+ if (D11REV_IS(sh->corerev, 4))
+ sflags = SISF_2G_PHY | SISF_5G_PHY;
+ else
+ sflags = si_core_sflags(sh->sih, 0, 0);
+
+ if (BAND_5G(bandtype)) {
+ if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) {
+ return NULL;
+ }
+ }
+
+ pi = sh->phy_head;
+ if ((sflags & SISF_DB_PHY) && pi) {
+
+ wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+ pi->refcnt++;
+ return &pi->pubpi_ro;
+ }
+
+ pi = (phy_info_t *) MALLOC(osh, sizeof(phy_info_t));
+ if (pi == NULL) {
+ return NULL;
+ }
+ bzero((char *)pi, sizeof(phy_info_t));
+ pi->regs = (d11regs_t *) regs;
+ pi->sh = sh;
+ pi->phy_init_por = TRUE;
+ pi->phy_wreg_limit = PHY_WREG_LIMIT;
+
+ pi->vars = vars;
+
+ pi->txpwr_percent = 100;
+
+ pi->do_initcal = TRUE;
+
+ pi->phycal_tempdelta = 0;
+
+ if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) {
+
+ pi->pubpi.coreflags = SICF_GMODE;
+ }
+
+ wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+ phyversion = R_REG(osh, &pi->regs->phyversion);
+
+ pi->pubpi.phy_type = PHY_TYPE(phyversion);
+ pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
+
+ if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
+ pi->pubpi.phy_type = PHY_TYPE_N;
+ pi->pubpi.phy_rev += LCNXN_BASEREV;
+ }
+ pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
+ pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
+
+ if (!VALID_PHYTYPE(pi->pubpi.phy_type)) {
+ goto err;
+ }
+ if (BAND_5G(bandtype)) {
+ if (!ISNPHY(pi)) {
+ goto err;
+ }
+ } else {
+ if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
+ goto err;
+ }
+ }
+
+ if (ISSIM_ENAB(pi->sh->sih)) {
+ pi->pubpi.radioid = NORADIO_ID;
+ pi->pubpi.radiorev = 5;
+ } else {
+ uint32 idcode;
+
+ wlc_phy_anacore((wlc_phy_t *) pi, ON);
+
+ idcode = wlc_phy_get_radio_ver(pi);
+ pi->pubpi.radioid =
+ (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
+ pi->pubpi.radiorev =
+ (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
+ pi->pubpi.radiover =
+ (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
+ if (!VALID_RADIO(pi, pi->pubpi.radioid)) {
+ goto err;
+ }
+
+ wlc_phy_switch_radio((wlc_phy_t *) pi, OFF);
+ }
+
+ wlc_set_phy_uninitted(pi);
+
+ pi->bw = WL_CHANSPEC_BW_20;
+ pi->radio_chanspec =
+ BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36);
+
+ pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+ pi->rxiq_antsel = ANT_RX_DIV_DEF;
+
+ pi->watchdog_override = TRUE;
+
+ pi->cal_type_override = PHY_PERICAL_AUTO;
+
+ pi->nphy_saved_noisevars.bufcount = 0;
+
+ if (ISNPHY(pi))
+ pi->min_txpower = PHY_TXPWR_MIN_NPHY;
+ else
+ pi->min_txpower = PHY_TXPWR_MIN;
+
+ pi->sh->phyrxchain = 0x3;
+
+ pi->rx2tx_biasentry = -1;
+
+ pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+ pi->phy_txcore_enable_temp =
+ PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
+ pi->phy_tempsense_offset = 0;
+ pi->phy_txcore_heatedup = FALSE;
+
+ pi->nphy_lastcal_temp = -50;
+
+ pi->phynoise_polling = TRUE;
+ if (ISNPHY(pi) || ISLCNPHY(pi))
+ pi->phynoise_polling = FALSE;
+
+ for (i = 0; i < TXP_NUM_RATES; i++) {
+ pi->txpwr_limit[i] = WLC_TXPWR_MAX;
+ pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+ pi->tx_user_target[i] = WLC_TXPWR_MAX;
+ }
+
+ pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
+
+ pi->user_txpwr_at_rfport = FALSE;
+
+ if (ISNPHY(pi)) {
+
+ pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
+ wlc_phy_timercb_phycal,
+ pi, "phycal");
+ if (!pi->phycal_timer) {
+ goto err;
+ }
+
+ if (!wlc_phy_attach_nphy(pi))
+ goto err;
+
+ } else if (ISLCNPHY(pi)) {
+ if (!wlc_phy_attach_lcnphy(pi))
+ goto err;
+
+ } else {
+
+ }
+
+ pi->refcnt++;
+ pi->next = pi->sh->phy_head;
+ sh->phy_head = pi;
+
+ pi->vars = (char *)&pi->vars;
+
+ bcopy(&pi->pubpi, &pi->pubpi_ro, sizeof(wlc_phy_t));
+
+ return &pi->pubpi_ro;
+
+ err:
+ if (pi)
+ MFREE(sh->osh, pi, sizeof(phy_info_t));
+ return NULL;
+}
+
+void BCMATTACHFN(wlc_phy_detach) (wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (pih) {
+ if (--pi->refcnt) {
+ return;
+ }
+
+ if (pi->phycal_timer) {
+ wlapi_free_timer(pi->sh->physhim, pi->phycal_timer);
+ pi->phycal_timer = NULL;
+ }
+
+ if (pi->sh->phy_head == pi)
+ pi->sh->phy_head = pi->next;
+ else if (pi->sh->phy_head->next == pi)
+ pi->sh->phy_head->next = NULL;
+ else
+ ASSERT(0);
+
+ if (pi->pi_fptr.detach)
+ (pi->pi_fptr.detach) (pi);
+
+ MFREE(pi->sh->osh, pi, sizeof(phy_info_t));
+ }
+}
+
+bool
+wlc_phy_get_phyversion(wlc_phy_t *pih, uint16 *phytype, uint16 *phyrev,
+ uint16 *radioid, uint16 *radiover)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ *phytype = (uint16) pi->pubpi.phy_type;
+ *phyrev = (uint16) pi->pubpi.phy_rev;
+ *radioid = pi->pubpi.radioid;
+ *radiover = pi->pubpi.radiorev;
+
+ return TRUE;
+}
+
+bool wlc_phy_get_encore(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ return pi->pubpi.abgphy_encore;
+}
+
+uint32 wlc_phy_get_coreflags(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ return pi->pubpi.coreflags;
+}
+
+static void wlc_phy_timercb_phycal(void *arg)
+{
+ phy_info_t *pi = (phy_info_t *) arg;
+ uint delay = 5;
+
+ if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+ if (!pi->sh->up) {
+ wlc_phy_cal_perical_mphase_reset(pi);
+ return;
+ }
+
+ if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
+
+ delay = 1000;
+ wlc_phy_cal_perical_mphase_restart(pi);
+ } else
+ wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
+ wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+ return;
+ }
+
+}
+
+void wlc_phy_anacore(wlc_phy_t *pih, bool on)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (ISNPHY(pi)) {
+ if (on) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0xa6, 0x0d);
+ write_phy_reg(pi, 0x8f, 0x0);
+ write_phy_reg(pi, 0xa7, 0x0d);
+ write_phy_reg(pi, 0xa5, 0x0);
+ } else {
+ write_phy_reg(pi, 0xa5, 0x0);
+ }
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0x8f, 0x07ff);
+ write_phy_reg(pi, 0xa6, 0x0fd);
+ write_phy_reg(pi, 0xa5, 0x07ff);
+ write_phy_reg(pi, 0xa7, 0x0fd);
+ } else {
+ write_phy_reg(pi, 0xa5, 0x7fff);
+ }
+ }
+ } else if (ISLCNPHY(pi)) {
+ if (on) {
+ and_phy_reg(pi, 0x43b,
+ ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+ } else {
+ or_phy_reg(pi, 0x43c,
+ (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+ or_phy_reg(pi, 0x43b,
+ (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+ }
+ }
+}
+
+uint32 wlc_phy_clk_bwbits(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ uint32 phy_bw_clkbits = 0;
+
+ if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
+ switch (pi->bw) {
+ case WL_CHANSPEC_BW_10:
+ phy_bw_clkbits = SICF_BW10;
+ break;
+ case WL_CHANSPEC_BW_20:
+ phy_bw_clkbits = SICF_BW20;
+ break;
+ case WL_CHANSPEC_BW_40:
+ phy_bw_clkbits = SICF_BW40;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ return phy_bw_clkbits;
+}
+
+void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->phy_init_por = TRUE;
+}
+
+void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->edcrs_threshold_lock = lock;
+
+ write_phy_reg(pi, 0x22c, 0x46b);
+ write_phy_reg(pi, 0x22d, 0x46b);
+ write_phy_reg(pi, 0x22e, 0x3c0);
+ write_phy_reg(pi, 0x22f, 0x3c0);
+}
+
+void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->do_initcal = initcal;
+}
+
+void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (!pi || !pi->sh)
+ return;
+
+ pi->sh->clk = newstate;
+}
+
+void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (!pi || !pi->sh)
+ return;
+
+ pi->sh->up = newstate;
+}
+
+void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec)
+{
+ uint32 mc;
+ initfn_t phy_init = NULL;
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (pi->init_in_progress)
+ return;
+
+ pi->init_in_progress = TRUE;
+
+ pi->radio_chanspec = chanspec;
+
+ mc = R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ if ((mc & MCTL_EN_MAC) != 0) {
+ ASSERT((const char *)
+ "wlc_phy_init: Called with the MAC running!" == NULL);
+ }
+
+ ASSERT(pi != NULL);
+
+ if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+ pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+ }
+
+ if (D11REV_GE(pi->sh->corerev, 5))
+ ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA);
+
+ phy_init = pi->pi_fptr.init;
+
+ if (phy_init == NULL) {
+ ASSERT(phy_init != NULL);
+ return;
+ }
+
+ wlc_phy_anacore(pih, ON);
+
+ if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
+ wlapi_bmac_bw_set(pi->sh->physhim,
+ CHSPEC_BW(pi->radio_chanspec));
+
+ pi->nphy_gain_boost = TRUE;
+
+ wlc_phy_switch_radio((wlc_phy_t *) pi, ON);
+
+ (*phy_init) (pi);
+
+ pi->phy_init_por = FALSE;
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+ wlc_phy_do_dummy_tx(pi, TRUE, OFF);
+
+ if (!(ISNPHY(pi)))
+ wlc_phy_txpower_update_shm(pi);
+
+ wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv);
+
+ pi->init_in_progress = FALSE;
+}
+
+void BCMINITFN(wlc_phy_cal_init) (wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ initfn_t cal_init = NULL;
+
+ ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0);
+
+ if (!pi->initialized) {
+ cal_init = pi->pi_fptr.calinit;
+ if (cal_init)
+ (*cal_init) (pi);
+
+ pi->initialized = TRUE;
+ }
+}
+
+int BCMUNINITFN(wlc_phy_down) (wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ int callbacks = 0;
+
+ ASSERT(pi->phytest_on == FALSE);
+
+ if (pi->phycal_timer
+ && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
+ callbacks++;
+
+ pi->nphy_iqcal_chanspec_2G = 0;
+ pi->nphy_iqcal_chanspec_5G = 0;
+
+ return callbacks;
+}
+
+static uint32 wlc_phy_get_radio_ver(phy_info_t *pi)
+{
+ uint32 ver;
+
+ ver = read_radio_id(pi);
+
+ return ver;
+}
+
+void
+wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+ uint16 tblAddr, uint16 tblDataHi, uint16 tblDataLo)
+{
+ write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+
+ pi->tbl_data_hi = tblDataHi;
+ pi->tbl_data_lo = tblDataLo;
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID ||
+ CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) &&
+ (pi->sh->chiprev == 1)) {
+ pi->tbl_addr = tblAddr;
+ pi->tbl_save_id = tbl_id;
+ pi->tbl_save_offset = tbl_offset;
+ }
+}
+
+void wlc_phy_table_data_write(phy_info_t *pi, uint width, uint32 val)
+{
+ ASSERT((width == 8) || (width == 16) || (width == 32));
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID ||
+ CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) &&
+ (pi->sh->chiprev == 1) &&
+ (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+ read_phy_reg(pi, pi->tbl_data_lo);
+
+ write_phy_reg(pi, pi->tbl_addr,
+ (pi->tbl_save_id << 10) | pi->tbl_save_offset);
+ pi->tbl_save_offset++;
+ }
+
+ if (width == 32) {
+
+ write_phy_reg(pi, pi->tbl_data_hi, (uint16) (val >> 16));
+ write_phy_reg(pi, pi->tbl_data_lo, (uint16) val);
+ } else {
+
+ write_phy_reg(pi, pi->tbl_data_lo, (uint16) val);
+ }
+}
+
+void
+wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+ uint16 tblAddr, uint16 tblDataHi, uint16 tblDataLo)
+{
+ uint idx;
+ uint tbl_id = ptbl_info->tbl_id;
+ uint tbl_offset = ptbl_info->tbl_offset;
+ uint tbl_width = ptbl_info->tbl_width;
+ const uint8 *ptbl_8b = (const uint8 *)ptbl_info->tbl_ptr;
+ const uint16 *ptbl_16b = (const uint16 *)ptbl_info->tbl_ptr;
+ const uint32 *ptbl_32b = (const uint32 *)ptbl_info->tbl_ptr;
+
+ ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32));
+
+ write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+
+ for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID ||
+ CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) &&
+ (pi->sh->chiprev == 1) &&
+ (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+ read_phy_reg(pi, tblDataLo);
+
+ write_phy_reg(pi, tblAddr,
+ (tbl_id << 10) | (tbl_offset + idx));
+ }
+
+ if (tbl_width == 32) {
+
+ write_phy_reg(pi, tblDataHi,
+ (uint16) (ptbl_32b[idx] >> 16));
+ write_phy_reg(pi, tblDataLo, (uint16) ptbl_32b[idx]);
+ } else if (tbl_width == 16) {
+
+ write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
+ } else {
+
+ write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
+ }
+ }
+}
+
+void
+wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+ uint16 tblAddr, uint16 tblDataHi, uint16 tblDataLo)
+{
+ uint idx;
+ uint tbl_id = ptbl_info->tbl_id;
+ uint tbl_offset = ptbl_info->tbl_offset;
+ uint tbl_width = ptbl_info->tbl_width;
+ uint8 *ptbl_8b = (uint8 *) (uintptr) ptbl_info->tbl_ptr;
+ uint16 *ptbl_16b = (uint16 *) (uintptr) ptbl_info->tbl_ptr;
+ uint32 *ptbl_32b = (uint32 *) (uintptr) ptbl_info->tbl_ptr;
+
+ ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32));
+
+ write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+
+ for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID ||
+ CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) &&
+ (pi->sh->chiprev == 1)) {
+ (void)read_phy_reg(pi, tblDataLo);
+
+ write_phy_reg(pi, tblAddr,
+ (tbl_id << 10) | (tbl_offset + idx));
+ }
+
+ if (tbl_width == 32) {
+
+ ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
+ ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
+ } else if (tbl_width == 16) {
+
+ ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
+ } else {
+
+ ptbl_8b[idx] = (uint8) read_phy_reg(pi, tblDataLo);
+ }
+ }
+}
+
+uint
+wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs)
+{
+ uint i = 0;
+
+ do {
+ if (radioregs[i].do_init) {
+ write_radio_reg(pi, radioregs[i].address,
+ (uint16) radioregs[i].init);
+ }
+
+ i++;
+ } while (radioregs[i].address != 0xffff);
+
+ return i;
+}
+
+uint
+wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+ uint16 core_offset)
+{
+ uint i = 0;
+ uint count = 0;
+
+ do {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (radioregs[i].do_init_a) {
+ write_radio_reg(pi,
+ radioregs[i].
+ address | core_offset,
+ (uint16) radioregs[i].init_a);
+ if (ISNPHY(pi) && (++count % 4 == 0))
+ WLC_PHY_WAR_PR51571(pi);
+ }
+ } else {
+ if (radioregs[i].do_init_g) {
+ write_radio_reg(pi,
+ radioregs[i].
+ address | core_offset,
+ (uint16) radioregs[i].init_g);
+ if (ISNPHY(pi) && (++count % 4 == 0))
+ WLC_PHY_WAR_PR51571(pi);
+ }
+ }
+
+ i++;
+ } while (radioregs[i].address != 0xffff);
+
+ return i;
+}
+
+void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on)
+{
+#define DUMMY_PKT_LEN 20
+ d11regs_t *regs = pi->regs;
+ int i, count;
+ uint8 ofdmpkt[DUMMY_PKT_LEN] = {
+ 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+ };
+ uint8 cckpkt[DUMMY_PKT_LEN] = {
+ 0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+ };
+ uint32 *dummypkt;
+
+ ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0);
+
+ dummypkt = (uint32 *) (ofdm ? ofdmpkt : cckpkt);
+ wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
+ dummypkt);
+
+ W_REG(pi->sh->osh, &regs->xmtsel, 0);
+
+ if (D11REV_GE(pi->sh->corerev, 11))
+ W_REG(pi->sh->osh, &regs->wepctl, 0x100);
+ else
+ W_REG(pi->sh->osh, &regs->wepctl, 0);
+
+ W_REG(pi->sh->osh, &regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
+ if (ISNPHY(pi) || ISLCNPHY(pi)) {
+ ASSERT(ofdm);
+ W_REG(pi->sh->osh, &regs->txe_phyctl1, 0x1A02);
+ }
+
+ W_REG(pi->sh->osh, &regs->txe_wm_0, 0);
+ W_REG(pi->sh->osh, &regs->txe_wm_1, 0);
+
+ W_REG(pi->sh->osh, &regs->xmttplatetxptr, 0);
+ W_REG(pi->sh->osh, &regs->xmttxcnt, DUMMY_PKT_LEN);
+
+ W_REG(pi->sh->osh, &regs->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
+
+ W_REG(pi->sh->osh, &regs->txe_ctl, 0);
+
+ if (!pa_on) {
+ if (ISNPHY(pi))
+ wlc_phy_pa_override_nphy(pi, OFF);
+ }
+
+ if (ISNPHY(pi) || ISLCNPHY(pi))
+ W_REG(pi->sh->osh, &regs->txe_aux, 0xD0);
+ else
+ W_REG(pi->sh->osh, &regs->txe_aux, ((1 << 5) | (1 << 4)));
+
+ (void)R_REG(pi->sh->osh, &regs->txe_aux);
+
+ i = 0;
+ count = ofdm ? 30 : 250;
+
+ if (ISSIM_ENAB(pi->sh->sih)) {
+ count *= 100;
+ }
+
+ while ((i++ < count)
+ && (R_REG(pi->sh->osh, &regs->txe_status) & (1 << 7))) {
+ OSL_DELAY(10);
+ }
+
+ i = 0;
+
+ while ((i++ < 10)
+ && ((R_REG(pi->sh->osh, &regs->txe_status) & (1 << 10)) == 0)) {
+ OSL_DELAY(10);
+ }
+
+ i = 0;
+
+ while ((i++ < 10) && ((R_REG(pi->sh->osh, &regs->ifsstat) & (1 << 8)))) {
+ OSL_DELAY(10);
+ }
+ if (!pa_on) {
+ if (ISNPHY(pi))
+ wlc_phy_pa_override_nphy(pi, ON);
+ }
+}
+
+void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ ASSERT(id);
+
+ if (set) {
+ mboolset(pi->measure_hold, id);
+ } else {
+ mboolclr(pi->measure_hold, id);
+ }
+
+ return;
+}
+
+void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (mute) {
+ mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+ } else {
+ mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+ }
+
+ if (!mute && (flags & PHY_MUTE_FOR_PREISM))
+ pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
+ return;
+}
+
+void wlc_phy_clear_tssi(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (ISNPHY(pi)) {
+ return;
+ } else {
+ wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
+ }
+}
+
+static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi)
+{
+ return FALSE;
+}
+
+void wlc_phy_switch_radio(wlc_phy_t *pih, bool on)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ {
+ uint mc;
+
+ mc = R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ }
+
+ if (ISNPHY(pi)) {
+ wlc_phy_switch_radio_nphy(pi, on);
+
+ } else if (ISLCNPHY(pi)) {
+ if (on) {
+ and_phy_reg(pi, 0x44c,
+ ~((0x1 << 8) |
+ (0x1 << 9) |
+ (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
+ and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
+ and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
+ } else {
+ and_phy_reg(pi, 0x44d,
+ ~((0x1 << 10) |
+ (0x1 << 11) |
+ (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
+ or_phy_reg(pi, 0x44c,
+ (0x1 << 8) |
+ (0x1 << 9) |
+ (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
+
+ and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
+ and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
+ or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
+ and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
+ or_phy_reg(pi, 0x4f9, (0x1 << 3));
+ }
+ }
+}
+
+uint16 wlc_phy_bw_state_get(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ return pi->bw;
+}
+
+void wlc_phy_bw_state_set(wlc_phy_t *ppi, uint16 bw)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->bw = bw;
+}
+
+void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ pi->radio_chanspec = newch;
+
+}
+
+chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ return pi->radio_chanspec;
+}
+
+void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint16 m_cur_channel;
+ chansetfn_t chanspec_set = NULL;
+
+ ASSERT(!wf_chspec_malformed(chanspec));
+
+ m_cur_channel = CHSPEC_CHANNEL(chanspec);
+ if (CHSPEC_IS5G(chanspec))
+ m_cur_channel |= D11_CURCHANNEL_5G;
+ if (CHSPEC_IS40(chanspec))
+ m_cur_channel |= D11_CURCHANNEL_40;
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
+
+ chanspec_set = pi->pi_fptr.chanset;
+ if (chanspec_set)
+ (*chanspec_set) (pi, chanspec);
+
+}
+
+int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
+{
+ int range = -1;
+
+ if (freq < 2500)
+ range = WL_CHAN_FREQ_RANGE_2G;
+ else if (freq <= 5320)
+ range = WL_CHAN_FREQ_RANGE_5GL;
+ else if (freq <= 5700)
+ range = WL_CHAN_FREQ_RANGE_5GM;
+ else
+ range = WL_CHAN_FREQ_RANGE_5GH;
+
+ return range;
+}
+
+int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec)
+{
+ int range = -1;
+ uint channel = CHSPEC_CHANNEL(chanspec);
+ uint freq = wlc_phy_channel2freq(channel);
+
+ if (ISNPHY(pi)) {
+ range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
+ } else if (ISLCNPHY(pi)) {
+ range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
+ } else
+ ASSERT(0);
+
+ return range;
+}
+
+void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->channel_14_wide_filter = wide_filter;
+
+}
+
+int wlc_phy_channel2freq(uint channel)
+{
+ uint i;
+
+ for (i = 0; i < ARRAYSIZE(chan_info_all); i++)
+ if (chan_info_all[i].chan == channel)
+ return chan_info_all[i].freq;
+ return 0;
+}
+
+void
+wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint i;
+ uint channel;
+
+ ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G));
+
+ bzero(channels, sizeof(chanvec_t));
+
+ for (i = 0; i < ARRAYSIZE(chan_info_all); i++) {
+ channel = chan_info_all[i].chan;
+
+ if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+ && (channel <= LAST_REF5_CHANNUM))
+ continue;
+
+ if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+ ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+ setbit(channels->vec, channel);
+ }
+}
+
+chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint i;
+ uint channel;
+ chanspec_t chspec;
+
+ ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G));
+
+ for (i = 0; i < ARRAYSIZE(chan_info_all); i++) {
+ channel = chan_info_all[i].chan;
+
+ if (ISNPHY(pi) && IS40MHZ(pi)) {
+ uint j;
+
+ for (j = 0; j < ARRAYSIZE(chan_info_all); j++) {
+ if (chan_info_all[j].chan ==
+ channel + CH_10MHZ_APART)
+ break;
+ }
+
+ if (j == ARRAYSIZE(chan_info_all))
+ continue;
+
+ channel = UPPER_20_SB(channel);
+ chspec =
+ channel | WL_CHANSPEC_BW_40 |
+ WL_CHANSPEC_CTL_SB_LOWER;
+ if (band == WLC_BAND_2G)
+ chspec |= WL_CHANSPEC_BAND_2G;
+ else
+ chspec |= WL_CHANSPEC_BAND_5G;
+ } else
+ chspec = CH20MHZ_CHSPEC(channel);
+
+ if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+ && (channel <= LAST_REF5_CHANNUM))
+ continue;
+
+ if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+ ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+ return chspec;
+ }
+
+ ASSERT(0);
+
+ return (chanspec_t) INVCHANSPEC;
+}
+
+int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ ASSERT(qdbm != NULL);
+ *qdbm = pi->tx_user_target[0];
+ if (override != NULL)
+ *override = pi->txpwroverride;
+ return 0;
+}
+
+void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr)
+{
+ bool mac_enabled = FALSE;
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ bcopy(&txpwr->cck[0], &pi->tx_user_target[TXP_FIRST_CCK],
+ WLC_NUM_RATES_CCK);
+
+ bcopy(&txpwr->ofdm[0], &pi->tx_user_target[TXP_FIRST_OFDM],
+ WLC_NUM_RATES_OFDM);
+ bcopy(&txpwr->ofdm_cdd[0], &pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
+ WLC_NUM_RATES_OFDM);
+
+ bcopy(&txpwr->ofdm_40_siso[0],
+ &pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], WLC_NUM_RATES_OFDM);
+ bcopy(&txpwr->ofdm_40_cdd[0],
+ &pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], WLC_NUM_RATES_OFDM);
+
+ bcopy(&txpwr->mcs_20_siso[0],
+ &pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_20_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_20_stbc[0],
+ &pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_20_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
+ WLC_NUM_RATES_MCS_2_STREAM);
+
+ bcopy(&txpwr->mcs_40_siso[0],
+ &pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_40_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_40_stbc[0],
+ &pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
+ WLC_NUM_RATES_MCS_1_STREAM);
+ bcopy(&txpwr->mcs_40_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
+ WLC_NUM_RATES_MCS_2_STREAM);
+
+ if (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)
+ mac_enabled = TRUE;
+
+ if (mac_enabled)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ wlc_phy_txpower_recalc_target(pi);
+ wlc_phy_cal_txpower_recalc_sw(pi);
+
+ if (mac_enabled)
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ int i;
+
+ if (qdbm > 127)
+ return 5;
+
+ for (i = 0; i < TXP_NUM_RATES; i++)
+ pi->tx_user_target[i] = (uint8) qdbm;
+
+ pi->txpwroverride = FALSE;
+
+ if (pi->sh->up) {
+ if (!SCAN_INPROG_PHY(pi)) {
+ bool suspend;
+
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) &
+ MCTL_EN_MAC));
+
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ wlc_phy_txpower_recalc_target(pi);
+ wlc_phy_cal_txpower_recalc_sw(pi);
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ }
+ }
+ return 0;
+}
+
+void
+wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, uint8 *min_pwr,
+ uint8 *max_pwr, int txp_rate_idx)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint i;
+
+ *min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR;
+
+ if (ISNPHY(pi)) {
+ if (txp_rate_idx < 0)
+ txp_rate_idx = TXP_FIRST_CCK;
+ wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
+ (uint8) txp_rate_idx);
+
+ } else if ((channel <= CH_MAX_2G_CHANNEL)) {
+ if (txp_rate_idx < 0)
+ txp_rate_idx = TXP_FIRST_CCK;
+ *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+ } else {
+
+ *max_pwr = WLC_TXPWR_MAX;
+
+ if (txp_rate_idx < 0)
+ txp_rate_idx = TXP_FIRST_OFDM;
+
+ for (i = 0; i < ARRAYSIZE(chan_info_all); i++) {
+ if (channel == chan_info_all[i].chan) {
+ break;
+ }
+ }
+ ASSERT(i < ARRAYSIZE(chan_info_all));
+
+ if (pi->hwtxpwr) {
+ *max_pwr = pi->hwtxpwr[i];
+ } else {
+
+ if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
+ *max_pwr =
+ pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+ if ((i >= FIRST_HIGH_5G_CHAN)
+ && (i <= LAST_HIGH_5G_CHAN))
+ *max_pwr =
+ pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+ if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
+ *max_pwr =
+ pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+ }
+ }
+}
+
+void
+wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, uint8 *max_txpwr,
+ uint8 *min_txpwr)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint8 tx_pwr_max = 0;
+ uint8 tx_pwr_min = 255;
+ uint8 max_num_rate;
+ uint8 maxtxpwr, mintxpwr, rate, pactrl;
+
+ pactrl = 0;
+
+ max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
+ ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1);
+
+ for (rate = 0; rate < max_num_rate; rate++) {
+
+ wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
+ rate);
+
+ maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+
+ maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+
+ tx_pwr_max = MAX(tx_pwr_max, maxtxpwr);
+ tx_pwr_min = MIN(tx_pwr_min, maxtxpwr);
+ }
+ *max_txpwr = tx_pwr_max;
+ *min_txpwr = tx_pwr_min;
+}
+
+void
+wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, int32 *max_pwr,
+ int32 *min_pwr, uint32 *step_pwr)
+{
+ return;
+}
+
+uint8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ return pi->tx_power_min;
+}
+
+uint8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ return pi->tx_power_max;
+}
+
+void wlc_phy_txpower_recalc_target(phy_info_t *pi)
+{
+ uint8 maxtxpwr, mintxpwr, rate, pactrl;
+ uint target_chan;
+ uint8 tx_pwr_target[TXP_NUM_RATES];
+ uint8 tx_pwr_max = 0;
+ uint8 tx_pwr_min = 255;
+ uint8 tx_pwr_max_rate_ind = 0;
+ uint8 max_num_rate;
+ uint8 start_rate = 0;
+ chanspec_t chspec;
+ uint32 band = CHSPEC2WLC_BAND(pi->radio_chanspec);
+ initfn_t txpwr_recalc_fn = NULL;
+
+ chspec = pi->radio_chanspec;
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
+ target_chan = CHSPEC_CHANNEL(chspec);
+ else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
+ target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+ else
+ target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+
+ pactrl = 0;
+ if (ISLCNPHY(pi)) {
+ uint32 offset_mcs, i;
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ offset_mcs = pi->mcs40_po;
+ for (i = TXP_FIRST_SISO_MCS_20;
+ i <= TXP_LAST_SISO_MCS_20; i++) {
+ pi->tx_srom_max_rate_2g[i - 8] =
+ pi->tx_srom_max_2g -
+ ((offset_mcs & 0xf) * 2);
+ offset_mcs >>= 4;
+ }
+ } else {
+ offset_mcs = pi->mcs20_po;
+ for (i = TXP_FIRST_SISO_MCS_20;
+ i <= TXP_LAST_SISO_MCS_20; i++) {
+ pi->tx_srom_max_rate_2g[i - 8] =
+ pi->tx_srom_max_2g -
+ ((offset_mcs & 0xf) * 2);
+ offset_mcs >>= 4;
+ }
+ }
+ }
+#if WL11N
+ max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+ ((ISLCNPHY(pi)) ?
+ (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
+#else
+ max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1));
+#endif
+
+ wlc_phy_upd_env_txpwr_rate_limits(pi, band);
+
+ for (rate = start_rate; rate < max_num_rate; rate++) {
+
+ tx_pwr_target[rate] = pi->tx_user_target[rate];
+
+ if (pi->user_txpwr_at_rfport) {
+ tx_pwr_target[rate] +=
+ wlc_user_txpwr_antport_to_rfport(pi, target_chan,
+ band, rate);
+ }
+
+ {
+
+ wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan,
+ &mintxpwr, &maxtxpwr, rate);
+
+ maxtxpwr = MIN(maxtxpwr, pi->txpwr_limit[rate]);
+
+ maxtxpwr =
+ (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+
+ maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+
+ maxtxpwr = MIN(maxtxpwr, tx_pwr_target[rate]);
+
+ if (pi->txpwr_percent <= 100)
+ maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
+
+ tx_pwr_target[rate] = MAX(maxtxpwr, mintxpwr);
+ }
+
+ tx_pwr_target[rate] =
+ MIN(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
+
+ if (tx_pwr_target[rate] > tx_pwr_max)
+ tx_pwr_max_rate_ind = rate;
+
+ tx_pwr_max = MAX(tx_pwr_max, tx_pwr_target[rate]);
+ tx_pwr_min = MIN(tx_pwr_min, tx_pwr_target[rate]);
+ }
+
+ bzero(pi->tx_power_offset, sizeof(pi->tx_power_offset));
+ pi->tx_power_max = tx_pwr_max;
+ pi->tx_power_min = tx_pwr_min;
+ pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
+ for (rate = 0; rate < max_num_rate; rate++) {
+
+ pi->tx_power_target[rate] = tx_pwr_target[rate];
+
+ if (!pi->hwpwrctrl || ISNPHY(pi)) {
+ pi->tx_power_offset[rate] =
+ pi->tx_power_max - pi->tx_power_target[rate];
+ } else {
+ pi->tx_power_offset[rate] =
+ pi->tx_power_target[rate] - pi->tx_power_min;
+ }
+ }
+
+ txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
+ if (txpwr_recalc_fn)
+ (*txpwr_recalc_fn) (pi);
+}
+
+void
+wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr,
+ chanspec_t chanspec)
+{
+ uint8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM];
+ uint8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
+ int rate_start_index = 0, rate1, rate2, k;
+
+ for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
+ rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
+ pi->txpwr_limit[rate1] = txpwr->cck[rate2];
+
+ for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
+ rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
+ pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
+
+ if (ISNPHY(pi)) {
+
+ for (k = 0; k < 4; k++) {
+ switch (k) {
+ case 0:
+
+ txpwr_ptr1 = txpwr->mcs_20_siso;
+ txpwr_ptr2 = txpwr->ofdm;
+ rate_start_index = WL_TX_POWER_OFDM_FIRST;
+ break;
+ case 1:
+
+ txpwr_ptr1 = txpwr->mcs_20_cdd;
+ txpwr_ptr2 = txpwr->ofdm_cdd;
+ rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
+ break;
+ case 2:
+
+ txpwr_ptr1 = txpwr->mcs_40_siso;
+ txpwr_ptr2 = txpwr->ofdm_40_siso;
+ rate_start_index =
+ WL_TX_POWER_OFDM40_SISO_FIRST;
+ break;
+ case 3:
+
+ txpwr_ptr1 = txpwr->mcs_40_cdd;
+ txpwr_ptr2 = txpwr->ofdm_40_cdd;
+ rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
+ break;
+ }
+
+ for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+ tmp_txpwr_limit[rate2] = 0;
+ tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+ txpwr_ptr1[rate2];
+ }
+ wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0,
+ WLC_NUM_RATES_OFDM - 1,
+ WLC_NUM_RATES_OFDM);
+ for (rate1 = rate_start_index, rate2 = 0;
+ rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++)
+ pi->txpwr_limit[rate1] =
+ MIN(txpwr_ptr2[rate2],
+ tmp_txpwr_limit[rate2]);
+ }
+
+ for (k = 0; k < 4; k++) {
+ switch (k) {
+ case 0:
+
+ txpwr_ptr1 = txpwr->ofdm;
+ txpwr_ptr2 = txpwr->mcs_20_siso;
+ rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
+ break;
+ case 1:
+
+ txpwr_ptr1 = txpwr->ofdm_cdd;
+ txpwr_ptr2 = txpwr->mcs_20_cdd;
+ rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
+ break;
+ case 2:
+
+ txpwr_ptr1 = txpwr->ofdm_40_siso;
+ txpwr_ptr2 = txpwr->mcs_40_siso;
+ rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
+ break;
+ case 3:
+
+ txpwr_ptr1 = txpwr->ofdm_40_cdd;
+ txpwr_ptr2 = txpwr->mcs_40_cdd;
+ rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
+ break;
+ }
+ for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+ tmp_txpwr_limit[rate2] = 0;
+ tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+ txpwr_ptr1[rate2];
+ }
+ wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0,
+ WLC_NUM_RATES_OFDM - 1,
+ WLC_NUM_RATES_OFDM);
+ for (rate1 = rate_start_index, rate2 = 0;
+ rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+ rate1++, rate2++)
+ pi->txpwr_limit[rate1] =
+ MIN(txpwr_ptr2[rate2],
+ tmp_txpwr_limit[rate2]);
+ }
+
+ for (k = 0; k < 2; k++) {
+ switch (k) {
+ case 0:
+
+ rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
+ txpwr_ptr1 = txpwr->mcs_20_stbc;
+ break;
+ case 1:
+
+ rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
+ txpwr_ptr1 = txpwr->mcs_40_stbc;
+ break;
+ }
+ for (rate1 = rate_start_index, rate2 = 0;
+ rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+ rate1++, rate2++)
+ pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+ }
+
+ for (k = 0; k < 2; k++) {
+ switch (k) {
+ case 0:
+
+ rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
+ txpwr_ptr1 = txpwr->mcs_20_mimo;
+ break;
+ case 1:
+
+ rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
+ txpwr_ptr1 = txpwr->mcs_40_mimo;
+ break;
+ }
+ for (rate1 = rate_start_index, rate2 = 0;
+ rate2 < WLC_NUM_RATES_MCS_2_STREAM;
+ rate1++, rate2++)
+ pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+ }
+
+ pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
+
+ pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
+ MIN(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
+ pi->txpwr_limit[WL_TX_POWER_MCS_32]);
+ pi->txpwr_limit[WL_TX_POWER_MCS_32] =
+ pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
+ }
+}
+
+void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, uint8 txpwr_percent)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->txpwr_percent = txpwr_percent;
+}
+
+void wlc_phy_machwcap_set(wlc_phy_t *ppi, uint32 machwcap)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->sh->machwcap = machwcap;
+}
+
+void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint16 rxc;
+ rxc = 0;
+
+ if (start_end == ON) {
+ if (!ISNPHY(pi))
+ return;
+
+ if (NREV_IS(pi->pubpi.phy_rev, 3)
+ || NREV_IS(pi->pubpi.phy_rev, 4)) {
+ W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0);
+ (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr);
+ rxc = R_REG(pi->sh->osh, &pi->regs->phyregdata);
+ W_REG(pi->sh->osh, &pi->regs->phyregdata,
+ (0x1 << 15) | rxc);
+ }
+ } else {
+ if (NREV_IS(pi->pubpi.phy_rev, 3)
+ || NREV_IS(pi->pubpi.phy_rev, 4)) {
+ W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0);
+ (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr);
+ W_REG(pi->sh->osh, &pi->regs->phyregdata, rxc);
+ }
+
+ wlc_phy_por_inform(ppi);
+ }
+}
+
+void
+wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr,
+ chanspec_t chanspec)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
+
+ if (ISLCNPHY(pi)) {
+ int i, j;
+ for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
+ j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) {
+ if (txpwr->mcs_20_siso[j])
+ pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
+ else
+ pi->txpwr_limit[i] = txpwr->ofdm[j];
+ }
+ }
+
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ wlc_phy_txpower_recalc_target(pi);
+ wlc_phy_cal_txpower_recalc_sw(pi);
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->ofdm_rateset_war = war;
+}
+
+void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->bf_preempt_4306 = bf_preempt;
+}
+
+void wlc_phy_txpower_update_shm(phy_info_t *pi)
+{
+ int j;
+ if (ISNPHY(pi)) {
+ ASSERT(0);
+ return;
+ }
+
+ if (!pi->sh->clk)
+ return;
+
+ if (pi->hwpwrctrl) {
+ uint16 offset;
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
+ 1 << NUM_TSSI_FRAMES);
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
+ pi->tx_power_min << NUM_TSSI_FRAMES);
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
+ pi->hwpwr_txcur);
+
+ for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
+ const uint8 ucode_ofdm_rates[] = {
+ 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
+ };
+ offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim,
+ ucode_ofdm_rates[j -
+ TXP_FIRST_OFDM]);
+ wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
+ pi->tx_power_offset[j]);
+ wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
+ -(pi->tx_power_offset[j] / 2));
+ }
+
+ wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
+ MHF2_HWPWRCTL, WLC_BAND_ALL);
+ } else {
+ int i;
+
+ for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
+ pi->tx_power_offset[i] =
+ (uint8) ROUNDUP(pi->tx_power_offset[i], 8);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
+ (uint16) ((pi->
+ tx_power_offset[TXP_FIRST_OFDM]
+ + 7) >> 3));
+ }
+}
+
+bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ if (ISNPHY(pi)) {
+ return pi->nphy_txpwrctrl;
+ } else {
+ return pi->hwpwrctrl;
+ }
+}
+
+void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ bool cur_hwpwrctrl = pi->hwpwrctrl;
+ bool suspend;
+
+ if (!pi->hwpwrctrl_capable) {
+ return;
+ }
+
+ pi->hwpwrctrl = hwpwrctrl;
+ pi->nphy_txpwrctrl = hwpwrctrl;
+ pi->txpwrctrl = hwpwrctrl;
+
+ if (ISNPHY(pi)) {
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+ if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+ wlc_phy_txpwr_fixpower_nphy(pi);
+ } else {
+
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+ pi->saved_txpwr_idx);
+ }
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ } else if (hwpwrctrl != cur_hwpwrctrl) {
+
+ return;
+ }
+}
+
+void wlc_phy_txpower_ipa_upd(phy_info_t *pi)
+{
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
+ pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
+ } else {
+ pi->ipa2g_on = FALSE;
+ pi->ipa5g_on = FALSE;
+ }
+}
+
+static uint32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi);
+
+static uint32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi)
+{
+ int16 tx0_status, tx1_status;
+ uint16 estPower1, estPower2;
+ uint8 pwr0, pwr1, adj_pwr0, adj_pwr1;
+ uint32 est_pwr;
+
+ estPower1 = read_phy_reg(pi, 0x118);
+ estPower2 = read_phy_reg(pi, 0x119);
+
+ if ((estPower1 & (0x1 << 8))
+ == (0x1 << 8)) {
+ pwr0 = (uint8) (estPower1 & (0xff << 0))
+ >> 0;
+ } else {
+ pwr0 = 0x80;
+ }
+
+ if ((estPower2 & (0x1 << 8))
+ == (0x1 << 8)) {
+ pwr1 = (uint8) (estPower2 & (0xff << 0))
+ >> 0;
+ } else {
+ pwr1 = 0x80;
+ }
+
+ tx0_status = read_phy_reg(pi, 0x1ed);
+ tx1_status = read_phy_reg(pi, 0x1ee);
+
+ if ((tx0_status & (0x1 << 15))
+ == (0x1 << 15)) {
+ adj_pwr0 = (uint8) (tx0_status & (0xff << 0))
+ >> 0;
+ } else {
+ adj_pwr0 = 0x80;
+ }
+ if ((tx1_status & (0x1 << 15))
+ == (0x1 << 15)) {
+ adj_pwr1 = (uint8) (tx1_status & (0xff << 0))
+ >> 0;
+ } else {
+ adj_pwr1 = 0x80;
+ }
+
+ est_pwr =
+ (uint32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1);
+ return est_pwr;
+}
+
+void
+wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint rate, num_rates;
+ uint8 min_pwr, max_pwr;
+
+#if WL_TX_POWER_RATES != TXP_NUM_RATES
+#error "tx_power_t struct out of sync with this fn"
+#endif
+
+ if (ISNPHY(pi)) {
+ power->rf_cores = 2;
+ power->flags |= (WL_TX_POWER_F_MIMO);
+ if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+ power->flags |=
+ (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
+ } else if (ISLCNPHY(pi)) {
+ power->rf_cores = 1;
+ power->flags |= (WL_TX_POWER_F_SISO);
+ if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
+ power->flags |= WL_TX_POWER_F_ENABLED;
+ if (pi->hwpwrctrl)
+ power->flags |= WL_TX_POWER_F_HW;
+ }
+
+ num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+ ((ISLCNPHY(pi)) ?
+ (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
+
+ for (rate = 0; rate < num_rates; rate++) {
+ power->user_limit[rate] = pi->tx_user_target[rate];
+ wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
+ rate);
+ power->board_limit[rate] = (uint8) max_pwr;
+ power->target[rate] = pi->tx_power_target[rate];
+ }
+
+ if (ISNPHY(pi)) {
+ uint32 est_pout;
+
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_phyreg_enter((wlc_phy_t *) pi);
+ est_pout = wlc_phy_txpower_est_power_nphy(pi);
+ wlc_phyreg_exit((wlc_phy_t *) pi);
+ wlapi_enable_mac(pi->sh->physhim);
+
+ power->est_Pout[0] = (est_pout >> 8) & 0xff;
+ power->est_Pout[1] = est_pout & 0xff;
+
+ power->est_Pout_act[0] = est_pout >> 24;
+ power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
+
+ if (power->est_Pout[0] == 0x80)
+ power->est_Pout[0] = 0;
+ if (power->est_Pout[1] == 0x80)
+ power->est_Pout[1] = 0;
+
+ if (power->est_Pout_act[0] == 0x80)
+ power->est_Pout_act[0] = 0;
+ if (power->est_Pout_act[1] == 0x80)
+ power->est_Pout_act[1] = 0;
+
+ power->est_Pout_cck = 0;
+
+ power->tx_power_max[0] = pi->tx_power_max;
+ power->tx_power_max[1] = pi->tx_power_max;
+
+ power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
+ power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
+ } else if (!pi->hwpwrctrl) {
+ } else if (pi->sh->up) {
+
+ wlc_phyreg_enter(ppi);
+ if (ISLCNPHY(pi)) {
+
+ power->tx_power_max[0] = pi->tx_power_max;
+ power->tx_power_max[1] = pi->tx_power_max;
+
+ power->tx_power_max_rate_ind[0] =
+ pi->tx_power_max_rate_ind;
+ power->tx_power_max_rate_ind[1] =
+ pi->tx_power_max_rate_ind;
+
+ if (wlc_phy_tpc_isenabled_lcnphy(pi))
+ power->flags |=
+ (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+ else
+ power->flags &=
+ ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+
+ wlc_lcnphy_get_tssi(pi, (int8 *) &power->est_Pout[0],
+ (int8 *) &power->est_Pout_cck);
+ }
+ wlc_phyreg_exit(ppi);
+ }
+}
+
+void wlc_phy_antsel_type_set(wlc_phy_t *ppi, uint8 antsel_type)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ pi->antsel_type = antsel_type;
+}
+
+bool wlc_phy_test_ison(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ return pi->phytest_on;
+}
+
+bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, uint8 *pval)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ bool ret = TRUE;
+
+ wlc_phyreg_enter(ppi);
+
+ if (ISNPHY(pi)) {
+
+ ret = FALSE;
+ } else if (ISLCNPHY(pi)) {
+ uint16 crsctrl = read_phy_reg(pi, 0x410);
+ uint16 div = crsctrl & (0x1 << 1);
+ *pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1)));
+ }
+
+ wlc_phyreg_exit(ppi);
+
+ return ret;
+}
+
+void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, uint8 val)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ bool suspend;
+
+ pi->sh->rx_antdiv = val;
+
+ if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
+ if (val > ANT_RX_DIV_FORCE_1)
+ wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
+ MHF1_ANTDIV, WLC_BAND_ALL);
+ else
+ wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
+ WLC_BAND_ALL);
+ }
+
+ if (ISNPHY(pi)) {
+
+ return;
+ }
+
+ if (!pi->sh->clk)
+ return;
+
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ if (ISLCNPHY(pi)) {
+ if (val > ANT_RX_DIV_FORCE_1) {
+ mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
+ mod_phy_reg(pi, 0x410,
+ (0x1 << 0),
+ ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
+ } else {
+ mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
+ mod_phy_reg(pi, 0x410, (0x1 << 0), (uint16) val << 0);
+ }
+ } else {
+ ASSERT(0);
+ }
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+
+ return;
+}
+
+static bool
+wlc_phy_noise_calc_phy(phy_info_t *pi, uint32 *cmplx_pwr, int8 *pwr_ant)
+{
+ int8 cmplx_pwr_dbm[PHY_CORE_MAX];
+ uint8 i;
+
+ bzero((uint8 *) cmplx_pwr_dbm, sizeof(cmplx_pwr_dbm));
+ ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
+ wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
+
+ for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3))
+ cmplx_pwr_dbm[i] += (int8) PHY_NOISE_OFFSETFACT_4322;
+ else
+
+ cmplx_pwr_dbm[i] += (int8) (16 - (15) * 3 - 70);
+ }
+
+ for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+ pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
+ pwr_ant[i] = cmplx_pwr_dbm[i];
+ }
+ pi->nphy_noise_index =
+ MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+ return TRUE;
+}
+
+static void
+wlc_phy_noise_sample_request(wlc_phy_t *pih, uint8 reason, uint8 ch)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ int8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+ bool sampling_in_progress = (pi->phynoise_state != 0);
+ bool wait_for_intr = TRUE;
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+ return;
+ }
+
+ switch (reason) {
+ case PHY_NOISE_SAMPLE_MON:
+
+ pi->phynoise_chan_watchdog = ch;
+ pi->phynoise_state |= PHY_NOISE_STATE_MON;
+
+ break;
+
+ case PHY_NOISE_SAMPLE_EXTERNAL:
+
+ pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if (sampling_in_progress)
+ return;
+
+ pi->phynoise_now = pi->sh->now;
+
+ if (pi->phy_fixed_noise) {
+ if (ISNPHY(pi)) {
+ pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
+ PHY_NOISE_FIXED_VAL_NPHY;
+ pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
+ PHY_NOISE_FIXED_VAL_NPHY;
+ pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+ PHY_NOISE_WINDOW_SZ);
+
+ noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+ } else {
+
+ noise_dbm = PHY_NOISE_FIXED_VAL;
+ }
+
+ wait_for_intr = FALSE;
+ goto done;
+ }
+
+ if (ISLCNPHY(pi)) {
+ if (!pi->phynoise_polling
+ || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+ wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+
+ OR_REG(pi->sh->osh, &pi->regs->maccommand,
+ MCMD_BG_NOISE);
+ } else {
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_deaf_mode(pi, (bool) 0);
+ noise_dbm = (int8) wlc_lcnphy_rx_signal_power(pi, 20);
+ wlc_lcnphy_deaf_mode(pi, (bool) 1);
+ wlapi_enable_mac(pi->sh->physhim);
+ wait_for_intr = FALSE;
+ }
+ } else if (ISNPHY(pi)) {
+ if (!pi->phynoise_polling
+ || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+
+ OR_REG(pi->sh->osh, &pi->regs->maccommand,
+ MCMD_BG_NOISE);
+ } else {
+ phy_iq_est_t est[PHY_CORE_MAX];
+ uint32 cmplx_pwr[PHY_CORE_MAX];
+ int8 noise_dbm_ant[PHY_CORE_MAX];
+ uint16 log_num_samps, num_samps, classif_state = 0;
+ uint8 wait_time = 32;
+ uint8 wait_crs = 0;
+ uint8 i;
+
+ bzero((uint8 *) est, sizeof(est));
+ bzero((uint8 *) cmplx_pwr, sizeof(cmplx_pwr));
+ bzero((uint8 *) noise_dbm_ant, sizeof(noise_dbm_ant));
+
+ log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+ num_samps = 1 << log_num_samps;
+
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+ wlc_phy_classifier_nphy(pi, 3, 0);
+ wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
+ wait_crs);
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+ wlapi_enable_mac(pi->sh->physhim);
+
+ for (i = 0; i < pi->pubpi.phy_corenum; i++)
+ cmplx_pwr[i] =
+ (est[i].i_pwr +
+ est[i].q_pwr) >> log_num_samps;
+
+ wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+
+ for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+ pi->nphy_noise_win[i][pi->nphy_noise_index] =
+ noise_dbm_ant[i];
+
+ if (noise_dbm_ant[i] > noise_dbm)
+ noise_dbm = noise_dbm_ant[i];
+ }
+ pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+ PHY_NOISE_WINDOW_SZ);
+
+ wait_for_intr = FALSE;
+ }
+ }
+
+ done:
+
+ if (!wait_for_intr)
+ wlc_phy_noise_cb(pi, ch, noise_dbm);
+
+}
+
+void wlc_phy_noise_sample_request_external(wlc_phy_t *pih)
+{
+ uint8 channel;
+
+ channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
+
+ wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
+}
+
+static void wlc_phy_noise_cb(phy_info_t *pi, uint8 channel, int8 noise_dbm)
+{
+ if (!pi->phynoise_state)
+ return;
+
+ if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
+ if (pi->phynoise_chan_watchdog == channel) {
+ pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
+ noise_dbm;
+ pi->sh->phy_noise_index =
+ MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
+ }
+ pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
+ }
+
+ if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) {
+ pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
+ }
+
+}
+
+static int8 wlc_phy_noise_read_shmem(phy_info_t *pi)
+{
+ uint32 cmplx_pwr[PHY_CORE_MAX];
+ int8 noise_dbm_ant[PHY_CORE_MAX];
+ uint16 lo, hi;
+ uint32 cmplx_pwr_tot = 0;
+ int8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+ uint8 idx, core;
+
+ ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
+ bzero((uint8 *) cmplx_pwr, sizeof(cmplx_pwr));
+ bzero((uint8 *) noise_dbm_ant, sizeof(noise_dbm_ant));
+
+ for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) {
+ lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
+ hi = wlapi_bmac_read_shm(pi->sh->physhim,
+ M_PWRIND_MAP(idx + 1));
+ cmplx_pwr[core] = (hi << 16) + lo;
+ cmplx_pwr_tot += cmplx_pwr[core];
+ if (cmplx_pwr[core] == 0) {
+ noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
+ } else
+ cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
+ }
+
+ if (cmplx_pwr_tot != 0)
+ wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ pi->nphy_noise_win[core][pi->nphy_noise_index] =
+ noise_dbm_ant[core];
+
+ if (noise_dbm_ant[core] > noise_dbm)
+ noise_dbm = noise_dbm_ant[core];
+ }
+ pi->nphy_noise_index =
+ MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+
+ return noise_dbm;
+
+}
+
+void wlc_phy_noise_sample_intr(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ uint16 jssi_aux;
+ uint8 channel = 0;
+ int8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+
+ if (ISLCNPHY(pi)) {
+ uint32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
+ uint16 lo, hi;
+ int32 pwr_offset_dB, gain_dB;
+ uint16 status_0, status_1;
+
+ jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+ channel = jssi_aux & D11_CURCHANNEL_MAX;
+
+ lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
+ hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
+ cmplx_pwr0 = (hi << 16) + lo;
+
+ lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
+ hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
+ cmplx_pwr1 = (hi << 16) + lo;
+ cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
+
+ status_0 = 0x44;
+ status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
+ if ((cmplx_pwr > 0 && cmplx_pwr < 500)
+ && ((status_1 & 0xc000) == 0x4000)) {
+
+ wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
+ pi->pubpi.phy_corenum);
+ pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
+ if (pwr_offset_dB > 127)
+ pwr_offset_dB -= 256;
+
+ noise_dbm += (int8) (pwr_offset_dB - 30);
+
+ gain_dB = (status_0 & 0x1ff);
+ noise_dbm -= (int8) (gain_dB);
+ } else {
+ noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
+ }
+ } else if (ISNPHY(pi)) {
+
+ jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+ channel = jssi_aux & D11_CURCHANNEL_MAX;
+
+ noise_dbm = wlc_phy_noise_read_shmem(pi);
+ } else {
+ ASSERT(0);
+ }
+
+ wlc_phy_noise_cb(pi, channel, noise_dbm);
+
+}
+
+int8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 9,
+ 10,
+ 8,
+ 8,
+ 7,
+ 7,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+void wlc_phy_compute_dB(uint32 *cmplx_pwr, int8 *p_cmplx_pwr_dB, uint8 core)
+{
+ uint8 shift_ct, lsb, msb, secondmsb, i;
+ uint32 tmp;
+
+ for (i = 0; i < core; i++) {
+ tmp = cmplx_pwr[i];
+ shift_ct = msb = secondmsb = 0;
+ while (tmp != 0) {
+ tmp = tmp >> 1;
+ shift_ct++;
+ lsb = (uint8) (tmp & 1);
+ if (lsb == 1)
+ msb = shift_ct;
+ }
+ secondmsb = (uint8) ((cmplx_pwr[i] >> (msb - 1)) & 1);
+ p_cmplx_pwr_dB[i] = (int8) (3 * msb + 2 * secondmsb);
+ }
+}
+
+void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx)
+{
+ wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx;
+ d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr;
+ int rssi = ltoh16(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK;
+ uint radioid = pih->radioid;
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+ rssi = WLC_RSSI_INVALID;
+ goto end;
+ }
+
+ if ((pi->sh->corerev >= 11)
+ && !(ltoh16(rxh->RxStatus2) & RXS_PHYRXST_VALID)) {
+ rssi = WLC_RSSI_INVALID;
+ goto end;
+ }
+
+ if (ISLCNPHY(pi)) {
+ uint8 gidx = (ltoh16(rxh->PhyRxStatus_2) & 0xFC00) >> 10;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (rssi > 127)
+ rssi -= 256;
+
+ rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
+ if ((rssi > -46) && (gidx > 18))
+ rssi = rssi + 7;
+
+ rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
+
+ rssi = rssi + 2;
+
+ }
+
+ if (ISLCNPHY(pi)) {
+
+ if (rssi > 127)
+ rssi -= 256;
+ } else if (radioid == BCM2055_ID || radioid == BCM2056_ID
+ || radioid == BCM2057_ID) {
+ ASSERT(ISNPHY(pi));
+ rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr);
+ } else {
+ ASSERT((const char *)"Unknown radio" == NULL);
+ }
+
+ end:
+ wlc_rxhdr->rssi = (int8) rssi;
+}
+
+void wlc_phy_freqtrack_start(wlc_phy_t *pih)
+{
+ return;
+}
+
+void wlc_phy_freqtrack_end(wlc_phy_t *pih)
+{
+ return;
+}
+
+void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag)
+{
+ phy_info_t *pi;
+ pi = (phy_info_t *) ppi;
+
+ if (ISLCNPHY(pi))
+ wlc_lcnphy_deaf_mode(pi, TRUE);
+ else if (ISNPHY(pi))
+ wlc_nphy_deaf_mode(pi, TRUE);
+ else {
+ ASSERT(0);
+ }
+}
+
+void wlc_phy_watchdog(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ bool delay_phy_cal = FALSE;
+ pi->sh->now++;
+
+ if (!pi->watchdog_override)
+ return;
+
+ if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) {
+ wlc_phy_noise_sample_request((wlc_phy_t *) pi,
+ PHY_NOISE_SAMPLE_MON,
+ CHSPEC_CHANNEL(pi->
+ radio_chanspec));
+ }
+
+ if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) {
+ pi->phynoise_state = 0;
+ }
+
+ if ((!pi->phycal_txpower) ||
+ ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
+
+ if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) {
+ pi->phycal_txpower = pi->sh->now;
+ }
+ }
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+ || ASSOC_INPROG_PHY(pi)))
+ return;
+
+ if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
+
+ if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
+ (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
+ ((pi->sh->now - pi->nphy_perical_last) >=
+ pi->sh->glacial_timer))
+ wlc_phy_cal_perical((wlc_phy_t *) pi,
+ PHY_PERICAL_WATCHDOG);
+
+ wlc_phy_txpwr_papd_cal_nphy(pi);
+ }
+
+ if (ISLCNPHY(pi)) {
+ if (pi->phy_forcecal ||
+ ((pi->sh->now - pi->phy_lastcal) >=
+ pi->sh->glacial_timer)) {
+ if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
+ wlc_lcnphy_calib_modes(pi,
+ LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+ if (!
+ (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+ || ASSOC_INPROG_PHY(pi)
+ || pi->carrier_suppr_disable
+ || pi->pkteng_in_progress || pi->disable_percal))
+ wlc_lcnphy_calib_modes(pi,
+ PHY_PERICAL_WATCHDOG);
+ }
+ }
+}
+
+void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ uint i;
+ uint k;
+
+ for (i = 0; i < MA_WINDOW_SZ; i++) {
+ pi->sh->phy_noise_window[i] = (int8) (rssi & 0xff);
+ }
+ if (ISLCNPHY(pi)) {
+ for (i = 0; i < MA_WINDOW_SZ; i++)
+ pi->sh->phy_noise_window[i] =
+ PHY_NOISE_FIXED_VAL_LCNPHY;
+ }
+ pi->sh->phy_noise_index = 0;
+
+ for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
+ for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
+ pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
+ }
+ pi->nphy_noise_index = 0;
+}
+
+void
+wlc_phy_papd_decode_epsilon(uint32 epsilon, int32 *eps_real, int32 *eps_imag)
+{
+ *eps_imag = (epsilon >> 13);
+ if (*eps_imag > 0xfff)
+ *eps_imag -= 0x2000;
+
+ *eps_real = (epsilon & 0x1fff);
+ if (*eps_real > 0xfff)
+ *eps_real -= 0x2000;
+}
+
+static const fixed AtanTbl[] = {
+ 2949120,
+ 1740967,
+ 919879,
+ 466945,
+ 234379,
+ 117304,
+ 58666,
+ 29335,
+ 14668,
+ 7334,
+ 3667,
+ 1833,
+ 917,
+ 458,
+ 229,
+ 115,
+ 57,
+ 29
+};
+
+void wlc_phy_cordic(fixed theta, cint32 *val)
+{
+ fixed angle, valtmp;
+ unsigned iter;
+ int signx = 1;
+ int signtheta;
+
+ val[0].i = CORDIC_AG;
+ val[0].q = 0;
+ angle = 0;
+
+ signtheta = (theta < 0) ? -1 : 1;
+ theta =
+ ((theta + FIXED(180) * signtheta) % FIXED(360)) -
+ FIXED(180) * signtheta;
+
+ if (FLOAT(theta) > 90) {
+ theta -= FIXED(180);
+ signx = -1;
+ } else if (FLOAT(theta) < -90) {
+ theta += FIXED(180);
+ signx = -1;
+ }
+
+ for (iter = 0; iter < CORDIC_NI; iter++) {
+ if (theta > angle) {
+ valtmp = val[0].i - (val[0].q >> iter);
+ val[0].q = (val[0].i >> iter) + val[0].q;
+ val[0].i = valtmp;
+ angle += AtanTbl[iter];
+ } else {
+ valtmp = val[0].i + (val[0].q >> iter);
+ val[0].q = -(val[0].i >> iter) + val[0].q;
+ val[0].i = valtmp;
+ angle -= AtanTbl[iter];
+ }
+ }
+
+ val[0].i = val[0].i * signx;
+ val[0].q = val[0].q * signx;
+}
+
+void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi)
+{
+ wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+
+ pi->cal_type_override = PHY_PERICAL_AUTO;
+ pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+ pi->mphase_txcal_cmdidx = 0;
+}
+
+static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay)
+{
+
+ if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
+ (pi->nphy_perical != PHY_PERICAL_MANUAL))
+ return;
+
+ wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+
+ pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+ wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+}
+
+void wlc_phy_cal_perical(wlc_phy_t *pih, uint8 reason)
+{
+ int16 nphy_currtemp = 0;
+ int16 delta_temp = 0;
+ bool do_periodic_cal = TRUE;
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ if (!ISNPHY(pi))
+ return;
+
+ if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
+ (pi->nphy_perical == PHY_PERICAL_MANUAL))
+ return;
+
+ switch (reason) {
+ case PHY_PERICAL_DRIVERUP:
+ break;
+
+ case PHY_PERICAL_PHYINIT:
+ if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+ if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+ wlc_phy_cal_perical_mphase_reset(pi);
+ }
+ wlc_phy_cal_perical_mphase_schedule(pi,
+ PHY_PERICAL_INIT_DELAY);
+ }
+ break;
+
+ case PHY_PERICAL_JOIN_BSS:
+ case PHY_PERICAL_START_IBSS:
+ case PHY_PERICAL_UP_BSS:
+ if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
+ PHY_PERICAL_MPHASE_PENDING(pi)) {
+ wlc_phy_cal_perical_mphase_reset(pi);
+ }
+
+ pi->first_cal_after_assoc = TRUE;
+
+ pi->cal_type_override = PHY_PERICAL_FULL;
+
+ if (pi->phycal_tempdelta) {
+ pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
+ }
+ wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
+ break;
+
+ case PHY_PERICAL_WATCHDOG:
+ if (pi->phycal_tempdelta) {
+ nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+ delta_temp =
+ (nphy_currtemp > pi->nphy_lastcal_temp) ?
+ nphy_currtemp - pi->nphy_lastcal_temp :
+ pi->nphy_lastcal_temp - nphy_currtemp;
+
+ if ((delta_temp < (int16) pi->phycal_tempdelta) &&
+ (pi->nphy_txiqlocal_chanspec ==
+ pi->radio_chanspec)) {
+ do_periodic_cal = FALSE;
+ } else {
+ pi->nphy_lastcal_temp = nphy_currtemp;
+ }
+ }
+
+ if (do_periodic_cal) {
+
+ if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+
+ if (!PHY_PERICAL_MPHASE_PENDING(pi))
+ wlc_phy_cal_perical_mphase_schedule(pi,
+ PHY_PERICAL_WDOG_DELAY);
+ } else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
+ wlc_phy_cal_perical_nphy_run(pi,
+ PHY_PERICAL_AUTO);
+ else {
+ ASSERT(0);
+ }
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi)
+{
+ pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+ pi->mphase_txcal_cmdidx = 0;
+}
+
+uint8 wlc_phy_nbits(int32 value)
+{
+ int32 abs_val;
+ uint8 nbits = 0;
+
+ abs_val = ABS(value);
+ while ((abs_val >> nbits) > 0)
+ nbits++;
+
+ return nbits;
+}
+
+uint32 wlc_phy_sqrt_int(uint32 value)
+{
+ uint32 root = 0, shift = 0;
+
+ for (shift = 0; shift < 32; shift += 2) {
+ if (((0x40000000 >> shift) + root) <= value) {
+ value -= ((0x40000000 >> shift) + root);
+ root = (root >> 1) | (0x40000000 >> shift);
+ } else {
+ root = root >> 1;
+ }
+ }
+
+ if (root < value)
+ ++root;
+
+ return root;
+}
+
+void wlc_phy_stf_chain_init(wlc_phy_t *pih, uint8 txchain, uint8 rxchain)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->sh->hw_phytxchain = txchain;
+ pi->sh->hw_phyrxchain = rxchain;
+ pi->sh->phytxchain = txchain;
+ pi->sh->phyrxchain = rxchain;
+ pi->pubpi.phy_corenum = (uint8) PHY_BITSCNT(pi->sh->phyrxchain);
+}
+
+void wlc_phy_stf_chain_set(wlc_phy_t *pih, uint8 txchain, uint8 rxchain)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ pi->sh->phytxchain = txchain;
+
+ if (ISNPHY(pi)) {
+ wlc_phy_rxcore_setstate_nphy(pih, rxchain);
+ }
+ pi->pubpi.phy_corenum = (uint8) PHY_BITSCNT(pi->sh->phyrxchain);
+}
+
+void wlc_phy_stf_chain_get(wlc_phy_t *pih, uint8 *txchain, uint8 *rxchain)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ *txchain = pi->sh->phytxchain;
+ *rxchain = pi->sh->phyrxchain;
+}
+
+uint8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih)
+{
+ int16 nphy_currtemp;
+ uint8 active_bitmap;
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
+
+ if (!pi->watchdog_override)
+ return active_bitmap;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+ wlapi_enable_mac(pi->sh->physhim);
+
+ if (!pi->phy_txcore_heatedup) {
+ if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
+ active_bitmap &= 0xFD;
+ pi->phy_txcore_heatedup = TRUE;
+ }
+ } else {
+ if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
+ active_bitmap |= 0x2;
+ pi->phy_txcore_heatedup = FALSE;
+ }
+ }
+ }
+
+ return active_bitmap;
+}
+
+int8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ uint8 siso_mcs_id, cdd_mcs_id;
+
+ siso_mcs_id =
+ (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
+ TXP_FIRST_MCS_20_SISO;
+ cdd_mcs_id =
+ (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
+ TXP_FIRST_MCS_20_CDD;
+
+ if (pi->tx_power_target[siso_mcs_id] >
+ (pi->tx_power_target[cdd_mcs_id] + 12))
+ return PHY_TXC1_MODE_SISO;
+ else
+ return PHY_TXC1_MODE_CDD;
+}
+
+const uint8 *wlc_phy_get_ofdm_rate_lookup(void)
+{
+ return ofdm_rate_lookup;
+}
+
+void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode)
+{
+ if ((CHIPID(pi->sh->chip) == BCM4313_CHIP_ID) &&
+ (pi->sh->boardflags & BFL_FEM)) {
+ if (mode) {
+ uint16 txant = 0;
+ txant = wlapi_bmac_get_txant(pi->sh->physhim);
+ if (txant == 1) {
+ mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
+
+ }
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiocontrol), ~0x0,
+ 0x0);
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpioout), 0x40, 0x40);
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpioouten), 0x40,
+ 0x40);
+ } else {
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
+
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpioout), 0x40, 0x00);
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpioouten), 0x40, 0x0);
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiocontrol), ~0x0,
+ 0x40);
+ }
+ }
+}
+
+static int8
+wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, uint32 band,
+ uint8 rate)
+{
+ int8 offset = 0;
+
+ if (!pi->user_txpwr_at_rfport)
+ return offset;
+ return offset;
+}
+
+static int8 wlc_phy_env_measure_vbat(phy_info_t *pi)
+{
+ if (ISLCNPHY(pi))
+ return wlc_lcnphy_vbatsense(pi, 0);
+ else
+ return 0;
+}
+
+static int8 wlc_phy_env_measure_temperature(phy_info_t *pi)
+{
+ if (ISLCNPHY(pi))
+ return wlc_lcnphy_tempsense_degree(pi, 0);
+ else
+ return 0;
+}
+
+static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, uint32 band)
+{
+ uint8 i;
+ int8 temp, vbat;
+
+ for (i = 0; i < TXP_NUM_RATES; i++)
+ pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+
+ vbat = wlc_phy_env_measure_vbat(pi);
+ temp = wlc_phy_env_measure_temperature(pi);
+
+}
+
+void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc)
+{
+ return;
+}
+
+void
+wlc_phy_get_pwrdet_offsets(phy_info_t *pi, int8 *cckoffset, int8 *ofdmoffset)
+{
+ *cckoffset = 0;
+ *ofdmoffset = 0;
+}
+
+uint32 wlc_phy_qdiv_roundup(uint32 dividend, uint32 divisor, uint8 precision)
+{
+ uint32 quotient, remainder, roundup, rbit;
+
+ ASSERT(divisor);
+
+ quotient = dividend / divisor;
+ remainder = dividend % divisor;
+ rbit = divisor & 1;
+ roundup = (divisor >> 1) + rbit;
+
+ while (precision--) {
+ quotient <<= 1;
+ if (remainder >= roundup) {
+ quotient++;
+ remainder = ((remainder - roundup) << 1) + rbit;
+ } else {
+ remainder <<= 1;
+ }
+ }
+
+ if (remainder >= roundup)
+ quotient++;
+
+ return quotient;
+}
+
+int8 wlc_phy_upd_rssi_offset(phy_info_t *pi, int8 rssi, chanspec_t chanspec)
+{
+
+ return rssi;
+}
+
+bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ if (ISNPHY(pi))
+ return wlc_phy_n_txpower_ipa_ison(pi);
+ else
+ return 0;
+}
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/phy/wlc_phy_hal.h
new file mode 100644
index 000000000000..5a8b6aebc4d1
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_hal.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_phy_h_
+#define _wlc_phy_h_
+
+#include <typedefs.h>
+#include <wlioctl.h>
+#include <siutils.h>
+#include <d11.h>
+#include <wlc_phy_shim.h>
+
+#define IDCODE_VER_MASK 0x0000000f
+#define IDCODE_VER_SHIFT 0
+#define IDCODE_MFG_MASK 0x00000fff
+#define IDCODE_MFG_SHIFT 0
+#define IDCODE_ID_MASK 0x0ffff000
+#define IDCODE_ID_SHIFT 12
+#define IDCODE_REV_MASK 0xf0000000
+#define IDCODE_REV_SHIFT 28
+
+#define NORADIO_ID 0xe4f5
+#define NORADIO_IDCODE 0x4e4f5246
+
+#define BCM2055_ID 0x2055
+#define BCM2055_IDCODE 0x02055000
+#define BCM2055A0_IDCODE 0x1205517f
+
+#define BCM2056_ID 0x2056
+#define BCM2056_IDCODE 0x02056000
+#define BCM2056A0_IDCODE 0x1205617f
+
+#define BCM2057_ID 0x2057
+#define BCM2057_IDCODE 0x02057000
+#define BCM2057A0_IDCODE 0x1205717f
+
+#define BCM2064_ID 0x2064
+#define BCM2064_IDCODE 0x02064000
+#define BCM2064A0_IDCODE 0x0206417f
+
+#define PHY_TPC_HW_OFF FALSE
+#define PHY_TPC_HW_ON TRUE
+
+#define PHY_PERICAL_DRIVERUP 1
+#define PHY_PERICAL_WATCHDOG 2
+#define PHY_PERICAL_PHYINIT 3
+#define PHY_PERICAL_JOIN_BSS 4
+#define PHY_PERICAL_START_IBSS 5
+#define PHY_PERICAL_UP_BSS 6
+#define PHY_PERICAL_CHAN 7
+#define PHY_FULLCAL 8
+
+#define PHY_PERICAL_DISABLE 0
+#define PHY_PERICAL_SPHASE 1
+#define PHY_PERICAL_MPHASE 2
+#define PHY_PERICAL_MANUAL 3
+
+#define PHY_HOLD_FOR_ASSOC 1
+#define PHY_HOLD_FOR_SCAN 2
+#define PHY_HOLD_FOR_RM 4
+#define PHY_HOLD_FOR_PLT 8
+#define PHY_HOLD_FOR_MUTE 16
+#define PHY_HOLD_FOR_NOT_ASSOC 0x20
+
+#define PHY_MUTE_FOR_PREISM 1
+#define PHY_MUTE_ALL 0xffffffff
+
+#define PHY_NOISE_FIXED_VAL (-95)
+#define PHY_NOISE_FIXED_VAL_NPHY (-92)
+#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
+
+#define PHY_MODE_CAL 0x0002
+#define PHY_MODE_NOISEM 0x0004
+
+#define WLC_TXPWR_DB_FACTOR 4
+
+#define WLC_NUM_RATES_CCK 4
+#define WLC_NUM_RATES_OFDM 8
+#define WLC_NUM_RATES_MCS_1_STREAM 8
+#define WLC_NUM_RATES_MCS_2_STREAM 8
+#define WLC_NUM_RATES_MCS_3_STREAM 8
+#define WLC_NUM_RATES_MCS_4_STREAM 8
+typedef struct txpwr_limits {
+ uint8 cck[WLC_NUM_RATES_CCK];
+ uint8 ofdm[WLC_NUM_RATES_OFDM];
+
+ uint8 ofdm_cdd[WLC_NUM_RATES_OFDM];
+
+ uint8 ofdm_40_siso[WLC_NUM_RATES_OFDM];
+ uint8 ofdm_40_cdd[WLC_NUM_RATES_OFDM];
+
+ uint8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+
+ uint8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+ uint8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+ uint8 mcs32;
+} txpwr_limits_t;
+
+typedef struct {
+ uint8 vec[MAXCHANNEL / NBBY];
+} chanvec_t;
+
+struct rpc_info;
+typedef struct shared_phy shared_phy_t;
+
+struct phy_pub;
+
+#ifdef WLC_HIGH_ONLY
+typedef struct wlc_rpc_phy wlc_phy_t;
+#else
+typedef struct phy_pub wlc_phy_t;
+#endif
+
+typedef struct shared_phy_params {
+ void *osh;
+ si_t *sih;
+ void *physhim;
+ uint unit;
+ uint corerev;
+ uint bustype;
+ uint buscorerev;
+ char *vars;
+ uint16 vid;
+ uint16 did;
+ uint chip;
+ uint chiprev;
+ uint chippkg;
+ uint sromrev;
+ uint boardtype;
+ uint boardrev;
+ uint boardvendor;
+ uint32 boardflags;
+ uint32 boardflags2;
+} shared_phy_params_t;
+
+#ifdef WLC_LOW
+
+extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp);
+extern void wlc_phy_shared_detach(shared_phy_t *phy_sh);
+extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+ char *vars);
+extern void wlc_phy_detach(wlc_phy_t *ppi);
+
+extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, uint16 *phytype,
+ uint16 *phyrev, uint16 *radioid,
+ uint16 *radiover);
+extern bool wlc_phy_get_encore(wlc_phy_t *pih);
+extern uint32 wlc_phy_get_coreflags(wlc_phy_t *pih);
+
+extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate);
+extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate);
+extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec);
+extern void wlc_phy_watchdog(wlc_phy_t *ppi);
+extern int wlc_phy_down(wlc_phy_t *ppi);
+extern uint32 wlc_phy_clk_bwbits(wlc_phy_t *pih);
+extern void wlc_phy_cal_init(wlc_phy_t *ppi);
+extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init);
+
+extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec);
+extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi);
+extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch);
+extern uint16 wlc_phy_bw_state_get(wlc_phy_t *ppi);
+extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, uint16 bw);
+
+extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx);
+extern void wlc_phy_por_inform(wlc_phy_t *ppi);
+extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi);
+extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi);
+
+extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag);
+
+extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on);
+extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on);
+
+#endif /* WLC_LOW */
+
+extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi);
+
+extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi,
+ bool wide_filter);
+extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band,
+ chanvec_t *channels);
+extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band);
+
+extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan,
+ uint8 *_min_, uint8 *_max_, int rate);
+extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan,
+ uint8 *_max_, uint8 *_min_);
+extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, int32 *,
+ int32 *, uint32 *);
+extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *,
+ chanspec_t chanspec);
+extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override);
+extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override);
+extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *);
+extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi);
+extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl);
+extern uint8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi);
+extern uint8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi);
+extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih);
+
+extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, uint8 txchain,
+ uint8 rxchain);
+extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, uint8 txchain,
+ uint8 rxchain);
+extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, uint8 *txchain,
+ uint8 *rxchain);
+extern uint8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih);
+extern int8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec);
+extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val);
+
+extern void wlc_phy_cal_perical(wlc_phy_t *ppi, uint8 reason);
+extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi);
+extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock);
+extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi);
+
+extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, uint8 val);
+extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, uint8 *pval);
+extern void wlc_phy_clear_tssi(wlc_phy_t *ppi);
+extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val);
+extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags);
+
+extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, uint8 antsel_type);
+
+extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power,
+ uint channel);
+
+extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal);
+extern bool wlc_phy_test_ison(wlc_phy_t *ppi);
+extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, uint8 txpwr_percent);
+extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war);
+extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt);
+extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, uint32 machwcap);
+
+extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end);
+
+extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi);
+extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi);
+
+extern const uint8 *wlc_phy_get_ofdm_rate_lookup(void);
+
+extern int8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi,
+ uint8 mcs_offset);
+extern int8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, uint8 tbl_offset);
+#endif /* _wlc_phy_h_ */
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_int.h b/drivers/staging/brcm80211/phy/wlc_phy_int.h
new file mode 100644
index 000000000000..d5e61c407540
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_int.h
@@ -0,0 +1,1229 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_phy_int_h_
+#define _wlc_phy_int_h_
+
+#include <typedefs.h>
+#include <bcmutils.h>
+
+#include <bcmsrom_fmt.h>
+#include <wlc_phy_hal.h>
+
+#define PHYHAL_ERROR 0x0001
+#define PHYHAL_TRACE 0x0002
+#define PHYHAL_INFORM 0x0004
+
+extern uint32 phyhal_msg_level;
+
+#define PHY_INFORM_ON() (phyhal_msg_level & PHYHAL_INFORM)
+#define PHY_THERMAL_ON() (phyhal_msg_level & PHYHAL_THERMAL)
+#define PHY_CAL_ON() (phyhal_msg_level & PHYHAL_CAL)
+
+#ifdef BOARD_TYPE
+#define BOARDTYPE(_type) BOARD_TYPE
+#else
+#define BOARDTYPE(_type) _type
+#endif
+
+#define LCNXN_BASEREV 16
+
+struct wlc_hw_info;
+typedef struct phy_info phy_info_t;
+typedef void (*initfn_t) (phy_info_t *);
+typedef void (*chansetfn_t) (phy_info_t *, chanspec_t);
+typedef int (*longtrnfn_t) (phy_info_t *, int);
+typedef void (*txiqccgetfn_t) (phy_info_t *, uint16 *, uint16 *);
+typedef void (*txiqccsetfn_t) (phy_info_t *, uint16, uint16);
+typedef uint16(*txloccgetfn_t) (phy_info_t *);
+typedef void (*radioloftgetfn_t) (phy_info_t *, uint8 *, uint8 *, uint8 *,
+ uint8 *);
+typedef int32(*rxsigpwrfn_t) (phy_info_t *, int32);
+typedef void (*detachfn_t) (phy_info_t *);
+
+#undef ISNPHY
+#undef ISLCNPHY
+#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
+#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
+
+#define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi))
+
+#define IS20MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_20)
+#define IS40MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_40)
+
+#define PHY_GET_RFATTN(rfgain) ((rfgain) & 0x0f)
+#define PHY_GET_PADMIX(rfgain) (((rfgain) & 0x10) >> 4)
+#define PHY_GET_RFGAINID(rfattn, padmix, width) ((rfattn) + ((padmix)*(width)))
+#define PHY_SAT(x, n) ((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
+ ((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
+#define PHY_SHIFT_ROUND(x, n) ((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
+#define PHY_HW_ROUND(x, s) ((x >> s) + ((x >> (s-1)) & (s != 0)))
+
+#define CH_5G_GROUP 3
+#define A_LOW_CHANS 0
+#define A_MID_CHANS 1
+#define A_HIGH_CHANS 2
+#define CH_2G_GROUP 1
+#define G_ALL_CHANS 0
+
+#define FIRST_REF5_CHANNUM 149
+#define LAST_REF5_CHANNUM 165
+#define FIRST_5G_CHAN 14
+#define LAST_5G_CHAN 50
+#define FIRST_MID_5G_CHAN 14
+#define LAST_MID_5G_CHAN 35
+#define FIRST_HIGH_5G_CHAN 36
+#define LAST_HIGH_5G_CHAN 41
+#define FIRST_LOW_5G_CHAN 42
+#define LAST_LOW_5G_CHAN 50
+
+#define BASE_LOW_5G_CHAN 4900
+#define BASE_MID_5G_CHAN 5100
+#define BASE_HIGH_5G_CHAN 5500
+
+#define CHAN5G_FREQ(chan) (5000 + chan*5)
+#define CHAN2G_FREQ(chan) (2407 + chan*5)
+
+#define TXP_FIRST_CCK 0
+#define TXP_LAST_CCK 3
+#define TXP_FIRST_OFDM 4
+#define TXP_LAST_OFDM 11
+#define TXP_FIRST_OFDM_20_CDD 12
+#define TXP_LAST_OFDM_20_CDD 19
+#define TXP_FIRST_MCS_20_SISO 20
+#define TXP_LAST_MCS_20_SISO 27
+#define TXP_FIRST_MCS_20_CDD 28
+#define TXP_LAST_MCS_20_CDD 35
+#define TXP_FIRST_MCS_20_STBC 36
+#define TXP_LAST_MCS_20_STBC 43
+#define TXP_FIRST_MCS_20_SDM 44
+#define TXP_LAST_MCS_20_SDM 51
+#define TXP_FIRST_OFDM_40_SISO 52
+#define TXP_LAST_OFDM_40_SISO 59
+#define TXP_FIRST_OFDM_40_CDD 60
+#define TXP_LAST_OFDM_40_CDD 67
+#define TXP_FIRST_MCS_40_SISO 68
+#define TXP_LAST_MCS_40_SISO 75
+#define TXP_FIRST_MCS_40_CDD 76
+#define TXP_LAST_MCS_40_CDD 83
+#define TXP_FIRST_MCS_40_STBC 84
+#define TXP_LAST_MCS_40_STBC 91
+#define TXP_FIRST_MCS_40_SDM 92
+#define TXP_LAST_MCS_40_SDM 99
+#define TXP_MCS_32 100
+#define TXP_NUM_RATES 101
+#define ADJ_PWR_TBL_LEN 84
+
+#define TXP_FIRST_SISO_MCS_20 20
+#define TXP_LAST_SISO_MCS_20 27
+
+#define PHY_CORE_NUM_1 1
+#define PHY_CORE_NUM_2 2
+#define PHY_CORE_NUM_3 3
+#define PHY_CORE_NUM_4 4
+#define PHY_CORE_MAX PHY_CORE_NUM_4
+#define PHY_CORE_0 0
+#define PHY_CORE_1 1
+#define PHY_CORE_2 2
+#define PHY_CORE_3 3
+
+#define MA_WINDOW_SZ 8
+
+#define PHY_NOISE_SAMPLE_MON 1
+#define PHY_NOISE_SAMPLE_EXTERNAL 2
+#define PHY_NOISE_WINDOW_SZ 16
+#define PHY_NOISE_GLITCH_INIT_MA 10
+#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
+#define PHY_NOISE_STATE_MON 0x1
+#define PHY_NOISE_STATE_EXTERNAL 0x2
+#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY 10
+#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE 9
+
+#define PHY_NOISE_OFFSETFACT_4322 (-103)
+#define PHY_NOISE_MA_WINDOW_SZ 2
+
+#define PHY_RSSI_TABLE_SIZE 64
+#define RSSI_ANT_MERGE_MAX 0
+#define RSSI_ANT_MERGE_MIN 1
+#define RSSI_ANT_MERGE_AVG 2
+
+#define PHY_TSSI_TABLE_SIZE 64
+#define APHY_TSSI_TABLE_SIZE 256
+#define TX_GAIN_TABLE_LENGTH 64
+#define DEFAULT_11A_TXP_IDX 24
+#define NUM_TSSI_FRAMES 4
+#define NULL_TSSI 0x7f
+#define NULL_TSSI_W 0x7f7f
+
+#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
+
+#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
+
+#define PHY_TXPWR_MIN 10
+#define PHY_TXPWR_MIN_NPHY 8
+#define RADIOPWR_OVERRIDE_DEF (-1)
+
+#define PWRTBL_NUM_COEFF 3
+
+#define SPURAVOID_DISABLE 0
+#define SPURAVOID_AUTO 1
+#define SPURAVOID_FORCEON 2
+#define SPURAVOID_FORCEON2 3
+
+#define PHY_SW_TIMER_FAST 15
+#define PHY_SW_TIMER_SLOW 60
+#define PHY_SW_TIMER_GLACIAL 120
+
+#define PHY_PERICAL_AUTO 0
+#define PHY_PERICAL_FULL 1
+#define PHY_PERICAL_PARTIAL 2
+
+#define PHY_PERICAL_NODELAY 0
+#define PHY_PERICAL_INIT_DELAY 5
+#define PHY_PERICAL_ASSOC_DELAY 5
+#define PHY_PERICAL_WDOG_DELAY 5
+
+#define MPHASE_TXCAL_NUMCMDS 2
+#define PHY_PERICAL_MPHASE_PENDING(pi) (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
+
+enum {
+ MPHASE_CAL_STATE_IDLE = 0,
+ MPHASE_CAL_STATE_INIT = 1,
+ MPHASE_CAL_STATE_TXPHASE0,
+ MPHASE_CAL_STATE_TXPHASE1,
+ MPHASE_CAL_STATE_TXPHASE2,
+ MPHASE_CAL_STATE_TXPHASE3,
+ MPHASE_CAL_STATE_TXPHASE4,
+ MPHASE_CAL_STATE_TXPHASE5,
+ MPHASE_CAL_STATE_PAPDCAL,
+ MPHASE_CAL_STATE_RXCAL,
+ MPHASE_CAL_STATE_RSSICAL,
+ MPHASE_CAL_STATE_IDLETSSI
+};
+
+typedef enum {
+ CAL_FULL,
+ CAL_RECAL,
+ CAL_CURRECAL,
+ CAL_DIGCAL,
+ CAL_GCTRL,
+ CAL_SOFT,
+ CAL_DIGLO
+} phy_cal_mode_t;
+
+#define RDR_NTIERS 1
+#define RDR_TIER_SIZE 64
+#define RDR_LIST_SIZE (512/3)
+#define RDR_EPOCH_SIZE 40
+#define RDR_NANTENNAS 2
+#define RDR_NTIER_SIZE RDR_LIST_SIZE
+#define RDR_LP_BUFFER_SIZE 64
+#define LP_LEN_HIS_SIZE 10
+
+#define STATIC_NUM_RF 32
+#define STATIC_NUM_BB 9
+
+#define BB_MULT_MASK 0x0000ffff
+#define BB_MULT_VALID_MASK 0x80000000
+
+#define CORDIC_AG 39797
+#define CORDIC_NI 18
+#define FIXED(X) ((int32)((X) << 16))
+#define FLOAT(X) (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
+
+#define PHY_CHAIN_TX_DISABLE_TEMP 115
+#define PHY_HYSTERESIS_DELTATEMP 5
+
+#define PHY_BITSCNT(x) bcm_bitcount((uint8 *)&(x), sizeof(uint8))
+
+#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \
+ mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \
+ (value) << phy_type##_##reg_name##_##field##_##SHIFT);
+#define READ_PHY_REG(pi, phy_type, reg_name, field) \
+ ((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\
+ >> phy_type##_##reg_name##_##field##_##SHIFT)
+
+#define VALID_PHYTYPE(phytype) (((uint)phytype == PHY_TYPE_N) || \
+ ((uint)phytype == PHY_TYPE_LCN))
+
+#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \
+ (radioid == BCM2057_ID))
+#define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID)
+
+#define VALID_RADIO(pi, radioid) (\
+ (ISNPHY(pi) ? VALID_N_RADIO(radioid) : FALSE) || \
+ (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : FALSE))
+
+#define SCAN_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
+#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM))
+#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
+#define ASSOC_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
+#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
+#define PHY_MUTED(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
+#define PUB_NOT_ASSOC(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
+
+#if defined(EXT_CBALL)
+#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID)
+#else
+#define NORADIO_ENAB(pub) 0
+#endif
+
+#define PHY_LTRN_LIST_LEN 64
+extern uint16 ltrn_list[PHY_LTRN_LIST_LEN];
+
+typedef struct _phy_table_info {
+ uint table;
+ int q;
+ uint max;
+} phy_table_info_t;
+
+typedef struct phytbl_info {
+ const void *tbl_ptr;
+ uint32 tbl_len;
+ uint32 tbl_id;
+ uint32 tbl_offset;
+ uint32 tbl_width;
+} phytbl_info_t;
+
+typedef struct {
+ uint8 curr_home_channel;
+ uint16 crsminpwrthld_40_stored;
+ uint16 crsminpwrthld_20L_stored;
+ uint16 crsminpwrthld_20U_stored;
+ uint16 init_gain_code_core1_stored;
+ uint16 init_gain_code_core2_stored;
+ uint16 init_gain_codeb_core1_stored;
+ uint16 init_gain_codeb_core2_stored;
+ uint16 init_gain_table_stored[4];
+
+ uint16 clip1_hi_gain_code_core1_stored;
+ uint16 clip1_hi_gain_code_core2_stored;
+ uint16 clip1_hi_gain_codeb_core1_stored;
+ uint16 clip1_hi_gain_codeb_core2_stored;
+ uint16 nb_clip_thresh_core1_stored;
+ uint16 nb_clip_thresh_core2_stored;
+ uint16 init_ofdmlna2gainchange_stored[4];
+ uint16 init_ccklna2gainchange_stored[4];
+ uint16 clip1_lo_gain_code_core1_stored;
+ uint16 clip1_lo_gain_code_core2_stored;
+ uint16 clip1_lo_gain_codeb_core1_stored;
+ uint16 clip1_lo_gain_codeb_core2_stored;
+ uint16 w1_clip_thresh_core1_stored;
+ uint16 w1_clip_thresh_core2_stored;
+ uint16 radio_2056_core1_rssi_gain_stored;
+ uint16 radio_2056_core2_rssi_gain_stored;
+ uint16 energy_drop_timeout_len_stored;
+
+ uint16 ed_crs40_assertthld0_stored;
+ uint16 ed_crs40_assertthld1_stored;
+ uint16 ed_crs40_deassertthld0_stored;
+ uint16 ed_crs40_deassertthld1_stored;
+ uint16 ed_crs20L_assertthld0_stored;
+ uint16 ed_crs20L_assertthld1_stored;
+ uint16 ed_crs20L_deassertthld0_stored;
+ uint16 ed_crs20L_deassertthld1_stored;
+ uint16 ed_crs20U_assertthld0_stored;
+ uint16 ed_crs20U_assertthld1_stored;
+ uint16 ed_crs20U_deassertthld0_stored;
+ uint16 ed_crs20U_deassertthld1_stored;
+
+ uint16 badplcp_ma;
+ uint16 badplcp_ma_previous;
+ uint16 badplcp_ma_total;
+ uint16 badplcp_ma_list[MA_WINDOW_SZ];
+ int badplcp_ma_index;
+ int16 pre_badplcp_cnt;
+ int16 bphy_pre_badplcp_cnt;
+
+ uint16 init_gain_core1;
+ uint16 init_gain_core2;
+ uint16 init_gainb_core1;
+ uint16 init_gainb_core2;
+ uint16 init_gain_rfseq[4];
+
+ uint16 crsminpwr0;
+ uint16 crsminpwrl0;
+ uint16 crsminpwru0;
+
+ int16 crsminpwr_index;
+
+ uint16 radio_2057_core1_rssi_wb1a_gc_stored;
+ uint16 radio_2057_core2_rssi_wb1a_gc_stored;
+ uint16 radio_2057_core1_rssi_wb1g_gc_stored;
+ uint16 radio_2057_core2_rssi_wb1g_gc_stored;
+ uint16 radio_2057_core1_rssi_wb2_gc_stored;
+ uint16 radio_2057_core2_rssi_wb2_gc_stored;
+ uint16 radio_2057_core1_rssi_nb_gc_stored;
+ uint16 radio_2057_core2_rssi_nb_gc_stored;
+
+} interference_info_t;
+
+typedef struct {
+ uint16 rc_cal_ovr;
+ uint16 phycrsth1;
+ uint16 phycrsth2;
+ uint16 init_n1p1_gain;
+ uint16 p1_p2_gain;
+ uint16 n1_n2_gain;
+ uint16 n1_p1_gain;
+ uint16 div_search_gain;
+ uint16 div_p1_p2_gain;
+ uint16 div_search_gn_change;
+ uint16 table_7_2;
+ uint16 table_7_3;
+ uint16 cckshbits_gnref;
+ uint16 clip_thresh;
+ uint16 clip2_thresh;
+ uint16 clip3_thresh;
+ uint16 clip_p2_thresh;
+ uint16 clip_pwdn_thresh;
+ uint16 clip_n1p1_thresh;
+ uint16 clip_n1_pwdn_thresh;
+ uint16 bbconfig;
+ uint16 cthr_sthr_shdin;
+ uint16 energy;
+ uint16 clip_p1_p2_thresh;
+ uint16 threshold;
+ uint16 reg15;
+ uint16 reg16;
+ uint16 reg17;
+ uint16 div_srch_idx;
+ uint16 div_srch_p1_p2;
+ uint16 div_srch_gn_back;
+ uint16 ant_dwell;
+ uint16 ant_wr_settle;
+} aci_save_gphy_t;
+
+typedef struct _lo_complex_t {
+ int8 i;
+ int8 q;
+} lo_complex_abgphy_info_t;
+
+typedef struct _nphy_iq_comp {
+ int16 a0;
+ int16 b0;
+ int16 a1;
+ int16 b1;
+} nphy_iq_comp_t;
+
+typedef struct _nphy_txpwrindex {
+ int8 index;
+ int8 index_internal;
+ int8 index_internal_save;
+ uint16 AfectrlOverride;
+ uint16 AfeCtrlDacGain;
+ uint16 rad_gain;
+ uint8 bbmult;
+ uint16 iqcomp_a;
+ uint16 iqcomp_b;
+ uint16 locomp;
+} phy_txpwrindex_t;
+
+typedef struct {
+
+ uint16 txcal_coeffs_2G[8];
+ uint16 txcal_radio_regs_2G[8];
+ nphy_iq_comp_t rxcal_coeffs_2G;
+
+ uint16 txcal_coeffs_5G[8];
+ uint16 txcal_radio_regs_5G[8];
+ nphy_iq_comp_t rxcal_coeffs_5G;
+} txiqcal_cache_t;
+
+typedef struct _nphy_pwrctrl {
+ int8 max_pwr_2g;
+ int8 idle_targ_2g;
+ int16 pwrdet_2g_a1;
+ int16 pwrdet_2g_b0;
+ int16 pwrdet_2g_b1;
+ int8 max_pwr_5gm;
+ int8 idle_targ_5gm;
+ int8 max_pwr_5gh;
+ int8 max_pwr_5gl;
+ int16 pwrdet_5gm_a1;
+ int16 pwrdet_5gm_b0;
+ int16 pwrdet_5gm_b1;
+ int16 pwrdet_5gl_a1;
+ int16 pwrdet_5gl_b0;
+ int16 pwrdet_5gl_b1;
+ int16 pwrdet_5gh_a1;
+ int16 pwrdet_5gh_b0;
+ int16 pwrdet_5gh_b1;
+ int8 idle_targ_5gl;
+ int8 idle_targ_5gh;
+ int8 idle_tssi_2g;
+ int8 idle_tssi_5g;
+ int8 idle_tssi;
+ int16 a1;
+ int16 b0;
+ int16 b1;
+} phy_pwrctrl_t;
+
+typedef struct _nphy_txgains {
+ uint16 txlpf[2];
+ uint16 txgm[2];
+ uint16 pga[2];
+ uint16 pad[2];
+ uint16 ipa[2];
+} nphy_txgains_t;
+
+#define PHY_NOISEVAR_BUFSIZE 10
+
+typedef struct _nphy_noisevar_buf {
+ int bufcount;
+ int tone_id[PHY_NOISEVAR_BUFSIZE];
+ uint32 noise_vars[PHY_NOISEVAR_BUFSIZE];
+ uint32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
+} phy_noisevar_buf_t;
+
+typedef struct {
+ uint16 rssical_radio_regs_2G[2];
+ uint16 rssical_phyregs_2G[12];
+
+ uint16 rssical_radio_regs_5G[2];
+ uint16 rssical_phyregs_5G[12];
+} rssical_cache_t;
+
+typedef struct {
+
+ uint16 txiqlocal_a;
+ uint16 txiqlocal_b;
+ uint16 txiqlocal_didq;
+ uint8 txiqlocal_ei0;
+ uint8 txiqlocal_eq0;
+ uint8 txiqlocal_fi0;
+ uint8 txiqlocal_fq0;
+
+ uint16 txiqlocal_bestcoeffs[11];
+ uint16 txiqlocal_bestcoeffs_valid;
+
+ uint32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
+ uint16 analog_gain_ref;
+ uint16 lut_begin;
+ uint16 lut_end;
+ uint16 lut_step;
+ uint16 rxcompdbm;
+ uint16 papdctrl;
+ uint16 sslpnCalibClkEnCtrl;
+
+ uint16 rxiqcal_coeff_a0;
+ uint16 rxiqcal_coeff_b0;
+} lcnphy_cal_results_t;
+
+struct shared_phy {
+ struct phy_info *phy_head;
+ uint unit;
+ osl_t *osh;
+ si_t *sih;
+ void *physhim;
+ uint corerev;
+ uint32 machwcap;
+ bool up;
+ bool clk;
+ uint now;
+ uint16 vid;
+ uint16 did;
+ uint chip;
+ uint chiprev;
+ uint chippkg;
+ uint sromrev;
+ uint boardtype;
+ uint boardrev;
+ uint boardvendor;
+ uint32 boardflags;
+ uint32 boardflags2;
+ uint bustype;
+ uint buscorerev;
+ uint fast_timer;
+ uint slow_timer;
+ uint glacial_timer;
+ uint8 rx_antdiv;
+ int8 phy_noise_window[MA_WINDOW_SZ];
+ uint phy_noise_index;
+ uint8 hw_phytxchain;
+ uint8 hw_phyrxchain;
+ uint8 phytxchain;
+ uint8 phyrxchain;
+ uint8 rssi_mode;
+ bool _rifs_phy;
+};
+
+struct phy_pub {
+ uint phy_type;
+ uint phy_rev;
+ uint8 phy_corenum;
+ uint16 radioid;
+ uint8 radiorev;
+ uint8 radiover;
+
+ uint coreflags;
+ uint ana_rev;
+ bool abgphy_encore;
+};
+
+struct phy_info_nphy;
+typedef struct phy_info_nphy phy_info_nphy_t;
+
+struct phy_info_lcnphy;
+typedef struct phy_info_lcnphy phy_info_lcnphy_t;
+
+struct phy_func_ptr {
+ initfn_t init;
+ initfn_t calinit;
+ chansetfn_t chanset;
+ initfn_t txpwrrecalc;
+ longtrnfn_t longtrn;
+ txiqccgetfn_t txiqccget;
+ txiqccsetfn_t txiqccset;
+ txloccgetfn_t txloccget;
+ radioloftgetfn_t radioloftget;
+ initfn_t carrsuppr;
+ rxsigpwrfn_t rxsigpwr;
+ detachfn_t detach;
+};
+typedef struct phy_func_ptr phy_func_ptr_t;
+
+struct phy_info {
+ wlc_phy_t pubpi_ro;
+ shared_phy_t *sh;
+ phy_func_ptr_t pi_fptr;
+ void *pi_ptr;
+
+ union {
+ phy_info_lcnphy_t *pi_lcnphy;
+ } u;
+ bool user_txpwr_at_rfport;
+
+ d11regs_t *regs;
+ struct phy_info *next;
+ char *vars;
+ wlc_phy_t pubpi;
+
+ bool do_initcal;
+ bool phytest_on;
+ bool ofdm_rateset_war;
+ bool bf_preempt_4306;
+ chanspec_t radio_chanspec;
+ uint8 antsel_type;
+ uint16 bw;
+ uint8 txpwr_percent;
+ bool phy_init_por;
+
+ bool init_in_progress;
+ bool initialized;
+ bool sbtml_gm;
+ uint refcnt;
+ bool watchdog_override;
+ uint8 phynoise_state;
+ uint phynoise_now;
+ int phynoise_chan_watchdog;
+ bool phynoise_polling;
+ bool disable_percal;
+ mbool measure_hold;
+
+ int16 txpa_2g[PWRTBL_NUM_COEFF];
+ int16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
+ int16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
+ int16 txpa_5g_low[PWRTBL_NUM_COEFF];
+ int16 txpa_5g_mid[PWRTBL_NUM_COEFF];
+ int16 txpa_5g_hi[PWRTBL_NUM_COEFF];
+
+ uint8 tx_srom_max_2g;
+ uint8 tx_srom_max_5g_low;
+ uint8 tx_srom_max_5g_mid;
+ uint8 tx_srom_max_5g_hi;
+ uint8 tx_srom_max_rate_2g[TXP_NUM_RATES];
+ uint8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
+ uint8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
+ uint8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
+ uint8 tx_user_target[TXP_NUM_RATES];
+ int8 tx_power_offset[TXP_NUM_RATES];
+ uint8 tx_power_target[TXP_NUM_RATES];
+
+ srom_fem_t srom_fem2g;
+ srom_fem_t srom_fem5g;
+
+ uint8 tx_power_max;
+ uint8 tx_power_max_rate_ind;
+ bool hwpwrctrl;
+ uint8 nphy_txpwrctrl;
+ int8 nphy_txrx_chain;
+ bool phy_5g_pwrgain;
+
+ uint16 phy_wreg;
+ uint16 phy_wreg_limit;
+
+ int8 n_preamble_override;
+ uint8 antswitch;
+ uint8 aa2g, aa5g;
+
+ int8 idle_tssi[CH_5G_GROUP];
+ int8 target_idle_tssi;
+ int8 txpwr_est_Pout;
+ uint8 tx_power_min;
+ uint8 txpwr_limit[TXP_NUM_RATES];
+ uint8 txpwr_env_limit[TXP_NUM_RATES];
+ uint8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
+
+ bool channel_14_wide_filter;
+
+ bool txpwroverride;
+ bool txpwridx_override_aphy;
+ int16 radiopwr_override;
+ uint16 hwpwr_txcur;
+ uint8 saved_txpwr_idx;
+
+ bool edcrs_threshold_lock;
+
+ uint32 tr_R_gain_val;
+ uint32 tr_T_gain_val;
+
+ int16 ofdm_analog_filt_bw_override;
+ int16 cck_analog_filt_bw_override;
+ int16 ofdm_rccal_override;
+ int16 cck_rccal_override;
+ uint16 extlna_type;
+
+ uint interference_mode_crs_time;
+ uint16 crsglitch_prev;
+ bool interference_mode_crs;
+
+ uint32 phy_tx_tone_freq;
+ uint phy_lastcal;
+ bool phy_forcecal;
+ bool phy_fixed_noise;
+ uint32 xtalfreq;
+ uint8 pdiv;
+ int8 carrier_suppr_disable;
+
+ bool phy_bphy_evm;
+ bool phy_bphy_rfcs;
+ int8 phy_scraminit;
+ uint8 phy_gpiosel;
+
+ int16 phy_txcore_disable_temp;
+ int16 phy_txcore_enable_temp;
+ int8 phy_tempsense_offset;
+ bool phy_txcore_heatedup;
+
+ uint16 radiopwr;
+ uint16 bb_atten;
+ uint16 txctl1;
+
+ uint16 mintxbias;
+ uint16 mintxmag;
+ lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB];
+ int8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
+ uint16 gain_table[TX_GAIN_TABLE_LENGTH];
+ bool loopback_gain;
+ int16 max_lpback_gain_hdB;
+ int16 trsw_rx_gain_hdB;
+ uint8 power_vec[8];
+
+ uint16 rc_cal;
+ int nrssi_table_delta;
+ int nrssi_slope_scale;
+ int nrssi_slope_offset;
+ int min_rssi;
+ int max_rssi;
+
+ int8 txpwridx;
+ uint8 min_txpower;
+
+ uint8 a_band_high_disable;
+
+ uint16 tx_vos;
+ uint16 global_tx_bb_dc_bias_loft;
+
+ int rf_max;
+ int bb_max;
+ int rf_list_size;
+ int bb_list_size;
+ uint16 *rf_attn_list;
+ uint16 *bb_attn_list;
+ uint16 padmix_mask;
+ uint16 padmix_reg;
+ uint16 *txmag_list;
+ uint txmag_len;
+ bool txmag_enable;
+
+ int8 *a_tssi_to_dbm;
+ int8 *m_tssi_to_dbm;
+ int8 *l_tssi_to_dbm;
+ int8 *h_tssi_to_dbm;
+ uint8 *hwtxpwr;
+
+ uint16 freqtrack_saved_regs[2];
+ int cur_interference_mode;
+ bool hwpwrctrl_capable;
+ bool temppwrctrl_capable;
+
+ uint phycal_nslope;
+ uint phycal_noffset;
+ uint phycal_mlo;
+ uint phycal_txpower;
+
+ bool pkteng_in_progress;
+ uint8 phy_aa2g;
+
+ bool nphy_tableloaded;
+ int8 nphy_rssisel;
+ uint32 nphy_bb_mult_save;
+ uint16 nphy_txiqlocal_bestc[11];
+ bool nphy_txiqlocal_coeffsvalid;
+ phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2];
+ phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2];
+ uint16 cck2gpo;
+ uint32 ofdm2gpo;
+ uint32 ofdm5gpo;
+ uint32 ofdm5glpo;
+ uint32 ofdm5ghpo;
+ uint8 bw402gpo;
+ uint8 bw405gpo;
+ uint8 bw405glpo;
+ uint8 bw405ghpo;
+ uint8 cdd2gpo;
+ uint8 cdd5gpo;
+ uint8 cdd5glpo;
+ uint8 cdd5ghpo;
+ uint8 stbc2gpo;
+ uint8 stbc5gpo;
+ uint8 stbc5glpo;
+ uint8 stbc5ghpo;
+ uint8 bwdup2gpo;
+ uint8 bwdup5gpo;
+ uint8 bwdup5glpo;
+ uint8 bwdup5ghpo;
+ uint16 mcs2gpo[8];
+ uint16 mcs5gpo[8];
+ uint16 mcs5glpo[8];
+ uint16 mcs5ghpo[8];
+ uint32 nphy_rxcalparams;
+
+ uint8 phy_spuravoid;
+ bool phy_isspuravoid;
+
+ uint8 phy_pabias;
+ uint8 nphy_papd_skip;
+ uint8 nphy_tssi_slope;
+
+ int16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
+ uint8 nphy_noise_index;
+
+ uint8 nphy_txpid2g[PHY_CORE_NUM_2];
+ uint8 nphy_txpid5g[PHY_CORE_NUM_2];
+ uint8 nphy_txpid5gl[PHY_CORE_NUM_2];
+ uint8 nphy_txpid5gh[PHY_CORE_NUM_2];
+
+ bool nphy_gain_boost;
+ bool nphy_elna_gain_config;
+ uint16 old_bphy_test;
+ uint16 old_bphy_testcontrol;
+
+ bool phyhang_avoid;
+
+ bool rssical_nphy;
+ uint8 nphy_perical;
+ uint nphy_perical_last;
+ uint8 cal_type_override;
+ uint8 mphase_cal_phase_id;
+ uint8 mphase_txcal_cmdidx;
+ uint8 mphase_txcal_numcmds;
+ uint16 mphase_txcal_bestcoeffs[11];
+ chanspec_t nphy_txiqlocal_chanspec;
+ chanspec_t nphy_iqcal_chanspec_2G;
+ chanspec_t nphy_iqcal_chanspec_5G;
+ chanspec_t nphy_rssical_chanspec_2G;
+ chanspec_t nphy_rssical_chanspec_5G;
+ struct wlapi_timer *phycal_timer;
+ bool use_int_tx_iqlo_cal_nphy;
+ bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
+ int16 nphy_lastcal_temp;
+
+ txiqcal_cache_t calibration_cache;
+ rssical_cache_t rssical_cache;
+
+ uint8 nphy_txpwr_idx[2];
+ uint8 nphy_papd_cal_type;
+ uint nphy_papd_last_cal;
+ uint16 nphy_papd_tx_gain_at_last_cal[2];
+ uint8 nphy_papd_cal_gain_index[2];
+ int16 nphy_papd_epsilon_offset[2];
+ bool nphy_papd_recal_enable;
+ uint32 nphy_papd_recal_counter;
+ bool nphy_force_papd_cal;
+ bool nphy_papdcomp;
+ bool ipa2g_on;
+ bool ipa5g_on;
+
+ uint16 classifier_state;
+ uint16 clip_state[2];
+ uint nphy_deaf_count;
+ uint8 rxiq_samps;
+ uint8 rxiq_antsel;
+
+ uint16 rfctrlIntc1_save;
+ uint16 rfctrlIntc2_save;
+ bool first_cal_after_assoc;
+ uint16 tx_rx_cal_radio_saveregs[22];
+ uint16 tx_rx_cal_phy_saveregs[15];
+
+ uint8 nphy_cal_orig_pwr_idx[2];
+ uint8 nphy_txcal_pwr_idx[2];
+ uint8 nphy_rxcal_pwr_idx[2];
+ uint16 nphy_cal_orig_tx_gain[2];
+ nphy_txgains_t nphy_cal_target_gain;
+ uint16 nphy_txcal_bbmult;
+ uint16 nphy_gmval;
+
+ uint16 nphy_saved_bbconf;
+
+ bool nphy_gband_spurwar_en;
+ bool nphy_gband_spurwar2_en;
+ bool nphy_aband_spurwar_en;
+ uint16 nphy_rccal_value;
+ uint16 nphy_crsminpwr[3];
+ phy_noisevar_buf_t nphy_saved_noisevars;
+ bool nphy_anarxlpf_adjusted;
+ bool nphy_crsminpwr_adjusted;
+ bool nphy_noisevars_adjusted;
+
+ bool nphy_rxcal_active;
+ uint16 radar_percal_mask;
+ bool dfs_lp_buffer_nphy;
+
+ uint16 nphy_fineclockgatecontrol;
+
+ int8 rx2tx_biasentry;
+
+ uint16 crsminpwr0;
+ uint16 crsminpwrl0;
+ uint16 crsminpwru0;
+ int16 noise_crsminpwr_index;
+ uint16 init_gain_core1;
+ uint16 init_gain_core2;
+ uint16 init_gainb_core1;
+ uint16 init_gainb_core2;
+ uint8 aci_noise_curr_channel;
+ uint16 init_gain_rfseq[4];
+
+ bool radio_is_on;
+
+ bool nphy_sample_play_lpf_bw_ctl_ovr;
+
+ uint16 tbl_data_hi;
+ uint16 tbl_data_lo;
+ uint16 tbl_addr;
+
+ uint tbl_save_id;
+ uint tbl_save_offset;
+
+ uint8 txpwrctrl;
+ int8 txpwrindex[PHY_CORE_MAX];
+
+ uint8 phycal_tempdelta;
+ uint32 mcs20_po;
+ uint32 mcs40_po;
+};
+
+typedef int32 fixed;
+
+typedef struct _cint32 {
+ fixed q;
+ fixed i;
+} cint32;
+
+typedef struct radio_regs {
+ uint16 address;
+ uint32 init_a;
+ uint32 init_g;
+ uint8 do_init_a;
+ uint8 do_init_g;
+} radio_regs_t;
+
+typedef struct radio_20xx_regs {
+ uint16 address;
+ uint8 init;
+ uint8 do_init;
+} radio_20xx_regs_t;
+
+typedef struct lcnphy_radio_regs {
+ uint16 address;
+ uint8 init_a;
+ uint8 init_g;
+ uint8 do_init_a;
+ uint8 do_init_g;
+} lcnphy_radio_regs_t;
+
+extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[];
+extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[];
+extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[],
+ regs_RX_2056[];
+extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[];
+extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
+ regs_RX_2056_rev5[];
+extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
+ regs_RX_2056_rev6[];
+extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
+ regs_RX_2056_rev7[];
+extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
+ regs_RX_2056_rev8[];
+extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[];
+extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[];
+
+extern char *phy_getvar(phy_info_t *pi, const char *name);
+extern int phy_getintvar(phy_info_t *pi, const char *name);
+#define PHY_GETVAR(pi, name) phy_getvar(pi, name)
+#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name)
+
+extern uint16 read_phy_reg(phy_info_t *pi, uint16 addr);
+extern void write_phy_reg(phy_info_t *pi, uint16 addr, uint16 val);
+extern void and_phy_reg(phy_info_t *pi, uint16 addr, uint16 val);
+extern void or_phy_reg(phy_info_t *pi, uint16 addr, uint16 val);
+extern void mod_phy_reg(phy_info_t *pi, uint16 addr, uint16 mask, uint16 val);
+
+extern uint16 read_radio_reg(phy_info_t *pi, uint16 addr);
+extern void or_radio_reg(phy_info_t *pi, uint16 addr, uint16 val);
+extern void and_radio_reg(phy_info_t *pi, uint16 addr, uint16 val);
+extern void mod_radio_reg(phy_info_t *pi, uint16 addr, uint16 mask,
+ uint16 val);
+extern void xor_radio_reg(phy_info_t *pi, uint16 addr, uint16 mask);
+
+extern void write_radio_reg(phy_info_t *pi, uint16 addr, uint16 val);
+
+extern void wlc_phyreg_enter(wlc_phy_t *pih);
+extern void wlc_phyreg_exit(wlc_phy_t *pih);
+extern void wlc_radioreg_enter(wlc_phy_t *pih);
+extern void wlc_radioreg_exit(wlc_phy_t *pih);
+
+extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+ uint16 tblAddr, uint16 tblDataHi,
+ uint16 tblDatalo);
+extern void wlc_phy_write_table(phy_info_t *pi,
+ const phytbl_info_t *ptbl_info, uint16 tblAddr,
+ uint16 tblDataHi, uint16 tblDatalo);
+extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+ uint16 tblAddr, uint16 tblDataHi,
+ uint16 tblDataLo);
+extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, uint32 val);
+
+extern void write_phy_channel_reg(phy_info_t *pi, uint val);
+extern void wlc_phy_txpower_update_shm(phy_info_t *pi);
+
+extern void wlc_phy_cordic(fixed theta, cint32 *val);
+extern uint8 wlc_phy_nbits(int32 value);
+extern uint32 wlc_phy_sqrt_int(uint32 value);
+extern void wlc_phy_compute_dB(uint32 *cmplx_pwr, int8 *p_dB, uint8 core);
+
+extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi,
+ radio_20xx_regs_t *radioregs);
+extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+ uint16 core_offset);
+
+extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi);
+
+extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on);
+extern void wlc_phy_papd_decode_epsilon(uint32 epsilon, int32 *eps_real,
+ int32 *eps_imag);
+
+extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi);
+extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi);
+
+extern bool wlc_phy_attach_nphy(phy_info_t *pi);
+extern bool wlc_phy_attach_lcnphy(phy_info_t *pi);
+
+extern void wlc_phy_detach_lcnphy(phy_info_t *pi);
+
+extern void wlc_phy_init_nphy(phy_info_t *pi);
+extern void wlc_phy_init_lcnphy(phy_info_t *pi);
+
+extern void wlc_phy_cal_init_nphy(phy_info_t *pi);
+extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi);
+
+extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec);
+extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec);
+extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi,
+ chanspec_t chanspec);
+extern int wlc_phy_channel2freq(uint channel);
+extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
+extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t);
+
+extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, uint16 mode);
+extern int8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi);
+
+extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi);
+extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi);
+extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi);
+
+extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index);
+extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable);
+extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi);
+extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, int32 f_kHz,
+ uint16 max_val, bool iqcalmode);
+
+extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan,
+ uint8 *max_pwr, uint8 rate_id);
+extern void wlc_phy_ofdm_to_mcs_powers_nphy(uint8 *power, uint8 rate_mcs_start,
+ uint8 rate_mcs_end,
+ uint8 rate_ofdm_start);
+extern void wlc_phy_mcs_to_ofdm_powers_nphy(uint8 *power,
+ uint8 rate_ofdm_start,
+ uint8 rate_ofdm_end,
+ uint8 rate_mcs_start);
+
+extern uint16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode);
+extern int16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode);
+extern int8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode);
+extern int8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode);
+extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi);
+extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel);
+extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode);
+extern void wlc_2064_vco_cal(phy_info_t *pi);
+
+extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
+extern uint32 wlc_phy_qdiv_roundup(uint32 dividend, uint32 divisor,
+ uint8 precision);
+
+#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18
+#define LCNPHY_TX_POWER_TABLE_SIZE 128
+#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1)
+#define LCNPHY_TBL_ID_TXPWRCTL 0x07
+#define LCNPHY_TX_PWR_CTRL_OFF 0
+#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15)
+#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \
+ (0x1 << 14) | \
+ (0x1 << 13))
+
+#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001
+
+extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti);
+extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti);
+extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, uint16 a, uint16 b);
+extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, uint16 didq);
+extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, uint16 *a, uint16 *b);
+extern uint16 wlc_lcnphy_get_tx_locc(phy_info_t *pi);
+extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, uint8 *ei0,
+ uint8 *eq0, uint8 *fi0, uint8 *fq0);
+extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode);
+extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode);
+extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi);
+extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi);
+extern int32 wlc_lcnphy_tssi2dbm(int32 tssi, int32 a1, int32 b0, int32 b1);
+extern void wlc_lcnphy_get_tssi(phy_info_t *pi, int8 *ofdm_pwr,
+ int8 *cck_pwr);
+extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi);
+
+extern int32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, int32 gain_index);
+
+#define NPHY_MAX_HPVGA1_INDEX 10
+#define NPHY_DEF_HPVGA1_INDEXLIMIT 7
+
+typedef struct _phy_iq_est {
+ int32 iq_prod;
+ uint32 i_pwr;
+ uint32 q_pwr;
+} phy_iq_est_t;
+
+extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable);
+extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode);
+
+#define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \
+ 0x74, 0x73)
+#define wlc_phy_read_table_nphy(pi, pti) wlc_phy_read_table(pi, pti, 0x72, \
+ 0x74, 0x73)
+#define wlc_nphy_table_addr(pi, id, off) wlc_phy_table_addr((pi), (id), (off), \
+ 0x72, 0x74, 0x73)
+#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v))
+
+extern void wlc_phy_table_read_nphy(phy_info_t *pi, uint32, uint32 l, uint32 o,
+ uint32 w, void *d);
+extern void wlc_phy_table_write_nphy(phy_info_t *pi, uint32, uint32, uint32,
+ uint32, const void *);
+
+#define PHY_IPA(pi) \
+ ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
+ (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
+
+#define WLC_PHY_WAR_PR51571(pi) \
+ if ((BUSTYPE((pi)->sh->bustype) == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \
+ (void)R_REG((pi)->sh->osh, &(pi)->regs->maccontrol)
+
+extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, uint8 caltype);
+extern void wlc_phy_aci_reset_nphy(phy_info_t *pi);
+extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en);
+
+extern uint8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan);
+extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on);
+
+extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi);
+
+extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, uint8 cmd);
+extern int16 wlc_phy_tempsense_nphy(phy_info_t *pi);
+
+extern uint16 wlc_phy_classifier_nphy(phy_info_t *pi, uint16 mask, uint16 val);
+
+extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est,
+ uint16 num_samps, uint8 wait_time,
+ uint8 wait_for_crs);
+
+extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, uint8 write,
+ nphy_iq_comp_t *comp);
+extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi);
+
+extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, uint8 rxcore_bitmask);
+extern uint8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih);
+
+extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, uint8 ctrl_type);
+extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi);
+extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi);
+extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi);
+extern uint16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi);
+
+extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi);
+extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+ bool full, bool m);
+extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+ uint8 type, bool d);
+extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, uint8 core_mask,
+ int8 txpwrindex, bool res);
+extern void wlc_phy_rssisel_nphy(phy_info_t *pi, uint8 core, uint8 rssi_type);
+extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, uint8 rssi_type,
+ int32 *rssi_buf, uint8 nsamps);
+extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi);
+extern int wlc_phy_aci_scan_nphy(phy_info_t *pi);
+extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, int32 dBm_targetpower,
+ bool debug);
+extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, uint32 f_kHz, uint16 max_val,
+ uint8 mode, uint8, bool);
+extern void wlc_phy_stopplayback_nphy(phy_info_t *pi);
+extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, int32 *qdBm_pwrbuf,
+ uint8 num_samps);
+extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi);
+
+extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh);
+
+#define NPHY_TESTPATTERN_BPHY_EVM 0
+#define NPHY_TESTPATTERN_BPHY_RFCS 1
+
+extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, uint8 rifs);
+
+void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, int8 *cckoffset,
+ int8 *ofdmoffset);
+extern int8 wlc_phy_upd_rssi_offset(phy_info_t *pi, int8 rssi,
+ chanspec_t chanspec);
+
+extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih);
+#endif /* _wlc_phy_int_h_ */
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c
new file mode 100644
index 000000000000..c34d06bf69e3
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c
@@ -0,0 +1,5329 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <qmath.h>
+#include <osl.h>
+#include <siutils.h>
+#include <bitfuncs.h>
+#include <hndpmu.h>
+
+#include <wlc_phy_radio.h>
+#include <wlc_phy_int.h>
+#include <wlc_phy_lcn.h>
+#include <wlc_phytbl_lcn.h>
+
+#define PLL_2064_NDIV 90
+#define PLL_2064_LOW_END_VCO 3000
+#define PLL_2064_LOW_END_KVCO 27
+#define PLL_2064_HIGH_END_VCO 4200
+#define PLL_2064_HIGH_END_KVCO 68
+#define PLL_2064_LOOP_BW_DOUBLER 200
+#define PLL_2064_D30_DOUBLER 10500
+#define PLL_2064_LOOP_BW 260
+#define PLL_2064_D30 8000
+#define PLL_2064_CAL_REF_TO 8
+#define PLL_2064_MHZ 1000000
+#define PLL_2064_OPEN_LOOP_DELAY 5
+
+#define TEMPSENSE 1
+#define VBATSENSE 2
+
+#define NOISE_IF_UPD_CHK_INTERVAL 1
+#define NOISE_IF_UPD_RST_INTERVAL 60
+#define NOISE_IF_UPD_THRESHOLD_CNT 1
+#define NOISE_IF_UPD_TRHRESHOLD 50
+#define NOISE_IF_UPD_TIMEOUT 1000
+#define NOISE_IF_OFF 0
+#define NOISE_IF_CHK 1
+#define NOISE_IF_ON 2
+
+#define PAPD_BLANKING_PROFILE 3
+#define PAPD2LUT 0
+#define PAPD_CORR_NORM 0
+#define PAPD_BLANKING_THRESHOLD 0
+#define PAPD_STOP_AFTER_LAST_UPDATE 0
+
+#define LCN_TARGET_PWR 60
+
+#define LCN_VBAT_OFFSET_433X 34649679
+#define LCN_VBAT_SLOPE_433X 8258032
+
+#define LCN_VBAT_SCALE_NOM 53
+#define LCN_VBAT_SCALE_DEN 432
+
+#define LCN_TEMPSENSE_OFFSET 80812
+#define LCN_TEMPSENSE_DEN 2647
+
+#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
+ (0 + 8)
+#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
+ (0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
+
+#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
+ (0 + 8)
+#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
+ (0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
+
+#define wlc_lcnphy_enable_tx_gain_override(pi) \
+ wlc_lcnphy_set_tx_gain_override(pi, TRUE)
+#define wlc_lcnphy_disable_tx_gain_override(pi) \
+ wlc_lcnphy_set_tx_gain_override(pi, FALSE)
+
+#define wlc_lcnphy_iqcal_active(pi) \
+ (read_phy_reg((pi), 0x451) & \
+ ((0x1 << 15) | (0x1 << 14)))
+
+#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
+#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \
+ (pi->temppwrctrl_capable)
+#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
+ (pi->hwpwrctrl_capable)
+
+#define SWCTRL_BT_TX 0x18
+#define SWCTRL_OVR_DISABLE 0x40
+
+#define AFE_CLK_INIT_MODE_TXRX2X 1
+#define AFE_CLK_INIT_MODE_PAPD 0
+
+#define LCNPHY_TBL_ID_IQLOCAL 0x00
+
+#define LCNPHY_TBL_ID_RFSEQ 0x08
+#define LCNPHY_TBL_ID_GAIN_IDX 0x0d
+#define LCNPHY_TBL_ID_SW_CTRL 0x0f
+#define LCNPHY_TBL_ID_GAIN_TBL 0x12
+#define LCNPHY_TBL_ID_SPUR 0x14
+#define LCNPHY_TBL_ID_SAMPLEPLAY 0x15
+#define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16
+
+#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832
+#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128
+#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192
+#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320
+#define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448
+#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576
+
+#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313 140
+
+#define LCNPHY_TX_PWR_CTRL_START_NPT 1
+#define LCNPHY_TX_PWR_CTRL_MAX_NPT 7
+
+#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
+
+#define LCNPHY_ACI_DETECT_START 1
+#define LCNPHY_ACI_DETECT_PROGRESS 2
+#define LCNPHY_ACI_DETECT_STOP 3
+
+#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
+#define LCNPHY_ACI_GLITCH_TRSH 2000
+#define LCNPHY_ACI_TMOUT 250
+#define LCNPHY_ACI_DETECT_TIMEOUT 2
+#define LCNPHY_ACI_START_DELAY 0
+
+#define wlc_lcnphy_tx_gain_override_enabled(pi) \
+ (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
+
+#define wlc_lcnphy_total_tx_frames(pi) \
+ wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + OFFSETOF(macstat_t, txallfrm))
+
+typedef struct {
+ uint16 gm_gain;
+ uint16 pga_gain;
+ uint16 pad_gain;
+ uint16 dac_gain;
+} lcnphy_txgains_t;
+
+typedef enum {
+ LCNPHY_CAL_FULL,
+ LCNPHY_CAL_RECAL,
+ LCNPHY_CAL_CURRECAL,
+ LCNPHY_CAL_DIGCAL,
+ LCNPHY_CAL_GCTRL
+} lcnphy_cal_mode_t;
+
+typedef struct {
+ lcnphy_txgains_t gains;
+ bool useindex;
+ uint8 index;
+} lcnphy_txcalgains_t;
+
+typedef struct {
+ uint8 chan;
+ int16 a;
+ int16 b;
+} lcnphy_rx_iqcomp_t;
+
+typedef struct {
+ int16 re;
+ int16 im;
+} lcnphy_spb_tone_t;
+
+typedef struct {
+ uint16 re;
+ uint16 im;
+} lcnphy_unsign16_struct;
+
+typedef struct {
+ uint32 iq_prod;
+ uint32 i_pwr;
+ uint32 q_pwr;
+} lcnphy_iq_est_t;
+
+typedef struct {
+ uint16 ptcentreTs20;
+ uint16 ptcentreFactor;
+} lcnphy_sfo_cfg_t;
+
+typedef enum {
+ LCNPHY_PAPD_CAL_CW,
+ LCNPHY_PAPD_CAL_OFDM
+} lcnphy_papd_cal_type_t;
+
+typedef uint16 iqcal_gain_params_lcnphy[9];
+
+static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
+
+static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
+ tbl_iqcal_gainparams_lcnphy_2G,
+};
+
+static const uint16 iqcal_gainparams_numgains_lcnphy[1] = {
+ sizeof(tbl_iqcal_gainparams_lcnphy_2G) /
+ sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
+};
+
+static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = {
+ {965, 1087},
+ {967, 1085},
+ {969, 1082},
+ {971, 1080},
+ {973, 1078},
+ {975, 1076},
+ {977, 1073},
+ {979, 1071},
+ {981, 1069},
+ {983, 1067},
+ {985, 1065},
+ {987, 1063},
+ {989, 1060},
+ {994, 1055}
+};
+
+static const
+uint16 lcnphy_iqcal_loft_gainladder[] = {
+ ((2 << 8) | 0),
+ ((3 << 8) | 0),
+ ((4 << 8) | 0),
+ ((6 << 8) | 0),
+ ((8 << 8) | 0),
+ ((11 << 8) | 0),
+ ((16 << 8) | 0),
+ ((16 << 8) | 1),
+ ((16 << 8) | 2),
+ ((16 << 8) | 3),
+ ((16 << 8) | 4),
+ ((16 << 8) | 5),
+ ((16 << 8) | 6),
+ ((16 << 8) | 7),
+ ((23 << 8) | 7),
+ ((32 << 8) | 7),
+ ((45 << 8) | 7),
+ ((64 << 8) | 7),
+ ((91 << 8) | 7),
+ ((128 << 8) | 7)
+};
+
+static const
+uint16 lcnphy_iqcal_ir_gainladder[] = {
+ ((1 << 8) | 0),
+ ((2 << 8) | 0),
+ ((4 << 8) | 0),
+ ((6 << 8) | 0),
+ ((8 << 8) | 0),
+ ((11 << 8) | 0),
+ ((16 << 8) | 0),
+ ((23 << 8) | 0),
+ ((32 << 8) | 0),
+ ((45 << 8) | 0),
+ ((64 << 8) | 0),
+ ((64 << 8) | 1),
+ ((64 << 8) | 2),
+ ((64 << 8) | 3),
+ ((64 << 8) | 4),
+ ((64 << 8) | 5),
+ ((64 << 8) | 6),
+ ((64 << 8) | 7),
+ ((91 << 8) | 7),
+ ((128 << 8) | 7)
+};
+
+static const
+lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = {
+ {88, 0},
+ {73, 49},
+ {34, 81},
+ {-17, 86},
+ {-62, 62},
+ {-86, 17},
+ {-81, -34},
+ {-49, -73},
+ {0, -88},
+ {49, -73},
+ {81, -34},
+ {86, 17},
+ {62, 62},
+ {17, 86},
+ {-34, 81},
+ {-73, 49},
+ {-88, 0},
+ {-73, -49},
+ {-34, -81},
+ {17, -86},
+ {62, -62},
+ {86, -17},
+ {81, 34},
+ {49, 73},
+ {0, 88},
+ {-49, 73},
+ {-81, 34},
+ {-86, -17},
+ {-62, -62},
+ {-17, -86},
+ {34, -81},
+ {73, -49},
+};
+
+static const
+uint16 iqlo_loopback_rf_regs[20] = {
+ RADIO_2064_REG036,
+ RADIO_2064_REG11A,
+ RADIO_2064_REG03A,
+ RADIO_2064_REG025,
+ RADIO_2064_REG028,
+ RADIO_2064_REG005,
+ RADIO_2064_REG112,
+ RADIO_2064_REG0FF,
+ RADIO_2064_REG11F,
+ RADIO_2064_REG00B,
+ RADIO_2064_REG113,
+ RADIO_2064_REG007,
+ RADIO_2064_REG0FC,
+ RADIO_2064_REG0FD,
+ RADIO_2064_REG012,
+ RADIO_2064_REG057,
+ RADIO_2064_REG059,
+ RADIO_2064_REG05C,
+ RADIO_2064_REG078,
+ RADIO_2064_REG092,
+};
+
+static const
+uint16 tempsense_phy_regs[14] = {
+ 0x503,
+ 0x4a4,
+ 0x4d0,
+ 0x4d9,
+ 0x4da,
+ 0x4a6,
+ 0x938,
+ 0x939,
+ 0x4d8,
+ 0x4d0,
+ 0x4d7,
+ 0x4a5,
+ 0x40d,
+ 0x4a2,
+};
+
+static const
+uint16 rxiq_cal_rf_reg[11] = {
+ RADIO_2064_REG098,
+ RADIO_2064_REG116,
+ RADIO_2064_REG12C,
+ RADIO_2064_REG06A,
+ RADIO_2064_REG00B,
+ RADIO_2064_REG01B,
+ RADIO_2064_REG113,
+ RADIO_2064_REG01D,
+ RADIO_2064_REG114,
+ RADIO_2064_REG02E,
+ RADIO_2064_REG12A,
+};
+
+static const
+lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = {
+ {1, 0, 0},
+ {2, 0, 0},
+ {3, 0, 0},
+ {4, 0, 0},
+ {5, 0, 0},
+ {6, 0, 0},
+ {7, 0, 0},
+ {8, 0, 0},
+ {9, 0, 0},
+ {10, 0, 0},
+ {11, 0, 0},
+ {12, 0, 0},
+ {13, 0, 0},
+ {14, 0, 0},
+ {34, 0, 0},
+ {38, 0, 0},
+ {42, 0, 0},
+ {46, 0, 0},
+ {36, 0, 0},
+ {40, 0, 0},
+ {44, 0, 0},
+ {48, 0, 0},
+ {52, 0, 0},
+ {56, 0, 0},
+ {60, 0, 0},
+ {64, 0, 0},
+ {100, 0, 0},
+ {104, 0, 0},
+ {108, 0, 0},
+ {112, 0, 0},
+ {116, 0, 0},
+ {120, 0, 0},
+ {124, 0, 0},
+ {128, 0, 0},
+ {132, 0, 0},
+ {136, 0, 0},
+ {140, 0, 0},
+ {149, 0, 0},
+ {153, 0, 0},
+ {157, 0, 0},
+ {161, 0, 0},
+ {165, 0, 0},
+ {184, 0, 0},
+ {188, 0, 0},
+ {192, 0, 0},
+ {196, 0, 0},
+ {200, 0, 0},
+ {204, 0, 0},
+ {208, 0, 0},
+ {212, 0, 0},
+ {216, 0, 0},
+};
+
+static const uint32 lcnphy_23bitgaincode_table[] = {
+ 0x200100,
+ 0x200200,
+ 0x200004,
+ 0x200014,
+ 0x200024,
+ 0x200034,
+ 0x200134,
+ 0x200234,
+ 0x200334,
+ 0x200434,
+ 0x200037,
+ 0x200137,
+ 0x200237,
+ 0x200337,
+ 0x200437,
+ 0x000035,
+ 0x000135,
+ 0x000235,
+ 0x000037,
+ 0x000137,
+ 0x000237,
+ 0x000337,
+ 0x00013f,
+ 0x00023f,
+ 0x00033f,
+ 0x00034f,
+ 0x00044f,
+ 0x00144f,
+ 0x00244f,
+ 0x00254f,
+ 0x00354f,
+ 0x00454f,
+ 0x00464f,
+ 0x01464f,
+ 0x02464f,
+ 0x03464f,
+ 0x04464f,
+};
+
+static const int8 lcnphy_gain_table[] = {
+ -16,
+ -13,
+ 10,
+ 7,
+ 4,
+ 0,
+ 3,
+ 6,
+ 9,
+ 12,
+ 15,
+ 18,
+ 21,
+ 24,
+ 27,
+ 30,
+ 33,
+ 36,
+ 39,
+ 42,
+ 45,
+ 48,
+ 50,
+ 53,
+ 56,
+ 59,
+ 62,
+ 65,
+ 68,
+ 71,
+ 74,
+ 77,
+ 80,
+ 83,
+ 86,
+ 89,
+ 92,
+};
+
+static const int8 lcnphy_gain_index_offset_for_rssi[] = {
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 7,
+ 6,
+ 7,
+ 7,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 4,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ -1,
+ -2,
+ -2,
+ -2
+};
+
+extern CONST uint8 spur_tbl_rev0[];
+extern CONST uint32 dot11lcnphytbl_rx_gain_info_sz_rev1;
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[];
+extern CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
+extern CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
+
+typedef struct _chan_info_2064_lcnphy {
+ uint chan;
+ uint freq;
+ uint8 logen_buftune;
+ uint8 logen_rccr_tx;
+ uint8 txrf_mix_tune_ctrl;
+ uint8 pa_input_tune_g;
+ uint8 logen_rccr_rx;
+ uint8 pa_rxrf_lna1_freq_tune;
+ uint8 pa_rxrf_lna2_freq_tune;
+ uint8 rxrf_rxrf_spare1;
+} chan_info_2064_lcnphy_t;
+
+static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = {
+ {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+ {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+};
+
+lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = {
+ {0x00, 0, 0, 0, 0},
+ {0x01, 0x64, 0x64, 0, 0},
+ {0x02, 0x20, 0x20, 0, 0},
+ {0x03, 0x66, 0x66, 0, 0},
+ {0x04, 0xf8, 0xf8, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0x10, 0x10, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0x37, 0x37, 0, 0},
+ {0x0B, 0x6, 0x6, 0, 0},
+ {0x0C, 0x55, 0x55, 0, 0},
+ {0x0D, 0x8b, 0x8b, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0x5, 0x5, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0xe, 0xe, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0xb, 0xb, 0, 0},
+ {0x14, 0x2, 0x2, 0, 0},
+ {0x15, 0x12, 0x12, 0, 0},
+ {0x16, 0x12, 0x12, 0, 0},
+ {0x17, 0xc, 0xc, 0, 0},
+ {0x18, 0xc, 0xc, 0, 0},
+ {0x19, 0xc, 0xc, 0, 0},
+ {0x1A, 0x8, 0x8, 0, 0},
+ {0x1B, 0x2, 0x2, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0x1, 0x1, 0, 0},
+ {0x1E, 0x12, 0x12, 0, 0},
+ {0x1F, 0x6e, 0x6e, 0, 0},
+ {0x20, 0x2, 0x2, 0, 0},
+ {0x21, 0x23, 0x23, 0, 0},
+ {0x22, 0x8, 0x8, 0, 0},
+ {0x23, 0, 0, 0, 0},
+ {0x24, 0, 0, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0x33, 0x33, 0, 0},
+ {0x27, 0x55, 0x55, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x30, 0x30, 0, 0},
+ {0x2A, 0xb, 0xb, 0, 0},
+ {0x2B, 0x1b, 0x1b, 0, 0},
+ {0x2C, 0x3, 0x3, 0, 0},
+ {0x2D, 0x1b, 0x1b, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x20, 0x20, 0, 0},
+ {0x30, 0xa, 0xa, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0x62, 0x62, 0, 0},
+ {0x33, 0x19, 0x19, 0, 0},
+ {0x34, 0x33, 0x33, 0, 0},
+ {0x35, 0x77, 0x77, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x70, 0x70, 0, 0},
+ {0x38, 0x3, 0x3, 0, 0},
+ {0x39, 0xf, 0xf, 0, 0},
+ {0x3A, 0x6, 0x6, 0, 0},
+ {0x3B, 0xcf, 0xcf, 0, 0},
+ {0x3C, 0x1a, 0x1a, 0, 0},
+ {0x3D, 0x6, 0x6, 0, 0},
+ {0x3E, 0x42, 0x42, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0xfb, 0xfb, 0, 0},
+ {0x41, 0x9a, 0x9a, 0, 0},
+ {0x42, 0x7a, 0x7a, 0, 0},
+ {0x43, 0x29, 0x29, 0, 0},
+ {0x44, 0, 0, 0, 0},
+ {0x45, 0x8, 0x8, 0, 0},
+ {0x46, 0xce, 0xce, 0, 0},
+ {0x47, 0x27, 0x27, 0, 0},
+ {0x48, 0x62, 0x62, 0, 0},
+ {0x49, 0x6, 0x6, 0, 0},
+ {0x4A, 0x58, 0x58, 0, 0},
+ {0x4B, 0xf7, 0xf7, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0xb3, 0xb3, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0, 0, 0, 0},
+ {0x51, 0x9, 0x9, 0, 0},
+ {0x52, 0x5, 0x5, 0, 0},
+ {0x53, 0x17, 0x17, 0, 0},
+ {0x54, 0x38, 0x38, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0xb, 0xb, 0, 0},
+ {0x58, 0, 0, 0, 0},
+ {0x59, 0, 0, 0, 0},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0, 0, 0, 0},
+ {0x5C, 0, 0, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x88, 0x88, 0, 0},
+ {0x5F, 0xcc, 0xcc, 0, 0},
+ {0x60, 0x74, 0x74, 0, 0},
+ {0x61, 0x74, 0x74, 0, 0},
+ {0x62, 0x74, 0x74, 0, 0},
+ {0x63, 0x44, 0x44, 0, 0},
+ {0x64, 0x77, 0x77, 0, 0},
+ {0x65, 0x44, 0x44, 0, 0},
+ {0x66, 0x77, 0x77, 0, 0},
+ {0x67, 0x55, 0x55, 0, 0},
+ {0x68, 0x77, 0x77, 0, 0},
+ {0x69, 0x77, 0x77, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0x7f, 0x7f, 0, 0},
+ {0x6C, 0x8, 0x8, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0x88, 0x88, 0, 0},
+ {0x6F, 0x66, 0x66, 0, 0},
+ {0x70, 0x66, 0x66, 0, 0},
+ {0x71, 0x28, 0x28, 0, 0},
+ {0x72, 0x55, 0x55, 0, 0},
+ {0x73, 0x4, 0x4, 0, 0},
+ {0x74, 0, 0, 0, 0},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0, 0, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0xd6, 0xd6, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0xb4, 0xb4, 0, 0},
+ {0x84, 0x1, 0x1, 0, 0},
+ {0x85, 0x20, 0x20, 0, 0},
+ {0x86, 0x5, 0x5, 0, 0},
+ {0x87, 0xff, 0xff, 0, 0},
+ {0x88, 0x7, 0x7, 0, 0},
+ {0x89, 0x77, 0x77, 0, 0},
+ {0x8A, 0x77, 0x77, 0, 0},
+ {0x8B, 0x77, 0x77, 0, 0},
+ {0x8C, 0x77, 0x77, 0, 0},
+ {0x8D, 0x8, 0x8, 0, 0},
+ {0x8E, 0xa, 0xa, 0, 0},
+ {0x8F, 0x8, 0x8, 0, 0},
+ {0x90, 0x18, 0x18, 0, 0},
+ {0x91, 0x5, 0x5, 0, 0},
+ {0x92, 0x1f, 0x1f, 0, 0},
+ {0x93, 0x10, 0x10, 0, 0},
+ {0x94, 0x3, 0x3, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0xaa, 0xaa, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0x23, 0x23, 0, 0},
+ {0x9A, 0x7, 0x7, 0, 0},
+ {0x9B, 0xf, 0xf, 0, 0},
+ {0x9C, 0x10, 0x10, 0, 0},
+ {0x9D, 0x3, 0x3, 0, 0},
+ {0x9E, 0x4, 0x4, 0, 0},
+ {0x9F, 0x20, 0x20, 0, 0},
+ {0xA0, 0, 0, 0, 0},
+ {0xA1, 0, 0, 0, 0},
+ {0xA2, 0, 0, 0, 0},
+ {0xA3, 0, 0, 0, 0},
+ {0xA4, 0x1, 0x1, 0, 0},
+ {0xA5, 0x77, 0x77, 0, 0},
+ {0xA6, 0x77, 0x77, 0, 0},
+ {0xA7, 0x77, 0x77, 0, 0},
+ {0xA8, 0x77, 0x77, 0, 0},
+ {0xA9, 0x8c, 0x8c, 0, 0},
+ {0xAA, 0x88, 0x88, 0, 0},
+ {0xAB, 0x78, 0x78, 0, 0},
+ {0xAC, 0x57, 0x57, 0, 0},
+ {0xAD, 0x88, 0x88, 0, 0},
+ {0xAE, 0, 0, 0, 0},
+ {0xAF, 0x8, 0x8, 0, 0},
+ {0xB0, 0x88, 0x88, 0, 0},
+ {0xB1, 0, 0, 0, 0},
+ {0xB2, 0x1b, 0x1b, 0, 0},
+ {0xB3, 0x3, 0x3, 0, 0},
+ {0xB4, 0x24, 0x24, 0, 0},
+ {0xB5, 0x3, 0x3, 0, 0},
+ {0xB6, 0x1b, 0x1b, 0, 0},
+ {0xB7, 0x24, 0x24, 0, 0},
+ {0xB8, 0x3, 0x3, 0, 0},
+ {0xB9, 0, 0, 0, 0},
+ {0xBA, 0xaa, 0xaa, 0, 0},
+ {0xBB, 0, 0, 0, 0},
+ {0xBC, 0x4, 0x4, 0, 0},
+ {0xBD, 0, 0, 0, 0},
+ {0xBE, 0x8, 0x8, 0, 0},
+ {0xBF, 0x11, 0x11, 0, 0},
+ {0xC0, 0, 0, 0, 0},
+ {0xC1, 0, 0, 0, 0},
+ {0xC2, 0x62, 0x62, 0, 0},
+ {0xC3, 0x1e, 0x1e, 0, 0},
+ {0xC4, 0x33, 0x33, 0, 0},
+ {0xC5, 0x37, 0x37, 0, 0},
+ {0xC6, 0, 0, 0, 0},
+ {0xC7, 0x70, 0x70, 0, 0},
+ {0xC8, 0x1e, 0x1e, 0, 0},
+ {0xC9, 0x6, 0x6, 0, 0},
+ {0xCA, 0x4, 0x4, 0, 0},
+ {0xCB, 0x2f, 0x2f, 0, 0},
+ {0xCC, 0xf, 0xf, 0, 0},
+ {0xCD, 0, 0, 0, 0},
+ {0xCE, 0xff, 0xff, 0, 0},
+ {0xCF, 0x8, 0x8, 0, 0},
+ {0xD0, 0x3f, 0x3f, 0, 0},
+ {0xD1, 0x3f, 0x3f, 0, 0},
+ {0xD2, 0x3f, 0x3f, 0, 0},
+ {0xD3, 0, 0, 0, 0},
+ {0xD4, 0, 0, 0, 0},
+ {0xD5, 0, 0, 0, 0},
+ {0xD6, 0xcc, 0xcc, 0, 0},
+ {0xD7, 0, 0, 0, 0},
+ {0xD8, 0x8, 0x8, 0, 0},
+ {0xD9, 0x8, 0x8, 0, 0},
+ {0xDA, 0x8, 0x8, 0, 0},
+ {0xDB, 0x11, 0x11, 0, 0},
+ {0xDC, 0, 0, 0, 0},
+ {0xDD, 0x87, 0x87, 0, 0},
+ {0xDE, 0x88, 0x88, 0, 0},
+ {0xDF, 0x8, 0x8, 0, 0},
+ {0xE0, 0x8, 0x8, 0, 0},
+ {0xE1, 0x8, 0x8, 0, 0},
+ {0xE2, 0, 0, 0, 0},
+ {0xE3, 0, 0, 0, 0},
+ {0xE4, 0, 0, 0, 0},
+ {0xE5, 0xf5, 0xf5, 0, 0},
+ {0xE6, 0x30, 0x30, 0, 0},
+ {0xE7, 0x1, 0x1, 0, 0},
+ {0xE8, 0, 0, 0, 0},
+ {0xE9, 0xff, 0xff, 0, 0},
+ {0xEA, 0, 0, 0, 0},
+ {0xEB, 0, 0, 0, 0},
+ {0xEC, 0x22, 0x22, 0, 0},
+ {0xED, 0, 0, 0, 0},
+ {0xEE, 0, 0, 0, 0},
+ {0xEF, 0, 0, 0, 0},
+ {0xF0, 0x3, 0x3, 0, 0},
+ {0xF1, 0x1, 0x1, 0, 0},
+ {0xF2, 0, 0, 0, 0},
+ {0xF3, 0, 0, 0, 0},
+ {0xF4, 0, 0, 0, 0},
+ {0xF5, 0, 0, 0, 0},
+ {0xF6, 0, 0, 0, 0},
+ {0xF7, 0x6, 0x6, 0, 0},
+ {0xF8, 0, 0, 0, 0},
+ {0xF9, 0, 0, 0, 0},
+ {0xFA, 0x40, 0x40, 0, 0},
+ {0xFB, 0, 0, 0, 0},
+ {0xFC, 0x1, 0x1, 0, 0},
+ {0xFD, 0x80, 0x80, 0, 0},
+ {0xFE, 0x2, 0x2, 0, 0},
+ {0xFF, 0x10, 0x10, 0, 0},
+ {0x100, 0x2, 0x2, 0, 0},
+ {0x101, 0x1e, 0x1e, 0, 0},
+ {0x102, 0x1e, 0x1e, 0, 0},
+ {0x103, 0, 0, 0, 0},
+ {0x104, 0x1f, 0x1f, 0, 0},
+ {0x105, 0, 0x8, 0, 1},
+ {0x106, 0x2a, 0x2a, 0, 0},
+ {0x107, 0xf, 0xf, 0, 0},
+ {0x108, 0, 0, 0, 0},
+ {0x109, 0, 0, 0, 0},
+ {0x10A, 0, 0, 0, 0},
+ {0x10B, 0, 0, 0, 0},
+ {0x10C, 0, 0, 0, 0},
+ {0x10D, 0, 0, 0, 0},
+ {0x10E, 0, 0, 0, 0},
+ {0x10F, 0, 0, 0, 0},
+ {0x110, 0, 0, 0, 0},
+ {0x111, 0, 0, 0, 0},
+ {0x112, 0, 0, 0, 0},
+ {0x113, 0, 0, 0, 0},
+ {0x114, 0, 0, 0, 0},
+ {0x115, 0, 0, 0, 0},
+ {0x116, 0, 0, 0, 0},
+ {0x117, 0, 0, 0, 0},
+ {0x118, 0, 0, 0, 0},
+ {0x119, 0, 0, 0, 0},
+ {0x11A, 0, 0, 0, 0},
+ {0x11B, 0, 0, 0, 0},
+ {0x11C, 0x1, 0x1, 0, 0},
+ {0x11D, 0, 0, 0, 0},
+ {0x11E, 0, 0, 0, 0},
+ {0x11F, 0, 0, 0, 0},
+ {0x120, 0, 0, 0, 0},
+ {0x121, 0, 0, 0, 0},
+ {0x122, 0x80, 0x80, 0, 0},
+ {0x123, 0, 0, 0, 0},
+ {0x124, 0xf8, 0xf8, 0, 0},
+ {0x125, 0, 0, 0, 0},
+ {0x126, 0, 0, 0, 0},
+ {0x127, 0, 0, 0, 0},
+ {0x128, 0, 0, 0, 0},
+ {0x129, 0, 0, 0, 0},
+ {0x12A, 0, 0, 0, 0},
+ {0x12B, 0, 0, 0, 0},
+ {0x12C, 0, 0, 0, 0},
+ {0x12D, 0, 0, 0, 0},
+ {0x12E, 0, 0, 0, 0},
+ {0x12F, 0, 0, 0, 0},
+ {0x130, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+#define LCNPHY_NUM_DIG_FILT_COEFFS 16
+#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
+
+uint16
+ LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
+ [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+ {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
+ 128, 64,},
+ {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
+ 167, 93,},
+ {2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
+ 128, 64,},
+ {3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
+ 170, 340, 170,},
+ {20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
+ 256, 185, 256,},
+ {21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
+ 256, 273, 256,},
+ {22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
+ 256, 352, 256,},
+ {23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
+ 128, 233, 128,},
+ {24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
+ 1881, 256,},
+ {25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
+ 1881, 256,},
+ {26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
+ 384, 288,},
+ {27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
+ 128, 384, 288,},
+ {30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
+ 170, 340, 170,},
+};
+
+#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
+uint16
+ LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
+ [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+ {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
+ 0x278, 0xfea0, 0x80, 0x100, 0x80,},
+ {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
+ 750, 0xFE2B, 212, 0xFFCE, 212,},
+ {2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
+ 0xFEF2, 128, 0xFFE2, 128}
+};
+
+#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
+ mod_phy_reg(pi, 0x4a4, \
+ (0x1ff << 0), \
+ (uint16)(idx) << 0)
+
+#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
+ mod_phy_reg(pi, 0x4a5, \
+ (0x7 << 8), \
+ (uint16)(npt) << 8)
+
+#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
+ (read_phy_reg((pi), 0x4a4) & \
+ ((0x1 << 15) | \
+ (0x1 << 14) | \
+ (0x1 << 13)))
+
+#define wlc_lcnphy_get_tx_pwr_npt(pi) \
+ ((read_phy_reg(pi, 0x4a5) & \
+ (0x7 << 8)) >> \
+ 8)
+
+#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
+ (read_phy_reg(pi, 0x473) & 0x1ff)
+
+#define wlc_lcnphy_get_target_tx_pwr(pi) \
+ ((read_phy_reg(pi, 0x4a7) & \
+ (0xff << 0)) >> \
+ 0)
+
+#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
+ mod_phy_reg(pi, 0x4a7, \
+ (0xff << 0), \
+ (uint16)(target) << 0)
+
+#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
+#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
+
+#define LCNPHY_IQLOCC_READ(val) ((uint8)(-(int8)(((val) & 0xf0) >> 4) + (int8)((val) & 0x0f)))
+#define FIXED_TXPWR 78
+#define LCNPHY_TEMPSENSE(val) ((int16)((val > 255) ? (val - 512) : val))
+
+static uint32 wlc_lcnphy_qdiv_roundup(uint32 divident, uint32 divisor,
+ uint8 precision);
+static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+ uint16 ext_lna, uint16 trsw,
+ uint16 biq2, uint16 biq1,
+ uint16 tia, uint16 lna2,
+ uint16 lna1);
+static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi);
+static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, uint16 gain);
+static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx);
+static void wlc_lcnphy_set_bbmult(phy_info_t *pi, uint8 m0);
+static uint8 wlc_lcnphy_get_bbmult(phy_info_t *pi);
+static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains);
+static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable);
+static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi);
+static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable);
+static void wlc_lcnphy_set_tx_gain(phy_info_t *pi,
+ lcnphy_txgains_t *target_gains);
+static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, uint16 num_samps,
+ uint8 wait_time, lcnphy_iq_est_t *iq_est);
+static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, uint16 num_samps);
+static uint16 wlc_lcnphy_get_pa_gain(phy_info_t *pi);
+static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, uint8 mode);
+extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi);
+extern void wlc_lcnphy_pktengtx(wlc_phy_t *ppi, wl_pkteng_t *pkteng,
+ uint8 rate, struct ether_addr *sa,
+ uint32 wait_delay);
+static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi,
+ uint8 channel);
+
+static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi,
+ const lcnphy_tx_gain_tbl_entry *g);
+
+static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo,
+ uint16 thresh, int16 *ptr, int mode);
+static int wlc_lcnphy_calc_floor(int16 coeff, int type);
+static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi,
+ uint16 *values_to_save);
+static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi,
+ uint16 *values_to_save);
+static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, int16 coeff_x,
+ int16 coeff_y);
+static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type);
+static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type,
+ int num_levels, int step_size_lg2);
+static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi);
+
+static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi,
+ chanspec_t chanspec);
+static void wlc_lcnphy_agc_temp_init(phy_info_t *pi);
+static void wlc_lcnphy_temp_adj(phy_info_t *pi);
+static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi);
+static void wlc_lcnphy_baseband_init(phy_info_t *pi);
+static void wlc_lcnphy_radio_init(phy_info_t *pi);
+static void wlc_lcnphy_rc_cal(phy_info_t *pi);
+static void wlc_lcnphy_rcal(phy_info_t *pi);
+static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable);
+static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm,
+ int16 filt_type);
+static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, uint16 a, uint16 b);
+
+void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti)
+{
+ wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
+}
+
+void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti)
+{
+ wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
+}
+
+static void
+wlc_lcnphy_common_read_table(phy_info_t *pi, uint32 tbl_id,
+ CONST void *tbl_ptr, uint32 tbl_len,
+ uint32 tbl_width, uint32 tbl_offset)
+{
+ phytbl_info_t tab;
+ tab.tbl_id = tbl_id;
+ tab.tbl_ptr = tbl_ptr;
+ tab.tbl_len = tbl_len;
+ tab.tbl_width = tbl_width;
+ tab.tbl_offset = tbl_offset;
+ wlc_lcnphy_read_table(pi, &tab);
+}
+
+static void
+wlc_lcnphy_common_write_table(phy_info_t *pi, uint32 tbl_id,
+ CONST void *tbl_ptr, uint32 tbl_len,
+ uint32 tbl_width, uint32 tbl_offset)
+{
+
+ phytbl_info_t tab;
+ tab.tbl_id = tbl_id;
+ tab.tbl_ptr = tbl_ptr;
+ tab.tbl_len = tbl_len;
+ tab.tbl_width = tbl_width;
+ tab.tbl_offset = tbl_offset;
+ wlc_lcnphy_write_table(pi, &tab);
+}
+
+static uint32
+wlc_lcnphy_qdiv_roundup(uint32 dividend, uint32 divisor, uint8 precision)
+{
+ uint32 quotient, remainder, roundup, rbit;
+
+ ASSERT(divisor);
+
+ quotient = dividend / divisor;
+ remainder = dividend % divisor;
+ rbit = divisor & 1;
+ roundup = (divisor >> 1) + rbit;
+
+ while (precision--) {
+ quotient <<= 1;
+ if (remainder >= roundup) {
+ quotient++;
+ remainder = ((remainder - roundup) << 1) + rbit;
+ } else {
+ remainder <<= 1;
+ }
+ }
+
+ if (remainder >= roundup)
+ quotient++;
+
+ return quotient;
+}
+
+static int wlc_lcnphy_calc_floor(int16 coeff_x, int type)
+{
+ int k;
+ k = 0;
+ if (type == 0) {
+ if (coeff_x < 0) {
+ k = (coeff_x - 1) / 2;
+ } else {
+ k = coeff_x / 2;
+ }
+ }
+ if (type == 1) {
+ if ((coeff_x + 1) < 0)
+ k = (coeff_x) / 2;
+ else
+ k = (coeff_x + 1) / 2;
+ }
+ return k;
+}
+
+int8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi)
+{
+ int8 index;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (txpwrctrl_off(pi))
+ index = pi_lcn->lcnphy_current_index;
+ else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+ index =
+ (int8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi)
+ / 2);
+ else
+ index = pi_lcn->lcnphy_current_index;
+ return index;
+}
+
+static uint32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, uint16 nsamples)
+{
+ lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+
+ if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
+ return 0;
+ return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
+}
+
+void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel)
+{
+ uint16 afectrlovr, afectrlovrval;
+ afectrlovr = read_phy_reg(pi, 0x43b);
+ afectrlovrval = read_phy_reg(pi, 0x43c);
+ if (channel != 0) {
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
+
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
+
+ mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
+
+ write_phy_reg(pi, 0x44b, 0xffff);
+ wlc_lcnphy_tx_pu(pi, 1);
+
+ mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
+
+ or_phy_reg(pi, 0x6da, 0x0080);
+
+ or_phy_reg(pi, 0x00a, 0x228);
+ } else {
+ and_phy_reg(pi, 0x00a, ~(0x228));
+
+ and_phy_reg(pi, 0x6da, 0xFF7F);
+ write_phy_reg(pi, 0x43b, afectrlovr);
+ write_phy_reg(pi, 0x43c, afectrlovrval);
+ }
+}
+
+static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi)
+{
+ uint16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
+
+ save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
+ save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
+
+ write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
+ write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
+
+ write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
+ write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
+
+ write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
+ write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
+}
+
+static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable)
+{
+ if (enable) {
+ write_phy_reg(pi, 0x942, 0x7);
+ write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
+ write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
+
+ write_phy_reg(pi, 0x44a, 0x084);
+ write_phy_reg(pi, 0x44a, 0x080);
+ write_phy_reg(pi, 0x6d3, 0x2222);
+ write_phy_reg(pi, 0x6d3, 0x2220);
+ } else {
+ write_phy_reg(pi, 0x942, 0x0);
+ write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
+ write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
+ }
+ wlapi_switch_macfreq(pi->sh->physhim, enable);
+}
+
+void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec)
+{
+ uint8 channel = CHSPEC_CHANNEL(chanspec);
+
+ wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+
+ wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
+
+ or_phy_reg(pi, 0x44a, 0x44);
+ write_phy_reg(pi, 0x44a, 0x80);
+
+ if (!NORADIO_ENAB(pi->pubpi)) {
+ wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
+ OSL_DELAY(1000);
+ }
+
+ wlc_lcnphy_toggle_afe_pwdn(pi);
+
+ write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
+ write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
+
+ if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+
+ wlc_lcnphy_load_tx_iir_filter(pi, FALSE, 3);
+ } else {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+
+ wlc_lcnphy_load_tx_iir_filter(pi, FALSE, 2);
+ }
+
+ wlc_lcnphy_load_tx_iir_filter(pi, TRUE, 0);
+
+ mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+
+}
+
+static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, uint16 dac_gain)
+{
+ uint16 dac_ctrl;
+
+ dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
+ dac_ctrl = dac_ctrl & 0xc7f;
+ dac_ctrl = dac_ctrl | (dac_gain << 7);
+ mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
+
+}
+
+static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable)
+{
+ uint16 bit = bEnable ? 1 : 0;
+
+ mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
+
+ mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
+}
+
+static uint16 wlc_lcnphy_get_pa_gain(phy_info_t *pi)
+{
+ uint16 pa_gain;
+
+ pa_gain = (read_phy_reg(pi, 0x4fb) &
+ LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
+ LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
+
+ return pa_gain;
+}
+
+static void
+wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains)
+{
+ uint16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
+
+ mod_phy_reg(pi, 0x4b5,
+ (0xffff << 0),
+ ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+ 0);
+ mod_phy_reg(pi, 0x4fb,
+ (0x7fff << 0),
+ ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+
+ mod_phy_reg(pi, 0x4fc,
+ (0xffff << 0),
+ ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+ 0);
+ mod_phy_reg(pi, 0x4fd,
+ (0x7fff << 0),
+ ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+
+ wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
+
+ wlc_lcnphy_enable_tx_gain_override(pi);
+}
+
+static void wlc_lcnphy_set_bbmult(phy_info_t *pi, uint8 m0)
+{
+ uint16 m0m1 = (uint16) m0 << 8;
+ phytbl_info_t tab;
+
+ tab.tbl_ptr = &m0m1;
+ tab.tbl_len = 1;
+ tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+ tab.tbl_offset = 87;
+ tab.tbl_width = 16;
+ wlc_lcnphy_write_table(pi, &tab);
+}
+
+static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi)
+{
+ uint32 data_buf[64];
+ phytbl_info_t tab;
+
+ bzero(data_buf, sizeof(data_buf));
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = data_buf;
+
+ if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+
+ tab.tbl_len = 30;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+
+ tab.tbl_len = 64;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
+ wlc_lcnphy_write_table(pi, &tab);
+}
+
+typedef enum {
+ LCNPHY_TSSI_PRE_PA,
+ LCNPHY_TSSI_POST_PA,
+ LCNPHY_TSSI_EXT
+} lcnphy_tssi_mode_t;
+
+static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos)
+{
+ mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
+
+ mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
+
+ if (LCNPHY_TSSI_POST_PA == pos) {
+ mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+ } else {
+ mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+ }
+ } else {
+ mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
+
+ mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+ } else {
+ mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+ }
+ }
+ mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
+
+ if (LCNPHY_TSSI_EXT == pos) {
+ write_radio_reg(pi, RADIO_2064_REG07F, 1);
+ mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
+ mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
+ }
+}
+
+static uint16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi)
+{
+ uint16 N1, N2, N3, N4, N5, N6, N;
+ N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
+ >> 0);
+ N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
+ >> 12);
+ N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
+ >> 0);
+ N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
+ >> 8);
+ N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
+ >> 0);
+ N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
+ >> 8);
+ N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
+ if (N < 1600)
+ N = 1600;
+ return N;
+}
+
+static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi)
+{
+ uint16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ auxpga_vmid =
+ (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
+ auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
+ auxpga_gain_temp = 2;
+
+ mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
+
+ mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
+
+ mod_phy_reg(pi, 0x4db,
+ (0x3ff << 0) |
+ (0x7 << 12),
+ (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+
+ mod_phy_reg(pi, 0x4dc,
+ (0x3ff << 0) |
+ (0x7 << 12),
+ (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+
+ mod_phy_reg(pi, 0x40a,
+ (0x3ff << 0) |
+ (0x7 << 12),
+ (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+
+ mod_phy_reg(pi, 0x40b,
+ (0x3ff << 0) |
+ (0x7 << 12),
+ (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+
+ mod_phy_reg(pi, 0x40c,
+ (0x3ff << 0) |
+ (0x7 << 12),
+ (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+
+ mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+}
+
+static void wlc_lcnphy_tssi_setup(phy_info_t *pi)
+{
+ phytbl_info_t tab;
+ uint32 rfseq, ind;
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = &ind;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 0;
+ for (ind = 0; ind < 128; ind++) {
+ wlc_lcnphy_write_table(pi, &tab);
+ tab.tbl_offset++;
+ }
+ tab.tbl_offset = 704;
+ for (ind = 0; ind < 128; ind++) {
+ wlc_lcnphy_write_table(pi, &tab);
+ tab.tbl_offset++;
+ }
+ mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
+
+ wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+ mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
+
+ mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+
+ mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
+
+ mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+
+ mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+
+ mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+
+ mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+
+ mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
+
+ mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+
+ mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
+
+ mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
+
+ mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
+
+ wlc_lcnphy_clear_tx_power_offsets(pi);
+
+ mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+
+ mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
+
+ mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+ mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+ } else {
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
+ }
+
+ write_radio_reg(pi, RADIO_2064_REG025, 0xc);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+ } else {
+ if (CHSPEC_IS2G(pi->radio_chanspec))
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+ else
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
+ }
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+ else
+ mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
+
+ mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
+
+ mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
+
+ if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+ mod_phy_reg(pi, 0x4d7,
+ (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
+ }
+
+ rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &rfseq;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 6;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+
+ mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
+
+ wlc_lcnphy_pwrctrl_rssiparams(pi);
+}
+
+void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi)
+{
+ uint16 tx_cnt, tx_total, npt;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ tx_total = wlc_lcnphy_total_tx_frames(pi);
+ tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
+ npt = wlc_lcnphy_get_tx_pwr_npt(pi);
+
+ if (tx_cnt > (1 << npt)) {
+
+ pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
+
+ pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+ pi_lcn->lcnphy_tssi_npt = npt;
+
+ }
+}
+
+int32 wlc_lcnphy_tssi2dbm(int32 tssi, int32 a1, int32 b0, int32 b1)
+{
+ int32 a, b, p;
+
+ a = 32768 + (a1 * tssi);
+ b = (1024 * b0) + (64 * b1 * tssi);
+ p = ((2 * b) + a) / (2 * a);
+
+ return p;
+}
+
+static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi)
+{
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+ return;
+
+ pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
+ pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
+}
+
+void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi)
+{
+ phytbl_info_t tab;
+ uint32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM +
+ WLC_NUM_RATES_MCS_1_STREAM];
+ uint i, j;
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+ return;
+
+ for (i = 0, j = 0; i < ARRAYSIZE(rate_table); i++, j++) {
+
+ if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM)
+ j = TXP_FIRST_MCS_20_SISO;
+
+ rate_table[i] = (uint32) ((int32) (-pi->tx_power_offset[j]));
+ }
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_len = ARRAYSIZE(rate_table);
+ tab.tbl_ptr = rate_table;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
+ wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
+
+ wlc_lcnphy_txpower_reset_npt(pi);
+ }
+}
+
+static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, int8 index)
+{
+ uint32 cck_offset[4] = { 22, 22, 22, 22 };
+ uint32 ofdm_offset, reg_offset_cck;
+ int i;
+ uint16 index2;
+ phytbl_info_t tab;
+
+ if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+ return;
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
+
+ or_phy_reg(pi, 0x6da, 0x0040);
+
+ reg_offset_cck = 0;
+ for (i = 0; i < 4; i++)
+ cck_offset[i] -= reg_offset_cck;
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_len = 4;
+ tab.tbl_ptr = cck_offset;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+ wlc_lcnphy_write_table(pi, &tab);
+ ofdm_offset = 0;
+ tab.tbl_len = 1;
+ tab.tbl_ptr = &ofdm_offset;
+ for (i = 836; i < 862; i++) {
+ tab.tbl_offset = i;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
+
+ mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
+
+ mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
+
+ index2 = (uint16) (index * 2);
+ mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+
+ mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
+
+}
+
+static int8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi)
+{
+ int8 index, delta_brd, delta_temp, new_index, tempcorrx;
+ int16 manp, meas_temp, temp_diff;
+ bool neg = 0;
+ uint16 temp;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+ return pi_lcn->lcnphy_current_index;
+
+ index = FIXED_TXPWR;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return index;
+
+ if (pi_lcn->lcnphy_tempsense_slope == 0) {
+ return index;
+ }
+ temp = (uint16) wlc_lcnphy_tempsense(pi, 0);
+ meas_temp = LCNPHY_TEMPSENSE(temp);
+
+ if (pi->tx_power_min != 0) {
+ delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
+ } else {
+ delta_brd = 0;
+ }
+
+ manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
+ temp_diff = manp - meas_temp;
+ if (temp_diff < 0) {
+
+ neg = 1;
+
+ temp_diff = -temp_diff;
+ }
+
+ delta_temp = (int8) wlc_lcnphy_qdiv_roundup((uint32) (temp_diff * 192),
+ (uint32) (pi_lcn->
+ lcnphy_tempsense_slope
+ * 10), 0);
+ if (neg)
+ delta_temp = -delta_temp;
+
+ if (pi_lcn->lcnphy_tempsense_option == 3
+ && LCNREV_IS(pi->pubpi.phy_rev, 0))
+ delta_temp = 0;
+ if (pi_lcn->lcnphy_tempcorrx > 31)
+ tempcorrx = (int8) (pi_lcn->lcnphy_tempcorrx - 64);
+ else
+ tempcorrx = (int8) pi_lcn->lcnphy_tempcorrx;
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+ tempcorrx = 4;
+ new_index =
+ index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
+ new_index += tempcorrx;
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+ index = 127;
+ if (new_index < 0 || new_index > 126) {
+ return index;
+ }
+ return new_index;
+}
+
+static uint16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, uint16 mode)
+{
+
+ uint16 current_mode = mode;
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
+ mode == LCNPHY_TX_PWR_CTRL_HW)
+ current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
+ if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+ mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
+ current_mode = LCNPHY_TX_PWR_CTRL_HW;
+ return current_mode;
+}
+
+void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, uint16 mode)
+{
+ uint16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ int8 index;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ ASSERT((LCNPHY_TX_PWR_CTRL_OFF == mode) ||
+ (LCNPHY_TX_PWR_CTRL_SW == mode) ||
+ (LCNPHY_TX_PWR_CTRL_HW == mode) ||
+ (LCNPHY_TX_PWR_CTRL_TEMPBASED == mode));
+
+ mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
+ old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 6),
+ ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
+
+ mod_phy_reg(pi, 0x6a3, (0x1 << 4),
+ ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
+
+ if (old_mode != mode) {
+ if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
+
+ wlc_lcnphy_tx_pwr_update_npt(pi);
+
+ wlc_lcnphy_clear_tx_power_offsets(pi);
+ }
+ if (LCNPHY_TX_PWR_CTRL_HW == mode) {
+
+ wlc_lcnphy_txpower_recalc_target(pi);
+
+ wlc_lcnphy_set_start_tx_pwr_idx(pi,
+ pi_lcn->
+ lcnphy_tssi_idx);
+ wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
+ mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
+
+ pi_lcn->lcnphy_tssi_tx_cnt =
+ wlc_lcnphy_total_tx_frames(pi);
+
+ wlc_lcnphy_disable_tx_gain_override(pi);
+ pi_lcn->lcnphy_tx_power_idx_override = -1;
+ } else
+ wlc_lcnphy_enable_tx_gain_override(pi);
+
+ mod_phy_reg(pi, 0x4a4,
+ ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
+ if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
+ index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+ wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
+ pi_lcn->lcnphy_current_index = (int8)
+ ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+ }
+ }
+}
+
+static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi)
+{
+ uint delay_count = 0;
+
+ while (wlc_lcnphy_iqcal_active(pi)) {
+ OSL_DELAY(100);
+ delay_count++;
+
+ if (delay_count > (10 * 500))
+ break;
+ }
+
+ return (0 == wlc_lcnphy_iqcal_active(pi));
+}
+
+static void
+wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi,
+ lcnphy_txgains_t *target_gains,
+ lcnphy_cal_mode_t cal_mode, bool keep_tone)
+{
+
+ lcnphy_txgains_t cal_gains, temp_gains;
+ uint16 hash;
+ uint8 band_idx;
+ int j;
+ uint16 ncorr_override[5];
+ uint16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ uint16 commands_fullcal[] = {
+ 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+
+ uint16 commands_recal[] = {
+ 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+
+ uint16 command_nums_fullcal[] = {
+ 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+
+ uint16 command_nums_recal[] = {
+ 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+ uint16 *command_nums = command_nums_fullcal;
+
+ uint16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
+ uint16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
+ uint16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
+ bool tx_gain_override_old;
+ lcnphy_txgains_t old_gains;
+ uint i, n_cal_cmds = 0, n_cal_start = 0;
+ uint16 *values_to_save;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ values_to_save = MALLOC(pi->sh->osh, sizeof(uint16) * 20);
+ if (NULL == values_to_save) {
+ return;
+ }
+
+ save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+ save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+
+ or_phy_reg(pi, 0x6da, 0x40);
+ or_phy_reg(pi, 0x6db, 0x3);
+
+ switch (cal_mode) {
+ case LCNPHY_CAL_FULL:
+ start_coeffs = syst_coeffs;
+ cal_cmds = commands_fullcal;
+ n_cal_cmds = ARRAYSIZE(commands_fullcal);
+ break;
+
+ case LCNPHY_CAL_RECAL:
+ ASSERT(pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid);
+
+ start_coeffs = syst_coeffs;
+
+ cal_cmds = commands_recal;
+ n_cal_cmds = ARRAYSIZE(commands_recal);
+ command_nums = command_nums_recal;
+ break;
+ default:
+ ASSERT(FALSE);
+ }
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ start_coeffs, 11, 16, 64);
+
+ write_phy_reg(pi, 0x6da, 0xffff);
+ mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
+
+ tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+
+ save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
+
+ mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
+
+ mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
+
+ wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
+
+ tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+ if (tx_gain_override_old)
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+
+ if (!target_gains) {
+ if (!tx_gain_override_old)
+ wlc_lcnphy_set_tx_pwr_by_index(pi,
+ pi_lcn->lcnphy_tssi_idx);
+ wlc_lcnphy_get_tx_gain(pi, &temp_gains);
+ target_gains = &temp_gains;
+ }
+
+ hash = (target_gains->gm_gain << 8) |
+ (target_gains->pga_gain << 4) | (target_gains->pad_gain);
+
+ band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+
+ cal_gains = *target_gains;
+ bzero(ncorr_override, sizeof(ncorr_override));
+ for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
+ if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
+ cal_gains.gm_gain =
+ tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
+ cal_gains.pga_gain =
+ tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
+ cal_gains.pad_gain =
+ tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
+ bcopy(&tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
+ ncorr_override, sizeof(ncorr_override));
+ break;
+ }
+ }
+
+ wlc_lcnphy_set_tx_gain(pi, &cal_gains);
+
+ write_phy_reg(pi, 0x453, 0xaa9);
+ write_phy_reg(pi, 0x93d, 0xc0);
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ (CONST void *)
+ lcnphy_iqcal_loft_gainladder,
+ ARRAYSIZE(lcnphy_iqcal_loft_gainladder),
+ 16, 0);
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ (CONST void *)lcnphy_iqcal_ir_gainladder,
+ ARRAYSIZE(lcnphy_iqcal_ir_gainladder), 16,
+ 32);
+
+ if (pi->phy_tx_tone_freq) {
+
+ wlc_lcnphy_stop_tx_tone(pi);
+ OSL_DELAY(5);
+ wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+ } else {
+ wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+ }
+
+ write_phy_reg(pi, 0x6da, 0xffff);
+
+ for (i = n_cal_start; i < n_cal_cmds; i++) {
+ uint16 zero_diq = 0;
+ uint16 best_coeffs[11];
+ uint16 command_num;
+
+ cal_type = (cal_cmds[i] & 0x0f00) >> 8;
+
+ command_num = command_nums[i];
+ if (ncorr_override[cal_type])
+ command_num =
+ ncorr_override[cal_type] << 8 | (command_num &
+ 0xff);
+
+ write_phy_reg(pi, 0x452, command_num);
+
+ if ((cal_type == 3) || (cal_type == 4)) {
+
+ wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ &diq_start, 1, 16, 69);
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ &zero_diq, 1, 16, 69);
+ }
+
+ write_phy_reg(pi, 0x451, cal_cmds[i]);
+
+ if (!wlc_lcnphy_iqcal_wait(pi)) {
+
+ goto cleanup;
+ }
+
+ wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ best_coeffs,
+ ARRAYSIZE(best_coeffs), 16, 96);
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ best_coeffs,
+ ARRAYSIZE(best_coeffs), 16, 64);
+
+ if ((cal_type == 3) || (cal_type == 4)) {
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ &diq_start, 1, 16, 69);
+ }
+ wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ pi_lcn->lcnphy_cal_results.
+ txiqlocal_bestcoeffs,
+ ARRAYSIZE(pi_lcn->
+ lcnphy_cal_results.
+ txiqlocal_bestcoeffs),
+ 16, 96);
+ }
+
+ wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ pi_lcn->lcnphy_cal_results.
+ txiqlocal_bestcoeffs,
+ ARRAYSIZE(pi_lcn->lcnphy_cal_results.
+ txiqlocal_bestcoeffs), 16, 96);
+ pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = TRUE;
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ &pi_lcn->lcnphy_cal_results.
+ txiqlocal_bestcoeffs[0], 4, 16, 80);
+
+ wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+ &pi_lcn->lcnphy_cal_results.
+ txiqlocal_bestcoeffs[5], 2, 16, 85);
+
+ cleanup:
+ wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
+ MFREE(pi->sh->osh, values_to_save, 20 * sizeof(uint16));
+
+ if (!keep_tone)
+ wlc_lcnphy_stop_tx_tone(pi);
+
+ write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
+
+ write_phy_reg(pi, 0x453, 0);
+
+ if (tx_gain_override_old)
+ wlc_lcnphy_set_tx_gain(pi, &old_gains);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
+
+ write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
+ write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
+
+}
+
+static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi)
+{
+ bool suspend, tx_gain_override_old;
+ lcnphy_txgains_t old_gains;
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
+ idleTssi0_regvalue_2C;
+ uint16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ uint16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
+ uint16 SAVE_jtag_bb_afe_switch =
+ read_radio_reg(pi, RADIO_2064_REG007) & 1;
+ uint16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
+ uint16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+ idleTssi = read_phy_reg(pi, 0x4ab);
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &((phy_info_t *) pi)->regs->maccontrol) &
+ MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+
+ tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+
+ wlc_lcnphy_enable_tx_gain_override(pi);
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+ write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+ mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
+ mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
+ mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
+ wlc_lcnphy_tssi_setup(pi);
+ wlc_phy_do_dummy_tx(pi, TRUE, OFF);
+ idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+ >> 0);
+
+ idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
+ >> 0);
+
+ if (idleTssi0_2C >= 256)
+ idleTssi0_OB = idleTssi0_2C - 256;
+ else
+ idleTssi0_OB = idleTssi0_2C + 256;
+
+ idleTssi0_regvalue_OB = idleTssi0_OB;
+ if (idleTssi0_regvalue_OB >= 256)
+ idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
+ else
+ idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
+ mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
+
+ wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
+ wlc_lcnphy_set_tx_gain(pi, &old_gains);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+
+ write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
+ mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
+ mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
+ mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
+ mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, uint8 mode)
+{
+ bool suspend;
+ uint16 save_txpwrCtrlEn;
+ uint8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
+ uint16 auxpga_vmid;
+ phytbl_info_t tab;
+ uint32 val;
+ uint8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
+ save_reg112;
+ uint16 values_to_save[14];
+ int8 index;
+ int i;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+ OSL_DELAY(999);
+
+ save_reg007 = (uint8) read_radio_reg(pi, RADIO_2064_REG007);
+ save_reg0FF = (uint8) read_radio_reg(pi, RADIO_2064_REG0FF);
+ save_reg11F = (uint8) read_radio_reg(pi, RADIO_2064_REG11F);
+ save_reg005 = (uint8) read_radio_reg(pi, RADIO_2064_REG005);
+ save_reg025 = (uint8) read_radio_reg(pi, RADIO_2064_REG025);
+ save_reg112 = (uint8) read_radio_reg(pi, RADIO_2064_REG112);
+
+ for (i = 0; i < 14; i++)
+ values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+ index = pi_lcn->lcnphy_current_index;
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+ mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
+ mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
+ mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
+ mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
+
+ mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+
+ mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+
+ mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+
+ mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+
+ mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+
+ mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
+
+ mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+
+ mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
+
+ mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
+
+ mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
+
+ mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
+
+ mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
+
+ mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
+
+ mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+
+ write_radio_reg(pi, RADIO_2064_REG025, 0xC);
+
+ mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
+
+ mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+
+ mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+
+ val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_len = 1;
+ tab.tbl_ptr = &val;
+ tab.tbl_offset = 6;
+ wlc_lcnphy_write_table(pi, &tab);
+ if (mode == TEMPSENSE) {
+ mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+
+ mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
+
+ auxpga_vmidcourse = 8;
+ auxpga_vmidfine = 0x4;
+ auxpga_gain = 2;
+ mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
+ } else {
+ mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+
+ mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
+
+ auxpga_vmidcourse = 7;
+ auxpga_vmidfine = 0xa;
+ auxpga_gain = 2;
+ }
+ auxpga_vmid =
+ (uint16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
+ mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
+
+ mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
+
+ mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
+
+ mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
+
+ write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+
+ wlc_phy_do_dummy_tx(pi, TRUE, OFF);
+ if (!tempsense_done(pi))
+ OSL_DELAY(10);
+
+ write_radio_reg(pi, RADIO_2064_REG007, (uint16) save_reg007);
+ write_radio_reg(pi, RADIO_2064_REG0FF, (uint16) save_reg0FF);
+ write_radio_reg(pi, RADIO_2064_REG11F, (uint16) save_reg11F);
+ write_radio_reg(pi, RADIO_2064_REG005, (uint16) save_reg005);
+ write_radio_reg(pi, RADIO_2064_REG025, (uint16) save_reg025);
+ write_radio_reg(pi, RADIO_2064_REG112, (uint16) save_reg112);
+ for (i = 0; i < 14; i++)
+ write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
+ wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
+
+ write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ OSL_DELAY(999);
+}
+
+void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi)
+{
+ lcnphy_txgains_t tx_gains;
+ uint8 bbmult;
+ phytbl_info_t tab;
+ int32 a1, b0, b1;
+ int32 tssi, pwr, maxtargetpwr, mintargetpwr;
+ bool suspend;
+ phy_info_t *pi = (phy_info_t *) ppi;
+
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+ wlc_lcnphy_set_bbmult(pi, 0x30);
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ return;
+ }
+
+ if (!pi->hwpwrctrl_capable) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ tx_gains.gm_gain = 4;
+ tx_gains.pga_gain = 12;
+ tx_gains.pad_gain = 12;
+ tx_gains.dac_gain = 0;
+
+ bbmult = 150;
+ } else {
+ tx_gains.gm_gain = 7;
+ tx_gains.pga_gain = 15;
+ tx_gains.pad_gain = 14;
+ tx_gains.dac_gain = 0;
+
+ bbmult = 150;
+ }
+ wlc_lcnphy_set_tx_gain(pi, &tx_gains);
+ wlc_lcnphy_set_bbmult(pi, bbmult);
+ wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+ } else {
+
+ wlc_lcnphy_idle_tssi_est(ppi);
+
+ wlc_lcnphy_clear_tx_power_offsets(pi);
+
+ b0 = pi->txpa_2g[0];
+ b1 = pi->txpa_2g[1];
+ a1 = pi->txpa_2g[2];
+ maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+ mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = &pwr;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 0;
+ for (tssi = 0; tssi < 128; tssi++) {
+ pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+
+ pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+ wlc_lcnphy_write_table(pi, &tab);
+ tab.tbl_offset++;
+ }
+
+ mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
+
+ write_phy_reg(pi, 0x4a8, 10);
+
+ wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+ }
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+static uint8 wlc_lcnphy_get_bbmult(phy_info_t *pi)
+{
+ uint16 m0m1;
+ phytbl_info_t tab;
+
+ tab.tbl_ptr = &m0m1;
+ tab.tbl_len = 1;
+ tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+ tab.tbl_offset = 87;
+ tab.tbl_width = 16;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ return (uint8) ((m0m1 & 0xff00) >> 8);
+}
+
+static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, uint16 gain)
+{
+ mod_phy_reg(pi, 0x4fb,
+ LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
+ gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
+ mod_phy_reg(pi, 0x4fd,
+ LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
+ gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
+}
+
+void
+wlc_lcnphy_get_radio_loft(phy_info_t *pi,
+ uint8 *ei0, uint8 *eq0, uint8 *fi0, uint8 *fq0)
+{
+ *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
+ *eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
+ *fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
+ *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
+}
+
+static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains)
+{
+ uint16 dac_gain;
+
+ dac_gain = read_phy_reg(pi, 0x439) >> 0;
+ gains->dac_gain = (dac_gain & 0x380) >> 7;
+
+ {
+ uint16 rfgain0, rfgain1;
+
+ rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
+ rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
+
+ gains->gm_gain = rfgain0 & 0xff;
+ gains->pga_gain = (rfgain0 >> 8) & 0xff;
+ gains->pad_gain = rfgain1 & 0xff;
+ }
+}
+
+void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, uint16 a, uint16 b)
+{
+ phytbl_info_t tab;
+ uint16 iqcc[2];
+
+ iqcc[0] = a;
+ iqcc[1] = b;
+
+ tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = iqcc;
+ tab.tbl_len = 2;
+ tab.tbl_offset = 80;
+ wlc_lcnphy_write_table(pi, &tab);
+}
+
+void wlc_lcnphy_set_tx_locc(phy_info_t *pi, uint16 didq)
+{
+ phytbl_info_t tab;
+
+ tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &didq;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 85;
+ wlc_lcnphy_write_table(pi, &tab);
+}
+
+void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index)
+{
+ phytbl_info_t tab;
+ uint16 a, b;
+ uint8 bb_mult;
+ uint32 bbmultiqcomp, txgain, locoeffs, rfpower;
+ lcnphy_txgains_t gains;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ ASSERT(index <= LCNPHY_MAX_TX_POWER_INDEX);
+
+ pi_lcn->lcnphy_tx_power_idx_override = (int8) index;
+ pi_lcn->lcnphy_current_index = (uint8) index;
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_len = 1;
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+ tab.tbl_ptr = &bbmultiqcomp;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = &txgain;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ gains.gm_gain = (uint16) (txgain & 0xff);
+ gains.pga_gain = (uint16) (txgain >> 8) & 0xff;
+ gains.pad_gain = (uint16) (txgain >> 16) & 0xff;
+ gains.dac_gain = (uint16) (bbmultiqcomp >> 28) & 0x07;
+ wlc_lcnphy_set_tx_gain(pi, &gains);
+ wlc_lcnphy_set_pa_gain(pi, (uint16) (txgain >> 24) & 0x7f);
+
+ bb_mult = (uint8) ((bbmultiqcomp >> 20) & 0xff);
+ wlc_lcnphy_set_bbmult(pi, bb_mult);
+
+ wlc_lcnphy_enable_tx_gain_override(pi);
+
+ if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+
+ a = (uint16) ((bbmultiqcomp >> 10) & 0x3ff);
+ b = (uint16) (bbmultiqcomp & 0x3ff);
+ wlc_lcnphy_set_tx_iqcc(pi, a, b);
+
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
+ tab.tbl_ptr = &locoeffs;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ wlc_lcnphy_set_tx_locc(pi, (uint16) locoeffs);
+
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+ tab.tbl_ptr = &rfpower;
+ wlc_lcnphy_read_table(pi, &tab);
+ mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
+
+ }
+}
+
+static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx)
+{
+
+ mod_phy_reg(pi, 0x44d,
+ (0x1 << 1) |
+ (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
+
+ or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
+}
+
+static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi)
+{
+ uint32 j;
+ phytbl_info_t tab;
+ uint32 temp_offset[128];
+ tab.tbl_ptr = temp_offset;
+ tab.tbl_len = 128;
+ tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
+ tab.tbl_width = 32;
+ tab.tbl_offset = 0;
+
+ bzero(temp_offset, sizeof(temp_offset));
+ for (j = 1; j < 128; j += 2)
+ temp_offset[j] = 0x80000;
+
+ wlc_lcnphy_write_table(pi, &tab);
+ return;
+}
+
+static void
+wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+ uint16 trsw,
+ uint16 ext_lna,
+ uint16 biq2,
+ uint16 biq1,
+ uint16 tia, uint16 lna2, uint16 lna1)
+{
+ uint16 gain0_15, gain16_19;
+
+ gain16_19 = biq2 & 0xf;
+ gain0_15 = ((biq1 & 0xf) << 12) |
+ ((tia & 0xf) << 8) |
+ ((lna2 & 0x3) << 6) |
+ ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+
+ mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+ mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+ mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+
+ if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+ mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+ mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+ } else {
+ mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
+
+ mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
+
+ mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+ }
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+
+}
+
+static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable)
+{
+ uint16 ebit = enable ? 1 : 0;
+
+ mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
+
+ if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+ mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
+ mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
+ mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+ mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
+ } else {
+ mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
+ mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
+ mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
+ mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
+ }
+}
+
+void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable)
+{
+ if (!bEnable) {
+
+ and_phy_reg(pi, 0x43b, ~(uint16) ((0x1 << 1) | (0x1 << 4)));
+
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
+
+ and_phy_reg(pi, 0x44c,
+ ~(uint16) ((0x1 << 3) |
+ (0x1 << 5) |
+ (0x1 << 12) |
+ (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+
+ and_phy_reg(pi, 0x44d,
+ ~(uint16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
+ mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
+
+ and_phy_reg(pi, 0x4f9,
+ ~(uint16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+
+ and_phy_reg(pi, 0x4fa,
+ ~(uint16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+ } else {
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
+ mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+ mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+
+ wlc_lcnphy_set_trsw_override(pi, TRUE, FALSE);
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+ mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
+ } else {
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+ mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+ }
+ }
+}
+
+static void
+wlc_lcnphy_run_samples(phy_info_t *pi,
+ uint16 num_samps,
+ uint16 num_loops, uint16 wait, bool iqcalmode)
+{
+
+ or_phy_reg(pi, 0x6da, 0x8080);
+
+ mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
+ if (num_loops != 0xffff)
+ num_loops--;
+ mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
+
+ mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
+
+ if (iqcalmode) {
+
+ and_phy_reg(pi, 0x453, (uint16) ~(0x1 << 15));
+ or_phy_reg(pi, 0x453, (0x1 << 15));
+ } else {
+ write_phy_reg(pi, 0x63f, 1);
+ wlc_lcnphy_tx_pu(pi, 1);
+ }
+
+ or_radio_reg(pi, RADIO_2064_REG112, 0x6);
+}
+
+void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode)
+{
+
+ uint8 phybw40;
+ phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+
+ if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+ mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+ mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+ } else {
+ mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+ mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+ }
+
+ if (phybw40 == 0) {
+ mod_phy_reg((pi), 0x410,
+ (0x1 << 6) |
+ (0x1 << 5),
+ ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) <<
+ 6 | (!mode) << 5);
+ mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
+ }
+}
+
+void
+wlc_lcnphy_start_tx_tone(phy_info_t *pi, int32 f_kHz, uint16 max_val,
+ bool iqcalmode)
+{
+ uint8 phy_bw;
+ uint16 num_samps, t, k;
+ uint32 bw;
+ fixed theta = 0, rot = 0;
+ cint32 tone_samp;
+ uint32 data_buf[64];
+ uint16 i_samp, q_samp;
+ phytbl_info_t tab;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ pi->phy_tx_tone_freq = f_kHz;
+
+ wlc_lcnphy_deaf_mode(pi, TRUE);
+
+ phy_bw = 40;
+ if (pi_lcn->lcnphy_spurmod) {
+ write_phy_reg(pi, 0x942, 0x2);
+ write_phy_reg(pi, 0x93b, 0x0);
+ write_phy_reg(pi, 0x93c, 0x0);
+ wlc_lcnphy_txrx_spur_avoidance_mode(pi, FALSE);
+ }
+
+ if (f_kHz) {
+ k = 1;
+ do {
+ bw = phy_bw * 1000 * k;
+ num_samps = bw / ABS(f_kHz);
+ ASSERT(num_samps <= ARRAYSIZE(data_buf));
+ k++;
+ } while ((num_samps * (uint32) (ABS(f_kHz))) != bw);
+ } else
+ num_samps = 2;
+
+ rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+ theta = 0;
+
+ for (t = 0; t < num_samps; t++) {
+
+ wlc_phy_cordic(theta, &tone_samp);
+
+ theta += rot;
+
+ i_samp = (uint16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
+ q_samp = (uint16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
+ data_buf[t] = (i_samp << 10) | q_samp;
+ }
+
+ mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
+
+ tab.tbl_ptr = data_buf;
+ tab.tbl_len = num_samps;
+ tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
+ tab.tbl_offset = 0;
+ tab.tbl_width = 32;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
+}
+
+void wlc_lcnphy_stop_tx_tone(phy_info_t *pi)
+{
+ int16 playback_status;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ pi->phy_tx_tone_freq = 0;
+ if (pi_lcn->lcnphy_spurmod) {
+ write_phy_reg(pi, 0x942, 0x7);
+ write_phy_reg(pi, 0x93b, 0x2017);
+ write_phy_reg(pi, 0x93c, 0x27c5);
+ wlc_lcnphy_txrx_spur_avoidance_mode(pi, TRUE);
+ }
+
+ playback_status = read_phy_reg(pi, 0x644);
+ if (playback_status & (0x1 << 0)) {
+ wlc_lcnphy_tx_pu(pi, 0);
+ mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
+ } else if (playback_status & (0x1 << 1))
+ mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
+
+ mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
+
+ and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
+
+ wlc_lcnphy_deaf_mode(pi, FALSE);
+}
+
+static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi)
+{
+
+ and_phy_reg(pi, 0x44c, (uint16) ~((0x1 << 1) | (0x1 << 0)));
+}
+
+void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, uint16 *a, uint16 *b)
+{
+ uint16 iqcc[2];
+ phytbl_info_t tab;
+
+ tab.tbl_ptr = iqcc;
+ tab.tbl_len = 2;
+ tab.tbl_id = 0;
+ tab.tbl_offset = 80;
+ tab.tbl_width = 16;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ *a = iqcc[0];
+ *b = iqcc[1];
+}
+
+uint16 wlc_lcnphy_get_tx_locc(phy_info_t *pi)
+{
+ phytbl_info_t tab;
+ uint16 didq;
+
+ tab.tbl_id = 0;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &didq;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 85;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ return didq;
+}
+
+static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi)
+{
+
+ lcnphy_txgains_t target_gains, old_gains;
+ uint8 save_bb_mult;
+ uint16 a, b, didq, save_pa_gain = 0;
+ uint idx, SAVE_txpwrindex = 0xFF;
+ uint32 val;
+ uint16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ phytbl_info_t tab;
+ uint8 ei0, eq0, fi0, fq0;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+ save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
+
+ save_bb_mult = wlc_lcnphy_get_bbmult(pi);
+
+ if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
+ SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+
+ target_gains.gm_gain = 7;
+ target_gains.pga_gain = 0;
+ target_gains.pad_gain = 21;
+ target_gains.dac_gain = 0;
+ wlc_lcnphy_set_tx_gain(pi, &target_gains);
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
+
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
+
+ wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+ (pi_lcn->
+ lcnphy_recal ? LCNPHY_CAL_RECAL :
+ LCNPHY_CAL_FULL), FALSE);
+ } else {
+
+ wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+ }
+
+ wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
+ if ((ABS((int8) fi0) == 15) && (ABS((int8) fq0) == 15)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ target_gains.gm_gain = 255;
+ target_gains.pga_gain = 255;
+ target_gains.pad_gain = 0xf0;
+ target_gains.dac_gain = 0;
+ } else {
+ target_gains.gm_gain = 7;
+ target_gains.pga_gain = 45;
+ target_gains.pad_gain = 186;
+ target_gains.dac_gain = 0;
+ }
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)
+ || pi_lcn->lcnphy_hw_iqcal_en) {
+
+ target_gains.pga_gain = 0;
+ target_gains.pad_gain = 30;
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+ wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+ LCNPHY_CAL_FULL, FALSE);
+ } else {
+
+ wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+ }
+
+ }
+
+ wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+
+ didq = wlc_lcnphy_get_tx_locc(pi);
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = &val;
+
+ tab.tbl_len = 1;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+
+ for (idx = 0; idx < 128; idx++) {
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
+
+ wlc_lcnphy_read_table(pi, &tab);
+ val = (val & 0xfff00000) |
+ ((uint32) (a & 0x3FF) << 10) | (b & 0x3ff);
+ wlc_lcnphy_write_table(pi, &tab);
+
+ val = didq;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+
+ pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
+ pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
+ pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
+ pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
+ pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
+ pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
+ pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
+
+ wlc_lcnphy_set_bbmult(pi, save_bb_mult);
+ wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
+ wlc_lcnphy_set_tx_gain(pi, &old_gains);
+
+ if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+ else
+ wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
+}
+
+int16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode)
+{
+ uint16 tempsenseval1, tempsenseval2;
+ int16 avg = 0;
+ bool suspend = 0;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return -1;
+
+ if (mode == 1) {
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+ }
+ tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+ tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+
+ if (tempsenseval1 > 255)
+ avg = (int16) (tempsenseval1 - 512);
+ else
+ avg = (int16) tempsenseval1;
+
+ if (tempsenseval2 > 255)
+ avg += (int16) (tempsenseval2 - 512);
+ else
+ avg += (int16) tempsenseval2;
+
+ avg /= 2;
+
+ if (mode == 1) {
+
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+
+ OSL_DELAY(100);
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ }
+ return avg;
+}
+
+uint16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode)
+{
+ uint16 tempsenseval1, tempsenseval2;
+ int32 avg = 0;
+ bool suspend = 0;
+ uint16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return -1;
+
+ if (mode == 1) {
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+ }
+ tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+ tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+
+ if (tempsenseval1 > 255)
+ avg = (int)(tempsenseval1 - 512);
+ else
+ avg = (int)tempsenseval1;
+
+ if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
+ if (tempsenseval2 > 255)
+ avg = (int)(avg - tempsenseval2 + 512);
+ else
+ avg = (int)(avg - tempsenseval2);
+ } else {
+ if (tempsenseval2 > 255)
+ avg = (int)(avg + tempsenseval2 - 512);
+ else
+ avg = (int)(avg + tempsenseval2);
+ avg = avg / 2;
+ }
+ if (avg < 0)
+ avg = avg + 512;
+
+ if (pi_lcn->lcnphy_tempsense_option == 2)
+ avg = tempsenseval1;
+
+ if (mode)
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+
+ if (mode == 1) {
+
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+
+ OSL_DELAY(100);
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ }
+ return (uint16) avg;
+}
+
+int8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode)
+{
+ int32 degree = wlc_lcnphy_tempsense_new(pi, mode);
+ degree =
+ ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
+ / LCN_TEMPSENSE_DEN;
+ return (int8) degree;
+}
+
+int8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode)
+{
+ uint16 vbatsenseval;
+ int32 avg = 0;
+ bool suspend = 0;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return -1;
+
+ if (mode == 1) {
+ suspend =
+ (0 ==
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
+ }
+
+ vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
+
+ if (vbatsenseval > 255)
+ avg = (int32) (vbatsenseval - 512);
+ else
+ avg = (int32) vbatsenseval;
+
+ avg =
+ (avg * LCN_VBAT_SCALE_NOM +
+ (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
+
+ if (mode == 1) {
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+ }
+ return (int8) avg;
+}
+
+static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, uint8 mode)
+{
+ uint8 phybw40;
+ phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+
+ mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
+
+ if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
+ (mode == AFE_CLK_INIT_MODE_TXRX2X))
+ write_phy_reg(pi, 0x6d0, 0x7);
+
+ wlc_lcnphy_toggle_afe_pwdn(pi);
+}
+
+static bool
+wlc_lcnphy_rx_iq_est(phy_info_t *pi,
+ uint16 num_samps,
+ uint8 wait_time, lcnphy_iq_est_t *iq_est)
+{
+ int wait_count = 0;
+ bool result = TRUE;
+ uint8 phybw40;
+ phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
+
+ mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
+
+ mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
+
+ mod_phy_reg(pi, 0x481, (0xff << 0), ((uint16) wait_time) << 0);
+
+ mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
+
+ mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
+
+ while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
+
+ if (wait_count > (10 * 500)) {
+ result = FALSE;
+ goto cleanup;
+ }
+ OSL_DELAY(100);
+ wait_count++;
+ }
+
+ iq_est->iq_prod = ((uint32) read_phy_reg(pi, 0x483) << 16) |
+ (uint32) read_phy_reg(pi, 0x484);
+ iq_est->i_pwr = ((uint32) read_phy_reg(pi, 0x485) << 16) |
+ (uint32) read_phy_reg(pi, 0x486);
+ iq_est->q_pwr = ((uint32) read_phy_reg(pi, 0x487) << 16) |
+ (uint32) read_phy_reg(pi, 0x488);
+
+ cleanup:
+ mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
+
+ mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
+
+ return result;
+}
+
+static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, uint16 num_samps)
+{
+#define LCNPHY_MIN_RXIQ_PWR 2
+ bool result;
+ uint16 a0_new, b0_new;
+ lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+ int32 a, b, temp;
+ int16 iq_nbits, qq_nbits, arsh, brsh;
+ int32 iq;
+ uint32 ii, qq;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
+ b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
+ mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
+
+ wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
+
+ result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
+ if (!result)
+ goto cleanup;
+
+ iq = (int32) iq_est.iq_prod;
+ ii = iq_est.i_pwr;
+ qq = iq_est.q_pwr;
+
+ if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
+ result = FALSE;
+ goto cleanup;
+ }
+
+ iq_nbits = wlc_phy_nbits(iq);
+ qq_nbits = wlc_phy_nbits(qq);
+
+ arsh = 10 - (30 - iq_nbits);
+ if (arsh >= 0) {
+ a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+ temp = (int32) (ii >> arsh);
+ if (temp == 0) {
+ return FALSE;
+ }
+ } else {
+ a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+ temp = (int32) (ii << -arsh);
+ if (temp == 0) {
+ return FALSE;
+ }
+ }
+ a /= temp;
+ brsh = qq_nbits - 31 + 20;
+ if (brsh >= 0) {
+ b = (qq << (31 - qq_nbits));
+ temp = (int32) (ii >> brsh);
+ if (temp == 0) {
+ return FALSE;
+ }
+ } else {
+ b = (qq << (31 - qq_nbits));
+ temp = (int32) (ii << -brsh);
+ if (temp == 0) {
+ return FALSE;
+ }
+ }
+ b /= temp;
+ b -= a * a;
+ b = (int32) wlc_phy_sqrt_int((uint32) b);
+ b -= (1 << 10);
+ a0_new = (uint16) (a & 0x3ff);
+ b0_new = (uint16) (b & 0x3ff);
+ cleanup:
+
+ wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
+
+ mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
+
+ pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
+ pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
+
+ return result;
+}
+
+static bool
+wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp,
+ int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
+ int tx_gain_idx)
+{
+ lcnphy_txgains_t old_gains;
+ uint16 tx_pwr_ctrl;
+ uint8 tx_gain_index_old = 0;
+ bool result = FALSE, tx_gain_override_old = FALSE;
+ uint16 i, Core1TxControl_old, RFOverride0_old,
+ RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
+ rfoverride3_old, rfoverride3val_old, rfoverride4_old,
+ rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
+ int tia_gain;
+ uint32 received_power, rx_pwr_threshold;
+ uint16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
+ uint16 values_to_save[11];
+ int16 *ptr;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ ptr = MALLOC(pi->sh->osh, sizeof(int16) * 131);
+ if (NULL == ptr) {
+ return FALSE;
+ }
+ if (module == 2) {
+ ASSERT(iqcomp_sz);
+
+ while (iqcomp_sz--) {
+ if (iqcomp[iqcomp_sz].chan ==
+ CHSPEC_CHANNEL(pi->radio_chanspec)) {
+
+ wlc_lcnphy_set_rx_iq_comp(pi,
+ (uint16)
+ iqcomp[iqcomp_sz].a,
+ (uint16)
+ iqcomp[iqcomp_sz].b);
+ result = TRUE;
+ break;
+ }
+ }
+ ASSERT(result);
+ goto cal_done;
+ }
+
+ if (module == 1) {
+
+ tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+
+ for (i = 0; i < 11; i++) {
+ values_to_save[i] =
+ read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+ }
+ Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+ or_phy_reg(pi, 0x631, 0x0015);
+
+ RFOverride0_old = read_phy_reg(pi, 0x44c);
+ RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+ rfoverride2_old = read_phy_reg(pi, 0x4b0);
+ rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+ rfoverride3_old = read_phy_reg(pi, 0x4f9);
+ rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+ rfoverride4_old = read_phy_reg(pi, 0x938);
+ rfoverride4val_old = read_phy_reg(pi, 0x939);
+ afectrlovr_old = read_phy_reg(pi, 0x43b);
+ afectrlovrval_old = read_phy_reg(pi, 0x43c);
+ old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+ old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+
+ tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+ if (tx_gain_override_old) {
+ wlc_lcnphy_get_tx_gain(pi, &old_gains);
+ tx_gain_index_old = pi_lcn->lcnphy_current_index;
+ }
+
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+
+ mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+
+ write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+ write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+ write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+ write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+ write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+ mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+ write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+ write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+ write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+ mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+ mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+ mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+ mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+ mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+ wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
+ write_phy_reg(pi, 0x6da, 0xffff);
+ or_phy_reg(pi, 0x6db, 0x3);
+ wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+ wlc_lcnphy_rx_gain_override_enable(pi, TRUE);
+
+ tia_gain = 8;
+ rx_pwr_threshold = 950;
+ while (tia_gain > 0) {
+ tia_gain -= 1;
+ wlc_lcnphy_set_rx_gain_by_distribution(pi,
+ 0, 0, 2, 2,
+ (uint16)
+ tia_gain, 1, 0);
+ OSL_DELAY(500);
+
+ received_power =
+ wlc_lcnphy_measure_digital_power(pi, 2000);
+ if (received_power < rx_pwr_threshold)
+ break;
+ }
+ result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+
+ wlc_lcnphy_stop_tx_tone(pi);
+
+ write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+ write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+ write_phy_reg(pi, 0x4b0, rfoverride2_old);
+ write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+ write_phy_reg(pi, 0x4f9, rfoverride3_old);
+ write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+ write_phy_reg(pi, 0x938, rfoverride4_old);
+ write_phy_reg(pi, 0x939, rfoverride4val_old);
+ write_phy_reg(pi, 0x43b, afectrlovr_old);
+ write_phy_reg(pi, 0x43c, afectrlovrval_old);
+ write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+ write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+
+ wlc_lcnphy_clear_trsw_override(pi);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+
+ for (i = 0; i < 11; i++) {
+ write_radio_reg(pi, rxiq_cal_rf_reg[i],
+ values_to_save[i]);
+ }
+
+ if (tx_gain_override_old) {
+ wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+ } else
+ wlc_lcnphy_disable_tx_gain_override(pi);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+
+ wlc_lcnphy_rx_gain_override_enable(pi, FALSE);
+ }
+
+ cal_done:
+ MFREE(pi->sh->osh, ptr, 131 * sizeof(int16));
+ return result;
+}
+
+static void wlc_lcnphy_temp_adj(phy_info_t *pi)
+{
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+}
+
+static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi)
+{
+ bool suspend;
+ int8 index;
+ uint16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_lcnphy_deaf_mode(pi, TRUE);
+ pi->phy_lastcal = pi->sh->now;
+ pi->phy_forcecal = FALSE;
+ index = pi_lcn->lcnphy_current_index;
+
+ wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+
+ wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+ wlc_lcnphy_deaf_mode(pi, FALSE);
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+
+}
+
+static void wlc_lcnphy_periodic_cal(phy_info_t *pi)
+{
+ bool suspend, full_cal;
+ const lcnphy_rx_iqcomp_t *rx_iqcomp;
+ int rx_iqcomp_sz;
+ uint16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ int8 index;
+ phytbl_info_t tab;
+ int32 a1, b0, b1;
+ int32 tssi, pwr, maxtargetpwr, mintargetpwr;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ pi->phy_lastcal = pi->sh->now;
+ pi->phy_forcecal = FALSE;
+ full_cal =
+ (pi_lcn->lcnphy_full_cal_channel !=
+ CHSPEC_CHANNEL(pi->radio_chanspec));
+ pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+ index = pi_lcn->lcnphy_current_index;
+
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend) {
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ }
+ wlc_lcnphy_deaf_mode(pi, TRUE);
+
+ wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+
+ rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
+ rx_iqcomp_sz = ARRAYSIZE(lcnphy_rx_iqcomp_table_rev0);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+ wlc_lcnphy_rx_iq_cal(pi, NULL, 0, TRUE, FALSE, 1, 40);
+ else
+ wlc_lcnphy_rx_iq_cal(pi, NULL, 0, TRUE, FALSE, 1, 127);
+
+ if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+
+ wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi);
+
+ b0 = pi->txpa_2g[0];
+ b1 = pi->txpa_2g[1];
+ a1 = pi->txpa_2g[2];
+ maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+ mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_ptr = &pwr;
+ tab.tbl_len = 1;
+ tab.tbl_offset = 0;
+ for (tssi = 0; tssi < 128; tssi++) {
+ pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+ pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+ wlc_lcnphy_write_table(pi, &tab);
+ tab.tbl_offset++;
+ }
+ }
+
+ wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+ wlc_lcnphy_deaf_mode(pi, FALSE);
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode)
+{
+ uint16 temp_new;
+ int temp1, temp2, temp_diff;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ switch (mode) {
+ case PHY_PERICAL_CHAN:
+
+ break;
+ case PHY_FULLCAL:
+ wlc_lcnphy_periodic_cal(pi);
+ break;
+ case PHY_PERICAL_PHYINIT:
+ wlc_lcnphy_periodic_cal(pi);
+ break;
+ case PHY_PERICAL_WATCHDOG:
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+ temp_new = wlc_lcnphy_tempsense(pi, 0);
+ temp1 = LCNPHY_TEMPSENSE(temp_new);
+ temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
+ temp_diff = temp1 - temp2;
+ if ((pi_lcn->lcnphy_cal_counter > 90) ||
+ (temp_diff > 60) || (temp_diff < -60)) {
+ wlc_lcnphy_glacial_timer_based_cal(pi);
+ wlc_2064_vco_cal(pi);
+ pi_lcn->lcnphy_cal_temper = temp_new;
+ pi_lcn->lcnphy_cal_counter = 0;
+ } else
+ pi_lcn->lcnphy_cal_counter++;
+ }
+ break;
+ case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+ wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+void wlc_lcnphy_get_tssi(phy_info_t *pi, int8 *ofdm_pwr, int8 *cck_pwr)
+{
+ int8 cck_offset;
+ uint16 status;
+ status = (read_phy_reg(pi, 0x4ab));
+ if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+ (status & (0x1 << 15))) {
+ *ofdm_pwr = (int8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+ >> 0) >> 1);
+
+ if (wlc_phy_tpc_isenabled_lcnphy(pi))
+ cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
+ else
+ cck_offset = 0;
+
+ *cck_pwr = *ofdm_pwr + cck_offset;
+ } else {
+ *cck_pwr = 0;
+ *ofdm_pwr = 0;
+ }
+}
+
+void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi)
+{
+ return;
+
+}
+
+static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec)
+{
+ uint8 channel = CHSPEC_CHANNEL(chanspec);
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ if (channel == 14) {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+
+ } else {
+ mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+
+ }
+ pi_lcn->lcnphy_bandedge_corr = 2;
+ if (channel == 1)
+ pi_lcn->lcnphy_bandedge_corr = 4;
+
+ if (channel == 1 || channel == 2 || channel == 3 ||
+ channel == 4 || channel == 9 ||
+ channel == 10 || channel == 11 || channel == 12) {
+ si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
+ si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
+ si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
+
+ si_pmu_pllupd(pi->sh->sih);
+ write_phy_reg(pi, 0x942, 0);
+ wlc_lcnphy_txrx_spur_avoidance_mode(pi, FALSE);
+ pi_lcn->lcnphy_spurmod = 0;
+ mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
+
+ write_phy_reg(pi, 0x425, 0x5907);
+ } else {
+ si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
+ si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
+ si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
+
+ si_pmu_pllupd(pi->sh->sih);
+ write_phy_reg(pi, 0x942, 0);
+ wlc_lcnphy_txrx_spur_avoidance_mode(pi, TRUE);
+
+ pi_lcn->lcnphy_spurmod = 0;
+ mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
+
+ write_phy_reg(pi, 0x425, 0x590a);
+ }
+
+ or_phy_reg(pi, 0x44a, 0x44);
+ write_phy_reg(pi, 0x44a, 0x80);
+}
+
+void
+wlc_lcnphy_pktengtx(wlc_phy_t *ppi, wl_pkteng_t *pkteng, uint8 rate,
+ struct ether_addr *sa, uint32 wait_delay)
+{
+}
+
+void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi)
+{
+ int8 index;
+ uint16 index2;
+ phy_info_t *pi = (phy_info_t *) ppi;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+ uint16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) {
+ index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+ index2 = (uint16) (index * 2);
+ mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+
+ pi_lcn->lcnphy_current_index = (int8)
+ ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+ }
+}
+
+static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, uint16 a, uint16 b)
+{
+ mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
+
+ mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
+
+ mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
+
+ mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
+
+ mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
+
+ mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
+
+}
+
+void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi)
+{
+ uint8 phybw40;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+ phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+
+ pi_lcn->lcnphy_cal_counter = 0;
+ pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
+
+ or_phy_reg(pi, 0x44a, 0x80);
+ and_phy_reg(pi, 0x44a, 0x7f);
+
+ wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
+
+ write_phy_reg(pi, 0x60a, 160);
+
+ write_phy_reg(pi, 0x46a, 25);
+
+ wlc_lcnphy_baseband_init(pi);
+
+ wlc_lcnphy_radio_init(pi);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec))
+ wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi);
+
+ wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+
+ si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
+
+ si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
+
+ if ((pi->sh->boardflags & BFL_FEM)
+ && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+ wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
+
+ wlc_lcnphy_agc_temp_init(pi);
+
+ wlc_lcnphy_temp_adj(pi);
+
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+
+ OSL_DELAY(100);
+ mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+ pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
+ wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
+}
+
+static void
+wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, uint16 *values_to_save)
+{
+ uint16 vmid;
+ int i;
+ for (i = 0; i < 20; i++) {
+ values_to_save[i] =
+ read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
+ }
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+ mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+
+ mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
+ mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+
+ mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+ and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
+ else
+ and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
+ or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
+
+ or_radio_reg(pi, RADIO_2064_REG036, 0x01);
+ or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
+ OSL_DELAY(20);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec))
+ mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+ else
+ or_radio_reg(pi, RADIO_2064_REG03A, 1);
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec))
+ mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
+ else
+ or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
+ }
+
+ OSL_DELAY(20);
+
+ write_radio_reg(pi, RADIO_2064_REG025, 0xF);
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec))
+ mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
+ else
+ mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec))
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
+ else
+ mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
+ }
+
+ OSL_DELAY(20);
+
+ write_radio_reg(pi, RADIO_2064_REG005, 0x8);
+ or_radio_reg(pi, RADIO_2064_REG112, 0x80);
+ OSL_DELAY(20);
+
+ or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+ or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+ OSL_DELAY(20);
+
+ or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+ or_radio_reg(pi, RADIO_2064_REG113, 0x10);
+ OSL_DELAY(20);
+
+ write_radio_reg(pi, RADIO_2064_REG007, 0x1);
+ OSL_DELAY(20);
+
+ vmid = 0x2A6;
+ mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
+ write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
+ or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+ OSL_DELAY(20);
+
+ or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+ OSL_DELAY(20);
+ write_radio_reg(pi, RADIO_2064_REG012, 0x02);
+ or_radio_reg(pi, RADIO_2064_REG112, 0x06);
+ write_radio_reg(pi, RADIO_2064_REG036, 0x11);
+ write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
+ write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
+ write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
+ write_radio_reg(pi, RADIO_2064_REG092, 0x15);
+}
+
+static void
+wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, uint16 thresh,
+ int16 *ptr, int mode)
+{
+ uint32 curval1, curval2, stpptr, curptr, strptr, val;
+ uint16 sslpnCalibClkEnCtrl, timer;
+ uint16 old_sslpnCalibClkEnCtrl;
+ int16 imag, real;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ timer = 0;
+ old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+
+ curval1 = R_REG(pi->sh->osh, &pi->regs->psm_corectlsts);
+ ptr[130] = 0;
+ W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, ((1 << 6) | curval1));
+
+ W_REG(pi->sh->osh, &pi->regs->smpl_clct_strptr, 0x7E00);
+ W_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr, 0x8000);
+ OSL_DELAY(20);
+ curval2 = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param);
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2 | 0x30);
+
+ write_phy_reg(pi, 0x555, 0x0);
+ write_phy_reg(pi, 0x5a6, 0x5);
+
+ write_phy_reg(pi, 0x5a2, (uint16) (mode | mode << 6));
+ write_phy_reg(pi, 0x5cf, 3);
+ write_phy_reg(pi, 0x5a5, 0x3);
+ write_phy_reg(pi, 0x583, 0x0);
+ write_phy_reg(pi, 0x584, 0x0);
+ write_phy_reg(pi, 0x585, 0x0fff);
+ write_phy_reg(pi, 0x586, 0x0000);
+
+ write_phy_reg(pi, 0x580, 0x4501);
+
+ sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+ write_phy_reg(pi, 0x6da, (uint32) (sslpnCalibClkEnCtrl | 0x2008));
+ stpptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr);
+ curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr);
+ do {
+ OSL_DELAY(10);
+ curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr);
+ timer++;
+ } while ((curptr != stpptr) && (timer < 500));
+
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, 0x2);
+ strptr = 0x7E00;
+ W_REG(pi->sh->osh, &pi->regs->tplatewrptr, strptr);
+ while (strptr < 0x8000) {
+ val = R_REG(pi->sh->osh, &pi->regs->tplatewrdata);
+ imag = ((val >> 16) & 0x3ff);
+ real = ((val) & 0x3ff);
+ if (imag > 511) {
+ imag -= 1024;
+ }
+ if (real > 511) {
+ real -= 1024;
+ }
+ if (pi_lcn->lcnphy_iqcal_swp_dis)
+ ptr[(strptr - 0x7E00) / 4] = real;
+ else
+ ptr[(strptr - 0x7E00) / 4] = imag;
+ if (clip_detect_algo) {
+ if (imag > thresh || imag < -thresh) {
+ strptr = 0x8000;
+ ptr[130] = 1;
+ }
+ }
+ strptr += 4;
+ }
+
+ write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2);
+ W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, curval1);
+}
+
+static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi)
+{
+ lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
+
+ wlc_lcnphy_set_cc(pi, 0, 0, 0);
+ wlc_lcnphy_set_cc(pi, 2, 0, 0);
+ wlc_lcnphy_set_cc(pi, 3, 0, 0);
+ wlc_lcnphy_set_cc(pi, 4, 0, 0);
+
+ wlc_lcnphy_a1(pi, 4, 0, 0);
+ wlc_lcnphy_a1(pi, 3, 0, 0);
+ wlc_lcnphy_a1(pi, 2, 3, 2);
+ wlc_lcnphy_a1(pi, 0, 5, 8);
+ wlc_lcnphy_a1(pi, 2, 2, 1);
+ wlc_lcnphy_a1(pi, 0, 4, 3);
+
+ iqcc0 = wlc_lcnphy_get_cc(pi, 0);
+ locc2 = wlc_lcnphy_get_cc(pi, 2);
+ locc3 = wlc_lcnphy_get_cc(pi, 3);
+ locc4 = wlc_lcnphy_get_cc(pi, 4);
+}
+
+static void
+wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, int16 coeff_x, int16 coeff_y)
+{
+ uint16 di0dq0;
+ uint16 x, y, data_rf;
+ int k;
+ switch (cal_type) {
+ case 0:
+ wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
+ break;
+ case 2:
+ di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
+ wlc_lcnphy_set_tx_locc(pi, di0dq0);
+ break;
+ case 3:
+ k = wlc_lcnphy_calc_floor(coeff_x, 0);
+ y = 8 + k;
+ k = wlc_lcnphy_calc_floor(coeff_x, 1);
+ x = 8 - k;
+ data_rf = (x * 16 + y);
+ write_radio_reg(pi, RADIO_2064_REG089, data_rf);
+ k = wlc_lcnphy_calc_floor(coeff_y, 0);
+ y = 8 + k;
+ k = wlc_lcnphy_calc_floor(coeff_y, 1);
+ x = 8 - k;
+ data_rf = (x * 16 + y);
+ write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
+ break;
+ case 4:
+ k = wlc_lcnphy_calc_floor(coeff_x, 0);
+ y = 8 + k;
+ k = wlc_lcnphy_calc_floor(coeff_x, 1);
+ x = 8 - k;
+ data_rf = (x * 16 + y);
+ write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
+ k = wlc_lcnphy_calc_floor(coeff_y, 0);
+ y = 8 + k;
+ k = wlc_lcnphy_calc_floor(coeff_y, 1);
+ x = 8 - k;
+ data_rf = (x * 16 + y);
+ write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
+ break;
+ }
+}
+
+static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type)
+{
+ uint16 a, b, didq;
+ uint8 di0, dq0, ei, eq, fi, fq;
+ lcnphy_unsign16_struct cc;
+ cc.re = 0;
+ cc.im = 0;
+ switch (cal_type) {
+ case 0:
+ wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+ cc.re = a;
+ cc.im = b;
+ break;
+ case 2:
+ didq = wlc_lcnphy_get_tx_locc(pi);
+ di0 = (((didq & 0xff00) << 16) >> 24);
+ dq0 = (((didq & 0x00ff) << 24) >> 24);
+ cc.re = (uint16) di0;
+ cc.im = (uint16) dq0;
+ break;
+ case 3:
+ wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+ cc.re = (uint16) ei;
+ cc.im = (uint16) eq;
+ break;
+ case 4:
+ wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+ cc.re = (uint16) fi;
+ cc.im = (uint16) fq;
+ break;
+ }
+ return cc;
+}
+
+static void
+wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2)
+{
+ const lcnphy_spb_tone_t *phy_c1;
+ lcnphy_spb_tone_t phy_c2;
+ lcnphy_unsign16_struct phy_c3;
+ int phy_c4, phy_c5, k, l, j, phy_c6;
+ uint16 phy_c7, phy_c8, phy_c9;
+ int16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
+ int16 *ptr, phy_c17;
+ int32 phy_c18, phy_c19;
+ uint32 phy_c20, phy_c21;
+ bool phy_c22, phy_c23, phy_c24, phy_c25;
+ uint16 phy_c26, phy_c27;
+ uint16 phy_c28, phy_c29, phy_c30;
+ uint16 phy_c31;
+ uint16 *phy_c32;
+ phy_c21 = 0;
+ phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
+ ptr = MALLOC(pi->sh->osh, sizeof(int16) * 131);
+ if (NULL == ptr) {
+ return;
+ }
+
+ phy_c32 = MALLOC(pi->sh->osh, sizeof(uint16) * 20);
+ if (NULL == phy_c32) {
+ return;
+ }
+ phy_c26 = read_phy_reg(pi, 0x6da);
+ phy_c27 = read_phy_reg(pi, 0x6db);
+ phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
+ write_phy_reg(pi, 0x93d, 0xC0);
+
+ wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
+ write_phy_reg(pi, 0x6da, 0xffff);
+ or_phy_reg(pi, 0x6db, 0x3);
+
+ wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
+ OSL_DELAY(500);
+ phy_c28 = read_phy_reg(pi, 0x938);
+ phy_c29 = read_phy_reg(pi, 0x4d7);
+ phy_c30 = read_phy_reg(pi, 0x4d8);
+ or_phy_reg(pi, 0x938, 0x1 << 2);
+ or_phy_reg(pi, 0x4d7, 0x1 << 2);
+ or_phy_reg(pi, 0x4d7, 0x1 << 3);
+ mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
+ or_phy_reg(pi, 0x4d8, 1 << 0);
+ or_phy_reg(pi, 0x4d8, 1 << 1);
+ mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
+ mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
+ phy_c1 = &lcnphy_spb_tone_3750[0];
+ phy_c4 = 32;
+
+ if (num_levels == 0) {
+ if (cal_type != 0) {
+ num_levels = 4;
+ } else {
+ num_levels = 9;
+ }
+ }
+ if (step_size_lg2 == 0) {
+ if (cal_type != 0) {
+ step_size_lg2 = 3;
+ } else {
+ step_size_lg2 = 8;
+ }
+ }
+
+ phy_c7 = (1 << step_size_lg2);
+ phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
+ phy_c15 = (int16) phy_c3.re;
+ phy_c16 = (int16) phy_c3.im;
+ if (cal_type == 2) {
+ if (phy_c3.re > 127)
+ phy_c15 = phy_c3.re - 256;
+ if (phy_c3.im > 127)
+ phy_c16 = phy_c3.im - 256;
+ }
+ wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+ OSL_DELAY(20);
+ for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
+ phy_c23 = 1;
+ phy_c22 = 0;
+ switch (cal_type) {
+ case 0:
+ phy_c10 = 511;
+ break;
+ case 2:
+ phy_c10 = 127;
+ break;
+ case 3:
+ phy_c10 = 15;
+ break;
+ case 4:
+ phy_c10 = 15;
+ break;
+ }
+
+ phy_c9 = read_phy_reg(pi, 0x93d);
+ phy_c9 = 2 * phy_c9;
+ phy_c24 = 0;
+ phy_c5 = 7;
+ phy_c25 = 1;
+ while (1) {
+ write_radio_reg(pi, RADIO_2064_REG026,
+ (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
+ OSL_DELAY(50);
+ phy_c22 = 0;
+ ptr[130] = 0;
+ wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
+ if (ptr[130] == 1)
+ phy_c22 = 1;
+ if (phy_c22)
+ phy_c5 -= 1;
+ if ((phy_c22 != phy_c24) && (!phy_c25))
+ break;
+ if (!phy_c22)
+ phy_c5 += 1;
+ if (phy_c5 <= 0 || phy_c5 >= 7)
+ break;
+ phy_c24 = phy_c22;
+ phy_c25 = 0;
+ }
+
+ if (phy_c5 < 0)
+ phy_c5 = 0;
+ else if (phy_c5 > 7)
+ phy_c5 = 7;
+
+ for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
+ for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
+ phy_c11 = phy_c15 + k;
+ phy_c12 = phy_c16 + l;
+
+ if (phy_c11 < -phy_c10)
+ phy_c11 = -phy_c10;
+ else if (phy_c11 > phy_c10)
+ phy_c11 = phy_c10;
+ if (phy_c12 < -phy_c10)
+ phy_c12 = -phy_c10;
+ else if (phy_c12 > phy_c10)
+ phy_c12 = phy_c10;
+ wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
+ phy_c12);
+ OSL_DELAY(20);
+ wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
+
+ phy_c18 = 0;
+ phy_c19 = 0;
+ for (j = 0; j < 128; j++) {
+ if (cal_type != 0) {
+ phy_c6 = j % phy_c4;
+ } else {
+ phy_c6 = (2 * j) % phy_c4;
+ }
+ phy_c2.re = phy_c1[phy_c6].re;
+ phy_c2.im = phy_c1[phy_c6].im;
+ phy_c17 = ptr[j];
+ phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
+ phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
+ }
+
+ phy_c18 = phy_c18 >> 10;
+ phy_c19 = phy_c19 >> 10;
+ phy_c20 =
+ ((phy_c18 * phy_c18) + (phy_c19 * phy_c19));
+
+ if (phy_c23 || phy_c20 < phy_c21) {
+ phy_c21 = phy_c20;
+ phy_c13 = phy_c11;
+ phy_c14 = phy_c12;
+ }
+ phy_c23 = 0;
+ }
+ }
+ phy_c23 = 1;
+ phy_c15 = phy_c13;
+ phy_c16 = phy_c14;
+ phy_c7 = phy_c7 >> 1;
+ wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+ OSL_DELAY(20);
+ }
+ goto cleanup;
+ cleanup:
+ wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
+ wlc_lcnphy_stop_tx_tone(pi);
+ write_phy_reg(pi, 0x6da, phy_c26);
+ write_phy_reg(pi, 0x6db, phy_c27);
+ write_phy_reg(pi, 0x938, phy_c28);
+ write_phy_reg(pi, 0x4d7, phy_c29);
+ write_phy_reg(pi, 0x4d8, phy_c30);
+ write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
+
+ MFREE(pi->sh->osh, phy_c32, 20 * sizeof(uint16));
+ MFREE(pi->sh->osh, ptr, 131 * sizeof(int16));
+}
+
+static void
+wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, uint16 *values_to_save)
+{
+ int i;
+
+ and_phy_reg(pi, 0x44c, 0x0 >> 11);
+
+ and_phy_reg(pi, 0x43b, 0xC);
+
+ for (i = 0; i < 20; i++) {
+ write_radio_reg(pi, iqlo_loopback_rf_regs[i],
+ values_to_save[i]);
+ }
+}
+
+static void
+WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi,
+ const lcnphy_tx_gain_tbl_entry *
+ gain_table) {
+ uint32 j;
+ phytbl_info_t tab;
+ uint32 val;
+ uint16 pa_gain;
+ uint16 gm_gain;
+
+ if (CHSPEC_IS5G(pi->radio_chanspec))
+ pa_gain = 0x70;
+ else
+ pa_gain = 0x70;
+
+ if (pi->sh->boardflags & BFL_FEM)
+ pa_gain = 0x10;
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_len = 1;
+ tab.tbl_ptr = &val;
+
+ for (j = 0; j < 128; j++) {
+ gm_gain = gain_table[j].gm;
+ val = (((uint32) pa_gain << 24) |
+ (gain_table[j].pad << 16) |
+ (gain_table[j].pga << 8) | gm_gain);
+
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+}
+
+static void wlc_lcnphy_load_rfpower(phy_info_t *pi)
+{
+ phytbl_info_t tab;
+ uint32 val, bbmult, rfgain;
+ uint8 index;
+ uint8 scale_factor = 1;
+ int16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
+
+ tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+ tab.tbl_width = 32;
+ tab.tbl_len = 1;
+
+ for (index = 0; index < 128; index++) {
+ tab.tbl_ptr = &bbmult;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+ wlc_lcnphy_read_table(pi, &tab);
+ bbmult = bbmult >> 20;
+
+ tab.tbl_ptr = &rfgain;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ qm_log10((int32) (bbmult), 0, &temp1, &qQ1);
+ qm_log10((int32) (1 << 6), 0, &temp2, &qQ2);
+
+ if (qQ1 < qQ2) {
+ temp2 = qm_shr16(temp2, qQ2 - qQ1);
+ qQ = qQ1;
+ } else {
+ temp1 = qm_shr16(temp1, qQ1 - qQ2);
+ qQ = qQ2;
+ }
+ temp = qm_sub16(temp1, temp2);
+
+ if (qQ >= 4)
+ shift = qQ - 4;
+ else
+ shift = 4 - qQ;
+
+ val = (((index << shift) + (5 * temp) +
+ (1 << (scale_factor + shift - 3))) >> (scale_factor +
+ shift - 2));
+
+ tab.tbl_ptr = &val;
+ tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+}
+
+static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi)
+{
+ uint idx;
+ uint8 phybw40;
+ phytbl_info_t tab;
+ uint32 val;
+
+ phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+
+ for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) {
+ wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
+ }
+
+ if (pi->sh->boardflags & BFL_FEM_BT) {
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &val;
+ tab.tbl_len = 1;
+ val = 100;
+ tab.tbl_offset = 4;
+ wlc_lcnphy_write_table(pi, &tab);
+ }
+
+ tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+ tab.tbl_width = 16;
+ tab.tbl_ptr = &val;
+ tab.tbl_len = 1;
+
+ val = 114;
+ tab.tbl_offset = 0;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ val = 130;
+ tab.tbl_offset = 1;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ val = 6;
+ tab.tbl_offset = 8;
+ wlc_lcnphy_write_table(pi, &tab);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->sh->boardflags & BFL_FEM)
+ wlc_lcnphy_load_tx_gain_table(pi,
+ dot11lcnphy_2GHz_extPA_gaintable_rev0);
+ else
+ wlc_lcnphy_load_tx_gain_table(pi,
+ dot11lcnphy_2GHz_gaintable_rev0);
+ }
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ for (idx = 0;
+ idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+ idx++)
+ if (pi->sh->boardflags & BFL_EXTLNA)
+ wlc_lcnphy_write_table(pi,
+ &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2
+ [idx]);
+ else
+ wlc_lcnphy_write_table(pi,
+ &dot11lcnphytbl_rx_gain_info_2G_rev2
+ [idx]);
+ } else {
+ for (idx = 0;
+ idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+ idx++)
+ if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
+ wlc_lcnphy_write_table(pi,
+ &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2
+ [idx]);
+ else
+ wlc_lcnphy_write_table(pi,
+ &dot11lcnphytbl_rx_gain_info_5G_rev2
+ [idx]);
+ }
+ }
+
+ if ((pi->sh->boardflags & BFL_FEM)
+ && !(pi->sh->boardflags & BFL_FEM_BT))
+ wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
+ else if (pi->sh->boardflags & BFL_FEM_BT) {
+ if (pi->sh->boardrev < 0x1250)
+ wlc_lcnphy_write_table(pi,
+ &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
+ else
+ wlc_lcnphy_write_table(pi,
+ &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
+ } else
+ wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
+
+ wlc_lcnphy_load_rfpower(pi);
+
+ wlc_lcnphy_clear_papd_comptable(pi);
+}
+
+static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi)
+{
+ uint16 afectrl1;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
+
+ write_phy_reg(pi, 0x43b, 0x0);
+ write_phy_reg(pi, 0x43c, 0x0);
+ write_phy_reg(pi, 0x44c, 0x0);
+ write_phy_reg(pi, 0x4e6, 0x0);
+ write_phy_reg(pi, 0x4f9, 0x0);
+ write_phy_reg(pi, 0x4b0, 0x0);
+ write_phy_reg(pi, 0x938, 0x0);
+ write_phy_reg(pi, 0x4b0, 0x0);
+ write_phy_reg(pi, 0x44e, 0);
+
+ or_phy_reg(pi, 0x567, 0x03);
+
+ or_phy_reg(pi, 0x44a, 0x44);
+ write_phy_reg(pi, 0x44a, 0x80);
+
+ if (!(pi->sh->boardflags & BFL_FEM))
+ wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
+
+ if (0) {
+ afectrl1 = 0;
+ afectrl1 = (uint16) ((pi_lcn->lcnphy_rssi_vf) |
+ (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn->
+ lcnphy_rssi_gs
+ << 10));
+ write_phy_reg(pi, 0x43e, afectrl1);
+ }
+
+ mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
+ if (pi->sh->boardflags & BFL_FEM) {
+ mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
+
+ write_phy_reg(pi, 0x910, 0x1);
+ }
+
+ mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
+ mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
+ mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
+
+}
+
+static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi)
+{
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
+
+ mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
+ }
+}
+
+static void wlc_lcnphy_agc_temp_init(phy_info_t *pi)
+{
+ int16 temp;
+ phytbl_info_t tab;
+ uint32 tableBuffer[2];
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ temp = (int16) read_phy_reg(pi, 0x4df);
+ pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
+
+ if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
+ pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
+
+ pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
+
+ if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
+ pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
+
+ tab.tbl_ptr = tableBuffer;
+ tab.tbl_len = 2;
+ tab.tbl_id = 17;
+ tab.tbl_offset = 59;
+ tab.tbl_width = 32;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ if (tableBuffer[0] > 63)
+ tableBuffer[0] -= 128;
+ pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
+
+ if (tableBuffer[1] > 63)
+ tableBuffer[1] -= 128;
+ pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
+
+ temp = (int16) (read_phy_reg(pi, 0x434)
+ & (0xff << 0));
+ if (temp > 127)
+ temp -= 256;
+ pi_lcn->lcnphy_input_pwr_offset_db = (int8) temp;
+
+ pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424)
+ & (0xff << 8))
+ >> 8;
+ pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425)
+ & (0xff << 0))
+ >> 0;
+
+ tab.tbl_ptr = tableBuffer;
+ tab.tbl_len = 2;
+ tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
+ tab.tbl_offset = 28;
+ tab.tbl_width = 32;
+ wlc_lcnphy_read_table(pi, &tab);
+
+ pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
+ pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
+
+}
+
+static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi)
+{
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ or_phy_reg(pi, 0x805, 0x1);
+
+ mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
+
+ mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
+
+ write_phy_reg(pi, 0x414, 0x1e10);
+ write_phy_reg(pi, 0x415, 0x0640);
+
+ mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
+
+ or_phy_reg(pi, 0x44a, 0x44);
+ write_phy_reg(pi, 0x44a, 0x80);
+ mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
+
+ mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
+
+ if (!(pi->sh->boardrev < 0x1204))
+ mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
+
+ write_phy_reg(pi, 0x7d6, 0x0902);
+ mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
+
+ mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+ mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
+
+ mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
+
+ mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
+
+ mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+
+ mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
+ mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
+ mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
+ mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
+ mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
+
+ mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
+
+ wlc_lcnphy_clear_tx_power_offsets(pi);
+ mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
+
+ }
+}
+
+static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi)
+{
+
+ wlc_lcnphy_tbl_init(pi);
+ wlc_lcnphy_rev0_baseband_init(pi);
+ if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+ wlc_lcnphy_rev2_baseband_init(pi);
+ wlc_lcnphy_bu_tweaks(pi);
+}
+
+static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi)
+{
+ uint32 i;
+ lcnphy_radio_regs_t *lcnphyregs = NULL;
+
+ lcnphyregs = lcnphy_radio_regs_2064;
+
+ for (i = 0; lcnphyregs[i].address != 0xffff; i++)
+ if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
+ write_radio_reg(pi,
+ ((lcnphyregs[i].address & 0x3fff) |
+ RADIO_DEFAULT_CORE),
+ (uint16) lcnphyregs[i].init_a);
+ else if (lcnphyregs[i].do_init_g)
+ write_radio_reg(pi,
+ ((lcnphyregs[i].address & 0x3fff) |
+ RADIO_DEFAULT_CORE),
+ (uint16) lcnphyregs[i].init_g);
+
+ write_radio_reg(pi, RADIO_2064_REG032, 0x62);
+ write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+
+ write_radio_reg(pi, RADIO_2064_REG090, 0x10);
+
+ write_radio_reg(pi, RADIO_2064_REG010, 0x00);
+
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+
+ write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
+ write_radio_reg(pi, RADIO_2064_REG061, 0x72);
+ write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
+ }
+
+ write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
+ write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
+
+ mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
+
+ mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
+
+ mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
+
+ mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
+
+ mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
+
+ write_phy_reg(pi, 0x4ea, 0x4688);
+
+ mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+
+ mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
+
+ mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
+
+ wlc_lcnphy_set_tx_locc(pi, 0);
+
+ wlc_lcnphy_rcal(pi);
+
+ wlc_lcnphy_rc_cal(pi);
+}
+
+static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi)
+{
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ wlc_radio_2064_init(pi);
+}
+
+static void wlc_lcnphy_rcal(phy_info_t *pi)
+{
+ uint8 rcal_value;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+
+ or_radio_reg(pi, RADIO_2064_REG004, 0x40);
+ or_radio_reg(pi, RADIO_2064_REG120, 0x10);
+
+ or_radio_reg(pi, RADIO_2064_REG078, 0x80);
+ or_radio_reg(pi, RADIO_2064_REG129, 0x02);
+
+ or_radio_reg(pi, RADIO_2064_REG057, 0x01);
+
+ or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
+ OSL_DELAY(5000);
+ SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
+
+ if (wlc_radio_2064_rcal_done(pi)) {
+ rcal_value = (uint8) read_radio_reg(pi, RADIO_2064_REG05C);
+ rcal_value = rcal_value & 0x1f;
+ }
+
+ and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+
+ and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
+}
+
+static void wlc_lcnphy_rc_cal(phy_info_t *pi)
+{
+ uint8 dflt_rc_cal_val;
+ uint16 flt_val;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ dflt_rc_cal_val = 7;
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+ dflt_rc_cal_val = 11;
+ flt_val =
+ (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
+ (dflt_rc_cal_val);
+ write_phy_reg(pi, 0x933, flt_val);
+ write_phy_reg(pi, 0x934, flt_val);
+ write_phy_reg(pi, 0x935, flt_val);
+ write_phy_reg(pi, 0x936, flt_val);
+ write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
+
+ return;
+}
+
+static bool BCMATTACHFN(wlc_phy_txpwr_srom_read_lcnphy) (phy_info_t *pi)
+{
+ int8 txpwr = 0;
+ int i;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ uint16 cckpo = 0;
+ uint32 offset_ofdm, offset_mcs;
+
+ pi_lcn->lcnphy_tr_isolation_mid =
+ (uint8) PHY_GETINTVAR(pi, "triso2g");
+
+ pi_lcn->lcnphy_rx_power_offset =
+ (uint8) PHY_GETINTVAR(pi, "rxpo2g");
+
+ pi->txpa_2g[0] = (int16) PHY_GETINTVAR(pi, "pa0b0");
+ pi->txpa_2g[1] = (int16) PHY_GETINTVAR(pi, "pa0b1");
+ pi->txpa_2g[2] = (int16) PHY_GETINTVAR(pi, "pa0b2");
+
+ pi_lcn->lcnphy_rssi_vf = (uint8) PHY_GETINTVAR(pi, "rssismf2g");
+ pi_lcn->lcnphy_rssi_vc = (uint8) PHY_GETINTVAR(pi, "rssismc2g");
+ pi_lcn->lcnphy_rssi_gs = (uint8) PHY_GETINTVAR(pi, "rssisav2g");
+
+ {
+ pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
+ pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
+ pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
+
+ pi_lcn->lcnphy_rssi_vf_hightemp =
+ pi_lcn->lcnphy_rssi_vf;
+ pi_lcn->lcnphy_rssi_vc_hightemp =
+ pi_lcn->lcnphy_rssi_vc;
+ pi_lcn->lcnphy_rssi_gs_hightemp =
+ pi_lcn->lcnphy_rssi_gs;
+ }
+
+ txpwr = (int8) PHY_GETINTVAR(pi, "maxp2ga0");
+ pi->tx_srom_max_2g = txpwr;
+
+ for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
+ pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
+ pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
+ }
+
+ cckpo = (uint16) PHY_GETINTVAR(pi, "cck2gpo");
+ if (cckpo) {
+ uint max_pwr_chan = txpwr;
+
+ for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+ pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+ ((cckpo & 0xf) * 2);
+ cckpo >>= 4;
+ }
+
+ offset_ofdm = (uint32) PHY_GETINTVAR(pi, "ofdm2gpo");
+ for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+ pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+ ((offset_ofdm & 0xf) * 2);
+ offset_ofdm >>= 4;
+ }
+ } else {
+ uint8 opo = 0;
+
+ opo = (uint8) PHY_GETINTVAR(pi, "opo");
+
+ for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+ pi->tx_srom_max_rate_2g[i] = txpwr;
+ }
+
+ offset_ofdm = (uint32) PHY_GETINTVAR(pi, "ofdm2gpo");
+
+ for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+ pi->tx_srom_max_rate_2g[i] = txpwr -
+ ((offset_ofdm & 0xf) * 2);
+ offset_ofdm >>= 4;
+ }
+ offset_mcs =
+ ((uint16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) |
+ (uint16) PHY_GETINTVAR(pi, "mcs2gpo0");
+ pi_lcn->lcnphy_mcs20_po = offset_mcs;
+ for (i = TXP_FIRST_SISO_MCS_20;
+ i <= TXP_LAST_SISO_MCS_20; i++) {
+ pi->tx_srom_max_rate_2g[i] =
+ txpwr - ((offset_mcs & 0xf) * 2);
+ offset_mcs >>= 4;
+ }
+ }
+
+ pi_lcn->lcnphy_rawtempsense =
+ (uint16) PHY_GETINTVAR(pi, "rawtempsense");
+ pi_lcn->lcnphy_measPower =
+ (uint8) PHY_GETINTVAR(pi, "measpower");
+ pi_lcn->lcnphy_tempsense_slope =
+ (uint8) PHY_GETINTVAR(pi, "tempsense_slope");
+ pi_lcn->lcnphy_hw_iqcal_en =
+ (bool) PHY_GETINTVAR(pi, "hw_iqcal_en");
+ pi_lcn->lcnphy_iqcal_swp_dis =
+ (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis");
+ pi_lcn->lcnphy_tempcorrx =
+ (uint8) PHY_GETINTVAR(pi, "tempcorrx");
+ pi_lcn->lcnphy_tempsense_option =
+ (uint8) PHY_GETINTVAR(pi, "tempsense_option");
+ pi_lcn->lcnphy_freqoffset_corr =
+ (uint8) PHY_GETINTVAR(pi, "freqoffset_corr");
+ if ((uint8) getintvar(pi->vars, "aa2g") > 1)
+ wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi,
+ (uint8) getintvar(pi->vars,
+ "aa2g"));
+ }
+ pi_lcn->lcnphy_cck_dig_filt_type = -1;
+ if (PHY_GETVAR(pi, "cckdigfilttype")) {
+ int16 temp;
+ temp = (int16) PHY_GETINTVAR(pi, "cckdigfilttype");
+ if (temp >= 0) {
+ pi_lcn->lcnphy_cck_dig_filt_type = temp;
+ }
+ }
+
+ return TRUE;
+}
+
+void wlc_2064_vco_cal(phy_info_t *pi)
+{
+ uint8 calnrst;
+
+ mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
+ calnrst = (uint8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
+ write_radio_reg(pi, RADIO_2064_REG056, calnrst);
+ OSL_DELAY(1);
+ write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
+ OSL_DELAY(1);
+ write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
+ OSL_DELAY(300);
+ mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
+}
+
+static void
+wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, uint8 channel)
+{
+ uint i;
+ const chan_info_2064_lcnphy_t *ci;
+ uint8 rfpll_doubler = 0;
+ uint8 pll_pwrup, pll_pwrup_ovr;
+ fixed qFxtal, qFref, qFvco, qFcal;
+ uint8 d15, d16, f16, e44, e45;
+ uint32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
+ uint16 loop_bw, d30, setCount;
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+ ci = &chan_info_2064_lcnphy[0];
+ rfpll_doubler = 1;
+
+ mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
+
+ write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
+ if (!rfpll_doubler) {
+ loop_bw = PLL_2064_LOOP_BW;
+ d30 = PLL_2064_D30;
+ } else {
+ loop_bw = PLL_2064_LOOP_BW_DOUBLER;
+ d30 = PLL_2064_D30_DOUBLER;
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ for (i = 0; i < ARRAYSIZE(chan_info_2064_lcnphy); i++)
+ if (chan_info_2064_lcnphy[i].chan == channel)
+ break;
+
+ if (i >= ARRAYSIZE(chan_info_2064_lcnphy)) {
+ return;
+ }
+
+ ci = &chan_info_2064_lcnphy[i];
+ }
+
+ write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
+
+ mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
+
+ mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
+
+ mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
+
+ mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
+ (ci->logen_rccr_rx) << 2);
+
+ mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
+
+ mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
+ (ci->pa_rxrf_lna2_freq_tune) << 4);
+
+ write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
+
+ pll_pwrup = (uint8) read_radio_reg(pi, RADIO_2064_REG044);
+ pll_pwrup_ovr = (uint8) read_radio_reg(pi, RADIO_2064_REG12B);
+
+ or_radio_reg(pi, RADIO_2064_REG044, 0x07);
+
+ or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
+ e44 = 0;
+ e45 = 0;
+
+ fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
+ if (pi->xtalfreq > 26000000)
+ e44 = 1;
+ if (pi->xtalfreq > 52000000)
+ e45 = 1;
+ if (e44 == 0)
+ fcal_div = 1;
+ else if (e45 == 0)
+ fcal_div = 2;
+ else
+ fcal_div = 4;
+ fvco3 = (ci->freq * 3);
+ fref3 = 2 * fpfd;
+
+ qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
+ qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
+ qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
+ qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
+
+ write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
+
+ d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
+ write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
+ write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
+
+ d16 = (qFcal * 8 / (d15 + 1)) - 1;
+ write_radio_reg(pi, RADIO_2064_REG051, d16);
+
+ f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
+ setCount = f16 * 3 * (ci->freq) / 32 - 1;
+ mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
+ (uint8) (setCount >> 8));
+
+ or_radio_reg(pi, RADIO_2064_REG053, 0x10);
+ write_radio_reg(pi, RADIO_2064_REG054, (uint8) (setCount & 0xff));
+
+ div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
+
+ div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
+ while (div_frac >= fref3) {
+ div_int++;
+ div_frac -= fref3;
+ }
+ div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
+
+ mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
+ (uint8) (div_int >> 4));
+ mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
+ (uint8) (div_int << 4));
+ mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
+ (uint8) (div_frac >> 16));
+ write_radio_reg(pi, RADIO_2064_REG047, (uint8) (div_frac >> 8) & 0xff);
+ write_radio_reg(pi, RADIO_2064_REG048, (uint8) div_frac & 0xff);
+
+ write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
+
+ write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
+ write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
+ write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
+
+ {
+ uint8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current;
+ uint16 c29, c38, c30, g30, d28;
+ c29 = loop_bw;
+ d29 = 200;
+ c38 = 1250;
+ h29 = d29 / c29;
+ h23 = 1;
+ c28 = 30;
+ d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
+ (fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
+ (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
+ + PLL_2064_LOW_END_KVCO;
+ h28_ten = (d28 * 10) / c28;
+ c30 = 2640;
+ e30 = (d30 - 680) / 490;
+ g30 = 680 + (e30 * 490);
+ h30_ten = (g30 * 10) / c30;
+ cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten;
+ mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
+ }
+ if (channel >= 1 && channel <= 5)
+ write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
+ else
+ write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
+ write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
+
+ mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
+ OSL_DELAY(1);
+
+ wlc_2064_vco_cal(pi);
+
+ write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
+ write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
+ if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+ write_radio_reg(pi, RADIO_2064_REG038, 3);
+ write_radio_reg(pi, RADIO_2064_REG091, 7);
+ }
+}
+
+bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi)
+{
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+ return 0;
+ else
+ return (LCNPHY_TX_PWR_CTRL_HW ==
+ wlc_lcnphy_get_tx_pwr_ctrl((pi)));
+}
+
+void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi)
+{
+ uint16 pwr_ctrl;
+ if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+ wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+ } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+
+ pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+ wlc_lcnphy_txpower_recalc_target(pi);
+
+ wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
+ } else
+ return;
+}
+
+void wlc_phy_detach_lcnphy(phy_info_t *pi)
+{
+ MFREE(pi->sh->osh, pi->u.pi_lcnphy, sizeof(phy_info_lcnphy_t));
+}
+
+bool wlc_phy_attach_lcnphy(phy_info_t *pi)
+{
+ phy_info_lcnphy_t *pi_lcn;
+
+ pi->u.pi_lcnphy =
+ (phy_info_lcnphy_t *) MALLOC(pi->sh->osh,
+ sizeof(phy_info_lcnphy_t));
+ if (pi->u.pi_lcnphy == NULL) {
+ return FALSE;
+ }
+ bzero((char *)pi->u.pi_lcnphy, sizeof(phy_info_lcnphy_t));
+
+ pi_lcn = pi->u.pi_lcnphy;
+
+ if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) {
+ pi->hwpwrctrl = TRUE;
+ pi->hwpwrctrl_capable = TRUE;
+ }
+
+ pi->xtalfreq = si_alp_clock(pi->sh->sih);
+ ASSERT(0 == (pi->xtalfreq % 1000));
+
+ pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
+
+ pi->pi_fptr.init = wlc_phy_init_lcnphy;
+ pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
+ pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
+ pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
+ pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
+ pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
+ pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
+ pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
+ pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
+
+ if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
+ return FALSE;
+
+ if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+ if (pi_lcn->lcnphy_tempsense_option == 3) {
+ pi->hwpwrctrl = TRUE;
+ pi->hwpwrctrl_capable = TRUE;
+ pi->temppwrctrl_capable = FALSE;
+ } else {
+ pi->hwpwrctrl = FALSE;
+ pi->hwpwrctrl_capable = FALSE;
+ pi->temppwrctrl_capable = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, uint32 gain)
+{
+ uint16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
+
+ trsw = (gain & ((uint32) 1 << 28)) ? 0 : 1;
+ ext_lna = (uint16) (gain >> 29) & 0x01;
+ lna1 = (uint16) (gain >> 0) & 0x0f;
+ lna2 = (uint16) (gain >> 4) & 0x0f;
+ tia = (uint16) (gain >> 8) & 0xf;
+ biq0 = (uint16) (gain >> 12) & 0xf;
+ biq1 = (uint16) (gain >> 16) & 0xf;
+
+ gain0_15 = (uint16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
+ ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
+ ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
+ gain16_19 = biq1;
+
+ mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
+ mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+ mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+ mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+ mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+ mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
+ }
+ wlc_lcnphy_rx_gain_override_enable(pi, TRUE);
+}
+
+static uint32 wlc_lcnphy_get_receive_power(phy_info_t *pi, int32 *gain_index)
+{
+ uint32 received_power = 0;
+ int32 max_index = 0;
+ uint32 gain_code = 0;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ max_index = 36;
+ if (*gain_index >= 0)
+ gain_code = lcnphy_23bitgaincode_table[*gain_index];
+
+ if (-1 == *gain_index) {
+ *gain_index = 0;
+ while ((*gain_index <= (int32) max_index)
+ && (received_power < 700)) {
+ wlc_lcnphy_set_rx_gain(pi,
+ lcnphy_23bitgaincode_table
+ [*gain_index]);
+ received_power =
+ wlc_lcnphy_measure_digital_power(pi,
+ pi_lcn->
+ lcnphy_noise_samples);
+ (*gain_index)++;
+ }
+ (*gain_index)--;
+ } else {
+ wlc_lcnphy_set_rx_gain(pi, gain_code);
+ received_power =
+ wlc_lcnphy_measure_digital_power(pi,
+ pi_lcn->
+ lcnphy_noise_samples);
+ }
+
+ return received_power;
+}
+
+int32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, int32 gain_index)
+{
+ int32 gain = 0;
+ int32 nominal_power_db;
+ int32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
+ input_power_db;
+ int32 received_power, temperature;
+ uint freq;
+ phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+
+ received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
+
+ gain = lcnphy_gain_table[gain_index];
+
+ nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
+
+ {
+ uint32 power = (received_power * 16);
+ uint32 msb1, msb2, val1, val2, diff1, diff2;
+ msb1 = find_msbit(power);
+ msb2 = msb1 + 1;
+ val1 = 1 << msb1;
+ val2 = 1 << msb2;
+ diff1 = (power - val1);
+ diff2 = (val2 - power);
+ if (diff1 < diff2)
+ log_val = msb1;
+ else
+ log_val = msb2;
+ }
+
+ log_val = log_val * 3;
+
+ gain_mismatch = (nominal_power_db / 2) - (log_val);
+
+ desired_gain = gain + gain_mismatch;
+
+ input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
+
+ if (input_power_offset_db > 127)
+ input_power_offset_db -= 256;
+
+ input_power_db = input_power_offset_db - desired_gain;
+
+ input_power_db =
+ input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
+
+ freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
+ if ((freq > 2427) && (freq <= 2467))
+ input_power_db = input_power_db - 1;
+
+ temperature = pi_lcn->lcnphy_lastsensed_temperature;
+
+ if ((temperature - 15) < -30) {
+ input_power_db =
+ input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+ 7;
+ } else if ((temperature - 15) < 4) {
+ input_power_db =
+ input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+ 3;
+ } else {
+ input_power_db =
+ input_power_db + (((temperature - 10 - 25) * 286) >> 12);
+ }
+
+ wlc_lcnphy_rx_gain_override_enable(pi, 0);
+
+ return input_power_db;
+}
+
+static int
+wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, int16 filt_type)
+{
+ int16 filt_index = -1;
+ int j;
+
+ uint16 addr[] = {
+ 0x910,
+ 0x91e,
+ 0x91f,
+ 0x924,
+ 0x925,
+ 0x926,
+ 0x920,
+ 0x921,
+ 0x927,
+ 0x928,
+ 0x929,
+ 0x922,
+ 0x923,
+ 0x930,
+ 0x931,
+ 0x932
+ };
+
+ uint16 addr_ofdm[] = {
+ 0x90f,
+ 0x900,
+ 0x901,
+ 0x906,
+ 0x907,
+ 0x908,
+ 0x902,
+ 0x903,
+ 0x909,
+ 0x90a,
+ 0x90b,
+ 0x904,
+ 0x905,
+ 0x90c,
+ 0x90d,
+ 0x90e
+ };
+
+ if (!is_ofdm) {
+ for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
+ if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
+ filt_index = (int16) j;
+ break;
+ }
+ }
+
+ if (filt_index == -1) {
+ ASSERT(FALSE);
+ } else {
+ for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, addr[j],
+ LCNPHY_txdigfiltcoeffs_cck
+ [filt_index][j + 1]);
+ }
+ }
+ } else {
+ for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
+ if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
+ filt_index = (int16) j;
+ break;
+ }
+ }
+
+ if (filt_index == -1) {
+ ASSERT(FALSE);
+ } else {
+ for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, addr_ofdm[j],
+ LCNPHY_txdigfiltcoeffs_ofdm
+ [filt_index][j + 1]);
+ }
+ }
+ }
+
+ return (filt_index != -1) ? 0 : -1;
+}
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/phy/wlc_phy_lcn.h
new file mode 100644
index 000000000000..e278a2c3d8fe
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_phy_lcn_h_
+#define _wlc_phy_lcn_h_
+
+#include <typedefs.h>
+
+struct phy_info_lcnphy {
+ int lcnphy_txrf_sp_9_override;
+ uint8 lcnphy_full_cal_channel;
+ uint8 lcnphy_cal_counter;
+ uint16 lcnphy_cal_temper;
+ bool lcnphy_recal;
+
+ uint8 lcnphy_rc_cap;
+ uint32 lcnphy_mcs20_po;
+
+ uint8 lcnphy_tr_isolation_mid;
+ uint8 lcnphy_tr_isolation_low;
+ uint8 lcnphy_tr_isolation_hi;
+
+ uint8 lcnphy_bx_arch;
+ uint8 lcnphy_rx_power_offset;
+ uint8 lcnphy_rssi_vf;
+ uint8 lcnphy_rssi_vc;
+ uint8 lcnphy_rssi_gs;
+ uint8 lcnphy_tssi_val;
+ uint8 lcnphy_rssi_vf_lowtemp;
+ uint8 lcnphy_rssi_vc_lowtemp;
+ uint8 lcnphy_rssi_gs_lowtemp;
+
+ uint8 lcnphy_rssi_vf_hightemp;
+ uint8 lcnphy_rssi_vc_hightemp;
+ uint8 lcnphy_rssi_gs_hightemp;
+
+ int16 lcnphy_pa0b0;
+ int16 lcnphy_pa0b1;
+ int16 lcnphy_pa0b2;
+
+ uint16 lcnphy_rawtempsense;
+ uint8 lcnphy_measPower;
+ uint8 lcnphy_tempsense_slope;
+ uint8 lcnphy_freqoffset_corr;
+ uint8 lcnphy_tempsense_option;
+ uint8 lcnphy_tempcorrx;
+ bool lcnphy_iqcal_swp_dis;
+ bool lcnphy_hw_iqcal_en;
+ uint lcnphy_bandedge_corr;
+ bool lcnphy_spurmod;
+ uint16 lcnphy_tssi_tx_cnt;
+ uint16 lcnphy_tssi_idx;
+ uint16 lcnphy_tssi_npt;
+
+ uint16 lcnphy_target_tx_freq;
+ int8 lcnphy_tx_power_idx_override;
+ uint16 lcnphy_noise_samples;
+
+ uint32 lcnphy_papdRxGnIdx;
+ uint32 lcnphy_papd_rxGnCtrl_init;
+
+ uint32 lcnphy_gain_idx_14_lowword;
+ uint32 lcnphy_gain_idx_14_hiword;
+ uint32 lcnphy_gain_idx_27_lowword;
+ uint32 lcnphy_gain_idx_27_hiword;
+ int16 lcnphy_ofdmgainidxtableoffset;
+ int16 lcnphy_dsssgainidxtableoffset;
+ uint32 lcnphy_tr_R_gain_val;
+ uint32 lcnphy_tr_T_gain_val;
+ int8 lcnphy_input_pwr_offset_db;
+ uint16 lcnphy_Med_Low_Gain_db;
+ uint16 lcnphy_Very_Low_Gain_db;
+ int8 lcnphy_lastsensed_temperature;
+ int8 lcnphy_pkteng_rssi_slope;
+ uint8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
+ uint8 lcnphy_volt_winner;
+ uint8 lcnphy_volt_low;
+ uint8 lcnphy_54_48_36_24mbps_backoff;
+ uint8 lcnphy_11n_backoff;
+ uint8 lcnphy_lowerofdm;
+ uint8 lcnphy_cck;
+ uint8 lcnphy_psat_2pt3_detected;
+ int32 lcnphy_lowest_Re_div_Im;
+ int8 lcnphy_final_papd_cal_idx;
+ uint16 lcnphy_extstxctrl4;
+ uint16 lcnphy_extstxctrl0;
+ uint16 lcnphy_extstxctrl1;
+ int16 lcnphy_cck_dig_filt_type;
+ int16 lcnphy_ofdm_dig_filt_type;
+ lcnphy_cal_results_t lcnphy_cal_results;
+
+ uint8 lcnphy_psat_pwr;
+ uint8 lcnphy_psat_indx;
+ int32 lcnphy_min_phase;
+ uint8 lcnphy_final_idx;
+ uint8 lcnphy_start_idx;
+ uint8 lcnphy_current_index;
+ uint16 lcnphy_logen_buf_1;
+ uint16 lcnphy_local_ovr_2;
+ uint16 lcnphy_local_oval_6;
+ uint16 lcnphy_local_oval_5;
+ uint16 lcnphy_logen_mixer_1;
+
+ uint8 lcnphy_aci_stat;
+ uint lcnphy_aci_start_time;
+ int8 lcnphy_tx_power_offset[TXP_NUM_RATES];
+};
+#endif /* _wlc_phy_lcn_h_ */
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c
new file mode 100644
index 000000000000..6a0c1cdcc371
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c
@@ -0,0 +1,29231 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <osl.h>
+#include <siutils.h>
+#include <sbchipc.h>
+#include <bitfuncs.h>
+#include <hndpmu.h>
+#include <bcmendian.h>
+
+#include <wlc_phy_radio.h>
+#include <wlc_phy_int.h>
+#include <wlc_phyreg_n.h>
+#include <wlc_phytbl_n.h>
+
+#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \
+ read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+ ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1))
+#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \
+ write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+ ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value);
+#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
+ write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value);
+
+#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \
+ read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+ radio_type##_##jspace##1##_##reg_name));
+#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \
+ write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+ radio_type##_##jspace##1##_##reg_name), value);
+#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \
+ read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+ radio_type##_##reg_name##_##jspace##1));
+#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \
+ write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+ radio_type##_##reg_name##_##jspace##1), value);
+
+#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
+#define NPHY_ACI_CHANNEL_DELTA 5
+#define NPHY_ACI_CHANNEL_SKIP 4
+#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
+#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
+#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
+#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
+#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
+#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
+
+#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
+
+#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
+
+#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
+
+#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
+
+#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
+
+#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
+
+#define NPHY_NOISE_NOASSOC_ENTER_TH 400
+
+#define NPHY_NOISE_ASSOC_ENTER_TH 400
+
+#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH 400
+
+#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
+#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
+
+#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
+
+#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
+
+#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
+
+#define NPHY_RSSICAL_MAXREAD 31
+
+#define NPHY_RSSICAL_NPOLL 8
+#define NPHY_RSSICAL_MAXD (1<<20)
+#define NPHY_MIN_RXIQ_PWR 2
+
+#define NPHY_RSSICAL_W1_TARGET 25
+#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
+#define NPHY_RSSICAL_NB_TARGET 0
+
+#define NPHY_RSSICAL_W1_TARGET_REV3 29
+#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
+
+#define NPHY_CALSANITY_RSSI_NB_MAX_POS 9
+#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
+#define NPHY_CALSANITY_RSSI_W1_MAX_POS 12
+#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD)
+#define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS
+#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD)
+#define NPHY_RSSI_SXT(x) ((int8) (-((x) & 0x20) + ((x) & 0x1f)))
+#define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
+ ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
+#define NPHY_RSSI_W1_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
+ ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
+#define NPHY_RSSI_W2_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
+ ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
+
+#define NPHY_IQCAL_NUMGAINS 9
+#define NPHY_N_GCTL 0x66
+
+#define NPHY_PAPD_EPS_TBL_SIZE 64
+#define NPHY_PAPD_SCL_TBL_SIZE 64
+#define NPHY_NUM_DIG_FILT_COEFFS 15
+
+#define NPHY_PAPD_COMP_OFF 0
+#define NPHY_PAPD_COMP_ON 1
+
+#define NPHY_SROM_TEMPSHIFT 32
+#define NPHY_SROM_MAXTEMPOFFSET 16
+#define NPHY_SROM_MINTEMPOFFSET -16
+
+#define NPHY_CAL_MAXTEMPDELTA 64
+
+#define NPHY_NOISEVAR_TBLLEN40 256
+#define NPHY_NOISEVAR_TBLLEN20 128
+
+#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
+
+#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
+
+typedef struct _nphy_iqcal_params {
+ uint16 txlpf;
+ uint16 txgm;
+ uint16 pga;
+ uint16 pad;
+ uint16 ipa;
+ uint16 cal_gain;
+ uint16 ncorr[5];
+} nphy_iqcal_params_t;
+
+typedef struct _nphy_txiqcal_ladder {
+ uint8 percent;
+ uint8 g_env;
+} nphy_txiqcal_ladder_t;
+
+typedef struct {
+ nphy_txgains_t gains;
+ bool useindex;
+ uint8 index;
+} nphy_ipa_txcalgains_t;
+
+typedef struct nphy_papd_restore_state_t {
+ uint16 fbmix[2];
+ uint16 vga_master[2];
+ uint16 intpa_master[2];
+ uint16 afectrl[2];
+ uint16 afeoverride[2];
+ uint16 pwrup[2];
+ uint16 atten[2];
+ uint16 mm;
+} nphy_papd_restore_state;
+
+typedef struct _nphy_ipa_txrxgain {
+ uint16 hpvga;
+ uint16 lpf_biq1;
+ uint16 lpf_biq0;
+ uint16 lna2;
+ uint16 lna1;
+ int8 txpwrindex;
+} nphy_ipa_txrxgain_t;
+
+#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
+
+nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100},
+{0, 0, 0, 0, 0, 50},
+{0, 0, 0, 0, 0, -1},
+{0, 0, 0, 3, 0, -1},
+{0, 0, 3, 3, 0, -1},
+{0, 2, 3, 3, 0, -1}
+};
+
+nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128},
+{0, 0, 0, 0, 0, 70},
+{0, 0, 0, 0, 0, 20},
+{0, 0, 0, 3, 0, 20},
+{0, 0, 3, 3, 0, 20},
+{0, 2, 3, 3, 0, 20}
+};
+
+nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100},
+{0, 0, 0, 0, 0, 50},
+{0, 0, 0, 0, 0, -1},
+{0, 0, 0, 3, 0, -1},
+{0, 0, 3, 3, 0, -1},
+{0, 0, 5, 3, 0, -1}
+};
+
+nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10},
+{0, 0, 0, 1, 0, 10},
+{0, 0, 1, 2, 0, 10},
+{0, 0, 1, 3, 0, 10},
+{0, 0, 4, 3, 0, 10},
+{0, 0, 6, 3, 0, 10}
+};
+
+#define NPHY_RXCAL_TONEAMP 181
+#define NPHY_RXCAL_TONEFREQ_40MHz 4000
+#define NPHY_RXCAL_TONEFREQ_20MHz 2000
+
+enum {
+ NPHY_RXCAL_GAIN_INIT = 0,
+ NPHY_RXCAL_GAIN_UP,
+ NPHY_RXCAL_GAIN_DOWN
+};
+
+#define wlc_phy_get_papd_nphy(pi) \
+ (read_phy_reg((pi), 0x1e7) & \
+ ((0x1 << 15) | \
+ (0x1 << 14) | \
+ (0x1 << 13)))
+
+#define TXFILT_SHAPING_OFDM20 0
+#define TXFILT_SHAPING_OFDM40 1
+#define TXFILT_SHAPING_CCK 2
+#define TXFILT_DEFAULT_OFDM20 3
+#define TXFILT_DEFAULT_OFDM40 4
+
+uint16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
+ {-377, 137, -407, 208, -1527, 956, 93, 186, 93,
+ 230, -44, 230, 201, -191, 201},
+ {-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
+ 26, 34, -32, 34},
+ {-360, 164, -376, 164, -1533, 576, 308, -314, 308,
+ 121, -73, 121, 91, 124, 91},
+ {-295, 200, -363, 142, -1391, 826, 151, 301, 151,
+ 151, 301, 151, 602, -752, 602},
+ {-92, 58, -96, 49, -104, 44, 17, 35, 17,
+ 12, 25, 12, 13, 27, 13},
+ {-375, 136, -399, 209, -1479, 949, 130, 260, 130,
+ 230, -44, 230, 201, -191, 201},
+ {0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
+ 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
+};
+
+typedef struct _chan_info_nphy_2055 {
+ uint16 chan;
+ uint16 freq;
+ uint unknown;
+ uint8 RF_pll_ref;
+ uint8 RF_rf_pll_mod1;
+ uint8 RF_rf_pll_mod0;
+ uint8 RF_vco_cap_tail;
+ uint8 RF_vco_cal1;
+ uint8 RF_vco_cal2;
+ uint8 RF_pll_lf_c1;
+ uint8 RF_pll_lf_r1;
+ uint8 RF_pll_lf_c2;
+ uint8 RF_lgbuf_cen_buf;
+ uint8 RF_lgen_tune1;
+ uint8 RF_lgen_tune2;
+ uint8 RF_core1_lgbuf_a_tune;
+ uint8 RF_core1_lgbuf_g_tune;
+ uint8 RF_core1_rxrf_reg1;
+ uint8 RF_core1_tx_pga_pad_tn;
+ uint8 RF_core1_tx_mx_bgtrim;
+ uint8 RF_core2_lgbuf_a_tune;
+ uint8 RF_core2_lgbuf_g_tune;
+ uint8 RF_core2_rxrf_reg1;
+ uint8 RF_core2_tx_pga_pad_tn;
+ uint8 RF_core2_tx_mx_bgtrim;
+ uint16 PHY_BW1a;
+ uint16 PHY_BW2;
+ uint16 PHY_BW3;
+ uint16 PHY_BW4;
+ uint16 PHY_BW5;
+ uint16 PHY_BW6;
+} chan_info_nphy_2055_t;
+
+typedef struct _chan_info_nphy_radio205x {
+ uint16 chan;
+ uint16 freq;
+ uint8 RF_SYN_pll_vcocal1;
+ uint8 RF_SYN_pll_vcocal2;
+ uint8 RF_SYN_pll_refdiv;
+ uint8 RF_SYN_pll_mmd2;
+ uint8 RF_SYN_pll_mmd1;
+ uint8 RF_SYN_pll_loopfilter1;
+ uint8 RF_SYN_pll_loopfilter2;
+ uint8 RF_SYN_pll_loopfilter3;
+ uint8 RF_SYN_pll_loopfilter4;
+ uint8 RF_SYN_pll_loopfilter5;
+ uint8 RF_SYN_reserved_addr27;
+ uint8 RF_SYN_reserved_addr28;
+ uint8 RF_SYN_reserved_addr29;
+ uint8 RF_SYN_logen_VCOBUF1;
+ uint8 RF_SYN_logen_MIXER2;
+ uint8 RF_SYN_logen_BUF3;
+ uint8 RF_SYN_logen_BUF4;
+ uint8 RF_RX0_lnaa_tune;
+ uint8 RF_RX0_lnag_tune;
+ uint8 RF_TX0_intpaa_boost_tune;
+ uint8 RF_TX0_intpag_boost_tune;
+ uint8 RF_TX0_pada_boost_tune;
+ uint8 RF_TX0_padg_boost_tune;
+ uint8 RF_TX0_pgaa_boost_tune;
+ uint8 RF_TX0_pgag_boost_tune;
+ uint8 RF_TX0_mixa_boost_tune;
+ uint8 RF_TX0_mixg_boost_tune;
+ uint8 RF_RX1_lnaa_tune;
+ uint8 RF_RX1_lnag_tune;
+ uint8 RF_TX1_intpaa_boost_tune;
+ uint8 RF_TX1_intpag_boost_tune;
+ uint8 RF_TX1_pada_boost_tune;
+ uint8 RF_TX1_padg_boost_tune;
+ uint8 RF_TX1_pgaa_boost_tune;
+ uint8 RF_TX1_pgag_boost_tune;
+ uint8 RF_TX1_mixa_boost_tune;
+ uint8 RF_TX1_mixg_boost_tune;
+ uint16 PHY_BW1a;
+ uint16 PHY_BW2;
+ uint16 PHY_BW3;
+ uint16 PHY_BW4;
+ uint16 PHY_BW5;
+ uint16 PHY_BW6;
+} chan_info_nphy_radio205x_t;
+
+typedef struct _chan_info_nphy_radio2057 {
+ uint16 chan;
+ uint16 freq;
+ uint8 RF_vcocal_countval0;
+ uint8 RF_vcocal_countval1;
+ uint8 RF_rfpll_refmaster_sparextalsize;
+ uint8 RF_rfpll_loopfilter_r1;
+ uint8 RF_rfpll_loopfilter_c2;
+ uint8 RF_rfpll_loopfilter_c1;
+ uint8 RF_cp_kpd_idac;
+ uint8 RF_rfpll_mmd0;
+ uint8 RF_rfpll_mmd1;
+ uint8 RF_vcobuf_tune;
+ uint8 RF_logen_mx2g_tune;
+ uint8 RF_logen_mx5g_tune;
+ uint8 RF_logen_indbuf2g_tune;
+ uint8 RF_logen_indbuf5g_tune;
+ uint8 RF_txmix2g_tune_boost_pu_core0;
+ uint8 RF_pad2g_tune_pus_core0;
+ uint8 RF_pga_boost_tune_core0;
+ uint8 RF_txmix5g_boost_tune_core0;
+ uint8 RF_pad5g_tune_misc_pus_core0;
+ uint8 RF_lna2g_tune_core0;
+ uint8 RF_lna5g_tune_core0;
+ uint8 RF_txmix2g_tune_boost_pu_core1;
+ uint8 RF_pad2g_tune_pus_core1;
+ uint8 RF_pga_boost_tune_core1;
+ uint8 RF_txmix5g_boost_tune_core1;
+ uint8 RF_pad5g_tune_misc_pus_core1;
+ uint8 RF_lna2g_tune_core1;
+ uint8 RF_lna5g_tune_core1;
+ uint16 PHY_BW1a;
+ uint16 PHY_BW2;
+ uint16 PHY_BW3;
+ uint16 PHY_BW4;
+ uint16 PHY_BW5;
+ uint16 PHY_BW6;
+} chan_info_nphy_radio2057_t;
+
+typedef struct _chan_info_nphy_radio2057_rev5 {
+ uint16 chan;
+ uint16 freq;
+ uint8 RF_vcocal_countval0;
+ uint8 RF_vcocal_countval1;
+ uint8 RF_rfpll_refmaster_sparextalsize;
+ uint8 RF_rfpll_loopfilter_r1;
+ uint8 RF_rfpll_loopfilter_c2;
+ uint8 RF_rfpll_loopfilter_c1;
+ uint8 RF_cp_kpd_idac;
+ uint8 RF_rfpll_mmd0;
+ uint8 RF_rfpll_mmd1;
+ uint8 RF_vcobuf_tune;
+ uint8 RF_logen_mx2g_tune;
+ uint8 RF_logen_indbuf2g_tune;
+ uint8 RF_txmix2g_tune_boost_pu_core0;
+ uint8 RF_pad2g_tune_pus_core0;
+ uint8 RF_lna2g_tune_core0;
+ uint8 RF_txmix2g_tune_boost_pu_core1;
+ uint8 RF_pad2g_tune_pus_core1;
+ uint8 RF_lna2g_tune_core1;
+ uint16 PHY_BW1a;
+ uint16 PHY_BW2;
+ uint16 PHY_BW3;
+ uint16 PHY_BW4;
+ uint16 PHY_BW5;
+ uint16 PHY_BW6;
+} chan_info_nphy_radio2057_rev5_t;
+
+typedef struct nphy_sfo_cfg {
+ uint16 PHY_BW1a;
+ uint16 PHY_BW2;
+ uint16 PHY_BW3;
+ uint16 PHY_BW4;
+ uint16 PHY_BW5;
+ uint16 PHY_BW6;
+} nphy_sfo_cfg_t;
+
+static chan_info_nphy_2055_t chan_info_nphy_2055[] = {
+ {
+ 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
+ {
+ 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
+ {
+ 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
+ {
+ 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
+ {
+ 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
+ {
+ 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
+ {
+ 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
+ {
+ 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
+ {
+ 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
+ {
+ 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
+ {
+ 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
+ {
+ 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
+ {
+ 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
+ {
+ 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+ 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
+ {
+ 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+ 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
+ {
+ 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+ 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
+ {
+ 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+ 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
+ {
+ 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+ 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
+ {
+ 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+ 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
+ {
+ 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+ 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
+ {
+ 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+ 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
+ {
+ 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+ 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
+ {
+ 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
+ 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
+ {
+ 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+ 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
+ {
+ 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+ 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
+ {
+ 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+ 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
+ {
+ 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+ 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+ 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
+ {
+ 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+ 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
+ {
+ 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+ 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
+ {
+ 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+ 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
+ {
+ 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+ 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+ 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
+ {
+ 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+ 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
+ {
+ 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+ 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
+ {
+ 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+ 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
+ {
+ 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+ 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+ 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
+ {
+ 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+ 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
+ {
+ 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+ 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
+ {
+ 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+ 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
+ {
+ 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+ 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+ 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
+ {
+ 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+ 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
+ {
+ 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+ 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
+ {
+ 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+ 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
+ {
+ 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+ 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+ 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
+ {
+ 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+ 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
+ {
+ 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+ 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
+ {
+ 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+ 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
+ {
+ 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+ 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+ 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
+ {
+ 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+ 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
+ {
+ 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+ 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
+ {
+ 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+ 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
+ {
+ 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+ 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+ 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
+ {
+ 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+ 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
+ {
+ 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+ 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
+ {
+ 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+ 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
+ {
+ 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+ 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+ 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
+ {
+ 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+ 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
+ {
+ 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+ 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
+ {
+ 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+ 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
+ {
+ 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+ 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+ 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
+ {
+ 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+ 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
+ {
+ 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+ 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
+ {
+ 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+ 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
+ {
+ 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+ 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+ 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
+ {
+ 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+ 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
+ {
+ 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+ 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
+ {
+ 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+ 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
+ {
+ 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+ 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+ 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
+ {
+ 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+ 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
+ {
+ 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+ 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
+ {
+ 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+ 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
+ {
+ 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+ 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+ 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
+ {
+ 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
+ {
+ 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
+ {
+ 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
+ {
+ 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
+ {
+ 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
+ {
+ 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
+ {
+ 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
+ {
+ 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
+ {
+ 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
+ {
+ 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
+ {
+ 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
+ {
+ 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
+ {
+ 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
+ {
+ 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
+ {
+ 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
+ {
+ 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
+ {
+ 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
+ {
+ 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
+ {
+ 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
+ {
+ 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
+ {
+ 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
+ {
+ 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
+ {
+ 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
+ {
+ 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
+ {
+ 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
+ {
+ 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
+ {
+ 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
+ {
+ 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
+ {
+ 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
+ {
+ 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
+ {
+ 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
+ {
+ 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
+ {
+ 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
+ {
+ 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
+ {
+ 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
+ {
+ 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
+ {
+ 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
+ {
+ 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
+ {
+ 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
+ {
+ 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
+ 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
+ {
+ 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
+ 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
+ {
+ 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+ 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
+ {
+ 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+ 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
+ {
+ 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
+ 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
+ {
+ 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
+ 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
+ {
+ 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
+ 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
+ {
+ 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
+ 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
+ {
+ 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
+ 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
+ {
+ 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
+ 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
+ {
+ 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
+ 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
+ {
+ 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
+ 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
+ {
+ 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
+ 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
+ {
+ 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+ 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
+ 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+ 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+ 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+ 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
+ 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+ 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+ 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+ 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
+ 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+ 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+ 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+ 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+ 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+ 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+ 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+ 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+ 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+ 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
+ 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+ 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+ 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+ 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+ 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+ 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+ 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+ 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+ 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = {
+ {
+ 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+ {
+ 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+ {
+ 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+ {
+ 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+ {
+ 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+ {
+ 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+ {
+ 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+ {
+ 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+ {
+ 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+ {
+ 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+ {
+ 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+ {
+ 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+ {
+ 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+ {
+ 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+ {
+ 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+ {
+ 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+ {
+ 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+ {
+ 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+ {
+ 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+ {
+ 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+ {
+ 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+ {
+ 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+ {
+ 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+ 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+ 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+ {
+ 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+ {
+ 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+ {
+ 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+ 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+ {
+ 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+ {
+ 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+ {
+ 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+ {
+ 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+ {
+ 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+ {
+ 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+ {
+ 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+ {
+ 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+ 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+ {
+ 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+ {
+ 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+ {
+ 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+ {
+ 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+ {
+ 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+ {
+ 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+ 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+ {
+ 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+ {
+ 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+ {
+ 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+ 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+ {
+ 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+ {
+ 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+ {
+ 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+ {
+ 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+ {
+ 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+ {
+ 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+ {
+ 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+ {
+ 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+ 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+ {
+ 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+ {
+ 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+ {
+ 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+ {
+ 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+ {
+ 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+ {
+ 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+ {
+ 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+ {
+ 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+ {
+ 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+ {
+ 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+ {
+ 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+ {
+ 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+ {
+ 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+ {
+ 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+ 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+ {
+ 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+ {
+ 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+ {
+ 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+ {
+ 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+ 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+ {
+ 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+ {
+ 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+ {
+ 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+ {
+ 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+ 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+ {
+ 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+ {
+ 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+ {
+ 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+ {
+ 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+ {
+ 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+ {
+ 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+ {
+ 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+ {
+ 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+ {
+ 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+ {
+ 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+ {
+ 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+ 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+ {
+ 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+ {
+ 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+ {
+ 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+ {
+ 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+ {
+ 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+ {
+ 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+ {
+ 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+ {
+ 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+ {
+ 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+ {
+ 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+ {
+ 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+ {
+ 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+ {
+ 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+ {
+ 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+ 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+ {
+ 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+ {
+ 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+ {
+ 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+ {
+ 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+ {
+ 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+ {
+ 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+ {
+ 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+ {
+ 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+ 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+ 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+ {
+ 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
+ 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+ 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = {
+ {
+ 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+ 0x0215,
+ 0x0216,
+ },
+ {
+ 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+ 0x0214,
+ 0x0215,
+ },
+ {
+ 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+ 0x0213,
+ 0x0214,
+ },
+ {
+ 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+ 0x0212,
+ 0x0213,
+ },
+ {
+ 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+ 0x0211,
+ 0x0212,
+ },
+ {
+ 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+ 0x020f,
+ 0x0211,
+ },
+ {
+ 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+ 0x020e,
+ 0x020f,
+ },
+ {
+ 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+ 0x020d,
+ 0x020e,
+ },
+ {
+ 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+ 0x020c,
+ 0x020d,
+ },
+ {
+ 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+ 0x020b,
+ 0x020c,
+ },
+ {
+ 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+ 0x020a,
+ 0x020b,
+ },
+ {
+ 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+ 0x0209,
+ 0x020a,
+ },
+ {
+ 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+ 0x0208,
+ 0x0209,
+ },
+ {
+ 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+ 0x0207,
+ 0x0208,
+ },
+ {
+ 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+ 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+ 0x0206,
+ 0x0207,
+ },
+ {
+ 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+ 0x0205,
+ 0x0206,
+ },
+ {
+ 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+ 0x0204,
+ 0x0205,
+ },
+ {
+ 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+ 0x0203,
+ 0x0204,
+ },
+ {
+ 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+ 0x0202,
+ 0x0203,
+ },
+ {
+ 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
+ 0x0201,
+ 0x0202,
+ },
+ {
+ 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
+ 0x0200,
+ 0x0201,
+ },
+ {
+ 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
+ 0x01ff,
+ 0x0200,
+ },
+ {
+ 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
+ 0x01fe,
+ 0x01ff,
+ },
+ {
+ 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
+ 0x01fc,
+ 0x01fd,
+ },
+ {
+ 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
+ 0x01fb,
+ 0x01fc,
+ },
+ {
+ 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
+ 0x01fa,
+ 0x01fb,
+ },
+ {
+ 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
+ 0x01f9,
+ 0x01fa,
+ },
+ {
+ 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
+ 0x01f8,
+ 0x01f9,
+ },
+ {
+ 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
+ 0x01f7,
+ 0x01f8,
+ },
+ {
+ 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
+ 0x01f6,
+ 0x01f7,
+ },
+ {
+ 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
+ 0x01f5,
+ 0x01f6,
+ },
+ {
+ 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
+ 0x01f4,
+ 0x01f5,
+ },
+ {
+ 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
+ 0x01f3,
+ 0x01f4,
+ },
+ {
+ 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
+ 0x01f2,
+ 0x01f3,
+ },
+ {
+ 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+ 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
+ 0x01f1,
+ 0x01f2,
+ },
+ {
+ 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
+ 0x01f0,
+ 0x01f1,
+ },
+ {
+ 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
+ 0x01f0,
+ 0x01f0,
+ },
+ {
+ 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
+ 0x01ef,
+ 0x01f0,
+ },
+ {
+ 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
+ 0x01ee,
+ 0x01ef,
+ },
+ {
+ 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
+ 0x01ed,
+ 0x01ee,
+ },
+ {
+ 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+ 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
+ 0x01ec,
+ 0x01ed,
+ },
+ {
+ 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
+ 0x01eb,
+ 0x01ec,
+ },
+ {
+ 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
+ 0x01ea,
+ 0x01eb,
+ },
+ {
+ 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
+ 0x01e9,
+ 0x01ea,
+ },
+ {
+ 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
+ 0x01e8,
+ 0x01e9,
+ },
+ {
+ 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
+ 0x01e7,
+ 0x01e8,
+ },
+ {
+ 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
+ 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
+ 0x01e6,
+ 0x01e7,
+ },
+ {
+ 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
+ 0x01e5,
+ 0x01e6,
+ },
+ {
+ 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
+ 0x01e5,
+ 0x01e5,
+ },
+ {
+ 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
+ 0x01e4,
+ 0x01e5,
+ },
+ {
+ 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
+ 0x01e3,
+ 0x01e4,
+ },
+ {
+ 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
+ 0x01e2,
+ 0x01e3,
+ },
+ {
+ 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+ 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
+ 0x01e1,
+ 0x01e2,
+ },
+ {
+ 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
+ 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
+ 0x01e0,
+ 0x01e1,
+ },
+ {
+ 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
+ 0x01df,
+ 0x01e0,
+ },
+ {
+ 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
+ 0x01de,
+ 0x01df,
+ },
+ {
+ 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
+ 0x01dd,
+ 0x01de,
+ },
+ {
+ 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
+ 0x01dd,
+ 0x01dd,
+ },
+ {
+ 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
+ 0x01dc,
+ 0x01dd,
+ },
+ {
+ 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
+ 0x01db,
+ 0x01dc,
+ },
+ {
+ 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+ 0x01da,
+ 0x01db,
+ },
+ {
+ 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+ 0x01d9,
+ 0x01da,
+ },
+ {
+ 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+ 0x01d8,
+ 0x01d9,
+ },
+ {
+ 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+ 0x01d7,
+ 0x01d8,
+ },
+ {
+ 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+ 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+ 0x01d7,
+ 0x01d7,
+ },
+ {
+ 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
+ 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+ 0x01d6,
+ 0x01d7,
+ },
+ {
+ 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
+ 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+ 0x01d5,
+ 0x01d6,
+ },
+ {
+ 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
+ 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+ 0x01d4,
+ 0x01d5,
+ },
+ {
+ 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+ 0x01d3,
+ 0x01d4,
+ },
+ {
+ 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+ 0x01d2,
+ 0x01d3,
+ },
+ {
+ 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+ 0x01d2,
+ 0x01d2,
+ },
+ {
+ 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+ 0x01d1,
+ 0x01d2,
+ },
+ {
+ 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+ 0x01d0,
+ 0x01d1,
+ },
+ {
+ 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+ 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+ 0x01cf,
+ 0x01d0,
+ },
+ {
+ 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+ 0x01ce,
+ 0x01cf,
+ },
+ {
+ 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+ 0x01ce,
+ 0x01ce,
+ },
+ {
+ 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+ 0x01cd,
+ 0x01ce,
+ },
+ {
+ 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+ 0x01cc,
+ 0x01cd,
+ },
+ {
+ 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+ 0x01cb,
+ 0x01cc,
+ },
+ {
+ 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+ 0x01ca,
+ 0x01cb,
+ },
+ {
+ 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+ 0x01ca,
+ 0x01cb,
+ },
+ {
+ 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+ 0x01c9,
+ 0x01ca,
+ },
+ {
+ 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+ 0x01c9,
+ 0x01ca,
+ },
+ {
+ 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+ 0x01c9,
+ 0x01c9,
+ },
+ {
+ 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+ 0x01c8,
+ 0x01c9,
+ },
+ {
+ 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+ 0x01c8,
+ 0x01c9,
+ },
+ {
+ 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+ 0x01c8,
+ 0x01c8,
+ },
+ {
+ 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+ 0x01c7,
+ 0x01c8,
+ },
+ {
+ 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+ 0x01c7,
+ 0x01c8,
+ },
+ {
+ 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+ 0x01c6,
+ 0x01c7,
+ },
+ {
+ 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+ 0x01c6,
+ 0x01c7,
+ },
+ {
+ 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+ 0x01c6,
+ 0x01c6,
+ },
+ {
+ 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+ 0x01c5,
+ 0x01c6,
+ },
+ {
+ 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+ 0x01c5,
+ 0x01c6,
+ },
+ {
+ 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+ 0x01c4,
+ 0x01c5,
+ },
+ {
+ 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+ 0x01c4,
+ 0x01c5,
+ },
+ {
+ 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+ 0x01c4,
+ 0x01c4,
+ },
+ {
+ 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+ 0x01c3,
+ 0x01c4,
+ },
+ {
+ 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+ 0x01c3,
+ 0x01c4,
+ },
+ {
+ 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+ 0x01c2,
+ 0x01c3,
+ },
+ {
+ 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+ 0x01c2,
+ 0x01c3,
+ },
+ {
+ 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+ 0x01c2,
+ 0x01c2,
+ },
+ {
+ 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+ 0x01c1,
+ 0x01c2,
+ },
+ {
+ 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+ 0x01c0,
+ 0x01c1,
+ },
+ {
+ 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+ 0x01bf,
+ 0x01c0,
+ },
+ {
+ 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+ 0x01bf,
+ 0x01bf,
+ },
+ {
+ 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+ 0x01be,
+ 0x01bf,
+ },
+ {
+ 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+ 0x01bd,
+ 0x01be,
+ },
+ {
+ 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+ 0x01bc,
+ 0x01bd,
+ },
+ {
+ 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+ 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+ 0x043f,
+ 0x0443,
+ },
+ {
+ 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+ 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+ 0x043d,
+ 0x0441,
+ },
+ {
+ 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+ 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+ 0x043a,
+ 0x043f,
+ },
+ {
+ 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+ 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+ 0x0438,
+ 0x043d,
+ },
+ {
+ 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+ 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+ 0x0436,
+ 0x043a,
+ },
+ {
+ 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+ 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+ 0x0434,
+ 0x0438,
+ },
+ {
+ 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+ 0x0431,
+ 0x0436,
+ },
+ {
+ 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+ 0x042f,
+ 0x0434,
+ },
+ {
+ 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+ 0x042d,
+ 0x0431,
+ },
+ {
+ 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+ 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+ 0x042b,
+ 0x042f,
+ },
+ {
+ 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+ 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+ 0x0429,
+ 0x042d,
+ },
+ {
+ 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+ 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+ 0x0427,
+ 0x042b,
+ },
+ {
+ 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+ 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+ 0x0424,
+ 0x0429,
+ },
+ {
+ 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+ 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
+ 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+ 0x041f,
+ 0x0424}
+};
+
+static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = {
+ {
+ 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+ 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+ 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+ 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+ 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+ 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+ 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+ 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+ 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+ 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+ 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+ 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+ 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+ 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+ 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+ 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+ 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+ 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+ 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+ 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+ 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+ 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+ 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = {
+ {
+ 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+ 0x043a, 0x043f, 0x0443},
+ {
+ 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+ 0x0438, 0x043d, 0x0441},
+ {
+ 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+ 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+ 0x0436, 0x043a, 0x043f},
+ {
+ 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+ 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+ 0x0434, 0x0438, 0x043d},
+ {
+ 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+ 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+ 0x0431, 0x0436, 0x043a},
+ {
+ 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+ 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+ 0x042f, 0x0434, 0x0438},
+ {
+ 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+ 0x042d, 0x0431, 0x0436},
+ {
+ 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+ 0x042b, 0x042f, 0x0434},
+ {
+ 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+ 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+ 0x0429, 0x042d, 0x0431},
+ {
+ 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+ 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+ 0x0427, 0x042b, 0x042f},
+ {
+ 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+ 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+ 0x0424, 0x0429, 0x042d},
+ {
+ 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+ 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+ 0x0422, 0x0427, 0x042b},
+ {
+ 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+ 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+ 0x0420, 0x0424, 0x0429},
+ {
+ 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+ 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+ 0x041b, 0x041f, 0x0424}
+};
+
+static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = {
+ {
+ 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+ 0x0215,
+ 0x0216},
+ {
+ 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+ 0x0214,
+ 0x0215},
+ {
+ 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+ 0x0213,
+ 0x0214},
+ {
+ 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+ 0x0212,
+ 0x0213},
+ {
+ 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+ 0x0211,
+ 0x0212},
+ {
+ 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+ 0x020f,
+ 0x0211},
+ {
+ 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+ 0x020e,
+ 0x020f},
+ {
+ 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+ 0x020d,
+ 0x020e},
+ {
+ 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+ 0x020c,
+ 0x020d},
+ {
+ 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+ 0x020b,
+ 0x020c},
+ {
+ 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+ 0x020a,
+ 0x020b},
+ {
+ 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+ 0x0209,
+ 0x020a},
+ {
+ 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+ 0x0208,
+ 0x0209},
+ {
+ 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+ 0x0207,
+ 0x0208},
+ {
+ 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+ 0x0206,
+ 0x0207},
+ {
+ 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+ 0x0205,
+ 0x0206},
+ {
+ 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+ 0x0204,
+ 0x0205},
+ {
+ 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+ 0x0203,
+ 0x0204},
+ {
+ 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+ 0x0202,
+ 0x0203},
+ {
+ 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+ 0x0201,
+ 0x0202},
+ {
+ 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+ 0x0200,
+ 0x0201},
+ {
+ 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+ 0x01ff,
+ 0x0200},
+ {
+ 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+ 0x01fe,
+ 0x01ff},
+ {
+ 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+ 0x01fc,
+ 0x01fd},
+ {
+ 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+ 0x01fb,
+ 0x01fc},
+ {
+ 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+ 0x01fa,
+ 0x01fb},
+ {
+ 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+ 0x01f9,
+ 0x01fa},
+ {
+ 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+ 0x01f8,
+ 0x01f9},
+ {
+ 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+ 0x01f7,
+ 0x01f8},
+ {
+ 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+ 0x01f6,
+ 0x01f7},
+ {
+ 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+ 0x01f5,
+ 0x01f6},
+ {
+ 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+ 0x01f4,
+ 0x01f5},
+ {
+ 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+ 0x01f3,
+ 0x01f4},
+ {
+ 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+ 0x01f2,
+ 0x01f3},
+ {
+ 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+ 0x01f1,
+ 0x01f2},
+ {
+ 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+ 0x01f0,
+ 0x01f1},
+ {
+ 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+ 0x01f0,
+ 0x01f0},
+ {
+ 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+ 0x01ef,
+ 0x01f0},
+ {
+ 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+ 0x01ee,
+ 0x01ef},
+ {
+ 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+ 0x01ed,
+ 0x01ee},
+ {
+ 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+ 0x01ec,
+ 0x01ed},
+ {
+ 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+ 0x01eb,
+ 0x01ec},
+ {
+ 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+ 0x01ea,
+ 0x01eb},
+ {
+ 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+ 0x01e9,
+ 0x01ea},
+ {
+ 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+ 0x01e8,
+ 0x01e9},
+ {
+ 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+ 0x01e7,
+ 0x01e8},
+ {
+ 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+ 0x01e6,
+ 0x01e7},
+ {
+ 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+ 0x01e5,
+ 0x01e6},
+ {
+ 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+ 0x01e5,
+ 0x01e5},
+ {
+ 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+ 0x01e4,
+ 0x01e5},
+ {
+ 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+ 0x01e3,
+ 0x01e4},
+ {
+ 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+ 0x01e2,
+ 0x01e3},
+ {
+ 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+ 0x01e1,
+ 0x01e2},
+ {
+ 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+ 0x01e0,
+ 0x01e1},
+ {
+ 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+ 0x01df,
+ 0x01e0},
+ {
+ 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+ 0x01de,
+ 0x01df},
+ {
+ 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+ 0x01dd,
+ 0x01de},
+ {
+ 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+ 0x01dd,
+ 0x01dd},
+ {
+ 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+ 0x01dc,
+ 0x01dd},
+ {
+ 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+ 0x01db,
+ 0x01dc},
+ {
+ 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+ 0x01da,
+ 0x01db},
+ {
+ 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+ 0x01d9,
+ 0x01da},
+ {
+ 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+ 0x01d8,
+ 0x01d9},
+ {
+ 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+ 0x01d7,
+ 0x01d8},
+ {
+ 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+ 0x01d7,
+ 0x01d7},
+ {
+ 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+ 0x01d6,
+ 0x01d7},
+ {
+ 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+ 0x01d5,
+ 0x01d6},
+ {
+ 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+ 0x01d4,
+ 0x01d5},
+ {
+ 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+ 0x01d3,
+ 0x01d4},
+ {
+ 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+ 0x01d2,
+ 0x01d3},
+ {
+ 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+ 0x01d2,
+ 0x01d2},
+ {
+ 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+ 0x01d1,
+ 0x01d2},
+ {
+ 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+ 0x01d0,
+ 0x01d1},
+ {
+ 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+ 0x01cf,
+ 0x01d0},
+ {
+ 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+ 0x01ce,
+ 0x01cf},
+ {
+ 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+ 0x01ce,
+ 0x01ce},
+ {
+ 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+ 0x01cd,
+ 0x01ce},
+ {
+ 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+ 0x01cc,
+ 0x01cd},
+ {
+ 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+ 0x01cb,
+ 0x01cc},
+ {
+ 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+ 0x01ca,
+ 0x01cb},
+ {
+ 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+ 0x01ca,
+ 0x01cb},
+ {
+ 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+ 0x01c9,
+ 0x01ca},
+ {
+ 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+ 0x01c9,
+ 0x01ca},
+ {
+ 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+ 0x01c9,
+ 0x01c9},
+ {
+ 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+ 0x01c8,
+ 0x01c9},
+ {
+ 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+ 0x01c8,
+ 0x01c9},
+ {
+ 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+ 0x01c8,
+ 0x01c8},
+ {
+ 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+ 0x01c7,
+ 0x01c8},
+ {
+ 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+ 0x01c7,
+ 0x01c8},
+ {
+ 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+ 0x01c6,
+ 0x01c7},
+ {
+ 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+ 0x01c6,
+ 0x01c7},
+ {
+ 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+ 0x01c6,
+ 0x01c6},
+ {
+ 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+ 0x01c5,
+ 0x01c6},
+ {
+ 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+ 0x01c5,
+ 0x01c6},
+ {
+ 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+ 0x01c4,
+ 0x01c5},
+ {
+ 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+ 0x01c4,
+ 0x01c5},
+ {
+ 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+ 0x01c4,
+ 0x01c4},
+ {
+ 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+ 0x01c3,
+ 0x01c4},
+ {
+ 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+ 0x01c3,
+ 0x01c4},
+ {
+ 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+ 0x01c2,
+ 0x01c3},
+ {
+ 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+ 0x01c2,
+ 0x01c3},
+ {
+ 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+ 0x01c2,
+ 0x01c2},
+ {
+ 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+ 0x01c1,
+ 0x01c2},
+ {
+ 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+ 0x01c0,
+ 0x01c1},
+ {
+ 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+ 0x01bf,
+ 0x01c0},
+ {
+ 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+ 0x01bf,
+ 0x01bf},
+ {
+ 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+ 0x01be,
+ 0x01bf},
+ {
+ 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+ 0x01bd,
+ 0x01be},
+ {
+ 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+ 0x01bc,
+ 0x01bd},
+ {
+ 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+ 0x043f,
+ 0x0443},
+ {
+ 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+ 0x043d,
+ 0x0441},
+ {
+ 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+ 0x043a,
+ 0x043f},
+ {
+ 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+ 0x0438,
+ 0x043d},
+ {
+ 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+ 0x0436,
+ 0x043a},
+ {
+ 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+ 0x0434,
+ 0x0438},
+ {
+ 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+ 0x0431,
+ 0x0436},
+ {
+ 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+ 0x042f,
+ 0x0434},
+ {
+ 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+ 0x042d,
+ 0x0431},
+ {
+ 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+ 0x042b,
+ 0x042f},
+ {
+ 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+ 0x0429,
+ 0x042d},
+ {
+ 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+ 0x0427,
+ 0x042b},
+ {
+ 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+ 0x0424,
+ 0x0429},
+ {
+ 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+ 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+ 0x041f,
+ 0x0424}
+};
+
+static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = {
+ {
+ 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+ 0x0214,
+ 0x0215},
+ {
+ 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+ 0x0213,
+ 0x0214},
+ {
+ 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+ 0x0212,
+ 0x0213},
+ {
+ 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+ 0x0211,
+ 0x0212},
+ {
+ 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+ 0x020f,
+ 0x0211},
+ {
+ 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+ 0x020e,
+ 0x020f},
+ {
+ 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+ 0x020d,
+ 0x020e},
+ {
+ 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+ 0x020c,
+ 0x020d},
+ {
+ 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+ 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+ 0x020b,
+ 0x020c},
+ {
+ 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+ 0x020a,
+ 0x020b},
+ {
+ 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+ 0x0209,
+ 0x020a},
+ {
+ 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+ 0x0208,
+ 0x0209},
+ {
+ 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+ 0x0207,
+ 0x0208},
+ {
+ 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+ 0x0206,
+ 0x0207},
+ {
+ 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+ 0x0205,
+ 0x0206},
+ {
+ 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+ 0x0204,
+ 0x0205},
+ {
+ 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+ 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+ 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+ 0x0203,
+ 0x0204},
+ {
+ 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+ 0x0202,
+ 0x0203},
+ {
+ 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+ 0x0201,
+ 0x0202},
+ {
+ 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+ 0x0200,
+ 0x0201},
+ {
+ 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+ 0x01ff,
+ 0x0200},
+ {
+ 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+ 0x01fe,
+ 0x01ff},
+ {
+ 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+ 0x01fc,
+ 0x01fd},
+ {
+ 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+ 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+ 0x01fb,
+ 0x01fc},
+ {
+ 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+ 0x01fa,
+ 0x01fb},
+ {
+ 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+ 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+ 0x01f9,
+ 0x01fa},
+ {
+ 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+ 0x01f8,
+ 0x01f9},
+ {
+ 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+ 0x01f7,
+ 0x01f8},
+ {
+ 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+ 0x01f6,
+ 0x01f7},
+ {
+ 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+ 0x01f5,
+ 0x01f6},
+ {
+ 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+ 0x01f4,
+ 0x01f5},
+ {
+ 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+ 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+ 0x01f3,
+ 0x01f4},
+ {
+ 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+ 0x01f2,
+ 0x01f3},
+ {
+ 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+ 0x01f1,
+ 0x01f2},
+ {
+ 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+ 0x01f0,
+ 0x01f1},
+ {
+ 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+ 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+ 0x01f0,
+ 0x01f0},
+ {
+ 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+ 0x01ef,
+ 0x01f0},
+ {
+ 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+ 0x01ee,
+ 0x01ef},
+ {
+ 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+ 0x01ed,
+ 0x01ee},
+ {
+ 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+ 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+ 0x01ec,
+ 0x01ed},
+ {
+ 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+ 0x01eb,
+ 0x01ec},
+ {
+ 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+ 0x01ea,
+ 0x01eb},
+ {
+ 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+ 0x01e9,
+ 0x01ea},
+ {
+ 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+ 0x01e8,
+ 0x01e9},
+ {
+ 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+ 0x01e7,
+ 0x01e8},
+ {
+ 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+ 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+ 0x01e6,
+ 0x01e7},
+ {
+ 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+ 0x01e5,
+ 0x01e6},
+ {
+ 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+ 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+ 0x01e5,
+ 0x01e5},
+ {
+ 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+ 0x01e4,
+ 0x01e5},
+ {
+ 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+ 0x01e3,
+ 0x01e4},
+ {
+ 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+ 0x01e2,
+ 0x01e3},
+ {
+ 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+ 0x01e1,
+ 0x01e2},
+ {
+ 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+ 0x01e0,
+ 0x01e1},
+ {
+ 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+ 0x01df,
+ 0x01e0},
+ {
+ 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+ 0x01de,
+ 0x01df},
+ {
+ 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+ 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+ 0x01dd,
+ 0x01de},
+ {
+ 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+ 0x01dd,
+ 0x01dd},
+ {
+ 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+ 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+ 0x01dc,
+ 0x01dd},
+ {
+ 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+ 0x01db,
+ 0x01dc},
+ {
+ 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+ 0x01da,
+ 0x01db},
+ {
+ 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+ 0x01d9,
+ 0x01da},
+ {
+ 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+ 0x01d8,
+ 0x01d9},
+ {
+ 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+ 0x01d7,
+ 0x01d8},
+ {
+ 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+ 0x01d7,
+ 0x01d7},
+ {
+ 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+ 0x01d6,
+ 0x01d7},
+ {
+ 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+ 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+ 0x01d5,
+ 0x01d6},
+ {
+ 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+ 0x01d4,
+ 0x01d5},
+ {
+ 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+ 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+ 0x01d3,
+ 0x01d4},
+ {
+ 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+ 0x01d2,
+ 0x01d3},
+ {
+ 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+ 0x01d2,
+ 0x01d2},
+ {
+ 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+ 0x01d1,
+ 0x01d2},
+ {
+ 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+ 0x01d0,
+ 0x01d1},
+ {
+ 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+ 0x01cf,
+ 0x01d0},
+ {
+ 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+ 0x01ce,
+ 0x01cf},
+ {
+ 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+ 0x01ce,
+ 0x01ce},
+ {
+ 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+ 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+ 0x01cd,
+ 0x01ce},
+ {
+ 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+ 0x01cc,
+ 0x01cd},
+ {
+ 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+ 0x01cb,
+ 0x01cc},
+ {
+ 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+ 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+ 0x01ca,
+ 0x01cb},
+ {
+ 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+ 0x01ca,
+ 0x01cb},
+ {
+ 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+ 0x01c9,
+ 0x01ca},
+ {
+ 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+ 0x01c9,
+ 0x01ca},
+ {
+ 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+ 0x01c9,
+ 0x01c9},
+ {
+ 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+ 0x01c8,
+ 0x01c9},
+ {
+ 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+ 0x01c8,
+ 0x01c9},
+ {
+ 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+ 0x01c8,
+ 0x01c8},
+ {
+ 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+ 0x01c7,
+ 0x01c8},
+ {
+ 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+ 0x01c7,
+ 0x01c8},
+ {
+ 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+ 0x01c6,
+ 0x01c7},
+ {
+ 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+ 0x01c6,
+ 0x01c7},
+ {
+ 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+ 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+ 0x01c6,
+ 0x01c6},
+ {
+ 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+ 0x01c5,
+ 0x01c6},
+ {
+ 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+ 0x01c5,
+ 0x01c6},
+ {
+ 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+ 0x01c4,
+ 0x01c5},
+ {
+ 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+ 0x01c4,
+ 0x01c5},
+ {
+ 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+ 0x01c4,
+ 0x01c4},
+ {
+ 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+ 0x01c3,
+ 0x01c4},
+ {
+ 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+ 0x01c3,
+ 0x01c4},
+ {
+ 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+ 0x01c2,
+ 0x01c3},
+ {
+ 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+ 0x01c2,
+ 0x01c3},
+ {
+ 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+ 0x01c2,
+ 0x01c2},
+ {
+ 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+ 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+ 0x01c1,
+ 0x01c2},
+ {
+ 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+ 0x01c0,
+ 0x01c1},
+ {
+ 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+ 0x01bf,
+ 0x01c0},
+ {
+ 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+ 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+ 0x01bf,
+ 0x01bf},
+ {
+ 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+ 0x01be,
+ 0x01bf},
+ {
+ 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+ 0x01bd,
+ 0x01be},
+ {
+ 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+ 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+ 0x01bc,
+ 0x01bd},
+ {
+ 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+ 0x043f,
+ 0x0443},
+ {
+ 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+ 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+ 0x043d,
+ 0x0441},
+ {
+ 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+ 0x043a,
+ 0x043f},
+ {
+ 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+ 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+ 0x0438,
+ 0x043d},
+ {
+ 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+ 0x0436,
+ 0x043a},
+ {
+ 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+ 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+ 0x0434,
+ 0x0438},
+ {
+ 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+ 0x0431,
+ 0x0436},
+ {
+ 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+ 0x042f,
+ 0x0434},
+ {
+ 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+ 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+ 0x042d,
+ 0x0431},
+ {
+ 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+ 0x042b,
+ 0x042f},
+ {
+ 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+ 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+ 0x0429,
+ 0x042d},
+ {
+ 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+ 0x0427,
+ 0x042b},
+ {
+ 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+ 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+ 0x0424,
+ 0x0429},
+ {
+ 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+ 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+ 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+ 0x041f,
+ 0x0424}
+};
+
+radio_regs_t regs_2055[] = {
+ {0x02, 0x80, 0x80, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0x27, 0x27, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0x27, 0x27, 0, 0},
+ {0x07, 0x7f, 0x7f, 1, 1},
+ {0x08, 0x7, 0x7, 1, 1},
+ {0x09, 0x7f, 0x7f, 1, 1},
+ {0x0A, 0x7, 0x7, 1, 1},
+ {0x0B, 0x15, 0x15, 0, 0},
+ {0x0C, 0x15, 0x15, 0, 0},
+ {0x0D, 0x4f, 0x4f, 1, 1},
+ {0x0E, 0x5, 0x5, 1, 1},
+ {0x0F, 0x4f, 0x4f, 1, 1},
+ {0x10, 0x5, 0x5, 1, 1},
+ {0x11, 0xd0, 0xd0, 0, 0},
+ {0x12, 0x2, 0x2, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0x40, 0x40, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0xc0, 0xc0, 0, 0},
+ {0x1E, 0xff, 0xff, 0, 0},
+ {0x1F, 0xc0, 0xc0, 0, 0},
+ {0x20, 0xff, 0xff, 0, 0},
+ {0x21, 0xc0, 0xc0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x2c, 0x2c, 0, 0},
+ {0x24, 0, 0, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0xa4, 0xa4, 0, 0},
+ {0x2E, 0x38, 0x38, 0, 0},
+ {0x2F, 0, 0, 0, 0},
+ {0x30, 0x4, 0x4, 1, 1},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0xa, 0xa, 0, 0},
+ {0x33, 0x87, 0x87, 0, 0},
+ {0x34, 0x9, 0x9, 0, 0},
+ {0x35, 0x70, 0x70, 0, 0},
+ {0x36, 0x11, 0x11, 0, 0},
+ {0x37, 0x18, 0x18, 1, 1},
+ {0x38, 0x6, 0x6, 0, 0},
+ {0x39, 0x4, 0x4, 1, 1},
+ {0x3A, 0x6, 0x6, 0, 0},
+ {0x3B, 0x9e, 0x9e, 0, 0},
+ {0x3C, 0x9, 0x9, 0, 0},
+ {0x3D, 0xc8, 0xc8, 1, 1},
+ {0x3E, 0x88, 0x88, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0, 0, 0, 0},
+ {0x42, 0x1, 0x1, 0, 0},
+ {0x43, 0x2, 0x2, 0, 0},
+ {0x44, 0x96, 0x96, 0, 0},
+ {0x45, 0x3e, 0x3e, 0, 0},
+ {0x46, 0x3e, 0x3e, 0, 0},
+ {0x47, 0x13, 0x13, 0, 0},
+ {0x48, 0x2, 0x2, 0, 0},
+ {0x49, 0x15, 0x15, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0, 0, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0, 0, 0, 0},
+ {0x50, 0x8, 0x8, 0, 0},
+ {0x51, 0x8, 0x8, 0, 0},
+ {0x52, 0x6, 0x6, 0, 0},
+ {0x53, 0x84, 0x84, 1, 1},
+ {0x54, 0xc3, 0xc3, 0, 0},
+ {0x55, 0x8f, 0x8f, 0, 0},
+ {0x56, 0xff, 0xff, 0, 0},
+ {0x57, 0xff, 0xff, 0, 0},
+ {0x58, 0x88, 0x88, 0, 0},
+ {0x59, 0x88, 0x88, 0, 0},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0xcc, 0xcc, 0, 0},
+ {0x5C, 0x6, 0x6, 0, 0},
+ {0x5D, 0x80, 0x80, 0, 0},
+ {0x5E, 0x80, 0x80, 0, 0},
+ {0x5F, 0xf8, 0xf8, 0, 0},
+ {0x60, 0x88, 0x88, 0, 0},
+ {0x61, 0x88, 0x88, 0, 0},
+ {0x62, 0x88, 0x8, 1, 1},
+ {0x63, 0x88, 0x88, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0x1, 0x1, 1, 1},
+ {0x66, 0x8a, 0x8a, 0, 0},
+ {0x67, 0x8, 0x8, 0, 0},
+ {0x68, 0x83, 0x83, 0, 0},
+ {0x69, 0x6, 0x6, 0, 0},
+ {0x6A, 0xa0, 0xa0, 0, 0},
+ {0x6B, 0xa, 0xa, 0, 0},
+ {0x6C, 0x87, 0x87, 1, 1},
+ {0x6D, 0x2a, 0x2a, 0, 0},
+ {0x6E, 0x2a, 0x2a, 0, 0},
+ {0x6F, 0x2a, 0x2a, 0, 0},
+ {0x70, 0x2a, 0x2a, 0, 0},
+ {0x71, 0x18, 0x18, 0, 0},
+ {0x72, 0x6a, 0x6a, 1, 1},
+ {0x73, 0xab, 0xab, 1, 1},
+ {0x74, 0x13, 0x13, 1, 1},
+ {0x75, 0xc1, 0xc1, 1, 1},
+ {0x76, 0xaa, 0xaa, 1, 1},
+ {0x77, 0x87, 0x87, 1, 1},
+ {0x78, 0, 0, 0, 0},
+ {0x79, 0x6, 0x6, 0, 0},
+ {0x7A, 0x7, 0x7, 0, 0},
+ {0x7B, 0x7, 0x7, 0, 0},
+ {0x7C, 0x15, 0x15, 0, 0},
+ {0x7D, 0x55, 0x55, 0, 0},
+ {0x7E, 0x97, 0x97, 1, 1},
+ {0x7F, 0x8, 0x8, 0, 0},
+ {0x80, 0x14, 0x14, 1, 1},
+ {0x81, 0x33, 0x33, 0, 0},
+ {0x82, 0x88, 0x88, 0, 0},
+ {0x83, 0x6, 0x6, 0, 0},
+ {0x84, 0x3, 0x3, 1, 1},
+ {0x85, 0xa, 0xa, 0, 0},
+ {0x86, 0x3, 0x3, 1, 1},
+ {0x87, 0x2a, 0x2a, 0, 0},
+ {0x88, 0xa4, 0xa4, 0, 0},
+ {0x89, 0x18, 0x18, 0, 0},
+ {0x8A, 0x28, 0x28, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0x4a, 0x4a, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0xf8, 0xf8, 0, 0},
+ {0x8F, 0x88, 0x88, 0, 0},
+ {0x90, 0x88, 0x88, 0, 0},
+ {0x91, 0x88, 0x8, 1, 1},
+ {0x92, 0x88, 0x88, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0x1, 0x1, 1, 1},
+ {0x95, 0x8a, 0x8a, 0, 0},
+ {0x96, 0x8, 0x8, 0, 0},
+ {0x97, 0x83, 0x83, 0, 0},
+ {0x98, 0x6, 0x6, 0, 0},
+ {0x99, 0xa0, 0xa0, 0, 0},
+ {0x9A, 0xa, 0xa, 0, 0},
+ {0x9B, 0x87, 0x87, 1, 1},
+ {0x9C, 0x2a, 0x2a, 0, 0},
+ {0x9D, 0x2a, 0x2a, 0, 0},
+ {0x9E, 0x2a, 0x2a, 0, 0},
+ {0x9F, 0x2a, 0x2a, 0, 0},
+ {0xA0, 0x18, 0x18, 0, 0},
+ {0xA1, 0x6a, 0x6a, 1, 1},
+ {0xA2, 0xab, 0xab, 1, 1},
+ {0xA3, 0x13, 0x13, 1, 1},
+ {0xA4, 0xc1, 0xc1, 1, 1},
+ {0xA5, 0xaa, 0xaa, 1, 1},
+ {0xA6, 0x87, 0x87, 1, 1},
+ {0xA7, 0, 0, 0, 0},
+ {0xA8, 0x6, 0x6, 0, 0},
+ {0xA9, 0x7, 0x7, 0, 0},
+ {0xAA, 0x7, 0x7, 0, 0},
+ {0xAB, 0x15, 0x15, 0, 0},
+ {0xAC, 0x55, 0x55, 0, 0},
+ {0xAD, 0x97, 0x97, 1, 1},
+ {0xAE, 0x8, 0x8, 0, 0},
+ {0xAF, 0x14, 0x14, 1, 1},
+ {0xB0, 0x33, 0x33, 0, 0},
+ {0xB1, 0x88, 0x88, 0, 0},
+ {0xB2, 0x6, 0x6, 0, 0},
+ {0xB3, 0x3, 0x3, 1, 1},
+ {0xB4, 0xa, 0xa, 0, 0},
+ {0xB5, 0x3, 0x3, 1, 1},
+ {0xB6, 0x2a, 0x2a, 0, 0},
+ {0xB7, 0xa4, 0xa4, 0, 0},
+ {0xB8, 0x18, 0x18, 0, 0},
+ {0xB9, 0x28, 0x28, 0, 0},
+ {0xBA, 0, 0, 0, 0},
+ {0xBB, 0x4a, 0x4a, 0, 0},
+ {0xBC, 0, 0, 0, 0},
+ {0xBD, 0x71, 0x71, 0, 0},
+ {0xBE, 0x72, 0x72, 0, 0},
+ {0xBF, 0x73, 0x73, 0, 0},
+ {0xC0, 0x74, 0x74, 0, 0},
+ {0xC1, 0x75, 0x75, 0, 0},
+ {0xC2, 0x76, 0x76, 0, 0},
+ {0xC3, 0x77, 0x77, 0, 0},
+ {0xC4, 0x78, 0x78, 0, 0},
+ {0xC5, 0x79, 0x79, 0, 0},
+ {0xC6, 0x7a, 0x7a, 0, 0},
+ {0xC7, 0, 0, 0, 0},
+ {0xC8, 0, 0, 0, 0},
+ {0xC9, 0, 0, 0, 0},
+ {0xCA, 0, 0, 0, 0},
+ {0xCB, 0, 0, 0, 0},
+ {0xCC, 0, 0, 0, 0},
+ {0xCD, 0, 0, 0, 0},
+ {0xCE, 0x6, 0x6, 0, 0},
+ {0xCF, 0, 0, 0, 0},
+ {0xD0, 0, 0, 0, 0},
+ {0xD1, 0x18, 0x18, 0, 0},
+ {0xD2, 0x88, 0x88, 0, 0},
+ {0xD3, 0, 0, 0, 0},
+ {0xD4, 0, 0, 0, 0},
+ {0xD5, 0, 0, 0, 0},
+ {0xD6, 0, 0, 0, 0},
+ {0xD7, 0, 0, 0, 0},
+ {0xD8, 0, 0, 0, 0},
+ {0xD9, 0, 0, 0, 0},
+ {0xDA, 0x6, 0x6, 0, 0},
+ {0xDB, 0, 0, 0, 0},
+ {0xDC, 0, 0, 0, 0},
+ {0xDD, 0x18, 0x18, 0, 0},
+ {0xDE, 0x88, 0x88, 0, 0},
+ {0xDF, 0, 0, 0, 0},
+ {0xE0, 0, 0, 0, 0},
+ {0xE1, 0, 0, 0, 0},
+ {0xE2, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_SYN_2056[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0xd, 0xd, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_TX_2056[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0x11, 0x11, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0xf, 0xf, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x2d, 0x2d, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0x74, 0x74, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_RX_2056[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x99, 0x99, 0, 0},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x44, 0x44, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0x44, 0x44, 0, 0},
+ {0x40, 0xf, 0xf, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0x50, 0x50, 1, 1},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x99, 0x99, 0, 0},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x44, 0x44, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x66, 0x66, 0, 0},
+ {0x50, 0x66, 0x66, 0, 0},
+ {0x51, 0x57, 0x57, 0, 0},
+ {0x52, 0x57, 0x57, 0, 0},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x23, 0x23, 0, 0},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0x2, 0x2, 0, 0},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_SYN_2056_A1[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0xd, 0xd, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_TX_2056_A1[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0x11, 0x11, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0xf, 0xf, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x2d, 0x2d, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0x72, 0x72, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_RX_2056_A1[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x44, 0x44, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0x44, 0x44, 0, 0},
+ {0x40, 0xf, 0xf, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0x50, 0x50, 1, 1},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x44, 0x44, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x2f, 0x2f, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_SYN_2056_rev5[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_TX_2056_rev5[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0x11, 0x11, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0xf, 0xf, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x2d, 0x2d, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0x70, 0x70, 0, 0},
+ {0x94, 0x70, 0x70, 0, 0},
+ {0x95, 0x71, 0x71, 1, 1},
+ {0x96, 0x71, 0x71, 1, 1},
+ {0x97, 0x72, 0x72, 1, 1},
+ {0x98, 0x73, 0x73, 1, 1},
+ {0x99, 0x74, 0x74, 1, 1},
+ {0x9A, 0x75, 0x75, 1, 1},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_RX_2056_rev5[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x88, 0x88, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 1, 1},
+ {0x40, 0x7, 0x7, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0, 0, 1, 1},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x4, 0x4, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_SYN_2056_rev6[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_TX_2056_rev6[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0xee, 0xee, 1, 1},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0x50, 0x50, 1, 1},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x50, 0x50, 1, 1},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0x30, 0x30, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0x70, 0x70, 0, 0},
+ {0x94, 0x70, 0x70, 0, 0},
+ {0x95, 0x70, 0x70, 0, 0},
+ {0x96, 0x70, 0x70, 0, 0},
+ {0x97, 0x70, 0x70, 0, 0},
+ {0x98, 0x70, 0x70, 0, 0},
+ {0x99, 0x70, 0x70, 0, 0},
+ {0x9A, 0x70, 0x70, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_RX_2056_rev6[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x88, 0x88, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0x44, 0x44, 0, 0},
+ {0x40, 0x7, 0x7, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x44, 0x44, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x4, 0x4, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0x5, 0x5, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0}
+};
+
+radio_regs_t regs_SYN_2056_rev7[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_TX_2056_rev7[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0xee, 0xee, 1, 1},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0x50, 0x50, 1, 1},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x50, 0x50, 1, 1},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0x30, 0x30, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0x70, 0x70, 0, 0},
+ {0x94, 0x70, 0x70, 0, 0},
+ {0x95, 0x71, 0x71, 1, 1},
+ {0x96, 0x71, 0x71, 1, 1},
+ {0x97, 0x72, 0x72, 1, 1},
+ {0x98, 0x73, 0x73, 1, 1},
+ {0x99, 0x74, 0x74, 1, 1},
+ {0x9A, 0x75, 0x75, 1, 1},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_RX_2056_rev7[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x88, 0x88, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 1, 1},
+ {0x40, 0x7, 0x7, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0, 0, 1, 1},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x4, 0x4, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_SYN_2056_rev8[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x4, 0x4, 0, 0},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x30, 0x30, 0, 0},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0xd, 0xd, 0, 0},
+ {0x4C, 0xd, 0xd, 0, 0},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x6, 0x6, 0, 0},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_TX_2056_rev8[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0xee, 0xee, 1, 1},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0x50, 0x50, 1, 1},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x50, 0x50, 1, 1},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0x30, 0x30, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0x70, 0x70, 0, 0},
+ {0x94, 0x70, 0x70, 0, 0},
+ {0x95, 0x70, 0x70, 0, 0},
+ {0x96, 0x70, 0x70, 0, 0},
+ {0x97, 0x70, 0x70, 0, 0},
+ {0x98, 0x70, 0x70, 0, 0},
+ {0x99, 0x70, 0x70, 0, 0},
+ {0x9A, 0x70, 0x70, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_RX_2056_rev8[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x88, 0x88, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0x44, 0x44, 0, 0},
+ {0x40, 0x7, 0x7, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x44, 0x44, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x4, 0x4, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0x5, 0x5, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_SYN_2056_rev11[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0x1, 0x1, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0x60, 0x60, 0, 0},
+ {0x23, 0x6, 0x6, 0, 0},
+ {0x24, 0xc, 0xc, 0, 0},
+ {0x25, 0, 0, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0, 0, 0, 0},
+ {0x28, 0x1, 0x1, 0, 0},
+ {0x29, 0, 0, 0, 0},
+ {0x2A, 0, 0, 0, 0},
+ {0x2B, 0, 0, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0, 0, 0, 0},
+ {0x2F, 0x1f, 0x1f, 0, 0},
+ {0x30, 0x15, 0x15, 0, 0},
+ {0x31, 0xf, 0xf, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0, 0, 0, 0},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0, 0, 0, 0},
+ {0x38, 0, 0, 0, 0},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0, 0, 0, 0},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x13, 0x13, 0, 0},
+ {0x3D, 0xf, 0xf, 0, 0},
+ {0x3E, 0x18, 0x18, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x20, 0x20, 0, 0},
+ {0x42, 0x20, 0x20, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x77, 0x77, 0, 0},
+ {0x45, 0x7, 0x7, 0, 0},
+ {0x46, 0x1, 0x1, 0, 0},
+ {0x47, 0x6, 0x6, 1, 1},
+ {0x48, 0xf, 0xf, 0, 0},
+ {0x49, 0x3f, 0x3f, 1, 1},
+ {0x4A, 0x32, 0x32, 0, 0},
+ {0x4B, 0x6, 0x6, 1, 1},
+ {0x4C, 0x6, 0x6, 1, 1},
+ {0x4D, 0x4, 0x4, 0, 0},
+ {0x4E, 0x2b, 0x2b, 1, 1},
+ {0x4F, 0x1, 0x1, 0, 0},
+ {0x50, 0x1c, 0x1c, 0, 0},
+ {0x51, 0x2, 0x2, 0, 0},
+ {0x52, 0x2, 0x2, 0, 0},
+ {0x53, 0xf7, 0xf7, 1, 1},
+ {0x54, 0xb4, 0xb4, 0, 0},
+ {0x55, 0xd2, 0xd2, 0, 0},
+ {0x56, 0, 0, 0, 0},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x4, 0x4, 0, 0},
+ {0x59, 0x96, 0x96, 0, 0},
+ {0x5A, 0x3e, 0x3e, 0, 0},
+ {0x5B, 0x3e, 0x3e, 0, 0},
+ {0x5C, 0x13, 0x13, 0, 0},
+ {0x5D, 0x2, 0x2, 0, 0},
+ {0x5E, 0, 0, 0, 0},
+ {0x5F, 0x7, 0x7, 0, 0},
+ {0x60, 0x7, 0x7, 1, 1},
+ {0x61, 0x8, 0x8, 0, 0},
+ {0x62, 0x3, 0x3, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0x40, 0x40, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0x1, 0x1, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0x60, 0x60, 0, 0},
+ {0x71, 0x66, 0x66, 0, 0},
+ {0x72, 0xc, 0xc, 0, 0},
+ {0x73, 0x66, 0x66, 0, 0},
+ {0x74, 0x8f, 0x8f, 1, 1},
+ {0x75, 0, 0, 0, 0},
+ {0x76, 0xcc, 0xcc, 0, 0},
+ {0x77, 0x1, 0x1, 0, 0},
+ {0x78, 0x66, 0x66, 0, 0},
+ {0x79, 0x66, 0x66, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0, 0, 0, 0},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0xff, 0xff, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0x95, 0, 0, 0, 0},
+ {0x96, 0, 0, 0, 0},
+ {0x97, 0, 0, 0, 0},
+ {0x98, 0, 0, 0, 0},
+ {0x99, 0, 0, 0, 0},
+ {0x9A, 0, 0, 0, 0},
+ {0x9B, 0, 0, 0, 0},
+ {0x9C, 0, 0, 0, 0},
+ {0x9D, 0, 0, 0, 0},
+ {0x9E, 0, 0, 0, 0},
+ {0x9F, 0x6, 0x6, 0, 0},
+ {0xA0, 0x66, 0x66, 0, 0},
+ {0xA1, 0x66, 0x66, 0, 0},
+ {0xA2, 0x66, 0x66, 0, 0},
+ {0xA3, 0x66, 0x66, 0, 0},
+ {0xA4, 0x66, 0x66, 0, 0},
+ {0xA5, 0x66, 0x66, 0, 0},
+ {0xA6, 0x66, 0x66, 0, 0},
+ {0xA7, 0x66, 0x66, 0, 0},
+ {0xA8, 0x66, 0x66, 0, 0},
+ {0xA9, 0x66, 0x66, 0, 0},
+ {0xAA, 0x66, 0x66, 0, 0},
+ {0xAB, 0x66, 0x66, 0, 0},
+ {0xAC, 0x66, 0x66, 0, 0},
+ {0xAD, 0x66, 0x66, 0, 0},
+ {0xAE, 0x66, 0x66, 0, 0},
+ {0xAF, 0x66, 0x66, 0, 0},
+ {0xB0, 0x66, 0x66, 0, 0},
+ {0xB1, 0x66, 0x66, 0, 0},
+ {0xB2, 0x66, 0x66, 0, 0},
+ {0xB3, 0xa, 0xa, 0, 0},
+ {0xB4, 0, 0, 0, 0},
+ {0xB5, 0, 0, 0, 0},
+ {0xB6, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_TX_2056_rev11[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0, 0, 0, 0},
+ {0x21, 0x88, 0x88, 0, 0},
+ {0x22, 0x88, 0x88, 0, 0},
+ {0x23, 0x88, 0x88, 0, 0},
+ {0x24, 0x88, 0x88, 0, 0},
+ {0x25, 0xc, 0xc, 0, 0},
+ {0x26, 0, 0, 0, 0},
+ {0x27, 0x3, 0x3, 0, 0},
+ {0x28, 0, 0, 0, 0},
+ {0x29, 0x3, 0x3, 0, 0},
+ {0x2A, 0x37, 0x37, 0, 0},
+ {0x2B, 0x3, 0x3, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0, 0, 0, 0},
+ {0x2E, 0x1, 0x1, 0, 0},
+ {0x2F, 0x1, 0x1, 0, 0},
+ {0x30, 0, 0, 0, 0},
+ {0x31, 0, 0, 0, 0},
+ {0x32, 0, 0, 0, 0},
+ {0x33, 0x11, 0x11, 0, 0},
+ {0x34, 0xee, 0xee, 1, 1},
+ {0x35, 0, 0, 0, 0},
+ {0x36, 0, 0, 0, 0},
+ {0x37, 0x3, 0x3, 0, 0},
+ {0x38, 0x50, 0x50, 1, 1},
+ {0x39, 0, 0, 0, 0},
+ {0x3A, 0x50, 0x50, 1, 1},
+ {0x3B, 0, 0, 0, 0},
+ {0x3C, 0x6e, 0x6e, 0, 0},
+ {0x3D, 0xf0, 0xf0, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0, 0, 0, 0},
+ {0x40, 0, 0, 0, 0},
+ {0x41, 0x3, 0x3, 0, 0},
+ {0x42, 0x3, 0x3, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x1e, 0x1e, 0, 0},
+ {0x45, 0, 0, 0, 0},
+ {0x46, 0x6e, 0x6e, 0, 0},
+ {0x47, 0xf0, 0xf0, 1, 1},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x2, 0x2, 0, 0},
+ {0x4A, 0xff, 0xff, 1, 1},
+ {0x4B, 0xc, 0xc, 0, 0},
+ {0x4C, 0, 0, 0, 0},
+ {0x4D, 0x38, 0x38, 0, 0},
+ {0x4E, 0x70, 0x70, 1, 1},
+ {0x4F, 0x2, 0x2, 0, 0},
+ {0x50, 0x88, 0x88, 0, 0},
+ {0x51, 0xc, 0xc, 0, 0},
+ {0x52, 0, 0, 0, 0},
+ {0x53, 0x8, 0x8, 0, 0},
+ {0x54, 0x70, 0x70, 1, 1},
+ {0x55, 0x2, 0x2, 0, 0},
+ {0x56, 0xff, 0xff, 1, 1},
+ {0x57, 0, 0, 0, 0},
+ {0x58, 0x83, 0x83, 0, 0},
+ {0x59, 0x77, 0x77, 1, 1},
+ {0x5A, 0, 0, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x88, 0x88, 0, 0},
+ {0x5D, 0, 0, 0, 0},
+ {0x5E, 0x8, 0x8, 0, 0},
+ {0x5F, 0x77, 0x77, 1, 1},
+ {0x60, 0x1, 0x1, 0, 0},
+ {0x61, 0, 0, 0, 0},
+ {0x62, 0x7, 0x7, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0x7, 0x7, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 1, 1},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0xa, 0xa, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0, 0, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0x2, 0x2, 0, 0},
+ {0x72, 0, 0, 0, 0},
+ {0x73, 0, 0, 0, 0},
+ {0x74, 0xe, 0xe, 0, 0},
+ {0x75, 0xe, 0xe, 0, 0},
+ {0x76, 0xe, 0xe, 0, 0},
+ {0x77, 0x13, 0x13, 0, 0},
+ {0x78, 0x13, 0x13, 0, 0},
+ {0x79, 0x1b, 0x1b, 0, 0},
+ {0x7A, 0x1b, 0x1b, 0, 0},
+ {0x7B, 0x55, 0x55, 0, 0},
+ {0x7C, 0x5b, 0x5b, 0, 0},
+ {0x7D, 0x30, 0x30, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0x70, 0x70, 0, 0},
+ {0x94, 0x70, 0x70, 0, 0},
+ {0x95, 0x70, 0x70, 0, 0},
+ {0x96, 0x70, 0x70, 0, 0},
+ {0x97, 0x70, 0x70, 0, 0},
+ {0x98, 0x70, 0x70, 0, 0},
+ {0x99, 0x70, 0x70, 0, 0},
+ {0x9A, 0x70, 0x70, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_regs_t regs_RX_2056_rev11[] = {
+ {0x02, 0, 0, 0, 0},
+ {0x03, 0, 0, 0, 0},
+ {0x04, 0, 0, 0, 0},
+ {0x05, 0, 0, 0, 0},
+ {0x06, 0, 0, 0, 0},
+ {0x07, 0, 0, 0, 0},
+ {0x08, 0, 0, 0, 0},
+ {0x09, 0, 0, 0, 0},
+ {0x0A, 0, 0, 0, 0},
+ {0x0B, 0, 0, 0, 0},
+ {0x0C, 0, 0, 0, 0},
+ {0x0D, 0, 0, 0, 0},
+ {0x0E, 0, 0, 0, 0},
+ {0x0F, 0, 0, 0, 0},
+ {0x10, 0, 0, 0, 0},
+ {0x11, 0, 0, 0, 0},
+ {0x12, 0, 0, 0, 0},
+ {0x13, 0, 0, 0, 0},
+ {0x14, 0, 0, 0, 0},
+ {0x15, 0, 0, 0, 0},
+ {0x16, 0, 0, 0, 0},
+ {0x17, 0, 0, 0, 0},
+ {0x18, 0, 0, 0, 0},
+ {0x19, 0, 0, 0, 0},
+ {0x1A, 0, 0, 0, 0},
+ {0x1B, 0, 0, 0, 0},
+ {0x1C, 0, 0, 0, 0},
+ {0x1D, 0, 0, 0, 0},
+ {0x1E, 0, 0, 0, 0},
+ {0x1F, 0, 0, 0, 0},
+ {0x20, 0x3, 0x3, 0, 0},
+ {0x21, 0, 0, 0, 0},
+ {0x22, 0, 0, 0, 0},
+ {0x23, 0x90, 0x90, 0, 0},
+ {0x24, 0x55, 0x55, 0, 0},
+ {0x25, 0x15, 0x15, 0, 0},
+ {0x26, 0x5, 0x5, 0, 0},
+ {0x27, 0x15, 0x15, 0, 0},
+ {0x28, 0x5, 0x5, 0, 0},
+ {0x29, 0x20, 0x20, 0, 0},
+ {0x2A, 0x11, 0x11, 0, 0},
+ {0x2B, 0x90, 0x90, 0, 0},
+ {0x2C, 0, 0, 0, 0},
+ {0x2D, 0x88, 0x88, 0, 0},
+ {0x2E, 0x32, 0x32, 0, 0},
+ {0x2F, 0x77, 0x77, 0, 0},
+ {0x30, 0x17, 0x17, 1, 1},
+ {0x31, 0xff, 0xff, 1, 1},
+ {0x32, 0x20, 0x20, 0, 0},
+ {0x33, 0, 0, 0, 0},
+ {0x34, 0x88, 0x88, 0, 0},
+ {0x35, 0x32, 0x32, 0, 0},
+ {0x36, 0x77, 0x77, 0, 0},
+ {0x37, 0x17, 0x17, 1, 1},
+ {0x38, 0xf0, 0xf0, 1, 1},
+ {0x39, 0x20, 0x20, 0, 0},
+ {0x3A, 0x8, 0x8, 0, 0},
+ {0x3B, 0x55, 0x55, 1, 1},
+ {0x3C, 0, 0, 0, 0},
+ {0x3D, 0x88, 0x88, 1, 1},
+ {0x3E, 0, 0, 0, 0},
+ {0x3F, 0x44, 0x44, 0, 0},
+ {0x40, 0x7, 0x7, 1, 1},
+ {0x41, 0x6, 0x6, 0, 0},
+ {0x42, 0x4, 0x4, 0, 0},
+ {0x43, 0, 0, 0, 0},
+ {0x44, 0x8, 0x8, 0, 0},
+ {0x45, 0x55, 0x55, 1, 1},
+ {0x46, 0, 0, 0, 0},
+ {0x47, 0x11, 0x11, 0, 0},
+ {0x48, 0, 0, 0, 0},
+ {0x49, 0x44, 0x44, 0, 0},
+ {0x4A, 0x7, 0x7, 0, 0},
+ {0x4B, 0x6, 0x6, 0, 0},
+ {0x4C, 0x4, 0x4, 0, 0},
+ {0x4D, 0, 0, 0, 0},
+ {0x4E, 0, 0, 0, 0},
+ {0x4F, 0x26, 0x26, 1, 1},
+ {0x50, 0x26, 0x26, 1, 1},
+ {0x51, 0xf, 0xf, 1, 1},
+ {0x52, 0xf, 0xf, 1, 1},
+ {0x53, 0x44, 0x44, 0, 0},
+ {0x54, 0, 0, 0, 0},
+ {0x55, 0, 0, 0, 0},
+ {0x56, 0x8, 0x8, 0, 0},
+ {0x57, 0x8, 0x8, 0, 0},
+ {0x58, 0x7, 0x7, 0, 0},
+ {0x59, 0x22, 0x22, 0, 0},
+ {0x5A, 0x22, 0x22, 0, 0},
+ {0x5B, 0x2, 0x2, 0, 0},
+ {0x5C, 0x4, 0x4, 1, 1},
+ {0x5D, 0x7, 0x7, 0, 0},
+ {0x5E, 0x55, 0x55, 0, 0},
+ {0x5F, 0x23, 0x23, 0, 0},
+ {0x60, 0x41, 0x41, 0, 0},
+ {0x61, 0x1, 0x1, 0, 0},
+ {0x62, 0xa, 0xa, 0, 0},
+ {0x63, 0, 0, 0, 0},
+ {0x64, 0, 0, 0, 0},
+ {0x65, 0, 0, 0, 0},
+ {0x66, 0, 0, 0, 0},
+ {0x67, 0, 0, 0, 0},
+ {0x68, 0, 0, 0, 0},
+ {0x69, 0, 0, 0, 0},
+ {0x6A, 0, 0, 0, 0},
+ {0x6B, 0xc, 0xc, 0, 0},
+ {0x6C, 0, 0, 0, 0},
+ {0x6D, 0, 0, 0, 0},
+ {0x6E, 0, 0, 0, 0},
+ {0x6F, 0, 0, 0, 0},
+ {0x70, 0, 0, 0, 0},
+ {0x71, 0, 0, 0, 0},
+ {0x72, 0x22, 0x22, 0, 0},
+ {0x73, 0x22, 0x22, 0, 0},
+ {0x74, 0, 0, 1, 1},
+ {0x75, 0xa, 0xa, 0, 0},
+ {0x76, 0x1, 0x1, 0, 0},
+ {0x77, 0x22, 0x22, 0, 0},
+ {0x78, 0x30, 0x30, 0, 0},
+ {0x79, 0, 0, 0, 0},
+ {0x7A, 0, 0, 0, 0},
+ {0x7B, 0, 0, 0, 0},
+ {0x7C, 0, 0, 0, 0},
+ {0x7D, 0x5, 0x5, 1, 1},
+ {0x7E, 0, 0, 0, 0},
+ {0x7F, 0, 0, 0, 0},
+ {0x80, 0, 0, 0, 0},
+ {0x81, 0, 0, 0, 0},
+ {0x82, 0, 0, 0, 0},
+ {0x83, 0, 0, 0, 0},
+ {0x84, 0, 0, 0, 0},
+ {0x85, 0, 0, 0, 0},
+ {0x86, 0, 0, 0, 0},
+ {0x87, 0, 0, 0, 0},
+ {0x88, 0, 0, 0, 0},
+ {0x89, 0, 0, 0, 0},
+ {0x8A, 0, 0, 0, 0},
+ {0x8B, 0, 0, 0, 0},
+ {0x8C, 0, 0, 0, 0},
+ {0x8D, 0, 0, 0, 0},
+ {0x8E, 0, 0, 0, 0},
+ {0x8F, 0, 0, 0, 0},
+ {0x90, 0, 0, 0, 0},
+ {0x91, 0, 0, 0, 0},
+ {0x92, 0, 0, 0, 0},
+ {0x93, 0, 0, 0, 0},
+ {0x94, 0, 0, 0, 0},
+ {0xFFFF, 0, 0, 0, 0},
+};
+
+radio_20xx_regs_t regs_2057_rev4[] = {
+ {0x00, 0x84, 0},
+ {0x01, 0, 0},
+ {0x02, 0x60, 0},
+ {0x03, 0x1f, 0},
+ {0x04, 0x4, 0},
+ {0x05, 0x2, 0},
+ {0x06, 0x1, 0},
+ {0x07, 0x1, 0},
+ {0x08, 0x1, 0},
+ {0x09, 0x69, 0},
+ {0x0A, 0x66, 0},
+ {0x0B, 0x6, 0},
+ {0x0C, 0x18, 0},
+ {0x0D, 0x3, 0},
+ {0x0E, 0x20, 1},
+ {0x0F, 0x20, 0},
+ {0x10, 0, 0},
+ {0x11, 0x7c, 0},
+ {0x12, 0x42, 0},
+ {0x13, 0xbd, 0},
+ {0x14, 0x7, 0},
+ {0x15, 0xf7, 0},
+ {0x16, 0x8, 0},
+ {0x17, 0x17, 0},
+ {0x18, 0x7, 0},
+ {0x19, 0, 0},
+ {0x1A, 0x2, 0},
+ {0x1B, 0x13, 0},
+ {0x1C, 0x3e, 0},
+ {0x1D, 0x3e, 0},
+ {0x1E, 0x96, 0},
+ {0x1F, 0x4, 0},
+ {0x20, 0, 0},
+ {0x21, 0, 0},
+ {0x22, 0x17, 0},
+ {0x23, 0x4, 0},
+ {0x24, 0x1, 0},
+ {0x25, 0x6, 0},
+ {0x26, 0x4, 0},
+ {0x27, 0xd, 0},
+ {0x28, 0xd, 0},
+ {0x29, 0x30, 0},
+ {0x2A, 0x32, 0},
+ {0x2B, 0x8, 0},
+ {0x2C, 0x1c, 0},
+ {0x2D, 0x2, 0},
+ {0x2E, 0x4, 0},
+ {0x2F, 0x7f, 0},
+ {0x30, 0x27, 0},
+ {0x31, 0, 1},
+ {0x32, 0, 1},
+ {0x33, 0, 1},
+ {0x34, 0, 0},
+ {0x35, 0x26, 1},
+ {0x36, 0x18, 0},
+ {0x37, 0x7, 0},
+ {0x38, 0x66, 0},
+ {0x39, 0x66, 0},
+ {0x3A, 0x66, 0},
+ {0x3B, 0x66, 0},
+ {0x3C, 0xff, 1},
+ {0x3D, 0xff, 1},
+ {0x3E, 0xff, 1},
+ {0x3F, 0xff, 1},
+ {0x40, 0x16, 0},
+ {0x41, 0x7, 0},
+ {0x42, 0x19, 0},
+ {0x43, 0x7, 0},
+ {0x44, 0x6, 0},
+ {0x45, 0x3, 0},
+ {0x46, 0x1, 0},
+ {0x47, 0x7, 0},
+ {0x48, 0x33, 0},
+ {0x49, 0x5, 0},
+ {0x4A, 0x77, 0},
+ {0x4B, 0x66, 0},
+ {0x4C, 0x66, 0},
+ {0x4D, 0, 0},
+ {0x4E, 0x4, 0},
+ {0x4F, 0xc, 0},
+ {0x50, 0, 0},
+ {0x51, 0x75, 0},
+ {0x56, 0x7, 0},
+ {0x57, 0, 0},
+ {0x58, 0, 0},
+ {0x59, 0xa8, 0},
+ {0x5A, 0, 0},
+ {0x5B, 0x1f, 0},
+ {0x5C, 0x30, 0},
+ {0x5D, 0x1, 0},
+ {0x5E, 0x30, 0},
+ {0x5F, 0x70, 0},
+ {0x60, 0, 0},
+ {0x61, 0, 0},
+ {0x62, 0x33, 1},
+ {0x63, 0x19, 0},
+ {0x64, 0x62, 0},
+ {0x65, 0, 0},
+ {0x66, 0x11, 0},
+ {0x69, 0, 0},
+ {0x6A, 0x7e, 0},
+ {0x6B, 0x3f, 0},
+ {0x6C, 0x7f, 0},
+ {0x6D, 0x78, 0},
+ {0x6E, 0xc8, 0},
+ {0x6F, 0x88, 0},
+ {0x70, 0x8, 0},
+ {0x71, 0xf, 0},
+ {0x72, 0xbc, 0},
+ {0x73, 0x8, 0},
+ {0x74, 0x60, 0},
+ {0x75, 0x1e, 0},
+ {0x76, 0x70, 0},
+ {0x77, 0, 0},
+ {0x78, 0, 0},
+ {0x79, 0, 0},
+ {0x7A, 0x33, 0},
+ {0x7B, 0x1e, 0},
+ {0x7C, 0x62, 0},
+ {0x7D, 0x11, 0},
+ {0x80, 0x3c, 0},
+ {0x81, 0x9c, 0},
+ {0x82, 0xa, 0},
+ {0x83, 0x9d, 0},
+ {0x84, 0xa, 0},
+ {0x85, 0, 0},
+ {0x86, 0x40, 0},
+ {0x87, 0x40, 0},
+ {0x88, 0x88, 0},
+ {0x89, 0x10, 0},
+ {0x8A, 0xf0, 1},
+ {0x8B, 0x10, 1},
+ {0x8C, 0xf0, 1},
+ {0x8D, 0, 0},
+ {0x8E, 0, 0},
+ {0x8F, 0x10, 0},
+ {0x90, 0x55, 0},
+ {0x91, 0x3f, 1},
+ {0x92, 0x36, 1},
+ {0x93, 0, 0},
+ {0x94, 0, 0},
+ {0x95, 0, 0},
+ {0x96, 0x87, 0},
+ {0x97, 0x11, 0},
+ {0x98, 0, 0},
+ {0x99, 0x33, 0},
+ {0x9A, 0x88, 0},
+ {0x9B, 0, 0},
+ {0x9C, 0x87, 0},
+ {0x9D, 0x11, 0},
+ {0x9E, 0, 0},
+ {0x9F, 0x33, 0},
+ {0xA0, 0x88, 0},
+ {0xA1, 0xe1, 0},
+ {0xA2, 0x3f, 0},
+ {0xA3, 0x44, 0},
+ {0xA4, 0x8c, 1},
+ {0xA5, 0x6d, 0},
+ {0xA6, 0x22, 0},
+ {0xA7, 0xbe, 0},
+ {0xA8, 0x55, 1},
+ {0xA9, 0xc, 0},
+ {0xAA, 0xc, 0},
+ {0xAB, 0xaa, 0},
+ {0xAC, 0x2, 0},
+ {0xAD, 0, 0},
+ {0xAE, 0x10, 0},
+ {0xAF, 0x1, 1},
+ {0xB0, 0, 0},
+ {0xB1, 0, 0},
+ {0xB2, 0x80, 0},
+ {0xB3, 0x60, 0},
+ {0xB4, 0x44, 0},
+ {0xB5, 0x55, 0},
+ {0xB6, 0x1, 0},
+ {0xB7, 0x55, 0},
+ {0xB8, 0x1, 0},
+ {0xB9, 0x5, 0},
+ {0xBA, 0x55, 0},
+ {0xBB, 0x55, 0},
+ {0xC1, 0, 0},
+ {0xC2, 0, 0},
+ {0xC3, 0, 0},
+ {0xC4, 0, 0},
+ {0xC5, 0, 0},
+ {0xC6, 0, 0},
+ {0xC7, 0, 0},
+ {0xC8, 0, 0},
+ {0xC9, 0, 0},
+ {0xCA, 0, 0},
+ {0xCB, 0, 0},
+ {0xCC, 0, 0},
+ {0xCD, 0, 0},
+ {0xCE, 0x5e, 0},
+ {0xCF, 0xc, 0},
+ {0xD0, 0xc, 0},
+ {0xD1, 0xc, 0},
+ {0xD2, 0, 0},
+ {0xD3, 0x2b, 0},
+ {0xD4, 0xc, 0},
+ {0xD5, 0, 0},
+ {0xD6, 0x75, 0},
+ {0xDB, 0x7, 0},
+ {0xDC, 0, 0},
+ {0xDD, 0, 0},
+ {0xDE, 0xa8, 0},
+ {0xDF, 0, 0},
+ {0xE0, 0x1f, 0},
+ {0xE1, 0x30, 0},
+ {0xE2, 0x1, 0},
+ {0xE3, 0x30, 0},
+ {0xE4, 0x70, 0},
+ {0xE5, 0, 0},
+ {0xE6, 0, 0},
+ {0xE7, 0x33, 0},
+ {0xE8, 0x19, 0},
+ {0xE9, 0x62, 0},
+ {0xEA, 0, 0},
+ {0xEB, 0x11, 0},
+ {0xEE, 0, 0},
+ {0xEF, 0x7e, 0},
+ {0xF0, 0x3f, 0},
+ {0xF1, 0x7f, 0},
+ {0xF2, 0x78, 0},
+ {0xF3, 0xc8, 0},
+ {0xF4, 0x88, 0},
+ {0xF5, 0x8, 0},
+ {0xF6, 0xf, 0},
+ {0xF7, 0xbc, 0},
+ {0xF8, 0x8, 0},
+ {0xF9, 0x60, 0},
+ {0xFA, 0x1e, 0},
+ {0xFB, 0x70, 0},
+ {0xFC, 0, 0},
+ {0xFD, 0, 0},
+ {0xFE, 0, 0},
+ {0xFF, 0x33, 0},
+ {0x100, 0x1e, 0},
+ {0x101, 0x62, 0},
+ {0x102, 0x11, 0},
+ {0x105, 0x3c, 0},
+ {0x106, 0x9c, 0},
+ {0x107, 0xa, 0},
+ {0x108, 0x9d, 0},
+ {0x109, 0xa, 0},
+ {0x10A, 0, 0},
+ {0x10B, 0x40, 0},
+ {0x10C, 0x40, 0},
+ {0x10D, 0x88, 0},
+ {0x10E, 0x10, 0},
+ {0x10F, 0xf0, 1},
+ {0x110, 0x10, 1},
+ {0x111, 0xf0, 1},
+ {0x112, 0, 0},
+ {0x113, 0, 0},
+ {0x114, 0x10, 0},
+ {0x115, 0x55, 0},
+ {0x116, 0x3f, 1},
+ {0x117, 0x36, 1},
+ {0x118, 0, 0},
+ {0x119, 0, 0},
+ {0x11A, 0, 0},
+ {0x11B, 0x87, 0},
+ {0x11C, 0x11, 0},
+ {0x11D, 0, 0},
+ {0x11E, 0x33, 0},
+ {0x11F, 0x88, 0},
+ {0x120, 0, 0},
+ {0x121, 0x87, 0},
+ {0x122, 0x11, 0},
+ {0x123, 0, 0},
+ {0x124, 0x33, 0},
+ {0x125, 0x88, 0},
+ {0x126, 0xe1, 0},
+ {0x127, 0x3f, 0},
+ {0x128, 0x44, 0},
+ {0x129, 0x8c, 1},
+ {0x12A, 0x6d, 0},
+ {0x12B, 0x22, 0},
+ {0x12C, 0xbe, 0},
+ {0x12D, 0x55, 1},
+ {0x12E, 0xc, 0},
+ {0x12F, 0xc, 0},
+ {0x130, 0xaa, 0},
+ {0x131, 0x2, 0},
+ {0x132, 0, 0},
+ {0x133, 0x10, 0},
+ {0x134, 0x1, 1},
+ {0x135, 0, 0},
+ {0x136, 0, 0},
+ {0x137, 0x80, 0},
+ {0x138, 0x60, 0},
+ {0x139, 0x44, 0},
+ {0x13A, 0x55, 0},
+ {0x13B, 0x1, 0},
+ {0x13C, 0x55, 0},
+ {0x13D, 0x1, 0},
+ {0x13E, 0x5, 0},
+ {0x13F, 0x55, 0},
+ {0x140, 0x55, 0},
+ {0x146, 0, 0},
+ {0x147, 0, 0},
+ {0x148, 0, 0},
+ {0x149, 0, 0},
+ {0x14A, 0, 0},
+ {0x14B, 0, 0},
+ {0x14C, 0, 0},
+ {0x14D, 0, 0},
+ {0x14E, 0, 0},
+ {0x14F, 0, 0},
+ {0x150, 0, 0},
+ {0x151, 0, 0},
+ {0x152, 0, 0},
+ {0x153, 0, 0},
+ {0x154, 0xc, 0},
+ {0x155, 0xc, 0},
+ {0x156, 0xc, 0},
+ {0x157, 0, 0},
+ {0x158, 0x2b, 0},
+ {0x159, 0x84, 0},
+ {0x15A, 0x15, 0},
+ {0x15B, 0xf, 0},
+ {0x15C, 0, 0},
+ {0x15D, 0, 0},
+ {0x15E, 0, 1},
+ {0x15F, 0, 1},
+ {0x160, 0, 1},
+ {0x161, 0, 1},
+ {0x162, 0, 1},
+ {0x163, 0, 1},
+ {0x164, 0, 0},
+ {0x165, 0, 0},
+ {0x166, 0, 0},
+ {0x167, 0, 0},
+ {0x168, 0, 0},
+ {0x169, 0x2, 1},
+ {0x16A, 0, 1},
+ {0x16B, 0, 1},
+ {0x16C, 0, 1},
+ {0x16D, 0, 0},
+ {0x170, 0, 0},
+ {0x171, 0x77, 0},
+ {0x172, 0x77, 0},
+ {0x173, 0x77, 0},
+ {0x174, 0x77, 0},
+ {0x175, 0, 0},
+ {0x176, 0x3, 0},
+ {0x177, 0x37, 0},
+ {0x178, 0x3, 0},
+ {0x179, 0, 0},
+ {0x17A, 0x21, 0},
+ {0x17B, 0x21, 0},
+ {0x17C, 0, 0},
+ {0x17D, 0xaa, 0},
+ {0x17E, 0, 0},
+ {0x17F, 0xaa, 0},
+ {0x180, 0, 0},
+ {0x190, 0, 0},
+ {0x191, 0x77, 0},
+ {0x192, 0x77, 0},
+ {0x193, 0x77, 0},
+ {0x194, 0x77, 0},
+ {0x195, 0, 0},
+ {0x196, 0x3, 0},
+ {0x197, 0x37, 0},
+ {0x198, 0x3, 0},
+ {0x199, 0, 0},
+ {0x19A, 0x21, 0},
+ {0x19B, 0x21, 0},
+ {0x19C, 0, 0},
+ {0x19D, 0xaa, 0},
+ {0x19E, 0, 0},
+ {0x19F, 0xaa, 0},
+ {0x1A0, 0, 0},
+ {0x1A1, 0x2, 0},
+ {0x1A2, 0xf, 0},
+ {0x1A3, 0xf, 0},
+ {0x1A4, 0, 1},
+ {0x1A5, 0, 1},
+ {0x1A6, 0, 1},
+ {0x1A7, 0x2, 0},
+ {0x1A8, 0xf, 0},
+ {0x1A9, 0xf, 0},
+ {0x1AA, 0, 1},
+ {0x1AB, 0, 1},
+ {0x1AC, 0, 1},
+ {0xFFFF, 0, 0},
+};
+
+radio_20xx_regs_t regs_2057_rev5[] = {
+ {0x00, 0, 1},
+ {0x01, 0x57, 1},
+ {0x02, 0x20, 1},
+ {0x03, 0x1f, 0},
+ {0x04, 0x4, 0},
+ {0x05, 0x2, 0},
+ {0x06, 0x1, 0},
+ {0x07, 0x1, 0},
+ {0x08, 0x1, 0},
+ {0x09, 0x69, 0},
+ {0x0A, 0x66, 0},
+ {0x0B, 0x6, 0},
+ {0x0C, 0x18, 0},
+ {0x0D, 0x3, 0},
+ {0x0E, 0x20, 0},
+ {0x0F, 0x20, 0},
+ {0x10, 0, 0},
+ {0x11, 0x7c, 0},
+ {0x12, 0x42, 0},
+ {0x13, 0xbd, 0},
+ {0x14, 0x7, 0},
+ {0x15, 0x87, 0},
+ {0x16, 0x8, 0},
+ {0x17, 0x17, 0},
+ {0x18, 0x7, 0},
+ {0x19, 0, 0},
+ {0x1A, 0x2, 0},
+ {0x1B, 0x13, 0},
+ {0x1C, 0x3e, 0},
+ {0x1D, 0x3e, 0},
+ {0x1E, 0x96, 0},
+ {0x1F, 0x4, 0},
+ {0x20, 0, 0},
+ {0x21, 0, 0},
+ {0x22, 0x17, 0},
+ {0x23, 0x6, 1},
+ {0x24, 0x1, 0},
+ {0x25, 0x6, 0},
+ {0x26, 0x4, 0},
+ {0x27, 0xd, 0},
+ {0x28, 0xd, 0},
+ {0x29, 0x30, 0},
+ {0x2A, 0x32, 0},
+ {0x2B, 0x8, 0},
+ {0x2C, 0x1c, 0},
+ {0x2D, 0x2, 0},
+ {0x2E, 0x4, 0},
+ {0x2F, 0x7f, 0},
+ {0x30, 0x27, 0},
+ {0x31, 0, 1},
+ {0x32, 0, 1},
+ {0x33, 0, 1},
+ {0x34, 0, 0},
+ {0x35, 0x20, 0},
+ {0x36, 0x18, 0},
+ {0x37, 0x7, 0},
+ {0x38, 0x66, 0},
+ {0x39, 0x66, 0},
+ {0x3C, 0xff, 0},
+ {0x3D, 0xff, 0},
+ {0x40, 0x16, 0},
+ {0x41, 0x7, 0},
+ {0x45, 0x3, 0},
+ {0x46, 0x1, 0},
+ {0x47, 0x7, 0},
+ {0x4B, 0x66, 0},
+ {0x4C, 0x66, 0},
+ {0x4D, 0, 0},
+ {0x4E, 0x4, 0},
+ {0x4F, 0xc, 0},
+ {0x50, 0, 0},
+ {0x51, 0x70, 1},
+ {0x56, 0x7, 0},
+ {0x57, 0, 0},
+ {0x58, 0, 0},
+ {0x59, 0x88, 1},
+ {0x5A, 0, 0},
+ {0x5B, 0x1f, 0},
+ {0x5C, 0x20, 1},
+ {0x5D, 0x1, 0},
+ {0x5E, 0x30, 0},
+ {0x5F, 0x70, 0},
+ {0x60, 0, 0},
+ {0x61, 0, 0},
+ {0x62, 0x33, 1},
+ {0x63, 0xf, 1},
+ {0x64, 0xf, 1},
+ {0x65, 0, 0},
+ {0x66, 0x11, 0},
+ {0x80, 0x3c, 0},
+ {0x81, 0x1, 1},
+ {0x82, 0xa, 0},
+ {0x85, 0, 0},
+ {0x86, 0x40, 0},
+ {0x87, 0x40, 0},
+ {0x88, 0x88, 0},
+ {0x89, 0x10, 0},
+ {0x8A, 0xf0, 0},
+ {0x8B, 0x10, 0},
+ {0x8C, 0xf0, 0},
+ {0x8F, 0x10, 0},
+ {0x90, 0x55, 0},
+ {0x91, 0x3f, 1},
+ {0x92, 0x36, 1},
+ {0x93, 0, 0},
+ {0x94, 0, 0},
+ {0x95, 0, 0},
+ {0x96, 0x87, 0},
+ {0x97, 0x11, 0},
+ {0x98, 0, 0},
+ {0x99, 0x33, 0},
+ {0x9A, 0x88, 0},
+ {0xA1, 0x20, 1},
+ {0xA2, 0x3f, 0},
+ {0xA3, 0x44, 0},
+ {0xA4, 0x8c, 0},
+ {0xA5, 0x6c, 0},
+ {0xA6, 0x22, 0},
+ {0xA7, 0xbe, 0},
+ {0xA8, 0x55, 0},
+ {0xAA, 0xc, 0},
+ {0xAB, 0xaa, 0},
+ {0xAC, 0x2, 0},
+ {0xAD, 0, 0},
+ {0xAE, 0x10, 0},
+ {0xAF, 0x1, 0},
+ {0xB0, 0, 0},
+ {0xB1, 0, 0},
+ {0xB2, 0x80, 0},
+ {0xB3, 0x60, 0},
+ {0xB4, 0x44, 0},
+ {0xB5, 0x55, 0},
+ {0xB6, 0x1, 0},
+ {0xB7, 0x55, 0},
+ {0xB8, 0x1, 0},
+ {0xB9, 0x5, 0},
+ {0xBA, 0x55, 0},
+ {0xBB, 0x55, 0},
+ {0xC3, 0, 0},
+ {0xC4, 0, 0},
+ {0xC5, 0, 0},
+ {0xC6, 0, 0},
+ {0xC7, 0, 0},
+ {0xC8, 0, 0},
+ {0xC9, 0, 0},
+ {0xCA, 0, 0},
+ {0xCB, 0, 0},
+ {0xCD, 0, 0},
+ {0xCE, 0x5e, 0},
+ {0xCF, 0xc, 0},
+ {0xD0, 0xc, 0},
+ {0xD1, 0xc, 0},
+ {0xD2, 0, 0},
+ {0xD3, 0x2b, 0},
+ {0xD4, 0xc, 0},
+ {0xD5, 0, 0},
+ {0xD6, 0x70, 1},
+ {0xDB, 0x7, 0},
+ {0xDC, 0, 0},
+ {0xDD, 0, 0},
+ {0xDE, 0x88, 1},
+ {0xDF, 0, 0},
+ {0xE0, 0x1f, 0},
+ {0xE1, 0x20, 1},
+ {0xE2, 0x1, 0},
+ {0xE3, 0x30, 0},
+ {0xE4, 0x70, 0},
+ {0xE5, 0, 0},
+ {0xE6, 0, 0},
+ {0xE7, 0x33, 0},
+ {0xE8, 0xf, 1},
+ {0xE9, 0xf, 1},
+ {0xEA, 0, 0},
+ {0xEB, 0x11, 0},
+ {0x105, 0x3c, 0},
+ {0x106, 0x1, 1},
+ {0x107, 0xa, 0},
+ {0x10A, 0, 0},
+ {0x10B, 0x40, 0},
+ {0x10C, 0x40, 0},
+ {0x10D, 0x88, 0},
+ {0x10E, 0x10, 0},
+ {0x10F, 0xf0, 0},
+ {0x110, 0x10, 0},
+ {0x111, 0xf0, 0},
+ {0x114, 0x10, 0},
+ {0x115, 0x55, 0},
+ {0x116, 0x3f, 1},
+ {0x117, 0x36, 1},
+ {0x118, 0, 0},
+ {0x119, 0, 0},
+ {0x11A, 0, 0},
+ {0x11B, 0x87, 0},
+ {0x11C, 0x11, 0},
+ {0x11D, 0, 0},
+ {0x11E, 0x33, 0},
+ {0x11F, 0x88, 0},
+ {0x126, 0x20, 1},
+ {0x127, 0x3f, 0},
+ {0x128, 0x44, 0},
+ {0x129, 0x8c, 0},
+ {0x12A, 0x6c, 0},
+ {0x12B, 0x22, 0},
+ {0x12C, 0xbe, 0},
+ {0x12D, 0x55, 0},
+ {0x12F, 0xc, 0},
+ {0x130, 0xaa, 0},
+ {0x131, 0x2, 0},
+ {0x132, 0, 0},
+ {0x133, 0x10, 0},
+ {0x134, 0x1, 0},
+ {0x135, 0, 0},
+ {0x136, 0, 0},
+ {0x137, 0x80, 0},
+ {0x138, 0x60, 0},
+ {0x139, 0x44, 0},
+ {0x13A, 0x55, 0},
+ {0x13B, 0x1, 0},
+ {0x13C, 0x55, 0},
+ {0x13D, 0x1, 0},
+ {0x13E, 0x5, 0},
+ {0x13F, 0x55, 0},
+ {0x140, 0x55, 0},
+ {0x148, 0, 0},
+ {0x149, 0, 0},
+ {0x14A, 0, 0},
+ {0x14B, 0, 0},
+ {0x14C, 0, 0},
+ {0x14D, 0, 0},
+ {0x14E, 0, 0},
+ {0x14F, 0, 0},
+ {0x150, 0, 0},
+ {0x154, 0xc, 0},
+ {0x155, 0xc, 0},
+ {0x156, 0xc, 0},
+ {0x157, 0, 0},
+ {0x158, 0x2b, 0},
+ {0x159, 0x84, 0},
+ {0x15A, 0x15, 0},
+ {0x15B, 0xf, 0},
+ {0x15C, 0, 0},
+ {0x15D, 0, 0},
+ {0x15E, 0, 1},
+ {0x15F, 0, 1},
+ {0x160, 0, 1},
+ {0x161, 0, 1},
+ {0x162, 0, 1},
+ {0x163, 0, 1},
+ {0x164, 0, 0},
+ {0x165, 0, 0},
+ {0x166, 0, 0},
+ {0x167, 0, 0},
+ {0x168, 0, 0},
+ {0x169, 0, 0},
+ {0x16A, 0, 1},
+ {0x16B, 0, 1},
+ {0x16C, 0, 1},
+ {0x16D, 0, 0},
+ {0x170, 0, 0},
+ {0x171, 0x77, 0},
+ {0x172, 0x77, 0},
+ {0x173, 0x77, 0},
+ {0x174, 0x77, 0},
+ {0x175, 0, 0},
+ {0x176, 0x3, 0},
+ {0x177, 0x37, 0},
+ {0x178, 0x3, 0},
+ {0x179, 0, 0},
+ {0x17B, 0x21, 0},
+ {0x17C, 0, 0},
+ {0x17D, 0xaa, 0},
+ {0x17E, 0, 0},
+ {0x190, 0, 0},
+ {0x191, 0x77, 0},
+ {0x192, 0x77, 0},
+ {0x193, 0x77, 0},
+ {0x194, 0x77, 0},
+ {0x195, 0, 0},
+ {0x196, 0x3, 0},
+ {0x197, 0x37, 0},
+ {0x198, 0x3, 0},
+ {0x199, 0, 0},
+ {0x19B, 0x21, 0},
+ {0x19C, 0, 0},
+ {0x19D, 0xaa, 0},
+ {0x19E, 0, 0},
+ {0x1A1, 0x2, 0},
+ {0x1A2, 0xf, 0},
+ {0x1A3, 0xf, 0},
+ {0x1A4, 0, 1},
+ {0x1A5, 0, 1},
+ {0x1A6, 0, 1},
+ {0x1A7, 0x2, 0},
+ {0x1A8, 0xf, 0},
+ {0x1A9, 0xf, 0},
+ {0x1AA, 0, 1},
+ {0x1AB, 0, 1},
+ {0x1AC, 0, 1},
+ {0x1AD, 0x84, 0},
+ {0x1AE, 0x60, 0},
+ {0x1AF, 0x47, 0},
+ {0x1B0, 0x47, 0},
+ {0x1B1, 0, 0},
+ {0x1B2, 0, 0},
+ {0x1B3, 0, 0},
+ {0x1B4, 0, 0},
+ {0x1B5, 0, 0},
+ {0x1B6, 0, 0},
+ {0x1B7, 0xc, 1},
+ {0x1B8, 0, 0},
+ {0x1B9, 0, 0},
+ {0x1BA, 0, 0},
+ {0x1BB, 0, 0},
+ {0x1BC, 0, 0},
+ {0x1BD, 0, 0},
+ {0x1BE, 0, 0},
+ {0x1BF, 0, 0},
+ {0x1C0, 0, 0},
+ {0x1C1, 0x1, 1},
+ {0x1C2, 0x80, 1},
+ {0x1C3, 0, 0},
+ {0x1C4, 0, 0},
+ {0x1C5, 0, 0},
+ {0x1C6, 0, 0},
+ {0x1C7, 0, 0},
+ {0x1C8, 0, 0},
+ {0x1C9, 0, 0},
+ {0x1CA, 0, 0},
+ {0xFFFF, 0, 0}
+};
+
+radio_20xx_regs_t regs_2057_rev5v1[] = {
+ {0x00, 0x15, 1},
+ {0x01, 0x57, 1},
+ {0x02, 0x20, 1},
+ {0x03, 0x1f, 0},
+ {0x04, 0x4, 0},
+ {0x05, 0x2, 0},
+ {0x06, 0x1, 0},
+ {0x07, 0x1, 0},
+ {0x08, 0x1, 0},
+ {0x09, 0x69, 0},
+ {0x0A, 0x66, 0},
+ {0x0B, 0x6, 0},
+ {0x0C, 0x18, 0},
+ {0x0D, 0x3, 0},
+ {0x0E, 0x20, 0},
+ {0x0F, 0x20, 0},
+ {0x10, 0, 0},
+ {0x11, 0x7c, 0},
+ {0x12, 0x42, 0},
+ {0x13, 0xbd, 0},
+ {0x14, 0x7, 0},
+ {0x15, 0x87, 0},
+ {0x16, 0x8, 0},
+ {0x17, 0x17, 0},
+ {0x18, 0x7, 0},
+ {0x19, 0, 0},
+ {0x1A, 0x2, 0},
+ {0x1B, 0x13, 0},
+ {0x1C, 0x3e, 0},
+ {0x1D, 0x3e, 0},
+ {0x1E, 0x96, 0},
+ {0x1F, 0x4, 0},
+ {0x20, 0, 0},
+ {0x21, 0, 0},
+ {0x22, 0x17, 0},
+ {0x23, 0x6, 1},
+ {0x24, 0x1, 0},
+ {0x25, 0x6, 0},
+ {0x26, 0x4, 0},
+ {0x27, 0xd, 0},
+ {0x28, 0xd, 0},
+ {0x29, 0x30, 0},
+ {0x2A, 0x32, 0},
+ {0x2B, 0x8, 0},
+ {0x2C, 0x1c, 0},
+ {0x2D, 0x2, 0},
+ {0x2E, 0x4, 0},
+ {0x2F, 0x7f, 0},
+ {0x30, 0x27, 0},
+ {0x31, 0, 1},
+ {0x32, 0, 1},
+ {0x33, 0, 1},
+ {0x34, 0, 0},
+ {0x35, 0x20, 0},
+ {0x36, 0x18, 0},
+ {0x37, 0x7, 0},
+ {0x38, 0x66, 0},
+ {0x39, 0x66, 0},
+ {0x3C, 0xff, 0},
+ {0x3D, 0xff, 0},
+ {0x40, 0x16, 0},
+ {0x41, 0x7, 0},
+ {0x45, 0x3, 0},
+ {0x46, 0x1, 0},
+ {0x47, 0x7, 0},
+ {0x4B, 0x66, 0},
+ {0x4C, 0x66, 0},
+ {0x4D, 0, 0},
+ {0x4E, 0x4, 0},
+ {0x4F, 0xc, 0},
+ {0x50, 0, 0},
+ {0x51, 0x70, 1},
+ {0x56, 0x7, 0},
+ {0x57, 0, 0},
+ {0x58, 0, 0},
+ {0x59, 0x88, 1},
+ {0x5A, 0, 0},
+ {0x5B, 0x1f, 0},
+ {0x5C, 0x20, 1},
+ {0x5D, 0x1, 0},
+ {0x5E, 0x30, 0},
+ {0x5F, 0x70, 0},
+ {0x60, 0, 0},
+ {0x61, 0, 0},
+ {0x62, 0x33, 1},
+ {0x63, 0xf, 1},
+ {0x64, 0xf, 1},
+ {0x65, 0, 0},
+ {0x66, 0x11, 0},
+ {0x80, 0x3c, 0},
+ {0x81, 0x1, 1},
+ {0x82, 0xa, 0},
+ {0x85, 0, 0},
+ {0x86, 0x40, 0},
+ {0x87, 0x40, 0},
+ {0x88, 0x88, 0},
+ {0x89, 0x10, 0},
+ {0x8A, 0xf0, 0},
+ {0x8B, 0x10, 0},
+ {0x8C, 0xf0, 0},
+ {0x8F, 0x10, 0},
+ {0x90, 0x55, 0},
+ {0x91, 0x3f, 1},
+ {0x92, 0x36, 1},
+ {0x93, 0, 0},
+ {0x94, 0, 0},
+ {0x95, 0, 0},
+ {0x96, 0x87, 0},
+ {0x97, 0x11, 0},
+ {0x98, 0, 0},
+ {0x99, 0x33, 0},
+ {0x9A, 0x88, 0},
+ {0xA1, 0x20, 1},
+ {0xA2, 0x3f, 0},
+ {0xA3, 0x44, 0},
+ {0xA4, 0x8c, 0},
+ {0xA5, 0x6c, 0},
+ {0xA6, 0x22, 0},
+ {0xA7, 0xbe, 0},
+ {0xA8, 0x55, 0},
+ {0xAA, 0xc, 0},
+ {0xAB, 0xaa, 0},
+ {0xAC, 0x2, 0},
+ {0xAD, 0, 0},
+ {0xAE, 0x10, 0},
+ {0xAF, 0x1, 0},
+ {0xB0, 0, 0},
+ {0xB1, 0, 0},
+ {0xB2, 0x80, 0},
+ {0xB3, 0x60, 0},
+ {0xB4, 0x44, 0},
+ {0xB5, 0x55, 0},
+ {0xB6, 0x1, 0},
+ {0xB7, 0x55, 0},
+ {0xB8, 0x1, 0},
+ {0xB9, 0x5, 0},
+ {0xBA, 0x55, 0},
+ {0xBB, 0x55, 0},
+ {0xC3, 0, 0},
+ {0xC4, 0, 0},
+ {0xC5, 0, 0},
+ {0xC6, 0, 0},
+ {0xC7, 0, 0},
+ {0xC8, 0, 0},
+ {0xC9, 0x1, 1},
+ {0xCA, 0, 0},
+ {0xCB, 0, 0},
+ {0xCD, 0, 0},
+ {0xCE, 0x5e, 0},
+ {0xCF, 0xc, 0},
+ {0xD0, 0xc, 0},
+ {0xD1, 0xc, 0},
+ {0xD2, 0, 0},
+ {0xD3, 0x2b, 0},
+ {0xD4, 0xc, 0},
+ {0xD5, 0, 0},
+ {0xD6, 0x70, 1},
+ {0xDB, 0x7, 0},
+ {0xDC, 0, 0},
+ {0xDD, 0, 0},
+ {0xDE, 0x88, 1},
+ {0xDF, 0, 0},
+ {0xE0, 0x1f, 0},
+ {0xE1, 0x20, 1},
+ {0xE2, 0x1, 0},
+ {0xE3, 0x30, 0},
+ {0xE4, 0x70, 0},
+ {0xE5, 0, 0},
+ {0xE6, 0, 0},
+ {0xE7, 0x33, 0},
+ {0xE8, 0xf, 1},
+ {0xE9, 0xf, 1},
+ {0xEA, 0, 0},
+ {0xEB, 0x11, 0},
+ {0x105, 0x3c, 0},
+ {0x106, 0x1, 1},
+ {0x107, 0xa, 0},
+ {0x10A, 0, 0},
+ {0x10B, 0x40, 0},
+ {0x10C, 0x40, 0},
+ {0x10D, 0x88, 0},
+ {0x10E, 0x10, 0},
+ {0x10F, 0xf0, 0},
+ {0x110, 0x10, 0},
+ {0x111, 0xf0, 0},
+ {0x114, 0x10, 0},
+ {0x115, 0x55, 0},
+ {0x116, 0x3f, 1},
+ {0x117, 0x36, 1},
+ {0x118, 0, 0},
+ {0x119, 0, 0},
+ {0x11A, 0, 0},
+ {0x11B, 0x87, 0},
+ {0x11C, 0x11, 0},
+ {0x11D, 0, 0},
+ {0x11E, 0x33, 0},
+ {0x11F, 0x88, 0},
+ {0x126, 0x20, 1},
+ {0x127, 0x3f, 0},
+ {0x128, 0x44, 0},
+ {0x129, 0x8c, 0},
+ {0x12A, 0x6c, 0},
+ {0x12B, 0x22, 0},
+ {0x12C, 0xbe, 0},
+ {0x12D, 0x55, 0},
+ {0x12F, 0xc, 0},
+ {0x130, 0xaa, 0},
+ {0x131, 0x2, 0},
+ {0x132, 0, 0},
+ {0x133, 0x10, 0},
+ {0x134, 0x1, 0},
+ {0x135, 0, 0},
+ {0x136, 0, 0},
+ {0x137, 0x80, 0},
+ {0x138, 0x60, 0},
+ {0x139, 0x44, 0},
+ {0x13A, 0x55, 0},
+ {0x13B, 0x1, 0},
+ {0x13C, 0x55, 0},
+ {0x13D, 0x1, 0},
+ {0x13E, 0x5, 0},
+ {0x13F, 0x55, 0},
+ {0x140, 0x55, 0},
+ {0x148, 0, 0},
+ {0x149, 0, 0},
+ {0x14A, 0, 0},
+ {0x14B, 0, 0},
+ {0x14C, 0, 0},
+ {0x14D, 0, 0},
+ {0x14E, 0x1, 1},
+ {0x14F, 0, 0},
+ {0x150, 0, 0},
+ {0x154, 0xc, 0},
+ {0x155, 0xc, 0},
+ {0x156, 0xc, 0},
+ {0x157, 0, 0},
+ {0x158, 0x2b, 0},
+ {0x159, 0x84, 0},
+ {0x15A, 0x15, 0},
+ {0x15B, 0xf, 0},
+ {0x15C, 0, 0},
+ {0x15D, 0, 0},
+ {0x15E, 0, 1},
+ {0x15F, 0, 1},
+ {0x160, 0, 1},
+ {0x161, 0, 1},
+ {0x162, 0, 1},
+ {0x163, 0, 1},
+ {0x164, 0, 0},
+ {0x165, 0, 0},
+ {0x166, 0, 0},
+ {0x167, 0, 0},
+ {0x168, 0, 0},
+ {0x169, 0, 0},
+ {0x16A, 0, 1},
+ {0x16B, 0, 1},
+ {0x16C, 0, 1},
+ {0x16D, 0, 0},
+ {0x170, 0, 0},
+ {0x171, 0x77, 0},
+ {0x172, 0x77, 0},
+ {0x173, 0x77, 0},
+ {0x174, 0x77, 0},
+ {0x175, 0, 0},
+ {0x176, 0x3, 0},
+ {0x177, 0x37, 0},
+ {0x178, 0x3, 0},
+ {0x179, 0, 0},
+ {0x17B, 0x21, 0},
+ {0x17C, 0, 0},
+ {0x17D, 0xaa, 0},
+ {0x17E, 0, 0},
+ {0x190, 0, 0},
+ {0x191, 0x77, 0},
+ {0x192, 0x77, 0},
+ {0x193, 0x77, 0},
+ {0x194, 0x77, 0},
+ {0x195, 0, 0},
+ {0x196, 0x3, 0},
+ {0x197, 0x37, 0},
+ {0x198, 0x3, 0},
+ {0x199, 0, 0},
+ {0x19B, 0x21, 0},
+ {0x19C, 0, 0},
+ {0x19D, 0xaa, 0},
+ {0x19E, 0, 0},
+ {0x1A1, 0x2, 0},
+ {0x1A2, 0xf, 0},
+ {0x1A3, 0xf, 0},
+ {0x1A4, 0, 1},
+ {0x1A5, 0, 1},
+ {0x1A6, 0, 1},
+ {0x1A7, 0x2, 0},
+ {0x1A8, 0xf, 0},
+ {0x1A9, 0xf, 0},
+ {0x1AA, 0, 1},
+ {0x1AB, 0, 1},
+ {0x1AC, 0, 1},
+ {0x1AD, 0x84, 0},
+ {0x1AE, 0x60, 0},
+ {0x1AF, 0x47, 0},
+ {0x1B0, 0x47, 0},
+ {0x1B1, 0, 0},
+ {0x1B2, 0, 0},
+ {0x1B3, 0, 0},
+ {0x1B4, 0, 0},
+ {0x1B5, 0, 0},
+ {0x1B6, 0, 0},
+ {0x1B7, 0xc, 1},
+ {0x1B8, 0, 0},
+ {0x1B9, 0, 0},
+ {0x1BA, 0, 0},
+ {0x1BB, 0, 0},
+ {0x1BC, 0, 0},
+ {0x1BD, 0, 0},
+ {0x1BE, 0, 0},
+ {0x1BF, 0, 0},
+ {0x1C0, 0, 0},
+ {0x1C1, 0x1, 1},
+ {0x1C2, 0x80, 1},
+ {0x1C3, 0, 0},
+ {0x1C4, 0, 0},
+ {0x1C5, 0, 0},
+ {0x1C6, 0, 0},
+ {0x1C7, 0, 0},
+ {0x1C8, 0, 0},
+ {0x1C9, 0, 0},
+ {0x1CA, 0, 0},
+ {0xFFFF, 0, 0}
+};
+
+radio_20xx_regs_t regs_2057_rev7[] = {
+ {0x00, 0, 1},
+ {0x01, 0x57, 1},
+ {0x02, 0x20, 1},
+ {0x03, 0x1f, 0},
+ {0x04, 0x4, 0},
+ {0x05, 0x2, 0},
+ {0x06, 0x1, 0},
+ {0x07, 0x1, 0},
+ {0x08, 0x1, 0},
+ {0x09, 0x69, 0},
+ {0x0A, 0x66, 0},
+ {0x0B, 0x6, 0},
+ {0x0C, 0x18, 0},
+ {0x0D, 0x3, 0},
+ {0x0E, 0x20, 0},
+ {0x0F, 0x20, 0},
+ {0x10, 0, 0},
+ {0x11, 0x7c, 0},
+ {0x12, 0x42, 0},
+ {0x13, 0xbd, 0},
+ {0x14, 0x7, 0},
+ {0x15, 0x87, 0},
+ {0x16, 0x8, 0},
+ {0x17, 0x17, 0},
+ {0x18, 0x7, 0},
+ {0x19, 0, 0},
+ {0x1A, 0x2, 0},
+ {0x1B, 0x13, 0},
+ {0x1C, 0x3e, 0},
+ {0x1D, 0x3e, 0},
+ {0x1E, 0x96, 0},
+ {0x1F, 0x4, 0},
+ {0x20, 0, 0},
+ {0x21, 0, 0},
+ {0x22, 0x17, 0},
+ {0x23, 0x6, 0},
+ {0x24, 0x1, 0},
+ {0x25, 0x6, 0},
+ {0x26, 0x4, 0},
+ {0x27, 0xd, 0},
+ {0x28, 0xd, 0},
+ {0x29, 0x30, 0},
+ {0x2A, 0x32, 0},
+ {0x2B, 0x8, 0},
+ {0x2C, 0x1c, 0},
+ {0x2D, 0x2, 0},
+ {0x2E, 0x4, 0},
+ {0x2F, 0x7f, 0},
+ {0x30, 0x27, 0},
+ {0x31, 0, 1},
+ {0x32, 0, 1},
+ {0x33, 0, 1},
+ {0x34, 0, 0},
+ {0x35, 0x20, 0},
+ {0x36, 0x18, 0},
+ {0x37, 0x7, 0},
+ {0x38, 0x66, 0},
+ {0x39, 0x66, 0},
+ {0x3A, 0x66, 0},
+ {0x3B, 0x66, 0},
+ {0x3C, 0xff, 0},
+ {0x3D, 0xff, 0},
+ {0x3E, 0xff, 0},
+ {0x3F, 0xff, 0},
+ {0x40, 0x16, 0},
+ {0x41, 0x7, 0},
+ {0x42, 0x19, 0},
+ {0x43, 0x7, 0},
+ {0x44, 0x6, 0},
+ {0x45, 0x3, 0},
+ {0x46, 0x1, 0},
+ {0x47, 0x7, 0},
+ {0x48, 0x33, 0},
+ {0x49, 0x5, 0},
+ {0x4A, 0x77, 0},
+ {0x4B, 0x66, 0},
+ {0x4C, 0x66, 0},
+ {0x4D, 0, 0},
+ {0x4E, 0x4, 0},
+ {0x4F, 0xc, 0},
+ {0x50, 0, 0},
+ {0x51, 0x70, 1},
+ {0x56, 0x7, 0},
+ {0x57, 0, 0},
+ {0x58, 0, 0},
+ {0x59, 0x88, 1},
+ {0x5A, 0, 0},
+ {0x5B, 0x1f, 0},
+ {0x5C, 0x20, 1},
+ {0x5D, 0x1, 0},
+ {0x5E, 0x30, 0},
+ {0x5F, 0x70, 0},
+ {0x60, 0, 0},
+ {0x61, 0, 0},
+ {0x62, 0x33, 1},
+ {0x63, 0xf, 1},
+ {0x64, 0x13, 1},
+ {0x65, 0, 0},
+ {0x66, 0xee, 1},
+ {0x69, 0, 0},
+ {0x6A, 0x7e, 0},
+ {0x6B, 0x3f, 0},
+ {0x6C, 0x7f, 0},
+ {0x6D, 0x78, 0},
+ {0x6E, 0x58, 1},
+ {0x6F, 0x88, 0},
+ {0x70, 0x8, 0},
+ {0x71, 0xf, 0},
+ {0x72, 0xbc, 0},
+ {0x73, 0x8, 0},
+ {0x74, 0x60, 0},
+ {0x75, 0x13, 1},
+ {0x76, 0x70, 0},
+ {0x77, 0, 0},
+ {0x78, 0, 0},
+ {0x79, 0, 0},
+ {0x7A, 0x33, 0},
+ {0x7B, 0x13, 1},
+ {0x7C, 0x14, 1},
+ {0x7D, 0xee, 1},
+ {0x80, 0x3c, 0},
+ {0x81, 0x1, 1},
+ {0x82, 0xa, 0},
+ {0x83, 0x9d, 0},
+ {0x84, 0xa, 0},
+ {0x85, 0, 0},
+ {0x86, 0x40, 0},
+ {0x87, 0x40, 0},
+ {0x88, 0x88, 0},
+ {0x89, 0x10, 0},
+ {0x8A, 0xf0, 0},
+ {0x8B, 0x10, 0},
+ {0x8C, 0xf0, 0},
+ {0x8D, 0, 0},
+ {0x8E, 0, 0},
+ {0x8F, 0x10, 0},
+ {0x90, 0x55, 0},
+ {0x91, 0x3f, 1},
+ {0x92, 0x36, 1},
+ {0x93, 0, 0},
+ {0x94, 0, 0},
+ {0x95, 0, 0},
+ {0x96, 0x87, 0},
+ {0x97, 0x11, 0},
+ {0x98, 0, 0},
+ {0x99, 0x33, 0},
+ {0x9A, 0x88, 0},
+ {0x9B, 0, 0},
+ {0x9C, 0x87, 0},
+ {0x9D, 0x11, 0},
+ {0x9E, 0, 0},
+ {0x9F, 0x33, 0},
+ {0xA0, 0x88, 0},
+ {0xA1, 0x20, 1},
+ {0xA2, 0x3f, 0},
+ {0xA3, 0x44, 0},
+ {0xA4, 0x8c, 0},
+ {0xA5, 0x6c, 0},
+ {0xA6, 0x22, 0},
+ {0xA7, 0xbe, 0},
+ {0xA8, 0x55, 0},
+ {0xAA, 0xc, 0},
+ {0xAB, 0xaa, 0},
+ {0xAC, 0x2, 0},
+ {0xAD, 0, 0},
+ {0xAE, 0x10, 0},
+ {0xAF, 0x1, 0},
+ {0xB0, 0, 0},
+ {0xB1, 0, 0},
+ {0xB2, 0x80, 0},
+ {0xB3, 0x60, 0},
+ {0xB4, 0x44, 0},
+ {0xB5, 0x55, 0},
+ {0xB6, 0x1, 0},
+ {0xB7, 0x55, 0},
+ {0xB8, 0x1, 0},
+ {0xB9, 0x5, 0},
+ {0xBA, 0x55, 0},
+ {0xBB, 0x55, 0},
+ {0xC1, 0, 0},
+ {0xC2, 0, 0},
+ {0xC3, 0, 0},
+ {0xC4, 0, 0},
+ {0xC5, 0, 0},
+ {0xC6, 0, 0},
+ {0xC7, 0, 0},
+ {0xC8, 0, 0},
+ {0xC9, 0, 0},
+ {0xCA, 0, 0},
+ {0xCB, 0, 0},
+ {0xCC, 0, 0},
+ {0xCD, 0, 0},
+ {0xCE, 0x5e, 0},
+ {0xCF, 0xc, 0},
+ {0xD0, 0xc, 0},
+ {0xD1, 0xc, 0},
+ {0xD2, 0, 0},
+ {0xD3, 0x2b, 0},
+ {0xD4, 0xc, 0},
+ {0xD5, 0, 0},
+ {0xD6, 0x70, 1},
+ {0xDB, 0x7, 0},
+ {0xDC, 0, 0},
+ {0xDD, 0, 0},
+ {0xDE, 0x88, 1},
+ {0xDF, 0, 0},
+ {0xE0, 0x1f, 0},
+ {0xE1, 0x20, 1},
+ {0xE2, 0x1, 0},
+ {0xE3, 0x30, 0},
+ {0xE4, 0x70, 0},
+ {0xE5, 0, 0},
+ {0xE6, 0, 0},
+ {0xE7, 0x33, 0},
+ {0xE8, 0xf, 1},
+ {0xE9, 0x13, 1},
+ {0xEA, 0, 0},
+ {0xEB, 0xee, 1},
+ {0xEE, 0, 0},
+ {0xEF, 0x7e, 0},
+ {0xF0, 0x3f, 0},
+ {0xF1, 0x7f, 0},
+ {0xF2, 0x78, 0},
+ {0xF3, 0x58, 1},
+ {0xF4, 0x88, 0},
+ {0xF5, 0x8, 0},
+ {0xF6, 0xf, 0},
+ {0xF7, 0xbc, 0},
+ {0xF8, 0x8, 0},
+ {0xF9, 0x60, 0},
+ {0xFA, 0x13, 1},
+ {0xFB, 0x70, 0},
+ {0xFC, 0, 0},
+ {0xFD, 0, 0},
+ {0xFE, 0, 0},
+ {0xFF, 0x33, 0},
+ {0x100, 0x13, 1},
+ {0x101, 0x14, 1},
+ {0x102, 0xee, 1},
+ {0x105, 0x3c, 0},
+ {0x106, 0x1, 1},
+ {0x107, 0xa, 0},
+ {0x108, 0x9d, 0},
+ {0x109, 0xa, 0},
+ {0x10A, 0, 0},
+ {0x10B, 0x40, 0},
+ {0x10C, 0x40, 0},
+ {0x10D, 0x88, 0},
+ {0x10E, 0x10, 0},
+ {0x10F, 0xf0, 0},
+ {0x110, 0x10, 0},
+ {0x111, 0xf0, 0},
+ {0x112, 0, 0},
+ {0x113, 0, 0},
+ {0x114, 0x10, 0},
+ {0x115, 0x55, 0},
+ {0x116, 0x3f, 1},
+ {0x117, 0x36, 1},
+ {0x118, 0, 0},
+ {0x119, 0, 0},
+ {0x11A, 0, 0},
+ {0x11B, 0x87, 0},
+ {0x11C, 0x11, 0},
+ {0x11D, 0, 0},
+ {0x11E, 0x33, 0},
+ {0x11F, 0x88, 0},
+ {0x120, 0, 0},
+ {0x121, 0x87, 0},
+ {0x122, 0x11, 0},
+ {0x123, 0, 0},
+ {0x124, 0x33, 0},
+ {0x125, 0x88, 0},
+ {0x126, 0x20, 1},
+ {0x127, 0x3f, 0},
+ {0x128, 0x44, 0},
+ {0x129, 0x8c, 0},
+ {0x12A, 0x6c, 0},
+ {0x12B, 0x22, 0},
+ {0x12C, 0xbe, 0},
+ {0x12D, 0x55, 0},
+ {0x12F, 0xc, 0},
+ {0x130, 0xaa, 0},
+ {0x131, 0x2, 0},
+ {0x132, 0, 0},
+ {0x133, 0x10, 0},
+ {0x134, 0x1, 0},
+ {0x135, 0, 0},
+ {0x136, 0, 0},
+ {0x137, 0x80, 0},
+ {0x138, 0x60, 0},
+ {0x139, 0x44, 0},
+ {0x13A, 0x55, 0},
+ {0x13B, 0x1, 0},
+ {0x13C, 0x55, 0},
+ {0x13D, 0x1, 0},
+ {0x13E, 0x5, 0},
+ {0x13F, 0x55, 0},
+ {0x140, 0x55, 0},
+ {0x146, 0, 0},
+ {0x147, 0, 0},
+ {0x148, 0, 0},
+ {0x149, 0, 0},
+ {0x14A, 0, 0},
+ {0x14B, 0, 0},
+ {0x14C, 0, 0},
+ {0x14D, 0, 0},
+ {0x14E, 0, 0},
+ {0x14F, 0, 0},
+ {0x150, 0, 0},
+ {0x151, 0, 0},
+ {0x154, 0xc, 0},
+ {0x155, 0xc, 0},
+ {0x156, 0xc, 0},
+ {0x157, 0, 0},
+ {0x158, 0x2b, 0},
+ {0x159, 0x84, 0},
+ {0x15A, 0x15, 0},
+ {0x15B, 0xf, 0},
+ {0x15C, 0, 0},
+ {0x15D, 0, 0},
+ {0x15E, 0, 1},
+ {0x15F, 0, 1},
+ {0x160, 0, 1},
+ {0x161, 0, 1},
+ {0x162, 0, 1},
+ {0x163, 0, 1},
+ {0x164, 0, 0},
+ {0x165, 0, 0},
+ {0x166, 0, 0},
+ {0x167, 0, 0},
+ {0x168, 0, 0},
+ {0x169, 0, 0},
+ {0x16A, 0, 1},
+ {0x16B, 0, 1},
+ {0x16C, 0, 1},
+ {0x16D, 0, 0},
+ {0x170, 0, 0},
+ {0x171, 0x77, 0},
+ {0x172, 0x77, 0},
+ {0x173, 0x77, 0},
+ {0x174, 0x77, 0},
+ {0x175, 0, 0},
+ {0x176, 0x3, 0},
+ {0x177, 0x37, 0},
+ {0x178, 0x3, 0},
+ {0x179, 0, 0},
+ {0x17A, 0x21, 0},
+ {0x17B, 0x21, 0},
+ {0x17C, 0, 0},
+ {0x17D, 0xaa, 0},
+ {0x17E, 0, 0},
+ {0x17F, 0xaa, 0},
+ {0x180, 0, 0},
+ {0x190, 0, 0},
+ {0x191, 0x77, 0},
+ {0x192, 0x77, 0},
+ {0x193, 0x77, 0},
+ {0x194, 0x77, 0},
+ {0x195, 0, 0},
+ {0x196, 0x3, 0},
+ {0x197, 0x37, 0},
+ {0x198, 0x3, 0},
+ {0x199, 0, 0},
+ {0x19A, 0x21, 0},
+ {0x19B, 0x21, 0},
+ {0x19C, 0, 0},
+ {0x19D, 0xaa, 0},
+ {0x19E, 0, 0},
+ {0x19F, 0xaa, 0},
+ {0x1A0, 0, 0},
+ {0x1A1, 0x2, 0},
+ {0x1A2, 0xf, 0},
+ {0x1A3, 0xf, 0},
+ {0x1A4, 0, 1},
+ {0x1A5, 0, 1},
+ {0x1A6, 0, 1},
+ {0x1A7, 0x2, 0},
+ {0x1A8, 0xf, 0},
+ {0x1A9, 0xf, 0},
+ {0x1AA, 0, 1},
+ {0x1AB, 0, 1},
+ {0x1AC, 0, 1},
+ {0x1AD, 0x84, 0},
+ {0x1AE, 0x60, 0},
+ {0x1AF, 0x47, 0},
+ {0x1B0, 0x47, 0},
+ {0x1B1, 0, 0},
+ {0x1B2, 0, 0},
+ {0x1B3, 0, 0},
+ {0x1B4, 0, 0},
+ {0x1B5, 0, 0},
+ {0x1B6, 0, 0},
+ {0x1B7, 0x5, 1},
+ {0x1B8, 0, 0},
+ {0x1B9, 0, 0},
+ {0x1BA, 0, 0},
+ {0x1BB, 0, 0},
+ {0x1BC, 0, 0},
+ {0x1BD, 0, 0},
+ {0x1BE, 0, 0},
+ {0x1BF, 0, 0},
+ {0x1C0, 0, 0},
+ {0x1C1, 0, 0},
+ {0x1C2, 0xa0, 1},
+ {0x1C3, 0, 0},
+ {0x1C4, 0, 0},
+ {0x1C5, 0, 0},
+ {0x1C6, 0, 0},
+ {0x1C7, 0, 0},
+ {0x1C8, 0, 0},
+ {0x1C9, 0, 0},
+ {0x1CA, 0, 0},
+ {0xFFFF, 0, 0}
+};
+
+radio_20xx_regs_t regs_2057_rev8[] = {
+ {0x00, 0x8, 1},
+ {0x01, 0x57, 1},
+ {0x02, 0x20, 1},
+ {0x03, 0x1f, 0},
+ {0x04, 0x4, 0},
+ {0x05, 0x2, 0},
+ {0x06, 0x1, 0},
+ {0x07, 0x1, 0},
+ {0x08, 0x1, 0},
+ {0x09, 0x69, 0},
+ {0x0A, 0x66, 0},
+ {0x0B, 0x6, 0},
+ {0x0C, 0x18, 0},
+ {0x0D, 0x3, 0},
+ {0x0E, 0x20, 0},
+ {0x0F, 0x20, 0},
+ {0x10, 0, 0},
+ {0x11, 0x7c, 0},
+ {0x12, 0x42, 0},
+ {0x13, 0xbd, 0},
+ {0x14, 0x7, 0},
+ {0x15, 0x87, 0},
+ {0x16, 0x8, 0},
+ {0x17, 0x17, 0},
+ {0x18, 0x7, 0},
+ {0x19, 0, 0},
+ {0x1A, 0x2, 0},
+ {0x1B, 0x13, 0},
+ {0x1C, 0x3e, 0},
+ {0x1D, 0x3e, 0},
+ {0x1E, 0x96, 0},
+ {0x1F, 0x4, 0},
+ {0x20, 0, 0},
+ {0x21, 0, 0},
+ {0x22, 0x17, 0},
+ {0x23, 0x6, 0},
+ {0x24, 0x1, 0},
+ {0x25, 0x6, 0},
+ {0x26, 0x4, 0},
+ {0x27, 0xd, 0},
+ {0x28, 0xd, 0},
+ {0x29, 0x30, 0},
+ {0x2A, 0x32, 0},
+ {0x2B, 0x8, 0},
+ {0x2C, 0x1c, 0},
+ {0x2D, 0x2, 0},
+ {0x2E, 0x4, 0},
+ {0x2F, 0x7f, 0},
+ {0x30, 0x27, 0},
+ {0x31, 0, 1},
+ {0x32, 0, 1},
+ {0x33, 0, 1},
+ {0x34, 0, 0},
+ {0x35, 0x20, 0},
+ {0x36, 0x18, 0},
+ {0x37, 0x7, 0},
+ {0x38, 0x66, 0},
+ {0x39, 0x66, 0},
+ {0x3A, 0x66, 0},
+ {0x3B, 0x66, 0},
+ {0x3C, 0xff, 0},
+ {0x3D, 0xff, 0},
+ {0x3E, 0xff, 0},
+ {0x3F, 0xff, 0},
+ {0x40, 0x16, 0},
+ {0x41, 0x7, 0},
+ {0x42, 0x19, 0},
+ {0x43, 0x7, 0},
+ {0x44, 0x6, 0},
+ {0x45, 0x3, 0},
+ {0x46, 0x1, 0},
+ {0x47, 0x7, 0},
+ {0x48, 0x33, 0},
+ {0x49, 0x5, 0},
+ {0x4A, 0x77, 0},
+ {0x4B, 0x66, 0},
+ {0x4C, 0x66, 0},
+ {0x4D, 0, 0},
+ {0x4E, 0x4, 0},
+ {0x4F, 0xc, 0},
+ {0x50, 0, 0},
+ {0x51, 0x70, 1},
+ {0x56, 0x7, 0},
+ {0x57, 0, 0},
+ {0x58, 0, 0},
+ {0x59, 0x88, 1},
+ {0x5A, 0, 0},
+ {0x5B, 0x1f, 0},
+ {0x5C, 0x20, 1},
+ {0x5D, 0x1, 0},
+ {0x5E, 0x30, 0},
+ {0x5F, 0x70, 0},
+ {0x60, 0, 0},
+ {0x61, 0, 0},
+ {0x62, 0x33, 1},
+ {0x63, 0xf, 1},
+ {0x64, 0xf, 1},
+ {0x65, 0, 0},
+ {0x66, 0x11, 0},
+ {0x69, 0, 0},
+ {0x6A, 0x7e, 0},
+ {0x6B, 0x3f, 0},
+ {0x6C, 0x7f, 0},
+ {0x6D, 0x78, 0},
+ {0x6E, 0x58, 1},
+ {0x6F, 0x88, 0},
+ {0x70, 0x8, 0},
+ {0x71, 0xf, 0},
+ {0x72, 0xbc, 0},
+ {0x73, 0x8, 0},
+ {0x74, 0x60, 0},
+ {0x75, 0x13, 1},
+ {0x76, 0x70, 0},
+ {0x77, 0, 0},
+ {0x78, 0, 0},
+ {0x79, 0, 0},
+ {0x7A, 0x33, 0},
+ {0x7B, 0x13, 1},
+ {0x7C, 0xf, 1},
+ {0x7D, 0xee, 1},
+ {0x80, 0x3c, 0},
+ {0x81, 0x1, 1},
+ {0x82, 0xa, 0},
+ {0x83, 0x9d, 0},
+ {0x84, 0xa, 0},
+ {0x85, 0, 0},
+ {0x86, 0x40, 0},
+ {0x87, 0x40, 0},
+ {0x88, 0x88, 0},
+ {0x89, 0x10, 0},
+ {0x8A, 0xf0, 0},
+ {0x8B, 0x10, 0},
+ {0x8C, 0xf0, 0},
+ {0x8D, 0, 0},
+ {0x8E, 0, 0},
+ {0x8F, 0x10, 0},
+ {0x90, 0x55, 0},
+ {0x91, 0x3f, 1},
+ {0x92, 0x36, 1},
+ {0x93, 0, 0},
+ {0x94, 0, 0},
+ {0x95, 0, 0},
+ {0x96, 0x87, 0},
+ {0x97, 0x11, 0},
+ {0x98, 0, 0},
+ {0x99, 0x33, 0},
+ {0x9A, 0x88, 0},
+ {0x9B, 0, 0},
+ {0x9C, 0x87, 0},
+ {0x9D, 0x11, 0},
+ {0x9E, 0, 0},
+ {0x9F, 0x33, 0},
+ {0xA0, 0x88, 0},
+ {0xA1, 0x20, 1},
+ {0xA2, 0x3f, 0},
+ {0xA3, 0x44, 0},
+ {0xA4, 0x8c, 0},
+ {0xA5, 0x6c, 0},
+ {0xA6, 0x22, 0},
+ {0xA7, 0xbe, 0},
+ {0xA8, 0x55, 0},
+ {0xAA, 0xc, 0},
+ {0xAB, 0xaa, 0},
+ {0xAC, 0x2, 0},
+ {0xAD, 0, 0},
+ {0xAE, 0x10, 0},
+ {0xAF, 0x1, 0},
+ {0xB0, 0, 0},
+ {0xB1, 0, 0},
+ {0xB2, 0x80, 0},
+ {0xB3, 0x60, 0},
+ {0xB4, 0x44, 0},
+ {0xB5, 0x55, 0},
+ {0xB6, 0x1, 0},
+ {0xB7, 0x55, 0},
+ {0xB8, 0x1, 0},
+ {0xB9, 0x5, 0},
+ {0xBA, 0x55, 0},
+ {0xBB, 0x55, 0},
+ {0xC1, 0, 0},
+ {0xC2, 0, 0},
+ {0xC3, 0, 0},
+ {0xC4, 0, 0},
+ {0xC5, 0, 0},
+ {0xC6, 0, 0},
+ {0xC7, 0, 0},
+ {0xC8, 0, 0},
+ {0xC9, 0x1, 1},
+ {0xCA, 0, 0},
+ {0xCB, 0, 0},
+ {0xCC, 0, 0},
+ {0xCD, 0, 0},
+ {0xCE, 0x5e, 0},
+ {0xCF, 0xc, 0},
+ {0xD0, 0xc, 0},
+ {0xD1, 0xc, 0},
+ {0xD2, 0, 0},
+ {0xD3, 0x2b, 0},
+ {0xD4, 0xc, 0},
+ {0xD5, 0, 0},
+ {0xD6, 0x70, 1},
+ {0xDB, 0x7, 0},
+ {0xDC, 0, 0},
+ {0xDD, 0, 0},
+ {0xDE, 0x88, 1},
+ {0xDF, 0, 0},
+ {0xE0, 0x1f, 0},
+ {0xE1, 0x20, 1},
+ {0xE2, 0x1, 0},
+ {0xE3, 0x30, 0},
+ {0xE4, 0x70, 0},
+ {0xE5, 0, 0},
+ {0xE6, 0, 0},
+ {0xE7, 0x33, 0},
+ {0xE8, 0xf, 1},
+ {0xE9, 0xf, 1},
+ {0xEA, 0, 0},
+ {0xEB, 0x11, 0},
+ {0xEE, 0, 0},
+ {0xEF, 0x7e, 0},
+ {0xF0, 0x3f, 0},
+ {0xF1, 0x7f, 0},
+ {0xF2, 0x78, 0},
+ {0xF3, 0x58, 1},
+ {0xF4, 0x88, 0},
+ {0xF5, 0x8, 0},
+ {0xF6, 0xf, 0},
+ {0xF7, 0xbc, 0},
+ {0xF8, 0x8, 0},
+ {0xF9, 0x60, 0},
+ {0xFA, 0x13, 1},
+ {0xFB, 0x70, 0},
+ {0xFC, 0, 0},
+ {0xFD, 0, 0},
+ {0xFE, 0, 0},
+ {0xFF, 0x33, 0},
+ {0x100, 0x13, 1},
+ {0x101, 0xf, 1},
+ {0x102, 0xee, 1},
+ {0x105, 0x3c, 0},
+ {0x106, 0x1, 1},
+ {0x107, 0xa, 0},
+ {0x108, 0x9d, 0},
+ {0x109, 0xa, 0},
+ {0x10A, 0, 0},
+ {0x10B, 0x40, 0},
+ {0x10C, 0x40, 0},
+ {0x10D, 0x88, 0},
+ {0x10E, 0x10, 0},
+ {0x10F, 0xf0, 0},
+ {0x110, 0x10, 0},
+ {0x111, 0xf0, 0},
+ {0x112, 0, 0},
+ {0x113, 0, 0},
+ {0x114, 0x10, 0},
+ {0x115, 0x55, 0},
+ {0x116, 0x3f, 1},
+ {0x117, 0x36, 1},
+ {0x118, 0, 0},
+ {0x119, 0, 0},
+ {0x11A, 0, 0},
+ {0x11B, 0x87, 0},
+ {0x11C, 0x11, 0},
+ {0x11D, 0, 0},
+ {0x11E, 0x33, 0},
+ {0x11F, 0x88, 0},
+ {0x120, 0, 0},
+ {0x121, 0x87, 0},
+ {0x122, 0x11, 0},
+ {0x123, 0, 0},
+ {0x124, 0x33, 0},
+ {0x125, 0x88, 0},
+ {0x126, 0x20, 1},
+ {0x127, 0x3f, 0},
+ {0x128, 0x44, 0},
+ {0x129, 0x8c, 0},
+ {0x12A, 0x6c, 0},
+ {0x12B, 0x22, 0},
+ {0x12C, 0xbe, 0},
+ {0x12D, 0x55, 0},
+ {0x12F, 0xc, 0},
+ {0x130, 0xaa, 0},
+ {0x131, 0x2, 0},
+ {0x132, 0, 0},
+ {0x133, 0x10, 0},
+ {0x134, 0x1, 0},
+ {0x135, 0, 0},
+ {0x136, 0, 0},
+ {0x137, 0x80, 0},
+ {0x138, 0x60, 0},
+ {0x139, 0x44, 0},
+ {0x13A, 0x55, 0},
+ {0x13B, 0x1, 0},
+ {0x13C, 0x55, 0},
+ {0x13D, 0x1, 0},
+ {0x13E, 0x5, 0},
+ {0x13F, 0x55, 0},
+ {0x140, 0x55, 0},
+ {0x146, 0, 0},
+ {0x147, 0, 0},
+ {0x148, 0, 0},
+ {0x149, 0, 0},
+ {0x14A, 0, 0},
+ {0x14B, 0, 0},
+ {0x14C, 0, 0},
+ {0x14D, 0, 0},
+ {0x14E, 0x1, 1},
+ {0x14F, 0, 0},
+ {0x150, 0, 0},
+ {0x151, 0, 0},
+ {0x154, 0xc, 0},
+ {0x155, 0xc, 0},
+ {0x156, 0xc, 0},
+ {0x157, 0, 0},
+ {0x158, 0x2b, 0},
+ {0x159, 0x84, 0},
+ {0x15A, 0x15, 0},
+ {0x15B, 0xf, 0},
+ {0x15C, 0, 0},
+ {0x15D, 0, 0},
+ {0x15E, 0, 1},
+ {0x15F, 0, 1},
+ {0x160, 0, 1},
+ {0x161, 0, 1},
+ {0x162, 0, 1},
+ {0x163, 0, 1},
+ {0x164, 0, 0},
+ {0x165, 0, 0},
+ {0x166, 0, 0},
+ {0x167, 0, 0},
+ {0x168, 0, 0},
+ {0x169, 0, 0},
+ {0x16A, 0, 1},
+ {0x16B, 0, 1},
+ {0x16C, 0, 1},
+ {0x16D, 0, 0},
+ {0x170, 0, 0},
+ {0x171, 0x77, 0},
+ {0x172, 0x77, 0},
+ {0x173, 0x77, 0},
+ {0x174, 0x77, 0},
+ {0x175, 0, 0},
+ {0x176, 0x3, 0},
+ {0x177, 0x37, 0},
+ {0x178, 0x3, 0},
+ {0x179, 0, 0},
+ {0x17A, 0x21, 0},
+ {0x17B, 0x21, 0},
+ {0x17C, 0, 0},
+ {0x17D, 0xaa, 0},
+ {0x17E, 0, 0},
+ {0x17F, 0xaa, 0},
+ {0x180, 0, 0},
+ {0x190, 0, 0},
+ {0x191, 0x77, 0},
+ {0x192, 0x77, 0},
+ {0x193, 0x77, 0},
+ {0x194, 0x77, 0},
+ {0x195, 0, 0},
+ {0x196, 0x3, 0},
+ {0x197, 0x37, 0},
+ {0x198, 0x3, 0},
+ {0x199, 0, 0},
+ {0x19A, 0x21, 0},
+ {0x19B, 0x21, 0},
+ {0x19C, 0, 0},
+ {0x19D, 0xaa, 0},
+ {0x19E, 0, 0},
+ {0x19F, 0xaa, 0},
+ {0x1A0, 0, 0},
+ {0x1A1, 0x2, 0},
+ {0x1A2, 0xf, 0},
+ {0x1A3, 0xf, 0},
+ {0x1A4, 0, 1},
+ {0x1A5, 0, 1},
+ {0x1A6, 0, 1},
+ {0x1A7, 0x2, 0},
+ {0x1A8, 0xf, 0},
+ {0x1A9, 0xf, 0},
+ {0x1AA, 0, 1},
+ {0x1AB, 0, 1},
+ {0x1AC, 0, 1},
+ {0x1AD, 0x84, 0},
+ {0x1AE, 0x60, 0},
+ {0x1AF, 0x47, 0},
+ {0x1B0, 0x47, 0},
+ {0x1B1, 0, 0},
+ {0x1B2, 0, 0},
+ {0x1B3, 0, 0},
+ {0x1B4, 0, 0},
+ {0x1B5, 0, 0},
+ {0x1B6, 0, 0},
+ {0x1B7, 0x5, 1},
+ {0x1B8, 0, 0},
+ {0x1B9, 0, 0},
+ {0x1BA, 0, 0},
+ {0x1BB, 0, 0},
+ {0x1BC, 0, 0},
+ {0x1BD, 0, 0},
+ {0x1BE, 0, 0},
+ {0x1BF, 0, 0},
+ {0x1C0, 0, 0},
+ {0x1C1, 0, 0},
+ {0x1C2, 0xa0, 1},
+ {0x1C3, 0, 0},
+ {0x1C4, 0, 0},
+ {0x1C5, 0, 0},
+ {0x1C6, 0, 0},
+ {0x1C7, 0, 0},
+ {0x1C8, 0, 0},
+ {0x1C9, 0, 0},
+ {0x1CA, 0, 0},
+ {0xFFFF, 0, 0}
+};
+
+static int16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
+
+static int32 nphy_lnagain_est0[] = { -315, 40370 };
+static int32 nphy_lnagain_est1[] = { -224, 23242 };
+
+static const uint16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
+ {
+ {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
+ {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
+ {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
+ {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
+ {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
+ {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
+ {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
+ {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
+ {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
+ },
+ {
+ {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+ {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+ {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
+ {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
+ {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
+ {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
+ {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
+ {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
+ {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
+ }
+};
+
+static const uint32 nphy_tpc_txgain[] = {
+ 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
+ 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
+ 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
+ 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
+ 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
+ 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
+ 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
+ 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
+ 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
+ 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
+ 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
+ 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
+ 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
+ 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
+ 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
+ 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
+ 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
+ 0x03902942, 0x03902844, 0x03902842, 0x03902744,
+ 0x03902742, 0x03902644, 0x03902642, 0x03902544,
+ 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
+ 0x03802a42, 0x03802944, 0x03802942, 0x03802844,
+ 0x03802842, 0x03802744, 0x03802742, 0x03802644,
+ 0x03802642, 0x03802544, 0x03802542, 0x03802444,
+ 0x03802442, 0x03802344, 0x03802342, 0x03802244,
+ 0x03802242, 0x03802144, 0x03802142, 0x03802044,
+ 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
+ 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
+ 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
+ 0x03801a42, 0x03801944, 0x03801942, 0x03801844,
+ 0x03801842, 0x03801744, 0x03801742, 0x03801644,
+ 0x03801642, 0x03801544, 0x03801542, 0x03801444,
+ 0x03801442, 0x03801344, 0x03801342, 0x00002b00
+};
+
+static const uint16 nphy_tpc_loscale[] = {
+ 256, 256, 271, 271, 287, 256, 256, 271,
+ 271, 287, 287, 304, 304, 256, 256, 271,
+ 271, 287, 287, 304, 304, 322, 322, 341,
+ 341, 362, 362, 383, 383, 256, 256, 271,
+ 271, 287, 287, 304, 304, 322, 322, 256,
+ 256, 271, 271, 287, 287, 304, 304, 322,
+ 322, 341, 341, 362, 362, 256, 256, 271,
+ 271, 287, 287, 304, 304, 322, 322, 256,
+ 256, 271, 271, 287, 287, 304, 304, 322,
+ 322, 341, 341, 362, 362, 256, 256, 271,
+ 271, 287, 287, 304, 304, 322, 322, 341,
+ 341, 362, 362, 383, 383, 406, 406, 430,
+ 430, 455, 455, 482, 482, 511, 511, 541,
+ 541, 573, 573, 607, 607, 643, 643, 681,
+ 681, 722, 722, 764, 764, 810, 810, 858,
+ 858, 908, 908, 962, 962, 1019, 1019, 256
+};
+
+static uint32 nphy_tpc_txgain_ipa[] = {
+ 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
+ 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
+ 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
+ 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
+ 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
+ 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
+ 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
+ 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
+ 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
+ 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
+ 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
+ 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
+ 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
+ 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
+ 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
+ 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
+ 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
+ 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
+ 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
+ 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
+ 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
+ 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
+ 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
+ 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
+ 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
+ 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
+ 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
+ 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
+ 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
+ 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
+ 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
+ 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
+};
+
+static uint32 nphy_tpc_txgain_ipa_rev5[] = {
+ 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
+ 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
+ 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
+ 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
+ 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
+ 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
+ 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
+ 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
+ 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
+ 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
+ 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
+ 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
+ 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
+ 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
+ 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
+ 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
+ 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
+ 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
+ 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
+ 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
+ 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
+ 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
+ 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
+ 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
+ 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
+ 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
+ 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
+ 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
+ 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
+ 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
+ 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
+ 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
+};
+
+static uint32 nphy_tpc_txgain_ipa_rev6[] = {
+ 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
+ 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
+ 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
+ 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
+ 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
+ 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
+ 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
+ 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
+ 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
+ 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
+ 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
+ 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
+ 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
+ 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
+ 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
+ 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
+ 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
+ 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
+ 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
+ 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
+ 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
+ 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
+ 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
+ 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
+ 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
+ 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
+ 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
+ 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
+ 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
+ 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
+ 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
+ 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
+};
+
+static uint32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
+ 0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
+ 0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
+ 0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
+ 0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
+ 0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
+ 0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
+ 0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
+ 0x70470028, 0x70470026, 0x70470024, 0x70470022,
+ 0x7047001f, 0x70370027, 0x70370024, 0x70370022,
+ 0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
+ 0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
+ 0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
+ 0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
+ 0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
+ 0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
+ 0x70170019, 0x70170018, 0x70170016, 0x70170015,
+ 0x70170014, 0x70170013, 0x70170012, 0x70170010,
+ 0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
+ 0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
+ 0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
+ 0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
+ 0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
+ 0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
+ 0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
+ 0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
+ 0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
+ 0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
+ 0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
+ 0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
+ 0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
+ 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
+ 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
+};
+
+static uint32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
+ 0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
+ 0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
+ 0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
+ 0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
+ 0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
+ 0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
+ 0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
+ 0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
+ 0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
+ 0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
+ 0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
+ 0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
+ 0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
+ 0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
+ 0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
+ 0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
+ 0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
+ 0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
+ 0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
+ 0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
+ 0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
+ 0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
+ 0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
+ 0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
+ 0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
+ 0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
+ 0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
+ 0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
+ 0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
+ 0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
+ 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
+ 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
+};
+
+static uint32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
+ 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+ 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+ 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+ 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+ 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+ 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+ 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+ 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+ 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+ 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+ 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+ 0x30170028, 0x30170026, 0x30170024, 0x30170022,
+ 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+ 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+ 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+ 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+ 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+ 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+ 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+};
+
+static uint32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
+ 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+ 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+ 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+ 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+ 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+ 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+ 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+ 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+ 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+ 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+ 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+ 0x30170028, 0x30170026, 0x30170024, 0x30170022,
+ 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+ 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+ 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+ 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+ 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+ 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+ 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+};
+
+static uint32 nphy_tpc_txgain_ipa_5g[] = {
+ 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
+ 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
+ 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
+ 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
+ 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
+ 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
+ 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
+ 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
+ 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
+ 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
+ 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
+ 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
+ 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
+ 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
+ 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
+ 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
+ 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
+ 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
+ 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
+ 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
+ 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
+ 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
+ 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
+ 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
+ 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
+ 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
+ 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
+ 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
+ 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
+ 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
+ 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
+ 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
+};
+
+static uint32 nphy_tpc_txgain_ipa_5g_2057[] = {
+ 0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
+ 0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
+ 0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
+ 0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
+ 0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
+ 0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
+ 0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
+ 0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
+ 0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
+ 0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
+ 0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
+ 0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
+ 0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
+ 0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
+ 0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
+ 0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
+ 0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
+ 0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
+ 0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
+ 0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
+ 0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
+ 0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
+ 0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
+ 0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
+ 0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
+ 0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
+ 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
+ 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
+ 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+ 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+ 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
+ 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
+};
+
+static uint32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
+ 0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
+ 0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
+ 0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
+ 0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
+ 0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
+ 0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
+ 0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
+ 0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
+ 0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
+ 0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
+ 0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
+ 0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
+ 0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
+ 0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
+ 0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
+ 0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
+ 0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
+ 0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
+ 0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
+ 0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
+ 0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
+ 0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
+ 0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
+ 0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
+ 0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
+ 0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
+ 0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
+ 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+ 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+ 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+ 0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
+ 0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
+};
+
+static int8 nphy_papd_pga_gain_delta_ipa_2g[] = {
+ -114, -108, -98, -91, -84, -78, -70, -62,
+ -54, -46, -39, -31, -23, -15, -8, 0
+};
+
+static int8 nphy_papd_pga_gain_delta_ipa_5g[] = {
+ -100, -95, -89, -83, -77, -70, -63, -56,
+ -48, -41, -33, -25, -19, -12, -6, 0
+};
+
+static int16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
+ -159, -113, -86, -72, -62, -54, -48, -43,
+ -39, -35, -31, -28, -25, -23, -20, -18,
+ -17, -15, -13, -11, -10, -8, -7, -6,
+ -5, -4, -3, -3, -2, -1, -1, 0
+};
+
+static int16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
+ -109, -109, -82, -68, -58, -50, -44, -39,
+ -35, -31, -28, -26, -23, -21, -19, -17,
+ -16, -14, -13, -11, -10, -9, -8, -7,
+ -5, -5, -4, -3, -2, -1, -1, 0
+};
+
+static int16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
+ -122, -122, -95, -80, -69, -61, -54, -49,
+ -43, -39, -35, -32, -28, -26, -23, -21,
+ -18, -16, -15, -13, -11, -10, -8, -7,
+ -6, -5, -4, -3, -2, -1, -1, 0
+};
+
+static int8 nphy_papd_pgagain_dlt_5g_2057[] = {
+ -107, -101, -92, -85, -78, -71, -62, -55,
+ -47, -39, -32, -24, -19, -12, -6, 0
+};
+
+static int8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
+ -110, -104, -95, -88, -81, -74, -66, -58,
+ -50, -44, -36, -28, -23, -15, -8, 0
+};
+
+static uint8 pad_gain_codes_used_2057rev5[] = {
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
+};
+
+static uint8 pad_gain_codes_used_2057rev7[] = {
+ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+ 5, 4, 3, 2, 1
+};
+
+static uint8 pad_all_gain_codes_2057[] = {
+ 31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
+ 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
+ 1, 0
+};
+
+static uint8 pga_all_gain_codes_2057[] = {
+ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+};
+
+static uint32 nphy_papd_scaltbl[] = {
+ 0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
+ 0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
+ 0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
+ 0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
+ 0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
+ 0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
+ 0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
+ 0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
+ 0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
+ 0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
+ 0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
+ 0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
+ 0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
+ 0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
+ 0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
+ 0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
+};
+
+static uint32 nphy_tpc_txgain_rev3[] = {
+ 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
+ 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
+ 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
+ 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
+ 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
+ 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
+ 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
+ 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
+ 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
+ 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
+ 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
+ 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
+ 0x19410044, 0x19410042, 0x19410040, 0x1941003e,
+ 0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
+ 0x18410044, 0x18410042, 0x18410040, 0x1841003e,
+ 0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
+ 0x17410044, 0x17410042, 0x17410040, 0x1741003e,
+ 0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
+ 0x16410044, 0x16410042, 0x16410040, 0x1641003e,
+ 0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
+ 0x15410044, 0x15410042, 0x15410040, 0x1541003e,
+ 0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
+ 0x14410044, 0x14410042, 0x14410040, 0x1441003e,
+ 0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
+ 0x13410044, 0x13410042, 0x13410040, 0x1341003e,
+ 0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
+ 0x12410044, 0x12410042, 0x12410040, 0x1241003e,
+ 0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
+ 0x11410044, 0x11410042, 0x11410040, 0x1141003e,
+ 0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
+ 0x10410044, 0x10410042, 0x10410040, 0x1041003e,
+ 0x1041003c, 0x1041003b, 0x10410039, 0x10410037
+};
+
+static uint32 nphy_tpc_txgain_HiPwrEPA[] = {
+ 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
+ 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
+ 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
+ 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
+ 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
+ 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
+ 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
+ 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
+ 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
+ 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
+ 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
+ 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
+ 0x09410044, 0x09410042, 0x09410040, 0x0941003e,
+ 0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
+ 0x08410044, 0x08410042, 0x08410040, 0x0841003e,
+ 0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
+ 0x07410044, 0x07410042, 0x07410040, 0x0741003e,
+ 0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
+ 0x06410044, 0x06410042, 0x06410040, 0x0641003e,
+ 0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
+ 0x05410044, 0x05410042, 0x05410040, 0x0541003e,
+ 0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
+ 0x04410044, 0x04410042, 0x04410040, 0x0441003e,
+ 0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
+ 0x03410044, 0x03410042, 0x03410040, 0x0341003e,
+ 0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
+ 0x02410044, 0x02410042, 0x02410040, 0x0241003e,
+ 0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
+ 0x01410044, 0x01410042, 0x01410040, 0x0141003e,
+ 0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
+ 0x00410044, 0x00410042, 0x00410040, 0x0041003e,
+ 0x0041003c, 0x0041003b, 0x00410039, 0x00410037
+};
+
+static uint32 nphy_tpc_txgain_epa_2057rev3[] = {
+ 0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
+ 0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
+ 0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
+ 0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
+ 0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
+ 0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
+ 0x80390038, 0x80390035, 0x8031003a, 0x80310036,
+ 0x80310033, 0x8029003a, 0x80290037, 0x80290034,
+ 0x80290031, 0x80210039, 0x80210036, 0x80210033,
+ 0x80210030, 0x8019003c, 0x80190039, 0x80190036,
+ 0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
+ 0x80190028, 0x8011003a, 0x80110036, 0x80110033,
+ 0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
+ 0x80110027, 0x80110024, 0x80110022, 0x80110020,
+ 0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
+ 0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
+ 0x80090029, 0x80090027, 0x80090025, 0x80090023,
+ 0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
+ 0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
+ 0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+ 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
+};
+
+static uint32 nphy_tpc_txgain_epa_2057rev5[] = {
+ 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
+ 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
+ 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
+ 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
+ 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
+ 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
+ 0x10390038, 0x10390035, 0x1031003a, 0x10310036,
+ 0x10310033, 0x1029003a, 0x10290037, 0x10290034,
+ 0x10290031, 0x10210039, 0x10210036, 0x10210033,
+ 0x10210030, 0x1019003c, 0x10190039, 0x10190036,
+ 0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
+ 0x10190028, 0x1011003a, 0x10110036, 0x10110033,
+ 0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
+ 0x10110027, 0x10110024, 0x10110022, 0x10110020,
+ 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
+ 0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
+ 0x10090029, 0x10090027, 0x10090025, 0x10090023,
+ 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
+ 0x1009001a, 0x10090018, 0x10090017, 0x10090016,
+ 0x10090015, 0x10090013, 0x10090012, 0x10090011,
+ 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
+ 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
+ 0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
+ 0x10090008, 0x10090008, 0x10090007, 0x10090007,
+ 0x10090007, 0x10090006, 0x10090006, 0x10090005,
+ 0x10090005, 0x10090005, 0x10090005, 0x10090004,
+ 0x10090004, 0x10090004, 0x10090004, 0x10090003,
+ 0x10090003, 0x10090003, 0x10090003, 0x10090003,
+ 0x10090003, 0x10090002, 0x10090002, 0x10090002,
+ 0x10090002, 0x10090002, 0x10090002, 0x10090002,
+ 0x10090002, 0x10090002, 0x10090001, 0x10090001,
+ 0x10090001, 0x10090001, 0x10090001, 0x10090001
+};
+
+static uint32 nphy_tpc_5GHz_txgain_rev3[] = {
+ 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
+ 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
+ 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
+ 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
+ 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
+ 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
+ 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
+ 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
+ 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
+ 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
+ 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
+ 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
+ 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
+ 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
+ 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
+ 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
+ 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
+ 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
+ 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
+ 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
+ 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
+ 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
+ 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
+ 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
+ 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
+ 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
+ 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
+ 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
+ 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
+ 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
+ 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
+ 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
+};
+
+static uint32 nphy_tpc_5GHz_txgain_rev4[] = {
+ 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
+ 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
+ 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
+ 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
+ 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
+ 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
+ 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
+ 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
+ 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
+ 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
+ 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
+ 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
+ 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
+ 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
+ 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
+ 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
+ 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
+ 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
+ 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
+ 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
+ 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
+ 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
+ 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
+ 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
+ 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
+ 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
+ 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
+ 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
+ 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
+ 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
+ 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
+ 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
+};
+
+static uint32 nphy_tpc_5GHz_txgain_rev5[] = {
+ 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
+ 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
+ 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
+ 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
+ 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
+ 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
+ 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
+ 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
+ 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
+ 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
+ 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
+ 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
+ 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
+ 0x09620039, 0x09620037, 0x09620035, 0x09620033,
+ 0x08620044, 0x08620042, 0x08620040, 0x0862003e,
+ 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
+ 0x07620043, 0x07620042, 0x07620040, 0x0762003f,
+ 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
+ 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
+ 0x06620039, 0x06620037, 0x06620035, 0x06620033,
+ 0x05620046, 0x05620044, 0x05620042, 0x05620040,
+ 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
+ 0x04620044, 0x04620042, 0x04620040, 0x0462003e,
+ 0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
+ 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
+ 0x03620038, 0x03620037, 0x03620035, 0x03620033,
+ 0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
+ 0x02620046, 0x02620044, 0x02620043, 0x02620042,
+ 0x0162004a, 0x01620048, 0x01620046, 0x01620044,
+ 0x01620043, 0x01620042, 0x01620041, 0x01620040,
+ 0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
+ 0x0062003b, 0x00620039, 0x00620037, 0x00620035
+};
+
+static uint32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
+ 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
+ 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
+ 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
+ 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
+ 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
+ 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
+ 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
+ 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
+ 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
+ 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
+ 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
+ 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
+ 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
+ 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
+ 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
+ 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
+ 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
+ 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
+ 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
+ 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
+ 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
+ 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
+ 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
+ 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
+ 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
+ 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
+ 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
+ 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
+ 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
+ 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
+ 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
+ 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
+};
+
+static uint8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
+static uint8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
+static uint8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
+ 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a };
+static uint8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
+ 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 };
+
+static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+ chan_info_nphy_radio2057_t **t0,
+ chan_info_nphy_radio205x_t **t1,
+ chan_info_nphy_radio2057_rev5_t **t2,
+ chan_info_nphy_2055_t **t3);
+static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans,
+ const nphy_sfo_cfg_t *c);
+
+static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi,
+ uint16 reduction_factr);
+static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *,
+ uint32 *buf);
+static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, uint8 minpwr);
+static void wlc_phy_txlpfbw_nphy(phy_info_t *pi);
+static void wlc_phy_spurwar_nphy(phy_info_t *pi);
+
+static void wlc_phy_radio_preinit_2055(phy_info_t *pi);
+static void wlc_phy_radio_init_2055(phy_info_t *pi);
+static void wlc_phy_radio_postinit_2055(phy_info_t *pi);
+static void wlc_phy_radio_preinit_205x(phy_info_t *pi);
+static void wlc_phy_radio_init_2056(phy_info_t *pi);
+static void wlc_phy_radio_postinit_2056(phy_info_t *pi);
+static void wlc_phy_radio_init_2057(phy_info_t *pi);
+static void wlc_phy_radio_postinit_2057(phy_info_t *pi);
+static void wlc_phy_workarounds_nphy(phy_info_t *pi);
+static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi);
+static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi);
+static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi);
+static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi);
+
+static void wlc_phy_restore_rssical_nphy(phy_info_t *pi);
+static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi);
+static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi);
+static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg,
+ uint8 type, bool d);
+static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, uint8 rxcore,
+ uint16 *rg, uint8 type);
+static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, int32 preamble);
+static void wlc_phy_savecal_nphy(phy_info_t *pi);
+static void wlc_phy_restorecal_nphy(phy_info_t *pi);
+static void wlc_phy_resetcca_nphy(phy_info_t *pi);
+
+static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi);
+static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi);
+static void wlc_phy_precal_txgain_nphy(phy_info_t *pi);
+static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, uint16 core);
+
+static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi);
+static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi);
+static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi);
+static uint16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi);
+static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, uint8 m0, uint8 m1);
+static uint32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi);
+
+static void wlc_phy_a1_nphy(phy_info_t *pi, uint8 core, uint32 winsz, uint32,
+ uint32 e);
+static uint8 wlc_phy_a3_nphy(phy_info_t *pi, uint8 start_gain, uint8 core);
+static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *,
+ phy_cal_mode_t, uint8);
+static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi,
+ nphy_papd_restore_state *state);
+static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi,
+ nphy_papd_restore_state *state, uint8);
+
+static void wlc_phy_clip_det_nphy(phy_info_t *pi, uint8 write, uint16 *vals);
+
+static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, uint8 cmd, uint8 *evts,
+ uint8 *dlys, uint8 len);
+
+static uint16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, uint16 offset);
+
+static void
+wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, uint16 field, uint16 value,
+ uint8 core_mask, uint8 off,
+ uint8 override_id);
+
+static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, uint8 rssi_type);
+static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi);
+
+static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi);
+static void wlc_phy_txpwr_nphy_srom_convert(uint8 *srom_max,
+ uint16 *pwr_offset,
+ uint8 tmp_max_pwr, uint8 rate_start,
+ uint8 rate_end);
+
+static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi);
+static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi);
+static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi);
+static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi);
+
+static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi);
+static uint8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, uint8 core);
+static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, uint8 idx0,
+ uint8 idx1);
+static void wlc_phy_a4(phy_info_t *pi, bool full_cal);
+
+static uint16 wlc_phy_radio205x_rcal(phy_info_t *pi);
+
+static uint16 wlc_phy_radio2057_rccal(phy_info_t *pi);
+
+static uint16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, uint32 f_kHz,
+ uint16 max_val,
+ uint8 dac_test_mode);
+static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cint32 *tone_buf,
+ uint16 num_samps);
+static void wlc_phy_runsamples_nphy(phy_info_t *pi, uint16 n, uint16 lps,
+ uint16 wait, uint8 iq, uint8 dac_test_mode,
+ bool modify_bbmult);
+
+bool wlc_phy_bist_check_phy(wlc_phy_t *pih)
+{
+ phy_info_t *pi = (phy_info_t *) pih;
+ uint32 phybist0, phybist1, phybist2, phybist3, phybist4;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 16))
+ return TRUE;
+
+ phybist0 = read_phy_reg(pi, 0x0e);
+ phybist1 = read_phy_reg(pi, 0x0f);
+ phybist2 = read_phy_reg(pi, 0xea);
+ phybist3 = read_phy_reg(pi, 0xeb);
+ phybist4 = read_phy_reg(pi, 0x156);
+
+ if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
+ (phybist3 == 0) && (phybist4 == 0)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi)
+{
+ uint16 addr, val;
+
+ ASSERT(ISNPHY(pi));
+
+ val = 0x1e1f;
+ for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
+ addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
+ write_phy_reg(pi, addr, val);
+ if (addr == (NPHY_TO_BPHY_OFF + 0x97))
+ val = 0x3e3f;
+ else
+ val -= 0x0202;
+ }
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+
+ write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206);
+
+ write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e);
+
+ or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a);
+
+ } else {
+
+ write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
+ }
+}
+
+void
+wlc_phy_table_write_nphy(phy_info_t *pi, uint32 id, uint32 len, uint32 offset,
+ uint32 width, const void *data)
+{
+ mimophytbl_info_t tbl;
+
+ tbl.tbl_id = id;
+ tbl.tbl_len = len;
+ tbl.tbl_offset = offset;
+ tbl.tbl_width = width;
+ tbl.tbl_ptr = data;
+ wlc_phy_write_table_nphy(pi, &tbl);
+}
+
+void
+wlc_phy_table_read_nphy(phy_info_t *pi, uint32 id, uint32 len, uint32 offset,
+ uint32 width, void *data)
+{
+ mimophytbl_info_t tbl;
+
+ tbl.tbl_id = id;
+ tbl.tbl_len = len;
+ tbl.tbl_offset = offset;
+ tbl.tbl_width = width;
+ tbl.tbl_ptr = data;
+ wlc_phy_read_table_nphy(pi, &tbl);
+}
+
+static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi)
+{
+ uint idx;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 16)) {
+ for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev16[idx]);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev7[idx]);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3[idx]);
+ } else {
+ for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev0[idx]);
+ }
+}
+
+static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi)
+{
+ uint idx = 0;
+ uint8 antswctrllut;
+
+ if (pi->phy_init_por)
+ wlc_phy_static_table_download_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+ pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut;
+
+ switch (antswctrllut) {
+ case 0:
+
+ break;
+
+ case 1:
+
+ if (pi->aa2g == 7) {
+
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x21, 8,
+ &ant_sw_ctrl_tbl_rev8_2o3
+ [0]);
+ } else {
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x21, 8,
+ &ant_sw_ctrl_tbl_rev8
+ [0]);
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x25, 8,
+ &ant_sw_ctrl_tbl_rev8[2]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x29, 8,
+ &ant_sw_ctrl_tbl_rev8[4]);
+ break;
+
+ case 2:
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x1, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core0
+ [0]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x5, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core0
+ [2]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x9, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core0
+ [4]);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x21, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core1
+ [0]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x25, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core1
+ [2]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 2, 0x29, 8,
+ &ant_sw_ctrl_tbl_rev8_2057v7_core1
+ [4]);
+ break;
+
+ default:
+
+ ASSERT(0);
+ break;
+ }
+
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
+
+ if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
+ antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+ pi->srom_fem2g.antswctrllut : pi->
+ srom_fem5g.antswctrllut;
+ switch (antswctrllut) {
+ case 0:
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3_volatile
+ [idx]);
+ break;
+ case 1:
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3_volatile1
+ [idx]);
+ break;
+ case 2:
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3_volatile2
+ [idx]);
+ break;
+ case 3:
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3_volatile3
+ [idx]);
+ break;
+ default:
+
+ ASSERT(0);
+ break;
+ }
+ } else {
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev3_volatile
+ [idx]);
+ }
+ }
+ } else {
+ for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) {
+ wlc_phy_write_table_nphy(pi,
+ &mimophytbl_info_rev0_volatile
+ [idx]);
+ }
+ }
+}
+
+static void
+wlc_phy_write_txmacreg_nphy(phy_info_t *pi, uint16 holdoff, uint16 delay)
+{
+ write_phy_reg(pi, 0x77, holdoff);
+ write_phy_reg(pi, 0xb4, delay);
+}
+
+void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, uint8 rifs)
+{
+ uint16 holdoff, delay;
+
+ if (rifs) {
+
+ holdoff = 0x10;
+ delay = 0x258;
+ } else {
+
+ holdoff = 0x15;
+ delay = 0x320;
+ }
+
+ wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
+
+ if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) {
+ pi->sh->_rifs_phy = rifs;
+ }
+}
+
+bool wlc_phy_attach_nphy(phy_info_t *pi)
+{
+ uint i;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) {
+ pi->phyhang_avoid = TRUE;
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ pi->nphy_gband_spurwar_en = TRUE;
+
+ if (pi->sh->boardflags2 & BFL2_SPUR_WAR) {
+ pi->nphy_aband_spurwar_en = TRUE;
+ }
+ }
+ if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) {
+ pi->nphy_gband_spurwar2_en = TRUE;
+ }
+ }
+
+ pi->n_preamble_override = AUTO;
+ if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
+ pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE;
+
+ pi->nphy_txrx_chain = AUTO;
+ pi->phy_scraminit = AUTO;
+
+ pi->nphy_rxcalparams = 0x010100B5;
+
+ pi->nphy_perical = PHY_PERICAL_MPHASE;
+ pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+ pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
+
+ pi->nphy_gain_boost = TRUE;
+ pi->nphy_elna_gain_config = FALSE;
+ pi->radio_is_on = FALSE;
+
+ for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+ pi->nphy_txpwrindex[i].index = AUTO;
+ }
+
+ wlc_phy_txpwrctrl_config_nphy(pi);
+ if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+ pi->hwpwrctrl_capable = TRUE;
+
+ pi->pi_fptr.init = wlc_phy_init_nphy;
+ pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
+ pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
+ pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
+
+ if (!wlc_phy_txpwr_srom_read_nphy(pi))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void BCMATTACHFN(wlc_phy_txpwrctrl_config_nphy) (phy_info_t *pi)
+{
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+ pi->phy_5g_pwrgain = TRUE;
+ return;
+ }
+
+ pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
+ pi->phy_5g_pwrgain = FALSE;
+
+ if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
+ NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
+ pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+ else if ((pi->sh->sromrev >= 4)
+ && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
+ pi->phy_5g_pwrgain = TRUE;
+}
+
+void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi)
+{
+ uint16 val;
+ uint16 clip1_ths[2];
+ nphy_txgains_t target_gain;
+ uint8 tx_pwr_ctrl_state;
+ bool do_nphy_cal = FALSE;
+ uint core;
+ uint origidx, intr_val;
+ d11regs_t *regs;
+ uint32 d11_clk_ctl_st;
+
+ core = 0;
+
+ if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+ pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+ }
+
+ if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
+ ((pi->sh->chippkg == BCM4717_PKG_ID) ||
+ (pi->sh->chippkg == BCM4718_PKG_ID))) {
+ if ((pi->sh->boardflags & BFL_EXTLNA) &&
+ (CHSPEC_IS2G(pi->radio_chanspec))) {
+ si_corereg(pi->sh->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol), 0x40,
+ 0x40);
+ }
+ }
+
+ if ((!PHY_IPA(pi)) && (CHIPID(pi->sh->chip) == BCM5357_CHIP_ID)) {
+ si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA,
+ CCTRL5357_EXTPA);
+ }
+
+ if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
+ CHSPEC_IS40(pi->radio_chanspec)) {
+
+ regs = (d11regs_t *) si_switch_core(pi->sh->sih, D11_CORE_ID,
+ &origidx, &intr_val);
+ ASSERT(regs != NULL);
+
+ d11_clk_ctl_st = R_REG(pi->sh->osh, &regs->clk_ctl_st);
+ AND_REG(pi->sh->osh, &regs->clk_ctl_st,
+ ~(CCS_FORCEHT | CCS_HTAREQ));
+
+ W_REG(pi->sh->osh, &regs->clk_ctl_st, d11_clk_ctl_st);
+
+ si_restore_core(pi->sh->sih, origidx, intr_val);
+ }
+
+ pi->use_int_tx_iqlo_cal_nphy =
+ (PHY_IPA(pi) ||
+ (NREV_GE(pi->pubpi.phy_rev, 7) ||
+ (NREV_GE(pi->pubpi.phy_rev, 5)
+ && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
+
+ pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = FALSE;
+
+ pi->nphy_deaf_count = 0;
+
+ wlc_phy_tbl_init_nphy(pi);
+
+ pi->nphy_crsminpwr_adjusted = FALSE;
+ pi->nphy_noisevars_adjusted = FALSE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0xe7, 0);
+ write_phy_reg(pi, 0xec, 0);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_phy_reg(pi, 0x342, 0);
+ write_phy_reg(pi, 0x343, 0);
+ write_phy_reg(pi, 0x346, 0);
+ write_phy_reg(pi, 0x347, 0);
+ }
+ write_phy_reg(pi, 0xe5, 0);
+ write_phy_reg(pi, 0xe6, 0);
+ } else {
+ write_phy_reg(pi, 0xec, 0);
+ }
+
+ write_phy_reg(pi, 0x91, 0);
+ write_phy_reg(pi, 0x92, 0);
+ if (NREV_LT(pi->pubpi.phy_rev, 6)) {
+ write_phy_reg(pi, 0x93, 0);
+ write_phy_reg(pi, 0x94, 0);
+ }
+
+ and_phy_reg(pi, 0xa1, ~3);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0x8f, 0);
+ write_phy_reg(pi, 0xa5, 0);
+ } else {
+ write_phy_reg(pi, 0xa5, 0);
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+ else if (NREV_LT(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+
+ write_phy_reg(pi, 0x203, 32);
+ write_phy_reg(pi, 0x201, 32);
+
+ if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
+ write_phy_reg(pi, 0x20d, 160);
+ else
+ write_phy_reg(pi, 0x20d, 184);
+
+ write_phy_reg(pi, 0x13a, 200);
+
+ write_phy_reg(pi, 0x70, 80);
+
+ write_phy_reg(pi, 0x1ff, 48);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
+ }
+
+ wlc_phy_stf_chain_upd_nphy(pi);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ write_phy_reg(pi, 0x180, 0xaa8);
+ write_phy_reg(pi, 0x181, 0x9a4);
+ }
+
+ if (PHY_IPA(pi)) {
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
+ 0x29c, (0x1ff << 7),
+ (pi->nphy_papd_epsilon_offset[core]) << 7);
+
+ }
+
+ wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+ } else {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+ wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
+ }
+ }
+
+ wlc_phy_workarounds_nphy(pi);
+
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+
+ val = read_phy_reg(pi, 0x01);
+ write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+ write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+
+ wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
+
+ wlc_phy_pa_override_nphy(pi, OFF);
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+ wlc_phy_pa_override_nphy(pi, ON);
+
+ wlc_phy_classifier_nphy(pi, 0, 0);
+ wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec))
+ wlc_phy_bphy_init_nphy(pi);
+
+ tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+ wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+
+ wlc_phy_txpwr_fixpower_nphy(pi);
+
+ wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+
+ wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ uint32 *tx_pwrctrl_tbl = NULL;
+ uint16 idx;
+ int16 pga_gn = 0;
+ int16 pad_gn = 0;
+ int32 rfpwr_offset = 0;
+
+ if (PHY_IPA(pi)) {
+ tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if NREV_IS
+ (pi->pubpi.phy_rev, 3) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_5GHz_txgain_rev3;
+ } else if NREV_IS
+ (pi->pubpi.phy_rev, 4) {
+ tx_pwrctrl_tbl =
+ (pi->srom_fem5g.extpagain == 3) ?
+ nphy_tpc_5GHz_txgain_HiPwrEPA :
+ nphy_tpc_5GHz_txgain_rev4;
+ } else {
+ tx_pwrctrl_tbl =
+ nphy_tpc_5GHz_txgain_rev5;
+ }
+
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (pi->pubpi.radiorev == 5) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_epa_2057rev5;
+ } else if (pi->pubpi.radiorev == 3) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_epa_2057rev3;
+ }
+
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+ (pi->srom_fem2g.extpagain == 3)) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_HiPwrEPA;
+ } else {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_rev3;
+ }
+ }
+ }
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+ 192, 32, tx_pwrctrl_tbl);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+ 192, 32, tx_pwrctrl_tbl);
+
+ pi->nphy_gmval = (uint16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ for (idx = 0; idx < 128; idx++) {
+ pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+ pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+ rfpwr_offset = (int16)
+ nphy_papd_padgain_dlt_2g_2057rev3n4
+ [pad_gn];
+ } else if (pi->pubpi.radiorev == 5) {
+ rfpwr_offset = (int16)
+ nphy_papd_padgain_dlt_2g_2057rev5
+ [pad_gn];
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev ==
+ 8)) {
+ rfpwr_offset = (int16)
+ nphy_papd_padgain_dlt_2g_2057rev7
+ [pad_gn];
+ } else {
+ ASSERT(0);
+ }
+
+ } else {
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+ rfpwr_offset = (int16)
+ nphy_papd_pgagain_dlt_5g_2057
+ [pga_gn];
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev ==
+ 8)) {
+ rfpwr_offset = (int16)
+ nphy_papd_pgagain_dlt_5g_2057rev7
+ [pga_gn];
+ } else {
+ ASSERT(0);
+ }
+ }
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_CORE1TXPWRCTL,
+ 1, 576 + idx, 32,
+ &rfpwr_offset);
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_CORE2TXPWRCTL,
+ 1, 576 + idx, 32,
+ &rfpwr_offset);
+ }
+ } else {
+
+ for (idx = 0; idx < 128; idx++) {
+ pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ rfpwr_offset = (int16)
+ nphy_papd_pga_gain_delta_ipa_2g
+ [pga_gn];
+ } else {
+ rfpwr_offset = (int16)
+ nphy_papd_pga_gain_delta_ipa_5g
+ [pga_gn];
+ }
+
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_CORE1TXPWRCTL,
+ 1, 576 + idx, 32,
+ &rfpwr_offset);
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_CORE2TXPWRCTL,
+ 1, 576 + idx, 32,
+ &rfpwr_offset);
+ }
+
+ }
+ } else {
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+ 192, 32, nphy_tpc_txgain);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+ 192, 32, nphy_tpc_txgain);
+ }
+
+ if (pi->sh->phyrxchain != 0x3) {
+ wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi,
+ pi->sh->phyrxchain);
+ }
+
+ if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+ wlc_phy_cal_perical_mphase_restart(pi);
+ }
+
+ if (!NORADIO_ENAB(pi->pubpi)) {
+ bool do_rssi_cal = FALSE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+ (pi->nphy_rssical_chanspec_2G == 0) :
+ (pi->nphy_rssical_chanspec_5G == 0);
+
+ if (do_rssi_cal) {
+ wlc_phy_rssi_cal_nphy(pi);
+ } else {
+ wlc_phy_restore_rssical_nphy(pi);
+ }
+ } else {
+ wlc_phy_rssi_cal_nphy(pi);
+ }
+
+ if (!SCAN_RM_IN_PROGRESS(pi)) {
+ do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+ (pi->nphy_iqcal_chanspec_2G == 0) :
+ (pi->nphy_iqcal_chanspec_5G == 0);
+ }
+
+ if (!pi->do_initcal)
+ do_nphy_cal = FALSE;
+
+ if (do_nphy_cal) {
+
+ target_gain = wlc_phy_get_tx_gain_nphy(pi);
+
+ if (pi->antsel_type == ANTSEL_2x3)
+ wlc_phy_antsel_init((wlc_phy_t *) pi, TRUE);
+
+ if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
+ wlc_phy_rssi_cal_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ pi->nphy_cal_orig_pwr_idx[0] =
+ pi->nphy_txpwrindex[PHY_CORE_0].
+ index_internal;
+ pi->nphy_cal_orig_pwr_idx[1] =
+ pi->nphy_txpwrindex[PHY_CORE_1].
+ index_internal;
+
+ wlc_phy_precal_txgain_nphy(pi);
+ target_gain =
+ wlc_phy_get_tx_gain_nphy(pi);
+ }
+
+ if (wlc_phy_cal_txiqlo_nphy
+ (pi, target_gain, TRUE, FALSE) == BCME_OK) {
+ if (wlc_phy_cal_rxiq_nphy
+ (pi, target_gain, 2,
+ FALSE) == BCME_OK) {
+ wlc_phy_savecal_nphy(pi);
+
+ }
+ }
+ } else if (pi->mphase_cal_phase_id ==
+ MPHASE_CAL_STATE_IDLE) {
+
+ wlc_phy_cal_perical((wlc_phy_t *) pi,
+ PHY_PERICAL_PHYINIT);
+ }
+ } else {
+ wlc_phy_restorecal_nphy(pi);
+ }
+ }
+
+ wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+
+ wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
+
+ write_phy_reg(pi, 0x70, 50);
+
+ wlc_phy_txlpfbw_nphy(pi);
+
+ wlc_phy_spurwar_nphy(pi);
+
+}
+
+static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, int32 preamble)
+{
+ bool gf_preamble = FALSE;
+ uint16 val;
+
+ if (preamble == WLC_N_PREAMBLE_GF) {
+ gf_preamble = TRUE;
+ }
+
+ val = read_phy_reg(pi, 0xed);
+
+ val |= RX_GF_MM_AUTO;
+ val &= ~RX_GF_OR_MM;
+ if (gf_preamble)
+ val |= RX_GF_OR_MM;
+
+ write_phy_reg(pi, 0xed, val);
+}
+
+static void wlc_phy_resetcca_nphy(phy_info_t *pi)
+{
+ uint16 val;
+
+ ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+
+ val = read_phy_reg(pi, 0x01);
+ write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+ OSL_DELAY(1);
+ write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+}
+
+void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en)
+{
+ uint16 rfctrlintc_override_val;
+
+ if (!en) {
+
+ pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
+ pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ rfctrlintc_override_val = 0x1480;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ rfctrlintc_override_val =
+ CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
+ } else {
+ rfctrlintc_override_val =
+ CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+ }
+
+ write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+ write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+ } else {
+
+ write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
+ write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
+ }
+
+}
+
+void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi)
+{
+
+ uint16 txrx_chain =
+ (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
+ bool CoreActv_override = FALSE;
+
+ if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) {
+ txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
+ CoreActv_override = TRUE;
+
+ if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+ and_phy_reg(pi, 0xa0, ~0x20);
+ }
+ } else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) {
+ txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
+ CoreActv_override = TRUE;
+
+ if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+ or_phy_reg(pi, 0xa0, 0x20);
+ }
+ }
+
+ mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
+
+ if (CoreActv_override) {
+
+ pi->nphy_perical = PHY_PERICAL_DISABLE;
+ or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+ } else {
+ pi->nphy_perical = PHY_PERICAL_MPHASE;
+ and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
+ }
+}
+
+void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, uint8 rxcore_bitmask)
+{
+ uint16 regval;
+ uint16 tbl_buf[16];
+ uint i;
+ phy_info_t *pi = (phy_info_t *) pih;
+ uint16 tbl_opcode;
+ bool suspend;
+
+ pi->sh->phyrxchain = rxcore_bitmask;
+
+ if (!pi->sh->clk)
+ return;
+
+ suspend =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!suspend)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ regval = read_phy_reg(pi, 0xa2);
+ regval &= ~(0xf << 4);
+ regval |= ((uint16) (rxcore_bitmask & 0x3)) << 4;
+ write_phy_reg(pi, 0xa2, regval);
+
+ if ((rxcore_bitmask & 0x3) != 0x3) {
+
+ write_phy_reg(pi, 0x20e, 1);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (pi->rx2tx_biasentry == -1) {
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ ARRAYSIZE(tbl_buf), 80,
+ 16, tbl_buf);
+
+ for (i = 0; i < ARRAYSIZE(tbl_buf); i++) {
+ if (tbl_buf[i] ==
+ NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
+
+ pi->rx2tx_biasentry = (uint8) i;
+ tbl_opcode =
+ NPHY_REV3_RFSEQ_CMD_NOP;
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_RFSEQ,
+ 1, i,
+ 16,
+ &tbl_opcode);
+ break;
+ } else if (tbl_buf[i] ==
+ NPHY_REV3_RFSEQ_CMD_END) {
+ break;
+ }
+ }
+ }
+ }
+ } else {
+
+ write_phy_reg(pi, 0x20e, 30);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (pi->rx2tx_biasentry != -1) {
+ tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1, pi->rx2tx_biasentry,
+ 16, &tbl_opcode);
+ pi->rx2tx_biasentry = -1;
+ }
+ }
+ }
+
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ if (!suspend)
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+uint8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih)
+{
+ uint16 regval, rxen_bits;
+ phy_info_t *pi = (phy_info_t *) pih;
+
+ regval = read_phy_reg(pi, 0xa2);
+ rxen_bits = (regval >> 4) & 0xf;
+
+ return (uint8) rxen_bits;
+}
+
+bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi)
+{
+ return PHY_IPA(pi);
+}
+
+static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi)
+{
+ uint8 idx, idx2, i, delta_ind;
+
+ for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) {
+ pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
+ }
+
+ for (i = 0; i < 4; i++) {
+ idx2 = 0;
+
+ delta_ind = 0;
+
+ switch (i) {
+ case 0:
+
+ if (CHSPEC_IS40(pi->radio_chanspec)
+ && NPHY_IS_SROM_REINTERPRET) {
+ idx = TXP_FIRST_MCS_40_SISO;
+ } else {
+ idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+ TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
+ delta_ind = 1;
+ }
+ break;
+
+ case 1:
+
+ idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+ TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
+ break;
+
+ case 2:
+
+ idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+ TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
+ break;
+
+ case 3:
+
+ idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+ TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
+ break;
+ }
+
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ idx = idx + delta_ind;
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx++];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ idx = idx + 1 - delta_ind;
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+ pi->tx_power_offset[idx];
+ }
+}
+
+void wlc_phy_cal_init_nphy(phy_info_t *pi)
+{
+}
+
+static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, uint8 core)
+{
+ if (core == PHY_CORE_0) {
+ write_phy_reg(pi, 0x38, 0x4);
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_phy_reg(pi, 0x37, 0x0060);
+ } else {
+ write_phy_reg(pi, 0x37, 0x1080);
+ }
+ } else if (core == PHY_CORE_1) {
+ write_phy_reg(pi, 0x2ae, 0x4);
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_phy_reg(pi, 0x2ad, 0x0060);
+ } else {
+ write_phy_reg(pi, 0x2ad, 0x1080);
+ }
+ }
+}
+
+static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, uint8 txchain)
+{
+ uint8 txchain0, txchain1;
+
+ txchain0 = txchain & 0x1;
+ txchain1 = (txchain & 0x2) >> 1;
+ if (!txchain0) {
+ wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+ }
+
+ if (!txchain1) {
+ wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+ }
+}
+
+static void wlc_phy_workarounds_nphy(phy_info_t *pi)
+{
+ uint8 rfseq_rx2tx_events[] = {
+ NPHY_RFSEQ_CMD_NOP,
+ NPHY_RFSEQ_CMD_RXG_FBW,
+ NPHY_RFSEQ_CMD_TR_SWITCH,
+ NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+ NPHY_RFSEQ_CMD_RXPD_TXPD,
+ NPHY_RFSEQ_CMD_TX_GAIN,
+ NPHY_RFSEQ_CMD_EXT_PA
+ };
+ uint8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
+ uint8 rfseq_tx2rx_events[] = {
+ NPHY_RFSEQ_CMD_NOP,
+ NPHY_RFSEQ_CMD_EXT_PA,
+ NPHY_RFSEQ_CMD_TX_GAIN,
+ NPHY_RFSEQ_CMD_RXPD_TXPD,
+ NPHY_RFSEQ_CMD_TR_SWITCH,
+ NPHY_RFSEQ_CMD_RXG_FBW,
+ NPHY_RFSEQ_CMD_CLR_HIQ_DIS
+ };
+ uint8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+ uint8 rfseq_tx2rx_events_rev3[] = {
+ NPHY_REV3_RFSEQ_CMD_EXT_PA,
+ NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+ NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+ NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+ NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+ NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+ NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+ NPHY_REV3_RFSEQ_CMD_END
+ };
+ uint8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+ uint8 rfseq_rx2tx_events_rev3[] = {
+ NPHY_REV3_RFSEQ_CMD_NOP,
+ NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+ NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+ NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+ NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+ NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+ NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+ NPHY_REV3_RFSEQ_CMD_EXT_PA,
+ NPHY_REV3_RFSEQ_CMD_END
+ };
+ uint8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
+
+ uint8 rfseq_rx2tx_events_rev3_ipa[] = {
+ NPHY_REV3_RFSEQ_CMD_NOP,
+ NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+ NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+ NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+ NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+ NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+ NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
+ NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+ NPHY_REV3_RFSEQ_CMD_END
+ };
+ uint8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+ uint16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
+
+ int16 alpha0, alpha1, alpha2;
+ int16 beta0, beta1, beta2;
+ uint32 leg_data_weights, ht_data_weights, nss1_data_weights,
+ stbc_data_weights;
+ uint8 chan_freq_range = 0;
+ uint16 dac_control = 0x0002;
+ uint16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
+ uint16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
+ uint16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+ uint16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+ uint16 *aux_adc_vmid;
+ uint16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
+ uint16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
+ uint16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
+ uint16 *aux_adc_gain;
+ uint16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+ uint16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+ int32 min_nvar_val = 0x18d;
+ int32 min_nvar_offset_6mbps = 20;
+ uint8 pdetrange;
+ uint8 triso;
+ uint16 regval;
+ uint16 afectrl_adc_ctrl1_rev7 = 0x20;
+ uint16 afectrl_adc_ctrl2_rev7 = 0x0;
+ uint16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
+ uint16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
+ uint16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
+ uint16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
+ uint16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+ uint16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+ uint16 ipalvlshift_3p3_war_en = 0;
+ uint16 rccal_bcap_val, rccal_scap_val;
+ uint16 rccal_tx20_11b_bcap = 0;
+ uint16 rccal_tx20_11b_scap = 0;
+ uint16 rccal_tx20_11n_bcap = 0;
+ uint16 rccal_tx20_11n_scap = 0;
+ uint16 rccal_tx40_11n_bcap = 0;
+ uint16 rccal_tx40_11n_scap = 0;
+ uint16 rx2tx_lpf_rc_lut_tx20_11b = 0;
+ uint16 rx2tx_lpf_rc_lut_tx20_11n = 0;
+ uint16 rx2tx_lpf_rc_lut_tx40_11n = 0;
+ uint16 tx_lpf_bw_ofdm_20mhz = 0;
+ uint16 tx_lpf_bw_ofdm_40mhz = 0;
+ uint16 tx_lpf_bw_11b = 0;
+ uint16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
+ uint16 txgm_idac_bleed = 0;
+ bool rccal_ovrd = FALSE;
+ uint16 freq;
+ int coreNum;
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
+ } else {
+ wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (!ISSIM_ENAB(pi->sh->sih)) {
+ or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+ mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
+
+ mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
+ mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
+ mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
+ mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
+ mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
+ mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
+ mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
+ mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
+ mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
+ mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
+ mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
+ mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
+ mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
+ mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
+ mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
+ mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
+ }
+
+ if (NREV_LE(pi->pubpi.phy_rev, 8)) {
+ write_phy_reg(pi, 0x23f, 0x1b0);
+ write_phy_reg(pi, 0x240, 0x1b0);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+ mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+ &dac_control);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+ &dac_control);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 0, 32, &leg_data_weights);
+ leg_data_weights = leg_data_weights & 0xffffff;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 0, 32, &leg_data_weights);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 2, 0x15e, 16,
+ rfseq_rx2tx_dacbufpu_rev7);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
+ rfseq_rx2tx_dacbufpu_rev7);
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+ rfseq_rx2tx_events_rev3_ipa,
+ rfseq_rx2tx_dlys_rev3_ipa,
+ sizeof
+ (rfseq_rx2tx_events_rev3_ipa) /
+ sizeof
+ (rfseq_rx2tx_events_rev3_ipa
+ [0]));
+ }
+
+ mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
+ mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
+
+ tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
+ tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
+ tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
+
+ if (PHY_IPA(pi)) {
+
+ if (((pi->pubpi.radiorev == 5)
+ && (CHSPEC_IS40(pi->radio_chanspec) == 1))
+ || (pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ rccal_bcap_val =
+ read_radio_reg(pi,
+ RADIO_2057_RCCAL_BCAP_VAL);
+ rccal_scap_val =
+ read_radio_reg(pi,
+ RADIO_2057_RCCAL_SCAP_VAL);
+
+ rccal_tx20_11b_bcap = rccal_bcap_val;
+ rccal_tx20_11b_scap = rccal_scap_val;
+
+ if ((pi->pubpi.radiorev == 5) &&
+ (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
+
+ rccal_tx20_11n_bcap = rccal_bcap_val;
+ rccal_tx20_11n_scap = rccal_scap_val;
+ rccal_tx40_11n_bcap = 0xc;
+ rccal_tx40_11n_scap = 0xc;
+
+ rccal_ovrd = TRUE;
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ tx_lpf_bw_ofdm_20mhz = 4;
+ tx_lpf_bw_11b = 1;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ rccal_tx20_11n_bcap = 0xc;
+ rccal_tx20_11n_scap = 0xc;
+ rccal_tx40_11n_bcap = 0xa;
+ rccal_tx40_11n_scap = 0xa;
+ } else {
+ rccal_tx20_11n_bcap = 0x14;
+ rccal_tx20_11n_scap = 0x14;
+ rccal_tx40_11n_bcap = 0xf;
+ rccal_tx40_11n_scap = 0xf;
+ }
+
+ rccal_ovrd = TRUE;
+ }
+ }
+
+ } else {
+
+ if (pi->pubpi.radiorev == 5) {
+
+ tx_lpf_bw_ofdm_20mhz = 1;
+ tx_lpf_bw_ofdm_40mhz = 3;
+
+ rccal_bcap_val =
+ read_radio_reg(pi,
+ RADIO_2057_RCCAL_BCAP_VAL);
+ rccal_scap_val =
+ read_radio_reg(pi,
+ RADIO_2057_RCCAL_SCAP_VAL);
+
+ rccal_tx20_11b_bcap = rccal_bcap_val;
+ rccal_tx20_11b_scap = rccal_scap_val;
+
+ rccal_tx20_11n_bcap = 0x13;
+ rccal_tx20_11n_scap = 0x11;
+ rccal_tx40_11n_bcap = 0x13;
+ rccal_tx40_11n_scap = 0x11;
+
+ rccal_ovrd = TRUE;
+ }
+ }
+
+ if (rccal_ovrd) {
+
+ rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) |
+ (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
+ rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) |
+ (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
+ rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) |
+ (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
+
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x152 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx20_11b);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x153 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx20_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x154 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx20_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x155 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx40_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x156 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx40_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x157 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx40_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x158 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx40_11n);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 1,
+ 0x159 + coreNum * 0x10,
+ 16,
+ &rx2tx_lpf_rc_lut_tx40_11n);
+ }
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+ 1, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ }
+
+ if (!NORADIO_ENAB(pi->pubpi)) {
+ write_phy_reg(pi, 0x32f, 0x3);
+ }
+
+ if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+ 1, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ }
+
+ if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+ if ((pi->sh->sromrev >= 8)
+ && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
+ ipalvlshift_3p3_war_en = 1;
+
+ if (ipalvlshift_3p3_war_en) {
+ write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
+ 0x5);
+ write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
+ 0x30);
+ write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
+ or_radio_reg(pi,
+ RADIO_2057_RXTXBIAS_CONFIG_CORE0,
+ 0x1);
+ or_radio_reg(pi,
+ RADIO_2057_RXTXBIAS_CONFIG_CORE1,
+ 0x1);
+
+ ipa2g_mainbias = 0x1f;
+
+ ipa2g_casconv = 0x6f;
+
+ ipa2g_biasfilt = 0xaa;
+ } else {
+
+ ipa2g_mainbias = 0x2b;
+
+ ipa2g_casconv = 0x7f;
+
+ ipa2g_biasfilt = 0xee;
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ coreNum, IPA2G_IMAIN,
+ ipa2g_mainbias);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ coreNum, IPA2G_CASCONV,
+ ipa2g_casconv);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ coreNum,
+ IPA2G_BIAS_FILTER,
+ ipa2g_biasfilt);
+ }
+ }
+ }
+
+ if (PHY_IPA(pi)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if ((pi->pubpi.radiorev == 3)
+ || (pi->pubpi.radiorev == 4)
+ || (pi->pubpi.radiorev == 6)) {
+
+ txgm_idac_bleed = 0x7f;
+ }
+
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+ if (txgm_idac_bleed != 0)
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ TXGM_IDAC_BLEED,
+ txgm_idac_bleed);
+ }
+
+ if (pi->pubpi.radiorev == 5) {
+
+ for (coreNum = 0; coreNum <= 1;
+ coreNum++) {
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ IPA2G_CASCONV,
+ 0x13);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ IPA2G_IMAIN,
+ 0x1f);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ IPA2G_BIAS_FILTER,
+ 0xee);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ PAD2G_IDACS,
+ 0x8a);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, coreNum,
+ PAD_BIAS_FILTER_BWS,
+ 0x3e);
+ }
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ if (CHSPEC_IS40(pi->radio_chanspec) ==
+ 0) {
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, 0,
+ IPA2G_IMAIN,
+ 0x14);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, 1,
+ IPA2G_IMAIN,
+ 0x12);
+ } else {
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, 0,
+ IPA2G_IMAIN,
+ 0x16);
+ WRITE_RADIO_REG4(pi, RADIO_2057,
+ CORE, 1,
+ IPA2G_IMAIN,
+ 0x16);
+ }
+ }
+
+ } else {
+ freq =
+ CHAN5G_FREQ(CHSPEC_CHANNEL
+ (pi->radio_chanspec));
+ if (((freq >= 5180) && (freq <= 5230))
+ || ((freq >= 5745) && (freq <= 5805))) {
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ 0, IPA5G_BIAS_FILTER,
+ 0xff);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ 1, IPA5G_BIAS_FILTER,
+ 0xff);
+ }
+ }
+ } else {
+
+ if (pi->pubpi.radiorev != 5) {
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ coreNum,
+ TXMIX2G_TUNE_BOOST_PU,
+ 0x61);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+ coreNum,
+ TXGM_IDAC_BLEED, 0x70);
+ }
+ }
+ }
+
+ if (pi->pubpi.radiorev == 4) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+ 0x05, 16,
+ &afectrl_adc_ctrl1_rev7);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+ 0x15, 16,
+ &afectrl_adc_ctrl1_rev7);
+
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+ AFE_VCM_CAL_MASTER, 0x0);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+ AFE_SET_VCM_I, 0x3f);
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+ AFE_SET_VCM_Q, 0x3f);
+ }
+ } else {
+ mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+
+ mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
+ mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
+ mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
+ mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+ 0x05, 16,
+ &afectrl_adc_ctrl2_rev7);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+ 0x15, 16,
+ &afectrl_adc_ctrl2_rev7);
+
+ mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+ mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
+ mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+ mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
+ }
+
+ write_phy_reg(pi, 0x6a, 0x2);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
+ &min_nvar_offset_6mbps);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
+ &rfseq_pktgn_lpf_hpc_rev7);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
+ &rfseq_pktgn_lpf_h_hpc_rev7);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
+ &rfseq_htpktgn_lpf_hpc_rev7);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
+ &rfseq_cckpktgn_lpf_hpc_rev7);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
+ &rfseq_tx2rx_lpf_h_hpc_rev7);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
+ &rfseq_rx2tx_lpf_h_hpc_rev7);
+
+ if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+ 32, &min_nvar_val);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ 127, 32, &min_nvar_val);
+ } else {
+ min_nvar_val = noise_var_tbl_rev7[3];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+ 32, &min_nvar_val);
+
+ min_nvar_val = noise_var_tbl_rev7[127];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ 127, 32, &min_nvar_val);
+ }
+
+ wlc_phy_workarounds_nphy_gainctrl(pi);
+
+ pdetrange =
+ (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+ pdetrange : pi->srom_fem2g.pdetrange;
+
+ if (pdetrange == 0) {
+ chan_freq_range =
+ wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ aux_adc_vmid_rev7_core0[3] = 0x70;
+ aux_adc_vmid_rev7_core1[3] = 0x70;
+ aux_adc_gain_rev7[3] = 2;
+ } else {
+ aux_adc_vmid_rev7_core0[3] = 0x80;
+ aux_adc_vmid_rev7_core1[3] = 0x80;
+ aux_adc_gain_rev7[3] = 3;
+ }
+ } else if (pdetrange == 1) {
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ aux_adc_vmid_rev7_core0[3] = 0x7c;
+ aux_adc_vmid_rev7_core1[3] = 0x7c;
+ aux_adc_gain_rev7[3] = 2;
+ } else {
+ aux_adc_vmid_rev7_core0[3] = 0x8c;
+ aux_adc_vmid_rev7_core1[3] = 0x8c;
+ aux_adc_gain_rev7[3] = 1;
+ }
+ } else if (pdetrange == 2) {
+ if (pi->pubpi.radioid == BCM2057_ID) {
+ if ((pi->pubpi.radiorev == 5)
+ || (pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+ if (chan_freq_range ==
+ WL_CHAN_FREQ_RANGE_2G) {
+ aux_adc_vmid_rev7_core0[3] =
+ 0x8c;
+ aux_adc_vmid_rev7_core1[3] =
+ 0x8c;
+ aux_adc_gain_rev7[3] = 0;
+ } else {
+ aux_adc_vmid_rev7_core0[3] =
+ 0x96;
+ aux_adc_vmid_rev7_core1[3] =
+ 0x96;
+ aux_adc_gain_rev7[3] = 0;
+ }
+ }
+ }
+
+ } else if (pdetrange == 3) {
+ if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
+ aux_adc_vmid_rev7_core0[3] = 0x89;
+ aux_adc_vmid_rev7_core1[3] = 0x89;
+ aux_adc_gain_rev7[3] = 0;
+ }
+
+ } else if (pdetrange == 5) {
+
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ aux_adc_vmid_rev7_core0[3] = 0x80;
+ aux_adc_vmid_rev7_core1[3] = 0x80;
+ aux_adc_gain_rev7[3] = 3;
+ } else {
+ aux_adc_vmid_rev7_core0[3] = 0x70;
+ aux_adc_vmid_rev7_core1[3] = 0x70;
+ aux_adc_gain_rev7[3] = 2;
+ }
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
+ &aux_adc_vmid_rev7_core0);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
+ &aux_adc_vmid_rev7_core1);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
+ &aux_adc_gain_rev7);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
+ &aux_adc_gain_rev7);
+
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ write_phy_reg(pi, 0x23f, 0x1f8);
+ write_phy_reg(pi, 0x240, 0x1f8);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 0, 32, &leg_data_weights);
+ leg_data_weights = leg_data_weights & 0xffffff;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 0, 32, &leg_data_weights);
+
+ alpha0 = 293;
+ alpha1 = 435;
+ alpha2 = 261;
+ beta0 = 366;
+ beta1 = 205;
+ beta2 = 32;
+ write_phy_reg(pi, 0x145, alpha0);
+ write_phy_reg(pi, 0x146, alpha1);
+ write_phy_reg(pi, 0x147, alpha2);
+ write_phy_reg(pi, 0x148, beta0);
+ write_phy_reg(pi, 0x149, beta1);
+ write_phy_reg(pi, 0x14a, beta2);
+
+ write_phy_reg(pi, 0x38, 0xC);
+ write_phy_reg(pi, 0x2ae, 0xC);
+
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
+ rfseq_tx2rx_events_rev3,
+ rfseq_tx2rx_dlys_rev3,
+ sizeof(rfseq_tx2rx_events_rev3) /
+ sizeof(rfseq_tx2rx_events_rev3[0]));
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+ rfseq_rx2tx_events_rev3_ipa,
+ rfseq_rx2tx_dlys_rev3_ipa,
+ sizeof
+ (rfseq_rx2tx_events_rev3_ipa) /
+ sizeof
+ (rfseq_rx2tx_events_rev3_ipa
+ [0]));
+ }
+
+ if ((pi->sh->hw_phyrxchain != 0x3) &&
+ (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
+
+ if (PHY_IPA(pi)) {
+ rfseq_rx2tx_dlys_rev3[5] = 59;
+ rfseq_rx2tx_dlys_rev3[6] = 1;
+ rfseq_rx2tx_events_rev3[7] =
+ NPHY_REV3_RFSEQ_CMD_END;
+ }
+
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+ rfseq_rx2tx_events_rev3,
+ rfseq_rx2tx_dlys_rev3,
+ sizeof(rfseq_rx2tx_events_rev3) /
+ sizeof(rfseq_rx2tx_events_rev3
+ [0]));
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_phy_reg(pi, 0x6a, 0x2);
+ } else {
+ write_phy_reg(pi, 0x6a, 0x9c40);
+ }
+
+ mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
+
+ if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+ 32, &min_nvar_val);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ 127, 32, &min_nvar_val);
+ } else {
+ min_nvar_val = noise_var_tbl_rev3[3];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+ 32, &min_nvar_val);
+
+ min_nvar_val = noise_var_tbl_rev3[127];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ 127, 32, &min_nvar_val);
+ }
+
+ wlc_phy_workarounds_nphy_gainctrl(pi);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+ &dac_control);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+ &dac_control);
+
+ pdetrange =
+ (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+ pdetrange : pi->srom_fem2g.pdetrange;
+
+ if (pdetrange == 0) {
+ if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ aux_adc_vmid = aux_adc_vmid_rev4;
+ aux_adc_gain = aux_adc_gain_rev4;
+ } else {
+ aux_adc_vmid = aux_adc_vmid_rev3;
+ aux_adc_gain = aux_adc_gain_rev3;
+ }
+ chan_freq_range =
+ wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ switch (chan_freq_range) {
+ case WL_CHAN_FREQ_RANGE_5GL:
+ aux_adc_vmid[3] = 0x89;
+ aux_adc_gain[3] = 0;
+ break;
+ case WL_CHAN_FREQ_RANGE_5GM:
+ aux_adc_vmid[3] = 0x89;
+ aux_adc_gain[3] = 0;
+ break;
+ case WL_CHAN_FREQ_RANGE_5GH:
+ aux_adc_vmid[3] = 0x89;
+ aux_adc_gain[3] = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x08, 16, aux_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x18, 16, aux_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x0c, 16, aux_adc_gain);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x1c, 16, aux_adc_gain);
+ } else if (pdetrange == 1) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x08, 16, sk_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x18, 16, sk_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x0c, 16, sk_adc_gain);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x1c, 16, sk_adc_gain);
+ } else if (pdetrange == 2) {
+
+ uint16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
+ uint16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ chan_freq_range =
+ wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ bcm_adc_vmid[3] = 0x8e;
+ bcm_adc_gain[3] = 0x03;
+ } else {
+ bcm_adc_vmid[3] = 0x94;
+ bcm_adc_gain[3] = 0x03;
+ }
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+ bcm_adc_vmid[3] = 0x84;
+ bcm_adc_gain[3] = 0x02;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x08, 16, bcm_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x18, 16, bcm_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x0c, 16, bcm_adc_gain);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x1c, 16, bcm_adc_gain);
+ } else if (pdetrange == 3) {
+ chan_freq_range =
+ wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ if ((NREV_GE(pi->pubpi.phy_rev, 4))
+ && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
+
+ uint16 auxadc_vmid[] = {
+ 0xa2, 0xb4, 0xb4, 0x270 };
+ uint16 auxadc_gain[] = {
+ 0x02, 0x02, 0x02, 0x00 };
+
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_AFECTRL, 4,
+ 0x08, 16, auxadc_vmid);
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_AFECTRL, 4,
+ 0x18, 16, auxadc_vmid);
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_AFECTRL, 4,
+ 0x0c, 16, auxadc_gain);
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_AFECTRL, 4,
+ 0x1c, 16, auxadc_gain);
+ }
+ } else if ((pdetrange == 4) || (pdetrange == 5)) {
+ uint16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
+ uint16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
+ uint16 Vmid[2], Av[2];
+
+ chan_freq_range =
+ wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+ Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
+ Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
+ Av[0] = (pdetrange == 4) ? 2 : 0;
+ Av[1] = (pdetrange == 4) ? 2 : 0;
+ } else {
+ Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
+ Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
+ Av[0] = (pdetrange == 4) ? 2 : 0;
+ Av[1] = (pdetrange == 4) ? 2 : 0;
+ }
+
+ bcm_adc_vmid[3] = Vmid[0];
+ bcm_adc_gain[3] = Av[0];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x08, 16, bcm_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x0c, 16, bcm_adc_gain);
+
+ bcm_adc_vmid[3] = Vmid[1];
+ bcm_adc_gain[3] = Av[1];
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x18, 16, bcm_adc_vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+ 0x1c, 16, bcm_adc_gain);
+ } else {
+ ASSERT(0);
+ }
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
+ 0x0);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
+ 0x0);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
+ 0x6);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
+ 0x6);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
+ 0x7);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
+ 0x7);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
+ 0x88);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
+ 0x88);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
+ 0x0);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
+ 0x0);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
+ 0x0);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
+ 0x0);
+
+ triso =
+ (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+ triso : pi->srom_fem2g.triso;
+ if (triso == 7) {
+ wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+ wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+ }
+
+ wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
+
+ if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
+ (CHSPEC_IS5G(pi->radio_chanspec))) ||
+ (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
+ (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
+ (CHSPEC_IS2G(pi->radio_chanspec)))) {
+ nss1_data_weights = 0x00088888;
+ ht_data_weights = 0x00088888;
+ stbc_data_weights = 0x00088888;
+ } else {
+ nss1_data_weights = 0x88888888;
+ ht_data_weights = 0x88888888;
+ stbc_data_weights = 0x88888888;
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 1, 32, &nss1_data_weights);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 2, 32, &ht_data_weights);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+ 1, 3, 32, &stbc_data_weights);
+
+ if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ write_radio_reg(pi,
+ RADIO_2056_TX_GMBB_IDAC |
+ RADIO_2056_TX0, 0x70);
+ write_radio_reg(pi,
+ RADIO_2056_TX_GMBB_IDAC |
+ RADIO_2056_TX1, 0x70);
+ }
+ }
+
+ if (!pi->edcrs_threshold_lock) {
+ write_phy_reg(pi, 0x224, 0x3eb);
+ write_phy_reg(pi, 0x225, 0x3eb);
+ write_phy_reg(pi, 0x226, 0x341);
+ write_phy_reg(pi, 0x227, 0x341);
+ write_phy_reg(pi, 0x228, 0x42b);
+ write_phy_reg(pi, 0x229, 0x42b);
+ write_phy_reg(pi, 0x22a, 0x381);
+ write_phy_reg(pi, 0x22b, 0x381);
+ write_phy_reg(pi, 0x22c, 0x42b);
+ write_phy_reg(pi, 0x22d, 0x42b);
+ write_phy_reg(pi, 0x22e, 0x381);
+ write_phy_reg(pi, 0x22f, 0x381);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+
+ if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) {
+ wlapi_bmac_mhf(pi->sh->physhim, MHF4,
+ MHF4_BPHY_TXCORE0,
+ MHF4_BPHY_TXCORE0, WLC_BAND_ALL);
+ }
+ }
+ } else {
+
+ if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
+ (pi->sh->boardtype == 0x8b)) {
+ uint i;
+ uint8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
+ for (i = 0; i < ARRAYSIZE(rfseq_rx2tx_dlys); i++)
+ rfseq_rx2tx_dlys[i] = war_dlys[i];
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
+ and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
+ and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
+ } else {
+ or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
+ or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
+ }
+
+ regval = 0x000a;
+ wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+ regval = 0xcdaa;
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ regval = 0x0000;
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
+
+ regval = 0x7aab;
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
+
+ regval = 0x0800;
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
+ wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
+ }
+
+ write_phy_reg(pi, 0xf8, 0x02d8);
+ write_phy_reg(pi, 0xf9, 0x0301);
+ write_phy_reg(pi, 0xfa, 0x02d8);
+ write_phy_reg(pi, 0xfb, 0x0301);
+
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
+ rfseq_rx2tx_dlys,
+ sizeof(rfseq_rx2tx_events) /
+ sizeof(rfseq_rx2tx_events[0]));
+
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
+ rfseq_tx2rx_dlys,
+ sizeof(rfseq_tx2rx_events) /
+ sizeof(rfseq_tx2rx_events[0]));
+
+ wlc_phy_workarounds_nphy_gainctrl(pi);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+
+ if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
+ wlapi_bmac_mhf(pi->sh->physhim, MHF3,
+ MHF3_NPHY_MLADV_WAR,
+ MHF3_NPHY_MLADV_WAR,
+ WLC_BAND_ALL);
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+ write_phy_reg(pi, 0x1e3, 0x0);
+ write_phy_reg(pi, 0x1e4, 0x0);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
+
+ alpha0 = 293;
+ alpha1 = 435;
+ alpha2 = 261;
+ beta0 = 366;
+ beta1 = 205;
+ beta2 = 32;
+ write_phy_reg(pi, 0x145, alpha0);
+ write_phy_reg(pi, 0x146, alpha1);
+ write_phy_reg(pi, 0x147, alpha2);
+ write_phy_reg(pi, 0x148, beta0);
+ write_phy_reg(pi, 0x149, beta1);
+ write_phy_reg(pi, 0x14a, beta2);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+ mod_phy_reg(pi, 0x142, (0xf << 12), 0);
+
+ write_phy_reg(pi, 0x192, 0xb5);
+ write_phy_reg(pi, 0x193, 0xa4);
+ write_phy_reg(pi, 0x194, 0x0);
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+ mod_phy_reg(pi, 0x221,
+ NPHY_FORCESIG_DECODEGATEDCLKS,
+ NPHY_FORCESIG_DECODEGATEDCLKS);
+ }
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi)
+{
+ uint16 w1th, hpf_code, currband;
+ int ctr;
+ uint8 rfseq_updategainu_events[] = {
+ NPHY_RFSEQ_CMD_RX_GAIN,
+ NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+ NPHY_RFSEQ_CMD_SET_HPF_BW
+ };
+ uint8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
+ int8 lna1G_gain_db[] = { 7, 11, 16, 23 };
+ int8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
+ int8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
+ int8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
+ int8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
+ int8 lna1A_gain_db[] = { 7, 11, 17, 23 };
+ int8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
+ int8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
+ int8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
+ int8 *lna1_gain_db = NULL;
+ int8 lna2G_gain_db[] = { -5, 6, 10, 14 };
+ int8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
+ int8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
+ int8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
+ int8 lna2A_gain_db[] = { -6, 2, 6, 10 };
+ int8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
+ int8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
+ int8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
+ int8 *lna2_gain_db = NULL;
+ int8 tiaG_gain_db[] = {
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
+ int8 tiaA_gain_db[] = {
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
+ int8 tiaA_gain_db_rev4[] = {
+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+ int8 tiaA_gain_db_rev5[] = {
+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+ int8 tiaA_gain_db_rev6[] = {
+ 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+ int8 *tia_gain_db;
+ int8 tiaG_gainbits[] = {
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+ int8 tiaA_gainbits[] = {
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
+ int8 tiaA_gainbits_rev4[] = {
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+ int8 tiaA_gainbits_rev5[] = {
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+ int8 tiaA_gainbits_rev6[] = {
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+ int8 *tia_gainbits;
+ int8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
+ int8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
+ uint16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
+ uint16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
+ uint16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
+ uint16 rfseqG_init_gain_rev5_elna[] = {
+ 0x013f, 0x013f, 0x013f, 0x013f };
+ uint16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
+ uint16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
+ uint16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
+ uint16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
+ uint16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
+ uint16 rfseqA_init_gain_rev4_elna[] = {
+ 0x314f, 0x314f, 0x314f, 0x314f };
+ uint16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
+ uint16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
+ uint16 *rfseq_init_gain;
+ uint16 initG_gaincode = 0x627e;
+ uint16 initG_gaincode_rev4 = 0x527e;
+ uint16 initG_gaincode_rev5 = 0x427e;
+ uint16 initG_gaincode_rev5_elna = 0x027e;
+ uint16 initG_gaincode_rev6 = 0x527e;
+ uint16 initG_gaincode_rev6_224B0 = 0x427e;
+ uint16 initG_gaincode_rev6_elna = 0x127e;
+ uint16 initA_gaincode = 0x52de;
+ uint16 initA_gaincode_rev4 = 0x629e;
+ uint16 initA_gaincode_rev4_elna = 0x329e;
+ uint16 initA_gaincode_rev5 = 0x729e;
+ uint16 initA_gaincode_rev6 = 0x729e;
+ uint16 init_gaincode;
+ uint16 clip1hiG_gaincode = 0x107e;
+ uint16 clip1hiG_gaincode_rev4 = 0x007e;
+ uint16 clip1hiG_gaincode_rev5 = 0x1076;
+ uint16 clip1hiG_gaincode_rev6 = 0x007e;
+ uint16 clip1hiA_gaincode = 0x00de;
+ uint16 clip1hiA_gaincode_rev4 = 0x029e;
+ uint16 clip1hiA_gaincode_rev5 = 0x029e;
+ uint16 clip1hiA_gaincode_rev6 = 0x029e;
+ uint16 clip1hi_gaincode;
+ uint16 clip1mdG_gaincode = 0x0066;
+ uint16 clip1mdA_gaincode = 0x00ca;
+ uint16 clip1mdA_gaincode_rev4 = 0x1084;
+ uint16 clip1mdA_gaincode_rev5 = 0x2084;
+ uint16 clip1mdA_gaincode_rev6 = 0x2084;
+ uint16 clip1md_gaincode = 0;
+ uint16 clip1loG_gaincode = 0x0074;
+ uint16 clip1loG_gaincode_rev5[] = {
+ 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
+ };
+ uint16 clip1loG_gaincode_rev6[] = {
+ 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
+ };
+ uint16 clip1loG_gaincode_rev6_224B0 = 0x1074;
+ uint16 clip1loA_gaincode = 0x00cc;
+ uint16 clip1loA_gaincode_rev4 = 0x0086;
+ uint16 clip1loA_gaincode_rev5 = 0x2086;
+ uint16 clip1loA_gaincode_rev6 = 0x2086;
+ uint16 clip1lo_gaincode;
+ uint8 crsminG_th = 0x18;
+ uint8 crsminG_th_rev5 = 0x18;
+ uint8 crsminG_th_rev6 = 0x18;
+ uint8 crsminA_th = 0x1e;
+ uint8 crsminA_th_rev4 = 0x24;
+ uint8 crsminA_th_rev5 = 0x24;
+ uint8 crsminA_th_rev6 = 0x24;
+ uint8 crsmin_th;
+ uint8 crsminlG_th = 0x18;
+ uint8 crsminlG_th_rev5 = 0x18;
+ uint8 crsminlG_th_rev6 = 0x18;
+ uint8 crsminlA_th = 0x1e;
+ uint8 crsminlA_th_rev4 = 0x24;
+ uint8 crsminlA_th_rev5 = 0x24;
+ uint8 crsminlA_th_rev6 = 0x24;
+ uint8 crsminl_th = 0;
+ uint8 crsminuG_th = 0x18;
+ uint8 crsminuG_th_rev5 = 0x18;
+ uint8 crsminuG_th_rev6 = 0x18;
+ uint8 crsminuA_th = 0x1e;
+ uint8 crsminuA_th_rev4 = 0x24;
+ uint8 crsminuA_th_rev5 = 0x24;
+ uint8 crsminuA_th_rev6 = 0x24;
+ uint8 crsminuA_th_rev6_224B0 = 0x2d;
+ uint8 crsminu_th;
+ uint16 nbclipG_th = 0x20d;
+ uint16 nbclipG_th_rev4 = 0x1a1;
+ uint16 nbclipG_th_rev5 = 0x1d0;
+ uint16 nbclipG_th_rev6 = 0x1d0;
+ uint16 nbclipA_th = 0x1a1;
+ uint16 nbclipA_th_rev4 = 0x107;
+ uint16 nbclipA_th_rev5 = 0x0a9;
+ uint16 nbclipA_th_rev6 = 0x0f0;
+ uint16 nbclip_th = 0;
+ uint8 w1clipG_th = 5;
+ uint8 w1clipG_th_rev5 = 9;
+ uint8 w1clipG_th_rev6 = 5;
+ uint8 w1clipA_th = 25, w1clip_th;
+ uint8 rssi_gain_default = 0x50;
+ uint8 rssiG_gain_rev6_224B0 = 0x50;
+ uint8 rssiA_gain_rev5 = 0x90;
+ uint8 rssiA_gain_rev6 = 0x90;
+ uint8 rssi_gain;
+ uint16 regval[21];
+ uint8 triso;
+
+ triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
+ pi->srom_fem2g.triso;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (pi->pubpi.radiorev == 5) {
+
+ wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
+ } else if (pi->pubpi.radiorev == 7) {
+ wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+
+ mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
+ mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
+
+ } else if ((pi->pubpi.radiorev == 3)
+ || (pi->pubpi.radiorev == 8)) {
+ wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+
+ if (pi->pubpi.radiorev == 8) {
+ mod_phy_reg(pi, 0x283,
+ (0xff << 0), (0x44 << 0));
+ mod_phy_reg(pi, 0x280,
+ (0xff << 0), (0x44 << 0));
+ }
+ } else {
+ wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+ }
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
+
+ mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+ mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+
+ currband =
+ read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+ if (currband == 0) {
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ if (pi->pubpi.radiorev == 11) {
+ lna1_gain_db = lna1G_gain_db_rev6_224B0;
+ lna2_gain_db = lna2G_gain_db_rev6_224B0;
+ rfseq_init_gain =
+ rfseqG_init_gain_rev6_224B0;
+ init_gaincode =
+ initG_gaincode_rev6_224B0;
+ clip1hi_gaincode =
+ clip1hiG_gaincode_rev6;
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6_224B0;
+ nbclip_th = nbclipG_th_rev6;
+ w1clip_th = w1clipG_th_rev6;
+ crsmin_th = crsminG_th_rev6;
+ crsminl_th = crsminlG_th_rev6;
+ crsminu_th = crsminuG_th_rev6;
+ rssi_gain = rssiG_gain_rev6_224B0;
+ } else {
+ lna1_gain_db = lna1G_gain_db_rev6;
+ lna2_gain_db = lna2G_gain_db_rev6;
+ if (pi->sh->boardflags & BFL_EXTLNA) {
+
+ rfseq_init_gain =
+ rfseqG_init_gain_rev6_elna;
+ init_gaincode =
+ initG_gaincode_rev6_elna;
+ } else {
+ rfseq_init_gain =
+ rfseqG_init_gain_rev6;
+ init_gaincode =
+ initG_gaincode_rev6;
+ }
+ clip1hi_gaincode =
+ clip1hiG_gaincode_rev6;
+ switch (triso) {
+ case 0:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[0];
+ break;
+ case 1:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[1];
+ break;
+ case 2:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[2];
+ break;
+ case 3:
+ default:
+
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[3];
+ break;
+ case 4:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[4];
+ break;
+ case 5:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[5];
+ break;
+ case 6:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[6];
+ break;
+ case 7:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev6[7];
+ break;
+ }
+ nbclip_th = nbclipG_th_rev6;
+ w1clip_th = w1clipG_th_rev6;
+ crsmin_th = crsminG_th_rev6;
+ crsminl_th = crsminlG_th_rev6;
+ crsminu_th = crsminuG_th_rev6;
+ rssi_gain = rssi_gain_default;
+ }
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+ lna1_gain_db = lna1G_gain_db_rev5;
+ lna2_gain_db = lna2G_gain_db_rev5;
+ if (pi->sh->boardflags & BFL_EXTLNA) {
+
+ rfseq_init_gain =
+ rfseqG_init_gain_rev5_elna;
+ init_gaincode =
+ initG_gaincode_rev5_elna;
+ } else {
+ rfseq_init_gain = rfseqG_init_gain_rev5;
+ init_gaincode = initG_gaincode_rev5;
+ }
+ clip1hi_gaincode = clip1hiG_gaincode_rev5;
+ switch (triso) {
+ case 0:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[0];
+ break;
+ case 1:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[1];
+ break;
+ case 2:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[2];
+ break;
+ case 3:
+
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[3];
+ break;
+ case 4:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[4];
+ break;
+ case 5:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[5];
+ break;
+ case 6:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[6];
+ break;
+ case 7:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[7];
+ break;
+ default:
+ clip1lo_gaincode =
+ clip1loG_gaincode_rev5[3];
+ break;
+ }
+ nbclip_th = nbclipG_th_rev5;
+ w1clip_th = w1clipG_th_rev5;
+ crsmin_th = crsminG_th_rev5;
+ crsminl_th = crsminlG_th_rev5;
+ crsminu_th = crsminuG_th_rev5;
+ rssi_gain = rssi_gain_default;
+ } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+ lna1_gain_db = lna1G_gain_db_rev4;
+ lna2_gain_db = lna2G_gain_db;
+ rfseq_init_gain = rfseqG_init_gain_rev4;
+ init_gaincode = initG_gaincode_rev4;
+ clip1hi_gaincode = clip1hiG_gaincode_rev4;
+ clip1lo_gaincode = clip1loG_gaincode;
+ nbclip_th = nbclipG_th_rev4;
+ w1clip_th = w1clipG_th;
+ crsmin_th = crsminG_th;
+ crsminl_th = crsminlG_th;
+ crsminu_th = crsminuG_th;
+ rssi_gain = rssi_gain_default;
+ } else {
+ lna1_gain_db = lna1G_gain_db;
+ lna2_gain_db = lna2G_gain_db;
+ rfseq_init_gain = rfseqG_init_gain;
+ init_gaincode = initG_gaincode;
+ clip1hi_gaincode = clip1hiG_gaincode;
+ clip1lo_gaincode = clip1loG_gaincode;
+ nbclip_th = nbclipG_th;
+ w1clip_th = w1clipG_th;
+ crsmin_th = crsminG_th;
+ crsminl_th = crsminlG_th;
+ crsminu_th = crsminuG_th;
+ rssi_gain = rssi_gain_default;
+ }
+ tia_gain_db = tiaG_gain_db;
+ tia_gainbits = tiaG_gainbits;
+ clip1md_gaincode = clip1mdG_gaincode;
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ lna1_gain_db = lna1A_gain_db_rev6;
+ lna2_gain_db = lna2A_gain_db_rev6;
+ tia_gain_db = tiaA_gain_db_rev6;
+ tia_gainbits = tiaA_gainbits_rev6;
+ rfseq_init_gain = rfseqA_init_gain_rev6;
+ init_gaincode = initA_gaincode_rev6;
+ clip1hi_gaincode = clip1hiA_gaincode_rev6;
+ clip1md_gaincode = clip1mdA_gaincode_rev6;
+ clip1lo_gaincode = clip1loA_gaincode_rev6;
+ crsmin_th = crsminA_th_rev6;
+ crsminl_th = crsminlA_th_rev6;
+ if ((pi->pubpi.radiorev == 11) &&
+ (CHSPEC_IS40(pi->radio_chanspec) == 0)) {
+ crsminu_th = crsminuA_th_rev6_224B0;
+ } else {
+ crsminu_th = crsminuA_th_rev6;
+ }
+ nbclip_th = nbclipA_th_rev6;
+ rssi_gain = rssiA_gain_rev6;
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+ lna1_gain_db = lna1A_gain_db_rev5;
+ lna2_gain_db = lna2A_gain_db_rev5;
+ tia_gain_db = tiaA_gain_db_rev5;
+ tia_gainbits = tiaA_gainbits_rev5;
+ rfseq_init_gain = rfseqA_init_gain_rev5;
+ init_gaincode = initA_gaincode_rev5;
+ clip1hi_gaincode = clip1hiA_gaincode_rev5;
+ clip1md_gaincode = clip1mdA_gaincode_rev5;
+ clip1lo_gaincode = clip1loA_gaincode_rev5;
+ crsmin_th = crsminA_th_rev5;
+ crsminl_th = crsminlA_th_rev5;
+ crsminu_th = crsminuA_th_rev5;
+ nbclip_th = nbclipA_th_rev5;
+ rssi_gain = rssiA_gain_rev5;
+ } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+ lna1_gain_db = lna1A_gain_db_rev4;
+ lna2_gain_db = lna2A_gain_db_rev4;
+ tia_gain_db = tiaA_gain_db_rev4;
+ tia_gainbits = tiaA_gainbits_rev4;
+ if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
+
+ rfseq_init_gain =
+ rfseqA_init_gain_rev4_elna;
+ init_gaincode =
+ initA_gaincode_rev4_elna;
+ } else {
+ rfseq_init_gain = rfseqA_init_gain_rev4;
+ init_gaincode = initA_gaincode_rev4;
+ }
+ clip1hi_gaincode = clip1hiA_gaincode_rev4;
+ clip1md_gaincode = clip1mdA_gaincode_rev4;
+ clip1lo_gaincode = clip1loA_gaincode_rev4;
+ crsmin_th = crsminA_th_rev4;
+ crsminl_th = crsminlA_th_rev4;
+ crsminu_th = crsminuA_th_rev4;
+ nbclip_th = nbclipA_th_rev4;
+ rssi_gain = rssi_gain_default;
+ } else {
+ lna1_gain_db = lna1A_gain_db;
+ lna2_gain_db = lna2A_gain_db;
+ tia_gain_db = tiaA_gain_db;
+ tia_gainbits = tiaA_gainbits;
+ rfseq_init_gain = rfseqA_init_gain;
+ init_gaincode = initA_gaincode;
+ clip1hi_gaincode = clip1hiA_gaincode;
+ clip1md_gaincode = clip1mdA_gaincode;
+ clip1lo_gaincode = clip1loA_gaincode;
+ crsmin_th = crsminA_th;
+ crsminl_th = crsminlA_th;
+ crsminu_th = crsminuA_th;
+ nbclip_th = nbclipA_th;
+ rssi_gain = rssi_gain_default;
+ }
+ w1clip_th = w1clipA_th;
+ }
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+ RADIO_2056_RX0), 0x17);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+ RADIO_2056_RX1), 0x17);
+
+ write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
+ 0xf0);
+ write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
+ 0xf0);
+
+ write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
+ 0x0);
+ write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
+ 0x0);
+
+ write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
+ rssi_gain);
+ write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
+ rssi_gain);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+ RADIO_2056_RX0), 0x17);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+ RADIO_2056_RX1), 0x17);
+
+ write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
+ 0xFF);
+ write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
+ 0xFF);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
+ 8, lna1_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
+ 8, lna1_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+ 8, lna2_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+ 8, lna2_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
+ 8, tia_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
+ 8, tia_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
+ 8, tia_gainbits);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
+ 8, tia_gainbits);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
+ 8, &lpf_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
+ 8, &lpf_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
+ 8, &lpf_gainbits);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
+ 8, &lpf_gainbits);
+
+ write_phy_reg(pi, 0x20, init_gaincode);
+ write_phy_reg(pi, 0x2a7, init_gaincode);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ pi->pubpi.phy_corenum, 0x106, 16,
+ rfseq_init_gain);
+
+ write_phy_reg(pi, 0x22, clip1hi_gaincode);
+ write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+
+ write_phy_reg(pi, 0x24, clip1md_gaincode);
+ write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+
+ write_phy_reg(pi, 0x37, clip1lo_gaincode);
+ write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+
+ mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
+ mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+ mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+
+ write_phy_reg(pi, 0x2b, nbclip_th);
+ write_phy_reg(pi, 0x41, nbclip_th);
+
+ mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
+ mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
+
+ write_phy_reg(pi, 0x150, 0x809c);
+
+ } else {
+
+ mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+ mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+
+ write_phy_reg(pi, 0x2b, 0x84);
+ write_phy_reg(pi, 0x41, 0x84);
+
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+ write_phy_reg(pi, 0x6b, 0x2b);
+ write_phy_reg(pi, 0x6c, 0x2b);
+ write_phy_reg(pi, 0x6d, 0x9);
+ write_phy_reg(pi, 0x6e, 0x9);
+ }
+
+ w1th = NPHY_RSSICAL_W1_TARGET - 4;
+ mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
+ mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
+
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
+ mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
+
+ mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
+ mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
+ }
+
+ write_phy_reg(pi, 0x150, 0x809c);
+
+ if (pi->nphy_gain_boost)
+ if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
+ (CHSPEC_IS40(pi->radio_chanspec)))
+ hpf_code = 4;
+ else
+ hpf_code = 5;
+ else if (CHSPEC_IS40(pi->radio_chanspec))
+ hpf_code = 6;
+ else
+ hpf_code = 7;
+
+ mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
+ mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
+
+ for (ctr = 0; ctr < 4; ctr++) {
+ regval[ctr] = (hpf_code << 8) | 0x7c;
+ }
+ wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+
+ wlc_phy_adjust_lnagaintbl_nphy(pi);
+
+ if (pi->nphy_elna_gain_config) {
+ regval[0] = 0;
+ regval[1] = 1;
+ regval[2] = 1;
+ regval[3] = 1;
+ wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
+ wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
+
+ for (ctr = 0; ctr < 4; ctr++) {
+ regval[ctr] = (hpf_code << 8) | 0x74;
+ }
+ wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+ for (ctr = 0; ctr < 21; ctr++) {
+ regval[ctr] = 3 * ctr;
+ }
+ wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
+ wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
+
+ for (ctr = 0; ctr < 21; ctr++) {
+ regval[ctr] = (uint16) ctr;
+ }
+ wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
+ wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
+ }
+
+ wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
+ rfseq_updategainu_events,
+ rfseq_updategainu_dlys,
+ sizeof(rfseq_updategainu_events) /
+ sizeof(rfseq_updategainu_events[0]));
+
+ mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
+
+ if (CHSPEC_IS2G(pi->radio_chanspec))
+ mod_phy_reg(pi,
+ (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
+ 0x7f, 0x4);
+ }
+}
+
+static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi)
+{
+ int8 lna1_gain_db[] = { 8, 13, 17, 22 };
+ int8 lna2_gain_db[] = { -2, 7, 11, 15 };
+ int8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
+ int8 tia_gainbits[] = {
+ 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+
+ mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+ mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+
+ mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+
+ mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
+ mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
+ lna1_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
+ lna1_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
+ lna2_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
+ lna2_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+ tia_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+ tia_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+ tia_gainbits);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+ tia_gainbits);
+
+ write_phy_reg(pi, 0x37, 0x74);
+ write_phy_reg(pi, 0x2ad, 0x74);
+ write_phy_reg(pi, 0x38, 0x18);
+ write_phy_reg(pi, 0x2ae, 0x18);
+
+ write_phy_reg(pi, 0x2b, 0xe8);
+ write_phy_reg(pi, 0x41, 0xe8);
+
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+
+ mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
+ mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
+ } else {
+
+ mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
+ mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
+ }
+}
+
+static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi)
+{
+ uint16 currband;
+ int8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
+ int8 *lna1_gain_db = NULL;
+ int8 *lna1_gain_db_2 = NULL;
+ int8 *lna2_gain_db = NULL;
+ int8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
+ int8 *tia_gain_db;
+ int8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
+ int8 *tia_gainbits;
+ uint16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
+ uint16 *rfseq_init_gain;
+ uint16 init_gaincode;
+ uint16 clip1hi_gaincode;
+ uint16 clip1md_gaincode = 0;
+ uint16 clip1md_gaincode_B;
+ uint16 clip1lo_gaincode;
+ uint16 clip1lo_gaincode_B;
+ uint8 crsminl_th = 0;
+ uint8 crsminu_th;
+ uint16 nbclip_th = 0;
+ uint8 w1clip_th;
+ uint16 freq;
+ int8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
+ uint8 chg_nbclip_th = 0;
+
+ mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+ mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+
+ currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+ if (currband == 0) {
+
+ lna1_gain_db = lna1G_gain_db_rev7;
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+ lna1_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+ lna1_gain_db);
+
+ mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
+ mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
+ }
+
+ mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+ mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
+ mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
+ }
+ } else {
+
+ init_gaincode = 0x9e;
+ clip1hi_gaincode = 0x9e;
+ clip1md_gaincode_B = 0x24;
+ clip1lo_gaincode = 0x8a;
+ clip1lo_gaincode_B = 8;
+ rfseq_init_gain = rfseqA_init_gain_rev7;
+
+ tia_gain_db = tiaA_gain_db_rev7;
+ tia_gainbits = tiaA_gainbits_rev7;
+
+ freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+
+ w1clip_th = 25;
+ clip1md_gaincode = 0x82;
+
+ if ((freq <= 5080) || (freq == 5825)) {
+
+ int8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
+ int8 lna1A_gain_db_2_rev7[] = {
+ 11, 17, 22, 25 };
+ int8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+
+ crsminu_th = 0x3e;
+ lna1_gain_db = lna1A_gain_db_rev7;
+ lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+ lna2_gain_db = lna2A_gain_db_rev7;
+ } else if ((freq >= 5500) && (freq <= 5700)) {
+
+ int8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
+ int8 lna1A_gain_db_2_rev7[] = {
+ 12, 18, 22, 26 };
+ int8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
+
+ crsminu_th = 0x45;
+ clip1md_gaincode_B = 0x14;
+ nbclip_th = 0xff;
+ chg_nbclip_th = 1;
+ lna1_gain_db = lna1A_gain_db_rev7;
+ lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+ lna2_gain_db = lna2A_gain_db_rev7;
+ } else {
+
+ int8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
+ int8 lna1A_gain_db_2_rev7[] = {
+ 12, 18, 22, 26 };
+ int8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+
+ crsminu_th = 0x41;
+ lna1_gain_db = lna1A_gain_db_rev7;
+ lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+ lna2_gain_db = lna2A_gain_db_rev7;
+ }
+
+ if (freq <= 4920) {
+ nvar_baseline_offset0 = 5;
+ nvar_baseline_offset1 = 5;
+ } else if ((freq > 4920) && (freq <= 5320)) {
+ nvar_baseline_offset0 = 3;
+ nvar_baseline_offset1 = 5;
+ } else if ((freq > 5320) && (freq <= 5700)) {
+ nvar_baseline_offset0 = 3;
+ nvar_baseline_offset1 = 2;
+ } else {
+ nvar_baseline_offset0 = 4;
+ nvar_baseline_offset1 = 0;
+ }
+ } else {
+
+ crsminu_th = 0x3a;
+ crsminl_th = 0x3a;
+ w1clip_th = 20;
+
+ if ((freq >= 4920) && (freq <= 5320)) {
+ nvar_baseline_offset0 = 4;
+ nvar_baseline_offset1 = 5;
+ } else if ((freq > 5320) && (freq <= 5550)) {
+ nvar_baseline_offset0 = 4;
+ nvar_baseline_offset1 = 2;
+ } else {
+ nvar_baseline_offset0 = 5;
+ nvar_baseline_offset1 = 3;
+ }
+ }
+
+ write_phy_reg(pi, 0x20, init_gaincode);
+ write_phy_reg(pi, 0x2a7, init_gaincode);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ pi->pubpi.phy_corenum, 0x106, 16,
+ rfseq_init_gain);
+
+ write_phy_reg(pi, 0x22, clip1hi_gaincode);
+ write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+
+ write_phy_reg(pi, 0x36, clip1md_gaincode_B);
+ write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
+
+ write_phy_reg(pi, 0x37, clip1lo_gaincode);
+ write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+ write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
+ write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+ tia_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+ tia_gain_db);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+ tia_gainbits);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+ tia_gainbits);
+
+ mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+
+ if (chg_nbclip_th == 1) {
+ write_phy_reg(pi, 0x2b, nbclip_th);
+ write_phy_reg(pi, 0x41, nbclip_th);
+ }
+
+ mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
+ mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
+
+ mod_phy_reg(pi, 0x2e4,
+ (0x3f << 0), (nvar_baseline_offset0 << 0));
+
+ mod_phy_reg(pi, 0x2e4,
+ (0x3f << 6), (nvar_baseline_offset1 << 6));
+
+ if (CHSPEC_IS20(pi->radio_chanspec)) {
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+ lna1_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+ lna1_gain_db_2);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+ 8, lna2_gain_db);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+ 8, lna2_gain_db);
+
+ write_phy_reg(pi, 0x24, clip1md_gaincode);
+ write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+ } else {
+ mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+ }
+
+ }
+
+}
+
+static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi)
+{
+ uint core;
+ int ctr;
+ int16 gain_delta[2];
+ uint8 curr_channel;
+ uint16 minmax_gain[2];
+ uint16 regval[4];
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (pi->nphy_gain_boost) {
+ if ((CHSPEC_IS2G(pi->radio_chanspec))) {
+
+ gain_delta[0] = 6;
+ gain_delta[1] = 6;
+ } else {
+
+ curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+ gain_delta[0] =
+ (int16)
+ PHY_HW_ROUND(((nphy_lnagain_est0[0] *
+ curr_channel) +
+ nphy_lnagain_est0[1]), 13);
+ gain_delta[1] =
+ (int16)
+ PHY_HW_ROUND(((nphy_lnagain_est1[0] *
+ curr_channel) +
+ nphy_lnagain_est1[1]), 13);
+ }
+ } else {
+
+ gain_delta[0] = 0;
+ gain_delta[1] = 0;
+ }
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (pi->nphy_elna_gain_config) {
+
+ regval[0] = nphy_def_lnagains[2] + gain_delta[core];
+ regval[1] = nphy_def_lnagains[3] + gain_delta[core];
+ regval[2] = nphy_def_lnagains[3] + gain_delta[core];
+ regval[3] = nphy_def_lnagains[3] + gain_delta[core];
+ } else {
+ for (ctr = 0; ctr < 4; ctr++) {
+ regval[ctr] =
+ nphy_def_lnagains[ctr] + gain_delta[core];
+ }
+ }
+ wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
+
+ minmax_gain[core] =
+ (uint16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
+ }
+
+ mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
+ mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on)
+{
+ if (on) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (!pi->radio_is_on) {
+ wlc_phy_radio_preinit_205x(pi);
+ wlc_phy_radio_init_2057(pi);
+ wlc_phy_radio_postinit_2057(pi);
+ }
+
+ wlc_phy_chanspec_set((wlc_phy_t *) pi,
+ pi->radio_chanspec);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_radio_preinit_205x(pi);
+ wlc_phy_radio_init_2056(pi);
+ wlc_phy_radio_postinit_2056(pi);
+
+ wlc_phy_chanspec_set((wlc_phy_t *) pi,
+ pi->radio_chanspec);
+ } else {
+ wlc_phy_radio_preinit_2055(pi);
+ wlc_phy_radio_init_2055(pi);
+ wlc_phy_radio_postinit_2055(pi);
+ }
+
+ pi->radio_is_on = TRUE;
+
+ } else {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)
+ && NREV_LT(pi->pubpi.phy_rev, 7)) {
+ and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+ mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_PADA_BOOST_TUNE |
+ RADIO_2056_TX0, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PADG_BOOST_TUNE |
+ RADIO_2056_TX0, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PGAA_BOOST_TUNE |
+ RADIO_2056_TX0, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PGAG_BOOST_TUNE |
+ RADIO_2056_TX0, 0);
+ mod_radio_reg(pi,
+ RADIO_2056_TX_MIXA_BOOST_TUNE |
+ RADIO_2056_TX0, 0xf0, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_MIXG_BOOST_TUNE |
+ RADIO_2056_TX0, 0);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_PADA_BOOST_TUNE |
+ RADIO_2056_TX1, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PADG_BOOST_TUNE |
+ RADIO_2056_TX1, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PGAA_BOOST_TUNE |
+ RADIO_2056_TX1, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_PGAG_BOOST_TUNE |
+ RADIO_2056_TX1, 0);
+ mod_radio_reg(pi,
+ RADIO_2056_TX_MIXA_BOOST_TUNE |
+ RADIO_2056_TX1, 0xf0, 0);
+ write_radio_reg(pi,
+ RADIO_2056_TX_MIXG_BOOST_TUNE |
+ RADIO_2056_TX1, 0);
+
+ pi->radio_is_on = FALSE;
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+ and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+ pi->radio_is_on = FALSE;
+ }
+
+ }
+}
+
+static void wlc_phy_radio_preinit_2055(phy_info_t *pi)
+{
+
+ and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
+ or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
+
+ or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
+}
+
+static void wlc_phy_radio_init_2055(phy_info_t *pi)
+{
+ wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
+}
+
+static void wlc_phy_radio_postinit_2055(phy_info_t *pi)
+{
+
+ and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
+ ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
+
+ if (((pi->sh->sromrev >= 4)
+ && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
+ || ((pi->sh->sromrev < 4))) {
+ and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
+ and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
+ }
+
+ mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
+ write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
+
+ and_radio_reg(pi, RADIO_2055_CAL_MISC,
+ ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
+
+ or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
+
+ or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
+
+ OSL_DELAY(1000);
+
+ or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
+
+ SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+ RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
+
+ ASSERT((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+ RADIO_2055_RCAL_DONE) == RADIO_2055_RCAL_DONE);
+
+ and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
+ ~(RADIO_2055_CAL_LPO_ENABLE));
+
+ wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+
+ write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
+ write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
+
+ write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
+ write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
+
+ mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
+ RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+ mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
+ RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+ if (pi->nphy_gain_boost) {
+ and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+ ~(RADIO_2055_GAINBST_DISABLE));
+ and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+ ~(RADIO_2055_GAINBST_DISABLE));
+ } else {
+ or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+ RADIO_2055_GAINBST_DISABLE);
+ or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+ RADIO_2055_GAINBST_DISABLE);
+ }
+
+ OSL_DELAY(2);
+}
+
+static void wlc_phy_radio_preinit_205x(phy_info_t *pi)
+{
+
+ and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+ and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
+
+ or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
+ or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
+
+}
+
+static void wlc_phy_radio_init_2056(phy_info_t *pi)
+{
+ radio_regs_t *regs_SYN_2056_ptr = NULL;
+ radio_regs_t *regs_TX_2056_ptr = NULL;
+ radio_regs_t *regs_RX_2056_ptr = NULL;
+
+ if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+ regs_SYN_2056_ptr = regs_SYN_2056;
+ regs_TX_2056_ptr = regs_TX_2056;
+ regs_RX_2056_ptr = regs_RX_2056;
+ } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+ regs_SYN_2056_ptr = regs_SYN_2056_A1;
+ regs_TX_2056_ptr = regs_TX_2056_A1;
+ regs_RX_2056_ptr = regs_RX_2056_A1;
+ } else {
+ switch (pi->pubpi.radiorev) {
+ case 5:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+ regs_TX_2056_ptr = regs_TX_2056_rev5;
+ regs_RX_2056_ptr = regs_RX_2056_rev5;
+ break;
+
+ case 6:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+ regs_TX_2056_ptr = regs_TX_2056_rev6;
+ regs_RX_2056_ptr = regs_RX_2056_rev6;
+ break;
+
+ case 7:
+ case 9:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+ regs_TX_2056_ptr = regs_TX_2056_rev7;
+ regs_RX_2056_ptr = regs_RX_2056_rev7;
+ break;
+
+ case 8:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+ regs_TX_2056_ptr = regs_TX_2056_rev8;
+ regs_RX_2056_ptr = regs_RX_2056_rev8;
+ break;
+
+ case 11:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+ regs_TX_2056_ptr = regs_TX_2056_rev11;
+ regs_RX_2056_ptr = regs_RX_2056_rev11;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (uint16) RADIO_2056_SYN);
+
+ wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (uint16) RADIO_2056_TX0);
+
+ wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (uint16) RADIO_2056_TX1);
+
+ wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (uint16) RADIO_2056_RX0);
+
+ wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (uint16) RADIO_2056_RX1);
+}
+
+static void wlc_phy_radio_postinit_2056(phy_info_t *pi)
+{
+ mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
+
+ mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
+ mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
+ OSL_DELAY(1000);
+ mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
+
+ if ((pi->sh->boardflags2 & BFL2_LEGACY)
+ || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) {
+
+ mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
+ } else {
+
+ mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
+ }
+
+ mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
+
+ if (pi->phy_init_por) {
+ wlc_phy_radio205x_rcal(pi);
+ }
+}
+
+static void wlc_phy_radio_init_2057(phy_info_t *pi)
+{
+ radio_20xx_regs_t *regs_2057_ptr = NULL;
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+
+ regs_2057_ptr = regs_2057_rev4;
+ } else if (NREV_IS(pi->pubpi.phy_rev, 8)
+ || NREV_IS(pi->pubpi.phy_rev, 9)) {
+ switch (pi->pubpi.radiorev) {
+ case 5:
+
+ if (pi->pubpi.radiover == 0x0) {
+
+ regs_2057_ptr = regs_2057_rev5;
+
+ } else if (pi->pubpi.radiover == 0x1) {
+
+ regs_2057_ptr = regs_2057_rev5v1;
+ } else {
+ ASSERT(0);
+ break;
+ }
+
+ case 7:
+
+ regs_2057_ptr = regs_2057_rev7;
+ break;
+
+ case 8:
+
+ regs_2057_ptr = regs_2057_rev8;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ } else {
+ ASSERT(0);
+ }
+
+ wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
+}
+
+static void wlc_phy_radio_postinit_2057(phy_info_t *pi)
+{
+
+ mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
+
+ if (CHIPID(pi->sh->chip) == !BCM6362_CHIP_ID) {
+
+ mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2);
+ }
+
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
+ mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
+ OSL_DELAY(2000);
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
+ mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
+
+ if (pi->phy_init_por) {
+ wlc_phy_radio205x_rcal(pi);
+ wlc_phy_radio2057_rccal(pi);
+ }
+
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
+}
+
+static bool
+wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+ chan_info_nphy_radio2057_t **t0,
+ chan_info_nphy_radio205x_t **t1,
+ chan_info_nphy_radio2057_rev5_t **t2,
+ chan_info_nphy_2055_t **t3)
+{
+ uint i;
+ chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL;
+ chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL;
+ chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL;
+ uint32 tbl_len = 0;
+
+ int freq = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+
+ chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev7_2057_rev4);
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 8)
+ || NREV_IS(pi->pubpi.phy_rev, 9)) {
+ switch (pi->pubpi.radiorev) {
+
+ case 5:
+
+ if (pi->pubpi.radiover == 0x0) {
+
+ chan_info_tbl_p_2 =
+ chan_info_nphyrev8_2057_rev5;
+ tbl_len =
+ ARRAYSIZE
+ (chan_info_nphyrev8_2057_rev5);
+
+ } else if (pi->pubpi.radiover == 0x1) {
+
+ chan_info_tbl_p_2 =
+ chan_info_nphyrev9_2057_rev5v1;
+ tbl_len =
+ ARRAYSIZE
+ (chan_info_nphyrev9_2057_rev5v1);
+
+ }
+ break;
+
+ case 7:
+ chan_info_tbl_p_0 =
+ chan_info_nphyrev8_2057_rev7;
+ tbl_len =
+ ARRAYSIZE(chan_info_nphyrev8_2057_rev7);
+ break;
+
+ case 8:
+ chan_info_tbl_p_0 =
+ chan_info_nphyrev8_2057_rev8;
+ tbl_len =
+ ARRAYSIZE(chan_info_nphyrev8_2057_rev8);
+ break;
+
+ default:
+ if (NORADIO_ENAB(pi->pubpi)) {
+ goto fail;
+ }
+ break;
+ }
+ } else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
+
+ chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev8_2057_rev8);
+ } else {
+ goto fail;
+ }
+
+ for (i = 0; i < tbl_len; i++) {
+ if (pi->pubpi.radiorev == 5) {
+
+ if (chan_info_tbl_p_2[i].chan == channel)
+ break;
+ } else {
+
+ if (chan_info_tbl_p_0[i].chan == channel)
+ break;
+ }
+ }
+
+ if (i >= tbl_len) {
+ ASSERT(i < tbl_len);
+ goto fail;
+ }
+ if (pi->pubpi.radiorev == 5) {
+ *t2 = &chan_info_tbl_p_2[i];
+ freq = chan_info_tbl_p_2[i].freq;
+ } else {
+ *t0 = &chan_info_tbl_p_0[i];
+ freq = chan_info_tbl_p_0[i].freq;
+ }
+
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+ chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev3_2056);
+ } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+ chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev4_2056_A1);
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)
+ || NREV_IS(pi->pubpi.phy_rev, 6)) {
+ switch (pi->pubpi.radiorev) {
+ case 5:
+ chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev5_2056v5);
+ break;
+ case 6:
+ chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev6_2056v6);
+ break;
+ case 7:
+ case 9:
+ chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
+ tbl_len =
+ ARRAYSIZE(chan_info_nphyrev5n6_2056v7);
+ break;
+ case 8:
+ chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev6_2056v8);
+ break;
+ case 11:
+ chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
+ tbl_len = ARRAYSIZE(chan_info_nphyrev6_2056v11);
+ break;
+ default:
+ if (NORADIO_ENAB(pi->pubpi)) {
+ goto fail;
+ }
+ break;
+ }
+ }
+
+ for (i = 0; i < tbl_len; i++) {
+ if (chan_info_tbl_p_1[i].chan == channel)
+ break;
+ }
+
+ if (i >= tbl_len) {
+ ASSERT(i < tbl_len);
+ goto fail;
+ }
+ *t1 = &chan_info_tbl_p_1[i];
+ freq = chan_info_tbl_p_1[i].freq;
+
+ } else {
+ for (i = 0; i < ARRAYSIZE(chan_info_nphy_2055); i++)
+ if (chan_info_nphy_2055[i].chan == channel)
+ break;
+
+ if (i >= ARRAYSIZE(chan_info_nphy_2055)) {
+ ASSERT(i < ARRAYSIZE(chan_info_nphy_2055));
+ goto fail;
+ }
+ *t3 = &chan_info_nphy_2055[i];
+ freq = chan_info_nphy_2055[i].freq;
+ }
+
+ *f = freq;
+ return TRUE;
+
+ fail:
+ *f = WL_CHAN_FREQ_RANGE_2G;
+ return FALSE;
+}
+
+uint8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel)
+{
+ int freq;
+ chan_info_nphy_radio2057_t *t0 = NULL;
+ chan_info_nphy_radio205x_t *t1 = NULL;
+ chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+ chan_info_nphy_2055_t *t3 = NULL;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return WL_CHAN_FREQ_RANGE_2G;
+
+ if (channel == 0)
+ channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+
+ wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec))
+ return WL_CHAN_FREQ_RANGE_2G;
+
+ if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) {
+ return WL_CHAN_FREQ_RANGE_5GL;
+ } else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) {
+ return WL_CHAN_FREQ_RANGE_5GM;
+ } else {
+ return WL_CHAN_FREQ_RANGE_5GH;
+ }
+}
+
+static void
+wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci)
+{
+
+ write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
+ write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
+ write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
+ write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
+ write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
+ write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
+ write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
+ write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
+ write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
+ write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
+ ci->RF_core1_lgbuf_a_tune);
+ write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
+ ci->RF_core1_lgbuf_g_tune);
+ write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
+ ci->RF_core1_tx_pga_pad_tn);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
+ ci->RF_core1_tx_mx_bgtrim);
+ write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
+ ci->RF_core2_lgbuf_a_tune);
+ write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
+ ci->RF_core2_lgbuf_g_tune);
+ write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
+ ci->RF_core2_tx_pga_pad_tn);
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
+ ci->RF_core2_tx_mx_bgtrim);
+
+ OSL_DELAY(50);
+
+ write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
+ write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
+
+ WLC_PHY_WAR_PR51571(pi);
+
+ write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
+
+ OSL_DELAY(300);
+}
+
+static void
+wlc_phy_chanspec_radio2056_setup(phy_info_t *pi,
+ const chan_info_nphy_radio205x_t *ci)
+{
+ radio_regs_t *regs_SYN_2056_ptr = NULL;
+
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_vcocal1);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_vcocal2);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
+ ci->RF_SYN_pll_refdiv);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_mmd2);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_mmd1);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_loopfilter1);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_loopfilter2);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_loopfilter3);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_loopfilter4);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
+ ci->RF_SYN_pll_loopfilter5);
+ write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
+ ci->RF_SYN_reserved_addr27);
+ write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
+ ci->RF_SYN_reserved_addr28);
+ write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
+ ci->RF_SYN_reserved_addr29);
+ write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
+ ci->RF_SYN_logen_VCOBUF1);
+ write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
+ ci->RF_SYN_logen_MIXER2);
+ write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
+ ci->RF_SYN_logen_BUF3);
+ write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
+ ci->RF_SYN_logen_BUF4);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
+ ci->RF_RX0_lnaa_tune);
+ write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
+ ci->RF_RX0_lnag_tune);
+ write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_intpaa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_intpag_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_pada_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_padg_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_pgaa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_pgag_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_mixa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
+ ci->RF_TX0_mixg_boost_tune);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
+ ci->RF_RX1_lnaa_tune);
+ write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
+ ci->RF_RX1_lnag_tune);
+ write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_intpaa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_intpag_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_pada_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_padg_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_pgaa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_pgag_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_mixa_boost_tune);
+ write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
+ ci->RF_TX1_mixg_boost_tune);
+
+ if (NREV_IS(pi->pubpi.phy_rev, 3))
+ regs_SYN_2056_ptr = regs_SYN_2056;
+ else if (NREV_IS(pi->pubpi.phy_rev, 4))
+ regs_SYN_2056_ptr = regs_SYN_2056_A1;
+ else {
+ switch (pi->pubpi.radiorev) {
+ case 5:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+ break;
+ case 6:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+ break;
+ case 7:
+ case 9:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+ break;
+ case 8:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+ break;
+ case 11:
+ regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+ break;
+ }
+ }
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+ RADIO_2056_SYN,
+ (uint16) regs_SYN_2056_ptr[0x49 - 2].init_g);
+ } else {
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+ RADIO_2056_SYN,
+ (uint16) regs_SYN_2056_ptr[0x49 - 2].init_a);
+ }
+
+ if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+ RADIO_2056_SYN, 0x1f);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+ RADIO_2056_SYN, 0x1f);
+
+ if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID)) {
+
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_LOOPFILTER4 |
+ RADIO_2056_SYN, 0x14);
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_CP2 |
+ RADIO_2056_SYN, 0x00);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_LOOPFILTER4 |
+ RADIO_2056_SYN, 0xb);
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_CP2 |
+ RADIO_2056_SYN, 0x14);
+ }
+ }
+ }
+
+ if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
+ (CHSPEC_IS2G(pi->radio_chanspec))) {
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+ 0x1f);
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+ 0x1f);
+ write_radio_reg(pi,
+ RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+ 0xb);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
+ 0x20);
+ }
+
+ if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+ RADIO_2056_SYN, 0x1f);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+ RADIO_2056_SYN, 0x1f);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
+ RADIO_2056_SYN, 0x5);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+ RADIO_2056_SYN, 0xc);
+ }
+ }
+
+ if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
+ uint16 pag_boost_tune;
+ uint16 padg_boost_tune;
+ uint16 pgag_boost_tune;
+ uint16 mixg_boost_tune;
+ uint16 bias, cascbias;
+ uint core;
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PADG_IDAC, 0xcc);
+
+ if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) ==
+ BCM47162_CHIP_ID)) {
+ bias = 0x40;
+ cascbias = 0x45;
+ pag_boost_tune = 0x5;
+ pgag_boost_tune = 0x33;
+ padg_boost_tune = 0x77;
+ mixg_boost_tune = 0x55;
+ } else {
+ bias = 0x25;
+ cascbias = 0x20;
+
+ if ((CHIPID(pi->sh->chip) ==
+ BCM43224_CHIP_ID)
+ || (CHIPID(pi->sh->chip) ==
+ BCM43225_CHIP_ID)
+ || (CHIPID(pi->sh->chip) ==
+ BCM43421_CHIP_ID)) {
+ if (pi->sh->chippkg ==
+ BCM43224_FAB_SMIC) {
+ bias = 0x2a;
+ cascbias = 0x38;
+ }
+ }
+
+ pag_boost_tune = 0x4;
+ pgag_boost_tune = 0x03;
+ padg_boost_tune = 0x77;
+ mixg_boost_tune = 0x65;
+ }
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_IMAIN_STAT, bias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_IAUX_STAT, bias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_CASCBIAS, cascbias);
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_BOOST_TUNE,
+ pag_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PGAG_BOOST_TUNE,
+ pgag_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PADG_BOOST_TUNE,
+ padg_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ MIXG_BOOST_TUNE,
+ mixg_boost_tune);
+ } else {
+
+ bias = IS40MHZ(pi) ? 0x40 : 0x20;
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_IMAIN_STAT, bias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_IAUX_STAT, bias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_CASCBIAS, 0x30);
+ }
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
+ 0xee);
+ }
+ }
+
+ if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
+ && CHSPEC_IS5G(pi->radio_chanspec)) {
+ uint16 paa_boost_tune;
+ uint16 pada_boost_tune;
+ uint16 pgaa_boost_tune;
+ uint16 mixa_boost_tune;
+ uint16 freq, pabias, cascbias;
+ uint core;
+
+ freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+
+ if (freq < 5150) {
+
+ paa_boost_tune = 0xa;
+ pada_boost_tune = 0x77;
+ pgaa_boost_tune = 0xf;
+ mixa_boost_tune = 0xf;
+ } else if (freq < 5340) {
+
+ paa_boost_tune = 0x8;
+ pada_boost_tune = 0x77;
+ pgaa_boost_tune = 0xfb;
+ mixa_boost_tune = 0xf;
+ } else if (freq < 5650) {
+
+ paa_boost_tune = 0x0;
+ pada_boost_tune = 0x77;
+ pgaa_boost_tune = 0xb;
+ mixa_boost_tune = 0xf;
+ } else {
+
+ paa_boost_tune = 0x0;
+ pada_boost_tune = 0x77;
+ if (freq != 5825) {
+ pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
+ } else {
+ pgaa_boost_tune = 6;
+ }
+ mixa_boost_tune = 0xf;
+ }
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_BOOST_TUNE, paa_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PADA_BOOST_TUNE, pada_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PGAA_BOOST_TUNE, pgaa_boost_tune);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ MIXA_BOOST_TUNE, mixa_boost_tune);
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TXSPARE1, 0x30);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PA_SPARE2, 0xee);
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ PADA_CASCBIAS, 0x3);
+
+ cascbias = 0x30;
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM43225_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM43421_CHIP_ID)) {
+ if (pi->sh->chippkg == BCM43224_FAB_SMIC) {
+ cascbias = 0x35;
+ }
+ }
+
+ pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_IAUX_STAT, pabias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_IMAIN_STAT, pabias);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_CASCBIAS, cascbias);
+ }
+ }
+
+ OSL_DELAY(50);
+
+ wlc_phy_radio205x_vcocal_nphy(pi);
+}
+
+void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi)
+{
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
+ (1 << 2));
+ mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
+ }
+
+ OSL_DELAY(300);
+}
+
+#define MAX_205x_RCAL_WAITLOOPS 10000
+
+static uint16 wlc_phy_radio205x_rcal(phy_info_t *pi)
+{
+ uint16 rcal_reg = 0;
+ int i;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if (pi->pubpi.radiorev == 5) {
+
+ and_phy_reg(pi, 0x342, ~(0x1 << 1));
+
+ OSL_DELAY(10);
+
+ mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
+ mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+ 0x1);
+ }
+ mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
+
+ OSL_DELAY(10);
+
+ mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
+
+ for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+ rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
+ if (rcal_reg & 0x1) {
+ break;
+ }
+ OSL_DELAY(100);
+ }
+
+ ASSERT(i < MAX_205x_RCAL_WAITLOOPS);
+
+ mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
+
+ rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
+
+ mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
+ if (pi->pubpi.radiorev == 5) {
+
+ mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
+ mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+ 0x0);
+ }
+
+ if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+
+ mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
+ rcal_reg);
+ mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
+ rcal_reg << 2);
+ }
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+ uint16 savereg;
+
+ savereg =
+ read_radio_reg(pi,
+ RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN);
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+ savereg | 0x7);
+ OSL_DELAY(10);
+
+ write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+ 0x1);
+ OSL_DELAY(10);
+
+ write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+ 0x9);
+
+ for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+ rcal_reg = read_radio_reg(pi,
+ RADIO_2056_SYN_RCAL_CODE_OUT |
+ RADIO_2056_SYN);
+ if (rcal_reg & 0x80) {
+ break;
+ }
+ OSL_DELAY(100);
+ }
+
+ ASSERT(i < MAX_205x_RCAL_WAITLOOPS);
+
+ write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+ 0x1);
+
+ rcal_reg =
+ read_radio_reg(pi,
+ RADIO_2056_SYN_RCAL_CODE_OUT |
+ RADIO_2056_SYN);
+
+ write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+ 0x0);
+
+ write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+ savereg);
+
+ return rcal_reg & 0x1f;
+ }
+ return rcal_reg & 0x3e;
+}
+
+static void
+wlc_phy_chanspec_radio2057_setup(phy_info_t *pi,
+ const chan_info_nphy_radio2057_t *ci,
+ const chan_info_nphy_radio2057_rev5_t *ci2)
+{
+ int coreNum;
+ uint16 txmix2g_tune_boost_pu = 0;
+ uint16 pad2g_tune_pus = 0;
+
+ if (pi->pubpi.radiorev == 5) {
+
+ write_radio_reg(pi,
+ RADIO_2057_VCOCAL_COUNTVAL0,
+ ci2->RF_vcocal_countval0);
+ write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+ ci2->RF_vcocal_countval1);
+ write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+ ci2->RF_rfpll_refmaster_sparextalsize);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ ci2->RF_rfpll_loopfilter_r1);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ ci2->RF_rfpll_loopfilter_c2);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ ci2->RF_rfpll_loopfilter_c1);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
+ ci2->RF_cp_kpd_idac);
+ write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
+ write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
+ write_radio_reg(pi,
+ RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
+ write_radio_reg(pi,
+ RADIO_2057_LOGEN_MX2G_TUNE,
+ ci2->RF_logen_mx2g_tune);
+ write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+ ci2->RF_logen_indbuf2g_tune);
+
+ write_radio_reg(pi,
+ RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+ ci2->RF_txmix2g_tune_boost_pu_core0);
+ write_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+ ci2->RF_pad2g_tune_pus_core0);
+ write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+ ci2->RF_lna2g_tune_core0);
+
+ write_radio_reg(pi,
+ RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+ ci2->RF_txmix2g_tune_boost_pu_core1);
+ write_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+ ci2->RF_pad2g_tune_pus_core1);
+ write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+ ci2->RF_lna2g_tune_core1);
+
+ } else {
+
+ write_radio_reg(pi,
+ RADIO_2057_VCOCAL_COUNTVAL0,
+ ci->RF_vcocal_countval0);
+ write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+ ci->RF_vcocal_countval1);
+ write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+ ci->RF_rfpll_refmaster_sparextalsize);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ ci->RF_rfpll_loopfilter_r1);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ ci->RF_rfpll_loopfilter_c2);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ ci->RF_rfpll_loopfilter_c1);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
+ write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
+ write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
+ write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
+ write_radio_reg(pi,
+ RADIO_2057_LOGEN_MX2G_TUNE,
+ ci->RF_logen_mx2g_tune);
+ write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
+ ci->RF_logen_mx5g_tune);
+ write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+ ci->RF_logen_indbuf2g_tune);
+ write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
+ ci->RF_logen_indbuf5g_tune);
+
+ write_radio_reg(pi,
+ RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+ ci->RF_txmix2g_tune_boost_pu_core0);
+ write_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+ ci->RF_pad2g_tune_pus_core0);
+ write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
+ ci->RF_pga_boost_tune_core0);
+ write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
+ ci->RF_txmix5g_boost_tune_core0);
+ write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
+ ci->RF_pad5g_tune_misc_pus_core0);
+ write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+ ci->RF_lna2g_tune_core0);
+ write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
+ ci->RF_lna5g_tune_core0);
+
+ write_radio_reg(pi,
+ RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+ ci->RF_txmix2g_tune_boost_pu_core1);
+ write_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+ ci->RF_pad2g_tune_pus_core1);
+ write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
+ ci->RF_pga_boost_tune_core1);
+ write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
+ ci->RF_txmix5g_boost_tune_core1);
+ write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
+ ci->RF_pad5g_tune_misc_pus_core1);
+ write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+ ci->RF_lna2g_tune_core1);
+ write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
+ ci->RF_lna5g_tune_core1);
+ }
+
+ if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ 0x3f);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ 0x8);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ 0x8);
+ } else {
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ 0x1f);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ 0x8);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ 0x8);
+ }
+ } else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
+ (pi->pubpi.radiorev == 8)) {
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ 0x1b);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ 0xa);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ 0xa);
+ } else {
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+ 0x1f);
+ write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+ 0x8);
+ write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+ 0x8);
+ }
+
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (PHY_IPA(pi)) {
+ if (pi->pubpi.radiorev == 3) {
+ txmix2g_tune_boost_pu = 0x6b;
+ }
+
+ if (pi->pubpi.radiorev == 5)
+ pad2g_tune_pus = 0x73;
+
+ } else {
+ if (pi->pubpi.radiorev != 5) {
+ pad2g_tune_pus = 0x3;
+
+ txmix2g_tune_boost_pu = 0x61;
+ }
+ }
+
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+
+ if (txmix2g_tune_boost_pu != 0)
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+ TXMIX2G_TUNE_BOOST_PU,
+ txmix2g_tune_boost_pu);
+
+ if (pad2g_tune_pus != 0)
+ WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+ PAD2G_TUNE_PUS,
+ pad2g_tune_pus);
+ }
+ }
+
+ OSL_DELAY(50);
+
+ wlc_phy_radio205x_vcocal_nphy(pi);
+}
+
+static uint16 wlc_phy_radio2057_rccal(phy_info_t *pi)
+{
+ uint16 rccal_valid;
+ int i;
+ bool chip43226_6362A0;
+
+ chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
+ || (pi->pubpi.radiorev == 4)
+ || (pi->pubpi.radiorev == 6));
+
+ rccal_valid = 0;
+ if (chip43226_6362A0) {
+ write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
+ } else {
+ write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
+ }
+ write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+
+ for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+ rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+ if (rccal_valid & 0x2) {
+ break;
+ }
+ OSL_DELAY(500);
+ }
+
+ ASSERT(rccal_valid & 0x2);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+
+ rccal_valid = 0;
+ if (chip43226_6362A0) {
+ write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+ } else {
+ write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
+ }
+ write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+
+ for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+ rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+ if (rccal_valid & 0x2) {
+ break;
+ }
+ OSL_DELAY(500);
+ }
+
+ ASSERT(rccal_valid & 0x2);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+
+ rccal_valid = 0;
+ if (chip43226_6362A0) {
+ write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+ } else {
+ write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
+ write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+ write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
+ }
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+
+ for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+ rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+ if (rccal_valid & 0x2) {
+ break;
+ }
+ OSL_DELAY(500);
+ }
+
+ ASSERT(rccal_valid & 0x2);
+
+ write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+
+ return rccal_valid;
+}
+
+static void
+wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, uint16 reduction_factr)
+{
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+ if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+ CHSPEC_IS40(pi->radio_chanspec)) {
+ if (!pi->nphy_anarxlpf_adjusted) {
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_LPC |
+ RADIO_2056_RX0),
+ ((pi->nphy_rccal_value +
+ reduction_factr) | 0x80));
+
+ pi->nphy_anarxlpf_adjusted = TRUE;
+ }
+ } else {
+ if (pi->nphy_anarxlpf_adjusted) {
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_LPC |
+ RADIO_2056_RX0),
+ (pi->nphy_rccal_value | 0x80));
+
+ pi->nphy_anarxlpf_adjusted = FALSE;
+ }
+ }
+ }
+}
+
+static void
+wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf,
+ uint32 *noise_var_buf)
+{
+ int i;
+ uint32 offset;
+ int tone_id;
+ int tbllen =
+ CHSPEC_IS40(pi->
+ radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 :
+ NPHY_NOISEVAR_TBLLEN20;
+
+ if (pi->nphy_noisevars_adjusted) {
+ for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
+ tone_id = pi->nphy_saved_noisevars.tone_id[i];
+ offset = (tone_id >= 0) ?
+ ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ offset, 32,
+ (void *)&pi->
+ nphy_saved_noisevars.
+ min_noise_vars[i]);
+ }
+
+ pi->nphy_saved_noisevars.bufcount = 0;
+ pi->nphy_noisevars_adjusted = FALSE;
+ }
+
+ if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
+ pi->nphy_saved_noisevars.bufcount = 0;
+
+ for (i = 0; i < ntones; i++) {
+ tone_id = tone_id_buf[i];
+ offset = (tone_id >= 0) ?
+ ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+ pi->nphy_saved_noisevars.tone_id[i] = tone_id;
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ offset, 32,
+ &pi->nphy_saved_noisevars.
+ min_noise_vars[i]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+ offset, 32,
+ (void *)&noise_var_buf[i]);
+ pi->nphy_saved_noisevars.bufcount++;
+ }
+
+ pi->nphy_noisevars_adjusted = TRUE;
+ }
+}
+
+static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, uint8 minpwr)
+{
+ uint16 regval;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+ CHSPEC_IS40(pi->radio_chanspec)) {
+ if (!pi->nphy_crsminpwr_adjusted) {
+ regval = read_phy_reg(pi, 0x27d);
+ pi->nphy_crsminpwr[0] = regval & 0xff;
+ regval &= 0xff00;
+ regval |= (uint16) minpwr;
+ write_phy_reg(pi, 0x27d, regval);
+
+ regval = read_phy_reg(pi, 0x280);
+ pi->nphy_crsminpwr[1] = regval & 0xff;
+ regval &= 0xff00;
+ regval |= (uint16) minpwr;
+ write_phy_reg(pi, 0x280, regval);
+
+ regval = read_phy_reg(pi, 0x283);
+ pi->nphy_crsminpwr[2] = regval & 0xff;
+ regval &= 0xff00;
+ regval |= (uint16) minpwr;
+ write_phy_reg(pi, 0x283, regval);
+
+ pi->nphy_crsminpwr_adjusted = TRUE;
+ }
+ } else {
+ if (pi->nphy_crsminpwr_adjusted) {
+ regval = read_phy_reg(pi, 0x27d);
+ regval &= 0xff00;
+ regval |= pi->nphy_crsminpwr[0];
+ write_phy_reg(pi, 0x27d, regval);
+
+ regval = read_phy_reg(pi, 0x280);
+ regval &= 0xff00;
+ regval |= pi->nphy_crsminpwr[1];
+ write_phy_reg(pi, 0x280, regval);
+
+ regval = read_phy_reg(pi, 0x283);
+ regval &= 0xff00;
+ regval |= pi->nphy_crsminpwr[2];
+ write_phy_reg(pi, 0x283, regval);
+
+ pi->nphy_crsminpwr_adjusted = FALSE;
+ }
+ }
+ }
+}
+
+static void wlc_phy_txlpfbw_nphy(phy_info_t *pi)
+{
+ uint8 tx_lpf_bw = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ tx_lpf_bw = 3;
+ } else {
+ tx_lpf_bw = 1;
+ }
+
+ if (PHY_IPA(pi)) {
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ tx_lpf_bw = 5;
+ } else {
+ tx_lpf_bw = 4;
+ }
+ }
+ write_phy_reg(pi, 0xe8,
+ (tx_lpf_bw << 0) |
+ (tx_lpf_bw << 3) |
+ (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+
+ if (PHY_IPA(pi)) {
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ tx_lpf_bw = 4;
+ } else {
+ tx_lpf_bw = 1;
+ }
+
+ write_phy_reg(pi, 0xe9,
+ (tx_lpf_bw << 0) |
+ (tx_lpf_bw << 3) |
+ (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+ }
+ }
+}
+
+static void wlc_phy_spurwar_nphy(phy_info_t *pi)
+{
+ uint16 cur_channel = 0;
+ int nphy_adj_tone_id_buf[] = { 57, 58 };
+ uint32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
+ bool isAdjustNoiseVar = FALSE;
+ uint numTonesAdjust = 0;
+ uint32 tempval = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+
+ if (pi->nphy_gband_spurwar_en) {
+
+ wlc_phy_adjust_rx_analpfbw_nphy(pi,
+ NPHY_ANARXLPFBW_REDUCTIONFACT);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if ((cur_channel == 11)
+ && CHSPEC_IS40(pi->radio_chanspec)) {
+
+ wlc_phy_adjust_min_noisevar_nphy(pi, 2,
+ nphy_adj_tone_id_buf,
+ nphy_adj_noise_var_buf);
+ } else {
+
+ wlc_phy_adjust_min_noisevar_nphy(pi, 0,
+ NULL,
+ NULL);
+ }
+ }
+ wlc_phy_adjust_crsminpwr_nphy(pi,
+ NPHY_ADJUSTED_MINCRSPOWER);
+ }
+
+ if ((pi->nphy_gband_spurwar2_en)
+ && CHSPEC_IS2G(pi->radio_chanspec)) {
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ switch (cur_channel) {
+ case 3:
+ nphy_adj_tone_id_buf[0] = 57;
+ nphy_adj_tone_id_buf[1] = 58;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x25f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 4:
+ nphy_adj_tone_id_buf[0] = 41;
+ nphy_adj_tone_id_buf[1] = 42;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x25f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 5:
+ nphy_adj_tone_id_buf[0] = 25;
+ nphy_adj_tone_id_buf[1] = 26;
+ nphy_adj_noise_var_buf[0] = 0x24f;
+ nphy_adj_noise_var_buf[1] = 0x25f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 6:
+ nphy_adj_tone_id_buf[0] = 9;
+ nphy_adj_tone_id_buf[1] = 10;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x24f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 7:
+ nphy_adj_tone_id_buf[0] = 121;
+ nphy_adj_tone_id_buf[1] = 122;
+ nphy_adj_noise_var_buf[0] = 0x18f;
+ nphy_adj_noise_var_buf[1] = 0x24f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 8:
+ nphy_adj_tone_id_buf[0] = 105;
+ nphy_adj_tone_id_buf[1] = 106;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x25f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 9:
+ nphy_adj_tone_id_buf[0] = 89;
+ nphy_adj_tone_id_buf[1] = 90;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x24f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ case 10:
+ nphy_adj_tone_id_buf[0] = 73;
+ nphy_adj_tone_id_buf[1] = 74;
+ nphy_adj_noise_var_buf[0] = 0x22f;
+ nphy_adj_noise_var_buf[1] = 0x24f;
+ isAdjustNoiseVar = TRUE;
+ break;
+ default:
+ isAdjustNoiseVar = FALSE;
+ break;
+ }
+ }
+
+ if (isAdjustNoiseVar) {
+ numTonesAdjust = sizeof(nphy_adj_tone_id_buf) /
+ sizeof(nphy_adj_tone_id_buf[0]);
+
+ wlc_phy_adjust_min_noisevar_nphy(pi,
+ numTonesAdjust,
+ nphy_adj_tone_id_buf,
+ nphy_adj_noise_var_buf);
+
+ tempval = 0;
+
+ } else {
+
+ wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+ NULL);
+ }
+ }
+
+ if ((pi->nphy_aband_spurwar_en) &&
+ (CHSPEC_IS5G(pi->radio_chanspec))) {
+ switch (cur_channel) {
+ case 54:
+ nphy_adj_tone_id_buf[0] = 32;
+ nphy_adj_noise_var_buf[0] = 0x25f;
+ break;
+ case 38:
+ case 102:
+ case 118:
+ if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) &&
+ (pi->sh->chippkg == BCM4717_PKG_ID)) {
+ nphy_adj_tone_id_buf[0] = 32;
+ nphy_adj_noise_var_buf[0] = 0x21f;
+ } else {
+ nphy_adj_tone_id_buf[0] = 0;
+ nphy_adj_noise_var_buf[0] = 0x0;
+ }
+ break;
+ case 134:
+ nphy_adj_tone_id_buf[0] = 32;
+ nphy_adj_noise_var_buf[0] = 0x21f;
+ break;
+ case 151:
+ nphy_adj_tone_id_buf[0] = 16;
+ nphy_adj_noise_var_buf[0] = 0x23f;
+ break;
+ case 153:
+ case 161:
+ nphy_adj_tone_id_buf[0] = 48;
+ nphy_adj_noise_var_buf[0] = 0x23f;
+ break;
+ default:
+ nphy_adj_tone_id_buf[0] = 0;
+ nphy_adj_noise_var_buf[0] = 0x0;
+ break;
+ }
+
+ if (nphy_adj_tone_id_buf[0]
+ && nphy_adj_noise_var_buf[0]) {
+ wlc_phy_adjust_min_noisevar_nphy(pi, 1,
+ nphy_adj_tone_id_buf,
+ nphy_adj_noise_var_buf);
+ } else {
+ wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+ NULL);
+ }
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+ }
+}
+
+static void
+wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec,
+ const nphy_sfo_cfg_t *ci)
+{
+ uint16 val;
+
+ val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+ if (CHSPEC_IS5G(chanspec) && !val) {
+
+ val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param);
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param,
+ (val | MAC_PHY_FORCE_CLK));
+
+ or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+ (BBCFG_RESETCCA | BBCFG_RESETRX));
+
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val);
+
+ or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
+ } else if (!CHSPEC_IS5G(chanspec) && val) {
+
+ and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
+
+ val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param);
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param,
+ (val | MAC_PHY_FORCE_CLK));
+
+ and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+ (uint16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
+
+ W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val);
+ }
+
+ write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
+ write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
+ write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
+
+ write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
+ write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
+ write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
+
+ if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+ wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
+
+ or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
+ } else {
+ wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
+ NPHY_ClassifierCtrl_ofdm_en);
+
+ if (CHSPEC_IS2G(chanspec))
+ and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
+ }
+
+ if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+ wlc_phy_txpwr_fixpower_nphy(pi);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+
+ wlc_phy_adjust_lnagaintbl_nphy(pi);
+ }
+
+ wlc_phy_txlpfbw_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)
+ && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
+ uint8 spuravoid = 0;
+
+ val = CHSPEC_CHANNEL(chanspec);
+ if (!CHSPEC_IS40(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if ((val == 13) || (val == 14) || (val == 153)) {
+ spuravoid = 1;
+ }
+ } else {
+
+ if (((val >= 5) && (val <= 8)) || (val == 13)
+ || (val == 14)) {
+ spuravoid = 1;
+ }
+ }
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (val == 54) {
+ spuravoid = 1;
+ }
+ } else {
+
+ if (pi->nphy_aband_spurwar_en &&
+ ((val == 38) || (val == 102)
+ || (val == 118))) {
+ if ((CHIPID(pi->sh->chip) ==
+ BCM4716_CHIP_ID)
+ && (pi->sh->chippkg ==
+ BCM4717_PKG_ID)) {
+ spuravoid = 0;
+ } else {
+ spuravoid = 1;
+ }
+ }
+ }
+ }
+
+ if (pi->phy_spuravoid == SPURAVOID_FORCEON)
+ spuravoid = 1;
+
+ if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID)) {
+ si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid);
+ } else {
+ wlapi_bmac_core_phypll_ctl(pi->sh->physhim, FALSE);
+ si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid);
+ wlapi_bmac_core_phypll_ctl(pi->sh->physhim, TRUE);
+ }
+
+ if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM43225_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM43421_CHIP_ID)) {
+
+ if (spuravoid == 1) {
+
+ W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l,
+ 0x5341);
+ W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h,
+ 0x8);
+ } else {
+
+ W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l,
+ 0x8889);
+ W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h,
+ 0x8);
+ }
+ }
+
+ if (!((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) ||
+ (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID))) {
+ wlapi_bmac_core_phypll_reset(pi->sh->physhim);
+ }
+
+ mod_phy_reg(pi, 0x01, (0x1 << 15),
+ ((spuravoid > 0) ? (0x1 << 15) : 0));
+
+ wlc_phy_resetcca_nphy(pi);
+
+ pi->phy_isspuravoid = (spuravoid > 0);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 7))
+ write_phy_reg(pi, 0x17e, 0x3830);
+
+ wlc_phy_spurwar_nphy(pi);
+}
+
+void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec)
+{
+ int freq;
+ chan_info_nphy_radio2057_t *t0 = NULL;
+ chan_info_nphy_radio205x_t *t1 = NULL;
+ chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+ chan_info_nphy_2055_t *t3 = NULL;
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+ return;
+ }
+
+ if (!wlc_phy_chan2freq_nphy
+ (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
+ return;
+
+ wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+
+ if (CHSPEC_BW(chanspec) != pi->bw)
+ wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
+
+ if (CHSPEC_IS40(chanspec)) {
+ if (CHSPEC_SB_UPPER(chanspec)) {
+ or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
+ }
+ } else {
+ and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ and_phy_reg(pi, 0x310,
+ (~PRIM_SEL_UP20 & 0xffff));
+ }
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if ((pi->pubpi.radiorev <= 4)
+ || (pi->pubpi.radiorev == 6)) {
+ mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
+ 0x2,
+ (CHSPEC_IS5G(chanspec) ? (1 << 1)
+ : 0));
+ mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
+ 0x2,
+ (CHSPEC_IS5G(chanspec) ? (1 << 1)
+ : 0));
+ }
+
+ wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
+ wlc_phy_chanspec_nphy_setup(pi, chanspec,
+ (pi->pubpi.radiorev ==
+ 5) ? (const nphy_sfo_cfg_t
+ *)&(t2->
+ PHY_BW1a)
+ : (const nphy_sfo_cfg_t *)
+ &(t0->PHY_BW1a));
+
+ } else {
+
+ mod_radio_reg(pi,
+ RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
+ 0x4,
+ (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
+ wlc_phy_chanspec_radio2056_setup(pi, t1);
+
+ wlc_phy_chanspec_nphy_setup(pi, chanspec,
+ (const nphy_sfo_cfg_t *)
+ &(t1->PHY_BW1a));
+ }
+
+ } else {
+
+ mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
+ (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
+ : (0x05 << 4)));
+
+ wlc_phy_chanspec_radio2055_setup(pi, t3);
+ wlc_phy_chanspec_nphy_setup(pi, chanspec,
+ (const nphy_sfo_cfg_t *)&(t3->
+ PHY_BW1a));
+ }
+
+}
+
+static void wlc_phy_savecal_nphy(phy_info_t *pi)
+{
+ void *tbl_ptr;
+ int coreNum;
+ uint16 *txcal_radio_regs = NULL;
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+ &pi->calibration_cache.
+ rxcal_coeffs_2G);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ txcal_radio_regs =
+ pi->calibration_cache.txcal_radio_regs_2G;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ pi->calibration_cache.txcal_radio_regs_2G[0] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_2G[1] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_2G[2] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX1);
+ pi->calibration_cache.txcal_radio_regs_2G[3] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX1);
+
+ pi->calibration_cache.txcal_radio_regs_2G[4] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_2G[5] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_2G[6] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX1);
+ pi->calibration_cache.txcal_radio_regs_2G[7] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX1);
+ } else {
+ pi->calibration_cache.txcal_radio_regs_2G[0] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+ pi->calibration_cache.txcal_radio_regs_2G[1] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+ pi->calibration_cache.txcal_radio_regs_2G[2] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+ pi->calibration_cache.txcal_radio_regs_2G[3] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+ }
+
+ pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
+ tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+ } else {
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+ &pi->calibration_cache.
+ rxcal_coeffs_5G);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ txcal_radio_regs =
+ pi->calibration_cache.txcal_radio_regs_5G;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ pi->calibration_cache.txcal_radio_regs_5G[0] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_5G[1] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_5G[2] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX1);
+ pi->calibration_cache.txcal_radio_regs_5G[3] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX1);
+
+ pi->calibration_cache.txcal_radio_regs_5G[4] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_5G[5] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX0);
+ pi->calibration_cache.txcal_radio_regs_5G[6] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX1);
+ pi->calibration_cache.txcal_radio_regs_5G[7] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX1);
+ } else {
+ pi->calibration_cache.txcal_radio_regs_5G[0] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+ pi->calibration_cache.txcal_radio_regs_5G[1] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+ pi->calibration_cache.txcal_radio_regs_5G[2] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+ pi->calibration_cache.txcal_radio_regs_5G[3] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+ }
+
+ pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
+ tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+ }
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+
+ txcal_radio_regs[2 * coreNum] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_FINE_I);
+ txcal_radio_regs[2 * coreNum + 1] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_FINE_Q);
+
+ txcal_radio_regs[2 * coreNum + 4] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_COARSE_I);
+ txcal_radio_regs[2 * coreNum + 5] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_COARSE_Q);
+ }
+ }
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void wlc_phy_restorecal_nphy(phy_info_t *pi)
+{
+ uint16 *loft_comp;
+ uint16 txcal_coeffs_bphy[4];
+ uint16 *tbl_ptr;
+ int coreNum;
+ uint16 *txcal_radio_regs = NULL;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->nphy_iqcal_chanspec_2G == 0)
+ return;
+
+ tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+ loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
+ } else {
+ if (pi->nphy_iqcal_chanspec_5G == 0)
+ return;
+
+ tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+ loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16,
+ (void *)tbl_ptr);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ txcal_coeffs_bphy[0] = tbl_ptr[0];
+ txcal_coeffs_bphy[1] = tbl_ptr[1];
+ txcal_coeffs_bphy[2] = tbl_ptr[2];
+ txcal_coeffs_bphy[3] = tbl_ptr[3];
+ } else {
+ txcal_coeffs_bphy[0] = 0;
+ txcal_coeffs_bphy[1] = 0;
+ txcal_coeffs_bphy[2] = 0;
+ txcal_coeffs_bphy[3] = 0;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
+ txcal_coeffs_bphy);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2))
+ wlc_phy_tx_iq_war_nphy(pi);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ txcal_radio_regs =
+ pi->calibration_cache.txcal_radio_regs_2G;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[0]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[1]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[2]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[3]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[4]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[5]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[6]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[7]);
+ } else {
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[0]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[1]);
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[2]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+ pi->calibration_cache.
+ txcal_radio_regs_2G[3]);
+ }
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+ &pi->calibration_cache.
+ rxcal_coeffs_2G);
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ txcal_radio_regs =
+ pi->calibration_cache.txcal_radio_regs_5G;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[0]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[1]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_I |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[2]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_FINE_Q |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[3]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[4]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX0,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[5]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_I |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[6]);
+ write_radio_reg(pi,
+ RADIO_2056_TX_LOFT_COARSE_Q |
+ RADIO_2056_TX1,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[7]);
+ } else {
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[0]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[1]);
+ write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[2]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+ pi->calibration_cache.
+ txcal_radio_regs_5G[3]);
+ }
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+ &pi->calibration_cache.
+ rxcal_coeffs_5G);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (coreNum = 0; coreNum <= 1; coreNum++) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_FINE_I,
+ txcal_radio_regs[2 * coreNum]);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_FINE_Q,
+ txcal_radio_regs[2 * coreNum + 1]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_COARSE_I,
+ txcal_radio_regs[2 * coreNum + 4]);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+ LOFT_COARSE_Q,
+ txcal_radio_regs[2 * coreNum + 5]);
+ }
+ }
+}
+
+void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init)
+{
+ phy_info_t *pi = (phy_info_t *) ppi;
+ uint16 mask = 0xfc00;
+ uint32 mc = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7))
+ return;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ uint16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
+
+ if (lut_init == FALSE)
+ return;
+
+ if (pi->srom_fem2g.antswctrllut == 0) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x02, 16, &v0);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x03, 16, &v1);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x08, 16, &v2);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x0C, 16, &v3);
+ } else {
+ ASSERT(0);
+ }
+
+ if (pi->srom_fem5g.antswctrllut == 0) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x12, 16, &v0);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x13, 16, &v1);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x18, 16, &v2);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+ 1, 0x1C, 16, &v3);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+
+ write_phy_reg(pi, 0xc8, 0x0);
+ write_phy_reg(pi, 0xc9, 0x0);
+
+ si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
+
+ mc = R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ mc &= ~MCTL_GPOUT_SEL_MASK;
+ W_REG(pi->sh->osh, &pi->regs->maccontrol, mc);
+
+ OR_REG(pi->sh->osh, &pi->regs->psm_gpio_oe, mask);
+
+ AND_REG(pi->sh->osh, &pi->regs->psm_gpio_out, ~mask);
+
+ if (lut_init) {
+ write_phy_reg(pi, 0xf8, 0x02d8);
+ write_phy_reg(pi, 0xf9, 0x0301);
+ write_phy_reg(pi, 0xfa, 0x02d8);
+ write_phy_reg(pi, 0xfb, 0x0301);
+ }
+ }
+}
+
+uint16 wlc_phy_classifier_nphy(phy_info_t *pi, uint16 mask, uint16 val)
+{
+ uint16 curr_ctl, new_ctl;
+ bool suspended = FALSE;
+
+ if (D11REV_IS(pi->sh->corerev, 16)) {
+ suspended =
+ (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) ?
+ FALSE : TRUE;
+ if (!suspended)
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ }
+
+ curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
+
+ new_ctl = (curr_ctl & (~mask)) | (val & mask);
+
+ mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
+
+ if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
+ wlapi_enable_mac(pi->sh->physhim);
+
+ return new_ctl;
+}
+
+static void wlc_phy_clip_det_nphy(phy_info_t *pi, uint8 write, uint16 *vals)
+{
+
+ if (write == 0) {
+ vals[0] = read_phy_reg(pi, 0x2c);
+ vals[1] = read_phy_reg(pi, 0x42);
+ } else {
+ write_phy_reg(pi, 0x2c, vals[0]);
+ write_phy_reg(pi, 0x42, vals[1]);
+ }
+}
+
+void wlc_phy_force_rfseq_nphy(phy_info_t *pi, uint8 cmd)
+{
+ uint16 trigger_mask, status_mask;
+ uint16 orig_RfseqCoreActv;
+
+ switch (cmd) {
+ case NPHY_RFSEQ_RX2TX:
+ trigger_mask = NPHY_RfseqTrigger_rx2tx;
+ status_mask = NPHY_RfseqStatus_rx2tx;
+ break;
+ case NPHY_RFSEQ_TX2RX:
+ trigger_mask = NPHY_RfseqTrigger_tx2rx;
+ status_mask = NPHY_RfseqStatus_tx2rx;
+ break;
+ case NPHY_RFSEQ_RESET2RX:
+ trigger_mask = NPHY_RfseqTrigger_reset2rx;
+ status_mask = NPHY_RfseqStatus_reset2rx;
+ break;
+ case NPHY_RFSEQ_UPDATEGAINH:
+ trigger_mask = NPHY_RfseqTrigger_updategainh;
+ status_mask = NPHY_RfseqStatus_updategainh;
+ break;
+ case NPHY_RFSEQ_UPDATEGAINL:
+ trigger_mask = NPHY_RfseqTrigger_updategainl;
+ status_mask = NPHY_RfseqStatus_updategainl;
+ break;
+ case NPHY_RFSEQ_UPDATEGAINU:
+ trigger_mask = NPHY_RfseqTrigger_updategainu;
+ status_mask = NPHY_RfseqStatus_updategainu;
+ break;
+ default:
+ return;
+ }
+
+ orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+ or_phy_reg(pi, 0xa1,
+ (NPHY_RfseqMode_CoreActv_override |
+ NPHY_RfseqMode_Trigger_override));
+ or_phy_reg(pi, 0xa3, trigger_mask);
+ SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
+ write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+
+ ASSERT((read_phy_reg(pi, 0xa4) & status_mask) == 0);
+}
+
+static void
+wlc_phy_set_rfseq_nphy(phy_info_t *pi, uint8 cmd, uint8 *events, uint8 *dlys,
+ uint8 len)
+{
+ uint32 t1_offset, t2_offset;
+ uint8 ctr;
+ uint8 end_event =
+ NREV_GE(pi->pubpi.phy_rev,
+ 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
+ uint8 end_dly = 1;
+
+ ASSERT(len <= 16);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ t1_offset = cmd << 4;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
+ events);
+ t2_offset = t1_offset + 0x080;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
+ dlys);
+
+ for (ctr = len; ctr < 16; ctr++) {
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+ t1_offset + ctr, 8, &end_event);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+ t2_offset + ctr, 8, &end_dly);
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static uint16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, uint16 offset)
+{
+ uint16 lpf_bw_ctl_val = 0;
+ uint16 rx2tx_lpf_rc_lut_offset = 0;
+
+ if (offset == 0) {
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ rx2tx_lpf_rc_lut_offset = 0x159;
+ } else {
+ rx2tx_lpf_rc_lut_offset = 0x154;
+ }
+ } else {
+ rx2tx_lpf_rc_lut_offset = offset;
+ }
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+ (uint32) rx2tx_lpf_rc_lut_offset, 16,
+ &lpf_bw_ctl_val);
+
+ lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
+
+ return lpf_bw_ctl_val;
+}
+
+static void
+wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, uint16 field, uint16 value,
+ uint8 core_mask, uint8 off, uint8 override_id)
+{
+ uint8 core_num;
+ uint16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
+ uint8 val_shift = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ en_mask = field;
+ for (core_num = 0; core_num < 2; core_num++) {
+ if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
+
+ switch (field) {
+ case (0x1 << 2):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 1);
+ val_shift = 1;
+ break;
+ case (0x1 << 3):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 2);
+ val_shift = 2;
+ break;
+ case (0x1 << 4):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 4);
+ val_shift = 4;
+ break;
+ case (0x1 << 5):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 5);
+ val_shift = 5;
+ break;
+ case (0x1 << 6):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 6);
+ val_shift = 6;
+ break;
+ case (0x1 << 7):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a :
+ 0x7d;
+ val_mask = (0x1 << 7);
+ val_shift = 7;
+ break;
+ case (0x1 << 10):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0xf8 :
+ 0xfa;
+ val_mask = (0x7 << 4);
+ val_shift = 4;
+ break;
+ case (0x1 << 11):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7b :
+ 0x7e;
+ val_mask = (0xffff << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 12):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7c :
+ 0x7f;
+ val_mask = (0xffff << 0);
+ val_shift = 0;
+ break;
+ case (0x3 << 13):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x348 :
+ 0x349;
+ val_mask = (0xff << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 13):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x348 :
+ 0x349;
+ val_mask = (0xf << 0);
+ val_shift = 0;
+ break;
+ default:
+ addr = 0xffff;
+ break;
+ }
+ } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) {
+
+ switch (field) {
+ case (0x1 << 1):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 1);
+ val_shift = 1;
+ break;
+ case (0x1 << 3):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 3);
+ val_shift = 3;
+ break;
+ case (0x1 << 5):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 5);
+ val_shift = 5;
+ break;
+ case (0x1 << 4):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 4);
+ val_shift = 4;
+ break;
+ case (0x1 << 2):
+
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 2);
+ val_shift = 2;
+ break;
+ case (0x1 << 7):
+
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x7 << 8);
+ val_shift = 8;
+ break;
+ case (0x1 << 11):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 14);
+ val_shift = 14;
+ break;
+ case (0x1 << 10):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 13);
+ val_shift = 13;
+ break;
+ case (0x1 << 9):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 12);
+ val_shift = 12;
+ break;
+ case (0x1 << 8):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 11);
+ val_shift = 11;
+ break;
+ case (0x1 << 6):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 6);
+ val_shift = 6;
+ break;
+ case (0x1 << 0):
+ en_addr = (core_num == 0) ? 0x342 :
+ 0x343;
+ val_addr = (core_num == 0) ? 0x340 :
+ 0x341;
+ val_mask = (0x1 << 0);
+ val_shift = 0;
+ break;
+ default:
+ addr = 0xffff;
+ break;
+ }
+ } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) {
+
+ switch (field) {
+ case (0x1 << 3):
+ en_addr = (core_num == 0) ? 0x346 :
+ 0x347;
+ val_addr = (core_num == 0) ? 0x344 :
+ 0x345;
+ val_mask = (0x1 << 3);
+ val_shift = 3;
+ break;
+ case (0x1 << 1):
+ en_addr = (core_num == 0) ? 0x346 :
+ 0x347;
+ val_addr = (core_num == 0) ? 0x344 :
+ 0x345;
+ val_mask = (0x1 << 1);
+ val_shift = 1;
+ break;
+ case (0x1 << 0):
+ en_addr = (core_num == 0) ? 0x346 :
+ 0x347;
+ val_addr = (core_num == 0) ? 0x344 :
+ 0x345;
+ val_mask = (0x1 << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 2):
+ en_addr = (core_num == 0) ? 0x346 :
+ 0x347;
+ val_addr = (core_num == 0) ? 0x344 :
+ 0x345;
+ val_mask = (0x1 << 2);
+ val_shift = 2;
+ break;
+ case (0x1 << 4):
+ en_addr = (core_num == 0) ? 0x346 :
+ 0x347;
+ val_addr = (core_num == 0) ? 0x344 :
+ 0x345;
+ val_mask = (0x1 << 4);
+ val_shift = 4;
+ break;
+ default:
+ addr = 0xffff;
+ break;
+ }
+ }
+
+ if (off) {
+ and_phy_reg(pi, en_addr, ~en_mask);
+ and_phy_reg(pi, val_addr, ~val_mask);
+ } else {
+
+ if ((core_mask == 0)
+ || (core_mask & (1 << core_num))) {
+ or_phy_reg(pi, en_addr, en_mask);
+
+ if (addr != 0xffff) {
+ mod_phy_reg(pi, val_addr,
+ val_mask,
+ (value <<
+ val_shift));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+wlc_phy_rfctrl_override_nphy(phy_info_t *pi, uint16 field, uint16 value,
+ uint8 core_mask, uint8 off)
+{
+ uint8 core_num;
+ uint16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
+ 0, val_mask = 0;
+ uint8 shift = 0, val_shift = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ en_mask = field;
+ for (core_num = 0; core_num < 2; core_num++) {
+
+ switch (field) {
+ case (0x1 << 1):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 2):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 1);
+ val_shift = 1;
+ break;
+ case (0x1 << 3):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 2);
+ val_shift = 2;
+ break;
+ case (0x1 << 4):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 4);
+ val_shift = 4;
+ break;
+ case (0x1 << 5):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 5);
+ val_shift = 5;
+ break;
+ case (0x1 << 6):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 6);
+ val_shift = 6;
+ break;
+ case (0x1 << 7):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x1 << 7);
+ val_shift = 7;
+ break;
+ case (0x1 << 8):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x7 << 8);
+ val_shift = 8;
+ break;
+ case (0x1 << 11):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7a : 0x7d;
+ val_mask = (0x7 << 13);
+ val_shift = 13;
+ break;
+
+ case (0x1 << 9):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+ val_mask = (0x7 << 0);
+ val_shift = 0;
+ break;
+
+ case (0x1 << 10):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+ val_mask = (0x7 << 4);
+ val_shift = 4;
+ break;
+
+ case (0x1 << 12):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7b : 0x7e;
+ val_mask = (0xffff << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 13):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0x7c : 0x7f;
+ val_mask = (0xffff << 0);
+ val_shift = 0;
+ break;
+ case (0x1 << 14):
+ en_addr = (core_num == 0) ? 0xe7 : 0xec;
+ val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+ val_mask = (0x3 << 6);
+ val_shift = 6;
+ break;
+ case (0x1 << 0):
+ en_addr = (core_num == 0) ? 0xe5 : 0xe6;
+ val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+ val_mask = (0x1 << 15);
+ val_shift = 15;
+ break;
+ default:
+ addr = 0xffff;
+ break;
+ }
+
+ if (off) {
+ and_phy_reg(pi, en_addr, ~en_mask);
+ and_phy_reg(pi, val_addr, ~val_mask);
+ } else {
+
+ if ((core_mask == 0)
+ || (core_mask & (1 << core_num))) {
+ or_phy_reg(pi, en_addr, en_mask);
+
+ if (addr != 0xffff) {
+ mod_phy_reg(pi, val_addr,
+ val_mask,
+ (value <<
+ val_shift));
+ }
+ }
+ }
+ }
+ } else {
+
+ if (off) {
+ and_phy_reg(pi, 0xec, ~field);
+ value = 0x0;
+ } else {
+ or_phy_reg(pi, 0xec, field);
+ }
+
+ for (core_num = 0; core_num < 2; core_num++) {
+
+ switch (field) {
+ case (0x1 << 1):
+ case (0x1 << 9):
+ case (0x1 << 12):
+ case (0x1 << 13):
+ case (0x1 << 14):
+ addr = 0x78;
+
+ core_mask = 0x1;
+ break;
+ case (0x1 << 2):
+ case (0x1 << 3):
+ case (0x1 << 4):
+ case (0x1 << 5):
+ case (0x1 << 6):
+ case (0x1 << 7):
+ case (0x1 << 8):
+ addr = (core_num == 0) ? 0x7a : 0x7d;
+ break;
+ case (0x1 << 10):
+ addr = (core_num == 0) ? 0x7b : 0x7e;
+ break;
+ case (0x1 << 11):
+ addr = (core_num == 0) ? 0x7c : 0x7f;
+ break;
+ default:
+ addr = 0xffff;
+ }
+
+ switch (field) {
+ case (0x1 << 1):
+ mask = (0x7 << 3);
+ shift = 3;
+ break;
+ case (0x1 << 9):
+ mask = (0x1 << 2);
+ shift = 2;
+ break;
+ case (0x1 << 12):
+ mask = (0x1 << 8);
+ shift = 8;
+ break;
+ case (0x1 << 13):
+ mask = (0x1 << 9);
+ shift = 9;
+ break;
+ case (0x1 << 14):
+ mask = (0xf << 12);
+ shift = 12;
+ break;
+ case (0x1 << 2):
+ mask = (0x1 << 0);
+ shift = 0;
+ break;
+ case (0x1 << 3):
+ mask = (0x1 << 1);
+ shift = 1;
+ break;
+ case (0x1 << 4):
+ mask = (0x1 << 2);
+ shift = 2;
+ break;
+ case (0x1 << 5):
+ mask = (0x3 << 4);
+ shift = 4;
+ break;
+ case (0x1 << 6):
+ mask = (0x3 << 6);
+ shift = 6;
+ break;
+ case (0x1 << 7):
+ mask = (0x1 << 8);
+ shift = 8;
+ break;
+ case (0x1 << 8):
+ mask = (0x1 << 9);
+ shift = 9;
+ break;
+ case (0x1 << 10):
+ mask = 0x1fff;
+ shift = 0x0;
+ break;
+ case (0x1 << 11):
+ mask = 0x1fff;
+ shift = 0x0;
+ break;
+ default:
+ mask = 0x0;
+ shift = 0x0;
+ break;
+ }
+
+ if ((addr != 0xffff) && (core_mask & (1 << core_num))) {
+ mod_phy_reg(pi, addr, mask, (value << shift));
+ }
+ }
+
+ or_phy_reg(pi, 0xec, (0x1 << 0));
+ or_phy_reg(pi, 0x78, (0x1 << 0));
+ OSL_DELAY(1);
+ and_phy_reg(pi, 0xec, ~(0x1 << 0));
+ }
+}
+
+static void
+wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, uint16 cmd, uint16 value,
+ uint8 core_mask, uint8 off)
+{
+ uint16 rfmxgain = 0, lpfgain = 0;
+ uint16 tgain = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ switch (cmd) {
+ case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+ value, core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ break;
+ case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+ value, core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ break;
+ case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+ value, core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1,
+ core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ break;
+ case NPHY_REV7_RfctrlOverride_cmd_rxgain:
+ rfmxgain = value & 0x000ff;
+ lpfgain = value & 0x0ff00;
+ lpfgain = lpfgain >> 8;
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+ rfmxgain, core_mask,
+ off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13),
+ lpfgain, core_mask,
+ off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ break;
+ case NPHY_REV7_RfctrlOverride_cmd_txgain:
+ tgain = value & 0x7fff;
+ lpfgain = value & 0x8000;
+ lpfgain = lpfgain >> 14;
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+ tgain, core_mask, off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13),
+ lpfgain, core_mask,
+ off,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ break;
+ }
+ }
+}
+
+static void
+wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, uint16 scale, int8 offset,
+ uint8 coresel, uint8 rail, uint8 rssi_type)
+{
+ uint16 valuetostuff;
+
+ offset = (offset > NPHY_RSSICAL_MAXREAD) ?
+ NPHY_RSSICAL_MAXREAD : offset;
+ offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
+ -NPHY_RSSICAL_MAXREAD - 1 : offset;
+
+ valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+ write_phy_reg(pi, 0x1a6, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+ write_phy_reg(pi, 0x1ac, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+ write_phy_reg(pi, 0x1b2, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+ write_phy_reg(pi, 0x1b8, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+ write_phy_reg(pi, 0x1a4, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+ write_phy_reg(pi, 0x1aa, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+ write_phy_reg(pi, 0x1b0, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+ write_phy_reg(pi, 0x1b6, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+ write_phy_reg(pi, 0x1a5, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+ write_phy_reg(pi, 0x1ab, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+ write_phy_reg(pi, 0x1b1, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+ write_phy_reg(pi, 0x1b7, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+ write_phy_reg(pi, 0x1a7, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+ write_phy_reg(pi, 0x1ad, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+ write_phy_reg(pi, 0x1b3, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+ write_phy_reg(pi, 0x1b9, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+ write_phy_reg(pi, 0x1a8, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+ write_phy_reg(pi, 0x1ae, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+ write_phy_reg(pi, 0x1b4, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+ write_phy_reg(pi, 0x1ba, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+ write_phy_reg(pi, 0x1a9, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+ write_phy_reg(pi, 0x1b5, valuetostuff);
+ }
+
+ if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+ write_phy_reg(pi, 0x1af, valuetostuff);
+ }
+ if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+ (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+ (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+ write_phy_reg(pi, 0x1bb, valuetostuff);
+ }
+}
+
+void wlc_phy_rssisel_nphy(phy_info_t *pi, uint8 core_code, uint8 rssi_type)
+{
+ uint16 mask, val;
+ uint16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
+ startseq;
+ uint16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
+ rfctrlovr_trigger_val;
+ uint16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
+ uint16 rfctrlcmd_val, rfctrlovr_val;
+ uint8 core;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (core_code == RADIO_MIMO_CORESEL_OFF) {
+ mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
+ mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
+
+ mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
+ mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
+
+ mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
+ mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
+
+ mask = (0x1 << 2) |
+ (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
+ mod_phy_reg(pi, 0xf9, mask, 0);
+ mod_phy_reg(pi, 0xfb, mask, 0);
+
+ } else {
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (core_code == RADIO_MIMO_CORESEL_CORE1
+ && core == PHY_CORE_1)
+ continue;
+ else if (core_code == RADIO_MIMO_CORESEL_CORE2
+ && core == PHY_CORE_0)
+ continue;
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0x8f : 0xa5, (0x1 << 9), 1 << 9);
+
+ if (rssi_type == NPHY_RSSI_SEL_W1 ||
+ rssi_type == NPHY_RSSI_SEL_W2 ||
+ rssi_type == NPHY_RSSI_SEL_NB) {
+
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6 : 0xa7,
+ (0x3 << 8), 0);
+
+ mask = (0x1 << 2) |
+ (0x1 << 3) |
+ (0x1 << 4) | (0x1 << 5);
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xf9 : 0xfb,
+ mask, 0);
+
+ if (rssi_type == NPHY_RSSI_SEL_W1) {
+ if (CHSPEC_IS5G
+ (pi->radio_chanspec)) {
+ mask = (0x1 << 2);
+ val = 1 << 2;
+ } else {
+ mask = (0x1 << 3);
+ val = 1 << 3;
+ }
+ } else if (rssi_type ==
+ NPHY_RSSI_SEL_W2) {
+ mask = (0x1 << 4);
+ val = 1 << 4;
+ } else {
+ mask = (0x1 << 5);
+ val = 1 << 5;
+ }
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xf9 : 0xfb,
+ mask, val);
+
+ mask = (0x1 << 5);
+ val = 1 << 5;
+ mod_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xe5 : 0xe6, mask, val);
+ } else {
+ if (rssi_type == NPHY_RSSI_SEL_TBD) {
+
+ mask = (0x3 << 8);
+ val = 1 << 8;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+ mask = (0x3 << 10);
+ val = 1 << 10;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+ } else if (rssi_type ==
+ NPHY_RSSI_SEL_IQ) {
+
+ mask = (0x3 << 8);
+ val = 2 << 8;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+ mask = (0x3 << 10);
+ val = 2 << 10;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+ } else {
+
+ mask = (0x3 << 8);
+ val = 3 << 8;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+ mask = (0x3 << 10);
+ val = 3 << 10;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xa6
+ : 0xa7, mask, val);
+
+ if (PHY_IPA(pi)) {
+ if (NREV_GE
+ (pi->pubpi.phy_rev,
+ 7)) {
+
+ write_radio_reg
+ (pi,
+ ((core ==
+ PHY_CORE_0)
+ ?
+ RADIO_2057_TX0_TX_SSI_MUX
+ :
+ RADIO_2057_TX1_TX_SSI_MUX),
+ (CHSPEC_IS5G
+ (pi->
+ radio_chanspec)
+ ? 0xc :
+ 0xe));
+ } else {
+ write_radio_reg
+ (pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ |
+ ((core ==
+ PHY_CORE_0)
+ ?
+ RADIO_2056_TX0
+ :
+ RADIO_2056_TX1),
+ (CHSPEC_IS5G
+ (pi->
+ radio_chanspec)
+ ? 0xc :
+ 0xe));
+ }
+ } else {
+
+ if (NREV_GE
+ (pi->pubpi.phy_rev,
+ 7)) {
+ write_radio_reg
+ (pi,
+ ((core ==
+ PHY_CORE_0)
+ ?
+ RADIO_2057_TX0_TX_SSI_MUX
+ :
+ RADIO_2057_TX1_TX_SSI_MUX),
+ 0x11);
+
+ if (pi->pubpi.
+ radioid ==
+ BCM2057_ID)
+ write_radio_reg
+ (pi,
+ RADIO_2057_IQTEST_SEL_PU,
+ 0x1);
+
+ } else {
+ write_radio_reg
+ (pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ |
+ ((core ==
+ PHY_CORE_0)
+ ?
+ RADIO_2056_TX0
+ :
+ RADIO_2056_TX1),
+ 0x11);
+ }
+ }
+
+ afectrlovr_rssi_val = 1 << 9;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x8f
+ : 0xa5, (0x1 << 9),
+ afectrlovr_rssi_val);
+ }
+ }
+ }
+ }
+ } else {
+
+ if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+ (rssi_type == NPHY_RSSI_SEL_W2) ||
+ (rssi_type == NPHY_RSSI_SEL_NB)) {
+
+ val = 0x0;
+ } else if (rssi_type == NPHY_RSSI_SEL_TBD) {
+
+ val = 0x1;
+ } else if (rssi_type == NPHY_RSSI_SEL_IQ) {
+
+ val = 0x2;
+ } else {
+
+ val = 0x3;
+ }
+ mask = ((0x3 << 12) | (0x3 << 14));
+ val = (val << 12) | (val << 14);
+ mod_phy_reg(pi, 0xa6, mask, val);
+ mod_phy_reg(pi, 0xa7, mask, val);
+
+ if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+ (rssi_type == NPHY_RSSI_SEL_W2) ||
+ (rssi_type == NPHY_RSSI_SEL_NB)) {
+ if (rssi_type == NPHY_RSSI_SEL_W1) {
+ val = 0x1;
+ }
+ if (rssi_type == NPHY_RSSI_SEL_W2) {
+ val = 0x2;
+ }
+ if (rssi_type == NPHY_RSSI_SEL_NB) {
+ val = 0x3;
+ }
+ mask = (0x3 << 4);
+ val = (val << 4);
+ mod_phy_reg(pi, 0x7a, mask, val);
+ mod_phy_reg(pi, 0x7d, mask, val);
+ }
+
+ if (core_code == RADIO_MIMO_CORESEL_OFF) {
+ afectrlovr_rssi_val = 0;
+ rfctrlcmd_rxen_val = 0;
+ rfctrlcmd_coresel_val = 0;
+ rfctrlovr_rssi_val = 0;
+ rfctrlovr_rxen_val = 0;
+ rfctrlovr_coresel_val = 0;
+ rfctrlovr_trigger_val = 0;
+ startseq = 0;
+ } else {
+ afectrlovr_rssi_val = 1;
+ rfctrlcmd_rxen_val = 1;
+ rfctrlcmd_coresel_val = core_code;
+ rfctrlovr_rssi_val = 1;
+ rfctrlovr_rxen_val = 1;
+ rfctrlovr_coresel_val = 1;
+ rfctrlovr_trigger_val = 1;
+ startseq = 1;
+ }
+
+ afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
+ afectrlovr_rssi_val = (afectrlovr_rssi_val <<
+ 12) | (afectrlovr_rssi_val << 13);
+ mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
+ afectrlovr_rssi_val);
+
+ if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+ (rssi_type == NPHY_RSSI_SEL_W2) ||
+ (rssi_type == NPHY_RSSI_SEL_NB)) {
+ rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
+ rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
+ (rfctrlcmd_coresel_val << 3);
+
+ rfctrlovr_mask = ((0x1 << 5) |
+ (0x1 << 12) |
+ (0x1 << 1) | (0x1 << 0));
+ rfctrlovr_val = (rfctrlovr_rssi_val <<
+ 5) |
+ (rfctrlovr_rxen_val << 12) |
+ (rfctrlovr_coresel_val << 1) |
+ (rfctrlovr_trigger_val << 0);
+
+ mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
+ mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
+
+ mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
+ OSL_DELAY(20);
+
+ mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+ }
+ }
+}
+
+int
+wlc_phy_poll_rssi_nphy(phy_info_t *pi, uint8 rssi_type, int32 *rssi_buf,
+ uint8 nsamps)
+{
+ int16 rssi0, rssi1;
+ uint16 afectrlCore1_save = 0;
+ uint16 afectrlCore2_save = 0;
+ uint16 afectrlOverride1_save = 0;
+ uint16 afectrlOverride2_save = 0;
+ uint16 rfctrlOverrideAux0_save = 0;
+ uint16 rfctrlOverrideAux1_save = 0;
+ uint16 rfctrlMiscReg1_save = 0;
+ uint16 rfctrlMiscReg2_save = 0;
+ uint16 rfctrlcmd_save = 0;
+ uint16 rfctrloverride_save = 0;
+ uint16 rfctrlrssiothers1_save = 0;
+ uint16 rfctrlrssiothers2_save = 0;
+ int8 tmp_buf[4];
+ uint8 ctr = 0, samp = 0;
+ int32 rssi_out_val;
+ uint16 gpiosel_orig;
+
+ afectrlCore1_save = read_phy_reg(pi, 0xa6);
+ afectrlCore2_save = read_phy_reg(pi, 0xa7);
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+ rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+ afectrlOverride1_save = read_phy_reg(pi, 0x8f);
+ afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+ rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+ rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+ } else {
+ afectrlOverride1_save = read_phy_reg(pi, 0xa5);
+ rfctrlcmd_save = read_phy_reg(pi, 0x78);
+ rfctrloverride_save = read_phy_reg(pi, 0xec);
+ rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
+ rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
+ }
+
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+
+ gpiosel_orig = read_phy_reg(pi, 0xca);
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ write_phy_reg(pi, 0xca, 5);
+ }
+
+ for (ctr = 0; ctr < 4; ctr++) {
+ rssi_buf[ctr] = 0;
+ }
+
+ for (samp = 0; samp < nsamps; samp++) {
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ rssi0 = read_phy_reg(pi, 0x1c9);
+ rssi1 = read_phy_reg(pi, 0x1ca);
+ } else {
+ rssi0 = read_phy_reg(pi, 0x219);
+ rssi1 = read_phy_reg(pi, 0x21a);
+ }
+
+ ctr = 0;
+ tmp_buf[ctr++] = ((int8) ((rssi0 & 0x3f) << 2)) >> 2;
+ tmp_buf[ctr++] = ((int8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
+ tmp_buf[ctr++] = ((int8) ((rssi1 & 0x3f) << 2)) >> 2;
+ tmp_buf[ctr++] = ((int8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
+
+ for (ctr = 0; ctr < 4; ctr++) {
+ rssi_buf[ctr] += tmp_buf[ctr];
+ }
+
+ }
+
+ rssi_out_val = rssi_buf[3] & 0xff;
+ rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
+ rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
+ rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ write_phy_reg(pi, 0xca, gpiosel_orig);
+ }
+
+ write_phy_reg(pi, 0xa6, afectrlCore1_save);
+ write_phy_reg(pi, 0xa7, afectrlCore2_save);
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
+ write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
+ write_phy_reg(pi, 0x8f, afectrlOverride1_save);
+ write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+ write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
+ write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
+ } else {
+ write_phy_reg(pi, 0xa5, afectrlOverride1_save);
+ write_phy_reg(pi, 0x78, rfctrlcmd_save);
+ write_phy_reg(pi, 0xec, rfctrloverride_save);
+ write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
+ write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
+ }
+
+ return rssi_out_val;
+}
+
+int16 wlc_phy_tempsense_nphy(phy_info_t *pi)
+{
+ uint16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
+ uint16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
+ uint16 pwrdet_rxtx_core1_save;
+ uint16 pwrdet_rxtx_core2_save;
+ uint16 afectrlCore1_save;
+ uint16 afectrlCore2_save;
+ uint16 afectrlOverride_save;
+ uint16 afectrlOverride2_save;
+ uint16 pd_pll_ts_save;
+ uint16 gpioSel_save;
+ int32 radio_temp[4];
+ int32 radio_temp2[4];
+ uint16 syn_tempprocsense_save;
+ int16 offset = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ uint16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
+ uint16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
+ uint16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
+ int32 auxADC_Vl;
+ uint16 RfctrlOverride5_save, RfctrlOverride6_save;
+ uint16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
+ uint16 RSSIMultCoef0QPowerDet_save;
+ uint16 tempsense_Rcal;
+
+ syn_tempprocsense_save =
+ read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
+
+ afectrlCore1_save = read_phy_reg(pi, 0xa6);
+ afectrlCore2_save = read_phy_reg(pi, 0xa7);
+ afectrlOverride_save = read_phy_reg(pi, 0x8f);
+ afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+ RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
+ RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+ RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+ RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+ RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+ &auxADC_Vmid_save);
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+ &auxADC_Av_save);
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+ &auxADC_rssi_ctrlL_save);
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+ &auxADC_rssi_ctrlH_save);
+
+ write_phy_reg(pi, 0x1ae, 0x0);
+
+ auxADC_rssi_ctrlL = 0x0;
+ auxADC_rssi_ctrlH = 0x20;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+ &auxADC_rssi_ctrlL);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+ &auxADC_rssi_ctrlH);
+
+ tempsense_Rcal = syn_tempprocsense_save & 0x1c;
+
+ write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+ tempsense_Rcal | 0x01);
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+ 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
+ mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
+ mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
+ mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
+
+ mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+ OSL_DELAY(5);
+ mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+ mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+ mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
+ mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
+ mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
+ mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
+ mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
+ mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
+ mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
+ mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
+
+ auxADC_Vmid = 0xA3;
+ auxADC_Av = 0x0;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+ &auxADC_Vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+ &auxADC_Av);
+
+ OSL_DELAY(3);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+ write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+ tempsense_Rcal | 0x03);
+
+ OSL_DELAY(5);
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+
+ auxADC_Av = 0x7;
+ if (radio_temp[1] + radio_temp2[1] < -30) {
+ auxADC_Vmid = 0x45;
+ auxADC_Vl = 263;
+ } else if (radio_temp[1] + radio_temp2[1] < -9) {
+ auxADC_Vmid = 0x200;
+ auxADC_Vl = 467;
+ } else if (radio_temp[1] + radio_temp2[1] < 11) {
+ auxADC_Vmid = 0x266;
+ auxADC_Vl = 634;
+ } else {
+ auxADC_Vmid = 0x2D5;
+ auxADC_Vl = 816;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+ &auxADC_Vmid);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+ &auxADC_Av);
+
+ OSL_DELAY(3);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+ write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+ tempsense_Rcal | 0x01);
+
+ OSL_DELAY(5);
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+
+ write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+ syn_tempprocsense_save);
+
+ write_phy_reg(pi, 0xa6, afectrlCore1_save);
+ write_phy_reg(pi, 0xa7, afectrlCore2_save);
+ write_phy_reg(pi, 0x8f, afectrlOverride_save);
+ write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+ write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
+ write_phy_reg(pi, 0x346, RfctrlOverride5_save);
+ write_phy_reg(pi, 0x347, RfctrlOverride6_save);
+ write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
+ write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+ &auxADC_Vmid_save);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+ &auxADC_Av_save);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+ &auxADC_rssi_ctrlL_save);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+ &auxADC_rssi_ctrlH_save);
+
+ if (CHIPID(pi->sh->chip) == BCM5357_CHIP_ID) {
+ radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1])
+ + 88 * (auxADC_Vl) - 27111 +
+ 128) / 256;
+ } else if (CHIPID(pi->sh->chip) == BCM43236_CHIP_ID) {
+ radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1])
+ + 91 * (auxADC_Vl) - 27243 +
+ 128) / 256;
+ } else {
+ radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
+ + 82 * (auxADC_Vl) - 28861 +
+ 128) / 256;
+ }
+
+ offset = (int16) pi->phy_tempsense_offset;
+
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ syn_tempprocsense_save =
+ read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
+
+ afectrlCore1_save = read_phy_reg(pi, 0xa6);
+ afectrlCore2_save = read_phy_reg(pi, 0xa7);
+ afectrlOverride_save = read_phy_reg(pi, 0x8f);
+ afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+ gpioSel_save = read_phy_reg(pi, 0xca);
+
+ write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ } else {
+ write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
+ }
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
+ } else {
+ write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+ }
+
+ radio_temp[0] =
+ (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
+
+ write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
+ syn_tempprocsense_save);
+
+ write_phy_reg(pi, 0xca, gpioSel_save);
+ write_phy_reg(pi, 0xa6, afectrlCore1_save);
+ write_phy_reg(pi, 0xa7, afectrlCore2_save);
+ write_phy_reg(pi, 0x8f, afectrlOverride_save);
+ write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+
+ offset = (int16) pi->phy_tempsense_offset;
+ } else {
+
+ pwrdet_rxtx_core1_save =
+ read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+ pwrdet_rxtx_core2_save =
+ read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+ core1_txrf_iqcal1_save =
+ read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+ core1_txrf_iqcal2_save =
+ read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+ core2_txrf_iqcal1_save =
+ read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+ core2_txrf_iqcal2_save =
+ read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+ pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
+
+ afectrlCore1_save = read_phy_reg(pi, 0xa6);
+ afectrlCore2_save = read_phy_reg(pi, 0xa7);
+ afectrlOverride_save = read_phy_reg(pi, 0xa5);
+ gpioSel_save = read_phy_reg(pi, 0xca);
+
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+ write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+ xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+ xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+ xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+
+ radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
+ radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
+ radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
+ radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
+
+ radio_temp[0] =
+ (radio_temp[0] + radio_temp[1] + radio_temp[2] +
+ radio_temp[3]);
+
+ radio_temp[0] =
+ (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8);
+
+ radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
+
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+ pwrdet_rxtx_core1_save);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+ pwrdet_rxtx_core2_save);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+ core1_txrf_iqcal1_save);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+ core2_txrf_iqcal1_save);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+ core1_txrf_iqcal2_save);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+ core2_txrf_iqcal2_save);
+ write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
+
+ write_phy_reg(pi, 0xca, gpioSel_save);
+ write_phy_reg(pi, 0xa6, afectrlCore1_save);
+ write_phy_reg(pi, 0xa7, afectrlCore2_save);
+ write_phy_reg(pi, 0xa5, afectrlOverride_save);
+ }
+
+ return (int16) radio_temp[0] + offset;
+}
+
+static void
+wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, uint8 rssi_type, uint8 *vcm_buf)
+{
+ uint8 core;
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (rssi_type == NPHY_RSSI_SEL_NB) {
+ if (core == PHY_CORE_0) {
+ mod_radio_reg(pi,
+ RADIO_2055_CORE1_B0_NBRSSI_VCM,
+ RADIO_2055_NBRSSI_VCM_I_MASK,
+ vcm_buf[2 *
+ core] <<
+ RADIO_2055_NBRSSI_VCM_I_SHIFT);
+ mod_radio_reg(pi,
+ RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+ RADIO_2055_NBRSSI_VCM_Q_MASK,
+ vcm_buf[2 * core +
+ 1] <<
+ RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2055_CORE2_B0_NBRSSI_VCM,
+ RADIO_2055_NBRSSI_VCM_I_MASK,
+ vcm_buf[2 *
+ core] <<
+ RADIO_2055_NBRSSI_VCM_I_SHIFT);
+ mod_radio_reg(pi,
+ RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+ RADIO_2055_NBRSSI_VCM_Q_MASK,
+ vcm_buf[2 * core +
+ 1] <<
+ RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+ }
+ } else {
+
+ if (core == PHY_CORE_0) {
+ mod_radio_reg(pi,
+ RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+ RADIO_2055_WBRSSI_VCM_IQ_MASK,
+ vcm_buf[2 *
+ core] <<
+ RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+ RADIO_2055_WBRSSI_VCM_IQ_MASK,
+ vcm_buf[2 *
+ core] <<
+ RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+ }
+ }
+ }
+}
+
+void wlc_phy_rssi_cal_nphy(phy_info_t *pi)
+{
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ wlc_phy_rssi_cal_nphy_rev3(pi);
+ } else {
+ wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
+ wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
+ wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
+ }
+}
+
+static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, uint8 rssi_type)
+{
+ int32 target_code;
+ uint16 classif_state;
+ uint16 clip_state[2];
+ uint16 rssi_ctrl_state[2], pd_state[2];
+ uint16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
+ uint16 rfctrlintc_override_val;
+ uint16 clip_off[] = { 0xffff, 0xffff };
+ uint16 rf_pd_val, pd_mask, rssi_ctrl_mask;
+ uint8 vcm, min_vcm, vcm_tmp[4];
+ uint8 vcm_final[4] = { 0, 0, 0, 0 };
+ uint8 result_idx, ctr;
+ int32 poll_results[4][4] = {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}
+ };
+ int32 poll_miniq[4][2] = {
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}
+ };
+ int32 min_d, curr_d;
+ int32 fine_digital_offset[4];
+ int32 poll_results_min[4] = { 0, 0, 0, 0 };
+ int32 min_poll;
+
+ switch (rssi_type) {
+ case NPHY_RSSI_SEL_NB:
+ target_code = NPHY_RSSICAL_NB_TARGET;
+ break;
+ case NPHY_RSSI_SEL_W1:
+ target_code = NPHY_RSSICAL_W1_TARGET;
+ break;
+ case NPHY_RSSI_SEL_W2:
+ target_code = NPHY_RSSICAL_W2_TARGET;
+ break;
+ default:
+ return;
+ break;
+ }
+
+ classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+ wlc_phy_clip_det_nphy(pi, 0, clip_state);
+ wlc_phy_clip_det_nphy(pi, 1, clip_off);
+
+ rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
+ rfctrlintc_override_val =
+ CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
+
+ rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
+ rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
+ write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+ write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
+
+ rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
+ rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
+ write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+ write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
+
+ pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
+ RADIO_2055_WBRSSI_G2_PD;
+ pd_state[0] =
+ read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
+ pd_state[1] =
+ read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
+ mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
+ mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
+ rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
+ RADIO_2055_WBRSSI_G2_SEL;
+ rssi_ctrl_state[0] =
+ read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
+ rssi_ctrl_state[1] =
+ read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+ NPHY_RAIL_I, rssi_type);
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+ NPHY_RAIL_Q, rssi_type);
+
+ for (vcm = 0; vcm < 4; vcm++) {
+
+ vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
+ if (rssi_type != NPHY_RSSI_SEL_W2) {
+ wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
+ }
+
+ wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
+ NPHY_RSSICAL_NPOLL);
+
+ if ((rssi_type == NPHY_RSSI_SEL_W1)
+ || (rssi_type == NPHY_RSSI_SEL_W2)) {
+ for (ctr = 0; ctr < 2; ctr++) {
+ poll_miniq[vcm][ctr] =
+ MIN(poll_results[vcm][ctr * 2 + 0],
+ poll_results[vcm][ctr * 2 + 1]);
+ }
+ }
+ }
+
+ for (result_idx = 0; result_idx < 4; result_idx++) {
+ min_d = NPHY_RSSICAL_MAXD;
+ min_vcm = 0;
+ min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
+ for (vcm = 0; vcm < 4; vcm++) {
+ curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ?
+ poll_results[vcm][result_idx] :
+ poll_miniq[vcm][result_idx / 2]) -
+ (target_code * NPHY_RSSICAL_NPOLL));
+ if (curr_d < min_d) {
+ min_d = curr_d;
+ min_vcm = vcm;
+ }
+ if (poll_results[vcm][result_idx] < min_poll) {
+ min_poll = poll_results[vcm][result_idx];
+ }
+ }
+ vcm_final[result_idx] = min_vcm;
+ poll_results_min[result_idx] = min_poll;
+ }
+
+ if (rssi_type != NPHY_RSSI_SEL_W2) {
+ wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
+ }
+
+ for (result_idx = 0; result_idx < 4; result_idx++) {
+ fine_digital_offset[result_idx] =
+ (target_code * NPHY_RSSICAL_NPOLL) -
+ poll_results[vcm_final[result_idx]][result_idx];
+ if (fine_digital_offset[result_idx] < 0) {
+ fine_digital_offset[result_idx] =
+ ABS(fine_digital_offset[result_idx]);
+ fine_digital_offset[result_idx] +=
+ (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+ fine_digital_offset[result_idx] =
+ -fine_digital_offset[result_idx];
+ } else {
+ fine_digital_offset[result_idx] +=
+ (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+ }
+
+ if (poll_results_min[result_idx] ==
+ NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+ fine_digital_offset[result_idx] =
+ (target_code - NPHY_RSSICAL_MAXREAD - 1);
+ }
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+ (int8)
+ fine_digital_offset[result_idx],
+ (result_idx / 2 ==
+ 0) ? RADIO_MIMO_CORESEL_CORE1 :
+ RADIO_MIMO_CORESEL_CORE2,
+ (result_idx % 2 ==
+ 0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
+ rssi_type);
+ }
+
+ mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
+ mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
+ if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+ NPHY_RSSI_SEL_NB);
+ } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+ NPHY_RSSI_SEL_W1);
+ } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+ NPHY_RSSI_SEL_W2);
+ } else {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+ NPHY_RSSI_SEL_W2);
+ }
+ if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RSSI_SEL_NB);
+ } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RSSI_SEL_W1);
+ } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RSSI_SEL_W2);
+ } else {
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RSSI_SEL_W2);
+ }
+
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
+
+ write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
+ write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
+ write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
+ write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
+
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+ wlc_phy_clip_det_nphy(pi, 1, clip_state);
+
+ wlc_phy_resetcca_nphy(pi);
+}
+
+int BCMFASTPATH
+wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh)
+{
+ d11rxhdr_t *rxh = &wlc_rxh->rxhdr;
+ int16 rxpwr, rxpwr0, rxpwr1;
+ int16 phyRx0_l, phyRx2_l;
+
+ rxpwr = 0;
+ rxpwr0 = ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK;
+ rxpwr1 = (ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8;
+
+ if (rxpwr0 > 127)
+ rxpwr0 -= 256;
+ if (rxpwr1 > 127)
+ rxpwr1 -= 256;
+
+ phyRx0_l = ltoh16(rxh->PhyRxStatus_0) & 0x00ff;
+ phyRx2_l = ltoh16(rxh->PhyRxStatus_2) & 0x00ff;
+ if (phyRx2_l > 127)
+ phyRx2_l -= 256;
+
+ if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
+ rxpwr0 = rxpwr1;
+ rxpwr1 = phyRx2_l;
+ }
+
+ wlc_rxh->rxpwr[0] = (int8) rxpwr0;
+ wlc_rxh->rxpwr[1] = (int8) rxpwr1;
+ wlc_rxh->do_rssi_ma = 0;
+
+ if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
+ rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
+ else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
+ rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
+ else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
+ rxpwr = (rxpwr0 + rxpwr1) >> 1;
+ else
+ ASSERT(0);
+
+ return rxpwr;
+}
+
+static void
+wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, uint8 field, uint16 value,
+ uint8 core_code)
+{
+ uint16 mask;
+ uint16 val;
+ uint8 core;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (core_code == RADIO_MIMO_CORESEL_CORE1
+ && core == PHY_CORE_1)
+ continue;
+ else if (core_code == RADIO_MIMO_CORESEL_CORE2
+ && core == PHY_CORE_0)
+ continue;
+
+ if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ mask = (0x1 << 10);
+ val = 1 << 10;
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+ 0x92, mask, val);
+ }
+
+ if (field == NPHY_RfctrlIntc_override_OFF) {
+
+ write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+ 0x92, 0);
+
+ wlc_phy_force_rfseq_nphy(pi,
+ NPHY_RFSEQ_RESET2RX);
+ } else if (field == NPHY_RfctrlIntc_override_TRSW) {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ mask = (0x1 << 6) | (0x1 << 7);
+
+ val = value << 6;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+
+ or_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ (0x1 << 10));
+
+ and_phy_reg(pi, 0x2ff, (uint16)
+ ~(0x3 << 14));
+ or_phy_reg(pi, 0x2ff, (0x1 << 13));
+ or_phy_reg(pi, 0x2ff, (0x1 << 0));
+ } else {
+
+ mask = (0x1 << 6) |
+ (0x1 << 7) |
+ (0x1 << 8) | (0x1 << 9);
+ val = value << 6;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+
+ mask = (0x1 << 0);
+ val = 1 << 0;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xe7 : 0xec,
+ mask, val);
+
+ mask = (core == PHY_CORE_0) ? (0x1 << 0)
+ : (0x1 << 1);
+ val = 1 << ((core == PHY_CORE_0) ?
+ 0 : 1);
+ mod_phy_reg(pi, 0x78, mask, val);
+
+ SPINWAIT(((read_phy_reg(pi, 0x78) & val)
+ != 0), 10000);
+ ASSERT((read_phy_reg(pi, 0x78) & val) ==
+ 0);
+
+ mask = (0x1 << 0);
+ val = 0 << 0;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xe7 : 0xec,
+ mask, val);
+ }
+ } else if (field == NPHY_RfctrlIntc_override_PA) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ mask = (0x1 << 4) | (0x1 << 5);
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ val = value << 5;
+ } else {
+ val = value << 4;
+ }
+
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+
+ or_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ (0x1 << 12));
+ } else {
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ mask = (0x1 << 5);
+ val = value << 5;
+ } else {
+ mask = (0x1 << 4);
+ val = value << 4;
+ }
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+ }
+ } else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+
+ mask = (0x1 << 0);
+ val = value << 0;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, val);
+
+ mask = (0x1 << 2);
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, 0);
+ } else {
+
+ mask = (0x1 << 2);
+ val = value << 2;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, val);
+
+ mask = (0x1 << 0);
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, 0);
+ }
+
+ mask = (0x1 << 11);
+ val = 1 << 11;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+ } else {
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ mask = (0x1 << 0);
+ val = value << 0;
+ } else {
+ mask = (0x1 << 2);
+ val = value << 2;
+ }
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+ }
+ } else if (field ==
+ NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+
+ mask = (0x1 << 1);
+ val = value << 1;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, val);
+
+ mask = (0x1 << 3);
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, 0);
+ } else {
+
+ mask = (0x1 << 3);
+ val = value << 3;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, val);
+
+ mask = (0x1 << 1);
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91
+ : 0x92, mask, 0);
+ }
+
+ mask = (0x1 << 11);
+ val = 1 << 11;
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+ } else {
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ mask = (0x1 << 1);
+ val = value << 1;
+ } else {
+ mask = (0x1 << 3);
+ val = value << 3;
+ }
+ mod_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0x91 : 0x92,
+ mask, val);
+ }
+ }
+ }
+ } else {
+ return;
+ }
+}
+
+static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi)
+{
+ uint16 classif_state;
+ uint16 clip_state[2];
+ uint16 clip_off[] = { 0xffff, 0xffff };
+ int32 target_code;
+ uint8 vcm, min_vcm;
+ uint8 vcm_final = 0;
+ uint8 result_idx;
+ int32 poll_results[8][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}
+ };
+ int32 poll_result_core[4] = { 0, 0, 0, 0 };
+ int32 min_d = NPHY_RSSICAL_MAXD, curr_d;
+ int32 fine_digital_offset[4];
+ int32 poll_results_min[4] = { 0, 0, 0, 0 };
+ int32 min_poll;
+ uint8 vcm_level_max;
+ uint8 core;
+ uint8 wb_cnt;
+ uint8 rssi_type;
+ uint16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
+ uint16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
+ uint16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
+ uint16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
+ uint16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
+ uint16 NPHY_RfctrlCmd_save;
+ uint16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
+ uint16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
+ uint8 rxcore_state;
+ uint16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
+ uint16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
+ uint16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
+ uint16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
+
+ NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save =
+ NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save =
+ NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save =
+ NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0;
+
+ classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+ wlc_phy_clip_det_nphy(pi, 0, clip_state);
+ wlc_phy_clip_det_nphy(pi, 1, clip_off);
+
+ NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
+ NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
+ NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
+ NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
+ NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
+ NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
+ NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
+ NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
+ NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
+ NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+ NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+ }
+ NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+ NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+ NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
+ NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+ NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
+ NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
+ NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+ NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+ }
+ NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
+ NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
+
+ wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
+ RADIO_MIMO_CORESEL_ALLRXTX);
+ wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
+ RADIO_MIMO_CORESEL_ALLRXTX);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
+ 0, 0, 0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_rx_pu,
+ 1, 0, 0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+ 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+ 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0,
+ 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
+ }
+
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+ 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0,
+ 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
+ }
+ }
+
+ rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+
+ vcm_level_max = 8;
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ if ((rxcore_state & (1 << core)) == 0)
+ continue;
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+ core ==
+ PHY_CORE_0 ?
+ RADIO_MIMO_CORESEL_CORE1 :
+ RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+ core ==
+ PHY_CORE_0 ?
+ RADIO_MIMO_CORESEL_CORE1 :
+ RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
+
+ for (vcm = 0; vcm < vcm_level_max; vcm++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ mod_radio_reg(pi, (core == PHY_CORE_0) ?
+ RADIO_2057_NB_MASTER_CORE0 :
+ RADIO_2057_NB_MASTER_CORE1,
+ RADIO_2057_VCM_MASK, vcm);
+ } else {
+
+ mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+ ((core ==
+ PHY_CORE_0) ? RADIO_2056_RX0 :
+ RADIO_2056_RX1),
+ RADIO_2056_VCM_MASK,
+ vcm << RADIO_2056_RSSI_VCM_SHIFT);
+ }
+
+ wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
+ &poll_results[vcm][0],
+ NPHY_RSSICAL_NPOLL);
+ }
+
+ for (result_idx = 0; result_idx < 4; result_idx++) {
+ if ((core == result_idx / 2) && (result_idx % 2 == 0)) {
+
+ min_d = NPHY_RSSICAL_MAXD;
+ min_vcm = 0;
+ min_poll =
+ NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL +
+ 1;
+ for (vcm = 0; vcm < vcm_level_max; vcm++) {
+ curr_d = poll_results[vcm][result_idx] *
+ poll_results[vcm][result_idx] +
+ poll_results[vcm][result_idx + 1] *
+ poll_results[vcm][result_idx + 1];
+ if (curr_d < min_d) {
+ min_d = curr_d;
+ min_vcm = vcm;
+ }
+ if (poll_results[vcm][result_idx] <
+ min_poll) {
+ min_poll =
+ poll_results[vcm]
+ [result_idx];
+ }
+ }
+ vcm_final = min_vcm;
+ poll_results_min[result_idx] = min_poll;
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_radio_reg(pi, (core == PHY_CORE_0) ?
+ RADIO_2057_NB_MASTER_CORE0 :
+ RADIO_2057_NB_MASTER_CORE1,
+ RADIO_2057_VCM_MASK, vcm_final);
+ } else {
+ mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+ ((core ==
+ PHY_CORE_0) ? RADIO_2056_RX0 :
+ RADIO_2056_RX1), RADIO_2056_VCM_MASK,
+ vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
+ }
+
+ for (result_idx = 0; result_idx < 4; result_idx++) {
+ if (core == result_idx / 2) {
+ fine_digital_offset[result_idx] =
+ (NPHY_RSSICAL_NB_TARGET *
+ NPHY_RSSICAL_NPOLL) -
+ poll_results[vcm_final][result_idx];
+ if (fine_digital_offset[result_idx] < 0) {
+ fine_digital_offset[result_idx] =
+ ABS(fine_digital_offset
+ [result_idx]);
+ fine_digital_offset[result_idx] +=
+ (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx] /=
+ NPHY_RSSICAL_NPOLL;
+ fine_digital_offset[result_idx] =
+ -fine_digital_offset[result_idx];
+ } else {
+ fine_digital_offset[result_idx] +=
+ (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx] /=
+ NPHY_RSSICAL_NPOLL;
+ }
+
+ if (poll_results_min[result_idx] ==
+ NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+ fine_digital_offset[result_idx] =
+ (NPHY_RSSICAL_NB_TARGET -
+ NPHY_RSSICAL_MAXREAD - 1);
+ }
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+ (int8)
+ fine_digital_offset
+ [result_idx],
+ (result_idx /
+ 2 ==
+ 0) ?
+ RADIO_MIMO_CORESEL_CORE1
+ :
+ RADIO_MIMO_CORESEL_CORE2,
+ (result_idx %
+ 2 ==
+ 0) ? NPHY_RAIL_I
+ : NPHY_RAIL_Q,
+ NPHY_RSSI_SEL_NB);
+ }
+ }
+
+ }
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ if ((rxcore_state & (1 << core)) == 0)
+ continue;
+
+ for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
+ if (wb_cnt == 0) {
+ rssi_type = NPHY_RSSI_SEL_W1;
+ target_code = NPHY_RSSICAL_W1_TARGET_REV3;
+ } else {
+ rssi_type = NPHY_RSSI_SEL_W2;
+ target_code = NPHY_RSSICAL_W2_TARGET_REV3;
+ }
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+ core ==
+ PHY_CORE_0 ?
+ RADIO_MIMO_CORESEL_CORE1
+ :
+ RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RAIL_I, rssi_type);
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+ core ==
+ PHY_CORE_0 ?
+ RADIO_MIMO_CORESEL_CORE1
+ :
+ RADIO_MIMO_CORESEL_CORE2,
+ NPHY_RAIL_Q, rssi_type);
+
+ wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
+ NPHY_RSSICAL_NPOLL);
+
+ for (result_idx = 0; result_idx < 4; result_idx++) {
+ if (core == result_idx / 2) {
+ fine_digital_offset[result_idx] =
+ (target_code * NPHY_RSSICAL_NPOLL) -
+ poll_result_core[result_idx];
+ if (fine_digital_offset[result_idx] < 0) {
+ fine_digital_offset[result_idx]
+ =
+ ABS(fine_digital_offset
+ [result_idx]);
+ fine_digital_offset[result_idx]
+ += (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx]
+ /= NPHY_RSSICAL_NPOLL;
+ fine_digital_offset[result_idx]
+ =
+ -fine_digital_offset
+ [result_idx];
+ } else {
+ fine_digital_offset[result_idx]
+ += (NPHY_RSSICAL_NPOLL / 2);
+ fine_digital_offset[result_idx]
+ /= NPHY_RSSICAL_NPOLL;
+ }
+
+ wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+ (int8)
+ fine_digital_offset
+ [core *
+ 2],
+ (core ==
+ PHY_CORE_0)
+ ?
+ RADIO_MIMO_CORESEL_CORE1
+ :
+ RADIO_MIMO_CORESEL_CORE2,
+ (result_idx
+ % 2 ==
+ 0) ?
+ NPHY_RAIL_I
+ :
+ NPHY_RAIL_Q,
+ rssi_type);
+ }
+ }
+
+ }
+ }
+
+ write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
+ write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
+
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+
+ mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
+
+ mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
+ mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
+ mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+
+ write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
+ write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
+ write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
+ write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
+ write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
+ write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
+ write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
+ write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
+ write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
+ }
+ write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
+ write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
+ write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
+ write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
+ write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
+ write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
+ write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
+ write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
+ }
+ write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
+ write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ pi->rssical_cache.rssical_radio_regs_2G[0] =
+ read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+ pi->rssical_cache.rssical_radio_regs_2G[1] =
+ read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+ } else {
+ pi->rssical_cache.rssical_radio_regs_2G[0] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC |
+ RADIO_2056_RX0);
+ pi->rssical_cache.rssical_radio_regs_2G[1] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC |
+ RADIO_2056_RX1);
+ }
+
+ pi->rssical_cache.rssical_phyregs_2G[0] =
+ read_phy_reg(pi, 0x1a6);
+ pi->rssical_cache.rssical_phyregs_2G[1] =
+ read_phy_reg(pi, 0x1ac);
+ pi->rssical_cache.rssical_phyregs_2G[2] =
+ read_phy_reg(pi, 0x1b2);
+ pi->rssical_cache.rssical_phyregs_2G[3] =
+ read_phy_reg(pi, 0x1b8);
+ pi->rssical_cache.rssical_phyregs_2G[4] =
+ read_phy_reg(pi, 0x1a4);
+ pi->rssical_cache.rssical_phyregs_2G[5] =
+ read_phy_reg(pi, 0x1aa);
+ pi->rssical_cache.rssical_phyregs_2G[6] =
+ read_phy_reg(pi, 0x1b0);
+ pi->rssical_cache.rssical_phyregs_2G[7] =
+ read_phy_reg(pi, 0x1b6);
+ pi->rssical_cache.rssical_phyregs_2G[8] =
+ read_phy_reg(pi, 0x1a5);
+ pi->rssical_cache.rssical_phyregs_2G[9] =
+ read_phy_reg(pi, 0x1ab);
+ pi->rssical_cache.rssical_phyregs_2G[10] =
+ read_phy_reg(pi, 0x1b1);
+ pi->rssical_cache.rssical_phyregs_2G[11] =
+ read_phy_reg(pi, 0x1b7);
+
+ pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ pi->rssical_cache.rssical_radio_regs_5G[0] =
+ read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+ pi->rssical_cache.rssical_radio_regs_5G[1] =
+ read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+ } else {
+ pi->rssical_cache.rssical_radio_regs_5G[0] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC |
+ RADIO_2056_RX0);
+ pi->rssical_cache.rssical_radio_regs_5G[1] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC |
+ RADIO_2056_RX1);
+ }
+
+ pi->rssical_cache.rssical_phyregs_5G[0] =
+ read_phy_reg(pi, 0x1a6);
+ pi->rssical_cache.rssical_phyregs_5G[1] =
+ read_phy_reg(pi, 0x1ac);
+ pi->rssical_cache.rssical_phyregs_5G[2] =
+ read_phy_reg(pi, 0x1b2);
+ pi->rssical_cache.rssical_phyregs_5G[3] =
+ read_phy_reg(pi, 0x1b8);
+ pi->rssical_cache.rssical_phyregs_5G[4] =
+ read_phy_reg(pi, 0x1a4);
+ pi->rssical_cache.rssical_phyregs_5G[5] =
+ read_phy_reg(pi, 0x1aa);
+ pi->rssical_cache.rssical_phyregs_5G[6] =
+ read_phy_reg(pi, 0x1b0);
+ pi->rssical_cache.rssical_phyregs_5G[7] =
+ read_phy_reg(pi, 0x1b6);
+ pi->rssical_cache.rssical_phyregs_5G[8] =
+ read_phy_reg(pi, 0x1a5);
+ pi->rssical_cache.rssical_phyregs_5G[9] =
+ read_phy_reg(pi, 0x1ab);
+ pi->rssical_cache.rssical_phyregs_5G[10] =
+ read_phy_reg(pi, 0x1b1);
+ pi->rssical_cache.rssical_phyregs_5G[11] =
+ read_phy_reg(pi, 0x1b7);
+
+ pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
+ }
+
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+ wlc_phy_clip_det_nphy(pi, 1, clip_state);
+}
+
+static void wlc_phy_restore_rssical_nphy(phy_info_t *pi)
+{
+ ASSERT(NREV_GE(pi->pubpi.phy_rev, 3));
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->nphy_rssical_chanspec_2G == 0)
+ return;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+ RADIO_2057_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_2G[0]);
+ mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+ RADIO_2057_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_2G[1]);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+ RADIO_2056_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_2G[0]);
+ mod_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+ RADIO_2056_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_2G[1]);
+ }
+
+ write_phy_reg(pi, 0x1a6,
+ pi->rssical_cache.rssical_phyregs_2G[0]);
+ write_phy_reg(pi, 0x1ac,
+ pi->rssical_cache.rssical_phyregs_2G[1]);
+ write_phy_reg(pi, 0x1b2,
+ pi->rssical_cache.rssical_phyregs_2G[2]);
+ write_phy_reg(pi, 0x1b8,
+ pi->rssical_cache.rssical_phyregs_2G[3]);
+ write_phy_reg(pi, 0x1a4,
+ pi->rssical_cache.rssical_phyregs_2G[4]);
+ write_phy_reg(pi, 0x1aa,
+ pi->rssical_cache.rssical_phyregs_2G[5]);
+ write_phy_reg(pi, 0x1b0,
+ pi->rssical_cache.rssical_phyregs_2G[6]);
+ write_phy_reg(pi, 0x1b6,
+ pi->rssical_cache.rssical_phyregs_2G[7]);
+ write_phy_reg(pi, 0x1a5,
+ pi->rssical_cache.rssical_phyregs_2G[8]);
+ write_phy_reg(pi, 0x1ab,
+ pi->rssical_cache.rssical_phyregs_2G[9]);
+ write_phy_reg(pi, 0x1b1,
+ pi->rssical_cache.rssical_phyregs_2G[10]);
+ write_phy_reg(pi, 0x1b7,
+ pi->rssical_cache.rssical_phyregs_2G[11]);
+
+ } else {
+ if (pi->nphy_rssical_chanspec_5G == 0)
+ return;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+ RADIO_2057_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_5G[0]);
+ mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+ RADIO_2057_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_5G[1]);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+ RADIO_2056_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_5G[0]);
+ mod_radio_reg(pi,
+ RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+ RADIO_2056_VCM_MASK,
+ pi->rssical_cache.
+ rssical_radio_regs_5G[1]);
+ }
+
+ write_phy_reg(pi, 0x1a6,
+ pi->rssical_cache.rssical_phyregs_5G[0]);
+ write_phy_reg(pi, 0x1ac,
+ pi->rssical_cache.rssical_phyregs_5G[1]);
+ write_phy_reg(pi, 0x1b2,
+ pi->rssical_cache.rssical_phyregs_5G[2]);
+ write_phy_reg(pi, 0x1b8,
+ pi->rssical_cache.rssical_phyregs_5G[3]);
+ write_phy_reg(pi, 0x1a4,
+ pi->rssical_cache.rssical_phyregs_5G[4]);
+ write_phy_reg(pi, 0x1aa,
+ pi->rssical_cache.rssical_phyregs_5G[5]);
+ write_phy_reg(pi, 0x1b0,
+ pi->rssical_cache.rssical_phyregs_5G[6]);
+ write_phy_reg(pi, 0x1b6,
+ pi->rssical_cache.rssical_phyregs_5G[7]);
+ write_phy_reg(pi, 0x1a5,
+ pi->rssical_cache.rssical_phyregs_5G[8]);
+ write_phy_reg(pi, 0x1ab,
+ pi->rssical_cache.rssical_phyregs_5G[9]);
+ write_phy_reg(pi, 0x1b1,
+ pi->rssical_cache.rssical_phyregs_5G[10]);
+ write_phy_reg(pi, 0x1b7,
+ pi->rssical_cache.rssical_phyregs_5G[11]);
+ }
+}
+
+static uint16
+wlc_phy_gen_load_samples_nphy(phy_info_t *pi, uint32 f_kHz, uint16 max_val,
+ uint8 dac_test_mode)
+{
+ uint8 phy_bw, is_phybw40;
+ uint16 num_samps, t, spur;
+ fixed theta = 0, rot = 0;
+ uint32 tbl_len;
+ cint32 *tone_buf = NULL;
+
+ is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+ phy_bw = (is_phybw40 == 1) ? 40 : 20;
+ tbl_len = (phy_bw << 3);
+
+ if (dac_test_mode == 1) {
+ spur = read_phy_reg(pi, 0x01);
+ spur = (spur >> 15) & 1;
+ phy_bw = (spur == 1) ? 82 : 80;
+ phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
+
+ tbl_len = (phy_bw << 1);
+ }
+
+ tone_buf = (cint32 *) MALLOC(pi->sh->osh, sizeof(cint32) * tbl_len);
+ if (tone_buf == NULL) {
+ return 0;
+ }
+
+ num_samps = (uint16) tbl_len;
+ rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+ theta = 0;
+
+ for (t = 0; t < num_samps; t++) {
+
+ wlc_phy_cordic(theta, &tone_buf[t]);
+
+ theta += rot;
+
+ tone_buf[t].q = (int32) FLOAT(tone_buf[t].q * max_val);
+ tone_buf[t].i = (int32) FLOAT(tone_buf[t].i * max_val);
+ }
+
+ wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
+
+ if (tone_buf != NULL)
+ MFREE(pi->sh->osh, tone_buf, sizeof(cint32) * tbl_len);
+
+ return num_samps;
+}
+
+int
+wlc_phy_tx_tone_nphy(phy_info_t *pi, uint32 f_kHz, uint16 max_val,
+ uint8 iqmode, uint8 dac_test_mode, bool modify_bbmult)
+{
+ uint16 num_samps;
+ uint16 loops = 0xffff;
+ uint16 wait = 0;
+
+ num_samps =
+ wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode);
+ if (num_samps == 0) {
+ return BCME_ERROR;
+ }
+
+ wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
+ dac_test_mode, modify_bbmult);
+
+ return BCME_OK;
+}
+
+static void
+wlc_phy_loadsampletable_nphy(phy_info_t *pi, cint32 *tone_buf,
+ uint16 num_samps)
+{
+ uint16 t;
+ uint32 *data_buf = NULL;
+
+ data_buf = (uint32 *) MALLOC(pi->sh->osh, sizeof(uint32) * num_samps);
+ if (data_buf == NULL) {
+ return;
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ for (t = 0; t < num_samps; t++) {
+ data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
+ (((unsigned int)tone_buf[t].q) & 0x3ff);
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
+ data_buf);
+
+ if (data_buf != NULL)
+ MFREE(pi->sh->osh, data_buf, sizeof(uint32) * num_samps);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void
+wlc_phy_runsamples_nphy(phy_info_t *pi, uint16 num_samps, uint16 loops,
+ uint16 wait, uint8 iqmode, uint8 dac_test_mode,
+ bool modify_bbmult)
+{
+ uint16 bb_mult;
+ uint8 phy_bw, sample_cmd;
+ uint16 orig_RfseqCoreActv;
+ uint16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
+ lpf_bw_ctl_miscreg4;
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ phy_bw = 20;
+ if (CHSPEC_IS40(pi->radio_chanspec))
+ phy_bw = 40;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
+ lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
+ if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
+ lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+ (0x7 << 8);
+ lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+ (0x7 << 8);
+ } else {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 7),
+ wlc_phy_read_lpf_bw_ctl_nphy
+ (pi, 0), 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+
+ pi->nphy_sample_play_lpf_bw_ctl_ovr = TRUE;
+
+ lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+ (0x7 << 8);
+ lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+ (0x7 << 8);
+ }
+ }
+
+ if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+ &bb_mult);
+ pi->nphy_bb_mult_save =
+ BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
+ }
+
+ if (modify_bbmult) {
+ bb_mult = (phy_bw == 20) ? 100 : 71;
+ bb_mult = (bb_mult << 8) + bb_mult;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+ &bb_mult);
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ write_phy_reg(pi, 0xc6, num_samps - 1);
+
+ if (loops != 0xffff) {
+ write_phy_reg(pi, 0xc4, loops - 1);
+ } else {
+ write_phy_reg(pi, 0xc4, loops);
+ }
+ write_phy_reg(pi, 0xc5, wait);
+
+ orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+ or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+ if (iqmode) {
+
+ and_phy_reg(pi, 0xc2, 0x7FFF);
+
+ or_phy_reg(pi, 0xc2, 0x8000);
+ } else {
+
+ sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
+ write_phy_reg(pi, 0xc3, sample_cmd);
+ }
+
+ SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
+
+ write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+}
+
+void wlc_phy_stopplayback_nphy(phy_info_t *pi)
+{
+ uint16 playback_status;
+ uint16 bb_mult;
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ playback_status = read_phy_reg(pi, 0xc7);
+ if (playback_status & 0x1) {
+ or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
+ } else if (playback_status & 0x2) {
+
+ and_phy_reg(pi, 0xc2,
+ (uint16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
+ }
+
+ and_phy_reg(pi, 0xc3, (uint16) ~(0x1 << 2));
+
+ if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
+
+ bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+ &bb_mult);
+
+ pi->nphy_bb_mult_save = 0;
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
+ if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 7),
+ 0, 0, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ pi->nphy_sample_play_lpf_bw_ctl_ovr = FALSE;
+ }
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi)
+{
+ uint16 base_idx[2], curr_gain[2];
+ uint8 core_no;
+ nphy_txgains_t target_gain;
+ uint32 *tx_pwrctrl_tbl = NULL;
+
+ if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ curr_gain);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ for (core_no = 0; core_no < 2; core_no++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ target_gain.ipa[core_no] =
+ curr_gain[core_no] & 0x0007;
+ target_gain.pad[core_no] =
+ ((curr_gain[core_no] & 0x00F8) >> 3);
+ target_gain.pga[core_no] =
+ ((curr_gain[core_no] & 0x0F00) >> 8);
+ target_gain.txgm[core_no] =
+ ((curr_gain[core_no] & 0x7000) >> 12);
+ target_gain.txlpf[core_no] =
+ ((curr_gain[core_no] & 0x8000) >> 15);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ target_gain.ipa[core_no] =
+ curr_gain[core_no] & 0x000F;
+ target_gain.pad[core_no] =
+ ((curr_gain[core_no] & 0x00F0) >> 4);
+ target_gain.pga[core_no] =
+ ((curr_gain[core_no] & 0x0F00) >> 8);
+ target_gain.txgm[core_no] =
+ ((curr_gain[core_no] & 0x7000) >> 12);
+ } else {
+ target_gain.ipa[core_no] =
+ curr_gain[core_no] & 0x0003;
+ target_gain.pad[core_no] =
+ ((curr_gain[core_no] & 0x000C) >> 2);
+ target_gain.pga[core_no] =
+ ((curr_gain[core_no] & 0x0070) >> 4);
+ target_gain.txgm[core_no] =
+ ((curr_gain[core_no] & 0x0380) >> 7);
+ }
+ }
+ } else {
+ base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
+ base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
+ for (core_no = 0; core_no < 2; core_no++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (PHY_IPA(pi)) {
+ tx_pwrctrl_tbl =
+ wlc_phy_get_ipa_gaintbl_nphy(pi);
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if NREV_IS
+ (pi->pubpi.phy_rev, 3) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_5GHz_txgain_rev3;
+ } else if NREV_IS
+ (pi->pubpi.phy_rev, 4) {
+ tx_pwrctrl_tbl =
+ (pi->srom_fem5g.
+ extpagain ==
+ 3) ?
+ nphy_tpc_5GHz_txgain_HiPwrEPA
+ :
+ nphy_tpc_5GHz_txgain_rev4;
+ } else {
+ tx_pwrctrl_tbl =
+ nphy_tpc_5GHz_txgain_rev5;
+ }
+ } else {
+ if (NREV_GE
+ (pi->pubpi.phy_rev, 7)) {
+ if (pi->pubpi.
+ radiorev == 3) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_epa_2057rev3;
+ } else if (pi->pubpi.
+ radiorev ==
+ 5) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_epa_2057rev5;
+ }
+
+ } else {
+ if (NREV_GE
+ (pi->pubpi.phy_rev,
+ 5)
+ && (pi->srom_fem2g.
+ extpagain ==
+ 3)) {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_HiPwrEPA;
+ } else {
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_rev3;
+ }
+ }
+ }
+ }
+ if NREV_GE
+ (pi->pubpi.phy_rev, 7) {
+ target_gain.ipa[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 16) & 0x7;
+ target_gain.pad[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 19) & 0x1f;
+ target_gain.pga[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 24) & 0xf;
+ target_gain.txgm[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 28) & 0x7;
+ target_gain.txlpf[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 31) & 0x1;
+ } else {
+ target_gain.ipa[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 16) & 0xf;
+ target_gain.pad[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 20) & 0xf;
+ target_gain.pga[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 24) & 0xf;
+ target_gain.txgm[core_no] =
+ (tx_pwrctrl_tbl[base_idx[core_no]]
+ >> 28) & 0x7;
+ }
+ } else {
+ target_gain.ipa[core_no] =
+ (nphy_tpc_txgain[base_idx[core_no]] >> 16) &
+ 0x3;
+ target_gain.pad[core_no] =
+ (nphy_tpc_txgain[base_idx[core_no]] >> 18) &
+ 0x3;
+ target_gain.pga[core_no] =
+ (nphy_tpc_txgain[base_idx[core_no]] >> 20) &
+ 0x7;
+ target_gain.txgm[core_no] =
+ (nphy_tpc_txgain[base_idx[core_no]] >> 23) &
+ 0x7;
+ }
+ }
+ }
+
+ return target_gain;
+}
+
+static void
+wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, uint16 core_no,
+ nphy_txgains_t target_gain,
+ nphy_iqcal_params_t *params)
+{
+ uint8 k;
+ int idx;
+ uint16 gain_index;
+ uint8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ params->txlpf = target_gain.txlpf[core_no];
+ }
+ params->txgm = target_gain.txgm[core_no];
+ params->pga = target_gain.pga[core_no];
+ params->pad = target_gain.pad[core_no];
+ params->ipa = target_gain.ipa[core_no];
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ params->cal_gain =
+ ((params->txlpf << 15) | (params->
+ txgm << 12) | (params->
+ pga << 8) |
+ (params->pad << 3) | (params->ipa));
+ } else {
+ params->cal_gain =
+ ((params->txgm << 12) | (params->
+ pga << 8) | (params->
+ pad << 4) |
+ (params->ipa));
+ }
+ params->ncorr[0] = 0x79;
+ params->ncorr[1] = 0x79;
+ params->ncorr[2] = 0x79;
+ params->ncorr[3] = 0x79;
+ params->ncorr[4] = 0x79;
+ } else {
+
+ gain_index = ((target_gain.pad[core_no] << 0) |
+ (target_gain.pga[core_no] << 4) | (target_gain.
+ txgm[core_no]
+ << 8));
+
+ idx = -1;
+ for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
+ if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
+ gain_index) {
+ idx = k;
+ break;
+ }
+ }
+
+ ASSERT(idx != -1);
+
+ params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
+ params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
+ params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
+ params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
+ (params->pad << 2));
+ params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
+ params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
+ params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
+ params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
+ }
+}
+
+static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi)
+{
+ uint16 jtag_core, core;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ for (core = 0; core <= 1; core++) {
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_VCM_HG);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_IDAC);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MUX);
+
+ if (pi->pubpi.radiorev != 5)
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSIA);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSI_MISC1);
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER, 0x0a);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_VCM_HG, 0x43);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_IDAC, 0x55);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSI_VCM, 0x00);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSIG, 0x00);
+ if (pi->use_int_tx_iqlo_cal_nphy) {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TX_SSI_MUX, 0x4);
+ if (!
+ (pi->
+ internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIA, 0x31);
+ } else {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIA, 0x21);
+ }
+ }
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSI_MISC1, 0x00);
+ } else {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER, 0x06);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_VCM_HG, 0x43);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ IQCAL_IDAC, 0x55);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSI_VCM, 0x00);
+
+ if (pi->pubpi.radiorev != 5)
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TSSIA, 0x00);
+ if (pi->use_int_tx_iqlo_cal_nphy) {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TX_SSI_MUX,
+ 0x06);
+ if (!
+ (pi->
+ internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIG, 0x31);
+ } else {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIG, 0x21);
+ }
+ }
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSI_MISC1, 0x00);
+ }
+ }
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ for (core = 0; core <= 1; core++) {
+ jtag_core =
+ (core ==
+ PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MASTER |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_VCM_HG |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_IDAC |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TSSI_VCM | jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TX_AMP_DET |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+ read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+ read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC1 |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC2 |
+ jtag_core);
+
+ pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC3 |
+ jtag_core);
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MASTER |
+ jtag_core, 0x0a);
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_VCM_HG |
+ jtag_core, 0x40);
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_IDAC |
+ jtag_core, 0x55);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_VCM |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_AMP_DET |
+ jtag_core, 0x00);
+
+ if (PHY_IPA(pi)) {
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ | jtag_core, 0x4);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIA |
+ jtag_core, 0x1);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ | jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIA |
+ jtag_core, 0x2f);
+ }
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIG | jtag_core,
+ 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC1 |
+ jtag_core, 0x00);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC2 |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC3 |
+ jtag_core, 0x00);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MASTER |
+ jtag_core, 0x06);
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_VCM_HG |
+ jtag_core, 0x40);
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_IDAC |
+ jtag_core, 0x55);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_VCM |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_AMP_DET |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIA | jtag_core,
+ 0x00);
+
+ if (PHY_IPA(pi)) {
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ | jtag_core, 0x06);
+ if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIG
+ | jtag_core,
+ 0x11);
+ } else {
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIG
+ | jtag_core,
+ 0x1);
+ }
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX
+ | jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSIG |
+ jtag_core, 0x20);
+ }
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC1 |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC2 |
+ jtag_core, 0x00);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC3 |
+ jtag_core, 0x00);
+ }
+ }
+ } else {
+
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
+
+ pi->tx_rx_cal_radio_saveregs[2] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
+ pi->tx_rx_cal_radio_saveregs[3] =
+ read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
+
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+ pi->tx_rx_cal_radio_saveregs[5] =
+ read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+
+ if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
+ 0) {
+
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+ } else {
+
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+
+ or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
+ or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
+ } else {
+
+ and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
+ and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
+ }
+ }
+}
+
+static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi)
+{
+ uint16 jtag_core, core;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (core = 0; core <= 1; core++) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 0]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 1]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 2]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 3]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 5]);
+
+ if (pi->pubpi.radiorev != 5)
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSIA,
+ pi->
+ tx_rx_cal_radio_saveregs[(core
+ *
+ 11) +
+ 6]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 7]);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 8]);
+ }
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ for (core = 0; core <= 1; core++) {
+ jtag_core =
+ (core ==
+ PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 0]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 1]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_IQCAL_IDAC | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 2]);
+
+ write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 3]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_AMP_DET | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 4]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 5]);
+
+ write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 6]);
+
+ write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 7]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC1 | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 8]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC2 | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 9]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TSSI_MISC3 | jtag_core,
+ pi->
+ tx_rx_cal_radio_saveregs[(core * 11) +
+ 10]);
+ }
+ } else {
+
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+ pi->tx_rx_cal_radio_saveregs[0]);
+ write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+ pi->tx_rx_cal_radio_saveregs[1]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+ pi->tx_rx_cal_radio_saveregs[2]);
+ write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+ pi->tx_rx_cal_radio_saveregs[3]);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+ pi->tx_rx_cal_radio_saveregs[4]);
+ write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+ pi->tx_rx_cal_radio_saveregs[5]);
+ }
+}
+
+static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi)
+{
+ uint16 val, mask;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+ pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+
+ mask = ((0x3 << 8) | (0x3 << 10));
+ val = (0x2 << 8);
+ val |= (0x2 << 10);
+ mod_phy_reg(pi, 0xa6, mask, val);
+ mod_phy_reg(pi, 0xa7, mask, val);
+
+ val = read_phy_reg(pi, 0x8f);
+ pi->tx_rx_cal_phy_saveregs[2] = val;
+ val |= ((0x1 << 9) | (0x1 << 10));
+ write_phy_reg(pi, 0x8f, val);
+
+ val = read_phy_reg(pi, 0xa5);
+ pi->tx_rx_cal_phy_saveregs[3] = val;
+ val |= ((0x1 << 9) | (0x1 << 10));
+ write_phy_reg(pi, 0xa5, val);
+
+ pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
+ mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+ &val);
+ pi->tx_rx_cal_phy_saveregs[5] = val;
+ val = 0;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+ &val);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+ &val);
+ pi->tx_rx_cal_phy_saveregs[6] = val;
+ val = 0;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+ &val);
+
+ pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
+ pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
+
+ if (!(pi->use_int_tx_iqlo_cal_nphy)) {
+
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_PA,
+ 1,
+ RADIO_MIMO_CORESEL_CORE1
+ |
+ RADIO_MIMO_CORESEL_CORE2);
+ } else {
+
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_PA,
+ 0,
+ RADIO_MIMO_CORESEL_CORE1
+ |
+ RADIO_MIMO_CORESEL_CORE2);
+ }
+
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x2, RADIO_MIMO_CORESEL_CORE1);
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x8, RADIO_MIMO_CORESEL_CORE2);
+
+ pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+ pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)
+ || NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+ wlc_phy_read_lpf_bw_ctl_nphy
+ (pi, 0), 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ }
+
+ if (pi->use_int_tx_iqlo_cal_nphy
+ && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+
+ mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+ 1 << 4);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ mod_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+ 1, 0);
+ mod_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+ 1, 0);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+ 1, 0);
+ mod_radio_reg(pi,
+ RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+ 1, 0);
+ }
+ } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 3), 0,
+ 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ }
+ }
+ } else {
+ pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+ pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+
+ mask = ((0x3 << 12) | (0x3 << 14));
+ val = (0x2 << 12);
+ val |= (0x2 << 14);
+ mod_phy_reg(pi, 0xa6, mask, val);
+ mod_phy_reg(pi, 0xa7, mask, val);
+
+ val = read_phy_reg(pi, 0xa5);
+ pi->tx_rx_cal_phy_saveregs[2] = val;
+ val |= ((0x1 << 12) | (0x1 << 13));
+ write_phy_reg(pi, 0xa5, val);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+ &val);
+ pi->tx_rx_cal_phy_saveregs[3] = val;
+ val |= 0x2000;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+ &val);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+ &val);
+ pi->tx_rx_cal_phy_saveregs[4] = val;
+ val |= 0x2000;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+ &val);
+
+ pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
+ pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
+ val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+ write_phy_reg(pi, 0x91, val);
+ write_phy_reg(pi, 0x92, val);
+ }
+}
+
+static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi)
+{
+ uint16 mask;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
+ write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
+ write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
+ write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
+ write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+ &pi->tx_rx_cal_phy_saveregs[5]);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+ &pi->tx_rx_cal_phy_saveregs[6]);
+
+ write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
+ write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
+
+ write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+ write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)
+ || NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+ 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ }
+
+ wlc_phy_resetcca_nphy(pi);
+
+ if (pi->use_int_tx_iqlo_cal_nphy
+ && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ mod_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+ 1, 1);
+ mod_radio_reg(pi,
+ RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+ 1, 1);
+ } else {
+ mod_radio_reg(pi,
+ RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+ 1, 1);
+ mod_radio_reg(pi,
+ RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+ 1, 1);
+ }
+
+ mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+ 0);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 3), 0,
+ 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ }
+ }
+ } else {
+ mask = ((0x3 << 12) | (0x3 << 14));
+ mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
+ mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
+ write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+ &pi->tx_rx_cal_phy_saveregs[3]);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+ &pi->tx_rx_cal_phy_saveregs[4]);
+
+ write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
+ write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
+ }
+}
+
+#define NPHY_CAL_TSSISAMPS 64
+#define NPHY_TEST_TONE_FREQ_40MHz 4000
+#define NPHY_TEST_TONE_FREQ_20MHz 2500
+
+void
+wlc_phy_est_tonepwr_nphy(phy_info_t *pi, int32 *qdBm_pwrbuf, uint8 num_samps)
+{
+ uint16 tssi_reg;
+ int32 temp, pwrindex[2];
+ int32 idle_tssi[2];
+ int32 rssi_buf[4];
+ int32 tssival[2];
+ uint8 tssi_type;
+
+ tssi_reg = read_phy_reg(pi, 0x1e9);
+
+ temp = (int32) (tssi_reg & 0x3f);
+ idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
+
+ temp = (int32) ((tssi_reg >> 8) & 0x3f);
+ idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
+
+ tssi_type =
+ CHSPEC_IS5G(pi->radio_chanspec) ?
+ (uint8)NPHY_RSSI_SEL_TSSI_5G:(uint8)NPHY_RSSI_SEL_TSSI_2G;
+
+ wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
+
+ tssival[0] = rssi_buf[0] / ((int32) num_samps);
+ tssival[1] = rssi_buf[2] / ((int32) num_samps);
+
+ pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
+ pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
+
+ if (pwrindex[0] < 0) {
+ pwrindex[0] = 0;
+ } else if (pwrindex[0] > 63) {
+ pwrindex[0] = 63;
+ }
+
+ if (pwrindex[1] < 0) {
+ pwrindex[1] = 0;
+ } else if (pwrindex[1] > 63) {
+ pwrindex[1] = 63;
+ }
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
+ (uint32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
+ (uint32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
+}
+
+static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi)
+{
+ uint16 txcal_gain[2];
+
+ pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
+ pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
+ wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], TRUE);
+ wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], TRUE);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ txcal_gain);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
+ txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
+ } else {
+ txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
+ txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ txcal_gain);
+}
+
+static void wlc_phy_precal_txgain_nphy(phy_info_t *pi)
+{
+ bool save_bbmult = FALSE;
+ uint8 txcal_index_2057_rev5n7 = 0;
+ uint8 txcal_index_2057_rev3n4n6 = 10;
+
+ if (pi->use_int_tx_iqlo_cal_nphy) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+
+ pi->nphy_txcal_pwr_idx[0] =
+ txcal_index_2057_rev3n4n6;
+ pi->nphy_txcal_pwr_idx[1] =
+ txcal_index_2057_rev3n4n6;
+ wlc_phy_txpwr_index_nphy(pi, 3,
+ txcal_index_2057_rev3n4n6,
+ FALSE);
+ } else {
+
+ pi->nphy_txcal_pwr_idx[0] =
+ txcal_index_2057_rev5n7;
+ pi->nphy_txcal_pwr_idx[1] =
+ txcal_index_2057_rev5n7;
+ wlc_phy_txpwr_index_nphy(pi, 3,
+ txcal_index_2057_rev5n7,
+ FALSE);
+ }
+ save_bbmult = TRUE;
+
+ } else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+ wlc_phy_cal_txgainctrl_nphy(pi, 11, FALSE);
+ if (pi->sh->hw_phytxchain != 3) {
+ pi->nphy_txcal_pwr_idx[1] =
+ pi->nphy_txcal_pwr_idx[0];
+ wlc_phy_txpwr_index_nphy(pi, 3,
+ pi->
+ nphy_txcal_pwr_idx[0],
+ TRUE);
+ save_bbmult = TRUE;
+ }
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+ if (PHY_IPA(pi)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ wlc_phy_cal_txgainctrl_nphy(pi, 12,
+ FALSE);
+ } else {
+ pi->nphy_txcal_pwr_idx[0] = 80;
+ pi->nphy_txcal_pwr_idx[1] = 80;
+ wlc_phy_txpwr_index_nphy(pi, 3, 80,
+ FALSE);
+ save_bbmult = TRUE;
+ }
+ } else {
+
+ wlc_phy_internal_cal_txgain_nphy(pi);
+ save_bbmult = TRUE;
+ }
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+ if (PHY_IPA(pi)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ wlc_phy_cal_txgainctrl_nphy(pi, 12,
+ FALSE);
+ } else {
+ wlc_phy_cal_txgainctrl_nphy(pi, 14,
+ FALSE);
+ }
+ } else {
+
+ wlc_phy_internal_cal_txgain_nphy(pi);
+ save_bbmult = TRUE;
+ }
+ }
+
+ } else {
+ wlc_phy_cal_txgainctrl_nphy(pi, 10, FALSE);
+ }
+
+ if (save_bbmult) {
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+ &pi->nphy_txcal_bbmult);
+ }
+}
+
+void
+wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, int32 dBm_targetpower, bool debug)
+{
+ int gainctrl_loopidx;
+ uint core;
+ uint16 m0m1, curr_m0m1;
+ int32 delta_power;
+ int32 txpwrindex;
+ int32 qdBm_power[2];
+ uint16 orig_BBConfig;
+ uint16 phy_saveregs[4];
+ uint32 freq_test;
+ uint16 ampl_test = 250;
+ uint stepsize;
+ bool phyhang_avoid_state = FALSE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ stepsize = 2;
+ } else {
+
+ stepsize = 1;
+ }
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ freq_test = 5000;
+ } else {
+ freq_test = 2500;
+ }
+
+ wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], TRUE);
+ wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], TRUE);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ phyhang_avoid_state = pi->phyhang_avoid;
+ pi->phyhang_avoid = FALSE;
+
+ phy_saveregs[0] = read_phy_reg(pi, 0x91);
+ phy_saveregs[1] = read_phy_reg(pi, 0x92);
+ phy_saveregs[2] = read_phy_reg(pi, 0xe7);
+ phy_saveregs[3] = read_phy_reg(pi, 0xec);
+ wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
+ RADIO_MIMO_CORESEL_CORE1 |
+ RADIO_MIMO_CORESEL_CORE2);
+
+ if (!debug) {
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x2, RADIO_MIMO_CORESEL_CORE1);
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x8, RADIO_MIMO_CORESEL_CORE2);
+ } else {
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x1, RADIO_MIMO_CORESEL_CORE1);
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x7, RADIO_MIMO_CORESEL_CORE2);
+ }
+
+ orig_BBConfig = read_phy_reg(pi, 0x01);
+ mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ txpwrindex = (int32) pi->nphy_cal_orig_pwr_idx[core];
+
+ for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
+ gainctrl_loopidx++) {
+ wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+ FALSE);
+
+ if (core == PHY_CORE_0) {
+ curr_m0m1 = m0m1 & 0xff00;
+ } else {
+ curr_m0m1 = m0m1 & 0x00ff;
+ }
+
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
+ wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
+
+ OSL_DELAY(50);
+
+ wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+ NPHY_CAL_TSSISAMPS);
+
+ pi->nphy_bb_mult_save = 0;
+ wlc_phy_stopplayback_nphy(pi);
+
+ delta_power = (dBm_targetpower * 4) - qdBm_power[core];
+
+ txpwrindex -= stepsize * delta_power;
+ if (txpwrindex < 0) {
+ txpwrindex = 0;
+ } else if (txpwrindex > 127) {
+ txpwrindex = 127;
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (NREV_IS(pi->pubpi.phy_rev, 4) &&
+ (pi->srom_fem5g.extpagain == 3)) {
+ if (txpwrindex < 30) {
+ txpwrindex = 30;
+ }
+ }
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+ (pi->srom_fem2g.extpagain == 3)) {
+ if (txpwrindex < 50) {
+ txpwrindex = 50;
+ }
+ }
+ }
+
+ wlc_phy_txpwr_index_nphy(pi, (1 << core),
+ (uint8) txpwrindex, TRUE);
+ }
+
+ pi->nphy_txcal_pwr_idx[core] = (uint8) txpwrindex;
+
+ if (debug) {
+ uint16 radio_gain;
+ uint16 dbg_m0m1;
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+
+ wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+ FALSE);
+
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+ wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
+
+ OSL_DELAY(100);
+
+ wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+ NPHY_CAL_TSSISAMPS);
+
+ wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
+ &radio_gain);
+
+ OSL_DELAY(4000000);
+ pi->nphy_bb_mult_save = 0;
+ wlc_phy_stopplayback_nphy(pi);
+ }
+ }
+
+ wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], TRUE);
+ wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], TRUE);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
+
+ write_phy_reg(pi, 0x01, orig_BBConfig);
+
+ write_phy_reg(pi, 0x91, phy_saveregs[0]);
+ write_phy_reg(pi, 0x92, phy_saveregs[1]);
+ write_phy_reg(pi, 0xe7, phy_saveregs[2]);
+ write_phy_reg(pi, 0xec, phy_saveregs[3]);
+
+ pi->phyhang_avoid = phyhang_avoid_state;
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, uint16 core)
+{
+ int index;
+ uint32 bbmult_scale;
+ uint16 bbmult;
+ uint16 tblentry;
+
+ nphy_txiqcal_ladder_t ladder_lo[] = {
+ {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+ {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
+ {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
+ };
+
+ nphy_txiqcal_ladder_t ladder_iq[] = {
+ {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+ {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
+ {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
+ };
+
+ bbmult = (core == PHY_CORE_0) ?
+ ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi->
+ nphy_txcal_bbmult & 0xff);
+
+ for (index = 0; index < 18; index++) {
+ bbmult_scale = ladder_lo[index].percent * bbmult;
+ bbmult_scale /= 100;
+
+ tblentry =
+ ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
+ &tblentry);
+
+ bbmult_scale = ladder_iq[index].percent * bbmult;
+ bbmult_scale /= 100;
+
+ tblentry =
+ ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
+ 16, &tblentry);
+ }
+}
+
+void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, uint8 caltype)
+{
+ nphy_txgains_t target_gain;
+ uint8 tx_pwr_ctrl_state;
+ bool fullcal = TRUE;
+ bool restore_tx_gain = FALSE;
+ bool mphase;
+
+ if (NORADIO_ENAB(pi->pubpi)) {
+ wlc_phy_cal_perical_mphase_reset(pi);
+ return;
+ }
+
+ if (PHY_MUTED(pi))
+ return;
+
+ ASSERT(pi->nphy_perical != PHY_PERICAL_DISABLE);
+
+ if (caltype == PHY_PERICAL_AUTO)
+ fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
+ else if (caltype == PHY_PERICAL_PARTIAL)
+ fullcal = FALSE;
+
+ if (pi->cal_type_override != PHY_PERICAL_AUTO) {
+ fullcal =
+ (pi->cal_type_override == PHY_PERICAL_FULL) ? TRUE : FALSE;
+ }
+
+ if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
+ if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
+ wlc_phy_cal_perical_mphase_restart(pi);
+ }
+
+ if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) {
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+ }
+
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ wlc_phyreg_enter((wlc_phy_t *) pi);
+
+ if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
+ (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
+ pi->nphy_cal_orig_pwr_idx[0] =
+ (uint8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
+ pi->nphy_cal_orig_pwr_idx[1] =
+ (uint8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
+
+ if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
+ 0x110, 16,
+ pi->nphy_cal_orig_tx_gain);
+ } else {
+ pi->nphy_cal_orig_tx_gain[0] = 0;
+ pi->nphy_cal_orig_tx_gain[1] = 0;
+ }
+ }
+ target_gain = wlc_phy_get_tx_gain_nphy(pi);
+ tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+ wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+
+ if (pi->antsel_type == ANTSEL_2x3)
+ wlc_phy_antsel_init((wlc_phy_t *) pi, TRUE);
+
+ mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
+ if (!mphase) {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_precal_txgain_nphy(pi);
+ pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+ restore_tx_gain = TRUE;
+
+ target_gain = pi->nphy_cal_target_gain;
+ }
+ if (BCME_OK ==
+ wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) {
+ if (PHY_IPA(pi))
+ wlc_phy_a4(pi, TRUE);
+
+ wlc_phyreg_exit((wlc_phy_t *) pi);
+ wlapi_enable_mac(pi->sh->physhim);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
+ 10000);
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ wlc_phyreg_enter((wlc_phy_t *) pi);
+
+ if (BCME_OK == wlc_phy_cal_rxiq_nphy(pi, target_gain,
+ (pi->
+ first_cal_after_assoc
+ || (pi->
+ cal_type_override
+ ==
+ PHY_PERICAL_FULL))
+ ? 2 : 0, FALSE)) {
+ wlc_phy_savecal_nphy(pi);
+
+ wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+
+ pi->nphy_perical_last = pi->sh->now;
+ }
+ }
+ if (caltype != PHY_PERICAL_AUTO) {
+ wlc_phy_rssi_cal_nphy(pi);
+ }
+
+ if (pi->first_cal_after_assoc
+ || (pi->cal_type_override == PHY_PERICAL_FULL)) {
+ pi->first_cal_after_assoc = FALSE;
+ wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+ wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_radio205x_vcocal_nphy(pi);
+ }
+ } else {
+ ASSERT(pi->nphy_perical >= PHY_PERICAL_MPHASE);
+
+ switch (pi->mphase_cal_phase_id) {
+ case MPHASE_CAL_STATE_INIT:
+ pi->nphy_perical_last = pi->sh->now;
+ pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_precal_txgain_nphy(pi);
+ }
+ pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+ pi->mphase_cal_phase_id++;
+ break;
+
+ case MPHASE_CAL_STATE_TXPHASE0:
+ case MPHASE_CAL_STATE_TXPHASE1:
+ case MPHASE_CAL_STATE_TXPHASE2:
+ case MPHASE_CAL_STATE_TXPHASE3:
+ case MPHASE_CAL_STATE_TXPHASE4:
+ case MPHASE_CAL_STATE_TXPHASE5:
+ if ((pi->radar_percal_mask & 0x10) != 0)
+ pi->nphy_rxcal_active = TRUE;
+
+ if (wlc_phy_cal_txiqlo_nphy
+ (pi, pi->nphy_cal_target_gain, fullcal,
+ TRUE) != BCME_OK) {
+
+ wlc_phy_cal_perical_mphase_reset(pi);
+ break;
+ }
+
+ if (NREV_LE(pi->pubpi.phy_rev, 2) &&
+ (pi->mphase_cal_phase_id ==
+ MPHASE_CAL_STATE_TXPHASE4)) {
+ pi->mphase_cal_phase_id += 2;
+ } else {
+ pi->mphase_cal_phase_id++;
+ }
+ break;
+
+ case MPHASE_CAL_STATE_PAPDCAL:
+ if ((pi->radar_percal_mask & 0x2) != 0)
+ pi->nphy_rxcal_active = TRUE;
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_a4(pi, TRUE);
+ }
+ pi->mphase_cal_phase_id++;
+ break;
+
+ case MPHASE_CAL_STATE_RXCAL:
+ if ((pi->radar_percal_mask & 0x1) != 0)
+ pi->nphy_rxcal_active = TRUE;
+ if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
+ (pi->first_cal_after_assoc ||
+ (pi->cal_type_override ==
+ PHY_PERICAL_FULL)) ? 2 : 0,
+ FALSE) == BCME_OK) {
+ wlc_phy_savecal_nphy(pi);
+ }
+
+ pi->mphase_cal_phase_id++;
+ break;
+
+ case MPHASE_CAL_STATE_RSSICAL:
+ if ((pi->radar_percal_mask & 0x4) != 0)
+ pi->nphy_rxcal_active = TRUE;
+ wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+ wlc_phy_rssi_cal_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_radio205x_vcocal_nphy(pi);
+ }
+ restore_tx_gain = TRUE;
+
+ if (pi->first_cal_after_assoc) {
+ pi->mphase_cal_phase_id++;
+ } else {
+ wlc_phy_cal_perical_mphase_reset(pi);
+ }
+
+ break;
+
+ case MPHASE_CAL_STATE_IDLETSSI:
+ if ((pi->radar_percal_mask & 0x8) != 0)
+ pi->nphy_rxcal_active = TRUE;
+
+ if (pi->first_cal_after_assoc) {
+ pi->first_cal_after_assoc = FALSE;
+ wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+ wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+ }
+
+ wlc_phy_cal_perical_mphase_reset(pi);
+ break;
+
+ default:
+ ASSERT(0);
+ wlc_phy_cal_perical_mphase_reset(pi);
+ break;
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (restore_tx_gain) {
+ if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
+
+ wlc_phy_txpwr_index_nphy(pi, 1,
+ pi->
+ nphy_cal_orig_pwr_idx
+ [0], FALSE);
+ wlc_phy_txpwr_index_nphy(pi, 2,
+ pi->
+ nphy_cal_orig_pwr_idx
+ [1], FALSE);
+
+ pi->nphy_txpwrindex[0].index = -1;
+ pi->nphy_txpwrindex[1].index = -1;
+ } else {
+ wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+ (int8) (pi->
+ nphy_txpwrindex
+ [0].
+ index_internal),
+ FALSE);
+ wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+ (int8) (pi->
+ nphy_txpwrindex
+ [1].
+ index_internal),
+ FALSE);
+ }
+ }
+ }
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+ wlc_phyreg_exit((wlc_phy_t *) pi);
+ wlapi_enable_mac(pi->sh->physhim);
+}
+
+int
+wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+ bool fullcal, bool mphase)
+{
+ uint16 val;
+ uint16 tbl_buf[11];
+ uint8 cal_cnt;
+ uint16 cal_cmd;
+ uint8 num_cals, max_cal_cmds;
+ uint16 core_no, cal_type;
+ uint16 diq_start = 0;
+ uint8 phy_bw;
+ uint16 max_val;
+ uint16 tone_freq;
+ uint16 gain_save[2];
+ uint16 cal_gain[2];
+ nphy_iqcal_params_t cal_params[2];
+ uint32 tbl_len;
+ void *tbl_ptr;
+ bool ladder_updated[2];
+ uint8 mphase_cal_lastphase = 0;
+ int bcmerror = BCME_OK;
+ bool phyhang_avoid_state = FALSE;
+
+ uint16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+ 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
+ 0x1902,
+ 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
+ 0x6407
+ };
+
+ uint16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+ 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
+ 0x3200,
+ 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
+ 0x6407
+ };
+
+ uint16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+ 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
+ 0x1202,
+ 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
+ 0x4707
+ };
+
+ uint16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+ 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
+ 0x2300,
+ 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
+ 0x4707
+ };
+
+ uint16 tbl_tx_iqlo_cal_startcoefs[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000
+ };
+
+ uint16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+ 0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
+ 0x9123, 0x9264, 0x9086, 0x9245, 0x9056
+ };
+
+ uint16 tbl_tx_iqlo_cal_cmds_recal[] = {
+ 0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
+ 0x9101, 0x9253, 0x9053, 0x9234, 0x9034
+ };
+
+ uint16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000
+ };
+
+ uint16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+ 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
+ 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
+ };
+
+ uint16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+ 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
+ 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
+ };
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ phyhang_avoid_state = pi->phyhang_avoid;
+ pi->phyhang_avoid = FALSE;
+ }
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ phy_bw = 40;
+ } else {
+ phy_bw = 20;
+ }
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+
+ for (core_no = 0; core_no <= 1; core_no++) {
+ wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+ &cal_params[core_no]);
+ cal_gain[core_no] = cal_params[core_no].cal_gain;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+
+ wlc_phy_txcal_radio_setup_nphy(pi);
+
+ wlc_phy_txcal_physetup_nphy(pi);
+
+ ladder_updated[0] = ladder_updated[1] = FALSE;
+ if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
+ (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
+ && (CHSPEC_IS2G(pi->radio_chanspec))))) {
+
+ if (phy_bw == 40) {
+ tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
+ tbl_len = ARRAYSIZE(tbl_tx_iqlo_cal_loft_ladder_40);
+ } else {
+ tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
+ tbl_len = ARRAYSIZE(tbl_tx_iqlo_cal_loft_ladder_20);
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
+ 16, tbl_ptr);
+
+ if (phy_bw == 40) {
+ tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
+ tbl_len = ARRAYSIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
+ } else {
+ tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
+ tbl_len = ARRAYSIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
+ 16, tbl_ptr);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_phy_reg(pi, 0xc2, 0x8ad9);
+ } else {
+ write_phy_reg(pi, 0xc2, 0x8aa9);
+ }
+
+ max_val = 250;
+ tone_freq = (phy_bw == 20) ? 2500 : 5000;
+
+ if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+ wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, FALSE);
+ bcmerror = BCME_OK;
+ } else {
+ bcmerror =
+ wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, FALSE);
+ }
+
+ if (bcmerror == BCME_OK) {
+
+ if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+ tbl_ptr = pi->mphase_txcal_bestcoeffs;
+ tbl_len = ARRAYSIZE(pi->mphase_txcal_bestcoeffs);
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+
+ tbl_len -= 2;
+ }
+ } else {
+ if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
+
+ tbl_ptr = pi->nphy_txiqlocal_bestc;
+ tbl_len = ARRAYSIZE(pi->nphy_txiqlocal_bestc);
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+
+ tbl_len -= 2;
+ }
+ } else {
+
+ fullcal = TRUE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ tbl_ptr =
+ tbl_tx_iqlo_cal_startcoefs_nphyrev3;
+ tbl_len =
+ ARRAYSIZE
+ (tbl_tx_iqlo_cal_startcoefs_nphyrev3);
+ } else {
+ tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
+ tbl_len =
+ ARRAYSIZE
+ (tbl_tx_iqlo_cal_startcoefs);
+ }
+ }
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
+ 16, tbl_ptr);
+
+ if (fullcal) {
+ max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+ ARRAYSIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
+ ARRAYSIZE(tbl_tx_iqlo_cal_cmds_fullcal);
+ } else {
+ max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+ ARRAYSIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
+ ARRAYSIZE(tbl_tx_iqlo_cal_cmds_recal);
+ }
+
+ if (mphase) {
+ cal_cnt = pi->mphase_txcal_cmdidx;
+ if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) {
+ num_cals = cal_cnt + pi->mphase_txcal_numcmds;
+ } else {
+ num_cals = max_cal_cmds;
+ }
+ } else {
+ cal_cnt = 0;
+ num_cals = max_cal_cmds;
+ }
+
+ for (; cal_cnt < num_cals; cal_cnt++) {
+
+ if (fullcal) {
+ cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+ tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
+ [cal_cnt] :
+ tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
+ } else {
+ cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+ tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt]
+ : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
+ }
+
+ core_no = ((cal_cmd & 0x3000) >> 12);
+ cal_type = ((cal_cmd & 0x0F00) >> 8);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6) ||
+ (NREV_IS(pi->pubpi.phy_rev, 5) &&
+ PHY_IPA(pi)
+ && (CHSPEC_IS2G(pi->radio_chanspec)))) {
+ if (!ladder_updated[core_no]) {
+ wlc_phy_update_txcal_ladder_nphy(pi,
+ core_no);
+ ladder_updated[core_no] = TRUE;
+ }
+ }
+
+ val =
+ (cal_params[core_no].
+ ncorr[cal_type] << 8) | NPHY_N_GCTL;
+ write_phy_reg(pi, 0xc1, val);
+
+ if ((cal_type == 1) || (cal_type == 3)
+ || (cal_type == 4)) {
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ 1, 69 + core_no, 16,
+ tbl_buf);
+
+ diq_start = tbl_buf[0];
+
+ tbl_buf[0] = 0;
+ wlc_phy_table_write_nphy(pi,
+ NPHY_TBL_ID_IQLOCAL, 1,
+ 69 + core_no, 16,
+ tbl_buf);
+ }
+
+ write_phy_reg(pi, 0xc0, cal_cmd);
+
+ SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
+ 20000);
+ ASSERT((read_phy_reg(pi, 0xc0) & 0xc000) == 0);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ tbl_len, 96, 16, tbl_buf);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ tbl_len, 64, 16, tbl_buf);
+
+ if ((cal_type == 1) || (cal_type == 3)
+ || (cal_type == 4)) {
+
+ tbl_buf[0] = diq_start;
+
+ }
+
+ }
+
+ if (mphase) {
+ pi->mphase_txcal_cmdidx = num_cals;
+ if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
+ pi->mphase_txcal_cmdidx = 0;
+ }
+
+ mphase_cal_lastphase =
+ (NREV_LE(pi->pubpi.phy_rev, 2)) ?
+ MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
+
+ if (!mphase
+ || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
+ 16, tbl_buf);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+ 16, tbl_buf);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+
+ tbl_buf[0] = 0;
+ tbl_buf[1] = 0;
+ tbl_buf[2] = 0;
+ tbl_buf[3] = 0;
+
+ }
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+ 16, tbl_buf);
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
+ 16, tbl_buf);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+ 16, tbl_buf);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+ 16, tbl_buf);
+
+ tbl_len = ARRAYSIZE(pi->nphy_txiqlocal_bestc);
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+
+ tbl_len -= 2;
+ }
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ tbl_len, 96, 16,
+ pi->nphy_txiqlocal_bestc);
+
+ pi->nphy_txiqlocal_coeffsvalid = TRUE;
+ pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+ } else {
+ tbl_len = ARRAYSIZE(pi->mphase_txcal_bestcoeffs);
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+
+ tbl_len -= 2;
+ }
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ tbl_len, 96, 16,
+ pi->mphase_txcal_bestcoeffs);
+ }
+
+ wlc_phy_stopplayback_nphy(pi);
+
+ write_phy_reg(pi, 0xc2, 0x0000);
+
+ }
+
+ wlc_phy_txcal_phycleanup_nphy(pi);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ gain_save);
+
+ wlc_phy_txcal_radio_cleanup_nphy(pi);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+ if (!mphase
+ || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
+ wlc_phy_tx_iq_war_nphy(pi);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ pi->phyhang_avoid = phyhang_avoid_state;
+ }
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ return bcmerror;
+}
+
+static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi)
+{
+ uint16 tbl_buf[7];
+
+ ASSERT(NREV_LT(pi->pubpi.phy_rev, 2));
+
+ if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
+ (pi->nphy_txiqlocal_coeffsvalid)) {
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+ ARRAYSIZE(tbl_buf), 80, 16, tbl_buf);
+
+ if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
+ (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
+ (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
+ (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+ 16, pi->nphy_txiqlocal_bestc);
+
+ tbl_buf[0] = 0;
+ tbl_buf[1] = 0;
+ tbl_buf[2] = 0;
+ tbl_buf[3] = 0;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+ 16, tbl_buf);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+ 16,
+ &pi->nphy_txiqlocal_bestc[5]);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+ 16,
+ &pi->nphy_txiqlocal_bestc[5]);
+ }
+ }
+}
+
+static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi)
+{
+ nphy_iq_comp_t tx_comp;
+
+ wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp);
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
+}
+
+void
+wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, uint8 write, nphy_iq_comp_t *pcomp)
+{
+ if (write) {
+ write_phy_reg(pi, 0x9a, pcomp->a0);
+ write_phy_reg(pi, 0x9b, pcomp->b0);
+ write_phy_reg(pi, 0x9c, pcomp->a1);
+ write_phy_reg(pi, 0x9d, pcomp->b1);
+ } else {
+ pcomp->a0 = read_phy_reg(pi, 0x9a);
+ pcomp->b0 = read_phy_reg(pi, 0x9b);
+ pcomp->a1 = read_phy_reg(pi, 0x9c);
+ pcomp->b1 = read_phy_reg(pi, 0x9d);
+ }
+}
+
+void
+wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, uint16 num_samps,
+ uint8 wait_time, uint8 wait_for_crs)
+{
+ uint8 core;
+
+ write_phy_reg(pi, 0x12b, num_samps);
+ mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
+ mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
+ (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
+
+ mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
+
+ SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
+ 10000);
+ ASSERT((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0);
+
+ if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
+ ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ est[core].i_pwr =
+ (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16)
+ | read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
+ est[core].q_pwr =
+ (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16)
+ | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
+ est[core].iq_prod =
+ (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) |
+ read_phy_reg(pi, NPHY_IqestIqAccLo(core));
+ }
+ }
+}
+
+#define CAL_RETRY_CNT 2
+static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, uint8 core_mask)
+{
+ uint8 curr_core;
+ phy_iq_est_t est[PHY_CORE_MAX];
+ nphy_iq_comp_t old_comp, new_comp;
+ int32 iq = 0;
+ uint32 ii = 0, qq = 0;
+ int16 iq_nbits, qq_nbits, brsh, arsh;
+ int32 a, b, temp;
+ int bcmerror = BCME_OK;
+ uint cal_retry = 0;
+
+ if (core_mask == 0x0)
+ return;
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
+ new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+
+ cal_try:
+ wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
+
+ new_comp = old_comp;
+
+ for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
+
+ if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+ iq = est[curr_core].iq_prod;
+ ii = est[curr_core].i_pwr;
+ qq = est[curr_core].q_pwr;
+ } else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+ iq = est[curr_core].iq_prod;
+ ii = est[curr_core].i_pwr;
+ qq = est[curr_core].q_pwr;
+ } else {
+ continue;
+ }
+
+ if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+
+ iq_nbits = wlc_phy_nbits(iq);
+ qq_nbits = wlc_phy_nbits(qq);
+
+ arsh = 10 - (30 - iq_nbits);
+ if (arsh >= 0) {
+ a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+ temp = (int32) (ii >> arsh);
+ if (temp == 0) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ } else {
+ a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+ temp = (int32) (ii << -arsh);
+ if (temp == 0) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ }
+
+ a /= temp;
+
+ brsh = qq_nbits - 31 + 20;
+ if (brsh >= 0) {
+ b = (qq << (31 - qq_nbits));
+ temp = (int32) (ii >> brsh);
+ if (temp == 0) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ } else {
+ b = (qq << (31 - qq_nbits));
+ temp = (int32) (ii << -brsh);
+ if (temp == 0) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ }
+ b /= temp;
+ b -= a * a;
+ b = (int32) wlc_phy_sqrt_int((uint32) b);
+ b -= (1 << 10);
+
+ if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ new_comp.a0 = (int16) a & 0x3ff;
+ new_comp.b0 = (int16) b & 0x3ff;
+ } else {
+
+ new_comp.a0 = (int16) b & 0x3ff;
+ new_comp.b0 = (int16) a & 0x3ff;
+ }
+ }
+ if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ new_comp.a1 = (int16) a & 0x3ff;
+ new_comp.b1 = (int16) b & 0x3ff;
+ } else {
+
+ new_comp.a1 = (int16) b & 0x3ff;
+ new_comp.b1 = (int16) a & 0x3ff;
+ }
+ }
+ }
+
+ if (bcmerror != BCME_OK) {
+ printk("%s: Failed, cnt = %d\n", __func__, cal_retry);
+
+ if (cal_retry < CAL_RETRY_CNT) {
+ cal_retry++;
+ goto cal_try;
+ }
+
+ new_comp = old_comp;
+ } else if (cal_retry > 0) {
+ }
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+}
+
+static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, uint8 rx_core)
+{
+ uint16 offtune_val;
+ uint16 bias_g = 0;
+ uint16 bias_a = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (rx_core == PHY_CORE_0) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
+
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+ 0x3);
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+ 0xaf);
+
+ } else {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
+
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+ 0x3);
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+ 0x7f);
+ }
+
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
+
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+ 0x3);
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+ 0xaf);
+
+ } else {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
+
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+ 0x3);
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+ 0x7f);
+ }
+ }
+
+ } else {
+ if (rx_core == PHY_CORE_0) {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX1);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX0);
+
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[2] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX0);
+ pi->tx_rx_cal_radio_saveregs[3] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX1);
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX0);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX0, 0x40);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX1, bias_a);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX0, bias_a);
+ } else {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE
+ | RADIO_2056_RX0);
+
+ offtune_val =
+ (pi->
+ tx_rx_cal_radio_saveregs[2] & 0xF0)
+ >> 8;
+ offtune_val =
+ (offtune_val <= 0x7) ? 0xF : 0;
+
+ mod_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE |
+ RADIO_2056_RX0, 0xF0,
+ (offtune_val << 8));
+ }
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX1, 0x9);
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX0, 0x9);
+ } else {
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX0);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX0, 0x40);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX1, bias_g);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX0, bias_g);
+
+ } else {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE
+ | RADIO_2056_RX0);
+
+ offtune_val =
+ (pi->
+ tx_rx_cal_radio_saveregs[2] & 0xF0)
+ >> 8;
+ offtune_val =
+ (offtune_val <= 0x7) ? 0xF : 0;
+
+ mod_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE |
+ RADIO_2056_RX0, 0xF0,
+ (offtune_val << 8));
+ }
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX1, 0x6);
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX0, 0x6);
+ }
+
+ } else {
+ pi->tx_rx_cal_radio_saveregs[0] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX0);
+ pi->tx_rx_cal_radio_saveregs[1] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX1);
+
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[2] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX1);
+ pi->tx_rx_cal_radio_saveregs[3] =
+ read_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX0);
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX1);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX1, 0x40);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX0, bias_a);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX1, bias_a);
+ } else {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE
+ | RADIO_2056_RX1);
+
+ offtune_val =
+ (pi->
+ tx_rx_cal_radio_saveregs[2] & 0xF0)
+ >> 8;
+ offtune_val =
+ (offtune_val <= 0x7) ? 0xF : 0;
+
+ mod_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE |
+ RADIO_2056_RX1, 0xF0,
+ (offtune_val << 8));
+ }
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX0, 0x9);
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX1, 0x9);
+ } else {
+ if (pi->pubpi.radiorev >= 5) {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX1);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX1, 0x40);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX0, bias_g);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX1, bias_g);
+ } else {
+ pi->tx_rx_cal_radio_saveregs[4] =
+ read_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE
+ | RADIO_2056_RX1);
+
+ offtune_val =
+ (pi->
+ tx_rx_cal_radio_saveregs[2] & 0xF0)
+ >> 8;
+ offtune_val =
+ (offtune_val <= 0x7) ? 0xF : 0;
+
+ mod_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE |
+ RADIO_2056_RX1, 0xF0,
+ (offtune_val << 8));
+ }
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX0, 0x6);
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX1, 0x6);
+ }
+ }
+ }
+}
+
+static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, uint8 rx_core)
+{
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (rx_core == PHY_CORE_0) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+ pi->
+ tx_rx_cal_radio_saveregs[0]);
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+ pi->
+ tx_rx_cal_radio_saveregs[1]);
+
+ } else {
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+ pi->
+ tx_rx_cal_radio_saveregs[0]);
+ write_radio_reg(pi,
+ RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+ pi->
+ tx_rx_cal_radio_saveregs[1]);
+ }
+
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+ pi->
+ tx_rx_cal_radio_saveregs[0]);
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+ pi->
+ tx_rx_cal_radio_saveregs[1]);
+
+ } else {
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+ pi->
+ tx_rx_cal_radio_saveregs[0]);
+ write_radio_reg(pi,
+ RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+ pi->
+ tx_rx_cal_radio_saveregs[1]);
+ }
+ }
+
+ } else {
+ if (rx_core == PHY_CORE_0) {
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX1,
+ pi->tx_rx_cal_radio_saveregs[0]);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX0,
+ pi->tx_rx_cal_radio_saveregs[1]);
+
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX0,
+ pi->
+ tx_rx_cal_radio_saveregs[2]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX1,
+ pi->
+ tx_rx_cal_radio_saveregs[3]);
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX0,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE
+ | RADIO_2056_RX0,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ }
+ } else {
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX0,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE
+ | RADIO_2056_RX0,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ }
+ }
+
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_TX_RXIQCAL_TXMUX |
+ RADIO_2056_TX0,
+ pi->tx_rx_cal_radio_saveregs[0]);
+
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXIQCAL_RXMUX |
+ RADIO_2056_RX1,
+ pi->tx_rx_cal_radio_saveregs[1]);
+
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_RXSPARE2 |
+ RADIO_2056_RX1,
+ pi->
+ tx_rx_cal_radio_saveregs[2]);
+
+ write_radio_reg(pi,
+ RADIO_2056_TX_TXSPARE2 |
+ RADIO_2056_TX0,
+ pi->
+ tx_rx_cal_radio_saveregs[3]);
+ }
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_MASTER
+ | RADIO_2056_RX1,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAA_TUNE
+ | RADIO_2056_RX1,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ }
+ } else {
+ if (pi->pubpi.radiorev >= 5) {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_MASTER
+ | RADIO_2056_RX1,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ } else {
+ write_radio_reg(pi,
+ RADIO_2056_RX_LNAG_TUNE
+ | RADIO_2056_RX1,
+ pi->
+ tx_rx_cal_radio_saveregs
+ [4]);
+ }
+ }
+ }
+ }
+}
+
+static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, uint8 rx_core)
+{
+ uint8 tx_core;
+ uint16 rx_antval, tx_antval;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ tx_core = rx_core;
+ } else {
+ tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
+ }
+
+ pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
+ pi->tx_rx_cal_phy_saveregs[1] =
+ read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
+ pi->tx_rx_cal_phy_saveregs[2] =
+ read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
+ pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
+ pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
+ pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
+ pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
+ pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
+ pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
+ pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
+ pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
+ pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
+ }
+
+ pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+ pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+
+ mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
+
+ } else {
+
+ mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+ mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+ mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
+ mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
+ }
+
+ mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
+ mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+ (0x1 << 2), (0x1 << 2));
+ if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+ mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+ (0x1 << 0) | (0x1 << 1), 0);
+ mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+ 0x8f : 0xa5,
+ (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
+ }
+
+ wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
+ RADIO_MIMO_CORESEL_CORE1 |
+ RADIO_MIMO_CORESEL_CORE2);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+ 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 7),
+ 2, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ } else {
+ wlc_phy_rfctrl_override_nphy_rev7(pi,
+ (0x1 << 7),
+ 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ }
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+ 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
+ }
+
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ 0x1, rx_core + 1);
+ } else {
+
+ if (rx_core == PHY_CORE_0) {
+ rx_antval = 0x1;
+ tx_antval = 0x8;
+ } else {
+ rx_antval = 0x4;
+ tx_antval = 0x2;
+ }
+
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ rx_antval, rx_core + 1);
+ wlc_phy_rfctrlintc_override_nphy(pi,
+ NPHY_RfctrlIntc_override_TRSW,
+ tx_antval, tx_core + 1);
+ }
+}
+
+static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, uint8 rx_core)
+{
+
+ write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
+ write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
+ pi->tx_rx_cal_phy_saveregs[1]);
+ write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+ pi->tx_rx_cal_phy_saveregs[2]);
+ write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
+ write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
+
+ write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
+ write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
+ write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
+ write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
+ write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
+ write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
+ write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
+ }
+
+ write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+ write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+}
+
+static void
+wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, uint8 rx_core,
+ uint16 *rxgain, uint8 cal_type)
+{
+
+ uint16 num_samps;
+ phy_iq_est_t est[PHY_CORE_MAX];
+ uint8 tx_core;
+ nphy_iq_comp_t save_comp, zero_comp;
+ uint32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr =
+ 10000;
+ int16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
+ bool gainctrl_done = FALSE;
+ uint8 mix_tia_gain = 3;
+ int8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
+ int8 curr_gaintbl_index = 3;
+ uint8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
+ nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl;
+ uint16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
+ int16 fine_gain_idx;
+ int8 txpwrindex;
+ uint16 nphy_rxcal_txgain[2];
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ tx_core = rx_core;
+ } else {
+ tx_core = 1 - rx_core;
+ }
+
+ num_samps = 1024;
+ desired_log2_pwr = (cal_type == 0) ? 13 : 13;
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
+ zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mix_tia_gain = 3;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ mix_tia_gain = 4;
+ } else {
+ mix_tia_gain = 6;
+ }
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
+ } else {
+ nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
+ }
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
+ } else {
+ nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
+ }
+ }
+
+ do {
+
+ hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
+ 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
+ lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
+ lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
+ lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
+ lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
+ txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_rxgain,
+ ((lpf_biq1 << 12) |
+ (lpf_biq0 << 8) |
+ (mix_tia_gain <<
+ 4) | (lna2 << 2)
+ | lna1), 0x3, 0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+ ((hpvga << 12) |
+ (lpf_biq1 << 10) |
+ (lpf_biq0 << 8) |
+ (mix_tia_gain << 4) |
+ (lna2 << 2) | lna1), 0x3,
+ 0);
+ }
+
+ pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
+
+ if (txpwrindex == -1) {
+ nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
+ nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+ 2, 0x110, 16,
+ nphy_rxcal_txgain);
+ } else {
+ wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
+ FALSE);
+ }
+
+ wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
+ NPHY_RXCAL_TONEFREQ_40MHz :
+ NPHY_RXCAL_TONEFREQ_20MHz,
+ NPHY_RXCAL_TONEAMP, 0, cal_type, FALSE);
+
+ wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+ i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
+ q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
+ curr_pwr = i_pwr + q_pwr;
+
+ switch (gainctrl_dirn) {
+ case NPHY_RXCAL_GAIN_INIT:
+ if (curr_pwr > thresh_pwr) {
+ gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
+ prev_gaintbl_index = curr_gaintbl_index;
+ curr_gaintbl_index--;
+ } else {
+ gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
+ prev_gaintbl_index = curr_gaintbl_index;
+ curr_gaintbl_index++;
+ }
+ break;
+
+ case NPHY_RXCAL_GAIN_UP:
+ if (curr_pwr > thresh_pwr) {
+ gainctrl_done = TRUE;
+ optim_pwr = prev_pwr;
+ optim_gaintbl_index = prev_gaintbl_index;
+ } else {
+ prev_gaintbl_index = curr_gaintbl_index;
+ curr_gaintbl_index++;
+ }
+ break;
+
+ case NPHY_RXCAL_GAIN_DOWN:
+ if (curr_pwr > thresh_pwr) {
+ prev_gaintbl_index = curr_gaintbl_index;
+ curr_gaintbl_index--;
+ } else {
+ gainctrl_done = TRUE;
+ optim_pwr = curr_pwr;
+ optim_gaintbl_index = curr_gaintbl_index;
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ if ((curr_gaintbl_index < 0) ||
+ (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
+ gainctrl_done = TRUE;
+ optim_pwr = curr_pwr;
+ optim_gaintbl_index = prev_gaintbl_index;
+ } else {
+ prev_pwr = curr_pwr;
+ }
+
+ wlc_phy_stopplayback_nphy(pi);
+ } while (!gainctrl_done);
+
+ hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
+ lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
+ lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
+ lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
+ lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
+ txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
+
+ actual_log2_pwr = wlc_phy_nbits(optim_pwr);
+ delta_pwr = desired_log2_pwr - actual_log2_pwr;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ fine_gain_idx = (int)lpf_biq1 + delta_pwr;
+
+ if (fine_gain_idx + (int)lpf_biq0 > 10) {
+ lpf_biq1 = 10 - lpf_biq0;
+ } else {
+ lpf_biq1 = (uint16) MAX(fine_gain_idx, 0);
+ }
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_rxgain,
+ ((lpf_biq1 << 12) |
+ (lpf_biq0 << 8) |
+ (mix_tia_gain << 4) |
+ (lna2 << 2) | lna1), 0x3,
+ 0);
+ } else {
+ hpvga = (uint16) MAX(MIN(((int)hpvga) + delta_pwr, 10), 0);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+ ((hpvga << 12) | (lpf_biq1 << 10) |
+ (lpf_biq0 << 8) | (mix_tia_gain <<
+ 4) | (lna2 <<
+ 2) |
+ lna1), 0x3, 0);
+
+ }
+
+ if (rxgain != NULL) {
+ *rxgain++ = lna1;
+ *rxgain++ = lna2;
+ *rxgain++ = mix_tia_gain;
+ *rxgain++ = lpf_biq0;
+ *rxgain++ = lpf_biq1;
+ *rxgain = hpvga;
+ }
+
+ wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
+}
+
+static void
+wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, uint8 rx_core, uint16 *rxgain,
+ uint8 cal_type)
+{
+ wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
+}
+
+static uint8
+wlc_phy_rc_sweep_nphy(phy_info_t *pi, uint8 core_idx, uint8 loopback_type)
+{
+ uint32 target_bws[2] = { 9500, 21000 };
+ uint32 ref_tones[2] = { 3000, 6000 };
+ uint32 target_bw, ref_tone;
+
+ uint32 target_pwr_ratios[2] = { 28606, 18468 };
+ uint32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
+
+ uint16 start_rccal_ovr_val = 128;
+ uint16 txlpf_rccal_lpc_ovr_val = 128;
+ uint16 rxlpf_rccal_hpc_ovr_val = 159;
+
+ uint16 orig_txlpf_rccal_lpc_ovr_val;
+ uint16 orig_rxlpf_rccal_hpc_ovr_val;
+ uint16 radio_addr_offset_rx;
+ uint16 radio_addr_offset_tx;
+ uint16 orig_dcBypass;
+ uint16 orig_RxStrnFilt40Num[6];
+ uint16 orig_RxStrnFilt40Den[4];
+ uint16 orig_rfctrloverride[2];
+ uint16 orig_rfctrlauxreg[2];
+ uint16 orig_rfctrlrssiothers;
+ uint16 tx_lpf_bw = 4;
+
+ uint16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
+ uint16 lpf_hpc = 7, hpvga_hpc = 7;
+
+ int8 rccal_stepsize;
+ uint16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
+ uint32 ref_iq_vals = 0, target_iq_vals = 0;
+ uint16 num_samps, log_num_samps = 10;
+ phy_iq_est_t est[PHY_CORE_MAX];
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ return 0;
+ }
+
+ num_samps = (1 << log_num_samps);
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ target_bw = target_bws[1];
+ target_pwr_ratio = target_pwr_ratios[1];
+ ref_tone = ref_tones[1];
+ rx_lpf_bw = rx_lpf_bws[1];
+ } else {
+ target_bw = target_bws[0];
+ target_pwr_ratio = target_pwr_ratios[0];
+ ref_tone = ref_tones[0];
+ rx_lpf_bw = rx_lpf_bws[0];
+ }
+
+ if (core_idx == 0) {
+ radio_addr_offset_rx = RADIO_2056_RX0;
+ radio_addr_offset_tx =
+ (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+ } else {
+ radio_addr_offset_rx = RADIO_2056_RX1;
+ radio_addr_offset_tx =
+ (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
+ }
+
+ orig_txlpf_rccal_lpc_ovr_val =
+ read_radio_reg(pi,
+ (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx));
+ orig_rxlpf_rccal_hpc_ovr_val =
+ read_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+ radio_addr_offset_rx));
+
+ orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
+
+ orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
+ orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
+ orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
+ orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
+ orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
+ orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
+ orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
+ orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
+ orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
+ orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
+
+ orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
+ orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
+ orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
+ orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
+ orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
+
+ write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+ txlpf_rccal_lpc_ovr_val);
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+ rxlpf_rccal_hpc_ovr_val);
+
+ mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
+
+ write_phy_reg(pi, 0x267, 0x02d4);
+ write_phy_reg(pi, 0x268, 0x0000);
+ write_phy_reg(pi, 0x269, 0x0000);
+ write_phy_reg(pi, 0x26a, 0x0000);
+ write_phy_reg(pi, 0x26b, 0x0000);
+ write_phy_reg(pi, 0x26c, 0x02d4);
+ write_phy_reg(pi, 0x26d, 0x0000);
+ write_phy_reg(pi, 0x26e, 0x0000);
+ write_phy_reg(pi, 0x26f, 0x0000);
+ write_phy_reg(pi, 0x270, 0x0000);
+
+ or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
+ or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
+ or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
+ or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
+
+ mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
+ (0x7 << 10), (tx_lpf_bw << 10));
+ mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+ (0x7 << 0), (hpvga_hpc << 0));
+ mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+ (0x7 << 4), (lpf_hpc << 4));
+ mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
+ (0x7 << 8), (rx_lpf_bw << 8));
+
+ rccal_stepsize = 16;
+ rccal_val = start_rccal_ovr_val + rccal_stepsize;
+
+ while (rccal_stepsize >= 0) {
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_LPC |
+ radio_addr_offset_rx), rccal_val);
+
+ if (rccal_stepsize == 16) {
+
+ wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
+ 0, 1, FALSE);
+ OSL_DELAY(2);
+
+ wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+
+ if (core_idx == 0) {
+ ref_iq_vals =
+ MAX((est[0].i_pwr +
+ est[0].q_pwr) >> (log_num_samps + 1),
+ 1);
+ } else {
+ ref_iq_vals =
+ MAX((est[1].i_pwr +
+ est[1].q_pwr) >> (log_num_samps + 1),
+ 1);
+ }
+
+ wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
+ 0, 1, FALSE);
+ OSL_DELAY(2);
+ }
+
+ wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+
+ if (core_idx == 0) {
+ target_iq_vals =
+ (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps +
+ 1);
+ } else {
+ target_iq_vals =
+ (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps +
+ 1);
+ }
+ pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
+
+ if (rccal_stepsize == 0) {
+ rccal_stepsize--;
+ } else if (rccal_stepsize == 1) {
+ last_rccal_val = rccal_val;
+ rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
+ last_pwr_ratio = pwr_ratio;
+ rccal_stepsize--;
+ } else {
+ rccal_stepsize = (rccal_stepsize >> 1);
+ rccal_val += ((pwr_ratio > target_pwr_ratio) ?
+ rccal_stepsize : (-rccal_stepsize));
+ }
+
+ if (rccal_stepsize == -1) {
+ best_rccal_val =
+ (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) <
+ ABS((int)pwr_ratio -
+ (int)target_pwr_ratio)) ? last_rccal_val :
+ rccal_val;
+
+ if (CHSPEC_IS40(pi->radio_chanspec)) {
+ if ((best_rccal_val > 140)
+ || (best_rccal_val < 135)) {
+ best_rccal_val = 138;
+ }
+ } else {
+ if ((best_rccal_val > 142)
+ || (best_rccal_val < 137)) {
+ best_rccal_val = 140;
+ }
+ }
+
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_LPC |
+ radio_addr_offset_rx), best_rccal_val);
+ }
+ }
+
+ wlc_phy_stopplayback_nphy(pi);
+
+ write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+ orig_txlpf_rccal_lpc_ovr_val);
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+ orig_rxlpf_rccal_hpc_ovr_val);
+
+ mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
+
+ write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
+ write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
+ write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
+ write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
+ write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
+ write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
+ write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
+ write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
+ write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
+ write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
+
+ write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
+ write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
+ write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
+ write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
+ write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
+
+ pi->nphy_anarxlpf_adjusted = FALSE;
+
+ return best_rccal_val - 0x80;
+}
+
+#define WAIT_FOR_SCOPE 4000000
+static int
+wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain,
+ uint8 cal_type, bool debug)
+{
+ uint16 orig_BBConfig;
+ uint8 core_no, rx_core;
+ uint8 best_rccal[2];
+ uint16 gain_save[2];
+ uint16 cal_gain[2];
+ nphy_iqcal_params_t cal_params[2];
+ uint8 rxcore_state;
+ int8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
+ int8 txlpf_idac;
+ bool phyhang_avoid_state = FALSE;
+ bool skip_rxiqcal = FALSE;
+
+ orig_BBConfig = read_phy_reg(pi, 0x01);
+ mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ phyhang_avoid_state = pi->phyhang_avoid;
+ pi->phyhang_avoid = FALSE;
+ }
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+
+ for (core_no = 0; core_no <= 1; core_no++) {
+ wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+ &cal_params[core_no]);
+ cal_gain[core_no] = cal_params[core_no].cal_gain;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+
+ rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+
+ for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+
+ skip_rxiqcal =
+ ((rxcore_state & (1 << rx_core)) == 0) ? TRUE : FALSE;
+
+ wlc_phy_rxcal_physetup_nphy(pi, rx_core);
+
+ wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
+
+ if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
+
+ wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
+
+ wlc_phy_tx_tone_nphy(pi,
+ (CHSPEC_IS40(pi->radio_chanspec)) ?
+ NPHY_RXCAL_TONEFREQ_40MHz :
+ NPHY_RXCAL_TONEFREQ_20MHz,
+ NPHY_RXCAL_TONEAMP, 0, cal_type,
+ FALSE);
+
+ if (debug)
+ OSL_DELAY(WAIT_FOR_SCOPE);
+
+ wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
+ wlc_phy_stopplayback_nphy(pi);
+ }
+
+ if (((cal_type == 1) || (cal_type == 2))
+ && NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ if (rx_core == PHY_CORE_1) {
+
+ if (rxcore_state == 1) {
+ wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+ *) pi, 3);
+ }
+
+ wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
+ 1);
+
+ best_rccal[rx_core] =
+ wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
+ pi->nphy_rccal_value = best_rccal[rx_core];
+
+ if (rxcore_state == 1) {
+ wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+ *) pi,
+ rxcore_state);
+ }
+ }
+ }
+
+ wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
+
+ wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+ }
+
+ if ((cal_type == 1) || (cal_type == 2)) {
+
+ best_rccal[0] = best_rccal[1];
+ write_radio_reg(pi,
+ (RADIO_2056_RX_RXLPF_RCCAL_LPC |
+ RADIO_2056_RX0), (best_rccal[0] | 0x80));
+
+ for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+ rxlpf_rccal_hpc =
+ (((int)best_rccal[rx_core] - 12) >> 1) + 10;
+ txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
+
+ if (PHY_IPA(pi)) {
+ txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12;
+ txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13;
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
+ TXLPF_IDAC_4, txlpf_idac);
+ }
+
+ rxlpf_rccal_hpc = MAX(MIN(rxlpf_rccal_hpc, 31), 0);
+ txlpf_rccal_lpc = MAX(MIN(txlpf_rccal_lpc, 31), 0);
+
+ write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+ ((rx_core ==
+ PHY_CORE_0) ? RADIO_2056_RX0 :
+ RADIO_2056_RX1)),
+ (rxlpf_rccal_hpc | 0x80));
+
+ write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
+ ((rx_core ==
+ PHY_CORE_0) ? RADIO_2056_TX0 :
+ RADIO_2056_TX1)),
+ (txlpf_rccal_lpc | 0x80));
+ }
+ }
+
+ write_phy_reg(pi, 0x01, orig_BBConfig);
+
+ wlc_phy_resetcca_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_rxgain,
+ 0, 0x3, 1);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+ }
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ gain_save);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+ pi->phyhang_avoid = phyhang_avoid_state;
+ }
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ return BCME_OK;
+}
+
+static int
+wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain,
+ bool debug)
+{
+ phy_iq_est_t est[PHY_CORE_MAX];
+ uint8 core_num, rx_core, tx_core;
+ uint16 lna_vals[] = { 0x3, 0x3, 0x1 };
+ uint16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
+ uint16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
+ int16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
+ int16 desired_log2_pwr, actual_log2_pwr, hpf_change;
+ uint16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
+ uint16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
+ uint16 num_samps;
+ uint32 i_pwr, q_pwr, tot_pwr[3];
+ uint8 gain_pass, use_hpf_num;
+ uint16 mask, val1, val2;
+ uint16 core_no;
+ uint16 gain_save[2];
+ uint16 cal_gain[2];
+ nphy_iqcal_params_t cal_params[2];
+ uint8 phy_bw;
+ int bcmerror = BCME_OK;
+ bool first_playtone = TRUE;
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+
+ wlc_phy_reapply_txcal_coeffs_nphy(pi);
+ }
+
+ wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+
+ for (core_no = 0; core_no <= 1; core_no++) {
+ wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+ &cal_params[core_no]);
+ cal_gain[core_no] = cal_params[core_no].cal_gain;
+ }
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+
+ num_samps = 1024;
+ desired_log2_pwr = 13;
+
+ for (core_num = 0; core_num < 2; core_num++) {
+
+ rx_core = core_num;
+ tx_core = 1 - core_num;
+
+ orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
+ orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+ 0xa6 : 0xa7);
+ orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
+ orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+ 0x91 : 0x92);
+ orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
+ 0x91 : 0x92);
+
+ mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+ mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+
+ or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+ ((0x1 << 1) | (0x1 << 2)));
+ or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
+
+ if (((pi->nphy_rxcalparams) & 0xff000000)) {
+
+ write_phy_reg(pi,
+ (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+ (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 :
+ 0x110));
+ } else {
+
+ write_phy_reg(pi,
+ (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+ (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 :
+ 0x120));
+ }
+
+ write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
+ (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
+ 0x114));
+
+ mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
+ if (rx_core == PHY_CORE_0) {
+ val1 = RADIO_2055_COUPLE_RX_MASK;
+ val2 = RADIO_2055_COUPLE_TX_MASK;
+ } else {
+ val1 = RADIO_2055_COUPLE_TX_MASK;
+ val2 = RADIO_2055_COUPLE_RX_MASK;
+ }
+
+ if ((pi->nphy_rxcalparams & 0x10000)) {
+ mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
+ val1);
+ mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
+ val2);
+ }
+
+ for (gain_pass = 0; gain_pass < 4; gain_pass++) {
+
+ if (debug)
+ OSL_DELAY(WAIT_FOR_SCOPE);
+
+ if (gain_pass < 3) {
+ curr_lna = lna_vals[gain_pass];
+ curr_hpf1 = hpf1_vals[gain_pass];
+ curr_hpf2 = hpf2_vals[gain_pass];
+ } else {
+
+ if (tot_pwr[1] > 10000) {
+ curr_lna = lna_vals[2];
+ curr_hpf1 = hpf1_vals[2];
+ curr_hpf2 = hpf2_vals[2];
+ use_hpf_num = 1;
+ curr_hpf = curr_hpf1;
+ actual_log2_pwr =
+ wlc_phy_nbits(tot_pwr[2]);
+ } else {
+ if (tot_pwr[0] > 10000) {
+ curr_lna = lna_vals[1];
+ curr_hpf1 = hpf1_vals[1];
+ curr_hpf2 = hpf2_vals[1];
+ use_hpf_num = 1;
+ curr_hpf = curr_hpf1;
+ actual_log2_pwr =
+ wlc_phy_nbits(tot_pwr[1]);
+ } else {
+ curr_lna = lna_vals[0];
+ curr_hpf1 = hpf1_vals[0];
+ curr_hpf2 = hpf2_vals[0];
+ use_hpf_num = 2;
+ curr_hpf = curr_hpf2;
+ actual_log2_pwr =
+ wlc_phy_nbits(tot_pwr[0]);
+ }
+ }
+
+ hpf_change = desired_log2_pwr - actual_log2_pwr;
+ curr_hpf += hpf_change;
+ curr_hpf = MAX(MIN(curr_hpf, 10), 0);
+ if (use_hpf_num == 1) {
+ curr_hpf1 = curr_hpf;
+ } else {
+ curr_hpf2 = curr_hpf;
+ }
+ }
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
+ ((curr_hpf2 << 8) |
+ (curr_hpf1 << 4) |
+ (curr_lna << 2)), 0x3, 0);
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+
+ wlc_phy_stopplayback_nphy(pi);
+
+ if (first_playtone) {
+ bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
+ (uint16) (pi->
+ nphy_rxcalparams
+ &
+ 0xffff),
+ 0, 0, TRUE);
+ first_playtone = FALSE;
+ } else {
+ phy_bw =
+ (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20;
+ wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
+ 0, 0, 0, TRUE);
+ }
+
+ if (bcmerror == BCME_OK) {
+ if (gain_pass < 3) {
+
+ wlc_phy_rx_iq_est_nphy(pi, est,
+ num_samps, 32,
+ 0);
+ i_pwr =
+ (est[rx_core].i_pwr +
+ num_samps / 2) / num_samps;
+ q_pwr =
+ (est[rx_core].q_pwr +
+ num_samps / 2) / num_samps;
+ tot_pwr[gain_pass] = i_pwr + q_pwr;
+ } else {
+
+ wlc_phy_calc_rx_iq_comp_nphy(pi,
+ (1 <<
+ rx_core));
+ }
+
+ wlc_phy_stopplayback_nphy(pi);
+ }
+
+ if (bcmerror != BCME_OK)
+ break;
+ }
+
+ and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
+ and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
+
+ write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
+ 0x92, orig_RfctrlIntcTx);
+ write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
+ 0x92, orig_RfctrlIntcRx);
+ write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
+ write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
+ 0xa7, orig_AfectrlCore);
+ write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
+
+ if (bcmerror != BCME_OK)
+ break;
+ }
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
+ wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+ gain_save);
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ return bcmerror;
+}
+
+int
+wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+ uint8 cal_type, bool debug)
+{
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ cal_type = 0;
+ }
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
+ debug);
+ } else {
+ return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
+ }
+}
+
+static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi)
+{
+ int j, type = 2;
+ uint16 addr_offset = 0x2c5;
+
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, addr_offset + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+ }
+}
+
+static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi)
+{
+ int j, type;
+ uint16 addr_offset[] = { 0x186, 0x195,
+ 0x2c5
+ };
+
+ for (type = 0; type < 3; type++) {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, addr_offset[type] + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+ }
+ }
+
+ if (IS40MHZ(pi)) {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, 0x186 + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+ }
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, 0x186 + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[5]
+ [j]);
+ }
+ }
+
+ if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, 0x2c5 + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[6]
+ [j]);
+ }
+ }
+ }
+}
+
+static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi)
+{
+ int j;
+
+ if (IS40MHZ(pi)) {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, 0x195 + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
+ }
+ } else {
+ for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+ write_phy_reg(pi, 0x186 + j,
+ NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+ }
+ }
+}
+
+static uint16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi)
+{
+ uint16 m0m1;
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+
+ return m0m1;
+}
+
+static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, uint8 m0, uint8 m1)
+{
+ uint16 m0m1 = (uint16) ((m0 << 8) | m1);
+
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
+ wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
+}
+
+static uint32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi)
+{
+ uint32 *tx_pwrctrl_tbl = NULL;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if ((pi->pubpi.radiorev == 4)
+ || (pi->pubpi.radiorev == 6)) {
+
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_ipa_2g_2057rev4n6;
+ } else if (pi->pubpi.radiorev == 3) {
+
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_ipa_2g_2057rev3;
+ } else if (pi->pubpi.radiorev == 5) {
+
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_ipa_2g_2057rev5;
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_ipa_2g_2057rev7;
+ } else {
+ ASSERT(0);
+ }
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
+ if (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID) {
+
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+ }
+
+ } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+ } else {
+
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
+ }
+
+ } else {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ tx_pwrctrl_tbl =
+ nphy_tpc_txgain_ipa_5g_2057rev7;
+ } else {
+ ASSERT(0);
+ }
+
+ } else {
+ tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
+ }
+ }
+
+ return tx_pwrctrl_tbl;
+}
+
+static void
+wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state,
+ uint8 core)
+{
+ int32 tone_freq;
+ uint8 off_core;
+ uint16 mixgain = 0;
+
+ off_core = core ^ 0x1;
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)
+ || NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+ wlc_phy_read_lpf_bw_ctl_nphy
+ (pi, 0), 0, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->pubpi.radiorev == 5) {
+ mixgain = (core == 0) ? 0x20 : 0x00;
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ mixgain = 0x00;
+
+ } else if ((pi->pubpi.radiorev <= 4)
+ || (pi->pubpi.radiorev == 6)) {
+
+ mixgain = 0x00;
+ } else {
+ ASSERT(0);
+ }
+
+ } else {
+ if ((pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+
+ mixgain = 0x50;
+ } else if ((pi->pubpi.radiorev == 3)
+ || (pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ mixgain = 0x0;
+ } else {
+ ASSERT(0);
+ }
+ }
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+ mixgain, (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+ 1, (1 << core), 0);
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+ 0, (1 << off_core), 0);
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+ 0, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+ 0, (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
+ (1 << core), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+
+ state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xa6 : 0xa7);
+ state->afeoverride[core] =
+ read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+ state->afectrl[off_core] =
+ read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
+ state->afeoverride[off_core] =
+ read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
+
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+ (0x1 << 2), 0);
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+ 0xa5), (0x1 << 2), (0x1 << 2));
+
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
+ (0x1 << 2), (0x1 << 2));
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
+ 0x8f), (0x1 << 2), (0x1 << 2));
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ state->pwrup[core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_PWRUP);
+ state->atten[core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_ATTEN);
+ state->pwrup[off_core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_2G_PWRUP);
+ state->atten[off_core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_2G_ATTEN);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_PWRUP, 0xc);
+
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_ATTEN, 0xf0);
+
+ } else if (pi->pubpi.radiorev == 5) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_ATTEN,
+ (core == 0) ? 0xf7 : 0xf2);
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_ATTEN, 0xf0);
+
+ } else {
+ ASSERT(0);
+ }
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_2G_PWRUP, 0x0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_2G_ATTEN, 0xff);
+
+ } else {
+ state->pwrup[core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_PWRUP);
+ state->atten[core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_ATTEN);
+ state->pwrup[off_core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_5G_PWRUP);
+ state->atten[off_core] =
+ READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_5G_ATTEN);
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_PWRUP, 0xc);
+
+ if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_ATTEN, 0xf4);
+
+ } else {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_ATTEN, 0xf0);
+ }
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_5G_PWRUP, 0x0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+ TXRXCOUPLE_5G_ATTEN, 0xff);
+ }
+
+ tone_freq = 4000;
+
+ wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, FALSE);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (1) << 13);
+
+ mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
+
+ mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (0) << 13);
+
+ } else {
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
+
+ state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xa6 : 0xa7);
+ state->afeoverride[core] =
+ read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+ (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+ 0xa5),
+ (0x1 << 0) |
+ (0x1 << 1) |
+ (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+
+ state->vga_master[core] =
+ READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ state->fbmix[core] =
+ READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+ TXFBMIX_G);
+ state->intpa_master[core] =
+ READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_MASTER);
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
+ 0x03);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_MASTER, 0x04);
+ } else {
+ state->fbmix[core] =
+ READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+ TXFBMIX_A);
+ state->intpa_master[core] =
+ READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_MASTER);
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
+ 0x03);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_MASTER, 0x04);
+
+ }
+
+ tone_freq = 4000;
+
+ wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, FALSE);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+ }
+}
+
+static void
+wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state)
+{
+ uint8 core;
+
+ wlc_phy_stopplayback_nphy(pi);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_PWRUP, 0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_2G_ATTEN,
+ state->atten[core]);
+ } else {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_PWRUP, 0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TXRXCOUPLE_5G_ATTEN,
+ state->atten[core]);
+ }
+ }
+
+ if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+ 1, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+ 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ }
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+ 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID2);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ write_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xa6 : 0xa7, state->afectrl[core]);
+ write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+ 0xa5, state->afeoverride[core]);
+ }
+
+ wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+ (state->mm & 0xff));
+
+ if (NREV_IS(pi->pubpi.phy_rev, 7)
+ || NREV_GE(pi->pubpi.phy_rev, 8)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+ 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID1);
+ }
+ } else {
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
+ state->vga_master[core]);
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+ TXFBMIX_G, state->fbmix[core]);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAG_MASTER,
+ state->intpa_master[core]);
+ } else {
+ WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+ TXFBMIX_A, state->fbmix[core]);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ INTPAA_MASTER,
+ state->intpa_master[core]);
+ }
+
+ write_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xa6 : 0xa7, state->afectrl[core]);
+ write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+ 0xa5, state->afeoverride[core]);
+ }
+
+ wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+ (state->mm & 0xff));
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
+ }
+}
+
+static void
+wlc_phy_a1_nphy(phy_info_t *pi, uint8 core, uint32 winsz, uint32 start,
+ uint32 end)
+{
+ uint32 *buf, *src, *dst, sz;
+
+ sz = end - start + 1;
+ ASSERT(end > start);
+ ASSERT(end < NPHY_PAPD_EPS_TBL_SIZE);
+
+ buf = MALLOC(pi->sh->osh, 2 * sizeof(uint32) * NPHY_PAPD_EPS_TBL_SIZE);
+ if (NULL == buf) {
+ return;
+ }
+
+ src = buf;
+ dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
+
+ wlc_phy_table_read_nphy(pi,
+ (core ==
+ PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
+ NPHY_TBL_ID_EPSILONTBL1),
+ NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
+
+ do {
+ uint32 phy_a1, phy_a2;
+ int32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
+
+ phy_a1 = end - MIN(end, (winsz >> 1));
+ phy_a2 = MIN(NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1));
+ phy_a3 = phy_a2 - phy_a1 + 1;
+ phy_a6 = 0;
+ phy_a7 = 0;
+
+ do {
+ wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
+ &phy_a5);
+ phy_a6 += phy_a4;
+ phy_a7 += phy_a5;
+ } while (phy_a2-- != phy_a1);
+
+ phy_a6 /= phy_a3;
+ phy_a7 /= phy_a3;
+ dst[end] = ((uint32) phy_a7 << 13) | ((uint32) phy_a6 & 0x1fff);
+ } while (end-- != start);
+
+ wlc_phy_table_write_nphy(pi,
+ (core ==
+ PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
+ NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
+
+ MFREE(pi->sh->osh, buf, 2 * sizeof(uint32) * NPHY_PAPD_EPS_TBL_SIZE);
+}
+
+static void
+wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains,
+ phy_cal_mode_t cal_mode, uint8 core)
+{
+ uint16 phy_a1, phy_a2, phy_a3;
+ uint16 phy_a4, phy_a5;
+ bool phy_a6;
+ uint8 phy_a7, m[2];
+ uint32 phy_a8 = 0;
+ nphy_txgains_t phy_a9;
+
+ if (NREV_LT(pi->pubpi.phy_rev, 3))
+ return;
+
+ phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
+
+ ASSERT((cal_mode == CAL_FULL) || (cal_mode == CAL_GCTRL)
+ || (cal_mode == CAL_SOFT));
+ phy_a6 = ((cal_mode == CAL_GCTRL)
+ || (cal_mode == CAL_SOFT)) ? TRUE : FALSE;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ phy_a5 = ((phy_a9.txlpf[core] << 15) |
+ (phy_a9.txgm[core] << 12) |
+ (phy_a9.pga[core] << 8) |
+ (txgains->gains.pad[core] << 3) |
+ (phy_a9.ipa[core]));
+ } else {
+ phy_a5 = ((phy_a9.txlpf[core] << 15) |
+ (phy_a9.txgm[core] << 12) |
+ (txgains->gains.pga[core] << 8) |
+ (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
+ }
+
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_txgain,
+ phy_a5, (1 << core), 0);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if ((pi->pubpi.radiorev <= 4)
+ || (pi->pubpi.radiorev == 6)) {
+
+ m[core] = IS40MHZ(pi) ? 60 : 79;
+ } else {
+
+ m[core] = IS40MHZ(pi) ? 45 : 64;
+ }
+
+ } else {
+ m[core] = IS40MHZ(pi) ? 75 : 107;
+ }
+
+ m[phy_a7] = 0;
+ wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+
+ phy_a2 = 63;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (CHIPID(pi->sh->chip) == BCM6362_CHIP_ID) {
+ phy_a1 = 35;
+ phy_a3 = 35;
+ } else if ((pi->pubpi.radiorev == 4)
+ || (pi->pubpi.radiorev == 6)) {
+ phy_a1 = 30;
+ phy_a3 = 30;
+ } else {
+ phy_a1 = 25;
+ phy_a3 = 25;
+ }
+ } else {
+ if ((pi->pubpi.radiorev == 5)
+ || (pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+ phy_a1 = 25;
+ phy_a3 = 25;
+ } else {
+ phy_a1 = 35;
+ phy_a3 = 35;
+ }
+ }
+
+ if (cal_mode == CAL_GCTRL) {
+ if ((pi->pubpi.radiorev == 5)
+ && (CHSPEC_IS2G(pi->radio_chanspec))) {
+ phy_a1 = 55;
+ } else if (((pi->pubpi.radiorev == 7) &&
+ (CHSPEC_IS2G(pi->radio_chanspec))) ||
+ ((pi->pubpi.radiorev == 8) &&
+ (CHSPEC_IS2G(pi->radio_chanspec)))) {
+ phy_a1 = 60;
+ } else {
+ phy_a1 = 63;
+ }
+
+ } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
+
+ phy_a1 = 35;
+ phy_a3 = 35;
+ }
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (1) << 13);
+
+ mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (0) << 13);
+
+ write_phy_reg(pi, 0x2a1, 0x80);
+ write_phy_reg(pi, 0x2a2, 0x100);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 4), (11) << 4);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 8), (11) << 8);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 0), (0x3) << 0);
+
+ write_phy_reg(pi, 0x2e5, 0x20);
+
+ mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+
+ mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+
+ mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+ 1, ((core == 0) ? 1 : 2), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+ 0, ((core == 0) ? 2 : 1), 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+
+ write_phy_reg(pi, 0x2be, 1);
+ SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+ 0, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+
+ wlc_phy_table_write_nphy(pi,
+ (core ==
+ PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+ : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+ 32, &phy_a8);
+
+ if (cal_mode != CAL_GCTRL) {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ wlc_phy_a1_nphy(pi, core, 5, 0, 35);
+ }
+ }
+
+ wlc_phy_rfctrl_override_1tomany_nphy(pi,
+ NPHY_REV7_RfctrlOverride_cmd_txgain,
+ phy_a5, (1 << core), 1);
+
+ } else {
+
+ if (txgains) {
+ if (txgains->useindex) {
+ phy_a4 = 15 - ((txgains->index) >> 3);
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ phy_a5 = 0x00f7 | (phy_a4 << 8);
+
+ if (CHIPID(pi->sh->chip) ==
+ BCM47162_CHIP_ID) {
+ phy_a5 =
+ 0x10f7 | (phy_a4 <<
+ 8);
+ }
+ } else
+ if (NREV_IS(pi->pubpi.phy_rev, 5))
+ phy_a5 = 0x10f7 | (phy_a4 << 8);
+ else
+ phy_a5 = 0x50f7 | (phy_a4 << 8);
+ } else {
+ phy_a5 = 0x70f7 | (phy_a4 << 8);
+ }
+ wlc_phy_rfctrl_override_nphy(pi,
+ (0x1 << 13),
+ phy_a5,
+ (1 << core), 0);
+ } else {
+ wlc_phy_rfctrl_override_nphy(pi,
+ (0x1 << 13),
+ 0x5bf7,
+ (1 << core), 0);
+ }
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ m[core] = IS40MHZ(pi) ? 45 : 64;
+ } else {
+ m[core] = IS40MHZ(pi) ? 75 : 107;
+ }
+
+ m[phy_a7] = 0;
+ wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+
+ phy_a2 = 63;
+
+ if (cal_mode == CAL_FULL) {
+ phy_a1 = 25;
+ phy_a3 = 25;
+ } else if (cal_mode == CAL_SOFT) {
+ phy_a1 = 25;
+ phy_a3 = 25;
+ } else if (cal_mode == CAL_GCTRL) {
+ phy_a1 = 63;
+ phy_a3 = 25;
+ } else {
+
+ phy_a1 = 25;
+ phy_a3 = 25;
+ }
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (1) << 0);
+
+ mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (0) << 0);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (1) << 13);
+
+ mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (0) << 13);
+
+ write_phy_reg(pi, 0x2a1, 0x20);
+ write_phy_reg(pi, 0x2a2, 0x60);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0xf << 4), (9) << 4);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0xf << 8), (9) << 8);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0xf << 0), (0x2) << 0);
+
+ write_phy_reg(pi, 0x2e5, 0x20);
+ } else {
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 11), (1) << 11);
+
+ mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 11), (0) << 11);
+
+ write_phy_reg(pi, 0x2a1, 0x80);
+ write_phy_reg(pi, 0x2a2, 0x600);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 4), (0) << 4);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 8), (0) << 8);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x7 << 0), (0x3) << 0);
+
+ mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
+
+ }
+
+ mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+
+ mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+
+ mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
+
+ write_phy_reg(pi, 0x2be, 1);
+ SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+
+ wlc_phy_table_write_nphy(pi,
+ (core ==
+ PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+ : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+ 32, &phy_a8);
+
+ if (cal_mode != CAL_GCTRL) {
+ wlc_phy_a1_nphy(pi, core, 5, 0, 40);
+ }
+ }
+}
+
+static uint8 wlc_phy_a3_nphy(phy_info_t *pi, uint8 start_gain, uint8 core)
+{
+ int phy_a1;
+ int phy_a2;
+ bool phy_a3;
+ nphy_ipa_txcalgains_t phy_a4;
+ bool phy_a5 = FALSE;
+ bool phy_a6 = TRUE;
+ int32 phy_a7, phy_a8;
+ uint32 phy_a9;
+ int phy_a10;
+ bool phy_a11 = FALSE;
+ int phy_a12;
+ uint8 phy_a13 = 0;
+ uint8 phy_a14;
+ uint8 *phy_a15 = NULL;
+
+ phy_a4.useindex = TRUE;
+ phy_a12 = start_gain;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+
+ phy_a2 = 20;
+ phy_a1 = 1;
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->pubpi.radiorev == 5) {
+
+ phy_a15 = pad_gain_codes_used_2057rev5;
+ phy_a13 = sizeof(pad_gain_codes_used_2057rev5) /
+ sizeof(pad_gain_codes_used_2057rev5[0]) - 1;
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ phy_a15 = pad_gain_codes_used_2057rev7;
+ phy_a13 = sizeof(pad_gain_codes_used_2057rev7) /
+ sizeof(pad_gain_codes_used_2057rev7[0]) - 1;
+
+ } else {
+
+ phy_a15 = pad_all_gain_codes_2057;
+ phy_a13 = sizeof(pad_all_gain_codes_2057) /
+ sizeof(pad_all_gain_codes_2057[0]) - 1;
+ }
+
+ } else {
+
+ phy_a15 = pga_all_gain_codes_2057;
+ phy_a13 = sizeof(pga_all_gain_codes_2057) /
+ sizeof(pga_all_gain_codes_2057[0]) - 1;
+ }
+
+ phy_a14 = 0;
+
+ for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ phy_a4.gains.pad[core] =
+ (uint16) phy_a15[phy_a12];
+ } else {
+ phy_a4.gains.pga[core] =
+ (uint16) phy_a15[phy_a12];
+ }
+
+ wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+
+ wlc_phy_table_read_nphy(pi,
+ (core ==
+ PHY_CORE_0 ?
+ NPHY_TBL_ID_EPSILONTBL0 :
+ NPHY_TBL_ID_EPSILONTBL1), 1,
+ 63, 32, &phy_a9);
+
+ wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+
+ phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+ (phy_a8 == 4095) || (phy_a8 == -4096));
+
+ if (!phy_a6 && (phy_a3 != phy_a5)) {
+ if (!phy_a3) {
+ phy_a12 -= (uint8) phy_a1;
+ }
+ phy_a11 = TRUE;
+ break;
+ }
+
+ if (phy_a3)
+ phy_a12 += (uint8) phy_a1;
+ else
+ phy_a12 -= (uint8) phy_a1;
+
+ if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
+ if (phy_a12 < phy_a14) {
+ phy_a12 = phy_a14;
+ } else {
+ phy_a12 = phy_a13;
+ }
+ phy_a11 = TRUE;
+ break;
+ }
+
+ phy_a6 = FALSE;
+ phy_a5 = phy_a3;
+ }
+
+ } else {
+ phy_a2 = 10;
+ phy_a1 = 8;
+ for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+ phy_a4.index = (uint8) phy_a12;
+ wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+
+ wlc_phy_table_read_nphy(pi,
+ (core ==
+ PHY_CORE_0 ?
+ NPHY_TBL_ID_EPSILONTBL0 :
+ NPHY_TBL_ID_EPSILONTBL1), 1,
+ 63, 32, &phy_a9);
+
+ wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+
+ phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+ (phy_a8 == 4095) || (phy_a8 == -4096));
+
+ if (!phy_a6 && (phy_a3 != phy_a5)) {
+ if (!phy_a3) {
+ phy_a12 -= (uint8) phy_a1;
+ }
+ phy_a11 = TRUE;
+ break;
+ }
+
+ if (phy_a3)
+ phy_a12 += (uint8) phy_a1;
+ else
+ phy_a12 -= (uint8) phy_a1;
+
+ if ((phy_a12 < 0) || (phy_a12 > 127)) {
+ if (phy_a12 < 0) {
+ phy_a12 = 0;
+ } else {
+ phy_a12 = 127;
+ }
+ phy_a11 = TRUE;
+ break;
+ }
+
+ phy_a6 = FALSE;
+ phy_a5 = phy_a3;
+ }
+
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ return (uint8) phy_a15[phy_a12];
+ } else {
+ return (uint8) phy_a12;
+ }
+
+}
+
+static void wlc_phy_a4(phy_info_t *pi, bool full_cal)
+{
+ nphy_ipa_txcalgains_t phy_b1[2];
+ nphy_papd_restore_state phy_b2;
+ bool phy_b3;
+ uint8 phy_b4;
+ uint8 phy_b5;
+ int16 phy_b6, phy_b7, phy_b8;
+ uint16 phy_b9;
+ int16 phy_b10, phy_b11, phy_b12;
+
+ phy_b11 = 0;
+ phy_b12 = 0;
+ phy_b7 = 0;
+ phy_b8 = 0;
+ phy_b6 = 0;
+
+ if (pi->nphy_papd_skip == 1)
+ return;
+
+ phy_b3 =
+ (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+ if (!phy_b3) {
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+ }
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ pi->nphy_force_papd_cal = FALSE;
+
+ for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
+ pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
+ wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
+
+ pi->nphy_papd_last_cal = pi->sh->now;
+ pi->nphy_papd_recal_counter++;
+
+ if (NORADIO_ENAB(pi->pubpi))
+ return;
+
+ phy_b4 = pi->nphy_txpwrctrl;
+ wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
+ nphy_papd_scaltbl);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
+ nphy_papd_scaltbl);
+
+ phy_b9 = read_phy_reg(pi, 0x01);
+ mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+
+ for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+ int32 i, val = 0;
+ for (i = 0; i < 64; i++) {
+ wlc_phy_table_write_nphy(pi,
+ ((phy_b5 ==
+ PHY_CORE_0) ?
+ NPHY_TBL_ID_EPSILONTBL0 :
+ NPHY_TBL_ID_EPSILONTBL1), 1,
+ i, 32, &val);
+ }
+ }
+
+ wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
+
+ phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
+ for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+ wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+
+ if ((pi->pubpi.radiorev == 3)
+ || (pi->pubpi.radiorev == 4)
+ || (pi->pubpi.radiorev == 6)) {
+
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ 23;
+
+ } else if (pi->pubpi.radiorev == 5) {
+
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ 0;
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ wlc_phy_a3_nphy(pi,
+ pi->
+ nphy_papd_cal_gain_index
+ [phy_b5], phy_b5);
+
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ 0;
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ wlc_phy_a3_nphy(pi,
+ pi->
+ nphy_papd_cal_gain_index
+ [phy_b5], phy_b5);
+
+ } else {
+ ASSERT(0);
+ }
+
+ phy_b1[phy_b5].gains.pad[phy_b5] =
+ pi->nphy_papd_cal_gain_index[phy_b5];
+
+ } else {
+ pi->nphy_papd_cal_gain_index[phy_b5] = 0;
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ wlc_phy_a3_nphy(pi,
+ pi->
+ nphy_papd_cal_gain_index
+ [phy_b5], phy_b5);
+ phy_b1[phy_b5].gains.pga[phy_b5] =
+ pi->nphy_papd_cal_gain_index[phy_b5];
+ }
+ } else {
+ phy_b1[phy_b5].useindex = TRUE;
+ phy_b1[phy_b5].index = 16;
+ phy_b1[phy_b5].index =
+ wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5);
+
+ pi->nphy_papd_cal_gain_index[phy_b5] =
+ 15 - ((phy_b1[phy_b5].index) >> 3);
+ }
+
+ switch (pi->nphy_papd_cal_type) {
+ case 0:
+ wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
+ break;
+ case 1:
+ wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
+ break;
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+ }
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+ }
+
+ for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+ int eps_offset = 0;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ if (pi->pubpi.radiorev == 3) {
+ eps_offset = -2;
+ } else if (pi->pubpi.radiorev == 5) {
+ eps_offset = 3;
+ } else {
+ eps_offset = -1;
+ }
+ } else {
+ eps_offset = 2;
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
+ phy_b10 = 0;
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+ phy_b12 =
+ -
+ (nphy_papd_padgain_dlt_2g_2057rev3n4
+ [phy_b8]
+ + 1) / 2;
+ phy_b10 = -1;
+ } else if (pi->pubpi.radiorev == 5) {
+ phy_b12 =
+ -(nphy_papd_padgain_dlt_2g_2057rev5
+ [phy_b8]
+ + 1) / 2;
+ } else if ((pi->pubpi.radiorev == 7) ||
+ (pi->pubpi.radiorev == 8)) {
+ phy_b12 =
+ -(nphy_papd_padgain_dlt_2g_2057rev7
+ [phy_b8]
+ + 1) / 2;
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
+ if ((pi->pubpi.radiorev == 3) ||
+ (pi->pubpi.radiorev == 4) ||
+ (pi->pubpi.radiorev == 6)) {
+ phy_b11 =
+ -(nphy_papd_pgagain_dlt_5g_2057
+ [phy_b7]
+ + 1) / 2;
+ } else if ((pi->pubpi.radiorev == 7)
+ || (pi->pubpi.radiorev == 8)) {
+ phy_b11 =
+ -(nphy_papd_pgagain_dlt_5g_2057rev7
+ [phy_b7]
+ + 1) / 2;
+ } else {
+ ASSERT(0);
+ }
+
+ phy_b10 = -9;
+ }
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ phy_b6 =
+ -60 + 27 + eps_offset + phy_b12 + phy_b10;
+ } else {
+ phy_b6 =
+ -60 + 27 + eps_offset + phy_b11 + phy_b10;
+ }
+
+ mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+ 0x29c, (0x1ff << 7), (phy_b6) << 7);
+
+ pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+ } else {
+ if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+ eps_offset = 4;
+ } else {
+ eps_offset = 2;
+ }
+
+ phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ phy_b11 =
+ -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] +
+ 1) / 2;
+ phy_b10 = 0;
+ } else {
+ phy_b11 =
+ -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] +
+ 1) / 2;
+ phy_b10 = -9;
+ }
+
+ phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
+
+ mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+ 0x29c, (0x1ff << 7), (phy_b6) << 7);
+
+ pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+ }
+ }
+
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (0) << 13);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 13), (0) << 13);
+
+ } else {
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 11), (0) << 11);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+ 0x2a4, (0x1 << 11), (0) << 11);
+
+ }
+ pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
+
+ write_phy_reg(pi, 0x01, phy_b9);
+
+ wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
+ if (phy_b4 == PHY_TPC_HW_OFF) {
+ wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+ (int8) (pi->nphy_txpwrindex[0].
+ index_internal), FALSE);
+ wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+ (int8) (pi->nphy_txpwrindex[1].
+ index_internal), FALSE);
+ }
+
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+
+ if (!phy_b3) {
+ wlapi_enable_mac(pi->sh->physhim);
+ }
+}
+
+void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi)
+{
+ uint core;
+ uint32 txgain;
+ uint16 rad_gain, dac_gain, bbmult, m1m2;
+ uint8 txpi[2], chan_freq_range;
+ int32 rfpwr_offset;
+
+ ASSERT(pi->nphy_txpwrctrl == PHY_TPC_HW_OFF);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ if (pi->sh->sromrev < 4) {
+ txpi[0] = txpi[1] = 72;
+ } else {
+
+ chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ switch (chan_freq_range) {
+ case WL_CHAN_FREQ_RANGE_2G:
+ txpi[0] = pi->nphy_txpid2g[0];
+ txpi[1] = pi->nphy_txpid2g[1];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GL:
+ txpi[0] = pi->nphy_txpid5gl[0];
+ txpi[1] = pi->nphy_txpid5gl[1];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GM:
+ txpi[0] = pi->nphy_txpid5g[0];
+ txpi[1] = pi->nphy_txpid5g[1];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GH:
+ txpi[0] = pi->nphy_txpid5gh[0];
+ txpi[1] = pi->nphy_txpid5gh[1];
+ break;
+ default:
+ txpi[0] = txpi[1] = 91;
+ break;
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ txpi[0] = txpi[1] = 30;
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ txpi[0] = txpi[1] = 40;
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+
+ if ((txpi[0] < 40) || (txpi[0] > 100) ||
+ (txpi[1] < 40) || (txpi[1] > 100))
+ txpi[0] = txpi[1] = 91;
+ }
+
+ pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
+ pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
+ pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
+ pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (PHY_IPA(pi)) {
+ uint32 *tx_gaintbl =
+ wlc_phy_get_ipa_gaintbl_nphy(pi);
+ txgain = tx_gaintbl[txpi[core]];
+ } else {
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if NREV_IS
+ (pi->pubpi.phy_rev, 3) {
+ txgain =
+ nphy_tpc_5GHz_txgain_rev3
+ [txpi[core]];
+ } else if NREV_IS
+ (pi->pubpi.phy_rev, 4) {
+ txgain =
+ (pi->srom_fem5g.extpagain ==
+ 3) ?
+ nphy_tpc_5GHz_txgain_HiPwrEPA
+ [txpi[core]] :
+ nphy_tpc_5GHz_txgain_rev4
+ [txpi[core]];
+ } else {
+ txgain =
+ nphy_tpc_5GHz_txgain_rev5
+ [txpi[core]];
+ }
+ } else {
+ if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+ (pi->srom_fem2g.extpagain == 3)) {
+ txgain =
+ nphy_tpc_txgain_HiPwrEPA
+ [txpi[core]];
+ } else {
+ txgain =
+ nphy_tpc_txgain_rev3[txpi
+ [core]];
+ }
+ }
+ }
+ } else {
+ txgain = nphy_tpc_txgain[txpi[core]];
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+ } else {
+ rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
+ } else {
+ dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+ }
+ bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+ 0xa5), (0x1 << 8), (0x1 << 8));
+ } else {
+ mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+ }
+ write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
+
+ wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+ &rad_gain);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+ m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+ m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_table_read_nphy(pi,
+ (core ==
+ PHY_CORE_0 ?
+ NPHY_TBL_ID_CORE1TXPWRCTL :
+ NPHY_TBL_ID_CORE2TXPWRCTL), 1,
+ 576 + txpi[core], 32,
+ &rfpwr_offset);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1ff << 4),
+ ((int16) rfpwr_offset) << 4);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 2), (1) << 2);
+
+ }
+ }
+
+ and_phy_reg(pi, 0xbf, (uint16) (~(0x1f << 0)));
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void
+wlc_phy_txpwr_nphy_srom_convert(uint8 *srom_max, uint16 *pwr_offset,
+ uint8 tmp_max_pwr, uint8 rate_start,
+ uint8 rate_end)
+{
+ uint8 rate;
+ uint8 word_num, nibble_num;
+ uint8 tmp_nibble;
+
+ for (rate = rate_start; rate <= rate_end; rate++) {
+ word_num = (rate - rate_start) >> 2;
+ nibble_num = (rate - rate_start) & 0x3;
+ tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
+
+ srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
+ }
+}
+
+static void
+wlc_phy_txpwr_nphy_po_apply(uint8 *srom_max, uint8 pwr_offset,
+ uint8 rate_start, uint8 rate_end)
+{
+ uint8 rate;
+
+ for (rate = rate_start; rate <= rate_end; rate++) {
+ srom_max[rate] -= 2 * pwr_offset;
+ }
+}
+
+void
+wlc_phy_ofdm_to_mcs_powers_nphy(uint8 *power, uint8 rate_mcs_start,
+ uint8 rate_mcs_end, uint8 rate_ofdm_start)
+{
+ uint8 rate1, rate2;
+
+ rate2 = rate_ofdm_start;
+ for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
+ power[rate1] = power[rate2];
+ rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
+ }
+ power[rate_mcs_end] = power[rate_mcs_end - 1];
+}
+
+void
+wlc_phy_mcs_to_ofdm_powers_nphy(uint8 *power, uint8 rate_ofdm_start,
+ uint8 rate_ofdm_end, uint8 rate_mcs_start)
+{
+ uint8 rate1, rate2;
+
+ for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
+ rate1 <= rate_ofdm_end; rate1++, rate2++) {
+ power[rate1] = power[rate2];
+ if (rate1 == rate_ofdm_start)
+ power[++rate1] = power[rate2];
+ }
+}
+
+void BCMNMIATTACHFN(wlc_phy_txpwr_apply_nphy) (phy_info_t *pi)
+{
+ uint rate1, rate2, band_num;
+ uint8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
+ uint8 tmp_max_pwr = 0;
+ uint16 pwr_offsets1[2], *pwr_offsets2 = NULL;
+ uint8 *tx_srom_max_rate = NULL;
+
+ for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+ switch (band_num) {
+ case 0:
+
+ tmp_max_pwr = MIN(pi->nphy_pwrctrl_info[0].max_pwr_2g,
+ pi->nphy_pwrctrl_info[1].max_pwr_2g);
+
+ pwr_offsets1[0] = pi->cck2gpo;
+ wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
+ pwr_offsets1,
+ tmp_max_pwr,
+ TXP_FIRST_CCK,
+ TXP_LAST_CCK);
+
+ pwr_offsets1[0] = (uint16) (pi->ofdm2gpo & 0xffff);
+ pwr_offsets1[1] =
+ (uint16) (pi->ofdm2gpo >> 16) & 0xffff;
+
+ pwr_offsets2 = pi->mcs2gpo;
+
+ tmp_cddpo = pi->cdd2gpo;
+ tmp_stbcpo = pi->stbc2gpo;
+ tmp_bw40po = pi->bw402gpo;
+
+ tx_srom_max_rate = pi->tx_srom_max_rate_2g;
+ break;
+ case 1:
+
+ tmp_max_pwr = MIN(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
+ pi->nphy_pwrctrl_info[1].max_pwr_5gm);
+
+ pwr_offsets1[0] = (uint16) (pi->ofdm5gpo & 0xffff);
+ pwr_offsets1[1] =
+ (uint16) (pi->ofdm5gpo >> 16) & 0xffff;
+
+ pwr_offsets2 = pi->mcs5gpo;
+
+ tmp_cddpo = pi->cdd5gpo;
+ tmp_stbcpo = pi->stbc5gpo;
+ tmp_bw40po = pi->bw405gpo;
+
+ tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
+ break;
+ case 2:
+
+ tmp_max_pwr = MIN(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
+ pi->nphy_pwrctrl_info[1].max_pwr_5gl);
+
+ pwr_offsets1[0] = (uint16) (pi->ofdm5glpo & 0xffff);
+ pwr_offsets1[1] =
+ (uint16) (pi->ofdm5glpo >> 16) & 0xffff;
+
+ pwr_offsets2 = pi->mcs5glpo;
+
+ tmp_cddpo = pi->cdd5glpo;
+ tmp_stbcpo = pi->stbc5glpo;
+ tmp_bw40po = pi->bw405glpo;
+
+ tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
+ break;
+ case 3:
+
+ tmp_max_pwr = MIN(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
+ pi->nphy_pwrctrl_info[1].max_pwr_5gh);
+
+ pwr_offsets1[0] = (uint16) (pi->ofdm5ghpo & 0xffff);
+ pwr_offsets1[1] =
+ (uint16) (pi->ofdm5ghpo >> 16) & 0xffff;
+
+ pwr_offsets2 = pi->mcs5ghpo;
+
+ tmp_cddpo = pi->cdd5ghpo;
+ tmp_stbcpo = pi->stbc5ghpo;
+ tmp_bw40po = pi->bw405ghpo;
+
+ tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
+ break;
+ }
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
+ tmp_max_pwr, TXP_FIRST_OFDM,
+ TXP_LAST_OFDM);
+
+ wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
+ TXP_FIRST_MCS_20_SISO,
+ TXP_LAST_MCS_20_SISO,
+ TXP_FIRST_OFDM);
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+ tmp_max_pwr,
+ TXP_FIRST_MCS_20_CDD,
+ TXP_LAST_MCS_20_CDD);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+ TXP_FIRST_MCS_20_CDD,
+ TXP_LAST_MCS_20_CDD);
+ }
+
+ wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+ TXP_FIRST_OFDM_20_CDD,
+ TXP_LAST_OFDM_20_CDD,
+ TXP_FIRST_MCS_20_CDD);
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+ tmp_max_pwr,
+ TXP_FIRST_MCS_20_STBC,
+ TXP_LAST_MCS_20_STBC);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+ tmp_stbcpo,
+ TXP_FIRST_MCS_20_STBC,
+ TXP_LAST_MCS_20_STBC);
+ }
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+ &pwr_offsets2[2], tmp_max_pwr,
+ TXP_FIRST_MCS_20_SDM,
+ TXP_LAST_MCS_20_SDM);
+
+ if (NPHY_IS_SROM_REINTERPRET) {
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+ &pwr_offsets2[4],
+ tmp_max_pwr,
+ TXP_FIRST_MCS_40_SISO,
+ TXP_LAST_MCS_40_SISO);
+
+ wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+ TXP_FIRST_OFDM_40_SISO,
+ TXP_LAST_OFDM_40_SISO,
+ TXP_FIRST_MCS_40_SISO);
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+ &pwr_offsets2[4],
+ tmp_max_pwr,
+ TXP_FIRST_MCS_40_CDD,
+ TXP_LAST_MCS_40_CDD);
+
+ wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+ TXP_FIRST_MCS_40_CDD,
+ TXP_LAST_MCS_40_CDD);
+
+ wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+ TXP_FIRST_OFDM_40_CDD,
+ TXP_LAST_OFDM_40_CDD,
+ TXP_FIRST_MCS_40_CDD);
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+ &pwr_offsets2[4],
+ tmp_max_pwr,
+ TXP_FIRST_MCS_40_STBC,
+ TXP_LAST_MCS_40_STBC);
+
+ wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+ tmp_stbcpo,
+ TXP_FIRST_MCS_40_STBC,
+ TXP_LAST_MCS_40_STBC);
+
+ wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+ &pwr_offsets2[6],
+ tmp_max_pwr,
+ TXP_FIRST_MCS_40_SDM,
+ TXP_LAST_MCS_40_SDM);
+ } else {
+
+ for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
+ TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM;
+ rate1++, rate2++)
+ tx_srom_max_rate[rate1] =
+ tx_srom_max_rate[rate2];
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+ tmp_bw40po,
+ TXP_FIRST_OFDM_40_SISO,
+ TXP_LAST_MCS_40_SDM);
+ }
+
+ tx_srom_max_rate[TXP_MCS_32] =
+ tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
+ }
+
+ return;
+}
+
+static void BCMATTACHFN(wlc_phy_txpwr_srom_read_ppr_nphy) (phy_info_t *pi)
+{
+ uint16 bw40po, cddpo, stbcpo, bwduppo;
+ uint band_num;
+
+ if (pi->sh->sromrev >= 9) {
+
+ return;
+ }
+
+ bw40po = (uint16) PHY_GETINTVAR(pi, "bw40po");
+ pi->bw402gpo = bw40po & 0xf;
+ pi->bw405gpo = (bw40po & 0xf0) >> 4;
+ pi->bw405glpo = (bw40po & 0xf00) >> 8;
+ pi->bw405ghpo = (bw40po & 0xf000) >> 12;
+
+ cddpo = (uint16) PHY_GETINTVAR(pi, "cddpo");
+ pi->cdd2gpo = cddpo & 0xf;
+ pi->cdd5gpo = (cddpo & 0xf0) >> 4;
+ pi->cdd5glpo = (cddpo & 0xf00) >> 8;
+ pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
+
+ stbcpo = (uint16) PHY_GETINTVAR(pi, "stbcpo");
+ pi->stbc2gpo = stbcpo & 0xf;
+ pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
+ pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
+ pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
+
+ bwduppo = (uint16) PHY_GETINTVAR(pi, "bwduppo");
+ pi->bwdup2gpo = bwduppo & 0xf;
+ pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
+ pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
+ pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
+
+ for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+ switch (band_num) {
+ case 0:
+
+ pi->nphy_txpid2g[PHY_CORE_0] =
+ (uint8) PHY_GETINTVAR(pi, "txpid2ga0");
+ pi->nphy_txpid2g[PHY_CORE_1] =
+ (uint8) PHY_GETINTVAR(pi, "txpid2ga1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
+ (int8) PHY_GETINTVAR(pi, "maxp2ga0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
+ (int8) PHY_GETINTVAR(pi, "maxp2ga1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw0a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw0a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw1a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw1a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw2a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa2gw2a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
+ (int8) PHY_GETINTVAR(pi, "itt2ga0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
+ (int8) PHY_GETINTVAR(pi, "itt2ga1");
+
+ pi->cck2gpo = (uint16) PHY_GETINTVAR(pi, "cck2gpo");
+
+ pi->ofdm2gpo = (uint32) PHY_GETINTVAR(pi, "ofdm2gpo");
+
+ pi->mcs2gpo[0] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo0");
+ pi->mcs2gpo[1] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo1");
+ pi->mcs2gpo[2] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo2");
+ pi->mcs2gpo[3] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo3");
+ pi->mcs2gpo[4] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo4");
+ pi->mcs2gpo[5] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo5");
+ pi->mcs2gpo[6] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo6");
+ pi->mcs2gpo[7] = (uint16) PHY_GETINTVAR(pi, "mcs2gpo7");
+ break;
+ case 1:
+
+ pi->nphy_txpid5g[PHY_CORE_0] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5ga0");
+ pi->nphy_txpid5g[PHY_CORE_1] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5ga1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
+ (int8) PHY_GETINTVAR(pi, "maxp5ga0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
+ (int8) PHY_GETINTVAR(pi, "maxp5ga1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw0a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw0a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw1a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw1a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw2a0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5gw2a1");
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
+ (int8) PHY_GETINTVAR(pi, "itt5ga0");
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
+ (int8) PHY_GETINTVAR(pi, "itt5ga1");
+
+ pi->ofdm5gpo = (uint32) PHY_GETINTVAR(pi, "ofdm5gpo");
+
+ pi->mcs5gpo[0] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo0");
+ pi->mcs5gpo[1] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo1");
+ pi->mcs5gpo[2] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo2");
+ pi->mcs5gpo[3] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo3");
+ pi->mcs5gpo[4] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo4");
+ pi->mcs5gpo[5] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo5");
+ pi->mcs5gpo[6] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo6");
+ pi->mcs5gpo[7] = (uint16) PHY_GETINTVAR(pi, "mcs5gpo7");
+ break;
+ case 2:
+
+ pi->nphy_txpid5gl[0] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5gla0");
+ pi->nphy_txpid5gl[1] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5gla1");
+ pi->nphy_pwrctrl_info[0].max_pwr_5gl =
+ (int8) PHY_GETINTVAR(pi, "maxp5gla0");
+ pi->nphy_pwrctrl_info[1].max_pwr_5gl =
+ (int8) PHY_GETINTVAR(pi, "maxp5gla1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw0a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw0a1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw1a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw1a1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw2a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5glw2a1");
+ pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
+ pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
+
+ pi->ofdm5glpo = (uint32) PHY_GETINTVAR(pi, "ofdm5glpo");
+
+ pi->mcs5glpo[0] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo0");
+ pi->mcs5glpo[1] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo1");
+ pi->mcs5glpo[2] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo2");
+ pi->mcs5glpo[3] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo3");
+ pi->mcs5glpo[4] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo4");
+ pi->mcs5glpo[5] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo5");
+ pi->mcs5glpo[6] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo6");
+ pi->mcs5glpo[7] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5glpo7");
+ break;
+ case 3:
+
+ pi->nphy_txpid5gh[0] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5gha0");
+ pi->nphy_txpid5gh[1] =
+ (uint8) PHY_GETINTVAR(pi, "txpid5gha1");
+ pi->nphy_pwrctrl_info[0].max_pwr_5gh =
+ (int8) PHY_GETINTVAR(pi, "maxp5gha0");
+ pi->nphy_pwrctrl_info[1].max_pwr_5gh =
+ (int8) PHY_GETINTVAR(pi, "maxp5gha1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw0a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw0a1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw1a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw1a1");
+ pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw2a0");
+ pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
+ (int16) PHY_GETINTVAR(pi, "pa5ghw2a1");
+ pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
+ pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
+
+ pi->ofdm5ghpo = (uint32) PHY_GETINTVAR(pi, "ofdm5ghpo");
+
+ pi->mcs5ghpo[0] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo0");
+ pi->mcs5ghpo[1] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo1");
+ pi->mcs5ghpo[2] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo2");
+ pi->mcs5ghpo[3] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo3");
+ pi->mcs5ghpo[4] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo4");
+ pi->mcs5ghpo[5] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo5");
+ pi->mcs5ghpo[6] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo6");
+ pi->mcs5ghpo[7] =
+ (uint16) PHY_GETINTVAR(pi, "mcs5ghpo7");
+ break;
+ }
+ }
+
+ wlc_phy_txpwr_apply_nphy(pi);
+}
+
+static bool BCMATTACHFN(wlc_phy_txpwr_srom_read_nphy) (phy_info_t *pi)
+{
+
+ pi->antswitch = (uint8) PHY_GETINTVAR(pi, "antswitch");
+ pi->aa2g = (uint8) PHY_GETINTVAR(pi, "aa2g");
+ pi->aa5g = (uint8) PHY_GETINTVAR(pi, "aa5g");
+
+ pi->srom_fem2g.tssipos = (uint8) PHY_GETINTVAR(pi, "tssipos2g");
+ pi->srom_fem2g.extpagain = (uint8) PHY_GETINTVAR(pi, "extpagain2g");
+ pi->srom_fem2g.pdetrange = (uint8) PHY_GETINTVAR(pi, "pdetrange2g");
+ pi->srom_fem2g.triso = (uint8) PHY_GETINTVAR(pi, "triso2g");
+ pi->srom_fem2g.antswctrllut = (uint8) PHY_GETINTVAR(pi, "antswctl2g");
+
+ pi->srom_fem5g.tssipos = (uint8) PHY_GETINTVAR(pi, "tssipos5g");
+ pi->srom_fem5g.extpagain = (uint8) PHY_GETINTVAR(pi, "extpagain5g");
+ pi->srom_fem5g.pdetrange = (uint8) PHY_GETINTVAR(pi, "pdetrange5g");
+ pi->srom_fem5g.triso = (uint8) PHY_GETINTVAR(pi, "triso5g");
+ if (PHY_GETVAR(pi, "antswctl5g")) {
+
+ pi->srom_fem5g.antswctrllut =
+ (uint8) PHY_GETINTVAR(pi, "antswctl5g");
+ } else {
+
+ pi->srom_fem5g.antswctrllut =
+ (uint8) PHY_GETINTVAR(pi, "antswctl2g");
+ }
+
+ wlc_phy_txpower_ipa_upd(pi);
+
+ pi->phy_txcore_disable_temp = (int16) PHY_GETINTVAR(pi, "tempthresh");
+ if (pi->phy_txcore_disable_temp == 0) {
+ pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+ }
+
+ pi->phy_tempsense_offset = (int8) PHY_GETINTVAR(pi, "tempoffset");
+ if (pi->phy_tempsense_offset != 0) {
+ if (pi->phy_tempsense_offset >
+ (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) {
+ pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
+ } else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
+ NPHY_SROM_MINTEMPOFFSET)) {
+ pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
+ } else {
+ pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
+ }
+ }
+
+ pi->phy_txcore_enable_temp =
+ pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
+
+ pi->phycal_tempdelta = (uint8) PHY_GETINTVAR(pi, "phycal_tempdelta");
+ if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) {
+ pi->phycal_tempdelta = 0;
+ }
+
+ wlc_phy_txpwr_srom_read_ppr_nphy(pi);
+
+ return TRUE;
+}
+
+void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi)
+{
+ uint8 tx_pwr_ctrl_state;
+ wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+ wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+
+ tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+ (void)R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ OSL_DELAY(1);
+ }
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+}
+
+static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi)
+{
+ uint32 idx;
+ uint16 iqloCalbuf[7];
+ uint32 iqcomp, locomp, curr_locomp;
+ int8 locomp_i, locomp_q;
+ int8 curr_locomp_i, curr_locomp_q;
+ uint32 tbl_id, tbl_len, tbl_offset;
+ uint32 regval[128];
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
+
+ tbl_len = 128;
+ tbl_offset = 320;
+ for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+ tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+ iqcomp =
+ (tbl_id ==
+ 26) ? (((uint32) (iqloCalbuf[0] & 0x3ff)) << 10) |
+ (iqloCalbuf[1] & 0x3ff)
+ : (((uint32) (iqloCalbuf[2] & 0x3ff)) << 10) |
+ (iqloCalbuf[3] & 0x3ff);
+
+ for (idx = 0; idx < tbl_len; idx++) {
+ regval[idx] = iqcomp;
+ }
+ wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+ regval);
+ }
+
+ tbl_offset = 448;
+ for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+ tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+
+ locomp =
+ (uint32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
+ locomp_i = (int8) ((locomp >> 8) & 0xff);
+ locomp_q = (int8) ((locomp) & 0xff);
+ for (idx = 0; idx < tbl_len; idx++) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ curr_locomp_i = locomp_i;
+ curr_locomp_q = locomp_q;
+ } else {
+ curr_locomp_i = (int8) ((locomp_i *
+ nphy_tpc_loscale[idx] +
+ 128) >> 8);
+ curr_locomp_q =
+ (int8) ((locomp_q * nphy_tpc_loscale[idx] +
+ 128) >> 8);
+ }
+ curr_locomp = (uint32) ((curr_locomp_i & 0xff) << 8);
+ curr_locomp |= (uint32) (curr_locomp_q & 0xff);
+ regval[idx] = curr_locomp;
+ }
+ wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+ regval);
+ }
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
+ wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi)
+{
+ uint8 core;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER, 0x5);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MUX, 0xe);
+
+ if (pi->pubpi.radiorev != 5)
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TSSIA, 0);
+
+ if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TSSIG, 0x1);
+ } else {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+ core, TSSIG, 0x31);
+ }
+ } else {
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MASTER, 0x9);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TX_SSI_MUX, 0xc);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+ TSSIG, 0);
+
+ if (pi->pubpi.radiorev != 5) {
+ if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIA, 0x1);
+ } else {
+
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TSSIA, 0x31);
+ }
+ }
+ }
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+ 0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+ 0);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+ 0x3);
+ WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+ 0x0);
+ }
+ } else {
+ WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
+ (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
+ 0x80);
+ WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
+ WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
+ 0x0);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
+ 0x0);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
+ 0x3);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
+ 0x0);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
+ 0x8);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
+ 0x0);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
+ 0x0);
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TX_SSI_MASTER, 0x5);
+
+ if (pi->pubpi.radiorev != 5)
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+ core, TSSIA, 0x0);
+ if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+ core, TSSIG, 0x31);
+ } else {
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+ core, TSSIG, 0x11);
+ }
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TX_SSI_MUX, 0xe);
+ } else {
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TX_SSI_MASTER, 0x9);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TSSIA, 0x31);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TSSIG, 0x0);
+ WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+ TX_SSI_MUX, 0xc);
+ }
+ }
+ }
+}
+
+static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi)
+{
+ int32 rssi_buf[4];
+ int32 int_val;
+
+ if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
+
+ return;
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_ipa_internal_tssi_setup_nphy(pi);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+ 0, 0x3, 0,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
+ }
+
+ wlc_phy_stopplayback_nphy(pi);
+
+ wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, FALSE);
+
+ OSL_DELAY(20);
+ int_val =
+ wlc_phy_poll_rssi_nphy(pi, (uint8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
+ 1);
+ wlc_phy_stopplayback_nphy(pi);
+ wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+ 0, 0x3, 1,
+ NPHY_REV7_RFCTRLOVERRIDE_ID0);
+ } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+ (uint8) ((int_val >> 24) & 0xff);
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+ (uint8) ((int_val >> 24) & 0xff);
+
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+ (uint8) ((int_val >> 8) & 0xff);
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+ (uint8) ((int_val >> 8) & 0xff);
+ } else {
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+ (uint8) ((int_val >> 24) & 0xff);
+
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+ (uint8) ((int_val >> 8) & 0xff);
+
+ pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+ (uint8) ((int_val >> 16) & 0xff);
+ pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+ (uint8) ((int_val) & 0xff);
+ }
+
+}
+
+static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi)
+{
+ uint32 idx;
+ int16 a1[2], b0[2], b1[2];
+ int8 target_pwr_qtrdbm[2];
+ int32 num, den, pwr_est;
+ uint8 chan_freq_range;
+ uint8 idle_tssi[2];
+ uint32 tbl_id, tbl_len, tbl_offset;
+ uint32 regval[64];
+ uint8 core;
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+ (void)R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ OSL_DELAY(1);
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ or_phy_reg(pi, 0x122, (0x1 << 0));
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ and_phy_reg(pi, 0x1e7, (uint16) (~(0x1 << 15)));
+ } else {
+
+ or_phy_reg(pi, 0x1e7, (0x1 << 15));
+ }
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+
+ if (pi->sh->sromrev < 4) {
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+ target_pwr_qtrdbm[0] = 13 * 4;
+ target_pwr_qtrdbm[1] = 13 * 4;
+ a1[0] = -424;
+ a1[1] = -424;
+ b0[0] = 5612;
+ b0[1] = 5612;
+ b1[1] = -1393;
+ b1[0] = -1393;
+ } else {
+
+ chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+ switch (chan_freq_range) {
+ case WL_CHAN_FREQ_RANGE_2G:
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+ target_pwr_qtrdbm[0] =
+ pi->nphy_pwrctrl_info[0].max_pwr_2g;
+ target_pwr_qtrdbm[1] =
+ pi->nphy_pwrctrl_info[1].max_pwr_2g;
+ a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
+ a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
+ b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
+ b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
+ b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
+ b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
+ break;
+ case WL_CHAN_FREQ_RANGE_5GL:
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+ target_pwr_qtrdbm[0] =
+ pi->nphy_pwrctrl_info[0].max_pwr_5gl;
+ target_pwr_qtrdbm[1] =
+ pi->nphy_pwrctrl_info[1].max_pwr_5gl;
+ a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
+ a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
+ b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
+ b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
+ b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
+ b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
+ break;
+ case WL_CHAN_FREQ_RANGE_5GM:
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+ target_pwr_qtrdbm[0] =
+ pi->nphy_pwrctrl_info[0].max_pwr_5gm;
+ target_pwr_qtrdbm[1] =
+ pi->nphy_pwrctrl_info[1].max_pwr_5gm;
+ a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
+ a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
+ b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
+ b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
+ b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
+ b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
+ break;
+ case WL_CHAN_FREQ_RANGE_5GH:
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+ target_pwr_qtrdbm[0] =
+ pi->nphy_pwrctrl_info[0].max_pwr_5gh;
+ target_pwr_qtrdbm[1] =
+ pi->nphy_pwrctrl_info[1].max_pwr_5gh;
+ a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
+ a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
+ b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
+ b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
+ b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
+ b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
+ break;
+ default:
+ idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+ idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+ target_pwr_qtrdbm[0] = 13 * 4;
+ target_pwr_qtrdbm[1] = 13 * 4;
+ a1[0] = -424;
+ a1[1] = -424;
+ b0[0] = 5612;
+ b0[1] = 5612;
+ b1[1] = -1393;
+ b1[0] = -1393;
+ break;
+ }
+ }
+
+ target_pwr_qtrdbm[0] = (int8) pi->tx_power_max;
+ target_pwr_qtrdbm[1] = (int8) pi->tx_power_max;
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if (pi->srom_fem2g.tssipos) {
+ or_phy_reg(pi, 0x1e9, (0x1 << 14));
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ for (core = 0; core <= 1; core++) {
+ if (PHY_IPA(pi)) {
+
+ if (CHSPEC_IS2G(pi->radio_chanspec)) {
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TX_SSI_MUX,
+ 0xe);
+ } else {
+ WRITE_RADIO_REG3(pi, RADIO_2057,
+ TX, core,
+ TX_SSI_MUX,
+ 0xc);
+ }
+ } else {
+ }
+ }
+ } else {
+ if (PHY_IPA(pi)) {
+
+ write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+ RADIO_2056_TX0,
+ (CHSPEC_IS5G
+ (pi->
+ radio_chanspec)) ? 0xc : 0xe);
+ write_radio_reg(pi,
+ RADIO_2056_TX_TX_SSI_MUX |
+ RADIO_2056_TX1,
+ (CHSPEC_IS5G
+ (pi->
+ radio_chanspec)) ? 0xc : 0xe);
+ } else {
+
+ write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+ RADIO_2056_TX0, 0x11);
+ write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+ RADIO_2056_TX1, 0x11);
+ }
+ }
+ }
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+ (void)R_REG(pi->sh->osh, &pi->regs->maccontrol);
+ OSL_DELAY(1);
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+ (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+ } else {
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+ (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_phy_reg(pi, 0x222, (0xff << 0),
+ (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+ } else if (NREV_GT(pi->pubpi.phy_rev, 1)) {
+ mod_phy_reg(pi, 0x222, (0xff << 0),
+ (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+ }
+
+ if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+ wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+
+ write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
+
+ write_phy_reg(pi, 0x1e9,
+ (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
+
+ write_phy_reg(pi, 0x1ea,
+ (target_pwr_qtrdbm[0] << 0) |
+ (target_pwr_qtrdbm[1] << 8));
+
+ tbl_len = 64;
+ tbl_offset = 0;
+ for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+ tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+
+ for (idx = 0; idx < tbl_len; idx++) {
+ num =
+ 8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
+ den = 32768 + a1[tbl_id - 26] * idx;
+ pwr_est = MAX(((4 * num + den / 2) / den), -8);
+ if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+ if (idx <=
+ (uint) (31 - idle_tssi[tbl_id - 26] + 1))
+ pwr_est =
+ MAX(pwr_est,
+ target_pwr_qtrdbm[tbl_id - 26] +
+ 1);
+ }
+ regval[idx] = (uint32) pwr_est;
+ }
+ wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+ regval);
+ }
+
+ wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
+ pi->adj_pwr_tbl_nphy);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
+ pi->adj_pwr_tbl_nphy);
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi)
+{
+ return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
+ (0x1 << 14) | (0x1 << 13));
+}
+
+static uint8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, uint8 core)
+{
+ uint16 tmp;
+ tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
+
+ tmp = (tmp & (0x7f << 8)) >> 8;
+ return (uint8) tmp;
+}
+
+static void
+wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, uint8 idx0, uint8 idx1)
+{
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
+
+ if (NREV_GT(pi->pubpi.phy_rev, 1))
+ mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
+}
+
+uint16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi)
+{
+ uint16 tmp;
+ uint16 pwr_idx[2];
+
+ if (wlc_phy_txpwr_ison_nphy(pi)) {
+ pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
+ pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
+
+ tmp = (pwr_idx[0] << 8) | pwr_idx[1];
+ } else {
+ tmp =
+ ((pi->nphy_txpwrindex[PHY_CORE_0].
+ index_internal & 0xff) << 8) | (pi->
+ nphy_txpwrindex
+ [PHY_CORE_1].
+ index_internal & 0xff);
+ }
+
+ return tmp;
+}
+
+void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi)
+{
+ if (PHY_IPA(pi)
+ && (pi->nphy_force_papd_cal
+ || (wlc_phy_txpwr_ison_nphy(pi)
+ &&
+ (((uint32)
+ ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
+ pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
+ || ((uint32)
+ ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
+ pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) {
+ wlc_phy_a4(pi, TRUE);
+ }
+}
+
+void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, uint8 ctrl_type)
+{
+ uint16 mask = 0, val = 0, ishw = 0;
+ uint8 ctr;
+ uint core;
+ uint32 tbl_offset;
+ uint32 tbl_len;
+ uint16 regval[84];
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ switch (ctrl_type) {
+ case PHY_TPC_HW_OFF:
+ case PHY_TPC_HW_ON:
+ pi->nphy_txpwrctrl = ctrl_type;
+ break;
+ default:
+ break;
+ }
+
+ if (ctrl_type == PHY_TPC_HW_OFF) {
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ if (wlc_phy_txpwr_ison_nphy(pi)) {
+ for (core = 0; core < pi->pubpi.phy_corenum;
+ core++)
+ pi->nphy_txpwr_idx[core] =
+ wlc_phy_txpwr_idx_cur_get_nphy(pi,
+ (uint8)
+ core);
+ }
+
+ }
+
+ tbl_len = 84;
+ tbl_offset = 64;
+ for (ctr = 0; ctr < tbl_len; ctr++) {
+ regval[ctr] = 0;
+ }
+ wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
+ regval);
+ wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
+ regval);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+
+ and_phy_reg(pi, 0x1e7,
+ (uint16) (~((0x1 << 15) |
+ (0x1 << 14) | (0x1 << 13))));
+ } else {
+ and_phy_reg(pi, 0x1e7,
+ (uint16) (~((0x1 << 14) | (0x1 << 13))));
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ or_phy_reg(pi, 0x8f, (0x1 << 8));
+ or_phy_reg(pi, 0xa5, (0x1 << 8));
+ } else {
+ or_phy_reg(pi, 0xa5, (0x1 << 14));
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
+ else if (NREV_LT(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+ wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+ MHF1_IQSWAP_WAR, WLC_BAND_ALL);
+
+ } else {
+
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
+ 8, pi->adj_pwr_tbl_nphy);
+ wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
+ 8, pi->adj_pwr_tbl_nphy);
+
+ ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
+ mask = (0x1 << 14) | (0x1 << 13);
+ val = (ishw << 14) | (ishw << 13);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ mask |= (0x1 << 15);
+ val |= (ishw << 15);
+ }
+
+ mod_phy_reg(pi, 0x1e7, mask, val);
+
+ if (CHSPEC_IS5G(pi->radio_chanspec)) {
+ if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
+ mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
+ } else {
+ mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
+ if (NREV_GT(pi->pubpi.phy_rev, 1))
+ mod_phy_reg(pi, 0x222,
+ (0xff << 0), 0x64);
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ if ((pi->nphy_txpwr_idx[0] != 128)
+ && (pi->nphy_txpwr_idx[1] != 128)) {
+ wlc_phy_txpwr_idx_cur_set_nphy(pi,
+ pi->
+ nphy_txpwr_idx
+ [0],
+ pi->
+ nphy_txpwr_idx
+ [1]);
+ }
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ and_phy_reg(pi, 0x8f, ~(0x1 << 8));
+ and_phy_reg(pi, 0xa5, ~(0x1 << 8));
+ } else {
+ and_phy_reg(pi, 0xa5, ~(0x1 << 14));
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+ else if (NREV_LT(pi->pubpi.phy_rev, 2))
+ mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+
+ if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+ wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+ 0x0, WLC_BAND_ALL);
+
+ if (PHY_IPA(pi)) {
+ mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 2), (0) << 2);
+
+ mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 2), (0) << 2);
+
+ }
+
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+void
+wlc_phy_txpwr_index_nphy(phy_info_t *pi, uint8 core_mask, int8 txpwrindex,
+ bool restore_cals)
+{
+ uint8 core, txpwrctl_tbl;
+ uint16 tx_ind0, iq_ind0, lo_ind0;
+ uint16 m1m2;
+ uint32 txgain;
+ uint16 rad_gain, dac_gain;
+ uint8 bbmult;
+ uint32 iqcomp;
+ uint16 iqcomp_a, iqcomp_b;
+ uint32 locomp;
+ uint16 tmpval;
+ uint8 tx_pwr_ctrl_state;
+ int32 rfpwr_offset;
+ uint16 regval[2];
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+
+ tx_ind0 = 192;
+ iq_ind0 = 320;
+ lo_ind0 = 448;
+
+ for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+
+ if ((core_mask & (1 << core)) == 0) {
+ continue;
+ }
+
+ txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
+
+ if (txpwrindex < 0) {
+ if (pi->nphy_txpwrindex[core].index < 0) {
+
+ continue;
+ }
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ mod_phy_reg(pi, 0x8f,
+ (0x1 << 8),
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride);
+ mod_phy_reg(pi, 0xa5, (0x1 << 8),
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride);
+ } else {
+ mod_phy_reg(pi, 0xa5,
+ (0x1 << 14),
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride);
+ }
+
+ write_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xaa : 0xab,
+ pi->nphy_txpwrindex[core].AfeCtrlDacGain);
+
+ wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+ &pi->nphy_txpwrindex[core].
+ rad_gain);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+ m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+ m1m2 |= ((core == PHY_CORE_0) ?
+ (pi->nphy_txpwrindex[core].bbmult << 8) :
+ (pi->nphy_txpwrindex[core].bbmult << 0));
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+
+ if (restore_cals) {
+
+ wlc_phy_table_write_nphy(pi, 15, 2,
+ (80 + 2 * core), 16,
+ (void *)&pi->
+ nphy_txpwrindex[core].
+ iqcomp_a);
+
+ wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+ 16,
+ &pi->
+ nphy_txpwrindex[core].
+ locomp);
+ wlc_phy_table_write_nphy(pi, 15, 1, (93 + core),
+ 16,
+ (void *)&pi->
+ nphy_txpwrindex[core].
+ locomp);
+ }
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+
+ pi->nphy_txpwrindex[core].index_internal =
+ pi->nphy_txpwrindex[core].index_internal_save;
+ } else {
+
+ if (pi->nphy_txpwrindex[core].index < 0) {
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ mod_phy_reg(pi, 0x8f,
+ (0x1 << 8),
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride);
+ mod_phy_reg(pi, 0xa5, (0x1 << 8),
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride);
+ } else {
+ pi->nphy_txpwrindex[core].
+ AfectrlOverride =
+ read_phy_reg(pi, 0xa5);
+ }
+
+ pi->nphy_txpwrindex[core].AfeCtrlDacGain =
+ read_phy_reg(pi,
+ (core ==
+ PHY_CORE_0) ? 0xaa : 0xab);
+
+ wlc_phy_table_read_nphy(pi, 7, 1,
+ (0x110 + core), 16,
+ &pi->
+ nphy_txpwrindex[core].
+ rad_gain);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+ &tmpval);
+ tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
+ tmpval &= 0xff;
+ pi->nphy_txpwrindex[core].bbmult =
+ (uint8) tmpval;
+
+ wlc_phy_table_read_nphy(pi, 15, 2,
+ (80 + 2 * core), 16,
+ (void *)&pi->
+ nphy_txpwrindex[core].
+ iqcomp_a);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
+ 16,
+ (void *)&pi->
+ nphy_txpwrindex[core].
+ locomp);
+
+ pi->nphy_txpwrindex[core].index_internal_save =
+ pi->nphy_txpwrindex[core].index_internal;
+ }
+
+ tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+ wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+
+ if (NREV_IS(pi->pubpi.phy_rev, 1))
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+
+ wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+ (tx_ind0 + txpwrindex), 32,
+ &txgain);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ rad_gain =
+ (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+ } else {
+ rad_gain =
+ (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+ }
+ dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+ bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+
+ if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+ mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+ 0xa5), (0x1 << 8), (0x1 << 8));
+ } else {
+ mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+ }
+ write_phy_reg(pi, (core == PHY_CORE_0) ?
+ 0xaa : 0xab, dac_gain);
+
+ wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+ &rad_gain);
+
+ wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+ m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+ m1m2 |=
+ ((core ==
+ PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+
+ wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+
+ wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+ (iq_ind0 + txpwrindex), 32,
+ &iqcomp);
+ iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
+ iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
+
+ if (restore_cals) {
+ regval[0] = (uint16) iqcomp_a;
+ regval[1] = (uint16) iqcomp_b;
+ wlc_phy_table_write_nphy(pi, 15, 2,
+ (80 + 2 * core), 16,
+ regval);
+ }
+
+ wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+ (lo_ind0 + txpwrindex), 32,
+ &locomp);
+ if (restore_cals) {
+ wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+ 16, &locomp);
+ }
+
+ if (NREV_IS(pi->pubpi.phy_rev, 1))
+ wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+
+ if (PHY_IPA(pi)) {
+ wlc_phy_table_read_nphy(pi,
+ (core ==
+ PHY_CORE_0 ?
+ NPHY_TBL_ID_CORE1TXPWRCTL
+ :
+ NPHY_TBL_ID_CORE2TXPWRCTL),
+ 1, 576 + txpwrindex, 32,
+ &rfpwr_offset);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1ff << 4),
+ ((int16) rfpwr_offset) << 4);
+
+ mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+ 0x29b, (0x1 << 2), (1) << 2);
+
+ }
+
+ wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+ }
+
+ pi->nphy_txpwrindex[core].index = txpwrindex;
+ }
+
+ if (pi->phyhang_avoid)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+}
+
+void
+wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, uint8 *max_pwr,
+ uint8 txp_rate_idx)
+{
+ uint8 chan_freq_range;
+
+ chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
+ switch (chan_freq_range) {
+ case WL_CHAN_FREQ_RANGE_2G:
+ *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GM:
+ *max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GL:
+ *max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+ break;
+ case WL_CHAN_FREQ_RANGE_5GH:
+ *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+ break;
+ default:
+ ASSERT(0);
+ *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+ break;
+ }
+
+ return;
+}
+
+void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable)
+{
+ uint16 clip_off[] = { 0xffff, 0xffff };
+
+ ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC));
+
+ if (enable) {
+ if (pi->nphy_deaf_count == 0) {
+ pi->classifier_state =
+ wlc_phy_classifier_nphy(pi, 0, 0);
+ wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+ wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
+ wlc_phy_clip_det_nphy(pi, 1, clip_off);
+ }
+
+ pi->nphy_deaf_count++;
+
+ wlc_phy_resetcca_nphy(pi);
+
+ } else {
+ ASSERT(pi->nphy_deaf_count > 0);
+
+ pi->nphy_deaf_count--;
+
+ if (pi->nphy_deaf_count == 0) {
+ wlc_phy_classifier_nphy(pi, (0x7 << 0),
+ pi->classifier_state);
+ wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
+ }
+ }
+}
+
+void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode)
+{
+ wlapi_suspend_mac_and_wait(pi->sh->physhim);
+
+ if (mode) {
+ if (pi->nphy_deaf_count == 0)
+ wlc_phy_stay_in_carriersearch_nphy(pi, TRUE);
+ } else {
+ if (pi->nphy_deaf_count > 0)
+ wlc_phy_stay_in_carriersearch_nphy(pi, FALSE);
+ }
+ wlapi_enable_mac(pi->sh->physhim);
+}
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/phy/wlc_phy_radio.h
new file mode 100644
index 000000000000..72176ae2882c
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phy_radio.h
@@ -0,0 +1,1533 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _BCM20XX_H
+#define _BCM20XX_H
+
+#define RADIO_IDCODE 0x01
+
+#define RADIO_DEFAULT_CORE 0
+
+#define RXC0_RSSI_RST 0x80
+#define RXC0_MODE_RSSI 0x40
+#define RXC0_MODE_OFF 0x20
+#define RXC0_MODE_CM 0x10
+#define RXC0_LAN_LOAD 0x08
+#define RXC0_OFF_ADJ_MASK 0x07
+
+#define TXC0_MODE_TXLPF 0x04
+#define TXC0_PA_TSSI_EN 0x02
+#define TXC0_TSSI_EN 0x01
+
+#define TXC1_PA_GAIN_MASK 0x60
+#define TXC1_PA_GAIN_3DB 0x40
+#define TXC1_PA_GAIN_2DB 0x20
+#define TXC1_TX_MIX_GAIN 0x10
+#define TXC1_OFF_I_MASK 0x0c
+#define TXC1_OFF_Q_MASK 0x03
+
+#define RADIO_2055_READ_OFF 0x100
+#define RADIO_2057_READ_OFF 0x200
+
+#define RADIO_2055_GEN_SPARE 0x00
+#define RADIO_2055_SP_PIN_PD 0x02
+#define RADIO_2055_SP_RSSI_CORE1 0x03
+#define RADIO_2055_SP_PD_MISC_CORE1 0x04
+#define RADIO_2055_SP_RSSI_CORE2 0x05
+#define RADIO_2055_SP_PD_MISC_CORE2 0x06
+#define RADIO_2055_SP_RX_GC1_CORE1 0x07
+#define RADIO_2055_SP_RX_GC2_CORE1 0x08
+#define RADIO_2055_SP_RX_GC1_CORE2 0x09
+#define RADIO_2055_SP_RX_GC2_CORE2 0x0a
+#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
+#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
+#define RADIO_2055_SP_TX_GC1_CORE1 0x0d
+#define RADIO_2055_SP_TX_GC2_CORE1 0x0e
+#define RADIO_2055_SP_TX_GC1_CORE2 0x0f
+#define RADIO_2055_SP_TX_GC2_CORE2 0x10
+#define RADIO_2055_MASTER_CNTRL1 0x11
+#define RADIO_2055_MASTER_CNTRL2 0x12
+#define RADIO_2055_PD_LGEN 0x13
+#define RADIO_2055_PD_PLL_TS 0x14
+#define RADIO_2055_PD_CORE1_LGBUF 0x15
+#define RADIO_2055_PD_CORE1_TX 0x16
+#define RADIO_2055_PD_CORE1_RXTX 0x17
+#define RADIO_2055_PD_CORE1_RSSI_MISC 0x18
+#define RADIO_2055_PD_CORE2_LGBUF 0x19
+#define RADIO_2055_PD_CORE2_TX 0x1a
+#define RADIO_2055_PD_CORE2_RXTX 0x1b
+#define RADIO_2055_PD_CORE2_RSSI_MISC 0x1c
+#define RADIO_2055_PWRDET_LGEN 0x1d
+#define RADIO_2055_PWRDET_LGBUF_CORE1 0x1e
+#define RADIO_2055_PWRDET_RXTX_CORE1 0x1f
+#define RADIO_2055_PWRDET_LGBUF_CORE2 0x20
+#define RADIO_2055_PWRDET_RXTX_CORE2 0x21
+#define RADIO_2055_RRCCAL_CNTRL_SPARE 0x22
+#define RADIO_2055_RRCCAL_N_OPT_SEL 0x23
+#define RADIO_2055_CAL_MISC 0x24
+#define RADIO_2055_CAL_COUNTER_OUT 0x25
+#define RADIO_2055_CAL_COUNTER_OUT2 0x26
+#define RADIO_2055_CAL_CVAR_CNTRL 0x27
+#define RADIO_2055_CAL_RVAR_CNTRL 0x28
+#define RADIO_2055_CAL_LPO_CNTRL 0x29
+#define RADIO_2055_CAL_TS 0x2a
+#define RADIO_2055_CAL_RCCAL_READ_TS 0x2b
+#define RADIO_2055_CAL_RCAL_READ_TS 0x2c
+#define RADIO_2055_PAD_DRIVER 0x2d
+#define RADIO_2055_XO_CNTRL1 0x2e
+#define RADIO_2055_XO_CNTRL2 0x2f
+#define RADIO_2055_XO_REGULATOR 0x30
+#define RADIO_2055_XO_MISC 0x31
+#define RADIO_2055_PLL_LF_C1 0x32
+#define RADIO_2055_PLL_CAL_VTH 0x33
+#define RADIO_2055_PLL_LF_C2 0x34
+#define RADIO_2055_PLL_REF 0x35
+#define RADIO_2055_PLL_LF_R1 0x36
+#define RADIO_2055_PLL_PFD_CP 0x37
+#define RADIO_2055_PLL_IDAC_CPOPAMP 0x38
+#define RADIO_2055_PLL_CP_REGULATOR 0x39
+#define RADIO_2055_PLL_RCAL 0x3a
+#define RADIO_2055_RF_PLL_MOD0 0x3b
+#define RADIO_2055_RF_PLL_MOD1 0x3c
+#define RADIO_2055_RF_MMD_IDAC1 0x3d
+#define RADIO_2055_RF_MMD_IDAC0 0x3e
+#define RADIO_2055_RF_MMD_SPARE 0x3f
+#define RADIO_2055_VCO_CAL1 0x40
+#define RADIO_2055_VCO_CAL2 0x41
+#define RADIO_2055_VCO_CAL3 0x42
+#define RADIO_2055_VCO_CAL4 0x43
+#define RADIO_2055_VCO_CAL5 0x44
+#define RADIO_2055_VCO_CAL6 0x45
+#define RADIO_2055_VCO_CAL7 0x46
+#define RADIO_2055_VCO_CAL8 0x47
+#define RADIO_2055_VCO_CAL9 0x48
+#define RADIO_2055_VCO_CAL10 0x49
+#define RADIO_2055_VCO_CAL11 0x4a
+#define RADIO_2055_VCO_CAL12 0x4b
+#define RADIO_2055_VCO_CAL13 0x4c
+#define RADIO_2055_VCO_CAL14 0x4d
+#define RADIO_2055_VCO_CAL15 0x4e
+#define RADIO_2055_VCO_CAL16 0x4f
+#define RADIO_2055_VCO_KVCO 0x50
+#define RADIO_2055_VCO_CAP_TAIL 0x51
+#define RADIO_2055_VCO_IDAC_VCO 0x52
+#define RADIO_2055_VCO_REGULATOR 0x53
+#define RADIO_2055_PLL_RF_VTH 0x54
+#define RADIO_2055_LGBUF_CEN_BUF 0x55
+#define RADIO_2055_LGEN_TUNE1 0x56
+#define RADIO_2055_LGEN_TUNE2 0x57
+#define RADIO_2055_LGEN_IDAC1 0x58
+#define RADIO_2055_LGEN_IDAC2 0x59
+#define RADIO_2055_LGEN_BIAS_CNT 0x5a
+#define RADIO_2055_LGEN_BIAS_IDAC 0x5b
+#define RADIO_2055_LGEN_RCAL 0x5c
+#define RADIO_2055_LGEN_DIV 0x5d
+#define RADIO_2055_LGEN_SPARE2 0x5e
+#define RADIO_2055_CORE1_LGBUF_A_TUNE 0x5f
+#define RADIO_2055_CORE1_LGBUF_G_TUNE 0x60
+#define RADIO_2055_CORE1_LGBUF_DIV 0x61
+#define RADIO_2055_CORE1_LGBUF_A_IDAC 0x62
+#define RADIO_2055_CORE1_LGBUF_G_IDAC 0x63
+#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
+#define RADIO_2055_CORE1_LGBUF_SPARE 0x65
+#define RADIO_2055_CORE1_RXRF_SPC1 0x66
+#define RADIO_2055_CORE1_RXRF_REG1 0x67
+#define RADIO_2055_CORE1_RXRF_REG2 0x68
+#define RADIO_2055_CORE1_RXRF_RCAL 0x69
+#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
+#define RADIO_2055_CORE1_RXBB_LPF 0x6b
+#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
+#define RADIO_2055_CORE1_RXBB_VGA1_IDAC 0x6d
+#define RADIO_2055_CORE1_RXBB_VGA2_IDAC 0x6e
+#define RADIO_2055_CORE1_RXBB_VGA3_IDAC 0x6f
+#define RADIO_2055_CORE1_RXBB_BUFO_CTRL 0x70
+#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
+#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
+#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
+#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
+#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
+#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
+#define RADIO_2055_CORE1_RXBB_REGULATOR 0x77
+#define RADIO_2055_CORE1_RXBB_SPARE1 0x78
+#define RADIO_2055_CORE1_RXTXBB_RCAL 0x79
+#define RADIO_2055_CORE1_TXRF_SGM_PGA 0x7a
+#define RADIO_2055_CORE1_TXRF_SGM_PAD 0x7b
+#define RADIO_2055_CORE1_TXRF_CNTR_PGA1 0x7c
+#define RADIO_2055_CORE1_TXRF_CNTR_PAD1 0x7d
+#define RADIO_2055_CORE1_TX_RFPGA_IDAC 0x7e
+#define RADIO_2055_CORE1_TX_PGA_PAD_TN 0x7f
+#define RADIO_2055_CORE1_TX_PAD_IDAC1 0x80
+#define RADIO_2055_CORE1_TX_PAD_IDAC2 0x81
+#define RADIO_2055_CORE1_TX_MX_BGTRIM 0x82
+#define RADIO_2055_CORE1_TXRF_RCAL 0x83
+#define RADIO_2055_CORE1_TXRF_PAD_TSSI1 0x84
+#define RADIO_2055_CORE1_TXRF_PAD_TSSI2 0x85
+#define RADIO_2055_CORE1_TX_RF_SPARE 0x86
+#define RADIO_2055_CORE1_TXRF_IQCAL1 0x87
+#define RADIO_2055_CORE1_TXRF_IQCAL2 0x88
+#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
+#define RADIO_2055_CORE1_TXBB_LPF1 0x8a
+#define RADIO_2055_CORE1_TX_VOS_CNCL 0x8b
+#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
+#define RADIO_2055_CORE1_TX_BB_MXGM 0x8d
+#define RADIO_2055_CORE2_LGBUF_A_TUNE 0x8e
+#define RADIO_2055_CORE2_LGBUF_G_TUNE 0x8f
+#define RADIO_2055_CORE2_LGBUF_DIV 0x90
+#define RADIO_2055_CORE2_LGBUF_A_IDAC 0x91
+#define RADIO_2055_CORE2_LGBUF_G_IDAC 0x92
+#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
+#define RADIO_2055_CORE2_LGBUF_SPARE 0x94
+#define RADIO_2055_CORE2_RXRF_SPC1 0x95
+#define RADIO_2055_CORE2_RXRF_REG1 0x96
+#define RADIO_2055_CORE2_RXRF_REG2 0x97
+#define RADIO_2055_CORE2_RXRF_RCAL 0x98
+#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
+#define RADIO_2055_CORE2_RXBB_LPF 0x9a
+#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
+#define RADIO_2055_CORE2_RXBB_VGA1_IDAC 0x9c
+#define RADIO_2055_CORE2_RXBB_VGA2_IDAC 0x9d
+#define RADIO_2055_CORE2_RXBB_VGA3_IDAC 0x9e
+#define RADIO_2055_CORE2_RXBB_BUFO_CTRL 0x9f
+#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
+#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
+#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
+#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
+#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
+#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
+#define RADIO_2055_CORE2_RXBB_REGULATOR 0xa6
+#define RADIO_2055_CORE2_RXBB_SPARE1 0xa7
+#define RADIO_2055_CORE2_RXTXBB_RCAL 0xa8
+#define RADIO_2055_CORE2_TXRF_SGM_PGA 0xa9
+#define RADIO_2055_CORE2_TXRF_SGM_PAD 0xaa
+#define RADIO_2055_CORE2_TXRF_CNTR_PGA1 0xab
+#define RADIO_2055_CORE2_TXRF_CNTR_PAD1 0xac
+#define RADIO_2055_CORE2_TX_RFPGA_IDAC 0xad
+#define RADIO_2055_CORE2_TX_PGA_PAD_TN 0xae
+#define RADIO_2055_CORE2_TX_PAD_IDAC1 0xaf
+#define RADIO_2055_CORE2_TX_PAD_IDAC2 0xb0
+#define RADIO_2055_CORE2_TX_MX_BGTRIM 0xb1
+#define RADIO_2055_CORE2_TXRF_RCAL 0xb2
+#define RADIO_2055_CORE2_TXRF_PAD_TSSI1 0xb3
+#define RADIO_2055_CORE2_TXRF_PAD_TSSI2 0xb4
+#define RADIO_2055_CORE2_TX_RF_SPARE 0xb5
+#define RADIO_2055_CORE2_TXRF_IQCAL1 0xb6
+#define RADIO_2055_CORE2_TXRF_IQCAL2 0xb7
+#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
+#define RADIO_2055_CORE2_TXBB_LPF1 0xb9
+#define RADIO_2055_CORE2_TX_VOS_CNCL 0xba
+#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
+#define RADIO_2055_CORE2_TX_BB_MXGM 0xbc
+#define RADIO_2055_PRG_GC_HPVGA23_21 0xbd
+#define RADIO_2055_PRG_GC_HPVGA23_22 0xbe
+#define RADIO_2055_PRG_GC_HPVGA23_23 0xbf
+#define RADIO_2055_PRG_GC_HPVGA23_24 0xc0
+#define RADIO_2055_PRG_GC_HPVGA23_25 0xc1
+#define RADIO_2055_PRG_GC_HPVGA23_26 0xc2
+#define RADIO_2055_PRG_GC_HPVGA23_27 0xc3
+#define RADIO_2055_PRG_GC_HPVGA23_28 0xc4
+#define RADIO_2055_PRG_GC_HPVGA23_29 0xc5
+#define RADIO_2055_PRG_GC_HPVGA23_30 0xc6
+#define RADIO_2055_CORE1_LNA_GAINBST 0xcd
+#define RADIO_2055_CORE1_B0_NBRSSI_VCM 0xd2
+#define RADIO_2055_CORE1_GEN_SPARE2 0xd6
+#define RADIO_2055_CORE2_LNA_GAINBST 0xd9
+#define RADIO_2055_CORE2_B0_NBRSSI_VCM 0xde
+#define RADIO_2055_CORE2_GEN_SPARE2 0xe2
+
+#define RADIO_2055_GAINBST_GAIN_DB 6
+#define RADIO_2055_GAINBST_CODE 0x6
+
+#define RADIO_2055_JTAGCTRL_MASK 0x04
+#define RADIO_2055_JTAGSYNC_MASK 0x08
+#define RADIO_2055_RRCAL_START 0x40
+#define RADIO_2055_RRCAL_RST_N 0x01
+#define RADIO_2055_CAL_LPO_ENABLE 0x80
+#define RADIO_2055_RCAL_DONE 0x80
+#define RADIO_2055_NBRSSI_VCM_I_MASK 0x03
+#define RADIO_2055_NBRSSI_VCM_I_SHIFT 0x00
+#define RADIO_2055_NBRSSI_VCM_Q_MASK 0x03
+#define RADIO_2055_NBRSSI_VCM_Q_SHIFT 0x00
+#define RADIO_2055_WBRSSI_VCM_IQ_MASK 0x0c
+#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT 0x02
+#define RADIO_2055_NBRSSI_PD 0x01
+#define RADIO_2055_WBRSSI_G1_PD 0x04
+#define RADIO_2055_WBRSSI_G2_PD 0x02
+#define RADIO_2055_NBRSSI_SEL 0x01
+#define RADIO_2055_WBRSSI_G1_SEL 0x04
+#define RADIO_2055_WBRSSI_G2_SEL 0x02
+#define RADIO_2055_COUPLE_RX_MASK 0x01
+#define RADIO_2055_COUPLE_TX_MASK 0x02
+#define RADIO_2055_GAINBST_DISABLE 0x02
+#define RADIO_2055_GAINBST_VAL_MASK 0x07
+#define RADIO_2055_RXMX_GC_MASK 0x0c
+
+#define RADIO_MIMO_CORESEL_OFF 0x0
+#define RADIO_MIMO_CORESEL_CORE1 0x1
+#define RADIO_MIMO_CORESEL_CORE2 0x2
+#define RADIO_MIMO_CORESEL_CORE3 0x3
+#define RADIO_MIMO_CORESEL_CORE4 0x4
+#define RADIO_MIMO_CORESEL_ALLRX 0x5
+#define RADIO_MIMO_CORESEL_ALLTX 0x6
+#define RADIO_MIMO_CORESEL_ALLRXTX 0x7
+
+#define RADIO_2064_READ_OFF 0x200
+
+#define RADIO_2064_REG000 0x0
+#define RADIO_2064_REG001 0x1
+#define RADIO_2064_REG002 0x2
+#define RADIO_2064_REG003 0x3
+#define RADIO_2064_REG004 0x4
+#define RADIO_2064_REG005 0x5
+#define RADIO_2064_REG006 0x6
+#define RADIO_2064_REG007 0x7
+#define RADIO_2064_REG008 0x8
+#define RADIO_2064_REG009 0x9
+#define RADIO_2064_REG00A 0xa
+#define RADIO_2064_REG00B 0xb
+#define RADIO_2064_REG00C 0xc
+#define RADIO_2064_REG00D 0xd
+#define RADIO_2064_REG00E 0xe
+#define RADIO_2064_REG00F 0xf
+#define RADIO_2064_REG010 0x10
+#define RADIO_2064_REG011 0x11
+#define RADIO_2064_REG012 0x12
+#define RADIO_2064_REG013 0x13
+#define RADIO_2064_REG014 0x14
+#define RADIO_2064_REG015 0x15
+#define RADIO_2064_REG016 0x16
+#define RADIO_2064_REG017 0x17
+#define RADIO_2064_REG018 0x18
+#define RADIO_2064_REG019 0x19
+#define RADIO_2064_REG01A 0x1a
+#define RADIO_2064_REG01B 0x1b
+#define RADIO_2064_REG01C 0x1c
+#define RADIO_2064_REG01D 0x1d
+#define RADIO_2064_REG01E 0x1e
+#define RADIO_2064_REG01F 0x1f
+#define RADIO_2064_REG020 0x20
+#define RADIO_2064_REG021 0x21
+#define RADIO_2064_REG022 0x22
+#define RADIO_2064_REG023 0x23
+#define RADIO_2064_REG024 0x24
+#define RADIO_2064_REG025 0x25
+#define RADIO_2064_REG026 0x26
+#define RADIO_2064_REG027 0x27
+#define RADIO_2064_REG028 0x28
+#define RADIO_2064_REG029 0x29
+#define RADIO_2064_REG02A 0x2a
+#define RADIO_2064_REG02B 0x2b
+#define RADIO_2064_REG02C 0x2c
+#define RADIO_2064_REG02D 0x2d
+#define RADIO_2064_REG02E 0x2e
+#define RADIO_2064_REG02F 0x2f
+#define RADIO_2064_REG030 0x30
+#define RADIO_2064_REG031 0x31
+#define RADIO_2064_REG032 0x32
+#define RADIO_2064_REG033 0x33
+#define RADIO_2064_REG034 0x34
+#define RADIO_2064_REG035 0x35
+#define RADIO_2064_REG036 0x36
+#define RADIO_2064_REG037 0x37
+#define RADIO_2064_REG038 0x38
+#define RADIO_2064_REG039 0x39
+#define RADIO_2064_REG03A 0x3a
+#define RADIO_2064_REG03B 0x3b
+#define RADIO_2064_REG03C 0x3c
+#define RADIO_2064_REG03D 0x3d
+#define RADIO_2064_REG03E 0x3e
+#define RADIO_2064_REG03F 0x3f
+#define RADIO_2064_REG040 0x40
+#define RADIO_2064_REG041 0x41
+#define RADIO_2064_REG042 0x42
+#define RADIO_2064_REG043 0x43
+#define RADIO_2064_REG044 0x44
+#define RADIO_2064_REG045 0x45
+#define RADIO_2064_REG046 0x46
+#define RADIO_2064_REG047 0x47
+#define RADIO_2064_REG048 0x48
+#define RADIO_2064_REG049 0x49
+#define RADIO_2064_REG04A 0x4a
+#define RADIO_2064_REG04B 0x4b
+#define RADIO_2064_REG04C 0x4c
+#define RADIO_2064_REG04D 0x4d
+#define RADIO_2064_REG04E 0x4e
+#define RADIO_2064_REG04F 0x4f
+#define RADIO_2064_REG050 0x50
+#define RADIO_2064_REG051 0x51
+#define RADIO_2064_REG052 0x52
+#define RADIO_2064_REG053 0x53
+#define RADIO_2064_REG054 0x54
+#define RADIO_2064_REG055 0x55
+#define RADIO_2064_REG056 0x56
+#define RADIO_2064_REG057 0x57
+#define RADIO_2064_REG058 0x58
+#define RADIO_2064_REG059 0x59
+#define RADIO_2064_REG05A 0x5a
+#define RADIO_2064_REG05B 0x5b
+#define RADIO_2064_REG05C 0x5c
+#define RADIO_2064_REG05D 0x5d
+#define RADIO_2064_REG05E 0x5e
+#define RADIO_2064_REG05F 0x5f
+#define RADIO_2064_REG060 0x60
+#define RADIO_2064_REG061 0x61
+#define RADIO_2064_REG062 0x62
+#define RADIO_2064_REG063 0x63
+#define RADIO_2064_REG064 0x64
+#define RADIO_2064_REG065 0x65
+#define RADIO_2064_REG066 0x66
+#define RADIO_2064_REG067 0x67
+#define RADIO_2064_REG068 0x68
+#define RADIO_2064_REG069 0x69
+#define RADIO_2064_REG06A 0x6a
+#define RADIO_2064_REG06B 0x6b
+#define RADIO_2064_REG06C 0x6c
+#define RADIO_2064_REG06D 0x6d
+#define RADIO_2064_REG06E 0x6e
+#define RADIO_2064_REG06F 0x6f
+#define RADIO_2064_REG070 0x70
+#define RADIO_2064_REG071 0x71
+#define RADIO_2064_REG072 0x72
+#define RADIO_2064_REG073 0x73
+#define RADIO_2064_REG074 0x74
+#define RADIO_2064_REG075 0x75
+#define RADIO_2064_REG076 0x76
+#define RADIO_2064_REG077 0x77
+#define RADIO_2064_REG078 0x78
+#define RADIO_2064_REG079 0x79
+#define RADIO_2064_REG07A 0x7a
+#define RADIO_2064_REG07B 0x7b
+#define RADIO_2064_REG07C 0x7c
+#define RADIO_2064_REG07D 0x7d
+#define RADIO_2064_REG07E 0x7e
+#define RADIO_2064_REG07F 0x7f
+#define RADIO_2064_REG080 0x80
+#define RADIO_2064_REG081 0x81
+#define RADIO_2064_REG082 0x82
+#define RADIO_2064_REG083 0x83
+#define RADIO_2064_REG084 0x84
+#define RADIO_2064_REG085 0x85
+#define RADIO_2064_REG086 0x86
+#define RADIO_2064_REG087 0x87
+#define RADIO_2064_REG088 0x88
+#define RADIO_2064_REG089 0x89
+#define RADIO_2064_REG08A 0x8a
+#define RADIO_2064_REG08B 0x8b
+#define RADIO_2064_REG08C 0x8c
+#define RADIO_2064_REG08D 0x8d
+#define RADIO_2064_REG08E 0x8e
+#define RADIO_2064_REG08F 0x8f
+#define RADIO_2064_REG090 0x90
+#define RADIO_2064_REG091 0x91
+#define RADIO_2064_REG092 0x92
+#define RADIO_2064_REG093 0x93
+#define RADIO_2064_REG094 0x94
+#define RADIO_2064_REG095 0x95
+#define RADIO_2064_REG096 0x96
+#define RADIO_2064_REG097 0x97
+#define RADIO_2064_REG098 0x98
+#define RADIO_2064_REG099 0x99
+#define RADIO_2064_REG09A 0x9a
+#define RADIO_2064_REG09B 0x9b
+#define RADIO_2064_REG09C 0x9c
+#define RADIO_2064_REG09D 0x9d
+#define RADIO_2064_REG09E 0x9e
+#define RADIO_2064_REG09F 0x9f
+#define RADIO_2064_REG0A0 0xa0
+#define RADIO_2064_REG0A1 0xa1
+#define RADIO_2064_REG0A2 0xa2
+#define RADIO_2064_REG0A3 0xa3
+#define RADIO_2064_REG0A4 0xa4
+#define RADIO_2064_REG0A5 0xa5
+#define RADIO_2064_REG0A6 0xa6
+#define RADIO_2064_REG0A7 0xa7
+#define RADIO_2064_REG0A8 0xa8
+#define RADIO_2064_REG0A9 0xa9
+#define RADIO_2064_REG0AA 0xaa
+#define RADIO_2064_REG0AB 0xab
+#define RADIO_2064_REG0AC 0xac
+#define RADIO_2064_REG0AD 0xad
+#define RADIO_2064_REG0AE 0xae
+#define RADIO_2064_REG0AF 0xaf
+#define RADIO_2064_REG0B0 0xb0
+#define RADIO_2064_REG0B1 0xb1
+#define RADIO_2064_REG0B2 0xb2
+#define RADIO_2064_REG0B3 0xb3
+#define RADIO_2064_REG0B4 0xb4
+#define RADIO_2064_REG0B5 0xb5
+#define RADIO_2064_REG0B6 0xb6
+#define RADIO_2064_REG0B7 0xb7
+#define RADIO_2064_REG0B8 0xb8
+#define RADIO_2064_REG0B9 0xb9
+#define RADIO_2064_REG0BA 0xba
+#define RADIO_2064_REG0BB 0xbb
+#define RADIO_2064_REG0BC 0xbc
+#define RADIO_2064_REG0BD 0xbd
+#define RADIO_2064_REG0BE 0xbe
+#define RADIO_2064_REG0BF 0xbf
+#define RADIO_2064_REG0C0 0xc0
+#define RADIO_2064_REG0C1 0xc1
+#define RADIO_2064_REG0C2 0xc2
+#define RADIO_2064_REG0C3 0xc3
+#define RADIO_2064_REG0C4 0xc4
+#define RADIO_2064_REG0C5 0xc5
+#define RADIO_2064_REG0C6 0xc6
+#define RADIO_2064_REG0C7 0xc7
+#define RADIO_2064_REG0C8 0xc8
+#define RADIO_2064_REG0C9 0xc9
+#define RADIO_2064_REG0CA 0xca
+#define RADIO_2064_REG0CB 0xcb
+#define RADIO_2064_REG0CC 0xcc
+#define RADIO_2064_REG0CD 0xcd
+#define RADIO_2064_REG0CE 0xce
+#define RADIO_2064_REG0CF 0xcf
+#define RADIO_2064_REG0D0 0xd0
+#define RADIO_2064_REG0D1 0xd1
+#define RADIO_2064_REG0D2 0xd2
+#define RADIO_2064_REG0D3 0xd3
+#define RADIO_2064_REG0D4 0xd4
+#define RADIO_2064_REG0D5 0xd5
+#define RADIO_2064_REG0D6 0xd6
+#define RADIO_2064_REG0D7 0xd7
+#define RADIO_2064_REG0D8 0xd8
+#define RADIO_2064_REG0D9 0xd9
+#define RADIO_2064_REG0DA 0xda
+#define RADIO_2064_REG0DB 0xdb
+#define RADIO_2064_REG0DC 0xdc
+#define RADIO_2064_REG0DD 0xdd
+#define RADIO_2064_REG0DE 0xde
+#define RADIO_2064_REG0DF 0xdf
+#define RADIO_2064_REG0E0 0xe0
+#define RADIO_2064_REG0E1 0xe1
+#define RADIO_2064_REG0E2 0xe2
+#define RADIO_2064_REG0E3 0xe3
+#define RADIO_2064_REG0E4 0xe4
+#define RADIO_2064_REG0E5 0xe5
+#define RADIO_2064_REG0E6 0xe6
+#define RADIO_2064_REG0E7 0xe7
+#define RADIO_2064_REG0E8 0xe8
+#define RADIO_2064_REG0E9 0xe9
+#define RADIO_2064_REG0EA 0xea
+#define RADIO_2064_REG0EB 0xeb
+#define RADIO_2064_REG0EC 0xec
+#define RADIO_2064_REG0ED 0xed
+#define RADIO_2064_REG0EE 0xee
+#define RADIO_2064_REG0EF 0xef
+#define RADIO_2064_REG0F0 0xf0
+#define RADIO_2064_REG0F1 0xf1
+#define RADIO_2064_REG0F2 0xf2
+#define RADIO_2064_REG0F3 0xf3
+#define RADIO_2064_REG0F4 0xf4
+#define RADIO_2064_REG0F5 0xf5
+#define RADIO_2064_REG0F6 0xf6
+#define RADIO_2064_REG0F7 0xf7
+#define RADIO_2064_REG0F8 0xf8
+#define RADIO_2064_REG0F9 0xf9
+#define RADIO_2064_REG0FA 0xfa
+#define RADIO_2064_REG0FB 0xfb
+#define RADIO_2064_REG0FC 0xfc
+#define RADIO_2064_REG0FD 0xfd
+#define RADIO_2064_REG0FE 0xfe
+#define RADIO_2064_REG0FF 0xff
+#define RADIO_2064_REG100 0x100
+#define RADIO_2064_REG101 0x101
+#define RADIO_2064_REG102 0x102
+#define RADIO_2064_REG103 0x103
+#define RADIO_2064_REG104 0x104
+#define RADIO_2064_REG105 0x105
+#define RADIO_2064_REG106 0x106
+#define RADIO_2064_REG107 0x107
+#define RADIO_2064_REG108 0x108
+#define RADIO_2064_REG109 0x109
+#define RADIO_2064_REG10A 0x10a
+#define RADIO_2064_REG10B 0x10b
+#define RADIO_2064_REG10C 0x10c
+#define RADIO_2064_REG10D 0x10d
+#define RADIO_2064_REG10E 0x10e
+#define RADIO_2064_REG10F 0x10f
+#define RADIO_2064_REG110 0x110
+#define RADIO_2064_REG111 0x111
+#define RADIO_2064_REG112 0x112
+#define RADIO_2064_REG113 0x113
+#define RADIO_2064_REG114 0x114
+#define RADIO_2064_REG115 0x115
+#define RADIO_2064_REG116 0x116
+#define RADIO_2064_REG117 0x117
+#define RADIO_2064_REG118 0x118
+#define RADIO_2064_REG119 0x119
+#define RADIO_2064_REG11A 0x11a
+#define RADIO_2064_REG11B 0x11b
+#define RADIO_2064_REG11C 0x11c
+#define RADIO_2064_REG11D 0x11d
+#define RADIO_2064_REG11E 0x11e
+#define RADIO_2064_REG11F 0x11f
+#define RADIO_2064_REG120 0x120
+#define RADIO_2064_REG121 0x121
+#define RADIO_2064_REG122 0x122
+#define RADIO_2064_REG123 0x123
+#define RADIO_2064_REG124 0x124
+#define RADIO_2064_REG125 0x125
+#define RADIO_2064_REG126 0x126
+#define RADIO_2064_REG127 0x127
+#define RADIO_2064_REG128 0x128
+#define RADIO_2064_REG129 0x129
+#define RADIO_2064_REG12A 0x12a
+#define RADIO_2064_REG12B 0x12b
+#define RADIO_2064_REG12C 0x12c
+#define RADIO_2064_REG12D 0x12d
+#define RADIO_2064_REG12E 0x12e
+#define RADIO_2064_REG12F 0x12f
+#define RADIO_2064_REG130 0x130
+
+#define RADIO_2056_SYN (0x0 << 12)
+#define RADIO_2056_TX0 (0x2 << 12)
+#define RADIO_2056_TX1 (0x3 << 12)
+#define RADIO_2056_RX0 (0x6 << 12)
+#define RADIO_2056_RX1 (0x7 << 12)
+#define RADIO_2056_ALLTX (0xe << 12)
+#define RADIO_2056_ALLRX (0xf << 12)
+
+#define RADIO_2056_SYN_RESERVED_ADDR0 0x0
+#define RADIO_2056_SYN_IDCODE 0x1
+#define RADIO_2056_SYN_RESERVED_ADDR2 0x2
+#define RADIO_2056_SYN_RESERVED_ADDR3 0x3
+#define RADIO_2056_SYN_RESERVED_ADDR4 0x4
+#define RADIO_2056_SYN_RESERVED_ADDR5 0x5
+#define RADIO_2056_SYN_RESERVED_ADDR6 0x6
+#define RADIO_2056_SYN_RESERVED_ADDR7 0x7
+#define RADIO_2056_SYN_COM_CTRL 0x8
+#define RADIO_2056_SYN_COM_PU 0x9
+#define RADIO_2056_SYN_COM_OVR 0xa
+#define RADIO_2056_SYN_COM_RESET 0xb
+#define RADIO_2056_SYN_COM_RCAL 0xc
+#define RADIO_2056_SYN_COM_RC_RXLPF 0xd
+#define RADIO_2056_SYN_COM_RC_TXLPF 0xe
+#define RADIO_2056_SYN_COM_RC_RXHPF 0xf
+#define RADIO_2056_SYN_RESERVED_ADDR16 0x10
+#define RADIO_2056_SYN_RESERVED_ADDR17 0x11
+#define RADIO_2056_SYN_RESERVED_ADDR18 0x12
+#define RADIO_2056_SYN_RESERVED_ADDR19 0x13
+#define RADIO_2056_SYN_RESERVED_ADDR20 0x14
+#define RADIO_2056_SYN_RESERVED_ADDR21 0x15
+#define RADIO_2056_SYN_RESERVED_ADDR22 0x16
+#define RADIO_2056_SYN_RESERVED_ADDR23 0x17
+#define RADIO_2056_SYN_RESERVED_ADDR24 0x18
+#define RADIO_2056_SYN_RESERVED_ADDR25 0x19
+#define RADIO_2056_SYN_RESERVED_ADDR26 0x1a
+#define RADIO_2056_SYN_RESERVED_ADDR27 0x1b
+#define RADIO_2056_SYN_RESERVED_ADDR28 0x1c
+#define RADIO_2056_SYN_RESERVED_ADDR29 0x1d
+#define RADIO_2056_SYN_RESERVED_ADDR30 0x1e
+#define RADIO_2056_SYN_RESERVED_ADDR31 0x1f
+#define RADIO_2056_SYN_GPIO_MASTER1 0x20
+#define RADIO_2056_SYN_GPIO_MASTER2 0x21
+#define RADIO_2056_SYN_TOPBIAS_MASTER 0x22
+#define RADIO_2056_SYN_TOPBIAS_RCAL 0x23
+#define RADIO_2056_SYN_AFEREG 0x24
+#define RADIO_2056_SYN_TEMPPROCSENSE 0x25
+#define RADIO_2056_SYN_TEMPPROCSENSEIDAC 0x26
+#define RADIO_2056_SYN_TEMPPROCSENSERCAL 0x27
+#define RADIO_2056_SYN_LPO 0x28
+#define RADIO_2056_SYN_VDDCAL_MASTER 0x29
+#define RADIO_2056_SYN_VDDCAL_IDAC 0x2a
+#define RADIO_2056_SYN_VDDCAL_STATUS 0x2b
+#define RADIO_2056_SYN_RCAL_MASTER 0x2c
+#define RADIO_2056_SYN_RCAL_CODE_OUT 0x2d
+#define RADIO_2056_SYN_RCCAL_CTRL0 0x2e
+#define RADIO_2056_SYN_RCCAL_CTRL1 0x2f
+#define RADIO_2056_SYN_RCCAL_CTRL2 0x30
+#define RADIO_2056_SYN_RCCAL_CTRL3 0x31
+#define RADIO_2056_SYN_RCCAL_CTRL4 0x32
+#define RADIO_2056_SYN_RCCAL_CTRL5 0x33
+#define RADIO_2056_SYN_RCCAL_CTRL6 0x34
+#define RADIO_2056_SYN_RCCAL_CTRL7 0x35
+#define RADIO_2056_SYN_RCCAL_CTRL8 0x36
+#define RADIO_2056_SYN_RCCAL_CTRL9 0x37
+#define RADIO_2056_SYN_RCCAL_CTRL10 0x38
+#define RADIO_2056_SYN_RCCAL_CTRL11 0x39
+#define RADIO_2056_SYN_ZCAL_SPARE1 0x3a
+#define RADIO_2056_SYN_ZCAL_SPARE2 0x3b
+#define RADIO_2056_SYN_PLL_MAST1 0x3c
+#define RADIO_2056_SYN_PLL_MAST2 0x3d
+#define RADIO_2056_SYN_PLL_MAST3 0x3e
+#define RADIO_2056_SYN_PLL_BIAS_RESET 0x3f
+#define RADIO_2056_SYN_PLL_XTAL0 0x40
+#define RADIO_2056_SYN_PLL_XTAL1 0x41
+#define RADIO_2056_SYN_PLL_XTAL3 0x42
+#define RADIO_2056_SYN_PLL_XTAL4 0x43
+#define RADIO_2056_SYN_PLL_XTAL5 0x44
+#define RADIO_2056_SYN_PLL_XTAL6 0x45
+#define RADIO_2056_SYN_PLL_REFDIV 0x46
+#define RADIO_2056_SYN_PLL_PFD 0x47
+#define RADIO_2056_SYN_PLL_CP1 0x48
+#define RADIO_2056_SYN_PLL_CP2 0x49
+#define RADIO_2056_SYN_PLL_CP3 0x4a
+#define RADIO_2056_SYN_PLL_LOOPFILTER1 0x4b
+#define RADIO_2056_SYN_PLL_LOOPFILTER2 0x4c
+#define RADIO_2056_SYN_PLL_LOOPFILTER3 0x4d
+#define RADIO_2056_SYN_PLL_LOOPFILTER4 0x4e
+#define RADIO_2056_SYN_PLL_LOOPFILTER5 0x4f
+#define RADIO_2056_SYN_PLL_MMD1 0x50
+#define RADIO_2056_SYN_PLL_MMD2 0x51
+#define RADIO_2056_SYN_PLL_VCO1 0x52
+#define RADIO_2056_SYN_PLL_VCO2 0x53
+#define RADIO_2056_SYN_PLL_MONITOR1 0x54
+#define RADIO_2056_SYN_PLL_MONITOR2 0x55
+#define RADIO_2056_SYN_PLL_VCOCAL1 0x56
+#define RADIO_2056_SYN_PLL_VCOCAL2 0x57
+#define RADIO_2056_SYN_PLL_VCOCAL4 0x58
+#define RADIO_2056_SYN_PLL_VCOCAL5 0x59
+#define RADIO_2056_SYN_PLL_VCOCAL6 0x5a
+#define RADIO_2056_SYN_PLL_VCOCAL7 0x5b
+#define RADIO_2056_SYN_PLL_VCOCAL8 0x5c
+#define RADIO_2056_SYN_PLL_VCOCAL9 0x5d
+#define RADIO_2056_SYN_PLL_VCOCAL10 0x5e
+#define RADIO_2056_SYN_PLL_VCOCAL11 0x5f
+#define RADIO_2056_SYN_PLL_VCOCAL12 0x60
+#define RADIO_2056_SYN_PLL_VCOCAL13 0x61
+#define RADIO_2056_SYN_PLL_VREG 0x62
+#define RADIO_2056_SYN_PLL_STATUS1 0x63
+#define RADIO_2056_SYN_PLL_STATUS2 0x64
+#define RADIO_2056_SYN_PLL_STATUS3 0x65
+#define RADIO_2056_SYN_LOGEN_PU0 0x66
+#define RADIO_2056_SYN_LOGEN_PU1 0x67
+#define RADIO_2056_SYN_LOGEN_PU2 0x68
+#define RADIO_2056_SYN_LOGEN_PU3 0x69
+#define RADIO_2056_SYN_LOGEN_PU5 0x6a
+#define RADIO_2056_SYN_LOGEN_PU6 0x6b
+#define RADIO_2056_SYN_LOGEN_PU7 0x6c
+#define RADIO_2056_SYN_LOGEN_PU8 0x6d
+#define RADIO_2056_SYN_LOGEN_BIAS_RESET 0x6e
+#define RADIO_2056_SYN_LOGEN_RCCR1 0x6f
+#define RADIO_2056_SYN_LOGEN_VCOBUF1 0x70
+#define RADIO_2056_SYN_LOGEN_MIXER1 0x71
+#define RADIO_2056_SYN_LOGEN_MIXER2 0x72
+#define RADIO_2056_SYN_LOGEN_BUF1 0x73
+#define RADIO_2056_SYN_LOGENBUF2 0x74
+#define RADIO_2056_SYN_LOGEN_BUF3 0x75
+#define RADIO_2056_SYN_LOGEN_BUF4 0x76
+#define RADIO_2056_SYN_LOGEN_DIV1 0x77
+#define RADIO_2056_SYN_LOGEN_DIV2 0x78
+#define RADIO_2056_SYN_LOGEN_DIV3 0x79
+#define RADIO_2056_SYN_LOGEN_ACL1 0x7a
+#define RADIO_2056_SYN_LOGEN_ACL2 0x7b
+#define RADIO_2056_SYN_LOGEN_ACL3 0x7c
+#define RADIO_2056_SYN_LOGEN_ACL4 0x7d
+#define RADIO_2056_SYN_LOGEN_ACL5 0x7e
+#define RADIO_2056_SYN_LOGEN_ACL6 0x7f
+#define RADIO_2056_SYN_LOGEN_ACLOUT 0x80
+#define RADIO_2056_SYN_LOGEN_ACLCAL1 0x81
+#define RADIO_2056_SYN_LOGEN_ACLCAL2 0x82
+#define RADIO_2056_SYN_LOGEN_ACLCAL3 0x83
+#define RADIO_2056_SYN_CALEN 0x84
+#define RADIO_2056_SYN_LOGEN_PEAKDET1 0x85
+#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR 0x86
+#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
+#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
+#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
+#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8a
+#define RADIO_2056_SYN_LOGEN_VCOBUF2 0x8b
+#define RADIO_2056_SYN_LOGEN_MIXER3 0x8c
+#define RADIO_2056_SYN_LOGEN_BUF5 0x8d
+#define RADIO_2056_SYN_LOGEN_BUF6 0x8e
+#define RADIO_2056_SYN_LOGEN_CBUFRX1 0x8f
+#define RADIO_2056_SYN_LOGEN_CBUFRX2 0x90
+#define RADIO_2056_SYN_LOGEN_CBUFRX3 0x91
+#define RADIO_2056_SYN_LOGEN_CBUFRX4 0x92
+#define RADIO_2056_SYN_LOGEN_CBUFTX1 0x93
+#define RADIO_2056_SYN_LOGEN_CBUFTX2 0x94
+#define RADIO_2056_SYN_LOGEN_CBUFTX3 0x95
+#define RADIO_2056_SYN_LOGEN_CBUFTX4 0x96
+#define RADIO_2056_SYN_LOGEN_CMOSRX1 0x97
+#define RADIO_2056_SYN_LOGEN_CMOSRX2 0x98
+#define RADIO_2056_SYN_LOGEN_CMOSRX3 0x99
+#define RADIO_2056_SYN_LOGEN_CMOSRX4 0x9a
+#define RADIO_2056_SYN_LOGEN_CMOSTX1 0x9b
+#define RADIO_2056_SYN_LOGEN_CMOSTX2 0x9c
+#define RADIO_2056_SYN_LOGEN_CMOSTX3 0x9d
+#define RADIO_2056_SYN_LOGEN_CMOSTX4 0x9e
+#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9f
+#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL 0xa0
+#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL 0xa1
+#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL 0xa2
+#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xa3
+#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xa4
+#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xa5
+#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xa6
+#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xa7
+#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xa8
+#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xa9
+#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xaa
+#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xab
+#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xac
+#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xad
+#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xae
+#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xaf
+#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xb0
+#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xb1
+#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xb2
+#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT 0xb3
+#define RADIO_2056_SYN_LOGEN_CORE_CALVALID 0xb4
+#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID 0xb5
+#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID 0xb6
+
+#define RADIO_2056_TX_RESERVED_ADDR0 0x0
+#define RADIO_2056_TX_IDCODE 0x1
+#define RADIO_2056_TX_RESERVED_ADDR2 0x2
+#define RADIO_2056_TX_RESERVED_ADDR3 0x3
+#define RADIO_2056_TX_RESERVED_ADDR4 0x4
+#define RADIO_2056_TX_RESERVED_ADDR5 0x5
+#define RADIO_2056_TX_RESERVED_ADDR6 0x6
+#define RADIO_2056_TX_RESERVED_ADDR7 0x7
+#define RADIO_2056_TX_COM_CTRL 0x8
+#define RADIO_2056_TX_COM_PU 0x9
+#define RADIO_2056_TX_COM_OVR 0xa
+#define RADIO_2056_TX_COM_RESET 0xb
+#define RADIO_2056_TX_COM_RCAL 0xc
+#define RADIO_2056_TX_COM_RC_RXLPF 0xd
+#define RADIO_2056_TX_COM_RC_TXLPF 0xe
+#define RADIO_2056_TX_COM_RC_RXHPF 0xf
+#define RADIO_2056_TX_RESERVED_ADDR16 0x10
+#define RADIO_2056_TX_RESERVED_ADDR17 0x11
+#define RADIO_2056_TX_RESERVED_ADDR18 0x12
+#define RADIO_2056_TX_RESERVED_ADDR19 0x13
+#define RADIO_2056_TX_RESERVED_ADDR20 0x14
+#define RADIO_2056_TX_RESERVED_ADDR21 0x15
+#define RADIO_2056_TX_RESERVED_ADDR22 0x16
+#define RADIO_2056_TX_RESERVED_ADDR23 0x17
+#define RADIO_2056_TX_RESERVED_ADDR24 0x18
+#define RADIO_2056_TX_RESERVED_ADDR25 0x19
+#define RADIO_2056_TX_RESERVED_ADDR26 0x1a
+#define RADIO_2056_TX_RESERVED_ADDR27 0x1b
+#define RADIO_2056_TX_RESERVED_ADDR28 0x1c
+#define RADIO_2056_TX_RESERVED_ADDR29 0x1d
+#define RADIO_2056_TX_RESERVED_ADDR30 0x1e
+#define RADIO_2056_TX_RESERVED_ADDR31 0x1f
+#define RADIO_2056_TX_IQCAL_GAIN_BW 0x20
+#define RADIO_2056_TX_LOFT_FINE_I 0x21
+#define RADIO_2056_TX_LOFT_FINE_Q 0x22
+#define RADIO_2056_TX_LOFT_COARSE_I 0x23
+#define RADIO_2056_TX_LOFT_COARSE_Q 0x24
+#define RADIO_2056_TX_TX_COM_MASTER1 0x25
+#define RADIO_2056_TX_TX_COM_MASTER2 0x26
+#define RADIO_2056_TX_RXIQCAL_TXMUX 0x27
+#define RADIO_2056_TX_TX_SSI_MASTER 0x28
+#define RADIO_2056_TX_IQCAL_VCM_HG 0x29
+#define RADIO_2056_TX_IQCAL_IDAC 0x2a
+#define RADIO_2056_TX_TSSI_VCM 0x2b
+#define RADIO_2056_TX_TX_AMP_DET 0x2c
+#define RADIO_2056_TX_TX_SSI_MUX 0x2d
+#define RADIO_2056_TX_TSSIA 0x2e
+#define RADIO_2056_TX_TSSIG 0x2f
+#define RADIO_2056_TX_TSSI_MISC1 0x30
+#define RADIO_2056_TX_TSSI_MISC2 0x31
+#define RADIO_2056_TX_TSSI_MISC3 0x32
+#define RADIO_2056_TX_PA_SPARE1 0x33
+#define RADIO_2056_TX_PA_SPARE2 0x34
+#define RADIO_2056_TX_INTPAA_MASTER 0x35
+#define RADIO_2056_TX_INTPAA_GAIN 0x36
+#define RADIO_2056_TX_INTPAA_BOOST_TUNE 0x37
+#define RADIO_2056_TX_INTPAA_IAUX_STAT 0x38
+#define RADIO_2056_TX_INTPAA_IAUX_DYN 0x39
+#define RADIO_2056_TX_INTPAA_IMAIN_STAT 0x3a
+#define RADIO_2056_TX_INTPAA_IMAIN_DYN 0x3b
+#define RADIO_2056_TX_INTPAA_CASCBIAS 0x3c
+#define RADIO_2056_TX_INTPAA_PASLOPE 0x3d
+#define RADIO_2056_TX_INTPAA_PA_MISC 0x3e
+#define RADIO_2056_TX_INTPAG_MASTER 0x3f
+#define RADIO_2056_TX_INTPAG_GAIN 0x40
+#define RADIO_2056_TX_INTPAG_BOOST_TUNE 0x41
+#define RADIO_2056_TX_INTPAG_IAUX_STAT 0x42
+#define RADIO_2056_TX_INTPAG_IAUX_DYN 0x43
+#define RADIO_2056_TX_INTPAG_IMAIN_STAT 0x44
+#define RADIO_2056_TX_INTPAG_IMAIN_DYN 0x45
+#define RADIO_2056_TX_INTPAG_CASCBIAS 0x46
+#define RADIO_2056_TX_INTPAG_PASLOPE 0x47
+#define RADIO_2056_TX_INTPAG_PA_MISC 0x48
+#define RADIO_2056_TX_PADA_MASTER 0x49
+#define RADIO_2056_TX_PADA_IDAC 0x4a
+#define RADIO_2056_TX_PADA_CASCBIAS 0x4b
+#define RADIO_2056_TX_PADA_GAIN 0x4c
+#define RADIO_2056_TX_PADA_BOOST_TUNE 0x4d
+#define RADIO_2056_TX_PADA_SLOPE 0x4e
+#define RADIO_2056_TX_PADG_MASTER 0x4f
+#define RADIO_2056_TX_PADG_IDAC 0x50
+#define RADIO_2056_TX_PADG_CASCBIAS 0x51
+#define RADIO_2056_TX_PADG_GAIN 0x52
+#define RADIO_2056_TX_PADG_BOOST_TUNE 0x53
+#define RADIO_2056_TX_PADG_SLOPE 0x54
+#define RADIO_2056_TX_PGAA_MASTER 0x55
+#define RADIO_2056_TX_PGAA_IDAC 0x56
+#define RADIO_2056_TX_PGAA_GAIN 0x57
+#define RADIO_2056_TX_PGAA_BOOST_TUNE 0x58
+#define RADIO_2056_TX_PGAA_SLOPE 0x59
+#define RADIO_2056_TX_PGAA_MISC 0x5a
+#define RADIO_2056_TX_PGAG_MASTER 0x5b
+#define RADIO_2056_TX_PGAG_IDAC 0x5c
+#define RADIO_2056_TX_PGAG_GAIN 0x5d
+#define RADIO_2056_TX_PGAG_BOOST_TUNE 0x5e
+#define RADIO_2056_TX_PGAG_SLOPE 0x5f
+#define RADIO_2056_TX_PGAG_MISC 0x60
+#define RADIO_2056_TX_MIXA_MASTER 0x61
+#define RADIO_2056_TX_MIXA_BOOST_TUNE 0x62
+#define RADIO_2056_TX_MIXG 0x63
+#define RADIO_2056_TX_MIXG_BOOST_TUNE 0x64
+#define RADIO_2056_TX_BB_GM_MASTER 0x65
+#define RADIO_2056_TX_GMBB_GM 0x66
+#define RADIO_2056_TX_GMBB_IDAC 0x67
+#define RADIO_2056_TX_TXLPF_MASTER 0x68
+#define RADIO_2056_TX_TXLPF_RCCAL 0x69
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF0 0x6a
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF1 0x6b
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF2 0x6c
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF3 0x6d
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF4 0x6e
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF5 0x6f
+#define RADIO_2056_TX_TXLPF_RCCAL_OFF6 0x70
+#define RADIO_2056_TX_TXLPF_BW 0x71
+#define RADIO_2056_TX_TXLPF_GAIN 0x72
+#define RADIO_2056_TX_TXLPF_IDAC 0x73
+#define RADIO_2056_TX_TXLPF_IDAC_0 0x74
+#define RADIO_2056_TX_TXLPF_IDAC_1 0x75
+#define RADIO_2056_TX_TXLPF_IDAC_2 0x76
+#define RADIO_2056_TX_TXLPF_IDAC_3 0x77
+#define RADIO_2056_TX_TXLPF_IDAC_4 0x78
+#define RADIO_2056_TX_TXLPF_IDAC_5 0x79
+#define RADIO_2056_TX_TXLPF_IDAC_6 0x7a
+#define RADIO_2056_TX_TXLPF_OPAMP_IDAC 0x7b
+#define RADIO_2056_TX_TXLPF_MISC 0x7c
+#define RADIO_2056_TX_TXSPARE1 0x7d
+#define RADIO_2056_TX_TXSPARE2 0x7e
+#define RADIO_2056_TX_TXSPARE3 0x7f
+#define RADIO_2056_TX_TXSPARE4 0x80
+#define RADIO_2056_TX_TXSPARE5 0x81
+#define RADIO_2056_TX_TXSPARE6 0x82
+#define RADIO_2056_TX_TXSPARE7 0x83
+#define RADIO_2056_TX_TXSPARE8 0x84
+#define RADIO_2056_TX_TXSPARE9 0x85
+#define RADIO_2056_TX_TXSPARE10 0x86
+#define RADIO_2056_TX_TXSPARE11 0x87
+#define RADIO_2056_TX_TXSPARE12 0x88
+#define RADIO_2056_TX_TXSPARE13 0x89
+#define RADIO_2056_TX_TXSPARE14 0x8a
+#define RADIO_2056_TX_TXSPARE15 0x8b
+#define RADIO_2056_TX_TXSPARE16 0x8c
+#define RADIO_2056_TX_STATUS_INTPA_GAIN 0x8d
+#define RADIO_2056_TX_STATUS_PAD_GAIN 0x8e
+#define RADIO_2056_TX_STATUS_PGA_GAIN 0x8f
+#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN 0x90
+#define RADIO_2056_TX_STATUS_TXLPF_BW 0x91
+#define RADIO_2056_TX_STATUS_TXLPF_RC 0x92
+#define RADIO_2056_TX_GMBB_IDAC0 0x93
+#define RADIO_2056_TX_GMBB_IDAC1 0x94
+#define RADIO_2056_TX_GMBB_IDAC2 0x95
+#define RADIO_2056_TX_GMBB_IDAC3 0x96
+#define RADIO_2056_TX_GMBB_IDAC4 0x97
+#define RADIO_2056_TX_GMBB_IDAC5 0x98
+#define RADIO_2056_TX_GMBB_IDAC6 0x99
+#define RADIO_2056_TX_GMBB_IDAC7 0x9a
+
+#define RADIO_2056_RX_RESERVED_ADDR0 0x0
+#define RADIO_2056_RX_IDCODE 0x1
+#define RADIO_2056_RX_RESERVED_ADDR2 0x2
+#define RADIO_2056_RX_RESERVED_ADDR3 0x3
+#define RADIO_2056_RX_RESERVED_ADDR4 0x4
+#define RADIO_2056_RX_RESERVED_ADDR5 0x5
+#define RADIO_2056_RX_RESERVED_ADDR6 0x6
+#define RADIO_2056_RX_RESERVED_ADDR7 0x7
+#define RADIO_2056_RX_COM_CTRL 0x8
+#define RADIO_2056_RX_COM_PU 0x9
+#define RADIO_2056_RX_COM_OVR 0xa
+#define RADIO_2056_RX_COM_RESET 0xb
+#define RADIO_2056_RX_COM_RCAL 0xc
+#define RADIO_2056_RX_COM_RC_RXLPF 0xd
+#define RADIO_2056_RX_COM_RC_TXLPF 0xe
+#define RADIO_2056_RX_COM_RC_RXHPF 0xf
+#define RADIO_2056_RX_RESERVED_ADDR16 0x10
+#define RADIO_2056_RX_RESERVED_ADDR17 0x11
+#define RADIO_2056_RX_RESERVED_ADDR18 0x12
+#define RADIO_2056_RX_RESERVED_ADDR19 0x13
+#define RADIO_2056_RX_RESERVED_ADDR20 0x14
+#define RADIO_2056_RX_RESERVED_ADDR21 0x15
+#define RADIO_2056_RX_RESERVED_ADDR22 0x16
+#define RADIO_2056_RX_RESERVED_ADDR23 0x17
+#define RADIO_2056_RX_RESERVED_ADDR24 0x18
+#define RADIO_2056_RX_RESERVED_ADDR25 0x19
+#define RADIO_2056_RX_RESERVED_ADDR26 0x1a
+#define RADIO_2056_RX_RESERVED_ADDR27 0x1b
+#define RADIO_2056_RX_RESERVED_ADDR28 0x1c
+#define RADIO_2056_RX_RESERVED_ADDR29 0x1d
+#define RADIO_2056_RX_RESERVED_ADDR30 0x1e
+#define RADIO_2056_RX_RESERVED_ADDR31 0x1f
+#define RADIO_2056_RX_RXIQCAL_RXMUX 0x20
+#define RADIO_2056_RX_RSSI_PU 0x21
+#define RADIO_2056_RX_RSSI_SEL 0x22
+#define RADIO_2056_RX_RSSI_GAIN 0x23
+#define RADIO_2056_RX_RSSI_NB_IDAC 0x24
+#define RADIO_2056_RX_RSSI_WB2I_IDAC_1 0x25
+#define RADIO_2056_RX_RSSI_WB2I_IDAC_2 0x26
+#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1 0x27
+#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2 0x28
+#define RADIO_2056_RX_RSSI_POLE 0x29
+#define RADIO_2056_RX_RSSI_WB1_IDAC 0x2a
+#define RADIO_2056_RX_RSSI_MISC 0x2b
+#define RADIO_2056_RX_LNAA_MASTER 0x2c
+#define RADIO_2056_RX_LNAA_TUNE 0x2d
+#define RADIO_2056_RX_LNAA_GAIN 0x2e
+#define RADIO_2056_RX_LNA_A_SLOPE 0x2f
+#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC 0x30
+#define RADIO_2056_RX_LNAA2_IDAC 0x31
+#define RADIO_2056_RX_LNA1A_MISC 0x32
+#define RADIO_2056_RX_LNAG_MASTER 0x33
+#define RADIO_2056_RX_LNAG_TUNE 0x34
+#define RADIO_2056_RX_LNAG_GAIN 0x35
+#define RADIO_2056_RX_LNA_G_SLOPE 0x36
+#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC 0x37
+#define RADIO_2056_RX_LNAG2_IDAC 0x38
+#define RADIO_2056_RX_LNA1G_MISC 0x39
+#define RADIO_2056_RX_MIXA_MASTER 0x3a
+#define RADIO_2056_RX_MIXA_VCM 0x3b
+#define RADIO_2056_RX_MIXA_CTRLPTAT 0x3c
+#define RADIO_2056_RX_MIXA_LOB_BIAS 0x3d
+#define RADIO_2056_RX_MIXA_CORE_IDAC 0x3e
+#define RADIO_2056_RX_MIXA_CMFB_IDAC 0x3f
+#define RADIO_2056_RX_MIXA_BIAS_AUX 0x40
+#define RADIO_2056_RX_MIXA_BIAS_MAIN 0x41
+#define RADIO_2056_RX_MIXA_BIAS_MISC 0x42
+#define RADIO_2056_RX_MIXA_MAST_BIAS 0x43
+#define RADIO_2056_RX_MIXG_MASTER 0x44
+#define RADIO_2056_RX_MIXG_VCM 0x45
+#define RADIO_2056_RX_MIXG_CTRLPTAT 0x46
+#define RADIO_2056_RX_MIXG_LOB_BIAS 0x47
+#define RADIO_2056_RX_MIXG_CORE_IDAC 0x48
+#define RADIO_2056_RX_MIXG_CMFB_IDAC 0x49
+#define RADIO_2056_RX_MIXG_BIAS_AUX 0x4a
+#define RADIO_2056_RX_MIXG_BIAS_MAIN 0x4b
+#define RADIO_2056_RX_MIXG_BIAS_MISC 0x4c
+#define RADIO_2056_RX_MIXG_MAST_BIAS 0x4d
+#define RADIO_2056_RX_TIA_MASTER 0x4e
+#define RADIO_2056_RX_TIA_IOPAMP 0x4f
+#define RADIO_2056_RX_TIA_QOPAMP 0x50
+#define RADIO_2056_RX_TIA_IMISC 0x51
+#define RADIO_2056_RX_TIA_QMISC 0x52
+#define RADIO_2056_RX_TIA_GAIN 0x53
+#define RADIO_2056_RX_TIA_SPARE1 0x54
+#define RADIO_2056_RX_TIA_SPARE2 0x55
+#define RADIO_2056_RX_BB_LPF_MASTER 0x56
+#define RADIO_2056_RX_AACI_MASTER 0x57
+#define RADIO_2056_RX_RXLPF_IDAC 0x58
+#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
+#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5a
+#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL 0x5b
+#define RADIO_2056_RX_RXLPF_OUTVCM 0x5c
+#define RADIO_2056_RX_RXLPF_INVCM_BODY 0x5d
+#define RADIO_2056_RX_RXLPF_CC_OP 0x5e
+#define RADIO_2056_RX_RXLPF_GAIN 0x5f
+#define RADIO_2056_RX_RXLPF_Q_BW 0x60
+#define RADIO_2056_RX_RXLPF_HP_CORNER_BW 0x61
+#define RADIO_2056_RX_RXLPF_RCCAL_HPC 0x62
+#define RADIO_2056_RX_RXHPF_OFF0 0x63
+#define RADIO_2056_RX_RXHPF_OFF1 0x64
+#define RADIO_2056_RX_RXHPF_OFF2 0x65
+#define RADIO_2056_RX_RXHPF_OFF3 0x66
+#define RADIO_2056_RX_RXHPF_OFF4 0x67
+#define RADIO_2056_RX_RXHPF_OFF5 0x68
+#define RADIO_2056_RX_RXHPF_OFF6 0x69
+#define RADIO_2056_RX_RXHPF_OFF7 0x6a
+#define RADIO_2056_RX_RXLPF_RCCAL_LPC 0x6b
+#define RADIO_2056_RX_RXLPF_OFF_0 0x6c
+#define RADIO_2056_RX_RXLPF_OFF_1 0x6d
+#define RADIO_2056_RX_RXLPF_OFF_2 0x6e
+#define RADIO_2056_RX_RXLPF_OFF_3 0x6f
+#define RADIO_2056_RX_RXLPF_OFF_4 0x70
+#define RADIO_2056_RX_UNUSED 0x71
+#define RADIO_2056_RX_VGA_MASTER 0x72
+#define RADIO_2056_RX_VGA_BIAS 0x73
+#define RADIO_2056_RX_VGA_BIAS_DCCANCEL 0x74
+#define RADIO_2056_RX_VGA_GAIN 0x75
+#define RADIO_2056_RX_VGA_HP_CORNER_BW 0x76
+#define RADIO_2056_RX_VGABUF_BIAS 0x77
+#define RADIO_2056_RX_VGABUF_GAIN_BW 0x78
+#define RADIO_2056_RX_TXFBMIX_A 0x79
+#define RADIO_2056_RX_TXFBMIX_G 0x7a
+#define RADIO_2056_RX_RXSPARE1 0x7b
+#define RADIO_2056_RX_RXSPARE2 0x7c
+#define RADIO_2056_RX_RXSPARE3 0x7d
+#define RADIO_2056_RX_RXSPARE4 0x7e
+#define RADIO_2056_RX_RXSPARE5 0x7f
+#define RADIO_2056_RX_RXSPARE6 0x80
+#define RADIO_2056_RX_RXSPARE7 0x81
+#define RADIO_2056_RX_RXSPARE8 0x82
+#define RADIO_2056_RX_RXSPARE9 0x83
+#define RADIO_2056_RX_RXSPARE10 0x84
+#define RADIO_2056_RX_RXSPARE11 0x85
+#define RADIO_2056_RX_RXSPARE12 0x86
+#define RADIO_2056_RX_RXSPARE13 0x87
+#define RADIO_2056_RX_RXSPARE14 0x88
+#define RADIO_2056_RX_RXSPARE15 0x89
+#define RADIO_2056_RX_RXSPARE16 0x8a
+#define RADIO_2056_RX_STATUS_LNAA_GAIN 0x8b
+#define RADIO_2056_RX_STATUS_LNAG_GAIN 0x8c
+#define RADIO_2056_RX_STATUS_MIXTIA_GAIN 0x8d
+#define RADIO_2056_RX_STATUS_RXLPF_GAIN 0x8e
+#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN 0x8f
+#define RADIO_2056_RX_STATUS_RXLPF_Q 0x90
+#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW 0x91
+#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC 0x92
+#define RADIO_2056_RX_STATUS_RXLPF_RC 0x93
+#define RADIO_2056_RX_STATUS_HPC_RC 0x94
+
+#define RADIO_2056_LNA1_A_PU 0x01
+#define RADIO_2056_LNA2_A_PU 0x02
+#define RADIO_2056_LNA1_G_PU 0x01
+#define RADIO_2056_LNA2_G_PU 0x02
+#define RADIO_2056_MIXA_PU_I 0x01
+#define RADIO_2056_MIXA_PU_Q 0x02
+#define RADIO_2056_MIXA_PU_GM 0x10
+#define RADIO_2056_MIXG_PU_I 0x01
+#define RADIO_2056_MIXG_PU_Q 0x02
+#define RADIO_2056_MIXG_PU_GM 0x10
+#define RADIO_2056_TIA_PU 0x01
+#define RADIO_2056_BB_LPF_PU 0x20
+#define RADIO_2056_W1_PU 0x02
+#define RADIO_2056_W2_PU 0x04
+#define RADIO_2056_NB_PU 0x08
+#define RADIO_2056_RSSI_W1_SEL 0x02
+#define RADIO_2056_RSSI_W2_SEL 0x04
+#define RADIO_2056_RSSI_NB_SEL 0x08
+#define RADIO_2056_VCM_MASK 0x1c
+#define RADIO_2056_RSSI_VCM_SHIFT 0x02
+
+#define RADIO_2057_DACBUF_VINCM_CORE0 0x0
+#define RADIO_2057_IDCODE 0x1
+#define RADIO_2057_RCCAL_MASTER 0x2
+#define RADIO_2057_RCCAL_CAP_SIZE 0x3
+#define RADIO_2057_RCAL_CONFIG 0x4
+#define RADIO_2057_GPAIO_CONFIG 0x5
+#define RADIO_2057_GPAIO_SEL1 0x6
+#define RADIO_2057_GPAIO_SEL0 0x7
+#define RADIO_2057_CLPO_CONFIG 0x8
+#define RADIO_2057_BANDGAP_CONFIG 0x9
+#define RADIO_2057_BANDGAP_RCAL_TRIM 0xa
+#define RADIO_2057_AFEREG_CONFIG 0xb
+#define RADIO_2057_TEMPSENSE_CONFIG 0xc
+#define RADIO_2057_XTAL_CONFIG1 0xd
+#define RADIO_2057_XTAL_ICORE_SIZE 0xe
+#define RADIO_2057_XTAL_BUF_SIZE 0xf
+#define RADIO_2057_XTAL_PULLCAP_SIZE 0x10
+#define RADIO_2057_RFPLL_MASTER 0x11
+#define RADIO_2057_VCOMONITOR_VTH_L 0x12
+#define RADIO_2057_VCOMONITOR_VTH_H 0x13
+#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
+#define RADIO_2057_VCO_VARCSIZE_IDAC 0x15
+#define RADIO_2057_VCOCAL_COUNTVAL0 0x16
+#define RADIO_2057_VCOCAL_COUNTVAL1 0x17
+#define RADIO_2057_VCOCAL_INTCLK_COUNT 0x18
+#define RADIO_2057_VCOCAL_MASTER 0x19
+#define RADIO_2057_VCOCAL_NUMCAPCHANGE 0x1a
+#define RADIO_2057_VCOCAL_WINSIZE 0x1b
+#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH 0x1c
+#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x1d
+#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x1e
+#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x1f
+#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1 0x20
+#define RADIO_2057_VCO_FORCECAP0 0x21
+#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
+#define RADIO_2057_RFPLL_PFD_RESET_PW 0x23
+#define RADIO_2057_RFPLL_LOOPFILTER_R2 0x24
+#define RADIO_2057_RFPLL_LOOPFILTER_R1 0x25
+#define RADIO_2057_RFPLL_LOOPFILTER_C3 0x26
+#define RADIO_2057_RFPLL_LOOPFILTER_C2 0x27
+#define RADIO_2057_RFPLL_LOOPFILTER_C1 0x28
+#define RADIO_2057_CP_KPD_IDAC 0x29
+#define RADIO_2057_RFPLL_IDACS 0x2a
+#define RADIO_2057_RFPLL_MISC_EN 0x2b
+#define RADIO_2057_RFPLL_MMD0 0x2c
+#define RADIO_2057_RFPLL_MMD1 0x2d
+#define RADIO_2057_RFPLL_MISC_CAL_RESETN 0x2e
+#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x2f
+#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x30
+#define RADIO_2057_VCOCAL_READCAP0 0x31
+#define RADIO_2057_VCOCAL_READCAP1 0x32
+#define RADIO_2057_VCOCAL_STATUS 0x33
+#define RADIO_2057_LOGEN_PUS 0x34
+#define RADIO_2057_LOGEN_PTAT_RESETS 0x35
+#define RADIO_2057_VCOBUF_IDACS 0x36
+#define RADIO_2057_VCOBUF_TUNE 0x37
+#define RADIO_2057_CMOSBUF_TX2GQ_IDACS 0x38
+#define RADIO_2057_CMOSBUF_TX2GI_IDACS 0x39
+#define RADIO_2057_CMOSBUF_TX5GQ_IDACS 0x3a
+#define RADIO_2057_CMOSBUF_TX5GI_IDACS 0x3b
+#define RADIO_2057_CMOSBUF_RX2GQ_IDACS 0x3c
+#define RADIO_2057_CMOSBUF_RX2GI_IDACS 0x3d
+#define RADIO_2057_CMOSBUF_RX5GQ_IDACS 0x3e
+#define RADIO_2057_CMOSBUF_RX5GI_IDACS 0x3f
+#define RADIO_2057_LOGEN_MX2G_IDACS 0x40
+#define RADIO_2057_LOGEN_MX2G_TUNE 0x41
+#define RADIO_2057_LOGEN_MX5G_IDACS 0x42
+#define RADIO_2057_LOGEN_MX5G_TUNE 0x43
+#define RADIO_2057_LOGEN_MX5G_RCCR 0x44
+#define RADIO_2057_LOGEN_INDBUF2G_IDAC 0x45
+#define RADIO_2057_LOGEN_INDBUF2G_IBOOST 0x46
+#define RADIO_2057_LOGEN_INDBUF2G_TUNE 0x47
+#define RADIO_2057_LOGEN_INDBUF5G_IDAC 0x48
+#define RADIO_2057_LOGEN_INDBUF5G_IBOOST 0x49
+#define RADIO_2057_LOGEN_INDBUF5G_TUNE 0x4a
+#define RADIO_2057_CMOSBUF_TX_RCCR 0x4b
+#define RADIO_2057_CMOSBUF_RX_RCCR 0x4c
+#define RADIO_2057_LOGEN_SEL_PKDET 0x4d
+#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT 0x4e
+#define RADIO_2057_RXTXBIAS_CONFIG_CORE0 0x4f
+#define RADIO_2057_TXGM_TXRF_PUS_CORE0 0x50
+#define RADIO_2057_TXGM_IDAC_BLEED_CORE0 0x51
+#define RADIO_2057_TXGM_GAIN_CORE0 0x56
+#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0 0x57
+#define RADIO_2057_PAD2G_PTATS_CORE0 0x58
+#define RADIO_2057_PAD2G_IDACS_CORE0 0x59
+#define RADIO_2057_PAD2G_BOOST_PU_CORE0 0x5a
+#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0 0x5b
+#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x5c
+#define RADIO_2057_TXMIX2G_LODC_CORE0 0x5d
+#define RADIO_2057_PAD2G_TUNE_PUS_CORE0 0x5e
+#define RADIO_2057_IPA2G_GAIN_CORE0 0x5f
+#define RADIO_2057_TSSI2G_SPARE1_CORE0 0x60
+#define RADIO_2057_TSSI2G_SPARE2_CORE0 0x61
+#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x62
+#define RADIO_2057_IPA2G_IMAIN_CORE0 0x63
+#define RADIO_2057_IPA2G_CASCONV_CORE0 0x64
+#define RADIO_2057_IPA2G_CASCOFFV_CORE0 0x65
+#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0 0x66
+#define RADIO_2057_TX5G_PKDET_CORE0 0x69
+#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0 0x6a
+#define RADIO_2057_PAD5G_PTATS1_CORE0 0x6b
+#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0 0x6c
+#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x6d
+#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0 0x6e
+#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
+#define RADIO_2057_PGA_BOOST_TUNE_CORE0 0x70
+#define RADIO_2057_PGA_GAIN_CORE0 0x71
+#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
+#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0 0x73
+#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0 0x74
+#define RADIO_2057_IPA5G_IAUX_CORE0 0x75
+#define RADIO_2057_IPA5G_GAIN_CORE0 0x76
+#define RADIO_2057_TSSI5G_SPARE1_CORE0 0x77
+#define RADIO_2057_TSSI5G_SPARE2_CORE0 0x78
+#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0 0x79
+#define RADIO_2057_IPA5G_PTAT_CORE0 0x7a
+#define RADIO_2057_IPA5G_IMAIN_CORE0 0x7b
+#define RADIO_2057_IPA5G_CASCONV_CORE0 0x7c
+#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0 0x7d
+#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0 0x80
+#define RADIO_2057_TR2G_CONFIG1_CORE0_NU 0x81
+#define RADIO_2057_TR2G_CONFIG2_CORE0_NU 0x82
+#define RADIO_2057_LNA5G_RFEN_CORE0 0x83
+#define RADIO_2057_TR5G_CONFIG2_CORE0_NU 0x84
+#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0 0x85
+#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
+#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x87
+#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x88
+#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0 0x89
+#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0 0x8a
+#define RADIO_2057_LNA2_IAUX_PTAT_CORE0 0x8b
+#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0 0x8c
+#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
+#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0 0x8e
+#define RADIO_2057_TIA_CONFIG_CORE0 0x8f
+#define RADIO_2057_TIA_IQGAIN_CORE0 0x90
+#define RADIO_2057_TIA_IBIAS2_CORE0 0x91
+#define RADIO_2057_TIA_IBIAS1_CORE0 0x92
+#define RADIO_2057_TIA_SPARE_Q_CORE0 0x93
+#define RADIO_2057_TIA_SPARE_I_CORE0 0x94
+#define RADIO_2057_RXMIX2G_PUS_CORE0 0x95
+#define RADIO_2057_RXMIX2G_VCMREFS_CORE0 0x96
+#define RADIO_2057_RXMIX2G_LODC_QI_CORE0 0x97
+#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0 0x98
+#define RADIO_2057_LNA2G_GAIN_CORE0 0x99
+#define RADIO_2057_LNA2G_TUNE_CORE0 0x9a
+#define RADIO_2057_RXMIX5G_PUS_CORE0 0x9b
+#define RADIO_2057_RXMIX5G_VCMREFS_CORE0 0x9c
+#define RADIO_2057_RXMIX5G_LODC_QI_CORE0 0x9d
+#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0 0x9e
+#define RADIO_2057_LNA5G_GAIN_CORE0 0x9f
+#define RADIO_2057_LNA5G_TUNE_CORE0 0xa0
+#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0xa1
+#define RADIO_2057_RXBB_BIAS_MASTER_CORE0 0xa2
+#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0 0xa3
+#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
+#define RADIO_2057_TXBUF_VINCM_CORE0 0xa5
+#define RADIO_2057_TXBUF_IDACS_CORE0 0xa6
+#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0 0xa7
+#define RADIO_2057_RXBB_CC_CORE0 0xa8
+#define RADIO_2057_RXBB_SPARE3_CORE0 0xa9
+#define RADIO_2057_RXBB_RCCAL_HPC_CORE0 0xaa
+#define RADIO_2057_LPF_IDACS_CORE0 0xab
+#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0xac
+#define RADIO_2057_TXBUF_GAIN_CORE0 0xad
+#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0 0xae
+#define RADIO_2057_RXBUF_DEGEN_CORE0 0xaf
+#define RADIO_2057_RXBB_SPARE2_CORE0 0xb0
+#define RADIO_2057_RXBB_SPARE1_CORE0 0xb1
+#define RADIO_2057_RSSI_MASTER_CORE0 0xb2
+#define RADIO_2057_W2_MASTER_CORE0 0xb3
+#define RADIO_2057_NB_MASTER_CORE0 0xb4
+#define RADIO_2057_W2_IDACS0_Q_CORE0 0xb5
+#define RADIO_2057_W2_IDACS1_Q_CORE0 0xb6
+#define RADIO_2057_W2_IDACS0_I_CORE0 0xb7
+#define RADIO_2057_W2_IDACS1_I_CORE0 0xb8
+#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0xb9
+#define RADIO_2057_NB_IDACS_Q_CORE0 0xba
+#define RADIO_2057_NB_IDACS_I_CORE0 0xbb
+#define RADIO_2057_BACKUP4_CORE0 0xc1
+#define RADIO_2057_BACKUP3_CORE0 0xc2
+#define RADIO_2057_BACKUP2_CORE0 0xc3
+#define RADIO_2057_BACKUP1_CORE0 0xc4
+#define RADIO_2057_SPARE16_CORE0 0xc5
+#define RADIO_2057_SPARE15_CORE0 0xc6
+#define RADIO_2057_SPARE14_CORE0 0xc7
+#define RADIO_2057_SPARE13_CORE0 0xc8
+#define RADIO_2057_SPARE12_CORE0 0xc9
+#define RADIO_2057_SPARE11_CORE0 0xca
+#define RADIO_2057_TX2G_BIAS_RESETS_CORE0 0xcb
+#define RADIO_2057_TX5G_BIAS_RESETS_CORE0 0xcc
+#define RADIO_2057_IQTEST_SEL_PU 0xcd
+#define RADIO_2057_XTAL_CONFIG2 0xce
+#define RADIO_2057_BUFS_MISC_LPFBW_CORE0 0xcf
+#define RADIO_2057_TXLPF_RCCAL_CORE0 0xd0
+#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
+#define RADIO_2057_LPF_GAIN_CORE0 0xd2
+#define RADIO_2057_DACBUF_IDACS_BW_CORE0 0xd3
+#define RADIO_2057_RXTXBIAS_CONFIG_CORE1 0xd4
+#define RADIO_2057_TXGM_TXRF_PUS_CORE1 0xd5
+#define RADIO_2057_TXGM_IDAC_BLEED_CORE1 0xd6
+#define RADIO_2057_TXGM_GAIN_CORE1 0xdb
+#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1 0xdc
+#define RADIO_2057_PAD2G_PTATS_CORE1 0xdd
+#define RADIO_2057_PAD2G_IDACS_CORE1 0xde
+#define RADIO_2057_PAD2G_BOOST_PU_CORE1 0xdf
+#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1 0xe0
+#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0xe1
+#define RADIO_2057_TXMIX2G_LODC_CORE1 0xe2
+#define RADIO_2057_PAD2G_TUNE_PUS_CORE1 0xe3
+#define RADIO_2057_IPA2G_GAIN_CORE1 0xe4
+#define RADIO_2057_TSSI2G_SPARE1_CORE1 0xe5
+#define RADIO_2057_TSSI2G_SPARE2_CORE1 0xe6
+#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0xe7
+#define RADIO_2057_IPA2G_IMAIN_CORE1 0xe8
+#define RADIO_2057_IPA2G_CASCONV_CORE1 0xe9
+#define RADIO_2057_IPA2G_CASCOFFV_CORE1 0xea
+#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1 0xeb
+#define RADIO_2057_TX5G_PKDET_CORE1 0xee
+#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1 0xef
+#define RADIO_2057_PAD5G_PTATS1_CORE1 0xf0
+#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1 0xf1
+#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1 0xf2
+#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1 0xf3
+#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
+#define RADIO_2057_PGA_BOOST_TUNE_CORE1 0xf5
+#define RADIO_2057_PGA_GAIN_CORE1 0xf6
+#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
+#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1 0xf8
+#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1 0xf9
+#define RADIO_2057_IPA5G_IAUX_CORE1 0xfa
+#define RADIO_2057_IPA5G_GAIN_CORE1 0xfb
+#define RADIO_2057_TSSI5G_SPARE1_CORE1 0xfc
+#define RADIO_2057_TSSI5G_SPARE2_CORE1 0xfd
+#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1 0xfe
+#define RADIO_2057_IPA5G_PTAT_CORE1 0xff
+#define RADIO_2057_IPA5G_IMAIN_CORE1 0x100
+#define RADIO_2057_IPA5G_CASCONV_CORE1 0x101
+#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1 0x102
+#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1 0x105
+#define RADIO_2057_TR2G_CONFIG1_CORE1_NU 0x106
+#define RADIO_2057_TR2G_CONFIG2_CORE1_NU 0x107
+#define RADIO_2057_LNA5G_RFEN_CORE1 0x108
+#define RADIO_2057_TR5G_CONFIG2_CORE1_NU 0x109
+#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a
+#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
+#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c
+#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d
+#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e
+#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f
+#define RADIO_2057_LNA2_IAUX_PTAT_CORE1 0x110
+#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111
+#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
+#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1 0x113
+#define RADIO_2057_TIA_CONFIG_CORE1 0x114
+#define RADIO_2057_TIA_IQGAIN_CORE1 0x115
+#define RADIO_2057_TIA_IBIAS2_CORE1 0x116
+#define RADIO_2057_TIA_IBIAS1_CORE1 0x117
+#define RADIO_2057_TIA_SPARE_Q_CORE1 0x118
+#define RADIO_2057_TIA_SPARE_I_CORE1 0x119
+#define RADIO_2057_RXMIX2G_PUS_CORE1 0x11a
+#define RADIO_2057_RXMIX2G_VCMREFS_CORE1 0x11b
+#define RADIO_2057_RXMIX2G_LODC_QI_CORE1 0x11c
+#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1 0x11d
+#define RADIO_2057_LNA2G_GAIN_CORE1 0x11e
+#define RADIO_2057_LNA2G_TUNE_CORE1 0x11f
+#define RADIO_2057_RXMIX5G_PUS_CORE1 0x120
+#define RADIO_2057_RXMIX5G_VCMREFS_CORE1 0x121
+#define RADIO_2057_RXMIX5G_LODC_QI_CORE1 0x122
+#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1 0x123
+#define RADIO_2057_LNA5G_GAIN_CORE1 0x124
+#define RADIO_2057_LNA5G_TUNE_CORE1 0x125
+#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126
+#define RADIO_2057_RXBB_BIAS_MASTER_CORE1 0x127
+#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1 0x128
+#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
+#define RADIO_2057_TXBUF_VINCM_CORE1 0x12a
+#define RADIO_2057_TXBUF_IDACS_CORE1 0x12b
+#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1 0x12c
+#define RADIO_2057_RXBB_CC_CORE1 0x12d
+#define RADIO_2057_RXBB_SPARE3_CORE1 0x12e
+#define RADIO_2057_RXBB_RCCAL_HPC_CORE1 0x12f
+#define RADIO_2057_LPF_IDACS_CORE1 0x130
+#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131
+#define RADIO_2057_TXBUF_GAIN_CORE1 0x132
+#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1 0x133
+#define RADIO_2057_RXBUF_DEGEN_CORE1 0x134
+#define RADIO_2057_RXBB_SPARE2_CORE1 0x135
+#define RADIO_2057_RXBB_SPARE1_CORE1 0x136
+#define RADIO_2057_RSSI_MASTER_CORE1 0x137
+#define RADIO_2057_W2_MASTER_CORE1 0x138
+#define RADIO_2057_NB_MASTER_CORE1 0x139
+#define RADIO_2057_W2_IDACS0_Q_CORE1 0x13a
+#define RADIO_2057_W2_IDACS1_Q_CORE1 0x13b
+#define RADIO_2057_W2_IDACS0_I_CORE1 0x13c
+#define RADIO_2057_W2_IDACS1_I_CORE1 0x13d
+#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e
+#define RADIO_2057_NB_IDACS_Q_CORE1 0x13f
+#define RADIO_2057_NB_IDACS_I_CORE1 0x140
+#define RADIO_2057_BACKUP4_CORE1 0x146
+#define RADIO_2057_BACKUP3_CORE1 0x147
+#define RADIO_2057_BACKUP2_CORE1 0x148
+#define RADIO_2057_BACKUP1_CORE1 0x149
+#define RADIO_2057_SPARE16_CORE1 0x14a
+#define RADIO_2057_SPARE15_CORE1 0x14b
+#define RADIO_2057_SPARE14_CORE1 0x14c
+#define RADIO_2057_SPARE13_CORE1 0x14d
+#define RADIO_2057_SPARE12_CORE1 0x14e
+#define RADIO_2057_SPARE11_CORE1 0x14f
+#define RADIO_2057_TX2G_BIAS_RESETS_CORE1 0x150
+#define RADIO_2057_TX5G_BIAS_RESETS_CORE1 0x151
+#define RADIO_2057_SPARE8_CORE1 0x152
+#define RADIO_2057_SPARE7_CORE1 0x153
+#define RADIO_2057_BUFS_MISC_LPFBW_CORE1 0x154
+#define RADIO_2057_TXLPF_RCCAL_CORE1 0x155
+#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
+#define RADIO_2057_LPF_GAIN_CORE1 0x157
+#define RADIO_2057_DACBUF_IDACS_BW_CORE1 0x158
+#define RADIO_2057_DACBUF_VINCM_CORE1 0x159
+#define RADIO_2057_RCCAL_START_R1_Q1_P1 0x15a
+#define RADIO_2057_RCCAL_X1 0x15b
+#define RADIO_2057_RCCAL_TRC0 0x15c
+#define RADIO_2057_RCCAL_TRC1 0x15d
+#define RADIO_2057_RCCAL_DONE_OSCCAP 0x15e
+#define RADIO_2057_RCCAL_N0_0 0x15f
+#define RADIO_2057_RCCAL_N0_1 0x160
+#define RADIO_2057_RCCAL_N1_0 0x161
+#define RADIO_2057_RCCAL_N1_1 0x162
+#define RADIO_2057_RCAL_STATUS 0x163
+#define RADIO_2057_XTALPUOVR_PINCTRL 0x164
+#define RADIO_2057_OVR_REG0 0x165
+#define RADIO_2057_OVR_REG1 0x166
+#define RADIO_2057_OVR_REG2 0x167
+#define RADIO_2057_OVR_REG3 0x168
+#define RADIO_2057_OVR_REG4 0x169
+#define RADIO_2057_RCCAL_SCAP_VAL 0x16a
+#define RADIO_2057_RCCAL_BCAP_VAL 0x16b
+#define RADIO_2057_RCCAL_HPC_VAL 0x16c
+#define RADIO_2057_RCCAL_OVERRIDES 0x16d
+#define RADIO_2057_TX0_IQCAL_GAIN_BW 0x170
+#define RADIO_2057_TX0_LOFT_FINE_I 0x171
+#define RADIO_2057_TX0_LOFT_FINE_Q 0x172
+#define RADIO_2057_TX0_LOFT_COARSE_I 0x173
+#define RADIO_2057_TX0_LOFT_COARSE_Q 0x174
+#define RADIO_2057_TX0_TX_SSI_MASTER 0x175
+#define RADIO_2057_TX0_IQCAL_VCM_HG 0x176
+#define RADIO_2057_TX0_IQCAL_IDAC 0x177
+#define RADIO_2057_TX0_TSSI_VCM 0x178
+#define RADIO_2057_TX0_TX_SSI_MUX 0x179
+#define RADIO_2057_TX0_TSSIA 0x17a
+#define RADIO_2057_TX0_TSSIG 0x17b
+#define RADIO_2057_TX0_TSSI_MISC1 0x17c
+#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d
+#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
+#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
+#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
+#define RADIO_2057_TX1_IQCAL_GAIN_BW 0x190
+#define RADIO_2057_TX1_LOFT_FINE_I 0x191
+#define RADIO_2057_TX1_LOFT_FINE_Q 0x192
+#define RADIO_2057_TX1_LOFT_COARSE_I 0x193
+#define RADIO_2057_TX1_LOFT_COARSE_Q 0x194
+#define RADIO_2057_TX1_TX_SSI_MASTER 0x195
+#define RADIO_2057_TX1_IQCAL_VCM_HG 0x196
+#define RADIO_2057_TX1_IQCAL_IDAC 0x197
+#define RADIO_2057_TX1_TSSI_VCM 0x198
+#define RADIO_2057_TX1_TX_SSI_MUX 0x199
+#define RADIO_2057_TX1_TSSIA 0x19a
+#define RADIO_2057_TX1_TSSIG 0x19b
+#define RADIO_2057_TX1_TSSI_MISC1 0x19c
+#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d
+#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
+#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
+#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
+#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
+#define RADIO_2057_AFE_SET_VCM_I_CORE0 0x1a2
+#define RADIO_2057_AFE_SET_VCM_Q_CORE0 0x1a3
+#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4
+#define RADIO_2057_AFE_STATUS_VCM_I_CORE0 0x1a5
+#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0 0x1a6
+#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7
+#define RADIO_2057_AFE_SET_VCM_I_CORE1 0x1a8
+#define RADIO_2057_AFE_SET_VCM_Q_CORE1 0x1a9
+#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa
+#define RADIO_2057_AFE_STATUS_VCM_I_CORE1 0x1ab
+#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1 0x1ac
+
+#define RADIO_2057v7_DACBUF_VINCM_CORE0 0x1ad
+#define RADIO_2057v7_RCCAL_MASTER 0x1ae
+#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU 0x1af
+#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0
+#define RADIO_2057v7_LOGEN_PUS1 0x1b1
+#define RADIO_2057v7_OVR_REG5 0x1b2
+#define RADIO_2057v7_OVR_REG6 0x1b3
+#define RADIO_2057v7_OVR_REG7 0x1b4
+#define RADIO_2057v7_OVR_REG8 0x1b5
+#define RADIO_2057v7_OVR_REG9 0x1b6
+#define RADIO_2057v7_OVR_REG10 0x1b7
+#define RADIO_2057v7_OVR_REG11 0x1b8
+#define RADIO_2057v7_OVR_REG12 0x1b9
+#define RADIO_2057v7_OVR_REG13 0x1ba
+#define RADIO_2057v7_OVR_REG14 0x1bb
+#define RADIO_2057v7_OVR_REG15 0x1bc
+#define RADIO_2057v7_OVR_REG16 0x1bd
+#define RADIO_2057v7_OVR_REG1 0x1be
+#define RADIO_2057v7_OVR_REG18 0x1bf
+#define RADIO_2057v7_OVR_REG19 0x1c0
+#define RADIO_2057v7_OVR_REG20 0x1c1
+#define RADIO_2057v7_OVR_REG21 0x1c2
+#define RADIO_2057v7_OVR_REG2 0x1c3
+#define RADIO_2057v7_OVR_REG23 0x1c4
+#define RADIO_2057v7_OVR_REG24 0x1c5
+#define RADIO_2057v7_OVR_REG25 0x1c6
+#define RADIO_2057v7_OVR_REG26 0x1c7
+#define RADIO_2057v7_OVR_REG27 0x1c8
+#define RADIO_2057v7_OVR_REG28 0x1c9
+#define RADIO_2057v7_IQTEST_SEL_PU2 0x1ca
+
+#define RADIO_2057_VCM_MASK 0x7
+
+#endif /* _BCM20XX_H */
diff --git a/drivers/staging/brcm80211/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/phy/wlc_phyreg_n.h
new file mode 100644
index 000000000000..211bc3a842af
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phyreg_n.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+#define NPHY_TBL_ID_GAIN1 0
+#define NPHY_TBL_ID_GAIN2 1
+#define NPHY_TBL_ID_GAINBITS1 2
+#define NPHY_TBL_ID_GAINBITS2 3
+#define NPHY_TBL_ID_GAINLIMIT 4
+#define NPHY_TBL_ID_WRSSIGainLimit 5
+#define NPHY_TBL_ID_RFSEQ 7
+#define NPHY_TBL_ID_AFECTRL 8
+#define NPHY_TBL_ID_ANTSWCTRLLUT 9
+#define NPHY_TBL_ID_IQLOCAL 15
+#define NPHY_TBL_ID_NOISEVAR 16
+#define NPHY_TBL_ID_SAMPLEPLAY 17
+#define NPHY_TBL_ID_CORE1TXPWRCTL 26
+#define NPHY_TBL_ID_CORE2TXPWRCTL 27
+#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
+
+#define NPHY_TBL_ID_EPSILONTBL0 31
+#define NPHY_TBL_ID_SCALARTBL0 32
+#define NPHY_TBL_ID_EPSILONTBL1 33
+#define NPHY_TBL_ID_SCALARTBL1 34
+
+#define NPHY_TO_BPHY_OFF 0xc00
+
+#define NPHY_BandControl_currentBand 0x0001
+#define RFCC_CHIP0_PU 0x0400
+#define RFCC_POR_FORCE 0x0040
+#define RFCC_OE_POR_FORCE 0x0080
+#define NPHY_RfctrlIntc_override_OFF 0
+#define NPHY_RfctrlIntc_override_TRSW 1
+#define NPHY_RfctrlIntc_override_PA 2
+#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
+#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
+#define RIFS_ENABLE 0x80
+#define BPHY_BAND_SEL_UP20 0x10
+#define NPHY_MLenable 0x02
+
+#define NPHY_RfseqMode_CoreActv_override 0x0001
+#define NPHY_RfseqMode_Trigger_override 0x0002
+#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
+#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
+
+#define NPHY_RfseqTrigger_rx2tx 0x0001
+#define NPHY_RfseqTrigger_tx2rx 0x0002
+#define NPHY_RfseqTrigger_updategainh 0x0004
+#define NPHY_RfseqTrigger_updategainl 0x0008
+#define NPHY_RfseqTrigger_updategainu 0x0010
+#define NPHY_RfseqTrigger_reset2rx 0x0020
+#define NPHY_RfseqStatus_rx2tx 0x0001
+#define NPHY_RfseqStatus_tx2rx 0x0002
+#define NPHY_RfseqStatus_updategainh 0x0004
+#define NPHY_RfseqStatus_updategainl 0x0008
+#define NPHY_RfseqStatus_updategainu 0x0010
+#define NPHY_RfseqStatus_reset2rx 0x0020
+#define NPHY_ClassifierCtrl_cck_en 0x1
+#define NPHY_ClassifierCtrl_ofdm_en 0x2
+#define NPHY_ClassifierCtrl_waited_en 0x4
+#define NPHY_IQFlip_ADC1 0x0001
+#define NPHY_IQFlip_ADC2 0x0010
+#define NPHY_sampleCmd_STOP 0x0002
+
+#define RX_GF_OR_MM 0x0004
+#define RX_GF_MM_AUTO 0x0100
+
+#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
+
+#define NPHY_IqestCmd_iqstart 0x1
+#define NPHY_IqestCmd_iqMode 0x2
+
+#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
+#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
+
+#define PRIM_SEL_UP20 0x8000
+
+#define NPHY_RFSEQ_RX2TX 0x0
+#define NPHY_RFSEQ_TX2RX 0x1
+#define NPHY_RFSEQ_RESET2RX 0x2
+#define NPHY_RFSEQ_UPDATEGAINH 0x3
+#define NPHY_RFSEQ_UPDATEGAINL 0x4
+#define NPHY_RFSEQ_UPDATEGAINU 0x5
+
+#define NPHY_RFSEQ_CMD_NOP 0x0
+#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
+#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
+#define NPHY_RFSEQ_CMD_EXT_PA 0x3
+#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
+#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
+#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
+#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
+#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
+#define NPHY_RFSEQ_CMD_END 0xf
+
+#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
+#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
+#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
+#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
+#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
+#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
+#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
+#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
+#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
+#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
+#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
+#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
+#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
+#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
+#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
+#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
+#define NPHY_REV3_RFSEQ_CMD_END 0x1f
+
+#define NPHY_RSSI_SEL_W1 0x0
+#define NPHY_RSSI_SEL_W2 0x1
+#define NPHY_RSSI_SEL_NB 0x2
+#define NPHY_RSSI_SEL_IQ 0x3
+#define NPHY_RSSI_SEL_TSSI_2G 0x4
+#define NPHY_RSSI_SEL_TSSI_5G 0x5
+#define NPHY_RSSI_SEL_TBD 0x6
+
+#define NPHY_RAIL_I 0x0
+#define NPHY_RAIL_Q 0x1
+
+#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
+
+#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
+#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
+#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
+#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
+#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
+
+#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
+#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
+#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
+
+#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
+#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
+#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
+
+#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
+#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
+#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
+
+#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
+
+#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
+
+#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
+
+#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
+
+#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
+
+#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c
new file mode 100644
index 000000000000..adfb97b9aa5f
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c
@@ -0,0 +1,3639 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+
+#include <wlc_phy_int.h>
+#include <wlc_phytbl_lcn.h>
+
+CONST uint32 dot11lcn_gain_tbl_rev0[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000004,
+ 0x00000000,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000d,
+ 0x0000004d,
+ 0x0000008d,
+ 0x0000000d,
+ 0x0000004d,
+ 0x0000008d,
+ 0x000000cd,
+ 0x0000004f,
+ 0x0000008f,
+ 0x000000cf,
+ 0x000000d3,
+ 0x00000113,
+ 0x00000513,
+ 0x00000913,
+ 0x00000953,
+ 0x00000d53,
+ 0x00001153,
+ 0x00001193,
+ 0x00005193,
+ 0x00009193,
+ 0x0000d193,
+ 0x00011193,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000004,
+ 0x00000000,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000d,
+ 0x0000004d,
+ 0x0000008d,
+ 0x0000000d,
+ 0x0000004d,
+ 0x0000008d,
+ 0x000000cd,
+ 0x0000004f,
+ 0x0000008f,
+ 0x000000cf,
+ 0x000000d3,
+ 0x00000113,
+ 0x00000513,
+ 0x00000913,
+ 0x00000953,
+ 0x00000d53,
+ 0x00001153,
+ 0x00005153,
+ 0x00009153,
+ 0x0000d153,
+ 0x00011153,
+ 0x00015153,
+ 0x00019153,
+ 0x0001d153,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 dot11lcn_gain_tbl_rev1[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000008,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000D,
+ 0x00000011,
+ 0x00000051,
+ 0x00000091,
+ 0x00000011,
+ 0x00000051,
+ 0x00000091,
+ 0x000000d1,
+ 0x00000053,
+ 0x00000093,
+ 0x000000d3,
+ 0x000000d7,
+ 0x00000117,
+ 0x00000517,
+ 0x00000917,
+ 0x00000957,
+ 0x00000d57,
+ 0x00001157,
+ 0x00001197,
+ 0x00005197,
+ 0x00009197,
+ 0x0000d197,
+ 0x00011197,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000008,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000D,
+ 0x00000011,
+ 0x00000051,
+ 0x00000091,
+ 0x00000011,
+ 0x00000051,
+ 0x00000091,
+ 0x000000d1,
+ 0x00000053,
+ 0x00000093,
+ 0x000000d3,
+ 0x000000d7,
+ 0x00000117,
+ 0x00000517,
+ 0x00000917,
+ 0x00000957,
+ 0x00000d57,
+ 0x00001157,
+ 0x00005157,
+ 0x00009157,
+ 0x0000d157,
+ 0x00011157,
+ 0x00015157,
+ 0x00019157,
+ 0x0001d157,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
+ 0x0401,
+ 0x0402,
+ 0x0403,
+ 0x0404,
+ 0x0405,
+ 0x0406,
+ 0x0407,
+ 0x0408,
+ 0x0409,
+ 0x040a,
+ 0x058b,
+ 0x058c,
+ 0x058d,
+ 0x058e,
+ 0x058f,
+ 0x0090,
+ 0x0091,
+ 0x0092,
+ 0x0193,
+ 0x0194,
+ 0x0195,
+ 0x0196,
+ 0x0197,
+ 0x0198,
+ 0x0199,
+ 0x019a,
+ 0x019b,
+ 0x019c,
+ 0x019d,
+ 0x019e,
+ 0x019f,
+ 0x01a0,
+ 0x01a1,
+ 0x01a2,
+ 0x01a3,
+ 0x01a4,
+ 0x01a5,
+ 0x0000,
+};
+
+CONST uint32 dot11lcn_gain_idx_tbl_rev0[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x10000000,
+ 0x00000000,
+ 0x20000000,
+ 0x00000000,
+ 0x30000000,
+ 0x00000000,
+ 0x40000000,
+ 0x00000000,
+ 0x50000000,
+ 0x00000000,
+ 0x60000000,
+ 0x00000000,
+ 0x70000000,
+ 0x00000000,
+ 0x80000000,
+ 0x00000000,
+ 0x90000000,
+ 0x00000008,
+ 0xa0000000,
+ 0x00000008,
+ 0xb0000000,
+ 0x00000008,
+ 0xc0000000,
+ 0x00000008,
+ 0xd0000000,
+ 0x00000008,
+ 0xe0000000,
+ 0x00000008,
+ 0xf0000000,
+ 0x00000008,
+ 0x00000000,
+ 0x00000009,
+ 0x10000000,
+ 0x00000009,
+ 0x20000000,
+ 0x00000019,
+ 0x30000000,
+ 0x00000019,
+ 0x40000000,
+ 0x00000019,
+ 0x50000000,
+ 0x00000019,
+ 0x60000000,
+ 0x00000019,
+ 0x70000000,
+ 0x00000019,
+ 0x80000000,
+ 0x00000019,
+ 0x90000000,
+ 0x00000019,
+ 0xa0000000,
+ 0x00000019,
+ 0xb0000000,
+ 0x00000019,
+ 0xc0000000,
+ 0x00000019,
+ 0xd0000000,
+ 0x00000019,
+ 0xe0000000,
+ 0x00000019,
+ 0xf0000000,
+ 0x00000019,
+ 0x00000000,
+ 0x0000001a,
+ 0x10000000,
+ 0x0000001a,
+ 0x20000000,
+ 0x0000001a,
+ 0x30000000,
+ 0x0000001a,
+ 0x40000000,
+ 0x0000001a,
+ 0x50000000,
+ 0x00000002,
+ 0x60000000,
+ 0x00000002,
+ 0x70000000,
+ 0x00000002,
+ 0x80000000,
+ 0x00000002,
+ 0x90000000,
+ 0x00000002,
+ 0xa0000000,
+ 0x00000002,
+ 0xb0000000,
+ 0x00000002,
+ 0xc0000000,
+ 0x0000000a,
+ 0xd0000000,
+ 0x0000000a,
+ 0xe0000000,
+ 0x0000000a,
+ 0xf0000000,
+ 0x0000000a,
+ 0x00000000,
+ 0x0000000b,
+ 0x10000000,
+ 0x0000000b,
+ 0x20000000,
+ 0x0000000b,
+ 0x30000000,
+ 0x0000000b,
+ 0x40000000,
+ 0x0000000b,
+ 0x50000000,
+ 0x0000001b,
+ 0x60000000,
+ 0x0000001b,
+ 0x70000000,
+ 0x0000001b,
+ 0x80000000,
+ 0x0000001b,
+ 0x90000000,
+ 0x0000001b,
+ 0xa0000000,
+ 0x0000001b,
+ 0xb0000000,
+ 0x0000001b,
+ 0xc0000000,
+ 0x0000001b,
+ 0xd0000000,
+ 0x0000001b,
+ 0xe0000000,
+ 0x0000001b,
+ 0xf0000000,
+ 0x0000001b,
+ 0x00000000,
+ 0x0000001c,
+ 0x10000000,
+ 0x0000001c,
+ 0x20000000,
+ 0x0000001c,
+ 0x30000000,
+ 0x0000001c,
+ 0x40000000,
+ 0x0000001c,
+ 0x50000000,
+ 0x0000001c,
+ 0x60000000,
+ 0x0000001c,
+ 0x70000000,
+ 0x0000001c,
+ 0x80000000,
+ 0x0000001c,
+ 0x90000000,
+ 0x0000001c,
+};
+
+CONST uint16 dot11lcn_aux_gain_idx_tbl_2G[] = {
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0001,
+ 0x0080,
+ 0x0081,
+ 0x0100,
+ 0x0101,
+ 0x0180,
+ 0x0181,
+ 0x0182,
+ 0x0183,
+ 0x0184,
+ 0x0185,
+ 0x0186,
+ 0x0187,
+ 0x0188,
+ 0x0285,
+ 0x0289,
+ 0x028a,
+ 0x028b,
+ 0x028c,
+ 0x028d,
+ 0x028e,
+ 0x028f,
+ 0x0290,
+ 0x0291,
+ 0x0292,
+ 0x0293,
+ 0x0294,
+ 0x0295,
+ 0x0296,
+ 0x0297,
+ 0x0298,
+ 0x0299,
+ 0x029a,
+ 0x0000
+};
+
+CONST uint8 dot11lcn_gain_val_tbl_2G[] = {
+ 0xfc,
+ 0x02,
+ 0x08,
+ 0x0e,
+ 0x13,
+ 0x1b,
+ 0xfc,
+ 0x02,
+ 0x08,
+ 0x0e,
+ 0x13,
+ 0x1b,
+ 0xfc,
+ 0x00,
+ 0x0c,
+ 0x03,
+ 0xeb,
+ 0xfe,
+ 0x07,
+ 0x0b,
+ 0x0f,
+ 0xfb,
+ 0xfe,
+ 0x01,
+ 0x05,
+ 0x08,
+ 0x0b,
+ 0x0e,
+ 0x11,
+ 0x14,
+ 0x17,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x15,
+ 0x18,
+ 0x1b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+CONST uint32 dot11lcn_gain_idx_tbl_2G[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x10000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000008,
+ 0x10000000,
+ 0x00000008,
+ 0x00000000,
+ 0x00000010,
+ 0x10000000,
+ 0x00000010,
+ 0x00000000,
+ 0x00000018,
+ 0x10000000,
+ 0x00000018,
+ 0x20000000,
+ 0x00000018,
+ 0x30000000,
+ 0x00000018,
+ 0x40000000,
+ 0x00000018,
+ 0x50000000,
+ 0x00000018,
+ 0x60000000,
+ 0x00000018,
+ 0x70000000,
+ 0x00000018,
+ 0x80000000,
+ 0x00000018,
+ 0x50000000,
+ 0x00000028,
+ 0x90000000,
+ 0x00000028,
+ 0xa0000000,
+ 0x00000028,
+ 0xb0000000,
+ 0x00000028,
+ 0xc0000000,
+ 0x00000028,
+ 0xd0000000,
+ 0x00000028,
+ 0xe0000000,
+ 0x00000028,
+ 0xf0000000,
+ 0x00000028,
+ 0x00000000,
+ 0x00000029,
+ 0x10000000,
+ 0x00000029,
+ 0x20000000,
+ 0x00000029,
+ 0x30000000,
+ 0x00000029,
+ 0x40000000,
+ 0x00000029,
+ 0x50000000,
+ 0x00000029,
+ 0x60000000,
+ 0x00000029,
+ 0x70000000,
+ 0x00000029,
+ 0x80000000,
+ 0x00000029,
+ 0x90000000,
+ 0x00000029,
+ 0xa0000000,
+ 0x00000029,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x10000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000008,
+ 0x10000000,
+ 0x00000008,
+ 0x00000000,
+ 0x00000010,
+ 0x10000000,
+ 0x00000010,
+ 0x00000000,
+ 0x00000018,
+ 0x10000000,
+ 0x00000018,
+ 0x20000000,
+ 0x00000018,
+ 0x30000000,
+ 0x00000018,
+ 0x40000000,
+ 0x00000018,
+ 0x50000000,
+ 0x00000018,
+ 0x60000000,
+ 0x00000018,
+ 0x70000000,
+ 0x00000018,
+ 0x80000000,
+ 0x00000018,
+ 0x50000000,
+ 0x00000028,
+ 0x90000000,
+ 0x00000028,
+ 0xa0000000,
+ 0x00000028,
+ 0xb0000000,
+ 0x00000028,
+ 0xc0000000,
+ 0x00000028,
+ 0xd0000000,
+ 0x00000028,
+ 0xe0000000,
+ 0x00000028,
+ 0xf0000000,
+ 0x00000028,
+ 0x00000000,
+ 0x00000029,
+ 0x10000000,
+ 0x00000029,
+ 0x20000000,
+ 0x00000029,
+ 0x30000000,
+ 0x00000029,
+ 0x40000000,
+ 0x00000029,
+ 0x50000000,
+ 0x00000029,
+ 0x60000000,
+ 0x00000029,
+ 0x70000000,
+ 0x00000029,
+ 0x80000000,
+ 0x00000029,
+ 0x90000000,
+ 0x00000029,
+ 0xa0000000,
+ 0x00000029,
+ 0xb0000000,
+ 0x00000029,
+ 0xc0000000,
+ 0x00000029,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST uint32 dot11lcn_gain_tbl_2G[] = {
+ 0x00000000,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000d,
+ 0x0000004d,
+ 0x0000008d,
+ 0x00000049,
+ 0x00000089,
+ 0x000000c9,
+ 0x0000004b,
+ 0x0000008b,
+ 0x000000cb,
+ 0x000000cf,
+ 0x0000010f,
+ 0x0000050f,
+ 0x0000090f,
+ 0x0000094f,
+ 0x00000d4f,
+ 0x0000114f,
+ 0x0000118f,
+ 0x0000518f,
+ 0x0000918f,
+ 0x0000d18f,
+ 0x0001118f,
+ 0x0001518f,
+ 0x0001918f,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST uint32 dot11lcn_gain_tbl_extlna_2G[] = {
+ 0x00000000,
+ 0x00000004,
+ 0x00000008,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000d,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000b,
+ 0x0000000f,
+ 0x0000004f,
+ 0x0000008f,
+ 0x000000cf,
+ 0x0000010f,
+ 0x0000014f,
+ 0x0000018f,
+ 0x0000058f,
+ 0x0000098f,
+ 0x00000d8f,
+ 0x00008000,
+ 0x00008004,
+ 0x00008008,
+ 0x00008001,
+ 0x00008005,
+ 0x00008009,
+ 0x0000800d,
+ 0x00008003,
+ 0x00008007,
+ 0x0000800b,
+ 0x0000800f,
+ 0x0000804f,
+ 0x0000808f,
+ 0x000080cf,
+ 0x0000810f,
+ 0x0000814f,
+ 0x0000818f,
+ 0x0000858f,
+ 0x0000898f,
+ 0x00008d8f,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST uint16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0400,
+ 0x0401,
+ 0x0402,
+ 0x0403,
+ 0x0404,
+ 0x0483,
+ 0x0484,
+ 0x0485,
+ 0x0486,
+ 0x0583,
+ 0x0584,
+ 0x0585,
+ 0x0587,
+ 0x0588,
+ 0x0589,
+ 0x058a,
+ 0x0687,
+ 0x0688,
+ 0x0689,
+ 0x068a,
+ 0x068b,
+ 0x068c,
+ 0x068d,
+ 0x068e,
+ 0x068f,
+ 0x0690,
+ 0x0691,
+ 0x0692,
+ 0x0693,
+ 0x0000
+};
+
+CONST uint8 dot11lcn_gain_val_tbl_extlna_2G[] = {
+ 0xfc,
+ 0x02,
+ 0x08,
+ 0x0e,
+ 0x13,
+ 0x1b,
+ 0xfc,
+ 0x02,
+ 0x08,
+ 0x0e,
+ 0x13,
+ 0x1b,
+ 0xfc,
+ 0x00,
+ 0x0f,
+ 0x03,
+ 0xeb,
+ 0xfe,
+ 0x07,
+ 0x0b,
+ 0x0f,
+ 0xfb,
+ 0xfe,
+ 0x01,
+ 0x05,
+ 0x08,
+ 0x0b,
+ 0x0e,
+ 0x11,
+ 0x14,
+ 0x17,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x15,
+ 0x18,
+ 0x1b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+CONST uint32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x00000000,
+ 0x00000040,
+ 0x10000000,
+ 0x00000040,
+ 0x20000000,
+ 0x00000040,
+ 0x30000000,
+ 0x00000040,
+ 0x40000000,
+ 0x00000040,
+ 0x30000000,
+ 0x00000048,
+ 0x40000000,
+ 0x00000048,
+ 0x50000000,
+ 0x00000048,
+ 0x60000000,
+ 0x00000048,
+ 0x30000000,
+ 0x00000058,
+ 0x40000000,
+ 0x00000058,
+ 0x50000000,
+ 0x00000058,
+ 0x70000000,
+ 0x00000058,
+ 0x80000000,
+ 0x00000058,
+ 0x90000000,
+ 0x00000058,
+ 0xa0000000,
+ 0x00000058,
+ 0x70000000,
+ 0x00000068,
+ 0x80000000,
+ 0x00000068,
+ 0x90000000,
+ 0x00000068,
+ 0xa0000000,
+ 0x00000068,
+ 0xb0000000,
+ 0x00000068,
+ 0xc0000000,
+ 0x00000068,
+ 0xd0000000,
+ 0x00000068,
+ 0xe0000000,
+ 0x00000068,
+ 0xf0000000,
+ 0x00000068,
+ 0x00000000,
+ 0x00000069,
+ 0x10000000,
+ 0x00000069,
+ 0x20000000,
+ 0x00000069,
+ 0x30000000,
+ 0x00000069,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x40000000,
+ 0x00000041,
+ 0x50000000,
+ 0x00000041,
+ 0x60000000,
+ 0x00000041,
+ 0x70000000,
+ 0x00000041,
+ 0x80000000,
+ 0x00000041,
+ 0x70000000,
+ 0x00000049,
+ 0x80000000,
+ 0x00000049,
+ 0x90000000,
+ 0x00000049,
+ 0xa0000000,
+ 0x00000049,
+ 0x70000000,
+ 0x00000059,
+ 0x80000000,
+ 0x00000059,
+ 0x90000000,
+ 0x00000059,
+ 0xb0000000,
+ 0x00000059,
+ 0xc0000000,
+ 0x00000059,
+ 0xd0000000,
+ 0x00000059,
+ 0xe0000000,
+ 0x00000059,
+ 0xb0000000,
+ 0x00000069,
+ 0xc0000000,
+ 0x00000069,
+ 0xd0000000,
+ 0x00000069,
+ 0xe0000000,
+ 0x00000069,
+ 0xf0000000,
+ 0x00000069,
+ 0x00000000,
+ 0x0000006a,
+ 0x10000000,
+ 0x0000006a,
+ 0x20000000,
+ 0x0000006a,
+ 0x30000000,
+ 0x0000006a,
+ 0x40000000,
+ 0x0000006a,
+ 0x50000000,
+ 0x0000006a,
+ 0x60000000,
+ 0x0000006a,
+ 0x70000000,
+ 0x0000006a,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST uint32 dot11lcn_aux_gain_idx_tbl_5G[] = {
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0001,
+ 0x0002,
+ 0x0003,
+ 0x0004,
+ 0x0083,
+ 0x0084,
+ 0x0085,
+ 0x0086,
+ 0x0087,
+ 0x0186,
+ 0x0187,
+ 0x0188,
+ 0x0189,
+ 0x018a,
+ 0x018b,
+ 0x018c,
+ 0x018d,
+ 0x018e,
+ 0x018f,
+ 0x0190,
+ 0x0191,
+ 0x0192,
+ 0x0193,
+ 0x0194,
+ 0x0195,
+ 0x0196,
+ 0x0197,
+ 0x0198,
+ 0x0199,
+ 0x019a,
+ 0x019b,
+ 0x019c,
+ 0x019d,
+ 0x0000
+};
+
+CONST uint32 dot11lcn_gain_val_tbl_5G[] = {
+ 0xf7,
+ 0xfd,
+ 0x00,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0xf7,
+ 0xfd,
+ 0x00,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0xf6,
+ 0x00,
+ 0x0c,
+ 0x03,
+ 0xeb,
+ 0xfe,
+ 0x06,
+ 0x0a,
+ 0x10,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x15,
+ 0x18,
+ 0x1b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x15,
+ 0x18,
+ 0x1b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+CONST uint32 dot11lcn_gain_idx_tbl_5G[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x10000000,
+ 0x00000000,
+ 0x20000000,
+ 0x00000000,
+ 0x30000000,
+ 0x00000000,
+ 0x40000000,
+ 0x00000000,
+ 0x30000000,
+ 0x00000008,
+ 0x40000000,
+ 0x00000008,
+ 0x50000000,
+ 0x00000008,
+ 0x60000000,
+ 0x00000008,
+ 0x70000000,
+ 0x00000008,
+ 0x60000000,
+ 0x00000018,
+ 0x70000000,
+ 0x00000018,
+ 0x80000000,
+ 0x00000018,
+ 0x90000000,
+ 0x00000018,
+ 0xa0000000,
+ 0x00000018,
+ 0xb0000000,
+ 0x00000018,
+ 0xc0000000,
+ 0x00000018,
+ 0xd0000000,
+ 0x00000018,
+ 0xe0000000,
+ 0x00000018,
+ 0xf0000000,
+ 0x00000018,
+ 0x00000000,
+ 0x00000019,
+ 0x10000000,
+ 0x00000019,
+ 0x20000000,
+ 0x00000019,
+ 0x30000000,
+ 0x00000019,
+ 0x40000000,
+ 0x00000019,
+ 0x50000000,
+ 0x00000019,
+ 0x60000000,
+ 0x00000019,
+ 0x70000000,
+ 0x00000019,
+ 0x80000000,
+ 0x00000019,
+ 0x90000000,
+ 0x00000019,
+ 0xa0000000,
+ 0x00000019,
+ 0xb0000000,
+ 0x00000019,
+ 0xc0000000,
+ 0x00000019,
+ 0xd0000000,
+ 0x00000019,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST uint32 dot11lcn_gain_tbl_5G[] = {
+ 0x00000000,
+ 0x00000040,
+ 0x00000080,
+ 0x00000001,
+ 0x00000005,
+ 0x00000009,
+ 0x0000000d,
+ 0x00000011,
+ 0x00000015,
+ 0x00000055,
+ 0x00000095,
+ 0x00000017,
+ 0x0000001b,
+ 0x0000005b,
+ 0x0000009b,
+ 0x000000db,
+ 0x0000011b,
+ 0x0000015b,
+ 0x0000019b,
+ 0x0000059b,
+ 0x0000099b,
+ 0x00000d9b,
+ 0x0000119b,
+ 0x0000519b,
+ 0x0000919b,
+ 0x0000d19b,
+ 0x0001119b,
+ 0x0001519b,
+ 0x0001919b,
+ 0x0001d19b,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = {
+ {&dot11lcn_gain_tbl_rev0,
+ sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+ 0, 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+ ,
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = {
+ {&dot11lcn_gain_tbl_rev1,
+ sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
+ 0, 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+ ,
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
+ {&dot11lcn_gain_tbl_2G,
+ sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
+ 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_2G,
+ sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_2G,
+ sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
+ 13, 0, 32}
+ ,
+ {&dot11lcn_gain_val_tbl_2G,
+ sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
+ 17, 0, 8}
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
+ {&dot11lcn_gain_tbl_5G,
+ sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+ 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_5G,
+ sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_5G,
+ sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+ 13, 0, 32}
+ ,
+ {&dot11lcn_gain_val_tbl_5G,
+ sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+ 17, 0, 8}
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
+ {&dot11lcn_gain_tbl_extlna_2G,
+ sizeof(dot11lcn_gain_tbl_extlna_2G) /
+ sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_extlna_2G,
+ sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_extlna_2G,
+ sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
+ sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
+ ,
+ {&dot11lcn_gain_val_tbl_extlna_2G,
+ sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
+ sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
+ {&dot11lcn_gain_tbl_5G,
+ sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+ 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_5G,
+ sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_gain_idx_tbl_5G,
+ sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+ 13, 0, 32}
+ ,
+ {&dot11lcn_gain_val_tbl_5G,
+ sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+ 17, 0, 8}
+};
+
+CONST uint32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
+ sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
+ sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
+
+CONST uint32 dot11lcnphytbl_rx_gain_info_sz_rev1 =
+ sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
+ sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
+
+CONST uint32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
+ sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
+ sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
+
+CONST uint32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
+ sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
+ sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
+
+CONST uint16 dot11lcn_min_sig_sq_tbl_rev0[] = {
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+ 0x014d,
+};
+
+CONST uint16 dot11lcn_noise_scale_tbl_rev0[] = {
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
+ 0x000141f8,
+ 0x000021f8,
+ 0x000021fb,
+ 0x000041fb,
+ 0x0001fe4b,
+ 0x0000217b,
+ 0x00002133,
+ 0x000040eb,
+ 0x0001fea3,
+ 0x0000024b,
+};
+
+CONST uint32 dot11lcn_ps_ctrl_tbl_rev0[] = {
+ 0x00100001,
+ 0x00200010,
+ 0x00300001,
+ 0x00400010,
+ 0x00500022,
+ 0x00600122,
+ 0x00700222,
+ 0x00800322,
+ 0x00900422,
+ 0x00a00522,
+ 0x00b00622,
+ 0x00c00722,
+ 0x00d00822,
+ 0x00f00922,
+ 0x00100a22,
+ 0x00200b22,
+ 0x00300c22,
+ 0x00400d22,
+ 0x00500e22,
+ 0x00600f22,
+};
+
+CONST uint16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x0007,
+ 0x0005,
+ 0x0006,
+ 0x0004,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+ 0x000b,
+ 0x000b,
+ 0x000a,
+ 0x000a,
+
+};
+
+CONST uint16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0005,
+ 0x0002,
+ 0x0000,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+ 0x0007,
+ 0x0007,
+ 0x0002,
+ 0x0002,
+};
+
+CONST uint16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+ 0x0002,
+ 0x0008,
+ 0x0004,
+ 0x0001,
+};
+
+CONST uint16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+ 0x000a,
+ 0x0009,
+ 0x0006,
+ 0x0005,
+};
+
+CONST uint16 dot11lcn_sw_ctrl_tbl_rev0[] = {
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+ 0x0004,
+ 0x0004,
+ 0x0002,
+ 0x0002,
+};
+
+CONST uint8 dot11lcn_nf_table_rev0[] = {
+ 0x5f,
+ 0x36,
+ 0x29,
+ 0x1f,
+ 0x5f,
+ 0x36,
+ 0x29,
+ 0x1f,
+ 0x5f,
+ 0x36,
+ 0x29,
+ 0x1f,
+ 0x5f,
+ 0x36,
+ 0x29,
+ 0x1f,
+};
+
+CONST uint8 dot11lcn_gain_val_tbl_rev0[] = {
+ 0x09,
+ 0x0f,
+ 0x14,
+ 0x18,
+ 0xfe,
+ 0x07,
+ 0x0b,
+ 0x0f,
+ 0xfb,
+ 0xfe,
+ 0x01,
+ 0x05,
+ 0x08,
+ 0x0b,
+ 0x0e,
+ 0x11,
+ 0x14,
+ 0x17,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x09,
+ 0x0c,
+ 0x0f,
+ 0x12,
+ 0x15,
+ 0x18,
+ 0x1b,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0xeb,
+ 0x00,
+ 0x00,
+};
+
+CONST uint8 dot11lcn_spur_tbl_rev0[] = {
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x01,
+ 0x03,
+ 0x02,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x02,
+ 0x03,
+ 0x01,
+ 0x03,
+ 0x02,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+};
+
+CONST uint16 dot11lcn_unsup_mcs_tbl_rev0[] = {
+ 0x001a,
+ 0x0034,
+ 0x004e,
+ 0x0068,
+ 0x009c,
+ 0x00d0,
+ 0x00ea,
+ 0x0104,
+ 0x0034,
+ 0x0068,
+ 0x009c,
+ 0x00d0,
+ 0x0138,
+ 0x01a0,
+ 0x01d4,
+ 0x0208,
+ 0x004e,
+ 0x009c,
+ 0x00ea,
+ 0x0138,
+ 0x01d4,
+ 0x0270,
+ 0x02be,
+ 0x030c,
+ 0x0068,
+ 0x00d0,
+ 0x0138,
+ 0x01a0,
+ 0x0270,
+ 0x0340,
+ 0x03a8,
+ 0x0410,
+ 0x0018,
+ 0x009c,
+ 0x00d0,
+ 0x0104,
+ 0x00ea,
+ 0x0138,
+ 0x0186,
+ 0x00d0,
+ 0x0104,
+ 0x0104,
+ 0x0138,
+ 0x016c,
+ 0x016c,
+ 0x01a0,
+ 0x0138,
+ 0x0186,
+ 0x0186,
+ 0x01d4,
+ 0x0222,
+ 0x0222,
+ 0x0270,
+ 0x0104,
+ 0x0138,
+ 0x016c,
+ 0x0138,
+ 0x016c,
+ 0x01a0,
+ 0x01d4,
+ 0x01a0,
+ 0x01d4,
+ 0x0208,
+ 0x0208,
+ 0x023c,
+ 0x0186,
+ 0x01d4,
+ 0x0222,
+ 0x01d4,
+ 0x0222,
+ 0x0270,
+ 0x02be,
+ 0x0270,
+ 0x02be,
+ 0x030c,
+ 0x030c,
+ 0x035a,
+ 0x0036,
+ 0x006c,
+ 0x00a2,
+ 0x00d8,
+ 0x0144,
+ 0x01b0,
+ 0x01e6,
+ 0x021c,
+ 0x006c,
+ 0x00d8,
+ 0x0144,
+ 0x01b0,
+ 0x0288,
+ 0x0360,
+ 0x03cc,
+ 0x0438,
+ 0x00a2,
+ 0x0144,
+ 0x01e6,
+ 0x0288,
+ 0x03cc,
+ 0x0510,
+ 0x05b2,
+ 0x0654,
+ 0x00d8,
+ 0x01b0,
+ 0x0288,
+ 0x0360,
+ 0x0510,
+ 0x06c0,
+ 0x0798,
+ 0x0870,
+ 0x0018,
+ 0x0144,
+ 0x01b0,
+ 0x021c,
+ 0x01e6,
+ 0x0288,
+ 0x032a,
+ 0x01b0,
+ 0x021c,
+ 0x021c,
+ 0x0288,
+ 0x02f4,
+ 0x02f4,
+ 0x0360,
+ 0x0288,
+ 0x032a,
+ 0x032a,
+ 0x03cc,
+ 0x046e,
+ 0x046e,
+ 0x0510,
+ 0x021c,
+ 0x0288,
+ 0x02f4,
+ 0x0288,
+ 0x02f4,
+ 0x0360,
+ 0x03cc,
+ 0x0360,
+ 0x03cc,
+ 0x0438,
+ 0x0438,
+ 0x04a4,
+ 0x032a,
+ 0x03cc,
+ 0x046e,
+ 0x03cc,
+ 0x046e,
+ 0x0510,
+ 0x05b2,
+ 0x0510,
+ 0x05b2,
+ 0x0654,
+ 0x0654,
+ 0x06f6,
+};
+
+CONST uint16 dot11lcn_iq_local_tbl_rev0[] = {
+ 0x0200,
+ 0x0300,
+ 0x0400,
+ 0x0600,
+ 0x0800,
+ 0x0b00,
+ 0x1000,
+ 0x1001,
+ 0x1002,
+ 0x1003,
+ 0x1004,
+ 0x1005,
+ 0x1006,
+ 0x1007,
+ 0x1707,
+ 0x2007,
+ 0x2d07,
+ 0x4007,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0200,
+ 0x0300,
+ 0x0400,
+ 0x0600,
+ 0x0800,
+ 0x0b00,
+ 0x1000,
+ 0x1001,
+ 0x1002,
+ 0x1003,
+ 0x1004,
+ 0x1005,
+ 0x1006,
+ 0x1007,
+ 0x1707,
+ 0x2007,
+ 0x2d07,
+ 0x4007,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x4000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint32 dot11lcn_papd_compdelta_tbl_rev0[] = {
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+ 0x00080000,
+};
+
+CONST dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = {
+ {&dot11lcn_min_sig_sq_tbl_rev0,
+ sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
+ sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
+ ,
+ {&dot11lcn_noise_scale_tbl_rev0,
+ sizeof(dot11lcn_noise_scale_tbl_rev0) /
+ sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
+ ,
+ {&dot11lcn_fltr_ctrl_tbl_rev0,
+ sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
+ sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
+ ,
+ {&dot11lcn_ps_ctrl_tbl_rev0,
+ sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
+ sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
+ ,
+ {&dot11lcn_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+ ,
+ {&dot11lcn_aux_gain_idx_tbl_rev0,
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+ sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+ ,
+ {&dot11lcn_sw_ctrl_tbl_rev0,
+ sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
+ sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
+ ,
+ {&dot11lcn_nf_table_rev0,
+ sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
+ 0, 8}
+ ,
+ {&dot11lcn_gain_val_tbl_rev0,
+ sizeof(dot11lcn_gain_val_tbl_rev0) /
+ sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
+ ,
+ {&dot11lcn_gain_tbl_rev0,
+ sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+ 0, 32}
+ ,
+ {&dot11lcn_spur_tbl_rev0,
+ sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
+ 0, 8}
+ ,
+ {&dot11lcn_unsup_mcs_tbl_rev0,
+ sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
+ sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
+ ,
+ {&dot11lcn_iq_local_tbl_rev0,
+ sizeof(dot11lcn_iq_local_tbl_rev0) /
+ sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
+ ,
+ {&dot11lcn_papd_compdelta_tbl_rev0,
+ sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
+ sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
+ ,
+};
+
+CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = {
+ &dot11lcn_sw_ctrl_tbl_4313_rev0,
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
+};
+
+CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = {
+ &dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
+};
+
+CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
+ &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
+};
+
+CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
+ &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
+ sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
+};
+
+CONST uint32 dot11lcnphytbl_info_sz_rev0 =
+ sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
+
+CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
+ {3, 0, 31, 0, 72,}
+ ,
+ {3, 0, 31, 0, 70,}
+ ,
+ {3, 0, 31, 0, 68,}
+ ,
+ {3, 0, 30, 0, 67,}
+ ,
+ {3, 0, 29, 0, 68,}
+ ,
+ {3, 0, 28, 0, 68,}
+ ,
+ {3, 0, 27, 0, 69,}
+ ,
+ {3, 0, 26, 0, 70,}
+ ,
+ {3, 0, 25, 0, 70,}
+ ,
+ {3, 0, 24, 0, 71,}
+ ,
+ {3, 0, 23, 0, 72,}
+ ,
+ {3, 0, 23, 0, 70,}
+ ,
+ {3, 0, 22, 0, 71,}
+ ,
+ {3, 0, 21, 0, 72,}
+ ,
+ {3, 0, 21, 0, 70,}
+ ,
+ {3, 0, 21, 0, 68,}
+ ,
+ {3, 0, 21, 0, 66,}
+ ,
+ {3, 0, 21, 0, 64,}
+ ,
+ {3, 0, 21, 0, 63,}
+ ,
+ {3, 0, 20, 0, 64,}
+ ,
+ {3, 0, 19, 0, 65,}
+ ,
+ {3, 0, 19, 0, 64,}
+ ,
+ {3, 0, 18, 0, 65,}
+ ,
+ {3, 0, 18, 0, 64,}
+ ,
+ {3, 0, 17, 0, 65,}
+ ,
+ {3, 0, 17, 0, 64,}
+ ,
+ {3, 0, 16, 0, 65,}
+ ,
+ {3, 0, 16, 0, 64,}
+ ,
+ {3, 0, 16, 0, 62,}
+ ,
+ {3, 0, 16, 0, 60,}
+ ,
+ {3, 0, 16, 0, 58,}
+ ,
+ {3, 0, 15, 0, 61,}
+ ,
+ {3, 0, 15, 0, 59,}
+ ,
+ {3, 0, 14, 0, 61,}
+ ,
+ {3, 0, 14, 0, 60,}
+ ,
+ {3, 0, 14, 0, 58,}
+ ,
+ {3, 0, 13, 0, 60,}
+ ,
+ {3, 0, 13, 0, 59,}
+ ,
+ {3, 0, 12, 0, 62,}
+ ,
+ {3, 0, 12, 0, 60,}
+ ,
+ {3, 0, 12, 0, 58,}
+ ,
+ {3, 0, 11, 0, 62,}
+ ,
+ {3, 0, 11, 0, 60,}
+ ,
+ {3, 0, 11, 0, 59,}
+ ,
+ {3, 0, 11, 0, 57,}
+ ,
+ {3, 0, 10, 0, 61,}
+ ,
+ {3, 0, 10, 0, 59,}
+ ,
+ {3, 0, 10, 0, 57,}
+ ,
+ {3, 0, 9, 0, 62,}
+ ,
+ {3, 0, 9, 0, 60,}
+ ,
+ {3, 0, 9, 0, 58,}
+ ,
+ {3, 0, 9, 0, 57,}
+ ,
+ {3, 0, 8, 0, 62,}
+ ,
+ {3, 0, 8, 0, 60,}
+ ,
+ {3, 0, 8, 0, 58,}
+ ,
+ {3, 0, 8, 0, 57,}
+ ,
+ {3, 0, 8, 0, 55,}
+ ,
+ {3, 0, 7, 0, 61,}
+ ,
+ {3, 0, 7, 0, 60,}
+ ,
+ {3, 0, 7, 0, 58,}
+ ,
+ {3, 0, 7, 0, 56,}
+ ,
+ {3, 0, 7, 0, 55,}
+ ,
+ {3, 0, 6, 0, 62,}
+ ,
+ {3, 0, 6, 0, 60,}
+ ,
+ {3, 0, 6, 0, 58,}
+ ,
+ {3, 0, 6, 0, 57,}
+ ,
+ {3, 0, 6, 0, 55,}
+ ,
+ {3, 0, 6, 0, 54,}
+ ,
+ {3, 0, 6, 0, 52,}
+ ,
+ {3, 0, 5, 0, 61,}
+ ,
+ {3, 0, 5, 0, 59,}
+ ,
+ {3, 0, 5, 0, 57,}
+ ,
+ {3, 0, 5, 0, 56,}
+ ,
+ {3, 0, 5, 0, 54,}
+ ,
+ {3, 0, 5, 0, 53,}
+ ,
+ {3, 0, 5, 0, 51,}
+ ,
+ {3, 0, 4, 0, 62,}
+ ,
+ {3, 0, 4, 0, 60,}
+ ,
+ {3, 0, 4, 0, 58,}
+ ,
+ {3, 0, 4, 0, 57,}
+ ,
+ {3, 0, 4, 0, 55,}
+ ,
+ {3, 0, 4, 0, 54,}
+ ,
+ {3, 0, 4, 0, 52,}
+ ,
+ {3, 0, 4, 0, 51,}
+ ,
+ {3, 0, 4, 0, 49,}
+ ,
+ {3, 0, 4, 0, 48,}
+ ,
+ {3, 0, 4, 0, 46,}
+ ,
+ {3, 0, 3, 0, 60,}
+ ,
+ {3, 0, 3, 0, 58,}
+ ,
+ {3, 0, 3, 0, 57,}
+ ,
+ {3, 0, 3, 0, 55,}
+ ,
+ {3, 0, 3, 0, 54,}
+ ,
+ {3, 0, 3, 0, 52,}
+ ,
+ {3, 0, 3, 0, 51,}
+ ,
+ {3, 0, 3, 0, 49,}
+ ,
+ {3, 0, 3, 0, 48,}
+ ,
+ {3, 0, 3, 0, 46,}
+ ,
+ {3, 0, 3, 0, 45,}
+ ,
+ {3, 0, 3, 0, 44,}
+ ,
+ {3, 0, 3, 0, 43,}
+ ,
+ {3, 0, 3, 0, 41,}
+ ,
+ {3, 0, 2, 0, 61,}
+ ,
+ {3, 0, 2, 0, 59,}
+ ,
+ {3, 0, 2, 0, 57,}
+ ,
+ {3, 0, 2, 0, 56,}
+ ,
+ {3, 0, 2, 0, 54,}
+ ,
+ {3, 0, 2, 0, 53,}
+ ,
+ {3, 0, 2, 0, 51,}
+ ,
+ {3, 0, 2, 0, 50,}
+ ,
+ {3, 0, 2, 0, 48,}
+ ,
+ {3, 0, 2, 0, 47,}
+ ,
+ {3, 0, 2, 0, 46,}
+ ,
+ {3, 0, 2, 0, 44,}
+ ,
+ {3, 0, 2, 0, 43,}
+ ,
+ {3, 0, 2, 0, 42,}
+ ,
+ {3, 0, 2, 0, 41,}
+ ,
+ {3, 0, 2, 0, 39,}
+ ,
+ {3, 0, 2, 0, 38,}
+ ,
+ {3, 0, 2, 0, 37,}
+ ,
+ {3, 0, 2, 0, 36,}
+ ,
+ {3, 0, 2, 0, 35,}
+ ,
+ {3, 0, 2, 0, 34,}
+ ,
+ {3, 0, 2, 0, 33,}
+ ,
+ {3, 0, 2, 0, 32,}
+ ,
+ {3, 0, 1, 0, 63,}
+ ,
+ {3, 0, 1, 0, 61,}
+ ,
+ {3, 0, 1, 0, 59,}
+ ,
+ {3, 0, 1, 0, 57,}
+ ,
+};
+
+CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
+ {7, 0, 31, 0, 72,}
+ ,
+ {7, 0, 31, 0, 70,}
+ ,
+ {7, 0, 31, 0, 68,}
+ ,
+ {7, 0, 30, 0, 67,}
+ ,
+ {7, 0, 29, 0, 68,}
+ ,
+ {7, 0, 28, 0, 68,}
+ ,
+ {7, 0, 27, 0, 69,}
+ ,
+ {7, 0, 26, 0, 70,}
+ ,
+ {7, 0, 25, 0, 70,}
+ ,
+ {7, 0, 24, 0, 71,}
+ ,
+ {7, 0, 23, 0, 72,}
+ ,
+ {7, 0, 23, 0, 70,}
+ ,
+ {7, 0, 22, 0, 71,}
+ ,
+ {7, 0, 21, 0, 72,}
+ ,
+ {7, 0, 21, 0, 70,}
+ ,
+ {7, 0, 21, 0, 68,}
+ ,
+ {7, 0, 21, 0, 66,}
+ ,
+ {7, 0, 21, 0, 64,}
+ ,
+ {7, 0, 21, 0, 63,}
+ ,
+ {7, 0, 20, 0, 64,}
+ ,
+ {7, 0, 19, 0, 65,}
+ ,
+ {7, 0, 19, 0, 64,}
+ ,
+ {7, 0, 18, 0, 65,}
+ ,
+ {7, 0, 18, 0, 64,}
+ ,
+ {7, 0, 17, 0, 65,}
+ ,
+ {7, 0, 17, 0, 64,}
+ ,
+ {7, 0, 16, 0, 65,}
+ ,
+ {7, 0, 16, 0, 64,}
+ ,
+ {7, 0, 16, 0, 62,}
+ ,
+ {7, 0, 16, 0, 60,}
+ ,
+ {7, 0, 16, 0, 58,}
+ ,
+ {7, 0, 15, 0, 61,}
+ ,
+ {7, 0, 15, 0, 59,}
+ ,
+ {7, 0, 14, 0, 61,}
+ ,
+ {7, 0, 14, 0, 60,}
+ ,
+ {7, 0, 14, 0, 58,}
+ ,
+ {7, 0, 13, 0, 60,}
+ ,
+ {7, 0, 13, 0, 59,}
+ ,
+ {7, 0, 12, 0, 62,}
+ ,
+ {7, 0, 12, 0, 60,}
+ ,
+ {7, 0, 12, 0, 58,}
+ ,
+ {7, 0, 11, 0, 62,}
+ ,
+ {7, 0, 11, 0, 60,}
+ ,
+ {7, 0, 11, 0, 59,}
+ ,
+ {7, 0, 11, 0, 57,}
+ ,
+ {7, 0, 10, 0, 61,}
+ ,
+ {7, 0, 10, 0, 59,}
+ ,
+ {7, 0, 10, 0, 57,}
+ ,
+ {7, 0, 9, 0, 62,}
+ ,
+ {7, 0, 9, 0, 60,}
+ ,
+ {7, 0, 9, 0, 58,}
+ ,
+ {7, 0, 9, 0, 57,}
+ ,
+ {7, 0, 8, 0, 62,}
+ ,
+ {7, 0, 8, 0, 60,}
+ ,
+ {7, 0, 8, 0, 58,}
+ ,
+ {7, 0, 8, 0, 57,}
+ ,
+ {7, 0, 8, 0, 55,}
+ ,
+ {7, 0, 7, 0, 61,}
+ ,
+ {7, 0, 7, 0, 60,}
+ ,
+ {7, 0, 7, 0, 58,}
+ ,
+ {7, 0, 7, 0, 56,}
+ ,
+ {7, 0, 7, 0, 55,}
+ ,
+ {7, 0, 6, 0, 62,}
+ ,
+ {7, 0, 6, 0, 60,}
+ ,
+ {7, 0, 6, 0, 58,}
+ ,
+ {7, 0, 6, 0, 57,}
+ ,
+ {7, 0, 6, 0, 55,}
+ ,
+ {7, 0, 6, 0, 54,}
+ ,
+ {7, 0, 6, 0, 52,}
+ ,
+ {7, 0, 5, 0, 61,}
+ ,
+ {7, 0, 5, 0, 59,}
+ ,
+ {7, 0, 5, 0, 57,}
+ ,
+ {7, 0, 5, 0, 56,}
+ ,
+ {7, 0, 5, 0, 54,}
+ ,
+ {7, 0, 5, 0, 53,}
+ ,
+ {7, 0, 5, 0, 51,}
+ ,
+ {7, 0, 4, 0, 62,}
+ ,
+ {7, 0, 4, 0, 60,}
+ ,
+ {7, 0, 4, 0, 58,}
+ ,
+ {7, 0, 4, 0, 57,}
+ ,
+ {7, 0, 4, 0, 55,}
+ ,
+ {7, 0, 4, 0, 54,}
+ ,
+ {7, 0, 4, 0, 52,}
+ ,
+ {7, 0, 4, 0, 51,}
+ ,
+ {7, 0, 4, 0, 49,}
+ ,
+ {7, 0, 4, 0, 48,}
+ ,
+ {7, 0, 4, 0, 46,}
+ ,
+ {7, 0, 3, 0, 60,}
+ ,
+ {7, 0, 3, 0, 58,}
+ ,
+ {7, 0, 3, 0, 57,}
+ ,
+ {7, 0, 3, 0, 55,}
+ ,
+ {7, 0, 3, 0, 54,}
+ ,
+ {7, 0, 3, 0, 52,}
+ ,
+ {7, 0, 3, 0, 51,}
+ ,
+ {7, 0, 3, 0, 49,}
+ ,
+ {7, 0, 3, 0, 48,}
+ ,
+ {7, 0, 3, 0, 46,}
+ ,
+ {7, 0, 3, 0, 45,}
+ ,
+ {7, 0, 3, 0, 44,}
+ ,
+ {7, 0, 3, 0, 43,}
+ ,
+ {7, 0, 3, 0, 41,}
+ ,
+ {7, 0, 2, 0, 61,}
+ ,
+ {7, 0, 2, 0, 59,}
+ ,
+ {7, 0, 2, 0, 57,}
+ ,
+ {7, 0, 2, 0, 56,}
+ ,
+ {7, 0, 2, 0, 54,}
+ ,
+ {7, 0, 2, 0, 53,}
+ ,
+ {7, 0, 2, 0, 51,}
+ ,
+ {7, 0, 2, 0, 50,}
+ ,
+ {7, 0, 2, 0, 48,}
+ ,
+ {7, 0, 2, 0, 47,}
+ ,
+ {7, 0, 2, 0, 46,}
+ ,
+ {7, 0, 2, 0, 44,}
+ ,
+ {7, 0, 2, 0, 43,}
+ ,
+ {7, 0, 2, 0, 42,}
+ ,
+ {7, 0, 2, 0, 41,}
+ ,
+ {7, 0, 2, 0, 39,}
+ ,
+ {7, 0, 2, 0, 38,}
+ ,
+ {7, 0, 2, 0, 37,}
+ ,
+ {7, 0, 2, 0, 36,}
+ ,
+ {7, 0, 2, 0, 35,}
+ ,
+ {7, 0, 2, 0, 34,}
+ ,
+ {7, 0, 2, 0, 33,}
+ ,
+ {7, 0, 2, 0, 32,}
+ ,
+ {7, 0, 1, 0, 63,}
+ ,
+ {7, 0, 1, 0, 61,}
+ ,
+ {7, 0, 1, 0, 59,}
+ ,
+ {7, 0, 1, 0, 57,}
+ ,
+};
+
+CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
+ {255, 255, 0xf0, 0, 152,}
+ ,
+ {255, 255, 0xf0, 0, 147,}
+ ,
+ {255, 255, 0xf0, 0, 143,}
+ ,
+ {255, 255, 0xf0, 0, 139,}
+ ,
+ {255, 255, 0xf0, 0, 135,}
+ ,
+ {255, 255, 0xf0, 0, 131,}
+ ,
+ {255, 255, 0xf0, 0, 128,}
+ ,
+ {255, 255, 0xf0, 0, 124,}
+ ,
+ {255, 255, 0xf0, 0, 121,}
+ ,
+ {255, 255, 0xf0, 0, 117,}
+ ,
+ {255, 255, 0xf0, 0, 114,}
+ ,
+ {255, 255, 0xf0, 0, 111,}
+ ,
+ {255, 255, 0xf0, 0, 107,}
+ ,
+ {255, 255, 0xf0, 0, 104,}
+ ,
+ {255, 255, 0xf0, 0, 101,}
+ ,
+ {255, 255, 0xf0, 0, 99,}
+ ,
+ {255, 255, 0xf0, 0, 96,}
+ ,
+ {255, 255, 0xf0, 0, 93,}
+ ,
+ {255, 255, 0xf0, 0, 90,}
+ ,
+ {255, 255, 0xf0, 0, 88,}
+ ,
+ {255, 255, 0xf0, 0, 85,}
+ ,
+ {255, 255, 0xf0, 0, 83,}
+ ,
+ {255, 255, 0xf0, 0, 81,}
+ ,
+ {255, 255, 0xf0, 0, 78,}
+ ,
+ {255, 255, 0xf0, 0, 76,}
+ ,
+ {255, 255, 0xf0, 0, 74,}
+ ,
+ {255, 255, 0xf0, 0, 72,}
+ ,
+ {255, 255, 0xf0, 0, 70,}
+ ,
+ {255, 255, 0xf0, 0, 68,}
+ ,
+ {255, 255, 0xf0, 0, 66,}
+ ,
+ {255, 255, 0xf0, 0, 64,}
+ ,
+ {255, 248, 0xf0, 0, 64,}
+ ,
+ {255, 241, 0xf0, 0, 64,}
+ ,
+ {255, 251, 0xe0, 0, 64,}
+ ,
+ {255, 244, 0xe0, 0, 64,}
+ ,
+ {255, 254, 0xd0, 0, 64,}
+ ,
+ {255, 246, 0xd0, 0, 64,}
+ ,
+ {255, 239, 0xd0, 0, 64,}
+ ,
+ {255, 249, 0xc0, 0, 64,}
+ ,
+ {255, 242, 0xc0, 0, 64,}
+ ,
+ {255, 255, 0xb0, 0, 64,}
+ ,
+ {255, 248, 0xb0, 0, 64,}
+ ,
+ {255, 241, 0xb0, 0, 64,}
+ ,
+ {255, 254, 0xa0, 0, 64,}
+ ,
+ {255, 246, 0xa0, 0, 64,}
+ ,
+ {255, 239, 0xa0, 0, 64,}
+ ,
+ {255, 255, 0x90, 0, 64,}
+ ,
+ {255, 248, 0x90, 0, 64,}
+ ,
+ {255, 241, 0x90, 0, 64,}
+ ,
+ {255, 234, 0x90, 0, 64,}
+ ,
+ {255, 255, 0x80, 0, 64,}
+ ,
+ {255, 248, 0x80, 0, 64,}
+ ,
+ {255, 241, 0x80, 0, 64,}
+ ,
+ {255, 234, 0x80, 0, 64,}
+ ,
+ {255, 255, 0x70, 0, 64,}
+ ,
+ {255, 248, 0x70, 0, 64,}
+ ,
+ {255, 241, 0x70, 0, 64,}
+ ,
+ {255, 234, 0x70, 0, 64,}
+ ,
+ {255, 227, 0x70, 0, 64,}
+ ,
+ {255, 221, 0x70, 0, 64,}
+ ,
+ {255, 215, 0x70, 0, 64,}
+ ,
+ {255, 208, 0x70, 0, 64,}
+ ,
+ {255, 203, 0x70, 0, 64,}
+ ,
+ {255, 197, 0x70, 0, 64,}
+ ,
+ {255, 255, 0x60, 0, 64,}
+ ,
+ {255, 248, 0x60, 0, 64,}
+ ,
+ {255, 241, 0x60, 0, 64,}
+ ,
+ {255, 234, 0x60, 0, 64,}
+ ,
+ {255, 227, 0x60, 0, 64,}
+ ,
+ {255, 221, 0x60, 0, 64,}
+ ,
+ {255, 255, 0x50, 0, 64,}
+ ,
+ {255, 248, 0x50, 0, 64,}
+ ,
+ {255, 241, 0x50, 0, 64,}
+ ,
+ {255, 234, 0x50, 0, 64,}
+ ,
+ {255, 227, 0x50, 0, 64,}
+ ,
+ {255, 221, 0x50, 0, 64,}
+ ,
+ {255, 215, 0x50, 0, 64,}
+ ,
+ {255, 208, 0x50, 0, 64,}
+ ,
+ {255, 255, 0x40, 0, 64,}
+ ,
+ {255, 248, 0x40, 0, 64,}
+ ,
+ {255, 241, 0x40, 0, 64,}
+ ,
+ {255, 234, 0x40, 0, 64,}
+ ,
+ {255, 227, 0x40, 0, 64,}
+ ,
+ {255, 221, 0x40, 0, 64,}
+ ,
+ {255, 215, 0x40, 0, 64,}
+ ,
+ {255, 208, 0x40, 0, 64,}
+ ,
+ {255, 203, 0x40, 0, 64,}
+ ,
+ {255, 197, 0x40, 0, 64,}
+ ,
+ {255, 255, 0x30, 0, 64,}
+ ,
+ {255, 248, 0x30, 0, 64,}
+ ,
+ {255, 241, 0x30, 0, 64,}
+ ,
+ {255, 234, 0x30, 0, 64,}
+ ,
+ {255, 227, 0x30, 0, 64,}
+ ,
+ {255, 221, 0x30, 0, 64,}
+ ,
+ {255, 215, 0x30, 0, 64,}
+ ,
+ {255, 208, 0x30, 0, 64,}
+ ,
+ {255, 203, 0x30, 0, 64,}
+ ,
+ {255, 197, 0x30, 0, 64,}
+ ,
+ {255, 191, 0x30, 0, 64,}
+ ,
+ {255, 186, 0x30, 0, 64,}
+ ,
+ {255, 181, 0x30, 0, 64,}
+ ,
+ {255, 175, 0x30, 0, 64,}
+ ,
+ {255, 255, 0x20, 0, 64,}
+ ,
+ {255, 248, 0x20, 0, 64,}
+ ,
+ {255, 241, 0x20, 0, 64,}
+ ,
+ {255, 234, 0x20, 0, 64,}
+ ,
+ {255, 227, 0x20, 0, 64,}
+ ,
+ {255, 221, 0x20, 0, 64,}
+ ,
+ {255, 215, 0x20, 0, 64,}
+ ,
+ {255, 208, 0x20, 0, 64,}
+ ,
+ {255, 203, 0x20, 0, 64,}
+ ,
+ {255, 197, 0x20, 0, 64,}
+ ,
+ {255, 191, 0x20, 0, 64,}
+ ,
+ {255, 186, 0x20, 0, 64,}
+ ,
+ {255, 181, 0x20, 0, 64,}
+ ,
+ {255, 175, 0x20, 0, 64,}
+ ,
+ {255, 170, 0x20, 0, 64,}
+ ,
+ {255, 166, 0x20, 0, 64,}
+ ,
+ {255, 161, 0x20, 0, 64,}
+ ,
+ {255, 156, 0x20, 0, 64,}
+ ,
+ {255, 152, 0x20, 0, 64,}
+ ,
+ {255, 148, 0x20, 0, 64,}
+ ,
+ {255, 143, 0x20, 0, 64,}
+ ,
+ {255, 139, 0x20, 0, 64,}
+ ,
+ {255, 135, 0x20, 0, 64,}
+ ,
+ {255, 132, 0x20, 0, 64,}
+ ,
+ {255, 255, 0x10, 0, 64,}
+ ,
+ {255, 248, 0x10, 0, 64,}
+ ,
+};
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h
new file mode 100644
index 000000000000..8a8ef7b736dc
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+typedef phytbl_info_t dot11lcnphytbl_info_t;
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[];
+extern CONST uint32 dot11lcnphytbl_rx_gain_info_sz_rev0;
+extern CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313;
+extern CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa;
+extern CONST dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[];
+extern CONST uint32 dot11lcnphytbl_info_sz_rev0;
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[];
+extern CONST uint32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[];
+extern CONST uint32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
+
+extern CONST dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
+
+typedef struct {
+ uchar gm;
+ uchar pga;
+ uchar pad;
+ uchar dac;
+ uchar bb_mult;
+} lcnphy_tx_gain_tbl_entry;
+
+extern CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
+extern CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
+
+extern CONST lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c
new file mode 100644
index 000000000000..e5f2e0278bdd
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c
@@ -0,0 +1,10631 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+
+#include <wlc_phy_int.h>
+#include <wlc_phytbl_n.h>
+
+CONST uint32 frame_struct_rev0[] = {
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x09804506,
+ 0x00100030,
+ 0x09804507,
+ 0x00100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a0c,
+ 0x00100004,
+ 0x01000a0d,
+ 0x00100024,
+ 0x0980450e,
+ 0x00100034,
+ 0x0980450f,
+ 0x00100034,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a04,
+ 0x00100000,
+ 0x11008a05,
+ 0x00100020,
+ 0x1980c506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x01800504,
+ 0x00100030,
+ 0x11808505,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000a04,
+ 0x00100000,
+ 0x11008a05,
+ 0x00100020,
+ 0x21810506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x1980c50e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x0180050c,
+ 0x00100038,
+ 0x1180850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x1980c506,
+ 0x00100030,
+ 0x1980c506,
+ 0x00100030,
+ 0x11808504,
+ 0x00100030,
+ 0x3981ca05,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x10008a04,
+ 0x00100000,
+ 0x3981ca05,
+ 0x00100030,
+ 0x1980c506,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a0c,
+ 0x00100008,
+ 0x01000a0d,
+ 0x00100028,
+ 0x1980c50e,
+ 0x00100038,
+ 0x1980c50e,
+ 0x00100038,
+ 0x1180850c,
+ 0x00100038,
+ 0x3981ca0d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x10008a0c,
+ 0x00100008,
+ 0x3981ca0d,
+ 0x00100038,
+ 0x1980c50e,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x02001405,
+ 0x00100040,
+ 0x0b004a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x43020a04,
+ 0x00100060,
+ 0x1b00ca05,
+ 0x00100060,
+ 0x23010a07,
+ 0x01500060,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x13008a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x0200140d,
+ 0x00100050,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x50029404,
+ 0x00100000,
+ 0x32019405,
+ 0x00100040,
+ 0x0b004a06,
+ 0x01900060,
+ 0x0b004a06,
+ 0x01900060,
+ 0x5b02ca04,
+ 0x00100060,
+ 0x3b01d405,
+ 0x00100060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x5802d404,
+ 0x00100000,
+ 0x3b01d405,
+ 0x00100060,
+ 0x0b004a06,
+ 0x01900060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x5002940c,
+ 0x00100010,
+ 0x3201940d,
+ 0x00100050,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x5b02ca0c,
+ 0x00100070,
+ 0x3b01d40d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x5802d40c,
+ 0x00100010,
+ 0x3b01d40d,
+ 0x00100070,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x000f4800,
+ 0x62031405,
+ 0x00100040,
+ 0x53028a06,
+ 0x01900060,
+ 0x53028a07,
+ 0x01900060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x000f4808,
+ 0x6203140d,
+ 0x00100048,
+ 0x53028a0e,
+ 0x01900068,
+ 0x53028a0f,
+ 0x01900068,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100004,
+ 0x11008a0d,
+ 0x00100024,
+ 0x1980c50e,
+ 0x00100034,
+ 0x2181050e,
+ 0x00100034,
+ 0x2181050e,
+ 0x00100034,
+ 0x0180050c,
+ 0x00100038,
+ 0x1180850d,
+ 0x00100038,
+ 0x1181850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x1181850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x0180c506,
+ 0x00100030,
+ 0x0180c506,
+ 0x00100030,
+ 0x2180c50c,
+ 0x00100030,
+ 0x49820a0d,
+ 0x0016a130,
+ 0x41824a0d,
+ 0x0016a130,
+ 0x2981450f,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x2000ca0c,
+ 0x00100000,
+ 0x49820a0d,
+ 0x0016a130,
+ 0x1980c50e,
+ 0x00100030,
+ 0x41824a0d,
+ 0x0016a130,
+ 0x2981450f,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100008,
+ 0x0200140d,
+ 0x00100048,
+ 0x0b004a0e,
+ 0x01900068,
+ 0x13008a0e,
+ 0x01900068,
+ 0x13008a0e,
+ 0x01900068,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x1b014a0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x1b014a0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x50029404,
+ 0x00100000,
+ 0x32019405,
+ 0x00100040,
+ 0x03004a06,
+ 0x01900060,
+ 0x03004a06,
+ 0x01900060,
+ 0x6b030a0c,
+ 0x00100060,
+ 0x4b02140d,
+ 0x0016a160,
+ 0x4302540d,
+ 0x0016a160,
+ 0x23010a0f,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x6b03140c,
+ 0x00100060,
+ 0x4b02140d,
+ 0x0016a160,
+ 0x0b004a0e,
+ 0x01900060,
+ 0x4302540d,
+ 0x0016a160,
+ 0x23010a0f,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x53028a06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x43020a04,
+ 0x00100060,
+ 0x1b00ca05,
+ 0x00100060,
+ 0x53028a07,
+ 0x0190c060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x53028a0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x53028a0f,
+ 0x0190c070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x53028a07,
+ 0x0190c060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x53028a0f,
+ 0x0190c070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint8 frame_lut_rev0[] = {
+ 0x02,
+ 0x04,
+ 0x14,
+ 0x14,
+ 0x03,
+ 0x05,
+ 0x16,
+ 0x16,
+ 0x0a,
+ 0x0c,
+ 0x1c,
+ 0x1c,
+ 0x0b,
+ 0x0d,
+ 0x1e,
+ 0x1e,
+ 0x06,
+ 0x08,
+ 0x18,
+ 0x18,
+ 0x07,
+ 0x09,
+ 0x1a,
+ 0x1a,
+ 0x0e,
+ 0x10,
+ 0x20,
+ 0x28,
+ 0x0f,
+ 0x11,
+ 0x22,
+ 0x2a,
+};
+
+CONST uint32 tmap_tbl_rev0[] = {
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x000aa888,
+ 0x88880000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00011111,
+ 0x11110000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00088aaa,
+ 0xaaaa0000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xaaa8aaa0,
+ 0x8aaa8aaa,
+ 0xaa8a8a8a,
+ 0x000aaa88,
+ 0x8aaa0000,
+ 0xaaa8a888,
+ 0x8aa88a8a,
+ 0x8a88a888,
+ 0x08080a00,
+ 0x0a08080a,
+ 0x080a0a08,
+ 0x00080808,
+ 0x080a0000,
+ 0x080a0808,
+ 0x080a0808,
+ 0x0a0a0a08,
+ 0xa0a0a0a0,
+ 0x80a0a080,
+ 0x8080a0a0,
+ 0x00008080,
+ 0x80a00000,
+ 0x80a080a0,
+ 0xa080a0a0,
+ 0x8080a0a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x99999000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x22000000,
+ 0x2222b222,
+ 0x22222222,
+ 0x222222b2,
+ 0xb2222220,
+ 0x22222222,
+ 0x22d22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333b333,
+ 0x33333333,
+ 0x333333b3,
+ 0xb3333330,
+ 0x33333333,
+ 0x33d33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x99b99b00,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb99,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x22222200,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0x22222222,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x11111111,
+ 0xf1111111,
+ 0x11111111,
+ 0x11f11111,
+ 0x01111111,
+ 0xbb9bb900,
+ 0xb9b9bb99,
+ 0xb99bbbbb,
+ 0xbbbb9b9b,
+ 0xb9bb99bb,
+ 0xb99999b9,
+ 0xb9b9b99b,
+ 0x00000bbb,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88aa,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x0a888aaa,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00000aaa,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0xbbbbbb00,
+ 0x999bbbbb,
+ 0x9bb99b9b,
+ 0xb9b9b9bb,
+ 0xb9b99bbb,
+ 0xb9b9b9bb,
+ 0xb9bb9b99,
+ 0x00000999,
+ 0x8a000000,
+ 0xaa88a888,
+ 0xa88888aa,
+ 0xa88a8a88,
+ 0xa88aa88a,
+ 0x88a8aaaa,
+ 0xa8aa8aaa,
+ 0x0888a88a,
+ 0x0b0b0b00,
+ 0x090b0b0b,
+ 0x0b090b0b,
+ 0x0909090b,
+ 0x09090b0b,
+ 0x09090b0b,
+ 0x09090b09,
+ 0x00000909,
+ 0x0a000000,
+ 0x0a080808,
+ 0x080a080a,
+ 0x080a0a08,
+ 0x080a080a,
+ 0x0808080a,
+ 0x0a0a0a08,
+ 0x0808080a,
+ 0xb0b0b000,
+ 0x9090b0b0,
+ 0x90b09090,
+ 0xb0b0b090,
+ 0xb0b090b0,
+ 0x90b0b0b0,
+ 0xb0b09090,
+ 0x00000090,
+ 0x80000000,
+ 0xa080a080,
+ 0xa08080a0,
+ 0xa0808080,
+ 0xa080a080,
+ 0x80a0a0a0,
+ 0xa0a080a0,
+ 0x00a0a0a0,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333f333,
+ 0x33333333,
+ 0x333333f3,
+ 0xf3333330,
+ 0x33333333,
+ 0x33f33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x99000000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88888000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x88a88a00,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdtrn_tbl_rev0[] = {
+ 0x061c061c,
+ 0x0050ee68,
+ 0xf592fe36,
+ 0xfe5212f6,
+ 0x00000c38,
+ 0xfe5212f6,
+ 0xf592fe36,
+ 0x0050ee68,
+ 0x061c061c,
+ 0xee680050,
+ 0xfe36f592,
+ 0x12f6fe52,
+ 0x0c380000,
+ 0x12f6fe52,
+ 0xfe36f592,
+ 0xee680050,
+ 0x061c061c,
+ 0x0050ee68,
+ 0xf592fe36,
+ 0xfe5212f6,
+ 0x00000c38,
+ 0xfe5212f6,
+ 0xf592fe36,
+ 0x0050ee68,
+ 0x061c061c,
+ 0xee680050,
+ 0xfe36f592,
+ 0x12f6fe52,
+ 0x0c380000,
+ 0x12f6fe52,
+ 0xfe36f592,
+ 0xee680050,
+ 0x05e305e3,
+ 0x004def0c,
+ 0xf5f3fe47,
+ 0xfe611246,
+ 0x00000bc7,
+ 0xfe611246,
+ 0xf5f3fe47,
+ 0x004def0c,
+ 0x05e305e3,
+ 0xef0c004d,
+ 0xfe47f5f3,
+ 0x1246fe61,
+ 0x0bc70000,
+ 0x1246fe61,
+ 0xfe47f5f3,
+ 0xef0c004d,
+ 0x05e305e3,
+ 0x004def0c,
+ 0xf5f3fe47,
+ 0xfe611246,
+ 0x00000bc7,
+ 0xfe611246,
+ 0xf5f3fe47,
+ 0x004def0c,
+ 0x05e305e3,
+ 0xef0c004d,
+ 0xfe47f5f3,
+ 0x1246fe61,
+ 0x0bc70000,
+ 0x1246fe61,
+ 0xfe47f5f3,
+ 0xef0c004d,
+ 0xfa58fa58,
+ 0xf895043b,
+ 0xff4c09c0,
+ 0xfbc6ffa8,
+ 0xfb84f384,
+ 0x0798f6f9,
+ 0x05760122,
+ 0x058409f6,
+ 0x0b500000,
+ 0x05b7f542,
+ 0x08860432,
+ 0x06ddfee7,
+ 0xfb84f384,
+ 0xf9d90664,
+ 0xf7e8025c,
+ 0x00fff7bd,
+ 0x05a805a8,
+ 0xf7bd00ff,
+ 0x025cf7e8,
+ 0x0664f9d9,
+ 0xf384fb84,
+ 0xfee706dd,
+ 0x04320886,
+ 0xf54205b7,
+ 0x00000b50,
+ 0x09f60584,
+ 0x01220576,
+ 0xf6f90798,
+ 0xf384fb84,
+ 0xffa8fbc6,
+ 0x09c0ff4c,
+ 0x043bf895,
+ 0x02d402d4,
+ 0x07de0270,
+ 0xfc96079c,
+ 0xf90afe94,
+ 0xfe00ff2c,
+ 0x02d4065d,
+ 0x092a0096,
+ 0x0014fbb8,
+ 0xfd2cfd2c,
+ 0x076afb3c,
+ 0x0096f752,
+ 0xf991fd87,
+ 0xfb2c0200,
+ 0xfeb8f960,
+ 0x08e0fc96,
+ 0x049802a8,
+ 0xfd2cfd2c,
+ 0x02a80498,
+ 0xfc9608e0,
+ 0xf960feb8,
+ 0x0200fb2c,
+ 0xfd87f991,
+ 0xf7520096,
+ 0xfb3c076a,
+ 0xfd2cfd2c,
+ 0xfbb80014,
+ 0x0096092a,
+ 0x065d02d4,
+ 0xff2cfe00,
+ 0xfe94f90a,
+ 0x079cfc96,
+ 0x027007de,
+ 0x02d402d4,
+ 0x027007de,
+ 0x079cfc96,
+ 0xfe94f90a,
+ 0xff2cfe00,
+ 0x065d02d4,
+ 0x0096092a,
+ 0xfbb80014,
+ 0xfd2cfd2c,
+ 0xfb3c076a,
+ 0xf7520096,
+ 0xfd87f991,
+ 0x0200fb2c,
+ 0xf960feb8,
+ 0xfc9608e0,
+ 0x02a80498,
+ 0xfd2cfd2c,
+ 0x049802a8,
+ 0x08e0fc96,
+ 0xfeb8f960,
+ 0xfb2c0200,
+ 0xf991fd87,
+ 0x0096f752,
+ 0x076afb3c,
+ 0xfd2cfd2c,
+ 0x0014fbb8,
+ 0x092a0096,
+ 0x02d4065d,
+ 0xfe00ff2c,
+ 0xf90afe94,
+ 0xfc96079c,
+ 0x07de0270,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x062a0000,
+ 0xfefa0759,
+ 0x08b80908,
+ 0xf396fc2d,
+ 0xf9d6045c,
+ 0xfc4ef608,
+ 0xf748f596,
+ 0x07b207bf,
+ 0x062a062a,
+ 0xf84ef841,
+ 0xf748f596,
+ 0x03b209f8,
+ 0xf9d6045c,
+ 0x0c6a03d3,
+ 0x08b80908,
+ 0x0106f8a7,
+ 0x062a0000,
+ 0xfefaf8a7,
+ 0x08b8f6f8,
+ 0xf39603d3,
+ 0xf9d6fba4,
+ 0xfc4e09f8,
+ 0xf7480a6a,
+ 0x07b2f841,
+ 0x062af9d6,
+ 0xf84e07bf,
+ 0xf7480a6a,
+ 0x03b2f608,
+ 0xf9d6fba4,
+ 0x0c6afc2d,
+ 0x08b8f6f8,
+ 0x01060759,
+ 0x062a0000,
+ 0xfefa0759,
+ 0x08b80908,
+ 0xf396fc2d,
+ 0xf9d6045c,
+ 0xfc4ef608,
+ 0xf748f596,
+ 0x07b207bf,
+ 0x062a062a,
+ 0xf84ef841,
+ 0xf748f596,
+ 0x03b209f8,
+ 0xf9d6045c,
+ 0x0c6a03d3,
+ 0x08b80908,
+ 0x0106f8a7,
+ 0x062a0000,
+ 0xfefaf8a7,
+ 0x08b8f6f8,
+ 0xf39603d3,
+ 0xf9d6fba4,
+ 0xfc4e09f8,
+ 0xf7480a6a,
+ 0x07b2f841,
+ 0x062af9d6,
+ 0xf84e07bf,
+ 0xf7480a6a,
+ 0x03b2f608,
+ 0xf9d6fba4,
+ 0x0c6afc2d,
+ 0x08b8f6f8,
+ 0x01060759,
+ 0x061c061c,
+ 0xff30009d,
+ 0xffb21141,
+ 0xfd87fb54,
+ 0xf65dfe59,
+ 0x02eef99e,
+ 0x0166f03c,
+ 0xfff809b6,
+ 0x000008a4,
+ 0x000af42b,
+ 0x00eff577,
+ 0xfa840bf2,
+ 0xfc02ff51,
+ 0x08260f67,
+ 0xfff0036f,
+ 0x0842f9c3,
+ 0x00000000,
+ 0x063df7be,
+ 0xfc910010,
+ 0xf099f7da,
+ 0x00af03fe,
+ 0xf40e057c,
+ 0x0a89ff11,
+ 0x0bd5fff6,
+ 0xf75c0000,
+ 0xf64a0008,
+ 0x0fc4fe9a,
+ 0x0662fd12,
+ 0x01a709a3,
+ 0x04ac0279,
+ 0xeebf004e,
+ 0xff6300d0,
+ 0xf9e4f9e4,
+ 0x00d0ff63,
+ 0x004eeebf,
+ 0x027904ac,
+ 0x09a301a7,
+ 0xfd120662,
+ 0xfe9a0fc4,
+ 0x0008f64a,
+ 0x0000f75c,
+ 0xfff60bd5,
+ 0xff110a89,
+ 0x057cf40e,
+ 0x03fe00af,
+ 0xf7daf099,
+ 0x0010fc91,
+ 0xf7be063d,
+ 0x00000000,
+ 0xf9c30842,
+ 0x036ffff0,
+ 0x0f670826,
+ 0xff51fc02,
+ 0x0bf2fa84,
+ 0xf57700ef,
+ 0xf42b000a,
+ 0x08a40000,
+ 0x09b6fff8,
+ 0xf03c0166,
+ 0xf99e02ee,
+ 0xfe59f65d,
+ 0xfb54fd87,
+ 0x1141ffb2,
+ 0x009dff30,
+ 0x05e30000,
+ 0xff060705,
+ 0x085408a0,
+ 0xf425fc59,
+ 0xfa1d042a,
+ 0xfc78f67a,
+ 0xf7acf60e,
+ 0x075a0766,
+ 0x05e305e3,
+ 0xf8a6f89a,
+ 0xf7acf60e,
+ 0x03880986,
+ 0xfa1d042a,
+ 0x0bdb03a7,
+ 0x085408a0,
+ 0x00faf8fb,
+ 0x05e30000,
+ 0xff06f8fb,
+ 0x0854f760,
+ 0xf42503a7,
+ 0xfa1dfbd6,
+ 0xfc780986,
+ 0xf7ac09f2,
+ 0x075af89a,
+ 0x05e3fa1d,
+ 0xf8a60766,
+ 0xf7ac09f2,
+ 0x0388f67a,
+ 0xfa1dfbd6,
+ 0x0bdbfc59,
+ 0x0854f760,
+ 0x00fa0705,
+ 0x05e30000,
+ 0xff060705,
+ 0x085408a0,
+ 0xf425fc59,
+ 0xfa1d042a,
+ 0xfc78f67a,
+ 0xf7acf60e,
+ 0x075a0766,
+ 0x05e305e3,
+ 0xf8a6f89a,
+ 0xf7acf60e,
+ 0x03880986,
+ 0xfa1d042a,
+ 0x0bdb03a7,
+ 0x085408a0,
+ 0x00faf8fb,
+ 0x05e30000,
+ 0xff06f8fb,
+ 0x0854f760,
+ 0xf42503a7,
+ 0xfa1dfbd6,
+ 0xfc780986,
+ 0xf7ac09f2,
+ 0x075af89a,
+ 0x05e3fa1d,
+ 0xf8a60766,
+ 0xf7ac09f2,
+ 0x0388f67a,
+ 0xfa1dfbd6,
+ 0x0bdbfc59,
+ 0x0854f760,
+ 0x00fa0705,
+ 0xfa58fa58,
+ 0xf8f0fe00,
+ 0x0448073d,
+ 0xfdc9fe46,
+ 0xf9910258,
+ 0x089d0407,
+ 0xfd5cf71a,
+ 0x02affde0,
+ 0x083e0496,
+ 0xff5a0740,
+ 0xff7afd97,
+ 0x00fe01f1,
+ 0x0009082e,
+ 0xfa94ff75,
+ 0xfecdf8ea,
+ 0xffb0f693,
+ 0xfd2cfa58,
+ 0x0433ff16,
+ 0xfba405dd,
+ 0xfa610341,
+ 0x06a606cb,
+ 0x0039fd2d,
+ 0x0677fa97,
+ 0x01fa05e0,
+ 0xf896003e,
+ 0x075a068b,
+ 0x012cfc3e,
+ 0xfa23f98d,
+ 0xfc7cfd43,
+ 0xff90fc0d,
+ 0x01c10982,
+ 0x00c601d6,
+ 0xfd2cfd2c,
+ 0x01d600c6,
+ 0x098201c1,
+ 0xfc0dff90,
+ 0xfd43fc7c,
+ 0xf98dfa23,
+ 0xfc3e012c,
+ 0x068b075a,
+ 0x003ef896,
+ 0x05e001fa,
+ 0xfa970677,
+ 0xfd2d0039,
+ 0x06cb06a6,
+ 0x0341fa61,
+ 0x05ddfba4,
+ 0xff160433,
+ 0xfa58fd2c,
+ 0xf693ffb0,
+ 0xf8eafecd,
+ 0xff75fa94,
+ 0x082e0009,
+ 0x01f100fe,
+ 0xfd97ff7a,
+ 0x0740ff5a,
+ 0x0496083e,
+ 0xfde002af,
+ 0xf71afd5c,
+ 0x0407089d,
+ 0x0258f991,
+ 0xfe46fdc9,
+ 0x073d0448,
+ 0xfe00f8f0,
+ 0xfd2cfd2c,
+ 0xfce00500,
+ 0xfc09fddc,
+ 0xfe680157,
+ 0x04c70571,
+ 0xfc3aff21,
+ 0xfcd70228,
+ 0x056d0277,
+ 0x0200fe00,
+ 0x0022f927,
+ 0xfe3c032b,
+ 0xfc44ff3c,
+ 0x03e9fbdb,
+ 0x04570313,
+ 0x04c9ff5c,
+ 0x000d03b8,
+ 0xfa580000,
+ 0xfbe900d2,
+ 0xf9d0fe0b,
+ 0x0125fdf9,
+ 0x042501bf,
+ 0x0328fa2b,
+ 0xffa902f0,
+ 0xfa250157,
+ 0x0200fe00,
+ 0x03740438,
+ 0xff0405fd,
+ 0x030cfe52,
+ 0x0037fb39,
+ 0xff6904c5,
+ 0x04f8fd23,
+ 0xfd31fc1b,
+ 0xfd2cfd2c,
+ 0xfc1bfd31,
+ 0xfd2304f8,
+ 0x04c5ff69,
+ 0xfb390037,
+ 0xfe52030c,
+ 0x05fdff04,
+ 0x04380374,
+ 0xfe000200,
+ 0x0157fa25,
+ 0x02f0ffa9,
+ 0xfa2b0328,
+ 0x01bf0425,
+ 0xfdf90125,
+ 0xfe0bf9d0,
+ 0x00d2fbe9,
+ 0x0000fa58,
+ 0x03b8000d,
+ 0xff5c04c9,
+ 0x03130457,
+ 0xfbdb03e9,
+ 0xff3cfc44,
+ 0x032bfe3c,
+ 0xf9270022,
+ 0xfe000200,
+ 0x0277056d,
+ 0x0228fcd7,
+ 0xff21fc3a,
+ 0x057104c7,
+ 0x0157fe68,
+ 0xfddcfc09,
+ 0x0500fce0,
+ 0xfd2cfd2c,
+ 0x0500fce0,
+ 0xfddcfc09,
+ 0x0157fe68,
+ 0x057104c7,
+ 0xff21fc3a,
+ 0x0228fcd7,
+ 0x0277056d,
+ 0xfe000200,
+ 0xf9270022,
+ 0x032bfe3c,
+ 0xff3cfc44,
+ 0xfbdb03e9,
+ 0x03130457,
+ 0xff5c04c9,
+ 0x03b8000d,
+ 0x0000fa58,
+ 0x00d2fbe9,
+ 0xfe0bf9d0,
+ 0xfdf90125,
+ 0x01bf0425,
+ 0xfa2b0328,
+ 0x02f0ffa9,
+ 0x0157fa25,
+ 0xfe000200,
+ 0x04380374,
+ 0x05fdff04,
+ 0xfe52030c,
+ 0xfb390037,
+ 0x04c5ff69,
+ 0xfd2304f8,
+ 0xfc1bfd31,
+ 0xfd2cfd2c,
+ 0xfd31fc1b,
+ 0x04f8fd23,
+ 0xff6904c5,
+ 0x0037fb39,
+ 0x030cfe52,
+ 0xff0405fd,
+ 0x03740438,
+ 0x0200fe00,
+ 0xfa250157,
+ 0xffa902f0,
+ 0x0328fa2b,
+ 0x042501bf,
+ 0x0125fdf9,
+ 0xf9d0fe0b,
+ 0xfbe900d2,
+ 0xfa580000,
+ 0x000d03b8,
+ 0x04c9ff5c,
+ 0x04570313,
+ 0x03e9fbdb,
+ 0xfc44ff3c,
+ 0xfe3c032b,
+ 0x0022f927,
+ 0x0200fe00,
+ 0x056d0277,
+ 0xfcd70228,
+ 0xfc3aff21,
+ 0x04c70571,
+ 0xfe680157,
+ 0xfc09fddc,
+ 0xfce00500,
+ 0x05a80000,
+ 0xff1006be,
+ 0x0800084a,
+ 0xf49cfc7e,
+ 0xfa580400,
+ 0xfc9cf6da,
+ 0xf800f672,
+ 0x0710071c,
+ 0x05a805a8,
+ 0xf8f0f8e4,
+ 0xf800f672,
+ 0x03640926,
+ 0xfa580400,
+ 0x0b640382,
+ 0x0800084a,
+ 0x00f0f942,
+ 0x05a80000,
+ 0xff10f942,
+ 0x0800f7b6,
+ 0xf49c0382,
+ 0xfa58fc00,
+ 0xfc9c0926,
+ 0xf800098e,
+ 0x0710f8e4,
+ 0x05a8fa58,
+ 0xf8f0071c,
+ 0xf800098e,
+ 0x0364f6da,
+ 0xfa58fc00,
+ 0x0b64fc7e,
+ 0x0800f7b6,
+ 0x00f006be,
+ 0x05a80000,
+ 0xff1006be,
+ 0x0800084a,
+ 0xf49cfc7e,
+ 0xfa580400,
+ 0xfc9cf6da,
+ 0xf800f672,
+ 0x0710071c,
+ 0x05a805a8,
+ 0xf8f0f8e4,
+ 0xf800f672,
+ 0x03640926,
+ 0xfa580400,
+ 0x0b640382,
+ 0x0800084a,
+ 0x00f0f942,
+ 0x05a80000,
+ 0xff10f942,
+ 0x0800f7b6,
+ 0xf49c0382,
+ 0xfa58fc00,
+ 0xfc9c0926,
+ 0xf800098e,
+ 0x0710f8e4,
+ 0x05a8fa58,
+ 0xf8f0071c,
+ 0xf800098e,
+ 0x0364f6da,
+ 0xfa58fc00,
+ 0x0b64fc7e,
+ 0x0800f7b6,
+ 0x00f006be,
+};
+
+CONST uint32 intlv_tbl_rev0[] = {
+ 0x00802070,
+ 0x0671188d,
+ 0x0a60192c,
+ 0x0a300e46,
+ 0x00c1188d,
+ 0x080024d2,
+ 0x00000070,
+};
+
+CONST uint16 pilot_tbl_rev0[] = {
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0xff0a,
+ 0xff82,
+ 0xffa0,
+ 0xff28,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xff82,
+ 0xffa0,
+ 0xff28,
+ 0xff0a,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xf83f,
+ 0xfa1f,
+ 0xfa97,
+ 0xfab5,
+ 0xf2bd,
+ 0xf0bf,
+ 0xffff,
+ 0xffff,
+ 0xf017,
+ 0xf815,
+ 0xf215,
+ 0xf095,
+ 0xf035,
+ 0xf01d,
+ 0xffff,
+ 0xffff,
+ 0xff08,
+ 0xff02,
+ 0xff80,
+ 0xff20,
+ 0xff08,
+ 0xff02,
+ 0xff80,
+ 0xff20,
+ 0xf01f,
+ 0xf817,
+ 0xfa15,
+ 0xf295,
+ 0xf0b5,
+ 0xf03d,
+ 0xffff,
+ 0xffff,
+ 0xf82a,
+ 0xfa0a,
+ 0xfa82,
+ 0xfaa0,
+ 0xf2a8,
+ 0xf0aa,
+ 0xffff,
+ 0xffff,
+ 0xf002,
+ 0xf800,
+ 0xf200,
+ 0xf080,
+ 0xf020,
+ 0xf008,
+ 0xffff,
+ 0xffff,
+ 0xf00a,
+ 0xf802,
+ 0xfa00,
+ 0xf280,
+ 0xf0a0,
+ 0xf028,
+ 0xffff,
+ 0xffff,
+};
+
+CONST uint32 pltlut_tbl_rev0[] = {
+ 0x76540123,
+ 0x62407351,
+ 0x76543201,
+ 0x76540213,
+ 0x76540123,
+ 0x76430521,
+};
+
+CONST uint32 tdi_tbl20_ant0_rev0[] = {
+ 0x00091226,
+ 0x000a1429,
+ 0x000b56ad,
+ 0x000c58b0,
+ 0x000d5ab3,
+ 0x000e9cb6,
+ 0x000f9eba,
+ 0x0000c13d,
+ 0x00020301,
+ 0x00030504,
+ 0x00040708,
+ 0x0005090b,
+ 0x00064b8e,
+ 0x00095291,
+ 0x000a5494,
+ 0x000b9718,
+ 0x000c9927,
+ 0x000d9b2a,
+ 0x000edd2e,
+ 0x000fdf31,
+ 0x000101b4,
+ 0x000243b7,
+ 0x000345bb,
+ 0x000447be,
+ 0x00058982,
+ 0x00068c05,
+ 0x00099309,
+ 0x000a950c,
+ 0x000bd78f,
+ 0x000cd992,
+ 0x000ddb96,
+ 0x000f1d99,
+ 0x00005fa8,
+ 0x0001422c,
+ 0x0002842f,
+ 0x00038632,
+ 0x00048835,
+ 0x0005ca38,
+ 0x0006ccbc,
+ 0x0009d3bf,
+ 0x000b1603,
+ 0x000c1806,
+ 0x000d1a0a,
+ 0x000e1c0d,
+ 0x000f5e10,
+ 0x00008093,
+ 0x00018297,
+ 0x0002c49a,
+ 0x0003c680,
+ 0x0004c880,
+ 0x00060b00,
+ 0x00070d00,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl20_ant1_rev0[] = {
+ 0x00014b26,
+ 0x00028d29,
+ 0x000393ad,
+ 0x00049630,
+ 0x0005d833,
+ 0x0006da36,
+ 0x00099c3a,
+ 0x000a9e3d,
+ 0x000bc081,
+ 0x000cc284,
+ 0x000dc488,
+ 0x000f068b,
+ 0x0000488e,
+ 0x00018b91,
+ 0x0002d214,
+ 0x0003d418,
+ 0x0004d6a7,
+ 0x000618aa,
+ 0x00071aae,
+ 0x0009dcb1,
+ 0x000b1eb4,
+ 0x000c0137,
+ 0x000d033b,
+ 0x000e053e,
+ 0x000f4702,
+ 0x00008905,
+ 0x00020c09,
+ 0x0003128c,
+ 0x0004148f,
+ 0x00051712,
+ 0x00065916,
+ 0x00091b19,
+ 0x000a1d28,
+ 0x000b5f2c,
+ 0x000c41af,
+ 0x000d43b2,
+ 0x000e85b5,
+ 0x000f87b8,
+ 0x0000c9bc,
+ 0x00024cbf,
+ 0x00035303,
+ 0x00045506,
+ 0x0005978a,
+ 0x0006998d,
+ 0x00095b90,
+ 0x000a5d93,
+ 0x000b9f97,
+ 0x000c821a,
+ 0x000d8400,
+ 0x000ec600,
+ 0x000fc800,
+ 0x00010a00,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl40_ant0_rev0[] = {
+ 0x0011a346,
+ 0x00136ccf,
+ 0x0014f5d9,
+ 0x001641e2,
+ 0x0017cb6b,
+ 0x00195475,
+ 0x001b2383,
+ 0x001cad0c,
+ 0x001e7616,
+ 0x0000821f,
+ 0x00020ba8,
+ 0x0003d4b2,
+ 0x00056447,
+ 0x00072dd0,
+ 0x0008b6da,
+ 0x000a02e3,
+ 0x000b8c6c,
+ 0x000d15f6,
+ 0x0011e484,
+ 0x0013ae0d,
+ 0x00153717,
+ 0x00168320,
+ 0x00180ca9,
+ 0x00199633,
+ 0x001b6548,
+ 0x001ceed1,
+ 0x001eb7db,
+ 0x0000c3e4,
+ 0x00024d6d,
+ 0x000416f7,
+ 0x0005a585,
+ 0x00076f0f,
+ 0x0008f818,
+ 0x000a4421,
+ 0x000bcdab,
+ 0x000d9734,
+ 0x00122649,
+ 0x0013efd2,
+ 0x001578dc,
+ 0x0016c4e5,
+ 0x00184e6e,
+ 0x001a17f8,
+ 0x001ba686,
+ 0x001d3010,
+ 0x001ef999,
+ 0x00010522,
+ 0x00028eac,
+ 0x00045835,
+ 0x0005e74a,
+ 0x0007b0d3,
+ 0x00093a5d,
+ 0x000a85e6,
+ 0x000c0f6f,
+ 0x000dd8f9,
+ 0x00126787,
+ 0x00143111,
+ 0x0015ba9a,
+ 0x00170623,
+ 0x00188fad,
+ 0x001a5936,
+ 0x001be84b,
+ 0x001db1d4,
+ 0x001f3b5e,
+ 0x000146e7,
+ 0x00031070,
+ 0x000499fa,
+ 0x00062888,
+ 0x0007f212,
+ 0x00097b9b,
+ 0x000ac7a4,
+ 0x000c50ae,
+ 0x000e1a37,
+ 0x0012a94c,
+ 0x001472d5,
+ 0x0015fc5f,
+ 0x00174868,
+ 0x0018d171,
+ 0x001a9afb,
+ 0x001c2989,
+ 0x001df313,
+ 0x001f7c9c,
+ 0x000188a5,
+ 0x000351af,
+ 0x0004db38,
+ 0x0006aa4d,
+ 0x000833d7,
+ 0x0009bd60,
+ 0x000b0969,
+ 0x000c9273,
+ 0x000e5bfc,
+ 0x00132a8a,
+ 0x0014b414,
+ 0x00163d9d,
+ 0x001789a6,
+ 0x001912b0,
+ 0x001adc39,
+ 0x001c6bce,
+ 0x001e34d8,
+ 0x001fbe61,
+ 0x0001ca6a,
+ 0x00039374,
+ 0x00051cfd,
+ 0x0006ec0b,
+ 0x00087515,
+ 0x0009fe9e,
+ 0x000b4aa7,
+ 0x000cd3b1,
+ 0x000e9d3a,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl40_ant1_rev0[] = {
+ 0x001edb36,
+ 0x000129ca,
+ 0x0002b353,
+ 0x00047cdd,
+ 0x0005c8e6,
+ 0x000791ef,
+ 0x00091bf9,
+ 0x000aaa07,
+ 0x000c3391,
+ 0x000dfd1a,
+ 0x00120923,
+ 0x0013d22d,
+ 0x00155c37,
+ 0x0016eacb,
+ 0x00187454,
+ 0x001a3dde,
+ 0x001b89e7,
+ 0x001d12f0,
+ 0x001f1cfa,
+ 0x00016b88,
+ 0x00033492,
+ 0x0004be1b,
+ 0x00060a24,
+ 0x0007d32e,
+ 0x00095d38,
+ 0x000aec4c,
+ 0x000c7555,
+ 0x000e3edf,
+ 0x00124ae8,
+ 0x001413f1,
+ 0x0015a37b,
+ 0x00172c89,
+ 0x0018b593,
+ 0x001a419c,
+ 0x001bcb25,
+ 0x001d942f,
+ 0x001f63b9,
+ 0x0001ad4d,
+ 0x00037657,
+ 0x0004c260,
+ 0x00068be9,
+ 0x000814f3,
+ 0x0009a47c,
+ 0x000b2d8a,
+ 0x000cb694,
+ 0x000e429d,
+ 0x00128c26,
+ 0x001455b0,
+ 0x0015e4ba,
+ 0x00176e4e,
+ 0x0018f758,
+ 0x001a8361,
+ 0x001c0cea,
+ 0x001dd674,
+ 0x001fa57d,
+ 0x0001ee8b,
+ 0x0003b795,
+ 0x0005039e,
+ 0x0006cd27,
+ 0x000856b1,
+ 0x0009e5c6,
+ 0x000b6f4f,
+ 0x000cf859,
+ 0x000e8462,
+ 0x00130deb,
+ 0x00149775,
+ 0x00162603,
+ 0x0017af8c,
+ 0x00193896,
+ 0x001ac49f,
+ 0x001c4e28,
+ 0x001e17b2,
+ 0x0000a6c7,
+ 0x00023050,
+ 0x0003f9da,
+ 0x00054563,
+ 0x00070eec,
+ 0x00089876,
+ 0x000a2704,
+ 0x000bb08d,
+ 0x000d3a17,
+ 0x001185a0,
+ 0x00134f29,
+ 0x0014d8b3,
+ 0x001667c8,
+ 0x0017f151,
+ 0x00197adb,
+ 0x001b0664,
+ 0x001c8fed,
+ 0x001e5977,
+ 0x0000e805,
+ 0x0002718f,
+ 0x00043b18,
+ 0x000586a1,
+ 0x0007502b,
+ 0x0008d9b4,
+ 0x000a68c9,
+ 0x000bf252,
+ 0x000dbbdc,
+ 0x0011c7e5,
+ 0x001390ee,
+ 0x00151a78,
+ 0x0016a906,
+ 0x00183290,
+ 0x0019bc19,
+ 0x001b4822,
+ 0x001cd12c,
+ 0x001e9ab5,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint16 bdi_tbl_rev0[] = {
+ 0x0070,
+ 0x0126,
+ 0x012c,
+ 0x0246,
+ 0x048d,
+ 0x04d2,
+};
+
+CONST uint32 chanest_tbl_rev0[] = {
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+};
+
+CONST uint8 mcs_tbl_rev0[] = {
+ 0x00,
+ 0x08,
+ 0x0a,
+ 0x10,
+ 0x12,
+ 0x19,
+ 0x1a,
+ 0x1c,
+ 0x40,
+ 0x48,
+ 0x4a,
+ 0x50,
+ 0x52,
+ 0x59,
+ 0x5a,
+ 0x5c,
+ 0x80,
+ 0x88,
+ 0x8a,
+ 0x90,
+ 0x92,
+ 0x99,
+ 0x9a,
+ 0x9c,
+ 0xc0,
+ 0xc8,
+ 0xca,
+ 0xd0,
+ 0xd2,
+ 0xd9,
+ 0xda,
+ 0xdc,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x09,
+ 0x0a,
+ 0x0c,
+ 0x10,
+ 0x11,
+ 0x12,
+ 0x14,
+ 0x18,
+ 0x19,
+ 0x1a,
+ 0x1c,
+ 0x20,
+ 0x21,
+ 0x22,
+ 0x24,
+ 0x40,
+ 0x41,
+ 0x42,
+ 0x44,
+ 0x48,
+ 0x49,
+ 0x4a,
+ 0x4c,
+ 0x50,
+ 0x51,
+ 0x52,
+ 0x54,
+ 0x58,
+ 0x59,
+ 0x5a,
+ 0x5c,
+ 0x60,
+ 0x61,
+ 0x62,
+ 0x64,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+CONST uint32 noise_var_tbl0_rev0[] = {
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+};
+
+CONST uint32 noise_var_tbl1_rev0[] = {
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+};
+
+CONST uint8 est_pwr_lut_core0_rev0[] = {
+ 0x50,
+ 0x4f,
+ 0x4e,
+ 0x4d,
+ 0x4c,
+ 0x4b,
+ 0x4a,
+ 0x49,
+ 0x48,
+ 0x47,
+ 0x46,
+ 0x45,
+ 0x44,
+ 0x43,
+ 0x42,
+ 0x41,
+ 0x40,
+ 0x3f,
+ 0x3e,
+ 0x3d,
+ 0x3c,
+ 0x3b,
+ 0x3a,
+ 0x39,
+ 0x38,
+ 0x37,
+ 0x36,
+ 0x35,
+ 0x34,
+ 0x33,
+ 0x32,
+ 0x31,
+ 0x30,
+ 0x2f,
+ 0x2e,
+ 0x2d,
+ 0x2c,
+ 0x2b,
+ 0x2a,
+ 0x29,
+ 0x28,
+ 0x27,
+ 0x26,
+ 0x25,
+ 0x24,
+ 0x23,
+ 0x22,
+ 0x21,
+ 0x20,
+ 0x1f,
+ 0x1e,
+ 0x1d,
+ 0x1c,
+ 0x1b,
+ 0x1a,
+ 0x19,
+ 0x18,
+ 0x17,
+ 0x16,
+ 0x15,
+ 0x14,
+ 0x13,
+ 0x12,
+ 0x11,
+};
+
+CONST uint8 est_pwr_lut_core1_rev0[] = {
+ 0x50,
+ 0x4f,
+ 0x4e,
+ 0x4d,
+ 0x4c,
+ 0x4b,
+ 0x4a,
+ 0x49,
+ 0x48,
+ 0x47,
+ 0x46,
+ 0x45,
+ 0x44,
+ 0x43,
+ 0x42,
+ 0x41,
+ 0x40,
+ 0x3f,
+ 0x3e,
+ 0x3d,
+ 0x3c,
+ 0x3b,
+ 0x3a,
+ 0x39,
+ 0x38,
+ 0x37,
+ 0x36,
+ 0x35,
+ 0x34,
+ 0x33,
+ 0x32,
+ 0x31,
+ 0x30,
+ 0x2f,
+ 0x2e,
+ 0x2d,
+ 0x2c,
+ 0x2b,
+ 0x2a,
+ 0x29,
+ 0x28,
+ 0x27,
+ 0x26,
+ 0x25,
+ 0x24,
+ 0x23,
+ 0x22,
+ 0x21,
+ 0x20,
+ 0x1f,
+ 0x1e,
+ 0x1d,
+ 0x1c,
+ 0x1b,
+ 0x1a,
+ 0x19,
+ 0x18,
+ 0x17,
+ 0x16,
+ 0x15,
+ 0x14,
+ 0x13,
+ 0x12,
+ 0x11,
+};
+
+CONST uint8 adj_pwr_lut_core0_rev0[] = {
+ 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,
+ 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,
+ 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,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+CONST uint8 adj_pwr_lut_core1_rev0[] = {
+ 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,
+ 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,
+ 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,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+CONST uint32 gainctrl_lut_core0_rev0[] = {
+ 0x03cc2b44,
+ 0x03cc2b42,
+ 0x03cc2b40,
+ 0x03cc2b3e,
+ 0x03cc2b3d,
+ 0x03cc2b3b,
+ 0x03c82b44,
+ 0x03c82b42,
+ 0x03c82b40,
+ 0x03c82b3e,
+ 0x03c82b3d,
+ 0x03c82b3b,
+ 0x03c82b39,
+ 0x03c82b38,
+ 0x03c82b36,
+ 0x03c82b34,
+ 0x03c42b44,
+ 0x03c42b42,
+ 0x03c42b40,
+ 0x03c42b3e,
+ 0x03c42b3d,
+ 0x03c42b3b,
+ 0x03c42b39,
+ 0x03c42b38,
+ 0x03c42b36,
+ 0x03c42b34,
+ 0x03c42b33,
+ 0x03c42b32,
+ 0x03c42b30,
+ 0x03c42b2f,
+ 0x03c42b2d,
+ 0x03c02b44,
+ 0x03c02b42,
+ 0x03c02b40,
+ 0x03c02b3e,
+ 0x03c02b3d,
+ 0x03c02b3b,
+ 0x03c02b39,
+ 0x03c02b38,
+ 0x03c02b36,
+ 0x03c02b34,
+ 0x03b02b44,
+ 0x03b02b42,
+ 0x03b02b40,
+ 0x03b02b3e,
+ 0x03b02b3d,
+ 0x03b02b3b,
+ 0x03b02b39,
+ 0x03b02b38,
+ 0x03b02b36,
+ 0x03b02b34,
+ 0x03b02b33,
+ 0x03b02b32,
+ 0x03b02b30,
+ 0x03b02b2f,
+ 0x03b02b2d,
+ 0x03a02b44,
+ 0x03a02b42,
+ 0x03a02b40,
+ 0x03a02b3e,
+ 0x03a02b3d,
+ 0x03a02b3b,
+ 0x03a02b39,
+ 0x03a02b38,
+ 0x03a02b36,
+ 0x03a02b34,
+ 0x03902b44,
+ 0x03902b42,
+ 0x03902b40,
+ 0x03902b3e,
+ 0x03902b3d,
+ 0x03902b3b,
+ 0x03902b39,
+ 0x03902b38,
+ 0x03902b36,
+ 0x03902b34,
+ 0x03902b33,
+ 0x03902b32,
+ 0x03902b30,
+ 0x03802b44,
+ 0x03802b42,
+ 0x03802b40,
+ 0x03802b3e,
+ 0x03802b3d,
+ 0x03802b3b,
+ 0x03802b39,
+ 0x03802b38,
+ 0x03802b36,
+ 0x03802b34,
+ 0x03802b33,
+ 0x03802b32,
+ 0x03802b30,
+ 0x03802b2f,
+ 0x03802b2d,
+ 0x03802b2c,
+ 0x03802b2b,
+ 0x03802b2a,
+ 0x03802b29,
+ 0x03802b27,
+ 0x03802b26,
+ 0x03802b25,
+ 0x03802b24,
+ 0x03802b23,
+ 0x03802b22,
+ 0x03802b21,
+ 0x03802b20,
+ 0x03802b1f,
+ 0x03802b1e,
+ 0x03802b1e,
+ 0x03802b1d,
+ 0x03802b1c,
+ 0x03802b1b,
+ 0x03802b1a,
+ 0x03802b1a,
+ 0x03802b19,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x00002b00,
+};
+
+CONST uint32 gainctrl_lut_core1_rev0[] = {
+ 0x03cc2b44,
+ 0x03cc2b42,
+ 0x03cc2b40,
+ 0x03cc2b3e,
+ 0x03cc2b3d,
+ 0x03cc2b3b,
+ 0x03c82b44,
+ 0x03c82b42,
+ 0x03c82b40,
+ 0x03c82b3e,
+ 0x03c82b3d,
+ 0x03c82b3b,
+ 0x03c82b39,
+ 0x03c82b38,
+ 0x03c82b36,
+ 0x03c82b34,
+ 0x03c42b44,
+ 0x03c42b42,
+ 0x03c42b40,
+ 0x03c42b3e,
+ 0x03c42b3d,
+ 0x03c42b3b,
+ 0x03c42b39,
+ 0x03c42b38,
+ 0x03c42b36,
+ 0x03c42b34,
+ 0x03c42b33,
+ 0x03c42b32,
+ 0x03c42b30,
+ 0x03c42b2f,
+ 0x03c42b2d,
+ 0x03c02b44,
+ 0x03c02b42,
+ 0x03c02b40,
+ 0x03c02b3e,
+ 0x03c02b3d,
+ 0x03c02b3b,
+ 0x03c02b39,
+ 0x03c02b38,
+ 0x03c02b36,
+ 0x03c02b34,
+ 0x03b02b44,
+ 0x03b02b42,
+ 0x03b02b40,
+ 0x03b02b3e,
+ 0x03b02b3d,
+ 0x03b02b3b,
+ 0x03b02b39,
+ 0x03b02b38,
+ 0x03b02b36,
+ 0x03b02b34,
+ 0x03b02b33,
+ 0x03b02b32,
+ 0x03b02b30,
+ 0x03b02b2f,
+ 0x03b02b2d,
+ 0x03a02b44,
+ 0x03a02b42,
+ 0x03a02b40,
+ 0x03a02b3e,
+ 0x03a02b3d,
+ 0x03a02b3b,
+ 0x03a02b39,
+ 0x03a02b38,
+ 0x03a02b36,
+ 0x03a02b34,
+ 0x03902b44,
+ 0x03902b42,
+ 0x03902b40,
+ 0x03902b3e,
+ 0x03902b3d,
+ 0x03902b3b,
+ 0x03902b39,
+ 0x03902b38,
+ 0x03902b36,
+ 0x03902b34,
+ 0x03902b33,
+ 0x03902b32,
+ 0x03902b30,
+ 0x03802b44,
+ 0x03802b42,
+ 0x03802b40,
+ 0x03802b3e,
+ 0x03802b3d,
+ 0x03802b3b,
+ 0x03802b39,
+ 0x03802b38,
+ 0x03802b36,
+ 0x03802b34,
+ 0x03802b33,
+ 0x03802b32,
+ 0x03802b30,
+ 0x03802b2f,
+ 0x03802b2d,
+ 0x03802b2c,
+ 0x03802b2b,
+ 0x03802b2a,
+ 0x03802b29,
+ 0x03802b27,
+ 0x03802b26,
+ 0x03802b25,
+ 0x03802b24,
+ 0x03802b23,
+ 0x03802b22,
+ 0x03802b21,
+ 0x03802b20,
+ 0x03802b1f,
+ 0x03802b1e,
+ 0x03802b1e,
+ 0x03802b1d,
+ 0x03802b1c,
+ 0x03802b1b,
+ 0x03802b1a,
+ 0x03802b1a,
+ 0x03802b19,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x03802b18,
+ 0x00002b00,
+};
+
+CONST uint32 iq_lut_core0_rev0[] = {
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+};
+
+CONST uint32 iq_lut_core1_rev0[] = {
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+ 0x0000007f,
+};
+
+CONST uint16 loft_lut_core0_rev0[] = {
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+};
+
+CONST uint16 loft_lut_core1_rev0[] = {
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+ 0x0000,
+ 0x0101,
+ 0x0002,
+ 0x0103,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev0_volatile[] = {
+ {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
+ 16}
+ ,
+ {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
+ 20, 0, 32}
+ ,
+ {&gainctrl_lut_core0_rev0,
+ sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
+ 26, 192, 32}
+ ,
+ {&gainctrl_lut_core1_rev0,
+ sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
+ 27, 192, 32}
+ ,
+
+ {&est_pwr_lut_core0_rev0,
+ sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
+ 0, 8}
+ ,
+ {&est_pwr_lut_core1_rev0,
+ sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
+ 0, 8}
+ ,
+ {&adj_pwr_lut_core0_rev0,
+ sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
+ 64, 8}
+ ,
+ {&adj_pwr_lut_core1_rev0,
+ sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
+ 64, 8}
+ ,
+ {&iq_lut_core0_rev0,
+ sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
+ ,
+ {&iq_lut_core1_rev0,
+ sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
+ ,
+ {&loft_lut_core0_rev0,
+ sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
+ 16}
+ ,
+ {&loft_lut_core1_rev0,
+ sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
+ 16}
+ ,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev0[] = {
+ {&frame_struct_rev0,
+ sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
+ ,
+ {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
+ 24, 0, 8}
+ ,
+ {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
+ 0, 32}
+ ,
+ {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
+ 14, 0, 32}
+ ,
+ {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
+ 13, 0, 32}
+ ,
+ {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
+ 11, 0, 16}
+ ,
+ {&tdi_tbl20_ant0_rev0,
+ sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
+ 32}
+ ,
+ {&tdi_tbl20_ant1_rev0,
+ sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
+ 32}
+ ,
+ {&tdi_tbl40_ant0_rev0,
+ sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
+ 32}
+ ,
+ {&tdi_tbl40_ant1_rev0,
+ sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
+ 32}
+ ,
+ {&chanest_tbl_rev0,
+ sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
+ ,
+ {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8}
+ ,
+ {&noise_var_tbl0_rev0,
+ sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
+ 32}
+ ,
+ {&noise_var_tbl1_rev0,
+ sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
+ 32}
+ ,
+};
+
+CONST uint32 mimophytbl_info_sz_rev0 =
+ sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
+CONST uint32 mimophytbl_info_sz_rev0_volatile =
+ sizeof(mimophytbl_info_rev0_volatile) /
+ sizeof(mimophytbl_info_rev0_volatile[0]);
+
+CONST uint16 ant_swctrl_tbl_rev3[] = {
+ 0x0082,
+ 0x0082,
+ 0x0211,
+ 0x0222,
+ 0x0328,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0144,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0188,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0082,
+ 0x0082,
+ 0x0211,
+ 0x0222,
+ 0x0328,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0144,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0188,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint16 ant_swctrl_tbl_rev3_1[] = {
+ 0x0022,
+ 0x0022,
+ 0x0011,
+ 0x0022,
+ 0x0022,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0011,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0022,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0022,
+ 0x0022,
+ 0x0011,
+ 0x0022,
+ 0x0022,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0011,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0022,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint16 ant_swctrl_tbl_rev3_2[] = {
+ 0x0088,
+ 0x0088,
+ 0x0044,
+ 0x0088,
+ 0x0088,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0044,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0088,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0088,
+ 0x0088,
+ 0x0044,
+ 0x0088,
+ 0x0088,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0044,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0088,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint16 ant_swctrl_tbl_rev3_3[] = {
+ 0x022,
+ 0x022,
+ 0x011,
+ 0x022,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x011,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x022,
+ 0x000,
+ 0x000,
+ 0x3cc,
+ 0x022,
+ 0x022,
+ 0x011,
+ 0x022,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x011,
+ 0x000,
+ 0x000,
+ 0x000,
+ 0x022,
+ 0x000,
+ 0x000,
+ 0x3cc
+};
+
+CONST uint32 frame_struct_rev3[] = {
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x09804506,
+ 0x00100030,
+ 0x09804507,
+ 0x00100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a0c,
+ 0x00100004,
+ 0x01000a0d,
+ 0x00100024,
+ 0x0980450e,
+ 0x00100034,
+ 0x0980450f,
+ 0x00100034,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a04,
+ 0x00100000,
+ 0x11008a05,
+ 0x00100020,
+ 0x1980c506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x01800504,
+ 0x00100030,
+ 0x11808505,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000a04,
+ 0x00100000,
+ 0x11008a05,
+ 0x00100020,
+ 0x21810506,
+ 0x00100030,
+ 0x21810506,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x1980c50e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x0180050c,
+ 0x00100038,
+ 0x1180850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x1980c506,
+ 0x00100030,
+ 0x1980c506,
+ 0x00100030,
+ 0x11808504,
+ 0x00100030,
+ 0x3981ca05,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x10008a04,
+ 0x00100000,
+ 0x3981ca05,
+ 0x00100030,
+ 0x1980c506,
+ 0x00100030,
+ 0x29814507,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a0c,
+ 0x00100008,
+ 0x01000a0d,
+ 0x00100028,
+ 0x1980c50e,
+ 0x00100038,
+ 0x1980c50e,
+ 0x00100038,
+ 0x1180850c,
+ 0x00100038,
+ 0x3981ca0d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x10008a0c,
+ 0x00100008,
+ 0x3981ca0d,
+ 0x00100038,
+ 0x1980c50e,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x02001405,
+ 0x00100040,
+ 0x0b004a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x43020a04,
+ 0x00100060,
+ 0x1b00ca05,
+ 0x00100060,
+ 0x23010a07,
+ 0x01500060,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x13008a06,
+ 0x01900060,
+ 0x13008a06,
+ 0x01900060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x0200140d,
+ 0x00100050,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x50029404,
+ 0x00100000,
+ 0x32019405,
+ 0x00100040,
+ 0x0b004a06,
+ 0x01900060,
+ 0x0b004a06,
+ 0x01900060,
+ 0x5b02ca04,
+ 0x00100060,
+ 0x3b01d405,
+ 0x00100060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x5802d404,
+ 0x00100000,
+ 0x3b01d405,
+ 0x00100060,
+ 0x0b004a06,
+ 0x01900060,
+ 0x23010a07,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x5002940c,
+ 0x00100010,
+ 0x3201940d,
+ 0x00100050,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x5b02ca0c,
+ 0x00100070,
+ 0x3b01d40d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x5802d40c,
+ 0x00100010,
+ 0x3b01d40d,
+ 0x00100070,
+ 0x0b004a0e,
+ 0x01900070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x000f4800,
+ 0x62031405,
+ 0x00100040,
+ 0x53028a06,
+ 0x01900060,
+ 0x53028a07,
+ 0x01900060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x000f4808,
+ 0x6203140d,
+ 0x00100048,
+ 0x53028a0e,
+ 0x01900068,
+ 0x53028a0f,
+ 0x01900068,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100004,
+ 0x11008a0d,
+ 0x00100024,
+ 0x1980c50e,
+ 0x00100034,
+ 0x2181050e,
+ 0x00100034,
+ 0x2181050e,
+ 0x00100034,
+ 0x0180050c,
+ 0x00100038,
+ 0x1180850d,
+ 0x00100038,
+ 0x1181850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000a0c,
+ 0x00100008,
+ 0x11008a0d,
+ 0x00100028,
+ 0x2181050e,
+ 0x00100038,
+ 0x2181050e,
+ 0x00100038,
+ 0x1181850d,
+ 0x00100038,
+ 0x2981450f,
+ 0x01100038,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x08004a04,
+ 0x00100000,
+ 0x01000a05,
+ 0x00100020,
+ 0x0180c506,
+ 0x00100030,
+ 0x0180c506,
+ 0x00100030,
+ 0x2180c50c,
+ 0x00100030,
+ 0x49820a0d,
+ 0x0016a130,
+ 0x41824a0d,
+ 0x0016a130,
+ 0x2981450f,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x2000ca0c,
+ 0x00100000,
+ 0x49820a0d,
+ 0x0016a130,
+ 0x1980c50e,
+ 0x00100030,
+ 0x41824a0d,
+ 0x0016a130,
+ 0x2981450f,
+ 0x01100030,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100008,
+ 0x0200140d,
+ 0x00100048,
+ 0x0b004a0e,
+ 0x01900068,
+ 0x13008a0e,
+ 0x01900068,
+ 0x13008a0e,
+ 0x01900068,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x1b014a0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x13008a0e,
+ 0x01900070,
+ 0x13008a0e,
+ 0x01900070,
+ 0x1b014a0d,
+ 0x00100070,
+ 0x23010a0f,
+ 0x01500070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x50029404,
+ 0x00100000,
+ 0x32019405,
+ 0x00100040,
+ 0x03004a06,
+ 0x01900060,
+ 0x03004a06,
+ 0x01900060,
+ 0x6b030a0c,
+ 0x00100060,
+ 0x4b02140d,
+ 0x0016a160,
+ 0x4302540d,
+ 0x0016a160,
+ 0x23010a0f,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x6b03140c,
+ 0x00100060,
+ 0x4b02140d,
+ 0x0016a160,
+ 0x0b004a0e,
+ 0x01900060,
+ 0x4302540d,
+ 0x0016a160,
+ 0x23010a0f,
+ 0x01500060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x53028a06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x43020a04,
+ 0x00100060,
+ 0x1b00ca05,
+ 0x00100060,
+ 0x53028a07,
+ 0x0190c060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x53028a0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x43020a0c,
+ 0x00100070,
+ 0x1b00ca0d,
+ 0x00100070,
+ 0x53028a0f,
+ 0x0190c070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x40021404,
+ 0x00100000,
+ 0x1a00d405,
+ 0x00100040,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x5b02ca06,
+ 0x01900060,
+ 0x53028a07,
+ 0x0190c060,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x4002140c,
+ 0x00100010,
+ 0x1a00d40d,
+ 0x00100050,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x5b02ca0e,
+ 0x01900070,
+ 0x53028a0f,
+ 0x0190c070,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint16 pilot_tbl_rev3[] = {
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0xff08,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0x80d5,
+ 0xff0a,
+ 0xff82,
+ 0xffa0,
+ 0xff28,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xff82,
+ 0xffa0,
+ 0xff28,
+ 0xff0a,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xf83f,
+ 0xfa1f,
+ 0xfa97,
+ 0xfab5,
+ 0xf2bd,
+ 0xf0bf,
+ 0xffff,
+ 0xffff,
+ 0xf017,
+ 0xf815,
+ 0xf215,
+ 0xf095,
+ 0xf035,
+ 0xf01d,
+ 0xffff,
+ 0xffff,
+ 0xff08,
+ 0xff02,
+ 0xff80,
+ 0xff20,
+ 0xff08,
+ 0xff02,
+ 0xff80,
+ 0xff20,
+ 0xf01f,
+ 0xf817,
+ 0xfa15,
+ 0xf295,
+ 0xf0b5,
+ 0xf03d,
+ 0xffff,
+ 0xffff,
+ 0xf82a,
+ 0xfa0a,
+ 0xfa82,
+ 0xfaa0,
+ 0xf2a8,
+ 0xf0aa,
+ 0xffff,
+ 0xffff,
+ 0xf002,
+ 0xf800,
+ 0xf200,
+ 0xf080,
+ 0xf020,
+ 0xf008,
+ 0xffff,
+ 0xffff,
+ 0xf00a,
+ 0xf802,
+ 0xfa00,
+ 0xf280,
+ 0xf0a0,
+ 0xf028,
+ 0xffff,
+ 0xffff,
+};
+
+CONST uint32 tmap_tbl_rev3[] = {
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x000aa888,
+ 0x88880000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00011111,
+ 0x11110000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00088aaa,
+ 0xaaaa0000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xaaa8aaa0,
+ 0x8aaa8aaa,
+ 0xaa8a8a8a,
+ 0x000aaa88,
+ 0x8aaa0000,
+ 0xaaa8a888,
+ 0x8aa88a8a,
+ 0x8a88a888,
+ 0x08080a00,
+ 0x0a08080a,
+ 0x080a0a08,
+ 0x00080808,
+ 0x080a0000,
+ 0x080a0808,
+ 0x080a0808,
+ 0x0a0a0a08,
+ 0xa0a0a0a0,
+ 0x80a0a080,
+ 0x8080a0a0,
+ 0x00008080,
+ 0x80a00000,
+ 0x80a080a0,
+ 0xa080a0a0,
+ 0x8080a0a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x99999000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x22000000,
+ 0x2222b222,
+ 0x22222222,
+ 0x222222b2,
+ 0xb2222220,
+ 0x22222222,
+ 0x22d22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333b333,
+ 0x33333333,
+ 0x333333b3,
+ 0xb3333330,
+ 0x33333333,
+ 0x33d33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x99b99b00,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb99,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x22222200,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0x22222222,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x11111111,
+ 0xf1111111,
+ 0x11111111,
+ 0x11f11111,
+ 0x01111111,
+ 0xbb9bb900,
+ 0xb9b9bb99,
+ 0xb99bbbbb,
+ 0xbbbb9b9b,
+ 0xb9bb99bb,
+ 0xb99999b9,
+ 0xb9b9b99b,
+ 0x00000bbb,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88aa,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x0a888aaa,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00000aaa,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0xbbbbbb00,
+ 0x999bbbbb,
+ 0x9bb99b9b,
+ 0xb9b9b9bb,
+ 0xb9b99bbb,
+ 0xb9b9b9bb,
+ 0xb9bb9b99,
+ 0x00000999,
+ 0x8a000000,
+ 0xaa88a888,
+ 0xa88888aa,
+ 0xa88a8a88,
+ 0xa88aa88a,
+ 0x88a8aaaa,
+ 0xa8aa8aaa,
+ 0x0888a88a,
+ 0x0b0b0b00,
+ 0x090b0b0b,
+ 0x0b090b0b,
+ 0x0909090b,
+ 0x09090b0b,
+ 0x09090b0b,
+ 0x09090b09,
+ 0x00000909,
+ 0x0a000000,
+ 0x0a080808,
+ 0x080a080a,
+ 0x080a0a08,
+ 0x080a080a,
+ 0x0808080a,
+ 0x0a0a0a08,
+ 0x0808080a,
+ 0xb0b0b000,
+ 0x9090b0b0,
+ 0x90b09090,
+ 0xb0b0b090,
+ 0xb0b090b0,
+ 0x90b0b0b0,
+ 0xb0b09090,
+ 0x00000090,
+ 0x80000000,
+ 0xa080a080,
+ 0xa08080a0,
+ 0xa0808080,
+ 0xa080a080,
+ 0x80a0a0a0,
+ 0xa0a080a0,
+ 0x00a0a0a0,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333f333,
+ 0x33333333,
+ 0x333333f3,
+ 0xf3333330,
+ 0x33333333,
+ 0x33f33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x99000000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88888000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x88a88a00,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 intlv_tbl_rev3[] = {
+ 0x00802070,
+ 0x0671188d,
+ 0x0a60192c,
+ 0x0a300e46,
+ 0x00c1188d,
+ 0x080024d2,
+ 0x00000070,
+};
+
+CONST uint32 tdtrn_tbl_rev3[] = {
+ 0x061c061c,
+ 0x0050ee68,
+ 0xf592fe36,
+ 0xfe5212f6,
+ 0x00000c38,
+ 0xfe5212f6,
+ 0xf592fe36,
+ 0x0050ee68,
+ 0x061c061c,
+ 0xee680050,
+ 0xfe36f592,
+ 0x12f6fe52,
+ 0x0c380000,
+ 0x12f6fe52,
+ 0xfe36f592,
+ 0xee680050,
+ 0x061c061c,
+ 0x0050ee68,
+ 0xf592fe36,
+ 0xfe5212f6,
+ 0x00000c38,
+ 0xfe5212f6,
+ 0xf592fe36,
+ 0x0050ee68,
+ 0x061c061c,
+ 0xee680050,
+ 0xfe36f592,
+ 0x12f6fe52,
+ 0x0c380000,
+ 0x12f6fe52,
+ 0xfe36f592,
+ 0xee680050,
+ 0x05e305e3,
+ 0x004def0c,
+ 0xf5f3fe47,
+ 0xfe611246,
+ 0x00000bc7,
+ 0xfe611246,
+ 0xf5f3fe47,
+ 0x004def0c,
+ 0x05e305e3,
+ 0xef0c004d,
+ 0xfe47f5f3,
+ 0x1246fe61,
+ 0x0bc70000,
+ 0x1246fe61,
+ 0xfe47f5f3,
+ 0xef0c004d,
+ 0x05e305e3,
+ 0x004def0c,
+ 0xf5f3fe47,
+ 0xfe611246,
+ 0x00000bc7,
+ 0xfe611246,
+ 0xf5f3fe47,
+ 0x004def0c,
+ 0x05e305e3,
+ 0xef0c004d,
+ 0xfe47f5f3,
+ 0x1246fe61,
+ 0x0bc70000,
+ 0x1246fe61,
+ 0xfe47f5f3,
+ 0xef0c004d,
+ 0xfa58fa58,
+ 0xf895043b,
+ 0xff4c09c0,
+ 0xfbc6ffa8,
+ 0xfb84f384,
+ 0x0798f6f9,
+ 0x05760122,
+ 0x058409f6,
+ 0x0b500000,
+ 0x05b7f542,
+ 0x08860432,
+ 0x06ddfee7,
+ 0xfb84f384,
+ 0xf9d90664,
+ 0xf7e8025c,
+ 0x00fff7bd,
+ 0x05a805a8,
+ 0xf7bd00ff,
+ 0x025cf7e8,
+ 0x0664f9d9,
+ 0xf384fb84,
+ 0xfee706dd,
+ 0x04320886,
+ 0xf54205b7,
+ 0x00000b50,
+ 0x09f60584,
+ 0x01220576,
+ 0xf6f90798,
+ 0xf384fb84,
+ 0xffa8fbc6,
+ 0x09c0ff4c,
+ 0x043bf895,
+ 0x02d402d4,
+ 0x07de0270,
+ 0xfc96079c,
+ 0xf90afe94,
+ 0xfe00ff2c,
+ 0x02d4065d,
+ 0x092a0096,
+ 0x0014fbb8,
+ 0xfd2cfd2c,
+ 0x076afb3c,
+ 0x0096f752,
+ 0xf991fd87,
+ 0xfb2c0200,
+ 0xfeb8f960,
+ 0x08e0fc96,
+ 0x049802a8,
+ 0xfd2cfd2c,
+ 0x02a80498,
+ 0xfc9608e0,
+ 0xf960feb8,
+ 0x0200fb2c,
+ 0xfd87f991,
+ 0xf7520096,
+ 0xfb3c076a,
+ 0xfd2cfd2c,
+ 0xfbb80014,
+ 0x0096092a,
+ 0x065d02d4,
+ 0xff2cfe00,
+ 0xfe94f90a,
+ 0x079cfc96,
+ 0x027007de,
+ 0x02d402d4,
+ 0x027007de,
+ 0x079cfc96,
+ 0xfe94f90a,
+ 0xff2cfe00,
+ 0x065d02d4,
+ 0x0096092a,
+ 0xfbb80014,
+ 0xfd2cfd2c,
+ 0xfb3c076a,
+ 0xf7520096,
+ 0xfd87f991,
+ 0x0200fb2c,
+ 0xf960feb8,
+ 0xfc9608e0,
+ 0x02a80498,
+ 0xfd2cfd2c,
+ 0x049802a8,
+ 0x08e0fc96,
+ 0xfeb8f960,
+ 0xfb2c0200,
+ 0xf991fd87,
+ 0x0096f752,
+ 0x076afb3c,
+ 0xfd2cfd2c,
+ 0x0014fbb8,
+ 0x092a0096,
+ 0x02d4065d,
+ 0xfe00ff2c,
+ 0xf90afe94,
+ 0xfc96079c,
+ 0x07de0270,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x062a0000,
+ 0xfefa0759,
+ 0x08b80908,
+ 0xf396fc2d,
+ 0xf9d6045c,
+ 0xfc4ef608,
+ 0xf748f596,
+ 0x07b207bf,
+ 0x062a062a,
+ 0xf84ef841,
+ 0xf748f596,
+ 0x03b209f8,
+ 0xf9d6045c,
+ 0x0c6a03d3,
+ 0x08b80908,
+ 0x0106f8a7,
+ 0x062a0000,
+ 0xfefaf8a7,
+ 0x08b8f6f8,
+ 0xf39603d3,
+ 0xf9d6fba4,
+ 0xfc4e09f8,
+ 0xf7480a6a,
+ 0x07b2f841,
+ 0x062af9d6,
+ 0xf84e07bf,
+ 0xf7480a6a,
+ 0x03b2f608,
+ 0xf9d6fba4,
+ 0x0c6afc2d,
+ 0x08b8f6f8,
+ 0x01060759,
+ 0x062a0000,
+ 0xfefa0759,
+ 0x08b80908,
+ 0xf396fc2d,
+ 0xf9d6045c,
+ 0xfc4ef608,
+ 0xf748f596,
+ 0x07b207bf,
+ 0x062a062a,
+ 0xf84ef841,
+ 0xf748f596,
+ 0x03b209f8,
+ 0xf9d6045c,
+ 0x0c6a03d3,
+ 0x08b80908,
+ 0x0106f8a7,
+ 0x062a0000,
+ 0xfefaf8a7,
+ 0x08b8f6f8,
+ 0xf39603d3,
+ 0xf9d6fba4,
+ 0xfc4e09f8,
+ 0xf7480a6a,
+ 0x07b2f841,
+ 0x062af9d6,
+ 0xf84e07bf,
+ 0xf7480a6a,
+ 0x03b2f608,
+ 0xf9d6fba4,
+ 0x0c6afc2d,
+ 0x08b8f6f8,
+ 0x01060759,
+ 0x061c061c,
+ 0xff30009d,
+ 0xffb21141,
+ 0xfd87fb54,
+ 0xf65dfe59,
+ 0x02eef99e,
+ 0x0166f03c,
+ 0xfff809b6,
+ 0x000008a4,
+ 0x000af42b,
+ 0x00eff577,
+ 0xfa840bf2,
+ 0xfc02ff51,
+ 0x08260f67,
+ 0xfff0036f,
+ 0x0842f9c3,
+ 0x00000000,
+ 0x063df7be,
+ 0xfc910010,
+ 0xf099f7da,
+ 0x00af03fe,
+ 0xf40e057c,
+ 0x0a89ff11,
+ 0x0bd5fff6,
+ 0xf75c0000,
+ 0xf64a0008,
+ 0x0fc4fe9a,
+ 0x0662fd12,
+ 0x01a709a3,
+ 0x04ac0279,
+ 0xeebf004e,
+ 0xff6300d0,
+ 0xf9e4f9e4,
+ 0x00d0ff63,
+ 0x004eeebf,
+ 0x027904ac,
+ 0x09a301a7,
+ 0xfd120662,
+ 0xfe9a0fc4,
+ 0x0008f64a,
+ 0x0000f75c,
+ 0xfff60bd5,
+ 0xff110a89,
+ 0x057cf40e,
+ 0x03fe00af,
+ 0xf7daf099,
+ 0x0010fc91,
+ 0xf7be063d,
+ 0x00000000,
+ 0xf9c30842,
+ 0x036ffff0,
+ 0x0f670826,
+ 0xff51fc02,
+ 0x0bf2fa84,
+ 0xf57700ef,
+ 0xf42b000a,
+ 0x08a40000,
+ 0x09b6fff8,
+ 0xf03c0166,
+ 0xf99e02ee,
+ 0xfe59f65d,
+ 0xfb54fd87,
+ 0x1141ffb2,
+ 0x009dff30,
+ 0x05e30000,
+ 0xff060705,
+ 0x085408a0,
+ 0xf425fc59,
+ 0xfa1d042a,
+ 0xfc78f67a,
+ 0xf7acf60e,
+ 0x075a0766,
+ 0x05e305e3,
+ 0xf8a6f89a,
+ 0xf7acf60e,
+ 0x03880986,
+ 0xfa1d042a,
+ 0x0bdb03a7,
+ 0x085408a0,
+ 0x00faf8fb,
+ 0x05e30000,
+ 0xff06f8fb,
+ 0x0854f760,
+ 0xf42503a7,
+ 0xfa1dfbd6,
+ 0xfc780986,
+ 0xf7ac09f2,
+ 0x075af89a,
+ 0x05e3fa1d,
+ 0xf8a60766,
+ 0xf7ac09f2,
+ 0x0388f67a,
+ 0xfa1dfbd6,
+ 0x0bdbfc59,
+ 0x0854f760,
+ 0x00fa0705,
+ 0x05e30000,
+ 0xff060705,
+ 0x085408a0,
+ 0xf425fc59,
+ 0xfa1d042a,
+ 0xfc78f67a,
+ 0xf7acf60e,
+ 0x075a0766,
+ 0x05e305e3,
+ 0xf8a6f89a,
+ 0xf7acf60e,
+ 0x03880986,
+ 0xfa1d042a,
+ 0x0bdb03a7,
+ 0x085408a0,
+ 0x00faf8fb,
+ 0x05e30000,
+ 0xff06f8fb,
+ 0x0854f760,
+ 0xf42503a7,
+ 0xfa1dfbd6,
+ 0xfc780986,
+ 0xf7ac09f2,
+ 0x075af89a,
+ 0x05e3fa1d,
+ 0xf8a60766,
+ 0xf7ac09f2,
+ 0x0388f67a,
+ 0xfa1dfbd6,
+ 0x0bdbfc59,
+ 0x0854f760,
+ 0x00fa0705,
+ 0xfa58fa58,
+ 0xf8f0fe00,
+ 0x0448073d,
+ 0xfdc9fe46,
+ 0xf9910258,
+ 0x089d0407,
+ 0xfd5cf71a,
+ 0x02affde0,
+ 0x083e0496,
+ 0xff5a0740,
+ 0xff7afd97,
+ 0x00fe01f1,
+ 0x0009082e,
+ 0xfa94ff75,
+ 0xfecdf8ea,
+ 0xffb0f693,
+ 0xfd2cfa58,
+ 0x0433ff16,
+ 0xfba405dd,
+ 0xfa610341,
+ 0x06a606cb,
+ 0x0039fd2d,
+ 0x0677fa97,
+ 0x01fa05e0,
+ 0xf896003e,
+ 0x075a068b,
+ 0x012cfc3e,
+ 0xfa23f98d,
+ 0xfc7cfd43,
+ 0xff90fc0d,
+ 0x01c10982,
+ 0x00c601d6,
+ 0xfd2cfd2c,
+ 0x01d600c6,
+ 0x098201c1,
+ 0xfc0dff90,
+ 0xfd43fc7c,
+ 0xf98dfa23,
+ 0xfc3e012c,
+ 0x068b075a,
+ 0x003ef896,
+ 0x05e001fa,
+ 0xfa970677,
+ 0xfd2d0039,
+ 0x06cb06a6,
+ 0x0341fa61,
+ 0x05ddfba4,
+ 0xff160433,
+ 0xfa58fd2c,
+ 0xf693ffb0,
+ 0xf8eafecd,
+ 0xff75fa94,
+ 0x082e0009,
+ 0x01f100fe,
+ 0xfd97ff7a,
+ 0x0740ff5a,
+ 0x0496083e,
+ 0xfde002af,
+ 0xf71afd5c,
+ 0x0407089d,
+ 0x0258f991,
+ 0xfe46fdc9,
+ 0x073d0448,
+ 0xfe00f8f0,
+ 0xfd2cfd2c,
+ 0xfce00500,
+ 0xfc09fddc,
+ 0xfe680157,
+ 0x04c70571,
+ 0xfc3aff21,
+ 0xfcd70228,
+ 0x056d0277,
+ 0x0200fe00,
+ 0x0022f927,
+ 0xfe3c032b,
+ 0xfc44ff3c,
+ 0x03e9fbdb,
+ 0x04570313,
+ 0x04c9ff5c,
+ 0x000d03b8,
+ 0xfa580000,
+ 0xfbe900d2,
+ 0xf9d0fe0b,
+ 0x0125fdf9,
+ 0x042501bf,
+ 0x0328fa2b,
+ 0xffa902f0,
+ 0xfa250157,
+ 0x0200fe00,
+ 0x03740438,
+ 0xff0405fd,
+ 0x030cfe52,
+ 0x0037fb39,
+ 0xff6904c5,
+ 0x04f8fd23,
+ 0xfd31fc1b,
+ 0xfd2cfd2c,
+ 0xfc1bfd31,
+ 0xfd2304f8,
+ 0x04c5ff69,
+ 0xfb390037,
+ 0xfe52030c,
+ 0x05fdff04,
+ 0x04380374,
+ 0xfe000200,
+ 0x0157fa25,
+ 0x02f0ffa9,
+ 0xfa2b0328,
+ 0x01bf0425,
+ 0xfdf90125,
+ 0xfe0bf9d0,
+ 0x00d2fbe9,
+ 0x0000fa58,
+ 0x03b8000d,
+ 0xff5c04c9,
+ 0x03130457,
+ 0xfbdb03e9,
+ 0xff3cfc44,
+ 0x032bfe3c,
+ 0xf9270022,
+ 0xfe000200,
+ 0x0277056d,
+ 0x0228fcd7,
+ 0xff21fc3a,
+ 0x057104c7,
+ 0x0157fe68,
+ 0xfddcfc09,
+ 0x0500fce0,
+ 0xfd2cfd2c,
+ 0x0500fce0,
+ 0xfddcfc09,
+ 0x0157fe68,
+ 0x057104c7,
+ 0xff21fc3a,
+ 0x0228fcd7,
+ 0x0277056d,
+ 0xfe000200,
+ 0xf9270022,
+ 0x032bfe3c,
+ 0xff3cfc44,
+ 0xfbdb03e9,
+ 0x03130457,
+ 0xff5c04c9,
+ 0x03b8000d,
+ 0x0000fa58,
+ 0x00d2fbe9,
+ 0xfe0bf9d0,
+ 0xfdf90125,
+ 0x01bf0425,
+ 0xfa2b0328,
+ 0x02f0ffa9,
+ 0x0157fa25,
+ 0xfe000200,
+ 0x04380374,
+ 0x05fdff04,
+ 0xfe52030c,
+ 0xfb390037,
+ 0x04c5ff69,
+ 0xfd2304f8,
+ 0xfc1bfd31,
+ 0xfd2cfd2c,
+ 0xfd31fc1b,
+ 0x04f8fd23,
+ 0xff6904c5,
+ 0x0037fb39,
+ 0x030cfe52,
+ 0xff0405fd,
+ 0x03740438,
+ 0x0200fe00,
+ 0xfa250157,
+ 0xffa902f0,
+ 0x0328fa2b,
+ 0x042501bf,
+ 0x0125fdf9,
+ 0xf9d0fe0b,
+ 0xfbe900d2,
+ 0xfa580000,
+ 0x000d03b8,
+ 0x04c9ff5c,
+ 0x04570313,
+ 0x03e9fbdb,
+ 0xfc44ff3c,
+ 0xfe3c032b,
+ 0x0022f927,
+ 0x0200fe00,
+ 0x056d0277,
+ 0xfcd70228,
+ 0xfc3aff21,
+ 0x04c70571,
+ 0xfe680157,
+ 0xfc09fddc,
+ 0xfce00500,
+ 0x05a80000,
+ 0xff1006be,
+ 0x0800084a,
+ 0xf49cfc7e,
+ 0xfa580400,
+ 0xfc9cf6da,
+ 0xf800f672,
+ 0x0710071c,
+ 0x05a805a8,
+ 0xf8f0f8e4,
+ 0xf800f672,
+ 0x03640926,
+ 0xfa580400,
+ 0x0b640382,
+ 0x0800084a,
+ 0x00f0f942,
+ 0x05a80000,
+ 0xff10f942,
+ 0x0800f7b6,
+ 0xf49c0382,
+ 0xfa58fc00,
+ 0xfc9c0926,
+ 0xf800098e,
+ 0x0710f8e4,
+ 0x05a8fa58,
+ 0xf8f0071c,
+ 0xf800098e,
+ 0x0364f6da,
+ 0xfa58fc00,
+ 0x0b64fc7e,
+ 0x0800f7b6,
+ 0x00f006be,
+ 0x05a80000,
+ 0xff1006be,
+ 0x0800084a,
+ 0xf49cfc7e,
+ 0xfa580400,
+ 0xfc9cf6da,
+ 0xf800f672,
+ 0x0710071c,
+ 0x05a805a8,
+ 0xf8f0f8e4,
+ 0xf800f672,
+ 0x03640926,
+ 0xfa580400,
+ 0x0b640382,
+ 0x0800084a,
+ 0x00f0f942,
+ 0x05a80000,
+ 0xff10f942,
+ 0x0800f7b6,
+ 0xf49c0382,
+ 0xfa58fc00,
+ 0xfc9c0926,
+ 0xf800098e,
+ 0x0710f8e4,
+ 0x05a8fa58,
+ 0xf8f0071c,
+ 0xf800098e,
+ 0x0364f6da,
+ 0xfa58fc00,
+ 0x0b64fc7e,
+ 0x0800f7b6,
+ 0x00f006be,
+};
+
+CONST uint32 noise_var_tbl_rev3[] = {
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+ 0x02110211,
+ 0x0000014d,
+};
+
+CONST uint16 mcs_tbl_rev3[] = {
+ 0x0000,
+ 0x0008,
+ 0x000a,
+ 0x0010,
+ 0x0012,
+ 0x0019,
+ 0x001a,
+ 0x001c,
+ 0x0080,
+ 0x0088,
+ 0x008a,
+ 0x0090,
+ 0x0092,
+ 0x0099,
+ 0x009a,
+ 0x009c,
+ 0x0100,
+ 0x0108,
+ 0x010a,
+ 0x0110,
+ 0x0112,
+ 0x0119,
+ 0x011a,
+ 0x011c,
+ 0x0180,
+ 0x0188,
+ 0x018a,
+ 0x0190,
+ 0x0192,
+ 0x0199,
+ 0x019a,
+ 0x019c,
+ 0x0000,
+ 0x0098,
+ 0x00a0,
+ 0x00a8,
+ 0x009a,
+ 0x00a2,
+ 0x00aa,
+ 0x0120,
+ 0x0128,
+ 0x0128,
+ 0x0130,
+ 0x0138,
+ 0x0138,
+ 0x0140,
+ 0x0122,
+ 0x012a,
+ 0x012a,
+ 0x0132,
+ 0x013a,
+ 0x013a,
+ 0x0142,
+ 0x01a8,
+ 0x01b0,
+ 0x01b8,
+ 0x01b0,
+ 0x01b8,
+ 0x01c0,
+ 0x01c8,
+ 0x01c0,
+ 0x01c8,
+ 0x01d0,
+ 0x01d0,
+ 0x01d8,
+ 0x01aa,
+ 0x01b2,
+ 0x01ba,
+ 0x01b2,
+ 0x01ba,
+ 0x01c2,
+ 0x01ca,
+ 0x01c2,
+ 0x01ca,
+ 0x01d2,
+ 0x01d2,
+ 0x01da,
+ 0x0001,
+ 0x0002,
+ 0x0004,
+ 0x0009,
+ 0x000c,
+ 0x0011,
+ 0x0014,
+ 0x0018,
+ 0x0020,
+ 0x0021,
+ 0x0022,
+ 0x0024,
+ 0x0081,
+ 0x0082,
+ 0x0084,
+ 0x0089,
+ 0x008c,
+ 0x0091,
+ 0x0094,
+ 0x0098,
+ 0x00a0,
+ 0x00a1,
+ 0x00a2,
+ 0x00a4,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+ 0x0007,
+};
+
+CONST uint32 tdi_tbl20_ant0_rev3[] = {
+ 0x00091226,
+ 0x000a1429,
+ 0x000b56ad,
+ 0x000c58b0,
+ 0x000d5ab3,
+ 0x000e9cb6,
+ 0x000f9eba,
+ 0x0000c13d,
+ 0x00020301,
+ 0x00030504,
+ 0x00040708,
+ 0x0005090b,
+ 0x00064b8e,
+ 0x00095291,
+ 0x000a5494,
+ 0x000b9718,
+ 0x000c9927,
+ 0x000d9b2a,
+ 0x000edd2e,
+ 0x000fdf31,
+ 0x000101b4,
+ 0x000243b7,
+ 0x000345bb,
+ 0x000447be,
+ 0x00058982,
+ 0x00068c05,
+ 0x00099309,
+ 0x000a950c,
+ 0x000bd78f,
+ 0x000cd992,
+ 0x000ddb96,
+ 0x000f1d99,
+ 0x00005fa8,
+ 0x0001422c,
+ 0x0002842f,
+ 0x00038632,
+ 0x00048835,
+ 0x0005ca38,
+ 0x0006ccbc,
+ 0x0009d3bf,
+ 0x000b1603,
+ 0x000c1806,
+ 0x000d1a0a,
+ 0x000e1c0d,
+ 0x000f5e10,
+ 0x00008093,
+ 0x00018297,
+ 0x0002c49a,
+ 0x0003c680,
+ 0x0004c880,
+ 0x00060b00,
+ 0x00070d00,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl20_ant1_rev3[] = {
+ 0x00014b26,
+ 0x00028d29,
+ 0x000393ad,
+ 0x00049630,
+ 0x0005d833,
+ 0x0006da36,
+ 0x00099c3a,
+ 0x000a9e3d,
+ 0x000bc081,
+ 0x000cc284,
+ 0x000dc488,
+ 0x000f068b,
+ 0x0000488e,
+ 0x00018b91,
+ 0x0002d214,
+ 0x0003d418,
+ 0x0004d6a7,
+ 0x000618aa,
+ 0x00071aae,
+ 0x0009dcb1,
+ 0x000b1eb4,
+ 0x000c0137,
+ 0x000d033b,
+ 0x000e053e,
+ 0x000f4702,
+ 0x00008905,
+ 0x00020c09,
+ 0x0003128c,
+ 0x0004148f,
+ 0x00051712,
+ 0x00065916,
+ 0x00091b19,
+ 0x000a1d28,
+ 0x000b5f2c,
+ 0x000c41af,
+ 0x000d43b2,
+ 0x000e85b5,
+ 0x000f87b8,
+ 0x0000c9bc,
+ 0x00024cbf,
+ 0x00035303,
+ 0x00045506,
+ 0x0005978a,
+ 0x0006998d,
+ 0x00095b90,
+ 0x000a5d93,
+ 0x000b9f97,
+ 0x000c821a,
+ 0x000d8400,
+ 0x000ec600,
+ 0x000fc800,
+ 0x00010a00,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl40_ant0_rev3[] = {
+ 0x0011a346,
+ 0x00136ccf,
+ 0x0014f5d9,
+ 0x001641e2,
+ 0x0017cb6b,
+ 0x00195475,
+ 0x001b2383,
+ 0x001cad0c,
+ 0x001e7616,
+ 0x0000821f,
+ 0x00020ba8,
+ 0x0003d4b2,
+ 0x00056447,
+ 0x00072dd0,
+ 0x0008b6da,
+ 0x000a02e3,
+ 0x000b8c6c,
+ 0x000d15f6,
+ 0x0011e484,
+ 0x0013ae0d,
+ 0x00153717,
+ 0x00168320,
+ 0x00180ca9,
+ 0x00199633,
+ 0x001b6548,
+ 0x001ceed1,
+ 0x001eb7db,
+ 0x0000c3e4,
+ 0x00024d6d,
+ 0x000416f7,
+ 0x0005a585,
+ 0x00076f0f,
+ 0x0008f818,
+ 0x000a4421,
+ 0x000bcdab,
+ 0x000d9734,
+ 0x00122649,
+ 0x0013efd2,
+ 0x001578dc,
+ 0x0016c4e5,
+ 0x00184e6e,
+ 0x001a17f8,
+ 0x001ba686,
+ 0x001d3010,
+ 0x001ef999,
+ 0x00010522,
+ 0x00028eac,
+ 0x00045835,
+ 0x0005e74a,
+ 0x0007b0d3,
+ 0x00093a5d,
+ 0x000a85e6,
+ 0x000c0f6f,
+ 0x000dd8f9,
+ 0x00126787,
+ 0x00143111,
+ 0x0015ba9a,
+ 0x00170623,
+ 0x00188fad,
+ 0x001a5936,
+ 0x001be84b,
+ 0x001db1d4,
+ 0x001f3b5e,
+ 0x000146e7,
+ 0x00031070,
+ 0x000499fa,
+ 0x00062888,
+ 0x0007f212,
+ 0x00097b9b,
+ 0x000ac7a4,
+ 0x000c50ae,
+ 0x000e1a37,
+ 0x0012a94c,
+ 0x001472d5,
+ 0x0015fc5f,
+ 0x00174868,
+ 0x0018d171,
+ 0x001a9afb,
+ 0x001c2989,
+ 0x001df313,
+ 0x001f7c9c,
+ 0x000188a5,
+ 0x000351af,
+ 0x0004db38,
+ 0x0006aa4d,
+ 0x000833d7,
+ 0x0009bd60,
+ 0x000b0969,
+ 0x000c9273,
+ 0x000e5bfc,
+ 0x00132a8a,
+ 0x0014b414,
+ 0x00163d9d,
+ 0x001789a6,
+ 0x001912b0,
+ 0x001adc39,
+ 0x001c6bce,
+ 0x001e34d8,
+ 0x001fbe61,
+ 0x0001ca6a,
+ 0x00039374,
+ 0x00051cfd,
+ 0x0006ec0b,
+ 0x00087515,
+ 0x0009fe9e,
+ 0x000b4aa7,
+ 0x000cd3b1,
+ 0x000e9d3a,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 tdi_tbl40_ant1_rev3[] = {
+ 0x001edb36,
+ 0x000129ca,
+ 0x0002b353,
+ 0x00047cdd,
+ 0x0005c8e6,
+ 0x000791ef,
+ 0x00091bf9,
+ 0x000aaa07,
+ 0x000c3391,
+ 0x000dfd1a,
+ 0x00120923,
+ 0x0013d22d,
+ 0x00155c37,
+ 0x0016eacb,
+ 0x00187454,
+ 0x001a3dde,
+ 0x001b89e7,
+ 0x001d12f0,
+ 0x001f1cfa,
+ 0x00016b88,
+ 0x00033492,
+ 0x0004be1b,
+ 0x00060a24,
+ 0x0007d32e,
+ 0x00095d38,
+ 0x000aec4c,
+ 0x000c7555,
+ 0x000e3edf,
+ 0x00124ae8,
+ 0x001413f1,
+ 0x0015a37b,
+ 0x00172c89,
+ 0x0018b593,
+ 0x001a419c,
+ 0x001bcb25,
+ 0x001d942f,
+ 0x001f63b9,
+ 0x0001ad4d,
+ 0x00037657,
+ 0x0004c260,
+ 0x00068be9,
+ 0x000814f3,
+ 0x0009a47c,
+ 0x000b2d8a,
+ 0x000cb694,
+ 0x000e429d,
+ 0x00128c26,
+ 0x001455b0,
+ 0x0015e4ba,
+ 0x00176e4e,
+ 0x0018f758,
+ 0x001a8361,
+ 0x001c0cea,
+ 0x001dd674,
+ 0x001fa57d,
+ 0x0001ee8b,
+ 0x0003b795,
+ 0x0005039e,
+ 0x0006cd27,
+ 0x000856b1,
+ 0x0009e5c6,
+ 0x000b6f4f,
+ 0x000cf859,
+ 0x000e8462,
+ 0x00130deb,
+ 0x00149775,
+ 0x00162603,
+ 0x0017af8c,
+ 0x00193896,
+ 0x001ac49f,
+ 0x001c4e28,
+ 0x001e17b2,
+ 0x0000a6c7,
+ 0x00023050,
+ 0x0003f9da,
+ 0x00054563,
+ 0x00070eec,
+ 0x00089876,
+ 0x000a2704,
+ 0x000bb08d,
+ 0x000d3a17,
+ 0x001185a0,
+ 0x00134f29,
+ 0x0014d8b3,
+ 0x001667c8,
+ 0x0017f151,
+ 0x00197adb,
+ 0x001b0664,
+ 0x001c8fed,
+ 0x001e5977,
+ 0x0000e805,
+ 0x0002718f,
+ 0x00043b18,
+ 0x000586a1,
+ 0x0007502b,
+ 0x0008d9b4,
+ 0x000a68c9,
+ 0x000bf252,
+ 0x000dbbdc,
+ 0x0011c7e5,
+ 0x001390ee,
+ 0x00151a78,
+ 0x0016a906,
+ 0x00183290,
+ 0x0019bc19,
+ 0x001b4822,
+ 0x001cd12c,
+ 0x001e9ab5,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 pltlut_tbl_rev3[] = {
+ 0x76540213,
+ 0x62407351,
+ 0x76543210,
+ 0x76540213,
+ 0x76540213,
+ 0x76430521,
+};
+
+CONST uint32 chanest_tbl_rev3[] = {
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x44444444,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+ 0x10101010,
+};
+
+CONST uint8 frame_lut_rev3[] = {
+ 0x02,
+ 0x04,
+ 0x14,
+ 0x14,
+ 0x03,
+ 0x05,
+ 0x16,
+ 0x16,
+ 0x0a,
+ 0x0c,
+ 0x1c,
+ 0x1c,
+ 0x0b,
+ 0x0d,
+ 0x1e,
+ 0x1e,
+ 0x06,
+ 0x08,
+ 0x18,
+ 0x18,
+ 0x07,
+ 0x09,
+ 0x1a,
+ 0x1a,
+ 0x0e,
+ 0x10,
+ 0x20,
+ 0x28,
+ 0x0f,
+ 0x11,
+ 0x22,
+ 0x2a,
+};
+
+CONST uint8 est_pwr_lut_core0_rev3[] = {
+ 0x55,
+ 0x54,
+ 0x54,
+ 0x53,
+ 0x52,
+ 0x52,
+ 0x51,
+ 0x51,
+ 0x50,
+ 0x4f,
+ 0x4f,
+ 0x4e,
+ 0x4e,
+ 0x4d,
+ 0x4c,
+ 0x4c,
+ 0x4b,
+ 0x4a,
+ 0x49,
+ 0x49,
+ 0x48,
+ 0x47,
+ 0x46,
+ 0x46,
+ 0x45,
+ 0x44,
+ 0x43,
+ 0x42,
+ 0x41,
+ 0x40,
+ 0x40,
+ 0x3f,
+ 0x3e,
+ 0x3d,
+ 0x3c,
+ 0x3a,
+ 0x39,
+ 0x38,
+ 0x37,
+ 0x36,
+ 0x35,
+ 0x33,
+ 0x32,
+ 0x31,
+ 0x2f,
+ 0x2e,
+ 0x2c,
+ 0x2b,
+ 0x29,
+ 0x27,
+ 0x25,
+ 0x23,
+ 0x21,
+ 0x1f,
+ 0x1d,
+ 0x1a,
+ 0x18,
+ 0x15,
+ 0x12,
+ 0x0e,
+ 0x0b,
+ 0x07,
+ 0x02,
+ 0xfd,
+};
+
+CONST uint8 est_pwr_lut_core1_rev3[] = {
+ 0x55,
+ 0x54,
+ 0x54,
+ 0x53,
+ 0x52,
+ 0x52,
+ 0x51,
+ 0x51,
+ 0x50,
+ 0x4f,
+ 0x4f,
+ 0x4e,
+ 0x4e,
+ 0x4d,
+ 0x4c,
+ 0x4c,
+ 0x4b,
+ 0x4a,
+ 0x49,
+ 0x49,
+ 0x48,
+ 0x47,
+ 0x46,
+ 0x46,
+ 0x45,
+ 0x44,
+ 0x43,
+ 0x42,
+ 0x41,
+ 0x40,
+ 0x40,
+ 0x3f,
+ 0x3e,
+ 0x3d,
+ 0x3c,
+ 0x3a,
+ 0x39,
+ 0x38,
+ 0x37,
+ 0x36,
+ 0x35,
+ 0x33,
+ 0x32,
+ 0x31,
+ 0x2f,
+ 0x2e,
+ 0x2c,
+ 0x2b,
+ 0x29,
+ 0x27,
+ 0x25,
+ 0x23,
+ 0x21,
+ 0x1f,
+ 0x1d,
+ 0x1a,
+ 0x18,
+ 0x15,
+ 0x12,
+ 0x0e,
+ 0x0b,
+ 0x07,
+ 0x02,
+ 0xfd,
+};
+
+CONST uint8 adj_pwr_lut_core0_rev3[] = {
+ 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,
+ 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,
+ 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,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+CONST uint8 adj_pwr_lut_core1_rev3[] = {
+ 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,
+ 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,
+ 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,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+
+CONST uint32 gainctrl_lut_core0_rev3[] = {
+ 0x5bf70044,
+ 0x5bf70042,
+ 0x5bf70040,
+ 0x5bf7003e,
+ 0x5bf7003c,
+ 0x5bf7003b,
+ 0x5bf70039,
+ 0x5bf70037,
+ 0x5bf70036,
+ 0x5bf70034,
+ 0x5bf70033,
+ 0x5bf70031,
+ 0x5bf70030,
+ 0x5ba70044,
+ 0x5ba70042,
+ 0x5ba70040,
+ 0x5ba7003e,
+ 0x5ba7003c,
+ 0x5ba7003b,
+ 0x5ba70039,
+ 0x5ba70037,
+ 0x5ba70036,
+ 0x5ba70034,
+ 0x5ba70033,
+ 0x5b770044,
+ 0x5b770042,
+ 0x5b770040,
+ 0x5b77003e,
+ 0x5b77003c,
+ 0x5b77003b,
+ 0x5b770039,
+ 0x5b770037,
+ 0x5b770036,
+ 0x5b770034,
+ 0x5b770033,
+ 0x5b770031,
+ 0x5b770030,
+ 0x5b77002f,
+ 0x5b77002d,
+ 0x5b77002c,
+ 0x5b470044,
+ 0x5b470042,
+ 0x5b470040,
+ 0x5b47003e,
+ 0x5b47003c,
+ 0x5b47003b,
+ 0x5b470039,
+ 0x5b470037,
+ 0x5b470036,
+ 0x5b470034,
+ 0x5b470033,
+ 0x5b470031,
+ 0x5b470030,
+ 0x5b47002f,
+ 0x5b47002d,
+ 0x5b47002c,
+ 0x5b47002b,
+ 0x5b47002a,
+ 0x5b270044,
+ 0x5b270042,
+ 0x5b270040,
+ 0x5b27003e,
+ 0x5b27003c,
+ 0x5b27003b,
+ 0x5b270039,
+ 0x5b270037,
+ 0x5b270036,
+ 0x5b270034,
+ 0x5b270033,
+ 0x5b270031,
+ 0x5b270030,
+ 0x5b27002f,
+ 0x5b170044,
+ 0x5b170042,
+ 0x5b170040,
+ 0x5b17003e,
+ 0x5b17003c,
+ 0x5b17003b,
+ 0x5b170039,
+ 0x5b170037,
+ 0x5b170036,
+ 0x5b170034,
+ 0x5b170033,
+ 0x5b170031,
+ 0x5b170030,
+ 0x5b17002f,
+ 0x5b17002d,
+ 0x5b17002c,
+ 0x5b17002b,
+ 0x5b17002a,
+ 0x5b170028,
+ 0x5b170027,
+ 0x5b170026,
+ 0x5b170025,
+ 0x5b170024,
+ 0x5b170023,
+ 0x5b070044,
+ 0x5b070042,
+ 0x5b070040,
+ 0x5b07003e,
+ 0x5b07003c,
+ 0x5b07003b,
+ 0x5b070039,
+ 0x5b070037,
+ 0x5b070036,
+ 0x5b070034,
+ 0x5b070033,
+ 0x5b070031,
+ 0x5b070030,
+ 0x5b07002f,
+ 0x5b07002d,
+ 0x5b07002c,
+ 0x5b07002b,
+ 0x5b07002a,
+ 0x5b070028,
+ 0x5b070027,
+ 0x5b070026,
+ 0x5b070025,
+ 0x5b070024,
+ 0x5b070023,
+ 0x5b070022,
+ 0x5b070021,
+ 0x5b070020,
+ 0x5b07001f,
+ 0x5b07001e,
+ 0x5b07001d,
+ 0x5b07001d,
+ 0x5b07001c,
+};
+
+CONST uint32 gainctrl_lut_core1_rev3[] = {
+ 0x5bf70044,
+ 0x5bf70042,
+ 0x5bf70040,
+ 0x5bf7003e,
+ 0x5bf7003c,
+ 0x5bf7003b,
+ 0x5bf70039,
+ 0x5bf70037,
+ 0x5bf70036,
+ 0x5bf70034,
+ 0x5bf70033,
+ 0x5bf70031,
+ 0x5bf70030,
+ 0x5ba70044,
+ 0x5ba70042,
+ 0x5ba70040,
+ 0x5ba7003e,
+ 0x5ba7003c,
+ 0x5ba7003b,
+ 0x5ba70039,
+ 0x5ba70037,
+ 0x5ba70036,
+ 0x5ba70034,
+ 0x5ba70033,
+ 0x5b770044,
+ 0x5b770042,
+ 0x5b770040,
+ 0x5b77003e,
+ 0x5b77003c,
+ 0x5b77003b,
+ 0x5b770039,
+ 0x5b770037,
+ 0x5b770036,
+ 0x5b770034,
+ 0x5b770033,
+ 0x5b770031,
+ 0x5b770030,
+ 0x5b77002f,
+ 0x5b77002d,
+ 0x5b77002c,
+ 0x5b470044,
+ 0x5b470042,
+ 0x5b470040,
+ 0x5b47003e,
+ 0x5b47003c,
+ 0x5b47003b,
+ 0x5b470039,
+ 0x5b470037,
+ 0x5b470036,
+ 0x5b470034,
+ 0x5b470033,
+ 0x5b470031,
+ 0x5b470030,
+ 0x5b47002f,
+ 0x5b47002d,
+ 0x5b47002c,
+ 0x5b47002b,
+ 0x5b47002a,
+ 0x5b270044,
+ 0x5b270042,
+ 0x5b270040,
+ 0x5b27003e,
+ 0x5b27003c,
+ 0x5b27003b,
+ 0x5b270039,
+ 0x5b270037,
+ 0x5b270036,
+ 0x5b270034,
+ 0x5b270033,
+ 0x5b270031,
+ 0x5b270030,
+ 0x5b27002f,
+ 0x5b170044,
+ 0x5b170042,
+ 0x5b170040,
+ 0x5b17003e,
+ 0x5b17003c,
+ 0x5b17003b,
+ 0x5b170039,
+ 0x5b170037,
+ 0x5b170036,
+ 0x5b170034,
+ 0x5b170033,
+ 0x5b170031,
+ 0x5b170030,
+ 0x5b17002f,
+ 0x5b17002d,
+ 0x5b17002c,
+ 0x5b17002b,
+ 0x5b17002a,
+ 0x5b170028,
+ 0x5b170027,
+ 0x5b170026,
+ 0x5b170025,
+ 0x5b170024,
+ 0x5b170023,
+ 0x5b070044,
+ 0x5b070042,
+ 0x5b070040,
+ 0x5b07003e,
+ 0x5b07003c,
+ 0x5b07003b,
+ 0x5b070039,
+ 0x5b070037,
+ 0x5b070036,
+ 0x5b070034,
+ 0x5b070033,
+ 0x5b070031,
+ 0x5b070030,
+ 0x5b07002f,
+ 0x5b07002d,
+ 0x5b07002c,
+ 0x5b07002b,
+ 0x5b07002a,
+ 0x5b070028,
+ 0x5b070027,
+ 0x5b070026,
+ 0x5b070025,
+ 0x5b070024,
+ 0x5b070023,
+ 0x5b070022,
+ 0x5b070021,
+ 0x5b070020,
+ 0x5b07001f,
+ 0x5b07001e,
+ 0x5b07001d,
+ 0x5b07001d,
+ 0x5b07001c,
+};
+
+CONST uint32 iq_lut_core0_rev3[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 iq_lut_core1_rev3[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint16 loft_lut_core0_rev3[] = {
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint16 loft_lut_core1_rev3[] = {
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+};
+
+CONST uint16 papd_comp_rfpwr_tbl_core0_rev3[] = {
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+};
+
+CONST uint16 papd_comp_rfpwr_tbl_core1_rev3[] = {
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x0036,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x002a,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x001e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x000e,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01fc,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01ee,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+ 0x01d6,
+};
+
+CONST uint32 papd_comp_epsilon_tbl_core0_rev3[] = {
+ 0x00000000,
+ 0x00001fa0,
+ 0x00019f78,
+ 0x0001df7e,
+ 0x03fa9f86,
+ 0x03fd1f90,
+ 0x03fe5f8a,
+ 0x03fb1f94,
+ 0x03fd9fa0,
+ 0x00009f98,
+ 0x03fd1fac,
+ 0x03ff9fa2,
+ 0x03fe9fae,
+ 0x00001fae,
+ 0x03fddfb4,
+ 0x03ff1fb8,
+ 0x03ff9fbc,
+ 0x03ffdfbe,
+ 0x03fe9fc2,
+ 0x03fedfc6,
+ 0x03fedfc6,
+ 0x03ff9fc8,
+ 0x03ff5fc6,
+ 0x03fedfc2,
+ 0x03ff9fc0,
+ 0x03ff5fac,
+ 0x03ff5fac,
+ 0x03ff9fa2,
+ 0x03ff9fa6,
+ 0x03ff9faa,
+ 0x03ff5fb0,
+ 0x03ff5fb4,
+ 0x03ff1fca,
+ 0x03ff5fce,
+ 0x03fcdfdc,
+ 0x03fb4006,
+ 0x00000030,
+ 0x03ff808a,
+ 0x03ff80da,
+ 0x0000016c,
+ 0x03ff8318,
+ 0x03ff063a,
+ 0x03fd8bd6,
+ 0x00014ffe,
+ 0x00034ffe,
+ 0x00034ffe,
+ 0x0003cffe,
+ 0x00040ffe,
+ 0x00040ffe,
+ 0x0003cffe,
+ 0x0003cffe,
+ 0x00020ffe,
+ 0x03fe0ffe,
+ 0x03fdcffe,
+ 0x03f94ffe,
+ 0x03f54ffe,
+ 0x03f44ffe,
+ 0x03ef8ffe,
+ 0x03ee0ffe,
+ 0x03ebcffe,
+ 0x03e8cffe,
+ 0x03e74ffe,
+ 0x03e4cffe,
+ 0x03e38ffe,
+};
+
+CONST uint32 papd_cal_scalars_tbl_core0_rev3[] = {
+ 0x05af005a,
+ 0x0571005e,
+ 0x05040066,
+ 0x04bd006c,
+ 0x047d0072,
+ 0x04430078,
+ 0x03f70081,
+ 0x03cb0087,
+ 0x03870091,
+ 0x035e0098,
+ 0x032e00a1,
+ 0x030300aa,
+ 0x02d800b4,
+ 0x02ae00bf,
+ 0x028900ca,
+ 0x026400d6,
+ 0x024100e3,
+ 0x022200f0,
+ 0x020200ff,
+ 0x01e5010e,
+ 0x01ca011e,
+ 0x01b0012f,
+ 0x01990140,
+ 0x01830153,
+ 0x016c0168,
+ 0x0158017d,
+ 0x01450193,
+ 0x013301ab,
+ 0x012101c5,
+ 0x011101e0,
+ 0x010201fc,
+ 0x00f4021a,
+ 0x00e6011d,
+ 0x00d9012e,
+ 0x00cd0140,
+ 0x00c20153,
+ 0x00b70167,
+ 0x00ac017c,
+ 0x00a30193,
+ 0x009a01ab,
+ 0x009101c4,
+ 0x008901df,
+ 0x008101fb,
+ 0x007a0219,
+ 0x00730239,
+ 0x006d025b,
+ 0x0067027e,
+ 0x006102a4,
+ 0x005c02cc,
+ 0x005602f6,
+ 0x00520323,
+ 0x004d0353,
+ 0x00490385,
+ 0x004503bb,
+ 0x004103f3,
+ 0x003d042f,
+ 0x003a046f,
+ 0x003704b2,
+ 0x003404f9,
+ 0x00310545,
+ 0x002e0596,
+ 0x002b05f5,
+ 0x00290640,
+ 0x002606a4,
+};
+
+CONST uint32 papd_comp_epsilon_tbl_core1_rev3[] = {
+ 0x00000000,
+ 0x00001fa0,
+ 0x00019f78,
+ 0x0001df7e,
+ 0x03fa9f86,
+ 0x03fd1f90,
+ 0x03fe5f8a,
+ 0x03fb1f94,
+ 0x03fd9fa0,
+ 0x00009f98,
+ 0x03fd1fac,
+ 0x03ff9fa2,
+ 0x03fe9fae,
+ 0x00001fae,
+ 0x03fddfb4,
+ 0x03ff1fb8,
+ 0x03ff9fbc,
+ 0x03ffdfbe,
+ 0x03fe9fc2,
+ 0x03fedfc6,
+ 0x03fedfc6,
+ 0x03ff9fc8,
+ 0x03ff5fc6,
+ 0x03fedfc2,
+ 0x03ff9fc0,
+ 0x03ff5fac,
+ 0x03ff5fac,
+ 0x03ff9fa2,
+ 0x03ff9fa6,
+ 0x03ff9faa,
+ 0x03ff5fb0,
+ 0x03ff5fb4,
+ 0x03ff1fca,
+ 0x03ff5fce,
+ 0x03fcdfdc,
+ 0x03fb4006,
+ 0x00000030,
+ 0x03ff808a,
+ 0x03ff80da,
+ 0x0000016c,
+ 0x03ff8318,
+ 0x03ff063a,
+ 0x03fd8bd6,
+ 0x00014ffe,
+ 0x00034ffe,
+ 0x00034ffe,
+ 0x0003cffe,
+ 0x00040ffe,
+ 0x00040ffe,
+ 0x0003cffe,
+ 0x0003cffe,
+ 0x00020ffe,
+ 0x03fe0ffe,
+ 0x03fdcffe,
+ 0x03f94ffe,
+ 0x03f54ffe,
+ 0x03f44ffe,
+ 0x03ef8ffe,
+ 0x03ee0ffe,
+ 0x03ebcffe,
+ 0x03e8cffe,
+ 0x03e74ffe,
+ 0x03e4cffe,
+ 0x03e38ffe,
+};
+
+CONST uint32 papd_cal_scalars_tbl_core1_rev3[] = {
+ 0x05af005a,
+ 0x0571005e,
+ 0x05040066,
+ 0x04bd006c,
+ 0x047d0072,
+ 0x04430078,
+ 0x03f70081,
+ 0x03cb0087,
+ 0x03870091,
+ 0x035e0098,
+ 0x032e00a1,
+ 0x030300aa,
+ 0x02d800b4,
+ 0x02ae00bf,
+ 0x028900ca,
+ 0x026400d6,
+ 0x024100e3,
+ 0x022200f0,
+ 0x020200ff,
+ 0x01e5010e,
+ 0x01ca011e,
+ 0x01b0012f,
+ 0x01990140,
+ 0x01830153,
+ 0x016c0168,
+ 0x0158017d,
+ 0x01450193,
+ 0x013301ab,
+ 0x012101c5,
+ 0x011101e0,
+ 0x010201fc,
+ 0x00f4021a,
+ 0x00e6011d,
+ 0x00d9012e,
+ 0x00cd0140,
+ 0x00c20153,
+ 0x00b70167,
+ 0x00ac017c,
+ 0x00a30193,
+ 0x009a01ab,
+ 0x009101c4,
+ 0x008901df,
+ 0x008101fb,
+ 0x007a0219,
+ 0x00730239,
+ 0x006d025b,
+ 0x0067027e,
+ 0x006102a4,
+ 0x005c02cc,
+ 0x005602f6,
+ 0x00520323,
+ 0x004d0353,
+ 0x00490385,
+ 0x004503bb,
+ 0x004103f3,
+ 0x003d042f,
+ 0x003a046f,
+ 0x003704b2,
+ 0x003404f9,
+ 0x00310545,
+ 0x002e0596,
+ 0x002b05f5,
+ 0x00290640,
+ 0x002606a4,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev3_volatile[] = {
+ {&ant_swctrl_tbl_rev3,
+ sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
+ ,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = {
+ {&ant_swctrl_tbl_rev3_1,
+ sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
+ 16}
+ ,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = {
+ {&ant_swctrl_tbl_rev3_2,
+ sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
+ 16}
+ ,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = {
+ {&ant_swctrl_tbl_rev3_3,
+ sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
+ 16}
+ ,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev3[] = {
+ {&frame_struct_rev3,
+ sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+ ,
+ {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+ 11, 0, 16}
+ ,
+ {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
+ 0, 32}
+ ,
+ {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+ 13, 0, 32}
+ ,
+ {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+ 14, 0, 32}
+ ,
+ {&noise_var_tbl_rev3,
+ sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
+ ,
+ {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+ 16}
+ ,
+ {&tdi_tbl20_ant0_rev3,
+ sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+ 32}
+ ,
+ {&tdi_tbl20_ant1_rev3,
+ sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+ 32}
+ ,
+ {&tdi_tbl40_ant0_rev3,
+ sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+ 32}
+ ,
+ {&tdi_tbl40_ant1_rev3,
+ sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+ 32}
+ ,
+ {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+ 20, 0, 32}
+ ,
+ {&chanest_tbl_rev3,
+ sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+ ,
+ {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+ 24, 0, 8}
+ ,
+ {&est_pwr_lut_core0_rev3,
+ sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+ 0, 8}
+ ,
+ {&est_pwr_lut_core1_rev3,
+ sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+ 0, 8}
+ ,
+ {&adj_pwr_lut_core0_rev3,
+ sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+ 64, 8}
+ ,
+ {&adj_pwr_lut_core1_rev3,
+ sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+ 64, 8}
+ ,
+ {&gainctrl_lut_core0_rev3,
+ sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+ 26, 192, 32}
+ ,
+ {&gainctrl_lut_core1_rev3,
+ sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+ 27, 192, 32}
+ ,
+ {&iq_lut_core0_rev3,
+ sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+ ,
+ {&iq_lut_core1_rev3,
+ sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+ ,
+ {&loft_lut_core0_rev3,
+ sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+ 16}
+ ,
+ {&loft_lut_core1_rev3,
+ sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+ 16}
+};
+
+CONST uint32 mimophytbl_info_sz_rev3 =
+ sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
+CONST uint32 mimophytbl_info_sz_rev3_volatile =
+ sizeof(mimophytbl_info_rev3_volatile) /
+ sizeof(mimophytbl_info_rev3_volatile[0]);
+CONST uint32 mimophytbl_info_sz_rev3_volatile1 =
+ sizeof(mimophytbl_info_rev3_volatile1) /
+ sizeof(mimophytbl_info_rev3_volatile1[0]);
+CONST uint32 mimophytbl_info_sz_rev3_volatile2 =
+ sizeof(mimophytbl_info_rev3_volatile2) /
+ sizeof(mimophytbl_info_rev3_volatile2[0]);
+CONST uint32 mimophytbl_info_sz_rev3_volatile3 =
+ sizeof(mimophytbl_info_rev3_volatile3) /
+ sizeof(mimophytbl_info_rev3_volatile3[0]);
+
+CONST uint32 tmap_tbl_rev7[] = {
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x000aa888,
+ 0x88880000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00011111,
+ 0x11110000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00088aaa,
+ 0xaaaa0000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xaaa8aaa0,
+ 0x8aaa8aaa,
+ 0xaa8a8a8a,
+ 0x000aaa88,
+ 0x8aaa0000,
+ 0xaaa8a888,
+ 0x8aa88a8a,
+ 0x8a88a888,
+ 0x08080a00,
+ 0x0a08080a,
+ 0x080a0a08,
+ 0x00080808,
+ 0x080a0000,
+ 0x080a0808,
+ 0x080a0808,
+ 0x0a0a0a08,
+ 0xa0a0a0a0,
+ 0x80a0a080,
+ 0x8080a0a0,
+ 0x00008080,
+ 0x80a00000,
+ 0x80a080a0,
+ 0xa080a0a0,
+ 0x8080a0a0,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x99999000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x22000000,
+ 0x2222b222,
+ 0x22222222,
+ 0x222222b2,
+ 0xb2222220,
+ 0x22222222,
+ 0x22d22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333b333,
+ 0x33333333,
+ 0x333333b3,
+ 0xb3333330,
+ 0x33333333,
+ 0x33d33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222a222,
+ 0x22222222,
+ 0x222222a2,
+ 0xa2222220,
+ 0x22222222,
+ 0x22c22222,
+ 0x00000222,
+ 0x99b99b00,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb99,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x22222200,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0x22222222,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x11111111,
+ 0xf1111111,
+ 0x11111111,
+ 0x11f11111,
+ 0x01111111,
+ 0xbb9bb900,
+ 0xb9b9bb99,
+ 0xb99bbbbb,
+ 0xbbbb9b9b,
+ 0xb9bb99bb,
+ 0xb99999b9,
+ 0xb9b9b99b,
+ 0x00000bbb,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88aa,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x0a888aaa,
+ 0xaa000000,
+ 0xa8a8aa88,
+ 0xa88aaaaa,
+ 0xaaaa8a8a,
+ 0xa8aa88a0,
+ 0xa88888a8,
+ 0xa8a8a88a,
+ 0x00000aaa,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0xbbbbbb00,
+ 0x999bbbbb,
+ 0x9bb99b9b,
+ 0xb9b9b9bb,
+ 0xb9b99bbb,
+ 0xb9b9b9bb,
+ 0xb9bb9b99,
+ 0x00000999,
+ 0x8a000000,
+ 0xaa88a888,
+ 0xa88888aa,
+ 0xa88a8a88,
+ 0xa88aa88a,
+ 0x88a8aaaa,
+ 0xa8aa8aaa,
+ 0x0888a88a,
+ 0x0b0b0b00,
+ 0x090b0b0b,
+ 0x0b090b0b,
+ 0x0909090b,
+ 0x09090b0b,
+ 0x09090b0b,
+ 0x09090b09,
+ 0x00000909,
+ 0x0a000000,
+ 0x0a080808,
+ 0x080a080a,
+ 0x080a0a08,
+ 0x080a080a,
+ 0x0808080a,
+ 0x0a0a0a08,
+ 0x0808080a,
+ 0xb0b0b000,
+ 0x9090b0b0,
+ 0x90b09090,
+ 0xb0b0b090,
+ 0xb0b090b0,
+ 0x90b0b0b0,
+ 0xb0b09090,
+ 0x00000090,
+ 0x80000000,
+ 0xa080a080,
+ 0xa08080a0,
+ 0xa0808080,
+ 0xa080a080,
+ 0x80a0a0a0,
+ 0xa0a080a0,
+ 0x00a0a0a0,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x11000000,
+ 0x1111f111,
+ 0x11111111,
+ 0x111111f1,
+ 0xf1111110,
+ 0x11111111,
+ 0x11f11111,
+ 0x00000111,
+ 0x33000000,
+ 0x3333f333,
+ 0x33333333,
+ 0x333333f3,
+ 0xf3333330,
+ 0x33333333,
+ 0x33f33333,
+ 0x00000333,
+ 0x22000000,
+ 0x2222f222,
+ 0x22222222,
+ 0x222222f2,
+ 0xf2222220,
+ 0x22222222,
+ 0x22f22222,
+ 0x00000222,
+ 0x99000000,
+ 0x9b9b99bb,
+ 0x9bb99999,
+ 0x9999b9b9,
+ 0x9b99bb90,
+ 0x9bbbbb9b,
+ 0x9b9b9bb9,
+ 0x00000999,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88888000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00aaa888,
+ 0x88a88a00,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x000aa888,
+ 0x88880000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa88,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x08aaa888,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x11000000,
+ 0x1111a111,
+ 0x11111111,
+ 0x111111a1,
+ 0xa1111110,
+ 0x11111111,
+ 0x11c11111,
+ 0x00000111,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x88000000,
+ 0x8a8a88aa,
+ 0x8aa88888,
+ 0x8888a8a8,
+ 0x8a88aa80,
+ 0x8aaaaa8a,
+ 0x8a8a8aa8,
+ 0x00000888,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+
+CONST uint32 noise_var_tbl_rev7[] = {
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+ 0x020c020c,
+ 0x0000014d,
+};
+
+CONST uint32 papd_comp_epsilon_tbl_core0_rev7[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00016023,
+ 0x00006028,
+ 0x00034036,
+ 0x0003402e,
+ 0x0007203c,
+ 0x0006e037,
+ 0x00070030,
+ 0x0009401f,
+ 0x0009a00f,
+ 0x000b600d,
+ 0x000c8007,
+ 0x000ce007,
+ 0x00101fff,
+ 0x00121ff9,
+ 0x0012e004,
+ 0x0014dffc,
+ 0x0016dff6,
+ 0x0018dfe9,
+ 0x001b3fe5,
+ 0x001c5fd0,
+ 0x001ddfc2,
+ 0x001f1fb6,
+ 0x00207fa4,
+ 0x00219f8f,
+ 0x0022ff7d,
+ 0x00247f6c,
+ 0x0024df5b,
+ 0x00267f4b,
+ 0x0027df3b,
+ 0x0029bf3b,
+ 0x002b5f2f,
+ 0x002d3f2e,
+ 0x002f5f2a,
+ 0x002fff15,
+ 0x00315f0b,
+ 0x0032defa,
+ 0x0033beeb,
+ 0x0034fed9,
+ 0x00353ec5,
+ 0x00361eb0,
+ 0x00363e9b,
+ 0x0036be87,
+ 0x0036be70,
+ 0x0038fe67,
+ 0x0044beb2,
+ 0x00513ef3,
+ 0x00595f11,
+ 0x00669f3d,
+ 0x0078dfdf,
+ 0x00a143aa,
+ 0x01642fff,
+ 0x0162afff,
+ 0x01620fff,
+ 0x0160cfff,
+ 0x015f0fff,
+ 0x015dafff,
+ 0x015bcfff,
+ 0x015bcfff,
+ 0x015b4fff,
+ 0x015acfff,
+ 0x01590fff,
+ 0x0156cfff,
+};
+
+CONST uint32 papd_cal_scalars_tbl_core0_rev7[] = {
+ 0x0b5e002d,
+ 0x0ae2002f,
+ 0x0a3b0032,
+ 0x09a70035,
+ 0x09220038,
+ 0x08ab003b,
+ 0x081f003f,
+ 0x07a20043,
+ 0x07340047,
+ 0x06d2004b,
+ 0x067a004f,
+ 0x06170054,
+ 0x05bf0059,
+ 0x0571005e,
+ 0x051e0064,
+ 0x04d3006a,
+ 0x04910070,
+ 0x044c0077,
+ 0x040f007e,
+ 0x03d90085,
+ 0x03a1008d,
+ 0x036f0095,
+ 0x033d009e,
+ 0x030b00a8,
+ 0x02e000b2,
+ 0x02b900bc,
+ 0x029200c7,
+ 0x026d00d3,
+ 0x024900e0,
+ 0x022900ed,
+ 0x020a00fb,
+ 0x01ec010a,
+ 0x01d20119,
+ 0x01b7012a,
+ 0x019e013c,
+ 0x0188014e,
+ 0x01720162,
+ 0x015d0177,
+ 0x0149018e,
+ 0x013701a5,
+ 0x012601be,
+ 0x011501d8,
+ 0x010601f4,
+ 0x00f70212,
+ 0x00e90231,
+ 0x00dc0253,
+ 0x00d00276,
+ 0x00c4029b,
+ 0x00b902c3,
+ 0x00af02ed,
+ 0x00a50319,
+ 0x009c0348,
+ 0x0093037a,
+ 0x008b03af,
+ 0x008303e6,
+ 0x007c0422,
+ 0x00750460,
+ 0x006e04a3,
+ 0x006804e9,
+ 0x00620533,
+ 0x005d0582,
+ 0x005805d6,
+ 0x0053062e,
+ 0x004e068c,
+};
+
+CONST uint32 papd_comp_epsilon_tbl_core1_rev7[] = {
+ 0x00000000,
+ 0x00000000,
+ 0x00016023,
+ 0x00006028,
+ 0x00034036,
+ 0x0003402e,
+ 0x0007203c,
+ 0x0006e037,
+ 0x00070030,
+ 0x0009401f,
+ 0x0009a00f,
+ 0x000b600d,
+ 0x000c8007,
+ 0x000ce007,
+ 0x00101fff,
+ 0x00121ff9,
+ 0x0012e004,
+ 0x0014dffc,
+ 0x0016dff6,
+ 0x0018dfe9,
+ 0x001b3fe5,
+ 0x001c5fd0,
+ 0x001ddfc2,
+ 0x001f1fb6,
+ 0x00207fa4,
+ 0x00219f8f,
+ 0x0022ff7d,
+ 0x00247f6c,
+ 0x0024df5b,
+ 0x00267f4b,
+ 0x0027df3b,
+ 0x0029bf3b,
+ 0x002b5f2f,
+ 0x002d3f2e,
+ 0x002f5f2a,
+ 0x002fff15,
+ 0x00315f0b,
+ 0x0032defa,
+ 0x0033beeb,
+ 0x0034fed9,
+ 0x00353ec5,
+ 0x00361eb0,
+ 0x00363e9b,
+ 0x0036be87,
+ 0x0036be70,
+ 0x0038fe67,
+ 0x0044beb2,
+ 0x00513ef3,
+ 0x00595f11,
+ 0x00669f3d,
+ 0x0078dfdf,
+ 0x00a143aa,
+ 0x01642fff,
+ 0x0162afff,
+ 0x01620fff,
+ 0x0160cfff,
+ 0x015f0fff,
+ 0x015dafff,
+ 0x015bcfff,
+ 0x015bcfff,
+ 0x015b4fff,
+ 0x015acfff,
+ 0x01590fff,
+ 0x0156cfff,
+};
+
+CONST uint32 papd_cal_scalars_tbl_core1_rev7[] = {
+ 0x0b5e002d,
+ 0x0ae2002f,
+ 0x0a3b0032,
+ 0x09a70035,
+ 0x09220038,
+ 0x08ab003b,
+ 0x081f003f,
+ 0x07a20043,
+ 0x07340047,
+ 0x06d2004b,
+ 0x067a004f,
+ 0x06170054,
+ 0x05bf0059,
+ 0x0571005e,
+ 0x051e0064,
+ 0x04d3006a,
+ 0x04910070,
+ 0x044c0077,
+ 0x040f007e,
+ 0x03d90085,
+ 0x03a1008d,
+ 0x036f0095,
+ 0x033d009e,
+ 0x030b00a8,
+ 0x02e000b2,
+ 0x02b900bc,
+ 0x029200c7,
+ 0x026d00d3,
+ 0x024900e0,
+ 0x022900ed,
+ 0x020a00fb,
+ 0x01ec010a,
+ 0x01d20119,
+ 0x01b7012a,
+ 0x019e013c,
+ 0x0188014e,
+ 0x01720162,
+ 0x015d0177,
+ 0x0149018e,
+ 0x013701a5,
+ 0x012601be,
+ 0x011501d8,
+ 0x010601f4,
+ 0x00f70212,
+ 0x00e90231,
+ 0x00dc0253,
+ 0x00d00276,
+ 0x00c4029b,
+ 0x00b902c3,
+ 0x00af02ed,
+ 0x00a50319,
+ 0x009c0348,
+ 0x0093037a,
+ 0x008b03af,
+ 0x008303e6,
+ 0x007c0422,
+ 0x00750460,
+ 0x006e04a3,
+ 0x006804e9,
+ 0x00620533,
+ 0x005d0582,
+ 0x005805d6,
+ 0x0053062e,
+ 0x004e068c,
+};
+
+CONST mimophytbl_info_t mimophytbl_info_rev7[] = {
+ {&frame_struct_rev3,
+ sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+ ,
+ {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+ 11, 0, 16}
+ ,
+ {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
+ 0, 32}
+ ,
+ {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+ 13, 0, 32}
+ ,
+ {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+ 14, 0, 32}
+ ,
+ {&noise_var_tbl_rev7,
+ sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+ ,
+ {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+ 16}
+ ,
+ {&tdi_tbl20_ant0_rev3,
+ sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+ 32}
+ ,
+ {&tdi_tbl20_ant1_rev3,
+ sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+ 32}
+ ,
+ {&tdi_tbl40_ant0_rev3,
+ sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+ 32}
+ ,
+ {&tdi_tbl40_ant1_rev3,
+ sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+ 32}
+ ,
+ {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+ 20, 0, 32}
+ ,
+ {&chanest_tbl_rev3,
+ sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+ ,
+ {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+ 24, 0, 8}
+ ,
+ {&est_pwr_lut_core0_rev3,
+ sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+ 0, 8}
+ ,
+ {&est_pwr_lut_core1_rev3,
+ sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+ 0, 8}
+ ,
+ {&adj_pwr_lut_core0_rev3,
+ sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+ 64, 8}
+ ,
+ {&adj_pwr_lut_core1_rev3,
+ sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+ 64, 8}
+ ,
+ {&gainctrl_lut_core0_rev3,
+ sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+ 26, 192, 32}
+ ,
+ {&gainctrl_lut_core1_rev3,
+ sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+ 27, 192, 32}
+ ,
+ {&iq_lut_core0_rev3,
+ sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+ ,
+ {&iq_lut_core1_rev3,
+ sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+ ,
+ {&loft_lut_core0_rev3,
+ sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+ 16}
+ ,
+ {&loft_lut_core1_rev3,
+ sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+ 16}
+ ,
+ {&papd_comp_rfpwr_tbl_core0_rev3,
+ sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
+ sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
+ ,
+ {&papd_comp_rfpwr_tbl_core1_rev3,
+ sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
+ sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
+ ,
+ {&papd_comp_epsilon_tbl_core0_rev7,
+ sizeof(papd_comp_epsilon_tbl_core0_rev7) /
+ sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
+ ,
+ {&papd_cal_scalars_tbl_core0_rev7,
+ sizeof(papd_cal_scalars_tbl_core0_rev7) /
+ sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
+ ,
+ {&papd_comp_epsilon_tbl_core1_rev7,
+ sizeof(papd_comp_epsilon_tbl_core1_rev7) /
+ sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
+ ,
+ {&papd_cal_scalars_tbl_core1_rev7,
+ sizeof(papd_cal_scalars_tbl_core1_rev7) /
+ sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
+ ,
+};
+
+CONST uint32 mimophytbl_info_sz_rev7 =
+ sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
+
+CONST mimophytbl_info_t mimophytbl_info_rev16[] = {
+ {&noise_var_tbl_rev7,
+ sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+ ,
+ {&est_pwr_lut_core0_rev3,
+ sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+ 0, 8}
+ ,
+ {&est_pwr_lut_core1_rev3,
+ sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+ 0, 8}
+ ,
+ {&adj_pwr_lut_core0_rev3,
+ sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+ 64, 8}
+ ,
+ {&adj_pwr_lut_core1_rev3,
+ sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+ 64, 8}
+ ,
+ {&gainctrl_lut_core0_rev3,
+ sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+ 26, 192, 32}
+ ,
+ {&gainctrl_lut_core1_rev3,
+ sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+ 27, 192, 32}
+ ,
+ {&iq_lut_core0_rev3,
+ sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+ ,
+ {&iq_lut_core1_rev3,
+ sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+ ,
+ {&loft_lut_core0_rev3,
+ sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+ 16}
+ ,
+ {&loft_lut_core1_rev3,
+ sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+ 16}
+ ,
+};
+
+CONST uint32 mimophytbl_info_sz_rev16 =
+ sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/phy/wlc_phytbl_n.h
new file mode 100644
index 000000000000..108197c0c4d9
--- /dev/null
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_n.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+#define ANT_SWCTRL_TBL_REV3_IDX (0)
+
+typedef phytbl_info_t mimophytbl_info_t;
+
+extern CONST mimophytbl_info_t mimophytbl_info_rev0[],
+ mimophytbl_info_rev0_volatile[];
+extern CONST uint32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile;
+
+extern CONST mimophytbl_info_t mimophytbl_info_rev3[],
+ mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[],
+ mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[];
+extern CONST uint32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile,
+ mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2,
+ mimophytbl_info_sz_rev3_volatile3;
+
+extern CONST uint32 noise_var_tbl_rev3[];
+
+extern CONST mimophytbl_info_t mimophytbl_info_rev7[];
+extern CONST uint32 mimophytbl_info_sz_rev7;
+extern CONST uint32 noise_var_tbl_rev7[];
+
+extern CONST mimophytbl_info_t mimophytbl_info_rev16[];
+extern CONST uint32 mimophytbl_info_sz_rev16;
diff --git a/drivers/staging/brcm80211/sys/d11ucode_ext.h b/drivers/staging/brcm80211/sys/d11ucode_ext.h
new file mode 100644
index 000000000000..c0c0d661e00e
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/d11ucode_ext.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+enum {
+ D11UCODE_NAMETAG_START = 0,
+ D11LCN0BSINITVALS24,
+ D11LCN0INITVALS24,
+ D11LCN1BSINITVALS24,
+ D11LCN1INITVALS24,
+ D11LCN2BSINITVALS24,
+ D11LCN2INITVALS24,
+ D11N0ABSINITVALS16,
+ D11N0BSINITVALS16,
+ D11N0INITVALS16,
+ D11UCODE_OVERSIGHT16_MIMO,
+ D11UCODE_OVERSIGHT16_MIMOSZ,
+ D11UCODE_OVERSIGHT24_LCN,
+ D11UCODE_OVERSIGHT24_LCNSZ,
+ D11UCODE_OVERSIGHT_BOMMAJOR,
+ D11UCODE_OVERSIGHT_BOMMINOR
+};
+#define UCODE_LOADER_API_VER 0
diff --git a/drivers/staging/brcm80211/sys/wl_dbg.h b/drivers/staging/brcm80211/sys/wl_dbg.h
new file mode 100644
index 000000000000..d83244cae449
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_dbg.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wl_dbg_h_
+#define _wl_dbg_h_
+
+/* wl_msg_level is a bit vector with defs in wlioctl.h */
+extern uint32 wl_msg_level;
+
+#define WL_PRINT(args) printf args
+#define WL_NONE(args)
+
+#ifdef BCMDBG
+
+#define WL_ERROR(args) do {if ((wl_msg_level & WL_ERROR_VAL)) WL_PRINT(args); } while (0)
+#define WL_TRACE(args) do {if (wl_msg_level & WL_TRACE_VAL) WL_PRINT(args); } while (0)
+#define WL_AMPDU(args) do {if (wl_msg_level & WL_AMPDU_VAL) WL_PRINT(args); } while (0)
+#define WL_FFPLD(args) do {if (wl_msg_level & WL_FFPLD_VAL) WL_PRINT(args); } while (0)
+
+#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL)
+
+/* Extra message control for AMPDU debugging */
+#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */
+#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */
+#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */
+#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */
+#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */
+#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */
+#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */
+#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */
+
+extern uint32 wl_ampdu_dbg;
+
+#define WL_AMPDU_UPDN(args) do {if (wl_ampdu_dbg & WL_AMPDU_UPDN_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_RX(args) do {if (wl_ampdu_dbg & WL_AMPDU_RX_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_ERR(args) do {if (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_TX(args) do {if (wl_ampdu_dbg & WL_AMPDU_TX_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_CTL(args) do {if (wl_ampdu_dbg & WL_AMPDU_CTL_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_HW(args) do {if (wl_ampdu_dbg & WL_AMPDU_HW_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_HWTXS(args) do {if (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_HWDBG(args) do {if (wl_ampdu_dbg & WL_AMPDU_HWDBG_VAL) {WL_AMPDU(args); } } while (0)
+#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL)
+#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL)
+#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL)
+
+#else /* BCMDBG */
+
+#define WL_ERROR(args)
+#define WL_TRACE(args)
+#define WL_AMPDU(args)
+#define WL_FFPLD(args)
+
+#define WL_ERROR_ON() 0
+
+#define WL_AMPDU_UPDN(args)
+#define WL_AMPDU_RX(args)
+#define WL_AMPDU_ERR(args)
+#define WL_AMPDU_TX(args)
+#define WL_AMPDU_CTL(args)
+#define WL_AMPDU_HW(args)
+#define WL_AMPDU_HWTXS(args)
+#define WL_AMPDU_HWDBG(args)
+#define WL_AMPDU_ERR_ON() 0
+#define WL_AMPDU_HW_ON() 0
+#define WL_AMPDU_HWTXS_ON() 0
+
+#endif /* BCMDBG */
+
+#endif /* _wl_dbg_h_ */
diff --git a/drivers/staging/brcm80211/sys/wl_export.h b/drivers/staging/brcm80211/sys/wl_export.h
new file mode 100644
index 000000000000..8a554c03f483
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_export.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wl_export_h_
+#define _wl_export_h_
+
+/* misc callbacks */
+struct wl_info;
+struct wl_if;
+struct wlc_if;
+extern void wl_init(struct wl_info *wl);
+extern uint wl_reset(struct wl_info *wl);
+extern void wl_intrson(struct wl_info *wl);
+extern uint32 wl_intrsoff(struct wl_info *wl);
+extern void wl_intrsrestore(struct wl_info *wl, uint32 macintmask);
+extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e);
+extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e,
+ uint8 *data, uint32 len);
+extern int wl_up(struct wl_info *wl);
+extern void wl_down(struct wl_info *wl);
+extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+ int prio);
+extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth);
+
+/* timer functions */
+struct wl_timer;
+extern struct wl_timer *wl_init_timer(struct wl_info *wl,
+ void (*fn) (void *arg), void *arg,
+ const char *name);
+extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer);
+extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
+ int periodic);
+extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
+
+extern uint wl_buf_to_pktcopy(osl_t *osh, void *p, uchar *buf, int len,
+ uint offset);
+extern void *wl_get_pktbuffer(osl_t *osh, int len);
+extern int wl_set_pktlen(osl_t *osh, void *p, int len);
+
+#define wl_sort_bsslist(a, b) FALSE
+
+extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len,
+ bool group_key, int id);
+extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len);
+extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len);
+extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len,
+ bool group_key);
+extern void wl_tkip_printstats(struct wl_info *wl, bool group_key);
+extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key);
+#endif /* _wl_export_h_ */
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c
new file mode 100644
index 000000000000..71bd46383c19
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.c
@@ -0,0 +1,2552 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+#define __UNDEF_NO_VERSION__
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ethtool.h>
+#include <linux/completion.h>
+#include <linux/pci_ids.h>
+#define WLC_MAXBSSCFG 1 /* single BSS configs */
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <wlc_cfg.h>
+#include <net/mac80211.h>
+#include <epivers.h>
+#ifndef WLC_HIGH_ONLY
+#include <phy_version.h>
+#endif
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <pcicfg.h>
+#include <wlioctl.h>
+#include <wlc_key.h>
+#include <proto/802.1d.h> /* NUMPRIO & BE */
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <wlc_channel.h>
+#include <wlc_pub.h>
+#include <wlc_scb.h>
+#include <wl_dbg.h>
+#ifdef BCMSDIO
+#include <bcmsdh.h>
+#endif
+#include <wl_export.h>
+#ifdef WLC_HIGH_ONLY
+#include "dbus.h"
+#include "bcm_rpc_tp.h"
+#include "bcm_rpc.h"
+#include "bcm_xdr.h"
+#include "wlc_rpc.h"
+#endif
+
+#include <wl_mac80211.h>
+#include <linux/firmware.h>
+#ifndef WLC_HIGH_ONLY
+#include <wl_ucode.h>
+#include <d11ucode_ext.h>
+#endif
+
+#ifdef BCMSDIO
+extern struct device *sdiommc_dev;
+#endif
+
+extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg,
+ bool suspend);
+bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw);
+void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc);
+void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset,
+ const struct ether_addr *addr);
+
+static void wl_timer(ulong data);
+static void _wl_timer(wl_timer_t *t);
+
+/* proc fs */
+static int wl_proc_read(char *buffer, char **start, off_t offset, int length,
+ int *eof, void *data);
+static int wl_proc_write(struct file *filp, const char __user *buff,
+ unsigned long len, void *data);
+
+#ifdef WLC_HIGH_ONLY
+#define RPCQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->rpcq_lock, (_flags))
+#define RPCQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->rpcq_lock, (_flags))
+#define TXQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->txq_lock, (_flags))
+#define TXQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->txq_lock, (_flags))
+static void wl_rpc_down(void *wlh);
+static void wl_rpcq_free(wl_info_t *wl);
+static void wl_rpcq_dispatch(struct wl_task *task);
+static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf);
+static void wl_start_txqwork(struct wl_task *task);
+static void wl_txq_free(wl_info_t *wl);
+static void wl_timer_task(wl_task_t *task);
+static int wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *),
+ void *context);
+#endif /* WLC_HIGH_ONLY */
+
+static int ieee_hw_init(struct ieee80211_hw *hw);
+static int ieee_hw_rate_init(struct ieee80211_hw *hw);
+
+static int wl_linux_watchdog(void *ctx);
+
+/* Flags we support */
+#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
+ FIF_ALLMULTI | \
+ FIF_FCSFAIL | \
+ FIF_PLCPFAIL | \
+ FIF_CONTROL | \
+ FIF_OTHER_BSS | \
+ FIF_BCN_PRBRESP_PROMISC)
+
+static int wl_found;
+
+struct ieee80211_tkip_data {
+#define TKIP_KEY_LEN 32
+ u8 key[TKIP_KEY_LEN];
+ int key_set;
+
+ u32 tx_iv32;
+ u16 tx_iv16;
+ u16 tx_ttak[5];
+ int tx_phase1_done;
+
+ u32 rx_iv32;
+ u16 rx_iv16;
+ u16 rx_ttak[5];
+ int rx_phase1_done;
+ u32 rx_iv32_new;
+ u16 rx_iv16_new;
+
+ u32 dot11RSNAStatsTKIPReplays;
+ u32 dot11RSNAStatsTKIPICVErrors;
+ u32 dot11RSNAStatsTKIPLocalMICFailures;
+
+ int key_idx;
+
+ struct crypto_tfm *tfm_arc4;
+ struct crypto_tfm *tfm_michael;
+
+ /* scratch buffers for virt_to_page() (crypto API) */
+ u8 rx_hdr[16], tx_hdr[16];
+};
+
+#ifndef WLC_HIGH_ONLY
+#define WL_INFO(dev) ((wl_info_t *)(WL_DEV_IF(dev)->wl)) /* points to wl */
+static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev);
+static void wl_release_fw(wl_info_t *wl);
+#endif
+
+/* local prototypes */
+static int wl_start(struct sk_buff *skb, wl_info_t *wl);
+static int wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw,
+ struct sk_buff *skb);
+static void wl_dpc(ulong data);
+
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#ifndef BCMSDIO
+/* recognized PCI IDs */
+static struct pci_device_id wl_id_table[] = {
+ {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */
+ {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */
+ {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, wl_id_table);
+#endif /* !BCMSDIO */
+
+#ifdef BCMSDIO
+static uint sd_drivestrength = 6;
+module_param(sd_drivestrength, uint, 0);
+#endif
+
+#ifdef BCMDBG
+static int msglevel = 0xdeadbeef;
+module_param(msglevel, int, 0);
+#ifndef WLC_HIGH_ONLY
+static int phymsglevel = 0xdeadbeef;
+module_param(phymsglevel, int, 0);
+#endif /* WLC_HIGH_ONLY */
+#endif /* BCMDBG */
+
+static int oneonly;
+module_param(oneonly, int, 0);
+
+static int piomode;
+module_param(piomode, int, 0);
+
+static int instance_base; /* Starting instance number */
+module_param(instance_base, int, 0);
+
+#if defined(BCMDBG)
+static char *macaddr;
+module_param(macaddr, charp, S_IRUGO);
+#endif
+
+static int nompc = 1;
+module_param(nompc, int, 0);
+
+static char name[IFNAMSIZ] = "eth%d";
+module_param_string(name, name, IFNAMSIZ, 0);
+
+#ifndef SRCBASE
+#define SRCBASE "."
+#endif
+
+#define WL_MAGIC 0xdeadbeef
+
+#define HW_TO_WL(hw) (hw->priv)
+#define WL_TO_HW(wl) (wl->pub->ieee_hw)
+#ifdef WLC_HIGH_ONLY
+static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb);
+#else
+static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+#endif
+static int wl_ops_start(struct ieee80211_hw *hw);
+static void wl_ops_stop(struct ieee80211_hw *hw);
+static int wl_ops_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+static void wl_ops_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+static int wl_ops_config(struct ieee80211_hw *hw, u32 changed);
+static void wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed);
+static void wl_ops_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast);
+static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ bool set);
+static void wl_ops_sw_scan_start(struct ieee80211_hw *hw);
+static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw);
+static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
+static int wl_ops_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats);
+static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
+static void wl_ops_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta);
+static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params);
+static u64 wl_ops_get_tsf(struct ieee80211_hw *hw);
+static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+
+#ifdef WLC_HIGH_ONLY
+static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ int status;
+ wl_info_t *wl = hw->priv;
+ if (!wl->pub->up) {
+ WL_ERROR(("ops->tx called while down\n"));
+ status = -ENETDOWN;
+ goto done;
+ }
+ status = wl_start(skb, wl);
+ done:
+ return status;
+}
+#else
+static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ int status;
+ wl_info_t *wl = hw->priv;
+ WL_LOCK(wl);
+ if (!wl->pub->up) {
+ WL_ERROR(("ops->tx called while down\n"));
+ status = -ENETDOWN;
+ goto done;
+ }
+ status = wl_start(skb, wl);
+ done:
+ WL_UNLOCK(wl);
+ return status;
+}
+#endif /* WLC_HIGH_ONLY */
+
+static int wl_ops_start(struct ieee80211_hw *hw)
+{
+ wl_info_t *wl = hw->priv;
+ /* struct ieee80211_channel *curchan = hw->conf.channel; */
+ WL_NONE(("%s : Initial channel: %d\n", __func__, curchan->hw_value));
+
+ WL_LOCK(wl);
+ ieee80211_wake_queues(hw);
+ WL_UNLOCK(wl);
+
+ return 0;
+}
+
+static void wl_ops_stop(struct ieee80211_hw *hw)
+{
+ wl_info_t *wl = hw->priv;
+ ASSERT(wl);
+ WL_LOCK(wl);
+ wl_down(wl);
+ ieee80211_stop_queues(hw);
+ WL_UNLOCK(wl);
+
+ return;
+}
+
+static int
+wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ wl_info_t *wl;
+ int err;
+
+ /* Just STA for now */
+ if (vif->type != NL80211_IFTYPE_AP &&
+ vif->type != NL80211_IFTYPE_MESH_POINT &&
+ vif->type != NL80211_IFTYPE_STATION &&
+ vif->type != NL80211_IFTYPE_WDS &&
+ vif->type != NL80211_IFTYPE_ADHOC) {
+ WL_ERROR(("%s: Attempt to add type %d, only STA for now\n",
+ __func__, vif->type));
+ return -EOPNOTSUPP;
+ }
+
+ wl = HW_TO_WL(hw);
+ WL_LOCK(wl);
+ err = wl_up(wl);
+ WL_UNLOCK(wl);
+
+ if (err != 0)
+ WL_ERROR(("%s: wl_up() returned %d\n", __func__, err));
+ return err;
+}
+
+static void
+wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ return;
+}
+
+static int
+ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
+ enum nl80211_channel_type type)
+{
+ wl_info_t *wl = HW_TO_WL(hw);
+ int err = 0;
+
+ switch (type) {
+ case NL80211_CHAN_HT20:
+ case NL80211_CHAN_NO_HT:
+ WL_LOCK(wl);
+ err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
+ WL_UNLOCK(wl);
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ case NL80211_CHAN_HT40PLUS:
+ WL_ERROR(("%s: Need to implement 40 Mhz Channels!\n",
+ __func__));
+ break;
+ }
+
+ if (err)
+ return -EIO;
+ return err;
+}
+
+static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct ieee80211_conf *conf = &hw->conf;
+ wl_info_t *wl = HW_TO_WL(hw);
+ int err = 0;
+ int new_int;
+
+ if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+ WL_NONE(("%s: Setting listen interval to %d\n",
+ __func__, conf->listen_interval));
+ if (wlc_iovar_setint
+ (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
+ WL_ERROR(("%s: Error setting listen_interval\n",
+ __func__));
+ err = -EIO;
+ goto config_out;
+ }
+ wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
+ ASSERT(new_int == conf->listen_interval);
+ }
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR)
+ WL_NONE(("Need to set monitor mode\n"));
+ if (changed & IEEE80211_CONF_CHANGE_PS)
+ WL_NONE(("Need to set Power-save mode\n"));
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ WL_NONE(("%s: Setting tx power to %d dbm\n", __func__,
+ conf->power_level));
+ if (wlc_iovar_setint
+ (wl->wlc, "qtxpower", conf->power_level * 4)) {
+ WL_ERROR(("%s: Error setting power_level\n", __func__));
+ err = -EIO;
+ goto config_out;
+ }
+ wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
+ if (new_int != (conf->power_level * 4))
+ WL_ERROR(("%s: Power level req != actual, %d %d\n",
+ __func__, conf->power_level * 4, new_int));
+ }
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ err = ieee_set_channel(hw, conf->channel, conf->channel_type);
+ }
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ WL_NONE(("%s: srl %d, lrl %d\n", __func__,
+ conf->short_frame_max_tx_count,
+ conf->long_frame_max_tx_count));
+ if (wlc_set
+ (wl->wlc, WLC_SET_SRL,
+ conf->short_frame_max_tx_count) < 0) {
+ WL_ERROR(("%s: Error setting srl\n", __func__));
+ err = -EIO;
+ goto config_out;
+ }
+ if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
+ < 0) {
+ WL_ERROR(("%s: Error setting lrl\n", __func__));
+ err = -EIO;
+ goto config_out;
+ }
+ }
+
+ config_out:
+ return err;
+}
+
+static void
+wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info, u32 changed)
+{
+ wl_info_t *wl = HW_TO_WL(hw);
+ int val;
+
+#ifdef WLC_HIGH_ONLY
+ WL_LOCK(wl);
+#endif
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ WL_ERROR(("Associated:\t%s\n", info->assoc ? "True" : "False"));
+ /* association status changed (associated/disassociated)
+ * also implies a change in the AID.
+ */
+ }
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ WL_NONE(("Use_cts_prot:\t%s Implement me\n",
+ info->use_cts_prot ? "True" : "False"));
+ /* CTS protection changed */
+ }
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ WL_NONE(("Short preamble:\t%s Implement me\n",
+ info->use_short_preamble ? "True" : "False"));
+ /* preamble changed */
+ }
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ WL_NONE(("Changing short slot:\t%s\n",
+ info->use_short_slot ? "True" : "False"));
+ if (info->use_short_slot)
+ val = 1;
+ else
+ val = 0;
+ wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
+ /* slot timing changed */
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ WL_NONE(("%s: HT mode - Implement me\n", __func__));
+ /* 802.11n parameters changed */
+ }
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ WL_NONE(("Need to change Basic Rates:\t0x%x! Implement me\n",
+ (uint32) info->basic_rates));
+ /* Basic rateset changed */
+ }
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ WL_NONE(("Beacon Interval:\t%d Implement me\n",
+ info->beacon_int));
+ /* Beacon interval changed */
+ }
+ if (changed & BSS_CHANGED_BSSID) {
+ /* char eabuf[ETHER_ADDR_STR_LEN]; */
+ WL_NONE(("new BSSID:\taid %d bss:%s\n",
+ info->aid,
+ bcm_ether_ntoa((struct ether_addr *)info->bssid,
+ eabuf)));
+ /* BSSID changed, for whatever reason (IBSS and managed mode) */
+ /* FIXME: need to store bssid in bsscfg */
+ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
+ (struct ether_addr *)info->bssid);
+ }
+ if (changed & BSS_CHANGED_BEACON) {
+ WL_ERROR(("BSS_CHANGED_BEACON\n"));
+ /* Beacon data changed, retrieve new beacon (beaconing modes) */
+ }
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ WL_ERROR(("Beacon enabled:\t%s\n",
+ info->enable_beacon ? "True" : "False"));
+ /* Beaconing should be enabled/disabled (beaconing modes) */
+ }
+#ifdef WLC_HIGH_ONLY
+ WL_UNLOCK(wl);
+#endif
+ return;
+}
+
+static void
+wl_ops_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast)
+{
+#ifndef WLC_HIGH_ONLY
+ wl_info_t *wl = hw->priv;
+#endif
+
+ changed_flags &= MAC_FILTERS;
+ *total_flags &= MAC_FILTERS;
+ if (changed_flags & FIF_PROMISC_IN_BSS)
+ WL_ERROR(("FIF_PROMISC_IN_BSS\n"));
+ if (changed_flags & FIF_ALLMULTI)
+ WL_ERROR(("FIF_ALLMULTI\n"));
+ if (changed_flags & FIF_FCSFAIL)
+ WL_ERROR(("FIF_FCSFAIL\n"));
+ if (changed_flags & FIF_PLCPFAIL)
+ WL_ERROR(("FIF_PLCPFAIL\n"));
+ if (changed_flags & FIF_CONTROL)
+ WL_ERROR(("FIF_CONTROL\n"));
+ if (changed_flags & FIF_OTHER_BSS)
+ WL_ERROR(("FIF_OTHER_BSS\n"));
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ WL_NONE(("FIF_BCN_PRBRESP_PROMISC\n"));
+#ifndef WLC_HIGH_ONLY
+ WL_LOCK(wl);
+ if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
+ wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
+ wlc_mac_bcn_promisc_change(wl->wlc, 1);
+ } else {
+ wlc_mac_bcn_promisc_change(wl->wlc, 0);
+ wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
+ }
+ WL_UNLOCK(wl);
+#endif
+ }
+ return;
+}
+
+static int
+wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+{
+ WL_ERROR(("%s: Enter\n", __func__));
+ return 0;
+}
+
+static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
+{
+ WL_NONE(("Scan Start\n"));
+ return;
+}
+
+static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ WL_NONE(("Scan Complete\n"));
+ return;
+}
+
+static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ WL_ERROR(("%s: Enter\n", __func__));
+ return;
+}
+
+static int
+wl_ops_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ WL_ERROR(("%s: Enter\n", __func__));
+ return 0;
+}
+
+static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ WL_ERROR(("%s: Enter\n", __func__));
+ return 0;
+}
+
+static void
+wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
+{
+ WL_NONE(("%s: Enter\n", __func__));
+ switch (cmd) {
+ default:
+ WL_ERROR(("%s: Uknown cmd = %d\n", __func__, cmd));
+ break;
+ }
+ return;
+}
+
+static int
+wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ wl_info_t *wl = hw->priv;
+
+ WL_NONE(("%s: Enter (WME config)\n", __func__));
+ WL_NONE(("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
+ params->txop, params->cw_min, params->cw_max, params->aifs));
+
+ WL_LOCK(wl);
+ wlc_wme_setparams(wl->wlc, queue, (void *)params, TRUE);
+ WL_UNLOCK(wl);
+
+ return 0;
+}
+
+static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
+{
+ WL_ERROR(("%s: Enter\n", __func__));
+ return 0;
+}
+
+static int
+wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct scb *scb;
+
+ int i;
+ wl_info_t *wl = hw->priv;
+
+ /* Init the scb */
+ scb = (struct scb *)sta->drv_priv;
+ bzero(scb, sizeof(struct scb));
+ for (i = 0; i < NUMPRIO; i++)
+ scb->seqctl[i] = 0xFFFF;
+ scb->seqctl_nonqos = 0xFFFF;
+ scb->magic = SCB_MAGIC;
+
+ wl->pub->global_scb = scb;
+ wl->pub->global_ampdu = &(scb->scb_ampdu);
+ wl->pub->global_ampdu->scb = scb;
+#ifdef WLC_HIGH_ONLY
+ wl->pub->global_ampdu->max_pdu = AMPDU_NUM_MPDU;
+#else
+ wl->pub->global_ampdu->max_pdu = 16;
+#endif
+ pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
+ AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
+
+ sta->ht_cap.ht_supported = TRUE;
+#ifdef WLC_HIGH_ONLY
+ sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_16K;
+#else
+ sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K;
+#endif
+ sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
+ sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+
+ /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
+ return 0;
+}
+
+static int
+wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ WL_NONE(("%s: Enter\n", __func__));
+ return 0;
+}
+
+static int
+wl_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+#if defined(BCMDBG)
+ struct scb *scb = (struct scb *)sta->drv_priv;
+#endif
+ wl_info_t *wl = hw->priv;
+
+ ASSERT(scb->magic == SCB_MAGIC);
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ WL_NONE(("%s: action = IEEE80211_AMPDU_RX_START\n", __func__));
+ break;
+ case IEEE80211_AMPDU_RX_STOP:
+ WL_NONE(("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__));
+ break;
+ case IEEE80211_AMPDU_TX_START:
+ if (!wlc_aggregatable(wl->wlc, tid)) {
+ /* WL_ERROR(("START: tid %d is not agg' able, return FAILURE to stack\n", tid)); */
+ return -1;
+ }
+ /* XXX: Use the starting sequence number provided ... */
+ *ssn = 0;
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
+
+ case IEEE80211_AMPDU_TX_STOP:
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ /* Not sure what to do here */
+ /* Power save wakeup */
+ WL_NONE(("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
+ __func__));
+ break;
+ default:
+ WL_ERROR(("%s: Invalid command, ignoring\n", __func__));
+ }
+
+ return 0;
+}
+
+static const struct ieee80211_ops wl_ops = {
+#ifdef WLC_HIGH_ONLY
+ .tx = wl_ops_tx_nl,
+#else
+ .tx = wl_ops_tx,
+#endif
+ .start = wl_ops_start,
+ .stop = wl_ops_stop,
+ .add_interface = wl_ops_add_interface,
+ .remove_interface = wl_ops_remove_interface,
+ .config = wl_ops_config,
+ .bss_info_changed = wl_ops_bss_info_changed,
+ .configure_filter = wl_ops_configure_filter,
+ .set_tim = wl_ops_set_tim,
+ .sw_scan_start = wl_ops_sw_scan_start,
+ .sw_scan_complete = wl_ops_sw_scan_complete,
+ .set_tsf = wl_ops_set_tsf,
+ .get_stats = wl_ops_get_stats,
+ .set_rts_threshold = wl_ops_set_rts_threshold,
+ .sta_notify = wl_ops_sta_notify,
+ .conf_tx = wl_ops_conf_tx,
+ .get_tsf = wl_ops_get_tsf,
+ .sta_add = wl_sta_add,
+ .sta_remove = wl_sta_remove,
+ .ampdu_action = wl_ampdu_action,
+};
+
+static int wl_set_hint(wl_info_t *wl, char *abbrev)
+{
+ WL_ERROR(("%s: Sending country code %c%c to MAC80211\n", __func__,
+ abbrev[0], abbrev[1]));
+ return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
+}
+
+/**
+ * attach to the WL device.
+ *
+ * Attach to the WL device identified by vendor and device parameters.
+ * regs is a host accessible memory address pointing to WL device registers.
+ *
+ * wl_attach is not defined as static because in the case where no bus
+ * is defined, wl_attach will never be called, and thus, gcc will issue
+ * a warning that this function is defined but not used if we declare
+ * it as static.
+ */
+static wl_info_t *wl_attach(uint16 vendor, uint16 device, ulong regs,
+ uint bustype, void *btparam, uint irq)
+{
+ wl_info_t *wl;
+ osl_t *osh;
+ int unit, err;
+
+ ulong base_addr;
+ struct ieee80211_hw *hw;
+ uint8 perm[ETH_ALEN];
+
+ unit = wl_found + instance_base;
+ err = 0;
+
+ if (unit < 0) {
+ WL_ERROR(("wl%d: unit number overflow, exiting\n", unit));
+ return NULL;
+ }
+
+ if (oneonly && (unit != instance_base)) {
+ WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit));
+ return NULL;
+ }
+
+ /* Requires pkttag feature */
+ osh = osl_attach(btparam, bustype, TRUE);
+ ASSERT(osh);
+
+#ifdef WLC_HIGH_ONLY
+ hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
+ if (!hw) {
+ WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
+ ASSERT(0);
+ }
+
+ bzero(hw->priv, sizeof(*wl));
+ wl = hw->priv;
+#else
+ /* allocate private info */
+ hw = pci_get_drvdata(btparam); /* btparam == pdev */
+ wl = hw->priv;
+#endif
+ ASSERT(wl);
+
+ wl->magic = WL_MAGIC;
+ wl->osh = osh;
+ atomic_set(&wl->callbacks, 0);
+
+ /* setup the bottom half handler */
+ tasklet_init(&wl->tasklet, wl_dpc, (ulong) wl);
+
+#ifdef WLC_HIGH_ONLY
+ wl->rpc_th = bcm_rpc_tp_attach(osh, NULL);
+ if (wl->rpc_th == NULL) {
+ WL_ERROR(("wl%d: %s: bcm_rpc_tp_attach failed!\n", unit,
+ __func__));
+ goto fail;
+ }
+
+ wl->rpc = bcm_rpc_attach(NULL, osh, wl->rpc_th);
+ if (wl->rpc == NULL) {
+ WL_ERROR(("wl%d: %s: bcm_rpc_attach failed!\n", unit,
+ __func__));
+ goto fail;
+ }
+
+ /* init tx work queue for wl_start/send pkt; no need to destroy workitem */
+ MY_INIT_WORK(&wl->txq_task.work, (work_func_t) wl_start_txqwork);
+ wl->txq_task.context = wl;
+#endif /* WLC_HIGH_ONLY */
+
+#ifdef BCMSDIO
+ SET_IEEE80211_DEV(hw, sdiommc_dev);
+#endif
+
+ base_addr = regs;
+
+ if (bustype == PCI_BUS) {
+ /* piomode can be overwritten by command argument */
+ wl->piomode = piomode;
+ WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA"));
+ } else if (bustype == RPC_BUS) {
+ /* Do nothing */
+ } else {
+ bustype = PCI_BUS;
+ WL_TRACE(("force to PCI\n"));
+ }
+ wl->bcm_bustype = bustype;
+
+#ifdef WLC_HIGH_ONLY
+ if (wl->bcm_bustype == RPC_BUS) {
+ wl->regsva = (void *)0;
+ btparam = wl->rpc;
+ } else
+#endif
+ wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
+ if (wl->regsva == NULL) {
+ WL_ERROR(("wl%d: ioremap() failed\n", unit));
+ goto fail;
+ }
+#ifdef WLC_HIGH_ONLY
+ spin_lock_init(&wl->rpcq_lock);
+ spin_lock_init(&wl->txq_lock);
+
+ init_MUTEX(&wl->sem);
+#else
+ spin_lock_init(&wl->lock);
+ spin_lock_init(&wl->isr_lock);
+#endif
+
+#ifndef WLC_HIGH_ONLY
+ /* prepare ucode */
+ if (wl_request_fw(wl, (struct pci_dev *)btparam)) {
+ printf("%s: %s driver failed\n", KBUILD_MODNAME,
+ EPI_VERSION_STR);
+ goto fail;
+ }
+#endif
+
+ /* common load-time initialization */
+ wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh,
+ wl->regsva, wl->bcm_bustype, btparam, &err);
+#ifndef WLC_HIGH_ONLY
+ wl_release_fw(wl);
+#endif
+ if (!wl->wlc) {
+ printf("%s: %s driver failed with code %d\n", KBUILD_MODNAME,
+ EPI_VERSION_STR, err);
+ goto fail;
+ }
+ wl->pub = wlc_pub(wl->wlc);
+
+ wl->pub->ieee_hw = hw;
+ ASSERT(wl->pub->ieee_hw);
+ ASSERT(wl->pub->ieee_hw->priv == wl);
+
+#ifdef WLC_HIGH_ONLY
+ REGOPSSET(osh, (osl_rreg_fn_t) wlc_reg_read,
+ (osl_wreg_fn_t) wlc_reg_write, wl->wlc);
+ wl->rpc_dispatch_ctx.rpc = wl->rpc;
+ wl->rpc_dispatch_ctx.wlc = wl->wlc;
+ bcm_rpc_rxcb_init(wl->rpc, wl, wl_rpc_dispatch_schedule, wl,
+ wl_rpc_down, NULL, NULL);
+#endif /* WLC_HIGH_ONLY */
+
+ if (nompc) {
+ if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+ WL_ERROR(("wl%d: Error setting MPC variable to 0\n",
+ unit));
+ }
+ }
+#ifdef BCMSDIO
+ /* Set SDIO drive strength */
+ wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength);
+#endif
+
+#ifdef WLC_LOW
+ /* register our interrupt handler */
+ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
+ WL_ERROR(("wl%d: request_irq() failed\n", unit));
+ goto fail;
+ }
+ wl->irq = irq;
+#endif /* WLC_LOW */
+
+ /* register module */
+ wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
+ NULL);
+
+ if (ieee_hw_init(hw)) {
+ WL_ERROR(("wl%d: %s: ieee_hw_init failed!\n", unit, __func__));
+ goto fail;
+ }
+
+ bcopy(&wl->pub->cur_etheraddr, perm, ETHER_ADDR_LEN);
+ ASSERT(is_valid_ether_addr(perm));
+ SET_IEEE80211_PERM_ADDR(hw, perm);
+
+ err = ieee80211_register_hw(hw);
+ if (err) {
+ WL_ERROR(("%s: ieee80211_register_hw failed, status %d\n",
+ __func__, err));
+ }
+
+ if (wl->pub->srom_ccode[0])
+ err = wl_set_hint(wl, wl->pub->srom_ccode);
+ else
+ err = wl_set_hint(wl, "US");
+ if (err) {
+ WL_ERROR(("%s: regulatory_hint failed, status %d\n", __func__,
+ err));
+ }
+#ifndef WLC_HIGH_ONLY
+ WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
+ EPI_VERSION_STR " (" PHY_VERSION_STR ")", unit));
+#else
+ WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
+ EPI_VERSION_STR, unit));
+#endif
+
+#ifdef BCMDBG
+ printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
+#endif /* BCMDBG */
+ printf("\n");
+
+ wl->proc_entry = create_proc_entry(PROC_ENTRY_NAME, 0644, NULL);
+ if (wl->proc_entry == NULL) {
+ WL_ERROR(("create_proc_entry failed *******\n"));
+ ASSERT(0);
+ } else {
+ wl->proc_entry->read_proc = wl_proc_read;
+ wl->proc_entry->write_proc = wl_proc_write;
+ wl->proc_entry->data = wl;
+ /* wl->proc_entry->owner = THIS_MODULE; */
+
+ wl->ioctlbuf = (char *)vmalloc(PAGE_SIZE);
+ if (wl->ioctlbuf == NULL) {
+ WL_ERROR(("%s: Vmalloc failed\n", __func__));
+ }
+ wl->ioctlbuf_sz = PAGE_SIZE;
+ memset(wl->ioctlbuf, 0, PAGE_SIZE);
+ wl->ioctlbuf[0] = '!';
+ }
+
+ wl_found++;
+ return wl;
+
+ fail:
+ wl_free(wl);
+ return NULL;
+}
+
+#define PROC_MESSAGE "Broadcom driver debugger access only. Requires matching 'wl' app\n"
+
+/* OS Entry point when app attempts to read */
+static int
+wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof,
+ void *data)
+{
+ wl_info_t *wl = (wl_info_t *) data;
+
+ switch (wl->proc_state) {
+
+ case WL_PROC_IDLE:
+ return 0;
+
+ case WL_PROC_HAVE_IOC:
+ /* Give the processed buffer back to userland */
+ if (!wl->ioctl_in_progress) {
+ WL_ERROR(("%s: No ioctl in progress nothing to read, 2\n", __func__));
+ return 0;
+ }
+
+ if (wl->ioc.len > wl->ioctlbuf_sz) {
+ }
+ bcopy(wl->ioctlbuf, buffer + offset, wl->ioc.len);
+ wl->proc_state--;
+ wl->ioctl_in_progress = 0;
+ return wl->ioc.len + offset;
+
+ case WL_PROC_HAVE_BUF:
+ /* Give the processed IOC back to userland */
+ if (!wl->ioctl_in_progress) {
+ WL_ERROR(("%s: No ioctl in progress nothing to read, 1\n", __func__));
+ return 0;
+ }
+ if (length != sizeof(wl_ioctl_t)) {
+ WL_ERROR(("%s: Reading ioc but len != sizeof(wl_ioctl_t)\n", __func__));
+ return 0;
+ }
+ bcopy(&wl->ioc, buffer + offset, length);
+ wl->proc_state--;
+ return length + offset;
+
+ default:
+ WL_ERROR(("%s: Proc read out of sync. proc_state %d, ioctl_in_progress %d\n", __func__, wl->proc_state, wl->ioctl_in_progress));
+ }
+
+ WL_ERROR(("%s: Invalid ioctl!!!\n", __func__));
+ return 0;
+}
+
+/* OS Entry point when app attempts to write */
+static int
+wl_proc_write(struct file *filp, const char __user *buff, unsigned long length,
+ void *data)
+{
+ wl_info_t *wl = (wl_info_t *) data;
+ int bcmerror;
+
+ switch (wl->proc_state) {
+
+ case WL_PROC_IDLE:
+ if (wl->ioctl_in_progress) {
+ WL_ERROR(("%s: ioctl still in progress\n", __func__));
+ return -EIO;
+ }
+ if (length != sizeof(wl_ioctl_t)) {
+ WL_ERROR(("%s: Expecting ioctl sized buf\n", __func__));
+ return -EIO;
+ }
+ if (copy_from_user(&wl->ioc, buff, sizeof(wl_ioctl_t))) {
+ WL_ERROR(("%s: copy from user failed\n", __func__));
+ return -EIO;
+ }
+ wl->proc_state++;
+ wl->ioctl_in_progress++;
+ return sizeof(wl_ioctl_t);
+
+ case WL_PROC_HAVE_IOC:
+ if (!wl->ioctl_in_progress) {
+ WL_ERROR(("%s: Ioctl not ready yet 1\n", __func__));
+ return -EIO;
+ }
+ if (wl->ioctlbuf_sz < length) {
+ WL_ERROR(("%s: Buf write, ioctl buf %d not big enough too hold buffer %d\n", __func__, (int)sizeof(wl->ioctlbuf), (int)length));
+ WL_ERROR(("Shortening input\n"));
+ length = wl->ioctlbuf_sz;
+ }
+ if (length != wl->ioc.len) {
+ WL_ERROR(("%s: ioc.len %d != length param %d\n",
+ __func__, wl->ioc.len, (int)length));
+ return -EIO;
+ }
+ if (copy_from_user(wl->ioctlbuf, buff, length)) {
+ WL_ERROR(("%s: copy from user of %d bytes failed\n",
+ __func__, (int)length));
+ return -EIO;
+ }
+ wl->proc_state++;
+
+ WL_LOCK(wl);
+ bcmerror =
+ wlc_ioctl(wl->wlc, wl->ioc.cmd, wl->ioctlbuf, wl->ioc.len,
+ NULL);
+ WL_UNLOCK(wl);
+
+ if (bcmerror < 0)
+ return bcmerror;
+
+ return length;
+
+ case WL_PROC_HAVE_BUF:
+ WL_ERROR(("%s: Illegal write. Rejecting.\n", __func__));
+ return 0;
+ default:
+ WL_ERROR(("%s: Proc write out of sync. proc_state %d, ioctl_in_progress %d\n", __func__, wl->proc_state, wl->ioctl_in_progress));
+ }
+ return 0;
+}
+
+#ifdef WLC_HIGH_ONLY
+static void *wl_dbus_probe_cb(void *arg, const char *desc, uint32 bustype,
+ uint32 hdrlen)
+{
+ wl_info_t *wl;
+ WL_ERROR(("%s:\n", __func__));
+
+ wl = wl_attach(BCM_DNGL_VID, BCM_DNGL_BDC_PID, (ulong) NULL, RPC_BUS,
+ NULL, 0);
+ if (!wl) {
+ WL_ERROR(("%s: wl_attach failed\n", __func__));
+ }
+
+ /* This is later passed to wl_dbus_disconnect_cb */
+ return wl;
+}
+
+static void wl_dbus_disconnect_cb(void *arg)
+{
+ wl_info_t *wl = arg;
+
+ WL_ERROR(("%s:\n", __func__));
+
+ if (wl) {
+#ifdef WLC_HIGH_ONLY
+ if (wl->pub->ieee_hw) {
+ ieee80211_unregister_hw(wl->pub->ieee_hw);
+ WL_ERROR(("%s: Back from down\n", __func__));
+ }
+ wlc_device_removed(wl->wlc);
+ wlc_bmac_dngl_reboot(wl->rpc);
+ bcm_rpc_down(wl->rpc);
+#endif
+ WL_LOCK(wl);
+ wl_down(wl);
+ WL_UNLOCK(wl);
+#ifdef WLC_HIGH_ONLY
+ if (wl->pub->ieee_hw) {
+ ieee80211_free_hw(wl->pub->ieee_hw);
+ WL_ERROR(("%s: Back from ieee80211_free_hw\n",
+ __func__));
+ wl->pub->ieee_hw = NULL;
+ }
+#endif
+ wl_free(wl);
+ }
+}
+#endif /* WLC_HIGH_ONLY */
+
+#ifndef BCMSDIO
+static void __devexit wl_remove(struct pci_dev *pdev);
+#endif
+
+#define CHAN2GHZ(channel, freqency, chflags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (freqency), \
+ .hw_value = (channel), \
+ .flags = chflags, \
+ .max_antenna_gain = 0, \
+ .max_power = 19, \
+}
+
+static struct ieee80211_channel wl_2ghz_chantable[] = {
+ CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN2GHZ(5, 2432, 0),
+ CHAN2GHZ(6, 2437, 0),
+ CHAN2GHZ(7, 2442, 0),
+ CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(12, 2467,
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(13, 2472,
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN2GHZ(14, 2484,
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+};
+
+#define CHAN5GHZ(channel, chflags) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = 5000 + 5*(channel), \
+ .hw_value = (channel), \
+ .flags = chflags, \
+ .max_antenna_gain = 0, \
+ .max_power = 21, \
+}
+
+static struct ieee80211_channel wl_5ghz_nphy_chantable[] = {
+ /* UNII-1 */
+ CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
+ /* UNII-2 */
+ CHAN5GHZ(52,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(56,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(60,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(64,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ /* MID */
+ CHAN5GHZ(100,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(104,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(108,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(112,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(116,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(120,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(124,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(128,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(132,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(136,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(140,
+ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
+ IEEE80211_CHAN_NO_HT40MINUS),
+ /* UNII-3 */
+ CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
+ CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
+ CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+};
+
+#define RATE(rate100m, _flags) { \
+ .bitrate = (rate100m), \
+ .flags = (_flags), \
+ .hw_value = (rate100m / 5), \
+}
+
+static struct ieee80211_rate wl_legacy_ratetable[] = {
+ RATE(10, 0),
+ RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(60, 0),
+ RATE(90, 0),
+ RATE(120, 0),
+ RATE(180, 0),
+ RATE(240, 0),
+ RATE(360, 0),
+ RATE(480, 0),
+ RATE(540, 0),
+};
+
+static struct ieee80211_supported_band wl_band_2GHz_nphy = {
+ .band = IEEE80211_BAND_2GHZ,
+ .channels = wl_2ghz_chantable,
+ .n_channels = ARRAY_SIZE(wl_2ghz_chantable),
+ .bitrates = wl_legacy_ratetable,
+ .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable),
+ .ht_cap = {
+ /* from include/linux/ieee80211.h */
+ .cap = IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
+#ifdef WLC_HIGH_ONLY
+ .ht_supported = true,
+ .ampdu_factor = AMPDU_RX_FACTOR_16K,
+#else
+ .ht_supported = true,
+ .ampdu_factor = AMPDU_RX_FACTOR_64K,
+#endif
+ .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+ .mcs = {
+ /* placeholders for now */
+#ifdef WLC_HIGH_ONLY
+ /*
+ * rx_mask[0] = 0xff by default
+ * rx_mask[1] = 0xff if number of rx chain >=2
+ * rx_mask[2] = 0xff if number of rx chain >=3
+ * rx_mask[4] = 1 if 40Mhz is supported
+ */
+ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ .rx_highest = 72, /* max rate of single stream */
+#else
+ .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+ .rx_highest = 500,
+#endif
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+ }
+};
+
+static struct ieee80211_supported_band wl_band_5GHz_nphy = {
+ .band = IEEE80211_BAND_5GHZ,
+ .channels = wl_5ghz_nphy_chantable,
+ .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable),
+ .bitrates = wl_legacy_ratetable + 4,
+ .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4,
+ .ht_cap = {
+ /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
+ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */
+ .ht_supported = true,
+ .ampdu_factor = AMPDU_RX_FACTOR_64K,
+ .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+ .mcs = {
+ /* placeholders for now */
+ .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+ .rx_highest = 500,
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+ }
+};
+
+static int ieee_hw_rate_init(struct ieee80211_hw *hw)
+{
+ wl_info_t *wl = HW_TO_WL(hw);
+ int has_5g;
+ char phy_list[4];
+
+ has_5g = 0;
+
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+
+ if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
+ WL_ERROR(("Phy list failed\n"));
+ }
+ WL_NONE(("%s: phylist = %c\n", __func__, phy_list[0]));
+
+#ifndef WLC_HIGH_ONLY
+ if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+ if (phy_list[0] == 'c') {
+ /* Single stream */
+ wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
+ wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
+ }
+#else
+ if (phy_list[0] == 's') {
+#endif
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
+ } else {
+ BUG();
+ return -1;
+ }
+
+ /* Assume all bands use the same phy. True for 11n devices. */
+ if (NBANDS_PUB(wl->pub) > 1) {
+ has_5g++;
+#ifndef WLC_HIGH_ONLY
+ if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+#else
+ if (phy_list[0] == 's') {
+#endif
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &wl_band_5GHz_nphy;
+ } else {
+ return -1;
+ }
+ }
+
+ WL_NONE(("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g));
+
+ return 0;
+}
+
+static int ieee_hw_init(struct ieee80211_hw *hw)
+{
+ hw->flags = IEEE80211_HW_SIGNAL_DBM
+ /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */
+ | IEEE80211_HW_REPORTS_TX_ACK_STATUS
+ | IEEE80211_HW_AMPDU_AGGREGATION;
+
+ hw->extra_tx_headroom = wlc_get_header_len();
+ /* FIXME: should get this from wlc->machwcap */
+ hw->queues = 4;
+ /* FIXME: this doesn't seem to be used properly in minstrel_ht.
+ * mac80211/status.c:ieee80211_tx_status() checks this value,
+ * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
+ * appears to always set 3 rates
+ */
+ hw->max_rates = 2; /* Primary rate and 1 fallback rate */
+
+ hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+ hw->rate_control_algorithm = "minstrel_ht";
+
+ hw->sta_data_size = sizeof(struct scb);
+ return ieee_hw_rate_init(hw);
+}
+
+#ifndef BCMSDIO
+/**
+ * determines if a device is a WL device, and if so, attaches it.
+ *
+ * This function determines if a device pointed to by pdev is a WL device,
+ * and if so, performs a wl_attach() on it.
+ *
+ */
+int __devinit
+wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int rc;
+ wl_info_t *wl;
+ struct ieee80211_hw *hw;
+ uint32 val;
+
+ ASSERT(pdev);
+
+ WL_TRACE(("%s: bus %d slot %d func %d irq %d\n", __func__,
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->irq));
+
+ if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
+ (((pdev->device & 0xff00) != 0x4300) &&
+ ((pdev->device & 0xff00) != 0x4700) &&
+ ((pdev->device < 43000) || (pdev->device > 43999))))
+ return -ENODEV;
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ WL_ERROR(("%s: Cannot enable device %d-%d_%d\n", __func__,
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn)));
+ return -ENODEV;
+ }
+ pci_set_master(pdev);
+
+ pci_read_config_dword(pdev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+ hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
+ if (!hw) {
+ WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
+ rc = -ENOMEM;
+ goto err_1;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+
+ pci_set_drvdata(pdev, hw);
+
+ bzero(hw->priv, sizeof(*wl));
+
+ wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
+ PCI_BUS, pdev, pdev->irq);
+
+ return 0;
+ err_1:
+ WL_ERROR(("%s: err_1: Major hoarkage\n", __func__));
+ return 0;
+}
+
+#ifdef LINUXSTA_PS
+static int wl_suspend(struct pci_dev *pdev, DRV_SUSPEND_STATE_TYPE state)
+{
+ wl_info_t *wl;
+ struct ieee80211_hw *hw;
+
+ WL_TRACE(("wl: wl_suspend\n"));
+
+ hw = pci_get_drvdata(pdev);
+ wl = HW_TO_WL(hw);
+ if (!wl) {
+ WL_ERROR(("wl: wl_suspend: pci_get_drvdata failed\n"));
+ return -ENODEV;
+ }
+
+ WL_LOCK(wl);
+ wl_down(wl);
+ wl->pub->hw_up = FALSE;
+ WL_UNLOCK(wl);
+ PCI_SAVE_STATE(pdev, wl->pci_psstate);
+ pci_disable_device(pdev);
+ return pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static int wl_resume(struct pci_dev *pdev)
+{
+ wl_info_t *wl;
+ struct ieee80211_hw *hw;
+ int err = 0;
+ uint32 val;
+
+ WL_TRACE(("wl: wl_resume\n"));
+ hw = pci_get_drvdata(pdev);
+ wl = HW_TO_WL(hw);
+ if (!wl) {
+ WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n"));
+ return -ENODEV;
+ }
+
+ err = pci_set_power_state(pdev, PCI_D0);
+ if (err)
+ return err;
+
+ PCI_RESTORE_STATE(pdev, wl->pci_psstate);
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ pci_set_master(pdev);
+
+ pci_read_config_dword(pdev, 0x40, &val);
+ if ((val & 0x0000ff00) != 0)
+ pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+ WL_LOCK(wl);
+ err = wl_up(wl);
+ WL_UNLOCK(wl);
+
+ return err;
+}
+#endif /* LINUXSTA_PS */
+
+static void __devexit wl_remove(struct pci_dev *pdev)
+{
+ wl_info_t *wl;
+ struct ieee80211_hw *hw;
+
+ hw = pci_get_drvdata(pdev);
+ wl = HW_TO_WL(hw);
+ if (!wl) {
+ WL_ERROR(("wl: wl_remove: pci_get_drvdata failed\n"));
+ return;
+ }
+ if (!wlc_chipmatch(pdev->vendor, pdev->device)) {
+ WL_ERROR(("wl: wl_remove: wlc_chipmatch failed\n"));
+ return;
+ }
+
+ ieee80211_unregister_hw(hw);
+
+ WL_LOCK(wl);
+ wl_down(wl);
+ WL_UNLOCK(wl);
+ WL_NONE(("%s: Down\n", __func__));
+
+ pci_disable_device(pdev);
+
+ wl_free(wl);
+
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+}
+
+static struct pci_driver wl_pci_driver = {
+ .name = "brcm80211",
+ .probe = wl_pci_probe,
+#ifdef LINUXSTA_PS
+ .suspend = wl_suspend,
+ .resume = wl_resume,
+#endif /* LINUXSTA_PS */
+ .remove = __devexit_p(wl_remove),
+ .id_table = wl_id_table,
+};
+#endif /* !BCMSDIO */
+
+/**
+ * This is the main entry point for the WL driver.
+ *
+ * This function determines if a device pointed to by pdev is a WL device,
+ * and if so, performs a wl_attach() on it.
+ *
+ */
+static int __init wl_module_init(void)
+{
+ int error = -ENODEV;
+
+#ifdef BCMDBG
+ if (msglevel != 0xdeadbeef)
+ wl_msg_level = msglevel;
+ else {
+ char *var = getvar(NULL, "wl_msglevel");
+ if (var)
+ wl_msg_level = bcm_strtoul(var, NULL, 0);
+ }
+#ifndef WLC_HIGH_ONLY
+ {
+ extern uint32 phyhal_msg_level;
+
+ if (phymsglevel != 0xdeadbeef)
+ phyhal_msg_level = phymsglevel;
+ else {
+ char *var = getvar(NULL, "phy_msglevel");
+ if (var)
+ phyhal_msg_level = bcm_strtoul(var, NULL, 0);
+ }
+ }
+#endif /* WLC_HIGH_ONLY */
+#endif /* BCMDBG */
+
+#ifndef BCMSDIO
+ error = pci_module_init(&wl_pci_driver);
+ if (!error)
+ return 0;
+
+#endif /* !BCMSDIO */
+
+#ifdef WLC_HIGH_ONLY
+ /* BMAC_NOTE: define hardcode number, why NODEVICE is ok ? */
+ error =
+ dbus_register(BCM_DNGL_VID, 0, wl_dbus_probe_cb,
+ wl_dbus_disconnect_cb, NULL, NULL, NULL);
+ if (error == DBUS_ERR_NODEVICE) {
+ error = DBUS_OK;
+ }
+#endif /* WLC_HIGH_ONLY */
+
+ return error;
+}
+
+/**
+ * This function unloads the WL driver from the system.
+ *
+ * This function unconditionally unloads the WL driver module from the
+ * system.
+ *
+ */
+static void __exit wl_module_exit(void)
+{
+#ifndef BCMSDIO
+ pci_unregister_driver(&wl_pci_driver);
+#endif /* !BCMSDIO */
+
+#ifdef WLC_HIGH_ONLY
+ dbus_deregister();
+#endif /* WLC_HIGH_ONLY */
+}
+
+module_init(wl_module_init);
+module_exit(wl_module_exit);
+
+/**
+ * This function frees the WL per-device resources.
+ *
+ * This function frees resources owned by the WL device pointed to
+ * by the wl parameter.
+ *
+ */
+void wl_free(wl_info_t *wl)
+{
+ wl_timer_t *t, *next;
+ osl_t *osh;
+
+ ASSERT(wl);
+#ifndef WLC_HIGH_ONLY
+ /* free ucode data */
+ if (wl->fw.fw_cnt)
+ wl_ucode_data_free();
+ if (wl->irq)
+ free_irq(wl->irq, wl);
+#endif
+
+ /* kill dpc */
+ tasklet_kill(&wl->tasklet);
+
+ if (wl->pub) {
+ wlc_module_unregister(wl->pub, "linux", wl);
+ }
+
+ /* free common resources */
+ if (wl->wlc) {
+ wlc_detach(wl->wlc);
+ wl->wlc = NULL;
+ wl->pub = NULL;
+ }
+
+ /* virtual interface deletion is deferred so we cannot spinwait */
+
+ /* wait for all pending callbacks to complete */
+ while (atomic_read(&wl->callbacks) > 0)
+ schedule();
+
+ /* free timers */
+ for (t = wl->timers; t; t = next) {
+ next = t->next;
+#ifdef BCMDBG
+ if (t->name)
+ MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+ MFREE(wl->osh, t, sizeof(wl_timer_t));
+ }
+
+ if (wl->ioctlbuf_sz) {
+ remove_proc_entry(PROC_ENTRY_NAME, NULL);
+ vfree(wl->ioctlbuf);
+ wl->ioctlbuf_sz = 0;
+ }
+
+ osh = wl->osh;
+
+ /*
+ * unregister_netdev() calls get_stats() which may read chip registers
+ * so we cannot unmap the chip registers until after calling unregister_netdev() .
+ */
+ if (wl->regsva && BUSTYPE(wl->bcm_bustype) != SDIO_BUS &&
+ BUSTYPE(wl->bcm_bustype) != JTAG_BUS) {
+ iounmap((void *)wl->regsva);
+ }
+ wl->regsva = NULL;
+
+#ifdef WLC_HIGH_ONLY
+ wl_rpcq_free(wl);
+
+ wl_txq_free(wl);
+
+ if (wl->rpc) {
+ bcm_rpc_detach(wl->rpc);
+ wl->rpc = NULL;
+ }
+
+ if (wl->rpc_th) {
+ bcm_rpc_tp_detach(wl->rpc_th);
+ wl->rpc_th = NULL;
+ }
+#endif /* WLC_HIGH_ONLY */
+
+ if (osl_malloced(osh)) {
+ printf("**** Memory leak of bytes %d\n", osl_malloced(osh));
+ ASSERT(0 && "Memory Leak");
+ }
+
+ osl_detach(osh);
+}
+
+#ifdef WLC_LOW
+/* transmit a packet */
+static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
+{
+ if (!wl)
+ return -ENETDOWN;
+
+ return wl_start_int(wl, WL_TO_HW(wl), skb);
+}
+#endif /* WLC_LOW */
+
+static int BCMFASTPATH
+wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+#ifdef WLC_HIGH_ONLY
+ WL_LOCK(wl);
+#endif
+ wlc_sendpkt_mac80211(wl->wlc, skb, hw);
+#ifdef WLC_HIGH_ONLY
+ WL_UNLOCK(wl);
+#endif
+ return NETDEV_TX_OK;
+}
+
+void wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio)
+{
+ WL_ERROR(("Shouldn't be here %s\n", __func__));
+}
+
+#if defined(WLC_HIGH_ONLY)
+/* Schedule a completion handler to run at safe time */
+static int
+wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *task),
+ void *context)
+{
+ wl_task_t *task;
+
+ WL_TRACE(("wl%d: wl_schedule_task\n", wl->pub->unit));
+
+ task = osl_malloc(wl->osh, sizeof(wl_task_t));
+ if (!task) {
+ WL_ERROR(("wl%d: wl_schedule_task: out of memory, malloced %d bytes\n", wl->pub->unit, osl_malloced(wl->osh)));
+ return -ENOMEM;
+ }
+
+ MY_INIT_WORK(&task->work, (work_func_t) fn);
+ task->context = context;
+
+ if (!schedule_work(&task->work)) {
+ WL_ERROR(("wl%d: schedule_work() failed\n", wl->pub->unit));
+ MFREE(wl->osh, task, sizeof(wl_task_t));
+ return -ENOMEM;
+ }
+
+ atomic_inc(&wl->callbacks);
+
+ return 0;
+}
+#endif /* defined(WLC_HIGH_ONLY) */
+
+void wl_init(wl_info_t *wl)
+{
+ WL_TRACE(("wl%d: wl_init\n", wl->pub->unit));
+
+ wl_reset(wl);
+
+ wlc_init(wl->wlc);
+}
+
+uint wl_reset(wl_info_t *wl)
+{
+ WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit));
+
+ wlc_reset(wl->wlc);
+
+ /* dpc will not be rescheduled */
+ wl->resched = 0;
+
+ return 0;
+}
+
+/*
+ * These are interrupt on/off entry points. Disable interrupts
+ * during interrupt state transition.
+ */
+void BCMFASTPATH wl_intrson(wl_info_t *wl)
+{
+#if defined(WLC_LOW)
+ unsigned long flags;
+
+ INT_LOCK(wl, flags);
+ wlc_intrson(wl->wlc);
+ INT_UNLOCK(wl, flags);
+#endif /* WLC_LOW */
+}
+
+bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth)
+{
+ return TRUE;
+}
+
+uint32 BCMFASTPATH wl_intrsoff(wl_info_t *wl)
+{
+#if defined(WLC_LOW)
+ unsigned long flags;
+ uint32 status;
+
+ INT_LOCK(wl, flags);
+ status = wlc_intrsoff(wl->wlc);
+ INT_UNLOCK(wl, flags);
+ return status;
+#else
+ return 0;
+#endif /* WLC_LOW */
+}
+
+void wl_intrsrestore(wl_info_t *wl, uint32 macintmask)
+{
+#if defined(WLC_LOW)
+ unsigned long flags;
+
+ INT_LOCK(wl, flags);
+ wlc_intrsrestore(wl->wlc, macintmask);
+ INT_UNLOCK(wl, flags);
+#endif /* WLC_LOW */
+}
+
+int wl_up(wl_info_t *wl)
+{
+ int error = 0;
+
+ if (wl->pub->up)
+ return 0;
+
+ error = wlc_up(wl->wlc);
+
+ return error;
+}
+
+void wl_down(wl_info_t *wl)
+{
+ uint callbacks, ret_val = 0;
+
+ /* call common down function */
+ ret_val = wlc_down(wl->wlc);
+ callbacks = atomic_read(&wl->callbacks) - ret_val;
+
+ /* wait for down callbacks to complete */
+ WL_UNLOCK(wl);
+
+#ifndef WLC_HIGH_ONLY
+ /* For HIGH_only driver, it's important to actually schedule other work,
+ * not just spin wait since everything runs at schedule level
+ */
+ SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
+#endif /* WLC_HIGH_ONLY */
+
+ WL_LOCK(wl);
+}
+
+irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
+{
+#if defined(WLC_LOW)
+ wl_info_t *wl;
+ bool ours, wantdpc;
+ unsigned long flags;
+
+ wl = (wl_info_t *) dev_id;
+
+ WL_ISRLOCK(wl, flags);
+
+ /* call common first level interrupt handler */
+ ours = wlc_isr(wl->wlc, &wantdpc);
+ if (ours) {
+ /* if more to do... */
+ if (wantdpc) {
+
+ /* ...and call the second level interrupt handler */
+ /* schedule dpc */
+ ASSERT(wl->resched == FALSE);
+ tasklet_schedule(&wl->tasklet);
+ }
+ }
+
+ WL_ISRUNLOCK(wl, flags);
+
+ return IRQ_RETVAL(ours);
+#else
+ return IRQ_RETVAL(0);
+#endif /* WLC_LOW */
+}
+
+static void BCMFASTPATH wl_dpc(ulong data)
+{
+#ifdef WLC_LOW
+ wl_info_t *wl;
+
+ wl = (wl_info_t *) data;
+
+ WL_LOCK(wl);
+
+ /* call the common second level interrupt handler */
+ if (wl->pub->up) {
+ if (wl->resched) {
+ unsigned long flags;
+
+ INT_LOCK(wl, flags);
+ wlc_intrsupd(wl->wlc);
+ INT_UNLOCK(wl, flags);
+ }
+
+ wl->resched = wlc_dpc(wl->wlc, TRUE);
+ }
+
+ /* wlc_dpc() may bring the driver down */
+ if (!wl->pub->up)
+ goto done;
+
+ /* re-schedule dpc */
+ if (wl->resched)
+ tasklet_schedule(&wl->tasklet);
+ else {
+ /* re-enable interrupts */
+ wl_intrson(wl);
+ }
+
+ done:
+ WL_UNLOCK(wl);
+#endif /* WLC_LOW */
+}
+
+static void wl_link_up(wl_info_t *wl, char *ifname)
+{
+ WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname));
+}
+
+static void wl_link_down(wl_info_t *wl, char *ifname)
+{
+ WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname));
+}
+
+void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e)
+{
+
+ switch (e->event.event_type) {
+ case WLC_E_LINK:
+ case WLC_E_NDIS_LINK:
+ if (e->event.flags & WLC_EVENT_MSG_LINK)
+ wl_link_up(wl, ifname);
+ else
+ wl_link_down(wl, ifname);
+ break;
+ case WLC_E_RADIO:
+ break;
+ }
+}
+
+static void wl_timer(ulong data)
+{
+#ifndef WLC_HIGH_ONLY
+ _wl_timer((wl_timer_t *) data);
+#else
+ wl_timer_t *t = (wl_timer_t *) data;
+ wl_schedule_task(t->wl, wl_timer_task, t);
+#endif /* WLC_HIGH_ONLY */
+}
+
+static void _wl_timer(wl_timer_t *t)
+{
+ WL_LOCK(t->wl);
+
+ if (t->set) {
+ if (t->periodic) {
+ t->timer.expires = jiffies + t->ms * HZ / 1000;
+ atomic_inc(&t->wl->callbacks);
+ add_timer(&t->timer);
+ t->set = TRUE;
+ } else
+ t->set = FALSE;
+
+ t->fn(t->arg);
+ }
+
+ atomic_dec(&t->wl->callbacks);
+
+ WL_UNLOCK(t->wl);
+}
+
+wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg,
+ const char *name)
+{
+ wl_timer_t *t;
+
+ t = osl_malloc(wl->osh, sizeof(wl_timer_t));
+ if (!t) {
+ WL_ERROR(("wl%d: wl_init_timer: out of memory, malloced %d bytes\n", wl->pub->unit, osl_malloced(wl->osh)));
+ return 0;
+ }
+
+ bzero(t, sizeof(wl_timer_t));
+
+ init_timer(&t->timer);
+ t->timer.data = (ulong) t;
+ t->timer.function = wl_timer;
+ t->wl = wl;
+ t->fn = fn;
+ t->arg = arg;
+ t->next = wl->timers;
+ wl->timers = t;
+
+#ifdef BCMDBG
+ t->name = osl_malloc(wl->osh, strlen(name) + 1);
+ if (t->name)
+ strcpy(t->name, name);
+#endif
+
+ return t;
+}
+
+/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
+ * as well as it's easier to make it periodic
+ */
+void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic)
+{
+#ifdef BCMDBG
+ if (t->set) {
+ WL_ERROR(("%s: Already set. Name: %s, per %d\n",
+ __func__, t->name, periodic));
+ }
+#endif
+ ASSERT(!t->set);
+
+ t->ms = ms;
+ t->periodic = (bool) periodic;
+ t->set = TRUE;
+ t->timer.expires = jiffies + ms * HZ / 1000;
+
+ atomic_inc(&wl->callbacks);
+ add_timer(&t->timer);
+}
+
+/* return TRUE if timer successfully deleted, FALSE if still pending */
+bool wl_del_timer(wl_info_t *wl, wl_timer_t *t)
+{
+ if (t->set) {
+ t->set = FALSE;
+ if (!del_timer(&t->timer)) {
+ return FALSE;
+ }
+ atomic_dec(&wl->callbacks);
+ }
+
+ return TRUE;
+}
+
+void wl_free_timer(wl_info_t *wl, wl_timer_t *t)
+{
+ wl_timer_t *tmp;
+
+ /* delete the timer in case it is active */
+ wl_del_timer(wl, t);
+
+ if (wl->timers == t) {
+ wl->timers = wl->timers->next;
+#ifdef BCMDBG
+ if (t->name)
+ MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+ MFREE(wl->osh, t, sizeof(wl_timer_t));
+ return;
+
+ }
+
+ tmp = wl->timers;
+ while (tmp) {
+ if (tmp->next == t) {
+ tmp->next = t->next;
+#ifdef BCMDBG
+ if (t->name)
+ MFREE(wl->osh, t->name, strlen(t->name) + 1);
+#endif
+ MFREE(wl->osh, t, sizeof(wl_timer_t));
+ return;
+ }
+ tmp = tmp->next;
+ }
+
+}
+
+static int wl_linux_watchdog(void *ctx)
+{
+ wl_info_t *wl = (wl_info_t *) ctx;
+ struct net_device_stats *stats = NULL;
+ uint id;
+ /* refresh stats */
+ if (wl->pub->up) {
+ ASSERT(wl->stats_id < 2);
+
+ id = 1 - wl->stats_id;
+
+ stats = &wl->stats_watchdog[id];
+ stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe);
+ stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe);
+ stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte);
+ stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte);
+ stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror);
+ stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror);
+ stats->collisions = 0;
+
+ stats->rx_length_errors = 0;
+ stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
+ stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc);
+ stats->rx_frame_errors = 0;
+ stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
+ stats->rx_missed_errors = 0;
+
+ stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo);
+
+ wl->stats_id = id;
+
+ }
+
+ return 0;
+}
+
+struct wl_fw_hdr {
+ uint32 offset;
+ uint32 len;
+ uint32 idx;
+};
+
+#ifdef WLC_HIGH_ONLY
+static void wl_rpc_down(void *wlh)
+{
+ wl_info_t *wl = (wl_info_t *) (wlh);
+
+ wlc_device_removed(wl->wlc);
+
+ wl_rpcq_free(wl);
+}
+
+static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
+{
+
+ ulong flags;
+
+ skb->prev = NULL;
+
+ /* Lock the queue as tasklet could be running at this time */
+ TXQ_LOCK(wl, flags);
+ if (wl->txq_head == NULL)
+ wl->txq_head = skb;
+ else {
+ wl->txq_tail->prev = skb;
+ }
+ wl->txq_tail = skb;
+
+ if (wl->txq_dispatched == FALSE) {
+ wl->txq_dispatched = TRUE;
+
+ if (schedule_work(&wl->txq_task.work)) {
+ atomic_inc(&wl->callbacks);
+ } else {
+ WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
+ wl->pub->unit));
+ }
+ }
+
+ TXQ_UNLOCK(wl, flags);
+
+ return 0;
+
+}
+
+static void wl_start_txqwork(struct wl_task *task)
+{
+ wl_info_t *wl = (wl_info_t *) task->context;
+ struct sk_buff *skb;
+ ulong flags;
+ uint count = 0;
+
+ WL_TRACE(("wl%d: wl_start_txqwork\n", wl->pub->unit));
+
+ /* First remove an entry then go for execution */
+ TXQ_LOCK(wl, flags);
+ while (wl->txq_head) {
+ skb = wl->txq_head;
+ wl->txq_head = skb->prev;
+ skb->prev = NULL;
+ if (wl->txq_head == NULL)
+ wl->txq_tail = NULL;
+ TXQ_UNLOCK(wl, flags);
+
+ /* it has WL_LOCK/WL_UNLOCK inside */
+ wl_start_int(wl, WL_TO_HW(wl), skb);
+
+ /* bounded our execution, reshedule ourself next */
+ if (++count >= 10)
+ break;
+
+ TXQ_LOCK(wl, flags);
+ }
+
+ if (count >= 10) {
+ if (!schedule_work(&wl->txq_task.work)) {
+ WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
+ wl->pub->unit));
+ atomic_dec(&wl->callbacks);
+ }
+ } else {
+ wl->txq_dispatched = FALSE;
+ TXQ_UNLOCK(wl, flags);
+ atomic_dec(&wl->callbacks);
+ }
+
+ return;
+}
+
+static void wl_txq_free(wl_info_t *wl)
+{
+ struct sk_buff *skb;
+
+ if (wl->txq_head == NULL) {
+ ASSERT(wl->txq_tail == NULL);
+ return;
+ }
+
+ while (wl->txq_head) {
+ skb = wl->txq_head;
+ wl->txq_head = skb->prev;
+ PKTFREE(wl->osh, skb, TRUE);
+ }
+
+ wl->txq_tail = NULL;
+}
+
+static void wl_rpcq_free(wl_info_t *wl)
+{
+ rpc_buf_t *buf;
+
+ if (wl->rpcq_head == NULL) {
+ ASSERT(wl->rpcq_tail == NULL);
+ return;
+ }
+
+ while (wl->rpcq_head) {
+ buf = wl->rpcq_head;
+ wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
+ bcm_rpc_buf_free(wl->rpc_dispatch_ctx.rpc, buf);
+ }
+
+ wl->rpcq_tail = NULL;
+}
+
+static void wl_rpcq_dispatch(struct wl_task *task)
+{
+ wl_info_t *wl = (wl_info_t *) task->context;
+ rpc_buf_t *buf;
+ ulong flags;
+
+ /* First remove an entry then go for execution */
+ RPCQ_LOCK(wl, flags);
+ while (wl->rpcq_head) {
+ buf = wl->rpcq_head;
+ wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
+
+ if (wl->rpcq_head == NULL)
+ wl->rpcq_tail = NULL;
+ RPCQ_UNLOCK(wl, flags);
+
+ WL_LOCK(wl);
+ wlc_rpc_high_dispatch(&wl->rpc_dispatch_ctx, buf);
+ WL_UNLOCK(wl);
+
+ RPCQ_LOCK(wl, flags);
+ }
+
+ wl->rpcq_dispatched = FALSE;
+
+ RPCQ_UNLOCK(wl, flags);
+
+ MFREE(wl->osh, task, sizeof(wl_task_t));
+ atomic_dec(&wl->callbacks);
+}
+
+static void wl_rpcq_add(wl_info_t *wl, rpc_buf_t *buf)
+{
+ ulong flags;
+
+ bcm_rpc_buf_next_set(wl->rpc_th, buf, NULL);
+
+ /* Lock the queue as tasklet could be running at this time */
+ RPCQ_LOCK(wl, flags);
+ if (wl->rpcq_head == NULL)
+ wl->rpcq_head = buf;
+ else
+ bcm_rpc_buf_next_set(wl->rpc_th, wl->rpcq_tail, buf);
+
+ wl->rpcq_tail = buf;
+
+ if (wl->rpcq_dispatched == FALSE) {
+ wl->rpcq_dispatched = TRUE;
+ wl_schedule_task(wl, wl_rpcq_dispatch, wl);
+ }
+
+ RPCQ_UNLOCK(wl, flags);
+}
+
+#if defined(BCMDBG)
+static const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE;
+#endif /* BCMDBG */
+
+/* dongle-side rpc dispatch routine */
+static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf)
+{
+ bcm_xdr_buf_t b;
+ wl_info_t *wl = (wl_info_t *) ctx;
+ wlc_rpc_id_t rpc_id;
+ int err;
+
+ bcm_xdr_buf_init(&b, bcm_rpc_buf_data(wl->rpc_th, buf),
+ bcm_rpc_buf_len_get(wl->rpc_th, buf));
+
+ err = bcm_xdr_unpack_uint32(&b, &rpc_id);
+ ASSERT(!err);
+ WL_TRACE(("%s: Dispatch id %s\n", __func__,
+ WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id)));
+
+ /* Handle few emergency ones */
+ switch (rpc_id) {
+ default:
+ wl_rpcq_add(wl, buf);
+ break;
+ }
+}
+
+static void wl_timer_task(wl_task_t *task)
+{
+ wl_timer_t *t = (wl_timer_t *) task->context;
+
+ _wl_timer(t);
+ MFREE(t->wl->osh, task, sizeof(wl_task_t));
+
+ /* This dec is for the task_schedule. The timer related
+ * callback is decremented in _wl_timer
+ */
+ atomic_dec(&t->wl->callbacks);
+}
+#endif /* WLC_HIGH_ONLY */
+
+#ifndef WLC_HIGH_ONLY
+char *wl_firmwares[WL_MAX_FW] = {
+ "brcm/bcm43xx",
+ NULL
+};
+
+#ifdef WLC_LOW
+int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, uint32 idx)
+{
+ int i, entry;
+ const uint8 *pdata;
+ struct wl_fw_hdr *hdr;
+ for (i = 0; i < wl->fw.fw_cnt; i++) {
+ hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+ for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+ entry++, hdr++) {
+ if (hdr->idx == idx) {
+ pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+ *pbuf = kmalloc(hdr->len, GFP_ATOMIC);
+ if (*pbuf == NULL) {
+ printf("fail to alloc %d bytes\n",
+ hdr->len);
+ }
+ bcopy(pdata, *pbuf, hdr->len);
+ return 0;
+ }
+ }
+ }
+ printf("ERROR: ucode buf tag:%d can not be found!\n", idx);
+ *pbuf = NULL;
+ return -1;
+}
+
+int wl_ucode_init_uint(wl_info_t *wl, uint32 *data, uint32 idx)
+{
+ int i, entry;
+ const uint8 *pdata;
+ struct wl_fw_hdr *hdr;
+ for (i = 0; i < wl->fw.fw_cnt; i++) {
+ hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+ for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+ entry++, hdr++) {
+ if (hdr->idx == idx) {
+ pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+ ASSERT(hdr->len == 4);
+ *data = *((uint32 *) pdata);
+ return 0;
+ }
+ }
+ }
+ printf("ERROR: ucode tag:%d can not be found!\n", idx);
+ return -1;
+}
+#endif /* WLC_LOW */
+
+static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev)
+{
+ int status;
+ struct device *device = &pdev->dev;
+ char fw_name[100];
+ int i;
+
+ bzero((void *)&wl->fw, sizeof(struct wl_firmware));
+ for (i = 0; i < WL_MAX_FW; i++) {
+ if (wl_firmwares[i] == NULL)
+ break;
+ sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
+ UCODE_LOADER_API_VER);
+ WL_NONE(("request fw %s\n", fw_name));
+ status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
+ if (status) {
+ printf("fail to request firmware %s\n", fw_name);
+ wl_release_fw(wl);
+ return status;
+ }
+ WL_NONE(("request fw %s\n", fw_name));
+ sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
+ UCODE_LOADER_API_VER);
+ status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
+ if (status) {
+ printf("fail to request firmware %s\n", fw_name);
+ wl_release_fw(wl);
+ return status;
+ }
+ wl->fw.hdr_num_entries[i] =
+ wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
+ WL_NONE(("request fw %s find: %d entries\n", fw_name,
+ wl->fw.hdr_num_entries[i]));
+ }
+ wl->fw.fw_cnt = i;
+ wl_ucode_data_init(wl);
+ return 0;
+}
+
+#ifdef WLC_LOW
+void wl_ucode_free_buf(void *p)
+{
+ kfree(p);
+}
+#endif /* WLC_LOW */
+
+static void wl_release_fw(wl_info_t *wl)
+{
+ int i;
+ for (i = 0; i < WL_MAX_FW; i++) {
+ release_firmware(wl->fw.fw_bin[i]);
+ release_firmware(wl->fw.fw_hdr[i]);
+ }
+}
+#endif /* WLC_HIGH_ONLY */
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h
new file mode 100644
index 000000000000..a6c13a354393
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wl_mac80211_h_
+#define _wl_mac80211_h_
+
+#include <wlc_types.h>
+
+/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and
+ * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
+ * submitted to workqueue instead of being on kernel timer
+ */
+typedef struct wl_timer {
+ struct timer_list timer;
+ struct wl_info *wl;
+ void (*fn) (void *);
+ void *arg; /* argument to fn */
+ uint ms;
+ bool periodic;
+ bool set;
+ struct wl_timer *next;
+#ifdef BCMDBG
+ char *name; /* Description of the timer */
+#endif
+} wl_timer_t;
+
+/* contortion to call functions at safe time */
+/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things
+ * will continue to work as long as the work structure is the first component of the task structure.
+ */
+typedef struct wl_task {
+ struct work_struct work;
+ void *context;
+} wl_task_t;
+
+struct wl_if {
+ uint subunit; /* WDS/BSS unit */
+ struct pci_dev *pci_dev;
+};
+
+#define WL_MAX_FW 4
+struct wl_firmware {
+ uint32 fw_cnt;
+ const struct firmware *fw_bin[WL_MAX_FW];
+ const struct firmware *fw_hdr[WL_MAX_FW];
+ uint32 hdr_num_entries[WL_MAX_FW];
+};
+
+struct wl_info {
+ wlc_pub_t *pub; /* pointer to public wlc state */
+ void *wlc; /* pointer to private common os-independent data */
+ osl_t *osh; /* pointer to os handler */
+ uint32 magic;
+
+ int irq;
+
+#ifdef WLC_HIGH_ONLY
+ struct semaphore sem; /* use semaphore to allow sleep */
+#else
+ spinlock_t lock; /* per-device perimeter lock */
+ spinlock_t isr_lock; /* per-device ISR synchronization lock */
+#endif
+ uint bcm_bustype; /* bus type */
+ bool piomode; /* set from insmod argument */
+ void *regsva; /* opaque chip registers virtual address */
+ atomic_t callbacks; /* # outstanding callback functions */
+ struct wl_timer *timers; /* timer cleanup queue */
+ struct tasklet_struct tasklet; /* dpc tasklet */
+#ifdef BCMSDIO
+ bcmsdh_info_t *sdh; /* pointer to sdio bus handler */
+ ulong flags; /* current irq flags */
+#endif /* BCMSDIO */
+ bool resched; /* dpc needs to be and is rescheduled */
+#ifdef LINUXSTA_PS
+ uint32 pci_psstate[16]; /* pci ps-state save/restore */
+#endif
+ /* RPC, handle, lock, txq, workitem */
+#ifdef WLC_HIGH_ONLY
+ rpc_info_t *rpc; /* RPC handle */
+ rpc_tp_info_t *rpc_th; /* RPC transport handle */
+ wlc_rpc_ctx_t rpc_dispatch_ctx;
+
+ bool rpcq_dispatched; /* Avoid scheduling multiple tasks */
+ spinlock_t rpcq_lock; /* Lock for the queue */
+ rpc_buf_t *rpcq_head; /* RPC Q */
+ rpc_buf_t *rpcq_tail; /* Points to the last buf */
+
+ bool txq_dispatched; /* Avoid scheduling multiple tasks */
+ spinlock_t txq_lock; /* Lock for the queue */
+ struct sk_buff *txq_head; /* TX Q */
+ struct sk_buff *txq_tail; /* Points to the last buf */
+
+ wl_task_t txq_task; /* work queue for wl_start() */
+#endif /* WLC_HIGH_ONLY */
+ uint stats_id; /* the current set of stats */
+ /* ping-pong stats counters updated by Linux watchdog */
+ struct net_device_stats stats_watchdog[2];
+
+ struct proc_dir_entry *proc_entry;
+ char *ioctlbuf;
+ unsigned int ioctlbuf_sz;
+ wl_ioctl_t ioc;
+ int proc_state;
+ bool ioctl_in_progress;
+ struct wl_firmware fw;
+};
+#define WL_PROC_IDLE (0)
+#define WL_PROC_HAVE_IOC (1)
+#define WL_PROC_HAVE_BUF (2)
+
+#ifndef WLC_HIGH_ONLY
+#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock)
+#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock)
+
+/* locking from inside wl_isr */
+#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0)
+#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0)
+
+/* locking under WL_LOCK() to synchronize with wl_isr */
+#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags)
+#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags)
+#else /* BCMSDIO */
+
+#define WL_LOCK(wl) down(&(wl)->sem)
+#define WL_UNLOCK(wl) up(&(wl)->sem)
+
+#define WL_ISRLOCK(wl)
+#define WL_ISRUNLOCK(wl)
+#endif /* WLC_HIGH_ONLY */
+
+/* handle forward declaration */
+typedef struct wl_info wl_info_t;
+
+#ifndef PCI_D0
+#define PCI_D0 0
+#endif
+
+#ifndef PCI_D3hot
+#define PCI_D3hot 3
+#endif
+
+/* exported functions */
+
+extern irqreturn_t wl_isr(int irq, void *dev_id);
+
+extern int __devinit wl_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+extern void wl_free(wl_info_t *wl);
+extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+extern int wl_ucode_data_init(wl_info_t *wl);
+extern void wl_ucode_data_free(void);
+#ifdef WLC_LOW
+extern void wl_ucode_free_buf(void *);
+extern int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, uint32 idx);
+extern int wl_ucode_init_uint(wl_info_t *wl, uint32 *data, uint32 idx);
+#endif /* WLC_LOW */
+
+#endif /* _wl_mac80211_h_ */
diff --git a/drivers/staging/brcm80211/sys/wl_ucode.h b/drivers/staging/brcm80211/sys/wl_ucode.h
new file mode 100644
index 000000000000..2763b7cd365b
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_ucode.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+typedef struct d11init {
+ uint16 addr;
+ uint16 size;
+ uint32 value;
+} d11init_t;
+
+extern d11init_t *d11lcn0bsinitvals24;
+extern d11init_t *d11lcn0initvals24;
+extern d11init_t *d11lcn1bsinitvals24;
+extern d11init_t *d11lcn1initvals24;
+extern d11init_t *d11lcn2bsinitvals24;
+extern d11init_t *d11lcn2initvals24;
+extern d11init_t *d11n0absinitvals16;
+extern d11init_t *d11n0bsinitvals16;
+extern d11init_t *d11n0initvals16;
+extern uint32 *bcm43xx_16_mimo;
+extern uint32 bcm43xx_16_mimosz;
+extern uint32 *bcm43xx_24_lcn;
+extern uint32 bcm43xx_24_lcnsz;
+extern uint32 *bcm43xx_bommajor;
+extern uint32 *bcm43xx_bomminor;
diff --git a/drivers/staging/brcm80211/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/sys/wl_ucode_loader.c
new file mode 100644
index 000000000000..f99c042c8f43
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wl_ucode_loader.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+typedef struct wl_info wl_info_t;
+#include <typedefs.h>
+#include <d11ucode_ext.h>
+#include <wl_ucode.h>
+
+extern int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, unsigned int idx);
+extern int wl_ucode_init_uint(wl_info_t *wl, unsigned *data, unsigned int idx);
+extern int wl_ucode_data_init(wl_info_t *wl);
+extern void wl_ucode_data_free(void);
+extern void wl_ucode_free_buf(void *);
+
+d11init_t *d11lcn0bsinitvals24;
+d11init_t *d11lcn0initvals24;
+d11init_t *d11lcn1bsinitvals24;
+d11init_t *d11lcn1initvals24;
+d11init_t *d11lcn2bsinitvals24;
+d11init_t *d11lcn2initvals24;
+d11init_t *d11n0absinitvals16;
+d11init_t *d11n0bsinitvals16;
+d11init_t *d11n0initvals16;
+uint32 *bcm43xx_16_mimo;
+uint32 bcm43xx_16_mimosz;
+uint32 *bcm43xx_24_lcn;
+uint32 bcm43xx_24_lcnsz;
+uint32 *bcm43xx_bommajor;
+uint32 *bcm43xx_bomminor;
+
+int wl_ucode_data_init(wl_info_t *wl)
+{
+ wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
+ D11LCN0BSINITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
+ D11LCN1BSINITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
+ D11LCN2BSINITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24);
+ wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16);
+ wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16);
+ wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16);
+ wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
+ D11UCODE_OVERSIGHT16_MIMO);
+ wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ);
+ wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
+ D11UCODE_OVERSIGHT24_LCN);
+ wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ);
+ wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
+ D11UCODE_OVERSIGHT_BOMMAJOR);
+ wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
+ D11UCODE_OVERSIGHT_BOMMINOR);
+
+ return 0;
+}
+
+void wl_ucode_data_free(void)
+{
+ wl_ucode_free_buf((void *)d11lcn0bsinitvals24);
+ wl_ucode_free_buf((void *)d11lcn0initvals24);
+ wl_ucode_free_buf((void *)d11lcn1bsinitvals24);
+ wl_ucode_free_buf((void *)d11lcn1initvals24);
+ wl_ucode_free_buf((void *)d11lcn2bsinitvals24);
+ wl_ucode_free_buf((void *)d11lcn2initvals24);
+ wl_ucode_free_buf((void *)d11n0absinitvals16);
+ wl_ucode_free_buf((void *)d11n0bsinitvals16);
+ wl_ucode_free_buf((void *)d11n0initvals16);
+ wl_ucode_free_buf((void *)bcm43xx_16_mimo);
+ wl_ucode_free_buf((void *)bcm43xx_24_lcn);
+ wl_ucode_free_buf((void *)bcm43xx_bommajor);
+ wl_ucode_free_buf((void *)bcm43xx_bomminor);
+
+ return;
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c
new file mode 100644
index 000000000000..c83e0952edbc
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_alloc.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <proto/802.11.h>
+#include <proto/802.11e.h>
+#include <proto/wpa.h>
+#include <wlioctl.h>
+#include <bcmwpa.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wlc_bsscfg.h>
+#include <wlc_mac80211.h>
+#include <wlc_alloc.h>
+
+static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err,
+ uint devid);
+static void wlc_pub_mfree(osl_t *osh, wlc_pub_t *pub);
+static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid);
+
+void *wlc_calloc(osl_t *osh, uint unit, uint size)
+{
+ void *item;
+
+ item = MALLOC(osh, size);
+ if (item == NULL)
+ WL_ERROR(("wl%d: %s: out of memory, malloced %d bytes\n",
+ unit, __func__, MALLOCED(osh)));
+ else
+ bzero((char *)item, size);
+ return item;
+}
+
+void BCMATTACHFN(wlc_tunables_init) (wlc_tunables_t *tunables, uint devid)
+{
+ tunables->ntxd = NTXD;
+ tunables->nrxd = NRXD;
+ tunables->rxbufsz = RXBUFSZ;
+ tunables->nrxbufpost = NRXBUFPOST;
+ tunables->maxscb = MAXSCB;
+ tunables->ampdunummpdu = AMPDU_NUM_MPDU;
+ tunables->maxpktcb = MAXPKTCB;
+ tunables->maxucodebss = WLC_MAX_UCODE_BSS;
+ tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4;
+ tunables->maxbss = MAXBSS;
+ tunables->datahiwat = WLC_DATAHIWAT;
+ tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT;
+ tunables->rxbnd = RXBND;
+ tunables->txsbnd = TXSBND;
+#if defined(WLC_HIGH_ONLY) && defined(NTXD_USB_4319)
+ if (devid == BCM4319_CHIP_ID) {
+ tunables->ntxd = NTXD_USB_4319;
+ }
+#endif /* WLC_HIGH_ONLY */
+}
+
+static wlc_pub_t *BCMATTACHFN(wlc_pub_malloc) (osl_t *osh, uint unit,
+ uint *err, uint devid) {
+ wlc_pub_t *pub;
+
+ pub = (wlc_pub_t *) wlc_calloc(osh, unit, sizeof(wlc_pub_t));
+ if (pub == NULL) {
+ *err = 1001;
+ goto fail;
+ }
+
+ pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit,
+ sizeof(wlc_tunables_t));
+ if (pub->tunables == NULL) {
+ *err = 1028;
+ goto fail;
+ }
+
+ /* need to init the tunables now */
+ wlc_tunables_init(pub->tunables, devid);
+
+ pub->multicast = (struct ether_addr *)wlc_calloc(osh, unit,
+ (sizeof(struct ether_addr) * MAXMULTILIST));
+ if (pub->multicast == NULL) {
+ *err = 1003;
+ goto fail;
+ }
+
+ return pub;
+
+ fail:
+ wlc_pub_mfree(osh, pub);
+ return NULL;
+}
+
+static void BCMATTACHFN(wlc_pub_mfree) (osl_t *osh, wlc_pub_t *pub)
+{
+ if (pub == NULL)
+ return;
+
+ if (pub->multicast)
+ MFREE(osh, pub->multicast,
+ (sizeof(struct ether_addr) * MAXMULTILIST));
+
+ if (pub->tunables) {
+ MFREE(osh, pub->tunables, sizeof(wlc_tunables_t));
+ pub->tunables = NULL;
+ }
+
+ MFREE(osh, pub, sizeof(wlc_pub_t));
+}
+
+wlc_bsscfg_t *wlc_bsscfg_malloc(osl_t *osh, uint unit)
+{
+ wlc_bsscfg_t *cfg;
+
+ cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t));
+ if (cfg == NULL)
+ goto fail;
+
+ cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit,
+ sizeof(wlc_bss_info_t));
+ if (cfg->current_bss == NULL)
+ goto fail;
+
+ return cfg;
+
+ fail:
+ wlc_bsscfg_mfree(osh, cfg);
+ return NULL;
+}
+
+void wlc_bsscfg_mfree(osl_t *osh, wlc_bsscfg_t *cfg)
+{
+ if (cfg == NULL)
+ return;
+
+ if (cfg->maclist) {
+ MFREE(osh, cfg->maclist,
+ (int)(OFFSETOF(struct maclist, ea) +
+ cfg->nmac * ETHER_ADDR_LEN));
+ cfg->maclist = NULL;
+ }
+
+ if (cfg->current_bss != NULL) {
+ wlc_bss_info_t *current_bss = cfg->current_bss;
+ if (current_bss->bcn_prb != NULL)
+ MFREE(osh, current_bss->bcn_prb,
+ current_bss->bcn_prb_len);
+ MFREE(osh, current_bss, sizeof(wlc_bss_info_t));
+ cfg->current_bss = NULL;
+ }
+
+ MFREE(osh, cfg, sizeof(wlc_bsscfg_t));
+}
+
+void wlc_bsscfg_ID_assign(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg)
+{
+ bsscfg->ID = wlc->next_bsscfg_ID;
+ wlc->next_bsscfg_ID++;
+}
+
+/*
+ * The common driver entry routine. Error codes should be unique
+ */
+wlc_info_t *BCMATTACHFN(wlc_attach_malloc) (osl_t *osh, uint unit, uint *err,
+ uint devid) {
+ wlc_info_t *wlc;
+
+ wlc = (wlc_info_t *) wlc_calloc(osh, unit, sizeof(wlc_info_t));
+ if (wlc == NULL) {
+ *err = 1002;
+ goto fail;
+ }
+
+ wlc->hwrxoff = WL_HWRXOFF;
+
+ /* allocate wlc_pub_t state structure */
+ wlc->pub = wlc_pub_malloc(osh, unit, err, devid);
+ if (wlc->pub == NULL) {
+ *err = 1003;
+ goto fail;
+ }
+ wlc->pub->wlc = wlc;
+
+ /* allocate wlc_hw_info_t state structure */
+
+ wlc->hw = (wlc_hw_info_t *)wlc_calloc(osh, unit,
+ sizeof(wlc_hw_info_t));
+ if (wlc->hw == NULL) {
+ *err = 1005;
+ goto fail;
+ }
+ wlc->hw->wlc = wlc;
+
+#ifdef WLC_LOW
+ wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit,
+ (sizeof(wlc_hwband_t) * MAXBANDS));
+ if (wlc->hw->bandstate[0] == NULL) {
+ *err = 1006;
+ goto fail;
+ } else {
+ int i;
+
+ for (i = 1; i < MAXBANDS; i++) {
+ wlc->hw->bandstate[i] = (wlc_hwband_t *)
+ ((uintptr) wlc->hw->bandstate[0] +
+ (sizeof(wlc_hwband_t) * i));
+ }
+ }
+#endif /* WLC_LOW */
+
+ wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit,
+ sizeof(modulecb_t) * WLC_MAXMODULES);
+ if (wlc->modulecb == NULL) {
+ *err = 1009;
+ goto fail;
+ }
+
+ wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit,
+ sizeof(wlc_bss_info_t));
+ if (wlc->default_bss == NULL) {
+ *err = 1010;
+ goto fail;
+ }
+
+ wlc->cfg = wlc_bsscfg_malloc(osh, unit);
+ if (wlc->cfg == NULL) {
+ *err = 1011;
+ goto fail;
+ }
+ wlc_bsscfg_ID_assign(wlc, wlc->cfg);
+
+ wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit,
+ (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1)));
+ if (wlc->pkt_callback == NULL) {
+ *err = 1013;
+ goto fail;
+ }
+
+ wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit,
+ (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS));
+ if (wlc->wsec_def_keys[0] == NULL) {
+ *err = 1015;
+ goto fail;
+ } else {
+ int i;
+ for (i = 1; i < WLC_DEFAULT_KEYS; i++) {
+ wlc->wsec_def_keys[i] = (wsec_key_t *)
+ ((uintptr) wlc->wsec_def_keys[0] +
+ (sizeof(wsec_key_t) * i));
+ }
+ }
+
+ wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit,
+ sizeof(wlc_protection_t));
+ if (wlc->protection == NULL) {
+ *err = 1016;
+ goto fail;
+ }
+
+ wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t));
+ if (wlc->stf == NULL) {
+ *err = 1017;
+ goto fail;
+ }
+
+ wlc->bandstate[0] = (wlcband_t *)wlc_calloc(osh, unit,
+ (sizeof(wlcband_t) * MAXBANDS));
+ if (wlc->bandstate[0] == NULL) {
+ *err = 1025;
+ goto fail;
+ } else {
+ int i;
+
+ for (i = 1; i < MAXBANDS; i++) {
+ wlc->bandstate[i] =
+ (wlcband_t *) ((uintptr) wlc->bandstate[0] +
+ (sizeof(wlcband_t) * i));
+ }
+ }
+
+ wlc->corestate = (wlccore_t *)wlc_calloc(osh, unit, sizeof(wlccore_t));
+ if (wlc->corestate == NULL) {
+ *err = 1026;
+ goto fail;
+ }
+
+ wlc->corestate->macstat_snapshot =
+ (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t));
+ if (wlc->corestate->macstat_snapshot == NULL) {
+ *err = 1027;
+ goto fail;
+ }
+
+ return wlc;
+
+ fail:
+ wlc_detach_mfree(wlc, osh);
+ return NULL;
+}
+
+void BCMATTACHFN(wlc_detach_mfree) (wlc_info_t *wlc, osl_t *osh)
+{
+ if (wlc == NULL)
+ return;
+
+ if (wlc->modulecb) {
+ MFREE(osh, wlc->modulecb, sizeof(modulecb_t) * WLC_MAXMODULES);
+ wlc->modulecb = NULL;
+ }
+
+ if (wlc->default_bss) {
+ MFREE(osh, wlc->default_bss, sizeof(wlc_bss_info_t));
+ wlc->default_bss = NULL;
+ }
+ if (wlc->cfg) {
+ wlc_bsscfg_mfree(osh, wlc->cfg);
+ wlc->cfg = NULL;
+ }
+
+ if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) {
+ MFREE(osh,
+ wlc->pkt_callback,
+ sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1));
+ wlc->pkt_callback = NULL;
+ }
+
+ if (wlc->wsec_def_keys[0])
+ MFREE(osh, wlc->wsec_def_keys[0],
+ (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS));
+
+ if (wlc->protection) {
+ MFREE(osh, wlc->protection, sizeof(wlc_protection_t));
+ wlc->protection = NULL;
+ }
+
+ if (wlc->stf) {
+ MFREE(osh, wlc->stf, sizeof(wlc_stf_t));
+ wlc->stf = NULL;
+ }
+
+ if (wlc->bandstate[0])
+ MFREE(osh, wlc->bandstate[0], (sizeof(wlcband_t) * MAXBANDS));
+
+ if (wlc->corestate) {
+ if (wlc->corestate->macstat_snapshot) {
+ MFREE(osh, wlc->corestate->macstat_snapshot,
+ sizeof(macstat_t));
+ wlc->corestate->macstat_snapshot = NULL;
+ }
+ MFREE(osh, wlc->corestate, sizeof(wlccore_t));
+ wlc->corestate = NULL;
+ }
+
+ if (wlc->pub) {
+ /* free pub struct */
+ wlc_pub_mfree(osh, wlc->pub);
+ wlc->pub = NULL;
+ }
+
+ if (wlc->hw) {
+#ifdef WLC_LOW
+ if (wlc->hw->bandstate[0]) {
+ MFREE(osh, wlc->hw->bandstate[0],
+ (sizeof(wlc_hwband_t) * MAXBANDS));
+ wlc->hw->bandstate[0] = NULL;
+ }
+#endif
+
+ /* free hw struct */
+ MFREE(osh, wlc->hw, sizeof(wlc_hw_info_t));
+ wlc->hw = NULL;
+ }
+
+ /* free the wlc */
+ MFREE(osh, wlc, sizeof(wlc_info_t));
+ wlc = NULL;
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.h b/drivers/staging/brcm80211/sys/wlc_alloc.h
new file mode 100644
index 000000000000..678a2b9784f8
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_alloc.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+extern void *wlc_calloc(osl_t *osh, uint unit, uint size);
+
+extern wlc_info_t *wlc_attach_malloc(osl_t *osh, uint unit, uint *err,
+ uint devid);
+extern void wlc_detach_mfree(wlc_info_t *wlc, osl_t *osh);
+
+struct wlc_bsscfg;
+extern struct wlc_bsscfg *wlc_bsscfg_malloc(osl_t *osh, uint unit);
+extern void wlc_bsscfg_mfree(osl_t *osh, struct wlc_bsscfg *cfg);
diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c
new file mode 100644
index 000000000000..d2eab6a89b62
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c
@@ -0,0 +1,1421 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <proto/802.11.h>
+#include <wlioctl.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <hnddma.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wlc_bsscfg.h>
+#include <wlc_mac80211.h>
+#include <wlc_phy_hal.h>
+#include <wlc_antsel.h>
+#include <wlc_scb.h>
+#include <net/mac80211.h>
+#include <wlc_ampdu.h>
+#include <wl_export.h>
+
+#ifdef WLC_HIGH_ONLY
+#include <bcm_rpc_tp.h>
+#include <wlc_rpctx.h>
+#endif
+
+#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */
+#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */
+#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
+#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */
+#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */
+#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */
+#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */
+#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */
+#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */
+#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */
+#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */
+#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */
+#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */
+
+#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */
+#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu
+ * without underflows
+ */
+#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */
+#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */
+#define FFPLD_PLD_INCR 1000 /* increments in bytes */
+#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we
+ * accumulate between resets.
+ */
+
+#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
+
+/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
+#define AMPDU_MAX_MPDU_OVERHEAD (DOT11_FCS_LEN + DOT11_ICV_AES_LEN + AMPDU_DELIMITER_LEN + 3 \
+ + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
+
+#ifdef BCMDBG
+uint32 wl_ampdu_dbg =
+ WL_AMPDU_UPDN_VAL |
+ WL_AMPDU_ERR_VAL |
+ WL_AMPDU_TX_VAL |
+ WL_AMPDU_RX_VAL |
+ WL_AMPDU_CTL_VAL |
+ WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL;
+#endif
+
+/* structure to hold tx fifo information and pre-loading state
+ * counters specific to tx underflows of ampdus
+ * some counters might be redundant with the ones in wlc or ampdu structures.
+ * This allows to maintain a specific state independantly of
+ * how often and/or when the wlc counters are updated.
+ */
+typedef struct wlc_fifo_info {
+ uint16 ampdu_pld_size; /* number of bytes to be pre-loaded */
+ uint8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */
+ uint16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */
+ uint32 accum_txfunfl; /* num of underflows since we modified pld params */
+ uint32 accum_txampdu; /* num of tx ampdu since we modified pld params */
+ uint32 prev_txampdu; /* previous reading of tx ampdu */
+ uint32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */
+} wlc_fifo_info_t;
+
+/* AMPDU module specific state */
+struct ampdu_info {
+ wlc_info_t *wlc; /* pointer to main wlc structure */
+ int scb_handle; /* scb cubby handle to retrieve data from scb */
+ uint8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */
+ uint8 ba_tx_wsize; /* Tx ba window size (in pdu) */
+ uint8 ba_rx_wsize; /* Rx ba window size (in pdu) */
+ uint8 retry_limit; /* mpdu transmit retry limit */
+ uint8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */
+ uint8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */
+ /* per-tid mpdu transmit retry limit at regular rate */
+ uint8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
+ uint8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */
+ int8 max_pdu; /* max pdus allowed in ampdu */
+ uint8 dur; /* max duration of an ampdu (in msec) */
+ uint8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */
+ uint8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */
+ uint32 ffpld_rsvd; /* number of bytes to reserve for preload */
+ uint32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */
+ void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */
+ bool mfbr; /* enable multiple fallback rate */
+ uint32 tx_max_funl; /* underflows should be kept such that
+ * (tx_max_funfl*underflows) < tx frames
+ */
+ wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */
+
+#ifdef WLC_HIGH_ONLY
+ void *p;
+ tx_status_t txs;
+ bool waiting_status; /* To help sanity checks */
+#endif
+};
+
+#define AMPDU_CLEANUPFLAG_RX (0x1)
+#define AMPDU_CLEANUPFLAG_TX (0x2)
+
+#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu))
+#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid]))
+
+static void wlc_ffpld_init(ampdu_info_t *ampdu);
+static int wlc_ffpld_check_txfunfl(wlc_info_t *wlc, int f);
+static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f);
+
+static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu,
+ scb_ampdu_t *scb_ampdu,
+ uint8 tid, bool override);
+static void ampdu_cleanup_tid_ini(ampdu_info_t *ampdu, scb_ampdu_t *scb_ampdu,
+ uint8 tid, bool force);
+static void ampdu_update_max_txlen(ampdu_info_t *ampdu, uint8 dur);
+static void scb_ampdu_update_config(ampdu_info_t *ampdu, struct scb *scb);
+static void scb_ampdu_update_config_all(ampdu_info_t *ampdu);
+
+#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0)
+
+static void wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb,
+ void *p, tx_status_t *txs,
+ uint32 frmtxstatus,
+ uint32 frmtxstatus2);
+
+static INLINE uint16 pkt_txh_seqnum(wlc_info_t *wlc, void *p)
+{
+ d11txh_t *txh;
+ struct dot11_header *h;
+ txh = (d11txh_t *) PKTDATA(p);
+ h = (struct dot11_header *)((uint8 *) (txh + 1) + D11_PHY_HDR_LEN);
+ return ltoh16(h->seq) >> SEQNUM_SHIFT;
+}
+
+ampdu_info_t *BCMATTACHFN(wlc_ampdu_attach) (wlc_info_t *wlc)
+{
+ ampdu_info_t *ampdu;
+ int i;
+
+ /* some code depends on packed structures */
+ ASSERT(sizeof(struct dot11_bar) == DOT11_BAR_LEN);
+ ASSERT(sizeof(struct dot11_ba) == DOT11_BA_LEN + DOT11_BA_BITMAP_LEN);
+ ASSERT(sizeof(struct dot11_ctl_header) == DOT11_CTL_HDR_LEN);
+ ASSERT(sizeof(struct dot11_addba_req) == DOT11_ADDBA_REQ_LEN);
+ ASSERT(sizeof(struct dot11_addba_resp) == DOT11_ADDBA_RESP_LEN);
+ ASSERT(sizeof(struct dot11_delba) == DOT11_DELBA_LEN);
+ ASSERT(DOT11_MAXNUMFRAGS == NBITS(uint16));
+ ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE));
+ ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE));
+ ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU);
+ ASSERT(wlc->pub->tunables->ampdunummpdu > 0);
+
+ ampdu = (ampdu_info_t *) MALLOC(wlc->osh, sizeof(ampdu_info_t));
+ if (!ampdu) {
+ WL_ERROR(("wl%d: wlc_ampdu_attach: out of mem, malloced %d bytes\n", wlc->pub->unit, MALLOCED(wlc->osh)));
+ return NULL;
+ }
+ bzero((char *)ampdu, sizeof(ampdu_info_t));
+ ampdu->wlc = wlc;
+
+ for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
+ ampdu->ini_enable[i] = TRUE;
+ /* Disable ampdu for VO by default */
+ ampdu->ini_enable[PRIO_8021D_VO] = FALSE;
+ ampdu->ini_enable[PRIO_8021D_NC] = FALSE;
+
+ /* Disable ampdu for BK by default since not enough fifo space */
+ ampdu->ini_enable[PRIO_8021D_NONE] = FALSE;
+ ampdu->ini_enable[PRIO_8021D_BK] = FALSE;
+
+ ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
+ ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
+ ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
+ ampdu->max_pdu = AUTO;
+ ampdu->dur = AMPDU_MAX_DUR;
+ ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
+
+ ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
+ /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */
+ if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
+ ampdu->rx_factor = AMPDU_RX_FACTOR_32K;
+ else
+ ampdu->rx_factor = AMPDU_RX_FACTOR_64K;
+#ifdef WLC_HIGH_ONLY
+ /* Restrict to smaller rcv size for BMAC dongle */
+ ampdu->rx_factor = AMPDU_RX_FACTOR_32K;
+#endif
+ ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
+ ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
+
+ for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
+ ampdu->retry_limit_tid[i] = ampdu->retry_limit;
+ ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
+ }
+
+ ampdu_update_max_txlen(ampdu, ampdu->dur);
+ ampdu->mfbr = FALSE;
+ /* try to set ampdu to the default value */
+ wlc_ampdu_set(ampdu, wlc->pub->_ampdu);
+
+ ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
+ wlc_ffpld_init(ampdu);
+
+ return ampdu;
+}
+
+void BCMATTACHFN(wlc_ampdu_detach) (ampdu_info_t *ampdu)
+{
+ int i;
+
+ if (!ampdu)
+ return;
+
+ /* free all ini's which were to be freed on callbacks which were never called */
+ for (i = 0; i < AMPDU_INI_FREE; i++) {
+ if (ampdu->ini_free[i]) {
+ MFREE(ampdu->wlc->osh, ampdu->ini_free[i],
+ sizeof(scb_ampdu_tid_ini_t));
+ }
+ }
+
+ wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
+ MFREE(ampdu->wlc->osh, ampdu, sizeof(ampdu_info_t));
+}
+
+void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb)
+{
+ scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ uint8 tid;
+
+ WL_AMPDU_UPDN(("scb_ampdu_cleanup: enter\n"));
+ ASSERT(scb_ampdu);
+
+ for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) {
+ ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, FALSE);
+ }
+}
+
+/* reset the ampdu state machine so that it can gracefully handle packets that were
+ * freed from the dma and tx queues during reinit
+ */
+void wlc_ampdu_reset(ampdu_info_t *ampdu)
+{
+ WL_NONE(("%s: Entering\n", __func__));
+}
+
+static void scb_ampdu_update_config(ampdu_info_t *ampdu, struct scb *scb)
+{
+ scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ int i;
+
+ scb_ampdu->max_pdu = (uint8) ampdu->wlc->pub->tunables->ampdunummpdu;
+
+ /* go back to legacy size if some preloading is occuring */
+ for (i = 0; i < NUM_FFPLD_FIFO; i++) {
+ if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
+ scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
+ }
+
+ /* apply user override */
+ if (ampdu->max_pdu != AUTO)
+ scb_ampdu->max_pdu = (uint8) ampdu->max_pdu;
+
+ scb_ampdu->release = MIN(scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE);
+
+ if (scb_ampdu->max_rxlen)
+ scb_ampdu->release =
+ MIN(scb_ampdu->release, scb_ampdu->max_rxlen / 1600);
+
+ scb_ampdu->release = MIN(scb_ampdu->release,
+ ampdu->fifo_tb[TX_AC_BE_FIFO].
+ mcs2ampdu_table[FFPLD_MAX_MCS]);
+
+ ASSERT(scb_ampdu->release);
+}
+
+void scb_ampdu_update_config_all(ampdu_info_t *ampdu)
+{
+ scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
+}
+
+static void wlc_ffpld_init(ampdu_info_t *ampdu)
+{
+ int i, j;
+ wlc_fifo_info_t *fifo;
+
+ for (j = 0; j < NUM_FFPLD_FIFO; j++) {
+ fifo = (ampdu->fifo_tb + j);
+ fifo->ampdu_pld_size = 0;
+ for (i = 0; i <= FFPLD_MAX_MCS; i++)
+ fifo->mcs2ampdu_table[i] = 255;
+ fifo->dmaxferrate = 0;
+ fifo->accum_txampdu = 0;
+ fifo->prev_txfunfl = 0;
+ fifo->accum_txfunfl = 0;
+
+ }
+}
+
+/* evaluate the dma transfer rate using the tx underflows as feedback.
+ * If necessary, increase tx fifo preloading. If not enough,
+ * decrease maximum ampdu size for each mcs till underflows stop
+ * Return 1 if pre-loading not active, -1 if not an underflow event,
+ * 0 if pre-loading module took care of the event.
+ */
+static int wlc_ffpld_check_txfunfl(wlc_info_t *wlc, int fid)
+{
+ ampdu_info_t *ampdu = wlc->ampdu;
+ uint32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, TRUE, FALSE);
+ uint32 txunfl_ratio;
+ uint8 max_mpdu;
+ uint32 current_ampdu_cnt = 0;
+ uint16 max_pld_size;
+ uint32 new_txunfl;
+ wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid);
+ uint xmtfifo_sz;
+ uint16 cur_txunfl;
+
+ /* return if we got here for a different reason than underflows */
+ cur_txunfl =
+ wlc_read_shm(wlc,
+ M_UCODE_MACSTAT + OFFSETOF(macstat_t, txfunfl[fid]));
+ new_txunfl = (uint16) (cur_txunfl - fifo->prev_txfunfl);
+ if (new_txunfl == 0) {
+ WL_FFPLD(("check_txunfl : TX status FRAG set but no tx underflows\n"));
+ return -1;
+ }
+ fifo->prev_txfunfl = cur_txunfl;
+
+ if (!ampdu->tx_max_funl)
+ return 1;
+
+ /* check if fifo is big enough */
+ if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) {
+ WL_FFPLD(("check_txunfl : get xmtfifo_sz failed.\n"));
+ return -1;
+ }
+
+ if ((TXFIFO_SIZE_UNIT * (uint32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
+ return 1;
+
+ max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
+ fifo->accum_txfunfl += new_txunfl;
+
+ /* we need to wait for at least 10 underflows */
+ if (fifo->accum_txfunfl < 10)
+ return 0;
+
+ WL_FFPLD(("ampdu_count %d tx_underflows %d\n",
+ current_ampdu_cnt, fifo->accum_txfunfl));
+
+ /*
+ compute the current ratio of tx unfl per ampdu.
+ When the current ampdu count becomes too
+ big while the ratio remains small, we reset
+ the current count in order to not
+ introduce too big of a latency in detecting a
+ large amount of tx underflows later.
+ */
+
+ txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
+
+ if (txunfl_ratio > ampdu->tx_max_funl) {
+ if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) {
+ fifo->accum_txfunfl = 0;
+ }
+ return 0;
+ }
+ max_mpdu =
+ MIN(fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+
+ /* In case max value max_pdu is already lower than
+ the fifo depth, there is nothing more we can do.
+ */
+
+ if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
+ WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)"));
+ fifo->accum_txfunfl = 0;
+ return 0;
+ }
+
+ if (fifo->ampdu_pld_size < max_pld_size) {
+
+ /* increment by TX_FIFO_PLD_INC bytes */
+ fifo->ampdu_pld_size += FFPLD_PLD_INCR;
+ if (fifo->ampdu_pld_size > max_pld_size)
+ fifo->ampdu_pld_size = max_pld_size;
+
+ /* update scb release size */
+ scb_ampdu_update_config_all(ampdu);
+
+ /*
+ compute a new dma xfer rate for max_mpdu @ max mcs.
+ This is the minimum dma rate that
+ can acheive no unferflow condition for the current mpdu size.
+ */
+ /* note : we divide/multiply by 100 to avoid integer overflows */
+ fifo->dmaxferrate =
+ (((phy_rate / 100) *
+ (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+ / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+
+ WL_FFPLD(("DMA estimated transfer rate %d; pre-load size %d\n",
+ fifo->dmaxferrate, fifo->ampdu_pld_size));
+ } else {
+
+ /* decrease ampdu size */
+ if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
+ if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
+ fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
+ AMPDU_NUM_MPDU_LEGACY - 1;
+ else
+ fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
+
+ /* recompute the table */
+ wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid);
+
+ /* update scb release size */
+ scb_ampdu_update_config_all(ampdu);
+ }
+ }
+ fifo->accum_txfunfl = 0;
+ return 0;
+}
+
+static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f)
+{
+ int i;
+ uint32 phy_rate, dma_rate, tmp;
+ uint8 max_mpdu;
+ wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f);
+
+ /* recompute the dma rate */
+ /* note : we divide/multiply by 100 to avoid integer overflows */
+ max_mpdu =
+ MIN(fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+ phy_rate = MCS_RATE(FFPLD_MAX_MCS, TRUE, FALSE);
+ dma_rate =
+ (((phy_rate / 100) *
+ (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+ / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+ fifo->dmaxferrate = dma_rate;
+
+ /* fill up the mcs2ampdu table; do not recalc the last mcs */
+ dma_rate = dma_rate >> 7;
+ for (i = 0; i < FFPLD_MAX_MCS; i++) {
+ /* shifting to keep it within integer range */
+ phy_rate = MCS_RATE(i, TRUE, FALSE) >> 7;
+ if (phy_rate > dma_rate) {
+ tmp = ((fifo->ampdu_pld_size * phy_rate) /
+ ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
+ tmp = MIN(tmp, 255);
+ fifo->mcs2ampdu_table[i] = (uint8) tmp;
+ }
+ }
+}
+
+static void BCMFASTPATH
+wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, void *p, uint prec)
+{
+ scb_ampdu_t *scb_ampdu;
+ scb_ampdu_tid_ini_t *ini;
+ uint8 tid = (uint8) PKTPRIO(p);
+
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+
+ /* initialize initiator on first packet; sends addba req */
+ ini = SCB_AMPDU_INI(scb_ampdu, tid);
+ if (ini->magic != INI_MAGIC) {
+ ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, FALSE);
+ }
+ return;
+}
+
+int BCMFASTPATH
+wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **pdu, int prec)
+{
+ wlc_info_t *wlc;
+ osl_t *osh;
+ void *p, *pkt[AMPDU_MAX_MPDU];
+ uint8 tid, ndelim;
+ int err = 0;
+ uint8 preamble_type = WLC_GF_PREAMBLE;
+ uint8 fbr_preamble_type = WLC_GF_PREAMBLE;
+ uint8 rts_preamble_type = WLC_LONG_PREAMBLE;
+ uint8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE;
+
+ bool rr = TRUE, fbr = FALSE;
+ uint i, count = 0, fifo, seg_cnt = 0;
+ uint16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
+ uint32 ampdu_len, maxlen = 0;
+ d11txh_t *txh = NULL;
+ uint8 *plcp;
+ struct dot11_header *h;
+ struct scb *scb;
+ scb_ampdu_t *scb_ampdu;
+ scb_ampdu_tid_ini_t *ini;
+ uint8 mcs = 0;
+ bool use_rts = FALSE, use_cts = FALSE;
+ ratespec_t rspec = 0, rspec_fallback = 0;
+ ratespec_t rts_rspec = 0, rts_rspec_fallback = 0;
+ uint16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+ struct dot11_rts_frame *rts;
+ uint8 rr_retry_limit;
+ wlc_fifo_info_t *f;
+ bool fbr_iscck;
+ struct ieee80211_tx_info *tx_info;
+ uint16 qlen;
+
+ wlc = ampdu->wlc;
+ osh = wlc->osh;
+ p = *pdu;
+
+ ASSERT(p);
+
+ tid = (uint8) PKTPRIO(p);
+ ASSERT(tid < AMPDU_MAX_SCB_TID);
+
+ f = ampdu->fifo_tb + prio2fifo[tid];
+
+ scb = wlc->pub->global_scb;
+ ASSERT(scb->magic == SCB_MAGIC);
+
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ ASSERT(scb_ampdu);
+ ini = &scb_ampdu->ini[tid];
+
+ /* Let pressure continue to build ... */
+ qlen = pktq_plen(&qi->q, prec);
+ if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
+ return BCME_BUSY;
+ }
+
+ wlc_ampdu_agg(ampdu, scb, p, tid);
+
+ if (wlc->block_datafifo) {
+ WL_ERROR(("%s: Fifo blocked\n", __func__));
+ return BCME_BUSY;
+ }
+ rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+ ampdu_len = 0;
+ dma_len = 0;
+ while (p) {
+ struct ieee80211_tx_rate *txrate;
+
+ tx_info = IEEE80211_SKB_CB(p);
+ txrate = tx_info->status.rates;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ err = wlc_prep_pdu(wlc, p, &fifo);
+ } else {
+ WL_ERROR(("%s: AMPDU flag is off!\n", __func__));
+ *pdu = NULL;
+ err = 0;
+ break;
+ }
+
+ if (err) {
+ if (err == BCME_BUSY) {
+ WL_ERROR(("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", wlc->pub->unit, seq));
+ WLCNTINCR(ampdu->cnt->sduretry);
+ *pdu = p;
+ break;
+ }
+
+ /* error in the packet; reject it */
+ WL_AMPDU_ERR(("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", wlc->pub->unit, seq));
+ WLCNTINCR(ampdu->cnt->sdurejected);
+
+ *pdu = NULL;
+ break;
+ }
+
+ /* pkt is good to be aggregated */
+ ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+ txh = (d11txh_t *) PKTDATA(p);
+ plcp = (uint8 *) (txh + 1);
+ h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN);
+ seq = ltoh16(h->seq) >> SEQNUM_SHIFT;
+ index = TX_SEQ_TO_INDEX(seq);
+
+ /* check mcl fields and test whether it can be agg'd */
+ mcl = ltoh16(txh->MacTxControlLow);
+ mcl &= ~TXC_AMPDU_MASK;
+ fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3);
+ ASSERT(!fbr_iscck);
+ txh->PreloadSize = 0; /* always default to 0 */
+
+ /* Handle retry limits */
+ if (txrate[0].count <= rr_retry_limit) {
+ txrate[0].count++;
+ rr = TRUE;
+ fbr = FALSE;
+ ASSERT(!fbr);
+ } else {
+ fbr = TRUE;
+ rr = FALSE;
+ txrate[1].count++;
+ }
+
+ /* extract the length info */
+ len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+ : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+
+ /* retrieve null delimiter count */
+ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+ seg_cnt += 1;
+
+ WL_AMPDU_TX(("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n",
+ wlc->pub->unit, count, len));
+
+ /*
+ * aggregateable mpdu. For ucode/hw agg,
+ * test whether need to break or change the epoch
+ */
+ if (count == 0) {
+ uint16 fc;
+ mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
+ /* refill the bits since might be a retx mpdu */
+ mcl |= TXC_STARTMSDU;
+ rts = (struct dot11_rts_frame *)&txh->rts_frame;
+ fc = ltoh16(rts->fc);
+ if ((fc & FC_KIND_MASK) == FC_RTS) {
+ mcl |= TXC_SENDRTS;
+ use_rts = TRUE;
+ }
+ if ((fc & FC_KIND_MASK) == FC_CTS) {
+ mcl |= TXC_SENDCTS;
+ use_cts = TRUE;
+ }
+ } else {
+ mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
+ mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
+ }
+
+ len = ROUNDUP(len, 4);
+ ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
+
+ dma_len += (uint16) pkttotlen(osh, p);
+
+ WL_AMPDU_TX(("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", wlc->pub->unit, ampdu_len, seg_cnt, ndelim));
+
+ txh->MacTxControlLow = htol16(mcl);
+
+ /* this packet is added */
+ pkt[count++] = p;
+
+ /* patch the first MPDU */
+ if (count == 1) {
+ uint8 plcp0, plcp3, is40, sgi;
+ struct ieee80211_sta *sta;
+
+ sta = tx_info->control.sta;
+
+ if (rr) {
+ plcp0 = plcp[0];
+ plcp3 = plcp[3];
+ } else {
+ plcp0 = txh->FragPLCPFallback[0];
+ plcp3 = txh->FragPLCPFallback[3];
+
+ }
+ is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
+ sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
+ mcs = plcp0 & ~MIMO_PLCP_40MHZ;
+ ASSERT(mcs < MCS_TABLE_SIZE);
+ maxlen =
+ MIN(scb_ampdu->max_rxlen,
+ ampdu->max_txlen[mcs][is40][sgi]);
+
+ WL_NONE(("sendampdu: sgi %d, is40 %d, mcs %d\n", sgi,
+ is40, mcs));
+
+ maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */
+
+ if (is40)
+ mimo_ctlchbw =
+ CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+ ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+
+ /* rebuild the rspec and rspec_fallback */
+ rspec = RSPEC_MIMORATE;
+ rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
+ if (plcp[0] & MIMO_PLCP_40MHZ)
+ rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+
+ if (fbr_iscck) /* CCK */
+ rspec_fallback =
+ CCK_RSPEC(CCK_PHY2MAC_RATE
+ (txh->FragPLCPFallback[0]));
+ else { /* MIMO */
+ rspec_fallback = RSPEC_MIMORATE;
+ rspec_fallback |=
+ txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
+ if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
+ rspec_fallback |=
+ (PHY_TXC1_BW_40MHZ <<
+ RSPEC_BW_SHIFT);
+ }
+
+ if (use_rts || use_cts) {
+ rts_rspec =
+ wlc_rspec_to_rts_rspec(wlc, rspec, FALSE,
+ mimo_ctlchbw);
+ rts_rspec_fallback =
+ wlc_rspec_to_rts_rspec(wlc, rspec_fallback,
+ FALSE, mimo_ctlchbw);
+ }
+ }
+
+ /* if (first mpdu for host agg) */
+ /* test whether to add more */
+ if ((MCS_RATE(mcs, TRUE, FALSE) >= f->dmaxferrate) &&
+ (count == f->mcs2ampdu_table[mcs])) {
+ WL_AMPDU_ERR(("wl%d: PR 37644: stopping ampdu at %d for mcs %d", wlc->pub->unit, count, mcs));
+ break;
+ }
+
+ if (count == scb_ampdu->max_pdu) {
+ WL_NONE(("Stop taking from q, reached %d deep\n",
+ scb_ampdu->max_pdu));
+ break;
+ }
+
+ /* check to see if the next pkt is a candidate for aggregation */
+ p = pktq_ppeek(&qi->q, prec);
+ tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */
+
+ if (p) {
+ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
+ ((uint8) PKTPRIO(p) == tid)) {
+
+ plen =
+ pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD;
+ plen = MAX(scb_ampdu->min_len, plen);
+
+ if ((plen + ampdu_len) > maxlen) {
+ p = NULL;
+ WL_ERROR(("%s: Bogus plen #1\n",
+ __func__));
+ ASSERT(3 == 4);
+ continue;
+ }
+
+ /* check if there are enough descriptors available */
+ if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) {
+ WL_ERROR(("%s: No fifo space !!!!!!\n", __func__));
+ p = NULL;
+ continue;
+ }
+ p = pktq_pdeq(&qi->q, prec);
+ ASSERT(p);
+ } else {
+ p = NULL;
+ }
+ }
+ } /* end while(p) */
+
+ ini->tx_in_transit += count;
+
+ if (count) {
+ WLCNTADD(ampdu->cnt->txmpdu, count);
+
+ /* patch up the last txh */
+ txh = (d11txh_t *) PKTDATA(pkt[count - 1]);
+ mcl = ltoh16(txh->MacTxControlLow);
+ mcl &= ~TXC_AMPDU_MASK;
+ mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
+ txh->MacTxControlLow = htol16(mcl);
+
+ /* remove the null delimiter after last mpdu */
+ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+ txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
+ ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
+
+ /* remove the pad len from last mpdu */
+ fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0);
+ len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+ : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+ ampdu_len -= ROUNDUP(len, 4) - len;
+
+ /* patch up the first txh & plcp */
+ txh = (d11txh_t *) PKTDATA(pkt[0]);
+ plcp = (uint8 *) (txh + 1);
+
+ WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
+ /* mark plcp to indicate ampdu */
+ WLC_SET_MIMO_PLCP_AMPDU(plcp);
+
+ /* reset the mixed mode header durations */
+ if (txh->MModeLen) {
+ uint16 mmodelen =
+ wlc_calc_lsig_len(wlc, rspec, ampdu_len);
+ txh->MModeLen = htol16(mmodelen);
+ preamble_type = WLC_MM_PREAMBLE;
+ }
+ if (txh->MModeFbrLen) {
+ uint16 mmfbrlen =
+ wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len);
+ txh->MModeFbrLen = htol16(mmfbrlen);
+ fbr_preamble_type = WLC_MM_PREAMBLE;
+ }
+
+ /* set the preload length */
+ if (MCS_RATE(mcs, TRUE, FALSE) >= f->dmaxferrate) {
+ dma_len = MIN(dma_len, f->ampdu_pld_size);
+ txh->PreloadSize = htol16(dma_len);
+ } else
+ txh->PreloadSize = 0;
+
+ mch = ltoh16(txh->MacTxControlHigh);
+
+ /* update RTS dur fields */
+ if (use_rts || use_cts) {
+ uint16 durid;
+ rts = (struct dot11_rts_frame *)&txh->rts_frame;
+ if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
+ TXC_PREAMBLE_RTS_MAIN_SHORT)
+ rts_preamble_type = WLC_SHORT_PREAMBLE;
+
+ if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
+ TXC_PREAMBLE_RTS_FB_SHORT)
+ rts_fbr_preamble_type = WLC_SHORT_PREAMBLE;
+
+ durid =
+ wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec,
+ rspec, rts_preamble_type,
+ preamble_type, ampdu_len,
+ TRUE);
+ rts->durid = htol16(durid);
+ durid = wlc_compute_rtscts_dur(wlc, use_cts,
+ rts_rspec_fallback,
+ rspec_fallback,
+ rts_fbr_preamble_type,
+ fbr_preamble_type,
+ ampdu_len, TRUE);
+ txh->RTSDurFallback = htol16(durid);
+ /* set TxFesTimeNormal */
+ txh->TxFesTimeNormal = rts->durid;
+ /* set fallback rate version of TxFesTimeNormal */
+ txh->TxFesTimeFallback = txh->RTSDurFallback;
+ }
+
+ /* set flag and plcp for fallback rate */
+ if (fbr) {
+ WLCNTADD(ampdu->cnt->txfbr_mpdu, count);
+ WLCNTINCR(ampdu->cnt->txfbr_ampdu);
+ mch |= TXC_AMPDU_FBR;
+ txh->MacTxControlHigh = htol16(mch);
+ WLC_SET_MIMO_PLCP_AMPDU(plcp);
+ WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
+ }
+
+ WL_AMPDU_TX(("wl%d: wlc_sendampdu: count %d ampdu_len %d\n",
+ wlc->pub->unit, count, ampdu_len));
+
+ /* inform rate_sel if it this is a rate probe pkt */
+ frameid = ltoh16(txh->TxFrameID);
+ if (frameid & TXFID_RATE_PROBE_MASK) {
+ WL_ERROR(("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", __func__));
+ }
+#ifdef WLC_HIGH_ONLY
+ if (wlc->rpc_agg & BCM_RPC_TP_HOST_AGG_AMPDU)
+ bcm_rpc_tp_agg_set(bcm_rpc_tp_get(wlc->rpc),
+ BCM_RPC_TP_HOST_AGG_AMPDU, TRUE);
+#endif
+ for (i = 0; i < count; i++)
+ wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1),
+ ampdu->txpkt_weight);
+#ifdef WLC_HIGH_ONLY
+ if (wlc->rpc_agg & BCM_RPC_TP_HOST_AGG_AMPDU)
+ bcm_rpc_tp_agg_set(bcm_rpc_tp_get(wlc->rpc),
+ BCM_RPC_TP_HOST_AGG_AMPDU, FALSE);
+#endif
+
+ }
+ /* endif (count) */
+ return err;
+}
+
+void BCMFASTPATH
+wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p,
+ tx_status_t *txs)
+{
+ scb_ampdu_t *scb_ampdu;
+ wlc_info_t *wlc = ampdu->wlc;
+ scb_ampdu_tid_ini_t *ini;
+ uint32 s1 = 0, s2 = 0;
+ struct ieee80211_tx_info *tx_info;
+
+ tx_info = IEEE80211_SKB_CB(p);
+ ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+ ASSERT(scb);
+ ASSERT(scb->magic == SCB_MAGIC);
+ ASSERT(txs->status & TX_STATUS_AMPDU);
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ ASSERT(scb_ampdu);
+ ini = SCB_AMPDU_INI(scb_ampdu, PKTPRIO(p));
+ ASSERT(ini->scb == scb);
+
+ /* BMAC_NOTE: For the split driver, second level txstatus comes later
+ * So if the ACK was received then wait for the second level else just
+ * call the first one
+ */
+ if (txs->status & TX_STATUS_ACK_RCV) {
+#ifdef WLC_LOW
+ uint8 status_delay = 0;
+
+ /* wait till the next 8 bytes of txstatus is available */
+ while (((s1 =
+ R_REG(wlc->osh,
+ &wlc->regs->frmtxstatus)) & TXS_V) == 0) {
+ OSL_DELAY(1);
+ status_delay++;
+ if (status_delay > 10) {
+ ASSERT(status_delay <= 10);
+ return;
+ }
+ }
+
+ ASSERT(!(s1 & TX_STATUS_INTERMEDIATE));
+ ASSERT(s1 & TX_STATUS_AMPDU);
+ s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2);
+#else /* WLC_LOW */
+
+ /* Store the relevant information in ampdu structure */
+ WL_AMPDU_TX(("wl%d: wlc_ampdu_dotxstatus: High Recvd\n",
+ wlc->pub->unit));
+
+ ASSERT(!ampdu->p);
+ ampdu->p = p;
+ bcopy(txs, &ampdu->txs, sizeof(tx_status_t));
+ ampdu->waiting_status = TRUE;
+ return;
+#endif /* WLC_LOW */
+ }
+
+ wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
+ wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
+}
+
+#ifdef WLC_HIGH_ONLY
+void wlc_ampdu_txstatus_complete(ampdu_info_t *ampdu, uint32 s1, uint32 s2)
+{
+ WL_AMPDU_TX(("wl%d: wlc_ampdu_txstatus_complete: High Recvd 0x%x 0x%x p:%p\n", ampdu->wlc->pub->unit, s1, s2, ampdu->p));
+
+ ASSERT(ampdu->waiting_status);
+
+ /* The packet may have been freed if the SCB went away, if so, then still free the
+ * DMA chain
+ */
+ if (ampdu->p) {
+ struct ieee80211_tx_info *tx_info;
+ struct scb *scb;
+
+ tx_info = IEEE80211_SKB_CB(ampdu->p);
+ scb = (struct scb *)tx_info->control.sta->drv_priv;
+
+ wlc_ampdu_dotxstatus_complete(ampdu, scb, ampdu->p, &ampdu->txs,
+ s1, s2);
+ ampdu->p = NULL;
+ }
+
+ ampdu->waiting_status = FALSE;
+}
+#endif /* WLC_HIGH_ONLY */
+void rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info,
+ tx_status_t *txs, uint8 mcs);
+
+void
+rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info,
+ tx_status_t *txs, uint8 mcs)
+{
+ struct ieee80211_tx_rate *txrate = tx_info->status.rates;
+ int i;
+
+ /* clear the rest of the rates */
+ for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+ txrate[i].idx = -1;
+ txrate[i].count = 0;
+ }
+}
+
+extern void wlc_txq_enq(wlc_info_t *wlc, struct scb *scb, void *sdu,
+ uint prec);
+
+#define SHORTNAME "AMPDU status"
+
+static void BCMFASTPATH
+wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, void *p,
+ tx_status_t *txs, uint32 s1, uint32 s2)
+{
+ scb_ampdu_t *scb_ampdu;
+ wlc_info_t *wlc = ampdu->wlc;
+ scb_ampdu_tid_ini_t *ini;
+ uint8 bitmap[8], queue, tid;
+ d11txh_t *txh;
+ uint8 *plcp;
+ struct dot11_header *h;
+ uint16 seq, start_seq = 0, bindex, index, mcl;
+ uint8 mcs = 0;
+ bool ba_recd = FALSE, ack_recd = FALSE;
+ uint8 suc_mpdu = 0, tot_mpdu = 0;
+ uint supr_status;
+ bool update_rate = TRUE, retry = TRUE, tx_error = FALSE;
+ uint16 mimoantsel = 0;
+ uint8 antselid = 0;
+ uint8 retry_limit, rr_retry_limit;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
+
+#ifdef BCMDBG
+ uint8 hole[AMPDU_MAX_MPDU];
+ bzero(hole, sizeof(hole));
+#endif
+
+ ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+ ASSERT(txs->status & TX_STATUS_AMPDU);
+
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ ASSERT(scb_ampdu);
+
+ tid = (uint8) PKTPRIO(p);
+
+ ini = SCB_AMPDU_INI(scb_ampdu, tid);
+ retry_limit = ampdu->retry_limit_tid[tid];
+ rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+
+ ASSERT(ini->scb == scb);
+
+ bzero(bitmap, sizeof(bitmap));
+ queue = txs->frameid & TXFID_QUEUE_MASK;
+ ASSERT(queue < AC_COUNT);
+
+ supr_status = txs->status & TX_STATUS_SUPR_MASK;
+
+ if (txs->status & TX_STATUS_ACK_RCV) {
+ if (TX_STATUS_SUPR_UF == supr_status) {
+ update_rate = FALSE;
+ }
+
+ ASSERT(txs->status & TX_STATUS_INTERMEDIATE);
+ start_seq = txs->sequence >> SEQNUM_SHIFT;
+ bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
+ TX_STATUS_BA_BMAP03_SHIFT;
+
+ ASSERT(!(s1 & TX_STATUS_INTERMEDIATE));
+ ASSERT(s1 & TX_STATUS_AMPDU);
+
+ bitmap[0] |=
+ (s1 & TX_STATUS_BA_BMAP47_MASK) <<
+ TX_STATUS_BA_BMAP47_SHIFT;
+ bitmap[1] = (s1 >> 8) & 0xff;
+ bitmap[2] = (s1 >> 16) & 0xff;
+ bitmap[3] = (s1 >> 24) & 0xff;
+
+ bitmap[4] = s2 & 0xff;
+ bitmap[5] = (s2 >> 8) & 0xff;
+ bitmap[6] = (s2 >> 16) & 0xff;
+ bitmap[7] = (s2 >> 24) & 0xff;
+
+ ba_recd = TRUE;
+ } else {
+ WLCNTINCR(ampdu->cnt->noba);
+ if (supr_status) {
+ update_rate = FALSE;
+ if (supr_status == TX_STATUS_SUPR_BADCH) {
+ WL_ERROR(("%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)));
+ } else {
+ if (supr_status == TX_STATUS_SUPR_FRAG)
+ WL_NONE(("%s: AMPDU frag err\n",
+ __func__));
+ else
+ WL_ERROR(("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", __func__, supr_status));
+ }
+ /* no need to retry for badch; will fail again */
+ if (supr_status == TX_STATUS_SUPR_BADCH ||
+ supr_status == TX_STATUS_SUPR_EXPTIME) {
+ retry = FALSE;
+ WLCNTINCR(wlc->pub->_cnt->txchanrej);
+ } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
+
+ WLCNTINCR(wlc->pub->_cnt->txexptime);
+
+ /* TX underflow : try tuning pre-loading or ampdu size */
+ } else if (supr_status == TX_STATUS_SUPR_FRAG) {
+ /* if there were underflows, but pre-loading is not active,
+ notify rate adaptation.
+ */
+ if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid])
+ > 0) {
+ tx_error = TRUE;
+#ifdef WLC_HIGH_ONLY
+ /* With BMAC, TX Underflows should not happen */
+ WL_ERROR(("wl%d: BMAC TX Underflow?",
+ wlc->pub->unit));
+#endif
+ }
+ }
+ } else if (txs->phyerr) {
+ update_rate = FALSE;
+ WLCNTINCR(wlc->pub->_cnt->txphyerr);
+ WL_ERROR(("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", wlc->pub->unit, txs->phyerr));
+
+#ifdef BCMDBG
+ if (WL_ERROR_ON()) {
+ prpkt("txpkt (AMPDU)", wlc->osh, p);
+ wlc_print_txdesc((d11txh_t *) PKTDATA(p));
+ wlc_print_txstatus(txs);
+ }
+#endif /* BCMDBG */
+ }
+ }
+
+ /* loop through all pkts and retry if not acked */
+ while (p) {
+ tx_info = IEEE80211_SKB_CB(p);
+ ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+ txh = (d11txh_t *) PKTDATA(p);
+ mcl = ltoh16(txh->MacTxControlLow);
+ plcp = (uint8 *) (txh + 1);
+ h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN);
+ seq = ltoh16(h->seq) >> SEQNUM_SHIFT;
+
+ if (tot_mpdu == 0) {
+ mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
+ mimoantsel = ltoh16(txh->ABI_MimoAntSel);
+ }
+
+ index = TX_SEQ_TO_INDEX(seq);
+ ack_recd = FALSE;
+ if (ba_recd) {
+ bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
+
+ WL_AMPDU_TX(("%s: tid %d seq is %d, start_seq is %d, "
+ "bindex is %d set %d, index %d\n",
+ __func__, tid, seq, start_seq, bindex,
+ isset(bitmap, bindex), index));
+
+ /* if acked then clear bit and free packet */
+ if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
+ && isset(bitmap, bindex)) {
+ ini->tx_in_transit--;
+ ini->txretry[index] = 0;
+
+ /* ampdu_ack_len: number of acked aggregated frames */
+ /* ampdu_ack_map: block ack bit map for the aggregation */
+ /* ampdu_len: number of aggregated frames */
+ rate_status(wlc, tx_info, txs, mcs);
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+
+ /* XXX TODO: Make these accurate. */
+ tx_info->status.ampdu_ack_len =
+ (txs->
+ status & TX_STATUS_FRM_RTX_MASK) >>
+ TX_STATUS_FRM_RTX_SHIFT;
+ tx_info->status.ampdu_len =
+ (txs->
+ status & TX_STATUS_FRM_RTX_MASK) >>
+ TX_STATUS_FRM_RTX_SHIFT;
+
+ PKTPULL(p, D11_PHY_HDR_LEN);
+ PKTPULL(p, D11_TXH_LEN);
+
+ ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+ p);
+ ack_recd = TRUE;
+ suc_mpdu++;
+ }
+ }
+ /* either retransmit or send bar if ack not recd */
+ if (!ack_recd) {
+ struct ieee80211_tx_rate *txrate =
+ tx_info->status.rates;
+ if (retry && (txrate[0].count < (int)retry_limit)) {
+ ini->txretry[index]++;
+ ini->tx_in_transit--;
+ /* Use high prededence for retransmit to give some punch */
+ /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */
+ wlc_txq_enq(wlc, scb, p,
+ WLC_PRIO_TO_HI_PREC(tid));
+ } else {
+ /* Retry timeout */
+ ini->tx_in_transit--;
+ ieee80211_tx_info_clear_status(tx_info);
+ tx_info->flags |=
+ IEEE80211_TX_STAT_AMPDU_NO_BACK;
+ PKTPULL(p, D11_PHY_HDR_LEN);
+ PKTPULL(p, D11_TXH_LEN);
+ WL_ERROR(("%s: BA Timeout, seq %d, in_transit %d\n", SHORTNAME, seq, ini->tx_in_transit));
+ ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+ p);
+ }
+ }
+ tot_mpdu++;
+
+ /* break out if last packet of ampdu */
+ if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
+ TXC_AMPDU_LAST)
+ break;
+
+ p = GETNEXTTXP(wlc, queue);
+ if (p == NULL) {
+ ASSERT(p);
+ break;
+ }
+ }
+ wlc_send_q(wlc, wlc->active_queue);
+
+ /* update rate state */
+ if (WLANTSEL_ENAB(wlc))
+ antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
+
+ wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+}
+
+static void
+ampdu_cleanup_tid_ini(ampdu_info_t *ampdu, scb_ampdu_t *scb_ampdu, uint8 tid,
+ bool force)
+{
+ scb_ampdu_tid_ini_t *ini;
+ ini = SCB_AMPDU_INI(scb_ampdu, tid);
+ if (!ini)
+ return;
+
+ WL_AMPDU_CTL(("wl%d: ampdu_cleanup_tid_ini: tid %d\n",
+ ampdu->wlc->pub->unit, tid));
+
+ if (ini->tx_in_transit && !force)
+ return;
+
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb);
+ ASSERT(ini == &scb_ampdu->ini[ini->tid]);
+
+ /* free all buffered tx packets */
+ pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, TRUE, NULL, 0);
+}
+
+/* initialize the initiator code for tid */
+static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu,
+ scb_ampdu_t *scb_ampdu,
+ uint8 tid, bool override)
+{
+ scb_ampdu_tid_ini_t *ini;
+
+ ASSERT(scb_ampdu);
+ ASSERT(scb_ampdu->scb);
+ ASSERT(SCB_AMPDU(scb_ampdu->scb));
+ ASSERT(tid < AMPDU_MAX_SCB_TID);
+
+ /* check for per-tid control of ampdu */
+ if (!ampdu->ini_enable[tid]) {
+ WL_ERROR(("%s: Rejecting tid %d\n", __func__, tid));
+ return NULL;
+ }
+
+ ini = SCB_AMPDU_INI(scb_ampdu, tid);
+ ini->tid = tid;
+ ini->scb = scb_ampdu->scb;
+ ini->magic = INI_MAGIC;
+ WLCNTINCR(ampdu->cnt->txaddbareq);
+
+ return ini;
+}
+
+int wlc_ampdu_set(ampdu_info_t *ampdu, bool on)
+{
+ wlc_info_t *wlc = ampdu->wlc;
+
+ wlc->pub->_ampdu = FALSE;
+
+ if (on) {
+ if (!N_ENAB(wlc->pub)) {
+ WL_AMPDU_ERR(("wl%d: driver not nmode enabled\n",
+ wlc->pub->unit));
+ return BCME_UNSUPPORTED;
+ }
+ if (!wlc_ampdu_cap(ampdu)) {
+ WL_AMPDU_ERR(("wl%d: device not ampdu capable\n",
+ wlc->pub->unit));
+ return BCME_UNSUPPORTED;
+ }
+ wlc->pub->_ampdu = on;
+ }
+
+ return 0;
+}
+
+bool wlc_ampdu_cap(ampdu_info_t *ampdu)
+{
+ if (WLC_PHY_11N_CAP(ampdu->wlc->band))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void ampdu_update_max_txlen(ampdu_info_t *ampdu, uint8 dur)
+{
+ uint32 rate, mcs;
+
+ for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
+ /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
+ /* 20MHz, No SGI */
+ rate = MCS_RATE(mcs, FALSE, FALSE);
+ ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
+ /* 40 MHz, No SGI */
+ rate = MCS_RATE(mcs, TRUE, FALSE);
+ ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
+ /* 20MHz, SGI */
+ rate = MCS_RATE(mcs, FALSE, TRUE);
+ ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
+ /* 40 MHz, SGI */
+ rate = MCS_RATE(mcs, TRUE, TRUE);
+ ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
+ }
+}
+
+uint8 BCMFASTPATH
+wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb,
+ ratespec_t rspec, int phylen)
+{
+ scb_ampdu_t *scb_ampdu;
+ int bytes, cnt, tmp;
+ uint8 tx_density;
+
+ ASSERT(scb);
+ ASSERT(SCB_AMPDU(scb));
+
+ scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+ ASSERT(scb_ampdu);
+
+ if (scb_ampdu->mpdu_density == 0)
+ return 0;
+
+ /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec
+ density x is in 2^(x-4) usec
+ ==> # of bytes needed for req density = rate/2^(17-x)
+ ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4)
+ */
+
+ tx_density = scb_ampdu->mpdu_density;
+
+ ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY);
+ tmp = 1 << (17 - tx_density);
+ bytes = CEIL(RSPEC2RATE(rspec), tmp);
+
+ if (bytes > phylen) {
+ cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN);
+ ASSERT(cnt <= 255);
+ return (uint8) cnt;
+ } else
+ return 0;
+}
+
+void wlc_ampdu_macaddr_upd(wlc_info_t *wlc)
+{
+ char template[T_RAM_ACCESS_SZ * 2];
+
+ /* driver needs to write the ta in the template; ta is at offset 16 */
+ bzero(template, sizeof(template));
+ bcopy((char *)wlc->pub->cur_etheraddr.octet, template, ETHER_ADDR_LEN);
+ wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2),
+ template);
+}
+
+bool wlc_aggregatable(wlc_info_t *wlc, uint8 tid)
+{
+ return wlc->ampdu->ini_enable[tid];
+}
+
+void wlc_ampdu_shm_upd(ampdu_info_t *ampdu)
+{
+ wlc_info_t *wlc = ampdu->wlc;
+
+ /* Extend ucode internal watchdog timer to match larger received frames */
+ if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) ==
+ AMPDU_RX_FACTOR_64K) {
+ wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
+ wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
+ } else {
+ wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
+ wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
+ }
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h
new file mode 100644
index 000000000000..9b6dd91a5af6
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_ampdu.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_ampdu_h_
+#define _wlc_ampdu_h_
+
+extern ampdu_info_t *wlc_ampdu_attach(wlc_info_t *wlc);
+extern void wlc_ampdu_detach(ampdu_info_t *ampdu);
+extern bool wlc_ampdu_cap(ampdu_info_t *ampdu);
+extern int wlc_ampdu_set(ampdu_info_t *ampdu, bool on);
+extern int wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **aggp,
+ int prec);
+extern void wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p,
+ tx_status_t *txs);
+extern void wlc_ampdu_reset(ampdu_info_t *ampdu);
+extern void wlc_ampdu_macaddr_upd(wlc_info_t *wlc);
+extern void wlc_ampdu_shm_upd(ampdu_info_t *ampdu);
+
+extern uint8 wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb,
+ ratespec_t rspec, int phylen);
+extern void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb);
+#ifdef WLC_HIGH_ONLY
+extern void wlc_ampdu_txstatus_complete(ampdu_info_t *ampdu, uint32 s1,
+ uint32 s2);
+#endif
+
+#endif /* _wlc_ampdu_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c
new file mode 100644
index 000000000000..a34ea66f9454
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_antsel.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+
+#ifdef WLANTSEL
+
+#include <typedefs.h>
+#include <qmath.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+#include <wlc_phy_radio.h>
+#include <bitfuncs.h>
+
+#include <proto/802.11.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_key.h>
+#include <wlc_pub.h>
+#include <wlc_bsscfg.h>
+#include <wl_dbg.h>
+#include <wlc_mac80211.h>
+#include <wlc_bmac.h>
+#include <wlc_phy_hal.h>
+#include <wl_export.h>
+#include <wlc_antsel.h>
+#include <wlc_phy_shim.h>
+
+/* useful macros */
+#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
+#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
+#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant)))
+#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
+#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
+
+/* antenna switch */
+/* defines for no boardlevel antenna diversity */
+#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
+
+/* 2x3 antdiv defines and tables for GPIO communication */
+#define ANT_SELCFG_NUM_2x3 3
+#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
+
+/* 2x4 antdiv rev4 defines and tables for GPIO communication */
+#define ANT_SELCFG_NUM_2x4 4
+#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
+
+/* static functions */
+static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel);
+static uint8 wlc_antsel_id2antcfg(antsel_info_t *asi, uint8 id);
+static uint16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, uint8 ant_cfg);
+static void wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel,
+ bool auto_sel);
+
+const uint16 mimo_2x4_div_antselpat_tbl[] = {
+ 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
+ 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
+ 0, 0, 0, 0, /* n.a. */
+ 0, 0, 0, 0 /* n.a. */
+};
+
+const uint8 mimo_2x4_div_antselid_tbl[16] = {
+ 0, 0, 0, 0, 0, 2, 3, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
+};
+
+const uint16 mimo_2x3_div_antselpat_tbl[] = {
+ 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
+ 16, 16, 16, 16, /* n.a. */
+ 16, 2, 16, 16, /* ant0: 2 ant1: 1 */
+ 16, 16, 16, 16 /* n.a. */
+};
+
+const uint8 mimo_2x3_div_antselid_tbl[16] = {
+ 0, 1, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
+};
+
+antsel_info_t *BCMNMIATTACHFN(wlc_antsel_attach) (wlc_info_t *wlc, osl_t *osh,
+ wlc_pub_t *pub,
+ wlc_hw_info_t *wlc_hw) {
+ antsel_info_t *asi;
+
+ asi = (antsel_info_t *) MALLOC(osh, sizeof(antsel_info_t));
+ if (!asi) {
+ WL_ERROR(("wl%d: wlc_antsel_attach: out of mem, malloced %d bytes\n", pub->unit, MALLOCED(osh)));
+ return NULL;
+ }
+
+ bzero((char *)asi, sizeof(antsel_info_t));
+
+ asi->wlc = wlc;
+ asi->pub = pub;
+ asi->antsel_type = ANTSEL_NA;
+ asi->antsel_avail = FALSE;
+ asi->antsel_antswitch = (uint8) getintvar(asi->pub->vars, "antswitch");
+
+ if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
+ switch (asi->antsel_antswitch) {
+ case ANTSWITCH_TYPE_1:
+ case ANTSWITCH_TYPE_2:
+ case ANTSWITCH_TYPE_3:
+ /* 4321/2 board with 2x3 switch logic */
+ asi->antsel_type = ANTSEL_2x3;
+ /* Antenna selection availability */
+ if (((uint16) getintvar(asi->pub->vars, "aa2g") == 7) ||
+ ((uint16) getintvar(asi->pub->vars, "aa5g") == 7)) {
+ asi->antsel_avail = TRUE;
+ } else
+ if (((uint16) getintvar(asi->pub->vars, "aa2g") ==
+ 3)
+ || ((uint16) getintvar(asi->pub->vars, "aa5g")
+ == 3)) {
+ asi->antsel_avail = FALSE;
+ } else {
+ asi->antsel_avail = FALSE;
+ WL_ERROR(("wlc_antsel_attach: 2o3 board cfg invalid\n"));
+ ASSERT(0);
+ }
+ break;
+ default:
+ break;
+ }
+ } else if ((asi->pub->sromrev == 4) &&
+ ((uint16) getintvar(asi->pub->vars, "aa2g") == 7) &&
+ ((uint16) getintvar(asi->pub->vars, "aa5g") == 0)) {
+ /* hack to match old 4321CB2 cards with 2of3 antenna switch */
+ asi->antsel_type = ANTSEL_2x3;
+ asi->antsel_avail = TRUE;
+ } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
+ asi->antsel_type = ANTSEL_2x4;
+ asi->antsel_avail = TRUE;
+ }
+
+ /* Set the antenna selection type for the low driver */
+ wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type);
+
+ /* Init (auto/manual) antenna selection */
+ wlc_antsel_init_cfg(asi, &asi->antcfg_11n, TRUE);
+ wlc_antsel_init_cfg(asi, &asi->antcfg_cur, TRUE);
+
+ return asi;
+}
+
+void BCMATTACHFN(wlc_antsel_detach) (antsel_info_t *asi)
+{
+ if (!asi)
+ return;
+
+ MFREE(asi->pub->osh, asi, sizeof(antsel_info_t));
+}
+
+void wlc_antsel_init(antsel_info_t *asi)
+{
+ if ((asi->antsel_type == ANTSEL_2x3) ||
+ (asi->antsel_type == ANTSEL_2x4))
+ wlc_antsel_cfgupd(asi, &asi->antcfg_11n);
+}
+
+/* boardlevel antenna selection: init antenna selection structure */
+static void
+wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel,
+ bool auto_sel)
+{
+ if (asi->antsel_type == ANTSEL_2x3) {
+ uint8 antcfg_def = ANT_SELCFG_DEF_2x3 |
+ ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
+ antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
+ antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
+ antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
+ antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
+ antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
+
+ } else if (asi->antsel_type == ANTSEL_2x4) {
+
+ antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
+ antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
+ antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
+ antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
+ antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
+
+ } else { /* no antenna selection available */
+
+ antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
+ antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
+ antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
+ antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
+ antsel->num_antcfg = 0;
+ }
+}
+
+void BCMFASTPATH
+wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel,
+ uint8 antselid, uint8 fbantselid, uint8 *antcfg,
+ uint8 *fbantcfg)
+{
+ uint8 ant;
+
+ /* if use default, assign it and return */
+ if (usedef) {
+ *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
+ *fbantcfg = *antcfg;
+ return;
+ }
+
+ if (!sel) {
+ *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+ *fbantcfg = *antcfg;
+
+ } else {
+ ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+ if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
+ *antcfg = wlc_antsel_id2antcfg(asi, antselid);
+ *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid);
+ } else {
+ *antcfg =
+ asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+ *fbantcfg = *antcfg;
+ }
+ }
+ return;
+}
+
+/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
+uint8 wlc_antsel_antsel2id(antsel_info_t *asi, uint16 antsel)
+{
+ uint8 antselid = 0;
+
+ if (asi->antsel_type == ANTSEL_2x4) {
+ /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+ antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
+ return antselid;
+
+ } else if (asi->antsel_type == ANTSEL_2x3) {
+ /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+ antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
+ return antselid;
+ }
+
+ return antselid;
+}
+
+/* boardlevel antenna selection: convert id to ant_cfg */
+static uint8 wlc_antsel_id2antcfg(antsel_info_t *asi, uint8 id)
+{
+ uint8 antcfg = ANT_SELCFG_DEF_2x2;
+
+ if (asi->antsel_type == ANTSEL_2x4) {
+ /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+ antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
+ return antcfg;
+
+ } else if (asi->antsel_type == ANTSEL_2x3) {
+ /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+ antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
+ return antcfg;
+ }
+
+ return antcfg;
+}
+
+/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
+static uint16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, uint8 ant_cfg)
+{
+ uint8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg));
+ uint16 mimo_antsel = 0;
+
+ if (asi->antsel_type == ANTSEL_2x4) {
+ /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+ mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
+ return mimo_antsel;
+
+ } else if (asi->antsel_type == ANTSEL_2x3) {
+ /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+ mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
+ return mimo_antsel;
+ }
+
+ return mimo_antsel;
+}
+
+/* boardlevel antenna selection: ucode interface control */
+static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel)
+{
+ wlc_info_t *wlc = asi->wlc;
+ uint8 ant_cfg;
+ uint16 mimo_antsel;
+
+ ASSERT(asi->antsel_type != ANTSEL_NA);
+
+ /* 1) Update TX antconfig for all frames that are not unicast data
+ * (aka default TX)
+ */
+ ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
+ mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+ wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
+ /* Update driver stats for currently selected default tx/rx antenna config */
+ asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
+
+ /* 2) Update RX antconfig for all frames that are not unicast data
+ * (aka default RX)
+ */
+ ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
+ mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+ wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
+ /* Update driver stats for currently selected default tx/rx antenna config */
+ asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
+
+ return 0;
+}
+
+#endif /* WLANTSEL */
diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h
new file mode 100644
index 000000000000..7ac52d0294b0
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_antsel.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_antsel_h_
+#define _wlc_antsel_h_
+extern antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, osl_t *osh,
+ wlc_pub_t *pub,
+ wlc_hw_info_t *wlc_hw);
+extern void wlc_antsel_detach(antsel_info_t *asi);
+extern void wlc_antsel_init(antsel_info_t *asi);
+extern void wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel,
+ uint8 id, uint8 fbid, uint8 *antcfg,
+ uint8 *fbantcfg);
+extern uint8 wlc_antsel_antsel2id(antsel_info_t *asi, uint16 antsel);
+#endif /* _wlc_antsel_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c
new file mode 100644
index 000000000000..c22394d84535
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_bmac.c
@@ -0,0 +1,4211 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 WLC_LOW
+#error "This file needs WLC_LOW"
+#endif
+
+#include <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <proto/802.11.h>
+#include <bcmwifi.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <hnddma.h>
+#include <hndpmu.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_channel.h>
+#include <bcmsrom.h>
+#include <wlc_key.h>
+/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type
+ * dependencies. Need to include these to files to allow a clean include of wlc.h
+ * with WLC_HIGH defined.
+ * At some point we may be able to skip the include of wlc.h and instead just
+ * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle.
+ */
+#include <wlc_mac80211.h>
+#include <wlc_bmac.h>
+#include <wlc_phy_shim.h>
+#include <wlc_phy_hal.h>
+#include <wl_export.h>
+#include "wl_ucode.h"
+#include "d11ucode_ext.h"
+#ifdef BCMSDIO
+#include <bcmsdh.h>
+#endif
+#include <bcmotp.h>
+
+/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level
+ * functions defined in the headers below. We should be eliminating those calls and
+ * will be able to delete these include lines.
+ */
+#include <wlc_antsel.h>
+
+#include <pcie_core.h>
+
+#include <wlc_alloc.h>
+
+#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */
+
+#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */
+#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */
+#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */
+#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */
+
+#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */
+
+#ifndef BMAC_DUP_TO_REMOVE
+#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */
+
+#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */
+
+#endif /* BMAC_DUP_TO_REMOVE */
+
+#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \
+ ((direction == DMA_TX) ? \
+ (void *)(uintptr)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \
+ (void *)(uintptr)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \
+ ((direction == DMA_TX) ? \
+ (void *)(uintptr)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \
+ (void *)(uintptr)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv)))
+
+/*
+ * The following table lists the buffer memory allocated to xmt fifos in HW.
+ * the size is in units of 256bytes(one block), total size is HW dependent
+ * ucode has default fifo partition, sw can overwrite if necessary
+ *
+ * This is documented in twiki under the topic UcodeTxFifo. Please ensure
+ * the twiki is updated before making changes.
+ */
+
+#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */
+
+static uint16 xmtfifo_sz[][NFIFO] = {
+ {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
+ {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
+ {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
+ {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
+ {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
+};
+
+static void wlc_clkctl_clk(wlc_hw_info_t *wlc, uint mode);
+static void wlc_coreinit(wlc_info_t *wlc);
+
+/* used by wlc_wakeucode_init() */
+static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits);
+static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const uint32 ucode[],
+ const uint nbytes);
+static void wlc_ucode_download(wlc_hw_info_t *wlc);
+static void wlc_ucode_txant_set(wlc_hw_info_t *wlc_hw);
+
+/* used by wlc_dpc() */
+static bool wlc_bmac_dotxstatus(wlc_hw_info_t *wlc, tx_status_t *txs,
+ uint32 s2);
+static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc);
+static bool wlc_bmac_txstatus(wlc_hw_info_t *wlc, bool bound, bool *fatal);
+static bool wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound);
+
+/* used by wlc_down() */
+static void wlc_flushqueues(wlc_info_t *wlc);
+
+static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, uint16 *mhfs);
+static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw);
+static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw);
+
+/* Low Level Prototypes */
+static uint16 wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset,
+ uint32 sel);
+static void wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, uint16 v,
+ uint32 sel);
+static bool wlc_bmac_attach_dmapio(wlc_info_t *wlc, uint j, bool wme);
+static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw);
+static void wlc_ucode_bsinit(wlc_hw_info_t *wlc_hw);
+static bool wlc_validboardtype(wlc_hw_info_t *wlc);
+static bool wlc_isgoodchip(wlc_hw_info_t *wlc_hw);
+static char *wlc_get_macaddr(wlc_hw_info_t *wlc_hw);
+static void wlc_mhfdef(wlc_info_t *wlc, uint16 *mhfs, uint16 mhf2_init);
+static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw);
+static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw);
+static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw);
+static uint32 wlc_wlintrsoff(wlc_info_t *wlc);
+static void wlc_wlintrsrestore(wlc_info_t *wlc, uint32 macintmask);
+static void wlc_gpio_init(wlc_info_t *wlc);
+static void wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn,
+ int len);
+static void wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn,
+ int len);
+static void wlc_bmac_bsinit(wlc_info_t *wlc, chanspec_t chanspec);
+static uint32 wlc_setband_inact(wlc_info_t *wlc, uint bandunit);
+static void wlc_bmac_setband(wlc_hw_info_t *wlc_hw, uint bandunit,
+ chanspec_t chanspec);
+static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot);
+static void wlc_upd_ofdm_pctl1_table(wlc_hw_info_t *wlc_hw);
+static uint16 wlc_bmac_ofdm_ratetable_offset(wlc_hw_info_t *wlc_hw,
+ uint8 rate);
+
+/* === Low Level functions === */
+
+void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot)
+{
+ wlc_hw->shortslot = shortslot;
+
+ if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) {
+ wlc_suspend_mac_and_wait(wlc_hw->wlc);
+ wlc_bmac_update_slot_timing(wlc_hw, shortslot);
+ wlc_enable_mac(wlc_hw->wlc);
+ }
+}
+
+/*
+ * Update the slot timing for standard 11b/g (20us slots)
+ * or shortslot 11g (9us slots)
+ * The PSM needs to be suspended for this call.
+ */
+static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot)
+{
+ osl_t *osh;
+ d11regs_t *regs;
+
+ osh = wlc_hw->osh;
+ regs = wlc_hw->regs;
+
+ if (shortslot) {
+ /* 11g short slot: 11a timing */
+ W_REG(osh, &regs->ifs_slot, 0x0207); /* APHY_SLOT_TIME */
+ wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
+ } else {
+ /* 11g long slot: 11b timing */
+ W_REG(osh, &regs->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */
+ wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
+ }
+}
+
+static void WLBANDINITFN(wlc_ucode_bsinit) (wlc_hw_info_t *wlc_hw)
+{
+ /* init microcode host flags */
+ wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs);
+
+ /* do band-specific ucode IHR, SHM, and SCR inits */
+ if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (WLCISNPHY(wlc_hw->band)) {
+ wlc_write_inits(wlc_hw, d11n0bsinitvals16);
+ } else {
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ }
+ } else {
+ if (D11REV_IS(wlc_hw->corerev, 24)) {
+ if (WLCISLCNPHY(wlc_hw->band)) {
+ wlc_write_inits(wlc_hw, d11lcn0bsinitvals24);
+ } else
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev));
+ } else {
+ WL_ERROR(("%s: wl%d: unsupported corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ }
+ }
+}
+
+/* switch to new band but leave it inactive */
+static uint32 WLBANDINITFN(wlc_setband_inact) (wlc_info_t *wlc, uint bandunit)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ uint32 macintmask;
+ uint32 tmp;
+
+ WL_TRACE(("wl%d: wlc_setband_inact\n", wlc_hw->unit));
+
+ ASSERT(bandunit != wlc_hw->band->bandunit);
+ ASSERT(si_iscoreup(wlc_hw->sih));
+ ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) ==
+ 0);
+
+ /* disable interrupts */
+ macintmask = wl_intrsoff(wlc->wl);
+
+ /* radio off */
+ wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+
+ ASSERT(wlc_hw->clk);
+
+ if (D11REV_LT(wlc_hw->corerev, 17))
+ tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol);
+
+ wlc_bmac_core_phy_clk(wlc_hw, OFF);
+
+ wlc_setxband(wlc_hw, bandunit);
+
+ return macintmask;
+}
+
+/* Process received frames */
+/*
+ * Return TRUE if more frames need to be processed. FALSE otherwise.
+ * Param 'bound' indicates max. # frames to process before break out.
+ */
+static bool BCMFASTPATH
+wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound)
+{
+ void *p;
+ void *head = NULL;
+ void *tail = NULL;
+ uint n = 0;
+ uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
+ uint32 tsf_h, tsf_l;
+ wlc_d11rxhdr_t *wlc_rxhdr = NULL;
+
+ WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__));
+ /* gather received frames */
+ while ((p = dma_rx(wlc_hw->di[fifo]))) {
+
+ if (!tail)
+ head = tail = p;
+ else {
+ PKTSETLINK(tail, p);
+ tail = p;
+ }
+
+ /* !give others some time to run! */
+ if (++n >= bound_limit)
+ break;
+ }
+
+ /* get the TSF REG reading */
+ wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h);
+
+ /* post more rbufs */
+ dma_rxfill(wlc_hw->di[fifo]);
+
+ /* process each frame */
+ while ((p = head) != NULL) {
+ head = PKTLINK(head);
+ PKTSETLINK(p, NULL);
+
+ /* record the tsf_l in wlc_rxd11hdr */
+ wlc_rxhdr = (wlc_d11rxhdr_t *) PKTDATA(p);
+ wlc_rxhdr->tsf_l = htol32(tsf_l);
+
+ /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
+ wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
+
+ wlc_recv(wlc_hw->wlc, p);
+ }
+
+ return n >= bound_limit;
+}
+
+/* second-level interrupt processing
+ * Return TRUE if another dpc needs to be re-scheduled. FALSE otherwise.
+ * Param 'bounded' indicates if applicable loops should be bounded.
+ */
+bool BCMFASTPATH wlc_dpc(wlc_info_t *wlc, bool bounded)
+{
+ uint32 macintstatus;
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs = wlc_hw->regs;
+ bool fatal = FALSE;
+
+ if (DEVICEREMOVED(wlc)) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__));
+ wl_down(wlc->wl);
+ return FALSE;
+ }
+
+ /* grab and clear the saved software intstatus bits */
+ macintstatus = wlc->macintstatus;
+ wlc->macintstatus = 0;
+
+ WL_TRACE(("wl%d: wlc_dpc: macintstatus 0x%x\n", wlc_hw->unit,
+ macintstatus));
+
+ if (macintstatus & MI_PRQ) {
+ /* Process probe request FIFO */
+ ASSERT(0 && "PRQ Interrupt in non-MBSS");
+ }
+
+ /* BCN template is available */
+ /* ZZZ: Use AP_ACTIVE ? */
+ if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated)
+ && (macintstatus & MI_BCNTPL)) {
+ wlc_update_beacon(wlc);
+ }
+
+ /* PMQ entry addition */
+ if (macintstatus & MI_PMQ) {
+ }
+
+ /* tx status */
+ if (macintstatus & MI_TFS) {
+ if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal))
+ wlc->macintstatus |= MI_TFS;
+ if (fatal) {
+ WL_ERROR(("MI_TFS: fatal\n"));
+ goto fatal;
+ }
+ }
+
+ if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
+ wlc_tbtt(wlc, regs);
+
+ /* ATIM window end */
+ if (macintstatus & MI_ATIMWINEND) {
+ WL_TRACE(("wlc_isr: end of ATIM window\n"));
+
+ OR_REG(wlc_hw->osh, &regs->maccommand, wlc->qvalid);
+ wlc->qvalid = 0;
+ }
+
+ /* phy tx error */
+ if (macintstatus & MI_PHYTXERR) {
+ WLCNTINCR(wlc->pub->_cnt->txphyerr);
+ }
+
+ /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
+ if (macintstatus & MI_DMAINT) {
+ if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) {
+ wlc->macintstatus |= MI_DMAINT;
+ }
+ }
+
+ /* TX FIFO suspend/flush completion */
+ if (macintstatus & MI_TXSTOP) {
+ if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) {
+ /* WL_ERROR(("dpc: fifo_suspend_comlete\n")); */
+ }
+ }
+
+ /* noise sample collected */
+ if (macintstatus & MI_BG_NOISE) {
+ wlc_phy_noise_sample_intr(wlc_hw->band->pi);
+ }
+
+ if (macintstatus & MI_GP0) {
+ WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now));
+
+ printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
+ __func__, CHIPID(wlc_hw->sih->chip),
+ CHIPREV(wlc_hw->sih->chiprev));
+
+ WLCNTINCR(wlc->pub->_cnt->psmwds);
+
+ /* big hammer */
+ wl_init(wlc->wl);
+ }
+
+ /* gptimer timeout */
+ if (macintstatus & MI_TO) {
+ W_REG(wlc_hw->osh, &regs->gptimer, 0);
+ }
+
+ if (macintstatus & MI_RFDISABLE) {
+#if defined(BCMDBG)
+ uint32 rfd = R_REG(wlc_hw->osh, &regs->phydebug) & PDBG_RFD;
+#endif
+
+ WL_ERROR(("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", wlc_hw->unit, rfd));
+
+ WLCNTINCR(wlc->pub->_cnt->rfdisable);
+ }
+
+ /* send any enq'd tx packets. Just makes sure to jump start tx */
+ if (!pktq_empty(&wlc->active_queue->q))
+ wlc_send_q(wlc, wlc->active_queue);
+
+ ASSERT(wlc_ps_check(wlc));
+
+ /* make sure the bound indication and the implementation are in sync */
+ ASSERT(bounded == TRUE || wlc->macintstatus == 0);
+
+ /* it isn't done and needs to be resched if macintstatus is non-zero */
+ return wlc->macintstatus != 0;
+
+ fatal:
+ wl_init(wlc->wl);
+ return wlc->macintstatus != 0;
+}
+
+/* common low-level watchdog code */
+void wlc_bmac_watchdog(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+
+ WL_TRACE(("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit));
+
+ if (!wlc_hw->up)
+ return;
+
+ /* increment second count */
+ wlc_hw->now++;
+
+ /* Check for FIFO error interrupts */
+ wlc_bmac_fifoerrors(wlc_hw);
+
+ /* make sure RX dma has buffers */
+ dma_rxfill(wlc->hw->di[RX_FIFO]);
+ if (D11REV_IS(wlc_hw->corerev, 4)) {
+ dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]);
+ }
+
+ wlc_phy_watchdog(wlc_hw->band->pi);
+}
+
+void
+wlc_bmac_set_chanspec(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, bool mute,
+ struct txpwr_limits *txpwr)
+{
+ uint bandunit;
+
+ WL_TRACE(("wl%d: wlc_bmac_set_chanspec 0x%x\n", wlc_hw->unit,
+ chanspec));
+
+ wlc_hw->chanspec = chanspec;
+
+ /* Switch bands if necessary */
+ if (NBANDS_HW(wlc_hw) > 1) {
+ bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+ if (wlc_hw->band->bandunit != bandunit) {
+ /* wlc_bmac_setband disables other bandunit,
+ * use light band switch if not up yet
+ */
+ if (wlc_hw->up) {
+ wlc_phy_chanspec_radio_set(wlc_hw->
+ bandstate[bandunit]->
+ pi, chanspec);
+ wlc_bmac_setband(wlc_hw, bandunit, chanspec);
+ } else {
+ wlc_setxband(wlc_hw, bandunit);
+ }
+ }
+ }
+
+ wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
+
+ if (!wlc_hw->up) {
+ if (wlc_hw->clk)
+ wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
+ chanspec);
+ wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+ } else {
+ wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
+ wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
+
+ /* Update muting of the channel */
+ wlc_bmac_mute(wlc_hw, mute, 0);
+ }
+}
+
+int wlc_bmac_revinfo_get(wlc_hw_info_t *wlc_hw, wlc_bmac_revinfo_t *revinfo)
+{
+ si_t *sih = wlc_hw->sih;
+ uint idx;
+
+ revinfo->vendorid = wlc_hw->vendorid;
+ revinfo->deviceid = wlc_hw->deviceid;
+
+ revinfo->boardrev = wlc_hw->boardrev;
+ revinfo->corerev = wlc_hw->corerev;
+ revinfo->sromrev = wlc_hw->sromrev;
+ revinfo->chiprev = sih->chiprev;
+ revinfo->chip = sih->chip;
+ revinfo->chippkg = sih->chippkg;
+ revinfo->boardtype = sih->boardtype;
+ revinfo->boardvendor = sih->boardvendor;
+ revinfo->bustype = sih->bustype;
+ revinfo->buscoretype = sih->buscoretype;
+ revinfo->buscorerev = sih->buscorerev;
+ revinfo->issim = sih->issim;
+
+ revinfo->nbands = NBANDS_HW(wlc_hw);
+
+ for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) {
+ wlc_hwband_t *band = wlc_hw->bandstate[idx];
+ revinfo->band[idx].bandunit = band->bandunit;
+ revinfo->band[idx].bandtype = band->bandtype;
+ revinfo->band[idx].phytype = band->phytype;
+ revinfo->band[idx].phyrev = band->phyrev;
+ revinfo->band[idx].radioid = band->radioid;
+ revinfo->band[idx].radiorev = band->radiorev;
+ revinfo->band[idx].abgphy_encore = band->abgphy_encore;
+ revinfo->band[idx].anarev = 0;
+
+ }
+ return 0;
+}
+
+int wlc_bmac_state_get(wlc_hw_info_t *wlc_hw, wlc_bmac_state_t *state)
+{
+ state->machwcap = wlc_hw->machwcap;
+
+ return 0;
+}
+
+static bool
+BCMATTACHFN(wlc_bmac_attach_dmapio) (wlc_info_t *wlc, uint j, bool wme)
+{
+ uint i;
+ char name[8];
+ /* ucode host flag 2 needed for pio mode, independent of band and fifo */
+ uint16 pio_mhf2 = 0;
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ uint unit = wlc_hw->unit;
+ wlc_tunables_t *tune = wlc->pub->tunables;
+
+ /* name and offsets for dma_attach */
+ snprintf(name, sizeof(name), "wl%d", unit);
+
+ if (wlc_hw->di[0] == 0) { /* Init FIFOs */
+ uint addrwidth;
+ int dma_attach_err = 0;
+ osl_t *osh = wlc_hw->osh;
+
+ /* Find out the DMA addressing capability and let OS know
+ * All the channels within one DMA core have 'common-minimum' same
+ * capability
+ */
+ addrwidth =
+ dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0));
+ OSL_DMADDRWIDTH(osh, addrwidth);
+
+ if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) {
+ WL_ERROR(("wl%d: wlc_attach: alloc_dma_resources failed\n", unit));
+ return FALSE;
+ }
+
+ /*
+ * FIFO 0
+ * TX: TX_AC_BK_FIFO (TX AC Background data packets)
+ * RX: RX_FIFO (RX data packets)
+ */
+ ASSERT(TX_AC_BK_FIFO == 0);
+ ASSERT(RX_FIFO == 0);
+ wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih,
+ (wme ? DMAREG(wlc_hw, DMA_TX, 0) :
+ NULL), DMAREG(wlc_hw, DMA_RX, 0),
+ (wme ? tune->ntxd : 0), tune->nrxd,
+ tune->rxbufsz, -1, tune->nrxbufpost,
+ WL_HWRXOFF, &wl_msg_level);
+ dma_attach_err |= (NULL == wlc_hw->di[0]);
+
+ /*
+ * FIFO 1
+ * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
+ * (legacy) TX_DATA_FIFO (TX data packets)
+ * RX: UNUSED
+ */
+ ASSERT(TX_AC_BE_FIFO == 1);
+ ASSERT(TX_DATA_FIFO == 1);
+ wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih,
+ DMAREG(wlc_hw, DMA_TX, 1), NULL,
+ tune->ntxd, 0, 0, -1, 0, 0,
+ &wl_msg_level);
+ dma_attach_err |= (NULL == wlc_hw->di[1]);
+
+ /*
+ * FIFO 2
+ * TX: TX_AC_VI_FIFO (TX AC Video data packets)
+ * RX: UNUSED
+ */
+ ASSERT(TX_AC_VI_FIFO == 2);
+ wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih,
+ DMAREG(wlc_hw, DMA_TX, 2), NULL,
+ tune->ntxd, 0, 0, -1, 0, 0,
+ &wl_msg_level);
+ dma_attach_err |= (NULL == wlc_hw->di[2]);
+ /*
+ * FIFO 3
+ * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
+ * (legacy) TX_CTL_FIFO (TX control & mgmt packets)
+ * RX: RX_TXSTATUS_FIFO (transmit-status packets)
+ * for corerev < 5 only
+ */
+ ASSERT(TX_AC_VO_FIFO == 3);
+ ASSERT(TX_CTL_FIFO == 3);
+ if (D11REV_IS(wlc_hw->corerev, 4)) {
+ ASSERT(RX_TXSTATUS_FIFO == 3);
+ wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih,
+ DMAREG(wlc_hw, DMA_TX, 3),
+ DMAREG(wlc_hw, DMA_RX, 3),
+ tune->ntxd, tune->nrxd,
+ sizeof(tx_status_t), -1,
+ tune->nrxbufpost, 0,
+ &wl_msg_level);
+ dma_attach_err |= (NULL == wlc_hw->di[3]);
+ } else {
+ wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih,
+ DMAREG(wlc_hw, DMA_TX, 3),
+ NULL, tune->ntxd, 0, 0, -1,
+ 0, 0, &wl_msg_level);
+ dma_attach_err |= (NULL == wlc_hw->di[3]);
+ }
+/* Cleaner to leave this as if with AP defined */
+
+ if (dma_attach_err) {
+ WL_ERROR(("wl%d: wlc_attach: dma_attach failed\n",
+ unit));
+ return FALSE;
+ }
+
+ /* get pointer to dma engine tx flow control variable */
+ for (i = 0; i < NFIFO; i++)
+ if (wlc_hw->di[i])
+ wlc_hw->txavail[i] =
+ (uint *) dma_getvar(wlc_hw->di[i],
+ "&txavail");
+ }
+
+ /* initial ucode host flags */
+ wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
+
+ return TRUE;
+}
+
+static void BCMATTACHFN(wlc_bmac_detach_dmapio) (wlc_hw_info_t *wlc_hw)
+{
+ uint j;
+
+ for (j = 0; j < NFIFO; j++) {
+ if (wlc_hw->di[j]) {
+ dma_detach(wlc_hw->di[j]);
+ wlc_hw->di[j] = NULL;
+ }
+ }
+}
+
+/* low level attach
+ * run backplane attach, init nvram
+ * run phy attach
+ * initialize software state for each core and band
+ * put the whole chip in reset(driver down state), no clock
+ */
+
+int
+BCMATTACHFN(wlc_bmac_attach) (wlc_info_t *wlc, uint16 vendor, uint16 device,
+ uint unit, bool piomode, osl_t *osh,
+ void *regsva, uint bustype, void *btparam) {
+ wlc_hw_info_t *wlc_hw;
+ d11regs_t *regs;
+ char *macaddr = NULL;
+ char *vars;
+ uint err = 0;
+ uint j;
+ bool wme = FALSE;
+ shared_phy_params_t sha_params;
+
+ WL_TRACE(("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", unit,
+ vendor, device));
+
+ ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF);
+
+ wme = TRUE;
+
+ wlc_hw = wlc->hw;
+ wlc_hw->wlc = wlc;
+ wlc_hw->unit = unit;
+ wlc_hw->osh = osh;
+ wlc_hw->band = wlc_hw->bandstate[0];
+ wlc_hw->_piomode = piomode;
+
+ /* populate wlc_hw_info_t with default values */
+ wlc_bmac_info_init(wlc_hw);
+
+ /*
+ * Do the hardware portion of the attach.
+ * Also initialize software state that depends on the particular hardware
+ * we are running.
+ */
+ wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam,
+ &wlc_hw->vars, &wlc_hw->vars_size);
+ if (wlc_hw->sih == NULL) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: si_attach failed\n", unit));
+ err = 11;
+ goto fail;
+ }
+ vars = wlc_hw->vars;
+
+ /*
+ * Get vendid/devid nvram overwrites, which could be different
+ * than those the BIOS recognizes for devices on PCMCIA_BUS,
+ * SDIO_BUS, and SROMless devices on PCI_BUS.
+ */
+#ifdef BCMBUSTYPE
+ bustype = BCMBUSTYPE;
+#endif
+ if (bustype != SI_BUS) {
+ char *var;
+
+ var = getvar(vars, "vendid");
+ if (var) {
+ vendor = (uint16) bcm_strtoul(var, NULL, 0);
+ WL_ERROR(("Overriding vendor id = 0x%x\n", vendor));
+ }
+ var = getvar(vars, "devid");
+ if (var) {
+ uint16 devid = (uint16) bcm_strtoul(var, NULL, 0);
+ if (devid != 0xffff) {
+ device = devid;
+ WL_ERROR(("Overriding device id = 0x%x\n",
+ device));
+ }
+ }
+
+ /* verify again the device is supported */
+ if (!wlc_chipmatch(vendor, device)) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", unit, vendor, device));
+ err = 12;
+ goto fail;
+ }
+ }
+
+ wlc_hw->vendorid = vendor;
+ wlc_hw->deviceid = device;
+
+ /* set bar0 window to point at D11 core */
+ wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0);
+ wlc_hw->corerev = si_corerev(wlc_hw->sih);
+
+ regs = wlc_hw->regs;
+
+ wlc->regs = wlc_hw->regs;
+
+ /* validate chip, chiprev and corerev */
+ if (!wlc_isgoodchip(wlc_hw)) {
+ err = 13;
+ goto fail;
+ }
+
+ /* initialize power control registers */
+ si_clkctl_init(wlc_hw->sih);
+
+ /* request fastclock and force fastclock for the rest of attach
+ * bring the d11 core out of reset.
+ * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still FALSE;
+ * But it will be called again inside wlc_corereset, after d11 is out of reset.
+ */
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+ wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+
+ if (!wlc_bmac_validate_chip_access(wlc_hw)) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: validate_chip_access failed\n", unit));
+ err = 14;
+ goto fail;
+ }
+
+ /* get the board rev, used just below */
+ j = getintvar(vars, "boardrev");
+ /* promote srom boardrev of 0xFF to 1 */
+ if (j == BOARDREV_PROMOTABLE)
+ j = BOARDREV_PROMOTED;
+ wlc_hw->boardrev = (uint16) j;
+ if (!wlc_validboardtype(wlc_hw)) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", unit, wlc_hw->sih->boardtype, wlc_hw->boardrev));
+ err = 15;
+ goto fail;
+ }
+ wlc_hw->sromrev = (uint8) getintvar(vars, "sromrev");
+ wlc_hw->boardflags = (uint32) getintvar(vars, "boardflags");
+ wlc_hw->boardflags2 = (uint32) getintvar(vars, "boardflags2");
+
+ if (D11REV_LE(wlc_hw->corerev, 4)
+ || (wlc_hw->boardflags & BFL_NOPLLDOWN))
+ wlc_bmac_pllreq(wlc_hw, TRUE, WLC_PLLREQ_SHARED);
+
+ if ((BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ && (si_pci_war16165(wlc_hw->sih)))
+ wlc->war16165 = TRUE;
+
+ /* check device id(srom, nvram etc.) to set bands */
+ if (wlc_hw->deviceid == BCM43224_D11N_ID) {
+ /* Dualband boards */
+ wlc_hw->_nbands = 2;
+ } else
+ wlc_hw->_nbands = 1;
+
+ if ((CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID))
+ wlc_hw->_nbands = 1;
+
+ /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the
+ * init of these values
+ */
+ wlc->vendorid = wlc_hw->vendorid;
+ wlc->deviceid = wlc_hw->deviceid;
+ wlc->pub->sih = wlc_hw->sih;
+ wlc->pub->corerev = wlc_hw->corerev;
+ wlc->pub->sromrev = wlc_hw->sromrev;
+ wlc->pub->boardrev = wlc_hw->boardrev;
+ wlc->pub->boardflags = wlc_hw->boardflags;
+ wlc->pub->boardflags2 = wlc_hw->boardflags2;
+ wlc->pub->_nbands = wlc_hw->_nbands;
+
+ wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
+
+ if (wlc_hw->physhim == NULL) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n",
+ unit));
+ err = 25;
+ goto fail;
+ }
+
+ /* pass all the parameters to wlc_phy_shared_attach in one struct */
+ sha_params.osh = osh;
+ sha_params.sih = wlc_hw->sih;
+ sha_params.physhim = wlc_hw->physhim;
+ sha_params.unit = unit;
+ sha_params.corerev = wlc_hw->corerev;
+ sha_params.vars = vars;
+ sha_params.vid = wlc_hw->vendorid;
+ sha_params.did = wlc_hw->deviceid;
+ sha_params.chip = wlc_hw->sih->chip;
+ sha_params.chiprev = wlc_hw->sih->chiprev;
+ sha_params.chippkg = wlc_hw->sih->chippkg;
+ sha_params.sromrev = wlc_hw->sromrev;
+ sha_params.boardtype = wlc_hw->sih->boardtype;
+ sha_params.boardrev = wlc_hw->boardrev;
+ sha_params.boardvendor = wlc_hw->sih->boardvendor;
+ sha_params.boardflags = wlc_hw->boardflags;
+ sha_params.boardflags2 = wlc_hw->boardflags2;
+ sha_params.bustype = wlc_hw->sih->bustype;
+ sha_params.buscorerev = wlc_hw->sih->buscorerev;
+
+ /* alloc and save pointer to shared phy state area */
+ wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
+ if (!wlc_hw->phy_sh) {
+ err = 16;
+ goto fail;
+ }
+
+ /* initialize software state for each core and band */
+ for (j = 0; j < NBANDS_HW(wlc_hw); j++) {
+ /*
+ * band0 is always 2.4Ghz
+ * band1, if present, is 5Ghz
+ */
+
+ /* So if this is a single band 11a card, use band 1 */
+ if (IS_SINGLEBAND_5G(wlc_hw->deviceid))
+ j = BAND_5G_INDEX;
+
+ wlc_setxband(wlc_hw, j);
+
+ wlc_hw->band->bandunit = j;
+ wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+ wlc->band->bandunit = j;
+ wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+ wlc->core->coreidx = si_coreidx(wlc_hw->sih);
+
+ if (D11REV_GE(wlc_hw->corerev, 13)) {
+ wlc_hw->machwcap = R_REG(wlc_hw->osh, &regs->machwcap);
+ wlc_hw->machwcap_backup = wlc_hw->machwcap;
+ }
+
+ /* init tx fifo size */
+ ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) <
+ ARRAYSIZE(xmtfifo_sz));
+ wlc_hw->xmtfifo_sz =
+ xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
+
+ /* Get a phy for this band */
+ wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh,
+ (void *)(uintptr) regs, wlc_hw->band->bandtype, vars);
+ if (wlc_hw->band->pi == NULL) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", unit));
+ err = 17;
+ goto fail;
+ }
+
+ wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
+
+ wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
+ &wlc_hw->band->phyrev,
+ &wlc_hw->band->radioid,
+ &wlc_hw->band->radiorev);
+ wlc_hw->band->abgphy_encore =
+ wlc_phy_get_encore(wlc_hw->band->pi);
+ wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
+ wlc_hw->band->core_flags =
+ wlc_phy_get_coreflags(wlc_hw->band->pi);
+
+ /* verify good phy_type & supported phy revision */
+ if (WLCISNPHY(wlc_hw->band)) {
+ if (NCONF_HAS(wlc_hw->band->phyrev))
+ goto good_phy;
+ else
+ goto bad_phy;
+ } else if (WLCISLCNPHY(wlc_hw->band)) {
+ if (LCNCONF_HAS(wlc_hw->band->phyrev))
+ goto good_phy;
+ else
+ goto bad_phy;
+ } else {
+ bad_phy:
+ WL_ERROR(("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", unit, wlc_hw->band->phytype, wlc_hw->band->phyrev));
+ err = 18;
+ goto fail;
+ }
+
+ good_phy:
+ /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the
+ * high level attach. However we can not make that change until all low level access
+ * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping
+ * wlc_hw->band->pi as well for incremental update of low level fns, and cut over
+ * low only init when all fns updated.
+ */
+ wlc->band->pi = wlc_hw->band->pi;
+ wlc->band->phytype = wlc_hw->band->phytype;
+ wlc->band->phyrev = wlc_hw->band->phyrev;
+ wlc->band->radioid = wlc_hw->band->radioid;
+ wlc->band->radiorev = wlc_hw->band->radiorev;
+
+ /* default contention windows size limits */
+ wlc_hw->band->CWmin = APHY_CWMIN;
+ wlc_hw->band->CWmax = PHY_CWMAX;
+
+ if (!wlc_bmac_attach_dmapio(wlc, j, wme)) {
+ err = 19;
+ goto fail;
+ }
+ }
+
+ /* disable core to match driver "down" state */
+ wlc_coredisable(wlc_hw);
+
+ /* Match driver "down" state */
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_down(wlc_hw->sih);
+
+ /* register sb interrupt callback functions */
+ si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff,
+ (void *)wlc_wlintrsrestore, NULL, wlc);
+
+ /* turn off pll and xtal to match driver "down" state */
+ wlc_bmac_xtal(wlc_hw, OFF);
+
+ /* *********************************************************************
+ * The hardware is in the DOWN state at this point. D11 core
+ * or cores are in reset with clocks off, and the board PLLs
+ * are off if possible.
+ *
+ * Beyond this point, wlc->sbclk == FALSE and chip registers
+ * should not be touched.
+ *********************************************************************
+ */
+
+ /* init etheraddr state variables */
+ macaddr = wlc_get_macaddr(wlc_hw);
+ if (macaddr == NULL) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: macaddr not found\n", unit));
+ err = 21;
+ goto fail;
+ }
+ bcm_ether_atoe(macaddr, &wlc_hw->etheraddr);
+ if (ETHER_ISBCAST((char *)&wlc_hw->etheraddr) ||
+ ETHER_ISNULLADDR((char *)&wlc_hw->etheraddr)) {
+ WL_ERROR(("wl%d: wlc_bmac_attach: bad macaddr %s\n", unit,
+ macaddr));
+ err = 22;
+ goto fail;
+ }
+
+ WL_ERROR(("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
+ __func__, wlc_hw->deviceid, wlc_hw->_nbands,
+ wlc_hw->sih->boardtype, macaddr));
+
+ return err;
+
+ fail:
+ WL_ERROR(("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err));
+ return err;
+}
+
+/*
+ * Initialize wlc_info default values ...
+ * may get overrides later in this function
+ * BMAC_NOTES, move low out and resolve the dangling ones
+ */
+void BCMATTACHFN(wlc_bmac_info_init) (wlc_hw_info_t *wlc_hw)
+{
+ wlc_info_t *wlc = wlc_hw->wlc;
+
+ /* set default sw macintmask value */
+ wlc->defmacintmask = DEF_MACINTMASK;
+
+ /* various 802.11g modes */
+ wlc_hw->shortslot = FALSE;
+
+ wlc_hw->SFBL = RETRY_SHORT_FB;
+ wlc_hw->LFBL = RETRY_LONG_FB;
+
+ /* default mac retry limits */
+ wlc_hw->SRL = RETRY_SHORT_DEF;
+ wlc_hw->LRL = RETRY_LONG_DEF;
+ wlc_hw->chanspec = CH20MHZ_CHSPEC(1);
+}
+
+/*
+ * low level detach
+ */
+int BCMATTACHFN(wlc_bmac_detach) (wlc_info_t *wlc)
+{
+ uint i;
+ wlc_hwband_t *band;
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ int callbacks;
+
+ callbacks = 0;
+
+ if (wlc_hw->sih) {
+ /* detach interrupt sync mechanism since interrupt is disabled and per-port
+ * interrupt object may has been freed. this must be done before sb core switch
+ */
+ si_deregister_intr_callback(wlc_hw->sih);
+
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_sleep(wlc_hw->sih);
+ }
+
+ wlc_bmac_detach_dmapio(wlc_hw);
+
+ band = wlc_hw->band;
+ for (i = 0; i < NBANDS_HW(wlc_hw); i++) {
+ if (band->pi) {
+ /* Detach this band's phy */
+ wlc_phy_detach(band->pi);
+ band->pi = NULL;
+ }
+ band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
+ }
+
+ /* Free shared phy state */
+ wlc_phy_shared_detach(wlc_hw->phy_sh);
+
+ wlc_phy_shim_detach(wlc_hw->physhim);
+
+ /* free vars */
+ if (wlc_hw->vars) {
+ MFREE(wlc_hw->osh, wlc_hw->vars, wlc_hw->vars_size);
+ wlc_hw->vars = NULL;
+ }
+
+ if (wlc_hw->sih) {
+ si_detach(wlc_hw->sih);
+ wlc_hw->sih = NULL;
+ }
+
+ return callbacks;
+
+}
+
+void BCMINITFN(wlc_bmac_reset) (wlc_hw_info_t *wlc_hw)
+{
+ WL_TRACE(("wl%d: wlc_bmac_reset\n", wlc_hw->unit));
+
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset);
+
+ /* reset the core */
+ if (!DEVICEREMOVED(wlc_hw->wlc))
+ wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+
+ /* purge the dma rings */
+ wlc_flushqueues(wlc_hw->wlc);
+
+ wlc_reset_bmac_done(wlc_hw->wlc);
+}
+
+void
+BCMINITFN(wlc_bmac_init) (wlc_hw_info_t *wlc_hw, chanspec_t chanspec,
+ bool mute) {
+ uint32 macintmask;
+ bool fastclk;
+ wlc_info_t *wlc = wlc_hw->wlc;
+
+ WL_TRACE(("wl%d: wlc_bmac_init\n", wlc_hw->unit));
+
+ /* request FAST clock if not on */
+ fastclk = wlc_hw->forcefastclk;
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ /* disable interrupts */
+ macintmask = wl_intrsoff(wlc->wl);
+
+ /* set up the specified band and chanspec */
+ wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec));
+ wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+
+ /* do one-time phy inits and calibration */
+ wlc_phy_cal_init(wlc_hw->band->pi);
+
+ /* core-specific initialization */
+ wlc_coreinit(wlc);
+
+ /* suspend the tx fifos and mute the phy for preism cac time */
+ if (mute)
+ wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
+
+ /* band-specific inits */
+ wlc_bmac_bsinit(wlc, chanspec);
+
+ /* restore macintmask */
+ wl_intrsrestore(wlc->wl, macintmask);
+
+ /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended
+ * and wlc_enable_mac() will clear this override bit.
+ */
+ mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND);
+
+ /*
+ * initialize mac_suspend_depth to 1 to match ucode initial suspended state
+ */
+ wlc_hw->mac_suspend_depth = 1;
+
+ /* restore the clk */
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+}
+
+int BCMINITFN(wlc_bmac_up_prep) (wlc_hw_info_t *wlc_hw)
+{
+ uint coremask;
+
+ WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__));
+
+ ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0);
+
+ /*
+ * Enable pll and xtal, initialize the power control registers,
+ * and force fastclock for the remainder of wlc_up().
+ */
+ wlc_bmac_xtal(wlc_hw, ON);
+ si_clkctl_init(wlc_hw->sih);
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ /*
+ * Configure pci/pcmcia here instead of in wlc_attach()
+ * to allow mfg hotswap: down, hotswap (chip power cycle), up.
+ */
+ coremask = (1 << wlc_hw->wlc->core->coreidx);
+
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_setup(wlc_hw->sih, coremask);
+
+ ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID);
+
+ /*
+ * Need to read the hwradio status here to cover the case where the system
+ * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+ */
+ if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) {
+ /* put SB PCI in down state again */
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_down(wlc_hw->sih);
+ wlc_bmac_xtal(wlc_hw, OFF);
+ return BCME_RADIOOFF;
+ }
+
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_up(wlc_hw->sih);
+
+ /* reset the d11 core */
+ wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+
+ return 0;
+}
+
+int BCMINITFN(wlc_bmac_up_finish) (wlc_hw_info_t *wlc_hw)
+{
+ WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__));
+
+ wlc_hw->up = TRUE;
+ wlc_phy_hw_state_upd(wlc_hw->band->pi, TRUE);
+
+ /* FULLY enable dynamic power control and d11 core interrupt */
+ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+ ASSERT(wlc_hw->wlc->macintmask == 0);
+ wl_intrson(wlc_hw->wlc->wl);
+ return 0;
+}
+
+int BCMUNINITFN(wlc_bmac_down_prep) (wlc_hw_info_t *wlc_hw)
+{
+ bool dev_gone;
+ uint callbacks = 0;
+
+ WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__));
+
+ if (!wlc_hw->up)
+ return callbacks;
+
+ dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+
+ /* disable interrupts */
+ if (dev_gone)
+ wlc_hw->wlc->macintmask = 0;
+ else {
+ /* now disable interrupts */
+ wl_intrsoff(wlc_hw->wlc->wl);
+
+ /* ensure we're running on the pll clock again */
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+ }
+ /* down phy at the last of this stage */
+ callbacks += wlc_phy_down(wlc_hw->band->pi);
+
+ return callbacks;
+}
+
+int BCMUNINITFN(wlc_bmac_down_finish) (wlc_hw_info_t *wlc_hw)
+{
+ uint callbacks = 0;
+ bool dev_gone;
+
+ WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__));
+
+ if (!wlc_hw->up)
+ return callbacks;
+
+ wlc_hw->up = FALSE;
+ wlc_phy_hw_state_upd(wlc_hw->band->pi, FALSE);
+
+ dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+
+ if (dev_gone) {
+ wlc_hw->sbclk = FALSE;
+ wlc_hw->clk = FALSE;
+ wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, FALSE);
+
+ /* reclaim any posted packets */
+ wlc_flushqueues(wlc_hw->wlc);
+ } else {
+
+ /* Reset and disable the core */
+ if (si_iscoreup(wlc_hw->sih)) {
+ if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) &
+ MCTL_EN_MAC)
+ wlc_suspend_mac_and_wait(wlc_hw->wlc);
+ callbacks += wl_reset(wlc_hw->wlc->wl);
+ wlc_coredisable(wlc_hw);
+ }
+
+ /* turn off primary xtal and pll */
+ if (!wlc_hw->noreset) {
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS)
+ si_pci_down(wlc_hw->sih);
+ wlc_bmac_xtal(wlc_hw, OFF);
+ }
+ }
+
+ return callbacks;
+}
+
+void wlc_bmac_wait_for_wake(wlc_hw_info_t *wlc_hw)
+{
+ if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */
+ OSL_DELAY(5);
+ else {
+ /* delay before first read of ucode state */
+ OSL_DELAY(40);
+
+ /* wait until ucode is no longer asleep */
+ SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) ==
+ DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
+ }
+
+ ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP);
+}
+
+void wlc_bmac_hw_etheraddr(wlc_hw_info_t *wlc_hw, struct ether_addr *ea)
+{
+ bcopy(&wlc_hw->etheraddr, ea, ETHER_ADDR_LEN);
+}
+
+void wlc_bmac_set_hw_etheraddr(wlc_hw_info_t *wlc_hw, struct ether_addr *ea)
+{
+ bcopy(ea, &wlc_hw->etheraddr, ETHER_ADDR_LEN);
+}
+
+int wlc_bmac_bandtype(wlc_hw_info_t *wlc_hw)
+{
+ return wlc_hw->band->bandtype;
+}
+
+void *wlc_cur_phy(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ return (void *)wlc_hw->band->pi;
+}
+
+/* control chip clock to save power, enable dynamic clock or force fast clock */
+static void wlc_clkctl_clk(wlc_hw_info_t *wlc_hw, uint mode)
+{
+ if (PMUCTL_ENAB(wlc_hw->sih)) {
+ /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane,
+ * but mac core will still run on ALP(not HT) when it enters powersave mode,
+ * which means the FCA bit may not be set.
+ * should wakeup mac if driver wants it to run on HT.
+ */
+
+ if (wlc_hw->clk) {
+ if (mode == CLK_FAST) {
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st,
+ CCS_FORCEHT);
+
+ OSL_DELAY(64);
+
+ SPINWAIT(((R_REG
+ (wlc_hw->osh,
+ &wlc_hw->regs->
+ clk_ctl_st) & CCS_HTAVAIL) == 0),
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(R_REG
+ (wlc_hw->osh,
+ &wlc_hw->regs->
+ clk_ctl_st) & CCS_HTAVAIL);
+ } else {
+ if ((wlc_hw->sih->pmurev == 0) &&
+ (R_REG
+ (wlc_hw->osh,
+ &wlc_hw->regs->
+ clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
+ SPINWAIT(((R_REG
+ (wlc_hw->osh,
+ &wlc_hw->regs->
+ clk_ctl_st) & CCS_HTAVAIL)
+ == 0),
+ PMU_MAX_TRANSITION_DLY);
+ AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st,
+ ~CCS_FORCEHT);
+ }
+ }
+ wlc_hw->forcefastclk = (mode == CLK_FAST);
+ } else {
+ bool wakeup_ucode;
+
+ /* old chips w/o PMU, force HT through cc,
+ * then use FCA to verify mac is running fast clock
+ */
+
+ wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9);
+
+ if (wlc_hw->up && wakeup_ucode)
+ wlc_ucode_wake_override_set(wlc_hw,
+ WLC_WAKE_OVERRIDE_CLKCTL);
+
+ wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode);
+
+ if (D11REV_LT(wlc_hw->corerev, 11)) {
+ /* ucode WAR for old chips */
+ if (wlc_hw->forcefastclk)
+ wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK,
+ MHF1_FORCEFASTCLK, WLC_BAND_ALL);
+ else
+ wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0,
+ WLC_BAND_ALL);
+ }
+
+ /* check fast clock is available (if core is not in reset) */
+ if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk
+ && wlc_hw->clk)
+ ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA);
+
+ /* keep the ucode wake bit on if forcefastclk is on
+ * since we do not want ucode to put us back to slow clock
+ * when it dozes for PM mode.
+ * Code below matches the wake override bit with current forcefastclk state
+ * Only setting bit in wake_override instead of waking ucode immediately
+ * since old code (wlc.c 1.4499) had this behavior. Older code set
+ * wlc->forcefastclk but only had the wake happen if the wakup_ucode work
+ * (protected by an up check) was executed just below.
+ */
+ if (wlc_hw->forcefastclk)
+ mboolset(wlc_hw->wake_override,
+ WLC_WAKE_OVERRIDE_FORCEFAST);
+ else
+ mboolclr(wlc_hw->wake_override,
+ WLC_WAKE_OVERRIDE_FORCEFAST);
+
+ /* ok to clear the wakeup now */
+ if (wlc_hw->up && wakeup_ucode)
+ wlc_ucode_wake_override_clear(wlc_hw,
+ WLC_WAKE_OVERRIDE_CLKCTL);
+ }
+}
+
+/* set initial host flags value */
+static void
+BCMINITFN(wlc_mhfdef) (wlc_info_t *wlc, uint16 *mhfs, uint16 mhf2_init)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+
+ bzero(mhfs, sizeof(uint16) * MHFMAX);
+
+ mhfs[MHF2] |= mhf2_init;
+
+ /* prohibit use of slowclock on multifunction boards */
+ if (wlc_hw->boardflags & BFL_NOPLLDOWN)
+ mhfs[MHF1] |= MHF1_FORCEFASTCLK;
+
+ if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
+ mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
+ mhfs[MHF1] |= MHF1_IQSWAP_WAR;
+ }
+}
+
+/* set or clear ucode host flag bits
+ * it has an optimization for no-change write
+ * it only writes through shared memory when the core has clock;
+ * pre-CLK changes should use wlc_write_mhf to get around the optimization
+ *
+ *
+ * bands values are: WLC_BAND_AUTO <--- Current band only
+ * WLC_BAND_5G <--- 5G band only
+ * WLC_BAND_2G <--- 2G band only
+ * WLC_BAND_ALL <--- All bands
+ */
+void
+wlc_bmac_mhf(wlc_hw_info_t *wlc_hw, uint8 idx, uint16 mask, uint16 val,
+ int bands)
+{
+ uint16 save;
+ uint16 addr[MHFMAX] = {
+ M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+ M_HOST_FLAGS5
+ };
+ wlc_hwband_t *band;
+
+ ASSERT((val & ~mask) == 0);
+ ASSERT(idx < MHFMAX);
+ ASSERT(ARRAYSIZE(addr) == MHFMAX);
+
+ switch (bands) {
+ /* Current band only or all bands,
+ * then set the band to current band
+ */
+ case WLC_BAND_AUTO:
+ case WLC_BAND_ALL:
+ band = wlc_hw->band;
+ break;
+ case WLC_BAND_5G:
+ band = wlc_hw->bandstate[BAND_5G_INDEX];
+ break;
+ case WLC_BAND_2G:
+ band = wlc_hw->bandstate[BAND_2G_INDEX];
+ break;
+ default:
+ ASSERT(0);
+ band = NULL;
+ }
+
+ if (band) {
+ save = band->mhfs[idx];
+ band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
+
+ /* optimization: only write through if changed, and
+ * changed band is the current band
+ */
+ if (wlc_hw->clk && (band->mhfs[idx] != save)
+ && (band == wlc_hw->band))
+ wlc_bmac_write_shm(wlc_hw, addr[idx],
+ (uint16) band->mhfs[idx]);
+ }
+
+ if (bands == WLC_BAND_ALL) {
+ wlc_hw->bandstate[0]->mhfs[idx] =
+ (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
+ wlc_hw->bandstate[1]->mhfs[idx] =
+ (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
+ }
+}
+
+uint16 wlc_bmac_mhf_get(wlc_hw_info_t *wlc_hw, uint8 idx, int bands)
+{
+ wlc_hwband_t *band;
+ ASSERT(idx < MHFMAX);
+
+ switch (bands) {
+ case WLC_BAND_AUTO:
+ band = wlc_hw->band;
+ break;
+ case WLC_BAND_5G:
+ band = wlc_hw->bandstate[BAND_5G_INDEX];
+ break;
+ case WLC_BAND_2G:
+ band = wlc_hw->bandstate[BAND_2G_INDEX];
+ break;
+ default:
+ ASSERT(0);
+ band = NULL;
+ }
+
+ if (!band)
+ return 0;
+
+ return band->mhfs[idx];
+}
+
+static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, uint16 *mhfs)
+{
+ uint8 idx;
+ uint16 addr[] = {
+ M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+ M_HOST_FLAGS5
+ };
+
+ ASSERT(ARRAYSIZE(addr) == MHFMAX);
+
+ for (idx = 0; idx < MHFMAX; idx++) {
+ wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]);
+ }
+}
+
+/* set the maccontrol register to desired reset state and
+ * initialize the sw cache of the register
+ */
+static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw)
+{
+ /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
+ wlc_hw->maccontrol = 0;
+ wlc_hw->suspended_fifos = 0;
+ wlc_hw->wake_override = 0;
+ wlc_hw->mute_override = 0;
+ wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
+}
+
+/* set or clear maccontrol bits */
+void wlc_bmac_mctrl(wlc_hw_info_t *wlc_hw, uint32 mask, uint32 val)
+{
+ uint32 maccontrol;
+ uint32 new_maccontrol;
+
+ ASSERT((val & ~mask) == 0);
+
+ maccontrol = wlc_hw->maccontrol;
+ new_maccontrol = (maccontrol & ~mask) | val;
+
+ /* if the new maccontrol value is the same as the old, nothing to do */
+ if (new_maccontrol == maccontrol)
+ return;
+
+ /* something changed, cache the new value */
+ wlc_hw->maccontrol = new_maccontrol;
+
+ /* write the new values with overrides applied */
+ wlc_mctrl_write(wlc_hw);
+}
+
+/* write the software state of maccontrol and overrides to the maccontrol register */
+static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw)
+{
+ uint32 maccontrol = wlc_hw->maccontrol;
+
+ /* OR in the wake bit if overridden */
+ if (wlc_hw->wake_override)
+ maccontrol |= MCTL_WAKE;
+
+ /* set AP and INFRA bits for mute if needed */
+ if (wlc_hw->mute_override) {
+ maccontrol &= ~(MCTL_AP);
+ maccontrol |= MCTL_INFRA;
+ }
+
+ W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol);
+}
+
+void wlc_ucode_wake_override_set(wlc_hw_info_t *wlc_hw, uint32 override_bit)
+{
+ ASSERT((wlc_hw->wake_override & override_bit) == 0);
+
+ if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
+ mboolset(wlc_hw->wake_override, override_bit);
+ return;
+ }
+
+ mboolset(wlc_hw->wake_override, override_bit);
+
+ wlc_mctrl_write(wlc_hw);
+ wlc_bmac_wait_for_wake(wlc_hw);
+
+ return;
+}
+
+void wlc_ucode_wake_override_clear(wlc_hw_info_t *wlc_hw, uint32 override_bit)
+{
+ ASSERT(wlc_hw->wake_override & override_bit);
+
+ mboolclr(wlc_hw->wake_override, override_bit);
+
+ if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
+ return;
+
+ wlc_mctrl_write(wlc_hw);
+
+ return;
+}
+
+/* When driver needs ucode to stop beaconing, it has to make sure that
+ * MCTL_AP is clear and MCTL_INFRA is set
+ * Mode MCTL_AP MCTL_INFRA
+ * AP 1 1
+ * STA 0 1 <--- This will ensure no beacons
+ * IBSS 0 0
+ */
+static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw)
+{
+ wlc_hw->mute_override = 1;
+
+ /* if maccontrol already has AP == 0 and INFRA == 1 without this
+ * override, then there is no change to write
+ */
+ if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+ return;
+
+ wlc_mctrl_write(wlc_hw);
+
+ return;
+}
+
+/* Clear the override on AP and INFRA bits */
+static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw)
+{
+ if (wlc_hw->mute_override == 0)
+ return;
+
+ wlc_hw->mute_override = 0;
+
+ /* if maccontrol already has AP == 0 and INFRA == 1 without this
+ * override, then there is no change to write
+ */
+ if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+ return;
+
+ wlc_mctrl_write(wlc_hw);
+}
+
+/*
+ * Write a MAC address to the rcmta structure
+ */
+void
+wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx,
+ const struct ether_addr *addr)
+{
+ d11regs_t *regs = wlc_hw->regs;
+ volatile uint16 *objdata16 =
+ (volatile uint16 *)(uintptr) & regs->objdata;
+ uint32 mac_hm;
+ uint16 mac_l;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__));
+
+ ASSERT(wlc_hw->corerev > 4);
+
+ mac_hm =
+ (addr->octet[3] << 24) | (addr->octet[2] << 16) | (addr->
+ octet[1] << 8) |
+ addr->octet[0];
+ mac_l = (addr->octet[5] << 8) | addr->octet[4];
+
+ osh = wlc_hw->osh;
+
+ W_REG(osh, &regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, mac_hm);
+ W_REG(osh, &regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, objdata16, mac_l);
+}
+
+/*
+ * Write a MAC address to the given match reg offset in the RXE match engine.
+ */
+void
+wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset,
+ const struct ether_addr *addr)
+{
+ d11regs_t *regs;
+ uint16 mac_l;
+ uint16 mac_m;
+ uint16 mac_h;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit));
+
+ ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4));
+
+ regs = wlc_hw->regs;
+ mac_l = addr->octet[0] | (addr->octet[1] << 8);
+ mac_m = addr->octet[2] | (addr->octet[3] << 8);
+ mac_h = addr->octet[4] | (addr->octet[5] << 8);
+
+ osh = wlc_hw->osh;
+
+ /* enter the MAC addr into the RXE match registers */
+ W_REG(osh, &regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
+ W_REG(osh, &regs->rcm_mat_data, mac_l);
+ W_REG(osh, &regs->rcm_mat_data, mac_m);
+ W_REG(osh, &regs->rcm_mat_data, mac_h);
+
+}
+
+void
+wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, int len,
+ void *buf)
+{
+ d11regs_t *regs;
+ uint32 word;
+ bool be_bit;
+#ifdef IL_BIGENDIAN
+ volatile uint16 *dptr = NULL;
+#endif /* IL_BIGENDIAN */
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit));
+
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ ASSERT(ISALIGNED(offset, sizeof(uint32)));
+ ASSERT(ISALIGNED(len, sizeof(uint32)));
+ ASSERT((offset & ~0xffff) == 0);
+
+ W_REG(osh, &regs->tplatewrptr, offset);
+
+ /* if MCTL_BIGEND bit set in mac control register,
+ * the chip swaps data in fifo, as well as data in
+ * template ram
+ */
+ be_bit = (R_REG(osh, &regs->maccontrol) & MCTL_BIGEND) != 0;
+
+ while (len > 0) {
+ bcopy((uint8 *) buf, &word, sizeof(uint32));
+
+ if (be_bit)
+ word = hton32(word);
+ else
+ word = htol32(word);
+
+ W_REG(osh, &regs->tplatewrdata, word);
+
+ buf = (uint8 *) buf + sizeof(uint32);
+ len -= sizeof(uint32);
+ }
+}
+
+void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, uint16 newmin)
+{
+ osl_t *osh;
+
+ osh = wlc_hw->osh;
+ wlc_hw->band->CWmin = newmin;
+
+ W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
+ (void)R_REG(osh, &wlc_hw->regs->objaddr);
+ W_REG(osh, &wlc_hw->regs->objdata, newmin);
+}
+
+void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, uint16 newmax)
+{
+ osl_t *osh;
+
+ osh = wlc_hw->osh;
+ wlc_hw->band->CWmax = newmax;
+
+ W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
+ (void)R_REG(osh, &wlc_hw->regs->objaddr);
+ W_REG(osh, &wlc_hw->regs->objdata, newmax);
+}
+
+void wlc_bmac_bw_set(wlc_hw_info_t *wlc_hw, uint16 bw)
+{
+ bool fastclk;
+ uint32 tmp;
+
+ /* request FAST clock if not on */
+ fastclk = wlc_hw->forcefastclk;
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
+
+ ASSERT(wlc_hw->clk);
+ if (D11REV_LT(wlc_hw->corerev, 17))
+ tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol);
+
+ wlc_bmac_phy_reset(wlc_hw);
+ wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
+
+ /* restore the clk */
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+}
+
+static void
+wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn, int len)
+{
+ d11regs_t *regs = wlc_hw->regs;
+
+ wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
+ bcn);
+ /* write beacon length to SCR */
+ ASSERT(len < 65536);
+ wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (uint16) len);
+ /* mark beacon0 valid */
+ OR_REG(wlc_hw->osh, &regs->maccommand, MCMD_BCN0VLD);
+}
+
+static void
+wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn, int len)
+{
+ d11regs_t *regs = wlc_hw->regs;
+
+ wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
+ bcn);
+ /* write beacon length to SCR */
+ ASSERT(len < 65536);
+ wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (uint16) len);
+ /* mark beacon1 valid */
+ OR_REG(wlc_hw->osh, &regs->maccommand, MCMD_BCN1VLD);
+}
+
+/* mac is assumed to be suspended at this point */
+void
+wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn, int len,
+ bool both)
+{
+ d11regs_t *regs = wlc_hw->regs;
+
+ if (both) {
+ wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+ wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+ } else {
+ /* bcn 0 */
+ if (!(R_REG(wlc_hw->osh, &regs->maccommand) & MCMD_BCN0VLD))
+ wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+ /* bcn 1 */
+ else if (!
+ (R_REG(wlc_hw->osh, &regs->maccommand) & MCMD_BCN1VLD))
+ wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+ else /* one template should always have been available */
+ ASSERT(0);
+ }
+}
+
+static void WLBANDINITFN(wlc_bmac_upd_synthpu) (wlc_hw_info_t *wlc_hw)
+{
+ uint16 v;
+ wlc_info_t *wlc = wlc_hw->wlc;
+ /* update SYNTHPU_DLY */
+
+ if (WLCISLCNPHY(wlc->band)) {
+ v = SYNTHPU_DLY_LPPHY_US;
+ } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) {
+ v = SYNTHPU_DLY_NPHY_US;
+ } else {
+ v = SYNTHPU_DLY_BPHY_US;
+ }
+
+ wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
+}
+
+/* band-specific init */
+static void
+WLBANDINITFN(wlc_bmac_bsinit) (wlc_info_t *wlc, chanspec_t chanspec)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+
+ WL_TRACE(("wl%d: wlc_bmac_bsinit: bandunit %d\n", wlc_hw->unit,
+ wlc_hw->band->bandunit));
+
+ /* sanity check */
+ if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) !=
+ PHY_TYPE_LCNXN)
+ ASSERT((uint)
+ PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion))
+ == wlc_hw->band->phytype);
+
+ wlc_ucode_bsinit(wlc_hw);
+
+ wlc_phy_init(wlc_hw->band->pi, chanspec);
+
+ wlc_ucode_txant_set(wlc_hw);
+
+ /* cwmin is band-specific, update hardware with value for current band */
+ wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
+ wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
+
+ wlc_bmac_update_slot_timing(wlc_hw,
+ BAND_5G(wlc_hw->band->
+ bandtype) ? TRUE : wlc_hw->
+ shortslot);
+
+ /* write phytype and phyvers */
+ wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (uint16) wlc_hw->band->phytype);
+ wlc_bmac_write_shm(wlc_hw, M_PHYVER, (uint16) wlc_hw->band->phyrev);
+
+ /* initialize the txphyctl1 rate table since shmem is shared between bands */
+ wlc_upd_ofdm_pctl1_table(wlc_hw);
+
+ wlc_bmac_upd_synthpu(wlc_hw);
+}
+
+void wlc_bmac_core_phy_clk(wlc_hw_info_t *wlc_hw, bool clk)
+{
+ WL_TRACE(("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk));
+
+ wlc_hw->phyclk = clk;
+
+ if (OFF == clk) { /* clear gmode bit, put phy into reset */
+
+ si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
+ (SICF_PRST | SICF_FGC));
+ OSL_DELAY(1);
+ si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
+ OSL_DELAY(1);
+
+ } else { /* take phy out of reset */
+
+ si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
+ OSL_DELAY(1);
+ si_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
+ OSL_DELAY(1);
+
+ }
+}
+
+/* Perform a soft reset of the PHY PLL */
+void wlc_bmac_core_phypll_reset(wlc_hw_info_t *wlc_hw)
+{
+ WL_TRACE(("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit));
+
+ si_corereg(wlc_hw->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_addr), ~0, 0);
+ OSL_DELAY(1);
+ si_corereg(wlc_hw->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data), 0x4, 0);
+ OSL_DELAY(1);
+ si_corereg(wlc_hw->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data), 0x4, 4);
+ OSL_DELAY(1);
+ si_corereg(wlc_hw->sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data), 0x4, 0);
+ OSL_DELAY(1);
+}
+
+/* light way to turn on phy clock without reset for NPHY only
+ * refer to wlc_bmac_core_phy_clk for full version
+ */
+void wlc_bmac_phyclk_fgc(wlc_hw_info_t *wlc_hw, bool clk)
+{
+ /* support(necessary for NPHY and HYPHY) only */
+ if (!WLCISNPHY(wlc_hw->band))
+ return;
+
+ if (ON == clk)
+ si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
+ else
+ si_core_cflags(wlc_hw->sih, SICF_FGC, 0);
+
+}
+
+void wlc_bmac_macphyclk_set(wlc_hw_info_t *wlc_hw, bool clk)
+{
+ if (ON == clk)
+ si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
+ else
+ si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
+}
+
+void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw)
+{
+ wlc_phy_t *pih = wlc_hw->band->pi;
+ uint32 phy_bw_clkbits;
+ bool phy_in_reset = FALSE;
+
+ WL_TRACE(("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit));
+
+ if (pih == NULL)
+ return;
+
+ phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
+
+ /* Specfic reset sequence required for NPHY rev 3 and 4 */
+ if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
+ NREV_LE(wlc_hw->band->phyrev, 4)) {
+ /* Set the PHY bandwidth */
+ si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
+
+ OSL_DELAY(1);
+
+ /* Perform a soft reset of the PHY PLL */
+ wlc_bmac_core_phypll_reset(wlc_hw);
+
+ /* reset the PHY */
+ si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
+ (SICF_PRST | SICF_PCLKE));
+ phy_in_reset = TRUE;
+ } else {
+
+ si_core_cflags(wlc_hw->sih,
+ (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
+ (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
+ }
+
+ OSL_DELAY(2);
+ wlc_bmac_core_phy_clk(wlc_hw, ON);
+
+ if (pih)
+ wlc_phy_anacore(pih, ON);
+}
+
+/* switch to and initialize new band */
+static void
+WLBANDINITFN(wlc_bmac_setband) (wlc_hw_info_t *wlc_hw, uint bandunit,
+ chanspec_t chanspec) {
+ wlc_info_t *wlc = wlc_hw->wlc;
+ uint32 macintmask;
+
+ ASSERT(NBANDS_HW(wlc_hw) > 1);
+ ASSERT(bandunit != wlc_hw->band->bandunit);
+
+ /* Enable the d11 core before accessing it */
+ if (!si_iscoreup(wlc_hw->sih)) {
+ si_core_reset(wlc_hw->sih, 0, 0);
+ ASSERT(si_iscoreup(wlc_hw->sih));
+ wlc_mctrl_reset(wlc_hw);
+ }
+
+ macintmask = wlc_setband_inact(wlc, bandunit);
+
+ if (!wlc_hw->up)
+ return;
+
+ wlc_bmac_core_phy_clk(wlc_hw, ON);
+
+ /* band-specific initializations */
+ wlc_bmac_bsinit(wlc, chanspec);
+
+ /*
+ * If there are any pending software interrupt bits,
+ * then replace these with a harmless nonzero value
+ * so wlc_dpc() will re-enable interrupts when done.
+ */
+ if (wlc->macintstatus)
+ wlc->macintstatus = MI_DMAINT;
+
+ /* restore macintmask */
+ wl_intrsrestore(wlc->wl, macintmask);
+
+ /* ucode should still be suspended.. */
+ ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) ==
+ 0);
+}
+
+/* low-level band switch utility routine */
+void WLBANDINITFN(wlc_setxband) (wlc_hw_info_t *wlc_hw, uint bandunit)
+{
+ WL_TRACE(("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit));
+
+ wlc_hw->band = wlc_hw->bandstate[bandunit];
+
+ /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */
+ wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
+
+ /* set gmode core flag */
+ if (wlc_hw->sbclk && !wlc_hw->noreset) {
+ si_core_cflags(wlc_hw->sih, SICF_GMODE,
+ ((bandunit == 0) ? SICF_GMODE : 0));
+ }
+}
+
+static bool BCMATTACHFN(wlc_isgoodchip) (wlc_hw_info_t *wlc_hw)
+{
+
+ /* reject unsupported corerev */
+ if (!VALID_COREREV(wlc_hw->corerev)) {
+ WL_ERROR(("unsupported core rev %d\n", wlc_hw->corerev));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bool BCMATTACHFN(wlc_validboardtype) (wlc_hw_info_t *wlc_hw)
+{
+ bool goodboard = TRUE;
+ uint boardrev = wlc_hw->boardrev;
+
+ if (boardrev == 0)
+ goodboard = FALSE;
+ else if (boardrev > 0xff) {
+ uint brt = (boardrev & 0xf000) >> 12;
+ uint b0 = (boardrev & 0xf00) >> 8;
+ uint b1 = (boardrev & 0xf0) >> 4;
+ uint b2 = boardrev & 0xf;
+
+ if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
+ || (b2 > 9))
+ goodboard = FALSE;
+ }
+
+ if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM)
+ return goodboard;
+
+ return goodboard;
+}
+
+static char *BCMINITFN(wlc_get_macaddr) (wlc_hw_info_t *wlc_hw)
+{
+ const char *varname = "macaddr";
+ char *macaddr;
+
+ /* If macaddr exists, use it (Sromrev4, CIS, ...). */
+ macaddr = getvar(wlc_hw->vars, varname);
+ if (macaddr != NULL)
+ return macaddr;
+
+ if (NBANDS_HW(wlc_hw) > 1)
+ varname = "et1macaddr";
+ else
+ varname = "il0macaddr";
+
+ macaddr = getvar(wlc_hw->vars, varname);
+ if (macaddr == NULL) {
+ WL_ERROR(("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", wlc_hw->unit, varname));
+ }
+
+ return macaddr;
+}
+
+/*
+ * Return TRUE if radio is disabled, otherwise FALSE.
+ * hw radio disable signal is an external pin, users activate it asynchronously
+ * this function could be called when driver is down and w/o clock
+ * it operates on different registers depending on corerev and boardflag.
+ */
+bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw)
+{
+ bool v, clk, xtal;
+ uint32 resetbits = 0, flags = 0;
+
+ xtal = wlc_hw->sbclk;
+ if (!xtal)
+ wlc_bmac_xtal(wlc_hw, ON);
+
+ /* may need to take core out of reset first */
+ clk = wlc_hw->clk;
+ if (!clk) {
+ if (D11REV_LE(wlc_hw->corerev, 11))
+ resetbits |= SICF_PCLKE;
+
+ /*
+ * corerev >= 18, mac no longer enables phyclk automatically when driver accesses
+ * phyreg throughput mac. This can be skipped since only mac reg is accessed below
+ */
+ if (D11REV_GE(wlc_hw->corerev, 18))
+ flags |= SICF_PCLKE;
+
+ /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+ if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID) ||
+ (CHIPID(wlc_hw->sih->chip) == BCM43421_CHIP_ID))
+ wlc_hw->regs =
+ (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID,
+ 0);
+ si_core_reset(wlc_hw->sih, flags, resetbits);
+ wlc_mctrl_reset(wlc_hw);
+ }
+
+ v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
+
+ /* put core back into reset */
+ if (!clk)
+ si_core_disable(wlc_hw->sih, 0);
+
+ if (!xtal)
+ wlc_bmac_xtal(wlc_hw, OFF);
+
+ return v;
+}
+
+/* Initialize just the hardware when coming out of POR or S3/S5 system states */
+void BCMINITFN(wlc_bmac_hw_up) (wlc_hw_info_t *wlc_hw)
+{
+ if (wlc_hw->wlc->pub->hw_up)
+ return;
+
+ WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__));
+
+ /*
+ * Enable pll and xtal, initialize the power control registers,
+ * and force fastclock for the remainder of wlc_up().
+ */
+ wlc_bmac_xtal(wlc_hw, ON);
+ si_clkctl_init(wlc_hw->sih);
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) {
+ si_pci_fixcfg(wlc_hw->sih);
+
+ /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+ if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID) ||
+ (CHIPID(wlc_hw->sih->chip) == BCM43421_CHIP_ID))
+ wlc_hw->regs =
+ (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID,
+ 0);
+ }
+
+ /* Inform phy that a POR reset has occurred so it does a complete phy init */
+ wlc_phy_por_inform(wlc_hw->band->pi);
+
+ wlc_hw->ucode_loaded = FALSE;
+ wlc_hw->wlc->pub->hw_up = TRUE;
+
+ if ((wlc_hw->boardflags & BFL_FEM)
+ && (CHIPID(wlc_hw->sih->chip) == BCM4313_CHIP_ID)) {
+ if (!
+ (wlc_hw->boardrev >= 0x1250
+ && (wlc_hw->boardflags & BFL_FEM_BT)))
+ si_epa_4313war(wlc_hw->sih);
+ }
+}
+
+static bool wlc_dma_rxreset(wlc_hw_info_t *wlc_hw, uint fifo)
+{
+ hnddma_t *di = wlc_hw->di[fifo];
+ osl_t *osh;
+
+ if (D11REV_LT(wlc_hw->corerev, 12)) {
+ bool rxidle = TRUE;
+ uint16 rcv_frm_cnt = 0;
+
+ osh = wlc_hw->osh;
+
+ W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8);
+ SPINWAIT((!(rxidle = dma_rxidle(di))) &&
+ ((rcv_frm_cnt =
+ R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0),
+ 50000);
+
+ if (!rxidle && (rcv_frm_cnt != 0))
+ WL_ERROR(("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", wlc_hw->unit, __func__, fifo, rcv_frm_cnt));
+ OSL_DELAY(2000);
+ }
+
+ return dma_rxreset(di);
+}
+
+/* d11 core reset
+ * ensure fask clock during reset
+ * reset dma
+ * reset d11(out of reset)
+ * reset phy(out of reset)
+ * clear software macintstatus for fresh new start
+ * one testing hack wlc_hw->noreset will bypass the d11/phy reset
+ */
+void BCMINITFN(wlc_bmac_corereset) (wlc_hw_info_t *wlc_hw, uint32 flags)
+{
+ d11regs_t *regs;
+ uint i;
+ bool fastclk;
+ uint32 resetbits = 0;
+
+ if (flags == WLC_USE_COREFLAGS)
+ flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
+
+ WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__));
+
+ regs = wlc_hw->regs;
+
+ /* request FAST clock if not on */
+ fastclk = wlc_hw->forcefastclk;
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ /* reset the dma engines except first time thru */
+ if (si_iscoreup(wlc_hw->sih)) {
+ for (i = 0; i < NFIFO; i++)
+ if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) {
+ WL_ERROR(("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, i));
+ }
+
+ if ((wlc_hw->di[RX_FIFO])
+ && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) {
+ WL_ERROR(("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_FIFO));
+ }
+ if (D11REV_IS(wlc_hw->corerev, 4)
+ && wlc_hw->di[RX_TXSTATUS_FIFO]
+ && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) {
+ WL_ERROR(("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_TXSTATUS_FIFO));
+ }
+ }
+ /* if noreset, just stop the psm and return */
+ if (wlc_hw->noreset) {
+ wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */
+ wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
+ return;
+ }
+
+ if (D11REV_LE(wlc_hw->corerev, 11))
+ resetbits |= SICF_PCLKE;
+
+ /*
+ * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg
+ * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid
+ * need to enable PHY CLK
+ */
+ if (D11REV_GE(wlc_hw->corerev, 18))
+ flags |= SICF_PCLKE;
+
+ /* reset the core
+ * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which
+ * is cleared by the core_reset. have to re-request it.
+ * This adds some delay and we can optimize it by also requesting fastclk through
+ * chipcommon during this period if necessary. But that has to work coordinate
+ * with other driver like mips/arm since they may touch chipcommon as well.
+ */
+ wlc_hw->clk = FALSE;
+ si_core_reset(wlc_hw->sih, flags, resetbits);
+ wlc_hw->clk = TRUE;
+ if (wlc_hw->band && wlc_hw->band->pi)
+ wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, TRUE);
+
+ wlc_mctrl_reset(wlc_hw);
+
+ if (PMUCTL_ENAB(wlc_hw->sih))
+ wlc_clkctl_clk(wlc_hw, CLK_FAST);
+
+ wlc_bmac_phy_reset(wlc_hw);
+
+ /* turn on PHY_PLL */
+ wlc_bmac_core_phypll_ctl(wlc_hw, TRUE);
+
+ /* clear sw intstatus */
+ wlc_hw->wlc->macintstatus = 0;
+
+ /* restore the clk setting */
+ if (!fastclk)
+ wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+}
+
+/* If the ucode that supports corerev 5 is used for corerev 9 and above,
+ * txfifo sizes needs to be modified(increased) since the newer cores
+ * have more memory.
+ */
+static void BCMINITFN(wlc_corerev_fifofixup) (wlc_hw_info_t *wlc_hw)
+{
+ d11regs_t *regs = wlc_hw->regs;
+ uint16 fifo_nu;
+ uint16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
+ uint16 txfifo_def, txfifo_def1;
+ uint16 txfifo_cmd;
+ osl_t *osh;
+
+ if (D11REV_LT(wlc_hw->corerev, 9))
+ goto exit;
+
+ /* tx fifos start at TXFIFO_START_BLK from the Base address */
+ txfifo_startblk = TXFIFO_START_BLK;
+
+ osh = wlc_hw->osh;
+
+ /* sequence of operations: reset fifo, set fifo size, reset fifo */
+ for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
+
+ txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
+ txfifo_def = (txfifo_startblk & 0xff) |
+ (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
+ txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
+ ((((txfifo_endblk -
+ 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
+ txfifo_cmd =
+ TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
+
+ W_REG(osh, &regs->xmtfifocmd, txfifo_cmd);
+ W_REG(osh, &regs->xmtfifodef, txfifo_def);
+ if (D11REV_GE(wlc_hw->corerev, 16))
+ W_REG(osh, &regs->xmtfifodef1, txfifo_def1);
+
+ W_REG(osh, &regs->xmtfifocmd, txfifo_cmd);
+
+ txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
+ }
+ exit:
+ /* need to propagate to shm location to be in sync since ucode/hw won't do this */
+ wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0,
+ wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
+ wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1,
+ wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
+ wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2,
+ ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
+ xmtfifo_sz[TX_AC_BK_FIFO]));
+ wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3,
+ ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
+ xmtfifo_sz[TX_BCMC_FIFO]));
+}
+
+/* d11 core init
+ * reset PSM
+ * download ucode/PCM
+ * let ucode run to suspended
+ * download ucode inits
+ * config other core registers
+ * init dma
+ */
+static void BCMINITFN(wlc_coreinit) (wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs;
+ uint32 sflags;
+ uint bcnint_us;
+ uint i = 0;
+ bool fifosz_fixup = FALSE;
+ osl_t *osh;
+ int err = 0;
+ uint16 buf[NFIFO];
+
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ WL_TRACE(("wl%d: wlc_coreinit\n", wlc_hw->unit));
+
+ /* reset PSM */
+ wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
+
+ wlc_ucode_download(wlc_hw);
+ /*
+ * FIFOSZ fixup
+ * 1) core5-9 use ucode 5 to save space since the PSM is the same
+ * 2) newer chips, driver wants to controls the fifo allocation
+ */
+ if (D11REV_GE(wlc_hw->corerev, 4))
+ fifosz_fixup = TRUE;
+
+ /* let the PSM run to the suspended state, set mode to BSS STA */
+ W_REG(osh, &regs->macintstatus, -1);
+ wlc_bmac_mctrl(wlc_hw, ~0,
+ (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
+
+ /* wait for ucode to self-suspend after auto-init */
+ SPINWAIT(((R_REG(osh, &regs->macintstatus) & MI_MACSSPNDD) == 0),
+ 1000 * 1000);
+ if ((R_REG(osh, &regs->macintstatus) & MI_MACSSPNDD) == 0)
+ WL_ERROR(("wl%d: wlc_coreinit: ucode did not self-suspend!\n",
+ wlc_hw->unit));
+
+ wlc_gpio_init(wlc);
+
+ sflags = si_core_sflags(wlc_hw->sih, 0, 0);
+
+ if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (WLCISNPHY(wlc_hw->band))
+ wlc_write_inits(wlc_hw, d11n0initvals16);
+ else
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ } else if (D11REV_IS(wlc_hw->corerev, 24)) {
+ if (WLCISLCNPHY(wlc_hw->band)) {
+ wlc_write_inits(wlc_hw, d11lcn0initvals24);
+ } else {
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ }
+ } else {
+ WL_ERROR(("%s: wl%d: unsupported corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ }
+
+ /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */
+ if (fifosz_fixup == TRUE) {
+ wlc_corerev_fifofixup(wlc_hw);
+ }
+
+ /* check txfifo allocations match between ucode and driver */
+ buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0);
+ if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
+ i = TX_AC_BE_FIFO;
+ err = -1;
+ }
+ buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1);
+ if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
+ i = TX_AC_VI_FIFO;
+ err = -1;
+ }
+ buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2);
+ buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
+ buf[TX_AC_BK_FIFO] &= 0xff;
+ if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
+ i = TX_AC_BK_FIFO;
+ err = -1;
+ }
+ if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
+ i = TX_AC_VO_FIFO;
+ err = -1;
+ }
+ buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3);
+ buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
+ buf[TX_BCMC_FIFO] &= 0xff;
+ if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
+ i = TX_BCMC_FIFO;
+ err = -1;
+ }
+ if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
+ i = TX_ATIM_FIFO;
+ err = -1;
+ }
+ if (err != 0) {
+ WL_ERROR(("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", buf[i], wlc_hw->xmtfifo_sz[i], i));
+ /* DO NOT ASSERT corerev < 4 even there is a mismatch
+ * shmem, since driver don't overwrite those chip and
+ * ucode initialize data will be used.
+ */
+ if (D11REV_GE(wlc_hw->corerev, 4))
+ ASSERT(0);
+ }
+
+ /* make sure we can still talk to the mac */
+ ASSERT(R_REG(osh, &regs->maccontrol) != 0xffffffff);
+
+ /* band-specific inits done by wlc_bsinit() */
+
+ /* Set up frame burst size and antenna swap threshold init values */
+ wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
+ wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
+
+ /* enable one rx interrupt per received frame */
+ W_REG(osh, &regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
+ if (D11REV_IS(wlc_hw->corerev, 4))
+ W_REG(osh, &regs->intrcvlazy[3], (1 << IRL_FC_SHIFT));
+
+ /* set the station mode (BSS STA) */
+ wlc_bmac_mctrl(wlc_hw,
+ (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
+ (MCTL_INFRA | MCTL_DISCARD_PMQ));
+
+ /* set up Beacon interval */
+ bcnint_us = 0x8000 << 10;
+ W_REG(osh, &regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
+ W_REG(osh, &regs->tsf_cfpstart, bcnint_us);
+ W_REG(osh, &regs->macintstatus, MI_GP1);
+
+ /* write interrupt mask */
+ W_REG(osh, &regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
+ if (D11REV_IS(wlc_hw->corerev, 4))
+ W_REG(osh, &regs->intctrlregs[RX_TXSTATUS_FIFO].intmask,
+ DEF_RXINTMASK);
+
+ /* allow the MAC to control the PHY clock (dynamic on/off) */
+ wlc_bmac_macphyclk_set(wlc_hw, ON);
+
+ /* program dynamic clock control fast powerup delay register */
+ if (D11REV_GT(wlc_hw->corerev, 4)) {
+ wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih);
+ W_REG(osh, &regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
+ }
+
+ /* tell the ucode the corerev */
+ wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (uint16) wlc_hw->corerev);
+
+ /* tell the ucode MAC capabilities */
+ if (D11REV_GE(wlc_hw->corerev, 13)) {
+ wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L,
+ (uint16) (wlc_hw->machwcap & 0xffff));
+ wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H,
+ (uint16) ((wlc_hw->
+ machwcap >> 16) & 0xffff));
+ }
+
+ /* write retry limits to SCR, this done after PSM init */
+ W_REG(osh, &regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, wlc_hw->SRL);
+ W_REG(osh, &regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, wlc_hw->LRL);
+
+ /* write rate fallback retry limits */
+ wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
+ wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
+
+ if (D11REV_GE(wlc_hw->corerev, 16)) {
+ AND_REG(osh, &regs->ifs_ctl, 0x0FFF);
+ W_REG(osh, &regs->ifs_aifsn, EDCF_AIFSN_MIN);
+ }
+
+ /* dma initializations */
+ wlc->txpend16165war = 0;
+
+ /* init the tx dma engines */
+ for (i = 0; i < NFIFO; i++) {
+ if (wlc_hw->di[i])
+ dma_txinit(wlc_hw->di[i]);
+ }
+
+ /* init the rx dma engine(s) and post receive buffers */
+ dma_rxinit(wlc_hw->di[RX_FIFO]);
+ dma_rxfill(wlc_hw->di[RX_FIFO]);
+ if (D11REV_IS(wlc_hw->corerev, 4)) {
+ dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]);
+ dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]);
+ }
+}
+
+/* This function is used for changing the tsf frac register
+ * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
+ * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
+ * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
+ * HTPHY Formula is 2^26/freq(MHz) e.g.
+ * For spuron2 - 126MHz -> 2^26/126 = 532610.0
+ * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
+ * For spuron: 123MHz -> 2^26/123 = 545600.5
+ * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
+ * For spur off: 120MHz -> 2^26/120 = 559240.5
+ * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
+ */
+
+void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, uint8 spurmode)
+{
+ d11regs_t *regs;
+ osl_t *osh;
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID)) {
+ if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */
+ W_REG(osh, &regs->tsf_clk_frac_l, 0x2082);
+ W_REG(osh, &regs->tsf_clk_frac_h, 0x8);
+ } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */
+ W_REG(osh, &regs->tsf_clk_frac_l, 0x5341);
+ W_REG(osh, &regs->tsf_clk_frac_h, 0x8);
+ } else { /* 120Mhz */
+ W_REG(osh, &regs->tsf_clk_frac_l, 0x8889);
+ W_REG(osh, &regs->tsf_clk_frac_h, 0x8);
+ }
+ } else if (WLCISLCNPHY(wlc_hw->band)) {
+ if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */
+ W_REG(osh, &regs->tsf_clk_frac_l, 0x7CE0);
+ W_REG(osh, &regs->tsf_clk_frac_h, 0xC);
+ } else { /* 80Mhz */
+ W_REG(osh, &regs->tsf_clk_frac_l, 0xCCCD);
+ W_REG(osh, &regs->tsf_clk_frac_h, 0xC);
+ }
+ }
+}
+
+/* Initialize GPIOs that are controlled by D11 core */
+static void BCMINITFN(wlc_gpio_init) (wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs;
+ uint32 gc, gm;
+ osl_t *osh;
+
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ /* use GPIO select 0 to get all gpio signals from the gpio out reg */
+ wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
+
+ /*
+ * Common GPIO setup:
+ * G0 = LED 0 = WLAN Activity
+ * G1 = LED 1 = WLAN 2.4 GHz Radio State
+ * G2 = LED 2 = WLAN 5 GHz Radio State
+ * G4 = radio disable input (HI enabled, LO disabled)
+ */
+
+ gc = gm = 0;
+
+ /* Allocate GPIOs for mimo antenna diversity feature */
+ if (WLANTSEL_ENAB(wlc)) {
+ if (wlc_hw->antsel_type == ANTSEL_2x3) {
+ /* Enable antenna diversity, use 2x3 mode */
+ wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+ MHF3_ANTSEL_EN, WLC_BAND_ALL);
+ wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
+ MHF3_ANTSEL_MODE, WLC_BAND_ALL);
+
+ /* init superswitch control */
+ wlc_phy_antsel_init(wlc_hw->band->pi, FALSE);
+
+ } else if (wlc_hw->antsel_type == ANTSEL_2x4) {
+ ASSERT((gm & BOARD_GPIO_12) == 0);
+ gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
+ /* The board itself is powered by these GPIOs (when not sending pattern)
+ * So set them high
+ */
+ OR_REG(osh, &regs->psm_gpio_oe,
+ (BOARD_GPIO_12 | BOARD_GPIO_13));
+ OR_REG(osh, &regs->psm_gpio_out,
+ (BOARD_GPIO_12 | BOARD_GPIO_13));
+
+ /* Enable antenna diversity, use 2x4 mode */
+ wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+ MHF3_ANTSEL_EN, WLC_BAND_ALL);
+ wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
+ WLC_BAND_ALL);
+
+ /* Configure the desired clock to be 4Mhz */
+ wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
+ ANTSEL_CLKDIV_4MHZ);
+ }
+ }
+ /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */
+ if (wlc_hw->boardflags & BFL_PACTRL)
+ gm |= gc |= BOARD_GPIO_PACTRL;
+
+ /* apply to gpiocontrol register */
+ si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
+}
+
+static void BCMATTACHFN(wlc_ucode_download) (wlc_hw_info_t *wlc_hw)
+{
+ wlc_info_t *wlc;
+ wlc = wlc_hw->wlc;
+
+ if (wlc_hw->ucode_loaded)
+ return;
+
+ if (D11REV_IS(wlc_hw->corerev, 23)) {
+ if (WLCISNPHY(wlc_hw->band)) {
+ wlc_ucode_write(wlc_hw, bcm43xx_16_mimo,
+ bcm43xx_16_mimosz);
+ wlc_hw->ucode_loaded = TRUE;
+ } else
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ } else if (D11REV_IS(wlc_hw->corerev, 24)) {
+ if (WLCISLCNPHY(wlc_hw->band)) {
+ wlc_ucode_write(wlc_hw, bcm43xx_24_lcn,
+ bcm43xx_24_lcnsz);
+ wlc_hw->ucode_loaded = TRUE;
+ } else {
+ WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n",
+ __func__, wlc_hw->unit, wlc_hw->corerev));
+ }
+ }
+}
+
+static void
+BCMATTACHFN(wlc_ucode_write) (wlc_hw_info_t *wlc_hw, const uint32 ucode[],
+ const uint nbytes) {
+ osl_t *osh;
+ d11regs_t *regs = wlc_hw->regs;
+ uint i;
+ uint count;
+
+ osh = wlc_hw->osh;
+
+ WL_TRACE(("wl%d: wlc_ucode_write\n", wlc_hw->unit));
+
+ ASSERT(ISALIGNED(nbytes, sizeof(uint32)));
+
+ count = (nbytes / sizeof(uint32));
+
+ W_REG(osh, &regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
+ (void)R_REG(osh, &regs->objaddr);
+ for (i = 0; i < count; i++)
+ W_REG(osh, &regs->objdata, ucode[i]);
+}
+
+static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits)
+{
+ int i;
+ osl_t *osh;
+ volatile uint8 *base;
+
+ WL_TRACE(("wl%d: wlc_write_inits\n", wlc_hw->unit));
+
+ osh = wlc_hw->osh;
+ base = (volatile uint8 *)wlc_hw->regs;
+
+ for (i = 0; inits[i].addr != 0xffff; i++) {
+ ASSERT((inits[i].size == 2) || (inits[i].size == 4));
+
+ if (inits[i].size == 2)
+ W_REG(osh, (uint16 *) (uintptr) (base + inits[i].addr),
+ inits[i].value);
+ else if (inits[i].size == 4)
+ W_REG(osh, (uint32 *) (uintptr) (base + inits[i].addr),
+ inits[i].value);
+ }
+}
+
+static void wlc_ucode_txant_set(wlc_hw_info_t *wlc_hw)
+{
+ uint16 phyctl;
+ uint16 phytxant = wlc_hw->bmac_phytxant;
+ uint16 mask = PHY_TXC_ANT_MASK;
+
+ /* set the Probe Response frame phy control word */
+ phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
+ phyctl = (phyctl & ~mask) | phytxant;
+ wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
+
+ /* set the Response (ACK/CTS) frame phy control word */
+ phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD);
+ phyctl = (phyctl & ~mask) | phytxant;
+ wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
+}
+
+void wlc_bmac_txant_set(wlc_hw_info_t *wlc_hw, uint16 phytxant)
+{
+ /* update sw state */
+ wlc_hw->bmac_phytxant = phytxant;
+
+ /* push to ucode if up */
+ if (!wlc_hw->up)
+ return;
+ wlc_ucode_txant_set(wlc_hw);
+
+}
+
+uint16 wlc_bmac_get_txant(wlc_hw_info_t *wlc_hw)
+{
+ return (uint16) wlc_hw->wlc->stf->txant;
+}
+
+void wlc_bmac_antsel_type_set(wlc_hw_info_t *wlc_hw, uint8 antsel_type)
+{
+ wlc_hw->antsel_type = antsel_type;
+
+ /* Update the antsel type for phy module to use */
+ wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
+}
+
+void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw)
+{
+ bool fatal = FALSE;
+ uint unit;
+ uint intstatus, idx;
+ d11regs_t *regs = wlc_hw->regs;
+
+ unit = wlc_hw->unit;
+
+ for (idx = 0; idx < NFIFO; idx++) {
+ /* read intstatus register and ignore any non-error bits */
+ intstatus =
+ R_REG(wlc_hw->osh,
+ &regs->intctrlregs[idx].intstatus) & I_ERRORS;
+ if (!intstatus)
+ continue;
+
+ WL_TRACE(("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", unit,
+ idx, intstatus));
+
+ if (intstatus & I_RO) {
+ WL_ERROR(("wl%d: fifo %d: receive fifo overflow\n",
+ unit, idx));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo);
+ fatal = TRUE;
+ }
+
+ if (intstatus & I_PC) {
+ WL_ERROR(("wl%d: fifo %d: descriptor error\n", unit,
+ idx));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade);
+ fatal = TRUE;
+ }
+
+ if (intstatus & I_PD) {
+ WL_ERROR(("wl%d: fifo %d: data error\n", unit, idx));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada);
+ fatal = TRUE;
+ }
+
+ if (intstatus & I_DE) {
+ WL_ERROR(("wl%d: fifo %d: descriptor protocol error\n",
+ unit, idx));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape);
+ fatal = TRUE;
+ }
+
+ if (intstatus & I_RU) {
+ WL_ERROR(("wl%d: fifo %d: receive descriptor underflow\n", unit, idx));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]);
+ }
+
+ if (intstatus & I_XU) {
+ WL_ERROR(("wl%d: fifo %d: transmit fifo underflow\n",
+ idx, unit));
+ WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo);
+ fatal = TRUE;
+ }
+
+ if (fatal) {
+ wlc_fatal_error(wlc_hw->wlc); /* big hammer */
+ break;
+ } else
+ W_REG(wlc_hw->osh, &regs->intctrlregs[idx].intstatus,
+ intstatus);
+ }
+}
+
+void wlc_intrson(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ ASSERT(wlc->defmacintmask);
+ wlc->macintmask = wlc->defmacintmask;
+ W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask);
+}
+
+/* callback for siutils.c, which has only wlc handler, no wl
+ * they both check up, not only because there is no need to off/restore d11 interrupt
+ * but also because per-port code may require sync with valid interrupt.
+ */
+
+static uint32 wlc_wlintrsoff(wlc_info_t *wlc)
+{
+ if (!wlc->hw->up)
+ return 0;
+
+ return wl_intrsoff(wlc->wl);
+}
+
+static void wlc_wlintrsrestore(wlc_info_t *wlc, uint32 macintmask)
+{
+ if (!wlc->hw->up)
+ return;
+
+ wl_intrsrestore(wlc->wl, macintmask);
+}
+
+uint32 wlc_intrsoff(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ uint32 macintmask;
+
+ if (!wlc_hw->clk)
+ return 0;
+
+ macintmask = wlc->macintmask; /* isr can still happen */
+
+ W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0);
+ (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */
+ OSL_DELAY(1); /* ensure int line is no longer driven */
+ wlc->macintmask = 0;
+
+ /* return previous macintmask; resolve race between us and our isr */
+ return wlc->macintstatus ? 0 : macintmask;
+}
+
+void wlc_intrsrestore(wlc_info_t *wlc, uint32 macintmask)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ if (!wlc_hw->clk)
+ return;
+
+ wlc->macintmask = macintmask;
+ W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask);
+}
+
+void wlc_bmac_mute(wlc_hw_info_t *wlc_hw, bool on, mbool flags)
+{
+ struct ether_addr null_ether_addr = { {0, 0, 0, 0, 0, 0} };
+
+ if (on) {
+ /* suspend tx fifos */
+ wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
+ wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
+ wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
+ wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
+
+ /* zero the address match register so we do not send ACKs */
+ wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+ &null_ether_addr);
+ } else {
+ /* resume tx fifos */
+ if (!wlc_hw->wlc->tx_suspended) {
+ wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
+ }
+ wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
+ wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
+ wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
+
+ /* Restore address */
+ wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+ &wlc_hw->etheraddr);
+ }
+
+ wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
+
+ if (on)
+ wlc_ucode_mute_override_set(wlc_hw);
+ else
+ wlc_ucode_mute_override_clear(wlc_hw);
+}
+
+void wlc_bmac_set_deaf(wlc_hw_info_t *wlc_hw, bool user_flag)
+{
+ wlc_phy_set_deaf(wlc_hw->band->pi, user_flag);
+}
+
+int wlc_bmac_xmtfifo_sz_get(wlc_hw_info_t *wlc_hw, uint fifo, uint *blocks)
+{
+ if (fifo >= NFIFO)
+ return BCME_RANGE;
+
+ *blocks = wlc_hw->xmtfifo_sz[fifo];
+
+ return 0;
+}
+
+int wlc_bmac_xmtfifo_sz_set(wlc_hw_info_t *wlc_hw, uint fifo, uint blocks)
+{
+ if (fifo >= NFIFO || blocks > 299)
+ return BCME_RANGE;
+
+ /* BMAC_NOTE, change blocks to uint16 */
+ wlc_hw->xmtfifo_sz[fifo] = (uint16) blocks;
+
+ return 0;
+}
+
+/* wlc_bmac_tx_fifo_suspended:
+ * Check the MAC's tx suspend status for a tx fifo.
+ *
+ * When the MAC acknowledges a tx suspend, it indicates that no more
+ * packets will be transmitted out the radio. This is independent of
+ * DMA channel suspension---the DMA may have finished suspending, or may still
+ * be pulling data into a tx fifo, by the time the MAC acks the suspend
+ * request.
+ */
+bool wlc_bmac_tx_fifo_suspended(wlc_hw_info_t *wlc_hw, uint tx_fifo)
+{
+ /* check that a suspend has been requested and is no longer pending */
+
+ /*
+ * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine,
+ * and the tx fifo suspend at the lower end of the MAC is acknowledged in the
+ * chnstatus register.
+ * The tx fifo suspend completion is independent of the DMA suspend completion and
+ * may be acked before or after the DMA is suspended.
+ */
+ if (dma_txsuspended(wlc_hw->di[tx_fifo]) &&
+ (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) &
+ (1 << tx_fifo)) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+void wlc_bmac_tx_fifo_suspend(wlc_hw_info_t *wlc_hw, uint tx_fifo)
+{
+ uint8 fifo = 1 << tx_fifo;
+
+ /* Two clients of this code, 11h Quiet period and scanning. */
+
+ /* only suspend if not already suspended */
+ if ((wlc_hw->suspended_fifos & fifo) == fifo)
+ return;
+
+ /* force the core awake only if not already */
+ if (wlc_hw->suspended_fifos == 0)
+ wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO);
+
+ wlc_hw->suspended_fifos |= fifo;
+
+ if (wlc_hw->di[tx_fifo]) {
+ /* Suspending AMPDU transmissions in the middle can cause underflow
+ * which may result in mismatch between ucode and driver
+ * so suspend the mac before suspending the FIFO
+ */
+ if (WLC_PHY_11N_CAP(wlc_hw->band))
+ wlc_suspend_mac_and_wait(wlc_hw->wlc);
+
+ dma_txsuspend(wlc_hw->di[tx_fifo]);
+
+ if (WLC_PHY_11N_CAP(wlc_hw->band))
+ wlc_enable_mac(wlc_hw->wlc);
+ }
+}
+
+void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo)
+{
+ /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done
+ * here for PIO otherwise the watchdog will catch the inconsistency and fire
+ */
+ /* Two clients of this code, 11h Quiet period and scanning. */
+ if (wlc_hw->di[tx_fifo])
+ dma_txresume(wlc_hw->di[tx_fifo]);
+
+ /* allow core to sleep again */
+ if (wlc_hw->suspended_fifos == 0)
+ return;
+ else {
+ wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
+ if (wlc_hw->suspended_fifos == 0)
+ wlc_ucode_wake_override_clear(wlc_hw,
+ WLC_WAKE_OVERRIDE_TXFIFO);
+ }
+}
+
+/*
+ * Read and clear macintmask and macintstatus and intstatus registers.
+ * This routine should be called with interrupts off
+ * Return:
+ * -1 if DEVICEREMOVED(wlc) evaluates to TRUE;
+ * 0 if the interrupt is not for us, or we are in some special cases;
+ * device interrupt status bits otherwise.
+ */
+static INLINE uint32 wlc_intstatus(wlc_info_t *wlc, bool in_isr)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs = wlc_hw->regs;
+ uint32 macintstatus;
+ uint32 intstatus_rxfifo, intstatus_txsfifo;
+ osl_t *osh;
+
+ osh = wlc_hw->osh;
+
+ /* macintstatus includes a DMA interrupt summary bit */
+ macintstatus = R_REG(osh, &regs->macintstatus);
+
+ WL_TRACE(("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus));
+
+ /* detect cardbus removed, in power down(suspend) and in reset */
+ if (DEVICEREMOVED(wlc))
+ return -1;
+
+ /* DEVICEREMOVED succeeds even when the core is still resetting,
+ * handle that case here.
+ */
+ if (macintstatus == 0xffffffff)
+ return 0;
+
+ /* defer unsolicited interrupts */
+ macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
+
+ /* if not for us */
+ if (macintstatus == 0)
+ return 0;
+
+ /* interrupts are already turned off for CFE build
+ * Caution: For CFE Turning off the interrupts again has some undesired
+ * consequences
+ */
+ /* turn off the interrupts */
+ W_REG(osh, &regs->macintmask, 0);
+#ifndef BCMSDIO
+ (void)R_REG(osh, &regs->macintmask); /* sync readback */
+#endif
+ wlc->macintmask = 0;
+
+ /* clear device interrupts */
+ W_REG(osh, &regs->macintstatus, macintstatus);
+
+ /* MI_DMAINT is indication of non-zero intstatus */
+ if (macintstatus & MI_DMAINT) {
+ if (D11REV_IS(wlc_hw->corerev, 4)) {
+ intstatus_rxfifo =
+ R_REG(osh, &regs->intctrlregs[RX_FIFO].intstatus);
+ intstatus_txsfifo =
+ R_REG(osh,
+ &regs->intctrlregs[RX_TXSTATUS_FIFO].
+ intstatus);
+ WL_TRACE(("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", wlc_hw->unit, intstatus_rxfifo, intstatus_txsfifo));
+
+ /* defer unsolicited interrupt hints */
+ intstatus_rxfifo &= DEF_RXINTMASK;
+ intstatus_txsfifo &= DEF_RXINTMASK;
+
+ /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */
+ /* clear interrupt hints */
+ if (intstatus_rxfifo)
+ W_REG(osh,
+ &regs->intctrlregs[RX_FIFO].intstatus,
+ intstatus_rxfifo);
+ else
+ macintstatus &= ~MI_DMAINT;
+
+ /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */
+ if (intstatus_txsfifo) {
+ W_REG(osh,
+ &regs->intctrlregs[RX_TXSTATUS_FIFO].
+ intstatus, intstatus_txsfifo);
+ macintstatus |= MI_TFS;
+ }
+ } else {
+ /*
+ * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO.
+ * If MI_DMAINT is set, assume it is set and clear the interrupt.
+ */
+ W_REG(osh, &regs->intctrlregs[RX_FIFO].intstatus,
+ DEF_RXINTMASK);
+ }
+ }
+
+ return macintstatus;
+}
+
+/* Update wlc->macintstatus and wlc->intstatus[]. */
+/* Return TRUE if they are updated successfully. FALSE otherwise */
+bool wlc_intrsupd(wlc_info_t *wlc)
+{
+ uint32 macintstatus;
+
+ ASSERT(wlc->macintstatus != 0);
+
+ /* read and clear macintstatus and intstatus registers */
+ macintstatus = wlc_intstatus(wlc, FALSE);
+
+ /* device is removed */
+ if (macintstatus == 0xffffffff)
+ return FALSE;
+
+ /* update interrupt status in software */
+ wlc->macintstatus |= macintstatus;
+
+ return TRUE;
+}
+
+/*
+ * First-level interrupt processing.
+ * Return TRUE if this was our interrupt, FALSE otherwise.
+ * *wantdpc will be set to TRUE if further wlc_dpc() processing is required,
+ * FALSE otherwise.
+ */
+bool BCMFASTPATH wlc_isr(wlc_info_t *wlc, bool *wantdpc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ uint32 macintstatus;
+
+ *wantdpc = FALSE;
+
+ if (!wlc_hw->up || !wlc->macintmask)
+ return FALSE;
+
+ /* read and clear macintstatus and intstatus registers */
+ macintstatus = wlc_intstatus(wlc, TRUE);
+
+ if (macintstatus == 0xffffffff)
+ WL_ERROR(("DEVICEREMOVED detected in the ISR code path.\n"));
+
+ /* it is not for us */
+ if (macintstatus == 0)
+ return FALSE;
+
+ *wantdpc = TRUE;
+
+ /* save interrupt status bits */
+ ASSERT(wlc->macintstatus == 0);
+ wlc->macintstatus = macintstatus;
+
+ return TRUE;
+
+}
+
+/* process tx completion events for corerev < 5 */
+static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw)
+{
+ void *status_p;
+ tx_status_t *txs;
+ osl_t *osh;
+ bool fatal = FALSE;
+
+ WL_TRACE(("wl%d: wlc_txstatusrecv\n", wlc_hw->unit));
+
+ osh = wlc_hw->osh;
+
+ while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) {
+
+ txs = (tx_status_t *) PKTDATA(status_p);
+ /* MAC uses little endian only */
+ ltoh16_buf((void *)txs, sizeof(tx_status_t));
+
+ /* shift low bits for tx_status_t status compatibility */
+ txs->status = (txs->status & ~TXS_COMPAT_MASK)
+ | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT));
+
+ fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0);
+
+ PKTFREE(osh, status_p, FALSE);
+ }
+
+ if (fatal)
+ return TRUE;
+
+ /* post more rbufs */
+ dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]);
+
+ return FALSE;
+}
+
+static bool BCMFASTPATH
+wlc_bmac_dotxstatus(wlc_hw_info_t *wlc_hw, tx_status_t *txs, uint32 s2)
+{
+ /* discard intermediate indications for ucode with one legitimate case:
+ * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+ * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+ * transmission count)
+ */
+ if (!(txs->status & TX_STATUS_AMPDU)
+ && (txs->status & TX_STATUS_INTERMEDIATE)) {
+ return FALSE;
+ }
+
+ return wlc_dotxstatus(wlc_hw->wlc, txs, s2);
+}
+
+/* process tx completion events in BMAC
+ * Return TRUE if more tx status need to be processed. FALSE otherwise.
+ */
+static bool BCMFASTPATH
+wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal)
+{
+ bool morepending = FALSE;
+ wlc_info_t *wlc = wlc_hw->wlc;
+
+ WL_TRACE(("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit));
+
+ if (D11REV_IS(wlc_hw->corerev, 4)) {
+ /* to retire soon */
+ *fatal = wlc_bmac_txstatus_corerev4(wlc->hw);
+
+ if (*fatal)
+ return 0;
+ } else {
+ /* corerev >= 5 */
+ d11regs_t *regs;
+ osl_t *osh;
+ tx_status_t txstatus, *txs;
+ uint32 s1, s2;
+ uint n = 0;
+ /* Param 'max_tx_num' indicates max. # tx status to process before break out. */
+ uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1;
+
+ txs = &txstatus;
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+ while (!(*fatal)
+ && (s1 = R_REG(osh, &regs->frmtxstatus)) & TXS_V) {
+
+ if (s1 == 0xffffffff) {
+ WL_ERROR(("wl%d: %s: dead chip\n",
+ wlc_hw->unit, __func__));
+ ASSERT(s1 != 0xffffffff);
+ return morepending;
+ }
+
+ s2 = R_REG(osh, &regs->frmtxstatus2);
+
+ txs->status = s1 & TXS_STATUS_MASK;
+ txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
+ txs->sequence = s2 & TXS_SEQ_MASK;
+ txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
+ txs->lasttxtime = 0;
+
+ *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2);
+
+ /* !give others some time to run! */
+ if (++n >= max_tx_num)
+ break;
+ }
+
+ if (*fatal)
+ return 0;
+
+ if (n >= max_tx_num)
+ morepending = TRUE;
+ }
+
+ if (!pktq_empty(&wlc->active_queue->q))
+ wlc_send_q(wlc, wlc->active_queue);
+
+ return morepending;
+}
+
+void wlc_suspend_mac_and_wait(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs = wlc_hw->regs;
+ uint32 mc, mi;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", wlc_hw->unit,
+ wlc_hw->band->bandunit));
+
+ /*
+ * Track overlapping suspend requests
+ */
+ wlc_hw->mac_suspend_depth++;
+ if (wlc_hw->mac_suspend_depth > 1)
+ return;
+
+ osh = wlc_hw->osh;
+
+ /* force the core awake */
+ wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+
+ mc = R_REG(osh, &regs->maccontrol);
+
+ if (mc == 0xffffffff) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__));
+ wl_down(wlc->wl);
+ return;
+ }
+ ASSERT(!(mc & MCTL_PSM_JMP_0));
+ ASSERT(mc & MCTL_PSM_RUN);
+ ASSERT(mc & MCTL_EN_MAC);
+
+ mi = R_REG(osh, &regs->macintstatus);
+ if (mi == 0xffffffff) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__));
+ wl_down(wlc->wl);
+ return;
+ }
+ ASSERT(!(mi & MI_MACSSPNDD));
+
+ wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0);
+
+ SPINWAIT(!(R_REG(osh, &regs->macintstatus) & MI_MACSSPNDD),
+ WLC_MAX_MAC_SUSPEND);
+
+ if (!(R_REG(osh, &regs->macintstatus) & MI_MACSSPNDD)) {
+ WL_ERROR(("wl%d: wlc_suspend_mac_and_wait: waited %d uS and "
+ "MI_MACSSPNDD is still not on.\n",
+ wlc_hw->unit, WLC_MAX_MAC_SUSPEND));
+ WL_ERROR(("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", wlc_hw->unit, R_REG(osh, &regs->psmdebug), R_REG(osh, &regs->phydebug), R_REG(osh, &regs->psm_brc)));
+ }
+
+ mc = R_REG(osh, &regs->maccontrol);
+ if (mc == 0xffffffff) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__));
+ wl_down(wlc->wl);
+ return;
+ }
+ ASSERT(!(mc & MCTL_PSM_JMP_0));
+ ASSERT(mc & MCTL_PSM_RUN);
+ ASSERT(!(mc & MCTL_EN_MAC));
+}
+
+void wlc_enable_mac(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ d11regs_t *regs = wlc_hw->regs;
+ uint32 mc, mi;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: wlc_enable_mac: bandunit %d\n", wlc_hw->unit,
+ wlc->band->bandunit));
+
+ /*
+ * Track overlapping suspend requests
+ */
+ ASSERT(wlc_hw->mac_suspend_depth > 0);
+ wlc_hw->mac_suspend_depth--;
+ if (wlc_hw->mac_suspend_depth > 0)
+ return;
+
+ osh = wlc_hw->osh;
+
+ mc = R_REG(osh, &regs->maccontrol);
+ ASSERT(!(mc & MCTL_PSM_JMP_0));
+ ASSERT(!(mc & MCTL_EN_MAC));
+ ASSERT(mc & MCTL_PSM_RUN);
+
+ wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
+ W_REG(osh, &regs->macintstatus, MI_MACSSPNDD);
+
+ mc = R_REG(osh, &regs->maccontrol);
+ ASSERT(!(mc & MCTL_PSM_JMP_0));
+ ASSERT(mc & MCTL_EN_MAC);
+ ASSERT(mc & MCTL_PSM_RUN);
+
+ mi = R_REG(osh, &regs->macintstatus);
+ ASSERT(!(mi & MI_MACSSPNDD));
+
+ wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+}
+
+void wlc_bmac_ifsctl_edcrs_set(wlc_hw_info_t *wlc_hw, bool abie, bool isht)
+{
+ if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16))))
+ return;
+
+ if (isht) {
+ if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) {
+ AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ ~IFS_CTL1_EDCRS);
+ }
+ } else {
+ /* enable EDCRS for non-11n association */
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS);
+ }
+
+ if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) {
+ if (CHSPEC_IS20(wlc_hw->chanspec)) {
+ /* 20 mhz, use 20U ED only */
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ IFS_CTL1_EDCRS);
+ AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ ~IFS_CTL1_EDCRS_20L);
+ AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ ~IFS_CTL1_EDCRS_40);
+ } else {
+ /* 40 mhz, use 20U 20L and 40 ED */
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ IFS_CTL1_EDCRS);
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ IFS_CTL1_EDCRS_20L);
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1,
+ IFS_CTL1_EDCRS_40);
+ }
+ }
+}
+
+static void wlc_upd_ofdm_pctl1_table(wlc_hw_info_t *wlc_hw)
+{
+ uint8 rate;
+ uint8 rates[8] = {
+ WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M,
+ WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M
+ };
+ uint16 entry_ptr;
+ uint16 pctl1;
+ uint i;
+
+ if (!WLC_PHY_11N_CAP(wlc_hw->band))
+ return;
+
+ /* walk the phy rate table and update the entries */
+ for (i = 0; i < ARRAYSIZE(rates); i++) {
+ rate = rates[i];
+
+ entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate);
+
+ /* read the SHM Rate Table entry OFDM PCTL1 values */
+ pctl1 =
+ wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
+
+ /* modify the value */
+ pctl1 &= ~PHY_TXC1_MODE_MASK;
+ pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
+
+ /* Update the SHM Rate Table entry OFDM PCTL1 values */
+ wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
+ pctl1);
+ }
+}
+
+static uint16 wlc_bmac_ofdm_ratetable_offset(wlc_hw_info_t *wlc_hw, uint8 rate)
+{
+ uint i;
+ uint8 plcp_rate = 0;
+ struct plcp_signal_rate_lookup {
+ uint8 rate;
+ uint8 signal_rate;
+ };
+ /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
+ const struct plcp_signal_rate_lookup rate_lookup[] = {
+ {WLC_RATE_6M, 0xB},
+ {WLC_RATE_9M, 0xF},
+ {WLC_RATE_12M, 0xA},
+ {WLC_RATE_18M, 0xE},
+ {WLC_RATE_24M, 0x9},
+ {WLC_RATE_36M, 0xD},
+ {WLC_RATE_48M, 0x8},
+ {WLC_RATE_54M, 0xC}
+ };
+
+ for (i = 0; i < ARRAYSIZE(rate_lookup); i++) {
+ if (rate == rate_lookup[i].rate) {
+ plcp_rate = rate_lookup[i].signal_rate;
+ break;
+ }
+ }
+
+ /* Find the SHM pointer to the rate table entry by looking in the
+ * Direct-map Table
+ */
+ return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
+}
+
+void wlc_bmac_band_stf_ss_set(wlc_hw_info_t *wlc_hw, uint8 stf_mode)
+{
+ wlc_hw->hw_stf_ss_opmode = stf_mode;
+
+ if (wlc_hw->clk)
+ wlc_upd_ofdm_pctl1_table(wlc_hw);
+}
+
+void BCMFASTPATH
+wlc_bmac_read_tsf(wlc_hw_info_t *wlc_hw, uint32 *tsf_l_ptr,
+ uint32 *tsf_h_ptr)
+{
+ d11regs_t *regs = wlc_hw->regs;
+
+ /* read the tsf timer low, then high to get an atomic read */
+ *tsf_l_ptr = R_REG(wlc_hw->osh, &regs->tsf_timerlow);
+ *tsf_h_ptr = R_REG(wlc_hw->osh, &regs->tsf_timerhigh);
+
+ return;
+}
+
+bool BCMATTACHFN(wlc_bmac_validate_chip_access) (wlc_hw_info_t *wlc_hw)
+{
+ d11regs_t *regs;
+ uint32 w, val;
+ volatile uint16 *reg16;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: validate_chip_access\n", wlc_hw->unit));
+
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ /* Validate dchip register access */
+
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ w = R_REG(osh, &regs->objdata);
+
+ /* Can we write and read back a 32bit register? */
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, (uint32) 0xaa5555aa);
+
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ val = R_REG(osh, &regs->objdata);
+ if (val != (uint32) 0xaa5555aa) {
+ WL_ERROR(("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", wlc_hw->unit, val));
+ return FALSE;
+ }
+
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, (uint32) 0x55aaaa55);
+
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ val = R_REG(osh, &regs->objdata);
+ if (val != (uint32) 0x55aaaa55) {
+ WL_ERROR(("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", wlc_hw->unit, val));
+ return FALSE;
+ }
+
+ W_REG(osh, &regs->objaddr, OBJADDR_SHM_SEL | 0);
+ (void)R_REG(osh, &regs->objaddr);
+ W_REG(osh, &regs->objdata, w);
+
+ if (D11REV_LT(wlc_hw->corerev, 11)) {
+ /* if 32 bit writes are split into 16 bit writes, are they in the correct order
+ * for our interface, low to high
+ */
+ reg16 = (volatile uint16 *)(uintptr) & regs->tsf_cfpstart;
+
+ /* write the CFPStart register low half explicitly, starting a buffered write */
+ W_REG(osh, reg16, 0xAAAA);
+
+ /* Write a 32 bit value to CFPStart to test the 16 bit split order.
+ * If the low 16 bits are written first, followed by the high 16 bits then the
+ * 32 bit value 0xCCCCBBBB should end up in the register.
+ * If the order is reversed, then the write to the high half will trigger a buffered
+ * write of 0xCCCCAAAA.
+ * If the bus is 32 bits, then this is not much of a test, and the reg should
+ * have the correct value 0xCCCCBBBB.
+ */
+ W_REG(osh, &regs->tsf_cfpstart, 0xCCCCBBBB);
+
+ /* verify with the 16 bit registers that have no side effects */
+ val = R_REG(osh, &regs->tsf_cfpstrt_l);
+ if (val != (uint) 0xBBBB) {
+ WL_ERROR(("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected" " 0x%x\n", wlc_hw->unit, val, 0xBBBB));
+ return FALSE;
+ }
+ val = R_REG(osh, &regs->tsf_cfpstrt_h);
+ if (val != (uint) 0xCCCC) {
+ WL_ERROR(("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected" " 0x%x\n", wlc_hw->unit, val, 0xCCCC));
+ return FALSE;
+ }
+
+ }
+
+ /* clear CFPStart */
+ W_REG(osh, &regs->tsf_cfpstart, 0);
+
+ w = R_REG(osh, &regs->maccontrol);
+ if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
+ (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
+ WL_ERROR(("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, (MCTL_IHR_EN | MCTL_WAKE), (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#define PHYPLL_WAIT_US 100000
+
+void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on)
+{
+ d11regs_t *regs;
+ osl_t *osh;
+ uint32 tmp;
+
+ WL_TRACE(("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit));
+
+ tmp = 0;
+ regs = wlc_hw->regs;
+ osh = wlc_hw->osh;
+
+ if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20))
+ return;
+
+ if (on) {
+ if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
+ OR_REG(osh, &regs->clk_ctl_st,
+ (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
+ CCS_ERSRC_REQ_PHYPLL));
+ SPINWAIT((R_REG(osh, &regs->clk_ctl_st) &
+ (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
+ PHYPLL_WAIT_US);
+
+ tmp = R_REG(osh, &regs->clk_ctl_st);
+ if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
+ (CCS_ERSRC_AVAIL_HT)) {
+ WL_ERROR(("%s: turn on PHY PLL failed\n",
+ __func__));
+ ASSERT(0);
+ }
+ } else {
+ OR_REG(osh, &regs->clk_ctl_st,
+ (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
+ SPINWAIT((R_REG(osh, &regs->clk_ctl_st) &
+ (CCS_ERSRC_AVAIL_D11PLL |
+ CCS_ERSRC_AVAIL_PHYPLL)) !=
+ (CCS_ERSRC_AVAIL_D11PLL |
+ CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
+
+ tmp = R_REG(osh, &regs->clk_ctl_st);
+ if ((tmp &
+ (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
+ !=
+ (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) {
+ WL_ERROR(("%s: turn on PHY PLL failed\n",
+ __func__));
+ ASSERT(0);
+ }
+ }
+ } else {
+ /* Since the PLL may be shared, other cores can still be requesting it;
+ * so we'll deassert the request but not wait for status to comply.
+ */
+ AND_REG(osh, &regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
+ tmp = R_REG(osh, &regs->clk_ctl_st);
+ }
+}
+
+void wlc_coredisable(wlc_hw_info_t *wlc_hw)
+{
+ bool dev_gone;
+
+ WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__));
+
+ ASSERT(!wlc_hw->up);
+
+ dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+
+ if (dev_gone)
+ return;
+
+ if (wlc_hw->noreset)
+ return;
+
+ /* radio off */
+ wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+
+ /* turn off analog core */
+ wlc_phy_anacore(wlc_hw->band->pi, OFF);
+
+ /* turn off PHYPLL to save power */
+ wlc_bmac_core_phypll_ctl(wlc_hw, FALSE);
+
+ /* No need to set wlc->pub->radio_active = OFF
+ * because this function needs down capability and
+ * radio_active is designed for BCMNODOWN.
+ */
+
+ /* remove gpio controls */
+ if (wlc_hw->ucode_dbgsel)
+ si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
+
+ wlc_hw->clk = FALSE;
+ si_core_disable(wlc_hw->sih, 0);
+ wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, FALSE);
+}
+
+/* power both the pll and external oscillator on/off */
+void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want)
+{
+ WL_TRACE(("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want));
+
+ /* dont power down if plldown is false or we must poll hw radio disable */
+ if (!want && wlc_hw->pllreq)
+ return;
+
+ if (wlc_hw->sih)
+ si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
+
+ wlc_hw->sbclk = want;
+ if (!wlc_hw->sbclk) {
+ wlc_hw->clk = FALSE;
+ if (wlc_hw->band && wlc_hw->band->pi)
+ wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, FALSE);
+ }
+}
+
+static void wlc_flushqueues(wlc_info_t *wlc)
+{
+ wlc_hw_info_t *wlc_hw = wlc->hw;
+ uint i;
+
+ wlc->txpend16165war = 0;
+
+ /* free any posted tx packets */
+ for (i = 0; i < NFIFO; i++)
+ if (wlc_hw->di[i]) {
+ dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL);
+ TXPKTPENDCLR(wlc, i);
+ WL_TRACE(("wlc_flushqueues: pktpend fifo %d cleared\n",
+ i));
+ }
+
+ /* free any posted rx packets */
+ dma_rxreclaim(wlc_hw->di[RX_FIFO]);
+ if (D11REV_IS(wlc_hw->corerev, 4))
+ dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]);
+}
+
+uint16 wlc_bmac_read_shm(wlc_hw_info_t *wlc_hw, uint offset)
+{
+ return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
+}
+
+void wlc_bmac_write_shm(wlc_hw_info_t *wlc_hw, uint offset, uint16 v)
+{
+ wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
+}
+
+/* Set a range of shared memory to a value.
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ */
+void wlc_bmac_set_shm(wlc_hw_info_t *wlc_hw, uint offset, uint16 v, int len)
+{
+ int i;
+
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len; i += 2) {
+ wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL);
+ }
+}
+
+static uint16
+wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset, uint32 sel)
+{
+ d11regs_t *regs = wlc_hw->regs;
+ volatile uint16 *objdata_lo =
+ (volatile uint16 *)(uintptr) & regs->objdata;
+ volatile uint16 *objdata_hi = objdata_lo + 1;
+ uint16 v;
+
+ ASSERT((offset & 1) == 0);
+
+ W_REG(wlc_hw->osh, &regs->objaddr, sel | (offset >> 2));
+ (void)R_REG(wlc_hw->osh, &regs->objaddr);
+ if (offset & 2) {
+ v = R_REG(wlc_hw->osh, objdata_hi);
+ } else {
+ v = R_REG(wlc_hw->osh, objdata_lo);
+ }
+
+ return v;
+}
+
+static void
+wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, uint16 v, uint32 sel)
+{
+ d11regs_t *regs = wlc_hw->regs;
+ volatile uint16 *objdata_lo =
+ (volatile uint16 *)(uintptr) & regs->objdata;
+ volatile uint16 *objdata_hi = objdata_lo + 1;
+
+ ASSERT((offset & 1) == 0);
+
+ W_REG(wlc_hw->osh, &regs->objaddr, sel | (offset >> 2));
+ (void)R_REG(wlc_hw->osh, &regs->objaddr);
+ if (offset & 2) {
+ W_REG(wlc_hw->osh, objdata_hi, v);
+ } else {
+ W_REG(wlc_hw->osh, objdata_lo, v);
+ }
+}
+
+/* Copy a buffer to shared memory of specified type .
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ * 'sel' selects the type of memory
+ */
+void
+wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw, uint offset, const void *buf,
+ int len, uint32 sel)
+{
+ uint16 v;
+ const uint8 *p = (const uint8 *)buf;
+ int i;
+
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len; i += 2) {
+ v = p[i] | (p[i + 1] << 8);
+ wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel);
+ }
+}
+
+/* Copy a piece of shared memory of specified type to a buffer .
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ * 'sel' selects the type of memory
+ */
+void
+wlc_bmac_copyfrom_objmem(wlc_hw_info_t *wlc_hw, uint offset, void *buf,
+ int len, uint32 sel)
+{
+ uint16 v;
+ uint8 *p = (uint8 *) buf;
+ int i;
+
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len; i += 2) {
+ v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel);
+ p[i] = v & 0xFF;
+ p[i + 1] = (v >> 8) & 0xFF;
+ }
+}
+
+void wlc_bmac_copyfrom_vars(wlc_hw_info_t *wlc_hw, char **buf, uint *len)
+{
+ WL_TRACE(("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n",
+ wlc_hw->vars_size));
+
+ *buf = wlc_hw->vars;
+ *len = wlc_hw->vars_size;
+}
+
+void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, uint16 SRL, uint16 LRL)
+{
+ wlc_hw->SRL = SRL;
+ wlc_hw->LRL = LRL;
+
+ /* write retry limit to SCR, shouldn't need to suspend */
+ if (wlc_hw->up) {
+ W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr,
+ OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+ (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr);
+ W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL);
+ W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr,
+ OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+ (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr);
+ W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL);
+ }
+}
+
+void wlc_bmac_set_noreset(wlc_hw_info_t *wlc_hw, bool noreset_flag)
+{
+ wlc_hw->noreset = noreset_flag;
+}
+
+void wlc_bmac_set_ucode_loaded(wlc_hw_info_t *wlc_hw, bool ucode_loaded)
+{
+ wlc_hw->ucode_loaded = ucode_loaded;
+}
+
+void wlc_bmac_pllreq(wlc_hw_info_t *wlc_hw, bool set, mbool req_bit)
+{
+ ASSERT(req_bit);
+
+ if (set) {
+ if (mboolisset(wlc_hw->pllreq, req_bit))
+ return;
+
+ mboolset(wlc_hw->pllreq, req_bit);
+
+ if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+ if (!wlc_hw->sbclk) {
+ wlc_bmac_xtal(wlc_hw, ON);
+ }
+ }
+ } else {
+ if (!mboolisset(wlc_hw->pllreq, req_bit))
+ return;
+
+ mboolclr(wlc_hw->pllreq, req_bit);
+
+ if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+ if (wlc_hw->sbclk) {
+ wlc_bmac_xtal(wlc_hw, OFF);
+ }
+ }
+ }
+
+ return;
+}
+
+void wlc_bmac_set_clk(wlc_hw_info_t *wlc_hw, bool on)
+{
+ if (on) {
+ /* power up pll and oscillator */
+ wlc_bmac_xtal(wlc_hw, ON);
+
+ /* enable core(s), ignore bandlocked
+ * Leave with the same band selected as we entered
+ */
+ wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+ } else {
+ /* if already down, must skip the core disable */
+ if (wlc_hw->clk) {
+ /* disable core(s), ignore bandlocked */
+ wlc_coredisable(wlc_hw);
+ }
+ /* power down pll and oscillator */
+ wlc_bmac_xtal(wlc_hw, OFF);
+ }
+}
+
+/* this will be true for all ai chips */
+bool wlc_bmac_taclear(wlc_hw_info_t *wlc_hw, bool ta_ok)
+{
+ return TRUE;
+}
+
+/* Lower down relevant GPIOs like LED when going down w/o
+ * doing PCI config cycles or touching interrupts
+ */
+void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw)
+{
+ if ((wlc_hw == NULL) || (wlc_hw->sih == NULL))
+ return;
+
+ /* Only chips with internal bus or PCIE cores or certain PCI cores
+ * are able to switch cores w/o disabling interrupts
+ */
+ if (!((BUSTYPE(wlc_hw->sih->bustype) == SI_BUS) ||
+ ((BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) &&
+ ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) ||
+ (wlc_hw->sih->buscorerev >= 13)))))
+ return;
+
+ WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__));
+ return;
+}
+
+bool wlc_bmac_radio_hw(wlc_hw_info_t *wlc_hw, bool enable)
+{
+ /* Do not access Phy registers if core is not up */
+ if (si_iscoreup(wlc_hw->sih) == FALSE)
+ return FALSE;
+
+ if (enable) {
+ if (PMUCTL_ENAB(wlc_hw->sih)) {
+ AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st,
+ ~CCS_FORCEHWREQOFF);
+ si_pmu_radio_enable(wlc_hw->sih, TRUE);
+ }
+
+ wlc_phy_anacore(wlc_hw->band->pi, ON);
+ wlc_phy_switch_radio(wlc_hw->band->pi, ON);
+
+ /* resume d11 core */
+ wlc_enable_mac(wlc_hw->wlc);
+ } else {
+ /* suspend d11 core */
+ wlc_suspend_mac_and_wait(wlc_hw->wlc);
+
+ wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+ wlc_phy_anacore(wlc_hw->band->pi, OFF);
+
+ if (PMUCTL_ENAB(wlc_hw->sih)) {
+ si_pmu_radio_enable(wlc_hw->sih, FALSE);
+ OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st,
+ CCS_FORCEHWREQOFF);
+ }
+ }
+
+ return TRUE;
+}
+
+uint16 wlc_bmac_rate_shm_offset(wlc_hw_info_t *wlc_hw, uint8 rate)
+{
+ uint16 table_ptr;
+ uint8 phy_rate, index;
+
+ /* get the phy specific rate encoding for the PLCP SIGNAL field */
+ /* XXX4321 fixup needed ? */
+ if (IS_OFDM(rate))
+ table_ptr = M_RT_DIRMAP_A;
+ else
+ table_ptr = M_RT_DIRMAP_B;
+
+ /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
+ * the index into the rate table.
+ */
+ phy_rate = rate_info[rate] & RATE_MASK;
+ index = phy_rate & 0xf;
+
+ /* Find the SHM pointer to the rate table entry by looking in the
+ * Direct-map Table
+ */
+ return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2));
+}
+
+void wlc_bmac_set_txpwr_percent(wlc_hw_info_t *wlc_hw, uint8 val)
+{
+ wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val);
+}
+
+void wlc_bmac_antsel_set(wlc_hw_info_t *wlc_hw, uint32 antsel_avail)
+{
+ wlc_hw->antsel_avail = antsel_avail;
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h
new file mode 100644
index 000000000000..e389cbecd70d
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_bmac.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+/* XXXXX this interface is under wlc.c by design
+ * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign
+ *
+ * high driver files(e.g. wlc_ampdu.c etc)
+ * wlc.h/wlc.c
+ * wlc_bmac.h/wlc_bmac.c
+ *
+ * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c
+ * create wrappers in wlc.c if needed
+ */
+
+/* Revision and other info required from BMAC driver for functioning of high ONLY driver */
+typedef struct wlc_bmac_revinfo {
+ uint vendorid; /* PCI vendor id */
+ uint deviceid; /* device id of chip */
+
+ uint boardrev; /* version # of particular board */
+ uint corerev; /* core revision */
+ uint sromrev; /* srom revision */
+ uint chiprev; /* chip revision */
+ uint chip; /* chip number */
+ uint chippkg; /* chip package */
+ uint boardtype; /* board type */
+ uint boardvendor; /* board vendor */
+ uint bustype; /* SB_BUS, PCI_BUS */
+ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+ uint buscorerev; /* buscore rev */
+ uint32 issim; /* chip is in simulation or emulation */
+
+ uint nbands;
+
+ struct band_info {
+ uint bandunit; /* To match on both sides */
+ uint bandtype; /* To match on both sides */
+ uint radiorev;
+ uint phytype;
+ uint phyrev;
+ uint anarev;
+ uint radioid;
+ bool abgphy_encore;
+ } band[MAXBANDS];
+} wlc_bmac_revinfo_t;
+
+/* dup state between BMAC(wlc_hw_info_t) and HIGH(wlc_info_t) driver */
+typedef struct wlc_bmac_state {
+ uint32 machwcap; /* mac hw capibility */
+ uint32 preamble_ovr; /* preamble override */
+} wlc_bmac_state_t;
+
+enum {
+ IOV_BMAC_DIAG,
+ IOV_BMAC_SBGPIOTIMERVAL,
+ IOV_BMAC_SBGPIOOUT,
+ IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */
+ IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */
+ IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */
+ IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */
+ IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */
+ IOV_BMAC_OTPDUMP,
+ IOV_BMAC_OTPSTAT,
+ IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */
+ IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */
+ IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */
+ IOV_BMAC_PCIELCREG, /* PCIE LCREG */
+ IOV_BMAC_SBGPIOTIMERMASK,
+ IOV_BMAC_RFDISABLEDLY,
+ IOV_BMAC_PCIEREG, /* PCIE REG */
+ IOV_BMAC_PCICFGREG, /* PCI Config register */
+ IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */
+ IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */
+ IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */
+ IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */
+ IOV_BMAC_DMALPBK,
+ IOV_BMAC_CCREG,
+ IOV_BMAC_COREREG,
+ IOV_BMAC_SDCIS,
+ IOV_BMAC_SDIO_DRIVE,
+ IOV_BMAC_OTPW,
+ IOV_BMAC_NVOTPW,
+ IOV_BMAC_SROM,
+ IOV_BMAC_SRCRC,
+ IOV_BMAC_CIS_SOURCE,
+ IOV_BMAC_CISVAR,
+ IOV_BMAC_OTPLOCK,
+ IOV_BMAC_OTP_CHIPID,
+ IOV_BMAC_CUSTOMVAR1,
+ IOV_BMAC_BOARDFLAGS,
+ IOV_BMAC_BOARDFLAGS2,
+ IOV_BMAC_WPSLED,
+ IOV_BMAC_NVRAM_SOURCE,
+ IOV_BMAC_OTP_RAW_READ,
+ IOV_BMAC_LAST
+};
+
+typedef enum {
+ BMAC_DUMP_GPIO_ID,
+ BMAC_DUMP_SI_ID,
+ BMAC_DUMP_SIREG_ID,
+ BMAC_DUMP_SICLK_ID,
+ BMAC_DUMP_CCREG_ID,
+ BMAC_DUMP_PCIEREG_ID,
+ BMAC_DUMP_PHYREG_ID,
+ BMAC_DUMP_PHYTBL_ID,
+ BMAC_DUMP_PHYTBL2_ID,
+ BMAC_DUMP_PHY_RADIOREG_ID,
+ BMAC_DUMP_LAST
+} wlc_bmac_dump_id_t;
+
+typedef enum {
+ WLCHW_STATE_ATTACH,
+ WLCHW_STATE_CLK,
+ WLCHW_STATE_UP,
+ WLCHW_STATE_ASSOC,
+ WLCHW_STATE_LAST
+} wlc_bmac_state_id_t;
+
+extern int wlc_bmac_attach(wlc_info_t *wlc, uint16 vendor, uint16 device,
+ uint unit, bool piomode, osl_t *osh, void *regsva,
+ uint bustype, void *btparam);
+extern int wlc_bmac_detach(wlc_info_t *wlc);
+extern void wlc_bmac_watchdog(void *arg);
+extern void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw);
+
+/* up/down, reset, clk */
+#ifdef WLC_LOW
+extern void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want);
+#endif
+
+extern void wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw,
+ uint offset, const void *buf, int len,
+ uint32 sel);
+extern void wlc_bmac_copyfrom_objmem(wlc_hw_info_t *wlc_hw, uint offset,
+ void *buf, int len, uint32 sel);
+#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \
+ wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \
+ wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+
+extern void wlc_bmac_core_phy_clk(wlc_hw_info_t *wlc_hw, bool clk);
+extern void wlc_bmac_core_phypll_reset(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on);
+extern void wlc_bmac_phyclk_fgc(wlc_hw_info_t *wlc_hw, bool clk);
+extern void wlc_bmac_macphyclk_set(wlc_hw_info_t *wlc_hw, bool clk);
+extern void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, uint32 flags);
+extern void wlc_bmac_reset(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_init(wlc_hw_info_t *wlc_hw, chanspec_t chanspec,
+ bool mute);
+extern int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw);
+extern int wlc_bmac_up_finish(wlc_hw_info_t *wlc_hw);
+extern int wlc_bmac_down_prep(wlc_hw_info_t *wlc_hw);
+extern int wlc_bmac_down_finish(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, uint32 flags);
+extern void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, uint8 spurmode);
+
+/* chanspec, ucode interface */
+extern int wlc_bmac_bandtype(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_set_chanspec(wlc_hw_info_t *wlc_hw, chanspec_t chanspec,
+ bool mute, struct txpwr_limits *txpwr);
+
+extern void wlc_bmac_txfifo(wlc_hw_info_t *wlc_hw, uint fifo, void *p,
+ bool commit, uint16 frameid, uint8 txpktpend);
+extern int wlc_bmac_xmtfifo_sz_get(wlc_hw_info_t *wlc_hw, uint fifo,
+ uint *blocks);
+extern void wlc_bmac_mhf(wlc_hw_info_t *wlc_hw, uint8 idx, uint16 mask,
+ uint16 val, int bands);
+extern void wlc_bmac_mctrl(wlc_hw_info_t *wlc_hw, uint32 mask, uint32 val);
+extern uint16 wlc_bmac_mhf_get(wlc_hw_info_t *wlc_hw, uint8 idx, int bands);
+extern int wlc_bmac_xmtfifo_sz_set(wlc_hw_info_t *wlc_hw, uint fifo,
+ uint blocks);
+extern void wlc_bmac_txant_set(wlc_hw_info_t *wlc_hw, uint16 phytxant);
+extern uint16 wlc_bmac_get_txant(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_antsel_type_set(wlc_hw_info_t *wlc_hw, uint8 antsel_type);
+extern int wlc_bmac_revinfo_get(wlc_hw_info_t *wlc_hw,
+ wlc_bmac_revinfo_t *revinfo);
+extern int wlc_bmac_state_get(wlc_hw_info_t *wlc_hw, wlc_bmac_state_t *state);
+extern void wlc_bmac_write_shm(wlc_hw_info_t *wlc_hw, uint offset, uint16 v);
+extern uint16 wlc_bmac_read_shm(wlc_hw_info_t *wlc_hw, uint offset);
+extern void wlc_bmac_set_shm(wlc_hw_info_t *wlc_hw, uint offset, uint16 v,
+ int len);
+extern void wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset,
+ int len, void *buf);
+extern void wlc_bmac_copyfrom_vars(wlc_hw_info_t *wlc_hw, char **buf,
+ uint *len);
+
+extern void wlc_bmac_process_ps_switch(wlc_hw_info_t *wlc,
+ struct ether_addr *ea, int8 ps_on);
+extern void wlc_bmac_hw_etheraddr(wlc_hw_info_t *wlc_hw,
+ struct ether_addr *ea);
+extern void wlc_bmac_set_hw_etheraddr(wlc_hw_info_t *wlc_hw,
+ struct ether_addr *ea);
+extern bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw);
+
+extern bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw);
+extern void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot);
+extern void wlc_bmac_mute(wlc_hw_info_t *wlc_hw, bool want, mbool flags);
+extern void wlc_bmac_set_deaf(wlc_hw_info_t *wlc_hw, bool user_flag);
+extern void wlc_bmac_band_stf_ss_set(wlc_hw_info_t *wlc_hw, uint8 stf_mode);
+
+extern void wlc_bmac_wait_for_wake(wlc_hw_info_t *wlc_hw);
+extern bool wlc_bmac_tx_fifo_suspended(wlc_hw_info_t *wlc_hw, uint tx_fifo);
+extern void wlc_bmac_tx_fifo_suspend(wlc_hw_info_t *wlc_hw, uint tx_fifo);
+extern void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo);
+
+extern void wlc_ucode_wake_override_set(wlc_hw_info_t *wlc_hw,
+ uint32 override_bit);
+extern void wlc_ucode_wake_override_clear(wlc_hw_info_t *wlc_hw,
+ uint32 override_bit);
+
+extern void wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx,
+ const struct ether_addr *addr);
+extern void wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset,
+ const struct ether_addr *addr);
+extern void wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn,
+ int len, bool both);
+
+extern void wlc_bmac_read_tsf(wlc_hw_info_t *wlc_hw, uint32 *tsf_l_ptr,
+ uint32 *tsf_h_ptr);
+extern void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, uint16 newmin);
+extern void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, uint16 newmax);
+extern void wlc_bmac_set_noreset(wlc_hw_info_t *wlc, bool noreset_flag);
+extern void wlc_bmac_set_ucode_loaded(wlc_hw_info_t *wlc, bool ucode_loaded);
+
+extern void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, uint16 SRL,
+ uint16 LRL);
+
+extern void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw);
+
+#ifdef WLC_HIGH_ONLY
+extern void wlc_bmac_dngl_reboot(rpc_info_t *);
+extern void wlc_bmac_dngl_rpc_agg(rpc_info_t *, uint16 agg);
+extern void wlc_bmac_dngl_rpc_msglevel(rpc_info_t *, uint16 level);
+extern void wlc_bmac_dngl_rpc_txq_wm_set(rpc_info_t *rpc, uint32 wm);
+extern void wlc_bmac_dngl_rpc_txq_wm_get(rpc_info_t *rpc, uint32 *wm);
+extern void wlc_bmac_dngl_rpc_agg_limit_set(rpc_info_t *rpc, uint32 val);
+extern void wlc_bmac_dngl_rpc_agg_limit_get(rpc_info_t *rpc, uint32 *pval);
+extern int wlc_bmac_debug_template(wlc_hw_info_t *wlc_hw);
+#endif
+
+/* API for BMAC driver (e.g. wlc_phy.c etc) */
+
+extern void wlc_bmac_bw_set(wlc_hw_info_t *wlc_hw, uint16 bw);
+extern void wlc_bmac_pllreq(wlc_hw_info_t *wlc_hw, bool set, mbool req_bit);
+extern void wlc_bmac_set_clk(wlc_hw_info_t *wlc_hw, bool on);
+extern bool wlc_bmac_taclear(wlc_hw_info_t *wlc_hw, bool ta_ok);
+extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw);
+
+extern void wlc_bmac_dump(wlc_hw_info_t *wlc_hw, struct bcmstrbuf *b,
+ wlc_bmac_dump_id_t dump_id);
+extern void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw);
+
+extern bool wlc_bmac_radio_hw(wlc_hw_info_t *wlc_hw, bool enable);
+extern uint16 wlc_bmac_rate_shm_offset(wlc_hw_info_t *wlc_hw, uint8 rate);
+
+extern void wlc_bmac_assert_type_set(wlc_hw_info_t *wlc_hw, uint32 type);
+extern void wlc_bmac_set_txpwr_percent(wlc_hw_info_t *wlc_hw, uint8 val);
+extern void wlc_bmac_blink_sync(wlc_hw_info_t *wlc_hw, uint32 led_pins);
+extern void wlc_bmac_ifsctl_edcrs_set(wlc_hw_info_t *wlc_hw, bool abie,
+ bool isht);
+
+extern void wlc_bmac_antsel_set(wlc_hw_info_t *wlc_hw, uint32 antsel_avail);
diff --git a/drivers/staging/brcm80211/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/sys/wlc_bsscfg.h
new file mode 100644
index 000000000000..af0886de55fe
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_bsscfg.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _WLC_BSSCFG_H_
+#define _WLC_BSSCFG_H_
+
+#include <wlc_types.h>
+
+/* Check if a particular BSS config is AP or STA */
+#define BSSCFG_AP(cfg) (0)
+#define BSSCFG_STA(cfg) (1)
+
+#define BSSCFG_IBSS(cfg) (!(cfg)->BSS)
+
+/* forward declarations */
+typedef struct wlc_bsscfg wlc_bsscfg_t;
+
+#include <wlc_rate.h>
+
+#define NTXRATE 64 /* # tx MPDUs rate is reported for */
+#define MAXMACLIST 64 /* max # source MAC matches */
+#define BCN_TEMPLATE_COUNT 2
+
+/* Iterator for "associated" STA bss configs: (wlc_info_t *wlc, int idx, wlc_bsscfg_t *cfg) */
+#define FOREACH_AS_STA(wlc, idx, cfg) \
+ for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+ if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated)
+
+/* As above for all non-NULL BSS configs */
+#define FOREACH_BSS(wlc, idx, cfg) \
+ for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+ if ((cfg = (wlc)->bsscfg[idx]))
+
+/* BSS configuration state */
+struct wlc_bsscfg {
+ struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */
+ bool up; /* is this configuration up operational */
+ bool enable; /* is this configuration enabled */
+ bool associated; /* is BSS in ASSOCIATED state */
+ bool BSS; /* infraustructure or adhac */
+ bool dtim_programmed;
+#ifdef LATER
+ bool _ap; /* is this configuration an AP */
+ struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */
+ void *sup; /* pointer to supplicant state */
+ int8 sup_type; /* type of supplicant */
+ bool sup_enable_wpa; /* supplicant WPA on/off */
+ void *authenticator; /* pointer to authenticator state */
+ bool sup_auth_pending; /* flag for auth timeout */
+#endif
+ uint8 SSID_len; /* the length of SSID */
+ uint8 SSID[DOT11_MAX_SSID_LEN]; /* SSID string */
+ struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */
+ int8 _idx; /* the index of this bsscfg,
+ * assigned at wlc_bsscfg_alloc()
+ */
+ /* MAC filter */
+ uint nmac; /* # of entries on maclist array */
+ int macmode; /* allow/deny stations on maclist array */
+ struct ether_addr *maclist; /* list of source MAC addrs to match */
+
+ /* security */
+ uint32 wsec; /* wireless security bitvec */
+ int16 auth; /* 802.11 authentication: Open, Shared Key, WPA */
+ int16 openshared; /* try Open auth first, then Shared Key */
+ bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */
+ bool eap_restrict; /* restrict data until 802.1X auth succeeds */
+ uint16 WPA_auth; /* WPA: authenticated key management */
+ bool wpa2_preauth; /* default is TRUE, wpa_cap sets value */
+ bool wsec_portopen; /* indicates keys are plumbed */
+ wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */
+ int wsec_index; /* 0-3: default tx key, -1: not set */
+ wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */
+
+ /* TKIP countermeasures */
+ bool tkip_countermeasures; /* flags TKIP no-assoc period */
+ uint32 tk_cm_dt; /* detect timer */
+ uint32 tk_cm_bt; /* blocking timer */
+ uint32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */
+ bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */
+
+ struct ether_addr BSSID; /* BSSID (associated) */
+ struct ether_addr cur_etheraddr; /* h/w address */
+ uint16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */
+ uint16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */
+
+ uint32 flags; /* WLC_BSSCFG flags; see below */
+
+ uint8 *bcn; /* AP beacon */
+ uint bcn_len; /* AP beacon length */
+ bool ar_disassoc; /* disassociated in associated recreation */
+
+ int auth_atmptd; /* auth type (open/shared) attempted */
+
+ pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */
+ uint npmkid_cand; /* num PMKID candidates */
+ pmkid_t pmkid[MAXPMKID]; /* PMKID cache */
+ uint npmkid; /* num cached PMKIDs */
+
+ wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */
+ wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */
+
+ /* PM states */
+ bool PMawakebcn; /* bcn recvd during current waking state */
+ bool PMpending; /* waiting for tx status with PM indicated set */
+ bool priorPMstate; /* Detecting PM state transitions */
+ bool PSpoll; /* whether there is an outstanding PS-Poll frame */
+
+ /* BSSID entry in RCMTA, use the wsec key management infrastructure to
+ * manage the RCMTA entries.
+ */
+ wsec_key_t *rcmta;
+
+ /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */
+ uint16 ID;
+
+ uint txrspecidx; /* index into tx rate circular buffer */
+ ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */
+};
+
+#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */
+#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */
+
+#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0)
+#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0)
+
+extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg);
+
+/* Extend N_ENAB to per-BSS */
+#define BSS_N_ENAB(wlc, cfg) \
+ (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE))
+
+#define MBSS_BCN_ENAB(cfg) 0
+#define MBSS_PRB_ENAB(cfg) 0
+#define SOFTBCN_ENAB(pub) (0)
+#define SOFTPRB_ENAB(pub) (0)
+#define wlc_bsscfg_tx_check(a) do { } while (0);
+
+#endif /* _WLC_BSSCFG_H_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_cfg.h b/drivers/staging/brcm80211/sys/wlc_cfg.h
new file mode 100644
index 000000000000..a415e1fd2c05
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_cfg.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_cfg_h_
+#define _wlc_cfg_h_
+
+#define NBANDS(wlc) ((wlc)->pub->_nbands)
+#define NBANDS_PUB(pub) ((pub)->_nbands)
+#define NBANDS_HW(hw) ((hw)->_nbands)
+
+#define IS_SINGLEBAND_5G(device) 0
+
+/* Keep WLC_HIGH_ONLY, WLC_SPLIT for USB extension later on */
+#if !defined(WLC_LOW)
+#define WLC_HIGH_ONLY
+#endif
+#if !defined(WLC_LOW)
+#define WLC_SPLIT
+#endif
+
+/* **** Core type/rev defaults **** */
+#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
+ * also need to update wlc.h MAXCOREREV
+ */
+
+#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs:
+ * 0 4321a0
+ * 1 4321a1
+ * 2 4321b0/b1/c0/c1
+ * 3 4322a0
+ * 4 4322a1
+ * 5 4716a0
+ * 6 43222a0, 43224a0
+ * 7 43226a0
+ * 8 5357a0, 43236a0
+ */
+
+#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs:
+ * 0 4313a0, 4336a0, 4330a0
+ * 1
+ * 2 4330a0
+ */
+
+#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs:
+ * 0 4329a0/k0
+ * 1 4329b0/4329C0
+ * 2 4319a0
+ * 3 5356a0
+ */
+
+#ifdef BCMSDIO
+#define D11CONF 0x100000
+#define SSLPNCONF 2
+#define GCCONF 0
+#define ACCONF 0
+#define NCONF 0
+#define LPCONF 0
+#define LCNCONF 0
+#define NTXD 32
+#define NRXD 16
+#define NRXBUFPOST 8
+#define WLC_DATAHIWAT 32
+#define RXBND 8
+#define MAXPKTCB 64
+#define AMPDU_NUM_MPDU 8
+#endif
+
+/* For undefined values, use defaults */
+#ifndef D11CONF
+#define D11CONF D11_DEFAULT
+#endif
+#ifndef NCONF
+#define NCONF NPHY_DEFAULT
+#endif
+#ifndef LCNCONF
+#define LCNCONF LCNPHY_DEFAULT
+#endif
+
+#ifndef SSLPNCONF
+#define SSLPNCONF SSLPNPHY_DEFAULT
+#endif
+
+#define BAND2G
+#define BAND5G
+#define WLANTSEL 1
+
+/********************************************************************
+ * Phy/Core Configuration. Defines macros to to check core phy/rev *
+ * compile-time configuration. Defines default core support. *
+ * ******************************************************************
+ */
+
+/* Basic macros to check a configuration bitmask */
+
+#define CONF_HAS(config, val) ((config) & (1 << (val)))
+#define CONF_MSK(config, mask) ((config) & (mask))
+#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
+#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
+
+#define CONF_IS(config, val) ((config) == (1 << (val)))
+#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
+#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
+#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
+#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
+
+/* Wrappers for some of the above, specific to config constants */
+
+#define NCONF_HAS(val) CONF_HAS(NCONF, val)
+#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
+#define NCONF_IS(val) CONF_IS(NCONF, val)
+#define NCONF_GE(val) CONF_GE(NCONF, val)
+#define NCONF_GT(val) CONF_GT(NCONF, val)
+#define NCONF_LT(val) CONF_LT(NCONF, val)
+#define NCONF_LE(val) CONF_LE(NCONF, val)
+
+#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
+#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
+#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
+#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
+#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
+#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
+#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
+
+#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
+#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
+#define D11CONF_IS(val) CONF_IS(D11CONF, val)
+#define D11CONF_GE(val) CONF_GE(D11CONF, val)
+#define D11CONF_GT(val) CONF_GT(D11CONF, val)
+#define D11CONF_LT(val) CONF_LT(D11CONF, val)
+#define D11CONF_LE(val) CONF_LE(D11CONF, val)
+
+#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
+#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
+
+#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
+#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
+#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
+#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
+#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
+
+#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
+#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
+#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
+#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
+#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
+
+#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
+#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
+#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
+#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
+#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
+
+#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
+
+/* Finally, early-exit from switch case if anyone wants it... */
+
+#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break
+#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break
+
+#if (D11CONF ^ (D11CONF & D11_DEFAULT))
+#error "Unsupported MAC revision configured"
+#endif
+#if (NCONF ^ (NCONF & NPHY_DEFAULT))
+#error "Unsupported NPHY revision configured"
+#endif
+#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT))
+#error "Unsupported LPPHY revision configured"
+#endif
+
+/* *** Consistency checks *** */
+#if !D11CONF
+#error "No MAC revisions configured!"
+#endif
+
+#if !NCONF && !LCNCONF && !SSLPNCONF
+#error "No PHY configured!"
+#endif
+
+/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
+
+#define _PHYCONF_N (1 << PHY_TYPE_N)
+
+#if LCNCONF
+#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
+#else
+#define _PHYCONF_LCN 0
+#endif /* LCNCONF */
+
+#if SSLPNCONF
+#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
+#else
+#define _PHYCONF_SSLPN 0
+#endif /* SSLPNCONF */
+
+#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
+
+/* Utility macro to identify 802.11n (HT) capable PHYs */
+#define PHYTYPE_11N_CAP(phytype) \
+ (PHYTYPE_IS(phytype, PHY_TYPE_N) || \
+ PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
+ PHYTYPE_IS(phytype, PHY_TYPE_SSN))
+
+/* Last but not least: shorter wlc-specific var checks */
+#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
+#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
+#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
+
+#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
+
+/**********************************************************************
+ * ------------- End of Core phy/rev configuration. ----------------- *
+ * ********************************************************************
+ */
+
+/*************************************************
+ * Defaults for tunables (e.g. sizing constants)
+ *
+ * For each new tunable, add a member to the end
+ * of wlc_tunables_t in wlc_pub.h to enable
+ * runtime checks of tunable values. (Directly
+ * using the macros in code invalidates ROM code)
+ *
+ * ***********************************************
+ */
+#ifndef NTXD
+#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */
+#endif /* NTXD */
+#ifndef NRXD
+#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */
+#endif /* NRXD */
+
+#ifndef NRXBUFPOST
+#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */
+#endif /* NRXBUFPOST */
+
+#ifndef MAXSCB /* station control blocks in cache */
+#define MAXSCB 32 /* Maximum SCBs in cache for STA */
+#endif /* MAXSCB */
+
+#ifndef AMPDU_NUM_MPDU
+#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */
+#endif /* AMPDU_NUM_MPDU */
+
+#ifndef AMPDU_NUM_MPDU_3STREAMS
+#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */
+#endif /* AMPDU_NUM_MPDU_3STREAMS */
+
+/* Count of packet callback structures. either of following
+ * 1. Set to the number of SCBs since a STA
+ * can queue up a rate callback for each IBSS STA it knows about, and an AP can
+ * queue up an "are you there?" Null Data callback for each associated STA
+ * 2. controlled by tunable config file
+ */
+#ifndef MAXPKTCB
+#define MAXPKTCB MAXSCB /* Max number of packet callbacks */
+#endif /* MAXPKTCB */
+
+#ifndef CTFPOOLSZ
+#define CTFPOOLSZ 128
+#endif /* CTFPOOLSZ */
+
+/* NetBSD also needs to keep track of this */
+#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */
+#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */
+#ifndef WLC_MAXBSSCFG
+#define WLC_MAXBSSCFG (1) /* max # BSS configs */
+#endif /* WLC_MAXBSSCFG */
+
+#ifndef MAXBSS
+#define MAXBSS 64 /* max # available networks */
+#endif /* MAXBSS */
+
+#ifndef WLC_DATAHIWAT
+#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */
+#endif /* WLC_DATAHIWAT */
+
+#ifndef WLC_AMPDUDATAHIWAT
+#define WLC_AMPDUDATAHIWAT 255
+#endif /* WLC_AMPDUDATAHIWAT */
+
+/* bounded rx loops */
+#ifndef RXBND
+#define RXBND 8 /* max # frames to process in wlc_recv() */
+#endif /* RXBND */
+#ifndef TXSBND
+#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */
+#endif /* TXSBND */
+
+#define BAND_5G(bt) ((bt) == WLC_BAND_5G)
+#define BAND_2G(bt) ((bt) == WLC_BAND_2G)
+
+#define WLBANDINITDATA(_data) _data
+#define WLBANDINITFN(_fn) _fn
+
+#define WLANTSEL_ENAB(wlc) 1
+
+#endif /* _wlc_cfg_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c
new file mode 100644
index 000000000000..554a0cb84ad5
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_channel.c
@@ -0,0 +1,1599 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <wlioctl.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wlc_mac80211.h>
+#include <wlc_bmac.h>
+#include <wlc_stf.h>
+#include <wlc_channel.h>
+
+typedef struct wlc_cm_band {
+ uint8 locale_flags; /* locale_info_t flags */
+ chanvec_t valid_channels; /* List of valid channels in the country */
+ const chanvec_t *restricted_channels; /* List of restricted use channels */
+ const chanvec_t *radar_channels; /* List of radar sensitive channels */
+ uint8 PAD[8];
+} wlc_cm_band_t;
+
+struct wlc_cm_info {
+ wlc_pub_t *pub;
+ wlc_info_t *wlc;
+ char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */
+ uint srom_regrev; /* Regulatory Rev for the SROM ccode */
+ const country_info_t *country; /* current country def */
+ char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */
+ uint regrev; /* current Regulatory Revision */
+ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */
+ wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */
+ /* quiet channels currently for radar sensitivity or 11h support */
+ chanvec_t quiet_channels; /* channels on which we cannot transmit */
+};
+
+static int wlc_channels_init(wlc_cm_info_t *wlc_cm,
+ const country_info_t *country);
+static void wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+ const char *country_abbrev,
+ const char *ccode, uint regrev,
+ const country_info_t *country);
+static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+ char *mapped_ccode, uint *mapped_regrev);
+static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+ uint regrev);
+static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+ const char *ccode,
+ char *mapped_ccode,
+ uint *mapped_regrev);
+static void wlc_channels_commit(wlc_cm_info_t *wlc_cm);
+static bool wlc_japan_ccode(const char *ccode);
+static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *
+ wlc_cm,
+ struct
+ txpwr_limits
+ *txpwr,
+ uint8
+ local_constraint_qdbm);
+void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels);
+static const locale_mimo_info_t *wlc_get_mimo_2g(uint8 locale_idx);
+static const locale_mimo_info_t *wlc_get_mimo_5g(uint8 locale_idx);
+
+/* QDB() macro takes a dB value and converts to a quarter dB value */
+#ifdef QDB
+#undef QDB
+#endif
+#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR)
+
+/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
+
+/*
+ * Some common channel sets
+ */
+
+/* No channels */
+static const chanvec_t chanvec_none = {
+ {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}
+};
+
+/* All 2.4 GHz HW channels */
+const chanvec_t chanvec_all_2G = {
+ {0xfe, 0x7f, 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}
+};
+
+/* All 5 GHz HW channels */
+const chanvec_t chanvec_all_5G = {
+ {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
+ 0x11, 0x11, 0x11, 0x01}
+};
+
+/*
+ * Radar channel sets
+ */
+
+/* No radar */
+#define radar_set_none chanvec_none
+
+static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */
+ 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */
+ 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+/*
+ * Restricted channel sets
+ */
+
+#define restricted_set_none chanvec_none
+
+/* Channels 34, 38, 42, 46 */
+static const chanvec_t restricted_set_japan_legacy = {
+ {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+/* Channels 12, 13 */
+static const chanvec_t restricted_set_2g_short = {
+ {0x00, 0x30, 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}
+};
+
+/* Channel 165 */
+static const chanvec_t restricted_chan_165 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+/* Channels 36 - 48 & 149 - 165 */
+static const chanvec_t restricted_low_hi = {
+ {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+/* Channels 12 - 14 */
+static const chanvec_t restricted_set_12_13_14 = {
+ {0x00, 0x70, 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}
+};
+
+#define LOCALE_CHAN_01_11 (1<<0)
+#define LOCALE_CHAN_12_13 (1<<1)
+#define LOCALE_CHAN_14 (1<<2)
+#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
+#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
+#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
+#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
+#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
+#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
+#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
+#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
+#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
+#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
+#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
+#define LOCALE_CHAN_52_140_ALL (1<<14)
+#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
+
+#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
+#define LOCALE_CHAN_100_140 \
+ (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
+#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
+#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
+
+#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14)
+
+#define LOCALE_RADAR_SET_NONE 0
+#define LOCALE_RADAR_SET_1 1
+
+#define LOCALE_RESTRICTED_NONE 0
+#define LOCALE_RESTRICTED_SET_2G_SHORT 1
+#define LOCALE_RESTRICTED_CHAN_165 2
+#define LOCALE_CHAN_ALL_5G 3
+#define LOCALE_RESTRICTED_JAPAN_LEGACY 4
+#define LOCALE_RESTRICTED_11D_2G 5
+#define LOCALE_RESTRICTED_11D_5G 6
+#define LOCALE_RESTRICTED_LOW_HI 7
+#define LOCALE_RESTRICTED_12_13_14 8
+
+/* global memory to provide working buffer for expanded locale */
+
+static const chanvec_t *g_table_radar_set[] = {
+ &chanvec_none,
+ &radar_set1
+};
+
+static const chanvec_t *g_table_restricted_chan[] = {
+ &chanvec_none, /* restricted_set_none */
+ &restricted_set_2g_short,
+ &restricted_chan_165,
+ &chanvec_all_5G,
+ &restricted_set_japan_legacy,
+ &chanvec_all_2G, /* restricted_set_11d_2G */
+ &chanvec_all_5G, /* restricted_set_11d_5G */
+ &restricted_low_hi,
+ &restricted_set_12_13_14
+};
+
+static const chanvec_t locale_2g_01_11 = {
+ {0xfe, 0x0f, 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}
+};
+
+static const chanvec_t locale_2g_12_13 = {
+ {0x00, 0x30, 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}
+};
+
+static const chanvec_t locale_2g_14 = {
+ {0x00, 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}
+};
+
+static const chanvec_t locale_5g_LOW_JP1 = {
+ {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_LOW_JP2 = {
+ {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_LOW1 = {
+ {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_LOW2 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_LOW3 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_MID1 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_MID2 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_MID3 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_HIGH1 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_HIGH2 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_HIGH3 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_52_140_ALL = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static const chanvec_t locale_5g_HIGH4 = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+ 0x11, 0x11, 0x11, 0x11}
+};
+
+static const chanvec_t *g_table_locale_base[] = {
+ &locale_2g_01_11,
+ &locale_2g_12_13,
+ &locale_2g_14,
+ &locale_5g_LOW_JP1,
+ &locale_5g_LOW_JP2,
+ &locale_5g_LOW1,
+ &locale_5g_LOW2,
+ &locale_5g_LOW3,
+ &locale_5g_MID1,
+ &locale_5g_MID2,
+ &locale_5g_MID3,
+ &locale_5g_HIGH1,
+ &locale_5g_HIGH2,
+ &locale_5g_HIGH3,
+ &locale_5g_52_140_ALL,
+ &locale_5g_HIGH4
+};
+
+void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels)
+{
+ uint8 i;
+ for (i = 0; i < sizeof(chanvec_t); i++) {
+ target->vec[i] |= channels->vec[i];
+ }
+}
+
+void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels)
+{
+ uint8 i;
+
+ bzero(channels, sizeof(chanvec_t));
+
+ for (i = 0; i < ARRAYSIZE(g_table_locale_base); i++) {
+ if (locale->valid_channels & (1 << i)) {
+ wlc_locale_add_channels(channels,
+ g_table_locale_base[i]);
+ }
+ }
+}
+
+/*
+ * Locale Definitions - 2.4 GHz
+ */
+static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */
+ LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
+ LOCALE_RADAR_SET_NONE,
+ LOCALE_RESTRICTED_SET_2G_SHORT,
+ {QDB(19), QDB(19), QDB(19),
+ QDB(19), QDB(19), QDB(19)},
+ {20, 20, 20, 0},
+ WLC_EIRP
+};
+
+/*
+ * Locale Definitions - 5 GHz
+ */
+static const locale_info_t locale_11 = {
+ /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
+ LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
+ LOCALE_RADAR_SET_1,
+ LOCALE_RESTRICTED_NONE,
+ {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
+ {23, 23, 23, 30, 30},
+ WLC_EIRP | WLC_DFS_EU
+};
+
+#define LOCALE_2G_IDX_i 0
+static const locale_info_t *g_locale_2g_table[] = {
+ &locale_i
+};
+
+#define LOCALE_5G_IDX_11 0
+static const locale_info_t *g_locale_5g_table[] = {
+ &locale_11
+};
+
+/*
+ * MIMO Locale Definitions - 2.4 GHz
+ */
+static const locale_mimo_info_t locale_bn = {
+ {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+ QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+ QDB(13), QDB(13), QDB(13)},
+ {0, 0, QDB(13), QDB(13), QDB(13),
+ QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+ QDB(13), 0, 0},
+ 0
+};
+
+/* locale mimo 2g indexes */
+#define LOCALE_MIMO_IDX_bn 0
+
+static const locale_mimo_info_t *g_mimo_2g_table[] = {
+ &locale_bn
+};
+
+/*
+ * MIMO Locale Definitions - 5 GHz
+ */
+static const locale_mimo_info_t locale_11n = {
+ { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
+ {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
+ 0
+};
+
+#define LOCALE_MIMO_IDX_11n 0
+static const locale_mimo_info_t *g_mimo_5g_table[] = {
+ &locale_11n
+};
+
+#ifdef LC
+#undef LC
+#endif
+#define LC(id) LOCALE_MIMO_IDX_ ## id
+
+#ifdef LC_2G
+#undef LC_2G
+#endif
+#define LC_2G(id) LOCALE_2G_IDX_ ## id
+
+#ifdef LC_5G
+#undef LC_5G
+#endif
+#define LC_5G(id) LOCALE_5G_IDX_ ## id
+
+#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
+
+static const struct {
+ char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */
+ country_info_t country;
+} cntry_locales[] = {
+ {
+ "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */
+};
+
+#ifdef SUPPORT_40MHZ
+/* 20MHz channel info for 40MHz pairing support */
+struct chan20_info {
+ uint8 sb;
+ uint8 adj_sbs;
+};
+
+/* indicates adjacent channels that are allowed for a 40 Mhz channel and
+ * those that permitted by the HT
+ */
+struct chan20_info chan20_info[] = {
+ /* 11b/11g */
+/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 11 */ {12, (CH_LOWER_SB)},
+/* 12 */ {13, (CH_LOWER_SB)},
+/* 13 */ {14, (CH_LOWER_SB)},
+
+/* 11a japan high */
+/* 14 */ {34, (CH_UPPER_SB)},
+/* 15 */ {38, (CH_LOWER_SB)},
+/* 16 */ {42, (CH_LOWER_SB)},
+/* 17 */ {46, (CH_LOWER_SB)},
+
+/* 11a usa low */
+/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
+
+/* 11a Europe */
+/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 36 */ {140, (CH_LOWER_SB)},
+
+/* 11a usa high, ref5 only */
+/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
+/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
+/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
+/* 41 */ {165, (CH_LOWER_SB)},
+
+/* 11a japan */
+/* 42 */ {184, (CH_UPPER_SB)},
+/* 43 */ {188, (CH_LOWER_SB)},
+/* 44 */ {192, (CH_UPPER_SB)},
+/* 45 */ {196, (CH_LOWER_SB)},
+/* 46 */ {200, (CH_UPPER_SB)},
+/* 47 */ {204, (CH_LOWER_SB)},
+/* 48 */ {208, (CH_UPPER_SB)},
+/* 49 */ {212, (CH_LOWER_SB)},
+/* 50 */ {216, (CH_LOWER_SB)}
+};
+#endif /* SUPPORT_40MHZ */
+
+const locale_info_t *wlc_get_locale_2g(uint8 locale_idx)
+{
+ if (locale_idx >= ARRAYSIZE(g_locale_2g_table)) {
+ WL_ERROR(("%s: locale 2g index size out of range %d\n",
+ __func__, locale_idx));
+ ASSERT(locale_idx < ARRAYSIZE(g_locale_2g_table));
+ return NULL;
+ }
+ return g_locale_2g_table[locale_idx];
+}
+
+const locale_info_t *wlc_get_locale_5g(uint8 locale_idx)
+{
+ if (locale_idx >= ARRAYSIZE(g_locale_5g_table)) {
+ WL_ERROR(("%s: locale 5g index size out of range %d\n",
+ __func__, locale_idx));
+ ASSERT(locale_idx < ARRAYSIZE(g_locale_5g_table));
+ return NULL;
+ }
+ return g_locale_5g_table[locale_idx];
+}
+
+const locale_mimo_info_t *wlc_get_mimo_2g(uint8 locale_idx)
+{
+ if (locale_idx >= ARRAYSIZE(g_mimo_2g_table)) {
+ WL_ERROR(("%s: mimo 2g index size out of range %d\n", __func__,
+ locale_idx));
+ return NULL;
+ }
+ return g_mimo_2g_table[locale_idx];
+}
+
+const locale_mimo_info_t *wlc_get_mimo_5g(uint8 locale_idx)
+{
+ if (locale_idx >= ARRAYSIZE(g_mimo_5g_table)) {
+ WL_ERROR(("%s: mimo 5g index size out of range %d\n", __func__,
+ locale_idx));
+ return NULL;
+ }
+ return g_mimo_5g_table[locale_idx];
+}
+
+wlc_cm_info_t *BCMATTACHFN(wlc_channel_mgr_attach) (wlc_info_t *wlc)
+{
+ wlc_cm_info_t *wlc_cm;
+ char country_abbrev[WLC_CNTRY_BUF_SZ];
+ const country_info_t *country;
+ wlc_pub_t *pub = wlc->pub;
+ char *ccode;
+
+ WL_TRACE(("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit));
+
+ wlc_cm = (wlc_cm_info_t *) MALLOC(pub->osh, sizeof(wlc_cm_info_t));
+ if (wlc_cm == NULL) {
+ WL_ERROR(("wl%d: %s: out of memory, malloced %d bytes",
+ pub->unit, __func__, MALLOCED(pub->osh)));
+ return NULL;
+ }
+ bzero((char *)wlc_cm, sizeof(wlc_cm_info_t));
+ wlc_cm->pub = pub;
+ wlc_cm->wlc = wlc;
+ wlc->cmi = wlc_cm;
+
+ /* store the country code for passing up as a regulatory hint */
+ ccode = getvar(wlc->pub->vars, "ccode");
+ if (ccode) {
+ strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+ WL_NONE(("%s: SROM country code is %c%c\n", __func__,
+ wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]));
+ }
+
+ /* internal country information which must match regulatory constraints in firmware */
+ bzero(country_abbrev, WLC_CNTRY_BUF_SZ);
+ strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
+ country = wlc_country_lookup(wlc, country_abbrev);
+
+ ASSERT(country != NULL);
+
+ /* save default country for exiting 11d regulatory mode */
+ strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+
+ /* initialize autocountry_default to driver default */
+ strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1);
+
+ wlc_set_countrycode(wlc_cm, country_abbrev);
+
+ return wlc_cm;
+}
+
+void BCMATTACHFN(wlc_channel_mgr_detach) (wlc_cm_info_t *wlc_cm)
+{
+ if (wlc_cm)
+ MFREE(wlc_cm->pub->osh, wlc_cm, sizeof(wlc_cm_info_t));
+}
+
+const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm)
+{
+ return wlc_cm->country_abbrev;
+}
+
+uint8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+
+ return wlc_cm->bandstate[wlc->band->bandunit].locale_flags;
+}
+
+uint8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
+{
+ return wlc_cm->bandstate[bandunit].locale_flags;
+}
+
+/* return chanvec for a given country code and band */
+bool
+wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev,
+ int bandtype, chanvec_t *channels)
+{
+ const country_info_t *country;
+ const locale_info_t *locale = NULL;
+
+ country = wlc_country_lookup(wlc, country_abbrev);
+ if (country == NULL)
+ return FALSE;
+
+ if (bandtype == WLC_BAND_2G)
+ locale = wlc_get_locale_2g(country->locale_2G);
+ else if (bandtype == WLC_BAND_5G)
+ locale = wlc_get_locale_5g(country->locale_5G);
+ if (locale == NULL)
+ return FALSE;
+
+ wlc_locale_get_channels(locale, channels);
+ return TRUE;
+}
+
+/* set the driver's current country and regulatory information using a country code
+ * as the source. Lookup built in country information found with the country code.
+ */
+int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode)
+{
+ char country_abbrev[WLC_CNTRY_BUF_SZ];
+ strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ);
+ return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
+}
+
+int
+wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+ const char *country_abbrev,
+ const char *ccode, int regrev)
+{
+ const country_info_t *country;
+ char mapped_ccode[WLC_CNTRY_BUF_SZ];
+ uint mapped_regrev;
+
+ WL_NONE(("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", __func__, country_abbrev, ccode, regrev, wlc_cm->srom_ccode, wlc_cm->srom_regrev));
+
+ /* if regrev is -1, lookup the mapped country code,
+ * otherwise use the ccode and regrev directly
+ */
+ if (regrev == -1) {
+ /* map the country code to a built-in country code, regrev, and country_info */
+ country =
+ wlc_countrycode_map(wlc_cm, ccode, mapped_ccode,
+ &mapped_regrev);
+ } else {
+ /* find the matching built-in country definition */
+ ASSERT(0);
+ country = wlc_country_lookup_direct(ccode, regrev);
+ strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+ mapped_regrev = regrev;
+ }
+
+ if (country == NULL)
+ return BCME_BADARG;
+
+ /* set the driver state for the country */
+ wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
+ mapped_regrev, country);
+
+ return 0;
+}
+
+/* set the driver's current country and regulatory information using a country code
+ * as the source. Look up built in country information found with the country code.
+ */
+static void
+wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+ const char *country_abbrev,
+ const char *ccode, uint regrev,
+ const country_info_t *country)
+{
+ const locale_mimo_info_t *li_mimo;
+ const locale_info_t *locale;
+ wlc_info_t *wlc = wlc_cm->wlc;
+ char prev_country_abbrev[WLC_CNTRY_BUF_SZ];
+
+ ASSERT(country != NULL);
+
+ /* save current country state */
+ wlc_cm->country = country;
+
+ bzero(&prev_country_abbrev, WLC_CNTRY_BUF_SZ);
+ strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
+ WLC_CNTRY_BUF_SZ - 1);
+
+ strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+ strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+ wlc_cm->regrev = regrev;
+
+ /* disable/restore nmode based on country regulations */
+ li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G);
+ if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) {
+ wlc_set_nmode(wlc, OFF);
+ wlc->stf->no_cddstbc = TRUE;
+ } else {
+ wlc->stf->no_cddstbc = FALSE;
+ if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
+ wlc_set_nmode(wlc, wlc->protection->nmode_user);
+ }
+
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+ /* set or restore gmode as required by regulatory */
+ locale = wlc_get_locale_2g(country->locale_2G);
+ if (locale && (locale->flags & WLC_NO_OFDM)) {
+ wlc_set_gmode(wlc, GMODE_LEGACY_B, FALSE);
+ } else {
+ wlc_set_gmode(wlc, wlc->protection->gmode_user, FALSE);
+ }
+
+ wlc_channels_init(wlc_cm, country);
+
+ return;
+}
+
+/* Lookup a country info structure from a null terminated country code
+ * The lookup is case sensitive.
+ */
+const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+ const char *ccode)
+{
+ const country_info_t *country;
+ char mapped_ccode[WLC_CNTRY_BUF_SZ];
+ uint mapped_regrev;
+
+ /* map the country code to a built-in country code, regrev, and country_info struct */
+ country =
+ wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev);
+
+ return country;
+}
+
+static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+ const char *ccode,
+ char *mapped_ccode,
+ uint *mapped_regrev)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ const country_info_t *country;
+ uint srom_regrev = wlc_cm->srom_regrev;
+ const char *srom_ccode = wlc_cm->srom_ccode;
+ int mapped;
+
+ /* check for currently supported ccode size */
+ if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) {
+ WL_ERROR(("wl%d: %s: ccode \"%s\" too long for match\n",
+ wlc->pub->unit, __func__, ccode));
+ return NULL;
+ }
+
+ /* default mapping is the given ccode and regrev 0 */
+ strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+ *mapped_regrev = 0;
+
+ /* If the desired country code matches the srom country code,
+ * then the mapped country is the srom regulatory rev.
+ * Otherwise look for an aggregate mapping.
+ */
+ if (!strcmp(srom_ccode, ccode)) {
+ *mapped_regrev = srom_regrev;
+ mapped = 0;
+ WL_ERROR(("srom_code == ccode %s\n", __func__));
+ ASSERT(0);
+ } else {
+ mapped =
+ wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
+ mapped_regrev);
+ }
+
+ /* find the matching built-in country definition */
+ country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+
+ /* if there is not an exact rev match, default to rev zero */
+ if (country == NULL && *mapped_regrev != 0) {
+ *mapped_regrev = 0;
+ ASSERT(0);
+ country =
+ wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+ }
+
+ return country;
+}
+
+static int
+wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+ char *mapped_ccode, uint *mapped_regrev)
+{
+ return FALSE;
+}
+
+/* Lookup a country info structure from a null terminated country
+ * abbreviation and regrev directly with no translation.
+ */
+static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+ uint regrev)
+{
+ uint size, i;
+
+ /* Should just return 0 for single locale driver. */
+ /* Keep it this way in case we add more locales. (for now anyway) */
+
+ /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
+ if (regrev > 0)
+ return NULL;
+
+ /* find matched table entry from country code */
+ size = ARRAYSIZE(cntry_locales);
+ for (i = 0; i < size; i++) {
+ if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
+ return &cntry_locales[i].country;
+ }
+ }
+
+ WL_ERROR(("%s: Returning NULL\n", __func__));
+ ASSERT(0);
+ return NULL;
+}
+
+static int
+wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ uint i, j;
+ wlcband_t *band;
+ const locale_info_t *li;
+ chanvec_t sup_chan;
+ const locale_mimo_info_t *li_mimo;
+
+ band = wlc->band;
+ for (i = 0; i < NBANDS(wlc);
+ i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+
+ li = BAND_5G(band->bandtype) ?
+ wlc_get_locale_5g(country->locale_5G) :
+ wlc_get_locale_2g(country->locale_2G);
+ ASSERT(li);
+ wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
+ li_mimo = BAND_5G(band->bandtype) ?
+ wlc_get_mimo_5g(country->locale_mimo_5G) :
+ wlc_get_mimo_2g(country->locale_mimo_2G);
+ ASSERT(li_mimo);
+
+ /* merge the mimo non-mimo locale flags */
+ wlc_cm->bandstate[band->bandunit].locale_flags |=
+ li_mimo->flags;
+
+ wlc_cm->bandstate[band->bandunit].restricted_channels =
+ g_table_restricted_chan[li->restricted_channels];
+ wlc_cm->bandstate[band->bandunit].radar_channels =
+ g_table_radar_set[li->radar_channels];
+
+ /* set the channel availability,
+ * masking out the channels that may not be supported on this phy
+ */
+ wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
+ &sup_chan);
+ wlc_locale_get_channels(li,
+ &wlc_cm->bandstate[band->bandunit].
+ valid_channels);
+ for (j = 0; j < sizeof(chanvec_t); j++)
+ wlc_cm->bandstate[band->bandunit].valid_channels.
+ vec[j] &= sup_chan.vec[j];
+ }
+
+ wlc_quiet_channels_reset(wlc_cm);
+ wlc_channels_commit(wlc_cm);
+
+ return 0;
+}
+
+/* Update the radio state (enable/disable) and tx power targets
+ * based on a new set of channel/regulatory information
+ */
+static void wlc_channels_commit(wlc_cm_info_t *wlc_cm)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ uint chan;
+ struct txpwr_limits txpwr;
+
+ /* search for the existence of any valid channel */
+ for (chan = 0; chan < MAXCHANNEL; chan++) {
+ if (VALID_CHANNEL20_DB(wlc, chan)) {
+ break;
+ }
+ }
+ if (chan == MAXCHANNEL)
+ chan = INVCHANNEL;
+
+ /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */
+ if (chan == INVCHANNEL) {
+ /* country/locale with no valid channels, set the radio disable bit */
+ mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+ WL_ERROR(("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", wlc->pub->unit, __func__, wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked));
+ } else
+ if (mboolisset(wlc->pub->radio_disabled,
+ WL_RADIO_COUNTRY_DISABLE)) {
+ /* country/locale with valid channel, clear the radio disable bit */
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+ }
+
+ /* Now that the country abbreviation is set, if the radio supports 2G, then
+ * set channel 14 restrictions based on the new locale.
+ */
+ if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) {
+ wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
+ wlc_japan(wlc) ? TRUE :
+ FALSE);
+ }
+
+ if (wlc->pub->up && chan != INVCHANNEL) {
+ wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
+ wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm,
+ &txpwr,
+ WLC_TXPWR_MAX);
+ wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
+ }
+}
+
+/* reset the quiet channels vector to the union of the restricted and radar channel sets */
+void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ uint i, j;
+ wlcband_t *band;
+ const chanvec_t *chanvec;
+
+ bzero(&wlc_cm->quiet_channels, sizeof(chanvec_t));
+
+ band = wlc->band;
+ for (i = 0; i < NBANDS(wlc);
+ i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+
+ /* initialize quiet channels for restricted channels */
+ chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
+ for (j = 0; j < sizeof(chanvec_t); j++)
+ wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
+
+ }
+}
+
+bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+{
+ return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
+ (isset
+ (wlc_cm->quiet_channels.vec,
+ LOWER_20_SB(CHSPEC_CHANNEL(chspec)))
+ || isset(wlc_cm->quiet_channels.vec,
+ UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm->
+ quiet_channels.
+ vec,
+ CHSPEC_CHANNEL
+ (chspec));
+}
+
+/* Is the channel valid for the current locale? (but don't consider channels not
+ * available due to bandlocking)
+ */
+bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+
+ return VALID_CHANNEL20(wlc, val) ||
+ (!wlc->bandlocked
+ && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
+}
+
+/* Is the channel valid for the current locale and specified band? */
+bool
+wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val)
+{
+ return ((val < MAXCHANNEL)
+ && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
+}
+
+/* Is the channel valid for the current locale and current band? */
+bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+
+ return ((val < MAXCHANNEL) &&
+ isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
+ val));
+}
+
+/* Is the 40 MHz allowed for the current locale and specified band? */
+bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+
+ return (((wlc_cm->bandstate[bandunit].
+ locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0)
+ && wlc->bandstate[bandunit]->mimo_cap_40);
+}
+
+static void
+wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm,
+ struct txpwr_limits *txpwr,
+ uint8
+ local_constraint_qdbm)
+{
+ int j;
+
+ /* CCK Rates */
+ for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) {
+ txpwr->cck[j] = MIN(txpwr->cck[j], local_constraint_qdbm);
+ }
+
+ /* 20 MHz Legacy OFDM SISO */
+ for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) {
+ txpwr->ofdm[j] = MIN(txpwr->ofdm[j], local_constraint_qdbm);
+ }
+
+ /* 20 MHz Legacy OFDM CDD */
+ for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+ txpwr->ofdm_cdd[j] =
+ MIN(txpwr->ofdm_cdd[j], local_constraint_qdbm);
+ }
+
+ /* 40 MHz Legacy OFDM SISO */
+ for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+ txpwr->ofdm_40_siso[j] =
+ MIN(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
+ }
+
+ /* 40 MHz Legacy OFDM CDD */
+ for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+ txpwr->ofdm_40_cdd[j] =
+ MIN(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
+ }
+
+ /* 20MHz MCS 0-7 SISO */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_20_siso[j] =
+ MIN(txpwr->mcs_20_siso[j], local_constraint_qdbm);
+ }
+
+ /* 20MHz MCS 0-7 CDD */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_20_cdd[j] =
+ MIN(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
+ }
+
+ /* 20MHz MCS 0-7 STBC */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_20_stbc[j] =
+ MIN(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
+ }
+
+ /* 20MHz MCS 8-15 MIMO */
+ for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+ txpwr->mcs_20_mimo[j] =
+ MIN(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
+
+ /* 40MHz MCS 0-7 SISO */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_40_siso[j] =
+ MIN(txpwr->mcs_40_siso[j], local_constraint_qdbm);
+ }
+
+ /* 40MHz MCS 0-7 CDD */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_40_cdd[j] =
+ MIN(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
+ }
+
+ /* 40MHz MCS 0-7 STBC */
+ for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+ txpwr->mcs_40_stbc[j] =
+ MIN(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
+ }
+
+ /* 40MHz MCS 8-15 MIMO */
+ for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+ txpwr->mcs_40_mimo[j] =
+ MIN(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
+
+ /* 40MHz MCS 32 */
+ txpwr->mcs32 = MIN(txpwr->mcs32, local_constraint_qdbm);
+
+}
+
+void
+wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+ uint8 local_constraint_qdbm)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ struct txpwr_limits txpwr;
+
+ wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr);
+
+ wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr,
+ local_constraint_qdbm);
+
+ wlc_bmac_set_chanspec(wlc->hw, chanspec,
+ (wlc_quiet_chanspec(wlc_cm, chanspec) != 0),
+ &txpwr);
+}
+
+int
+wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm,
+ uint8 local_constraint_qdbm)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ struct txpwr_limits txpwr;
+
+ wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
+
+ wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr,
+ local_constraint_qdbm);
+
+ wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
+
+ return 0;
+}
+
+#ifdef POWER_DBG
+static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr)
+{
+ int i;
+ char fraction[4][4] = { " ", ".25", ".5 ", ".75" };
+
+ printf("CCK ");
+ for (i = 0; i < WLC_NUM_RATES_CCK; i++) {
+ printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz OFDM SISO ");
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz OFDM CDD ");
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz OFDM SISO ");
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz OFDM CDD ");
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz MCS0-7 SISO ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz MCS0-7 CDD ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz MCS0-7 STBC ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("20 MHz MCS8-15 SDM ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz MCS0-7 SISO ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz MCS0-7 CDD ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz MCS0-7 STBC ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("40 MHz MCS8-15 SDM ");
+ for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+ printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+ }
+ printf("\n");
+
+ printf("MCS32 %2d%s\n",
+ txpwr->mcs32 / WLC_TXPWR_DB_FACTOR,
+ fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]);
+}
+#endif /* POWER_DBG */
+
+void
+wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+ txpwr_limits_t *txpwr)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ uint i;
+ uint chan;
+ int maxpwr;
+ int delta;
+ const country_info_t *country;
+ wlcband_t *band;
+ const locale_info_t *li;
+ int conducted_max;
+ int conducted_ofdm_max;
+ const locale_mimo_info_t *li_mimo;
+ int maxpwr20, maxpwr40;
+ int maxpwr_idx;
+ uint j;
+
+ bzero(txpwr, sizeof(txpwr_limits_t));
+
+ if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) {
+ country = wlc_country_lookup(wlc, wlc->autocountry_default);
+ if (country == NULL)
+ return;
+ } else {
+ country = wlc_cm->country;
+ }
+
+ chan = CHSPEC_CHANNEL(chanspec);
+ band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)];
+ li = BAND_5G(band->bandtype) ?
+ wlc_get_locale_5g(country->locale_5G) :
+ wlc_get_locale_2g(country->locale_2G);
+
+ li_mimo = BAND_5G(band->bandtype) ?
+ wlc_get_mimo_5g(country->locale_mimo_5G) :
+ wlc_get_mimo_2g(country->locale_mimo_2G);
+
+ if (li->flags & WLC_EIRP) {
+ delta = band->antgain;
+ } else {
+ delta = 0;
+ if (band->antgain > QDB(6))
+ delta = band->antgain - QDB(6); /* Excess over 6 dB */
+ }
+
+ if (li == &locale_i) {
+ conducted_max = QDB(22);
+ conducted_ofdm_max = QDB(22);
+ }
+
+ /* CCK txpwr limits for 2.4G band */
+ if (BAND_2G(band->bandtype)) {
+ maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
+
+ maxpwr = maxpwr - delta;
+ maxpwr = MAX(maxpwr, 0);
+ maxpwr = MIN(maxpwr, conducted_max);
+
+ for (i = 0; i < WLC_NUM_RATES_CCK; i++)
+ txpwr->cck[i] = (uint8) maxpwr;
+ }
+
+ /* OFDM txpwr limits for 2.4G or 5G bands */
+ if (BAND_2G(band->bandtype)) {
+ maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
+
+ } else {
+ maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
+ }
+
+ maxpwr = maxpwr - delta;
+ maxpwr = MAX(maxpwr, 0);
+ maxpwr = MIN(maxpwr, conducted_ofdm_max);
+
+ /* Keep OFDM lmit below CCK limit */
+ if (BAND_2G(band->bandtype))
+ maxpwr = MIN(maxpwr, txpwr->cck[0]);
+
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ txpwr->ofdm[i] = (uint8) maxpwr;
+ }
+
+ for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+ /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless
+ * overriden by the locale specific code. We set this value to 0 as a
+ * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
+ * to the 40 MHz value if it wasn't explicitly set.
+ */
+ txpwr->ofdm_40_siso[i] = 0;
+
+ txpwr->ofdm_cdd[i] = (uint8) maxpwr;
+
+ txpwr->ofdm_40_cdd[i] = 0;
+ }
+
+ /* MIMO/HT specific limits */
+ if (li_mimo->flags & WLC_EIRP) {
+ delta = band->antgain;
+ } else {
+ delta = 0;
+ if (band->antgain > QDB(6))
+ delta = band->antgain - QDB(6); /* Excess over 6 dB */
+ }
+
+ if (BAND_2G(band->bandtype))
+ maxpwr_idx = (chan - 1);
+ else
+ maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
+
+ maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
+ maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
+
+ maxpwr20 = maxpwr20 - delta;
+ maxpwr20 = MAX(maxpwr20, 0);
+ maxpwr40 = maxpwr40 - delta;
+ maxpwr40 = MAX(maxpwr40, 0);
+
+ /* Fill in the MCS 0-7 (SISO) rates */
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+
+ /* 20 MHz has the same power as the corresponding OFDM rate unless
+ * overriden by the locale specific code.
+ */
+ txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
+ txpwr->mcs_40_siso[i] = 0;
+ }
+
+ /* Fill in the MCS 0-7 CDD rates */
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ txpwr->mcs_20_cdd[i] = (uint8) maxpwr20;
+ txpwr->mcs_40_cdd[i] = (uint8) maxpwr40;
+ }
+
+ /* These locales have SISO expressed in the table and override CDD later */
+ if (li_mimo == &locale_bn) {
+ if (li_mimo == &locale_bn) {
+ maxpwr20 = QDB(16);
+ maxpwr40 = 0;
+
+ if (chan >= 3 && chan <= 11) {
+ maxpwr40 = QDB(16);
+ }
+ }
+
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ txpwr->mcs_20_siso[i] = (uint8) maxpwr20;
+ txpwr->mcs_40_siso[i] = (uint8) maxpwr40;
+ }
+ }
+
+ /* Fill in the MCS 0-7 STBC rates */
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ txpwr->mcs_20_stbc[i] = 0;
+ txpwr->mcs_40_stbc[i] = 0;
+ }
+
+ /* Fill in the MCS 8-15 SDM rates */
+ for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+ txpwr->mcs_20_mimo[i] = (uint8) maxpwr20;
+ txpwr->mcs_40_mimo[i] = (uint8) maxpwr40;
+ }
+
+ /* Fill in MCS32 */
+ txpwr->mcs32 = (uint8) maxpwr40;
+
+ for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+ if (txpwr->ofdm_40_cdd[i] == 0)
+ txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+ if (i == 0) {
+ i = i + 1;
+ if (txpwr->ofdm_40_cdd[i] == 0)
+ txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+ }
+ }
+
+ /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't
+ * provided explicitly.
+ */
+
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ if (txpwr->mcs_40_siso[i] == 0)
+ txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
+ }
+
+ for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+ if (txpwr->ofdm_40_siso[i] == 0)
+ txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+ if (i == 0) {
+ i = i + 1;
+ if (txpwr->ofdm_40_siso[i] == 0)
+ txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+ }
+ }
+
+ /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't
+ * provided explicitly.
+ */
+ for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+ if (txpwr->mcs_20_stbc[i] == 0)
+ txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
+
+ if (txpwr->mcs_40_stbc[i] == 0)
+ txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
+ }
+
+#ifdef POWER_DBG
+ wlc_phy_txpower_limits_dump(txpwr);
+#endif
+ return;
+}
+
+/* Returns TRUE if currently set country is Japan or variant */
+bool wlc_japan(struct wlc_info *wlc)
+{
+ return wlc_japan_ccode(wlc->cmi->country_abbrev);
+}
+
+/* JP, J1 - J10 are Japan ccodes */
+static bool wlc_japan_ccode(const char *ccode)
+{
+ return (ccode[0] == 'J' &&
+ (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
+}
+
+/*
+ * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands
+ * are valid 20MZH channels in this locale and they are also a legal HT combination
+ */
+static bool
+wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband)
+{
+ wlc_info_t *wlc = wlc_cm->wlc;
+ uint8 channel = CHSPEC_CHANNEL(chspec);
+
+ /* check the chanspec */
+ if (wf_chspec_malformed(chspec)) {
+ WL_ERROR(("wl%d: malformed chanspec 0x%x\n", wlc->pub->unit,
+ chspec));
+ ASSERT(0);
+ return FALSE;
+ }
+
+ if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
+ CHSPEC_WLCBANDUNIT(chspec))
+ return FALSE;
+
+ /* Check a 20Mhz channel */
+ if (CHSPEC_IS20(chspec)) {
+ if (dualband)
+ return VALID_CHANNEL20_DB(wlc_cm->wlc, channel);
+ else
+ return VALID_CHANNEL20(wlc_cm->wlc, channel);
+ }
+#ifdef SUPPORT_40MHZ
+ /* We know we are now checking a 40MHZ channel, so we should only be here
+ * for NPHYS
+ */
+ if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) {
+ uint8 upper_sideband = 0, idx;
+ uint8 num_ch20_entries =
+ sizeof(chan20_info) / sizeof(struct chan20_info);
+
+ if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec)))
+ return FALSE;
+
+ if (dualband) {
+ if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) ||
+ !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel)))
+ return FALSE;
+ } else {
+ if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) ||
+ !VALID_CHANNEL20(wlc, UPPER_20_SB(channel)))
+ return FALSE;
+ }
+
+ /* find the lower sideband info in the sideband array */
+ for (idx = 0; idx < num_ch20_entries; idx++) {
+ if (chan20_info[idx].sb == LOWER_20_SB(channel))
+ upper_sideband = chan20_info[idx].adj_sbs;
+ }
+ /* check that the lower sideband allows an upper sideband */
+ if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
+ (CH_UPPER_SB | CH_EWA_VALID))
+ return TRUE;
+ return FALSE;
+ }
+#endif /* 40 MHZ */
+
+ return FALSE;
+}
+
+bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+{
+ return wlc_valid_chanspec_ext(wlc_cm, chspec, FALSE);
+}
+
+bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+{
+ return wlc_valid_chanspec_ext(wlc_cm, chspec, TRUE);
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_channel.h b/drivers/staging/brcm80211/sys/wlc_channel.h
new file mode 100644
index 000000000000..6ad80537c615
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_channel.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _WLC_CHANNEL_H_
+#define _WLC_CHANNEL_H_
+
+#include <wlc_phy_hal.h>
+
+#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */
+
+struct wlc_info;
+
+/* maxpwr mapping to 5GHz band channels:
+ * maxpwr[0] - channels [34-48]
+ * maxpwr[1] - channels [52-60]
+ * maxpwr[2] - channels [62-64]
+ * maxpwr[3] - channels [100-140]
+ * maxpwr[4] - channels [149-165]
+ */
+#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */
+
+/* power level in group of 2.4GHz band channels:
+ * maxpwr[0] - CCK channels [1]
+ * maxpwr[1] - CCK channels [2-10]
+ * maxpwr[2] - CCK channels [11-14]
+ * maxpwr[3] - OFDM channels [1]
+ * maxpwr[4] - OFDM channels [2-10]
+ * maxpwr[5] - OFDM channels [11-14]
+ */
+
+/* macro to get 2.4 GHz channel group index for tx power */
+#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */
+#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */
+
+/* macro to get 5 GHz channel group index for tx power */
+#define CHANNEL_POWER_IDX_5G(c) \
+ (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
+
+#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
+#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
+
+/* locale channel and power info. */
+typedef struct {
+ uint32 valid_channels;
+ uint8 radar_channels; /* List of radar sensitive channels */
+ uint8 restricted_channels; /* List of channels used only if APs are detected */
+ int8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */
+ int8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm
+ * per sub-band
+ */
+ uint8 flags;
+} locale_info_t;
+
+/* bits for locale_info flags */
+#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */
+#define WLC_EIRP 0x01 /* Flag for EIRP */
+#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */
+#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */
+#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
+#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
+#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */
+#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */
+#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */
+
+#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU)
+
+/* locale per-channel tx power limits for MIMO frames
+ * maxpwr arrays are index by channel for 2.4 GHz limits, and
+ * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
+ */
+typedef struct {
+ int8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */
+ int8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */
+ uint8 flags;
+} locale_mimo_info_t;
+
+extern const chanvec_t chanvec_all_2G;
+extern const chanvec_t chanvec_all_5G;
+
+/*
+ * Country names and abbreviations with locale defined from ISO 3166
+ */
+struct country_info {
+ const uint8 locale_2G; /* 2.4G band locale */
+ const uint8 locale_5G; /* 5G band locale */
+ const uint8 locale_mimo_2G; /* 2.4G mimo info */
+ const uint8 locale_mimo_5G; /* 5G mimo info */
+};
+
+typedef struct country_info country_info_t;
+
+typedef struct wlc_cm_info wlc_cm_info_t;
+
+extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc);
+extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm);
+
+extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode);
+extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+ const char *country_abbrev,
+ const char *ccode, int regrev);
+
+extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm);
+extern uint8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm);
+extern uint8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm,
+ uint bandunit);
+
+extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm);
+extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+
+#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val)
+#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \
+ wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val)
+#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val)
+#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit)
+
+extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val);
+extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit,
+ uint val);
+extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val);
+extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit);
+
+extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm,
+ chanspec_t chanspec,
+ struct txpwr_limits *txpwr);
+extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm,
+ chanspec_t chanspec,
+ uint8 local_constraint_qdbm);
+extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm,
+ uint8 local_constraint_qdbm);
+
+extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+ const char *ccode);
+extern void wlc_locale_get_channels(const locale_info_t *locale,
+ chanvec_t *valid_channels);
+extern const locale_info_t *wlc_get_locale_2g(uint8 locale_idx);
+extern const locale_info_t *wlc_get_locale_5g(uint8 locale_idx);
+extern bool wlc_japan(struct wlc_info *wlc);
+
+extern uint8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec);
+extern bool wlc_channel_get_chanvec(struct wlc_info *wlc,
+ const char *country_abbrev, int bandtype,
+ chanvec_t *channels);
+
+#endif /* _WLC_CHANNEL_H */
diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c
new file mode 100644
index 000000000000..9052d690ccfe
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_event.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+#include <wl_dbg.h>
+#include <wlc_cfg.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wl_export.h>
+#include <wlc_event.h>
+
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_mac80211.h>
+#ifdef MSGTRACE
+#include <msgtrace.h>
+#endif
+
+/* Local prototypes */
+static void wlc_timer_cb(void *arg);
+
+/* Private data structures */
+struct wlc_eventq {
+ wlc_event_t *head;
+ wlc_event_t *tail;
+ struct wlc_info *wlc;
+ void *wl;
+ wlc_pub_t *pub;
+ bool tpending;
+ bool workpending;
+ struct wl_timer *timer;
+ wlc_eventq_cb_t cb;
+ uint8 event_inds_mask[ROUNDUP(WLC_E_LAST, NBBY) / NBBY];
+};
+
+/*
+ * Export functions
+ */
+wlc_eventq_t *BCMATTACHFN(wlc_eventq_attach) (wlc_pub_t *pub,
+ struct wlc_info *wlc, void *wl,
+ wlc_eventq_cb_t cb) {
+ wlc_eventq_t *eq;
+
+ eq = (wlc_eventq_t *) MALLOC(pub->osh, sizeof(wlc_eventq_t));
+ if (eq == NULL)
+ return NULL;
+
+ bzero(eq, sizeof(wlc_eventq_t));
+
+ eq->cb = cb;
+ eq->wlc = wlc;
+ eq->wl = wl;
+ eq->pub = pub;
+
+ eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq");
+ if (!eq->timer) {
+ WL_ERROR(("wl%d: wlc_eventq_attach: timer failed\n",
+ pub->unit));
+ MFREE(eq->pub->osh, eq, sizeof(wlc_eventq_t));
+ return NULL;
+ }
+
+ return eq;
+}
+
+int BCMATTACHFN(wlc_eventq_detach) (wlc_eventq_t *eq)
+{
+ /* Clean up pending events */
+ wlc_eventq_down(eq);
+
+ if (eq->timer) {
+ if (eq->tpending) {
+ wl_del_timer(eq->wl, eq->timer);
+ eq->tpending = FALSE;
+ }
+ wl_free_timer(eq->wl, eq->timer);
+ eq->timer = NULL;
+ }
+
+ ASSERT(wlc_eventq_avail(eq) == FALSE);
+ MFREE(eq->pub->osh, eq, sizeof(wlc_eventq_t));
+ return 0;
+}
+
+int BCMUNINITFN(wlc_eventq_down) (wlc_eventq_t *eq)
+{
+ int callbacks = 0;
+ if (eq->tpending && !eq->workpending) {
+ if (!wl_del_timer(eq->wl, eq->timer))
+ callbacks++;
+
+ ASSERT(wlc_eventq_avail(eq) == TRUE);
+ ASSERT(eq->workpending == FALSE);
+ eq->workpending = TRUE;
+ if (eq->cb)
+ eq->cb(eq->wlc);
+
+ ASSERT(eq->workpending == TRUE);
+ eq->workpending = FALSE;
+ eq->tpending = FALSE;
+ } else {
+ ASSERT(eq->workpending || wlc_eventq_avail(eq) == FALSE);
+ }
+ return callbacks;
+}
+
+wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq)
+{
+ wlc_event_t *e;
+
+ e = MALLOC(eq->pub->osh, sizeof(wlc_event_t));
+
+ if (e == NULL)
+ return NULL;
+
+ bzero(e, sizeof(wlc_event_t));
+ return e;
+}
+
+void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e)
+{
+ ASSERT(e->data == NULL);
+ ASSERT(e->next == NULL);
+ MFREE(eq->pub->osh, e, sizeof(wlc_event_t));
+}
+
+void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e)
+{
+ ASSERT(e->next == NULL);
+ e->next = NULL;
+
+ if (eq->tail) {
+ eq->tail->next = e;
+ eq->tail = e;
+ } else
+ eq->head = eq->tail = e;
+
+ if (!eq->tpending) {
+ eq->tpending = TRUE;
+ /* Use a zero-delay timer to trigger
+ * delayed processing of the event.
+ */
+ wl_add_timer(eq->wl, eq->timer, 0, 0);
+ }
+}
+
+wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq)
+{
+ wlc_event_t *e;
+
+ e = eq->head;
+ if (e) {
+ eq->head = e->next;
+ e->next = NULL;
+
+ if (eq->head == NULL)
+ eq->tail = eq->head;
+ }
+ return e;
+}
+
+wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e)
+{
+#ifdef BCMDBG
+ wlc_event_t *etmp;
+
+ for (etmp = eq->head; etmp; etmp = etmp->next) {
+ if (etmp == e)
+ break;
+ }
+ ASSERT(etmp != NULL);
+#endif
+
+ return e->next;
+}
+
+int wlc_eventq_cnt(wlc_eventq_t *eq)
+{
+ wlc_event_t *etmp;
+ int cnt = 0;
+
+ for (etmp = eq->head; etmp; etmp = etmp->next)
+ cnt++;
+
+ return cnt;
+}
+
+bool wlc_eventq_avail(wlc_eventq_t *eq)
+{
+ return (eq->head != NULL);
+}
+
+/*
+ * Local Functions
+ */
+static void wlc_timer_cb(void *arg)
+{
+ struct wlc_eventq *eq = (struct wlc_eventq *)arg;
+
+ ASSERT(eq->tpending == TRUE);
+ ASSERT(wlc_eventq_avail(eq) == TRUE);
+ ASSERT(eq->workpending == FALSE);
+ eq->workpending = TRUE;
+
+ if (eq->cb)
+ eq->cb(eq->wlc);
+
+ ASSERT(wlc_eventq_avail(eq) == FALSE);
+ ASSERT(eq->tpending == TRUE);
+ eq->workpending = FALSE;
+ eq->tpending = FALSE;
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_event.h b/drivers/staging/brcm80211/sys/wlc_event.h
new file mode 100644
index 000000000000..88aadf5d0d4a
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_event.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _WLC_EVENT_H_
+#define _WLC_EVENT_H_
+
+typedef struct wlc_eventq wlc_eventq_t;
+
+typedef void (*wlc_eventq_cb_t) (void *arg);
+
+extern wlc_eventq_t *wlc_eventq_attach(wlc_pub_t *pub, struct wlc_info *wlc,
+ void *wl, wlc_eventq_cb_t cb);
+extern int wlc_eventq_detach(wlc_eventq_t *eq);
+extern int wlc_eventq_down(wlc_eventq_t *eq);
+extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e);
+extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e);
+extern int wlc_eventq_cnt(wlc_eventq_t *eq);
+extern bool wlc_eventq_avail(wlc_eventq_t *eq);
+extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq);
+extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e);
+extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq);
+
+extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect);
+extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect);
+extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et);
+extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on);
+extern void wlc_eventq_flush(wlc_eventq_t *eq);
+extern void wlc_assign_event_msg(wlc_info_t *wlc, wl_event_msg_t *msg,
+ const wlc_event_t *e, uint8 *data,
+ uint32 len);
+
+#ifdef MSGTRACE
+extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus,
+ uint8 *hdr, uint16 hdrlen, uint8 *buf,
+ uint16 buflen);
+#endif
+
+#endif /* _WLC_EVENT_H_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_key.h b/drivers/staging/brcm80211/sys/wlc_key.h
new file mode 100644
index 000000000000..b2e8efdad9b0
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_key.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_key_h_
+#define _wlc_key_h_
+
+struct scb;
+struct wlc_info;
+struct wlc_bsscfg;
+/* Maximum # of keys that wl driver supports in S/W.
+ * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS.
+ */
+#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */
+#define WLC_DEFAULT_KEYS 4 /* Default # of keys */
+
+#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */
+
+#define WPA2_GTK_MAX 3
+
+/*
+* Max # of keys currently supported:
+*
+* s/w keys if WSEC_SW(wlc->wsec).
+* h/w keys otherwise.
+*/
+#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS
+
+/* number of 802.11 default (non-paired, group keys) */
+#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */
+
+/* Max # of hardware keys supported */
+#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS
+
+/* Max # of hardware TKIP MIC keys supported */
+#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \
+ WSEC_MAX_TKMIC_ENGINE_KEYS : 0)
+
+#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \
+ (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \
+ (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \
+ !WSEC_SOFTKEY(wlc, key, bsscfg) && \
+ WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \
+ (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS))
+
+/* index of key in key table */
+#define WSEC_KEY_INDEX(wlc, key) ((key)->idx)
+
+#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \
+ WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc))
+
+/* get a key, non-NULL only if key allocated and not clear */
+#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \
+ (wlc)->wsec_keys[i] : NULL)
+
+#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? TRUE : FALSE)
+
+/* default key */
+#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \
+ (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index])
+
+/* Macros for key management in IBSS mode */
+#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */
+#define WSEC_IBSS_RCMTA_INDEX(idx) \
+ (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS)
+
+/* contiguous # key slots for infrastructure mode STA */
+#define WSEC_BSS_STA_KEY_GROUP_SIZE 5
+
+typedef struct wsec_iv {
+ uint32 hi; /* upper 32 bits of IV */
+ uint16 lo; /* lower 16 bits of IV */
+} wsec_iv_t;
+
+#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */
+
+typedef struct wsec_key {
+ struct ether_addr ea; /* per station */
+ uint8 idx; /* key index in wsec_keys array */
+ uint8 id; /* key ID [0-3] */
+ uint8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+ uint8 rcmta; /* rcmta entry index, same as idx by default */
+ uint16 flags; /* misc flags */
+ uint8 algo_hw; /* cache for hw register */
+ uint8 aes_mode; /* cache for hw register */
+ int8 iv_len; /* IV length */
+ int8 icv_len; /* ICV length */
+ uint32 len; /* key length..don't move this var */
+ /* data is 4byte aligned */
+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */
+ wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */
+ wsec_iv_t txiv; /* Tx IV */
+
+} wsec_key_t;
+
+typedef struct {
+ uint8 vec[ROUNDUP(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */
+} wsec_key_vec_t;
+
+/* For use with wsec_key_t.flags */
+
+#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */
+#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */
+#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */
+#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */
+#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */
+#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */
+
+#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR)
+#define wlc_key_update(a, b, c) do {} while (0)
+#define wlc_key_remove(a, b, c) do {} while (0)
+#define wlc_key_remove_all(a, b) do {} while (0)
+#define wlc_key_delete(a, b, c) do {} while (0)
+#define wlc_scb_key_delete(a, b) do {} while (0)
+#define wlc_key_lookup(a, b, c, d, e) (NULL)
+#define wlc_key_hw_init_all(a) do {} while (0)
+#define wlc_key_hw_init(a, b, c) do {} while (0)
+#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0)
+#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0)
+#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR)
+#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0)
+#define wlc_key_iv_init(a, b, c) do {} while (0)
+#define wlc_key_set_error(a, b, c) (BCME_ERROR)
+#define wlc_key_dump_hw(a, b) (BCME_ERROR)
+#define wlc_key_dump_sw(a, b) (BCME_ERROR)
+#define wlc_key_defkeyflag(a) (0)
+#define wlc_rcmta_add_bssid(a, b) do {} while (0)
+#define wlc_rcmta_del_bssid(a, b) do {} while (0)
+#define wlc_key_scb_delete(a, b) do {} while (0)
+
+#endif /* _wlc_key_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c
new file mode 100644
index 000000000000..27ddc23ae9e5
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c
@@ -0,0 +1,9143 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmwifi.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <proto/802.1d.h>
+#include <proto/802.11.h>
+#include <proto/802.11e.h>
+#include <proto/wpa.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <bcmsrom.h>
+#include <wlioctl.h>
+#include <epivers.h>
+#include <bcmwpa.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <hnddma.h>
+#include <hndpmu.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wlc_bsscfg.h>
+#include <wlc_channel.h>
+#include <wlc_mac80211.h>
+#include <wlc_bmac.h>
+#include <wlc_scb.h>
+#include <wlc_phy_hal.h>
+#include <wlc_phy_shim.h>
+#include <wlc_antsel.h>
+#include <wlc_stf.h>
+#include <wlc_ampdu.h>
+#include <wlc_event.h>
+#include <wl_export.h>
+#ifdef BCMSDIO
+#include <bcmsdh.h>
+#else
+#include "d11ucode_ext.h"
+#endif
+#ifdef WLC_HIGH_ONLY
+#include <bcm_rpc_tp.h>
+#include <bcm_rpc.h>
+#include <bcm_xdr.h>
+#include <wlc_rpc.h>
+#include <wlc_rpctx.h>
+#endif /* WLC_HIGH_ONLY */
+#include <wlc_alloc.h>
+#include <net/mac80211.h>
+
+#ifdef WLC_HIGH_ONLY
+#undef R_REG
+#undef W_REG
+#define R_REG(osh, r) RPC_READ_REG(osh, r)
+#define W_REG(osh, r, v) RPC_WRITE_REG(osh, r, v)
+#endif
+
+/*
+ * buffer length needed for wlc_format_ssid
+ * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+ */
+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1)
+
+#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */
+#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */
+
+#ifndef WLC_MPC_MAX_DELAYCNT
+#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */
+#endif
+#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */
+#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */
+
+#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */
+#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */
+
+/* Scale down delays to accommodate QT slow speed */
+#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */
+#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */
+
+#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */
+
+/*
+ * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
+ * watchdog) it is not a wall clock and won't increment when driver is in "down" state
+ * this low resolution driver tick can be used for maintenance tasks such as phy
+ * calibration and scb update
+ */
+
+/* watchdog trigger mode: OSL timer or TBTT */
+#define WLC_WATCHDOG_TBTT(wlc) \
+ (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt)
+
+/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
+#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid))
+
+#ifndef WLC_HIGH_ONLY
+#define WLC_WAR16165(wlc) (BUSTYPE(wlc->pub->sih->bustype) == PCI_BUS && \
+ (!AP_ENAB(wlc->pub)) && (wlc->war16165))
+#else
+#define WLC_WAR16165(wlc) (FALSE)
+#endif /* WLC_HIGH_ONLY */
+
+/* debug/trace */
+uint wl_msg_level =
+#if defined(BCMDBG)
+ WL_ERROR_VAL;
+#else
+ 0;
+#endif /* BCMDBG */
+
+/* Find basic rate for a given rate */
+#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \
+ (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
+ (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])
+
+#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM))
+
+#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */
+
+#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */
+
+#define SCAN_IN_PROGRESS(x) 0
+
+#ifdef BCMDBG
+/* pointer to most recently allocated wl/wlc */
+static wlc_info_t *wlc_info_dbg = (wlc_info_t *) (NULL);
+#endif
+
+#if defined(BCMDBG)
+struct wlc_id_name_entry {
+ int id;
+ const char *name;
+};
+typedef struct wlc_id_name_entry wlc_id_name_table_t[];
+#endif
+
+/* IOVar table */
+
+/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars
+ * table and by the wlc_doiovar() function. No ordering is imposed:
+ * the table is keyed by name, and the function uses a switch.
+ */
+enum {
+ IOV_MPC = 1,
+ IOV_QTXPOWER,
+ IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */
+ IOV_LAST /* In case of a need to check max ID number */
+};
+
+const bcm_iovar_t wlc_iovars[] = {
+ {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0},
+ {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32,
+ 0},
+ {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0},
+ {NULL, 0, 0, 0, 0}
+};
+
+const uint8 prio2fifo[NUMPRIO] = {
+ TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
+ TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
+ TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
+ TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
+ TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
+ TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
+ TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
+ TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
+};
+
+/* precedences numbers for wlc queues. These are twice as may levels as
+ * 802.1D priorities.
+ * Odd numbers are used for HI priority traffic at same precedence levels
+ * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere.
+ */
+#define _WLC_PREC_NONE 0 /* None = - */
+#define _WLC_PREC_BK 2 /* BK - Background */
+#define _WLC_PREC_BE 4 /* BE - Best-effort */
+#define _WLC_PREC_EE 6 /* EE - Excellent-effort */
+#define _WLC_PREC_CL 8 /* CL - Controlled Load */
+#define _WLC_PREC_VI 10 /* Vi - Video */
+#define _WLC_PREC_VO 12 /* Vo - Voice */
+#define _WLC_PREC_NC 14 /* NC - Network Control */
+
+/* 802.1D Priority to precedence queue mapping */
+const uint8 wlc_prio2prec_map[] = {
+ _WLC_PREC_BE, /* 0 BE - Best-effort */
+ _WLC_PREC_BK, /* 1 BK - Background */
+ _WLC_PREC_NONE, /* 2 None = - */
+ _WLC_PREC_EE, /* 3 EE - Excellent-effort */
+ _WLC_PREC_CL, /* 4 CL - Controlled Load */
+ _WLC_PREC_VI, /* 5 Vi - Video */
+ _WLC_PREC_VO, /* 6 Vo - Voice */
+ _WLC_PREC_NC, /* 7 NC - Network Control */
+};
+
+/* Sanity check for tx_prec_map and fifo synchup
+ * Either there are some packets pending for the fifo, else if fifo is empty then
+ * all the corresponding precmap bits should be set
+ */
+#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \
+ (TXPKTPENDGET((wlc), (fifo)) == 0 && \
+ ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \
+ (wlc)->fifo2prec_map[(fifo)]))
+
+/* TX FIFO number to WME/802.1E Access Category */
+const uint8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
+
+/* WME/802.1E Access Category to TX FIFO number */
+static const uint8 wme_ac2fifo[] = { 1, 0, 2, 3 };
+
+static bool in_send_q = FALSE;
+
+/* Shared memory location index for various AC params */
+#define wme_shmemacindex(ac) wme_ac2fifo[ac]
+
+#ifdef BCMDBG
+static const char *fifo_names[] = {
+ "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
+const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" };
+#endif
+
+static const uint8 acbitmap2maxprio[] = {
+ PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
+ PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
+ PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
+ PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
+};
+
+/* currently the best mechanism for determining SIFS is the band in use */
+#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME);
+
+/* value for # replay counters currently supported */
+#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS
+
+/* local prototypes */
+extern void wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec);
+static uint16 BCMFASTPATH wlc_d11hdrs_mac80211(wlc_info_t *wlc,
+ struct ieee80211_hw *hw, void *p,
+ struct scb *scb, uint frag,
+ uint nfrags, uint queue,
+ uint next_frag_len,
+ wsec_key_t *key,
+ ratespec_t rspec_override);
+bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw);
+void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend);
+static void wlc_bss_default_init(wlc_info_t *wlc);
+static void wlc_ucode_mac_upd(wlc_info_t *wlc);
+static ratespec_t mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band,
+ uint32 int_val);
+static void wlc_tx_prec_map_init(wlc_info_t *wlc);
+static void wlc_watchdog(void *arg);
+static void wlc_watchdog_by_timer(void *arg);
+static int wlc_set_rateset(wlc_info_t *wlc, wlc_rateset_t *rs_arg);
+static int wlc_iovar_rangecheck(wlc_info_t *wlc, uint32 val,
+ const bcm_iovar_t *vi);
+static uint8 wlc_local_constraint_qdbm(wlc_info_t *wlc);
+
+#if defined(BCMDBG)
+static void wlc_print_dot11hdr(uint8 *buf, int len);
+#endif
+
+/* send and receive */
+static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, osl_t *osh);
+static void wlc_txq_free(wlc_info_t *wlc, osl_t *osh, wlc_txq_info_t *qi);
+static void wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi,
+ bool on, int prio);
+static void wlc_txflowcontrol_reset(wlc_info_t *wlc);
+static uint16 wlc_compute_airtime(wlc_info_t *wlc, ratespec_t rspec,
+ uint length);
+static void wlc_compute_cck_plcp(ratespec_t rate, uint length, uint8 *plcp);
+static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, uint8 *plcp);
+static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, uint8 *plcp);
+static uint16 wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate,
+ uint8 preamble_type, uint next_frag_len);
+static void wlc_recvctl(wlc_info_t *wlc, osl_t *osh, d11rxhdr_t *rxh,
+ void *p);
+static uint wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t rate,
+ uint8 preamble_type, uint dur);
+static uint wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rate,
+ uint8 preamble_type);
+static uint wlc_calc_cts_time(wlc_info_t *wlc, ratespec_t rate,
+ uint8 preamble_type);
+/* interrupt, up/down, band */
+static void wlc_setband(wlc_info_t *wlc, uint bandunit);
+static chanspec_t wlc_init_chanspec(wlc_info_t *wlc);
+static void wlc_bandinit_ordered(wlc_info_t *wlc, chanspec_t chanspec);
+static void wlc_bsinit(wlc_info_t *wlc);
+static int wlc_duty_cycle_set(wlc_info_t *wlc, int duty_cycle, bool isOFDM,
+ bool writeToShm);
+static void wlc_radio_hwdisable_upd(wlc_info_t *wlc);
+static bool wlc_radio_monitor_start(wlc_info_t *wlc);
+static void wlc_radio_timer(void *arg);
+static void wlc_radio_enable(wlc_info_t *wlc);
+static void wlc_radio_upd(wlc_info_t *wlc);
+
+/* scan, association, BSS */
+static uint wlc_calc_ba_time(wlc_info_t *wlc, ratespec_t rate,
+ uint8 preamble_type);
+static void wlc_update_mimo_band_bwcap(wlc_info_t *wlc, uint8 bwcap);
+static void wlc_ht_update_sgi_rx(wlc_info_t *wlc, int val);
+void wlc_ht_mimops_cap_update(wlc_info_t *wlc, uint8 mimops_mode);
+static void wlc_ht_update_ldpc(wlc_info_t *wlc, int8 val);
+static void wlc_war16165(wlc_info_t *wlc, bool tx);
+
+static void wlc_process_eventq(void *arg);
+static void wlc_wme_retries_write(wlc_info_t *wlc);
+static bool wlc_attach_stf_ant_init(wlc_info_t *wlc);
+static uint wlc_attach_module(wlc_info_t *wlc);
+static void wlc_detach_module(wlc_info_t *wlc);
+static void wlc_timers_deinit(wlc_info_t *wlc);
+static void wlc_down_led_upd(wlc_info_t *wlc);
+static uint wlc_down_del_timer(wlc_info_t *wlc);
+static void wlc_ofdm_rateset_war(wlc_info_t *wlc);
+static int _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len,
+ struct wlc_if *wlcif);
+char *print_fk(uint16 fk);
+
+#if defined(BCMDBG)
+void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr)
+{
+ d11regs_t *regs = wlc->regs;
+ uint32 v32;
+ osl_t *osh;
+
+ WL_TRACE(("wl%d: %s\n", WLCWLUNIT(wlc), __func__));
+
+ ASSERT(wlc->pub->corerev > 4);
+
+ osh = wlc->osh;
+
+ W_REG(osh, &regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));
+ (void)R_REG(osh, &regs->objaddr);
+ v32 = R_REG(osh, &regs->objdata);
+ addr->octet[0] = (uint8) v32;
+ addr->octet[1] = (uint8) (v32 >> 8);
+ addr->octet[2] = (uint8) (v32 >> 16);
+ addr->octet[3] = (uint8) (v32 >> 24);
+ W_REG(osh, &regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));
+ (void)R_REG(osh, &regs->objaddr);
+ v32 = R_REG(osh, (volatile uint16 *)(uintptr) & regs->objdata);
+ addr->octet[4] = (uint8) v32;
+ addr->octet[5] = (uint8) (v32 >> 8);
+}
+#endif /* defined(BCMDBG) */
+
+/* keep the chip awake if needed */
+bool wlc_stay_awake(wlc_info_t *wlc)
+{
+ return TRUE;
+}
+
+/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
+ */
+bool wlc_ps_allowed(wlc_info_t *wlc)
+{
+ int idx;
+ wlc_bsscfg_t *cfg;
+
+ /* disallow PS when one of the following global conditions meets */
+ if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override)
+ return FALSE;
+
+ /* disallow PS when one of these meets when not scanning */
+ if (!wlc->PMblocked) {
+ if (AP_ACTIVE(wlc) || wlc->monitor)
+ return FALSE;
+ }
+
+ FOREACH_AS_STA(wlc, idx, cfg) {
+ /* disallow PS when one of the following bsscfg specific conditions meets */
+ if (!cfg->BSS || !WLC_PORTOPEN(cfg))
+ return FALSE;
+
+ if (!cfg->dtim_programmed)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void BCMINITFN(wlc_reset) (wlc_info_t *wlc)
+{
+ WL_TRACE(("wl%d: wlc_reset\n", wlc->pub->unit));
+
+ wlc->check_for_unaligned_tbtt = FALSE;
+
+ /* slurp up hw mac counters before core reset */
+ if (WLC_UPDATE_STATS(wlc)) {
+ wlc_statsupd(wlc);
+
+ /* reset our snapshot of macstat counters */
+ bzero((char *)wlc->core->macstat_snapshot, sizeof(macstat_t));
+ }
+
+ wlc_bmac_reset(wlc->hw);
+ wlc_ampdu_reset(wlc->ampdu);
+ wlc->txretried = 0;
+
+#ifdef WLC_HIGH_ONLY
+ /* Need to set a flag(to be cleared asynchronously by BMAC driver with high call)
+ * in order to prevent wlc_rpctx_txreclaim() from screwing wlc_rpctx_getnexttxp(),
+ * which could be invoked by already QUEUED high call(s) from BMAC driver before
+ * wlc_bmac_reset() finishes.
+ * It's not needed before in monolithic driver model because d11core interrupts would
+ * have been cleared instantly in wlc_bmac_reset() and no txstatus interrupt
+ * will come to driver to fetch those flushed dma pkt pointers.
+ */
+ wlc->reset_bmac_pending = TRUE;
+
+ wlc_rpctx_txreclaim(wlc->rpctx);
+
+ wlc_stf_phy_txant_upd(wlc);
+ wlc_phy_ant_rxdiv_set(wlc->band->pi, wlc->stf->ant_rx_ovr);
+#endif
+}
+
+void wlc_fatal_error(wlc_info_t *wlc)
+{
+ WL_ERROR(("wl%d: fatal error, reinitializing\n", wlc->pub->unit));
+ wl_init(wlc->wl);
+}
+
+/* Return the channel the driver should initialize during wlc_init.
+ * the channel may have to be changed from the currently configured channel
+ * if other configurations are in conflict (bandlocked, 11n mode disabled,
+ * invalid channel for current country, etc.)
+ */
+static chanspec_t BCMINITFN(wlc_init_chanspec) (wlc_info_t *wlc)
+{
+ chanspec_t chanspec =
+ 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
+ WL_CHANSPEC_BAND_2G;
+
+ /* make sure the channel is on the supported band if we are band-restricted */
+ if (wlc->bandlocked || NBANDS(wlc) == 1) {
+ ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);
+ }
+ ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
+ return chanspec;
+}
+
+struct scb global_scb;
+
+static void wlc_init_scb(wlc_info_t *wlc, struct scb *scb)
+{
+ int i;
+ scb->flags = SCB_WMECAP | SCB_HTCAP;
+ for (i = 0; i < NUMPRIO; i++)
+ scb->seqnum[i] = 0;
+}
+
+void BCMINITFN(wlc_init) (wlc_info_t *wlc)
+{
+ d11regs_t *regs;
+ chanspec_t chanspec;
+ int i;
+ wlc_bsscfg_t *bsscfg;
+ bool mute = FALSE;
+
+ WL_TRACE(("wl%d: wlc_init\n", wlc->pub->unit));
+
+ regs = wlc->regs;
+
+ /* This will happen if a big-hammer was executed. In that case, we want to go back
+ * to the channel that we were on and not new channel
+ */
+ if (wlc->pub->associated)
+ chanspec = wlc->home_chanspec;
+ else
+ chanspec = wlc_init_chanspec(wlc);
+
+ wlc_bmac_init(wlc->hw, chanspec, mute);
+
+ wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2;
+ if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC))
+ wlc->tkmickeys =
+ wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2;
+
+ /* update beacon listen interval */
+ wlc_bcn_li_upd(wlc);
+ wlc->bcn_wait_prd =
+ (uint8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10);
+ ASSERT(wlc->bcn_wait_prd > 0);
+
+ /* the world is new again, so is our reported rate */
+ wlc_reprate_init(wlc);
+
+ /* write ethernet address to core */
+ FOREACH_BSS(wlc, i, bsscfg) {
+ wlc_set_mac(bsscfg);
+ wlc_set_bssid(bsscfg);
+ }
+
+ /* Update tsf_cfprep if associated and up */
+ if (wlc->pub->associated) {
+ FOREACH_BSS(wlc, i, bsscfg) {
+ if (bsscfg->up) {
+ uint32 bi;
+
+ /* get beacon period from bsscfg and convert to uS */
+ bi = bsscfg->current_bss->beacon_period << 10;
+ /* update the tsf_cfprep register */
+ /* since init path would reset to default value */
+ W_REG(wlc->osh, &regs->tsf_cfprep,
+ (bi << CFPREP_CBI_SHIFT));
+
+ /* Update maccontrol PM related bits */
+ wlc_set_ps_ctrl(wlc);
+
+ break;
+ }
+ }
+ }
+
+ wlc_key_hw_init_all(wlc);
+
+ wlc_bandinit_ordered(wlc, chanspec);
+
+ wlc_init_scb(wlc, &global_scb);
+
+ /* init probe response timeout */
+ wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
+
+ /* init max burst txop (framebursting) */
+ wlc_write_shm(wlc, M_MBURST_TXOP,
+ (wlc->
+ _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
+
+ /* initialize maximum allowed duty cycle */
+ wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, TRUE, TRUE);
+ wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, FALSE, TRUE);
+
+ /* Update some shared memory locations related to max AMPDU size allowed to received */
+ wlc_ampdu_shm_upd(wlc->ampdu);
+
+ /* band-specific inits */
+ wlc_bsinit(wlc);
+
+ /* Enable EDCF mode (while the MAC is suspended) */
+ if (EDCF_ENAB(wlc->pub)) {
+ OR_REG(wlc->osh, &regs->ifs_ctl, IFS_USEEDCF);
+ wlc_edcf_setparams(wlc->cfg, FALSE);
+ }
+
+ /* Init precedence maps for empty FIFOs */
+ wlc_tx_prec_map_init(wlc);
+
+ /* read the ucode version if we have not yet done so */
+ if (wlc->ucode_rev == 0) {
+ wlc->ucode_rev =
+ wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(uint16);
+ wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR);
+ }
+
+ /* ..now really unleash hell (allow the MAC out of suspend) */
+ wlc_enable_mac(wlc);
+
+ /* clear tx flow control */
+ wlc_txflowcontrol_reset(wlc);
+
+ /* clear tx data fifo suspends */
+ wlc->tx_suspended = FALSE;
+
+ /* enable the RF Disable Delay timer */
+ if (D11REV_GE(wlc->pub->corerev, 10))
+ W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
+
+ /* initialize mpc delay */
+ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+
+ /*
+ * Initialize WME parameters; if they haven't been set by some other
+ * mechanism (IOVar, etc) then read them from the hardware.
+ */
+ if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */
+ int ac;
+
+ ASSERT(wlc->clk);
+ for (ac = 0; ac < AC_COUNT; ac++) {
+ wlc->wme_retries[ac] =
+ wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
+ }
+ }
+}
+
+void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc)
+{
+ wlc->bcnmisc_monitor = promisc;
+ wlc_mac_bcn_promisc(wlc);
+}
+
+void wlc_mac_bcn_promisc(wlc_info_t *wlc)
+{
+ if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
+ wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
+ wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
+ else
+ wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
+}
+
+/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
+void wlc_mac_promisc(wlc_info_t *wlc)
+{
+ uint32 promisc_bits = 0;
+
+ /* promiscuous mode just sets MCTL_PROMISC
+ * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
+ * since all BSS data traffic is directed at the AP
+ */
+ if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet)
+ promisc_bits |= MCTL_PROMISC;
+
+ /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
+ * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
+ * handled in wlc_mac_bcn_promisc()
+ */
+ if (MONITOR_ENAB(wlc))
+ promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
+
+ wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
+}
+
+/* check if hps and wake states of sw and hw are in sync */
+bool wlc_ps_check(wlc_info_t *wlc)
+{
+ bool res = TRUE;
+ bool hps, wake;
+ bool wake_ok;
+
+ if (!AP_ACTIVE(wlc)) {
+ volatile uint32 tmp;
+ tmp = R_REG(wlc->osh, &wlc->regs->maccontrol);
+
+ /* If deviceremoved is detected, then don't take any action as this can be called
+ * in any context. Assume that caller will take care of the condition. This is just
+ * to avoid assert
+ */
+ if (tmp == 0xffffffff) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit,
+ __func__));
+ return DEVICEREMOVED(wlc);
+ }
+
+ hps = PS_ALLOWED(wlc);
+
+ if (hps != ((tmp & MCTL_HPS) != 0)) {
+ int idx;
+ wlc_bsscfg_t *cfg;
+ WL_ERROR(("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", wlc->pub->unit, hps, tmp));
+ FOREACH_BSS(wlc, idx, cfg) {
+ if (!BSSCFG_STA(cfg))
+ continue;
+ }
+
+ res = FALSE;
+ }
+#ifdef WLC_LOW
+ /* For a monolithic build the wake check can be exact since it looks at wake
+ * override bits. The MCTL_WAKE bit should match the 'wake' value.
+ */
+ wake = STAY_AWAKE(wlc) || wlc->hw->wake_override;
+ wake_ok = (wake == ((tmp & MCTL_WAKE) != 0));
+#else
+ /* For a split build we will not have access to any wake overrides from the low
+ * level. The check can only make sure the MCTL_WAKE bit is on if the high
+ * level 'wake' value is true. If the high level 'wake' is false, the MCTL_WAKE
+ * may be either true or false due to the low level override.
+ */
+ wake = STAY_AWAKE(wlc);
+ wake_ok = (wake && ((tmp & MCTL_WAKE) != 0)) || !wake;
+#endif
+ if (hps && !wake_ok) {
+ WL_ERROR(("wl%d: wake not sync, sw %d maccontrol 0x%x\n", wlc->pub->unit, wake, tmp));
+ res = FALSE;
+ }
+ }
+ ASSERT(res);
+ return res;
+}
+
+/* push sw hps and wake state through hardware */
+void wlc_set_ps_ctrl(wlc_info_t *wlc)
+{
+ uint32 v1, v2;
+ bool hps, wake;
+ bool awake_before;
+
+ hps = PS_ALLOWED(wlc);
+ wake = hps ? (STAY_AWAKE(wlc)) : TRUE;
+
+ WL_TRACE(("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", wlc->pub->unit,
+ hps, wake));
+
+ v1 = R_REG(wlc->osh, &wlc->regs->maccontrol);
+ v2 = 0;
+ if (hps)
+ v2 |= MCTL_HPS;
+ if (wake)
+ v2 |= MCTL_WAKE;
+
+ wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
+
+ awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
+
+ if (wake && !awake_before)
+ wlc_bmac_wait_for_wake(wlc->hw);
+
+}
+
+/*
+ * Write this BSS config's MAC address to core.
+ * Updates RXE match engine.
+ */
+int wlc_set_mac(wlc_bsscfg_t *cfg)
+{
+ int err = 0;
+ wlc_info_t *wlc = cfg->wlc;
+
+ if (cfg == wlc->cfg) {
+ /* enter the MAC addr into the RXE match registers */
+ wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, &cfg->cur_etheraddr);
+ }
+
+ wlc_ampdu_macaddr_upd(wlc);
+
+ return err;
+}
+
+/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
+ * Updates RXE match engine.
+ */
+void wlc_set_bssid(wlc_bsscfg_t *cfg)
+{
+ wlc_info_t *wlc = cfg->wlc;
+
+ /* if primary config, we need to update BSSID in RXE match registers */
+ if (cfg == wlc->cfg) {
+ wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, &cfg->BSSID);
+ }
+#ifdef SUPPORT_HWKEYS
+ else if (BSSCFG_STA(cfg) && cfg->BSS) {
+ wlc_rcmta_add_bssid(wlc, cfg);
+ }
+#endif
+}
+
+/*
+ * Suspend the the MAC and update the slot timing
+ * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
+ */
+void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot)
+{
+ int idx;
+ wlc_bsscfg_t *cfg;
+
+ ASSERT(wlc->band->gmode);
+
+ /* use the override if it is set */
+ if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO)
+ shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON);
+
+ if (wlc->shortslot == shortslot)
+ return;
+
+ wlc->shortslot = shortslot;
+
+ /* update the capability based on current shortslot mode */
+ FOREACH_BSS(wlc, idx, cfg) {
+ if (!cfg->associated)
+ continue;
+ cfg->current_bss->capability &= ~DOT11_CAP_SHORTSLOT;
+ if (wlc->shortslot)
+ cfg->current_bss->capability |= DOT11_CAP_SHORTSLOT;
+ }
+
+ wlc_bmac_set_shortslot(wlc->hw, shortslot);
+}
+
+static uint8 wlc_local_constraint_qdbm(wlc_info_t *wlc)
+{
+ uint8 local;
+ int16 local_max;
+
+ local = WLC_TXPWR_MAX;
+ if (wlc->pub->associated &&
+ (wf_chspec_ctlchan(wlc->chanspec) ==
+ wf_chspec_ctlchan(wlc->home_chanspec))) {
+
+ /* get the local power constraint if we are on the AP's
+ * channel [802.11h, 7.3.2.13]
+ */
+ /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */
+ local_max =
+ (wlc->txpwr_local_max -
+ wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR;
+ if (local_max > 0 && local_max < WLC_TXPWR_MAX)
+ return (uint8) local_max;
+ if (local_max < 0)
+ return 0;
+ }
+
+ return local;
+}
+
+/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
+void wlc_set_home_chanspec(wlc_info_t *wlc, chanspec_t chanspec)
+{
+ if (wlc->home_chanspec != chanspec) {
+ int idx;
+ wlc_bsscfg_t *cfg;
+
+ wlc->home_chanspec = chanspec;
+
+ FOREACH_BSS(wlc, idx, cfg) {
+ if (!cfg->associated)
+ continue;
+ cfg->target_bss->chanspec = chanspec;
+ cfg->current_bss->chanspec = chanspec;
+ }
+
+ }
+}
+
+static void wlc_set_phy_chanspec(wlc_info_t *wlc, chanspec_t chanspec)
+{
+ /* Save our copy of the chanspec */
+ wlc->chanspec = chanspec;
+
+ /* Set the chanspec and power limits for this locale after computing
+ * any 11h local tx power constraints.
+ */
+ wlc_channel_set_chanspec(wlc->cmi, chanspec,
+ wlc_local_constraint_qdbm(wlc));
+
+ if (wlc->stf->ss_algosel_auto)
+ wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
+ chanspec);
+
+ wlc_stf_ss_update(wlc, wlc->band);
+
+}
+
+void wlc_set_chanspec(wlc_info_t *wlc, chanspec_t chanspec)
+{
+ uint bandunit;
+ bool switchband = FALSE;
+ chanspec_t old_chanspec = wlc->chanspec;
+
+ if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
+ WL_ERROR(("wl%d: %s: Bad channel %d\n",
+ wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)));
+ ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
+ return;
+ }
+
+ /* Switch bands if necessary */
+ if (NBANDS(wlc) > 1) {
+ bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+ if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
+ switchband = TRUE;
+ if (wlc->bandlocked) {
+ WL_ERROR(("wl%d: %s: chspec %d band is locked!\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)));
+ return;
+ }
+ /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ?
+ * if the setband updates (wlc_bsinit) use low level calls to inspect and
+ * set state, the state inspected may be from the wrong band, or the
+ * following wlc_bmac_set_chanspec() may undo the work.
+ */
+ wlc_setband(wlc, bandunit);
+ }
+ }
+
+ ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec));
+
+ /* sync up phy/radio chanspec */
+ wlc_set_phy_chanspec(wlc, chanspec);
+
+ /* init antenna selection */
+ if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
+ if (WLANTSEL_ENAB(wlc))
+ wlc_antsel_init(wlc->asi);
+
+ /* Fix the hardware rateset based on bw.
+ * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
+ */
+ wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
+ wlc->band->
+ mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
+ : 0);
+ }
+
+ /* update some mac configuration since chanspec changed */
+ wlc_ucode_mac_upd(wlc);
+}
+
+#if defined(BCMDBG)
+static int wlc_get_current_txpwr(wlc_info_t *wlc, void *pwr, uint len)
+{
+ txpwr_limits_t txpwr;
+ tx_power_t power;
+ tx_power_legacy_t *old_power = NULL;
+ int r, c;
+ uint qdbm;
+ bool override;
+
+ if (len == sizeof(tx_power_legacy_t))
+ old_power = (tx_power_legacy_t *) pwr;
+ else if (len < sizeof(tx_power_t))
+ return BCME_BUFTOOSHORT;
+
+ bzero(&power, sizeof(tx_power_t));
+
+ power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC;
+ if (wlc->pub->associated)
+ power.local_chanspec = wlc->home_chanspec;
+
+ /* Return the user target tx power limits for the various rates. Note wlc_phy.c's
+ * public interface only implements getting and setting a single value for all of
+ * rates, so we need to fill the array ourselves.
+ */
+ wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
+ for (r = 0; r < WL_TX_POWER_RATES; r++) {
+ power.user_limit[r] = (uint8) qdbm;
+ }
+
+ power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR;
+ power.local_constraint =
+ wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR;
+
+ power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain;
+ power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain;
+
+ wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr);
+
+#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK
+#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK"
+#endif
+
+ /* CCK tx power limits */
+ for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM;
+ c++, r++)
+ power.reg_limit[r] = txpwr.cck[c];
+
+#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM
+#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM"
+#endif
+
+ /* 20 MHz OFDM SISO tx power limits */
+ for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM;
+ c++, r++)
+ power.reg_limit[r] = txpwr.ofdm[c];
+
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+
+ /* 20 MHz OFDM CDD tx power limits */
+ for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST;
+ c < WL_TX_POWER_OFDM_NUM; c++, r++)
+ power.reg_limit[r] = txpwr.ofdm_cdd[c];
+
+ /* 40 MHz OFDM SISO tx power limits */
+ for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST;
+ c < WL_TX_POWER_OFDM_NUM; c++, r++)
+ power.reg_limit[r] = txpwr.ofdm_40_siso[c];
+
+ /* 40 MHz OFDM CDD tx power limits */
+ for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST;
+ c < WL_TX_POWER_OFDM_NUM; c++, r++)
+ power.reg_limit[r] = txpwr.ofdm_40_cdd[c];
+
+#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM
+#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM"
+#endif
+
+ /* 20MHz MCS0-7 SISO tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_20_siso[c];
+
+ /* 20MHz MCS0-7 CDD tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_20_cdd[c];
+
+ /* 20MHz MCS0-7 STBC tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_20_stbc[c];
+
+ /* 40MHz MCS0-7 SISO tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_40_siso[c];
+
+ /* 40MHz MCS0-7 CDD tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_40_cdd[c];
+
+ /* 40MHz MCS0-7 STBC tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST;
+ c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_40_stbc[c];
+
+#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM
+#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM"
+#endif
+
+ /* 20MHz MCS8-15 SDM tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST;
+ c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_20_mimo[c];
+
+ /* 40MHz MCS8-15 SDM tx power limits */
+ for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST;
+ c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+ power.reg_limit[r] = txpwr.mcs_40_mimo[c];
+
+ /* MCS 32 */
+ power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32;
+ }
+
+ wlc_phy_txpower_get_current(wlc->band->pi, &power,
+ CHSPEC_CHANNEL(power.chanspec));
+
+ /* copy the tx_power_t struct to the return buffer,
+ * or convert to a tx_power_legacy_t struct
+ */
+ if (!old_power) {
+ bcopy(&power, pwr, sizeof(tx_power_t));
+ } else {
+ int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1;
+
+ bzero(old_power, sizeof(tx_power_legacy_t));
+
+ old_power->txpwr_local_max = power.local_max;
+ old_power->txpwr_local_constraint = power.local_constraint;
+ if (CHSPEC_IS2G(power.chanspec)) {
+ old_power->txpwr_chan_reg_max = txpwr.cck[0];
+ old_power->txpwr_est_Pout[band_idx] =
+ power.est_Pout_cck;
+ old_power->txpwr_est_Pout_gofdm = power.est_Pout[0];
+ } else {
+ old_power->txpwr_chan_reg_max = txpwr.ofdm[0];
+ old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0];
+ }
+ old_power->txpwr_antgain[0] = power.antgain[0];
+ old_power->txpwr_antgain[1] = power.antgain[1];
+
+ for (r = 0; r < NUM_PWRCTRL_RATES; r++) {
+ old_power->txpwr_band_max[r] = power.user_limit[r];
+ old_power->txpwr_limit[r] = power.reg_limit[r];
+ old_power->txpwr_target[band_idx][r] = power.target[r];
+ if (CHSPEC_IS2G(power.chanspec))
+ old_power->txpwr_bphy_cck_max[r] =
+ power.board_limit[r];
+ else
+ old_power->txpwr_aphy_max[r] =
+ power.board_limit[r];
+ }
+ }
+
+ return 0;
+}
+#endif /* defined(BCMDBG) */
+
+static uint32 wlc_watchdog_backup_bi(wlc_info_t *wlc)
+{
+ uint32 bi;
+ bi = 2 * wlc->cfg->current_bss->dtim_period *
+ wlc->cfg->current_bss->beacon_period;
+ if (wlc->bcn_li_dtim)
+ bi *= wlc->bcn_li_dtim;
+ else if (wlc->bcn_li_bcn)
+ /* recalculate bi based on bcn_li_bcn */
+ bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period;
+
+ if (bi < 2 * TIMER_INTERVAL_WATCHDOG)
+ bi = 2 * TIMER_INTERVAL_WATCHDOG;
+ return bi;
+}
+
+/* Change to run the watchdog either from a periodic timer or from tbtt handler.
+ * Call watchdog from tbtt handler if tbtt is TRUE, watchdog timer otherwise.
+ */
+void wlc_watchdog_upd(wlc_info_t *wlc, bool tbtt)
+{
+ /* make sure changing watchdog driver is allowed */
+ if (!wlc->pub->up || !wlc->pub->align_wd_tbtt)
+ return;
+ if (!tbtt && wlc->WDarmed) {
+ wl_del_timer(wlc->wl, wlc->wdtimer);
+ wlc->WDarmed = FALSE;
+ }
+
+ /* stop watchdog timer and use tbtt interrupt to drive watchdog */
+ if (tbtt && wlc->WDarmed) {
+ wl_del_timer(wlc->wl, wlc->wdtimer);
+ wlc->WDarmed = FALSE;
+ wlc->WDlast = OSL_SYSUPTIME();
+ }
+ /* arm watchdog timer and drive the watchdog there */
+ else if (!tbtt && !wlc->WDarmed) {
+ wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+ TRUE);
+ wlc->WDarmed = TRUE;
+ }
+ if (tbtt && !wlc->WDarmed) {
+ wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc),
+ TRUE);
+ wlc->WDarmed = TRUE;
+ }
+}
+
+ratespec_t wlc_lowest_basic_rspec(wlc_info_t *wlc, wlc_rateset_t *rs)
+{
+ ratespec_t lowest_basic_rspec;
+ uint i;
+
+ /* Use the lowest basic rate */
+ lowest_basic_rspec = rs->rates[0] & RATE_MASK;
+ for (i = 0; i < rs->count; i++) {
+ if (rs->rates[i] & WLC_RATE_FLAG) {
+ lowest_basic_rspec = rs->rates[i] & RATE_MASK;
+ break;
+ }
+ }
+#if NCONF
+ /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
+ if (IS_OFDM(lowest_basic_rspec)) {
+ lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+ }
+#endif
+
+ return lowest_basic_rspec;
+}
+
+/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
+ * setting as per this table:
+ * ratespec CCK ant = wlc->stf->txant
+ * OFDM ant = 3
+ */
+void wlc_beacon_phytxctl_txant_upd(wlc_info_t *wlc, ratespec_t bcn_rspec)
+{
+ uint16 phyctl;
+ uint16 phytxant = wlc->stf->phytxant;
+ uint16 mask = PHY_TXC_ANT_MASK;
+
+ /* for non-siso rates or default setting, use the available chains */
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec);
+ }
+
+ phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD);
+ phyctl = (phyctl & ~mask) | phytxant;
+ wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl);
+}
+
+/* centralized protection config change function to simplify debugging, no consistency checking
+ * this should be called only on changes to avoid overhead in periodic function
+*/
+void wlc_protection_upd(wlc_info_t *wlc, uint idx, int val)
+{
+ WL_TRACE(("wlc_protection_upd: idx %d, val %d\n", idx, val));
+
+ switch (idx) {
+ case WLC_PROT_G_SPEC:
+ wlc->protection->_g = (bool) val;
+ break;
+ case WLC_PROT_G_OVR:
+ wlc->protection->g_override = (int8) val;
+ break;
+ case WLC_PROT_G_USER:
+ wlc->protection->gmode_user = (uint8) val;
+ break;
+ case WLC_PROT_OVERLAP:
+ wlc->protection->overlap = (int8) val;
+ break;
+ case WLC_PROT_N_USER:
+ wlc->protection->nmode_user = (int8) val;
+ break;
+ case WLC_PROT_N_CFG:
+ wlc->protection->n_cfg = (int8) val;
+ break;
+ case WLC_PROT_N_CFG_OVR:
+ wlc->protection->n_cfg_override = (int8) val;
+ break;
+ case WLC_PROT_N_NONGF:
+ wlc->protection->nongf = (bool) val;
+ break;
+ case WLC_PROT_N_NONGF_OVR:
+ wlc->protection->nongf_override = (int8) val;
+ break;
+ case WLC_PROT_N_PAM_OVR:
+ wlc->protection->n_pam_override = (int8) val;
+ break;
+ case WLC_PROT_N_OBSS:
+ wlc->protection->n_obss = (bool) val;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+}
+
+static void wlc_ht_update_sgi_rx(wlc_info_t *wlc, int val)
+{
+ wlc->ht_cap.cap &= ~(HT_CAP_SHORT_GI_20 | HT_CAP_SHORT_GI_40);
+ wlc->ht_cap.cap |= (val & WLC_N_SGI_20) ? HT_CAP_SHORT_GI_20 : 0;
+ wlc->ht_cap.cap |= (val & WLC_N_SGI_40) ? HT_CAP_SHORT_GI_40 : 0;
+
+ if (wlc->pub->up) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ }
+}
+
+static void wlc_ht_update_ldpc(wlc_info_t *wlc, int8 val)
+{
+ wlc->stf->ldpc = val;
+
+ wlc->ht_cap.cap &= ~HT_CAP_LDPC_CODING;
+ if (wlc->stf->ldpc != OFF)
+ wlc->ht_cap.cap |= HT_CAP_LDPC_CODING;
+
+ if (wlc->pub->up) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ wlc_phy_ldpc_override_set(wlc->band->pi, (val ? TRUE : FALSE));
+ }
+}
+
+/*
+ * ucode, hwmac update
+ * Channel dependent updates for ucode and hw
+ */
+static void wlc_ucode_mac_upd(wlc_info_t *wlc)
+{
+ /* enable or disable any active IBSSs depending on whether or not
+ * we are on the home channel
+ */
+ if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) {
+ if (wlc->pub->associated) {
+ /* BMAC_NOTE: This is something that should be fixed in ucode inits.
+ * I think that the ucode inits set up the bcn templates and shm values
+ * with a bogus beacon. This should not be done in the inits. If ucode needs
+ * to set up a beacon for testing, the test routines should write it down,
+ * not expect the inits to populate a bogus beacon.
+ */
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET,
+ wlc->band->bcntsfoff);
+ }
+ }
+ } else {
+ /* disable an active IBSS if we are not on the home channel */
+ }
+
+ /* update the various promisc bits */
+ wlc_mac_bcn_promisc(wlc);
+ wlc_mac_promisc(wlc);
+}
+
+static void wlc_bandinit_ordered(wlc_info_t *wlc, chanspec_t chanspec)
+{
+ wlc_rateset_t default_rateset;
+ uint parkband;
+ uint i, band_order[2];
+
+ WL_TRACE(("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit));
+ /*
+ * We might have been bandlocked during down and the chip power-cycled (hibernate).
+ * figure out the right band to park on
+ */
+ if (wlc->bandlocked || NBANDS(wlc) == 1) {
+ ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);
+
+ parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */
+ band_order[0] = band_order[1] = parkband;
+ } else {
+ /* park on the band of the specified chanspec */
+ parkband = CHSPEC_WLCBANDUNIT(chanspec);
+
+ /* order so that parkband initialize last */
+ band_order[0] = parkband ^ 1;
+ band_order[1] = parkband;
+ }
+
+ /* make each band operational, software state init */
+ for (i = 0; i < NBANDS(wlc); i++) {
+ uint j = band_order[i];
+
+ wlc->band = wlc->bandstate[j];
+
+ wlc_default_rateset(wlc, &default_rateset);
+
+ /* fill in hw_rate */
+ wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
+ FALSE, WLC_RATES_CCK_OFDM, RATE_MASK,
+ (bool) N_ENAB(wlc->pub));
+
+ /* init basic rate lookup */
+ wlc_rate_lookup_init(wlc, &default_rateset);
+ }
+
+ /* sync up phy/radio chanspec */
+ wlc_set_phy_chanspec(wlc, chanspec);
+}
+
+/* band-specific init */
+static void WLBANDINITFN(wlc_bsinit) (wlc_info_t *wlc)
+{
+ WL_TRACE(("wl%d: wlc_bsinit: bandunit %d\n", wlc->pub->unit,
+ wlc->band->bandunit));
+
+ /* write ucode ACK/CTS rate table */
+ wlc_set_ratetable(wlc);
+
+ /* update some band specific mac configuration */
+ wlc_ucode_mac_upd(wlc);
+
+ /* init antenna selection */
+ if (WLANTSEL_ENAB(wlc))
+ wlc_antsel_init(wlc->asi);
+
+}
+
+/* switch to and initialize new band */
+static void WLBANDINITFN(wlc_setband) (wlc_info_t *wlc, uint bandunit)
+{
+ int idx;
+ wlc_bsscfg_t *cfg;
+
+ ASSERT(NBANDS(wlc) > 1);
+ ASSERT(!wlc->bandlocked);
+ ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending);
+
+ wlc->band = wlc->bandstate[bandunit];
+
+ if (!wlc->pub->up)
+ return;
+
+ /* wait for at least one beacon before entering sleeping state */
+ wlc->PMawakebcn = TRUE;
+ FOREACH_AS_STA(wlc, idx, cfg)
+ cfg->PMawakebcn = TRUE;
+ wlc_set_ps_ctrl(wlc);
+
+ /* band-specific initializations */
+ wlc_bsinit(wlc);
+}
+
+/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
+void wlc_wme_initparams_sta(wlc_info_t *wlc, wme_param_ie_t *pe)
+{
+ static const wme_param_ie_t stadef = {
+ WME_OUI,
+ WME_TYPE,
+ WME_SUBTYPE_PARAM_IE,
+ WME_VER,
+ 0,
+ 0,
+ {
+ {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
+ HTOL16(EDCF_AC_BE_TXOP_STA)},
+ {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
+ HTOL16(EDCF_AC_BK_TXOP_STA)},
+ {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
+ HTOL16(EDCF_AC_VI_TXOP_STA)},
+ {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
+ HTOL16(EDCF_AC_VO_TXOP_STA)}
+ }
+ };
+
+ ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN);
+ memcpy(pe, &stadef, sizeof(*pe));
+}
+
+void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend)
+{
+ int i;
+ shm_acparams_t acp_shm;
+ uint16 *shm_entry;
+ struct ieee80211_tx_queue_params *params = arg;
+
+ ASSERT(wlc);
+
+ /* Only apply params if the core is out of reset and has clocks */
+ if (!wlc->clk) {
+ WL_ERROR(("wl%d: %s : no-clock\n", wlc->pub->unit, __func__));
+ return;
+ }
+
+ /*
+ * AP uses AC params from wme_param_ie_ap.
+ * AP advertises AC params from wme_param_ie.
+ * STA uses AC params from wme_param_ie.
+ */
+
+ wlc->wme_admctl = 0;
+
+ do {
+ bzero((char *)&acp_shm, sizeof(shm_acparams_t));
+ /* find out which ac this set of params applies to */
+ ASSERT(aci < AC_COUNT);
+ /* set the admission control policy for this AC */
+ /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */
+
+ /* fill in shm ac params struct */
+ acp_shm.txop = ltoh16(params->txop);
+ /* convert from units of 32us to us for ucode */
+ wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
+ EDCF_TXOP2USEC(acp_shm.txop);
+ acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
+
+ if (aci == AC_VI && acp_shm.txop == 0
+ && acp_shm.aifs < EDCF_AIFSN_MAX)
+ acp_shm.aifs++;
+
+ if (acp_shm.aifs < EDCF_AIFSN_MIN
+ || acp_shm.aifs > EDCF_AIFSN_MAX) {
+ WL_ERROR(("wl%d: wlc_edcf_setparams: bad aifs %d\n",
+ wlc->pub->unit, acp_shm.aifs));
+ continue;
+ }
+
+ acp_shm.cwmin = params->cw_min;
+ acp_shm.cwmax = params->cw_max;
+ acp_shm.cwcur = acp_shm.cwmin;
+ acp_shm.bslots =
+ R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur;
+ acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
+ /* Indicate the new params to the ucode */
+ acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
+ wme_shmemacindex(aci) *
+ M_EDCF_QLEN +
+ M_EDCF_STATUS_OFF));
+ acp_shm.status |= WME_STATUS_NEWAC;
+
+ /* Fill in shm acparam table */
+ shm_entry = (uint16 *) &acp_shm;
+ for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2)
+ wlc_write_shm(wlc,
+ M_EDCF_QINFO +
+ wme_shmemacindex(aci) * M_EDCF_QLEN + i,
+ *shm_entry++);
+
+ } while (0);
+
+ if (suspend)
+ wlc_suspend_mac_and_wait(wlc);
+
+ if (suspend)
+ wlc_enable_mac(wlc);
+
+}
+
+void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend)
+{
+ wlc_info_t *wlc = cfg->wlc;
+ uint aci, i, j;
+ edcf_acparam_t *edcf_acp;
+ shm_acparams_t acp_shm;
+ uint16 *shm_entry;
+
+ ASSERT(cfg);
+ ASSERT(wlc);
+
+ /* Only apply params if the core is out of reset and has clocks */
+ if (!wlc->clk)
+ return;
+
+ /*
+ * AP uses AC params from wme_param_ie_ap.
+ * AP advertises AC params from wme_param_ie.
+ * STA uses AC params from wme_param_ie.
+ */
+
+ edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0];
+
+ wlc->wme_admctl = 0;
+
+ for (i = 0; i < AC_COUNT; i++, edcf_acp++) {
+ bzero((char *)&acp_shm, sizeof(shm_acparams_t));
+ /* find out which ac this set of params applies to */
+ aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
+ ASSERT(aci < AC_COUNT);
+ /* set the admission control policy for this AC */
+ if (edcf_acp->ACI & EDCF_ACM_MASK) {
+ wlc->wme_admctl |= 1 << aci;
+ }
+
+ /* fill in shm ac params struct */
+ acp_shm.txop = ltoh16(edcf_acp->TXOP);
+ /* convert from units of 32us to us for ucode */
+ wlc->edcf_txop[aci] = acp_shm.txop =
+ EDCF_TXOP2USEC(acp_shm.txop);
+ acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK);
+
+ if (aci == AC_VI && acp_shm.txop == 0
+ && acp_shm.aifs < EDCF_AIFSN_MAX)
+ acp_shm.aifs++;
+
+ if (acp_shm.aifs < EDCF_AIFSN_MIN
+ || acp_shm.aifs > EDCF_AIFSN_MAX) {
+ WL_ERROR(("wl%d: wlc_edcf_setparams: bad aifs %d\n",
+ wlc->pub->unit, acp_shm.aifs));
+ continue;
+ }
+
+ /* CWmin = 2^(ECWmin) - 1 */
+ acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
+ /* CWmax = 2^(ECWmax) - 1 */
+ acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
+ >> EDCF_ECWMAX_SHIFT);
+ acp_shm.cwcur = acp_shm.cwmin;
+ acp_shm.bslots =
+ R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur;
+ acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
+ /* Indicate the new params to the ucode */
+ acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
+ wme_shmemacindex(aci) *
+ M_EDCF_QLEN +
+ M_EDCF_STATUS_OFF));
+ acp_shm.status |= WME_STATUS_NEWAC;
+
+ /* Fill in shm acparam table */
+ shm_entry = (uint16 *) &acp_shm;
+ for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2)
+ wlc_write_shm(wlc,
+ M_EDCF_QINFO +
+ wme_shmemacindex(aci) * M_EDCF_QLEN + j,
+ *shm_entry++);
+ }
+
+ if (suspend)
+ wlc_suspend_mac_and_wait(wlc);
+
+ if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, FALSE);
+ }
+
+ if (suspend)
+ wlc_enable_mac(wlc);
+
+}
+
+bool BCMATTACHFN(wlc_timers_init) (wlc_info_t *wlc, int unit)
+{
+ wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer,
+ wlc, "watchdog");
+ if (!wlc->wdtimer) {
+ WL_ERROR(("wl%d: wl_init_timer for wdtimer failed\n", unit));
+ goto fail;
+ }
+
+ wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer,
+ wlc, "radio");
+ if (!wlc->radio_timer) {
+ WL_ERROR(("wl%d: wl_init_timer for radio_timer failed\n",
+ unit));
+ goto fail;
+ }
+
+ return TRUE;
+
+ fail:
+ return FALSE;
+}
+
+/*
+ * Initialize wlc_info default values ...
+ * may get overrides later in this function
+ */
+void BCMATTACHFN(wlc_info_init) (wlc_info_t *wlc, int unit)
+{
+ int i;
+ /* Assume the device is there until proven otherwise */
+ wlc->device_present = TRUE;
+
+ /* set default power output percentage to 100 percent */
+ wlc->txpwr_percent = 100;
+
+ /* Save our copy of the chanspec */
+ wlc->chanspec = CH20MHZ_CHSPEC(1);
+
+ /* initialize CCK preamble mode to unassociated state */
+ wlc->shortpreamble = FALSE;
+
+ wlc->legacy_probe = TRUE;
+
+ /* various 802.11g modes */
+ wlc->shortslot = FALSE;
+ wlc->shortslot_override = WLC_SHORTSLOT_AUTO;
+
+ wlc->barker_overlap_control = TRUE;
+ wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED;
+ wlc->txburst_limit_override = AUTO;
+
+ wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO);
+ wlc_protection_upd(wlc, WLC_PROT_G_SPEC, FALSE);
+
+ wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO);
+ wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF);
+ wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO);
+ wlc_protection_upd(wlc, WLC_PROT_N_NONGF, FALSE);
+ wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO);
+
+ wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP);
+
+ /* 802.11g draft 4.0 NonERP elt advertisement */
+ wlc->include_legacy_erp = TRUE;
+
+ wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
+ wlc->stf->txant = ANT_TX_DEF;
+
+ wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT;
+
+ wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
+ for (i = 0; i < NFIFO; i++)
+ wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
+ wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
+
+ /* default rate fallback retry limits */
+ wlc->SFBL = RETRY_SHORT_FB;
+ wlc->LFBL = RETRY_LONG_FB;
+
+ /* default mac retry limits */
+ wlc->SRL = RETRY_SHORT_DEF;
+ wlc->LRL = RETRY_LONG_DEF;
+
+ /* init PM state */
+ wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */
+ wlc->PM_override = FALSE; /* Prevents from going to PM if our AP is 'ill' */
+ wlc->PMenabled = FALSE; /* Current PM state */
+ wlc->PMpending = FALSE; /* Tracks whether STA indicated PM in the last attempt */
+ wlc->PMblocked = FALSE; /* To allow blocking going into PM during RM and scans */
+
+ /* In WMM Auto mode, PM is allowed if association is a UAPSD association */
+ wlc->WME_PM_blocked = FALSE;
+
+ /* Init wme queuing method */
+ wlc->wme_prec_queuing = FALSE;
+
+ /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */
+ wlc->wake = FALSE;
+ /* Are we waiting for a response to PS-Poll that we sent */
+ wlc->PSpoll = FALSE;
+
+ /* APSD defaults */
+ wlc->wme_apsd = TRUE;
+ wlc->apsd_sta_usp = FALSE;
+ wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */
+ wlc->apsd_trigger_ac = AC_BITMAP_ALL;
+
+ /* Set flag to indicate that hw keys should be used when available. */
+ wlc->wsec_swkeys = FALSE;
+
+ /* init the 4 static WEP default keys */
+ for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+ wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
+ wlc->wsec_keys[i]->idx = (uint8) i;
+ }
+
+ wlc->_regulatory_domain = FALSE; /* 802.11d */
+
+ /* WME QoS mode is Auto by default */
+ wlc->pub->_wme = AUTO;
+
+#ifdef BCMSDIODEV_ENABLED
+ wlc->pub->_priofc = TRUE; /* enable priority flow control for sdio dongle */
+#endif
+
+ wlc->pub->_ampdu = AMPDU_AGG_HOST;
+ wlc->pub->bcmerror = 0;
+ wlc->ibss_allowed = TRUE;
+ wlc->ibss_coalesce_allowed = TRUE;
+ wlc->pub->_coex = ON;
+
+ /* intialize mpc delay */
+ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+
+ wlc->pr80838_war = TRUE;
+}
+
+static bool wlc_state_bmac_sync(wlc_info_t *wlc)
+{
+ wlc_bmac_state_t state_bmac;
+
+ if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0)
+ return FALSE;
+
+ wlc->machwcap = state_bmac.machwcap;
+ wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR,
+ (int8) state_bmac.preamble_ovr);
+
+ return TRUE;
+}
+
+static uint BCMATTACHFN(wlc_attach_module) (wlc_info_t *wlc)
+{
+ uint err = 0;
+ uint unit;
+ unit = wlc->pub->unit;
+
+ wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw);
+ if (wlc->asi == NULL) {
+ WL_ERROR(("wl%d: wlc_attach: wlc_antsel_attach failed\n",
+ unit));
+ err = 44;
+ goto fail;
+ }
+
+ wlc->ampdu = wlc_ampdu_attach(wlc);
+ if (wlc->ampdu == NULL) {
+ WL_ERROR(("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit));
+ err = 50;
+ goto fail;
+ }
+
+ /* Initialize event queue; needed before following calls */
+ wlc->eventq =
+ wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq);
+ if (wlc->eventq == NULL) {
+ WL_ERROR(("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit));
+ err = 57;
+ goto fail;
+ }
+
+ if ((wlc_stf_attach(wlc) != 0)) {
+ WL_ERROR(("wl%d: wlc_attach: wlc_stf_attach failed\n", unit));
+ err = 68;
+ goto fail;
+ }
+ fail:
+ return err;
+}
+
+wlc_pub_t *wlc_pub(void *wlc)
+{
+ return ((wlc_info_t *) wlc)->pub;
+}
+
+#define CHIP_SUPPORTS_11N(wlc) 1
+
+/*
+ * The common driver entry routine. Error codes should be unique
+ */
+void *BCMATTACHFN(wlc_attach) (void *wl, uint16 vendor, uint16 device,
+ uint unit, bool piomode, osl_t *osh,
+ void *regsva, uint bustype, void *btparam,
+ uint *perr) {
+ wlc_info_t *wlc;
+ uint err = 0;
+ uint j;
+ wlc_pub_t *pub;
+ wlc_txq_info_t *qi;
+ uint n_disabled;
+
+ WL_NONE(("wl%d: %s: vendor 0x%x device 0x%x\n", unit, __func__, vendor,
+ device));
+
+ ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS);
+ ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS);
+
+ /* some code depends on packed structures */
+ ASSERT(sizeof(struct ether_addr) == ETHER_ADDR_LEN);
+ ASSERT(sizeof(struct ether_header) == ETHER_HDR_LEN);
+ ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE);
+ ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN);
+ ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN);
+ ASSERT(sizeof(d11txh_t) == D11_TXH_LEN);
+ ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN);
+ ASSERT(sizeof(struct dot11_llc_snap_header) == DOT11_LLC_SNAP_HDR_LEN);
+ ASSERT(sizeof(struct dot11_header) == DOT11_A4_HDR_LEN);
+ ASSERT(sizeof(struct dot11_rts_frame) == DOT11_RTS_LEN);
+ ASSERT(sizeof(struct dot11_cts_frame) == DOT11_CTS_LEN);
+ ASSERT(sizeof(struct dot11_ack_frame) == DOT11_ACK_LEN);
+ ASSERT(sizeof(struct dot11_ps_poll_frame) == DOT11_PS_POLL_LEN);
+ ASSERT(sizeof(struct dot11_cf_end_frame) == DOT11_CS_END_LEN);
+ ASSERT(sizeof(struct dot11_management_header) == DOT11_MGMT_HDR_LEN);
+ ASSERT(sizeof(struct dot11_auth) == DOT11_AUTH_FIXED_LEN);
+ ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN);
+ ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN);
+ ASSERT(sizeof(ht_add_ie_t) == HT_ADD_IE_LEN);
+ ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN);
+ ASSERT(OFFSETOF(wl_scan_params_t, channel_list) ==
+ WL_SCAN_PARAMS_FIXED_SIZE);
+ ASSERT(TKIP_MIC_SIZE == (2 * sizeof(uint32)));
+ ASSERT(ISALIGNED(OFFSETOF(wsec_key_t, data), sizeof(uint32)));
+ ASSERT(ISPOWEROF2(MA_WINDOW_SZ));
+
+ ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF);
+
+ /*
+ * Number of replay counters value used in WPA IE must match # rxivs
+ * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17
+ * 'RSN Information Element' figure 8 for this mapping.
+ */
+ ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
+ && 16 == WLC_NUMRXIVS)
+ || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
+ && 4 == WLC_NUMRXIVS));
+
+ /* allocate wlc_info_t state and its substructures */
+ wlc = (wlc_info_t *) wlc_attach_malloc(osh, unit, &err, device);
+ if (wlc == NULL)
+ goto fail;
+ wlc->osh = osh;
+ pub = wlc->pub;
+
+#if defined(BCMDBG)
+ wlc_info_dbg = wlc;
+#endif
+
+ wlc->band = wlc->bandstate[0];
+ wlc->core = wlc->corestate;
+ wlc->wl = wl;
+ pub->unit = unit;
+ pub->osh = osh;
+ wlc->btparam = btparam;
+ pub->_piomode = piomode;
+ wlc->bandinit_pending = FALSE;
+ /* By default restrict TKIP associations from 11n STA's */
+ wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT;
+
+ /* populate wlc_info_t with default values */
+ wlc_info_init(wlc, unit);
+
+ /* update sta/ap related parameters */
+ wlc_ap_upd(wlc);
+
+ /* 11n_disable nvram */
+ n_disabled = getintvar(pub->vars, "11n_disable");
+
+ /* register a module (to handle iovars) */
+ wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc,
+ wlc_doiovar, NULL, NULL);
+
+ /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */
+ err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva,
+ bustype, btparam);
+ if (err)
+ goto fail;
+
+ /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
+ * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
+ */
+ if (!wlc_state_bmac_sync(wlc)) {
+ err = 20;
+ goto fail;
+ }
+
+ pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band);
+
+ /* propagate *vars* from BMAC driver to high driver */
+ wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
+
+#ifdef WLC_HIGH_ONLY
+ WL_TRACE(("nvram : vars %p , vars_size %d\n", pub->vars,
+ wlc->vars_size));
+#endif
+
+ /* set maximum allowed duty cycle */
+ wlc->tx_duty_cycle_ofdm =
+ (uint16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
+ wlc->tx_duty_cycle_cck =
+ (uint16) getintvar(pub->vars, "tx_duty_cycle_cck");
+
+ wlc_stf_phy_chain_calc(wlc);
+
+ /* txchain 1: txant 0, txchain 2: txant 1 */
+ if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+ wlc->stf->txant = wlc->stf->hw_txchain - 1;
+
+ /* push to BMAC driver */
+ wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
+ wlc->stf->hw_rxchain);
+
+#ifdef WLC_LOW
+ /* pull up some info resulting from the low attach */
+ {
+ int i;
+ for (i = 0; i < NFIFO; i++)
+ wlc->core->txavail[i] = wlc->hw->txavail[i];
+ }
+#endif /* WLC_LOW */
+
+ wlc_bmac_hw_etheraddr(wlc->hw, &wlc->perm_etheraddr);
+
+ bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr,
+ ETHER_ADDR_LEN);
+
+ for (j = 0; j < NBANDS(wlc); j++) {
+ /* Use band 1 for single band 11a */
+ if (IS_SINGLEBAND_5G(wlc->deviceid))
+ j = BAND_5G_INDEX;
+
+ wlc->band = wlc->bandstate[j];
+
+ if (!wlc_attach_stf_ant_init(wlc)) {
+ err = 24;
+ goto fail;
+ }
+
+ /* default contention windows size limits */
+ wlc->band->CWmin = APHY_CWMIN;
+ wlc->band->CWmax = PHY_CWMAX;
+
+ /* init gmode value */
+ if (BAND_2G(wlc->band->bandtype)) {
+ wlc->band->gmode = GMODE_AUTO;
+ wlc_protection_upd(wlc, WLC_PROT_G_USER,
+ wlc->band->gmode);
+ }
+
+ /* init _n_enab supported mode */
+ if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
+ if (n_disabled & WLFEATURE_DISABLE_11N) {
+ pub->_n_enab = OFF;
+ wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF);
+ } else {
+ pub->_n_enab = SUPPORT_11N;
+ wlc_protection_upd(wlc, WLC_PROT_N_USER,
+ ((pub->_n_enab ==
+ SUPPORT_11N) ? WL_11N_2x2 :
+ WL_11N_3x3));
+ }
+ }
+
+ /* init per-band default rateset, depend on band->gmode */
+ wlc_default_rateset(wlc, &wlc->band->defrateset);
+
+ /* fill in hw_rateset (used early by WLC_SET_RATESET) */
+ wlc_rateset_filter(&wlc->band->defrateset,
+ &wlc->band->hw_rateset, FALSE,
+ WLC_RATES_CCK_OFDM, RATE_MASK,
+ (bool) N_ENAB(wlc->pub));
+ }
+
+ /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
+ wlc_stf_phy_txant_upd(wlc);
+
+ /* attach each modules */
+ err = wlc_attach_module(wlc);
+ if (err != 0)
+ goto fail;
+
+ if (!wlc_timers_init(wlc, unit)) {
+ WL_ERROR(("wl%d: %s: wlc_init_timer failed\n", unit, __func__));
+ err = 32;
+ goto fail;
+ }
+
+ /* depend on rateset, gmode */
+ wlc->cmi = wlc_channel_mgr_attach(wlc);
+ if (!wlc->cmi) {
+ WL_ERROR(("wl%d: %s: wlc_channel_mgr_attach failed\n", unit,
+ __func__));
+ err = 33;
+ goto fail;
+ }
+
+ /* init default when all parameters are ready, i.e. ->rateset */
+ wlc_bss_default_init(wlc);
+
+ /*
+ * Complete the wlc default state initializations..
+ */
+
+ /* allocate our initial queue */
+ qi = wlc_txq_alloc(wlc, osh);
+ if (qi == NULL) {
+ WL_ERROR(("wl%d: %s: failed to malloc tx queue\n", unit,
+ __func__));
+ err = 100;
+ goto fail;
+ }
+ wlc->active_queue = qi;
+
+ wlc->bsscfg[0] = wlc->cfg;
+ wlc->cfg->_idx = 0;
+ wlc->cfg->wlc = wlc;
+ pub->txmaxpkts = MAXTXPKTS;
+
+ WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION);
+ WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t));
+
+ WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION);
+ WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t));
+
+ wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie);
+
+ wlc->mimoft = FT_HT;
+ wlc->ht_cap.cap = HT_CAP;
+ if (HT_ENAB(wlc->pub))
+ wlc->stf->ldpc = AUTO;
+
+ wlc->mimo_40txbw = AUTO;
+ wlc->ofdm_40txbw = AUTO;
+ wlc->cck_40txbw = AUTO;
+ wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G);
+
+ /* Enable setting the RIFS Mode bit by default in HT Info IE */
+ wlc->rifs_advert = AUTO;
+
+ /* Set default values of SGI */
+ if (WLC_SGI_CAP_PHY(wlc)) {
+ wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+ wlc->sgi_tx = AUTO;
+ } else if (WLCISSSLPNPHY(wlc->band)) {
+ wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+ wlc->sgi_tx = AUTO;
+ } else {
+ wlc_ht_update_sgi_rx(wlc, 0);
+ wlc->sgi_tx = OFF;
+ }
+
+ /* *******nvram 11n config overrides Start ********* */
+
+ /* apply the sgi override from nvram conf */
+ if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
+ wlc->sgi_tx = OFF;
+
+ if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
+ wlc_ht_update_sgi_rx(wlc, 0);
+
+ /* apply the stbc override from nvram conf */
+ if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
+ wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+ wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+ wlc->ht_cap.cap &= ~HT_CAP_TX_STBC;
+ }
+ if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
+ wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
+
+ /* apply the GF override from nvram conf */
+ if (n_disabled & WLFEATURE_DISABLE_11N_GF)
+ wlc->ht_cap.cap &= ~HT_CAP_GF;
+
+ /* initialize radio_mpc_disable according to wlc->mpc */
+ wlc_radio_mpc_upd(wlc);
+
+ if (WLANTSEL_ENAB(wlc)) {
+ if ((CHIPID(wlc->pub->sih->chip)) == BCM43235_CHIP_ID) {
+ if ((getintvar(wlc->pub->vars, "aa2g") == 7) ||
+ (getintvar(wlc->pub->vars, "aa5g") == 7)) {
+ wlc_bmac_antsel_set(wlc->hw, 1);
+ }
+ } else {
+ wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail);
+ }
+ }
+
+ if (perr)
+ *perr = 0;
+
+ return (void *)wlc;
+
+ fail:
+ WL_ERROR(("wl%d: %s: failed with err %d\n", unit, __func__, err));
+ if (wlc)
+ wlc_detach(wlc);
+
+ if (perr)
+ *perr = err;
+ return NULL;
+}
+
+static void BCMNMIATTACHFN(wlc_attach_antgain_init) (wlc_info_t *wlc)
+{
+ uint unit;
+ unit = wlc->pub->unit;
+
+ if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
+ /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
+ wlc->band->antgain = 8;
+ } else if (wlc->band->antgain == -1) {
+ WL_ERROR(("wl%d: %s: Invalid antennas available in srom, using 2dB\n", unit, __func__));
+ wlc->band->antgain = 8;
+ } else {
+ int8 gain, fract;
+ /* Older sroms specified gain in whole dbm only. In order
+ * be able to specify qdbm granularity and remain backward compatible
+ * the whole dbms are now encoded in only low 6 bits and remaining qdbms
+ * are encoded in the hi 2 bits. 6 bit signed number ranges from
+ * -32 - 31. Examples: 0x1 = 1 db,
+ * 0xc1 = 1.75 db (1 + 3 quarters),
+ * 0x3f = -1 (-1 + 0 quarters),
+ * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
+ * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
+ */
+ gain = wlc->band->antgain & 0x3f;
+ gain <<= 2; /* Sign extend */
+ gain >>= 2;
+ fract = (wlc->band->antgain & 0xc0) >> 6;
+ wlc->band->antgain = 4 * gain + fract;
+ }
+}
+
+static bool BCMATTACHFN(wlc_attach_stf_ant_init) (wlc_info_t *wlc)
+{
+ int aa;
+ uint unit;
+ char *vars;
+ int bandtype;
+
+ unit = wlc->pub->unit;
+ vars = wlc->pub->vars;
+ bandtype = wlc->band->bandtype;
+
+ /* get antennas available */
+ aa = (int8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
+ if (aa == 0)
+ aa = (int8) getintvar(vars,
+ (BAND_5G(bandtype) ? "aa1" : "aa0"));
+ if ((aa < 1) || (aa > 15)) {
+ WL_ERROR(("wl%d: %s: Invalid antennas available in srom (0x%x), using 3.\n", unit, __func__, aa));
+ aa = 3;
+ }
+
+ /* reset the defaults if we have a single antenna */
+ if (aa == 1) {
+ wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
+ wlc->stf->txant = ANT_TX_FORCE_0;
+ } else if (aa == 2) {
+ wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
+ wlc->stf->txant = ANT_TX_FORCE_1;
+ } else {
+ }
+
+ /* Compute Antenna Gain */
+ wlc->band->antgain =
+ (int8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
+ wlc_attach_antgain_init(wlc);
+
+ return TRUE;
+}
+
+#ifdef WLC_HIGH_ONLY
+/* HIGH_ONLY bmac_attach, which sync over LOW_ONLY bmac_attach states */
+int
+BCMATTACHFN(wlc_bmac_attach) (wlc_info_t *wlc, uint16 vendor, uint16 device,
+ uint unit, bool piomode, osl_t *osh,
+ void *regsva, uint bustype, void *btparam) {
+ wlc_bmac_revinfo_t revinfo;
+ uint idx = 0;
+ rpc_info_t *rpc = (rpc_info_t *) btparam;
+
+ ASSERT(bustype == RPC_BUS);
+
+ /* install the rpc handle in the various state structures used by stub RPC functions */
+ wlc->rpc = rpc;
+ wlc->hw->rpc = rpc;
+ wlc->hw->osh = osh;
+
+ wlc->regs = 0;
+
+ wlc->rpctx = wlc_rpctx_attach(wlc->pub, wlc);
+ if (wlc->rpctx == NULL)
+ return -1;
+
+ /*
+ * FIFO 0
+ * TX: TX_AC_BK_FIFO (TX AC Background data packets)
+ */
+ /* Always initialized */
+ ASSERT(NRPCTXBUFPOST <= NTXD);
+ wlc_rpctx_fifoinit(wlc->rpctx, TX_DATA_FIFO, NRPCTXBUFPOST);
+ wlc_rpctx_fifoinit(wlc->rpctx, TX_CTL_FIFO, NRPCTXBUFPOST);
+ wlc_rpctx_fifoinit(wlc->rpctx, TX_BCMC_FIFO, NRPCTXBUFPOST);
+
+ /* VI and BK inited only if WME */
+ if (WME_ENAB(wlc->pub)) {
+ wlc_rpctx_fifoinit(wlc->rpctx, TX_AC_BK_FIFO, NRPCTXBUFPOST);
+ wlc_rpctx_fifoinit(wlc->rpctx, TX_AC_VI_FIFO, NRPCTXBUFPOST);
+ }
+
+ /* Allocate SB handle */
+ wlc->pub->sih = osl_malloc(wlc->osh, sizeof(si_t));
+ if (!wlc->pub->sih)
+ return -1;
+ bzero(wlc->pub->sih, sizeof(si_t));
+
+ /* sync up revinfo with BMAC */
+ bzero(&revinfo, sizeof(wlc_bmac_revinfo_t));
+ if (wlc_bmac_revinfo_get(wlc->hw, &revinfo) != 0)
+ return -1;
+ wlc->vendorid = (uint16) revinfo.vendorid;
+ wlc->deviceid = (uint16) revinfo.deviceid;
+
+ wlc->pub->boardrev = (uint16) revinfo.boardrev;
+ wlc->pub->corerev = revinfo.corerev;
+ wlc->pub->sromrev = (uint8) revinfo.sromrev;
+ wlc->pub->sih->chiprev = revinfo.chiprev;
+ wlc->pub->sih->chip = revinfo.chip;
+ wlc->pub->sih->chippkg = revinfo.chippkg;
+ wlc->pub->sih->boardtype = revinfo.boardtype;
+ wlc->pub->sih->boardvendor = revinfo.boardvendor;
+ wlc->pub->sih->bustype = revinfo.bustype;
+ wlc->pub->sih->buscoretype = revinfo.buscoretype;
+ wlc->pub->sih->buscorerev = revinfo.buscorerev;
+ wlc->pub->sih->issim = (bool) revinfo.issim;
+ wlc->pub->sih->rpc = rpc;
+
+ if (revinfo.nbands == 0 || revinfo.nbands > 2)
+ return -1;
+ wlc->pub->_nbands = revinfo.nbands;
+
+ for (idx = 0; idx < wlc->pub->_nbands; idx++) {
+ uint bandunit, bandtype; /* To access bandstate */
+ wlc_phy_t *pi = osl_malloc(wlc->osh, sizeof(wlc_phy_t));
+
+ if (!pi)
+ return -1;
+ bzero(pi, sizeof(wlc_phy_t));
+ pi->rpc = rpc;
+
+ bandunit = revinfo.band[idx].bandunit;
+ bandtype = revinfo.band[idx].bandtype;
+ wlc->bandstate[bandunit]->radiorev =
+ (uint8) revinfo.band[idx].radiorev;
+ wlc->bandstate[bandunit]->phytype =
+ (uint16) revinfo.band[idx].phytype;
+ wlc->bandstate[bandunit]->phyrev =
+ (uint16) revinfo.band[idx].phyrev;
+ wlc->bandstate[bandunit]->radioid =
+ (uint16) revinfo.band[idx].radioid;
+ wlc->bandstate[bandunit]->abgphy_encore =
+ revinfo.band[idx].abgphy_encore;
+
+ wlc->bandstate[bandunit]->pi = pi;
+ wlc->bandstate[bandunit]->bandunit = bandunit;
+ wlc->bandstate[bandunit]->bandtype = bandtype;
+ }
+
+ /* misc stuff */
+
+ return 0;
+}
+
+/* Free the convenience handles */
+int wlc_bmac_detach(wlc_info_t *wlc)
+{
+ uint idx;
+
+ if (wlc->pub->sih) {
+ osl_mfree(wlc->osh, (void *)wlc->pub->sih, sizeof(si_t));
+ wlc->pub->sih = NULL;
+ }
+
+ for (idx = 0; idx < MAXBANDS; idx++)
+ if (wlc->bandstate[idx]->pi) {
+ osl_mfree(wlc->osh, wlc->bandstate[idx]->pi,
+ sizeof(wlc_phy_t));
+ wlc->bandstate[idx]->pi = NULL;
+ }
+
+ if (wlc->rpctx) {
+ wlc_rpctx_detach(wlc->rpctx);
+ wlc->rpctx = NULL;
+ }
+
+ return 0;
+
+}
+
+#endif /* WLC_HIGH_ONLY */
+
+static void BCMATTACHFN(wlc_timers_deinit) (wlc_info_t *wlc)
+{
+ /* free timer state */
+ if (wlc->wdtimer) {
+ wl_free_timer(wlc->wl, wlc->wdtimer);
+ wlc->wdtimer = NULL;
+ }
+ if (wlc->radio_timer) {
+ wl_free_timer(wlc->wl, wlc->radio_timer);
+ wlc->radio_timer = NULL;
+ }
+}
+
+static void BCMATTACHFN(wlc_detach_module) (wlc_info_t *wlc)
+{
+ if (wlc->asi) {
+ wlc_antsel_detach(wlc->asi);
+ wlc->asi = NULL;
+ }
+
+ if (wlc->ampdu) {
+ wlc_ampdu_detach(wlc->ampdu);
+ wlc->ampdu = NULL;
+ }
+
+ wlc_stf_detach(wlc);
+}
+
+/*
+ * Return a count of the number of driver callbacks still pending.
+ *
+ * General policy is that wlc_detach can only dealloc/free software states. It can NOT
+ * touch hardware registers since the d11core may be in reset and clock may not be available.
+ * One exception is sb register access, which is possible if crystal is turned on
+ * After "down" state, driver should avoid software timer with the exception of radio_monitor.
+ */
+uint BCMATTACHFN(wlc_detach) (wlc_info_t *wlc)
+{
+ uint i;
+ uint callbacks = 0;
+
+ if (wlc == NULL)
+ return 0;
+
+ WL_TRACE(("wl%d: %s\n", wlc->pub->unit, __func__));
+
+ ASSERT(!wlc->pub->up);
+
+ callbacks += wlc_bmac_detach(wlc);
+
+ /* delete software timers */
+ if (!wlc_radio_monitor_stop(wlc))
+ callbacks++;
+
+ if (wlc->eventq) {
+ wlc_eventq_detach(wlc->eventq);
+ wlc->eventq = NULL;
+ }
+
+ wlc_channel_mgr_detach(wlc->cmi);
+
+ wlc_timers_deinit(wlc);
+
+ wlc_detach_module(wlc);
+
+ /* free other state */
+
+#ifdef WLC_HIGH_ONLY
+ /* High-Only driver has an allocated copy of vars, monolithic just
+ * references the wlc->hw->vars which is freed in wlc_bmac_detach()
+ */
+ if (wlc->pub->vars) {
+ osl_mfree(wlc->osh, wlc->pub->vars, wlc->vars_size);
+ wlc->pub->vars = NULL;
+ }
+#endif
+
+#ifdef BCMDBG
+ if (wlc->country_ie_override) {
+ osl_mfree(wlc->osh, wlc->country_ie_override,
+ wlc->country_ie_override->len + TLV_HDR_LEN);
+ wlc->country_ie_override = NULL;
+ }
+#endif /* BCMDBG */
+
+ {
+ /* free dumpcb list */
+ dumpcb_t *prev, *ptr;
+ prev = ptr = wlc->dumpcb_head;
+ while (ptr) {
+ ptr = prev->next;
+ osl_mfree(wlc->osh, prev, sizeof(dumpcb_t));
+ prev = ptr;
+ }
+ wlc->dumpcb_head = NULL;
+ }
+
+ /* Detach from iovar manager */
+ wlc_module_unregister(wlc->pub, "wlc_iovars", wlc);
+
+ /*
+ if (wlc->ap) {
+ wlc_ap_detach(wlc->ap);
+ wlc->ap = NULL;
+ }
+ */
+
+ while (wlc->tx_queues != NULL) {
+ wlc_txq_free(wlc, wlc->osh, wlc->tx_queues);
+ }
+
+ /*
+ * consistency check: wlc_module_register/wlc_module_unregister calls
+ * should match therefore nothing should be left here.
+ */
+ for (i = 0; i < WLC_MAXMODULES; i++)
+ ASSERT(wlc->modulecb[i].name[0] == '\0');
+
+ wlc_detach_mfree(wlc, wlc->osh);
+ return callbacks;
+}
+
+/* update state that depends on the current value of "ap" */
+void wlc_ap_upd(wlc_info_t *wlc)
+{
+ if (AP_ENAB(wlc->pub))
+ wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */
+ else
+ wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */
+
+ /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */
+ wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO;
+
+ /* fixup mpc */
+ wlc->mpc = TRUE;
+}
+
+/* read hwdisable state and propagate to wlc flag */
+static void wlc_radio_hwdisable_upd(wlc_info_t *wlc)
+{
+ if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
+ return;
+
+ if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) {
+ mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+ } else {
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+ }
+}
+
+/* return TRUE if Minimum Power Consumption should be entered, FALSE otherwise */
+bool wlc_is_non_delay_mpc(wlc_info_t *wlc)
+{
+ return FALSE;
+}
+
+bool wlc_ismpc(wlc_info_t *wlc)
+{
+ return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc));
+}
+
+void wlc_radio_mpc_upd(wlc_info_t *wlc)
+{
+ bool mpc_radio, radio_state;
+
+ /*
+ * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
+ * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
+ * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
+ * the radio is going down.
+ */
+ if (!wlc->mpc) {
+ if (!wlc->pub->radio_disabled)
+ return;
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+ wlc_radio_upd(wlc);
+ if (!wlc->pub->radio_disabled)
+ wlc_radio_monitor_stop(wlc);
+ return;
+ }
+
+ /*
+ * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
+ * to go ON, always call radio_upd synchronously
+ * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
+ */
+ radio_state =
+ (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
+ ON);
+ mpc_radio = (wlc_ismpc(wlc) == TRUE) ? OFF : ON;
+
+ if (radio_state == ON && mpc_radio == OFF)
+ wlc->mpc_delay_off = wlc->mpc_dlycnt;
+ else if (radio_state == OFF && mpc_radio == ON) {
+ mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+ wlc_radio_upd(wlc);
+ if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) {
+ wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT;
+ } else
+ wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+ wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
+ }
+ /* Below logic is meant to capture the transition from mpc off to mpc on for reasons
+ * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
+ * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
+ */
+ if ((wlc->prev_non_delay_mpc == FALSE) &&
+ (wlc_is_non_delay_mpc(wlc) == TRUE) && wlc->mpc_delay_off) {
+ wlc->mpc_delay_off = wlc->mpc_dlycnt;
+ }
+ wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc);
+}
+
+/*
+ * centralized radio disable/enable function,
+ * invoke radio enable/disable after updating hwradio status
+ */
+static void wlc_radio_upd(wlc_info_t *wlc)
+{
+ if (wlc->pub->radio_disabled)
+ wlc_radio_disable(wlc);
+ else
+ wlc_radio_enable(wlc);
+}
+
+/* maintain LED behavior in down state */
+static void wlc_down_led_upd(wlc_info_t *wlc)
+{
+ ASSERT(!wlc->pub->up);
+
+ /* maintain LEDs while in down state, turn on sbclk if not available yet */
+ /* turn on sbclk if necessary */
+ if (!AP_ENAB(wlc->pub)) {
+ wlc_pllreq(wlc, TRUE, WLC_PLLREQ_FLIP);
+
+ wlc_pllreq(wlc, FALSE, WLC_PLLREQ_FLIP);
+ }
+}
+
+void wlc_radio_disable(wlc_info_t *wlc)
+{
+ if (!wlc->pub->up) {
+ wlc_down_led_upd(wlc);
+ return;
+ }
+
+ wlc_radio_monitor_start(wlc);
+ wl_down(wlc->wl);
+}
+
+static void wlc_radio_enable(wlc_info_t *wlc)
+{
+ if (wlc->pub->up)
+ return;
+
+ if (DEVICEREMOVED(wlc))
+ return;
+
+ if (!wlc->down_override) { /* imposed by wl down/out ioctl */
+ wl_up(wlc->wl);
+ }
+}
+
+/* periodical query hw radio button while driver is "down" */
+static void wlc_radio_timer(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+
+ if (DEVICEREMOVED(wlc)) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__));
+ wl_down(wlc->wl);
+ return;
+ }
+
+ /* cap mpc off count */
+ if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT)
+ wlc->mpc_offcnt++;
+
+ /* validate all the reasons driver could be down and running this radio_timer */
+ ASSERT(wlc->pub->radio_disabled || wlc->down_override);
+ wlc_radio_hwdisable_upd(wlc);
+ wlc_radio_upd(wlc);
+}
+
+static bool wlc_radio_monitor_start(wlc_info_t *wlc)
+{
+ /* Don't start the timer if HWRADIO feature is disabled */
+ if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
+ return TRUE;
+
+ wlc->radio_monitor = TRUE;
+ wlc_pllreq(wlc, TRUE, WLC_PLLREQ_RADIO_MON);
+ wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, TRUE);
+ return TRUE;
+}
+
+bool wlc_radio_monitor_stop(wlc_info_t *wlc)
+{
+ if (!wlc->radio_monitor)
+ return TRUE;
+
+ ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) !=
+ WL_SWFL_NOHWRADIO);
+
+ wlc->radio_monitor = FALSE;
+ wlc_pllreq(wlc, FALSE, WLC_PLLREQ_RADIO_MON);
+ return wl_del_timer(wlc->wl, wlc->radio_timer);
+}
+
+/* bring the driver down, but don't reset hardware */
+void wlc_out(wlc_info_t *wlc)
+{
+ wlc_bmac_set_noreset(wlc->hw, TRUE);
+ wlc_radio_upd(wlc);
+ wl_down(wlc->wl);
+ wlc_bmac_set_noreset(wlc->hw, FALSE);
+
+ /* core clk is TRUE in BMAC driver due to noreset, need to mirror it in HIGH */
+ wlc->clk = TRUE;
+
+ /* This will make sure that when 'up' is done
+ * after 'out' it'll restore hardware (especially gpios)
+ */
+ wlc->pub->hw_up = FALSE;
+}
+
+#if defined(BCMDBG)
+/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that
+ * if there is no packet pending for the FIFO, then the corresponding prec bits should be set
+ * in prec_map. Of course, ignore this rule when block_datafifo is set
+ */
+static bool wlc_tx_prec_map_verify(wlc_info_t *wlc)
+{
+ /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both
+ * fail the check.
+ */
+ if (!EDCF_ENAB(wlc->pub)) {
+ if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) ||
+ WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO)))
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO)
+ && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO)
+ && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO)
+ && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO);
+}
+#endif /* BCMDBG */
+
+static void wlc_watchdog_by_timer(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+ wlc_watchdog(arg);
+ if (WLC_WATCHDOG_TBTT(wlc)) {
+ /* set to normal osl watchdog period */
+ wl_del_timer(wlc->wl, wlc->wdtimer);
+ wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+ TRUE);
+ }
+}
+
+/* common watchdog code */
+static void wlc_watchdog(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+ int i;
+ wlc_bsscfg_t *cfg;
+
+ WL_TRACE(("wl%d: wlc_watchdog\n", wlc->pub->unit));
+
+ if (!wlc->pub->up)
+ return;
+
+ if (DEVICEREMOVED(wlc)) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__));
+ wl_down(wlc->wl);
+ return;
+ }
+
+ /* increment second count */
+ wlc->pub->now++;
+
+ /* delay radio disable */
+ if (wlc->mpc_delay_off) {
+ if (--wlc->mpc_delay_off == 0) {
+ mboolset(wlc->pub->radio_disabled,
+ WL_RADIO_MPC_DISABLE);
+ if (wlc->mpc && wlc_ismpc(wlc))
+ wlc->mpc_offcnt = 0;
+ wlc->mpc_laston_ts = OSL_SYSUPTIME();
+ }
+ }
+
+ /* mpc sync */
+ wlc_radio_mpc_upd(wlc);
+ /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
+ wlc_radio_hwdisable_upd(wlc);
+ wlc_radio_upd(wlc);
+ /* if ismpc, driver should be in down state if up/down is allowed */
+ if (wlc->mpc && wlc_ismpc(wlc))
+ ASSERT(!wlc->pub->up);
+ /* if radio is disable, driver may be down, quit here */
+ if (wlc->pub->radio_disabled)
+ return;
+
+#ifdef WLC_LOW
+ wlc_bmac_watchdog(wlc);
+#endif
+#ifdef WLC_HIGH_ONLY
+ /* maintenance */
+ wlc_bmac_rpc_watchdog(wlc);
+#endif
+
+ /* occasionally sample mac stat counters to detect 16-bit counter wrap */
+ if ((WLC_UPDATE_STATS(wlc))
+ && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD)))
+ wlc_statsupd(wlc);
+
+ /* Manage TKIP countermeasures timers */
+ FOREACH_BSS(wlc, i, cfg) {
+ if (cfg->tk_cm_dt) {
+ cfg->tk_cm_dt--;
+ }
+ if (cfg->tk_cm_bt) {
+ cfg->tk_cm_bt--;
+ }
+ }
+
+ /* Call any registered watchdog handlers */
+ for (i = 0; i < WLC_MAXMODULES; i++) {
+ if (wlc->modulecb[i].watchdog_fn)
+ wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
+ }
+
+ if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
+ ((wlc->pub->now - wlc->tempsense_lasttime) >=
+ WLC_TEMPSENSE_PERIOD)) {
+ wlc->tempsense_lasttime = wlc->pub->now;
+ wlc_tempsense_upd(wlc);
+ }
+#ifdef WLC_LOW
+ /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
+ ASSERT(wlc_bmac_taclear(wlc->hw, TRUE));
+#endif
+
+ /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */
+ ASSERT(wlc_tx_prec_map_verify(wlc));
+
+ ASSERT(wlc_ps_check(wlc));
+}
+
+/* make interface operational */
+int BCMINITFN(wlc_up) (wlc_info_t *wlc)
+{
+ WL_TRACE(("wl%d: %s:\n", wlc->pub->unit, __func__));
+
+ /* HW is turned off so don't try to access it */
+ if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
+ return BCME_RADIOOFF;
+
+ if (!wlc->pub->hw_up) {
+ wlc_bmac_hw_up(wlc->hw);
+ wlc->pub->hw_up = TRUE;
+ }
+
+ if ((wlc->pub->boardflags & BFL_FEM)
+ && (CHIPID(wlc->pub->sih->chip) == BCM4313_CHIP_ID)) {
+ if (wlc->pub->boardrev >= 0x1250
+ && (wlc->pub->boardflags & BFL_FEM_BT)) {
+ wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
+ MHF5_4313_GPIOCTRL, WLC_BAND_ALL);
+ } else {
+ wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE,
+ WLC_BAND_ALL);
+ }
+ }
+
+ /*
+ * Need to read the hwradio status here to cover the case where the system
+ * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+ * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
+ * don't call radio_update to avoid looping wlc_up.
+ *
+ * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only
+ */
+ if (!wlc->pub->radio_disabled) {
+ int status = wlc_bmac_up_prep(wlc->hw);
+ if (status == BCME_RADIOOFF) {
+ if (!mboolisset
+ (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
+ int idx;
+ wlc_bsscfg_t *bsscfg;
+ mboolset(wlc->pub->radio_disabled,
+ WL_RADIO_HW_DISABLE);
+
+ FOREACH_BSS(wlc, idx, bsscfg) {
+ if (!BSSCFG_STA(bsscfg)
+ || !bsscfg->enable || !bsscfg->BSS)
+ continue;
+ WL_ERROR(("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", wlc->pub->unit, idx));
+ }
+ }
+ } else
+ ASSERT(!status);
+ }
+
+ if (wlc->pub->radio_disabled) {
+ wlc_radio_monitor_start(wlc);
+ return 0;
+ }
+
+ /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */
+ wlc->clk = TRUE;
+
+ wlc_radio_monitor_stop(wlc);
+
+ /* Set EDCF hostflags */
+ if (EDCF_ENAB(wlc->pub)) {
+ wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL);
+ } else {
+ wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL);
+ }
+
+ if (WLC_WAR16165(wlc))
+ wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
+ WLC_BAND_ALL);
+
+ wl_init(wlc->wl);
+ wlc->pub->up = TRUE;
+
+ if (wlc->bandinit_pending) {
+ wlc_suspend_mac_and_wait(wlc);
+ wlc_set_chanspec(wlc, wlc->default_bss->chanspec);
+ wlc->bandinit_pending = FALSE;
+ wlc_enable_mac(wlc);
+ }
+
+ wlc_bmac_up_finish(wlc->hw);
+
+ /* other software states up after ISR is running */
+ /* start APs that were to be brought up but are not up yet */
+ /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */
+
+ /* Program the TX wme params with the current settings */
+ wlc_wme_retries_write(wlc);
+
+ /* start one second watchdog timer */
+ ASSERT(!wlc->WDarmed);
+ wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, TRUE);
+ wlc->WDarmed = TRUE;
+
+ /* ensure antenna config is up to date */
+ wlc_stf_phy_txant_upd(wlc);
+ /* ensure LDPC config is in sync */
+ wlc_ht_update_ldpc(wlc, wlc->stf->ldpc);
+
+ return 0;
+}
+
+/* Initialize the base precedence map for dequeueing from txq based on WME settings */
+static void BCMINITFN(wlc_tx_prec_map_init) (wlc_info_t *wlc)
+{
+ wlc->tx_prec_map = WLC_PREC_BMP_ALL;
+ bzero(wlc->fifo2prec_map, sizeof(uint16) * NFIFO);
+
+ /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
+ * if either is full.
+ */
+ if (!EDCF_ENAB(wlc->pub)) {
+ wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL;
+ wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL;
+ } else {
+ wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK;
+ wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE;
+ wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI;
+ wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO;
+ }
+}
+
+static uint BCMUNINITFN(wlc_down_del_timer) (wlc_info_t *wlc)
+{
+ uint callbacks = 0;
+
+ return callbacks;
+}
+
+/*
+ * Mark the interface nonoperational, stop the software mechanisms,
+ * disable the hardware, free any transient buffer state.
+ * Return a count of the number of driver callbacks still pending.
+ */
+uint BCMUNINITFN(wlc_down) (wlc_info_t *wlc)
+{
+
+ uint callbacks = 0;
+ int i;
+ bool dev_gone = FALSE;
+ wlc_txq_info_t *qi;
+
+ WL_TRACE(("wl%d: %s:\n", wlc->pub->unit, __func__));
+
+ /* check if we are already in the going down path */
+ if (wlc->going_down) {
+ WL_ERROR(("wl%d: %s: Driver going down so return\n",
+ wlc->pub->unit, __func__));
+ return 0;
+ }
+ if (!wlc->pub->up)
+ return callbacks;
+
+ /* in between, mpc could try to bring down again.. */
+ wlc->going_down = TRUE;
+
+ callbacks += wlc_bmac_down_prep(wlc->hw);
+
+ dev_gone = DEVICEREMOVED(wlc);
+
+ /* Call any registered down handlers */
+ for (i = 0; i < WLC_MAXMODULES; i++) {
+ if (wlc->modulecb[i].down_fn)
+ callbacks +=
+ wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
+ }
+
+ /* cancel the watchdog timer */
+ if (wlc->WDarmed) {
+ if (!wl_del_timer(wlc->wl, wlc->wdtimer))
+ callbacks++;
+ wlc->WDarmed = FALSE;
+ }
+ /* cancel all other timers */
+ callbacks += wlc_down_del_timer(wlc);
+
+ /* interrupt must have been blocked */
+ ASSERT((wlc->macintmask == 0) || !wlc->pub->up);
+
+ wlc->pub->up = FALSE;
+
+ wlc_phy_mute_upd(wlc->band->pi, FALSE, PHY_MUTE_ALL);
+
+ /* clear txq flow control */
+ wlc_txflowcontrol_reset(wlc);
+
+ /* flush tx queues */
+ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+ pktq_flush(wlc->osh, &qi->q, TRUE, NULL, 0);
+ ASSERT(pktq_empty(&qi->q));
+ }
+
+ /* flush event queue.
+ * Should be the last thing done after all the events are generated
+ * Just delivers the events synchronously instead of waiting for a timer
+ */
+ callbacks += wlc_eventq_down(wlc->eventq);
+
+ callbacks += wlc_bmac_down_finish(wlc->hw);
+
+ /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */
+ wlc->clk = FALSE;
+
+#ifdef WLC_HIGH_ONLY
+ wlc_rpctx_txreclaim(wlc->rpctx);
+#endif
+
+ /* Verify all packets are flushed from the driver */
+ if (PKTALLOCED(wlc->osh) != 0) {
+ WL_ERROR(("%d packets not freed at wlc_down!!!!!!\n",
+ PKTALLOCED(wlc->osh)));
+ }
+#ifdef BCMDBG
+ /* Since all the packets should have been freed,
+ * all callbacks should have been called
+ */
+ for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++)
+ ASSERT(wlc->pkt_callback[i].fn == NULL);
+#endif
+ wlc->going_down = FALSE;
+ return callbacks;
+}
+
+/* Set the current gmode configuration */
+int wlc_set_gmode(wlc_info_t *wlc, uint8 gmode, bool config)
+{
+ int ret = 0;
+ uint i;
+ wlc_rateset_t rs;
+ /* Default to 54g Auto */
+ int8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
+ bool shortslot_restrict = FALSE; /* Restrict association to stations that support shortslot
+ */
+ bool ignore_bcns = TRUE; /* Ignore legacy beacons on the same channel */
+ bool ofdm_basic = FALSE; /* Make 6, 12, and 24 basic rates */
+ int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
+ bool preamble_restrict = FALSE; /* Restrict association to stations that support short
+ * preambles
+ */
+ wlcband_t *band;
+
+ /* if N-support is enabled, allow Gmode set as long as requested
+ * Gmode is not GMODE_LEGACY_B
+ */
+ if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
+ return BCME_UNSUPPORTED;
+
+ /* verify that we are dealing with 2G band and grab the band pointer */
+ if (wlc->band->bandtype == WLC_BAND_2G)
+ band = wlc->band;
+ else if ((NBANDS(wlc) > 1) &&
+ (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G))
+ band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+ else
+ return BCME_BADBAND;
+
+ /* Legacy or bust when no OFDM is supported by regulatory */
+ if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
+ WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B))
+ return BCME_RANGE;
+
+ /* update configuration value */
+ if (config == TRUE)
+ wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode);
+
+ /* Clear supported rates filter */
+ bzero(&wlc->sup_rates_override, sizeof(wlc_rateset_t));
+
+ /* Clear rateset override */
+ bzero(&rs, sizeof(wlc_rateset_t));
+
+ switch (gmode) {
+ case GMODE_LEGACY_B:
+ shortslot = WLC_SHORTSLOT_OFF;
+ wlc_rateset_copy(&gphy_legacy_rates, &rs);
+
+ break;
+
+ case GMODE_LRS:
+ if (AP_ENAB(wlc->pub))
+ wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override);
+ break;
+
+ case GMODE_AUTO:
+ /* Accept defaults */
+ break;
+
+ case GMODE_ONLY:
+ ofdm_basic = TRUE;
+ preamble = WLC_PLCP_SHORT;
+ preamble_restrict = TRUE;
+ break;
+
+ case GMODE_PERFORMANCE:
+ if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */
+ wlc_rateset_copy(&cck_ofdm_rates,
+ &wlc->sup_rates_override);
+
+ shortslot = WLC_SHORTSLOT_ON;
+ shortslot_restrict = TRUE;
+ ofdm_basic = TRUE;
+ preamble = WLC_PLCP_SHORT;
+ preamble_restrict = TRUE;
+ break;
+
+ default:
+ /* Error */
+ WL_ERROR(("wl%d: %s: invalid gmode %d\n", wlc->pub->unit,
+ __func__, gmode));
+ return BCME_UNSUPPORTED;
+ }
+
+ /*
+ * If we are switching to gmode == GMODE_LEGACY_B,
+ * clean up rate info that may refer to OFDM rates.
+ */
+ if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
+ band->gmode = gmode;
+ if (band->rspec_override && !IS_CCK(band->rspec_override)) {
+ band->rspec_override = 0;
+ wlc_reprate_init(wlc);
+ }
+ if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
+ band->mrspec_override = 0;
+ }
+ }
+
+ band->gmode = gmode;
+
+ wlc->ignore_bcns = ignore_bcns;
+
+ wlc->shortslot_override = shortslot;
+
+ if (AP_ENAB(wlc->pub)) {
+ /* wlc->ap->shortslot_restrict = shortslot_restrict; */
+ wlc->PLCPHdr_override =
+ (preamble !=
+ WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO;
+ }
+
+ if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG)
+ || preamble == WLC_PLCP_SHORT)
+ wlc->default_bss->capability |= DOT11_CAP_SHORT;
+ else
+ wlc->default_bss->capability &= ~DOT11_CAP_SHORT;
+
+ /* Update shortslot capability bit for AP and IBSS */
+ if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) ||
+ shortslot == WLC_SHORTSLOT_ON)
+ wlc->default_bss->capability |= DOT11_CAP_SHORTSLOT;
+ else
+ wlc->default_bss->capability &= ~DOT11_CAP_SHORTSLOT;
+
+ /* Use the default 11g rateset */
+ if (!rs.count)
+ wlc_rateset_copy(&cck_ofdm_rates, &rs);
+
+ if (ofdm_basic) {
+ for (i = 0; i < rs.count; i++) {
+ if (rs.rates[i] == WLC_RATE_6M
+ || rs.rates[i] == WLC_RATE_12M
+ || rs.rates[i] == WLC_RATE_24M)
+ rs.rates[i] |= WLC_RATE_FLAG;
+ }
+ }
+
+ /* Set default bss rateset */
+ wlc->default_bss->rateset.count = rs.count;
+ bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates,
+ sizeof(wlc->default_bss->rateset.rates));
+
+ return ret;
+}
+
+static int wlc_nmode_validate(wlc_info_t *wlc, int32 nmode)
+{
+ int err = 0;
+
+ switch (nmode) {
+
+ case OFF:
+ break;
+
+ case AUTO:
+ case WL_11N_2x2:
+ case WL_11N_3x3:
+ if (!(WLC_PHY_11N_CAP(wlc->band)))
+ err = BCME_BADBAND;
+ break;
+
+ default:
+ err = BCME_RANGE;
+ break;
+ }
+
+ return err;
+}
+
+int wlc_set_nmode(wlc_info_t *wlc, int32 nmode)
+{
+ uint i;
+ int err;
+
+ err = wlc_nmode_validate(wlc, nmode);
+ ASSERT(err == 0);
+ if (err)
+ return err;
+
+ switch (nmode) {
+ case OFF:
+ wlc->pub->_n_enab = OFF;
+ wlc->default_bss->flags &= ~WLC_BSS_HT;
+ /* delete the mcs rates from the default and hw ratesets */
+ wlc_rateset_mcs_clear(&wlc->default_bss->rateset);
+ for (i = 0; i < NBANDS(wlc); i++) {
+ memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
+ MCSSET_LEN);
+ if (IS_MCS(wlc->band->rspec_override)) {
+ wlc->bandstate[i]->rspec_override = 0;
+ wlc_reprate_init(wlc);
+ }
+ if (IS_MCS(wlc->band->mrspec_override))
+ wlc->bandstate[i]->mrspec_override = 0;
+ }
+ break;
+
+ case AUTO:
+ if (wlc->stf->txstreams == WL_11N_3x3)
+ nmode = WL_11N_3x3;
+ else
+ nmode = WL_11N_2x2;
+ case WL_11N_2x2:
+ case WL_11N_3x3:
+ ASSERT(WLC_PHY_11N_CAP(wlc->band));
+ /* force GMODE_AUTO if NMODE is ON */
+ wlc_set_gmode(wlc, GMODE_AUTO, TRUE);
+ if (nmode == WL_11N_3x3)
+ wlc->pub->_n_enab = SUPPORT_HT;
+ else
+ wlc->pub->_n_enab = SUPPORT_11N;
+ wlc->default_bss->flags |= WLC_BSS_HT;
+ /* add the mcs rates to the default and hw ratesets */
+ wlc_rateset_mcs_build(&wlc->default_bss->rateset,
+ wlc->stf->txstreams);
+ for (i = 0; i < NBANDS(wlc); i++)
+ memcpy(wlc->bandstate[i]->hw_rateset.mcs,
+ wlc->default_bss->rateset.mcs, MCSSET_LEN);
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ return err;
+}
+
+static int wlc_set_rateset(wlc_info_t *wlc, wlc_rateset_t *rs_arg)
+{
+ wlc_rateset_t rs, new;
+ uint bandunit;
+
+ bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t));
+
+ /* check for bad count value */
+ if ((rs.count == 0) || (rs.count > WLC_NUMRATES))
+ return BCME_BADRATESET;
+
+ /* try the current band */
+ bandunit = wlc->band->bandunit;
+ bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t));
+ if (wlc_rate_hwrs_filter_sort_validate
+ (&new, &wlc->bandstate[bandunit]->hw_rateset, TRUE,
+ wlc->stf->txstreams))
+ goto good;
+
+ /* try the other band */
+ if (IS_MBAND_UNLOCKED(wlc)) {
+ bandunit = OTHERBANDUNIT(wlc);
+ bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t));
+ if (wlc_rate_hwrs_filter_sort_validate(&new,
+ &wlc->
+ bandstate[bandunit]->
+ hw_rateset, TRUE,
+ wlc->stf->txstreams))
+ goto good;
+ }
+
+ return BCME_ERROR;
+
+ good:
+ /* apply new rateset */
+ bcopy((char *)&new, (char *)&wlc->default_bss->rateset,
+ sizeof(wlc_rateset_t));
+ bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset,
+ sizeof(wlc_rateset_t));
+ return 0;
+}
+
+/* simplified integer set interface for common ioctl handler */
+int wlc_set(wlc_info_t *wlc, int cmd, int arg)
+{
+ return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
+}
+
+/* simplified integer get interface for common ioctl handler */
+int wlc_get(wlc_info_t *wlc, int cmd, int *arg)
+{
+ return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL);
+}
+
+static void wlc_ofdm_rateset_war(wlc_info_t *wlc)
+{
+ uint8 r;
+ bool war = FALSE;
+
+ if (wlc->cfg->associated)
+ r = wlc->cfg->current_bss->rateset.rates[0];
+ else
+ r = wlc->default_bss->rateset.rates[0];
+
+ wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
+
+ return;
+}
+
+int
+wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif)
+{
+ return _wlc_ioctl(wlc, cmd, arg, len, wlcif);
+}
+
+/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
+static int
+_wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif)
+{
+ int val, *pval;
+ bool bool_val;
+ int bcmerror;
+ d11regs_t *regs;
+ uint i;
+ struct scb *nextscb;
+ bool ta_ok;
+ uint band;
+ rw_reg_t *r;
+ wlc_bsscfg_t *bsscfg;
+ osl_t *osh;
+ wlc_bss_info_t *current_bss;
+
+ /* update bsscfg pointer */
+ bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */
+ current_bss = NULL;
+
+ /* initialize the following to get rid of compiler warning */
+ nextscb = NULL;
+ ta_ok = FALSE;
+ band = 0;
+ r = NULL;
+
+ /* If the device is turned off, then it's not "removed" */
+ if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
+ WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__));
+ wl_down(wlc->wl);
+ return BCME_ERROR;
+ }
+
+ ASSERT(!(wlc->pub->hw_off && wlc->pub->up));
+
+ /* default argument is generic integer */
+ pval = arg ? (int *)arg:NULL;
+
+ /* This will prevent the misaligned access */
+ if (pval && (uint32) len >= sizeof(val))
+ bcopy(pval, &val, sizeof(val));
+ else
+ val = 0;
+
+ /* bool conversion to avoid duplication below */
+ bool_val = val != 0;
+
+ if (cmd != WLC_SET_CHANNEL)
+ WL_NONE(("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", cmd,
+ (uint) val, val, len));
+
+ bcmerror = 0;
+ regs = wlc->regs;
+ osh = wlc->osh;
+
+ /* A few commands don't need any arguments; all the others do. */
+ switch (cmd) {
+ case WLC_UP:
+ case WLC_OUT:
+ case WLC_DOWN:
+ case WLC_DISASSOC:
+ case WLC_RESTART:
+ case WLC_REBOOT:
+ case WLC_START_CHANNEL_QA:
+ case WLC_INIT:
+ break;
+
+ default:
+ if ((arg == NULL) || (len <= 0)) {
+ WL_ERROR(("wl%d: %s: Command %d needs arguments\n",
+ wlc->pub->unit, __func__, cmd));
+ bcmerror = BCME_BADARG;
+ goto done;
+ }
+ }
+
+ switch (cmd) {
+
+#if defined(BCMDBG)
+ case WLC_GET_MSGLEVEL:
+ *pval = wl_msg_level;
+ break;
+
+ case WLC_SET_MSGLEVEL:
+ wl_msg_level = val;
+ break;
+#endif
+
+ case WLC_GET_INSTANCE:
+ *pval = wlc->pub->unit;
+ break;
+
+ case WLC_GET_CHANNEL:{
+ channel_info_t *ci = (channel_info_t *) arg;
+
+ ASSERT(len > (int)sizeof(ci));
+
+ ci->hw_channel =
+ CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC);
+ ci->target_channel =
+ CHSPEC_CHANNEL(wlc->default_bss->chanspec);
+ ci->scan_channel = 0;
+
+ break;
+ }
+
+ case WLC_SET_CHANNEL:{
+ chanspec_t chspec = CH20MHZ_CHSPEC(val);
+
+ if (val < 0 || val > MAXCHANNEL) {
+ bcmerror = BCME_OUTOFRANGECHAN;
+ break;
+ }
+
+ if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) {
+ bcmerror = BCME_BADCHAN;
+ break;
+ }
+
+ if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
+ if (wlc->band->bandunit !=
+ CHSPEC_WLCBANDUNIT(chspec))
+ wlc->bandinit_pending = TRUE;
+ else
+ wlc->bandinit_pending = FALSE;
+ }
+
+ wlc->default_bss->chanspec = chspec;
+ /* wlc_BSSinit() will sanitize the rateset before using it.. */
+ if (wlc->pub->up && !wlc->pub->associated &&
+ (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) {
+ wlc_set_home_chanspec(wlc, chspec);
+ wlc_suspend_mac_and_wait(wlc);
+ wlc_set_chanspec(wlc, chspec);
+ wlc_enable_mac(wlc);
+ }
+#ifdef WLC_HIGH_ONLY
+ /* delay for channel change */
+ msleep(50);
+#endif
+ break;
+ }
+
+#if defined(BCMDBG)
+ case WLC_GET_UCFLAGS:
+ if (!wlc->pub->up) {
+ bcmerror = BCME_NOTUP;
+ break;
+ }
+
+ /* optional band is stored in the second integer of incoming buffer */
+ band =
+ (len <
+ (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ if (val >= MHFMAX) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ *pval = wlc_bmac_mhf_get(wlc->hw, (uint8) val, WLC_BAND_AUTO);
+ break;
+
+ case WLC_SET_UCFLAGS:
+ if (!wlc->pub->up) {
+ bcmerror = BCME_NOTUP;
+ break;
+ }
+
+ /* optional band is stored in the second integer of incoming buffer */
+ band =
+ (len <
+ (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ i = (uint16) val;
+ if (i >= MHFMAX) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ wlc_mhf(wlc, (uint8) i, 0xffff, (uint16) (val >> NBITS(uint16)),
+ WLC_BAND_AUTO);
+ break;
+
+ case WLC_GET_SHMEM:
+ ta_ok = TRUE;
+
+ /* optional band is stored in the second integer of incoming buffer */
+ band =
+ (len <
+ (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ if (val & 1) {
+ bcmerror = BCME_BADADDR;
+ break;
+ }
+
+ *pval = wlc_read_shm(wlc, (uint16) val);
+ break;
+
+ case WLC_SET_SHMEM:
+ ta_ok = TRUE;
+
+ /* optional band is stored in the second integer of incoming buffer */
+ band =
+ (len <
+ (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ if (val & 1) {
+ bcmerror = BCME_BADADDR;
+ break;
+ }
+
+ wlc_write_shm(wlc, (uint16) val,
+ (uint16) (val >> NBITS(uint16)));
+ break;
+
+ case WLC_R_REG: /* MAC registers */
+ ta_ok = TRUE;
+ r = (rw_reg_t *) arg;
+ band = WLC_BAND_AUTO;
+
+ if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ if (len >= (int)sizeof(rw_reg_t))
+ band = r->band;
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ if ((r->byteoff + r->size) > sizeof(d11regs_t)) {
+ bcmerror = BCME_BADADDR;
+ break;
+ }
+ if (r->size == sizeof(uint32))
+ r->val =
+ R_REG(osh,
+ (uint32 *) ((uchar *) (uintptr) regs +
+ r->byteoff));
+ else if (r->size == sizeof(uint16))
+ r->val =
+ R_REG(osh,
+ (uint16 *) ((uchar *) (uintptr) regs +
+ r->byteoff));
+ else
+ bcmerror = BCME_BADADDR;
+ break;
+
+ case WLC_W_REG:
+ ta_ok = TRUE;
+ r = (rw_reg_t *) arg;
+ band = WLC_BAND_AUTO;
+
+ if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ if (len >= (int)sizeof(rw_reg_t))
+ band = r->band;
+
+ /* bcmerror checking */
+ bcmerror = wlc_iocregchk(wlc, band);
+ if (bcmerror)
+ break;
+
+ if (r->byteoff + r->size > sizeof(d11regs_t)) {
+ bcmerror = BCME_BADADDR;
+ break;
+ }
+ if (r->size == sizeof(uint32))
+ W_REG(osh,
+ (uint32 *) ((uchar *) (uintptr) regs +
+ r->byteoff), r->val);
+ else if (r->size == sizeof(uint16))
+ W_REG(osh,
+ (uint16 *) ((uchar *) (uintptr) regs +
+ r->byteoff), r->val);
+ else
+ bcmerror = BCME_BADADDR;
+ break;
+#endif /* BCMDBG */
+
+ case WLC_GET_TXANT:
+ *pval = wlc->stf->txant;
+ break;
+
+ case WLC_SET_TXANT:
+ bcmerror = wlc_stf_ant_txant_validate(wlc, (int8) val);
+ if (bcmerror < 0)
+ break;
+
+ wlc->stf->txant = (int8) val;
+
+ /* if down, we are done */
+ if (!wlc->pub->up)
+ break;
+
+ wlc_suspend_mac_and_wait(wlc);
+
+ wlc_stf_phy_txant_upd(wlc);
+ wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+
+ wlc_enable_mac(wlc);
+
+ break;
+
+ case WLC_GET_ANTDIV:{
+ uint8 phy_antdiv;
+
+ /* return configured value if core is down */
+ if (!wlc->pub->up) {
+ *pval = wlc->stf->ant_rx_ovr;
+
+ } else {
+ if (wlc_phy_ant_rxdiv_get
+ (wlc->band->pi, &phy_antdiv))
+ *pval = (int)phy_antdiv;
+ else
+ *pval = (int)wlc->stf->ant_rx_ovr;
+ }
+
+ break;
+ }
+ case WLC_SET_ANTDIV:
+ /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */
+ if ((val < -1) || (val > 3)) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ if (val == -1)
+ val = ANT_RX_DIV_DEF;
+
+ wlc->stf->ant_rx_ovr = (uint8) val;
+ wlc_phy_ant_rxdiv_set(wlc->band->pi, (uint8) val);
+ break;
+
+ case WLC_GET_RX_ANT:{ /* get latest used rx antenna */
+ uint16 rxstatus;
+
+ if (!wlc->pub->up) {
+ bcmerror = BCME_NOTUP;
+ break;
+ }
+
+ rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0);
+ if (rxstatus == 0xdead || rxstatus == (uint16) -1) {
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
+ break;
+ }
+
+#if defined(BCMDBG)
+ case WLC_GET_UCANTDIV:
+ if (!wlc->clk) {
+ bcmerror = BCME_NOCLK;
+ break;
+ }
+
+ *pval =
+ (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) &
+ MHF1_ANTDIV);
+ break;
+
+ case WLC_SET_UCANTDIV:{
+ if (!wlc->pub->up) {
+ bcmerror = BCME_NOTUP;
+ break;
+ }
+
+ /* if multiband, band must be locked */
+ if (IS_MBAND_UNLOCKED(wlc)) {
+ bcmerror = BCME_NOTBANDLOCKED;
+ break;
+ }
+
+ /* 4322 supports antdiv in phy, no need to set it to ucode */
+ if (WLCISNPHY(wlc->band)
+ && D11REV_IS(wlc->pub->corerev, 16)) {
+ WL_ERROR(("wl%d: can't set ucantdiv for 4322\n",
+ wlc->pub->unit));
+ bcmerror = BCME_UNSUPPORTED;
+ } else
+ wlc_mhf(wlc, MHF1, MHF1_ANTDIV,
+ (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO);
+ break;
+ }
+#endif /* defined(BCMDBG) */
+
+ case WLC_GET_SRL:
+ *pval = wlc->SRL;
+ break;
+
+ case WLC_SET_SRL:
+ if (val >= 1 && val <= RETRY_SHORT_MAX) {
+ int ac;
+ wlc->SRL = (uint16) val;
+
+ wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+
+ for (ac = 0; ac < AC_COUNT; ac++) {
+ WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
+ }
+ wlc_wme_retries_write(wlc);
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+ case WLC_GET_LRL:
+ *pval = wlc->LRL;
+ break;
+
+ case WLC_SET_LRL:
+ if (val >= 1 && val <= 255) {
+ int ac;
+ wlc->LRL = (uint16) val;
+
+ wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+
+ for (ac = 0; ac < AC_COUNT; ac++) {
+ WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
+ }
+ wlc_wme_retries_write(wlc);
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+ case WLC_GET_CWMIN:
+ *pval = wlc->band->CWmin;
+ break;
+
+ case WLC_SET_CWMIN:
+ if (!wlc->clk) {
+ bcmerror = BCME_NOCLK;
+ break;
+ }
+
+ if (val >= 1 && val <= 255) {
+ wlc_set_cwmin(wlc, (uint16) val);
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+ case WLC_GET_CWMAX:
+ *pval = wlc->band->CWmax;
+ break;
+
+ case WLC_SET_CWMAX:
+ if (!wlc->clk) {
+ bcmerror = BCME_NOCLK;
+ break;
+ }
+
+ if (val >= 255 && val <= 2047) {
+ wlc_set_cwmax(wlc, (uint16) val);
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+ case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */
+ *pval = wlc->pub->radio_disabled;
+ break;
+
+ case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to
+ * set
+ */
+ uint16 radiomask, radioval;
+ uint validbits =
+ WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE;
+ mbool new = 0;
+
+ radiomask = (val & 0xffff0000) >> 16;
+ radioval = val & 0x0000ffff;
+
+ if ((radiomask == 0) || (radiomask & ~validbits)
+ || (radioval & ~validbits)
+ || ((radioval & ~radiomask) != 0)) {
+ WL_ERROR(("SET_RADIO with wrong bits 0x%x\n",
+ val));
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ new =
+ (wlc->pub->radio_disabled & ~radiomask) | radioval;
+ wlc->pub->radio_disabled = new;
+
+ wlc_radio_hwdisable_upd(wlc);
+ wlc_radio_upd(wlc);
+ break;
+ }
+
+ case WLC_GET_PHYTYPE:
+ *pval = WLC_PHYTYPE(wlc->band->phytype);
+ break;
+
+#if defined(BCMDBG)
+ case WLC_GET_KEY:
+ if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) {
+ wl_wsec_key_t key;
+
+ wsec_key_t *src_key = wlc->wsec_keys[val];
+
+ if (len < (int)sizeof(key)) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ bzero((char *)&key, sizeof(key));
+ if (src_key) {
+ key.index = src_key->id;
+ key.len = src_key->len;
+ bcopy(src_key->data, key.data, key.len);
+ key.algo = src_key->algo;
+ if (WSEC_SOFTKEY(wlc, src_key, bsscfg))
+ key.flags |= WL_SOFT_KEY;
+ if (src_key->flags & WSEC_PRIMARY_KEY)
+ key.flags |= WL_PRIMARY_KEY;
+
+ bcopy(src_key->ea.octet, key.ea.octet,
+ ETHER_ADDR_LEN);
+ }
+
+ bcopy((char *)&key, arg, sizeof(key));
+ } else
+ bcmerror = BCME_BADKEYIDX;
+ break;
+#endif /* defined(BCMDBG) */
+
+ case WLC_SET_KEY:
+ bcmerror =
+ wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET,
+ wlcif);
+ break;
+
+ case WLC_GET_KEY_SEQ:{
+ wsec_key_t *key;
+
+ if (len < DOT11_WPA_KEY_RSC_LEN) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ /* Return the key's tx iv as an EAPOL sequence counter.
+ * This will be used to supply the RSC value to a supplicant.
+ * The format is 8 bytes, with least significant in seq[0].
+ */
+
+ key = WSEC_KEY(wlc, val);
+ if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) &&
+ (key != NULL)) {
+ uint8 seq[DOT11_WPA_KEY_RSC_LEN];
+ uint16 lo;
+ uint32 hi;
+ /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */
+ if ((bsscfg->WPA_auth & WPA_AUTH_NONE)
+ && ETHER_ISNULLADDR(&key->ea)) {
+ lo = bsscfg->wpa_none_txiv.lo;
+ hi = bsscfg->wpa_none_txiv.hi;
+ } else {
+ lo = key->txiv.lo;
+ hi = key->txiv.hi;
+ }
+
+ /* format the buffer, low to high */
+ seq[0] = lo & 0xff;
+ seq[1] = (lo >> 8) & 0xff;
+ seq[2] = hi & 0xff;
+ seq[3] = (hi >> 8) & 0xff;
+ seq[4] = (hi >> 16) & 0xff;
+ seq[5] = (hi >> 24) & 0xff;
+ seq[6] = 0;
+ seq[7] = 0;
+
+ bcopy((char *)seq, arg, sizeof(seq));
+ } else {
+ bcmerror = BCME_BADKEYIDX;
+ }
+ break;
+ }
+
+ case WLC_GET_CURR_RATESET:{
+ wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+ wlc_rateset_t *rs;
+
+ if (bsscfg->associated)
+ rs = &current_bss->rateset;
+ else
+ rs = &wlc->default_bss->rateset;
+
+ if (len < (int)(rs->count + sizeof(rs->count))) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ /* Copy only legacy rateset section */
+ ret_rs->count = rs->count;
+ bcopy(&rs->rates, &ret_rs->rates, rs->count);
+ break;
+ }
+
+ case WLC_GET_RATESET:{
+ wlc_rateset_t rs;
+ wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+
+ bzero(&rs, sizeof(wlc_rateset_t));
+ wlc_default_rateset(wlc, (wlc_rateset_t *) &rs);
+
+ if (len < (int)(rs.count + sizeof(rs.count))) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ /* Copy only legacy rateset section */
+ ret_rs->count = rs.count;
+ bcopy(&rs.rates, &ret_rs->rates, rs.count);
+ break;
+ }
+
+ case WLC_SET_RATESET:{
+ wlc_rateset_t rs;
+ wl_rateset_t *in_rs = (wl_rateset_t *) arg;
+
+ if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ if (in_rs->count > WLC_NUMRATES) {
+ bcmerror = BCME_BUFTOOLONG;
+ break;
+ }
+
+ bzero(&rs, sizeof(wlc_rateset_t));
+
+ /* Copy only legacy rateset section */
+ rs.count = in_rs->count;
+ bcopy(&in_rs->rates, &rs.rates, rs.count);
+
+ /* merge rateset coming in with the current mcsset */
+ if (N_ENAB(wlc->pub)) {
+ if (bsscfg->associated)
+ bcopy(&current_bss->rateset.mcs[0],
+ rs.mcs, MCSSET_LEN);
+ else
+ bcopy(&wlc->default_bss->rateset.mcs[0],
+ rs.mcs, MCSSET_LEN);
+ }
+
+ bcmerror = wlc_set_rateset(wlc, &rs);
+
+ if (!bcmerror)
+ wlc_ofdm_rateset_war(wlc);
+
+ break;
+ }
+
+ case WLC_GET_BCNPRD:
+ if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+ *pval = current_bss->beacon_period;
+ else
+ *pval = wlc->default_bss->beacon_period;
+ break;
+
+ case WLC_SET_BCNPRD:
+ /* range [1, 0xffff] */
+ if (val >= DOT11_MIN_BEACON_PERIOD
+ && val <= DOT11_MAX_BEACON_PERIOD) {
+ wlc->default_bss->beacon_period = (uint16) val;
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+ case WLC_GET_DTIMPRD:
+ if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+ *pval = current_bss->dtim_period;
+ else
+ *pval = wlc->default_bss->dtim_period;
+ break;
+
+ case WLC_SET_DTIMPRD:
+ /* range [1, 0xff] */
+ if (val >= DOT11_MIN_DTIM_PERIOD
+ && val <= DOT11_MAX_DTIM_PERIOD) {
+ wlc->default_bss->dtim_period = (uint8) val;
+ } else
+ bcmerror = BCME_RANGE;
+ break;
+
+#ifdef SUPPORT_PS
+ case WLC_GET_PM:
+ *pval = wlc->PM;
+ break;
+
+ case WLC_SET_PM:
+ if ((val >= PM_OFF) && (val <= PM_MAX)) {
+ wlc->PM = (uint8) val;
+ if (wlc->pub->up) {
+ }
+ /* Change watchdog driver to align watchdog with tbtt if possible */
+ wlc_watchdog_upd(wlc, PS_ALLOWED(wlc));
+ } else
+ bcmerror = BCME_ERROR;
+ break;
+#endif /* SUPPORT_PS */
+
+#ifdef SUPPORT_PS
+#ifdef BCMDBG
+ case WLC_GET_WAKE:
+ if (AP_ENAB(wlc->pub)) {
+ bcmerror = BCME_NOTSTA;
+ break;
+ }
+ *pval = wlc->wake;
+ break;
+
+ case WLC_SET_WAKE:
+ if (AP_ENAB(wlc->pub)) {
+ bcmerror = BCME_NOTSTA;
+ break;
+ }
+
+ wlc->wake = val ? TRUE : FALSE;
+
+ /* if down, we're done */
+ if (!wlc->pub->up)
+ break;
+
+ /* apply to the mac */
+ wlc_set_ps_ctrl(wlc);
+ break;
+#endif /* BCMDBG */
+#endif /* SUPPORT_PS */
+
+ case WLC_GET_REVINFO:
+ bcmerror = wlc_get_revision_info(wlc, arg, (uint) len);
+ break;
+
+ case WLC_GET_AP:
+ *pval = (int)AP_ENAB(wlc->pub);
+ break;
+
+ case WLC_GET_ATIM:
+ if (bsscfg->associated)
+ *pval = (int)current_bss->atim_window;
+ else
+ *pval = (int)wlc->default_bss->atim_window;
+ break;
+
+ case WLC_SET_ATIM:
+ wlc->default_bss->atim_window = (uint32) val;
+ break;
+
+ case WLC_GET_PKTCNTS:{
+ get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval;
+ if (WLC_UPDATE_STATS(wlc))
+ wlc_statsupd(wlc);
+ pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe);
+ pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror);
+ pktcnt->tx_good_pkt =
+ WLCNTVAL(wlc->pub->_cnt->txfrmsnt);
+ pktcnt->tx_bad_pkt =
+ WLCNTVAL(wlc->pub->_cnt->txerror) +
+ WLCNTVAL(wlc->pub->_cnt->txfail);
+ if (len >= (int)sizeof(get_pktcnt_t)) {
+ /* Be backward compatible - only if buffer is large enough */
+ pktcnt->rx_ocast_good_pkt =
+ WLCNTVAL(wlc->pub->_cnt->rxmfrmocast);
+ }
+ break;
+ }
+
+#ifdef SUPPORT_HWKEY
+ case WLC_GET_WSEC:
+ bcmerror =
+ wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET,
+ wlcif);
+ break;
+
+ case WLC_SET_WSEC:
+ bcmerror =
+ wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET,
+ wlcif);
+ break;
+
+ case WLC_GET_WPA_AUTH:
+ *pval = (int)bsscfg->WPA_auth;
+ break;
+
+ case WLC_SET_WPA_AUTH:
+ /* change of WPA_Auth modifies the PS_ALLOWED state */
+ if (BSSCFG_STA(bsscfg)) {
+ bsscfg->WPA_auth = (uint16) val;
+ } else
+ bsscfg->WPA_auth = (uint16) val;
+ break;
+#endif /* SUPPORT_HWKEY */
+
+ case WLC_GET_BANDLIST:
+ /* count of number of bands, followed by each band type */
+ *pval++ = NBANDS(wlc);
+ *pval++ = wlc->band->bandtype;
+ if (NBANDS(wlc) > 1)
+ *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype;
+ break;
+
+ case WLC_GET_BAND:
+ *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO;
+ break;
+
+ case WLC_GET_PHYLIST:
+ {
+ uchar *cp = arg;
+ if (len < 3) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ if (WLCISNPHY(wlc->band)) {
+ *cp++ = 'n';
+ } else if (WLCISLCNPHY(wlc->band)) {
+ *cp++ = 'c';
+ } else if (WLCISSSLPNPHY(wlc->band)) {
+ *cp++ = 's';
+ }
+ *cp = '\0';
+ break;
+ }
+
+ case WLC_GET_SHORTSLOT:
+ *pval = wlc->shortslot;
+ break;
+
+ case WLC_GET_SHORTSLOT_OVERRIDE:
+ *pval = wlc->shortslot_override;
+ break;
+
+ case WLC_SET_SHORTSLOT_OVERRIDE:
+ if ((val != WLC_SHORTSLOT_AUTO) &&
+ (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ wlc->shortslot_override = (int8) val;
+
+ /* shortslot is an 11g feature, so no more work if we are
+ * currently on the 5G band
+ */
+ if (BAND_5G(wlc->band->bandtype))
+ break;
+
+ if (wlc->pub->up && wlc->pub->associated) {
+ /* let watchdog or beacon processing update shortslot */
+ } else if (wlc->pub->up) {
+ /* unassociated shortslot is off */
+ wlc_switch_shortslot(wlc, FALSE);
+ } else {
+ /* driver is down, so just update the wlc_info value */
+ if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) {
+ wlc->shortslot = FALSE;
+ } else {
+ wlc->shortslot =
+ (wlc->shortslot_override ==
+ WLC_SHORTSLOT_ON);
+ }
+ }
+
+ break;
+
+ case WLC_GET_LEGACY_ERP:
+ *pval = wlc->include_legacy_erp;
+ break;
+
+ case WLC_SET_LEGACY_ERP:
+ if (wlc->include_legacy_erp == bool_val)
+ break;
+
+ wlc->include_legacy_erp = bool_val;
+
+ if (AP_ENAB(wlc->pub) && wlc->clk) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ }
+ break;
+
+ case WLC_GET_GMODE:
+ if (wlc->band->bandtype == WLC_BAND_2G)
+ *pval = wlc->band->gmode;
+ else if (NBANDS(wlc) > 1)
+ *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode;
+ break;
+
+ case WLC_SET_GMODE:
+ if (!wlc->pub->associated)
+ bcmerror = wlc_set_gmode(wlc, (uint8) val, TRUE);
+ else {
+ bcmerror = BCME_ASSOCIATED;
+ break;
+ }
+ break;
+
+ case WLC_GET_GMODE_PROTECTION:
+ *pval = wlc->protection->_g;
+ break;
+
+ case WLC_GET_PROTECTION_CONTROL:
+ *pval = wlc->protection->overlap;
+ break;
+
+ case WLC_SET_PROTECTION_CONTROL:
+ if ((val != WLC_PROTECTION_CTL_OFF) &&
+ (val != WLC_PROTECTION_CTL_LOCAL) &&
+ (val != WLC_PROTECTION_CTL_OVERLAP)) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (int8) val);
+
+ /* Current g_protection will sync up to the specified control alg in watchdog
+ * if the driver is up and associated.
+ * If the driver is down or not associated, the control setting has no effect.
+ */
+ break;
+
+ case WLC_GET_GMODE_PROTECTION_OVERRIDE:
+ *pval = wlc->protection->g_override;
+ break;
+
+ case WLC_SET_GMODE_PROTECTION_OVERRIDE:
+ if ((val != WLC_PROTECTION_AUTO) &&
+ (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) {
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ wlc_protection_upd(wlc, WLC_PROT_G_OVR, (int8) val);
+
+ break;
+
+ case WLC_SET_SUP_RATESET_OVERRIDE:{
+ wlc_rateset_t rs, new;
+
+ /* copyin */
+ if (len < (int)sizeof(wlc_rateset_t)) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+ bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t));
+
+ /* check for bad count value */
+ if (rs.count > WLC_NUMRATES) {
+ bcmerror = BCME_BADRATESET; /* invalid rateset */
+ break;
+ }
+
+ /* this command is only appropriate for gmode operation */
+ if (!(wlc->band->gmode ||
+ ((NBANDS(wlc) > 1)
+ && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+ bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */
+ break;
+ }
+
+ /* check for an empty rateset to clear the override */
+ if (rs.count == 0) {
+ bzero(&wlc->sup_rates_override,
+ sizeof(wlc_rateset_t));
+ break;
+ }
+
+ /* validate rateset by comparing pre and post sorted against 11g hw rates */
+ wlc_rateset_filter(&rs, &new, FALSE, WLC_RATES_CCK_OFDM,
+ RATE_MASK, BSS_N_ENAB(wlc, bsscfg));
+ wlc_rate_hwrs_filter_sort_validate(&new,
+ &cck_ofdm_rates,
+ FALSE,
+ wlc->stf->txstreams);
+ if (rs.count != new.count) {
+ bcmerror = BCME_BADRATESET; /* invalid rateset */
+ break;
+ }
+
+ /* apply new rateset to the override */
+ bcopy((char *)&new, (char *)&wlc->sup_rates_override,
+ sizeof(wlc_rateset_t));
+
+ /* update bcn and probe resp if needed */
+ if (wlc->pub->up && AP_ENAB(wlc->pub)
+ && wlc->pub->associated) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ }
+ break;
+ }
+
+ case WLC_GET_SUP_RATESET_OVERRIDE:
+ /* this command is only appropriate for gmode operation */
+ if (!(wlc->band->gmode ||
+ ((NBANDS(wlc) > 1)
+ && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+ bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */
+ break;
+ }
+ if (len < (int)sizeof(wlc_rateset_t)) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+ bcopy((char *)&wlc->sup_rates_override, (char *)arg,
+ sizeof(wlc_rateset_t));
+
+ break;
+
+ case WLC_GET_PRB_RESP_TIMEOUT:
+ *pval = wlc->prb_resp_timeout;
+ break;
+
+ case WLC_SET_PRB_RESP_TIMEOUT:
+ if (wlc->pub->up) {
+ bcmerror = BCME_NOTDOWN;
+ break;
+ }
+ if (val < 0 || val >= 0xFFFF) {
+ bcmerror = BCME_RANGE; /* bad value */
+ break;
+ }
+ wlc->prb_resp_timeout = (uint16) val;
+ break;
+
+ case WLC_GET_KEY_PRIMARY:{
+ wsec_key_t *key;
+
+ /* treat the 'val' parm as the key id */
+ key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+ if (key != NULL) {
+ *pval = key->id == val ? TRUE : FALSE;
+ } else {
+ bcmerror = BCME_BADKEYIDX;
+ }
+ break;
+ }
+
+ case WLC_SET_KEY_PRIMARY:{
+ wsec_key_t *key, *old_key;
+
+ bcmerror = BCME_BADKEYIDX;
+
+ /* treat the 'val' parm as the key id */
+ for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+ key = bsscfg->bss_def_keys[i];
+ if (key != NULL && key->id == val) {
+ old_key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+ if (old_key != NULL)
+ old_key->flags &=
+ ~WSEC_PRIMARY_KEY;
+ key->flags |= WSEC_PRIMARY_KEY;
+ bsscfg->wsec_index = i;
+ bcmerror = BCME_OK;
+ }
+ }
+ break;
+ }
+
+#ifdef BCMDBG
+ case WLC_INIT:
+ wl_init(wlc->wl);
+ break;
+#endif
+
+ case WLC_SET_VAR:
+ case WLC_GET_VAR:{
+ char *name;
+ /* validate the name value */
+ name = (char *)arg;
+ for (i = 0; i < (uint) len && *name != '\0';
+ i++, name++)
+ ;
+
+ if (i == (uint) len) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+ i++; /* include the null in the string length */
+
+ if (cmd == WLC_GET_VAR) {
+ bcmerror =
+ wlc_iovar_op(wlc, arg,
+ (void *)((int8 *) arg + i),
+ len - i, arg, len, IOV_GET,
+ wlcif);
+ } else
+ bcmerror =
+ wlc_iovar_op(wlc, arg, NULL, 0,
+ (void *)((int8 *) arg + i),
+ len - i, IOV_SET, wlcif);
+
+ break;
+ }
+
+ case WLC_SET_WSEC_PMK:
+ bcmerror = BCME_UNSUPPORTED;
+ break;
+
+#if defined(BCMDBG)
+ case WLC_CURRENT_PWR:
+ if (!wlc->pub->up)
+ bcmerror = BCME_NOTUP;
+ else
+ bcmerror = wlc_get_current_txpwr(wlc, arg, len);
+ break;
+#endif
+
+ case WLC_LAST:
+ WL_ERROR(("%s: WLC_LAST\n", __func__));
+ }
+ done:
+
+ if (bcmerror) {
+ if (VALID_BCMERROR(bcmerror))
+ wlc->pub->bcmerror = bcmerror;
+ else {
+ bcmerror = 0;
+ }
+
+ }
+#ifdef WLC_LOW
+ /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
+ /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would
+ * certainly result in getting -1 for register reads. So skip ta_clear altogether
+ */
+ if (!(wlc->pub->hw_off))
+ ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok);
+#endif
+
+ return bcmerror;
+}
+
+#if defined(BCMDBG)
+/* consolidated register access ioctl error checking */
+int wlc_iocregchk(wlc_info_t *wlc, uint band)
+{
+ /* if band is specified, it must be the current band */
+ if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype))
+ return BCME_BADBAND;
+
+ /* if multiband and band is not specified, band must be locked */
+ if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc))
+ return BCME_NOTBANDLOCKED;
+
+ /* must have core clocks */
+ if (!wlc->clk)
+ return BCME_NOCLK;
+
+ return 0;
+}
+#endif /* defined(BCMDBG) */
+
+#if defined(BCMDBG)
+/* For some ioctls, make sure that the pi pointer matches the current phy */
+int wlc_iocpichk(wlc_info_t *wlc, uint phytype)
+{
+ if (wlc->band->phytype != phytype)
+ return BCME_BADBAND;
+ return 0;
+}
+#endif
+
+/* Look up the given var name in the given table */
+static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table,
+ const char *name)
+{
+ const bcm_iovar_t *vi;
+ const char *lookup_name;
+
+ /* skip any ':' delimited option prefixes */
+ lookup_name = strrchr(name, ':');
+ if (lookup_name != NULL)
+ lookup_name++;
+ else
+ lookup_name = name;
+
+ ASSERT(table != NULL);
+
+ for (vi = table; vi->name; vi++) {
+ if (!strcmp(vi->name, lookup_name))
+ return vi;
+ }
+ /* ran to end of table */
+
+ return NULL; /* var name not found */
+}
+
+/* simplified integer get interface for common WLC_GET_VAR ioctl handler */
+int wlc_iovar_getint(wlc_info_t *wlc, const char *name, int *arg)
+{
+ return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(int32), IOV_GET,
+ NULL);
+}
+
+/* simplified integer set interface for common WLC_SET_VAR ioctl handler */
+int wlc_iovar_setint(wlc_info_t *wlc, const char *name, int arg)
+{
+ return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg),
+ IOV_SET, NULL);
+}
+
+/* simplified int8 get interface for common WLC_GET_VAR ioctl handler */
+int wlc_iovar_getint8(wlc_info_t *wlc, const char *name, int8 *arg)
+{
+ int iovar_int;
+ int err;
+
+ err =
+ wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int),
+ IOV_GET, NULL);
+ if (!err)
+ *arg = (int8) iovar_int;
+
+ return err;
+}
+
+/*
+ * register iovar table, watchdog and down handlers.
+ * calling function must keep 'iovars' until wlc_module_unregister is called.
+ * 'iovar' must have the last entry's name field being NULL as terminator.
+ */
+int
+BCMATTACHFN(wlc_module_register) (wlc_pub_t *pub, const bcm_iovar_t *iovars,
+ const char *name, void *hdl, iovar_fn_t i_fn,
+ watchdog_fn_t w_fn, down_fn_t d_fn) {
+ wlc_info_t *wlc = (wlc_info_t *) pub->wlc;
+ int i;
+
+ ASSERT(name != NULL);
+ ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL);
+
+ /* find an empty entry and just add, no duplication check! */
+ for (i = 0; i < WLC_MAXMODULES; i++) {
+ if (wlc->modulecb[i].name[0] == '\0') {
+ strncpy(wlc->modulecb[i].name, name,
+ sizeof(wlc->modulecb[i].name) - 1);
+ wlc->modulecb[i].iovars = iovars;
+ wlc->modulecb[i].hdl = hdl;
+ wlc->modulecb[i].iovar_fn = i_fn;
+ wlc->modulecb[i].watchdog_fn = w_fn;
+ wlc->modulecb[i].down_fn = d_fn;
+ return 0;
+ }
+ }
+
+ /* it is time to increase the capacity */
+ ASSERT(i < WLC_MAXMODULES);
+ return BCME_NORESOURCE;
+}
+
+/* unregister module callbacks */
+int
+BCMATTACHFN(wlc_module_unregister) (wlc_pub_t *pub, const char *name,
+ void *hdl) {
+ wlc_info_t *wlc = (wlc_info_t *) pub->wlc;
+ int i;
+
+ if (wlc == NULL)
+ return BCME_NOTFOUND;
+
+ ASSERT(name != NULL);
+
+ for (i = 0; i < WLC_MAXMODULES; i++) {
+ if (!strcmp(wlc->modulecb[i].name, name) &&
+ (wlc->modulecb[i].hdl == hdl)) {
+ bzero(&wlc->modulecb[i], sizeof(modulecb_t));
+ return 0;
+ }
+ }
+
+ /* table not found! */
+ return BCME_NOTFOUND;
+}
+
+/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
+static void wlc_wme_retries_write(wlc_info_t *wlc)
+{
+ int ac;
+
+ /* Need clock to do this */
+ if (!wlc->clk)
+ return;
+
+ for (ac = 0; ac < AC_COUNT; ac++) {
+ wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]);
+ }
+}
+
+/* Get or set an iovar. The params/p_len pair specifies any additional
+ * qualifying parameters (e.g. an "element index") for a get, while the
+ * arg/len pair is the buffer for the value to be set or retrieved.
+ * Operation (get/set) is specified by the last argument.
+ * interface context provided by wlcif
+ *
+ * All pointers may point into the same buffer.
+ */
+int
+wlc_iovar_op(wlc_info_t *wlc, const char *name,
+ void *params, int p_len, void *arg, int len,
+ bool set, struct wlc_if *wlcif)
+{
+ int err = 0;
+ int val_size;
+ const bcm_iovar_t *vi = NULL;
+ uint32 actionid;
+ int i;
+
+ ASSERT(name != NULL);
+
+ ASSERT(len >= 0);
+
+ /* Get MUST have return space */
+ ASSERT(set || (arg && len));
+
+ ASSERT(!(wlc->pub->hw_off && wlc->pub->up));
+
+ /* Set does NOT take qualifiers */
+ ASSERT(!set || (!params && !p_len));
+
+ if (!set && (len == sizeof(int)) &&
+ !(ISALIGNED((uintptr) (arg), (uint) sizeof(int)))) {
+ WL_ERROR(("wl%d: %s unaligned get ptr for %s\n",
+ wlc->pub->unit, __func__, name));
+ ASSERT(0);
+ }
+
+ /* find the given iovar name */
+ for (i = 0; i < WLC_MAXMODULES; i++) {
+ if (!wlc->modulecb[i].iovars)
+ continue;
+ vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name);
+ if (vi)
+ break;
+ }
+ /* iovar name not found */
+ if (i >= WLC_MAXMODULES) {
+ err = BCME_UNSUPPORTED;
+#ifdef WLC_HIGH_ONLY
+ err =
+ bcmsdh_iovar_op(wlc->btparam, name, params, p_len, arg, len,
+ set);
+#endif
+ goto exit;
+ }
+
+ /* set up 'params' pointer in case this is a set command so that
+ * the convenience int and bool code can be common to set and get
+ */
+ if (params == NULL) {
+ params = arg;
+ p_len = len;
+ }
+
+ if (vi->type == IOVT_VOID)
+ val_size = 0;
+ else if (vi->type == IOVT_BUFFER)
+ val_size = len;
+ else
+ /* all other types are integer sized */
+ val_size = sizeof(int);
+
+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+
+ /* Do the actual parameter implementation */
+ err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid,
+ name, params, p_len, arg, len, val_size,
+ wlcif);
+
+ exit:
+ return err;
+}
+
+int
+wlc_iovar_check(wlc_pub_t *pub, const bcm_iovar_t *vi, void *arg, int len,
+ bool set)
+{
+ wlc_info_t *wlc = (wlc_info_t *) pub->wlc;
+ int err = 0;
+ int32 int_val = 0;
+
+ /* check generic condition flags */
+ if (set) {
+ if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) ||
+ ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) {
+ err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
+ } else if ((vi->flags & IOVF_SET_BAND)
+ && IS_MBAND_UNLOCKED(wlc)) {
+ err = BCME_NOTBANDLOCKED;
+ } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) {
+ err = BCME_NOCLK;
+ }
+ } else {
+ if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) ||
+ ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) {
+ err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
+ } else if ((vi->flags & IOVF_GET_BAND)
+ && IS_MBAND_UNLOCKED(wlc)) {
+ err = BCME_NOTBANDLOCKED;
+ } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) {
+ err = BCME_NOCLK;
+ }
+ }
+
+ if (err)
+ goto exit;
+
+ /* length check on io buf */
+ err = bcm_iovar_lencheck(vi, arg, len, set);
+ if (err)
+ goto exit;
+
+ /* On set, check value ranges for integer types */
+ if (set) {
+ switch (vi->type) {
+ case IOVT_BOOL:
+ case IOVT_INT8:
+ case IOVT_INT16:
+ case IOVT_INT32:
+ case IOVT_UINT8:
+ case IOVT_UINT16:
+ case IOVT_UINT32:
+ bcopy(arg, &int_val, sizeof(int));
+ err = wlc_iovar_rangecheck(wlc, int_val, vi);
+ break;
+ }
+ }
+ exit:
+ return err;
+}
+
+/* handler for iovar table wlc_iovars */
+/*
+ * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each
+ * iovar case, the switch statement maps the iovar id into separate get
+ * and set values. If you add a new iovar to the switch you MUST use
+ * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with
+ * another case.
+ * Please use params for additional qualifying parameters.
+ */
+int
+wlc_doiovar(void *hdl, const bcm_iovar_t *vi, uint32 actionid,
+ const char *name, void *params, uint p_len, void *arg, int len,
+ int val_size, struct wlc_if *wlcif)
+{
+ wlc_info_t *wlc = hdl;
+ wlc_bsscfg_t *bsscfg;
+ int err = 0;
+ int32 int_val = 0;
+ int32 int_val2 = 0;
+ int32 *ret_int_ptr;
+ bool bool_val;
+ bool bool_val2;
+ wlc_bss_info_t *current_bss;
+
+ WL_TRACE(("wl%d: %s\n", wlc->pub->unit, __func__));
+
+ bsscfg = NULL;
+ current_bss = NULL;
+
+ err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid));
+ if (err != 0)
+ return err;
+
+ /* convenience int and bool vals for first 8 bytes of buffer */
+ if (p_len >= (int)sizeof(int_val))
+ bcopy(params, &int_val, sizeof(int_val));
+
+ if (p_len >= (int)sizeof(int_val) * 2)
+ bcopy((void *)((uintptr) params + sizeof(int_val)), &int_val2,
+ sizeof(int_val));
+
+ /* convenience int ptr for 4-byte gets (requires int aligned arg) */
+ ret_int_ptr = (int32 *) arg;
+
+ bool_val = (int_val != 0) ? TRUE : FALSE;
+ bool_val2 = (int_val2 != 0) ? TRUE : FALSE;
+
+ WL_TRACE(("wl%d: %s: id %d\n", wlc->pub->unit, __func__,
+ IOV_ID(actionid)));
+ /* Do the actual parameter implementation */
+ switch (actionid) {
+
+ case IOV_GVAL(IOV_QTXPOWER):{
+ uint qdbm;
+ bool override;
+
+ err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
+ &override);
+ if (err != BCME_OK)
+ return err;
+
+ /* Return qdbm units */
+ *ret_int_ptr =
+ qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
+ break;
+ }
+
+ /* As long as override is false, this only sets the *user* targets.
+ User can twiddle this all he wants with no harm.
+ wlc_phy_txpower_set() explicitly sets override to false if
+ not internal or test.
+ */
+ case IOV_SVAL(IOV_QTXPOWER):{
+ uint8 qdbm;
+ bool override;
+
+ /* Remove override bit and clip to max qdbm value */
+ qdbm =
+ (uint8) MIN((int_val & ~WL_TXPWR_OVERRIDE), 0xff);
+ /* Extract override setting */
+ override = (int_val & WL_TXPWR_OVERRIDE) ? TRUE : FALSE;
+ err =
+ wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
+ break;
+ }
+
+ case IOV_GVAL(IOV_MPC):
+ *ret_int_ptr = (int32) wlc->mpc;
+ break;
+
+ case IOV_SVAL(IOV_MPC):
+ wlc->mpc = bool_val;
+ wlc_radio_mpc_upd(wlc);
+
+ break;
+
+ case IOV_GVAL(IOV_BCN_LI_BCN):
+ *ret_int_ptr = wlc->bcn_li_bcn;
+ break;
+
+ case IOV_SVAL(IOV_BCN_LI_BCN):
+ wlc->bcn_li_bcn = (uint8) int_val;
+ if (wlc->pub->up)
+ wlc_bcn_li_upd(wlc);
+ break;
+
+ default:
+ WL_ERROR(("wl%d: %s: unsupported\n", wlc->pub->unit, __func__));
+ err = BCME_UNSUPPORTED;
+ break;
+ }
+
+ goto exit; /* avoid unused label warning */
+
+ exit:
+ return err;
+}
+
+static int
+wlc_iovar_rangecheck(wlc_info_t *wlc, uint32 val, const bcm_iovar_t *vi)
+{
+ int err = 0;
+ uint32 min_val = 0;
+ uint32 max_val = 0;
+
+ /* Only ranged integers are checked */
+ switch (vi->type) {
+ case IOVT_INT32:
+ max_val |= 0x7fffffff;
+ /* fall through */
+ case IOVT_INT16:
+ max_val |= 0x00007fff;
+ /* fall through */
+ case IOVT_INT8:
+ max_val |= 0x0000007f;
+ min_val = ~max_val;
+ if (vi->flags & IOVF_NTRL)
+ min_val = 1;
+ else if (vi->flags & IOVF_WHL)
+ min_val = 0;
+ /* Signed values are checked against max_val and min_val */
+ if ((int32) val < (int32) min_val
+ || (int32) val > (int32) max_val)
+ err = BCME_RANGE;
+ break;
+
+ case IOVT_UINT32:
+ max_val |= 0xffffffff;
+ /* fall through */
+ case IOVT_UINT16:
+ max_val |= 0x0000ffff;
+ /* fall through */
+ case IOVT_UINT8:
+ max_val |= 0x000000ff;
+ if (vi->flags & IOVF_NTRL)
+ min_val = 1;
+ if ((val < min_val) || (val > max_val))
+ err = BCME_RANGE;
+ break;
+ }
+
+ return err;
+}
+
+#if defined(BCMDBG)
+static const struct wlc_id_name_entry dot11_ie_names[] = {
+ {DOT11_MNG_SSID_ID, "SSID"},
+ {DOT11_MNG_RATES_ID, "Rates"},
+ {DOT11_MNG_FH_PARMS_ID, "FH Parms"},
+ {DOT11_MNG_DS_PARMS_ID, "DS Parms"},
+ {DOT11_MNG_CF_PARMS_ID, "CF Parms"},
+ {DOT11_MNG_TIM_ID, "TIM"},
+ {DOT11_MNG_IBSS_PARMS_ID, "IBSS Parms"},
+ {DOT11_MNG_COUNTRY_ID, "Country"},
+ {DOT11_MNG_HOPPING_PARMS_ID, "Hopping Parms"},
+ {DOT11_MNG_HOPPING_TABLE_ID, "Hopping Table"},
+ {DOT11_MNG_REQUEST_ID, "Request"},
+ {DOT11_MNG_QBSS_LOAD_ID, "QBSS LOAD"},
+ {DOT11_MNG_CHALLENGE_ID, "Challenge"},
+ {DOT11_MNG_PWR_CONSTRAINT_ID, "Pwr Constraint"},
+ {DOT11_MNG_PWR_CAP_ID, "Pwr Capability"},
+ {DOT11_MNG_TPC_REQUEST_ID, "TPC Request"},
+ {DOT11_MNG_TPC_REPORT_ID, "TPC Report"},
+ {DOT11_MNG_SUPP_CHANNELS_ID, "Supported Channels"},
+ {DOT11_MNG_CHANNEL_SWITCH_ID, "Channel Switch"},
+ {DOT11_MNG_MEASURE_REQUEST_ID, "Measure Request"},
+ {DOT11_MNG_MEASURE_REPORT_ID, "Measure Report"},
+ {DOT11_MNG_QUIET_ID, "Quiet"},
+ {DOT11_MNG_IBSS_DFS_ID, "IBSS DFS"},
+ {DOT11_MNG_ERP_ID, "ERP Info"},
+ {DOT11_MNG_TS_DELAY_ID, "TS Delay"},
+ {DOT11_MNG_HT_CAP, "HT Capability"},
+ {DOT11_MNG_NONERP_ID, "Legacy ERP Info"},
+ {DOT11_MNG_RSN_ID, "RSN"},
+ {DOT11_MNG_EXT_RATES_ID, "Ext Rates"},
+ {DOT11_MNG_HT_ADD, "HT Additional"},
+ {DOT11_MNG_EXT_CHANNEL_OFFSET, "Ext Channel Offset"},
+ {DOT11_MNG_VS_ID, "Vendor Specific"},
+ {0, NULL}
+};
+#endif /* defined(BCMDBG) */
+
+#ifdef BCMDBG
+static const char *supr_reason[] = {
+ "None", "PMQ Entry", "Flush request",
+ "Previous frag failure", "Channel mismatch",
+ "Lifetime Expiry", "Underflow"
+};
+
+static void wlc_print_txs_status(uint16 s)
+{
+ printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >>
+ TX_STATUS_FRM_RTX_SHIFT);
+ printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >>
+ TX_STATUS_RTS_RTX_SHIFT);
+ printf(" [7] %d PM mode indicated\n",
+ ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
+ printf(" [6] %d intermediate status\n",
+ ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
+ printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0);
+ printf(" [4:2] %d Frame Suppressed Reason (%s)\n",
+ ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
+ supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
+ printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
+}
+#endif /* BCMDBG */
+
+void wlc_print_txstatus(tx_status_t *txs)
+{
+#if defined(BCMDBG)
+ uint16 s = txs->status;
+ uint16 ackphyrxsh = txs->ackphyrxsh;
+
+ printf("\ntxpkt (MPDU) Complete\n");
+
+ printf("FrameID: %04x ", txs->frameid);
+ printf("TxStatus: %04x", s);
+ printf("\n");
+#ifdef BCMDBG
+ wlc_print_txs_status(s);
+#endif
+ printf("LastTxTime: %04x ", txs->lasttxtime);
+ printf("Seq: %04x ", txs->sequence);
+ printf("PHYTxStatus: %04x ", txs->phyerr);
+ printf("RxAckRSSI: %04x ",
+ (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
+ printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
+ printf("\n");
+#endif /* defined(BCMDBG) */
+}
+
+#define MACSTATUPD(name) \
+ wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name)
+
+void wlc_statsupd(wlc_info_t *wlc)
+{
+ int i;
+#ifdef BCMDBG
+ uint16 delta;
+ uint16 rxf0ovfl;
+ uint16 txfunfl[NFIFO];
+#endif /* BCMDBG */
+
+ /* if driver down, make no sense to update stats */
+ if (!wlc->pub->up)
+ return;
+
+#ifdef BCMDBG
+ /* save last rx fifo 0 overflow count */
+ rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
+
+ /* save last tx fifo underflow count */
+ for (i = 0; i < NFIFO; i++)
+ txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
+#endif /* BCMDBG */
+
+#ifdef BCMDBG
+ /* check for rx fifo 0 overflow */
+ delta = (uint16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
+ if (delta)
+ WL_ERROR(("wl%d: %u rx fifo 0 overflows!\n", wlc->pub->unit,
+ delta));
+
+ /* check for tx fifo underflows */
+ for (i = 0; i < NFIFO; i++) {
+ delta =
+ (uint16) (wlc->core->macstat_snapshot->txfunfl[i] -
+ txfunfl[i]);
+ if (delta)
+ WL_ERROR(("wl%d: %u tx fifo %d underflows!\n",
+ wlc->pub->unit, delta, i));
+ }
+#endif /* BCMDBG */
+
+ /* dot11 counter update */
+
+ WLCNTSET(wlc->pub->_cnt->txrts,
+ (wlc->pub->_cnt->rxctsucast -
+ wlc->pub->_cnt->d11cnt_txrts_off));
+ WLCNTSET(wlc->pub->_cnt->rxcrc,
+ (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off));
+ WLCNTSET(wlc->pub->_cnt->txnocts,
+ ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) -
+ wlc->pub->_cnt->d11cnt_txnocts_off));
+
+ /* merge counters from dma module */
+ for (i = 0; i < NFIFO; i++) {
+ if (wlc->hw->di[i]) {
+ WLCNTADD(wlc->pub->_cnt->txnobuf,
+ (wlc->hw->di[i])->txnobuf);
+ WLCNTADD(wlc->pub->_cnt->rxnobuf,
+ (wlc->hw->di[i])->rxnobuf);
+ WLCNTADD(wlc->pub->_cnt->rxgiant,
+ (wlc->hw->di[i])->rxgiants);
+ dma_counterreset(wlc->hw->di[i]);
+ }
+ }
+
+ /*
+ * Aggregate transmit and receive errors that probably resulted
+ * in the loss of a frame are computed on the fly.
+ */
+ WLCNTSET(wlc->pub->_cnt->txerror,
+ wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc +
+ wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt +
+ wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada +
+ wlc->pub->_cnt->dmape);
+ WLCNTSET(wlc->pub->_cnt->rxerror,
+ wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf +
+ wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt +
+ wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb +
+ wlc->pub->_cnt->rxbadsrcmac);
+ for (i = 0; i < NFIFO; i++)
+ WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]);
+}
+
+bool wlc_chipmatch(uint16 vendor, uint16 device)
+{
+ if (vendor != VENDOR_BROADCOM) {
+ WL_ERROR(("wlc_chipmatch: unknown vendor id %04x\n", vendor));
+ return FALSE;
+ }
+
+ if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
+ return TRUE;
+
+ if (device == BCM4313_D11N2G_ID)
+ return TRUE;
+ if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
+ return TRUE;
+
+ WL_ERROR(("wlc_chipmatch: unknown device id %04x\n", device));
+ return FALSE;
+}
+
+#if defined(BCMDBG)
+static const char *errstr = "802.11 Header INCOMPLETE\n";
+static const char *fillstr = "------------";
+static void wlc_print_dot11hdr(uint8 *buf, int len)
+{
+ char hexbuf[(2 * D11B_PHY_HDR_LEN) + 1];
+
+ if (len == 0) {
+ printf("802.11 Header MISSING\n");
+ return;
+ }
+
+ if (len < D11B_PHY_HDR_LEN) {
+ bcm_format_hex(hexbuf, buf, len);
+ strncpy(hexbuf + (2 * len), fillstr,
+ 2 * (D11B_PHY_HDR_LEN - len));
+ hexbuf[sizeof(hexbuf) - 1] = '\0';
+ } else {
+ bcm_format_hex(hexbuf, buf, D11B_PHY_HDR_LEN);
+ }
+
+ printf("PLCPHdr: %s ", hexbuf);
+ if (len < D11B_PHY_HDR_LEN) {
+ printf("%s\n", errstr);
+ return;
+ }
+
+ len -= D11B_PHY_HDR_LEN;
+ buf += D11B_PHY_HDR_LEN;
+
+ wlc_print_dot11_mac_hdr(buf, len);
+}
+
+void wlc_print_dot11_mac_hdr(uint8 *buf, int len)
+{
+ char hexbuf[(2 * D11B_PHY_HDR_LEN) + 1];
+ char a1[(2 * ETHER_ADDR_LEN) + 1], a2[(2 * ETHER_ADDR_LEN) + 1];
+ char a3[(2 * ETHER_ADDR_LEN) + 1];
+ char flagstr[64];
+ uint16 fc, kind, toDS, fromDS;
+ uint16 v;
+ int fill_len = 0;
+ static const bcm_bit_desc_t fc_flags[] = {
+ {FC_TODS, "ToDS"},
+ {FC_FROMDS, "FromDS"},
+ {FC_MOREFRAG, "MoreFrag"},
+ {FC_RETRY, "Retry"},
+ {FC_PM, "PM"},
+ {FC_MOREDATA, "MoreData"},
+ {FC_WEP, "WEP"},
+ {FC_ORDER, "Order"},
+ {0, NULL}
+ };
+
+ if (len < 2) {
+ printf("FC: ------ ");
+ printf("%s\n", errstr);
+ return;
+ }
+
+ fc = buf[0] | (buf[1] << 8);
+ kind = fc & FC_KIND_MASK;
+ toDS = (fc & FC_TODS) != 0;
+ fromDS = (fc & FC_FROMDS) != 0;
+
+ bcm_format_flags(fc_flags, fc, flagstr, 64);
+
+ printf("FC: 0x%04x ", fc);
+ if (flagstr[0] != '\0')
+ printf("(%s) ", flagstr);
+
+ len -= 2;
+ buf += 2;
+
+ if (len < 2) {
+ printf("Dur/AID: ----- ");
+ printf("%s\n", errstr);
+ return;
+ }
+
+ v = buf[0] | (buf[1] << 8);
+ if (kind == FC_PS_POLL) {
+ printf("AID: 0x%04x", v);
+ } else {
+ printf("Dur: 0x%04x", v);
+ }
+ printf("\n");
+ len -= 2;
+ buf += 2;
+
+ strncpy(a1, fillstr, sizeof(a1));
+ strncpy(a2, fillstr, sizeof(a2));
+ strncpy(a3, fillstr, sizeof(a3));
+
+ if (len < ETHER_ADDR_LEN) {
+ bcm_format_hex(a1, buf, len);
+ strncpy(a1 + (2 * len), fillstr, 2 * (ETHER_ADDR_LEN - len));
+ } else if (len < 2 * ETHER_ADDR_LEN) {
+ bcm_format_hex(a1, buf, ETHER_ADDR_LEN);
+ bcm_format_hex(a2, buf + ETHER_ADDR_LEN, len - ETHER_ADDR_LEN);
+ fill_len = len - ETHER_ADDR_LEN;
+ strncpy(a2 + (2 * fill_len), fillstr,
+ 2 * (ETHER_ADDR_LEN - fill_len));
+ } else if (len < 3 * ETHER_ADDR_LEN) {
+ bcm_format_hex(a1, buf, ETHER_ADDR_LEN);
+ bcm_format_hex(a2, buf + ETHER_ADDR_LEN, ETHER_ADDR_LEN);
+ bcm_format_hex(a3, buf + (2 * ETHER_ADDR_LEN),
+ len - (2 * ETHER_ADDR_LEN));
+ fill_len = len - (2 * ETHER_ADDR_LEN);
+ strncpy(a3 + (2 * fill_len), fillstr,
+ 2 * (ETHER_ADDR_LEN - fill_len));
+ } else {
+ bcm_format_hex(a1, buf, ETHER_ADDR_LEN);
+ bcm_format_hex(a2, buf + ETHER_ADDR_LEN, ETHER_ADDR_LEN);
+ bcm_format_hex(a3, buf + (2 * ETHER_ADDR_LEN), ETHER_ADDR_LEN);
+ }
+
+ if (kind == FC_RTS) {
+ printf("RA: %s ", a1);
+ printf("TA: %s ", a2);
+ if (len < 2 * ETHER_ADDR_LEN)
+ printf("%s ", errstr);
+ } else if (kind == FC_CTS || kind == FC_ACK) {
+ printf("RA: %s ", a1);
+ if (len < ETHER_ADDR_LEN)
+ printf("%s ", errstr);
+ } else if (kind == FC_PS_POLL) {
+ printf("BSSID: %s", a1);
+ printf("TA: %s ", a2);
+ if (len < 2 * ETHER_ADDR_LEN)
+ printf("%s ", errstr);
+ } else if (kind == FC_CF_END || kind == FC_CF_END_ACK) {
+ printf("RA: %s ", a1);
+ printf("BSSID: %s ", a2);
+ if (len < 2 * ETHER_ADDR_LEN)
+ printf("%s ", errstr);
+ } else if (FC_TYPE(fc) == FC_TYPE_DATA) {
+ if (!toDS) {
+ printf("DA: %s ", a1);
+ if (!fromDS) {
+ printf("SA: %s ", a2);
+ printf("BSSID: %s ", a3);
+ } else {
+ printf("BSSID: %s ", a2);
+ printf("SA: %s ", a3);
+ }
+ } else if (!fromDS) {
+ printf("BSSID: %s ", a1);
+ printf("SA: %s ", a2);
+ printf("DA: %s ", a3);
+ } else {
+ printf("RA: %s ", a1);
+ printf("TA: %s ", a2);
+ printf("DA: %s ", a3);
+ }
+ if (len < 3 * ETHER_ADDR_LEN) {
+ printf("%s ", errstr);
+ } else if (len < 20) {
+ printf("SeqCtl: ------ ");
+ printf("%s ", errstr);
+ } else {
+ len -= 3 * ETHER_ADDR_LEN;
+ buf += 3 * ETHER_ADDR_LEN;
+ v = buf[0] | (buf[1] << 8);
+ printf("SeqCtl: 0x%04x ", v);
+ len -= 2;
+ buf += 2;
+ }
+ } else if (FC_TYPE(fc) == FC_TYPE_MNG) {
+ printf("DA: %s ", a1);
+ printf("SA: %s ", a2);
+ printf("BSSID: %s ", a3);
+ if (len < 3 * ETHER_ADDR_LEN) {
+ printf("%s ", errstr);
+ } else if (len < 20) {
+ printf("SeqCtl: ------ ");
+ printf("%s ", errstr);
+ } else {
+ len -= 3 * ETHER_ADDR_LEN;
+ buf += 3 * ETHER_ADDR_LEN;
+ v = buf[0] | (buf[1] << 8);
+ printf("SeqCtl: 0x%04x ", v);
+ len -= 2;
+ buf += 2;
+ }
+ }
+
+ if ((FC_TYPE(fc) == FC_TYPE_DATA) && toDS && fromDS) {
+
+ if (len < ETHER_ADDR_LEN) {
+ bcm_format_hex(hexbuf, buf, len);
+ strncpy(hexbuf + (2 * len), fillstr,
+ 2 * (ETHER_ADDR_LEN - len));
+ } else {
+ bcm_format_hex(hexbuf, buf, ETHER_ADDR_LEN);
+ }
+
+ printf("SA: %s ", hexbuf);
+
+ if (len < ETHER_ADDR_LEN) {
+ printf("%s ", errstr);
+ } else {
+ len -= ETHER_ADDR_LEN;
+ buf += ETHER_ADDR_LEN;
+ }
+ }
+
+ if ((FC_TYPE(fc) == FC_TYPE_DATA) && (kind == FC_QOS_DATA)) {
+ if (len < 2) {
+ printf("QoS: ------");
+ printf("%s ", errstr);
+ } else {
+ v = buf[0] | (buf[1] << 8);
+ printf("QoS: 0x%04x ", v);
+ len -= 2;
+ buf += 2;
+ }
+ }
+
+ printf("\n");
+ return;
+}
+#endif /* defined(BCMDBG) */
+
+#if defined(BCMDBG)
+void wlc_print_txdesc(d11txh_t *txh)
+{
+ uint16 mtcl = ltoh16(txh->MacTxControlLow);
+ uint16 mtch = ltoh16(txh->MacTxControlHigh);
+ uint16 mfc = ltoh16(txh->MacFrameControl);
+ uint16 tfest = ltoh16(txh->TxFesTimeNormal);
+ uint16 ptcw = ltoh16(txh->PhyTxControlWord);
+ uint16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1);
+ uint16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr);
+ uint16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts);
+ uint16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts);
+ uint16 mainrates = ltoh16(txh->MainRates);
+ uint16 xtraft = ltoh16(txh->XtraFrameTypes);
+ uint8 *iv = txh->IV;
+ uint8 *ra = txh->TxFrameRA;
+ uint16 tfestfb = ltoh16(txh->TxFesTimeFallback);
+ uint8 *rtspfb = txh->RTSPLCPFallback;
+ uint16 rtsdfb = ltoh16(txh->RTSDurFallback);
+ uint8 *fragpfb = txh->FragPLCPFallback;
+ uint16 fragdfb = ltoh16(txh->FragDurFallback);
+ uint16 mmodelen = ltoh16(txh->MModeLen);
+ uint16 mmodefbrlen = ltoh16(txh->MModeFbrLen);
+ uint16 tfid = ltoh16(txh->TxFrameID);
+ uint16 txs = ltoh16(txh->TxStatus);
+ uint16 mnmpdu = ltoh16(txh->MaxNMpdus);
+ uint16 mabyte = ltoh16(txh->MaxABytes_MRT);
+ uint16 mabyte_f = ltoh16(txh->MaxABytes_FBR);
+ uint16 mmbyte = ltoh16(txh->MinMBytes);
+
+ uint8 *rtsph = txh->RTSPhyHeader;
+ struct dot11_rts_frame rts = txh->rts_frame;
+ char hexbuf[256];
+
+ /* add plcp header along with txh descriptor */
+ prhex("Raw TxDesc + plcp header", (uchar *) txh, sizeof(d11txh_t) + 48);
+
+ printf("TxCtlLow: %04x ", mtcl);
+ printf("TxCtlHigh: %04x ", mtch);
+ printf("FC: %04x ", mfc);
+ printf("FES Time: %04x\n", tfest);
+ printf("PhyCtl: %04x%s ", ptcw,
+ (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
+ printf("PhyCtl_1: %04x ", ptcw_1);
+ printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
+ printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
+ printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
+ printf("MainRates: %04x ", mainrates);
+ printf("XtraFrameTypes: %04x ", xtraft);
+ printf("\n");
+
+ bcm_format_hex(hexbuf, iv, sizeof(txh->IV));
+ printf("SecIV: %s\n", hexbuf);
+ bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
+ printf("RA: %s\n", hexbuf);
+
+ printf("Fb FES Time: %04x ", tfestfb);
+ bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
+ printf("RTS PLCP: %s ", hexbuf);
+ printf("RTS DUR: %04x ", rtsdfb);
+ bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
+ printf("PLCP: %s ", hexbuf);
+ printf("DUR: %04x", fragdfb);
+ printf("\n");
+
+ printf("MModeLen: %04x ", mmodelen);
+ printf("MModeFbrLen: %04x\n", mmodefbrlen);
+
+ printf("FrameID: %04x\n", tfid);
+ printf("TxStatus: %04x\n", txs);
+
+ printf("MaxNumMpdu: %04x\n", mnmpdu);
+ printf("MaxAggbyte: %04x\n", mabyte);
+ printf("MaxAggbyte_fb: %04x\n", mabyte_f);
+ printf("MinByte: %04x\n", mmbyte);
+
+ bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
+ printf("RTS PLCP: %s ", hexbuf);
+ bcm_format_hex(hexbuf, (uint8 *) &rts, sizeof(txh->rts_frame));
+ printf("RTS Frame: %s", hexbuf);
+ printf("\n");
+
+ if (mtcl & TXC_SENDRTS) {
+ wlc_print_dot11_mac_hdr((uint8 *) &rts,
+ sizeof(txh->rts_frame));
+ }
+}
+#endif /* defined(BCMDBG) */
+
+#if defined(BCMDBG)
+void wlc_print_rxh(d11rxhdr_t *rxh)
+{
+ uint16 len = rxh->RxFrameSize;
+ uint16 phystatus_0 = rxh->PhyRxStatus_0;
+ uint16 phystatus_1 = rxh->PhyRxStatus_1;
+ uint16 phystatus_2 = rxh->PhyRxStatus_2;
+ uint16 phystatus_3 = rxh->PhyRxStatus_3;
+ uint16 macstatus1 = rxh->RxStatus1;
+ uint16 macstatus2 = rxh->RxStatus2;
+ char flagstr[64];
+ char lenbuf[20];
+ static const bcm_bit_desc_t macstat_flags[] = {
+ {RXS_FCSERR, "FCSErr"},
+ {RXS_RESPFRAMETX, "Reply"},
+ {RXS_PBPRES, "PADDING"},
+ {RXS_DECATMPT, "DeCr"},
+ {RXS_DECERR, "DeCrErr"},
+ {RXS_BCNSENT, "Bcn"},
+ {0, NULL}
+ };
+
+ prhex("Raw RxDesc", (uchar *) rxh, sizeof(d11rxhdr_t));
+
+ bcm_format_flags(macstat_flags, macstatus1, flagstr, 64);
+
+ snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
+
+ printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len,
+ (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
+ printf("RxPHYStatus: %04x %04x %04x %04x\n",
+ phystatus_0, phystatus_1, phystatus_2, phystatus_3);
+ printf("RxMACStatus: %x %s\n", macstatus1, flagstr);
+ printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK));
+ printf("RxTSFTime: %04x\n", rxh->RxTSFTime);
+}
+
+void
+wlc_print_hdrs(wlc_info_t *wlc, const char *prefix, uint8 *frame,
+ d11txh_t *txh, d11rxhdr_t *rxh, uint len)
+{
+ ASSERT(!(txh && rxh));
+
+ printf("\nwl%d: %s:\n", wlc->pub->unit, prefix);
+
+ if (txh) {
+ wlc_print_txdesc(txh);
+ } else if (rxh) {
+ wlc_print_rxh(rxh);
+ }
+
+ if (len > 0) {
+ ASSERT(frame != NULL);
+ wlc_print_dot11hdr(frame, len);
+ }
+}
+#endif /* defined(BCMDBG) */
+
+#if defined(BCMDBG)
+int wlc_format_ssid(char *buf, const uchar ssid[], uint ssid_len)
+{
+ uint i, c;
+ char *p = buf;
+ char *endp = buf + SSID_FMT_BUF_LEN;
+
+ if (ssid_len > DOT11_MAX_SSID_LEN)
+ ssid_len = DOT11_MAX_SSID_LEN;
+
+ for (i = 0; i < ssid_len; i++) {
+ c = (uint) ssid[i];
+ if (c == '\\') {
+ *p++ = '\\';
+ *p++ = '\\';
+ } else if (bcm_isprint((uchar) c)) {
+ *p++ = (char)c;
+ } else {
+ p += snprintf(p, (endp - p), "\\x%02X", c);
+ }
+ }
+ *p = '\0';
+ ASSERT(p < endp);
+
+ return (int)(p - buf);
+}
+#endif /* defined(BCMDBG) */
+
+uint16 wlc_rate_shm_offset(wlc_info_t *wlc, uint8 rate)
+{
+ return wlc_bmac_rate_shm_offset(wlc->hw, rate);
+}
+
+/* Callback for device removed */
+#if defined(WLC_HIGH_ONLY)
+void wlc_device_removed(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+
+ wlc->device_present = FALSE;
+}
+#endif /* WLC_HIGH_ONLY */
+
+/*
+ * Attempts to queue a packet onto a multiple-precedence queue,
+ * if necessary evicting a lower precedence packet from the queue.
+ *
+ * 'prec' is the precedence number that has already been mapped
+ * from the packet priority.
+ *
+ * Returns TRUE if packet consumed (queued), FALSE if not.
+ */
+bool BCMFASTPATH
+wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec)
+{
+ return wlc_prec_enq_head(wlc, q, pkt, prec, FALSE);
+}
+
+bool BCMFASTPATH
+wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec,
+ bool head)
+{
+ void *p;
+ int eprec = -1; /* precedence to evict from */
+
+ /* Determine precedence from which to evict packet, if any */
+ if (pktq_pfull(q, prec))
+ eprec = prec;
+ else if (pktq_full(q)) {
+ p = pktq_peek_tail(q, &eprec);
+ ASSERT(p != NULL);
+ if (eprec > prec) {
+ WL_ERROR(("%s: Failing: eprec %d > prec %d\n", __func__,
+ eprec, prec));
+ return FALSE;
+ }
+ }
+
+ /* Evict if needed */
+ if (eprec >= 0) {
+ bool discard_oldest;
+
+ /* Detect queueing to unconfigured precedence */
+ ASSERT(!pktq_pempty(q, eprec));
+
+ discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
+
+ /* Refuse newer packet unless configured to discard oldest */
+ if (eprec == prec && !discard_oldest) {
+ WL_ERROR(("%s: No where to go, prec == %d\n", __func__,
+ prec));
+ return FALSE;
+ }
+
+ /* Evict packet according to discard policy */
+ p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q,
+ eprec);
+ ASSERT(p != NULL);
+
+ /* Increment wme stats */
+ if (WME_ENAB(wlc->pub)) {
+ WLCNTINCR(wlc->pub->_wme_cnt->
+ tx_failed[WME_PRIO2AC(PKTPRIO(p))].packets);
+ WLCNTADD(wlc->pub->_wme_cnt->
+ tx_failed[WME_PRIO2AC(PKTPRIO(p))].bytes,
+ pkttotlen(wlc->osh, p));
+ }
+
+ ASSERT(0);
+ PKTFREE(wlc->osh, p, TRUE);
+ WLCNTINCR(wlc->pub->_cnt->txnobuf);
+ }
+
+ /* Enqueue */
+ if (head)
+ p = pktq_penq_head(q, prec, pkt);
+ else
+ p = pktq_penq(q, prec, pkt);
+ ASSERT(p != NULL);
+
+ return TRUE;
+}
+
+void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec)
+{
+ wlc_info_t *wlc = (wlc_info_t *) ctx;
+ wlc_txq_info_t *qi = wlc->active_queue; /* Check me */
+ struct pktq *q = &qi->q;
+ int prio;
+
+ prio = PKTPRIO(sdu);
+
+ ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat);
+
+ if (!wlc_prec_enq(wlc, q, sdu, prec)) {
+ if (!EDCF_ENAB(wlc->pub)
+ || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
+ WL_ERROR(("wl%d: wlc_txq_enq: txq overflow\n",
+ wlc->pub->unit));
+
+ /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */
+ PKTFREE(wlc->osh, sdu, TRUE);
+ WLCNTINCR(wlc->pub->_cnt->txnobuf);
+ }
+
+ /* Check if flow control needs to be turned on after enqueuing the packet
+ * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
+ * to drop instead of relying on stack to make the right decision
+ */
+ if (!EDCF_ENAB(wlc->pub)
+ || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+ if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
+ wlc_txflowcontrol(wlc, qi, ON, ALLPRIO);
+ }
+ } else if (wlc->pub->_priofc) {
+ if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
+ wlc->pub->tunables->datahiwat) {
+ wlc_txflowcontrol(wlc, qi, ON, prio);
+ }
+ }
+}
+
+bool BCMFASTPATH
+wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw)
+{
+ uint8 prio;
+ uint fifo;
+ void *pkt;
+ struct scb *scb = &global_scb;
+ struct dot11_header *d11_header = (struct dot11_header *)PKTDATA(sdu);
+ uint16 type, fc;
+
+ ASSERT(sdu);
+
+ fc = ltoh16(d11_header->fc);
+ type = FC_TYPE(fc);
+
+ /* 802.11 standard requires management traffic to go at highest priority */
+ prio = (type == FC_TYPE_DATA ? PKTPRIO(sdu) : MAXPRIO);
+ fifo = prio2fifo[prio];
+
+ ASSERT((uint) PKTHEADROOM(sdu) >= TXOFF);
+ ASSERT(!PKTSHARED(sdu));
+ ASSERT(!PKTNEXT(sdu));
+ ASSERT(!PKTLINK(sdu));
+ ASSERT(fifo < NFIFO);
+
+ pkt = sdu;
+ if (unlikely
+ (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
+ return -EINVAL;
+ wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
+ wlc_send_q(wlc, wlc->active_queue);
+
+ WLCNTINCR(wlc->pub->_cnt->ieee_tx);
+ return 0;
+}
+
+void BCMFASTPATH wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi)
+{
+ void *pkt[DOT11_MAXNUMFRAGS];
+ int prec;
+ uint16 prec_map;
+ int err = 0, i, count;
+ uint fifo;
+ struct pktq *q = &qi->q;
+ struct ieee80211_tx_info *tx_info;
+
+ /* only do work for the active queue */
+ if (qi != wlc->active_queue)
+ return;
+
+ if (in_send_q)
+ return;
+ else
+ in_send_q = TRUE;
+
+ prec_map = wlc->tx_prec_map;
+
+ /* Send all the enq'd pkts that we can.
+ * Dequeue packets with precedence with empty HW fifo only
+ */
+ while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) {
+ tx_info = IEEE80211_SKB_CB(pkt[0]);
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec);
+ } else {
+ count = 1;
+ err = wlc_prep_pdu(wlc, pkt[0], &fifo);
+ if (!err) {
+ for (i = 0; i < count; i++) {
+ wlc_txfifo(wlc, fifo, pkt[i], TRUE, 1);
+ }
+ }
+ }
+
+ if (err == BCME_BUSY) {
+ pktq_penq_head(q, prec, pkt[0]);
+ /* If send failed due to any other reason than a change in
+ * HW FIFO condition, quit. Otherwise, read the new prec_map!
+ */
+ if (prec_map == wlc->tx_prec_map)
+ break;
+ prec_map = wlc->tx_prec_map;
+ }
+ }
+
+ /* Check if flow control needs to be turned off after sending the packet */
+ if (!EDCF_ENAB(wlc->pub)
+ || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+ if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
+ && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
+ wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO);
+ }
+ } else if (wlc->pub->_priofc) {
+ int prio;
+ for (prio = MAXPRIO; prio >= 0; prio--) {
+ if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) &&
+ (pktq_plen(q, wlc_prio2prec_map[prio]) <
+ wlc->pub->tunables->datahiwat / 2)) {
+ wlc_txflowcontrol(wlc, qi, OFF, prio);
+ }
+ }
+ }
+ in_send_q = FALSE;
+}
+
+/*
+ * bcmc_fid_generate:
+ * Generate frame ID for a BCMC packet. The frag field is not used
+ * for MC frames so is used as part of the sequence number.
+ */
+static INLINE uint16
+bcmc_fid_generate(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh)
+{
+ uint16 frameid;
+
+ frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK);
+ frameid |=
+ (((wlc->
+ mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+ TX_BCMC_FIFO;
+
+ return frameid;
+}
+
+void BCMFASTPATH
+wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit, int8 txpktpend)
+{
+ uint16 frameid = INVALIDFID;
+ d11txh_t *txh;
+
+ ASSERT(fifo < NFIFO);
+ txh = (d11txh_t *) PKTDATA(p);
+
+ /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
+ * ucode or BSS info as appropriate.
+ */
+ if (fifo == TX_BCMC_FIFO) {
+ frameid = ltoh16(txh->TxFrameID);
+
+ }
+
+ if (WLC_WAR16165(wlc))
+ wlc_war16165(wlc, TRUE);
+
+#ifdef WLC_HIGH_ONLY
+ if (RPCTX_ENAB(wlc->pub)) {
+ (void)wlc_rpctx_tx(wlc->rpctx, fifo, p, commit, frameid,
+ txpktpend);
+ return;
+ }
+#else
+
+ /* Bump up pending count for if not using rpc. If rpc is used, this will be handled
+ * in wlc_bmac_txfifo()
+ */
+ if (commit) {
+ TXPKTPENDINC(wlc, fifo, txpktpend);
+ WL_TRACE(("wlc_txfifo, pktpend inc %d to %d\n", txpktpend,
+ TXPKTPENDGET(wlc, fifo)));
+ }
+
+ /* Commit BCMC sequence number in the SHM frame ID location */
+ if (frameid != INVALIDFID)
+ BCMCFID(wlc, frameid);
+
+ if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
+ WL_ERROR(("wlc_txfifo: fatal, toss frames !!!\n"));
+ }
+#endif /* WLC_HIGH_ONLY */
+}
+
+static uint16
+wlc_compute_airtime(wlc_info_t *wlc, ratespec_t rspec, uint length)
+{
+ uint16 usec = 0;
+ uint mac_rate = RSPEC2RATE(rspec);
+ uint nsyms;
+
+ if (IS_MCS(rspec)) {
+ /* not supported yet */
+ ASSERT(0);
+ } else if (IS_OFDM(rspec)) {
+ /* nsyms = Ceiling(Nbits / (Nbits/sym))
+ *
+ * Nbits = length * 8
+ * Nbits/sym = Mbps * 4 = mac_rate * 2
+ */
+ nsyms = CEIL((length * 8), (mac_rate * 2));
+
+ /* usec = symbols * usec/symbol */
+ usec = (uint16) (nsyms * APHY_SYMBOL_TIME);
+ return usec;
+ } else {
+ switch (mac_rate) {
+ case WLC_RATE_1M:
+ usec = length << 3;
+ break;
+ case WLC_RATE_2M:
+ usec = length << 2;
+ break;
+ case WLC_RATE_5M5:
+ usec = (length << 4) / 11;
+ break;
+ case WLC_RATE_11M:
+ usec = (length << 3) / 11;
+ break;
+ default:
+ WL_ERROR(("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", wlc->pub->unit, rspec));
+ ASSERT((const char *)"Bad phy_rate" == NULL);
+ break;
+ }
+ }
+
+ return usec;
+}
+
+void BCMFASTPATH
+wlc_compute_plcp(wlc_info_t *wlc, ratespec_t rspec, uint length, uint8 *plcp)
+{
+ if (IS_MCS(rspec)) {
+ wlc_compute_mimo_plcp(rspec, length, plcp);
+ } else if (IS_OFDM(rspec)) {
+ wlc_compute_ofdm_plcp(rspec, length, plcp);
+ } else {
+ wlc_compute_cck_plcp(rspec, length, plcp);
+ }
+ return;
+}
+
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, uint8 *plcp)
+{
+ uint8 mcs = (uint8) (rspec & RSPEC_RATE_MASK);
+ ASSERT(IS_MCS(rspec));
+ plcp[0] = mcs;
+ if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
+ plcp[0] |= MIMO_PLCP_40MHZ;
+ WLC_SET_MIMO_PLCP_LEN(plcp, length);
+ plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */
+ plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
+ plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
+ plcp[5] = 0;
+}
+
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void BCMFASTPATH
+wlc_compute_ofdm_plcp(ratespec_t rspec, uint32 length, uint8 *plcp)
+{
+ uint8 rate_signal;
+ uint32 tmp = 0;
+ int rate = RSPEC2RATE(rspec);
+
+ ASSERT(IS_OFDM(rspec));
+
+ /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
+ rate_signal = rate_info[rate] & RATE_MASK;
+ ASSERT(rate_signal != 0);
+
+ bzero(plcp, D11_PHY_HDR_LEN);
+ D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal);
+
+ tmp = (length & 0xfff) << 5;
+ plcp[2] |= (tmp >> 16) & 0xff;
+ plcp[1] |= (tmp >> 8) & 0xff;
+ plcp[0] |= tmp & 0xff;
+
+ return;
+}
+
+/*
+ * Compute PLCP, but only requires actual rate and length of pkt.
+ * Rate is given in the driver standard multiple of 500 kbps.
+ * le is set for 11 Mbps rate if necessary.
+ * Broken out for PRQ.
+ */
+
+static void wlc_cck_plcp_set(int rate_500, uint length, uint8 *plcp)
+{
+ uint16 usec = 0;
+ uint8 le = 0;
+
+ switch (rate_500) {
+ case WLC_RATE_1M:
+ usec = length << 3;
+ break;
+ case WLC_RATE_2M:
+ usec = length << 2;
+ break;
+ case WLC_RATE_5M5:
+ usec = (length << 4) / 11;
+ if ((length << 4) - (usec * 11) > 0)
+ usec++;
+ break;
+ case WLC_RATE_11M:
+ usec = (length << 3) / 11;
+ if ((length << 3) - (usec * 11) > 0) {
+ usec++;
+ if ((usec * 11) - (length << 3) >= 8)
+ le = D11B_PLCP_SIGNAL_LE;
+ }
+ break;
+
+ default:
+ WL_ERROR(("wlc_cck_plcp_set: unsupported rate %d\n", rate_500));
+ rate_500 = WLC_RATE_1M;
+ usec = length << 3;
+ break;
+ }
+ /* PLCP signal byte */
+ plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
+ /* PLCP service byte */
+ plcp[1] = (uint8) (le | D11B_PLCP_SIGNAL_LOCKED);
+ /* PLCP length uint16, little endian */
+ plcp[2] = usec & 0xff;
+ plcp[3] = (usec >> 8) & 0xff;
+ /* PLCP CRC16 */
+ plcp[4] = 0;
+ plcp[5] = 0;
+}
+
+/* Rate: 802.11 rate code, length: PSDU length in octets */
+static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, uint8 *plcp)
+{
+ int rate = RSPEC2RATE(rspec);
+
+ ASSERT(IS_CCK(rspec));
+
+ wlc_cck_plcp_set(rate, length, plcp);
+}
+
+/* wlc_compute_frame_dur()
+ *
+ * Calculate the 802.11 MAC header DUR field for MPDU
+ * DUR for a single frame = 1 SIFS + 1 ACK
+ * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
+ *
+ * rate MPDU rate in unit of 500kbps
+ * next_frag_len next MPDU length in bytes
+ * preamble_type use short/GF or long/MM PLCP header
+ */
+static uint16 BCMFASTPATH
+wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, uint8 preamble_type,
+ uint next_frag_len)
+{
+ uint16 dur, sifs;
+
+ sifs = SIFS(wlc->band);
+
+ dur = sifs;
+ dur += (uint16) wlc_calc_ack_time(wlc, rate, preamble_type);
+
+ if (next_frag_len) {
+ /* Double the current DUR to get 2 SIFS + 2 ACKs */
+ dur *= 2;
+ /* add another SIFS and the frag time */
+ dur += sifs;
+ dur +=
+ (uint16) wlc_calc_frame_time(wlc, rate, preamble_type,
+ next_frag_len);
+ }
+ return dur;
+}
+
+/* wlc_compute_rtscts_dur()
+ *
+ * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
+ * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
+ * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
+ *
+ * cts cts-to-self or rts/cts
+ * rts_rate rts or cts rate in unit of 500kbps
+ * rate next MPDU rate in unit of 500kbps
+ * frame_len next MPDU frame length in bytes
+ */
+uint16 BCMFASTPATH
+wlc_compute_rtscts_dur(wlc_info_t *wlc, bool cts_only, ratespec_t rts_rate,
+ ratespec_t frame_rate, uint8 rts_preamble_type,
+ uint8 frame_preamble_type, uint frame_len, bool ba)
+{
+ uint16 dur, sifs;
+
+ sifs = SIFS(wlc->band);
+
+ if (!cts_only) { /* RTS/CTS */
+ dur = 3 * sifs;
+ dur +=
+ (uint16) wlc_calc_cts_time(wlc, rts_rate,
+ rts_preamble_type);
+ } else { /* CTS-TO-SELF */
+ dur = 2 * sifs;
+ }
+
+ dur +=
+ (uint16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type,
+ frame_len);
+ if (ba)
+ dur +=
+ (uint16) wlc_calc_ba_time(wlc, frame_rate,
+ WLC_SHORT_PREAMBLE);
+ else
+ dur +=
+ (uint16) wlc_calc_ack_time(wlc, frame_rate,
+ frame_preamble_type);
+ return dur;
+}
+
+static bool wlc_phy_rspec_check(wlc_info_t *wlc, uint16 bw, ratespec_t rspec)
+{
+ if (IS_MCS(rspec)) {
+ uint mcs = rspec & RSPEC_RATE_MASK;
+
+ if (mcs < 8) {
+ ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
+ } else if ((mcs >= 8) && (mcs <= 23)) {
+ ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM);
+ } else if (mcs == 32) {
+ ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
+ ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP);
+ }
+ } else if (IS_OFDM(rspec)) {
+ ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC);
+ } else {
+ ASSERT(IS_CCK(rspec));
+
+ ASSERT((bw == PHY_TXC1_BW_20MHZ)
+ || (bw == PHY_TXC1_BW_20MHZ_UP));
+ ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO);
+ }
+
+ return TRUE;
+}
+
+uint16 BCMFASTPATH wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec)
+{
+ uint16 phyctl1 = 0;
+ uint16 bw;
+
+ if (WLCISLCNPHY(wlc->band)) {
+ bw = PHY_TXC1_BW_20MHZ;
+ } else {
+ bw = RSPEC_GET_BW(rspec);
+ /* 10Mhz is not supported yet */
+ if (bw < PHY_TXC1_BW_20MHZ) {
+ WL_ERROR(("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", bw));
+ bw = PHY_TXC1_BW_20MHZ;
+ }
+
+ wlc_phy_rspec_check(wlc, bw, rspec);
+ }
+
+ if (IS_MCS(rspec)) {
+ uint mcs = rspec & RSPEC_RATE_MASK;
+
+ /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
+ phyctl1 = RSPEC_PHYTXBYTE2(rspec);
+ /* set the upper byte of phyctl1 */
+ phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
+ } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band)
+ && !WLCISSSLPNPHY(wlc->band)) {
+ /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+ /* Eventually MIMOPHY would also be converted to this format */
+ /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+ phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+ } else { /* legacy OFDM/CCK */
+ int16 phycfg;
+ /* get the phyctl byte from rate phycfg table */
+ phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec));
+ if (phycfg == -1) {
+ WL_ERROR(("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"));
+ ASSERT(0);
+ phycfg = 0;
+ }
+ /* set the upper byte of phyctl1 */
+ phyctl1 =
+ (bw | (phycfg << 8) |
+ (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+ }
+
+#ifdef BCMDBG
+ /* phy clock must support 40Mhz if tx descriptor uses it */
+ if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) {
+ ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ);
+#ifndef WLC_HIGH_ONLY
+ ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi));
+#endif
+ }
+#endif /* BCMDBG */
+ return phyctl1;
+}
+
+ratespec_t BCMFASTPATH
+wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec, bool use_rspec,
+ uint16 mimo_ctlchbw)
+{
+ ratespec_t rts_rspec = 0;
+
+ if (use_rspec) {
+ /* use frame rate as rts rate */
+ rts_rspec = rspec;
+
+ } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
+ /* Use 11Mbps as the g protection RTS target rate and fallback.
+ * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the
+ * target in case 11 Mbps is not Basic.
+ * 6 and 9 Mbps are not usually selected by rate selection, but even
+ * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
+ */
+ rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M);
+ } else {
+ /* calculate RTS rate and fallback rate based on the frame rate
+ * RTS must be sent at a basic rate since it is a
+ * control frame, sec 9.6 of 802.11 spec
+ */
+ rts_rspec = WLC_BASIC_RATE(wlc, rspec);
+ }
+
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ /* set rts txbw to correct side band */
+ rts_rspec &= ~RSPEC_BW_MASK;
+
+ /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
+ * (DUP), otherwise send RTS on control channel
+ */
+ if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
+ rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
+ else
+ rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+
+ /* pick siso/cdd as default for ofdm */
+ if (IS_OFDM(rts_rspec)) {
+ rts_rspec &= ~RSPEC_STF_MASK;
+ rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+ }
+ }
+ return rts_rspec;
+}
+
+/*
+ * Add d11txh_t, cck_phy_hdr_t.
+ *
+ * 'p' data must start with 802.11 MAC header
+ * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
+ *
+ * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
+ *
+ */
+static uint16 BCMFASTPATH
+wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw,
+ void *p, struct scb *scb, uint frag,
+ uint nfrags, uint queue, uint next_frag_len,
+ wsec_key_t *key, ratespec_t rspec_override)
+{
+ struct dot11_header *h;
+ d11txh_t *txh;
+ uint8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
+ osl_t *osh;
+ int len, phylen, rts_phylen;
+ uint16 fc, type, frameid, mch, phyctl, xfts, mainrates;
+ uint16 seq = 0, mcl = 0, status = 0;
+ ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = {
+ WLC_RATE_1M, WLC_RATE_1M};
+ bool use_rts = FALSE;
+ bool use_cts = FALSE;
+ bool use_rifs = FALSE;
+ bool short_preamble[2] = { FALSE, FALSE };
+ uint8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+ uint8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+ uint8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
+ struct dot11_rts_frame *rts = NULL;
+ bool qos;
+ uint ac;
+ uint32 rate_val[2];
+ bool hwtkmic = FALSE;
+ uint16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+#ifdef WLANTSEL
+#define ANTCFG_NONE 0xFF
+ uint8 antcfg = ANTCFG_NONE;
+ uint8 fbantcfg = ANTCFG_NONE;
+#endif
+ uint phyctl1_stf = 0;
+ uint16 durid = 0;
+ struct ieee80211_tx_rate *txrate[2];
+ int k;
+ struct ieee80211_tx_info *tx_info;
+ bool is_mcs[2];
+ uint16 mimo_txbw;
+ uint8 mimo_preamble_type;
+
+ frameid = 0;
+
+ ASSERT(queue < NFIFO);
+
+ osh = wlc->osh;
+
+ /* locate 802.11 MAC header */
+ h = (struct dot11_header *)PKTDATA(p);
+ fc = ltoh16(h->fc);
+ type = FC_TYPE(fc);
+
+ qos = (type == FC_TYPE_DATA && FC_SUBTYPE_ANY_QOS(FC_SUBTYPE(fc)));
+
+ /* compute length of frame in bytes for use in PLCP computations */
+ len = pkttotlen(osh, p);
+ phylen = len + DOT11_FCS_LEN;
+
+ /* If WEP enabled, add room in phylen for the additional bytes of
+ * ICV which MAC generates. We do NOT add the additional bytes to
+ * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
+ * in this case
+ */
+ if (key) {
+ phylen += key->icv_len;
+ }
+
+ /* Get tx_info */
+ tx_info = IEEE80211_SKB_CB(p);
+ ASSERT(tx_info);
+
+ /* add PLCP */
+ plcp = PKTPUSH(p, D11_PHY_HDR_LEN);
+
+ /* add Broadcom tx descriptor header */
+ txh = (d11txh_t *) PKTPUSH(p, D11_TXH_LEN);
+ bzero((char *)txh, D11_TXH_LEN);
+
+ /* setup frameid */
+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ /* non-AP STA should never use BCMC queue */
+ ASSERT(queue != TX_BCMC_FIFO);
+ if (queue == TX_BCMC_FIFO) {
+ WL_ERROR(("wl%d: %s: ASSERT queue == TX_BCMC!\n",
+ WLCWLUNIT(wlc), __func__));
+ frameid = bcmc_fid_generate(wlc, NULL, txh);
+ } else {
+ /* Increment the counter for first fragment */
+ if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+ SCB_SEQNUM(scb, PKTPRIO(p))++;
+ }
+
+ /* extract fragment number from frame first */
+ seq = ltoh16(seq) & FRAGNUM_MASK;
+ seq |= (SCB_SEQNUM(scb, PKTPRIO(p)) << SEQNUM_SHIFT);
+ h->seq = htol16(seq);
+
+ frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+ (queue & TXFID_QUEUE_MASK);
+ }
+ }
+ frameid |= queue & TXFID_QUEUE_MASK;
+
+ /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
+ if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON))
+ mcl |= TXC_IGNOREPMQ;
+
+ ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES);
+ ASSERT(hw->max_rates == 2);
+
+ txrate[0] = tx_info->control.rates;
+ txrate[1] = txrate[0] + 1;
+
+ ASSERT(txrate[0]->idx >= 0);
+ /* if rate control algorithm didn't give us a fallback rate, use the primary rate */
+ if (txrate[1]->idx < 0) {
+ txrate[1] = txrate[0];
+ }
+#ifdef WLC_HIGH_ONLY
+ /* Double protection , just in case */
+ if (txrate[0]->idx > HIGHEST_SINGLE_STREAM_MCS)
+ txrate[0]->idx = HIGHEST_SINGLE_STREAM_MCS;
+ if (txrate[1]->idx > HIGHEST_SINGLE_STREAM_MCS)
+ txrate[1]->idx = HIGHEST_SINGLE_STREAM_MCS;
+#endif
+
+ for (k = 0; k < hw->max_rates; k++) {
+ is_mcs[k] =
+ txrate[k]->flags & IEEE80211_TX_RC_MCS ? TRUE : FALSE;
+ if (!is_mcs[k]) {
+ ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU));
+ if ((txrate[k]->idx >= 0)
+ && (txrate[k]->idx <
+ hw->wiphy->bands[tx_info->band]->n_bitrates)) {
+ rate_val[k] =
+ hw->wiphy->bands[tx_info->band]->
+ bitrates[txrate[k]->idx].hw_value;
+ short_preamble[k] =
+ txrate[k]->
+ flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
+ TRUE : FALSE;
+ } else {
+ ASSERT((txrate[k]->idx >= 0) &&
+ (txrate[k]->idx <
+ hw->wiphy->bands[tx_info->band]->
+ n_bitrates));
+ rate_val[k] = WLC_RATE_1M;
+ }
+ } else {
+ rate_val[k] = txrate[k]->idx;
+ }
+ /* Currently only support same setting for primay and fallback rates.
+ * Unify flags for each rate into a single value for the frame
+ */
+ use_rts |=
+ txrate[k]->
+ flags & IEEE80211_TX_RC_USE_RTS_CTS ? TRUE : FALSE;
+ use_cts |=
+ txrate[k]->
+ flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? TRUE : FALSE;
+
+ if (is_mcs[k])
+ rate_val[k] |= NRATE_MCS_INUSE;
+
+ rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);
+
+ /* (1) RATE: determine and validate primary rate and fallback rates */
+ if (!RSPEC_ACTIVE(rspec[k])) {
+ ASSERT(RSPEC_ACTIVE(rspec[k]));
+ rspec[k] = WLC_RATE_1M;
+ } else {
+ if (WLANTSEL_ENAB(wlc) && !ETHER_ISMULTI(&h->a1)) {
+ /* set tx antenna config */
+ wlc_antsel_antcfg_get(wlc->asi, FALSE, FALSE, 0,
+ 0, &antcfg, &fbantcfg);
+ }
+ }
+ }
+
+ phyctl1_stf = wlc->stf->ss_opmode;
+
+ if (N_ENAB(wlc->pub)) {
+ for (k = 0; k < hw->max_rates; k++) {
+ /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
+ if (((IS_MCS(rspec[k]) &&
+ IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
+ IS_OFDM(rspec[k]))
+ && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
+ || !(rspec[k] & RSPEC_OVERRIDE))) {
+ rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
+
+ /* For SISO MCS use STBC if possible */
+ if (IS_MCS(rspec[k])
+ && WLC_STF_SS_STBC_TX(wlc, scb)) {
+ uint8 stc;
+
+ ASSERT(WLC_STBC_CAP_PHY(wlc));
+ stc = 1; /* Nss for single stream is always 1 */
+ rspec[k] |=
+ (PHY_TXC1_MODE_STBC <<
+ RSPEC_STF_SHIFT) | (stc <<
+ RSPEC_STC_SHIFT);
+ } else
+ rspec[k] |=
+ (phyctl1_stf << RSPEC_STF_SHIFT);
+ }
+
+ /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
+ if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) {
+ /* default txbw is 20in40 SB */
+ mimo_ctlchbw = mimo_txbw =
+ CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+ ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+
+ if (IS_MCS(rspec[k])) {
+ /* mcs 32 must be 40b/w DUP */
+ if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+ mimo_txbw =
+ PHY_TXC1_BW_40MHZ_DUP;
+ /* use override */
+ } else if (wlc->mimo_40txbw != AUTO)
+ mimo_txbw = wlc->mimo_40txbw;
+ /* else check if dst is using 40 Mhz */
+ else if (scb->flags & SCB_IS40)
+ mimo_txbw = PHY_TXC1_BW_40MHZ;
+ } else if (IS_OFDM(rspec[k])) {
+ if (wlc->ofdm_40txbw != AUTO)
+ mimo_txbw = wlc->ofdm_40txbw;
+ } else {
+ ASSERT(IS_CCK(rspec[k]));
+ if (wlc->cck_40txbw != AUTO)
+ mimo_txbw = wlc->cck_40txbw;
+ }
+ } else {
+ /* mcs32 is 40 b/w only.
+ * This is possible for probe packets on a STA during SCAN
+ */
+ if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+ /* mcs 0 */
+ rspec[k] = RSPEC_MIMORATE;
+ }
+ mimo_txbw = PHY_TXC1_BW_20MHZ;
+ }
+
+ /* Set channel width */
+ rspec[k] &= ~RSPEC_BW_MASK;
+ if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
+ rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
+ else
+ rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+
+ /* Set Short GI */
+#ifdef NOSGIYET
+ if (IS_MCS(rspec[k])
+ && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+ rspec[k] |= RSPEC_SHORT_GI;
+ else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+ rspec[k] &= ~RSPEC_SHORT_GI;
+#else
+ rspec[k] &= ~RSPEC_SHORT_GI;
+#endif
+
+ mimo_preamble_type = WLC_MM_PREAMBLE;
+ if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ mimo_preamble_type = WLC_GF_PREAMBLE;
+
+ if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
+ && (!IS_MCS(rspec[k]))) {
+ WL_ERROR(("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", WLCWLUNIT(wlc), __func__));
+ ASSERT(0 && "Rate mismatch");
+ }
+
+ if (IS_MCS(rspec[k])) {
+ preamble_type[k] = mimo_preamble_type;
+
+ /* if SGI is selected, then forced mm for single stream */
+ if ((rspec[k] & RSPEC_SHORT_GI)
+ && IS_SINGLE_STREAM(rspec[k] &
+ RSPEC_RATE_MASK)) {
+ preamble_type[k] = WLC_MM_PREAMBLE;
+ }
+ }
+
+ /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */
+ ASSERT(VALID_RATE_DBG(wlc, rspec[0]));
+
+ /* should be better conditionalized */
+ if (!IS_MCS(rspec[0])
+ && (tx_info->control.rates[0].
+ flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
+ preamble_type[k] = WLC_SHORT_PREAMBLE;
+
+ ASSERT(!IS_MCS(rspec[0])
+ || WLC_IS_MIMO_PREAMBLE(preamble_type[k]));
+ }
+ } else {
+ for (k = 0; k < hw->max_rates; k++) {
+ /* Set ctrlchbw as 20Mhz */
+ ASSERT(!IS_MCS(rspec[k]));
+ rspec[k] &= ~RSPEC_BW_MASK;
+ rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
+
+ /* for nphy, stf of ofdm frames must follow policies */
+ if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
+ rspec[k] &= ~RSPEC_STF_MASK;
+ rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
+ }
+ }
+ }
+
+ /* Reset these for use with AMPDU's */
+ txrate[0]->count = 0;
+ txrate[1]->count = 0;
+
+ /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */
+ wlc_compute_plcp(wlc, rspec[0], phylen, plcp);
+ wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
+ bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback,
+ sizeof(txh->FragPLCPFallback));
+
+ /* Length field now put in CCK FBR CRC field */
+ if (IS_CCK(rspec[1])) {
+ txh->FragPLCPFallback[4] = phylen & 0xff;
+ txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
+ }
+
+ /* MIMO-RATE: need validation ?? */
+ mainrates =
+ IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) :
+ plcp[0];
+
+ /* DUR field for main rate */
+ if ((fc != FC_PS_POLL) && !ETHER_ISMULTI(&h->a1) && !use_rifs) {
+ durid =
+ wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0],
+ next_frag_len);
+ h->durid = htol16(durid);
+ } else if (use_rifs) {
+ /* NAV protect to end of next max packet size */
+ durid =
+ (uint16) wlc_calc_frame_time(wlc, rspec[0],
+ preamble_type[0],
+ DOT11_MAX_FRAG_LEN);
+ durid += RIFS_11N_TIME;
+ h->durid = htol16(durid);
+ }
+
+ /* DUR field for fallback rate */
+ if (fc == FC_PS_POLL)
+ txh->FragDurFallback = h->durid;
+ else if (ETHER_ISMULTI(&h->a1) || use_rifs)
+ txh->FragDurFallback = 0;
+ else {
+ durid = wlc_compute_frame_dur(wlc, rspec[1],
+ preamble_type[1], next_frag_len);
+ txh->FragDurFallback = htol16(durid);
+ }
+
+ /* (4) MAC-HDR: MacTxControlLow */
+ if (frag == 0)
+ mcl |= TXC_STARTMSDU;
+
+ if (!ETHER_ISMULTI(&h->a1))
+ mcl |= TXC_IMMEDACK;
+
+ if (BAND_5G(wlc->band->bandtype))
+ mcl |= TXC_FREQBAND_5G;
+
+ if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC))
+ mcl |= TXC_BW_40;
+
+ /* set AMIC bit if using hardware TKIP MIC */
+ if (hwtkmic)
+ mcl |= TXC_AMIC;
+
+ txh->MacTxControlLow = htol16(mcl);
+
+ /* MacTxControlHigh */
+ mch = 0;
+
+ /* Set fallback rate preamble type */
+ if ((preamble_type[1] == WLC_SHORT_PREAMBLE) ||
+ (preamble_type[1] == WLC_GF_PREAMBLE)) {
+ ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) ||
+ (!IS_MCS(rspec[1])));
+ if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M)
+ mch |= TXC_PREAMBLE_DATA_FB_SHORT;
+ }
+
+ /* MacFrameControl */
+ bcopy((char *)&h->fc, (char *)&txh->MacFrameControl, sizeof(uint16));
+
+ txh->TxFesTimeNormal = htol16(0);
+
+ txh->TxFesTimeFallback = htol16(0);
+
+ /* TxFrameRA */
+ bcopy((char *)&h->a1, (char *)&txh->TxFrameRA, ETHER_ADDR_LEN);
+
+ /* TxFrameID */
+ txh->TxFrameID = htol16(frameid);
+
+ /* TxStatus, Note the case of recreating the first frag of a suppressed frame
+ * then we may need to reset the retry cnt's via the status reg
+ */
+ txh->TxStatus = htol16(status);
+
+ if (D11REV_GE(wlc->pub->corerev, 16)) {
+ /* extra fields for ucode AMPDU aggregation, the new fields are added to
+ * the END of previous structure so that it's compatible in driver.
+ * In old rev ucode, these fields should be ignored
+ */
+ txh->MaxNMpdus = htol16(0);
+ txh->MaxABytes_MRT = htol16(0);
+ txh->MaxABytes_FBR = htol16(0);
+ txh->MinMBytes = htol16(0);
+ }
+
+ /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */
+ /* RTS PLCP header and RTS frame */
+ if (use_rts || use_cts) {
+ if (use_rts && use_cts)
+ use_cts = FALSE;
+
+ for (k = 0; k < 2; k++) {
+ rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k],
+ FALSE,
+ mimo_ctlchbw);
+ }
+
+ if (!IS_OFDM(rts_rspec[0]) &&
+ !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) ||
+ (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+ rts_preamble_type[0] = WLC_SHORT_PREAMBLE;
+ mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
+ }
+
+ if (!IS_OFDM(rts_rspec[1]) &&
+ !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) ||
+ (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+ rts_preamble_type[1] = WLC_SHORT_PREAMBLE;
+ mch |= TXC_PREAMBLE_RTS_FB_SHORT;
+ }
+
+ /* RTS/CTS additions to MacTxControlLow */
+ if (use_cts) {
+ txh->MacTxControlLow |= htol16(TXC_SENDCTS);
+ } else {
+ txh->MacTxControlLow |= htol16(TXC_SENDRTS);
+ txh->MacTxControlLow |= htol16(TXC_LONGFRAME);
+ }
+
+ /* RTS PLCP header */
+ ASSERT(ISALIGNED((uintptr) txh->RTSPhyHeader, sizeof(uint16)));
+ rts_plcp = txh->RTSPhyHeader;
+ if (use_cts)
+ rts_phylen = DOT11_CTS_LEN + DOT11_FCS_LEN;
+ else
+ rts_phylen = DOT11_RTS_LEN + DOT11_FCS_LEN;
+
+ wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
+
+ /* fallback rate version of RTS PLCP header */
+ wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen,
+ rts_plcp_fallback);
+ bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback,
+ sizeof(txh->RTSPLCPFallback));
+
+ /* RTS frame fields... */
+ rts = (struct dot11_rts_frame *)&txh->rts_frame;
+
+ durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
+ rspec[0], rts_preamble_type[0],
+ preamble_type[0], phylen, FALSE);
+ rts->durid = htol16(durid);
+ /* fallback rate version of RTS DUR field */
+ durid = wlc_compute_rtscts_dur(wlc, use_cts,
+ rts_rspec[1], rspec[1],
+ rts_preamble_type[1],
+ preamble_type[1], phylen, FALSE);
+ txh->RTSDurFallback = htol16(durid);
+
+ if (use_cts) {
+ rts->fc = htol16(FC_CTS);
+ bcopy((char *)&h->a2, (char *)&rts->ra, ETHER_ADDR_LEN);
+ } else {
+ rts->fc = htol16((uint16) FC_RTS);
+ bcopy((char *)&h->a1, (char *)&rts->ra,
+ 2 * ETHER_ADDR_LEN);
+ }
+
+ /* mainrate
+ * low 8 bits: main frag rate/mcs,
+ * high 8 bits: rts/cts rate/mcs
+ */
+ mainrates |= (IS_OFDM(rts_rspec[0]) ?
+ D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) :
+ rts_plcp[0]) << 8;
+ } else {
+ bzero((char *)txh->RTSPhyHeader, D11_PHY_HDR_LEN);
+ bzero((char *)&txh->rts_frame, sizeof(struct dot11_rts_frame));
+ bzero((char *)txh->RTSPLCPFallback,
+ sizeof(txh->RTSPLCPFallback));
+ txh->RTSDurFallback = 0;
+ }
+
+#ifdef SUPPORT_40MHZ
+ /* add null delimiter count */
+ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
+ txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
+ wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
+ }
+#endif
+
+ /* Now that RTS/RTS FB preamble types are updated, write the final value */
+ txh->MacTxControlHigh = htol16(mch);
+
+ /* MainRates (both the rts and frag plcp rates have been calculated now) */
+ txh->MainRates = htol16(mainrates);
+
+ /* XtraFrameTypes */
+ xfts = FRAMETYPE(rspec[1], wlc->mimoft);
+ xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
+ xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
+ xfts |=
+ CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
+ txh->XtraFrameTypes = htol16(xfts);
+
+ /* PhyTxControlWord */
+ phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
+ if ((preamble_type[0] == WLC_SHORT_PREAMBLE) ||
+ (preamble_type[0] == WLC_GF_PREAMBLE)) {
+ ASSERT((preamble_type[0] == WLC_GF_PREAMBLE)
+ || !IS_MCS(rspec[0]));
+ if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
+ phyctl |= PHY_TXC_SHORT_HDR;
+ WLCNTINCR(wlc->pub->_cnt->txprshort);
+ }
+
+ /* phytxant is properly bit shifted */
+ phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
+ txh->PhyTxControlWord = htol16(phyctl);
+
+ /* PhyTxControlWord_1 */
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ uint16 phyctl1 = 0;
+
+ phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]);
+ txh->PhyTxControlWord_1 = htol16(phyctl1);
+ phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]);
+ txh->PhyTxControlWord_1_Fbr = htol16(phyctl1);
+
+ if (use_rts || use_cts) {
+ phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]);
+ txh->PhyTxControlWord_1_Rts = htol16(phyctl1);
+ phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]);
+ txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1);
+ }
+
+ /*
+ * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
+ * fill in non-zero MModeLen and/or MModeFbrLen
+ * it will be unnecessary if they are separated
+ */
+ if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) {
+ uint16 mmodelen =
+ wlc_calc_lsig_len(wlc, rspec[0], phylen);
+ txh->MModeLen = htol16(mmodelen);
+ }
+
+ if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) {
+ uint16 mmodefbrlen =
+ wlc_calc_lsig_len(wlc, rspec[1], phylen);
+ txh->MModeFbrLen = htol16(mmodefbrlen);
+ }
+ }
+
+ if (IS_MCS(rspec[0]))
+ ASSERT(IS_MCS(rspec[1]));
+
+ ASSERT(!IS_MCS(rspec[0]) ||
+ ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0)));
+ ASSERT(!IS_MCS(rspec[1]) ||
+ ((preamble_type[1] == WLC_MM_PREAMBLE) ==
+ (txh->MModeFbrLen != 0)));
+
+ ac = wme_fifo2ac[queue];
+ if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
+ uint frag_dur, dur, dur_fallback;
+
+ ASSERT(!ETHER_ISMULTI(&h->a1));
+
+ /* WME: Update TXOP threshold */
+ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
+ frag_dur =
+ wlc_calc_frame_time(wlc, rspec[0], preamble_type[0],
+ phylen);
+
+ if (rts) {
+ /* 1 RTS or CTS-to-self frame */
+ dur =
+ wlc_calc_cts_time(wlc, rts_rspec[0],
+ rts_preamble_type[0]);
+ dur_fallback =
+ wlc_calc_cts_time(wlc, rts_rspec[1],
+ rts_preamble_type[1]);
+ /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
+ dur += ltoh16(rts->durid);
+ dur_fallback += ltoh16(txh->RTSDurFallback);
+ } else if (use_rifs) {
+ dur = frag_dur;
+ dur_fallback = 0;
+ } else {
+ /* frame + SIFS + ACK */
+ dur = frag_dur;
+ dur +=
+ wlc_compute_frame_dur(wlc, rspec[0],
+ preamble_type[0], 0);
+
+ dur_fallback =
+ wlc_calc_frame_time(wlc, rspec[1],
+ preamble_type[1],
+ phylen);
+ dur_fallback +=
+ wlc_compute_frame_dur(wlc, rspec[1],
+ preamble_type[1], 0);
+ }
+ /* NEED to set TxFesTimeNormal (hard) */
+ txh->TxFesTimeNormal = htol16((uint16) dur);
+ /* NEED to set fallback rate version of TxFesTimeNormal (hard) */
+ txh->TxFesTimeFallback = htol16((uint16) dur_fallback);
+
+ /* update txop byte threshold (txop minus intraframe overhead) */
+ if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
+ {
+ uint newfragthresh;
+
+ newfragthresh =
+ wlc_calc_frame_len(wlc, rspec[0],
+ preamble_type[0],
+ (wlc->
+ edcf_txop[ac] -
+ (dur -
+ frag_dur)));
+ /* range bound the fragthreshold */
+ if (newfragthresh < DOT11_MIN_FRAG_LEN)
+ newfragthresh =
+ DOT11_MIN_FRAG_LEN;
+ else if (newfragthresh >
+ wlc->usr_fragthresh)
+ newfragthresh =
+ wlc->usr_fragthresh;
+ /* update the fragthresh and do txc update */
+ if (wlc->fragthresh[queue] !=
+ (uint16) newfragthresh) {
+ wlc->fragthresh[queue] =
+ (uint16) newfragthresh;
+ }
+ }
+ } else
+ WL_ERROR(("wl%d: %s txop invalid for rate %d\n",
+ wlc->pub->unit, fifo_names[queue],
+ RSPEC2RATE(rspec[0])));
+
+ if (dur > wlc->edcf_txop[ac])
+ WL_ERROR(("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", wlc->pub->unit, __func__, fifo_names[queue], phylen, wlc->fragthresh[queue], dur, wlc->edcf_txop[ac]));
+ }
+ }
+
+ return 0;
+}
+
+void wlc_tbtt(wlc_info_t *wlc, d11regs_t *regs)
+{
+ wlc_bsscfg_t *cfg = wlc->cfg;
+
+ WLCNTINCR(wlc->pub->_cnt->tbtt);
+
+ if (BSSCFG_STA(cfg)) {
+ /* run watchdog here if the watchdog timer is not armed */
+ if (WLC_WATCHDOG_TBTT(wlc)) {
+ uint32 cur, delta;
+ if (wlc->WDarmed) {
+ wl_del_timer(wlc->wl, wlc->wdtimer);
+ wlc->WDarmed = FALSE;
+ }
+
+ cur = OSL_SYSUPTIME();
+ delta = cur > wlc->WDlast ? cur - wlc->WDlast :
+ (uint32) ~0 - wlc->WDlast + cur + 1;
+ if (delta >= TIMER_INTERVAL_WATCHDOG) {
+ wlc_watchdog((void *)wlc);
+ wlc->WDlast = cur;
+ }
+
+ wl_add_timer(wlc->wl, wlc->wdtimer,
+ wlc_watchdog_backup_bi(wlc), TRUE);
+ wlc->WDarmed = TRUE;
+ }
+ }
+
+ if (!cfg->BSS) {
+ /* DirFrmQ is now valid...defer setting until end of ATIM window */
+ wlc->qvalid |= MCMD_DIRFRMQVAL;
+ }
+}
+
+/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */
+void wlc_hwtimer_gptimer_set(wlc_info_t *wlc, uint us)
+{
+ ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */
+ W_REG(wlc->osh, &wlc->regs->gptimer, us);
+}
+
+void wlc_hwtimer_gptimer_abort(wlc_info_t *wlc)
+{
+ ASSERT(wlc->pub->corerev >= 3);
+ W_REG(wlc->osh, &wlc->regs->gptimer, 0);
+}
+
+static void wlc_hwtimer_gptimer_cb(wlc_info_t *wlc)
+{
+ /* when interrupt is generated, the counter is loaded with last value
+ * written and continue to decrement. So it has to be cleaned first
+ */
+ W_REG(wlc->osh, &wlc->regs->gptimer, 0);
+}
+
+/*
+ * This fn has all the high level dpc processing from wlc_dpc.
+ * POLICY: no macinstatus change, no bounding loop.
+ * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint
+ */
+void wlc_high_dpc(wlc_info_t *wlc, uint32 macintstatus)
+{
+ d11regs_t *regs = wlc->regs;
+#ifdef BCMDBG
+ char flagstr[128];
+ static const bcm_bit_desc_t int_flags[] = {
+ {MI_MACSSPNDD, "MACSSPNDD"},
+ {MI_BCNTPL, "BCNTPL"},
+ {MI_TBTT, "TBTT"},
+ {MI_BCNSUCCESS, "BCNSUCCESS"},
+ {MI_BCNCANCLD, "BCNCANCLD"},
+ {MI_ATIMWINEND, "ATIMWINEND"},
+ {MI_PMQ, "PMQ"},
+ {MI_NSPECGEN_0, "NSPECGEN_0"},
+ {MI_NSPECGEN_1, "NSPECGEN_1"},
+ {MI_MACTXERR, "MACTXERR"},
+ {MI_NSPECGEN_3, "NSPECGEN_3"},
+ {MI_PHYTXERR, "PHYTXERR"},
+ {MI_PME, "PME"},
+ {MI_GP0, "GP0"},
+ {MI_GP1, "GP1"},
+ {MI_DMAINT, "DMAINT"},
+ {MI_TXSTOP, "TXSTOP"},
+ {MI_CCA, "CCA"},
+ {MI_BG_NOISE, "BG_NOISE"},
+ {MI_DTIM_TBTT, "DTIM_TBTT"},
+ {MI_PRQ, "PRQ"},
+ {MI_PWRUP, "PWRUP"},
+ {MI_RFDISABLE, "RFDISABLE"},
+ {MI_TFS, "TFS"},
+ {MI_PHYCHANGED, "PHYCHANGED"},
+ {MI_TO, "TO"},
+ {0, NULL}
+ };
+
+ if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) {
+ bcm_format_flags(int_flags, macintstatus, flagstr,
+ sizeof(flagstr));
+ WL_TRACE(("wl%d: macintstatus 0x%x %s\n", wlc->pub->unit,
+ macintstatus, flagstr));
+ }
+#endif /* BCMDBG */
+
+ if (macintstatus & MI_PRQ) {
+ /* Process probe request FIFO */
+ ASSERT(0 && "PRQ Interrupt in non-MBSS");
+ }
+
+ /* TBTT indication */
+ /* ucode only gives either TBTT or DTIM_TBTT, not both */
+ if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
+ wlc_tbtt(wlc, regs);
+
+ if (macintstatus & MI_GP0) {
+ WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc->pub->unit, wlc->pub->now));
+
+ printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
+ __func__, CHIPID(wlc->pub->sih->chip),
+ CHIPREV(wlc->pub->sih->chiprev));
+
+ WLCNTINCR(wlc->pub->_cnt->psmwds);
+
+ /* big hammer */
+ wl_init(wlc->wl);
+ }
+
+ /* gptimer timeout */
+ if (macintstatus & MI_TO) {
+ wlc_hwtimer_gptimer_cb(wlc);
+ }
+
+ if (macintstatus & MI_RFDISABLE) {
+ WL_ERROR(("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", wlc->pub->unit, R_REG(wlc->osh, &regs->phydebug) & PDBG_RFD));
+ /* delay the cleanup to wl_down in IBSS case */
+ if ((R_REG(wlc->osh, &regs->phydebug) & PDBG_RFD)) {
+ int idx;
+ wlc_bsscfg_t *bsscfg;
+ FOREACH_BSS(wlc, idx, bsscfg) {
+ if (!BSSCFG_STA(bsscfg) || !bsscfg->enable
+ || !bsscfg->BSS)
+ continue;
+ WL_ERROR(("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", wlc->pub->unit));
+ }
+ }
+ }
+
+ /* send any enq'd tx packets. Just makes sure to jump start tx */
+ if (!pktq_empty(&wlc->active_queue->q))
+ wlc_send_q(wlc, wlc->active_queue);
+
+#ifndef WLC_HIGH_ONLY
+ ASSERT(wlc_ps_check(wlc));
+#endif
+}
+
+static void *wlc_15420war(wlc_info_t *wlc, uint queue)
+{
+ hnddma_t *di;
+ void *p;
+
+ ASSERT(queue < NFIFO);
+
+ if ((D11REV_IS(wlc->pub->corerev, 4))
+ || (D11REV_GT(wlc->pub->corerev, 6)))
+ return NULL;
+
+ di = wlc->hw->di[queue];
+ ASSERT(di != NULL);
+
+ /* get next packet, ignoring XmtStatus.Curr */
+ p = dma_getnexttxp(di, HNDDMA_RANGE_ALL);
+
+ /* sw block tx dma */
+ dma_txblock(di);
+
+ /* if tx ring is now empty, reset and re-init the tx dma channel */
+ if (dma_txactive(wlc->hw->di[queue]) == 0) {
+ WLCNTINCR(wlc->pub->_cnt->txdmawar);
+ if (!dma_txreset(di))
+ WL_ERROR(("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", wlc->pub->unit, __func__, queue));
+ dma_txinit(di);
+ }
+ return p;
+}
+
+static void wlc_war16165(wlc_info_t *wlc, bool tx)
+{
+ if (tx) {
+ /* the post-increment is used in STAY_AWAKE macro */
+ if (wlc->txpend16165war++ == 0)
+ wlc_set_ps_ctrl(wlc);
+ } else {
+ wlc->txpend16165war--;
+ if (wlc->txpend16165war == 0)
+ wlc_set_ps_ctrl(wlc);
+ }
+}
+
+/* process an individual tx_status_t */
+/* WLC_HIGH_API */
+bool BCMFASTPATH
+wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, uint32 frm_tx2)
+{
+ void *p;
+ uint queue;
+ d11txh_t *txh;
+ struct scb *scb = NULL;
+ bool free_pdu;
+ osl_t *osh;
+ int tx_rts, tx_frame_count, tx_rts_count;
+ uint totlen, supr_status;
+ bool lastframe;
+ struct dot11_header *h;
+ uint16 fc;
+ uint16 mcl;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *txrate;
+ int i;
+
+ (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */
+
+ /* discard intermediate indications for ucode with one legitimate case:
+ * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+ * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+ * transmission count)
+ */
+ if (!(txs->status & TX_STATUS_AMPDU)
+ && (txs->status & TX_STATUS_INTERMEDIATE)) {
+ WLCNTADD(wlc->pub->_cnt->txnoack,
+ ((txs->
+ status & TX_STATUS_FRM_RTX_MASK) >>
+ TX_STATUS_FRM_RTX_SHIFT));
+ WL_ERROR(("%s: INTERMEDIATE but not AMPDU\n", __func__));
+ return FALSE;
+ }
+
+ osh = wlc->osh;
+ queue = txs->frameid & TXFID_QUEUE_MASK;
+ ASSERT(queue < NFIFO);
+ if (queue >= NFIFO) {
+ p = NULL;
+ goto fatal;
+ }
+
+ p = GETNEXTTXP(wlc, queue);
+ if (WLC_WAR16165(wlc))
+ wlc_war16165(wlc, FALSE);
+ if (p == NULL)
+ p = wlc_15420war(wlc, queue);
+ ASSERT(p != NULL);
+ if (p == NULL)
+ goto fatal;
+
+ txh = (d11txh_t *) PKTDATA(p);
+ mcl = ltoh16(txh->MacTxControlLow);
+
+ if (txs->phyerr) {
+ WL_ERROR(("phyerr 0x%x, rate 0x%x\n", txs->phyerr,
+ txh->MainRates));
+ wlc_print_txdesc(txh);
+ wlc_print_txstatus(txs);
+ }
+
+ ASSERT(txs->frameid == htol16(txh->TxFrameID));
+ if (txs->frameid != htol16(txh->TxFrameID))
+ goto fatal;
+
+ tx_info = IEEE80211_SKB_CB(p);
+ h = (struct dot11_header *)((uint8 *) (txh + 1) + D11_PHY_HDR_LEN);
+ fc = ltoh16(h->fc);
+
+ scb = (struct scb *)tx_info->control.sta->drv_priv;
+
+ if (N_ENAB(wlc->pub)) {
+ uint8 *plcp = (uint8 *) (txh + 1);
+ if (PLCP3_ISSGI(plcp[3]))
+ WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi);
+ if (PLCP3_ISSTBC(plcp[3]))
+ WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc);
+ }
+
+ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+ ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE);
+ wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
+ return FALSE;
+ }
+
+ supr_status = txs->status & TX_STATUS_SUPR_MASK;
+ if (supr_status == TX_STATUS_SUPR_BADCH)
+ WL_NONE(("%s: Pkt tx suppressed, possibly channel %d\n",
+ __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)));
+
+ tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS;
+ tx_frame_count =
+ (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
+ tx_rts_count =
+ (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
+
+ lastframe = (fc & FC_MOREFRAG) == 0;
+
+ if (!lastframe) {
+ WL_ERROR(("Not last frame!\n"));
+ } else {
+ uint16 sfbl, lfbl;
+ ieee80211_tx_info_clear_status(tx_info);
+ if (queue < AC_COUNT) {
+ sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
+ lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
+ } else {
+ sfbl = wlc->SFBL;
+ lfbl = wlc->LFBL;
+ }
+
+ txrate = tx_info->status.rates;
+ /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */
+ if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) {
+ /* rate selection requested a fallback rate and we used it */
+ txrate->count = lfbl;
+ txrate[1].count = tx_frame_count - lfbl;
+ } else {
+ /* rate selection did not request fallback rate, or we didn't need it */
+ txrate->count = tx_frame_count;
+ /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
+ txrate[1].idx = -1;
+ txrate[1].count = 0;
+ }
+
+ /* clear the rest of the rates */
+ for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+ txrate[i].idx = -1;
+ txrate[i].count = 0;
+ }
+
+ if (txs->status & TX_STATUS_ACK_RCV)
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ totlen = pkttotlen(osh, p);
+ free_pdu = TRUE;
+
+ wlc_txfifo_complete(wlc, queue, 1);
+
+ if (lastframe) {
+ PKTSETNEXT(p, NULL);
+ PKTSETLINK(p, NULL);
+ wlc->txretried = 0;
+ /* remove PLCP & Broadcom tx descriptor header */
+ PKTPULL(p, D11_PHY_HDR_LEN);
+ PKTPULL(p, D11_TXH_LEN);
+ ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
+ WLCNTINCR(wlc->pub->_cnt->ieee_tx_status);
+ } else {
+ WL_ERROR(("%s: Not last frame => not calling tx_status\n",
+ __func__));
+ }
+
+ return FALSE;
+
+ fatal:
+ ASSERT(0);
+ if (p)
+ PKTFREE(osh, p, TRUE);
+
+#ifdef WLC_HIGH_ONLY
+ /* If this is a split driver, do the big-hammer here.
+ * If this is a monolithic driver, wlc_bmac.c:wlc_dpc() will do the big-hammer.
+ */
+ wl_init(wlc->wl);
+#endif
+ return TRUE;
+
+}
+
+void BCMFASTPATH
+wlc_txfifo_complete(wlc_info_t *wlc, uint fifo, int8 txpktpend)
+{
+ TXPKTPENDDEC(wlc, fifo, txpktpend);
+ WL_TRACE(("wlc_txfifo_complete, pktpend dec %d to %d\n", txpktpend,
+ TXPKTPENDGET(wlc, fifo)));
+
+ /* There is more room; mark precedences related to this FIFO sendable */
+ WLC_TX_FIFO_ENAB(wlc, fifo);
+ ASSERT(TXPKTPENDGET(wlc, fifo) >= 0);
+
+ if (!TXPKTPENDTOT(wlc)) {
+ if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR)
+ wlc_bsscfg_tx_check(wlc);
+ }
+
+ /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
+ if (AP_ENAB(wlc->pub) &&
+ wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
+ wlc->bcmcfifo_drain = FALSE;
+ wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO);
+ }
+
+ /* figure out which bsscfg is being worked on... */
+}
+
+/* Given the beacon interval in kus, and a 64 bit TSF in us,
+ * return the offset (in us) of the TSF from the last TBTT
+ */
+uint32 wlc_calc_tbtt_offset(uint32 bp, uint32 tsf_h, uint32 tsf_l)
+{
+ uint32 k, btklo, btkhi, offset;
+
+ /* TBTT is always an even multiple of the beacon_interval,
+ * so the TBTT less than or equal to the beacon timestamp is
+ * the beacon timestamp minus the beacon timestamp modulo
+ * the beacon interval.
+ *
+ * TBTT = BT - (BT % BIu)
+ * = (BTk - (BTk % BP)) * 2^10
+ *
+ * BT = beacon timestamp (usec, 64bits)
+ * BTk = beacon timestamp (Kusec, 54bits)
+ * BP = beacon interval (Kusec, 16bits)
+ * BIu = BP * 2^10 = beacon interval (usec, 26bits)
+ *
+ * To keep the calculations in uint32s, the modulo operation
+ * on the high part of BT needs to be done in parts using the
+ * relations:
+ * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z
+ * and
+ * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z
+ *
+ * So, if BTk[n] = uint16 n [0,3] of BTk.
+ * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP
+ * and the SUM term can be broken down:
+ * (BTk[n] * 2^16n) % BP
+ * (BTk[n] * (2^16n % BP)) % BP
+ *
+ * Create a set of power of 2 mod BP constants:
+ * K[n] = 2^(16n) % BP
+ * = (K[n-1] * 2^16) % BP
+ * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP
+ *
+ * BTk % BP = BTk[0-1] % BP +
+ * (BTk[2] * K[2]) % BP +
+ * (BTk[3] * K[3]) % BP
+ *
+ * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32
+ */
+
+ /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */
+ btklo = (tsf_h << 22) | (tsf_l >> 10);
+ btkhi = tsf_h >> 10;
+
+ /* offset = BTk % BP */
+ offset = btklo % bp;
+
+ /* K[2] = ((2^16 % BP) * 2^16) % BP */
+ k = (uint32) (1 << 16) % bp;
+ k = (uint32) (k * 1 << 16) % (uint32) bp;
+
+ /* offset += (BTk[2] * K[2]) % BP */
+ offset += ((btkhi & 0xffff) * k) % bp;
+
+ /* BTk[3] */
+ btkhi = btkhi >> 16;
+
+ /* k[3] = (K[2] * 2^16) % BP */
+ k = (k << 16) % bp;
+
+ /* offset += (BTk[3] * K[3]) % BP */
+ offset += ((btkhi & 0xffff) * k) % bp;
+
+ offset = offset % bp;
+
+ /* convert offset from kus to us by shifting up 10 bits and
+ * add in the low 10 bits of tsf that we ignored
+ */
+ offset = (offset << 10) + (tsf_l & 0x3FF);
+
+ return offset;
+}
+
+/* Update beacon listen interval in shared memory */
+void wlc_bcn_li_upd(wlc_info_t *wlc)
+{
+ if (AP_ENAB(wlc->pub))
+ return;
+
+ /* wake up every DTIM is the default */
+ if (wlc->bcn_li_dtim == 1)
+ wlc_write_shm(wlc, M_BCN_LI, 0);
+ else
+ wlc_write_shm(wlc, M_BCN_LI,
+ (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
+}
+
+static void
+prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, void *p,
+ struct ieee80211_rx_status *rx_status)
+{
+ uint32 tsf_l, tsf_h;
+ wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
+ int preamble;
+ int channel;
+ ratespec_t rspec;
+ uchar *plcp;
+
+ wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */
+ rx_status->mactime = tsf_h;
+ rx_status->mactime <<= 32;
+ rx_status->mactime |= tsf_l;
+ rx_status->flag |= RX_FLAG_TSFT;
+
+ channel = WLC_CHAN_CHANNEL(rxh->RxChan);
+
+ /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */
+ if (channel > 14) {
+ rx_status->band = IEEE80211_BAND_5GHZ;
+ rx_status->freq = wf_channel2mhz(channel, WF_CHAN_FACTOR_5_G);
+ } else {
+ rx_status->band = IEEE80211_BAND_2GHZ;
+ rx_status->freq = wf_channel2mhz(channel, WF_CHAN_FACTOR_2_4_G);
+ }
+
+ rx_status->signal = wlc_rxh->rssi; /* signal */
+
+ /* noise */
+ /* qual */
+ rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */
+
+ plcp = PKTDATA(p);
+
+ rspec = wlc_compute_rspec(rxh, plcp);
+ if (IS_MCS(rspec)) {
+ rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
+ rx_status->flag |= RX_FLAG_HT;
+ if (RSPEC_IS40MHZ(rspec))
+ rx_status->flag |= RX_FLAG_40MHZ;
+ } else {
+ switch (RSPEC2RATE(rspec)) {
+ case WLC_RATE_1M:
+ rx_status->rate_idx = 0;
+ break;
+ case WLC_RATE_2M:
+ rx_status->rate_idx = 1;
+ break;
+ case WLC_RATE_5M5:
+ rx_status->rate_idx = 2;
+ break;
+ case WLC_RATE_11M:
+ rx_status->rate_idx = 3;
+ break;
+ case WLC_RATE_6M:
+ rx_status->rate_idx = 4;
+ break;
+ case WLC_RATE_9M:
+ rx_status->rate_idx = 5;
+ break;
+ case WLC_RATE_12M:
+ rx_status->rate_idx = 6;
+ break;
+ case WLC_RATE_18M:
+ rx_status->rate_idx = 7;
+ break;
+ case WLC_RATE_24M:
+ rx_status->rate_idx = 8;
+ break;
+ case WLC_RATE_36M:
+ rx_status->rate_idx = 9;
+ break;
+ case WLC_RATE_48M:
+ rx_status->rate_idx = 10;
+ break;
+ case WLC_RATE_54M:
+ rx_status->rate_idx = 11;
+ break;
+ default:
+ WL_ERROR(("%s: Unknown rate\n", __func__));
+ }
+
+ /* Determine short preamble and rate_idx */
+ preamble = 0;
+ if (IS_CCK(rspec)) {
+ if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
+ WL_ERROR(("Short CCK\n"));
+ rx_status->flag |= RX_FLAG_SHORTPRE;
+ } else if (IS_OFDM(rspec)) {
+ rx_status->flag |= RX_FLAG_SHORTPRE;
+ } else {
+ WL_ERROR(("%s: Unknown modulation\n", __func__));
+ }
+ }
+
+ if (PLCP3_ISSGI(plcp[3]))
+ rx_status->flag |= RX_FLAG_SHORT_GI;
+
+ if (rxh->RxStatus1 & RXS_DECERR) {
+ rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+ WL_ERROR(("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__));
+ }
+ if (rxh->RxStatus1 & RXS_FCSERR) {
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ WL_ERROR(("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__));
+ }
+}
+
+char *print_fk(uint16 fk)
+{
+ char *str;
+ switch (fk) {
+ case FC_ASSOC_REQ:
+ str = "FC_ASSOC_REQ";
+ break;
+ case FC_ASSOC_RESP:
+ str = "FC_ASSOC_RESP";
+ break;
+ case FC_REASSOC_REQ:
+ str = "FC_REASSOC_REQ";
+ break;
+ case FC_REASSOC_RESP:
+ str = "FC_REASSOC_RESP";
+ break;
+ case FC_PROBE_REQ:
+ str = "FC_PROBE_REQ";
+ break;
+ case FC_PROBE_RESP:
+ str = "FC_PROBE_RESP";
+ break;
+ case FC_BEACON:
+ str = "FC_BEACON";
+ break;
+ case FC_DISASSOC:
+ str = "FC_DISASSOC";
+ break;
+ case FC_AUTH:
+ str = "FC_AUTH";
+ break;
+ case FC_DEAUTH:
+ str = "FC_DEAUTH";
+ break;
+ case FC_ACTION:
+ str = "FC_ACTION";
+ break;
+ case FC_ACTION_NOACK:
+ str = "FC_ACTION_NOACK";
+ break;
+ case FC_CTL_WRAPPER:
+ str = "FC_CTL_WRAPPER";
+ break;
+ case FC_BLOCKACK_REQ:
+ str = "FC_BLOCKACK_REQ";
+ break;
+ case FC_BLOCKACK:
+ str = "FC_BLOCKACK";
+ break;
+ case FC_PS_POLL:
+ str = "FC_PS_POLL";
+ break;
+ case FC_RTS:
+ str = "FC_RTS";
+ break;
+ case FC_CTS:
+ str = "FC_CTS";
+ break;
+ case FC_ACK:
+ str = "FC_ACK";
+ break;
+ case FC_CF_END:
+ str = "FC_CF_END";
+ break;
+ case FC_CF_END_ACK:
+ str = "FC_CF_END_ACK";
+ break;
+ case FC_DATA:
+ str = "FC_DATA";
+ break;
+ case FC_NULL_DATA:
+ str = "FC_NULL_DATA";
+ break;
+ case FC_DATA_CF_ACK:
+ str = "FC_DATA_CF_ACK";
+ break;
+ case FC_QOS_DATA:
+ str = "FC_QOS_DATA";
+ break;
+ case FC_QOS_NULL:
+ str = "FC_QOS_NULL";
+ break;
+ default:
+ str = "Unknown!!";
+ break;
+ }
+ return str;
+}
+
+static void
+wlc_recvctl(wlc_info_t *wlc, osl_t *osh, d11rxhdr_t *rxh, void *p)
+{
+ int len_mpdu;
+ struct ieee80211_rx_status rx_status;
+#if defined(BCMDBG)
+ struct sk_buff *skb = p;
+#endif /* BCMDBG */
+ /* Todo:
+ * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE.
+ * Test for INTERMEDIATE like so:
+ * if (!(plcp[0] | plcp[1] | plcp[2]))
+ */
+
+ memset(&rx_status, 0, sizeof(rx_status));
+ prep_mac80211_status(wlc, rxh, p, &rx_status);
+
+ /* mac header+body length, exclude CRC and plcp header */
+ len_mpdu = PKTLEN(p) - D11_PHY_HDR_LEN - DOT11_FCS_LEN;
+ PKTPULL(p, D11_PHY_HDR_LEN);
+ PKTSETLEN(p, len_mpdu);
+
+ ASSERT(!PKTNEXT(p));
+ ASSERT(!PKTLINK(p));
+
+ ASSERT(ISALIGNED((uintptr) skb->data, 2));
+
+ memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
+ ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
+
+ WLCNTINCR(wlc->pub->_cnt->ieee_rx);
+ PKTUNALLOC(osh);
+ return;
+}
+
+void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list)
+{
+ uint index;
+ wlc_bss_info_t *bi;
+
+ if (!bss_list) {
+ WL_ERROR(("%s: Attempting to free NULL list\n", __func__));
+ return;
+ }
+ /* inspect all BSS descriptor */
+ for (index = 0; index < bss_list->count; index++) {
+ bi = bss_list->ptrs[index];
+ if (bi) {
+ if (bi->bcn_prb) {
+ osl_mfree(wlc->osh, bi->bcn_prb,
+ bi->bcn_prb_len);
+ }
+ osl_mfree(wlc->osh, bi, sizeof(wlc_bss_info_t));
+ bss_list->ptrs[index] = NULL;
+ }
+ }
+ bss_list->count = 0;
+}
+
+/* Process received frames */
+/*
+ * Return TRUE if more frames need to be processed. FALSE otherwise.
+ * Param 'bound' indicates max. # frames to process before break out.
+ */
+/* WLC_HIGH_API */
+void BCMFASTPATH wlc_recv(wlc_info_t *wlc, void *p)
+{
+ d11rxhdr_t *rxh;
+ struct dot11_header *h;
+ osl_t *osh;
+ uint16 fc;
+ uint len;
+ bool is_amsdu;
+#ifdef BCMDBG
+ char eabuf[ETHER_ADDR_STR_LEN];
+#endif
+
+ WL_TRACE(("wl%d: wlc_recv\n", wlc->pub->unit));
+
+ osh = wlc->osh;
+
+ /* frame starts with rxhdr */
+ rxh = (d11rxhdr_t *) PKTDATA(p);
+
+ /* strip off rxhdr */
+ PKTPULL(p, wlc->hwrxoff);
+
+ /* fixup rx header endianness */
+ ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t));
+
+ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
+ if (rxh->RxStatus1 & RXS_PBPRES) {
+ if (PKTLEN(p) < 2) {
+ WLCNTINCR(wlc->pub->_cnt->rxrunt);
+ WL_ERROR(("wl%d: wlc_recv: rcvd runt of len %d\n",
+ wlc->pub->unit, PKTLEN(p)));
+ goto toss;
+ }
+ PKTPULL(p, 2);
+ }
+
+ h = (struct dot11_header *)(PKTDATA(p) + D11_PHY_HDR_LEN);
+ len = PKTLEN(p);
+
+ if (rxh->RxStatus1 & RXS_FCSERR) {
+ if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
+ WL_ERROR(("FCSERR while scanning******* - tossing\n"));
+ goto toss;
+ } else {
+ WL_ERROR(("RCSERR!!!\n"));
+ goto toss;
+ }
+ }
+
+ /* check received pkt has at least frame control field */
+ if (len >= D11_PHY_HDR_LEN + sizeof(h->fc)) {
+ fc = ltoh16(h->fc);
+ } else {
+ WLCNTINCR(wlc->pub->_cnt->rxrunt);
+ goto toss;
+ }
+
+ is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
+
+ /* explicitly test bad src address to avoid sending bad deauth */
+ if (!is_amsdu) {
+ /* CTS and ACK CTL frames are w/o a2 */
+ if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) {
+ if ((ETHER_ISNULLADDR(&h->a2) || ETHER_ISMULTI(&h->a2))) {
+ WL_ERROR(("wl%d: %s: dropping a frame with invalid" " src mac address, a2: %s\n", wlc->pub->unit, __func__, bcm_ether_ntoa(&h->a2, eabuf)));
+ WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac);
+ goto toss;
+ }
+ WLCNTINCR(wlc->pub->_cnt->rxfrag);
+ }
+ }
+
+ /* due to sheer numbers, toss out probe reqs for now */
+ if (FC_TYPE(fc) == FC_TYPE_MNG) {
+ if ((fc & FC_KIND_MASK) == FC_PROBE_REQ)
+ goto toss;
+ }
+
+ if (is_amsdu) {
+ WL_ERROR(("%s: is_amsdu causing toss\n", __func__));
+ goto toss;
+ }
+
+ wlc_recvctl(wlc, osh, rxh, p);
+ return;
+
+ toss:
+ PKTFREE(osh, p, FALSE);
+}
+
+/* calculate frame duration for Mixed-mode L-SIG spoofing, return
+ * number of bytes goes in the length field
+ *
+ * Formula given by HT PHY Spec v 1.13
+ * len = 3(nsyms + nstream + 3) - 3
+ */
+uint16 BCMFASTPATH
+wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec, uint mac_len)
+{
+ uint nsyms, len = 0, kNdps;
+
+ WL_TRACE(("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", wlc->pub->unit,
+ RSPEC2RATE(ratespec), mac_len));
+
+ if (IS_MCS(ratespec)) {
+ uint mcs = ratespec & RSPEC_RATE_MASK;
+ /* MCS_TXS(mcs) returns num tx streams - 1 */
+ int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
+
+ ASSERT(WLC_PHY_11N_CAP(wlc->band));
+ /* the payload duration calculation matches that of regular ofdm */
+ /* 1000Ndbps = kbps * 4 */
+ kNdps =
+ MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+ RSPEC_ISSGI(ratespec)) * 4;
+
+ if (RSPEC_STC(ratespec) == 0)
+ /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+ nsyms =
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, kNdps);
+ else
+ /* STBC needs to have even number of symbols */
+ nsyms =
+ 2 *
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+
+ nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */
+ /* 3 bytes/symbol @ legacy 6Mbps rate */
+ len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */
+ }
+
+ return (uint16) len;
+}
+
+/* calculate frame duration of a given rate and length, return time in usec unit */
+uint BCMFASTPATH
+wlc_calc_frame_time(wlc_info_t *wlc, ratespec_t ratespec, uint8 preamble_type,
+ uint mac_len)
+{
+ uint nsyms, dur = 0, Ndps, kNdps;
+ uint rate = RSPEC2RATE(ratespec);
+
+ if (rate == 0) {
+ ASSERT(0);
+ WL_ERROR(("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit));
+ rate = WLC_RATE_1M;
+ }
+
+ WL_TRACE(("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", wlc->pub->unit, ratespec, preamble_type, mac_len));
+
+ if (IS_MCS(ratespec)) {
+ uint mcs = ratespec & RSPEC_RATE_MASK;
+ int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+ ASSERT(WLC_PHY_11N_CAP(wlc->band));
+ ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type));
+
+ dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+ if (preamble_type == WLC_MM_PREAMBLE)
+ dur += PREN_MM_EXT;
+ /* 1000Ndbps = kbps * 4 */
+ kNdps =
+ MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+ RSPEC_ISSGI(ratespec)) * 4;
+
+ if (RSPEC_STC(ratespec) == 0)
+ /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+ nsyms =
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, kNdps);
+ else
+ /* STBC needs to have even number of symbols */
+ nsyms =
+ 2 *
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+ APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+
+ dur += APHY_SYMBOL_TIME * nsyms;
+ if (BAND_2G(wlc->band->bandtype))
+ dur += DOT11_OFDM_SIGNAL_EXTENSION;
+ } else if (IS_OFDM(rate)) {
+ dur = APHY_PREAMBLE_TIME;
+ dur += APHY_SIGNAL_TIME;
+ /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+ Ndps = rate * 2;
+ /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+ nsyms =
+ CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
+ Ndps);
+ dur += APHY_SYMBOL_TIME * nsyms;
+ if (BAND_2G(wlc->band->bandtype))
+ dur += DOT11_OFDM_SIGNAL_EXTENSION;
+ } else {
+ /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
+ mac_len = mac_len * 8 * 2;
+ /* calc ceiling of bits/rate = microseconds of air time */
+ dur = (mac_len + rate - 1) / rate;
+ if (preamble_type & WLC_SHORT_PREAMBLE)
+ dur += BPHY_PLCP_SHORT_TIME;
+ else
+ dur += BPHY_PLCP_TIME;
+ }
+ return dur;
+}
+
+/* The opposite of wlc_calc_frame_time */
+static uint
+wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t ratespec, uint8 preamble_type,
+ uint dur)
+{
+ uint nsyms, mac_len, Ndps, kNdps;
+ uint rate = RSPEC2RATE(ratespec);
+
+ WL_TRACE(("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", wlc->pub->unit, ratespec, preamble_type, dur));
+
+ if (IS_MCS(ratespec)) {
+ uint mcs = ratespec & RSPEC_RATE_MASK;
+ int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+ ASSERT(WLC_PHY_11N_CAP(wlc->band));
+ dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+ /* payload calculation matches that of regular ofdm */
+ if (BAND_2G(wlc->band->bandtype))
+ dur -= DOT11_OFDM_SIGNAL_EXTENSION;
+ /* kNdbps = kbps * 4 */
+ kNdps =
+ MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+ RSPEC_ISSGI(ratespec)) * 4;
+ nsyms = dur / APHY_SYMBOL_TIME;
+ mac_len =
+ ((nsyms * kNdps) -
+ ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
+ } else if (IS_OFDM(ratespec)) {
+ dur -= APHY_PREAMBLE_TIME;
+ dur -= APHY_SIGNAL_TIME;
+ /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+ Ndps = rate * 2;
+ nsyms = dur / APHY_SYMBOL_TIME;
+ mac_len =
+ ((nsyms * Ndps) -
+ (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
+ } else {
+ if (preamble_type & WLC_SHORT_PREAMBLE)
+ dur -= BPHY_PLCP_SHORT_TIME;
+ else
+ dur -= BPHY_PLCP_TIME;
+ mac_len = dur * rate;
+ /* divide out factor of 2 in rate (1/2 mbps) */
+ mac_len = mac_len / 8 / 2;
+ }
+ return mac_len;
+}
+
+static uint
+wlc_calc_ba_time(wlc_info_t *wlc, ratespec_t rspec, uint8 preamble_type)
+{
+ WL_TRACE(("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type));
+ /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+ * or equal to the rate of the immediately previous frame in the FES
+ */
+ rspec = WLC_BASIC_RATE(wlc, rspec);
+ ASSERT(VALID_RATE_DBG(wlc, rspec));
+
+ /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
+ return wlc_calc_frame_time(wlc, rspec, preamble_type,
+ (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
+ DOT11_FCS_LEN));
+}
+
+static uint BCMFASTPATH
+wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rspec, uint8 preamble_type)
+{
+ uint dur = 0;
+
+ WL_TRACE(("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type));
+ /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+ * or equal to the rate of the immediately previous frame in the FES
+ */
+ rspec = WLC_BASIC_RATE(wlc, rspec);
+ ASSERT(VALID_RATE_DBG(wlc, rspec));
+
+ /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
+ dur =
+ wlc_calc_frame_time(wlc, rspec, preamble_type,
+ (DOT11_ACK_LEN + DOT11_FCS_LEN));
+ return dur;
+}
+
+static uint
+wlc_calc_cts_time(wlc_info_t *wlc, ratespec_t rspec, uint8 preamble_type)
+{
+ WL_TRACE(("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n",
+ wlc->pub->unit, rspec, preamble_type));
+ return wlc_calc_ack_time(wlc, rspec, preamble_type);
+}
+
+/* derive wlc->band->basic_rate[] table from 'rateset' */
+void wlc_rate_lookup_init(wlc_info_t *wlc, wlc_rateset_t *rateset)
+{
+ uint8 rate;
+ uint8 mandatory;
+ uint8 cck_basic = 0;
+ uint8 ofdm_basic = 0;
+ uint8 *br = wlc->band->basic_rate;
+ uint i;
+
+ /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
+ bzero(br, WLC_MAXRATE + 1);
+
+ /* For each basic rate in the rates list, make an entry in the
+ * best basic lookup.
+ */
+ for (i = 0; i < rateset->count; i++) {
+ /* only make an entry for a basic rate */
+ if (!(rateset->rates[i] & WLC_RATE_FLAG))
+ continue;
+
+ /* mask off basic bit */
+ rate = (rateset->rates[i] & RATE_MASK);
+
+ if (rate > WLC_MAXRATE) {
+ WL_ERROR(("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", rateset->rates[i]));
+ continue;
+ }
+
+ br[rate] = rate;
+ }
+
+ /* The rate lookup table now has non-zero entries for each
+ * basic rate, equal to the basic rate: br[basicN] = basicN
+ *
+ * To look up the best basic rate corresponding to any
+ * particular rate, code can use the basic_rate table
+ * like this
+ *
+ * basic_rate = wlc->band->basic_rate[tx_rate]
+ *
+ * Make sure there is a best basic rate entry for
+ * every rate by walking up the table from low rates
+ * to high, filling in holes in the lookup table
+ */
+
+ for (i = 0; i < wlc->band->hw_rateset.count; i++) {
+ rate = wlc->band->hw_rateset.rates[i];
+ ASSERT(rate <= WLC_MAXRATE);
+
+ if (br[rate] != 0) {
+ /* This rate is a basic rate.
+ * Keep track of the best basic rate so far by
+ * modulation type.
+ */
+ if (IS_OFDM(rate))
+ ofdm_basic = rate;
+ else
+ cck_basic = rate;
+
+ continue;
+ }
+
+ /* This rate is not a basic rate so figure out the
+ * best basic rate less than this rate and fill in
+ * the hole in the table
+ */
+
+ br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;
+
+ if (br[rate] != 0)
+ continue;
+
+ if (IS_OFDM(rate)) {
+ /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
+ if (rate >= WLC_RATE_24M)
+ mandatory = WLC_RATE_24M;
+ else if (rate >= WLC_RATE_12M)
+ mandatory = WLC_RATE_12M;
+ else
+ mandatory = WLC_RATE_6M;
+ } else {
+ /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
+ mandatory = rate;
+ }
+
+ br[rate] = mandatory;
+ }
+}
+
+static void wlc_write_rate_shm(wlc_info_t *wlc, uint8 rate, uint8 basic_rate)
+{
+ uint8 phy_rate, index;
+ uint8 basic_phy_rate, basic_index;
+ uint16 dir_table, basic_table;
+ uint16 basic_ptr;
+
+ /* Shared memory address for the table we are reading */
+ dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
+
+ /* Shared memory address for the table we are writing */
+ basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
+
+ /*
+ * for a given rate, the LS-nibble of the PLCP SIGNAL field is
+ * the index into the rate table.
+ */
+ phy_rate = rate_info[rate] & RATE_MASK;
+ basic_phy_rate = rate_info[basic_rate] & RATE_MASK;
+ index = phy_rate & 0xf;
+ basic_index = basic_phy_rate & 0xf;
+
+ /* Find the SHM pointer to the ACK rate entry by looking in the
+ * Direct-map Table
+ */
+ basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2));
+
+ /* Update the SHM BSS-basic-rate-set mapping table with the pointer
+ * to the correct basic rate for the given incoming rate
+ */
+ wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr);
+}
+
+static const wlc_rateset_t *wlc_rateset_get_hwrs(wlc_info_t *wlc)
+{
+ const wlc_rateset_t *rs_dflt;
+
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ if (BAND_5G(wlc->band->bandtype))
+ rs_dflt = &ofdm_mimo_rates;
+ else
+ rs_dflt = &cck_ofdm_mimo_rates;
+ } else if (wlc->band->gmode)
+ rs_dflt = &cck_ofdm_rates;
+ else
+ rs_dflt = &cck_rates;
+
+ return rs_dflt;
+}
+
+void wlc_set_ratetable(wlc_info_t *wlc)
+{
+ const wlc_rateset_t *rs_dflt;
+ wlc_rateset_t rs;
+ uint8 rate, basic_rate;
+ uint i;
+
+ rs_dflt = wlc_rateset_get_hwrs(wlc);
+ ASSERT(rs_dflt != NULL);
+
+ wlc_rateset_copy(rs_dflt, &rs);
+ wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+
+ /* walk the phy rate table and update SHM basic rate lookup table */
+ for (i = 0; i < rs.count; i++) {
+ rate = rs.rates[i] & RATE_MASK;
+
+ /* for a given rate WLC_BASIC_RATE returns the rate at
+ * which a response ACK/CTS should be sent.
+ */
+ basic_rate = WLC_BASIC_RATE(wlc, rate);
+ if (basic_rate == 0) {
+ /* This should only happen if we are using a
+ * restricted rateset.
+ */
+ basic_rate = rs.rates[0] & RATE_MASK;
+ }
+
+ wlc_write_rate_shm(wlc, rate, basic_rate);
+ }
+}
+
+/*
+ * Return true if the specified rate is supported by the specified band.
+ * WLC_BAND_AUTO indicates the current band.
+ */
+bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rspec, int band, bool verbose)
+{
+ wlc_rateset_t *hw_rateset;
+ uint i;
+
+ if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) {
+ hw_rateset = &wlc->band->hw_rateset;
+ } else if (NBANDS(wlc) > 1) {
+ hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
+ } else {
+ /* other band specified and we are a single band device */
+ return FALSE;
+ }
+
+ /* check if this is a mimo rate */
+ if (IS_MCS(rspec)) {
+ if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
+ goto error;
+
+ return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
+ }
+
+ for (i = 0; i < hw_rateset->count; i++)
+ if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
+ return TRUE;
+ error:
+ if (verbose) {
+ WL_ERROR(("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", wlc->pub->unit, rspec));
+ }
+
+ return FALSE;
+}
+
+static void wlc_update_mimo_band_bwcap(wlc_info_t *wlc, uint8 bwcap)
+{
+ uint i;
+ wlcband_t *band;
+
+ for (i = 0; i < NBANDS(wlc); i++) {
+ if (IS_SINGLEBAND_5G(wlc->deviceid))
+ i = BAND_5G_INDEX;
+ band = wlc->bandstate[i];
+ if (band->bandtype == WLC_BAND_5G) {
+ if ((bwcap == WLC_N_BW_40ALL)
+ || (bwcap == WLC_N_BW_20IN2G_40IN5G))
+ band->mimo_cap_40 = TRUE;
+ else
+ band->mimo_cap_40 = FALSE;
+ } else {
+ ASSERT(band->bandtype == WLC_BAND_2G);
+ if (bwcap == WLC_N_BW_40ALL)
+ band->mimo_cap_40 = TRUE;
+ else
+ band->mimo_cap_40 = FALSE;
+ }
+ }
+
+ wlc->mimo_band_bwcap = bwcap;
+}
+
+void wlc_mod_prb_rsp_rate_table(wlc_info_t *wlc, uint frame_len)
+{
+ const wlc_rateset_t *rs_dflt;
+ wlc_rateset_t rs;
+ uint8 rate;
+ uint16 entry_ptr;
+ uint8 plcp[D11_PHY_HDR_LEN];
+ uint16 dur, sifs;
+ uint i;
+
+ sifs = SIFS(wlc->band);
+
+ rs_dflt = wlc_rateset_get_hwrs(wlc);
+ ASSERT(rs_dflt != NULL);
+
+ wlc_rateset_copy(rs_dflt, &rs);
+ wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+
+ /* walk the phy rate table and update MAC core SHM basic rate table entries */
+ for (i = 0; i < rs.count; i++) {
+ rate = rs.rates[i] & RATE_MASK;
+
+ entry_ptr = wlc_rate_shm_offset(wlc, rate);
+
+ /* Calculate the Probe Response PLCP for the given rate */
+ wlc_compute_plcp(wlc, rate, frame_len, plcp);
+
+ /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
+ dur =
+ (uint16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE,
+ frame_len);
+ dur += sifs;
+
+ /* Update the SHM Rate Table entry Probe Response values */
+ wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
+ (uint16) (plcp[0] + (plcp[1] << 8)));
+ wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
+ (uint16) (plcp[2] + (plcp[3] << 8)));
+ wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
+ }
+}
+
+uint16
+wlc_compute_bcntsfoff(wlc_info_t *wlc, ratespec_t rspec, bool short_preamble,
+ bool phydelay)
+{
+ uint bcntsfoff = 0;
+
+ if (IS_MCS(rspec)) {
+ WL_ERROR(("wl%d: recd beacon with mcs rate; rspec 0x%x\n",
+ wlc->pub->unit, rspec));
+ } else if (IS_OFDM(rspec)) {
+ /* tx delay from MAC through phy to air (2.1 usec) +
+ * phy header time (preamble + PLCP SIGNAL == 20 usec) +
+ * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26
+ * bytes at beacon rate)
+ */
+ bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0;
+ bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME;
+ bcntsfoff +=
+ wlc_compute_airtime(wlc, rspec,
+ APHY_SERVICE_NBITS / 8 +
+ DOT11_MAC_HDR_LEN);
+ } else {
+ /* tx delay from MAC through phy to air (3.4 usec) +
+ * phy header time (long preamble + PLCP == 192 usec) +
+ * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate)
+ */
+ bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0;
+ bcntsfoff +=
+ short_preamble ? D11B_PHY_SPREHDR_TIME :
+ D11B_PHY_LPREHDR_TIME;
+ bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN);
+ }
+ return (uint16) (bcntsfoff);
+}
+
+/* Max buffering needed for beacon template/prb resp template is 142 bytes.
+ *
+ * PLCP header is 6 bytes.
+ * 802.11 A3 header is 24 bytes.
+ * Max beacon frame body template length is 112 bytes.
+ * Max probe resp frame body template length is 110 bytes.
+ *
+ * *len on input contains the max length of the packet available.
+ *
+ * The *len value is set to the number of bytes in buf used, and starts with the PLCP
+ * and included up to, but not including, the 4 byte FCS.
+ */
+static void
+wlc_bcn_prb_template(wlc_info_t *wlc, uint type, ratespec_t bcn_rspec,
+ wlc_bsscfg_t *cfg, uint16 *buf, int *len)
+{
+ cck_phy_hdr_t *plcp;
+ struct dot11_management_header *h;
+ int hdr_len, body_len;
+
+ ASSERT(*len >= 142);
+ ASSERT(type == FC_BEACON || type == FC_PROBE_RESP);
+
+ if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON)
+ hdr_len = DOT11_MAC_HDR_LEN;
+ else
+ hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
+ body_len = *len - hdr_len; /* calc buffer size provided for frame body */
+
+ *len = hdr_len + body_len; /* return actual size */
+
+ /* format PHY and MAC headers */
+ bzero((char *)buf, hdr_len);
+
+ plcp = (cck_phy_hdr_t *) buf;
+
+ /* PLCP for Probe Response frames are filled in from core's rate table */
+ if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) {
+ /* fill in PLCP */
+ wlc_compute_plcp(wlc, bcn_rspec,
+ (DOT11_MAC_HDR_LEN + body_len + DOT11_FCS_LEN),
+ (uint8 *) plcp);
+
+ }
+ /* "Regular" and 16 MBSS but not for 4 MBSS */
+ /* Update the phytxctl for the beacon based on the rspec */
+ if (!SOFTBCN_ENAB(cfg))
+ wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
+
+ if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON)
+ h = (struct dot11_management_header *)&plcp[0];
+ else
+ h = (struct dot11_management_header *)&plcp[1];
+
+ /* fill in 802.11 header */
+ h->fc = htol16((uint16) type);
+
+ /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
+ /* A1 filled in by MAC for prb resp, broadcast for bcn */
+ if (type == FC_BEACON)
+ bcopy((const char *)&ether_bcast, (char *)&h->da,
+ ETHER_ADDR_LEN);
+ bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETHER_ADDR_LEN);
+ bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETHER_ADDR_LEN);
+
+ /* SEQ filled in by MAC */
+
+ return;
+}
+
+int wlc_get_header_len()
+{
+ return TXOFF;
+}
+
+/* Update a beacon for a particular BSS
+ * For MBSS, this updates the software template and sets "latest" to the index of the
+ * template updated.
+ * Otherwise, it updates the hardware template.
+ */
+void wlc_bss_update_beacon(wlc_info_t *wlc, wlc_bsscfg_t *cfg)
+{
+ int len = BCN_TMPL_LEN;
+
+ /* Clear the soft intmask */
+ wlc->defmacintmask &= ~MI_BCNTPL;
+
+ if (!cfg->up) { /* Only allow updates on an UP bss */
+ return;
+ }
+
+ if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */
+ } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */
+ uint16 bcn[BCN_TMPL_LEN / 2];
+ uint32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
+ d11regs_t *regs = wlc->regs;
+ osl_t *osh = NULL;
+
+ osh = wlc->osh;
+
+ /* Check if both templates are in use, if so sched. an interrupt
+ * that will call back into this routine
+ */
+ if ((R_REG(osh, &regs->maccommand) & both_valid) == both_valid) {
+ /* clear any previous status */
+ W_REG(osh, &regs->macintstatus, MI_BCNTPL);
+ }
+ /* Check that after scheduling the interrupt both of the
+ * templates are still busy. if not clear the int. & remask
+ */
+ if ((R_REG(osh, &regs->maccommand) & both_valid) == both_valid) {
+ wlc->defmacintmask |= MI_BCNTPL;
+ return;
+ }
+
+ wlc->bcn_rspec =
+ wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
+ ASSERT(wlc_valid_rate
+ (wlc, wlc->bcn_rspec,
+ CHSPEC_IS2G(cfg->current_bss->
+ chanspec) ? WLC_BAND_2G : WLC_BAND_5G,
+ TRUE));
+
+ /* update the template and ucode shm */
+ wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn,
+ &len);
+ wlc_write_hw_bcntemplates(wlc, bcn, len, FALSE);
+ }
+}
+
+/*
+ * Update all beacons for the system.
+ */
+void wlc_update_beacon(wlc_info_t *wlc)
+{
+ int idx;
+ wlc_bsscfg_t *bsscfg;
+
+ /* update AP or IBSS beacons */
+ FOREACH_BSS(wlc, idx, bsscfg) {
+ if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+ wlc_bss_update_beacon(wlc, bsscfg);
+ }
+}
+
+/* Write ssid into shared memory */
+void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg)
+{
+ uint8 *ssidptr = cfg->SSID;
+ uint16 base = M_SSID;
+ uint8 ssidbuf[DOT11_MAX_SSID_LEN];
+
+ /* padding the ssid with zero and copy it into shm */
+ bzero(ssidbuf, DOT11_MAX_SSID_LEN);
+ bcopy(ssidptr, ssidbuf, cfg->SSID_len);
+
+ wlc_copyto_shm(wlc, base, ssidbuf, DOT11_MAX_SSID_LEN);
+
+ if (!MBSS_BCN_ENAB(cfg))
+ wlc_write_shm(wlc, M_SSIDLEN, (uint16) cfg->SSID_len);
+}
+
+void wlc_update_probe_resp(wlc_info_t *wlc, bool suspend)
+{
+ int idx;
+ wlc_bsscfg_t *bsscfg;
+
+ /* update AP or IBSS probe responses */
+ FOREACH_BSS(wlc, idx, bsscfg) {
+ if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+ wlc_bss_update_probe_resp(wlc, bsscfg, suspend);
+ }
+}
+
+void
+wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, bool suspend)
+{
+ uint16 prb_resp[BCN_TMPL_LEN / 2];
+ int len = BCN_TMPL_LEN;
+
+ /* write the probe response to hardware, or save in the config structure */
+ if (!MBSS_PRB_ENAB(cfg)) {
+
+ /* create the probe response template */
+ wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp,
+ &len);
+
+ if (suspend)
+ wlc_suspend_mac_and_wait(wlc);
+
+ /* write the probe response into the template region */
+ wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
+ (len + 3) & ~3, prb_resp);
+
+ /* write the length of the probe response frame (+PLCP/-FCS) */
+ wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (uint16) len);
+
+ /* write the SSID and SSID length */
+ wlc_shm_ssid_upd(wlc, cfg);
+
+ /*
+ * Write PLCP headers and durations for probe response frames at all rates.
+ * Use the actual frame length covered by the PLCP header for the call to
+ * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS.
+ */
+ len += (-D11_PHY_HDR_LEN + DOT11_FCS_LEN);
+ wlc_mod_prb_rsp_rate_table(wlc, (uint16) len);
+
+ if (suspend)
+ wlc_enable_mac(wlc);
+ } else { /* Generating probe resp in sw; update local template */
+ ASSERT(0 && "No software probe response support without MBSS");
+ }
+}
+
+/* prepares pdu for transmission. returns BCM error codes */
+int wlc_prep_pdu(wlc_info_t *wlc, void *pdu, uint *fifop)
+{
+ osl_t *osh;
+ uint fifo;
+ d11txh_t *txh;
+ struct dot11_header *h;
+ struct scb *scb;
+ uint16 fc;
+
+ osh = wlc->osh;
+
+ ASSERT(pdu);
+ txh = (d11txh_t *) PKTDATA(pdu);
+ ASSERT(txh);
+ h = (struct dot11_header *)((uint8 *) (txh + 1) + D11_PHY_HDR_LEN);
+ ASSERT(h);
+ fc = ltoh16(h->fc);
+
+ /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */
+ fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK;
+
+ scb = NULL;
+
+ *fifop = fifo;
+
+ /* return if insufficient dma resources */
+ if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
+ /* Mark precedences related to this FIFO, unsendable */
+ WLC_TX_FIFO_CLEAR(wlc, fifo);
+ return BCME_BUSY;
+ }
+
+ if (FC_TYPE(ltoh16(txh->MacFrameControl)) != FC_TYPE_DATA)
+ WLCNTINCR(wlc->pub->_cnt->txctl);
+
+ return 0;
+}
+
+/* init tx reported rate mechanism */
+void wlc_reprate_init(wlc_info_t *wlc)
+{
+ int i;
+ wlc_bsscfg_t *bsscfg;
+
+ FOREACH_BSS(wlc, i, bsscfg) {
+ wlc_bsscfg_reprate_init(bsscfg);
+ }
+}
+
+/* per bsscfg init tx reported rate mechanism */
+void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg)
+{
+ bsscfg->txrspecidx = 0;
+ bzero((char *)bsscfg->txrspec, sizeof(bsscfg->txrspec));
+}
+
+/* Retrieve a consolidated set of revision information,
+ * typically for the WLC_GET_REVINFO ioctl
+ */
+int wlc_get_revision_info(wlc_info_t *wlc, void *buf, uint len)
+{
+ wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf;
+
+ if (len < WL_REV_INFO_LEGACY_LENGTH)
+ return BCME_BUFTOOSHORT;
+
+ rinfo->vendorid = wlc->vendorid;
+ rinfo->deviceid = wlc->deviceid;
+ rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) |
+ (wlc->band->radioid << IDCODE_ID_SHIFT);
+ rinfo->chiprev = wlc->pub->sih->chiprev;
+ rinfo->corerev = wlc->pub->corerev;
+ rinfo->boardid = wlc->pub->sih->boardtype;
+ rinfo->boardvendor = wlc->pub->sih->boardvendor;
+ rinfo->boardrev = wlc->pub->boardrev;
+ rinfo->ucoderev = wlc->ucode_rev;
+ rinfo->driverrev = EPI_VERSION_NUM;
+ rinfo->bus = wlc->pub->sih->bustype;
+ rinfo->chipnum = wlc->pub->sih->chip;
+
+ if (len >= (OFFSETOF(wlc_rev_info_t, chippkg))) {
+ rinfo->phytype = wlc->band->phytype;
+ rinfo->phyrev = wlc->band->phyrev;
+ rinfo->anarev = 0; /* obsolete stuff, suppress */
+ }
+
+ if (len >= sizeof(*rinfo)) {
+ rinfo->chippkg = wlc->pub->sih->chippkg;
+ }
+
+ return BCME_OK;
+}
+
+void wlc_default_rateset(wlc_info_t *wlc, wlc_rateset_t *rs)
+{
+ wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype,
+ FALSE, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+ CHSPEC_WLC_BW(wlc->default_bss->chanspec),
+ wlc->stf->txstreams);
+}
+
+static void BCMATTACHFN(wlc_bss_default_init) (wlc_info_t *wlc)
+{
+ chanspec_t chanspec;
+ wlcband_t *band;
+ wlc_bss_info_t *bi = wlc->default_bss;
+
+ /* init default and target BSS with some sane initial values */
+ bzero((char *)(bi), sizeof(wlc_bss_info_t));
+ bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT :
+ BEACON_INTERVAL_DEFAULT;
+ bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT :
+ DTIM_INTERVAL_DEFAULT;
+
+ /* fill the default channel as the first valid channel
+ * starting from the 2G channels
+ */
+ chanspec = CH20MHZ_CHSPEC(1);
+ ASSERT(chanspec != INVCHANSPEC);
+
+ wlc->home_chanspec = bi->chanspec = chanspec;
+
+ /* find the band of our default channel */
+ band = wlc->band;
+ if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec))
+ band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+
+ /* init bss rates to the band specific default rate set */
+ wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype,
+ FALSE, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+ CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams);
+
+ if (N_ENAB(wlc->pub))
+ bi->flags |= WLC_BSS_HT;
+}
+
+/* Deferred event processing */
+static void wlc_process_eventq(void *arg)
+{
+ wlc_info_t *wlc = (wlc_info_t *) arg;
+ wlc_event_t *etmp;
+
+ while ((etmp = wlc_eventq_deq(wlc->eventq))) {
+ /* Perform OS specific event processing */
+ wl_event(wlc->wl, etmp->event.ifname, etmp);
+ if (etmp->data) {
+ osl_mfree(wlc->osh, etmp->data, etmp->event.datalen);
+ etmp->data = NULL;
+ }
+ wlc_event_free(wlc->eventq, etmp);
+ }
+}
+
+void
+wlc_uint64_sub(uint32 *a_high, uint32 *a_low, uint32 b_high, uint32 b_low)
+{
+ if (b_low > *a_low) {
+ /* low half needs a carry */
+ b_high += 1;
+ }
+ *a_low -= b_low;
+ *a_high -= b_high;
+}
+
+static ratespec_t
+mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band, uint32 int_val)
+{
+ uint8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
+ uint8 rate = int_val & NRATE_RATE_MASK;
+ ratespec_t rspec;
+ bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
+ bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
+ bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
+ == NRATE_OVERRIDE_MCS_ONLY);
+ int bcmerror = 0;
+
+ if (!ismcs) {
+ return (ratespec_t) rate;
+ }
+
+ /* validate the combination of rate/mcs/stf is allowed */
+ if (N_ENAB(wlc->pub) && ismcs) {
+ /* mcs only allowed when nmode */
+ if (stf > PHY_TXC1_MODE_SDM) {
+ WL_ERROR(("wl%d: %s: Invalid stf\n", WLCWLUNIT(wlc),
+ __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+
+ /* mcs 32 is a special case, DUP mode 40 only */
+ if (rate == 32) {
+ if (!CHSPEC_IS40(wlc->home_chanspec) ||
+ ((stf != PHY_TXC1_MODE_SISO)
+ && (stf != PHY_TXC1_MODE_CDD))) {
+ WL_ERROR(("wl%d: %s: Invalid mcs 32\n",
+ WLCWLUNIT(wlc), __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+ /* mcs > 7 must use stf SDM */
+ } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
+ /* mcs > 7 must use stf SDM */
+ if (stf != PHY_TXC1_MODE_SDM) {
+ WL_TRACE(("wl%d: %s: enabling SDM mode for mcs %d\n", WLCWLUNIT(wlc), __func__, rate));
+ stf = PHY_TXC1_MODE_SDM;
+ }
+ } else {
+ /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
+ if ((stf > PHY_TXC1_MODE_STBC) ||
+ (!WLC_STBC_CAP_PHY(wlc)
+ && (stf == PHY_TXC1_MODE_STBC))) {
+ WL_ERROR(("wl%d: %s: Invalid STBC\n",
+ WLCWLUNIT(wlc), __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+ }
+ } else if (IS_OFDM(rate)) {
+ if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
+ WL_ERROR(("wl%d: %s: Invalid OFDM\n", WLCWLUNIT(wlc),
+ __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+ } else if (IS_CCK(rate)) {
+ if ((cur_band->bandtype != WLC_BAND_2G)
+ || (stf != PHY_TXC1_MODE_SISO)) {
+ WL_ERROR(("wl%d: %s: Invalid CCK\n", WLCWLUNIT(wlc),
+ __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+ } else {
+ WL_ERROR(("wl%d: %s: Unknown rate type\n", WLCWLUNIT(wlc),
+ __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+ /* make sure multiple antennae are available for non-siso rates */
+ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
+ WL_ERROR(("wl%d: %s: SISO antenna but !SISO request\n",
+ WLCWLUNIT(wlc), __func__));
+ bcmerror = BCME_RANGE;
+ goto done;
+ }
+
+ rspec = rate;
+ if (ismcs) {
+ rspec |= RSPEC_MIMORATE;
+ /* For STBC populate the STC field of the ratespec */
+ if (stf == PHY_TXC1_MODE_STBC) {
+ uint8 stc;
+ stc = 1; /* Nss for single stream is always 1 */
+ rspec |= (stc << RSPEC_STC_SHIFT);
+ }
+ }
+
+ rspec |= (stf << RSPEC_STF_SHIFT);
+
+ if (override_mcs_only)
+ rspec |= RSPEC_OVERRIDE_MCS_ONLY;
+
+ if (issgi)
+ rspec |= RSPEC_SHORT_GI;
+
+ if ((rate != 0)
+ && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, TRUE)) {
+ return rate;
+ }
+
+ return rspec;
+ done:
+ WL_ERROR(("Hoark\n"));
+ return rate;
+}
+
+/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
+static int
+wlc_duty_cycle_set(wlc_info_t *wlc, int duty_cycle, bool isOFDM,
+ bool writeToShm)
+{
+ int idle_busy_ratio_x_16 = 0;
+ uint offset =
+ isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
+ M_TX_IDLE_BUSY_RATIO_X_16_CCK;
+ if (duty_cycle > 100 || duty_cycle < 0) {
+ WL_ERROR(("wl%d: duty cycle value off limit\n",
+ wlc->pub->unit));
+ return BCME_RANGE;
+ }
+ if (duty_cycle)
+ idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
+ /* Only write to shared memory when wl is up */
+ if (writeToShm)
+ wlc_write_shm(wlc, offset, (uint16) idle_busy_ratio_x_16);
+
+ if (isOFDM)
+ wlc->tx_duty_cycle_ofdm = (uint16) duty_cycle;
+ else
+ wlc->tx_duty_cycle_cck = (uint16) duty_cycle;
+
+ return BCME_OK;
+}
+
+void
+wlc_pktengtx(wlc_info_t *wlc, wl_pkteng_t *pkteng, uint8 rate,
+ struct ether_addr *sa, uint32 wait_delay)
+{
+ bool suspend;
+ uint16 val = M_PKTENG_MODE_TX;
+ volatile uint16 frame_cnt_check;
+ uint8 counter = 0;
+
+ wlc_bmac_set_deaf(wlc->hw, TRUE);
+
+ suspend =
+ (0 == (R_REG(wlc->hw->osh, &wlc->regs->maccontrol) & MCTL_EN_MAC));
+ if (suspend)
+ wlc_enable_mac(wlc);
+
+ /* set nframes */
+ if (pkteng->nframes) {
+ /* retry counter is used to replay the packet */
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_FRMCNT_LO,
+ (pkteng->nframes & 0xffff));
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_FRMCNT_HI,
+ ((pkteng->nframes >> 16) & 0xffff));
+ val |= M_PKTENG_FRMCNT_VLD;
+ }
+
+ if (pkteng->length) {
+ /* DATA frame */
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_CTRL, val);
+ /* we write to M_MFGTEST_IFS the IFS required in 1/8us factor */
+ /* 10 : for factoring difference b/w Tx.crs and energy in air */
+ /* 44 : amount of time spent after TX_RRSP to frame start */
+ /* IFS */
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_IFS,
+ (pkteng->delay - 10) * 8 - 44);
+ } else {
+ /* CTS frame */
+ val |= M_PKTENG_MODE_TX_CTS;
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_IFS,
+ (uint16) pkteng->delay);
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_CTRL, val);
+ }
+
+ /* Wait for packets to finish */
+ frame_cnt_check = wlc_bmac_read_shm(wlc->hw, M_PKTENG_FRMCNT_LO);
+ while ((counter < 100) && (frame_cnt_check != 0)) {
+ OSL_DELAY(100);
+ frame_cnt_check =
+ wlc_bmac_read_shm(wlc->hw, M_PKTENG_FRMCNT_LO);
+ counter++;
+ }
+
+ wlc_bmac_write_shm(wlc->hw, M_PKTENG_CTRL, 0);
+
+ if (suspend)
+ wlc_suspend_mac_and_wait(wlc);
+
+ wlc_bmac_set_deaf(wlc->hw, FALSE);
+}
+
+/* Read a single uint16 from shared memory.
+ * SHM 'offset' needs to be an even address
+ */
+uint16 wlc_read_shm(wlc_info_t *wlc, uint offset)
+{
+ return wlc_bmac_read_shm(wlc->hw, offset);
+}
+
+/* Write a single uint16 to shared memory.
+ * SHM 'offset' needs to be an even address
+ */
+void wlc_write_shm(wlc_info_t *wlc, uint offset, uint16 v)
+{
+ wlc_bmac_write_shm(wlc->hw, offset, v);
+}
+
+/* Set a range of shared memory to a value.
+ * SHM 'offset' needs to be an even address and
+ * Range length 'len' must be an even number of bytes
+ */
+void wlc_set_shm(wlc_info_t *wlc, uint offset, uint16 v, int len)
+{
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+
+ wlc_bmac_set_shm(wlc->hw, offset, v, len);
+}
+
+/* Copy a buffer to shared memory.
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ */
+void wlc_copyto_shm(wlc_info_t *wlc, uint offset, const void *buf, int len)
+{
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+ wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+
+}
+
+/* Copy from shared memory to a buffer.
+ * SHM 'offset' needs to be an even address and
+ * Buffer length 'len' must be an even number of bytes
+ */
+void wlc_copyfrom_shm(wlc_info_t *wlc, uint offset, void *buf, int len)
+{
+ /* offset and len need to be even */
+ ASSERT((offset & 1) == 0);
+ ASSERT((len & 1) == 0);
+
+ if (len <= 0)
+ return;
+
+ wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+}
+
+/* wrapper BMAC functions to for HIGH driver access */
+void wlc_mctrl(wlc_info_t *wlc, uint32 mask, uint32 val)
+{
+ wlc_bmac_mctrl(wlc->hw, mask, val);
+}
+
+void wlc_corereset(wlc_info_t *wlc, uint32 flags)
+{
+ wlc_bmac_corereset(wlc->hw, flags);
+}
+
+void wlc_mhf(wlc_info_t *wlc, uint8 idx, uint16 mask, uint16 val, int bands)
+{
+ wlc_bmac_mhf(wlc->hw, idx, mask, val, bands);
+}
+
+uint16 wlc_mhf_get(wlc_info_t *wlc, uint8 idx, int bands)
+{
+ return wlc_bmac_mhf_get(wlc->hw, idx, bands);
+}
+
+int wlc_xmtfifo_sz_get(wlc_info_t *wlc, uint fifo, uint *blocks)
+{
+ return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks);
+}
+
+void wlc_write_template_ram(wlc_info_t *wlc, int offset, int len, void *buf)
+{
+ wlc_bmac_write_template_ram(wlc->hw, offset, len, buf);
+}
+
+void wlc_write_hw_bcntemplates(wlc_info_t *wlc, void *bcn, int len, bool both)
+{
+ wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both);
+}
+
+void
+wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset,
+ const struct ether_addr *addr)
+{
+ wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr);
+}
+
+void wlc_set_rcmta(wlc_info_t *wlc, int idx, const struct ether_addr *addr)
+{
+ wlc_bmac_set_rcmta(wlc->hw, idx, addr);
+}
+
+void wlc_read_tsf(wlc_info_t *wlc, uint32 *tsf_l_ptr, uint32 *tsf_h_ptr)
+{
+ wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr);
+}
+
+void wlc_set_cwmin(wlc_info_t *wlc, uint16 newmin)
+{
+ wlc->band->CWmin = newmin;
+ wlc_bmac_set_cwmin(wlc->hw, newmin);
+}
+
+void wlc_set_cwmax(wlc_info_t *wlc, uint16 newmax)
+{
+ wlc->band->CWmax = newmax;
+ wlc_bmac_set_cwmax(wlc->hw, newmax);
+}
+
+void wlc_fifoerrors(wlc_info_t *wlc)
+{
+
+ wlc_bmac_fifoerrors(wlc->hw);
+}
+
+/* Search mem rw utilities */
+
+void wlc_pllreq(wlc_info_t *wlc, bool set, mbool req_bit)
+{
+ wlc_bmac_pllreq(wlc->hw, set, req_bit);
+}
+
+void wlc_reset_bmac_done(wlc_info_t *wlc)
+{
+#ifdef WLC_HIGH_ONLY
+ wlc->reset_bmac_pending = FALSE;
+#endif
+}
+
+void wlc_ht_mimops_cap_update(wlc_info_t *wlc, uint8 mimops_mode)
+{
+ wlc->ht_cap.cap &= ~HT_CAP_MIMO_PS_MASK;
+ wlc->ht_cap.cap |= (mimops_mode << HT_CAP_MIMO_PS_SHIFT);
+
+ if (AP_ENAB(wlc->pub) && wlc->clk) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ }
+}
+
+/* check for the particular priority flow control bit being set */
+bool
+wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *q, int prio)
+{
+ uint prio_mask;
+
+ if (prio == ALLPRIO) {
+ prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
+ } else {
+ ASSERT(prio >= 0 && prio <= MAXPRIO);
+ prio_mask = NBITVAL(prio);
+ }
+
+ return (q->stopped & prio_mask) == prio_mask;
+}
+
+/* propogate the flow control to all interfaces using the given tx queue */
+void wlc_txflowcontrol(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, int prio)
+{
+ uint prio_bits;
+ uint cur_bits;
+
+ WL_ERROR(("%s: flow contro kicks in\n", __func__));
+
+ if (prio == ALLPRIO) {
+ prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
+ } else {
+ ASSERT(prio >= 0 && prio <= MAXPRIO);
+ prio_bits = NBITVAL(prio);
+ }
+
+ cur_bits = qi->stopped & prio_bits;
+
+ /* Check for the case of no change and return early
+ * Otherwise update the bit and continue
+ */
+ if (on) {
+ if (cur_bits == prio_bits) {
+ return;
+ }
+ mboolset(qi->stopped, prio_bits);
+ } else {
+ if (cur_bits == 0) {
+ return;
+ }
+ mboolclr(qi->stopped, prio_bits);
+ }
+
+ /* If there is a flow control override we will not change the external
+ * flow control state.
+ */
+ if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
+ return;
+ }
+
+ wlc_txflowcontrol_signal(wlc, qi, on, prio);
+}
+
+void
+wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on,
+ uint override)
+{
+ uint prev_override;
+
+ ASSERT(override != 0);
+ ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0);
+
+ prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
+
+ /* Update the flow control bits and do an early return if there is
+ * no change in the external flow control state.
+ */
+ if (on) {
+ mboolset(qi->stopped, override);
+ /* if there was a previous override bit on, then setting this
+ * makes no difference.
+ */
+ if (prev_override) {
+ return;
+ }
+
+ wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
+ } else {
+ mboolclr(qi->stopped, override);
+ /* clearing an override bit will only make a difference for
+ * flow control if it was the only bit set. For any other
+ * override setting, just return
+ */
+ if (prev_override != override) {
+ return;
+ }
+
+ if (qi->stopped == 0) {
+ wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+ } else {
+ int prio;
+
+ for (prio = MAXPRIO; prio >= 0; prio--) {
+ if (!mboolisset(qi->stopped, NBITVAL(prio)))
+ wlc_txflowcontrol_signal(wlc, qi, OFF,
+ prio);
+ }
+ }
+ }
+}
+
+static void wlc_txflowcontrol_reset(wlc_info_t *wlc)
+{
+ wlc_txq_info_t *qi;
+
+ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+ if (qi->stopped) {
+ wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+ qi->stopped = 0;
+ }
+ }
+}
+
+static void
+wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on,
+ int prio)
+{
+ wlc_if_t *wlcif;
+
+ for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
+ if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED)
+ wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
+ }
+}
+
+static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, osl_t *osh)
+{
+ wlc_txq_info_t *qi, *p;
+
+ qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit,
+ sizeof(wlc_txq_info_t));
+ if (qi == NULL) {
+ return NULL;
+ }
+
+ /* Have enough room for control packets along with HI watermark */
+ /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */
+ /* The watermark for flowcontrol to OS packets will remain the same */
+ pktq_init(&qi->q, WLC_PREC_COUNT,
+ (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT +
+ wlc->pub->psq_pkts_total);
+
+ /* add this queue to the the global list */
+ p = wlc->tx_queues;
+ if (p == NULL) {
+ wlc->tx_queues = qi;
+ } else {
+ while (p->next != NULL)
+ p = p->next;
+ p->next = qi;
+ }
+
+ return qi;
+}
+
+static void wlc_txq_free(wlc_info_t *wlc, osl_t *osh, wlc_txq_info_t *qi)
+{
+ wlc_txq_info_t *p;
+
+ if (qi == NULL)
+ return;
+
+ /* remove the queue from the linked list */
+ p = wlc->tx_queues;
+ if (p == qi)
+ wlc->tx_queues = p->next;
+ else {
+ while (p != NULL && p->next != qi)
+ p = p->next;
+ ASSERT(p->next == qi);
+ if (p != NULL)
+ p->next = p->next->next;
+ }
+
+ osl_mfree(osh, qi, sizeof(wlc_txq_info_t));
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h
new file mode 100644
index 000000000000..cf6ce4214f81
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h
@@ -0,0 +1,1039 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_h_
+#define _wlc_h_
+
+#include <wlc_types.h>
+
+#include <wl_dbg.h>
+#include <wlioctl.h>
+#include <wlc_event.h>
+#include <wlc_phy_hal.h>
+#include <wlc_channel.h>
+#ifdef WLC_SPLIT
+#include <bcm_rpc.h>
+#endif
+
+#include <wlc_bsscfg.h>
+
+#include <wlc_scb.h>
+
+#define MA_WINDOW_SZ 8 /* moving average window size */
+#define WL_HWRXOFF 38 /* chip rx buffer offset */
+#define INVCHANNEL 255 /* invalid channel */
+#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */
+#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */
+
+/* network protection config */
+#define WLC_PROT_G_SPEC 1 /* SPEC g protection */
+#define WLC_PROT_G_OVR 2 /* SPEC g prot override */
+#define WLC_PROT_G_USER 3 /* gmode specified by user */
+#define WLC_PROT_OVERLAP 4 /* overlap */
+#define WLC_PROT_N_USER 10 /* nmode specified by user */
+#define WLC_PROT_N_CFG 11 /* n protection */
+#define WLC_PROT_N_CFG_OVR 12 /* n protection override */
+#define WLC_PROT_N_NONGF 13 /* non-GF protection */
+#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */
+#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */
+#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */
+
+#define WLC_BITSCNT(x) bcm_bitcount((uint8 *)&(x), sizeof(uint8))
+
+/* Maximum wait time for a MAC suspend */
+#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
+
+/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable
+ */
+#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
+
+/* transmit buffer max headroom for protocol headers */
+#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
+
+/* For managing scan result lists */
+typedef struct wlc_bss_list {
+ uint count;
+ bool beacon; /* set for beacon, cleared for probe response */
+ wlc_bss_info_t *ptrs[MAXBSS];
+} wlc_bss_list_t;
+
+#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
+
+/* Double check that unsupported cores are not enabled */
+#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
+#error "Configuration for D11CONF includes unsupported versions."
+#endif /* Bad versions */
+
+#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev)
+
+/* values for shortslot_override */
+#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
+#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */
+#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */
+
+/* value for short/long and mixmode/greenfield preamble */
+
+#define WLC_LONG_PREAMBLE (0)
+#define WLC_SHORT_PREAMBLE (1 << 0)
+#define WLC_GF_PREAMBLE (1 << 1)
+#define WLC_MM_PREAMBLE (1 << 2)
+#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE))
+
+/* values for barker_preamble */
+#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */
+
+/* A fifo is full. Clear precedences related to that FIFO */
+#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo])
+
+/* Fifo is NOT full. Enable precedences for that FIFO */
+#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo])
+
+/* TxFrameID */
+/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
+/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
+#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
+#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
+#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
+#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
+#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
+#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
+
+/* promote boardrev */
+#define BOARDREV_PROMOTABLE 0xFF /* from */
+#define BOARDREV_PROMOTED 1 /* to */
+
+/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true
+ */
+#define WLC_PORTOPEN(cfg) \
+ (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \
+ (cfg)->wsec_portopen : TRUE)
+
+#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc)
+#define STAY_AWAKE(wlc) wlc_stay_awake(wlc)
+
+#define DATA_BLOCK_TX_SUPR (1 << 4)
+
+/* 802.1D Priority to TX FIFO number for wme */
+extern const uint8 prio2fifo[];
+
+/* Ucode MCTL_WAKE override bits */
+#define WLC_WAKE_OVERRIDE_CLKCTL 0x01
+#define WLC_WAKE_OVERRIDE_PHYREG 0x02
+#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04
+#define WLC_WAKE_OVERRIDE_TXFIFO 0x08
+#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10
+
+/* stuff pulled in from wlc.c */
+
+/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
+ * times; and if we run out, constant I_RU interrupts may cause lockup. We
+ * will still get error counts from rx0ovfl.
+ */
+#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
+/* default software intmasks */
+#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
+#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
+ MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
+ MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
+
+#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */
+#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */
+#define RETRY_LONG_DEF 4 /* Default Long retry count */
+#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */
+#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */
+
+#define MAXTXPKTS 6 /* max # pkts pending */
+
+/* frameburst */
+#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
+#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
+
+/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */
+#define EDCF_SHORT_S 0
+#define EDCF_SFB_S 4
+#define EDCF_LONG_S 8
+#define EDCF_LFB_S 12
+#define EDCF_SHORT_M BITFIELD_MASK(4)
+#define EDCF_SFB_M BITFIELD_MASK(4)
+#define EDCF_LONG_M BITFIELD_MASK(4)
+#define EDCF_LFB_M BITFIELD_MASK(4)
+
+#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT)
+#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB)
+#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG)
+#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB)
+
+#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \
+ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val))
+#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \
+ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val))
+#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \
+ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val))
+#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \
+ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val))
+
+/* PLL requests */
+#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */
+#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */
+#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */
+
+/* Do we support this rate? */
+#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, TRUE)
+
+/*
+ * Macros to check if AP or STA is active.
+ * AP Active means more than just configured: driver and BSS are "up";
+ * that is, we are beaconing/responding as an AP (aps_associated).
+ * STA Active similarly means the driver is up and a configured STA BSS
+ * is up: either associated (stas_associated) or trying.
+ *
+ * Macro definitions vary as per AP/STA ifdefs, allowing references to
+ * ifdef'd structure fields and constant values (0) for optimization.
+ * Make sure to enclose blocks of code such that any routines they
+ * reference can also be unused and optimized out by the linker.
+ */
+/* NOTE: References structure fields defined in wlc.h */
+#define AP_ACTIVE(wlc) (0)
+
+/*
+ * Detect Card removed.
+ * Even checking an sbconfig register read will not false trigger when the core is in reset.
+ * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy
+ * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern
+ * (some platforms return all 0).
+ * If clocks are present, call the sb routine which will figure out if the device is removed.
+ */
+#ifdef WLC_HIGH_ONLY
+#define DEVICEREMOVED(wlc) (!wlc->device_present)
+#else
+#define DEVICEREMOVED(wlc) \
+ ((wlc->hw->clk) ? \
+ ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \
+ (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \
+ (si_deviceremoved(wlc->hw->sih)))
+#endif /* WLC_HIGH_ONLY */
+
+#define WLCWLUNIT(wlc) ((wlc)->pub->unit)
+
+typedef struct wlc_protection {
+ bool _g; /* use g spec protection, driver internal */
+ int8 g_override; /* override for use of g spec protection */
+ uint8 gmode_user; /* user config gmode, operating band->gmode is different */
+ int8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */
+ int8 nmode_user; /* user config nmode, operating pub->nmode is different */
+ int8 n_cfg; /* use OFDM protection on MIMO frames */
+ int8 n_cfg_override; /* override for use of N protection */
+ bool nongf; /* non-GF present protection */
+ int8 nongf_override; /* override for use of GF protection */
+ int8 n_pam_override; /* override for preamble: MM or GF */
+ bool n_obss; /* indicated OBSS Non-HT STA present */
+
+ uint longpre_detect_timeout; /* #sec until long preamble bcns gone */
+ uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */
+ /* only is gone */
+ uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */
+ uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */
+ uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */
+ uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */
+ uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */
+ uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */
+ uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */
+ uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */
+ uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */
+} wlc_protection_t;
+
+/* anything affects the single/dual streams/antenna operation */
+typedef struct wlc_stf {
+ uint8 hw_txchain; /* HW txchain bitmap cfg */
+ uint8 txchain; /* txchain bitmap being used */
+ uint8 txstreams; /* number of txchains being used */
+
+ uint8 hw_rxchain; /* HW rxchain bitmap cfg */
+ uint8 rxchain; /* rxchain bitmap being used */
+ uint8 rxstreams; /* number of rxchains being used */
+
+ uint8 ant_rx_ovr; /* rx antenna override */
+ int8 txant; /* userTx antenna setting */
+ uint16 phytxant; /* phyTx antenna setting in txheader */
+
+ uint8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */
+ bool ss_algosel_auto; /* if TRUE, use wlc->stf->ss_algo_channel; */
+ /* else use wlc->band->stf->ss_mode_band; */
+ uint16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */
+ uint8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */
+
+ uint8 rxchain_restore_delay; /* delay time to restore default rxchain */
+
+ int8 ldpc; /* AUTO/ON/OFF ldpc cap supported */
+ uint8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */
+ int8 spatial_policy;
+} wlc_stf_t;
+
+#define WLC_STF_SS_STBC_TX(wlc, scb) \
+ (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \
+ (SCB_STBC_CAP((scb)) && \
+ (wlc)->band->band_stf_stbc_tx == AUTO && \
+ isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
+
+#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3))
+
+#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \
+ WLCISLCNPHY(wlc->band))
+
+#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT)
+#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT)
+#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan))
+
+/* wlc_bss_info flag bit values */
+#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */
+
+/* Flags used in wlc_txq_info.stopped */
+#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */
+#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */
+#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */
+
+#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */
+#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */
+
+/*
+ * core state (mac)
+ */
+typedef struct wlccore {
+#ifdef WLC_LOW
+ uint coreidx; /* # sb enumerated core */
+
+ /* fifo */
+ uint *txavail[NFIFO]; /* # tx descriptors available */
+ int16 txpktpend[NFIFO]; /* tx admission control */
+#endif /* WLC_LOW */
+
+ macstat_t *macstat_snapshot; /* mac hw prev read values */
+} wlccore_t;
+
+/*
+ * band state (phy+ana+radio)
+ */
+typedef struct wlcband {
+ int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */
+ uint bandunit; /* bandstate[] index */
+
+ uint16 phytype; /* phytype */
+ uint16 phyrev;
+ uint16 radioid;
+ uint16 radiorev;
+ wlc_phy_t *pi; /* pointer to phy specific information */
+ bool abgphy_encore;
+
+ uint8 gmode; /* currently active gmode (see wlioctl.h) */
+
+ struct scb *hwrs_scb; /* permanent scb for hw rateset */
+
+ wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */
+
+ ratespec_t rspec_override; /* 802.11 rate override */
+ ratespec_t mrspec_override; /* multicast rate override */
+ uint8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
+ int8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
+ wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */
+ uint8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */
+ bool mimo_cap_40; /* 40 MHz cap enabled on this band */
+ int8 antgain; /* antenna gain from srom */
+
+ uint16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */
+ uint16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */
+ uint16 bcntsfoff; /* beacon tsf offset */
+} wlcband_t;
+
+/* generic function callback takes just one arg */
+typedef void (*cb_fn_t) (void *);
+
+/* tx completion callback takes 3 args */
+typedef void (*pkcb_fn_t) (wlc_info_t *wlc, uint txstatus, void *arg);
+
+typedef struct pkt_cb {
+ pkcb_fn_t fn; /* function to call when tx frame completes */
+ void *arg; /* void arg for fn */
+ uint8 nextidx; /* index of next call back if threading */
+ bool entered; /* recursion check */
+} pkt_cb_t;
+
+ /* module control blocks */
+typedef struct modulecb {
+ char name[32]; /* module name : NULL indicates empty array member */
+ const bcm_iovar_t *iovars; /* iovar table */
+ void *hdl; /* handle passed when handler 'doiovar' is called */
+ watchdog_fn_t watchdog_fn; /* watchdog handler */
+ iovar_fn_t iovar_fn; /* iovar handler */
+ down_fn_t down_fn; /* down handler. Note: the int returned
+ * by the down function is a count of the
+ * number of timers that could not be
+ * freed.
+ */
+} modulecb_t;
+
+ /* dump control blocks */
+typedef struct dumpcb_s {
+ const char *name; /* dump name */
+ dump_fn_t dump_fn; /* 'wl dump' handler */
+ void *dump_fn_arg;
+ struct dumpcb_s *next;
+} dumpcb_t;
+
+/* virtual interface */
+struct wlc_if {
+ wlc_if_t *next;
+ uint8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */
+ uint8 index; /* assigned in wl_add_if(), index of the wlif if any,
+ * not necessarily corresponding to bsscfg._idx or
+ * AID2PVBMAP(scb).
+ */
+ uint8 flags; /* flags for the interface */
+ wl_if_t *wlif; /* pointer to wlif */
+ struct wlc_txq_info *qi; /* pointer to associated tx queue */
+ union {
+ struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */
+ struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */
+ } u;
+};
+
+/* flags for the interface */
+#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */
+
+#ifdef WLC_LOW
+typedef struct wlc_hwband {
+ int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */
+ uint bandunit; /* bandstate[] index */
+ uint16 mhfs[MHFMAX]; /* MHF array shadow */
+ uint8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
+ uint16 CWmin;
+ uint16 CWmax;
+ uint32 core_flags;
+
+ uint16 phytype; /* phytype */
+ uint16 phyrev;
+ uint16 radioid;
+ uint16 radiorev;
+ wlc_phy_t *pi; /* pointer to phy specific information */
+ bool abgphy_encore;
+} wlc_hwband_t;
+#endif /* WLC_LOW */
+
+struct wlc_hw_info {
+#ifdef WLC_SPLIT
+ rpc_info_t *rpc; /* Handle to RPC module */
+#endif
+ osl_t *osh; /* pointer to os handle */
+ bool _piomode; /* true if pio mode */
+ wlc_info_t *wlc;
+
+ /* fifo */
+ hnddma_t *di[NFIFO]; /* hnddma handles, per fifo */
+
+#ifdef WLC_LOW
+ uint unit; /* device instance number */
+
+ /* version info */
+ uint16 vendorid; /* PCI vendor id */
+ uint16 deviceid; /* PCI device id */
+ uint corerev; /* core revision */
+ uint8 sromrev; /* version # of the srom */
+ uint16 boardrev; /* version # of particular board */
+ uint32 boardflags; /* Board specific flags from srom */
+ uint32 boardflags2; /* More board flags if sromrev >= 4 */
+ uint32 machwcap; /* MAC capabilities (corerev >= 13) */
+ uint32 machwcap_backup; /* backup of machwcap (corerev >= 13) */
+ uint16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */
+
+ si_t *sih; /* SB handle (cookie for siutils calls) */
+ char *vars; /* "environment" name=value */
+ uint vars_size; /* size of vars, free vars on detach */
+ d11regs_t *regs; /* pointer to device registers */
+ void *physhim; /* phy shim layer handler */
+ void *phy_sh; /* pointer to shared phy state */
+ wlc_hwband_t *band; /* pointer to active per-band state */
+ wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */
+ uint16 bmac_phytxant; /* cache of high phytxant state */
+ bool shortslot; /* currently using 11g ShortSlot timing */
+ uint16 SRL; /* 802.11 dot11ShortRetryLimit */
+ uint16 LRL; /* 802.11 dot11LongRetryLimit */
+ uint16 SFBL; /* Short Frame Rate Fallback Limit */
+ uint16 LFBL; /* Long Frame Rate Fallback Limit */
+
+ bool up; /* d11 hardware up and running */
+ uint now; /* # elapsed seconds */
+ uint _nbands; /* # bands supported */
+ chanspec_t chanspec; /* bmac chanspec shadow */
+
+ uint *txavail[NFIFO]; /* # tx descriptors available */
+ uint16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
+
+ mbool pllreq; /* pll requests to keep PLL on */
+
+ uint8 suspended_fifos; /* Which TX fifo to remain awake for */
+ uint32 maccontrol; /* Cached value of maccontrol */
+ uint mac_suspend_depth; /* current depth of mac_suspend levels */
+ uint32 wake_override; /* Various conditions to force MAC to WAKE mode */
+ uint32 mute_override; /* Prevent ucode from sending beacons */
+ struct ether_addr etheraddr; /* currently configured ethernet address */
+ uint32 led_gpio_mask; /* LED GPIO Mask */
+ bool noreset; /* true= do not reset hw, used by WLC_OUT */
+ bool forcefastclk; /* true if the h/w is forcing the use of fast clk */
+ bool clk; /* core is out of reset and has clock */
+ bool sbclk; /* sb has clock */
+ bmac_pmq_t *bmac_pmq; /* bmac PM states derived from ucode PMQ */
+ bool phyclk; /* phy is out of reset and has clock */
+ bool dma_lpbk; /* core is in DMA loopback */
+
+#ifdef BCMSDIO
+ void *sdh;
+#endif
+ bool ucode_loaded; /* TRUE after ucode downloaded */
+
+#ifdef WLC_LOW_ONLY
+ struct wl_timer *wdtimer; /* timer for watchdog routine */
+ struct ether_addr orig_etheraddr; /* original hw ethernet address */
+ uint16 rpc_dngl_agg; /* rpc agg control for dongle */
+ uint32 mem_required_def; /* memory required to replenish RX DMA ring */
+ uint32 mem_required_lower; /* memory required with lower RX bound */
+ uint32 mem_required_least; /* minimum memory requirement to handle RX */
+
+#endif /* WLC_LOW_ONLY */
+
+ uint8 hw_stf_ss_opmode; /* STF single stream operation mode */
+ uint8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
+ * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+ */
+ uint32 antsel_avail; /* put antsel_info_t here if more info is needed */
+#endif /* WLC_LOW */
+};
+
+/* TX Queue information
+ *
+ * Each flow of traffic out of the device has a TX Queue with independent
+ * flow control. Several interfaces may be associated with a single TX Queue
+ * if they belong to the same flow of traffic from the device. For multi-channel
+ * operation there are independent TX Queues for each channel.
+ */
+typedef struct wlc_txq_info {
+ struct wlc_txq_info *next;
+ struct pktq q;
+ uint stopped; /* tx flow control bits */
+} wlc_txq_info_t;
+
+/*
+ * Principal common (os-independent) software data structure.
+ */
+struct wlc_info {
+ wlc_pub_t *pub; /* pointer to wlc public state */
+ osl_t *osh; /* pointer to os handle */
+ struct wl_info *wl; /* pointer to os-specific private state */
+ d11regs_t *regs; /* pointer to device registers */
+
+ wlc_hw_info_t *hw; /* HW related state used primarily by BMAC */
+#ifdef WLC_SPLIT
+ rpc_info_t *rpc; /* Handle to RPC module */
+#endif
+
+ /* clock */
+ int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */
+ uint16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */
+
+ /* interrupt */
+ uint32 macintstatus; /* bit channel between isr and dpc */
+ uint32 macintmask; /* sw runtime master macintmask value */
+ uint32 defmacintmask; /* default "on" macintmask value */
+
+ /* up and down */
+ bool device_present; /* (removable) device is present */
+
+ bool clk; /* core is out of reset and has clock */
+
+ /* multiband */
+ wlccore_t *core; /* pointer to active io core */
+ wlcband_t *band; /* pointer to active per-band state */
+ wlccore_t *corestate; /* per-core state (one per hw core) */
+ wlcband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */
+
+ bool war16165; /* PCI slow clock 16165 war flag */
+
+ bool tx_suspended; /* data fifos need to remain suspended */
+
+ uint txpend16165war;
+
+ /* packet queue */
+ uint qvalid; /* DirFrmQValid and BcMcFrmQValid */
+
+ /* Regulatory power limits */
+ int8 txpwr_local_max; /* regulatory local txpwr max */
+ uint8 txpwr_local_constraint; /* local power contraint in dB */
+
+#ifdef WLC_HIGH_ONLY
+ rpctx_info_t *rpctx; /* RPC TX module */
+ bool reset_bmac_pending; /* bmac reset is in progressing */
+ uint32 rpc_agg; /* host agg: bit 16-31, bmac agg: bit 0-15 */
+ uint32 rpc_msglevel; /* host rpc: bit 16-31, bmac rpc: bit 0-15 */
+#endif
+
+ ampdu_info_t *ampdu; /* ampdu module handler */
+ antsel_info_t *asi; /* antsel module handler */
+ wlc_cm_info_t *cmi; /* channel manager module handler */
+
+ void *btparam; /* bus type specific cookie */
+
+ uint vars_size; /* size of vars, free vars on detach */
+
+ uint16 vendorid; /* PCI vendor id */
+ uint16 deviceid; /* PCI device id */
+ uint ucode_rev; /* microcode revision */
+
+ uint32 machwcap; /* MAC capabilities, BMAC shadow */
+
+ struct ether_addr perm_etheraddr; /* original sprom local ethernet address */
+
+ bool bandlocked; /* disable auto multi-band switching */
+ bool bandinit_pending; /* track band init in auto band */
+
+ bool radio_monitor; /* radio timer is running */
+ bool down_override; /* true=down */
+ bool going_down; /* down path intermediate variable */
+
+ bool mpc; /* enable minimum power consumption */
+ uint8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */
+ uint8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */
+ uint8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */
+ uint8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */
+
+ /* timer */
+ struct wl_timer *wdtimer; /* timer for watchdog routine */
+ uint fast_timer; /* Periodic timeout for 'fast' timer */
+ uint slow_timer; /* Periodic timeout for 'slow' timer */
+ uint glacial_timer; /* Periodic timeout for 'glacial' timer */
+ uint phycal_mlo; /* last time measurelow calibration was done */
+ uint phycal_txpower; /* last time txpower calibration was done */
+
+ struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */
+ struct wl_timer *pspoll_timer; /* periodic pspoll timer */
+
+ /* promiscuous */
+ bool monitor; /* monitor (MPDU sniffing) mode */
+ bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */
+ bool bcnmisc_scan; /* bcns promisc mode override for scan */
+ bool bcnmisc_monitor; /* bcns promisc mode override for monitor */
+
+ uint8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */
+
+ /* driver feature */
+ bool _rifs; /* enable per-packet rifs */
+ int32 rifs_advert; /* RIFS mode advertisement */
+ int8 sgi_tx; /* sgi tx */
+ bool wet; /* true if wireless ethernet bridging mode */
+
+ /* AP-STA synchronization, power save */
+ bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */
+ bool PM_override; /* no power-save flag, override PM(user input) */
+ bool PMenabled; /* current power-management state (CAM or PS) */
+ bool PMpending; /* waiting for tx status with PM indicated set */
+ bool PMblocked; /* block any PSPolling in PS mode, used to buffer
+ * AP traffic, also used to indicate in progress
+ * of scan, rm, etc. off home channel activity.
+ */
+ bool PSpoll; /* whether there is an outstanding PS-Poll frame */
+ uint8 PM; /* power-management mode (CAM, PS or FASTPS) */
+ bool PMawakebcn; /* bcn recvd during current waking state */
+
+ bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */
+ bool wake; /* host-specified PS-mode sleep state */
+ uint8 pspoll_prd; /* pspoll interval in milliseconds */
+ uint8 bcn_li_bcn; /* beacon listen interval in # beacons */
+ uint8 bcn_li_dtim; /* beacon listen interval in # dtims */
+
+ bool WDarmed; /* watchdog timer is armed */
+ uint32 WDlast; /* last time wlc_watchdog() was called */
+
+ /* WME */
+ ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */
+ bool wme_apsd; /* enable Advanced Power Save Delivery */
+ ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */
+ uint16 edcf_txop[AC_COUNT]; /* current txop for each ac */
+ wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA
+ * contains parameters in use locally, and on
+ * AP contains parameters advertised to STA
+ * in beacons and assoc responses.
+ */
+ bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */
+ uint16 wme_retries[AC_COUNT]; /* per-AC retry limits */
+
+ int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */
+ uint16 tx_prec_map; /* Precedence map based on HW FIFO space */
+ uint16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */
+
+ /* BSS Configurations */
+ wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and
+ * always valid
+ */
+ wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */
+ uint8 stas_associated; /* count of ASSOCIATED STA bsscfgs */
+ uint8 aps_associated; /* count of UP AP bsscfgs */
+ uint8 block_datafifo; /* prohibit posting frames to data fifos */
+ bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */
+
+ /* tx queue */
+ wlc_txq_info_t *tx_queues; /* common TX Queue list */
+
+ /* event */
+ wlc_eventq_t *eventq; /* event queue for deferred processing */
+
+ /* security */
+ wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */
+ wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */
+ bool wsec_swkeys; /* indicates that all keys should be
+ * treated as sw keys (used for debugging)
+ */
+ modulecb_t *modulecb;
+ dumpcb_t *dumpcb_head;
+
+ uint8 mimoft; /* SIGN or 11N */
+ uint8 mimo_band_bwcap; /* bw cap per band type */
+ int8 txburst_limit_override; /* tx burst limit override */
+ uint16 txburst_limit; /* tx burst limit value */
+ int8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */
+ int8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */
+ int8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */
+ ht_cap_ie_t ht_cap; /* HT CAP IE being advertised by this node */
+ ht_add_ie_t ht_add; /* HT ADD IE being used by this node */
+
+ uint seckeys; /* 54 key table shm address */
+ uint tkmickeys; /* 12 TKIP MIC key table shm address */
+
+ wlc_bss_info_t *default_bss; /* configured BSS parameters */
+
+ uint16 AID; /* association ID */
+ uint16 counter; /* per-sdu monotonically increasing counter */
+ uint16 mc_fid_counter; /* BC/MC FIFO frame ID counter */
+
+ bool ibss_allowed; /* FALSE, all IBSS will be ignored during a scan
+ * and the driver will not allow the creation of
+ * an IBSS network
+ */
+ bool ibss_coalesce_allowed;
+
+ char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d
+ * auto-country mode
+ */
+ char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d
+ * auto-country mode
+ */
+#ifdef BCMDBG
+ bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */
+#endif
+
+ uint16 prb_resp_timeout; /* do not send prb resp if request older than this,
+ * 0 = disable
+ */
+
+ wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if
+ * specifed
+ */
+
+ chanspec_t home_chanspec; /* shared home chanspec */
+
+ /* PHY parameters */
+ chanspec_t chanspec; /* target operational channel */
+ uint16 usr_fragthresh; /* user configured fragmentation threshold */
+ uint16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */
+ uint16 RTSThresh; /* 802.11 dot11RTSThreshold */
+ uint16 SRL; /* 802.11 dot11ShortRetryLimit */
+ uint16 LRL; /* 802.11 dot11LongRetryLimit */
+ uint16 SFBL; /* Short Frame Rate Fallback Limit */
+ uint16 LFBL; /* Long Frame Rate Fallback Limit */
+
+ /* network config */
+ bool shortpreamble; /* currently operating with CCK ShortPreambles */
+ bool shortslot; /* currently using 11g ShortSlot timing */
+ int8 barker_preamble; /* current Barker Preamble Mode */
+ int8 shortslot_override; /* 11g ShortSlot override */
+ bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */
+ bool barker_overlap_control; /* TRUE: be aware of overlapping BSSs for barker */
+ bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */
+ bool legacy_probe; /* restricts probe requests to CCK rates */
+
+ wlc_protection_t *protection;
+ int8 PLCPHdr_override; /* 802.11b Preamble Type override */
+
+ wlc_stf_t *stf;
+
+ pkt_cb_t *pkt_callback; /* tx completion callback handlers */
+
+ uint32 txretried; /* tx retried number in one msdu */
+
+ ratespec_t bcn_rspec; /* save bcn ratespec purpose */
+
+ bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */
+ struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */
+ uint32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms)
+ * 0 == disable
+ */
+ ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null
+ * Trigger frames can be send
+ */
+ wlc_ap_info_t *ap;
+
+ uint8 htphy_membership; /* HT PHY membership */
+
+ bool _regulatory_domain; /* 802.11d enabled? */
+
+ uint8 mimops_PM;
+
+ uint8 txpwr_percent; /* power output percentage */
+
+ uint8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */
+
+ uint tempsense_lasttime;
+
+ uint16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */
+ uint16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */
+
+ uint16 next_bsscfg_ID;
+
+ wlc_if_t *wlcif_list; /* linked list of wlc_if structs */
+ wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */
+ uint32 mpc_dur; /* total time (ms) in mpc mode except for the
+ * portion since radio is turned off last time
+ */
+ uint32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last
+ * time
+ */
+ bool pr80838_war;
+ uint hwrxoff;
+};
+
+/* antsel module specific state */
+struct antsel_info {
+ wlc_info_t *wlc; /* pointer to main wlc structure */
+ wlc_pub_t *pub; /* pointer to public fn */
+ uint8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
+ * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+ */
+ uint8 antsel_antswitch; /* board level antenna switch type */
+ bool antsel_avail; /* Ant selection availability (SROM based) */
+ wlc_antselcfg_t antcfg_11n; /* antenna configuration */
+ wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */
+};
+
+#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
+#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
+
+#define IS_MBAND_UNLOCKED(wlc) \
+ ((NBANDS(wlc) > 1) && !(wlc)->bandlocked)
+
+#ifdef WLC_LOW
+#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi)
+#else
+#define WLC_BAND_PI_RADIO_CHANSPEC (wlc->chanspec)
+#endif
+
+/* sum the individual fifo tx pending packet counts */
+#if defined(WLC_HIGH_ONLY)
+#define TXPKTPENDTOT(wlc) (wlc_rpctx_txpktpend((wlc)->rpctx, 0, TRUE))
+#define TXPKTPENDGET(wlc, fifo) (wlc_rpctx_txpktpend((wlc)->rpctx, (fifo), FALSE))
+#define TXPKTPENDINC(wlc, fifo, val) (wlc_rpctx_txpktpendinc((wlc)->rpctx, (fifo), (val)))
+#define TXPKTPENDDEC(wlc, fifo, val) (wlc_rpctx_txpktpenddec((wlc)->rpctx, (fifo), (val)))
+#define TXPKTPENDCLR(wlc, fifo) (wlc_rpctx_txpktpendclr((wlc)->rpctx, (fifo)))
+#define TXAVAIL(wlc, fifo) (wlc_rpctx_txavail((wlc)->rpctx, (fifo)))
+#define GETNEXTTXP(wlc, _queue) (wlc_rpctx_getnexttxp((wlc)->rpctx, (_queue)))
+
+#else
+#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \
+ (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3])
+#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)])
+#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val))
+#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val))
+#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0)
+#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)])
+#define GETNEXTTXP(wlc, _queue) \
+ dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED)
+#endif /* WLC_HIGH_ONLY */
+
+#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \
+ ((len1 == len2) && !bcmp(ssid1, ssid2, len1))
+
+/* API shared by both WLC_HIGH and WLC_LOW driver */
+extern void wlc_high_dpc(wlc_info_t *wlc, uint32 macintstatus);
+extern void wlc_fatal_error(wlc_info_t *wlc);
+extern void wlc_bmac_rpc_watchdog(wlc_info_t *wlc);
+extern void wlc_recv(wlc_info_t *wlc, void *p);
+extern bool wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, uint32 frm_tx2);
+extern void wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit,
+ int8 txpktpend);
+extern void wlc_txfifo_complete(wlc_info_t *wlc, uint fifo, int8 txpktpend);
+extern void wlc_info_init(wlc_info_t *wlc, int unit);
+extern void wlc_print_txstatus(tx_status_t *txs);
+extern int wlc_xmtfifo_sz_get(wlc_info_t *wlc, uint fifo, uint *blocks);
+extern void wlc_write_template_ram(wlc_info_t *wlc, int offset, int len,
+ void *buf);
+extern void wlc_write_hw_bcntemplates(wlc_info_t *wlc, void *bcn, int len,
+ bool both);
+#if defined(BCMDBG)
+extern void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr);
+#endif
+extern void wlc_set_rcmta(wlc_info_t *wlc, int idx,
+ const struct ether_addr *addr);
+extern void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset,
+ const struct ether_addr *addr);
+extern void wlc_read_tsf(wlc_info_t *wlc, uint32 *tsf_l_ptr,
+ uint32 *tsf_h_ptr);
+extern void wlc_set_cwmin(wlc_info_t *wlc, uint16 newmin);
+extern void wlc_set_cwmax(wlc_info_t *wlc, uint16 newmax);
+extern void wlc_fifoerrors(wlc_info_t *wlc);
+extern void wlc_pllreq(wlc_info_t *wlc, bool set, mbool req_bit);
+extern void wlc_reset_bmac_done(wlc_info_t *wlc);
+extern void wlc_protection_upd(wlc_info_t *wlc, uint idx, int val);
+extern void wlc_hwtimer_gptimer_set(wlc_info_t *wlc, uint us);
+extern void wlc_hwtimer_gptimer_abort(wlc_info_t *wlc);
+extern void wlc_pktengtx(wlc_info_t *wlc, wl_pkteng_t *pkteng, uint8 rate,
+ struct ether_addr *sa, uint32 wait_delay);
+
+#if defined(BCMDBG)
+extern void wlc_print_rxh(d11rxhdr_t *rxh);
+extern void wlc_print_hdrs(wlc_info_t *wlc, const char *prefix, uint8 *frame,
+ d11txh_t *txh, d11rxhdr_t *rxh, uint len);
+extern void wlc_print_txdesc(d11txh_t *txh);
+#endif
+#if defined(BCMDBG)
+extern void wlc_print_dot11_mac_hdr(uint8 *buf, int len);
+#endif
+
+#ifdef WLC_LOW
+extern void wlc_setxband(wlc_hw_info_t *wlc_hw, uint bandunit);
+extern void wlc_coredisable(wlc_hw_info_t *wlc_hw);
+#endif
+
+extern bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rate, int band,
+ bool verbose);
+extern void wlc_ap_upd(wlc_info_t *wlc);
+
+/* helper functions */
+extern void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg);
+extern int wlc_set_gmode(wlc_info_t *wlc, uint8 gmode, bool config);
+
+extern void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc);
+extern void wlc_mac_bcn_promisc(wlc_info_t *wlc);
+extern void wlc_mac_promisc(wlc_info_t *wlc);
+extern void wlc_txflowcontrol(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on,
+ int prio);
+extern void wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi,
+ bool on, uint override);
+extern bool wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *qi,
+ int prio);
+extern void wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi);
+extern int wlc_prep_pdu(wlc_info_t *wlc, void *pdu, uint *fifo);
+
+extern uint16 wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec,
+ uint mac_len);
+extern ratespec_t wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec,
+ bool use_rspec, uint16 mimo_ctlchbw);
+extern uint16 wlc_compute_rtscts_dur(wlc_info_t *wlc, bool cts_only,
+ ratespec_t rts_rate, ratespec_t frame_rate,
+ uint8 rts_preamble_type,
+ uint8 frame_preamble_type, uint frame_len,
+ bool ba);
+
+extern void wlc_tbtt(wlc_info_t *wlc, d11regs_t *regs);
+
+#if defined(BCMDBG)
+extern void wlc_dump_ie(wlc_info_t *wlc, bcm_tlv_t *ie, struct bcmstrbuf *b);
+#endif
+
+extern bool wlc_ps_check(wlc_info_t *wlc);
+extern void wlc_reprate_init(wlc_info_t *wlc);
+extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg);
+extern void wlc_uint64_sub(uint32 *a_high, uint32 *a_low, uint32 b_high,
+ uint32 b_low);
+extern uint32 wlc_calc_tbtt_offset(uint32 bi, uint32 tsf_h, uint32 tsf_l);
+
+/* Shared memory access */
+extern void wlc_write_shm(wlc_info_t *wlc, uint offset, uint16 v);
+extern uint16 wlc_read_shm(wlc_info_t *wlc, uint offset);
+extern void wlc_set_shm(wlc_info_t *wlc, uint offset, uint16 v, int len);
+extern void wlc_copyto_shm(wlc_info_t *wlc, uint offset, const void *buf,
+ int len);
+extern void wlc_copyfrom_shm(wlc_info_t *wlc, uint offset, void *buf, int len);
+
+extern void wlc_update_beacon(wlc_info_t *wlc);
+extern void wlc_bss_update_beacon(wlc_info_t *wlc, struct wlc_bsscfg *bsscfg);
+
+extern void wlc_update_probe_resp(wlc_info_t *wlc, bool suspend);
+extern void wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg,
+ bool suspend);
+
+extern bool wlc_ismpc(wlc_info_t *wlc);
+extern bool wlc_is_non_delay_mpc(wlc_info_t *wlc);
+extern void wlc_radio_mpc_upd(wlc_info_t *wlc);
+extern bool wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec);
+extern bool wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, void *pkt,
+ int prec, bool head);
+extern uint16 wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec);
+extern void wlc_compute_plcp(wlc_info_t *wlc, ratespec_t rate, uint length,
+ uint8 *plcp);
+extern uint wlc_calc_frame_time(wlc_info_t *wlc, ratespec_t ratespec,
+ uint8 preamble_type, uint mac_len);
+
+extern void wlc_set_chanspec(wlc_info_t *wlc, chanspec_t chanspec);
+
+extern bool wlc_timers_init(wlc_info_t *wlc, int unit);
+
+extern const bcm_iovar_t wlc_iovars[];
+
+extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, uint32 actionid,
+ const char *name, void *params, uint p_len, void *arg,
+ int len, int val_size, wlc_if_t *wlcif);
+
+#if defined(BCMDBG)
+extern void wlc_print_ies(wlc_info_t *wlc, uint8 *ies, uint ies_len);
+#endif
+
+extern int wlc_set_nmode(wlc_info_t *wlc, int32 nmode);
+extern void wlc_ht_mimops_cap_update(wlc_info_t *wlc, uint8 mimops_mode);
+extern void wlc_mimops_action_ht_send(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg,
+ uint8 mimops_mode);
+
+extern void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot);
+extern void wlc_set_bssid(wlc_bsscfg_t *cfg);
+extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend);
+extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg,
+ bool suspend);
+
+extern void wlc_set_ratetable(wlc_info_t *wlc);
+extern int wlc_set_mac(wlc_bsscfg_t *cfg);
+extern void wlc_beacon_phytxctl_txant_upd(wlc_info_t *wlc,
+ ratespec_t bcn_rate);
+extern void wlc_mod_prb_rsp_rate_table(wlc_info_t *wlc, uint frame_len);
+extern ratespec_t wlc_lowest_basic_rspec(wlc_info_t *wlc, wlc_rateset_t *rs);
+extern uint16 wlc_compute_bcntsfoff(wlc_info_t *wlc, ratespec_t rspec,
+ bool short_preamble, bool phydelay);
+extern void wlc_radio_disable(wlc_info_t *wlc);
+extern void wlc_bcn_li_upd(wlc_info_t *wlc);
+
+extern int wlc_get_revision_info(wlc_info_t *wlc, void *buf, uint len);
+extern void wlc_out(wlc_info_t *wlc);
+extern void wlc_set_home_chanspec(wlc_info_t *wlc, chanspec_t chanspec);
+extern void wlc_watchdog_upd(wlc_info_t *wlc, bool tbtt);
+extern bool wlc_ps_allowed(wlc_info_t *wlc);
+extern bool wlc_stay_awake(wlc_info_t *wlc);
+extern void wlc_wme_initparams_sta(wlc_info_t *wlc, wme_param_ie_t *pe);
+
+extern void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list);
+#endif /* _wlc_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c
new file mode 100644
index 000000000000..5a41da14d44b
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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.
+ */
+
+/*
+ * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer.
+ * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY.
+ * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the
+ * access to wlc_hw pointer.
+ */
+
+#include <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <bcmdefs.h>
+#include <osl.h>
+
+#include <proto/802.11.h>
+#include <bcmwifi.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <hnddma.h>
+#include <hndpmu.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_channel.h>
+#include <bcmsrom.h>
+#include <wlc_key.h>
+
+#include <wlc_mac80211.h>
+
+#include <wlc_bmac.h>
+#include <wlc_phy_shim.h>
+#include <wlc_phy_hal.h>
+#include <wl_export.h>
+
+/* PHY SHIM module specific state */
+struct wlc_phy_shim_info {
+ wlc_hw_info_t *wlc_hw; /* pointer to main wlc_hw structure */
+ void *wlc; /* pointer to main wlc structure */
+ void *wl; /* pointer to os-specific private state */
+};
+
+wlc_phy_shim_info_t *BCMATTACHFN(wlc_phy_shim_attach) (wlc_hw_info_t *wlc_hw,
+ void *wl, void *wlc) {
+ wlc_phy_shim_info_t *physhim = NULL;
+
+ physhim = (wlc_phy_shim_info_t *)MALLOC(wlc_hw->osh,
+ sizeof(wlc_phy_shim_info_t));
+ if (!physhim) {
+ WL_ERROR(("wl%d: wlc_phy_shim_attach: out of mem, malloced %d bytes\n", wlc_hw->unit, MALLOCED(wlc_hw->osh)));
+ return NULL;
+ }
+ bzero((char *)physhim, sizeof(wlc_phy_shim_info_t));
+ physhim->wlc_hw = wlc_hw;
+ physhim->wlc = wlc;
+ physhim->wl = wl;
+
+ return physhim;
+}
+
+void BCMATTACHFN(wlc_phy_shim_detach) (wlc_phy_shim_info_t *physhim)
+{
+ if (!physhim)
+ return;
+
+ MFREE(physhim->wlc_hw->osh, physhim, sizeof(wlc_phy_shim_info_t));
+}
+
+struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+ void (*fn) (void *arg), void *arg,
+ const char *name)
+{
+ return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name);
+}
+
+void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+{
+ wl_free_timer(physhim->wl, (struct wl_timer *)t);
+}
+
+void
+wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms,
+ int periodic)
+{
+ wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic);
+}
+
+bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+{
+ return wl_del_timer(physhim->wl, (struct wl_timer *)t);
+}
+
+void wlapi_intrson(wlc_phy_shim_info_t *physhim)
+{
+ wl_intrson(physhim->wl);
+}
+
+uint32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim)
+{
+ return wl_intrsoff(physhim->wl);
+}
+
+void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, uint32 macintmask)
+{
+ wl_intrsrestore(physhim->wl, macintmask);
+}
+
+void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, uint16 v)
+{
+ wlc_bmac_write_shm(physhim->wlc_hw, offset, v);
+}
+
+uint16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset)
+{
+ return wlc_bmac_read_shm(physhim->wlc_hw, offset);
+}
+
+void
+wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, uint8 idx, uint16 mask,
+ uint16 val, int bands)
+{
+ wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands);
+}
+
+void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, uint32 flags)
+{
+ wlc_bmac_corereset(physhim->wlc_hw, flags);
+}
+
+void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim)
+{
+ wlc_suspend_mac_and_wait(physhim->wlc);
+}
+
+void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, uint8 spurmode)
+{
+ wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode);
+}
+
+void wlapi_enable_mac(wlc_phy_shim_info_t *physhim)
+{
+ wlc_enable_mac(physhim->wlc);
+}
+
+void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, uint32 mask, uint32 val)
+{
+ wlc_bmac_mctrl(physhim->wlc_hw, mask, val);
+}
+
+void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim)
+{
+ wlc_bmac_phy_reset(physhim->wlc_hw);
+}
+
+void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, uint16 bw)
+{
+ wlc_bmac_bw_set(physhim->wlc_hw, bw);
+}
+
+uint16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim)
+{
+ return wlc_bmac_get_txant(physhim->wlc_hw);
+}
+
+void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk)
+{
+ wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk);
+}
+
+void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk)
+{
+ wlc_bmac_macphyclk_set(physhim->wlc_hw, clk);
+}
+
+void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on)
+{
+ wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on);
+}
+
+void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim)
+{
+ wlc_bmac_core_phypll_reset(physhim->wlc_hw);
+}
+
+void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim)
+{
+ wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG);
+}
+
+void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim)
+{
+ wlc_ucode_wake_override_clear(physhim->wlc_hw,
+ WLC_WAKE_OVERRIDE_PHYREG);
+}
+
+void
+wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset,
+ int len, void *buf)
+{
+ wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf);
+}
+
+uint16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, uint8 rate)
+{
+ return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate);
+}
+
+void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim)
+{
+}
+
+void
+wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf,
+ int len, uint32 sel)
+{
+ wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
+}
+
+void
+wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf,
+ int l, uint32 sel)
+{
+ wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
+}
+
+void
+wlapi_bmac_pktengtx(wlc_phy_shim_info_t *physhim, wl_pkteng_t *pkteng,
+ uint8 rate, struct ether_addr *sa, uint32 wait_delay)
+{
+ wlc_pktengtx(physhim->wlc, pkteng, rate, sa, wait_delay);
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.h b/drivers/staging/brcm80211/sys/wlc_phy_shim.h
new file mode 100644
index 000000000000..77bc20e712be
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_phy_shim_h_
+#define _wlc_phy_shim_h_
+
+#define RADAR_TYPE_NONE 0 /* Radar type None */
+#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
+#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
+#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
+#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
+#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
+#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
+#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
+#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
+#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
+#define RADAR_TYPE_FRA 10 /* French radar */
+
+/* French radar pulse widths */
+#define FRA_T1_20MHZ 52770
+#define FRA_T2_20MHZ 61538
+#define FRA_T3_20MHZ 66002
+#define FRA_T1_40MHZ 105541
+#define FRA_T2_40MHZ 123077
+#define FRA_T3_40MHZ 132004
+#define FRA_ERR_20MHZ 60
+#define FRA_ERR_40MHZ 120
+
+#define ANTSEL_NA 0 /* No boardlevel selection available */
+#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
+#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
+
+/* Rx Antenna diversity control values */
+#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
+#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
+#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
+#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
+#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
+#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
+
+/* Forward declarations */
+struct wlc_hw_info;
+typedef struct wlc_phy_shim_info wlc_phy_shim_info_t;
+
+extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw,
+ void *wl, void *wlc);
+extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim);
+
+/* PHY to WL utility functions */
+struct wlapi_timer;
+extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+ void (*fn) (void *arg), void *arg,
+ const char *name);
+extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim,
+ struct wlapi_timer *t);
+extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim,
+ struct wlapi_timer *t, uint ms, int periodic);
+extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim,
+ struct wlapi_timer *t);
+extern void wlapi_intrson(wlc_phy_shim_info_t *physhim);
+extern uint32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim);
+extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim,
+ uint32 macintmask);
+
+extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset,
+ uint16 v);
+extern uint16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset);
+extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, uint8 idx,
+ uint16 mask, uint16 val, int bands);
+extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, uint32 flags);
+extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim);
+extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, uint8 spurmode);
+extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim);
+extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, uint32 mask,
+ uint32 val);
+extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim);
+extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, uint16 bw);
+extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk);
+extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk);
+extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on);
+extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim);
+extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *
+ physhim);
+extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *
+ physhim);
+extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o,
+ int len, void *buf);
+extern uint16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim,
+ uint8 rate);
+extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim);
+extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint,
+ void *buf, int, uint32 sel);
+extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint,
+ const void *buf, int, uint32);
+
+extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim,
+ uint32 phy_mode);
+extern void wlapi_bmac_pktengtx(wlc_phy_shim_info_t *physhim,
+ wl_pkteng_t *pkteng, uint8 rate,
+ struct ether_addr *sa, uint32 wait_delay);
+extern uint16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim);
+#endif /* _wlc_phy_shim_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h
new file mode 100644
index 000000000000..e01e6ed57f4a
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_pub.h
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_pub_h_
+#define _wlc_pub_h_
+
+#include <wlc_types.h>
+#include <wlc_scb.h>
+
+#define WLC_NUMRATES 16 /* max # of rates in a rateset */
+#define MAXMULTILIST 32 /* max # multicast addresses */
+#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */
+
+/* phy types */
+#define PHY_TYPE_A 0 /* Phy type A */
+#define PHY_TYPE_G 2 /* Phy type G */
+#define PHY_TYPE_N 4 /* Phy type N */
+#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
+#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
+#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
+#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
+#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
+
+/* bw */
+#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
+#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
+#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
+
+#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \
+ CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \
+ WLC_10_MHZ)
+
+#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
+#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
+#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
+#define WLC_RSSI_LOW -70 /* Low quality cutoffs */
+#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */
+#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
+#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
+
+#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */
+
+#define MA_WINDOW_SZ 8 /* moving average window size */
+
+#define WLC_SNR_INVALID 0 /* invalid SNR value */
+
+/* a large TX Power as an init value to factor out of MIN() calculations,
+ * keep low enough to fit in an int8, units are .25 dBm
+ */
+#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
+
+/* legacy rx Antenna diversity for SISO rates */
+#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
+#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
+#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
+#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
+#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
+#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
+
+/* legacy rx Antenna diversity for SISO rates */
+#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */
+#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */
+#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */
+#define ANT_TX_DEF 3 /* driver's default tx antenna setting */
+
+#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */
+
+/* Tx Chain values */
+#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */
+#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */
+#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */
+#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */
+#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */
+#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */
+#define ANTSWITCH_NONE 0 /* no antenna switch */
+#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */
+#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */
+#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */
+
+#define RXBUFSZ PKTBUFSZ
+#ifndef AIDMAPSZ
+#define AIDMAPSZ (ROUNDUP(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */
+#endif /* AIDMAPSZ */
+
+typedef struct wlc_tunables {
+ int ntxd; /* size of tx descriptor table */
+ int nrxd; /* size of rx descriptor table */
+ int rxbufsz; /* size of rx buffers to post */
+ int nrxbufpost; /* # of rx buffers to post */
+ int maxscb; /* # of SCBs supported */
+ int ampdunummpdu; /* max number of mpdu in an ampdu */
+ int maxpktcb; /* max # of packet callbacks */
+ int maxucodebss; /* max # of BSS handled in ucode bcn/prb */
+ int maxucodebss4; /* max # of BSS handled in sw bcn/prb */
+ int maxbss; /* max # of bss info elements in scan list */
+ int datahiwat; /* data msg txq hiwat mark */
+ int ampdudatahiwat; /* AMPDU msg txq hiwat mark */
+ int rxbnd; /* max # of rx bufs to process before deferring to dpc */
+ int txsbnd; /* max # tx status to process in wlc_txstatus() */
+ int memreserved; /* memory reserved for BMAC's USB dma rx */
+} wlc_tunables_t;
+
+typedef struct wlc_rateset {
+ uint count; /* number of rates in rates[] */
+ uint8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */
+ uint8 htphy_membership; /* HT PHY Membership */
+ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
+} wlc_rateset_t;
+
+struct rsn_parms {
+ uint8 flags; /* misc booleans (e.g., supported) */
+ uint8 multicast; /* multicast cipher */
+ uint8 ucount; /* count of unicast ciphers */
+ uint8 unicast[4]; /* unicast ciphers */
+ uint8 acount; /* count of auth modes */
+ uint8 auth[4]; /* Authentication modes */
+ uint8 PAD[4]; /* padding for future growth */
+};
+
+/*
+ * buffer length needed for wlc_format_ssid
+ * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+ */
+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1)
+
+#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */
+#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */
+
+/* All the HT-specific default advertised capabilities (including AMPDU)
+ * should be grouped here at one place
+ */
+#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
+
+/* defaults for the HT (MIMO) bss */
+#define HT_CAP ((HT_CAP_MIMO_PS_OFF << HT_CAP_MIMO_PS_SHIFT) | HT_CAP_40MHZ | \
+ HT_CAP_GF | HT_CAP_MAX_AMSDU | HT_CAP_DSSS_CCK)
+
+/* WLC packet type is a void * */
+typedef void *wlc_pkt_t;
+
+/* Event data type */
+typedef struct wlc_event {
+ wl_event_msg_t event; /* encapsulated event */
+ struct ether_addr *addr; /* used to keep a trace of the potential present of
+ * an address in wlc_event_msg_t
+ */
+ int bsscfgidx; /* BSS config when needed */
+ struct wl_if *wlif; /* pointer to wlif */
+ void *data; /* used to hang additional data on an event */
+ struct wlc_event *next; /* enables ordered list of pending events */
+} wlc_event_t;
+
+/* wlc internal bss_info, wl external one is in wlioctl.h */
+typedef struct wlc_bss_info {
+ struct ether_addr BSSID; /* network BSSID */
+ uint16 flags; /* flags for internal attributes */
+ uint8 SSID_len; /* the length of SSID */
+ uint8 SSID[32]; /* SSID string */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int16 SNR; /* receive signal SNR in dB */
+ uint16 beacon_period; /* units are Kusec */
+ uint16 atim_window; /* units are Kusec */
+ chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */
+ int8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */
+ wlc_rateset_t rateset; /* supported rates */
+ uint8 dtim_period; /* DTIM period */
+ int8 phy_noise; /* noise right after tx (in dBm) */
+ uint16 capability; /* Capability information */
+ struct dot11_bcn_prb *bcn_prb; /* beacon/probe response frame (ioctl na) */
+ uint16 bcn_prb_len; /* beacon/probe response frame length (ioctl na) */
+ uint8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */
+ struct rsn_parms wpa;
+ struct rsn_parms wpa2;
+ uint16 qbss_load_aac; /* qbss load available admission capacity */
+ /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */
+ uint8 qbss_load_chan_free; /* indicates how free the channel is */
+ uint8 mcipher; /* multicast cipher */
+ uint8 wpacfg; /* wpa config index */
+} wlc_bss_info_t;
+
+/* forward declarations */
+struct wlc_if;
+
+/* wlc_ioctl error codes */
+#define WLC_ENOIOCTL 1 /* No such Ioctl */
+#define WLC_EINVAL 2 /* Invalid value */
+#define WLC_ETOOSMALL 3 /* Value too small */
+#define WLC_ETOOBIG 4 /* Value too big */
+#define WLC_ERANGE 5 /* Out of range */
+#define WLC_EDOWN 6 /* Down */
+#define WLC_EUP 7 /* Up */
+#define WLC_ENOMEM 8 /* No Memory */
+#define WLC_EBUSY 9 /* Busy */
+
+/* IOVar flags for common error checks */
+#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */
+#define IOVF_WHL (1<<4) /* value must be whole (0-max) */
+#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */
+
+#define IOVF_SET_UP (1<<6) /* set requires driver be up */
+#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */
+#define IOVF_SET_CLK (1<<8) /* set requires core clock */
+#define IOVF_SET_BAND (1<<9) /* set requires fixed band */
+
+#define IOVF_GET_UP (1<<10) /* get requires driver be up */
+#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */
+#define IOVF_GET_CLK (1<<12) /* get requires core clock */
+#define IOVF_GET_BAND (1<<13) /* get requires fixed band */
+#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */
+
+/* watchdog down and dump callback function proto's */
+typedef int (*watchdog_fn_t) (void *handle);
+typedef int (*down_fn_t) (void *handle);
+typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b);
+
+/* IOVar handler
+ *
+ * handle - a pointer value registered with the function
+ * vi - iovar_info that was looked up
+ * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid.
+ * name - the actual iovar name
+ * params/plen - parameters and length for a get, input only.
+ * arg/len - buffer and length for value to be set or retrieved, input or output.
+ * vsize - value size, valid for integer type only.
+ * wlcif - interface context (wlc_if pointer)
+ *
+ * All pointers may point into the same buffer.
+ */
+typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi,
+ uint32 actionid, const char *name, void *params,
+ uint plen, void *arg, int alen, int vsize,
+ struct wlc_if *wlcif);
+
+#define MAC80211_PROMISC_BCNS (1 << 0)
+#define MAC80211_SCAN (1 << 1)
+
+/*
+ * Public portion of "common" os-independent state structure.
+ * The wlc handle points at this.
+ */
+typedef struct wlc_pub {
+ void *wlc;
+
+ struct ieee80211_hw *ieee_hw;
+ struct scb *global_scb;
+ scb_ampdu_t *global_ampdu;
+ uint mac80211_state;
+ uint unit; /* device instance number */
+ uint corerev; /* core revision */
+ osl_t *osh; /* pointer to os handle */
+ si_t *sih; /* SB handle (cookie for siutils calls) */
+ char *vars; /* "environment" name=value */
+ bool up; /* interface up and running */
+ bool hw_off; /* HW is off */
+ wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */
+ bool hw_up; /* one time hw up/down(from boot or hibernation) */
+ bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */
+ uint _nbands; /* # bands supported */
+ uint now; /* # elapsed seconds */
+
+ bool promisc; /* promiscuous destination address */
+ bool delayed_down; /* down delayed */
+ bool _ap; /* AP mode enabled */
+ bool _apsta; /* simultaneous AP/STA mode enabled */
+ bool _assoc_recreate; /* association recreation on up transitions */
+ int _wme; /* WME QoS mode */
+ uint8 _mbss; /* MBSS mode on */
+ bool allmulti; /* enable all multicasts */
+ bool associated; /* true:part of [I]BSS, false: not */
+ /* (union of stas_associated, aps_associated) */
+ bool phytest_on; /* whether a PHY test is running */
+ bool bf_preempt_4306; /* True to enable 'darwin' mode */
+ bool _ampdu; /* ampdu enabled or not */
+ bool _cac; /* 802.11e CAC enabled */
+ uint8 _n_enab; /* bitmap of 11N + HT support */
+ bool _n_reqd; /* N support required for clients */
+
+ int8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */
+ bool _priofc; /* Priority-based flowcontrol */
+
+ struct ether_addr cur_etheraddr; /* our local ethernet address */
+
+ struct ether_addr *multicast; /* ptr to list of multicast addresses */
+ uint nmulticast; /* # enabled multicast addresses */
+
+ uint32 wlfeatureflag; /* Flags to control sw features from registry */
+ int psq_pkts_total; /* total num of ps pkts */
+
+ uint16 txmaxpkts; /* max number of large pkts allowed to be pending */
+
+ /* s/w decryption counters */
+ uint32 swdecrypt; /* s/w decrypt attempts */
+
+ int bcmerror; /* last bcm error */
+
+ mbool radio_disabled; /* bit vector for radio disabled reasons */
+ bool radio_active; /* radio on/off state */
+ uint16 roam_time_thresh; /* Max. # secs. of not hearing beacons
+ * before roaming.
+ */
+ bool align_wd_tbtt; /* Align watchdog with tbtt indication
+ * handling. This flag is cleared by default
+ * and is set by per port code explicitly and
+ * you need to make sure the OSL_SYSUPTIME()
+ * is implemented properly in osl of that port
+ * when it enables this Power Save feature.
+ */
+#ifdef BCMSDIO
+ uint sdiod_drive_strength; /* SDIO drive strength */
+#endif /* BCMSDIO */
+
+ uint16 boardrev; /* version # of particular board */
+ uint8 sromrev; /* version # of the srom */
+ char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */
+ uint32 boardflags; /* Board specific flags from srom */
+ uint32 boardflags2; /* More board flags if sromrev >= 4 */
+ bool tempsense_disable; /* disable periodic tempsense check */
+
+ bool _lmac; /* lmac module included and enabled */
+ bool _lmacproto; /* lmac protocol module included and enabled */
+ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
+ bool _ampdumac; /* mac assist ampdu enabled or not */
+} wlc_pub_t;
+
+/* wl_monitor rx status per packet */
+typedef struct wl_rxsts {
+ uint pkterror; /* error flags per pkt */
+ uint phytype; /* 802.11 A/B/G ... */
+ uint channel; /* channel */
+ uint datarate; /* rate in 500kbps */
+ uint antenna; /* antenna pkts received on */
+ uint pktlength; /* pkt length minus bcm phy hdr */
+ uint32 mactime; /* time stamp from mac, count per 1us */
+ uint sq; /* signal quality */
+ int32 signal; /* in dbm */
+ int32 noise; /* in dbm */
+ uint preamble; /* Unknown, short, long */
+ uint encoding; /* Unknown, CCK, PBCC, OFDM */
+ uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */
+ struct wl_if *wlif; /* wl interface */
+} wl_rxsts_t;
+
+/* status per error RX pkt */
+#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */
+#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */
+#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */
+#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */
+#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */
+#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */
+#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */
+#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */
+#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */
+
+/* phy type */
+#define WL_RXS_PHY_A 0x00000000 /* A phy type */
+#define WL_RXS_PHY_B 0x00000001 /* B phy type */
+#define WL_RXS_PHY_G 0x00000002 /* G phy type */
+#define WL_RXS_PHY_N 0x00000004 /* N phy type */
+
+/* encoding */
+#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */
+#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */
+
+/* preamble */
+#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */
+#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */
+#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */
+#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */
+#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */
+
+#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */
+#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */
+#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */
+#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */
+
+/* forward declare and use the struct notation so we don't have to
+ * have it defined if not necessary.
+ */
+struct wlc_info;
+struct wlc_hw_info;
+struct wlc_bsscfg;
+struct wlc_if;
+
+/* Structure for Pkttag area in a packet.
+ * CAUTION: Please carefully consider your design before adding any new fields to the pkttag
+ * The size is limited to 32 bytes which on 64-bit machine allows only 4 fields.
+ * If adding a member, be sure to check if wlc_pkttag_info_move should transfer it.
+ */
+typedef struct {
+ uint32 flags; /* Describe various packet properties */
+ uint16 seq; /* preassigned seqnum for AMPDU */
+#ifdef BCMDBG
+ uint16 _scb_dbgid; /* Uniqe debug id for the scb pointed by scb pointer */
+#endif
+ uint8 callbackidx; /* Index into pkt_callback tables for callback function */
+ int8 _bsscfgidx; /* Index of bsscfg for this frame */
+ int8 ac_override; /* fifo on which this frame should go */
+ int8 rssi; /* RSSI for the recvd. packet */
+ uint32 exptime; /* Time of expiry for the packet */
+ struct scb *_scb; /* Pointer to SCB for associated ea */
+ uint32 rspec; /* Phy rate for received packet */
+ union {
+ uint32 packetid;
+ } shared;
+} wlc_pkttag_t;
+
+#define WLPKTTAG(p) ((wlc_pkttag_t *)PKTTAG(p))
+
+/* Flags used in wlc_pkttag_t.
+ * If adding a flag, be sure to check if WLPKTTAG_FLAG_MOVE should transfer it.
+ */
+#define WLF_PSMARK 0x00000001 /* PKT marking for PSQ aging */
+#define WLF_PSDONTQ 0x00000002 /* PS-Poll response don't queue flag */
+#define WLF_MPDU 0x00000004 /* Set if pkt is a PDU as opposed to MSDU */
+#define WLF_NON8023 0x00000008 /* original pkt is not 8023 */
+#define WLF_8021X 0x00000010 /* original pkt is 802.1x */
+#define WLF_APSD 0x00000020 /* APSD delivery frame */
+#define WLF_AMSDU 0x00000040 /* pkt is aggregated msdu */
+#define WLF_HWAMSDU 0x00000080 /* Rx: HW/ucode has deaggregated this A-MSDU */
+#define WLF_TXHDR 0x00000080 /* Tx: pkt is 802.11 MPDU with plcp and txhdr */
+#define WLF_BA 0x00000100 /* Used by BA module if pkt is not to be acked */
+#define WLF_EXPTIME 0x00000200 /* pkttag has a valid expiration time for the pkt */
+#define WLF_AMPDU_MPDU 0x00000400 /* mpdu in a ampdu */
+#define WLF_MIMO 0x00000800 /* mpdu has a mimo rate */
+#define WLF_RIFS 0x00001000 /* frameburst with RIFS separated */
+#define WLF_VRATE_PROBE 0x00002000 /* vertical rate probe mpdu */
+#define WLF_BSS_DOWN 0x00004000 /* The BSS associated with the pkt has gone down */
+#define WLF_UMAC_PKT 0x00008000 /* UMAC Packet */
+#define WLF_EXEMPT_MASK 0x00030000 /* mask for encryption exemption (Vista) */
+#define WLF_WME_NOACK 0x00040000 /* pkt use WME No ACK policy */
+#define WLF_USERTS 0x04000000 /* protect the packet with RTS/CTS */
+#define WLF_RATE_AUTO 0x08000000 /* pkt uses rates from the rate selection module */
+
+#define WLF_DATA 0x40000000 /* pkt is pure data */
+
+#define WLPKTFLAG_BA(pkttag) FALSE
+
+#define WLPKTFLAG_AMPDU(pkttag) ((pkttag)->flags & WLF_AMPDU_MPDU)
+#define WLPKTFLAG_RIFS(pkttag) ((pkttag)->flags & WLF_RIFS)
+
+/* API for accessing BSSCFG index in WLPKTTAG */
+#define BSSCFGIDX_ISVALID(bsscfgidx) (((bsscfgidx >= 0) && (bsscfgidx < WLC_MAXBSSCFG)) ? 1 : 0)
+
+static INLINE int8 wlc_pkttag_bsscfg_get(void *p)
+{
+ int8 idx = WLPKTTAG(p)->_bsscfgidx;
+#ifdef BCMDBG
+ ASSERT(BSSCFGIDX_ISVALID(idx));
+#endif
+ return idx;
+}
+
+#define WLPKTTAGBSSCFGGET(p) (wlc_pkttag_bsscfg_get(p))
+#define WLPKTTAGBSSCFGSET(p, bsscfgidx) (WLPKTTAG(p)->_bsscfgidx = bsscfgidx)
+
+/* Raw get of bss idx from pkt tag without error checking */
+#define WLPKTTAG_BSSIDX_GET(pkttag) ((pkttag)->_bsscfgidx)
+
+/***********************************************
+ * Feature-related macros to optimize out code *
+ * *********************************************
+ */
+
+/* AP Support (versus STA) */
+#define AP_ENAB(pub) (0)
+
+/* Macro to check if APSTA mode enabled */
+#define APSTA_ENAB(pub) (0)
+
+/* Some useful combinations */
+#define STA_ONLY(pub) (!AP_ENAB(pub))
+#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub))
+
+#define ENAB_1x1 0x01
+#define ENAB_2x2 0x02
+#define ENAB_3x3 0x04
+#define ENAB_4x4 0x08
+#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
+#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
+/* WL11N Support */
+#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \
+ (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0)))
+#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N)
+#define N_REQD(pub) ((pub)->_n_reqd)
+#else
+#define N_ENAB(pub) 0
+#define N_REQD(pub) 0
+#endif
+
+#if (defined(HTCONF) && (HTCONF != 0))
+#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT)
+#else
+#define HT_ENAB(pub) 0
+#endif
+
+#define AMPDU_AGG_HOST 1
+#define AMPDU_ENAB(pub) ((pub)->_ampdu)
+
+#define EDCF_ENAB(pub) (WME_ENAB(pub))
+#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
+
+#define MONITOR_ENAB(wlc) (bcmspace && (wlc)->monitor)
+
+#define PROMISC_ENAB(wlc) (bcmspace && (wlc)->promisc)
+
+extern void wlc_pkttag_info_move(wlc_pub_t *pub, void *pkt_from, void *pkt_to);
+
+#define WLPKTTAGSCB(p) (WLPKTTAG(p)->_scb)
+
+#define WLC_PREC_COUNT 16 /* Max precedence level implemented */
+
+/* pri is PKTPRIO encoded in the packet. This maps the Packet priority to
+ * enqueue precedence as defined in wlc_prec_map
+ */
+extern const uint8 wlc_prio2prec_map[];
+#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
+
+/* This maps priority to one precedence higher - Used by PS-Poll response packets to
+ * simulate enqueue-at-head operation, but still maintain the order on the queue
+ */
+#define WLC_PRIO_TO_HI_PREC(pri) MIN(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1)
+
+extern const uint8 wme_fifo2ac[];
+#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]]
+
+/* Mask to describe all precedence levels */
+#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT)
+
+/* Define a bitmap of precedences comprised by each AC */
+#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
+ NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
+#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
+ NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
+#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
+ NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
+#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
+ NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \
+ NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
+
+/* WME Support */
+#define WME_ENAB(pub) ((pub)->_wme != OFF)
+#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
+
+#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */
+
+#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */
+#define WLCNTINCR(a) /* No stats support */
+#define WLCNTDECR(a) /* No stats support */
+#define WLCNTADD(a, delta) /* No stats support */
+#define WLCNTSET(a, value) /* No stats support */
+#define WLCNTVAL(a) 0 /* No stats support */
+
+/* common functions for every port */
+extern void *wlc_attach(void *wl, uint16 vendor, uint16 device, uint unit,
+ bool piomode, osl_t *osh, void *regsva, uint bustype,
+ void *btparam, uint *perr);
+extern uint wlc_detach(struct wlc_info *wlc);
+extern int wlc_up(struct wlc_info *wlc);
+extern uint wlc_down(struct wlc_info *wlc);
+
+extern int wlc_set(struct wlc_info *wlc, int cmd, int arg);
+extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg);
+extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg);
+extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg);
+extern bool wlc_chipmatch(uint16 vendor, uint16 device);
+extern void wlc_init(struct wlc_info *wlc);
+extern void wlc_reset(struct wlc_info *wlc);
+
+extern void wlc_intrson(struct wlc_info *wlc);
+extern uint32 wlc_intrsoff(struct wlc_info *wlc);
+extern void wlc_intrsrestore(struct wlc_info *wlc, uint32 macintmask);
+extern bool wlc_intrsupd(struct wlc_info *wlc);
+extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc);
+extern bool wlc_dpc(struct wlc_info *wlc, bool bounded);
+extern bool wlc_send80211_raw(struct wlc_info *wlc, wlc_if_t *wlcif, void *p,
+ uint ac);
+extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params,
+ int p_len, void *arg, int len, bool set,
+ struct wlc_if *wlcif);
+extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+ struct wlc_if *wlcif);
+/* helper functions */
+extern void wlc_statsupd(struct wlc_info *wlc);
+extern int wlc_get_header_len(void);
+
+extern wlc_pub_t *wlc_pub(void *wlc);
+
+/* common functions for every port */
+extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw);
+extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw);
+extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw);
+extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw);
+
+extern int wlc_nin_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+ struct wlc_if *wlcif);
+extern bool wlc_nin_process_sendup(struct wlc_info *wlc, void *p);
+void wlc_nin_create_iapp_ind(struct wlc_info *wlc, void *p, int len);
+
+extern uint32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size);
+extern void wlc_reg_write(struct wlc_info *wlc, void *r, uint32 v, uint size);
+extern void wlc_corereset(struct wlc_info *wlc, uint32 flags);
+extern void wlc_mhf(struct wlc_info *wlc, uint8 idx, uint16 mask, uint16 val,
+ int bands);
+extern uint16 wlc_mhf_get(struct wlc_info *wlc, uint8 idx, int bands);
+extern uint32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo);
+extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset);
+extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs);
+extern void wlc_join_attempt(struct wlc_bsscfg *cfg);
+extern void wlc_join_bss_start(struct wlc_bsscfg *cfg);
+extern void wlc_join_BSS(struct wlc_bsscfg *cfg, wlc_bss_info_t *bi);
+
+/* wlc_phy.c helper functions */
+extern bool wlc_scan_inprog(struct wlc_info *wlc);
+extern bool wlc_associnprog(struct wlc_info *wlc);
+extern bool wlc_scan_inprog(struct wlc_info *wlc);
+extern void *wlc_cur_phy(struct wlc_info *wlc);
+extern void wlc_set_ps_ctrl(struct wlc_info *wlc);
+extern void wlc_mctrl(struct wlc_info *wlc, uint32 mask, uint32 val);
+extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc);
+
+/* ioctl */
+extern int wlc_iovar_getint8(struct wlc_info *wlc, const char *name,
+ int8 *arg);
+extern int wlc_iovar_check(wlc_pub_t *pub, const bcm_iovar_t *vi, void *arg,
+ int len, bool set);
+
+extern int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars,
+ const char *name, void *hdl, iovar_fn_t iovar_fn,
+ watchdog_fn_t watchdog_fn, down_fn_t down_fn);
+extern int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl);
+extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg,
+ wlc_event_t *e, const struct ether_addr *addr);
+extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc);
+extern void wlc_enable_mac(struct wlc_info *wlc);
+extern uint16 wlc_rate_shm_offset(struct wlc_info *wlc, uint8 rate);
+extern uint32 wlc_get_rspec_history(struct wlc_bsscfg *cfg);
+extern uint32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg);
+
+static INLINE int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
+ uint *arg)
+{
+ return wlc_iovar_getint(wlc, name, (int *)arg);
+}
+
+static INLINE int wlc_iovar_getuint8(struct wlc_info *wlc, const char *name,
+ uint8 *arg)
+{
+ return wlc_iovar_getint8(wlc, name, (int8 *) arg);
+}
+
+static INLINE int wlc_iovar_setuint(struct wlc_info *wlc, const char *name,
+ uint arg)
+{
+ return wlc_iovar_setint(wlc, name, (int)arg);
+}
+
+#if defined(BCMDBG)
+extern int wlc_iocregchk(struct wlc_info *wlc, uint band);
+#endif
+#if defined(BCMDBG)
+extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype);
+#endif
+
+/* helper functions */
+extern void wlc_getrand(struct wlc_info *wlc, uint8 *buf, int len);
+
+struct scb;
+extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb);
+extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard);
+extern bool wlc_radio_monitor_stop(struct wlc_info *wlc);
+
+#if defined(BCMDBG)
+extern int wlc_format_ssid(char *buf, const uchar ssid[], uint ssid_len);
+#endif
+
+extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID);
+extern void wlc_pmkid_event(struct wlc_bsscfg *cfg);
+
+#define MAXBANDS 2 /* Maximum #of bands */
+/* bandstate array indices */
+#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
+#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */
+
+#define BAND_2G_NAME "2.4G"
+#define BAND_5G_NAME "5G"
+
+#if defined(BCMSDIO) || defined(WLC_HIGH_ONLY)
+void wlc_device_removed(void *arg);
+#endif
+
+/* BMAC RPC: 7 uint32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */
+#define WLC_RPCTX_PARAMS 32
+
+#endif /* _wlc_pub_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c
new file mode 100644
index 000000000000..9e9e4688e2ed
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_rate.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <wlioctl.h>
+
+#include <proto/802.11.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wl_dbg.h>
+#include <wlc_pub.h>
+
+/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */
+const uint8 rate_info[WLC_MAXRATE + 1] = {
+ /* 0 1 2 3 4 5 6 7 8 9 */
+/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
+/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
+/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
+/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
+/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
+};
+
+/* rates are in units of Kbps */
+const mcs_info_t mcs_table[MCS_TABLE_SIZE] = {
+ /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
+ {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
+ WLC_RATE_6M},
+ /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
+ {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
+ WLC_RATE_12M},
+ /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
+ {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
+ WLC_RATE_18M},
+ /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
+ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
+ WLC_RATE_24M},
+ /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
+ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
+ WLC_RATE_36M},
+ /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
+ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
+ WLC_RATE_48M},
+ /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
+ {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
+ WLC_RATE_54M},
+ /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
+ {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
+ WLC_RATE_54M},
+ /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
+ {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
+ WLC_RATE_6M},
+ /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
+ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
+ WLC_RATE_12M},
+ /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
+ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
+ WLC_RATE_18M},
+ /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
+ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
+ WLC_RATE_24M},
+ /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
+ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
+ WLC_RATE_36M},
+ /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
+ {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
+ WLC_RATE_48M},
+ /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
+ {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
+ WLC_RATE_54M},
+ /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
+ {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
+ WLC_RATE_54M},
+ /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
+ {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
+ WLC_RATE_6M},
+ /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
+ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
+ WLC_RATE_12M},
+ /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
+ {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
+ WLC_RATE_18M},
+ /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
+ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
+ WLC_RATE_24M},
+ /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
+ {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
+ WLC_RATE_36M},
+ /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
+ {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
+ WLC_RATE_48M},
+ /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
+ {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
+ WLC_RATE_54M},
+ /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
+ {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
+ WLC_RATE_54M},
+ /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
+ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
+ WLC_RATE_6M},
+ /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
+ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
+ WLC_RATE_12M},
+ /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
+ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
+ WLC_RATE_18M},
+ /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
+ {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
+ WLC_RATE_24M},
+ /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
+ {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
+ WLC_RATE_36M},
+ /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
+ {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
+ WLC_RATE_48M},
+ /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
+ {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
+ WLC_RATE_54M},
+ /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
+ {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
+ WLC_RATE_54M},
+ /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
+ {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M},
+};
+
+/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
+ * Number of spatial streams: always 1
+ * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard
+ */
+typedef struct legacy_phycfg {
+ uint32 rate_ofdm; /* ofdm mac rate */
+ uint8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
+} legacy_phycfg_t;
+
+#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */
+
+/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+/* Eventually MIMOPHY would also be converted to this format */
+/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
+ {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
+ {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
+ {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
+ {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
+ {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
+ {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
+ {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
+ {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
+ {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
+ {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
+ {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
+ {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
+};
+
+/* Hardware rates (also encodes default basic rates) */
+
+const wlc_rateset_t cck_ofdm_mimo_rates = {
+ 12,
+ { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
+ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+ 0x6c},
+ 0x00,
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t ofdm_mimo_rates = {
+ 8,
+ { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
+ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+ 0x00,
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+/* Default ratesets that include MCS32 for 40BW channels */
+const wlc_rateset_t cck_ofdm_40bw_mimo_rates = {
+ 12,
+ { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
+ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+ 0x6c},
+ 0x00,
+ {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t ofdm_40bw_mimo_rates = {
+ 8,
+ { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
+ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+ 0x00,
+ {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t cck_ofdm_rates = {
+ 12,
+ { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
+ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+ 0x6c},
+ 0x00,
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t gphy_legacy_rates = {
+ 4,
+ { /* 1b, 2b, 5.5b, 11b Mbps */
+ 0x82, 0x84, 0x8b, 0x96},
+ 0x00,
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t ofdm_rates = {
+ 8,
+ { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
+ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+ 0x00,
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+const wlc_rateset_t cck_rates = {
+ 4,
+ { /* 1b, 2b, 5.5, 11 Mbps */
+ 0x82, 0x84, 0x0b, 0x16},
+ 0x00,
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00}
+};
+
+static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate);
+
+/* check if rateset is valid.
+ * if check_brate is true, rateset without a basic rate is considered NOT valid.
+ */
+static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate)
+{
+ uint idx;
+
+ if (!rs->count)
+ return FALSE;
+
+ if (!check_brate)
+ return TRUE;
+
+ /* error if no basic rates */
+ for (idx = 0; idx < rs->count; idx++) {
+ if (rs->rates[idx] & WLC_RATE_FLAG)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void wlc_rateset_mcs_upd(wlc_rateset_t *rs, uint8 txstreams)
+{
+ int i;
+ for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
+ rs->mcs[i] = 0;
+}
+
+/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved,
+ * and check if resulting rateset is valid.
+*/
+bool
+wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs,
+ const wlc_rateset_t *hw_rs,
+ bool check_brate, uint8 txstreams)
+{
+ uint8 rateset[WLC_MAXRATE + 1];
+ uint8 r;
+ uint count;
+ uint i;
+
+ bzero(rateset, sizeof(rateset));
+ count = rs->count;
+
+ for (i = 0; i < count; i++) {
+ /* mask off "basic rate" bit, WLC_RATE_FLAG */
+ r = (int)rs->rates[i] & RATE_MASK;
+ if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) {
+ continue;
+ }
+ rateset[r] = rs->rates[i]; /* preserve basic bit! */
+ }
+
+ /* fill out the rates in order, looking at only supported rates */
+ count = 0;
+ for (i = 0; i < hw_rs->count; i++) {
+ r = hw_rs->rates[i] & RATE_MASK;
+ ASSERT(r <= WLC_MAXRATE);
+ if (rateset[r])
+ rs->rates[count++] = rateset[r];
+ }
+
+ rs->count = count;
+
+ /* only set the mcs rate bit if the equivalent hw mcs bit is set */
+ for (i = 0; i < MCSSET_LEN; i++)
+ rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
+
+ if (wlc_rateset_valid(rs, check_brate))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* caluclate the rate of a rx'd frame and return it as a ratespec */
+ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, uint8 *plcp)
+{
+ int phy_type;
+ ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
+
+ phy_type =
+ ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
+
+ if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
+ (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
+ switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
+ case PRXS0_CCK:
+ rspec =
+ CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+ break;
+ case PRXS0_OFDM:
+ rspec =
+ OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->
+ rlpt[0]);
+ break;
+ case PRXS0_PREN:
+ rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
+ if (plcp[0] & MIMO_PLCP_40MHZ) {
+ /* indicate rspec is for 40 MHz mode */
+ rspec &= ~RSPEC_BW_MASK;
+ rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+ }
+ break;
+ case PRXS0_STDN:
+ /* fallthru */
+ default:
+ /* not supported */
+ ASSERT(0);
+ break;
+ }
+ if (PLCP3_ISSGI(plcp[3]))
+ rspec |= RSPEC_SHORT_GI;
+ } else
+ if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
+ rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]);
+ else
+ rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+
+ return rspec;
+}
+
+/* copy rateset src to dst as-is (no masking or sorting) */
+void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst)
+{
+ bcopy(src, dst, sizeof(wlc_rateset_t));
+}
+
+/*
+ * Copy and selectively filter one rateset to another.
+ * 'basic_only' means only copy basic rates.
+ * 'rates' indicates cck (11b) and ofdm rates combinations.
+ * - 0: cck and ofdm
+ * - 1: cck only
+ * - 2: ofdm only
+ * 'xmask' is the copy mask (typically 0x7f or 0xff).
+ */
+void
+wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only,
+ uint8 rates, uint xmask, bool mcsallow)
+{
+ uint i;
+ uint r;
+ uint count;
+
+ count = 0;
+ for (i = 0; i < src->count; i++) {
+ r = src->rates[i];
+ if (basic_only && !(r & WLC_RATE_FLAG))
+ continue;
+ if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK)))
+ continue;
+ if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK)))
+ continue;
+ dst->rates[count++] = r & xmask;
+ }
+ dst->count = count;
+ dst->htphy_membership = src->htphy_membership;
+
+ if (mcsallow && rates != WLC_RATES_CCK)
+ bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN);
+ else
+ wlc_rateset_mcs_clear(dst);
+}
+
+/* select rateset for a given phy_type and bandtype and filter it, sort it
+ * and fill rs_tgt with result
+ */
+void
+wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw,
+ uint phy_type, int bandtype, bool cck_only, uint rate_mask,
+ bool mcsallow, uint8 bw, uint8 txstreams)
+{
+ const wlc_rateset_t *rs_dflt;
+ wlc_rateset_t rs_sel;
+ if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
+ (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
+ (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
+ (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
+ if (BAND_5G(bandtype)) {
+ rs_dflt = (bw == WLC_20_MHZ ?
+ &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
+ } else {
+ rs_dflt = (bw == WLC_20_MHZ ?
+ &cck_ofdm_mimo_rates :
+ &cck_ofdm_40bw_mimo_rates);
+ }
+ } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
+ rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates;
+ } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
+ rs_dflt = &ofdm_rates;
+ } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
+ rs_dflt = &cck_ofdm_rates;
+ } else {
+ ASSERT(0); /* should not happen */
+ rs_dflt = &cck_rates; /* force cck */
+ }
+
+ /* if hw rateset is not supplied, assign selected rateset to it */
+ if (!rs_hw)
+ rs_hw = rs_dflt;
+
+ wlc_rateset_copy(rs_dflt, &rs_sel);
+ wlc_rateset_mcs_upd(&rs_sel, txstreams);
+ wlc_rateset_filter(&rs_sel, rs_tgt, FALSE,
+ cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM,
+ rate_mask, mcsallow);
+ wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, FALSE,
+ mcsallow ? txstreams : 1);
+}
+
+int16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate)
+{
+ uint i;
+ for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
+ if (rate == legacy_phycfg_table[i].rate_ofdm)
+ return legacy_phycfg_table[i].tx_phy_ctl3;
+
+ return -1;
+}
+
+void wlc_rateset_mcs_clear(wlc_rateset_t *rateset)
+{
+ uint i;
+ for (i = 0; i < MCSSET_LEN; i++)
+ rateset->mcs[i] = 0;
+}
+
+void wlc_rateset_mcs_build(wlc_rateset_t *rateset, uint8 txstreams)
+{
+ bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN);
+ wlc_rateset_mcs_upd(rateset, txstreams);
+}
+
+/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
+void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, uint8 bw)
+{
+ if (bw == WLC_40_MHZ)
+ setbit(rateset->mcs, 32);
+ else
+ clrbit(rateset->mcs, 32);
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_rate.h b/drivers/staging/brcm80211/sys/wlc_rate.h
new file mode 100644
index 000000000000..c687d7bde30e
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_rate.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _WLC_RATE_H_
+#define _WLC_RATE_H_
+
+extern const uint8 rate_info[];
+extern const struct wlc_rateset cck_ofdm_mimo_rates;
+extern const struct wlc_rateset ofdm_mimo_rates;
+extern const struct wlc_rateset cck_ofdm_rates;
+extern const struct wlc_rateset ofdm_rates;
+extern const struct wlc_rateset cck_rates;
+extern const struct wlc_rateset gphy_legacy_rates;
+extern const struct wlc_rateset wlc_lrs_rates;
+extern const struct wlc_rateset rate_limit_1_2;
+
+typedef struct mcs_info {
+ uint32 phy_rate_20; /* phy rate in kbps [20Mhz] */
+ uint32 phy_rate_40; /* phy rate in kbps [40Mhz] */
+ uint32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */
+ uint32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */
+ uint8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
+ uint8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */
+} mcs_info_t;
+
+#define WLC_MAXMCS 32 /* max valid mcs index */
+#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
+extern const mcs_info_t mcs_table[];
+
+#define MCS_INVALID 0xFF
+#define MCS_CR_MASK 0x07 /* Code Rate bit mask */
+#define MCS_MOD_MASK 0x38 /* Modulation bit shift */
+#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */
+#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
+#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
+#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK)
+#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT)
+#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT)
+#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \
+ (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \
+ (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
+#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE))
+
+#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */
+
+/* Macros to use the rate_info table */
+#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
+#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
+
+#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */
+
+/* rate spec : holds rate and mode specific information required to generate a tx frame. */
+/* Legacy CCK and OFDM information is held in the same manner as was done in the past */
+/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */
+typedef uint32 ratespec_t;
+
+/* rate spec bit fields */
+#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */
+#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */
+#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */
+#define RSPEC_BW_SHIFT 8 /* mimo bw shift */
+#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */
+#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */
+#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */
+#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */
+#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */
+#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */
+#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */
+#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */
+#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
+#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */
+
+#define WLC_HTPHY 127 /* HT PHY Membership */
+
+#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE))
+#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \
+ MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \
+ (rspec & RSPEC_RATE_MASK))
+/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
+#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
+ MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \
+ (rspec & RSPEC_RATE_MASK))
+#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
+ MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\
+ (rspec & RSPEC_RATE_MASK))
+
+#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500)
+#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8)
+#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT)
+#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \
+ PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \
+ RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP))
+#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI)
+#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16)
+#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16))
+#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT)
+#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT)
+#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10)
+#define PLCP3_STC_MASK 0x30
+#define PLCP3_STC_SHIFT 4
+
+/* Rate info table; takes a legacy rate or ratespec_t */
+#define IS_MCS(r) (r & RSPEC_MIMORATE)
+#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG))
+#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \
+ ((r) & RATE_MASK) == WLC_RATE_2M || \
+ ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M))
+#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
+#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK)
+#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\
+ (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT))
+#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate))
+
+#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \
+ (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \
+ (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT)))
+
+/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
+extern const uint8 ofdm_rate_lookup[];
+#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7])
+#define CCK_PHY2MAC_RATE(signal) (signal/5)
+
+/* Rates specified in wlc_rateset_filter() */
+#define WLC_RATES_CCK_OFDM 0
+#define WLC_RATES_CCK 1
+#define WLC_RATES_OFDM 2
+
+/* use the stuct form instead of typedef to fix dependency problems */
+struct wlc_rateset;
+
+/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */
+extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs,
+ const struct wlc_rateset *hw_rs,
+ bool check_brate,
+ uint8 txstreams);
+/* copy rateset src to dst as-is (no masking or sorting) */
+extern void wlc_rateset_copy(const struct wlc_rateset *src,
+ struct wlc_rateset *dst);
+
+/* would be nice to have these documented ... */
+extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, uint8 *plcp);
+
+extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst,
+ bool basic_only, uint8 rates, uint xmask,
+ bool mcsallow);
+extern void wlc_rateset_default(struct wlc_rateset *rs_tgt,
+ const struct wlc_rateset *rs_hw, uint phy_type,
+ int bandtype, bool cck_only, uint rate_mask,
+ bool mcsallow, uint8 bw, uint8 txstreams);
+extern int16 wlc_rate_legacy_phyctl(uint rate);
+
+extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, uint8 txstreams);
+extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset);
+extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, uint8 txstreams);
+extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, uint8 bw);
+
+#endif /* _WLC_RATE_H_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_rpc.h b/drivers/staging/brcm80211/sys/wlc_rpc.h
new file mode 100644
index 000000000000..b582c104b29c
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_rpc.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _WLC_RPC_H_
+#define _WLC_RPC_H_
+
+#include <wlc_types.h>
+
+/* RPC IDs, reordering is OK. This needs to be in sync with RPC_ID_TABLE below */
+typedef enum {
+ WLRPC_NULL_ID = 0,
+ WLRPC_WLC_REG_READ_ID,
+ WLRPC_WLC_REG_WRITE_ID,
+ WLRPC_WLC_MHF_SET_ID,
+ WLRPC_WLC_MHF_GET_ID,
+ WLRPC_WLC_BMAC_UP_PREP_ID,
+ WLRPC_WLC_BMAC_UP_FINISH_ID,
+ WLRPC_WLC_BMAC_DOWN_PREP_ID,
+ WLRPC_WLC_BMAC_DOWN_FINISH_ID,
+ WLRPC_WLC_BMAC_WRITE_HW_BCNTEMPLATES_ID,
+ WLRPC_WLC_BMAC_RESET_ID,
+ WLRPC_WLC_DNGL_REBOOT_ID,
+ WLRPC_WLC_BMAC_RPC_TXQ_WM_SET_ID,
+ WLRPC_WLC_BMAC_RPC_TXQ_WM_GET_ID,
+ WLRPC_WLC_BMAC_RPC_AGG_SET_ID,
+ WLRPC_WLC_BMAC_RPC_MSGLEVEL_SET_ID,
+ WLRPC_WLC_BMAC_RPC_AGG_LIMIT_SET_ID,
+ WLRPC_WLC_BMAC_RPC_AGG_LIMIT_GET_ID,
+ WLRPC_WLC_BMAC_INIT_ID,
+ WLRPC_WLC_BMAC_SET_CWMIN_ID,
+ WLRPC_WLC_BMAC_MUTE_ID,
+ WLRPC_WLC_PHY_DOIOVAR_ID,
+ WLRPC_WLC_PHY_HOLD_UPD_ID,
+ WLRPC_WLC_PHY_MUTE_UPD_ID,
+ WLRPC_WLC_PHY_CLEAR_TSSI_ID,
+ WLRPC_WLC_PHY_ANT_RXDIV_GET_ID,
+ WLRPC_WLC_PHY_ANT_RXDIV_SET_ID,
+ WLRPC_WLC_PHY_PREAMBLE_SET_ID,
+ WLRPC_WLC_PHY_FREQTRACK_END_ID,
+ WLRPC_WLC_PHY_FREQTRACK_START_ID,
+ WLRPC_WLC_PHY_IOCTL_ID,
+ WLRPC_WLC_PHY_NOISE_SAMPLE_REQUEST_ID,
+ WLRPC_WLC_PHY_CAL_PERICAL_ID,
+ WLRPC_WLC_PHY_TXPOWER_GET_ID,
+ WLRPC_WLC_PHY_TXPOWER_SET_ID,
+ WLRPC_WLC_PHY_TXPOWER_SROMLIMIT_ID,
+ WLRPC_WLC_PHY_RADAR_DETECT_ENABLE_ID,
+ WLRPC_WLC_PHY_RADAR_DETECT_RUN_ID,
+ WLRPC_WLC_PHY_TEST_ISON_ID,
+ WLRPC_WLC_BMAC_COPYFROM_OBJMEM_ID,
+ WLRPC_WLC_BMAC_COPYTO_OBJMEM_ID,
+ WLRPC_WLC_ENABLE_MAC_ID,
+ WLRPC_WLC_MCTRL_ID,
+ WLRPC_WLC_CORERESET_ID,
+ WLRPC_WLC_BMAC_READ_SHM_ID,
+ WLRPC_WLC_BMAC_READ_TSF_ID,
+ WLRPC_WLC_BMAC_SET_ADDRMATCH_ID,
+ WLRPC_WLC_BMAC_SET_CWMAX_ID,
+ WLRPC_WLC_BMAC_SET_RCMTA_ID,
+ WLRPC_WLC_BMAC_SET_SHM_ID,
+ WLRPC_WLC_SUSPEND_MAC_AND_WAIT_ID,
+ WLRPC_WLC_BMAC_WRITE_SHM_ID,
+ WLRPC_WLC_BMAC_WRITE_TEMPLATE_RAM_ID,
+ WLRPC_WLC_TX_FIFO_SUSPEND_ID,
+ WLRPC_WLC_TX_FIFO_RESUME_ID,
+ WLRPC_WLC_TX_FIFO_SUSPENDED_ID,
+ WLRPC_WLC_HW_ETHERADDR_ID,
+ WLRPC_WLC_SET_HW_ETHERADDR_ID,
+ WLRPC_WLC_BMAC_CHANSPEC_SET_ID,
+ WLRPC_WLC_BMAC_TXANT_SET_ID,
+ WLRPC_WLC_BMAC_ANTSEL_TYPE_SET_ID,
+ WLRPC_WLC_BMAC_TXFIFO_ID,
+ WLRPC_WLC_RADIO_READ_HWDISABLED_ID,
+ WLRPC_WLC_RM_CCA_MEASURE_ID,
+ WLRPC_WLC_SET_SHORTSLOT_ID,
+ WLRPC_WLC_WAIT_FOR_WAKE_ID,
+ WLRPC_WLC_PHY_TXPOWER_GET_CURRENT_ID,
+ WLRPC_WLC_PHY_TXPOWER_HW_CTRL_GET_ID,
+ WLRPC_WLC_PHY_TXPOWER_HW_CTRL_SET_ID,
+ WLRPC_WLC_PHY_BSSINIT_ID,
+ WLRPC_WLC_BAND_STF_SS_SET_ID,
+ WLRPC_WLC_PHY_BAND_FIRST_CHANSPEC_ID,
+ WLRPC_WLC_PHY_TXPOWER_LIMIT_SET_ID,
+ WLRPC_WLC_PHY_BAND_CHANNELS_ID,
+ WLRPC_WLC_BMAC_REVINFO_GET_ID,
+ WLRPC_WLC_BMAC_STATE_GET_ID,
+ WLRPC_WLC_BMAC_XMTFIFO_SZ_GET_ID,
+ WLRPC_WLC_BMAC_XMTFIFO_SZ_SET_ID,
+ WLRPC_WLC_BMAC_VALIDATE_CHIP_ACCESS_ID,
+ WLRPC_WLC_RM_CCA_COMPLETE_ID,
+ WLRPC_WLC_RECV_ID,
+ WLRPC_WLC_DOTXSTATUS_ID,
+ WLRPC_WLC_HIGH_DPC_ID,
+ WLRPC_WLC_FATAL_ERROR_ID,
+ WLRPC_WLC_PHY_SET_CHANNEL_14_WIDE_FILTER_ID,
+ WLRPC_WLC_PHY_NOISE_AVG_ID,
+ WLRPC_WLC_PHYCHAIN_INIT_ID,
+ WLRPC_WLC_PHYCHAIN_SET_ID,
+ WLRPC_WLC_PHYCHAIN_GET_ID,
+ WLRPC_WLC_PHY_TKIP_RIFS_WAR_ID,
+ WLRPC_WLC_BMAC_COPYFROM_VARS_ID,
+ WLRPC_WLC_BMAC_RETRYLIMIT_UPD_ID,
+ WLRPC_WLC_BMAC_BTC_MODE_SET_ID,
+ WLRPC_WLC_BMAC_BTC_MODE_GET_ID,
+ WLRPC_WLC_BMAC_BTC_WIRE_SET_ID,
+ WLRPC_WLC_BMAC_BTC_WIRE_GET_ID,
+ WLRPC_WLC_BMAC_SET_NORESET_ID,
+ WLRPC_WLC_AMPDU_TXSTATUS_COMPLETE_ID,
+ WLRPC_WLC_BMAC_FIFOERRORS_ID,
+ WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MIN_ID,
+ WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MAX_ID,
+ WLRPC_WLC_NOISE_CB_ID,
+ WLRPC_WLC_BMAC_LED_HW_DEINIT_ID,
+ WLRPC_WLC_BMAC_LED_HW_MASK_INIT_ID,
+ WLRPC_WLC_PLLREQ_ID,
+ WLRPC_WLC_BMAC_TACLEAR_ID,
+ WLRPC_WLC_BMAC_SET_CLK_ID,
+ WLRPC_WLC_PHY_OFDM_RATESET_WAR_ID,
+ WLRPC_WLC_PHY_BF_PREEMPT_ENABLE_ID,
+ WLRPC_WLC_BMAC_DOIOVARS_ID,
+ WLRPC_WLC_BMAC_DUMP_ID,
+ WLRPC_WLC_CISWRITE_ID,
+ WLRPC_WLC_CISDUMP_ID,
+ WLRPC_WLC_UPDATE_PHY_MODE_ID,
+ WLRPC_WLC_RESET_BMAC_DONE_ID,
+ WLRPC_WLC_BMAC_LED_BLINK_EVENT_ID,
+ WLRPC_WLC_BMAC_LED_SET_ID,
+ WLRPC_WLC_BMAC_LED_BLINK_ID,
+ WLRPC_WLC_BMAC_LED_ID,
+ WLRPC_WLC_BMAC_RATE_SHM_OFFSET_ID,
+ WLRPC_SI_ISCORE_UP_ID,
+ WLRPC_WLC_BMAC_PS_SWITCH_ID,
+ WLRPC_WLC_PHY_STF_SSMODE_GET_ID,
+ WLRPC_WLC_BMAC_DEBUG_ID,
+ WLRPC_WLC_EXTLOG_MSG_ID,
+ WLRPC_WLC_EXTLOG_CFG_ID,
+ WLRPC_BCM_ASSERT_LOG_ID,
+ WLRPC_BCM_ASSERT_TYPE_ID,
+ WLRPC_WLC_BMAC_SET_PHYCAL_CACHE_FLAG_ID,
+ WLRPC_WLC_BMAC_GET_PHYCAL_CACHE_FLAG_ID,
+ WLRPC_WLC_PHY_CAL_CACHE_INIT_ID,
+ WLRPC_WLC_PHY_CAL_CACHE_DEINIT_ID,
+ WLRPC_WLC_BMAC_HW_UP_ID,
+ WLRPC_WLC_BMAC_SET_TXPWR_PERCENT_ID,
+ WLRPC_WLC_PHYCHAIN_ACTIVE_GET_ID,
+ WLRPC_WLC_BMAC_BLINK_SYNC_ID,
+ WLRPC_WLC_BMAC_UCODE_DBGSEL_SET_ID,
+ WLRPC_WLC_BMAC_UCODE_DBGSEL_GET_ID,
+ WLRPC_WLC_PHY_RADAR_DETECT_MODE_SET_ID,
+ WLRPC_WLC_PHY_ACIM_NOISEM_RESET_NPHY_ID,
+ WLRPC_WLC_PHY_INTERFER_SET_NPHY_ID,
+ WLRPC_WLC_BMAC_IFSCTL_EDCRS_SET_ID,
+ WLRPC_WLC_PKTENGTX,
+ WLRPC_WLC_BMAC_SET_DEAF,
+ WLRPC_WLC_BMAC_CLEAR_DEAF,
+ WLRPC_WLC_BMAC_BTC_FLAGS_SET_ID,
+ WLRPC_WLC_BMAC_BTC_FLAGS_GET_ID,
+ WLRPC_WLC_BMAC_SET_RCMTA_TYPE_ID,
+ WLRPC_WLC_BMAC_BTC_FLAGS_UPD_ID,
+ WLRPC_WLC_BMAC_BTC_STUCKWAR_ID,
+ WLRPC_WLC_BMAC_CCA_STATS_READ_ID,
+ WLRPC_WLC_BMAC_ANTSEL_SET_ID,
+ WLRPC_WLC_BMAC_SET_UCODE_LOADED,
+ WLRPC_WLC_PHY_LDPC_SET_ID,
+
+ WLRPC_LAST
+} wlc_rpc_id_t;
+
+#if defined(BCMDBG) | 0
+struct name_entry {
+ int id;
+ char *name;
+};
+
+#define NAME_ENTRY(x) {x, #x}
+
+#define RPC_ID_TABLE { \
+ NAME_ENTRY(WLRPC_WLC_REG_READ_ID), \
+ NAME_ENTRY(WLRPC_WLC_REG_WRITE_ID), \
+ NAME_ENTRY(WLRPC_WLC_MHF_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_MHF_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_UP_PREP_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_UP_FINISH_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_DOWN_PREP_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_DOWN_FINISH_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_HW_BCNTEMPLATES_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RESET_ID), \
+ NAME_ENTRY(WLRPC_WLC_DNGL_REBOOT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_TXQ_WM_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_TXQ_WM_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_MSGLEVEL_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_LIMIT_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_LIMIT_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_INIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_CWMIN_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_MUTE_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_DOIOVAR_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_HOLD_UPD_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_MUTE_UPD_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_CLEAR_TSSI_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_ANT_RXDIV_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_ANT_RXDIV_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_PREAMBLE_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_FREQTRACK_END_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_FREQTRACK_START_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_IOCTL_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_NOISE_SAMPLE_REQUEST_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_CAL_PERICAL_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_SROMLIMIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_ENABLE_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_RUN_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TEST_ISON_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_COPYFROM_OBJMEM_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_COPYTO_OBJMEM_ID), \
+ NAME_ENTRY(WLRPC_WLC_ENABLE_MAC_ID), \
+ NAME_ENTRY(WLRPC_WLC_MCTRL_ID), \
+ NAME_ENTRY(WLRPC_WLC_CORERESET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_READ_SHM_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_READ_TSF_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_ADDRMATCH_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_CWMAX_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_RCMTA_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_SHM_ID), \
+ NAME_ENTRY(WLRPC_WLC_SUSPEND_MAC_AND_WAIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_SHM_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_TEMPLATE_RAM_ID), \
+ NAME_ENTRY(WLRPC_WLC_TX_FIFO_SUSPEND_ID), \
+ NAME_ENTRY(WLRPC_WLC_TX_FIFO_RESUME_ID), \
+ NAME_ENTRY(WLRPC_WLC_TX_FIFO_SUSPENDED_ID), \
+ NAME_ENTRY(WLRPC_WLC_HW_ETHERADDR_ID), \
+ NAME_ENTRY(WLRPC_WLC_SET_HW_ETHERADDR_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_CHANSPEC_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_TXANT_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_ANTSEL_TYPE_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_TXFIFO_ID), \
+ NAME_ENTRY(WLRPC_WLC_RADIO_READ_HWDISABLED_ID), \
+ NAME_ENTRY(WLRPC_WLC_RM_CCA_MEASURE_ID), \
+ NAME_ENTRY(WLRPC_WLC_SET_SHORTSLOT_ID), \
+ NAME_ENTRY(WLRPC_WLC_WAIT_FOR_WAKE_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_CURRENT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_HW_CTRL_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_HW_CTRL_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_BSSINIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BAND_STF_SS_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_BAND_FIRST_CHANSPEC_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_LIMIT_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_BAND_CHANNELS_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_REVINFO_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_STATE_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_XMTFIFO_SZ_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_XMTFIFO_SZ_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_VALIDATE_CHIP_ACCESS_ID), \
+ NAME_ENTRY(WLRPC_WLC_RM_CCA_COMPLETE_ID), \
+ NAME_ENTRY(WLRPC_WLC_RECV_ID), \
+ NAME_ENTRY(WLRPC_WLC_DOTXSTATUS_ID), \
+ NAME_ENTRY(WLRPC_WLC_HIGH_DPC_ID), \
+ NAME_ENTRY(WLRPC_WLC_FATAL_ERROR_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_SET_CHANNEL_14_WIDE_FILTER_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_NOISE_AVG_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHYCHAIN_INIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHYCHAIN_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHYCHAIN_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TKIP_RIFS_WAR_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_COPYFROM_VARS_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RETRYLIMIT_UPD_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_MODE_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_MODE_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_WIRE_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_WIRE_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_NORESET_ID), \
+ NAME_ENTRY(WLRPC_WLC_AMPDU_TXSTATUS_COMPLETE_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_FIFOERRORS_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MIN_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MAX_ID), \
+ NAME_ENTRY(WLRPC_WLC_NOISE_CB_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_HW_DEINIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_HW_MASK_INIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PLLREQ_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_TACLEAR_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_CLK_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_OFDM_RATESET_WAR_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_BF_PREEMPT_ENABLE_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_DOIOVARS_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_DUMP_ID), \
+ NAME_ENTRY(WLRPC_WLC_CISWRITE_ID), \
+ NAME_ENTRY(WLRPC_WLC_CISDUMP_ID), \
+ NAME_ENTRY(WLRPC_WLC_UPDATE_PHY_MODE_ID), \
+ NAME_ENTRY(WLRPC_WLC_RESET_BMAC_DONE_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_BLINK_EVENT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_BLINK_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_LED_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_RATE_SHM_OFFSET_ID), \
+ NAME_ENTRY(WLRPC_SI_ISCORE_UP_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_PS_SWITCH_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_STF_SSMODE_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_DEBUG_ID), \
+ NAME_ENTRY(WLRPC_WLC_EXTLOG_MSG_ID), \
+ NAME_ENTRY(WLRPC_WLC_EXTLOG_CFG_ID), \
+ NAME_ENTRY(WLRPC_BCM_ASSERT_LOG_ID), \
+ NAME_ENTRY(WLRPC_BCM_ASSERT_TYPE_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_PHYCAL_CACHE_FLAG_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_GET_PHYCAL_CACHE_FLAG_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_CAL_CACHE_INIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_CAL_CACHE_DEINIT_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_HW_UP_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_TXPWR_PERCENT_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHYCHAIN_ACTIVE_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BLINK_SYNC_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_UCODE_DBGSEL_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_UCODE_DBGSEL_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_MODE_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_ACIM_NOISEM_RESET_NPHY_ID), \
+ NAME_ENTRY(WLRPC_WLC_PHY_INTERFER_SET_NPHY_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_IFSCTL_EDCRS_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_PKTENGTX), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_DEAF), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_CLEAR_DEAF), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_FLAGS_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_BTC_FLAGS_GET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_RCMTA_TYPE_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_CCA_STATS_READ_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_ANTSEL_SET_ID), \
+ NAME_ENTRY(WLRPC_WLC_BMAC_SET_UCODE_LOADED), \
+ NAME_ENTRY(WLRPC_WLC_PHY_LDPC_SET_ID), \
+ {0, NULL} \
+ }
+
+static __inline char *_wlc_rpc_id_lookup(const struct name_entry *tbl, int _id)
+{
+ const struct name_entry *elt = tbl;
+ static char __unknown[64];
+ for (; elt->name != NULL; elt++) {
+ if (_id == elt->id)
+ break;
+ }
+ if (_id == elt->id)
+ strncpy(__unknown, elt->name, sizeof(__unknown));
+ else
+ snprintf(__unknown, sizeof(__unknown), "ID:%d", _id);
+ return __unknown;
+}
+
+#define WLC_RPC_ID_LOOKUP(tbl, _id) (_wlc_rpc_id_lookup(tbl, _id))
+
+#endif /* BCMDBG */
+
+/* refer to txpwr_limits_t for each elements, mcs32 is the at the end for 1 byte */
+#define TXPOWER_XDR_SZ (ROUNDUP(WLC_NUM_RATES_CCK, 4) + ROUNDUP(WLC_NUM_RATES_OFDM, 4) * 4 + \
+ ROUNDUP(WLC_NUM_RATES_MCS_1_STREAM, 4) * 6 + ROUNDUP(WLC_NUM_RATES_MCS_2_STREAM, 4) * 2 + \
+ ROUNDUP(1, 4))
+
+#define wlc_rpc_txpwr_limits(b, txpwr, op, err) \
+ do { \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->cck, WLC_NUM_RATES_CCK); \
+ ASSERT(!(err)); \
+ \
+ /* 20 MHz Legacy OFDM rates with SISO transmission */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->ofdm, WLC_NUM_RATES_OFDM); \
+ ASSERT(!(err)); \
+ \
+ /* 20 MHz Legacy OFDM rates with CDD transmission */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->ofdm_cdd, WLC_NUM_RATES_OFDM); \
+ ASSERT(!(err)); \
+ \
+ /* 40 MHz Legacy OFDM rates with SISO transmission */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->ofdm_40_siso, WLC_NUM_RATES_OFDM); \
+ ASSERT(!(err)); \
+ \
+ /* 40 MHz Legacy OFDM rates with CDD transmission */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->ofdm_40_cdd, WLC_NUM_RATES_OFDM); \
+ ASSERT(!(err)); \
+ \
+ /* 20MHz MCS rates SISO/CDD/STBC/SDM */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_20_siso, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_20_cdd, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_20_stbc, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_20_mimo, WLC_NUM_RATES_MCS_2_STREAM); \
+ ASSERT(!(err)); \
+ \
+ /* 40MHz MCS rates SISO/CDD/STBC/SDM */ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_40_siso, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_40_cdd, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_40_stbc, WLC_NUM_RATES_MCS_1_STREAM); \
+ ASSERT(!(err)); \
+ \
+ (err) = bcm_xdr_##op##_uint8_vec((b), (txpwr)->mcs_40_mimo, WLC_NUM_RATES_MCS_2_STREAM); \
+ ASSERT(!(err)); \
+ } while (0)
+
+typedef struct wlc_rpc_ctx {
+ rpc_info_t *rpc;
+ wlc_info_t *wlc;
+ wlc_hw_info_t *wlc_hw;
+} wlc_rpc_ctx_t;
+
+static INLINE rpc_buf_t *wlc_rpc_buf_alloc(rpc_info_t *rpc, bcm_xdr_buf_t *b,
+ uint len, wlc_rpc_id_t rpc_id)
+{
+ rpc_buf_t *rpc_buf;
+
+ rpc_buf = bcm_rpc_buf_alloc(rpc, len + sizeof(uint32));
+
+ if (!rpc_buf)
+ return NULL;
+
+ bcm_xdr_buf_init(b, bcm_rpc_buf_data(bcm_rpc_tp_get(rpc), rpc_buf),
+ len + sizeof(uint32));
+
+ bcm_xdr_pack_uint32(b, rpc_id);
+
+ return rpc_buf;
+}
+
+#if defined(BCMDBG)
+static __inline wlc_rpc_id_t
+wlc_rpc_id_get(struct rpc_info *rpc, rpc_buf_t *buf)
+{
+ wlc_rpc_id_t rpc_id;
+ bcm_xdr_buf_t b;
+
+ bcm_xdr_buf_init(&b, bcm_rpc_buf_data(bcm_rpc_tp_get(rpc), buf),
+ sizeof(uint32));
+
+ bcm_xdr_unpack_uint32(&b, (uint32 *) ((uintptr) & rpc_id));
+ return rpc_id;
+}
+#endif
+
+static __inline int _wlc_rpc_call(struct rpc_info *rpc, rpc_buf_t *send)
+{
+ int _err = 0;
+#if defined(BCMDBG)
+ wlc_rpc_id_t rpc_id = wlc_rpc_id_get(rpc, send);
+ /* const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE; */
+ static struct name_entry rpc_name_tbl[] = RPC_ID_TABLE;
+ WL_TRACE(("%s: Called id %s\n", __func__,
+ WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id)));
+#endif
+ _err = bcm_rpc_call(rpc, send);
+ if (_err) {
+#if defined(BCMDBG)
+ WL_ERROR(("%s: Call id %s FAILED\n", __func__,
+ WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id)));
+#endif
+ _err = 0;
+ }
+ return _err;
+}
+
+#define wlc_rpc_call(rpc, send) (_wlc_rpc_call(rpc, send))
+
+#include <sbhnddma.h>
+#include <sbhndpio.h>
+#include <d11.h>
+
+#ifdef WLC_LOW
+extern void wlc_rpc_bmac_dispatch(wlc_rpc_ctx_t *rpc_ctx, struct rpc_buf *buf);
+extern void wlc_rpc_bmac_dump_txfifohist(wlc_hw_info_t *wlc_hw,
+ bool dump_clear);
+#else
+extern void wlc_rpc_high_dispatch(wlc_rpc_ctx_t *ctx, struct rpc_buf *buf);
+#endif
+
+/* Packed structure for ease of transport across RPC bus along uint32 boundary */
+typedef struct wlc_rpc_txstatus {
+ uint32 PAD_framelen;
+ uint32 status_frameid;
+ uint32 sequence_lasttxtime;
+ uint32 ackphyrxsh_phyerr;
+} wlc_rpc_txstatus_t;
+
+static INLINE
+ void txstatus2rpc_txstatus(tx_status_t *txstatus,
+ wlc_rpc_txstatus_t *rpc_txstatus)
+{
+ rpc_txstatus->PAD_framelen = txstatus->framelen;
+ rpc_txstatus->status_frameid =
+ (txstatus->status << 16) | txstatus->frameid;
+ rpc_txstatus->sequence_lasttxtime =
+ (txstatus->sequence << 16) | txstatus->lasttxtime;
+ rpc_txstatus->ackphyrxsh_phyerr =
+ (txstatus->ackphyrxsh << 16) | txstatus->phyerr;
+}
+
+static INLINE
+ void rpc_txstatus2txstatus(wlc_rpc_txstatus_t *rpc_txstatus,
+ tx_status_t *txstatus)
+{
+ txstatus->framelen = rpc_txstatus->PAD_framelen & 0xffff;
+ txstatus->status = (rpc_txstatus->status_frameid >> 16) & 0xffff;
+ txstatus->frameid = rpc_txstatus->status_frameid & 0xffff;
+ txstatus->sequence = (rpc_txstatus->sequence_lasttxtime >> 16) & 0xffff;
+ txstatus->lasttxtime = rpc_txstatus->sequence_lasttxtime & 0xffff;
+ txstatus->ackphyrxsh = (rpc_txstatus->ackphyrxsh_phyerr >> 16) & 0xffff;
+ txstatus->phyerr = rpc_txstatus->ackphyrxsh_phyerr & 0xffff;
+}
+
+extern void wlc_bmac_dngl_reboot(rpc_info_t *rpc);
+
+#endif /* WLC_RPC_H */
diff --git a/drivers/staging/brcm80211/sys/wlc_rpctx.h b/drivers/staging/brcm80211/sys/wlc_rpctx.h
new file mode 100644
index 000000000000..a07c68b45890
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_rpctx.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_rpctx_h_
+#define _wlc_rpctx_h_
+
+/* forward declaration */
+struct wlc_info;
+
+/* This controls how many packets are given to the dongle. This is required as
+ * NTXD needs to be power of 2 but we may not have enough memory to absorb that
+ * large number of frames
+ */
+#ifndef NRPCTXBUFPOST
+#define NRPCTXBUFPOST NTXD
+#endif
+
+#if defined(WLC_HIGH_ONLY)
+
+struct wlc_rpc_phy {
+ struct rpc_info *rpc;
+};
+
+#define RPCTX_ENAB(pub) (TRUE)
+extern rpctx_info_t *wlc_rpctx_attach(wlc_pub_t *pub, struct wlc_info *wlc);
+extern int wlc_rpctx_fifoinit(rpctx_info_t *rpctx, uint fifo, uint ntxd);
+extern void wlc_rpctx_detach(rpctx_info_t *rpctx);
+extern int wlc_rpctx_dump(rpctx_info_t *rpctx, struct bcmstrbuf *b);
+extern void *wlc_rpctx_getnexttxp(rpctx_info_t *rpctx, uint fifo);
+extern void wlc_rpctx_txreclaim(rpctx_info_t *rpctx);
+extern uint wlc_rpctx_txavail(rpctx_info_t *rpctx, uint fifo);
+extern int wlc_rpctx_pkteng(rpctx_info_t *rpctx, uint fifo, void *p);
+extern int wlc_rpctx_tx(rpctx_info_t *rpctx, uint fifo, void *p, bool commit,
+ uint16 frameid, uint8 txpktpend);
+extern void wlc_rpctx_txpktpendinc(rpctx_info_t *rpctx, uint fifo, uint8 val);
+extern void wlc_rpctx_txpktpenddec(rpctx_info_t *rpctx, uint fifo, uint8 val);
+extern void wlc_rpctx_txpktpendclr(rpctx_info_t *rpctx, uint fifo);
+extern int wlc_rpctx_txpktpend(rpctx_info_t *rpctx, uint fifo, bool all);
+
+#else
+#define RPCTX_ENAB(pub) (FALSE)
+#define wlc_rpctx_attach(pub, wlc) (NULL)
+#define wlc_rpctx_fifoinit(rpctx, fifo, ntxd) (0)
+#define wlc_rpctx_detach(rpctx) ASSERT(0)
+#define wlc_rpctx_txavail(rpctx, f) (FALSE)
+#define wlc_rpctx_dump(rpctx, b) (0)
+#define wlc_rpctx_getnexttxp(rpctx, f) (NULL)
+#define wlc_rpctx_txreclaim(rpctx) ASSERT(0)
+#define wlc_rpctx_pkteng(rpctx, fifo, p) do { } while (0)
+#define wlc_rpctx_tx(rpctx, f, p, c, fid, t) (0)
+#define wlc_rpctx_txpktpendinc(rpctx, f, val) do { } while (0)
+#define wlc_rpctx_txpktpenddec(rpctx, f, val) do { } while (0)
+#define wlc_rpctx_txpktpendclr(rpctx, f) do { } while (0)
+#define wlc_rpctx_txpktpend(rpctx, f, all) (0)
+
+#endif /* WLC_HIGH */
+
+#endif /* _wlc_rpctx_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_scb.h b/drivers/staging/brcm80211/sys/wlc_scb.h
new file mode 100644
index 000000000000..5634796c3ac6
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_scb.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_scb_h_
+#define _wlc_scb_h_
+
+#include <proto/802.1d.h>
+
+extern bool wlc_aggregatable(wlc_info_t *wlc, uint8 tid);
+
+#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
+/* structure to store per-tid state for the ampdu initiator */
+typedef struct scb_ampdu_tid_ini {
+ uint32 magic;
+ uint8 tx_in_transit; /* number of pending mpdus in transit in driver */
+ uint8 tid; /* initiator tid for easy lookup */
+ uint8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */
+ struct scb *scb; /* backptr for easy lookup */
+} scb_ampdu_tid_ini_t;
+
+#define AMPDU_MAX_SCB_TID NUMPRIO
+
+typedef struct scb_ampdu {
+ struct scb *scb; /* back pointer for easy reference */
+ uint8 mpdu_density; /* mpdu density */
+ uint8 max_pdu; /* max pdus allowed in ampdu */
+ uint8 release; /* # of mpdus released at a time */
+ uint16 min_len; /* min mpdu len to support the density */
+ uint32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
+ struct pktq txq; /* sdu transmit queue pending aggregation */
+
+ /* This could easily be a ini[] pointer and we keep this info in wl itself instead
+ * of having mac80211 hold it for us. Also could be made dynamic per tid instead of
+ * static.
+ */
+ scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */
+} scb_ampdu_t;
+
+#define SCB_MAGIC 0xbeefcafe
+#define INI_MAGIC 0xabcd1234
+
+/* station control block - one per remote MAC address */
+struct scb {
+ uint32 magic;
+ uint32 flags; /* various bit flags as defined below */
+ uint32 flags2; /* various bit flags2 as defined below */
+ uint8 state; /* current state bitfield of auth/assoc process */
+ struct ether_addr ea; /* station address */
+ void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */
+ uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */
+
+ uint16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
+ uint16 seqctl_nonqos; /* seqctl of last received frame (for dups) for
+ * non-QoS data and management
+ */
+ uint16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */
+
+ scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */
+};
+
+/* SCB flags */
+#define SCB_NONERP 0x0001 /* No ERP */
+#define SCB_LONGSLOT 0x0002 /* Long Slot */
+#define SCB_SHORTPREAMBLE 0x0004 /* Short Preamble ok */
+#define SCB_8021XHDR 0x0008 /* 802.1x Header */
+#define SCB_WPA_SUP 0x0010 /* 0 - authenticator, 1 - supplicant */
+#define SCB_DEAUTH 0x0020 /* 0 - ok to deauth, 1 - no (just did) */
+#define SCB_WMECAP 0x0040 /* WME Cap; may ONLY be set if WME_ENAB(wlc) */
+#define SCB_BRCM 0x0100 /* BRCM AP or STA */
+#define SCB_WDS_LINKUP 0x0200 /* WDS link up */
+#define SCB_RESERVED1 0x0400
+#define SCB_RESERVED2 0x0800
+#define SCB_MYAP 0x1000 /* We are associated to this AP */
+#define SCB_PENDING_PROBE 0x2000 /* Probe is pending to this SCB */
+#define SCB_AMSDUCAP 0x4000 /* A-MSDU capable */
+#define SCB_BACAP 0x8000 /* pre-n blockack capable */
+#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
+#define SCB_RECV_PM 0x20000 /* state of PM bit in last data frame recv'd */
+#define SCB_AMPDUCAP 0x40000 /* A-MPDU capable */
+#define SCB_IS40 0x80000 /* 40MHz capable */
+#define SCB_NONGF 0x100000 /* Not Green Field capable */
+#define SCB_APSDCAP 0x200000 /* APSD capable */
+#define SCB_PENDING_FREE 0x400000 /* marked for deletion - clip recursion */
+#define SCB_PENDING_PSPOLL 0x800000 /* PS-Poll is pending to this SCB */
+#define SCB_RIFSCAP 0x1000000 /* RIFS capable */
+#define SCB_HT40INTOLERANT 0x2000000 /* 40 Intolerant */
+#define SCB_WMEPS 0x4000000 /* PS + WME w/o APSD capable */
+#define SCB_SENT_APSD_TRIG 0x8000000 /* APSD Trigger Null Frame was recently sent */
+#define SCB_COEX_MGMT 0x10000000 /* Coexistence Management supported */
+#define SCB_IBSS_PEER 0x20000000 /* Station is an IBSS peer */
+#define SCB_STBCCAP 0x40000000 /* STBC Capable */
+
+/* scb flags2 */
+#define SCB2_SGI20_CAP 0x00000001 /* 20MHz SGI Capable */
+#define SCB2_SGI40_CAP 0x00000002 /* 40MHz SGI Capable */
+#define SCB2_RX_LARGE_AGG 0x00000004 /* device can rx large aggs */
+#define SCB2_INTERNAL 0x00000008 /* This scb is an internal scb */
+#define SCB2_IN_ASSOC 0x00000010 /* Incoming assocation in progress */
+#define SCB2_RESERVED1 0x00000040
+#define SCB2_LDPCCAP 0x00000080 /* LDPC Cap */
+
+/* scb association state bitfield */
+#define UNAUTHENTICATED 0 /* unknown */
+#define AUTHENTICATED 1 /* 802.11 authenticated (open or shared key) */
+#define ASSOCIATED 2 /* 802.11 associated */
+#define PENDING_AUTH 4 /* Waiting for 802.11 authentication response */
+#define PENDING_ASSOC 8 /* Waiting for 802.11 association response */
+#define AUTHORIZED 0x10 /* 802.1X authorized */
+#define TAKEN4IBSS 0x80 /* Taken */
+
+/* scb association state helpers */
+#define SCB_ASSOCIATED(a) ((a)->state & ASSOCIATED)
+#define SCB_AUTHENTICATED(a) ((a)->state & AUTHENTICATED)
+#define SCB_AUTHORIZED(a) ((a)->state & AUTHORIZED)
+
+/* flag access */
+#define SCB_ISMYAP(a) ((a)->flags & SCB_MYAP)
+#define SCB_ISPERMANENT(a) ((a)->permanent)
+#define SCB_INTERNAL(a) ((a)->flags2 & SCB2_INTERNAL)
+/* scb association state helpers w/ respect to ssid (in case of multi ssids)
+ * The bit set in the bit field is relative to the current state (i.e. if
+ * the current state is "associated", a 1 at the position "i" means the
+ * sta is associated to ssid "i"
+ */
+#define SCB_ASSOCIATED_BSSCFG(a, i) \
+ (((a)->state & ASSOCIATED) && isset(&(scb->auth_bsscfg), i))
+
+#define SCB_AUTHENTICATED_BSSCFG(a, i) \
+ (((a)->state & AUTHENTICATED) && isset(&(scb->auth_bsscfg), i))
+
+#define SCB_AUTHORIZED_BSSCFG(a, i) \
+ (((a)->state & AUTHORIZED) && isset(&(scb->auth_bsscfg), i))
+
+#define SCB_LONG_TIMEOUT 3600 /* # seconds of idle time after which we proactively
+ * free an authenticated SCB
+ */
+#define SCB_SHORT_TIMEOUT 60 /* # seconds of idle time after which we will reclaim an
+ * authenticated SCB if we would otherwise fail
+ * an SCB allocation.
+ */
+#define SCB_TIMEOUT 60 /* # seconds: interval to probe idle STAs */
+#define SCB_ACTIVITY_TIME 5 /* # seconds: skip probe if activity during this time */
+#define SCB_GRACE_ATTEMPTS 3 /* # attempts to probe sta beyond scb_activity_time */
+
+/* scb_info macros */
+#define SCB_PS(a) NULL
+#define SCB_WDS(a) NULL
+#define SCB_INTERFACE(a) ((a)->bsscfg->wlcif->wlif)
+#define SCB_WLCIFP(a) (((a)->bsscfg->wlcif))
+#define WLC_BCMC_PSMODE(wlc, bsscfg) (TRUE)
+
+#define SCB_WME(a) ((a)->flags & SCB_WMECAP) /* Also implies WME_ENAB(wlc) */
+
+#define SCB_AMPDU(a) TRUE
+#define SCB_AMSDU(a) FALSE
+
+#define SCB_HT_CAP(a) ((a)->flags & SCB_HTCAP)
+#define SCB_ISGF_CAP(a) (((a)->flags & (SCB_HTCAP | SCB_NONGF)) == SCB_HTCAP)
+#define SCB_NONGF_CAP(a) (((a)->flags & (SCB_HTCAP | SCB_NONGF)) == \
+ (SCB_HTCAP | SCB_NONGF))
+#define SCB_COEX_CAP(a) ((a)->flags & SCB_COEX_MGMT)
+#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP)
+#define SCB_LDPC_CAP(a) (SCB_HT_CAP(a) && ((a)->flags2 & SCB2_LDPCCAP))
+
+#define SCB_IS_IBSS_PEER(a) ((a)->flags & SCB_IBSS_PEER)
+#define SCB_SET_IBSS_PEER(a) ((a)->flags |= SCB_IBSS_PEER)
+#define SCB_UNSET_IBSS_PEER(a) ((a)->flags &= ~SCB_IBSS_PEER)
+
+#define SCB_11E(a) FALSE
+
+#define SCB_QOS(a) ((a)->flags & (SCB_WMECAP | SCB_HTCAP))
+
+#define SCB_BSSCFG(a) ((a)->bsscfg)
+
+#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)])
+
+#define SCB_ISMULTI(a) ETHER_ISMULTI((a)->ea.octet)
+#define SCB_ISVALID(a, _pkttag_dbgid) ((a) && (a)->_dbgid == (_pkttag_dbgid))
+
+/* API for accessing SCB pointer in WLPKTTAG */
+#ifdef BCMDBG
+#define WLPKTTAGSCBSET(p, scb) { WLPKTTAG(p)->_scb = scb; WLPKTTAG(p)->_scb_dbgid = scb->_dbgid; }
+#define WLPKTTAGSCBCLR(p) { WLPKTTAG(p)->_scb = NULL; WLPKTTAG(p)->_scb_dbgid = 0; }
+#else
+#define WLPKTTAGSCBSET(p, scb) (WLPKTTAG(p)->_scb = scb)
+#define WLPKTTAGSCBCLR(p) (WLPKTTAG(p)->_scb = NULL)
+#endif
+
+#define WLCNTSCBINCR(a) /* No stats support */
+#define WLCNTSCBDECR(a) /* No stats support */
+#define WLCNTSCBADD(a, delta) /* No stats support */
+#define WLCNTSCBSET(a, value) /* No stats support */
+#define WLCNTSCBVAL(a) 0 /* No stats support */
+#define WLCNTSCB_COND_SET(c, a, v) /* No stats support */
+#define WLCNTSCB_COND_ADD(c, a, d) /* No stats support */
+#define WLCNTSCB_COND_INCR(c, a) /* No stats support */
+
+#endif /* _wlc_scb_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c
new file mode 100644
index 000000000000..5b3a8848c83f
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_stf.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <wlc_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <proto/802.11.h>
+#include <wlioctl.h>
+#include <bcmwpa.h>
+#include <bcmwifi.h>
+#include <d11.h>
+#include <wlc_rate.h>
+#include <wlc_pub.h>
+#include <wlc_key.h>
+#include <wlc_channel.h>
+#include <wlc_bsscfg.h>
+#include <wlc_mac80211.h>
+#include <wlc_scb.h>
+#include <wl_export.h>
+#include <wlc_bmac.h>
+#include <wlc_stf.h>
+
+#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \
+ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
+
+static int8 wlc_stf_stbc_rx_get(wlc_info_t *wlc);
+static bool wlc_stf_stbc_tx_set(wlc_info_t *wlc, int32 int_val);
+static int wlc_stf_txcore_set(wlc_info_t *wlc, uint8 Nsts, uint8 val);
+static int wlc_stf_spatial_policy_set(wlc_info_t *wlc, int val);
+static void wlc_stf_stbc_rx_ht_update(wlc_info_t *wlc, int val);
+
+static void _wlc_stf_phy_txant_upd(wlc_info_t *wlc);
+static uint16 _wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec);
+
+#define NSTS_1 1
+#define NSTS_2 2
+#define NSTS_3 3
+#define NSTS_4 4
+const uint8 txcore_default[5] = {
+ (0), /* bitmap of the core enabled */
+ (0x01), /* For Nsts = 1, enable core 1 */
+ (0x03), /* For Nsts = 2, enable core 1 & 2 */
+ (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
+ (0x0f) /* For Nsts = 4, enable all cores */
+};
+
+static void wlc_stf_stbc_rx_ht_update(wlc_info_t *wlc, int val)
+{
+ ASSERT((val == HT_CAP_RX_STBC_NO)
+ || (val == HT_CAP_RX_STBC_ONE_STREAM));
+
+ /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
+ if (WLC_STF_SS_STBC_RX(wlc)) {
+ if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
+ return;
+ }
+
+ wlc->ht_cap.cap &= ~HT_CAP_RX_STBC_MASK;
+ wlc->ht_cap.cap |= (val << HT_CAP_RX_STBC_SHIFT);
+
+ if (wlc->pub->up) {
+ wlc_update_beacon(wlc);
+ wlc_update_probe_resp(wlc, TRUE);
+ }
+}
+
+/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */
+void wlc_tempsense_upd(wlc_info_t *wlc)
+{
+ wlc_phy_t *pi = wlc->band->pi;
+ uint active_chains, txchain;
+
+ /* Check if the chip is too hot. Disable one Tx chain, if it is */
+ /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
+ active_chains = wlc_phy_stf_chain_active_get(pi);
+ txchain = active_chains & 0xf;
+
+ if (wlc->stf->txchain == wlc->stf->hw_txchain) {
+ if (txchain && (txchain < wlc->stf->hw_txchain)) {
+ /* turn off 1 tx chain */
+ wlc_stf_txchain_set(wlc, txchain, TRUE);
+ }
+ } else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
+ if (txchain == wlc->stf->hw_txchain) {
+ /* turn back on txchain */
+ wlc_stf_txchain_set(wlc, txchain, TRUE);
+ }
+ }
+}
+
+void
+wlc_stf_ss_algo_channel_get(wlc_info_t *wlc, uint16 *ss_algo_channel,
+ chanspec_t chanspec)
+{
+ tx_power_t power;
+ uint8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
+
+ /* Clear previous settings */
+ *ss_algo_channel = 0;
+
+ if (!wlc->pub->up) {
+ *ss_algo_channel = (uint16) -1;
+ return;
+ }
+
+ wlc_phy_txpower_get_current(wlc->band->pi, &power,
+ CHSPEC_CHANNEL(chanspec));
+
+ siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
+ WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
+ cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
+ WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
+ stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
+ WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
+
+ /* criteria to choose stf mode */
+
+ /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs
+ * on both chains
+ */
+ if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
+ setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
+ else
+ setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
+
+ /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check
+ * so cannot be default mode of operation. One of SISO, CDD have to be set
+ */
+ if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
+ setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
+}
+
+static int8 wlc_stf_stbc_rx_get(wlc_info_t *wlc)
+{
+ return (wlc->ht_cap.cap & HT_CAP_RX_STBC_MASK) >> HT_CAP_RX_STBC_SHIFT;
+}
+
+static bool wlc_stf_stbc_tx_set(wlc_info_t *wlc, int32 int_val)
+{
+ if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) {
+ return FALSE;
+ }
+
+ if ((int_val == ON) && (wlc->stf->txstreams == 1))
+ return FALSE;
+
+ if ((int_val == OFF) || (wlc->stf->txstreams == 1)
+ || !WLC_STBC_CAP_PHY(wlc))
+ wlc->ht_cap.cap &= ~HT_CAP_TX_STBC;
+ else
+ wlc->ht_cap.cap |= HT_CAP_TX_STBC;
+
+ wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (int8) int_val;
+ wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (int8) int_val;
+
+ return TRUE;
+}
+
+bool wlc_stf_stbc_rx_set(wlc_info_t *wlc, int32 int_val)
+{
+ if ((int_val != HT_CAP_RX_STBC_NO)
+ && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) {
+ return FALSE;
+ }
+
+ if (WLC_STF_SS_STBC_RX(wlc)) {
+ if ((int_val != HT_CAP_RX_STBC_NO)
+ && (wlc->stf->rxstreams == 1))
+ return FALSE;
+ }
+
+ wlc_stf_stbc_rx_ht_update(wlc, int_val);
+ return TRUE;
+}
+
+static int wlc_stf_txcore_set(wlc_info_t *wlc, uint8 Nsts, uint8 core_mask)
+{
+ WL_TRACE(("wl%d: %s: Nsts %d core_mask %x\n",
+ wlc->pub->unit, __func__, Nsts, core_mask));
+
+ ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED));
+
+ if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) {
+ core_mask = 0;
+ }
+
+ if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) &&
+ ((core_mask & ~wlc->stf->txchain)
+ || !(core_mask & wlc->stf->txchain))) {
+ core_mask = wlc->stf->txchain;
+ }
+
+ ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask));
+
+ wlc->stf->txcore[Nsts] = core_mask;
+ /* Nsts = 1..4, txcore index = 1..4 */
+ if (Nsts == 1) {
+ /* Needs to update beacon and ucode generated response
+ * frames when 1 stream core map changed
+ */
+ wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
+ wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+ if (wlc->clk) {
+ wlc_suspend_mac_and_wait(wlc);
+ wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+ wlc_enable_mac(wlc);
+ }
+ }
+
+ return BCME_OK;
+}
+
+static int wlc_stf_spatial_policy_set(wlc_info_t *wlc, int val)
+{
+ int i;
+ uint8 core_mask = 0;
+
+ WL_TRACE(("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val));
+
+ wlc->stf->spatial_policy = (int8) val;
+ for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
+ core_mask = (val == MAX_SPATIAL_EXPANSION) ?
+ wlc->stf->txchain : txcore_default[i];
+ wlc_stf_txcore_set(wlc, (uint8) i, core_mask);
+ }
+ return BCME_OK;
+}
+
+int wlc_stf_txchain_set(wlc_info_t *wlc, int32 int_val, bool force)
+{
+ uint8 txchain = (uint8) int_val;
+ uint8 txstreams;
+ uint i;
+
+ if (wlc->stf->txchain == txchain)
+ return BCME_OK;
+
+ if ((txchain & ~wlc->stf->hw_txchain)
+ || !(txchain & wlc->stf->hw_txchain))
+ return BCME_RANGE;
+
+ /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
+ txstreams = (uint8) WLC_BITSCNT(txchain);
+ if (txstreams > MAX_STREAMS_SUPPORTED)
+ return BCME_RANGE;
+
+ if (txstreams == 1) {
+ for (i = 0; i < NBANDS(wlc); i++)
+ if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
+ PHY_TXC1_MODE_SISO)
+ || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
+ PHY_TXC1_MODE_SISO)) {
+ if (!force)
+ return BCME_ERROR;
+
+ /* over-write the override rspec */
+ if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
+ != PHY_TXC1_MODE_SISO) {
+ wlc->bandstate[i]->rspec_override = 0;
+ WL_ERROR(("%s(): temp sense override non-SISO" " rspec_override.\n", __func__));
+ }
+ if (RSPEC_STF
+ (wlc->bandstate[i]->mrspec_override) !=
+ PHY_TXC1_MODE_SISO) {
+ wlc->bandstate[i]->mrspec_override = 0;
+ WL_ERROR(("%s(): temp sense override non-SISO" " mrspec_override.\n", __func__));
+ }
+ }
+ }
+
+ wlc->stf->txchain = txchain;
+ wlc->stf->txstreams = txstreams;
+ wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+ wlc->stf->txant =
+ (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
+ _wlc_stf_phy_txant_upd(wlc);
+
+ wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+ wlc->stf->rxchain);
+
+ for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
+ wlc_stf_txcore_set(wlc, (uint8) i, txcore_default[i]);
+
+ return BCME_OK;
+}
+
+int wlc_stf_rxchain_set(wlc_info_t *wlc, int32 int_val)
+{
+ uint8 rxchain_cnt;
+ uint8 rxchain = (uint8) int_val;
+ uint8 mimops_mode;
+ uint8 old_rxchain, old_rxchain_cnt;
+
+ if (wlc->stf->rxchain == rxchain)
+ return BCME_OK;
+
+ if ((rxchain & ~wlc->stf->hw_rxchain)
+ || !(rxchain & wlc->stf->hw_rxchain))
+ return BCME_RANGE;
+
+ rxchain_cnt = (uint8) WLC_BITSCNT(rxchain);
+ if (WLC_STF_SS_STBC_RX(wlc)) {
+ if ((rxchain_cnt == 1)
+ && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO))
+ return BCME_RANGE;
+ }
+
+ if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated))
+ return BCME_ASSOCIATED;
+
+ old_rxchain = wlc->stf->rxchain;
+ old_rxchain_cnt = wlc->stf->rxstreams;
+
+ wlc->stf->rxchain = rxchain;
+ wlc->stf->rxstreams = rxchain_cnt;
+
+ if (rxchain_cnt != old_rxchain_cnt) {
+ mimops_mode =
+ (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF;
+ wlc->mimops_PM = mimops_mode;
+ if (AP_ENAB(wlc->pub)) {
+ wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+ wlc->stf->rxchain);
+ wlc_ht_mimops_cap_update(wlc, mimops_mode);
+ if (wlc->pub->associated)
+ wlc_mimops_action_ht_send(wlc, wlc->cfg,
+ mimops_mode);
+ return BCME_OK;
+ }
+ if (wlc->pub->associated) {
+ if (mimops_mode == HT_CAP_MIMO_PS_OFF) {
+ /* if mimops is off, turn on the Rx chain first */
+ wlc_phy_stf_chain_set(wlc->band->pi,
+ wlc->stf->txchain,
+ wlc->stf->rxchain);
+ wlc_ht_mimops_cap_update(wlc, mimops_mode);
+ }
+ } else {
+ wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+ wlc->stf->rxchain);
+ wlc_ht_mimops_cap_update(wlc, mimops_mode);
+ }
+ } else if (old_rxchain != rxchain)
+ wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+ wlc->stf->rxchain);
+
+ return BCME_OK;
+}
+
+/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
+int wlc_stf_ss_update(wlc_info_t *wlc, wlcband_t *band)
+{
+ int ret_code = 0;
+ uint8 prev_stf_ss;
+ uint8 upd_stf_ss;
+
+ prev_stf_ss = wlc->stf->ss_opmode;
+
+ /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */
+ if (WLC_STBC_CAP_PHY(wlc) &&
+ wlc->stf->ss_algosel_auto
+ && (wlc->stf->ss_algo_channel != (uint16) -1)) {
+ ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD)
+ || isset(&wlc->stf->ss_algo_channel,
+ PHY_TXC1_MODE_SISO));
+ upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
+ || isset(&wlc->stf->ss_algo_channel,
+ PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
+ : PHY_TXC1_MODE_CDD;
+ } else {
+ if (wlc->band != band)
+ return ret_code;
+ upd_stf_ss = (wlc->stf->no_cddstbc
+ || (wlc->stf->txstreams ==
+ 1)) ? PHY_TXC1_MODE_SISO : band->
+ band_stf_ss_mode;
+ }
+ if (prev_stf_ss != upd_stf_ss) {
+ wlc->stf->ss_opmode = upd_stf_ss;
+ wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss);
+ }
+
+ return ret_code;
+}
+
+int BCMATTACHFN(wlc_stf_attach) (wlc_info_t *wlc)
+{
+ wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
+ wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
+
+ if (WLCISNPHY(wlc->band) &&
+ (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
+ wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
+ PHY_TXC1_MODE_CDD;
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+ wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+
+ wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
+ wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+ wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+
+ if (WLC_STBC_CAP_PHY(wlc)) {
+ wlc->stf->ss_algosel_auto = TRUE;
+ wlc->stf->ss_algo_channel = (uint16) -1; /* Init the default value */
+ }
+ return 0;
+}
+
+void BCMATTACHFN(wlc_stf_detach) (wlc_info_t *wlc)
+{
+}
+
+int wlc_stf_ant_txant_validate(wlc_info_t *wlc, int8 val)
+{
+ int bcmerror = BCME_OK;
+
+ /* when there is only 1 tx_streams, don't allow to change the txant */
+ if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+ return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE);
+
+ switch (val) {
+ case -1:
+ val = ANT_TX_DEF;
+ break;
+ case 0:
+ val = ANT_TX_FORCE_0;
+ break;
+ case 1:
+ val = ANT_TX_FORCE_1;
+ break;
+ case 3:
+ val = ANT_TX_LAST_RX;
+ break;
+ default:
+ bcmerror = BCME_RANGE;
+ break;
+ }
+
+ if (bcmerror == BCME_OK)
+ wlc->stf->txant = (int8) val;
+
+ return bcmerror;
+
+}
+
+/*
+ * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain
+ * change
+ *
+ * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
+ * achieve various tx/rx antenna selection schemes
+ *
+ * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx)
+ * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+ * do tx-antenna selection for SISO transmissions
+ * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+ * do tx-antenna selection for SISO transmissions
+ * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active
+*/
+static void _wlc_stf_phy_txant_upd(wlc_info_t *wlc)
+{
+ int8 txant;
+
+ txant = (int8) wlc->stf->txant;
+ ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1
+ || txant == ANT_TX_LAST_RX);
+
+ if (WLC_PHY_11N_CAP(wlc->band)) {
+ if (txant == ANT_TX_FORCE_0) {
+ wlc->stf->phytxant = PHY_TXC_ANT_0;
+ } else if (txant == ANT_TX_FORCE_1) {
+ wlc->stf->phytxant = PHY_TXC_ANT_1;
+
+ if (WLCISNPHY(wlc->band) &&
+ NREV_GE(wlc->band->phyrev, 3)
+ && NREV_LT(wlc->band->phyrev, 7)) {
+ wlc->stf->phytxant = PHY_TXC_ANT_2;
+ }
+ } else {
+ if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band))
+ wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
+ else {
+ /* keep this assert to catch out of sync wlc->stf->txcore */
+ ASSERT(wlc->stf->txchain > 0);
+ wlc->stf->phytxant =
+ wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+ }
+ }
+ } else {
+ if (txant == ANT_TX_FORCE_0)
+ wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
+ else if (txant == ANT_TX_FORCE_1)
+ wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
+ else
+ wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
+ }
+
+ wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+}
+
+void wlc_stf_phy_txant_upd(wlc_info_t *wlc)
+{
+ _wlc_stf_phy_txant_upd(wlc);
+}
+
+void BCMATTACHFN(wlc_stf_phy_chain_calc) (wlc_info_t *wlc)
+{
+ /* get available rx/tx chains */
+ wlc->stf->hw_txchain = (uint8) getintvar(wlc->pub->vars, "txchain");
+ wlc->stf->hw_rxchain = (uint8) getintvar(wlc->pub->vars, "rxchain");
+
+ /* these parameter are intended to be used for all PHY types */
+ if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
+ if (WLCISNPHY(wlc->band)) {
+ wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
+ } else {
+ wlc->stf->hw_txchain = TXCHAIN_DEF;
+ }
+ }
+
+ wlc->stf->txchain = wlc->stf->hw_txchain;
+ wlc->stf->txstreams = (uint8) WLC_BITSCNT(wlc->stf->hw_txchain);
+
+ if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
+ if (WLCISNPHY(wlc->band)) {
+ wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
+ } else {
+ wlc->stf->hw_rxchain = RXCHAIN_DEF;
+ }
+ }
+
+ wlc->stf->rxchain = wlc->stf->hw_rxchain;
+ wlc->stf->rxstreams = (uint8) WLC_BITSCNT(wlc->stf->hw_rxchain);
+
+ /* initialize the txcore table */
+ bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore));
+
+ /* default spatial_policy */
+ wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
+ wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
+}
+
+static uint16 _wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec)
+{
+ uint16 phytxant = wlc->stf->phytxant;
+
+ if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
+ ASSERT(wlc->stf->txstreams > 1);
+ phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+ } else if (wlc->stf->txant == ANT_TX_DEF)
+ phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+ phytxant &= PHY_TXC_ANT_MASK;
+ return phytxant;
+}
+
+uint16 wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec)
+{
+ return _wlc_stf_phytxchain_sel(wlc, rspec);
+}
+
+uint16 wlc_stf_d11hdrs_phyctl_txant(wlc_info_t *wlc, ratespec_t rspec)
+{
+ uint16 phytxant = wlc->stf->phytxant;
+ uint16 mask = PHY_TXC_ANT_MASK;
+
+ /* for non-siso rates or default setting, use the available chains */
+ if (WLCISNPHY(wlc->band)) {
+ ASSERT(wlc->stf->txchain != 0);
+ phytxant = _wlc_stf_phytxchain_sel(wlc, rspec);
+ mask = PHY_TXC_HTANT_MASK;
+ }
+ phytxant |= phytxant & mask;
+ return phytxant;
+}
diff --git a/drivers/staging/brcm80211/sys/wlc_stf.h b/drivers/staging/brcm80211/sys/wlc_stf.h
new file mode 100644
index 000000000000..81568a926831
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_stf.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_stf_h_
+#define _wlc_stf_h_
+
+#define MIN_SPATIAL_EXPANSION 0
+#define MAX_SPATIAL_EXPANSION 1
+
+extern int wlc_stf_attach(wlc_info_t *wlc);
+extern void wlc_stf_detach(wlc_info_t *wlc);
+
+extern void wlc_tempsense_upd(wlc_info_t *wlc);
+extern void wlc_stf_ss_algo_channel_get(wlc_info_t *wlc,
+ uint16 *ss_algo_channel,
+ chanspec_t chanspec);
+extern int wlc_stf_ss_update(wlc_info_t *wlc, struct wlcband *band);
+extern void wlc_stf_phy_txant_upd(wlc_info_t *wlc);
+extern int wlc_stf_txchain_set(wlc_info_t *wlc, int32 int_val, bool force);
+extern int wlc_stf_rxchain_set(wlc_info_t *wlc, int32 int_val);
+extern bool wlc_stf_stbc_rx_set(wlc_info_t *wlc, int32 int_val);
+
+extern int wlc_stf_ant_txant_validate(wlc_info_t *wlc, int8 val);
+extern void wlc_stf_phy_txant_upd(wlc_info_t *wlc);
+extern void wlc_stf_phy_chain_calc(wlc_info_t *wlc);
+extern uint16 wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec);
+extern uint16 wlc_stf_d11hdrs_phyctl_txant(wlc_info_t *wlc, ratespec_t rspec);
+extern uint16 wlc_stf_spatial_expansion_get(wlc_info_t *wlc, ratespec_t rspec);
+#endif /* _wlc_stf_h_ */
diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h
new file mode 100644
index 000000000000..33047ebab979
--- /dev/null
+++ b/drivers/staging/brcm80211/sys/wlc_types.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _wlc_types_h_
+#define _wlc_types_h_
+
+/* forward declarations */
+
+typedef struct wlc_info wlc_info_t;
+typedef struct wlc_hw_info wlc_hw_info_t;
+typedef struct wlc_if wlc_if_t;
+typedef struct wl_if wl_if_t;
+typedef struct led_info led_info_t;
+typedef struct bmac_led bmac_led_t;
+typedef struct bmac_led_info bmac_led_info_t;
+typedef struct scb_module scb_module_t;
+typedef struct ba_info ba_info_t;
+typedef struct ampdu_info ampdu_info_t;
+typedef struct ratesel_info ratesel_info_t;
+typedef struct wlc_ap_info wlc_ap_info_t;
+typedef struct wlc_auth_info wlc_auth_info_t;
+typedef struct supplicant supplicant_t;
+typedef struct authenticator authenticator_t;
+typedef struct antsel_info antsel_info_t;
+#if !defined(WLC_LOW)
+typedef struct rpctx_info rpctx_info_t;
+#endif
+#ifdef WLC_LOW
+typedef struct bmac_pmq bmac_pmq_t;
+#endif
+
+struct d11init;
+
+#ifndef _hnddma_pub_
+#define _hnddma_pub_
+typedef const struct hnddma_pub hnddma_t;
+#endif /* _hnddma_pub_ */
+
+#endif /* _wlc_types_h_ */
diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c
new file mode 100644
index 000000000000..6ac49eccf0bf
--- /dev/null
+++ b/drivers/staging/brcm80211/util/aiutils.c
@@ -0,0 +1,796 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <bcmdevs.h>
+
+#define BCM47162_DMP() ((CHIPID(sih->chip) == BCM47162_CHIP_ID) && \
+ (CHIPREV(sih->chiprev) == 0) && \
+ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
+
+/* EROM parsing */
+
+static uint32
+get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match)
+{
+ uint32 ent;
+ uint inv = 0, nom = 0;
+
+ while (TRUE) {
+ ent = R_REG(si_osh(sih), *eromptr);
+ (*eromptr)++;
+
+ if (mask == 0)
+ break;
+
+ if ((ent & ER_VALID) == 0) {
+ inv++;
+ continue;
+ }
+
+ if (ent == (ER_END | ER_VALID))
+ break;
+
+ if ((ent & mask) == match)
+ break;
+
+ nom++;
+ }
+
+ SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
+ if (inv + nom) {
+ SI_VMSG((" after %d invalid and %d non-matching entries\n",
+ inv, nom));
+ }
+ return ent;
+}
+
+static uint32
+get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st,
+ uint32 *addrl, uint32 *addrh, uint32 *sizel, uint32 *sizeh)
+{
+ uint32 asd, sz, szd;
+
+ asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+ if (((asd & ER_TAG1) != ER_ADD) ||
+ (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+ ((asd & AD_ST_MASK) != st)) {
+ /* This is not what we want, "push" it back */
+ (*eromptr)--;
+ return 0;
+ }
+ *addrl = asd & AD_ADDR_MASK;
+ if (asd & AD_AG32)
+ *addrh = get_erom_ent(sih, eromptr, 0, 0);
+ else
+ *addrh = 0;
+ *sizeh = 0;
+ sz = asd & AD_SZ_MASK;
+ if (sz == AD_SZ_SZD) {
+ szd = get_erom_ent(sih, eromptr, 0, 0);
+ *sizel = szd & SD_SZ_MASK;
+ if (szd & SD_SG32)
+ *sizeh = get_erom_ent(sih, eromptr, 0, 0);
+ } else
+ *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+
+ SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+ sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
+
+ return asd;
+}
+
+static void ai_hwfixup(si_info_t *sii)
+{
+}
+
+/* parse the enumeration rom to identify all cores */
+void BCMATTACHFN(ai_scan) (si_t *sih, void *regs, uint devid)
+{
+ si_info_t *sii = SI_INFO(sih);
+ chipcregs_t *cc = (chipcregs_t *) regs;
+ uint32 erombase, *eromptr, *eromlim;
+
+ erombase = R_REG(sii->osh, &cc->eromptr);
+
+ switch (BUSTYPE(sih->bustype)) {
+ case SI_BUS:
+ eromptr = (uint32 *) REG_MAP(erombase, SI_CORE_SIZE);
+ break;
+
+ case PCI_BUS:
+ /* Set wrappers address */
+ sii->curwrap = (void *)((uintptr) regs + SI_CORE_SIZE);
+
+ /* Now point the window at the erom */
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase);
+ eromptr = regs;
+ break;
+
+#ifdef BCMSDIO
+ case SPI_BUS:
+ case SDIO_BUS:
+#endif /* BCMSDIO */
+ eromptr = (uint32 *) (uintptr) erombase;
+ break;
+
+ default:
+ SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
+ sih->bustype));
+ ASSERT(0);
+ return;
+ }
+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
+
+ SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
+ while (eromptr < eromlim) {
+ uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+ uint32 mpd, asd, addrl, addrh, sizel, sizeh;
+ uint32 *base;
+ uint i, j, idx;
+ bool br;
+
+ br = FALSE;
+
+ /* Grok a component */
+ cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+ if (cia == (ER_END | ER_VALID)) {
+ SI_VMSG(("Found END of erom after %d cores\n",
+ sii->numcores));
+ ai_hwfixup(sii);
+ return;
+ }
+ base = eromptr - 1;
+ cib = get_erom_ent(sih, &eromptr, 0, 0);
+
+ if ((cib & ER_TAG) != ER_CI) {
+ SI_ERROR(("CIA not followed by CIB\n"));
+ goto error;
+ }
+
+ cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+ mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+ crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+ nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+ nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+ SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
+
+ if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
+ continue;
+ if ((nmw + nsw == 0)) {
+ /* A component which is not a core */
+ if (cid == OOB_ROUTER_CORE_ID) {
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+ &addrl, &addrh, &sizel, &sizeh);
+ if (asd != 0) {
+ sii->oob_router = addrl;
+ }
+ }
+ continue;
+ }
+
+ idx = sii->numcores;
+/* sii->eromptr[idx] = base; */
+ sii->cia[idx] = cia;
+ sii->cib[idx] = cib;
+ sii->coreid[idx] = cid;
+
+ for (i = 0; i < nmp; i++) {
+ mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+ if ((mpd & ER_TAG) != ER_MP) {
+ SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
+ goto error;
+ }
+ SI_VMSG((" Master port %d, mp: %d id: %d\n", i,
+ (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+ (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
+ }
+
+ /* First Slave Address Descriptor should be port 0:
+ * the main register space for the core
+ */
+ asd =
+ get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
+ &sizel, &sizeh);
+ if (asd == 0) {
+ /* Try again to see if it is a bridge */
+ asd =
+ get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
+ &addrh, &sizel, &sizeh);
+ if (asd != 0)
+ br = TRUE;
+ else if ((addrh != 0) || (sizeh != 0)
+ || (sizel != SI_CORE_SIZE)) {
+ SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
+ goto error;
+ }
+ }
+ sii->coresba[idx] = addrl;
+ sii->coresba_size[idx] = sizel;
+ /* Get any more ASDs in port 0 */
+ j = 1;
+ do {
+ asd =
+ get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
+ &addrh, &sizel, &sizeh);
+ if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
+ sii->coresba2[idx] = addrl;
+ sii->coresba2_size[idx] = sizel;
+ }
+ j++;
+ } while (asd != 0);
+
+ /* Go through the ASDs for other slave ports */
+ for (i = 1; i < nsp; i++) {
+ j = 0;
+ do {
+ asd =
+ get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
+ &addrl, &addrh, &sizel, &sizeh);
+ } while (asd != 0);
+ if (j == 0) {
+ SI_ERROR((" SP %d has no address descriptors\n",
+ i));
+ goto error;
+ }
+ }
+
+ /* Now get master wrappers */
+ for (i = 0; i < nmw; i++) {
+ asd =
+ get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
+ &addrh, &sizel, &sizeh);
+ if (asd == 0) {
+ SI_ERROR(("Missing descriptor for MW %d\n", i));
+ goto error;
+ }
+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+ SI_ERROR(("Master wrapper %d is not 4KB\n", i));
+ goto error;
+ }
+ if (i == 0)
+ sii->wrapba[idx] = addrl;
+ }
+
+ /* And finally slave wrappers */
+ for (i = 0; i < nsw; i++) {
+ uint fwp = (nsp == 1) ? 0 : 1;
+ asd =
+ get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
+ &addrl, &addrh, &sizel, &sizeh);
+ if (asd == 0) {
+ SI_ERROR(("Missing descriptor for SW %d\n", i));
+ goto error;
+ }
+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+ SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
+ goto error;
+ }
+ if ((nmw == 0) && (i == 0))
+ sii->wrapba[idx] = addrl;
+ }
+
+ /* Don't record bridges */
+ if (br)
+ continue;
+
+ /* Done with core */
+ sii->numcores++;
+ }
+
+ SI_ERROR(("Reached end of erom without finding END"));
+
+ error:
+ sii->numcores = 0;
+ return;
+}
+
+/* This function changes the logical "focus" to the indicated core.
+ * Return the current core's virtual address.
+ */
+void *ai_setcoreidx(si_t *sih, uint coreidx)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint32 addr = sii->coresba[coreidx];
+ uint32 wrap = sii->wrapba[coreidx];
+ void *regs;
+
+ if (coreidx >= sii->numcores)
+ return NULL;
+
+ /*
+ * If the user has provided an interrupt mask enabled function,
+ * then assert interrupts are disabled before switching the core.
+ */
+ ASSERT((sii->intrsenabled_fn == NULL)
+ || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg));
+
+ switch (BUSTYPE(sih->bustype)) {
+ case SI_BUS:
+ /* map new one */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ sii->curmap = regs = sii->regs[coreidx];
+ if (!sii->wrappers[coreidx]) {
+ sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->wrappers[coreidx]));
+ }
+ sii->curwrap = sii->wrappers[coreidx];
+ break;
+
+ case PCI_BUS:
+ /* point bar0 window */
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr);
+ regs = sii->curmap;
+ /* point bar0 2nd 4KB window */
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN2, 4, wrap);
+ break;
+
+#ifdef BCMSDIO
+ case SPI_BUS:
+ case SDIO_BUS:
+#endif /* BCMSDIO */
+ sii->curmap = regs = (void *)((uintptr) addr);
+ sii->curwrap = (void *)((uintptr) wrap);
+ break;
+
+ default:
+ ASSERT(0);
+ regs = NULL;
+ break;
+ }
+
+ sii->curmap = regs;
+ sii->curidx = coreidx;
+
+ return regs;
+}
+
+/* Return the number of address spaces in current core */
+int ai_numaddrspaces(si_t *sih)
+{
+ return 2;
+}
+
+/* Return the address of the nth address space in the current core */
+uint32 ai_addrspace(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+ uint cidx;
+
+ sii = SI_INFO(sih);
+ cidx = sii->curidx;
+
+ if (asidx == 0)
+ return sii->coresba[cidx];
+ else if (asidx == 1)
+ return sii->coresba2[cidx];
+ else {
+ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+ return 0;
+ }
+}
+
+/* Return the size of the nth address space in the current core */
+uint32 ai_addrspacesize(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+ uint cidx;
+
+ sii = SI_INFO(sih);
+ cidx = sii->curidx;
+
+ if (asidx == 0)
+ return sii->coresba_size[cidx];
+ else if (asidx == 1)
+ return sii->coresba2_size[cidx];
+ else {
+ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+ return 0;
+ }
+}
+
+uint ai_flag(si_t *sih)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
+ return sii->curidx;
+ }
+ ai = sii->curwrap;
+
+ return R_REG(sii->osh, &ai->oobselouta30) & 0x1f;
+}
+
+void ai_setint(si_t *sih, int siflag)
+{
+}
+
+void ai_write_wrap_reg(si_t *sih, uint32 offset, uint32 val)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint32 *w = (uint32 *) sii->curwrap;
+ W_REG(sii->osh, w + (offset / 4), val);
+ return;
+}
+
+uint ai_corevendor(si_t *sih)
+{
+ si_info_t *sii;
+ uint32 cia;
+
+ sii = SI_INFO(sih);
+ cia = sii->cia[sii->curidx];
+ return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+}
+
+uint ai_corerev(si_t *sih)
+{
+ si_info_t *sii;
+ uint32 cib;
+
+ sii = SI_INFO(sih);
+ cib = sii->cib[sii->curidx];
+ return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+}
+
+bool ai_iscoreup(si_t *sih)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+ ai = sii->curwrap;
+
+ return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
+ SICF_CLOCK_EN)
+ && ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0));
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
+ * switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
+ * and (on newer pci cores) chipcommon registers.
+ */
+uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+ uint origidx = 0;
+ uint32 *r = NULL;
+ uint w;
+ uint intr_val = 0;
+ bool fast = FALSE;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODIDX(coreidx));
+ ASSERT(regoff < SI_CORE_SIZE);
+ ASSERT((val & ~mask) == 0);
+
+ if (coreidx >= SI_MAXCORES)
+ return 0;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ /* If internal bus, we can always get at everything */
+ fast = TRUE;
+ /* map if does not exist */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+ SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ r = (uint32 *) ((uchar *) sii->regs[coreidx] + regoff);
+ } else if (BUSTYPE(sih->bustype) == PCI_BUS) {
+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+ /* Chipc registers are mapped at 12KB */
+
+ fast = TRUE;
+ r = (uint32 *) ((char *)sii->curmap +
+ PCI_16KB0_CCREGS_OFFSET + regoff);
+ } else if (sii->pub.buscoreidx == coreidx) {
+ /* pci registers are at either in the last 2KB of an 8KB window
+ * or, in pcie and pci rev 13 at 8KB
+ */
+ fast = TRUE;
+ if (SI_FAST(sii))
+ r = (uint32 *) ((char *)sii->curmap +
+ PCI_16KB0_PCIREGS_OFFSET +
+ regoff);
+ else
+ r = (uint32 *) ((char *)sii->curmap +
+ ((regoff >= SBCONFIGOFF) ?
+ PCI_BAR0_PCISBR_OFFSET :
+ PCI_BAR0_PCIREGS_OFFSET) +
+ regoff);
+ }
+ }
+
+ if (!fast) {
+ INTR_OFF(sii, intr_val);
+
+ /* save current core index */
+ origidx = si_coreidx(&sii->pub);
+
+ /* switch core */
+ r = (uint32 *) ((uchar *) ai_setcoreidx(&sii->pub, coreidx) +
+ regoff);
+ }
+ ASSERT(r != NULL);
+
+ /* mask and set */
+ if (mask || val) {
+ w = (R_REG(sii->osh, r) & ~mask) | val;
+ W_REG(sii->osh, r, w);
+ }
+
+ /* readback */
+ w = R_REG(sii->osh, r);
+
+ if (!fast) {
+ /* restore core index */
+ if (origidx != coreidx)
+ ai_setcoreidx(&sii->pub, origidx);
+
+ INTR_RESTORE(sii, intr_val);
+ }
+
+ return w;
+}
+
+void ai_core_disable(si_t *sih, uint32 bits)
+{
+ si_info_t *sii;
+ volatile uint32 dummy;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ /* if core is already in reset, just return */
+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET)
+ return;
+
+ W_REG(sii->osh, &ai->ioctrl, bits);
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ OSL_DELAY(10);
+
+ W_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
+ OSL_DELAY(1);
+}
+
+/* reset and re-enable a core
+ * inputs:
+ * bits - core specific bits that are set during and after reset sequence
+ * resetbits - core specific bits that are set only during reset sequence
+ */
+void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ volatile uint32 dummy;
+
+ sii = SI_INFO(sih);
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ /*
+ * Must do the disable sequence first to work for arbitrary current core state.
+ */
+ ai_core_disable(sih, (bits | resetbits));
+
+ /*
+ * Now do the initialization sequence.
+ */
+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ W_REG(sii->osh, &ai->resetctrl, 0);
+ OSL_DELAY(1);
+
+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN));
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ OSL_DELAY(1);
+}
+
+void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+
+ if (BCM47162_DMP()) {
+ SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+ __func__));
+ return;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+ W_REG(sii->osh, &ai->ioctrl, w);
+ }
+}
+
+uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+ __func__));
+ return 0;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+ W_REG(sii->osh, &ai->ioctrl, w);
+ }
+
+ return R_REG(sii->osh, &ai->ioctrl);
+}
+
+uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
+ return 0;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+ ASSERT((mask & ~SISF_CORE_BITS) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val);
+ W_REG(sii->osh, &ai->iostatus, w);
+ }
+
+ return R_REG(sii->osh, &ai->iostatus);
+}
+
+#ifdef BCMDBG
+void ai_view(si_t *sih, bool verbose)
+{
+ si_info_t *sii;
+ osl_t *osh;
+ aidmp_t *ai;
+ uint32 config;
+
+ sii = SI_INFO(sih);
+ ai = sii->curwrap;
+ osh = sii->osh;
+ if (BCM47162_DMP()) {
+ SI_ERROR(("Cannot access mips74k DMP in 47162a0\n"));
+ return;
+ }
+
+ config = R_REG(osh, &ai->config);
+ SI_ERROR(("\nCore ID: 0x%x, config 0x%x\n", si_coreid(&sii->pub),
+ config));
+
+ if (config & AICFG_RST)
+ SI_ERROR(("resetctrl 0x%x, resetstatus 0x%x, resetreadid 0x%x, resetwriteid 0x%x\n", R_REG(osh, &ai->resetctrl), R_REG(osh, &ai->resetstatus), R_REG(osh, &ai->resetreadid), R_REG(osh, &ai->resetwriteid)));
+
+ if (config & AICFG_IOC)
+ SI_ERROR(("ioctrl 0x%x, width %d\n", R_REG(osh, &ai->ioctrl),
+ R_REG(osh, &ai->ioctrlwidth)));
+
+ if (config & AICFG_IOS)
+ SI_ERROR(("iostatus 0x%x, width %d\n",
+ R_REG(osh, &ai->iostatus), R_REG(osh,
+ &ai->
+ iostatuswidth)));
+
+ if (config & AICFG_ERRL) {
+ SI_ERROR(("errlogctrl 0x%x, errlogdone 0x%x, errlogstatus 0x%x, intstatus 0x%x\n", R_REG(osh, &ai->errlogctrl), R_REG(osh, &ai->errlogdone), R_REG(osh, &ai->errlogstatus), R_REG(osh, &ai->intstatus)));
+ SI_ERROR(("errlogid 0x%x, errloguser 0x%x, errlogflags 0x%x, errlogaddr " "0x%x/0x%x\n", R_REG(osh, &ai->errlogid), R_REG(osh, &ai->errloguser), R_REG(osh, &ai->errlogflags), R_REG(osh, &ai->errlogaddrhi), R_REG(osh, &ai->errlogaddrlo)));
+ }
+
+ if (verbose && (config & AICFG_OOB)) {
+ SI_ERROR(("oobselina30 0x%x, oobselina74 0x%x\n",
+ R_REG(osh, &ai->oobselina30), R_REG(osh,
+ &ai->
+ oobselina74)));
+ SI_ERROR(("oobselinb30 0x%x, oobselinb74 0x%x\n",
+ R_REG(osh, &ai->oobselinb30), R_REG(osh,
+ &ai->
+ oobselinb74)));
+ SI_ERROR(("oobselinc30 0x%x, oobselinc74 0x%x\n",
+ R_REG(osh, &ai->oobselinc30), R_REG(osh,
+ &ai->
+ oobselinc74)));
+ SI_ERROR(("oobselind30 0x%x, oobselind74 0x%x\n",
+ R_REG(osh, &ai->oobselind30), R_REG(osh,
+ &ai->
+ oobselind74)));
+ SI_ERROR(("oobselouta30 0x%x, oobselouta74 0x%x\n",
+ R_REG(osh, &ai->oobselouta30), R_REG(osh,
+ &ai->
+ oobselouta74)));
+ SI_ERROR(("oobseloutb30 0x%x, oobseloutb74 0x%x\n",
+ R_REG(osh, &ai->oobseloutb30), R_REG(osh,
+ &ai->
+ oobseloutb74)));
+ SI_ERROR(("oobseloutc30 0x%x, oobseloutc74 0x%x\n",
+ R_REG(osh, &ai->oobseloutc30), R_REG(osh,
+ &ai->
+ oobseloutc74)));
+ SI_ERROR(("oobseloutd30 0x%x, oobseloutd74 0x%x\n",
+ R_REG(osh, &ai->oobseloutd30), R_REG(osh,
+ &ai->
+ oobseloutd74)));
+ SI_ERROR(("oobsynca 0x%x, oobseloutaen 0x%x\n",
+ R_REG(osh, &ai->oobsynca), R_REG(osh,
+ &ai->oobseloutaen)));
+ SI_ERROR(("oobsyncb 0x%x, oobseloutben 0x%x\n",
+ R_REG(osh, &ai->oobsyncb), R_REG(osh,
+ &ai->oobseloutben)));
+ SI_ERROR(("oobsyncc 0x%x, oobseloutcen 0x%x\n",
+ R_REG(osh, &ai->oobsyncc), R_REG(osh,
+ &ai->oobseloutcen)));
+ SI_ERROR(("oobsyncd 0x%x, oobseloutden 0x%x\n",
+ R_REG(osh, &ai->oobsyncd), R_REG(osh,
+ &ai->oobseloutden)));
+ SI_ERROR(("oobaextwidth 0x%x, oobainwidth 0x%x, oobaoutwidth 0x%x\n", R_REG(osh, &ai->oobaextwidth), R_REG(osh, &ai->oobainwidth), R_REG(osh, &ai->oobaoutwidth)));
+ SI_ERROR(("oobbextwidth 0x%x, oobbinwidth 0x%x, oobboutwidth 0x%x\n", R_REG(osh, &ai->oobbextwidth), R_REG(osh, &ai->oobbinwidth), R_REG(osh, &ai->oobboutwidth)));
+ SI_ERROR(("oobcextwidth 0x%x, oobcinwidth 0x%x, oobcoutwidth 0x%x\n", R_REG(osh, &ai->oobcextwidth), R_REG(osh, &ai->oobcinwidth), R_REG(osh, &ai->oobcoutwidth)));
+ SI_ERROR(("oobdextwidth 0x%x, oobdinwidth 0x%x, oobdoutwidth 0x%x\n", R_REG(osh, &ai->oobdextwidth), R_REG(osh, &ai->oobdinwidth), R_REG(osh, &ai->oobdoutwidth)));
+ }
+}
+#endif /* BCMDBG */
diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c
new file mode 100644
index 000000000000..a63214fb7954
--- /dev/null
+++ b/drivers/staging/brcm80211/util/bcmotp.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmdevs.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <bcmotp.h>
+#include "siutils_priv.h"
+
+/*
+ * There are two different OTP controllers so far:
+ * 1. new IPX OTP controller: chipc 21, >=23
+ * 2. older HND OTP controller: chipc 12, 17, 22
+ *
+ * Define BCMHNDOTP to include support for the HND OTP controller.
+ * Define BCMIPXOTP to include support for the IPX OTP controller.
+ *
+ * NOTE 1: More than one may be defined
+ * NOTE 2: If none are defined, the default is to include them all.
+ */
+
+#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
+#define BCMHNDOTP 1
+#define BCMIPXOTP 1
+#endif
+
+#define OTPTYPE_HND(ccrev) ((ccrev) < 21 || (ccrev) == 22)
+#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
+
+#define OTPP_TRIES 10000000 /* # of tries for OTPP */
+
+#ifdef BCMIPXOTP
+#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
+#endif
+
+/* OTP common function type */
+typedef int (*otp_status_t) (void *oh);
+typedef int (*otp_size_t) (void *oh);
+typedef void *(*otp_init_t) (si_t *sih);
+typedef uint16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
+typedef int (*otp_read_region_t) (si_t *sih, int region, uint16 *data,
+ uint *wlen);
+typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
+
+/* OTP function struct */
+typedef struct otp_fn_s {
+ otp_size_t size;
+ otp_read_bit_t read_bit;
+ otp_init_t init;
+ otp_read_region_t read_region;
+ otp_nvread_t nvread;
+ otp_status_t status;
+} otp_fn_t;
+
+typedef struct {
+ uint ccrev; /* chipc revision */
+ otp_fn_t *fn; /* OTP functions */
+ si_t *sih; /* Saved sb handle */
+ osl_t *osh;
+
+#ifdef BCMIPXOTP
+ /* IPX OTP section */
+ uint16 wsize; /* Size of otp in words */
+ uint16 rows; /* Geometry */
+ uint16 cols; /* Geometry */
+ uint32 status; /* Flag bits (lock/prog/rv).
+ * (Reflected only when OTP is power cycled)
+ */
+ uint16 hwbase; /* hardware subregion offset */
+ uint16 hwlim; /* hardware subregion boundary */
+ uint16 swbase; /* software subregion offset */
+ uint16 swlim; /* software subregion boundary */
+ uint16 fbase; /* fuse subregion offset */
+ uint16 flim; /* fuse subregion boundary */
+ int otpgu_base; /* offset to General Use Region */
+#endif /* BCMIPXOTP */
+
+#ifdef BCMHNDOTP
+ /* HND OTP section */
+ uint size; /* Size of otp in bytes */
+ uint hwprot; /* Hardware protection bits */
+ uint signvalid; /* Signature valid bits */
+ int boundary; /* hw/sw boundary */
+#endif /* BCMHNDOTP */
+} otpinfo_t;
+
+static otpinfo_t otpinfo;
+
+/*
+ * IPX OTP Code
+ *
+ * Exported functions:
+ * ipxotp_status()
+ * ipxotp_size()
+ * ipxotp_init()
+ * ipxotp_read_bit()
+ * ipxotp_read_region()
+ * ipxotp_nvread()
+ *
+ */
+
+#ifdef BCMIPXOTP
+
+#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
+
+/* OTP layout */
+/* CC revs 21, 24 and 27 OTP General Use Region word offset */
+#define REVA4_OTPGU_BASE 12
+
+/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
+#define REVB8_OTPGU_BASE 20
+
+/* CC rev 36 OTP General Use Region word offset */
+#define REV36_OTPGU_BASE 12
+
+/* Subregion word offsets in General Use region */
+#define OTPGU_HSB_OFF 0
+#define OTPGU_SFB_OFF 1
+#define OTPGU_CI_OFF 2
+#define OTPGU_P_OFF 3
+#define OTPGU_SROM_OFF 4
+
+/* Flag bit offsets in General Use region */
+#define OTPGU_HWP_OFF 60
+#define OTPGU_SWP_OFF 61
+#define OTPGU_CIP_OFF 62
+#define OTPGU_FUSEP_OFF 63
+#define OTPGU_CIP_MSK 0x4000
+#define OTPGU_P_MSK 0xf000
+#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
+
+/* OTP Size */
+#define OTP_SZ_FU_324 ((ROUNDUP(324, 8))/8) /* 324 bits */
+#define OTP_SZ_FU_288 (288/8) /* 288 bits */
+#define OTP_SZ_FU_216 (216/8) /* 216 bits */
+#define OTP_SZ_FU_72 (72/8) /* 72 bits */
+#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
+#define OTP4315_SWREG_SZ 178 /* 178 bytes */
+#define OTP_SZ_FU_144 (144/8) /* 144 bits */
+
+static int ipxotp_status(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ return (int)(oi->status);
+}
+
+/* Return size in bytes */
+static int ipxotp_size(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ return (int)oi->wsize * 2;
+}
+
+static uint16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+{
+ otpinfo_t *oi;
+
+ oi = (otpinfo_t *) oh;
+
+ ASSERT(wn < oi->wsize);
+ ASSERT(cc != NULL);
+
+ return R_REG(oi->osh, &cc->sromotp[wn]);
+}
+
+static uint16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint k, row, col;
+ uint32 otpp, st;
+
+ row = off / oi->cols;
+ col = off % oi->cols;
+
+ otpp = OTPP_START_BUSY |
+ ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
+ ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
+ ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
+ W_REG(oi->osh, &cc->otpprog, otpp);
+
+ for (k = 0;
+ ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY)
+ && (k < OTPP_TRIES); k++)
+ ;
+ if (k >= OTPP_TRIES) {
+ return 0xffff;
+ }
+ if (st & OTPP_READERR) {
+ return 0xffff;
+ }
+ st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+
+ return (int)st;
+}
+
+/* Calculate max HW/SW region byte size by substracting fuse region and checksum size,
+ * osizew is oi->wsize (OTP size - GU size) in words
+ */
+static int ipxotp_max_rgnsz(si_t *sih, int osizew)
+{
+ int ret = 0;
+
+ switch (CHIPID(sih->chip)) {
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+ break;
+ case BCM4313_CHIP_ID:
+ ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+ break;
+ default:
+ ASSERT(0); /* Don't konw about this chip */
+ }
+
+ return ret;
+}
+
+static void BCMNMIATTACHFN(_ipxotp_init) (otpinfo_t *oi, chipcregs_t *cc)
+{
+ uint k;
+ uint32 otpp, st;
+
+ /* record word offset of General Use Region for various chipcommon revs */
+ if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
+ || oi->sih->ccrev == 27) {
+ oi->otpgu_base = REVA4_OTPGU_BASE;
+ } else if (oi->sih->ccrev == 36) {
+ /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
+ if (oi->wsize >= 128)
+ oi->otpgu_base = REVB8_OTPGU_BASE;
+ else
+ oi->otpgu_base = REV36_OTPGU_BASE;
+ } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
+ oi->otpgu_base = REVB8_OTPGU_BASE;
+ }
+
+ /* First issue an init command so the status is up to date */
+ otpp =
+ OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
+
+ W_REG(oi->osh, &cc->otpprog, otpp);
+ for (k = 0;
+ ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY)
+ && (k < OTPP_TRIES); k++)
+ ;
+ if (k >= OTPP_TRIES) {
+ return;
+ }
+
+ /* Read OTP lock bits and subregion programmed indication bits */
+ oi->status = R_REG(oi->osh, &cc->otpstatus);
+
+ if ((CHIPID(oi->sih->chip) == BCM43224_CHIP_ID)
+ || (CHIPID(oi->sih->chip) == BCM43225_CHIP_ID)) {
+ uint32 p_bits;
+ p_bits =
+ (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
+ OTPGU_P_MSK)
+ >> OTPGU_P_SHIFT;
+ oi->status |= (p_bits << OTPS_GUP_SHIFT);
+ }
+
+ /*
+ * h/w region base and fuse region limit are fixed to the top and
+ * the bottom of the general use region. Everything else can be flexible.
+ */
+ oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
+ oi->hwlim = oi->wsize;
+ if (oi->status & OTPS_GUP_HW) {
+ oi->hwlim =
+ ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
+ oi->swbase = oi->hwlim;
+ } else
+ oi->swbase = oi->hwbase;
+
+ /* subtract fuse and checksum from beginning */
+ oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
+
+ if (oi->status & OTPS_GUP_SW) {
+ oi->swlim =
+ ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
+ oi->fbase = oi->swlim;
+ } else
+ oi->fbase = oi->swbase;
+
+ oi->flim = oi->wsize;
+}
+
+static void *BCMNMIATTACHFN(ipxotp_init) (si_t *sih)
+{
+ uint idx;
+ chipcregs_t *cc;
+ otpinfo_t *oi;
+
+ /* Make sure we're running IPX OTP */
+ ASSERT(OTPTYPE_IPX(sih->ccrev));
+ if (!OTPTYPE_IPX(sih->ccrev))
+ return NULL;
+
+ /* Make sure OTP is not disabled */
+ if (si_is_otp_disabled(sih)) {
+ return NULL;
+ }
+
+ /* Make sure OTP is powered up */
+ if (!si_is_otp_powered(sih)) {
+ return NULL;
+ }
+
+ oi = &otpinfo;
+
+ /* Check for otp size */
+ switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
+ case 0:
+ /* Nothing there */
+ return NULL;
+ case 1: /* 32x64 */
+ oi->rows = 32;
+ oi->cols = 64;
+ oi->wsize = 128;
+ break;
+ case 2: /* 64x64 */
+ oi->rows = 64;
+ oi->cols = 64;
+ oi->wsize = 256;
+ break;
+ case 5: /* 96x64 */
+ oi->rows = 96;
+ oi->cols = 64;
+ oi->wsize = 384;
+ break;
+ case 7: /* 16x64 *//* 1024 bits */
+ oi->rows = 16;
+ oi->cols = 64;
+ oi->wsize = 64;
+ break;
+ default:
+ /* Don't know the geometry */
+ return NULL;
+ }
+
+ /* Retrieve OTP region info */
+ idx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ _ipxotp_init(oi, cc);
+
+ si_setcoreidx(sih, idx);
+
+ return (void *)oi;
+}
+
+static int ipxotp_read_region(void *oh, int region, uint16 *data, uint *wlen)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint idx;
+ chipcregs_t *cc;
+ uint base, i, sz;
+
+ /* Validate region selection */
+ switch (region) {
+ case OTP_HW_RGN:
+ sz = (uint) oi->hwlim - oi->hwbase;
+ if (!(oi->status & OTPS_GUP_HW)) {
+ *wlen = sz;
+ return BCME_NOTFOUND;
+ }
+ if (*wlen < sz) {
+ *wlen = sz;
+ return BCME_BUFTOOSHORT;
+ }
+ base = oi->hwbase;
+ break;
+ case OTP_SW_RGN:
+ sz = ((uint) oi->swlim - oi->swbase);
+ if (!(oi->status & OTPS_GUP_SW)) {
+ *wlen = sz;
+ return BCME_NOTFOUND;
+ }
+ if (*wlen < sz) {
+ *wlen = sz;
+ return BCME_BUFTOOSHORT;
+ }
+ base = oi->swbase;
+ break;
+ case OTP_CI_RGN:
+ sz = OTPGU_CI_SZ;
+ if (!(oi->status & OTPS_GUP_CI)) {
+ *wlen = sz;
+ return BCME_NOTFOUND;
+ }
+ if (*wlen < sz) {
+ *wlen = sz;
+ return BCME_BUFTOOSHORT;
+ }
+ base = oi->otpgu_base + OTPGU_CI_OFF;
+ break;
+ case OTP_FUSE_RGN:
+ sz = (uint) oi->flim - oi->fbase;
+ if (!(oi->status & OTPS_GUP_FUSE)) {
+ *wlen = sz;
+ return BCME_NOTFOUND;
+ }
+ if (*wlen < sz) {
+ *wlen = sz;
+ return BCME_BUFTOOSHORT;
+ }
+ base = oi->fbase;
+ break;
+ case OTP_ALL_RGN:
+ sz = ((uint) oi->flim - oi->hwbase);
+ if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
+ *wlen = sz;
+ return BCME_NOTFOUND;
+ }
+ if (*wlen < sz) {
+ *wlen = sz;
+ return BCME_BUFTOOSHORT;
+ }
+ base = oi->hwbase;
+ break;
+ default:
+ return BCME_BADARG;
+ }
+
+ idx = si_coreidx(oi->sih);
+ cc = si_setcoreidx(oi->sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ /* Read the data */
+ for (i = 0; i < sz; i++)
+ data[i] = ipxotp_otpr(oh, cc, base + i);
+
+ si_setcoreidx(oi->sih, idx);
+ *wlen = sz;
+ return 0;
+}
+
+static int ipxotp_nvread(void *oh, char *data, uint *len)
+{
+ return BCME_UNSUPPORTED;
+}
+
+static otp_fn_t ipxotp_fn = {
+ (otp_size_t) ipxotp_size,
+ (otp_read_bit_t) ipxotp_read_bit,
+
+ (otp_init_t) ipxotp_init,
+ (otp_read_region_t) ipxotp_read_region,
+ (otp_nvread_t) ipxotp_nvread,
+
+ (otp_status_t) ipxotp_status
+};
+
+#endif /* BCMIPXOTP */
+
+/*
+ * HND OTP Code
+ *
+ * Exported functions:
+ * hndotp_status()
+ * hndotp_size()
+ * hndotp_init()
+ * hndotp_read_bit()
+ * hndotp_read_region()
+ * hndotp_nvread()
+ *
+ */
+
+#ifdef BCMHNDOTP
+
+/* Fields in otpstatus */
+#define OTPS_PROGFAIL 0x80000000
+#define OTPS_PROTECT 0x00000007
+#define OTPS_HW_PROTECT 0x00000001
+#define OTPS_SW_PROTECT 0x00000002
+#define OTPS_CID_PROTECT 0x00000004
+#define OTPS_RCEV_MSK 0x00003f00
+#define OTPS_RCEV_SHIFT 8
+
+/* Fields in the otpcontrol register */
+#define OTPC_RECWAIT 0xff000000
+#define OTPC_PROGWAIT 0x00ffff00
+#define OTPC_PRW_SHIFT 8
+#define OTPC_MAXFAIL 0x00000038
+#define OTPC_VSEL 0x00000006
+#define OTPC_SELVL 0x00000001
+
+/* OTP regions (Word offsets from otp size) */
+#define OTP_SWLIM_OFF (-4)
+#define OTP_CIDBASE_OFF 0
+#define OTP_CIDLIM_OFF 4
+
+/* Predefined OTP words (Word offset from otp size) */
+#define OTP_BOUNDARY_OFF (-4)
+#define OTP_HWSIGN_OFF (-3)
+#define OTP_SWSIGN_OFF (-2)
+#define OTP_CIDSIGN_OFF (-1)
+#define OTP_CID_OFF 0
+#define OTP_PKG_OFF 1
+#define OTP_FID_OFF 2
+#define OTP_RSV_OFF 3
+#define OTP_LIM_OFF 4
+#define OTP_RD_OFF 4 /* Redundancy row starts here */
+#define OTP_RC0_OFF 28 /* Redundancy control word 1 */
+#define OTP_RC1_OFF 32 /* Redundancy control word 2 */
+#define OTP_RC_LIM_OFF 36 /* Redundancy control word end */
+
+#define OTP_HW_REGION OTPS_HW_PROTECT
+#define OTP_SW_REGION OTPS_SW_PROTECT
+#define OTP_CID_REGION OTPS_CID_PROTECT
+
+#if OTP_HW_REGION != OTP_HW_RGN
+#error "incompatible OTP_HW_RGN"
+#endif
+#if OTP_SW_REGION != OTP_SW_RGN
+#error "incompatible OTP_SW_RGN"
+#endif
+#if OTP_CID_REGION != OTP_CI_RGN
+#error "incompatible OTP_CI_RGN"
+#endif
+
+/* Redundancy entry definitions */
+#define OTP_RCE_ROW_SZ 6
+#define OTP_RCE_SIGN_MASK 0x7fff
+#define OTP_RCE_ROW_MASK 0x3f
+#define OTP_RCE_BITS 21
+#define OTP_RCE_SIGN_SZ 15
+#define OTP_RCE_BIT0 1
+
+#define OTP_WPR 4
+#define OTP_SIGNATURE 0x578a
+#define OTP_MAGIC 0x4e56
+
+static int hndotp_status(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ return (int)(oi->hwprot | oi->signvalid);
+}
+
+static int hndotp_size(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ return (int)(oi->size);
+}
+
+static uint16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ osl_t *osh;
+ volatile uint16 *ptr;
+
+ ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF));
+ ASSERT(cc != NULL);
+
+ osh = si_osh(oi->sih);
+
+ ptr = (volatile uint16 *)((volatile char *)cc + CC_SROM_OTP);
+ return R_REG(osh, &ptr[wn]);
+}
+
+static uint16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ osl_t *osh;
+ volatile uint16 *ptr;
+
+ ASSERT(woff >= (-((int)oi->size / 2)));
+ ASSERT(woff < OTP_LIM_OFF);
+ ASSERT(cc != NULL);
+
+ osh = si_osh(oi->sih);
+
+ ptr = (volatile uint16 *)((volatile char *)cc + CC_SROM_OTP);
+
+ return R_REG(osh, &ptr[(oi->size / 2) + woff]);
+}
+
+static uint16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint k, row, col;
+ uint32 otpp, st;
+ osl_t *osh;
+
+ osh = si_osh(oi->sih);
+ row = idx / 65;
+ col = idx % 65;
+
+ otpp = OTPP_START_BUSY | OTPP_READ |
+ ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
+
+ W_REG(osh, &cc->otpprog, otpp);
+ st = R_REG(osh, &cc->otpprog);
+ for (k = 0;
+ ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
+ k++)
+ st = R_REG(osh, &cc->otpprog);
+
+ if (k >= OTPP_TRIES) {
+ return 0xffff;
+ }
+ if (st & OTPP_READERR) {
+ return 0xffff;
+ }
+ st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+ return (uint16) st;
+}
+
+static void *BCMNMIATTACHFN(hndotp_init) (si_t *sih)
+{
+ uint idx;
+ chipcregs_t *cc;
+ otpinfo_t *oi;
+ uint32 cap = 0, clkdiv, otpdiv = 0;
+ void *ret = NULL;
+ osl_t *osh;
+
+ oi = &otpinfo;
+
+ idx = si_coreidx(sih);
+ osh = si_osh(oi->sih);
+
+ /* Check for otp */
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ if (cc != NULL) {
+ cap = R_REG(osh, &cc->capabilities);
+ if ((cap & CC_CAP_OTPSIZE) == 0) {
+ /* Nothing there */
+ goto out;
+ }
+
+ /* As of right now, support only 4320a2, 4311a1 and 4312 */
+ ASSERT((oi->ccrev == 12) || (oi->ccrev == 17)
+ || (oi->ccrev == 22));
+ if (!
+ ((oi->ccrev == 12) || (oi->ccrev == 17)
+ || (oi->ccrev == 22)))
+ return NULL;
+
+ /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
+ * 8 row (64 bytes) smaller
+ */
+ oi->size =
+ 1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
+ + CC_CAP_OTPSIZE_BASE);
+ if (oi->ccrev >= 18)
+ oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
+
+ oi->hwprot = (int)(R_REG(osh, &cc->otpstatus) & OTPS_PROTECT);
+ oi->boundary = -1;
+
+ /* Check the region signature */
+ if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
+ oi->signvalid |= OTP_HW_REGION;
+ oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
+ }
+
+ if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
+ oi->signvalid |= OTP_SW_REGION;
+
+ if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
+ oi->signvalid |= OTP_CID_REGION;
+
+ /* Set OTP clkdiv for stability */
+ if (oi->ccrev == 22)
+ otpdiv = 12;
+
+ if (otpdiv) {
+ clkdiv = R_REG(osh, &cc->clkdiv);
+ clkdiv =
+ (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
+ W_REG(osh, &cc->clkdiv, clkdiv);
+ }
+ OSL_DELAY(10);
+
+ ret = (void *)oi;
+ }
+
+ out: /* All done */
+ si_setcoreidx(sih, idx);
+
+ return ret;
+}
+
+static int hndotp_read_region(void *oh, int region, uint16 *data, uint *wlen)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint32 idx, st;
+ chipcregs_t *cc;
+ int i;
+
+ /* Only support HW region (no active chips use HND OTP SW region) */
+ ASSERT(region == OTP_HW_REGION);
+
+ /* Region empty? */
+ st = oi->hwprot | oi->signvalid;
+ if ((st & region) == 0)
+ return BCME_NOTFOUND;
+
+ *wlen =
+ ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
+
+ idx = si_coreidx(oi->sih);
+ cc = si_setcoreidx(oi->sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ for (i = 0; i < (int)*wlen; i++)
+ data[i] = hndotp_otpr(oh, cc, i);
+
+ si_setcoreidx(oi->sih, idx);
+
+ return 0;
+}
+
+static int hndotp_nvread(void *oh, char *data, uint *len)
+{
+ int rc = 0;
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint32 base, bound, lim = 0, st;
+ int i, chunk, gchunks, tsz = 0;
+ uint32 idx;
+ chipcregs_t *cc;
+ uint offset;
+ uint16 *rawotp = NULL;
+
+ /* save the orig core */
+ idx = si_coreidx(oi->sih);
+ cc = si_setcoreidx(oi->sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ st = hndotp_status(oh);
+ if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
+ rc = -1;
+ goto out;
+ }
+
+ /* Read the whole otp so we can easily manipulate it */
+ lim = hndotp_size(oh);
+ rawotp = MALLOC(si_osh(oi->sih), lim);
+ if (rawotp == NULL) {
+ rc = -2;
+ goto out;
+ }
+ for (i = 0; i < (int)(lim / 2); i++)
+ rawotp[i] = hndotp_otpr(oh, cc, i);
+
+ if ((st & OTP_HW_REGION) == 0) {
+ /* This could be a programming failure in the first
+ * chunk followed by one or more good chunks
+ */
+ for (i = 0; i < (int)(lim / 2); i++)
+ if (rawotp[i] == OTP_MAGIC)
+ break;
+
+ if (i < (int)(lim / 2)) {
+ base = i;
+ bound = (i * 2) + rawotp[i + 1];
+ } else {
+ rc = -3;
+ goto out;
+ }
+ } else {
+ bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
+
+ /* There are two cases: 1) The whole otp is used as nvram
+ * and 2) There is a hardware header followed by nvram.
+ */
+ if (rawotp[0] == OTP_MAGIC) {
+ base = 0;
+ } else
+ base = bound;
+ }
+
+ /* Find and copy the data */
+
+ chunk = 0;
+ gchunks = 0;
+ i = base / 2;
+ offset = 0;
+ while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
+ int dsz, rsz = rawotp[i + 1];
+
+ if (((i * 2) + rsz) >= (int)lim) {
+ /* Bad length, try to find another chunk anyway */
+ rsz = 6;
+ }
+ if (hndcrc16((uint8 *) &rawotp[i], rsz,
+ CRC16_INIT_VALUE) == CRC16_GOOD_VALUE) {
+ /* Good crc, copy the vars */
+ gchunks++;
+ dsz = rsz - 6;
+ tsz += dsz;
+ if (offset + dsz >= *len) {
+ goto out;
+ }
+ bcopy((char *)&rawotp[i + 2], &data[offset], dsz);
+ offset += dsz;
+ /* Remove extra null characters at the end */
+ while (offset > 1 &&
+ data[offset - 1] == 0 && data[offset - 2] == 0)
+ offset--;
+ i += rsz / 2;
+ } else {
+ /* bad length or crc didn't check, try to find the next set */
+ if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
+ /* Assume length is good */
+ i += rsz / 2;
+ } else {
+ while (++i < (int)(lim / 2))
+ if (rawotp[i] == OTP_MAGIC)
+ break;
+ }
+ }
+ chunk++;
+ }
+
+ *len = offset;
+
+ out:
+ if (rawotp)
+ MFREE(si_osh(oi->sih), rawotp, lim);
+ si_setcoreidx(oi->sih, idx);
+
+ return rc;
+}
+
+static otp_fn_t hndotp_fn = {
+ (otp_size_t) hndotp_size,
+ (otp_read_bit_t) hndotp_read_bit,
+
+ (otp_init_t) hndotp_init,
+ (otp_read_region_t) hndotp_read_region,
+ (otp_nvread_t) hndotp_nvread,
+
+ (otp_status_t) hndotp_status
+};
+
+#endif /* BCMHNDOTP */
+
+/*
+ * Common Code: Compiled for IPX / HND / AUTO
+ * otp_status()
+ * otp_size()
+ * otp_read_bit()
+ * otp_init()
+ * otp_read_region()
+ * otp_nvread()
+ */
+
+int otp_status(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+
+ return oi->fn->status(oh);
+}
+
+int otp_size(void *oh)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+
+ return oi->fn->size(oh);
+}
+
+uint16 otp_read_bit(void *oh, uint offset)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+ uint idx = si_coreidx(oi->sih);
+ chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX);
+ uint16 readBit = (uint16) oi->fn->read_bit(oh, cc, offset);
+ si_setcoreidx(oi->sih, idx);
+ return readBit;
+}
+
+void *BCMNMIATTACHFN(otp_init) (si_t *sih)
+{
+ otpinfo_t *oi;
+ void *ret = NULL;
+
+ oi = &otpinfo;
+ bzero(oi, sizeof(otpinfo_t));
+
+ oi->ccrev = sih->ccrev;
+
+#ifdef BCMIPXOTP
+ if (OTPTYPE_IPX(oi->ccrev))
+ oi->fn = &ipxotp_fn;
+#endif
+
+#ifdef BCMHNDOTP
+ if (OTPTYPE_HND(oi->ccrev))
+ oi->fn = &hndotp_fn;
+#endif
+
+ if (oi->fn == NULL) {
+ return NULL;
+ }
+
+ oi->sih = sih;
+ oi->osh = si_osh(oi->sih);
+
+ ret = (oi->fn->init) (sih);
+
+ return ret;
+}
+
+int
+BCMNMIATTACHFN(otp_read_region) (si_t *sih, int region, uint16 *data,
+ uint *wlen) {
+ bool wasup = FALSE;
+ void *oh;
+ int err = 0;
+
+ wasup = si_is_otp_powered(sih);
+ if (!wasup)
+ si_otp_power(sih, TRUE);
+
+ if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) {
+ err = BCME_NOTREADY;
+ goto out;
+ }
+
+ oh = otp_init(sih);
+ if (oh == NULL) {
+ err = BCME_ERROR;
+ goto out;
+ }
+
+ err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
+
+ out:
+ if (!wasup)
+ si_otp_power(sih, FALSE);
+
+ return err;
+}
+
+int otp_nvread(void *oh, char *data, uint *len)
+{
+ otpinfo_t *oi = (otpinfo_t *) oh;
+
+ return oi->fn->nvread(oh, data, len);
+}
diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c
new file mode 100644
index 000000000000..a295ecb9320c
--- /dev/null
+++ b/drivers/staging/brcm80211/util/bcmsrom.c
@@ -0,0 +1,2092 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <stdarg.h>
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <pcicfg.h>
+#include <siutils.h>
+#include <bcmsrom.h>
+#include <bcmsrom_tbl.h>
+#ifdef BCMSDIO
+#include <bcmsdh.h>
+#include <sdio.h>
+#endif
+
+#include <bcmnvram.h>
+#include <bcmotp.h>
+
+#if defined(BCMSDIO)
+#include <sbsdio.h>
+#include <sbhnddma.h>
+#include <sbsdpcmdev.h>
+#endif
+
+#include <proto/ethernet.h> /* for sprom content groking */
+
+#define BS_ERROR(args)
+
+#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
+ (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
+ ((uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
+ ((uint8 *)curmap + PCI_BAR0_SPROM_OFFSET))
+
+#if defined(BCMDBG)
+#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
+#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
+#endif
+
+typedef struct varbuf {
+ char *base; /* pointer to buffer base */
+ char *buf; /* pointer to current position */
+ unsigned int size; /* current (residual) size in bytes */
+} varbuf_t;
+extern char *_vars;
+extern uint _varsz;
+
+#define SROM_CIS_SINGLE 1
+
+static int initvars_srom_si(si_t *sih, osl_t *osh, void *curmap, char **vars,
+ uint *count);
+static void _initvars_srom_pci(uint8 sromrev, uint16 *srom, uint off,
+ varbuf_t *b);
+static int initvars_srom_pci(si_t *sih, void *curmap, char **vars,
+ uint *count);
+static int initvars_flash_si(si_t *sih, char **vars, uint *count);
+#ifdef BCMSDIO
+static int initvars_cis_sdio(osl_t *osh, char **vars, uint *count);
+static int sprom_cmd_sdio(osl_t *osh, uint8 cmd);
+static int sprom_read_sdio(osl_t *osh, uint16 addr, uint16 *data);
+#endif /* BCMSDIO */
+static int sprom_read_pci(osl_t *osh, si_t *sih, uint16 *sprom, uint wordoff,
+ uint16 *buf, uint nwords, bool check_crc);
+#if defined(BCMNVRAMR)
+static int otp_read_pci(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz);
+#endif
+static uint16 srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, uint32 cmd,
+ uint wordoff, uint16 data);
+
+static int initvars_table(osl_t *osh, char *start, char *end, char **vars,
+ uint *count);
+static int initvars_flash(si_t *sih, osl_t *osh, char **vp, uint len);
+
+/* Initialization of varbuf structure */
+static void BCMATTACHFN(varbuf_init) (varbuf_t *b, char *buf, uint size)
+{
+ b->size = size;
+ b->base = b->buf = buf;
+}
+
+/* append a null terminated var=value string */
+static int BCMATTACHFN(varbuf_append) (varbuf_t *b, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+ size_t len;
+ char *s;
+
+ if (b->size < 2)
+ return 0;
+
+ va_start(ap, fmt);
+ r = vsnprintf(b->buf, b->size, fmt, ap);
+ va_end(ap);
+
+ /* C99 snprintf behavior returns r >= size on overflow,
+ * others return -1 on overflow.
+ * All return -1 on format error.
+ * We need to leave room for 2 null terminations, one for the current var
+ * string, and one for final null of the var table. So check that the
+ * strlen written, r, leaves room for 2 chars.
+ */
+ if ((r == -1) || (r > (int)(b->size - 2))) {
+ b->size = 0;
+ return 0;
+ }
+
+ /* Remove any earlier occurrence of the same variable */
+ s = strchr(b->buf, '=');
+ if (s != NULL) {
+ len = (size_t) (s - b->buf);
+ for (s = b->base; s < b->buf;) {
+ if ((bcmp(s, b->buf, len) == 0) && s[len] == '=') {
+ len = strlen(s) + 1;
+ memmove(s, (s + len),
+ ((b->buf + r + 1) - (s + len)));
+ b->buf -= len;
+ b->size += (unsigned int)len;
+ break;
+ }
+
+ while (*s++)
+ ;
+ }
+ }
+
+ /* skip over this string's null termination */
+ r++;
+ b->size -= r;
+ b->buf += r;
+
+ return r;
+}
+
+/*
+ * Initialize local vars from the right source for this platform.
+ * Return 0 on success, nonzero on error.
+ */
+int
+BCMATTACHFN(srom_var_init) (si_t *sih, uint bustype, void *curmap, osl_t *osh,
+ char **vars, uint *count) {
+ uint len;
+
+ len = 0;
+
+ ASSERT(bustype == BUSTYPE(bustype));
+ if (vars == NULL || count == NULL)
+ return 0;
+
+ *vars = NULL;
+ *count = 0;
+
+ switch (BUSTYPE(bustype)) {
+ case SI_BUS:
+ case JTAG_BUS:
+ return initvars_srom_si(sih, osh, curmap, vars, count);
+
+ case PCI_BUS:
+ ASSERT(curmap != NULL);
+ if (curmap == NULL)
+ return -1;
+
+ return initvars_srom_pci(sih, curmap, vars, count);
+
+#ifdef BCMSDIO
+ case SDIO_BUS:
+ return initvars_cis_sdio(osh, vars, count);
+#endif /* BCMSDIO */
+
+ default:
+ ASSERT(0);
+ }
+ return -1;
+}
+
+/* support only 16-bit word read from srom */
+int
+srom_read(si_t *sih, uint bustype, void *curmap, osl_t *osh,
+ uint byteoff, uint nbytes, uint16 *buf, bool check_crc)
+{
+ uint off, nw;
+#ifdef BCMSDIO
+ uint i;
+#endif /* BCMSDIO */
+
+ ASSERT(bustype == BUSTYPE(bustype));
+
+ /* check input - 16-bit access only */
+ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX)
+ return 1;
+
+ off = byteoff / 2;
+ nw = nbytes / 2;
+
+ if (BUSTYPE(bustype) == PCI_BUS) {
+ if (!curmap)
+ return 1;
+
+ if (si_is_sprom_available(sih)) {
+ uint16 *srom;
+
+ srom = (uint16 *) SROM_OFFSET(sih);
+ if (srom == NULL)
+ return 1;
+
+ if (sprom_read_pci
+ (osh, sih, srom, off, buf, nw, check_crc))
+ return 1;
+ }
+#if defined(BCMNVRAMR)
+ else {
+ if (otp_read_pci(osh, sih, buf, SROM_MAX))
+ return 1;
+ }
+#endif
+#ifdef BCMSDIO
+ } else if (BUSTYPE(bustype) == SDIO_BUS) {
+ off = byteoff / 2;
+ nw = nbytes / 2;
+ for (i = 0; i < nw; i++) {
+ if (sprom_read_sdio
+ (osh, (uint16) (off + i), (uint16 *) (buf + i)))
+ return 1;
+ }
+#endif /* BCMSDIO */
+ } else if (BUSTYPE(bustype) == SI_BUS) {
+ return 1;
+ } else {
+ return 1;
+ }
+
+ return 0;
+}
+
+static const char BCMATTACHDATA(vstr_manf)[] = "manf=%s";
+static const char BCMATTACHDATA(vstr_productname)[] = "productname=%s";
+static const char BCMATTACHDATA(vstr_manfid)[] = "manfid=0x%x";
+static const char BCMATTACHDATA(vstr_prodid)[] = "prodid=0x%x";
+#ifdef BCMSDIO
+static const char BCMATTACHDATA(vstr_sdmaxspeed)[] = "sdmaxspeed=%d";
+static const char BCMATTACHDATA(vstr_sdmaxblk)[][13] = {
+"sdmaxblk0=%d", "sdmaxblk1=%d", "sdmaxblk2=%d"};
+#endif
+static const char BCMATTACHDATA(vstr_regwindowsz)[] = "regwindowsz=%d";
+static const char BCMATTACHDATA(vstr_sromrev)[] = "sromrev=%d";
+static const char BCMATTACHDATA(vstr_chiprev)[] = "chiprev=%d";
+static const char BCMATTACHDATA(vstr_subvendid)[] = "subvendid=0x%x";
+static const char BCMATTACHDATA(vstr_subdevid)[] = "subdevid=0x%x";
+static const char BCMATTACHDATA(vstr_boardrev)[] = "boardrev=0x%x";
+static const char BCMATTACHDATA(vstr_aa2g)[] = "aa2g=0x%x";
+static const char BCMATTACHDATA(vstr_aa5g)[] = "aa5g=0x%x";
+static const char BCMATTACHDATA(vstr_ag)[] = "ag%d=0x%x";
+static const char BCMATTACHDATA(vstr_cc)[] = "cc=%d";
+static const char BCMATTACHDATA(vstr_opo)[] = "opo=%d";
+static const char BCMATTACHDATA(vstr_pa0b)[][9] = {
+"pa0b0=%d", "pa0b1=%d", "pa0b2=%d"};
+
+static const char BCMATTACHDATA(vstr_pa0itssit)[] = "pa0itssit=%d";
+static const char BCMATTACHDATA(vstr_pa0maxpwr)[] = "pa0maxpwr=%d";
+static const char BCMATTACHDATA(vstr_pa1b)[][9] = {
+"pa1b0=%d", "pa1b1=%d", "pa1b2=%d"};
+
+static const char BCMATTACHDATA(vstr_pa1lob)[][11] = {
+"pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d"};
+
+static const char BCMATTACHDATA(vstr_pa1hib)[][11] = {
+"pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d"};
+
+static const char BCMATTACHDATA(vstr_pa1itssit)[] = "pa1itssit=%d";
+static const char BCMATTACHDATA(vstr_pa1maxpwr)[] = "pa1maxpwr=%d";
+static const char BCMATTACHDATA(vstr_pa1lomaxpwr)[] = "pa1lomaxpwr=%d";
+static const char BCMATTACHDATA(vstr_pa1himaxpwr)[] = "pa1himaxpwr=%d";
+static const char BCMATTACHDATA(vstr_oem)[] =
+ "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
+static const char BCMATTACHDATA(vstr_boardflags)[] = "boardflags=0x%x";
+static const char BCMATTACHDATA(vstr_boardflags2)[] = "boardflags2=0x%x";
+static const char BCMATTACHDATA(vstr_ledbh)[] = "ledbh%d=0x%x";
+static const char BCMATTACHDATA(vstr_noccode)[] = "ccode=0x0";
+static const char BCMATTACHDATA(vstr_ccode)[] = "ccode=%c%c";
+static const char BCMATTACHDATA(vstr_cctl)[] = "cctl=0x%x";
+static const char BCMATTACHDATA(vstr_cckpo)[] = "cckpo=0x%x";
+static const char BCMATTACHDATA(vstr_ofdmpo)[] = "ofdmpo=0x%x";
+static const char BCMATTACHDATA(vstr_rdlid)[] = "rdlid=0x%x";
+static const char BCMATTACHDATA(vstr_rdlrndis)[] = "rdlrndis=%d";
+static const char BCMATTACHDATA(vstr_rdlrwu)[] = "rdlrwu=%d";
+static const char BCMATTACHDATA(vstr_usbfs)[] = "usbfs=%d";
+static const char BCMATTACHDATA(vstr_wpsgpio)[] = "wpsgpio=%d";
+static const char BCMATTACHDATA(vstr_wpsled)[] = "wpsled=%d";
+static const char BCMATTACHDATA(vstr_rdlsn)[] = "rdlsn=%d";
+static const char BCMATTACHDATA(vstr_rssismf2g)[] = "rssismf2g=%d";
+static const char BCMATTACHDATA(vstr_rssismc2g)[] = "rssismc2g=%d";
+static const char BCMATTACHDATA(vstr_rssisav2g)[] = "rssisav2g=%d";
+static const char BCMATTACHDATA(vstr_bxa2g)[] = "bxa2g=%d";
+static const char BCMATTACHDATA(vstr_rssismf5g)[] = "rssismf5g=%d";
+static const char BCMATTACHDATA(vstr_rssismc5g)[] = "rssismc5g=%d";
+static const char BCMATTACHDATA(vstr_rssisav5g)[] = "rssisav5g=%d";
+static const char BCMATTACHDATA(vstr_bxa5g)[] = "bxa5g=%d";
+static const char BCMATTACHDATA(vstr_tri2g)[] = "tri2g=%d";
+static const char BCMATTACHDATA(vstr_tri5gl)[] = "tri5gl=%d";
+static const char BCMATTACHDATA(vstr_tri5g)[] = "tri5g=%d";
+static const char BCMATTACHDATA(vstr_tri5gh)[] = "tri5gh=%d";
+static const char BCMATTACHDATA(vstr_rxpo2g)[] = "rxpo2g=%d";
+static const char BCMATTACHDATA(vstr_rxpo5g)[] = "rxpo5g=%d";
+static const char BCMATTACHDATA(vstr_boardtype)[] = "boardtype=0x%x";
+static const char BCMATTACHDATA(vstr_leddc)[] = "leddc=0x%04x";
+static const char BCMATTACHDATA(vstr_vendid)[] = "vendid=0x%x";
+static const char BCMATTACHDATA(vstr_devid)[] = "devid=0x%x";
+static const char BCMATTACHDATA(vstr_xtalfreq)[] = "xtalfreq=%d";
+static const char BCMATTACHDATA(vstr_txchain)[] = "txchain=0x%x";
+static const char BCMATTACHDATA(vstr_rxchain)[] = "rxchain=0x%x";
+static const char BCMATTACHDATA(vstr_antswitch)[] = "antswitch=0x%x";
+static const char BCMATTACHDATA(vstr_regrev)[] = "regrev=0x%x";
+static const char BCMATTACHDATA(vstr_antswctl2g)[] = "antswctl2g=0x%x";
+static const char BCMATTACHDATA(vstr_triso2g)[] = "triso2g=0x%x";
+static const char BCMATTACHDATA(vstr_pdetrange2g)[] = "pdetrange2g=0x%x";
+static const char BCMATTACHDATA(vstr_extpagain2g)[] = "extpagain2g=0x%x";
+static const char BCMATTACHDATA(vstr_tssipos2g)[] = "tssipos2g=0x%x";
+static const char BCMATTACHDATA(vstr_antswctl5g)[] = "antswctl5g=0x%x";
+static const char BCMATTACHDATA(vstr_triso5g)[] = "triso5g=0x%x";
+static const char BCMATTACHDATA(vstr_pdetrange5g)[] = "pdetrange5g=0x%x";
+static const char BCMATTACHDATA(vstr_extpagain5g)[] = "extpagain5g=0x%x";
+static const char BCMATTACHDATA(vstr_tssipos5g)[] = "tssipos5g=0x%x";
+static const char BCMATTACHDATA(vstr_maxp2ga0)[] = "maxp2ga0=0x%x";
+static const char BCMATTACHDATA(vstr_itt2ga0)[] = "itt2ga0=0x%x";
+static const char BCMATTACHDATA(vstr_pa)[] = "pa%dgw%da%d=0x%x";
+static const char BCMATTACHDATA(vstr_pahl)[] = "pa%dg%cw%da%d=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5ga0)[] = "maxp5ga0=0x%x";
+static const char BCMATTACHDATA(vstr_itt5ga0)[] = "itt5ga0=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5gha0)[] = "maxp5gha0=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5gla0)[] = "maxp5gla0=0x%x";
+static const char BCMATTACHDATA(vstr_maxp2ga1)[] = "maxp2ga1=0x%x";
+static const char BCMATTACHDATA(vstr_itt2ga1)[] = "itt2ga1=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5ga1)[] = "maxp5ga1=0x%x";
+static const char BCMATTACHDATA(vstr_itt5ga1)[] = "itt5ga1=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5gha1)[] = "maxp5gha1=0x%x";
+static const char BCMATTACHDATA(vstr_maxp5gla1)[] = "maxp5gla1=0x%x";
+static const char BCMATTACHDATA(vstr_cck2gpo)[] = "cck2gpo=0x%x";
+static const char BCMATTACHDATA(vstr_ofdm2gpo)[] = "ofdm2gpo=0x%x";
+static const char BCMATTACHDATA(vstr_ofdm5gpo)[] = "ofdm5gpo=0x%x";
+static const char BCMATTACHDATA(vstr_ofdm5glpo)[] = "ofdm5glpo=0x%x";
+static const char BCMATTACHDATA(vstr_ofdm5ghpo)[] = "ofdm5ghpo=0x%x";
+static const char BCMATTACHDATA(vstr_cddpo)[] = "cddpo=0x%x";
+static const char BCMATTACHDATA(vstr_stbcpo)[] = "stbcpo=0x%x";
+static const char BCMATTACHDATA(vstr_bw40po)[] = "bw40po=0x%x";
+static const char BCMATTACHDATA(vstr_bwduppo)[] = "bwduppo=0x%x";
+static const char BCMATTACHDATA(vstr_mcspo)[] = "mcs%dgpo%d=0x%x";
+static const char BCMATTACHDATA(vstr_mcspohl)[] = "mcs%dg%cpo%d=0x%x";
+static const char BCMATTACHDATA(vstr_custom)[] = "customvar%d=0x%x";
+static const char BCMATTACHDATA(vstr_cckdigfilttype)[] = "cckdigfilttype=%d";
+static const char BCMATTACHDATA(vstr_boardnum)[] = "boardnum=%d";
+static const char BCMATTACHDATA(vstr_macaddr)[] = "macaddr=%s";
+static const char BCMATTACHDATA(vstr_usbepnum)[] = "usbepnum=0x%x";
+static const char BCMATTACHDATA(vstr_end)[] = "END\0";
+
+uint8 patch_pair;
+
+/* For dongle HW, accept partial calibration parameters */
+#define BCMDONGLECASE(n)
+
+int
+BCMATTACHFN(srom_parsecis) (osl_t *osh, uint8 *pcis[], uint ciscnt,
+ char **vars, uint *count)
+{
+ char eabuf[32];
+ char *base;
+ varbuf_t b;
+ uint8 *cis, tup, tlen, sromrev = 1;
+ int i, j;
+ bool ag_init = FALSE;
+ uint32 w32;
+ uint funcid;
+ uint cisnum;
+ int32 boardnum;
+ int err;
+ bool standard_cis;
+
+ ASSERT(vars != NULL);
+ ASSERT(count != NULL);
+
+ boardnum = -1;
+
+ base = MALLOC(osh, MAXSZ_NVRAM_VARS);
+ ASSERT(base != NULL);
+ if (!base)
+ return -2;
+
+ varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
+ bzero(base, MAXSZ_NVRAM_VARS);
+ eabuf[0] = '\0';
+ for (cisnum = 0; cisnum < ciscnt; cisnum++) {
+ cis = *pcis++;
+ i = 0;
+ funcid = 0;
+ standard_cis = TRUE;
+ do {
+ if (standard_cis) {
+ tup = cis[i++];
+ if (tup == CISTPL_NULL || tup == CISTPL_END)
+ tlen = 0;
+ else
+ tlen = cis[i++];
+ } else {
+ if (cis[i] == CISTPL_NULL
+ || cis[i] == CISTPL_END) {
+ tlen = 0;
+ tup = cis[i];
+ } else {
+ tlen = cis[i];
+ tup = CISTPL_BRCM_HNBU;
+ }
+ ++i;
+ }
+ if ((i + tlen) >= CIS_SIZE)
+ break;
+
+ switch (tup) {
+ case CISTPL_VERS_1:
+ /* assume the strings are good if the version field checks out */
+ if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) {
+ varbuf_append(&b, vstr_manf,
+ &cis[i + 2]);
+ varbuf_append(&b, vstr_productname,
+ &cis[i + 3 +
+ strlen((char *)
+ &cis[i +
+ 2])]);
+ break;
+ }
+
+ case CISTPL_MANFID:
+ varbuf_append(&b, vstr_manfid,
+ (cis[i + 1] << 8) + cis[i]);
+ varbuf_append(&b, vstr_prodid,
+ (cis[i + 3] << 8) + cis[i + 2]);
+ break;
+
+ case CISTPL_FUNCID:
+ funcid = cis[i];
+ break;
+
+ case CISTPL_FUNCE:
+ switch (funcid) {
+ case CISTPL_FID_SDIO:
+#ifdef BCMSDIO
+ if (cis[i] == 0) {
+ uint8 spd = cis[i + 3];
+ static int base[] = {
+ -1, 10, 12, 13, 15, 20,
+ 25, 30,
+ 35, 40, 45, 50, 55, 60,
+ 70, 80
+ };
+ static int mult[] = {
+ 10, 100, 1000, 10000,
+ -1, -1, -1, -1
+ };
+ ASSERT((mult[spd & 0x7] != -1)
+ &&
+ (base
+ [(spd >> 3) & 0x0f]));
+ varbuf_append(&b,
+ vstr_sdmaxblk[0],
+ (cis[i + 2] << 8)
+ + cis[i + 1]);
+ varbuf_append(&b,
+ vstr_sdmaxspeed,
+ (mult[spd & 0x7] *
+ base[(spd >> 3) &
+ 0x0f]));
+ } else if (cis[i] == 1) {
+ varbuf_append(&b,
+ vstr_sdmaxblk
+ [cisnum],
+ (cis[i + 13] << 8)
+ | cis[i + 12]);
+ }
+#endif /* BCMSDIO */
+ funcid = 0;
+ break;
+ default:
+ /* set macaddr if HNBU_MACADDR not seen yet */
+ if (eabuf[0] == '\0'
+ && cis[i] == LAN_NID
+ && !(ETHER_ISNULLADDR(&cis[i + 2]))
+ && !(ETHER_ISMULTI(&cis[i + 2]))) {
+ ASSERT(cis[i + 1] ==
+ ETHER_ADDR_LEN);
+ bcm_ether_ntoa(
+ (struct ether_addr *)
+ &cis[i + 2],
+ eabuf);
+
+ /* set boardnum if HNBU_BOARDNUM not seen yet */
+ if (boardnum == -1)
+ boardnum =
+ (cis[i + 6] << 8) +
+ cis[i + 7];
+ }
+ break;
+ }
+ break;
+
+ case CISTPL_CFTABLE:
+ varbuf_append(&b, vstr_regwindowsz,
+ (cis[i + 7] << 8) | cis[i + 6]);
+ break;
+
+ case CISTPL_BRCM_HNBU:
+ switch (cis[i]) {
+ case HNBU_SROMREV:
+ sromrev = cis[i + 1];
+ varbuf_append(&b, vstr_sromrev,
+ sromrev);
+ break;
+
+ case HNBU_XTALFREQ:
+ varbuf_append(&b, vstr_xtalfreq,
+ (cis[i + 4] << 24) |
+ (cis[i + 3] << 16) |
+ (cis[i + 2] << 8) |
+ cis[i + 1]);
+ break;
+
+ case HNBU_CHIPID:
+ varbuf_append(&b, vstr_vendid,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ varbuf_append(&b, vstr_devid,
+ (cis[i + 4] << 8) +
+ cis[i + 3]);
+ if (tlen >= 7) {
+ varbuf_append(&b, vstr_chiprev,
+ (cis[i + 6] << 8)
+ + cis[i + 5]);
+ }
+ if (tlen >= 9) {
+ varbuf_append(&b,
+ vstr_subvendid,
+ (cis[i + 8] << 8)
+ + cis[i + 7]);
+ }
+ if (tlen >= 11) {
+ varbuf_append(&b, vstr_subdevid,
+ (cis[i + 10] << 8)
+ + cis[i + 9]);
+ /* subdevid doubles for boardtype */
+ varbuf_append(&b,
+ vstr_boardtype,
+ (cis[i + 10] << 8)
+ + cis[i + 9]);
+ }
+ break;
+
+ case HNBU_BOARDNUM:
+ boardnum =
+ (cis[i + 2] << 8) + cis[i + 1];
+ break;
+
+ case HNBU_PATCH:
+ {
+ char vstr_paddr[16];
+ char vstr_pdata[16];
+
+ /* retrieve the patch pairs
+ * from tlen/6; where 6 is
+ * sizeof(patch addr(2)) +
+ * sizeof(patch data(4)).
+ */
+ patch_pair = tlen / 6;
+
+ for (j = 0; j < patch_pair; j++) {
+ snprintf(vstr_paddr,
+ sizeof
+ (vstr_paddr),
+ "pa%d=0x%%x",
+ j);
+ snprintf(vstr_pdata,
+ sizeof
+ (vstr_pdata),
+ "pd%d=0x%%x",
+ j);
+
+ varbuf_append(&b,
+ vstr_paddr,
+ (cis
+ [i +
+ (j *
+ 6) +
+ 2] << 8)
+ | cis[i +
+ (j *
+ 6)
+ +
+ 1]);
+
+ varbuf_append(&b,
+ vstr_pdata,
+ (cis
+ [i +
+ (j *
+ 6) +
+ 6] <<
+ 24) |
+ (cis
+ [i +
+ (j *
+ 6) +
+ 5] <<
+ 16) |
+ (cis
+ [i +
+ (j *
+ 6) +
+ 4] << 8)
+ | cis[i +
+ (j *
+ 6)
+ +
+ 3]);
+ }
+ }
+ break;
+
+ case HNBU_BOARDREV:
+ if (tlen == 2)
+ varbuf_append(&b, vstr_boardrev,
+ cis[i + 1]);
+ else
+ varbuf_append(&b, vstr_boardrev,
+ (cis[i + 2] << 8)
+ + cis[i + 1]);
+ break;
+
+ case HNBU_BOARDFLAGS:
+ w32 = (cis[i + 2] << 8) + cis[i + 1];
+ if (tlen >= 5)
+ w32 |=
+ ((cis[i + 4] << 24) +
+ (cis[i + 3] << 16));
+ varbuf_append(&b, vstr_boardflags, w32);
+
+ if (tlen >= 7) {
+ w32 =
+ (cis[i + 6] << 8) + cis[i +
+ 5];
+ if (tlen >= 9)
+ w32 |=
+ ((cis[i + 8] << 24)
+ +
+ (cis[i + 7] <<
+ 16));
+ varbuf_append(&b,
+ vstr_boardflags2,
+ w32);
+ }
+ break;
+
+ case HNBU_USBFS:
+ varbuf_append(&b, vstr_usbfs,
+ cis[i + 1]);
+ break;
+
+ case HNBU_BOARDTYPE:
+ varbuf_append(&b, vstr_boardtype,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ break;
+
+ case HNBU_HNBUCIS:
+ /*
+ * what follows is a nonstandard HNBU CIS
+ * that lacks CISTPL_BRCM_HNBU tags
+ *
+ * skip 0xff (end of standard CIS)
+ * after this tuple
+ */
+ tlen++;
+ standard_cis = FALSE;
+ break;
+
+ case HNBU_USBEPNUM:
+ varbuf_append(&b, vstr_usbepnum,
+ (cis[i + 2] << 8) | cis[i
+ +
+ 1]);
+ break;
+
+ case HNBU_AA:
+ varbuf_append(&b, vstr_aa2g,
+ cis[i + 1]);
+ if (tlen >= 3)
+ varbuf_append(&b, vstr_aa5g,
+ cis[i + 2]);
+ break;
+
+ case HNBU_AG:
+ varbuf_append(&b, vstr_ag, 0,
+ cis[i + 1]);
+ if (tlen >= 3)
+ varbuf_append(&b, vstr_ag, 1,
+ cis[i + 2]);
+ if (tlen >= 4)
+ varbuf_append(&b, vstr_ag, 2,
+ cis[i + 3]);
+ if (tlen >= 5)
+ varbuf_append(&b, vstr_ag, 3,
+ cis[i + 4]);
+ ag_init = TRUE;
+ break;
+
+ case HNBU_ANT5G:
+ varbuf_append(&b, vstr_aa5g,
+ cis[i + 1]);
+ varbuf_append(&b, vstr_ag, 1,
+ cis[i + 2]);
+ break;
+
+ case HNBU_CC:
+ ASSERT(sromrev == 1);
+ varbuf_append(&b, vstr_cc, cis[i + 1]);
+ break;
+
+ case HNBU_PAPARMS:
+ switch (tlen) {
+ case 2:
+ ASSERT(sromrev == 1);
+ varbuf_append(&b,
+ vstr_pa0maxpwr,
+ cis[i + 1]);
+ break;
+ case 10:
+ ASSERT(sromrev >= 2);
+ varbuf_append(&b, vstr_opo,
+ cis[i + 9]);
+ /* FALLTHROUGH */
+ case 9:
+ varbuf_append(&b,
+ vstr_pa0maxpwr,
+ cis[i + 8]);
+ /* FALLTHROUGH */
+ BCMDONGLECASE(8)
+ varbuf_append(&b,
+ vstr_pa0itssit,
+ cis[i + 7]);
+ /* FALLTHROUGH */
+ BCMDONGLECASE(7)
+ for (j = 0; j < 3; j++) {
+ varbuf_append(&b,
+ vstr_pa0b
+ [j],
+ (cis
+ [i +
+ (j *
+ 2) +
+ 2] << 8)
+ + cis[i +
+ (j *
+ 2)
+ +
+ 1]);
+ }
+ break;
+ default:
+ ASSERT((tlen == 2)
+ || (tlen == 9)
+ || (tlen == 10));
+ break;
+ }
+ break;
+
+ case HNBU_PAPARMS5G:
+ ASSERT((sromrev == 2)
+ || (sromrev == 3));
+ switch (tlen) {
+ case 23:
+ varbuf_append(&b,
+ vstr_pa1himaxpwr,
+ cis[i + 22]);
+ varbuf_append(&b,
+ vstr_pa1lomaxpwr,
+ cis[i + 21]);
+ varbuf_append(&b,
+ vstr_pa1maxpwr,
+ cis[i + 20]);
+ /* FALLTHROUGH */
+ case 20:
+ varbuf_append(&b,
+ vstr_pa1itssit,
+ cis[i + 19]);
+ /* FALLTHROUGH */
+ case 19:
+ for (j = 0; j < 3; j++) {
+ varbuf_append(&b,
+ vstr_pa1b
+ [j],
+ (cis
+ [i +
+ (j *
+ 2) +
+ 2] << 8)
+ + cis[i +
+ (j *
+ 2)
+ +
+ 1]);
+ }
+ for (j = 3; j < 6; j++) {
+ varbuf_append(&b,
+ vstr_pa1lob
+ [j - 3],
+ (cis
+ [i +
+ (j *
+ 2) +
+ 2] << 8)
+ + cis[i +
+ (j *
+ 2)
+ +
+ 1]);
+ }
+ for (j = 6; j < 9; j++) {
+ varbuf_append(&b,
+ vstr_pa1hib
+ [j - 6],
+ (cis
+ [i +
+ (j *
+ 2) +
+ 2] << 8)
+ + cis[i +
+ (j *
+ 2)
+ +
+ 1]);
+ }
+ break;
+ default:
+ ASSERT((tlen == 19) ||
+ (tlen == 20)
+ || (tlen == 23));
+ break;
+ }
+ break;
+
+ case HNBU_OEM:
+ ASSERT(sromrev == 1);
+ varbuf_append(&b, vstr_oem,
+ cis[i + 1], cis[i + 2],
+ cis[i + 3], cis[i + 4],
+ cis[i + 5], cis[i + 6],
+ cis[i + 7], cis[i + 8]);
+ break;
+
+ case HNBU_LEDS:
+ for (j = 1; j <= 4; j++) {
+ if (cis[i + j] != 0xff) {
+ varbuf_append(&b,
+ vstr_ledbh,
+ j - 1,
+ cis[i +
+ j]);
+ }
+ }
+ break;
+
+ case HNBU_CCODE:
+ ASSERT(sromrev > 1);
+ if ((cis[i + 1] == 0)
+ || (cis[i + 2] == 0))
+ varbuf_append(&b, vstr_noccode);
+ else
+ varbuf_append(&b, vstr_ccode,
+ cis[i + 1],
+ cis[i + 2]);
+ varbuf_append(&b, vstr_cctl,
+ cis[i + 3]);
+ break;
+
+ case HNBU_CCKPO:
+ ASSERT(sromrev > 2);
+ varbuf_append(&b, vstr_cckpo,
+ (cis[i + 2] << 8) | cis[i
+ +
+ 1]);
+ break;
+
+ case HNBU_OFDMPO:
+ ASSERT(sromrev > 2);
+ varbuf_append(&b, vstr_ofdmpo,
+ (cis[i + 4] << 24) |
+ (cis[i + 3] << 16) |
+ (cis[i + 2] << 8) |
+ cis[i + 1]);
+ break;
+
+ case HNBU_WPS:
+ varbuf_append(&b, vstr_wpsgpio,
+ cis[i + 1]);
+ if (tlen >= 3)
+ varbuf_append(&b, vstr_wpsled,
+ cis[i + 2]);
+ break;
+
+ case HNBU_RSSISMBXA2G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_rssismf2g,
+ cis[i + 1] & 0xf);
+ varbuf_append(&b, vstr_rssismc2g,
+ (cis[i + 1] >> 4) & 0xf);
+ varbuf_append(&b, vstr_rssisav2g,
+ cis[i + 2] & 0x7);
+ varbuf_append(&b, vstr_bxa2g,
+ (cis[i + 2] >> 3) & 0x3);
+ break;
+
+ case HNBU_RSSISMBXA5G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_rssismf5g,
+ cis[i + 1] & 0xf);
+ varbuf_append(&b, vstr_rssismc5g,
+ (cis[i + 1] >> 4) & 0xf);
+ varbuf_append(&b, vstr_rssisav5g,
+ cis[i + 2] & 0x7);
+ varbuf_append(&b, vstr_bxa5g,
+ (cis[i + 2] >> 3) & 0x3);
+ break;
+
+ case HNBU_TRI2G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_tri2g,
+ cis[i + 1]);
+ break;
+
+ case HNBU_TRI5G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_tri5gl,
+ cis[i + 1]);
+ varbuf_append(&b, vstr_tri5g,
+ cis[i + 2]);
+ varbuf_append(&b, vstr_tri5gh,
+ cis[i + 3]);
+ break;
+
+ case HNBU_RXPO2G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_rxpo2g,
+ cis[i + 1]);
+ break;
+
+ case HNBU_RXPO5G:
+ ASSERT(sromrev == 3);
+ varbuf_append(&b, vstr_rxpo5g,
+ cis[i + 1]);
+ break;
+
+ case HNBU_MACADDR:
+ if (!(ETHER_ISNULLADDR(&cis[i + 1])) &&
+ !(ETHER_ISMULTI(&cis[i + 1]))) {
+ bcm_ether_ntoa(
+ (struct ether_addr *)
+ &cis[i + 1],
+ eabuf);
+
+ /* set boardnum if HNBU_BOARDNUM not seen yet */
+ if (boardnum == -1)
+ boardnum =
+ (cis[i + 5] << 8) +
+ cis[i + 6];
+ }
+ break;
+
+ case HNBU_LEDDC:
+ /* CIS leddc only has 16bits, convert it to 32bits */
+ w32 = ((cis[i + 2] << 24) | /* oncount */
+ (cis[i + 1] << 8)); /* offcount */
+ varbuf_append(&b, vstr_leddc, w32);
+ break;
+
+ case HNBU_CHAINSWITCH:
+ varbuf_append(&b, vstr_txchain,
+ cis[i + 1]);
+ varbuf_append(&b, vstr_rxchain,
+ cis[i + 2]);
+ varbuf_append(&b, vstr_antswitch,
+ (cis[i + 4] << 8) +
+ cis[i + 3]);
+ break;
+
+ case HNBU_REGREV:
+ varbuf_append(&b, vstr_regrev,
+ cis[i + 1]);
+ break;
+
+ case HNBU_FEM:{
+ uint16 fem =
+ (cis[i + 2] << 8) + cis[i +
+ 1];
+ varbuf_append(&b,
+ vstr_antswctl2g,
+ (fem &
+ SROM8_FEM_ANTSWLUT_MASK)
+ >>
+ SROM8_FEM_ANTSWLUT_SHIFT);
+ varbuf_append(&b, vstr_triso2g,
+ (fem &
+ SROM8_FEM_TR_ISO_MASK)
+ >>
+ SROM8_FEM_TR_ISO_SHIFT);
+ varbuf_append(&b,
+ vstr_pdetrange2g,
+ (fem &
+ SROM8_FEM_PDET_RANGE_MASK)
+ >>
+ SROM8_FEM_PDET_RANGE_SHIFT);
+ varbuf_append(&b,
+ vstr_extpagain2g,
+ (fem &
+ SROM8_FEM_EXTPA_GAIN_MASK)
+ >>
+ SROM8_FEM_EXTPA_GAIN_SHIFT);
+ varbuf_append(&b,
+ vstr_tssipos2g,
+ (fem &
+ SROM8_FEM_TSSIPOS_MASK)
+ >>
+ SROM8_FEM_TSSIPOS_SHIFT);
+ if (tlen < 5)
+ break;
+
+ fem =
+ (cis[i + 4] << 8) + cis[i +
+ 3];
+ varbuf_append(&b,
+ vstr_antswctl5g,
+ (fem &
+ SROM8_FEM_ANTSWLUT_MASK)
+ >>
+ SROM8_FEM_ANTSWLUT_SHIFT);
+ varbuf_append(&b, vstr_triso5g,
+ (fem &
+ SROM8_FEM_TR_ISO_MASK)
+ >>
+ SROM8_FEM_TR_ISO_SHIFT);
+ varbuf_append(&b,
+ vstr_pdetrange5g,
+ (fem &
+ SROM8_FEM_PDET_RANGE_MASK)
+ >>
+ SROM8_FEM_PDET_RANGE_SHIFT);
+ varbuf_append(&b,
+ vstr_extpagain5g,
+ (fem &
+ SROM8_FEM_EXTPA_GAIN_MASK)
+ >>
+ SROM8_FEM_EXTPA_GAIN_SHIFT);
+ varbuf_append(&b,
+ vstr_tssipos5g,
+ (fem &
+ SROM8_FEM_TSSIPOS_MASK)
+ >>
+ SROM8_FEM_TSSIPOS_SHIFT);
+ break;
+ }
+
+ case HNBU_PAPARMS_C0:
+ varbuf_append(&b, vstr_maxp2ga0,
+ cis[i + 1]);
+ varbuf_append(&b, vstr_itt2ga0,
+ cis[i + 2]);
+ varbuf_append(&b, vstr_pa, 2, 0, 0,
+ (cis[i + 4] << 8) +
+ cis[i + 3]);
+ varbuf_append(&b, vstr_pa, 2, 1, 0,
+ (cis[i + 6] << 8) +
+ cis[i + 5]);
+ varbuf_append(&b, vstr_pa, 2, 2, 0,
+ (cis[i + 8] << 8) +
+ cis[i + 7]);
+ if (tlen < 31)
+ break;
+
+ varbuf_append(&b, vstr_maxp5ga0,
+ cis[i + 9]);
+ varbuf_append(&b, vstr_itt5ga0,
+ cis[i + 10]);
+ varbuf_append(&b, vstr_maxp5gha0,
+ cis[i + 11]);
+ varbuf_append(&b, vstr_maxp5gla0,
+ cis[i + 12]);
+ varbuf_append(&b, vstr_pa, 5, 0, 0,
+ (cis[i + 14] << 8) +
+ cis[i + 13]);
+ varbuf_append(&b, vstr_pa, 5, 1, 0,
+ (cis[i + 16] << 8) +
+ cis[i + 15]);
+ varbuf_append(&b, vstr_pa, 5, 2, 0,
+ (cis[i + 18] << 8) +
+ cis[i + 17]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 0,
+ 0,
+ (cis[i + 20] << 8) +
+ cis[i + 19]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 1,
+ 0,
+ (cis[i + 22] << 8) +
+ cis[i + 21]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 2,
+ 0,
+ (cis[i + 24] << 8) +
+ cis[i + 23]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 0,
+ 0,
+ (cis[i + 26] << 8) +
+ cis[i + 25]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 1,
+ 0,
+ (cis[i + 28] << 8) +
+ cis[i + 27]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 2,
+ 0,
+ (cis[i + 30] << 8) +
+ cis[i + 29]);
+ break;
+
+ case HNBU_PAPARMS_C1:
+ varbuf_append(&b, vstr_maxp2ga1,
+ cis[i + 1]);
+ varbuf_append(&b, vstr_itt2ga1,
+ cis[i + 2]);
+ varbuf_append(&b, vstr_pa, 2, 0, 1,
+ (cis[i + 4] << 8) +
+ cis[i + 3]);
+ varbuf_append(&b, vstr_pa, 2, 1, 1,
+ (cis[i + 6] << 8) +
+ cis[i + 5]);
+ varbuf_append(&b, vstr_pa, 2, 2, 1,
+ (cis[i + 8] << 8) +
+ cis[i + 7]);
+ if (tlen < 31)
+ break;
+
+ varbuf_append(&b, vstr_maxp5ga1,
+ cis[i + 9]);
+ varbuf_append(&b, vstr_itt5ga1,
+ cis[i + 10]);
+ varbuf_append(&b, vstr_maxp5gha1,
+ cis[i + 11]);
+ varbuf_append(&b, vstr_maxp5gla1,
+ cis[i + 12]);
+ varbuf_append(&b, vstr_pa, 5, 0, 1,
+ (cis[i + 14] << 8) +
+ cis[i + 13]);
+ varbuf_append(&b, vstr_pa, 5, 1, 1,
+ (cis[i + 16] << 8) +
+ cis[i + 15]);
+ varbuf_append(&b, vstr_pa, 5, 2, 1,
+ (cis[i + 18] << 8) +
+ cis[i + 17]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 0,
+ 1,
+ (cis[i + 20] << 8) +
+ cis[i + 19]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 1,
+ 1,
+ (cis[i + 22] << 8) +
+ cis[i + 21]);
+ varbuf_append(&b, vstr_pahl, 5, 'l', 2,
+ 1,
+ (cis[i + 24] << 8) +
+ cis[i + 23]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 0,
+ 1,
+ (cis[i + 26] << 8) +
+ cis[i + 25]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 1,
+ 1,
+ (cis[i + 28] << 8) +
+ cis[i + 27]);
+ varbuf_append(&b, vstr_pahl, 5, 'h', 2,
+ 1,
+ (cis[i + 30] << 8) +
+ cis[i + 29]);
+ break;
+
+ case HNBU_PO_CCKOFDM:
+ varbuf_append(&b, vstr_cck2gpo,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ varbuf_append(&b, vstr_ofdm2gpo,
+ (cis[i + 6] << 24) +
+ (cis[i + 5] << 16) +
+ (cis[i + 4] << 8) +
+ cis[i + 3]);
+ if (tlen < 19)
+ break;
+
+ varbuf_append(&b, vstr_ofdm5gpo,
+ (cis[i + 10] << 24) +
+ (cis[i + 9] << 16) +
+ (cis[i + 8] << 8) +
+ cis[i + 7]);
+ varbuf_append(&b, vstr_ofdm5glpo,
+ (cis[i + 14] << 24) +
+ (cis[i + 13] << 16) +
+ (cis[i + 12] << 8) +
+ cis[i + 11]);
+ varbuf_append(&b, vstr_ofdm5ghpo,
+ (cis[i + 18] << 24) +
+ (cis[i + 17] << 16) +
+ (cis[i + 16] << 8) +
+ cis[i + 15]);
+ break;
+
+ case HNBU_PO_MCS2G:
+ for (j = 0; j <= (tlen / 2); j++) {
+ varbuf_append(&b, vstr_mcspo, 2,
+ j,
+ (cis
+ [i + 2 +
+ 2 * j] << 8) +
+ cis[i + 1 +
+ 2 * j]);
+ }
+ break;
+
+ case HNBU_PO_MCS5GM:
+ for (j = 0; j <= (tlen / 2); j++) {
+ varbuf_append(&b, vstr_mcspo, 5,
+ j,
+ (cis
+ [i + 2 +
+ 2 * j] << 8) +
+ cis[i + 1 +
+ 2 * j]);
+ }
+ break;
+
+ case HNBU_PO_MCS5GLH:
+ for (j = 0; j <= (tlen / 4); j++) {
+ varbuf_append(&b, vstr_mcspohl,
+ 5, 'l', j,
+ (cis
+ [i + 2 +
+ 2 * j] << 8) +
+ cis[i + 1 +
+ 2 * j]);
+ }
+
+ for (j = 0; j <= (tlen / 4); j++) {
+ varbuf_append(&b, vstr_mcspohl,
+ 5, 'h', j,
+ (cis
+ [i +
+ ((tlen / 2) +
+ 2) +
+ 2 * j] << 8) +
+ cis[i +
+ ((tlen / 2) +
+ 1) + 2 * j]);
+ }
+
+ break;
+
+ case HNBU_PO_CDD:
+ varbuf_append(&b, vstr_cddpo,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ break;
+
+ case HNBU_PO_STBC:
+ varbuf_append(&b, vstr_stbcpo,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ break;
+
+ case HNBU_PO_40M:
+ varbuf_append(&b, vstr_bw40po,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ break;
+
+ case HNBU_PO_40MDUP:
+ varbuf_append(&b, vstr_bwduppo,
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ break;
+
+ case HNBU_OFDMPO5G:
+ varbuf_append(&b, vstr_ofdm5gpo,
+ (cis[i + 4] << 24) +
+ (cis[i + 3] << 16) +
+ (cis[i + 2] << 8) +
+ cis[i + 1]);
+ varbuf_append(&b, vstr_ofdm5glpo,
+ (cis[i + 8] << 24) +
+ (cis[i + 7] << 16) +
+ (cis[i + 6] << 8) +
+ cis[i + 5]);
+ varbuf_append(&b, vstr_ofdm5ghpo,
+ (cis[i + 12] << 24) +
+ (cis[i + 11] << 16) +
+ (cis[i + 10] << 8) +
+ cis[i + 9]);
+ break;
+
+ case HNBU_CUSTOM1:
+ varbuf_append(&b, vstr_custom, 1,
+ ((cis[i + 4] << 24) +
+ (cis[i + 3] << 16) +
+ (cis[i + 2] << 8) +
+ cis[i + 1]));
+ break;
+
+#if defined(BCMSDIO)
+ case HNBU_SROM3SWRGN:
+ if (tlen >= 73) {
+ uint16 srom[35];
+ uint8 srev = cis[i + 1 + 70];
+ ASSERT(srev == 3);
+ /* make tuple value 16-bit aligned and parse it */
+ bcopy(&cis[i + 1], srom,
+ sizeof(srom));
+ _initvars_srom_pci(srev, srom,
+ SROM3_SWRGN_OFF,
+ &b);
+ /* 2.4G antenna gain is included in SROM */
+ ag_init = TRUE;
+ /* Ethernet MAC address is included in SROM */
+ eabuf[0] = 0;
+ boardnum = -1;
+ }
+ /* create extra variables */
+ if (tlen >= 75)
+ varbuf_append(&b, vstr_vendid,
+ (cis[i + 1 + 73]
+ << 8) + cis[i +
+ 1 +
+ 72]);
+ if (tlen >= 77)
+ varbuf_append(&b, vstr_devid,
+ (cis[i + 1 + 75]
+ << 8) + cis[i +
+ 1 +
+ 74]);
+ if (tlen >= 79)
+ varbuf_append(&b, vstr_xtalfreq,
+ (cis[i + 1 + 77]
+ << 8) + cis[i +
+ 1 +
+ 76]);
+ break;
+#endif /* defined(BCMSDIO) */
+
+ case HNBU_CCKFILTTYPE:
+ varbuf_append(&b, vstr_cckdigfilttype,
+ (cis[i + 1]));
+ break;
+ }
+
+ break;
+ }
+ i += tlen;
+ } while (tup != CISTPL_END);
+ }
+
+ if (boardnum != -1) {
+ varbuf_append(&b, vstr_boardnum, boardnum);
+ }
+
+ if (eabuf[0]) {
+ varbuf_append(&b, vstr_macaddr, eabuf);
+ }
+
+ /* if there is no antenna gain field, set default */
+ if (getvar(NULL, "ag0") == NULL && ag_init == FALSE) {
+ varbuf_append(&b, vstr_ag, 0, 0xff);
+ }
+
+ /* final nullbyte terminator */
+ ASSERT(b.size >= 1);
+ *b.buf++ = '\0';
+
+ ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS);
+ err = initvars_table(osh, base, b.buf, vars, count);
+
+ MFREE(osh, base, MAXSZ_NVRAM_VARS);
+ return err;
+}
+
+/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
+ * not in the bus cores.
+ */
+static uint16
+srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, uint32 cmd, uint wordoff,
+ uint16 data)
+{
+ chipcregs_t *cc = (chipcregs_t *) ccregs;
+ uint wait_cnt = 1000;
+
+ if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
+ W_REG(osh, &cc->sromaddress, wordoff * 2);
+ if (cmd == SRC_OP_WRITE)
+ W_REG(osh, &cc->sromdata, data);
+ }
+
+ W_REG(osh, &cc->sromcontrol, SRC_START | cmd);
+
+ while (wait_cnt--) {
+ if ((R_REG(osh, &cc->sromcontrol) & SRC_BUSY) == 0)
+ break;
+ }
+
+ if (!wait_cnt) {
+ BS_ERROR(("%s: Command 0x%x timed out\n", __func__, cmd));
+ return 0xffff;
+ }
+ if (cmd == SRC_OP_READ)
+ return (uint16) R_REG(osh, &cc->sromdata);
+ else
+ return 0xffff;
+}
+
+/*
+ * Read in and validate sprom.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+sprom_read_pci(osl_t *osh, si_t *sih, uint16 *sprom, uint wordoff,
+ uint16 *buf, uint nwords, bool check_crc)
+{
+ int err = 0;
+ uint i;
+ void *ccregs = NULL;
+
+ /* read the sprom */
+ for (i = 0; i < nwords; i++) {
+
+ if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
+ /* use indirect since direct is too slow on QT */
+ if ((sih->cccaps & CC_CAP_SROM) == 0)
+ return 1;
+
+ ccregs = (void *)((uint8 *) sprom - CC_SROM_OTP);
+ buf[i] =
+ srom_cc_cmd(sih, osh, ccregs, SRC_OP_READ,
+ wordoff + i, 0);
+
+ } else {
+ if (ISSIM_ENAB(sih))
+ buf[i] = R_REG(osh, &sprom[wordoff + i]);
+
+ buf[i] = R_REG(osh, &sprom[wordoff + i]);
+ }
+
+ }
+
+ /* bypass crc checking for simulation to allow srom hack */
+ if (ISSIM_ENAB(sih))
+ return err;
+
+ if (check_crc) {
+
+ if (buf[0] == 0xffff) {
+ /* The hardware thinks that an srom that starts with 0xffff
+ * is blank, regardless of the rest of the content, so declare
+ * it bad.
+ */
+ BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n",
+ __func__, buf[0]));
+ return 1;
+ }
+
+ /* fixup the endianness so crc8 will pass */
+ htol16_buf(buf, nwords * 2);
+ if (hndcrc8((uint8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
+ CRC8_GOOD_VALUE) {
+ /* DBG only pci always read srom4 first, then srom8/9 */
+ /* BS_ERROR(("%s: bad crc\n", __func__)); */
+ err = 1;
+ }
+ /* now correct the endianness of the byte array */
+ ltoh16_buf(buf, nwords * 2);
+ }
+ return err;
+}
+
+#if defined(BCMNVRAMR)
+static int otp_read_pci(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz)
+{
+ uint8 *otp;
+ uint sz = OTP_SZ_MAX / 2; /* size in words */
+ int err = 0;
+
+ ASSERT(bufsz <= OTP_SZ_MAX);
+
+ otp = MALLOC(osh, OTP_SZ_MAX);
+ if (otp == NULL) {
+ return BCME_ERROR;
+ }
+
+ bzero(otp, OTP_SZ_MAX);
+
+ err = otp_read_region(sih, OTP_HW_RGN, (uint16 *) otp, &sz);
+
+ bcopy(otp, buf, bufsz);
+
+ if (otp)
+ MFREE(osh, otp, OTP_SZ_MAX);
+
+ /* Check CRC */
+ if (buf[0] == 0xffff) {
+ /* The hardware thinks that an srom that starts with 0xffff
+ * is blank, regardless of the rest of the content, so declare
+ * it bad.
+ */
+ BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __func__,
+ buf[0]));
+ return 1;
+ }
+
+ /* fixup the endianness so crc8 will pass */
+ htol16_buf(buf, bufsz);
+ if (hndcrc8((uint8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
+ CRC8_GOOD_VALUE) {
+ BS_ERROR(("%s: bad crc\n", __func__));
+ err = 1;
+ }
+ /* now correct the endianness of the byte array */
+ ltoh16_buf(buf, bufsz);
+
+ return err;
+}
+#endif /* defined(BCMNVRAMR) */
+/*
+* Create variable table from memory.
+* Return 0 on success, nonzero on error.
+*/
+static int
+BCMATTACHFN(initvars_table) (osl_t *osh, char *start, char *end, char **vars,
+ uint *count) {
+ int c = (int)(end - start);
+
+ /* do it only when there is more than just the null string */
+ if (c > 1) {
+ char *vp = MALLOC(osh, c);
+ ASSERT(vp != NULL);
+ if (!vp)
+ return BCME_NOMEM;
+ bcopy(start, vp, c);
+ *vars = vp;
+ *count = c;
+ } else {
+ *vars = NULL;
+ *count = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Find variables with <devpath> from flash. 'base' points to the beginning
+ * of the table upon enter and to the end of the table upon exit when success.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+BCMATTACHFN(initvars_flash) (si_t *sih, osl_t *osh, char **base, uint len)
+{
+ char *vp = *base;
+ char *flash;
+ int err;
+ char *s;
+ uint l, dl, copy_len;
+ char devpath[SI_DEVPATH_BUFSZ];
+
+ /* allocate memory and read in flash */
+ flash = MALLOC(osh, NVRAM_SPACE);
+ if (!flash)
+ return BCME_NOMEM;
+ err = nvram_getall(flash, NVRAM_SPACE);
+ if (err)
+ goto exit;
+
+ si_devpath(sih, devpath, sizeof(devpath));
+
+ /* grab vars with the <devpath> prefix in name */
+ dl = strlen(devpath);
+ for (s = flash; s && *s; s += l + 1) {
+ l = strlen(s);
+
+ /* skip non-matching variable */
+ if (strncmp(s, devpath, dl))
+ continue;
+
+ /* is there enough room to copy? */
+ copy_len = l - dl + 1;
+ if (len < copy_len) {
+ err = BCME_BUFTOOSHORT;
+ goto exit;
+ }
+
+ /* no prefix, just the name=value */
+ strncpy(vp, &s[dl], copy_len);
+ vp += copy_len;
+ len -= copy_len;
+ }
+
+ /* add null string as terminator */
+ if (len < 1) {
+ err = BCME_BUFTOOSHORT;
+ goto exit;
+ }
+ *vp++ = '\0';
+
+ *base = vp;
+
+ exit: MFREE(osh, flash, NVRAM_SPACE);
+ return err;
+}
+
+/*
+ * Initialize nonvolatile variable table from flash.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+BCMATTACHFN(initvars_flash_si) (si_t *sih, char **vars, uint *count)
+{
+ osl_t *osh = si_osh(sih);
+ char *vp, *base;
+ int err;
+
+ ASSERT(vars != NULL);
+ ASSERT(count != NULL);
+
+ base = vp = MALLOC(osh, MAXSZ_NVRAM_VARS);
+ ASSERT(vp != NULL);
+ if (!vp)
+ return BCME_NOMEM;
+
+ err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS);
+ if (err == 0)
+ err = initvars_table(osh, base, vp, vars, count);
+
+ MFREE(osh, base, MAXSZ_NVRAM_VARS);
+
+ return err;
+}
+
+/* Parse SROM and create name=value pairs. 'srom' points to
+ * the SROM word array. 'off' specifies the offset of the
+ * first word 'srom' points to, which should be either 0 or
+ * SROM3_SWRG_OFF (full SROM or software region).
+ */
+
+static uint mask_shift(uint16 mask)
+{
+ uint i;
+ for (i = 0; i < (sizeof(mask) << 3); i++) {
+ if (mask & (1 << i))
+ return i;
+ }
+ ASSERT(mask);
+ return 0;
+}
+
+static uint mask_width(uint16 mask)
+{
+ int i;
+ for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
+ if (mask & (1 << i))
+ return (uint) (i - mask_shift(mask) + 1);
+ }
+ ASSERT(mask);
+ return 0;
+}
+
+#if defined(BCMDBG)
+static bool mask_valid(uint16 mask)
+{
+ uint shift = mask_shift(mask);
+ uint width = mask_width(mask);
+ return mask == ((~0 << shift) & ~(~0 << (shift + width)));
+}
+#endif /* BCMDBG */
+
+static void
+BCMATTACHFN(_initvars_srom_pci) (uint8 sromrev, uint16 *srom, uint off,
+ varbuf_t *b) {
+ uint16 w;
+ uint32 val;
+ const sromvar_t *srv;
+ uint width;
+ uint flags;
+ uint32 sr = (1 << sromrev);
+
+ varbuf_append(b, "sromrev=%d", sromrev);
+
+ for (srv = pci_sromvars; srv->name != NULL; srv++) {
+ const char *name;
+
+ if ((srv->revmask & sr) == 0)
+ continue;
+
+ if (srv->off < off)
+ continue;
+
+ flags = srv->flags;
+ name = srv->name;
+
+ /* This entry is for mfgc only. Don't generate param for it, */
+ if (flags & SRFL_NOVAR)
+ continue;
+
+ if (flags & SRFL_ETHADDR) {
+ char eabuf[ETHER_ADDR_STR_LEN];
+ struct ether_addr ea;
+
+ ea.octet[0] = (srom[srv->off - off] >> 8) & 0xff;
+ ea.octet[1] = srom[srv->off - off] & 0xff;
+ ea.octet[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
+ ea.octet[3] = srom[srv->off + 1 - off] & 0xff;
+ ea.octet[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
+ ea.octet[5] = srom[srv->off + 2 - off] & 0xff;
+ bcm_ether_ntoa(&ea, eabuf);
+
+ varbuf_append(b, "%s=%s", name, eabuf);
+ } else {
+ ASSERT(mask_valid(srv->mask));
+ ASSERT(mask_width(srv->mask));
+
+ w = srom[srv->off - off];
+ val = (w & srv->mask) >> mask_shift(srv->mask);
+ width = mask_width(srv->mask);
+
+ while (srv->flags & SRFL_MORE) {
+ srv++;
+ ASSERT(srv->name != NULL);
+
+ if (srv->off == 0 || srv->off < off)
+ continue;
+
+ ASSERT(mask_valid(srv->mask));
+ ASSERT(mask_width(srv->mask));
+
+ w = srom[srv->off - off];
+ val +=
+ ((w & srv->mask) >> mask_shift(srv->
+ mask)) <<
+ width;
+ width += mask_width(srv->mask);
+ }
+
+ if ((flags & SRFL_NOFFS)
+ && ((int)val == (1 << width) - 1))
+ continue;
+
+ if (flags & SRFL_CCODE) {
+ if (val == 0)
+ varbuf_append(b, "ccode=");
+ else
+ varbuf_append(b, "ccode=%c%c",
+ (val >> 8), (val & 0xff));
+ }
+ /* LED Powersave duty cycle has to be scaled:
+ *(oncount >> 24) (offcount >> 8)
+ */
+ else if (flags & SRFL_LEDDC) {
+ uint32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */
+ (((val & 0xff)) << 8); /* offcount */
+ varbuf_append(b, "leddc=%d", w32);
+ } else if (flags & SRFL_PRHEX)
+ varbuf_append(b, "%s=0x%x", name, val);
+ else if ((flags & SRFL_PRSIGN)
+ && (val & (1 << (width - 1))))
+ varbuf_append(b, "%s=%d", name,
+ (int)(val | (~0 << width)));
+ else
+ varbuf_append(b, "%s=%u", name, val);
+ }
+ }
+
+ if (sromrev >= 4) {
+ /* Do per-path variables */
+ uint p, pb, psz;
+
+ if (sromrev >= 8) {
+ pb = SROM8_PATH0;
+ psz = SROM8_PATH1 - SROM8_PATH0;
+ } else {
+ pb = SROM4_PATH0;
+ psz = SROM4_PATH1 - SROM4_PATH0;
+ }
+
+ for (p = 0; p < MAX_PATH_SROM; p++) {
+ for (srv = perpath_pci_sromvars; srv->name != NULL;
+ srv++) {
+ if ((srv->revmask & sr) == 0)
+ continue;
+
+ if (pb + srv->off < off)
+ continue;
+
+ /* This entry is for mfgc only. Don't generate param for it, */
+ if (srv->flags & SRFL_NOVAR)
+ continue;
+
+ w = srom[pb + srv->off - off];
+
+ ASSERT(mask_valid(srv->mask));
+ val = (w & srv->mask) >> mask_shift(srv->mask);
+ width = mask_width(srv->mask);
+
+ /* Cheating: no per-path var is more than 1 word */
+
+ if ((srv->flags & SRFL_NOFFS)
+ && ((int)val == (1 << width) - 1))
+ continue;
+
+ if (srv->flags & SRFL_PRHEX)
+ varbuf_append(b, "%s%d=0x%x", srv->name,
+ p, val);
+ else
+ varbuf_append(b, "%s%d=%d", srv->name,
+ p, val);
+ }
+ pb += psz;
+ }
+ }
+}
+
+/*
+ * Initialize nonvolatile variable table from sprom.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+BCMATTACHFN(initvars_srom_pci) (si_t *sih, void *curmap, char **vars,
+ uint *count) {
+ uint16 *srom, *sromwindow;
+ uint8 sromrev = 0;
+ uint32 sr;
+ varbuf_t b;
+ char *vp, *base = NULL;
+ osl_t *osh = si_osh(sih);
+ bool flash = FALSE;
+ int err = 0;
+
+ /*
+ * Apply CRC over SROM content regardless SROM is present or not,
+ * and use variable <devpath>sromrev's existance in flash to decide
+ * if we should return an error when CRC fails or read SROM variables
+ * from flash.
+ */
+ srom = MALLOC(osh, SROM_MAX);
+ ASSERT(srom != NULL);
+ if (!srom)
+ return -2;
+
+ sromwindow = (uint16 *) SROM_OFFSET(sih);
+ if (si_is_sprom_available(sih)) {
+ err =
+ sprom_read_pci(osh, sih, sromwindow, 0, srom, SROM_WORDS,
+ TRUE);
+
+ if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
+ (((sih->buscoretype == PCIE_CORE_ID)
+ && (sih->buscorerev >= 6))
+ || ((sih->buscoretype == PCI_CORE_ID)
+ && (sih->buscorerev >= 0xe)))) {
+ /* sromrev >= 4, read more */
+ err =
+ sprom_read_pci(osh, sih, sromwindow, 0, srom,
+ SROM4_WORDS, TRUE);
+ sromrev = srom[SROM4_CRCREV] & 0xff;
+ if (err)
+ BS_ERROR(("%s: srom %d, bad crc\n", __func__,
+ sromrev));
+
+ } else if (err == 0) {
+ /* srom is good and is rev < 4 */
+ /* top word of sprom contains version and crc8 */
+ sromrev = srom[SROM_CRCREV] & 0xff;
+ /* bcm4401 sroms misprogrammed */
+ if (sromrev == 0x10)
+ sromrev = 1;
+ }
+ }
+#if defined(BCMNVRAMR)
+ /* Use OTP if SPROM not available */
+ else if ((err = otp_read_pci(osh, sih, srom, SROM_MAX)) == 0) {
+ /* OTP only contain SROM rev8/rev9 for now */
+ sromrev = srom[SROM4_CRCREV] & 0xff;
+ }
+#endif
+ else {
+ err = 1;
+ BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
+ }
+
+ /* We want internal/wltest driver to come up with default sromvars so we can
+ * program a blank SPROM/OTP.
+ */
+ if (err) {
+ char *value;
+ uint32 val;
+ val = 0;
+
+ value = si_getdevpathvar(sih, "sromrev");
+ if (value) {
+ sromrev = (uint8) bcm_strtoul(value, NULL, 0);
+ flash = TRUE;
+ goto varscont;
+ }
+
+ BS_ERROR(("%s, SROM CRC Error\n", __func__));
+
+ value = si_getnvramflvar(sih, "sromrev");
+ if (value) {
+ err = 0;
+ goto errout;
+ }
+
+ {
+ err = -1;
+ goto errout;
+ }
+ }
+
+ varscont:
+ /* Bitmask for the sromrev */
+ sr = 1 << sromrev;
+
+ /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
+ if ((sr & 0x33e) == 0) {
+ err = -2;
+ goto errout;
+ }
+
+ ASSERT(vars != NULL);
+ ASSERT(count != NULL);
+
+ base = vp = MALLOC(osh, MAXSZ_NVRAM_VARS);
+ ASSERT(vp != NULL);
+ if (!vp) {
+ err = -2;
+ goto errout;
+ }
+
+ /* read variables from flash */
+ if (flash) {
+ err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS);
+ if (err)
+ goto errout;
+ goto varsdone;
+ }
+
+ varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
+
+ /* parse SROM into name=value pairs. */
+ _initvars_srom_pci(sromrev, srom, 0, &b);
+
+ /* final nullbyte terminator */
+ ASSERT(b.size >= 1);
+ vp = b.buf;
+ *vp++ = '\0';
+
+ ASSERT((vp - base) <= MAXSZ_NVRAM_VARS);
+
+ varsdone:
+ err = initvars_table(osh, base, vp, vars, count);
+
+ errout:
+ if (base)
+ MFREE(osh, base, MAXSZ_NVRAM_VARS);
+
+ MFREE(osh, srom, SROM_MAX);
+ return err;
+}
+
+#ifdef BCMSDIO
+/*
+ * Read the SDIO cis and call parsecis to initialize the vars.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+BCMATTACHFN(initvars_cis_sdio) (osl_t *osh, char **vars, uint *count)
+{
+ uint8 *cis[SBSDIO_NUM_FUNCTION + 1];
+ uint fn, numfn;
+ int rc = 0;
+
+ numfn = bcmsdh_query_iofnum(NULL);
+ ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
+
+ for (fn = 0; fn <= numfn; fn++) {
+ cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT)
+ if (cis[fn] == NULL) {
+ rc = -1;
+ break;
+ }
+
+ bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+
+ if (bcmsdh_cis_read(NULL, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT) !=
+ 0) {
+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+ rc = -2;
+ break;
+ }
+ }
+
+ if (!rc)
+ rc = srom_parsecis(osh, cis, fn, vars, count);
+
+ while (fn-- > 0)
+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+
+ return rc;
+}
+
+/* set SDIO sprom command register */
+static int BCMATTACHFN(sprom_cmd_sdio) (osl_t *osh, uint8 cmd)
+{
+ uint8 status = 0;
+ uint wait_cnt = 1000;
+
+ /* write sprom command register */
+ bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, cmd, NULL);
+
+ /* wait status */
+ while (wait_cnt--) {
+ status =
+ bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, NULL);
+ if (status & SBSDIO_SPROM_DONE)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* read a word from the SDIO srom */
+static int sprom_read_sdio(osl_t *osh, uint16 addr, uint16 *data)
+{
+ uint8 addr_l, addr_h, data_l, data_h;
+
+ addr_l = (uint8) ((addr * 2) & 0xff);
+ addr_h = (uint8) (((addr * 2) >> 8) & 0xff);
+
+ /* set address */
+ bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h,
+ NULL);
+ bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l,
+ NULL);
+
+ /* do read */
+ if (sprom_cmd_sdio(osh, SBSDIO_SPROM_READ))
+ return 1;
+
+ /* read data */
+ data_h =
+ bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, NULL);
+ data_l =
+ bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, NULL);
+
+ *data = (data_h << 8) | data_l;
+ return 0;
+}
+#endif /* BCMSDIO */
+
+static int
+BCMATTACHFN(initvars_srom_si) (si_t *sih, osl_t *osh, void *curmap,
+ char **vars, uint *varsz) {
+ /* Search flash nvram section for srom variables */
+ return initvars_flash_si(sih, vars, varsz);
+}
diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c
new file mode 100644
index 000000000000..950506495be7
--- /dev/null
+++ b/drivers/staging/brcm80211/util/bcmutils.c
@@ -0,0 +1,1789 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <stdarg.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmnvram.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <proto/ethernet.h>
+#include <proto/802.1d.h>
+#include <proto/802.11.h>
+
+#ifdef WLC_LOW
+/* nvram vars cache */
+static char *nvram_vars;
+static int vars_len = -1;
+#endif /* WLC_LOW */
+
+/* copy a pkt buffer chain into a buffer */
+uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
+{
+ uint n, ret = 0;
+
+ if (len < 0)
+ len = 4096; /* "infinite" */
+
+ /* skip 'offset' bytes */
+ for (; p && offset; p = PKTNEXT(p)) {
+ if (offset < (uint) PKTLEN(p))
+ break;
+ offset -= PKTLEN(p);
+ }
+
+ if (!p)
+ return 0;
+
+ /* copy the data */
+ for (; p && len; p = PKTNEXT(p)) {
+ n = MIN((uint) PKTLEN(p) - offset, (uint) len);
+ bcopy(PKTDATA(p) + offset, buf, n);
+ buf += n;
+ len -= n;
+ ret += n;
+ offset = 0;
+ }
+
+ return ret;
+}
+
+/* copy a buffer into a pkt buffer chain */
+uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf)
+{
+ uint n, ret = 0;
+
+ /* skip 'offset' bytes */
+ for (; p && offset; p = PKTNEXT(p)) {
+ if (offset < (uint) PKTLEN(p))
+ break;
+ offset -= PKTLEN(p);
+ }
+
+ if (!p)
+ return 0;
+
+ /* copy the data */
+ for (; p && len; p = PKTNEXT(p)) {
+ n = MIN((uint) PKTLEN(p) - offset, (uint) len);
+ bcopy(buf, PKTDATA(p) + offset, n);
+ buf += n;
+ len -= n;
+ ret += n;
+ offset = 0;
+ }
+
+ return ret;
+}
+
+/* return total length of buffer chain */
+uint BCMFASTPATH pkttotlen(osl_t *osh, void *p)
+{
+ uint total;
+
+ total = 0;
+ for (; p; p = PKTNEXT(p))
+ total += PKTLEN(p);
+ return total;
+}
+
+/* return the last buffer of chained pkt */
+void *pktlast(osl_t *osh, void *p)
+{
+ for (; PKTNEXT(p); p = PKTNEXT(p))
+ ;
+
+ return p;
+}
+
+/* count segments of a chained packet */
+uint BCMFASTPATH pktsegcnt(osl_t *osh, void *p)
+{
+ uint cnt;
+
+ for (cnt = 0; p; p = PKTNEXT(p))
+ cnt++;
+
+ return cnt;
+}
+
+/*
+ * osl multiple-precedence packet queue
+ * hi_prec is always >= the number of the highest non-empty precedence
+ */
+void *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, void *p)
+{
+ struct pktq_prec *q;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+
+ ASSERT(!pktq_full(pq));
+ ASSERT(!pktq_pfull(pq, prec));
+
+ q = &pq->q[prec];
+
+ if (q->head)
+ PKTSETLINK(q->tail, p);
+ else
+ q->head = p;
+
+ q->tail = p;
+ q->len++;
+
+ pq->len++;
+
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8) prec;
+
+ return p;
+}
+
+void *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, void *p)
+{
+ struct pktq_prec *q;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+
+ ASSERT(!pktq_full(pq));
+ ASSERT(!pktq_pfull(pq, prec));
+
+ q = &pq->q[prec];
+
+ if (q->head == NULL)
+ q->tail = p;
+
+ PKTSETLINK(p, q->head);
+ q->head = p;
+ q->len++;
+
+ pq->len++;
+
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8) prec;
+
+ return p;
+}
+
+void *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ q = &pq->q[prec];
+
+ p = q->head;
+ if (p == NULL)
+ return NULL;
+
+ q->head = PKTLINK(p);
+ if (q->head == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ pq->len--;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec)
+{
+ struct pktq_prec *q;
+ void *p, *prev;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ q = &pq->q[prec];
+
+ p = q->head;
+ if (p == NULL)
+ return NULL;
+
+ for (prev = NULL; p != q->tail; p = PKTLINK(p))
+ prev = p;
+
+ if (prev)
+ PKTSETLINK(prev, NULL);
+ else
+ q->head = NULL;
+
+ q->tail = prev;
+ q->len--;
+
+ pq->len--;
+
+ return p;
+}
+
+void
+pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn,
+ int arg)
+{
+ struct pktq_prec *q;
+ void *p, *prev = NULL;
+
+ q = &pq->q[prec];
+ p = q->head;
+ while (p) {
+ if (fn == NULL || (*fn) (p, arg)) {
+ bool head = (p == q->head);
+ if (head)
+ q->head = PKTLINK(p);
+ else
+ PKTSETLINK(prev, PKTLINK(p));
+ PKTSETLINK(p, NULL);
+ PKTFREE(osh, p, dir);
+ q->len--;
+ pq->len--;
+ p = (head ? q->head : PKTLINK(prev));
+ } else {
+ prev = p;
+ p = PKTLINK(p);
+ }
+ }
+
+ if (q->head == NULL) {
+ ASSERT(q->len == 0);
+ q->tail = NULL;
+ }
+}
+
+bool BCMFASTPATH pktq_pdel(struct pktq *pq, void *pktbuf, int prec)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ if (!pktbuf)
+ return FALSE;
+
+ q = &pq->q[prec];
+
+ if (q->head == pktbuf) {
+ q->head = PKTLINK(pktbuf);
+ if (q->head == NULL)
+ q->tail = NULL;
+ } else {
+ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p))
+ ;
+ if (p == NULL)
+ return FALSE;
+
+ PKTSETLINK(p, PKTLINK(pktbuf));
+ if (q->tail == pktbuf)
+ q->tail = p;
+ }
+
+ q->len--;
+ pq->len--;
+ PKTSETLINK(pktbuf, NULL);
+ return TRUE;
+}
+
+void pktq_init(struct pktq *pq, int num_prec, int max_len)
+{
+ int prec;
+
+ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
+
+ /* pq is variable size; only zero out what's requested */
+ bzero(pq,
+ OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
+
+ pq->num_prec = (uint16) num_prec;
+
+ pq->max = (uint16) max_len;
+
+ for (prec = 0; prec < num_prec; prec++)
+ pq->q[prec].max = pq->max;
+}
+
+void *BCMFASTPATH pktq_deq(struct pktq *pq, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ q = &pq->q[prec];
+
+ p = q->head;
+ if (p == NULL)
+ return NULL;
+
+ q->head = PKTLINK(p);
+ if (q->head == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ pq->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void *BCMFASTPATH pktq_deq_tail(struct pktq *pq, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p, *prev;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
+
+ q = &pq->q[prec];
+
+ p = q->head;
+ if (p == NULL)
+ return NULL;
+
+ for (prev = NULL; p != q->tail; p = PKTLINK(p))
+ prev = p;
+
+ if (prev)
+ PKTSETLINK(prev, NULL);
+ else
+ q->head = NULL;
+
+ q->tail = prev;
+ q->len--;
+
+ pq->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void *pktq_peek(struct pktq *pq, int *prec_out)
+{
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return pq->q[prec].head;
+}
+
+void *pktq_peek_tail(struct pktq *pq, int *prec_out)
+{
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return pq->q[prec].tail;
+}
+
+void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg)
+{
+ int prec;
+ for (prec = 0; prec < pq->num_prec; prec++)
+ pktq_pflush(osh, pq, prec, dir, fn, arg);
+ if (fn == NULL)
+ ASSERT(pq->len == 0);
+}
+
+/* Return sum of lengths of a specific set of precedences */
+int pktq_mlen(struct pktq *pq, uint prec_bmp)
+{
+ int prec, len;
+
+ len = 0;
+
+ for (prec = 0; prec <= pq->hi_prec; prec++)
+ if (prec_bmp & (1 << prec))
+ len += pq->q[prec].len;
+
+ return len;
+}
+
+/* Priority dequeue from a specific set of precedences */
+void *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+ if (prec-- == 0)
+ return NULL;
+
+ q = &pq->q[prec];
+
+ p = q->head;
+ if (p == NULL)
+ return NULL;
+
+ q->head = PKTLINK(p);
+ if (q->head == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ pq->len--;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+const unsigned char bcm_ctype[] = {
+
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 0-7 */
+ _BCM_C, _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C | _BCM_S,
+ _BCM_C | _BCM_S, _BCM_C | _BCM_S, _BCM_C,
+ _BCM_C, /* 8-15 */
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 16-23 */
+ _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, _BCM_C, /* 24-31 */
+ _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 32-39 */
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 40-47 */
+ _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, _BCM_D, /* 48-55 */
+ _BCM_D, _BCM_D, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 56-63 */
+ _BCM_P, _BCM_U | _BCM_X, _BCM_U | _BCM_X, _BCM_U | _BCM_X,
+ _BCM_U | _BCM_X, _BCM_U | _BCM_X,
+ _BCM_U | _BCM_X, _BCM_U, /* 64-71 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 72-79 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 80-87 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 88-95 */
+ _BCM_P, _BCM_L | _BCM_X, _BCM_L | _BCM_X, _BCM_L | _BCM_X,
+ _BCM_L | _BCM_X, _BCM_L | _BCM_X,
+ _BCM_L | _BCM_X, _BCM_L, /* 96-103 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 104-111 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 112-119 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_C, /* 120-127 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
+ _BCM_S | _BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U,
+ _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L,
+ _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
+};
+
+ulong BCMROMFN(bcm_strtoul) (char *cp, char **endp, uint base)
+{
+ ulong result, last_result = 0, value;
+ bool minus;
+
+ minus = FALSE;
+
+ while (bcm_isspace(*cp))
+ cp++;
+
+ if (cp[0] == '+')
+ cp++;
+ else if (cp[0] == '-') {
+ minus = TRUE;
+ cp++;
+ }
+
+ if (base == 0) {
+ if (cp[0] == '0') {
+ if ((cp[1] == 'x') || (cp[1] == 'X')) {
+ base = 16;
+ cp = &cp[2];
+ } else {
+ base = 8;
+ cp = &cp[1];
+ }
+ } else
+ base = 10;
+ } else if (base == 16 && (cp[0] == '0')
+ && ((cp[1] == 'x') || (cp[1] == 'X'))) {
+ cp = &cp[2];
+ }
+
+ result = 0;
+
+ while (bcm_isxdigit(*cp) &&
+ (value =
+ bcm_isdigit(*cp) ? *cp - '0' : bcm_toupper(*cp) - 'A' + 10) <
+ base) {
+ result = result * base + value;
+ /* Detected overflow */
+ if (result < last_result && !minus)
+ return (ulong) -1;
+ last_result = result;
+ cp++;
+ }
+
+ if (minus)
+ result = (ulong) (-(long)result);
+
+ if (endp)
+ *endp = (char *)cp;
+
+ return result;
+}
+
+int BCMROMFN(bcm_atoi) (char *s)
+{
+ return (int)bcm_strtoul(s, NULL, 10);
+}
+
+/* return pointer to location of substring 'needle' in 'haystack' */
+char *BCMROMFN(bcmstrstr) (char *haystack, char *needle)
+{
+ int len, nlen;
+ int i;
+
+ if ((haystack == NULL) || (needle == NULL))
+ return haystack;
+
+ nlen = strlen(needle);
+ len = strlen(haystack) - nlen + 1;
+
+ for (i = 0; i < len; i++)
+ if (memcmp(needle, &haystack[i], nlen) == 0)
+ return &haystack[i];
+ return NULL;
+}
+
+char *BCMROMFN(bcmstrcat) (char *dest, const char *src)
+{
+ char *p;
+
+ p = dest + strlen(dest);
+
+ while ((*p++ = *src++) != '\0')
+ ;
+
+ return dest;
+}
+
+char *BCMROMFN(bcmstrncat) (char *dest, const char *src, uint size)
+{
+ char *endp;
+ char *p;
+
+ p = dest + strlen(dest);
+ endp = p + size;
+
+ while (p != endp && (*p++ = *src++) != '\0')
+ ;
+
+ return dest;
+}
+
+/****************************************************************************
+* Function: bcmstrtok
+*
+* Purpose:
+* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(),
+* but allows strToken() to be used by different strings or callers at the same
+* time. Each call modifies '*string' by substituting a NULL character for the
+* first delimiter that is encountered, and updates 'string' to point to the char
+* after the delimiter. Leading delimiters are skipped.
+*
+* Parameters:
+* string (mod) Ptr to string ptr, updated by token.
+* delimiters (in) Set of delimiter characters.
+* tokdelim (out) Character that delimits the returned token. (May
+* be set to NULL if token delimiter is not required).
+*
+* Returns: Pointer to the next token found. NULL when no more tokens are found.
+*****************************************************************************
+*/
+char *bcmstrtok(char **string, const char *delimiters, char *tokdelim)
+{
+ unsigned char *str;
+ unsigned long map[8];
+ int count;
+ char *nextoken;
+
+ if (tokdelim != NULL) {
+ /* Prime the token delimiter */
+ *tokdelim = '\0';
+ }
+
+ /* Clear control map */
+ for (count = 0; count < 8; count++) {
+ map[count] = 0;
+ }
+
+ /* Set bits in delimiter table */
+ do {
+ map[*delimiters >> 5] |= (1 << (*delimiters & 31));
+ } while (*delimiters++);
+
+ str = (unsigned char *)*string;
+
+ /* Find beginning of token (skip over leading delimiters). Note that
+ * there is no token iff this loop sets str to point to the terminal
+ * null (*str == '\0')
+ */
+ while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) {
+ str++;
+ }
+
+ nextoken = (char *)str;
+
+ /* Find the end of the token. If it is not the end of the string,
+ * put a null there.
+ */
+ for (; *str; str++) {
+ if (map[*str >> 5] & (1 << (*str & 31))) {
+ if (tokdelim != NULL) {
+ *tokdelim = *str;
+ }
+
+ *str++ = '\0';
+ break;
+ }
+ }
+
+ *string = (char *)str;
+
+ /* Determine if a token has been found. */
+ if (nextoken == (char *)str) {
+ return NULL;
+ } else {
+ return nextoken;
+ }
+}
+
+#define xToLower(C) \
+ ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C)
+
+/****************************************************************************
+* Function: bcmstricmp
+*
+* Purpose: Compare to strings case insensitively.
+*
+* Parameters: s1 (in) First string to compare.
+* s2 (in) Second string to compare.
+*
+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+* t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int bcmstricmp(const char *s1, const char *s2)
+{
+ char dc, sc;
+
+ while (*s2 && *s1) {
+ dc = xToLower(*s1);
+ sc = xToLower(*s2);
+ if (dc < sc)
+ return -1;
+ if (dc > sc)
+ return 1;
+ s1++;
+ s2++;
+ }
+
+ if (*s1 && !*s2)
+ return 1;
+ if (!*s1 && *s2)
+ return -1;
+ return 0;
+}
+
+/****************************************************************************
+* Function: bcmstrnicmp
+*
+* Purpose: Compare to strings case insensitively, upto a max of 'cnt'
+* characters.
+*
+* Parameters: s1 (in) First string to compare.
+* s2 (in) Second string to compare.
+* cnt (in) Max characters to compare.
+*
+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+* t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int bcmstrnicmp(const char *s1, const char *s2, int cnt)
+{
+ char dc, sc;
+
+ while (*s2 && *s1 && cnt) {
+ dc = xToLower(*s1);
+ sc = xToLower(*s2);
+ if (dc < sc)
+ return -1;
+ if (dc > sc)
+ return 1;
+ s1++;
+ s2++;
+ cnt--;
+ }
+
+ if (!cnt)
+ return 0;
+ if (*s1 && !*s2)
+ return 1;
+ if (!*s1 && *s2)
+ return -1;
+ return 0;
+}
+
+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+int BCMROMFN(bcm_ether_atoe) (char *p, struct ether_addr *ea)
+{
+ int i = 0;
+
+ for (;;) {
+ ea->octet[i++] = (char)bcm_strtoul(p, &p, 16);
+ if (!*p++ || i == 6)
+ break;
+ }
+
+ return i == 6;
+}
+
+char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf)
+{
+ snprintf(buf, 18, "%pM", ea->octet);
+ return buf;
+}
+
+void bcm_mdelay(uint ms)
+{
+ uint i;
+
+ for (i = 0; i < ms; i++) {
+ OSL_DELAY(1000);
+ }
+}
+
+/*
+ * Search the name=value vars for a specific one and return its value.
+ * Returns NULL if not found.
+ */
+char *getvar(char *vars, const char *name)
+{
+ char *s;
+ int len;
+
+ if (!name)
+ return NULL;
+
+ len = strlen(name);
+ if (len == 0)
+ return NULL;
+
+ /* first look in vars[] */
+ for (s = vars; s && *s;) {
+ if ((bcmp(s, name, len) == 0) && (s[len] == '='))
+ return &s[len + 1];
+
+ while (*s++)
+ ;
+ }
+
+ /* then query nvram */
+ return nvram_get(name);
+}
+
+/*
+ * Search the vars for a specific one and return its value as
+ * an integer. Returns 0 if not found.
+ */
+int getintvar(char *vars, const char *name)
+{
+ char *val;
+
+ val = getvar(vars, name);
+ if (val == NULL)
+ return 0;
+
+ return bcm_strtoul(val, NULL, 0);
+}
+
+int getintvararray(char *vars, const char *name, uint8 index)
+{
+ char *buf, *endp;
+ int i = 0;
+ int val = 0;
+
+ buf = getvar(vars, name);
+ if (buf == NULL) {
+ return 0;
+ }
+
+ /* table values are always separated by "," or " " */
+ while (*buf != '\0') {
+ val = bcm_strtoul(buf, &endp, 0);
+ if (i == index) {
+ return val;
+ }
+ buf = endp;
+ /* delimiter is ',' */
+ if (*buf == ',')
+ buf++;
+ i++;
+ }
+ return 0;
+}
+
+/* Search for token in comma separated token-string */
+static int findmatch(char *string, char *name)
+{
+ uint len;
+ char *c;
+
+ len = strlen(name);
+ while ((c = strchr(string, ',')) != NULL) {
+ if (len == (uint) (c - string) && !strncmp(string, name, len))
+ return 1;
+ string = c + 1;
+ }
+
+ return !strcmp(string, name);
+}
+
+/* Return gpio pin number assigned to the named pin
+ *
+ * Variable should be in format:
+ *
+ * gpio<N>=pin_name,pin_name
+ *
+ * This format allows multiple features to share the gpio with mutual
+ * understanding.
+ *
+ * 'def_pin' is returned if a specific gpio is not defined for the requested functionality
+ * and if def_pin is not used by others.
+ */
+uint getgpiopin(char *vars, char *pin_name, uint def_pin)
+{
+ char name[] = "gpioXXXX";
+ char *val;
+ uint pin;
+
+ /* Go thru all possibilities till a match in pin name */
+ for (pin = 0; pin < GPIO_NUMPINS; pin++) {
+ snprintf(name, sizeof(name), "gpio%d", pin);
+ val = getvar(vars, name);
+ if (val && findmatch(val, pin_name))
+ return pin;
+ }
+
+ if (def_pin != GPIO_PIN_NOTDEFINED) {
+ /* make sure the default pin is not used by someone else */
+ snprintf(name, sizeof(name), "gpio%d", def_pin);
+ if (getvar(vars, name)) {
+ def_pin = GPIO_PIN_NOTDEFINED;
+ }
+ }
+ return def_pin;
+}
+
+#if defined(BCMDBG)
+/* pretty hex print a pkt buffer chain */
+void prpkt(const char *msg, osl_t *osh, void *p0)
+{
+ void *p;
+
+ if (msg && (msg[0] != '\0'))
+ printf("%s:\n", msg);
+
+ for (p = p0; p; p = PKTNEXT(p))
+ prhex(NULL, PKTDATA(p), PKTLEN(p));
+}
+#endif /* defined(BCMDBG) */
+
+static char bcm_undeferrstr[32];
+static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
+
+/* Convert the error codes into related error strings */
+const char *bcmerrorstr(int bcmerror)
+{
+ /* check if someone added a bcmerror code but forgot to add errorstring */
+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
+
+ if (bcmerror > 0 || bcmerror < BCME_LAST) {
+ snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr),
+ "Undefined error %d", bcmerror);
+ return bcm_undeferrstr;
+ }
+
+ ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
+
+ return bcmerrorstrtable[-bcmerror];
+}
+
+#ifdef WLC_LOW
+static void BCMINITFN(bcm_nvram_refresh) (char *flash)
+{
+ int i;
+ int ret = 0;
+
+ ASSERT(flash != NULL);
+
+ /* default "empty" vars cache */
+ bzero(flash, 2);
+
+ ret = nvram_getall(flash, NVRAM_SPACE);
+ if (ret)
+ return;
+
+ /* determine nvram length */
+ for (i = 0; i < NVRAM_SPACE; i++) {
+ if (flash[i] == '\0' && flash[i + 1] == '\0')
+ break;
+ }
+
+ if (i > 1)
+ vars_len = i + 2;
+ else
+ vars_len = 0;
+}
+
+char *bcm_nvram_vars(uint *length)
+{
+#ifndef BCMNVRAMR
+ /* cache may be stale if nvram is read/write */
+ if (nvram_vars) {
+ ASSERT(!bcmreclaimed);
+ bcm_nvram_refresh(nvram_vars);
+ }
+#endif
+ if (length)
+ *length = vars_len;
+ return nvram_vars;
+}
+
+/* copy nvram vars into locally-allocated multi-string array */
+int BCMINITFN(bcm_nvram_cache) (void *sih)
+{
+ int ret = 0;
+ void *osh;
+ char *flash = NULL;
+
+ if (vars_len >= 0) {
+#ifndef BCMNVRAMR
+ bcm_nvram_refresh(nvram_vars);
+#endif
+ return 0;
+ }
+
+ osh = si_osh((si_t *) sih);
+
+ /* allocate memory and read in flash */
+ flash = MALLOC(osh, NVRAM_SPACE);
+ if (!flash) {
+ ret = BCME_NOMEM;
+ goto exit;
+ }
+
+ bcm_nvram_refresh(flash);
+#ifdef BCMNVRAMR
+ if (vars_len > 3) {
+ /* copy into a properly-sized buffer */
+ nvram_vars = MALLOC(osh, vars_len);
+ if (!nvram_vars) {
+ ret = BCME_NOMEM;
+ } else
+ bcopy(flash, nvram_vars, vars_len);
+ }
+ MFREE(osh, flash, NVRAM_SPACE);
+#else
+ /* cache must be full size of nvram if read/write */
+ nvram_vars = flash;
+#endif /* BCMNVRAMR */
+
+ exit:
+ return ret;
+}
+#endif /* WLC_LOW */
+
+/* iovar table lookup */
+const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
+{
+ const bcm_iovar_t *vi;
+ const char *lookup_name;
+
+ /* skip any ':' delimited option prefixes */
+ lookup_name = strrchr(name, ':');
+ if (lookup_name != NULL)
+ lookup_name++;
+ else
+ lookup_name = name;
+
+ ASSERT(table != NULL);
+
+ for (vi = table; vi->name; vi++) {
+ if (!strcmp(vi->name, lookup_name))
+ return vi;
+ }
+ /* ran to end of table */
+
+ return NULL; /* var name not found */
+}
+
+int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
+{
+ int bcmerror = 0;
+
+ /* length check on io buf */
+ switch (vi->type) {
+ case IOVT_BOOL:
+ case IOVT_INT8:
+ case IOVT_INT16:
+ case IOVT_INT32:
+ case IOVT_UINT8:
+ case IOVT_UINT16:
+ case IOVT_UINT32:
+ /* all integers are int32 sized args at the ioctl interface */
+ if (len < (int)sizeof(int)) {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
+
+ case IOVT_BUFFER:
+ /* buffer must meet minimum length requirement */
+ if (len < vi->minlen) {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
+
+ case IOVT_VOID:
+ if (!set) {
+ /* Cannot return nil... */
+ bcmerror = BCME_UNSUPPORTED;
+ } else if (len) {
+ /* Set is an action w/o parameters */
+ bcmerror = BCME_BUFTOOLONG;
+ }
+ break;
+
+ default:
+ /* unknown type for length check in iovar info */
+ ASSERT(0);
+ bcmerror = BCME_UNSUPPORTED;
+ }
+
+ return bcmerror;
+}
+
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8 crc8_table[256] = {
+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+};
+
+#define CRC_INNER_LOOP(n, c, x) \
+ ((c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff])
+
+uint8 BCMROMFN(hndcrc8) (uint8 *pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */
+ ) {
+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro
+ * to avoid the undefined and unnecessary (uint8 >> 8) operation.
+ */
+ while (nbytes-- > 0)
+ crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
+
+/*******************************************************************************
+ * crc16
+ *
+ * Computes a crc16 over the input data using the polynomial:
+ *
+ * x^16 + x^12 +x^5 + 1
+ *
+ * The caller provides the initial value (either CRC16_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC16_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint16 crc16_table[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
+};
+
+uint16 BCMROMFN(hndcrc16) (uint8 *pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */
+ ) {
+ while (nbytes-- > 0)
+ CRC_INNER_LOOP(16, crc, *pdata++);
+ return crc;
+}
+
+/*
+ * Advance from the current 1-byte tag/1-byte length/variable-length value
+ * triple, to the next, returning a pointer to the next.
+ * If the current or next TLV is invalid (does not fit in given buffer length),
+ * NULL is returned.
+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
+ * by the TLV parameter's length if it is valid.
+ */
+bcm_tlv_t *BCMROMFN(bcm_next_tlv) (bcm_tlv_t *elt, int *buflen)
+{
+ int len;
+
+ /* validate current elt */
+ if (!bcm_valid_tlv(elt, *buflen))
+ return NULL;
+
+ /* advance to next elt */
+ len = elt->len;
+ elt = (bcm_tlv_t *) (elt->data + len);
+ *buflen -= (2 + len);
+
+ /* validate next elt */
+ if (!bcm_valid_tlv(elt, *buflen))
+ return NULL;
+
+ return elt;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ */
+bcm_tlv_t *BCMROMFN(bcm_parse_tlvs) (void *buf, int buflen, uint key)
+{
+ bcm_tlv_t *elt;
+ int totlen;
+
+ elt = (bcm_tlv_t *) buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= 2) {
+ int len = elt->len;
+
+ /* validate remaining totlen */
+ if ((elt->id == key) && (totlen >= (len + 2)))
+ return elt;
+
+ elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2));
+ totlen -= (len + 2);
+ }
+
+ return NULL;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag. Stop parsing when we see an element whose ID is greater
+ * than the target key.
+ */
+bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs) (void *buf, int buflen, uint key)
+{
+ bcm_tlv_t *elt;
+ int totlen;
+
+ elt = (bcm_tlv_t *) buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= 2) {
+ uint id = elt->id;
+ int len = elt->len;
+
+ /* Punt if we start seeing IDs > than target key */
+ if (id > key)
+ return NULL;
+
+ /* validate remaining totlen */
+ if ((id == key) && (totlen >= (len + 2)))
+ return elt;
+
+ elt = (bcm_tlv_t *) ((uint8 *) elt + (len + 2));
+ totlen -= (len + 2);
+ }
+ return NULL;
+}
+
+#if defined(BCMDBG)
+int
+bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char *buf, int len)
+{
+ int i;
+ char *p = buf;
+ char hexstr[16];
+ int slen = 0, nlen = 0;
+ uint32 bit;
+ const char *name;
+
+ if (len < 2 || !buf)
+ return 0;
+
+ buf[0] = '\0';
+
+ for (i = 0; flags != 0; i++) {
+ bit = bd[i].bit;
+ name = bd[i].name;
+ if (bit == 0 && flags != 0) {
+ /* print any unnamed bits */
+ snprintf(hexstr, 16, "0x%X", flags);
+ name = hexstr;
+ flags = 0; /* exit loop */
+ } else if ((flags & bit) == 0)
+ continue;
+ flags &= ~bit;
+ nlen = strlen(name);
+ slen += nlen;
+ /* count btwn flag space */
+ if (flags != 0)
+ slen += 1;
+ /* need NULL char as well */
+ if (len <= slen)
+ break;
+ /* copy NULL char but don't count it */
+ strncpy(p, name, nlen + 1);
+ p += nlen;
+ /* copy btwn flag space and NULL char */
+ if (flags != 0)
+ p += snprintf(p, 2, " ");
+ len -= slen;
+ }
+
+ /* indicate the str was too short */
+ if (flags != 0) {
+ if (len < 2)
+ p -= 2 - len; /* overwrite last char */
+ p += snprintf(p, 2, ">");
+ }
+
+ return (int)(p - buf);
+}
+
+/* print bytes formatted as hex to a string. return the resulting string length */
+int bcm_format_hex(char *str, const void *bytes, int len)
+{
+ int i;
+ char *p = str;
+ const uint8 *src = (const uint8 *)bytes;
+
+ for (i = 0; i < len; i++) {
+ p += snprintf(p, 3, "%02X", *src);
+ src++;
+ }
+ return (int)(p - str);
+}
+#endif /* defined(BCMDBG) */
+
+/* pretty hex print a contiguous buffer */
+void prhex(const char *msg, uchar *buf, uint nbytes)
+{
+ char line[128], *p;
+ int len = sizeof(line);
+ int nchar;
+ uint i;
+
+ if (msg && (msg[0] != '\0'))
+ printf("%s:\n", msg);
+
+ p = line;
+ for (i = 0; i < nbytes; i++) {
+ if (i % 16 == 0) {
+ nchar = snprintf(p, len, " %04d: ", i); /* line prefix */
+ p += nchar;
+ len -= nchar;
+ }
+ if (len > 0) {
+ nchar = snprintf(p, len, "%02x ", buf[i]);
+ p += nchar;
+ len -= nchar;
+ }
+
+ if (i % 16 == 15) {
+ printf("%s\n", line); /* flush line */
+ p = line;
+ len = sizeof(line);
+ }
+ }
+
+ /* flush last partial line */
+ if (p != line)
+ printf("%s\n", line);
+}
+
+static const char *crypto_algo_names[] = {
+ "NONE",
+ "WEP1",
+ "TKIP",
+ "WEP128",
+ "AES_CCM",
+ "NALG" "UNDEF",
+ "UNDEF",
+ "UNDEF",
+ "UNDEF"
+};
+
+const char *bcm_crypto_algo_name(uint algo)
+{
+ return (algo <
+ ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR";
+}
+
+#ifdef BCMDBG
+void deadbeef(void *p, uint len)
+{
+ static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef };
+
+ while (len-- > 0) {
+ *(uint8 *) p = meat[((uintptr) p) & 3];
+ p = (uint8 *) p + 1;
+ }
+}
+#endif /* BCMDBG */
+
+char *bcm_chipname(uint chipid, char *buf, uint len)
+{
+ const char *fmt;
+
+ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+ snprintf(buf, len, fmt, chipid);
+ return buf;
+}
+
+/* Produce a human-readable string for boardrev */
+char *bcm_brev_str(uint32 brev, char *buf)
+{
+ if (brev < 0x100)
+ snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
+ else
+ snprintf(buf, 8, "%c%03x",
+ ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff);
+
+ return buf;
+}
+
+#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */
+
+/* dump large strings to console */
+void printbig(char *buf)
+{
+ uint len, max_len;
+ char c;
+
+ len = strlen(buf);
+
+ max_len = BUFSIZE_TODUMP_ATONCE;
+
+ while (len > max_len) {
+ c = buf[max_len];
+ buf[max_len] = '\0';
+ printf("%s", buf);
+ buf[max_len] = c;
+
+ buf += max_len;
+ len -= max_len;
+ }
+ /* print the remaining string */
+ printf("%s\n", buf);
+ return;
+}
+
+/* routine to dump fields in a fileddesc structure */
+uint
+bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1,
+ struct fielddesc *fielddesc_array, char *buf, uint32 bufsize)
+{
+ uint filled_len;
+ int len;
+ struct fielddesc *cur_ptr;
+
+ filled_len = 0;
+ cur_ptr = fielddesc_array;
+
+ while (bufsize > 1) {
+ if (cur_ptr->nameandfmt == NULL)
+ break;
+ len = snprintf(buf, bufsize, cur_ptr->nameandfmt,
+ read_rtn(arg0, arg1, cur_ptr->offset));
+ /* check for snprintf overflow or error */
+ if (len < 0 || (uint32) len >= bufsize)
+ len = bufsize - 1;
+ buf += len;
+ bufsize -= len;
+ filled_len += len;
+ cur_ptr++;
+ }
+ return filled_len;
+}
+
+uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+{
+ uint len;
+
+ len = strlen(name) + 1;
+
+ if ((len + datalen) > buflen)
+ return 0;
+
+ strncpy(buf, name, buflen);
+
+ /* append data onto the end of the name string */
+ memcpy(&buf[len], data, datalen);
+ len += datalen;
+
+ return len;
+}
+
+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a uint16.
+ */
+
+#define QDBM_OFFSET 153 /* Offset for first entry */
+#define QDBM_TABLE_LEN 40 /* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+
+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+};
+
+uint16 BCMROMFN(bcm_qdbm_to_mw) (uint8 qdbm)
+{
+ uint factor = 1;
+ int idx = qdbm - QDBM_OFFSET;
+
+ if (idx >= QDBM_TABLE_LEN) {
+ /* clamp to max uint16 mW value */
+ return 0xFFFF;
+ }
+
+ /* scale the qdBm index up to the range of the table 0-40
+ * where an offset of 40 qdBm equals a factor of 10 mW.
+ */
+ while (idx < 0) {
+ idx += 40;
+ factor *= 10;
+ }
+
+ /* return the mW value scaled down to the correct factor of 10,
+ * adding in factor/2 to get proper rounding.
+ */
+ return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+}
+
+uint8 BCMROMFN(bcm_mw_to_qdbm) (uint16 mw)
+{
+ uint8 qdbm;
+ int offset;
+ uint mw_uint = mw;
+ uint boundary;
+
+ /* handle boundary case */
+ if (mw_uint <= 1)
+ return 0;
+
+ offset = QDBM_OFFSET;
+
+ /* move mw into the range of the table */
+ while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+ mw_uint *= 10;
+ offset -= 40;
+ }
+
+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+ nqdBm_to_mW_map[qdbm]) / 2;
+ if (mw_uint < boundary)
+ break;
+ }
+
+ qdbm += (uint8) offset;
+
+ return qdbm;
+}
+
+uint BCMROMFN(bcm_bitcount) (uint8 *bitmap, uint length)
+{
+ uint bitcount = 0, i;
+ uint8 tmp;
+ for (i = 0; i < length; i++) {
+ tmp = bitmap[i];
+ while (tmp) {
+ bitcount++;
+ tmp &= (tmp - 1);
+ }
+ }
+ return bitcount;
+}
+
+/* Initialization of bcmstrbuf structure */
+void bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
+{
+ b->origsize = b->size = size;
+ b->origbuf = b->buf = buf;
+}
+
+/* Buffer sprintf wrapper to guard against buffer overflow */
+int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+ r = vsnprintf(b->buf, b->size, fmt, ap);
+
+ /* Non Ansi C99 compliant returns -1,
+ * Ansi compliant return r >= b->size,
+ * bcmstdlib returns 0, handle all
+ */
+ if ((r == -1) || (r >= (int)b->size) || (r == 0)) {
+ b->size = 0;
+ } else {
+ b->size -= r;
+ b->buf += r;
+ }
+
+ va_end(ap);
+
+ return r;
+}
+
+void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount)
+{
+ int i;
+
+ for (i = 0; i < num_bytes; i++) {
+ num[i] += amount;
+ if (num[i] >= amount)
+ break;
+ amount = 1;
+ }
+}
+
+int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes)
+{
+ int i;
+
+ for (i = nbytes - 1; i >= 0; i--) {
+ if (arg1[i] != arg2[i])
+ return arg1[i] - arg2[i];
+ }
+ return 0;
+}
+
+void bcm_print_bytes(char *name, const uchar *data, int len)
+{
+ int i;
+ int per_line = 0;
+
+ printf("%s: %d\n", name ? name : "", len);
+ for (i = 0; i < len; i++) {
+ printf("%02x ", *data++);
+ per_line++;
+ if (per_line == 16) {
+ per_line = 0;
+ printf("\n");
+ }
+ }
+ printf("\n");
+}
+
+#if defined(BCMDBG)
+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1)
+int bcm_format_ssid(char *buf, const uchar ssid[], uint ssid_len)
+{
+ uint i, c;
+ char *p = buf;
+ char *endp = buf + SSID_FMT_BUF_LEN;
+
+ if (ssid_len > DOT11_MAX_SSID_LEN)
+ ssid_len = DOT11_MAX_SSID_LEN;
+
+ for (i = 0; i < ssid_len; i++) {
+ c = (uint) ssid[i];
+ if (c == '\\') {
+ *p++ = '\\';
+ *p++ = '\\';
+ } else if (bcm_isprint((uchar) c)) {
+ *p++ = (char)c;
+ } else {
+ p += snprintf(p, (endp - p), "\\x%02X", c);
+ }
+ }
+ *p = '\0';
+ ASSERT(p < endp);
+
+ return (int)(p - buf);
+}
+#endif /* defined(BCMDBG) */
diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c
new file mode 100644
index 000000000000..5eced8ef125c
--- /dev/null
+++ b/drivers/staging/brcm80211/util/bcmwifi.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+
+#include <osl.h>
+#include <bcmutils.h>
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#include <bcmwifi.h>
+
+/* Chanspec ASCII representation:
+ * <channel><band><bandwidth><ctl-sideband>
+ * digit [AB] [N] [UL]
+ *
+ * <channel>: channel number of the 10MHz or 20MHz channel,
+ * or control sideband channel of 40MHz channel.
+ * <band>: A for 5GHz, B for 2.4GHz
+ * <bandwidth>: N for 10MHz, nothing for 20MHz or 40MHz
+ * (ctl-sideband spec implies 40MHz)
+ * <ctl-sideband>: U for upper, L for lower
+ *
+ * <band> may be omitted on input, and will be assumed to be
+ * 2.4GHz if channel number <= 14.
+ *
+ * Examples:
+ * 8 -> 2.4GHz channel 8, 20MHz
+ * 8b -> 2.4GHz channel 8, 20MHz
+ * 8l -> 2.4GHz channel 8, 40MHz, lower ctl sideband
+ * 8a -> 5GHz channel 8 (low 5 GHz band), 20MHz
+ * 36 -> 5GHz channel 36, 20MHz
+ * 36l -> 5GHz channel 36, 40MHz, lower ctl sideband
+ * 40u -> 5GHz channel 40, 40MHz, upper ctl sideband
+ * 180n -> channel 180, 10MHz
+ */
+
+/* given a chanspec and a string buffer, format the chanspec as a
+ * string, and return the original pointer a.
+ * Min buffer length must be CHANSPEC_STR_LEN.
+ * On error return NULL
+ */
+char *wf_chspec_ntoa(chanspec_t chspec, char *buf)
+{
+ const char *band, *bw, *sb;
+ uint channel;
+
+ band = "";
+ bw = "";
+ sb = "";
+ channel = CHSPEC_CHANNEL(chspec);
+ /* check for non-default band spec */
+ if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) ||
+ (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL))
+ band = (CHSPEC_IS2G(chspec)) ? "b" : "a";
+ if (CHSPEC_IS40(chspec)) {
+ if (CHSPEC_SB_UPPER(chspec)) {
+ sb = "u";
+ channel += CH_10MHZ_APART;
+ } else {
+ sb = "l";
+ channel -= CH_10MHZ_APART;
+ }
+ } else if (CHSPEC_IS10(chspec)) {
+ bw = "n";
+ }
+
+ /* Outputs a max of 6 chars including '\0' */
+ snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb);
+ return buf;
+}
+
+/* given a chanspec string, convert to a chanspec.
+ * On error return 0
+ */
+chanspec_t wf_chspec_aton(char *a)
+{
+ char *endp = NULL;
+ uint channel, band, bw, ctl_sb;
+ char c;
+
+ channel = strtoul(a, &endp, 10);
+
+ /* check for no digits parsed */
+ if (endp == a)
+ return 0;
+
+ if (channel > MAXCHANNEL)
+ return 0;
+
+ band =
+ ((channel <=
+ CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+ bw = WL_CHANSPEC_BW_20;
+ ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
+
+ a = endp;
+
+ c = tolower(a[0]);
+ if (c == '\0')
+ goto done;
+
+ /* parse the optional ['A' | 'B'] band spec */
+ if (c == 'a' || c == 'b') {
+ band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;
+ a++;
+ c = tolower(a[0]);
+ if (c == '\0')
+ goto done;
+ }
+
+ /* parse bandwidth 'N' (10MHz) or 40MHz ctl sideband ['L' | 'U'] */
+ if (c == 'n') {
+ bw = WL_CHANSPEC_BW_10;
+ } else if (c == 'l') {
+ bw = WL_CHANSPEC_BW_40;
+ ctl_sb = WL_CHANSPEC_CTL_SB_LOWER;
+ /* adjust channel to center of 40MHz band */
+ if (channel <= (MAXCHANNEL - CH_20MHZ_APART))
+ channel += CH_10MHZ_APART;
+ else
+ return 0;
+ } else if (c == 'u') {
+ bw = WL_CHANSPEC_BW_40;
+ ctl_sb = WL_CHANSPEC_CTL_SB_UPPER;
+ /* adjust channel to center of 40MHz band */
+ if (channel > CH_20MHZ_APART)
+ channel -= CH_10MHZ_APART;
+ else
+ return 0;
+ } else {
+ return 0;
+ }
+
+ done:
+ return channel | band | bw | ctl_sb;
+}
+
+/*
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, ctl_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good.
+ */
+bool wf_chspec_malformed(chanspec_t chanspec)
+{
+ /* must be 2G or 5G band */
+ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
+ return TRUE;
+ /* must be 20 or 40 bandwidth */
+ if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
+ return TRUE;
+
+ /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
+ if (CHSPEC_IS20(chanspec)) {
+ if (!CHSPEC_SB_NONE(chanspec))
+ return TRUE;
+ } else {
+ if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * This function returns the channel number that control traffic is being sent on, for legacy
+ * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+ * sideband depending on the chanspec selected
+ */
+uint8 wf_chspec_ctlchan(chanspec_t chspec)
+{
+ uint8 ctl_chan;
+
+ /* Is there a sideband ? */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+ return CHSPEC_CHANNEL(chspec);
+ } else {
+ /* we only support 40MHZ with sidebands */
+ ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40);
+ /* chanspec channel holds the centre frequency, use that and the
+ * side band information to reconstruct the control channel number
+ */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+ /* control chan is the upper 20 MHZ SB of the 40MHZ channel */
+ ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+ } else {
+ ASSERT(CHSPEC_CTL_SB(chspec) ==
+ WL_CHANSPEC_CTL_SB_LOWER);
+ /* control chan is the lower 20 MHZ SB of the 40MHZ channel */
+ ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+ }
+ }
+
+ return ctl_chan;
+}
+
+chanspec_t wf_chspec_ctlchspec(chanspec_t chspec)
+{
+ chanspec_t ctl_chspec = 0;
+ uint8 channel;
+
+ ASSERT(!wf_chspec_malformed(chspec));
+
+ /* Is there a sideband ? */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+ return chspec;
+ } else {
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+ channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+ } else {
+ channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+ }
+ ctl_chspec =
+ channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
+ ctl_chspec |= CHSPEC_BAND(chspec);
+ }
+ return ctl_chspec;
+}
+
+/*
+ * Return the channel number for a given frequency and base frequency.
+ * The returned channel number is relative to the given base frequency.
+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+ *
+ * Frequency is specified in MHz.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ *
+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+ * and [0, 200] otherwise.
+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+int wf_mhz2channel(uint freq, uint start_factor)
+{
+ int ch = -1;
+ uint base;
+ int offset;
+
+ /* take the default channel start frequency */
+ if (start_factor == 0) {
+ if (freq >= 2400 && freq <= 2500)
+ start_factor = WF_CHAN_FACTOR_2_4_G;
+ else if (freq >= 5000 && freq <= 6000)
+ start_factor = WF_CHAN_FACTOR_5_G;
+ }
+
+ if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
+ return 14;
+
+ base = start_factor / 2;
+
+ /* check that the frequency is in 1GHz range of the base */
+ if ((freq < base) || (freq > base + 1000))
+ return -1;
+
+ offset = freq - base;
+ ch = offset / 5;
+
+ /* check that frequency is a 5MHz multiple from the base */
+ if (offset != (ch * 5))
+ return -1;
+
+ /* restricted channel range check for 2.4G */
+ if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
+ return -1;
+
+ return ch;
+}
+
+/*
+ * Return the center frequency in MHz of the given channel and base frequency.
+ * The channel number is interpreted relative to the given base frequency.
+ *
+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_4_G, and WF_CHAN_FACTOR_5_G
+ * are defined for 2.4 GHz, 4 GHz, and 5 GHz bands.
+ * The channel range of [1, 14] is only checked for a start_factor of
+ * WF_CHAN_FACTOR_2_4_G (4814 = 2407 * 2).
+ * Odd start_factors produce channels on .5 MHz boundaries, in which case
+ * the answer is rounded down to an integral MHz.
+ * -1 is returned for an out of range channel.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+int wf_channel2mhz(uint ch, uint start_factor)
+{
+ int freq;
+
+ if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
+ (ch > 200))
+ freq = -1;
+ else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14))
+ freq = 2484;
+ else
+ freq = ch * 5 + start_factor / 2;
+
+ return freq;
+}
diff --git a/drivers/staging/brcm80211/util/bcmwpa.c b/drivers/staging/brcm80211/util/bcmwpa.c
new file mode 100644
index 000000000000..a78be437d002
--- /dev/null
+++ b/drivers/staging/brcm80211/util/bcmwpa.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <bcmutils.h>
+#include <bcmwpa.h>
+
+/* Is this body of this tlvs entry a WFA entry? If
+ * not update the tlvs buffer pointer/length.
+ */
+bool bcm_is_wfa_ie(uint8 *ie, uint8 **tlvs, uint *tlvs_len, uint8 type)
+{
+ /* If the contents match the WFA_OUI and type */
+ if ((ie[TLV_LEN_OFF] > (WFA_OUI_LEN + 1)) &&
+ !bcmp(&ie[TLV_BODY_OFF], WFA_OUI, WFA_OUI_LEN) &&
+ type == ie[TLV_BODY_OFF + WFA_OUI_LEN]) {
+ return TRUE;
+ }
+
+ /* point to the next ie */
+ ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
+ /* calculate the length of the rest of the buffer */
+ *tlvs_len -= (int)(ie - *tlvs);
+ /* update the pointer to the start of the buffer */
+ *tlvs = ie;
+
+ return FALSE;
+}
+
+wpa_ie_fixed_t *BCMROMFN(bcm_find_wpaie) (uint8 * parse, uint len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, len, DOT11_MNG_VS_ID))) {
+ if (bcm_is_wpa_ie((uint8 *) ie, &parse, &len)) {
+ return (wpa_ie_fixed_t *) ie;
+ }
+ }
+ return NULL;
+}
diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c
new file mode 100644
index 000000000000..b78cca169dce
--- /dev/null
+++ b/drivers/staging/brcm80211/util/hnddma.c
@@ -0,0 +1,2699 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <bcmdevs.h>
+#include <osl.h>
+#include <bcmendian.h>
+#include <hndsoc.h>
+#include <bcmutils.h>
+#include <siutils.h>
+
+#include <sbhnddma.h>
+#include <hnddma.h>
+
+/* debug/trace */
+#ifdef BCMDBG
+#define DMA_ERROR(args) \
+ do { \
+ if (!(*di->msg_level & 1)) \
+ ; \
+ else \
+ printf args; \
+ } while (0)
+#define DMA_TRACE(args) \
+ do { \
+ if (!(*di->msg_level & 2)) \
+ ; \
+ else \
+ printf args; \
+ } while (0)
+#else
+#define DMA_ERROR(args)
+#define DMA_TRACE(args)
+#endif /* BCMDBG */
+
+#define DMA_NONE(args)
+
+#define d32txregs dregs.d32_u.txregs_32
+#define d32rxregs dregs.d32_u.rxregs_32
+#define txd32 dregs.d32_u.txd_32
+#define rxd32 dregs.d32_u.rxd_32
+
+#define d64txregs dregs.d64_u.txregs_64
+#define d64rxregs dregs.d64_u.rxregs_64
+#define txd64 dregs.d64_u.txd_64
+#define rxd64 dregs.d64_u.rxd_64
+
+/* default dma message level (if input msg_level pointer is null in dma_attach()) */
+static uint dma_msg_level;
+
+#define MAXNAMEL 8 /* 8 char names */
+
+#define DI_INFO(dmah) ((dma_info_t *)dmah)
+
+/* dma engine software state */
+typedef struct dma_info {
+ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t,
+ * which could be const
+ */
+ uint *msg_level; /* message level pointer */
+ char name[MAXNAMEL]; /* callers name for diag msgs */
+
+ void *osh; /* os handle */
+ si_t *sih; /* sb handle */
+
+ bool dma64; /* this dma engine is operating in 64-bit mode */
+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
+
+ union {
+ struct {
+ dma32regs_t *txregs_32; /* 32-bit dma tx engine registers */
+ dma32regs_t *rxregs_32; /* 32-bit dma rx engine registers */
+ dma32dd_t *txd_32; /* pointer to dma32 tx descriptor ring */
+ dma32dd_t *rxd_32; /* pointer to dma32 rx descriptor ring */
+ } d32_u;
+ struct {
+ dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */
+ dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */
+ dma64dd_t *txd_64; /* pointer to dma64 tx descriptor ring */
+ dma64dd_t *rxd_64; /* pointer to dma64 rx descriptor ring */
+ } d64_u;
+ } dregs;
+
+ uint16 dmadesc_align; /* alignment requirement for dma descriptors */
+
+ uint16 ntxd; /* # tx descriptors tunable */
+ uint16 txin; /* index of next descriptor to reclaim */
+ uint16 txout; /* index of next descriptor to post */
+ void **txp; /* pointer to parallel array of pointers to packets */
+ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */
+ hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */
+ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */
+ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */
+ uint16 txdalign; /* #bytes added to alloc'd mem to align txd */
+ uint32 txdalloc; /* #bytes allocated for the ring */
+ uint32 xmtptrbase; /* When using unaligned descriptors, the ptr register
+ * is not just an index, it needs all 13 bits to be
+ * an offset from the addr register.
+ */
+
+ uint16 nrxd; /* # rx descriptors tunable */
+ uint16 rxin; /* index of next descriptor to reclaim */
+ uint16 rxout; /* index of next descriptor to post */
+ void **rxp; /* pointer to parallel array of pointers to packets */
+ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */
+ hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */
+ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */
+ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */
+ uint16 rxdalign; /* #bytes added to alloc'd mem to align rxd */
+ uint32 rxdalloc; /* #bytes allocated for the ring */
+ uint32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */
+
+ /* tunables */
+ uint16 rxbufsize; /* rx buffer size in bytes,
+ * not including the extra headroom
+ */
+ uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper stack
+ * e.g. some rx pkt buffers will be bridged to tx side
+ * without byte copying. The extra headroom needs to be
+ * large enough to fit txheader needs.
+ * Some dongle driver may not need it.
+ */
+ uint nrxpost; /* # rx buffers to keep posted */
+ uint rxoffset; /* rxcontrol offset */
+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
+ uint ddoffsethigh; /* high 32 bits */
+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
+ uint dataoffsethigh; /* high 32 bits */
+ bool aligndesc_4k; /* descriptor base need to be aligned or not */
+} dma_info_t;
+
+/*
+ * If BCMDMA32 is defined, hnddma will support both 32-bit and 64-bit DMA engines.
+ * Otherwise it will support only 64-bit.
+ *
+ * DMA32_ENAB indicates whether hnddma is compiled with support for 32-bit DMA engines.
+ * DMA64_ENAB indicates whether hnddma is compiled with support for 64-bit DMA engines.
+ *
+ * DMA64_MODE indicates whether the current DMA engine is running as 64-bit.
+ */
+#ifdef BCMDMA32
+#define DMA32_ENAB(di) 1
+#define DMA64_ENAB(di) 1
+#define DMA64_MODE(di) ((di)->dma64)
+#else /* !BCMDMA32 */
+#define DMA32_ENAB(di) 0
+#define DMA64_ENAB(di) 1
+#define DMA64_MODE(di) 1
+#endif /* !BCMDMA32 */
+
+/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
+#ifdef BCMDMASGLISTOSL
+#define DMASGLIST_ENAB TRUE
+#else
+#define DMASGLIST_ENAB FALSE
+#endif /* BCMDMASGLISTOSL */
+
+/* descriptor bumping macros */
+#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */
+#define TXD(x) XXD((x), di->ntxd)
+#define RXD(x) XXD((x), di->nrxd)
+#define NEXTTXD(i) TXD((i) + 1)
+#define PREVTXD(i) TXD((i) - 1)
+#define NEXTRXD(i) RXD((i) + 1)
+#define PREVRXD(i) RXD((i) - 1)
+
+#define NTXDACTIVE(h, t) TXD((t) - (h))
+#define NRXDACTIVE(h, t) RXD((t) - (h))
+
+/* macros to convert between byte offsets and indexes */
+#define B2I(bytes, type) ((bytes) / sizeof(type))
+#define I2B(index, type) ((index) * sizeof(type))
+
+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
+#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
+
+#define PCI64ADDR_HIGH 0x80000000 /* address[63] */
+#define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */
+
+/* Common prototypes */
+static bool _dma_isaddrext(dma_info_t *di);
+static bool _dma_descriptor_align(dma_info_t *di);
+static bool _dma_alloc(dma_info_t *di, uint direction);
+static void _dma_detach(dma_info_t *di);
+static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
+static void _dma_rxinit(dma_info_t *di);
+static void *_dma_rx(dma_info_t *di);
+static bool _dma_rxfill(dma_info_t *di);
+static void _dma_rxreclaim(dma_info_t *di);
+static void _dma_rxenable(dma_info_t *di);
+static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
+static void _dma_rx_param_get(dma_info_t *di, uint16 *rxoffset,
+ uint16 *rxbufsize);
+
+static void _dma_txblock(dma_info_t *di);
+static void _dma_txunblock(dma_info_t *di);
+static uint _dma_txactive(dma_info_t *di);
+static uint _dma_rxactive(dma_info_t *di);
+static uint _dma_txpending(dma_info_t *di);
+static uint _dma_txcommitted(dma_info_t *di);
+
+static void *_dma_peeknexttxp(dma_info_t *di);
+static void *_dma_peeknextrxp(dma_info_t *di);
+static uintptr _dma_getvar(dma_info_t *di, const char *name);
+static void _dma_counterreset(dma_info_t *di);
+static void _dma_fifoloopbackenable(dma_info_t *di);
+static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
+static uint8 dma_align_sizetobits(uint size);
+static void *dma_ringalloc(osl_t *osh, uint32 boundary, uint size,
+ uint16 *alignbits, uint *alloced,
+ dmaaddr_t *descpa, osldma_t **dmah);
+
+/* Prototypes for 32-bit routines */
+static bool dma32_alloc(dma_info_t *di, uint direction);
+static bool dma32_txreset(dma_info_t *di);
+static bool dma32_rxreset(dma_info_t *di);
+static bool dma32_txsuspendedidle(dma_info_t *di);
+static int dma32_txfast(dma_info_t *di, void *p0, bool commit);
+static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range);
+static void *dma32_getnextrxp(dma_info_t *di, bool forceall);
+static void dma32_txrotate(dma_info_t *di);
+static bool dma32_rxidle(dma_info_t *di);
+static void dma32_txinit(dma_info_t *di);
+static bool dma32_txenabled(dma_info_t *di);
+static void dma32_txsuspend(dma_info_t *di);
+static void dma32_txresume(dma_info_t *di);
+static bool dma32_txsuspended(dma_info_t *di);
+static void dma32_txreclaim(dma_info_t *di, txd_range_t range);
+static bool dma32_txstopped(dma_info_t *di);
+static bool dma32_rxstopped(dma_info_t *di);
+static bool dma32_rxenabled(dma_info_t *di);
+
+static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs);
+
+/* Prototypes for 64-bit routines */
+static bool dma64_alloc(dma_info_t *di, uint direction);
+static bool dma64_txreset(dma_info_t *di);
+static bool dma64_rxreset(dma_info_t *di);
+static bool dma64_txsuspendedidle(dma_info_t *di);
+static int dma64_txfast(dma_info_t *di, void *p0, bool commit);
+static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
+static void *dma64_getpos(dma_info_t *di, bool direction);
+static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
+static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
+static void dma64_txrotate(dma_info_t *di);
+
+static bool dma64_rxidle(dma_info_t *di);
+static void dma64_txinit(dma_info_t *di);
+static bool dma64_txenabled(dma_info_t *di);
+static void dma64_txsuspend(dma_info_t *di);
+static void dma64_txresume(dma_info_t *di);
+static bool dma64_txsuspended(dma_info_t *di);
+static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
+static bool dma64_txstopped(dma_info_t *di);
+static bool dma64_rxstopped(dma_info_t *di);
+static bool dma64_rxenabled(dma_info_t *di);
+static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs);
+
+STATIC INLINE uint32 parity32(uint32 data);
+
+const di_fcn_t dma64proc = {
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma64_txinit,
+ (di_txreset_t) dma64_txreset,
+ (di_txenabled_t) dma64_txenabled,
+ (di_txsuspend_t) dma64_txsuspend,
+ (di_txresume_t) dma64_txresume,
+ (di_txsuspended_t) dma64_txsuspended,
+ (di_txsuspendedidle_t) dma64_txsuspendedidle,
+ (di_txfast_t) dma64_txfast,
+ (di_txunframed_t) dma64_txunframed,
+ (di_getpos_t) dma64_getpos,
+ (di_txstopped_t) dma64_txstopped,
+ (di_txreclaim_t) dma64_txreclaim,
+ (di_getnexttxp_t) dma64_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma64_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma64_rxreset,
+ (di_rxidle_t) dma64_rxidle,
+ (di_rxstopped_t) dma64_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma64_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+ (di_peeknextrxp_t) _dma_peeknextrxp,
+ (di_rxparam_get_t) _dma_rx_param_get,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+ (di_ctrlflags_t) _dma_ctrlflags,
+ NULL,
+ NULL,
+ NULL,
+ (di_rxactive_t) _dma_rxactive,
+ (di_txpending_t) _dma_txpending,
+ (di_txcommitted_t) _dma_txcommitted,
+ 39
+};
+
+static const di_fcn_t dma32proc = {
+ (di_detach_t) _dma_detach,
+ (di_txinit_t) dma32_txinit,
+ (di_txreset_t) dma32_txreset,
+ (di_txenabled_t) dma32_txenabled,
+ (di_txsuspend_t) dma32_txsuspend,
+ (di_txresume_t) dma32_txresume,
+ (di_txsuspended_t) dma32_txsuspended,
+ (di_txsuspendedidle_t) dma32_txsuspendedidle,
+ (di_txfast_t) dma32_txfast,
+ NULL,
+ NULL,
+ (di_txstopped_t) dma32_txstopped,
+ (di_txreclaim_t) dma32_txreclaim,
+ (di_getnexttxp_t) dma32_getnexttxp,
+ (di_peeknexttxp_t) _dma_peeknexttxp,
+ (di_txblock_t) _dma_txblock,
+ (di_txunblock_t) _dma_txunblock,
+ (di_txactive_t) _dma_txactive,
+ (di_txrotate_t) dma32_txrotate,
+
+ (di_rxinit_t) _dma_rxinit,
+ (di_rxreset_t) dma32_rxreset,
+ (di_rxidle_t) dma32_rxidle,
+ (di_rxstopped_t) dma32_rxstopped,
+ (di_rxenable_t) _dma_rxenable,
+ (di_rxenabled_t) dma32_rxenabled,
+ (di_rx_t) _dma_rx,
+ (di_rxfill_t) _dma_rxfill,
+ (di_rxreclaim_t) _dma_rxreclaim,
+ (di_getnextrxp_t) _dma_getnextrxp,
+ (di_peeknextrxp_t) _dma_peeknextrxp,
+ (di_rxparam_get_t) _dma_rx_param_get,
+
+ (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+ (di_getvar_t) _dma_getvar,
+ (di_counterreset_t) _dma_counterreset,
+ (di_ctrlflags_t) _dma_ctrlflags,
+ NULL,
+ NULL,
+ NULL,
+ (di_rxactive_t) _dma_rxactive,
+ (di_txpending_t) _dma_txpending,
+ (di_txcommitted_t) _dma_txcommitted,
+ 39
+};
+
+hnddma_t *dma_attach(osl_t *osh, char *name, si_t *sih, void *dmaregstx,
+ void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize,
+ int rxextheadroom, uint nrxpost, uint rxoffset,
+ uint *msg_level)
+{
+ dma_info_t *di;
+ uint size;
+
+ /* allocate private info structure */
+ di = MALLOC(osh, sizeof(dma_info_t));
+ if (di == NULL) {
+#ifdef BCMDBG
+ printf("dma_attach: out of memory, malloced %d bytes\n",
+ MALLOCED(osh));
+#endif
+ return NULL;
+ }
+
+ bzero((char *)di, sizeof(dma_info_t));
+
+ di->msg_level = msg_level ? msg_level : &dma_msg_level;
+
+ /* old chips w/o sb is no longer supported */
+ ASSERT(sih != NULL);
+
+ if (DMA64_ENAB(di))
+ di->dma64 =
+ ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
+ else
+ di->dma64 = 0;
+
+ /* check arguments */
+ ASSERT(ISPOWEROF2(ntxd));
+ ASSERT(ISPOWEROF2(nrxd));
+
+ if (nrxd == 0)
+ ASSERT(dmaregsrx == NULL);
+ if (ntxd == 0)
+ ASSERT(dmaregstx == NULL);
+
+ /* init dma reg pointer */
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ ASSERT(ntxd <= D64MAXDD);
+ ASSERT(nrxd <= D64MAXDD);
+ di->d64txregs = (dma64regs_t *) dmaregstx;
+ di->d64rxregs = (dma64regs_t *) dmaregsrx;
+ di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
+ } else if (DMA32_ENAB(di)) {
+ ASSERT(ntxd <= D32MAXDD);
+ ASSERT(nrxd <= D32MAXDD);
+ di->d32txregs = (dma32regs_t *) dmaregstx;
+ di->d32rxregs = (dma32regs_t *) dmaregsrx;
+ di->hnddma.di_fn = (const di_fcn_t *)&dma32proc;
+ } else {
+ DMA_ERROR(("dma_attach: driver doesn't support 32-bit DMA\n"));
+ ASSERT(0);
+ goto fail;
+ }
+
+ /* Default flags (which can be changed by the driver calling dma_ctrlflags
+ * before enable): For backwards compatibility both Rx Overflow Continue
+ * and Parity are DISABLED.
+ * supports it.
+ */
+ di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
+ 0);
+
+ DMA_TRACE(("%s: dma_attach: %s osh %p flags 0x%x ntxd %d nrxd %d rxbufsize %d " "rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (DMA64_MODE(di) ? "DMA64" : "DMA32"), osh, di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+
+ /* make a private copy of our callers name */
+ strncpy(di->name, name, MAXNAMEL);
+ di->name[MAXNAMEL - 1] = '\0';
+
+ di->osh = osh;
+ di->sih = sih;
+
+ /* save tunables */
+ di->ntxd = (uint16) ntxd;
+ di->nrxd = (uint16) nrxd;
+
+ /* the actual dma size doesn't include the extra headroom */
+ di->rxextrahdrroom =
+ (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
+ if (rxbufsize > BCMEXTRAHDROOM)
+ di->rxbufsize = (uint16) (rxbufsize - di->rxextrahdrroom);
+ else
+ di->rxbufsize = (uint16) rxbufsize;
+
+ di->nrxpost = (uint16) nrxpost;
+ di->rxoffset = (uint8) rxoffset;
+
+ /*
+ * figure out the DMA physical address offset for dd and data
+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+ * Other bus: use zero
+ * SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+ */
+ di->ddoffsetlow = 0;
+ di->dataoffsetlow = 0;
+ /* for pci bus, add offset */
+ if (sih->bustype == PCI_BUS) {
+ if ((sih->buscoretype == PCIE_CORE_ID) && DMA64_MODE(di)) {
+ /* pcie with DMA64 */
+ di->ddoffsetlow = 0;
+ di->ddoffsethigh = SI_PCIE_DMA_H32;
+ } else {
+ /* pci(DMA32/DMA64) or pcie with DMA32 */
+ di->ddoffsetlow = SI_PCI_DMA;
+ di->ddoffsethigh = 0;
+ }
+ di->dataoffsetlow = di->ddoffsetlow;
+ di->dataoffsethigh = di->ddoffsethigh;
+ }
+#if defined(__mips__) && defined(IL_BIGENDIAN)
+ di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
+#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */
+ /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
+ if ((si_coreid(sih) == SDIOD_CORE_ID)
+ && ((si_corerev(sih) > 0) && (si_corerev(sih) <= 2)))
+ di->addrext = 0;
+ else if ((si_coreid(sih) == I2S_CORE_ID) &&
+ ((si_corerev(sih) == 0) || (si_corerev(sih) == 1)))
+ di->addrext = 0;
+ else
+ di->addrext = _dma_isaddrext(di);
+
+ /* does the descriptors need to be aligned and if yes, on 4K/8K or not */
+ di->aligndesc_4k = _dma_descriptor_align(di);
+ if (di->aligndesc_4k) {
+ if (DMA64_MODE(di)) {
+ di->dmadesc_align = D64RINGALIGN_BITS;
+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
+ /* for smaller dd table, HW relax the alignment requirement */
+ di->dmadesc_align = D64RINGALIGN_BITS - 1;
+ }
+ } else
+ di->dmadesc_align = D32RINGALIGN_BITS;
+ } else
+ di->dmadesc_align = 4; /* 16 byte alignment */
+
+ DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
+ di->aligndesc_4k, di->dmadesc_align));
+
+ /* allocate tx packet pointer vector */
+ if (ntxd) {
+ size = ntxd * sizeof(void *);
+ di->txp = MALLOC(osh, size);
+ if (di->txp == NULL) {
+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
+ goto fail;
+ }
+ bzero((char *)di->txp, size);
+ }
+
+ /* allocate rx packet pointer vector */
+ if (nrxd) {
+ size = nrxd * sizeof(void *);
+ di->rxp = MALLOC(osh, size);
+ if (di->rxp == NULL) {
+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
+ goto fail;
+ }
+ bzero((char *)di->rxp, size);
+ }
+
+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+ if (ntxd) {
+ if (!_dma_alloc(di, DMA_TX))
+ goto fail;
+ }
+
+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+ if (nrxd) {
+ if (!_dma_alloc(di, DMA_RX))
+ goto fail;
+ }
+
+ if ((di->ddoffsetlow != 0) && !di->addrext) {
+ if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
+ DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (uint32) PHYSADDRLO(di->txdpa)));
+ goto fail;
+ }
+ if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (uint32) PHYSADDRLO(di->rxdpa)));
+ goto fail;
+ }
+ }
+
+ DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+
+ /* allocate DMA mapping vectors */
+ if (DMASGLIST_ENAB) {
+ if (ntxd) {
+ size = ntxd * sizeof(hnddma_seg_map_t);
+ di->txp_dmah = (hnddma_seg_map_t *) MALLOC(osh, size);
+ if (di->txp_dmah == NULL)
+ goto fail;
+ bzero((char *)di->txp_dmah, size);
+ }
+
+ if (nrxd) {
+ size = nrxd * sizeof(hnddma_seg_map_t);
+ di->rxp_dmah = (hnddma_seg_map_t *) MALLOC(osh, size);
+ if (di->rxp_dmah == NULL)
+ goto fail;
+ bzero((char *)di->rxp_dmah, size);
+ }
+ }
+
+ return (hnddma_t *) di;
+
+ fail:
+ _dma_detach(di);
+ return NULL;
+}
+
+/* init the tx or rx descriptor */
+static INLINE void
+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, dmaaddr_t pa, uint outidx,
+ uint32 *flags, uint32 bufcount)
+{
+ /* dma32 uses 32-bit control to fit both flags and bufcounter */
+ *flags = *flags | (bufcount & CTRL_BC_MASK);
+
+ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+ W_SM(&ddring[outidx].addr,
+ BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
+ } else {
+ /* address extension */
+ uint32 ae;
+ ASSERT(di->addrext);
+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+
+ *flags |= (ae << CTRL_AE_SHIFT);
+ W_SM(&ddring[outidx].addr,
+ BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags));
+ }
+}
+
+/* Check for odd number of 1's */
+STATIC INLINE uint32 parity32(uint32 data)
+{
+ data ^= data >> 16;
+ data ^= data >> 8;
+ data ^= data >> 4;
+ data ^= data >> 2;
+ data ^= data >> 1;
+
+ return data & 1;
+}
+
+#define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
+
+static INLINE void
+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
+ uint32 *flags, uint32 bufcount)
+{
+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+
+ /* PCI bus with big(>1G) physical address, use address extension */
+#if defined(__mips__) && defined(IL_BIGENDIAN)
+ if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
+ || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+#else
+ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */
+ ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0);
+
+ W_SM(&ddring[outidx].addrlow,
+ BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+ W_SM(&ddring[outidx].addrhigh,
+ BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+ } else {
+ /* address extension for 32-bit PCI */
+ uint32 ae;
+ ASSERT(di->addrext);
+
+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+ ASSERT(PHYSADDRHI(pa) == 0);
+
+ ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+ W_SM(&ddring[outidx].addrlow,
+ BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+ W_SM(&ddring[outidx].addrhigh,
+ BUS_SWAP32(0 + di->dataoffsethigh));
+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+ }
+ if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
+ if (DMA64_DD_PARITY(&ddring[outidx])) {
+ W_SM(&ddring[outidx].ctrl2,
+ BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
+ }
+ }
+}
+
+static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs)
+{
+ uint32 w;
+
+ OR_REG(osh, &dma32regs->control, XC_AE);
+ w = R_REG(osh, &dma32regs->control);
+ AND_REG(osh, &dma32regs->control, ~XC_AE);
+ return (w & XC_AE) == XC_AE;
+}
+
+static bool _dma_alloc(dma_info_t *di, uint direction)
+{
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ return dma64_alloc(di, direction);
+ } else if (DMA32_ENAB(di)) {
+ return dma32_alloc(di, direction);
+ } else
+ ASSERT(0);
+}
+
+/* !! may be called with core in reset */
+static void _dma_detach(dma_info_t *di)
+{
+
+ DMA_TRACE(("%s: dma_detach\n", di->name));
+
+ /* shouldn't be here if descriptors are unreclaimed */
+ ASSERT(di->txin == di->txout);
+ ASSERT(di->rxin == di->rxout);
+
+ /* free dma descriptor rings */
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ if (di->txd64)
+ DMA_FREE_CONSISTENT(di->osh,
+ ((int8 *) (uintptr) di->txd64 -
+ di->txdalign), di->txdalloc,
+ (di->txdpaorig), &di->tx_dmah);
+ if (di->rxd64)
+ DMA_FREE_CONSISTENT(di->osh,
+ ((int8 *) (uintptr) di->rxd64 -
+ di->rxdalign), di->rxdalloc,
+ (di->rxdpaorig), &di->rx_dmah);
+ } else if (DMA32_ENAB(di)) {
+ if (di->txd32)
+ DMA_FREE_CONSISTENT(di->osh,
+ ((int8 *) (uintptr) di->txd32 -
+ di->txdalign), di->txdalloc,
+ (di->txdpaorig), &di->tx_dmah);
+ if (di->rxd32)
+ DMA_FREE_CONSISTENT(di->osh,
+ ((int8 *) (uintptr) di->rxd32 -
+ di->rxdalign), di->rxdalloc,
+ (di->rxdpaorig), &di->rx_dmah);
+ } else
+ ASSERT(0);
+
+ /* free packet pointer vectors */
+ if (di->txp)
+ MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *)));
+ if (di->rxp)
+ MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *)));
+
+ /* free tx packet DMA handles */
+ if (di->txp_dmah)
+ MFREE(di->osh, (void *)di->txp_dmah,
+ di->ntxd * sizeof(hnddma_seg_map_t));
+
+ /* free rx packet DMA handles */
+ if (di->rxp_dmah)
+ MFREE(di->osh, (void *)di->rxp_dmah,
+ di->nrxd * sizeof(hnddma_seg_map_t));
+
+ /* free our private info structure */
+ MFREE(di->osh, (void *)di, sizeof(dma_info_t));
+
+}
+
+static bool _dma_descriptor_align(dma_info_t *di)
+{
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ uint32 addrl;
+
+ /* Check to see if the descriptors need to be aligned on 4K/8K or not */
+ if (di->d64txregs != NULL) {
+ W_REG(di->osh, &di->d64txregs->addrlow, 0xff0);
+ addrl = R_REG(di->osh, &di->d64txregs->addrlow);
+ if (addrl != 0)
+ return FALSE;
+ } else if (di->d64rxregs != NULL) {
+ W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0);
+ addrl = R_REG(di->osh, &di->d64rxregs->addrlow);
+ if (addrl != 0)
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
+static bool _dma_isaddrext(dma_info_t *di)
+{
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ /* DMA64 supports full 32- or 64-bit operation. AE is always valid */
+
+ /* not all tx or rx channel are available */
+ if (di->d64txregs != NULL) {
+ if (!_dma64_addrext(di->osh, di->d64txregs)) {
+ DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name));
+ ASSERT(0);
+ }
+ return TRUE;
+ } else if (di->d64rxregs != NULL) {
+ if (!_dma64_addrext(di->osh, di->d64rxregs)) {
+ DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name));
+ ASSERT(0);
+ }
+ return TRUE;
+ }
+ return FALSE;
+ } else if (DMA32_ENAB(di)) {
+ if (di->d32txregs)
+ return _dma32_addrext(di->osh, di->d32txregs);
+ else if (di->d32rxregs)
+ return _dma32_addrext(di->osh, di->d32rxregs);
+ } else
+ ASSERT(0);
+
+ return FALSE;
+}
+
+/* initialize descriptor table base address */
+static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
+{
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ if (!di->aligndesc_4k) {
+ if (direction == DMA_TX)
+ di->xmtptrbase = PHYSADDRLO(pa);
+ else
+ di->rcvptrbase = PHYSADDRLO(pa);
+ }
+
+ if ((di->ddoffsetlow == 0)
+ || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+ if (direction == DMA_TX) {
+ W_REG(di->osh, &di->d64txregs->addrlow,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ W_REG(di->osh, &di->d64txregs->addrhigh,
+ (PHYSADDRHI(pa) + di->ddoffsethigh));
+ } else {
+ W_REG(di->osh, &di->d64rxregs->addrlow,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ W_REG(di->osh, &di->d64rxregs->addrhigh,
+ (PHYSADDRHI(pa) + di->ddoffsethigh));
+ }
+ } else {
+ /* DMA64 32bits address extension */
+ uint32 ae;
+ ASSERT(di->addrext);
+ ASSERT(PHYSADDRHI(pa) == 0);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
+ PCI32ADDR_HIGH_SHIFT;
+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX) {
+ W_REG(di->osh, &di->d64txregs->addrlow,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ W_REG(di->osh, &di->d64txregs->addrhigh,
+ di->ddoffsethigh);
+ SET_REG(di->osh, &di->d64txregs->control,
+ D64_XC_AE, (ae << D64_XC_AE_SHIFT));
+ } else {
+ W_REG(di->osh, &di->d64rxregs->addrlow,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ W_REG(di->osh, &di->d64rxregs->addrhigh,
+ di->ddoffsethigh);
+ SET_REG(di->osh, &di->d64rxregs->control,
+ D64_RC_AE, (ae << D64_RC_AE_SHIFT));
+ }
+ }
+
+ } else if (DMA32_ENAB(di)) {
+ ASSERT(PHYSADDRHI(pa) == 0);
+ if ((di->ddoffsetlow == 0)
+ || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+ if (direction == DMA_TX)
+ W_REG(di->osh, &di->d32txregs->addr,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ else
+ W_REG(di->osh, &di->d32rxregs->addr,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ } else {
+ /* dma32 address extension */
+ uint32 ae;
+ ASSERT(di->addrext);
+
+ /* shift the high bit(s) from pa to ae */
+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
+ PCI32ADDR_HIGH_SHIFT;
+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+
+ if (direction == DMA_TX) {
+ W_REG(di->osh, &di->d32txregs->addr,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ SET_REG(di->osh, &di->d32txregs->control, XC_AE,
+ ae << XC_AE_SHIFT);
+ } else {
+ W_REG(di->osh, &di->d32rxregs->addr,
+ (PHYSADDRLO(pa) + di->ddoffsetlow));
+ SET_REG(di->osh, &di->d32rxregs->control, RC_AE,
+ ae << RC_AE_SHIFT);
+ }
+ }
+ } else
+ ASSERT(0);
+}
+
+static void _dma_fifoloopbackenable(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di))
+ OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE);
+ else if (DMA32_ENAB(di))
+ OR_REG(di->osh, &di->d32txregs->control, XC_LE);
+ else
+ ASSERT(0);
+}
+
+static void _dma_rxinit(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_rxinit\n", di->name));
+
+ if (di->nrxd == 0)
+ return;
+
+ di->rxin = di->rxout = 0;
+
+ /* clear rx descriptor ring */
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ BZERO_SM((void *)(uintptr) di->rxd64,
+ (di->nrxd * sizeof(dma64dd_t)));
+
+ /* DMA engine with out alignment requirement requires table to be inited
+ * before enabling the engine
+ */
+ if (!di->aligndesc_4k)
+ _dma_ddtable_init(di, DMA_RX, di->rxdpa);
+
+ _dma_rxenable(di);
+
+ if (di->aligndesc_4k)
+ _dma_ddtable_init(di, DMA_RX, di->rxdpa);
+ } else if (DMA32_ENAB(di)) {
+ BZERO_SM((void *)(uintptr) di->rxd32,
+ (di->nrxd * sizeof(dma32dd_t)));
+ _dma_rxenable(di);
+ _dma_ddtable_init(di, DMA_RX, di->rxdpa);
+ } else
+ ASSERT(0);
+}
+
+static void _dma_rxenable(dma_info_t *di)
+{
+ uint dmactrlflags = di->hnddma.dmactrlflags;
+
+ DMA_TRACE(("%s: dma_rxenable\n", di->name));
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ uint32 control =
+ (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) |
+ D64_RC_RE;
+
+ if ((dmactrlflags & DMA_CTRL_PEN) == 0)
+ control |= D64_RC_PD;
+
+ if (dmactrlflags & DMA_CTRL_ROC)
+ control |= D64_RC_OC;
+
+ W_REG(di->osh, &di->d64rxregs->control,
+ ((di->rxoffset << D64_RC_RO_SHIFT) | control));
+ } else if (DMA32_ENAB(di)) {
+ uint32 control =
+ (R_REG(di->osh, &di->d32rxregs->control) & RC_AE) | RC_RE;
+
+ if ((dmactrlflags & DMA_CTRL_PEN) == 0)
+ control |= RC_PD;
+
+ if (dmactrlflags & DMA_CTRL_ROC)
+ control |= RC_OC;
+
+ W_REG(di->osh, &di->d32rxregs->control,
+ ((di->rxoffset << RC_RO_SHIFT) | control));
+ } else
+ ASSERT(0);
+}
+
+static void
+_dma_rx_param_get(dma_info_t *di, uint16 *rxoffset, uint16 *rxbufsize)
+{
+ /* the normal values fit into 16 bits */
+ *rxoffset = (uint16) di->rxoffset;
+ *rxbufsize = (uint16) di->rxbufsize;
+}
+
+/* !! rx entry routine
+ * returns a pointer to the next frame received, or NULL if there are no more
+ * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
+ * with pkts chain
+ * otherwise, it's treated as giant pkt and will be tossed.
+ * The DMA scattering starts with normal DMA header, followed by first buffer data.
+ * After it reaches the max size of buffer, the data continues in next DMA descriptor
+ * buffer WITHOUT DMA header
+ */
+static void *BCMFASTPATH _dma_rx(dma_info_t *di)
+{
+ void *p, *head, *tail;
+ uint len;
+ uint pkt_len;
+ int resid = 0;
+
+ next_frame:
+ head = _dma_getnextrxp(di, FALSE);
+ if (head == NULL)
+ return NULL;
+
+ len = ltoh16(*(uint16 *) (PKTDATA(head)));
+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
+
+#if defined(__mips__)
+ if (!len) {
+ while (!(len = *(uint16 *) OSL_UNCACHED(PKTDATA(head))))
+ OSL_DELAY(1);
+
+ *(uint16 *) PKTDATA(head) = htol16((uint16) len);
+ }
+#endif /* defined(__mips__) */
+
+ /* set actual length */
+ pkt_len = MIN((di->rxoffset + len), di->rxbufsize);
+ PKTSETLEN(head, pkt_len);
+ resid = len - (di->rxbufsize - di->rxoffset);
+
+ /* check for single or multi-buffer rx */
+ if (resid > 0) {
+ tail = head;
+ while ((resid > 0) && (p = _dma_getnextrxp(di, FALSE))) {
+ PKTSETNEXT(tail, p);
+ pkt_len = MIN(resid, (int)di->rxbufsize);
+ PKTSETLEN(p, pkt_len);
+
+ tail = p;
+ resid -= di->rxbufsize;
+ }
+
+#ifdef BCMDBG
+ if (resid > 0) {
+ uint cur;
+ ASSERT(p == NULL);
+ cur = (DMA64_ENAB(di) && DMA64_MODE(di)) ?
+ B2I(((R_REG(di->osh, &di->d64rxregs->status0) &
+ D64_RS0_CD_MASK) -
+ di->rcvptrbase) & D64_RS0_CD_MASK,
+ dma64dd_t) : B2I(R_REG(di->osh,
+ &di->d32rxregs->
+ status) & RS_CD_MASK,
+ dma32dd_t);
+ DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
+ di->rxin, di->rxout, cur));
+ }
+#endif /* BCMDBG */
+
+ if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
+ di->name, len));
+ PKTFREE(di->osh, head, FALSE);
+ di->hnddma.rxgiants++;
+ goto next_frame;
+ }
+ }
+
+ return head;
+}
+
+/* post receive buffers
+ * return FALSE is refill failed completely and ring is empty
+ * this will stall the rx dma and user might want to call rxfill again asap
+ * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
+ */
+static bool BCMFASTPATH _dma_rxfill(dma_info_t *di)
+{
+ void *p;
+ uint16 rxin, rxout;
+ uint32 flags = 0;
+ uint n;
+ uint i;
+ dmaaddr_t pa;
+ uint extra_offset = 0;
+ bool ring_empty;
+
+ ring_empty = FALSE;
+
+ /*
+ * Determine how many receive buffers we're lacking
+ * from the full complement, allocate, initialize,
+ * and post them, then update the chip rx lastdscr.
+ */
+
+ rxin = di->rxin;
+ rxout = di->rxout;
+
+ n = di->nrxpost - NRXDACTIVE(rxin, rxout);
+
+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
+
+ if (di->rxbufsize > BCMEXTRAHDROOM)
+ extra_offset = di->rxextrahdrroom;
+
+ for (i = 0; i < n; i++) {
+ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+ size to be allocated
+ */
+
+ p = osl_pktget(di->osh, di->rxbufsize + extra_offset);
+
+ if (p == NULL) {
+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
+ di->name));
+ if (i == 0) {
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ if (dma64_rxidle(di)) {
+ DMA_ERROR(("%s: rxfill64: ring is empty !\n", di->name));
+ ring_empty = TRUE;
+ }
+ } else if (DMA32_ENAB(di)) {
+ if (dma32_rxidle(di)) {
+ DMA_ERROR(("%s: rxfill32: ring is empty !\n", di->name));
+ ring_empty = TRUE;
+ }
+ } else
+ ASSERT(0);
+ }
+ di->hnddma.rxnobuf++;
+ break;
+ }
+ /* reserve an extra headroom, if applicable */
+ if (extra_offset)
+ PKTPULL(p, extra_offset);
+
+ /* Do a cached write instead of uncached write since DMA_MAP
+ * will flush the cache.
+ */
+ *(uint32 *) (PKTDATA(p)) = 0;
+
+ if (DMASGLIST_ENAB)
+ bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t));
+
+ pa = DMA_MAP(di->osh, PKTDATA(p),
+ di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]);
+
+ ASSERT(ISALIGNED(PHYSADDRLO(pa), 4));
+
+ /* save the free packet pointer */
+ ASSERT(di->rxp[rxout] == NULL);
+ di->rxp[rxout] = p;
+
+ /* reset flags for each descriptor */
+ flags = 0;
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ if (rxout == (di->nrxd - 1))
+ flags = D64_CTRL1_EOT;
+
+ dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
+ di->rxbufsize);
+ } else if (DMA32_ENAB(di)) {
+ if (rxout == (di->nrxd - 1))
+ flags = CTRL_EOT;
+
+ ASSERT(PHYSADDRHI(pa) == 0);
+ dma32_dd_upd(di, di->rxd32, pa, rxout, &flags,
+ di->rxbufsize);
+ } else
+ ASSERT(0);
+ rxout = NEXTRXD(rxout);
+ }
+
+ di->rxout = rxout;
+
+ /* update the chip lastdscr pointer */
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ W_REG(di->osh, &di->d64rxregs->ptr,
+ di->rcvptrbase + I2B(rxout, dma64dd_t));
+ } else if (DMA32_ENAB(di)) {
+ W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
+ } else
+ ASSERT(0);
+
+ return ring_empty;
+}
+
+/* like getnexttxp but no reclaim */
+static void *_dma_peeknexttxp(dma_info_t *di)
+{
+ uint end, i;
+
+ if (di->ntxd == 0)
+ return NULL;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ end =
+ B2I(((R_REG(di->osh, &di->d64txregs->status0) &
+ D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+ dma64dd_t);
+ } else if (DMA32_ENAB(di)) {
+ end =
+ B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK,
+ dma32dd_t);
+ } else
+ ASSERT(0);
+
+ for (i = di->txin; i != end; i = NEXTTXD(i))
+ if (di->txp[i])
+ return di->txp[i];
+
+ return NULL;
+}
+
+/* like getnextrxp but not take off the ring */
+static void *_dma_peeknextrxp(dma_info_t *di)
+{
+ uint end, i;
+
+ if (di->nrxd == 0)
+ return NULL;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ end =
+ B2I(((R_REG(di->osh, &di->d64rxregs->status0) &
+ D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
+ dma64dd_t);
+ } else if (DMA32_ENAB(di)) {
+ end =
+ B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK,
+ dma32dd_t);
+ } else
+ ASSERT(0);
+
+ for (i = di->rxin; i != end; i = NEXTRXD(i))
+ if (di->rxp[i])
+ return di->rxp[i];
+
+ return NULL;
+}
+
+static void _dma_rxreclaim(dma_info_t *di)
+{
+ void *p;
+
+ /* "unused local" warning suppression for OSLs that
+ * define PKTFREE() without using the di->osh arg
+ */
+ di = di;
+
+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+
+ while ((p = _dma_getnextrxp(di, TRUE)))
+ PKTFREE(di->osh, p, FALSE);
+}
+
+static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall)
+{
+ if (di->nrxd == 0)
+ return NULL;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ return dma64_getnextrxp(di, forceall);
+ } else if (DMA32_ENAB(di)) {
+ return dma32_getnextrxp(di, forceall);
+ } else
+ ASSERT(0);
+}
+
+static void _dma_txblock(dma_info_t *di)
+{
+ di->hnddma.txavail = 0;
+}
+
+static void _dma_txunblock(dma_info_t *di)
+{
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+}
+
+static uint _dma_txactive(dma_info_t *di)
+{
+ return NTXDACTIVE(di->txin, di->txout);
+}
+
+static uint _dma_txpending(dma_info_t *di)
+{
+ uint curr;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ curr =
+ B2I(((R_REG(di->osh, &di->d64txregs->status0) &
+ D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+ dma64dd_t);
+ } else if (DMA32_ENAB(di)) {
+ curr =
+ B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK,
+ dma32dd_t);
+ } else
+ ASSERT(0);
+
+ return NTXDACTIVE(curr, di->txout);
+}
+
+static uint _dma_txcommitted(dma_info_t *di)
+{
+ uint ptr;
+ uint txin = di->txin;
+
+ if (txin == di->txout)
+ return 0;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t);
+ } else if (DMA32_ENAB(di)) {
+ ptr = B2I(R_REG(di->osh, &di->d32txregs->ptr), dma32dd_t);
+ } else
+ ASSERT(0);
+
+ return NTXDACTIVE(di->txin, ptr);
+}
+
+static uint _dma_rxactive(dma_info_t *di)
+{
+ return NRXDACTIVE(di->rxin, di->rxout);
+}
+
+static void _dma_counterreset(dma_info_t *di)
+{
+ /* reset all software counter */
+ di->hnddma.rxgiants = 0;
+ di->hnddma.rxnobuf = 0;
+ di->hnddma.txnobuf = 0;
+}
+
+static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
+{
+ uint dmactrlflags = di->hnddma.dmactrlflags;
+
+ if (di == NULL) {
+ DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+ return 0;
+ }
+
+ ASSERT((flags & ~mask) == 0);
+
+ dmactrlflags &= ~mask;
+ dmactrlflags |= flags;
+
+ /* If trying to enable parity, check if parity is actually supported */
+ if (dmactrlflags & DMA_CTRL_PEN) {
+ uint32 control;
+
+ if (DMA64_ENAB(di) && DMA64_MODE(di)) {
+ control = R_REG(di->osh, &di->d64txregs->control);
+ W_REG(di->osh, &di->d64txregs->control,
+ control | D64_XC_PD);
+ if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) {
+ /* We *can* disable it so it is supported,
+ * restore control register
+ */
+ W_REG(di->osh, &di->d64txregs->control,
+ control);
+ } else {
+ /* Not supported, don't allow it to be enabled */
+ dmactrlflags &= ~DMA_CTRL_PEN;
+ }
+ } else if (DMA32_ENAB(di)) {
+ control = R_REG(di->osh, &di->d32txregs->control);
+ W_REG(di->osh, &di->d32txregs->control,
+ control | XC_PD);
+ if (R_REG(di->osh, &di->d32txregs->control) & XC_PD) {
+ W_REG(di->osh, &di->d32txregs->control,
+ control);
+ } else {
+ /* Not supported, don't allow it to be enabled */
+ dmactrlflags &= ~DMA_CTRL_PEN;
+ }
+ } else
+ ASSERT(0);
+ }
+
+ di->hnddma.dmactrlflags = dmactrlflags;
+
+ return dmactrlflags;
+}
+
+/* get the address of the var in order to change later */
+static uintptr _dma_getvar(dma_info_t *di, const char *name)
+{
+ if (!strcmp(name, "&txavail"))
+ return (uintptr) &(di->hnddma.txavail);
+ else {
+ ASSERT(0);
+ }
+ return 0;
+}
+
+void dma_txpioloopback(osl_t *osh, dma32regs_t *regs)
+{
+ OR_REG(osh, &regs->control, XC_LE);
+}
+
+static
+uint8 dma_align_sizetobits(uint size)
+{
+ uint8 bitpos = 0;
+ ASSERT(size);
+ ASSERT(!(size & (size - 1)));
+ while (size >>= 1) {
+ bitpos++;
+ }
+ return bitpos;
+}
+
+/* This function ensures that the DMA descriptor ring will not get allocated
+ * across Page boundary. If the allocation is done across the page boundary
+ * at the first time, then it is freed and the allocation is done at
+ * descriptor ring size aligned location. This will ensure that the ring will
+ * not cross page boundary
+ */
+static void *dma_ringalloc(osl_t *osh, uint32 boundary, uint size,
+ uint16 *alignbits, uint *alloced,
+ dmaaddr_t *descpa, osldma_t **dmah)
+{
+ void *va;
+ uint32 desc_strtaddr;
+ uint32 alignbytes = 1 << *alignbits;
+
+ va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa,
+ dmah);
+ if (NULL == va)
+ return NULL;
+
+ desc_strtaddr = (uint32) ROUNDUP((uintptr) va, alignbytes);
+ if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
+ & boundary)) {
+ *alignbits = dma_align_sizetobits(size);
+ DMA_FREE_CONSISTENT(osh, va, size, *descpa, dmah);
+ va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced,
+ descpa, dmah);
+ }
+ return va;
+}
+
+/* 32-bit DMA functions */
+
+static void dma32_txinit(dma_info_t *di)
+{
+ uint32 control = XC_XE;
+
+ DMA_TRACE(("%s: dma_txinit\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
+
+ /* clear tx descriptor ring */
+ BZERO_SM((void *)(uintptr) di->txd32, (di->ntxd * sizeof(dma32dd_t)));
+
+ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
+ control |= XC_PD;
+ W_REG(di->osh, &di->d32txregs->control, control);
+ _dma_ddtable_init(di, DMA_TX, di->txdpa);
+}
+
+static bool dma32_txenabled(dma_info_t *di)
+{
+ uint32 xc;
+
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG(di->osh, &di->d32txregs->control);
+ return (xc != 0xffffffff) && (xc & XC_XE);
+}
+
+static void dma32_txsuspend(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ OR_REG(di->osh, &di->d32txregs->control, XC_SE);
+}
+
+static void dma32_txresume(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_txresume\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ AND_REG(di->osh, &di->d32txregs->control, ~XC_SE);
+}
+
+static bool dma32_txsuspended(dma_info_t *di)
+{
+ return (di->ntxd == 0)
+ || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE);
+}
+
+static void dma32_txreclaim(dma_info_t *di, txd_range_t range)
+{
+ void *p;
+
+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
+ (range == HNDDMA_RANGE_ALL) ? "all" :
+ ((range ==
+ HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+ "transfered")));
+
+ if (di->txin == di->txout)
+ return;
+
+ while ((p = dma32_getnexttxp(di, range)))
+ PKTFREE(di->osh, p, TRUE);
+}
+
+static bool dma32_txstopped(dma_info_t *di)
+{
+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_STOPPED);
+}
+
+static bool dma32_rxstopped(dma_info_t *di)
+{
+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) ==
+ RS_RS_STOPPED);
+}
+
+static bool dma32_alloc(dma_info_t *di, uint direction)
+{
+ uint size;
+ uint ddlen;
+ void *va;
+ uint alloced;
+ uint16 align;
+ uint16 align_bits;
+
+ ddlen = sizeof(dma32dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+
+ alloced = 0;
+ align_bits = di->dmadesc_align;
+ align = (1 << align_bits);
+
+ if (direction == DMA_TX) {
+ va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits,
+ &alloced, &di->txdpaorig, &di->tx_dmah);
+ if (va == NULL) {
+ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
+ return FALSE;
+ }
+
+ PHYSADDRHISET(di->txdpa, 0);
+ ASSERT(PHYSADDRHI(di->txdpaorig) == 0);
+ di->txd32 = (dma32dd_t *) ROUNDUP((uintptr) va, align);
+ di->txdalign =
+ (uint) ((int8 *) (uintptr) di->txd32 - (int8 *) va);
+
+ PHYSADDRLOSET(di->txdpa,
+ PHYSADDRLO(di->txdpaorig) + di->txdalign);
+ /* Make sure that alignment didn't overflow */
+ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig));
+
+ di->txdalloc = alloced;
+ ASSERT(ISALIGNED((uintptr) di->txd32, align));
+ } else {
+ va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits,
+ &alloced, &di->rxdpaorig, &di->rx_dmah);
+ if (va == NULL) {
+ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
+ return FALSE;
+ }
+
+ PHYSADDRHISET(di->rxdpa, 0);
+ ASSERT(PHYSADDRHI(di->rxdpaorig) == 0);
+ di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr) va, align);
+ di->rxdalign =
+ (uint) ((int8 *) (uintptr) di->rxd32 - (int8 *) va);
+
+ PHYSADDRLOSET(di->rxdpa,
+ PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
+ /* Make sure that alignment didn't overflow */
+ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig));
+ di->rxdalloc = alloced;
+ ASSERT(ISALIGNED((uintptr) di->rxd32, align));
+ }
+
+ return TRUE;
+}
+
+static bool dma32_txreset(dma_info_t *di)
+{
+ uint32 status;
+
+ if (di->ntxd == 0)
+ return TRUE;
+
+ /* suspend tx DMA first */
+ W_REG(di->osh, &di->d32txregs->control, XC_SE);
+ SPINWAIT(((status =
+ (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK))
+ != XS_XS_DISABLED) && (status != XS_XS_IDLE)
+ && (status != XS_XS_STOPPED), (10000));
+
+ W_REG(di->osh, &di->d32txregs->control, 0);
+ SPINWAIT(((status = (R_REG(di->osh,
+ &di->d32txregs->status) & XS_XS_MASK)) !=
+ XS_XS_DISABLED), 10000);
+
+ /* wait for the last transaction to complete */
+ OSL_DELAY(300);
+
+ return status == XS_XS_DISABLED;
+}
+
+static bool dma32_rxidle(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_rxidle\n", di->name));
+
+ if (di->nrxd == 0)
+ return TRUE;
+
+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) ==
+ R_REG(di->osh, &di->d32rxregs->ptr));
+}
+
+static bool dma32_rxreset(dma_info_t *di)
+{
+ uint32 status;
+
+ if (di->nrxd == 0)
+ return TRUE;
+
+ W_REG(di->osh, &di->d32rxregs->control, 0);
+ SPINWAIT(((status = (R_REG(di->osh,
+ &di->d32rxregs->status) & RS_RS_MASK)) !=
+ RS_RS_DISABLED), 10000);
+
+ return status == RS_RS_DISABLED;
+}
+
+static bool dma32_rxenabled(dma_info_t *di)
+{
+ uint32 rc;
+
+ rc = R_REG(di->osh, &di->d32rxregs->control);
+ return (rc != 0xffffffff) && (rc & RC_RE);
+}
+
+static bool dma32_txsuspendedidle(dma_info_t *di)
+{
+ if (di->ntxd == 0)
+ return TRUE;
+
+ if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE))
+ return 0;
+
+ if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
+ return 0;
+
+ OSL_DELAY(2);
+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) ==
+ XS_XS_IDLE);
+}
+
+/* !! tx entry routine
+ * supports full 32bit dma engine buffer addressing so
+ * dma buffers can cross 4 Kbyte page boundaries.
+ *
+ * WARNING: call must check the return value for error.
+ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems
+ */
+static int dma32_txfast(dma_info_t *di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint16 txout;
+ uint32 flags = 0;
+ dmaaddr_t pa;
+
+ DMA_TRACE(("%s: dma_txfast\n", di->name));
+
+ txout = di->txout;
+
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next) {
+ uint nsegs, j;
+ hnddma_seg_map_t *map;
+
+ data = PKTDATA(p);
+ len = PKTLEN(p);
+#ifdef BCM_DMAPAD
+ len += PKTDMAPAD(di->osh, p);
+#endif
+ next = PKTNEXT(p);
+
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD(txout) == di->txin)
+ goto outoftxd;
+
+ if (len == 0)
+ continue;
+
+ if (DMASGLIST_ENAB)
+ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t));
+
+ /* get physical address of buffer start */
+ pa = DMA_MAP(di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ if (DMASGLIST_ENAB) {
+ map = &di->txp_dmah[txout];
+
+ /* See if all the segments can be accounted for */
+ if (map->nsegs >
+ (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
+ 1))
+ goto outoftxd;
+
+ nsegs = map->nsegs;
+ } else
+ nsegs = 1;
+
+ for (j = 1; j <= nsegs; j++) {
+ flags = 0;
+ if (p == p0 && j == 1)
+ flags |= CTRL_SOF;
+
+ /* With a DMA segment list, Descriptor table is filled
+ * using the segment list instead of looping over
+ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
+ * end of segment list is reached.
+ */
+ if ((!DMASGLIST_ENAB && next == NULL) ||
+ (DMASGLIST_ENAB && j == nsegs))
+ flags |= (CTRL_IOC | CTRL_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= CTRL_EOT;
+
+ if (DMASGLIST_ENAB) {
+ len = map->segs[j - 1].length;
+ pa = map->segs[j - 1].addr;
+ }
+ ASSERT(PHYSADDRHI(pa) == 0);
+
+ dma32_dd_upd(di, di->txd32, pa, txout, &flags, len);
+ ASSERT(di->txp[txout] == NULL);
+
+ txout = NEXTTXD(txout);
+ }
+
+ /* See above. No need to loop over individual buffers */
+ if (DMASGLIST_ENAB)
+ break;
+ }
+
+ /* if last txd eof not set, fix it */
+ if (!(flags & CTRL_EOF))
+ W_SM(&di->txd32[PREVTXD(txout)].ctrl,
+ BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF));
+
+ /* save the packet */
+ di->txp[PREVTXD(txout)] = p0;
+
+ /* bump the tx descriptor index */
+ di->txout = txout;
+
+ /* kick the chip */
+ if (commit)
+ W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ return 0;
+
+ outoftxd:
+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
+ PKTFREE(di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return -1;
+}
+
+/*
+ * Reclaim next completed txd (txds if using chained buffers) in the range
+ * specified and return associated packet.
+ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
+ * transmitted as noted by the hardware "CurrDescr" pointer.
+ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
+ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer.
+ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
+ * return associated packet regardless of the value of hardware pointers.
+ */
+static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range)
+{
+ uint16 start, end, i;
+ uint16 active_desc;
+ void *txp;
+
+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
+ (range == HNDDMA_RANGE_ALL) ? "all" :
+ ((range ==
+ HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+ "transfered")));
+
+ if (di->ntxd == 0)
+ return NULL;
+
+ txp = NULL;
+
+ start = di->txin;
+ if (range == HNDDMA_RANGE_ALL)
+ end = di->txout;
+ else {
+ dma32regs_t *dregs = di->d32txregs;
+
+ end =
+ (uint16) B2I(R_REG(di->osh, &dregs->status) & XS_CD_MASK,
+ dma32dd_t);
+
+ if (range == HNDDMA_RANGE_TRANSFERED) {
+ active_desc =
+ (uint16) ((R_REG(di->osh, &dregs->status) &
+ XS_AD_MASK) >> XS_AD_SHIFT);
+ active_desc = (uint16) B2I(active_desc, dma32dd_t);
+ if (end != active_desc)
+ end = PREVTXD(active_desc);
+ }
+ }
+
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
+
+ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
+ dmaaddr_t pa;
+ hnddma_seg_map_t *map = NULL;
+ uint size, j, nsegs;
+
+ PHYSADDRLOSET(pa,
+ (BUS_SWAP32(R_SM(&di->txd32[i].addr)) -
+ di->dataoffsetlow));
+ PHYSADDRHISET(pa, 0);
+
+ if (DMASGLIST_ENAB) {
+ map = &di->txp_dmah[i];
+ size = map->origsize;
+ nsegs = map->nsegs;
+ } else {
+ size =
+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) &
+ CTRL_BC_MASK);
+ nsegs = 1;
+ }
+
+ for (j = nsegs; j > 0; j--) {
+ W_SM(&di->txd32[i].addr, 0xdeadbeef);
+
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ if (j > 1)
+ i = NEXTTXD(i);
+ }
+
+ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map);
+ }
+
+ di->txin = i;
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ return txp;
+
+ bogus:
+ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
+ return NULL;
+}
+
+static void *dma32_getnextrxp(dma_info_t *di, bool forceall)
+{
+ uint i, curr;
+ void *rxp;
+ dmaaddr_t pa;
+ /* if forcing, dma engine must be disabled */
+ ASSERT(!forceall || !dma32_rxenabled(di));
+
+ i = di->rxin;
+
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return NULL;
+
+ curr =
+ B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t);
+
+ /* ignore curr if forceall */
+ if (!forceall && (i == curr))
+ return NULL;
+
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT(rxp);
+ di->rxp[i] = NULL;
+
+ PHYSADDRLOSET(pa,
+ (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) -
+ di->dataoffsetlow));
+ PHYSADDRHISET(pa, 0);
+
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
+
+ W_SM(&di->rxd32[i].addr, 0xdeadbeef);
+
+ di->rxin = NEXTRXD(i);
+
+ return rxp;
+}
+
+/*
+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
+ */
+static void dma32_txrotate(dma_info_t *di)
+{
+ uint16 ad;
+ uint nactive;
+ uint rot;
+ uint16 old, new;
+ uint32 w;
+ uint16 first, last;
+
+ ASSERT(dma32_txsuspendedidle(di));
+
+ nactive = _dma_txactive(di);
+ ad = (uint16) (B2I
+ (((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK)
+ >> XS_AD_SHIFT), dma32dd_t));
+ rot = TXD(ad - di->txin);
+
+ ASSERT(rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive)) {
+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD(di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
+ new = TXD(old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT;
+ if (new == (di->ntxd - 1))
+ w |= CTRL_EOT;
+ W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w));
+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT(di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+
+ /* Move the segment map as well */
+ if (DMASGLIST_ENAB) {
+ bcopy(&di->txp_dmah[old], &di->txp_dmah[new],
+ sizeof(hnddma_seg_map_t));
+ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t));
+ }
+
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD(di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t));
+}
+
+/* 64-bit DMA functions */
+
+static void dma64_txinit(dma_info_t *di)
+{
+ uint32 control = D64_XC_XE;
+
+ DMA_TRACE(("%s: dma_txinit\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ di->txin = di->txout = 0;
+ di->hnddma.txavail = di->ntxd - 1;
+
+ /* clear tx descriptor ring */
+ BZERO_SM((void *)(uintptr) di->txd64, (di->ntxd * sizeof(dma64dd_t)));
+
+ /* DMA engine with out alignment requirement requires table to be inited
+ * before enabling the engine
+ */
+ if (!di->aligndesc_4k)
+ _dma_ddtable_init(di, DMA_TX, di->txdpa);
+
+ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
+ control |= D64_XC_PD;
+ OR_REG(di->osh, &di->d64txregs->control, control);
+
+ /* DMA engine with alignment requirement requires table to be inited
+ * before enabling the engine
+ */
+ if (di->aligndesc_4k)
+ _dma_ddtable_init(di, DMA_TX, di->txdpa);
+}
+
+static bool dma64_txenabled(dma_info_t *di)
+{
+ uint32 xc;
+
+ /* If the chip is dead, it is not enabled :-) */
+ xc = R_REG(di->osh, &di->d64txregs->control);
+ return (xc != 0xffffffff) && (xc & D64_XC_XE);
+}
+
+static void dma64_txsuspend(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
+}
+
+static void dma64_txresume(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_txresume\n", di->name));
+
+ if (di->ntxd == 0)
+ return;
+
+ AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE);
+}
+
+static bool dma64_txsuspended(dma_info_t *di)
+{
+ return (di->ntxd == 0) ||
+ ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE) ==
+ D64_XC_SE);
+}
+
+static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range)
+{
+ void *p;
+
+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
+ (range == HNDDMA_RANGE_ALL) ? "all" :
+ ((range ==
+ HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+ "transfered")));
+
+ if (di->txin == di->txout)
+ return;
+
+ while ((p = dma64_getnexttxp(di, range))) {
+ /* For unframed data, we don't have any packets to free */
+ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
+ PKTFREE(di->osh, p, TRUE);
+ }
+}
+
+static bool dma64_txstopped(dma_info_t *di)
+{
+ return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_STOPPED);
+}
+
+static bool dma64_rxstopped(dma_info_t *di)
+{
+ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+ D64_RS0_RS_STOPPED);
+}
+
+static bool dma64_alloc(dma_info_t *di, uint direction)
+{
+ uint16 size;
+ uint ddlen;
+ void *va;
+ uint alloced = 0;
+ uint16 align;
+ uint16 align_bits;
+
+ ddlen = sizeof(dma64dd_t);
+
+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+ align_bits = di->dmadesc_align;
+ align = (1 << align_bits);
+
+ if (direction == DMA_TX) {
+ va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits,
+ &alloced, &di->txdpaorig, &di->tx_dmah);
+ if (va == NULL) {
+ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
+ return FALSE;
+ }
+ align = (1 << align_bits);
+ di->txd64 = (dma64dd_t *) ROUNDUP((uintptr) va, align);
+ di->txdalign =
+ (uint) ((int8 *) (uintptr) di->txd64 - (int8 *) va);
+ PHYSADDRLOSET(di->txdpa,
+ PHYSADDRLO(di->txdpaorig) + di->txdalign);
+ /* Make sure that alignment didn't overflow */
+ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig));
+
+ PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
+ di->txdalloc = alloced;
+ ASSERT(ISALIGNED((uintptr) di->txd64, align));
+ } else {
+ va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits,
+ &alloced, &di->rxdpaorig, &di->rx_dmah);
+ if (va == NULL) {
+ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
+ return FALSE;
+ }
+ align = (1 << align_bits);
+ di->rxd64 = (dma64dd_t *) ROUNDUP((uintptr) va, align);
+ di->rxdalign =
+ (uint) ((int8 *) (uintptr) di->rxd64 - (int8 *) va);
+ PHYSADDRLOSET(di->rxdpa,
+ PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
+ /* Make sure that alignment didn't overflow */
+ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig));
+
+ PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
+ di->rxdalloc = alloced;
+ ASSERT(ISALIGNED((uintptr) di->rxd64, align));
+ }
+
+ return TRUE;
+}
+
+static bool dma64_txreset(dma_info_t *di)
+{
+ uint32 status;
+
+ if (di->ntxd == 0)
+ return TRUE;
+
+ /* suspend tx DMA first */
+ W_REG(di->osh, &di->d64txregs->control, D64_XC_SE);
+ SPINWAIT(((status =
+ (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK))
+ != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+ && (status != D64_XS0_XS_STOPPED), 10000);
+
+ W_REG(di->osh, &di->d64txregs->control, 0);
+ SPINWAIT(((status =
+ (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK))
+ != D64_XS0_XS_DISABLED), 10000);
+
+ /* wait for the last transaction to complete */
+ OSL_DELAY(300);
+
+ return status == D64_XS0_XS_DISABLED;
+}
+
+static bool dma64_rxidle(dma_info_t *di)
+{
+ DMA_TRACE(("%s: dma_rxidle\n", di->name));
+
+ if (di->nrxd == 0)
+ return TRUE;
+
+ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+ (R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK));
+}
+
+static bool dma64_rxreset(dma_info_t *di)
+{
+ uint32 status;
+
+ if (di->nrxd == 0)
+ return TRUE;
+
+ W_REG(di->osh, &di->d64rxregs->control, 0);
+ SPINWAIT(((status =
+ (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK))
+ != D64_RS0_RS_DISABLED), 10000);
+
+ return status == D64_RS0_RS_DISABLED;
+}
+
+static bool dma64_rxenabled(dma_info_t *di)
+{
+ uint32 rc;
+
+ rc = R_REG(di->osh, &di->d64rxregs->control);
+ return (rc != 0xffffffff) && (rc & D64_RC_RE);
+}
+
+static bool dma64_txsuspendedidle(dma_info_t *di)
+{
+
+ if (di->ntxd == 0)
+ return TRUE;
+
+ if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE))
+ return 0;
+
+ if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+ D64_XS0_XS_IDLE)
+ return 1;
+
+ return 0;
+}
+
+/* Useful when sending unframed data. This allows us to get a progress report from the DMA.
+ * We return a pointer to the beginning of the DATA buffer of the current descriptor.
+ * If DMA is idle, we return NULL.
+ */
+static void *dma64_getpos(dma_info_t *di, bool direction)
+{
+ void *va;
+ bool idle;
+ uint32 cd_offset;
+
+ if (direction == DMA_TX) {
+ cd_offset =
+ R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK;
+ idle = !NTXDACTIVE(di->txin, di->txout);
+ va = di->txp[B2I(cd_offset, dma64dd_t)];
+ } else {
+ cd_offset =
+ R_REG(di->osh, &di->d64rxregs->status0) & D64_XS0_CD_MASK;
+ idle = !NRXDACTIVE(di->rxin, di->rxout);
+ va = di->rxp[B2I(cd_offset, dma64dd_t)];
+ }
+
+ /* If DMA is IDLE, return NULL */
+ if (idle) {
+ DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
+ va = NULL;
+ }
+
+ return va;
+}
+
+/* TX of unframed data
+ *
+ * Adds a DMA ring descriptor for the data pointed to by "buf".
+ * This is for DMA of a buffer of data and is unlike other hnddma TX functions
+ * that take a pointer to a "packet"
+ * Each call to this is results in a single descriptor being added for "len" bytes of
+ * data starting at "buf", it doesn't handle chained buffers.
+ */
+static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
+{
+ uint16 txout;
+ uint32 flags = 0;
+ dmaaddr_t pa; /* phys addr */
+
+ txout = di->txout;
+
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD(txout) == di->txin)
+ goto outoftxd;
+
+ if (len == 0)
+ return 0;
+
+ pa = DMA_MAP(di->osh, buf, len, DMA_TX, NULL, &di->txp_dmah[txout]);
+
+ flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
+
+ if (txout == (di->ntxd - 1))
+ flags |= D64_CTRL1_EOT;
+
+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+ ASSERT(di->txp[txout] == NULL);
+
+ /* save the buffer pointer - used by dma_getpos */
+ di->txp[txout] = buf;
+
+ txout = NEXTTXD(txout);
+ /* bump the tx descriptor index */
+ di->txout = txout;
+
+ /* kick the chip */
+ if (commit) {
+ W_REG(di->osh, &di->d64txregs->ptr,
+ di->xmtptrbase + I2B(txout, dma64dd_t));
+ }
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ return 0;
+
+ outoftxd:
+ DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return -1;
+}
+
+/* !! tx entry routine
+ * WARNING: call must check the return value for error.
+ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems
+ */
+static int BCMFASTPATH dma64_txfast(dma_info_t *di, void *p0, bool commit)
+{
+ void *p, *next;
+ uchar *data;
+ uint len;
+ uint16 txout;
+ uint32 flags = 0;
+ dmaaddr_t pa;
+
+ DMA_TRACE(("%s: dma_txfast\n", di->name));
+
+ txout = di->txout;
+
+ /*
+ * Walk the chain of packet buffers
+ * allocating and initializing transmit descriptor entries.
+ */
+ for (p = p0; p; p = next) {
+ uint nsegs, j;
+ hnddma_seg_map_t *map;
+
+ data = PKTDATA(p);
+ len = PKTLEN(p);
+#ifdef BCM_DMAPAD
+ len += PKTDMAPAD(di->osh, p);
+#endif /* BCM_DMAPAD */
+ next = PKTNEXT(p);
+
+ /* return nonzero if out of tx descriptors */
+ if (NEXTTXD(txout) == di->txin)
+ goto outoftxd;
+
+ if (len == 0)
+ continue;
+
+ /* get physical address of buffer start */
+ if (DMASGLIST_ENAB)
+ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t));
+
+ pa = DMA_MAP(di->osh, data, len, DMA_TX, p,
+ &di->txp_dmah[txout]);
+
+ if (DMASGLIST_ENAB) {
+ map = &di->txp_dmah[txout];
+
+ /* See if all the segments can be accounted for */
+ if (map->nsegs >
+ (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
+ 1))
+ goto outoftxd;
+
+ nsegs = map->nsegs;
+ } else
+ nsegs = 1;
+
+ for (j = 1; j <= nsegs; j++) {
+ flags = 0;
+ if (p == p0 && j == 1)
+ flags |= D64_CTRL1_SOF;
+
+ /* With a DMA segment list, Descriptor table is filled
+ * using the segment list instead of looping over
+ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
+ * end of segment list is reached.
+ */
+ if ((!DMASGLIST_ENAB && next == NULL) ||
+ (DMASGLIST_ENAB && j == nsegs))
+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+ if (txout == (di->ntxd - 1))
+ flags |= D64_CTRL1_EOT;
+
+ if (DMASGLIST_ENAB) {
+ len = map->segs[j - 1].length;
+ pa = map->segs[j - 1].addr;
+ }
+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+ ASSERT(di->txp[txout] == NULL);
+
+ txout = NEXTTXD(txout);
+ }
+
+ /* See above. No need to loop over individual buffers */
+ if (DMASGLIST_ENAB)
+ break;
+ }
+
+ /* if last txd eof not set, fix it */
+ if (!(flags & D64_CTRL1_EOF))
+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
+ BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+
+ /* save the packet */
+ di->txp[PREVTXD(txout)] = p0;
+
+ /* bump the tx descriptor index */
+ di->txout = txout;
+
+ /* kick the chip */
+ if (commit)
+ W_REG(di->osh, &di->d64txregs->ptr,
+ di->xmtptrbase + I2B(txout, dma64dd_t));
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ return 0;
+
+ outoftxd:
+ DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
+ PKTFREE(di->osh, p0, TRUE);
+ di->hnddma.txavail = 0;
+ di->hnddma.txnobuf++;
+ return -1;
+}
+
+/*
+ * Reclaim next completed txd (txds if using chained buffers) in the range
+ * specified and return associated packet.
+ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
+ * transmitted as noted by the hardware "CurrDescr" pointer.
+ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
+ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer.
+ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
+ * return associated packet regardless of the value of hardware pointers.
+ */
+static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range)
+{
+ uint16 start, end, i;
+ uint16 active_desc;
+ void *txp;
+
+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
+ (range == HNDDMA_RANGE_ALL) ? "all" :
+ ((range ==
+ HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+ "transfered")));
+
+ if (di->ntxd == 0)
+ return NULL;
+
+ txp = NULL;
+
+ start = di->txin;
+ if (range == HNDDMA_RANGE_ALL)
+ end = di->txout;
+ else {
+ dma64regs_t *dregs = di->d64txregs;
+
+ end =
+ (uint16) (B2I
+ (((R_REG(di->osh, &dregs->status0) &
+ D64_XS0_CD_MASK) -
+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
+
+ if (range == HNDDMA_RANGE_TRANSFERED) {
+ active_desc =
+ (uint16) (R_REG(di->osh, &dregs->status1) &
+ D64_XS1_AD_MASK);
+ active_desc =
+ (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
+ active_desc = B2I(active_desc, dma64dd_t);
+ if (end != active_desc)
+ end = PREVTXD(active_desc);
+ }
+ }
+
+ if ((start == 0) && (end > di->txout))
+ goto bogus;
+
+ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
+ dmaaddr_t pa;
+ hnddma_seg_map_t *map = NULL;
+ uint size, j, nsegs;
+
+ PHYSADDRLOSET(pa,
+ (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
+ di->dataoffsetlow));
+ PHYSADDRHISET(pa,
+ (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
+ di->dataoffsethigh));
+
+ if (DMASGLIST_ENAB) {
+ map = &di->txp_dmah[i];
+ size = map->origsize;
+ nsegs = map->nsegs;
+ } else {
+ size =
+ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
+ D64_CTRL2_BC_MASK);
+ nsegs = 1;
+ }
+
+ for (j = nsegs; j > 0; j--) {
+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
+ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+
+ txp = di->txp[i];
+ di->txp[i] = NULL;
+ if (j > 1)
+ i = NEXTTXD(i);
+ }
+
+ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map);
+ }
+
+ di->txin = i;
+
+ /* tx flow control */
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ return txp;
+
+ bogus:
+ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
+ return NULL;
+}
+
+static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall)
+{
+ uint i, curr;
+ void *rxp;
+ dmaaddr_t pa;
+
+ /* if forcing, dma engine must be disabled */
+ ASSERT(!forceall || !dma64_rxenabled(di));
+
+ i = di->rxin;
+
+ /* return if no packets posted */
+ if (i == di->rxout)
+ return NULL;
+
+ curr =
+ B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) -
+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
+
+ /* ignore curr if forceall */
+ if (!forceall && (i == curr))
+ return NULL;
+
+ /* get the packet pointer that corresponds to the rx descriptor */
+ rxp = di->rxp[i];
+ ASSERT(rxp);
+ di->rxp[i] = NULL;
+
+ PHYSADDRLOSET(pa,
+ (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
+ di->dataoffsetlow));
+ PHYSADDRHISET(pa,
+ (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
+ di->dataoffsethigh));
+
+ /* clear this packet from the descriptor ring */
+ DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]);
+
+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+
+ di->rxin = NEXTRXD(i);
+
+ return rxp;
+}
+
+static bool _dma64_addrext(osl_t *osh, dma64regs_t * dma64regs)
+{
+ uint32 w;
+ OR_REG(osh, &dma64regs->control, D64_XC_AE);
+ w = R_REG(osh, &dma64regs->control);
+ AND_REG(osh, &dma64regs->control, ~D64_XC_AE);
+ return (w & D64_XC_AE) == D64_XC_AE;
+}
+
+/*
+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
+ */
+static void dma64_txrotate(dma_info_t *di)
+{
+ uint16 ad;
+ uint nactive;
+ uint rot;
+ uint16 old, new;
+ uint32 w;
+ uint16 first, last;
+
+ ASSERT(dma64_txsuspendedidle(di));
+
+ nactive = _dma_txactive(di);
+ ad = (uint16) (B2I
+ ((((R_REG(di->osh, &di->d64txregs->status1) &
+ D64_XS1_AD_MASK)
+ - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
+ rot = TXD(ad - di->txin);
+
+ ASSERT(rot < di->ntxd);
+
+ /* full-ring case is a lot harder - don't worry about this */
+ if (rot >= (di->ntxd - nactive)) {
+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
+ return;
+ }
+
+ first = di->txin;
+ last = PREVTXD(di->txout);
+
+ /* move entries starting at last and moving backwards to first */
+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
+ new = TXD(old + rot);
+
+ /*
+ * Move the tx dma descriptor.
+ * EOT is set only in the last entry in the ring.
+ */
+ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+ if (new == (di->ntxd - 1))
+ w |= D64_CTRL1_EOT;
+ W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
+
+ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
+ W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
+
+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
+
+ /* zap the old tx dma descriptor address field */
+ W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
+ W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
+
+ /* move the corresponding txp[] entry */
+ ASSERT(di->txp[new] == NULL);
+ di->txp[new] = di->txp[old];
+
+ /* Move the map */
+ if (DMASGLIST_ENAB) {
+ bcopy(&di->txp_dmah[old], &di->txp_dmah[new],
+ sizeof(hnddma_seg_map_t));
+ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t));
+ }
+
+ di->txp[old] = NULL;
+ }
+
+ /* update txin and txout */
+ di->txin = ad;
+ di->txout = TXD(di->txout + rot);
+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+ /* kick the chip */
+ W_REG(di->osh, &di->d64txregs->ptr,
+ di->xmtptrbase + I2B(di->txout, dma64dd_t));
+}
+
+uint dma_addrwidth(si_t *sih, void *dmaregs)
+{
+ dma32regs_t *dma32regs;
+ osl_t *osh;
+
+ osh = si_osh(sih);
+
+ /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
+ /* DMA engine is 64-bit capable */
+ if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
+ /* backplane are 64-bit capable */
+ if (si_backplane64(sih))
+ /* If bus is System Backplane or PCIE then we can access 64-bits */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) ||
+ ((BUSTYPE(sih->bustype) == PCI_BUS) &&
+ (sih->buscoretype == PCIE_CORE_ID)))
+ return DMADDRWIDTH_64;
+
+ /* DMA64 is always 32-bit capable, AE is always TRUE */
+ ASSERT(_dma64_addrext(osh, (dma64regs_t *) dmaregs));
+
+ return DMADDRWIDTH_32;
+ }
+
+ /* Start checking for 32-bit / 30-bit addressing */
+ dma32regs = (dma32regs_t *) dmaregs;
+
+ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) ||
+ ((BUSTYPE(sih->bustype) == PCI_BUS)
+ && sih->buscoretype == PCIE_CORE_ID)
+ || (_dma32_addrext(osh, dma32regs)))
+ return DMADDRWIDTH_32;
+
+ /* Fallthru */
+ return DMADDRWIDTH_30;
+}
diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c
new file mode 100644
index 000000000000..daa019838b11
--- /dev/null
+++ b/drivers/staging/brcm80211/util/hndpmu.c
@@ -0,0 +1,2683 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <hndpmu.h>
+#include "siutils_priv.h"
+
+#define PMU_ERROR(args)
+
+#ifdef BCMDBG
+#define PMU_MSG(args) printf args
+#else
+#define PMU_MSG(args)
+#endif /* BCMDBG */
+
+/* To check in verbose debugging messages not intended
+ * to be on except on private builds.
+ */
+#define PMU_NONE(args)
+
+/* PLL controls/clocks */
+static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc,
+ uint32 xtal);
+static uint32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
+static uint32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
+
+/* PMU resources */
+static bool si_pmu_res_depfltr_bb(si_t *sih);
+static bool si_pmu_res_depfltr_ncb(si_t *sih);
+static bool si_pmu_res_depfltr_paldo(si_t *sih);
+static bool si_pmu_res_depfltr_npaldo(si_t *sih);
+static uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc,
+ uint32 rsrcs, bool all);
+static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc,
+ uint8 rsrc);
+static void si_pmu_res_masks(si_t *sih, uint32 * pmin, uint32 * pmax);
+static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc,
+ osl_t *osh, uint8 spuravoid);
+
+static void si_pmu_set_4330_plldivs(si_t *sih);
+
+/* FVCO frequency */
+#define FVCO_880 880000 /* 880MHz */
+#define FVCO_1760 1760000 /* 1760MHz */
+#define FVCO_1440 1440000 /* 1440MHz */
+#define FVCO_960 960000 /* 960MHz */
+
+/* Read/write a chipcontrol reg */
+uint32 si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
+{
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr), ~0,
+ reg);
+ return si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data), mask, val);
+}
+
+/* Read/write a regcontrol reg */
+uint32 si_pmu_regcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
+{
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr), ~0,
+ reg);
+ return si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, regcontrol_data), mask, val);
+}
+
+/* Read/write a pllcontrol reg */
+uint32 si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
+{
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pllcontrol_addr), ~0,
+ reg);
+ return si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, pllcontrol_data), mask, val);
+}
+
+/* PMU PLL update */
+void si_pmu_pllupd(si_t *sih)
+{
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmucontrol),
+ PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
+}
+
+/* Setup switcher voltage */
+void
+BCMATTACHFN(si_pmu_set_switcher_voltage) (si_t *sih, osl_t *osh,
+ uint8 bb_voltage, uint8 rf_voltage) {
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ W_REG(osh, &cc->regcontrol_addr, 0x01);
+ W_REG(osh, &cc->regcontrol_data, (uint32) (bb_voltage & 0x1f) << 22);
+
+ W_REG(osh, &cc->regcontrol_addr, 0x00);
+ W_REG(osh, &cc->regcontrol_data, (uint32) (rf_voltage & 0x1f) << 14);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+void
+BCMATTACHFN(si_pmu_set_ldo_voltage) (si_t *sih, osl_t *osh, uint8 ldo,
+ uint8 voltage) {
+ uint8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
+ uint8 addr = 0;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4336_CHIP_ID:
+ switch (ldo) {
+ case SET_LDO_VOLTAGE_CLDO_PWM:
+ addr = 4;
+ rc_shift = 1;
+ mask = 0xf;
+ break;
+ case SET_LDO_VOLTAGE_CLDO_BURST:
+ addr = 4;
+ rc_shift = 5;
+ mask = 0xf;
+ break;
+ case SET_LDO_VOLTAGE_LNLDO1:
+ addr = 4;
+ rc_shift = 17;
+ mask = 0xf;
+ break;
+ default:
+ ASSERT(FALSE);
+ return;
+ }
+ break;
+ case BCM4330_CHIP_ID:
+ switch (ldo) {
+ case SET_LDO_VOLTAGE_CBUCK_PWM:
+ addr = 3;
+ rc_shift = 0;
+ mask = 0x1f;
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+ break;
+ default:
+ ASSERT(FALSE);
+ return;
+ }
+
+ shift = sr_cntl_shift + rc_shift;
+
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr),
+ ~0, addr);
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data),
+ mask << shift, (voltage & mask) << shift);
+}
+
+/* d11 slow to fast clock transition time in slow clock cycles */
+#define D11SCC_SLOW2FAST_TRANSITION 2
+
+uint16 BCMINITFN(si_pmu_fast_pwrup_delay) (si_t *sih, osl_t *osh)
+{
+ uint delay = PMU_MAX_TRANSITION_DLY;
+ chipcregs_t *cc;
+ uint origidx;
+#ifdef BCMDBG
+ char chn[8];
+ chn[0] = 0; /* to suppress compile error */
+#endif
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ case BCM4313_CHIP_ID:
+ delay = ISSIM_ENAB(sih) ? 70 : 3700;
+ break;
+ case BCM4329_CHIP_ID:
+ if (ISSIM_ENAB(sih))
+ delay = 70;
+ else {
+ uint32 ilp = si_ilp_clock(sih);
+ delay =
+ (si_pmu_res_uptime(sih, osh, cc, RES4329_HT_AVAIL) +
+ D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+ 1) / ilp);
+ delay = (11 * delay) / 10;
+ }
+ break;
+ case BCM4319_CHIP_ID:
+ delay = ISSIM_ENAB(sih) ? 70 : 3700;
+ break;
+ case BCM4336_CHIP_ID:
+ if (ISSIM_ENAB(sih))
+ delay = 70;
+ else {
+ uint32 ilp = si_ilp_clock(sih);
+ delay =
+ (si_pmu_res_uptime(sih, osh, cc, RES4336_HT_AVAIL) +
+ D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+ 1) / ilp);
+ delay = (11 * delay) / 10;
+ }
+ break;
+ case BCM4330_CHIP_ID:
+ if (ISSIM_ENAB(sih))
+ delay = 70;
+ else {
+ uint32 ilp = si_ilp_clock(sih);
+ delay =
+ (si_pmu_res_uptime(sih, osh, cc, RES4330_HT_AVAIL) +
+ D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+ 1) / ilp);
+ delay = (11 * delay) / 10;
+ }
+ break;
+ default:
+ break;
+ }
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+
+ return (uint16) delay;
+}
+
+uint32 BCMATTACHFN(si_pmu_force_ilp) (si_t *sih, osl_t *osh, bool force)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 oldpmucontrol;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ oldpmucontrol = R_REG(osh, &cc->pmucontrol);
+ if (force)
+ W_REG(osh, &cc->pmucontrol, oldpmucontrol &
+ ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
+ else
+ W_REG(osh, &cc->pmucontrol, oldpmucontrol |
+ (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+
+ return oldpmucontrol;
+}
+
+/* Setup resource up/down timers */
+typedef struct {
+ uint8 resnum;
+ uint16 updown;
+} pmu_res_updown_t;
+
+/* Change resource dependancies masks */
+typedef struct {
+ uint32 res_mask; /* resources (chip specific) */
+ int8 action; /* action */
+ uint32 depend_mask; /* changes to the dependancies mask */
+ bool(*filter) (si_t *sih); /* action is taken when filter is NULL or return TRUE */
+} pmu_res_depend_t;
+
+/* Resource dependancies mask change action */
+#define RES_DEPEND_SET 0 /* Override the dependancies mask */
+#define RES_DEPEND_ADD 1 /* Add to the dependancies mask */
+#define RES_DEPEND_REMOVE -1 /* Remove from the dependancies mask */
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4328a0_res_updown)[] = {
+ {
+ RES4328_EXT_SWITCHER_PWM, 0x0101}, {
+ RES4328_BB_SWITCHER_PWM, 0x1f01}, {
+ RES4328_BB_SWITCHER_BURST, 0x010f}, {
+ RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
+ RES4328_ILP_REQUEST, 0x0202}, {
+ RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
+ RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
+ RES4328_ROM_SWITCH, 0x0101}, {
+ RES4328_PA_REF_LDO, 0x0f01}, {
+ RES4328_RADIO_LDO, 0x0f01}, {
+ RES4328_AFE_LDO, 0x0f01}, {
+ RES4328_PLL_LDO, 0x0f01}, {
+ RES4328_BG_FILTBYP, 0x0101}, {
+ RES4328_TX_FILTBYP, 0x0101}, {
+ RES4328_RX_FILTBYP, 0x0101}, {
+ RES4328_XTAL_PU, 0x0101}, {
+ RES4328_XTAL_EN, 0xa001}, {
+ RES4328_BB_PLL_FILTBYP, 0x0101}, {
+ RES4328_RF_PLL_FILTBYP, 0x0101}, {
+ RES4328_BB_PLL_PU, 0x0701}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4328a0_res_depend)[] = {
+ /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
+ {
+ PMURES_BIT(RES4328_ILP_REQUEST),
+ RES_DEPEND_SET,
+ PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
+ PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown_qt)[] = {
+ {
+ RES4325_HT_AVAIL, 0x0300}, {
+ RES4325_BBPLL_PWRSW_PU, 0x0101}, {
+ RES4325_RFPLL_PWRSW_PU, 0x0101}, {
+ RES4325_ALP_AVAIL, 0x0100}, {
+ RES4325_XTAL_PU, 0x1000}, {
+ RES4325_LNLDO1_PU, 0x0800}, {
+ RES4325_CLDO_CBUCK_PWM, 0x0101}, {
+ RES4325_CBUCK_PWM, 0x0803}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown)[] = {
+ {
+ RES4325_XTAL_PU, 0x1501}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4325a0_res_depend)[] = {
+ /* Adjust OTP PU resource dependencies - remove BB BURST */
+ {
+ PMURES_BIT(RES4325_OTP_PU),
+ RES_DEPEND_REMOVE,
+ PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
+ /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
+ {
+ PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
+ PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
+ /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+ {
+ PMURES_BIT(RES4325_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4325_RX_PWRSW_PU) |
+ PMURES_BIT(RES4325_TX_PWRSW_PU) |
+ PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
+ /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+ {
+ PMURES_BIT(RES4325_ILP_REQUEST) |
+ PMURES_BIT(RES4325_ABUCK_BURST) |
+ PMURES_BIT(RES4325_ABUCK_PWM) |
+ PMURES_BIT(RES4325_LNLDO1_PU) |
+ PMURES_BIT(RES4325C1_LNLDO2_PU) |
+ PMURES_BIT(RES4325_XTAL_PU) |
+ PMURES_BIT(RES4325_ALP_AVAIL) |
+ PMURES_BIT(RES4325_RX_PWRSW_PU) |
+ PMURES_BIT(RES4325_TX_PWRSW_PU) |
+ PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
+ PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4325_AFE_PWRSW_PU) |
+ PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
+ PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
+ PMURES_BIT(RES4325B0_CBUCK_LPOM) |
+ PMURES_BIT(RES4325B0_CBUCK_BURST) |
+ PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown_qt)[] = {
+ {
+ RES4315_HT_AVAIL, 0x0101}, {
+ RES4315_XTAL_PU, 0x0100}, {
+ RES4315_LNLDO1_PU, 0x0100}, {
+ RES4315_PALDO_PU, 0x0100}, {
+ RES4315_CLDO_PU, 0x0100}, {
+ RES4315_CBUCK_PWM, 0x0100}, {
+ RES4315_CBUCK_BURST, 0x0100}, {
+ RES4315_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown)[] = {
+ {
+ RES4315_XTAL_PU, 0x2501}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4315a0_res_depend)[] = {
+ /* Adjust OTP PU resource dependencies - not need PALDO unless write */
+ {
+ PMURES_BIT(RES4315_OTP_PU),
+ RES_DEPEND_REMOVE,
+ PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
+ /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
+ {
+ PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
+ /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+ {
+ PMURES_BIT(RES4315_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4315_RX_PWRSW_PU) |
+ PMURES_BIT(RES4315_TX_PWRSW_PU) |
+ PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
+ /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+ {
+ PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
+ PMURES_BIT(RES4315_LNLDO1_PU) |
+ PMURES_BIT(RES4315_OTP_PU) |
+ PMURES_BIT(RES4315_LNLDO2_PU) |
+ PMURES_BIT(RES4315_XTAL_PU) |
+ PMURES_BIT(RES4315_ALP_AVAIL) |
+ PMURES_BIT(RES4315_RX_PWRSW_PU) |
+ PMURES_BIT(RES4315_TX_PWRSW_PU) |
+ PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
+ PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4315_AFE_PWRSW_PU) |
+ PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
+ PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
+ PMURES_BIT(RES4315_CBUCK_LPOM) |
+ PMURES_BIT(RES4315_CBUCK_BURST) |
+ PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+};
+
+ /* 4329 specific. needs to come back this issue later */
+static const pmu_res_updown_t BCMINITDATA(bcm4329_res_updown)[] = {
+ {
+ RES4329_XTAL_PU, 0x1501}
+};
+
+static const pmu_res_depend_t BCMINITDATA(bcm4329_res_depend)[] = {
+ /* Adjust HT Avail resource dependencies */
+ {
+ PMURES_BIT(RES4329_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4329_CBUCK_LPOM) |
+ PMURES_BIT(RES4329_CBUCK_BURST) |
+ PMURES_BIT(RES4329_CBUCK_PWM) |
+ PMURES_BIT(RES4329_CLDO_PU) |
+ PMURES_BIT(RES4329_PALDO_PU) |
+ PMURES_BIT(RES4329_LNLDO1_PU) |
+ PMURES_BIT(RES4329_XTAL_PU) |
+ PMURES_BIT(RES4329_ALP_AVAIL) |
+ PMURES_BIT(RES4329_RX_PWRSW_PU) |
+ PMURES_BIT(RES4329_TX_PWRSW_PU) |
+ PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
+ PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4329_AFE_PWRSW_PU) |
+ PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown_qt)[] = {
+ {
+ RES4319_HT_AVAIL, 0x0101}, {
+ RES4319_XTAL_PU, 0x0100}, {
+ RES4319_LNLDO1_PU, 0x0100}, {
+ RES4319_PALDO_PU, 0x0100}, {
+ RES4319_CLDO_PU, 0x0100}, {
+ RES4319_CBUCK_PWM, 0x0100}, {
+ RES4319_CBUCK_BURST, 0x0100}, {
+ RES4319_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown)[] = {
+ {
+ RES4319_XTAL_PU, 0x3f01}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4319a0_res_depend)[] = {
+ /* Adjust OTP PU resource dependencies - not need PALDO unless write */
+ {
+ PMURES_BIT(RES4319_OTP_PU),
+ RES_DEPEND_REMOVE,
+ PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
+ /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
+ {
+ PMURES_BIT(RES4319_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
+ /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+ {
+ PMURES_BIT(RES4319_HT_AVAIL),
+ RES_DEPEND_ADD,
+ PMURES_BIT(RES4319_RX_PWRSW_PU) |
+ PMURES_BIT(RES4319_TX_PWRSW_PU) |
+ PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
+ PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
+ PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown_qt)[] = {
+ {
+ RES4336_HT_AVAIL, 0x0101}, {
+ RES4336_XTAL_PU, 0x0100}, {
+ RES4336_CLDO_PU, 0x0100}, {
+ RES4336_CBUCK_PWM, 0x0100}, {
+ RES4336_CBUCK_BURST, 0x0100}, {
+ RES4336_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown)[] = {
+ {
+ RES4336_HT_AVAIL, 0x0D01}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4336a0_res_depend)[] = {
+ /* Just a dummy entry for now */
+ {
+ PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown_qt)[] = {
+ {
+ RES4330_HT_AVAIL, 0x0101}, {
+ RES4330_XTAL_PU, 0x0100}, {
+ RES4330_CLDO_PU, 0x0100}, {
+ RES4330_CBUCK_PWM, 0x0100}, {
+ RES4330_CBUCK_BURST, 0x0100}, {
+ RES4330_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown)[] = {
+ {
+ RES4330_HT_AVAIL, 0x0e02}
+};
+
+static const pmu_res_depend_t BCMATTACHDATA(bcm4330a0_res_depend)[] = {
+ /* Just a dummy entry for now */
+ {
+ PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
+};
+
+/* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
+static bool BCMATTACHFN(si_pmu_res_depfltr_bb) (si_t *sih)
+{
+ return (sih->boardflags & BFL_BUCKBOOST) != 0;
+}
+
+/* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
+static bool BCMATTACHFN(si_pmu_res_depfltr_ncb) (si_t *sih)
+{
+
+ return (sih->boardflags & BFL_NOCBUCK) != 0;
+}
+
+/* TRUE if the power topology uses the PALDO */
+static bool BCMATTACHFN(si_pmu_res_depfltr_paldo) (si_t *sih)
+{
+ return (sih->boardflags & BFL_PALDO) != 0;
+}
+
+/* TRUE if the power topology doesn't use the PALDO */
+static bool BCMATTACHFN(si_pmu_res_depfltr_npaldo) (si_t *sih)
+{
+ return (sih->boardflags & BFL_PALDO) == 0;
+}
+
+#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
+ sih->boardtype == BCM94325BGABU_BOARD)
+
+/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
+static void si_pmu_res_masks(si_t *sih, uint32 * pmin, uint32 * pmax)
+{
+ uint32 min_mask = 0, max_mask = 0;
+ uint rsrcs;
+ char *val;
+
+ /* # resources */
+ rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+
+ /* determine min/max rsrc masks */
+ switch (CHIPID(sih->chip)) {
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ /* ??? */
+ break;
+
+ case BCM4329_CHIP_ID:
+ /* 4329 spedific issue. Needs to come back this issue later */
+ /* Down to save the power. */
+ min_mask =
+ PMURES_BIT(RES4329_CBUCK_LPOM) |
+ PMURES_BIT(RES4329_CLDO_PU);
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0x3ff63e;
+ break;
+ case BCM4319_CHIP_ID:
+ /* We only need a few resources to be kept on all the time */
+ min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
+ PMURES_BIT(RES4319_CLDO_PU);
+
+ /* Allow everything else to be turned on upon requests */
+ max_mask = ~(~0 << rsrcs);
+ break;
+ case BCM4336_CHIP_ID:
+ /* Down to save the power. */
+ min_mask =
+ PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
+ | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
+ | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0x1ffffff;
+ break;
+
+ case BCM4330_CHIP_ID:
+ /* Down to save the power. */
+ min_mask =
+ PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
+ | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
+ PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0xfffffff;
+ break;
+
+ case BCM4313_CHIP_ID:
+ min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
+ PMURES_BIT(RES4313_XTAL_PU_RSRC) |
+ PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
+ PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
+ max_mask = 0xffff;
+ break;
+ default:
+ break;
+ }
+
+ /* Apply nvram override to min mask */
+ val = getvar(NULL, "rmin");
+ if (val != NULL) {
+ PMU_MSG(("Applying rmin=%s to min_mask\n", val));
+ min_mask = (uint32) bcm_strtoul(val, NULL, 0);
+ }
+ /* Apply nvram override to max mask */
+ val = getvar(NULL, "rmax");
+ if (val != NULL) {
+ PMU_MSG(("Applying rmax=%s to max_mask\n", val));
+ max_mask = (uint32) bcm_strtoul(val, NULL, 0);
+ }
+
+ *pmin = min_mask;
+ *pmax = max_mask;
+}
+
+/* initialize PMU resources */
+void BCMATTACHFN(si_pmu_res_init) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ const pmu_res_updown_t *pmu_res_updown_table = NULL;
+ uint pmu_res_updown_table_sz = 0;
+ const pmu_res_depend_t *pmu_res_depend_table = NULL;
+ uint pmu_res_depend_table_sz = 0;
+ uint32 min_mask = 0, max_mask = 0;
+ char name[8], *val;
+ uint i, rsrcs;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ /* Optimize resources up/down timers */
+ if (ISSIM_ENAB(sih)) {
+ pmu_res_updown_table = NULL;
+ pmu_res_updown_table_sz = 0;
+ } else {
+ pmu_res_updown_table = bcm4329_res_updown;
+ pmu_res_updown_table_sz = ARRAYSIZE(bcm4329_res_updown);
+ }
+ /* Optimize resources dependencies */
+ pmu_res_depend_table = bcm4329_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE(bcm4329_res_depend);
+ break;
+
+ case BCM4319_CHIP_ID:
+ /* Optimize resources up/down timers */
+ if (ISSIM_ENAB(sih)) {
+ pmu_res_updown_table = bcm4319a0_res_updown_qt;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4319a0_res_updown_qt);
+ } else {
+ pmu_res_updown_table = bcm4319a0_res_updown;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4319a0_res_updown);
+ }
+ /* Optimize resources dependancies masks */
+ pmu_res_depend_table = bcm4319a0_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE(bcm4319a0_res_depend);
+ break;
+
+ case BCM4336_CHIP_ID:
+ /* Optimize resources up/down timers */
+ if (ISSIM_ENAB(sih)) {
+ pmu_res_updown_table = bcm4336a0_res_updown_qt;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4336a0_res_updown_qt);
+ } else {
+ pmu_res_updown_table = bcm4336a0_res_updown;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4336a0_res_updown);
+ }
+ /* Optimize resources dependancies masks */
+ pmu_res_depend_table = bcm4336a0_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE(bcm4336a0_res_depend);
+ break;
+
+ case BCM4330_CHIP_ID:
+ /* Optimize resources up/down timers */
+ if (ISSIM_ENAB(sih)) {
+ pmu_res_updown_table = bcm4330a0_res_updown_qt;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4330a0_res_updown_qt);
+ } else {
+ pmu_res_updown_table = bcm4330a0_res_updown;
+ pmu_res_updown_table_sz =
+ ARRAYSIZE(bcm4330a0_res_updown);
+ }
+ /* Optimize resources dependancies masks */
+ pmu_res_depend_table = bcm4330a0_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE(bcm4330a0_res_depend);
+ break;
+
+ default:
+ break;
+ }
+
+ /* # resources */
+ rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+
+ /* Program up/down timers */
+ while (pmu_res_updown_table_sz--) {
+ ASSERT(pmu_res_updown_table != NULL);
+ PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
+ pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
+ pmu_res_updown_table[pmu_res_updown_table_sz].updown));
+ W_REG(osh, &cc->res_table_sel,
+ pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
+ W_REG(osh, &cc->res_updn_timer,
+ pmu_res_updown_table[pmu_res_updown_table_sz].updown);
+ }
+ /* Apply nvram overrides to up/down timers */
+ for (i = 0; i < rsrcs; i++) {
+ snprintf(name, sizeof(name), "r%dt", i);
+ val = getvar(NULL, name);
+ if (val == NULL)
+ continue;
+ PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name,
+ val, i));
+ W_REG(osh, &cc->res_table_sel, (uint32) i);
+ W_REG(osh, &cc->res_updn_timer,
+ (uint32) bcm_strtoul(val, NULL, 0));
+ }
+
+ /* Program resource dependencies table */
+ while (pmu_res_depend_table_sz--) {
+ ASSERT(pmu_res_depend_table != NULL);
+ if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
+ && !(pmu_res_depend_table[pmu_res_depend_table_sz].
+ filter) (sih))
+ continue;
+ for (i = 0; i < rsrcs; i++) {
+ if ((pmu_res_depend_table[pmu_res_depend_table_sz].
+ res_mask & PMURES_BIT(i)) == 0)
+ continue;
+ W_REG(osh, &cc->res_table_sel, i);
+ switch (pmu_res_depend_table[pmu_res_depend_table_sz].
+ action) {
+ case RES_DEPEND_SET:
+ PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask));
+ W_REG(osh, &cc->res_dep_mask,
+ pmu_res_depend_table
+ [pmu_res_depend_table_sz].depend_mask);
+ break;
+ case RES_DEPEND_ADD:
+ PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
+ OR_REG(osh, &cc->res_dep_mask,
+ pmu_res_depend_table
+ [pmu_res_depend_table_sz].depend_mask);
+ break;
+ case RES_DEPEND_REMOVE:
+ PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
+ AND_REG(osh, &cc->res_dep_mask,
+ ~pmu_res_depend_table
+ [pmu_res_depend_table_sz].depend_mask);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+ }
+ /* Apply nvram overrides to dependancies masks */
+ for (i = 0; i < rsrcs; i++) {
+ snprintf(name, sizeof(name), "r%dd", i);
+ val = getvar(NULL, name);
+ if (val == NULL)
+ continue;
+ PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val,
+ i));
+ W_REG(osh, &cc->res_table_sel, (uint32) i);
+ W_REG(osh, &cc->res_dep_mask,
+ (uint32) bcm_strtoul(val, NULL, 0));
+ }
+
+ /* Determine min/max rsrc masks */
+ si_pmu_res_masks(sih, &min_mask, &max_mask);
+
+ /* It is required to program max_mask first and then min_mask */
+
+ /* Program max resource mask */
+
+ if (max_mask) {
+ PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
+ W_REG(osh, &cc->max_res_mask, max_mask);
+ }
+
+ /* Program min resource mask */
+
+ if (min_mask) {
+ PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
+ W_REG(osh, &cc->min_res_mask, min_mask);
+ }
+
+ /* Add some delay; allow resources to come up and settle. */
+ OSL_DELAY(2000);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+/* setup pll and query clock speed */
+typedef struct {
+ uint16 freq;
+ uint8 xf;
+ uint8 wbint;
+ uint32 wbfrac;
+} pmu0_xtaltab0_t;
+
+/* the following table is based on 880Mhz fvco */
+static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = {
+ {
+ 12000, 1, 73, 349525}, {
+ 13000, 2, 67, 725937}, {
+ 14400, 3, 61, 116508}, {
+ 15360, 4, 57, 305834}, {
+ 16200, 5, 54, 336579}, {
+ 16800, 6, 52, 399457}, {
+ 19200, 7, 45, 873813}, {
+ 19800, 8, 44, 466033}, {
+ 20000, 9, 44, 0}, {
+ 25000, 10, 70, 419430}, {
+ 26000, 11, 67, 725937}, {
+ 30000, 12, 58, 699050}, {
+ 38400, 13, 45, 873813}, {
+ 40000, 14, 45, 0}, {
+ 0, 0, 0, 0}
+};
+
+#define PMU0_XTAL0_DEFAULT 8
+
+/* setup pll and query clock speed */
+typedef struct {
+ uint16 fref;
+ uint8 xf;
+ uint8 p1div;
+ uint8 p2div;
+ uint8 ndiv_int;
+ uint32 ndiv_frac;
+} pmu1_xtaltab0_t;
+
+static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880_4329)[] = {
+ {
+ 12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+ 13000, 2, 1, 6, 0xb, 0x483483}, {
+ 14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+ 15360, 4, 1, 5, 0xb, 0x755555}, {
+ 16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+ 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+ 19200, 7, 1, 4, 0xb, 0x755555}, {
+ 19800, 8, 1, 11, 0x4, 0xA57EB}, {
+ 20000, 9, 1, 11, 0x4, 0x0}, {
+ 24000, 10, 3, 11, 0xa, 0x0}, {
+ 25000, 11, 5, 16, 0xb, 0x0}, {
+ 26000, 12, 1, 1, 0x21, 0xD89D89}, {
+ 30000, 13, 3, 8, 0xb, 0x0}, {
+ 37400, 14, 3, 1, 0x46, 0x969696}, {
+ 38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
+ 40000, 16, 1, 2, 0xb, 0}, {
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* the following table is based on 880Mhz fvco */
+static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880)[] = {
+ {
+ 12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+ 13000, 2, 1, 6, 0xb, 0x483483}, {
+ 14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+ 15360, 4, 1, 5, 0xb, 0x755555}, {
+ 16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+ 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+ 19200, 7, 1, 4, 0xb, 0x755555}, {
+ 19800, 8, 1, 11, 0x4, 0xA57EB}, {
+ 20000, 9, 1, 11, 0x4, 0x0}, {
+ 24000, 10, 3, 11, 0xa, 0x0}, {
+ 25000, 11, 5, 16, 0xb, 0x0}, {
+ 26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
+ 30000, 13, 3, 8, 0xb, 0x0}, {
+ 33600, 14, 1, 2, 0xd, 0x186186}, {
+ 38400, 15, 1, 2, 0xb, 0x755555}, {
+ 40000, 16, 1, 2, 0xb, 0}, {
+ 0, 0, 0, 0, 0, 0}
+};
+
+#define PMU1_XTALTAB0_880_12000K 0
+#define PMU1_XTALTAB0_880_13000K 1
+#define PMU1_XTALTAB0_880_14400K 2
+#define PMU1_XTALTAB0_880_15360K 3
+#define PMU1_XTALTAB0_880_16200K 4
+#define PMU1_XTALTAB0_880_16800K 5
+#define PMU1_XTALTAB0_880_19200K 6
+#define PMU1_XTALTAB0_880_19800K 7
+#define PMU1_XTALTAB0_880_20000K 8
+#define PMU1_XTALTAB0_880_24000K 9
+#define PMU1_XTALTAB0_880_25000K 10
+#define PMU1_XTALTAB0_880_26000K 11
+#define PMU1_XTALTAB0_880_30000K 12
+#define PMU1_XTALTAB0_880_37400K 13
+#define PMU1_XTALTAB0_880_38400K 14
+#define PMU1_XTALTAB0_880_40000K 15
+
+/* the following table is based on 1760Mhz fvco */
+static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1760)[] = {
+ {
+ 12000, 1, 3, 44, 0x9, 0xFFFFEF}, {
+ 13000, 2, 1, 12, 0xb, 0x483483}, {
+ 14400, 3, 1, 20, 0xa, 0x1C71C7}, {
+ 15360, 4, 1, 10, 0xb, 0x755555}, {
+ 16200, 5, 1, 20, 0x5, 0x6E9E06}, {
+ 16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, {
+ 19200, 7, 1, 18, 0x5, 0x17B425}, {
+ 19800, 8, 1, 22, 0x4, 0xA57EB}, {
+ 20000, 9, 1, 22, 0x4, 0x0}, {
+ 24000, 10, 3, 22, 0xa, 0x0}, {
+ 25000, 11, 5, 32, 0xb, 0x0}, {
+ 26000, 12, 1, 4, 0x10, 0xEC4EC4}, {
+ 30000, 13, 3, 16, 0xb, 0x0}, {
+ 38400, 14, 1, 10, 0x4, 0x955555}, {
+ 40000, 15, 1, 4, 0xb, 0}, {
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* table index */
+#define PMU1_XTALTAB0_1760_12000K 0
+#define PMU1_XTALTAB0_1760_13000K 1
+#define PMU1_XTALTAB0_1760_14400K 2
+#define PMU1_XTALTAB0_1760_15360K 3
+#define PMU1_XTALTAB0_1760_16200K 4
+#define PMU1_XTALTAB0_1760_16800K 5
+#define PMU1_XTALTAB0_1760_19200K 6
+#define PMU1_XTALTAB0_1760_19800K 7
+#define PMU1_XTALTAB0_1760_20000K 8
+#define PMU1_XTALTAB0_1760_24000K 9
+#define PMU1_XTALTAB0_1760_25000K 10
+#define PMU1_XTALTAB0_1760_26000K 11
+#define PMU1_XTALTAB0_1760_30000K 12
+#define PMU1_XTALTAB0_1760_38400K 13
+#define PMU1_XTALTAB0_1760_40000K 14
+
+/* the following table is based on 1440Mhz fvco */
+static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1440)[] = {
+ {
+ 12000, 1, 1, 1, 0x78, 0x0}, {
+ 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
+ 14400, 3, 1, 1, 0x64, 0x0}, {
+ 15360, 4, 1, 1, 0x5D, 0xC00000}, {
+ 16200, 5, 1, 1, 0x58, 0xE38E38}, {
+ 16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
+ 19200, 7, 1, 1, 0x4B, 0}, {
+ 19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
+ 20000, 9, 1, 1, 0x48, 0x0}, {
+ 25000, 10, 1, 1, 0x39, 0x999999}, {
+ 26000, 11, 1, 1, 0x37, 0x627627}, {
+ 30000, 12, 1, 1, 0x30, 0x0}, {
+ 37400, 13, 2, 1, 0x4D, 0x15E76}, {
+ 38400, 13, 2, 1, 0x4B, 0x0}, {
+ 40000, 14, 2, 1, 0x48, 0x0}, {
+ 48000, 15, 2, 1, 0x3c, 0x0}, {
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* table index */
+#define PMU1_XTALTAB0_1440_12000K 0
+#define PMU1_XTALTAB0_1440_13000K 1
+#define PMU1_XTALTAB0_1440_14400K 2
+#define PMU1_XTALTAB0_1440_15360K 3
+#define PMU1_XTALTAB0_1440_16200K 4
+#define PMU1_XTALTAB0_1440_16800K 5
+#define PMU1_XTALTAB0_1440_19200K 6
+#define PMU1_XTALTAB0_1440_19800K 7
+#define PMU1_XTALTAB0_1440_20000K 8
+#define PMU1_XTALTAB0_1440_25000K 9
+#define PMU1_XTALTAB0_1440_26000K 10
+#define PMU1_XTALTAB0_1440_30000K 11
+#define PMU1_XTALTAB0_1440_37400K 12
+#define PMU1_XTALTAB0_1440_38400K 13
+#define PMU1_XTALTAB0_1440_40000K 14
+#define PMU1_XTALTAB0_1440_48000K 15
+
+#define XTAL_FREQ_24000MHZ 24000
+#define XTAL_FREQ_30000MHZ 30000
+#define XTAL_FREQ_37400MHZ 37400
+#define XTAL_FREQ_48000MHZ 48000
+
+static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_960)[] = {
+ {
+ 12000, 1, 1, 1, 0x50, 0x0}, {
+ 13000, 2, 1, 1, 0x49, 0xD89D89}, {
+ 14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
+ 15360, 4, 1, 1, 0x3E, 0x800000}, {
+ 16200, 5, 1, 1, 0x39, 0x425ED0}, {
+ 16800, 6, 1, 1, 0x39, 0x249249}, {
+ 19200, 7, 1, 1, 0x32, 0x0}, {
+ 19800, 8, 1, 1, 0x30, 0x7C1F07}, {
+ 20000, 9, 1, 1, 0x30, 0x0}, {
+ 25000, 10, 1, 1, 0x26, 0x666666}, {
+ 26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
+ 30000, 12, 1, 1, 0x20, 0x0}, {
+ 37400, 13, 2, 1, 0x33, 0x563EF9}, {
+ 38400, 14, 2, 1, 0x32, 0x0}, {
+ 40000, 15, 2, 1, 0x30, 0x0}, {
+ 48000, 16, 2, 1, 0x28, 0x0}, {
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* table index */
+#define PMU1_XTALTAB0_960_12000K 0
+#define PMU1_XTALTAB0_960_13000K 1
+#define PMU1_XTALTAB0_960_14400K 2
+#define PMU1_XTALTAB0_960_15360K 3
+#define PMU1_XTALTAB0_960_16200K 4
+#define PMU1_XTALTAB0_960_16800K 5
+#define PMU1_XTALTAB0_960_19200K 6
+#define PMU1_XTALTAB0_960_19800K 7
+#define PMU1_XTALTAB0_960_20000K 8
+#define PMU1_XTALTAB0_960_25000K 9
+#define PMU1_XTALTAB0_960_26000K 10
+#define PMU1_XTALTAB0_960_30000K 11
+#define PMU1_XTALTAB0_960_37400K 12
+#define PMU1_XTALTAB0_960_38400K 13
+#define PMU1_XTALTAB0_960_40000K 14
+#define PMU1_XTALTAB0_960_48000K 15
+
+/* select xtal table for each chip */
+static const pmu1_xtaltab0_t *BCMINITFN(si_pmu1_xtaltab0) (si_t *sih)
+{
+#ifdef BCMDBG
+ char chn[8];
+#endif
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ return pmu1_xtaltab0_880_4329;
+ case BCM4319_CHIP_ID:
+ return pmu1_xtaltab0_1440;
+ case BCM4336_CHIP_ID:
+ return pmu1_xtaltab0_960;
+ case BCM4330_CHIP_ID:
+ if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+ return pmu1_xtaltab0_960;
+ else
+ return pmu1_xtaltab0_1440;
+ default:
+ PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n",
+ bcm_chipname(sih->chip, chn, 8)));
+ break;
+ }
+ ASSERT(0);
+ return NULL;
+}
+
+/* select default xtal frequency for each chip */
+static const pmu1_xtaltab0_t *BCMINITFN(si_pmu1_xtaldef0) (si_t *sih)
+{
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ /* Default to 38400Khz */
+ return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
+ case BCM4319_CHIP_ID:
+ /* Default to 30000Khz */
+ return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
+ case BCM4336_CHIP_ID:
+ /* Default to 26000Khz */
+ return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
+ case BCM4330_CHIP_ID:
+ /* Default to 37400Khz */
+ if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+ return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
+ else
+ return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
+ default:
+ PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n",
+ bcm_chipname(sih->chip, chn, 8)));
+ break;
+ }
+ ASSERT(0);
+ return NULL;
+}
+
+/* select default pll fvco for each chip */
+static uint32 BCMINITFN(si_pmu1_pllfvco0) (si_t *sih)
+{
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ return FVCO_880;
+ case BCM4319_CHIP_ID:
+ return FVCO_1440;
+ case BCM4336_CHIP_ID:
+ return FVCO_960;
+ case BCM4330_CHIP_ID:
+ if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+ return FVCO_960;
+ else
+ return FVCO_1440;
+ default:
+ PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n",
+ bcm_chipname(sih->chip, chn, 8)));
+ break;
+ }
+ ASSERT(0);
+ return 0;
+}
+
+/* query alp/xtal clock frequency */
+static uint32
+BCMINITFN(si_pmu1_alpclk0) (si_t *sih, osl_t *osh, chipcregs_t *cc)
+{
+ const pmu1_xtaltab0_t *xt;
+ uint32 xf;
+
+ /* Find the frequency in the table */
+ xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+ if (xt->xf == xf)
+ break;
+ /* Could not find it so assign a default value */
+ if (xt == NULL || xt->fref == 0)
+ xt = si_pmu1_xtaldef0(sih);
+ ASSERT(xt != NULL && xt->fref != 0);
+
+ return xt->fref * 1000;
+}
+
+/* Set up PLL registers in the PMU as per the crystal speed.
+ * XtalFreq field in pmucontrol register being 0 indicates the PLL
+ * is not programmed and the h/w default is assumed to work, in which
+ * case the xtal frequency is unknown to the s/w so we need to call
+ * si_pmu1_xtaldef0() wherever it is needed to return a default value.
+ */
+static void
+BCMATTACHFN(si_pmu1_pllinit0) (si_t *sih, osl_t *osh, chipcregs_t *cc,
+ uint32 xtal) {
+ const pmu1_xtaltab0_t *xt;
+ uint32 tmp;
+ uint32 buf_strength = 0;
+ uint8 ndiv_mode = 1;
+
+ /* Use h/w default PLL config */
+ if (xtal == 0) {
+ PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
+ return;
+ }
+
+ /* Find the frequency in the table */
+ for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+ if (xt->fref == xtal)
+ break;
+
+ /* Check current PLL state, bail out if it has been programmed or
+ * we don't know how to program it.
+ */
+ if (xt == NULL || xt->fref == 0) {
+ PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", xtal / 1000, xtal % 1000));
+ return;
+ }
+ /* for 4319 bootloader already programs the PLL but bootloader does not program the
+ PLL4 and PLL5. So Skip this check for 4319
+ */
+ if ((((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT) == xt->xf) &&
+ !((CHIPID(sih->chip) == BCM4319_CHIP_ID)
+ || (CHIPID(sih->chip) == BCM4330_CHIP_ID))) {
+ PMU_MSG(("PLL already programmed for %d.%d MHz\n",
+ xt->fref / 1000, xt->fref % 1000));
+ return;
+ }
+
+ PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
+ PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000,
+ xt->fref % 1000));
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ /* Change the BBPLL drive strength to 8 for all channels */
+ buf_strength = 0x888888;
+ AND_REG(osh, &cc->min_res_mask,
+ ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+ PMURES_BIT(RES4329_HT_AVAIL)));
+ AND_REG(osh, &cc->max_res_mask,
+ ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+ PMURES_BIT(RES4329_HT_AVAIL)));
+ SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ if (xt->fref == 38400)
+ tmp = 0x200024C0;
+ else if (xt->fref == 37400)
+ tmp = 0x20004500;
+ else if (xt->fref == 26000)
+ tmp = 0x200024C0;
+ else
+ tmp = 0x200005C0; /* Chip Dflt Settings */
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ tmp =
+ R_REG(osh,
+ &cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
+ if ((xt->fref == 38400) || (xt->fref == 37400)
+ || (xt->fref == 26000))
+ tmp |= 0x15;
+ else
+ tmp |= 0x25; /* Chip Dflt Settings */
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+ break;
+
+ case BCM4319_CHIP_ID:
+ /* Change the BBPLL drive strength to 2 for all channels */
+ buf_strength = 0x222222;
+
+ /* Make sure the PLL is off */
+ /* WAR65104: Disable the HT_AVAIL resource first and then
+ * after a delay (more than downtime for HT_AVAIL) remove the
+ * BBPLL resource; backplane clock moves to ALP from HT.
+ */
+ AND_REG(osh, &cc->min_res_mask,
+ ~(PMURES_BIT(RES4319_HT_AVAIL)));
+ AND_REG(osh, &cc->max_res_mask,
+ ~(PMURES_BIT(RES4319_HT_AVAIL)));
+
+ OSL_DELAY(100);
+ AND_REG(osh, &cc->min_res_mask,
+ ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+ AND_REG(osh, &cc->max_res_mask,
+ ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+
+ OSL_DELAY(100);
+ SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ tmp = 0x200005c0;
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+ break;
+
+ case BCM4336_CHIP_ID:
+ AND_REG(osh, &cc->min_res_mask,
+ ~(PMURES_BIT(RES4336_HT_AVAIL) |
+ PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+ AND_REG(osh, &cc->max_res_mask,
+ ~(PMURES_BIT(RES4336_HT_AVAIL) |
+ PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+ OSL_DELAY(100);
+ SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
+ break;
+
+ case BCM4330_CHIP_ID:
+ AND_REG(osh, &cc->min_res_mask,
+ ~(PMURES_BIT(RES4330_HT_AVAIL) |
+ PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+ AND_REG(osh, &cc->max_res_mask,
+ ~(PMURES_BIT(RES4330_HT_AVAIL) |
+ PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+ OSL_DELAY(100);
+ SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ PMU_MSG(("Done masking\n"));
+
+ /* Write p1div and p2div to pllcontrol[0] */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ tmp = R_REG(osh, &cc->pllcontrol_data) &
+ ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
+ tmp |=
+ ((xt->
+ p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
+ ((xt->
+ p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+
+ if ((CHIPID(sih->chip) == BCM4330_CHIP_ID))
+ si_pmu_set_4330_plldivs(sih);
+
+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID)
+ && (CHIPREV(sih->chiprev) == 0)) {
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
+ tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+ }
+ if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4330_CHIP_ID))
+ ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
+ else
+ ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
+
+ /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ tmp = R_REG(osh, &cc->pllcontrol_data) &
+ ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
+ tmp |=
+ ((xt->
+ ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
+ PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
+ PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
+ PMU1_PLL0_PC2_NDIV_MODE_MASK);
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+
+ /* Write ndiv_frac to pllcontrol[3] */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
+ tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
+ PMU1_PLL0_PC3_NDIV_FRAC_MASK);
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+
+ /* Write clock driving strength to pllcontrol[5] */
+ if (buf_strength) {
+ PMU_MSG(("Adjusting PLL buffer drive strength: %x\n",
+ buf_strength));
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ tmp =
+ R_REG(osh,
+ &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
+ tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+ }
+
+ PMU_MSG(("Done pll\n"));
+
+ /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
+ * to be updated.
+ */
+ if ((CHIPID(sih->chip) == BCM4319_CHIP_ID)
+ && (xt->fref != XTAL_FREQ_30000MHZ)) {
+ W_REG(osh, &cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
+ tmp =
+ R_REG(osh,
+ &cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
+ if (xt->fref == XTAL_FREQ_24000MHZ) {
+ tmp |=
+ (CCTL_4319USB_24MHZ_PLL_SEL <<
+ CCTL_4319USB_XTAL_SEL_SHIFT);
+ } else if (xt->fref == XTAL_FREQ_48000MHZ) {
+ tmp |=
+ (CCTL_4319USB_48MHZ_PLL_SEL <<
+ CCTL_4319USB_XTAL_SEL_SHIFT);
+ }
+ W_REG(osh, &cc->chipcontrol_data, tmp);
+ }
+
+ /* Flush deferred pll control registers writes */
+ if (sih->pmurev >= 2)
+ OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
+
+ /* Write XtalFreq. Set the divisor also. */
+ tmp = R_REG(osh, &cc->pmucontrol) &
+ ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
+ tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+ PCTL_ILP_DIV_MASK) |
+ ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
+
+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID)
+ && CHIPREV(sih->chiprev) == 0) {
+ /* clear the htstretch before clearing HTReqEn */
+ AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT);
+ tmp &= ~PCTL_HT_REQ_EN;
+ }
+
+ W_REG(osh, &cc->pmucontrol, tmp);
+}
+
+/* query the CPU clock frequency */
+static uint32
+BCMINITFN(si_pmu1_cpuclk0) (si_t *sih, osl_t *osh, chipcregs_t *cc)
+{
+ uint32 tmp, m1div;
+#ifdef BCMDBG
+ uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
+ uint32 fref;
+#endif
+ uint32 FVCO = si_pmu1_pllfvco0(sih);
+
+ /* Read m1div from pllcontrol[1] */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
+
+#ifdef BCMDBG
+ /* Read p2div/p1div from pllcontrol[0] */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
+ p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
+
+ /* Calculate fvco based on xtal freq and ndiv and pdiv */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ ndiv_int =
+ (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ ndiv_frac =
+ (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >>
+ PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
+
+ fref = si_pmu1_alpclk0(sih, osh, cc) / 1000;
+
+ fvco = (fref * ndiv_int) << 8;
+ fvco += (fref * (ndiv_frac >> 12)) >> 4;
+ fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
+ fvco >>= 8;
+ fvco *= p2div;
+ fvco /= p1div;
+ fvco /= 1000;
+ fvco *= 1000;
+
+ PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco));
+
+ FVCO = fvco;
+#endif /* BCMDBG */
+
+ /* Return ARM/SB clock */
+ return FVCO / m1div * 1000;
+}
+
+/* initialize PLL */
+void BCMATTACHFN(si_pmu_pll_init) (si_t *sih, osl_t *osh, uint xtalfreq)
+{
+ chipcregs_t *cc;
+ uint origidx;
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ if (xtalfreq == 0)
+ xtalfreq = 38400;
+ si_pmu1_pllinit0(sih, osh, cc, xtalfreq);
+ break;
+ case BCM4313_CHIP_ID:
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ /* ??? */
+ break;
+ case BCM4319_CHIP_ID:
+ case BCM4336_CHIP_ID:
+ case BCM4330_CHIP_ID:
+ si_pmu1_pllinit0(sih, osh, cc, xtalfreq);
+ break;
+ default:
+ PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
+ bcm_chipname(sih->chip, chn, 8), sih->chiprev,
+ sih->pmurev));
+ break;
+ }
+
+#ifdef BCMDBG_FORCEHT
+ OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT);
+#endif
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+/* query alp/xtal clock frequency */
+uint32 BCMINITFN(si_pmu_alp_clock) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock = ALP_CLOCK;
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ case BCM4716_CHIP_ID:
+ case BCM4748_CHIP_ID:
+ case BCM47162_CHIP_ID:
+ case BCM4313_CHIP_ID:
+ case BCM5357_CHIP_ID:
+ /* always 20Mhz */
+ clock = 20000 * 1000;
+ break;
+ case BCM4329_CHIP_ID:
+ case BCM4319_CHIP_ID:
+ case BCM4336_CHIP_ID:
+ case BCM4330_CHIP_ID:
+
+ clock = si_pmu1_alpclk0(sih, osh, cc);
+ break;
+ case BCM5356_CHIP_ID:
+ /* always 25Mhz */
+ clock = 25000 * 1000;
+ break;
+ default:
+ PMU_MSG(("No ALP clock specified "
+ "for chip %s rev %d pmurev %d, using default %d Hz\n",
+ bcm_chipname(sih->chip, chn, 8), sih->chiprev,
+ sih->pmurev, clock));
+ break;
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+ return clock;
+}
+
+/* Find the output of the "m" pll divider given pll controls that start with
+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
+ */
+static uint32
+BCMINITFN(si_pmu5_clock) (si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0,
+ uint m) {
+ uint32 tmp, div, ndiv, p1, p2, fc;
+
+ if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) {
+ PMU_ERROR(("%s: Bad pll0: %d\n", __func__, pll0));
+ return 0;
+ }
+
+ /* Strictly there is an m5 divider, but I'm not sure we use it */
+ if ((m == 0) || (m > 4)) {
+ PMU_ERROR(("%s: Bad m divider: %d\n", __func__, m));
+ return 0;
+ }
+
+ if (CHIPID(sih->chip) == BCM5357_CHIP_ID) {
+ /* Detect failure in clock setting */
+ if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) {
+ return 133 * 1000000;
+ }
+ }
+
+ W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF);
+ (void)R_REG(osh, &cc->pllcontrol_addr);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT;
+ p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT;
+
+ W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF);
+ (void)R_REG(osh, &cc->pllcontrol_addr);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK;
+
+ W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF);
+ (void)R_REG(osh, &cc->pllcontrol_addr);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT;
+
+ /* Do calculation in Mhz */
+ fc = si_pmu_alp_clock(sih, osh) / 1000000;
+ fc = (p1 * ndiv * fc) / p2;
+
+ PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
+ __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div));
+
+ /* Return clock in Hertz */
+ return (fc / div) * 1000000;
+}
+
+/* query backplane clock frequency */
+/* For designs that feed the same clock to both backplane
+ * and CPU just return the CPU clock speed.
+ */
+uint32 BCMINITFN(si_pmu_si_clock) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock = HT_CLOCK;
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ /* 96MHz backplane clock */
+ clock = 96000 * 1000;
+ break;
+ case BCM4716_CHIP_ID:
+ case BCM4748_CHIP_ID:
+ case BCM47162_CHIP_ID:
+ clock =
+ si_pmu5_clock(sih, osh, cc, PMU4716_MAINPLL_PLL0,
+ PMU5_MAINPLL_SI);
+ break;
+ case BCM4329_CHIP_ID:
+ if (CHIPREV(sih->chiprev) == 0)
+ clock = 38400 * 1000;
+ else
+ clock = si_pmu1_cpuclk0(sih, osh, cc);
+ break;
+ case BCM4319_CHIP_ID:
+ case BCM4336_CHIP_ID:
+ case BCM4330_CHIP_ID:
+ clock = si_pmu1_cpuclk0(sih, osh, cc);
+ break;
+ case BCM4313_CHIP_ID:
+ /* 80MHz backplane clock */
+ clock = 80000 * 1000;
+ break;
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ clock =
+ (cc->chipstatus & CST43236_BP_CLK) ? (120000 *
+ 1000) : (96000 *
+ 1000);
+ break;
+ case BCM5356_CHIP_ID:
+ clock =
+ si_pmu5_clock(sih, osh, cc, PMU5356_MAINPLL_PLL0,
+ PMU5_MAINPLL_SI);
+ break;
+ case BCM5357_CHIP_ID:
+ clock =
+ si_pmu5_clock(sih, osh, cc, PMU5357_MAINPLL_PLL0,
+ PMU5_MAINPLL_SI);
+ break;
+ default:
+ PMU_MSG(("No backplane clock specified "
+ "for chip %s rev %d pmurev %d, using default %d Hz\n",
+ bcm_chipname(sih->chip, chn, 8), sih->chiprev,
+ sih->pmurev, clock));
+ break;
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+ return clock;
+}
+
+/* query CPU clock frequency */
+uint32 BCMINITFN(si_pmu_cpu_clock) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ if ((sih->pmurev >= 5) &&
+ !((CHIPID(sih->chip) == BCM4329_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43236_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4330_CHIP_ID))) {
+ uint pll;
+
+ switch (CHIPID(sih->chip)) {
+ case BCM5356_CHIP_ID:
+ pll = PMU5356_MAINPLL_PLL0;
+ break;
+ case BCM5357_CHIP_ID:
+ pll = PMU5357_MAINPLL_PLL0;
+ break;
+ default:
+ pll = PMU4716_MAINPLL_PLL0;
+ break;
+ }
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_CPU);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+ } else
+ clock = si_pmu_si_clock(sih, osh);
+
+ return clock;
+}
+
+/* query memory clock frequency */
+uint32 BCMINITFN(si_pmu_mem_clock) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ if ((sih->pmurev >= 5) &&
+ !((CHIPID(sih->chip) == BCM4329_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4330_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43236_CHIP_ID))) {
+ uint pll;
+
+ switch (CHIPID(sih->chip)) {
+ case BCM5356_CHIP_ID:
+ pll = PMU5356_MAINPLL_PLL0;
+ break;
+ case BCM5357_CHIP_ID:
+ pll = PMU5357_MAINPLL_PLL0;
+ break;
+ default:
+ pll = PMU4716_MAINPLL_PLL0;
+ break;
+ }
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_MEM);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+ } else {
+ clock = si_pmu_si_clock(sih, osh);
+ }
+
+ return clock;
+}
+
+/* Measure ILP clock frequency */
+#define ILP_CALC_DUR 10 /* ms, make sure 1000 can be divided by it. */
+
+static uint32 ilpcycles_per_sec;
+
+uint32 BCMINITFN(si_pmu_ilp_clock) (si_t *sih, osl_t *osh)
+{
+ if (ISSIM_ENAB(sih))
+ return ILP_CLOCK;
+
+ if (ilpcycles_per_sec == 0) {
+ uint32 start, end, delta;
+ uint32 origidx = si_coreidx(sih);
+ chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+ start = R_REG(osh, &cc->pmutimer);
+ OSL_DELAY(ILP_CALC_DUR * 1000);
+ end = R_REG(osh, &cc->pmutimer);
+ delta = end - start;
+ ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
+ si_setcoreidx(sih, origidx);
+ }
+
+ return ilpcycles_per_sec;
+}
+
+/* SDIO Pad drive strength to select value mappings */
+typedef struct {
+ uint8 strength; /* Pad Drive Strength in mA */
+ uint8 sel; /* Chip-specific select value */
+} sdiod_drive_str_t;
+
+/* SDIO Drive Strength to sel value table for PMU Rev 1 */
+static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab1)[] = {
+ {
+ 4, 0x2}, {
+ 2, 0x3}, {
+ 1, 0x0}, {
+ 0, 0x0}
+ };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
+static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab2)[] = {
+ {
+ 12, 0x7}, {
+ 10, 0x6}, {
+ 8, 0x5}, {
+ 6, 0x4}, {
+ 4, 0x2}, {
+ 2, 0x1}, {
+ 0, 0x0}
+ };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
+static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab3)[] = {
+ {
+ 32, 0x7}, {
+ 26, 0x6}, {
+ 22, 0x5}, {
+ 16, 0x4}, {
+ 12, 0x3}, {
+ 8, 0x2}, {
+ 4, 0x1}, {
+ 0, 0x0}
+ };
+
+#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
+
+void
+BCMINITFN(si_sdiod_drive_strength_init) (si_t *sih, osl_t *osh,
+ uint32 drivestrength) {
+ chipcregs_t *cc;
+ uint origidx, intr_val = 0;
+ sdiod_drive_str_t *str_tab = NULL;
+ uint32 str_mask = 0;
+ uint32 str_shift = 0;
+#ifdef BCMDBG
+ char chn[8];
+#endif
+
+ if (!(sih->cccaps & CC_CAP_PMU)) {
+ return;
+ }
+
+ /* Remember original core before switch to chipc */
+ cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
+ &intr_val);
+
+ switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) {
+ case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
+ str_tab = (sdiod_drive_str_t *) &sdiod_drive_strength_tab3;
+ str_mask = 0x00003800;
+ str_shift = 11;
+ break;
+
+ default:
+ PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
+
+ break;
+ }
+
+ if (str_tab != NULL) {
+ uint32 drivestrength_sel = 0;
+ uint32 cc_data_temp;
+ int i;
+
+ for (i = 0; str_tab[i].strength != 0; i++) {
+ if (drivestrength >= str_tab[i].strength) {
+ drivestrength_sel = str_tab[i].sel;
+ break;
+ }
+ }
+
+ W_REG(osh, &cc->chipcontrol_addr, 1);
+ cc_data_temp = R_REG(osh, &cc->chipcontrol_data);
+ cc_data_temp &= ~str_mask;
+ drivestrength_sel <<= str_shift;
+ cc_data_temp |= drivestrength_sel;
+ W_REG(osh, &cc->chipcontrol_data, cc_data_temp);
+
+ PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
+ drivestrength, cc_data_temp));
+ }
+
+ /* Return to original core */
+ si_restore_core(sih, origidx, intr_val);
+}
+
+/* initialize PMU */
+void BCMATTACHFN(si_pmu_init) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ if (sih->pmurev == 1)
+ AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
+ else if (sih->pmurev >= 2)
+ OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT);
+
+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
+ /* Fix for 4329b0 bad LPOM state. */
+ W_REG(osh, &cc->regcontrol_addr, 2);
+ OR_REG(osh, &cc->regcontrol_data, 0x100);
+
+ W_REG(osh, &cc->regcontrol_addr, 3);
+ OR_REG(osh, &cc->regcontrol_data, 0x4);
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+/* Return up time in ILP cycles for the given resource. */
+static uint
+BCMINITFN(si_pmu_res_uptime) (si_t *sih, osl_t *osh, chipcregs_t *cc,
+ uint8 rsrc) {
+ uint32 deps;
+ uint up, i, dup, dmax;
+ uint32 min_mask = 0, max_mask = 0;
+
+ /* uptime of resource 'rsrc' */
+ W_REG(osh, &cc->res_table_sel, rsrc);
+ up = (R_REG(osh, &cc->res_updn_timer) >> 8) & 0xff;
+
+ /* direct dependancies of resource 'rsrc' */
+ deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), FALSE);
+ for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+ if (!(deps & PMURES_BIT(i)))
+ continue;
+ deps &= ~si_pmu_res_deps(sih, osh, cc, PMURES_BIT(i), TRUE);
+ }
+ si_pmu_res_masks(sih, &min_mask, &max_mask);
+ deps &= ~min_mask;
+
+ /* max uptime of direct dependancies */
+ dmax = 0;
+ for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+ if (!(deps & PMURES_BIT(i)))
+ continue;
+ dup = si_pmu_res_uptime(sih, osh, cc, (uint8) i);
+ if (dmax < dup)
+ dmax = dup;
+ }
+
+ PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", rsrc, up, deps, dmax));
+
+ return up + dmax + PMURES_UP_TRANSITION;
+}
+
+/* Return dependancies (direct or all/indirect) for the given resources */
+static uint32
+si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs,
+ bool all)
+{
+ uint32 deps = 0;
+ uint32 i;
+
+ for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+ if (!(rsrcs & PMURES_BIT(i)))
+ continue;
+ W_REG(osh, &cc->res_table_sel, i);
+ deps |= R_REG(osh, &cc->res_dep_mask);
+ }
+
+ return !all ? deps : (deps
+ ? (deps |
+ si_pmu_res_deps(sih, osh, cc, deps,
+ TRUE)) : 0);
+}
+
+/* power up/down OTP through PMU resources */
+void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 rsrcs = 0; /* rsrcs to turn on/off OTP power */
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Don't do anything if OTP is disabled */
+ if (si_is_otp_disabled(sih)) {
+ PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
+ return;
+ }
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ rsrcs = PMURES_BIT(RES4329_OTP_PU);
+ break;
+ case BCM4319_CHIP_ID:
+ rsrcs = PMURES_BIT(RES4319_OTP_PU);
+ break;
+ case BCM4336_CHIP_ID:
+ rsrcs = PMURES_BIT(RES4336_OTP_PU);
+ break;
+ case BCM4330_CHIP_ID:
+ rsrcs = PMURES_BIT(RES4330_OTP_PU);
+ break;
+ default:
+ break;
+ }
+
+ if (rsrcs != 0) {
+ uint32 otps;
+
+ /* Figure out the dependancies (exclude min_res_mask) */
+ uint32 deps = si_pmu_res_deps(sih, osh, cc, rsrcs, TRUE);
+ uint32 min_mask = 0, max_mask = 0;
+ si_pmu_res_masks(sih, &min_mask, &max_mask);
+ deps &= ~min_mask;
+ /* Turn on/off the power */
+ if (on) {
+ PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n",
+ rsrcs | deps));
+ OR_REG(osh, &cc->min_res_mask, (rsrcs | deps));
+ SPINWAIT(!(R_REG(osh, &cc->res_state) & rsrcs),
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT(R_REG(osh, &cc->res_state) & rsrcs);
+ } else {
+ PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n",
+ rsrcs | deps));
+ AND_REG(osh, &cc->min_res_mask, ~(rsrcs | deps));
+ }
+
+ SPINWAIT((((otps = R_REG(osh, &cc->otpstatus)) & OTPS_READY) !=
+ (on ? OTPS_READY : 0)), 100);
+ ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0));
+ if ((otps & OTPS_READY) != (on ? OTPS_READY : 0))
+ PMU_MSG(("OTP ready bit not %s after wait\n",
+ (on ? "ON" : "OFF")));
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+void si_pmu_rcal(si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:{
+ uint8 rcal_code;
+ uint32 val;
+
+ /* Kick RCal */
+ W_REG(osh, &cc->chipcontrol_addr, 1);
+
+ /* Power Down RCAL Block */
+ AND_REG(osh, &cc->chipcontrol_data, ~0x04);
+
+ /* Power Up RCAL block */
+ OR_REG(osh, &cc->chipcontrol_data, 0x04);
+
+ /* Wait for completion */
+ SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08),
+ 10 * 1000 * 1000);
+ ASSERT(R_REG(osh, &cc->chipstatus) & 0x08);
+
+ /* Drop the LSB to convert from 5 bit code to 4 bit code */
+ rcal_code =
+ (uint8) (R_REG(osh, &cc->chipstatus) >> 5) & 0x0f;
+
+ PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
+ R_REG(osh, &cc->chipstatus), rcal_code));
+
+ /* Write RCal code into pmu_vreg_ctrl[32:29] */
+ W_REG(osh, &cc->regcontrol_addr, 0);
+ val =
+ R_REG(osh,
+ &cc->
+ regcontrol_data) & ~((uint32) 0x07 << 29);
+ val |= (uint32) (rcal_code & 0x07) << 29;
+ W_REG(osh, &cc->regcontrol_data, val);
+ W_REG(osh, &cc->regcontrol_addr, 1);
+ val = R_REG(osh, &cc->regcontrol_data) & ~(uint32) 0x01;
+ val |= (uint32) ((rcal_code >> 3) & 0x01);
+ W_REG(osh, &cc->regcontrol_data, val);
+
+ /* Write RCal code into pmu_chip_ctrl[33:30] */
+ W_REG(osh, &cc->chipcontrol_addr, 0);
+ val =
+ R_REG(osh,
+ &cc->
+ chipcontrol_data) & ~((uint32) 0x03 << 30);
+ val |= (uint32) (rcal_code & 0x03) << 30;
+ W_REG(osh, &cc->chipcontrol_data, val);
+ W_REG(osh, &cc->chipcontrol_addr, 1);
+ val =
+ R_REG(osh, &cc->chipcontrol_data) & ~(uint32) 0x03;
+ val |= (uint32) ((rcal_code >> 2) & 0x03);
+ W_REG(osh, &cc->chipcontrol_data, val);
+
+ /* Set override in pmu_chip_ctrl[29] */
+ W_REG(osh, &cc->chipcontrol_addr, 0);
+ OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29));
+
+ /* Power off RCal block */
+ W_REG(osh, &cc->chipcontrol_addr, 1);
+ AND_REG(osh, &cc->chipcontrol_data, ~0x04);
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+void si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid)
+{
+ chipcregs_t *cc;
+ uint origidx, intr_val;
+ uint32 tmp = 0;
+
+ /* Remember original core before switch to chipc */
+ cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
+ &intr_val);
+ ASSERT(cc != NULL);
+
+ /* force the HT off */
+ if (CHIPID(sih->chip) == BCM4336_CHIP_ID) {
+ tmp = R_REG(osh, &cc->max_res_mask);
+ tmp &= ~RES4336_HT_AVAIL;
+ W_REG(osh, &cc->max_res_mask, tmp);
+ /* wait for the ht to really go away */
+ SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
+ 10000);
+ ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0);
+ }
+
+ /* update the pll changes */
+ si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid);
+
+ /* enable HT back on */
+ if (CHIPID(sih->chip) == BCM4336_CHIP_ID) {
+ tmp = R_REG(osh, &cc->max_res_mask);
+ tmp |= RES4336_HT_AVAIL;
+ W_REG(osh, &cc->max_res_mask, tmp);
+ }
+
+ /* Return to original core */
+ si_restore_core(sih, origidx, intr_val);
+}
+
+static void
+si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh,
+ uint8 spuravoid)
+{
+ uint32 tmp = 0;
+ uint8 phypll_offset = 0;
+ uint8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
+ uint8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
+
+ switch (CHIPID(sih->chip)) {
+ case BCM5357_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+
+ /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */
+ phypll_offset = (CHIPID(sih->chip) == BCM5357_CHIP_ID) ? 6 : 0;
+
+ /* RMW only the P1 divider */
+ W_REG(osh, &cc->pllcontrol_addr,
+ PMU1_PLL0_PLLCTL0 + phypll_offset);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
+ tmp |=
+ (bcm5357_bcm43236_p1div[spuravoid] <<
+ PMU1_PLL0_PC0_P1DIV_SHIFT);
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+
+ /* RMW only the int feedback divider */
+ W_REG(osh, &cc->pllcontrol_addr,
+ PMU1_PLL0_PLLCTL2 + phypll_offset);
+ tmp = R_REG(osh, &cc->pllcontrol_data);
+ tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
+ tmp |=
+ (bcm5357_bcm43236_ndiv[spuravoid]) <<
+ PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+ W_REG(osh, &cc->pllcontrol_data, tmp);
+
+ tmp = 1 << 10;
+ break;
+
+ case BCM4331_CHIP_ID:
+ if (spuravoid == 2) {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11500014);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x0FC00a08);
+ } else if (spuravoid == 1) {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11500014);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x0F600a08);
+ } else {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11100014);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x03000a08);
+ }
+ tmp = 1 << 10;
+ break;
+
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM6362_CHIP_ID:
+ if (spuravoid == 1) {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11500010);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x000C0C06);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x0F600a08);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ W_REG(osh, &cc->pllcontrol_data, 0x00000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x2001E920);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888815);
+ } else {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11100010);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x000c0c06);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x03000a08);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ W_REG(osh, &cc->pllcontrol_data, 0x00000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x200005c0);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888815);
+ }
+ tmp = 1 << 10;
+ break;
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11100008);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x0c000c06);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x03000a08);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ W_REG(osh, &cc->pllcontrol_data, 0x00000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x200005c0);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888855);
+
+ tmp = 1 << 10;
+ break;
+
+ case BCM4716_CHIP_ID:
+ case BCM4748_CHIP_ID:
+ case BCM47162_CHIP_ID:
+ if (spuravoid == 1) {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11500060);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x080C0C06);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x0F600000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ W_REG(osh, &cc->pllcontrol_data, 0x00000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x2001E924);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888815);
+ } else {
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11100060);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x080c0c06);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x03000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ W_REG(osh, &cc->pllcontrol_data, 0x00000000);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x200005c0);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888815);
+ }
+
+ tmp = 3 << 9;
+ break;
+
+ case BCM4319_CHIP_ID:
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x11100070);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x1014140a);
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888854);
+
+ if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x05201828);
+ } else { /* enable 40/80/160Mhz clock mode */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x05001828);
+ }
+ break;
+ case BCM4336_CHIP_ID:
+ /* Looks like these are only for default xtal freq 26MHz */
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ W_REG(osh, &cc->pllcontrol_data, 0x02100020);
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ W_REG(osh, &cc->pllcontrol_data, 0x0C0C0C0C);
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ W_REG(osh, &cc->pllcontrol_data, 0x01240C0C);
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+ W_REG(osh, &cc->pllcontrol_data, 0x202C2820);
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ W_REG(osh, &cc->pllcontrol_data, 0x88888825);
+
+ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ if (spuravoid == 1) {
+ W_REG(osh, &cc->pllcontrol_data, 0x00EC4EC4);
+ } else {
+ W_REG(osh, &cc->pllcontrol_data, 0x00762762);
+ }
+
+ tmp = PCTL_PLL_PLLCTL_UPD;
+ break;
+
+ default:
+ PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", __func__, bcm_chipname(sih->chip, chn, 8)));
+ break;
+ }
+
+ tmp |= R_REG(osh, &cc->pmucontrol);
+ W_REG(osh, &cc->pmucontrol, tmp);
+}
+
+bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh)
+{
+ uint idx;
+ chipcregs_t *cc;
+ bool st;
+
+ /* Remember original core before switch to chipc */
+ idx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
+ != 0;
+ break;
+ case BCM4319_CHIP_ID:
+ st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
+ != 0;
+ break;
+ case BCM4336_CHIP_ID:
+ st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
+ != 0;
+ break;
+ case BCM4330_CHIP_ID:
+ st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
+ != 0;
+ break;
+
+ /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
+ * Use OTP_INIT command to reset/refresh state.
+ */
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ st = TRUE;
+ break;
+ default:
+ st = TRUE;
+ break;
+ }
+
+ /* Return to original core */
+ si_setcoreidx(sih, idx);
+ return st;
+}
+
+void
+#if defined(BCMDBG)
+si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable)
+#else
+BCMATTACHFN(si_pmu_sprom_enable) (si_t *sih, osl_t *osh, bool enable)
+#endif
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+/* initialize PMU chip controls and other chip level stuff */
+void BCMATTACHFN(si_pmu_chip_init) (si_t *sih, osl_t *osh)
+{
+ uint origidx;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+#ifdef CHIPC_UART_ALWAYS_ON
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st),
+ CCS_FORCEALP, CCS_FORCEALP);
+#endif /* CHIPC_UART_ALWAYS_ON */
+
+ /* Gate off SPROM clock and chip select signals */
+ si_pmu_sprom_enable(sih, osh, FALSE);
+
+ /* Remember original core */
+ origidx = si_coreidx(sih);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+}
+
+/* initialize PMU switch/regulators */
+void BCMATTACHFN(si_pmu_swreg_init) (si_t *sih, osl_t *osh)
+{
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4336_CHIP_ID:
+ /* Reduce CLDO PWM output voltage to 1.2V */
+ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
+ /* Reduce CLDO BURST output voltage to 1.2V */
+ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST,
+ 0xe);
+ /* Reduce LNLDO1 output voltage to 1.2V */
+ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe);
+ if (CHIPREV(sih->chiprev) == 0)
+ si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
+ break;
+
+ case BCM4330_CHIP_ID:
+ /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
+ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+void si_pmu_radio_enable(si_t *sih, bool enable)
+{
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4319_CHIP_ID:
+ if (enable)
+ si_write_wrapperreg(sih, AI_OOBSELOUTB74,
+ (uint32) 0x868584);
+ else
+ si_write_wrapperreg(sih, AI_OOBSELOUTB74,
+ (uint32) 0x060584);
+ break;
+ }
+}
+
+/* Wait for a particular clock level to be on the backplane */
+uint32
+si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk,
+ uint32 delay)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ if (delay)
+ SPINWAIT(((R_REG(osh, &cc->pmustatus) & clk) != clk), delay);
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+
+ return R_REG(osh, &cc->pmustatus) & clk;
+}
+
+/*
+ * Measures the ALP clock frequency in KHz. Returns 0 if not possible.
+ * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
+ */
+
+#define EXT_ILP_HZ 32768
+
+uint32 BCMATTACHFN(si_pmu_measure_alpclk) (si_t *sih, osl_t *osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 alp_khz;
+
+ if (sih->pmurev < 10)
+ return 0;
+
+ ASSERT(sih->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT(cc != NULL);
+
+ if (R_REG(osh, &cc->pmustatus) & PST_EXTLPOAVAIL) {
+ uint32 ilp_ctr, alp_hz;
+
+ /* Enable the reg to measure the freq, in case disabled before */
+ W_REG(osh, &cc->pmu_xtalfreq,
+ 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
+
+ /* Delay for well over 4 ILP clocks */
+ OSL_DELAY(1000);
+
+ /* Read the latched number of ALP ticks per 4 ILP ticks */
+ ilp_ctr =
+ R_REG(osh,
+ &cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
+
+ /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
+ W_REG(osh, &cc->pmu_xtalfreq, 0);
+
+ /* Calculate ALP frequency */
+ alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
+
+ /* Round to nearest 100KHz, and at the same time convert to KHz */
+ alp_khz = (alp_hz + 50000) / 100000 * 100;
+ } else
+ alp_khz = 0;
+
+ /* Return to original core */
+ si_setcoreidx(sih, origidx);
+
+ return alp_khz;
+}
+
+static void BCMATTACHFN(si_pmu_set_4330_plldivs) (si_t *sih)
+{
+ uint32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
+ uint32 m1div, m2div, m3div, m4div, m5div, m6div;
+ uint32 pllc1, pllc2;
+
+ m2div = m3div = m4div = m6div = FVCO / 80;
+ m5div = FVCO / 160;
+
+ if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+ m1div = FVCO / 80;
+ else
+ m1div = FVCO / 90;
+ pllc1 =
+ (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
+ PMU1_PLL0_PC1_M2DIV_SHIFT) |
+ (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
+ PMU1_PLL0_PC1_M4DIV_SHIFT);
+ si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
+
+ pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
+ pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
+ pllc2 |=
+ ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
+ (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
+ si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
+}
diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c
new file mode 100644
index 000000000000..3726e0273342
--- /dev/null
+++ b/drivers/staging/brcm80211/util/linux_osl.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmendian.h>
+#include <linuxver.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <linux/delay.h>
+#ifdef mips
+#include <asm/paccess.h>
+#endif /* mips */
+#include <pcicfg.h>
+
+#include <linux/fs.h>
+
+#define PCI_CFG_RETRY 10
+
+#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */
+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
+
+typedef struct bcm_mem_link {
+ struct bcm_mem_link *prev;
+ struct bcm_mem_link *next;
+ uint size;
+ int line;
+ char file[BCM_MEM_FILENAME_LEN];
+} bcm_mem_link_t;
+
+struct osl_info {
+ osl_pubinfo_t pub;
+ uint magic;
+ void *pdev;
+ uint malloced;
+ uint failed;
+ uint bustype;
+ bcm_mem_link_t *dbgmem_list;
+};
+
+/* Global ASSERT type flag */
+uint32 g_assert_type;
+
+static int16 linuxbcmerrormap[] = { 0, /* 0 */
+ -EINVAL, /* BCME_ERROR */
+ -EINVAL, /* BCME_BADARG */
+ -EINVAL, /* BCME_BADOPTION */
+ -EINVAL, /* BCME_NOTUP */
+ -EINVAL, /* BCME_NOTDOWN */
+ -EINVAL, /* BCME_NOTAP */
+ -EINVAL, /* BCME_NOTSTA */
+ -EINVAL, /* BCME_BADKEYIDX */
+ -EINVAL, /* BCME_RADIOOFF */
+ -EINVAL, /* BCME_NOTBANDLOCKED */
+ -EINVAL, /* BCME_NOCLK */
+ -EINVAL, /* BCME_BADRATESET */
+ -EINVAL, /* BCME_BADBAND */
+ -E2BIG, /* BCME_BUFTOOSHORT */
+ -E2BIG, /* BCME_BUFTOOLONG */
+ -EBUSY, /* BCME_BUSY */
+ -EINVAL, /* BCME_NOTASSOCIATED */
+ -EINVAL, /* BCME_BADSSIDLEN */
+ -EINVAL, /* BCME_OUTOFRANGECHAN */
+ -EINVAL, /* BCME_BADCHAN */
+ -EFAULT, /* BCME_BADADDR */
+ -ENOMEM, /* BCME_NORESOURCE */
+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */
+ -EMSGSIZE, /* BCME_BADLENGTH */
+ -EINVAL, /* BCME_NOTREADY */
+ -EPERM, /* BCME_NOTPERMITTED */
+ -ENOMEM, /* BCME_NOMEM */
+ -EINVAL, /* BCME_ASSOCIATED */
+ -ERANGE, /* BCME_RANGE */
+ -EINVAL, /* BCME_NOTFOUND */
+ -EINVAL, /* BCME_WME_NOT_ENABLED */
+ -EINVAL, /* BCME_TSPEC_NOTFOUND */
+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */
+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */
+ -EIO, /* BCME_SDIO_ERROR */
+ -ENODEV, /* BCME_DONGLE_DOWN */
+ -EINVAL, /* BCME_VERSION */
+ -EIO, /* BCME_TXFAIL */
+ -EIO, /* BCME_RXFAIL */
+ -EINVAL, /* BCME_NODEVICE */
+ -EINVAL, /* BCME_NMODE_DISABLED */
+ -ENODATA, /* BCME_NONRESIDENT */
+
+/* When an new error code is added to bcmutils.h, add os
+ * spcecific error translation here as well
+ */
+/* check if BCME_LAST changed since the last time this function was updated */
+#if BCME_LAST != -42
+#error "You need to add a OS error translation in the linuxbcmerrormap \
+ for new error code defined in bcmutils.h"
+#endif
+};
+
+/* translate bcmerrors into linux errors */
+int osl_error(int bcmerror)
+{
+ if (bcmerror > 0)
+ bcmerror = 0;
+ else if (bcmerror < BCME_LAST)
+ bcmerror = BCME_ERROR;
+
+ /* Array bounds covered by ASSERT in osl_attach */
+ return linuxbcmerrormap[-bcmerror];
+}
+
+osl_t *osl_attach(void *pdev, uint bustype, bool pkttag)
+{
+ osl_t *osh;
+
+ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
+ ASSERT(osh);
+
+ bzero(osh, sizeof(osl_t));
+
+ /* Check that error map has the right number of entries in it */
+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
+
+ osh->magic = OS_HANDLE_MAGIC;
+ osh->malloced = 0;
+ osh->failed = 0;
+ osh->dbgmem_list = NULL;
+ osh->pdev = pdev;
+ osh->pub.pkttag = pkttag;
+ osh->bustype = bustype;
+
+ switch (bustype) {
+ case PCI_BUS:
+ case SI_BUS:
+ osh->pub.mmbus = TRUE;
+ break;
+ case JTAG_BUS:
+ case SDIO_BUS:
+ case USB_BUS:
+ case SPI_BUS:
+ case RPC_BUS:
+ osh->pub.mmbus = FALSE;
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+#ifdef BCMDBG
+ if (pkttag) {
+ struct sk_buff *skb;
+ ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb));
+ }
+#endif
+ return osh;
+}
+
+void osl_detach(osl_t *osh)
+{
+ if (osh == NULL)
+ return;
+
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+ kfree(osh);
+}
+
+/* Return a new packet. zero out pkttag */
+void *BCMFASTPATH osl_pktget(osl_t *osh, uint len)
+{
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(len);
+ if (skb) {
+ skb_put(skb, len);
+ skb->priority = 0;
+
+ osh->pub.pktalloced++;
+ }
+
+ return (void *)skb;
+}
+
+/* Free the driver packet. Free the tag if present */
+void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send)
+{
+ struct sk_buff *skb, *nskb;
+ int nest = 0;
+
+ skb = (struct sk_buff *)p;
+ ASSERT(skb);
+
+ if (send && osh->pub.tx_fn)
+ osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);
+
+ /* perversion: we use skb->next to chain multi-skb packets */
+ while (skb) {
+ nskb = skb->next;
+ skb->next = NULL;
+
+ if (skb->destructor)
+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
+ * destructor exists
+ */
+ dev_kfree_skb_any(skb);
+ else
+ /* can free immediately (even in_irq()) if destructor
+ * does not exist
+ */
+ dev_kfree_skb(skb);
+
+ osh->pub.pktalloced--;
+ nest++;
+ skb = nskb;
+ }
+}
+
+uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size)
+{
+ uint val = 0;
+ uint retry = PCI_CFG_RETRY;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ /* only 4byte access supported */
+ ASSERT(size == 4);
+
+ do {
+ pci_read_config_dword(osh->pdev, offset, &val);
+ if (val != 0xffffffff)
+ break;
+ } while (retry--);
+
+#ifdef BCMDBG
+ if (retry < PCI_CFG_RETRY)
+ printk("PCI CONFIG READ access to %d required %d retries\n",
+ offset, (PCI_CFG_RETRY - retry));
+#endif /* BCMDBG */
+
+ return val;
+}
+
+void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
+{
+ uint retry = PCI_CFG_RETRY;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ /* only 4byte access supported */
+ ASSERT(size == 4);
+
+ do {
+ pci_write_config_dword(osh->pdev, offset, val);
+ if (offset != PCI_BAR0_WIN)
+ break;
+ if (osl_pci_read_config(osh, offset, size) == val)
+ break;
+ } while (retry--);
+
+#ifdef BCMDBG
+ if (retry < PCI_CFG_RETRY)
+ printk("PCI CONFIG WRITE access to %d required %d retries\n",
+ offset, (PCI_CFG_RETRY - retry));
+#endif /* BCMDBG */
+}
+
+/* return bus # for the pci device pointed by osh->pdev */
+uint osl_pci_bus(osl_t *osh)
+{
+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return ((struct pci_dev *)osh->pdev)->bus->number;
+}
+
+/* return slot # for the pci device pointed by osh->pdev */
+uint osl_pci_slot(osl_t *osh)
+{
+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
+}
+
+static void
+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
+{
+}
+
+void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+ osl_pcmcia_attr(osh, offset, (char *)buf, size, FALSE);
+}
+
+void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+ osl_pcmcia_attr(osh, offset, (char *)buf, size, TRUE);
+}
+
+void *osl_malloc(osl_t *osh, uint size)
+{
+ void *addr;
+
+ /* only ASSERT if osh is defined */
+ if (osh)
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+
+ addr = kmalloc(size, GFP_ATOMIC);
+ if (addr == NULL) {
+ if (osh)
+ osh->failed++;
+ return NULL;
+ }
+ if (osh)
+ osh->malloced += size;
+
+ return addr;
+}
+
+void osl_mfree(osl_t *osh, void *addr, uint size)
+{
+ if (osh) {
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+ osh->malloced -= size;
+ }
+ kfree(addr);
+}
+
+uint osl_malloced(osl_t *osh)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return osh->malloced;
+}
+
+uint osl_malloc_failed(osl_t *osh)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return osh->failed;
+}
+
+uint osl_dma_consistent_align(void)
+{
+ return PAGE_SIZE;
+}
+
+void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits,
+ uint *alloced, ulong *pap)
+{
+ uint16 align = (1 << align_bits);
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
+ size += align;
+ *alloced = size;
+
+ return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap);
+}
+
+void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa);
+}
+
+uint BCMFASTPATH osl_dma_map(osl_t *osh, void *va, uint size, int direction)
+{
+ int dir;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
+ return pci_map_single(osh->pdev, va, size, dir);
+}
+
+void BCMFASTPATH osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
+{
+ int dir;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE;
+ pci_unmap_single(osh->pdev, (uint32) pa, size, dir);
+}
+
+#if defined(BCMDBG_ASSERT)
+void osl_assert(char *exp, char *file, int line)
+{
+ char tempbuf[256];
+ char *basename;
+
+ basename = strrchr(file, '/');
+ /* skip the '/' */
+ if (basename)
+ basename++;
+
+ if (!basename)
+ basename = file;
+
+#ifdef BCMDBG_ASSERT
+ snprintf(tempbuf, 256,
+ "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
+ basename, line);
+
+ /* Print assert message and give it time to be written to /var/log/messages */
+ if (!in_interrupt()) {
+ const int delay = 3;
+ printk("%s", tempbuf);
+ printk("panic in %d seconds\n", delay);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(delay * HZ);
+ }
+
+ switch (g_assert_type) {
+ case 0:
+ panic("%s", tempbuf);
+ break;
+ case 1:
+ printk("%s", tempbuf);
+ BUG();
+ break;
+ case 2:
+ printk("%s", tempbuf);
+ break;
+ default:
+ break;
+ }
+#endif /* BCMDBG_ASSERT */
+
+}
+#endif /* defined(BCMDBG_ASSERT) */
+
+void osl_delay(uint usec)
+{
+ uint d;
+
+ while (usec > 0) {
+ d = MIN(usec, 1000);
+ udelay(d);
+ usec -= d;
+ }
+}
+
+/* Clone a packet.
+ * The pkttag contents are NOT cloned.
+ */
+void *osl_pktdup(osl_t *osh, void *skb)
+{
+ void *p;
+
+ p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC);
+ if (p == NULL)
+ return NULL;
+
+ /* skb_clone copies skb->cb.. we don't want that */
+ if (osh->pub.pkttag)
+ bzero((void *)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ);
+
+ /* Increment the packet counter */
+ osh->pub.pktalloced++;
+ return p;
+}
+
+#ifdef BCMSDIO
+uint8 osl_readb(osl_t *osh, volatile uint8 *r)
+{
+ osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ return (uint8) ((rreg) (ctx, (void *)r, sizeof(uint8)));
+}
+
+uint16 osl_readw(osl_t *osh, volatile uint16 *r)
+{
+ osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ return (uint16) ((rreg) (ctx, (void *)r, sizeof(uint16)));
+}
+
+uint32 osl_readl(osl_t *osh, volatile uint32 *r)
+{
+ osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ return (uint32) ((rreg) (ctx, (void *)r, sizeof(uint32)));
+}
+
+void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v)
+{
+ osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ ((wreg) (ctx, (void *)r, v, sizeof(uint8)));
+}
+
+void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v)
+{
+ osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ ((wreg) (ctx, (void *)r, v, sizeof(uint16)));
+}
+
+void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v)
+{
+ osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn;
+ void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx;
+
+ ((wreg) (ctx, (void *)r, v, sizeof(uint32)));
+}
+#endif /* BCMSDIO */
+/* Linux Kernel: File Operations: end */
diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c
new file mode 100644
index 000000000000..0b4f562427e2
--- /dev/null
+++ b/drivers/staging/brcm80211/util/nicpci.c
@@ -0,0 +1,883 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <hndsoc.h>
+#include <bcmdevs.h>
+#include <sbchipc.h>
+#include <pci_core.h>
+#include <pcie_core.h>
+#include <nicpci.h>
+#include <pcicfg.h>
+
+typedef struct {
+ union {
+ sbpcieregs_t *pcieregs;
+ sbpciregs_t *pciregs;
+ } regs; /* Memory mapped register to the core */
+
+ si_t *sih; /* System interconnect handle */
+ osl_t *osh; /* OSL handle */
+ uint8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */
+ bool pcie_pr42767;
+ uint8 pcie_polarity;
+ uint8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
+
+ uint8 pmecap_offset; /* PM Capability offset in the config space */
+ bool pmecap; /* Capable of generating PME */
+} pcicore_info_t;
+
+/* debug/trace */
+#define PCI_ERROR(args)
+#define PCIE_PUB(sih) ((BUSTYPE((sih)->bustype) == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))
+
+/* routines to access mdio slave device registers */
+static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
+static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
+ bool write, uint *val);
+static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
+ uint val);
+static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
+ uint *ret_val);
+
+static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
+static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);
+
+static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
+static void pcie_war_serdes(pcicore_info_t *pi);
+static void pcie_war_noplldown(pcicore_info_t *pi);
+static void pcie_war_polarity(pcicore_info_t *pi);
+static void pcie_war_pci_setup(pcicore_info_t *pi);
+
+static bool pcicore_pmecap(pcicore_info_t *pi);
+
+#define PCIE_ASPM(sih) ((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))
+
+#define DWORD_ALIGN(x) (x & ~(0x03))
+#define BYTE_POS(x) (x & 0x3)
+#define WORD_POS(x) (x & 0x1)
+
+#define BYTE_SHIFT(x) (8 * BYTE_POS(x))
+#define WORD_SHIFT(x) (16 * WORD_POS(x))
+
+#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
+#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)
+
+#define read_pci_cfg_byte(a) \
+ (BYTE_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xff)
+
+#define read_pci_cfg_word(a) \
+ (WORD_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xffff)
+
+#define write_pci_cfg_byte(a, val) do { \
+ uint32 tmpval; \
+ tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFF << BYTE_POS(a)) | \
+ val << BYTE_POS(a); \
+ OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \
+ } while (0)
+
+#define write_pci_cfg_word(a, val) do { \
+ uint32 tmpval; \
+ tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFFFF << WORD_POS(a)) | \
+ val << WORD_POS(a); \
+ OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \
+ } while (0)
+
+/* delay needed between the mdio control/ mdiodata register data access */
+#define PR28829_DELAY() OSL_DELAY(10)
+
+/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
+ * only once
+ */
+void *pcicore_init(si_t *sih, osl_t *osh, void *regs)
+{
+ pcicore_info_t *pi;
+
+ ASSERT(sih->bustype == PCI_BUS);
+
+ /* alloc pcicore_info_t */
+ pi = MALLOC(osh, sizeof(pcicore_info_t));
+ if (pi == NULL) {
+ PCI_ERROR(("pci_attach: malloc failed! malloced %d bytes\n",
+ MALLOCED(osh)));
+ return NULL;
+ }
+
+ bzero(pi, sizeof(pcicore_info_t));
+
+ pi->sih = sih;
+ pi->osh = osh;
+
+ if (sih->buscoretype == PCIE_CORE_ID) {
+ uint8 cap_ptr;
+ pi->regs.pcieregs = (sbpcieregs_t *) regs;
+ cap_ptr =
+ pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID,
+ NULL, NULL);
+ ASSERT(cap_ptr);
+ pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
+ } else
+ pi->regs.pciregs = (sbpciregs_t *) regs;
+
+ return pi;
+}
+
+void pcicore_deinit(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (pi == NULL)
+ return;
+ MFREE(pi->osh, pi, sizeof(pcicore_info_t));
+}
+
+/* return cap_offset if requested capability exists in the PCI config space */
+/* Note that it's caller's responsibility to make sure it's a pci bus */
+uint8
+pcicore_find_pci_capability(osl_t *osh, uint8 req_cap_id, uchar *buf,
+ uint32 *buflen)
+{
+ uint8 cap_id;
+ uint8 cap_ptr = 0;
+ uint32 bufsize;
+ uint8 byte_val;
+
+ /* check for Header type 0 */
+ byte_val = read_pci_cfg_byte(PCI_CFG_HDR);
+ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
+ goto end;
+
+ /* check if the capability pointer field exists */
+ byte_val = read_pci_cfg_byte(PCI_CFG_STAT);
+ if (!(byte_val & PCI_CAPPTR_PRESENT))
+ goto end;
+
+ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR);
+ /* check if the capability pointer is 0x00 */
+ if (cap_ptr == 0x00)
+ goto end;
+
+ /* loop thr'u the capability list and see if the pcie capabilty exists */
+
+ cap_id = read_pci_cfg_byte(cap_ptr);
+
+ while (cap_id != req_cap_id) {
+ cap_ptr = read_pci_cfg_byte((cap_ptr + 1));
+ if (cap_ptr == 0x00)
+ break;
+ cap_id = read_pci_cfg_byte(cap_ptr);
+ }
+ if (cap_id != req_cap_id) {
+ goto end;
+ }
+ /* found the caller requested capability */
+ if ((buf != NULL) && (buflen != NULL)) {
+ uint8 cap_data;
+
+ bufsize = *buflen;
+ if (!bufsize)
+ goto end;
+ *buflen = 0;
+ /* copy the cpability data excluding cap ID and next ptr */
+ cap_data = cap_ptr + 2;
+ if ((bufsize + cap_data) > SZPCR)
+ bufsize = SZPCR - cap_data;
+ *buflen = bufsize;
+ while (bufsize--) {
+ *buf = read_pci_cfg_byte(cap_data);
+ cap_data++;
+ buf++;
+ }
+ }
+ end:
+ return cap_ptr;
+}
+
+/* ***** Register Access API */
+uint
+pcie_readreg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset)
+{
+ uint retval = 0xFFFFFFFF;
+
+ ASSERT(pcieregs != NULL);
+
+ switch (addrtype) {
+ case PCIE_CONFIGREGS:
+ W_REG(osh, (&pcieregs->configaddr), offset);
+ (void)R_REG(osh, (&pcieregs->configaddr));
+ retval = R_REG(osh, &(pcieregs->configdata));
+ break;
+ case PCIE_PCIEREGS:
+ W_REG(osh, &(pcieregs->pcieindaddr), offset);
+ (void)R_REG(osh, (&pcieregs->pcieindaddr));
+ retval = R_REG(osh, &(pcieregs->pcieinddata));
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ return retval;
+}
+
+uint
+pcie_writereg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset,
+ uint val)
+{
+ ASSERT(pcieregs != NULL);
+
+ switch (addrtype) {
+ case PCIE_CONFIGREGS:
+ W_REG(osh, (&pcieregs->configaddr), offset);
+ W_REG(osh, (&pcieregs->configdata), val);
+ break;
+ case PCIE_PCIEREGS:
+ W_REG(osh, (&pcieregs->pcieindaddr), offset);
+ W_REG(osh, (&pcieregs->pcieinddata), val);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return 0;
+}
+
+static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
+{
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ uint mdiodata, i = 0;
+ uint pcie_serdes_spinwait = 200;
+
+ mdiodata =
+ MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
+ MDIODATA_DEVADDR_SHF) |
+ (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
+ 4);
+ W_REG(pi->osh, &pcieregs->mdiodata, mdiodata);
+
+ PR28829_DELAY();
+ /* retry till the transaction is complete */
+ while (i < pcie_serdes_spinwait) {
+ if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) &
+ MDIOCTL_ACCESS_DONE) {
+ break;
+ }
+ OSL_DELAY(1000);
+ i++;
+ }
+
+ if (i >= pcie_serdes_spinwait) {
+ PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
+ uint *val)
+{
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ uint mdiodata;
+ uint i = 0;
+ uint pcie_serdes_spinwait = 10;
+
+ /* enable mdio access to SERDES */
+ W_REG(pi->osh, (&pcieregs->mdiocontrol),
+ MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+
+ if (pi->sih->buscorerev >= 10) {
+ /* new serdes is slower in rw, using two layers of reg address mapping */
+ if (!pcie_mdiosetblock(pi, physmedia))
+ return 1;
+ mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
+ (regaddr << MDIODATA_REGADDR_SHF);
+ pcie_serdes_spinwait *= 20;
+ } else {
+ mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
+ (regaddr << MDIODATA_REGADDR_SHF_OLD);
+ }
+
+ if (!write)
+ mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
+ else
+ mdiodata |=
+ (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);
+
+ W_REG(pi->osh, &pcieregs->mdiodata, mdiodata);
+
+ PR28829_DELAY();
+
+ /* retry till the transaction is complete */
+ while (i < pcie_serdes_spinwait) {
+ if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) &
+ MDIOCTL_ACCESS_DONE) {
+ if (!write) {
+ PR28829_DELAY();
+ *val =
+ (R_REG(pi->osh, &(pcieregs->mdiodata)) &
+ MDIODATA_MASK);
+ }
+ /* Disable mdio access to SERDES */
+ W_REG(pi->osh, (&pcieregs->mdiocontrol), 0);
+ return 0;
+ }
+ OSL_DELAY(1000);
+ i++;
+ }
+
+ PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
+ /* Disable mdio access to SERDES */
+ W_REG(pi->osh, (&pcieregs->mdiocontrol), 0);
+ return 1;
+}
+
+/* use the mdio interface to read from mdio slaves */
+static int
+pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
+{
+ return pcie_mdioop(pi, physmedia, regaddr, FALSE, regval);
+}
+
+/* use the mdio interface to write to mdio slaves */
+static int
+pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
+{
+ return pcie_mdioop(pi, physmedia, regaddr, TRUE, &val);
+}
+
+/* ***** Support functions ***** */
+uint8 pcie_clkreq(void *pch, uint32 mask, uint32 val)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint32 reg_val;
+ uint8 offset;
+
+ offset = pi->pciecap_lcreg_offset;
+ if (!offset)
+ return 0;
+
+ reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32));
+ /* set operation */
+ if (mask) {
+ if (val)
+ reg_val |= PCIE_CLKREQ_ENAB;
+ else
+ reg_val &= ~PCIE_CLKREQ_ENAB;
+ OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), reg_val);
+ reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32));
+ }
+ if (reg_val & PCIE_CLKREQ_ENAB)
+ return 1;
+ else
+ return 0;
+}
+
+static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
+{
+ uint32 w;
+ si_t *sih = pi->sih;
+ osl_t *osh = pi->osh;
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+
+ if (!PCIE_PUB(sih) || sih->buscorerev < 7)
+ return;
+
+ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+ if (extend)
+ w |= PCIE_ASPMTIMER_EXTEND;
+ else
+ w &= ~PCIE_ASPMTIMER_EXTEND;
+ pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
+ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+}
+
+/* centralized clkreq control policy */
+static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
+{
+ si_t *sih = pi->sih;
+ ASSERT(PCIE_PUB(sih));
+
+ switch (state) {
+ case SI_DOATTACH:
+ if (PCIE_ASPM(sih))
+ pcie_clkreq((void *)pi, 1, 0);
+ break;
+ case SI_PCIDOWN:
+ if (sih->buscorerev == 6) { /* turn on serdes PLL down */
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_addr), ~0,
+ 0);
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data),
+ ~0x40, 0);
+ } else if (pi->pcie_pr42767) {
+ pcie_clkreq((void *)pi, 1, 1);
+ }
+ break;
+ case SI_PCIUP:
+ if (sih->buscorerev == 6) { /* turn off serdes PLL down */
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_addr), ~0,
+ 0);
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol_data),
+ ~0x40, 0x40);
+ } else if (PCIE_ASPM(sih)) { /* disable clkreq */
+ pcie_clkreq((void *)pi, 1, 0);
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+/* ***** PCI core WARs ***** */
+/* Done only once at attach time */
+static void pcie_war_polarity(pcicore_info_t *pi)
+{
+ uint32 w;
+
+ if (pi->pcie_polarity != 0)
+ return;
+
+ w = pcie_readreg(pi->osh, pi->regs.pcieregs, PCIE_PCIEREGS,
+ PCIE_PLP_STATUSREG);
+
+ /* Detect the current polarity at attach and force that polarity and
+ * disable changing the polarity
+ */
+ if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
+ pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
+ else
+ pi->pcie_polarity =
+ (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
+}
+
+/* enable ASPM and CLKREQ if srom doesn't have it */
+/* Needs to happen when update to shadow SROM is needed
+ * : Coming out of 'standby'/'hibernate'
+ * : If pcie_war_aspm_ovr state changed
+ */
+static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
+{
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ si_t *sih = pi->sih;
+ uint16 val16, *reg16;
+ uint32 w;
+
+ if (!PCIE_ASPM(sih))
+ return;
+
+ /* bypass this on QT or VSIM */
+ if (!ISSIM_ENAB(sih)) {
+
+ reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
+ val16 = R_REG(pi->osh, reg16);
+
+ val16 &= ~SRSH_ASPM_ENB;
+ if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
+ val16 |= SRSH_ASPM_ENB;
+ else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
+ val16 |= SRSH_ASPM_L1_ENB;
+ else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
+ val16 |= SRSH_ASPM_L0s_ENB;
+
+ W_REG(pi->osh, reg16, val16);
+
+ w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
+ sizeof(uint32));
+ w &= ~PCIE_ASPM_ENAB;
+ w |= pi->pcie_war_aspm_ovr;
+ OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
+ sizeof(uint32), w);
+ }
+
+ reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
+ val16 = R_REG(pi->osh, reg16);
+
+ if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
+ val16 |= SRSH_CLKREQ_ENB;
+ pi->pcie_pr42767 = TRUE;
+ } else
+ val16 &= ~SRSH_CLKREQ_ENB;
+
+ W_REG(pi->osh, reg16, val16);
+}
+
+/* Apply the polarity determined at the start */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_serdes(pcicore_info_t *pi)
+{
+ uint32 w = 0;
+
+ if (pi->pcie_polarity != 0)
+ pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
+ pi->pcie_polarity);
+
+ pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
+ if (w & PLL_CTRL_FREQDET_EN) {
+ w &= ~PLL_CTRL_FREQDET_EN;
+ pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
+ }
+}
+
+/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void BCMINITFN(pcie_misc_config_fixup) (pcicore_info_t *pi)
+{
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ uint16 val16, *reg16;
+
+ reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
+ val16 = R_REG(pi->osh, reg16);
+
+ if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
+ val16 |= SRSH_L23READY_EXIT_NOPERST;
+ W_REG(pi->osh, reg16, val16);
+ }
+}
+
+/* quick hack for testing */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_noplldown(pcicore_info_t *pi)
+{
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ uint16 *reg16;
+
+ ASSERT(pi->sih->buscorerev == 7);
+
+ /* turn off serdes PLL down */
+ si_corereg(pi->sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol),
+ CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
+
+ /* clear srom shadow backdoor */
+ reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
+ W_REG(pi->osh, reg16, 0);
+}
+
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_pci_setup(pcicore_info_t *pi)
+{
+ si_t *sih = pi->sih;
+ osl_t *osh = pi->osh;
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ uint32 w;
+
+ if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
+ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS,
+ PCIE_TLP_WORKAROUNDSREG);
+ w |= 0x8;
+ pcie_writereg(osh, pcieregs, PCIE_PCIEREGS,
+ PCIE_TLP_WORKAROUNDSREG, w);
+ }
+
+ if (sih->buscorerev == 1) {
+ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
+ w |= (0x40);
+ pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
+ }
+
+ if (sih->buscorerev == 0) {
+ pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
+ pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
+ pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
+ } else if (PCIE_ASPM(sih)) {
+ /* Change the L1 threshold for better performance */
+ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS,
+ PCIE_DLLP_PMTHRESHREG);
+ w &= ~(PCIE_L1THRESHOLDTIME_MASK);
+ w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
+ pcie_writereg(osh, pcieregs, PCIE_PCIEREGS,
+ PCIE_DLLP_PMTHRESHREG, w);
+
+ pcie_war_serdes(pi);
+
+ pcie_war_aspm_clkreq(pi);
+ } else if (pi->sih->buscorerev == 7)
+ pcie_war_noplldown(pi);
+
+ /* Note that the fix is actually in the SROM, that's why this is open-ended */
+ if (pi->sih->buscorerev >= 6)
+ pcie_misc_config_fixup(pi);
+}
+
+void pcie_war_ovr_aspm_update(void *pch, uint8 aspm)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (!PCIE_ASPM(pi->sih))
+ return;
+
+ /* Validate */
+ if (aspm > PCIE_ASPM_ENAB)
+ return;
+
+ pi->pcie_war_aspm_ovr = aspm;
+
+ /* Update the current state */
+ pcie_war_aspm_clkreq(pi);
+}
+
+/* ***** Functions called during driver state changes ***** */
+void BCMATTACHFN(pcicore_attach) (void *pch, char *pvars, int state)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ si_t *sih = pi->sih;
+
+ /* Determine if this board needs override */
+ if (PCIE_ASPM(sih)) {
+ if ((uint32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
+ pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
+ } else {
+ pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
+ }
+ }
+
+ /* These need to happen in this order only */
+ pcie_war_polarity(pi);
+
+ pcie_war_serdes(pi);
+
+ pcie_war_aspm_clkreq(pi);
+
+ pcie_clkreq_upd(pi, state);
+
+}
+
+void pcicore_hwup(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (!pi || !PCIE_PUB(pi->sih))
+ return;
+
+ pcie_war_pci_setup(pi);
+}
+
+void pcicore_up(void *pch, int state)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (!pi || !PCIE_PUB(pi->sih))
+ return;
+
+ /* Restore L1 timer for better performance */
+ pcie_extendL1timer(pi, TRUE);
+
+ pcie_clkreq_upd(pi, state);
+}
+
+/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
+void pcicore_sleep(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint32 w;
+
+ if (!pi || !PCIE_ASPM(pi->sih))
+ return;
+
+ w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
+ sizeof(uint32));
+ w &= ~PCIE_CAP_LCREG_ASPML1;
+ OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32),
+ w);
+
+ pi->pcie_pr42767 = FALSE;
+}
+
+void pcicore_down(void *pch, int state)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (!pi || !PCIE_PUB(pi->sih))
+ return;
+
+ pcie_clkreq_upd(pi, state);
+
+ /* Reduce L1 timer for better power savings */
+ pcie_extendL1timer(pi, FALSE);
+}
+
+/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
+/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
+bool pcicore_pmecap_fast(osl_t *osh)
+{
+ uint8 cap_ptr;
+ uint32 pmecap;
+
+ cap_ptr =
+ pcicore_find_pci_capability(osh, PCI_CAP_POWERMGMTCAP_ID, NULL,
+ NULL);
+
+ if (!cap_ptr)
+ return FALSE;
+
+ pmecap = OSL_PCI_READ_CONFIG(osh, cap_ptr, sizeof(uint32));
+
+ return (pmecap & PME_CAP_PM_STATES) != 0;
+}
+
+/* return TRUE if PM capability exists in the pci config space
+ * Uses and caches the information using core handle
+ */
+static bool pcicore_pmecap(pcicore_info_t *pi)
+{
+ uint8 cap_ptr;
+ uint32 pmecap;
+
+ if (!pi->pmecap_offset) {
+ cap_ptr =
+ pcicore_find_pci_capability(pi->osh,
+ PCI_CAP_POWERMGMTCAP_ID, NULL,
+ NULL);
+ if (!cap_ptr)
+ return FALSE;
+
+ pi->pmecap_offset = cap_ptr;
+
+ pmecap =
+ OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset,
+ sizeof(uint32));
+
+ /* At least one state can generate PME */
+ pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0;
+ }
+
+ return pi->pmecap;
+}
+
+/* Enable PME generation */
+void pcicore_pmeen(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint32 w;
+
+ /* if not pmecapable return */
+ if (!pcicore_pmecap(pi))
+ return;
+
+ w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32));
+ w |= (PME_CSR_PME_EN);
+ OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32), w);
+}
+
+/*
+ * Return TRUE if PME status set
+ */
+bool pcicore_pmestat(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint32 w;
+
+ if (!pcicore_pmecap(pi))
+ return FALSE;
+
+ w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32));
+
+ return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT;
+}
+
+/* Disable PME generation, clear the PME status bit if set
+ */
+void pcicore_pmeclr(void *pch)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint32 w;
+
+ if (!pcicore_pmecap(pi))
+ return;
+
+ w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32));
+
+ PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));
+
+ /* PMESTAT is cleared by writing 1 to it */
+ w &= ~(PME_CSR_PME_EN);
+
+ OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32), w);
+}
+
+uint32 pcie_lcreg(void *pch, uint32 mask, uint32 val)
+{
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ uint8 offset;
+
+ offset = pi->pciecap_lcreg_offset;
+ if (!offset)
+ return 0;
+
+ /* set operation */
+ if (mask)
+ OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), val);
+
+ return OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32));
+}
+
+uint32
+pcicore_pciereg(void *pch, uint32 offset, uint32 mask, uint32 val, uint type)
+{
+ uint32 reg_val = 0;
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+ sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+ osl_t *osh = pi->osh;
+
+ if (mask) {
+ PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val));
+ pcie_writereg(osh, pcieregs, type, offset, val);
+ }
+
+ /* Should not read register 0x154 */
+ if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
+ && type == PCIE_PCIEREGS)
+ return reg_val;
+
+ reg_val = pcie_readreg(osh, pcieregs, type, offset);
+ PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));
+
+ return reg_val;
+}
+
+uint32
+pcicore_pcieserdesreg(void *pch, uint32 mdioslave, uint32 offset, uint32 mask,
+ uint32 val)
+{
+ uint32 reg_val = 0;
+ pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+ if (mask) {
+ PCI_ERROR(("PCIEMDIOREG: 0x%x writeval 0x%x\n", offset, val));
+ pcie_mdiowrite(pi, mdioslave, offset, val);
+ }
+
+ if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
+ reg_val = 0xFFFFFFFF;
+ PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
+ offset, reg_val));
+
+ return reg_val;
+}
diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c
new file mode 100644
index 000000000000..f6640ef8fb97
--- /dev/null
+++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmendian.h>
+#include <bcmnvram.h>
+#include <sbchipc.h>
+#include <bcmsrom.h>
+#include <bcmotp.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+
+#define NVR_MSG(x)
+
+typedef struct _vars {
+ struct _vars *next;
+ int bufsz; /* allocated size */
+ int size; /* actual vars size */
+ char *vars;
+} vars_t;
+
+#define VARS_T_OH sizeof(vars_t)
+
+static vars_t *vars;
+
+#define NVRAM_FILE 1
+
+static char *findvar(char *vars, char *lim, const char *name);
+
+#if defined(FLASH)
+/* copy flash to ram */
+static void BCMINITFN(get_flash_nvram) (si_t *sih, struct nvram_header *nvh)
+{
+ osl_t *osh;
+ uint nvs, bufsz;
+ vars_t *new;
+
+ osh = si_osh(sih);
+
+ nvs = R_REG(osh, &nvh->len) - sizeof(struct nvram_header);
+ bufsz = nvs + VARS_T_OH;
+
+ new = (vars_t *) MALLOC(osh, bufsz);
+ if (new == NULL) {
+ NVR_MSG(("Out of memory for flash vars\n"));
+ return;
+ }
+ new->vars = (char *)new + VARS_T_OH;
+
+ new->bufsz = bufsz;
+ new->size = nvs;
+ new->next = vars;
+ vars = new;
+
+ bcopy((char *)(&nvh[1]), new->vars, nvs);
+
+ NVR_MSG(("%s: flash nvram @ %p, copied %d bytes to %p\n", __func__,
+ nvh, nvs, new->vars));
+}
+#endif /* FLASH */
+
+int BCMATTACHFN(nvram_init) (void *si)
+{
+
+ /* Make sure we read nvram in flash just once before freeing the memory */
+ if (vars != NULL) {
+ NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
+ return 0;
+ }
+ return 0;
+}
+
+int BCMATTACHFN(nvram_append) (void *si, char *varlst, uint varsz)
+{
+ uint bufsz = VARS_T_OH;
+ vars_t *new;
+
+ new = MALLOC(si_osh((si_t *) si), bufsz);
+ if (new == NULL)
+ return BCME_NOMEM;
+
+ new->vars = varlst;
+ new->bufsz = bufsz;
+ new->size = varsz;
+ new->next = vars;
+ vars = new;
+
+ return BCME_OK;
+}
+
+void BCMUNINITFN(nvram_exit) (void *si)
+{
+ vars_t *this, *next;
+ si_t *sih;
+
+ sih = (si_t *) si;
+ this = vars;
+
+ if (this)
+ MFREE(si_osh(sih), this->vars, this->size);
+
+ while (this) {
+ next = this->next;
+ MFREE(si_osh(sih), this, this->bufsz);
+ this = next;
+ }
+ vars = NULL;
+}
+
+static char *findvar(char *vars, char *lim, const char *name)
+{
+ char *s;
+ int len;
+
+ len = strlen(name);
+
+ for (s = vars; (s < lim) && *s;) {
+ if ((bcmp(s, name, len) == 0) && (s[len] == '='))
+ return &s[len + 1];
+
+ while (*s++)
+ ;
+ }
+
+ return NULL;
+}
+
+char *nvram_get(const char *name)
+{
+ char *v = NULL;
+ vars_t *cur;
+
+ for (cur = vars; cur; cur = cur->next) {
+ v = findvar(cur->vars, cur->vars + cur->size, name);
+ if (v)
+ break;
+ }
+
+ return v;
+}
+
+int BCMATTACHFN(nvram_set) (const char *name, const char *value)
+{
+ return 0;
+}
+
+int BCMATTACHFN(nvram_unset) (const char *name)
+{
+ return 0;
+}
+
+int BCMATTACHFN(nvram_reset) (void *si)
+{
+ return 0;
+}
+
+int BCMATTACHFN(nvram_commit) (void)
+{
+ return 0;
+}
+
+int nvram_getall(char *buf, int count)
+{
+ int len, resid = count;
+ vars_t *this;
+
+ this = vars;
+ while (this) {
+ char *from, *lim, *to;
+ int acc;
+
+ from = this->vars;
+ lim = (char *)((uintptr) this->vars + this->size);
+ to = buf;
+ acc = 0;
+ while ((from < lim) && (*from)) {
+ len = strlen(from) + 1;
+ if (resid < (acc + len))
+ return BCME_BUFTOOSHORT;
+ bcopy(from, to, len);
+ acc += len;
+ from += len;
+ to += len;
+ }
+
+ resid -= acc;
+ buf += acc;
+ this = this->next;
+ }
+ if (resid < 1)
+ return BCME_BUFTOOSHORT;
+ *buf = '\0';
+ return 0;
+}
diff --git a/drivers/staging/brcm80211/util/qmath.c b/drivers/staging/brcm80211/util/qmath.c
new file mode 100644
index 000000000000..f9b30a66cae8
--- /dev/null
+++ b/drivers/staging/brcm80211/util/qmath.c
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 "qmath.h"
+
+/*
+Description: This function saturate input 32 bit number into a 16 bit number.
+If input number is greater than 0x7fff then output is saturated to 0x7fff.
+else if input number is less than 0xffff8000 then output is saturated to 0xffff8000
+else output is same as input.
+*/
+int16 qm_sat32(int32 op)
+{
+ int16 result;
+ if (op > (int32) 0x7fff) {
+ result = 0x7fff;
+ } else if (op < (int32) 0xffff8000) {
+ result = (int16) (0x8000);
+ } else {
+ result = (int16) op;
+ }
+ return result;
+}
+
+/*
+Description: This function multiply two input 16 bit numbers and return the 32 bit result.
+This multiplication is similar to compiler multiplication. This operation is defined if
+16 bit multiplication on the processor platform is cheaper than 32 bit multiplication (as
+the most of qmath functions can be replaced with processor intrinsic instructions).
+*/
+int32 qm_mul321616(int16 op1, int16 op2)
+{
+ return (int32) (op1) * (int32) (op2);
+}
+
+/*
+Description: This function make 16 bit multiplication and return the result in 16 bits.
+To fit the result into 16 bits the 32 bit multiplication result is right
+shifted by 16 bits.
+*/
+int16 qm_mul16(int16 op1, int16 op2)
+{
+ int32 result;
+ result = ((int32) (op1) * (int32) (op2));
+ return (int16) (result >> 16);
+}
+
+/*
+Description: This function multiply two 16 bit numbers and return the result in 32 bits.
+This function remove the extra sign bit created by the multiplication by leftshifting the
+32 bit multiplication result by 1 bit before returning the result. So the output is
+twice that of compiler multiplication. (i.e. qm_muls321616(2,3)=12).
+When both input 16 bit numbers are 0x8000, then the result is saturated to 0x7fffffff.
+*/
+int32 qm_muls321616(int16 op1, int16 op2)
+{
+ int32 result;
+ if (op1 == (int16) (0x8000) && op2 == (int16) (0x8000)) {
+ result = 0x7fffffff;
+ } else {
+ result = ((int32) (op1) * (int32) (op2));
+ result = result << 1;
+ }
+ return result;
+}
+
+/*
+Description: This function make 16 bit unsigned multiplication. To fit the output into
+16 bits the 32 bit multiplication result is right shifted by 16 bits.
+*/
+uint16 qm_mulu16(uint16 op1, uint16 op2)
+{
+ return (uint16) (((uint32) op1 * (uint32) op2) >> 16);
+}
+
+/*
+Description: This function make 16 bit multiplication and return the result in 16 bits.
+To fit the multiplication result into 16 bits the multiplication result is right shifted by
+15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
+due to the multiplication.
+When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
+*/
+int16 qm_muls16(int16 op1, int16 op2)
+{
+ int32 result;
+ if (op1 == (int16) 0x8000 && op2 == (int16) 0x8000) {
+ result = 0x7fffffff;
+ } else {
+ result = ((int32) (op1) * (int32) (op2));
+ }
+ return (int16) (result >> 15);
+}
+
+/*
+Description: This function add two 32 bit numbers and return the 32bit result.
+If the result overflow 32 bits, the output will be saturated to 32bits.
+*/
+int32 qm_add32(int32 op1, int32 op2)
+{
+ int32 result;
+ result = op1 + op2;
+ if (op1 < 0 && op2 < 0 && result > 0) {
+ result = 0x80000000;
+ } else if (op1 > 0 && op2 > 0 && result < 0) {
+ result = 0x7fffffff;
+ }
+ return result;
+}
+
+/*
+Description: This function add two 16 bit numbers and return the 16bit result.
+If the result overflow 16 bits, the output will be saturated to 16bits.
+*/
+int16 qm_add16(int16 op1, int16 op2)
+{
+ int16 result;
+ int32 temp = (int32) op1 + (int32) op2;
+ if (temp > (int32) 0x7fff) {
+ result = (int16) 0x7fff;
+ } else if (temp < (int32) 0xffff8000) {
+ result = (int16) 0xffff8000;
+ } else {
+ result = (int16) temp;
+ }
+ return result;
+}
+
+/*
+Description: This function make 16 bit subtraction and return the 16bit result.
+If the result overflow 16 bits, the output will be saturated to 16bits.
+*/
+int16 qm_sub16(int16 op1, int16 op2)
+{
+ int16 result;
+ int32 temp = (int32) op1 - (int32) op2;
+ if (temp > (int32) 0x7fff) {
+ result = (int16) 0x7fff;
+ } else if (temp < (int32) 0xffff8000) {
+ result = (int16) 0xffff8000;
+ } else {
+ result = (int16) temp;
+ }
+ return result;
+}
+
+/*
+Description: This function make 32 bit subtraction and return the 32bit result.
+If the result overflow 32 bits, the output will be saturated to 32bits.
+*/
+int32 qm_sub32(int32 op1, int32 op2)
+{
+ int32 result;
+ result = op1 - op2;
+ if (op1 >= 0 && op2 < 0 && result < 0) {
+ result = 0x7fffffff;
+ } else if (op1 < 0 && op2 > 0 && result > 0) {
+ result = 0x80000000;
+ }
+ return result;
+}
+
+/*
+Description: This function multiply input 16 bit numbers and accumulate the result
+into the input 32 bit number and return the 32 bit accumulated result.
+If the accumulation result in overflow, then the output will be saturated.
+*/
+int32 qm_mac321616(int32 acc, int16 op1, int16 op2)
+{
+ int32 result;
+ result = qm_add32(acc, qm_mul321616(op1, op2));
+ return result;
+}
+
+/*
+Description: This function make a 32 bit saturated left shift when the specified shift
+is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
+This function return the result after shifting operation.
+*/
+int32 qm_shl32(int32 op, int shift)
+{
+ int i;
+ int32 result;
+ result = op;
+ if (shift > 31)
+ shift = 31;
+ else if (shift < -31)
+ shift = -31;
+ if (shift >= 0) {
+ for (i = 0; i < shift; i++) {
+ result = qm_add32(result, result);
+ }
+ } else {
+ result = result >> (-shift);
+ }
+ return result;
+}
+
+/*
+Description: This function make a 32 bit right shift when shift is +ve.
+This function make a 32 bit saturated left shift when shift is -ve. This function
+return the result of the shift operation.
+*/
+int32 qm_shr32(int32 op, int shift)
+{
+ return qm_shl32(op, -shift);
+}
+
+/*
+Description: This function make a 16 bit saturated left shift when the specified shift
+is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
+This function return the result after shifting operation.
+*/
+int16 qm_shl16(int16 op, int shift)
+{
+ int i;
+ int16 result;
+ result = op;
+ if (shift > 15)
+ shift = 15;
+ else if (shift < -15)
+ shift = -15;
+ if (shift > 0) {
+ for (i = 0; i < shift; i++) {
+ result = qm_add16(result, result);
+ }
+ } else {
+ result = result >> (-shift);
+ }
+ return result;
+}
+
+/*
+Description: This function make a 16 bit right shift when shift is +ve.
+This function make a 16 bit saturated left shift when shift is -ve. This function
+return the result of the shift operation.
+*/
+int16 qm_shr16(int16 op, int shift)
+{
+ return qm_shl16(op, -shift);
+}
+
+/*
+Description: This function return the number of redundant sign bits in a 16 bit number.
+Example: qm_norm16(0x0080) = 7.
+*/
+int16 qm_norm16(int16 op)
+{
+ uint16 u16extraSignBits;
+ if (op == 0) {
+ return 15;
+ } else {
+ u16extraSignBits = 0;
+ while ((op >> 15) == (op >> 14)) {
+ u16extraSignBits++;
+ op = op << 1;
+ }
+ }
+ return u16extraSignBits;
+}
+
+/*
+Description: This function return the number of redundant sign bits in a 32 bit number.
+Example: qm_norm32(0x00000080) = 23
+*/
+int16 qm_norm32(int32 op)
+{
+ uint16 u16extraSignBits;
+ if (op == 0) {
+ return 31;
+ } else {
+ u16extraSignBits = 0;
+ while ((op >> 31) == (op >> 30)) {
+ u16extraSignBits++;
+ op = op << 1;
+ }
+ }
+ return u16extraSignBits;
+}
+
+/*
+Description: This function divide two 16 bit unsigned numbers.
+The numerator should be less than denominator. So the quotient is always less than 1.
+This function return the quotient in q.15 format.
+*/
+int16 qm_div_s(int16 num, int16 denom)
+{
+ int16 var_out;
+ int16 iteration;
+ int32 L_num;
+ int32 L_denom;
+ L_num = (num) << 15;
+ L_denom = (denom) << 15;
+ for (iteration = 0; iteration < 15; iteration++) {
+ L_num <<= 1;
+ if (L_num >= L_denom) {
+ L_num = qm_sub32(L_num, L_denom);
+ L_num = qm_add32(L_num, 1);
+ }
+ }
+ var_out = (int16) (L_num & 0x7fff);
+ return var_out;
+}
+
+/*
+Description: This function compute the absolute value of a 16 bit number.
+*/
+int16 qm_abs16(int16 op)
+{
+ if (op < 0) {
+ if (op == (int16) 0xffff8000) {
+ return 0x7fff;
+ } else {
+ return -op;
+ }
+ } else {
+ return op;
+ }
+}
+
+/*
+Description: This function divide two 16 bit numbers.
+The quotient is returned through return value.
+The qformat of the quotient is returned through the pointer (qQuotient) passed
+to this function. The qformat of quotient is adjusted appropriately such that
+the quotient occupies all 16 bits.
+*/
+int16 qm_div16(int16 num, int16 denom, int16 *qQuotient)
+{
+ int16 sign;
+ int16 nNum, nDenom;
+ sign = num ^ denom;
+ num = qm_abs16(num);
+ denom = qm_abs16(denom);
+ nNum = qm_norm16(num);
+ nDenom = qm_norm16(denom);
+ num = qm_shl16(num, nNum - 1);
+ denom = qm_shl16(denom, nDenom);
+ *qQuotient = nNum - 1 - nDenom + 15;
+ if (sign >= 0) {
+ return qm_div_s(num, denom);
+ } else {
+ return -qm_div_s(num, denom);
+ }
+}
+
+/*
+Description: This function compute absolute value of a 32 bit number.
+*/
+int32 qm_abs32(int32 op)
+{
+ if (op < 0) {
+ if (op == (int32) 0x80000000) {
+ return 0x7fffffff;
+ } else {
+ return -op;
+ }
+ } else {
+ return op;
+ }
+}
+
+/*
+Description: This function divide two 32 bit numbers. The division is performed
+by considering only important 16 bits in 32 bit numbers.
+The quotient is returned through return value.
+The qformat of the quotient is returned through the pointer (qquotient) passed
+to this function. The qformat of quotient is adjusted appropriately such that
+the quotient occupies all 16 bits.
+*/
+int16 qm_div163232(int32 num, int32 denom, int16 *qquotient)
+{
+ int32 sign;
+ int16 nNum, nDenom;
+ sign = num ^ denom;
+ num = qm_abs32(num);
+ denom = qm_abs32(denom);
+ nNum = qm_norm32(num);
+ nDenom = qm_norm32(denom);
+ num = qm_shl32(num, nNum - 1);
+ denom = qm_shl32(denom, nDenom);
+ *qquotient = nNum - 1 - nDenom + 15;
+ if (sign >= 0) {
+ return qm_div_s((int16) (num >> 16), (int16) (denom >> 16));
+ } else {
+ return -qm_div_s((int16) (num >> 16), (int16) (denom >> 16));
+ }
+}
+
+/*
+Description: This function multiply a 32 bit number with a 16 bit number.
+The multiplicaton result is right shifted by 16 bits to fit the result
+into 32 bit output.
+*/
+int32 qm_mul323216(int32 op1, int16 op2)
+{
+ int16 hi;
+ uint16 lo;
+ int32 result;
+ hi = op1 >> 16;
+ lo = (int16) (op1 & 0xffff);
+ result = qm_mul321616(hi, op2);
+ result = result + (qm_mulsu321616(op2, lo) >> 16);
+ return result;
+}
+
+/*
+Description: This function multiply signed 16 bit number with unsigned 16 bit number and return
+the result in 32 bits.
+*/
+int32 qm_mulsu321616(int16 op1, uint16 op2)
+{
+ return (int32) (op1) * op2;
+}
+
+/*
+Description: This function multiply 32 bit number with 16 bit number. The multiplication result is
+right shifted by 15 bits to fit the result into 32 bits. Right shifting by only 15 bits instead of
+16 bits is done to remove the extra sign bit formed by multiplication from the return value.
+When the input numbers are 0x80000000, 0x8000 the return value is saturated to 0x7fffffff.
+*/
+int32 qm_muls323216(int32 op1, int16 op2)
+{
+ int16 hi;
+ uint16 lo;
+ int32 result;
+ hi = op1 >> 16;
+ lo = (int16) (op1 & 0xffff);
+ result = qm_muls321616(hi, op2);
+ result = qm_add32(result, (qm_mulsu321616(op2, lo) >> 15));
+ return result;
+}
+
+/*
+Description: This function multiply two 32 bit numbers. The multiplication result is right
+shifted by 32 bits to fit the multiplication result into 32 bits. The right shifted
+multiplication result is returned as output.
+*/
+int32 qm_mul32(int32 a, int32 b)
+{
+ int16 hi1, hi2;
+ uint16 lo1, lo2;
+ int32 result;
+ hi1 = a >> 16;
+ hi2 = b >> 16;
+ lo1 = (uint16) (a & 0xffff);
+ lo2 = (uint16) (b & 0xffff);
+ result = qm_mul321616(hi1, hi2);
+ result = result + (qm_mulsu321616(hi1, lo2) >> 16);
+ result = result + (qm_mulsu321616(hi2, lo1) >> 16);
+ return result;
+}
+
+/*
+Description: This function multiply two 32 bit numbers. The multiplication result is
+right shifted by 31 bits to fit the multiplication result into 32 bits. The right
+shifted multiplication result is returned as output. Right shifting by only 31 bits
+instead of 32 bits is done to remove the extra sign bit formed by multiplication.
+When the input numbers are 0x80000000, 0x80000000 the return value is saturated to
+0x7fffffff.
+*/
+int32 qm_muls32(int32 a, int32 b)
+{
+ int16 hi1, hi2;
+ uint16 lo1, lo2;
+ int32 result;
+ hi1 = a >> 16;
+ hi2 = b >> 16;
+ lo1 = (uint16) (a & 0xffff);
+ lo2 = (uint16) (b & 0xffff);
+ result = qm_muls321616(hi1, hi2);
+ result = qm_add32(result, (qm_mulsu321616(hi1, lo2) >> 15));
+ result = qm_add32(result, (qm_mulsu321616(hi2, lo1) >> 15));
+ result = qm_add32(result, (qm_mulu16(lo1, lo2) >> 15));
+ return result;
+}
+
+/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
+static const int16 log_table[] = {
+ 0,
+ 1455,
+ 2866,
+ 4236,
+ 5568,
+ 6863,
+ 8124,
+ 9352,
+ 10549,
+ 11716,
+ 12855,
+ 13968,
+ 15055,
+ 16117,
+ 17156,
+ 18173,
+ 19168,
+ 20143,
+ 21098,
+ 22034,
+ 22952,
+ 23852,
+ 24736,
+ 25604,
+ 26455,
+ 27292,
+ 28114,
+ 28922,
+ 29717,
+ 30498,
+ 31267,
+ 32024
+};
+
+#define LOG_TABLE_SIZE 32 /* log_table size */
+#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
+#define Q_LOG_TABLE 15 /* qformat of log_table */
+#define LOG10_2 19728 /* log10(2) in q.16 */
+
+/*
+Description:
+This routine takes the input number N and its q format qN and compute
+the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format.
+mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
+From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
+This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
+As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
+Next 16 MSBs are used for interpolation.
+Inputs:
+N - number to which log10 has to be found.
+qN - q format of N
+log10N - address where log10(N) will be written.
+qLog10N - address where log10N qformat will be written.
+Note/Problem:
+For accurate results input should be in normalized or near normalized form.
+*/
+void qm_log10(int32 N, int16 qN, int16 *log10N, int16 *qLog10N)
+{
+ int16 s16norm, s16tableIndex, s16errorApproximation;
+ uint16 u16offset;
+ int32 s32log;
+
+ /* Logerithm of negative values is undefined.
+ * assert N is greater than 0.
+ */
+ /* ASSERT(N > 0); */
+
+ /* normalize the N. */
+ s16norm = qm_norm32(N);
+ N = N << s16norm;
+
+ /* The qformat of N after normalization.
+ * -30 is added to treat the no as between 1.0 to 2.0
+ * i.e. after adding the -30 to the qformat the decimal point will be
+ * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
+ * at the right side of 30th bit.
+ */
+ qN = qN + s16norm - 30;
+
+ /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
+ s16tableIndex = (int16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
+
+ /* remove the MSB. the MSB is always 1 after normalization. */
+ s16tableIndex =
+ s16tableIndex & (int16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
+
+ /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
+ N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
+
+ /* take the offset as the 16 MSBS after table index.
+ */
+ u16offset = (uint16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
+
+ /* look the log value in the table. */
+ s32log = log_table[s16tableIndex]; /* q.15 format */
+
+ /* interpolate using the offset. */
+ s16errorApproximation = (int16) qm_mulu16(u16offset, (uint16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */
+
+ s32log = qm_add16((int16) s32log, s16errorApproximation); /* q.15 format */
+
+ /* adjust for the qformat of the N as
+ * log2(mag * 2^x) = log2(mag) + x
+ */
+ s32log = qm_add32(s32log, ((int32) -qN) << 15); /* q.15 format */
+
+ /* normalize the result. */
+ s16norm = qm_norm32(s32log);
+
+ /* bring all the important bits into lower 16 bits */
+ s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */
+
+ /* compute the log10(N) by multiplying log2(N) with log10(2).
+ * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
+ * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
+ */
+ *log10N = qm_muls16((int16) s32log, (int16) LOG10_2);
+
+ /* write the q format of the result. */
+ *qLog10N = 15 + s16norm - 16 + 1;
+
+ return;
+}
+
+/*
+Description:
+This routine compute 1/N.
+This routine reformates the given no N as N * 2^qN where N is in between 0.5 and 1.0
+in q.15 format in 16 bits. So the problem now boils down to finding the inverse of a
+q.15 no in 16 bits which is in the range of 0.5 to 1.0. The output is always between
+2.0 to 1. So the output is 2.0 to 1.0 in q.30 format. Once the final output format is found
+by taking the qN into account. Inverse is found with newton rapson method. Initially
+inverse (x) is guessed as 1/0.75 (with appropriate sign). The new guess is calculated
+using the formula x' = 2*x - N*x*x. After 4 or 5 iterations the inverse is very close to
+inverse of N.
+Inputs:
+N - number to which 1/N has to be found.
+qn - q format of N.
+sqrtN - address where 1/N has to be written.
+qsqrtN - address where q format of 1/N has to be written.
+*/
+#define qx 29
+void qm_1byN(int32 N, int16 qN, int32 *result, int16 *qResult)
+{
+ int16 normN;
+ int32 s32firstTerm, s32secondTerm, x;
+ int i;
+
+ normN = qm_norm32(N);
+
+ /* limit N to least significant 16 bits. 15th bit is the sign bit. */
+ N = qm_shl32(N, normN - 16);
+ qN = qN + normN - 16 - 15;
+ /* -15 is added to treat N as 16 bit q.15 number in the range from 0.5 to 1 */
+
+ /* Take the initial guess as 1/0.75 in qx format with appropriate sign. */
+ if (N >= 0) {
+ x = (int32) ((1 / 0.75) * (1 << qx));
+ /* input no is in the range 0.5 to 1. So 1/0.75 is taken as initial guess. */
+ } else {
+ x = (int32) ((1 / -0.75) * (1 << qx));
+ /* input no is in the range -0.5 to -1. So 1/-0.75 is taken as initial guess. */
+ }
+
+ /* iterate the equation x = 2*x - N*x*x for 4 times. */
+ for (i = 0; i < 4; i++) {
+ s32firstTerm = qm_shl32(x, 1); /* s32firstTerm = 2*x in q.29 */
+ s32secondTerm =
+ qm_muls321616((int16) (s32firstTerm >> 16),
+ (int16) (s32firstTerm >> 16));
+ /* s32secondTerm = x*x in q.(29+1-16)*2+1 */
+ s32secondTerm =
+ qm_muls321616((int16) (s32secondTerm >> 16), (int16) N);
+ /* s32secondTerm = N*x*x in q.((29+1-16)*2+1)-16+15+1 i.e. in q.29 */
+ x = qm_sub32(s32firstTerm, s32secondTerm);
+ /* can be added directly as both are in q.29 */
+ }
+
+ /* Bring the x to q.30 format. */
+ *result = qm_shl32(x, 1);
+ /* giving the output in q.30 format for q.15 input in 16 bits. */
+
+ /* compute the final q format of the result. */
+ *qResult = -qN + 30; /* adjusting the q format of actual output */
+
+ return;
+}
+
+#undef qx
diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c
new file mode 100644
index 000000000000..08393ee1efaf
--- /dev/null
+++ b/drivers/staging/brcm80211/util/siutils.c
@@ -0,0 +1,2961 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pci_core.h>
+#include <pcie_core.h>
+#include <nicpci.h>
+#include <bcmnvram.h>
+#include <bcmsrom.h>
+#include <hndtcam.h>
+#include <pcicfg.h>
+#include <sbsocram.h>
+#ifdef BCMSDIO
+#include <bcmsdh.h>
+#include <sdio.h>
+#include <sbsdio.h>
+#include <sbhnddma.h>
+#include <sbsdpcmdev.h>
+#include <bcmsdpcm.h>
+#endif /* BCMSDIO */
+#include <hndpmu.h>
+
+/* this file now contains only definitions for sb functions, only necessary
+*for devices using Sonics backplanes (bcm4329)
+*/
+
+/* if an amba SDIO device is supported, please further restrict the inclusion
+ * of this file
+ */
+#ifdef BCMSDIO
+#include "siutils_priv.h"
+#endif
+
+/* local prototypes */
+static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh,
+ void *regs, uint bustype, void *sdh, char **vars,
+ uint *varsz);
+static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+ void *sdh);
+static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+ uint32 savewin, uint *origidx, void *regs);
+static void si_nvram_process(si_info_t *sii, char *pvars);
+
+/* dev path concatenation util */
+static char *si_devpathvar(si_t *sih, char *var, int len, const char *name);
+static bool _si_clkctl_cc(si_info_t *sii, uint mode);
+static bool si_ispcie(si_info_t *sii);
+static uint BCMINITFN(socram_banksize) (si_info_t *sii, sbsocramregs_t *r,
+ uint8 idx, uint8 mtype);
+
+/* global variable to indicate reservation/release of gpio's */
+static uint32 si_gpioreservation;
+
+/* global flag to prevent shared resources from being initialized multiple times in si_attach() */
+
+/*
+ * Allocate a si handle.
+ * devid - pci device id (used to determine chip#)
+ * osh - opaque OS handle
+ * regs - virtual address of initial core registers
+ * bustype - pci/sb/sdio/etc
+ * vars - pointer to a pointer area for "environment" variables
+ * varsz - pointer to int to return the size of the vars
+ */
+si_t *BCMATTACHFN(si_attach) (uint devid, osl_t *osh, void *regs,
+ uint bustype, void *sdh, char **vars,
+ uint *varsz) {
+ si_info_t *sii;
+
+ /* alloc si_info_t */
+ sii = MALLOC(osh, sizeof(si_info_t));
+ if (sii == NULL) {
+ SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n",
+ MALLOCED(osh)));
+ return NULL;
+ }
+
+ if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) ==
+ NULL) {
+ MFREE(osh, sii, sizeof(si_info_t));
+ return NULL;
+ }
+ sii->vars = vars ? *vars : NULL;
+ sii->varsz = varsz ? *varsz : 0;
+
+ return (si_t *) sii;
+}
+
+/* global kernel resource */
+static si_info_t ksii;
+
+static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
+
+static bool
+BCMATTACHFN(si_buscore_prep) (si_info_t *sii, uint bustype, uint devid,
+ void *sdh) {
+
+ /* kludge to enable the clock on the 4306 which lacks a slowclock */
+ if (BUSTYPE(bustype) == PCI_BUS && !si_ispcie(sii))
+ si_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
+
+#if defined(BCMSDIO)
+ if (BUSTYPE(bustype) == SDIO_BUS) {
+ int err;
+ uint8 clkset;
+
+ /* Try forcing SDIO core to do ALPAvail request only */
+ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ clkset, &err);
+ if (!err) {
+ uint8 clkval;
+
+ /* If register supported, wait for ALPAvail and then force ALP */
+ clkval =
+ bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+ if ((clkval & ~SBSDIO_AVBITS) == clkset) {
+ SPINWAIT(((clkval =
+ bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ NULL)),
+ !SBSDIO_ALPAV(clkval)),
+ PMU_MAX_TRANSITION_DLY);
+ if (!SBSDIO_ALPAV(clkval)) {
+ SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval));
+ return FALSE;
+ }
+ clkset =
+ SBSDIO_FORCE_HW_CLKREQ_OFF |
+ SBSDIO_FORCE_ALP;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ clkset, &err);
+ OSL_DELAY(65);
+ }
+ }
+
+ /* Also, disable the extra SDIO pull-ups */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
+ NULL);
+ }
+#endif /* defined(BCMSDIO) */
+
+ return TRUE;
+}
+
+static bool
+BCMATTACHFN(si_buscore_setup) (si_info_t *sii, chipcregs_t *cc, uint bustype,
+ uint32 savewin, uint *origidx, void *regs) {
+ bool pci, pcie;
+ uint i;
+ uint pciidx, pcieidx, pcirev, pcierev;
+
+ cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
+ ASSERT((uintptr) cc);
+
+ /* get chipcommon rev */
+ sii->pub.ccrev = (int)si_corerev(&sii->pub);
+
+ /* get chipcommon chipstatus */
+ if (sii->pub.ccrev >= 11)
+ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
+
+ /* get chipcommon capabilites */
+ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
+ /* get chipcommon extended capabilities */
+
+ if (sii->pub.ccrev >= 35)
+ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
+
+ /* get pmu rev and caps */
+ if (sii->pub.cccaps & CC_CAP_PMU) {
+ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
+ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+ }
+
+ /*
+ SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
+ sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
+ sii->pub.pmucaps));
+ */
+
+ /* figure out bus/orignal core idx */
+ sii->pub.buscoretype = NODEV_CORE_ID;
+ sii->pub.buscorerev = NOREV;
+ sii->pub.buscoreidx = BADIDX;
+
+ pci = pcie = FALSE;
+ pcirev = pcierev = NOREV;
+ pciidx = pcieidx = BADIDX;
+
+ for (i = 0; i < sii->numcores; i++) {
+ uint cid, crev;
+
+ si_setcoreidx(&sii->pub, i);
+ cid = si_coreid(&sii->pub);
+ crev = si_corerev(&sii->pub);
+
+ /* Display cores found */
+ SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
+ i, cid, crev, sii->coresba[i], sii->regs[i]));
+
+ if (BUSTYPE(bustype) == PCI_BUS) {
+ if (cid == PCI_CORE_ID) {
+ pciidx = i;
+ pcirev = crev;
+ pci = TRUE;
+ } else if (cid == PCIE_CORE_ID) {
+ pcieidx = i;
+ pcierev = crev;
+ pcie = TRUE;
+ }
+ }
+#ifdef BCMSDIO
+ else if (((BUSTYPE(bustype) == SDIO_BUS) ||
+ (BUSTYPE(bustype) == SPI_BUS)) &&
+ ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) {
+ sii->pub.buscorerev = crev;
+ sii->pub.buscoretype = cid;
+ sii->pub.buscoreidx = i;
+ }
+#endif /* BCMSDIO */
+
+ /* find the core idx before entering this func. */
+ if ((savewin && (savewin == sii->coresba[i])) ||
+ (regs == sii->regs[i]))
+ *origidx = i;
+ }
+
+ if (pci && pcie) {
+ if (si_ispcie(sii))
+ pci = FALSE;
+ else
+ pcie = FALSE;
+ }
+ if (pci) {
+ sii->pub.buscoretype = PCI_CORE_ID;
+ sii->pub.buscorerev = pcirev;
+ sii->pub.buscoreidx = pciidx;
+ } else if (pcie) {
+ sii->pub.buscoretype = PCIE_CORE_ID;
+ sii->pub.buscorerev = pcierev;
+ sii->pub.buscoreidx = pcieidx;
+ }
+
+ SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
+ sii->pub.buscoretype, sii->pub.buscorerev));
+
+ /* fixup necessary chip/core configurations */
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+ if (SI_FAST(sii)) {
+ if (!sii->pch) {
+ sii->pch = (void *)(uintptr)pcicore_init(
+ &sii->pub, sii->osh,
+ (void *)PCIEREGS(sii));
+ if (sii->pch == NULL)
+ return FALSE;
+ }
+ }
+ if (si_pci_fixcfg(&sii->pub)) {
+ SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
+ return FALSE;
+ }
+ }
+
+ /* return to the original core */
+ si_setcoreidx(&sii->pub, *origidx);
+
+ return TRUE;
+}
+
+static void BCMATTACHFN(si_nvram_process) (si_info_t *sii, char *pvars)
+{
+ uint w = 0;
+
+ /* get boardtype and boardrev */
+ switch (BUSTYPE(sii->pub.bustype)) {
+ case PCI_BUS:
+ /* do a pci config read to get subsystem id and subvendor id */
+ w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(uint32));
+ /* Let nvram variables override subsystem Vend/ID */
+ sii->pub.boardvendor = (uint16)si_getdevpathintvar(&sii->pub,
+ "boardvendor");
+ if (sii->pub.boardvendor == 0)
+ sii->pub.boardvendor = w & 0xffff;
+ else
+ SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff));
+ sii->pub.boardtype = (uint16)si_getdevpathintvar(&sii->pub,
+ "boardtype");
+ if (sii->pub.boardtype == 0)
+ sii->pub.boardtype = (w >> 16) & 0xffff;
+ else
+ SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff));
+ break;
+
+#ifdef BCMSDIO
+ case SDIO_BUS:
+#endif
+ sii->pub.boardvendor = getintvar(pvars, "manfid");
+ sii->pub.boardtype = getintvar(pvars, "prodid");
+ break;
+
+#ifdef BCMSDIO
+ case SPI_BUS:
+ sii->pub.boardvendor = VENDOR_BROADCOM;
+ sii->pub.boardtype = SPI_BOARD;
+ break;
+#endif
+
+ case SI_BUS:
+ case JTAG_BUS:
+ sii->pub.boardvendor = VENDOR_BROADCOM;
+ sii->pub.boardtype = getintvar(pvars, "prodid");
+ if (pvars == NULL || (sii->pub.boardtype == 0)) {
+ sii->pub.boardtype = getintvar(NULL, "boardtype");
+ if (sii->pub.boardtype == 0)
+ sii->pub.boardtype = 0xffff;
+ }
+ break;
+ }
+
+ if (sii->pub.boardtype == 0) {
+ SI_ERROR(("si_doattach: unknown board type\n"));
+ ASSERT(sii->pub.boardtype);
+ }
+
+ sii->pub.boardflags = getintvar(pvars, "boardflags");
+}
+
+/* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
+/* this has been customized for the bcm 4329 ONLY */
+#ifdef BCMSDIO
+static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
+ osl_t *osh, void *regs,
+ uint bustype, void *sdh,
+ char **vars, uint *varsz) {
+ struct si_pub *sih = &sii->pub;
+ uint32 w, savewin;
+ chipcregs_t *cc;
+ char *pvars = NULL;
+ uint origidx;
+
+ ASSERT(GOODREGS(regs));
+
+ bzero((uchar *) sii, sizeof(si_info_t));
+
+ savewin = 0;
+
+ sih->buscoreidx = BADIDX;
+
+ sii->curmap = regs;
+ sii->sdh = sdh;
+ sii->osh = osh;
+
+ /* find Chipcommon address */
+ cc = (chipcregs_t *) sii->curmap;
+ sih->bustype = bustype;
+
+ if (bustype != BUSTYPE(bustype)) {
+ SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
+ return NULL;
+ }
+
+ /* bus/core/clk setup for register access */
+ if (!si_buscore_prep(sii, bustype, devid, sdh)) {
+ SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
+ bustype));
+ return NULL;
+ }
+
+ /* ChipID recognition.
+ * We assume we can read chipid at offset 0 from the regs arg.
+ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
+ * some way of recognizing them needs to be added here.
+ */
+ w = R_REG(osh, &cc->chipid);
+ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+ /* Might as wll fill in chip id rev & pkg */
+ sih->chip = w & CID_ID_MASK;
+ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+
+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
+ (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
+ sih->chippkg = BCM4329_182PIN_PKG_ID;
+ }
+ sih->issim = IS_SIM(sih->chippkg);
+
+ /* scan for cores */
+ /* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
+ sb_scan(&sii->pub, regs, devid);
+
+ /* no cores found, bail out */
+ if (sii->numcores == 0) {
+ SI_ERROR(("si_doattach: could not find any cores\n"));
+ return NULL;
+ }
+ /* bus/core/clk setup */
+ origidx = SI_CC_IDX;
+ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+ SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
+ goto exit;
+ }
+
+ /* Init nvram from flash if it exists */
+ nvram_init((void *)&(sii->pub));
+
+ /* Init nvram from sprom/otp if they exist */
+ if (srom_var_init
+ (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
+ SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
+ goto exit;
+ }
+ pvars = vars ? *vars : NULL;
+ si_nvram_process(sii, pvars);
+
+ /* === NVRAM, clock is ready === */
+
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+ W_REG(osh, &cc->gpiopullup, 0);
+ W_REG(osh, &cc->gpiopulldown, 0);
+ sb_setcoreidx(sih, origidx);
+
+ /* PMU specific initializations */
+ if (PMUCTL_ENAB(sih)) {
+ uint32 xtalfreq;
+ si_pmu_init(sih, sii->osh);
+ si_pmu_chip_init(sih, sii->osh);
+ xtalfreq = getintvar(pvars, "xtalfreq");
+ /* If xtalfreq var not available, try to measure it */
+ if (xtalfreq == 0)
+ xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
+ si_pmu_pll_init(sih, sii->osh, xtalfreq);
+ si_pmu_res_init(sih, sii->osh);
+ si_pmu_swreg_init(sih, sii->osh);
+ }
+
+ /* setup the GPIO based LED powersave register */
+ w = getintvar(pvars, "leddc");
+ if (w == 0)
+ w = DEFAULT_GPIOTIMERVAL;
+ sb_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
+
+#ifdef BCMDBG
+ /* clear any previous epidiag-induced target abort */
+ sb_taclear(sih, FALSE);
+#endif /* BCMDBG */
+
+ return sii;
+
+ exit:
+ return NULL;
+}
+
+#else /* BCMSDIO */
+static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
+ osl_t *osh, void *regs,
+ uint bustype, void *sdh,
+ char **vars, uint *varsz) {
+ struct si_pub *sih = &sii->pub;
+ uint32 w, savewin;
+ chipcregs_t *cc;
+ char *pvars = NULL;
+ uint origidx;
+
+ ASSERT(GOODREGS(regs));
+
+ bzero((uchar *) sii, sizeof(si_info_t));
+
+ savewin = 0;
+
+ sih->buscoreidx = BADIDX;
+
+ sii->curmap = regs;
+ sii->sdh = sdh;
+ sii->osh = osh;
+
+ /* check to see if we are a si core mimic'ing a pci core */
+ if ((bustype == PCI_BUS) &&
+ (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) ==
+ 0xffffffff)) {
+ SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " "devid:0x%x\n", __func__, devid));
+ bustype = SI_BUS;
+ }
+
+ /* find Chipcommon address */
+ if (bustype == PCI_BUS) {
+ savewin =
+ OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
+ if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
+ savewin = SI_ENUM_BASE;
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
+ cc = (chipcregs_t *) regs;
+ } else {
+ cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+ }
+
+ sih->bustype = bustype;
+ if (bustype != BUSTYPE(bustype)) {
+ SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
+ return NULL;
+ }
+
+ /* bus/core/clk setup for register access */
+ if (!si_buscore_prep(sii, bustype, devid, sdh)) {
+ SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
+ bustype));
+ return NULL;
+ }
+
+ /* ChipID recognition.
+ * We assume we can read chipid at offset 0 from the regs arg.
+ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
+ * some way of recognizing them needs to be added here.
+ */
+ w = R_REG(osh, &cc->chipid);
+ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+ /* Might as wll fill in chip id rev & pkg */
+ sih->chip = w & CID_ID_MASK;
+ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+
+ sih->issim = IS_SIM(sih->chippkg);
+
+ /* scan for cores */
+ if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
+ SI_MSG(("Found chip type AI (0x%08x)\n", w));
+ /* pass chipc address instead of original core base */
+ ai_scan(&sii->pub, (void *)(uintptr) cc, devid);
+ } else {
+ SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
+ return NULL;
+ }
+ /* no cores found, bail out */
+ if (sii->numcores == 0) {
+ SI_ERROR(("si_doattach: could not find any cores\n"));
+ return NULL;
+ }
+ /* bus/core/clk setup */
+ origidx = SI_CC_IDX;
+ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+ SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
+ goto exit;
+ }
+
+ /* assume current core is CC */
+ if ((sii->pub.ccrev == 0x25)
+ &&
+ ((CHIPID(sih->chip) == BCM43236_CHIP_ID
+ || CHIPID(sih->chip) == BCM43235_CHIP_ID
+ || CHIPID(sih->chip) == BCM43238_CHIP_ID)
+ && (CHIPREV(sii->pub.chiprev) <= 2))) {
+
+ if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
+ uint clkdiv;
+ clkdiv = R_REG(osh, &cc->clkdiv);
+ /* otp_clk_div is even number, 120/14 < 9mhz */
+ clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
+ W_REG(osh, &cc->clkdiv, clkdiv);
+ SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
+ }
+ OSL_DELAY(10);
+ }
+
+ /* Init nvram from flash if it exists */
+ nvram_init((void *)&(sii->pub));
+
+ /* Init nvram from sprom/otp if they exist */
+ if (srom_var_init
+ (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
+ SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
+ goto exit;
+ }
+ pvars = vars ? *vars : NULL;
+ si_nvram_process(sii, pvars);
+
+ /* === NVRAM, clock is ready === */
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+ W_REG(osh, &cc->gpiopullup, 0);
+ W_REG(osh, &cc->gpiopulldown, 0);
+ si_setcoreidx(sih, origidx);
+
+ /* PMU specific initializations */
+ if (PMUCTL_ENAB(sih)) {
+ uint32 xtalfreq;
+ si_pmu_init(sih, sii->osh);
+ si_pmu_chip_init(sih, sii->osh);
+ xtalfreq = getintvar(pvars, "xtalfreq");
+ /* If xtalfreq var not available, try to measure it */
+ if (xtalfreq == 0)
+ xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
+ si_pmu_pll_init(sih, sii->osh, xtalfreq);
+ si_pmu_res_init(sih, sii->osh);
+ si_pmu_swreg_init(sih, sii->osh);
+ }
+
+ /* setup the GPIO based LED powersave register */
+ w = getintvar(pvars, "leddc");
+ if (w == 0)
+ w = DEFAULT_GPIOTIMERVAL;
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
+
+ if (PCIE(sii)) {
+ ASSERT(sii->pch != NULL);
+ pcicore_attach(sii->pch, pvars, SI_DOATTACH);
+ }
+
+ if ((CHIPID(sih->chip) == BCM43224_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43421_CHIP_ID)) {
+ /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
+ if (CHIPREV(sih->chiprev) == 0) {
+ SI_MSG(("Applying 43224A0 WARs\n"));
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, chipcontrol),
+ CCTRL43224_GPIO_TOGGLE,
+ CCTRL43224_GPIO_TOGGLE);
+ si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
+ CCTRL_43224A0_12MA_LED_DRIVE);
+ }
+ if (CHIPREV(sih->chiprev) >= 1) {
+ SI_MSG(("Applying 43224B0+ WARs\n"));
+ si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
+ CCTRL_43224B0_12MA_LED_DRIVE);
+ }
+ }
+
+ if (CHIPID(sih->chip) == BCM4313_CHIP_ID) {
+ /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
+ SI_MSG(("Applying 4313 WARs\n"));
+ si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
+ CCTRL_4313_12MA_LED_DRIVE);
+ }
+
+ if (CHIPID(sih->chip) == BCM4331_CHIP_ID) {
+ /* Enable Ext PA lines depending on chip package option */
+ si_chipcontrl_epa4331(sih, TRUE);
+ }
+
+ return sii;
+ exit:
+ if (BUSTYPE(sih->bustype) == PCI_BUS) {
+ if (sii->pch)
+ pcicore_deinit(sii->pch);
+ sii->pch = NULL;
+ }
+
+ return NULL;
+}
+#endif /* BCMSDIO */
+
+/* may be called with core in reset */
+void BCMATTACHFN(si_detach) (si_t *sih)
+{
+ si_info_t *sii;
+ uint idx;
+
+ struct si_pub *si_local = NULL;
+ bcopy(&sih, &si_local, sizeof(si_t **));
+
+ sii = SI_INFO(sih);
+
+ if (sii == NULL)
+ return;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS)
+ for (idx = 0; idx < SI_MAXCORES; idx++)
+ if (sii->regs[idx]) {
+ REG_UNMAP(sii->regs[idx]);
+ sii->regs[idx] = NULL;
+ }
+
+ nvram_exit((void *)si_local); /* free up nvram buffers */
+
+ if (BUSTYPE(sih->bustype) == PCI_BUS) {
+ if (sii->pch)
+ pcicore_deinit(sii->pch);
+ sii->pch = NULL;
+ }
+#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
+ if (sii != &ksii)
+#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
+ MFREE(sii->osh, sii, sizeof(si_info_t));
+}
+
+void *si_osh(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->osh;
+}
+
+void si_setosh(si_t *sih, osl_t *osh)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ if (sii->osh != NULL) {
+ SI_ERROR(("osh is already set....\n"));
+ ASSERT(!sii->osh);
+ }
+ sii->osh = osh;
+}
+
+/* register driver interrupt disabling and restoring callback functions */
+void
+si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+ void *intrsenabled_fn, void *intr_arg)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ sii->intr_arg = intr_arg;
+ sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
+ sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
+ sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
+ /* save current core id. when this function called, the current core
+ * must be the core which provides driver functions(il, et, wl, etc.)
+ */
+ sii->dev_coreid = sii->coreid[sii->curidx];
+}
+
+void si_deregister_intr_callback(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ sii->intrsoff_fn = NULL;
+}
+
+uint si_intflag(si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return R_REG(sii->osh,
+ ((uint32 *) (uintptr) (sii->oob_router +
+ OOB_STATUSA)));
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint si_flag(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_flag(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void si_setint(si_t *sih, int siflag)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_setint(sih, siflag);
+ else
+ ASSERT(0);
+}
+
+#ifndef BCMSDIO
+uint si_coreid(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->coreid[sii->curidx];
+}
+#endif
+
+uint si_coreidx(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->curidx;
+}
+
+/* return the core-type instantiation # of the current core */
+uint si_coreunit(si_t *sih)
+{
+ si_info_t *sii;
+ uint idx;
+ uint coreid;
+ uint coreunit;
+ uint i;
+
+ sii = SI_INFO(sih);
+ coreunit = 0;
+
+ idx = sii->curidx;
+
+ ASSERT(GOODREGS(sii->curmap));
+ coreid = si_coreid(sih);
+
+ /* count the cores of our type */
+ for (i = 0; i < idx; i++)
+ if (sii->coreid[i] == coreid)
+ coreunit++;
+
+ return coreunit;
+}
+
+uint si_corevendor(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corevendor(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+bool si_backplane64(si_t *sih)
+{
+ return (sih->cccaps & CC_CAP_BKPLN64) != 0;
+}
+
+#ifndef BCMSDIO
+uint si_corerev(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corerev(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+#endif
+
+/* return index of coreid or BADIDX if not found */
+uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
+{
+ si_info_t *sii;
+ uint found;
+ uint i;
+
+ sii = SI_INFO(sih);
+
+ found = 0;
+
+ for (i = 0; i < sii->numcores; i++)
+ if (sii->coreid[i] == coreid) {
+ if (found == coreunit)
+ return i;
+ found++;
+ }
+
+ return BADIDX;
+}
+
+/* return list of found cores */
+uint si_corelist(si_t *sih, uint coreid[])
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ bcopy((uchar *) sii->coreid, (uchar *) coreid,
+ (sii->numcores * sizeof(uint)));
+ return sii->numcores;
+}
+
+/* return current register mapping */
+void *si_coreregs(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ ASSERT(GOODREGS(sii->curmap));
+
+ return sii->curmap;
+}
+
+/*
+ * This function changes logical "focus" to the indicated core;
+ * must be called with interrupts off.
+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core
+ */
+void *si_setcore(si_t *sih, uint coreid, uint coreunit)
+{
+ uint idx;
+
+ idx = si_findcoreidx(sih, coreid, coreunit);
+ if (!GOODIDX(idx))
+ return NULL;
+
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_setcoreidx(sih, idx);
+ else {
+#ifdef BCMSDIO
+ return sb_setcoreidx(sih, idx);
+#else
+ ASSERT(0);
+ return NULL;
+#endif
+ }
+}
+
+#ifndef BCMSDIO
+void *si_setcoreidx(si_t *sih, uint coreidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_setcoreidx(sih, coreidx);
+ else {
+ ASSERT(0);
+ return NULL;
+ }
+}
+#endif
+
+/* Turn off interrupt as required by sb_setcore, before switch core */
+void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
+{
+ void *cc;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (SI_FAST(sii)) {
+ /* Overloading the origidx variable to remember the coreid,
+ * this works because the core ids cannot be confused with
+ * core indices.
+ */
+ *origidx = coreid;
+ if (coreid == CC_CORE_ID)
+ return (void *)CCREGS_FAST(sii);
+ else if (coreid == sih->buscoretype)
+ return (void *)PCIEREGS(sii);
+ }
+ INTR_OFF(sii, *intr_val);
+ *origidx = sii->curidx;
+ cc = si_setcore(sih, coreid, 0);
+ ASSERT(cc != NULL);
+
+ return cc;
+}
+
+/* restore coreidx and restore interrupt */
+void si_restore_core(si_t *sih, uint coreid, uint intr_val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ if (SI_FAST(sii)
+ && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+ return;
+
+ si_setcoreidx(sih, coreid);
+ INTR_RESTORE(sii, intr_val);
+}
+
+int si_numaddrspaces(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_numaddrspaces(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint32 si_addrspace(si_t *sih, uint asidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_addrspace(sih, asidx);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint32 si_addrspacesize(si_t *sih, uint asidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_addrspacesize(sih, asidx);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_core_cflags(sih, mask, val);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_cflags_wo(sih, mask, val);
+ else
+ ASSERT(0);
+}
+
+uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_core_sflags(sih, mask, val);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+bool si_iscoreup(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_iscoreup(sih);
+ else {
+#ifdef BCMSDIO
+ return sb_iscoreup(sih);
+#else
+ ASSERT(0);
+ return FALSE;
+#endif
+ }
+}
+
+void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val)
+{
+ /* only for 4319, no requirement for SOCI_SB */
+ if (CHIPTYPE(sih->socitype) == SOCI_AI) {
+ ai_write_wrap_reg(sih, offset, val);
+ }
+}
+
+uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corereg(sih, coreidx, regoff, mask, val);
+ else {
+#ifdef BCMSDIO
+ return sb_corereg(sih, coreidx, regoff, mask, val);
+#else
+ ASSERT(0);
+ return 0;
+#endif
+ }
+}
+
+void si_core_disable(si_t *sih, uint32 bits)
+{
+
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_disable(sih, bits);
+#ifdef BCMSDIO
+ else
+ sb_core_disable(sih, bits);
+#endif
+}
+
+void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_reset(sih, bits, resetbits);
+#ifdef BCMSDIO
+ else
+ sb_core_reset(sih, bits, resetbits);
+#endif
+}
+
+/* Run bist on current core. Caller needs to take care of core-specific bist hazards */
+int si_corebist(si_t *sih)
+{
+ uint32 cflags;
+ int result = 0;
+
+ /* Read core control flags */
+ cflags = si_core_cflags(sih, 0, 0);
+
+ /* Set bist & fgc */
+ si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
+
+ /* Wait for bist done */
+ SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
+
+ if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
+ result = BCME_ERROR;
+
+ /* Reset core control flags */
+ si_core_cflags(sih, 0xffff, cflags);
+
+ return result;
+}
+
+static uint32 BCMINITFN(factor6) (uint32 x)
+{
+ switch (x) {
+ case CC_F6_2:
+ return 2;
+ case CC_F6_3:
+ return 3;
+ case CC_F6_4:
+ return 4;
+ case CC_F6_5:
+ return 5;
+ case CC_F6_6:
+ return 6;
+ case CC_F6_7:
+ return 7;
+ default:
+ return 0;
+ }
+}
+
+/* calculate the speed the SI would run at given a set of clockcontrol values */
+uint32 BCMINITFN(si_clock_rate) (uint32 pll_type, uint32 n, uint32 m)
+{
+ uint32 n1, n2, clock, m1, m2, m3, mc;
+
+ n1 = n & CN_N1_MASK;
+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
+
+ if (pll_type == PLL_TYPE6) {
+ if (m & CC_T6_MMASK)
+ return CC_T6_M1;
+ else
+ return CC_T6_M0;
+ } else if ((pll_type == PLL_TYPE1) ||
+ (pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
+ n1 = factor6(n1);
+ n2 += CC_F5_BIAS;
+ } else if (pll_type == PLL_TYPE2) {
+ n1 += CC_T2_BIAS;
+ n2 += CC_T2_BIAS;
+ ASSERT((n1 >= 2) && (n1 <= 7));
+ ASSERT((n2 >= 5) && (n2 <= 23));
+ } else if (pll_type == PLL_TYPE5) {
+ return 100000000;
+ } else
+ ASSERT(0);
+ /* PLL types 3 and 7 use BASE2 (25Mhz) */
+ if ((pll_type == PLL_TYPE3) || (pll_type == PLL_TYPE7)) {
+ clock = CC_CLOCK_BASE2 * n1 * n2;
+ } else
+ clock = CC_CLOCK_BASE1 * n1 * n2;
+
+ if (clock == 0)
+ return 0;
+
+ m1 = m & CC_M1_MASK;
+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
+
+ if ((pll_type == PLL_TYPE1) ||
+ (pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
+ m1 = factor6(m1);
+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
+ m2 += CC_F5_BIAS;
+ else
+ m2 = factor6(m2);
+ m3 = factor6(m3);
+
+ switch (mc) {
+ case CC_MC_BYPASS:
+ return clock;
+ case CC_MC_M1:
+ return clock / m1;
+ case CC_MC_M1M2:
+ return clock / (m1 * m2);
+ case CC_MC_M1M2M3:
+ return clock / (m1 * m2 * m3);
+ case CC_MC_M1M3:
+ return clock / (m1 * m3);
+ default:
+ return 0;
+ }
+ } else {
+ ASSERT(pll_type == PLL_TYPE2);
+
+ m1 += CC_T2_BIAS;
+ m2 += CC_T2M2_BIAS;
+ m3 += CC_T2_BIAS;
+ ASSERT((m1 >= 2) && (m1 <= 7));
+ ASSERT((m2 >= 3) && (m2 <= 10));
+ ASSERT((m3 >= 2) && (m3 <= 7));
+
+ if ((mc & CC_T2MC_M1BYP) == 0)
+ clock /= m1;
+ if ((mc & CC_T2MC_M2BYP) == 0)
+ clock /= m2;
+ if ((mc & CC_T2MC_M3BYP) == 0)
+ clock /= m3;
+
+ return clock;
+ }
+}
+
+uint32 BCMINITFN(si_clock) (si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint32 n, m;
+ uint idx;
+ uint32 pll_type, rate;
+ uint intr_val = 0;
+
+ sii = SI_INFO(sih);
+ INTR_OFF(sii, intr_val);
+ if (PMUCTL_ENAB(sih)) {
+ rate = si_pmu_si_clock(sih, sii->osh);
+ goto exit;
+ }
+
+ idx = sii->curidx;
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+ ASSERT(cc != NULL);
+
+ n = R_REG(sii->osh, &cc->clockcontrol_n);
+ pll_type = sih->cccaps & CC_CAP_PLL_MASK;
+ if (pll_type == PLL_TYPE6)
+ m = R_REG(sii->osh, &cc->clockcontrol_m3);
+ else if (pll_type == PLL_TYPE3)
+ m = R_REG(sii->osh, &cc->clockcontrol_m2);
+ else
+ m = R_REG(sii->osh, &cc->clockcontrol_sb);
+
+ /* calculate rate */
+ rate = si_clock_rate(pll_type, n, m);
+
+ if (pll_type == PLL_TYPE3)
+ rate = rate / 2;
+
+ /* switch back to previous core */
+ si_setcoreidx(sih, idx);
+ exit:
+ INTR_RESTORE(sii, intr_val);
+
+ return rate;
+}
+
+uint32 BCMINITFN(si_alp_clock) (si_t *sih)
+{
+ if (PMUCTL_ENAB(sih))
+ return si_pmu_alp_clock(sih, si_osh(sih));
+
+ return ALP_CLOCK;
+}
+
+uint32 BCMINITFN(si_ilp_clock) (si_t *sih)
+{
+ if (PMUCTL_ENAB(sih))
+ return si_pmu_ilp_clock(sih, si_osh(sih));
+
+ return ILP_CLOCK;
+}
+
+/* set chip watchdog reset timer to fire in 'ticks' */
+void si_watchdog(si_t *sih, uint ticks)
+{
+ uint nb, maxt;
+
+ if (PMUCTL_ENAB(sih)) {
+
+ if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
+ (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
+ si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
+ si_setcore(sih, USB20D_CORE_ID, 0);
+ si_core_disable(sih, 1);
+ si_setcore(sih, CC_CORE_ID, 0);
+ }
+
+ nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
+ /* The mips compiler uses the sllv instruction,
+ * so we specially handle the 32-bit case.
+ */
+ if (nb == 32)
+ maxt = 0xffffffff;
+ else
+ maxt = ((1 << nb) - 1);
+
+ if (ticks == 1)
+ ticks = 2;
+ else if (ticks > maxt)
+ ticks = maxt;
+
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog),
+ ~0, ticks);
+ } else {
+ /* make sure we come up in fast clock mode; or if clearing, clear clock */
+ si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC);
+ maxt = (1 << 28) - 1;
+ if (ticks > maxt)
+ ticks = maxt;
+
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0,
+ ticks);
+ }
+}
+
+/* trigger watchdog reset after ms milliseconds */
+void si_watchdog_ms(si_t *sih, uint32 ms)
+{
+ si_watchdog(sih, wd_msticks * ms);
+}
+
+uint16 BCMATTACHFN(si_d11_devid) (si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint16 device;
+
+ /* normal case: nvram variable with devpath->devid->wl0id */
+ device = (uint16) si_getdevpathintvar(sih, "devid");
+ if (device != 0)
+ goto bail;
+
+ /* Get devid from OTP/SPROM depending on where the SROM is read */
+ device = (uint16) getintvar(sii->vars, "devid");
+ if (device != 0)
+ goto bail;
+
+ /* no longer support wl0id, but keep the code here for backward compatibility. */
+ device = (uint16) getintvar(sii->vars, "wl0id");
+ if (device != 0)
+ goto bail;
+
+ /* ignore it */
+ device = 0xffff;
+
+bail:
+ return device;
+}
+
+/* return the slow clock source - LPO, XTAL, or PCI */
+static uint si_slowclk_src(si_info_t *sii)
+{
+ chipcregs_t *cc;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ if (sii->pub.ccrev < 6) {
+ if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
+ (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32))
+ & PCI_CFG_GPIO_SCS))
+ return SCC_SS_PCI;
+ else
+ return SCC_SS_XTAL;
+ } else if (sii->pub.ccrev < 10) {
+ cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx);
+ return R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK;
+ } else /* Insta-clock */
+ return SCC_SS_XTAL;
+}
+
+/* return the ILP (slowclock) min or max frequency */
+static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+{
+ uint32 slowclk;
+ uint div;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ /* shouldn't be here unless we've established the chip has dynamic clk control */
+ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
+
+ slowclk = si_slowclk_src(sii);
+ if (sii->pub.ccrev < 6) {
+ if (slowclk == SCC_SS_PCI)
+ return max_freq ? (PCIMAXFREQ / 64)
+ : (PCIMINFREQ / 64);
+ else
+ return max_freq ? (XTALMAXFREQ / 32)
+ : (XTALMINFREQ / 32);
+ } else if (sii->pub.ccrev < 10) {
+ div = 4 *
+ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >>
+ SCC_CD_SHIFT) + 1);
+ if (slowclk == SCC_SS_LPO)
+ return max_freq ? LPOMAXFREQ : LPOMINFREQ;
+ else if (slowclk == SCC_SS_XTAL)
+ return max_freq ? (XTALMAXFREQ / div)
+ : (XTALMINFREQ / div);
+ else if (slowclk == SCC_SS_PCI)
+ return max_freq ? (PCIMAXFREQ / div)
+ : (PCIMINFREQ / div);
+ else
+ ASSERT(0);
+ } else {
+ /* Chipc rev 10 is InstaClock */
+ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+ div = 4 * (div + 1);
+ return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
+ }
+ return 0;
+}
+
+static void BCMINITFN(si_clkctl_setdelay) (si_info_t *sii, void *chipcregs)
+{
+ chipcregs_t *cc = (chipcregs_t *) chipcregs;
+ uint slowmaxfreq, pll_delay, slowclk;
+ uint pll_on_delay, fref_sel_delay;
+
+ pll_delay = PLL_DELAY;
+
+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
+ * since the xtal will also be powered down by dynamic clk control logic.
+ */
+
+ slowclk = si_slowclk_src(sii);
+ if (slowclk != SCC_SS_XTAL)
+ pll_delay += XTAL_ON_DELAY;
+
+ /* Starting with 4318 it is ILP that is used for the delays */
+ slowmaxfreq =
+ si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
+
+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+
+ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
+ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
+}
+
+/* initialize power control delay registers */
+void BCMINITFN(si_clkctl_init) (si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx = 0;
+ chipcregs_t *cc;
+ bool fast;
+
+ if (!CCCTL_ENAB(sih))
+ return;
+
+ sii = SI_INFO(sih);
+ fast = SI_FAST(sii);
+ if (!fast) {
+ origidx = sii->curidx;
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+ if (cc == NULL)
+ return;
+ } else {
+ cc = (chipcregs_t *) CCREGS_FAST(sii);
+ if (cc == NULL)
+ return;
+ }
+ ASSERT(cc != NULL);
+
+ /* set all Instaclk chip ILP to 1 MHz */
+ if (sih->ccrev >= 10)
+ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+
+ si_clkctl_setdelay(sii, (void *)(uintptr) cc);
+
+ if (!fast)
+ si_setcoreidx(sih, origidx);
+}
+
+/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
+uint16 BCMINITFN(si_clkctl_fast_pwrup_delay) (si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx = 0;
+ chipcregs_t *cc;
+ uint slowminfreq;
+ uint16 fpdelay;
+ uint intr_val = 0;
+ bool fast;
+
+ sii = SI_INFO(sih);
+ if (PMUCTL_ENAB(sih)) {
+ INTR_OFF(sii, intr_val);
+ fpdelay = si_pmu_fast_pwrup_delay(sih, sii->osh);
+ INTR_RESTORE(sii, intr_val);
+ return fpdelay;
+ }
+
+ if (!CCCTL_ENAB(sih))
+ return 0;
+
+ fast = SI_FAST(sii);
+ fpdelay = 0;
+ if (!fast) {
+ origidx = sii->curidx;
+ INTR_OFF(sii, intr_val);
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+ if (cc == NULL)
+ goto done;
+ } else {
+ cc = (chipcregs_t *) CCREGS_FAST(sii);
+ if (cc == NULL)
+ goto done;
+ }
+ ASSERT(cc != NULL);
+
+ slowminfreq = si_slowclk_freq(sii, FALSE, cc);
+ fpdelay = (((R_REG(sii->osh, &cc->pll_on_delay) + 2) * 1000000) +
+ (slowminfreq - 1)) / slowminfreq;
+
+ done:
+ if (!fast) {
+ si_setcoreidx(sih, origidx);
+ INTR_RESTORE(sii, intr_val);
+ }
+ return fpdelay;
+}
+
+/* turn primary xtal and/or pll off/on */
+int si_clkctl_xtal(si_t *sih, uint what, bool on)
+{
+ si_info_t *sii;
+ uint32 in, out, outen;
+
+ sii = SI_INFO(sih);
+
+ switch (BUSTYPE(sih->bustype)) {
+
+#ifdef BCMSDIO
+ case SDIO_BUS:
+ return -1;
+#endif /* BCMSDIO */
+
+ case PCI_BUS:
+ /* pcie core doesn't have any mapping to control the xtal pu */
+ if (PCIE(sii))
+ return -1;
+
+ in = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_IN, sizeof(uint32));
+ out =
+ OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32));
+ outen =
+ OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32));
+
+ /*
+ * Avoid glitching the clock if GPRS is already using it.
+ * We can't actually read the state of the PLLPD so we infer it
+ * by the value of XTAL_PU which *is* readable via gpioin.
+ */
+ if (on && (in & PCI_CFG_GPIO_XTAL))
+ return 0;
+
+ if (what & XTAL)
+ outen |= PCI_CFG_GPIO_XTAL;
+ if (what & PLL)
+ outen |= PCI_CFG_GPIO_PLL;
+
+ if (on) {
+ /* turn primary xtal on */
+ if (what & XTAL) {
+ out |= PCI_CFG_GPIO_XTAL;
+ if (what & PLL)
+ out |= PCI_CFG_GPIO_PLL;
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32), outen);
+ OSL_DELAY(XTAL_ON_DELAY);
+ }
+
+ /* turn pll on */
+ if (what & PLL) {
+ out &= ~PCI_CFG_GPIO_PLL;
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_DELAY(2000);
+ }
+ } else {
+ if (what & XTAL)
+ out &= ~PCI_CFG_GPIO_XTAL;
+ if (what & PLL)
+ out |= PCI_CFG_GPIO_PLL;
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32), outen);
+ }
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * clock control policy function throught chipcommon
+ *
+ * set dynamic clk control mode (forceslow, forcefast, dynamic)
+ * returns true if we are forcing fast clock
+ * this is a wrapper over the next internal function
+ * to allow flexible policy settings for outside caller
+ */
+bool si_clkctl_cc(si_t *sih, uint mode)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ /* chipcommon cores prior to rev6 don't support dynamic clock control */
+ if (sih->ccrev < 6)
+ return FALSE;
+
+ if (PCI_FORCEHT(sii))
+ return mode == CLK_FAST;
+
+ return _si_clkctl_cc(sii, mode);
+}
+
+/* clk control mechanism through chipcommon, no policy checking */
+static bool _si_clkctl_cc(si_info_t *sii, uint mode)
+{
+ uint origidx = 0;
+ chipcregs_t *cc;
+ uint32 scc;
+ uint intr_val = 0;
+ bool fast = SI_FAST(sii);
+
+ /* chipcommon cores prior to rev6 don't support dynamic clock control */
+ if (sii->pub.ccrev < 6)
+ return FALSE;
+
+ /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
+ ASSERT(sii->pub.ccrev != 10);
+
+ if (!fast) {
+ INTR_OFF(sii, intr_val);
+ origidx = sii->curidx;
+
+ if ((BUSTYPE(sii->pub.bustype) == SI_BUS) &&
+ si_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
+ (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
+ goto done;
+
+ cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0);
+ } else {
+ cc = (chipcregs_t *) CCREGS_FAST(sii);
+ if (cc == NULL)
+ goto done;
+ }
+ ASSERT(cc != NULL);
+
+ if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
+ goto done;
+
+ switch (mode) {
+ case CLK_FAST: /* FORCEHT, fast (pll) clock */
+ if (sii->pub.ccrev < 10) {
+ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
+ si_clkctl_xtal(&sii->pub, XTAL, ON);
+ SET_REG(sii->osh, &cc->slow_clk_ctl,
+ (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
+ } else if (sii->pub.ccrev < 20) {
+ OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR);
+ } else {
+ OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT);
+ }
+
+ /* wait for the PLL */
+ if (PMUCTL_ENAB(&sii->pub)) {
+ uint32 htavail = CCS_HTAVAIL;
+ SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail)
+ == 0), PMU_MAX_TRANSITION_DLY);
+ ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail);
+ } else {
+ OSL_DELAY(PLL_DELAY);
+ }
+ break;
+
+ case CLK_DYNAMIC: /* enable dynamic clock control */
+ if (sii->pub.ccrev < 10) {
+ scc = R_REG(sii->osh, &cc->slow_clk_ctl);
+ scc &= ~(SCC_FS | SCC_IP | SCC_XC);
+ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
+ scc |= SCC_XC;
+ W_REG(sii->osh, &cc->slow_clk_ctl, scc);
+
+ /* for dynamic control, we have to release our xtal_pu "force on" */
+ if (scc & SCC_XC)
+ si_clkctl_xtal(&sii->pub, XTAL, OFF);
+ } else if (sii->pub.ccrev < 20) {
+ /* Instaclock */
+ AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR);
+ } else {
+ AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT);
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ done:
+ if (!fast) {
+ si_setcoreidx(&sii->pub, origidx);
+ INTR_RESTORE(sii, intr_val);
+ }
+ return mode == CLK_FAST;
+}
+
+/* Build device path. Support SI, PCI, and JTAG for now. */
+int BCMATTACHFN(si_devpath) (si_t *sih, char *path, int size)
+{
+ int slen;
+
+ ASSERT(path != NULL);
+ ASSERT(size >= SI_DEVPATH_BUFSZ);
+
+ if (!path || size <= 0)
+ return -1;
+
+ switch (BUSTYPE(sih->bustype)) {
+ case SI_BUS:
+ case JTAG_BUS:
+ slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih));
+ break;
+ case PCI_BUS:
+ ASSERT((SI_INFO(sih))->osh != NULL);
+ slen = snprintf(path, (size_t) size, "pci/%u/%u/",
+ OSL_PCI_BUS((SI_INFO(sih))->osh),
+ OSL_PCI_SLOT((SI_INFO(sih))->osh));
+ break;
+
+#ifdef BCMSDIO
+ case SDIO_BUS:
+ SI_ERROR(("si_devpath: device 0 assumed\n"));
+ slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih));
+ break;
+#endif
+ default:
+ slen = -1;
+ ASSERT(0);
+ break;
+ }
+
+ if (slen < 0 || slen >= size) {
+ path[0] = '\0';
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Get a variable, but only if it has a devpath prefix */
+char *BCMATTACHFN(si_getdevpathvar) (si_t *sih, const char *name)
+{
+ char varname[SI_DEVPATH_BUFSZ + 32];
+
+ si_devpathvar(sih, varname, sizeof(varname), name);
+
+ return getvar(NULL, varname);
+}
+
+/* Get a variable, but only if it has a devpath prefix */
+int BCMATTACHFN(si_getdevpathintvar) (si_t *sih, const char *name)
+{
+#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
+ return getintvar(NULL, name);
+#else
+ char varname[SI_DEVPATH_BUFSZ + 32];
+
+ si_devpathvar(sih, varname, sizeof(varname), name);
+
+ return getintvar(NULL, varname);
+#endif
+}
+
+char *si_getnvramflvar(si_t *sih, const char *name)
+{
+ return getvar(NULL, name);
+}
+
+/* Concatenate the dev path with a varname into the given 'var' buffer
+ * and return the 'var' pointer.
+ * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
+ * On overflow, the first char will be set to '\0'.
+ */
+static char *BCMATTACHFN(si_devpathvar) (si_t *sih, char *var, int len,
+ const char *name) {
+ uint path_len;
+
+ if (!var || len <= 0)
+ return var;
+
+ if (si_devpath(sih, var, len) == 0) {
+ path_len = strlen(var);
+
+ if (strlen(name) + 1 > (uint) (len - path_len))
+ var[0] = '\0';
+ else
+ strncpy(var + path_len, name, len - path_len - 1);
+ }
+
+ return var;
+}
+
+uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (!PCIE(sii)) {
+ SI_ERROR(("%s: Not a PCIE device\n", __func__));
+ return 0;
+ }
+
+ return pcicore_pciereg(sii->pch, offset, mask, val, type);
+}
+
+uint32
+si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask,
+ uint32 val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (!PCIE(sii)) {
+ SI_ERROR(("%s: Not a PCIE device\n", __func__));
+ return 0;
+ }
+
+ return pcicore_pcieserdesreg(sii->pch, mdioslave, offset, mask, val);
+
+}
+
+/* return TRUE if PCIE capability exists in the pci config space */
+static bool si_ispcie(si_info_t *sii)
+{
+ uint8 cap_ptr;
+
+ if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
+ return FALSE;
+
+ cap_ptr =
+ pcicore_find_pci_capability(sii->osh, PCI_CAP_PCIECAP_ID, NULL,
+ NULL);
+ if (!cap_ptr)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Wake-on-wireless-LAN (WOWL) support functions */
+/* Enable PME generation and disable clkreq */
+void si_pci_pmeen(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ pcicore_pmeen(sii->pch);
+}
+
+/* Return TRUE if PME status is set */
+bool si_pci_pmestat(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ return pcicore_pmestat(sii->pch);
+}
+
+/* Disable PME generation, clear the PME status bit if set */
+void si_pci_pmeclr(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ pcicore_pmeclr(sii->pch);
+}
+
+#ifdef BCMSDIO
+/* initialize the sdio core */
+void si_sdio_init(si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+
+ if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) ||
+ (sih->buscoretype == SDIOD_CORE_ID)) {
+ uint idx;
+ sdpcmd_regs_t *sdpregs;
+
+ /* get the current core index */
+ idx = sii->curidx;
+ ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0));
+
+ /* switch to sdio core */
+ sdpregs = (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0);
+ if (!sdpregs)
+ sdpregs =
+ (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0);
+ ASSERT(sdpregs);
+
+ SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs));
+
+ /* enable backplane error and core interrupts */
+ W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT);
+ W_REG(sii->osh, &sdpregs->sbintmask,
+ (I_SB_SERR | I_SB_RESPERR | (1 << idx)));
+
+ /* switch back to previous core */
+ si_setcoreidx(sih, idx);
+ }
+
+ /* enable interrupts */
+ bcmsdh_intr_enable(sii->sdh);
+
+}
+#endif /* BCMSDIO */
+
+bool BCMATTACHFN(si_pci_war16165) (si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ return PCI(sii) && (sih->buscorerev <= 10);
+}
+
+/* Disable pcie_war_ovr for some platforms (sigh!)
+ * This is for boards that have BFL2_PCIEWAR_OVR set
+ * but are in systems that still want the benefits of ASPM
+ * Note that this should be done AFTER si_doattach
+ */
+void si_pcie_war_ovr_update(si_t *sih, uint8 aspm)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (!PCIE(sii))
+ return;
+
+ pcie_war_ovr_aspm_update(sii->pch, aspm);
+}
+
+/* back door for other module to override chippkg */
+void si_chippkg_set(si_t *sih, uint val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ sii->pub.chippkg = val;
+}
+
+void BCMINITFN(si_pci_up) (si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ /* if not pci bus, we're done */
+ if (BUSTYPE(sih->bustype) != PCI_BUS)
+ return;
+
+ if (PCI_FORCEHT(sii))
+ _si_clkctl_cc(sii, CLK_FAST);
+
+ if (PCIE(sii))
+ pcicore_up(sii->pch, SI_PCIUP);
+
+}
+
+/* Unconfigure and/or apply various WARs when system is going to sleep mode */
+void BCMUNINITFN(si_pci_sleep) (si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ pcicore_sleep(sii->pch);
+}
+
+/* Unconfigure and/or apply various WARs when going down */
+void BCMINITFN(si_pci_down) (si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ /* if not pci bus, we're done */
+ if (BUSTYPE(sih->bustype) != PCI_BUS)
+ return;
+
+ /* release FORCEHT since chip is going to "down" state */
+ if (PCI_FORCEHT(sii))
+ _si_clkctl_cc(sii, CLK_DYNAMIC);
+
+ pcicore_down(sii->pch, SI_PCIDOWN);
+}
+
+/*
+ * Configure the pci core for pci client (NIC) action
+ * coremask is the bitvec of cores by index to be enabled.
+ */
+void BCMATTACHFN(si_pci_setup) (si_t *sih, uint coremask)
+{
+ si_info_t *sii;
+ sbpciregs_t *pciregs = NULL;
+ uint32 siflag = 0, w;
+ uint idx = 0;
+
+ sii = SI_INFO(sih);
+
+ if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
+ return;
+
+ ASSERT(PCI(sii) || PCIE(sii));
+ ASSERT(sii->pub.buscoreidx != BADIDX);
+
+ if (PCI(sii)) {
+ /* get current core index */
+ idx = sii->curidx;
+
+ /* we interrupt on this backplane flag number */
+ siflag = si_flag(sih);
+
+ /* switch over to pci core */
+ pciregs =
+ (sbpciregs_t *) si_setcoreidx(sih, sii->pub.buscoreidx);
+ }
+
+ /*
+ * Enable sb->pci interrupts. Assume
+ * PCI rev 2.3 support was added in pci core rev 6 and things changed..
+ */
+ if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
+ /* pci config write to set this core bit in PCIIntMask */
+ w = OSL_PCI_READ_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32));
+ w |= (coremask << PCI_SBIM_SHIFT);
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32), w);
+ } else {
+ /* set sbintvec bit for our flag number */
+ si_setint(sih, siflag);
+ }
+
+ if (PCI(sii)) {
+ OR_REG(sii->osh, &pciregs->sbtopci2,
+ (SBTOPCI_PREF | SBTOPCI_BURST));
+ if (sii->pub.buscorerev >= 11) {
+ OR_REG(sii->osh, &pciregs->sbtopci2,
+ SBTOPCI_RC_READMULTI);
+ w = R_REG(sii->osh, &pciregs->clkrun);
+ W_REG(sii->osh, &pciregs->clkrun,
+ (w | PCI_CLKRUN_DSBL));
+ w = R_REG(sii->osh, &pciregs->clkrun);
+ }
+
+ /* switch back to previous core */
+ si_setcoreidx(sih, idx);
+ }
+}
+
+uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (!(PCIE(sii)))
+ return 0;
+ return pcie_clkreq(sii->pch, mask, val);
+}
+
+uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (!PCIE(sii))
+ return 0;
+
+ return pcie_lcreg(sii->pch, mask, val);
+}
+
+/* indirect way to read pcie config regs */
+uint si_pcie_readreg(void *sih, uint addrtype, uint offset)
+{
+ return pcie_readreg(((si_info_t *) sih)->osh,
+ (sbpcieregs_t *) PCIEREGS(((si_info_t *) sih)),
+ addrtype, offset);
+}
+
+/*
+ * Fixup SROMless PCI device's configuration.
+ * The current core may be changed upon return.
+ */
+int si_pci_fixcfg(si_t *sih)
+{
+ uint origidx, pciidx;
+ sbpciregs_t *pciregs = NULL;
+ sbpcieregs_t *pcieregs = NULL;
+ void *regs = NULL;
+ uint16 val16, *reg16 = NULL;
+
+ si_info_t *sii = SI_INFO(sih);
+
+ ASSERT(BUSTYPE(sii->pub.bustype) == PCI_BUS);
+
+ /* Fixup PI in SROM shadow area to enable the correct PCI core access */
+ /* save the current index */
+ origidx = si_coreidx(&sii->pub);
+
+ /* check 'pi' is correct and fix it if not */
+ if (sii->pub.buscoretype == PCIE_CORE_ID) {
+ pcieregs =
+ (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0);
+ regs = pcieregs;
+ ASSERT(pcieregs != NULL);
+ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
+ } else if (sii->pub.buscoretype == PCI_CORE_ID) {
+ pciregs = (sbpciregs_t *) si_setcore(&sii->pub, PCI_CORE_ID, 0);
+ regs = pciregs;
+ ASSERT(pciregs != NULL);
+ reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
+ }
+ pciidx = si_coreidx(&sii->pub);
+ val16 = R_REG(sii->osh, reg16);
+ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16) pciidx) {
+ val16 =
+ (uint16) (pciidx << SRSH_PI_SHIFT) | (val16 &
+ ~SRSH_PI_MASK);
+ W_REG(sii->osh, reg16, val16);
+ }
+
+ /* restore the original index */
+ si_setcoreidx(&sii->pub, origidx);
+
+ pcicore_hwup(sii->pch);
+ return 0;
+}
+
+/* change logical "focus" to the gpio core for optimized access */
+void *si_gpiosetcore(si_t *sih)
+{
+ return si_setcoreidx(sih, SI_CC_IDX);
+}
+
+/* mask&set gpiocontrol bits */
+uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiocontrol);
+ return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+/* mask&set gpio output enable bits */
+uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpioouten);
+ return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+/* mask&set gpio output bits */
+uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpioout);
+ return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+/* reserve one gpio */
+uint32 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ /* only cores on SI_BUS share GPIO's and only applcation users need to
+ * reserve/release GPIO
+ */
+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
+ return 0xffffffff;
+ }
+ /* make sure only one bit is set */
+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
+ ASSERT((gpio_bitmask)
+ && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ return 0xffffffff;
+ }
+
+ /* already reserved */
+ if (si_gpioreservation & gpio_bitmask)
+ return 0xffffffff;
+ /* set reservation */
+ si_gpioreservation |= gpio_bitmask;
+
+ return si_gpioreservation;
+}
+
+/* release one gpio */
+/*
+ * releasing the gpio doesn't change the current value on the GPIO last write value
+ * persists till some one overwrites it
+ */
+
+uint32 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ /* only cores on SI_BUS share GPIO's and only applcation users need to
+ * reserve/release GPIO
+ */
+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
+ return 0xffffffff;
+ }
+ /* make sure only one bit is set */
+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
+ ASSERT((gpio_bitmask)
+ && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ return 0xffffffff;
+ }
+
+ /* already released */
+ if (!(si_gpioreservation & gpio_bitmask))
+ return 0xffffffff;
+
+ /* clear reservation */
+ si_gpioreservation &= ~gpio_bitmask;
+
+ return si_gpioreservation;
+}
+
+/* return the current gpioin register value */
+uint32 si_gpioin(si_t *sih)
+{
+ si_info_t *sii;
+ uint regoff;
+
+ sii = SI_INFO(sih);
+ regoff = 0;
+
+ regoff = OFFSETOF(chipcregs_t, gpioin);
+ return si_corereg(sih, SI_CC_IDX, regoff, 0, 0);
+}
+
+/* mask&set gpio interrupt polarity bits */
+uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ si_info_t *sii;
+ uint regoff;
+
+ sii = SI_INFO(sih);
+ regoff = 0;
+
+ /* gpios could be shared on router platforms */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
+ return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+/* mask&set gpio interrupt mask bits */
+uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ si_info_t *sii;
+ uint regoff;
+
+ sii = SI_INFO(sih);
+ regoff = 0;
+
+ /* gpios could be shared on router platforms */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiointmask);
+ return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+/* assign the gpio to an led */
+uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 16)
+ return 0xffffffff;
+
+ /* gpio led powersave reg */
+ return si_corereg
+ (sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask,
+ val);
+}
+
+/* mask&set gpio timer val */
+uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (sih->ccrev < 16)
+ return 0xffffffff;
+
+ return si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiotimerval), mask,
+ gpiotimerval);
+}
+
+uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ uint offs;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 20)
+ return 0xffffffff;
+
+ offs =
+ (updown ? OFFSETOF(chipcregs_t, gpiopulldown) :
+ OFFSETOF(chipcregs_t, gpiopullup));
+ return si_corereg(sih, SI_CC_IDX, offs, mask, val);
+}
+
+uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ uint offs;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return 0xffffffff;
+
+ if (regtype == GPIO_REGEVT)
+ offs = OFFSETOF(chipcregs_t, gpioevent);
+ else if (regtype == GPIO_REGEVT_INTMSK)
+ offs = OFFSETOF(chipcregs_t, gpioeventintmask);
+ else if (regtype == GPIO_REGEVT_INTPOL)
+ offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
+ else
+ return 0xffffffff;
+
+ return si_corereg(sih, SI_CC_IDX, offs, mask, val);
+}
+
+void *BCMATTACHFN(si_gpio_handler_register) (si_t *sih, uint32 event,
+ bool level, gpio_handler_t cb,
+ void *arg) {
+ si_info_t *sii;
+ gpioh_item_t *gi;
+
+ ASSERT(event);
+ ASSERT(cb != NULL);
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return NULL;
+
+ gi = MALLOC(sii->osh, sizeof(gpioh_item_t));
+ if (gi == NULL)
+ return NULL;
+
+ bzero(gi, sizeof(gpioh_item_t));
+ gi->event = event;
+ gi->handler = cb;
+ gi->arg = arg;
+ gi->level = level;
+
+ gi->next = sii->gpioh_head;
+ sii->gpioh_head = gi;
+
+ return (void *)(gi);
+}
+
+void BCMATTACHFN(si_gpio_handler_unregister) (si_t *sih, void *gpioh)
+{
+ si_info_t *sii;
+ gpioh_item_t *p, *n;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return;
+
+ ASSERT(sii->gpioh_head != NULL);
+ if ((void *)sii->gpioh_head == gpioh) {
+ sii->gpioh_head = sii->gpioh_head->next;
+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ } else {
+ p = sii->gpioh_head;
+ n = p->next;
+ while (n) {
+ if ((void *)n == gpioh) {
+ p->next = n->next;
+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ }
+ p = n;
+ n = n->next;
+ }
+ }
+
+ ASSERT(0); /* Not found in list */
+}
+
+void si_gpio_handler_process(si_t *sih)
+{
+ si_info_t *sii;
+ gpioh_item_t *h;
+ uint32 status;
+ uint32 level = si_gpioin(sih);
+ uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
+
+ sii = SI_INFO(sih);
+ for (h = sii->gpioh_head; h != NULL; h = h->next) {
+ if (h->handler) {
+ status = (h->level ? level : edge);
+
+ if (status & h->event)
+ h->handler(status, h->arg);
+ }
+ }
+
+ si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
+}
+
+uint32 si_gpio_int_enable(si_t *sih, bool enable)
+{
+ si_info_t *sii;
+ uint offs;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return 0xffffffff;
+
+ offs = OFFSETOF(chipcregs_t, intmask);
+ return si_corereg
+ (sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0));
+}
+
+/* Return the size of the specified SOCRAM bank */
+static uint
+socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index,
+ uint8 mem_type)
+{
+ uint banksize, bankinfo;
+ uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+
+ ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
+
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ banksize =
+ SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
+ return banksize;
+}
+
+void si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ if (!set)
+ *enable = *protect = 0;
+
+ /* Switch to SOCRAM core */
+ regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
+ if (!regs)
+ goto done;
+
+ /* Get info for determining size */
+ wasup = si_iscoreup(sih);
+ if (!wasup)
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 10) {
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+ uint32 bankidx, bankinfo;
+
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
+ SOCRAM_DEVRAMBANK_SHIFT);
+ for (i = 0; i < nb; i++) {
+ bankidx =
+ i | (SOCRAM_MEMTYPE_DEVRAM <<
+ SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ if (set) {
+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
+ if (*enable) {
+ bankinfo |=
+ (1 <<
+ SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
+ if (*protect)
+ bankinfo |=
+ (1 <<
+ SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
+ }
+ W_REG(sii->osh, &regs->bankinfo, bankinfo);
+ } else if (i == 0) {
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
+ *enable = 1;
+ if (bankinfo &
+ SOCRAM_BANKINFO_DEVRAMPRO_MASK)
+ *protect = 1;
+ }
+ }
+ }
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+ done:
+ INTR_RESTORE(sii, intr_val);
+}
+
+bool si_socdevram_pkg(si_t *sih)
+{
+ if (si_socdevram_size(sih) > 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+uint32 si_socdevram_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ uint32 memsize = 0;
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
+ if (!regs)
+ goto done;
+
+ /* Get info for determining size */
+ wasup = si_iscoreup(sih);
+ if (!wasup)
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 10) {
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
+ SOCRAM_DEVRAMBANK_SHIFT));
+ for (i = 0; i < nb; i++)
+ memsize +=
+ socram_banksize(sii, regs, i,
+ SOCRAM_MEMTYPE_DEVRAM);
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+ done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+/* Return the RAM size of the SOCRAM core */
+uint32 si_socram_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+ uint32 coreinfo;
+ uint memsize = 0;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
+ if (!regs)
+ goto done;
+
+ /* Get info for determining size */
+ wasup = si_iscoreup(sih);
+ if (!wasup)
+ si_core_reset(sih, 0, 0);
+ corerev = si_corerev(sih);
+ coreinfo = R_REG(sii->osh, &regs->coreinfo);
+
+ /* Calculate size from coreinfo based on rev */
+ if (corerev == 0)
+ memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
+ else if (corerev < 3) {
+ memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
+ memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ } else if ((corerev <= 7) || (corerev == 12)) {
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
+ uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
+ if (lss != 0)
+ nb--;
+ memsize = nb * (1 << (bsz + SR_BSZ_BASE));
+ if (lss != 0)
+ memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
+ } else {
+ uint8 i;
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ for (i = 0; i < nb; i++)
+ memsize +=
+ socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+ done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+void si_chipcontrl_epa4331(si_t *sih, bool on)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+
+ val = R_REG(sii->osh, &cc->chipcontrol);
+
+ if (on) {
+ if (sih->chippkg == 9 || sih->chippkg == 0xb) {
+ /* Ext PA Controls for 4331 12x9 Package */
+ W_REG(sii->osh, &cc->chipcontrol, val |
+ (CCTRL4331_EXTPA_EN |
+ CCTRL4331_EXTPA_ON_GPIO2_5));
+ } else {
+ /* Ext PA Controls for 4331 12x12 Package */
+ W_REG(sii->osh, &cc->chipcontrol,
+ val | (CCTRL4331_EXTPA_EN));
+ }
+ } else {
+ val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ }
+
+ si_setcoreidx(sih, origidx);
+}
+
+/* Enable BT-COEX & Ex-PA for 4313 */
+void si_epa_4313war(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
+
+ /* EPA Fix */
+ W_REG(sii->osh, &cc->gpiocontrol,
+ R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
+
+ si_setcoreidx(sih, origidx);
+}
+
+/* check if the device is removed */
+bool si_deviceremoved(si_t *sih)
+{
+ uint32 w;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ switch (BUSTYPE(sih->bustype)) {
+ case PCI_BUS:
+ ASSERT(sii->osh != NULL);
+ w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
+ if ((w & 0xFFFF) != VENDOR_BROADCOM)
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+bool si_is_sprom_available(si_t *sih)
+{
+ if (sih->ccrev >= 31) {
+ si_info_t *sii;
+ uint origidx;
+ chipcregs_t *cc;
+ uint32 sromctrl;
+
+ if ((sih->cccaps & CC_CAP_SROM) == 0)
+ return FALSE;
+
+ sii = SI_INFO(sih);
+ origidx = sii->curidx;
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ sromctrl = R_REG(sii->osh, &cc->sromcontrol);
+ si_setcoreidx(sih, origidx);
+ return sromctrl & SRC_PRESENT;
+ }
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ return (sih->chipst & CST4329_SPROM_SEL) != 0;
+ case BCM4319_CHIP_ID:
+ return (sih->chipst & CST4319_SPROM_SEL) != 0;
+ case BCM4336_CHIP_ID:
+ return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+ case BCM4330_CHIP_ID:
+ return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+ case BCM4313_CHIP_ID:
+ return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+ case BCM4331_CHIP_ID:
+ return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
+ default:
+ return TRUE;
+ }
+}
+
+bool si_is_otp_disabled(si_t *sih)
+{
+ switch (CHIPID(sih->chip)) {
+ case BCM4329_CHIP_ID:
+ return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
+ CST4329_OTP_PWRDN;
+ case BCM4319_CHIP_ID:
+ return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
+ CST4319_OTP_PWRDN;
+ case BCM4336_CHIP_ID:
+ return (sih->chipst & CST4336_OTP_PRESENT) == 0;
+ case BCM4330_CHIP_ID:
+ return (sih->chipst & CST4330_OTP_PRESENT) == 0;
+ case BCM4313_CHIP_ID:
+ return (sih->chipst & CST4313_OTP_PRESENT) == 0;
+ /* These chips always have their OTP on */
+ case BCM43224_CHIP_ID:
+ case BCM43225_CHIP_ID:
+ case BCM43421_CHIP_ID:
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:
+ case BCM4331_CHIP_ID:
+ default:
+ return FALSE;
+ }
+}
+
+bool si_is_otp_powered(si_t *sih)
+{
+ if (PMUCTL_ENAB(sih))
+ return si_pmu_is_otp_powered(sih, si_osh(sih));
+ return TRUE;
+}
+
+void si_otp_power(si_t *sih, bool on)
+{
+ if (PMUCTL_ENAB(sih))
+ si_pmu_otp_power(sih, si_osh(sih), on);
+ OSL_DELAY(1000);
+}
+
+bool
+#if defined(BCMDBG)
+si_is_sprom_enabled(si_t *sih)
+#else
+BCMATTACHFN(si_is_sprom_enabled) (si_t *sih)
+#endif
+{
+
+ return TRUE;
+}
+
+void
+#if defined(BCMDBG)
+si_sprom_enable(si_t *sih, bool enable)
+#else
+BCMATTACHFN(si_sprom_enable) (si_t *sih, bool enable)
+#endif
+{
+ if (PMUCTL_ENAB(sih))
+ si_pmu_sprom_enable(sih, si_osh(sih), enable);
+}
+
+/* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
+int si_cis_source(si_t *sih)
+{
+ /* Many chips have the same mapping of their chipstatus field */
+ static const uint cis_sel[] = {
+ CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_SROM };
+ static const uint cis_43236_sel[] = {
+ CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_OTP };
+
+ /* PCI chips use SROM format instead of CIS */
+ if (BUSTYPE(sih->bustype) == PCI_BUS)
+ return BCME_NOTFOUND;
+
+ switch (CHIPID(sih->chip)) {
+ case BCM43235_CHIP_ID:
+ case BCM43236_CHIP_ID:
+ case BCM43238_CHIP_ID:{
+ uint8 strap =
+ (sih->
+ chipst & CST4322_SPROM_OTP_SEL_MASK) >>
+ CST4322_SPROM_OTP_SEL_SHIFT;
+ return ((strap >=
+ sizeof(cis_sel)) ? CIS_DEFAULT :
+ cis_43236_sel[strap]);
+ }
+
+ case BCM4329_CHIP_ID:
+ return ((sih->chipst & CST4329_SPROM_OTP_SEL_MASK) >=
+ sizeof(cis_sel)) ? CIS_DEFAULT : cis_sel[(sih->
+ chipst &
+ CST4329_SPROM_OTP_SEL_MASK)];
+ case BCM4319_CHIP_ID:{
+ uint cis_sel4319 =
+ ((sih->
+ chipst & CST4319_SPROM_OTP_SEL_MASK) >>
+ CST4319_SPROM_OTP_SEL_SHIFT);
+ return (cis_sel4319 >=
+ sizeof(cis_sel)) ? CIS_DEFAULT :
+ cis_sel[cis_sel4319];
+ }
+ case BCM4336_CHIP_ID:{
+ if (sih->chipst & CST4336_SPROM_PRESENT)
+ return CIS_SROM;
+ if (sih->chipst & CST4336_OTP_PRESENT)
+ return CIS_OTP;
+ return CIS_DEFAULT;
+ }
+ case BCM4330_CHIP_ID:{
+ if (sih->chipst & CST4330_SPROM_PRESENT)
+ return CIS_SROM;
+ if (sih->chipst & CST4330_OTP_PRESENT)
+ return CIS_OTP;
+ return CIS_DEFAULT;
+ }
+ default:
+ return CIS_DEFAULT;
+ }
+}
diff --git a/drivers/staging/brcm80211/util/siutils_priv.h b/drivers/staging/brcm80211/util/siutils_priv.h
new file mode 100644
index 000000000000..51b8803c9ce1
--- /dev/null
+++ b/drivers/staging/brcm80211/util/siutils_priv.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 _siutils_priv_h_
+#define _siutils_priv_h_
+
+/* Silicon Backplane externs */
+extern void sb_scan(si_t *sih, void *regs, uint devid);
+uint sb_coreid(si_t *sih);
+uint sb_corerev(si_t *sih);
+extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+ uint val);
+extern bool sb_iscoreup(si_t *sih);
+void *sb_setcoreidx(si_t *sih, uint coreidx);
+extern uint32 sb_base(uint32 admatch);
+extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void sb_core_disable(si_t *sih, uint32 bits);
+extern bool sb_taclear(si_t *sih, bool details);
+#endif /* _siutils_priv_h_ */
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 14091313cebb..aeb26ee587b6 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -537,7 +537,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
x = (dev->minor << 28) | (it.subdev << 24) | (i << 16) |
(s->range_table_list[i]->length);
- put_user(x, it.rangelist + i);
+ if (put_user(x, it.rangelist + i))
+ return -EFAULT;
}
#if 0
if (copy_to_user(it.rangelist, s->range_type_list,
@@ -1922,6 +1923,7 @@ const struct file_operations comedi_fops = {
.mmap = comedi_mmap,
.poll = comedi_poll,
.fasync = comedi_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct class *comedi_class;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
index d7d768ee7c23..7bd931c07877 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -1,4 +1,4 @@
-//**
+/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
@@ -33,7 +33,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-1710 |
+ | Description : Hardware Layer Access For APCI-1710 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 1369e22b7ee6..cf63db6f13aa 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-035 |
+ | Description : Hardware Layer Access For APCI-035 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
index faea003e16c7..fdcbdd8cd9f3 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-1032 |
+ | Description : Hardware Layer Access For APCI-1032 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index b3b921853e60..ab492fb23862 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-1500 |
+ | Description : Hardware Layer Access For APCI-1500 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
index 7948c41f60f5..9f93bc349319 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-1516 |
+ | Description : Hardware Layer Access For APCI-1516 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 4299ff5214dd..a264fff8a24d 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-1564 |
+ | Description : Hardware Layer Access For APCI-1564 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
index 89783b1eb0bd..1baf2bfc53b9 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-2016 |
+ | Description : Hardware Layer Access For APCI-2016 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
index d7d22236778d..fd135a5b91dd 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-2032 |
+ | Description : Hardware Layer Access For APCI-2032 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
index e01889c3c4fc..2726d66ae01e 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-2200 |
+ | Description : Hardware Layer Access For APCI-2200 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 560c848f6258..86e88edd7a8d 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-3200 |
+ | Description : Hardware Layer Access For APCI-3200 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index 4ed441a1adc8..b9e1adaf6fa6 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -34,7 +34,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
- | Description : Hardware Layer Acces For APCI-3501 |
+ | Description : Hardware Layer Access For APCI-3501 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 073d0242c28e..4fc9e8520217 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -90,9 +90,8 @@ static const struct pci6208_board pci6208_boards[] = {
static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = {
/* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
/* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
- {
- PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index b2a02b0f569a..18103b68769c 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -1,26 +1,26 @@
/*
- comedi/drivers/adl_pci9111.c
+comedi/drivers/adl_pci9111.c
- Hardware driver for PCI9111 ADLink cards:
+Hardware driver for PCI9111 ADLink cards:
- PCI-9111HR
+PCI-9111HR
- Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
- 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.
- 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 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.
+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.
*/
/*
@@ -32,46 +32,46 @@ Status: experimental
Supports:
- - ai_insn read
- - ao_insn read/write
- - di_insn read
- - do_insn read/write
- - ai_do_cmd mode with the following sources:
+ - ai_insn read
+ - ao_insn read/write
+ - di_insn read
+ - do_insn read/write
+ - ai_do_cmd mode with the following sources:
- - start_src TRIG_NOW
- - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
- - convert_src TRIG_TIMER TRIG_EXT
- - scan_end_src TRIG_COUNT
- - stop_src TRIG_COUNT TRIG_NONE
+ - start_src TRIG_NOW
+ - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
+ - convert_src TRIG_TIMER TRIG_EXT
+ - scan_end_src TRIG_COUNT
+ - stop_src TRIG_COUNT TRIG_NONE
- The scanned channels must be consecutive and start from 0. They must
- all have the same range and aref.
+The scanned channels must be consecutive and start from 0. They must
+all have the same range and aref.
Configuration options:
- [0] - PCI bus number (optional)
- [1] - PCI slot number (optional)
+ [0] - PCI bus number (optional)
+ [1] - PCI slot number (optional)
- If bus/slot is not specified, the first available PCI
- device will be used.
+If bus/slot is not specified, the first available PCI
+device will be used.
*/
/*
CHANGELOG:
- 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
- a multiple of chanlist_len*convert_arg.
- 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
- 2002/02/18 Added external trigger support for analog input.
+2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
+a multiple of chanlist_len*convert_arg.
+2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
+2002/02/18 Added external trigger support for analog input.
TODO:
- - Really test implemented functionality.
- - Add support for the PCI-9111DG with a probe routine to identify the card
- type (perhaps with the help of the channel number readback of the A/D Data
- register).
- - Add external multiplexer support.
+ - Really test implemented functionality.
+ - Add support for the PCI-9111DG with a probe routine to identify
+ the card type (perhaps with the help of the channel number readback
+ of the A/D Data register).
+ - Add external multiplexer support.
*/
@@ -187,95 +187,107 @@ TODO:
*/
#define pci9111_trigger_and_autoscan_get() \
- (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
+ (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
#define pci9111_trigger_and_autoscan_set(flags) \
- outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
+ outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
-#define pci9111_interrupt_and_fifo_get() \
- ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) \
- &0x03)
+#define pci9111_interrupt_and_fifo_get() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \
+ >> 4) & 0x03)
#define pci9111_interrupt_and_fifo_set(flags) \
- outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+ outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
#define pci9111_interrupt_clear() \
- outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
+ outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
#define pci9111_software_trigger() \
- outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
+ outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
-#define pci9111_fifo_reset() do { \
- outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
- PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
- outb(PCI9111_FFEN_SET_FIFO_DISABLE, \
- PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
- outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
- PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
- } while (0)
+#define pci9111_fifo_reset() do { \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_DISABLE, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ } while (0)
#define pci9111_is_fifo_full() \
- ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
- PCI9111_FIFO_FULL_MASK) == 0)
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_FULL_MASK) == 0)
#define pci9111_is_fifo_half_full() \
- ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
- PCI9111_FIFO_HALF_FULL_MASK) == 0)
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_HALF_FULL_MASK) == 0)
#define pci9111_is_fifo_empty() \
- ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
- PCI9111_FIFO_EMPTY_MASK) == 0)
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_EMPTY_MASK) == 0)
-#define pci9111_ai_channel_set(channel) \
- outb((channel)&PCI9111_CHANNEL_MASK, \
- PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+#define pci9111_ai_channel_set(channel) \
+ outb((channel)&PCI9111_CHANNEL_MASK, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
-#define pci9111_ai_channel_get() \
- (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK) \
- &PCI9111_CHANNEL_MASK)
+#define pci9111_ai_channel_get() \
+ (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK) \
+ &PCI9111_CHANNEL_MASK)
-#define pci9111_ai_range_set(range) \
- outb((range)&PCI9111_RANGE_MASK, \
- PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+#define pci9111_ai_range_set(range) \
+ outb((range)&PCI9111_RANGE_MASK, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
-#define pci9111_ai_range_get() \
- (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK) \
- &PCI9111_RANGE_MASK)
+#define pci9111_ai_range_get() \
+ (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK) \
+ &PCI9111_RANGE_MASK)
-#define pci9111_ai_get_data() \
- (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \
- &PCI9111_AI_RESOLUTION_MASK) \
- ^ PCI9111_AI_RESOLUTION_2_CMP_BIT)
+#define pci9111_ai_get_data() \
+ (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \
+ &PCI9111_AI_RESOLUTION_MASK) \
+ ^ PCI9111_AI_RESOLUTION_2_CMP_BIT)
-#define pci9111_hr_ai_get_data() \
- ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) \
- & PCI9111_HR_AI_RESOLUTION_MASK) \
- ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT)
+#define pci9111_hr_ai_get_data() \
+ ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) \
+ &PCI9111_HR_AI_RESOLUTION_MASK) \
+ ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT)
-#define pci9111_ao_set_data(data) \
- outw(data&PCI9111_AO_RESOLUTION_MASK, \
- PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+#define pci9111_ao_set_data(data) \
+ outw(data&PCI9111_AO_RESOLUTION_MASK, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
#define pci9111_di_get_bits() \
- inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+ inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
#define pci9111_do_set_bits(bits) \
- outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+ outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
#define pci9111_8254_control_set(flags) \
- outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
+ outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
#define pci9111_8254_counter_0_set(data) \
- outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
- outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0)
+ do { \
+ outb(data & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
+ outb((data >> 8) & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
+ } while (0)
#define pci9111_8254_counter_1_set(data) \
- outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
- outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1)
+ do { \
+ outb(data & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
+ outb((data >> 8) & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
+ } while (0)
#define pci9111_8254_counter_2_set(data) \
- outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
- outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2)
+ do { \
+ outb(data & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
+ outb((data >> 8) & 0xFF, \
+ PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
+ } while (0)
/* Function prototypes */
@@ -342,7 +354,7 @@ static const struct pci9111_board pci9111_boards[] = {
};
#define pci9111_board_nbr \
- (sizeof(pci9111_boards)/sizeof(struct pci9111_board))
+ (sizeof(pci9111_boards)/sizeof(struct pci9111_board))
static struct comedi_driver pci9111_driver = {
.driver_name = PCI9111_DRIVER_NAME,
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index b0e39cb74774..cb2843d34bea 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -252,9 +252,8 @@ struct boardtype {
};
static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
- {
- PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
@@ -635,7 +634,7 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev,
/*
==============================================================================
*/
-static unsigned int move_block_from_dma(struct comedi_device *dev,
+static int move_block_from_dma(struct comedi_device *dev,
struct comedi_subdevice *s,
short *dma_buffer,
unsigned int num_samples)
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index bdd6954cad96..466e69f94ef2 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -217,13 +217,12 @@ struct boardtype {
};
static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
- {
- PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pci1710_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index b133bb84c4fe..1b5682104a08 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -155,9 +155,8 @@ static const struct pci1723_board boardtypes[] = {
* Should only be used for PCI and ISA-PnP devices
*/
static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = {
- {
- PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index d018bb4e2890..9102667ab40e 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -256,21 +256,20 @@ struct dio_boardtype {
};
static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
- {
- PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1735, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1730) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1733) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1753) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1754) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1756) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1762) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
index 1728cc013d16..b0f98e5e4bf3 100644
--- a/drivers/staging/comedi/drivers/aio_aio12_8.c
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -2,7 +2,7 @@
comedi/drivers/aio_aio12_8.c
- Driver for Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+ Driver for Access I/O Products PC-104 AIO12-8 Analog I/O Board
Copyright (C) 2006 C&C Technologies, Inc.
This program is free software; you can redistribute it and/or modify
@@ -23,10 +23,10 @@
/*
Driver: aio_aio12_8
-Description: Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+Description: Access I/O Products PC-104 AIO12-8 Analog I/O Board
Author: Pablo Mejia <pablo.mejia@cctechnol.com>
Devices:
- [Acces I/O] PC-104 AIO12-8
+ [Access I/O] PC-104 AIO12-8
Status: experimental
Configuration Options:
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 487599531fed..160b0a0f4f1e 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -2,7 +2,7 @@
comedi/drivers/aio_iiro_16.c
- Driver for Acces I/O Products PC-104 AIO-IIRO-16 Digital I/O board
+ Driver for Access I/O Products PC-104 AIO-IIRO-16 Digital I/O board
Copyright (C) 2006 C&C Technologies, Inc.
This program is free software; you can redistribute it and/or modify
@@ -23,10 +23,10 @@
/*
Driver: aio_iiro_16
-Description: Acces I/O Products PC-104 IIRO16 Relay And Isolated Input Board
+Description: Access I/O Products PC-104 IIRO16 Relay And Isolated Input Board
Author: Zachary Ware <zach.ware@cctechnol.com>
Devices:
- [Acces I/O] PC-104 AIO12-8
+ [Access I/O] PC-104 AIO12-8
Status: experimental
Configuration Options:
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 6530b6c9d98b..3275fc50615f 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -377,16 +377,15 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
};
static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
- {
- PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 53e7015869fc..9b1dd3cc2120 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -1028,46 +1028,26 @@ static const struct pcidas64_board pcidas64_boards[] = {
};
static DEFINE_PCI_DEVICE_TABLE(pcidas64_pci_table) = {
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) },
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pcidas64_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 2d35143b8e52..6383fc93b83d 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -196,14 +196,13 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = {
};
static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
- {
- PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index c1693c91a6d0..79477a595ef9 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -91,11 +91,10 @@ static const struct pcidio_board pcidio_boards[] = {
/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
* upstream. */
static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = {
- {
- PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index ced346a7cae3..16c322d040fd 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -126,10 +126,8 @@ static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
/* This is used by modprobe to translate PCI IDs to drivers. Should
* only be used for PCI and ISA-PnP devices */
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
- {
- PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index c6aa52f8dcee..48d9fb1227df 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -222,7 +222,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
index 651fe050d029..99c1584153d7 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -82,13 +82,13 @@ static int dt2817_dio_insn_config(struct comedi_device *dev,
return -EINVAL;
chan = CR_CHAN(insn->chanspec);
- if (chan < 8) {
+ if (chan < 8)
mask = 0xff;
- } else if (chan < 16) {
+ else if (chan < 16)
mask = 0xff00;
- } else if (chan < 24) {
+ else if (chan < 24)
mask = 0xff0000;
- } else
+ else
mask = 0xff000000;
if (data[0])
s->io_bits |= mask;
@@ -152,7 +152,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
unsigned long iobase;
iobase = it->options[0];
- printk("comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
+ printk(KERN_INFO "comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
if (!request_region(iobase, DT2817_SIZE, "dt2817")) {
printk("I/O port conflict\n");
return -EIO;
@@ -177,14 +177,14 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->state = 0;
outb(0, dev->iobase + DT2817_CR);
- printk("\n");
+ printk(KERN_INFO "\n");
return 0;
}
static int dt2817_detach(struct comedi_device *dev)
{
- printk("comedi%d: dt2817: remove\n", dev->minor);
+ printk(KERN_INFO "comedi%d: dt2817: remove\n", dev->minor);
if (dev->iobase)
release_region(dev->iobase, DT2817_SIZE);
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 656e7bbf2fcb..6170f7bac46e 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -165,15 +165,14 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = {
- {
- PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) },
+ { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, dt3k_pci_table);
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index d01d2dc79112..0560a7451512 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -1128,7 +1128,7 @@ static int __init usb_dt9812_init(void)
/* Initialize all driver slots */
for (i = 0; i < DT9812_NUM_SLOTS; i++) {
- init_MUTEX(&dt9812[i].mutex);
+ sema_init(&dt9812[i].mutex, 1);
dt9812[i].serial = 0;
dt9812[i].usb = NULL;
dt9812[i].comedi = NULL;
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 14713849564d..e6825c2569a5 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -71,21 +71,20 @@ broken.
===========================================================================*/
static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
- {
- PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, me4000_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 3acf7e62bec4..19f79e8c497a 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -250,7 +250,7 @@ static unsigned int labpc_serial_in(struct comedi_device *dev);
static unsigned int labpc_eeprom_read(struct comedi_device *dev,
unsigned int address);
static unsigned int labpc_eeprom_read_status(struct comedi_device *dev);
-static unsigned int labpc_eeprom_write(struct comedi_device *dev,
+static int labpc_eeprom_write(struct comedi_device *dev,
unsigned int address,
unsigned int value);
static void write_caldac(struct comedi_device *dev, unsigned int channel,
@@ -1986,8 +1986,8 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
return value;
}
-static unsigned int labpc_eeprom_write(struct comedi_device *dev,
- unsigned int address, unsigned int value)
+static int labpc_eeprom_write(struct comedi_device *dev,
+ unsigned int address, unsigned int value)
{
const int write_enable_instruction = 0x6;
const int write_instruction = 0x2;
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 0367d2b9e2fa..5858d97fcd05 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -329,10 +329,9 @@ static const struct rtdBoard rtd520Boards[] = {
};
static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
- {
- PCI_VENDOR_ID_RTD, 0x7520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_RTD, 0x4520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) },
+ { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index 0b9ecb19511e..ed69008f0d39 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -116,10 +116,9 @@ static const struct skel_board skel_boards[] = {
* upstream. */
#define PCI_VENDOR_ID_SKEL 0xdafe
static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
- {
- PCI_VENDOR_ID_SKEL, 0x0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- PCI_VENDOR_ID_SKEL, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
- 0}
+ { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, skel_pci_table);
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c
index fbb80f09a3d9..51a6876460e2 100644
--- a/drivers/staging/crystalhd/crystalhd_lnx.c
+++ b/drivers/staging/crystalhd/crystalhd_lnx.c
@@ -351,6 +351,7 @@ static const struct file_operations chd_dec_fops = {
.unlocked_ioctl = chd_dec_ioctl,
.open = chd_dec_open,
.release = chd_dec_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
@@ -570,6 +571,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
rc = chd_pci_reserve_mem(pinfo);
if (rc) {
BCMLOG_ERR("Failed to setup memory regions.\n");
+ pci_disable_device(pdev);
return -ENOMEM;
}
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index bbe36437ac16..2a01dc057b2c 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -629,7 +629,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
* Only boards with eeprom and byte 1 at eeprom=1 have it
*/
-static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
+static const struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
{0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0,}
};
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index cdff49f409f2..27087dbe5b7d 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -40,8 +40,7 @@ MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
MODULE_LICENSE("GPL");
static int _intr_msk =
- FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC |
- FLD_AUD_SRC_OPC_ERR;
+FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR;
int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
struct sram_channel *ch,
@@ -506,7 +505,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
{
int i = 0;
u32 int_msk_tmp;
- struct sram_channel *channel = dev->channels[chan_num].sram_channels;
+ struct sram_channel *channel = dev->channels[chan_num].sram_channels;
dma_addr_t risc_phys_jump_addr;
__le32 *rp;
@@ -608,8 +607,8 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
if (!dev)
return -1;
- sram_ch = dev->channels[dev->_audio_upstream_channel_select].
- sram_channels;
+ sram_ch = dev->channels[dev->_audio_upstream_channel_select].
+ sram_channels;
msk_stat = cx_read(sram_ch->int_mstat);
audio_status = cx_read(sram_ch->int_stat);
@@ -733,7 +732,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
}
dev->_audio_upstream_channel_select = channel_select;
- sram_ch = dev->channels[channel_select].sram_channels;
+ sram_ch = dev->channels[channel_select].sram_channels;
/* Work queue */
INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
@@ -764,9 +763,9 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
str_length + 1);
/* Default if filename is empty string */
- if (strcmp(dev->input_audiofilename, "") == 0) {
+ if (strcmp(dev->input_audiofilename, "") == 0)
dev->_audiofilename = "/root/audioGOOD.wav";
- }
+
} else {
str_length = strlen(_defaultAudioName);
dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL);
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
index 434b2a312a80..aa5725b09328 100644
--- a/drivers/staging/cx25821/cx25821-audio.h
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -31,18 +31,21 @@
#define NUMBER_OF_PROGRAMS 8
/*
- Max size of the RISC program for a buffer. - worst case is 2 writes per line
- Space is also added for the 4 no-op instructions added on the end.
+* Max size of the RISC program for a buffer. - worst case is 2 writes per line
+* Space is also added for the 4 no-op instructions added on the end.
*/
#ifndef USE_RISC_NOOP
-#define MAX_BUFFER_PROGRAM_SIZE \
- (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
+#define MAX_BUFFER_PROGRAM_SIZE \
+(2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + \
+ RISC_WRITECR_INSTRUCTION_SIZE*4)
+
#endif
/* MAE 12 July 2005 Try to use NOOP RISC instruction instead */
#ifdef USE_RISC_NOOP
#define MAX_BUFFER_PROGRAM_SIZE \
- (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
+(2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4l)
+
#endif
/* Sizes of various instructions in bytes. Used when adding instructions. */
@@ -53,6 +56,7 @@
#define RISC_WRITECR_INSTRUCTION_SIZE 16
#define RISC_NOOP_INSTRUCTION_SIZE 4
-#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
+#define MAX_AUDIO_DMA_BUFFER_SIZE \
+(MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
#endif
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index c487c19256b9..ad7ce013ba50 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -962,7 +962,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->pci->subsystem_device);
cx25821_devcount--;
- return -ENODEV;
+ return -EBUSY;
}
/* PCIe stuff */
@@ -1412,9 +1412,12 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
printk(KERN_INFO "cx25821 Athena pci enable !\n");
- if (cx25821_dev_setup(dev) < 0) {
- err = -EINVAL;
- goto fail_unregister_device;
+ err = cx25821_dev_setup(dev);
+ if (err) {
+ if (err == -EBUSY)
+ goto fail_unregister_device;
+ else
+ goto fail_unregister_pci;
}
/* print pci info */
@@ -1448,6 +1451,8 @@ fail_irq:
printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ !\n");
cx25821_dev_unregister(dev);
+fail_unregister_pci:
+ pci_disable_device(pci_dev);
fail_unregister_device:
v4l2_device_unregister(&dev->v4l2_dev);
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 1d5e8796d383..6fff985358a6 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -993,6 +993,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
{
struct cx25821_fh *fh = priv;
struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+ struct v4l2_mbus_framefmt mbus_fmt;
int err;
int pix_format = PIXEL_FRMT_422;
@@ -1039,7 +1040,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
+ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
+ cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
return 0;
}
diff --git a/drivers/staging/cxt1e1/Kconfig b/drivers/staging/cxt1e1/Kconfig
index 68e9b6d973f7..73430ef6ae2b 100644
--- a/drivers/staging/cxt1e1/Kconfig
+++ b/drivers/staging/cxt1e1/Kconfig
@@ -18,5 +18,5 @@ config SBE_PMCC4_NCOMM
---help---
SBE supplies optional support for NCOMM products.
- If you have purchased this optional support you must say Y or M
+ If you have purchased this optional support you must say Y
here to allow the driver to operate with the NCOMM product.
diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c
index 23ea101d7a89..ab399c2f7488 100644
--- a/drivers/staging/cxt1e1/functions.c
+++ b/drivers/staging/cxt1e1/functions.c
@@ -184,10 +184,10 @@ OS_sem_init (void *sem, int state)
switch (state)
{
case SEM_TAKEN:
- init_MUTEX_LOCKED ((struct semaphore *) sem);
+ sema_init((struct semaphore *) sem, 0);
break;
case SEM_AVAILABLE:
- init_MUTEX ((struct semaphore *) sem);
+ sema_init((struct semaphore *) sem, 1);
break;
default: /* otherwise, set sem.count to state's
* value */
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
index 81bd71fd816e..8483a71753e1 100644
--- a/drivers/staging/dream/camera/msm_camera.c
+++ b/drivers/staging/dream/camera/msm_camera.c
@@ -1941,6 +1941,7 @@ static const struct file_operations msm_fops_config = {
.open = msm_open,
.unlocked_ioctl = msm_ioctl_config,
.release = msm_release_config,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static const struct file_operations msm_fops_control = {
@@ -1948,6 +1949,7 @@ static const struct file_operations msm_fops_control = {
.open = msm_open_control,
.unlocked_ioctl = msm_ioctl_control,
.release = msm_release_control,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static const struct file_operations msm_fops_frame = {
@@ -1956,6 +1958,7 @@ static const struct file_operations msm_fops_frame = {
.unlocked_ioctl = msm_ioctl_frame,
.release = msm_release_frame,
.poll = msm_poll_frame,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int msm_setup_cdev(struct msm_device *msm,
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
index 7d6bbadd7fc7..b72d2a251d81 100644
--- a/drivers/staging/dream/pmem.c
+++ b/drivers/staging/dream/pmem.c
@@ -180,6 +180,7 @@ const struct file_operations pmem_fops = {
.mmap = pmem_mmap,
.open = pmem_open,
.unlocked_ioctl = pmem_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
static int get_id(struct file *file)
@@ -1204,6 +1205,7 @@ static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
static struct file_operations debug_fops = {
.read = debug_read,
.open = debug_open,
+ .llseek = default_llseek,/* read accesses f_pos */
};
#endif
@@ -1231,7 +1233,7 @@ int pmem_setup(struct android_pmem_platform_data *pdata,
pmem[id].ioctl = ioctl;
pmem[id].release = release;
init_rwsem(&pmem[id].bitmap_sem);
- init_MUTEX(&pmem[id].data_list_sem);
+ sema_init(&pmem[id].data_list_sem, 1);
INIT_LIST_HEAD(&pmem[id].data_list);
pmem[id].dev.name = pdata->name;
pmem[id].dev.minor = id;
diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c
index 8197765aae1e..99a86b674b04 100644
--- a/drivers/staging/dream/qdsp5/adsp_driver.c
+++ b/drivers/staging/dream/qdsp5/adsp_driver.c
@@ -582,6 +582,7 @@ static struct file_operations adsp_fops = {
.open = adsp_open,
.unlocked_ioctl = adsp_ioctl,
.release = adsp_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static void adsp_create(struct adsp_device *adev, const char *name,
diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c
index a373f3522384..912288836f75 100644
--- a/drivers/staging/dream/qdsp5/audio_aac.c
+++ b/drivers/staging/dream/qdsp5/audio_aac.c
@@ -1030,6 +1030,7 @@ static struct file_operations audio_aac_fops = {
.read = audio_read,
.write = audio_write,
.unlocked_ioctl = audio_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct miscdevice audio_aac_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c
index 07b79d5836e5..7c1c7134c7e6 100644
--- a/drivers/staging/dream/qdsp5/audio_amrnb.c
+++ b/drivers/staging/dream/qdsp5/audio_amrnb.c
@@ -841,6 +841,7 @@ static struct file_operations audio_amrnb_fops = {
.read = audamrnb_read,
.write = audamrnb_write,
.unlocked_ioctl = audamrnb_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct miscdevice audio_amrnb_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c
index ad989ee87690..687aec082798 100644
--- a/drivers/staging/dream/qdsp5/audio_evrc.c
+++ b/drivers/staging/dream/qdsp5/audio_evrc.c
@@ -813,6 +813,7 @@ static struct file_operations audio_evrc_fops = {
.read = audevrc_read,
.write = audevrc_write,
.unlocked_ioctl = audevrc_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct miscdevice audio_evrc_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c
index 6ae48e72d145..ad68c7d108fa 100644
--- a/drivers/staging/dream/qdsp5/audio_in.c
+++ b/drivers/staging/dream/qdsp5/audio_in.c
@@ -921,12 +921,14 @@ static struct file_operations audio_fops = {
.read = audio_in_read,
.write = audio_in_write,
.unlocked_ioctl = audio_in_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct file_operations audpre_fops = {
.owner = THIS_MODULE,
.open = audpre_open,
.unlocked_ioctl = audpre_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
struct miscdevice audio_in_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
index 530e1f35eed3..633e6ae91c88 100644
--- a/drivers/staging/dream/qdsp5/audio_mp3.c
+++ b/drivers/staging/dream/qdsp5/audio_mp3.c
@@ -948,6 +948,7 @@ static struct file_operations audio_mp3_fops = {
.read = audio_read,
.write = audio_write,
.unlocked_ioctl = audio_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct miscdevice audio_mp3_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
index 76d7fa5667d5..9c2e11bddd82 100644
--- a/drivers/staging/dream/qdsp5/audio_out.c
+++ b/drivers/staging/dream/qdsp5/audio_out.c
@@ -807,12 +807,14 @@ static struct file_operations audio_fops = {
.read = audio_read,
.write = audio_write,
.unlocked_ioctl = audio_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct file_operations audpp_fops = {
.owner = THIS_MODULE,
.open = audpp_open,
.unlocked_ioctl = audpp_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
struct miscdevice audio_misc = {
diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c
index effa96f34fdc..fac03cafe510 100644
--- a/drivers/staging/dream/qdsp5/audio_qcelp.c
+++ b/drivers/staging/dream/qdsp5/audio_qcelp.c
@@ -824,6 +824,7 @@ static struct file_operations audio_qcelp_fops = {
.read = audqcelp_read,
.write = audqcelp_write,
.unlocked_ioctl = audqcelp_ioctl,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
struct miscdevice audio_qcelp_misc = {
diff --git a/drivers/staging/dream/qdsp5/evlog.h b/drivers/staging/dream/qdsp5/evlog.h
index 922ce670a32a..37cca4039ac8 100644
--- a/drivers/staging/dream/qdsp5/evlog.h
+++ b/drivers/staging/dream/qdsp5/evlog.h
@@ -123,6 +123,7 @@ static int ev_log_open(struct inode *inode, struct file *file)
static const struct file_operations ev_log_ops = {
.read = ev_log_read,
.open = ev_log_open,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int ev_log_init(struct ev_log *log)
diff --git a/drivers/staging/dream/qdsp5/snd.c b/drivers/staging/dream/qdsp5/snd.c
index 037d7ffb7e67..4b0625bdae66 100644
--- a/drivers/staging/dream/qdsp5/snd.c
+++ b/drivers/staging/dream/qdsp5/snd.c
@@ -247,6 +247,7 @@ static struct file_operations snd_fops = {
.open = snd_open,
.release = snd_release,
.unlocked_ioctl = snd_ioctl,
+ .llseek = noop_llseek,/* no read or write fn */
};
struct miscdevice snd_misc = {
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 47baab3e6ea8..10bcb45d73a3 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -726,7 +726,7 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev,
/* Initialize link state */
et131x_link_detection_handler((unsigned long)adapter);
- /* Intialize variable for counting how long we do not have
+ /* Initialize variable for counting how long we do not have
link status */
adapter->PoMgmt.TransPhyComaModeOnBoot = 0;
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 4e52105e6070..9bf71d0e0546 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -641,6 +641,7 @@ static const struct file_operations usb_alphatrack_fops = {
.open = usb_alphatrack_open,
.release = usb_alphatrack_release,
.poll = usb_alphatrack_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*
@@ -671,7 +672,7 @@ static int usb_alphatrack_probe(struct usb_interface *intf,
int true_size;
int retval = -ENOMEM;
- /* allocate memory for our device state and intialize it */
+ /* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index eed74f0fe0b6..3fe4cb4464b8 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -767,6 +767,7 @@ static const struct file_operations usb_tranzport_fops = {
.open = usb_tranzport_open,
.release = usb_tranzport_release,
.poll = usb_tranzport_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*
@@ -795,7 +796,7 @@ static int usb_tranzport_probe(struct usb_interface *intf,
int true_size;
int retval = -ENOMEM;
- /* allocate memory for our device state and intialize it */
+ /* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 46b4b9f6855b..2b27d8da70a2 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -252,23 +252,22 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
go->modet_map[i] = 0;
if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
- struct v4l2_format res;
+ struct v4l2_mbus_framefmt mbus_fmt;
- if (fmt != NULL) {
- res = *fmt;
- } else {
- res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- res.fmt.pix.width = width;
- }
+ mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
+ if (fmt != NULL)
+ mbus_fmt.width = fmt->fmt.pix.width;
+ else
+ mbus_fmt.width = width;
if (height > sensor_height / 2) {
- res.fmt.pix.height = height / 2;
+ mbus_fmt.height = height / 2;
go->encoder_v_halve = 0;
} else {
- res.fmt.pix.height = height;
+ mbus_fmt.height = height;
go->encoder_v_halve = 1;
}
- call_all(&go->v4l2_dev, video, s_fmt, &res);
+ call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
} else {
if (width <= sensor_width / 4) {
go->encoder_h_halve = 1;
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 93f26048e3b4..db8ac51279f9 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -479,12 +479,13 @@ static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-static int s2250_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
{
struct s2250 *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (fmt->fmt.pix.height < 640) {
+ if (fmt->height < 640) {
write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
write_reg_fp(client, 0x140, 0x060);
} else {
@@ -555,7 +556,7 @@ static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
static const struct v4l2_subdev_video_ops s2250_video_ops = {
.s_routing = s2250_s_video_routing,
- .s_fmt = s2250_s_fmt,
+ .s_mbus_fmt = s2250_s_mbus_fmt,
};
static const struct v4l2_subdev_ops s2250_ops = {
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
index 66a89c809dd3..582fd4ab3f1e 100644
--- a/drivers/staging/hv/TODO
+++ b/drivers/staging/hv/TODO
@@ -2,8 +2,6 @@ TODO:
- fix remaining checkpatch warnings and errors
- audit the vmbus to verify it is working properly with the
driver model
- - convert vmbus driver interface function pointer tables
- to constant, a.k.a vmbus_ops
- see if the vmbus can be merged with the other virtual busses
in the kernel
- audit the network driver
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index ff1d24720f11..8284297b30e9 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -25,7 +25,7 @@
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -124,6 +124,7 @@ struct blkvsc_driver_context {
};
/* Static decl */
+static DEFINE_MUTEX(blkvsc_mutex);
static int blkvsc_probe(struct device *dev);
static int blkvsc_remove(struct device *device);
static void blkvsc_shutdown(struct device *device);
@@ -1309,7 +1310,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode)
DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
blkdev->gd->disk_name);
- lock_kernel();
+ mutex_lock(&blkvsc_mutex);
spin_lock(&blkdev->lock);
if (!blkdev->users && blkdev->device_type == DVD_TYPE) {
@@ -1321,7 +1322,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode)
blkdev->users++;
spin_unlock(&blkdev->lock);
- unlock_kernel();
+ mutex_unlock(&blkvsc_mutex);
return 0;
}
@@ -1332,7 +1333,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode)
DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
blkdev->gd->disk_name);
- lock_kernel();
+ mutex_lock(&blkvsc_mutex);
spin_lock(&blkdev->lock);
if (blkdev->users == 1) {
spin_unlock(&blkdev->lock);
@@ -1343,7 +1344,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode)
blkdev->users--;
spin_unlock(&blkdev->lock);
- unlock_kernel();
+ mutex_unlock(&blkvsc_mutex);
return 0;
}
diff --git a/drivers/staging/hv/channel_interface.c b/drivers/staging/hv/channel_interface.c
index d9f51ac75eaa..3f6a1cb9cd8f 100644
--- a/drivers/staging/hv/channel_interface.c
+++ b/drivers/staging/hv/channel_interface.c
@@ -97,20 +97,6 @@ static int IVmbusChannelTeardownGpadl(struct hv_device *device, u32 GpadlHandle)
}
-void GetChannelInterface(struct vmbus_channel_interface *iface)
-{
- iface->Open = IVmbusChannelOpen;
- iface->Close = IVmbusChannelClose;
- iface->SendPacket = IVmbusChannelSendPacket;
- iface->SendPacketPageBuffer = IVmbusChannelSendPacketPageBuffer;
- iface->SendPacketMultiPageBuffer =
- IVmbusChannelSendPacketMultiPageBuffer;
- iface->RecvPacket = IVmbusChannelRecvPacket;
- iface->RecvPacketRaw = IVmbusChannelRecvPacketRaw;
- iface->EstablishGpadl = IVmbusChannelEstablishGpadl;
- iface->TeardownGpadl = IVmbusChannelTeardownGpadl;
- iface->GetInfo = GetChannelInfo;
-}
void GetChannelInfo(struct hv_device *device, struct hv_device_info *info)
{
@@ -150,3 +136,18 @@ void GetChannelInfo(struct hv_device *device, struct hv_device_info *info)
info->Outbound.BytesAvailToRead = debugInfo.Outbound.BytesAvailToRead;
info->Outbound.BytesAvailToWrite = debugInfo.Outbound.BytesAvailToWrite;
}
+
+
+/* vmbus interface function pointer table */
+const struct vmbus_channel_interface vmbus_ops = {
+ .Open = IVmbusChannelOpen,
+ .Close = IVmbusChannelClose,
+ .SendPacket = IVmbusChannelSendPacket,
+ .SendPacketPageBuffer = IVmbusChannelSendPacketPageBuffer,
+ .SendPacketMultiPageBuffer = IVmbusChannelSendPacketMultiPageBuffer,
+ .RecvPacket = IVmbusChannelRecvPacket,
+ .RecvPacketRaw = IVmbusChannelRecvPacketRaw,
+ .EstablishGpadl = IVmbusChannelEstablishGpadl,
+ .TeardownGpadl = IVmbusChannelTeardownGpadl,
+ .GetInfo = GetChannelInfo,
+};
diff --git a/drivers/staging/hv/channel_interface.h b/drivers/staging/hv/channel_interface.h
index 6acaf6ce2c48..ec882192c73e 100644
--- a/drivers/staging/hv/channel_interface.h
+++ b/drivers/staging/hv/channel_interface.h
@@ -27,8 +27,6 @@
#include "vmbus_api.h"
-void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface);
-
void GetChannelInfo(struct hv_device *Device,
struct hv_device_info *DeviceInfo);
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 56e11575c977..64a01147ecae 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -327,6 +327,9 @@ static const struct net_device_ops device_ops = {
.ndo_stop = netvsc_close,
.ndo_start_xmit = netvsc_start_xmit,
.ndo_set_multicast_list = netvsc_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
};
static int netvsc_probe(struct device *device)
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c
index 17bc7626f70a..d78c569ac94a 100644
--- a/drivers/staging/hv/ring_buffer.c
+++ b/drivers/staging/hv/ring_buffer.c
@@ -193,8 +193,7 @@ Description:
static inline u64
GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo)
{
- return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
- || RingInfo->RingBuffer->ReadIndex;
+ return (u64)RingInfo->RingBuffer->WriteIndex << 32;
}
diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h
index 0063bde9a4b2..8505a1c5f9ee 100644
--- a/drivers/staging/hv/storvsc_api.h
+++ b/drivers/staging/hv/storvsc_api.h
@@ -28,10 +28,10 @@
#include "vmbus_api.h"
/* Defines */
-#define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE)
+#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
#define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
-#define STORVSC_MAX_IO_REQUESTS 64
+#define STORVSC_MAX_IO_REQUESTS 128
/*
* In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 075b61bd492f..62882a437aa4 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -495,7 +495,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
/* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
- if (j == 0)
+ if (bounce_addr == 0)
bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
while (srclen) {
@@ -556,7 +556,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
destlen = orig_sgl[i].length;
/* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
- if (j == 0)
+ if (bounce_addr == 0)
bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
while (destlen) {
@@ -615,6 +615,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
unsigned int request_size = 0;
int i;
struct scatterlist *sgl;
+ unsigned int sg_count = 0;
DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d "
"queue depth %d tagged %d", scmnd, scmnd->sc_data_direction,
@@ -697,6 +698,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
request->DataBuffer.Length = scsi_bufflen(scmnd);
if (scsi_sg_count(scmnd)) {
sgl = (struct scatterlist *)scsi_sglist(scmnd);
+ sg_count = scsi_sg_count(scmnd);
/* check if we need to bounce the sgl */
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
@@ -731,15 +733,16 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
scsi_sg_count(scmnd));
sgl = cmd_request->bounce_sgl;
+ sg_count = cmd_request->bounce_sgl_count;
}
request->DataBuffer.Offset = sgl[0].offset;
- for (i = 0; i < scsi_sg_count(scmnd); i++) {
+ for (i = 0; i < sg_count; i++) {
DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n",
i, sgl[i].length, sgl[i].offset);
request->DataBuffer.PfnArray[i] =
- page_to_pfn(sg_page((&sgl[i])));
+ page_to_pfn(sg_page((&sgl[i])));
}
} else if (scsi_sglist(scmnd)) {
/* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */
diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c
index ca1e18a62006..db2afa33eac7 100644
--- a/drivers/staging/hv/vmbus.c
+++ b/drivers/staging/hv/vmbus.c
@@ -61,14 +61,6 @@ static void VmbusGetChannelOffers(void)
}
/*
- * VmbusGetChannelInterface - Get the channel interface
- */
-static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface)
-{
- GetChannelInterface(Interface);
-}
-
-/*
* VmbusGetChannelInfo - Get the device info for the specified device object
*/
static void VmbusGetChannelInfo(struct hv_device *DeviceObject,
@@ -279,7 +271,6 @@ int VmbusInitialize(struct hv_driver *drv)
driver->OnMsgDpc = VmbusOnMsgDPC;
driver->OnEventDpc = VmbusOnEventDPC;
driver->GetChannelOffers = VmbusGetChannelOffers;
- driver->GetChannelInterface = VmbusGetChannelInterface;
driver->GetChannelInfo = VmbusGetChannelInfo;
/* Hypervisor initialization...setup hypercall page..etc */
diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h
index 4275be3292ce..7f3d7dcb96a7 100644
--- a/drivers/staging/hv/vmbus_api.h
+++ b/drivers/staging/hv/vmbus_api.h
@@ -129,6 +129,9 @@ struct vmbus_channel_interface {
void (*GetInfo)(struct hv_device *dev, struct hv_device_info *devinfo);
};
+extern const struct vmbus_channel_interface vmbus_ops;
+
+
/* Base driver object */
struct hv_driver {
const char *name;
@@ -183,7 +186,6 @@ struct vmbus_driver {
void (*OnEventDpc)(struct hv_driver *driver);
void (*GetChannelOffers)(void);
- void (*GetChannelInterface)(struct vmbus_channel_interface *i);
void (*GetChannelInfo)(struct hv_device *dev,
struct hv_device_info *devinfo);
};
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 092f02ed6be1..ad298871d3f3 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -458,9 +458,7 @@ EXPORT_SYMBOL(vmbus_child_driver_unregister);
*/
void vmbus_get_interface(struct vmbus_channel_interface *interface)
{
- struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
-
- vmbus_drv_obj->GetChannelInterface(interface);
+ *interface = vmbus_ops;
}
EXPORT_SYMBOL(vmbus_get_interface);
diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c
index 3a580284020c..2fc3fd81a7a7 100644
--- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c
+++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
goto error_free_buf_dir_name;
/* Enable the buffer */
- ret = write_sysfs_int("ring_enable", buf_dir_name, 1);
+ ret = write_sysfs_int("enable", buf_dir_name, 1);
if (ret < 0)
goto error_free_buf_dir_name;
@@ -209,7 +209,7 @@ int main(int argc, char **argv)
}
/* Stop the ring buffer */
- ret = write_sysfs_int("ring_enable", buf_dir_name, 0);
+ ret = write_sysfs_int("enable", buf_dir_name, 0);
if (ret < 0)
goto error_close_buffer_event;
diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt
index cc6ecad4035c..d97106cb2b96 100644
--- a/drivers/staging/iio/Documentation/overview.txt
+++ b/drivers/staging/iio/Documentation/overview.txt
@@ -1,8 +1,8 @@
Overview of IIO
-The Industrial I/O subsytem is intended to provide support for devices
-that in some sense are analog to digital convertors (ADCs). As many
-actual devices combine some ADCs with digital to analog convertors
+The Industrial I/O subsystem is intended to provide support for devices
+that in some sense are analog to digital converters (ADCs). As many
+actual devices combine some ADCs with digital to analog converters
(DACs) the intention is to add that functionality at a future date
(hence the name).
@@ -46,18 +46,17 @@ external signal (trigger). These triggers might be a data ready
signal, a gpio line connected to some external system or an on
processor periodic interrupt. A single trigger may initialize data
capture or reading from a number of sensors. These triggers are
-used in iio to fill software ring buffers acting in a very similar
+used in IIO to fill software ring buffers acting in a very similar
fashion to the hardware buffers described above.
Other documentation:
-userspace.txt - overview of ring buffer reading from userspace
+userspace.txt - overview of ring buffer reading from userspace.
-device.txt - elemennts of a typical device driver.
+device.txt - elements of a typical device driver.
trigger.txt - elements of a typical trigger driver.
-ring.txt - additional elements required for ring buffer support
-
-
+ring.txt - additional elements required for ring buffer support.
+sysfs-bus-iio - abi documentation file.
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index d2ca6834c169..3696c364e644 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -47,10 +47,8 @@ request_update
If parameters have changed that require reinitialization or configuration of
the ring buffer this will trigger it.
-get_bpd, set_bpd
- Get/set the number of bytes for a given reading (single element, not sample set)
- The value of bps (bytes per set) is created from a combination of this and the
- enabled scan elements.
+get_bytes_per_datum, set_bytes_per_datum
+ Get/set the number of bytes for a complete scan. (All samples + timestamp)
get_length / set_length
Get/set the number of sample sets that may be held by the buffer.
diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio
index 714b4c57c82a..c13702037b08 100644
--- a/drivers/staging/iio/Documentation/sysfs-class-iio
+++ b/drivers/staging/iio/Documentation/sysfs-bus-iio
@@ -158,7 +158,7 @@ Contact: linux-iio@vger.kernel.org
Description:
Magnetic field along axis x, y or z (may be arbitrarily assigned)
channel m (not present if only one magnetometer at this orientation).
- Data converted by application of offset then scale to Gauss
+ Data converted by application of offset then scale to Gauss.
Has all the equivalent modifiers as per in[m].
What: /sys/.../device[n]/device[n]:event[m]
@@ -212,39 +212,6 @@ Description:
The actual value of the threshold in raw device units obtained by
reverse application of scale and offfset to the acceleration in m/s^2.
-What: /sys/.../device[n]/scan_elements
-KernelVersion: 2.6.35
-Contact: linux-iio@vger.kernel.org
-Description:
- Directory containing interfaces for elements that will be captured
- for a single triggered sample set in the buffer.
-
-What: /sys/.../device[n]/scan_elements/[m]_accel_x0_en
-KernelVersion: 2.6.35
-Contact: linux-iio@vger.kernel.org
-Description:
- Scan element control for triggered data capture. m implies the
- ordering within the buffer. Next the type is specified with
- modifier and channel number as per the sysfs single channel
- access above.
-
-What: /sys/.../device[n]/scan_elements/accel[_x0]_precision
-KernelVersion: 2.6.35
-Contact: linux-iio@vger.kernel.org
-Description:
- Scan element precision within the buffer. Note that the
- data alignment must restrictions must be read from within
- buffer to work out full data alignment for data read
- via buffer_access chrdev. _x0 dropped if shared across all
- acceleration channels.
-
-What: /sys/.../device[n]/scan_elements/accel[_x0]_shift
-KernelVersion: 2.6.35
-Contact: linux-iio@vger.kernel.org
-Description:
- A bit shift (to right) that must be applied prior to
- extracting the bits specified by accel[_x0]_precision.
-
What: /sys/.../device[n]/device[n]:buffer:event/dev
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
@@ -270,8 +237,8 @@ Contact: linux-iio@vger.kernel.org
Description:
Number of scans contained by the buffer.
-What: /sys/.../device[n]:buffer/bps
-KernelVersion: 2.6.35
+What: /sys/.../device[n]:buffer/bytes_per_datum
+KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
Bytes per scan. Due to alignment fun, the scan may be larger
@@ -292,3 +259,36 @@ Description:
to the nearest power of 2 times this. (may not be true in weird
hardware buffers that pack data well)
+What: /sys/.../device[n]/buffer/scan_elements
+KernelVersion: 2.6.37
+Contact: linux-iio@vger.kernel.org
+Description:
+ Directory containing interfaces for elements that will be captured
+ for a single triggered sample set in the buffer.
+
+What: /sys/.../device[n]/buffer/scan_elements/[m]_accel_x0_en
+KernelVersion: 2.6.37
+Contact: linux-iio@vger.kernel.org
+Description:
+ Scan element control for triggered data capture. m implies the
+ ordering within the buffer. Next the type is specified with
+ modifier and channel number as per the sysfs single channel
+ access above.
+
+What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_precision
+KernelVersion: 2.6.37
+Contact: linux-iio@vger.kernel.org
+Description:
+ Scan element precision within the buffer. Note that the
+ data alignment must restrictions must be read from within
+ buffer to work out full data alignment for data read
+ via buffer_access chrdev. _x0 dropped if shared across all
+ acceleration channels.
+
+What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift
+KernelVersion: 2.6.37
+Contact: linux-iio@vger.kernel.org
+Description:
+ A bit shift (to right) that must be applied prior to
+ extracting the bits specified by accel[_x0]_precision.
+
diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
index 4838818f65ef..ff06e5dc7188 100644
--- a/drivers/staging/iio/Documentation/userspace.txt
+++ b/drivers/staging/iio/Documentation/userspace.txt
@@ -1,60 +1,12 @@
Userspace access to IIO
-Example, ST Microelectronics LIS3L02DQ accelerometer.
-
-Typical sysfs entries (pruned for clarity)
-
-/sys/class/iio
- device0 - iio_dev related elements
- name - driver specific identifier (here lis3l02dq)
- accel_x - polled (or from ring) raw readout of acceleration
- accel_x_gain - hardware gain (calibration)
- accel_x_offset - hardware offset (calibration)
- available_sampling_frequency
-
- available_sampling_frequency - what options are there
- sampling_frequency - control of internal sampling frequency
- scan_elements - controls which channels will be stored in the ring buffer
- scan_en_accel_x
- scan_en_accel_y
- scan_en_timestamp
- device - link to underlying hardware device
- uevent - udev related element
-
- thresh - unified threshold used for detection on all axis
- event_line0_sources - which events are enabled
- accel_x_high - enable x axis high threshold event
- accel_x_low - enable x axis low threshold event
-
- event_line0 - event interface
- dev - major:minor for the chrdev (note major allocation dynamic)
- trigger - consumer attachement
- current_trigger - name based association with a trigger
- ring_buffer0 - ring buffer interface
- bps - byptes per sample (read only), dependant on scan element selection
- length - (rw) specificy length fo software ring buffer (typically ro in hw case)
- ring_enable - turn the ring on. If its the first to be enabled attached to this
- trigger will also enable the trigger.
- ring_access0
- dev - major:minor for ring buffer access chrdev
- ring_event_line0
- dev - major:minor for ring buffer event chrdev
-
- trigger0 - data ready trigger elements
- name - unqiue name of trigger
+The sysfs attributes are documented in sysfs-bus-iio.
Udev will create the following entries under /dev by default:
-ring_access0 - ring access chrdev
-ring_event0 - ring event chrdev
-event_line0 - general event chrdev.
-
-For the example code we assume the following rules have been used to ensure
-unique and consistent naming of these for the lis3l02dq in question:
-
-KERNEL="ring_event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_event"
-KERNEL="event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_event"
-KERNEL="ring_access*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_access"
+device0:buffer0:access0 - ring access chrdev
+device0:buffer0:event0 - ring event chrdev
+device0:event0 - general event chrdev.
The files, lis3l02dqbuffersimple.c and iio_utils.h in this directory provide an example
of how to use the ring buffer and event interfaces.
diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
index 1b6e37f76200..01e930201aa8 100644
--- a/drivers/staging/iio/accel/accel.h
+++ b/drivers/staging/iio/accel/accel.h
@@ -14,14 +14,44 @@
#define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_ACCEL_X_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(accel_x_gain, _mode, _show, _store, _addr)
+#define IIO_CONST_ATTR_ACCEL_SCALE(_string) \
+ IIO_CONST_ATTR(accel_scale, _string)
-#define IIO_DEV_ATTR_ACCEL_Y_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(accel_y_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_ACCEL_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_scale, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_ACCEL_X_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_x_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_y_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_z_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_x_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_y_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_z_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_x_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_y_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(accel_z_calibscale, _mode, _show, _store, _addr)
#define IIO_DEV_ATTR_ACCEL(_show, _addr) \
IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 6c6923f2eaa5..ab3988513d74 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -393,7 +393,7 @@ err_ret:
static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned,
ADIS16209_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.30518");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.30518");
static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned,
ADIS16209_AUX_ADC);
static IIO_CONST_ATTR(in0_scale, "0.6105");
@@ -402,40 +402,32 @@ static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed,
ADIS16209_XACCL_OUT);
static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed,
ADIS16209_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16209_read_14bit_signed,
adis16209_write_16bit,
ADIS16209_XACCL_NULL);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16209_read_14bit_signed,
adis16209_write_16bit,
ADIS16209_YACCL_NULL);
-static IIO_CONST_ATTR(accel_scale, "0.24414");
+static IIO_CONST_ATTR_ACCEL_SCALE("0.002394195531");
static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed,
ADIS16209_XINCL_OUT);
static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed,
ADIS16209_YINCL_OUT);
-static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
- adis16209_read_14bit_signed,
- adis16209_write_16bit,
- ADIS16209_XACCL_NULL);
-static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
- adis16209_read_14bit_signed,
- adis16209_write_16bit,
- ADIS16209_YACCL_NULL);
-static IIO_CONST_ATTR(incli_scale, "0.025");
+static IIO_CONST_ATTR(incli_scale, "0.00043633231");
static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
NULL, ADIS16209_ROT_OUT);
-static IIO_DEV_ATTR_TEMP(adis16209_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static IIO_DEV_ATTR_TEMP_RAW(adis16209_read_temp);
+static IIO_CONST_ATTR_TEMP_OFFSET("25");
+static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
-static IIO_CONST_ATTR(name, "adis16209");
+static IIO_CONST_ATTR_NAME("adis16209");
static struct attribute *adis16209_event_attributes[] = {
NULL
@@ -448,7 +440,7 @@ static struct attribute_group adis16209_event_attribute_group = {
static struct attribute *adis16209_attributes[] = {
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
- &iio_dev_attr_temp.dev_attr.attr,
+ &iio_dev_attr_temp_raw.dev_attr.attr,
&iio_const_attr_temp_offset.dev_attr.attr,
&iio_const_attr_temp_scale.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
@@ -457,13 +449,11 @@ static struct attribute *adis16209_attributes[] = {
&iio_const_attr_in0_scale.dev_attr.attr,
&iio_dev_attr_accel_x_raw.dev_attr.attr,
&iio_dev_attr_accel_y_raw.dev_attr.attr,
- &iio_dev_attr_accel_x_offset.dev_attr.attr,
- &iio_dev_attr_accel_y_offset.dev_attr.attr,
+ &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
&iio_const_attr_accel_scale.dev_attr.attr,
&iio_dev_attr_incli_x_raw.dev_attr.attr,
&iio_dev_attr_incli_y_raw.dev_attr.attr,
- &iio_dev_attr_incli_x_offset.dev_attr.attr,
- &iio_dev_attr_incli_y_offset.dev_attr.attr,
&iio_const_attr_incli_scale.dev_attr.attr,
&iio_dev_attr_rot_raw.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 25fde659d098..3eb1d559eb69 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -17,13 +17,13 @@
#include "../trigger.h"
#include "adis16209.h"
-static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
ADIS16209_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14),
ADIS16209_XACCL_OUT, NULL);
static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14),
ADIS16209_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
ADIS16209_AUX_ADC, NULL);
static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12),
ADIS16209_TEMP_OUT, NULL);
@@ -37,10 +37,10 @@ static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14),
static IIO_SCAN_EL_TIMESTAMP(8);
static struct attribute *adis16209_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_accel_x.dev_attr.attr,
&iio_scan_el_accel_y.dev_attr.attr,
- &iio_scan_el_aux_adc.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_temp.dev_attr.attr,
&iio_scan_el_incli_x.dev_attr.attr,
&iio_scan_el_incli_y.dev_attr.attr,
@@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16209_state *st
= container_of(work_s, struct adis16209_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
+ ring->access.store_to(ring,
+ (u8 *)data,
+ st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
kfree(data);
@@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
struct adis16209_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16209_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -182,11 +169,23 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16209_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_rot.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+ iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c
index 1487effa2e30..d2980dc74440 100644
--- a/drivers/staging/iio/accel/adis16209_trigger.c
+++ b/drivers/staging/iio/accel/adis16209_trigger.c
@@ -30,7 +30,7 @@ static int adis16209_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16209_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16209_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index bb7d76539cd7..032616ee65af 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -487,7 +487,7 @@ static struct bin_attribute adc2_bin = {
static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned,
ADIS16220_CAPT_SUPPLY);
-static IIO_CONST_ATTR(in_supply_scale, "0.0012207");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0012207");
static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA);
static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit,
NULL, ADIS16220_CAPT_PEAKA);
@@ -495,9 +495,10 @@ static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO,
adis16220_read_16bit,
adis16220_write_16bit,
ADIS16220_ACCL_NULL);
+static IIO_CONST_ATTR_ACCEL_SCALE("0.18704223545");
static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static IIO_CONST_ATTR_TEMP_OFFSET("25");
+static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
static IIO_DEV_ATTR_IN_RAW(0, adis16220_read_16bit, ADIS16220_CAPT_BUF1);
static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2);
@@ -518,9 +519,9 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO,
adis16220_write_16bit,
ADIS16220_CAPT_PNTR);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("100200");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200");
-static IIO_CONST_ATTR(name, "adis16220");
+static IIO_CONST_ATTR_NAME("adis16220");
static struct attribute *adis16220_attributes[] = {
&iio_dev_attr_in_supply_raw.dev_attr.attr,
@@ -528,12 +529,13 @@ static struct attribute *adis16220_attributes[] = {
&iio_dev_attr_accel_raw.dev_attr.attr,
&iio_dev_attr_accel_offset.dev_attr.attr,
&iio_dev_attr_accel_peak_raw.dev_attr.attr,
+ &iio_const_attr_accel_scale.dev_attr.attr,
&iio_dev_attr_temp_raw.dev_attr.attr,
&iio_dev_attr_in0_raw.dev_attr.attr,
&iio_dev_attr_in1_raw.dev_attr.attr,
&iio_const_attr_temp_offset.dev_attr.attr,
&iio_const_attr_temp_scale.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_dev_attr_capture.dev_attr.attr,
&iio_dev_attr_capture_count.dev_attr.attr,
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 3e9531dd0000..49e172a6a0cd 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -380,7 +380,10 @@ static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16240_read_10bit_unsigned,
ADIS16240_SUPPLY_OUT);
static IIO_DEV_ATTR_IN_RAW(0, adis16240_read_10bit_signed,
ADIS16240_AUX_ADC);
-static IIO_CONST_ATTR(in_supply_scale, "0.00488");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00488");
+
+static IIO_CONST_ATTR_ACCEL_SCALE("0.50406181");
+static IIO_CONST_ATTR(accel_peak_scale, "6.6292954");
static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed,
ADIS16240_XACCL_OUT);
static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO,
@@ -400,26 +403,26 @@ static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO,
static IIO_DEVICE_ATTR(accel_xyz_squared_peak_raw, S_IRUGO,
adis16240_read_12bit_signed, NULL,
ADIS16240_XYZPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16240_read_10bit_signed,
adis16240_write_16bit,
ADIS16240_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16240_read_10bit_signed,
adis16240_write_16bit,
ADIS16240_YACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16240_read_10bit_signed,
adis16240_write_16bit,
ADIS16240_ZACCL_OFF);
static IIO_DEV_ATTR_TEMP_RAW(adis16240_read_10bit_unsigned);
-static IIO_CONST_ATTR(temp_scale, "0.244");
+static IIO_CONST_ATTR_TEMP_SCALE("0.244");
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("4096");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
-static IIO_CONST_ATTR(name, "adis16240");
+static IIO_CONST_ATTR_NAME("adis16240");
static struct attribute *adis16240_event_attributes[] = {
NULL
@@ -433,19 +436,21 @@ static struct attribute *adis16240_attributes[] = {
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
&iio_dev_attr_in0_raw.dev_attr.attr,
+ &iio_const_attr_accel_scale.dev_attr.attr,
+ &iio_const_attr_accel_peak_scale.dev_attr.attr,
&iio_dev_attr_accel_x_raw.dev_attr.attr,
- &iio_dev_attr_accel_x_offset.dev_attr.attr,
+ &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
&iio_dev_attr_accel_x_peak_raw.dev_attr.attr,
&iio_dev_attr_accel_y_raw.dev_attr.attr,
- &iio_dev_attr_accel_y_offset.dev_attr.attr,
+ &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
&iio_dev_attr_accel_y_peak_raw.dev_attr.attr,
&iio_dev_attr_accel_z_raw.dev_attr.attr,
- &iio_dev_attr_accel_z_offset.dev_attr.attr,
+ &iio_dev_attr_accel_z_calibbias.dev_attr.attr,
&iio_dev_attr_accel_z_peak_raw.dev_attr.attr,
&iio_dev_attr_accel_xyz_squared_peak_raw.dev_attr.attr,
&iio_dev_attr_temp_raw.dev_attr.attr,
&iio_const_attr_temp_scale.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index cd69a2e2bb9a..9282372e7a69 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -17,7 +17,7 @@
#include "../trigger.h"
#include "adis16240.h"
-static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
+static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
ADIS16240_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10),
ADIS16240_XACCL_OUT, NULL);
@@ -25,7 +25,7 @@ static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10),
ADIS16240_YACCL_OUT, NULL);
static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10),
ADIS16240_ZACCL_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
+static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
ADIS16240_AUX_ADC, NULL);
static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
ADIS16240_TEMP_OUT, NULL);
@@ -33,11 +33,11 @@ static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
static IIO_SCAN_EL_TIMESTAMP(6);
static struct attribute *adis16240_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_accel_x.dev_attr.attr,
&iio_scan_el_accel_y.dev_attr.attr,
&iio_scan_el_accel_z.dev_attr.attr,
- &iio_scan_el_aux_adc.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_temp.dev_attr.attr,
&iio_scan_el_timestamp.dev_attr.attr,
NULL,
@@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16240_state *st
= container_of(work_s, struct adis16240_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+ ring->access.store_to(ring,
(u8 *)data,
st->last_timestamp);
@@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
struct adis16240_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16240_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -172,11 +161,21 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16240_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c
index 2ba71fd73a47..6cb8681f2853 100644
--- a/drivers/staging/iio/accel/adis16240_trigger.c
+++ b/drivers/staging/iio/accel/adis16240_trigger.c
@@ -30,7 +30,7 @@ static int adis16240_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16240_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16240_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h
index 5b49f835eac5..faf73d7892e0 100644
--- a/drivers/staging/iio/accel/inclinometer.h
+++ b/drivers/staging/iio/accel/inclinometer.h
@@ -21,3 +21,5 @@
#define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr)
+#define IIO_CONST_ATTR_INCLI_SCALE(_string) \
+ IIO_CONST_ATTR(incli_scale, _string)
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 0ee933737545..655f2b7672e0 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -731,7 +731,7 @@ static struct attribute_group lis3l02dq_event_attribute_group = {
.attrs = lis3l02dq_event_attributes,
};
-static IIO_CONST_ATTR(name, "lis3l02dq");
+static IIO_CONST_ATTR_NAME("lis3l02dq");
static IIO_CONST_ATTR(accel_scale, "0.00958");
static struct attribute *lis3l02dq_attributes[] = {
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index a960a8ff3c40..f26c0fe44129 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
int ret, len = 0, i = 0;
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *dev_info = dev_get_drvdata(dev);
+ struct iio_ring_buffer *ring = dev_info->ring;
+ struct attribute_group *scan_el_attrs = ring->scan_el_attrs;
s16 *data;
- while (dev_info->scan_el_attrs->attrs[i]) {
+ while (scan_el_attrs->attrs[i]) {
el = to_iio_scan_el((struct device_attribute *)
- (dev_info->scan_el_attrs->attrs[i]));
+ (scan_el_attrs->attrs[i]));
/* label is in fact the address */
if (el->label == this_attr->address)
break;
i++;
}
- if (!dev_info->scan_el_attrs->attrs[i]) {
+ if (!scan_el_attrs->attrs[i]) {
ret = -EINVAL;
goto error_ret;
}
/* If this element is in the scan mask */
- ret = iio_scan_mask_query(dev_info, el->number);
+ ret = iio_scan_mask_query(ring, el->number);
if (ret < 0)
goto error_ret;
if (ret) {
- data = kmalloc(dev_info->ring->access.get_bpd(dev_info->ring),
+ data = kmalloc(ring->access.get_bytes_per_datum(ring),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- ret = dev_info->ring->access.read_last(dev_info->ring,
- (u8 *)data);
+ ret = ring->access.read_last(ring,
+ (u8 *)data);
if (ret)
goto error_free_data;
} else {
ret = -EINVAL;
goto error_ret;
}
- len = iio_scan_mask_count_to_right(dev_info, el->number);
+ len = iio_scan_mask_count_to_right(ring, el->number);
if (len < 0) {
ret = len;
goto error_free_data;
@@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
**/
static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
{
+ struct iio_ring_buffer *ring = st->help.indio_dev->ring;
struct spi_transfer *xfers;
struct spi_message msg;
int ret, i, j = 0;
- xfers = kzalloc((st->help.indio_dev->scan_count) * 2
+ xfers = kzalloc((ring->scan_count) * 2
* sizeof(*xfers), GFP_KERNEL);
if (!xfers)
return -ENOMEM;
@@ -223,7 +226,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
mutex_lock(&st->buf_lock);
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
- if (st->help.indio_dev->scan_mask & (1 << i)) {
+ if (ring->scan_mask & (1 << i)) {
/* lower byte */
xfers[j].tx_buf = st->tx + 2*j;
st->tx[2*j] = read_all_tx_array[i*4];
@@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
* values in alternate bytes
*/
spi_message_init(&msg);
- for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
+ for (j = 0; j < ring->scan_count * 2; j++)
spi_message_add_tail(&xfers[j], &msg);
ret = spi_sync(st->us, &msg);
@@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
u8 *rx_array ;
s16 *data = (s16 *)buf;
- rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
+ rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
if (rx_array == NULL)
return -ENOMEM;
ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
if (ret < 0)
return ret;
- for (i = 0; i < h->indio_dev->scan_count; i++)
+ for (i = 0; i < h->indio_dev->ring->scan_count; i++)
data[i] = combine_8_to_16(rx_array[i*4+1],
rx_array[i*4+3]);
kfree(rx_array);
@@ -379,7 +382,8 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
&t);
return ret;
}
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *lis3l02dq_trigger_attrs[] = {
&dev_attr_name.attr,
@@ -479,28 +483,29 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
{
int ret;
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-
+ struct iio_ring_buffer *ring;
INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
- /* Set default scan mode */
h->get_ring_element = &lis3l02dq_get_ring_element;
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
- indio_dev->scan_timestamp = true;
- indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
-
- indio_dev->ring = iio_sw_rb_allocate(indio_dev);
- if (!indio_dev->ring)
+ ring = iio_sw_rb_allocate(indio_dev);
+ if (!ring)
return -ENOMEM;
+ indio_dev->ring = ring;
/* Effectively select the ring buffer implementation */
- iio_ring_sw_register_funcs(&indio_dev->ring->access);
- indio_dev->ring->bpe = 2;
- indio_dev->ring->preenable = &iio_sw_ring_preenable;
- indio_dev->ring->postenable = &iio_triggered_ring_postenable;
- indio_dev->ring->predisable = &iio_triggered_ring_predisable;
- indio_dev->ring->owner = THIS_MODULE;
+ iio_ring_sw_register_funcs(&ring->access);
+ ring->bpe = 2;
+ ring->scan_el_attrs = &lis3l02dq_scan_el_group;
+ ring->scan_timestamp = true;
+ ring->preenable = &iio_sw_ring_preenable;
+ ring->postenable = &iio_triggered_ring_postenable;
+ ring->predisable = &iio_triggered_ring_predisable;
+ ring->owner = THIS_MODULE;
+
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
if (ret)
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index 09d9470bb9a0..23892848f5ae 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -91,7 +91,7 @@
#define SCA3000_INT_STATUS_X_TRIGGER 0x02
#define SCA3000_INT_STATUS_Z_TRIGGER 0x01
-/* Used to allow accesss to multiplexed registers */
+/* Used to allow access to multiplexed registers */
#define SCA3000_REG_ADDR_CTRL_SEL 0x18
/* Only available for SCA3000-D03 and SCA3000-D01 */
#define SCA3000_REG_CTRL_SEL_I2C_DISABLE 0x01
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index b78b6b66ffe0..0eb2c4cdeb48 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -721,8 +721,8 @@ error_ret:
}
static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp);
-static IIO_CONST_ATTR(temp_scale, "0.555556");
-static IIO_CONST_ATTR(temp_offset, "-214.6");
+static IIO_CONST_ATTR_TEMP_SCALE("0.555556");
+static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
/**
* sca3000_show_thresh() sysfs query of a threshold
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 8e8c068d401b..c93f85cacbc0 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -53,7 +53,8 @@ static int sca3000_rip_hw_rb(struct iio_ring_buffer *r,
struct iio_dev *indio_dev = hw_ring->private;
struct sca3000_state *st = indio_dev->dev_data;
u8 *rx;
- int ret, num_available, num_read = 0;
+ s16 *samples;
+ int ret, i, num_available, num_read = 0;
int bytes_per_sample = 1;
if (st->bpse == 11)
@@ -87,6 +88,17 @@ static int sca3000_rip_hw_rb(struct iio_ring_buffer *r,
ret = sca3000_read_data(st,
SCA3000_REG_ADDR_RING_OUT,
data, num_read);
+
+ /* Convert byte order and shift to default resolution */
+ if (st->bpse == 11) {
+ samples = (s16*)(*data+1);
+ for (i = 0; i < (num_read/2); i++) {
+ samples[i] = be16_to_cpup(
+ (__be16 *)&(samples[i]));
+ samples[i] >>= 3;
+ }
+ }
+
error_ret:
mutex_unlock(&st->lock);
@@ -100,7 +112,7 @@ static int sca3000_ring_get_length(struct iio_ring_buffer *r)
}
/* only valid if resolution is kept at 11bits */
-static int sca3000_ring_get_bpd(struct iio_ring_buffer *r)
+static int sca3000_ring_get_bytes_per_datum(struct iio_ring_buffer *r)
{
return 6;
}
@@ -111,7 +123,7 @@ static void sca3000_ring_release(struct device *dev)
}
static IIO_RING_ENABLE_ATTR;
-static IIO_RING_BPS_ATTR;
+static IIO_RING_BYTES_PER_DATUM_ATTR;
static IIO_RING_LENGTH_ATTR;
/**
@@ -126,8 +138,8 @@ static ssize_t sca3000_show_ring_bpse(struct device *dev,
{
int len = 0, ret;
u8 *rx;
- struct iio_ring_buffer *r = dev_get_drvdata(dev);
- struct sca3000_state *st = r->indio_dev->dev_data;
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct sca3000_state *st = indio_dev->dev_data;
mutex_lock(&st->lock);
ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
@@ -153,8 +165,8 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev,
const char *buf,
size_t len)
{
- struct iio_ring_buffer *r = dev_get_drvdata(dev);
- struct sca3000_state *st = r->indio_dev->dev_data;
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct sca3000_state *st = indio_dev->dev_data;
int ret;
u8 *rx;
long val;
@@ -218,8 +230,8 @@ static struct attribute_group sca3000_scan_el_group = {
*/
static struct attribute *sca3000_ring_attributes[] = {
&dev_attr_length.attr,
- &dev_attr_bps.attr,
- &dev_attr_ring_enable.attr,
+ &dev_attr_bytes_per_datum.attr,
+ &dev_attr_enable.attr,
NULL,
};
@@ -264,15 +276,15 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
int sca3000_configure_ring(struct iio_dev *indio_dev)
{
- indio_dev->scan_el_attrs = &sca3000_scan_el_group;
indio_dev->ring = sca3000_rb_allocate(indio_dev);
if (indio_dev->ring == NULL)
return -ENOMEM;
indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
+ indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
indio_dev->ring->access.get_length = &sca3000_ring_get_length;
- indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd;
+ indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
return 0;
}
diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h
index 7841e6ad4349..953b5ceec3af 100644
--- a/drivers/staging/iio/adc/adc.h
+++ b/drivers/staging/iio/adc/adc.h
@@ -27,5 +27,12 @@
NULL, \
_addr)
+
+#define IIO_CONST_ATTR_IN_NAMED_OFFSET(_name, _string) \
+ IIO_CONST_ATTR(in_##_name##_offset, _string)
+
+#define IIO_CONST_ATTR_IN_NAMED_SCALE(_name, _string) \
+ IIO_CONST_ATTR(in_##_name##_scale, _string)
+
#define IIO_EVENT_CODE_IN_HIGH_THRESH(a) (IIO_EVENT_CODE_ADC_BASE + a)
#define IIO_EVENT_CODE_IN_LOW_THRESH(a) (IIO_EVENT_CODE_ADC_BASE + a + 32)
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 6435e509dd56..1dc428fc0cce 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
st->indio_dev->attrs = st->chip_info->dev_attrs;
/* Todo: this shouldn't be here. */
- st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
st->indio_dev->dev_data = (void *)(st);
st->indio_dev->driver_module = THIS_MODULE;
st->indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 786b17a0d6b0..1d6ce54e9a86 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -30,6 +30,7 @@
/* Todo: test this */
int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
{
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
unsigned long numvals;
int count = 0, ret;
u8 *ring_data;
@@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
ret = -ENOMEM;
goto error_ret;
}
- ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
- ring_data);
+ ret = ring->access.read_last(ring, ring_data);
if (ret)
goto error_free_ring_data;
/* Need a count of channels prior to this one */
@@ -77,6 +77,7 @@ error_ret:
static int max1363_ring_preenable(struct iio_dev *indio_dev)
{
struct max1363_state *st = indio_dev->dev_data;
+ struct iio_ring_buffer *ring = indio_dev->ring;
size_t d_size;
unsigned long numvals;
@@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
* Need to figure out the current mode based upon the requested
* scan mask in iio_dev
*/
- st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
+ st->current_mode = max1363_match_mode(ring->scan_mask,
st->chip_info);
if (!st->current_mode)
return -EINVAL;
@@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
max1363_set_scan_mode(st);
numvals = hweight_long(st->current_mode->modemask);
- if (indio_dev->ring->access.set_bpd) {
+ if (ring->access.set_bytes_per_datum) {
if (st->chip_info->bits != 8)
d_size = numvals*2 + sizeof(s64);
else
d_size = numvals + sizeof(s64);
if (d_size % 8)
d_size += 8 - (d_size % 8);
- indio_dev->ring->access.set_bpd(indio_dev->ring, d_size);
+ ring->access.set_bytes_per_datum(ring, d_size);
}
return 0;
@@ -135,7 +136,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
struct max1363_state *st = container_of(work_s, struct max1363_state,
poll_work);
struct iio_dev *indio_dev = st->indio_dev;
- struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
+ struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
s64 time_ns;
__u8 *rxbuf;
int b_sent;
@@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
- indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
+ indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
done:
kfree(rxbuf);
atomic_dec(&st->protect_ring);
@@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
goto error_ret;
}
/* Effectively select the ring buffer implementation */
- iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
+ iio_ring_sw_register_funcs(&indio_dev->ring->access);
ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
if (ret)
goto error_deallocate_sw_rb;
/* Ring buffer functions - here trigger setup related */
+ indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
indio_dev->ring->postenable = &iio_triggered_ring_postenable;
indio_dev->ring->preenable = &max1363_ring_preenable;
indio_dev->ring->predisable = &iio_triggered_ring_predisable;
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index fd23bd1ea7b6..98d1a2c12df2 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -73,7 +73,6 @@ struct iio_shared_ev_pointer {
* @det_events: list of detected events
* @max_events: maximum number of events before new ones are dropped
* @current_events: number of events in detected list
- * @attr: this chrdev's minor number sysfs attribute
* @owner: ensure the driver module owns the file, not iio
* @private: driver specific data
* @_name: used internally to store the sysfs name for minor id
@@ -88,7 +87,6 @@ struct iio_event_interface {
struct iio_detected_event_list det_events;
int max_events;
int current_events;
- struct iio_chrdev_minor_attr attr;
struct module *owner;
void *private;
char _name[35];
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 134dfaae2f0c..c1ad0c8f5f15 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -445,22 +445,23 @@ err_ret:
static IIO_DEV_ATTR_IN_NAMED_RAW(supply,
adis16260_read_12bit_unsigned,
ADIS16260_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.0018315");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.0018315");
static IIO_DEV_ATTR_GYRO(adis16260_read_14bit_signed,
ADIS16260_GYRO_OUT);
-static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO,
+static IIO_CONST_ATTR_GYRO_SCALE("0.00127862821");
+static IIO_DEV_ATTR_GYRO_CALIBSCALE(S_IWUSR | S_IRUGO,
adis16260_read_14bit_signed,
adis16260_write_16bit,
ADIS16260_GYRO_SCALE);
-static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_GYRO_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16260_read_12bit_signed,
adis16260_write_16bit,
ADIS16260_GYRO_OFF);
static IIO_DEV_ATTR_TEMP_RAW(adis16260_read_12bit_unsigned);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "0.1453");
+static IIO_CONST_ATTR_TEMP_OFFSET("25");
+static IIO_CONST_ATTR_TEMP_SCALE("0.1453");
static IIO_DEV_ATTR_IN_RAW(0, adis16260_read_12bit_unsigned,
ADIS16260_AUX_ADC);
@@ -474,9 +475,9 @@ static IIO_DEV_ATTR_ANGL(adis16260_read_14bit_signed,
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("256 2048");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("256 2048");
-static IIO_CONST_ATTR(name, "adis16260");
+static IIO_CONST_ATTR_NAME("adis16260");
static struct attribute *adis16260_event_attributes[] = {
NULL
@@ -490,8 +491,9 @@ static struct attribute *adis16260_attributes[] = {
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
&iio_dev_attr_gyro_raw.dev_attr.attr,
- &iio_dev_attr_gyro_scale.dev_attr.attr,
- &iio_dev_attr_gyro_offset.dev_attr.attr,
+ &iio_const_attr_gyro_scale.dev_attr.attr,
+ &iio_dev_attr_gyro_calibscale.dev_attr.attr,
+ &iio_dev_attr_gyro_calibbias.dev_attr.attr,
&iio_dev_attr_angl_raw.dev_attr.attr,
&iio_dev_attr_temp_raw.dev_attr.attr,
&iio_const_attr_temp_offset.dev_attr.attr,
@@ -499,7 +501,7 @@ static struct attribute *adis16260_attributes[] = {
&iio_dev_attr_in0_raw.dev_attr.attr,
&iio_const_attr_in0_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 9ef7f9080dcd..659a672b1c5d 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -17,11 +17,11 @@
#include "../trigger.h"
#include "adis16260.h"
-static IIO_SCAN_EL_C(supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in_supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12),
ADIS16260_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, IIO_SIGNED(14),
ADIS16260_GYRO_OUT, NULL);
-static IIO_SCAN_EL_C(aux_adc, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(in0, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14),
ADIS16260_AUX_ADC, NULL);
static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, IIO_UNSIGNED(12),
ADIS16260_TEMP_OUT, NULL);
@@ -31,9 +31,9 @@ static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, IIO_UNSIGNED(12),
static IIO_SCAN_EL_TIMESTAMP(5);
static struct attribute *adis16260_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_gyro.dev_attr.attr,
- &iio_scan_el_aux_adc.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_temp.dev_attr.attr,
&iio_scan_el_angl.dev_attr.attr,
&iio_scan_el_timestamp.dev_attr.attr,
@@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16260_state *st
= container_of(work_s, struct adis16260_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+ ring->access.store_to(ring,
(u8 *)data,
st->last_timestamp);
@@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
struct adis16260_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16260_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -174,11 +164,20 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16260_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp.number);
+ iio_scan_mask_set(ring, iio_scan_el_angl.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
index de01537d257e..4a744c11ca6c 100644
--- a/drivers/staging/iio/gyro/adis16260_trigger.c
+++ b/drivers/staging/iio/gyro/adis16260_trigger.c
@@ -30,7 +30,7 @@ static int adis16260_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16260_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16260_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h
index f68edab8f30d..98b837b775a2 100644
--- a/drivers/staging/iio/gyro/gyro.h
+++ b/drivers/staging/iio/gyro/gyro.h
@@ -3,6 +3,9 @@
/* Gyroscope types of attribute */
+#define IIO_CONST_ATTR_GYRO_OFFSET(_string) \
+ IIO_CONST_ATTR(gyro_offset, _string)
+
#define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr)
@@ -15,18 +18,45 @@
#define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_GYRO_X_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(gyro_x_gain, _mode, _show, _store, _addr)
-
-#define IIO_DEV_ATTR_GYRO_Y_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(gyro_y_gain, _mode, _show, _store, _addr)
-
-#define IIO_DEV_ATTR_GYRO_Z_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(gyro_z_gain, _mode, _show, _store, _addr)
+#define IIO_CONST_ATTR_GYRO_SCALE(_string) \
+ IIO_CONST_ATTR(gyro_scale, _string)
#define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr)
+#define IIO_DEV_ATTR_GYRO_X_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_x_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_y_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
+
#define IIO_DEV_ATTR_GYRO(_show, _addr) \
IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 9d0ca128679e..248bdd2846fd 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -90,12 +90,7 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
* @ring: [DRIVER] any ring buffer present
* @mlock: [INTERN] lock used to prevent simultaneous device state
* changes
- * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
- * control method is used
- * @scan_count: [INTERN] the number of elements in the current scan mode
- * @scan_mask: [INTERN] bitmask used in masking scan mode elements
* @available_scan_masks: [DRIVER] optional array of allowed bitmasks
- * @scan_timestamp: [INTERN] does the scan mode include a timestamp
* @trig: [INTERN] current device trigger (ring buffer modes)
* @pollfunc: [DRIVER] function run on trigger being recieved
**/
@@ -118,104 +113,11 @@ struct iio_dev {
struct iio_ring_buffer *ring;
struct mutex mlock;
- struct attribute_group *scan_el_attrs;
- int scan_count;
-
- u32 scan_mask;
u32 *available_scan_masks;
- bool scan_timestamp;
struct iio_trigger *trig;
struct iio_poll_func *pollfunc;
};
-/*
- * These are mainly provided to allow for a change of implementation if a device
- * has a large number of scan elements
- */
-#define IIO_MAX_SCAN_LENGTH 31
-
-/* note 0 used as error indicator as it doesn't make sense. */
-static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
-{
- while (*av_masks) {
- if (!(~*av_masks & mask))
- return *av_masks;
- av_masks++;
- }
- return 0;
-}
-
-static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
-{
- u32 mask;
-
- if (bit > IIO_MAX_SCAN_LENGTH)
- return -EINVAL;
-
- if (!dev_info->scan_mask)
- return 0;
-
- if (dev_info->available_scan_masks)
- mask = iio_scan_mask_match(dev_info->available_scan_masks,
- dev_info->scan_mask);
- else
- mask = dev_info->scan_mask;
-
- if (!mask)
- return -EINVAL;
-
- return !!(mask & (1 << bit));
-};
-
-static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
-{
- u32 mask;
- u32 trialmask = dev_info->scan_mask | (1 << bit);
-
- if (bit > IIO_MAX_SCAN_LENGTH)
- return -EINVAL;
- if (dev_info->available_scan_masks) {
- mask = iio_scan_mask_match(dev_info->available_scan_masks,
- trialmask);
- if (!mask)
- return -EINVAL;
- }
- dev_info->scan_mask = trialmask;
- dev_info->scan_count++;
-
- return 0;
-};
-
-static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
-{
- if (bit > IIO_MAX_SCAN_LENGTH)
- return -EINVAL;
- dev_info->scan_mask &= ~(1 << bit);
- dev_info->scan_count--;
- return 0;
-};
-
-/**
- * iio_scan_mask_count_to_right() - how many scan elements occur before here
- * @dev_info: the iio_device whose scan mode we are querying
- * @bit: which number scan element is this
- **/
-static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
- int bit)
-{
- int count = 0;
- int mask = (1 << bit);
- if (bit > IIO_MAX_SCAN_LENGTH)
- return -EINVAL;
- while (mask) {
- mask >>= 1;
- if (mask & dev_info->scan_mask)
- count++;
- }
-
- return count;
-}
-
/**
* iio_device_register() - register a device with the IIO subsystem
* @dev_info: Device structure filled by the device driver
@@ -233,7 +135,7 @@ void iio_device_unregister(struct iio_dev *dev_info);
* physical interrupt lines
* @dev_info: the iio device for which the is an interrupt line
* @line_number: associated line number
- * @id: idr allocated unique id number
+ * @id: ida allocated unique id number
* @irq: associate interrupt number
* @ev_list: event handler list for associated events
* @ev_list_lock: ensure only one access to list at a time
@@ -400,8 +302,8 @@ static inline bool iio_ring_enabled(struct iio_dev *dev_info)
| INDIO_RING_HARDWARE_BUFFER);
};
-struct idr;
+struct ida;
-int iio_get_new_idr_val(struct idr *this_idr);
-void iio_free_idr_val(struct idr *this_idr, int id);
+int iio_get_new_ida_val(struct ida *this_ida);
+void iio_free_ida_val(struct ida *this_ida, int id);
#endif /* _INDUSTRIAL_IO_H_ */
diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c
index f1950d56cb1f..3ed86cc1d2e7 100644
--- a/drivers/staging/iio/imu/adis16300_core.c
+++ b/drivers/staging/iio/imu/adis16300_core.c
@@ -503,28 +503,33 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
+ adis16300_read_12bit_signed,
+ adis16300_write_16bit,
+ ADIS16300_XGYRO_OFF);
+
+static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16300_read_12bit_signed,
adis16300_write_16bit,
ADIS16300_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16300_read_12bit_signed,
adis16300_write_16bit,
ADIS16300_YACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16300_read_12bit_signed,
adis16300_write_16bit,
ADIS16300_ZACCL_OFF);
static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16300_read_14bit_unsigned,
ADIS16300_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.00242");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.00242");
static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed,
ADIS16300_XGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s");
+static IIO_CONST_ATTR_GYRO_SCALE("0.000872664");
static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
ADIS16300_XACCL_OUT);
@@ -532,17 +537,17 @@ static IIO_DEV_ATTR_ACCEL_Y(adis16300_read_14bit_signed,
ADIS16300_YACCL_OUT);
static IIO_DEV_ATTR_ACCEL_Z(adis16300_read_14bit_signed,
ADIS16300_ZACCL_OUT);
-static IIO_CONST_ATTR(accel_scale, "0.0006 g");
+static IIO_CONST_ATTR_ACCEL_SCALE("0.00588399");
static IIO_DEV_ATTR_INCLI_X(adis16300_read_13bit_signed,
ADIS16300_XINCLI_OUT);
static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed,
ADIS16300_YINCLI_OUT);
-static IIO_CONST_ATTR(incli_scale, "0.044 d");
+static IIO_CONST_ATTR_INCLI_SCALE("0.00076794487");
static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
-static IIO_CONST_ATTR(temp_offset, "198.16 K");
-static IIO_CONST_ATTR(temp_scale, "0.14 K");
+static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
+static IIO_CONST_ATTR_TEMP_SCALE("0.14");
static IIO_DEV_ATTR_IN_RAW(0, adis16300_read_12bit_unsigned,
ADIS16300_AUX_ADC);
@@ -554,9 +559,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-static IIO_CONST_ATTR(name, "adis16300");
+static IIO_CONST_ATTR_NAME("adis16300");
static struct attribute *adis16300_event_attributes[] = {
NULL
@@ -567,9 +572,10 @@ static struct attribute_group adis16300_event_attribute_group = {
};
static struct attribute *adis16300_attributes[] = {
- &iio_dev_attr_accel_x_offset.dev_attr.attr,
- &iio_dev_attr_accel_y_offset.dev_attr.attr,
- &iio_dev_attr_accel_z_offset.dev_attr.attr,
+ &iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_z_calibbias.dev_attr.attr,
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -587,7 +593,7 @@ static struct attribute *adis16300_attributes[] = {
&iio_dev_attr_in0_raw.dev_attr.attr,
&iio_const_attr_in0_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c
index fc93160acb26..0e09051e5545 100644
--- a/drivers/staging/iio/imu/adis16300_ring.c
+++ b/drivers/staging/iio/imu/adis16300_ring.c
@@ -17,7 +17,7 @@
#include "../trigger.h"
#include "adis16300.h"
-static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16300_SCAN_SUPPLY, IIO_UNSIGNED(14),
ADIS16300_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -32,7 +32,7 @@ static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, IIO_SIGNED(14),
static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_UNSIGNED(12),
ADIS16300_TEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16300_SCAN_ADC_0, IIO_UNSIGNED(12),
ADIS16300_AUX_ADC, NULL);
static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X, IIO_SIGNED(12),
@@ -43,7 +43,7 @@ static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y, IIO_SIGNED(12),
static IIO_SCAN_EL_TIMESTAMP(9);
static struct attribute *adis16300_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_gyro_x.dev_attr.attr,
&iio_scan_el_temp.dev_attr.attr,
&iio_scan_el_accel_x.dev_attr.attr,
@@ -51,7 +51,7 @@ static struct attribute *adis16300_scan_el_attrs[] = {
&iio_scan_el_accel_z.dev_attr.attr,
&iio_scan_el_incli_x.dev_attr.attr,
&iio_scan_el_incli_y.dev_attr.attr,
- &iio_scan_el_adc_0.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_timestamp.dev_attr.attr,
NULL,
};
@@ -134,11 +134,11 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16300_state *st
= container_of(work_s, struct adis16300_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
+ ring->access.store_to(ring,
+ (u8 *)data,
+ st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
kfree(data);
@@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
struct adis16300_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16300_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -202,11 +188,24 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16300_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+ iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/imu/adis16300_trigger.c b/drivers/staging/iio/imu/adis16300_trigger.c
index 64036cd99102..d6677b64edb9 100644
--- a/drivers/staging/iio/imu/adis16300_trigger.c
+++ b/drivers/staging/iio/imu/adis16300_trigger.c
@@ -30,7 +30,7 @@ static int adis16300_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16300_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16300_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
index 1575b7b5d44f..cc33843bbc09 100644
--- a/drivers/staging/iio/imu/adis16350_core.c
+++ b/drivers/staging/iio/imu/adis16350_core.c
@@ -475,24 +475,39 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
+ adis16350_read_12bit_signed,
+ adis16350_write_16bit,
+ ADIS16350_XGYRO_OFF);
+
+static IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
+ adis16350_read_12bit_signed,
+ adis16350_write_16bit,
+ ADIS16350_YGYRO_OFF);
+
+static IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
+ adis16350_read_12bit_signed,
+ adis16350_write_16bit,
+ ADIS16350_ZGYRO_OFF);
+
+static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16350_read_12bit_signed,
adis16350_write_16bit,
ADIS16350_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16350_read_12bit_signed,
adis16350_write_16bit,
ADIS16350_YACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
adis16350_read_12bit_signed,
adis16350_write_16bit,
ADIS16350_ZACCL_OFF);
static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16350_read_12bit_unsigned,
ADIS16350_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.002418");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418");
static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
ADIS16350_XGYRO_OUT);
@@ -500,7 +515,7 @@ static IIO_DEV_ATTR_GYRO_Y(adis16350_read_14bit_signed,
ADIS16350_YGYRO_OUT);
static IIO_DEV_ATTR_GYRO_Z(adis16350_read_14bit_signed,
ADIS16350_ZGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.05");
+static IIO_CONST_ATTR_GYRO_SCALE("0.00127862821");
static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
ADIS16350_XACCL_OUT);
@@ -508,7 +523,7 @@ static IIO_DEV_ATTR_ACCEL_Y(adis16350_read_14bit_signed,
ADIS16350_YACCL_OUT);
static IIO_DEV_ATTR_ACCEL_Z(adis16350_read_14bit_signed,
ADIS16350_ZACCL_OUT);
-static IIO_CONST_ATTR(accel_scale, "0.00333");
+static IIO_CONST_ATTR_ACCEL_SCALE("0.0247323713");
static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
NULL, ADIS16350_XTEMP_OUT);
@@ -516,7 +531,8 @@ static IIO_DEVICE_ATTR(temp_y_raw, S_IRUGO, adis16350_read_12bit_signed,
NULL, ADIS16350_YTEMP_OUT);
static IIO_DEVICE_ATTR(temp_z_raw, S_IRUGO, adis16350_read_12bit_signed,
NULL, ADIS16350_ZTEMP_OUT);
-static IIO_CONST_ATTR(temp_scale, "0.0005");
+static IIO_CONST_ATTR_TEMP_SCALE("0.14534");
+static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
static IIO_DEV_ATTR_IN_RAW(0, adis16350_read_12bit_unsigned,
ADIS16350_AUX_ADC);
@@ -529,14 +545,17 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
adis16350_write_reset, 0);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-static IIO_CONST_ATTR(name, "adis16350");
+static IIO_CONST_ATTR_NAME("adis16350");
static struct attribute *adis16350_attributes[] = {
- &iio_dev_attr_accel_x_offset.dev_attr.attr,
- &iio_dev_attr_accel_y_offset.dev_attr.attr,
- &iio_dev_attr_accel_z_offset.dev_attr.attr,
+ &iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
+ &iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_z_calibbias.dev_attr.attr,
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -554,7 +573,7 @@ static struct attribute *adis16350_attributes[] = {
&iio_dev_attr_in0_raw.dev_attr.attr,
&iio_const_attr_in0_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
index e053e9aaa2ed..aefbae589e76 100644
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -17,7 +17,7 @@
#include "../trigger.h"
#include "adis16350.h"
-static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in_supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
ADIS16350_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -41,13 +41,13 @@ static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12),
static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12),
ADIS16350_ZTEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
ADIS16350_AUX_ADC, NULL);
static IIO_SCAN_EL_TIMESTAMP(11);
static struct attribute *adis16350_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_gyro_x.dev_attr.attr,
&iio_scan_el_gyro_y.dev_attr.attr,
&iio_scan_el_gyro_z.dev_attr.attr,
@@ -57,7 +57,7 @@ static struct attribute *adis16350_scan_el_attrs[] = {
&iio_scan_el_temp_x.dev_attr.attr,
&iio_scan_el_temp_y.dev_attr.attr,
&iio_scan_el_temp_z.dev_attr.attr,
- &iio_scan_el_adc_0.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_timestamp.dev_attr.attr,
NULL,
};
@@ -134,11 +134,11 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16350_state *st
= container_of(work_s, struct adis16350_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
+ ring->access.store_to(ring,
+ (u8 *)data,
+ st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
kfree(data);
@@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
struct adis16350_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16350_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -204,11 +188,26 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16350_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/imu/adis16350_trigger.c b/drivers/staging/iio/imu/adis16350_trigger.c
index 76edccc85b71..739b7ecb2e7c 100644
--- a/drivers/staging/iio/imu/adis16350_trigger.c
+++ b/drivers/staging/iio/imu/adis16350_trigger.c
@@ -30,7 +30,7 @@ static int adis16350_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16350_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16350_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 6013fee218e9..5f1643a341cb 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -490,24 +490,24 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
- adis16400_read_12bit_signed,
- adis16400_write_16bit,
- ADIS16400_XACCL_OFF);
+#define ADIS16400_DEV_ATTR_CALIBBIAS(_channel, _reg) \
+ IIO_DEV_ATTR_##_channel##_CALIBBIAS(S_IWUSR | S_IRUGO, \
+ adis16400_read_12bit_signed, \
+ adis16400_write_16bit, \
+ _reg)
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
- adis16400_read_12bit_signed,
- adis16400_write_16bit,
- ADIS16400_YACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_XGYRO_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_XGYRO_OFF);
+
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_XACCL_OFF);
+static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
- adis16400_read_12bit_signed,
- adis16400_write_16bit,
- ADIS16400_ZACCL_OFF);
static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16400_read_14bit_signed,
ADIS16400_SUPPLY_OUT);
-static IIO_CONST_ATTR(in_supply_scale, "0.002418");
+static IIO_CONST_ATTR_IN_NAMED_SCALE(supply, "0.002418 V");
static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed,
ADIS16400_XGYRO_OUT);
@@ -515,7 +515,7 @@ static IIO_DEV_ATTR_GYRO_Y(adis16400_read_14bit_signed,
ADIS16400_YGYRO_OUT);
static IIO_DEV_ATTR_GYRO_Z(adis16400_read_14bit_signed,
ADIS16400_ZGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s");
+static IIO_CONST_ATTR(gyro_scale, "0.0008726646");
static IIO_DEV_ATTR_ACCEL_X(adis16400_read_14bit_signed,
ADIS16400_XACCL_OUT);
@@ -523,7 +523,7 @@ static IIO_DEV_ATTR_ACCEL_Y(adis16400_read_14bit_signed,
ADIS16400_YACCL_OUT);
static IIO_DEV_ATTR_ACCEL_Z(adis16400_read_14bit_signed,
ADIS16400_ZACCL_OUT);
-static IIO_CONST_ATTR(accel_scale, "0.00333 g");
+static IIO_CONST_ATTR(accel_scale, "0.0326561445");
static IIO_DEV_ATTR_MAGN_X(adis16400_read_14bit_signed,
ADIS16400_XMAGN_OUT);
@@ -535,12 +535,12 @@ static IIO_CONST_ATTR(magn_scale, "0.0005 Gs");
static IIO_DEV_ATTR_TEMP_RAW(adis16400_read_12bit_signed);
-static IIO_CONST_ATTR(temp_offset, "198.16 K");
-static IIO_CONST_ATTR(temp_scale, "0.14 K");
+static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
+static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
static IIO_DEV_ATTR_IN_RAW(0, adis16400_read_12bit_unsigned,
ADIS16400_AUX_ADC);
-static IIO_CONST_ATTR(in0_scale, "0.000806");
+static IIO_CONST_ATTR(in0_scale, "0.000806 V");
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
adis16400_read_frequency,
@@ -548,9 +548,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0);
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-static IIO_CONST_ATTR(name, "adis16400");
+static IIO_CONST_ATTR_NAME("adis16400");
static struct attribute *adis16400_event_attributes[] = {
NULL
@@ -561,9 +561,12 @@ static struct attribute_group adis16400_event_attribute_group = {
};
static struct attribute *adis16400_attributes[] = {
- &iio_dev_attr_accel_x_offset.dev_attr.attr,
- &iio_dev_attr_accel_y_offset.dev_attr.attr,
- &iio_dev_attr_accel_z_offset.dev_attr.attr,
+ &iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
+ &iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
+ &iio_dev_attr_accel_z_calibbias.dev_attr.attr,
&iio_dev_attr_in_supply_raw.dev_attr.attr,
&iio_const_attr_in_supply_scale.dev_attr.attr,
&iio_dev_attr_gyro_x_raw.dev_attr.attr,
@@ -584,7 +587,7 @@ static struct attribute *adis16400_attributes[] = {
&iio_dev_attr_in0_raw.dev_attr.attr,
&iio_const_attr_in0_scale.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_reset.dev_attr.attr,
&iio_const_attr_name.dev_attr.attr,
NULL
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 949db76283d7..de5ef5c1cfd0 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -17,7 +17,7 @@
#include "../trigger.h"
#include "adis16400.h"
-static IIO_SCAN_EL_C(supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(in_supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14),
ADIS16400_SUPPLY_OUT, NULL);
static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -43,13 +43,13 @@ static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, IIO_SIGNED(14),
static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, IIO_SIGNED(12),
ADIS16400_TEMP_OUT, NULL);
-static IIO_SCAN_EL_C(adc_0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12),
ADIS16400_AUX_ADC, NULL);
static IIO_SCAN_EL_TIMESTAMP(12);
static struct attribute *adis16400_scan_el_attrs[] = {
- &iio_scan_el_supply.dev_attr.attr,
+ &iio_scan_el_in_supply.dev_attr.attr,
&iio_scan_el_gyro_x.dev_attr.attr,
&iio_scan_el_gyro_y.dev_attr.attr,
&iio_scan_el_gyro_z.dev_attr.attr,
@@ -60,7 +60,7 @@ static struct attribute *adis16400_scan_el_attrs[] = {
&iio_scan_el_magn_y.dev_attr.attr,
&iio_scan_el_magn_z.dev_attr.attr,
&iio_scan_el_temp.dev_attr.attr,
- &iio_scan_el_adc_0.dev_attr.attr,
+ &iio_scan_el_in0.dev_attr.attr,
&iio_scan_el_timestamp.dev_attr.attr,
NULL,
};
@@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
struct adis16400_state *st
= container_of(work_s, struct adis16400_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int i = 0;
s16 *data;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
@@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
- for (; i < st->indio_dev->scan_count; i++)
+ for (; i < ring->scan_count; i++)
data[i] = be16_to_cpup(
(__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
- st->last_timestamp);
+ ring->access.store_to(ring,
+ (u8 *) data,
+ st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
kfree(data);
@@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
struct adis16400_state *st = indio_dev->dev_data;
struct iio_ring_buffer *ring;
INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
- /* Set default scan mode */
-
- iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
- iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
- indio_dev->scan_timestamp = true;
-
- indio_dev->scan_el_attrs = &adis16400_scan_el_group;
ring = iio_sw_rb_allocate(indio_dev);
if (!ring) {
@@ -214,11 +197,27 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
iio_ring_sw_register_funcs(&ring->access);
ring->bpe = 2;
+ ring->scan_el_attrs = &adis16400_scan_el_group;
+ ring->scan_timestamp = true;
ring->preenable = &iio_sw_ring_preenable;
ring->postenable = &iio_triggered_ring_postenable;
ring->predisable = &iio_triggered_ring_predisable;
ring->owner = THIS_MODULE;
+ /* Set default scan mode */
+ iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_magn_x.number);
+ iio_scan_mask_set(ring, iio_scan_el_magn_y.number);
+ iio_scan_mask_set(ring, iio_scan_el_magn_z.number);
+ iio_scan_mask_set(ring, iio_scan_el_temp.number);
+ iio_scan_mask_set(ring, iio_scan_el_in0.number);
+
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
if (ret)
goto error_iio_sw_rb_free;
diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c
index aafe6010f1b1..36b5ff5be983 100644
--- a/drivers/staging/iio/imu/adis16400_trigger.c
+++ b/drivers/staging/iio/imu/adis16400_trigger.c
@@ -30,7 +30,7 @@ static int adis16400_data_rdy_trig_poll(struct iio_dev *dev_info,
IIO_EVENT_SH(data_rdy_trig, &adis16400_data_rdy_trig_poll);
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *adis16400_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index dd4d87a8bcaf..5c35ef8ef5e9 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -29,11 +29,11 @@
#define IIO_ID_FORMAT IIO_ID_PREFIX "%d"
/* IDR to assign each registered device a unique id*/
-static DEFINE_IDR(iio_idr);
+static DEFINE_IDA(iio_ida);
/* IDR to allocate character device minor numbers */
-static DEFINE_IDR(iio_chrdev_idr);
+static DEFINE_IDA(iio_chrdev_ida);
/* Lock used to protect both of the above */
-static DEFINE_SPINLOCK(iio_idr_lock);
+static DEFINE_SPINLOCK(iio_ida_lock);
dev_t iio_devt;
EXPORT_SYMBOL(iio_devt);
@@ -125,19 +125,10 @@ static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
}
time_ns = iio_get_time_ns();
- /* detect single element list*/
- if (list_is_singular(&int_info->ev_list)) {
+ list_for_each_entry(p, &int_info->ev_list, list) {
disable_irq_nosync(irq);
- p = list_first_entry(&int_info->ev_list,
- struct iio_event_handler_list,
- list);
- /* single event handler - maybe shared */
p->handler(dev_info, 1, time_ns, !(p->refcount > 1));
- } else
- list_for_each_entry(p, &int_info->ev_list, list) {
- disable_irq_nosync(irq);
- p->handler(dev_info, 1, time_ns, 0);
- }
+ }
spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
return IRQ_HANDLED;
@@ -349,6 +340,7 @@ static const struct file_operations iio_event_chrdev_fileops = {
.release = iio_event_chrdev_release,
.open = iio_event_chrdev_open,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
static void iio_event_dev_release(struct device *dev)
@@ -367,14 +359,14 @@ int iio_device_get_chrdev_minor(void)
{
int ret, val;
-idr_again:
- if (unlikely(idr_pre_get(&iio_chrdev_idr, GFP_KERNEL) == 0))
+ida_again:
+ if (unlikely(ida_pre_get(&iio_chrdev_ida, GFP_KERNEL) == 0))
return -ENOMEM;
- spin_lock(&iio_idr_lock);
- ret = idr_get_new(&iio_chrdev_idr, NULL, &val);
- spin_unlock(&iio_idr_lock);
+ spin_lock(&iio_ida_lock);
+ ret = ida_get_new(&iio_chrdev_ida, &val);
+ spin_unlock(&iio_ida_lock);
if (unlikely(ret == -EAGAIN))
- goto idr_again;
+ goto ida_again;
else if (unlikely(ret))
return ret;
if (val > IIO_DEV_MAX)
@@ -384,9 +376,9 @@ idr_again:
void iio_device_free_chrdev_minor(int val)
{
- spin_lock(&iio_idr_lock);
- idr_remove(&iio_chrdev_idr, val);
- spin_unlock(&iio_idr_lock);
+ spin_lock(&iio_ida_lock);
+ ida_remove(&iio_chrdev_ida, val);
+ spin_unlock(&iio_ida_lock);
}
int iio_setup_ev_int(struct iio_event_interface *ev_int,
@@ -507,62 +499,49 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
goto error_ret;
}
- if (dev_info->scan_el_attrs) {
- ret = sysfs_create_group(&dev_info->dev.kobj,
- dev_info->scan_el_attrs);
- if (ret)
- dev_err(&dev_info->dev,
- "Failed to add sysfs scan els\n");
- }
-
error_ret:
return ret;
}
static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
{
- if (dev_info->scan_el_attrs)
- sysfs_remove_group(&dev_info->dev.kobj,
- dev_info->scan_el_attrs);
-
sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
}
/* Return a negative errno on failure */
-int iio_get_new_idr_val(struct idr *this_idr)
+int iio_get_new_ida_val(struct ida *this_ida)
{
int ret;
int val;
-idr_again:
- if (unlikely(idr_pre_get(this_idr, GFP_KERNEL) == 0))
+ida_again:
+ if (unlikely(ida_pre_get(this_ida, GFP_KERNEL) == 0))
return -ENOMEM;
- spin_lock(&iio_idr_lock);
- ret = idr_get_new(this_idr, NULL, &val);
- spin_unlock(&iio_idr_lock);
+ spin_lock(&iio_ida_lock);
+ ret = ida_get_new(this_ida, &val);
+ spin_unlock(&iio_ida_lock);
if (unlikely(ret == -EAGAIN))
- goto idr_again;
+ goto ida_again;
else if (unlikely(ret))
return ret;
return val;
}
-EXPORT_SYMBOL(iio_get_new_idr_val);
+EXPORT_SYMBOL(iio_get_new_ida_val);
-void iio_free_idr_val(struct idr *this_idr, int id)
+void iio_free_ida_val(struct ida *this_ida, int id)
{
- spin_lock(&iio_idr_lock);
- idr_remove(this_idr, id);
- spin_unlock(&iio_idr_lock);
+ spin_lock(&iio_ida_lock);
+ ida_remove(this_ida, id);
+ spin_unlock(&iio_ida_lock);
}
-EXPORT_SYMBOL(iio_free_idr_val);
+EXPORT_SYMBOL(iio_free_ida_val);
static int iio_device_register_id(struct iio_dev *dev_info,
- struct idr *this_idr)
+ struct ida *this_ida)
{
-
- dev_info->id = iio_get_new_idr_val(&iio_idr);
+ dev_info->id = iio_get_new_ida_val(&iio_ida);
if (dev_info->id < 0)
return dev_info->id;
return 0;
@@ -570,7 +549,7 @@ static int iio_device_register_id(struct iio_dev *dev_info,
static void iio_device_unregister_id(struct iio_dev *dev_info)
{
- iio_free_idr_val(&iio_idr, dev_info->id);
+ iio_free_ida_val(&iio_ida, dev_info->id);
}
static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
@@ -769,7 +748,7 @@ int iio_device_register(struct iio_dev *dev_info)
{
int ret;
- ret = iio_device_register_id(dev_info, &iio_idr);
+ ret = iio_device_register_id(dev_info, &iio_ida);
if (ret) {
dev_err(&dev_info->dev, "Failed to get id\n");
goto error_ret;
@@ -778,7 +757,7 @@ int iio_device_register(struct iio_dev *dev_info)
ret = device_add(&dev_info->dev);
if (ret)
- goto error_free_idr;
+ goto error_free_ida;
ret = iio_device_register_sysfs(dev_info);
if (ret) {
dev_err(dev_info->dev.parent,
@@ -800,7 +779,7 @@ error_free_sysfs:
iio_device_unregister_sysfs(dev_info);
error_del_device:
device_del(&dev_info->dev);
-error_free_idr:
+error_free_ida:
iio_device_unregister_id(dev_info);
error_ret:
return ret;
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 6ab578e4f5f3..ccf456141cd5 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -15,10 +15,8 @@
*/
#include <linux/kernel.h>
#include <linux/device.h>
-#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/poll.h>
-#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/slab.h>
@@ -53,7 +51,7 @@ int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
EXPORT_SYMBOL(iio_push_or_escallate_ring_event);
/**
- * iio_ring_open() chrdev file open for ring buffer access
+ * iio_ring_open() - chrdev file open for ring buffer access
*
* This function relies on all ring buffer implementations having an
* iio_ring_buffer as their first element.
@@ -72,7 +70,7 @@ static int iio_ring_open(struct inode *inode, struct file *filp)
}
/**
- * iio_ring_release() -chrdev file close ring buffer access
+ * iio_ring_release() - chrdev file close ring buffer access
*
* This function relies on all ring buffer implementations having an
* iio_ring_buffer as their first element.
@@ -91,7 +89,7 @@ static int iio_ring_release(struct inode *inode, struct file *filp)
}
/**
- * iio_ring_rip_outer() chrdev read for ring buffer access
+ * iio_ring_rip_outer() - chrdev read for ring buffer access
*
* This function relies on all ring buffer implementations having an
* iio_ring _bufer as their first element.
@@ -133,11 +131,13 @@ static const struct file_operations iio_ring_fileops = {
.release = iio_ring_release,
.open = iio_ring_open,
.owner = THIS_MODULE,
+ .llseek = noop_llseek,/* read uses no f_pos */
};
/**
- * __iio_request_ring_buffer_event_chrdev() allocate ring event chrdev
+ * __iio_request_ring_buffer_event_chrdev() - allocate ring event chrdev
* @buf: ring buffer whose event chrdev we are allocating
+ * @id: id of this ring buffer (typically 0)
* @owner: the module who owns the ring buffer (for ref counting)
* @dev: device with which the chrdev is associated
**/
@@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
if (ret)
goto error_free_ring_buffer_event_chrdev;
+ if (ring->scan_el_attrs) {
+ ret = sysfs_create_group(&ring->dev.kobj,
+ ring->scan_el_attrs);
+ if (ret) {
+ dev_err(&ring->dev,
+ "Failed to add sysfs scan elements\n");
+ goto error_free_ring_buffer_event_chrdev;
+ }
+ }
+
return ret;
error_free_ring_buffer_event_chrdev:
__iio_free_ring_buffer_event_chrdev(ring);
@@ -291,6 +301,10 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
{
+ if (ring->scan_el_attrs)
+ sysfs_remove_group(&ring->dev.kobj,
+ ring->scan_el_attrs);
+
__iio_free_ring_buffer_access_chrdev(ring);
__iio_free_ring_buffer_event_chrdev(ring);
device_del(&ring->dev);
@@ -338,20 +352,20 @@ EXPORT_SYMBOL(iio_read_ring_length);
}
EXPORT_SYMBOL(iio_write_ring_length);
-ssize_t iio_read_ring_bps(struct device *dev,
+ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int len = 0;
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
- if (ring->access.get_bpd)
+ if (ring->access.get_bytes_per_datum)
len = sprintf(buf, "%d\n",
- ring->access.get_bpd(ring));
+ ring->access.get_bytes_per_datum(ring));
return len;
}
-EXPORT_SYMBOL(iio_read_ring_bps);
+EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
ssize_t iio_store_ring_enable(struct device *dev,
struct device_attribute *attr,
@@ -465,10 +479,10 @@ ssize_t iio_scan_el_show(struct device *dev,
char *buf)
{
int ret;
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct iio_ring_buffer *ring = dev_get_drvdata(dev);
struct iio_scan_el *this_el = to_iio_scan_el(attr);
- ret = iio_scan_mask_query(indio_dev, this_el->number);
+ ret = iio_scan_mask_query(ring, this_el->number);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", ret);
@@ -482,7 +496,8 @@ ssize_t iio_scan_el_store(struct device *dev,
{
int ret = 0;
bool state;
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+ struct iio_dev *indio_dev = ring->indio_dev;
struct iio_scan_el *this_el = to_iio_scan_el(attr);
state = !(buf[0] == '0');
@@ -491,19 +506,17 @@ ssize_t iio_scan_el_store(struct device *dev,
ret = -EBUSY;
goto error_ret;
}
- ret = iio_scan_mask_query(indio_dev, this_el->number);
+ ret = iio_scan_mask_query(ring, this_el->number);
if (ret < 0)
goto error_ret;
if (!state && ret) {
- ret = iio_scan_mask_clear(indio_dev, this_el->number);
+ ret = iio_scan_mask_clear(ring, this_el->number);
if (ret)
goto error_ret;
- indio_dev->scan_count--;
} else if (state && !ret) {
- ret = iio_scan_mask_set(indio_dev, this_el->number);
+ ret = iio_scan_mask_set(ring, this_el->number);
if (ret)
goto error_ret;
- indio_dev->scan_count++;
}
if (this_el->set_state)
ret = this_el->set_state(this_el, indio_dev, state);
@@ -519,8 +532,8 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
+ struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", ring->scan_timestamp);
}
EXPORT_SYMBOL(iio_scan_el_ts_show);
@@ -530,7 +543,8 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
size_t len)
{
int ret = 0;
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+ struct iio_dev *indio_dev = ring->indio_dev;
bool state;
state = !(buf[0] == '0');
mutex_lock(&indio_dev->mlock);
@@ -538,7 +552,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
ret = -EBUSY;
goto error_ret;
}
- indio_dev->scan_timestamp = state;
+ ring->scan_timestamp = state;
error_ret:
mutex_unlock(&indio_dev->mlock);
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index d01445060f51..81b579d371df 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -3,6 +3,16 @@
#
comment "Magnetometer sensors"
+config SENSORS_AK8975
+ tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
+ depends on I2C
+ help
+ Say yes here to build support for Asahi Kasei AK8975 3-Axis
+ Magnetometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ak8975.
+
config SENSORS_HMC5843
tristate "Honeywell HMC5843 3-Axis Magnetometer"
depends on I2C
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
index f9bfb2e11d7d..f2a753f80796 100644
--- a/drivers/staging/iio/magnetometer/Makefile
+++ b/drivers/staging/iio/magnetometer/Makefile
@@ -2,4 +2,5 @@
# Makefile for industrial I/O Magnetometer sensors
#
+obj-$(CONFIG_SENSORS_AK8975) += ak8975.o
obj-$(CONFIG_SENSORS_HMC5843) += hmc5843.o
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
new file mode 100644
index 000000000000..420f206cf517
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -0,0 +1,558 @@
+/*
+ * A sensor driver for the magnetometer AK8975.
+ *
+ * Magnetic compass sensor driver for monitoring magnetic flux information.
+ *
+ * Copyright (c) 2010, NVIDIA 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include <linux/gpio.h>
+
+#include "../iio.h"
+#include "magnet.h"
+
+/*
+ * Register definitions, as well as various shifts and masks to get at the
+ * individual fields of the registers.
+ */
+#define AK8975_REG_WIA 0x00
+#define AK8975_DEVICE_ID 0x48
+
+#define AK8975_REG_INFO 0x01
+
+#define AK8975_REG_ST1 0x02
+#define AK8975_REG_ST1_DRDY_SHIFT 0
+#define AK8975_REG_ST1_DRDY_MASK (1 << AK8975_REG_ST1_DRDY_SHIFT)
+
+#define AK8975_REG_HXL 0x03
+#define AK8975_REG_HXH 0x04
+#define AK8975_REG_HYL 0x05
+#define AK8975_REG_HYH 0x06
+#define AK8975_REG_HZL 0x07
+#define AK8975_REG_HZH 0x08
+#define AK8975_REG_ST2 0x09
+#define AK8975_REG_ST2_DERR_SHIFT 2
+#define AK8975_REG_ST2_DERR_MASK (1 << AK8975_REG_ST2_DERR_SHIFT)
+
+#define AK8975_REG_ST2_HOFL_SHIFT 3
+#define AK8975_REG_ST2_HOFL_MASK (1 << AK8975_REG_ST2_HOFL_SHIFT)
+
+#define AK8975_REG_CNTL 0x0A
+#define AK8975_REG_CNTL_MODE_SHIFT 0
+#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT)
+#define AK8975_REG_CNTL_MODE_POWER_DOWN 0
+#define AK8975_REG_CNTL_MODE_ONCE 1
+#define AK8975_REG_CNTL_MODE_SELF_TEST 8
+#define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF
+
+#define AK8975_REG_RSVC 0x0B
+#define AK8975_REG_ASTC 0x0C
+#define AK8975_REG_TS1 0x0D
+#define AK8975_REG_TS2 0x0E
+#define AK8975_REG_I2CDIS 0x0F
+#define AK8975_REG_ASAX 0x10
+#define AK8975_REG_ASAY 0x11
+#define AK8975_REG_ASAZ 0x12
+
+#define AK8975_MAX_REGS AK8975_REG_ASAZ
+
+/*
+ * Miscellaneous values.
+ */
+#define AK8975_MAX_CONVERSION_TIMEOUT 500
+#define AK8975_CONVERSION_DONE_POLL_TIME 10
+
+/*
+ * Per-instance context data for the device.
+ */
+struct ak8975_data {
+ struct i2c_client *client;
+ struct iio_dev *indio_dev;
+ struct attribute_group attrs;
+ struct mutex lock;
+ u8 asa[3];
+ long raw_to_gauss[3];
+ unsigned long mode;
+ u8 reg_cache[AK8975_MAX_REGS];
+ int eoc_gpio;
+ int eoc_irq;
+};
+
+/*
+ * Helper function to write to the I2C device's registers.
+ */
+static int ak8975_write_data(struct i2c_client *client,
+ u8 reg, u8 val, u8 mask, u8 shift)
+{
+ u8 regval;
+ struct i2c_msg msg;
+ u8 w_data[2];
+ int ret = 0;
+
+ struct ak8975_data *data = i2c_get_clientdata(client);
+
+ regval = data->reg_cache[reg];
+ regval &= ~mask;
+ regval |= val << shift;
+
+ w_data[0] = reg;
+ w_data[1] = regval;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ msg.buf = w_data;
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Write to device fails status %x\n", ret);
+ return ret;
+ }
+ data->reg_cache[reg] = regval;
+
+ return 0;
+}
+
+/*
+ * Helper function to read a contiguous set of the I2C device's registers.
+ */
+static int ak8975_read_data(struct i2c_client *client,
+ u8 reg, u8 length, u8 *buffer)
+{
+ struct i2c_msg msg[2];
+ u8 w_data[2];
+ int ret;
+
+ w_data[0] = reg;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = I2C_M_NOSTART; /* set repeated start and write */
+ msg[0].len = 1;
+ msg[0].buf = w_data;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = length;
+ msg[1].buf = buffer;
+
+ ret = i2c_transfer(client->adapter, msg, 2);
+ if (ret < 0) {
+ dev_err(&client->dev, "Read from device fails\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Perform some start-of-day setup, including reading the asa calibration
+ * values and caching them.
+ */
+static int ak8975_setup(struct i2c_client *client)
+{
+ struct ak8975_data *data = i2c_get_clientdata(client);
+ u8 device_id;
+ int ret;
+
+ /* Confirm that the device we're talking to is really an AK8975. */
+ ret = ak8975_read_data(client, AK8975_REG_WIA, 1, &device_id);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading WIA\n");
+ return ret;
+ }
+ if (device_id != AK8975_DEVICE_ID) {
+ dev_err(&client->dev, "Device ak8975 not found\n");
+ return -ENODEV;
+ }
+
+ /* Write the fused rom access mode. */
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ AK8975_REG_CNTL_MODE_FUSE_ROM,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting fuse access mode\n");
+ return ret;
+ }
+
+ /* Get asa data and store in the device data. */
+ ret = ak8975_read_data(client, AK8975_REG_ASAX, 3, data->asa);
+ if (ret < 0) {
+ dev_err(&client->dev, "Not able to read asa data\n");
+ return ret;
+ }
+
+ /* Precalculate scale factor for each axis and
+ store in the device data. */
+ data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
+ data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
+ data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
+
+ return 0;
+}
+
+/*
+ * Shows the device's mode. 0 = off, 1 = on.
+ */
+static ssize_t show_mode(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ak8975_data *data = indio_dev->dev_data;
+
+ return sprintf(buf, "%lu\n", data->mode);
+}
+
+/*
+ * Sets the device's mode. 0 = off, 1 = on. The device's mode must be on
+ * for the magn raw attributes to be available.
+ */
+static ssize_t store_mode(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ak8975_data *data = indio_dev->dev_data;
+ struct i2c_client *client = data->client;
+ unsigned long oval;
+ int ret;
+
+ /* Convert mode string and do some basic sanity checking on it.
+ only 0 or 1 are valid. */
+ if (strict_strtoul(buf, 10, &oval))
+ return -EINVAL;
+
+ if (oval > 1) {
+ dev_err(dev, "mode value is not supported\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->lock);
+
+ /* Write the mode to the device. */
+ if (data->mode != oval) {
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ (u8)oval,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+ data->mode = oval;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+/*
+ * Emits the scale factor to bring the raw value into Gauss units.
+ *
+ * This scale factor is axis-dependent, and is derived from 3 calibration
+ * factors ASA(x), ASA(y), and ASA(z).
+ *
+ * These ASA values are read from the sensor device at start of day, and
+ * cached in the device context struct.
+ *
+ * Adjusting the flux value with the sensitivity adjustment value should be
+ * done via the following formula:
+ *
+ * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
+ *
+ * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
+ * is the resultant adjusted value.
+ *
+ * We reduce the formula to:
+ *
+ * Hadj = H * (ASA + 128) / 256
+ *
+ * H is in the range of -4096 to 4095. The magnetometer has a range of
+ * +-1229uT. To go from the raw value to uT is:
+ *
+ * HuT = H * 1229/4096, or roughly, 3/10.
+ *
+ * Since 1uT = 100 gauss, our final scale factor becomes:
+ *
+ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
+ * Hadj = H * ((ASA + 128) * 30 / 256
+ *
+ * Since ASA doesn't change, we cache the resultant scale factor into the
+ * device context in ak8975_setup().
+ */
+static ssize_t show_scale(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ak8975_data *data = indio_dev->dev_data;
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr);
+
+ return sprintf(buf, "%ld\n", data->raw_to_gauss[this_attr->address]);
+}
+
+/*
+ * Emits the raw flux value for the x, y, or z axis.
+ */
+static ssize_t show_raw(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ak8975_data *data = indio_dev->dev_data;
+ struct i2c_client *client = data->client;
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr);
+ u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
+ u16 meas_reg;
+ s16 raw;
+ u8 read_status;
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ if (data->mode == 0) {
+ dev_err(&client->dev, "Operating mode is in power down mode\n");
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Set up the device for taking a sample. */
+ ret = ak8975_write_data(client,
+ AK8975_REG_CNTL,
+ AK8975_REG_CNTL_MODE_ONCE,
+ AK8975_REG_CNTL_MODE_MASK,
+ AK8975_REG_CNTL_MODE_SHIFT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in setting operating mode\n");
+ goto exit;
+ }
+
+ /* Wait for the conversion to complete. */
+ while (timeout_ms) {
+ msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+ if (gpio_get_value(data->eoc_gpio))
+ break;
+ timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
+ }
+ if (!timeout_ms) {
+ dev_err(&client->dev, "Conversion timeout happened\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in reading ST1\n");
+ goto exit;
+ }
+
+ if (read_status & AK8975_REG_ST1_DRDY_MASK) {
+ ret = ak8975_read_data(client, AK8975_REG_ST2, 1, &read_status);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in reading ST2\n");
+ goto exit;
+ }
+ if (read_status & (AK8975_REG_ST2_DERR_MASK |
+ AK8975_REG_ST2_HOFL_MASK)) {
+ dev_err(&client->dev, "ST2 status error 0x%x\n",
+ read_status);
+ ret = -EINVAL;
+ goto exit;
+ }
+ }
+
+ /* Read the flux value from the appropriate register
+ (the register is specified in the iio device attributes). */
+ ret = ak8975_read_data(client, this_attr->address, 2, (u8 *)&meas_reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "Read axis data fails\n");
+ goto exit;
+ }
+
+ mutex_unlock(&data->lock);
+
+ /* Endian conversion of the measured values. */
+ raw = (s16) (le16_to_cpu(meas_reg));
+
+ /* Clamp to valid range. */
+ raw = clamp_t(s16, raw, -4096, 4095);
+
+ return sprintf(buf, "%d\n", raw);
+
+exit:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode, 0);
+static IIO_DEV_ATTR_MAGN_X_SCALE(S_IRUGO, show_scale, NULL, 0);
+static IIO_DEV_ATTR_MAGN_Y_SCALE(S_IRUGO, show_scale, NULL, 1);
+static IIO_DEV_ATTR_MAGN_Z_SCALE(S_IRUGO, show_scale, NULL, 2);
+static IIO_DEV_ATTR_MAGN_X(show_raw, AK8975_REG_HXL);
+static IIO_DEV_ATTR_MAGN_Y(show_raw, AK8975_REG_HYL);
+static IIO_DEV_ATTR_MAGN_Z(show_raw, AK8975_REG_HZL);
+
+static struct attribute *ak8975_attr[] = {
+ &iio_dev_attr_mode.dev_attr.attr,
+ &iio_dev_attr_magn_x_scale.dev_attr.attr,
+ &iio_dev_attr_magn_y_scale.dev_attr.attr,
+ &iio_dev_attr_magn_z_scale.dev_attr.attr,
+ &iio_dev_attr_magn_x_raw.dev_attr.attr,
+ &iio_dev_attr_magn_y_raw.dev_attr.attr,
+ &iio_dev_attr_magn_z_raw.dev_attr.attr,
+ NULL
+};
+
+static struct attribute_group ak8975_attr_group = {
+ .attrs = ak8975_attr,
+};
+
+static int ak8975_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ak8975_data *data;
+ int err;
+
+ /* Allocate our device context. */
+ data = kzalloc(sizeof(struct ak8975_data), GFP_KERNEL);
+ if (!data) {
+ dev_err(&client->dev, "Memory allocation fails\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(client, data);
+ data->client = client;
+
+ mutex_init(&data->lock);
+
+ /* Grab and set up the supplied GPIO. */
+ data->eoc_irq = client->irq;
+ data->eoc_gpio = irq_to_gpio(client->irq);
+
+ if (!data->eoc_gpio) {
+ dev_err(&client->dev, "failed, no valid GPIO\n");
+ err = -EINVAL;
+ goto exit_free;
+ }
+
+ err = gpio_request(data->eoc_gpio, "ak_8975");
+ if (err < 0) {
+ dev_err(&client->dev, "failed to request GPIO %d, error %d\n",
+ data->eoc_gpio, err);
+ goto exit_free;
+ }
+
+ err = gpio_direction_input(data->eoc_gpio);
+ if (err < 0) {
+ dev_err(&client->dev, "Failed to configure input direction for"
+ " GPIO %d, error %d\n", data->eoc_gpio, err);
+ goto exit_gpio;
+ }
+
+ /* Perform some basic start-of-day setup of the device. */
+ err = ak8975_setup(client);
+ if (err < 0) {
+ dev_err(&client->dev, "AK8975 initialization fails\n");
+ goto exit_gpio;
+ }
+
+ /* Register with IIO */
+ data->indio_dev = iio_allocate_device();
+ if (data->indio_dev == NULL) {
+ err = -ENOMEM;
+ goto exit_gpio;
+ }
+
+ data->indio_dev->dev.parent = &client->dev;
+ data->indio_dev->attrs = &ak8975_attr_group;
+ data->indio_dev->dev_data = (void *)(data);
+ data->indio_dev->driver_module = THIS_MODULE;
+ data->indio_dev->modes = INDIO_DIRECT_MODE;
+
+ err = iio_device_register(data->indio_dev);
+ if (err < 0)
+ goto exit_free_iio;
+
+ return 0;
+
+exit_free_iio:
+ iio_free_device(data->indio_dev);
+exit_gpio:
+ gpio_free(data->eoc_gpio);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int ak8975_remove(struct i2c_client *client)
+{
+ struct ak8975_data *data = i2c_get_clientdata(client);
+
+ iio_device_unregister(data->indio_dev);
+ iio_free_device(data->indio_dev);
+
+ gpio_free(data->eoc_gpio);
+
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id ak8975_id[] = {
+ {"ak8975", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ak8975_id);
+
+static struct i2c_driver ak8975_driver = {
+ .driver = {
+ .name = "ak8975",
+ },
+ .probe = ak8975_probe,
+ .remove = __devexit_p(ak8975_remove),
+ .id_table = ak8975_id,
+};
+
+static int __init ak8975_init(void)
+{
+ return i2c_add_driver(&ak8975_driver);
+}
+
+static void __exit ak8975_exit(void)
+{
+ i2c_del_driver(&ak8975_driver);
+}
+
+module_init(ak8975_init);
+module_exit(ak8975_exit);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("AK8975 magnetometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 92f6c6fb90fe..51689177e00e 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -95,15 +95,15 @@
#define CONF_NOT_USED 0x03
#define MEAS_CONF_MASK 0x03
-static const int regval_to_counts_per_mg[] = {
- 1620,
- 1300,
- 970,
- 780,
- 530,
- 460,
- 390,
- 280
+static const char *regval_to_scale[] = {
+ "0.0000006173",
+ "0.0000007692",
+ "0.0000010309",
+ "0.0000012821",
+ "0.0000018868",
+ "0.0000021739",
+ "0.0000025641",
+ "0.0000035714",
};
static const int regval_to_input_field_mg[] = {
700,
@@ -220,11 +220,15 @@ static ssize_t hmc5843_set_operating_mode(struct device *dev,
int error;
mutex_lock(&data->lock);
error = strict_strtoul(buf, 10, &operating_mode);
- if (error)
- return error;
+ if (error) {
+ count = error;
+ goto exit;
+ }
dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
- if (operating_mode > MODE_SLEEP)
- return -EINVAL;
+ if (operating_mode > MODE_SLEEP) {
+ count = -EINVAL;
+ goto exit;
+ }
status = i2c_smbus_write_byte_data(client, this_attr->address,
operating_mode);
@@ -322,7 +326,7 @@ static IIO_DEVICE_ATTR(meas_conf,
* 6 | 50
* 7 | Not used
*/
-static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
static s32 hmc5843_set_rate(struct i2c_client *client,
u8 rate)
@@ -385,11 +389,11 @@ static ssize_t show_sampling_frequency(struct device *dev,
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u32 rate;
+ s32 rate;
rate = i2c_smbus_read_byte_data(client, this_attr->address);
if (rate < 0)
- return -EINVAL;
+ return rate;
rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
}
@@ -437,18 +441,23 @@ static ssize_t set_range(struct device *dev,
int error;
mutex_lock(&data->lock);
error = strict_strtoul(buf, 10, &range);
- if (error)
- return error;
+ if (error) {
+ count = error;
+ goto exit;
+ }
dev_dbg(dev, "set range to %lu\n", range);
- if (range > RANGE_6_5)
- return -EINVAL;
+ if (range > RANGE_6_5) {
+ count = -EINVAL;
+ goto exit;
+ }
data->range = range;
range = range << RANGE_GAIN_OFFSET;
if (i2c_smbus_write_byte_data(client, this_attr->address, range))
count = -EINVAL;
+exit:
mutex_unlock(&data->lock);
return count;
@@ -459,17 +468,17 @@ static IIO_DEVICE_ATTR(magn_range,
set_range,
HMC5843_CONFIG_REG_B);
-static ssize_t show_gain(struct device *dev,
+static ssize_t show_scale(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct hmc5843_data *data = indio_dev->dev_data;
- return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
+ return strlen(strcpy(buf, regval_to_scale[data->range]));
}
-static IIO_DEVICE_ATTR(magn_gain,
+static IIO_DEVICE_ATTR(magn_scale,
S_IRUGO,
- show_gain,
+ show_scale,
NULL , 0);
static struct attribute *hmc5843_attributes[] = {
@@ -477,11 +486,11 @@ static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_operating_mode.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_magn_range.dev_attr.attr,
- &iio_dev_attr_magn_gain.dev_attr.attr,
+ &iio_dev_attr_magn_scale.dev_attr.attr,
&iio_dev_attr_magn_x_raw.dev_attr.attr,
&iio_dev_attr_magn_y_raw.dev_attr.attr,
&iio_dev_attr_magn_z_raw.dev_attr.attr,
- &iio_const_attr_available_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
diff --git a/drivers/staging/iio/magnetometer/magnet.h b/drivers/staging/iio/magnetometer/magnet.h
index 64338301f8df..1260eb7bd41e 100644
--- a/drivers/staging/iio/magnetometer/magnet.h
+++ b/drivers/staging/iio/magnetometer/magnet.h
@@ -12,14 +12,14 @@
#define IIO_DEV_ATTR_MAGN_Z_OFFSET(_mode, _show, _store, _addr) \
IIO_DEVICE_ATTR(magn_z_offset, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_MAGN_X_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(magn_x_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_MAGN_X_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(magn_x_scale, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_MAGN_Y_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(magn_y_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_MAGN_Y_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(magn_y_scale, _mode, _show, _store, _addr)
-#define IIO_DEV_ATTR_MAGN_Z_GAIN(_mode, _show, _store, _addr) \
- IIO_DEVICE_ATTR(magn_z_gain, _mode, _show, _store, _addr)
+#define IIO_DEV_ATTR_MAGN_Z_SCALE(_mode, _show, _store, _addr) \
+ IIO_DEVICE_ATTR(magn_z_scale, _mode, _show, _store, _addr)
#define IIO_DEV_ATTR_MAGN_X(_show, _addr) \
IIO_DEVICE_ATTR(magn_x_raw, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index a872d3904a33..7b29cd5a91d2 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -13,9 +13,7 @@
#ifdef CONFIG_IIO_RING_BUFFER
-struct iio_handler;
struct iio_ring_buffer;
-struct iio_dev;
/**
* iio_push_ring_event() - ring buffer specific push to event chrdev
@@ -52,8 +50,8 @@ int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
* change.
* @request_update: if a parameter change has been marked, update underlying
* storage.
- * @get_bpd: get current bytes per datum
- * @set_bpd: set number of bytes per datum
+ * @get_bytes_per_datum:get current bytes per datum
+ * @set_bytes_per_datum:set number of bytes per datum
* @get_length: get number of datums in ring
* @set_length: set number of datums in ring
* @is_enabled: query if ring is currently being used
@@ -81,8 +79,8 @@ struct iio_ring_access_funcs {
int (*mark_param_change)(struct iio_ring_buffer *ring);
int (*request_update)(struct iio_ring_buffer *ring);
- int (*get_bpd)(struct iio_ring_buffer *ring);
- int (*set_bpd)(struct iio_ring_buffer *ring, size_t bpd);
+ int (*get_bytes_per_datum)(struct iio_ring_buffer *ring);
+ int (*set_bytes_per_datum)(struct iio_ring_buffer *ring, size_t bpd);
int (*get_length)(struct iio_ring_buffer *ring);
int (*set_length)(struct iio_ring_buffer *ring, int length);
@@ -99,9 +97,14 @@ struct iio_ring_access_funcs {
* @id: unique id number
* @access_id: device id number
* @length: [DEVICE] number of datums in ring
- * @bpd: [DEVICE] size of individual datum including timestamp
+ * @bytes_per_datum: [DEVICE] size of individual datum including timestamp
* @bpe: [DEVICE] size of individual channel value
* @loopcount: [INTERN] number of times the ring has looped
+ * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
+ * control method is used
+ * @scan_count: [INTERN] the number of elements in the current scan mode
+ * @scan_mask: [INTERN] bitmask used in masking scan mode elements
+ * @scan_timestamp: [INTERN] does the scan mode include a timestamp
* @access_handler: [INTERN] chrdev access handling
* @ev_int: [INTERN] chrdev interface for the event chrdev
* @shared_ev_pointer: [INTERN] the shared event pointer to allow escalation of
@@ -121,9 +124,13 @@ struct iio_ring_buffer {
int id;
int access_id;
int length;
- int bpd;
+ int bytes_per_datum;
int bpe;
int loopcount;
+ struct attribute_group *scan_el_attrs;
+ int scan_count;
+ u32 scan_mask;
+ bool scan_timestamp;
struct iio_handler access_handler;
struct iio_event_interface ev_int;
struct iio_shared_ev_pointer shared_ev_pointer;
@@ -134,6 +141,12 @@ struct iio_ring_buffer {
int (*postdisable)(struct iio_dev *);
};
+
+/**
+ * iio_ring_buffer_init() - Initialize the buffer structure
+ * @ring: buffer to be initialized
+ * @dev_info: the iio device the buffer is assocated with
+ **/
void iio_ring_buffer_init(struct iio_ring_buffer *ring,
struct iio_dev *dev_info);
@@ -146,7 +159,7 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring,
int bytes_per_datum, int length)
{
- ring->bpd = bytes_per_datum;
+ ring->bytes_per_datum = bytes_per_datum;
ring->length = length;
ring->loopcount = 0;
}
@@ -192,7 +205,7 @@ struct iio_scan_el {
ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len);
/**
- * iio_scal_el_show() - sysfs interface to query whether a scan element is
+ * iio_scan_el_show() - sysfs interface to query whether a scan element
* is enabled or not
* @dev: the target device
* @attr: the device attribute that is being processed
@@ -201,9 +214,16 @@ ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr,
ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr,
char *buf);
+/**
+ * iio_scan_el_ts_store() - sysfs interface to set whether a timestamp is included
+ * in the scan.
+ **/
ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len);
-
+/**
+ * iio_scan_el_ts_show() - sysfs interface to query if a timestamp is included
+ * in the scan.
+ **/
ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
char *buf);
/**
@@ -247,6 +267,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
__IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf)
/**
* IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps
+ * @number: specify where in the scan order this is stored.
*
* Odd one out. Handled slightly differently from other scan elements.
**/
@@ -258,6 +279,110 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
iio_scan_el_ts_store), \
}
+/*
+ * These are mainly provided to allow for a change of implementation if a device
+ * has a large number of scan elements
+ */
+#define IIO_MAX_SCAN_LENGTH 31
+
+/* note 0 used as error indicator as it doesn't make sense. */
+static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
+{
+ while (*av_masks) {
+ if (!(~*av_masks & mask))
+ return *av_masks;
+ av_masks++;
+ }
+ return 0;
+}
+
+static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
+{
+ struct iio_dev *dev_info = ring->indio_dev;
+ u32 mask;
+
+ if (bit > IIO_MAX_SCAN_LENGTH)
+ return -EINVAL;
+
+ if (!ring->scan_mask)
+ return 0;
+
+ if (dev_info->available_scan_masks)
+ mask = iio_scan_mask_match(dev_info->available_scan_masks,
+ ring->scan_mask);
+ else
+ mask = ring->scan_mask;
+
+ if (!mask)
+ return -EINVAL;
+
+ return !!(mask & (1 << bit));
+};
+
+/**
+ * iio_scan_mask_set() - set particular bit in the scan mask
+ * @ring: the ring buffer whose scan mask we are interested in
+ * @bit: the bit to be set.
+ **/
+static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
+{
+ struct iio_dev *dev_info = ring->indio_dev;
+ u32 mask;
+ u32 trialmask = ring->scan_mask | (1 << bit);
+
+ if (bit > IIO_MAX_SCAN_LENGTH)
+ return -EINVAL;
+ if (dev_info->available_scan_masks) {
+ mask = iio_scan_mask_match(dev_info->available_scan_masks,
+ trialmask);
+ if (!mask)
+ return -EINVAL;
+ }
+ ring->scan_mask = trialmask;
+ ring->scan_count++;
+
+ return 0;
+};
+
+/**
+ * iio_scan_mask_clear() - clear a particular element from the scan mask
+ * @ring: the ring buffer whose scan mask we are interested in
+ * @bit: the bit to clear
+ **/
+static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
+{
+ if (bit > IIO_MAX_SCAN_LENGTH)
+ return -EINVAL;
+ ring->scan_mask &= ~(1 << bit);
+ ring->scan_count--;
+ return 0;
+};
+
+/**
+ * iio_scan_mask_count_to_right() - how many scan elements occur before here
+ * @ring: the ring buffer whose scan mask we interested in
+ * @bit: which number scan element is this
+ **/
+static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
+ int bit)
+{
+ int count = 0;
+ int mask = (1 << bit);
+ if (bit > IIO_MAX_SCAN_LENGTH)
+ return -EINVAL;
+ while (mask) {
+ mask >>= 1;
+ if (mask & ring->scan_mask)
+ count++;
+ }
+
+ return count;
+}
+
+/**
+ * iio_put_ring_buffer() - notify done with buffer
+ * @ring: the buffer we are done with.
+ **/
static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
{
put_device(&ring->dev);
@@ -267,32 +392,58 @@ static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
container_of(d, struct iio_ring_buffer, dev)
#define access_dev_to_iio_ring_buffer(d) \
container_of(d, struct iio_ring_buffer, access_dev)
+
+/**
+ * iio_ring_buffer_register() - register the buffer with IIO core
+ * @ring: the buffer to be registered
+ * @id: the id of the buffer (typically 0)
+ **/
int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id);
+
+/**
+ * iio_ring_buffer_unregister() - unregister the buffer from IIO core
+ * @ring: the buffer to be unregistered
+ **/
void iio_ring_buffer_unregister(struct iio_ring_buffer *ring);
+/**
+ * iio_read_ring_length() - attr func to get number of datums in the buffer
+ **/
ssize_t iio_read_ring_length(struct device *dev,
struct device_attribute *attr,
char *buf);
+/**
+ * iio_write_ring_length() - attr func to set number of datums in the buffer
+ **/
ssize_t iio_write_ring_length(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len);
-ssize_t iio_read_ring_bps(struct device *dev,
+/**
+ * iio_read_ring_bytes_per_datum() - attr for number of bytes in whole datum
+ **/
+ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
struct device_attribute *attr,
char *buf);
+/**
+ * iio_store_ring_enable() - attr to turn the buffer on
+ **/
ssize_t iio_store_ring_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len);
+/**
+ * iio_show_ring_enable() - attr to see if the buffer is on
+ **/
ssize_t iio_show_ring_enable(struct device *dev,
struct device_attribute *attr,
char *buf);
#define IIO_RING_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \
iio_read_ring_length, \
iio_write_ring_length)
-#define IIO_RING_BPS_ATTR DEVICE_ATTR(bps, S_IRUGO | S_IWUSR, \
- iio_read_ring_bps, NULL)
-#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(ring_enable, S_IRUGO | S_IWUSR, \
+#define IIO_RING_BYTES_PER_DATUM_ATTR DEVICE_ATTR(bytes_per_datum, S_IRUGO | S_IWUSR, \
+ iio_read_ring_bytes_per_datum, NULL)
+#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
iio_show_ring_enable, \
iio_store_ring_enable)
#else /* CONFIG_IIO_RING_BUFFER */
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index e2f01c640baf..52624ace0bc5 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -21,7 +21,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
if ((length == 0) || (bytes_per_datum == 0))
return -EINVAL;
__iio_update_ring_buffer(&ring->buf, bytes_per_datum, length);
- ring->data = kmalloc(length*ring->buf.bpd, GFP_ATOMIC);
+ ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC);
ring->read_p = NULL;
ring->write_p = NULL;
ring->last_written_p = NULL;
@@ -77,10 +77,10 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
* as long as the read pointer is valid before this
* passes it - guaranteed as set later in this function.
*/
- ring->half_p = ring->data - ring->buf.length*ring->buf.bpd/2;
+ ring->half_p = ring->data - ring->buf.length*ring->buf.bytes_per_datum/2;
}
/* Copy data to where ever the current write pointer says */
- memcpy(ring->write_p, data, ring->buf.bpd);
+ memcpy(ring->write_p, data, ring->buf.bytes_per_datum);
barrier();
/* Update the pointer used to get most recent value.
* Always valid as either points to latest or second latest value.
@@ -91,9 +91,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
/* temp_ptr used to ensure we never have an invalid pointer
* it may be slightly lagging, but never invalid
*/
- temp_ptr = ring->write_p + ring->buf.bpd;
+ temp_ptr = ring->write_p + ring->buf.bytes_per_datum;
/* End of ring, back to the beginning */
- if (temp_ptr == ring->data + ring->buf.length*ring->buf.bpd)
+ if (temp_ptr == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
temp_ptr = ring->data;
/* Update the write pointer
* always valid as long as this is the only function able to write.
@@ -112,9 +112,9 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
*/
else if (ring->write_p == ring->read_p) {
change_test_ptr = ring->read_p;
- temp_ptr = change_test_ptr + ring->buf.bpd;
+ temp_ptr = change_test_ptr + ring->buf.bytes_per_datum;
if (temp_ptr
- == ring->data + ring->buf.length*ring->buf.bpd) {
+ == ring->data + ring->buf.length*ring->buf.bytes_per_datum) {
temp_ptr = ring->data;
}
/* We are moving pointer on one because the ring is full. Any
@@ -135,8 +135,8 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
/* There are definite 'issues' with this and chances of
* simultaneous read */
/* Also need to use loop count to ensure this only happens once */
- ring->half_p += ring->buf.bpd;
- if (ring->half_p == ring->data + ring->buf.length*ring->buf.bpd)
+ ring->half_p += ring->buf.bytes_per_datum;
+ if (ring->half_p == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
ring->half_p = ring->data;
if (ring->half_p == ring->read_p) {
spin_lock(&ring->buf.shared_ev_pointer.lock);
@@ -164,15 +164,15 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
* read something that is not a whole number of bpds.
* Return an error.
*/
- if (count % ring->buf.bpd) {
+ if (count % ring->buf.bytes_per_datum) {
ret = -EINVAL;
printk(KERN_INFO "Ring buffer read request not whole number of"
- "samples: Request bytes %zd, Current bpd %d\n",
- count, ring->buf.bpd);
+ "samples: Request bytes %zd, Current bytes per datum %d\n",
+ count, ring->buf.bytes_per_datum);
goto error_ret;
}
/* Limit size to whole of ring buffer */
- bytes_to_rip = min((size_t)(ring->buf.bpd*ring->buf.length), count);
+ bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), count);
*data = kmalloc(bytes_to_rip, GFP_KERNEL);
if (*data == NULL) {
@@ -214,7 +214,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
} else {
/* going through 'end' of ring buffer */
max_copied = ring->data
- + ring->buf.length*ring->buf.bpd - initial_read_p;
+ + ring->buf.length*ring->buf.bytes_per_datum - initial_read_p;
memcpy(*data, initial_read_p, max_copied);
/* possible we are done if we align precisely with end */
if (max_copied == bytes_to_rip)
@@ -240,7 +240,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r,
if (initial_read_p <= current_read_p)
*dead_offset = current_read_p - initial_read_p;
else
- *dead_offset = ring->buf.length*ring->buf.bpd
+ *dead_offset = ring->buf.length*ring->buf.bytes_per_datum
- (initial_read_p - current_read_p);
/* possible issue if the initial write has been lapped or indeed
@@ -293,7 +293,7 @@ again:
/* Check there is anything here */
if (last_written_p_copy == NULL)
return -EAGAIN;
- memcpy(data, last_written_p_copy, ring->buf.bpd);
+ memcpy(data, last_written_p_copy, ring->buf.bytes_per_datum);
if (unlikely(ring->last_written_p != last_written_p_copy))
goto again;
@@ -322,7 +322,7 @@ int iio_request_update_sw_rb(struct iio_ring_buffer *r)
goto error_ret;
}
__iio_free_sw_ring_buffer(ring);
- ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bpd,
+ ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bytes_per_datum,
ring->buf.length);
error_ret:
spin_unlock(&ring->use_lock);
@@ -330,23 +330,23 @@ error_ret:
}
EXPORT_SYMBOL(iio_request_update_sw_rb);
-int iio_get_bpd_sw_rb(struct iio_ring_buffer *r)
+int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
{
struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
- return ring->buf.bpd;
+ return ring->buf.bytes_per_datum;
}
-EXPORT_SYMBOL(iio_get_bpd_sw_rb);
+EXPORT_SYMBOL(iio_get_bytes_per_datum_sw_rb);
-int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd)
+int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
{
- if (r->bpd != bpd) {
- r->bpd = bpd;
+ if (r->bytes_per_datum != bpd) {
+ r->bytes_per_datum = bpd;
if (r->access.mark_param_change)
r->access.mark_param_change(r);
}
return 0;
}
-EXPORT_SYMBOL(iio_set_bpd_sw_rb);
+EXPORT_SYMBOL(iio_set_bytes_per_datum_sw_rb);
int iio_get_length_sw_rb(struct iio_ring_buffer *r)
{
@@ -380,14 +380,14 @@ static void iio_sw_rb_release(struct device *dev)
}
static IIO_RING_ENABLE_ATTR;
-static IIO_RING_BPS_ATTR;
+static IIO_RING_BYTES_PER_DATUM_ATTR;
static IIO_RING_LENGTH_ATTR;
/* Standard set of ring buffer attributes */
static struct attribute *iio_ring_attributes[] = {
&dev_attr_length.attr,
- &dev_attr_bps.attr,
- &dev_attr_ring_enable.attr,
+ &dev_attr_bytes_per_datum.attr,
+ &dev_attr_enable.attr,
NULL,
};
@@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
int iio_sw_ring_preenable(struct iio_dev *indio_dev)
{
+ struct iio_ring_buffer *ring = indio_dev->ring;
size_t size;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
/* Check if there are any scan elements enabled, if not fail*/
- if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
+ if (!(ring->scan_count || ring->scan_timestamp))
return -EINVAL;
- if (indio_dev->scan_timestamp)
- if (indio_dev->scan_count)
+ if (ring->scan_timestamp)
+ if (ring->scan_count)
/* Timestamp (aligned to s64) and data */
- size = (((indio_dev->scan_count * indio_dev->ring->bpe)
+ size = (((ring->scan_count * ring->bpe)
+ sizeof(s64) - 1)
& ~(sizeof(s64) - 1))
+ sizeof(s64);
else /* Timestamp only */
size = sizeof(s64);
else /* Data only */
- size = indio_dev->scan_count * indio_dev->ring->bpe;
- indio_dev->ring->access.set_bpd(indio_dev->ring, size);
+ size = ring->scan_count * ring->bpe;
+ ring->access.set_bytes_per_datum(ring, size);
return 0;
}
@@ -462,9 +463,9 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
struct iio_sw_ring_helper_state *st
= container_of(work_s, struct iio_sw_ring_helper_state,
work_trigger_to_ring);
+ struct iio_ring_buffer *ring = st->indio_dev->ring;
int len = 0;
- size_t datasize = st->indio_dev
- ->ring->access.get_bpd(st->indio_dev->ring);
+ size_t datasize = ring->access.get_bytes_per_datum(ring);
char *data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
@@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
return;
}
- if (st->indio_dev->scan_count)
+ if (ring->scan_count)
len = st->get_ring_element(st, data);
/* Guaranteed to be aligned with 8 byte boundary */
- if (st->indio_dev->scan_timestamp)
+ if (ring->scan_timestamp)
*(s64 *)(((phys_addr_t)data + len
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
= st->last_timestamp;
- st->indio_dev->ring->access.store_to(st->indio_dev->ring,
- (u8 *)data,
+ ring->access.store_to(ring,
+ (u8 *)data,
st->last_timestamp);
iio_trigger_notify_done(st->indio_dev->trig);
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index 61f1ed650392..ad03d832c1b9 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -121,19 +121,19 @@ int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
/**
- * iio_get_bpd_sw_rb() - get the datum size in bytes
+ * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes
* @r: pointer to a software ring buffer created by an
* iio_create_sw_rb call
**/
-int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
+int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r);
/**
- * iio_set_bpd_sw_rb() - set the datum size in bytes
+ * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes
* @r: pointer to a software ring buffer created by an
* iio_create_sw_rb call
* @bpd: bytes per datum value
**/
-int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
+int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd);
/**
* iio_get_length_sw_rb() - get how many datums the rb may contain
@@ -166,8 +166,8 @@ static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
ra->mark_param_change = &iio_mark_update_needed_sw_rb;
ra->request_update = &iio_request_update_sw_rb;
- ra->get_bpd = &iio_get_bpd_sw_rb;
- ra->set_bpd = &iio_set_bpd_sw_rb;
+ ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb;
+ ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb;
ra->get_length = &iio_get_length_sw_rb;
ra->set_length = &iio_set_length_sw_rb;
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 60834162eb32..b531dc1db4f1 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -30,27 +30,6 @@ struct iio_event_attr {
container_of(_dev_attr, struct iio_event_attr, dev_attr)
/**
- * struct iio_chrdev_minor_attr - simple attribute to allow reading of chrdev
- * minor number
- * @dev_attr: underlying device attribute
- * @minor: the minor number
- */
-struct iio_chrdev_minor_attr {
- struct device_attribute dev_attr;
- int minor;
-};
-
-void
-__init_iio_chrdev_minor_attr(struct iio_chrdev_minor_attr *minor_attr,
- const char *name,
- struct module *owner,
- int id);
-
-
-#define to_iio_chrdev_minor_attr(_dev_attr) \
- container_of(_dev_attr, struct iio_chrdev_minor_attr, dev_attr);
-
-/**
* struct iio_dev_attr - iio specific device attribute
* @dev_attr: underlying device attribute
* @address: associated register address
@@ -89,11 +68,6 @@ struct iio_const_attr {
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.address = _addr }
-#define IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2) \
- { .dev_attr = __ATTR(_name, _mode, _show, _store), \
- .address = _addr, \
- .val2 = _val2 }
-
#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \
struct iio_dev_attr iio_dev_attr_##_name \
= IIO_ATTR(_name, _mode, _show, _store, _addr)
@@ -130,6 +104,13 @@ struct iio_const_attr {
IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
/**
+ * IIO_CONST_ATTR_NAME - constant identifier
+ * @_string: the name
+ **/
+#define IIO_CONST_ATTR_NAME(_string) \
+ IIO_CONST_ATTR(name, _string)
+
+/**
* IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency
* @_mode: sysfs file mode/permissions
* @_show: output method for the attribute
@@ -156,48 +137,10 @@ struct iio_const_attr {
*
* Constant version
**/
-/* Deprecated */
-#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string) \
- IIO_CONST_ATTR(available_sampling_frequency, _string)
-
#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \
IIO_CONST_ATTR(sampling_frequency_available, _string)
/**
- * IIO_DEV_ATTR_SCAN_MODE - select a scan mode
- * @_mode: sysfs file mode/permissions
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- *
- * This is used when only certain combinations of inputs may be read in one
- * scan.
- **/
-#define IIO_DEV_ATTR_SCAN_MODE(_mode, _show, _store) \
- IIO_DEVICE_ATTR(scan_mode, _mode, _show, _store, 0)
-
-/**
- * IIO_DEV_ATTR_AVAIL_SCAN_MODES - list available scan modes
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_AVAIL_SCAN_MODES(_show) \
- IIO_DEVICE_ATTR(available_scan_modes, S_IRUGO, _show, NULL, 0)
-
-/**
- * IIO_DEV_ATTR_SCAN - result of scan of multiple channels
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_SCAN(_show) \
- IIO_DEVICE_ATTR(scan, S_IRUGO, _show, NULL, 0);
-
-/**
- * IIO_DEV_ATTR_INPUT - direct read of a single input channel
- * @_number: input channel number
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_INPUT(_number, _show) \
- IIO_DEVICE_ATTR(in##_number, S_IRUGO, _show, NULL, _number)
-
-/**
* IIO_DEV_ATTR_SW_RING_ENABLE - enable software ring buffer
* @_show: output method for the attribute
* @_store: input method for the attribute
@@ -218,32 +161,15 @@ struct iio_const_attr {
#define IIO_DEV_ATTR_HW_RING_ENABLE(_show, _store) \
IIO_DEVICE_ATTR(hw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0)
-/**
- * IIO_DEV_ATTR_BPSE - set number of bits per scan element
- * @_mode: sysfs file mode/permissions
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- **/
-#define IIO_DEV_ATTR_BPSE(_mode, _show, _store) \
- IIO_DEVICE_ATTR(bpse, _mode, _show, _store, 0)
-
-/**
- * IIO_DEV_ATTR_BPSE_AVAILABLE - number of bits per scan element supported
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_BPSE_AVAILABLE(_show) \
- IIO_DEVICE_ATTR(bpse_available, S_IRUGO, _show, NULL, 0)
-
-/**
- * IIO_DEV_ATTR_TEMP - many sensors have auxiliary temperature sensors
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_TEMP(_show) \
- IIO_DEVICE_ATTR(temp, S_IRUGO, _show, NULL, 0)
-
#define IIO_DEV_ATTR_TEMP_RAW(_show) \
IIO_DEVICE_ATTR(temp_raw, S_IRUGO, _show, NULL, 0)
+#define IIO_CONST_ATTR_TEMP_OFFSET(_string) \
+ IIO_CONST_ATTR(temp_offset, _string)
+
+#define IIO_CONST_ATTR_TEMP_SCALE(_string) \
+ IIO_CONST_ATTR(temp_scale, _string)
+
/**
* IIO_EVENT_SH - generic shared event handler
* @_name: event name
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 4699586a5931..469beba3e71d 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -152,7 +152,7 @@ int iio_alloc_pollfunc(struct iio_dev *indio_dev,
/*
* Two functions for common case where all that happens is a pollfunc
- * is attached and detached form a trigger
+ * is attached and detached from a trigger
*/
int iio_triggered_ring_postenable(struct iio_dev *indio_dev);
int iio_triggered_ring_predisable(struct iio_dev *indio_dev);
@@ -161,8 +161,4 @@ struct iio_trigger *iio_allocate_trigger(void);
void iio_free_trigger(struct iio_trigger *trig);
-
-struct iio_simple_trigger {
- struct iio_trigger trig;
-};
#endif /* _IIO_TRIGGER_H_ */
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
index f93cc9169832..2ce95e964cfd 100644
--- a/drivers/staging/iio/trigger/iio-trig-gpio.c
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -47,7 +47,7 @@ static irqreturn_t iio_gpio_trigger_poll(int irq, void *private)
return IRQ_HANDLED;
}
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+static IIO_TRIGGER_NAME_ATTR;
static struct attribute *iio_gpio_trigger_attrs[] = {
&dev_attr_name.attr,
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index b0b52f84edfd..24f174e1cda5 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -72,17 +72,7 @@ error_ret:
return ret;
}
-static ssize_t iio_trig_periodic_read_name(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_trigger *trig = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", trig->name);
-}
-
-static DEVICE_ATTR(name, S_IRUGO,
- iio_trig_periodic_read_name,
- NULL);
+static IIO_TRIGGER_NAME_ATTR;
static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR,
iio_trig_periodic_read_freq,
iio_trig_periodic_write_freq);
diff --git a/drivers/staging/keucr/Kconfig b/drivers/staging/keucr/Kconfig
new file mode 100644
index 000000000000..ff42d7ed853e
--- /dev/null
+++ b/drivers/staging/keucr/Kconfig
@@ -0,0 +1,13 @@
+config USB_ENESTORAGE
+ tristate "USB ENE card reader support"
+ depends on USB && SCSI
+ ---help---
+ Say Y here if you wish to control a ENE Card reader.
+
+ This option depends on 'SCSI' support being enabled, but you
+ probably also need 'SCSI device support: SCSI disk support'
+ (BLK_DEV_SD) for most USB storage devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called keucr.
+
diff --git a/drivers/staging/keucr/Makefile b/drivers/staging/keucr/Makefile
new file mode 100644
index 000000000000..2a4200f019d2
--- /dev/null
+++ b/drivers/staging/keucr/Makefile
@@ -0,0 +1,16 @@
+EXTRA_CFLAGS += -Idrivers/scsi
+
+obj-$(CONFIG_USB_ENESTORAGE) += keucr.o
+
+keucr-objs := \
+ usb.o \
+ scsiglue.o \
+ transport.o \
+ init.o \
+ sdscsi.o \
+ msscsi.o \
+ ms.o \
+ smscsi.o \
+ smilmain.o \
+ smilsub.o \
+ smilecc.o
diff --git a/drivers/staging/keucr/Module.symvers b/drivers/staging/keucr/Module.symvers
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/drivers/staging/keucr/Module.symvers
diff --git a/drivers/staging/keucr/TODO b/drivers/staging/keucr/TODO
new file mode 100644
index 000000000000..4e39e03f5796
--- /dev/null
+++ b/drivers/staging/keucr/TODO
@@ -0,0 +1,11 @@
+TODO:
+ - checkpatch.pl clean
+ - sparse clean
+ - determine if the driver should not be using a duplicate
+ version of the usb-storage scsi interface code, but should
+ be merged into the drivers/usb/storage/ directory and
+ infrastructure instead.
+ - review by the USB developer community
+
+Please send any patches for this driver to Al Cho <acho@novell.com> and
+Greg Kroah-Hartman <gregkh@suse.de>.
diff --git a/drivers/staging/keucr/common.h b/drivers/staging/keucr/common.h
new file mode 100644
index 000000000000..8693c54f76d0
--- /dev/null
+++ b/drivers/staging/keucr/common.h
@@ -0,0 +1,26 @@
+#ifndef COMMON_INCD
+#define COMMON_INCD
+
+typedef void VOID;
+typedef u8 BOOLEAN;
+typedef u8 BYTE;
+typedef u8 *PBYTE;
+typedef u16 WORD;
+typedef u16 *PWORD;
+typedef u32 DWORD;
+typedef u32 *PDWORD;
+
+#define swapWORD(w) ((((unsigned short)(w) << 8) & 0xff00) | \
+ (((unsigned short)(w) >> 8) & 0x00ff))
+#define swapDWORD(dw) ((((unsigned long)(dw) << 24) & 0xff000000) | \
+ (((unsigned long)(dw) << 8) & 0x00ff0000) | \
+ (((unsigned long)(dw) >> 8) & 0x0000ff00) | \
+ (((unsigned long)(dw) >> 24) & 0x000000ff))
+
+#define LittleEndianWORD(w) (w)
+#define LittleEndianDWORD(dw) (dw)
+#define BigEndianWORD(w) swapWORD(w)
+#define BigEndianDWORD(dw) swapDWORD(dw)
+
+#endif
+
diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c
new file mode 100644
index 000000000000..2ae129bfb608
--- /dev/null
+++ b/drivers/staging/keucr/init.c
@@ -0,0 +1,541 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+#include "init.h"
+
+BYTE IsSSFDCCompliance;
+BYTE IsXDCompliance;
+extern DWORD MediaChange;
+extern int Check_D_MediaFmt(struct us_data *);
+
+//----- ENE_InitMedia() ----------------------------------------
+int ENE_InitMedia(struct us_data *us)
+{
+ int result;
+ BYTE MiscReg03 = 0;
+
+ printk("--- Initial Nedia ---\n");
+ result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Read register fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ printk("MiscReg03 = %x\n", MiscReg03);
+
+ if (MiscReg03 & 0x01)
+ {
+ if (!us->SD_Status.Ready)
+ {
+ result = ENE_SDInit(us);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ }
+
+ if (MiscReg03 & 0x02)
+ {
+ if (!us->SM_Status.Ready && !us->MS_Status.Ready)
+ {
+ result = ENE_SMInit(us);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ result = ENE_MSInit(us);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ }
+
+ }
+ return result;
+}
+
+//----- ENE_Read_BYTE() ----------------------------------------
+int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x01;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xED;
+ bcb->CDB[2] = (BYTE)(index>>8);
+ bcb->CDB[3] = (BYTE)index;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
+ return result;
+}
+
+//----- ENE_SDInit() ---------------------
+int ENE_SDInit(struct us_data *us)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ BYTE buf[0x200];
+
+ printk("transport --- ENE_SDInit\n");
+ // SD Init Part-1
+ result = ENE_LoadBinCode(us, SD_INIT1_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SD Init Code Part-1 Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF2;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Exection SD Init Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ // SD Init Part-2
+ result = ENE_LoadBinCode(us, SD_INIT2_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SD Init Code Part-2 Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Exection SD Init Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ us->SD_Status = *(PSD_STATUS)&buf[0];
+ if (us->SD_Status.Insert && us->SD_Status.Ready)
+ {
+ ENE_ReadSDReg(us, (PBYTE)&buf);
+ printk("Insert = %x\n", us->SD_Status.Insert);
+ printk("Ready = %x\n", us->SD_Status.Ready);
+ printk("IsMMC = %x\n", us->SD_Status.IsMMC);
+ printk("HiCapacity = %x\n", us->SD_Status.HiCapacity);
+ printk("HiSpeed = %x\n", us->SD_Status.HiSpeed);
+ printk("WtP = %x\n", us->SD_Status.WtP);
+ }
+ else
+ {
+ printk("SD Card Not Ready --- %x\n", buf[0]);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_MSInit() ----------------------------------------
+int ENE_MSInit(struct us_data *us)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ BYTE buf[0x200];
+ WORD MSP_BlockSize, MSP_UserAreaBlocks;
+
+
+ printk("transport --- ENE_MSInit\n");
+ result = ENE_LoadBinCode(us, MS_INIT_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load MS Init Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x01;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Exection MS Init Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ us->MS_Status = *(PMS_STATUS)&buf[0];
+
+ if (us->MS_Status.Insert && us->MS_Status.Ready)
+ {
+ printk("Insert = %x\n", us->MS_Status.Insert);
+ printk("Ready = %x\n", us->MS_Status.Ready);
+ printk("IsMSPro = %x\n", us->MS_Status.IsMSPro);
+ printk("IsMSPHG = %x\n", us->MS_Status.IsMSPHG);
+ printk("WtP = %x\n", us->MS_Status.WtP);
+ if (us->MS_Status.IsMSPro)
+ {
+ MSP_BlockSize = (buf[6] <<8) | buf[7];
+ MSP_UserAreaBlocks = (buf[10]<<8) | buf[11];
+ us->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
+ }
+ else
+ MS_CardInit(us);
+ printk("MS Init Code OK !!\n");
+ }
+ else
+ {
+ printk("MS Card Not Ready --- %x\n", buf[0]);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_SMInit() ----------------------------------------
+int ENE_SMInit(struct us_data *us)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ BYTE buf[0x200];
+
+ printk("transport --- ENE_SMInit\n");
+
+ result = ENE_LoadBinCode(us, SM_INIT_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM Init Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x01;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Exection SM Init Code Fail !! result = %x\n", result);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ us->SM_Status = *(PSM_STATUS)&buf[0];
+
+ us->SM_DeviceID = buf[1];
+ us->SM_CardID = buf[2];
+
+ if (us->SM_Status.Insert && us->SM_Status.Ready)
+ {
+ printk("Insert = %x\n", us->SM_Status.Insert);
+ printk("Ready = %x\n", us->SM_Status.Ready);
+ printk("WtP = %x\n", us->SM_Status.WtP);
+ printk("DeviceID = %x\n", us->SM_DeviceID);
+ printk("CardID = %x\n", us->SM_CardID);
+ MediaChange = 1;
+ Check_D_MediaFmt(us);
+ }
+ else
+ {
+ printk("SM Card Not Ready --- %x\n", buf[0]);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_ReadSDReg() ----------------------------------------------
+int ENE_ReadSDReg(struct us_data *us, u8 *RdBuf)
+{
+ WORD tmpreg;
+ DWORD reg4b;
+
+ //printk("transport --- ENE_ReadSDReg\n");
+ reg4b = *(PDWORD)&RdBuf[0x18];
+ us->SD_READ_BL_LEN = (BYTE)((reg4b >> 8) & 0x0f);
+
+ tmpreg = (WORD) reg4b;
+ reg4b = *(PDWORD)(&RdBuf[0x14]);
+ if (us->SD_Status.HiCapacity && !us->SD_Status.IsMMC)
+ us->HC_C_SIZE = (reg4b >> 8) & 0x3fffff;
+
+ us->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (WORD)(reg4b >> 22);
+ us->SD_C_SIZE_MULT = (BYTE)(reg4b >> 7) & 0x07;
+ if (us->SD_Status.HiCapacity && us->SD_Status.IsMMC)
+ us->HC_C_SIZE = *(PDWORD)(&RdBuf[0x100]);
+
+ if (us->SD_READ_BL_LEN > SD_BLOCK_LEN)
+ {
+ us->SD_Block_Mult = 1 << (us->SD_READ_BL_LEN - SD_BLOCK_LEN); us->SD_READ_BL_LEN = SD_BLOCK_LEN;
+ }
+ else
+ { us->SD_Block_Mult = 1;
+ }
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_LoadBinCode() ---------------------
+int ENE_LoadBinCode(struct us_data *us, BYTE flag)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ //void *buf;
+ PBYTE buf;
+
+ //printk("transport --- ENE_LoadBinCode\n");
+ if (us->BIN_FLAG == flag)
+ return USB_STOR_TRANSPORT_GOOD;
+
+ buf = kmalloc(0x800, GFP_KERNEL);
+ switch ( flag )
+ {
+ // For SD
+ case SD_INIT1_PATTERN:
+ printk("SD_INIT1_PATTERN\n");
+ memcpy(buf, SD_Init1, 0x800);
+ break;
+ case SD_INIT2_PATTERN:
+ printk("SD_INIT2_PATTERN\n");
+ memcpy(buf, SD_Init2, 0x800);
+ break;
+ case SD_RW_PATTERN:
+ printk("SD_RW_PATTERN\n");
+ memcpy(buf, SD_Rdwr, 0x800);
+ break;
+ // For MS
+ case MS_INIT_PATTERN:
+ printk("MS_INIT_PATTERN\n");
+ memcpy(buf, MS_Init, 0x800);
+ break;
+ case MSP_RW_PATTERN:
+ printk("MSP_RW_PATTERN\n");
+ memcpy(buf, MSP_Rdwr, 0x800);
+ break;
+ case MS_RW_PATTERN:
+ printk("MS_RW_PATTERN\n");
+ memcpy(buf, MS_Rdwr, 0x800);
+ break;
+ // For SS
+ case SM_INIT_PATTERN:
+ printk("SM_INIT_PATTERN\n");
+ memcpy(buf, SM_Init, 0x800);
+ break;
+ case SM_RW_PATTERN:
+ printk("SM_RW_PATTERN\n");
+ memcpy(buf, SM_Rdwr, 0x800);
+ break;
+ }
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x800;
+ bcb->Flags =0x00;
+ bcb->CDB[0] = 0xEF;
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
+
+ kfree(buf);
+ us->BIN_FLAG = flag;
+ return result;
+}
+
+//----- ENE_SendScsiCmd() ---------------------
+int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
+
+ int result;
+ unsigned int transfer_length=bcb->DataTransferLength, cswlen=0, partial=0;
+ unsigned int residue;
+
+ //printk("transport --- ENE_SendScsiCmd\n");
+ // send cmd to out endpoint
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("send cmd to out endpoint fail ---\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ if (buf)
+ {
+ unsigned int pipe = fDir == FDIR_READ ? us->recv_bulk_pipe : us->send_bulk_pipe;
+ // Bulk
+ if (use_sg)
+ result = usb_stor_bulk_srb(us, pipe, us->srb);
+ else
+ result = usb_stor_bulk_transfer_sg(us, pipe, buf, transfer_length, 0, &partial);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("data transfer fail ---\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ }
+
+ // Get CSW for device status
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+
+ if (result == USB_STOR_XFER_SHORT && cswlen == 0)
+ {
+ printk("Received 0-length CSW; retrying...\n");
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+ }
+
+ if (result == USB_STOR_XFER_STALLED)
+ {
+ /* get the status again */
+ printk("Attempting to get CSW (2nd try)...\n");
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL);
+ }
+
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ /* check bulk status */
+ residue = le32_to_cpu(bcs->Residue);
+
+ /* try to compute the actual residue, based on how much data
+ * was really transferred and what the device tells us */
+ if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE))
+ {
+ residue = min(residue, transfer_length);
+ scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), (int) residue));
+ }
+
+ if (bcs->Status != US_BULK_STAT_OK)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_Read_Data() ---------------------
+int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
+ int result;
+
+ //printk("transport --- ENE_Read_Data\n");
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = length;
+ bcb->Flags =0x80;
+ bcb->CDB[0] = 0xED;
+ bcb->CDB[2] = 0xFF;
+ bcb->CDB[3] = 0x81;
+
+ // send cmd to out endpoint
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // R/W data
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buf, length, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Get CSW for device status
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+ if (bcs->Status != US_BULK_STAT_OK)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- ENE_Write_Data() ---------------------
+int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
+ int result;
+
+ //printk("transport --- ENE_Write_Data\n");
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = length;
+ bcb->Flags =0x00;
+ bcb->CDB[0] = 0xEE;
+ bcb->CDB[2] = 0xFF;
+ bcb->CDB[3] = 0x81;
+
+ // send cmd to out endpoint
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // R/W data
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, buf, length, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Get CSW for device status
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+ if (bcs->Status != US_BULK_STAT_OK)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- usb_stor_print_cmd() ---------------------
+void usb_stor_print_cmd(struct scsi_cmnd *srb)
+{
+ PBYTE Cdb = srb->cmnd;
+ DWORD cmd = Cdb[0];
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+
+ switch (cmd) {
+ case TEST_UNIT_READY:
+ //printk("scsi cmd %X --- SCSIOP_TEST_UNIT_READY\n", cmd);
+ break;
+ case INQUIRY:
+ printk("scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
+ break;
+ case MODE_SENSE:
+ printk("scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
+ break;
+ case START_STOP:
+ printk("scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
+ break;
+ case READ_CAPACITY:
+ printk("scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
+ break;
+ case READ_10:
+ //printk("scsi cmd %X --- SCSIOP_READ, bn = %X, blen = %X\n", cmd, bn, blen);
+ break;
+ case WRITE_10:
+ //printk("scsi cmd %X --- SCSIOP_WRITE, bn = %X, blen = %X\n", cmd, bn, blen);
+ break;
+ case ALLOW_MEDIUM_REMOVAL:
+ printk("scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
+ break;
+ default:
+ printk("scsi cmd %X --- Other cmd\n", cmd);
+ break;
+ }
+ bn = 0;
+ blen = 0;
+}
+
+
diff --git a/drivers/staging/keucr/init.h b/drivers/staging/keucr/init.h
new file mode 100644
index 000000000000..cd199fc1e6d5
--- /dev/null
+++ b/drivers/staging/keucr/init.h
@@ -0,0 +1,2066 @@
+#include "common.h"
+
+BYTE SD_Init1[] = {
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90,
+0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x0A, 0xC2,
+0x0F, 0xD2, 0x10, 0xC2, 0x17, 0xC3, 0x02, 0xE3,
+0x13, 0x7F, 0x03, 0x12, 0x2F, 0xCB, 0x7E, 0x00,
+0x7F, 0x10, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x07,
+0xE0, 0x54, 0xBA, 0xF0, 0x75, 0x16, 0x00, 0x75,
+0x17, 0x00, 0x90, 0xFE, 0x05, 0x74, 0x80, 0xF0,
+0x90, 0xFE, 0x07, 0x74, 0x80, 0xF0, 0x7F, 0x32,
+0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x05,
+0xE0, 0x44, 0x01, 0xF0, 0xE0, 0x44, 0x08, 0xF0,
+0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90,
+0xFE, 0x05, 0xE0, 0x54, 0xF7, 0xF0, 0x7F, 0x32,
+0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFF, 0x81,
+0xE0, 0xC2, 0xE3, 0xF0, 0xE0, 0x54, 0xCF, 0x44,
+0x20, 0xD2, 0xE3, 0xF0, 0x90, 0xFF, 0x84, 0xE0,
+0x54, 0x1F, 0x44, 0x40, 0xF0, 0x90, 0xFE, 0x05,
+0xE0, 0xD2, 0xE0, 0xF0, 0xE0, 0x30, 0xE0, 0xF8,
+0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90,
+0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA,
+0xD3, 0x80, 0x01, 0xC3, 0x90, 0xFE, 0x05, 0xE0,
+0x44, 0x30, 0xF0, 0x90, 0xFE, 0x06, 0x74, 0x70,
+0xF0, 0x74, 0xFF, 0x90, 0xFE, 0x08, 0xF0, 0x74,
+0xFF, 0x90, 0xFE, 0x09, 0xF0, 0x90, 0xFE, 0x04,
+0xE0, 0x44, 0x06, 0xF0, 0xE4, 0x90, 0xFE, 0x0C,
+0xF0, 0x90, 0xFE, 0x0D, 0xF0, 0x90, 0xFE, 0x0E,
+0xF0, 0xC2, 0x12, 0xE4, 0x90, 0xEB, 0xF9, 0xF0,
+0x90, 0xEB, 0xFA, 0xF0, 0x90, 0xFF, 0x81, 0xE0,
+0x54, 0x8F, 0x44, 0x7F, 0xF0, 0x7F, 0x32, 0x7E,
+0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x05, 0xE0,
+0x54, 0xBF, 0xF0, 0x75, 0xF0, 0xFF, 0xD2, 0x17,
+0xC2, 0x13, 0xE5, 0xF0, 0x14, 0xF5, 0xF0, 0x70,
+0x03, 0x02, 0xE2, 0xFC, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03, 0x02,
+0xE2, 0xFC, 0xE4, 0xFE, 0x74, 0xFF, 0xFF, 0x78,
+0x00, 0x79, 0x08, 0x12, 0xE3, 0x22, 0x20, 0x13,
+0x24, 0x30, 0x17, 0x21, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03, 0x02,
+0xE2, 0xFC, 0x78, 0x08, 0x79, 0x28, 0x7D, 0xAA,
+0x7C, 0x01, 0x7B, 0x00, 0x7A, 0x00, 0x12, 0xE3,
+0x22, 0x50, 0x02, 0x21, 0xED, 0x90, 0xFF, 0x83,
+0xE0, 0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03,
+0x02, 0xE2, 0xFC, 0x30, 0x13, 0x02, 0x80, 0x17,
+0x78, 0x37, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00,
+0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50,
+0x02, 0x80, 0x7A, 0x78, 0x69, 0x80, 0x02, 0x78,
+0x01, 0x79, 0x2A, 0x7A, 0x80, 0x30, 0x17, 0x02,
+0x7A, 0x40, 0x7B, 0x70, 0x7C, 0x00, 0x7D, 0x00,
+0x12, 0xE3, 0x22, 0x50, 0x16, 0x90, 0xFE, 0x04,
+0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30,
+0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01,
+0xC3, 0x80, 0x4A, 0x90, 0xFE, 0x20, 0xE0, 0x54,
+0x00, 0xB4, 0x00, 0x23, 0x90, 0xFE, 0x21, 0xE0,
+0x54, 0x00, 0xB4, 0x00, 0x1A, 0x90, 0xFE, 0x22,
+0xE0, 0x54, 0x70, 0xB4, 0x70, 0x11, 0x90, 0xFE,
+0x23, 0xE0, 0x30, 0xE7, 0x0A, 0x30, 0x17, 0x05,
+0x20, 0xE6, 0x02, 0xC2, 0x17, 0x41, 0x02, 0xC3,
+0xEF, 0x94, 0x01, 0xFF, 0xEE, 0x94, 0x00, 0xFE,
+0xC0, 0x06, 0xC0, 0x07, 0x7F, 0x64, 0x7E, 0x00,
+0x12, 0xE3, 0xFA, 0xD0, 0x07, 0xD0, 0x06, 0xEE,
+0x4F, 0x60, 0x02, 0x21, 0x4D, 0x7F, 0x64, 0x7E,
+0x00, 0x12, 0xE3, 0xFA, 0xB2, 0x17, 0x30, 0x17,
+0x07, 0xB2, 0x13, 0x20, 0x13, 0x02, 0x01, 0xFE,
+0x21, 0x0C, 0x78, 0x02, 0x79, 0x2D, 0x12, 0xE3,
+0x22, 0x50, 0x03, 0x02, 0xE2, 0xFC, 0x7B, 0x0F,
+0x7C, 0xFE, 0x7D, 0x20, 0x7E, 0xEA, 0x7F, 0x1A,
+0x12, 0xE3, 0xD3, 0x78, 0x03, 0x20, 0x13, 0x02,
+0x78, 0x03, 0x79, 0x28, 0x90, 0xEB, 0xFA, 0xE0,
+0xFA, 0x90, 0xEB, 0xF9, 0xE0, 0xFB, 0x7C, 0x00,
+0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50, 0x03, 0x02,
+0xE2, 0xFC, 0x90, 0xFE, 0x22, 0xE0, 0x90, 0xEB,
+0xF9, 0xF0, 0x90, 0xFE, 0x23, 0xE0, 0x90, 0xEB,
+0xFA, 0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xC2, 0xE3,
+0xF0, 0x30, 0x13, 0x11, 0x90, 0xFF, 0x85, 0xE0,
+0x54, 0xCF, 0x44, 0x20, 0xF0, 0x90, 0xFF, 0x81,
+0x74, 0x94, 0xF0, 0x80, 0x0F, 0x90, 0xFF, 0x85,
+0xE0, 0x54, 0xCF, 0x44, 0x30, 0xF0, 0x90, 0xFF,
+0x81, 0x74, 0x94, 0xF0, 0x90, 0xFF, 0x81, 0xE0,
+0xD2, 0xE3, 0xF0, 0x7F, 0x32, 0x7E, 0x00, 0x12,
+0xE3, 0xFA, 0x78, 0x09, 0x79, 0x4D, 0x90, 0xEB,
+0xFA, 0xE0, 0xFA, 0x90, 0xEB, 0xF9, 0xE0, 0xFB,
+0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50,
+0x03, 0x02, 0xE2, 0xFC, 0x12, 0xE3, 0x91, 0x78,
+0x87, 0x79, 0x50, 0x90, 0xEB, 0xFA, 0xE0, 0xFA,
+0x90, 0xEB, 0xF9, 0xE0, 0xFB, 0x7C, 0x00, 0x7D,
+0x00, 0x12, 0xE3, 0x22, 0x50, 0x03, 0x02, 0xE2,
+0xFC, 0x30, 0x13, 0x09, 0x90, 0xFE, 0x05, 0xE0,
+0x54, 0xBF, 0xF0, 0x80, 0x35, 0x78, 0x37, 0x79,
+0x50, 0x90, 0xEB, 0xFA, 0xE0, 0xFA, 0x90, 0xEB,
+0xF9, 0xE0, 0xFB, 0x7C, 0x00, 0x7D, 0x00, 0x12,
+0xE3, 0x22, 0x50, 0x03, 0x02, 0xE2, 0xFC, 0x78,
+0x46, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C,
+0x00, 0x7D, 0x02, 0x12, 0xE3, 0x22, 0x50, 0x03,
+0x02, 0xE2, 0xFC, 0x90, 0xFE, 0x05, 0xE0, 0x44,
+0x40, 0xF0, 0xD3, 0x22, 0x30, 0x14, 0x14, 0x90,
+0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE,
+0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3,
+0x80, 0x01, 0xC3, 0x90, 0xFE, 0xD8, 0x74, 0x01,
+0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0,
+0xC3, 0x22, 0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9,
+0x90, 0xFE, 0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18,
+0xF0, 0xEC, 0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90,
+0xFE, 0x1A, 0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0,
+0x74, 0xFF, 0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE,
+0x11, 0xF0, 0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54,
+0x80, 0xFE, 0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0,
+0x30, 0x14, 0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54,
+0x05, 0x60, 0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11,
+0xE0, 0x30, 0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30,
+0xE1, 0xE6, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05,
+0x70, 0xE9, 0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3,
+0x22, 0x90, 0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90,
+0xFE, 0x23, 0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3,
+0x22, 0x7B, 0x0F, 0x7C, 0xFE, 0x7D, 0x20, 0x7E,
+0xEA, 0x7F, 0x29, 0x12, 0xE3, 0xD3, 0x30, 0x13,
+0x1B, 0x90, 0xFE, 0x20, 0xE0, 0x54, 0x30, 0x64,
+0x30, 0x70, 0x02, 0xD2, 0x11, 0x30, 0x13, 0x0C,
+0x90, 0xFE, 0x2E, 0xE0, 0x54, 0x3C, 0x64, 0x10,
+0x70, 0x02, 0xD2, 0x12, 0x30, 0x17, 0x03, 0x02,
+0xE3, 0xC4, 0x80, 0x03, 0x20, 0x13, 0x00, 0xC2,
+0x11, 0x90, 0xFE, 0x13, 0xE0, 0x30, 0xE2, 0x02,
+0xD2, 0x11, 0x22, 0xC0, 0x04, 0xC0, 0x05, 0x8E,
+0x83, 0x8F, 0x82, 0xEB, 0x60, 0x17, 0xC0, 0x82,
+0xC0, 0x83, 0x8C, 0x83, 0x8D, 0x82, 0xE0, 0xA3,
+0xAC, 0x83, 0xAD, 0x82, 0xD0, 0x83, 0xD0, 0x82,
+0xF0, 0xA3, 0x1B, 0x80, 0xE6, 0xD0, 0x05, 0xD0,
+0x04, 0x22, 0x75, 0x8A, 0x00, 0x75, 0x8C, 0xCE,
+0xC2, 0x8D, 0x90, 0xEA, 0x65, 0xE4, 0xF0, 0xA3,
+0xF0, 0xD2, 0x8C, 0x90, 0xEA, 0x65, 0xE0, 0xFC,
+0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x9E, 0x40, 0xF3,
+0x70, 0x05, 0xED, 0xC3, 0x9F, 0x40, 0xEC, 0xC2,
+0x8C, 0x22, 0xF5, 0xD3, 0xE0, 0x64, 0x01, 0x70,
+0x02, 0xD2, 0x3F, 0x75, 0x17, 0x00, 0x75, 0x18,
+0x00, 0x85, 0x14, 0x19, 0x75, 0x1B, 0x01, 0x12,
+0x2F, 0x8C, 0x40, 0x03, 0x02, 0xE4, 0x45, 0x90,
+0xEA, 0x49, 0xE5, 0x14, 0xF0, 0x05, 0x14, 0x02,
+0xE2, 0xDC, 0xD2, 0x22, 0x90, 0xEA, 0x49, 0xE0,
+0x64, 0xFF, 0x70, 0x02, 0x80, 0x02, 0x80, 0x12,
+0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25,
+0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x12, 0x2F, 0x9E,
+0xC3, 0x22, 0x30, 0x3F, 0x36, 0x74, 0x88, 0x90,
+0xEA, 0x44, 0xF0, 0x75, 0x17, 0x00, 0x79, 0x00,
+0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02, 0x7D, 0x02,
+0x12, 0x2F, 0xA7, 0x7F, 0x80, 0x12, 0x2F, 0xC5,
+0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
+0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xFE,
+0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04, 0xE0,
+0x20, 0xE1, 0xF9, 0xD3, 0x22, 0x75, 0x8A, 0x00,
+0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65,
+0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA,
+0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3,
+0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F,
+0x40, 0xEC, 0xC2, 0x8C, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x53, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x31,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 };
+
+BYTE SD_Init2[] = {
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90,
+0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x0A, 0xC2,
+0x0F, 0xD2, 0x10, 0xC2, 0x17, 0xC3, 0x02, 0xE0,
+0xA0, 0x20, 0x13, 0x05, 0x12, 0xE3, 0x8D, 0x80,
+0x03, 0x12, 0xE1, 0x1F, 0xD2, 0x0F, 0xC2, 0x10,
+0xD3, 0x90, 0xF3, 0xFF, 0x75, 0xF0, 0xFF, 0x74,
+0x00, 0xA3, 0xF0, 0xD5, 0xF0, 0xFB, 0x7B, 0x0F,
+0x7C, 0xEA, 0x7D, 0x29, 0x7E, 0xF4, 0x7F, 0x10,
+0x12, 0xE5, 0x5D, 0x90, 0xF4, 0x00, 0xE4, 0xA2,
+0x14, 0x92, 0xE0, 0xA2, 0x0F, 0x92, 0xE1, 0xA2,
+0x10, 0x92, 0xE2, 0xA2, 0x13, 0x92, 0xE3, 0xA2,
+0x17, 0x92, 0xE4, 0xA2, 0x12, 0x92, 0xE5, 0xA2,
+0x11, 0x92, 0xE6, 0xF0, 0xF0, 0x74, 0xFF, 0xA3,
+0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0xFF, 0x2A,
+0x74, 0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0xD3,
+0x22, 0x30, 0x14, 0x14, 0x90, 0xFE, 0x04, 0xE0,
+0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14,
+0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3,
+0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0x90, 0xFE,
+0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0xE0, 0x39,
+0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9, 0x90, 0xFE,
+0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18, 0xF0, 0xEC,
+0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90, 0xFE, 0x1A,
+0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0, 0x74, 0xFF,
+0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE, 0x11, 0xF0,
+0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54, 0x80, 0xFE,
+0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0, 0x30, 0x14,
+0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, 0x60,
+0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11, 0xE0, 0x30,
+0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30, 0xE1, 0xE6,
+0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, 0x70, 0xE9,
+0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3, 0x22, 0x90,
+0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90, 0xFE, 0x23,
+0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3, 0x22, 0x20,
+0x12, 0x03, 0x02, 0xE3, 0x17, 0x90, 0xFE, 0x1C,
+0x74, 0xFF, 0xF0, 0x90, 0xFE, 0x1D, 0x74, 0x01,
+0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1E, 0xF0, 0x90,
+0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x54,
+0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0, 0x54, 0xF0,
+0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0, 0xA3,
+0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6, 0x74, 0x01,
+0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0xFE, 0xC5,
+0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x04, 0xF0,
+0x78, 0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00,
+0x7C, 0x02, 0x7D, 0x00, 0x12, 0xE0, 0xB0, 0x50,
+0x03, 0x02, 0xE3, 0x17, 0x78, 0x08, 0x79, 0xE8,
+0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE3, 0x17,
+0x90, 0xFE, 0xC8, 0xE0, 0xF0, 0x90, 0xFE, 0xC4,
+0xE0, 0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90,
+0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90,
+0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90,
+0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01,
+0xD3, 0x40, 0x03, 0x02, 0xE3, 0x17, 0x20, 0x17,
+0x02, 0x80, 0x39, 0xC3, 0x90, 0xF4, 0xD4, 0xE0,
+0x90, 0xF5, 0x00, 0xF0, 0x90, 0xEB, 0xF8, 0x94,
+0x01, 0xF0, 0x90, 0xF4, 0xD5, 0xE0, 0x90, 0xF5,
+0x01, 0xF0, 0x90, 0xEB, 0xF7, 0x94, 0x00, 0xF0,
+0x90, 0xF4, 0xD6, 0xE0, 0x90, 0xF5, 0x02, 0xF0,
+0x90, 0xEB, 0xF6, 0x94, 0x00, 0xF0, 0x90, 0xF4,
+0xD7, 0xE0, 0x90, 0xF5, 0x03, 0xF0, 0x90, 0xEB,
+0xF5, 0x94, 0x00, 0xF0, 0x90, 0xF4, 0x00, 0x43,
+0x82, 0xC4, 0xE0, 0x54, 0x03, 0xF5, 0x09, 0x90,
+0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0xFE,
+0x06, 0xE0, 0x54, 0x3F, 0x44, 0x00, 0xF0, 0x90,
+0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE,
+0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3,
+0x80, 0x01, 0xC3, 0x74, 0x03, 0x90, 0xFE, 0x1C,
+0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1D, 0xF0, 0x90,
+0xFE, 0x1E, 0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x78,
+0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C,
+0x00, 0x7D, 0x04, 0x12, 0xE0, 0xB0, 0x50, 0x03,
+0x02, 0xE3, 0x17, 0x90, 0xFE, 0x07, 0xE0, 0xC2,
+0xE6, 0xF0, 0x90, 0xFE, 0x07, 0xE0, 0xD2, 0xE0,
+0xF0, 0x90, 0xFE, 0x05, 0xE0, 0xD2, 0xE7, 0xF0,
+0x7B, 0x55, 0x7C, 0xAA, 0x7D, 0xAA, 0x7E, 0x55,
+0x12, 0xE3, 0x35, 0x50, 0x05, 0x75, 0x08, 0x02,
+0x41, 0xB0, 0x90, 0xFE, 0x07, 0xE0, 0x54, 0xBE,
+0xF0, 0x90, 0xFE, 0x05, 0xE0, 0x44, 0x40, 0xF0,
+0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90,
+0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA,
+0xD3, 0x80, 0x01, 0xC3, 0x7B, 0x5A, 0x7C, 0x5A,
+0x7D, 0xA5, 0x7E, 0x00, 0x12, 0xE3, 0x35, 0x50,
+0x05, 0x75, 0x08, 0x01, 0x41, 0xB0, 0x90, 0xFE,
+0x05, 0xE0, 0x54, 0xBF, 0xF0, 0x02, 0xE3, 0x17,
+0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90,
+0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA,
+0xD3, 0x80, 0x01, 0xC3, 0xE5, 0x08, 0x78, 0x86,
+0x79, 0x50, 0x7A, 0x03, 0x7B, 0xB7, 0xFC, 0x7D,
+0x00, 0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE3,
+0x17, 0x78, 0x86, 0x79, 0x50, 0x7A, 0x03, 0x7B,
+0xB9, 0x7C, 0x01, 0x7D, 0x00, 0x12, 0xE0, 0xB0,
+0x40, 0xBC, 0xE5, 0x09, 0x20, 0xE1, 0x04, 0x74,
+0x94, 0x80, 0x02, 0x74, 0x84, 0x90, 0xFF, 0x81,
+0xF0, 0x90, 0xFE, 0x07, 0xE0, 0xD2, 0xE6, 0xF0,
+0x90, 0xFF, 0x85, 0xE0, 0x54, 0xCF, 0x44, 0x30,
+0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xD2, 0xE3, 0xF0,
+0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE5, 0x84, 0x90,
+0xFE, 0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40, 0xF0,
+0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90,
+0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA,
+0xD3, 0x80, 0x01, 0xC3, 0x22, 0xC0, 0x05, 0xC0,
+0x06, 0x78, 0x13, 0x79, 0x68, 0x12, 0xE0, 0xB0,
+0x50, 0x03, 0x02, 0xE3, 0x8B, 0xEB, 0x90, 0xFE,
+0x00, 0xF0, 0xEC, 0xF0, 0x90, 0xFE, 0x12, 0xE0,
+0x30, 0xE1, 0xF9, 0x90, 0xFE, 0x04, 0xE0, 0x44,
+0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14, 0x06,
+0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x78,
+0x0E, 0x79, 0xE8, 0x12, 0xE0, 0xB0, 0x50, 0x03,
+0x02, 0xE3, 0x8B, 0x90, 0xFE, 0x12, 0xE0, 0x20,
+0xE1, 0xF9, 0xD0, 0x06, 0xD0, 0x05, 0x90, 0xFE,
+0x00, 0xE0, 0x6D, 0x70, 0x06, 0xE0, 0x6E, 0x70,
+0x02, 0xD3, 0x22, 0xC3, 0x22, 0x90, 0xFE, 0x06,
+0xE0, 0x54, 0x3F, 0x44, 0x00, 0xF0, 0x90, 0xFE,
+0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04,
+0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80,
+0x01, 0xC3, 0x74, 0x07, 0x90, 0xFE, 0x1C, 0xF0,
+0x74, 0x00, 0x90, 0xFE, 0x1D, 0xF0, 0x90, 0xFE,
+0x1E, 0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x78, 0x10,
+0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x30, 0x17,
+0x06, 0x7C, 0x02, 0x7D, 0x00, 0x80, 0x04, 0x7C,
+0x00, 0x7D, 0x08, 0x12, 0xE0, 0xB0, 0x50, 0x03,
+0x02, 0xE4, 0x39, 0x78, 0x37, 0x79, 0x50, 0x90,
+0xEB, 0xFA, 0xE0, 0xFA, 0x90, 0xEB, 0xF9, 0xE0,
+0xFB, 0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE0, 0xB0,
+0x50, 0x03, 0x02, 0xE4, 0x39, 0x78, 0x73, 0x79,
+0xE8, 0x7A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D,
+0x00, 0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE4,
+0x39, 0x90, 0xFE, 0x12, 0xE0, 0x20, 0xE1, 0xF9,
+0x78, 0x08, 0x90, 0xEA, 0x3F, 0xC0, 0x83, 0xC0,
+0x82, 0x90, 0xFE, 0x00, 0xE0, 0xD0, 0x82, 0xD0,
+0x83, 0xF0, 0xC3, 0xE5, 0x82, 0x24, 0xFF, 0xF5,
+0x82, 0xE5, 0x83, 0x34, 0xFF, 0xF5, 0x83, 0xD8,
+0xE4, 0x90, 0xEA, 0x3F, 0xE0, 0x54, 0x0F, 0x70,
+0x25, 0x90, 0xFE, 0x07, 0xE0, 0xC2, 0xE6, 0xF0,
+0x90, 0xFE, 0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40,
+0xF0, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0,
+0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70,
+0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x22, 0x90, 0xFE,
+0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40, 0xF0, 0x90,
+0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE,
+0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3,
+0x80, 0x01, 0xC3, 0x7E, 0x00, 0x12, 0xE4, 0xBF,
+0x40, 0x03, 0x02, 0xE4, 0xBE, 0x7E, 0x80, 0x12,
+0xE4, 0xBF, 0x40, 0x03, 0x02, 0xE4, 0xBE, 0x90,
+0xFF, 0x81, 0xE0, 0xC2, 0xE3, 0xF0, 0x90, 0xFF,
+0x81, 0x74, 0x84, 0xF0, 0x90, 0xFE, 0x07, 0xE0,
+0xD2, 0xE6, 0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xD2,
+0xE3, 0xF0, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06,
+0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0,
+0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x22, 0x90,
+0xFE, 0x1C, 0x74, 0x3F, 0xF0, 0x90, 0xFE, 0x1D,
+0x74, 0x00, 0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1E,
+0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0xCC,
+0xE0, 0x54, 0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0,
+0x54, 0xF0, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4,
+0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6,
+0x74, 0x00, 0xF0, 0xA3, 0x74, 0x3F, 0xF0, 0x90,
+0xFE, 0xC5, 0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74,
+0x04, 0xF0, 0x78, 0x06, 0x79, 0xE8, 0xAA, 0x06,
+0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0x01, 0x12, 0xE0,
+0xB0, 0x50, 0x03, 0x02, 0xE5, 0x5B, 0x90, 0xFE,
+0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xC4, 0xE0,
+0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90, 0xFE,
+0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90, 0xFE,
+0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90, 0xFE,
+0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01, 0xD3,
+0x40, 0x03, 0x02, 0xE5, 0x5B, 0x90, 0xFE, 0xCC,
+0xE0, 0x44, 0x80, 0xF0, 0x90, 0xF4, 0x0D, 0xE0,
+0x90, 0xF4, 0x10, 0xE0, 0x64, 0x0F, 0x60, 0x03,
+0xD3, 0x80, 0x01, 0xC3, 0x22, 0xC0, 0x04, 0xC0,
+0x05, 0x8E, 0x83, 0x8F, 0x82, 0xEB, 0x60, 0x17,
+0xC0, 0x82, 0xC0, 0x83, 0x8C, 0x83, 0x8D, 0x82,
+0xE0, 0xA3, 0xAC, 0x83, 0xAD, 0x82, 0xD0, 0x83,
+0xD0, 0x82, 0xF0, 0xA3, 0x1B, 0x80, 0xE6, 0xD0,
+0x05, 0xD0, 0x04, 0x22, 0x75, 0x8A, 0x00, 0x75,
+0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65, 0xE4,
+0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA, 0x65,
+0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x9E,
+0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F, 0x40,
+0xEC, 0xC2, 0x8C, 0x22, 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,
+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, 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,
+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, 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,
+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, 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,
+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, 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,
+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, 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,
+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, 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,
+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, 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,
+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, 0x00, 0x00, 0x00, 0x00,
+0x53, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x32,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 };
+
+BYTE SD_Rdwr[] = {
+0x90, 0xF0, 0x11, 0xE0, 0x90, 0xEB, 0x2A, 0xF0,
+0x90, 0xF0, 0x12, 0xE0, 0x90, 0xEB, 0x2B, 0xF0,
+0x90, 0xF0, 0x13, 0xE0, 0x90, 0xEB, 0x2C, 0xF0,
+0x90, 0xF0, 0x14, 0xE0, 0x90, 0xEB, 0x2D, 0xF0,
+0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE0, 0x92, 0x14,
+0x30, 0x14, 0x3E, 0x30, 0x0F, 0x3B, 0x90, 0xEB,
+0x2A, 0xE0, 0xF5, 0x10, 0xA3, 0xE0, 0xF5, 0x11,
+0xA3, 0xE0, 0xF5, 0x12, 0xA3, 0xE0, 0xF5, 0x13,
+0xC3, 0xE5, 0x3D, 0x13, 0xF5, 0x14, 0xE5, 0x3E,
+0x13, 0xF5, 0x15, 0x85, 0x14, 0x16, 0x85, 0x15,
+0x17, 0x90, 0xF0, 0x0C, 0xE0, 0x54, 0x80, 0x70,
+0x12, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06,
+0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x02, 0xE2,
+0x31, 0xC3, 0x22, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0,
+0xE5, 0x15, 0x24, 0xFF, 0x90, 0xFE, 0x1E, 0xF0,
+0xE5, 0x14, 0x34, 0xFF, 0x90, 0xFE, 0x1F, 0xF0,
+0x90, 0xFE, 0x1C, 0x74, 0xFF, 0xF0, 0x90, 0xFE,
+0x1D, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xCC, 0xE0,
+0x54, 0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0, 0x54,
+0xF0, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0,
+0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6, 0x74,
+0x01, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0xFE,
+0xC5, 0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x04,
+0xF0, 0x78, 0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B,
+0x00, 0x7C, 0x02, 0x7D, 0x00, 0x12, 0xE3, 0xEA,
+0x50, 0x03, 0x02, 0xE1, 0xFA, 0x12, 0xE4, 0x44,
+0x50, 0x03, 0x02, 0xE1, 0xFA, 0xAD, 0x13, 0xAC,
+0x12, 0xAB, 0x11, 0xAA, 0x10, 0x80, 0x00, 0xE5,
+0x15, 0x64, 0x01, 0x45, 0x14, 0x70, 0x0E, 0x78,
+0x11, 0x79, 0xE8, 0x12, 0xE3, 0xEA, 0x50, 0x03,
+0x02, 0xE1, 0xFA, 0x80, 0x0C, 0x78, 0x12, 0x79,
+0xE8, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE1,
+0xFA, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE1,
+0xFA, 0x30, 0x14, 0x07, 0x90, 0xFE, 0x12, 0xE0,
+0x30, 0xE4, 0xF6, 0x20, 0x14, 0x03, 0x02, 0xE1,
+0xFA, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC,
+0x90, 0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE,
+0xC4, 0xE0, 0x44, 0x01, 0xF0, 0xC3, 0xE5, 0x17,
+0x94, 0x01, 0xF5, 0x17, 0xE5, 0x16, 0x94, 0x00,
+0xF5, 0x16, 0x45, 0x17, 0x60, 0x42, 0x30, 0x14,
+0x10, 0x90, 0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60,
+0x11, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60,
+0xED, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3,
+0x80, 0x01, 0xD3, 0x40, 0x03, 0x02, 0xE1, 0xFA,
+0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74,
+0x00, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5,
+0xFC, 0x90, 0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90,
+0xFE, 0xC4, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0xAD,
+0x30, 0x14, 0x10, 0x90, 0xFE, 0xC8, 0xE0, 0x64,
+0x01, 0x60, 0x11, 0x90, 0xFE, 0x10, 0xE0, 0x54,
+0x0A, 0x60, 0xED, 0x90, 0xFE, 0xD8, 0x74, 0x01,
+0xF0, 0xC3, 0x80, 0x01, 0xD3, 0x40, 0x03, 0x02,
+0xE1, 0xFA, 0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0,
+0xA3, 0x74, 0x00, 0xF0, 0xE5, 0x15, 0x64, 0x01,
+0x45, 0x14, 0x60, 0x29, 0x90, 0xFF, 0x09, 0xE0,
+0x30, 0xE5, 0xFC, 0x78, 0x8C, 0x79, 0x50, 0x12,
+0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE1, 0xFA, 0x12,
+0xE4, 0x44, 0x50, 0x11, 0x90, 0xFE, 0x22, 0xE0,
+0x70, 0x20, 0x90, 0xFE, 0x23, 0xE0, 0x64, 0x80,
+0x60, 0x03, 0x02, 0xE1, 0xFA, 0x90, 0xFE, 0xCC,
+0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3C, 0x00, 0x75,
+0x3D, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00,
+0xD3, 0x22, 0x30, 0x14, 0x14, 0x90, 0xFE, 0x04,
+0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30,
+0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01,
+0xC3, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0x90,
+0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3F,
+0x00, 0xC3, 0xE5, 0x17, 0x33, 0xF5, 0x3E, 0xE5,
+0x16, 0x33, 0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3,
+0x22, 0xE5, 0x3E, 0x54, 0x01, 0x45, 0x3F, 0x60,
+0x03, 0x02, 0xE0, 0x69, 0xE5, 0x15, 0x24, 0xFF,
+0x90, 0xFE, 0x1E, 0xF0, 0xE5, 0x14, 0x34, 0xFF,
+0x90, 0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0x1C, 0x74,
+0xFF, 0xF0, 0x90, 0xFE, 0x1D, 0x74, 0x01, 0xF0,
+0x90, 0xFE, 0x06, 0xE0, 0x54, 0xF0, 0x44, 0x0F,
+0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF0, 0xF0, 0xA3,
+0x74, 0x00, 0xF0, 0xE5, 0x4D, 0x24, 0xFF, 0xFF,
+0xE5, 0x4C, 0x34, 0xFF, 0x90, 0xFE, 0xC6, 0xF0,
+0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0xFE, 0xC5, 0xF0,
+0x74, 0x06, 0x90, 0xFE, 0xC4, 0xF0, 0x90, 0xFE,
+0xCC, 0xE0, 0x54, 0x7F, 0xF0, 0x78, 0x10, 0x79,
+0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C, 0x02, 0x7D,
+0x00, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3,
+0x9E, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE3,
+0x9E, 0xAD, 0x13, 0xAC, 0x12, 0xAB, 0x11, 0xAA,
+0x10, 0x80, 0x10, 0x74, 0x00, 0xFD, 0xC3, 0xE5,
+0x13, 0x33, 0xFC, 0xE5, 0x12, 0x33, 0xFB, 0xE5,
+0x11, 0x33, 0xFA, 0xE5, 0x15, 0x64, 0x01, 0x45,
+0x14, 0x70, 0x0E, 0x78, 0x18, 0x79, 0x68, 0x12,
+0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3, 0x9E, 0x80,
+0x0C, 0x78, 0x19, 0x79, 0x68, 0x12, 0xE3, 0xEA,
+0x50, 0x03, 0x02, 0xE3, 0x9E, 0x12, 0xE4, 0x44,
+0x50, 0x03, 0x02, 0xE3, 0x9E, 0x75, 0x1F, 0x01,
+0x20, 0x2D, 0x03, 0x75, 0x1F, 0x08, 0xE5, 0x16,
+0x45, 0x17, 0x70, 0x03, 0x02, 0xE3, 0x6B, 0x85,
+0x1F, 0x1E, 0x30, 0x14, 0x3C, 0x90, 0xFF, 0x09,
+0x30, 0x14, 0x04, 0xE0, 0x30, 0xE1, 0xF9, 0x90,
+0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xC4,
+0xE0, 0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90,
+0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90,
+0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90,
+0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01,
+0xD3, 0x40, 0x03, 0x02, 0xE3, 0x9E, 0x90, 0xFE,
+0x12, 0x30, 0x14, 0x2A, 0xE0, 0x30, 0xE1, 0xF9,
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90,
+0xFF, 0x23, 0x74, 0x80, 0xF0, 0x15, 0x1E, 0xE5,
+0x1E, 0x70, 0xA7, 0xC3, 0xE5, 0x17, 0x94, 0x01,
+0xF5, 0x17, 0xE5, 0x16, 0x94, 0x00, 0xF5, 0x16,
+0x02, 0xE2, 0xF6, 0x90, 0xFE, 0x12, 0x30, 0x14,
+0x2D, 0xE0, 0x20, 0xE4, 0xF9, 0xE5, 0x15, 0x64,
+0x01, 0x45, 0x14, 0x60, 0x58, 0x78, 0x8C, 0x79,
+0x50, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3,
+0x9E, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE3,
+0x9E, 0x30, 0x14, 0x41, 0x90, 0xFE, 0x12, 0xE0,
+0x20, 0xE4, 0xF6, 0x02, 0xE3, 0xD5, 0x30, 0x14,
+0x14, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0,
+0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70,
+0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x90, 0xFE, 0xD8,
+0x74, 0x01, 0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x44,
+0x80, 0xF0, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x17,
+0x33, 0xF5, 0x3E, 0xE5, 0x16, 0x33, 0xF5, 0x3D,
+0x75, 0x3C, 0x00, 0xC3, 0x22, 0x90, 0xFE, 0xCC,
+0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3C, 0x00, 0x75,
+0x3D, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00,
+0xD3, 0x22, 0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9,
+0x90, 0xFE, 0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18,
+0xF0, 0xEC, 0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90,
+0xFE, 0x1A, 0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0,
+0x74, 0xFF, 0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE,
+0x11, 0xF0, 0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54,
+0x80, 0xFE, 0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0,
+0x30, 0x14, 0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54,
+0x05, 0x60, 0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11,
+0xE0, 0x30, 0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30,
+0xE1, 0xE6, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05,
+0x70, 0xE9, 0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3,
+0x22, 0x90, 0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90,
+0xFE, 0x23, 0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3,
+0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x53, 0x44, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 };
+
+BYTE MS_Init[] = {
+0x90, 0xF0, 0x15, 0xE0, 0xF5, 0x1C, 0x11, 0x2C,
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90,
+0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE5, 0xFC, 0x51, 0x59, 0x75, 0x3F,
+0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75,
+0x3C, 0x00, 0xD3, 0x22, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE1, 0x92, 0x25, 0x20, 0x25, 0x06, 0xC2,
+0x1F, 0xD2, 0x19, 0xC3, 0x22, 0x7F, 0x02, 0x12,
+0x2F, 0xCB, 0x20, 0x19, 0x05, 0x30, 0x1F, 0x02,
+0xD3, 0x22, 0x90, 0xEA, 0x44, 0x74, 0x80, 0xF0,
+0x7F, 0x10, 0x12, 0x2F, 0xC5, 0x90, 0xFE, 0x47,
+0xE0, 0x44, 0x80, 0xF0, 0x78, 0x00, 0xE8, 0xC3,
+0x94, 0x04, 0x50, 0x0A, 0x7F, 0x88, 0x7E, 0x13,
+0x12, 0xE4, 0xA6, 0x08, 0x80, 0xF0, 0x90, 0xFE,
+0x45, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xFE, 0x47,
+0xE0, 0x54, 0xBF, 0xF0, 0x90, 0xFE, 0x45, 0xE0,
+0x54, 0xFE, 0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54,
+0x7F, 0xF0, 0x90, 0xFE, 0x46, 0xE0, 0x44, 0x40,
+0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xC7, 0x44,
+0x18, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x44, 0x08,
+0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x44, 0x40, 0xF0,
+0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE4, 0xA6, 0x90,
+0xFE, 0x51, 0xE0, 0x54, 0x33, 0xF0, 0x90, 0xFE,
+0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04, 0xE0,
+0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x51, 0xE0, 0x54,
+0x0F, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0,
+0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90,
+0xFE, 0x44, 0x74, 0x04, 0xF0, 0x30, 0x25, 0x04,
+0xE0, 0x20, 0xE2, 0xF9, 0x90, 0xFE, 0x4C, 0xE0,
+0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x90, 0xFE,
+0x48, 0x74, 0x7F, 0xF0, 0x90, 0xFE, 0x49, 0x74,
+0x9F, 0xF0, 0x90, 0xFE, 0x51, 0xE0, 0x54, 0x3C,
+0x44, 0x02, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02,
+0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9,
+0x90, 0xFE, 0x46, 0xE0, 0x44, 0x20, 0xF0, 0x79,
+0x02, 0x7A, 0x06, 0x7B, 0x00, 0x7C, 0x00, 0x7D,
+0x06, 0x7E, 0xEB, 0x7F, 0xC9, 0x12, 0x2F, 0xA7,
+0x40, 0x03, 0x02, 0xE2, 0x37, 0xC2, 0x45, 0xC2,
+0x1E, 0x90, 0xEB, 0xCB, 0xE0, 0x64, 0x01, 0x70,
+0x65, 0x90, 0xEB, 0xCD, 0xE0, 0x70, 0x5F, 0x90,
+0xEB, 0xCE, 0xE0, 0x60, 0x08, 0x54, 0x03, 0x60,
+0x55, 0xD2, 0x1E, 0x80, 0x09, 0x90, 0xEB, 0xC9,
+0xE0, 0x30, 0xE0, 0x02, 0xD2, 0x1E, 0x90, 0xEA,
+0x45, 0x74, 0x01, 0xF0, 0x75, 0x0B, 0x00, 0xE5,
+0x0B, 0xC3, 0x94, 0x80, 0x50, 0x31, 0x12, 0x2F,
+0xB9, 0x40, 0x03, 0x02, 0xE2, 0x37, 0x90, 0xEB,
+0xC8, 0xE0, 0x54, 0x80, 0x70, 0x0B, 0x7F, 0x38,
+0x7E, 0x13, 0x12, 0xE4, 0xA6, 0x05, 0x0B, 0x80,
+0xDE, 0x12, 0x2F, 0xB9, 0x40, 0x03, 0x02, 0xE2,
+0x37, 0x90, 0xEB, 0xC8, 0xE0, 0xF9, 0x54, 0x40,
+0x60, 0x0A, 0xE9, 0x54, 0x01, 0x70, 0x03, 0x02,
+0xE2, 0x37, 0xD2, 0x1E, 0x80, 0x24, 0x90, 0xEB,
+0xCB, 0xE0, 0x64, 0x00, 0x60, 0x03, 0x02, 0xE2,
+0x37, 0x90, 0xEA, 0x45, 0x74, 0x00, 0xF0, 0x7F,
+0x90, 0x12, 0x2F, 0xC5, 0x12, 0xE2, 0xB0, 0x40,
+0x03, 0x02, 0xE2, 0x37, 0xD2, 0x1F, 0xC2, 0x19,
+0xD3, 0x22, 0x90, 0xEA, 0x44, 0x74, 0x00, 0xF0,
+0x75, 0x17, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B,
+0x10, 0x7C, 0x02, 0x7D, 0x02, 0x12, 0x2F, 0xA7,
+0x40, 0x02, 0x80, 0x5B, 0x7F, 0x80, 0x12, 0x2F,
+0xC5, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0,
+0x90, 0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90,
+0xEB, 0xCC, 0xE0, 0x64, 0x07, 0x70, 0x2D, 0x90,
+0xEA, 0x44, 0x74, 0x40, 0xF0, 0x75, 0x17, 0x00,
+0x79, 0x00, 0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02,
+0x7D, 0x02, 0x12, 0x2F, 0xA7, 0x40, 0x02, 0x80,
+0x26, 0x7F, 0x80, 0x12, 0x2F, 0xC5, 0x90, 0xFE,
+0x45, 0xE0, 0x54, 0xFA, 0xF0, 0x90, 0xFE, 0x45,
+0xE0, 0x44, 0x01, 0xF0, 0x90, 0xEA, 0x45, 0xE0,
+0x60, 0x07, 0x12, 0x2F, 0xCE, 0x40, 0x02, 0x80,
+0x06, 0xD2, 0x1F, 0xC2, 0x19, 0xD3, 0x22, 0xE4,
+0x90, 0xFE, 0x48, 0xF0, 0x90, 0xFE, 0x49, 0xF0,
+0x90, 0xFE, 0x4C, 0xE0, 0xF0, 0x90, 0xFE, 0x4D,
+0xE0, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x54, 0x7F,
+0xF0, 0xC2, 0x25, 0xC2, 0x1F, 0xD2, 0x19, 0xC3,
+0x22, 0x90, 0xEA, 0x45, 0xE0, 0x64, 0x01, 0x70,
+0x03, 0xD3, 0x80, 0x01, 0xC3, 0xE4, 0x92, 0xE3,
+0xC0, 0xE0, 0x90, 0xEB, 0xCC, 0xE0, 0x64, 0x07,
+0x70, 0x03, 0xD3, 0x80, 0x01, 0xC3, 0xD0, 0xE0,
+0x92, 0xE4, 0xA2, 0x25, 0x92, 0xE0, 0xA2, 0x1F,
+0x92, 0xE1, 0xA2, 0x19, 0x92, 0xE2, 0xA2, 0x1E,
+0x92, 0xE6, 0x90, 0xF4, 0x00, 0xF0, 0x74, 0xFF,
+0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0x7B,
+0x40, 0x7C, 0xEB, 0x7D, 0x6F, 0xAE, 0x83, 0xAF,
+0x82, 0x12, 0x2F, 0xC8, 0x90, 0xFF, 0x2A, 0x74,
+0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0xD3, 0x22,
+0xC2, 0x1E, 0x74, 0xFF, 0x90, 0xEA, 0x49, 0xF0,
+0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25,
+0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFF, 0x09,
+0x30, 0x25, 0x07, 0xE0, 0x30, 0xE5, 0xF9, 0xD3,
+0x80, 0x01, 0xC3, 0x40, 0x01, 0x22, 0xC2, 0x1A,
+0xC2, 0x22, 0x75, 0x14, 0x00, 0xE5, 0x14, 0x64,
+0x0C, 0x70, 0x03, 0x02, 0xE4, 0x4B, 0x75, 0x17,
+0x00, 0x75, 0x18, 0x00, 0x85, 0x14, 0x19, 0x75,
+0x1B, 0x00, 0x12, 0x2F, 0x8C, 0x40, 0x03, 0x02,
+0xE4, 0x46, 0x30, 0x41, 0x03, 0x02, 0xE4, 0x46,
+0x90, 0xEB, 0xDD, 0xE0, 0x20, 0xE7, 0x03, 0x02,
+0xE4, 0x46, 0x90, 0xEB, 0xDE, 0xE0, 0x20, 0xE2,
+0x02, 0x80, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF4,
+0x00, 0xE0, 0xFE, 0x90, 0xF4, 0x01, 0xE0, 0x64,
+0x01, 0x4E, 0x60, 0x03, 0x02, 0xE4, 0x46, 0x90,
+0xEA, 0x49, 0xE0, 0x64, 0xFF, 0x60, 0x03, 0x02,
+0xE4, 0x4B, 0x90, 0xF5, 0xA0, 0xE0, 0x64, 0x01,
+0x60, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0xD6,
+0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0xE4, 0x46,
+0x90, 0xF5, 0xD8, 0xE0, 0xFF, 0xC3, 0x74, 0x03,
+0x9F, 0x50, 0x03, 0x02, 0xE4, 0x46, 0xEF, 0x60,
+0x04, 0xD2, 0x1E, 0x80, 0x0B, 0xC2, 0x1E, 0x90,
+0xEB, 0xC9, 0xE0, 0x30, 0xE0, 0x02, 0xD2, 0x1E,
+0x90, 0xF5, 0xA2, 0xE0, 0xFE, 0x90, 0xF5, 0xA3,
+0xE0, 0xFF, 0x25, 0xE0, 0x90, 0xEA, 0x47, 0xF0,
+0xE4, 0x74, 0x10, 0x9F, 0x74, 0x00, 0x9E, 0x50,
+0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0xA4, 0xE0,
+0xFE, 0x90, 0xF5, 0xA5, 0xE0, 0xFF, 0xC3, 0x74,
+0x00, 0x9F, 0x74, 0x20, 0x9E, 0x50, 0x03, 0x02,
+0xE4, 0x46, 0xEE, 0x4F, 0x70, 0x03, 0x02, 0xE4,
+0x46, 0x90, 0xF5, 0xA6, 0xE0, 0xFE, 0x90, 0xF5,
+0xA7, 0xE0, 0xFF, 0xEE, 0x4F, 0x70, 0x03, 0x02,
+0xE4, 0x46, 0x90, 0xF5, 0x78, 0xE0, 0x64, 0x01,
+0x60, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0x74,
+0xE0, 0xFC, 0x90, 0xF5, 0x75, 0xE0, 0xFD, 0x90,
+0xF5, 0x76, 0xE0, 0x90, 0xEA, 0x5B, 0xF0, 0xFE,
+0x90, 0xF5, 0x77, 0xE0, 0x90, 0xEA, 0x5C, 0xF0,
+0xFF, 0x4E, 0x4D, 0x4C, 0x70, 0x03, 0x02, 0xE4,
+0x46, 0x90, 0xF5, 0x70, 0xE0, 0xFC, 0x90, 0xF5,
+0x71, 0xE0, 0xFD, 0x90, 0xF5, 0x72, 0xE0, 0xFE,
+0x90, 0xF5, 0x73, 0xE0, 0xFF, 0xEC, 0x90, 0xEA,
+0x55, 0xF0, 0xED, 0x90, 0xEA, 0x56, 0xF0, 0xEE,
+0x90, 0xEA, 0x57, 0xF0, 0xEF, 0x90, 0xEA, 0x58,
+0xF0, 0xEC, 0x64, 0xFF, 0x70, 0x12, 0xED, 0x64,
+0xFF, 0x70, 0x0D, 0xEE, 0x64, 0xFF, 0x70, 0x08,
+0xEF, 0x64, 0xFF, 0x70, 0x03, 0x02, 0xE4, 0x46,
+0xC2, 0x3F, 0x90, 0xF5, 0xD3, 0xE0, 0x64, 0x01,
+0x70, 0x02, 0xD2, 0x3F, 0x75, 0x17, 0x00, 0x75,
+0x18, 0x00, 0x85, 0x14, 0x19, 0x75, 0x1B, 0x01,
+0x12, 0x2F, 0x8C, 0x40, 0x03, 0x02, 0xE4, 0x46,
+0x90, 0xEA, 0x49, 0xE5, 0x14, 0xF0, 0x05, 0x14,
+0x02, 0xE2, 0xDD, 0xD2, 0x22, 0x90, 0xEA, 0x49,
+0xE0, 0x64, 0xFF, 0x70, 0x02, 0x80, 0x02, 0x80,
+0x12, 0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30,
+0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x12, 0x2F,
+0x9E, 0xC3, 0x22, 0x30, 0x3F, 0x36, 0x74, 0x88,
+0x90, 0xEA, 0x44, 0xF0, 0x75, 0x17, 0x00, 0x79,
+0x00, 0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02, 0x7D,
+0x02, 0x12, 0x2F, 0xA7, 0x7F, 0x80, 0x12, 0x2F,
+0xC5, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0,
+0x90, 0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90,
+0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04,
+0xE0, 0x20, 0xE1, 0xF9, 0xD3, 0x22, 0x75, 0x8A,
+0x00, 0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA,
+0x65, 0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90,
+0xEA, 0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC,
+0xC3, 0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3,
+0x9F, 0x40, 0xEC, 0xC2, 0x8C, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x4D, 0x53, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 };
+
+BYTE MSP_Rdwr[] = {
+0x90, 0xF0, 0x10, 0xE0, 0x90, 0xEA, 0x46, 0xF0,
+0xB4, 0x04, 0x03, 0x02, 0xE1, 0x1E, 0x90, 0xFF,
+0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23,
+0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1,
+0x92, 0x25, 0x40, 0x01, 0x22, 0x20, 0x1F, 0x02,
+0xC3, 0x22, 0x30, 0x45, 0x02, 0xC3, 0x22, 0xC3,
+0xE5, 0x3D, 0x13, 0xF5, 0x08, 0xE5, 0x3E, 0x13,
+0xF5, 0x09, 0x78, 0x96, 0x79, 0x20, 0xAA, 0x08,
+0xAB, 0x09, 0x12, 0xE2, 0x53, 0x20, 0x1D, 0x10,
+0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25,
+0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24,
+0x20, 0x23, 0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2,
+0xE1, 0x92, 0x25, 0x30, 0x25, 0x03, 0x30, 0x24,
+0xEF, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22,
+0xC2, 0x24, 0xC2, 0x23, 0x90, 0xEA, 0x4B, 0xE0,
+0x30, 0xE3, 0x0B, 0xC2, 0x25, 0x90, 0xFF, 0x85,
+0xE0, 0x54, 0xFD, 0xF0, 0xC3, 0x22, 0x30, 0xE2,
+0x78, 0x90, 0xFF, 0x09, 0x90, 0xFF, 0x83, 0xE0,
+0xA2, 0xE1, 0x92, 0x25, 0x30, 0x25, 0x0A, 0x90,
+0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xEE, 0xD3, 0x80,
+0x01, 0xC3, 0x40, 0x01, 0x22, 0x79, 0x00, 0x90,
+0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, 0xF0, 0x78,
+0x2D, 0x12, 0x2F, 0xAA, 0x7E, 0xF4, 0x7F, 0x00,
+0x7D, 0x00, 0x7C, 0x02, 0x12, 0x2F, 0xC2, 0x20,
+0x1D, 0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1,
+0x92, 0x25, 0x30, 0x25, 0x03, 0x30, 0x24, 0xEF,
+0xD2, 0x24, 0x30, 0x24, 0x13, 0x75, 0x3F, 0x00,
+0xC3, 0xE5, 0x09, 0x33, 0xF5, 0x3E, 0xE5, 0x08,
+0x33, 0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3, 0x22,
+0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74,
+0x00, 0xF0, 0xE5, 0x09, 0x24, 0xFF, 0xF5, 0x09,
+0xE5, 0x08, 0x34, 0xFF, 0xF5, 0x08, 0x02, 0xE0,
+0x60, 0x90, 0xEA, 0x4B, 0xE0, 0x20, 0xE0, 0x03,
+0x02, 0xE0, 0x60, 0xE4, 0xF5, 0x3F, 0xF5, 0x3E,
+0xF5, 0x3D, 0xF5, 0x3C, 0xD3, 0x22, 0x90, 0xFF,
+0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23,
+0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1,
+0x92, 0x25, 0x40, 0x01, 0x22, 0x20, 0x1F, 0x02,
+0xC3, 0x22, 0x30, 0x1E, 0x02, 0xC3, 0x22, 0xC3,
+0xE5, 0x3D, 0x13, 0xF5, 0x08, 0xE5, 0x3E, 0x13,
+0xF5, 0x09, 0x78, 0x96, 0x79, 0x21, 0xAA, 0x08,
+0xAB, 0x09, 0x12, 0xE2, 0x53, 0x20, 0x1D, 0x10,
+0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25,
+0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24,
+0x30, 0x2D, 0x05, 0x75, 0x0A, 0x01, 0x80, 0x03,
+0x75, 0x0A, 0x08, 0x20, 0x23, 0x10, 0x90, 0xFF,
+0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, 0x30, 0x25,
+0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24, 0x30, 0x24,
+0x02, 0xC3, 0x22, 0xC2, 0x24, 0xC2, 0x23, 0x90,
+0xEA, 0x4B, 0xE0, 0x30, 0xE1, 0x0B, 0xC2, 0x25,
+0x90, 0xFF, 0x85, 0xE0, 0x54, 0xFD, 0xF0, 0xC3,
+0x22, 0x20, 0xE2, 0x03, 0x02, 0xE2, 0x3E, 0x79,
+0x0F, 0x90, 0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49,
+0xF0, 0x75, 0x0B, 0x00, 0xE5, 0x0B, 0xC3, 0x95,
+0x0A, 0x50, 0x43, 0x90, 0xFF, 0x09, 0x30, 0x25,
+0x0B, 0xE0, 0x30, 0xE1, 0xF9, 0x90, 0xFF, 0x09,
+0xF0, 0xD3, 0x80, 0x01, 0xC3, 0x50, 0x0F, 0xAF,
+0x0B, 0x7C, 0xF0, 0x7D, 0x00, 0xAB, 0x4D, 0xAA,
+0x4C, 0x12, 0x2F, 0xBF, 0x40, 0x0F, 0x90, 0xFF,
+0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23,
+0x74, 0x80, 0xF0, 0xC3, 0x22, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74,
+0x80, 0xF0, 0x05, 0x0B, 0x80, 0xB6, 0x20, 0x1D,
+0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92,
+0x25, 0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2,
+0x24, 0x30, 0x24, 0x13, 0x75, 0x3F, 0x00, 0xC3,
+0xE5, 0x09, 0x33, 0xF5, 0x3E, 0xE5, 0x08, 0x33,
+0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3, 0x22, 0xE5,
+0x09, 0x24, 0xFF, 0xF5, 0x09, 0xE5, 0x08, 0x34,
+0xFF, 0xF5, 0x08, 0x02, 0xE1, 0x7B, 0x90, 0xEA,
+0x4B, 0xE0, 0x20, 0xE0, 0x03, 0x02, 0xE1, 0x7B,
+0xE4, 0xF5, 0x3F, 0xF5, 0x3E, 0xF5, 0x3D, 0xF5,
+0x3C, 0xD3, 0x22, 0x90, 0xFE, 0x4C, 0xE0, 0xF0,
+0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0xC2, 0x24, 0xC2,
+0x23, 0xC2, 0x1D, 0x90, 0xFE, 0x50, 0xE8, 0xF0,
+0x90, 0xFE, 0x40, 0xE9, 0xF0, 0x90, 0xFE, 0x40,
+0xEA, 0xF0, 0x90, 0xFE, 0x40, 0xEB, 0xF0, 0x90,
+0xEB, 0x2A, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90,
+0xEB, 0x2B, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90,
+0xEB, 0x2C, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90,
+0xEB, 0x2D, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90,
+0xFE, 0x44, 0x74, 0x01, 0xF0, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+0x4D, 0x53, 0x50, 0x2D, 0x52, 0x57, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 };
+
+BYTE MS_Rdwr[] = {
+0x90, 0xF0, 0x10, 0xE0, 0x90, 0xEA, 0x46, 0xF0,
+0xB4, 0x02, 0x02, 0x80, 0x36, 0x90, 0xF0, 0x11,
+0xE0, 0xF5, 0x17, 0x90, 0xF0, 0x12, 0xE0, 0xF5,
+0x18, 0x90, 0xF0, 0x13, 0xE0, 0xF5, 0x19, 0x90,
+0xF0, 0x14, 0xE0, 0xF5, 0x1B, 0x90, 0xF0, 0x15,
+0xE0, 0xF5, 0x1C, 0x90, 0xF0, 0x16, 0xE0, 0xF5,
+0x1D, 0x90, 0xF0, 0x17, 0xE0, 0xF5, 0x1E, 0x90,
+0xF0, 0x18, 0xE0, 0xF5, 0x1F, 0x90, 0xF0, 0x19,
+0xE0, 0xF5, 0x10, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0,
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC, 0x90,
+0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, 0x40,
+0x01, 0x22, 0x90, 0xEA, 0x46, 0xE0, 0xB4, 0x02,
+0x02, 0x80, 0x2B, 0xB4, 0x03, 0x03, 0x02, 0xE0,
+0x96, 0xB4, 0x04, 0x05, 0xD2, 0x21, 0x02, 0xE2,
+0xBC, 0xB4, 0x08, 0x0E, 0x85, 0x1C, 0x11, 0x85,
+0x1D, 0x12, 0x85, 0x10, 0x1B, 0xC2, 0x21, 0x02,
+0xE2, 0xBC, 0xB4, 0x06, 0x03, 0x02, 0xE2, 0x2F,
+0xB4, 0x05, 0x03, 0x02, 0xE2, 0x7A, 0x20, 0x1F,
+0x02, 0xC3, 0x22, 0x90, 0xEA, 0x46, 0xE0, 0xB4,
+0x03, 0x03, 0x02, 0xE1, 0x94, 0xC3, 0xE5, 0x3D,
+0x13, 0xF5, 0x14, 0xE5, 0x3E, 0x13, 0xF5, 0x15,
+0x90, 0xEB, 0x2A, 0xE0, 0xFC, 0x90, 0xEB, 0x2B,
+0xE0, 0xFD, 0x90, 0xEB, 0x2C, 0xE0, 0xFE, 0x90,
+0xEB, 0x2D, 0xE0, 0xFF, 0x90, 0xEA, 0x47, 0xE0,
+0x14, 0xFB, 0x60, 0x12, 0xC3, 0xEC, 0x13, 0xFC,
+0xED, 0x13, 0xFD, 0xEE, 0x13, 0xFE, 0xEF, 0x13,
+0xFF, 0xC3, 0xEB, 0x13, 0x80, 0xEB, 0x8E, 0x1E,
+0x8F, 0x1F, 0x90, 0xEB, 0x2D, 0xE0, 0xFF, 0x90,
+0xEA, 0x47, 0xE0, 0x14, 0x5F, 0xF5, 0x1B, 0xD2,
+0x1A, 0x90, 0xEA, 0x47, 0xE0, 0xC3, 0x95, 0x1B,
+0xF5, 0x16, 0xE5, 0x14, 0x70, 0x0A, 0xE5, 0x16,
+0xD3, 0x95, 0x15, 0x40, 0x03, 0x85, 0x15, 0x16,
+0xE5, 0x1E, 0xF5, 0x18, 0xE5, 0x1F, 0xF5, 0x19,
+0x75, 0x17, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8,
+0x90, 0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08,
+0xA3, 0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07,
+0xA3, 0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3,
+0x40, 0x4F, 0xE5, 0x16, 0x64, 0x01, 0x70, 0x07,
+0x12, 0x2F, 0x8C, 0x50, 0x41, 0x80, 0x07, 0xAB,
+0x16, 0x12, 0xE5, 0x60, 0x50, 0x38, 0xC3, 0xE5,
+0x15, 0x95, 0x16, 0xF5, 0x15, 0xE5, 0x14, 0x94,
+0x00, 0xF5, 0x14, 0xE5, 0x14, 0x45, 0x15, 0x60,
+0x17, 0x05, 0x0D, 0xE5, 0x0D, 0x70, 0x02, 0x05,
+0x0C, 0x05, 0x1F, 0xE5, 0x1F, 0x70, 0x02, 0x05,
+0x1E, 0x74, 0x00, 0xF5, 0x1B, 0x02, 0xE0, 0xF1,
+0x75, 0x3F, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D,
+0x00, 0x75, 0x3C, 0x00, 0xD3, 0x22, 0x12, 0x2F,
+0x9E, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x15, 0x33,
+0xF5, 0x3E, 0xE5, 0x14, 0x33, 0xF5, 0x3D, 0x75,
+0x3C, 0x00, 0xC3, 0x22, 0xE5, 0x1C, 0x70, 0x03,
+0x75, 0x1C, 0x01, 0xC3, 0x94, 0x80, 0x40, 0x03,
+0x75, 0x1C, 0x80, 0xAA, 0x1C, 0xAD, 0x1B, 0x90,
+0xF4, 0x00, 0xC0, 0x83, 0xC0, 0x82, 0xEA, 0x60,
+0x5F, 0xAE, 0x18, 0xAF, 0x19, 0xE4, 0x90, 0xFE,
+0x48, 0xF0, 0x90, 0xFE, 0x49, 0xF0, 0x12, 0x2F,
+0x8F, 0x90, 0xFE, 0x48, 0x74, 0x7F, 0xF0, 0x90,
+0xFE, 0x49, 0x74, 0x9F, 0xF0, 0x90, 0xEB, 0xDD,
+0xE0, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xA3, 0xC0,
+0x83, 0xC0, 0x82, 0x90, 0xEB, 0xDE, 0xE0, 0xD0,
+0x82, 0xD0, 0x83, 0xF0, 0xA3, 0xC0, 0x83, 0xC0,
+0x82, 0x90, 0xEB, 0xDF, 0xE0, 0xD0, 0x82, 0xD0,
+0x83, 0xF0, 0xA3, 0xC0, 0x83, 0xC0, 0x82, 0x90,
+0xEB, 0xE0, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0xF0,
+0xA3, 0xC0, 0x83, 0xC0, 0x82, 0x1A, 0x05, 0x19,
+0xE5, 0x19, 0x70, 0x02, 0x05, 0x18, 0x80, 0x9E,
+0xD0, 0x82, 0xD0, 0x83, 0xE5, 0x1C, 0x25, 0xE0,
+0xFF, 0x74, 0x00, 0x33, 0xFE, 0xEF, 0x25, 0xE0,
+0xFF, 0xEE, 0x33, 0xFE, 0x90, 0xFF, 0x2A, 0xEE,
+0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0xE1, 0x70, 0x20,
+0x1F, 0x02, 0xC3, 0x22, 0x30, 0x1E, 0x02, 0x80,
+0xF9, 0xD2, 0x1A, 0x75, 0x17, 0x00, 0x75, 0x3F,
+0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75,
+0x3C, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8, 0x90,
+0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08, 0xA3,
+0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07, 0xA3,
+0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3, 0x40,
+0x0E, 0x75, 0x1C, 0xF8, 0x75, 0x1D, 0xFF, 0x12,
+0xE7, 0x77, 0x40, 0x05, 0x12, 0x2F, 0x9E, 0xC3,
+0x22, 0x22, 0x20, 0x1F, 0x02, 0xC3, 0x22, 0x30,
+0x1E, 0x02, 0x80, 0xF9, 0xD2, 0x1A, 0x75, 0x3F,
+0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75,
+0x3C, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8, 0x90,
+0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08, 0xA3,
+0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07, 0xA3,
+0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3, 0x40,
+0x08, 0x12, 0xE6, 0x6F, 0x40, 0x05, 0x12, 0x2F,
+0x9E, 0xC3, 0x22, 0x22, 0x20, 0x1F, 0x02, 0xC3,
+0x22, 0x30, 0x1E, 0x02, 0x80, 0xF9, 0xC3, 0xE5,
+0x3D, 0x13, 0xF5, 0x14, 0xE5, 0x3E, 0x13, 0xF5,
+0x15, 0x30, 0x21, 0x39, 0x90, 0xEB, 0x2A, 0xE0,
+0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0x90, 0xEA, 0x47, 0xE0, 0x14, 0xFB,
+0x60, 0x12, 0xC3, 0xEC, 0x13, 0xFC, 0xED, 0x13,
+0xFD, 0xEE, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xC3,
+0xEB, 0x13, 0x80, 0xEB, 0x8E, 0x18, 0x8F, 0x19,
+0x90, 0xEB, 0x2D, 0xE0, 0xFF, 0x90, 0xEA, 0x47,
+0xE0, 0x14, 0x5F, 0xF5, 0x1B, 0xD2, 0x1C, 0xC3,
+0x90, 0xEA, 0x47, 0xE0, 0x95, 0x1B, 0xF5, 0x16,
+0xE5, 0x14, 0x70, 0x0A, 0xD3, 0xE5, 0x16, 0x95,
+0x15, 0x40, 0x03, 0x85, 0x15, 0x16, 0x90, 0xEA,
+0x5C, 0xE0, 0xF8, 0x90, 0xEB, 0x6D, 0xE0, 0x65,
+0x18, 0x70, 0x08, 0xA3, 0xE0, 0x65, 0x19, 0x70,
+0x03, 0x80, 0x07, 0xA3, 0xA3, 0xD8, 0xEF, 0xC3,
+0x80, 0x01, 0xD3, 0x50, 0x03, 0x02, 0xE4, 0x34,
+0x20, 0x21, 0x2F, 0xC2, 0x42, 0x75, 0x10, 0x00,
+0xE5, 0x10, 0x65, 0x1B, 0x70, 0x03, 0x02, 0xE3,
+0x7A, 0x12, 0x2F, 0x89, 0x40, 0x03, 0x02, 0xE4,
+0x31, 0xE5, 0x10, 0x70, 0x11, 0xC0, 0x1C, 0xC0,
+0x1B, 0x75, 0x1B, 0x00, 0x75, 0x1C, 0xEF, 0x12,
+0x2F, 0x95, 0xD0, 0x1B, 0xD0, 0x1C, 0x05, 0x10,
+0x80, 0xD6, 0x75, 0x17, 0x00, 0x30, 0x21, 0x06,
+0xC0, 0x18, 0xC0, 0x19, 0x80, 0x10, 0x75, 0x1C,
+0xF8, 0x75, 0x1D, 0xFF, 0xC0, 0x18, 0xC0, 0x19,
+0x85, 0x11, 0x18, 0x85, 0x12, 0x19, 0xE5, 0x16,
+0xB4, 0x01, 0x0C, 0x12, 0xE5, 0x11, 0x40, 0x13,
+0xD0, 0x19, 0xD0, 0x18, 0x02, 0xE4, 0x31, 0x12,
+0x2F, 0x92, 0x40, 0x07, 0xD0, 0x19, 0xD0, 0x18,
+0x02, 0xE4, 0x31, 0xD0, 0x19, 0xD0, 0x18, 0xE5,
+0x10, 0x25, 0x16, 0xF5, 0x10, 0x20, 0x21, 0x3A,
+0x90, 0xEA, 0x47, 0xE0, 0x65, 0x10, 0x60, 0x0C,
+0x12, 0x2F, 0x89, 0x40, 0x03, 0x02, 0xE4, 0x31,
+0x05, 0x10, 0x80, 0xEC, 0x20, 0x42, 0x05, 0x12,
+0xE7, 0x77, 0x80, 0x09, 0x75, 0x1B, 0x00, 0x75,
+0x1C, 0x7F, 0x12, 0x2F, 0x95, 0x75, 0x17, 0x00,
+0x85, 0x11, 0x18, 0x85, 0x12, 0x19, 0x75, 0x1B,
+0x00, 0x75, 0x1C, 0xF8, 0x75, 0x1D, 0xFF, 0x12,
+0xE6, 0x6F, 0xC3, 0xE5, 0x15, 0x95, 0x16, 0xF5,
+0x15, 0xE5, 0x14, 0x94, 0x00, 0xF5, 0x14, 0xE5,
+0x15, 0x45, 0x14, 0x60, 0x16, 0x05, 0x19, 0xE5,
+0x19, 0x70, 0x02, 0x05, 0x18, 0x05, 0x0D, 0xE5,
+0x0D, 0x70, 0x02, 0x05, 0x0C, 0x75, 0x1B, 0x00,
+0x02, 0xE3, 0x0F, 0x75, 0x3F, 0x00, 0x75, 0x3E,
+0x00, 0x75, 0x3D, 0x00, 0x75, 0x3C, 0x00, 0xD3,
+0x22, 0x12, 0x2F, 0x9E, 0x90, 0xFF, 0x09, 0xE0,
+0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80,
+0xF0, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x15, 0x33,
+0xF5, 0x3E, 0xE5, 0x14, 0x33, 0xF5, 0x3D, 0x75,
+0x3C, 0x00, 0xC3, 0x22, 0x75, 0x1A, 0x20, 0x12,
+0x2F, 0xA4, 0x40, 0x03, 0x02, 0xE5, 0x0F, 0x79,
+0x0F, 0x90, 0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49,
+0xF0, 0x78, 0xD2, 0x12, 0x2F, 0xAA, 0x30, 0x1C,
+0x5A, 0x30, 0x2D, 0x05, 0x75, 0x16, 0x01, 0x80,
+0x03, 0x75, 0x16, 0x08, 0x75, 0x08, 0x00, 0xE5,
+0x08, 0x65, 0x16, 0x70, 0x02, 0x80, 0x55, 0x90,
+0xFF, 0x09, 0x30, 0x25, 0x0B, 0xE0, 0x30, 0xE1,
+0xF9, 0x90, 0xFF, 0x09, 0xF0, 0xD3, 0x80, 0x01,
+0xC3, 0x50, 0x0F, 0xAF, 0x08, 0x7C, 0xF0, 0x7D,
+0x00, 0xAB, 0x4D, 0xAA, 0x4C, 0x12, 0x2F, 0xBF,
+0x40, 0x10, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1,
+0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x02,
+0xE5, 0x0A, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1,
+0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x05,
+0x08, 0x80, 0xB4, 0x7C, 0xF0, 0x7D, 0x00, 0x7B,
+0x00, 0x7A, 0x02, 0x7F, 0x00, 0x12, 0x2F, 0xBF,
+0x40, 0x02, 0x80, 0x2E, 0x20, 0x1D, 0x08, 0x30,
+0x25, 0x03, 0x30, 0x24, 0xF7, 0xD2, 0x24, 0x30,
+0x24, 0x02, 0xC3, 0x22, 0x79, 0x55, 0x7A, 0x01,
+0x12, 0x2F, 0xAD, 0x40, 0x02, 0x80, 0x18, 0x12,
+0x2F, 0xB0, 0x30, 0x24, 0x02, 0xC3, 0x22, 0xEF,
+0x54, 0xC1, 0x64, 0x80, 0x60, 0x02, 0x80, 0x02,
+0xD3, 0x22, 0x79, 0xC3, 0x12, 0x2F, 0x9B, 0xC3,
+0x22, 0xC0, 0x16, 0x30, 0x1E, 0x03, 0x02, 0xE5,
+0x5C, 0x75, 0x09, 0x00, 0x7C, 0x08, 0x30, 0x2D,
+0x02, 0x7C, 0x20, 0x20, 0x25, 0x03, 0x02, 0xE5,
+0x5C, 0xC0, 0x04, 0x12, 0xE4, 0x54, 0xD0, 0x04,
+0x50, 0x04, 0xD0, 0x16, 0xD3, 0x22, 0xA9, 0x09,
+0xE9, 0x54, 0x07, 0x60, 0x0C, 0x90, 0xFE, 0x4C,
+0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x80,
+0x09, 0x20, 0x25, 0x03, 0x02, 0xE5, 0x5C, 0x12,
+0x2F, 0xB3, 0x05, 0x09, 0xE5, 0x09, 0x6C, 0x60,
+0x03, 0x02, 0xE5, 0x23, 0xD0, 0x16, 0xC3, 0x22,
+0xC0, 0x03, 0x75, 0x1A, 0x00, 0x12, 0x2F, 0xB6,
+0x40, 0x04, 0xD0, 0x03, 0xC3, 0x22, 0xC2, 0x41,
+0x79, 0xAA, 0x7A, 0x00, 0x12, 0x2F, 0xAD, 0x50,
+0xF1, 0xD0, 0x03, 0x1B, 0x8B, 0x08, 0xC2, 0x40,
+0x20, 0x20, 0x08, 0x30, 0x25, 0x03, 0x30, 0x24,
+0xF7, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22,
+0x12, 0x2F, 0xB0, 0xC2, 0x20, 0xC2, 0x24, 0xEF,
+0x54, 0xE1, 0xFF, 0x30, 0xE0, 0x03, 0x02, 0xE6,
+0x6D, 0x20, 0xE6, 0x0F, 0x30, 0xE7, 0x02, 0xD2,
+0x40, 0x20, 0xE5, 0x19, 0x64, 0x80, 0x70, 0x03,
+0x02, 0xE6, 0x4B, 0x12, 0x2F, 0xB9, 0x40, 0x03,
+0x02, 0xE6, 0x68, 0x90, 0xEB, 0xCA, 0xE0, 0x54,
+0x15, 0x60, 0x02, 0xD2, 0x41, 0xE5, 0x08, 0x70,
+0x0E, 0x20, 0x40, 0x0B, 0x79, 0x33, 0x7A, 0x01,
+0x12, 0x2F, 0xAD, 0x40, 0x02, 0xC1, 0x6D, 0x12,
+0x2F, 0xBC, 0x40, 0x02, 0xC1, 0x6D, 0x90, 0xEB,
+0xDE, 0xE0, 0x54, 0x30, 0x64, 0x30, 0x60, 0x02,
+0xC1, 0x6D, 0x79, 0x00, 0x90, 0xFE, 0x46, 0xE0,
+0x54, 0xF0, 0x49, 0xF0, 0x79, 0x00, 0x78, 0x2D,
+0x12, 0x2F, 0xAA, 0x90, 0xFF, 0x09, 0x30, 0x25,
+0x07, 0xE0, 0x30, 0xE5, 0xF9, 0xD3, 0x80, 0x01,
+0xC3, 0x40, 0x02, 0x80, 0x5B, 0xC0, 0x01, 0x7E,
+0xF4, 0x7F, 0x00, 0x7D, 0x00, 0x7C, 0x02, 0x12,
+0x2F, 0xC2, 0xD0, 0x01, 0x40, 0x09, 0x09, 0xE9,
+0x64, 0x20, 0x70, 0xD2, 0x02, 0xE6, 0x68, 0x90,
+0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x00,
+0xF0, 0x20, 0x1D, 0x08, 0x30, 0x25, 0x03, 0x30,
+0x24, 0xF7, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3,
+0x22, 0x30, 0x40, 0x02, 0x80, 0x05, 0x15, 0x08,
+0x02, 0xE5, 0x80, 0x30, 0x41, 0x16, 0x79, 0xCC,
+0x12, 0x2F, 0x9B, 0xC2, 0x1A, 0x90, 0xEA, 0x47,
+0xE0, 0x65, 0x1B, 0x60, 0x07, 0x12, 0x2F, 0x8C,
+0x05, 0x1B, 0x80, 0xF1, 0xD2, 0x1A, 0xD3, 0x22,
+0x79, 0xC3, 0x12, 0x2F, 0x9B, 0xC3, 0x22, 0xC0,
+0x08, 0x30, 0x1E, 0x02, 0x80, 0x33, 0x75, 0x1A,
+0x40, 0x75, 0x1D, 0xFF, 0x75, 0x08, 0x00, 0x20,
+0x25, 0x02, 0x80, 0x25, 0x12, 0xE6, 0xAD, 0x50,
+0x04, 0xD0, 0x08, 0xD3, 0x22, 0xA9, 0x08, 0xE9,
+0x54, 0x07, 0x60, 0x02, 0x80, 0x08, 0x20, 0x25,
+0x02, 0x80, 0x0E, 0x12, 0x2F, 0xB3, 0x05, 0x08,
+0xE5, 0x08, 0x64, 0x20, 0x60, 0x03, 0x02, 0xE6,
+0x7F, 0xD0, 0x08, 0xC3, 0x22, 0x90, 0xFE, 0x4C,
+0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0xC2,
+0x1D, 0xC2, 0x24, 0x90, 0xFE, 0x50, 0x74, 0x87,
+0xF0, 0x90, 0xFE, 0x40, 0x74, 0x00, 0xF0, 0x90,
+0xFE, 0x40, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0x40,
+0x74, 0x10, 0xF0, 0x90, 0xFE, 0x40, 0x74, 0x0F,
+0xF0, 0x90, 0xFE, 0x57, 0x74, 0x0F, 0xF0, 0x90,
+0xFE, 0x44, 0x74, 0x01, 0xF0, 0x20, 0x1D, 0x08,
+0x30, 0x25, 0x03, 0x30, 0x24, 0xF7, 0xD2, 0x24,
+0x30, 0x24, 0x02, 0xC3, 0x22, 0x79, 0x00, 0x90,
+0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, 0xF0, 0x90,
+0xFE, 0x4D, 0x30, 0x25, 0x07, 0xE0, 0x30, 0xE5,
+0xF9, 0xD3, 0x80, 0x01, 0xC3, 0x40, 0x01, 0x22,
+0x78, 0xB4, 0x12, 0x2F, 0xAA, 0x90, 0xEA, 0x44,
+0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x78, 0x17, 0x7D,
+0x09, 0xE6, 0x08, 0x90, 0xFE, 0x40, 0xF0, 0xDD,
+0xF8, 0x74, 0xFF, 0x90, 0xFE, 0x40, 0xF0, 0xF0,
+0xF0, 0xF0, 0xC2, 0x1D, 0xC2, 0x24, 0xF0, 0x20,
+0x1D, 0x08, 0x30, 0x25, 0x03, 0x30, 0x24, 0xF7,
+0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22, 0x90,
+0xFE, 0x4E, 0x30, 0x25, 0x07, 0xE0, 0x30, 0xE6,
+0xF9, 0xD3, 0x80, 0x01, 0xC3, 0x79, 0x55, 0x7A,
+0x01, 0x12, 0x2F, 0xAD, 0x40, 0x02, 0x80, 0x13,
+0x12, 0x2F, 0xB0, 0x30, 0x24, 0x02, 0xC3, 0x22,
+0xEF, 0x20, 0xE0, 0x07, 0x54, 0xC0, 0xB4, 0x80,
+0x02, 0x80, 0x02, 0xC3, 0x22, 0xD3, 0x22, 0x30,
+0x1E, 0x02, 0x80, 0x0A, 0x12, 0xE7, 0x88, 0x40,
+0x03, 0x02, 0xE7, 0x86, 0xD3, 0x22, 0xC3, 0x22,
+0xC0, 0x08, 0x75, 0x08, 0x00, 0x20, 0x25, 0x02,
+0x80, 0x25, 0x12, 0x2F, 0xA1, 0x50, 0x03, 0xD0,
+0x08, 0x22, 0xA9, 0x08, 0xE9, 0x54, 0x07, 0x60,
+0x02, 0x80, 0x09, 0xA2, 0x25, 0x40, 0x02, 0x80,
+0x0E, 0x12, 0x2F, 0xB3, 0x05, 0x08, 0xE5, 0x08,
+0x64, 0x20, 0x60, 0x03, 0x02, 0xE7, 0x8D, 0xD0,
+0x08, 0xC3, 0x22, 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, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x4D, 0x53, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 };
+
+BYTE SM_Init[] = {
+0x7B, 0x09, 0x7C, 0xF0, 0x7D, 0x10, 0x7E, 0xE9,
+0x7F, 0xCC, 0x12, 0x2F, 0x71, 0x90, 0xE9, 0xCC,
+0xE0, 0xB4, 0x07, 0x12, 0x90, 0xFF, 0x09, 0xE0,
+0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80,
+0xF0, 0x12, 0x2F, 0x5C, 0xD3, 0x22, 0x78, 0x00,
+0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x0A,
+0x20, 0x0A, 0x03, 0x02, 0xE0, 0xD0, 0x7F, 0x00,
+0x12, 0x2F, 0xCB, 0x20, 0x01, 0x05, 0xC2, 0x25,
+0x02, 0xE0, 0xEB, 0xC3, 0xE8, 0x94, 0x02, 0x40,
+0x03, 0x02, 0xE0, 0xD0, 0xC0, 0x00, 0x90, 0xFE,
+0x66, 0x74, 0x90, 0xF0, 0x12, 0xE1, 0x40, 0x90,
+0xFF, 0x95, 0xE0, 0xC2, 0xE4, 0xF0, 0x90, 0xFF,
+0x97, 0x74, 0x01, 0xF0, 0x7E, 0x01, 0x7F, 0x90,
+0x12, 0x2F, 0x74, 0x90, 0xFF, 0x97, 0x74, 0x03,
+0xF0, 0x90, 0xFE, 0xC5, 0xE4, 0xF0, 0x74, 0x00,
+0x90, 0xFE, 0x6A, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0,
+0xA3, 0xF0, 0x7E, 0x23, 0x7F, 0xDC, 0x12, 0x2F,
+0x74, 0x12, 0x2F, 0x5C, 0x90, 0xFE, 0x64, 0xE0,
+0x54, 0x01, 0x60, 0x04, 0xD2, 0x02, 0x80, 0x02,
+0xC2, 0x02, 0x90, 0xFF, 0x95, 0xE0, 0xD2, 0xE4,
+0xF0, 0x78, 0x10, 0x79, 0x04, 0x12, 0xE1, 0x71,
+0x50, 0x3A, 0x90, 0xE9, 0xC6, 0xE0, 0x90, 0xE9,
+0xC3, 0xF0, 0x78, 0x9A, 0x79, 0x04, 0x12, 0xE1,
+0x71, 0x50, 0x29, 0x90, 0xE9, 0xC7, 0xE0, 0xB4,
+0xB5, 0x22, 0x90, 0xE9, 0xC4, 0xF0, 0xD0, 0x00,
+0xD2, 0x00, 0xC2, 0x01, 0xC2, 0x25, 0x80, 0x1B,
+0xC2, 0x00, 0xD2, 0x01, 0x74, 0xFF, 0x90, 0xE9,
+0xC3, 0xF0, 0xA3, 0xF0, 0x51, 0x01, 0xC2, 0x0A,
+0xC2, 0x02, 0x80, 0x07, 0xD0, 0x00, 0x05, 0x00,
+0x02, 0xE0, 0x43, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0,
+0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC, 0xE4,
+0xA2, 0x0A, 0x92, 0xE0, 0xA2, 0x00, 0x92, 0xE1,
+0xA2, 0x01, 0x92, 0xE2, 0xA2, 0x02, 0x92, 0xE6,
+0xA2, 0x25, 0x92, 0xE7, 0x90, 0xF4, 0x00, 0xF0,
+0x90, 0xE9, 0xC3, 0xE0, 0x90, 0xF4, 0x01, 0xF0,
+0x90, 0xE9, 0xC4, 0xE0, 0x90, 0xF4, 0x02, 0xF0,
+0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74,
+0x00, 0xF0, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
+0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
+0x90, 0xFE, 0x71, 0xE4, 0xF0, 0x90, 0xFE, 0x72,
+0x74, 0x01, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0x0C,
+0xF0, 0x90, 0xFE, 0x64, 0x74, 0x00, 0x45, 0x4E,
+0xF0, 0x90, 0xFE, 0x64, 0xE0, 0x54, 0x10, 0x60,
+0x08, 0x90, 0xFE, 0x72, 0x74, 0x81, 0xF0, 0xD3,
+0x22, 0x90, 0xFE, 0x64, 0x74, 0x08, 0xF0, 0xC3,
+0x22, 0x90, 0xFE, 0x6F, 0xE9, 0x14, 0xF0, 0x90,
+0xFE, 0x70, 0xE0, 0x54, 0xFC, 0xF0, 0x90, 0xFE,
+0x68, 0x74, 0x00, 0xF0, 0xB8, 0x9A, 0x2A, 0x74,
+0x15, 0x90, 0xFE, 0x64, 0xF0, 0x74, 0x9A, 0x90,
+0xFE, 0x60, 0xF0, 0x74, 0x16, 0x90, 0xFE, 0x64,
+0xF0, 0x74, 0x00, 0x90, 0xFE, 0x60, 0xF0, 0x30,
+0x0A, 0x5D, 0x90, 0xFE, 0x64, 0xE0, 0x20, 0xE7,
+0xF6, 0x74, 0x14, 0x90, 0xFE, 0x64, 0xF0, 0x80,
+0x20, 0x90, 0xFE, 0x6E, 0xE8, 0x44, 0x01, 0xF0,
+0xC2, 0x09, 0x12, 0xE3, 0x26, 0x20, 0x08, 0x0E,
+0x12, 0xE3, 0x32, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
+0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x20, 0x09,
+0x2E, 0x7A, 0xE9, 0x7B, 0xC5, 0x7C, 0xFE, 0x7D,
+0x60, 0xB8, 0x10, 0x07, 0x90, 0xFE, 0x69, 0xE0,
+0x20, 0xE6, 0xFC, 0x8C, 0x83, 0x8D, 0x82, 0xE0,
+0x8A, 0x83, 0x8B, 0x82, 0xF0, 0xA3, 0xAA, 0x83,
+0xAB, 0x82, 0xD9, 0xE5, 0xB8, 0x9A, 0x06, 0x74,
+0x10, 0x90, 0xFE, 0x64, 0xF0, 0xD3, 0x22, 0xC3,
+0x22, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92,
+0x25, 0x20, 0x25, 0x06, 0xC2, 0x1F, 0xD2, 0x19,
+0xC3, 0x22, 0x7F, 0x02, 0x12, 0x2F, 0xCB, 0x20,
+0x19, 0x05, 0x30, 0x1F, 0x02, 0xD3, 0x22, 0x90,
+0xEA, 0x44, 0x74, 0x80, 0xF0, 0x7F, 0x10, 0x12,
+0x2F, 0xC5, 0x90, 0xFE, 0x47, 0xE0, 0x44, 0x80,
+0xF0, 0x78, 0x00, 0xE8, 0xC3, 0x94, 0x04, 0x50,
+0x0A, 0x7F, 0x88, 0x7E, 0x13, 0x12, 0xE3, 0x4D,
+0x08, 0x80, 0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54,
+0xFB, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x54, 0xBF,
+0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0,
+0x90, 0xFE, 0x45, 0xE0, 0x54, 0x7F, 0xF0, 0x90,
+0xFE, 0x46, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xFE,
+0x45, 0xE0, 0x54, 0xC7, 0x44, 0x18, 0xF0, 0x90,
+0xFE, 0x47, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0xFE,
+0x45, 0xE0, 0x44, 0x40, 0xF0, 0x7F, 0x32, 0x7E,
+0x00, 0x12, 0xE3, 0x4D, 0x90, 0xFE, 0x51, 0xE0,
+0x54, 0x33, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02,
+0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9,
+0x90, 0xFE, 0x51, 0xE0, 0x54, 0x0F, 0xF0, 0x90,
+0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04,
+0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x44, 0x74,
+0x04, 0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE2,
+0xF9, 0x90, 0xFE, 0x4C, 0xE0, 0xF0, 0x90, 0xFE,
+0x4D, 0xE0, 0xF0, 0x90, 0xFE, 0x48, 0x74, 0x7F,
+0xF0, 0x90, 0xFE, 0x49, 0x74, 0x9F, 0xF0, 0x90,
+0xFE, 0x51, 0xE0, 0x54, 0x3C, 0x44, 0x02, 0xF0,
+0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25,
+0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x46,
+0xE0, 0x44, 0x20, 0xF0, 0x79, 0x02, 0x7A, 0x06,
+0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x06, 0x7E, 0xEB,
+0x7F, 0xC9, 0x12, 0x2F, 0xA7, 0x40, 0x03, 0x02,
+0xE3, 0x04, 0xD3, 0x22, 0xE4, 0x90, 0xFE, 0x48,
+0xF0, 0x90, 0xFE, 0x49, 0xF0, 0x90, 0xFE, 0x4C,
+0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x90,
+0xFE, 0x47, 0xE0, 0x54, 0x7F, 0xF0, 0xC2, 0x25,
+0xC2, 0x1F, 0xD2, 0x19, 0xC3, 0x22, 0xC2, 0x3E,
+0x75, 0x7C, 0x00, 0x75, 0x7D, 0x00, 0x75, 0x7E,
+0x00, 0x22, 0x05, 0x7C, 0xE5, 0x7C, 0x70, 0x14,
+0x05, 0x7D, 0xE5, 0x7D, 0x70, 0x04, 0x05, 0x7E,
+0x80, 0x0A, 0xB4, 0x17, 0x07, 0xE5, 0x7E, 0xB4,
+0x06, 0x02, 0xD2, 0x3E, 0x22, 0x75, 0x8A, 0x00,
+0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65,
+0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA,
+0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3,
+0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F,
+0x40, 0xEC, 0xC2, 0x8C, 0x22, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+0x58, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 };
+
+BYTE SM_Rdwr[] = {
+0x7B, 0x0C, 0x7C, 0xF0, 0x7D, 0x10, 0x7E, 0xE9,
+0x7F, 0xCC, 0x12, 0x2F, 0x71, 0x90, 0xE9, 0xC3,
+0xE0, 0xB4, 0x73, 0x04, 0x74, 0x40, 0x80, 0x09,
+0xB4, 0x75, 0x04, 0x74, 0x40, 0x80, 0x02, 0x74,
+0xC0, 0x90, 0xFE, 0x70, 0xF0, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74,
+0x80, 0xF0, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1,
+0x92, 0x0A, 0x40, 0x01, 0x22, 0x90, 0xFE, 0x6A,
+0xE4, 0xF0, 0x90, 0xE9, 0xCC, 0xE0, 0xB4, 0x02,
+0x05, 0xD2, 0x06, 0x02, 0xE0, 0x78, 0xB4, 0x03,
+0x03, 0x02, 0xE3, 0xD0, 0xB4, 0x04, 0x03, 0x02,
+0xE1, 0xC6, 0xB4, 0x05, 0x03, 0x02, 0xE5, 0x20,
+0xB4, 0x06, 0x03, 0x02, 0xE5, 0xE0, 0xB4, 0x07,
+0x05, 0x12, 0x2F, 0x5C, 0xD3, 0x22, 0xB4, 0x08,
+0x05, 0xC2, 0x06, 0x02, 0xE6, 0x3B, 0xC3, 0x22,
+0xE5, 0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA, 0xF0,
+0xC0, 0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0, 0x12,
+0xE0, 0xD8, 0xEF, 0x70, 0x21, 0x20, 0x37, 0x07,
+0x20, 0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05, 0xD0,
+0xF0, 0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90, 0xFF,
+0x28, 0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF, 0x28,
+0xE0, 0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0, 0xF0,
+0x90, 0xE9, 0xCF, 0xE0, 0x24, 0x01, 0xF0, 0x90,
+0xE9, 0xCE, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9,
+0xCD, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0, 0x14,
+0x70, 0xB6, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
+0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
+0xC2, 0x08, 0xC2, 0x36, 0xC2, 0x37, 0xE4, 0x90,
+0xEB, 0xC2, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0xF8,
+0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90, 0xFE, 0x6B,
+0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8, 0xF0, 0x90,
+0xFE, 0x6F, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0x70,
+0xE0, 0x54, 0xFC, 0x44, 0x02, 0xF0, 0x90, 0xFE,
+0xC6, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0F, 0xF0,
+0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0, 0x74, 0x00,
+0xA3, 0xF0, 0x90, 0xFE, 0x68, 0x74, 0x21, 0xF0,
+0x90, 0xFE, 0x64, 0x74, 0x70, 0x45, 0x4E, 0xF0,
+0x90, 0xFE, 0x64, 0x74, 0x30, 0x45, 0x4E, 0xF0,
+0x30, 0x06, 0x07, 0x90, 0xFF, 0x09, 0xE0, 0x30,
+0xE5, 0xFC, 0x90, 0xFE, 0x6E, 0x74, 0x51, 0xF0,
+0x90, 0xFE, 0xC4, 0x74, 0x21, 0xF0, 0xC2, 0x09,
+0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E, 0x12, 0xE7,
+0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE, 0xD8, 0x74,
+0x01, 0xF0, 0xD2, 0x09, 0x30, 0x09, 0x03, 0x7F,
+0x00, 0x22, 0x12, 0xE7, 0xB0, 0x20, 0x36, 0x11,
+0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E,
+0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2,
+0x37, 0x30, 0x37, 0x03, 0x7F, 0x00, 0x22, 0x90,
+0xFE, 0x64, 0x74, 0x10, 0x45, 0x4E, 0xF0, 0x90,
+0xFE, 0x64, 0x74, 0x00, 0x45, 0x4E, 0xF0, 0x12,
+0x2F, 0x65, 0x12, 0x2F, 0x68, 0xBF, 0x00, 0x09,
+0x74, 0x02, 0x90, 0xEB, 0xC2, 0xF0, 0x7F, 0x00,
+0x22, 0x12, 0x2F, 0x6B, 0xBF, 0x00, 0x0F, 0x12,
+0x2F, 0x6E, 0xBF, 0x00, 0x09, 0x74, 0x01, 0x90,
+0xEB, 0xC2, 0xF0, 0x7F, 0x00, 0x22, 0x30, 0x06,
+0x0A, 0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3,
+0x74, 0x00, 0xF0, 0x7F, 0x01, 0x22, 0x12, 0xE3,
+0xAA, 0x74, 0x01, 0x90, 0xE9, 0xCB, 0xF0, 0xE5,
+0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA, 0xF0, 0xC0,
+0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0, 0x12, 0xE2,
+0x2F, 0xEF, 0x70, 0x21, 0x20, 0x37, 0x07, 0x20,
+0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05, 0xD0, 0xF0,
+0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90, 0xFF, 0x28,
+0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF, 0x28, 0xE0,
+0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0, 0xF0, 0x90,
+0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0, 0x90, 0xE9,
+0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD0,
+0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0, 0x14, 0x70,
+0xB6, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00, 0x75,
+0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22, 0xC2,
+0x08, 0xC2, 0x36, 0xC2, 0x37, 0x90, 0xFE, 0x68,
+0x74, 0x31, 0xF0, 0x90, 0xE9, 0xD0, 0xE0, 0xF8,
+0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90, 0xFE, 0x6B,
+0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8, 0xF0, 0x90,
+0xFE, 0x6F, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0x70,
+0xE0, 0x54, 0xFC, 0x44, 0x22, 0xF0, 0x90, 0xE9,
+0xCB, 0xE0, 0x70, 0x0C, 0x90, 0xFE, 0xC0, 0x74,
+0xF4, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x80, 0x0A,
+0x90, 0xFE, 0xC0, 0x74, 0xF0, 0xF0, 0xA3, 0x74,
+0x00, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0xF0, 0x45,
+0x4E, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0xB0, 0x45,
+0x4E, 0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x81, 0xF0,
+0x90, 0xE9, 0xCB, 0xE0, 0x70, 0x0D, 0x90, 0xFE,
+0xC6, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0F, 0xF0,
+0x02, 0xE3, 0x56, 0x20, 0x2D, 0x03, 0x02, 0xE2,
+0xEF, 0x90, 0xFE, 0xC6, 0x74, 0x01, 0xF0, 0xA3,
+0x74, 0xFF, 0xF0, 0x90, 0xFF, 0x09, 0x30, 0x0A,
+0x04, 0xE0, 0x30, 0xE1, 0xF9, 0x90, 0xFE, 0xC4,
+0x74, 0x23, 0xF0, 0x12, 0xE7, 0xB0, 0x20, 0x36,
+0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30,
+0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0,
+0xD2, 0x37, 0x30, 0x37, 0x02, 0x61, 0xA7, 0x90,
+0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF,
+0x23, 0x74, 0x80, 0xF0, 0x02, 0xE3, 0x3F, 0x90,
+0xFE, 0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x3F, 0xF0,
+0x78, 0x08, 0xC0, 0x00, 0xC2, 0x36, 0xC2, 0x37,
+0x90, 0xFF, 0x09, 0x30, 0x0A, 0x04, 0xE0, 0x30,
+0xE1, 0xF9, 0x90, 0xFE, 0xC4, 0x74, 0x23, 0xF0,
+0x12, 0xE7, 0xB0, 0x20, 0x36, 0x11, 0x20, 0x37,
+0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF4, 0x90,
+0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x37, 0x90,
+0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF,
+0x23, 0x74, 0x80, 0xF0, 0x30, 0x37, 0x04, 0xD0,
+0x00, 0x80, 0x6C, 0xD0, 0x00, 0xD8, 0xBB, 0xC2,
+0x36, 0xC2, 0x37, 0x90, 0xFE, 0xC6, 0xE4, 0xF0,
+0xA3, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0xC0, 0x74,
+0xF6, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE,
+0xC4, 0x74, 0x23, 0xF0, 0x12, 0xE7, 0xB0, 0x20,
+0x36, 0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC,
+0x30, 0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01,
+0xF0, 0xD2, 0x37, 0x30, 0x37, 0x02, 0x80, 0x2F,
+0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E,
+0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
+0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x30, 0x09,
+0x02, 0x80, 0x14, 0x90, 0xFE, 0x64, 0x74, 0x90,
+0x45, 0x4E, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0x80,
+0x45, 0x4E, 0xF0, 0x12, 0x2F, 0x59, 0x22, 0x7F,
+0x00, 0x22, 0x90, 0xF6, 0x00, 0x7F, 0x06, 0x74,
+0xFF, 0xF0, 0xA3, 0xDF, 0xFC, 0x7B, 0x02, 0x7C,
+0xE9, 0x7D, 0xD3, 0x7E, 0xF6, 0x7F, 0x06, 0x12,
+0x2F, 0x71, 0x7B, 0x02, 0x7C, 0xE9, 0x7D, 0xD3,
+0x7E, 0xF6, 0x7F, 0x0B, 0x12, 0x2F, 0x71, 0x22,
+0x90, 0xFE, 0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x0F,
+0xF0, 0x90, 0xFE, 0x6F, 0xF0, 0x90, 0xFE, 0x70,
+0xE0, 0x54, 0xFC, 0xF0, 0x90, 0xFE, 0xC0, 0x74,
+0xF6, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE,
+0x68, 0x74, 0x21, 0xF0, 0x90, 0xFE, 0x66, 0xE0,
+0x54, 0xEF, 0xF0, 0x90, 0xE9, 0xD3, 0xE0, 0xF5,
+0x08, 0xA3, 0xE0, 0xF5, 0x09, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE5, 0xFC, 0xE4, 0xF5, 0x10, 0x7E,
+0xF4, 0x7F, 0x00, 0xC0, 0x06, 0xC0, 0x07, 0xC2,
+0x36, 0xC2, 0x37, 0xC2, 0x09, 0x90, 0xE9, 0xCD,
+0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90,
+0xFE, 0x6B, 0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8,
+0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x71, 0xF0, 0x90,
+0xFE, 0xC4, 0x74, 0x21, 0xF0, 0x90, 0xFE, 0x65,
+0x12, 0xE7, 0xB0, 0xE0, 0x20, 0xE4, 0x11, 0x12,
+0xE7, 0xBC, 0x30, 0x3E, 0xF6, 0x90, 0xFE, 0xD8,
+0x74, 0x01, 0xF0, 0xD2, 0x09, 0x02, 0xE4, 0x72,
+0x74, 0x10, 0xF0, 0x12, 0xE7, 0xB0, 0x20, 0x36,
+0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30,
+0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0,
+0xD2, 0x37, 0x20, 0x09, 0x05, 0x20, 0x37, 0x02,
+0x80, 0x10, 0x90, 0xFE, 0x66, 0xE0, 0x44, 0x10,
+0xF0, 0x12, 0x2F, 0x5C, 0xD0, 0x07, 0xD0, 0x06,
+0xC3, 0x22, 0xD0, 0x07, 0xD0, 0x06, 0x7B, 0x10,
+0x7C, 0xF6, 0x7D, 0x00, 0x12, 0x2F, 0x71, 0x05,
+0x10, 0xC3, 0xE5, 0x09, 0x94, 0x01, 0xF5, 0x09,
+0xE5, 0x08, 0x94, 0x00, 0xF5, 0x08, 0x45, 0x09,
+0x70, 0x03, 0x02, 0xE4, 0xEF, 0x90, 0xE9, 0xCF,
+0xE0, 0x24, 0x20, 0xF0, 0x90, 0xE9, 0xCE, 0xE0,
+0x34, 0x00, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0x34,
+0x00, 0xF0, 0xC3, 0xEF, 0x24, 0x10, 0xFF, 0xEE,
+0x34, 0x00, 0xFE, 0xE5, 0x10, 0x64, 0x20, 0x60,
+0x03, 0x02, 0xE4, 0x13, 0x90, 0xFF, 0x2A, 0x74,
+0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x75, 0x10,
+0x00, 0x7E, 0xF4, 0x7F, 0x00, 0x90, 0xFF, 0x09,
+0xE0, 0x30, 0xE5, 0xFC, 0x02, 0xE4, 0x13, 0xE5,
+0x10, 0x60, 0x17, 0x7E, 0x00, 0x7F, 0x00, 0x78,
+0x04, 0xC3, 0x33, 0xFF, 0xEE, 0x33, 0xFE, 0xEF,
+0xD8, 0xF8, 0x90, 0xFF, 0x2A, 0xEE, 0xF0, 0xA3,
+0xEF, 0xF0, 0x90, 0xFE, 0x66, 0xE0, 0x44, 0x10,
+0xF0, 0x12, 0x2F, 0x5C, 0x78, 0x00, 0x88, 0x3C,
+0x88, 0x3D, 0x88, 0x3E, 0x88, 0x3F, 0xD3, 0x22,
+0x12, 0x2F, 0x5F, 0x12, 0x2F, 0x62, 0x90, 0xFE,
+0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0x90,
+0xFE, 0x6F, 0xF0, 0x90, 0xFE, 0x70, 0xE0, 0x54,
+0xFC, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF6, 0xF0,
+0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0x68, 0x74,
+0x31, 0xF0, 0x90, 0xE9, 0xD3, 0xE0, 0xF8, 0xC0,
+0x00, 0xC2, 0x08, 0xC2, 0x36, 0xC2, 0x37, 0x90,
+0xE9, 0xD0, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3,
+0xE0, 0x90, 0xFE, 0x6B, 0xF0, 0xA3, 0xE9, 0xF0,
+0xA3, 0xE8, 0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x81,
+0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x23, 0xF0, 0x12,
+0xE7, 0xB0, 0x20, 0x36, 0x11, 0x20, 0x37, 0x0E,
+0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF4, 0x90, 0xFE,
+0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x37, 0x30, 0x37,
+0x07, 0xD0, 0x00, 0x12, 0x2F, 0x5C, 0xC3, 0x22,
+0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E,
+0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
+0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x20, 0x09,
+0xE0, 0x90, 0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0,
+0x90, 0xE9, 0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90,
+0xE9, 0xD0, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0x00,
+0x18, 0xE8, 0x60, 0x03, 0x02, 0xE5, 0x4F, 0x12,
+0x2F, 0x5C, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
+0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
+0x90, 0xE9, 0xD0, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9,
+0xA3, 0xE0, 0x90, 0xFE, 0x6B, 0xF0, 0xA3, 0xE9,
+0xF0, 0xA3, 0xE8, 0xF0, 0x90, 0xFE, 0x68, 0x74,
+0x00, 0xF0, 0xC2, 0x08, 0x90, 0xFE, 0x6E, 0x74,
+0xB1, 0xF0, 0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20,
+0x08, 0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7,
+0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09,
+0x20, 0x09, 0x1E, 0x90, 0xFE, 0x70, 0xE0, 0x44,
+0x10, 0xF0, 0x54, 0xEF, 0xF0, 0x12, 0x2F, 0x59,
+0xEF, 0x60, 0x0E, 0x75, 0x3C, 0x00, 0x75, 0x3D,
+0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3,
+0x22, 0xC3, 0x22, 0x7B, 0x03, 0x7C, 0xE9, 0x7D,
+0xCD, 0x7E, 0xE9, 0x7F, 0xD7, 0x12, 0x2F, 0x71,
+0x12, 0xE3, 0xAA, 0x90, 0xE9, 0xD5, 0xE0, 0x60,
+0x12, 0xF9, 0x12, 0xE7, 0x17, 0x40, 0x01, 0x22,
+0x90, 0xF6, 0x00, 0x78, 0x06, 0x74, 0xFF, 0xF0,
+0xA3, 0xD8, 0xFC, 0x74, 0x01, 0x90, 0xE9, 0xCB,
+0xF0, 0xE5, 0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA,
+0xF0, 0xC0, 0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0,
+0x12, 0xE2, 0x2F, 0xEF, 0x70, 0x21, 0x20, 0x37,
+0x07, 0x20, 0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05,
+0xD0, 0xF0, 0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90,
+0xFF, 0x28, 0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF,
+0x28, 0xE0, 0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0,
+0xF0, 0x90, 0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0,
+0x90, 0xE9, 0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90,
+0xE9, 0xD0, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0,
+0x14, 0x70, 0xB6, 0x90, 0xE9, 0xD5, 0xE0, 0xF8,
+0x90, 0xE9, 0xCA, 0xE0, 0x28, 0xF5, 0xF0, 0xC3,
+0x74, 0x20, 0x95, 0xF0, 0x60, 0x22, 0xF9, 0x90,
+0xE9, 0xCA, 0xE0, 0xF5, 0xF0, 0x90, 0xE9, 0xCF,
+0xE0, 0x25, 0xF0, 0xF0, 0x90, 0xE9, 0xCE, 0xE0,
+0x34, 0x00, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0x34,
+0x00, 0xF0, 0x12, 0xE7, 0x17, 0x40, 0x01, 0x22,
+0x90, 0xE9, 0xD6, 0xE0, 0x70, 0x13, 0x7B, 0x03,
+0x7C, 0xE9, 0x7D, 0xD7, 0x7E, 0xE9, 0x7F, 0xD0,
+0x12, 0x2F, 0x71, 0x12, 0xE5, 0xE0, 0x40, 0x01,
+0x22, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00, 0x75,
+0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22, 0x90,
+0xE9, 0xD6, 0xE0, 0x60, 0x18, 0x74, 0xFF, 0x90,
+0xF4, 0x00, 0x78, 0xFF, 0xF0, 0xA3, 0x18, 0xB8,
+0x00, 0xFA, 0x78, 0xFF, 0xF0, 0xA3, 0x18, 0xB8,
+0x00, 0xFA, 0xF0, 0xA3, 0xF0, 0xC0, 0x01, 0x12,
+0xE7, 0x70, 0x40, 0x04, 0xD0, 0x01, 0xC3, 0x22,
+0x90, 0xE9, 0xCF, 0xE0, 0x24, 0x01, 0xF0, 0x90,
+0xE9, 0xCE, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9,
+0xCD, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD2,
+0xE0, 0x24, 0x01, 0xF0, 0x90, 0xE9, 0xD1, 0xE0,
+0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD0, 0xE0, 0x34,
+0x00, 0xF0, 0xD0, 0x01, 0xD9, 0xC7, 0xD3, 0x22,
+0xC2, 0x06, 0x90, 0xE9, 0xD6, 0xE0, 0x70, 0x28,
+0x12, 0xE0, 0xD8, 0xEF, 0x60, 0x03, 0x02, 0xE7,
+0xA0, 0x90, 0xEB, 0xC2, 0xE0, 0x60, 0x17, 0x64,
+0x02, 0x60, 0x15, 0x90, 0xF6, 0x00, 0x78, 0x06,
+0x74, 0xFF, 0xF0, 0xA3, 0xD8, 0xFC, 0x74, 0xF0,
+0x90, 0xF6, 0x04, 0xF0, 0x80, 0x02, 0xC3, 0x22,
+0xE4, 0x90, 0xE9, 0xCB, 0xF0, 0x12, 0xE2, 0x2F,
+0xEF, 0x70, 0x03, 0x02, 0xE7, 0x81, 0xD3, 0x22,
+0xC2, 0x3E, 0x75, 0x7C, 0x00, 0x75, 0x7D, 0x00,
+0x75, 0x7E, 0x00, 0x22, 0x05, 0x7C, 0xE5, 0x7C,
+0x70, 0x14, 0x05, 0x7D, 0xE5, 0x7D, 0x70, 0x04,
+0x05, 0x7E, 0x80, 0x0A, 0xB4, 0x17, 0x07, 0xE5,
+0x7E, 0xB4, 0x06, 0x02, 0xD2, 0x3E, 0x22, 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,
+0x58, 0x44, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 };
+
diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c
new file mode 100644
index 000000000000..d4340a9da87d
--- /dev/null
+++ b/drivers/staging/keucr/ms.c
@@ -0,0 +1,956 @@
+#include <linux/slab.h>
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+#include "ms.h"
+
+//----- MS_ReaderCopyBlock() ------------------------------------------
+int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+
+ //printk("MS_ReaderCopyBlock --- PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200*len;
+ bcb->Flags = 0x00;
+ bcb->CDB[0] = 0xF0;
+ bcb->CDB[1] = 0x08;
+ bcb->CDB[4] = (BYTE)(oldphy);
+ bcb->CDB[3] = (BYTE)(oldphy>>8);
+ bcb->CDB[2] = (BYTE)(oldphy>>16);
+ bcb->CDB[7] = (BYTE)(newphy);
+ bcb->CDB[6] = (BYTE)(newphy>>8);
+ bcb->CDB[5] = (BYTE)(newphy>>16);
+ bcb->CDB[9] = (BYTE)(PhyBlockAddr);
+ bcb->CDB[8] = (BYTE)(PhyBlockAddr>>8);
+ bcb->CDB[10] = PageNum;
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_ReaderReadPage() ------------------------------------------
+int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWORD PageBuf, MS_LibTypeExtdat *ExtraDat)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ BYTE ExtBuf[4];
+ DWORD bn = PhyBlockAddr * 0x20 + PageNum;
+
+ //printk("MS --- MS_ReaderReadPage, PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Read Page Data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x02;
+ bcb->CDB[5] = (BYTE)(bn);
+ bcb->CDB[4] = (BYTE)(bn>>8);
+ bcb->CDB[3] = (BYTE)(bn>>16);
+ bcb->CDB[2] = (BYTE)(bn>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, PageBuf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Read Extra Data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x4;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[5] = (BYTE)(PageNum);
+ bcb->CDB[4] = (BYTE)(PhyBlockAddr);
+ bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8);
+ bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16);
+ bcb->CDB[6] = 0x01;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ ExtraDat->reserved = 0;
+ ExtraDat->intr = 0x80; // Not yet, ¥ý°²³], µ¥ fireware support
+ ExtraDat->status0 = 0x10; // Not yet, ¥ý°²³], µ¥ fireware support
+ ExtraDat->status1 = 0x00; // Not yet, ¥ý°²³], µ¥ fireware support
+ ExtraDat->ovrflg = ExtBuf[0];
+ ExtraDat->mngflg = ExtBuf[1];
+ ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_ReaderEraseBlock() ----------------------------------------
+int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ DWORD bn = PhyBlockAddr;
+
+ //printk("MS --- MS_ReaderEraseBlock, PhyBlockAddr = %x\n", PhyBlockAddr);
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF2;
+ bcb->CDB[1] = 0x06;
+ bcb->CDB[4] = (BYTE)(bn);
+ bcb->CDB[3] = (BYTE)(bn>>8);
+ bcb->CDB[2] = (BYTE)(bn>>16);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_CardInit() ------------------------------------------------
+int MS_CardInit(struct us_data *us)
+{
+ DWORD result=0;
+ WORD TmpBlock;
+ PBYTE PageBuffer0 = NULL, PageBuffer1 = NULL;
+ MS_LibTypeExtdat extdat;
+ WORD btBlk1st, btBlk2nd;
+ DWORD btBlk1stErred;
+
+ printk("MS_CardInit start\n");
+
+ MS_LibFreeAllocatedArea(us);
+
+ if (((PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL) ||
+ ((PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
+ {
+ result = MS_NO_MEMORY_ERROR;
+ goto exit;
+ }
+
+ btBlk1st = btBlk2nd = MS_LB_NOT_USED;
+ btBlk1stErred = 0;
+
+ for (TmpBlock=0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++)
+ {
+ switch (MS_ReaderReadPage(us, TmpBlock, 0, (DWORD *)PageBuffer0, &extdat))
+ {
+ case MS_STATUS_SUCCESS:
+ break;
+ case MS_STATUS_INT_ERROR:
+ break;
+ case MS_STATUS_ERROR:
+ default:
+ continue;
+ }
+
+ if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG)
+ continue;
+
+ if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) ||
+ (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) ||
+ (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) ||
+ (((MemStickBootBlockPage0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES))
+ continue;
+
+ if (btBlk1st != MS_LB_NOT_USED)
+ {
+ btBlk2nd = TmpBlock;
+ break;
+ }
+
+ btBlk1st = TmpBlock;
+ memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE);
+ if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER))
+ btBlk1stErred = 1;
+ }
+
+ if (btBlk1st == MS_LB_NOT_USED)
+ {
+ result = MS_STATUS_ERROR;
+ goto exit;
+ }
+
+ // write protect
+ if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON)
+ MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
+
+ result = MS_STATUS_ERROR;
+ // 1st Boot Block
+ if (btBlk1stErred == 0)
+ result = MS_LibProcessBootBlock(us, btBlk1st, PageBuffer1); // 1st
+ // 2nd Boot Block
+ if (result && (btBlk2nd != MS_LB_NOT_USED))
+ result = MS_LibProcessBootBlock(us, btBlk2nd, PageBuffer0);
+
+ if (result)
+ {
+ result = MS_STATUS_ERROR;
+ goto exit;
+ }
+
+ for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++)
+ us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
+
+ us->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK;
+
+ if (btBlk2nd != MS_LB_NOT_USED)
+ {
+ for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++)
+ us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
+ us->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK;
+ }
+
+ result = MS_LibScanLogicalBlockNumber(us, btBlk1st);
+ if (result)
+ goto exit;
+
+ for (TmpBlock=MS_PHYSICAL_BLOCKS_PER_SEGMENT; TmpBlock<us->MS_Lib.NumberOfPhyBlock; TmpBlock+=MS_PHYSICAL_BLOCKS_PER_SEGMENT)
+ {
+ if (MS_CountFreeBlock(us, TmpBlock) == 0)
+ {
+ MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
+ break;
+ }
+ }
+
+ // write
+ if (MS_LibAllocWriteBuf(us))
+ {
+ result = MS_NO_MEMORY_ERROR;
+ goto exit;
+ }
+
+ result = MS_STATUS_SUCCESS;
+
+exit:
+ if (PageBuffer1) kfree(PageBuffer1);
+ if (PageBuffer0) kfree(PageBuffer0);
+
+ printk("MS_CardInit end\n");
+ return result;
+}
+
+//----- MS_LibCheckDisableBlock() ------------------------------------
+int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock)
+{
+ PWORD PageBuf=NULL;
+ DWORD result=MS_STATUS_SUCCESS;
+ DWORD blk, index=0;
+ MS_LibTypeExtdat extdat;
+
+ if (((PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
+ {
+ result = MS_NO_MEMORY_ERROR;
+ goto exit;
+ }
+
+ MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat);
+ do
+ {
+ blk = BigEndianWORD(PageBuf[index]);
+ if (blk == MS_LB_NOT_USED)
+ break;
+ if (blk == us->MS_Lib.Log2PhyMap[0])
+ {
+ result = MS_ERROR_FLASH_READ;
+ break;
+ }
+ index++;
+ } while(1);
+
+exit:
+ if (PageBuf) kfree(PageBuf);
+ return result;
+}
+
+//----- MS_LibFreeAllocatedArea() ------------------------------------
+void MS_LibFreeAllocatedArea(struct us_data *us)
+{
+ MS_LibFreeWriteBuf(us);
+ MS_LibFreeLogicalMap(us);
+
+ us->MS_Lib.flags = 0;
+ us->MS_Lib.BytesPerSector = 0;
+ us->MS_Lib.SectorsPerCylinder = 0;
+
+ us->MS_Lib.cardType = 0;
+ us->MS_Lib.blockSize = 0;
+ us->MS_Lib.PagesPerBlock = 0;
+
+ us->MS_Lib.NumberOfPhyBlock = 0;
+ us->MS_Lib.NumberOfLogBlock = 0;
+}
+
+//----- MS_LibFreeWriteBuf() -----------------------------------------
+void MS_LibFreeWriteBuf(struct us_data *us)
+{
+ us->MS_Lib.wrtblk = (WORD)-1; //set to -1
+ MS_LibClearPageMap(us); // memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap))
+
+ if (us->MS_Lib.blkpag)
+ {
+ kfree((BYTE *)(us->MS_Lib.blkpag)); // Arnold test ...
+ us->MS_Lib.blkpag = NULL;
+ }
+
+ if (us->MS_Lib.blkext)
+ {
+ kfree((BYTE *)(us->MS_Lib.blkext)); // Arnold test ...
+ us->MS_Lib.blkext = NULL;
+ }
+}
+
+//----- MS_LibFreeLogicalMap() ---------------------------------------
+int MS_LibFreeLogicalMap(struct us_data *us)
+{
+ if (us->MS_Lib.Phy2LogMap)
+ {
+ kfree(us->MS_Lib.Phy2LogMap);
+ us->MS_Lib.Phy2LogMap = NULL;
+ }
+
+ if (us->MS_Lib.Log2PhyMap)
+ {
+ kfree(us->MS_Lib.Log2PhyMap);
+ us->MS_Lib.Log2PhyMap = NULL;
+ }
+
+ return 0;
+}
+
+//----- MS_LibProcessBootBlock() -------------------------------------
+int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData)
+{
+ MemStickBootBlockSysEnt *SysEntry;
+ MemStickBootBlockSysInf *SysInfo;
+ DWORD i, result;
+ BYTE PageNumber;
+ BYTE *PageBuffer;
+ MS_LibTypeExtdat ExtraData;
+
+ if ((PageBuffer = (BYTE *)kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
+ return (DWORD)-1;
+
+ result = (DWORD)-1;
+
+ SysInfo= &(((MemStickBootBlockPage0 *)PageData)->sysinf);
+
+ if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) ||
+ (BigEndianWORD(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) ||
+ ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) ||
+ (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) ||
+ (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) ||
+ (SysInfo->bFormatType!= MS_SYSINF_FORMAT_FAT) ||
+ (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL))
+ goto exit;
+
+ switch (us->MS_Lib.cardType = SysInfo->bCardType)
+ {
+ case MS_SYSINF_CARDTYPE_RDONLY:
+ MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
+ break;
+ case MS_SYSINF_CARDTYPE_RDWR:
+ MS_LibCtrlReset(us, MS_LIB_CTRL_RDONLY);
+ break;
+ case MS_SYSINF_CARDTYPE_HYBRID:
+ default:
+ goto exit;
+ }
+
+ us->MS_Lib.blockSize = BigEndianWORD(SysInfo->wBlockSize);
+ us->MS_Lib.NumberOfPhyBlock = BigEndianWORD(SysInfo->wBlockNumber);
+ us->MS_Lib.NumberOfLogBlock = BigEndianWORD(SysInfo->wTotalBlockNumber)- 2;
+ us->MS_Lib.PagesPerBlock = us->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE;
+ us->MS_Lib.NumberOfSegment = us->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+ us->MS_Model = BigEndianWORD(SysInfo->wMemorySize);
+
+ if (MS_LibAllocLogicalMap(us)) //Allocate to all number of logicalblock and physicalblock
+ goto exit;
+
+ MS_LibSetBootBlockMark(us, PhyBlock); //Mark the book block
+
+ SysEntry = &(((MemStickBootBlockPage0 *)PageData)->sysent);
+
+ for (i=0; i<MS_NUMBER_OF_SYSTEM_ENTRY; i++)
+ {
+ DWORD EntryOffset, EntrySize;
+
+ if ((EntryOffset = BigEndianDWORD(SysEntry->entry[i].dwStart)) == 0xffffff)
+ continue;
+
+ if ((EntrySize = BigEndianDWORD(SysEntry->entry[i].dwSize)) == 0)
+ continue;
+
+ if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO)
+ continue;
+
+ if (i == 0)
+ {
+ BYTE PrevPageNumber = 0;
+ WORD phyblk;
+
+ if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK)
+ goto exit;
+
+ while (EntrySize > 0)
+ {
+ if ((PageNumber = (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1)) != PrevPageNumber)
+ {
+ switch (MS_ReaderReadPage(us, PhyBlock, PageNumber, (DWORD *)PageBuffer, &ExtraData))
+ {
+ case MS_STATUS_SUCCESS:
+ break;
+ case MS_STATUS_WRITE_PROTECT:
+ case MS_ERROR_FLASH_READ:
+ case MS_STATUS_ERROR:
+ default:
+ goto exit;
+ }
+
+ PrevPageNumber = PageNumber;
+ }
+
+ if ((phyblk = BigEndianWORD(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff)
+ MS_LibSetInitialErrorBlock(us, phyblk);
+
+ EntryOffset += 2;
+ EntrySize -= 2;
+ }
+ }
+ else if (i == 1)
+ { // CIS/IDI
+ MemStickBootBlockIDI *idi;
+
+ if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI)
+ goto exit;
+
+ switch (MS_ReaderReadPage(us, PhyBlock, (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1), (DWORD *)PageBuffer, &ExtraData))
+ {
+ case MS_STATUS_SUCCESS:
+ break;
+ case MS_STATUS_WRITE_PROTECT:
+ case MS_ERROR_FLASH_READ:
+ case MS_STATUS_ERROR:
+ default:
+ goto exit;
+ }
+
+ idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
+ if (LittleEndianWORD(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
+ goto exit;
+
+ us->MS_Lib.BytesPerSector = LittleEndianWORD(idi->wIDIbytesPerSector);
+ if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE)
+ goto exit;
+ }
+ } // End for ..
+
+ result = 0;
+
+exit:
+ if (result) MS_LibFreeLogicalMap(us);
+ if (PageBuffer) kfree(PageBuffer);
+
+ result = 0;
+ return result;
+}
+
+//----- MS_LibAllocLogicalMap() --------------------------------------
+int MS_LibAllocLogicalMap(struct us_data *us)
+{
+ DWORD i;
+
+
+ us->MS_Lib.Phy2LogMap = (WORD *)kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL);
+ us->MS_Lib.Log2PhyMap = (WORD *)kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL);
+
+ if ((us->MS_Lib.Phy2LogMap == NULL) || (us->MS_Lib.Log2PhyMap == NULL))
+ {
+ MS_LibFreeLogicalMap(us);
+ return (DWORD)-1;
+ }
+
+ for (i = 0; i < us->MS_Lib.NumberOfPhyBlock; i++)
+ us->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED;
+
+ for (i = 0; i < us->MS_Lib.NumberOfLogBlock; i++)
+ us->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED;
+
+ return 0;
+}
+
+//----- MS_LibSetBootBlockMark() -------------------------------------
+int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk)
+{
+ return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_BOOT_BLOCK);
+}
+
+//----- MS_LibSetLogicalBlockMark() ----------------------------------
+int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark)
+{
+ if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+ return (DWORD)-1;
+
+ us->MS_Lib.Phy2LogMap[phyblk] = mark;
+
+ return 0;
+}
+
+//----- MS_LibSetInitialErrorBlock() ---------------------------------
+int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk)
+{
+ return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_INITIAL_ERROR);
+}
+
+//----- MS_LibScanLogicalBlockNumber() -------------------------------
+int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD btBlk1st)
+{
+ WORD PhyBlock, newblk, i;
+ WORD LogStart, LogEnde;
+ MS_LibTypeExtdat extdat;
+ BYTE buf[0x200];
+ DWORD count=0, index=0;
+
+ for (PhyBlock = 0; PhyBlock < us->MS_Lib.NumberOfPhyBlock;)
+ {
+ MS_LibPhy2LogRange(PhyBlock, &LogStart, &LogEnde);
+
+ for (i=0; i<MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++)
+ {
+ switch (MS_LibConv2Logical(us, PhyBlock))
+ {
+ case MS_STATUS_ERROR:
+ continue;
+ default:
+ break;
+ }
+
+ if (count == PhyBlock)
+ {
+ MS_LibReadExtraBlock(us, PhyBlock, 0, 0x80, &buf);
+ count += 0x80;
+ }
+ index = (PhyBlock % 0x80) * 4;
+
+ extdat.ovrflg = buf[index];
+ extdat.mngflg = buf[index+1];
+ extdat.logadr = MemStickLogAddr(buf[index+2], buf[index+3]);
+
+ if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
+ {
+ MS_LibSetAcquiredErrorBlock(us, PhyBlock);
+ continue;
+ }
+
+ if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL)
+ {
+ MS_LibErasePhyBlock(us, PhyBlock);
+ continue;
+ }
+
+ if (extdat.logadr != MS_LB_NOT_USED)
+ {
+ if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr))
+ {
+ MS_LibErasePhyBlock(us, PhyBlock);
+ continue;
+ }
+
+ if ((newblk = MS_LibConv2Physical(us, extdat.logadr)) != MS_LB_NOT_USED)
+ {
+ if (extdat.logadr==0)
+ {
+ MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
+ if ( MS_LibCheckDisableBlock(us, btBlk1st) )
+ {
+ MS_LibSetLogicalPair(us, extdat.logadr, newblk);
+ continue;
+ }
+ }
+
+ MS_LibReadExtra(us, newblk, 0, &extdat);
+ if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING)
+ {
+ MS_LibErasePhyBlock(us, PhyBlock);
+ continue;
+ }
+ else
+ MS_LibErasePhyBlock(us, newblk);
+ }
+
+ MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
+ }
+ }
+ } //End for ...
+
+ return MS_STATUS_SUCCESS;
+}
+
+//----- MS_LibAllocWriteBuf() ----------------------------------------
+int MS_LibAllocWriteBuf(struct us_data *us)
+{
+ us->MS_Lib.wrtblk = (WORD)-1;
+
+ us->MS_Lib.blkpag = (BYTE *)kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL);
+ us->MS_Lib.blkext = (MS_LibTypeExtdat *)kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL);
+
+ if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL))
+ {
+ MS_LibFreeWriteBuf(us);
+ return (DWORD)-1;
+ }
+
+ MS_LibClearWriteBuf(us);
+
+ return 0;
+}
+
+//----- MS_LibClearWriteBuf() ----------------------------------------
+void MS_LibClearWriteBuf(struct us_data *us)
+{
+ int i;
+
+ us->MS_Lib.wrtblk = (WORD)-1;
+ MS_LibClearPageMap(us);
+
+ if (us->MS_Lib.blkpag)
+ memset(us->MS_Lib.blkpag, 0xff, us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector);
+
+ if (us->MS_Lib.blkext)
+ {
+ for (i = 0; i < us->MS_Lib.PagesPerBlock; i++)
+ {
+ us->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT;
+ us->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT;
+ us->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT;
+ us->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED;
+ }
+ }
+}
+
+//----- MS_LibPhy2LogRange() -----------------------------------------
+void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde)
+{
+ PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+
+ if (PhyBlock)
+ {
+ *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
+ *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
+ }
+ else
+ {
+ *LogStart = 0;
+ *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;//494
+ }
+}
+
+//----- MS_LibReadExtraBlock() --------------------------------------------
+int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE blen, void *buf)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+
+ //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
+
+ // Read Extra Data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x4 * blen;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[5] = (BYTE)(PageNum);
+ bcb->CDB[4] = (BYTE)(PhyBlock);
+ bcb->CDB[3] = (BYTE)(PhyBlock>>8);
+ bcb->CDB[2] = (BYTE)(PhyBlock>>16);
+ bcb->CDB[6] = blen;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_LibReadExtra() --------------------------------------------
+int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibTypeExtdat *ExtraDat)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ BYTE ExtBuf[4];
+
+ //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum);
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x4;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[5] = (BYTE)(PageNum);
+ bcb->CDB[4] = (BYTE)(PhyBlock);
+ bcb->CDB[3] = (BYTE)(PhyBlock>>8);
+ bcb->CDB[2] = (BYTE)(PhyBlock>>16);
+ bcb->CDB[6] = 0x01;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ ExtraDat->reserved = 0;
+ ExtraDat->intr = 0x80; // Not yet, waiting for fireware support
+ ExtraDat->status0 = 0x10; // Not yet, waiting for fireware support
+ ExtraDat->status1 = 0x00; // Not yet, waiting for fireware support
+ ExtraDat->ovrflg = ExtBuf[0];
+ ExtraDat->mngflg = ExtBuf[1];
+ ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_LibSetAcquiredErrorBlock() --------------------------------
+int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk)
+{
+ WORD log;
+
+ if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+ return (DWORD)-1;
+
+ if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
+ us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
+
+ if (us->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR)
+ us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR;
+
+ return 0;
+}
+
+//----- MS_LibErasePhyBlock() ----------------------------------------
+int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk)
+{
+ WORD log;
+
+ if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+ return MS_STATUS_ERROR;
+
+ if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
+ us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
+
+ us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED;
+
+ if (MS_LibIsWritable(us))
+ {
+ switch (MS_ReaderEraseBlock(us, phyblk))
+ {
+ case MS_STATUS_SUCCESS:
+ us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED;
+ return MS_STATUS_SUCCESS;
+ case MS_ERROR_FLASH_ERASE:
+ case MS_STATUS_INT_ERROR :
+ MS_LibErrorPhyBlock(us, phyblk);
+ return MS_ERROR_FLASH_ERASE;
+ case MS_STATUS_ERROR:
+ default:
+ MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
+ MS_LibSetAcquiredErrorBlock(us, phyblk);
+ return MS_STATUS_ERROR;
+ }
+ }
+
+ MS_LibSetAcquiredErrorBlock(us, phyblk);
+
+ return MS_STATUS_SUCCESS;
+}
+
+//----- MS_LibErrorPhyBlock() ----------------------------------------
+int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk)
+{
+ if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+ return MS_STATUS_ERROR;
+
+ MS_LibSetAcquiredErrorBlock(us, phyblk);
+
+ if (MS_LibIsWritable(us))
+ return MS_LibOverwriteExtra(us, phyblk, 0, (BYTE)(~MS_REG_OVR_BKST));
+
+
+ return MS_STATUS_SUCCESS;
+}
+
+//----- MS_LibOverwriteExtra() ---------------------------------------
+int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, BYTE OverwriteFlag)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+
+ //printk("MS --- MS_LibOverwriteExtra, PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x4;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF2;
+ bcb->CDB[1] = 0x05;
+ bcb->CDB[5] = (BYTE)(PageNum);
+ bcb->CDB[4] = (BYTE)(PhyBlockAddr);
+ bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8);
+ bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16);
+ bcb->CDB[6] = OverwriteFlag;
+ bcb->CDB[7] = 0xFF;
+ bcb->CDB[8] = 0xFF;
+ bcb->CDB[9] = 0xFF;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_LibForceSetLogicalPair() ----------------------------------
+int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
+{
+ if (logblk == MS_LB_NOT_USED)
+ return 0;
+
+ if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
+ return (DWORD)-1;
+
+ us->MS_Lib.Phy2LogMap[phyblk] = logblk;
+ us->MS_Lib.Log2PhyMap[logblk] = phyblk;
+
+ return 0;
+}
+
+//----- MS_LibSetLogicalPair() ---------------------------------------
+int MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
+{
+ if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
+ return (DWORD)-1;
+
+ us->MS_Lib.Phy2LogMap[phyblk] = logblk;
+ us->MS_Lib.Log2PhyMap[logblk] = phyblk;
+
+ return 0;
+}
+
+//----- MS_CountFreeBlock() ------------------------------------------
+int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock)
+{
+ DWORD Ende, Count;
+
+ Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+ for (Count = 0; PhyBlock < Ende; PhyBlock++)
+ {
+ switch (us->MS_Lib.Phy2LogMap[PhyBlock])
+ {
+ case MS_LB_NOT_USED:
+ case MS_LB_NOT_USED_ERASED:
+ Count++;
+ default:
+ break;
+ }
+ }
+
+ return Count;
+}
+
+//----- MS_LibSearchBlockFromPhysical() ------------------------------
+int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk)
+{
+ WORD Newblk;
+ WORD blk;
+ MS_LibTypeExtdat extdat;
+
+ if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+ return MS_LB_ERROR;
+
+ for (blk = phyblk + 1; blk != phyblk; blk++)
+ {
+ if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0)
+ blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+
+ Newblk = us->MS_Lib.Phy2LogMap[blk];
+ if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED)
+ return blk;
+ else if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED)
+ {
+ switch (MS_LibReadExtra(us, blk, 0, &extdat))
+ {
+ case MS_STATUS_SUCCESS :
+ case MS_STATUS_SUCCESS_WITH_ECC:
+ break;
+ case MS_NOCARD_ERROR:
+ return MS_NOCARD_ERROR;
+ case MS_STATUS_INT_ERROR:
+ return MS_LB_ERROR;
+ case MS_ERROR_FLASH_READ:
+ default:
+ MS_LibSetAcquiredErrorBlock(us, blk); // MS_LibErrorPhyBlock(fdoExt, blk);
+ continue;
+ } // End switch
+
+ if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
+ {
+ MS_LibSetAcquiredErrorBlock(us, blk);
+ continue;
+ }
+
+ switch (MS_LibErasePhyBlock(us, blk))
+ {
+ case MS_STATUS_SUCCESS:
+ return blk;
+ case MS_STATUS_ERROR:
+ return MS_LB_ERROR;
+ case MS_ERROR_FLASH_ERASE:
+ default:
+ MS_LibErrorPhyBlock(us, blk);
+ break;
+ }
+ }
+ } // End for
+
+ return MS_LB_ERROR;
+}
+
+//----- MS_LibSearchBlockFromLogical() -------------------------------
+int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk)
+{
+ WORD phyblk;
+
+ if ((phyblk=MS_LibConv2Physical(us, logblk)) >= MS_LB_ERROR)
+ {
+ if (logblk >= us->MS_Lib.NumberOfLogBlock)
+ return MS_LB_ERROR;
+
+ phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT;
+ phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+ phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1;
+ }
+
+ return MS_LibSearchBlockFromPhysical(us, phyblk);
+}
+
+
diff --git a/drivers/staging/keucr/ms.h b/drivers/staging/keucr/ms.h
new file mode 100644
index 000000000000..4509db79298a
--- /dev/null
+++ b/drivers/staging/keucr/ms.h
@@ -0,0 +1,381 @@
+#ifndef MS_INCD
+#define MS_INCD
+
+#include <linux/blkdev.h>
+#include "common.h"
+
+// MemoryStick Register
+// Status Register 0
+#define MS_REG_ST0_MB 0x80 // media busy
+#define MS_REG_ST0_FB0 0x40 // flush busy 0
+#define MS_REG_ST0_BE 0x20 // buffer empty
+#define MS_REG_ST0_BF 0x10 // buffer full
+#define MS_REG_ST0_SL 0x02 // sleep
+#define MS_REG_ST0_WP 0x01 // write protected
+#define MS_REG_ST0_WP_ON MS_REG_ST0_WP
+#define MS_REG_ST0_WP_OFF 0x00
+
+// Status Register 1
+#define MS_REG_ST1_MB 0x80 // media busy
+#define MS_REG_ST1_FB1 0x40 // flush busy 1
+#define MS_REG_ST1_DTER 0x20 // error on data(corrected)
+#define MS_REG_ST1_UCDT 0x10 // unable to correct data
+#define MS_REG_ST1_EXER 0x08 // error on extra(corrected)
+#define MS_REG_ST1_UCEX 0x04 // unable to correct extra
+#define MS_REG_ST1_FGER 0x02 // error on overwrite flag(corrected)
+#define MS_REG_ST1_UCFG 0x01 // unable to correct overwrite flag
+#define MS_REG_ST1_DEFAULT (MS_REG_ST1_MB | MS_REG_ST1_FB1 | \
+ MS_REG_ST1_DTER | MS_REG_ST1_UCDT | \
+ MS_REG_ST1_EXER | MS_REG_ST1_UCEX | \
+ MS_REG_ST1_FGER | MS_REG_ST1_UCFG)
+
+// System Parameter
+#define MS_REG_SYSPAR_BAMD 0x80 // block address mode
+#define MS_REG_SYSPAR_BAND_LINEAR MS_REG_SYSPAR_BAMD // linear mode
+#define MS_REG_SYSPAR_BAND_CHIP 0x00 // chip mode
+#define MS_REG_SYSPAR_ATEN 0x40 // attribute ROM enable
+#define MS_REG_SYSPAR_ATEN_ENABLE MS_REG_SYSPAR_ATEN // enable
+#define MS_REG_SYSPAR_ATEN_DISABLE 0x00 // disable
+#define MS_REG_SYSPAR_RESERVED 0x2f
+
+// Command Parameter
+#define MS_REG_CMDPAR_CP2 0x80
+#define MS_REG_CMDPAR_CP1 0x40
+#define MS_REG_CMDPAR_CP0 0x20
+#define MS_REG_CMDPAR_BLOCK_ACCESS 0
+#define MS_REG_CMDPAR_PAGE_ACCESS MS_REG_CMDPAR_CP0
+#define MS_REG_CMDPAR_EXTRA_DATA MS_REG_CMDPAR_CP1
+#define MS_REG_CMDPAR_OVERWRITE MS_REG_CMDPAR_CP2
+#define MS_REG_CMDPAR_RESERVED 0x1f
+
+// Overwrite Area
+#define MS_REG_OVR_BKST 0x80 // block status
+#define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST // OK
+#define MS_REG_OVR_BKST_NG 0x00 // NG
+#define MS_REG_OVR_PGST0 0x40 // page status
+#define MS_REG_OVR_PGST1 0x20
+#define MS_REG_OVR_PGST_MASK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1)
+#define MS_REG_OVR_PGST_OK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) // OK
+#define MS_REG_OVR_PGST_NG MS_REG_OVR_PGST1 // NG
+#define MS_REG_OVR_PGST_DATA_ERROR 0x00 // data error
+#define MS_REG_OVR_UDST 0x10 // update status
+#define MS_REG_OVR_UDST_UPDATING 0x00 // updating
+#define MS_REG_OVR_UDST_NO_UPDATE MS_REG_OVR_UDST
+#define MS_REG_OVR_RESERVED 0x08
+#define MS_REG_OVR_DEFAULT (MS_REG_OVR_BKST_OK | \
+ MS_REG_OVR_PGST_OK | \
+ MS_REG_OVR_UDST_NO_UPDATE | \
+ MS_REG_OVR_RESERVED)
+// Management Flag
+#define MS_REG_MNG_SCMS0 0x20 // serial copy management system
+#define MS_REG_MNG_SCMS1 0x10
+#define MS_REG_MNG_SCMS_MASK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
+#define MS_REG_MNG_SCMS_COPY_OK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
+#define MS_REG_MNG_SCMS_ONE_COPY MS_REG_MNG_SCMS1
+#define MS_REG_MNG_SCMS_NO_COPY 0x00
+#define MS_REG_MNG_ATFLG 0x08 // address transfer table flag
+#define MS_REG_MNG_ATFLG_OTHER MS_REG_MNG_ATFLG // other
+#define MS_REG_MNG_ATFLG_ATTBL 0x00 // address transfer table
+#define MS_REG_MNG_SYSFLG 0x04 // system flag
+#define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG // user block
+#define MS_REG_MNG_SYSFLG_BOOT 0x00 // system block
+#define MS_REG_MNG_RESERVED 0xc3
+#define MS_REG_MNG_DEFAULT (MS_REG_MNG_SCMS_COPY_OK | \
+ MS_REG_MNG_ATFLG_OTHER | \
+ MS_REG_MNG_SYSFLG_USER | \
+ MS_REG_MNG_RESERVED)
+
+// Error codes
+#define MS_STATUS_SUCCESS 0x0000
+#define MS_ERROR_OUT_OF_SPACE 0x0103
+#define MS_STATUS_WRITE_PROTECT 0x0106
+#define MS_ERROR_READ_DATA 0x8002
+#define MS_ERROR_FLASH_READ 0x8003
+#define MS_ERROR_FLASH_WRITE 0x8004
+#define MS_ERROR_FLASH_ERASE 0x8005
+#define MS_ERROR_FLASH_COPY 0x8006
+
+#define MS_STATUS_ERROR 0xfffe
+#define MS_FIFO_ERROR 0xfffd
+#define MS_UNDEFINED_ERROR 0xfffc
+#define MS_KETIMEOUT_ERROR 0xfffb
+#define MS_STATUS_INT_ERROR 0xfffa
+#define MS_NO_MEMORY_ERROR 0xfff9
+#define MS_NOCARD_ERROR 0xfff8
+#define MS_LB_NOT_USED 0xffff
+#define MS_LB_ERROR 0xfff0
+#define MS_LB_BOOT_BLOCK 0xfff1
+#define MS_LB_INITIAL_ERROR 0xfff2
+#define MS_STATUS_SUCCESS_WITH_ECC 0xfff3
+#define MS_LB_ACQUIRED_ERROR 0xfff4
+#define MS_LB_NOT_USED_ERASED 0xfff5
+
+#define MS_LibConv2Physical(pdx, LogBlock) (((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock])
+#define MS_LibConv2Logical(pdx, PhyBlock) (((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock]) //¬dphy->log table
+
+#define MS_LIB_CTRL_RDONLY 0
+#define MS_LIB_CTRL_WRPROTECT 1
+#define MS_LibCtrlCheck(pdx, Flag) ((pdx)->MS_Lib.flags & (1 << (Flag)))
+
+#define MS_LibCtrlSet(pdx, Flag) (pdx)->MS_Lib.flags |= (1 << (Flag))
+#define MS_LibCtrlReset(pdx, Flag) (pdx)->MS_Lib.flags &= ~(1 << (Flag))
+#define MS_LibIsWritable(pdx) ((MS_LibCtrlCheck((pdx), MS_LIB_CTRL_RDONLY) == 0) && (MS_LibCtrlCheck(pdx, MS_LIB_CTRL_WRPROTECT) == 0))
+
+#define MS_MAX_PAGES_PER_BLOCK 32
+#define MS_LIB_BITS_PER_BYTE 8
+
+#define MS_LibPageMapIdx(n) ((n) / MS_LIB_BITS_PER_BYTE)
+#define MS_LibPageMapBit(n) (1 << ((n) % MS_LIB_BITS_PER_BYTE))
+#define MS_LibCheckPageMapBit(pdx, n) ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] & MS_LibPageMapBit(n))
+#define MS_LibSetPageMapBit(pdx, n) ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] |= MS_LibPageMapBit(n))
+#define MS_LibResetPageMapBit(pdx, n) ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] &= ~MS_LibPageMapBit(n))
+#define MS_LibClearPageMap(pdx) memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap))
+
+
+#define MemStickLogAddr(logadr1, logadr0) ((((WORD)(logadr1)) << 8) | (logadr0))
+
+#define MS_BYTES_PER_PAGE 512
+
+#define MS_MAX_INITIAL_ERROR_BLOCKS 10
+#define MS_NUMBER_OF_PAGES_FOR_BOOT_BLOCK 3
+#define MS_NUMBER_OF_PAGES_FOR_LPCTBL 2
+
+#define MS_NUMBER_OF_BOOT_BLOCK 2
+#define MS_NUMBER_OF_SYSTEM_BLOCK 4
+#define MS_LOGICAL_BLOCKS_PER_SEGMENT 496
+#define MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT 494
+#define MS_PHYSICAL_BLOCKS_PER_SEGMENT 0x200 // 512
+#define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK 0x1ff
+
+#define MS_SECTOR_SIZE 512
+#define MBR_SIGNATURE 0xAA55
+#define PBR_SIGNATURE 0xAA55
+
+#define PARTITION_FAT_12 1
+#define PARTITION_FAT_16 2
+
+#define MS_BOOT_BLOCK_ID 0x0001
+#define MS_BOOT_BLOCK_FORMAT_VERSION 0x0100
+#define MS_BOOT_BLOCK_DATA_ENTRIES 2
+
+#define MS_SYSINF_MSCLASS_TYPE_1 1
+#define MS_SYSINF_CARDTYPE_RDONLY 1
+#define MS_SYSINF_CARDTYPE_RDWR 2
+#define MS_SYSINF_CARDTYPE_HYBRID 3
+#define MS_SYSINF_SECURITY 0x01
+#define MS_SYSINF_SECURITY_NO_SUPPORT MS_SYSINF_SECURITY
+#define MS_SYSINF_SECURITY_SUPPORT 0
+#define MS_SYSINF_FORMAT_MAT 0 // ?
+#define MS_SYSINF_FORMAT_FAT 1
+#define MS_SYSINF_USAGE_GENERAL 0
+#define MS_SYSINF_PAGE_SIZE MS_BYTES_PER_PAGE // fixed
+#define MS_SYSINF_RESERVED1 1
+#define MS_SYSINF_RESERVED2 1
+
+#define MS_SYSENT_TYPE_INVALID_BLOCK 0x01
+#define MS_SYSENT_TYPE_CIS_IDI 0x0a // CIS/IDI
+
+#define SIZE_OF_KIRO 1024
+
+// BOOT BLOCK
+#define MS_NUMBER_OF_SYSTEM_ENTRY 4
+
+//----- MemStickRegisters --------------------------------------------
+// Status registers (16 bytes)
+typedef struct {
+ BYTE Reserved0; // 00
+ BYTE INTRegister; // 01
+ BYTE StatusRegister0; // 02
+ BYTE StatusRegister1; // 03
+ BYTE Reserved1[12]; // 04-0F
+} MemStickStatusRegisters;
+
+// Parameter registers (6 bytes)
+typedef struct {
+ BYTE SystemParameter; // 10
+ BYTE BlockAddress2; // 11
+ BYTE BlockAddress1; // 12
+ BYTE BlockAddress0; // 13
+ BYTE CMDParameter; // 14
+ BYTE PageAddress; // 15
+} MemStickParameterRegisters;
+
+// Extra registers (9 bytes)
+typedef struct {
+ BYTE OverwriteFlag; // 16
+ BYTE ManagementFlag; // 17
+ BYTE LogicalAddress1; // 18
+ BYTE LogicalAddress0; // 19
+ BYTE ReservedArea[5]; // 1A-1E
+} MemStickExtraDataRegisters;
+
+// All registers in Memory Stick (32 bytes, includes 1 byte padding)
+typedef struct {
+ MemStickStatusRegisters status;
+ MemStickParameterRegisters param;
+ MemStickExtraDataRegisters extra;
+ BYTE padding;
+} MemStickRegisters, *PMemStickRegisters;
+
+//----- MemStickBootBlockPage0 ---------------------------------------
+typedef struct {
+ WORD wBlockID;
+ WORD wFormatVersion;
+ BYTE bReserved1[184];
+ BYTE bNumberOfDataEntry;
+ BYTE bReserved2[179];
+} MemStickBootBlockHeader;
+
+typedef struct {
+ DWORD dwStart;
+ DWORD dwSize;
+ BYTE bType;
+ BYTE bReserved[3];
+} MemStickBootBlockSysEntRec;
+
+typedef struct {
+ MemStickBootBlockSysEntRec entry[MS_NUMBER_OF_SYSTEM_ENTRY];
+} MemStickBootBlockSysEnt;
+
+typedef struct {
+ BYTE bMsClass; // must be 1
+ BYTE bCardType; // see below
+ WORD wBlockSize; // n KB
+ WORD wBlockNumber; // number of physical block
+ WORD wTotalBlockNumber; // number of logical block
+ WORD wPageSize; // must be 0x200
+ BYTE bExtraSize; // 0x10
+ BYTE bSecuritySupport;
+ BYTE bAssemblyDate[8];
+ BYTE bFactoryArea[4];
+ BYTE bAssemblyMakerCode;
+ BYTE bAssemblyMachineCode[3];
+ WORD wMemoryMakerCode;
+ WORD wMemoryDeviceCode;
+ WORD wMemorySize;
+ BYTE bReserved1;
+ BYTE bReserved2;
+ BYTE bVCC;
+ BYTE bVPP;
+ WORD wControllerChipNumber;
+ WORD wControllerFunction; // New MS
+ BYTE bReserved3[9]; // New MS
+ BYTE bParallelSupport; // New MS
+ WORD wFormatValue; // New MS
+ BYTE bFormatType;
+ BYTE bUsage;
+ BYTE bDeviceType;
+ BYTE bReserved4[22];
+ BYTE bFUValue3;
+ BYTE bFUValue4;
+ BYTE bReserved5[15];
+} MemStickBootBlockSysInf;
+
+typedef struct {
+ MemStickBootBlockHeader header;
+ MemStickBootBlockSysEnt sysent;
+ MemStickBootBlockSysInf sysinf;
+} MemStickBootBlockPage0;
+
+//----- MemStickBootBlockCIS_IDI -------------------------------------
+typedef struct {
+ BYTE bCistplDEVICE[6]; // 0
+ BYTE bCistplDEVICE0C[6]; // 6
+ BYTE bCistplJEDECC[4]; // 12
+ BYTE bCistplMANFID[6]; // 16
+ BYTE bCistplVER1[32]; // 22
+ BYTE bCistplFUNCID[4]; // 54
+ BYTE bCistplFUNCE0[4]; // 58
+ BYTE bCistplFUNCE1[5]; // 62
+ BYTE bCistplCONF[7]; // 67
+ BYTE bCistplCFTBLENT0[10]; // 74
+ BYTE bCistplCFTBLENT1[8]; // 84
+ BYTE bCistplCFTBLENT2[12]; // 92
+ BYTE bCistplCFTBLENT3[8]; // 104
+ BYTE bCistplCFTBLENT4[17]; // 112
+ BYTE bCistplCFTBLENT5[8]; // 129
+ BYTE bCistplCFTBLENT6[17]; // 137
+ BYTE bCistplCFTBLENT7[8]; // 154
+ BYTE bCistplNOLINK[3]; // 162
+} MemStickBootBlockCIS;
+
+typedef struct {
+#define MS_IDI_GENERAL_CONF 0x848A
+ WORD wIDIgeneralConfiguration; // 0
+ WORD wIDInumberOfCylinder; // 1
+ WORD wIDIreserved0; // 2
+ WORD wIDInumberOfHead; // 3
+ WORD wIDIbytesPerTrack; // 4
+ WORD wIDIbytesPerSector; // 5
+ WORD wIDIsectorsPerTrack; // 6
+ WORD wIDItotalSectors[2]; // 7-8 high,low
+ WORD wIDIreserved1[11]; // 9-19
+ WORD wIDIbufferType; // 20
+ WORD wIDIbufferSize; // 21
+ WORD wIDIlongCmdECC; // 22
+ WORD wIDIfirmVersion[4]; // 23-26
+ WORD wIDImodelName[20]; // 27-46
+ WORD wIDIreserved2; // 47
+ WORD wIDIlongWordSupported; // 48
+ WORD wIDIdmaSupported; // 49
+ WORD wIDIreserved3; // 50
+ WORD wIDIpioTiming; // 51
+ WORD wIDIdmaTiming; // 52
+ WORD wIDItransferParameter; // 53
+ WORD wIDIformattedCylinder; // 54
+ WORD wIDIformattedHead; // 55
+ WORD wIDIformattedSectorsPerTrack; // 56
+ WORD wIDIformattedTotalSectors[2]; // 57-58
+ WORD wIDImultiSector; // 59
+ WORD wIDIlbaSectors[2]; // 60-61
+ WORD wIDIsingleWordDMA; // 62
+ WORD wIDImultiWordDMA; // 63
+ WORD wIDIreserved4[192]; // 64-255
+} MemStickBootBlockIDI;
+
+typedef struct {
+ union {
+ MemStickBootBlockCIS cis;
+ BYTE dmy[256];
+ } cis;
+
+ union {
+ MemStickBootBlockIDI idi;
+ BYTE dmy[256];
+ } idi;
+
+} MemStickBootBlockCIS_IDI;
+
+//----- MS_LibControl ------------------------------------------------
+typedef struct {
+ BYTE reserved;
+ BYTE intr;
+ BYTE status0;
+ BYTE status1;
+ BYTE ovrflg;
+ BYTE mngflg;
+ WORD logadr;
+} MS_LibTypeExtdat;
+
+typedef struct {
+ DWORD flags;
+ DWORD BytesPerSector;
+ DWORD NumberOfCylinder;
+ DWORD SectorsPerCylinder;
+ WORD cardType; // R/W, RO, Hybrid
+ WORD blockSize;
+ WORD PagesPerBlock;
+ WORD NumberOfPhyBlock;
+ WORD NumberOfLogBlock;
+ WORD NumberOfSegment;
+ WORD *Phy2LogMap; // phy2log table
+ WORD *Log2PhyMap; // log2phy table
+ WORD wrtblk;
+ BYTE pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) /
+ MS_LIB_BITS_PER_BYTE];
+ BYTE *blkpag;
+ MS_LibTypeExtdat *blkext;
+ BYTE copybuf[512];
+} MS_LibControl;
+
+#endif
diff --git a/drivers/staging/keucr/msscsi.c b/drivers/staging/keucr/msscsi.c
new file mode 100644
index 000000000000..b908a2383966
--- /dev/null
+++ b/drivers/staging/keucr/msscsi.c
@@ -0,0 +1,320 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+
+int MS_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Inquiry (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Mode_Sense (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Start_Stop (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Read_Capacity (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Read (struct us_data *us, struct scsi_cmnd *srb);
+int MS_SCSI_Write (struct us_data *us, struct scsi_cmnd *srb);
+
+//----- MS_SCSIIrp() --------------------------------------------------
+int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
+{
+ int result;
+
+ us->SrbStatus = SS_SUCCESS;
+ switch (srb->cmnd[0])
+ {
+ case TEST_UNIT_READY : result = MS_SCSI_Test_Unit_Ready (us, srb); break; //0x00
+ case INQUIRY : result = MS_SCSI_Inquiry (us, srb); break; //0x12
+ case MODE_SENSE : result = MS_SCSI_Mode_Sense (us, srb); break; //0x1A
+ case READ_CAPACITY : result = MS_SCSI_Read_Capacity (us, srb); break; //0x25
+ case READ_10 : result = MS_SCSI_Read (us, srb); break; //0x28
+ case WRITE_10 : result = MS_SCSI_Write (us, srb); break; //0x2A
+
+ default:
+ us->SrbStatus = SS_ILLEGAL_REQUEST;
+ result = USB_STOR_TRANSPORT_FAILED;
+ break;
+ }
+ return result;
+}
+
+//----- MS_SCSI_Test_Unit_Ready() --------------------------------------------------
+int MS_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("MS_SCSI_Test_Unit_Ready\n");
+ if (us->MS_Status.Insert && us->MS_Status.Ready)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ {
+ ENE_MSInit(us);
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_SCSI_Inquiry() --------------------------------------------------
+int MS_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("MS_SCSI_Inquiry\n");
+ BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
+
+ usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+
+//----- MS_SCSI_Mode_Sense() --------------------------------------------------
+int MS_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
+{
+ BYTE mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+ BYTE mediaWP[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+
+ if (us->MS_Status.WtP)
+ usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
+ else
+ usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF);
+
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_SCSI_Read_Capacity() --------------------------------------------------
+int MS_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
+{
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
+ DWORD bl_num;
+ WORD bl_len;
+ BYTE buf[8];
+
+ printk("MS_SCSI_Read_Capacity\n");
+
+ bl_len = 0x200;
+ if ( us->MS_Status.IsMSPro )
+ bl_num = us->MSP_TotalBlock - 1;
+ else
+ bl_num = us->MS_Lib.NumberOfLogBlock * us->MS_Lib.blockSize * 2 - 1;
+
+ us->bl_num = bl_num;
+ printk("bl_len = %x\n", bl_len);
+ printk("bl_num = %x\n", bl_num);
+
+ //srb->request_bufflen = 8;
+ buf[0] = (bl_num>>24) & 0xff;
+ buf[1] = (bl_num>>16) & 0xff;
+ buf[2] = (bl_num>> 8) & 0xff;
+ buf[3] = (bl_num>> 0) & 0xff;
+ buf[4] = (bl_len>>24) & 0xff;
+ buf[5] = (bl_len>>16) & 0xff;
+ buf[6] = (bl_len>> 8) & 0xff;
+ buf[7] = (bl_len>> 0) & 0xff;
+
+ usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);
+ //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- MS_SCSI_Read() --------------------------------------------------
+int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result=0;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD blenByte = blen * 0x200;
+
+ //printk("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg);
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ if (us->MS_Status.IsMSPro)
+ {
+ result = ENE_LoadBinCode(us, MSP_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load MSP RW pattern Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = blenByte;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x02;
+ bcb->CDB[5] = (BYTE)(bn);
+ bcb->CDB[4] = (BYTE)(bn>>8);
+ bcb->CDB[3] = (BYTE)(bn>>16);
+ bcb->CDB[2] = (BYTE)(bn>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, scsi_sglist(srb), 1);
+ }
+ else
+ {
+ void *buf;
+ int offset=0;
+ WORD phyblk, logblk;
+ BYTE PageNum;
+ WORD len;
+ DWORD blkno;
+
+ buf = kmalloc(blenByte, GFP_KERNEL);
+
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load MS RW pattern Fail !!\n");
+ result = USB_STOR_TRANSPORT_ERROR;
+ goto exit;
+ }
+
+ logblk = (WORD)(bn / us->MS_Lib.PagesPerBlock);
+ PageNum = (BYTE)(bn % us->MS_Lib.PagesPerBlock);
+
+ while(1)
+ {
+ if (blen > (us->MS_Lib.PagesPerBlock-PageNum) )
+ len = us->MS_Lib.PagesPerBlock-PageNum;
+ else
+ len = blen;
+
+ phyblk = MS_LibConv2Physical(us, logblk);
+ blkno = phyblk * 0x20 + PageNum;
+
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200 * len;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x02;
+ bcb->CDB[5] = (BYTE)(blkno);
+ bcb->CDB[4] = (BYTE)(blkno>>8);
+ bcb->CDB[3] = (BYTE)(blkno>>16);
+ bcb->CDB[2] = (BYTE)(blkno>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf+offset, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("MS_SCSI_Read --- result = %x\n", result);
+ result = USB_STOR_TRANSPORT_ERROR;
+ goto exit;
+ }
+
+ blen -= len;
+ if (blen<=0)
+ break;
+ logblk++;
+ PageNum = 0;
+ offset += MS_BYTES_PER_PAGE*len;
+ }
+ usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF);
+exit:
+ kfree(buf);
+ }
+ return result;
+}
+
+//----- MS_SCSI_Write() --------------------------------------------------
+int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result=0;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD blenByte = blen * 0x200;
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ if (us->MS_Status.IsMSPro)
+ {
+ result = ENE_LoadBinCode(us, MSP_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load MSP RW pattern Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = blenByte;
+ bcb->Flags = 0x00;
+ bcb->CDB[0] = 0xF0;
+ bcb->CDB[1] = 0x04;
+ bcb->CDB[5] = (BYTE)(bn);
+ bcb->CDB[4] = (BYTE)(bn>>8);
+ bcb->CDB[3] = (BYTE)(bn>>16);
+ bcb->CDB[2] = (BYTE)(bn>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
+ }
+ else
+ {
+ void *buf;
+ int offset=0;
+ WORD PhyBlockAddr;
+ BYTE PageNum;
+ DWORD result;
+ WORD len, oldphy, newphy;
+
+ buf = kmalloc(blenByte, GFP_KERNEL);
+ usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF);
+
+ result = ENE_LoadBinCode(us, MS_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load MS RW pattern Fail !!\n");
+ result = USB_STOR_TRANSPORT_ERROR;
+ goto exit;
+ }
+
+ PhyBlockAddr = (WORD)(bn / us->MS_Lib.PagesPerBlock);
+ PageNum = (BYTE)(bn % us->MS_Lib.PagesPerBlock);
+
+ while(1)
+ {
+ if (blen > (us->MS_Lib.PagesPerBlock-PageNum) )
+ len = us->MS_Lib.PagesPerBlock-PageNum;
+ else
+ len = blen;
+
+ oldphy = MS_LibConv2Physical(us, PhyBlockAddr);
+ newphy = MS_LibSearchBlockFromLogical(us, PhyBlockAddr);
+
+ result = MS_ReaderCopyBlock(us, oldphy, newphy, PhyBlockAddr, PageNum, buf+offset, len);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("MS_SCSI_Write --- result = %x\n", result);
+ result = USB_STOR_TRANSPORT_ERROR;
+ goto exit;
+ }
+
+ us->MS_Lib.Phy2LogMap[oldphy] = MS_LB_NOT_USED_ERASED;
+ MS_LibForceSetLogicalPair(us, PhyBlockAddr, newphy);
+
+ blen -= len;
+ if (blen<=0)
+ break;
+ PhyBlockAddr++;
+ PageNum = 0;
+ offset += MS_BYTES_PER_PAGE*len;
+ }
+exit:
+ kfree(buf);
+ }
+ return result;
+}
+
diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c
new file mode 100644
index 000000000000..d830348ed011
--- /dev/null
+++ b/drivers/staging/keucr/scsiglue.c
@@ -0,0 +1,448 @@
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+
+/* Host functions */
+//----- host_info() ---------------------
+static const char* host_info(struct Scsi_Host *host)
+{
+ //printk("scsiglue --- host_info\n");
+ return "SCSI emulation for USB Mass Storage devices";
+}
+
+//----- slave_alloc() ---------------------
+static int slave_alloc(struct scsi_device *sdev)
+{
+ struct us_data *us = host_to_us(sdev->host);
+
+ //printk("scsiglue --- slave_alloc\n");
+ sdev->inquiry_len = 36;
+
+ blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
+
+ if (us->subclass == US_SC_UFI)
+ sdev->sdev_target->pdt_1f_for_no_lun = 1;
+
+ return 0;
+}
+
+//----- slave_configure() ---------------------
+static int slave_configure(struct scsi_device *sdev)
+{
+ struct us_data *us = host_to_us(sdev->host);
+
+ //printk("scsiglue --- slave_configure\n");
+ if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN))
+ {
+ unsigned int max_sectors = 64;
+
+ if (us->fflags & US_FL_MAX_SECTORS_MIN)
+ max_sectors = PAGE_CACHE_SIZE >> 9;
+ if (queue_max_sectors(sdev->request_queue) > max_sectors)
+ blk_queue_max_hw_sectors(sdev->request_queue,
+ max_sectors);
+ }
+
+ if (sdev->type == TYPE_DISK)
+ {
+ if (us->subclass != US_SC_SCSI && us->subclass != US_SC_CYP_ATACB)
+ sdev->use_10_for_ms = 1;
+ sdev->use_192_bytes_for_3f = 1;
+ if (us->fflags & US_FL_NO_WP_DETECT)
+ sdev->skip_ms_page_3f = 1;
+ sdev->skip_ms_page_8 = 1;
+ if (us->fflags & US_FL_FIX_CAPACITY)
+ sdev->fix_capacity = 1;
+ if (us->fflags & US_FL_CAPACITY_HEURISTICS)
+ sdev->guess_capacity = 1;
+ if (sdev->scsi_level > SCSI_2)
+ sdev->sdev_target->scsi_level = sdev->scsi_level = SCSI_2;
+ sdev->retry_hwerror = 1;
+ sdev->allow_restart = 1;
+ sdev->last_sector_bug = 1;
+ }
+ else
+ {
+ sdev->use_10_for_ms = 1;
+ }
+
+ if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) && sdev->scsi_level == SCSI_UNKNOWN)
+ us->max_lun = 0;
+
+ if (us->fflags & US_FL_NOT_LOCKABLE)
+ sdev->lockable = 0;
+
+ return 0;
+}
+
+/* This is always called with scsi_lock(host) held */
+//----- queuecommand() ---------------------
+static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
+{
+ struct us_data *us = host_to_us(srb->device->host);
+
+ //printk("scsiglue --- queuecommand\n");
+
+ /* check for state-transition errors */
+ if (us->srb != NULL)
+ {
+ printk("Error in %s: us->srb = %p\n", __FUNCTION__, us->srb);
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ /* fail the command if we are disconnecting */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
+ {
+ printk("Fail command during disconnect\n");
+ srb->result = DID_NO_CONNECT << 16;
+ done(srb);
+ return 0;
+ }
+
+ /* enqueue the command and wake up the control thread */
+ srb->scsi_done = done;
+ us->srb = srb;
+ complete(&us->cmnd_ready);
+
+ return 0;
+}
+
+/***********************************************************************
+ * Error handling functions
+ ***********************************************************************/
+
+/* Command timeout and abort */
+//----- command_abort() ---------------------
+static int command_abort(struct scsi_cmnd *srb)
+{
+ struct us_data *us = host_to_us(srb->device->host);
+
+ //printk("scsiglue --- command_abort\n");
+
+ scsi_lock(us_to_host(us));
+ if (us->srb != srb)
+ {
+ scsi_unlock(us_to_host(us));
+ printk ("-- nothing to abort\n");
+ return FAILED;
+ }
+
+ set_bit(US_FLIDX_TIMED_OUT, &us->dflags);
+ if (!test_bit(US_FLIDX_RESETTING, &us->dflags))
+ {
+ set_bit(US_FLIDX_ABORTING, &us->dflags);
+ usb_stor_stop_transport(us);
+ }
+ scsi_unlock(us_to_host(us));
+
+ /* Wait for the aborted command to finish */
+ wait_for_completion(&us->notify);
+ return SUCCESS;
+}
+
+/* This invokes the transport reset mechanism to reset the state of the device */
+//----- device_reset() ---------------------
+static int device_reset(struct scsi_cmnd *srb)
+{
+ struct us_data *us = host_to_us(srb->device->host);
+ int result;
+
+ //printk("scsiglue --- device_reset\n");
+
+ /* lock the device pointers and do the reset */
+ mutex_lock(&(us->dev_mutex));
+ result = us->transport_reset(us);
+ mutex_unlock(&us->dev_mutex);
+
+ return result < 0 ? FAILED : SUCCESS;
+}
+
+//----- bus_reset() ---------------------
+static int bus_reset(struct scsi_cmnd *srb)
+{
+ struct us_data *us = host_to_us(srb->device->host);
+ int result;
+
+ //printk("scsiglue --- bus_reset\n");
+ result = usb_stor_port_reset(us);
+ return result < 0 ? FAILED : SUCCESS;
+}
+
+//----- usb_stor_report_device_reset() ---------------------
+void usb_stor_report_device_reset(struct us_data *us)
+{
+ int i;
+ struct Scsi_Host *host = us_to_host(us);
+
+ //printk("scsiglue --- usb_stor_report_device_reset\n");
+ scsi_report_device_reset(host, 0, 0);
+ if (us->fflags & US_FL_SCM_MULT_TARG)
+ {
+ for (i = 1; i < host->max_id; ++i)
+ scsi_report_device_reset(host, 0, i);
+ }
+}
+
+//----- usb_stor_report_bus_reset() ---------------------
+void usb_stor_report_bus_reset(struct us_data *us)
+{
+ struct Scsi_Host *host = us_to_host(us);
+
+ //printk("scsiglue --- usb_stor_report_bus_reset\n");
+ scsi_lock(host);
+ scsi_report_bus_reset(host, 0);
+ scsi_unlock(host);
+}
+
+/***********************************************************************
+ * /proc/scsi/ functions
+ ***********************************************************************/
+
+/* we use this macro to help us write into the buffer */
+#undef SPRINTF
+#define SPRINTF(args...) \
+ do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
+
+//----- proc_info() ---------------------
+static int proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
+{
+ struct us_data *us = host_to_us(host);
+ char *pos = buffer;
+ const char *string;
+
+ //printk("scsiglue --- proc_info\n");
+ if (inout)
+ return length;
+
+ /* print the controller name */
+ SPRINTF(" Host scsi%d: usb-storage\n", host->host_no);
+
+ /* print product, vendor, and serial number strings */
+ if (us->pusb_dev->manufacturer)
+ string = us->pusb_dev->manufacturer;
+ else if (us->unusual_dev->vendorName)
+ string = us->unusual_dev->vendorName;
+ else
+ string = "Unknown";
+ SPRINTF(" Vendor: %s\n", string);
+ if (us->pusb_dev->product)
+ string = us->pusb_dev->product;
+ else if (us->unusual_dev->productName)
+ string = us->unusual_dev->productName;
+ else
+ string = "Unknown";
+ SPRINTF(" Product: %s\n", string);
+ if (us->pusb_dev->serial)
+ string = us->pusb_dev->serial;
+ else
+ string = "None";
+ SPRINTF("Serial Number: %s\n", string);
+
+ /* show the protocol and transport */
+ SPRINTF(" Protocol: %s\n", us->protocol_name);
+ SPRINTF(" Transport: %s\n", us->transport_name);
+
+ /* show the device flags */
+ if (pos < buffer + length)
+ {
+ pos += sprintf(pos, " Quirks:");
+
+#define US_FLAG(name, value) \
+ if (us->fflags & value) pos += sprintf(pos, " " #name);
+US_DO_ALL_FLAGS
+#undef US_FLAG
+
+ *(pos++) = '\n';
+ }
+
+ /* Calculate start of next buffer, and return value. */
+ *start = buffer + offset;
+
+ if ((pos - buffer) < offset)
+ return (0);
+ else if ((pos - buffer - offset) < length)
+ return (pos - buffer - offset);
+ else
+ return (length);
+}
+
+/***********************************************************************
+ * Sysfs interface
+ ***********************************************************************/
+
+/* Output routine for the sysfs max_sectors file */
+//----- show_max_sectors() ---------------------
+static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+
+ //printk("scsiglue --- ssize_t show_max_sectors\n");
+ return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue));
+}
+
+/* Input routine for the sysfs max_sectors file */
+//----- store_max_sectors() ---------------------
+static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ unsigned short ms;
+
+ //printk("scsiglue --- ssize_t store_max_sectors\n");
+ if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS)
+ {
+ blk_queue_max_hw_sectors(sdev->request_queue, ms);
+ return strlen(buf);
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors, store_max_sectors);
+static struct device_attribute *sysfs_device_attr_list[] = {&dev_attr_max_sectors, NULL, };
+
+/* this defines our host template, with which we'll allocate hosts */
+
+//----- usb_stor_host_template() ---------------------
+struct scsi_host_template usb_stor_host_template = {
+ /* basic userland interface stuff */
+ .name = "eucr-storage",
+ .proc_name = "eucr-storage",
+ .proc_info = proc_info,
+ .info = host_info,
+
+ /* command interface -- queued only */
+ .queuecommand = queuecommand,
+
+ /* error and abort handlers */
+ .eh_abort_handler = command_abort,
+ .eh_device_reset_handler = device_reset,
+ .eh_bus_reset_handler = bus_reset,
+
+ /* queue commands only, only one command per LUN */
+ .can_queue = 1,
+ .cmd_per_lun = 1,
+
+ /* unknown initiator id */
+ .this_id = -1,
+
+ .slave_alloc = slave_alloc,
+ .slave_configure = slave_configure,
+
+ /* lots of sg segments can be handled */
+ .sg_tablesize = SG_ALL,
+
+ /* limit the total size of a transfer to 120 KB */
+ .max_sectors = 240,
+
+ /* merge commands... this seems to help performance, but
+ * periodically someone should test to see which setting is more
+ * optimal.
+ */
+ .use_clustering = 1,
+
+ /* emulated HBA */
+ .emulated = 1,
+
+ /* we do our own delay after a device or bus reset */
+ .skip_settle_delay = 1,
+
+ /* sysfs device attributes */
+ .sdev_attrs = sysfs_device_attr_list,
+
+ /* module management */
+ .module = THIS_MODULE
+};
+
+/* To Report "Illegal Request: Invalid Field in CDB */
+unsigned char usb_stor_sense_invalidCDB[18] = {
+ [0] = 0x70, /* current error */
+ [2] = ILLEGAL_REQUEST, /* Illegal Request = 0x05 */
+ [7] = 0x0a, /* additional length */
+ [12] = 0x24 /* Invalid Field in CDB */
+};
+
+/***********************************************************************
+ * Scatter-gather transfer buffer access routines
+ ***********************************************************************/
+
+//----- usb_stor_access_xfer_buf() ---------------------
+unsigned int usb_stor_access_xfer_buf(struct us_data *us, unsigned char *buffer,
+ unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
+ unsigned int *offset, enum xfer_buf_dir dir)
+{
+ unsigned int cnt;
+
+ //printk("transport --- usb_stor_access_xfer_buf\n");
+ struct scatterlist *sg = *sgptr;
+
+ if (!sg)
+ sg = scsi_sglist(srb);
+
+ cnt = 0;
+ while (cnt < buflen && sg)
+ {
+ struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT);
+ unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1);
+ unsigned int sglen = sg->length - *offset;
+
+ if (sglen > buflen - cnt)
+ {
+ /* Transfer ends within this s-g entry */
+ sglen = buflen - cnt;
+ *offset += sglen;
+ }
+ else
+ {
+ /* Transfer continues to next s-g entry */
+ *offset = 0;
+ sg = sg_next(sg);
+ }
+
+ while (sglen > 0)
+ {
+ unsigned int plen = min(sglen, (unsigned int)PAGE_SIZE - poff);
+ unsigned char *ptr = kmap(page);
+
+ if (dir == TO_XFER_BUF)
+ memcpy(ptr + poff, buffer + cnt, plen);
+ else
+ memcpy(buffer + cnt, ptr + poff, plen);
+ kunmap(page);
+
+ /* Start at the beginning of the next page */
+ poff = 0;
+ ++page;
+ cnt += plen;
+ sglen -= plen;
+ }
+ }
+ *sgptr = sg;
+
+ /* Return the amount actually transferred */
+ return cnt;
+}
+
+/* Store the contents of buffer into srb's transfer buffer and set the SCSI residue. */
+//----- usb_stor_set_xfer_buf() ---------------------
+void usb_stor_set_xfer_buf(struct us_data *us, unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
+ unsigned int dir)
+{
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
+
+ //printk("transport --- usb_stor_set_xfer_buf\n");
+ // TO_XFER_BUF = 0, FROM_XFER_BUF = 1
+ buflen = min(buflen, scsi_bufflen(srb));
+ buflen = usb_stor_access_xfer_buf(us, buffer, buflen, srb, &sg, &offset, dir);
+ if (buflen < scsi_bufflen(srb))
+ scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
+}
diff --git a/drivers/staging/keucr/scsiglue.h b/drivers/staging/keucr/scsiglue.h
new file mode 100644
index 000000000000..c7e59f0f9cd6
--- /dev/null
+++ b/drivers/staging/keucr/scsiglue.h
@@ -0,0 +1,10 @@
+#ifndef _SCSIGLUE_H_
+#define _SCSIGLUE_H_
+
+extern void usb_stor_report_device_reset(struct us_data *us);
+extern void usb_stor_report_bus_reset(struct us_data *us);
+
+extern unsigned char usb_stor_sense_invalidCDB[18];
+extern struct scsi_host_template usb_stor_host_template;
+
+#endif
diff --git a/drivers/staging/keucr/sdscsi.c b/drivers/staging/keucr/sdscsi.c
new file mode 100644
index 000000000000..6c332f850ebe
--- /dev/null
+++ b/drivers/staging/keucr/sdscsi.c
@@ -0,0 +1,210 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+
+int SD_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Inquiry (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Mode_Sense (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Start_Stop (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Read_Capacity (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Read (struct us_data *us, struct scsi_cmnd *srb);
+int SD_SCSI_Write (struct us_data *us, struct scsi_cmnd *srb);
+
+//----- SD_SCSIIrp() --------------------------------------------------
+int SD_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
+{
+ int result;
+
+ us->SrbStatus = SS_SUCCESS;
+ switch (srb->cmnd[0])
+ {
+ case TEST_UNIT_READY : result = SD_SCSI_Test_Unit_Ready (us, srb); break; //0x00
+ case INQUIRY : result = SD_SCSI_Inquiry (us, srb); break; //0x12
+ case MODE_SENSE : result = SD_SCSI_Mode_Sense (us, srb); break; //0x1A
+// case START_STOP : result = SD_SCSI_Start_Stop (us, srb); break; //0x1B
+ case READ_CAPACITY : result = SD_SCSI_Read_Capacity (us, srb); break; //0x25
+ case READ_10 : result = SD_SCSI_Read (us, srb); break; //0x28
+ case WRITE_10 : result = SD_SCSI_Write (us, srb); break; //0x2A
+
+ default:
+ us->SrbStatus = SS_ILLEGAL_REQUEST;
+ result = USB_STOR_TRANSPORT_FAILED;
+ break;
+ }
+ return result;
+}
+
+//----- SD_SCSI_Test_Unit_Ready() --------------------------------------------------
+int SD_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("SD_SCSI_Test_Unit_Ready\n");
+ if (us->SD_Status.Insert && us->SD_Status.Ready)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ {
+ ENE_SDInit(us);
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SD_SCSI_Inquiry() --------------------------------------------------
+int SD_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("SD_SCSI_Inquiry\n");
+ BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
+
+ usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+
+//----- SD_SCSI_Mode_Sense() --------------------------------------------------
+int SD_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
+{
+ BYTE mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+ BYTE mediaWP[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+
+ if (us->SD_Status.WtP)
+ usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
+ else
+ usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF);
+
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SD_SCSI_Read_Capacity() --------------------------------------------------
+int SD_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
+{
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
+ DWORD bl_num;
+ WORD bl_len;
+ BYTE buf[8];
+
+ printk("SD_SCSI_Read_Capacity\n");
+ if ( us->SD_Status.HiCapacity )
+ {
+ bl_len = 0x200;
+ if (us->SD_Status.IsMMC)
+ bl_num = us->HC_C_SIZE-1;
+ else
+ bl_num = (us->HC_C_SIZE + 1) * 1024 - 1;
+ }
+ else
+ {
+ bl_len = 1<<(us->SD_READ_BL_LEN);
+ bl_num = us->SD_Block_Mult*(us->SD_C_SIZE+1)*(1<<(us->SD_C_SIZE_MULT+2)) - 1;
+ }
+ us->bl_num = bl_num;
+ printk("bl_len = %x\n", bl_len);
+ printk("bl_num = %x\n", bl_num);
+
+ //srb->request_bufflen = 8;
+ buf[0] = (bl_num>>24) & 0xff;
+ buf[1] = (bl_num>>16) & 0xff;
+ buf[2] = (bl_num>> 8) & 0xff;
+ buf[3] = (bl_num>> 0) & 0xff;
+ buf[4] = (bl_len>>24) & 0xff;
+ buf[5] = (bl_len>>16) & 0xff;
+ buf[6] = (bl_len>> 8) & 0xff;
+ buf[7] = (bl_len>> 0) & 0xff;
+
+ usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);
+ //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SD_SCSI_Read() --------------------------------------------------
+int SD_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD bnByte = bn * 0x200;
+ DWORD blenByte = blen * 0x200;
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ result = ENE_LoadBinCode(us, SD_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SD RW pattern Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ if ( us->SD_Status.HiCapacity )
+ bnByte = bn;
+
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = blenByte;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[5] = (BYTE)(bnByte);
+ bcb->CDB[4] = (BYTE)(bnByte>>8);
+ bcb->CDB[3] = (BYTE)(bnByte>>16);
+ bcb->CDB[2] = (BYTE)(bnByte>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, scsi_sglist(srb), 1);
+ return result;
+}
+
+//----- SD_SCSI_Write() --------------------------------------------------
+int SD_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD bnByte = bn * 0x200;
+ DWORD blenByte = blen * 0x200;
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ result = ENE_LoadBinCode(us, SD_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SD RW pattern Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ if ( us->SD_Status.HiCapacity )
+ bnByte = bn;
+
+ // set up the command wrapper
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = blenByte;
+ bcb->Flags = 0x00;
+ bcb->CDB[0] = 0xF0;
+ bcb->CDB[5] = (BYTE)(bnByte);
+ bcb->CDB[4] = (BYTE)(bnByte>>8);
+ bcb->CDB[3] = (BYTE)(bnByte>>16);
+ bcb->CDB[2] = (BYTE)(bnByte>>24);
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
+ return result;
+}
+
+
+
diff --git a/drivers/staging/keucr/smcommon.h b/drivers/staging/keucr/smcommon.h
new file mode 100644
index 000000000000..169460547662
--- /dev/null
+++ b/drivers/staging/keucr/smcommon.h
@@ -0,0 +1,33 @@
+/*----- < SMCommon.h> --------------------------------------------------*/
+#ifndef SMCOMMON_INCD
+#define SMCOMMON_INCD
+
+
+/***************************************************************************
+Define Difinetion
+***************************************************************************/
+#define SUCCESS 0x0000 /* SUCCESS */
+#define ERROR 0xFFFF /* ERROR */
+#define CORRECT 0x0001 /* CORRECTABLE */
+
+/***************************************************************************/
+#define NO_ERROR 0x0000 /* NO ERROR */
+#define ERR_WriteFault 0x0003 /* Peripheral Device Write Fault */
+#define ERR_HwError 0x0004 /* Hardware Error */
+#define ERR_DataStatus 0x0010 /* DataStatus Error */
+#define ERR_EccReadErr 0x0011 /* Unrecovered Read Error */
+#define ERR_CorReadErr 0x0018 /* Recovered Read Data with ECC */
+#define ERR_OutOfLBA 0x0021 /* Illegal Logical Block Address */
+#define ERR_WrtProtect 0x0027 /* Write Protected */
+#define ERR_ChangedMedia 0x0028 /* Medium Changed */
+#define ERR_UnknownMedia 0x0030 /* Incompatible Medium Installed */
+#define ERR_IllegalFmt 0x0031 /* Medium Format Corrupted */
+#define ERR_NoSmartMedia 0x003A /* Medium Not Present */
+
+/***************************************************************************/
+char Bit_D_Count(BYTE);
+char Bit_D_CountWord(WORD);
+void StringCopy(char *, char *, int);
+int StringCmp(char *, char *, int);
+
+#endif
diff --git a/drivers/staging/keucr/smil.h b/drivers/staging/keucr/smil.h
new file mode 100644
index 000000000000..4226813ba588
--- /dev/null
+++ b/drivers/staging/keucr/smil.h
@@ -0,0 +1,290 @@
+/*----- < smil.h> ----------------------------------------------------*/
+#ifndef SMIL_INCD
+#define SMIL_INCD
+
+/***************************************************************************
+Define Definition
+***************************************************************************/
+#define K_BYTE 1024 /* Kilo Byte */
+#define SECTSIZE 512 /* Sector buffer size */
+#define REDTSIZE 16 /* Redundant buffer size */
+
+/***************************************************************************/
+#define DUMMY_DATA 0xFF /* No Assign Sector Read Data */
+
+/***************************************************************************
+Max Zone/Block/Sectors Data Definition
+***************************************************************************/
+#define MAX_ZONENUM 128 /* Max Zone Numbers in a SmartMedia */
+#define MAX_BLOCKNUM 0x0400 /* Max Block Numbers in a Zone */
+#define MAX_SECTNUM 0x20 /* Max Sector Numbers in a Block */
+#define MAX_LOGBLOCK 1000 /* Max Logical Block Numbers in a Zone */
+
+/***************************************************************************/
+#define CIS_SEARCH_SECT 0x08 /* Max CIS Search Sector Number */
+
+/***************************************************************************
+Logical to Physical Block Table Data Definition
+***************************************************************************/
+#define NO_ASSIGN 0xFFFF /* No Assign Logical Block Address */
+
+/***************************************************************************
+'SectCopyMode' Data
+***************************************************************************/
+#define COMPLETED 0 /* Sector Copy Completed */
+#define REQ_ERASE 1 /* Request Read Block Erase */
+#define REQ_FAIL 2 /* Request Read Block Failed */
+
+/***************************************************************************
+Retry Counter Definition
+***************************************************************************/
+#define RDERR_REASSIGN 1 /* Reassign with Read Error */
+#define L2P_ERR_ERASE 1 /* BlockErase for Contradicted L2P Table */
+
+/***************************************************************************
+Hardware ECC Definition
+***************************************************************************/
+#define HW_ECC_SUPPORTED 1 /* Hardware ECC Supported */ /* No difinition for Software ECC */
+
+/***************************************************************************
+SmartMedia Command & Status Definition
+***************************************************************************/
+/* SmartMedia Command */
+#define WRDATA 0x80
+//#define READ 0x00
+#define READ_REDT 0x50
+//#define WRITE 0x10
+#define RDSTATUS 0x70
+
+#define READ1 0x00 //NO
+#define READ2 0x01 //NO
+#define READ3 0x50 //NO
+#define RST_CHIP 0xFF
+#define ERASE1 0x60
+#define ERASE2 0xD0
+#define READ_ID_1 0x90
+#define READ_ID_2 0x91
+#define READ_ID_3 0x9A
+
+/* 712 SmartMedia Command */
+#define SM_CMD_RESET 0x00 // 0xFF
+#define SM_CMD_READ_ID_1 0x10 // 0x90
+#define SM_CMD_READ_ID_2 0x20 // 0x91
+#define SM_CMD_READ_STAT 0x30 // 0x70
+#define SM_CMD_RDMULTPL_STAT 0x40 // 0x71
+#define SM_CMD_READ_1 0x50 // 0x00
+#define SM_CMD_READ_2 0x60 // 0x01
+#define SM_CMD_READ_3 0x70 // 0x50
+#define SM_CMD_PAGPRGM_TRUE 0x80 // {0x80, 0x10}
+#define SM_CMD_PAGPRGM_DUMY 0x90 // {0x80, 0x11}
+#define SM_CMD_PAGPRGM_MBLK 0xA0 // {0x80, 0x15}
+#define SM_CMD_BLKERASE 0xB0 // {0x60, 0xD0}
+#define SM_CMD_BLKERASE_MULTPL 0xC0 // {0x60-0x60, 0xD0}
+
+#define SM_CRADDTCT_DEBNCETIMER_EN 0x02
+#define SM_CMD_START_BIT 0x01
+
+#define SM_WaitCmdDone { while (!SM_CmdDone); }
+#define SM_WaitDmaDone { while (!SM_DmaDone); }
+
+// SmartMedia Status
+#define WR_FAIL 0x01 // 0:Pass, 1:Fail
+#define SUSPENDED 0x20 // 0:Not Suspended, 1:Suspended
+#define READY 0x40 // 0:Busy, 1:Ready
+#define WR_PRTCT 0x80 // 0:Protect, 1:Not Protect
+
+// SmartMedia Busy Time (1bit:0.1ms)
+#define BUSY_PROG 200 // tPROG : 20ms ----- Program Time old : 200
+#define BUSY_ERASE 4000 // tBERASE : 400ms ----- Block Erase Time old : 4000
+//for 712 Test
+//#define BUSY_READ 1 // tR : 100us ----- Data transfer Time old : 1
+//#define BUSY_READ 10 // tR : 100us ----- Data transfer Time old : 1
+#define BUSY_READ 200 // tR : 20ms ----- Data transfer Time old : 1
+//#define BUSY_RESET 60 // tRST : 6ms ----- Device Resetting Time old : 60
+#define BUSY_RESET 600 // tRST : 60ms ----- Device Resetting Time old : 60
+
+// Hardware Timer (1bit:0.1ms)
+#define TIME_PON 3000 // 300ms ------ Power On Wait Time
+#define TIME_CDCHK 200 // 20ms ------ Card Check Interval Timer
+#define TIME_WPCHK 50 // 5ms ------ WP Check Interval Timer
+#define TIME_5VCHK 10 // 1ms ------ 5V Check Interval Timer
+
+/***************************************************************************
+Redundant Data
+***************************************************************************/
+#define REDT_DATA 0x04
+#define REDT_BLOCK 0x05
+#define REDT_ADDR1H 0x06
+#define REDT_ADDR1L 0x07
+#define REDT_ADDR2H 0x0B
+#define REDT_ADDR2L 0x0C
+#define REDT_ECC10 0x0D
+#define REDT_ECC11 0x0E
+#define REDT_ECC12 0x0F
+#define REDT_ECC20 0x08
+#define REDT_ECC21 0x09
+#define REDT_ECC22 0x0A
+
+/***************************************************************************
+SmartMedia Model & Attribute
+***************************************************************************/
+/* SmartMedia Attribute */
+#define NOWP 0x00 // 0... .... No Write Protect
+#define WP 0x80 // 1... .... Write Protected
+#define MASK 0x00 // .00. .... NAND MASK ROM Model
+#define FLASH 0x20 // .01. .... NAND Flash ROM Model
+#define AD3CYC 0x00 // ...0 .... Address 3-cycle
+#define AD4CYC 0x10 // ...1 .... Address 4-cycle
+#define BS16 0x00 // .... 00.. 16page/block
+#define BS32 0x04 // .... 01.. 32page/block
+#define PS256 0x00 // .... ..00 256byte/page
+#define PS512 0x01 // .... ..01 512byte/page
+#define MWP 0x80 // WriteProtect mask
+#define MFLASH 0x60 // Flash Rom mask
+#define MADC 0x10 // Address Cycle
+#define MBS 0x0C // BlockSize mask
+#define MPS 0x03 // PageSize mask
+
+/* SmartMedia Model */
+#define NOSSFDC 0x00 // NO SmartMedia
+#define SSFDC1MB 0x01 // 1MB SmartMedia
+#define SSFDC2MB 0x02 // 2MB SmartMedia
+#define SSFDC4MB 0x03 // 4MB SmartMedia
+#define SSFDC8MB 0x04 // 8MB SmartMedia
+#define SSFDC16MB 0x05 // 16MB SmartMedia
+#define SSFDC32MB 0x06 // 32MB SmartMedia
+#define SSFDC64MB 0x07 // 64MB SmartMedia
+#define SSFDC128MB 0x08 //128MB SmartMedia
+#define SSFDC256MB 0x09
+#define SSFDC512MB 0x0A
+#define SSFDC1GB 0x0B
+#define SSFDC2GB 0x0C
+
+/***************************************************************************
+Struct Definition
+***************************************************************************/
+struct SSFDCTYPE
+{
+ BYTE Model;
+ BYTE Attribute;
+ BYTE MaxZones;
+ BYTE MaxSectors;
+ WORD MaxBlocks;
+ WORD MaxLogBlocks;
+};
+
+typedef struct SSFDCTYPE_T
+{
+ BYTE Model;
+ BYTE Attribute;
+ BYTE MaxZones;
+ BYTE MaxSectors;
+ WORD MaxBlocks;
+ WORD MaxLogBlocks;
+} *SSFDCTYPE_T;
+
+struct ADDRESS
+{
+ BYTE Zone; /* Zone Number */
+ BYTE Sector; /* Sector(512byte) Number on Block */
+ WORD PhyBlock; /* Physical Block Number on Zone */
+ WORD LogBlock; /* Logical Block Number of Zone */
+};
+
+typedef struct ADDRESS_T
+{
+ BYTE Zone; /* Zone Number */
+ BYTE Sector; /* Sector(512byte) Number on Block */
+ WORD PhyBlock; /* Physical Block Number on Zone */
+ WORD LogBlock; /* Logical Block Number of Zone */
+} *ADDRESS_T;
+
+struct CIS_AREA
+{
+ BYTE Sector; /* Sector(512byte) Number on Block */
+ WORD PhyBlock; /* Physical Block Number on Zone 0 */
+};
+
+
+//----- SMILMain.c ---------------------------------------------------
+/******************************************/
+int Init_D_SmartMedia (void);
+int Pwoff_D_SmartMedia (void);
+int Check_D_SmartMedia (void);
+int Check_D_Parameter (struct us_data *,WORD *,BYTE *,BYTE *);
+int Media_D_ReadSector (struct us_data *,DWORD,WORD,BYTE *);
+int Media_D_WriteSector (struct us_data *,DWORD,WORD,BYTE *);
+int Media_D_CopySector (struct us_data *,DWORD,WORD,BYTE *);
+int Media_D_EraseBlock (struct us_data *,DWORD,WORD);
+int Media_D_EraseAll (struct us_data *);
+/******************************************/
+int Media_D_OneSectWriteStart (struct us_data *,DWORD,BYTE *);
+int Media_D_OneSectWriteNext (struct us_data *,BYTE *);
+int Media_D_OneSectWriteFlush (struct us_data *);
+
+/******************************************/
+void SM_EnableLED (struct us_data *,BOOLEAN);
+void Led_D_TernOn (void);
+void Led_D_TernOff (void);
+
+int Media_D_EraseAllRedtData (DWORD Index, BOOLEAN CheckBlock);
+//DWORD Media_D_GetMediaInfo (struct us_data * fdoExt, PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut);
+
+//----- SMILSub.c ----------------------------------------------------
+/******************************************/
+int Check_D_DataBlank (BYTE *);
+int Check_D_FailBlock (BYTE *);
+int Check_D_DataStatus (BYTE *);
+int Load_D_LogBlockAddr (BYTE *);
+void Clr_D_RedundantData (BYTE *);
+void Set_D_LogBlockAddr (BYTE *);
+void Set_D_FailBlock (BYTE *);
+void Set_D_DataStaus (BYTE *);
+
+/******************************************/
+void Ssfdc_D_Reset (struct us_data *);
+int Ssfdc_D_ReadCisSect (struct us_data *, BYTE *,BYTE *);
+void Ssfdc_D_WriteRedtMode (void);
+void Ssfdc_D_ReadID (BYTE *, BYTE);
+int Ssfdc_D_ReadSect (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_ReadBlock (struct us_data *, WORD, BYTE *,BYTE *);
+int Ssfdc_D_WriteSect (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_WriteBlock (struct us_data *, WORD, BYTE *,BYTE *);
+int Ssfdc_D_CopyBlock (struct us_data *, WORD, BYTE *,BYTE *);
+int Ssfdc_D_WriteSectForCopy (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_EraseBlock (struct us_data *);
+int Ssfdc_D_ReadRedtData (struct us_data *, BYTE *);
+int Ssfdc_D_WriteRedtData (struct us_data *, BYTE *);
+int Ssfdc_D_CheckStatus (void);
+int Set_D_SsfdcModel (BYTE);
+void Cnt_D_Reset (void);
+int Cnt_D_PowerOn (void);
+void Cnt_D_PowerOff (void);
+void Cnt_D_LedOn (void);
+void Cnt_D_LedOff (void);
+int Check_D_CntPower (void);
+int Check_D_CardExist (void);
+int Check_D_CardStsChg (void);
+int Check_D_SsfdcWP (void);
+int SM_ReadBlock (struct us_data *, BYTE *,BYTE *);
+
+int Ssfdc_D_ReadSect_DMA (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_ReadSect_PIO (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_WriteSect_DMA (struct us_data *, BYTE *,BYTE *);
+int Ssfdc_D_WriteSect_PIO (struct us_data *, BYTE *,BYTE *);
+
+/******************************************/
+int Check_D_ReadError (BYTE *);
+int Check_D_Correct (BYTE *,BYTE *);
+int Check_D_CISdata (BYTE *,BYTE *);
+void Set_D_RightECC (BYTE *);
+
+//----- SMILECC.c ----------------------------------------------------
+void calculate_ecc (BYTE *, BYTE *, BYTE *, BYTE *, BYTE *);
+BYTE correct_data (BYTE *, BYTE *, BYTE, BYTE, BYTE);
+int _Correct_D_SwECC (BYTE *,BYTE *,BYTE *);
+void _Calculate_D_SwECC (BYTE *,BYTE *);
+
+void SM_Init (void);
+
+#endif // already included
diff --git a/drivers/staging/keucr/smilecc.c b/drivers/staging/keucr/smilecc.c
new file mode 100644
index 000000000000..daf322ac9bf9
--- /dev/null
+++ b/drivers/staging/keucr/smilecc.c
@@ -0,0 +1,201 @@
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+//#include "stdlib.h"
+//#include "EUCR6SK.h"
+#include "smcommon.h"
+#include "smil.h"
+
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <string.h>
+//#include <dos.h>
+//
+//#include "EMCRIOS.h"
+
+// CP0-CP5 code table
+static BYTE ecctable[256] = {
+0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00,
+0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
+0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
+0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
+0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
+0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
+0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
+0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
+0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
+0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
+0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
+0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
+0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
+0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
+0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
+0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00
+};
+
+static void trans_result (BYTE, BYTE, BYTE *, BYTE *);
+
+#define BIT7 0x80
+#define BIT6 0x40
+#define BIT5 0x20
+#define BIT4 0x10
+#define BIT3 0x08
+#define BIT2 0x04
+#define BIT1 0x02
+#define BIT0 0x01
+#define BIT1BIT0 0x03
+#define BIT23 0x00800000L
+#define MASK_CPS 0x3f
+#define CORRECTABLE 0x00555554L
+
+static void trans_result(reg2,reg3,ecc1,ecc2)
+BYTE reg2; // LP14,LP12,LP10,...
+BYTE reg3; // LP15,LP13,LP11,...
+BYTE *ecc1; // LP15,LP14,LP13,...
+BYTE *ecc2; // LP07,LP06,LP05,...
+{
+ BYTE a; // Working for reg2,reg3
+ BYTE b; // Working for ecc1,ecc2
+ BYTE i; // For counting
+
+ a=BIT7; b=BIT7; // 80h=10000000b
+ *ecc1=*ecc2=0; // Clear ecc1,ecc2
+ for(i=0; i<4; ++i) {
+ if ((reg3&a)!=0)
+ *ecc1|=b; // LP15,13,11,9 -> ecc1
+ b=b>>1; // Right shift
+ if ((reg2&a)!=0)
+ *ecc1|=b; // LP14,12,10,8 -> ecc1
+ b=b>>1; // Right shift
+ a=a>>1; // Right shift
+ }
+
+ b=BIT7; // 80h=10000000b
+ for(i=0; i<4; ++i) {
+ if ((reg3&a)!=0)
+ *ecc2|=b; // LP7,5,3,1 -> ecc2
+ b=b>>1; // Right shift
+ if ((reg2&a)!=0)
+ *ecc2|=b; // LP6,4,2,0 -> ecc2
+ b=b>>1; // Right shift
+ a=a>>1; // Right shift
+ }
+}
+
+//static void calculate_ecc(table,data,ecc1,ecc2,ecc3)
+void calculate_ecc(table,data,ecc1,ecc2,ecc3)
+BYTE *table; // CP0-CP5 code table
+BYTE *data; // DATA
+BYTE *ecc1; // LP15,LP14,LP13,...
+BYTE *ecc2; // LP07,LP06,LP05,...
+BYTE *ecc3; // CP5,CP4,CP3,...,"1","1"
+{
+ DWORD i; // For counting
+ BYTE a; // Working for table
+ BYTE reg1; // D-all,CP5,CP4,CP3,...
+ BYTE reg2; // LP14,LP12,L10,...
+ BYTE reg3; // LP15,LP13,L11,...
+
+ reg1=reg2=reg3=0; // Clear parameter
+ for(i=0; i<256; ++i) {
+ a=table[data[i]]; // Get CP0-CP5 code from table
+ reg1^=(a&MASK_CPS); // XOR with a
+ if ((a&BIT6)!=0)
+ { // If D_all(all bit XOR) = 1
+ reg3^=(BYTE)i; // XOR with counter
+ reg2^=~((BYTE)i); // XOR with inv. of counter
+ }
+ }
+
+ // Trans LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,..
+ trans_result(reg2,reg3,ecc1,ecc2);
+ *ecc1=~(*ecc1); *ecc2=~(*ecc2); // Inv. ecc2 & ecc3
+ *ecc3=((~reg1)<<2)|BIT1BIT0; // Make TEL format
+}
+
+BYTE correct_data(data,eccdata,ecc1,ecc2,ecc3)
+BYTE *data; // DATA
+BYTE *eccdata; // ECC DATA
+BYTE ecc1; // LP15,LP14,LP13,...
+BYTE ecc2; // LP07,LP06,LP05,...
+BYTE ecc3; // CP5,CP4,CP3,...,"1","1"
+{
+ DWORD l; // Working to check d
+ DWORD d; // Result of comparison
+ DWORD i; // For counting
+ BYTE d1,d2,d3; // Result of comparison
+ BYTE a; // Working for add
+ BYTE add; // Byte address of cor. DATA
+ BYTE b; // Working for bit
+ BYTE bit; // Bit address of cor. DATA
+
+ d1=ecc1^eccdata[1]; d2=ecc2^eccdata[0]; // Compare LP's
+ d3=ecc3^eccdata[2]; // Comapre CP's
+ d=((DWORD)d1<<16) // Result of comparison
+ +((DWORD)d2<<8)
+ +(DWORD)d3;
+
+ if (d==0) return(0); // If No error, return
+
+ if (((d^(d>>1))&CORRECTABLE)==CORRECTABLE)
+ { // If correctable
+ l=BIT23;
+ add=0; // Clear parameter
+ a=BIT7;
+
+ for(i=0; i<8; ++i) { // Checking 8 bit
+ if ((d&l)!=0) add|=a; // Make byte address from LP's
+ l>>=2; a>>=1; // Right Shift
+ }
+
+ bit=0; // Clear parameter
+ b=BIT2;
+ for(i=0; i<3; ++i) { // Checking 3 bit
+ if ((d&l)!=0) bit|=b; // Make bit address from CP's
+ l>>=2; b>>=1; // Right shift
+ }
+
+ b=BIT0;
+ data[add]^=(b<<bit); // Put corrected data
+ return(1);
+ }
+
+ i=0; // Clear count
+ d&=0x00ffffffL; // Masking
+
+ while(d) { // If d=0 finish counting
+ if (d&BIT0) ++i; // Count number of 1 bit
+ d>>=1; // Right shift
+ }
+
+ if (i==1)
+ { // If ECC error
+ eccdata[1]=ecc1; eccdata[0]=ecc2; // Put right ECC code
+ eccdata[2]=ecc3;
+ return(2);
+ }
+ return(3); // Uncorrectable error
+}
+
+int _Correct_D_SwECC(buf,redundant_ecc,calculate_ecc)
+BYTE *buf;
+BYTE *redundant_ecc;
+BYTE *calculate_ecc;
+{
+ DWORD err;
+
+ err=correct_data(buf,redundant_ecc,*(calculate_ecc+1),*(calculate_ecc),*(calculate_ecc+2));
+ if (err==1) StringCopy(calculate_ecc,redundant_ecc,3);
+ if (err==0 || err==1 || err==2)
+ return(0);
+ return(-1);
+}
+
+void _Calculate_D_SwECC(buf,ecc)
+BYTE *buf;
+BYTE *ecc;
+{
+ calculate_ecc(ecctable,buf,ecc+1,ecc+0,ecc+2);
+}
+
+
diff --git a/drivers/staging/keucr/smilmain.c b/drivers/staging/keucr/smilmain.c
new file mode 100644
index 000000000000..bdfbf76f8df9
--- /dev/null
+++ b/drivers/staging/keucr/smilmain.c
@@ -0,0 +1,1852 @@
+#include <linux/slab.h>
+#include "usb.h"
+#include "scsiglue.h"
+#include "smcommon.h"
+#include "smil.h"
+
+int Check_D_LogCHS (WORD *,BYTE *,BYTE *);
+void Initialize_D_Media (void);
+void PowerOff_D_Media (void);
+int Check_D_MediaPower (void);
+int Check_D_MediaExist (void);
+int Check_D_MediaWP (void);
+int Check_D_MediaFmt (struct us_data *);
+int Check_D_MediaFmtForEraseAll (struct us_data *);
+int Conv_D_MediaAddr (struct us_data *, DWORD);
+int Inc_D_MediaAddr (struct us_data *);
+int Check_D_FirstSect (void);
+int Check_D_LastSect (void);
+int Media_D_ReadOneSect (struct us_data *, WORD, BYTE *);
+int Media_D_WriteOneSect (struct us_data *, WORD, BYTE *);
+int Media_D_CopyBlockHead (struct us_data *);
+int Media_D_CopyBlockTail (struct us_data *);
+int Media_D_EraseOneBlock (void);
+int Media_D_EraseAllBlock (void);
+
+int Copy_D_BlockAll (struct us_data *, DWORD);
+int Copy_D_BlockHead (struct us_data *);
+int Copy_D_BlockTail (struct us_data *);
+int Reassign_D_BlockHead (struct us_data *);
+
+int Assign_D_WriteBlock (void);
+int Release_D_ReadBlock (struct us_data *);
+int Release_D_WriteBlock (struct us_data *);
+int Release_D_CopySector (struct us_data *);
+
+int Copy_D_PhyOneSect (struct us_data *);
+int Read_D_PhyOneSect (struct us_data *, WORD, BYTE *);
+int Write_D_PhyOneSect (struct us_data *, WORD, BYTE *);
+int Erase_D_PhyOneBlock (struct us_data *);
+
+int Set_D_PhyFmtValue (struct us_data *);
+int Search_D_CIS (struct us_data *);
+int Make_D_LogTable (struct us_data *);
+void Check_D_BlockIsFull (void);
+
+int MarkFail_D_PhyOneBlock (struct us_data *);
+
+DWORD ErrXDCode;
+DWORD ErrCode;
+//BYTE SectBuf[SECTSIZE];
+BYTE WorkBuf[SECTSIZE];
+BYTE Redundant[REDTSIZE];
+BYTE WorkRedund[REDTSIZE];
+//WORD Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
+WORD *Log2Phy[MAX_ZONENUM]; // 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
+BYTE Assign[MAX_ZONENUM][MAX_BLOCKNUM/8];
+WORD AssignStart[MAX_ZONENUM];
+WORD ReadBlock;
+WORD WriteBlock;
+DWORD MediaChange;
+DWORD SectCopyMode;
+
+extern struct SSFDCTYPE Ssfdc;
+extern struct ADDRESS Media;
+extern struct CIS_AREA CisArea;
+
+//BIT Controll Macro
+BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ;
+#define Set_D_Bit(a,b) (a[(BYTE)((b)/8)]|= BitData[(b)%8])
+#define Clr_D_Bit(a,b) (a[(BYTE)((b)/8)]&=~BitData[(b)%8])
+#define Chk_D_Bit(a,b) (a[(BYTE)((b)/8)] & BitData[(b)%8])
+
+//extern PBYTE SMHostAddr;
+extern BYTE IsSSFDCCompliance;
+extern BYTE IsXDCompliance;
+
+
+//
+////Power Controll & Media Exist Check Function
+////----- Init_D_SmartMedia() --------------------------------------------
+//int Init_D_SmartMedia(void)
+//{
+// int i;
+//
+// EMCR_Print("Init_D_SmartMedia start\n");
+// for (i=0; i<MAX_ZONENUM; i++)
+// {
+// if (Log2Phy[i]!=NULL)
+// {
+// EMCR_Print("ExFreePool Zone = %x, Addr = %x\n", i, Log2Phy[i]);
+// ExFreePool(Log2Phy[i]);
+// Log2Phy[i] = NULL;
+// }
+// }
+//
+// Initialize_D_Media();
+// return(NO_ERROR);
+//}
+
+//----- SM_FreeMem() -------------------------------------------------
+int SM_FreeMem(void)
+{
+ int i;
+
+ printk("SM_FreeMem start\n");
+ for (i=0; i<MAX_ZONENUM; i++)
+ {
+ if (Log2Phy[i]!=NULL)
+ {
+ printk("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
+ kfree(Log2Phy[i]);
+ Log2Phy[i] = NULL;
+ }
+ }
+ return(NO_ERROR);
+}
+
+////----- Pwoff_D_SmartMedia() -------------------------------------------
+//int Pwoff_D_SmartMedia(void)
+//{
+// PowerOff_D_Media();
+// return(NO_ERROR);
+//}
+//
+////----- Check_D_SmartMedia() -------------------------------------------
+//int Check_D_SmartMedia(void)
+//{
+// if (Check_D_MediaExist())
+// return(ErrCode);
+//
+// return(NO_ERROR);
+//}
+//
+////----- Check_D_Parameter() --------------------------------------------
+//int Check_D_Parameter(PFDO_DEVICE_EXTENSION fdoExt,WORD *pcyl,BYTE *phead,BYTE *psect)
+//{
+// if (Check_D_MediaPower())
+// return(ErrCode);
+//
+// if (Check_D_MediaFmt(fdoExt))
+// return(ErrCode);
+//
+// if (Check_D_LogCHS(pcyl,phead,psect))
+// return(ErrCode);
+//
+// return(NO_ERROR);
+//}
+
+//SmartMedia Read/Write/Erase Function
+//----- Media_D_ReadSector() -------------------------------------------
+int Media_D_ReadSector(struct us_data *us, DWORD start,WORD count,BYTE *buf)
+{
+ WORD len, bn;
+
+ //if (Check_D_MediaPower()) ; ¦b 6250 don't care
+ // return(ErrCode); ;
+ //if (Check_D_MediaFmt(fdoExt)) ;
+ // return(ErrCode); ;
+ if (Conv_D_MediaAddr(us, start))
+ return(ErrCode);
+
+ while(1)
+ {
+ len = Ssfdc.MaxSectors - Media.Sector;
+ if (count > len)
+ bn = len;
+ else
+ bn = count;
+ //if (Media_D_ReadOneSect(fdoExt, SectBuf))
+ //if (Media_D_ReadOneSect(fdoExt, count, buf))
+ if (Media_D_ReadOneSect(us, bn, buf))
+ {
+ ErrCode = ERR_EccReadErr;
+ return(ErrCode);
+ }
+
+ Media.Sector += bn;
+ count -= bn;
+
+ if (count<=0)
+ break;
+
+ buf += bn * SECTSIZE;
+
+ if (Inc_D_MediaAddr(us))
+ return(ErrCode);
+ }
+
+ return(NO_ERROR);
+}
+// here
+//----- Media_D_CopySector() ------------------------------------------
+int Media_D_CopySector(struct us_data *us, DWORD start,WORD count,BYTE *buf)
+{
+ //DWORD mode;
+ //int i;
+ WORD len, bn;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ //printk("Media_D_CopySector !!!\n");
+ if (Conv_D_MediaAddr(us, start))
+ return(ErrCode);
+
+ while(1)
+ {
+ if (Assign_D_WriteBlock())
+ return(ERROR);
+
+ len = Ssfdc.MaxSectors - Media.Sector;
+ if (count > len)
+ bn = len;
+ else
+ bn = count;
+
+ //if (Ssfdc_D_CopyBlock(fdoExt,count,buf,Redundant))
+ if (Ssfdc_D_CopyBlock(us,bn,buf,Redundant))
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+
+ Media.Sector = 0x1F;
+ //if (Release_D_ReadBlock(fdoExt))
+ if (Release_D_CopySector(us))
+ {
+ if (ErrCode==ERR_HwError)
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+ }
+ count -= bn;
+
+ if (count<=0)
+ break;
+
+ buf += bn * SECTSIZE;
+
+ if (Inc_D_MediaAddr(us))
+ return(ErrCode);
+
+ }
+ return(NO_ERROR);
+}
+
+//----- Release_D_CopySector() ------------------------------------------
+int Release_D_CopySector(struct us_data *us)
+{
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ Log2Phy[Media.Zone][Media.LogBlock]=WriteBlock;
+ Media.PhyBlock=ReadBlock;
+
+ if (Media.PhyBlock==NO_ASSIGN)
+ {
+ Media.PhyBlock=WriteBlock;
+ return(SUCCESS);
+ }
+
+ Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+ Media.PhyBlock=WriteBlock;
+
+ return(SUCCESS);
+}
+/*
+//----- Media_D_WriteSector() ------------------------------------------
+int Media_D_WriteSector(PFDO_DEVICE_EXTENSION fdoExt, DWORD start,WORD count,BYTE *buf)
+{
+ int i;
+ WORD len, bn;
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ //if (Check_D_MediaPower())
+ // return(ErrCode);
+ //
+ //if (Check_D_MediaFmt(fdoExt))
+ // return(ErrCode);
+ //
+ //if (Check_D_MediaWP())
+ // return(ErrCode);
+
+ if (Conv_D_MediaAddr(fdoExt, start))
+ return(ErrCode);
+
+ //ENE_Print("Media_D_WriteSector --- Sector = %x\n", Media.Sector);
+ if (Check_D_FirstSect())
+ {
+ if (Media_D_CopyBlockHead(fdoExt))
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+ }
+
+ while(1)
+ {
+ if (!Check_D_FirstSect())
+ {
+ if (Assign_D_WriteBlock())
+ return(ErrCode);
+ }
+
+ len = Ssfdc.MaxSectors - Media.Sector;
+ if (count > len)
+ bn = len;
+ else
+ bn = count;
+ //for(i=0;i<SECTSIZE;i++)
+ // SectBuf[i]=*buf++;
+
+ //if (Media_D_WriteOneSect(fdoExt, SectBuf))
+ if (Media_D_WriteOneSect(fdoExt, bn, buf))
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+
+ Media.Sector += bn - 1;
+
+ if (!Check_D_LastSect())
+ {
+ if (Release_D_ReadBlock(fdoExt))
+
+ { if (ErrCode==ERR_HwError)
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+ }
+ }
+
+ count -= bn;
+
+ if (count<=0)
+ break;
+
+ buf += bn * SECTSIZE;
+
+ //if (--count<=0)
+ // break;
+
+ if (Inc_D_MediaAddr(fdoExt))
+ return(ErrCode);
+ }
+
+ if (!Check_D_LastSect())
+ return(NO_ERROR);
+
+ if (Inc_D_MediaAddr(fdoExt))
+ return(ErrCode);
+
+ if (Media_D_CopyBlockTail(fdoExt))
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+
+ return(NO_ERROR);
+}
+//
+////----- Media_D_EraseBlock() -------------------------------------------
+//int Media_D_EraseBlock(PFDO_DEVICE_EXTENSION fdoExt, DWORD start,WORD count)
+//{
+// if (Check_D_MediaPower())
+// return(ErrCode);
+//
+// if (Check_D_MediaFmt(fdoExt))
+// return(ErrCode);
+//
+// if (Check_D_MediaWP())
+// return(ErrCode);
+//
+// if (Conv_D_MediaAddr(start))
+// return(ErrCode);
+//
+// while(Check_D_FirstSect()) {
+// if (Inc_D_MediaAddr(fdoExt))
+// return(ErrCode);
+//
+// if (--count<=0)
+// return(NO_ERROR);
+// }
+//
+// while(1) {
+// if (!Check_D_LastSect())
+// if (Media_D_EraseOneBlock())
+// if (ErrCode==ERR_HwError)
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+//
+// if (Inc_D_MediaAddr(fdoExt))
+// return(ErrCode);
+//
+// if (--count<=0)
+// return(NO_ERROR);
+// }
+//}
+//
+////----- Media_D_EraseAll() ---------------------------------------------
+//int Media_D_EraseAll(PFDO_DEVICE_EXTENSION fdoExt)
+//{
+// if (Check_D_MediaPower())
+// return(ErrCode);
+//
+// if (Check_D_MediaFmtForEraseAll(fdoExt))
+// return(ErrCode);
+//
+// if (Check_D_MediaWP())
+// return(ErrCode);
+//
+// if (Media_D_EraseAllBlock())
+// return(ErrCode);
+//
+// return(NO_ERROR);
+//}
+
+//SmartMedia Write Function for One Sector Write Mode
+//----- Media_D_OneSectWriteStart() ------------------------------------
+int Media_D_OneSectWriteStart(PFDO_DEVICE_EXTENSION fdoExt,DWORD start,BYTE *buf)
+{
+// int i;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// //if (Check_D_MediaPower())
+// // return(ErrCode);
+// //if (Check_D_MediaFmt(fdoExt))
+// // return(ErrCode);
+// //if (Check_D_MediaWP())
+// // return(ErrCode);
+// if (Conv_D_MediaAddr(fdoExt, start))
+// return(ErrCode);
+//
+// if (Check_D_FirstSect())
+// if (Media_D_CopyBlockHead(fdoExt))
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+//
+// if (!Check_D_FirstSect())
+// if (Assign_D_WriteBlock())
+// return(ErrCode);
+//
+// //for(i=0;i<SECTSIZE;i++)
+// // SectBuf[i]=*buf++;
+//
+// //if (Media_D_WriteOneSect(fdoExt, SectBuf))
+// if (Media_D_WriteOneSect(fdoExt, buf))
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+//
+// if (!Check_D_LastSect())
+// {
+// if (Release_D_ReadBlock(fdoExt))
+// if (ErrCode==ERR_HwError)
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+// }
+
+ return(NO_ERROR);
+}
+
+//----- Media_D_OneSectWriteNext() -------------------------------------
+int Media_D_OneSectWriteNext(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf)
+{
+// int i;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// if (Inc_D_MediaAddr(fdoExt))
+// return(ErrCode);
+//
+// if (!Check_D_FirstSect())
+// if (Assign_D_WriteBlock())
+// return(ErrCode);
+//
+// //for(i=0;i<SECTSIZE;i++)
+// // SectBuf[i]=*buf++;
+//
+// //if (Media_D_WriteOneSect(fdoExt, SectBuf))
+// if (Media_D_WriteOneSect(fdoExt, buf))
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+//
+// if (!Check_D_LastSect())
+// {
+// if (Release_D_ReadBlock(fdoExt))
+// if (ErrCode==ERR_HwError)
+// {
+// ErrCode = ERR_WriteFault;
+// return(ErrCode);
+// }
+// }
+
+ return(NO_ERROR);
+}
+
+//----- Media_D_OneSectWriteFlush() ------------------------------------
+int Media_D_OneSectWriteFlush(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ if (!Check_D_LastSect())
+ return(NO_ERROR);
+
+ if (Inc_D_MediaAddr(fdoExt))
+ return(ErrCode);
+
+ if (Media_D_CopyBlockTail(fdoExt))
+ {
+ ErrCode = ERR_WriteFault;
+ return(ErrCode);
+ }
+
+ return(NO_ERROR);
+}
+//
+////LED Tern On/Off Subroutine
+////----- SM_EnableLED() -----------------------------------------------
+//void SM_EnableLED(PFDO_DEVICE_EXTENSION fdoExt, BOOLEAN enable)
+//{
+// if (fdoExt->Drive_IsSWLED)
+// {
+// if (enable)
+// Led_D_TernOn();
+// else
+// Led_D_TernOff();
+// }
+//}
+//
+////----- Led_D_TernOn() -------------------------------------------------
+//void Led_D_TernOn(void)
+//{
+// if (Check_D_CardStsChg())
+// MediaChange=ERROR;
+//
+// Cnt_D_LedOn();
+//}
+//
+////----- Led_D_TernOff() ------------------------------------------------
+//void Led_D_TernOff(void)
+//{
+// if (Check_D_CardStsChg())
+// MediaChange=ERROR;
+//
+// Cnt_D_LedOff();
+//}
+//
+////SmartMedia Logical Format Subroutine
+////----- Check_D_LogCHS() -----------------------------------------------
+//int Check_D_LogCHS(WORD *c,BYTE *h,BYTE *s)
+//{
+// switch(Ssfdc.Model) {
+// case SSFDC1MB: *c=125; *h= 4; *s= 4; break;
+// case SSFDC2MB: *c=125; *h= 4; *s= 8; break;
+// case SSFDC4MB: *c=250; *h= 4; *s= 8; break;
+// case SSFDC8MB: *c=250; *h= 4; *s=16; break;
+// case SSFDC16MB: *c=500; *h= 4; *s=16; break;
+// case SSFDC32MB: *c=500; *h= 8; *s=16; break;
+// case SSFDC64MB: *c=500; *h= 8; *s=32; break;
+// case SSFDC128MB: *c=500; *h=16; *s=32; break;
+// default: *c= 0; *h= 0; *s= 0; ErrCode = ERR_NoSmartMedia; return(ERROR);
+// }
+//
+// return(SUCCESS);
+//}
+//
+////Power Controll & Media Exist Check Subroutine
+////----- Initialize_D_Media() -------------------------------------------
+//void Initialize_D_Media(void)
+//{
+// ErrCode = NO_ERROR;
+// MediaChange = ERROR;
+// SectCopyMode = COMPLETED;
+// Cnt_D_Reset();
+//}
+//
+////----- PowerOff_D_Media() ---------------------------------------------
+//void PowerOff_D_Media(void)
+//{
+// Cnt_D_PowerOff();
+//}
+//
+////----- Check_D_MediaPower() -------------------------------------------
+//int Check_D_MediaPower(void)
+//{
+// //usleep(56*1024);
+// if (Check_D_CardStsChg())
+// MediaChange = ERROR;
+// //usleep(56*1024);
+// if ((!Check_D_CntPower())&&(!MediaChange)) // ¦³ power & Media ¨S³Q change, «h return success
+// return(SUCCESS);
+// //usleep(56*1024);
+//
+// if (Check_D_CardExist()) // Check if card is not exist, return err
+// {
+// ErrCode = ERR_NoSmartMedia;
+// MediaChange = ERROR;
+// return(ERROR);
+// }
+// //usleep(56*1024);
+// if (Cnt_D_PowerOn())
+// {
+// ErrCode = ERR_NoSmartMedia;
+// MediaChange = ERROR;
+// return(ERROR);
+// }
+// //usleep(56*1024);
+// Ssfdc_D_Reset(fdoExt);
+// //usleep(56*1024);
+// return(SUCCESS);
+//}
+//
+////-----Check_D_MediaExist() --------------------------------------------
+//int Check_D_MediaExist(void)
+//{
+// if (Check_D_CardStsChg())
+// MediaChange = ERROR;
+//
+// if (!Check_D_CardExist())
+// {
+// if (!MediaChange)
+// return(SUCCESS);
+//
+// ErrCode = ERR_ChangedMedia;
+// return(ERROR);
+// }
+//
+// ErrCode = ERR_NoSmartMedia;
+//
+// return(ERROR);
+//}
+//
+////----- Check_D_MediaWP() ----------------------------------------------
+//int Check_D_MediaWP(void)
+//{
+// if (Ssfdc.Attribute &MWP)
+// {
+// ErrCode = ERR_WrtProtect;
+// return(ERROR);
+// }
+//
+// return(SUCCESS);
+//}
+*/
+//SmartMedia Physical Format Test Subroutine
+//----- Check_D_MediaFmt() ---------------------------------------------
+int Check_D_MediaFmt(struct us_data *us)
+{
+ printk("Check_D_MediaFmt\n");
+ //ULONG i,j, result=FALSE, zone,block;
+
+ //usleep(56*1024);
+ if (!MediaChange)
+ return(SUCCESS);
+
+ MediaChange = ERROR;
+ SectCopyMode = COMPLETED;
+
+ //usleep(56*1024);
+ if (Set_D_PhyFmtValue(us))
+ {
+ ErrCode = ERR_UnknownMedia;
+ return(ERROR);
+ }
+
+ //usleep(56*1024);
+ if (Search_D_CIS(us))
+ {
+ ErrCode = ERR_IllegalFmt;
+ return(ERROR);
+ }
+
+
+ MediaChange = SUCCESS;
+ return(SUCCESS);
+}
+/*
+////----- Check_D_BlockIsFull() ----------------------------------
+//void Check_D_BlockIsFull()
+//{
+// ULONG i, block;
+//
+// if (IsXDCompliance || IsSSFDCCompliance)
+// {
+// // If the blocks are full then return write-protect.
+// block = Ssfdc.MaxBlocks/8;
+// for (Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
+// {
+// if (Log2Phy[Media.Zone]==NULL)
+// {
+// if (Make_D_LogTable())
+// {
+// ErrCode = ERR_IllegalFmt;
+// return;
+// }
+// }
+//
+// for (i=0; i<block; i++)
+// {
+// if (Assign[Media.Zone][i] != 0xFF)
+// return;
+// }
+// }
+// Ssfdc.Attribute |= WP;
+// }
+//}
+//
+//
+////----- Check_D_MediaFmtForEraseAll() ----------------------------------
+//int Check_D_MediaFmtForEraseAll(PFDO_DEVICE_EXTENSION fdoExt)
+//{
+// MediaChange = ERROR;
+// SectCopyMode = COMPLETED;
+//
+// if (Set_D_PhyFmtValue(fdoExt))
+// {
+// ErrCode = ERR_UnknownMedia;
+// return(ERROR);
+// }
+//
+// if (Search_D_CIS(fdoExt))
+// {
+// ErrCode = ERR_IllegalFmt;
+// return(ERROR);
+// }
+//
+// return(SUCCESS);
+//}
+*/
+//SmartMedia Physical Address Controll Subroutine
+//----- Conv_D_MediaAddr() ---------------------------------------------
+int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
+{
+ DWORD temp;
+ //ULONG zz;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ temp = addr/Ssfdc.MaxSectors;
+ Media.Zone = (BYTE) (temp/Ssfdc.MaxLogBlocks);
+
+ if (Log2Phy[Media.Zone]==NULL)
+ {
+ if (Make_D_LogTable(us))
+ {
+ ErrCode = ERR_IllegalFmt;
+ return(ERROR);
+ }
+ }
+
+ Media.Sector = (BYTE) (addr%Ssfdc.MaxSectors);
+ Media.LogBlock = (WORD) (temp%Ssfdc.MaxLogBlocks);
+
+ if (Media.Zone<Ssfdc.MaxZones)
+ {
+ Clr_D_RedundantData(Redundant);
+ Set_D_LogBlockAddr(Redundant);
+ Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
+ return(SUCCESS);
+ }
+
+ ErrCode = ERR_OutOfLBA;
+ return(ERROR);
+}
+
+//----- Inc_D_MediaAddr() ----------------------------------------------
+int Inc_D_MediaAddr(struct us_data *us)
+{
+ WORD LogBlock = Media.LogBlock;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (++Media.Sector<Ssfdc.MaxSectors)
+ return(SUCCESS);
+
+ if (Log2Phy[Media.Zone]==NULL)
+ {
+ if (Make_D_LogTable(us))
+ {
+ ErrCode = ERR_IllegalFmt;
+ return(ERROR);
+ }
+ }
+
+ Media.Sector=0;
+ Media.LogBlock = LogBlock;
+
+ if (++Media.LogBlock<Ssfdc.MaxLogBlocks)
+ {
+ Clr_D_RedundantData(Redundant);
+ Set_D_LogBlockAddr(Redundant);
+ Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
+ return(SUCCESS);
+ }
+
+ Media.LogBlock=0;
+
+ if (++Media.Zone<Ssfdc.MaxZones)
+ {
+ if (Log2Phy[Media.Zone]==NULL)
+ {
+ if (Make_D_LogTable(us))
+ {
+ ErrCode = ERR_IllegalFmt;
+ return(ERROR);
+ }
+ }
+
+ Media.LogBlock = 0;
+
+ Clr_D_RedundantData(Redundant);
+ Set_D_LogBlockAddr(Redundant);
+ Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
+ return(SUCCESS);
+ }
+
+ Media.Zone=0;
+ ErrCode = ERR_OutOfLBA;
+
+ return(ERROR);
+}
+/*
+//----- Check_D_FirstSect() --------------------------------------------
+int Check_D_FirstSect(void)
+{
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (!Media.Sector)
+ return(SUCCESS);
+
+ return(ERROR);
+}
+
+//----- Check_D_LastSect() ---------------------------------------------
+int Check_D_LastSect(void)
+{
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (Media.Sector<(Ssfdc.MaxSectors-1))
+ return(ERROR);
+
+ return(SUCCESS);
+}
+*/
+//SmartMedia Read/Write Subroutine with Retry
+//----- Media_D_ReadOneSect() ------------------------------------------
+int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
+{
+ DWORD err, retry;
+
+ if (!Read_D_PhyOneSect(us, count, buf))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ if (ErrCode==ERR_DataStatus)
+ return(ERROR);
+
+#ifdef RDERR_REASSIGN
+ if (Ssfdc.Attribute &MWP)
+ {
+ if (ErrCode==ERR_CorReadErr)
+ return(SUCCESS);
+ return(ERROR);
+ }
+
+ err=ErrCode;
+ for(retry=0; retry<2; retry++)
+ {
+ if (Copy_D_BlockAll(us, (err==ERR_EccReadErr)?REQ_FAIL:REQ_ERASE))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ continue;
+ }
+
+ ErrCode = err;
+ if (ErrCode==ERR_CorReadErr)
+ return(SUCCESS);
+ return(ERROR);
+ }
+
+ MediaChange = ERROR;
+#else
+ if (ErrCode==ERR_CorReadErr) return(SUCCESS);
+#endif
+
+ return(ERROR);
+}
+/*
+//----- Media_D_WriteOneSect() -----------------------------------------
+int Media_D_WriteOneSect(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf)
+{
+ DWORD retry;
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (!Write_D_PhyOneSect(fdoExt, count, buf))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+
+ for(retry=1; retry<2; retry++)
+ {
+ if (Reassign_D_BlockHead(fdoExt))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ continue;
+ }
+
+ if (!Write_D_PhyOneSect(fdoExt, count, buf))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ }
+
+ if (Release_D_WriteBlock(fdoExt))
+ return(ERROR);
+
+ ErrCode = ERR_WriteFault;
+ MediaChange = ERROR;
+ return(ERROR);
+}
+
+//SmartMedia Data Copy Subroutine with Retry
+//----- Media_D_CopyBlockHead() ----------------------------------------
+int Media_D_CopyBlockHead(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ DWORD retry;
+
+ for(retry=0; retry<2; retry++)
+ {
+ if (!Copy_D_BlockHead(fdoExt))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ }
+
+ MediaChange = ERROR;
+ return(ERROR);
+}
+
+//----- Media_D_CopyBlockTail() ----------------------------------------
+int Media_D_CopyBlockTail(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ DWORD retry;
+
+ if (!Copy_D_BlockTail(fdoExt))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+
+ for(retry=1; retry<2; retry++)
+ {
+ if (Reassign_D_BlockHead(fdoExt))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ continue;
+ }
+
+ if (!Copy_D_BlockTail(fdoExt))
+ return(SUCCESS);
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ }
+
+ if (Release_D_WriteBlock(fdoExt))
+ return(ERROR);
+
+ ErrCode = ERR_WriteFault;
+ MediaChange = ERROR;
+ return(ERROR);
+}
+//
+////----- Media_D_EraseOneBlock() ----------------------------------------
+//int Media_D_EraseOneBlock(void)
+//{
+// WORD LogBlock = Media.LogBlock;
+// WORD PhyBlock = Media.PhyBlock;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// if (Media.PhyBlock==NO_ASSIGN)
+// return(SUCCESS);
+//
+// if (Log2Phy[Media.Zone]==NULL)
+// {
+// if (Make_D_LogTable())
+// {
+// ErrCode = ERR_IllegalFmt;
+// return(ERROR);
+// }
+// }
+// Media.LogBlock = LogBlock;
+// Media.PhyBlock = PhyBlock;
+//
+// Log2Phy[Media.Zone][Media.LogBlock]=NO_ASSIGN;
+//
+// if (Erase_D_PhyOneBlock(fdoExt))
+// {
+// if (ErrCode==ERR_HwError)
+// return(ERROR);
+// if (MarkFail_D_PhyOneBlock())
+// return(ERROR);
+//
+// ErrCode = ERR_WriteFault;
+// return(ERROR);
+// }
+//
+// Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+// Media.PhyBlock=NO_ASSIGN;
+// return(SUCCESS);
+//}
+//
+////SmartMedia Erase Subroutine
+////----- Media_D_EraseAllBlock() ----------------------------------------
+//int Media_D_EraseAllBlock(void)
+//{
+// WORD cis=0;
+//
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// MediaChange = ERROR;
+// Media.Sector = 0;
+//
+// for(Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
+// for(Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++) {
+// if (Ssfdc_D_ReadRedtData(Redundant))
+// {
+// Ssfdc_D_Reset(fdoExt);
+// return(ERROR);
+// }
+//
+// Ssfdc_D_Reset(fdoExt);
+// if (!Check_D_FailBlock(Redundant))
+// {
+// if (cis)
+// {
+// if (Ssfdc_D_EraseBlock(fdoExt))
+// {
+// ErrCode = ERR_HwError;
+// return(ERROR);
+// }
+//
+// if (Ssfdc_D_CheckStatus())
+// {
+// if (MarkFail_D_PhyOneBlock())
+// return(ERROR);
+// }
+//
+// continue;
+// }
+//
+// if (Media.PhyBlock!=CisArea.PhyBlock)
+// {
+// ErrCode = ERR_IllegalFmt;
+// return(ERROR);
+// }
+//
+// cis++;
+// }
+//
+// }
+// return(SUCCESS);
+//}
+*/
+//SmartMedia Physical Sector Data Copy Subroutine
+//----- Copy_D_BlockAll() ----------------------------------------------
+int Copy_D_BlockAll(struct us_data *us, DWORD mode)
+{
+ BYTE sect;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ sect=Media.Sector;
+
+ if (Assign_D_WriteBlock())
+ return(ERROR);
+ if (mode==REQ_FAIL)
+ SectCopyMode=REQ_FAIL;
+
+ for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
+ {
+ if (Copy_D_PhyOneSect(us))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ if (Release_D_WriteBlock(us))
+ return(ERROR);
+
+ ErrCode = ERR_WriteFault;
+ Media.PhyBlock=ReadBlock;
+ Media.Sector=sect;
+
+ return(ERROR);
+ }
+ }
+
+ if (Release_D_ReadBlock(us))
+ return(ERROR);
+
+ Media.PhyBlock=WriteBlock;
+ Media.Sector=sect;
+ return(SUCCESS);
+}
+/*
+//----- Copy_D_BlockHead() ---------------------------------------------
+int Copy_D_BlockHead(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ BYTE sect;
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ sect=Media.Sector;
+ if (Assign_D_WriteBlock())
+ return(ERROR);
+
+ for(Media.Sector=0; Media.Sector<sect; Media.Sector++)
+ {
+ if (Copy_D_PhyOneSect(fdoExt))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ if (Release_D_WriteBlock(fdoExt))
+ return(ERROR);
+
+ ErrCode = ERR_WriteFault;
+ Media.PhyBlock=ReadBlock;
+ Media.Sector=sect;
+
+ return(ERROR);
+ }
+ }
+
+ Media.PhyBlock=WriteBlock;
+ Media.Sector=sect;
+ return(SUCCESS);
+}
+
+//----- Copy_D_BlockTail() ---------------------------------------------
+int Copy_D_BlockTail(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ BYTE sect;
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ for(sect=Media.Sector; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
+ {
+ if (Copy_D_PhyOneSect(fdoExt))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+
+ Media.PhyBlock=WriteBlock;
+ Media.Sector=sect;
+
+ return(ERROR);
+ }
+ }
+
+ if (Release_D_ReadBlock(fdoExt))
+ return(ERROR);
+
+ Media.PhyBlock=WriteBlock;
+ Media.Sector=sect;
+ return(SUCCESS);
+}
+
+//----- Reassign_D_BlockHead() -----------------------------------------
+int Reassign_D_BlockHead(PFDO_DEVICE_EXTENSION fdoExt)
+{
+ DWORD mode;
+ WORD block;
+ BYTE sect;
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ mode=SectCopyMode;
+ block=ReadBlock;
+ sect=Media.Sector;
+
+ if (Assign_D_WriteBlock())
+ return(ERROR);
+
+ SectCopyMode=REQ_FAIL;
+
+ for(Media.Sector=0; Media.Sector<sect; Media.Sector++)
+ {
+ if (Copy_D_PhyOneSect(fdoExt))
+ {
+ if (ErrCode==ERR_HwError)
+ return(ERROR);
+ if (Release_D_WriteBlock(fdoExt))
+ return(ERROR);
+
+ ErrCode = ERR_WriteFault;
+ SectCopyMode=mode;
+ WriteBlock=ReadBlock;
+ ReadBlock=block;
+ Media.Sector=sect;
+ Media.PhyBlock=WriteBlock;
+
+ return(ERROR);
+ }
+ }
+
+ if (Release_D_ReadBlock(fdoExt))
+ return(ERROR);
+
+ SectCopyMode=mode;
+ ReadBlock=block;
+ Media.Sector=sect;
+ Media.PhyBlock=WriteBlock;
+ return(SUCCESS);
+}
+*/
+//SmartMedia Physical Block Assign/Release Subroutine
+//----- Assign_D_WriteBlock() ------------------------------------------
+int Assign_D_WriteBlock(void)
+{
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+ ReadBlock=Media.PhyBlock;
+
+ for(WriteBlock=AssignStart[Media.Zone]; WriteBlock<Ssfdc.MaxBlocks; WriteBlock++)
+ {
+ if (!Chk_D_Bit(Assign[Media.Zone],WriteBlock))
+ {
+ Set_D_Bit(Assign[Media.Zone],WriteBlock);
+ AssignStart[Media.Zone]=WriteBlock+1;
+ Media.PhyBlock=WriteBlock;
+ SectCopyMode=REQ_ERASE;
+ //ErrXDCode = NO_ERROR;
+ return(SUCCESS);
+ }
+ }
+
+ for(WriteBlock=0; WriteBlock<AssignStart[Media.Zone]; WriteBlock++)
+ {
+ if (!Chk_D_Bit(Assign[Media.Zone],WriteBlock))
+ {
+ Set_D_Bit(Assign[Media.Zone],WriteBlock);
+ AssignStart[Media.Zone]=WriteBlock+1;
+ Media.PhyBlock=WriteBlock;
+ SectCopyMode=REQ_ERASE;
+ //ErrXDCode = NO_ERROR;
+ return(SUCCESS);
+ }
+ }
+
+ WriteBlock=NO_ASSIGN;
+ ErrCode = ERR_WriteFault;
+ // For xD test
+ //Ssfdc.Attribute |= WP;
+ //ErrXDCode = ERR_WrtProtect;
+ return(ERROR);
+}
+
+//----- Release_D_ReadBlock() ------------------------------------------
+int Release_D_ReadBlock(struct us_data *us)
+{
+ DWORD mode;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ mode=SectCopyMode;
+ SectCopyMode=COMPLETED;
+
+ if (mode==COMPLETED)
+ return(SUCCESS);
+
+ Log2Phy[Media.Zone][Media.LogBlock]=WriteBlock;
+ Media.PhyBlock=ReadBlock;
+
+ if (Media.PhyBlock==NO_ASSIGN)
+ {
+ Media.PhyBlock=WriteBlock;
+ return(SUCCESS);
+ }
+
+ if (mode==REQ_ERASE)
+ {
+ if (Erase_D_PhyOneBlock(us))
+ {
+ if (ErrCode==ERR_HwError) return(ERROR);
+ if (MarkFail_D_PhyOneBlock(us)) return(ERROR);
+ }
+ else
+ Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+ }
+ else if (MarkFail_D_PhyOneBlock(us))
+ return(ERROR);
+
+ Media.PhyBlock=WriteBlock;
+ return(SUCCESS);
+}
+
+//----- Release_D_WriteBlock() -----------------------------------------
+int Release_D_WriteBlock(struct us_data *us)
+{
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+ SectCopyMode=COMPLETED;
+ Media.PhyBlock=WriteBlock;
+
+ if (MarkFail_D_PhyOneBlock(us))
+ return(ERROR);
+
+ Media.PhyBlock=ReadBlock;
+ return(SUCCESS);
+}
+
+//SmartMedia Physical Sector Data Copy Subroutine
+//----- Copy_D_PhyOneSect() --------------------------------------------
+int Copy_D_PhyOneSect(struct us_data *us)
+{
+ int i;
+ DWORD err, retry;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ //printk("Copy_D_PhyOneSect --- Secotr = %x\n", Media.Sector);
+ if (ReadBlock!=NO_ASSIGN)
+ {
+ Media.PhyBlock=ReadBlock;
+ for(retry=0; retry<2; retry++)
+ {
+ if (retry!=0)
+ {
+ Ssfdc_D_Reset(us);
+ if (Ssfdc_D_ReadCisSect(us,WorkBuf,WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+
+ if (Check_D_CISdata(WorkBuf,WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ }
+
+ if (Ssfdc_D_ReadSect(us,WorkBuf,WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Check_D_DataStatus(WorkRedund))
+ { err=ERROR; break; }
+ if (!Check_D_ReadError(WorkRedund))
+ { err=SUCCESS; break; }
+ if (!Check_D_Correct(WorkBuf,WorkRedund))
+ { err=SUCCESS; break; }
+
+ err=ERROR;
+ SectCopyMode=REQ_FAIL;
+ }
+ }
+ else
+ {
+ err=SUCCESS;
+ for(i=0; i<SECTSIZE; i++)
+ WorkBuf[i]=DUMMY_DATA;
+ Clr_D_RedundantData(WorkRedund);
+ }
+
+ Set_D_LogBlockAddr(WorkRedund);
+ if (err==ERROR)
+ {
+ Set_D_RightECC(WorkRedund);
+ Set_D_DataStaus(WorkRedund);
+ }
+
+ Media.PhyBlock=WriteBlock;
+
+ if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Ssfdc_D_CheckStatus())
+ { ErrCode = ERR_WriteFault; return(ERROR); }
+
+ Media.PhyBlock=ReadBlock;
+ return(SUCCESS);
+}
+
+//SmartMedia Physical Sector Read/Write/Erase Subroutine
+//----- Read_D_PhyOneSect() --------------------------------------------
+int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf)
+{
+ int i;
+ DWORD retry;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (Media.PhyBlock==NO_ASSIGN)
+ {
+ for(i=0; i<SECTSIZE; i++)
+ *buf++=DUMMY_DATA;
+ return(SUCCESS);
+ }
+
+ for(retry=0; retry<2; retry++)
+ {
+ if (retry!=0)
+ {
+ Ssfdc_D_Reset(us);
+
+ if (Ssfdc_D_ReadCisSect(us,WorkBuf,WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Check_D_CISdata(WorkBuf,WorkRedund))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ }
+
+ //if (Ssfdc_D_ReadSect(fdoExt,buf,Redundant))
+ if (Ssfdc_D_ReadBlock(us,count,buf,Redundant))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Check_D_DataStatus(Redundant))
+ { ErrCode = ERR_DataStatus; return(ERROR); }
+
+ if (!Check_D_ReadError(Redundant))
+ return(SUCCESS);
+
+ if (!Check_D_Correct(buf,Redundant))
+ { ErrCode = ERR_CorReadErr; return(ERROR); }
+ }
+
+ ErrCode = ERR_EccReadErr;
+ return(ERROR);
+}
+/*
+//----- Write_D_PhyOneSect() -------------------------------------------
+int Write_D_PhyOneSect(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf)
+{
+ SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ //if (Ssfdc_D_WriteSect(fdoExt,buf,Redundant))
+ if (Ssfdc_D_WriteBlock(fdoExt,count,buf,Redundant))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Ssfdc_D_CheckStatus())
+ { ErrCode = ERR_WriteFault; return(ERROR); }
+
+ return(SUCCESS);
+}
+*/
+//----- Erase_D_PhyOneBlock() ------------------------------------------
+int Erase_D_PhyOneBlock(struct us_data *us)
+{
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (Ssfdc_D_EraseBlock(us))
+ { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+ if (Ssfdc_D_CheckStatus())
+ { ErrCode = ERR_WriteFault; return(ERROR); }
+
+ return(SUCCESS);
+}
+
+//SmartMedia Physical Format Check Local Subroutine
+//----- Set_D_PhyFmtValue() --------------------------------------------
+int Set_D_PhyFmtValue(struct us_data *us)
+{
+// PPDO_DEVICE_EXTENSION pdoExt;
+// BYTE idcode[4];
+// DWORD UserDefData_1, UserDefData_2, Data, mask;
+//
+// //if (!fdoExt->ChildDeviceObject) return(ERROR);
+// //pdoExt = fdoExt->ChildDeviceObject->DeviceExtension;
+//
+// Ssfdc_D_ReadID(idcode, READ_ID_1);
+//
+ //if (Set_D_SsfdcModel(idcode[1]))
+ if (Set_D_SsfdcModel(us->SM_DeviceID))
+ return(ERROR);
+
+// //Use Multi-function pin to differentiate SM and xD.
+// UserDefData_1 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) & 0x80;
+// if (UserDefData_1)
+// {
+// if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x80 ) fdoExt->DiskType = DISKTYPE_XD;
+// if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x40 ) fdoExt->DiskType = DISKTYPE_SM;
+//
+// if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) )
+// {
+// Ssfdc_D_ReadID(idcode, READ_ID_3);
+// if (idcode[2] != 0xB5)
+// return(ERROR);
+// }
+// }
+//
+// //Use GPIO to differentiate SM and xD.
+// UserDefData_2 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) >> 8;
+// if ( UserDefData_2 )
+// {
+// Data = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, 0, 0xAC);
+//
+// mask = 1 << (UserDefData_2-1);
+// // 1 : xD , 0 : SM
+// if ( Data & mask)
+// fdoExt->DiskType = DISKTYPE_XD;
+// else
+// fdoExt->DiskType = DISKTYPE_SM;
+//
+// if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) )
+// {
+// Ssfdc_D_ReadID(idcode, READ_ID_3);
+// if (idcode[2] != 0xB5)
+// return(ERROR);
+// }
+// }
+//
+// if ( !(UserDefData_1 | UserDefData_2) )
+// {
+// // Use UserDefine Register to differentiate SM and xD.
+// Ssfdc_D_ReadID(idcode, READ_ID_3);
+//
+// if (idcode[2] == 0xB5)
+// fdoExt->DiskType = DISKTYPE_XD;
+// else
+// {
+// if (!IsXDCompliance)
+// fdoExt->DiskType = DISKTYPE_SM;
+// else
+// return(ERROR);
+// }
+//
+// if (fdoExt->UserDef_DiskType == 0x04) fdoExt->DiskType = DISKTYPE_XD;
+// if (fdoExt->UserDef_DiskType == 0x08) fdoExt->DiskType = DISKTYPE_SM;
+// }
+//
+// if (!fdoExt->UserDef_DisableWP)
+// {
+// if (fdoExt->DiskType == DISKTYPE_SM)
+// {
+// if (Check_D_SsfdcWP())
+// Ssfdc.Attribute|=WP;
+// }
+// }
+
+ return(SUCCESS);
+}
+
+//----- Search_D_CIS() -------------------------------------------------
+int Search_D_CIS(struct us_data *us)
+{
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ Media.Zone=0; Media.Sector=0;
+
+ for (Media.PhyBlock=0; Media.PhyBlock<(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1); Media.PhyBlock++)
+ {
+ if (Ssfdc_D_ReadRedtData(us, Redundant))
+ {
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+ }
+
+ if (!Check_D_FailBlock(Redundant))
+ break;
+ }
+
+ if (Media.PhyBlock==(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1))
+ {
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+ }
+
+ while (Media.Sector<CIS_SEARCH_SECT)
+ {
+ if (Media.Sector)
+ {
+ if (Ssfdc_D_ReadRedtData(us, Redundant))
+ {
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+ }
+ }
+ if (!Check_D_DataStatus(Redundant))
+ {
+ if (Ssfdc_D_ReadSect(us,WorkBuf,Redundant))
+ {
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+ }
+
+ if (Check_D_CISdata(WorkBuf,Redundant))
+ {
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+ }
+
+ CisArea.PhyBlock=Media.PhyBlock;
+ CisArea.Sector=Media.Sector;
+ Ssfdc_D_Reset(us);
+ return(SUCCESS);
+ }
+
+ Media.Sector++;
+ }
+
+ Ssfdc_D_Reset(us);
+ return(ERROR);
+}
+
+//----- Make_D_LogTable() ----------------------------------------------
+int Make_D_LogTable(struct us_data *us)
+{
+ WORD phyblock,logblock;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ if (Log2Phy[Media.Zone]==NULL)
+ {
+ Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK*sizeof(WORD), GFP_KERNEL);
+ //printk("ExAllocatePool Zone = %x, Addr = %x\n", Media.Zone, Log2Phy[Media.Zone]);
+ if (Log2Phy[Media.Zone]==NULL)
+ return(ERROR);
+ }
+
+ Media.Sector=0;
+
+ //for(Media.Zone=0; Media.Zone<MAX_ZONENUM; Media.Zone++)
+ //for(Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
+ {
+ //printk("Make_D_LogTable --- MediaZone = 0x%x\n", Media.Zone);
+ for(Media.LogBlock=0; Media.LogBlock<Ssfdc.MaxLogBlocks; Media.LogBlock++)
+ Log2Phy[Media.Zone][Media.LogBlock]=NO_ASSIGN;
+
+ for(Media.PhyBlock=0; Media.PhyBlock<(MAX_BLOCKNUM/8); Media.PhyBlock++)
+ Assign[Media.Zone][Media.PhyBlock]=0x00;
+
+ for(Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++)
+ {
+ if ((!Media.Zone) && (Media.PhyBlock<=CisArea.PhyBlock))
+ {
+ Set_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+ continue;
+ }
+
+ if (Ssfdc_D_ReadRedtData(us, Redundant))
+ { Ssfdc_D_Reset(us); return(ERROR); }
+
+ if (!Check_D_DataBlank(Redundant))
+ continue;
+
+ Set_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+
+ if (Check_D_FailBlock(Redundant))
+ continue;
+
+ //if (Check_D_DataStatus(Redundant))
+ // continue;
+
+ if (Load_D_LogBlockAddr(Redundant))
+ continue;
+
+ if (Media.LogBlock>=Ssfdc.MaxLogBlocks)
+ continue;
+
+ if (Log2Phy[Media.Zone][Media.LogBlock]==NO_ASSIGN)
+ {
+ Log2Phy[Media.Zone][Media.LogBlock]=Media.PhyBlock;
+ continue;
+ }
+
+ phyblock = Media.PhyBlock;
+ logblock = Media.LogBlock;
+ Media.Sector = (BYTE)(Ssfdc.MaxSectors-1);
+
+ if (Ssfdc_D_ReadRedtData(us, Redundant))
+ { Ssfdc_D_Reset(us); return(ERROR); }
+
+ if (!Load_D_LogBlockAddr(Redundant))
+ {
+ if (Media.LogBlock==logblock)
+ {
+ Media.PhyBlock=Log2Phy[Media.Zone][logblock];
+
+ if (Ssfdc_D_ReadRedtData(us, Redundant))
+ { Ssfdc_D_Reset(us); return(ERROR); }
+
+ Media.PhyBlock=phyblock;
+
+ if (!Load_D_LogBlockAddr(Redundant))
+ {
+ if (Media.LogBlock!=logblock)
+ {
+ Media.PhyBlock=Log2Phy[Media.Zone][logblock];
+ Log2Phy[Media.Zone][logblock]=phyblock;
+ }
+ }
+ else
+ {
+ Media.PhyBlock=Log2Phy[Media.Zone][logblock];
+ Log2Phy[Media.Zone][logblock]=phyblock;
+ }
+ }
+ }
+
+ Media.Sector=0;
+
+// here Not yet
+//#ifdef L2P_ERR_ERASE
+// if (!(Ssfdc.Attribute &MWP))
+// {
+// Ssfdc_D_Reset(fdoExt);
+// if (Ssfdc_D_EraseBlock(fdoExt))
+// return(ERROR);
+//
+// if (Ssfdc_D_CheckStatus())
+// {
+// if (MarkFail_D_PhyOneBlock())
+// return(ERROR);
+// }
+// else
+// Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+// }
+//#else
+// Ssfdc.Attribute|=MWP;
+//#endif
+ Media.PhyBlock=phyblock;
+
+ } // End for (Media.PhyBlock<Ssfdc.MaxBlocks)
+
+ AssignStart[Media.Zone]=0;
+
+ } // End for (Media.Zone<MAX_ZONENUM)
+
+ Ssfdc_D_Reset(us);
+ return(SUCCESS);
+}
+
+//----- MarkFail_D_PhyOneBlock() ---------------------------------------
+int MarkFail_D_PhyOneBlock(struct us_data *us)
+{
+ BYTE sect;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ sect=Media.Sector;
+ Set_D_FailBlock(WorkRedund);
+ //Ssfdc_D_WriteRedtMode();
+
+ for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
+ {
+ if (Ssfdc_D_WriteRedtData(us, WorkRedund))
+ {
+ Ssfdc_D_Reset(us);
+ Media.Sector = sect;
+ ErrCode = ERR_HwError;
+ MediaChange = ERROR;
+ return(ERROR);
+ } // NO Status Check
+ }
+
+ Ssfdc_D_Reset(us);
+ Media.Sector=sect;
+ return(SUCCESS);
+}
+/*
+//
+////----- SM_Init() ----------------------------------------------------
+//void SM_Init(void)
+//{
+// _Hw_D_ClrIntCardChg();
+// _Hw_D_SetIntMask();
+// // For DMA Interrupt
+// _Hw_D_ClrDMAIntCardChg();
+// _Hw_D_SetDMAIntMask();
+//}
+//
+////----- Media_D_EraseAllRedtData() -----------------------------------
+//int Media_D_EraseAllRedtData(DWORD Index, BOOLEAN CheckBlock)
+//{
+// BYTE i;
+//
+// if (Check_D_MediaPower())
+// return(ErrCode);
+//
+// if (Check_D_MediaWP())
+// return(ErrCode);
+//
+// for (i=0; i<REDTSIZE; i++)
+// WorkRedund[i] = 0xFF;
+//
+// Media.Zone = (BYTE)Index;
+// for (Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++)
+// {
+// if ((!Media.Zone) && (Media.PhyBlock<=CisArea.PhyBlock))
+// continue;
+//
+// if (Ssfdc_D_EraseBlock(fdoExt))
+// {
+// ErrCode = ERR_HwError;
+// return(ERROR);
+// }
+//
+// for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
+// {
+// Ssfdc_D_WriteRedtMode();
+//
+// if (Ssfdc_D_WriteRedtData(WorkRedund))
+// {
+// Ssfdc_D_Reset(fdoExt);
+// ErrCode = ERR_HwError;
+// MediaChange = ERROR;
+// return(ERROR);
+// } // NO Status Check
+// }
+//
+// Ssfdc_D_Reset(fdoExt);
+// }
+//
+// Ssfdc_D_Reset(fdoExt);
+//
+// return(SUCCESS);
+//}
+//
+////----- Media_D_GetMediaInfo() ---------------------------------------
+//DWORD Media_D_GetMediaInfo(PFDO_DEVICE_EXTENSION fdoExt, PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut)
+//{
+// pParamOut->ErrCode = STATUS_CMD_FAIL;
+//
+// Init_D_SmartMedia();
+//
+// if (Check_D_MediaPower())
+// return (ErrCode==ERR_NoSmartMedia) ? STATUS_CMD_NO_MEDIA : STATUS_CMD_FAIL;
+//
+// if (Set_D_PhyFmtValue(fdoExt))
+// return STATUS_CMD_FAIL;
+//
+// //usleep(56*1024);
+// if (Search_D_CIS(fdoExt))
+// return STATUS_CMD_FAIL;
+//
+// if (Check_D_MediaWP())
+// return STATUS_CMD_MEDIA_WP;
+//
+// pParamOut->PageSize = Ssfdc.MaxSectors;
+// pParamOut->BlockSize = Ssfdc.MaxBlocks;
+// pParamOut->ZoneSize = Ssfdc.MaxZones;
+//
+// return STATUS_CMD_SUCCESS;
+//}*/
diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c
new file mode 100644
index 000000000000..844b65988636
--- /dev/null
+++ b/drivers/staging/keucr/smilsub.c
@@ -0,0 +1,1661 @@
+#include <linux/slab.h>
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+//#include "init.h"
+
+//#include "stdlib.h"
+//#include "EUCR6SK.h"
+#include "smcommon.h"
+#include "smil.h"
+
+void _Set_D_SsfdcRdCmd (BYTE);
+void _Set_D_SsfdcRdAddr (BYTE);
+void _Set_D_SsfdcRdChip (void);
+void _Set_D_SsfdcRdStandby (void);
+void _Start_D_SsfdcRdHwECC (void);
+void _Stop_D_SsfdcRdHwECC (void);
+void _Load_D_SsfdcRdHwECC (BYTE);
+void _Set_D_SsfdcWrCmd (BYTE);
+void _Set_D_SsfdcWrAddr (BYTE);
+void _Set_D_SsfdcWrBlock (void);
+void _Set_D_SsfdcWrStandby (void);
+void _Start_D_SsfdcWrHwECC (void);
+void _Load_D_SsfdcWrHwECC (BYTE);
+int _Check_D_SsfdcBusy (WORD);
+int _Check_D_SsfdcStatus (void);
+void _Reset_D_SsfdcErr (void);
+void _Read_D_SsfdcBuf (BYTE *);
+void _Write_D_SsfdcBuf (BYTE *);
+void _Read_D_SsfdcByte (BYTE *);
+void _ReadRedt_D_SsfdcBuf (BYTE *);
+void _WriteRedt_D_SsfdcBuf (BYTE *);
+BYTE _Check_D_DevCode (BYTE);
+
+void _Set_D_ECCdata (BYTE,BYTE *);
+void _Calc_D_ECCdata (BYTE *);
+
+//void SM_ReadDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD);
+//void SM_WriteDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD);
+//
+struct SSFDCTYPE Ssfdc;
+struct ADDRESS Media;
+struct CIS_AREA CisArea;
+
+BYTE EccBuf[6];
+extern PBYTE SMHostAddr;
+extern BYTE IsSSFDCCompliance;
+extern BYTE IsXDCompliance;
+extern DWORD ErrXDCode;
+
+extern WORD ReadBlock;
+extern WORD WriteBlock;
+
+//KEVENT SM_DMADoneEvent;
+
+#define EVEN 0 // Even Page for 256byte/page
+#define ODD 1 // Odd Page for 256byte/page
+
+
+//SmartMedia Redundant buffer data Controll Subroutine
+//----- Check_D_DataBlank() --------------------------------------------
+int Check_D_DataBlank(BYTE *redundant)
+{
+ char i;
+
+ for(i=0; i<REDTSIZE; i++)
+ if (*redundant++!=0xFF)
+ return(ERROR);
+
+ return(SUCCESS);
+}
+
+//----- Check_D_FailBlock() --------------------------------------------
+int Check_D_FailBlock(BYTE *redundant)
+{
+ redundant+=REDT_BLOCK;
+
+ if (*redundant==0xFF)
+ return(SUCCESS);
+ if (!*redundant)
+ return(ERROR);
+ if (Bit_D_Count(*redundant)<7)
+ return(ERROR);
+
+ return(SUCCESS);
+}
+
+//----- Check_D_DataStatus() -------------------------------------------
+int Check_D_DataStatus(BYTE *redundant)
+{
+ redundant+=REDT_DATA;
+
+ if (*redundant==0xFF)
+ return(SUCCESS);
+ if (!*redundant)
+ {
+ ErrXDCode = ERR_DataStatus;
+ return(ERROR);
+ }
+ else
+ ErrXDCode = NO_ERROR;
+
+ if (Bit_D_Count(*redundant)<5)
+ return(ERROR);
+
+ return(SUCCESS);
+}
+
+//----- Load_D_LogBlockAddr() ------------------------------------------
+int Load_D_LogBlockAddr(BYTE *redundant)
+{
+ WORD addr1,addr2;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ addr1=(WORD)*(redundant+REDT_ADDR1H)*0x0100+(WORD)*(redundant+REDT_ADDR1L);
+ addr2=(WORD)*(redundant+REDT_ADDR2H)*0x0100+(WORD)*(redundant+REDT_ADDR2L);
+
+ if (addr1==addr2)
+ if ((addr1 &0xF000)==0x1000)
+ { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
+
+ if (Bit_D_CountWord((WORD)(addr1^addr2))!=0x01) return(ERROR);
+
+ if ((addr1 &0xF000)==0x1000)
+ if (!(Bit_D_CountWord(addr1) &0x01))
+ { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
+
+ if ((addr2 &0xF000)==0x1000)
+ if (!(Bit_D_CountWord(addr2) &0x01))
+ { Media.LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
+
+ return(ERROR);
+}
+
+//----- Clr_D_RedundantData() ------------------------------------------
+void Clr_D_RedundantData(BYTE *redundant)
+{
+ char i;
+
+ for(i=0; i<REDTSIZE; i++)
+ *(redundant+i)=0xFF;
+}
+
+//----- Set_D_LogBlockAddr() -------------------------------------------
+void Set_D_LogBlockAddr(BYTE *redundant)
+{
+ WORD addr;
+
+ *(redundant+REDT_BLOCK)=0xFF;
+ *(redundant+REDT_DATA) =0xFF;
+ addr=Media.LogBlock*2+0x1000;
+
+ if ((Bit_D_CountWord(addr)%2))
+ addr++;
+
+ *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=(BYTE)(addr/0x0100);
+ *(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(BYTE)addr;
+}
+
+//----- Set_D_FailBlock() ----------------------------------------------
+void Set_D_FailBlock(BYTE *redundant)
+{
+ char i;
+
+ for(i=0; i<REDTSIZE; i++)
+ *redundant++=(BYTE)((i==REDT_BLOCK)?0xF0:0xFF);
+}
+
+//----- Set_D_DataStaus() ----------------------------------------------
+void Set_D_DataStaus(BYTE *redundant)
+{
+ redundant+=REDT_DATA;
+ *redundant=0x00;
+}
+
+//SmartMedia Function Command Subroutine
+// 6250 CMD 6
+//----- Ssfdc_D_Reset() ------------------------------------------------
+void Ssfdc_D_Reset(struct us_data *us)
+{
+ //NTSTATUS ntStatus = STATUS_SUCCESS;
+ //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ //BYTE buf[0x200];
+
+ //printk("Ssfdc_D_Reset --- But do nothing !!\n");
+ return;
+/* RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW));
+ pBulkCbw->dCBWSignature = CBW_SIGNTURE;
+ pBulkCbw->bCBWLun = CBW_LUN;
+ //pBulkCbw->dCBWDataTransferLength = 0x200;
+ pBulkCbw->bmCBWFlags = 0x80;
+ pBulkCbw->CBWCb[0] = 0xF2;
+ pBulkCbw->CBWCb[1] = 0x07;
+
+ ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, NULL);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ ENE_Print("Ssfdc_D_Reset Fail !!\n");
+ //return ntStatus;
+ }*/
+}
+
+//----- Ssfdc_D_ReadCisSect() ------------------------------------------
+int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf,BYTE *redundant)
+{
+ BYTE zone,sector;
+ WORD block;
+ //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+ //ADDRESS_T bb = (ADDRESS_T) &Media;
+
+ zone=Media.Zone; block=Media.PhyBlock; sector=Media.Sector;
+ Media.Zone=0;
+ Media.PhyBlock=CisArea.PhyBlock;
+ Media.Sector=CisArea.Sector;
+
+ if (Ssfdc_D_ReadSect(us,buf,redundant))
+ {
+ Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector;
+ return(ERROR);
+ }
+
+ Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector;
+ return(SUCCESS);
+}
+/*
+////----- Ssfdc_D_WriteRedtMode() ----------------------------------------
+//void Ssfdc_D_WriteRedtMode(void)
+//{
+// _Set_D_SsfdcRdCmd (RST_CHIP);
+// _Check_D_SsfdcBusy (BUSY_RESET);
+// _Set_D_SsfdcRdCmd (READ_REDT);
+// _Check_D_SsfdcBusy (BUSY_READ);
+// _Set_D_SsfdcRdStandby ();
+//}
+//
+////----- Ssfdc_D_ReadID() -----------------------------------------------
+//void Ssfdc_D_ReadID(BYTE *buf, BYTE ReadID)
+//{
+// _Set_D_SsfdcRdCmd (ReadID);
+// _Set_D_SsfdcRdChip ();
+// _Read_D_SsfdcByte (buf++);
+// _Read_D_SsfdcByte (buf++);
+// _Read_D_SsfdcByte (buf++);
+// _Read_D_SsfdcByte (buf);
+// _Set_D_SsfdcRdStandby ();
+//}
+*/
+// 6250 CMD 1
+//----- Ssfdc_D_ReadSect() ---------------------------------------------
+int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ WORD addr;
+
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Read sect data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x02;
+ bcb->CDB[4] = (BYTE)addr;
+ bcb->CDB[3] = (BYTE)(addr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Read redundant
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x10;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[4] = (BYTE)addr;
+ bcb->CDB[3] = (BYTE)(addr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+ bcb->CDB[8] = 0;
+ bcb->CDB[9] = 1;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- Ssfdc_D_ReadBlock() ---------------------------------------------
+int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ WORD addr;
+
+ //printk("Ssfdc_D_ReadBlock\n");
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Read sect data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200*count;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x02;
+ bcb->CDB[4] = (BYTE)addr;
+ bcb->CDB[3] = (BYTE)(addr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ // Read redundant
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x10;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[4] = (BYTE)addr;
+ bcb->CDB[3] = (BYTE)(addr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+ bcb->CDB[8] = 0;
+ bcb->CDB[9] = 1;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+/*
+////----- Ssfdc_D_ReadSect_DMA() ---------------------------------------------
+//int Ssfdc_D_ReadSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+//{
+// WORD SectByteCount, addr;
+// DWORD Buffer[4];
+// WORD len;
+//
+// if (!_Hw_D_ChkCardIn())
+// return(ERROR);
+// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+// // cycle starting address
+// SM_STARTADDR_LSB = 0x00;
+// SM_STARTADDR_IISB = (BYTE)addr;
+// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100);
+// SM_STARTADDR_MSB = Media.Zone/2;
+//
+// //Sector byte count = 0x200(DMA)
+// SectByteCount = 0x20f;
+// SM_BYTECNT_LO = (BYTE)SectByteCount;
+// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | (BYTE)(SectByteCount/0x0100);
+// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate )
+// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK);
+// else
+// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK);
+//
+// _Hw_D_EccRdReset();
+// _Hw_D_EccRdStart();
+//
+// SM_CMD_CTRL1 = (SM_CMD_READ_1);
+// SM_CMD_CTRL1 = (SM_CMD_READ_1 | SM_CMD_START_BIT);
+//
+// SectByteCount = 0x1ff;
+// //SM_ReadDataWithDMA(fdoExt, buf, SectByteCount);
+// //_ReadRedt_D_SsfdcBuf(redundant);
+// len = 0x1000 - ((WORD)(buf) & 0x0FFF);
+// if (len < 0x200)
+// {
+// SM_ReadDataWithDMA(fdoExt, buf, len-1);
+// SM_ReadDataWithDMA(fdoExt, buf+len, SectByteCount-len);
+// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len);
+// }
+// else
+// SM_ReadDataWithDMA(fdoExt, buf, SectByteCount);
+//
+// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate )
+// {
+// _ReadRedt_D_SsfdcBuf(redundant);
+// }
+// else
+// {
+// Buffer[0] = READ_PORT_DWORD(SM_REG_DATA);
+// Buffer[1] = READ_PORT_DWORD(SM_REG_DATA);
+// Buffer[2] = READ_PORT_DWORD(SM_REG_DATA);
+// Buffer[3] = READ_PORT_DWORD(SM_REG_DATA);
+// memcpy(redundant, Buffer, 0x10);
+// }
+//
+// while ( _Hw_D_ChkCardIn() )
+// {
+// if((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10))
+// {
+// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10);
+// break;
+// }
+// }
+// _Hw_D_EccRdStop();
+// _Hw_D_SetRdStandby();
+// _Load_D_SsfdcRdHwECC(EVEN);
+//
+// _Calc_D_ECCdata(buf);
+// _Set_D_SsfdcRdStandby();
+//
+// if (!_Hw_D_ChkCardIn())
+// return(ERROR);
+// return(SUCCESS);
+//}
+//
+////----- Ssfdc_D_ReadSect_PIO() ---------------------------------------------
+//int Ssfdc_D_ReadSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+//{
+// _Set_D_SsfdcRdCmd(READ);
+// _Set_D_SsfdcRdAddr(EVEN);
+//
+// if (_Check_D_SsfdcBusy(BUSY_READ))
+// { _Reset_D_SsfdcErr(); return(ERROR); }
+//
+// _Start_D_SsfdcRdHwECC();
+// _Read_D_SsfdcBuf(buf);
+// _Stop_D_SsfdcRdHwECC();
+// _ReadRedt_D_SsfdcBuf(redundant);
+// _Load_D_SsfdcRdHwECC(EVEN);
+//
+// if (_Check_D_SsfdcBusy(BUSY_READ))
+// { _Reset_D_SsfdcErr(); return(ERROR); }
+//
+// _Calc_D_ECCdata(buf);
+// _Set_D_SsfdcRdStandby();
+// return(SUCCESS);
+//}
+
+// 6250 CMD 3
+//----- Ssfdc_D_WriteSect() --------------------------------------------
+int Ssfdc_D_WriteSect(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+{
+ PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ NTSTATUS ntStatus;
+ WORD addr;
+
+ //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n");
+ ENE_LoadBinCode(fdoExt, SM_RW_PATTERN);
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Write sect data
+ RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW));
+ pBulkCbw->dCBWSignature = CBW_SIGNTURE;
+ pBulkCbw->bCBWLun = CBW_LUN;
+ pBulkCbw->dCBWDataTransferLength = 0x200;
+ pBulkCbw->bmCBWFlags = 0x00;
+ pBulkCbw->CBWCb[0] = 0xF0;
+ pBulkCbw->CBWCb[1] = 0x04;
+ //pBulkCbw->CBWCb[4] = (BYTE)addr;
+ //pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100);
+ //pBulkCbw->CBWCb[2] = Media.Zone/2;
+ //pBulkCbw->CBWCb[5] = *(redundant+REDT_ADDR1H);
+ //pBulkCbw->CBWCb[6] = *(redundant+REDT_ADDR1L);
+ pBulkCbw->CBWCb[7] = (BYTE)addr;
+ pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100);
+ pBulkCbw->CBWCb[5] = Media.Zone/2;
+ pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H);
+ pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L);
+
+ ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf);
+
+ if (!NT_SUCCESS(ntStatus))
+ return(ERROR);
+
+// // For Test
+// {
+// BYTE bf[0x200], rdd[0x10];
+// ULONG i;
+//
+// RtlZeroMemory(bf, 0x200);
+// RtlZeroMemory(rdd, 0x10);
+// ntStatus = SM_ReadBlock(fdoExt, bf, rdd);
+// for (i=0; i<0x200; i++)
+// {
+// if (buf[i] != bf[i])
+// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf);
+// }
+// if (!NT_SUCCESS(ntStatus))
+// ENE_Print("Error\n");
+// }
+
+ return(SUCCESS);
+}
+*/
+//----- Ssfdc_D_CopyBlock() --------------------------------------------
+int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ //NTSTATUS ntStatus;
+ WORD ReadAddr, WriteAddr;
+
+ //printk("Ssfdc_D_WriteSect --- ZONE = %x, ReadBlock = %x, WriteBlock = %x\n", Media.Zone, ReadBlock, WriteBlock);
+
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+ReadBlock;
+ ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors;
+ WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+WriteBlock;
+ WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors;
+
+ // Write sect data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200*count;
+ bcb->Flags = 0x00;
+ bcb->CDB[0] = 0xF0;
+ bcb->CDB[1] = 0x08;
+ bcb->CDB[7] = (BYTE)WriteAddr;
+ bcb->CDB[6] = (BYTE)(WriteAddr/0x0100);
+ bcb->CDB[5] = Media.Zone/2;
+ bcb->CDB[8] = *(redundant+REDT_ADDR1H);
+ bcb->CDB[9] = *(redundant+REDT_ADDR1L);
+ bcb->CDB[10] = Media.Sector;
+
+ if (ReadBlock != NO_ASSIGN)
+ {
+ bcb->CDB[4] = (BYTE)ReadAddr;
+ bcb->CDB[3] = (BYTE)(ReadAddr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+ }
+ else
+ bcb->CDB[11] = 1;
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+/*
+//----- Ssfdc_D_WriteBlock() --------------------------------------------
+int Ssfdc_D_WriteBlock(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf,BYTE *redundant)
+{
+ PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ NTSTATUS ntStatus;
+ WORD addr;
+
+ //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n");
+ ENE_LoadBinCode(fdoExt, SM_RW_PATTERN);
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Write sect data
+ RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW));
+ pBulkCbw->dCBWSignature = CBW_SIGNTURE;
+ pBulkCbw->bCBWLun = CBW_LUN;
+ pBulkCbw->dCBWDataTransferLength = 0x200*count;
+ pBulkCbw->bmCBWFlags = 0x00;
+ pBulkCbw->CBWCb[0] = 0xF0;
+ pBulkCbw->CBWCb[1] = 0x04;
+ pBulkCbw->CBWCb[7] = (BYTE)addr;
+ pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100);
+ pBulkCbw->CBWCb[5] = Media.Zone/2;
+ pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H);
+ pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L);
+
+ ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf);
+
+ if (!NT_SUCCESS(ntStatus))
+ return(ERROR);
+
+// // For Test
+// {
+// BYTE bf[0x200], rdd[0x10];
+// ULONG i;
+//
+// RtlZeroMemory(bf, 0x200);
+// RtlZeroMemory(rdd, 0x10);
+// ntStatus = SM_ReadBlock(fdoExt, bf, rdd);
+// for (i=0; i<0x200; i++)
+// {
+// if (buf[i] != bf[i])
+// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf);
+// }
+// if (!NT_SUCCESS(ntStatus))
+// ENE_Print("Error\n");
+// }
+
+ return(SUCCESS);
+}
+//
+////----- Ssfdc_D_WriteSect_DMA() --------------------------------------------
+//int Ssfdc_D_WriteSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+//{
+// WORD SectByteCount, addr;
+// DWORD Buffer[4];
+// WORD len;
+//
+// if (!_Hw_D_ChkCardIn())
+// return(ERROR);
+// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+// // cycle starting address
+// SM_STARTADDR_LSB = 0x00;
+// SM_STARTADDR_IISB = (BYTE)addr;
+// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100);
+// SM_STARTADDR_MSB = Media.Zone/2;
+//
+// //Sector byte count (DMA)
+// SectByteCount = 0x20f;
+// SM_BYTECNT_LO = (BYTE)SectByteCount;
+// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | 0x20 | (BYTE)(SectByteCount/0x0100);
+// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate )
+// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK);
+// else
+// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK);
+//
+// _Hw_D_EccRdReset();
+// _Hw_D_EccRdStart();
+//
+// SM_CMD_CTRL1 = SM_CMD_PAGPRGM_TRUE;
+// SM_CMD_CTRL1 = (SM_CMD_PAGPRGM_TRUE | SM_CMD_START_BIT);
+//
+// SectByteCount = 0x1ff;
+// //SM_WriteDataWithDMA(fdoExt, buf, SectByteCount);
+// //_WriteRedt_D_SsfdcBuf(redundant);
+// len = 0x1000 - ((WORD)(buf) & 0x0FFF);
+// if (len < 0x200)
+// {
+// SM_WriteDataWithDMA(fdoExt, buf, len-1);
+// SM_WriteDataWithDMA(fdoExt, buf+len, SectByteCount-len);
+// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len);
+// }
+// else
+// SM_WriteDataWithDMA(fdoExt, buf, SectByteCount);
+//
+// //T1 = (ULONGLONG)buf & 0xFFFFFFFFFFFFF000;
+// //T2 = ((ULONGLONG)buf + 0x1FF) & 0xFFFFFFFFFFFFF000;
+// //if (T1 != T2)
+// // ENE_Print("Ssfdc_D_WriteSect_DMA !!! buf = %p, T1 = %p, T2 = %p\n", buf, T1, T2);
+// //if (T2-T1)
+// //{
+// // l1 = (WORD)(T2 - (ULONGLONG)buf);
+// // SM_WriteDataWithDMA(fdoExt, buf, l1-1);
+// // SM_WriteDataWithDMA(fdoExt, (PBYTE)T2, SectByteCount-l1);
+// //}
+// //else
+// // SM_WriteDataWithDMA(fdoExt, buf, SectByteCount);
+//
+// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate )
+// {
+// _WriteRedt_D_SsfdcBuf(redundant);
+// }
+// else
+// {
+// memcpy(Buffer, redundant, 0x10);
+// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[0]);
+// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[1]);
+// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[2]);
+// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[3]);
+// }
+//
+// while ( _Hw_D_ChkCardIn() )
+// {
+// if ((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10))
+// {
+// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10);
+// break;
+// }
+// }
+// _Hw_D_EccRdStop();
+// _Hw_D_SetRdStandby();
+//
+// _Set_D_SsfdcWrStandby();
+// _Set_D_SsfdcRdStandby();
+// if (!_Hw_D_ChkCardIn())
+// return(ERROR);
+//
+// return(SUCCESS);
+//}
+//
+////----- Ssfdc_D_WriteSect_PIO() --------------------------------------------
+//int Ssfdc_D_WriteSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+//{
+// _Calc_D_ECCdata(buf);
+// _Set_D_SsfdcWrCmd(WRDATA);
+// _Set_D_SsfdcWrAddr(EVEN);
+// _Start_D_SsfdcWrHwECC();
+//
+// _Write_D_SsfdcBuf(buf);
+//
+// _Load_D_SsfdcWrHwECC(EVEN);
+// _Set_D_ECCdata(EVEN,redundant);
+//
+// _WriteRedt_D_SsfdcBuf(redundant);
+//
+// _Set_D_SsfdcWrCmd(WRITE);
+//
+// if (_Check_D_SsfdcBusy(BUSY_PROG))
+// { _Reset_D_SsfdcErr(); return(ERROR); }
+//
+// _Set_D_SsfdcWrStandby();
+// _Set_D_SsfdcRdStandby();
+// return(SUCCESS);
+//}
+*/
+//----- Ssfdc_D_WriteSectForCopy() -------------------------------------
+int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ //NTSTATUS ntStatus;
+ WORD addr;
+
+ //printk("SMILSUB --- Ssfdc_D_WriteSectForCopy\n");
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Write sect data
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x00;
+ bcb->CDB[0] = 0xF0;
+ bcb->CDB[1] = 0x04;
+ bcb->CDB[7] = (BYTE)addr;
+ bcb->CDB[6] = (BYTE)(addr/0x0100);
+ bcb->CDB[5] = Media.Zone/2;
+ bcb->CDB[8] = *(redundant+REDT_ADDR1H);;
+ bcb->CDB[9] = *(redundant+REDT_ADDR1L);;
+
+ result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+// 6250 CMD 5
+//----- Ssfdc_D_EraseBlock() -------------------------------------------
+int Ssfdc_D_EraseBlock(struct us_data *us)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ WORD addr;
+
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr=addr*(WORD)Ssfdc.MaxSectors;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x200;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF2;
+ bcb->CDB[1] = 0x06;
+ bcb->CDB[7] = (BYTE)addr;
+ bcb->CDB[6] = (BYTE)(addr/0x0100);
+ bcb->CDB[5] = Media.Zone/2;
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+// 6250 CMD 2
+//----- Ssfdc_D_ReadRedtData() -----------------------------------------
+int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ WORD addr;
+ BYTE *buf;
+
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x10;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF1;
+ bcb->CDB[1] = 0x03;
+ bcb->CDB[4] = (BYTE)addr;
+ bcb->CDB[3] = (BYTE)(addr/0x0100);
+ bcb->CDB[2] = Media.Zone/2;
+ bcb->CDB[8] = 0;
+ bcb->CDB[9] = 1;
+
+ buf = kmalloc(0x10, GFP_KERNEL);
+ //result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
+ result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
+ memcpy(redundant, buf, 0x10);
+ kfree(buf);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+// 6250 CMD 4
+//----- Ssfdc_D_WriteRedtData() ----------------------------------------
+int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result;
+ //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ //NTSTATUS ntStatus;
+ WORD addr;
+
+ result = ENE_LoadBinCode(us, SM_RW_PATTERN);
+ if (result != USB_STOR_XFER_GOOD)
+ {
+ printk("Load SM RW Code Fail !!\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ memset(bcb, 0, sizeof(bcb));
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = 0x10;
+ bcb->Flags = 0x80;
+ bcb->CDB[0] = 0xF2;
+ bcb->CDB[1] = 0x05;
+ bcb->CDB[7] = (BYTE)addr;
+ bcb->CDB[6] = (BYTE)(addr/0x0100);
+ bcb->CDB[5] = Media.Zone/2;
+ bcb->CDB[8] = *(redundant+REDT_ADDR1H);
+ bcb->CDB[9] = *(redundant+REDT_ADDR1L);
+
+ result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- Ssfdc_D_CheckStatus() ------------------------------------------
+int Ssfdc_D_CheckStatus(void)
+{
+ // Driver ¤£°µ
+ return(SUCCESS);
+ //_Set_D_SsfdcRdCmd(RDSTATUS);
+ //
+ //if (_Check_D_SsfdcStatus())
+ //{ _Set_D_SsfdcRdStandby(); return(ERROR); }
+ //
+ //_Set_D_SsfdcRdStandby();
+ //return(SUCCESS);
+}
+/*
+////NAND Memory (SmartMedia) Control Subroutine for Read Data
+////----- _Set_D_SsfdcRdCmd() --------------------------------------------
+//void _Set_D_SsfdcRdCmd(BYTE cmd)
+//{
+// _Hw_D_SetRdCmd();
+// _Hw_D_OutData(cmd);
+// _Hw_D_SetRdData();
+//}
+//
+////----- _Set_D_SsfdcRdAddr() -------------------------------------------
+//void _Set_D_SsfdcRdAddr(BYTE add)
+//{
+// WORD addr;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+//
+// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page
+// // addr=addr*2+(WORD)add;
+//
+// _Hw_D_SetRdAddr();
+// _Hw_D_OutData(0x00);
+// _Hw_D_OutData((BYTE)addr);
+// _Hw_D_OutData((BYTE)(addr/0x0100));
+//
+// if ((Ssfdc.Attribute &MADC)==AD4CYC)
+// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch
+//
+// _Hw_D_SetRdData();
+//}
+//
+////----- _Set_D_SsfdcRdChip() -------------------------------------------
+//void _Set_D_SsfdcRdChip(void)
+//{
+// _Hw_D_SetRdAddr();
+// _Hw_D_OutData(0x00);
+// _Hw_D_SetRdData();
+//}
+//
+////----- _Set_D_SsfdcRdStandby() ----------------------------------------
+//void _Set_D_SsfdcRdStandby(void)
+//{
+// _Hw_D_SetRdStandby();
+//}
+//
+////----- _Start_D_SsfdcRdHwECC() ----------------------------------------
+//void _Start_D_SsfdcRdHwECC(void)
+//{
+//#ifdef HW_ECC_SUPPORTED
+// _Hw_D_EccRdReset();
+// _Hw_D_InData();
+// _Hw_D_EccRdStart();
+//#endif
+//}
+//
+////----- _Stop_D_SsfdcRdHwECC() -----------------------------------------
+//void _Stop_D_SsfdcRdHwECC(void)
+//{
+//#ifdef HW_ECC_SUPPORTED
+// _Hw_D_EccRdStop();
+//#endif
+//}
+//
+////----- _Load_D_SsfdcRdHwECC() -----------------------------------------
+//void _Load_D_SsfdcRdHwECC(BYTE add)
+//{
+//#ifdef HW_ECC_SUPPORTED
+// _Hw_D_EccRdRead();
+// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256))
+// {
+// EccBuf[0]=_Hw_D_InData();
+// EccBuf[1]=_Hw_D_InData();
+// EccBuf[2]=_Hw_D_InData();
+// }
+//
+// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256))
+// {
+// EccBuf[3]=_Hw_D_InData();
+// EccBuf[4]=_Hw_D_InData();
+// EccBuf[5]=_Hw_D_InData();
+// }
+//
+// _Hw_D_EccRdStop();
+//#endif
+//}
+//
+////NAND Memory (SmartMedia) Control Subroutine for Write Data
+//
+////----- _Set_D_SsfdcWrCmd() -----------------------------------------
+//void _Set_D_SsfdcWrCmd(BYTE cmd)
+//{
+// _Hw_D_SetWrCmd();
+// _Hw_D_OutData(cmd);
+// _Hw_D_SetWrData();
+//}
+//
+////----- _Set_D_SsfdcWrAddr() -----------------------------------------
+//void _Set_D_SsfdcWrAddr(BYTE add)
+//{
+// WORD addr;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+//
+// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page
+// // addr=addr*2+(WORD)add;
+//
+// _Hw_D_SetWrAddr();
+// _Hw_D_OutData(0x00);
+// _Hw_D_OutData((BYTE)addr);
+// _Hw_D_OutData((BYTE)(addr/0x0100));
+//
+// if ((Ssfdc.Attribute &MADC)==AD4CYC)
+// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch
+//
+// _Hw_D_SetWrData();
+//}
+//
+////----- _Set_D_SsfdcWrBlock() -----------------------------------------
+//void _Set_D_SsfdcWrBlock(void)
+//{
+// WORD addr;
+// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
+// ADDRESS_T bb = (ADDRESS_T) &Media;
+//
+// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+// addr=addr*(WORD)Ssfdc.MaxSectors;
+//
+// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page
+// // addr=addr*2;
+//
+// _Hw_D_SetWrAddr();
+// _Hw_D_OutData((BYTE)addr);
+// _Hw_D_OutData((BYTE)(addr/0x0100));
+//
+// if ((Ssfdc.Attribute &MADC)==AD4CYC)
+// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch
+//
+// _Hw_D_SetWrData();
+//}
+//
+////----- _Set_D_SsfdcWrStandby() -----------------------------------------
+//void _Set_D_SsfdcWrStandby(void)
+//{
+// _Hw_D_SetWrStandby();
+//}
+//
+////----- _Start_D_SsfdcWrHwECC() -----------------------------------------
+//void _Start_D_SsfdcWrHwECC(void)
+//{
+//#ifdef HW_ECC_SUPPORTED
+// _Hw_D_EccWrReset();
+// _Hw_D_InData();
+// _Hw_D_EccWrStart();
+//#endif
+//}
+//
+////----- _Load_D_SsfdcWrHwECC() -----------------------------------------
+//void _Load_D_SsfdcWrHwECC(BYTE add)
+//{
+//#ifdef HW_ECC_SUPPORTED
+// _Hw_D_EccWrRead();
+// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256))
+// {
+// EccBuf[0]=_Hw_D_InData();
+// EccBuf[1]=_Hw_D_InData();
+// EccBuf[2]=_Hw_D_InData();
+// }
+//
+// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256))
+// {
+// EccBuf[3]=_Hw_D_InData();
+// EccBuf[4]=_Hw_D_InData();
+// EccBuf[5]=_Hw_D_InData();
+// }
+//
+// _Hw_D_EccWrStop();
+//#endif
+//}
+//
+////NAND Memory (SmartMedia) Control Subroutine
+////----- _Check_D_SsfdcBusy() -------------------------------------------
+//int _Check_D_SsfdcBusy(WORD time)
+//{
+// WORD count = 0;
+//
+// do {
+// if (!_Hw_D_ChkBusy())
+// return(SUCCESS);
+// EDelay(100);
+// count++;
+// } while (count<=time);
+//
+// return(ERROR);
+//}
+//
+////----- _Check_D_SsfdcStatus() -----------------------------------------
+//int _Check_D_SsfdcStatus(void)
+//{
+// if (_Hw_D_InData() & WR_FAIL)
+// return(ERROR);
+//
+// return(SUCCESS);
+//}
+//
+//// For 712
+////----- _Reset_D_SsfdcErr() -----------------------------------------
+//void _Reset_D_SsfdcErr(void)
+//{
+// WORD count = 0;
+//
+// _Hw_D_SetRdCmd();
+// _Hw_D_OutData(RST_CHIP);
+// _Hw_D_SetRdData();
+//
+// do {
+// if (!_Hw_D_ChkBusy())
+// break;
+// EDelay(100);
+// count++;
+// } while (count<=BUSY_RESET);
+//
+// _Hw_D_SetRdStandby();
+//}
+//
+////NAND Memory (SmartMedia) Buffer Data Xfer Subroutine
+////----- SM_ReadDataWithDMA() -----------------------------------------
+//void SM_ReadDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount)
+//{
+// PHYSICAL_ADDRESS Addr;
+// LARGE_INTEGER ptimeout ;
+//
+// KeClearEvent(&fdoExt->SM_DMADoneEvent);
+//
+// Addr = MmGetPhysicalAddress(databuf);
+//
+// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart);
+// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0);
+// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount);
+//
+// while ( _Hw_D_ChkCardIn() )
+// {
+// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x80))
+// break;
+// }
+// if (!_Hw_D_ChkCardIn()) return;
+// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x01);
+//
+// ptimeout.QuadPart = 2000 * (-10000); // 2 sec
+// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout);
+// _Hw_D_SetDMAIntMask();
+//}
+//
+////----- SM_WriteDataWithDMA() -----------------------------------------
+//void SM_WriteDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount)
+//{
+// PHYSICAL_ADDRESS Addr;
+// LARGE_INTEGER ptimeout ;
+//
+// KeClearEvent(&fdoExt->SM_DMADoneEvent);
+//
+// Addr = MmGetPhysicalAddress(databuf);
+//
+// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart);
+// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 2);
+// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount);
+//
+// while ( _Hw_D_ChkCardIn() )
+// {
+// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x40))
+// break;
+// }
+// if (!_Hw_D_ChkCardIn()) return;
+// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x03);
+//
+// ptimeout.QuadPart = 2000 * (-10000); // 2 sec
+// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout);
+// _Hw_D_SetDMAIntMask();
+//}
+//
+////----- _Read_D_SsfdcBuf() -----------------------------------------
+//void _Read_D_SsfdcBuf(BYTE *databuf)
+//{
+// int i;
+//
+// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++)
+// for(i=0; i<0x200; i++)
+// *databuf++ =_Hw_D_InData();
+//}
+//
+////----- _Write_D_SsfdcBuf() -----------------------------------------
+//void _Write_D_SsfdcBuf(BYTE *databuf)
+//{
+// int i;
+//
+// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++)
+// for(i=0; i<0x200; i++)
+// _Hw_D_OutData(*databuf++);
+//}
+//
+////----- _Read_D_SsfdcByte() -----------------------------------------
+//void _Read_D_SsfdcByte(BYTE *databuf)
+//{
+// *databuf=(BYTE)_Hw_D_InData();
+//}
+//
+////----- _ReadRedt_D_SsfdcBuf() -----------------------------------------
+//void _ReadRedt_D_SsfdcBuf(BYTE *redundant)
+//{
+// char i;
+//
+// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++)
+// for(i=0; i<0x10; i++)
+// redundant[i] =_Hw_D_InData();
+//}
+//
+////----- _WriteRedt_D_SsfdcBuf() -----------------------------------------
+//void _WriteRedt_D_SsfdcBuf(BYTE *redundant)
+//{
+// char i;
+//
+// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++)
+// for(i=0; i<0x10; i++)
+// _Hw_D_OutData(*redundant++);
+//}
+*/
+//SmartMedia ID Code Check & Mode Set Subroutine
+//----- Set_D_SsfdcModel() ---------------------------------------------
+int Set_D_SsfdcModel(BYTE dcode)
+{
+ switch (_Check_D_DevCode(dcode)) {
+ case SSFDC1MB:
+ Ssfdc.Model = SSFDC1MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
+ Ssfdc.MaxZones = 1;
+ Ssfdc.MaxBlocks = 256;
+ Ssfdc.MaxLogBlocks = 250;
+ Ssfdc.MaxSectors = 8;
+ break;
+ case SSFDC2MB:
+ Ssfdc.Model = SSFDC2MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
+ Ssfdc.MaxZones = 1;
+ Ssfdc.MaxBlocks = 512;
+ Ssfdc.MaxLogBlocks = 500;
+ Ssfdc.MaxSectors = 8;
+ break;
+ case SSFDC4MB:
+ Ssfdc.Model = SSFDC4MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
+ Ssfdc.MaxZones = 1;
+ Ssfdc.MaxBlocks = 512;
+ Ssfdc.MaxLogBlocks = 500;
+ Ssfdc.MaxSectors = 16;
+ break;
+ case SSFDC8MB:
+ Ssfdc.Model = SSFDC8MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
+ Ssfdc.MaxZones = 1;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 16;
+ break;
+ case SSFDC16MB:
+ Ssfdc.Model = SSFDC16MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 1;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC32MB:
+ Ssfdc.Model = SSFDC32MB;
+ Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 2;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC64MB:
+ Ssfdc.Model = SSFDC64MB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 4;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC128MB:
+ Ssfdc.Model = SSFDC128MB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 8;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC256MB:
+ Ssfdc.Model = SSFDC256MB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 16;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC512MB:
+ Ssfdc.Model = SSFDC512MB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 32;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC1GB:
+ Ssfdc.Model = SSFDC1GB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 64;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ case SSFDC2GB:
+ Ssfdc.Model = SSFDC2GB;
+ Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
+ Ssfdc.MaxZones = 128;
+ Ssfdc.MaxBlocks = 1024;
+ Ssfdc.MaxLogBlocks = 1000;
+ Ssfdc.MaxSectors = 32;
+ break;
+ default:
+ Ssfdc.Model = NOSSFDC;
+ return(ERROR);
+ }
+
+ return(SUCCESS);
+}
+
+//----- _Check_D_DevCode() ---------------------------------------------
+BYTE _Check_D_DevCode(BYTE dcode)
+{
+ switch(dcode){
+ case 0x6E:
+ case 0xE8:
+ case 0xEC: return(SSFDC1MB); // 8Mbit (1M) NAND
+ case 0x64:
+ case 0xEA: return(SSFDC2MB); // 16Mbit (2M) NAND
+ case 0x6B:
+ case 0xE3:
+ case 0xE5: return(SSFDC4MB); // 32Mbit (4M) NAND
+ case 0xE6: return(SSFDC8MB); // 64Mbit (8M) NAND
+ case 0x73: return(SSFDC16MB); // 128Mbit (16M)NAND
+ case 0x75: return(SSFDC32MB); // 256Mbit (32M)NAND
+ case 0x76: return(SSFDC64MB); // 512Mbit (64M)NAND
+ case 0x79: return(SSFDC128MB); // 1Gbit(128M)NAND
+ case 0x71: return(SSFDC256MB);
+ case 0xDC: return(SSFDC512MB);
+ case 0xD3: return(SSFDC1GB);
+ case 0xD5: return(SSFDC2GB);
+ default: return(NOSSFDC);
+ }
+}
+/*
+////SmartMedia Power Controll Subroutine
+////----- Cnt_D_Reset() ----------------------------------------------
+//void Cnt_D_Reset(void)
+//{
+// _Hw_D_LedOff();
+// _Hw_D_SetRdStandby();
+// _Hw_D_VccOff();
+//}
+//
+////----- Cnt_D_PowerOn() ----------------------------------------------
+//int Cnt_D_PowerOn(void)
+//{
+// // No support 5V.
+// _Hw_D_EnableVcc3VOn(); // Set SM_REG_CTRL_5 Reg. to 3V
+// _Hw_D_VccOn();
+// _Hw_D_SetRdStandby();
+// _Wait_D_Timer(TIME_PON);
+//
+// if (_Hw_D_ChkPower())
+// {
+// _Hw_D_EnableOB(); // Set SM_REG_CTRL_5 Reg. to 0x83
+// return(SUCCESS);
+// }
+//
+// _Hw_D_SetVccOff();
+// return(ERROR);
+//}
+//
+////----- Cnt_D_PowerOff() ----------------------------------------------
+//void Cnt_D_PowerOff(void)
+//{
+// _Hw_D_SetRdStandby();
+// _Hw_D_SetVccOff();
+// _Hw_D_VccOff();
+//}
+//
+////----- Cnt_D_LedOn() ----------------------------------------------
+//void Cnt_D_LedOn(void)
+//{
+// _Hw_D_LedOn();
+//}
+//
+////----- Cnt_D_LedOff() ----------------------------------------------
+//void Cnt_D_LedOff(void)
+//{
+// _Hw_D_LedOff();
+//}
+//
+////----- Check_D_CntPower() ----------------------------------------------
+//int Check_D_CntPower(void)
+//{
+// if (_Hw_D_ChkPower())
+// return(SUCCESS); // Power On
+//
+// return(ERROR); // Power Off
+//}
+//
+////----- Check_D_CardExist() ----------------------------------------------
+//int Check_D_CardExist(void)
+//{
+// char i,j,k;
+//
+// if (!_Hw_D_ChkStatus()) // Not Status Change
+// if (_Hw_D_ChkCardIn())
+// return(SUCCESS); // Card exist in Slot
+//
+// for(i=0,j=0,k=0; i<16; i++) {
+// if (_Hw_D_ChkCardIn()) // Status Change
+// {
+// j++; k=0;
+// }
+// else
+// {
+// j=0; k++;
+// }
+//
+// if (j>3)
+// return(SUCCESS); // Card exist in Slot
+// if (k>3)
+// return(ERROR); // NO Card exist in Slot
+//
+// _Wait_D_Timer(TIME_CDCHK);
+// }
+//
+// return(ERROR);
+//}
+//
+////----- Check_D_CardStsChg() ----------------------------------------------
+//int Check_D_CardStsChg(void)
+//{
+// if (_Hw_D_ChkStatus())
+// return(ERROR); // Status Change
+//
+// return(SUCCESS); // Not Status Change
+//}
+//
+////----- Check_D_SsfdcWP() ----------------------------------------------
+//int Check_D_SsfdcWP(void)
+//{ // ERROR: WP, SUCCESS: Not WP
+// char i;
+//
+// for(i=0; i<8; i++) {
+// if (_Hw_D_ChkWP())
+// return(ERROR);
+// _Wait_D_Timer(TIME_WPCHK);
+// }
+//
+// return(SUCCESS);
+//}
+//
+*/
+//SmartMedia ECC Controll Subroutine
+//----- Check_D_ReadError() ----------------------------------------------
+int Check_D_ReadError(BYTE *redundant)
+{
+ // Driver ¤£°µ ECC Check
+ return(SUCCESS);
+ if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3))
+ if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3))
+ return(SUCCESS);
+
+ return(ERROR);
+}
+
+//----- Check_D_Correct() ----------------------------------------------
+int Check_D_Correct(BYTE *buf,BYTE *redundant)
+{
+ // Driver ¤£°µ ECC Check
+ return(SUCCESS);
+ if (StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3))
+ if (_Correct_D_SwECC(buf,redundant+0x0D,EccBuf))
+ return(ERROR);
+
+ buf+=0x100;
+ if (StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3))
+ if (_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03))
+ return(ERROR);
+
+ return(SUCCESS);
+}
+
+//----- Check_D_CISdata() ----------------------------------------------
+int Check_D_CISdata(BYTE *buf, BYTE *redundant)
+{
+ BYTE cis[]={0x01,0x03,0xD9,0x01,0xFF,0x18,0x02,0xDF,0x01,0x20};
+
+ if (!IsSSFDCCompliance && !IsXDCompliance)
+ return(SUCCESS); // ¥Ø«e¬°±j¨î SUCCESS [Arnold 02-08-23] SSFDC ´ú¸Õ, ¤£¯à±j¨î SUCCESS
+
+ if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3))
+ return(StringCmp((char *)buf,(char *)cis,10));
+
+ if (!_Correct_D_SwECC(buf,redundant+0x0D,EccBuf))
+ return(StringCmp((char *)buf,(char *)cis,10));
+
+ buf+=0x100;
+ if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3))
+ return(StringCmp((char *)buf,(char *)cis,10));
+
+ if (!_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03))
+ return(StringCmp((char *)buf,(char *)cis,10));
+
+ return(ERROR);
+}
+
+//----- Set_D_RightECC() ----------------------------------------------
+void Set_D_RightECC(BYTE *redundant)
+{
+ // Driver ¤£°µ ECC Check
+ return;
+ //StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3);
+ //StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3);
+}
+/*
+////----- _Calc_D_ECCdata() ----------------------------------------------
+//void _Calc_D_ECCdata(BYTE *buf)
+//{
+//#ifdef HW_ECC_SUPPORTED
+//#else
+// _Calculate_D_SwECC(buf,EccBuf);
+// buf+=0x0100;
+// _Calculate_D_SwECC(buf,EccBuf+0x03);
+//#endif
+//}
+//
+////----- _Set_D_ECCdata() ----------------------------------------------
+//void _Set_D_ECCdata(BYTE add,BYTE *redundant)
+//{
+// //if (add==EVEN && (Ssfdc.Attribute &MPS)==PS256)
+// // return;
+//
+// // for 256byte/page
+// StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3);
+// StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3);
+//}
+*/
+//Common Subroutine
+char Bit_D_Count(BYTE cdata)
+{
+ WORD bitcount=0;
+
+ while(cdata) {
+ bitcount+=(WORD)(cdata &0x01);
+ cdata /=2;
+ }
+
+ return((char)bitcount);
+}
+
+//-----
+char Bit_D_CountWord(WORD cdata)
+{
+ WORD bitcount=0;
+
+ while(cdata) {
+ bitcount+=(cdata &0x01);
+ cdata /=2;
+ }
+
+ return((char)bitcount);
+}
+
+void StringCopy(char *stringA, char *stringB, int count)
+{
+ int i;
+
+ for(i=0; i<count; i++)
+ *stringA++ = *stringB++;
+}
+
+//-----
+int StringCmp(char *stringA, char *stringB, int count)
+{
+ int i;
+
+ for (i=0;i<count;i++)
+ if (*stringA++ != *stringB++)
+ return(ERROR);
+
+ return(SUCCESS);
+}
+/*
+//----- SM_ReadBlock() ---------------------------------------------
+int SM_ReadBlock(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant)
+{
+ PBULK_CBW pBulkCbw = fdoExt->pBulkCbw;
+ NTSTATUS ntStatus;
+ WORD addr;
+
+ ENE_LoadBinCode(fdoExt, SM_RW_PATTERN);
+
+ addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
+ addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
+
+ // Read sect data
+ RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW));
+ pBulkCbw->dCBWSignature = CBW_SIGNTURE;
+ pBulkCbw->bCBWLun = CBW_LUN;
+ pBulkCbw->dCBWDataTransferLength = 0x200;
+ pBulkCbw->bmCBWFlags = 0x80;
+ pBulkCbw->CBWCb[0] = 0xF1;
+ pBulkCbw->CBWCb[1] = 0x02;
+ pBulkCbw->CBWCb[4] = (BYTE)addr;
+ pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100);
+ pBulkCbw->CBWCb[2] = Media.Zone/2;
+
+ ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, buf);
+
+ if (!NT_SUCCESS(ntStatus))
+ return(ERROR);
+
+ // Read redundant
+ RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW));
+ pBulkCbw->dCBWSignature = CBW_SIGNTURE;
+ pBulkCbw->bCBWLun = CBW_LUN;
+ pBulkCbw->dCBWDataTransferLength = 0x10;
+ pBulkCbw->bmCBWFlags = 0x80;
+ pBulkCbw->CBWCb[0] = 0xF1;
+ pBulkCbw->CBWCb[1] = 0x03;
+ pBulkCbw->CBWCb[4] = (BYTE)addr;
+ pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100);
+ pBulkCbw->CBWCb[2] = Media.Zone/2;
+ pBulkCbw->CBWCb[5] = 0;
+ pBulkCbw->CBWCb[6] = 1;
+
+ ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, redundant);
+
+ if (!NT_SUCCESS(ntStatus))
+ return(ERROR);
+
+ return(SUCCESS);
+}*/
diff --git a/drivers/staging/keucr/smscsi.c b/drivers/staging/keucr/smscsi.c
new file mode 100644
index 000000000000..43e32c6ded90
--- /dev/null
+++ b/drivers/staging/keucr/smscsi.c
@@ -0,0 +1,189 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+//#include "smcommon.h"
+#include "smil.h"
+
+int SM_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Inquiry (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Mode_Sense (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Start_Stop (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Read_Capacity (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Read (struct us_data *us, struct scsi_cmnd *srb);
+int SM_SCSI_Write (struct us_data *us, struct scsi_cmnd *srb);
+
+extern struct SSFDCTYPE Ssfdc;
+extern struct ADDRESS Media;
+extern PBYTE SMHostAddr;
+extern DWORD ErrXDCode;
+
+//----- SM_SCSIIrp() --------------------------------------------------
+int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
+{
+ int result;
+
+ us->SrbStatus = SS_SUCCESS;
+ switch (srb->cmnd[0])
+ {
+ case TEST_UNIT_READY : result = SM_SCSI_Test_Unit_Ready (us, srb); break; //0x00
+ case INQUIRY : result = SM_SCSI_Inquiry (us, srb); break; //0x12
+ case MODE_SENSE : result = SM_SCSI_Mode_Sense (us, srb); break; //0x1A
+ case READ_CAPACITY : result = SM_SCSI_Read_Capacity (us, srb); break; //0x25
+ case READ_10 : result = SM_SCSI_Read (us, srb); break; //0x28
+ case WRITE_10 : result = SM_SCSI_Write (us, srb); break; //0x2A
+
+ default:
+ us->SrbStatus = SS_ILLEGAL_REQUEST;
+ result = USB_STOR_TRANSPORT_FAILED;
+ break;
+ }
+ return result;
+}
+
+//----- SM_SCSI_Test_Unit_Ready() --------------------------------------------------
+int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("SM_SCSI_Test_Unit_Ready\n");
+ if (us->SM_Status.Insert && us->SM_Status.Ready)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ {
+ ENE_SMInit(us);
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SM_SCSI_Inquiry() --------------------------------------------------
+int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //printk("SM_SCSI_Inquiry\n");
+ BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
+
+ usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+
+//----- SM_SCSI_Mode_Sense() --------------------------------------------------
+int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
+{
+ BYTE mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+ BYTE mediaWP[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+
+ if (us->SM_Status.WtP)
+ usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
+ else
+ usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF);
+
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SM_SCSI_Read_Capacity() --------------------------------------------------
+int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
+{
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
+ DWORD bl_num;
+ WORD bl_len;
+ BYTE buf[8];
+
+ printk("SM_SCSI_Read_Capacity\n");
+
+ bl_len = 0x200;
+ bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1;
+ //printk("MaxLogBlocks = %x\n", Ssfdc.MaxLogBlocks);
+ //printk("MaxSectors = %x\n", Ssfdc.MaxSectors);
+ //printk("MaxZones = %x\n", Ssfdc.MaxZones);
+ //printk("bl_num = %x\n", bl_num);
+
+ us->bl_num = bl_num;
+ printk("bl_len = %x\n", bl_len);
+ printk("bl_num = %x\n", bl_num);
+
+ //srb->request_bufflen = 8;
+ buf[0] = (bl_num>>24) & 0xff;
+ buf[1] = (bl_num>>16) & 0xff;
+ buf[2] = (bl_num>> 8) & 0xff;
+ buf[3] = (bl_num>> 0) & 0xff;
+ buf[4] = (bl_len>>24) & 0xff;
+ buf[5] = (bl_len>>16) & 0xff;
+ buf[6] = (bl_len>> 8) & 0xff;
+ buf[7] = (bl_len>> 0) & 0xff;
+
+ usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);
+ //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SM_SCSI_Read() --------------------------------------------------
+int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result=0;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD blenByte = blen * 0x200;
+ void *buf;
+
+ //printk("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg);
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ buf = kmalloc(blenByte, GFP_KERNEL);
+ result = Media_D_ReadSector(us, bn, blen, buf);
+ usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF);
+ kfree(buf);
+
+ if (!result)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+//----- SM_SCSI_Write() --------------------------------------------------
+int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
+{
+ //struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ int result=0;
+ PBYTE Cdb = srb->cmnd;
+ DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
+ ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
+ WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff);
+ DWORD blenByte = blen * 0x200;
+ void *buf;
+
+ //printk("SCSIOP_Write --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg);
+
+ if (bn > us->bl_num)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ buf = kmalloc(blenByte, GFP_KERNEL);
+ usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF);
+ result = Media_D_CopySector(us, bn, blen, buf);
+ kfree(buf);
+
+ if (!result)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ return USB_STOR_TRANSPORT_ERROR;
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c
new file mode 100644
index 000000000000..7215429759bc
--- /dev/null
+++ b/drivers/staging/keucr/transport.c
@@ -0,0 +1,788 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+
+/***********************************************************************
+ * Data transfer routines
+ ***********************************************************************/
+//----- usb_stor_blocking_completion() ---------------------
+static void usb_stor_blocking_completion(struct urb *urb)
+{
+ struct completion *urb_done_ptr = urb->context;
+
+ //printk("transport --- usb_stor_blocking_completion\n");
+ complete(urb_done_ptr);
+}
+
+//----- usb_stor_msg_common() ---------------------
+static int usb_stor_msg_common(struct us_data *us, int timeout)
+{
+ struct completion urb_done;
+ long timeleft;
+ int status;
+
+ //printk("transport --- usb_stor_msg_common\n");
+ if (test_bit(US_FLIDX_ABORTING, &us->dflags))
+ return -EIO;
+
+ init_completion(&urb_done);
+
+ us->current_urb->context = &urb_done;
+ us->current_urb->actual_length = 0;
+ us->current_urb->error_count = 0;
+ us->current_urb->status = 0;
+
+// us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
+ if (us->current_urb->transfer_buffer == us->iobuf)
+ us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ us->current_urb->transfer_dma = us->iobuf_dma;
+ us->current_urb->setup_dma = us->cr_dma;
+
+ status = usb_submit_urb(us->current_urb, GFP_NOIO);
+ if (status)
+ return status;
+
+ set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
+
+ if (test_bit(US_FLIDX_ABORTING, &us->dflags))
+ {
+ if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags))
+ {
+ //printk("-- cancelling URB\n");
+ usb_unlink_urb(us->current_urb);
+ }
+ }
+
+ timeleft = wait_for_completion_interruptible_timeout(&urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
+ clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
+
+ if (timeleft <= 0)
+ {
+ //printk("%s -- cancelling URB\n", timeleft == 0 ? "Timeout" : "Signal");
+ usb_kill_urb(us->current_urb);
+ }
+
+ return us->current_urb->status;
+}
+
+//----- usb_stor_control_msg() ---------------------
+int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
+ u8 request, u8 requesttype, u16 value, u16 index,
+ void *data, u16 size, int timeout)
+{
+ int status;
+
+ //printk("transport --- usb_stor_control_msg\n");
+
+ /* fill in the devrequest structure */
+ us->cr->bRequestType = requesttype;
+ us->cr->bRequest = request;
+ us->cr->wValue = cpu_to_le16(value);
+ us->cr->wIndex = cpu_to_le16(index);
+ us->cr->wLength = cpu_to_le16(size);
+
+ /* fill and submit the URB */
+ usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
+ (unsigned char*) us->cr, data, size,
+ usb_stor_blocking_completion, NULL);
+ status = usb_stor_msg_common(us, timeout);
+
+ /* return the actual length of the data transferred if no error */
+ if (status == 0)
+ status = us->current_urb->actual_length;
+ return status;
+}
+
+//----- usb_stor_clear_halt() ---------------------
+int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
+{
+ int result;
+ int endp = usb_pipeendpoint(pipe);
+
+ //printk("transport --- usb_stor_clear_halt\n");
+ if (usb_pipein (pipe))
+ endp |= USB_DIR_IN;
+
+ result = usb_stor_control_msg(us, us->send_ctrl_pipe,
+ USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, endp,
+ NULL, 0, 3*HZ);
+
+ /* reset the endpoint toggle */
+ if (result >= 0)
+ //usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+ usb_reset_endpoint(us->pusb_dev, endp);
+
+ return result;
+}
+
+//----- interpret_urb_result() ---------------------
+static int interpret_urb_result(struct us_data *us, unsigned int pipe,
+ unsigned int length, int result, unsigned int partial)
+{
+ //printk("transport --- interpret_urb_result\n");
+ switch (result) {
+ /* no error code; did we send all the data? */
+ case 0:
+ if (partial != length)
+ {
+ //printk("-- short transfer\n");
+ return USB_STOR_XFER_SHORT;
+ }
+ //printk("-- transfer complete\n");
+ return USB_STOR_XFER_GOOD;
+ case -EPIPE:
+ if (usb_pipecontrol(pipe))
+ {
+ //printk("-- stall on control pipe\n");
+ return USB_STOR_XFER_STALLED;
+ }
+ //printk("clearing endpoint halt for pipe 0x%x\n", pipe);
+ if (usb_stor_clear_halt(us, pipe) < 0)
+ return USB_STOR_XFER_ERROR;
+ return USB_STOR_XFER_STALLED;
+ case -EOVERFLOW:
+ //printk("-- babble\n");
+ return USB_STOR_XFER_LONG;
+ case -ECONNRESET:
+ //printk("-- transfer cancelled\n");
+ return USB_STOR_XFER_ERROR;
+ case -EREMOTEIO:
+ //printk("-- short read transfer\n");
+ return USB_STOR_XFER_SHORT;
+ case -EIO:
+ //printk("-- abort or disconnect in progress\n");
+ return USB_STOR_XFER_ERROR;
+ default:
+ //printk("-- unknown error\n");
+ return USB_STOR_XFER_ERROR;
+ }
+}
+
+//----- usb_stor_bulk_transfer_buf() ---------------------
+int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
+ void *buf, unsigned int length, unsigned int *act_len)
+{
+ int result;
+
+ //printk("transport --- usb_stor_bulk_transfer_buf\n");
+
+ /* fill and submit the URB */
+ usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length, usb_stor_blocking_completion, NULL);
+ result = usb_stor_msg_common(us, 0);
+
+ /* store the actual length of the data transferred */
+ if (act_len)
+ *act_len = us->current_urb->actual_length;
+
+ return interpret_urb_result(us, pipe, length, result, us->current_urb->actual_length);
+}
+
+//----- usb_stor_bulk_transfer_sglist() ---------------------
+static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
+ struct scatterlist *sg, int num_sg, unsigned int length,
+ unsigned int *act_len)
+{
+ int result;
+
+ //printk("transport --- usb_stor_bulk_transfer_sglist\n");
+ if (test_bit(US_FLIDX_ABORTING, &us->dflags))
+ return USB_STOR_XFER_ERROR;
+
+ /* initialize the scatter-gather request block */
+ result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, GFP_NOIO);
+ if (result)
+ {
+ //printk("usb_sg_init returned %d\n", result);
+ return USB_STOR_XFER_ERROR;
+ }
+
+ /* since the block has been initialized successfully, it's now okay to cancel it */
+ set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
+
+ /* did an abort/disconnect occur during the submission? */
+ if (test_bit(US_FLIDX_ABORTING, &us->dflags))
+ {
+ /* cancel the request, if it hasn't been cancelled already */
+ if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags))
+ {
+ //printk("-- cancelling sg request\n");
+ usb_sg_cancel(&us->current_sg);
+ }
+ }
+
+ /* wait for the completion of the transfer */
+ usb_sg_wait(&us->current_sg);
+ clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
+
+ result = us->current_sg.status;
+ if (act_len)
+ *act_len = us->current_sg.bytes;
+
+ return interpret_urb_result(us, pipe, length, result, us->current_sg.bytes);
+}
+
+//----- usb_stor_bulk_srb() ---------------------
+int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, struct scsi_cmnd* srb)
+{
+ unsigned int partial;
+ int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
+ scsi_sg_count(srb), scsi_bufflen(srb),
+ &partial);
+
+ scsi_set_resid(srb, scsi_bufflen(srb) - partial);
+ return result;
+}
+
+//----- usb_stor_bulk_transfer_sg() ---------------------
+int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
+ void *buf, unsigned int length_left, int use_sg, int *residual)
+{
+ int result;
+ unsigned int partial;
+
+ //printk("transport --- usb_stor_bulk_transfer_sg\n");
+ /* are we scatter-gathering? */
+ if (use_sg)
+ {
+ /* use the usb core scatter-gather primitives */
+ result = usb_stor_bulk_transfer_sglist(us, pipe,
+ (struct scatterlist *) buf, use_sg,
+ length_left, &partial);
+ length_left -= partial;
+ }
+ else
+ {
+ /* no scatter-gather, just make the request */
+ result = usb_stor_bulk_transfer_buf(us, pipe, buf, length_left, &partial);
+ length_left -= partial;
+ }
+
+ /* store the residual and return the error code */
+ if (residual)
+ *residual = length_left;
+ return result;
+}
+
+/***********************************************************************
+ * Transport routines
+ ***********************************************************************/
+//----- usb_stor_invoke_transport() ---------------------
+void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+ int need_auto_sense;
+ int result;
+
+ //printk("transport --- usb_stor_invoke_transport\n");
+ usb_stor_print_cmd(srb);
+ /* send the command to the transport layer */
+ scsi_set_resid(srb, 0);
+ result = us->transport(srb, us); //usb_stor_Bulk_transport;
+
+ /* if the command gets aborted by the higher layers, we need to short-circuit all other processing */
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
+ {
+ //printk("-- command was aborted\n");
+ srb->result = DID_ABORT << 16;
+ goto Handle_Errors;
+ }
+
+ /* if there is a transport error, reset and don't auto-sense */
+ if (result == USB_STOR_TRANSPORT_ERROR)
+ {
+ //printk("-- transport indicates error, resetting\n");
+ srb->result = DID_ERROR << 16;
+ goto Handle_Errors;
+ }
+
+ /* if the transport provided its own sense data, don't auto-sense */
+ if (result == USB_STOR_TRANSPORT_NO_SENSE)
+ {
+ srb->result = SAM_STAT_CHECK_CONDITION;
+ return;
+ }
+
+ srb->result = SAM_STAT_GOOD;
+
+ /* Determine if we need to auto-sense */
+ need_auto_sense = 0;
+
+ if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) && srb->sc_data_direction != DMA_FROM_DEVICE)
+ {
+ //printk("-- CB transport device requiring auto-sense\n");
+ need_auto_sense = 1;
+ }
+
+ if (result == USB_STOR_TRANSPORT_FAILED)
+ {
+ //printk("-- transport indicates command failure\n");
+ need_auto_sense = 1;
+ }
+
+ /* Now, if we need to do the auto-sense, let's do it */
+ if (need_auto_sense)
+ {
+ int temp_result;
+ struct scsi_eh_save ses;
+
+ printk("Issuing auto-REQUEST_SENSE\n");
+
+ scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
+
+ /* we must do the protocol translation here */
+ if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI || us->subclass == US_SC_CYP_ATACB)
+ srb->cmd_len = 6;
+ else
+ srb->cmd_len = 12;
+
+ /* issue the auto-sense command */
+ scsi_set_resid(srb, 0);
+ temp_result = us->transport(us->srb, us);
+
+ /* let's clean up right away */
+ scsi_eh_restore_cmnd(srb, &ses);
+
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
+ {
+ //printk("-- auto-sense aborted\n");
+ srb->result = DID_ABORT << 16;
+ goto Handle_Errors;
+ }
+ if (temp_result != USB_STOR_TRANSPORT_GOOD)
+ {
+ //printk("-- auto-sense failure\n");
+ srb->result = DID_ERROR << 16;
+ if (!(us->fflags & US_FL_SCM_MULT_TARG))
+ goto Handle_Errors;
+ return;
+ }
+
+ /* set the result so the higher layers expect this data */
+ srb->result = SAM_STAT_CHECK_CONDITION;
+
+ if (result == USB_STOR_TRANSPORT_GOOD &&
+ (srb->sense_buffer[2] & 0xaf) == 0 &&
+ srb->sense_buffer[12] == 0 &&
+ srb->sense_buffer[13] == 0)
+ {
+ srb->result = SAM_STAT_GOOD;
+ srb->sense_buffer[0] = 0x0;
+ }
+ }
+
+ /* Did we transfer less than the minimum amount required? */
+ if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
+ srb->result = (DID_ERROR << 16);//v02 | (SUGGEST_RETRY << 24);
+
+ return;
+
+Handle_Errors:
+ scsi_lock(us_to_host(us));
+ set_bit(US_FLIDX_RESETTING, &us->dflags);
+ clear_bit(US_FLIDX_ABORTING, &us->dflags);
+ scsi_unlock(us_to_host(us));
+
+ mutex_unlock(&us->dev_mutex);
+ result = usb_stor_port_reset(us);
+ mutex_lock(&us->dev_mutex);
+
+ if (result < 0)
+ {
+ scsi_lock(us_to_host(us));
+ usb_stor_report_device_reset(us);
+ scsi_unlock(us_to_host(us));
+ us->transport_reset(us);
+ }
+ clear_bit(US_FLIDX_RESETTING, &us->dflags);
+}
+
+//----- ENE_stor_invoke_transport() ---------------------
+void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+ int result=0;
+
+ //printk("transport --- ENE_stor_invoke_transport\n");
+ usb_stor_print_cmd(srb);
+ /* send the command to the transport layer */
+ scsi_set_resid(srb, 0);
+ if ( !(us->SD_Status.Ready || us->MS_Status.Ready || us->SM_Status.Ready) )
+ result = ENE_InitMedia(us);
+
+ if (us->Power_IsResum == true) {
+ result = ENE_InitMedia(us);
+ us->Power_IsResum = false;
+ }
+
+ if (us->SD_Status.Ready) result = SD_SCSIIrp(us, srb);
+ if (us->MS_Status.Ready) result = MS_SCSIIrp(us, srb);
+ if (us->SM_Status.Ready) result = SM_SCSIIrp(us, srb);
+
+ /* if the command gets aborted by the higher layers, we need to short-circuit all other processing */
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
+ {
+ //printk("-- command was aborted\n");
+ srb->result = DID_ABORT << 16;
+ goto Handle_Errors;
+ }
+
+ /* if there is a transport error, reset and don't auto-sense */
+ if (result == USB_STOR_TRANSPORT_ERROR)
+ {
+ //printk("-- transport indicates error, resetting\n");
+ srb->result = DID_ERROR << 16;
+ goto Handle_Errors;
+ }
+
+ /* if the transport provided its own sense data, don't auto-sense */
+ if (result == USB_STOR_TRANSPORT_NO_SENSE)
+ {
+ srb->result = SAM_STAT_CHECK_CONDITION;
+ return;
+ }
+
+ srb->result = SAM_STAT_GOOD;
+ if (result == USB_STOR_TRANSPORT_FAILED)
+ {
+ //printk("-- transport indicates command failure\n");
+ //need_auto_sense = 1;
+ BuildSenseBuffer(srb, us->SrbStatus);
+ srb->result = SAM_STAT_CHECK_CONDITION;
+ }
+
+ /* Did we transfer less than the minimum amount required? */
+ if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
+ srb->result = (DID_ERROR << 16);//v02 | (SUGGEST_RETRY << 24);
+
+ return;
+
+Handle_Errors:
+ scsi_lock(us_to_host(us));
+ set_bit(US_FLIDX_RESETTING, &us->dflags);
+ clear_bit(US_FLIDX_ABORTING, &us->dflags);
+ scsi_unlock(us_to_host(us));
+
+ mutex_unlock(&us->dev_mutex);
+ result = usb_stor_port_reset(us);
+ mutex_lock(&us->dev_mutex);
+
+ if (result < 0)
+ {
+ scsi_lock(us_to_host(us));
+ usb_stor_report_device_reset(us);
+ scsi_unlock(us_to_host(us));
+ us->transport_reset(us);
+ }
+ clear_bit(US_FLIDX_RESETTING, &us->dflags);
+}
+
+//----- BuildSenseBuffer() -------------------------------------------
+void BuildSenseBuffer(struct scsi_cmnd *srb, int SrbStatus)
+{
+ BYTE *buf = srb->sense_buffer;
+ BYTE asc;
+
+ printk("transport --- BuildSenseBuffer\n");
+ switch (SrbStatus)
+ {
+ case SS_NOT_READY: asc = 0x3a; break; // sense key = 0x02
+ case SS_MEDIUM_ERR: asc = 0x0c; break; // sense key = 0x03
+ case SS_ILLEGAL_REQUEST: asc = 0x20; break; // sense key = 0x05
+ default: asc = 0x00; break; // ??
+ }
+
+ memset(buf, 0, 18);
+ buf[0x00] = 0xf0;
+ buf[0x02] = SrbStatus;
+ buf[0x07] = 0x0b;
+ buf[0x0c] = asc;
+}
+
+//----- usb_stor_stop_transport() ---------------------
+void usb_stor_stop_transport(struct us_data *us)
+{
+ //printk("transport --- usb_stor_stop_transport\n");
+
+ if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags))
+ {
+ //printk("-- cancelling URB\n");
+ usb_unlink_urb(us->current_urb);
+ }
+
+ if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags))
+ {
+ //printk("-- cancelling sg request\n");
+ usb_sg_cancel(&us->current_sg);
+ }
+}
+
+//----- usb_stor_Bulk_max_lun() ---------------------
+int usb_stor_Bulk_max_lun(struct us_data *us)
+{
+ int result;
+
+ //printk("transport --- usb_stor_Bulk_max_lun\n");
+ /* issue the command */
+ us->iobuf[0] = 0;
+ result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
+ US_BULK_GET_MAX_LUN,
+ USB_DIR_IN | USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE,
+ 0, us->ifnum, us->iobuf, 1, HZ);
+
+ //printk("GetMaxLUN command result is %d, data is %d\n", result, us->iobuf[0]);
+
+ /* if we have a successful request, return the result */
+ if (result > 0)
+ return us->iobuf[0];
+
+ return 0;
+}
+
+//----- usb_stor_Bulk_transport() ---------------------
+int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+ struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
+ unsigned int transfer_length = scsi_bufflen(srb);
+ unsigned int residue;
+ int result;
+ int fake_sense = 0;
+ unsigned int cswlen;
+ unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
+
+ //printk("transport --- usb_stor_Bulk_transport\n");
+ /* Take care of BULK32 devices; set extra byte to 0 */
+ if (unlikely(us->fflags & US_FL_BULK32))
+ {
+ cbwlen = 32;
+ us->iobuf[31] = 0;
+ }
+
+ /* set up the command wrapper */
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = cpu_to_le32(transfer_length);
+ bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
+ bcb->Tag = ++us->tag;
+ bcb->Lun = srb->device->lun;
+ if (us->fflags & US_FL_SCM_MULT_TARG)
+ bcb->Lun |= srb->device->id << 4;
+ bcb->Length = srb->cmd_len;
+
+ /* copy the command payload */
+ memset(bcb->CDB, 0, sizeof(bcb->CDB));
+ memcpy(bcb->CDB, srb->cmnd, bcb->Length);
+
+ // send command
+ /* send it to out endpoint */
+ /*printk("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
+ le32_to_cpu(bcb->Signature), bcb->Tag,
+ le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
+ (bcb->Lun >> 4), (bcb->Lun & 0x0F),
+ bcb->Length);*/
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, cbwlen, NULL);
+ //printk("Bulk command transfer result=%d\n", result);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ if (unlikely(us->fflags & US_FL_GO_SLOW))
+ udelay(125);
+
+ // R/W data
+ if (transfer_length)
+ {
+ unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe;
+ result = usb_stor_bulk_srb(us, pipe, srb);
+ //printk("Bulk data transfer result 0x%x\n", result);
+ if (result == USB_STOR_XFER_ERROR)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ if (result == USB_STOR_XFER_LONG)
+ fake_sense = 1;
+ }
+
+ /* get CSW for device status */
+ //printk("Attempting to get CSW...\n");
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+
+ if (result == USB_STOR_XFER_SHORT && cswlen == 0)
+ {
+ //printk("Received 0-length CSW; retrying...\n");
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+ }
+
+ /* did the attempt to read the CSW fail? */
+ if (result == USB_STOR_XFER_STALLED)
+ {
+ /* get the status again */
+ //printk("Attempting to get CSW (2nd try)...\n");
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL);
+ }
+
+ /* if we still have a failure at this point, we're in trouble */
+ //printk("Bulk status result = %d\n", result);
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
+
+ /* check bulk status */
+ residue = le32_to_cpu(bcs->Residue);
+ //printk("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, residue, bcs->Status);
+ if (!(bcs->Tag == us->tag || (us->fflags & US_FL_BULK_IGNORE_TAG)) || bcs->Status > US_BULK_STAT_PHASE)
+ {
+ //printk("Bulk logical error\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ if (!us->bcs_signature)
+ {
+ us->bcs_signature = bcs->Signature;
+ //if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN))
+ // printk("Learnt BCS signature 0x%08X\n", le32_to_cpu(us->bcs_signature));
+ }
+ else if (bcs->Signature != us->bcs_signature)
+ {
+ /*printk("Signature mismatch: got %08X, expecting %08X\n",
+ le32_to_cpu(bcs->Signature),
+ le32_to_cpu(us->bcs_signature));*/
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ /* try to compute the actual residue, based on how much data
+ * was really transferred and what the device tells us */
+ if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE))
+ {
+
+ /* Heuristically detect devices that generate bogus residues
+ * by seeing what happens with INQUIRY and READ CAPACITY
+ * commands.
+ */
+ if (bcs->Status == US_BULK_STAT_OK &&
+ scsi_get_resid(srb) == 0 &&
+ ((srb->cmnd[0] == INQUIRY &&
+ transfer_length == 36) ||
+ (srb->cmnd[0] == READ_CAPACITY &&
+ transfer_length == 8)))
+ {
+ us->fflags |= US_FL_IGNORE_RESIDUE;
+
+ }
+ else
+ {
+ residue = min(residue, transfer_length);
+ scsi_set_resid(srb, max(scsi_get_resid(srb), (int) residue));
+ }
+ }
+
+ /* based on the status code, we report good or bad */
+ switch (bcs->Status)
+ {
+ case US_BULK_STAT_OK:
+ if (fake_sense)
+ {
+ memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB, sizeof(usb_stor_sense_invalidCDB));
+ return USB_STOR_TRANSPORT_NO_SENSE;
+ }
+ return USB_STOR_TRANSPORT_GOOD;
+
+ case US_BULK_STAT_FAIL:
+ return USB_STOR_TRANSPORT_FAILED;
+
+ case US_BULK_STAT_PHASE:
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ return USB_STOR_TRANSPORT_ERROR;
+}
+
+/***********************************************************************
+ * Reset routines
+ ***********************************************************************/
+//----- usb_stor_reset_common() ---------------------
+static int usb_stor_reset_common(struct us_data *us,
+ u8 request, u8 requesttype,
+ u16 value, u16 index, void *data, u16 size)
+{
+ int result;
+ int result2;
+
+ //printk("transport --- usb_stor_reset_common\n");
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
+ {
+ //printk("No reset during disconnect\n");
+ return -EIO;
+ }
+
+ result = usb_stor_control_msg(us, us->send_ctrl_pipe, request, requesttype, value, index, data, size, 5*HZ);
+ if (result < 0)
+ {
+ //printk("Soft reset failed: %d\n", result);
+ return result;
+ }
+
+ wait_event_interruptible_timeout(us->delay_wait, test_bit(US_FLIDX_DISCONNECTING, &us->dflags), HZ*6);
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
+ {
+ //printk("Reset interrupted by disconnect\n");
+ return -EIO;
+ }
+
+ //printk("Soft reset: clearing bulk-in endpoint halt\n");
+ result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
+
+ //printk("Soft reset: clearing bulk-out endpoint halt\n");
+ result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);
+
+ /* return a result code based on the result of the clear-halts */
+ if (result >= 0)
+ result = result2;
+ //if (result < 0)
+ // printk("Soft reset failed\n");
+ //else
+ // printk("Soft reset done\n");
+ return result;
+}
+
+//----- usb_stor_Bulk_reset() ---------------------
+int usb_stor_Bulk_reset(struct us_data *us)
+{
+ //printk("transport --- usb_stor_Bulk_reset\n");
+ return usb_stor_reset_common(us, US_BULK_RESET_REQUEST,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum, NULL, 0);
+}
+
+//----- usb_stor_port_reset() ---------------------
+int usb_stor_port_reset(struct us_data *us)
+{
+ int result, rc_lock;
+
+ //printk("transport --- usb_stor_port_reset\n");
+ result = rc_lock = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
+ if (result < 0)
+ printk("unable to lock device for reset: %d\n", result);
+ else
+ {
+ /* Were we disconnected while waiting for the lock? */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
+ {
+ result = -EIO;
+ //printk("No reset during disconnect\n");
+ }
+ else
+ {
+ result = usb_reset_device(us->pusb_dev);
+ //printk("usb_reset_composite_device returns %d\n", result);
+ }
+ if (rc_lock)
+ usb_unlock_device(us->pusb_dev);
+ }
+ return result;
+}
+
+
diff --git a/drivers/staging/keucr/transport.h b/drivers/staging/keucr/transport.h
new file mode 100644
index 000000000000..ae9b5ee8a0cc
--- /dev/null
+++ b/drivers/staging/keucr/transport.h
@@ -0,0 +1,144 @@
+#ifndef _TRANSPORT_H_
+#define _TRANSPORT_H_
+
+#include <linux/blkdev.h>
+
+/* Bulk only data structures */
+
+/* command block wrapper */
+struct bulk_cb_wrap {
+ __le32 Signature; /* contains 'USBC' */
+ __u32 Tag; /* unique per command id */
+ __le32 DataTransferLength; /* size of data */
+ __u8 Flags; /* direction in bit 0 */
+ __u8 Lun; /* LUN normally 0 */
+ __u8 Length; /* of of the CDB */
+ __u8 CDB[16]; /* max command */
+};
+
+#define US_BULK_CB_WRAP_LEN 31
+#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */
+#define US_BULK_FLAG_IN 1
+#define US_BULK_FLAG_OUT 0
+
+/* command status wrapper */
+struct bulk_cs_wrap {
+ __le32 Signature; /* should = 'USBS' */
+ __u32 Tag; /* same as original command */
+ __le32 Residue; /* amount not transferred */
+ __u8 Status; /* see below */
+ __u8 Filler[18];
+};
+
+#define US_BULK_CS_WRAP_LEN 13
+#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */
+#define US_BULK_STAT_OK 0
+#define US_BULK_STAT_FAIL 1
+#define US_BULK_STAT_PHASE 2
+
+/* bulk-only class specific requests */
+#define US_BULK_RESET_REQUEST 0xff
+#define US_BULK_GET_MAX_LUN 0xfe
+
+/* usb_stor_bulk_transfer_xxx() return codes, in order of severity */
+#define USB_STOR_XFER_GOOD 0 /* good transfer */
+#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
+#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
+#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
+#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
+
+/* Transport return codes */
+#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
+#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
+#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
+#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
+
+/*
+ * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
+ * return codes. But now the transport and low-level transfer routines
+ * treat an abort as just another error (-ENOENT for a cancelled URB).
+ * It is up to the invoke_transport() function to test for aborts and
+ * distinguish them from genuine communication errors.
+ */
+
+/* CBI accept device specific command */
+#define US_CBI_ADSC 0
+extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
+extern int usb_stor_Bulk_max_lun(struct us_data*);
+extern int usb_stor_Bulk_reset(struct us_data*);
+extern void usb_stor_print_cmd(struct scsi_cmnd *);
+extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
+extern void usb_stor_stop_transport(struct us_data*);
+extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
+ u8 request, u8 requesttype, u16 value, u16 index,
+ void *data, u16 size, int timeout);
+extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe);
+extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
+ void *buf, unsigned int length, unsigned int *act_len);
+extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
+ void *buf, unsigned int length, int use_sg, int *residual);
+extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
+ struct scsi_cmnd* srb);
+extern int usb_stor_port_reset(struct us_data *us);
+
+/* Protocol handling routines */
+enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
+extern unsigned int usb_stor_access_xfer_buf(struct us_data*, unsigned char *buffer,
+ unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **,
+ unsigned int *offset, enum xfer_buf_dir dir);
+extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
+ unsigned int dir);
+
+// ENE scsi function
+extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
+extern int ENE_InitMedia(struct us_data*);
+extern int ENE_SDInit(struct us_data*);
+extern int ENE_MSInit(struct us_data*);
+extern int ENE_SMInit(struct us_data*);
+extern int ENE_ReadSDReg(struct us_data*, u8*);
+extern int ENE_SendScsiCmd(struct us_data*, BYTE, void*, int);
+extern int ENE_LoadBinCode(struct us_data*, BYTE);
+extern int ENE_Read_BYTE(struct us_data*, WORD index, void *buf);
+extern int ENE_Read_Data(struct us_data*, void *buf, unsigned int length);
+extern int ENE_Write_Data(struct us_data*, void *buf, unsigned int length);
+extern void BuildSenseBuffer(struct scsi_cmnd *, int);
+
+// ENE scsi function
+extern int SD_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
+extern int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
+extern int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
+
+// ENE MS function
+extern int MS_CardInit(struct us_data *us);
+extern void MS_LibFreeAllocatedArea(struct us_data *us);
+extern void MS_LibFreeWriteBuf(struct us_data *us);
+extern int MS_LibFreeLogicalMap(struct us_data *us);
+extern int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk);
+extern int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, DWORD *PageBuf, MS_LibTypeExtdat *ExtraDat);
+extern int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len);
+extern int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr);
+extern int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData);
+extern int MS_LibAllocLogicalMap(struct us_data *us);
+extern int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk);
+extern int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark);
+extern int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk);
+extern int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD phyblk);
+extern int MS_LibAllocWriteBuf(struct us_data *us);
+void MS_LibClearWriteBuf(struct us_data *us);
+void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde);
+extern int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibTypeExtdat *ExtraDat);
+extern int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE blen, void *buf);
+extern int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk);
+extern int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk);
+extern int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk);
+extern int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, BYTE OverwriteFlag);
+extern int MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk);
+extern int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock);
+extern int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock);
+extern int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk);
+extern int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk);
+
+// ENE SM function
+extern int SM_FreeMem(void);
+
+#endif
diff --git a/drivers/staging/keucr/usb.c b/drivers/staging/keucr/usb.c
new file mode 100644
index 000000000000..d7dab727cd6f
--- /dev/null
+++ b/drivers/staging/keucr/usb.c
@@ -0,0 +1,701 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/freezer.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/utsname.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "scsiglue.h"
+#include "transport.h"
+
+/* Some informational data */
+MODULE_AUTHOR("Domao");
+MODULE_DESCRIPTION("ENE USB Mass Storage driver for Linux");
+MODULE_LICENSE("GPL");
+
+static struct usb_device_id eucr_usb_ids [] = {
+ { USB_DEVICE(0x058f, 0x6366) },
+ { USB_DEVICE(0x0cf2, 0x6230) },
+ { USB_DEVICE(0x0cf2, 0x6250) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, eucr_usb_ids);
+
+
+
+int eucr_suspend(struct usb_interface *iface, pm_message_t message)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+ printk("--- eucr_suspend ---\n");
+ /* Wait until no command is running */
+ mutex_lock(&us->dev_mutex);
+
+ //US_DEBUGP("%s\n", __func__);
+ if (us->suspend_resume_hook)
+ (us->suspend_resume_hook)(us, US_SUSPEND);
+
+ /* When runtime PM is working, we'll set a flag to indicate
+ * whether we should autoresume when a SCSI request arrives. */
+ // us->Power_IsResum = true;
+ //us->SD_Status.Ready = 0;
+
+ mutex_unlock(&us->dev_mutex);
+ return 0;
+}
+//EXPORT_SYMBOL_GPL(eucr_suspend);
+
+int eucr_resume(struct usb_interface *iface)
+{
+ BYTE tmp = 0;
+
+ struct us_data *us = usb_get_intfdata(iface);
+ printk("--- eucr_resume---\n");
+ mutex_lock(&us->dev_mutex);
+
+ //US_DEBUGP("%s\n", __func__);
+ if (us->suspend_resume_hook)
+ (us->suspend_resume_hook)(us, US_RESUME);
+
+
+ mutex_unlock(&us->dev_mutex);
+
+
+ us->Power_IsResum = true;
+ //
+ //us->SD_Status.Ready = 0; //??
+ us->SD_Status = *(PSD_STATUS)&tmp;
+ us->MS_Status = *(PMS_STATUS)&tmp;
+ us->SM_Status = *(PSM_STATUS)&tmp;
+
+ return 0;
+}
+//EXPORT_SYMBOL_GPL(eucr_resume);
+int eucr_reset_resume(struct usb_interface *iface)
+{
+ BYTE tmp = 0;
+ struct us_data *us = usb_get_intfdata(iface);
+
+ printk("--- eucr_reset_resume---\n");
+ //US_DEBUGP("%s\n", __func__);
+
+ /* Report the reset to the SCSI core */
+ usb_stor_report_bus_reset(us);
+
+ /* FIXME: Notify the subdrivers that they need to reinitialize
+ * the device */
+ //ENE_InitMedia(us);
+ us->Power_IsResum = true;
+ //
+ //us->SD_Status.Ready = 0; //??
+ us->SD_Status = *(PSD_STATUS)&tmp;
+ us->MS_Status = *(PMS_STATUS)&tmp;
+ us->SM_Status = *(PSM_STATUS)&tmp;
+ return 0;
+}
+//EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
+
+//----- eucr_pre_reset() ---------------------
+static int eucr_pre_reset(struct usb_interface *iface)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+
+ printk("usb --- eucr_pre_reset\n");
+
+ /* Make sure no command runs during the reset */
+ mutex_lock(&us->dev_mutex);
+ return 0;
+}
+
+//----- eucr_post_reset() ---------------------
+static int eucr_post_reset(struct usb_interface *iface)
+{
+ struct us_data *us = usb_get_intfdata(iface);
+
+ printk("usb --- eucr_post_reset\n");
+
+ /* Report the reset to the SCSI core */
+ usb_stor_report_bus_reset(us);
+
+ mutex_unlock(&us->dev_mutex);
+ return 0;
+}
+
+//----- fill_inquiry_response() ---------------------
+void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len)
+{
+ printk("usb --- fill_inquiry_response\n");
+ if (data_len<36) // You lose.
+ return;
+
+ if (data[0]&0x20)
+ {
+ memset(data+8,0,28);
+ }
+ else
+ {
+ u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
+ memcpy(data+8, us->unusual_dev->vendorName,
+ strlen(us->unusual_dev->vendorName) > 8 ? 8 :
+ strlen(us->unusual_dev->vendorName));
+ memcpy(data+16, us->unusual_dev->productName,
+ strlen(us->unusual_dev->productName) > 16 ? 16 :
+ strlen(us->unusual_dev->productName));
+ data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
+ data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
+ data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
+ data[35] = 0x30 + ((bcdDevice) & 0x0F);
+ }
+ usb_stor_set_xfer_buf(us, data, data_len, us->srb, TO_XFER_BUF);
+}
+
+//----- usb_stor_control_thread() ---------------------
+static int usb_stor_control_thread(void * __us)
+{
+ struct us_data *us = (struct us_data *)__us;
+ struct Scsi_Host *host = us_to_host(us);
+
+ printk("usb --- usb_stor_control_thread\n");
+ for(;;)
+ {
+ if (wait_for_completion_interruptible(&us->cmnd_ready))
+ break;
+
+ /* lock the device pointers */
+ mutex_lock(&(us->dev_mutex));
+
+ /* if the device has disconnected, we are free to exit */
+/* if (test_bit(US_FLIDX_DISCONNECTING, &us->flags))
+ {
+ mutex_unlock(&us->dev_mutex);
+ break;
+ }*/
+
+ /* lock access to the state */
+ scsi_lock(host);
+
+ /* When we are called with no command pending, we're done */
+ if (us->srb == NULL)
+ {
+ scsi_unlock(host);
+ mutex_unlock(&us->dev_mutex);
+ //US_DEBUGP("-- exiting\n");
+ break;
+ }
+
+ /* has the command timed out *already* ? */
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
+ {
+ us->srb->result = DID_ABORT << 16;
+ goto SkipForAbort;
+ }
+
+ scsi_unlock(host);
+
+ if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL)
+ {
+ us->srb->result = DID_ERROR << 16;
+ }
+ else if (us->srb->device->id && !(us->fflags & US_FL_SCM_MULT_TARG))
+ {
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+ else if (us->srb->device->lun > us->max_lun)
+ {
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+ else if ((us->srb->cmnd[0] == INQUIRY) && (us->fflags & US_FL_FIX_INQUIRY))
+ {
+ unsigned char data_ptr[36] = {0x00, 0x80, 0x02, 0x02, 0x1F, 0x00, 0x00, 0x00};
+
+ fill_inquiry_response(us, data_ptr, 36);
+ us->srb->result = SAM_STAT_GOOD;
+ }
+ else
+ {
+ us->proto_handler(us->srb, us);
+ }
+
+ /* lock access to the state */
+ scsi_lock(host);
+
+ /* indicate that the command is done */
+ if (us->srb->result != DID_ABORT << 16)
+ {
+ us->srb->scsi_done(us->srb);
+ }
+ else
+ {
+SkipForAbort:
+ printk("scsi command aborted\n");
+ }
+
+ if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
+ {
+ complete(&(us->notify));
+
+ /* Allow USB transfers to resume */
+ clear_bit(US_FLIDX_ABORTING, &us->dflags);
+ clear_bit(US_FLIDX_TIMED_OUT, &us->dflags);
+ }
+
+ /* finished working on this command */
+ us->srb = NULL;
+ scsi_unlock(host);
+
+ /* unlock the device pointers */
+ mutex_unlock(&us->dev_mutex);
+ } /* for (;;) */
+
+ /* Wait until we are told to stop */
+ for (;;)
+ {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (kthread_should_stop())
+ break;
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+ return 0;
+}
+
+//----- associate_dev() ---------------------
+static int associate_dev(struct us_data *us, struct usb_interface *intf)
+{
+ printk("usb --- associate_dev\n");
+
+ /* Fill in the device-related fields */
+ us->pusb_dev = interface_to_usbdev(intf);
+ us->pusb_intf = intf;
+ us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
+
+ /* Store our private data in the interface */
+ usb_set_intfdata(intf, us);
+
+ /* Allocate the device-related DMA-mapped buffers */
+ us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL, &us->cr_dma);
+ if (!us->cr)
+ {
+ printk("usb_ctrlrequest allocation failed\n");
+ return -ENOMEM;
+ }
+
+ us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);
+ if (!us->iobuf)
+ {
+ printk("I/O buffer allocation failed\n");
+ return -ENOMEM;
+ }
+
+ us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
+ if (!us->sensebuf)
+ {
+ printk("Sense buffer allocation failed\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+//----- get_device_info() ---------------------
+static int get_device_info(struct us_data *us, const struct usb_device_id *id)
+{
+ struct usb_device *dev = us->pusb_dev;
+ struct usb_interface_descriptor *idesc = &us->pusb_intf->cur_altsetting->desc;
+
+ printk("usb --- get_device_info\n");
+
+ us->subclass = idesc->bInterfaceSubClass;
+ us->protocol = idesc->bInterfaceProtocol;
+ us->fflags = USB_US_ORIG_FLAGS(id->driver_info);
+ us->Power_IsResum = false;
+
+ if (us->fflags & US_FL_IGNORE_DEVICE)
+ {
+ printk("device ignored\n");
+ return -ENODEV;
+ }
+
+ if (dev->speed != USB_SPEED_HIGH)
+ us->fflags &= ~US_FL_GO_SLOW;
+
+ return 0;
+}
+
+//----- get_transport() ---------------------
+static int get_transport(struct us_data *us)
+{
+ printk("usb --- get_transport\n");
+ switch (us->protocol) {
+ case US_PR_BULK:
+ us->transport_name = "Bulk";
+ us->transport = usb_stor_Bulk_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ break;
+
+ default:
+ return -EIO;
+ }
+ //printk("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_protocol() ---------------------
+static int get_protocol(struct us_data *us)
+{
+ printk("usb --- get_protocol\n");
+ printk("us->pusb_dev->descriptor.idVendor = %x\n", us->pusb_dev->descriptor.idVendor);
+ printk("us->pusb_dev->descriptor.idProduct = %x\n", us->pusb_dev->descriptor.idProduct);
+ switch (us->subclass) {
+ case US_SC_SCSI:
+ us->protocol_name = "Transparent SCSI";
+ if( (us->pusb_dev->descriptor.idVendor == 0x0CF2) && (us->pusb_dev->descriptor.idProduct == 0x6250) )
+ us->proto_handler = ENE_stor_invoke_transport;
+ else
+ us->proto_handler = usb_stor_invoke_transport;
+ break;
+
+ default:
+ return -EIO;
+ }
+ //printk("Protocol: %s\n", us->protocol_name);
+ return 0;
+}
+
+//----- get_pipes() ---------------------
+static int get_pipes(struct us_data *us)
+{
+ struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
+ int i;
+ struct usb_endpoint_descriptor *ep;
+ struct usb_endpoint_descriptor *ep_in = NULL;
+ struct usb_endpoint_descriptor *ep_out = NULL;
+ struct usb_endpoint_descriptor *ep_int = NULL;
+
+ printk("usb --- get_pipes\n");
+
+ for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
+ {
+ ep = &altsetting->endpoint[i].desc;
+
+ if (usb_endpoint_xfer_bulk(ep))
+ {
+ if (usb_endpoint_dir_in(ep))
+ {
+ if (!ep_in)
+ ep_in = ep;
+ }
+ else
+ {
+ if (!ep_out)
+ ep_out = ep;
+ }
+ }
+ else if (usb_endpoint_is_int_in(ep))
+ {
+ if (!ep_int)
+ ep_int = ep;
+ }
+ }
+
+ if (!ep_in || !ep_out || (us->protocol == US_PR_CBI && !ep_int))
+ {
+ printk("Endpoint sanity check failed! Rejecting dev.\n");
+ return -EIO;
+ }
+
+ /* Calculate and store the pipe values */
+ 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);
+ us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ if (ep_int)
+ {
+ us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ us->ep_bInterval = ep_int->bInterval;
+ }
+ return 0;
+}
+
+//----- usb_stor_acquire_resources() ---------------------
+static int usb_stor_acquire_resources(struct us_data *us)
+{
+ struct task_struct *th;
+
+ printk("usb --- usb_stor_acquire_resources\n");
+ us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!us->current_urb)
+ {
+ printk("URB allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* Start up our control thread */
+ th = kthread_run(usb_stor_control_thread, us, "eucr-storage");
+ if (IS_ERR(th))
+ {
+ printk("Unable to start control thread\n");
+ return PTR_ERR(th);
+ }
+ us->ctl_thread = th;
+
+ return 0;
+}
+
+//----- usb_stor_release_resources() ---------------------
+static void usb_stor_release_resources(struct us_data *us)
+{
+ printk("usb --- usb_stor_release_resources\n");
+
+ SM_FreeMem();
+
+ complete(&us->cmnd_ready);
+ if (us->ctl_thread)
+ kthread_stop(us->ctl_thread);
+
+ /* Call the destructor routine, if it exists */
+ if (us->extra_destructor)
+ {
+ printk("-- calling extra_destructor()\n");
+ us->extra_destructor(us->extra);
+ }
+
+ /* Free the extra data and the URB */
+ kfree(us->extra);
+ usb_free_urb(us->current_urb);
+}
+
+//----- dissociate_dev() ---------------------
+static void dissociate_dev(struct us_data *us)
+{
+ printk("usb --- dissociate_dev\n");
+
+ kfree(us->sensebuf);
+
+ /* Free the device-related DMA-mapped buffers */
+ if (us->cr)
+ usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
+ if (us->iobuf)
+ usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, us->iobuf_dma);
+
+ /* Remove our private data from the interface */
+ usb_set_intfdata(us->pusb_intf, NULL);
+}
+
+//----- quiesce_and_remove_host() ---------------------
+static void quiesce_and_remove_host(struct us_data *us)
+{
+ struct Scsi_Host *host = us_to_host(us);
+
+ printk("usb --- quiesce_and_remove_host\n");
+
+ /* If the device is really gone, cut short reset delays */
+ if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
+ set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+
+ /* Prevent SCSI-scanning (if it hasn't started yet)
+ * and wait for the SCSI-scanning thread to stop.
+ */
+ set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
+ wake_up(&us->delay_wait);
+ wait_for_completion(&us->scanning_done);
+
+ /* Removing the host will perform an orderly shutdown: caches
+ * synchronized, disks spun down, etc.
+ */
+ scsi_remove_host(host);
+
+ /* Prevent any new commands from being accepted and cut short
+ * reset delays.
+ */
+ scsi_lock(host);
+ set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+ scsi_unlock(host);
+ wake_up(&us->delay_wait);
+}
+
+//----- release_everything() ---------------------
+static void release_everything(struct us_data *us)
+{
+ printk("usb --- release_everything\n");
+
+ usb_stor_release_resources(us);
+ dissociate_dev(us);
+ scsi_host_put(us_to_host(us));
+}
+
+//----- usb_stor_scan_thread() ---------------------
+static int usb_stor_scan_thread(void * __us)
+{
+ struct us_data *us = (struct us_data *)__us;
+
+ printk("usb --- usb_stor_scan_thread\n");
+ printk("EUCR : device found at %d\n", us->pusb_dev->devnum);
+
+// Have we to add this code ?
+// set_freezable();
+// /* Wait for the timeout to expire or for a disconnect */
+// if (delay_use > 0)
+// {
+// wait_event_freezable_timeout(us->delay_wait,
+// test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
+// delay_use * HZ);
+// }
+
+ /* If the device is still connected, perform the scanning */
+ if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags))
+ {
+ /* For bulk-only devices, determine the max LUN value */
+ if (us->protocol == US_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN))
+ {
+ mutex_lock(&us->dev_mutex);
+ us->max_lun = usb_stor_Bulk_max_lun(us);
+ mutex_unlock(&us->dev_mutex);
+ }
+ scsi_scan_host(us_to_host(us));
+ printk("EUCR : device scan complete\n");
+ }
+ complete_and_exit(&us->scanning_done, 0);
+}
+
+//----- eucr_probe() ---------------------
+static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct Scsi_Host *host;
+ struct us_data *us;
+ int result;
+ struct task_struct *th;
+
+ printk("usb --- eucr_probe\n");
+
+ host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
+ if (!host)
+ {
+ printk("Unable to allocate the scsi host\n");
+ return -ENOMEM;
+ }
+
+ /* Allow 16-byte CDBs and thus > 2TB */
+ host->max_cmd_len = 16;
+ us = host_to_us(host);
+ memset(us, 0, sizeof(struct us_data));
+ mutex_init(&(us->dev_mutex));
+ init_completion(&us->cmnd_ready);
+ init_completion(&(us->notify));
+ init_waitqueue_head(&us->delay_wait);
+ init_completion(&us->scanning_done);
+
+ /* Associate the us_data structure with the USB device */
+ result = associate_dev(us, intf);
+ if (result)
+ goto BadDevice;
+
+ /* Get Device info */
+ result = get_device_info(us, id);
+ 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)
+ goto BadDevice;
+ result = get_pipes(us);
+ if (result)
+ goto BadDevice;
+
+ /* Acquire all the other resources and add the host */
+ result = usb_stor_acquire_resources(us);
+ if (result)
+ goto BadDevice;
+
+ result = scsi_add_host(host, &intf->dev);
+ if (result)
+ {
+ printk("Unable to add the scsi host\n");
+ goto BadDevice;
+ }
+
+ /* Start up the thread for delayed SCSI-device scanning */
+ th = kthread_create(usb_stor_scan_thread, us, "eucr-stor-scan");
+ if (IS_ERR(th))
+ {
+ printk("Unable to start the device-scanning thread\n");
+ complete(&us->scanning_done);
+ quiesce_and_remove_host(us);
+ result = PTR_ERR(th);
+ goto BadDevice;
+ }
+ wake_up_process(th);
+ return 0;
+
+ /* We come here if there are any problems */
+BadDevice:
+ printk("usb --- eucr_probe failed\n");
+ release_everything(us);
+ return result;
+}
+
+//----- eucr_disconnect() ---------------------
+static void eucr_disconnect(struct usb_interface *intf)
+{
+ struct us_data *us = usb_get_intfdata(intf);
+
+ printk("usb --- eucr_disconnect\n");
+ quiesce_and_remove_host(us);
+ release_everything(us);
+}
+
+/***********************************************************************
+ * Initialization and registration
+ ***********************************************************************/
+
+//----- usb_storage_driver() ---------------------
+static struct usb_driver usb_storage_driver = {
+ .name = "eucr",
+ .probe = eucr_probe,
+ .suspend = eucr_suspend,
+ .resume = eucr_resume,
+ .reset_resume = eucr_reset_resume,
+ .disconnect = eucr_disconnect,
+ .pre_reset = eucr_pre_reset,
+ .post_reset = eucr_post_reset,
+ .id_table = eucr_usb_ids,
+ .soft_unbind = 1,
+};
+
+//----- usb_stor_init() ---------------------
+static int __init usb_stor_init(void)
+{
+ int retval;
+ printk("usb --- usb_stor_init start\n");
+
+ retval = usb_register(&usb_storage_driver);
+ if (retval == 0)
+ printk("ENE USB Mass Storage support registered.\n");
+
+ return retval;
+}
+
+//----- usb_stor_exit() ---------------------
+static void __exit usb_stor_exit(void)
+{
+ printk("usb --- usb_stor_exit\n");
+
+ usb_deregister(&usb_storage_driver) ;
+}
+
+module_init(usb_stor_init);
+module_exit(usb_stor_exit);
diff --git a/drivers/staging/keucr/usb.h b/drivers/staging/keucr/usb.h
new file mode 100644
index 000000000000..bbf578ad6316
--- /dev/null
+++ b/drivers/staging/keucr/usb.h
@@ -0,0 +1,238 @@
+// Driver for USB Mass Storage compliant devices
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/blkdev.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <scsi/scsi_host.h>
+#include "common.h"
+#include "ms.h"
+
+struct us_data;
+struct scsi_cmnd;
+
+/*
+ * Unusual device list definitions
+ */
+
+struct us_unusual_dev {
+ const char* vendorName;
+ const char* productName;
+ __u8 useProtocol;
+ __u8 useTransport;
+ int (*initFunction)(struct us_data *);
+};
+
+//EnE HW Register
+#define REG_CARD_STATUS 0xFF83
+#define REG_HW_TRAP1 0xFF89
+
+// SRB Status. Refers /usr/include/wine/wine/wnaspi32.h & SCSI sense key
+#define SS_SUCCESS 0x00 // No Sense
+#define SS_NOT_READY 0x02
+#define SS_MEDIUM_ERR 0x03
+#define SS_HW_ERR 0x04
+#define SS_ILLEGAL_REQUEST 0x05
+#define SS_UNIT_ATTENTION 0x06
+
+//ENE Load FW Pattern
+#define SD_INIT1_PATTERN 1
+#define SD_INIT2_PATTERN 2
+#define SD_RW_PATTERN 3
+#define MS_INIT_PATTERN 4
+#define MSP_RW_PATTERN 5
+#define MS_RW_PATTERN 6
+#define SM_INIT_PATTERN 7
+#define SM_RW_PATTERN 8
+
+#define FDIR_WRITE 0
+#define FDIR_READ 1
+
+typedef struct _SD_STATUS {
+ BYTE Insert:1;
+ BYTE Ready:1;
+ BYTE MediaChange:1;
+ BYTE IsMMC:1;
+ BYTE HiCapacity:1;
+ BYTE HiSpeed:1;
+ BYTE WtP:1;
+ BYTE Reserved:1;
+} SD_STATUS, *PSD_STATUS;
+
+typedef struct _MS_STATUS {
+ BYTE Insert:1;
+ BYTE Ready:1;
+ BYTE MediaChange:1;
+ BYTE IsMSPro:1;
+ BYTE IsMSPHG:1;
+ BYTE Reserved1:1;
+ BYTE WtP:1;
+ BYTE Reserved2:1;
+} MS_STATUS, *PMS_STATUS;
+
+typedef struct _SM_STATUS {
+ BYTE Insert:1;
+ BYTE Ready:1;
+ BYTE MediaChange:1;
+ BYTE Reserved:3;
+ BYTE WtP:1;
+ BYTE IsMS:1;
+} SM_STATUS, *PSM_STATUS;
+
+// SD Block Length
+#define SD_BLOCK_LEN 9 // 2^9 = 512 Bytes, The HW maximum read/write data length
+
+/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
+#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */
+#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */
+#define US_FLIDX_ABORTING 2 /* abort is in progress */
+#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
+#define US_FLIDX_RESETTING 4 /* device reset in progress */
+#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
+#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */
+
+
+#define USB_STOR_STRING_LEN 32
+
+/*
+ * We provide a DMA-mapped I/O buffer for use with small USB transfers.
+ * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
+ * 31-byte buffer. But Freecom needs a 64-byte buffer, so that's the
+ * size we'll allocate.
+ */
+
+#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */
+#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */
+
+typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
+typedef int (*trans_reset)(struct us_data*);
+typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
+typedef void (*extra_data_destructor)(void *); /* extra data destructor */
+typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
+
+#define US_SUSPEND 0
+#define US_RESUME 1
+
+/* we allocate one of these for every device that we remember */
+struct us_data {
+ /* The device we're working with
+ * It's important to note:
+ * (o) you must hold dev_mutex to change pusb_dev
+ */
+ struct mutex dev_mutex; /* protect pusb_dev */
+ struct usb_device *pusb_dev; /* this usb_device */
+ struct usb_interface *pusb_intf; /* this interface */
+ struct us_unusual_dev *unusual_dev; /* device-filter entry */
+ unsigned long fflags; /* fixed flags from filter */
+ unsigned long dflags; /* dynamic atomic bitflags */
+ unsigned int send_bulk_pipe; /* cached pipe values */
+ unsigned int recv_bulk_pipe;
+ unsigned int send_ctrl_pipe;
+ unsigned int recv_ctrl_pipe;
+ unsigned int recv_intr_pipe;
+
+ /* information about the device */
+ char *transport_name;
+ char *protocol_name;
+ __le32 bcs_signature;
+ u8 subclass;
+ u8 protocol;
+ u8 max_lun;
+
+ u8 ifnum; /* interface number */
+ u8 ep_bInterval; /* interrupt interval */
+
+ /* function pointers for this device */
+ trans_cmnd transport; /* transport function */
+ trans_reset transport_reset; /* transport device reset */
+ proto_cmnd proto_handler; /* protocol handler */
+
+ /* SCSI interfaces */
+ struct scsi_cmnd *srb; /* current srb */
+ unsigned int tag; /* current dCBWTag */
+
+ /* control and bulk communications data */
+ struct urb *current_urb; /* USB requests */
+ struct usb_ctrlrequest *cr; /* control requests */
+ struct usb_sg_request current_sg; /* scatter-gather req. */
+ unsigned char *iobuf; /* I/O buffer */
+ unsigned char *sensebuf; /* sense data buffer */
+ dma_addr_t cr_dma; /* buffer DMA addresses */
+ dma_addr_t iobuf_dma;
+ struct task_struct *ctl_thread; /* the control thread */
+
+ /* mutual exclusion and synchronization structures */
+ struct completion cmnd_ready; /* to sleep thread on */
+ struct completion notify; /* thread begin/end */
+ wait_queue_head_t delay_wait; /* wait during scan, reset */
+ struct completion scanning_done; /* wait for scan thread */
+
+ /* subdriver information */
+ void *extra; /* Any extra data */
+ extra_data_destructor extra_destructor;/* extra data destructor */
+#ifdef CONFIG_PM
+ pm_hook suspend_resume_hook;
+#endif
+ // for 6250 code
+ SD_STATUS SD_Status;
+ MS_STATUS MS_Status;
+ SM_STATUS SM_Status;
+
+ //----- SD Control Data ----------------
+ //SD_REGISTER SD_Regs;
+ WORD SD_Block_Mult;
+ BYTE SD_READ_BL_LEN;
+ WORD SD_C_SIZE;
+ BYTE SD_C_SIZE_MULT;
+
+ // SD/MMC New spec.
+ BYTE SD_SPEC_VER;
+ BYTE SD_CSD_VER;
+ BYTE SD20_HIGH_CAPACITY;
+ DWORD HC_C_SIZE;
+ BYTE MMC_SPEC_VER;
+ BYTE MMC_BusWidth;
+ BYTE MMC_HIGH_CAPACITY;
+
+ //----- MS Control Data ----------------
+ BOOLEAN MS_SWWP;
+ DWORD MSP_TotalBlock;
+ MS_LibControl MS_Lib;
+ BOOLEAN MS_IsRWPage;
+ WORD MS_Model;
+
+ //----- SM Control Data ----------------
+ BYTE SM_DeviceID;
+ BYTE SM_CardID;
+
+ PBYTE testbuf;
+ BYTE BIN_FLAG;
+ DWORD bl_num;
+ int SrbStatus;
+
+ //------Power Managerment ---------------
+ BOOLEAN Power_IsResum;
+};
+
+/* Convert between us_data and the corresponding Scsi_Host */
+static inline struct Scsi_Host *us_to_host(struct us_data *us) {
+ return container_of((void *) us, struct Scsi_Host, hostdata);
+}
+static inline struct us_data *host_to_us(struct Scsi_Host *host) {
+ return (struct us_data *) host->hostdata;
+}
+
+/* Function to fill an inquiry response. See usb.c for details */
+extern void fill_inquiry_response(struct us_data *us,
+ unsigned char *data, unsigned int data_len);
+
+/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
+ * single queue element srb for write access */
+#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
+#define scsi_lock(host) spin_lock_irq(host->host_lock)
+
+#endif
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
index bc1ffbed3c8a..43120ff2ab78 100644
--- a/drivers/staging/line6/Kconfig
+++ b/drivers/staging/line6/Kconfig
@@ -1,4 +1,4 @@
-config LINE6_USB
+menuconfig LINE6_USB
tristate "Line6 USB support"
depends on USB && SND
select SND_RAWMIDI
@@ -18,5 +18,68 @@ config LINE6_USB
* Signal routing (record clean/processed guitar signal,
re-amping)
- Preliminary support for the Variax Workbench is included.
+ Preliminary support for the Variax Workbench and TonePort
+ devices is included.
+if LINE6_USB
+
+config LINE6_USB_DEBUG
+ bool "print debug messages"
+ default n
+ help
+ Say Y here to write debug messages to the syslog.
+
+ If unsure, say N.
+
+config LINE6_USB_DUMP_CTRL
+ bool "dump control messages"
+ default n
+ help
+ Say Y here to write control messages sent to and received from
+ Line6 devices to the syslog.
+
+ If unsure, say N.
+
+config LINE6_USB_DUMP_MIDI
+ bool "dump MIDI messages"
+ default n
+ help
+ Say Y here to write MIDI messages sent to and received from
+ Line6 devices to the syslog.
+
+ If unsure, say N.
+
+config LINE6_USB_DUMP_PCM
+ bool "dump PCM data"
+ default n
+ help
+ Say Y here to write PCM data sent to and received from Line6
+ devices to the syslog. This will produce a huge amount of
+ syslog data during playback and capture.
+
+ If unsure, say N.
+
+config LINE6_USB_RAW
+ bool "raw data communication"
+ default n
+ help
+ Say Y here to create special files which allow to send raw data
+ to the device. This bypasses any sanity checks, so if you discover
+ the code to erase the firmware, feel free to render your device
+ useless, but only after reading the GPL section "NO WARRANTY".
+
+ If unsure, say N.
+
+config LINE6_USB_IMPULSE_RESPONSE
+ bool "measure impulse response"
+ default n
+ help
+ Say Y here to add code to measure the impulse response of a Line6
+ device. This is more accurate than user-space methods since it
+ bypasses any PCM data buffering (e.g., by ALSA or jack). This is
+ useful for assessing the performance of new devices, but is not
+ required for normal operation.
+
+ If unsure, say N.
+
+endif # LINE6_USB
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
index e2ac8d60f8c2..b1488d321c7b 100644
--- a/drivers/staging/line6/audio.c
+++ b/drivers/staging/line6/audio.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,17 +9,15 @@
*
*/
-#include "driver.h"
-#include "audio.h"
-
#include <sound/core.h>
#include <sound/initval.h>
+#include "driver.h"
+#include "audio.h"
static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-
/*
Initialize the Line6 USB audio system.
*/
@@ -36,10 +34,10 @@ int line6_init_audio(struct usb_line6 *line6)
line6->card = card;
+ strcpy(card->id, line6->properties->id);
strcpy(card->driver, DRIVER_NAME);
- strcpy(card->shortname, "Line6-USB");
- sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
- dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
+ strcpy(card->shortname, line6->properties->name);
+ sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
return 0;
}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
index cc0245adbcd9..5f8a09a0fa95 100644
--- a/drivers/staging/line6/audio.h
+++ b/drivers/staging/line6/audio.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,13 +12,10 @@
#ifndef AUDIO_H
#define AUDIO_H
-
#include "driver.h"
-
extern void line6_cleanup_audio(struct usb_line6 *);
extern int line6_init_audio(struct usb_line6 *);
extern int line6_register_audio(struct usb_line6 *);
-
#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index ca092247f363..a3c99244b359 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,37 +9,34 @@
*
*/
-#include "driver.h"
-
-#include <linux/slab.h>
-
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "audio.h"
+#include "capture.h"
+#include "driver.h"
#include "pcm.h"
#include "pod.h"
-#include "capture.h"
/*
Find a free URB and submit it.
*/
-static int submit_audio_in_urb(struct snd_pcm_substream *substream)
+static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
{
- unsigned int index;
+ int index;
unsigned long flags;
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
int i, urb_size;
+ int ret;
struct urb *urb_in;
spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
index =
find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
- if (index >= LINE6_ISO_BUFFERS) {
+ if (index < 0 || index >= LINE6_ISO_BUFFERS) {
spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
- dev_err(s2m(substream), "no free URB found\n");
+ dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
return -EINVAL;
}
@@ -58,13 +55,15 @@ static int submit_audio_in_urb(struct snd_pcm_substream *substream)
line6pcm->buffer_in +
index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
urb_in->transfer_buffer_length = urb_size;
- urb_in->context = substream;
+ urb_in->context = line6pcm;
+
+ ret = usb_submit_urb(urb_in, GFP_ATOMIC);
- if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
+ if (ret == 0)
set_bit(index, &line6pcm->active_urb_in);
else
- dev_err(s2m(substream), "URB in #%d submission failed\n",
- index);
+ dev_err(line6pcm->line6->ifcdev,
+ "URB in #%d submission failed (%d)\n", index, ret);
spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
return 0;
@@ -73,12 +72,12 @@ static int submit_audio_in_urb(struct snd_pcm_substream *substream)
/*
Submit all currently available capture URBs.
*/
-static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
+int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
{
int ret, i;
for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
- ret = submit_audio_in_urb(substream);
+ ret = submit_audio_in_urb(line6pcm);
if (ret < 0)
return ret;
}
@@ -89,7 +88,7 @@ static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
/*
Unlink all currently active capture URBs.
*/
-static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
{
unsigned int i;
@@ -126,41 +125,83 @@ static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
} while (--timeout > 0);
if (alive)
snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-
- line6pcm->active_urb_in = 0;
- line6pcm->unlink_urb_in = 0;
}
/*
Unlink all currently active capture URBs, and wait for finishing.
*/
-void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
{
- unlink_audio_in_urbs(line6pcm);
+ line6_unlink_audio_in_urbs(line6pcm);
wait_clear_audio_in_urbs(line6pcm);
}
/*
- Callback for completed capture URB.
+ Copy data into ALSA capture buffer.
+*/
+void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
+{
+ struct snd_pcm_substream *substream =
+ get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+ int frames = fsize / bytes_per_frame;
+
+ if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+ /*
+ The transferred area goes over buffer boundary,
+ copy two separate chunks.
+ */
+ int len;
+ len = runtime->buffer_size - line6pcm->pos_in_done;
+
+ if (len > 0) {
+ memcpy(runtime->dma_area +
+ line6pcm->pos_in_done * bytes_per_frame, fbuf,
+ len * bytes_per_frame);
+ memcpy(runtime->dma_area, fbuf + len * bytes_per_frame,
+ (frames - len) * bytes_per_frame);
+ } else
+ dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ } else {
+ /* copy single chunk */
+ memcpy(runtime->dma_area +
+ line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize);
+ }
+
+ if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
+ line6pcm->pos_in_done -= runtime->buffer_size;
+}
+
+void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
+{
+ struct snd_pcm_substream *substream =
+ get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
+
+ if ((line6pcm->bytes_in += length) >= line6pcm->period_in) {
+ line6pcm->bytes_in %= line6pcm->period_in;
+ snd_pcm_period_elapsed(substream);
+ }
+}
+
+/*
+ Callback for completed capture URB.
*/
static void audio_in_callback(struct urb *urb)
{
int i, index, length = 0, shutdown = 0;
- int frames;
unsigned long flags;
- struct snd_pcm_substream *substream =
- (struct snd_pcm_substream *)urb->context;
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
- const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
- struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
+
+ line6pcm->last_frame_in = urb->start_frame;
/* find index of URB */
for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
if (urb == line6pcm->urb_audio_in[index])
break;
-#if DO_DUMP_PCM_RECEIVE
+#ifdef CONFIG_LINE6_USB_DUMP_PCM
for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
struct usb_iso_packet_descriptor *fout =
&urb->iso_frame_desc[i];
@@ -177,71 +218,53 @@ static void audio_in_callback(struct urb *urb)
int fsize;
struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
- if (fin->status == -18) {
+ if (fin->status == -EXDEV) {
shutdown = 1;
break;
}
fbuf = urb->transfer_buffer + fin->offset;
fsize = fin->actual_length;
+
+ if (fsize > line6pcm->max_packet_size) {
+ dev_err(line6pcm->line6->ifcdev,
+ "driver and/or device bug: packet too large (%d > %d)\n",
+ fsize, line6pcm->max_packet_size);
+ }
+
length += fsize;
- if (fsize > 0) {
- frames = fsize / bytes_per_frame;
-
- if (line6pcm->pos_in_done + frames >
- runtime->buffer_size) {
- /*
- The transferred area goes over buffer
- boundary, copy two separate chunks.
- */
- int len;
- len =
- runtime->buffer_size -
- line6pcm->pos_in_done;
-
- if (len > 0) {
- memcpy(runtime->dma_area +
- line6pcm->pos_in_done *
- bytes_per_frame, fbuf,
- len * bytes_per_frame);
- memcpy(runtime->dma_area,
- fbuf + len * bytes_per_frame,
- (frames -
- len) * bytes_per_frame);
- } else {
- /* this is somewhat paranoid */
- dev_err(s2m(substream),
- "driver bug: len = %d\n", len);
- }
- } else {
- /* copy single chunk */
- memcpy(runtime->dma_area +
- line6pcm->pos_in_done * bytes_per_frame,
- fbuf, fsize * bytes_per_frame);
- }
+ /* the following assumes LINE6_ISO_PACKETS == 1: */
+#if LINE6_BACKUP_MONITOR_SIGNAL
+ memcpy(line6pcm->prev_fbuf, fbuf, fsize);
+#else
+ line6pcm->prev_fbuf = fbuf;
+#endif
+ line6pcm->prev_fsize = fsize;
- line6pcm->pos_in_done += frames;
- if (line6pcm->pos_in_done >= runtime->buffer_size)
- line6pcm->pos_in_done -= runtime->buffer_size;
- }
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ if (!(line6pcm->flags & MASK_PCM_IMPULSE))
+#endif
+ if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)
+ && (fsize > 0))
+ line6_capture_copy(line6pcm, fbuf, fsize);
}
clear_bit(index, &line6pcm->active_urb_in);
- if (test_bit(index, &line6pcm->unlink_urb_in))
+ if (test_and_clear_bit(index, &line6pcm->unlink_urb_in))
shutdown = 1;
spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
if (!shutdown) {
- submit_audio_in_urb(substream);
+ submit_audio_in_urb(line6pcm);
- line6pcm->bytes_in += length;
- if (line6pcm->bytes_in >= line6pcm->period_in) {
- line6pcm->bytes_in -= line6pcm->period_in;
- snd_pcm_period_elapsed(substream);
- }
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ if (!(line6pcm->flags & MASK_PCM_IMPULSE))
+#endif
+ if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
+ line6_capture_check_period(line6pcm, length);
}
}
@@ -254,8 +277,8 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream)
err = snd_pcm_hw_constraint_ratdens(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- (&line6pcm->properties->
- snd_line6_rates));
+ (&line6pcm->
+ properties->snd_line6_rates));
if (err < 0)
return err;
@@ -294,54 +317,40 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
return ret;
line6pcm->period_in = params_period_bytes(hw_params);
- line6pcm->buffer_in =
- kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
- LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
-
- if (!line6pcm->buffer_in) {
- dev_err(s2m(substream), "cannot malloc buffer_in\n");
- return -ENOMEM;
- }
-
return 0;
}
/* hw_free capture callback */
static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
- unlink_wait_clear_audio_in_urbs(line6pcm);
-
- kfree(line6pcm->buffer_in);
- line6pcm->buffer_in = NULL;
-
return snd_pcm_lib_free_pages(substream);
}
/* trigger callback */
-int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
{
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
int err;
- line6pcm->count_in = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- if (!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) {
- err = submit_audio_in_all_urbs(substream);
+#ifdef CONFIG_PM
+ case SNDRV_PCM_TRIGGER_RESUME:
+#endif
+ err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE);
- if (err < 0) {
- clear_bit(BIT_RUNNING_CAPTURE,
- &line6pcm->flags);
- return err;
- }
- }
+ if (err < 0)
+ return err;
break;
case SNDRV_PCM_TRIGGER_STOP:
- if (test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags))
- unlink_audio_in_urbs(line6pcm);
+#ifdef CONFIG_PM
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+#endif
+ err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE);
+
+ if (err < 0)
+ return err;
break;
@@ -372,7 +381,7 @@ struct snd_pcm_ops snd_line6_capture_ops = {
.pointer = snd_line6_capture_pointer,
};
-int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
{
int i;
@@ -392,8 +401,8 @@ int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
urb->dev = line6pcm->line6->usbdev;
urb->pipe =
usb_rcvisocpipe(line6pcm->line6->usbdev,
- line6pcm->
- ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
+ line6pcm->ep_audio_read &
+ USB_ENDPOINT_NUMBER_MASK);
urb->transfer_flags = URB_ISO_ASAP;
urb->start_frame = -1;
urb->number_of_packets = LINE6_ISO_PACKETS;
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
index 5c44464d29d4..a7509fbbb954 100644
--- a/drivers/staging/line6/capture.h
+++ b/drivers/staging/line6/capture.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,21 +12,22 @@
#ifndef CAPTURE_H
#define CAPTURE_H
-
-#include "driver.h"
-
#include <sound/pcm.h>
+#include "driver.h"
#include "pcm.h"
-
extern struct snd_pcm_ops snd_line6_capture_ops;
-
-extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream,
- int cmd);
-extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-
+extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
+ int fsize);
+extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
+ int length);
+extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
+ *line6pcm);
+extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
#endif
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
index 0b598526de62..22564aed61e4 100644
--- a/drivers/staging/line6/control.c
+++ b/drivers/staging/line6/control.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,11 +9,10 @@
*
*/
-#include "driver.h"
-
#include <linux/usb.h>
#include "control.h"
+#include "driver.h"
#include "pod.h"
#include "usbdefs.h"
#include "variax.h"
@@ -45,7 +44,7 @@ static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_wait_dump(&pod->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&pod->dumpreq);
if (retval < 0)
return retval;
return sprintf(buf, "%d\n", pod->prog_data.control[param]);
@@ -63,7 +62,7 @@ static ssize_t pod_set_param_int(struct device *dev, const char *buf,
if (retval)
return retval;
- pod_transmit_parameter(pod, param, value);
+ line6_pod_transmit_parameter(pod, param, value);
return count;
}
@@ -71,7 +70,7 @@ static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_variax *variax = usb_get_intfdata(interface);
- int retval = line6_wait_dump(&variax->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&variax->dumpreq);
if (retval < 0)
return retval;
return sprintf(buf, "%d\n", variax->model_data.control[param]);
@@ -80,12 +79,11 @@ static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
{
/*
- We do our own floating point handling here since floats in the
- kernel are problematic for at least two reasons: - many distros
- are still shipped with binary kernels optimized for the ancient
- 80386 without FPU
- - there isn't a printf("%f")
- (see http://www.kernelthread.com/publications/faq/335.html)
+ We do our own floating point handling here since at the time
+ this code was written (Jan 2006) it was highly discouraged to
+ use floating point arithmetic in the kernel. If you think that
+ this no longer applies, feel free to replace this by generic
+ floating point code.
*/
static const int BIAS = 0x7f;
@@ -97,7 +95,7 @@ static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_variax *variax = usb_get_intfdata(interface);
const unsigned char *p = variax->model_data.control + param;
- int retval = line6_wait_dump(&variax->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&variax->dumpreq);
if (retval < 0)
return retval;
@@ -530,7 +528,7 @@ static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring,
line6_nop_write);
-int pod_create_files(int firmware, int type, struct device *dev)
+int line6_pod_create_files(int firmware, int type, struct device *dev)
{
int err;
CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
@@ -733,9 +731,10 @@ int pod_create_files(int firmware, int type, struct device *dev)
(dev, &dev_attr_band_6_gain__bass));
return 0;
}
-EXPORT_SYMBOL(pod_create_files);
-void pod_remove_files(int firmware, int type, struct device *dev)
+EXPORT_SYMBOL(line6_pod_create_files);
+
+void line6_pod_remove_files(int firmware, int type, struct device *dev)
{
device_remove_file(dev, &dev_attr_tweak);
device_remove_file(dev, &dev_attr_wah_position);
@@ -908,9 +907,10 @@ void pod_remove_files(int firmware, int type, struct device *dev)
if (firmware >= 200)
device_remove_file(dev, &dev_attr_band_6_gain__bass);
}
-EXPORT_SYMBOL(pod_remove_files);
-int variax_create_files(int firmware, int type, struct device *dev)
+EXPORT_SYMBOL(line6_pod_remove_files);
+
+int line6_variax_create_files(int firmware, int type, struct device *dev)
{
int err;
CHECK_RETURN(device_create_file(dev, &dev_attr_body));
@@ -954,9 +954,10 @@ int variax_create_files(int firmware, int type, struct device *dev)
CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
return 0;
}
-EXPORT_SYMBOL(variax_create_files);
-void variax_remove_files(int firmware, int type, struct device *dev)
+EXPORT_SYMBOL(line6_variax_create_files);
+
+void line6_variax_remove_files(int firmware, int type, struct device *dev)
{
device_remove_file(dev, &dev_attr_body);
device_remove_file(dev, &dev_attr_pickup1_enable);
@@ -998,4 +999,5 @@ void variax_remove_files(int firmware, int type, struct device *dev)
device_remove_file(dev, &dev_attr_mix1);
device_remove_file(dev, &dev_attr_pickup_wiring);
}
-EXPORT_SYMBOL(variax_remove_files);
+
+EXPORT_SYMBOL(line6_variax_remove_files);
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
index 47e18ab6d5b0..e4c5d2ce2aae 100644
--- a/drivers/staging/line6/control.h
+++ b/drivers/staging/line6/control.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,54 +12,40 @@
#ifndef LINE6_CONTROL_H
#define LINE6_CONTROL_H
-
/**
List of PODxt Pro controls.
See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
Comments after the number refer to the PODxt Pro firmware version required
for this feature.
+
+ Please *don't* reformat this file since "control.c" is created automatically
+ from "control.h", and this process depends on the exact formatting of the
+ code and the comments below!
*/
+
+/* *INDENT-OFF* */
+
enum {
POD_tweak = 1,
POD_wah_position = 4,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_compression_gain = 5,
-
+ POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */
POD_vol_pedal_position = 7,
POD_compression_threshold = 9,
POD_pan = 10,
POD_amp_model_setup = 11,
- POD_amp_model = 12, /* firmware: 2.0 */
+ POD_amp_model = 12, /* firmware: 2.0 */
POD_drive = 13,
POD_bass = 14,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_mid = 15,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_lowmid = 15,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_treble = 16,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_highmid = 16,
-
+ POD_mid = 15, /* device: LINE6_BITS_PODXTALL */
+ POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_treble = 16, /* device: LINE6_BITS_PODXTALL */
+ POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */
POD_chan_vol = 17,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_reverb_mix = 18,
-
+ POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */
POD_effect_setup = 19,
POD_band_1_frequency = 20, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_PODXTALL */
- POD_presence = 21,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_treble__bass = 21,
-
+ POD_presence = 21, /* device: LINE6_BITS_PODXTALL */
+ POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */
POD_noise_gate_enable = 22,
POD_gate_threshold = 23,
POD_gate_decay_time = 24,
@@ -70,137 +56,78 @@ enum {
POD_mod_param_1 = 29,
POD_delay_param_1 = 30,
POD_delay_param_1_note_value = 31,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_2_frequency__bass = 32, /* firmware: 2.0 */
-
+ POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_delay_param_2 = 33,
POD_delay_volume_mix = 34,
POD_delay_param_3 = 35,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_reverb_enable = 36,
- POD_reverb_type = 37,
- POD_reverb_decay = 38,
- POD_reverb_tone = 39,
- POD_reverb_pre_delay = 40,
- POD_reverb_pre_post = 41,
- POD_band_2_frequency = 42,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_3_frequency__bass = 42, /* firmware: 2.0 */
-
+ POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */
+ POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_wah_enable = 43,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_modulation_lo_cut = 44,
- POD_delay_reverb_lo_cut = 45,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_volume_pedal_minimum = 46, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_eq_pre_post = 46, /* firmware: 2.0 */
-
+ POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_volume_pre_post = 47,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_di_model = 48,
- POD_di_delay = 49,
-
+ POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */
POD_mod_enable = 50,
POD_mod_param_1_note_value = 51,
POD_mod_param_2 = 52,
POD_mod_param_3 = 53,
POD_mod_param_4 = 54,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_mod_param_5 = 55,
-
+ POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */
POD_mod_volume_mix = 56,
POD_mod_pre_post = 57,
POD_modulation_model = 58,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_band_3_frequency = 60, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_4_frequency__bass = 60, /* firmware: 2.0 */
-
+ POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_mod_param_1_double_precision = 61,
POD_delay_param_1_double_precision = 62,
POD_eq_enable = 63, /* firmware: 2.0 */
POD_tap = 64,
POD_volume_tweak_pedal_assign = 65,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_5_frequency = 68, /* firmware: 2.0 */
-
+ POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_tuner = 69,
POD_mic_selection = 70,
POD_cabinet_model = 71,
POD_stomp_model = 75,
POD_roomlevel = 76,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_band_4_frequency = 77, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_6_frequency = 77, /* firmware: 2.0 */
-
+ POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
POD_stomp_param_1_note_value = 78,
POD_stomp_param_2 = 79,
POD_stomp_param_3 = 80,
POD_stomp_param_4 = 81,
POD_stomp_param_5 = 82,
POD_stomp_param_6 = 83,
-
- /* device: LINE6_BITS_LIVE */
- POD_amp_switch_select = 84,
-
+ POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */
POD_delay_param_4 = 85,
POD_delay_param_5 = 86,
POD_delay_pre_post = 87,
-
- /* device: LINE6_BITS_PODXTALL */
- POD_delay_model = 88,
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_delay_verb_model = 88,
-
+ POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */
+ POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */
POD_tempo_msb = 89,
POD_tempo_lsb = 90,
POD_wah_model = 91, /* firmware: 3.0 */
POD_bypass_volume = 105, /* firmware: 2.14 */
-
- /* device: LINE6_BITS_PRO */
- POD_fx_loop_on_off = 107,
-
+ POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */
POD_tweak_param_select = 108,
POD_amp1_engage = 111,
POD_band_1_gain = 114, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_2_gain__bass = 115, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_PODXTALL */
- POD_band_2_gain = 116, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_3_gain__bass = 116, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_PODXTALL */
- POD_band_3_gain = 117, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_4_gain__bass = 117, /* firmware: 2.0 */
- POD_band_5_gain__bass = 118, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_PODXTALL */
- POD_band_4_gain = 119, /* firmware: 2.0 */
-
- /* device: LINE6_BITS_BASSPODXTALL */
- POD_band_6_gain__bass = 119 /* firmware: 2.0 */
+ POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
};
/**
@@ -218,8 +145,7 @@ enum {
VARIAX_pickup2_position = 23, /* type: 24 bit float */
VARIAX_pickup2_angle = 26, /* type: 24 bit float */
VARIAX_pickup2_level = 29, /* type: 24 bit float */
- VARIAX_pickup_phase = 32, /* 0: in phase,
- 1: out of phase */
+ VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */
VARIAX_capacitance = 33, /* type: 24 bit float */
VARIAX_tone_resistance = 36, /* type: 24 bit float */
VARIAX_volume_resistance = 39, /* type: 24 bit float */
@@ -257,11 +183,13 @@ enum {
VARIAXMIDI_tone = 79,
};
+/* *INDENT-ON* */
-extern int pod_create_files(int firmware, int type, struct device *dev);
-extern void pod_remove_files(int firmware, int type, struct device *dev);
-extern int variax_create_files(int firmware, int type, struct device *dev);
-extern void variax_remove_files(int firmware, int type, struct device *dev);
-
+extern int line6_pod_create_files(int firmware, int type, struct device *dev);
+extern void line6_pod_remove_files(int firmware, int type, struct device *dev);
+extern int line6_variax_create_files(int firmware, int type,
+ struct device *dev);
+extern void line6_variax_remove_files(int firmware, int type,
+ struct device *dev);
#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index 27b986a50a03..c671427350ef 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,8 +9,6 @@
*
*/
-#include "driver.h"
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -19,6 +17,7 @@
#include "audio.h"
#include "capture.h"
#include "control.h"
+#include "driver.h"
#include "midi.h"
#include "playback.h"
#include "pod.h"
@@ -27,58 +26,77 @@
#include "usbdefs.h"
#include "variax.h"
-
#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
#define DRIVER_DESC "Line6 USB Driver"
-#define DRIVER_VERSION "0.8.0"
-
+#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
/* table of devices that work with this driver */
static const struct usb_device_id line6_id_table[] = {
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
- { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
- { },
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)},
+ {USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)},
+ {},
};
+
MODULE_DEVICE_TABLE(usb, line6_id_table);
+/* *INDENT-OFF* */
static struct line6_properties line6_properties_table[] = {
- { "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM },
- { "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
- { "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM },
- { "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM },
- { "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL_PCM },
- { "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM },
- { "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM },
- { "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM },
- { "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM },
- { "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM },
- { "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM },
- { "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM },
- { "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
- { "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
+ { "BassPODxt", "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "BassPODxtLive", "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "BassPODxtPro", "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "GuitarPort", "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM },
+ { "PocketPOD", "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL },
+ { "PODStudioGX", "POD Studio GX", LINE6_BIT_PODSTUDIO_GX, LINE6_BIT_PCM },
+ { "PODStudioUX1", "POD Studio UX1", LINE6_BIT_PODSTUDIO_UX1, LINE6_BIT_PCM },
+ { "PODStudioUX2", "POD Studio UX2", LINE6_BIT_PODSTUDIO_UX2, LINE6_BIT_PCM },
+ { "PODX3", "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM },
+ { "PODX3Live", "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM },
+ { "PODxt", "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "PODxtLive", "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "PODxtPro", "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM_HWMON },
+ { "TonePortGX", "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM },
+ { "TonePortUX1", "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM },
+ { "TonePortUX2", "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
+ { "Variax", "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
};
-
+/* *INDENT-ON* */
/*
This is Line6's MIDI manufacturer ID.
*/
-const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };
+const unsigned char line6_midi_id[] = {
+ 0x00, 0x01, 0x0c
+};
-struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
-struct workqueue_struct *line6_workqueue;
+/*
+ Code to request version of POD, Variax interface
+ (and maybe other devices).
+*/
+static const char line6_request_version0[] = {
+ 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7
+};
+/*
+ Copy of version request code with GFP_KERNEL flag for use in URB.
+*/
+static const char *line6_request_version;
+
+struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
/**
Class for asynchronous messages.
@@ -90,7 +108,6 @@ struct message {
int done;
};
-
/*
Forward declarations.
*/
@@ -98,21 +115,30 @@ static void line6_data_received(struct urb *urb);
static int line6_send_raw_message_async_part(struct message *msg,
struct urb *urb);
-
/*
Start to listen on endpoint.
*/
static int line6_start_listen(struct usb_line6 *line6)
{
+ int err;
usb_fill_int_urb(line6->urb_listen, line6->usbdev,
usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
line6_data_received, line6, line6->interval);
line6->urb_listen->actual_length = 0;
- return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
+ err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
+ return err;
}
-#if DO_DUMP_ANY
+/*
+ Stop listening on endpoint.
+*/
+static void line6_stop_listen(struct usb_line6 *line6)
+{
+ usb_kill_urb(line6->urb_listen);
+}
+
+#ifdef CONFIG_LINE6_USB_DUMP_ANY
/*
Write hexdump to syslog.
*/
@@ -136,12 +162,13 @@ void line6_write_hexdump(struct usb_line6 *line6, char dir,
if (j < n) {
unsigned char val = buffer[i + j];
bytes = snprintf(p, hexdumpsize, " %02X", val);
- asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
+ asc[j] = ((val >= 0x20)
+ && (val < 0x7f)) ? val : '.';
} else
bytes = snprintf(p, hexdumpsize, " ");
if (bytes > hexdumpsize)
- break; /* buffer overflow */
+ break; /* buffer overflow */
p += bytes;
hexdumpsize -= bytes;
@@ -152,7 +179,7 @@ void line6_write_hexdump(struct usb_line6 *line6, char dir,
}
#endif
-#if DO_DUMP_URB_RECEIVE
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
/*
Dump URB data to syslog.
*/
@@ -169,19 +196,19 @@ static void line6_dump_urb(struct urb *urb)
#endif
/*
- Send raw message in pieces of max_packet_size bytes.
+ Send raw message in pieces of wMaxPacketSize bytes.
*/
int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
int size)
{
int i, done = 0;
- int actual_size;
-#if DO_DUMP_URB_SEND
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
line6_write_hexdump(line6, 'S', buffer, size);
#endif
- for (i = 0; i < size; i += actual_size) {
+ for (i = 0; i < size; i += line6->max_packet_size) {
+ int partial;
const char *frag_buf = buffer + i;
int frag_size = min(line6->max_packet_size, size - i);
int retval;
@@ -190,7 +217,7 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
usb_sndintpipe(line6->usbdev,
line6->ep_control_write),
(char *)frag_buf, frag_size,
- &actual_size, LINE6_TIMEOUT * HZ);
+ &partial, LINE6_TIMEOUT * HZ);
if (retval) {
dev_err(line6->ifcdev,
@@ -198,7 +225,7 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
break;
}
- done += actual_size;
+ done += frag_size;
}
return done;
@@ -234,7 +261,7 @@ static int line6_send_raw_message_async_part(struct message *msg,
(char *)msg->buffer + done, bytes,
line6_async_request_sent, msg, line6->interval);
-#if DO_DUMP_URB_SEND
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
#endif
@@ -253,6 +280,17 @@ static int line6_send_raw_message_async_part(struct message *msg,
}
/*
+ Setup and start timer.
+*/
+void line6_start_timer(struct timer_list *timer, unsigned int msecs,
+ void (*function) (unsigned long), unsigned long data)
+{
+ setup_timer(timer, function, data);
+ timer->expires = jiffies + msecs * HZ / 1000;
+ add_timer(timer);
+}
+
+/*
Asynchronously send raw message.
*/
int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
@@ -289,12 +327,34 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
}
/*
+ Send asynchronous device version request.
+*/
+int line6_version_request_async(struct usb_line6 *line6)
+{
+ return line6_send_raw_message_async(line6, line6_request_version,
+ sizeof(line6_request_version0));
+}
+
+/*
Send sysex message in pieces of wMaxPacketSize bytes.
*/
int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
int size)
{
- return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
+ return line6_send_raw_message(line6, buffer,
+ size + SYSEX_EXTRA_SIZE) -
+ SYSEX_EXTRA_SIZE;
+}
+
+/*
+ Send sysex message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_sysex_message_async(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ return line6_send_raw_message_async(line6, buffer,
+ size + SYSEX_EXTRA_SIZE) -
+ SYSEX_EXTRA_SIZE;
}
/*
@@ -305,7 +365,7 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
int size)
{
- char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);
+ char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_ATOMIC);
if (!buffer) {
dev_err(line6->ifcdev, "out of memory\n");
@@ -332,29 +392,36 @@ static void line6_data_received(struct urb *urb)
if (urb->status == -ESHUTDOWN)
return;
-#if DO_DUMP_URB_RECEIVE
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
line6_dump_urb(urb);
#endif
- done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+ done =
+ line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
if (done < urb->actual_length) {
- midibuf_ignore(mb, done);
- DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
+ line6_midibuf_ignore(mb, done);
+ DEBUG_MESSAGES(dev_err
+ (line6->ifcdev,
+ "%d %d buffer overflow - message skipped\n",
+ done, urb->actual_length));
}
for (;;) {
- done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
+ done =
+ line6_midibuf_read(mb, line6->buffer_message,
+ LINE6_MESSAGE_MAXLEN);
if (done == 0)
break;
/* MIDI input filter */
- if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
+ if (line6_midibuf_skip_message
+ (mb, line6->line6midi->midi_mask_receive))
continue;
line6->message_length = done;
-#if DO_DUMP_MIDI_RECEIVE
+#ifdef CONFIG_LINE6_USB_DUMP_MIDI
line6_write_hexdump(line6, 'r', line6->buffer_message, done);
#endif
line6_midi_receive(line6, line6->buffer_message, done);
@@ -366,26 +433,33 @@ static void line6_data_received(struct urb *urb)
case LINE6_DEVID_PODXT:
case LINE6_DEVID_PODXTPRO:
case LINE6_DEVID_POCKETPOD:
- pod_process_message((struct usb_line6_pod *)line6);
+ line6_pod_process_message((struct usb_line6_pod *)
+ line6);
break;
case LINE6_DEVID_PODXTLIVE:
switch (line6->interface_number) {
case PODXTLIVE_INTERFACE_POD:
- pod_process_message((struct usb_line6_pod *)line6);
+ line6_pod_process_message((struct usb_line6_pod
+ *)line6);
break;
case PODXTLIVE_INTERFACE_VARIAX:
- variax_process_message((struct usb_line6_variax *)line6);
+ line6_variax_process_message((struct
+ usb_line6_variax
+ *)line6);
break;
default:
- dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
+ dev_err(line6->ifcdev,
+ "PODxt Live interface %d not supported\n",
+ line6->interface_number);
}
break;
case LINE6_DEVID_VARIAX:
- variax_process_message((struct usb_line6_variax *)line6);
+ line6_variax_process_message((struct usb_line6_variax *)
+ line6);
break;
default:
@@ -396,44 +470,17 @@ static void line6_data_received(struct urb *urb)
line6_start_listen(line6);
}
-static int line6_send(struct usb_line6 *line6, unsigned char *buf, size_t len)
-{
- int retval;
- int partial;
-
-#if DO_DUMP_URB_SEND
- line6_write_hexdump(line6, 'S', buf, len);
-#endif
-
- retval = usb_interrupt_msg(line6->usbdev,
- usb_sndintpipe(line6->usbdev,
- line6->ep_control_write),
- buf, len, &partial,
- LINE6_TIMEOUT * HZ);
-
- if (retval) {
- dev_err(line6->ifcdev,
- "usb_interrupt_msg failed (%d)\n", retval);
- }
-
- if (partial != len) {
- dev_err(line6->ifcdev,
- "usb_interrupt_msg sent partial message (%d)\n",
- retval);
- }
-
- return retval;
-}
-
/*
Send channel number (i.e., switch to a different sound).
*/
int line6_send_program(struct usb_line6 *line6, int value)
{
+ int retval;
unsigned char *buffer;
- size_t len = 2;
+ int partial;
+
+ buffer = kmalloc(2, GFP_KERNEL);
- buffer = kmalloc(len, GFP_KERNEL);
if (!buffer) {
dev_err(line6->ifcdev, "out of memory\n");
return -ENOMEM;
@@ -442,7 +489,21 @@ int line6_send_program(struct usb_line6 *line6, int value)
buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
buffer[1] = value;
- return line6_send(line6, buffer, len);
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
+ line6_write_hexdump(line6, 'S', buffer, 2);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ buffer, 2, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
+ retval);
+
+ kfree(buffer);
+ return retval;
}
/*
@@ -450,10 +511,12 @@ int line6_send_program(struct usb_line6 *line6, int value)
*/
int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
{
+ int retval;
unsigned char *buffer;
- size_t len = 3;
+ int partial;
+
+ buffer = kmalloc(3, GFP_KERNEL);
- buffer = kmalloc(len, GFP_KERNEL);
if (!buffer) {
dev_err(line6->ifcdev, "out of memory\n");
return -ENOMEM;
@@ -463,13 +526,28 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
buffer[1] = param;
buffer[2] = value;
- return line6_send(line6, buffer, len);
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
+ line6_write_hexdump(line6, 'S', buffer, 3);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ buffer, 3, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
+ retval);
+
+ kfree(buffer);
+ return retval;
}
/*
Read data from device.
*/
-int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
+int line6_read_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen)
{
struct usb_device *usbdev = line6->usbdev;
int ret;
@@ -477,10 +555,9 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t dat
/* query the serial number: */
ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE
- | USB_DIR_OUT,
- (datalen << 8) | 0x21, address,
- NULL, 0, LINE6_TIMEOUT * HZ);
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ (datalen << 8) | 0x21, address,
+ NULL, 0, LINE6_TIMEOUT * HZ);
if (ret < 0) {
dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
@@ -558,8 +635,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
return ret;
}
}
- while (status == 0xff)
- ;
+ while (status == 0xff);
if (status != 0) {
dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
@@ -575,7 +651,8 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
*/
int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
{
- return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
+ return line6_read_data(line6, 0x80d0, serial_number,
+ sizeof(*serial_number));
}
/*
@@ -590,7 +667,7 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
/*
No operation (i.e., unsupported).
*/
-ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
+ssize_t line6_nop_write(struct device * dev, struct device_attribute * attr,
const char *buf, size_t count)
{
return count;
@@ -599,8 +676,8 @@ ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
/*
"write" request on "raw" special file.
*/
-#if CREATE_RAW_FILE
-ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+#ifdef CONFIG_LINE6_USB_RAW
+ssize_t line6_set_raw(struct device * dev, struct device_attribute * attr,
const char *buf, size_t count)
{
struct usb_interface *interface = to_usb_interface(dev);
@@ -637,25 +714,11 @@ static void line6_destruct(struct usb_interface *interface)
kfree(line6);
}
-static void line6_list_devices(void)
-{
- int i;
-
- for (i = 0; i < LINE6_MAX_DEVICES; ++i) {
- struct usb_line6 *dev = line6_devices[i];
- printk(KERN_INFO "Line6 device %d: ", i);
-
- if (dev == NULL)
- printk("(not used)\n");
- else
- printk("%s:%d\n", dev->properties->name, dev->interface_number);
- }
-}
-
/*
Probe USB device.
*/
-static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
+static int line6_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
{
int devtype;
struct usb_device *usbdev = NULL;
@@ -674,10 +737,6 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
if (usbdev == NULL)
return -ENODEV;
- /* increment reference counters: */
- usb_get_intf(interface);
- usb_get_dev(usbdev);
-
/* we don't handle multiple configurations */
if (usbdev->descriptor.bNumConfigurations != 1) {
ret = -ENODEV;
@@ -689,8 +748,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor);
u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
- if (idVendor == line6_id_table[devtype].idVendor
- && idProduct == line6_id_table[devtype].idProduct)
+ if (idVendor == line6_id_table[devtype].idVendor &&
+ idProduct == line6_id_table[devtype].idProduct)
break;
}
@@ -719,12 +778,23 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
switch (product) {
case LINE6_DEVID_BASSPODXTLIVE:
- case LINE6_DEVID_POCKETPOD:
case LINE6_DEVID_PODXTLIVE:
case LINE6_DEVID_VARIAX:
alternate = 1;
break;
+ case LINE6_DEVID_POCKETPOD:
+ switch (interface_number) {
+ case 0:
+ return 0; /* this interface has no endpoints */
+ case 1:
+ alternate = 0;
+ break;
+ default:
+ MISSING_CASE;
+ }
+ break;
+
case LINE6_DEVID_PODX3:
case LINE6_DEVID_PODX3LIVE:
switch (interface_number) {
@@ -746,21 +816,27 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
alternate = 5;
break;
- case LINE6_DEVID_TONEPORT_GX:
case LINE6_DEVID_GUITARPORT:
- alternate = 2; /* 1..4 seem to be ok */
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ alternate = 2; /* 1..4 seem to be ok */
break;
- case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_PODSTUDIO_UX2:
switch (interface_number) {
case 0:
/* defaults to 44.1kHz, 16-bit */
alternate = 2;
break;
case 1:
- alternate = 0;
- break;
+ /* don't know yet what this is ...
+ alternate = 1;
+ break;
+ */
+ return -ENODEV;
default:
MISSING_CASE;
}
@@ -783,22 +859,30 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
case LINE6_DEVID_BASSPODXT:
case LINE6_DEVID_BASSPODXTLIVE:
case LINE6_DEVID_BASSPODXTPRO:
- case LINE6_DEVID_POCKETPOD:
case LINE6_DEVID_PODXT:
case LINE6_DEVID_PODXTPRO:
size = sizeof(struct usb_line6_pod);
- ep_read = 0x84;
+ ep_read = 0x84;
ep_write = 0x03;
break;
+ case LINE6_DEVID_POCKETPOD:
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x82;
+ ep_write = 0x02;
+ break;
+
case LINE6_DEVID_PODX3:
case LINE6_DEVID_PODX3LIVE:
/* currently unused! */
size = sizeof(struct usb_line6_pod);
- ep_read = 0x81;
+ ep_read = 0x81;
ep_write = 0x01;
break;
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX2:
case LINE6_DEVID_TONEPORT_GX:
case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
@@ -811,13 +895,13 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
switch (interface_number) {
case PODXTLIVE_INTERFACE_POD:
size = sizeof(struct usb_line6_pod);
- ep_read = 0x84;
+ ep_read = 0x84;
ep_write = 0x03;
break;
case PODXTLIVE_INTERFACE_VARIAX:
size = sizeof(struct usb_line6_variax);
- ep_read = 0x86;
+ ep_read = 0x86;
ep_write = 0x05;
break;
@@ -829,7 +913,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
case LINE6_DEVID_VARIAX:
size = sizeof(struct usb_line6_variax);
- ep_read = 0x82;
+ ep_read = 0x82;
ep_write = 0x01;
break;
@@ -840,7 +924,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
}
if (size == 0) {
- dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
+ dev_err(line6->ifcdev,
+ "driver bug: interface data size not set\n");
ret = -ENODEV;
goto err_put;
}
@@ -865,16 +950,19 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
/* get data from endpoint descriptor (see usb_maxpacket): */
{
struct usb_host_endpoint *ep;
- unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
+ unsigned epnum =
+ usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
ep = usbdev->ep_in[epnum];
if (ep != NULL) {
line6->interval = ep->desc.bInterval;
- line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+ line6->max_packet_size =
+ le16_to_cpu(ep->desc.wMaxPacketSize);
} else {
line6->interval = LINE6_FALLBACK_INTERVAL;
line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
- dev_err(line6->ifcdev, "endpoint not available, using fallback values");
+ dev_err(line6->ifcdev,
+ "endpoint not available, using fallback values");
}
}
@@ -882,7 +970,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
if (properties->capabilities & LINE6_BIT_CONTROL) {
/* initialize USB buffers: */
- line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+ line6->buffer_listen =
+ kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
if (line6->buffer_listen == NULL) {
dev_err(&interface->dev, "Out of memory\n");
@@ -890,7 +979,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
goto err_destruct;
}
- line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
+ line6->buffer_message =
+ kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
if (line6->buffer_message == NULL) {
dev_err(&interface->dev, "Out of memory\n");
@@ -925,17 +1015,21 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
case LINE6_DEVID_PODX3LIVE:
case LINE6_DEVID_PODXT:
case LINE6_DEVID_PODXTPRO:
- ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);
break;
case LINE6_DEVID_PODXTLIVE:
switch (interface_number) {
case PODXTLIVE_INTERFACE_POD:
- ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ ret =
+ line6_pod_init(interface,
+ (struct usb_line6_pod *)line6);
break;
case PODXTLIVE_INTERFACE_VARIAX:
- ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ ret =
+ line6_variax_init(interface,
+ (struct usb_line6_variax *)line6);
break;
default:
@@ -948,14 +1042,21 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
break;
case LINE6_DEVID_VARIAX:
- ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ ret =
+ line6_variax_init(interface,
+ (struct usb_line6_variax *)line6);
break;
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX2:
case LINE6_DEVID_TONEPORT_GX:
case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
case LINE6_DEVID_GUITARPORT:
- ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
+ ret =
+ line6_toneport_init(interface,
+ (struct usb_line6_toneport *)line6);
break;
default:
@@ -971,10 +1072,24 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
if (ret < 0)
goto err_destruct;
+ /* creation of additional special files should go here */
+
dev_info(&interface->dev, "Line6 %s now attached\n",
line6->properties->name);
line6_devices[devnum] = line6;
- line6_list_devices();
+
+ switch (product) {
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ dev_info(&interface->dev,
+ "NOTE: the Line6 %s is detected, but not yet supported\n",
+ line6->properties->name);
+ }
+
+ /* increment reference counters: */
+ usb_get_intf(interface);
+ usb_get_dev(usbdev);
+
return 0;
err_destruct:
@@ -1000,6 +1115,8 @@ static void line6_disconnect(struct usb_interface *interface)
if (usbdev == NULL)
return;
+ /* removal of additional special files should go here */
+
sysfs_remove_link(&interface->dev.kobj, "usb_device");
interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
@@ -1007,7 +1124,7 @@ static void line6_disconnect(struct usb_interface *interface)
if (line6 != NULL) {
if (line6->urb_listen != NULL)
- usb_kill_urb(line6->urb_listen);
+ line6_stop_listen(line6);
if (usbdev != line6->usbdev)
dev_err(line6->ifcdev,
@@ -1022,43 +1139,46 @@ static void line6_disconnect(struct usb_interface *interface)
case LINE6_DEVID_PODX3LIVE:
case LINE6_DEVID_PODXT:
case LINE6_DEVID_PODXTPRO:
- pod_disconnect(interface);
+ line6_pod_disconnect(interface);
break;
case LINE6_DEVID_PODXTLIVE:
switch (interface_number) {
case PODXTLIVE_INTERFACE_POD:
- pod_disconnect(interface);
+ line6_pod_disconnect(interface);
break;
case PODXTLIVE_INTERFACE_VARIAX:
- variax_disconnect(interface);
+ line6_variax_disconnect(interface);
break;
}
break;
case LINE6_DEVID_VARIAX:
- variax_disconnect(interface);
+ line6_variax_disconnect(interface);
break;
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX2:
case LINE6_DEVID_TONEPORT_GX:
case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
case LINE6_DEVID_GUITARPORT:
- toneport_disconnect(interface);
+ line6_toneport_disconnect(interface);
break;
default:
MISSING_CASE;
}
- dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
+ dev_info(&interface->dev, "Line6 %s now disconnected\n",
+ line6->properties->name);
- for (i = LINE6_MAX_DEVICES; i--;) {
+ for (i = LINE6_MAX_DEVICES; i--;)
if (line6_devices[i] == line6)
line6_devices[i] = NULL;
- }
}
line6_destruct(interface);
@@ -1066,14 +1186,78 @@ static void line6_disconnect(struct usb_interface *interface)
/* decrement reference counters: */
usb_put_intf(interface);
usb_put_dev(usbdev);
+}
+
+#ifdef CONFIG_PM
+
+/*
+ Suspend Line6 device.
+*/
+static int line6_suspend(struct usb_interface *interface, pm_message_t message)
+{
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ struct snd_line6_pcm *line6pcm = line6->line6pcm;
+
+ snd_power_change_state(line6->card, SNDRV_CTL_POWER_D3hot);
+
+ if (line6->properties->capabilities & LINE6_BIT_CONTROL)
+ line6_stop_listen(line6);
+
+ if (line6pcm != NULL) {
+ snd_pcm_suspend_all(line6pcm->pcm);
+ line6_pcm_disconnect(line6pcm);
+ line6pcm->flags = 0;
+ }
- line6_list_devices();
+ return 0;
+}
+
+/*
+ Resume Line6 device.
+*/
+static int line6_resume(struct usb_interface *interface)
+{
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+
+ if (line6->properties->capabilities & LINE6_BIT_CONTROL)
+ line6_start_listen(line6);
+
+ snd_power_change_state(line6->card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+
+/*
+ Resume Line6 device after reset.
+*/
+static int line6_reset_resume(struct usb_interface *interface)
+{
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX2:
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ line6_toneport_reset_resume((struct usb_line6_toneport *)line6);
+ }
+
+ return line6_resume(interface);
}
+#endif /* CONFIG_PM */
+
static struct usb_driver line6_driver = {
.name = DRIVER_NAME,
.probe = line6_probe,
.disconnect = line6_disconnect,
+#ifdef CONFIG_PM
+ .suspend = line6_suspend,
+ .resume = line6_resume,
+ .reset_resume = line6_reset_resume,
+#endif
.id_table = line6_id_table,
};
@@ -1084,22 +1268,28 @@ static int __init line6_init(void)
{
int i, retval;
- printk(KERN_INFO "%s driver version %s%s\n",
- DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
- line6_workqueue = create_workqueue(DRIVER_NAME);
-
- if (line6_workqueue == NULL) {
- err("couldn't create workqueue");
- return -EINVAL;
- }
+ printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION);
for (i = LINE6_MAX_DEVICES; i--;)
line6_devices[i] = NULL;
retval = usb_register(&line6_driver);
- if (retval)
+ if (retval) {
err("usb_register failed. Error number %d", retval);
+ return retval;
+ }
+
+ line6_request_version = kmalloc(sizeof(line6_request_version0),
+ GFP_KERNEL);
+
+ if (line6_request_version == NULL) {
+ err("Out of memory");
+ return -ENOMEM;
+ }
+
+ memcpy((char *)line6_request_version, line6_request_version0,
+ sizeof(line6_request_version0));
return retval;
}
@@ -1109,8 +1299,27 @@ static int __init line6_init(void)
*/
static void __exit line6_exit(void)
{
- destroy_workqueue(line6_workqueue);
+ int i;
+ struct usb_line6 *line6;
+ struct snd_line6_pcm *line6pcm;
+
+ /* stop all PCM channels */
+ for (i = LINE6_MAX_DEVICES; i--;) {
+ line6 = line6_devices[i];
+
+ if (line6 == NULL)
+ continue;
+
+ line6pcm = line6->line6pcm;
+
+ if (line6pcm == NULL)
+ continue;
+
+ line6_pcm_stop(line6pcm, ~0);
+ }
+
usb_deregister(&line6_driver);
+ kfree(line6_request_version);
}
module_init(line6_init);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
index 9908bfa6afaf..01fa27e75774 100644
--- a/drivers/staging/line6/driver.h
+++ b/drivers/staging/line6/driver.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,24 +12,23 @@
#ifndef DRIVER_H
#define DRIVER_H
-
-#include "config.h"
-
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/wait.h>
#include <sound/core.h>
#include "midi.h"
#define DRIVER_NAME "line6usb"
+#if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM)
+#define CONFIG_LINE6_USB_DUMP_ANY
+#endif
+
#define LINE6_TIMEOUT 1
#define LINE6_MAX_DEVICES 8
#define LINE6_BUFSIZE_LISTEN 32
#define LINE6_MESSAGE_MAXLEN 256
-
/*
Line6 MIDI control commands
*/
@@ -50,16 +49,20 @@
*/
#define LINE6_CHANNEL_DEVICE 0x02
-#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
+#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
#define LINE6_CHANNEL_MASK 0x0f
+#ifdef CONFIG_LINE6_USB_DEBUG
+#define DEBUG_MESSAGES(x) (x)
+#else
+#define DEBUG_MESSAGES(x)
+#endif
#define MISSING_CASE \
printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
__FILE__, __LINE__)
-
#define CHECK_RETURN(x) \
do { \
err = x; \
@@ -67,21 +70,42 @@ do { \
return err; \
} while (0)
+#define CHECK_STARTUP_PROGRESS(x, n) \
+ if((x) >= (n)) \
+ return; \
+ x = (n);
extern const unsigned char line6_midi_id[3];
extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
-extern struct workqueue_struct *line6_workqueue;
static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
-
/**
Common properties of Line6 devices.
*/
struct line6_properties {
+ /**
+ Card id string (maximum 16 characters).
+ This can be used to address the device in ALSA programs as
+ "default:CARD=<id>"
+ */
+ const char *id;
+
+ /**
+ Card short name (maximum 32 characters).
+ */
const char *name;
+
+ /**
+ Bit identifying this device in the line6usb driver.
+ */
int device_bit;
+
+ /**
+ Bit vector defining this device's capabilities in the
+ line6usb driver.
+ */
int capabilities;
};
@@ -172,7 +196,6 @@ struct usb_line6 {
int message_length;
};
-
extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
int code2, int size);
extern ssize_t line6_nop_read(struct device *dev,
@@ -191,14 +214,22 @@ extern int line6_send_raw_message_async(struct usb_line6 *line6,
const char *buffer, int size);
extern int line6_send_sysex_message(struct usb_line6 *line6,
const char *buffer, int size);
+extern int line6_send_sysex_message_async(struct usb_line6 *line6,
+ const char *buffer, int size);
extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
+extern void line6_start_timer(struct timer_list *timer, unsigned int msecs,
+ void (*function) (unsigned long),
+ unsigned long data);
extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
int value);
+extern int line6_version_request_async(struct usb_line6 *line6);
extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
size_t datalen);
+
+#ifdef CONFIG_LINE6_USB_DUMP_ANY
extern void line6_write_hexdump(struct usb_line6 *line6, char dir,
const unsigned char *buffer, int size);
-
+#endif
#endif
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
index cd468c39da5c..60c7bae3ad3c 100644
--- a/drivers/staging/line6/dumprequest.c
+++ b/drivers/staging/line6/dumprequest.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,13 +9,11 @@
*
*/
-#include "driver.h"
-
#include <linux/slab.h>
+#include "driver.h"
#include "dumprequest.h"
-
/*
Set "dump in progress" flag.
*/
@@ -39,17 +37,17 @@ void line6_invalidate_current(struct line6_dump_request *l6dr)
void line6_dump_finished(struct line6_dump_request *l6dr)
{
l6dr->in_progress = LINE6_DUMP_NONE;
- wake_up_interruptible(&l6dr->wait);
+ wake_up(&l6dr->wait);
}
/*
Send an asynchronous channel dump request.
*/
int line6_dump_request_async(struct line6_dump_request *l6dr,
- struct usb_line6 *line6, int num)
+ struct usb_line6 *line6, int num, int dest)
{
int ret;
- line6_invalidate_current(l6dr);
+ line6_dump_started(l6dr, dest);
ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
l6dr->reqbufs[num].length);
@@ -60,43 +58,30 @@ int line6_dump_request_async(struct line6_dump_request *l6dr,
}
/*
- Send an asynchronous dump request after a given interval.
+ Wait for completion (interruptible).
*/
-void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
- void (*function)(unsigned long), void *data)
+int line6_dump_wait_interruptible(struct line6_dump_request *l6dr)
{
- l6dr->timer.expires = jiffies + seconds * HZ;
- l6dr->timer.function = function;
- l6dr->timer.data = (unsigned long)data;
- add_timer(&l6dr->timer);
+ return wait_event_interruptible(l6dr->wait,
+ l6dr->in_progress == LINE6_DUMP_NONE);
}
/*
Wait for completion.
*/
-int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock)
+void line6_dump_wait(struct line6_dump_request *l6dr)
{
- int retval = 0;
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&l6dr->wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
-
- while (l6dr->in_progress) {
- if (nonblock) {
- retval = -EAGAIN;
- break;
- }
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- } else
- schedule();
- }
+ wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE);
+}
- current->state = TASK_RUNNING;
- remove_wait_queue(&l6dr->wait, &wait);
- return retval;
+/*
+ Wait for completion (with timeout).
+*/
+int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout)
+{
+ return wait_event_timeout(l6dr->wait,
+ l6dr->in_progress == LINE6_DUMP_NONE,
+ timeout);
}
/*
@@ -123,7 +108,6 @@ int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
if (ret < 0)
return ret;
init_waitqueue_head(&l6dr->wait);
- init_timer(&l6dr->timer);
return 0;
}
@@ -148,6 +132,4 @@ void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
if (l6dr->reqbufs[0].buffer == NULL)
return;
line6_dumpreq_destructbuf(l6dr, 0);
- l6dr->ok = 1;
- del_timer_sync(&l6dr->timer);
}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
index 1975d54b3c20..c17a262fad2e 100644
--- a/drivers/staging/line6/dumprequest.h
+++ b/drivers/staging/line6/dumprequest.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,19 +12,15 @@
#ifndef DUMPREQUEST_H
#define DUMPREQUEST_H
-
#include <linux/usb.h>
#include <linux/wait.h>
-
#include <sound/core.h>
-
enum {
LINE6_DUMP_NONE,
LINE6_DUMP_CURRENT
};
-
struct line6_dump_reqbuf {
/**
Buffer for dump requests.
@@ -56,16 +52,6 @@ struct line6_dump_request {
int in_progress;
/**
- Timer for delayed dump request.
- */
- struct timer_list timer;
-
- /**
- Flag if initial dump request has been successful.
- */
- char ok;
-
- /**
Dump request buffers
*/
struct line6_dump_reqbuf reqbufs[1];
@@ -73,7 +59,7 @@ struct line6_dump_request {
extern void line6_dump_finished(struct line6_dump_request *l6dr);
extern int line6_dump_request_async(struct line6_dump_request *l6dr,
- struct usb_line6 *line6, int num);
+ struct usb_line6 *line6, int num, int dest);
extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
@@ -82,9 +68,9 @@ extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr,
const void *buf, size_t len, int num);
extern void line6_invalidate_current(struct line6_dump_request *l6dr);
-extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
- void (*function)(unsigned long), void *data);
-extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock);
-
+extern void line6_dump_wait(struct line6_dump_request *l6dr);
+extern int line6_dump_wait_interruptible(struct line6_dump_request *l6dr);
+extern int line6_dump_wait_timeout(struct line6_dump_request *l6dr,
+ long timeout);
#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 32b6ca75cadb..fffd80503776 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,32 +9,23 @@
*
*/
-#include "driver.h"
-
-#include <linux/usb.h>
#include <linux/slab.h>
-
+#include <linux/usb.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include "audio.h"
+#include "driver.h"
#include "midi.h"
#include "pod.h"
#include "usbdefs.h"
-
-#define USE_MIDIBUF 1
-#define OUTPUT_DUMP_ONLY 0
-
-
#define line6_rawmidi_substream_midi(substream) \
((struct snd_line6_midi *)((substream)->rmidi->private_data))
-
static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
int length);
-
/*
Pass data received via USB to MIDI.
*/
@@ -51,7 +42,8 @@ void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
*/
static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
{
- struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ struct usb_line6 *line6 =
+ line6_rawmidi_substream_midi(substream)->line6;
struct snd_line6_midi *line6midi = line6->line6midi;
struct MidiBuffer *mb = &line6midi->midibuf_out;
unsigned long flags;
@@ -61,26 +53,27 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
for (;;) {
- req = min(midibuf_bytes_free(mb), line6->max_packet_size);
+ req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
done = snd_rawmidi_transmit_peek(substream, chunk, req);
if (done == 0)
break;
-#if DO_DUMP_MIDI_SEND
+#ifdef CONFIG_LINE6_USB_DUMP_MIDI
line6_write_hexdump(line6, 's', chunk, done);
#endif
- midibuf_write(mb, chunk, done);
+ line6_midibuf_write(mb, chunk, done);
snd_rawmidi_transmit_ack(substream, done);
}
for (;;) {
- done = midibuf_read(mb, chunk, line6->max_packet_size);
+ done = line6_midibuf_read(mb, chunk, line6->max_packet_size);
if (done == 0)
break;
- if (midibuf_skip_message(mb, line6midi->midi_mask_transmit))
+ if (line6_midibuf_skip_message
+ (mb, line6midi->midi_mask_transmit))
continue;
send_midi_async(line6, chunk, done);
@@ -115,7 +108,7 @@ static void midi_sent(struct urb *urb)
}
if (num == 0)
- wake_up_interruptible(&line6->line6midi->send_wait);
+ wake_up(&line6->line6midi->send_wait);
spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
}
@@ -138,8 +131,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
dev_err(line6->ifcdev, "Out of memory\n");
return -ENOMEM;
}
-
-#if DO_DUMP_URB_SEND
+#ifdef CONFIG_LINE6_USB_DUMP_CTRL
line6_write_hexdump(line6, 'S', data, length);
#endif
@@ -176,8 +168,11 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
case LINE6_DEVID_PODXTLIVE:
case LINE6_DEVID_PODXTPRO:
case LINE6_DEVID_POCKETPOD:
- pod_midi_postprocess((struct usb_line6_pod *)line6, data,
- length);
+ line6_pod_midi_postprocess((struct usb_line6_pod *)line6, data,
+ length);
+ break;
+
+ case LINE6_DEVID_VARIAX:
break;
default:
@@ -201,7 +196,8 @@ static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
int up)
{
unsigned long flags;
- struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ struct usb_line6 *line6 =
+ line6_rawmidi_substream_midi(substream)->line6;
line6->line6midi->substream_transmit = substream;
spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
@@ -214,20 +210,11 @@ static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
{
- struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
- wait_queue_head_t *head = &line6->line6midi->send_wait;
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(head, &wait);
- current->state = TASK_INTERRUPTIBLE;
-
- while (line6->line6midi->num_active_send_urbs > 0)
- if (signal_pending(current))
- break;
- else
- schedule();
-
- current->state = TASK_RUNNING;
- remove_wait_queue(head, &wait);
+ struct usb_line6 *line6 =
+ line6_rawmidi_substream_midi(substream)->line6;
+ struct snd_line6_midi *midi = line6->line6midi;
+ wait_event_interruptible(midi->send_wait,
+ midi->num_active_send_urbs == 0);
}
static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
@@ -243,7 +230,8 @@ static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
int up)
{
- struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ struct usb_line6 *line6 =
+ line6_rawmidi_substream_midi(substream)->line6;
if (up)
line6->line6midi->substream_receive = substream;
@@ -284,12 +272,12 @@ static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
rmidi->private_data = line6midi;
rmidi->private_free = line6_cleanup_midi;
+ strcpy(rmidi->id, line6midi->line6->properties->id);
strcpy(rmidi->name, line6midi->line6->properties->name);
rmidi->info_flags =
- SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
+ SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
&line6_midi_output_ops);
@@ -362,17 +350,21 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
return count;
}
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
+ midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
+ midi_get_midi_mask_receive, midi_set_midi_mask_receive);
/* MIDI device destructor */
static int snd_line6_midi_free(struct snd_device *device)
{
struct snd_line6_midi *line6midi = device->device_data;
- device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
- device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
- midibuf_destroy(&line6midi->midibuf_in);
- midibuf_destroy(&line6midi->midibuf_out);
+ device_remove_file(line6midi->line6->ifcdev,
+ &dev_attr_midi_mask_transmit);
+ device_remove_file(line6midi->line6->ifcdev,
+ &dev_attr_midi_mask_receive);
+ line6_midibuf_destroy(&line6midi->midibuf_in);
+ line6_midibuf_destroy(&line6midi->midibuf_out);
return 0;
}
@@ -389,18 +381,18 @@ int line6_init_midi(struct usb_line6 *line6)
struct snd_line6_midi *line6midi;
if (!(line6->properties->capabilities & LINE6_BIT_CONTROL))
- return 0; /* skip MIDI initialization and report success */
+ return 0; /* skip MIDI initialization and report success */
line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
if (line6midi == NULL)
return -ENOMEM;
- err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
+ err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
if (err < 0)
return err;
- err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
+ err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
if (err < 0)
return err;
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
index c69fd118957b..b73a025d8be9 100644
--- a/drivers/staging/line6/midi.h
+++ b/drivers/staging/line6/midi.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,15 +12,12 @@
#ifndef MIDI_H
#define MIDI_H
-
#include <sound/rawmidi.h>
#include "midibuf.h"
-
#define MIDI_BUFFER_SIZE 1024
-
struct snd_line6_midi {
/**
Pointer back to the Line6 driver data structure.
@@ -78,10 +75,8 @@ struct snd_line6_midi {
struct MidiBuffer midibuf_out;
};
-
extern int line6_init_midi(struct usb_line6 *line6);
extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
int length);
-
#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
index ab0a5f30fbca..7b532e5ce8b4 100644
--- a/drivers/staging/line6/midibuf.c
+++ b/drivers/staging/line6/midibuf.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,13 +9,10 @@
*
*/
-#include "config.h"
-
#include <linux/slab.h>
#include "midibuf.h"
-
static int midibuf_message_length(unsigned char code)
{
if (code < 0x80)
@@ -25,23 +22,34 @@ static int midibuf_message_length(unsigned char code)
return length[(code >> 4) - 8];
} else {
/*
- Note that according to the MIDI specification 0xf2 is
- the "Song Position Pointer", but this is used by Line6
- to send sysex messages to the host.
- */
+ Note that according to the MIDI specification 0xf2 is
+ the "Song Position Pointer", but this is used by Line6
+ to send sysex messages to the host.
+ */
static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
- 1, 1, 1, -1, 1, 1 };
+ 1, 1, 1, -1, 1, 1
+ };
return length[code & 0x0f];
}
}
-void midibuf_reset(struct MidiBuffer *this)
+static int midibuf_is_empty(struct MidiBuffer *this)
+{
+ return (this->pos_read == this->pos_write) && !this->full;
+}
+
+static int midibuf_is_full(struct MidiBuffer *this)
+{
+ return this->full;
+}
+
+void line6_midibuf_reset(struct MidiBuffer *this)
{
this->pos_read = this->pos_write = this->full = 0;
this->command_prev = -1;
}
-int midibuf_init(struct MidiBuffer *this, int size, int split)
+int line6_midibuf_init(struct MidiBuffer *this, int size, int split)
{
this->buf = kmalloc(size, GFP_KERNEL);
@@ -50,44 +58,37 @@ int midibuf_init(struct MidiBuffer *this, int size, int split)
this->size = size;
this->split = split;
- midibuf_reset(this);
+ line6_midibuf_reset(this);
return 0;
}
-void midibuf_status(struct MidiBuffer *this)
+void line6_midibuf_status(struct MidiBuffer *this)
{
printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d "
"full=%d command_prev=%02x\n", this->size, this->split,
this->pos_read, this->pos_write, this->full, this->command_prev);
}
-static int midibuf_is_empty(struct MidiBuffer *this)
-{
- return (this->pos_read == this->pos_write) && !this->full;
-}
-
-static int midibuf_is_full(struct MidiBuffer *this)
-{
- return this->full;
-}
-
-int midibuf_bytes_free(struct MidiBuffer *this)
+int line6_midibuf_bytes_free(struct MidiBuffer *this)
{
return
- midibuf_is_full(this) ?
- 0 :
- (this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
+ midibuf_is_full(this) ?
+ 0 :
+ (this->pos_read - this->pos_write + this->size - 1) % this->size +
+ 1;
}
-int midibuf_bytes_used(struct MidiBuffer *this)
+int line6_midibuf_bytes_used(struct MidiBuffer *this)
{
return
- midibuf_is_empty(this) ?
- 0 :
- (this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
+ midibuf_is_empty(this) ?
+ 0 :
+ (this->pos_write - this->pos_read + this->size - 1) % this->size +
+ 1;
}
-int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
+int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data,
+ int length)
{
int bytes_free;
int length1, length2;
@@ -102,7 +103,7 @@ int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
skip_active_sense = 1;
}
- bytes_free = midibuf_bytes_free(this);
+ bytes_free = line6_midibuf_bytes_free(this);
if (length > bytes_free)
length = bytes_free;
@@ -129,7 +130,7 @@ int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
return length + skip_active_sense;
}
-int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
+int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
{
int bytes_used;
int length1, length2;
@@ -145,7 +146,7 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
if (midibuf_is_empty(this))
return 0;
- bytes_used = midibuf_bytes_used(this);
+ bytes_used = line6_midibuf_bytes_used(this);
if (length > bytes_used)
length = bytes_used;
@@ -160,7 +161,8 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
this->command_prev = command;
} else {
if (this->command_prev > 0) {
- int midi_length_prev = midibuf_message_length(this->command_prev);
+ int midi_length_prev =
+ midibuf_message_length(this->command_prev);
if (midi_length_prev > 0) {
midi_length = midi_length_prev - 1;
@@ -200,15 +202,15 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
}
if (midi_length == length)
- midi_length = -1; /* end of message not found */
+ midi_length = -1; /* end of message not found */
}
if (midi_length < 0) {
if (!this->split)
- return 0; /* command is not yet complete */
+ return 0; /* command is not yet complete */
} else {
if (length < midi_length)
- return 0; /* command is not yet complete */
+ return 0; /* command is not yet complete */
length = midi_length;
}
@@ -232,9 +234,9 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
return length + repeat;
}
-int midibuf_ignore(struct MidiBuffer *this, int length)
+int line6_midibuf_ignore(struct MidiBuffer *this, int length)
{
- int bytes_used = midibuf_bytes_used(this);
+ int bytes_used = line6_midibuf_bytes_used(this);
if (length > bytes_used)
length = bytes_used;
@@ -244,7 +246,7 @@ int midibuf_ignore(struct MidiBuffer *this, int length)
return length;
}
-int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
+int line6_midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
{
int cmd = this->command_prev;
@@ -255,7 +257,7 @@ int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
return 0;
}
-void midibuf_destroy(struct MidiBuffer *this)
+void line6_midibuf_destroy(struct MidiBuffer *this)
{
kfree(this->buf);
this->buf = NULL;
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
index 9877581bcd9a..444cb3a12d72 100644
--- a/drivers/staging/line6/midibuf.h
+++ b/drivers/staging/line6/midibuf.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,7 +12,6 @@
#ifndef MIDIBUF_H
#define MIDIBUF_H
-
struct MidiBuffer {
unsigned char *buf;
int size;
@@ -22,18 +21,18 @@ struct MidiBuffer {
int command_prev;
};
-
-extern int midibuf_bytes_used(struct MidiBuffer *mb);
-extern int midibuf_bytes_free(struct MidiBuffer *mb);
-extern void midibuf_destroy(struct MidiBuffer *mb);
-extern int midibuf_ignore(struct MidiBuffer *mb, int length);
-extern int midibuf_init(struct MidiBuffer *mb, int size, int split);
-extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
-extern void midibuf_reset(struct MidiBuffer *mb);
-extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
-extern void midibuf_status(struct MidiBuffer *mb);
-extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data,
- int length);
-
+extern int line6_midibuf_bytes_used(struct MidiBuffer *mb);
+extern int line6_midibuf_bytes_free(struct MidiBuffer *mb);
+extern void line6_midibuf_destroy(struct MidiBuffer *mb);
+extern int line6_midibuf_ignore(struct MidiBuffer *mb, int length);
+extern int line6_midibuf_init(struct MidiBuffer *mb, int size, int split);
+extern int line6_midibuf_read(struct MidiBuffer *mb, unsigned char *data,
+ int length);
+extern void line6_midibuf_reset(struct MidiBuffer *mb);
+extern int line6_midibuf_skip_message(struct MidiBuffer *mb,
+ unsigned short mask);
+extern void line6_midibuf_status(struct MidiBuffer *mb);
+extern int line6_midibuf_write(struct MidiBuffer *mb, unsigned char *data,
+ int length);
#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index fbe4b083eac5..8fb5596efe9e 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,10 +9,7 @@
*
*/
-#include "driver.h"
-
#include <linux/slab.h>
-
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
@@ -20,9 +17,184 @@
#include "audio.h"
#include "capture.h"
+#include "driver.h"
#include "playback.h"
#include "pod.h"
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+
+static struct snd_line6_pcm *dev2pcm(struct device *dev)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ struct snd_line6_pcm *line6pcm = line6->line6pcm;
+ return line6pcm;
+}
+
+/*
+ "read" request on "impulse_volume" special file.
+*/
+static ssize_t pcm_get_impulse_volume(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);
+}
+
+/*
+ "write" request on "impulse_volume" special file.
+*/
+static ssize_t pcm_set_impulse_volume(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct snd_line6_pcm *line6pcm = dev2pcm(dev);
+ int value = simple_strtoul(buf, NULL, 10);
+ line6pcm->impulse_volume = value;
+
+ if (value > 0)
+ line6_pcm_start(line6pcm, MASK_PCM_IMPULSE);
+ else
+ line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE);
+
+ return count;
+}
+
+/*
+ "read" request on "impulse_period" special file.
+*/
+static ssize_t pcm_get_impulse_period(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);
+}
+
+/*
+ "write" request on "impulse_period" special file.
+*/
+static ssize_t pcm_set_impulse_period(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ dev2pcm(dev)->impulse_period = simple_strtoul(buf, NULL, 10);
+ return count;
+}
+
+static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
+ pcm_set_impulse_volume);
+static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
+ pcm_set_impulse_period);
+
+#endif
+
+int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels)
+{
+ unsigned long flags_old =
+ __sync_fetch_and_or(&line6pcm->flags, channels);
+ unsigned long flags_new = flags_old | channels;
+ int err = 0;
+
+#if LINE6_BACKUP_MONITOR_SIGNAL
+ if (!(line6pcm->line6->properties->capabilities & LINE6_BIT_HWMON)) {
+ line6pcm->prev_fbuf =
+ kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size,
+ GFP_KERNEL);
+
+ if (!line6pcm->prev_fbuf) {
+ dev_err(line6pcm->line6->ifcdev,
+ "cannot malloc monitor buffer\n");
+ return -ENOMEM;
+ }
+ }
+#else
+ line6pcm->prev_fbuf = NULL;
+#endif
+
+ if (((flags_old & MASK_CAPTURE) == 0) &&
+ ((flags_new & MASK_CAPTURE) != 0)) {
+ /*
+ Waiting for completion of active URBs in the stop handler is
+ a bug, we therefore report an error if capturing is restarted
+ too soon.
+ */
+ if (line6pcm->active_urb_in | line6pcm->unlink_urb_in)
+ return -EBUSY;
+
+ line6pcm->buffer_in =
+ kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+ line6pcm->max_packet_size, GFP_KERNEL);
+
+ if (!line6pcm->buffer_in) {
+ dev_err(line6pcm->line6->ifcdev,
+ "cannot malloc capture buffer\n");
+ return -ENOMEM;
+ }
+
+ line6pcm->count_in = 0;
+ line6pcm->prev_fsize = 0;
+ err = line6_submit_audio_in_all_urbs(line6pcm);
+
+ if (err < 0) {
+ __sync_fetch_and_and(&line6pcm->flags, ~channels);
+ return err;
+ }
+ }
+
+ if (((flags_old & MASK_PLAYBACK) == 0) &&
+ ((flags_new & MASK_PLAYBACK) != 0)) {
+ /*
+ See comment above regarding PCM restart.
+ */
+ if (line6pcm->active_urb_out | line6pcm->unlink_urb_out)
+ return -EBUSY;
+
+ line6pcm->buffer_out =
+ kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+ line6pcm->max_packet_size, GFP_KERNEL);
+
+ if (!line6pcm->buffer_out) {
+ dev_err(line6pcm->line6->ifcdev,
+ "cannot malloc playback buffer\n");
+ return -ENOMEM;
+ }
+
+ line6pcm->count_out = 0;
+ err = line6_submit_audio_out_all_urbs(line6pcm);
+
+ if (err < 0) {
+ __sync_fetch_and_and(&line6pcm->flags, ~channels);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels)
+{
+ unsigned long flags_old =
+ __sync_fetch_and_and(&line6pcm->flags, ~channels);
+ unsigned long flags_new = flags_old & ~channels;
+
+ if (((flags_old & MASK_CAPTURE) != 0) &&
+ ((flags_new & MASK_CAPTURE) == 0)) {
+ line6_unlink_audio_in_urbs(line6pcm);
+ kfree(line6pcm->buffer_in);
+ line6pcm->buffer_in = NULL;
+ }
+
+ if (((flags_old & MASK_PLAYBACK) != 0) &&
+ ((flags_new & MASK_PLAYBACK) == 0)) {
+ line6_unlink_audio_out_urbs(line6pcm);
+ kfree(line6pcm->buffer_out);
+ line6pcm->buffer_out = NULL;
+ }
+#if LINE6_BACKUP_MONITOR_SIGNAL
+ if (line6pcm->prev_fbuf != NULL)
+ kfree(line6pcm->prev_fbuf);
+#endif
+
+ return 0;
+}
/* trigger callback */
int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -38,7 +210,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
snd_pcm_group_for_each_entry(s, substream) {
switch (s->stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
- err = snd_line6_playback_trigger(s, cmd);
+ err = snd_line6_playback_trigger(line6pcm, cmd);
if (err < 0) {
spin_unlock_irqrestore(&line6pcm->lock_trigger,
@@ -49,7 +221,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
break;
case SNDRV_PCM_STREAM_CAPTURE:
- err = snd_line6_capture_trigger(s, cmd);
+ err = snd_line6_capture_trigger(line6pcm, cmd);
if (err < 0) {
spin_unlock_irqrestore(&line6pcm->lock_trigger,
@@ -60,8 +232,8 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
break;
default:
- dev_err(s2m(substream), "Unknown stream direction %d\n",
- s->stream);
+ dev_err(line6pcm->line6->ifcdev,
+ "Unknown stream direction %d\n", s->stream);
}
}
@@ -70,8 +242,8 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
}
/* control info callback */
-static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
+static int snd_line6_control_playback_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
@@ -81,28 +253,30 @@ static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
}
/* control get callback */
-static int snd_line6_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int snd_line6_control_playback_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int i;
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
for (i = 2; i--;)
- ucontrol->value.integer.value[i] = line6pcm->volume[i];
+ ucontrol->value.integer.value[i] = line6pcm->volume_playback[i];
return 0;
}
/* control put callback */
-static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
int i, changed = 0;
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
for (i = 2; i--;)
- if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
- line6pcm->volume[i] = ucontrol->value.integer.value[i];
+ if (line6pcm->volume_playback[i] !=
+ ucontrol->value.integer.value[i]) {
+ line6pcm->volume_playback[i] =
+ ucontrol->value.integer.value[i];
changed = 1;
}
@@ -110,14 +284,14 @@ static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
}
/* control definition */
-static struct snd_kcontrol_new line6_control = {
+static struct snd_kcontrol_new line6_control_playback = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Volume",
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_line6_control_info,
- .get = snd_line6_control_get,
- .put = snd_line6_control_put
+ .info = snd_line6_control_playback_info,
+ .get = snd_line6_control_playback_get,
+ .put = snd_line6_control_playback_put
};
/*
@@ -128,6 +302,11 @@ static void line6_cleanup_pcm(struct snd_pcm *pcm)
int i;
struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_volume);
+ device_remove_file(line6pcm->line6->ifcdev, &dev_attr_impulse_period);
+#endif
+
for (i = LINE6_ISO_BUFFERS; i--;) {
if (line6pcm->urb_audio_out[i]) {
usb_kill_urb(line6pcm->urb_audio_out[i]);
@@ -147,8 +326,8 @@ static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
int err;
err = snd_pcm_new(line6pcm->line6->card,
- (char *)line6pcm->line6->properties->name,
- 0, 1, 1, &pcm);
+ (char *)line6pcm->line6->properties->name,
+ 0, 1, 1, &pcm);
if (err < 0)
return err;
@@ -164,8 +343,9 @@ static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
/* pre-allocation of buffers */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64 * 1024, 128 * 1024);
+ snd_dma_continuous_data
+ (GFP_KERNEL), 64 * 1024,
+ 128 * 1024);
return 0;
}
@@ -177,6 +357,29 @@ static int snd_line6_pcm_free(struct snd_device *device)
}
/*
+ Stop substream if still running.
+*/
+static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
+{
+ if (substream->runtime && snd_pcm_running(substream)) {
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+ }
+}
+
+/*
+ Stop PCM stream.
+*/
+void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
+{
+ pcm_disconnect_substream(get_substream
+ (line6pcm, SNDRV_PCM_STREAM_CAPTURE));
+ pcm_disconnect_substream(get_substream
+ (line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
+ line6_unlink_wait_clear_audio_out_urbs(line6pcm);
+ line6_unlink_wait_clear_audio_in_urbs(line6pcm);
+}
+
+/*
Create and register the PCM device and mixer entries.
Create URBs for playback and capture.
*/
@@ -192,7 +395,7 @@ int line6_init_pcm(struct usb_line6 *line6,
struct snd_line6_pcm *line6pcm;
if (!(line6->properties->capabilities & LINE6_BIT_PCM))
- return 0; /* skip PCM initialization and report success */
+ return 0; /* skip PCM initialization and report success */
/* initialize PCM subsystem based on product id: */
switch (line6->product) {
@@ -202,37 +405,40 @@ int line6_init_pcm(struct usb_line6 *line6,
case LINE6_DEVID_PODXT:
case LINE6_DEVID_PODXTLIVE:
case LINE6_DEVID_PODXTPRO:
- ep_read = 0x82;
+ ep_read = 0x82;
ep_write = 0x01;
break;
case LINE6_DEVID_PODX3:
case LINE6_DEVID_PODX3LIVE:
- ep_read = 0x86;
+ ep_read = 0x86;
ep_write = 0x02;
break;
case LINE6_DEVID_POCKETPOD:
- ep_read = 0x82;
+ ep_read = 0x82;
ep_write = 0x02;
break;
case LINE6_DEVID_GUITARPORT:
+ case LINE6_DEVID_PODSTUDIO_GX:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX2:
case LINE6_DEVID_TONEPORT_GX:
- ep_read = 0x82;
- ep_write = 0x01;
- break;
-
case LINE6_DEVID_TONEPORT_UX1:
- ep_read = 0x00;
- ep_write = 0x00;
- break;
-
case LINE6_DEVID_TONEPORT_UX2:
- ep_read = 0x87;
- ep_write = 0x00;
+ ep_read = 0x82;
+ ep_write = 0x01;
break;
+ /* this is for interface_number == 1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_PODSTUDIO_UX2:
+ ep_read = 0x87;
+ ep_write = 0x00;
+ break;
+ */
+
default:
MISSING_CASE;
}
@@ -242,14 +448,14 @@ int line6_init_pcm(struct usb_line6 *line6,
if (line6pcm == NULL)
return -ENOMEM;
- line6pcm->volume[0] = line6pcm->volume[1] = 128;
+ line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
+ line6pcm->volume_monitor = 255;
line6pcm->line6 = line6;
line6pcm->ep_audio_read = ep_read;
line6pcm->ep_audio_write = ep_write;
line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
- usb_rcvintpipe(line6->usbdev,
- ep_read),
- 0);
+ usb_rcvintpipe(line6->usbdev,
+ ep_read), 0);
line6pcm->properties = properties;
line6->line6pcm = line6pcm;
@@ -268,19 +474,34 @@ int line6_init_pcm(struct usb_line6 *line6,
spin_lock_init(&line6pcm->lock_audio_in);
spin_lock_init(&line6pcm->lock_trigger);
- err = create_audio_out_urbs(line6pcm);
+ err = line6_create_audio_out_urbs(line6pcm);
if (err < 0)
return err;
- err = create_audio_in_urbs(line6pcm);
+ err = line6_create_audio_in_urbs(line6pcm);
if (err < 0)
return err;
/* mixer: */
- err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm));
+ err =
+ snd_ctl_add(line6->card,
+ snd_ctl_new1(&line6_control_playback, line6pcm));
+ if (err < 0)
+ return err;
+
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ /* impulse response test: */
+ err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume);
if (err < 0)
return err;
+ err = device_create_file(line6->ifcdev, &dev_attr_impulse_period);
+ if (err < 0)
+ return err;
+
+ line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
+#endif
+
return 0;
}
@@ -290,12 +511,11 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
- unlink_wait_clear_audio_out_urbs(line6pcm);
+ line6pcm->count_out = 0;
line6pcm->pos_out = 0;
line6pcm->pos_out_done = 0;
-
- unlink_wait_clear_audio_in_urbs(line6pcm);
line6pcm->bytes_out = 0;
+ line6pcm->count_in = 0;
line6pcm->pos_in_done = 0;
line6pcm->bytes_in = 0;
}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
index 53db217cd42d..3a50083cb30c 100644
--- a/drivers/staging/line6/pcm.h
+++ b/drivers/staging/line6/pcm.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -16,38 +16,89 @@
#ifndef PCM_H
#define PCM_H
-
#include <sound/pcm.h>
#include "driver.h"
#include "usbdefs.h"
-
/* number of URBs */
-#define LINE6_ISO_BUFFERS 8
+#define LINE6_ISO_BUFFERS 2
-/* number of USB frames per URB */
-#define LINE6_ISO_PACKETS 2
+/*
+ number of USB frames per URB
+ The Line6 Windows driver always transmits two frames per packet, but
+ the Linux driver performs significantly better (i.e., lower latency)
+ with only one frame per packet.
+*/
+#define LINE6_ISO_PACKETS 1
/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
#define LINE6_ISO_INTERVAL 1
-/* this should be queried dynamically from the USB interface! */
-#define LINE6_ISO_PACKET_SIZE_MAX 252
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+#define LINE6_IMPULSE_DEFAULT_PERIOD 100
+#endif
+#define LINE6_BACKUP_MONITOR_SIGNAL 0
+#define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0
/*
- Extract the messaging device from the substream instance
+ Get substream from Line6 PCM data structure
*/
-#define s2m(s) (((struct snd_line6_pcm *) \
- snd_pcm_substream_chip(s))->line6->ifcdev)
-
+#define get_substream(line6pcm, stream) (line6pcm->pcm->streams[stream].substream)
+/*
+ PCM mode bits and masks.
+ "ALSA": operations triggered by applications via ALSA
+ "MONITOR": software monitoring
+ "IMPULSE": optional impulse response operation
+*/
enum {
- BIT_RUNNING_PLAYBACK,
- BIT_RUNNING_CAPTURE,
+ /* individual bits: */
+ BIT_PCM_ALSA_PLAYBACK,
+ BIT_PCM_ALSA_CAPTURE,
+ BIT_PCM_MONITOR_PLAYBACK,
+ BIT_PCM_MONITOR_CAPTURE,
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ BIT_PCM_IMPULSE_PLAYBACK,
+ BIT_PCM_IMPULSE_CAPTURE,
+#endif
BIT_PAUSE_PLAYBACK,
- BIT_PREPARED
+ BIT_PREPARED,
+
+ /* individual masks: */
+/* *INDENT-OFF* */
+ MASK_PCM_ALSA_PLAYBACK = 1 << BIT_PCM_ALSA_PLAYBACK,
+ MASK_PCM_ALSA_CAPTURE = 1 << BIT_PCM_ALSA_CAPTURE,
+ MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK,
+ MASK_PCM_MONITOR_CAPTURE = 1 << BIT_PCM_MONITOR_CAPTURE,
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK,
+ MASK_PCM_IMPULSE_CAPTURE = 1 << BIT_PCM_IMPULSE_CAPTURE,
+#endif
+ MASK_PAUSE_PLAYBACK = 1 << BIT_PAUSE_PLAYBACK,
+ MASK_PREPARED = 1 << BIT_PREPARED,
+/* *INDENT-ON* */
+
+ /* combined masks (by operation): */
+ MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE,
+ MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE,
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE,
+#endif
+
+ /* combined masks (by direction): */
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ MASK_PLAYBACK =
+ MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK |
+ MASK_PCM_IMPULSE_PLAYBACK,
+ MASK_CAPTURE =
+ MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE |
+ MASK_PCM_IMPULSE_CAPTURE
+#else
+ MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK,
+ MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE
+#endif
};
struct line6_pcm_properties {
@@ -83,9 +134,11 @@ struct snd_line6_pcm {
struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
/**
- Temporary buffer to hold data when playback buffer wraps.
+ Temporary buffer for playback.
+ Since the packet size is not known in advance, this buffer is
+ large enough to store maximum size packets.
*/
- unsigned char *wrap_out;
+ unsigned char *buffer_out;
/**
Temporary buffer for capture.
@@ -95,6 +148,21 @@ struct snd_line6_pcm {
unsigned char *buffer_in;
/**
+ Temporary buffer index for playback.
+ */
+ int index_out;
+
+ /**
+ Previously captured frame (for software monitoring).
+ */
+ unsigned char *prev_fbuf;
+
+ /**
+ Size of previously captured frame (for software monitoring).
+ */
+ int prev_fsize;
+
+ /**
Free frame position in the playback buffer.
*/
snd_pcm_uframes_t pos_out;
@@ -204,19 +272,53 @@ struct snd_line6_pcm {
/**
PCM playback volume (left and right).
*/
- int volume[2];
+ int volume_playback[2];
+
+ /**
+ PCM monitor volume.
+ */
+ int volume_monitor;
+
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ /**
+ Volume of impulse response test signal (if zero, test is disabled).
+ */
+ int impulse_volume;
+
+ /**
+ Period of impulse response test signal.
+ */
+ int impulse_period;
+
+ /**
+ Counter for impulse response test signal.
+ */
+ int impulse_count;
+#endif
/**
Several status bits (see BIT_*).
*/
unsigned long flags;
-};
+ int last_frame_in, last_frame_out;
+};
extern int line6_init_pcm(struct usb_line6 *line6,
struct line6_pcm_properties *properties);
extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
extern int snd_line6_prepare(struct snd_pcm_substream *substream);
-
+extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
+extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels);
+extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels);
+
+#define PRINT_FRAME_DIFF(op) { \
+ static int diff_prev = 1000; \
+ int diff = line6pcm->last_frame_out - line6pcm->last_frame_in; \
+ if((diff != diff_prev) && (abs(diff) < 100)) { \
+ printk("%s frame diff = %d\n", op, diff); \
+ diff_prev = diff; \
+ } \
+ }
#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index fbcd6e150aaf..39218d686aa2 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,15 +9,13 @@
*
*/
-#include "driver.h"
-
-#include <linux/slab.h>
-
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "audio.h"
+#include "capture.h"
+#include "driver.h"
#include "pcm.h"
#include "pod.h"
#include "playback.h"
@@ -59,22 +57,93 @@ static void change_volume(struct urb *urb_out, int volume[],
}
}
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+
+/*
+ Create signal for impulse response test.
+*/
+static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
+ struct urb *urb_out, int bytes_per_frame)
+{
+ int frames = urb_out->transfer_buffer_length / bytes_per_frame;
+
+ if (bytes_per_frame == 4) {
+ int i;
+ short *pi = (short *)line6pcm->prev_fbuf;
+ short *po = (short *)urb_out->transfer_buffer;
+
+ for (i = 0; i < frames; ++i) {
+ po[0] = pi[0];
+ po[1] = 0;
+ pi += 2;
+ po += 2;
+ }
+ } else if (bytes_per_frame == 6) {
+ int i, j;
+ unsigned char *pi = line6pcm->prev_fbuf;
+ unsigned char *po = urb_out->transfer_buffer;
+
+ for (i = 0; i < frames; ++i) {
+ for (j = 0; j < bytes_per_frame / 2; ++j)
+ po[j] = pi[j];
+
+ for (; j < bytes_per_frame; ++j)
+ po[j] = 0;
+
+ pi += bytes_per_frame;
+ po += bytes_per_frame;
+ }
+ }
+ if (--line6pcm->impulse_count <= 0) {
+ ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
+ 1] =
+ line6pcm->impulse_volume;
+ line6pcm->impulse_count = line6pcm->impulse_period;
+ }
+}
+
+#endif
+
+/*
+ Add signal to buffer for software monitoring.
+*/
+static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
+ int volume, int bytes_per_frame)
+{
+ if (volume == 0)
+ return; /* zero volume - no change */
+
+ if (bytes_per_frame == 4) {
+ short *pi, *po, *buf_end;
+ pi = (short *)signal;
+ po = (short *)urb_out->transfer_buffer;
+ buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
+
+ for (; po < buf_end; ++pi, ++po)
+ *po += (*pi * volume) >> 8;
+ }
+
+ /*
+ We don't need to handle devices with 6 bytes per frame here
+ since they all support hardware monitoring.
+ */
+}
+
/*
Find a free URB, prepare audio data, and submit URB.
*/
-static int submit_audio_out_urb(struct snd_pcm_substream *substream)
+static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
{
int index;
unsigned long flags;
int i, urb_size, urb_frames;
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int ret;
const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
const int frame_increment =
line6pcm->properties->snd_line6_rates.rats[0].num_min;
const int frame_factor =
line6pcm->properties->snd_line6_rates.rats[0].den *
(USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
- struct snd_pcm_runtime *runtime = substream->runtime;
struct urb *urb_out;
spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
@@ -83,7 +152,7 @@ static int submit_audio_out_urb(struct snd_pcm_substream *substream)
if (index < 0 || index >= LINE6_ISO_BUFFERS) {
spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
- dev_err(s2m(substream), "no free URB found\n");
+ dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
return -EINVAL;
}
@@ -92,24 +161,49 @@ static int submit_audio_out_urb(struct snd_pcm_substream *substream)
for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
/* compute frame size for given sampling rate */
- int n, fs;
+ int fsize = 0;
struct usb_iso_packet_descriptor *fout =
&urb_out->iso_frame_desc[i];
- line6pcm->count_out += frame_increment;
- n = line6pcm->count_out / frame_factor;
- line6pcm->count_out -= n * frame_factor;
- fs = n * bytes_per_frame;
+
+ if (line6pcm->flags & MASK_CAPTURE) {
+ fsize = line6pcm->prev_fsize;
+ }
+
+ if (fsize == 0) {
+ int n;
+ line6pcm->count_out += frame_increment;
+ n = line6pcm->count_out / frame_factor;
+ line6pcm->count_out -= n * frame_factor;
+ fsize = n * bytes_per_frame;
+ }
+
fout->offset = urb_size;
- fout->length = fs;
- urb_size += fs;
+ fout->length = fsize;
+ urb_size += fsize;
+ }
+
+ if (urb_size == 0) {
+ /* can't determine URB size */
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+ dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); /* this is somewhat paranoid */
+ return -EINVAL;
}
urb_frames = urb_size / bytes_per_frame;
+ urb_out->transfer_buffer =
+ line6pcm->buffer_out +
+ line6pcm->max_packet_size * line6pcm->index_out;
+ urb_out->transfer_buffer_length = urb_size;
+ urb_out->context = line6pcm;
+
+ if (++line6pcm->index_out == LINE6_ISO_BUFFERS)
+ line6pcm->index_out = 0;
+
+ if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) &&
+ !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
+ struct snd_pcm_runtime *runtime =
+ get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
- if (test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
- urb_out->transfer_buffer = line6pcm->wrap_out;
- memset(line6pcm->wrap_out, 0, urb_size);
- } else {
if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
/*
The transferred area goes over buffer boundary,
@@ -117,38 +211,69 @@ static int submit_audio_out_urb(struct snd_pcm_substream *substream)
*/
int len;
len = runtime->buffer_size - line6pcm->pos_out;
- urb_out->transfer_buffer = line6pcm->wrap_out;
if (len > 0) {
- memcpy(line6pcm->wrap_out,
+ memcpy(urb_out->transfer_buffer,
runtime->dma_area +
line6pcm->pos_out * bytes_per_frame,
len * bytes_per_frame);
- memcpy(line6pcm->wrap_out +
+ memcpy(urb_out->transfer_buffer +
len * bytes_per_frame, runtime->dma_area,
(urb_frames - len) * bytes_per_frame);
- } else {
- /* this is somewhat paranoid */
- dev_err(s2m(substream),
- "driver bug: len = %d\n", len);
- }
+ } else
+ dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */
} else {
+#if LINE6_REUSE_DMA_AREA_FOR_PLAYBACK
/* set the buffer pointer */
urb_out->transfer_buffer =
runtime->dma_area +
line6pcm->pos_out * bytes_per_frame;
+#else
+ /* copy data */
+ memcpy(urb_out->transfer_buffer,
+ runtime->dma_area +
+ line6pcm->pos_out * bytes_per_frame,
+ urb_out->transfer_buffer_length);
+#endif
}
- }
- line6pcm->pos_out += urb_frames;
- if (line6pcm->pos_out >= runtime->buffer_size)
- line6pcm->pos_out -= runtime->buffer_size;
-
- urb_out->transfer_buffer_length = urb_size;
- urb_out->context = substream;
- change_volume(urb_out, line6pcm->volume, bytes_per_frame);
+ if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
+ line6pcm->pos_out -= runtime->buffer_size;
+ } else {
+ memset(urb_out->transfer_buffer, 0,
+ urb_out->transfer_buffer_length);
+ }
-#if DO_DUMP_PCM_SEND
+ change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame);
+
+ if (line6pcm->prev_fbuf != 0) {
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ if (line6pcm->flags & MASK_PCM_IMPULSE) {
+ create_impulse_test_signal(line6pcm, urb_out,
+ bytes_per_frame);
+ if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) {
+ line6_capture_copy(line6pcm,
+ urb_out->transfer_buffer,
+ urb_out->
+ transfer_buffer_length);
+ line6_capture_check_period(line6pcm,
+ urb_out->transfer_buffer_length);
+ }
+ } else {
+#endif
+ if (!
+ (line6pcm->line6->
+ properties->capabilities & LINE6_BIT_HWMON)
+&& (line6pcm->flags & MASK_PLAYBACK)
+&& (line6pcm->flags & MASK_CAPTURE))
+ add_monitor_signal(urb_out, line6pcm->prev_fbuf,
+ line6pcm->volume_monitor,
+ bytes_per_frame);
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+ }
+#endif
+ }
+#ifdef CONFIG_LINE6_USB_DUMP_PCM
for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
struct usb_iso_packet_descriptor *fout =
&urb_out->iso_frame_desc[i];
@@ -158,11 +283,13 @@ static int submit_audio_out_urb(struct snd_pcm_substream *substream)
}
#endif
- if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
+ ret = usb_submit_urb(urb_out, GFP_ATOMIC);
+
+ if (ret == 0)
set_bit(index, &line6pcm->active_urb_out);
else
- dev_err(s2m(substream), "URB out #%d submission failed\n",
- index);
+ dev_err(line6pcm->line6->ifcdev,
+ "URB out #%d submission failed (%d)\n", index, ret);
spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
return 0;
@@ -171,12 +298,12 @@ static int submit_audio_out_urb(struct snd_pcm_substream *substream)
/*
Submit all currently available playback URBs.
*/
-static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
+int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
{
int ret, i;
for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
- ret = submit_audio_out_urb(substream);
+ ret = submit_audio_out_urb(line6pcm);
if (ret < 0)
return ret;
}
@@ -187,7 +314,7 @@ static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
/*
Unlink all currently active playback URBs.
*/
-static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
{
unsigned int i;
@@ -202,7 +329,7 @@ static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
}
/*
- Wait until unlinking of all currently active playback URBs has been finished.
+ Wait until unlinking of all currently active playback URBs has been finished.
*/
static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
{
@@ -223,17 +350,14 @@ static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
} while (--timeout > 0);
if (alive)
snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-
- line6pcm->active_urb_out = 0;
- line6pcm->unlink_urb_out = 0;
}
/*
Unlink all currently active playback URBs, and wait for finishing.
*/
-void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
{
- unlink_audio_out_urbs(line6pcm);
+ line6_unlink_audio_out_urbs(line6pcm);
wait_clear_audio_out_urbs(line6pcm);
}
@@ -245,10 +369,15 @@ static void audio_out_callback(struct urb *urb)
int i, index, length = 0, shutdown = 0;
unsigned long flags;
+ struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
struct snd_pcm_substream *substream =
- (struct snd_pcm_substream *)urb->context;
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
+ get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
+
+#if USE_CLEAR_BUFFER_WORKAROUND
+ memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
+#endif
+
+ line6pcm->last_frame_out = urb->start_frame;
/* find index of URB */
for (index = LINE6_ISO_BUFFERS; index--;)
@@ -262,32 +391,38 @@ static void audio_out_callback(struct urb *urb)
length += urb->iso_frame_desc[i].length;
spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
- line6pcm->pos_out_done +=
- length / line6pcm->properties->bytes_per_frame;
- if (line6pcm->pos_out_done >= runtime->buffer_size)
- line6pcm->pos_out_done -= runtime->buffer_size;
+ if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) {
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ line6pcm->pos_out_done +=
+ length / line6pcm->properties->bytes_per_frame;
+
+ if (line6pcm->pos_out_done >= runtime->buffer_size)
+ line6pcm->pos_out_done -= runtime->buffer_size;
+ }
clear_bit(index, &line6pcm->active_urb_out);
for (i = LINE6_ISO_PACKETS; i--;)
- if (urb->iso_frame_desc[i].status == -ESHUTDOWN) {
+ if (urb->iso_frame_desc[i].status == -EXDEV) {
shutdown = 1;
break;
}
- if (test_bit(index, &line6pcm->unlink_urb_out))
+ if (test_and_clear_bit(index, &line6pcm->unlink_urb_out))
shutdown = 1;
spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
if (!shutdown) {
- submit_audio_out_urb(substream);
+ submit_audio_out_urb(line6pcm);
- line6pcm->bytes_out += length;
- if (line6pcm->bytes_out >= line6pcm->period_out) {
- line6pcm->bytes_out -= line6pcm->period_out;
- snd_pcm_period_elapsed(substream);
+ if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) {
+ if ((line6pcm->bytes_out +=
+ length) >= line6pcm->period_out) {
+ line6pcm->bytes_out %= line6pcm->period_out;
+ snd_pcm_period_elapsed(substream);
+ }
}
}
}
@@ -300,8 +435,8 @@ static int snd_line6_playback_open(struct snd_pcm_substream *substream)
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- (&line6pcm->properties->
- snd_line6_rates));
+ (&line6pcm->
+ properties->snd_line6_rates));
if (err < 0)
return err;
@@ -340,52 +475,40 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
return ret;
line6pcm->period_out = params_period_bytes(hw_params);
- line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
-
- if (!line6pcm->wrap_out) {
- dev_err(s2m(substream), "cannot malloc wrap_out\n");
- return -ENOMEM;
- }
-
return 0;
}
/* hw_free playback callback */
static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
- unlink_wait_clear_audio_out_urbs(line6pcm);
-
- kfree(line6pcm->wrap_out);
- line6pcm->wrap_out = NULL;
-
return snd_pcm_lib_free_pages(substream);
}
/* trigger playback callback */
-int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
{
- struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
int err;
- line6pcm->count_out = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- if (!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) {
- err = submit_audio_out_all_urbs(substream);
+#ifdef CONFIG_PM
+ case SNDRV_PCM_TRIGGER_RESUME:
+#endif
+ err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK);
- if (err < 0) {
- clear_bit(BIT_RUNNING_PLAYBACK,
- &line6pcm->flags);
- return err;
- }
- }
+ if (err < 0)
+ return err;
break;
case SNDRV_PCM_TRIGGER_STOP:
- if (test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags))
- unlink_audio_out_urbs(line6pcm);
+#ifdef CONFIG_PM
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+#endif
+ err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK);
+
+ if (err < 0)
+ return err;
break;
@@ -424,7 +547,7 @@ struct snd_pcm_ops snd_line6_playback_ops = {
.pointer = snd_line6_playback_pointer,
};
-int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
{
int i;
@@ -444,8 +567,8 @@ int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
urb->dev = line6pcm->line6->usbdev;
urb->pipe =
usb_sndisocpipe(line6pcm->line6->usbdev,
- line6pcm->
- ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
+ line6pcm->ep_audio_write &
+ USB_ENDPOINT_NUMBER_MASK);
urb->transfer_flags = URB_ISO_ASAP;
urb->start_frame = -1;
urb->number_of_packets = LINE6_ISO_PACKETS;
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
index db1e48b3596e..c6f2a172d6f9 100644
--- a/drivers/staging/line6/playback.h
+++ b/drivers/staging/line6/playback.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,19 +12,27 @@
#ifndef PLAYBACK_H
#define PLAYBACK_H
+#include <sound/pcm.h>
#include "driver.h"
-#include <sound/pcm.h>
-
+/*
+ When the TonePort is used with jack in full duplex mode and the outputs are
+ not connected, the software monitor produces an ugly noise since everything
+ written to the output buffer (i.e., the input signal) will be repeated in the
+ next period (sounds like a delay effect). As a workaround, the output buffer
+ is cleared after the data have been read, but there must be a better
+ solution. Until one is found, this workaround can be used to fix the problem.
+*/
+#define USE_CLEAR_BUFFER_WORKAROUND 1
extern struct snd_pcm_ops snd_line6_playback_ops;
-
-extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream,
- int cmd);
-extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-
+extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
+ *line6pcm);
+extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 28f514611abc..e6a1c79cd851 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,20 +9,21 @@
*
*/
-#include "driver.h"
-
#include <linux/slab.h>
+#include <linux/wait.h>
+#include <sound/control.h>
#include "audio.h"
#include "capture.h"
#include "control.h"
+#include "driver.h"
#include "playback.h"
#include "pod.h"
-
#define POD_SYSEX_CODE 3
-#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
+#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
+/* *INDENT-OFF* */
enum {
POD_SYSEX_CLIP = 0x0f,
@@ -45,9 +46,11 @@ enum {
POD_tuner_freq = 0x15,
POD_tuner_note = 0x16,
POD_tuner_pitch = 0x17,
- POD_system_invalid = 0x7fff
+ POD_system_invalid = 0x10000
};
+/* *INDENT-ON* */
+
enum {
POD_DUMP_MEMORY = 2
};
@@ -60,7 +63,6 @@ enum {
POD_BUSY_MIDISEND
};
-
static struct snd_ratden pod_ratden = {
.num_min = 78125,
.num_max = 78125,
@@ -69,54 +71,65 @@ static struct snd_ratden pod_ratden = {
};
static struct line6_pcm_properties pod_pcm_properties = {
- .snd_line6_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = 39062,
- .rate_max = 39063,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 60000,
- .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
- .period_bytes_max = 8192,
- .periods_min = 1,
- .periods_max = 1024
- },
- .snd_line6_capture_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_KNOT,
- .rate_min = 39062,
- .rate_max = 39063,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = 60000,
- .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
- .period_bytes_max = 8192,
- .periods_min = 1,
- .periods_max = 1024
- },
+ .snd_line6_playback_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+#ifdef CONFIG_PM
+ SNDRV_PCM_INFO_RESUME |
+#endif
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 64,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024},
+ .snd_line6_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+#ifdef CONFIG_PM
+ SNDRV_PCM_INFO_RESUME |
+#endif
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 64,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024},
.snd_line6_rates = {
- .nrats = 1,
- .rats = &pod_ratden
- },
+ .nrats = 1,
+ .rats = &pod_ratden},
.bytes_per_frame = POD_BYTES_PER_FRAME
};
-static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
-static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
-static const char pod_version_header[] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
+static const char pod_request_channel[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7
+};
+
+static const char pod_version_header[] = {
+ 0xf2, 0x7e, 0x7f, 0x06, 0x02
+};
+/* forward declarations: */
+static void pod_startup2(unsigned long data);
+static void pod_startup3(struct usb_line6_pod *pod);
+static void pod_startup4(struct usb_line6_pod *pod);
/*
Mark all parameters as dirty and notify waiting processes.
@@ -129,63 +142,11 @@ static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
set_bit(i, pod->param_dirty);
}
-/*
- Send an asynchronous request for the POD firmware version and device ID.
-*/
-static int pod_version_request_async(struct usb_line6_pod *pod)
-{
- return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
-}
-
-static void pod_create_files_work(struct work_struct *work)
-{
- struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
-
- pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
-}
-
-static void pod_startup_timeout(unsigned long arg)
+static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
+ int size)
{
- enum {
- REQUEST_NONE,
- REQUEST_DUMP,
- REQUEST_VERSION
- };
-
- int request = REQUEST_NONE;
- struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
-
- if (pod->dumpreq.ok) {
- if (!pod->versionreq_ok)
- request = REQUEST_VERSION;
- } else {
- if (pod->versionreq_ok)
- request = REQUEST_DUMP;
- else if (pod->startup_count++ & 1)
- request = REQUEST_DUMP;
- else
- request = REQUEST_VERSION;
- }
-
- switch (request) {
- case REQUEST_DUMP:
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
- break;
-
- case REQUEST_VERSION:
- pod_version_request_async(pod);
- break;
-
- default:
- return;
- }
-
- line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
-}
-
-static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
-{
- return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
+ return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
+ size);
}
/*
@@ -218,9 +179,10 @@ static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
}
/*
- Handle SAVE button
+ Handle SAVE button.
*/
-static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
+static void pod_save_button_pressed(struct usb_line6_pod *pod, int type,
+ int index)
{
pod->dirty = 0;
set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
@@ -229,7 +191,7 @@ static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int ind
/*
Process a completely received message.
*/
-void pod_process_message(struct usb_line6_pod *pod)
+void line6_pod_process_message(struct usb_line6_pod *pod)
{
const unsigned char *buf = pod->line6.buffer_message;
@@ -238,10 +200,10 @@ void pod_process_message(struct usb_line6_pod *pod)
case LINE6_PARAM_CHANGE:
case LINE6_PROGRAM_CHANGE:
case LINE6_SYSEX_BEGIN:
- break; /* handle these further down */
+ break; /* handle these further down */
default:
- return; /* ignore all others */
+ return; /* ignore all others */
}
/* process all remaining messages */
@@ -254,7 +216,8 @@ void pod_process_message(struct usb_line6_pod *pod)
if ((buf[1] == POD_amp_model_setup) ||
(buf[1] == POD_effect_setup))
/* these also affect other settings */
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
+ LINE6_DUMP_CURRENT);
break;
@@ -263,7 +226,8 @@ void pod_process_message(struct usb_line6_pod *pod)
pod->channel_num = buf[1];
pod->dirty = 0;
set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
- line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
+ LINE6_DUMP_CURRENT);
break;
case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
@@ -271,54 +235,82 @@ void pod_process_message(struct usb_line6_pod *pod)
if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
switch (buf[5]) {
case POD_SYSEX_DUMP:
- if (pod->line6.message_length == sizeof(pod->prog_data) + 7) {
+ if (pod->line6.message_length ==
+ sizeof(pod->prog_data) + 7) {
switch (pod->dumpreq.in_progress) {
case LINE6_DUMP_CURRENT:
- memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
+ memcpy(&pod->prog_data, buf + 7,
+ sizeof(pod->prog_data));
pod_mark_batch_all_dirty(pod);
- pod->dumpreq.ok = 1;
break;
case POD_DUMP_MEMORY:
- memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
+ memcpy(&pod->prog_data_buf,
+ buf + 7,
+ sizeof
+ (pod->prog_data_buf));
break;
default:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
+ DEBUG_MESSAGES(dev_err
+ (pod->
+ line6.ifcdev,
+ "unknown dump code %02X\n",
+ pod->
+ dumpreq.in_progress));
}
line6_dump_finished(&pod->dumpreq);
+ pod_startup3(pod);
} else
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
- pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "wrong size of channel dump message (%d instead of %d)\n",
+ pod->
+ line6.message_length,
+ (int)
+ sizeof(pod->prog_data) +
+ 7));
break;
- case POD_SYSEX_SYSTEM: {
- short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
+ case POD_SYSEX_SYSTEM:{
+ short value =
+ ((int)buf[7] << 12) | ((int)buf[8]
+ << 8) |
+ ((int)buf[9] << 4) | (int)buf[10];
#define PROCESS_SYSTEM_PARAM(x) \
case POD_ ## x: \
pod->x.value = value; \
- wake_up_interruptible(&pod->x.wait); \
+ wake_up(&pod->x.wait); \
break;
- switch (buf[6]) {
- PROCESS_SYSTEM_PARAM(monitor_level);
- PROCESS_SYSTEM_PARAM(routing);
- PROCESS_SYSTEM_PARAM(tuner_mute);
- PROCESS_SYSTEM_PARAM(tuner_freq);
- PROCESS_SYSTEM_PARAM(tuner_note);
- PROCESS_SYSTEM_PARAM(tuner_pitch);
+ switch (buf[6]) {
+ PROCESS_SYSTEM_PARAM
+ (monitor_level);
+ PROCESS_SYSTEM_PARAM(routing);
+ PROCESS_SYSTEM_PARAM
+ (tuner_mute);
+ PROCESS_SYSTEM_PARAM
+ (tuner_freq);
+ PROCESS_SYSTEM_PARAM
+ (tuner_note);
+ PROCESS_SYSTEM_PARAM
+ (tuner_pitch);
#undef PROCESS_SYSTEM_PARAM
- default:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
- }
+ default:
+ DEBUG_MESSAGES(dev_err
+ (pod->
+ line6.ifcdev,
+ "unknown tuner/system response %02X\n",
+ buf[6]));
+ }
- break;
- }
+ break;
+ }
case POD_SYSEX_FINISH:
/* do we need to respond to this? */
@@ -329,32 +321,40 @@ void pod_process_message(struct usb_line6_pod *pod)
break;
case POD_SYSEX_CLIP:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "audio clipped\n"));
pod->clipping.value = 1;
- wake_up_interruptible(&pod->clipping.wait);
+ wake_up(&pod->clipping.wait);
break;
case POD_SYSEX_STORE:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "message %02X not yet implemented\n",
+ buf[5]));
break;
default:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "unknown sysex message %02X\n",
+ buf[5]));
}
- } else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
- if (pod->versionreq_ok == 0) {
- pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
- pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
- pod->versionreq_ok = 1;
-
- /* Now we know the firmware version, so we schedule a bottom half
- handler to create the special files: */
- INIT_WORK(&pod->create_files_work, pod_create_files_work);
- queue_work(line6_workqueue, &pod->create_files_work);
- } else
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
} else
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
+ if (memcmp
+ (buf, pod_version_header,
+ sizeof(pod_version_header)) == 0) {
+ pod->firmware_version =
+ buf[13] * 100 + buf[14] * 10 + buf[15];
+ pod->device_id =
+ ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
+ buf[10];
+ pod_startup4(pod);
+ } else
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "unknown sysex header\n"));
break;
@@ -362,7 +362,9 @@ void pod_process_message(struct usb_line6_pod *pod)
break;
default:
- DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
+ DEBUG_MESSAGES(dev_err
+ (pod->line6.ifcdev,
+ "POD: unknown message %02X\n", buf[0]));
}
}
@@ -377,7 +379,8 @@ void pod_process_message(struct usb_line6_pod *pod)
*) This method fails if a param change message is "chopped" after the first
byte.
*/
-void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
+void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
+ int length)
{
int i;
@@ -388,8 +391,11 @@ void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int le
if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
line6_invalidate_current(&pod->dumpreq);
break;
- } else if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
- if ((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
+ } else
+ if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST))
+ && (i < length - 1))
+ if ((data[i + 1] == POD_amp_model_setup)
+ || (data[i + 1] == POD_effect_setup)) {
line6_invalidate_current(&pod->dumpreq);
break;
}
@@ -412,19 +418,21 @@ static void pod_send_channel(struct usb_line6_pod *pod, int value)
/*
Transmit PODxt Pro control parameter.
*/
-void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
+void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
+ int value)
{
if (line6_transmit_parameter(&pod->line6, param, value) == 0)
pod_store_parameter(pod, param, value);
- if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
+ if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
line6_invalidate_current(&pod->dumpreq);
}
/*
Resolve value to memory location.
*/
-static int pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
+static int pod_resolve(const char *buf, short block0, short block1,
+ unsigned char *location)
{
unsigned long value;
short block;
@@ -444,7 +452,8 @@ static int pod_resolve(const char *buf, short block0, short block1, unsigned cha
/*
Send command to store channel/effects setup/amp setup to PODxt Pro.
*/
-static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+static ssize_t pod_send_store_command(struct device *dev, const char *buf,
+ size_t count, short block0, short block1)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
@@ -455,14 +464,15 @@ static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_
if (!sysex)
return 0;
- sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
+ sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
if (ret) {
kfree(sysex);
return ret;
}
- memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+ memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf,
+ sizeof(pod->prog_data_buf));
line6_send_sysex_message(&pod->line6, sysex, size);
kfree(sysex);
@@ -473,7 +483,9 @@ static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_
/*
Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
*/
-static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf,
+ size_t count, short block0,
+ short block1)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
@@ -504,14 +516,15 @@ static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, si
/*
Generic get name function.
*/
-static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
+static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str,
+ char *buf)
{
int length = 0;
const char *p1;
char *p2;
char *last_non_space = buf;
- int retval = line6_wait_dump(&pod->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&pod->dumpreq);
if (retval < 0)
return retval;
@@ -566,7 +579,8 @@ static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
+ return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET,
+ buf);
}
/*
@@ -577,7 +591,9 @@ static ssize_t pod_get_name_buf(struct device *dev,
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
+ return get_name_generic(pod,
+ pod->prog_data_buf.header + POD_NAME_OFFSET,
+ buf);
}
/*
@@ -588,7 +604,7 @@ static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr,
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_wait_dump(&pod->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&pod->dumpreq);
if (retval < 0)
return retval;
memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
@@ -606,8 +622,8 @@ static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
if (count != sizeof(pod->prog_data)) {
dev_err(pod->line6.ifcdev,
- "data block must be exactly %zu bytes\n",
- sizeof(pod->prog_data));
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
return -EINVAL;
}
@@ -616,86 +632,116 @@ static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
}
/*
- Request system parameter.
+ Identify system parameters related to the tuner.
+*/
+static bool pod_is_tuner(int code)
+{
+ return
+ (code == POD_tuner_mute) ||
+ (code == POD_tuner_freq) ||
+ (code == POD_tuner_note) || (code == POD_tuner_pitch);
+}
+
+/*
+ Get system parameter (as integer).
@param tuner non-zero, if code refers to a tuner parameter
*/
-static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
+static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value,
+ int code, struct ValueWait *param, int sign)
{
char *sysex;
- int value;
static const int size = 1;
int retval = 0;
- DECLARE_WAITQUEUE(wait, current);
- if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
+ && pod_is_tuner(code))
return -ENODEV;
- /* send value request to tuner: */
+ /* send value request to device: */
param->value = POD_system_invalid;
sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
+
if (!sysex)
- return 0;
+ return -ENOMEM;
+
sysex[SYSEX_DATA_OFS] = code;
line6_send_sysex_message(&pod->line6, sysex, size);
kfree(sysex);
- /* wait for tuner to respond: */
- add_wait_queue(&param->wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
+ /* wait for device to respond: */
+ retval =
+ wait_event_interruptible(param->wait,
+ param->value != POD_system_invalid);
- while (param->value == POD_system_invalid) {
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- } else
- schedule();
- }
+ if (retval < 0)
+ return retval;
- current->state = TASK_RUNNING;
- remove_wait_queue(&param->wait, &wait);
+ *value = sign ? (int)(signed short)param->value : (int)(unsigned short)
+ param->value;
+
+ if (*value == POD_system_invalid)
+ *value = 0; /* don't report uninitialized values */
+
+ return 0;
+}
+
+/*
+ Get system parameter (as string).
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
+ int code, struct ValueWait *param,
+ int sign)
+{
+ int retval, value = 0;
+ retval = pod_get_system_param_int(pod, &value, code, param, sign);
if (retval < 0)
return retval;
- value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
return sprintf(buf, "%d\n", value);
}
/*
- Send system parameter.
+ Send system parameter (from integer).
@param tuner non-zero, if code refers to a tuner parameter
*/
-static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf,
- int count, int code, unsigned short mask,
- int tuner)
+static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
+ int code)
{
char *sysex;
static const int size = 5;
- unsigned short value;
- unsigned long result;
- int ret;
- if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
+ && pod_is_tuner(code))
return -EINVAL;
/* send value to tuner: */
sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
if (!sysex)
- return 0;
-
- ret = strict_strtoul(buf, 10, &result);
- if (ret)
- return ret;
-
- value = result & mask;
+ return -ENOMEM;
sysex[SYSEX_DATA_OFS] = code;
sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
- sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
- sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
- sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
line6_send_sysex_message(&pod->line6, sysex, size);
kfree(sysex);
- return count;
+ return 0;
+}
+
+/*
+ Send system parameter (from string).
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod,
+ const char *buf, int count, int code,
+ unsigned short mask)
+{
+ int retval;
+ unsigned short value = simple_strtoul(buf, NULL, 10) & mask;
+ retval = pod_set_system_param_int(pod, value, code);
+ return (retval < 0) ? retval : count;
}
/*
@@ -706,7 +752,7 @@ static ssize_t pod_get_dump_buf(struct device *dev,
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int retval = line6_wait_dump(&pod->dumpreq, 0);
+ int retval = line6_dump_wait_interruptible(&pod->dumpreq);
if (retval < 0)
return retval;
memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
@@ -725,8 +771,8 @@ static ssize_t pod_set_dump_buf(struct device *dev,
if (count != sizeof(pod->prog_data)) {
dev_err(pod->line6.ifcdev,
- "data block must be exactly %zu bytes\n",
- sizeof(pod->prog_data));
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
return -EINVAL;
}
@@ -900,87 +946,203 @@ static ssize_t pod_wait_for_clip(struct device *dev,
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int err = 0;
- DECLARE_WAITQUEUE(wait, current);
- pod->clipping.value = 0;
- add_wait_queue(&pod->clipping.wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
-
- while (pod->clipping.value == 0) {
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- } else
- schedule();
- }
+ return wait_event_interruptible(pod->clipping.wait,
+ pod->clipping.value != 0);
+}
- current->state = TASK_RUNNING;
- remove_wait_queue(&pod->clipping.wait, &wait);
- return err;
+/*
+ POD startup procedure.
+ This is a sequence of functions with special requirements (e.g., must
+ not run immediately after initialization, must not run in interrupt
+ context). After the last one has finished, the device is ready to use.
+*/
+
+static void pod_startup1(struct usb_line6_pod *pod)
+{
+ CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
+
+ /* delay startup procedure: */
+ line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
+ (unsigned long)pod);
}
-#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static void pod_startup2(unsigned long data)
+{
+ struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
+
+ /* schedule another startup procedure until startup is complete: */
+ if (pod->startup_progress >= POD_STARTUP_LAST)
+ return;
+
+ pod->startup_progress = POD_STARTUP_DUMPREQ;
+ line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
+ (unsigned long)pod);
+
+ /* current channel dump: */
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
+ LINE6_DUMP_CURRENT);
+}
+
+static void pod_startup3(struct usb_line6_pod *pod)
+{
+ struct usb_line6 *line6 = &pod->line6;
+ CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
+
+ /* request firmware version: */
+ line6_version_request_async(line6);
+}
+
+static void pod_startup4(struct usb_line6_pod *pod)
+{
+ CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
+
+ /* schedule work for global work queue: */
+ schedule_work(&pod->startup_work);
+}
+
+static void pod_startup5(struct work_struct *work)
+{
+ struct usb_line6_pod *pod =
+ container_of(work, struct usb_line6_pod, startup_work);
+ struct usb_line6 *line6 = &pod->line6;
+
+ CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
+
+ /* serial number: */
+ line6_read_serial_number(&pod->line6, &pod->serial_number);
+
+ /* ALSA audio interface: */
+ line6_register_audio(line6);
+
+ /* device files: */
+ line6_pod_create_files(pod->firmware_version,
+ line6->properties->device_bit, line6->ifcdev);
+}
+
+#define POD_GET_SYSTEM_PARAM(code, sign) \
static ssize_t pod_get_ ## code(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *interface = to_usb_interface(dev); \
struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, \
- tuner, sign); \
+ return pod_get_system_param_string(pod, buf, POD_ ## code, \
+ &pod->code, sign); \
}
-#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
-POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+#define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \
+POD_GET_SYSTEM_PARAM(code, sign) \
static ssize_t pod_set_ ## code(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct usb_interface *interface = to_usb_interface(dev); \
struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_set_system_param(pod, buf, count, POD_ ## code, mask, \
- tuner); \
+ return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \
}
-POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
-POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
-POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
-POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
+POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0);
+POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0);
+POD_GET_SYSTEM_PARAM(tuner_note, 1);
+POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
#undef GET_SET_SYSTEM_PARAM
#undef GET_SYSTEM_PARAM
/* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
+ pod_set_channel);
static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
+ pod_set_dump_buf);
static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
-static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
+ line6_nop_write);
+static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
+ pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
+ pod_set_monitor_level);
static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
-static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
+ pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
+ pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
+ pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
+ pod_set_routing);
+static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
+ line6_nop_write);
+static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
+ pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
+ pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
+ pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
+ pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
+ pod_set_tuner_mute);
static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
-#if CREATE_RAW_FILE
+#ifdef CONFIG_LINE6_USB_RAW
static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
#endif
+/* control info callback */
+static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 65535;
+ return 0;
+}
+
+/* control get callback */
+static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+ struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+ ucontrol->value.integer.value[0] = pod->monitor_level.value;
+ return 0;
+}
+
+/* control put callback */
+static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+ struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+
+ if (ucontrol->value.integer.value[0] == pod->monitor_level.value)
+ return 0;
+
+ pod->monitor_level.value = ucontrol->value.integer.value[0];
+ pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
+ POD_monitor_level);
+ return 1;
+}
+
+/* control definition */
+static struct snd_kcontrol_new pod_control_monitor = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Monitor Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_pod_control_monitor_info,
+ .get = snd_pod_control_monitor_get,
+ .put = snd_pod_control_monitor_put
+};
+
/*
POD destructor.
*/
@@ -996,10 +1158,11 @@ static void pod_destruct(struct usb_interface *interface)
return;
line6_cleanup_audio(line6);
+ del_timer(&pod->startup_timer);
+ cancel_work_sync(&pod->startup_work);
+
/* free dump request data: */
line6_dumpreq_destruct(&pod->dumpreq);
-
- kfree(pod->buffer_versionreq);
}
/*
@@ -1034,7 +1197,7 @@ static int pod_create_files2(struct device *dev)
CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
-#if CREATE_RAW_FILE
+#ifdef CONFIG_LINE6_USB_RAW
CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
#endif
@@ -1042,13 +1205,17 @@ static int pod_create_files2(struct device *dev)
}
/*
- Init POD device.
+ Try to init POD device.
*/
-int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
+static int pod_try_init(struct usb_interface *interface,
+ struct usb_line6_pod *pod)
{
int err;
struct usb_line6 *line6 = &pod->line6;
+ init_timer(&pod->startup_timer);
+ INIT_WORK(&pod->startup_work, pod_startup5);
+
if ((interface == NULL) || (pod == NULL))
return -ENODEV;
@@ -1070,69 +1237,75 @@ int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
sizeof(pod_request_channel));
if (err < 0) {
dev_err(&interface->dev, "Out of memory\n");
- pod_destruct(interface);
- return -ENOMEM;
- }
-
- pod->buffer_versionreq = kmemdup(pod_request_version,
- sizeof(pod_request_version),
- GFP_KERNEL);
-
- if (pod->buffer_versionreq == NULL) {
- dev_err(&interface->dev, "Out of memory\n");
- pod_destruct(interface);
return -ENOMEM;
}
/* create sysfs entries: */
err = pod_create_files2(&interface->dev);
if (err < 0) {
- pod_destruct(interface);
return err;
}
/* initialize audio system: */
err = line6_init_audio(line6);
if (err < 0) {
- pod_destruct(interface);
return err;
}
/* initialize MIDI subsystem: */
err = line6_init_midi(line6);
if (err < 0) {
- pod_destruct(interface);
return err;
}
/* initialize PCM subsystem: */
err = line6_init_pcm(line6, &pod_pcm_properties);
if (err < 0) {
- pod_destruct(interface);
return err;
}
- /* register audio system: */
- err = line6_register_audio(line6);
+ /* register monitor control: */
+ err =
+ snd_ctl_add(line6->card,
+ snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
if (err < 0) {
- pod_destruct(interface);
return err;
}
+ /*
+ When the sound card is registered at this point, the PODxt Live
+ displays "Invalid Code Error 07", so we do it later in the event
+ handler.
+ */
+
if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
- /* query some data: */
- line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY,
- pod_startup_timeout, pod);
- line6_read_serial_number(&pod->line6, &pod->serial_number);
+ pod->monitor_level.value = POD_system_invalid;
+
+ /* initiate startup procedure: */
+ pod_startup1(pod);
}
return 0;
}
/*
+ Init POD device (and clean up in case of failure).
+*/
+int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
+{
+ int err = pod_try_init(interface, pod);
+
+ if (err < 0) {
+ pod_destruct(interface);
+ }
+
+ return err;
+}
+
+/*
POD device disconnected.
*/
-void pod_disconnect(struct usb_interface *interface)
+void line6_pod_disconnect(struct usb_interface *interface)
{
struct usb_line6_pod *pod;
@@ -1145,14 +1318,14 @@ void pod_disconnect(struct usb_interface *interface)
struct device *dev = &interface->dev;
if (line6pcm != NULL) {
- unlink_wait_clear_audio_out_urbs(line6pcm);
- unlink_wait_clear_audio_in_urbs(line6pcm);
+ line6_pcm_disconnect(line6pcm);
}
if (dev != NULL) {
/* remove sysfs entries: */
- if (pod->versionreq_ok)
- pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
+ line6_pod_remove_files(pod->firmware_version,
+ pod->line6.
+ properties->device_bit, dev);
device_remove_file(dev, &dev_attr_channel);
device_remove_file(dev, &dev_attr_clip);
@@ -1168,7 +1341,8 @@ void pod_disconnect(struct usb_interface *interface)
device_remove_file(dev, &dev_attr_name_buf);
device_remove_file(dev, &dev_attr_retrieve_amp_setup);
device_remove_file(dev, &dev_attr_retrieve_channel);
- device_remove_file(dev, &dev_attr_retrieve_effects_setup);
+ device_remove_file(dev,
+ &dev_attr_retrieve_effects_setup);
device_remove_file(dev, &dev_attr_routing);
device_remove_file(dev, &dev_attr_serial_number);
device_remove_file(dev, &dev_attr_store_amp_setup);
@@ -1179,7 +1353,7 @@ void pod_disconnect(struct usb_interface *interface)
device_remove_file(dev, &dev_attr_tuner_note);
device_remove_file(dev, &dev_attr_tuner_pitch);
-#if CREATE_RAW_FILE
+#ifdef CONFIG_LINE6_USB_RAW
device_remove_file(dev, &dev_attr_raw);
#endif
}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
index 7051ca613819..18b9d08c3288 100644
--- a/drivers/staging/line6/pod.h
+++ b/drivers/staging/line6/pod.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,19 +12,16 @@
#ifndef POD_H
#define POD_H
-
-#include "driver.h"
-
+#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/wait.h>
-#include <linux/workqueue.h>
#include <sound/core.h>
+#include "driver.h"
#include "dumprequest.h"
-
/*
PODxt Live interfaces
*/
@@ -42,163 +39,167 @@
*/
#define POD_CONTROL_SIZE 0x80
#define POD_BUFSIZE_DUMPREQ 7
-#define POD_STARTUP_DELAY 3
+#define POD_STARTUP_DELAY 1000
+/*
+ Stages of POD startup procedure
+*/
+enum {
+ POD_STARTUP_INIT = 1,
+ POD_STARTUP_DUMPREQ,
+ POD_STARTUP_VERSIONREQ,
+ POD_STARTUP_WORKQUEUE,
+ POD_STARTUP_SETUP,
+ POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
+};
/**
- Data structure for values that need to be requested explicitly.
- This is the case for system and tuner settings.
+ Data structure for values that need to be requested explicitly.
+ This is the case for system and tuner settings.
*/
struct ValueWait {
- unsigned short value;
+ int value;
wait_queue_head_t wait;
};
/**
- Binary PodXT Pro program dump
+ Binary PODxt Pro program dump
*/
struct pod_program {
/**
- Header information (including program name).
+ Header information (including program name).
*/
unsigned char header[0x20];
/**
- Program parameters.
+ Program parameters.
*/
unsigned char control[POD_CONTROL_SIZE];
};
struct usb_line6_pod {
/**
- Generic Line6 USB data.
+ Generic Line6 USB data.
*/
struct usb_line6 line6;
/**
- Dump request structure.
+ Dump request structure.
*/
struct line6_dump_request dumpreq;
/**
- Current program number.
+ Current program number.
*/
unsigned char channel_num;
/**
- Current program settings.
+ Current program settings.
*/
struct pod_program prog_data;
/**
- Buffer for data retrieved from or to be stored on PODxt Pro.
+ Buffer for data retrieved from or to be stored on PODxt Pro.
*/
struct pod_program prog_data_buf;
/**
- Buffer for requesting version number.
- */
- unsigned char *buffer_versionreq;
-
- /**
- Tuner mute mode.
+ Tuner mute mode.
*/
struct ValueWait tuner_mute;
/**
- Tuner base frequency (typically 440Hz).
+ Tuner base frequency (typically 440Hz).
*/
struct ValueWait tuner_freq;
/**
- Note received from tuner.
+ Note received from tuner.
*/
struct ValueWait tuner_note;
/**
- Pitch value received from tuner.
+ Pitch value received from tuner.
*/
struct ValueWait tuner_pitch;
/**
- Instrument monitor level.
+ Instrument monitor level.
*/
struct ValueWait monitor_level;
/**
- Audio routing mode.
- 0: send processed guitar
- 1: send clean guitar
- 2: send clean guitar re-amp playback
- 3: send re-amp playback
+ Audio routing mode.
+ 0: send processed guitar
+ 1: send clean guitar
+ 2: send clean guitar re-amp playback
+ 3: send re-amp playback
*/
struct ValueWait routing;
/**
- Wait for audio clipping event.
+ Wait for audio clipping event.
*/
struct ValueWait clipping;
/**
- Bottom-half for creation of sysfs special files.
+ Timer for device initializaton.
*/
- struct work_struct create_files_work;
+ struct timer_list startup_timer;
/**
- Dirty flags for access to parameter data.
+ Work handler for device initializaton.
*/
- unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
+ struct work_struct startup_work;
/**
- Some atomic flags.
+ Current progress in startup procedure.
*/
- unsigned long atomic_flags;
+ int startup_progress;
+
+ /**
+ Dirty flags for access to parameter data.
+ */
+ unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
/**
- Counter for startup process.
+ Some atomic flags.
*/
- int startup_count;
+ unsigned long atomic_flags;
/**
- Serial number of device.
+ Serial number of device.
*/
int serial_number;
/**
- Firmware version (x 100).
+ Firmware version (x 100).
*/
int firmware_version;
/**
- Device ID.
+ Device ID.
*/
int device_id;
/**
- Flag to indicate modification of current program settings.
+ Flag to indicate modification of current program settings.
*/
char dirty;
/**
- Flag if initial firmware version request has been successful.
- */
- char versionreq_ok;
-
- /**
- Flag to enable MIDI postprocessing.
+ Flag to enable MIDI postprocessing.
*/
char midi_postprocess;
};
-
-extern void pod_disconnect(struct usb_interface *interface);
-extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
-extern void pod_midi_postprocess(struct usb_line6_pod *pod,
- unsigned char *data, int length);
-extern void pod_process_message(struct usb_line6_pod *pod);
-extern void pod_receive_parameter(struct usb_line6_pod *pod, int param);
-extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param,
- int value);
-
+extern void line6_pod_disconnect(struct usb_interface *interface);
+extern int line6_pod_init(struct usb_interface *interface,
+ struct usb_line6_pod *pod);
+extern void line6_pod_midi_postprocess(struct usb_line6_pod *pod,
+ unsigned char *data, int length);
+extern void line6_pod_process_message(struct usb_line6_pod *pod);
+extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
+ int value);
#endif
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
index b2a0a85efe69..e9883f6d2ecc 100644
--- a/drivers/staging/line6/revision.h
+++ b/drivers/staging/line6/revision.h
@@ -1,4 +1,4 @@
#ifndef DRIVER_REVISION
/* current subversion revision */
-#define DRIVER_REVISION " (revision 529)"
+#define DRIVER_REVISION " (revision 684)"
#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index e6770ea17936..d4ac734d744f 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
* Emil Myhrman (emil.myhrman@gmail.com)
*
* This program is free software; you can redistribute it and/or
@@ -10,15 +10,19 @@
*
*/
-#include "driver.h"
+#include <linux/wait.h>
+#include <sound/control.h>
#include "audio.h"
#include "capture.h"
+#include "driver.h"
#include "playback.h"
#include "toneport.h"
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
+#define TONEPORT_PCM_DELAY 1
+
static struct snd_ratden toneport_ratden = {
.num_min = 44100,
.num_max = 44100,
@@ -33,6 +37,9 @@ static struct line6_pcm_properties toneport_pcm_properties = {
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
+#ifdef CONFIG_PM
+ SNDRV_PCM_INFO_RESUME |
+#endif
SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_KNOT,
@@ -41,7 +48,7 @@ static struct line6_pcm_properties toneport_pcm_properties = {
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 60000,
- .period_bytes_min = 180 * 4,
+ .period_bytes_min = 64,
.period_bytes_max = 8192,
.periods_min = 1,
.periods_max = 1024},
@@ -50,6 +57,9 @@ static struct line6_pcm_properties toneport_pcm_properties = {
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
+#ifdef CONFIG_PM
+ SNDRV_PCM_INFO_RESUME |
+#endif
SNDRV_PCM_INFO_SYNC_START),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_KNOT,
@@ -58,7 +68,7 @@ static struct line6_pcm_properties toneport_pcm_properties = {
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 60000,
- .period_bytes_min = 188 * 4,
+ .period_bytes_min = 64,
.period_bytes_max = 8192,
.periods_min = 1,
.periods_max = 1024},
@@ -77,6 +87,26 @@ static struct line6_pcm_properties toneport_pcm_properties = {
static int led_red = 0x00;
static int led_green = 0x26;
+struct ToneportSourceInfo {
+ const char *name;
+ int code;
+};
+
+static const struct ToneportSourceInfo toneport_source_info[] = {
+ {"Microphone", 0x0a01},
+ {"Line", 0x0801},
+ {"Instrument", 0x0b01},
+ {"Inst & Mic", 0x0901}
+};
+
+static bool toneport_has_led(short product)
+{
+ return
+ (product == LINE6_DEVID_GUITARPORT) ||
+ (product == LINE6_DEVID_TONEPORT_GX);
+ /* add your device here if you are missing support for the LEDs */
+}
+
static void toneport_update_led(struct device *dev)
{
struct usb_interface *interface = to_usb_interface(dev);
@@ -145,6 +175,120 @@ static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
return 0;
}
+/* monitor info callback */
+static int snd_toneport_monitor_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 256;
+ return 0;
+}
+
+/* monitor get callback */
+static int snd_toneport_monitor_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.integer.value[0] = line6pcm->volume_monitor;
+ return 0;
+}
+
+/* monitor put callback */
+static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+ if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
+ return 0;
+
+ line6pcm->volume_monitor = ucontrol->value.integer.value[0];
+
+ if (line6pcm->volume_monitor > 0)
+ line6_pcm_start(line6pcm, MASK_PCM_MONITOR);
+ else
+ line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
+
+ return 1;
+}
+
+/* source info callback */
+static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ const int size = ARRAY_SIZE(toneport_source_info);
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = size;
+
+ if (uinfo->value.enumerated.item >= size)
+ uinfo->value.enumerated.item = size - 1;
+
+ strcpy(uinfo->value.enumerated.name,
+ toneport_source_info[uinfo->value.enumerated.item].name);
+
+ return 0;
+}
+
+/* source get callback */
+static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+ struct usb_line6_toneport *toneport =
+ (struct usb_line6_toneport *)line6pcm->line6;
+ ucontrol->value.enumerated.item[0] = toneport->source;
+ return 0;
+}
+
+/* source put callback */
+static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+ struct usb_line6_toneport *toneport =
+ (struct usb_line6_toneport *)line6pcm->line6;
+
+ if (ucontrol->value.enumerated.item[0] == toneport->source)
+ return 0;
+
+ toneport->source = ucontrol->value.enumerated.item[0];
+ toneport_send_cmd(toneport->line6.usbdev,
+ toneport_source_info[toneport->source].code, 0x0000);
+ return 1;
+}
+
+static void toneport_start_pcm(unsigned long arg)
+{
+ struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
+ struct usb_line6 *line6 = &toneport->line6;
+ line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR);
+}
+
+/* control definition */
+static struct snd_kcontrol_new toneport_control_monitor = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Monitor Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_toneport_monitor_info,
+ .get = snd_toneport_monitor_get,
+ .put = snd_toneport_monitor_put
+};
+
+/* source selector definition */
+static struct snd_kcontrol_new toneport_control_source = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Capture Source",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_toneport_source_info,
+ .get = snd_toneport_source_get,
+ .put = snd_toneport_source_put
+};
+
/*
Toneport destructor.
*/
@@ -162,14 +306,43 @@ static void toneport_destruct(struct usb_interface *interface)
}
/*
- Init Toneport device.
+ Setup Toneport device.
+*/
+static void toneport_setup(struct usb_line6_toneport *toneport)
+{
+ int ticks;
+ struct usb_line6 *line6 = &toneport->line6;
+ struct usb_device *usbdev = line6->usbdev;
+
+ /* sync time on device with host: */
+ ticks = (int)get_seconds();
+ line6_write_data(line6, 0x80c6, &ticks, 4);
+
+ /* enable device: */
+ toneport_send_cmd(usbdev, 0x0301, 0x0000);
+
+ /* initialize source select: */
+ switch (usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ toneport_send_cmd(usbdev,
+ toneport_source_info[toneport->source].code,
+ 0x0000);
+ }
+
+ if (toneport_has_led(usbdev->descriptor.idProduct))
+ toneport_update_led(&usbdev->dev);
+}
+
+/*
+ Try to init Toneport device.
*/
-int toneport_init(struct usb_interface *interface,
- struct usb_line6_toneport *toneport)
+static int toneport_try_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport)
{
- int err, ticks;
+ int err;
struct usb_line6 *line6 = &toneport->line6;
- struct usb_device *usbdev;
+ struct usb_device *usbdev = line6->usbdev;
if ((interface == NULL) || (toneport == NULL))
return -ENODEV;
@@ -177,64 +350,101 @@ int toneport_init(struct usb_interface *interface,
/* initialize audio system: */
err = line6_init_audio(line6);
if (err < 0) {
- toneport_destruct(interface);
return err;
}
/* initialize PCM subsystem: */
err = line6_init_pcm(line6, &toneport_pcm_properties);
if (err < 0) {
- toneport_destruct(interface);
return err;
}
+ /* register monitor control: */
+ err =
+ snd_ctl_add(line6->card,
+ snd_ctl_new1(&toneport_control_monitor,
+ line6->line6pcm));
+ if (err < 0) {
+ return err;
+ }
+
+ /* register source select control: */
+ switch (usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_PODSTUDIO_UX1:
+ err =
+ snd_ctl_add(line6->card,
+ snd_ctl_new1(&toneport_control_source,
+ line6->line6pcm));
+ if (err < 0) {
+ return err;
+ }
+ }
+
/* register audio system: */
err = line6_register_audio(line6);
if (err < 0) {
- toneport_destruct(interface);
return err;
}
- usbdev = line6->usbdev;
line6_read_serial_number(line6, &toneport->serial_number);
line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
- /* sync time on device with host: */
- ticks = (int)get_seconds();
- line6_write_data(line6, 0x80c6, &ticks, 4);
-
- /*
- seems to work without the first two...
- */
- /* toneport_send_cmd(usbdev, 0x0201, 0x0002); */
- /* toneport_send_cmd(usbdev, 0x0801, 0x0000); */
- /* only one that works for me; on GP, TP might be different? */
- toneport_send_cmd(usbdev, 0x0301, 0x0000);
-
- if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+ if (toneport_has_led(usbdev->descriptor.idProduct)) {
CHECK_RETURN(device_create_file
(&interface->dev, &dev_attr_led_red));
CHECK_RETURN(device_create_file
(&interface->dev, &dev_attr_led_green));
- toneport_update_led(&usbdev->dev);
}
+ toneport_setup(toneport);
+
+ init_timer(&toneport->timer);
+ toneport->timer.expires = jiffies + TONEPORT_PCM_DELAY * HZ;
+ toneport->timer.function = toneport_start_pcm;
+ toneport->timer.data = (unsigned long)toneport;
+ add_timer(&toneport->timer);
+
return 0;
}
/*
+ Init Toneport device (and clean up in case of failure).
+*/
+int line6_toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport)
+{
+ int err = toneport_try_init(interface, toneport);
+
+ if (err < 0) {
+ toneport_destruct(interface);
+ }
+
+ return err;
+}
+
+/*
+ Resume Toneport device after reset.
+*/
+void line6_toneport_reset_resume(struct usb_line6_toneport *toneport)
+{
+ toneport_setup(toneport);
+}
+
+/*
Toneport device disconnected.
*/
-void toneport_disconnect(struct usb_interface *interface)
+void line6_toneport_disconnect(struct usb_interface *interface)
{
struct usb_line6_toneport *toneport;
if (interface == NULL)
return;
+
toneport = usb_get_intfdata(interface);
+ del_timer_sync(&toneport->timer);
- if (toneport->line6.usbdev->descriptor.idProduct !=
- LINE6_DEVID_GUITARPORT) {
+ if (toneport_has_led(toneport->line6.usbdev->descriptor.idProduct)) {
device_remove_file(&interface->dev, &dev_attr_led_red);
device_remove_file(&interface->dev, &dev_attr_led_green);
}
@@ -243,8 +453,8 @@ void toneport_disconnect(struct usb_interface *interface)
struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
if (line6pcm != NULL) {
- unlink_wait_clear_audio_out_urbs(line6pcm);
- unlink_wait_clear_audio_in_urbs(line6pcm);
+ line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
+ line6_pcm_disconnect(line6pcm);
}
}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
index bddc58dd7e3a..8576b7263648 100644
--- a/drivers/staging/line6/toneport.h
+++ b/drivers/staging/line6/toneport.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,34 +12,41 @@
#ifndef TONEPORT_H
#define TONEPORT_H
-
-#include "driver.h"
-
#include <linux/usb.h>
#include <sound/core.h>
+#include "driver.h"
struct usb_line6_toneport {
/**
- Generic Line6 USB data.
+ Generic Line6 USB data.
*/
struct usb_line6 line6;
/**
- Serial number of device.
+ Source selector.
+ */
+ int source;
+
+ /**
+ Serial number of device.
*/
int serial_number;
/**
- Firmware version (x 100).
+ Firmware version (x 100).
*/
int firmware_version;
-};
-
-extern void toneport_disconnect(struct usb_interface *interface);
-extern int toneport_init(struct usb_interface *interface,
- struct usb_line6_toneport *toneport);
+ /**
+ Timer for delayed PCM startup.
+ */
+ struct timer_list timer;
+};
+extern void line6_toneport_disconnect(struct usb_interface *interface);
+extern int line6_toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport);
+extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport);
#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
index c38f31f2f421..a8a43a28a972 100644
--- a/drivers/staging/line6/usbdefs.h
+++ b/drivers/staging/line6/usbdefs.h
@@ -1,5 +1,5 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
* Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
*
@@ -12,7 +12,6 @@
#ifndef USBDEFS_H
#define USBDEFS_H
-
#define LINE6_VENDOR_ID 0x0e41
#define USB_INTERVALS_PER_SECOND 1000
@@ -25,6 +24,9 @@
#define LINE6_DEVID_BASSPODXTPRO 0x4252
#define LINE6_DEVID_GUITARPORT 0x4750
#define LINE6_DEVID_POCKETPOD 0x5051
+#define LINE6_DEVID_PODSTUDIO_GX 0x4153
+#define LINE6_DEVID_PODSTUDIO_UX1 0x4150
+#define LINE6_DEVID_PODSTUDIO_UX2 0x4151
#define LINE6_DEVID_PODX3 0x414a
#define LINE6_DEVID_PODX3LIVE 0x414b
#define LINE6_DEVID_PODXT 0x5044
@@ -35,20 +37,23 @@
#define LINE6_DEVID_TONEPORT_UX2 0x4142
#define LINE6_DEVID_VARIAX 0x534d
-#define LINE6_BIT_BASSPODXT (1 << 0)
-#define LINE6_BIT_BASSPODXTLIVE (1 << 1)
-#define LINE6_BIT_BASSPODXTPRO (1 << 2)
-#define LINE6_BIT_GUITARPORT (1 << 3)
-#define LINE6_BIT_POCKETPOD (1 << 4)
-#define LINE6_BIT_PODX3 (1 << 5)
-#define LINE6_BIT_PODX3LIVE (1 << 6)
-#define LINE6_BIT_PODXT (1 << 7)
-#define LINE6_BIT_PODXTLIVE (1 << 8)
-#define LINE6_BIT_PODXTPRO (1 << 9)
-#define LINE6_BIT_TONEPORT_GX (1 << 10)
-#define LINE6_BIT_TONEPORT_UX1 (1 << 11)
-#define LINE6_BIT_TONEPORT_UX2 (1 << 12)
-#define LINE6_BIT_VARIAX (1 << 13)
+#define LINE6_BIT_BASSPODXT (1 << 0)
+#define LINE6_BIT_BASSPODXTLIVE (1 << 1)
+#define LINE6_BIT_BASSPODXTPRO (1 << 2)
+#define LINE6_BIT_GUITARPORT (1 << 3)
+#define LINE6_BIT_POCKETPOD (1 << 4)
+#define LINE6_BIT_PODSTUDIO_GX (1 << 5)
+#define LINE6_BIT_PODSTUDIO_UX1 (1 << 6)
+#define LINE6_BIT_PODSTUDIO_UX2 (1 << 7)
+#define LINE6_BIT_PODX3 (1 << 8)
+#define LINE6_BIT_PODX3LIVE (1 << 9)
+#define LINE6_BIT_PODXT (1 << 10)
+#define LINE6_BIT_PODXTLIVE (1 << 11)
+#define LINE6_BIT_PODXTPRO (1 << 12)
+#define LINE6_BIT_TONEPORT_GX (1 << 13)
+#define LINE6_BIT_TONEPORT_UX1 (1 << 14)
+#define LINE6_BIT_TONEPORT_UX2 (1 << 15)
+#define LINE6_BIT_VARIAX (1 << 16)
#define LINE6_BITS_PRO (LINE6_BIT_BASSPODXTPRO | \
LINE6_BIT_PODXTPRO)
@@ -66,7 +71,10 @@
#define LINE6_BIT_CONTROL (1 << 0)
/* device supports PCM input/output via USB */
#define LINE6_BIT_PCM (1 << 1)
-#define LINE6_BIT_CONTROL_PCM (LINE6_BIT_CONTROL | LINE6_BIT_PCM)
+/* device support hardware monitoring */
+#define LINE6_BIT_HWMON (1 << 2)
+
+#define LINE6_BIT_CONTROL_PCM_HWMON (LINE6_BIT_CONTROL | LINE6_BIT_PCM | LINE6_BIT_HWMON)
#define LINE6_FALLBACK_INTERVAL 10
#define LINE6_FALLBACK_MAXPACKETSIZE 16
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 58ddbe6393ff..3a46104a14a1 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -9,15 +9,13 @@
*
*/
-#include "driver.h"
-
#include <linux/slab.h>
#include "audio.h"
#include "control.h"
+#include "driver.h"
#include "variax.h"
-
#define VARIAX_SYSEX_CODE 7
#define VARIAX_SYSEX_PARAM 0x3b
#define VARIAX_SYSEX_ACTIVATE 0x2a
@@ -25,25 +23,57 @@
#define VARIAX_MODEL_MESSAGE_LENGTH 199
#define VARIAX_OFFSET_ACTIVATE 7
+/*
+ This message is sent by the device during initialization and identifies
+ the connected guitar model.
+*/
+static const char variax_init_model[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x69, 0x02,
+ 0x00
+};
+
+/*
+ This message is sent by the device during initialization and identifies
+ the connected guitar version.
+*/
+static const char variax_init_version[] = {
+ 0xf0, 0x7e, 0x7f, 0x06, 0x02, 0x00, 0x01, 0x0c,
+ 0x07, 0x00, 0x00, 0x00
+};
+
+/*
+ This message is the last one sent by the device during initialization.
+*/
+static const char variax_init_done[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6b
+};
static const char variax_activate[] = {
0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
0xf7
};
+
static const char variax_request_bank[] = {
0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
};
+
static const char variax_request_model1[] = {
0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
0x00, 0x00, 0x00, 0xf7
};
+
static const char variax_request_model2[] = {
0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
0x00, 0x00, 0x00, 0xf7
};
+/* forward declarations: */
+static int variax_create_files2(struct device *dev);
+static void variax_startup2(unsigned long data);
+static void variax_startup4(unsigned long data);
+static void variax_startup5(unsigned long data);
/*
Decode data transmitted by workbench.
@@ -60,42 +90,108 @@ static void variax_decode(const unsigned char *raw_data, unsigned char *data,
}
}
-static void variax_activate_timeout(unsigned long arg)
+static void variax_activate_async(struct usb_line6_variax *variax, int a)
{
- struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
- variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
sizeof(variax_activate));
}
/*
- Send an asynchronous activation request after a given interval.
+ Variax startup procedure.
+ This is a sequence of functions with special requirements (e.g., must
+ not run immediately after initialization, must not run in interrupt
+ context). After the last one has finished, the device is ready to use.
*/
-static void variax_activate_delayed(struct usb_line6_variax *variax,
- int seconds)
+
+static void variax_startup1(struct usb_line6_variax *variax)
{
- variax->activate_timer.expires = jiffies + seconds * HZ;
- variax->activate_timer.function = variax_activate_timeout;
- variax->activate_timer.data = (unsigned long)variax;
- add_timer(&variax->activate_timer);
+ CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
+
+ /* delay startup procedure: */
+ line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
+ variax_startup2, (unsigned long)variax);
}
-static void variax_startup_timeout(unsigned long arg)
+static void variax_startup2(unsigned long data)
{
- struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+ struct usb_line6 *line6 = &variax->line6;
- if (variax->dumpreq.ok)
+ /* schedule another startup procedure until startup is complete: */
+ if (variax->startup_progress >= VARIAX_STARTUP_LAST)
return;
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
- line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout,
- variax);
+ variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
+ line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
+ variax_startup2, (unsigned long)variax);
+
+ /* request firmware version: */
+ line6_version_request_async(line6);
+}
+
+static void variax_startup3(struct usb_line6_variax *variax)
+{
+ CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
+
+ /* delay startup procedure: */
+ line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
+ variax_startup4, (unsigned long)variax);
+}
+
+static void variax_startup4(unsigned long data)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+ CHECK_STARTUP_PROGRESS(variax->startup_progress,
+ VARIAX_STARTUP_ACTIVATE);
+
+ /* activate device: */
+ variax_activate_async(variax, 1);
+ line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
+ variax_startup5, (unsigned long)variax);
+}
+
+static void variax_startup5(unsigned long data)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
+ CHECK_STARTUP_PROGRESS(variax->startup_progress,
+ VARIAX_STARTUP_DUMPREQ);
+
+ /* current model dump: */
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
+ VARIAX_DUMP_PASS1);
+ /* passes 2 and 3 are performed implicitly before entering variax_startup6 */
+}
+
+static void variax_startup6(struct usb_line6_variax *variax)
+{
+ CHECK_STARTUP_PROGRESS(variax->startup_progress,
+ VARIAX_STARTUP_WORKQUEUE);
+
+ /* schedule work for global work queue: */
+ schedule_work(&variax->startup_work);
+}
+
+static void variax_startup7(struct work_struct *work)
+{
+ struct usb_line6_variax *variax =
+ container_of(work, struct usb_line6_variax, startup_work);
+ struct usb_line6 *line6 = &variax->line6;
+
+ CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
+
+ /* ALSA audio interface: */
+ line6_register_audio(&variax->line6);
+
+ /* device files: */
+ line6_variax_create_files(0, 0, line6->ifcdev);
+ variax_create_files2(line6->ifcdev);
}
/*
Process a completely received message.
*/
-void variax_process_message(struct usb_line6_variax *variax)
+void line6_variax_process_message(struct usb_line6_variax *variax)
{
const unsigned char *buf = variax->line6.buffer_message;
@@ -115,12 +211,12 @@ void variax_process_message(struct usb_line6_variax *variax)
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
variax->model = buf[1];
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
+ VARIAX_DUMP_PASS1);
break;
case LINE6_RESET:
dev_info(variax->line6.ifcdev, "VARIAX reset\n");
- variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
break;
case LINE6_SYSEX_BEGIN:
@@ -130,32 +226,65 @@ void variax_process_message(struct usb_line6_variax *variax)
VARIAX_MODEL_MESSAGE_LENGTH) {
switch (variax->dumpreq.in_progress) {
case VARIAX_DUMP_PASS1:
- variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
- (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 1);
- line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2);
+ variax_decode(buf +
+ VARIAX_MODEL_HEADER_LENGTH,
+ (unsigned char *)
+ &variax->model_data,
+ (sizeof
+ (variax->model_data.
+ name) +
+ sizeof(variax->
+ model_data.
+ control)
+ / 2) * 2);
+ line6_dump_request_async
+ (&variax->dumpreq, &variax->line6,
+ 1, VARIAX_DUMP_PASS2);
break;
case VARIAX_DUMP_PASS2:
/* model name is transmitted twice, so skip it here: */
- variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
- (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
- sizeof(variax->model_data.control) / 2 * 2);
- variax->dumpreq.ok = 1;
- line6_dump_request_async(&variax->dumpreq, &variax->line6, 2);
- line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3);
+ variax_decode(buf +
+ VARIAX_MODEL_HEADER_LENGTH,
+ (unsigned char *)
+ &variax->
+ model_data.control +
+ sizeof(variax->model_data.
+ control)
+ / 2,
+ sizeof(variax->model_data.
+ control)
+ / 2 * 2);
+ line6_dump_request_async
+ (&variax->dumpreq, &variax->line6,
+ 2, VARIAX_DUMP_PASS3);
}
} else {
- DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
+ DEBUG_MESSAGES(dev_err
+ (variax->line6.ifcdev,
+ "illegal length %d of model data\n",
+ variax->line6.message_length));
line6_dump_finished(&variax->dumpreq);
}
} else if (memcmp(buf + 1, variax_request_bank + 1,
- sizeof(variax_request_bank) - 2) == 0) {
+ sizeof(variax_request_bank) - 2) == 0) {
memcpy(variax->bank,
buf + sizeof(variax_request_bank) - 1,
sizeof(variax->bank));
- variax->dumpreq.ok = 1;
line6_dump_finished(&variax->dumpreq);
+ variax_startup6(variax);
+ } else if (memcmp(buf + 1, variax_init_model + 1,
+ sizeof(variax_init_model) - 1) == 0) {
+ memcpy(variax->guitar,
+ buf + sizeof(variax_init_model),
+ sizeof(variax->guitar));
+ } else if (memcmp(buf + 1, variax_init_version + 1,
+ sizeof(variax_init_version) - 1) == 0) {
+ variax_startup3(variax);
+ } else if (memcmp(buf + 1, variax_init_done + 1,
+ sizeof(variax_init_done) - 1) == 0) {
+ /* notify of complete initialization: */
+ variax_startup4((unsigned long)variax);
}
break;
@@ -164,7 +293,9 @@ void variax_process_message(struct usb_line6_variax *variax)
break;
default:
- DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
+ DEBUG_MESSAGES(dev_err
+ (variax->line6.ifcdev,
+ "Variax: unknown message %02X\n", buf[0]));
}
}
@@ -174,7 +305,8 @@ void variax_process_message(struct usb_line6_variax *variax)
static ssize_t variax_get_volume(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
return sprintf(buf, "%d\n", variax->volume);
}
@@ -185,7 +317,8 @@ static ssize_t variax_set_volume(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
unsigned long value;
int ret;
@@ -206,7 +339,8 @@ static ssize_t variax_set_volume(struct device *dev,
static ssize_t variax_get_model(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
return sprintf(buf, "%d\n", variax->model);
}
@@ -217,7 +351,8 @@ static ssize_t variax_set_model(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
unsigned long value;
int ret;
@@ -237,8 +372,10 @@ static ssize_t variax_set_model(struct device *dev,
static ssize_t variax_get_active(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
- return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n",
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
}
/*
@@ -248,7 +385,8 @@ static ssize_t variax_set_active(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
unsigned long value;
int ret;
@@ -256,9 +394,7 @@ static ssize_t variax_set_active(struct device *dev,
if (ret)
return ret;
- variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0;
- line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
- sizeof(variax_activate));
+ variax_activate_async(variax, value ? 1 : 0);
return count;
}
@@ -268,7 +404,8 @@ static ssize_t variax_set_active(struct device *dev,
static ssize_t variax_get_tone(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
return sprintf(buf, "%d\n", variax->tone);
}
@@ -279,7 +416,8 @@ static ssize_t variax_set_tone(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
unsigned long value;
int ret;
@@ -316,8 +454,9 @@ static ssize_t get_string(char *buf, const char *data, int length)
static ssize_t variax_get_name(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
- line6_wait_dump(&variax->dumpreq, 0);
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
+ line6_dump_wait_interruptible(&variax->dumpreq);
return get_string(buf, variax->model_data.name,
sizeof(variax->model_data.name));
}
@@ -328,8 +467,9 @@ static ssize_t variax_get_name(struct device *dev,
static ssize_t variax_get_bank(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
- line6_wait_dump(&variax->dumpreq, 0);
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
+ line6_dump_wait_interruptible(&variax->dumpreq);
return get_string(buf, variax->bank, sizeof(variax->bank));
}
@@ -339,9 +479,10 @@ static ssize_t variax_get_bank(struct device *dev,
static ssize_t variax_get_dump(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
int retval;
- retval = line6_wait_dump(&variax->dumpreq, 0);
+ retval = line6_dump_wait_interruptible(&variax->dumpreq);
if (retval < 0)
return retval;
memcpy(buf, &variax->model_data.control,
@@ -349,7 +490,25 @@ static ssize_t variax_get_dump(struct device *dev,
return sizeof(variax->model_data.control);
}
-#if CREATE_RAW_FILE
+/*
+ "read" request on "guitar" special file.
+*/
+static ssize_t variax_get_guitar(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%s\n", variax->guitar);
+}
+
+#ifdef CONFIG_LINE6_USB_RAW
+
+static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
+ int code, int size)
+{
+ return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
+ size);
+}
/*
"write" request on "raw" special file.
@@ -358,7 +517,8 @@ static ssize_t variax_set_raw2(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ struct usb_line6_variax *variax =
+ usb_get_intfdata(to_usb_interface(dev));
int size;
int i;
char *sysex;
@@ -389,20 +549,23 @@ static ssize_t variax_set_raw2(struct device *dev,
#endif
/* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
+ variax_set_model);
+static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
+ variax_set_volume);
static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
+static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
+ variax_set_active);
+static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
-#if CREATE_RAW_FILE
+#ifdef CONFIG_LINE6_USB_RAW
static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
#endif
-
/*
Variax destructor.
*/
@@ -418,13 +581,16 @@ static void variax_destruct(struct usb_interface *interface)
return;
line6_cleanup_audio(line6);
+ del_timer(&variax->startup_timer1);
+ del_timer(&variax->startup_timer2);
+ cancel_work_sync(&variax->startup_work);
+
/* free dump request data: */
line6_dumpreq_destructbuf(&variax->dumpreq, 2);
line6_dumpreq_destructbuf(&variax->dumpreq, 1);
line6_dumpreq_destruct(&variax->dumpreq);
kfree(variax->buffer_activate);
- del_timer_sync(&variax->activate_timer);
}
/*
@@ -440,7 +606,8 @@ static int variax_create_files2(struct device *dev)
CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
CHECK_RETURN(device_create_file(dev, &dev_attr_active));
-#if CREATE_RAW_FILE
+ CHECK_RETURN(device_create_file(dev, &dev_attr_guitar));
+#ifdef CONFIG_LINE6_USB_RAW
CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
#endif
@@ -448,13 +615,17 @@ static int variax_create_files2(struct device *dev)
}
/*
- Init workbench device.
+ Try to init workbench device.
*/
-int variax_init(struct usb_interface *interface,
- struct usb_line6_variax *variax)
+static int variax_try_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax)
{
int err;
+ init_timer(&variax->startup_timer1);
+ init_timer(&variax->startup_timer2);
+ INIT_WORK(&variax->startup_work, variax_startup7);
+
if ((interface == NULL) || (variax == NULL))
return -ENODEV;
@@ -464,7 +635,6 @@ int variax_init(struct usb_interface *interface,
if (err < 0) {
dev_err(&interface->dev, "Out of memory\n");
- variax_destruct(interface);
return err;
}
@@ -473,7 +643,6 @@ int variax_init(struct usb_interface *interface,
if (err < 0) {
dev_err(&interface->dev, "Out of memory\n");
- variax_destruct(interface);
return err;
}
@@ -482,7 +651,6 @@ int variax_init(struct usb_interface *interface,
if (err < 0) {
dev_err(&interface->dev, "Out of memory\n");
- variax_destruct(interface);
return err;
}
@@ -491,56 +659,45 @@ int variax_init(struct usb_interface *interface,
if (variax->buffer_activate == NULL) {
dev_err(&interface->dev, "Out of memory\n");
- variax_destruct(interface);
return -ENOMEM;
}
- init_timer(&variax->activate_timer);
-
- /* create sysfs entries: */
- err = variax_create_files(0, 0, &interface->dev);
- if (err < 0) {
- variax_destruct(interface);
- return err;
- }
-
- err = variax_create_files2(&interface->dev);
- if (err < 0) {
- variax_destruct(interface);
- return err;
- }
-
/* initialize audio system: */
err = line6_init_audio(&variax->line6);
if (err < 0) {
- variax_destruct(interface);
return err;
}
/* initialize MIDI subsystem: */
err = line6_init_midi(&variax->line6);
if (err < 0) {
- variax_destruct(interface);
return err;
}
- /* register audio system: */
- err = line6_register_audio(&variax->line6);
+ /* initiate startup procedure: */
+ variax_startup1(variax);
+ return 0;
+}
+
+/*
+ Init workbench device (and clean up in case of failure).
+*/
+int line6_variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax)
+{
+ int err = variax_try_init(interface, variax);
+
if (err < 0) {
variax_destruct(interface);
- return err;
}
- variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
- line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY,
- variax_startup_timeout, variax);
- return 0;
+ return err;
}
/*
Workbench device disconnected.
*/
-void variax_disconnect(struct usb_interface *interface)
+void line6_variax_disconnect(struct usb_interface *interface)
{
struct device *dev;
@@ -550,7 +707,7 @@ void variax_disconnect(struct usb_interface *interface)
if (dev != NULL) {
/* remove sysfs entries: */
- variax_remove_files(0, 0, dev);
+ line6_variax_remove_files(0, 0, dev);
device_remove_file(dev, &dev_attr_model);
device_remove_file(dev, &dev_attr_volume);
device_remove_file(dev, &dev_attr_tone);
@@ -558,7 +715,8 @@ void variax_disconnect(struct usb_interface *interface)
device_remove_file(dev, &dev_attr_bank);
device_remove_file(dev, &dev_attr_dump);
device_remove_file(dev, &dev_attr_active);
-#if CREATE_RAW_FILE
+ device_remove_file(dev, &dev_attr_guitar);
+#ifdef CONFIG_LINE6_USB_RAW
device_remove_file(dev, &dev_attr_raw);
device_remove_file(dev, &dev_attr_raw2);
#endif
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
index ee330ba30898..e2999ab41b08 100644
--- a/drivers/staging/line6/variax.h
+++ b/drivers/staging/line6/variax.h
@@ -1,7 +1,7 @@
/*
- * Line6 Linux USB driver - 0.8.0
+ * Line6 Linux USB driver - 0.9.1beta
*
- * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -12,21 +12,31 @@
#ifndef VARIAX_H
#define VARIAX_H
-
-#include "driver.h"
-
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/wait.h>
-
#include <sound/core.h>
+#include "driver.h"
#include "dumprequest.h"
+#define VARIAX_STARTUP_DELAY1 1000
+#define VARIAX_STARTUP_DELAY3 100
+#define VARIAX_STARTUP_DELAY4 100
-#define VARIAX_ACTIVATE_DELAY 10
-#define VARIAX_STARTUP_DELAY 3
-
+/*
+ Stages of Variax startup procedure
+*/
+enum {
+ VARIAX_STARTUP_INIT = 1,
+ VARIAX_STARTUP_VERSIONREQ,
+ VARIAX_STARTUP_WAIT,
+ VARIAX_STARTUP_ACTIVATE,
+ VARIAX_STARTUP_DUMPREQ,
+ VARIAX_STARTUP_WORKQUEUE,
+ VARIAX_STARTUP_SETUP,
+ VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
+};
enum {
VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
@@ -34,75 +44,89 @@ enum {
VARIAX_DUMP_PASS3
};
-
/**
- Binary Variax model dump
+ Binary Variax model dump
*/
struct variax_model {
/**
- Header information (including program name).
+ Header information (including program name).
*/
unsigned char name[18];
/**
- Model parameters.
+ Model parameters.
*/
unsigned char control[78 * 2];
};
struct usb_line6_variax {
/**
- Generic Line6 USB data.
+ Generic Line6 USB data.
*/
struct usb_line6 line6;
/**
- Dump request structure.
- Append two extra buffers for 3-pass data query.
+ Dump request structure.
+ Append two extra buffers for 3-pass data query.
*/
- struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
+ struct line6_dump_request dumpreq;
+ struct line6_dump_reqbuf extrabuf[2];
/**
- Buffer for activation code.
+ Buffer for activation code.
*/
unsigned char *buffer_activate;
/**
- Model number.
+ Model number.
*/
int model;
/**
- Current model settings.
+ Current model settings.
*/
struct variax_model model_data;
/**
- Name of current model bank.
+ Name of connected guitar.
+ */
+ unsigned char guitar[18];
+
+ /**
+ Name of current model bank.
*/
unsigned char bank[18];
/**
- Position of volume dial.
+ Position of volume dial.
*/
int volume;
/**
- Position of tone control dial.
+ Position of tone control dial.
*/
int tone;
/**
- Timer for delayed activation request.
+ Handler for device initializaton.
*/
- struct timer_list activate_timer;
-};
+ struct work_struct startup_work;
+ /**
+ Timers for device initializaton.
+ */
+ struct timer_list startup_timer1;
+ struct timer_list startup_timer2;
-extern void variax_disconnect(struct usb_interface *interface);
-extern int variax_init(struct usb_interface *interface,
- struct usb_line6_variax *variax);
-extern void variax_process_message(struct usb_line6_variax *variax);
+ /**
+ Current progress in startup procedure.
+ */
+ int startup_progress;
+};
+extern void line6_variax_disconnect(struct usb_interface *interface);
+extern int line6_variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax);
+extern void line6_variax_process_message(struct usb_line6_variax *variax);
#endif
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c
index 66493253042e..33ffc6dfc71f 100644
--- a/drivers/staging/lirc/lirc_imon.c
+++ b/drivers/staging/lirc/lirc_imon.c
@@ -115,7 +115,8 @@ static const struct file_operations display_fops = {
.owner = THIS_MODULE,
.open = &display_open,
.write = &vfd_write,
- .release = &display_close
+ .release = &display_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
@@ -277,7 +278,7 @@ static int display_close(struct inode *inode, struct file *file)
struct imon_context *context = NULL;
int retval = 0;
- context = (struct imon_context *)file->private_data;
+ context = file->private_data;
if (!context) {
err("%s: no context for device", __func__);
@@ -320,7 +321,6 @@ static int send_packet(struct imon_context *context)
unsigned int pipe;
int interval = 0;
int retval = 0;
- struct usb_ctrlrequest *control_req = NULL;
/* Check if we need to use control or interrupt urb */
pipe = usb_sndintpipe(context->usbdev,
@@ -355,8 +355,6 @@ static int send_packet(struct imon_context *context)
err("%s: packet tx failed (%d)", __func__, retval);
}
- kfree(control_req);
-
return retval;
}
@@ -383,7 +381,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
int *data_buf;
- context = (struct imon_context *)file->private_data;
+ context = file->private_data;
if (!context) {
err("%s: no context for device", __func__);
return -ENODEV;
@@ -599,7 +597,7 @@ static void imon_incoming_packet(struct imon_context *context,
struct device *dev = context->driver->dev;
int octet, bit;
unsigned char mask;
- int i, chunk_num;
+ int i;
/*
* just bail out if no listening IR client
@@ -658,7 +656,7 @@ static void imon_incoming_packet(struct imon_context *context,
}
}
- if (chunk_num == 10) {
+ if (buf[7] == 10) {
if (context->rx.count) {
submit_data(context);
context->rx.count = 0;
@@ -876,7 +874,7 @@ static int imon_probe(struct usb_interface *interface,
if (lirc_minor < 0) {
err("%s: lirc_register_driver failed", __func__);
alloc_status = 7;
- goto alloc_status_switch;
+ goto unlock;
} else
dev_info(dev, "Registered iMON driver "
"(lirc minor: %d)\n", lirc_minor);
@@ -932,8 +930,9 @@ static int imon_probe(struct usb_interface *interface,
"usb<%d:%d> initialized\n", vendor, product, ifnum,
usbdev->bus->busnum, usbdev->devnum);
-alloc_status_switch:
+unlock:
mutex_unlock(&context->ctx_lock);
+alloc_status_switch:
switch (alloc_status) {
case 7:
diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c
index ec11c0e949a0..07d216dc8437 100644
--- a/drivers/staging/lirc/lirc_it87.c
+++ b/drivers/staging/lirc/lirc_it87.c
@@ -342,6 +342,7 @@ static const struct file_operations lirc_fops = {
.unlocked_ioctl = lirc_ioctl,
.open = lirc_open,
.release = lirc_close,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int set_use_inc(void *data)
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
index 73166c3f581f..e84b1c10ab68 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/lirc/lirc_sasem.c
@@ -125,6 +125,7 @@ static const struct file_operations vfd_fops = {
.write = &vfd_write,
.unlocked_ioctl = &vfd_ioctl,
.release = &vfd_close,
+ .llseek = noop_llseek,/* no read or write fn */
};
/* USB Device ID for Sasem USB Control Board */
@@ -386,8 +387,10 @@ static ssize_t vfd_write(struct file *file, const char *buf,
}
data_buf = memdup_user(buf, n_bytes);
- if (PTR_ERR(data_buf))
- return PTR_ERR(data_buf);
+ if (PTR_ERR(data_buf)) {
+ retval = PTR_ERR(data_buf);
+ goto exit;
+ }
memcpy(context->tx.data_buf, data_buf, n_bytes);
@@ -512,7 +515,7 @@ exit:
mutex_unlock(&context->ctx_lock);
mutex_unlock(&disconnect_lock);
- return 0;
+ return retval;
}
/**
@@ -803,7 +806,8 @@ static int sasem_probe(struct usb_interface *interface,
if (lirc_minor < 0) {
err("%s: lirc_register_driver failed", __func__);
alloc_status = 7;
- mutex_unlock(&context->ctx_lock);
+ retval = lirc_minor;
+ goto unlock;
} else
printk(KERN_INFO "%s: Registered Sasem driver (minor:%d)\n",
__func__, lirc_minor);
@@ -828,7 +832,7 @@ alloc_status_switch:
context = NULL;
case 1:
retval = -ENOMEM;
- goto exit;
+ goto unlock;
}
/* Needed while unregistering! */
@@ -859,7 +863,7 @@ alloc_status_switch:
printk(KERN_INFO "%s: Sasem device on usb<%d:%d> initialized\n",
__func__, dev->bus->busnum, dev->devnum);
-
+unlock:
mutex_unlock(&context->ctx_lock);
exit:
return retval;
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c
index 9456f8e3f9ef..8da382492612 100644
--- a/drivers/staging/lirc/lirc_serial.c
+++ b/drivers/staging/lirc/lirc_serial.c
@@ -1058,6 +1058,7 @@ static const struct file_operations lirc_fops = {
.poll = lirc_dev_fop_poll,
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
+ .llseek = no_llseek,
};
static struct lirc_driver driver = {
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c
index eb08fa7138ba..2478871bd95e 100644
--- a/drivers/staging/lirc/lirc_sir.c
+++ b/drivers/staging/lirc/lirc_sir.c
@@ -459,6 +459,7 @@ static const struct file_operations lirc_fops = {
.unlocked_ioctl = lirc_ioctl,
.open = lirc_dev_fop_open,
.release = lirc_dev_fop_close,
+ .llseek = no_llseek,
};
static int set_use_inc(void *data)
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index 100caab10451..9b77552f566e 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -716,7 +716,7 @@ static loff_t lseek(struct file *filep, loff_t offset, int orig)
/* copied from lirc_dev */
static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
{
- struct IR *ir = (struct IR *)filep->private_data;
+ struct IR *ir = filep->private_data;
unsigned char buf[ir->buf.chunk_size];
int ret = 0, written = 0;
DECLARE_WAITQUEUE(wait, current);
@@ -898,7 +898,7 @@ done:
static ssize_t write(struct file *filep, const char *buf, size_t n,
loff_t *ppos)
{
- struct IR *ir = (struct IR *)filep->private_data;
+ struct IR *ir = filep->private_data;
size_t i;
int failures = 0;
@@ -972,7 +972,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
/* copied from lirc_dev */
static unsigned int poll(struct file *filep, poll_table *wait)
{
- struct IR *ir = (struct IR *)filep->private_data;
+ struct IR *ir = filep->private_data;
unsigned int ret;
dprintk("poll called\n");
@@ -994,7 +994,7 @@ static unsigned int poll(struct file *filep, poll_table *wait)
static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
- struct IR *ir = (struct IR *)filep->private_data;
+ struct IR *ir = filep->private_data;
int result;
unsigned long mode, features = 0;
@@ -1086,7 +1086,7 @@ static int open(struct inode *node, struct file *filep)
static int close(struct inode *node, struct file *filep)
{
/* find our IR struct */
- struct IR *ir = (struct IR *)filep->private_data;
+ struct IR *ir = filep->private_data;
if (ir == NULL) {
zilog_error("close: no private_data attached to the file!\n");
return -ENODEV;
diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c
index a98b3f1f11e0..3371b4c4ea2a 100644
--- a/drivers/staging/memrar/memrar_handler.c
+++ b/drivers/staging/memrar/memrar_handler.c
@@ -890,6 +890,7 @@ static const struct file_operations memrar_fops = {
.mmap = memrar_mmap,
.open = memrar_open,
.release = memrar_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice memrar_miscdev = {
diff --git a/drivers/staging/mrst-touchscreen/Kconfig b/drivers/staging/mrst-touchscreen/Kconfig
deleted file mode 100644
index c2af49217084..000000000000
--- a/drivers/staging/mrst-touchscreen/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config TOUCHSCREEN_INTEL_MID
- tristate "Intel MID platform resistive touchscreen"
- depends on INTEL_SCU_IPC
- default y
- help
- Say Y here if you have a Intel MID based touchscreen
- If unsure, say N.
diff --git a/drivers/staging/mrst-touchscreen/Makefile b/drivers/staging/mrst-touchscreen/Makefile
deleted file mode 100644
index 2d638b0d70bf..000000000000
--- a/drivers/staging/mrst-touchscreen/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) := intel_mid_touch.o
-
-
diff --git a/drivers/staging/mrst-touchscreen/TODO b/drivers/staging/mrst-touchscreen/TODO
deleted file mode 100644
index 7157028d634a..000000000000
--- a/drivers/staging/mrst-touchscreen/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-- Move the driver to not think it is SPI (requires fixing some of the SFI
- and firmware side)
diff --git a/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/drivers/staging/mrst-touchscreen/intel-mid-touch.c
deleted file mode 100644
index abba22f921be..000000000000
--- a/drivers/staging/mrst-touchscreen/intel-mid-touch.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * intel_mid_touch.c - Intel MID Resistive Touch Screen Driver
- *
- * Copyright (C) 2008 Intel Corp
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; ifnot, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
- * Ramesh Agarwal (ramesh.agarwal@intel.com)
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * TODO:
- * kill off mrstouch_debug eventually
- * review conversion of r/m/w sequences
- * Replace interrupt mutex abuse
- * Kill of mrstouchdevp pointer
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/param.h>
-#include <linux/spi/spi.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <asm/intel_scu_ipc.h>
-
-
-#if defined(MRSTOUCH_DEBUG)
-#define mrstouch_debug(fmt, args...)\
- do { \
- printk(KERN_DEBUG "\n[MRSTOUCH(%d)] - ", __LINE__); \
- printk(KERN_DEBUG fmt, ##args); \
- } while (0);
-#else
-#define mrstouch_debug(fmt, args...)
-#endif
-
-/* PMIC Interrupt registers */
-#define PMIC_REG_ID1 0x00 /*PMIC ID1 register */
-
-/* PMIC Interrupt registers */
-#define PMIC_REG_INT 0x04 /*PMIC interrupt register */
-#define PMIC_REG_MINT 0x05 /*PMIC interrupt mask register */
-
-/* ADC Interrupt registers */
-#define PMIC_REG_ADCINT 0x5F /*ADC interrupt register */
-#define PMIC_REG_MADCINT 0x60 /*ADC interrupt mask register */
-
-/* ADC Control registers */
-#define PMIC_REG_ADCCNTL1 0x61 /*ADC control register */
-
-/* ADC Channel Selection registers */
-#define PMICADDR0 0xA4
-#define END_OF_CHANNEL 0x1F
-
-/* ADC Result register */
-#define PMIC_REG_ADCSNS0H 0x64
-
-/* ADC channels for touch screen */
-#define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */
-#define MRST_TS_CHAN11 0xB /* Touch screen X- connection */
-#define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */
-#define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */
-
-/* Touch screen coordinate constants */
-#define TOUCH_PRESSURE 50
-#define TOUCH_PRESSURE_FS 100
-
-#define XMOVE_LIMIT 5
-#define YMOVE_LIMIT 5
-#define XYMOVE_CNT 3
-
-#define MAX_10BIT ((1<<10)-1)
-
-/* Touch screen channel BIAS constants */
-#define XBIAS 0x20
-#define YBIAS 0x40
-#define ZBIAS 0x80
-
-/* Touch screen coordinates */
-#define MIN_X 10
-#define MAX_X 1024
-#define MIN_Y 10
-#define MAX_Y 1024
-#define WAIT_ADC_COMPLETION 10
-
-/* PMIC ADC round robin delays */
-#define ADC_LOOP_DELAY0 0x0 /* Continuous loop */
-#define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */
-
-/* PMIC Vendor Identifiers */
-#define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */
-#define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */
-#define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */
-#define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */
-
-/* Touch screen device structure */
-struct mrstouch_dev {
- struct spi_device *spi; /* SPI device associated with touch screen */
- struct input_dev *input; /* input device for touchscreen*/
- char phys[32]; /* Device name */
- struct task_struct *pendet_thrd; /* PENDET interrupt handler */
- struct mutex lock; /* Sync between interrupt and PENDET handler */
- bool busy; /* Busy flag */
- u16 asr; /* Address selection register */
- int irq; /* Touch screen IRQ # */
- uint vendor; /* PMIC vendor */
- uint rev; /* PMIC revision */
- bool suspended; /* Device suspended status */
- bool disabled; /* Device disabled status */
- u16 x; /* X coordinate */
- u16 y; /* Y coordinate */
- bool pendown; /* PEN position */
-} ;
-
-
-/* Global Pointer to Touch screen device */
-static struct mrstouch_dev *mrstouchdevp;
-
-/* Utility to read PMIC ID */
-static int mrstouch_pmic_id(uint *vendor, uint *rev)
-{
- int err;
- u8 r;
-
- err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r);
- if (err)
- return err;
-
- *vendor = r & 0x7;
- *rev = (r >> 3) & 0x7;
-
- return 0;
-}
-
-/*
- * Parse ADC channels to find end of the channel configured by other ADC user
- * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
- */
-static int mrstouch_chan_parse(struct mrstouch_dev *tsdev)
-{
- int err, i, j, found;
- u32 r32;
-
- found = -1;
-
- for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) {
- if (found >= 0)
- break;
-
- err = intel_scu_ipc_ioread32(PMICADDR0, &r32);
- if (err)
- return err;
-
- for (j = 0; j < 32; j+= 8) {
- if (((r32 >> j) & 0xFF) == END_OF_CHANNEL) {
- found = i;
- break;
- }
- }
- }
- if (found < 0)
- return 0;
-
- if (tsdev->vendor == PMIC_VENDOR_FS) {
- if (found && found > (MRSTOUCH_MAX_CHANNELS - 18))
- return -ENOSPC;
- } else {
- if (found && found > (MRSTOUCH_MAX_CHANNELS - 4))
- return -ENOSPC;
- }
- return found;
-}
-
-/* Utility to enable/disable pendet.
- * pendet set to true enables PENDET interrupt
- * pendet set to false disables PENDET interrupt
- * Also clears RND mask bit
-*/
-static int pendet_enable(struct mrstouch_dev *tsdev, bool pendet)
-{
- u16 reg;
- u8 r;
- u8 pendet_enabled = 0;
- int retry = 0;
- int err;
-
- err = intel_scu_ipc_ioread16(PMIC_REG_MADCINT, &reg);
- if (err)
- return err;
-
- if (pendet) {
- reg &= ~0x0005;
- reg |= 0x2000; /* Enable pendet */
- } else
- reg &= 0xDFFF; /* Disable pendet */
-
- /* Set MADCINT and update ADCCNTL1 (next reg byte) */
- err = intel_scu_ipc_iowrite16(PMIC_REG_MADCINT, reg);
- if (!pendet || err)
- return err;
-
- /*
- * Sometimes even after the register write succeeds
- * the PMIC register value is not updated. Retry few iterations
- * to enable pendet.
- */
-
- err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r);
- pendet_enabled = (r >> 5) & 0x01;
-
- retry = 0;
- while (!err && !pendet_enabled) {
- retry++;
- msleep(10);
- err = intel_scu_ipc_iowrite8(PMIC_REG_ADCCNTL1, reg >> 8);
- if (err)
- break;
- err = intel_scu_ipc_ioread8(PMIC_REG_ADCCNTL1, &r);
- if (err == 0)
- pendet_enabled = (r >> 5) & 0x01;
- if (retry >= 10) {
- dev_err(&tsdev->spi->dev, "Touch screen disabled.\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-/* To read PMIC ADC touch screen result
- * Reads ADC storage registers for higher 7 and lower 3 bits
- * converts the two readings to single value and turns off gain bit
- */
-static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm)
-{
- int err;
- u16 result;
- u32 res;
-
- result = PMIC_REG_ADCSNS0H + offset;
-
- if (chan == MRST_TS_CHAN12)
- result += 4;
-
- err = intel_scu_ipc_ioread32(result, &res);
- if (err)
- return err;
-
- /* Mash the bits up */
-
- *vp = (res & 0xFF) << 3; /* Highest 7 bits */
- *vp |= (res >> 8) & 0x07; /* Lower 3 bits */
- *vp &= 0x3FF;
-
- res >>= 16;
-
- *vm = (res & 0xFF) << 3; /* Highest 7 bits */
- *vm |= (res >> 8) & 0x07; /* Lower 3 bits */
- *vm &= 0x3FF;
-
- return 0;
-}
-
-/* To configure touch screen channels
- * Writes touch screen channels to ADC address selection registers
- */
-static int mrstouch_ts_chan_set(uint offset)
-{
- int count;
- u16 chan;
- u16 reg[5];
- u8 data[5];
-
- chan = PMICADDR0 + offset;
- for (count = 0; count <= 3; count++) {
- reg[count] = chan++;
- data[count] = MRST_TS_CHAN10 + count;
- }
- reg[count] = chan;
- data[count] = END_OF_CHANNEL;
-
- return intel_scu_ipc_writev(reg, data, 5);
-}
-
-/* Initialize ADC */
-static int mrstouch_adc_init(struct mrstouch_dev *tsdev)
-{
- int err, start;
- u8 ra, rm;
-
- err = mrstouch_pmic_id(&tsdev->vendor, &tsdev->rev);
- if (err) {
- dev_err(&tsdev->spi->dev, "Unable to read PMIC id\n");
- return err;
- }
-
- start = mrstouch_chan_parse(tsdev);
- if (start < 0) {
- dev_err(&tsdev->spi->dev, "Unable to parse channels\n");
- return start;
- }
-
- tsdev->asr = start;
-
- mrstouch_debug("Channel offset(%d): 0x%X\n", tsdev->asr, tsdev->vendor);
-
- /* ADC power on, start, enable PENDET and set loop delay
- * ADC loop delay is set to 4.5 ms approximately
- * Loop delay more than this results in jitter in adc readings
- * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
- * interrupt generation sometimes.
- */
-
- if (tsdev->vendor == PMIC_VENDOR_FS) {
- ra = 0xE0 | ADC_LOOP_DELAY0;
- rm = 0x5;
- } else {
- /* NEC and MAXIm not consistent with loop delay 0 */
- ra = 0xE0 | ADC_LOOP_DELAY1;
- rm = 0x0;
-
- /* configure touch screen channels */
- err = mrstouch_ts_chan_set(tsdev->asr);
- if (err)
- return err;
- }
- err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7);
- if (err == 0)
- err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03);
- return err;
-}
-
-/* Reports x,y coordinates to event subsystem */
-static void mrstouch_report_xy(struct mrstouch_dev *tsdev, u16 x, u16 y, u16 z)
-{
- int xdiff, ydiff;
-
- if (tsdev->pendown && z <= TOUCH_PRESSURE) {
- /* Pen removed, report button release */
- mrstouch_debug("BTN REL(%d)", z);
- input_report_key(tsdev->input, BTN_TOUCH, 0);
- tsdev->pendown = false;
- }
-
- xdiff = abs(x - tsdev->x);
- ydiff = abs(y - tsdev->y);
-
- /*
- if x and y values changes for XYMOVE_CNT readings it is considered
- as stylus is moving. This is required to differentiate between stylus
- movement and jitter
- */
- if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) {
- /* Spurious values, release button if touched and return */
- if (tsdev->pendown) {
- mrstouch_debug("BTN REL(%d)", z);
- input_report_key(tsdev->input, BTN_TOUCH, 0);
- tsdev->pendown = false;
- }
- return;
- } else if (xdiff >= XMOVE_LIMIT || ydiff >= YMOVE_LIMIT) {
- tsdev->x = x;
- tsdev->y = y;
-
- input_report_abs(tsdev->input, ABS_X, x);
- input_report_abs(tsdev->input, ABS_Y, y);
- input_sync(tsdev->input);
- }
-
-
- if (!tsdev->pendown && z > TOUCH_PRESSURE) {
- /* Pen touched, report button touch */
- mrstouch_debug("BTN TCH(%d, %d, %d)", x, y, z);
- input_report_key(tsdev->input, BTN_TOUCH, 1);
- tsdev->pendown = true;
- }
-}
-
-
-/* Utility to start ADC, used by freescale handler */
-static int pendet_mask(void)
-{
- return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02);
-}
-
-/* Utility to stop ADC, used by freescale handler */
-static int pendet_umask(void)
-{
- return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02);
-}
-
-/* Utility to read ADC, used by freescale handler */
-static int mrstouch_pmic_fs_adc_read(struct mrstouch_dev *tsdev)
-{
- int err;
- u16 x, y, z, result;
- u16 reg[4];
- u8 data[4];
-
- result = PMIC_REG_ADCSNS0H + tsdev->asr;
-
- reg[0] = result + 4;
- reg[1] = result + 5;
- reg[2] = result + 16;
- reg[3] = result + 17;
-
- err = intel_scu_ipc_readv(reg, data, 4);
- if (err)
- goto ipc_error;
-
- x = data[0] << 3; /* Higher 7 bits */
- x |= data[1] & 0x7; /* Lower 3 bits */
- x &= 0x3FF;
-
- y = data[2] << 3; /* Higher 7 bits */
- y |= data[3] & 0x7; /* Lower 3 bits */
- y &= 0x3FF;
-
- /* Read Z value */
- reg[0] = result + 28;
- reg[1] = result + 29;
-
- err = intel_scu_ipc_readv(reg, data, 4);
- if (err)
- goto ipc_error;
-
- z = data[0] << 3; /* Higher 7 bits */
- z |= data[1] & 0x7; /* Lower 3 bits */
- z &= 0x3FF;
-
-#if defined(MRSTOUCH_PRINT_XYZP)
- mrstouch_debug("X: %d, Y: %d, Z: %d", x, y, z);
-#endif
-
- if (z >= TOUCH_PRESSURE_FS) {
- mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE - 1); /* Pen Removed */
- return TOUCH_PRESSURE - 1;
- } else {
- mrstouch_report_xy(tsdev, x, y, TOUCH_PRESSURE + 1); /* Pen Touched */
- return TOUCH_PRESSURE + 1;
- }
-
- return 0;
-
-ipc_error:
- dev_err(&tsdev->spi->dev, "ipc error during fs_adc read\n");
- return err;
-}
-
-/* To handle free scale pmic pendet interrupt */
-static int pmic0_pendet(void *dev_id)
-{
- int err, count;
- u16 chan;
- unsigned int touched;
- struct mrstouch_dev *tsdev = (struct mrstouch_dev *)dev_id;
- u16 reg[5];
- u8 data[5];
-
- chan = PMICADDR0 + tsdev->asr;
-
- /* Set X BIAS */
- for (count = 0; count <= 3; count++) {
- reg[count] = chan++;
- data[count] = 0x2A;
- }
- reg[count] = chan++; /* Dummy */
- data[count] = 0;
-
- err = intel_scu_ipc_writev(reg, data, 5);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /* Set Y BIAS */
- for (count = 0; count <= 3; count++) {
- reg[count] = chan++;
- data[count] = 0x4A;
- }
- reg[count] = chan++; /* Dummy */
- data[count] = 0;
-
- err = intel_scu_ipc_writev(reg, data, 5);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /* Set Z BIAS */
- err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /*Read touch screen channels till pen removed
- * Freescale reports constant value of z for all points
- * z is high when screen is not touched and low when touched
- * Map high z value to not touched and low z value to pen touched
- */
- touched = mrstouch_pmic_fs_adc_read(tsdev);
- while (touched > TOUCH_PRESSURE) {
- touched = mrstouch_pmic_fs_adc_read(tsdev);
- msleep(WAIT_ADC_COMPLETION);
- }
-
- /* Clear all TS channels */
- chan = PMICADDR0 + tsdev->asr;
- for (count = 0; count <= 4; count++) {
- reg[count] = chan++;
- data[count] = 0;
- }
- err = intel_scu_ipc_writev(reg, data, 5);
- if (err)
- goto ipc_error;
-
- for (count = 0; count <= 4; count++) {
- reg[count] = chan++;
- data[count] = 0;
- }
- err = intel_scu_ipc_writev(reg, data, 5);
- if (err)
- goto ipc_error;
-
- err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000);
- if (err)
- goto ipc_error;
-
- return 0;
-
-ipc_error:
- dev_err(&tsdev->spi->dev, "ipc error during pendet\n");
- return err;
-}
-
-
-/* To enable X, Y and Z bias values
- * Enables YPYM for X channels and XPXM for Y channels
- */
-static int mrstouch_ts_bias_set(uint offset, uint bias)
-{
- int count;
- u16 chan, start;
- u16 reg[4];
- u8 data[4];
-
- chan = PMICADDR0 + offset;
- start = MRST_TS_CHAN10;
-
- for (count = 0; count <= 3; count++) {
- reg[count] = chan++;
- data[count] = bias | (start + count);
- }
- return intel_scu_ipc_writev(reg, data, 4);
-}
-
-/* To read touch screen channel values */
-static int mrstouch_adc_read(struct mrstouch_dev *tsdev)
-{
- int err;
- u16 xp, xm, yp, ym, zp, zm;
-
- /* configure Y bias for X channels */
- err = mrstouch_ts_bias_set(tsdev->asr, YBIAS);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /* read x+ and x- channels */
- err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &xp, &xm);
- if (err)
- goto ipc_error;
-
- /* configure x bias for y channels */
- err = mrstouch_ts_bias_set(tsdev->asr, XBIAS);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /* read y+ and y- channels */
- err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, &yp, &ym);
- if (err)
- goto ipc_error;
-
- /* configure z bias for x and y channels */
- err = mrstouch_ts_bias_set(tsdev->asr, ZBIAS);
- if (err)
- goto ipc_error;
-
- msleep(WAIT_ADC_COMPLETION);
-
- /* read z+ and z- channels */
- err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, &zp, &zm);
- if (err)
- goto ipc_error;
-
-#if defined(MRSTOUCH_PRINT_XYZP)
- printk(KERN_INFO "X+: %d, Y+: %d, Z+: %d\n", xp, yp, zp);
-#endif
-
-#if defined(MRSTOUCH_PRINT_XYZM)
- printk(KERN_INFO "X-: %d, Y-: %d, Z-: %d\n", xm, ym, zm);
-#endif
-
- mrstouch_report_xy(tsdev, xp, yp, zp); /* report x and y to eventX */
-
- return zp;
-
-ipc_error:
- dev_err(&tsdev->spi->dev, "ipc error during adc read\n");
- return err;
-}
-
-/* PENDET interrupt handler function for NEC and MAXIM */
-static void pmic12_pendet(void *data)
-{
- unsigned int touched;
- struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data;
-
- /* read touch screen channels till pen removed */
- do {
- touched = mrstouch_adc_read(tsdev);
- } while (touched > TOUCH_PRESSURE);
-}
-
-/* Handler to process PENDET interrupt */
-int mrstouch_pendet(void *data)
-{
- struct mrstouch_dev *tsdev = (struct mrstouch_dev *)data;
- while (1) {
- /* Wait for PENDET interrupt */
- if (mutex_lock_interruptible(&tsdev->lock)) {
- msleep(WAIT_ADC_COMPLETION);
- continue;
- }
-
- if (tsdev->busy)
- return 0;
-
- tsdev->busy = true;
-
- if (tsdev->vendor == PMIC_VENDOR_NEC ||
- tsdev->vendor == PMIC_VENDOR_MAXIM) {
- /* PENDET must be disabled in NEC before reading ADC */
- pendet_enable(tsdev,false); /* Disbale PENDET */
- pmic12_pendet(tsdev);
- pendet_enable(tsdev, true); /*Enable PENDET */
- } else if (tsdev->vendor == PMIC_VENDOR_FS) {
- pendet_umask(); /* Stop ADC */
- pmic0_pendet(tsdev);
- pendet_mask(); /* Stop ADC */
- } else
- dev_err(&tsdev->spi->dev, "Unsupported touchscreen: %d\n",
- tsdev->vendor);
-
- tsdev->busy = false;
-
- }
- return 0;
-}
-
-/* PENDET interrupt handler */
-static irqreturn_t pendet_intr_handler(int irq, void *handle)
-{
- struct mrstouch_dev *tsdev = (struct mrstouch_dev *)handle;
-
- mutex_unlock(&tsdev->lock);
- return IRQ_HANDLED;
-}
-
-/* Intializes input device and registers with input subsystem */
-static int ts_input_dev_init(struct mrstouch_dev *tsdev, struct spi_device *spi)
-{
- int err = 0;
-
- mrstouch_debug("%s", __func__);
-
- tsdev->input = input_allocate_device();
- if (!tsdev->input) {
- dev_err(&tsdev->spi->dev, "Unable to allocate input device.\n");
- return -EINVAL;
- }
-
- tsdev->input->name = "mrst_touchscreen";
- snprintf(tsdev->phys, sizeof(tsdev->phys),
- "%s/input0", dev_name(&spi->dev));
- tsdev->input->phys = tsdev->phys;
- tsdev->input->dev.parent = &spi->dev;
-
- tsdev->input->id.vendor = tsdev->vendor;
- tsdev->input->id.version = tsdev->rev;
-
- tsdev->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- tsdev->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
- input_set_abs_params(tsdev->input, ABS_X, MIN_X, MIN_Y, 0, 0);
- input_set_abs_params(tsdev->input, ABS_Y, MIN_X, MIN_Y, 0, 0);
-
- err = input_register_device(tsdev->input);
- if (err) {
- dev_err(&tsdev->spi->dev, "unable to register input device\n");
- input_free_device(tsdev->input);
- return err;
- }
-
- mrstouch_debug("%s", "mrstouch initialized");
-
- return 0;
-
-}
-
-/* Probe function for touch screen driver */
-static int __devinit mrstouch_probe(struct spi_device *mrstouch_spi)
-{
- int err;
- unsigned int myirq;
- struct mrstouch_dev *tsdev;
-
- mrstouch_debug("%s(%p)", __func__, mrstouch_spi);
-
- mrstouchdevp = NULL;
- myirq = mrstouch_spi->irq;
-
- if (!mrstouch_spi->irq) {
- dev_err(&mrstouch_spi->dev, "no interrupt assigned\n");
- return -EINVAL;
- }
-
- tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL);
- if (!tsdev) {
- dev_err(&mrstouch_spi->dev, "unable to allocate memory\n");
- return -ENOMEM;
- }
-
- tsdev->irq = myirq;
- mrstouchdevp = tsdev;
-
- err = mrstouch_adc_init(tsdev);
- if (err) {
- dev_err(&mrstouch_spi->dev, "ADC init failed\n");
- goto mrstouch_err_free_mem;
- }
-
- dev_set_drvdata(&mrstouch_spi->dev, tsdev);
- tsdev->spi = mrstouch_spi;
-
- err = ts_input_dev_init(tsdev, mrstouch_spi);
- if (err) {
- dev_err(&tsdev->spi->dev, "ts_input_dev_init failed");
- goto mrstouch_err_free_mem;
- }
-
- mutex_init(&tsdev->lock);
- mutex_lock(&tsdev->lock)
-
- mrstouch_debug("Requesting IRQ-%d", myirq);
- err = request_irq(myirq, pendet_intr_handler,
- 0, "mrstouch", tsdev);
- if (err) {
- dev_err(&tsdev->spi->dev, "unable to allocate irq\n");
- goto mrstouch_err_free_mem;
- }
-
- tsdev->pendet_thrd = kthread_run(mrstouch_pendet,
- (void *)tsdev, "pendet handler");
- if (IS_ERR(tsdev->pendet_thrd)) {
- dev_err(&tsdev->spi->dev, "kthread_run failed\n");
- err = PTR_ERR(tsdev->pendet_thrd);
- goto mrstouch_err_free_mem;
- }
- mrstouch_debug("%s", "Driver initialized");
- return 0;
-
-mrstouch_err_free_mem:
- kfree(tsdev);
- return err;
-}
-
-static int mrstouch_suspend(struct spi_device *spi, pm_message_t msg)
-{
- mrstouch_debug("%s", __func__);
- mrstouchdevp->suspended = 1;
- return 0;
-}
-
-static int mrstouch_resume(struct spi_device *spi)
-{
- mrstouch_debug("%s", __func__);
- mrstouchdevp->suspended = 0;
- return 0;
-}
-
-static int mrstouch_remove(struct spi_device *spi)
-{
- mrstouch_debug("%s", __func__);
- free_irq(mrstouchdevp->irq, mrstouchdevp);
- input_unregister_device(mrstouchdevp->input);
- input_free_device(mrstouchdevp->input);
- if (mrstouchdevp->pendet_thrd)
- kthread_stop(mrstouchdevp->pendet_thrd);
- kfree(mrstouchdevp);
- return 0;
-}
-
-static struct spi_driver mrstouch_driver = {
- .driver = {
- .name = "pmic_touch",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
- .probe = mrstouch_probe,
- .suspend = mrstouch_suspend,
- .resume = mrstouch_resume,
- .remove = mrstouch_remove,
-};
-
-static int __init mrstouch_module_init(void)
-{
- int err;
-
- mrstouch_debug("%s", __func__);
- err = spi_register_driver(&mrstouch_driver);
- if (err) {
- mrstouch_debug("%s(%d)", "SPI PENDET failed", err);
- return -1;
- }
-
- return 0;
-}
-
-static void __exit mrstouch_module_exit(void)
-{
- mrstouch_debug("%s", __func__);
- spi_unregister_driver(&mrstouch_driver);
- return;
-}
-
-module_init(mrstouch_module_init);
-module_exit(mrstouch_module_exit);
-
-MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
-MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/msm/mddihost.c b/drivers/staging/msm/mddihost.c
index c6c1ee4eda05..58a86d5d995f 100644
--- a/drivers/staging/msm/mddihost.c
+++ b/drivers/staging/msm/mddihost.c
@@ -67,7 +67,7 @@ void mddi_init(void)
mddi_host_initialized = TRUE;
- init_MUTEX(&mddi_host_mutex);
+ sema_init(&mddi_host_mutex, 1);
if (!mddi_host_powered) {
down(&mddi_host_mutex);
diff --git a/drivers/staging/msm/mdp.c b/drivers/staging/msm/mdp.c
index 36053afdebe2..58cb40462930 100644
--- a/drivers/staging/msm/mdp.c
+++ b/drivers/staging/msm/mdp.c
@@ -669,24 +669,24 @@ static void mdp_drv_init(void)
/* initialize semaphore */
init_completion(&mdp_ppp_comp);
- init_MUTEX(&mdp_ppp_mutex);
- init_MUTEX(&mdp_pipe_ctrl_mutex);
+ sema_init(&mdp_ppp_mutex, 1);
+ sema_init(&mdp_pipe_ctrl_mutex, 1);
dma2_data.busy = FALSE;
dma2_data.waiting = FALSE;
init_completion(&dma2_data.comp);
- init_MUTEX(&dma2_data.mutex);
+ sema_init(&dma2_data.mutex, 1);
mutex_init(&dma2_data.ov_mutex);
dma3_data.busy = FALSE;
dma3_data.waiting = FALSE;
init_completion(&dma3_data.comp);
- init_MUTEX(&dma3_data.mutex);
+ sema_init(&dma3_data.mutex, 1);
dma_s_data.busy = FALSE;
dma_s_data.waiting = FALSE;
init_completion(&dma_s_data.comp);
- init_MUTEX(&dma_s_data.mutex);
+ sema_init(&dma_s_data.mutex, 1);
dma_e_data.busy = FALSE;
dma_e_data.waiting = FALSE;
diff --git a/drivers/staging/msm/msm_fb.c b/drivers/staging/msm/msm_fb.c
index af5620e4eee1..ea268edbf43b 100644
--- a/drivers/staging/msm/msm_fb.c
+++ b/drivers/staging/msm/msm_fb.c
@@ -915,7 +915,7 @@ static int msm_fb_register(struct msm_fb_data_type *mfd)
mfd->pan_waiting = FALSE;
init_completion(&mfd->pan_comp);
init_completion(&mfd->refresher_comp);
- init_MUTEX(&mfd->sem);
+ sema_init(&mfd->sem, 1);
fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram;
fbram += fbram_offset;
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
index 638ad6b35891..9493128e5fd2 100644
--- a/drivers/staging/octeon/Kconfig
+++ b/drivers/staging/octeon/Kconfig
@@ -1,6 +1,6 @@
config OCTEON_ETHERNET
tristate "Cavium Networks Octeon Ethernet support"
- depends on CPU_CAVIUM_OCTEON
+ depends on CPU_CAVIUM_OCTEON && NETDEVICES
select PHYLIB
select MDIO_OCTEON
help
diff --git a/drivers/staging/octeon/cvmx-fpa.c b/drivers/staging/octeon/cvmx-fpa.c
index 55d9147acc85..ad44b8bd8057 100644
--- a/drivers/staging/octeon/cvmx-fpa.c
+++ b/drivers/staging/octeon/cvmx-fpa.c
@@ -53,7 +53,7 @@ CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
* @name: Constant character string to name this pool.
* String is not copied.
* @buffer: Pointer to the block of memory to use. This must be
- * accessable by all processors and external hardware.
+ * accessible by all processors and external hardware.
* @block_size: Size for each block controlled by the FPA
* @num_blocks: Number of blocks
*
diff --git a/drivers/staging/octeon/cvmx-fpa.h b/drivers/staging/octeon/cvmx-fpa.h
index 1d7788fe09f2..50a8c91778fa 100644
--- a/drivers/staging/octeon/cvmx-fpa.h
+++ b/drivers/staging/octeon/cvmx-fpa.h
@@ -264,7 +264,7 @@ static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
* @name: Constant character string to name this pool.
* String is not copied.
* @buffer: Pointer to the block of memory to use. This must be
- * accessable by all processors and external hardware.
+ * accessible by all processors and external hardware.
* @block_size: Size for each block controlled by the FPA
* @num_blocks: Number of blocks
*
diff --git a/drivers/staging/otus/80211core/ratectrl.c b/drivers/staging/otus/80211core/ratectrl.c
index a1abe2f4f342..283b2b52638c 100644
--- a/drivers/staging/otus/80211core/ratectrl.c
+++ b/drivers/staging/otus/80211core/ratectrl.c
@@ -422,23 +422,15 @@ u8_t zfRateCtrlRateDiff(struct zsRcCell* rcCell, u8_t retryRate)
u16_t i;
/* Find retryRate in operationRateSet[] */
- for (i=0; i<rcCell->operationRateCount; i++)
- {
- if (retryRate == rcCell->operationRateSet[i])
- {
- if (i < rcCell->currentRateIndex)
- {
- return ((rcCell->currentRateIndex - i)+1)>>1;
- }
- else if (i == rcCell->currentRateIndex == 0)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
+ for (i = 0; i < rcCell->operationRateCount; i++) {
+ if (retryRate == rcCell->operationRateSet[i]) {
+ if (i < rcCell->currentRateIndex)
+ return ((rcCell->currentRateIndex - i)+1)>>1;
+ else if (i == rcCell->currentRateIndex && i == 0)
+ return 1;
+ else
+ return 0;
+ }
}
/* TODO : retry rate not in operation rate set */
zm_msg1_tx(ZM_LV_0, "Not in operation rate set:", retryRate);
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index fcd3da07155b..c4bbd6b2a5fa 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -936,7 +936,7 @@ u32_t zfwReadReg(zdev_t *dev, u32_t offset)
#define KEVENT_WATCHDOG 0x00000001
-u32_t smp_kevent_Lock = 0;
+u32_t smp_kevent_Lock;
void kevent(struct work_struct *work)
{
@@ -985,7 +985,7 @@ u8_t zfLnxCreateThread(zdev_t *dev)
/* Create Mutex and keventd */
INIT_WORK(&macp->kevent, kevent);
- init_MUTEX(&macp->ioctl_sem);
+ sema_init(&macp->ioctl_sem, 1);
return 0;
}
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 3221814a856e..cbe966e714f2 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -1631,6 +1631,7 @@ static const struct file_operations keypad_fops = {
.read = keypad_read, /* read */
.open = keypad_open, /* open */
.release = keypad_release, /* close */
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct miscdevice keypad_dev = {
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index 8c8d1c282e7e..89279ba1b737 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -301,10 +301,8 @@ static int pohmelfs_cn_dump(struct cn_msg *msg)
mutex_lock(&pohmelfs_config_lock);
- list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
- if (g)
- total_msg += g->num_entry;
- }
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry)
+ total_msg += g->num_entry;
if (total_msg == 0) {
if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
err = -ENOMEM;
@@ -312,15 +310,16 @@ static int pohmelfs_cn_dump(struct cn_msg *msg)
}
list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
- if (g) {
- list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
- struct pohmelfs_ctl *sc = &c->state.ctl;
- if (pohmelfs_send_reply(err, total_msg - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
- err = -ENOMEM;
- goto out_unlock;
- }
- i += 1;
+ list_for_each_entry_safe(c, tmp, &g->config_list,
+ config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+ if (pohmelfs_send_reply(err, total_msg - i,
+ POHMELFS_CTLINFO_ACK, msg,
+ sc)) {
+ err = -ENOMEM;
+ goto out_unlock;
}
+ i += 1;
}
}
@@ -354,12 +353,11 @@ static int pohmelfs_cn_flush(struct cn_msg *msg)
}
} else {
list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
- if (g) {
- list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
- list_del(&c->config_entry);
- g->num_entry--;
- kfree(c);
- }
+ list_for_each_entry_safe(c, tmp, &g->config_list,
+ config_entry) {
+ list_del(&c->config_entry);
+ g->num_entry--;
+ kfree(c);
}
}
}
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
index 9838ea279c5c..ed58f482c963 100644
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -577,7 +577,7 @@ int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
port0->bulk_in_buffer,
port0->bulk_in_size,
qt2_read_bulk_callback, serial);
- dbg("port0 bulk in URB intialised");
+ dbg("port0 bulk in URB initialised");
/* submit URB, i.e. start reading from device (async) */
dev_extra->ReadBulkStopped = false;
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
index 66122479d529..33c09fad1856 100644
--- a/drivers/staging/quickstart/quickstart.c
+++ b/drivers/staging/quickstart/quickstart.c
@@ -398,16 +398,15 @@ static int __init quickstart_init_input(void)
static int __init quickstart_init(void)
{
int ret;
- acpi_status status = 0;
/* ACPI Check */
if (acpi_disabled)
return -ENODEV;
/* ACPI driver register */
- status = acpi_bus_register_driver(&quickstart_acpi_driver);
- if (status < 0)
- return -ENODEV;
+ ret = acpi_bus_register_driver(&quickstart_acpi_driver);
+ if (ret)
+ return ret;
/* If existing bus with no devices */
if (!quickstart_data.btn_lst) {
diff --git a/drivers/staging/rt2860/ap.h b/drivers/staging/rt2860/ap.h
index faac85d931d1..2737c0c022f9 100644
--- a/drivers/staging/rt2860/ap.h
+++ b/drivers/staging/rt2860/ap.h
@@ -24,18 +24,18 @@
* *
*************************************************************************
- Module Name:
- ap.h
+Module Name:
+ap.h
- Abstract:
- Miniport generic portion header file
+Abstract:
+Miniport generic portion header file
- Revision History:
- Who When What
- -------- ---------- ----------------------------------------------
- Paul Lin 08-01-2002 created
- James Tan 09-06-2002 modified (Revise NTCRegTable)
- John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
+Revision History:
+Who When What
+-------- ---------- ----------------------------------------------
+Paul Lin 08-01-2002 created
+James Tan 09-06-2002 modified (Revise NTCRegTable)
+John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
*/
#ifndef __AP_H__
#define __AP_H__
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index a09038542f26..ff9f87c6be74 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -704,7 +704,7 @@ void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr)
DBGPRINT(RT_DEBUG_TRACE,
("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum));
- /* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize */
+ /* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to initialize */
/* MAC address registers according to E2PROM setting */
if (mac_addr == NULL ||
strlen((char *)mac_addr) != 17 ||
@@ -2507,7 +2507,7 @@ void UserCfgInit(struct rt_rtmp_adapter *pAd)
DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
/* */
- /* part I. intialize common configuration */
+ /* part I. initialize common configuration */
/* */
#ifdef RTMP_MAC_USB
pAd->BulkOutReq = 0;
@@ -2646,7 +2646,7 @@ void UserCfgInit(struct rt_rtmp_adapter *pAd)
pAd->CommonCfg.BeaconPeriod = 100; /* in mSec */
/* */
- /* part II. intialize STA specific configuration */
+ /* part II. initialize STA specific configuration */
/* */
{
RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
@@ -3509,7 +3509,7 @@ int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType)
("STA Driver version-%s\n", STA_DRIVER_VERSION));
#ifdef RTMP_MAC_USB
- init_MUTEX(&(pAd->UsbVendorReq_semaphore));
+ sema_init(&(pAd->UsbVendorReq_semaphore), 1);
os_alloc_mem(pAd, (u8 **) & pAd->UsbVendorReqBuf,
MAX_PARAM_BUFFER_SIZE - 1);
if (pAd->UsbVendorReqBuf == NULL) {
diff --git a/drivers/staging/rt2860/eeprom.h b/drivers/staging/rt2860/eeprom.h
index 039801a97099..72c8fb941655 100644
--- a/drivers/staging/rt2860/eeprom.h
+++ b/drivers/staging/rt2860/eeprom.h
@@ -42,7 +42,7 @@
* Public function declarations for prom-based chipset
************************************************************************/
int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
- u16 Offset, u16 * pValue);
+ u16 Offset, u16 *pValue);
#endif /* RTMP_PCI_SUPPORT // */
#ifdef RTMP_USB_SUPPORT
/*************************************************************************
@@ -55,7 +55,7 @@ int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
#ifdef RT30xx
#ifdef RTMP_EFUSE_SUPPORT
int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
- u16 Offset, u16 * pValue);
+ u16 Offset, u16 *pValue);
#endif /* RTMP_EFUSE_SUPPORT // */
#endif /* RT30xx // */
diff --git a/drivers/staging/rt2860/iface/rtmp_pci.h b/drivers/staging/rt2860/iface/rtmp_pci.h
index 7759d56a3043..3d66e386bd8a 100644
--- a/drivers/staging/rt2860/iface/rtmp_pci.h
+++ b/drivers/staging/rt2860/iface/rtmp_pci.h
@@ -32,7 +32,7 @@
((struct os_cookie *)handle)->pci_dev = dev_p;
#ifdef LINUX
-// set driver data
+/* set driver data */
#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev);
#define RT28XX_PUT_DEVICE(dev_p)
@@ -42,7 +42,8 @@
#ifdef PCI_MSI_SUPPORT
#define RTMP_MSI_ENABLE(_pAd) \
{ struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \
- (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \
+ (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) \
+ == 0 ? TRUE : FALSE; \
}
#define RTMP_MSI_DISABLE(_pAd) \
@@ -52,27 +53,28 @@
_pAd->HaveMsi = FALSE; \
}
#else
-#define RTMP_MSI_ENABLE(_pAd) do{}while(0)
-#define RTMP_MSI_DISABLE(_pAd) do{}while(0)
-#endif // PCI_MSI_SUPPORT //
+#define RTMP_MSI_ENABLE(_pAd) do {} while (0)
+#define RTMP_MSI_DISABLE(_pAd) do {} while (0)
+#endif /* PCI_MSI_SUPPORT */
-#define RTMP_PCI_DEV_UNMAP() \
-{ if (net_dev->base_addr) { \
- iounmap((void *)(net_dev->base_addr)); \
+#define RTMP_PCI_DEV_UNMAP() \
+{ if (net_dev->base_addr) { \
+ iounmap((void *)(net_dev->base_addr)); \
release_mem_region(pci_resource_start(dev_p, 0), \
- pci_resource_len(dev_p, 0)); } \
- if (net_dev->irq) pci_release_regions(dev_p); }
+ pci_resource_len(dev_p, 0)); } \
+ if (net_dev->irq) \
+ pci_release_regions(dev_p); }
-#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) \
- if (pci_read_config_word(pci_dev, offset, &reg16) == 0) \
- Configuration = le2cpu16(reg16); \
- else \
- Configuration = 0;
+#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) {\
+ if (pci_read_config_word(pci_dev, offset, &reg16) == 0) \
+ Configuration = le2cpu16(reg16); \
+ else \
+ Configuration = 0; }
-#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) \
- reg16 = cpu2le16(Configuration); \
- pci_write_config_word(pci_dev, offset, reg16);
+#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) {\
+ reg16 = cpu2le16(Configuration); \
+ pci_write_config_word(pci_dev, offset, reg16); }
-#endif // LINUX //
+#endif /* LINUX */
-#endif // __RTMP_PCI_H__ //
+#endif /* __RTMP_PCI_H__ */
diff --git a/drivers/staging/rt2860/iface/rtmp_usb.h b/drivers/staging/rt2860/iface/rtmp_usb.h
index 33479cc443a5..571289637973 100644
--- a/drivers/staging/rt2860/iface/rtmp_usb.h
+++ b/drivers/staging/rt2860/iface/rtmp_usb.h
@@ -32,41 +32,40 @@
#ifdef LINUX
#include <linux/usb.h>
-#endif // LINUX //
+#endif /* LINUX */
extern u8 EpToQueue[6];
#define RXBULKAGGRE_ZISE 12
-#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
-#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
-#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
#define MAX_MLME_HANDLER_MEMORY 20
-// Flags for Bulkflags control for bulk out data
-//
+/* Flags for Bulkflags control for bulk out data */
#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001
-#define fRTUSB_BULK_OUT_RTS 0x00000002
-#define fRTUSB_BULK_OUT_MLME 0x00000004
+#define fRTUSB_BULK_OUT_RTS 0x00000002
+#define fRTUSB_BULK_OUT_MLME 0x00000004
-#define fRTUSB_BULK_OUT_PSPOLL 0x00000010
+#define fRTUSB_BULK_OUT_PSPOLL 0x00000010
#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000020
-#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000040
-#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000080
-#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000100
+#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000040
+#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000080
+#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000100
-#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
+#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000
#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000
#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000
-// TODO:move to ./ate/include/iface/ate_usb.h
+/* TODO:move to ./ate/include/iface/ate_usb.h */
#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext) \
-{ \
- if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition) \
- { \
+{ \
+ if ((_txContext)->ENextBulkOutPosition == \
+ (_txContext)->CurWritePosition) {\
(_txContext)->bRingEmpty = TRUE; \
- } \
+ } \
/*NdisInterlockedDecrement(&(_p)->TxCount); */\
}
@@ -77,16 +76,32 @@ extern u8 EpToQueue[6];
******************************************************************************/
#ifdef LINUX
-#define BULKAGGRE_ZISE 100
-#define RT28XX_PUT_DEVICE usb_put_dev
-#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC)
-#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC)
-#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_alloc_coherent(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
-#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_free_coherent(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+#define BULKAGGRE_ZISE 100
+#define RT28XX_PUT_DEVICE usb_put_dev
+#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, \
+ GFP_ATOMIC)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, \
+ BufSize, \
+ pDma_addr) \
+ usb_alloc_coherent(\
+ pUsb_Dev, \
+ BufSize, \
+ GFP_ATOMIC, \
+ pDma_addr)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, \
+ BufSize, \
+ pTransferBuf, \
+ Dma_addr) \
+ usb_free_coherent( \
+ pUsb_Dev, \
+ BufSize, \
+ pTransferBuf, \
+ Dma_addr)
#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb)
-// unlink urb
+/* unlink urb */
#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb)
extern void dump_urb(struct urb *purb);
@@ -97,9 +112,9 @@ extern void dump_urb(struct urb *purb);
#define NdisInterlockedDecrement atomic_dec
#define InterlockedExchange atomic_set
-#endif // LINUX //
+#endif /* LINUX */
-#define NT_SUCCESS(status) (((status) >=0) ? (TRUE):(FALSE))
+#define NT_SUCCESS(status) (((status) >= 0) ? (TRUE) : (FALSE))
#define USBD_TRANSFER_DIRECTION_OUT 0
#define USBD_TRANSFER_DIRECTION_IN 0
@@ -112,8 +127,8 @@ extern void dump_urb(struct urb *purb);
#define USB_ST_NOERROR 0
#endif
-// vendor-specific control operations
-#define CONTROL_TIMEOUT_JIFFIES ( (100 * OS_HZ) / 1000)
+/* vendor-specific control operations */
+#define CONTROL_TIMEOUT_JIFFIES ((100 * OS_HZ) / 1000)
#define UNLINK_TIMEOUT_MS 3
void RTUSBBulkOutDataPacketComplete(struct urb *purb, struct pt_regs *pt_regs);
@@ -125,50 +140,49 @@ void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs);
#ifdef KTHREAD_SUPPORT
#define RTUSBMlmeUp(pAd) \
- do{ \
+ do { \
struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
- if (_pTask->kthread_task) \
- { \
+ if (_pTask->kthread_task) {\
_pTask->kthread_running = TRUE; \
- wake_up(&_pTask->kthread_q); \
+ wake_up(&_pTask->kthread_q); \
} \
- }while(0)
+ } while (0)
#else
#define RTUSBMlmeUp(pAd) \
- do{ \
+ do { \
struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
CHECK_PID_LEGALITY(_pTask->taskPID) \
{ \
RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
- }\
- }while(0)
+ } \
+ } while (0)
#endif
#ifdef KTHREAD_SUPPORT
#define RTUSBCMDUp(pAd) \
- do{ \
+ do { \
struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask); \
{ \
_pTask->kthread_running = TRUE; \
- wake_up(&_pTask->kthread_q); \
+ wake_up(&_pTask->kthread_q); \
} \
- }while(0)
+ } while (0)
#else
#define RTUSBCMDUp(pAd) \
- do{ \
+ do { \
struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask); \
CHECK_PID_LEGALITY(_pTask->taskPID) \
{\
RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
- }\
- }while(0)
+ } \
+ } while (0)
#endif
#define DEVICE_VENDOR_REQUEST_OUT 0x40
#define DEVICE_VENDOR_REQUEST_IN 0xc0
-//#define INTERFACE_VENDOR_REQUEST_OUT 0x41
-//#define INTERFACE_VENDOR_REQUEST_IN 0xc1
+/*#define INTERFACE_VENDOR_REQUEST_OUT 0x41*/
+/*#define INTERFACE_VENDOR_REQUEST_IN 0xc1*/
#define BULKOUT_MGMT_RESET_FLAG 0x80
@@ -176,7 +190,7 @@ void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs);
#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
-#define RTMP_IRQ_REQUEST(net_dev) do{}while(0)
-#define RTMP_IRQ_RELEASE(net_dev) do{}while(0)
+#define RTMP_IRQ_REQUEST(net_dev) do {} while (0)
+#define RTMP_IRQ_RELEASE(net_dev) do {} while (0)
-#endif // __RTMP_USB_H__ //
+#endif /* __RTMP_USB_H__ */
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index fd1c14192451..1704c27b2736 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -701,7 +701,7 @@ struct PACKED rt_rt_802_11_acl {
struct rt_802_11_wds {
unsigned long Num;
- NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */ ];
+ NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */];
unsigned long KeyLength;
u8 KeyMaterial[32];
};
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index 6536965df3f3..5b79f655bb0b 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -1313,9 +1313,8 @@ int RtmpOSNetDevAttach(struct net_device *pNetDev,
/* OS specific flags, here we used to indicate if we are virtual interface */
pNetDev->priv_flags = pDevOpHook->priv_flags;
- if (pAd->OpMode == OPMODE_STA) {
+ if (pAd->OpMode == OPMODE_STA)
pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
- }
/* copy the net device mac address to the net_device structure. */
NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 282935caba2c..f133c8cb6807 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -2239,15 +2239,15 @@ struct rt_tx_blk {
unsigned long Priv; /* Hardware specific value saved in here. */
};
-#define fTX_bRtsRequired 0x0001 /* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */
-#define fTX_bAckRequired 0x0002 /* the packet need ack response */
-#define fTX_bPiggyBack 0x0004 /* Legacy device use Piggback or not */
-#define fTX_bHTRate 0x0008 /* allow to use HT rate */
-#define fTX_bForceNonQoS 0x0010 /* force to transmit frame without WMM-QoS in HT mode */
-#define fTX_bAllowFrag 0x0020 /* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */
-#define fTX_bMoreData 0x0040 /* there are more data packets in PowerSave Queue */
-#define fTX_bWMM 0x0080 /* QOS Data */
-#define fTX_bClearEAPFrame 0x0100
+#define fTX_bRtsRequired 0x0001 /* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */
+#define fTX_bAckRequired 0x0002 /* the packet need ack response */
+#define fTX_bPiggyBack 0x0004 /* Legacy device use Piggback or not */
+#define fTX_bHTRate 0x0008 /* allow to use HT rate */
+#define fTX_bForceNonQoS 0x0010 /* force to transmit frame without WMM-QoS in HT mode */
+#define fTX_bAllowFrag 0x0020 /* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */
+#define fTX_bMoreData 0x0040 /* there are more data packets in PowerSave Queue */
+#define fTX_bWMM 0x0080 /* QOS Data */
+#define fTX_bClearEAPFrame 0x0100
#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index a0fe31de0a6d..ebf9074a9083 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -44,6 +44,7 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */
{USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */
{USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */
+ {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */
{USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */
{USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */
{USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */
@@ -95,7 +96,8 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x050d, 0x815c)},
{USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */
{USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */
- {USB_DEVICE(0x04E8, 0x2018)}, /* samsung */
+ {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */
+ {USB_DEVICE(0x1690, 0x0740)}, /* Askey */
{USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */
{USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */
{USB_DEVICE(0x7392, 0x7718)},
@@ -105,21 +107,34 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */
{USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */
{USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */
+ {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */
#endif /* RT2870 // */
#ifdef RT3070
{USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */
{USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */
{USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */
{USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */
{USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */
{USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */
+ {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */
+ {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */
{USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */
{USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */
{USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */
+ {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */
+ {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */
{USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */
{USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */
{USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */
+ {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */
+ {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */
+ {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */
{USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */
+ {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/
{USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */
{USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */
{USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */
@@ -132,14 +147,36 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */
{USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */
{USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */
+ {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */
+ {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */
{USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */
{USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */
{USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */
{USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */
{USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */
+ {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */
+ {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */
{USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */
+ {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */
+ {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */
+ {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/
+ {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/
+ {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/
+ {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/
+ {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */
+ {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */
+ {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */
+ {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */
+ {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */
+ {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */
+ {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */
+ {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */
+ {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */
+ {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */
+ {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */
+ {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */
#endif /* RT3070 // */
- {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom WL-608 */
{USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */
{USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */
{USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 4cd95c3dc947..dc608c70deb1 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -215,7 +215,6 @@ do { if (ieee80211_debug_level & (level)) \
#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)
#include <linux/netdevice.h>
-#include <linux/wireless.h>
#include <linux/if_arp.h> /* ARPHRD_ETHER */
#ifndef WIRELESS_SPY
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index 1b838a266e0d..652d879509e6 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -454,7 +454,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
goto out; /* scan completed */
}while(!channel_map[ch]);
- /* this fuction can be called in two situations
+ /* this function can be called in two situations
* 1- We have switched to ad-hoc mode and we are
* performing a complete syncro scan before conclude
* there are no interesting cell and to create a
@@ -517,7 +517,7 @@ void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
// printk("=======hh===============>ips scan\n");
while(1)
{
- /* this fuction can be called in two situations
+ /* this function can be called in two situations
* 1- We have switched to ad-hoc mode and we are
* performing a complete syncro scan before conclude
* there are no interesting cell and to create a
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index ed7457bc24ea..70ab0084e5f5 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -3547,6 +3547,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
struct net_device *dev = NULL;
struct r8180_priv *priv = NULL;
u8 unit = 0;
+ int ret = -ENODEV;
unsigned long pmem_start, pmem_len, pmem_flags;
@@ -3561,8 +3562,10 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
pci_set_dma_mask(pdev, 0xffffff00ULL);
pci_set_consistent_dma_mask(pdev, 0xffffff00ULL);
dev = alloc_ieee80211(sizeof(struct r8180_priv));
- if (!dev)
- return -ENOMEM;
+ if (!dev) {
+ ret = -ENOMEM;
+ goto fail_free;
+ }
priv = ieee80211_priv(dev);
priv->ieee80211 = netdev_priv(dev);
@@ -3641,11 +3644,12 @@ fail:
free_ieee80211(dev);
}
+fail_free:
pci_disable_device(pdev);
DMESG("wlan driver load failed\n");
pci_set_drvdata(pdev, NULL);
- return -ENODEV;
+ return ret;
}
static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h
index e1f03d79d2b6..16298e052667 100644
--- a/drivers/staging/rtl8192e/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211.h
@@ -2420,205 +2420,204 @@ static inline int ieee80211_is_cck_rate(u8 rate)
/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
+void free_ieee80211(struct net_device *dev);
+struct net_device *alloc_ieee80211(int sizeof_priv);
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+int ieee80211_set_encryption(struct ieee80211_device *ieee);
/* ieee80211_tx.c */
-extern int ieee80211_encrypt_fragment(
+int ieee80211_encrypt_fragment(
struct ieee80211_device *ieee,
struct sk_buff *frag,
int hdr_len);
-extern int ieee80211_rtl_xmit(struct sk_buff *skb,
+int ieee80211_rtl_xmit(struct sk_buff *skb,
struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
+void ieee80211_txb_free(struct ieee80211_txb *);
/* ieee80211_rx.c */
-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+void ieee80211_rx_mgt(struct ieee80211_device *ieee,
struct ieee80211_hdr_4addr *header,
struct ieee80211_rx_stats *stats);
/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+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,
+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,
+int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
#if WIRELESS_EXT >= 18
-extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data* wrqu, char *extra);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data* wrqu, char *extra);
-extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
struct iw_request_info *info,
struct iw_param *data, char *extra);
-extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
#endif
-extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
+int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(struct ieee80211_network net);
-extern short ieee80211_is_shortslot(struct ieee80211_network net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
+short ieee80211_is_54g(struct ieee80211_network net);
+short ieee80211_is_shortslot(struct ieee80211_network net);
+int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats, u16 type,
u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
+void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
-
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-
-extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+void notify_wx_assoc_event(struct ieee80211_device *ieee);
+void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
+void ieee80211_start_bss(struct ieee80211_device *ieee);
+void ieee80211_start_master_bss(struct ieee80211_device *ieee);
+void ieee80211_start_ibss(struct ieee80211_device *ieee);
+void ieee80211_softmac_init(struct ieee80211_device *ieee);
+void ieee80211_softmac_free(struct ieee80211_device *ieee);
+void ieee80211_associate_abort(struct ieee80211_device *ieee);
+void ieee80211_disassociate(struct ieee80211_device *ieee);
+void ieee80211_stop_scan(struct ieee80211_device *ieee);
+void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
+void ieee80211_check_all_nets(struct ieee80211_device *ieee);
+void ieee80211_start_protocol(struct ieee80211_device *ieee);
+void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
+void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+void ieee80211_reset_queue(struct ieee80211_device *ieee);
+void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
+void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
+struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
+void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
+void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
+void notify_wx_assoc_event(struct ieee80211_device *ieee);
+void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
+
+void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
+void ieee80211_tkip_null(void);
+void ieee80211_wep_null(void);
+void ieee80211_ccmp_null(void);
/* ieee80211_softmac_wx.c */
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
+int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *ext);
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
+int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *awrq,
char *extra);
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
+int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
+int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
+int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b);
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b);
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
+int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
struct iw_request_info *a,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b);
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b);
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
union iwreq_data *wrqu, char *b);
-//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
+void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
+int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
+int ieee80211_wx_get_name(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
+int ieee80211_wx_set_power(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
+int ieee80211_wx_get_power(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
//HT
#define MAX_RECEIVE_BUFFER_SIZE 9100 //
-extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
-extern void HTDebugHTInfo(u8* InfoIE, u8* TitleString);
+void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+void HTDebugHTInfo(u8* InfoIE, u8* TitleString);
void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
-extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
-extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
-extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
-extern void HTOnAssocRsp(struct ieee80211_device *ieee);
-extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
-extern void HTInitializeBssDesc(PBSS_HT pBssHT);
-extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
-extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+void HTOnAssocRsp(struct ieee80211_device *ieee);
+void HTInitializeHTInfo(struct ieee80211_device* ieee);
+void HTInitializeBssDesc(PBSS_HT pBssHT);
+void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
extern u8 MCS_FILTER_ALL[];
extern u16 MCS_DATA_RATE[2][2][77] ;
-extern u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame);
+u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame);
//extern void HTSetConnectBwModeCallback(unsigned long data);
-extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
-extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
-extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate);
-extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
-extern u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
+bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate);
+u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
//function in BAPROC.c
-extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
-extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending);
-extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
-extern void BaSetupTimeOut(unsigned long data);
-extern void TxBaInactTimeout(unsigned long data);
-extern void RxBaInactTimeout(unsigned long data);
-extern void ResetBaEntry( PBA_RECORD pBA);
+int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending);
+void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+void BaSetupTimeOut(unsigned long data);
+void TxBaInactTimeout(unsigned long data);
+void RxBaInactTimeout(unsigned long data);
+void ResetBaEntry( PBA_RECORD pBA);
//function in TS.c
-extern bool GetTs(
+bool GetTs(
struct ieee80211_device* ieee,
PTS_COMMON_INFO *ppTS,
u8* Addr,
@@ -2626,10 +2625,10 @@ extern bool GetTs(
TR_SELECT TxRxSelect, //Rx:1, Tx:0
bool bAddNewTs
);
-extern void TSInitialize(struct ieee80211_device *ieee);
-extern void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS);
-extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
-extern void RemoveAllTS(struct ieee80211_device* ieee);
+void TSInitialize(struct ieee80211_device *ieee);
+void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS);
+void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+void RemoveAllTS(struct ieee80211_device* ieee);
void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
extern const long ieee80211_wlan_frequencies[];
@@ -2671,9 +2670,9 @@ static inline const char *escape_essid(const char *essid, u8 essid_len) {
/* For the function is more related to hardware setting, it's better to use the
* ieee handler to refer to it.
*/
-extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
-extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
-extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+short check_nic_enough_desc(struct net_device *dev, int queue_index);
+int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+int ieee80211_parse_info_param(struct ieee80211_device *ieee,
struct ieee80211_info_element *info_element,
u16 length,
struct ieee80211_network *network,
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
index 7edf5c897a68..08bfdb1a4c6e 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
@@ -69,7 +69,7 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
GFP_KERNEL);
if (!ieee->networks) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
+ ieee->dev->name);
return -ENOMEM;
}
@@ -99,7 +99,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct ieee80211_device *ieee;
struct net_device *dev;
- int i,err;
+ int i, err;
IEEE80211_DEBUG_INFO("Initializing...\n");
@@ -111,7 +111,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
ieee = netdev_priv(dev);
- memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
+ memset(ieee, 0, sizeof(struct ieee80211_device) + sizeof_priv);
ieee->dev = dev;
err = ieee80211_networks_allocate(ieee);
@@ -142,7 +142,8 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
spin_lock_init(&ieee->wpax_suitlist_lock);
spin_lock_init(&ieee->bw_spinlock);
spin_lock_init(&ieee->reorder_spinlock);
- //added by WB
+
+ /* added by WB */
atomic_set(&(ieee->atm_chnlop), 0);
atomic_set(&(ieee->atm_swbw), 0);
@@ -153,8 +154,8 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
ieee->privacy_invoked = 0;
ieee->ieee802_1x = 1;
ieee->raw_tx = 0;
- //ieee->hwsec_support = 1; //default support hw security. //use module_param instead.
- ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
+ /* ieee->hwsec_support = 1; default support hw security: use module_param instead */
+ ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary */
ieee80211_softmac_init(ieee);
@@ -165,25 +166,25 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
return NULL;
}
HTUpdateDefaultSetting(ieee);
- HTInitializeHTInfo(ieee); //may move to other place.
+ HTInitializeHTInfo(ieee); /* may move to other place */
TSInitialize(ieee);
for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
+ ieee->last_rxseq_num[i] = -1;
+ ieee->last_rxfrag_num[i] = -1;
+ ieee->last_packet_time[i] = 0;
}
-//These function were added to load crypte module autoly
+ /* Functions to load crypt module automatically */
ieee80211_tkip_null();
ieee80211_wep_null();
ieee80211_ccmp_null();
return dev;
- failed:
+failed:
if (dev)
free_netdev(dev);
return NULL;
@@ -222,35 +223,35 @@ void free_ieee80211(struct net_device *dev)
u32 ieee80211_debug_level = 0;
static int debug = \
- // IEEE80211_DL_INFO |
- // IEEE80211_DL_WX |
- // IEEE80211_DL_SCAN |
- // IEEE80211_DL_STATE |
- // IEEE80211_DL_MGMT |
- // IEEE80211_DL_FRAG |
- // IEEE80211_DL_EAP |
- // IEEE80211_DL_DROP |
- // IEEE80211_DL_TX |
- // IEEE80211_DL_RX |
- //IEEE80211_DL_QOS |
- // IEEE80211_DL_HT |
- // IEEE80211_DL_TS |
-// IEEE80211_DL_BA |
- // IEEE80211_DL_REORDER|
-// IEEE80211_DL_TRACE |
- //IEEE80211_DL_DATA |
- IEEE80211_DL_ERR //awayls open this flags to show error out
- ;
+ /* IEEE80211_DL_INFO | */
+ /* IEEE80211_DL_WX | */
+ /* IEEE80211_DL_SCAN | */
+ /* IEEE80211_DL_STATE | */
+ /* IEEE80211_DL_MGMT | */
+ /* IEEE80211_DL_FRAG | */
+ /* IEEE80211_DL_EAP | */
+ /* IEEE80211_DL_DROP | */
+ /* IEEE80211_DL_TX | */
+ /* IEEE80211_DL_RX | */
+ /* IEEE80211_DL_QOS | */
+ /* IEEE80211_DL_HT | */
+ /* IEEE80211_DL_TS | */
+ /* IEEE80211_DL_BA | */
+ /* IEEE80211_DL_REORDER | */
+ /* IEEE80211_DL_TRACE | */
+ /* IEEE80211_DL_DATA | */
+ IEEE80211_DL_ERR /* always open this flag to show error out */
+ ;
struct proc_dir_entry *ieee80211_proc = NULL;
static int show_debug_level(char *page, char **start, off_t offset,
- int count, int *eof, void *data)
+ int count, int *eof, void *data)
{
return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
}
static int store_debug_level(struct file *file, const char *buffer,
- unsigned long count, void *data)
+ unsigned long count, void *data)
{
char buf[] = "0x00000000";
unsigned long len = min(sizeof(buf) - 1, (u32)count);
@@ -269,7 +270,7 @@ static int store_debug_level(struct file *file, const char *buffer,
val = simple_strtoul(p, &p, 10);
if (p == buf)
printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ ": %s is not in hex or decimal form.\n", buf);
else
ieee80211_debug_level = val;
@@ -320,7 +321,7 @@ int __init ieee80211_rtl_init(void)
return -EIO;
}
e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
- ieee80211_proc);
+ ieee80211_proc);
if (!e) {
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
index aaf9b9dc45e6..9318695042fb 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
@@ -2579,7 +2579,7 @@ static inline void update_network(struct ieee80211_network *dst,
if(src->wmm_param[0].ac_aci_acm_aifsn|| \
src->wmm_param[1].ac_aci_acm_aifsn|| \
src->wmm_param[2].ac_aci_acm_aifsn|| \
- src->wmm_param[1].ac_aci_acm_aifsn) {
+ src->wmm_param[3].ac_aci_acm_aifsn) {
memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
}
//dst->QoS_Enable = src->QoS_Enable;
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index b7ec1ddee704..54c9c2471ec3 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -455,7 +455,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
}while(!ieee->channel_map[ch]);
#endif
- /* this fuction can be called in two situations
+ /* this function can be called in two situations
* 1- We have switched to ad-hoc mode and we are
* performing a complete syncro scan before conclude
* there are no interesting cell and to create a
@@ -527,16 +527,16 @@ void ieee80211_softmac_scan_wq(struct work_struct *work)
do{
ieee->current_network.channel =
(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- if (watchdog++ > MAX_CHANNEL_NUMBER)
- {
- //if current channel is not in channel map, set to default channel.
- #ifdef ENABLE_DOT11D
- if (!channel_map[ieee->current_network.channel]);
- #else
- if (!ieee->channel_map[ieee->current_network.channel]);
- #endif
+ if (watchdog++ > MAX_CHANNEL_NUMBER) {
+ /* if current channel is not in channel map, set to default channel. */
+#ifdef ENABLE_DOT11D
+ if (!channel_map[ieee->current_network.channel]) {
+#else
+ if (!ieee->channel_map[ieee->current_network.channel]) {
+#endif
ieee->current_network.channel = 6;
goto out; /* no good chans */
+ }
}
#ifdef ENABLE_DOT11D
}while(!channel_map[ieee->current_network.channel]);
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c
index 262ed5fd086a..a554627a0bcf 100644
--- a/drivers/staging/rtl8192e/r8180_93cx6.c
+++ b/drivers/staging/rtl8192e/r8180_93cx6.c
@@ -24,10 +24,10 @@ static void eprom_cs(struct net_device *dev, short bit)
{
if (bit)
write_nic_byte(dev, EPROM_CMD,
- (1<<EPROM_CS_SHIFT) | \
+ (1<<EPROM_CS_SHIFT) |
read_nic_byte(dev, EPROM_CMD)); //enable EPROM
else
- write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
+ write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
&~(1<<EPROM_CS_SHIFT)); //disable EPROM
force_pci_posting(dev);
@@ -51,10 +51,10 @@ static void eprom_ck_cycle(struct net_device *dev)
static void eprom_w(struct net_device *dev, short bit)
{
if (bit)
- write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
+ write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) |
read_nic_byte(dev, EPROM_CMD));
else
- write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
+ write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
&~(1<<EPROM_W_SHIFT));
force_pci_posting(dev);
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c
index 8bd5b173a7d2..e2abfd7fd246 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.c
@@ -80,7 +80,6 @@ void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)
}
}
- return;
}
/*--------------------------------------------------------------------------
* Overview: Interface to config 8256
@@ -414,7 +413,6 @@ void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
#endif
#endif
- return;
}
#define MAX_DOZE_WAITING_TIMES_9x 64
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h
index ce49c606521a..a50b14092cb8 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.h
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.h
@@ -16,17 +16,17 @@
#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */
#endif
-extern void PHY_SetRF8256Bandwidth(struct net_device *dev,
+void PHY_SetRF8256Bandwidth(struct net_device *dev,
HT_CHANNEL_WIDTH Bandwidth);
-extern RT_STATUS PHY_RF8256_Config(struct net_device *dev);
+RT_STATUS PHY_RF8256_Config(struct net_device *dev);
-extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev);
+RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev);
-extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel);
-extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
+void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel);
+void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
-extern bool MgntActSet_RF_State(struct net_device *dev,
+bool MgntActSet_RF_State(struct net_device *dev,
RT_RF_POWER_STATE StateToSet,
RT_RF_CHANGE_SOURCE ChangeSource);
diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h
index 865cdc008975..1e3375c58cca 100644
--- a/drivers/staging/rtl8192e/r8192E.h
+++ b/drivers/staging/rtl8192e/r8192E.h
@@ -1505,10 +1505,9 @@ void rtl8187_set_rxconf(struct net_device *dev);
void CamResetAllEntry(struct net_device* dev);
void EnableHWSecurityConfig8192(struct net_device *dev);
void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
-void CamPrintDbgReg(struct net_device* dev);
-extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
-extern void firmware_init_param(struct net_device *dev);
-extern RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
+void dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
+void firmware_init_param(struct net_device *dev);
+RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
void rtl8192_hw_wakeup_wq (struct work_struct *work);
short rtl8192_is_tx_queue_empty(struct net_device *dev);
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index 17a806f9ee77..c408f422babe 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -58,9 +58,6 @@
#include "r819xE_phyreg.h"
#include "r819xE_cmdpkt.h"
#include "r8192E_dm.h"
-//#include "r8192xU_phyreg.h"
-//#include <linux/usb.h>
-// FIXME: check if 2.6.7 is ok
#ifdef CONFIG_PM
#include "r8192_pm.h"
@@ -71,7 +68,7 @@
#endif
//set here to open your trace code. //WB
-u32 rt_global_debug_component = \
+u32 rt_global_debug_component =
// COMP_INIT |
// COMP_EPROM |
// COMP_PHY |
@@ -160,6 +157,11 @@ static void rtl8192_prepare_beacon(struct r8192_priv *priv);
static irqreturn_t rtl8192_interrupt(int irq, void *netdev);
static void rtl8192_try_wake_queue(struct net_device *dev, int pri);
static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
+static void rtl8192_update_ratr_table(struct net_device* dev);
+static void rtl8192_restart(struct work_struct *work);
+static void watch_dog_timer_callback(unsigned long data);
+static int _rtl8192_up(struct net_device *dev);
+static void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
#ifdef ENABLE_DOT11D
@@ -363,8 +365,8 @@ u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
crypt = ieee->crypt[ieee->tx_keyidx];
- encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\
- (ieee->host_encrypt && crypt && crypt->ops && \
+ encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||
+ (ieee->host_encrypt && crypt && crypt->ops &&
(0 == strcmp(crypt->ops->name,"WEP")));
/* simply judge */
@@ -498,13 +500,9 @@ void force_pci_posting(struct net_device *dev)
}
-//warning message WB
//static struct net_device_stats *rtl8192_stats(struct net_device *dev);
-//void rtl8192_restart(struct net_device *dev);
-void rtl8192_restart(struct work_struct *work);
//void rtl8192_rq_tx_ack(struct work_struct *work);
-void watch_dog_timer_callback(unsigned long data);
/****************************************************************************
-----------------------------PROCFS STUFF-------------------------
*****************************************************************************/
@@ -812,11 +810,7 @@ short check_nic_enough_desc(struct net_device *dev, int prio)
/* for now we reserve two free descriptor as a safety boundary
* between the tail and the head
*/
- if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
- return 1;
- } else {
- return 0;
- }
+ return (ring->entries - skb_queue_len(&ring->queue) >= 2);
}
static void tx_timeout(struct net_device *dev)
@@ -1109,7 +1103,6 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset)
}
skb_queue_purge(&priv->skb_queue);
- return;
}
#if 0
@@ -1168,7 +1161,7 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
/* shall not be referred by command packet */
assert(queue_index != TXCMD_QUEUE);
- if((priv->bHwRadioOff == true)||(!priv->up))
+ if (priv->bHwRadioOff ||(!priv->up))
{
kfree_skb(skb);
return;
@@ -1198,7 +1191,6 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
//spin_unlock_irqrestore(&priv->tx_lock,flags);
// return ret;
- return;
}
/* This is a rough attempt to TX a frame
@@ -1217,7 +1209,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
u8 queue_index = tcb_desc->queue_index;
if(queue_index != TXCMD_QUEUE){
- if((priv->bHwRadioOff == true)||(!priv->up))
+ if (priv->bHwRadioOff ||(!priv->up))
{
kfree_skb(skb);
return 0;
@@ -1713,7 +1705,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
pdesc = &ring->desc[idx];
if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
- RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
+ RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x",
tcb_desc->queue_index,ring->idx, idx,skb->len);
spin_unlock_irqrestore(&priv->irq_th_lock,flags);
return skb->len;
@@ -1919,7 +1911,6 @@ static void rtl8192_pci_resetdescring(struct net_device *dev)
}
#if 1
-extern void rtl8192_update_ratr_table(struct net_device* dev);
static void rtl8192_link_change(struct net_device *dev)
{
// int i;
@@ -1962,7 +1953,7 @@ static void rtl8192_link_change(struct net_device *dev)
#endif
-static struct ieee80211_qos_parameters def_qos_parameters = {
+static const struct ieee80211_qos_parameters def_qos_parameters = {
{3,3,3,3},/* cw_min */
{7,7,7,7},/* cw_max */
{2,2,2,2},/* aifs */
@@ -2049,7 +2040,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
"qos_activate\n");
}
} else {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+ memcpy(&priv->ieee80211->current_network.qos_data.parameters,
&def_qos_parameters, size);
if ((network->qos_data.active == 1) && (active_network == 1)) {
@@ -2101,24 +2092,24 @@ static int rtl8192_qos_association_resp(struct r8192_priv *priv,
spin_lock_irqsave(&priv->ieee80211->lock, flags);
if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
- &network->qos_data.parameters,\
+ memcpy(&priv->ieee80211->current_network.qos_data.parameters,
+ &network->qos_data.parameters,
sizeof(struct ieee80211_qos_parameters));
priv->ieee80211->current_network.qos_data.active = 1;
#if 0
- if((priv->ieee80211->current_network.qos_data.param_count != \
+ if((priv->ieee80211->current_network.qos_data.param_count !=
network->qos_data.param_count))
#endif
{
set_qos_param = 1;
/* update qos parameter for current network */
- priv->ieee80211->current_network.qos_data.old_param_count = \
+ priv->ieee80211->current_network.qos_data.old_param_count =
priv->ieee80211->current_network.qos_data.param_count;
- priv->ieee80211->current_network.qos_data.param_count = \
+ priv->ieee80211->current_network.qos_data.param_count =
network->qos_data.param_count;
}
} else {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+ memcpy(&priv->ieee80211->current_network.qos_data.parameters,
&def_qos_parameters, size);
priv->ieee80211->current_network.qos_data.active = 0;
priv->ieee80211->current_network.qos_data.supported = 0;
@@ -2146,7 +2137,7 @@ static int rtl8192_handle_assoc_response(struct net_device *dev,
//updateRATRTabel for MCS only. Basic rate is not implement.
-void rtl8192_update_ratr_table(struct net_device* dev)
+static void rtl8192_update_ratr_table(struct net_device* dev)
// POCTET_STRING posLegacyRate,
// u8* pMcsRate)
// PRT_WLAN_STA pEntry)
@@ -2207,12 +2198,8 @@ static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee80211;
- if (ieee->rtllib_ap_sec_type &&
- (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
- return false;
- } else {
- return true;
- }
+ return !(ieee->rtllib_ap_sec_type &&
+ (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP)));
#else
struct r8192_priv* priv = ieee80211_priv(dev);
struct ieee80211_device* ieee = priv->ieee80211;
@@ -2256,7 +2243,6 @@ static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
}
else
memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
- return;
}
static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
@@ -2331,16 +2317,10 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
{
- bool Reval;
struct r8192_priv* priv = ieee80211_priv(dev);
struct ieee80211_device* ieee = priv->ieee80211;
- if(ieee->bHalfWirelessN24GMode == true)
- Reval = true;
- else
- Reval = false;
-
- return Reval;
+ return ieee->bHalfWirelessN24GMode;
}
short rtl8192_is_tx_queue_empty(struct net_device *dev)
@@ -2605,9 +2585,9 @@ static void rtl8192_init_priv_variable(struct net_device* dev)
RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
- priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
- IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
- IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |\
+ priv->irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |
+ IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |
+ IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW |
IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
priv->AcmControl = 0;
@@ -3330,7 +3310,7 @@ static void rtl8192_hwconfig(struct net_device* dev)
// Set Retry Limit here
//
write_nic_word(dev, RETRY_LIMIT,
- priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
+ priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT |
priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
// Set Contention Window here
@@ -3485,12 +3465,12 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
//2Set Tx dma burst
#ifdef RTL8190P
- write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
- (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
- (1<<MULRW_SHIFT)));
+ write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
+ (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) |
+ (1<<MULRW_SHIFT)));
#else
#ifdef RTL8192E
- write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
+ write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |
(MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
#endif
#endif
@@ -3504,25 +3484,25 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
#ifdef TO_DO_LIST
if(priv->bInHctTest)
{
- PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
- NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
- NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+ PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
+ NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
+ NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
- PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
- NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
+ PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
+ NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
}
else
#endif
{
- write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
- NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
- NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+ write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |
+ NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT |
+ NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT |
NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
- write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
- NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
+ write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW|
+ NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|
NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
}
@@ -4246,9 +4226,6 @@ static void CamRestoreAllEntry(struct net_device *dev)
}
}
-void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
-int _rtl8192_up(struct net_device *dev);
-
/*
* This function is used to fix Tx/Rx stop bug temporarily.
* This function will do "system reset" to NIC when Tx or Rx is stuck.
@@ -4400,7 +4377,7 @@ void InactivePsWorkItemCallback(struct net_device *dev)
//
pPSC->bSwRfProcessing = TRUE;
- RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
+ RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n",
pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
@@ -4673,7 +4650,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work)
static u8 last_time = 0;
bool bEnterPS = false;
- if((!priv->up) || (priv->bHwRadioOff == true))
+ if ((!priv->up) || priv->bHwRadioOff)
return;
if(!priv->up)
@@ -4683,8 +4660,8 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work)
// printk("watch_dog ENABLE_IPS\n");
if(ieee->actscanning == false){
//printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
- if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&\
- (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&\
+ if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&
+ (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&
(!ieee->proto_stoppping) && !ieee->wx_set_enc){
if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
//printk("====================>haha:IPSEnter()\n");
@@ -4811,7 +4788,8 @@ void watch_dog_timer_callback(unsigned long data)
mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
}
-int _rtl8192_up(struct net_device *dev)
+
+static int _rtl8192_up(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
//int i;
@@ -4961,7 +4939,7 @@ void rtl8192_commit(struct net_device *dev)
_rtl8192_up(dev);
}
-void rtl8192_restart(struct work_struct *work)
+static void rtl8192_restart(struct work_struct *work)
{
struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
struct net_device *dev = priv->ieee80211->dev;
@@ -5610,7 +5588,7 @@ static u8 rtl819x_query_rxpwrpercentage(
return (100+antpower);
}
-} /* QueryRxPwrPercentage */
+}
static u8
rtl819x_evm_dbtopercentage(
@@ -5629,7 +5607,7 @@ rtl819x_evm_dbtopercentage(
ret_val*=3;
if(ret_val == 99)
ret_val = 100;
- return(ret_val);
+ return ret_val;
}
//
@@ -5962,7 +5940,7 @@ static void rtl8192_query_rxphystatus(
if (rf_rx_num != 0)
pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
}
-} /* QueryRxPhyStatus8190Pci */
+}
static void
rtl8192_record_rxdesc_forlateruse(
@@ -6325,6 +6303,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
struct net_device *dev = NULL;
struct r8192_priv *priv= NULL;
u8 unit = 0;
+ int ret = -ENODEV;
#ifdef CONFIG_RTL8192_IO_MAP
unsigned long pio_start, pio_len, pio_flags;
@@ -6344,8 +6323,10 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
pci_set_dma_mask(pdev, 0xffffff00ULL);
pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
dev = alloc_ieee80211(sizeof(struct r8192_priv));
- if (!dev)
- return -ENOMEM;
+ if (!dev) {
+ ret = -ENOMEM;
+ goto fail_free;
+ }
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -6494,18 +6475,19 @@ fail:
free_ieee80211(dev);
}
+fail_free:
pci_disable_device(pdev);
DMESG("wlan driver load failed\n");
pci_set_drvdata(pdev, NULL);
- return -ENODEV;
+ return ret;
}
/* detach all the work and timer structure declared or inititialized
* in r8192_init function.
* */
-void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
+static void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
{
/* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
* is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
@@ -6825,7 +6807,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev)
SECR_value &= ~SCR_RxDecEnable;
}
- RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
+ RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__,
ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
{
write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK );
@@ -6910,26 +6892,6 @@ void setKey( struct net_device *dev,
}
RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
}
-// This function seems not ready! WB
-void CamPrintDbgReg(struct net_device* dev)
-{
- unsigned long rvalue;
- unsigned char ucValue;
- write_nic_dword(dev, DCAM, 0x80000000);
- msleep(40);
- rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
- RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
- if((rvalue & 0x40000000) != 0x4000000)
- RT_TRACE(COMP_SEC, "-->TX Key Not Found ");
- msleep(20);
- write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
- rvalue = read_nic_dword(dev, DCAM); //delay_ms(40);
- RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
- if((rvalue & 0x40000000) != 0x4000000)
- RT_TRACE(COMP_SEC, "-->CAM Key Not Found ");
- ucValue = read_nic_byte(dev, SECR);
- RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
-}
bool NicIFEnableNIC(struct net_device* dev)
{
@@ -6963,7 +6925,7 @@ bool NicIFEnableNIC(struct net_device* dev)
rtl8192_irq_enable(dev);
priv->bdisable_nic = false;
//RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
- return (init_status == RT_STATUS_SUCCESS) ? true:false;
+ return (init_status == RT_STATUS_SUCCESS);
}
bool NicIFDisableNIC(struct net_device* dev)
{
diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c
index a5884c6bcc25..0f7bc5234902 100644
--- a/drivers/staging/rtl8192e/r8192E_dm.c
+++ b/drivers/staging/rtl8192e/r8192E_dm.c
@@ -21,7 +21,7 @@ Major Change History:
#include "r8190_rtl8256.h"
#define DRV_NAME "rtl819xE"
-/*---------------------------Define Local Constant---------------------------*/
+
//
// Indicate different AP vendor for IOT issue.
//
@@ -46,21 +46,11 @@ static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
#define RTK_UL_EDCA 0xa44f
#define RTK_DL_EDCA 0x5e4322
-/*---------------------------Define Local Constant---------------------------*/
-/*------------------------Define global variable-----------------------------*/
-// Debug variable ?
dig_t dm_digtable;
-// Store current shoftware write register content for MAC PHY.
-u8 dm_shadow[16][256] = {{0}};
// For Dynamic Rx Path Selection by Signal Strength
DRxPathSel DM_RxPathSelTable;
-/*------------------------Define global variable-----------------------------*/
-
-
-/*------------------------Define local variable------------------------------*/
-/*------------------------Define local variable------------------------------*/
/*--------------------Define export function prototype-----------------------*/
@@ -90,7 +80,6 @@ extern void dm_rf_operation_test_callback(unsigned long data);
extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
extern void dm_fsync_timer_callback(unsigned long data);
extern void dm_check_fsync(struct net_device *dev);
-extern void dm_shadow_init(struct net_device *dev);
extern void dm_initialize_txpower_tracking(struct net_device *dev);
#ifdef RTL8192E
@@ -98,11 +87,6 @@ extern void dm_gpio_change_rf_callback(struct work_struct *work);
#endif
-
-/*--------------------Define export function prototype-----------------------*/
-
-
-/*---------------------Define local function prototype-----------------------*/
// DM --> Rate Adaptive
static void dm_check_rate_adaptive(struct net_device *dev);
@@ -111,20 +95,12 @@ static void dm_init_bandwidth_autoswitch(struct net_device *dev);
static void dm_bandwidth_autoswitch( struct net_device *dev);
// DM --> TX power control
-//static void dm_initialize_txpower_tracking(struct net_device *dev);
-
static void dm_check_txpower_tracking(struct net_device *dev);
-
-
-//static void dm_txpower_reset_recovery(struct net_device *dev);
-
-
// DM --> BB init gain restore
#ifndef RTL8192U
static void dm_bb_initialgain_restore(struct net_device *dev);
-
// DM --> BB init gain backup
static void dm_bb_initialgain_backup(struct net_device *dev);
#endif
@@ -146,49 +122,33 @@ static void dm_check_edca_turbo(struct net_device *dev);
// DM --> HW RF control
static void dm_check_rfctrl_gpio(struct net_device *dev);
-#ifndef RTL8190P
-//static void dm_gpio_change_rf(struct net_device *dev);
-#endif
// DM --> Check PBC
static void dm_check_pbc_gpio(struct net_device *dev);
-
// DM --> Check current RX RF path state
static void dm_check_rx_path_selection(struct net_device *dev);
static void dm_init_rxpath_selection(struct net_device *dev);
static void dm_rxpath_sel_byrssi(struct net_device *dev);
-
// DM --> Fsync for broadcom ap
static void dm_init_fsync(struct net_device *dev);
static void dm_deInit_fsync(struct net_device *dev);
-//Added by vivi, 20080522
static void dm_check_txrateandretrycount(struct net_device *dev);
-/*---------------------Define local function prototype-----------------------*/
/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18
static void dm_init_dynamic_txpower(struct net_device *dev);
static void dm_dynamic_txpower(struct net_device *dev);
-
// DM --> For rate adaptive and DIG, we must send RSSI to firmware
static void dm_send_rssi_tofw(struct net_device *dev);
static void dm_ctstoself(struct net_device *dev);
-/*---------------------------Define function prototype------------------------*/
-//================================================================================
-// HW Dynamic mechanism interface.
-//================================================================================
-//
-// Description:
-// Prepare SW resource for HW dynamic mechanism.
-//
-// Assumption:
-// This function is only invoked at driver intialization once.
-//
-//
+/*
+ * Prepare SW resource for HW dynamic mechanism.
+ * This function is only invoked at driver intialization once.
+ */
void init_hal_dm(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -210,7 +170,7 @@ void init_hal_dm(struct net_device *dev)
INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
#endif
-} // InitHalDm
+}
void deinit_hal_dm(struct net_device *dev)
{
@@ -273,7 +233,7 @@ void dm_CheckRxAggregation(struct net_device *dev) {
lastTxOkCnt = priv->stats.txbytesunicast;
lastRxOkCnt = priv->stats.rxbytesunicast;
-} // dm_CheckEdcaTurbo
+}
#endif
@@ -298,16 +258,10 @@ void dm_check_ac_dc_power(struct net_device *dev)
return;
}
call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
-
- return;
-};
+}
void hal_dm_watchdog(struct net_device *dev)
{
- //struct r8192_priv *priv = ieee80211_priv(dev);
-
- //static u8 previous_bssid[6] ={0};
-
dm_check_ac_dc_power(dev);
/*Add by amy 2008/05/15 ,porting from windows code.*/
@@ -333,7 +287,7 @@ void hal_dm_watchdog(struct net_device *dev)
#ifdef USB_RX_AGGREGATION_SUPPORT
dm_CheckRxAggregation(dev);
#endif
-} //HalDmWatchDog
+}
/*
@@ -385,25 +339,9 @@ void init_rate_adaptive(struct net_device * dev)
pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
}
-} // InitRateAdaptive
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rate_adaptive()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/26/08 amy Create version 0 proting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
static void dm_check_rate_adaptive(struct net_device * dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -557,7 +495,7 @@ static void dm_check_rate_adaptive(struct net_device * dev)
pra->ratr_state = DM_RATR_STA_MAX;
}
-} // dm_CheckRateAdaptive
+}
static void dm_init_bandwidth_autoswitch(struct net_device * dev)
@@ -569,7 +507,7 @@ static void dm_init_bandwidth_autoswitch(struct net_device * dev)
priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
-} // dm_init_bandwidth_autoswitch
+}
static void dm_bandwidth_autoswitch(struct net_device * dev)
@@ -588,7 +526,7 @@ static void dm_bandwidth_autoswitch(struct net_device * dev)
}
}
-} // dm_BandwidthAutoSwitch
+}
//OFDM default at 0db, index=6.
#ifndef RTL8190P
@@ -947,9 +885,9 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
priv->CCK_index =(u8) i;
RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
rCCK0_TxFilter1, TempCCk, priv->CCK_index);
- break;
- }
-}
+ break;
+ }
+ }
priv->btxpower_trackingInit = TRUE;
//pHalData->TXPowercount = 0;
return;
@@ -1580,13 +1518,12 @@ void dm_initialize_txpower_tracking(struct net_device *dev)
#ifdef RTL8190P
dm_InitializeTXPowerTracking_TSSI(dev);
#else
- //if(priv->bDcut == TRUE)
if(priv->IC_Cut >= IC_VersionCut_D)
dm_InitializeTXPowerTracking_TSSI(dev);
else
dm_InitializeTXPowerTracking_ThermalMeter(dev);
#endif
-} // dm_InitializeTXPowerTracking
+}
static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
@@ -1600,13 +1537,10 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
return;
tx_power_track_counter++;
-
- if(tx_power_track_counter > 90)
- {
- queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
+ if (tx_power_track_counter > 90) {
+ queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
tx_power_track_counter =0;
- }
-
+ }
}
#ifndef RTL8190P
@@ -1639,12 +1573,11 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
TM_Trigger = 1;
return;
}
- else
- {
+ else {
//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
TM_Trigger = 0;
- }
+ }
}
#endif
@@ -1664,7 +1597,7 @@ static void dm_check_txpower_tracking(struct net_device *dev)
dm_CheckTXPowerTracking_ThermalMeter(dev);
#endif
-} // dm_CheckTXPowerTracking
+}
static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
@@ -1777,19 +1710,18 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH
RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
rCCK0_DebugPort, TempVal);
}
- }
+}
#endif
void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
-{ // dm_CCKTxPowerAdjust
+{
#ifndef RTL8190P
struct r8192_priv *priv = ieee80211_priv(dev);
#endif
#ifdef RTL8190P
dm_CCKTxPowerAdjust_TSSI(dev, binch14);
#else
- //if(priv->bDcut == TRUE)
if(priv->IC_Cut >= IC_VersionCut_D)
dm_CCKTxPowerAdjust_TSSI(dev, binch14);
else
@@ -1818,7 +1750,7 @@ static void dm_txpower_reset_recovery(
RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
-} // dm_TXPowerResetRecovery
+}
void dm_restore_dynamic_mechanism_state(struct net_device *dev)
{
@@ -1864,7 +1796,7 @@ void dm_restore_dynamic_mechanism_state(struct net_device *dev)
//
dm_bb_initialgain_restore(dev);
-} // DM_RestoreDynamicMechanismState
+}
static void dm_bb_initialgain_restore(struct net_device *dev)
{
@@ -1893,7 +1825,7 @@ static void dm_bb_initialgain_restore(struct net_device *dev)
//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
-} // dm_BBInitialGainRestore
+}
void dm_backup_dynamic_mechanism_state(struct net_device *dev)
@@ -1906,7 +1838,7 @@ void dm_backup_dynamic_mechanism_state(struct net_device *dev)
//Backup BB InitialGain
dm_bb_initialgain_backup(dev);
-} // DM_BackupDynamicMechanismState
+}
static void dm_bb_initialgain_backup(struct net_device *dev)
@@ -1932,25 +1864,10 @@ static void dm_bb_initialgain_backup(struct net_device *dev)
RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
-} // dm_BBInitialGainBakcup
+}
#endif
-/*-----------------------------------------------------------------------------
- * Function: dm_change_dynamic_initgain_thresh()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/29/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+
void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32 dm_value)
{
if (dm_type == DIG_TYPE_THRESH_HIGH)
@@ -2017,25 +1934,10 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32
dm_value = 0x50;
dm_digtable.rx_gain_range_max = (u8)dm_value;
}
-} /* DM_ChangeDynamicInitGainThresh */
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_dig_init()
- *
- * Overview: Set DIG scheme init value.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/15/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+/* Set DIG scheme init value. */
static void dm_dig_init(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -2064,26 +1966,14 @@ static void dm_dig_init(struct net_device *dev)
else
dm_digtable.rx_gain_range_min = DM_DIG_MIN;
-} /* dm_dig_init */
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_ctrl_initgain_byrssi()
- *
- * Overview: Driver must monitor RSSI and notify firmware to change initial
- * gain according to different threshold. BB team provide the
- * suggested solution.
- *
- * Input: struct net_device *dev
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/27/2008 amy Create Version 0 porting from windows code.
- *---------------------------------------------------------------------------*/
+}
+
+
+/*
+ * Driver must monitor RSSI and notify firmware to change initial
+ * gain according to different threshold. BB team provide the
+ * suggested solution.
+ */
static void dm_ctrl_initgain_byrssi(struct net_device *dev)
{
@@ -2136,7 +2026,7 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi(
dm_digtable.dig_algorithm_switch = 0;
dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
-} /* dm_CtrlInitGainByRssi */
+}
static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
struct net_device *dev)
@@ -2307,25 +2197,8 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
dm_ctrl_initgain_byrssi_highpwr(dev);
-} /* dm_CtrlInitGainByRssi */
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_ctrl_initgain_byrssi_highpwr()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
static void dm_ctrl_initgain_byrssi_highpwr(
struct net_device * dev)
{
@@ -2398,7 +2271,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
reset_cnt_highpwr = priv->reset_count;
-} /* dm_CtrlInitGainByRssiHighPwr */
+}
static void dm_initial_gain(
@@ -2623,25 +2496,23 @@ static void dm_cs_ratio(
}
+ if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
+ !initialized || force_write)
{
- if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
- !initialized || force_write)
+ //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
+ if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
{
- //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
- if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
- {
- // Lower CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0x08);
- }
- else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
- {
- // Higher CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0xcd);
- }
- dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
- initialized = 1;
- force_write = 0;
+ // Lower CS ratio for CCK.
+ write_nic_byte(dev, 0xa0a, 0x08);
+ }
+ else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
+ {
+ // Higher CS ratio for CCK.
+ write_nic_byte(dev, 0xa0a, 0xcd);
}
+ dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
+ initialized = 1;
+ force_write = 0;
}
}
@@ -2652,7 +2523,7 @@ void dm_init_edca_turbo(struct net_device *dev)
priv->bcurrent_turbo_EDCA = false;
priv->ieee80211->bis_any_nonbepkts = false;
priv->bis_cur_rdlstate = false;
-} // dm_init_edca_turbo
+}
#if 1
static void dm_check_edca_turbo(
@@ -2766,7 +2637,7 @@ dm_CheckEdcaTurbo_EXIT:
priv->ieee80211->bis_any_nonbepkts = false;
lastTxOkCnt = priv->stats.txbytesunicast;
lastRxOkCnt = priv->stats.rxbytesunicast;
-} // dm_CheckEdcaTurbo
+}
#endif
static void dm_init_ctstoself(struct net_device * dev)
@@ -2831,22 +2702,7 @@ static void dm_ctstoself(struct net_device *dev)
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rfctrl_gpio()
- *
- * Overview: Copy 8187B template for 9xseries.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+/* Copy 8187B template for 9xseries */
#if 1
static void dm_check_rfctrl_gpio(struct net_device * dev)
{
@@ -2869,25 +2725,10 @@ static void dm_check_rfctrl_gpio(struct net_device * dev)
queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
#endif
-} /* dm_CheckRfCtrlGPIO */
+}
#endif
-/*-----------------------------------------------------------------------------
- * Function: dm_check_pbc_gpio()
- *
- * Overview: Check if PBC button is pressed.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+/* Check if PBC button is pressed. */
static void dm_check_pbc_gpio(struct net_device *dev)
{
#ifdef RTL8192U
@@ -2897,7 +2738,7 @@ static void dm_check_pbc_gpio(struct net_device *dev)
tmp1byte = read_nic_byte(dev,GPI);
if(tmp1byte == 0xff)
- return;
+ return;
if (tmp1byte&BIT6 || tmp1byte&BIT0)
{
@@ -2912,94 +2753,54 @@ static void dm_check_pbc_gpio(struct net_device *dev)
#ifdef RTL8192E
-/*-----------------------------------------------------------------------------
- * Function: dm_GPIOChangeRF
- * Overview: PCI will not support workitem call back HW radio on-off control.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 02/21/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+/* PCI will not support workitem call back HW radio on-off control. */
void dm_gpio_change_rf_callback(struct work_struct *work)
{
struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
- struct net_device *dev = priv->ieee80211->dev;
+ struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
+ struct net_device *dev = priv->ieee80211->dev;
u8 tmp1byte;
RT_RF_POWER_STATE eRfPowerStateToSet;
bool bActuallySet = false;
- if(!priv->up)
- {
+ if (!priv->up) {
RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
- }
- else
- {
- // 0x108 GPIO input register is read only
- //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
- tmp1byte = read_nic_byte(dev,GPI);
+ } else {
+ // 0x108 GPIO input register is read only
+ //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
+ tmp1byte = read_nic_byte(dev,GPI);
- eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
+ eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
- if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
- {
+ if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
- priv->bHwRadioOff = false;
- bActuallySet = true;
- }
- else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
- {
+ priv->bHwRadioOff = false;
+ bActuallySet = true;
+ } else if ((!priv->bHwRadioOff) && (eRfPowerStateToSet == eRfOff)) {
RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
- priv->bHwRadioOff = true;
- bActuallySet = true;
- }
+ priv->bHwRadioOff = true;
+ bActuallySet = true;
+ }
- if(bActuallySet)
- {
+ if (bActuallySet) {
priv->bHwRfOffAction = 1;
- MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
- //DrvIFIndicateCurrentPhyStatus(pAdapter);
-
- }
- else
- {
+ MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
+ //DrvIFIndicateCurrentPhyStatus(pAdapter);
+ } else {
msleep(2000);
- }
-
}
-
-} /* dm_GPIOChangeRF */
+ }
+}
#endif
-/*-----------------------------------------------------------------------------
- * Function: DM_RFPathCheckWorkItemCallBack()
- *
- * Overview: Check if Current RF RX path is enabled
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 01/30/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+
+/* Check if Current RF RX path is enabled */
void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
{
struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
- struct net_device *dev =priv->ieee80211->dev;
+ struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
+ struct net_device *dev =priv->ieee80211->dev;
//bool bactually_set = false;
u8 rfpath = 0, i;
@@ -3020,7 +2821,7 @@ void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
return;
dm_rxpath_sel_byrssi(dev);
-} /* DM_RFPathCheckWorkItemCallBack */
+}
static void dm_init_rxpath_selection(struct net_device * dev)
{
@@ -3305,28 +3106,14 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev)
}
}
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rx_path_selection()
- *
- * Overview: Call a workitem to check current RXRF path and Rx Path selection by RSSI.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_rx_path_selection(struct net_device *dev)
+/*
+ * Call a workitem to check current RXRF path and Rx Path selection by RSSI.
+ */
+static void dm_check_rx_path_selection(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
-} /* dm_CheckRxRFPath */
-
+}
static void dm_init_fsync (struct net_device *dev)
{
@@ -3722,63 +3509,10 @@ void dm_check_fsync(struct net_device *dev)
}
}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_shadow_init()
- *
- * Overview: Store all NIC MAC/BB register content.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/29/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-void dm_shadow_init(struct net_device *dev)
-{
- u8 page;
- u16 offset;
-
- for (page = 0; page < 5; page++)
- for (offset = 0; offset < 256; offset++)
- {
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
- //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
- }
-
- for (page = 8; page < 11; page++)
- for (offset = 0; offset < 256; offset++)
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
-
- for (page = 12; page < 15; page++)
- for (offset = 0; offset < 256; offset++)
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
-
-} /* dm_shadow_init */
-
-/*---------------------------Define function prototype------------------------*/
-/*-----------------------------------------------------------------------------
- * Function: DM_DynamicTxPower()
- *
- * Overview: Detect Signal strength to control TX Registry
- Tx Power Control For Near/Far Range
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 03/06/2008 Jacken Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+/*
+ * Detect Signal strength to control TX Registry
+ * Tx Power Control For Near/Far Range
+ */
static void dm_init_dynamic_txpower(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -3861,7 +3595,7 @@ static void dm_dynamic_txpower(struct net_device *dev)
priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
-} /* dm_dynamic_txpower */
+}
//added by vivi, for read tx rate and retrycount
static void dm_check_txrateandretrycount(struct net_device * dev)
@@ -3900,5 +3634,3 @@ static void dm_send_rssi_tofw(struct net_device *dev)
#endif
}
-/*---------------------------Define function prototype------------------------*/
-
diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h
index f74a880506f1..237c30db8c3f 100644
--- a/drivers/staging/rtl8192e/r8192E_dm.h
+++ b/drivers/staging/rtl8192e/r8192E_dm.h
@@ -261,7 +261,6 @@ typedef struct tag_Tx_Config_Cmd_Format
/*------------------------Export global variable----------------------------*/
extern dig_t dm_digtable;
-extern u8 dm_shadow[16][256];
extern DRxPathSel DM_RxPathSelTable;
/*------------------------Export global variable----------------------------*/
@@ -302,7 +301,6 @@ extern void dm_fsync_timer_callback(unsigned long data);
extern bool dm_check_lbus_status(struct net_device *dev);
#endif
extern void dm_check_fsync(struct net_device *dev);
-extern void dm_shadow_init(struct net_device *dev);
extern void dm_initialize_txpower_tracking(struct net_device *dev);
diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c
index 5742cee81203..5ae65164af5c 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.c
+++ b/drivers/staging/rtl8192e/r8192E_wx.c
@@ -70,7 +70,7 @@ static int r8192_wx_set_rate(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -90,7 +90,7 @@ static int r8192_wx_set_rts(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -117,7 +117,7 @@ static int r8192_wx_set_power(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -144,7 +144,7 @@ static int r8192_wx_set_rawtx(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -182,7 +182,7 @@ static int r8192_wx_set_crcmon(struct net_device *dev,
int enable = (parms[0] > 0);
short prev = priv->crcmon;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -212,7 +212,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
RT_RF_POWER_STATE rtState;
int ret;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
rtState = priv->ieee80211->eRFPowerState;
@@ -383,7 +383,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
RT_RF_POWER_STATE rtState;
int ret;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
rtState = priv->ieee80211->eRFPowerState;
@@ -452,7 +452,7 @@ static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
if(!priv->up) return -ENETDOWN;
@@ -474,7 +474,7 @@ static int r8192_wx_set_essid(struct net_device *dev,
RT_RF_POWER_STATE rtState;
int ret;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
rtState = priv->ieee80211->eRFPowerState;
@@ -518,7 +518,7 @@ static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -544,7 +544,7 @@ static int r8192_wx_set_frag(struct net_device *dev,
{
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
if (wrqu->frag.disabled)
@@ -585,7 +585,7 @@ static int r8192_wx_set_wap(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
// struct sockaddr *temp = (struct sockaddr *)awrq;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -641,7 +641,7 @@ static int r8192_wx_set_enc(struct net_device *dev,
{0x00,0x00,0x00,0x00,0x00,0x03} };
int i;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
if(!priv->up) return -ENETDOWN;
@@ -786,7 +786,7 @@ static int r8192_wx_set_retry(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
int err = 0;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -882,7 +882,7 @@ static int r8192_wx_set_sens(struct net_device *dev,
short err = 0;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -911,7 +911,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_device* ieee = priv->ieee80211;
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -1016,7 +1016,7 @@ static int r8192_wx_set_auth(struct net_device *dev,
//printk("====>%s()\n", __FUNCTION__);
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -1034,7 +1034,7 @@ static int r8192_wx_set_mlme(struct net_device *dev,
int ret=0;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
@@ -1051,7 +1051,7 @@ static int r8192_wx_set_gen_ie(struct net_device *dev,
int ret=0;
struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->bHwRadioOff == true)
+ if (priv->bHwRadioOff)
return 0;
down(&priv->wx_sem);
diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h
index 047030bc051a..291cb6a24486 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.h
+++ b/drivers/staging/rtl8192e/r8192E_wx.h
@@ -17,5 +17,5 @@
//#include <linux/wireless.h>
extern struct iw_handler_def r8192_wx_handlers_def;
/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
-extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
+struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
#endif
diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c
index 521d49f8f8ea..c691bc9d88bb 100644
--- a/drivers/staging/rtl8192e/r8192_pm.c
+++ b/drivers/staging/rtl8192e/r8192_pm.c
@@ -17,7 +17,7 @@
int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state)
{
printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event);
- return(-EAGAIN);
+ return -EAGAIN;
}
@@ -104,7 +104,7 @@ out_pci_suspend:
netif_device_detach(dev);
pci_save_state(pdev);
pci_disable_device(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev,state),\
+ pci_enable_wake(pdev, pci_choose_state(pdev,state),
priv->ieee80211->bSupportRemoteWakeUp?1:0);
pci_set_power_state(pdev,pci_choose_state(pdev,state));
@@ -166,5 +166,5 @@ int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable)
{
printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n",
state.event, enable);
- return(-EAGAIN);
+ return -EAGAIN;
}
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
index 87c334fb7333..135439d12428 100644
--- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
@@ -24,41 +24,14 @@
#include "r8192E.h"
#include "r8192E_hw.h"
#include "r819xE_cmdpkt.h"
-/*---------------------------Define Local Constant---------------------------*/
-/* Debug constant*/
-#define CMPK_DEBOUNCE_CNT 1
-/* 2007/10/24 MH Add for printing a range of data. */
-#define CMPK_PRINT(Address)\
-{\
- unsigned char i;\
- u32 temp[10];\
- \
- memcpy(temp, Address, 40);\
- for (i = 0; i <40; i+=4)\
- printk("\r\n %08x", temp[i]);\
-}\
-
-/*---------------------------Define functions---------------------------------*/
-/*-----------------------------------------------------------------------------
- * Function: cmpk_message_handle_tx()
- *
- * Overview: Driver internal module can call the API to send message to
- * firmware side. For example, you can send a debug command packet.
- * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
- * Otherwise, you can change MAC/PHT/RF register by firmware at
- * run time. We do not support message more than one segment now.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/06/2008 amy porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+
+/*
+ * Driver internal module can call the API to send message to
+ * firmware side. For example, you can send a debug command packet.
+ * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
+ * Otherwise, you can change MAC/PHT/RF register by firmware at
+ * run time. We do not support message more than one segment now.
+ */
RT_STATUS cmpk_message_handle_tx(
struct net_device *dev,
u8* code_virtual_address,
@@ -156,26 +129,9 @@ Failed:
#endif
-} /* CMPK_Message_Handle_Tx */
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_counttxstatistic()
- *
- * Overview:
- *
- * Input: PADAPTER pAdapter - .
- * CMPK_TXFB_T *psTx_FB - .
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void
+}
+
+static void
cmpk_count_txstatistic(
struct net_device *dev,
cmpk_txfb_t *pstx_fb)
@@ -250,32 +206,18 @@ cmpk_count_txstatistic(
priv->stats.txretrycount += pstx_fb->retry_cnt;
priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
-} /* cmpk_CountTxStatistic */
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_handle_tx_feedback()
- *
- * Overview: The function is responsible for extract the message inside TX
- * feedbck message from firmware. It will contain dedicated info in
- * ws-06-0063-rtl8190-command-packet-specification. Please
- * refer to chapter "TX Feedback Element". We have to read 20 bytes
- * in the command packet.
- *
- * Input: struct net_device * dev
- * u8 * pmsg - Msg Ptr of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/08/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void
+}
+
+
+
+/*
+ * The function is responsible for extract the message inside TX
+ * feedbck message from firmware. It will contain dedicated info in
+ * ws-06-0063-rtl8190-command-packet-specification. Please
+ * refer to chapter "TX Feedback Element". We have to read 20 bytes
+ * in the command packet.
+ */
+static void
cmpk_handle_tx_feedback(
struct net_device *dev,
u8 * pmsg)
@@ -334,58 +276,15 @@ cmpk_handle_tx_feedback(
or multicast. */
//CountTxStatistics( pAdapter, &tcb );
-} /* cmpk_Handle_Tx_Feedback */
-
-static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 tx_rate;
- {
- //
- // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn.
- //
- if((priv->ieee80211->current_network.mode == IEEE_A) ||
- (priv->ieee80211->current_network.mode == IEEE_N_5G) ||
- ((priv->ieee80211->current_network.mode == IEEE_N_24G) && (!priv->ieee80211->pHTInfo->bCurSuppCCK)))
- {
- tx_rate = 60;
- DMESG("send beacon frame tx rate is 6Mbpm\n");
- }
- else
- {
- tx_rate =10;
- DMESG("send beacon frame tx rate is 1Mbpm\n");
- }
-
- //rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon
-
- }
-
}
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_handle_interrupt_status()
- *
- * Overview: The function is responsible for extract the message from
- * firmware. It will contain dedicated info in
- * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
- * Please refer to chapter "Interrupt Status Element".
- *
- * Input: struct net_device *dev,
- * u8* pmsg - Message Pointer of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Add this for rtl8192 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+/*
+ * The function is responsible for extract the message from
+ * firmware. It will contain dedicated info in
+ * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
+ * Please refer to chapter "Interrupt Status Element".
+ */
static void
cmpk_handle_interrupt_status(
struct net_device *dev,
@@ -432,12 +331,6 @@ cmpk_handle_interrupt_status(
priv->ieee80211->bibsscoordinator = false;
priv->stats.txbeaconerr++;
}
-
- if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
- {
- cmdpkt_beacontimerinterrupt_819xusb(dev);
- }
-
}
// Other informations in interrupt status we need?
@@ -445,28 +338,15 @@ cmpk_handle_interrupt_status(
DMESG("<---- cmpk_handle_interrupt_status()\n");
-} /* cmpk_handle_interrupt_status */
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_handle_query_config_rx()
- *
- * Overview: The function is responsible for extract the message from
- * firmware. It will contain dedicated info in
- * ws-06-0063-rtl8190-command-packet-specification. Please
- * refer to chapter "Beacon State Element".
- *
- * Input: u8 * pmsg - Message Pointer of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+/*
+ * The function is responsible for extract the message from
+ * firmware. It will contain dedicated info in
+ * ws-06-0063-rtl8190-command-packet-specification. Please
+ * refer to chapter "Beacon State Element".
+ */
static void
cmpk_handle_query_config_rx(
struct net_device *dev,
@@ -493,26 +373,13 @@ cmpk_handle_query_config_rx(
rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
(pmsg[14] << 8) | (pmsg[15] << 0);
-} /* cmpk_Handle_Query_Config_Rx */
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_count_tx_status()
- *
- * Overview: Count aggregated tx status from firmwar of one type rx command
- * packet element id = RX_TX_STATUS.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+/*
+ * Count aggregated tx status from firmwar of one type rx command
+ * packet element id = RX_TX_STATUS.
+ */
static void cmpk_count_tx_status( struct net_device *dev,
cmpk_tx_status_t *pstx_status)
{
@@ -559,27 +426,14 @@ static void cmpk_count_tx_status( struct net_device *dev,
priv->stats.txbytesunicast += pstx_status->txuclength;
priv->stats.last_packet_rate = pstx_status->rate;
-} /* cmpk_CountTxStatus */
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_handle_tx_status()
- *
- * Overview: Firmware add a new tx feedback status to reduce rx command
- * packet buffer operation load.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+
+/*
+ * Firmware add a new tx feedback status to reduce rx command
+ * packet buffer operation load.
+ */
static void
cmpk_handle_tx_status(
struct net_device *dev,
@@ -591,25 +445,10 @@ cmpk_handle_tx_status(
/* 2. Use tx feedback info to count TX statistics. */
cmpk_count_tx_status(dev, &rx_tx_sts);
-} /* cmpk_Handle_Tx_Status */
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_handle_tx_rate_history()
- *
- * Overview: Firmware add a new tx rate history
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/12/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+/* Firmware add a new tx rate history */
static void
cmpk_handle_tx_rate_history(
struct net_device *dev,
@@ -671,29 +510,16 @@ cmpk_handle_tx_rate_history(
priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
}
-} /* cmpk_Handle_Tx_Rate_History */
-
-
-/*-----------------------------------------------------------------------------
- * Function: cmpk_message_handle_rx()
- *
- * Overview: In the function, we will capture different RX command packet
- * info. Every RX command packet element has different message
- * length and meaning in content. We only support three type of RX
- * command packet now. Please refer to document
- * ws-06-0063-rtl8190-command-packet-specification.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/06/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
+}
+
+
+/*
+ * In the function, we will capture different RX command packet
+ * info. Every RX command packet element has different message
+ * length and meaning in content. We only support three type of RX
+ * command packet now. Please refer to document
+ * ws-06-0063-rtl8190-command-packet-specification.
+ */
u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats)
{
// u32 debug_level = DBG_LOUD;
@@ -801,4 +627,4 @@ u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *ps
return 1; /* This is a command packet. */
RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
-} /* CMPK_Message_Handle_Rx */
+}
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.h b/drivers/staging/rtl8192e/r819xE_cmdpkt.h
index 8fe2b9e949ed..8d705ce4da12 100644
--- a/drivers/staging/rtl8192e/r819xE_cmdpkt.h
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.h
@@ -201,7 +201,7 @@ typedef enum tag_command_packet_directories
RX_CMD_ELE_MAX
}cmpk_element_e;
-extern u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats);
+u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats);
#endif
diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c
index 793a17545554..5c3da468f0dc 100644
--- a/drivers/staging/rtl8192e/r819xE_firmware.c
+++ b/drivers/staging/rtl8192e/r819xE_firmware.c
@@ -1,18 +1,9 @@
/*
* Procedure: Init boot code/firmware code/data session
*
- * Description: This routine will intialize firmware. If any error occurs
+ * Description: This routine will initialize firmware. If any error occurs
* during the initialization process, the routine shall terminate
- * immediately and return fail. NIC driver should call
- * NdisOpenFile only from MiniportInitialize.
- *
- * Arguments: The pointer of the adapter
- *
- * Returns:
- * NDIS_STATUS_FAILURE - the following initialization process
- * should be terminated
- * NDIS_STATUS_SUCCESS - if firmware initialization process
- * success
+ * immediately and return fail.
*/
#include "r8192E.h"
@@ -91,16 +82,16 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
* Transform from little endian to big endian and pending zero
*/
for (i = 0; i < frag_length; i += 4) {
- *seg_ptr++ = ((i+0) < frag_length) ? \
+ *seg_ptr++ = ((i+0) < frag_length) ?
code_virtual_address[i+3] : 0;
- *seg_ptr++ = ((i+1) < frag_length) ? \
+ *seg_ptr++ = ((i+1) < frag_length) ?
code_virtual_address[i+2] : 0;
- *seg_ptr++ = ((i+2) < frag_length) ? \
+ *seg_ptr++ = ((i+2) < frag_length) ?
code_virtual_address[i+1] : 0;
- *seg_ptr++ = ((i+3) < frag_length) ? \
+ *seg_ptr++ = ((i+3) < frag_length) ?
code_virtual_address[i+0] : 0;
}
tcb_desc->txbuf_size = (u16)i;
@@ -116,18 +107,11 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
}
/*
- * Procedure: Check whether main code is download OK. If OK, turn on CPU
- *
- * Description: CPU register locates in different page against general
- * register. Switch to CPU register in the begin and switch
- * back before return
- *
- * Arguments: The pointer of the adapter
+ * Check whether main code is download OK. If OK, turn on CPU
*
- * Returns:
- * NDIS_STATUS_FAILURE - the following initialization process should be
- * terminated
- * NDIS_STATUS_SUCCESS - if firmware initialization process success
+ * CPU register locates in different page against general
+ * register. Switch to CPU register in the begin and switch
+ * back before return
*/
static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
{
@@ -249,7 +233,7 @@ bool init_firmware(struct net_device *dev)
* Download boot, main, and data image for System reset.
* Download data image for firmware reseta
*/
- for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; \
+ for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA;
init_step++) {
/*
* Open Image file, and map file to contineous memory if open file success.
@@ -266,7 +250,7 @@ bool init_firmware(struct net_device *dev)
}
if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
- RT_TRACE(COMP_FIRMWARE, \
+ RT_TRACE(COMP_FIRMWARE,
"img file size exceed the container buffer fail!\n");
goto download_firmware_fail;
}
diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c
index ffd1e97e27b9..d83bcbcb20bd 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.c
+++ b/drivers/staging/rtl8192e/r819xE_phy.c
@@ -1477,7 +1477,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32
write_nic_dword(dev, dwRegAddr, NewValue);
}else
write_nic_dword(dev, dwRegAddr, dwData);
- return;
}
/******************************************************************************
*function: This function reads specific bits from BB register
@@ -1490,13 +1489,11 @@ void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32
* ****************************************************************************/
u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask)
{
- u32 Ret = 0, OriginalValue, BitShift;
+ u32 OriginalValue, BitShift;
OriginalValue = read_nic_dword(dev, dwRegAddr);
BitShift = rtl8192_CalculateBitShift(dwBitMask);
- Ret = (OriginalValue & dwBitMask) >> BitShift;
-
- return (Ret);
+ return (OriginalValue & dwBitMask) >> BitShift;
}
/******************************************************************************
*function: This function read register from RF chip
@@ -1705,8 +1702,6 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E
#endif
#endif
}
-
- return;
}
/******************************************************************************
@@ -1764,7 +1759,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
}
//spin_unlock_irqrestore(&priv->rf_lock, flags);
//up(&priv->rf_sem);
- return;
}
/******************************************************************************
@@ -1801,7 +1795,7 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
Readback_Value = (Original_Value & BitMask) >> BitShift;
up(&priv->rf_sem);
// udelay(200);
- return (Readback_Value);
+ return Readback_Value;
}
/******************************************************************************
@@ -1816,7 +1810,6 @@ static u32 phy_FwRFSerialRead(
RF90_RADIO_PATH_E eRFPath,
u32 Offset )
{
- u32 retValue = 0;
u32 Data = 0;
u8 time = 0;
//DbgPrint("FW RF CTRL\n\r");
@@ -1857,13 +1850,10 @@ static u32 phy_FwRFSerialRead(
udelay(10);
}
else
- return (0);
+ return 0;
}
- retValue = read_nic_dword(dev, RF_DATA);
-
- return (retValue);
-
-} /* phy_FwRFSerialRead */
+ return read_nic_dword(dev, RF_DATA);
+}
/******************************************************************************
*function: We support firmware to execute RF-R/W.
@@ -1917,7 +1907,7 @@ phy_FwRFSerialWrite(
/* 2008/01/17 MH We support delay in firmware side now. */
//delay_us(20);
-} /* phy_FwRFSerialWrite */
+}
/******************************************************************************
@@ -1967,8 +1957,6 @@ if(Adapter->bInHctTest)
}
rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
}
- return;
-
}
/******************************************************************************
@@ -2039,9 +2027,6 @@ void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType)
RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x \n",i, Rtl819XAGCTAB_Array_Table[i], Rtl819XAGCTAB_Array_Table[i+1]);
}
}
- return;
-
-
}
/******************************************************************************
*function: This function initialize Register definition offset for Radio Path
@@ -2324,12 +2309,10 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev)
* ***************************************************************************/
RT_STATUS rtl8192_BBConfig(struct net_device* dev)
{
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
rtl8192_InitBBRFRegDef(dev);
//config BB&RF. As hardCode based initialization has not been well
//implemented, so use file first.FIXME:should implement it for hardcode?
- rtStatus = rtl8192_BB_Config_ParaFile(dev);
- return rtStatus;
+ return rtl8192_BB_Config_ParaFile(dev);
}
/******************************************************************************
@@ -2381,7 +2364,6 @@ void rtl8192_phy_getTxPower(struct net_device* dev)
rOFDM0_RxDetector3, priv->framesync);
// read SIFS (save the value read fome MACPHY_REG.txt)
priv->SifsTime = read_nic_word(dev, SIFS);
- return;
}
/******************************************************************************
@@ -2503,7 +2485,6 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel)
RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", __FUNCTION__);
break;
}
- return;
}
/******************************************************************************
@@ -2546,7 +2527,6 @@ RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev)
* ***************************************************************************/
void rtl8192_phy_updateInitGain(struct net_device* dev)
{
- return;
}
/******************************************************************************
@@ -2653,7 +2633,6 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
break;
}
- return;
}
/****************************************************************************************
*function: This function set command table variable(struct SwChnlCmd).
@@ -3088,7 +3067,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
u8 regBwOpMode;
- RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", \
+ RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n",
priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")
diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h
index 41e0d777eabd..95a509fa35f8 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.h
+++ b/drivers/staging/rtl8192e/r819xE_phy.h
@@ -102,62 +102,50 @@ typedef enum _RF90_RADIO_PATH {
#define bMaskLWord 0x0000ffff
#define bMaskDWord 0xffffffff
-/*extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
+u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath);
-extern u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
- RF90_RADIO_PATH_E eRFPath, u32 Offset);
-
-extern void rtl8192_phy_RFSerialWrite(struct net_device *dev,
- RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-
-extern void rtl8192_InitBBRFRegDef(struct net_device *dev);
-
-extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device *dev); */
-
-extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath);
-
-extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr,
+void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr,
u32 dwBitMask, u32 dwData);
-extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr,
+u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr,
u32 dwBitMask);
-extern void rtl8192_phy_SetRFReg(struct net_device *dev,
+void rtl8192_phy_SetRFReg(struct net_device *dev,
RF90_RADIO_PATH_E eRFPath, u32 RegAddr,
u32 BitMask, u32 Data);
-extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
+u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
-extern void rtl8192_phy_configmac(struct net_device *dev);
+void rtl8192_phy_configmac(struct net_device *dev);
-extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
+void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
-extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev,
+RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev,
HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
-extern RT_STATUS rtl8192_BBConfig(struct net_device *dev);
+RT_STATUS rtl8192_BBConfig(struct net_device *dev);
-extern void rtl8192_phy_getTxPower(struct net_device *dev);
+void rtl8192_phy_getTxPower(struct net_device *dev);
-extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel);
+void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel);
-extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
+RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
-extern void rtl8192_phy_updateInitGain(struct net_device* dev);
+void rtl8192_phy_updateInitGain(struct net_device* dev);
-extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
+u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
RF90_RADIO_PATH_E eRFPath);
-extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel);
+u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel);
-extern void rtl8192_SetBWMode(struct net_device *dev,
+void rtl8192_SetBWMode(struct net_device *dev,
HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
+void rtl8192_SwChnl_WorkItem(struct net_device *dev);
-extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
+void rtl8192_SetBWModeWorkItem(struct net_device *dev);
-extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
+void InitialGain819xPci(struct net_device *dev, u8 Operation);
#endif /* _R819XU_PHY_H */
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig
deleted file mode 100644
index 27b89a432670..000000000000
--- a/drivers/staging/rtl8192su/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config RTL8192SU
- tristate "RealTek RTL8192SU Wireless LAN NIC driver"
- depends on PCI && WLAN && USB
- select WIRELESS_EXT
- select WEXT_PRIV
- select EEPROM_93CX6
- select CRYPTO
- default N
- ---help---
diff --git a/drivers/staging/rtl8192su/Makefile b/drivers/staging/rtl8192su/Makefile
deleted file mode 100644
index 7133894afe76..000000000000
--- a/drivers/staging/rtl8192su/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-NIC_SELECT = RTL8192SU
-
-EXTRA_CFLAGS += -std=gnu89
-EXTRA_CFLAGS += -O2
-
-EXTRA_CFLAGS += -DJACKSON_NEW_RX
-EXTRA_CFLAGS += -DTHOMAS_BEACON
-
-#EXTRA_CFLAGS += -DMUTIPLE_BULK_OUT
-
-r8192s_usb-objs := \
- r8192U_wx.o \
- r8192S_phy.o \
- r8192S_rtl6052.o \
- r8192S_rtl8225.o \
- r819xU_cmdpkt.o \
- r8192U_dm.o \
- r8192SU_HWImg.o \
- r8192S_firmware.o \
- r8192S_Efuse.o \
- r8192U_core.o \
- r8192U_pm.o \
- r8192SU_led.o \
- ieee80211/ieee80211_crypt.o \
- ieee80211/ieee80211_crypt_tkip.o \
- ieee80211/ieee80211_crypt_ccmp.o \
- ieee80211/ieee80211_crypt_wep.o \
- ieee80211/ieee80211_rx.o \
- ieee80211/ieee80211_softmac.o \
- ieee80211/ieee80211_tx.o \
- ieee80211/ieee80211_wx.o \
- ieee80211/ieee80211_module.o \
- ieee80211/ieee80211_softmac_wx.o\
- ieee80211/rtl819x_HTProc.o \
- ieee80211/rtl819x_TSProc.o \
- ieee80211/rtl819x_BAProc.o \
- ieee80211/dot11d.o
-
-obj-$(CONFIG_RTL8192SU) += r8192s_usb.o
diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO
deleted file mode 100644
index b15204ea4ec4..000000000000
--- a/drivers/staging/rtl8192su/TODO
+++ /dev/null
@@ -1,21 +0,0 @@
-TODO:
-- merge realteks bugfixes and new features into the driver:
- - an updated version of this driver can be found here:
- http://www.getnet.eu/products_GN-621U.html
- - note:
- realtek has stripped alomost all comments from the source,
- so please leave all comments that may help in development in the code.
-- prepare private ieee80211 stack for merge with rtl8187se's version:
- - remove rtl8192su's specific dead code
- - cleanup ieee80211.h
- - move rtl8192su's specific code out from ieee80211.h
- - abstract rtl819su's specific code
-- switch to use shared "librtl" instead of private ieee80211 stack
-- switch to use LIB80211
-- switch to use MAC80211
-- use kernel coding style
-- checkpatch.pl fixes
-- sparse fixes
-- integrate with drivers/net/wireless/rtl818x
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
diff --git a/drivers/staging/rtl8192su/authors b/drivers/staging/rtl8192su/authors
deleted file mode 100644
index b08bbae39e72..000000000000
--- a/drivers/staging/rtl8192su/authors
+++ /dev/null
@@ -1 +0,0 @@
-Andrea Merello <andreamrl@tiscali.it>
diff --git a/drivers/staging/rtl8192su/ieee80211/Makefile b/drivers/staging/rtl8192su/ieee80211/Makefile
deleted file mode 100644
index a500bfaeaef2..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-NIC_SELECT = RTL8192SU
-
-EXTRA_CFLAGS += -O2
-EXTRA_CFLAGS += -DRTL8192S_DISABLE_FW_DM=0
-EXTRA_CFLAGS += -DRTL8192SU
-#EXTRA_CFLAGS += -DJOHN_NOCPY
-EXTRA_CFLAGS += -DTHOMAS_TURBO
-
-ieee80211-rsl-objs := ieee80211_rx.o \
- ieee80211_softmac.o \
- ieee80211_tx.o \
- ieee80211_wx.o \
- ieee80211_module.o \
- ieee80211_softmac_wx.o\
- rtl819x_HTProc.o\
- rtl819x_TSProc.o\
- rtl819x_BAProc.o\
- dot11d.o
-
-ieee80211_crypt-rsl-objs := ieee80211_crypt.o
-ieee80211_crypt_tkip-rsl-objs := ieee80211_crypt_tkip.o
-ieee80211_crypt_ccmp-rsl-objs := ieee80211_crypt_ccmp.o
-ieee80211_crypt_wep-rsl-objs := ieee80211_crypt_wep.o
-
-obj-m +=ieee80211-rsl.o
-obj-m +=ieee80211_crypt-rsl.o
-obj-m +=ieee80211_crypt_wep-rsl.o
-obj-m +=ieee80211_crypt_tkip-rsl.o
-obj-m +=ieee80211_crypt_ccmp-rsl.o
-
diff --git a/drivers/staging/rtl8192su/ieee80211/dot11d.c b/drivers/staging/rtl8192su/ieee80211/dot11d.c
deleted file mode 100644
index 6275cc75ec85..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/dot11d.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-#include "dot11d.h"
-
-void
-Dot11d_Init(struct ieee80211_device *ieee)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- pDot11dInfo->bEnabled = 0;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- RESET_CIE_WATCHDOG(ieee);
-
- printk("Dot11d_Init()\n");
-}
-
-//
-// Description:
-// Reset to the state as we are just entering a regulatory domain.
-//
-void
-Dot11d_Reset(struct ieee80211_device *ieee)
-{
- u32 i;
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- // Clear old channel map
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- // Set new channel map
- for (i=1; i<=11; i++) {
- (pDot11dInfo->channel_map)[i] = 1;
- }
- for (i=12; i<=14; i++) {
- (pDot11dInfo->channel_map)[i] = 2;
- }
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- RESET_CIE_WATCHDOG(ieee);
-
-}
-
-//
-// Description:
-// Update country IE from Beacon or Probe Resopnse
-// and configure PHY for operation in the regulatory domain.
-//
-// TODO:
-// Configure Tx power.
-//
-// Assumption:
-// 1. IS_DOT11D_ENABLE() is TRUE.
-// 2. Input IE is an valid one.
-//
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 i, j, NumTriples, MaxChnlNum;
- PCHNL_TXPOWER_TRIPLE pTriple;
-
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- MaxChnlNum = 0;
- NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
- pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- for(i = 0; i < NumTriples; i++)
- {
- if(MaxChnlNum >= pTriple->FirstChnl)
- { // It is not in a monotonically increasing order, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- return;
- }
- if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
- { // It is not a valid set of channel id, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- return;
- }
-
- for(j = 0 ; j < pTriple->NumChnls; j++)
- {
- pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
- pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
- MaxChnlNum = pTriple->FirstChnl + j;
- }
-
- pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
- }
-#if 1
- printk("Channel List:");
- for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- if(pDot11dInfo->channel_map[i] > 0)
- printk(" %d", i);
- printk("\n");
-#endif
-
- UPDATE_CIE_SRC(dev, pTaddr);
-
- pDot11dInfo->CountryIeLen = CoutryIeLen;
- memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
- pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 MaxTxPwrInDbm = 255;
-
- if(MAX_CHANNEL_NUMBER < Channel)
- {
- printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- return MaxTxPwrInDbm;
- }
- if(pDot11dInfo->channel_map[Channel])
- {
- MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
- }
-
- return MaxTxPwrInDbm;
-}
-
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- switch(pDot11dInfo->State)
- {
- case DOT11D_STATE_LEARNED:
- pDot11dInfo->State = DOT11D_STATE_DONE;
- break;
-
- case DOT11D_STATE_DONE:
- if( GET_CIE_WATCHDOG(dev) == 0 )
- { // Reset country IE if previous one is gone.
- Dot11d_Reset(dev);
- }
- break;
- case DOT11D_STATE_NONE:
- break;
- }
-}
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return 0;
- }
- if(pDot11dInfo->channel_map[channel] > 0)
- return 1;
- return 0;
-}
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 default_chn = 0;
- u32 i = 0;
-
- for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
- {
- if(pDot11dInfo->channel_map[i] > 0)
- {
- default_chn = i;
- break;
- }
- }
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return default_chn;
- }
-
- if(pDot11dInfo->channel_map[channel] > 0)
- return channel;
-
- return default_chn;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/dot11d.h b/drivers/staging/rtl8192su/ieee80211/dot11d.h
deleted file mode 100644
index 62a2c905e1fa..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/dot11d.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-}DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
-
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
-
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
deleted file mode 100644
index 1d6789db4e4d..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h
+++ /dev/null
@@ -1,1934 +0,0 @@
-/*
- * 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
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andreamrl@tiscali.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-
-#include <linux/delay.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-
-#include "rtl819x_HT.h"
-#include "rtl819x_BA.h"
-#include "rtl819x_TS.h"
-
-#define KEY_TYPE_NA 0x0
-#define KEY_TYPE_WEP40 0x1
-#define KEY_TYPE_TKIP 0x2
-#define KEY_TYPE_CCMP 0x4
-#define KEY_TYPE_WEP104 0x5
-
-#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A) || \
- (priv->ieee80211->current_network.mode == IEEE_N_24G) || \
- (priv->ieee80211->current_network.mode == IEEE_N_5G)) \
- ? 16 : 10)
-
-#define MGMT_QUEUE_NUM 5
-
-#define IEEE_CMD_SET_WPA_PARAM 1
-#define IEEE_CMD_SET_WPA_IE 2
-#define IEEE_CMD_SET_ENCRYPTION 3
-#define IEEE_CMD_MLME 4
-
-#define IEEE_PARAM_WPA_ENABLED 1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
-#define IEEE_PARAM_DROP_UNENCRYPTED 3
-#define IEEE_PARAM_PRIVACY_INVOKED 4
-#define IEEE_PARAM_AUTH_ALGS 5
-#define IEEE_PARAM_IEEE_802_1X 6
-//It should consistent with the driver_XXX.c
-// David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT 7
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_PROTO_WPA 1
-#define IEEE_PROTO_RSN 2
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_WPAX_USEGROUP 0
-#define IEEE_WPAX_WEP40 1
-#define IEEE_WPAX_TKIP 2
-#define IEEE_WPAX_WRAP 3
-#define IEEE_WPAX_CCMP 4
-#define IEEE_WPAX_WEP104 5
-
-#define IEEE_KEY_MGMT_IEEE8021X 1
-#define IEEE_KEY_MGMT_PSK 2
-
-#define IEEE_MLME_STA_DEAUTH 1
-#define IEEE_MLME_STA_DISASSOC 2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
-
-
-#define IEEE_CRYPT_ALG_NAME_LEN 16
-
-#define MAX_IE_LEN 0xff
-
-typedef struct ieee_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 name;
- u32 value;
- } wpa_param;
- struct {
- u32 len;
- u8 reserved[32];
- u8 data[0];
- } wpa_ie;
- struct{
- int command;
- int reason_code;
- } mlme;
- struct {
- u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
- u8 set_tx;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- } u;
-}ieee_param;
-
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rsl msleep_interruptible
-
-#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 IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD 256U
-#define MAX_FRAG_THRESHOLD 2346U
-
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_FRAMETYPE 0x00fc
-#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
-#define IEEE80211_FCTL_WEP 0x4000
-
-/* management */
-#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
-
-/* control */
-#define IEEE80211_STYPE_BLOCKACK 0x0094
-
-/* QOS control */
-#define IEEE80211_QCTL_TID 0x000F
-
-#define OUI_SUBTYPE_WMM_INFO 0
-#define OUI_SUBTYPE_WMM_PARAM 1
-#define OUI_SUBTYPE_QOS_CAPABI 5
-
-/* debug macros */
-#define CONFIG_IEEE80211_DEBUG
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
- do { \
- if (ieee80211_debug_level & (level)) \
- printk(KERN_DEBUG "ieee80211: " fmt, ## args); \
- } while (0)
-#define IEEE80211_DEBUG_DATA(level, data, datalen) \
- do { \
- if ((ieee80211_debug_level & (level)) == (level)) { \
- u8 *pdata = (u8 *)data; \
- int i; \
- printk(KERN_DEBUG "ieee80211: %s()\n", __func__); \
- for (i = 0; i < (int)(datalen); i++) { \
- printk("%2x ", pdata[i]); \
- if ((i + 1) % 16 == 0) \
- printk("\n"); \
- } \
- printk("\n"); \
- } \
- } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
-#endif /* CONFIG_IEEE80211_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/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_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_EAP (1<<6)
-#define IEEE80211_DL_DROP (1<<7)
-
-#define IEEE80211_DL_TX (1<<8)
-#define IEEE80211_DL_RX (1<<9)
-
-#define IEEE80211_DL_HT (1 << 10)
-#define IEEE80211_DL_BA (1 << 11)
-#define IEEE80211_DL_TS (1 << 12)
-#define IEEE80211_DL_QOS (1 << 13)
-#define IEEE80211_DL_REORDER (1 << 14)
-#define IEEE80211_DL_IOT (1 << 15)
-#define IEEE80211_DL_IPS (1 << 16)
-#define IEEE80211_DL_TRACE (1 << 29)
-#define IEEE80211_DL_DATA (1 << 30)
-#define IEEE80211_DL_ERR (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_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, 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
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#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_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-
-#define RTL_WLAN_AUTH_LEAP 2
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-#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_LEN 4
-#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_LEN 8
-#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
-
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK 0x0c
-#define IEEE80211_FC0_TYPE_DATA 0x08
-#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS 0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
- (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
- (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num[17];
- u16 frag_num[17];
- unsigned long packet_time[17];
- struct list_head list;
-};
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- * information for frames received. Not setting these will not cause
- * any adverse affects. */
-struct ieee80211_rx_stats {
- u32 mac_time[2];
- 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;
- u8 nic_type;
-
- u16 Length;
- u8 SignalQuality; /* in 0-100 index */
- /* real power in dBm for this packet, no beautification & aggregation */
- s32 RecvSignalPower;
- s8 RxPower; /* in dBm Translate from PWdB */
- u8 SignalStrength; /* in 0-100 index */
- u16 bHwError:1;
- u16 bCRC:1;
- u16 bICV:1;
- u16 bShortPreamble:1;
- u16 Antenna:1; /* RTL8185 */
- u16 Decrypted:1; /* RTL8185, RTL8187 */
- u16 Wakeup:1; /* RTL8185 */
- u16 Reserved0:1; /* RTL8185 */
- u8 AGC;
- u32 TimeStampLow;
- u32 TimeStampHigh;
- bool bShift;
- bool bIsQosData;
- u8 UserPriority;
-
- /* < 11n or 8190 specific code */
- u8 RxDrvInfoSize;
- u8 RxBufShift;
- bool bIsAMPDU;
- bool bFirstMPDU;
- bool bContainHTC;
- bool RxIs40MHzPacket;
- u32 RxPWDBAll;
- u8 RxMIMOSignalStrength[4]; /* in 0~100 index */
- s8 RxMIMOSignalQuality[2];
- bool bPacketMatchBSSID;
- bool bIsCCK;
- bool bPacketToSelf;
-
- u8 *virtual_address;
- /* total packet length: must equal to sum of all FragLength */
- u16 packetlength;
- /* FragLength should equal to PacketLength in non-fragment case */
- u16 fraglength;
- u16 fragoffset; /* data offset for this fragment */
- u16 ntotalfrag;
- bool bisrxaggrsubframe;
- bool bPacketBeacon; /* for rssi */
- bool bToSelfBA; /* for rssi */
- char cck_adc_pwdb[4]; /* for rx path selection */
- u16 Seq_Num;
- u8 nTotalAggPkt; /* number of aggregated packets */
-};
-
-/* 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;
-
-#include "ieee80211_crypt.h"
-
-#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_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 WEP_KEYS 4
-#define WEP_KEY_LEN 13
-#define SCM_KEY_LEN 32
-
-struct ieee80211_security {
- u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1,
- encrypt:1;
- 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
-*/
-
-/* Management Frame Information Element Types */
-enum {
- MFIE_TYPE_SSID = 0,
- MFIE_TYPE_RATES = 1,
- MFIE_TYPE_FH_SET = 2,
- MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
- MFIE_TYPE_TIM = 5,
- MFIE_TYPE_IBSS_SET = 6,
- MFIE_TYPE_COUNTRY = 7,
- MFIE_TYPE_HOP_PARAMS = 8,
- MFIE_TYPE_HOP_TABLE = 9,
- MFIE_TYPE_REQUEST = 10,
- MFIE_TYPE_CHALLENGE = 16,
- MFIE_TYPE_POWER_CONSTRAINT = 32,
- MFIE_TYPE_POWER_CAPABILITY = 33,
- MFIE_TYPE_TPC_REQUEST = 34,
- MFIE_TYPE_TPC_REPORT = 35,
- MFIE_TYPE_SUPP_CHANNELS = 36,
- MFIE_TYPE_CSA = 37,
- MFIE_TYPE_MEASURE_REQUEST = 38,
- MFIE_TYPE_MEASURE_REPORT = 39,
- MFIE_TYPE_QUIET = 40,
- MFIE_TYPE_IBSS_DFS = 41,
- MFIE_TYPE_ERP = 42,
- MFIE_TYPE_RSN = 48,
- MFIE_TYPE_RATES_EX = 50,
- MFIE_TYPE_HT_CAP= 45,
- MFIE_TYPE_HT_INFO= 61,
- MFIE_TYPE_AIRONET=133,
- MFIE_TYPE_GENERIC = 221,
- MFIE_TYPE_QOS_PARAMETER = 222,
-};
-
-/* Minimal header; can be used for passing 802.11 frames with sufficient
- * information to determine what type of underlying data type is actually
- * stored in the data. */
-struct rtl_ieee80211_hdr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 payload[0];
-} __attribute__ ((packed));
-
-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_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_hdr_4addrqos {
- __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];
- __le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
- struct ieee80211_hdr_3addr header;
- __le16 algorithm;
- __le16 transaction;
- __le16 status;
- /* challenge */
- struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc {
- struct ieee80211_hdr_3addr header;
- __le16 reason;
-} __attribute__ ((packed));
-
-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;
- u32 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));
-
-struct ieee80211_assoc_request_frame {
- 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_frame {
- struct ieee80211_hdr_3addr header;
- __le16 capability;
- __le16 listen_interval;
- u8 current_ap[ETH_ALEN];
- /* SSID, supported rates, RSN */
- struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
- struct ieee80211_hdr_3addr header;
- __le16 capability;
- __le16 status;
- __le16 aid;
- struct ieee80211_info_element info_element[0]; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_txb {
- u8 nr_frags;
- u8 encrypted;
- u8 queue_index;
- u8 rts_included;
- u16 reserved;
- __le16 frag_size;
- __le16 payload_size;
- struct sk_buff *fragments[0];
-};
-
-#define MAX_SUBFRAME_COUNT 64
-struct ieee80211_rxb {
- u8 nr_subframes;
- struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
-}__attribute__((packed));
-
-/* 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 MAX_CHANNEL_NUMBER 161
-
-#define IEEE80211_SOFTMAC_SCAN_TIME 100 /* (HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1 << 0)
-#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)
-
-#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));
-
-struct ieee80211_wmm_ac_param {
- u8 ac_aci_acm_aifsn;
- u8 ac_ecwmin_ecwmax;
- u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
- u8 ac_dir_tid;
- u8 ac_up_psb;
- u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
- struct ieee80211_wmm_ts_info ts_info;
- u16 norm_msdu_size;
- u16 max_msdu_size;
- u32 min_serv_inter;
- u32 max_serv_inter;
- u32 inact_inter;
- u32 suspen_inter;
- u32 serv_start_time;
- u32 min_data_rate;
- u32 mean_data_rate;
- u32 peak_data_rate;
- u32 max_burst_size;
- u32 delay_bound;
- u32 min_phy_rate;
- u16 surp_band_allow;
- u16 medium_time;
-}__attribute__((packed));
-
-enum eap_type {
- EAP_PACKET = 0,
- EAPOL_START,
- EAPOL_LOGOFF,
- EAPOL_KEY,
- EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
- [EAP_PACKET] = "EAP-Packet",
- [EAPOL_START] = "EAPOL-Start",
- [EAPOL_LOGOFF] = "EAPOL-Logoff",
- [EAPOL_KEY] = "EAPOL-Key",
- [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
- return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
- u8 snap[6];
- u16 ethertype;
- u8 version;
- u8 type;
- u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats {
- unsigned int rx_ass_ok;
- unsigned int rx_ass_err;
- unsigned int rx_probe_rq;
- unsigned int tx_probe_rs;
- unsigned int tx_beacons;
- unsigned int rx_auth_rq;
- unsigned int rx_auth_rs_ok;
- unsigned int rx_auth_rs_err;
- unsigned int tx_auth_rq;
- unsigned int no_auth_rs;
- unsigned int no_ass_rs;
- unsigned int tx_ass_rq;
- unsigned int rx_ass_rq;
- unsigned int tx_probe_rq;
- unsigned int reassoc;
- unsigned int swtxstop;
- unsigned int swtxawake;
- unsigned char CurrentShowTxate;
- unsigned char last_packet_rate;
- unsigned int txretrycount;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
-} __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;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 2 /* 1Mbps */
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BK 0x00
-#define WME_AC_BE 0x01
-#define WME_AC_VI 0x02
-#define WME_AC_VO 0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
-#define UP2AC(up) ( \
- ((up) < 1) ? WME_AC_BE : \
- ((up) < 3) ? WME_AC_BK : \
- ((up) < 4) ? WME_AC_BE : \
- ((up) < 6) ? WME_AC_VI : \
- WME_AC_VO)
-
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac) ( \
- ((_ac) == WME_AC_VO) ? 6 : \
- ((_ac) == WME_AC_VI) ? 5 : \
- ((_ac) == WME_AC_BK) ? 1 : \
- 0)
-
-#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
-
-/* length of two Ethernet address plus ether type */
-#define ETHERNET_HEADER_SIZE 14
-
-struct ether_header {
- u8 ether_dhost[ETHER_ADDR_LEN];
- u8 ether_shost[ETHER_ADDR_LEN];
- u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define ETHERTYPE_IP 0x0800 /* IP protocol */
-#endif
-
-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;
-
- /* for LEAP */
- bool bWithAironetIE;
- bool bCkipSupported;
- bool bCcxRmEnable;
- u16 CcxRmState[2];
-
- /* CCXv4 S59, MBSSID. */
- bool bMBssidValid;
- u8 MBssidMask;
- u8 MBssid[6];
-
- /* CCX 2 S38, WLAN Device Version Number element. */
- bool bWithCcxVerNum;
- u8 BssCcxVerNumber;
-
- /* 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;
- u8 dtim_period;
- u8 dtim_data;
- u32 last_dtim_sta_time[2];
-
- //appeded for QoS
- u8 wmm_info;
- struct ieee80211_wmm_ac_param wmm_param[4];
- u8 QoS_Enable;
- u8 Turbo_Enable;//enable turbo mode, added by thomas
- u16 CountryIeLen;
- u8 CountryIeBuf[MAX_IE_LEN];
-
- /* HT Related */
- BSS_HT bssht;
- /* Added to handle broadcom AP management frame CCK rate. */
- bool broadcom_cap_exist;
- bool realtek_cap_exit;
- bool marvell_cap_exist;
- bool ralink_cap_exist;
- bool atheros_cap_exist;
- bool cisco_cap_exist;
- bool unknown_cap_exist;
- bool berp_info_valid;
- bool buseprotection;
-
- struct list_head list; /* put at the end of the structure */
-};
-
-enum ieee80211_state {
-
- /* the card is not linked at all */
- IEEE80211_NOLINK = 0,
-
- /* IEEE80211_ASSOCIATING* are for BSS client mode
- * the driver shall not perform RX filtering unless
- * the state is LINKED.
- * The driver shall just check for the state LINKED and
- * defaults to NOLINK for ALL the other states (including
- * LINKED_SCANNING)
- */
-
- /* the association procedure will start (wq scheduling)*/
- IEEE80211_ASSOCIATING,
- IEEE80211_ASSOCIATING_RETRY,
-
- /* the association procedure is sending AUTH request*/
- IEEE80211_ASSOCIATING_AUTHENTICATING,
-
- /* the association procedure has successfully authentcated
- * and is sending association request
- */
- IEEE80211_ASSOCIATING_AUTHENTICATED,
-
- /* the link is ok. the card associated to a BSS or linked
- * to a ibss cell or acting as an AP and creating the bss
- */
- IEEE80211_LINKED,
-
- /* same as LINKED, but the driver shall apply RX filter
- * rules as we are in NO_LINK mode. As the card is still
- * logically linked, but it is doing a syncro site survey
- * then it will be back to LINKED state.
- */
- IEEE80211_LINKED_SCANNING,
-
-};
-
-#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 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)
-
-typedef struct tx_pending_t{
- int frag;
- struct ieee80211_txb *txb;
-}tx_pending_t;
-
-enum {
- COUNTRY_CODE_FCC = 0,
- COUNTRY_CODE_IC = 1,
- COUNTRY_CODE_ETSI = 2,
- COUNTRY_CODE_SPAIN = 3,
- COUNTRY_CODE_FRANCE = 4,
- COUNTRY_CODE_MKK = 5,
- COUNTRY_CODE_MKK1 = 6,
- COUNTRY_CODE_ISRAEL = 7,
- COUNTRY_CODE_TELEC = 8,
- COUNTRY_CODE_MIC = 9,
- COUNTRY_CODE_GLOBAL_DOMAIN = 10,
- COUNTRY_CODE_WORLD_WIDE_13 = 11,
- COUNTRY_CODE_TELEC_NETGEAR = 12,
- COUNTRY_CODE_MAX
-};
-
-#define NUM_PMKID_CACHE 16
-
-typedef struct _RT_PMKID_LIST
-{
- u8 bUsed;
- u8 Bssid[6];
- u8 PMKID[16];
- u8 SsidBuf[33];
- u8* ssid_octet;
- u16 ssid_length;
-} RT_PMKID_LIST, *PRT_PMKID_LIST;
-
-
-#include "ieee80211_r8192s.h"
-
-struct ieee80211_device {
- struct net_device *dev;
- struct ieee80211_security sec;
-
- /* hw security related */
- u8 hwsec_active;
- bool is_silent_reset;
- bool force_mic_error;
- bool is_roaming;
- bool ieee_up;
- bool bSupportRemoteWakeUp;
- RT_PS_MODE dot11PowerSaveMode;
- bool actscanning;
- bool be_scan_inprogress;
- bool beinretry;
- RT_RF_POWER_STATE eRFPowerState;
- u32 RfOffReason;
- bool is_set_key;
-
- /* 11n HT below */
- PRT_HIGH_THROUGHPUT pHTInfo;
- spinlock_t bw_spinlock;
-
- spinlock_t reorder_spinlock;
- /*
- * for HT operation rate set, we use this one for HT data rate to
- * separate different descriptors the way fill this is the same as
- * in the IE
- */
- u8 Regdot11HTOperationalRateSet[16]; /* use RATR format */
- u8 dot11HTOperationalRateSet[16]; /* use RATR format */
- u8 RegHTSuppRateSet[16];
- u8 HTCurrentOperaRate;
- u8 HTHighestOperaRate;
- /* for rate operation mode to firmware */
- u8 bTxDisableRateFallBack;
- u8 bTxUseDriverAssingedRate;
- atomic_t atm_chnlop;
- atomic_t atm_swbw;
-
- /* 802.11e and WMM Traffic Stream Info (TX) */
- struct list_head Tx_TS_Admit_List;
- struct list_head Tx_TS_Pending_List;
- struct list_head Tx_TS_Unused_List;
- TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM];
- /* 802.11e and WMM Traffic Stream Info (RX) */
- struct list_head Rx_TS_Admit_List;
- struct list_head Rx_TS_Pending_List;
- struct list_head Rx_TS_Unused_List;
- RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM];
-
- RX_REORDER_ENTRY RxReorderEntry[128];
- struct list_head RxReorder_Unused_List;
-
- /* Qos related */
- /* Force per-packet priority 1~7. (default: 0, not to force it.) */
- u8 ForcedPriority;
-
- /* Bookkeeping structures */
- struct net_device_stats stats;
- struct ieee80211_stats ieee_stats;
- struct ieee80211_softmac_stats softmac_stats;
-
- /* 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;
-
- spinlock_t lock;
- spinlock_t wpax_suitlist_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 auth_mode;
- 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 */
- bool bHalfWirelessN24GMode;
- int wpa_enabled;
- int drop_unencrypted;
- int tkip_countermeasures;
- int privacy_invoked;
- size_t wpa_ie_len;
- u8 *wpa_ie;
- u8 ap_mac_addr[6];
- u16 pairwise_key_type;
- u16 group_key_type;
- struct list_head crypt_deinit_list;
- struct ieee80211_crypt_data *crypt[WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
- struct timer_list crypt_deinit_timer;
- int crypt_quiesced;
-
- int bcrx_sta_key; /* use individual keys to override default keys even
- * with RX of broad/multicast frames */
-
- RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE];
- /* Fragmentation structures */
- // each streaming contain a entry
- struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
- unsigned int frag_next_idx[17];
- u16 fts; /* Fragmentation Threshold */
-#define DEFAULT_RTS_THRESHOLD 2346U
-#define MIN_RTS_THRESHOLD 1
-#define MAX_RTS_THRESHOLD 2346U
- u16 rts; /* RTS threshold */
-
- /* Association info */
- u8 bssid[ETH_ALEN];
-
- /* This stores infos for the current network.
- * Either the network we are associated in INFRASTRUCTURE
- * or the network that we are creating in MASTER mode.
- * ad-hoc is a mixture ;-).
- * Note that in infrastructure mode, even when not associated,
- * fields bssid and essid may be valid (if wpa_set and essid_set
- * are true) as thy carry the value set by the user via iwconfig
- */
- struct ieee80211_network current_network;
-
- enum ieee80211_state state;
-
- int short_slot;
- int reg_mode;
- int mode; /* A, B, G */
- int modulation; /* CCK, OFDM */
- int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- int abg_true; /* ABG flag */
-
- /* used for forcing the ibss workqueue to terminate
- * without wait for the syncro scan to terminate
- */
- short sync_scan_hurryup;
- u16 scan_watch_dog;
- int perfect_rssi;
- int worst_rssi;
-
- u16 prev_seq_ctl; /* used to drop duplicate frames */
-
- /*
- * map of allowed channels. 0 is dummy, FIXME: remeber to default to
- * a basic channel plan depending of the PHY type
- */
- void *pDot11dInfo;
- bool bGlobalDomain;
-
- u8 IbssStartChnl;
- u8 ibss_maxjoin_chal;
-
- int rate; /* current rate */
- int basic_rate;
- //FIXME: pleace callback, see if redundant with softmac_features
- short active_scan;
-
- /* this contains flags for selectively enable softmac support */
- u16 softmac_features;
-
- /* if the sequence control field is not filled by HW */
- u16 seq_ctrl[5];
-
- /* association procedure transaction sequence number */
- u16 associate_seq;
-
- /* AID for RTXed association responses */
- u16 assoc_id;
-
- /* power save mode related*/
- u8 ack_tx_to_ieee;
- short ps;
- short sta_sleep;
- int ps_timeout;
- int ps_period;
- struct tasklet_struct ps_task;
- u32 ps_th;
- u32 ps_tl;
-
- short raw_tx;
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- short queue_stop;
- short scanning;
- short proto_started;
-
- struct semaphore wx_sem;
- struct semaphore scan_sem;
-
- spinlock_t mgmt_tx_lock;
- spinlock_t beacon_lock;
-
- short beacon_txing;
-
- short wap_set;
- short ssid_set;
-
- u8 wpax_type_set; //{added by David, 2006.9.28}
- u32 wpax_type_notify; //{added by David, 2006.9.26}
-
- /* QoS related flag */
- char init_wmmparam_flag;
- /* set on initialization */
- u8 qos_support;
-
- /* for discarding duplicated packets in IBSS */
- struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
- /* for discarding duplicated packets in BSS */
- u16 last_rxseq_num[17]; /* rx seq previous per-tid */
- u16 last_rxfrag_num[17];/* tx frag previous per-tid */
- unsigned long last_packet_time[17];
-
- /* for PS mode */
- unsigned long last_rx_ps_time;
-
- /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
- struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
- int mgmt_queue_head;
- int mgmt_queue_tail;
-
-/* rtl819x start */
- u8 AsocRetryCount;
- unsigned int hw_header;
- struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
- struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE];
- struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE];
- u32 sta_edca_param[4];
- bool aggregation;
- /* Enable/Disable Rx immediate BA capability. */
- bool enable_rx_imm_BA;
- bool bibsscoordinator;
-
- /* Dynamic Tx power for near/far range enable/disable. */
- bool bdynamic_txpower_enable;
-
- bool bCTSToSelfEnable;
- u8 CTSToSelfTH;
-
- u32 fsync_time_interval;
- u32 fsync_rate_bitmap;
- u8 fsync_rssi_threshold;
- bool bfsync_enable;
-
- u8 fsync_multiple_timeinterval; /* value * FsyncTimeInterval */
- u32 fsync_firstdiff_ratethreshold; /* low threshold */
- u32 fsync_seconddiff_ratethreshold; /* decrease threshold */
- Fsync_State fsync_state;
- bool bis_any_nonbepkts;
- /* 20Mhz 40Mhz AutoSwitch Threshold */
- struct bandwidth_autoswitch bandwidth_auto_switch;
- /* for txpower tracking */
- bool FwRWRF;
-
- /* for AP roaming */
- struct rt_link_detect LinkDetectInfo;
-
- struct rt_power_save_control PowerSaveControl;
-/* rtl819x end */
-
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- struct tx_pending_t tx_pending;
-
- /* used if IEEE_SOFTMAC_ASSOCIATE is set */
- struct timer_list associate_timer;
-
- /* used if IEEE_SOFTMAC_BEACONS is set */
- struct timer_list beacon_timer;
- struct work_struct associate_complete_wq;
- struct work_struct associate_procedure_wq;
- struct delayed_work softmac_scan_wq;
- struct delayed_work associate_retry_wq;
- struct delayed_work start_ibss_wq;
- struct delayed_work hw_wakeup_wq;
- struct delayed_work hw_sleep_wq;
- struct delayed_work link_change_wq;
- struct work_struct wx_sync_scan_wq;
- struct workqueue_struct *wq;
-
- /* Callback functions */
- void (*set_security)(struct net_device *dev,
- struct ieee80211_security *sec);
-
- /* Used to TX data frame by using txb structs.
- * this is not used if in the softmac_features
- * is set the flag IEEE_SOFTMAC_TX_QUEUE
- */
- int (*hard_start_xmit)(struct ieee80211_txb *txb,
- struct net_device *dev);
-
- 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);
-
- /* Softmac-generated frames (mamagement) are TXed via this
- * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- * not set. As some cards may have different HW queues that
- * one might want to use for data and management frames
- * the option to have two callbacks might be useful.
- * This fucntion can't sleep.
- */
- int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- * then also management frames are sent via this callback.
- * This function can't sleep.
- */
- void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev,int rate);
-
- /* stops the HW queue for DATA frames. Useful to avoid
- * waste time to TX data frame when we are reassociating
- * This function can sleep.
- */
- void (*data_hard_stop)(struct net_device *dev);
-
- /* OK this is complementar to data_poll_hard_stop */
- void (*data_hard_resume)(struct net_device *dev);
-
- /* ask to the driver to retune the radio .
- * This function can sleep. the driver should ensure
- * the radio has been swithced before return.
- */
- void (*set_chan)(struct net_device *dev,short ch);
-
- /* These are not used if the ieee stack takes care of
- * scanning (IEEE_SOFTMAC_SCAN feature set).
- * In this case only the set_chan is used.
- *
- * The syncro version is similar to the start_scan but
- * does not return until all channels has been scanned.
- * this is called in user context and should sleep,
- * it is called in a work_queue when swithcing to ad-hoc mode
- * or in behalf of iwlist scan when the card is associated
- * and root user ask for a scan.
- * the fucntion stop_scan should stop both the syncro and
- * background scanning and can sleep.
- * The fucntion start_scan should initiate the background
- * scanning and can't sleep.
- */
- void (*scan_syncro)(struct net_device *dev);
- void (*start_scan)(struct net_device *dev);
- void (*stop_scan)(struct net_device *dev);
-
- /* indicate the driver that the link state is changed
- * for example it may indicate the card is associated now.
- * Driver might be interested in this to apply RX filter
- * rules or simply light the LINK led
- */
- void (*link_change)(struct net_device *dev);
-
- /* these two function indicates to the HW when to start
- * and stop to send beacons. This is used when the
- * IEEE_SOFTMAC_BEACONS is not set. For now the
- * stop_send_bacons is NOT guaranteed to be called only
- * after start_send_beacons.
- */
- void (*start_send_beacons) (struct net_device *dev);
- void (*stop_send_beacons) (struct net_device *dev);
-
- /* power save mode related */
- void (*sta_wake_up) (struct net_device *dev);
- void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
- short (*ps_is_queue_empty) (struct net_device *dev);
-
- int (*handle_beacon)(struct net_device *dev,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network);
- int (*handle_assoc_response)(struct net_device *dev,
- struct ieee80211_assoc_response_frame *resp,
- struct ieee80211_network *network);
-
- /* check whether Tx hw resouce available */
- short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
- /* HT related */
- void (*SetBWModeHandler)(struct net_device *dev,
- HT_CHANNEL_WIDTH Bandwidth,
- HT_EXTCHNL_OFFSET Offset);
- bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
- void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
- bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
- bool (*is_ap_in_wep_tkip)(struct net_device* dev);
- void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
- bool (*SetFwCmdHandler)(struct net_device *dev, FW_CMD_IO_TYPE FwCmdIO);
- void (*LedControlHandler)(struct net_device *dev,
- LED_CTL_MODE LedAction);
- /* 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_N_24G (1<<4)
-#define IEEE_N_5G (1<<5)
-#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate respones to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons. The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
- return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-extern 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;
-}
-
-extern inline int ieee80211_get_hdrlen(u16 fc)
-{
- int hdrlen = IEEE80211_3ADDR_LEN;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */
- if(IEEE80211_QOS_HAS_SEQ(fc))
- hdrlen += 2; /* QOS ctrl*/
- 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 rtl_ieee80211_hdr *hdr)
-{
- switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
- 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 (void *)hdr+sizeof(struct ieee80211_hdr_3addr);
- 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_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(
- struct ieee80211_device *ieee,
- struct sk_buff *frag,
- int hdr_len);
-
-extern int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb,
- struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats);
-
-/* 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_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data* wrqu, char *extra);
-extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra);
-extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(struct ieee80211_network net);
-extern short ieee80211_is_shortslot(struct ieee80211_network net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
-
-void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
-
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-
-extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
- ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
- return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (ieee80211_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else {
- *d++ = *s++;
- }
- }
- *d = '\0';
- return escaped;
-}
-
-/* For the function is more related to hardware setting, it's better to use the
- * ieee handler to refer to it.
- */
-extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
-extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
-extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
- struct ieee80211_info_element *info_element,
- u16 length,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats);
-
-extern void ieee80211_indicate_packets(struct ieee80211_device *ieee,
- struct ieee80211_rxb **prxbIndicateArray,
- u8 index);
-#define RT_ASOC_RETRY_LIMIT 5
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index 24e7d595e3ce..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.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. See README and COPYING for
- * more details.
- *
- */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/string.h>
-#include <asm/errno.h>
-
-#include "ieee80211.h"
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("HostAP crypto");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_crypto_alg {
- struct list_head list;
- struct ieee80211_crypto_ops *ops;
-};
-
-
-struct ieee80211_crypto {
- struct list_head algs;
- spinlock_t lock;
-};
-
-static struct ieee80211_crypto *hcrypt;
-
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
- int force)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypt_data *entry;
-
- for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
- ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
- entry = list_entry(ptr, struct ieee80211_crypt_data, list);
-
- if (atomic_read(&entry->refcnt) != 0 && !force)
- continue;
-
- list_del(ptr);
-
- if (entry->ops)
- entry->ops->deinit(entry->priv);
- kfree(entry);
- }
-}
-
-void ieee80211_crypt_deinit_handler(unsigned long data)
-{
- struct ieee80211_device *ieee = (struct ieee80211_device *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- ieee80211_crypt_deinit_entries(ieee, 0);
- if (!list_empty(&ieee->crypt_deinit_list)) {
- printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
- "deletion list\n", ieee->dev->name);
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt)
-{
- struct ieee80211_crypt_data *tmp;
- unsigned long flags;
-
- if (*crypt == NULL)
- return;
-
- tmp = *crypt;
- *crypt = NULL;
-
- /* must not run ops->deinit() while there may be pending encrypt or
- * decrypt operations. Use a list of delayed deinits to avoid needing
- * locking. */
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct ieee80211_crypto_alg *alg;
-
- if (hcrypt == NULL)
- return -1;
-
- alg = kzalloc(sizeof(*alg), GFP_KERNEL);
- if (alg == NULL)
- return -ENOMEM;
-
- alg->ops = ops;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- list_add(&alg->list, &hcrypt->algs);
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
- ops->name);
-
- return 0;
-}
-
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *del_alg = NULL;
-
- if (hcrypt == NULL)
- return -1;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (alg->ops == ops) {
- list_del(&alg->list);
- del_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (del_alg) {
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s'\n", ops->name);
- kfree(del_alg);
- }
-
- return del_alg ? 0 : -1;
-}
-
-
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *found_alg = NULL;
-
- if (hcrypt == NULL)
- return NULL;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (strcmp(alg->ops->name, name) == 0) {
- found_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (found_alg)
- return found_alg->ops;
- else
- return NULL;
-}
-
-
-static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
-static void ieee80211_crypt_null_deinit(void *priv) {}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .encrypt_mpdu = NULL,
- .decrypt_mpdu = NULL,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = NULL,
- .get_key = NULL,
- .extra_prefix_len = 0,
- .extra_postfix_len = 0,
- .owner = THIS_MODULE,
-};
-
-int ieee80211_crypto_init(void)
-{
- int ret = -ENOMEM;
-
- hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
- if (!hcrypt)
- goto out;
-
- INIT_LIST_HEAD(&hcrypt->algs);
- spin_lock_init(&hcrypt->lock);
-
- ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
- if (ret < 0) {
- kfree(hcrypt);
- hcrypt = NULL;
- }
-out:
- return ret;
-}
-
-void ieee80211_crypto_deinit(void)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypto_alg *alg = NULL;
-
- if (hcrypt == NULL)
- return;
-
- 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/rtl8192su/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
deleted file mode 100644
index 42e52aedd292..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code 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
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, 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.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
- const char *name;
-
- /* init new crypto context (e.g., allocate private data space,
- * select IV, etc.); returns NULL on failure or pointer to allocated
- * private data on success */
- void * (*init)(int keyidx);
-
- /* deinitialize crypto context and free allocated private data */
- void (*deinit)(void *priv);
-
- /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
- * value from decrypt_mpdu is passed as the keyidx value for
- * decrypt_msdu. skb must have enough head and tail room for the
- * encryption; if not, error will be returned; these functions are
- * called for all MPDUs (i.e., fragments).
- */
- int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
- /* These functions are called for full MSDUs, i.e. full frames.
- * These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- void *priv, struct ieee80211_device* ieee);
-
- int (*set_key)(void *key, int len, u8 *seq, void *priv);
- int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
- /* procfs handler for printing out key information and possible
- * statistics */
- char * (*print_stats)(char *p, void *priv);
-
- /* maximum number of bytes added by encryption; encrypt buf is
- * allocated with extra_prefix_len bytes, copy of in_buf, and
- * extra_postfix_len; encrypt need not use all this space, but
- * the result must start at the beginning of the buffer and correct
- * length must be returned */
- int extra_prefix_len, extra_postfix_len;
-
- struct module *owner;
-};
-
-struct ieee80211_crypt_data {
- struct list_head list; /* delayed deletion list */
- struct ieee80211_crypto_ops *ops;
- void *priv;
- atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
deleted file mode 100644
index caee44ba3bc3..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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.
- */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-#include <linux/wireless.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct ieee80211_ccmp_data {
- u8 key[CCMP_TK_LEN];
- int key_set;
-
- u8 tx_pn[CCMP_PN_LEN];
- u8 rx_pn[CCMP_PN_LEN];
-
- u32 dot11RSNAStatsCCMPFormatErrors;
- u32 dot11RSNAStatsCCMPReplays;
- u32 dot11RSNAStatsCCMPDecryptErrors;
-
- int key_idx;
-
- struct crypto_tfm *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
- u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
-};
-
-void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
- const u8 pt[16], u8 ct[16])
-{
- crypto_cipher_encrypt_one((void*)tfm, ct, pt);
-}
-
-static void * ieee80211_ccmp_init(int key_idx)
-{
- struct ieee80211_ccmp_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
- "crypto API aes\n");
- priv->tfm = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_cipher((void*)priv->tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_ccmp_deinit(void *priv)
-{
- struct ieee80211_ccmp_data *_priv = priv;
-
- if (_priv && _priv->tfm)
- crypto_free_cipher((void*)_priv->tfm);
- kfree(priv);
-}
-
-
-static inline void xor_block(u8 *b, u8 *a, size_t len)
-{
- int i;
- for (i = 0; i < len; i++)
- b[i] ^= a[i];
-}
-
-
-
-static void ccmp_init_blocks(struct crypto_tfm *tfm,
- struct ieee80211_hdr_4addr *hdr,
- u8 *pn, size_t dlen, u8 *b0, u8 *auth,
- u8 *s0)
-{
- u8 *pos, qc = 0;
- size_t aad_len;
- u16 fc;
- int a4_included, qc_included;
- u8 aad[2 * AES_BLOCK_LEN];
-
- fc = le16_to_cpu(hdr->frame_ctl);
- a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
- /*
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x08));
- */
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x80));
- aad_len = 22;
- if (a4_included)
- aad_len += 6;
- if (qc_included) {
- pos = (u8 *) &hdr->addr4;
- if (a4_included)
- pos += 6;
- qc = *pos & 0x0f;
- aad_len += 2;
- }
- /* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
- * Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
- b0[1] = qc;
- memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
- memcpy(b0 + 8, pn, CCMP_PN_LEN);
- b0[14] = (dlen >> 8) & 0xff;
- b0[15] = dlen & 0xff;
-
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- pos = (u8 *) hdr;
- aad[0] = 0; /* aad_len >> 8 */
- aad[1] = aad_len & 0xff;
- aad[2] = pos[0] & 0x8f;
- aad[3] = pos[1] & 0xc7;
- memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- pos = (u8 *) &hdr->seq_ctl;
- aad[22] = pos[0] & 0x0f;
- aad[23] = 0; /* all bits masked */
- memset(aad + 24, 0, 8);
- if (a4_included)
- memcpy(aad + 24, hdr->addr4, ETH_ALEN);
- if (qc_included) {
- aad[a4_included ? 30 : 24] = qc;
- /* rest of QC masked */
- }
-
- /* Start with the first block and AAD */
- ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
- xor_block(auth, aad, AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- b0[0] &= 0x07;
- b0[14] = b0[15] = 0;
- ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
-}
-
-
-
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- int data_len, i;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN ||
- skb->len < hdr_len)
- return -1;
-
- data_len = skb->len - hdr_len;
- pos = skb_push(skb, CCMP_HDR_LEN);
- memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- pos += hdr_len;
-
- i = CCMP_PN_LEN - 1;
- while (i >= 0) {
- key->tx_pn[i]++;
- if (key->tx_pn[i] != 0)
- break;
- i--;
- }
-
- *pos++ = key->tx_pn[5];
- *pos++ = key->tx_pn[4];
- *pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = key->tx_pn[3];
- *pos++ = key->tx_pn[2];
- *pos++ = key->tx_pn[1];
- *pos++ = key->tx_pn[0];
-
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- if (!tcb_desc->bHwSec)
- {
- int blocks, last, len;
- u8 *mic;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
-
- mic = skb_put(skb, CCMP_MIC_LEN);
-
- ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Authentication */
- xor_block(b, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
- /* Encryption, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
- xor_block(pos, e, len);
- pos += len;
- }
-
- for (i = 0; i < CCMP_MIC_LEN; i++)
- mic[i] = b[i] ^ s0[i];
- }
- return 0;
-}
-
-
-static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- u8 keyidx, *pos;
- struct ieee80211_hdr_4addr *hdr;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- u8 pn[6];
-
- if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -1;
- }
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- " flag from %pM\n", hdr->addr2);
- }
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -2;
- }
- keyidx >>= 6;
- if (key->key_idx != keyidx) {
- printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
- return -6;
- }
- if (!key->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: received packet from %pM"
- " with keyid=%d that does not have a configured"
- " key\n", hdr->addr2, keyidx);
- }
- return -3;
- }
-
- pn[0] = pos[7];
- pn[1] = pos[6];
- pn[2] = pos[5];
- pn[3] = pos[4];
- pn[4] = pos[1];
- pn[5] = pos[0];
- pos += 8;
-
- if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
- " previous PN %pm received PN %pm\n",
- hdr->addr2, key->rx_pn, pn);
- }
- key->dot11RSNAStatsCCMPReplays++;
- return -4;
- }
- if (!tcb_desc->bHwSec)
- {
- size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
- u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
- u8 *b0 = key->rx_b0;
- u8 *b = key->rx_b;
- u8 *a = key->rx_a;
- int i, blocks, last, len;
-
-
- ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
- xor_block(mic, b, CCMP_MIC_LEN);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Decrypt, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
- xor_block(pos, b, len);
- /* Authentication */
- xor_block(a, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
- pos += len;
- }
-
- if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- "%pM\n", hdr->addr2);
- }
- key->dot11RSNAStatsCCMPDecryptErrors++;
- return -5;
- }
-
- memcpy(key->rx_pn, pn, CCMP_PN_LEN);
- }
- /* Remove hdr and MIC */
- memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- skb_pull(skb, CCMP_HDR_LEN);
- skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
- return keyidx;
-}
-
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
- int keyidx;
- struct crypto_tfm *tfm = data->tfm;
-
- keyidx = data->key_idx;
- memset(data, 0, sizeof(*data));
- data->key_idx = keyidx;
- data->tfm = tfm;
- if (len == CCMP_TK_LEN) {
- memcpy(data->key, key, CCMP_TK_LEN);
- data->key_set = 1;
- if (seq) {
- data->rx_pn[0] = seq[5];
- data->rx_pn[1] = seq[4];
- data->rx_pn[2] = seq[3];
- data->rx_pn[3] = seq[2];
- data->rx_pn[4] = seq[1];
- data->rx_pn[5] = seq[0];
- }
- crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
- } else if (len == 0)
- data->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
-
- if (len < CCMP_TK_LEN)
- return -1;
-
- if (!data->key_set)
- return 0;
- memcpy(key, data->key, CCMP_TK_LEN);
-
- if (seq) {
- seq[0] = data->tx_pn[5];
- seq[1] = data->tx_pn[4];
- seq[2] = data->tx_pn[3];
- seq[3] = data->tx_pn[2];
- seq[4] = data->tx_pn[1];
- seq[5] = data->tx_pn[0];
- }
-
- return CCMP_TK_LEN;
-}
-
-
-static char * ieee80211_ccmp_print_stats(char *p, void *priv)
-{
- struct ieee80211_ccmp_data *ccmp = priv;
- p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- "tx_pn=%pm rx_pn=%pm "
- "format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- ccmp->tx_pn, ccmp->rx_pn,
- ccmp->dot11RSNAStatsCCMPFormatErrors,
- ccmp->dot11RSNAStatsCCMPReplays,
- ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
- return p;
-}
-
-void ieee80211_ccmp_null(void)
-{
- return;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_prefix_len = CCMP_HDR_LEN,
- .extra_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
-};
-
-int __init ieee80211_crypto_ccmp_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-void ieee80211_crypto_ccmp_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
deleted file mode 100644
index 5ab94a9665e5..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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.
- */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: TKIP");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_tkip_data {
-#define TKIP_KEY_LEN 32
- u8 key[TKIP_KEY_LEN];
- int key_set;
-
- u32 tx_iv32;
- u16 tx_iv16;
- u16 tx_ttak[5];
- int tx_phase1_done;
-
- u32 rx_iv32;
- u16 rx_iv16;
- bool initialized;
- u16 rx_ttak[5];
- int rx_phase1_done;
- u32 rx_iv32_new;
- u16 rx_iv16_new;
-
- u32 dot11RSNAStatsTKIPReplays;
- u32 dot11RSNAStatsTKIPICVErrors;
- u32 dot11RSNAStatsTKIPLocalMICFailures;
-
- int key_idx;
-
- struct crypto_blkcipher *rx_tfm_arc4;
- struct crypto_hash *rx_tfm_michael;
- struct crypto_blkcipher *tx_tfm_arc4;
- struct crypto_hash *tx_tfm_michael;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16], tx_hdr[16];
-};
-
-static void * ieee80211_tkip_init(int key_idx)
-{
- struct ieee80211_tkip_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm_michael)
- crypto_free_hash(priv->tx_tfm_michael);
- if (priv->tx_tfm_arc4)
- crypto_free_blkcipher(priv->tx_tfm_arc4);
- if (priv->rx_tfm_michael)
- crypto_free_hash(priv->rx_tfm_michael);
- if (priv->rx_tfm_arc4)
- crypto_free_blkcipher(priv->rx_tfm_arc4);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_tkip_deinit(void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm_michael)
- crypto_free_hash(_priv->tx_tfm_michael);
- if (_priv->tx_tfm_arc4)
- crypto_free_blkcipher(_priv->tx_tfm_arc4);
- if (_priv->rx_tfm_michael)
- crypto_free_hash(_priv->rx_tfm_michael);
- if (_priv->rx_tfm_arc4)
- crypto_free_blkcipher(_priv->rx_tfm_arc4);
- }
- kfree(priv);
-}
-
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (((u16) hi) << 8);
-}
-
-
-static inline u16 Mk16_le(u16 *v)
-{
- return le16_to_cpu(*v);
-}
-
-
-static const u16 Sbox[256] =
-{
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-
-#define PHASE1_LOOP_COUNT 8
-
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- u16 IV16)
-{
- /* Make temporary area overlap WEP seed so that the final copy can be
- * avoided on little endian hosts. */
- u16 *PPK = (u16 *) &WEPSeed[4];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
- {
- int i;
- for (i = 0; i < 6; i++)
- PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- }
-#endif
-}
-
-
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int len;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
- int ret = 0;
- u8 rc4key[16], *icv;
- u32 crc;
- struct scatterlist sg;
-
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
-
- if (!tcb_desc->bHwSec)
- {
- if (!tkey->tx_phase1_done) {
- tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- tkey->tx_iv32);
- tkey->tx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
- }
- else
- tkey->tx_phase1_done = 1;
-
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 8);
- memmove(pos, pos + 8, hdr_len);
- pos += hdr_len;
-
- if (tcb_desc->bHwSec)
- {
- *pos++ = Hi8(tkey->tx_iv16);
- *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
- *pos++ = Lo8(tkey->tx_iv16);
- }
- else
- {
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
- }
-
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = tkey->tx_iv32 & 0xff;
- *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
- if (!tcb_desc->bHwSec)
- {
- icv = skb_put(skb, 4);
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, len + 4);
- ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
- }
-
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
-
- if (!tcb_desc->bHwSec)
- return ret;
- else
- return 0;
-
-
-}
-
-static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 keyidx, *pos;
- u32 iv32;
- u16 iv16;
- struct ieee80211_hdr_4addr *hdr;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
- u8 rc4key[16];
- u8 icv[4];
- u32 crc;
- struct scatterlist sg;
- int plen;
- if (skb->len < hdr_len + 8 + 4)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from %pM\n", hdr->addr2);
- }
- return -2;
- }
- keyidx >>= 6;
- if (tkey->key_idx != keyidx) {
- printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
- return -6;
- }
- if (!tkey->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from %pM"
- " with keyid=%d that does not have a configured"
- " key\n", hdr->addr2, keyidx);
- }
- return -3;
- }
- iv16 = (pos[0] << 8) | pos[2];
- iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- pos += 8;
-
- if (!tcb_desc->bHwSec)
- {
- if ((iv32 < tkey->rx_iv32 ||
- (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16))&&tkey->initialized) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
- " previous TSC %08x%04x received TSC "
- "%08x%04x\n", hdr->addr2,
- tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
- }
- tkey->dot11RSNAStatsTKIPReplays++;
- return -4;
- }
- tkey->initialized = true;
-
- if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
- tkey->rx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
- plen = skb->len - hdr_len - 12;
- sg_init_one(&sg, pos, plen+4);
- crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from %pM\n",
- hdr->addr2);
- }
- return -7;
- }
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- if (memcmp(icv, pos + plen, 4) != 0) {
- if (iv32 != tkey->rx_iv32) {
- /* Previously cached Phase1 result was already lost, so
- * it needs to be recalculated for the next packet. */
- tkey->rx_phase1_done = 0;
- }
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- "%pM\n", hdr->addr2);
- }
- tkey->dot11RSNAStatsTKIPICVErrors++;
- return -5;
- }
-
- }
-
- /* Update real counters only after Michael MIC verification has
- * completed */
- tkey->rx_iv32_new = iv32;
- tkey->rx_iv16_new = iv16;
-
- /* Remove IV and ICV */
- memmove(skb->data + 8, skb->data, hdr_len);
- skb_pull(skb, 8);
- skb_trim(skb, skb->len - 4);
-
- return keyidx;
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
- u8 * data, size_t data_len, u8 * mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
-
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, 16);
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, 8))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + 16, mic);
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
-{
- struct ieee80211_hdr_4addr *hdr11;
-
- hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
- switch (le16_to_cpu(hdr11->frame_ctl) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- break;
- case 0:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
-
- if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- printk(KERN_DEBUG "Invalid packet for Michael MIC add "
- "(tailroom=%d hdr_len=%d skb->len=%d)\n",
- skb_tailroom(skb), hdr_len, skb->len);
- return -1;
- }
-
- michael_mic_hdr(skb, tkey->tx_hdr);
-
- if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
- tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
- }
- pos = skb_put(skb, 8);
-
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
- return 0;
-}
-
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr_4addr *hdr,
- int keyidx)
-{
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if (hdr->addr1[0] & 0x01)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- ev.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
-}
-
-static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv, struct ieee80211_device* ieee)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 mic[8];
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
-
- if (!tkey->key_set)
- return -1;
-
- michael_mic_hdr(skb, tkey->rx_hdr);
- if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
- tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
- }
-
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr_4addr *hdr;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from %pM keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", hdr->addr2,
- keyidx);
- printk("%d, force_mic_error = %d\n", (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\
- ieee->force_mic_error);
- if (skb->dev) {
- printk("skb->dev != NULL\n");
- ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
- }
- tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- ieee->force_mic_error = false;
- return -1;
- }
-
- /* Update TSC counters for RX now that the packet verification has
- * completed. */
- tkey->rx_iv32 = tkey->rx_iv32_new;
- tkey->rx_iv16 = tkey->rx_iv16_new;
-
- skb_trim(skb, skb->len - 8);
-
- return 0;
-}
-
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int keyidx;
- struct crypto_hash *tfm = tkey->tx_tfm_michael;
- struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
- struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
- struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-
- keyidx = tkey->key_idx;
- memset(tkey, 0, sizeof(*tkey));
- tkey->key_idx = keyidx;
- tkey->tx_tfm_michael = tfm;
- tkey->tx_tfm_arc4 = tfm2;
- tkey->rx_tfm_michael = tfm3;
- tkey->rx_tfm_arc4 = tfm4;
-
- if (len == TKIP_KEY_LEN) {
- memcpy(tkey->key, key, TKIP_KEY_LEN);
- tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- if (seq) {
- tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
- tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- }
- } else if (len == 0)
- tkey->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
-
- if (len < TKIP_KEY_LEN)
- return -1;
-
- if (!tkey->key_set)
- return 0;
- memcpy(key, tkey->key, TKIP_KEY_LEN);
-
- if (seq) {
- /* Return the sequence number of the last transmitted frame. */
- u16 iv16 = tkey->tx_iv16;
- u32 iv32 = tkey->tx_iv32;
- if (iv16 == 0)
- iv32--;
- iv16--;
- seq[0] = tkey->tx_iv16;
- seq[1] = tkey->tx_iv16 >> 8;
- seq[2] = tkey->tx_iv32;
- seq[3] = tkey->tx_iv32 >> 8;
- seq[4] = tkey->tx_iv32 >> 16;
- seq[5] = tkey->tx_iv32 >> 24;
- }
-
- return TKIP_KEY_LEN;
-}
-
-
-static char * ieee80211_tkip_print_stats(char *p, void *priv)
-{
- struct ieee80211_tkip_data *tkip = priv;
- p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "replays=%d icv_errors=%d local_mic_failures=%d\n",
- tkip->key_idx, tkip->key_set,
- (tkip->tx_iv32 >> 24) & 0xff,
- (tkip->tx_iv32 >> 16) & 0xff,
- (tkip->tx_iv32 >> 8) & 0xff,
- tkip->tx_iv32 & 0xff,
- (tkip->tx_iv16 >> 8) & 0xff,
- tkip->tx_iv16 & 0xff,
- (tkip->rx_iv32 >> 24) & 0xff,
- (tkip->rx_iv32 >> 16) & 0xff,
- (tkip->rx_iv32 >> 8) & 0xff,
- tkip->rx_iv32 & 0xff,
- (tkip->rx_iv16 >> 8) & 0xff,
- tkip->rx_iv16 & 0xff,
- tkip->dot11RSNAStatsTKIPReplays,
- tkip->dot11RSNAStatsTKIPICVErrors,
- tkip->dot11RSNAStatsTKIPLocalMICFailures);
- return p;
-}
-
-
-static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
-};
-
-int ieee80211_crypto_tkip_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-void ieee80211_crypto_tkip_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-void ieee80211_tkip_null(void)
-{
- return;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
deleted file mode 100644
index 5219bfd4ea8e..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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.
- */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <asm/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct prism2_wep_data {
- u32 iv;
-#define WEP_KEY_LEN 13
- u8 key[WEP_KEY_LEN + 1];
- u8 key_len;
- u8 key_idx;
- struct crypto_blkcipher *tx_tfm;
- struct crypto_blkcipher *rx_tfm;
-};
-
-
-static void * prism2_wep_init(int keyidx)
-{
- struct prism2_wep_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = keyidx;
-
- priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm = NULL;
- goto fail;
- }
- priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm)) {
- printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm = NULL;
- goto fail;
- }
-
- /* start WEP IV from a random value */
- get_random_bytes(&priv->iv, 4);
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm)
- crypto_free_blkcipher(priv->tx_tfm);
- if (priv->rx_tfm)
- crypto_free_blkcipher(priv->rx_tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void prism2_wep_deinit(void *priv)
-{
- struct prism2_wep_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm)
- crypto_free_blkcipher(_priv->tx_tfm);
- if (_priv->rx_tfm)
- crypto_free_blkcipher(_priv->rx_tfm);
- }
- kfree(priv);
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- u32 klen, len;
- u8 key[WEP_KEY_LEN + 3];
- u8 *pos;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
- u32 crc;
- u8 *icv;
- struct scatterlist sg;
- if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 4);
- memmove(pos, pos + 4, hdr_len);
- pos += hdr_len;
-
- klen = 3 + wep->key_len;
-
- wep->iv++;
-
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- * can be used to speedup attacks, so avoid using them. */
- if ((wep->iv & 0xff00) == 0xff00) {
- u8 B = (wep->iv >> 16) & 0xff;
- if (B >= 3 && B < klen)
- wep->iv += 0x0100;
- }
-
- /* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- *pos++ = key[2] = wep->iv & 0xff;
- *pos++ = wep->key_idx << 6;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- if (!tcb_desc->bHwSec)
- {
-
- /* Append little-endian CRC32 and encrypt it to produce ICV */
- crc = ~crc32_le(~0, pos, len);
- icv = skb_put(skb, 4);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- sg_init_one(&sg, pos, len+4);
-
- return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
- }
-
- return 0;
-}
-
-
-/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- u32 klen, plen;
- u8 key[WEP_KEY_LEN + 3];
- u8 keyidx, *pos;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
- u32 crc;
- u8 icv[4];
- struct scatterlist sg;
- if (skb->len < hdr_len + 8)
- return -1;
-
- pos = skb->data + hdr_len;
- key[0] = *pos++;
- key[1] = *pos++;
- key[2] = *pos++;
- keyidx = *pos++ >> 6;
- if (keyidx != wep->key_idx)
- return -1;
-
- klen = 3 + wep->key_len;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Apply RC4 to data and compute CRC32 over decrypted data */
- plen = skb->len - hdr_len - 8;
-
- if (!tcb_desc->bHwSec)
- {
- crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- sg_init_one(&sg, pos, plen + 4);
-
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
- return -7;
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- /* ICV mismatch - drop frame */
- return -2;
- }
- }
- /* Remove IV and ICV */
- memmove(skb->data + 4, skb->data, hdr_len);
- skb_pull(skb, 4);
- skb_trim(skb, skb->len - 4);
-
- return 0;
-}
-
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < 0 || len > WEP_KEY_LEN)
- return -1;
-
- memcpy(wep->key, key, len);
- wep->key_len = len;
-
- return 0;
-}
-
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < wep->key_len)
- return -1;
-
- memcpy(key, wep->key, wep->key_len);
-
- return wep->key_len;
-}
-
-
-static char * prism2_wep_print_stats(char *p, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- p += sprintf(p, "key[%d] alg=WEP len=%d\n",
- wep->key_idx, wep->key_len);
- return p;
-}
-
-
-static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
-};
-
-int ieee80211_crypto_wep_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_crypto_wep_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_wep_null(void)
-{
- return;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
deleted file mode 100644
index 4945b3dbf72b..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*******************************************************************************
-
- Copyright(c) 2004 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <jkmaline@cc.hut.fi>
- Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
-
- 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/version.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <net/arp.h>
-
-#include "ieee80211.h"
-
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
-
-#define DRV_NAME "ieee80211"
-
-static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
-{
- if (ieee->networks)
- return 0;
-
- ieee->networks = kcalloc(
- MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
- GFP_KERNEL);
- if (!ieee->networks) {
- printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- ieee->dev->name);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
-{
- if (!ieee->networks)
- return;
- kfree(ieee->networks);
- ieee->networks = NULL;
-}
-
-static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
-{
- int i;
-
- INIT_LIST_HEAD(&ieee->network_free_list);
- INIT_LIST_HEAD(&ieee->network_list);
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
-}
-
-
-struct net_device *alloc_ieee80211(int sizeof_priv)
-{
- struct ieee80211_device *ieee;
- struct net_device *dev;
- int i,err;
-
- IEEE80211_DEBUG_INFO("Initializing...\n");
-
- dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
- if (!dev) {
- IEEE80211_ERROR("Unable to network device.\n");
- goto failed;
- }
-
- ieee = netdev_priv(dev);
- memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
- ieee->dev = dev;
-
- err = ieee80211_networks_allocate(ieee);
- if (err) {
- IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
- err);
- goto failed;
- }
- ieee80211_networks_initialize(ieee);
-
-
- /* Default fragmentation threshold is maximum payload size */
- ieee->fts = DEFAULT_FTS;
- ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- ieee->open_wep = 1;
-
- /* Default to enabling full open WEP with host based encrypt/decrypt */
- ieee->host_encrypt = 1;
- ieee->host_decrypt = 1;
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
- INIT_LIST_HEAD(&ieee->crypt_deinit_list);
- init_timer(&ieee->crypt_deinit_timer);
- ieee->crypt_deinit_timer.data = (unsigned long)ieee;
- ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
-
- spin_lock_init(&ieee->lock);
- spin_lock_init(&ieee->wpax_suitlist_lock);
- spin_lock_init(&ieee->bw_spinlock);
- spin_lock_init(&ieee->reorder_spinlock);
- atomic_set(&(ieee->atm_chnlop), 0);
- atomic_set(&(ieee->atm_swbw), 0);
-
- ieee->wpax_type_set = 0;
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
- ieee->raw_tx = 0;
- ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
-
- ieee80211_softmac_init(ieee);
-
- ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
- if (ieee->pHTInfo == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
- return NULL;
- }
- HTUpdateDefaultSetting(ieee);
- HTInitializeHTInfo(ieee); //may move to other place.
- TSInitialize(ieee);
-
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
-//These function were added to load crypte module autoly
- ieee80211_tkip_null();
- ieee80211_wep_null();
- ieee80211_ccmp_null();
-
- return dev;
-
- failed:
- if (dev)
- free_netdev(dev);
-
- return NULL;
-}
-
-
-void free_ieee80211(struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- int i;
-#if 1
- if (ieee->pHTInfo != NULL)
- {
- kfree(ieee->pHTInfo);
- ieee->pHTInfo = NULL;
- }
-#endif
- RemoveAllTS(ieee);
- ieee80211_softmac_free(ieee);
- del_timer_sync(&ieee->crypt_deinit_timer);
- ieee80211_crypt_deinit_entries(ieee, 1);
-
- for (i = 0; i < WEP_KEYS; i++) {
- struct ieee80211_crypt_data *crypt = ieee->crypt[i];
- if (crypt) {
- if (crypt->ops)
- crypt->ops->deinit(crypt->priv);
- kfree(crypt);
- ieee->crypt[i] = NULL;
- }
- }
-
- ieee80211_networks_free(ieee);
- free_netdev(dev);
-}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-
-u32 ieee80211_debug_level = 0;
-static int debug = \
- IEEE80211_DL_ERR //awayls open this flags to show error out
- ;
-struct proc_dir_entry *ieee80211_proc = NULL;
-
-static int show_debug_level(char *page, char **start, off_t offset,
- int count, int *eof, void *data)
-{
- return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
-}
-
-static int store_debug_level(struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- char buf[] = "0x00000000";
- unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
- char *p = (char *)buf;
- unsigned long val;
-
- if (copy_from_user(buf, buffer, len))
- return count;
- buf[len] = 0;
- if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
- p++;
- if (p[0] == 'x' || p[0] == 'X')
- p++;
- val = simple_strtoul(p, &p, 16);
- } else
- val = simple_strtoul(p, &p, 10);
- if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
- else
- ieee80211_debug_level = val;
-
- return strnlen(buf, count);
-}
-
-int ieee80211_debug_init(void)
-{
- struct proc_dir_entry *e;
-
- ieee80211_debug_level = debug;
-
- ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
- if (ieee80211_proc == NULL) {
- IEEE80211_ERROR("Unable to create " DRV_NAME
- " proc directory\n");
- return -EIO;
- }
- e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
- ieee80211_proc);
- if (!e) {
- remove_proc_entry(DRV_NAME, init_net.proc_net);
- ieee80211_proc = NULL;
- return -EIO;
- }
- e->read_proc = show_debug_level;
- e->write_proc = store_debug_level;
- e->data = NULL;
-
- return 0;
-}
-
-void ieee80211_debug_exit(void)
-{
- if (ieee80211_proc) {
- remove_proc_entry("debug_level", ieee80211_proc);
- remove_proc_entry(DRV_NAME, init_net.proc_net);
- ieee80211_proc = NULL;
- }
-}
-
-#include <linux/moduleparam.h>
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "debug output mask");
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h b/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
deleted file mode 100644
index 7e7fbb269800..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
+++ /dev/null
@@ -1,449 +0,0 @@
-#ifndef __IEEE80211_R8192S_H
-#define __IEEE80211_R8192S_H
-
-/* added for rtl819x tx procedure */
-#define MAX_QUEUE_SIZE 0x10
-
-/* 8190 queue mapping */
-enum {
- BK_QUEUE = 0,
- BE_QUEUE = 1,
- VI_QUEUE = 2,
- VO_QUEUE = 3,
- HCCA_QUEUE = 4,
- TXCMD_QUEUE = 5,
- MGNT_QUEUE = 6,
- HIGH_QUEUE = 7,
- BEACON_QUEUE = 8,
-
- LOW_QUEUE = BE_QUEUE,
- NORMAL_QUEUE = MGNT_QUEUE
-};
-
-#define SWRF_TIMEOUT 50
-
-/* LEAP related */
-/* Flag byte: byte 8, numbered from 0. */
-#define IE_CISCO_FLAG_POSITION 0x08
-#define SUPPORT_CKIP_MIC 0x08 /* bit3 */
-#define SUPPORT_CKIP_PK 0x10 /* bit4 */
-
-/* defined for skb cb field, at most 28 byte */
-typedef struct cb_desc {
- /* Tx Desc Related flags (8-9) */
- u8 bLastIniPkt:1;
- u8 bCmdOrInit:1;
- u8 bFirstSeg:1;
- u8 bLastSeg:1;
- u8 bEncrypt:1;
- u8 bTxDisableRateFallBack:1;
- u8 bTxUseDriverAssingedRate:1;
- u8 bHwSec:1; /* indicate whether use Hw security */
-
- u8 reserved1;
-
- /* Tx Firmware Relaged flags (10-11) */
- u8 bCTSEnable:1;
- u8 bRTSEnable:1;
- u8 bUseShortGI:1;
- u8 bUseShortPreamble:1;
- u8 bTxEnableFwCalcDur:1;
- u8 bAMPDUEnable:1;
- u8 bRTSSTBC:1;
- u8 RTSSC:1;
-
- u8 bRTSBW:1;
- u8 bPacketBW:1;
- u8 bRTSUseShortPreamble:1;
- u8 bRTSUseShortGI:1;
- u8 bMulticast:1;
- u8 bBroadcast:1;
- u8 drv_agg_enable:1;
- u8 reserved2:1;
-
- /* Tx Desc related element(12-19) */
- u8 rata_index;
- u8 queue_index;
- u16 txbuf_size;
- u8 RATRIndex;
- u8 reserved6;
- u8 reserved7;
- u8 reserved8;
-
- /* Tx firmware related element(20-27) */
- u8 data_rate;
- u8 rts_rate;
- u8 ampdu_factor;
- u8 ampdu_density;
- u8 DrvAggrNum;
- u16 pkt_size;
- u8 reserved12;
-} cb_desc, *pcb_desc;
-
-enum {
- MGN_1M = 0x02,
- MGN_2M = 0x04,
- MGN_5_5M = 0x0b,
- MGN_11M = 0x16,
-
- MGN_6M = 0x0c,
- MGN_9M = 0x12,
- MGN_12M = 0x18,
- MGN_18M = 0x24,
- MGN_24M = 0x30,
- MGN_36M = 0x48,
- MGN_48M = 0x60,
- MGN_54M = 0x6c,
-
- MGN_MCS0 = 0x80,
- MGN_MCS1 = 0x81,
- MGN_MCS2 = 0x82,
- MGN_MCS3 = 0x83,
- MGN_MCS4 = 0x84,
- MGN_MCS5 = 0x85,
- MGN_MCS6 = 0x86,
- MGN_MCS7 = 0x87,
- MGN_MCS8 = 0x88,
- MGN_MCS9 = 0x89,
- MGN_MCS10 = 0x8a,
- MGN_MCS11 = 0x8b,
- MGN_MCS12 = 0x8c,
- MGN_MCS13 = 0x8d,
- MGN_MCS14 = 0x8e,
- MGN_MCS15 = 0x8f,
-
- MGN_MCS0_SG = 0x90,
- MGN_MCS1_SG = 0x91,
- MGN_MCS2_SG = 0x92,
- MGN_MCS3_SG = 0x93,
- MGN_MCS4_SG = 0x94,
- MGN_MCS5_SG = 0x95,
- MGN_MCS6_SG = 0x96,
- MGN_MCS7_SG = 0x97,
- MGN_MCS8_SG = 0x98,
- MGN_MCS9_SG = 0x99,
- MGN_MCS10_SG = 0x9a,
- MGN_MCS11_SG = 0x9b,
- MGN_MCS12_SG = 0x9c,
- MGN_MCS13_SG = 0x9d,
- MGN_MCS14_SG = 0x9e,
- MGN_MCS15_SG = 0x9f,
-};
-
-#define FC_QOS_BIT BIT7
-
-#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false)
-#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0] & FC_QOS_BIT)))
-#define IsQoSDataFrame(pframe) \
- ((*(u16 *)pframe & (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) \
- == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
-
-#define Frame_Order(pframe) (*(u16 *)pframe & IEEE80211_FCTL_ORDER)
-
-#define SN_LESS(a, b) (((a - b) & 0x800) != 0)
-#define SN_EQUAL(a, b) (a == b)
-
-#define MAX_DEV_ADDR_SIZE 8
-
-enum {
- /* ACT_CATEGORY */
- ACT_CAT_QOS = 1,
- ACT_CAT_DLS = 2,
- ACT_CAT_BA = 3,
- ACT_CAT_HT = 7,
- ACT_CAT_WMM = 17,
-
- /* TS_ACTION */
- ACT_ADDTSREQ = 0,
- ACT_ADDTSRSP = 1,
- ACT_DELTS = 2,
- ACT_SCHEDULE = 3,
-
- /* BA_ACTION */
- ACT_ADDBAREQ = 0,
- ACT_ADDBARSP = 1,
- ACT_DELBA = 2,
-};
-
-/* InitialGainOpType */
-enum {
- IG_Backup = 0,
- IG_Restore,
- IG_Max
-};
-
-typedef enum _LED_CTL_MODE{
- LED_CTL_POWER_ON = 1,
- LED_CTL_LINK = 2,
- LED_CTL_NO_LINK = 3,
- LED_CTL_TX = 4,
- LED_CTL_RX = 5,
- LED_CTL_SITE_SURVEY = 6,
- LED_CTL_POWER_OFF = 7,
- LED_CTL_START_TO_LINK = 8,
- LED_CTL_START_WPS = 9,
- LED_CTL_STOP_WPS = 10,
- LED_CTL_START_WPS_BOTTON = 11,
- LED_CTL_STOP_WPS_FAIL = 12,
- LED_CTL_STOP_WPS_FAIL_OVERLAP = 13,
-} LED_CTL_MODE;
-
-typedef union _frameqos {
- u16 shortdata;
- u8 chardata[2];
- struct {
- u16 tid:4;
- u16 eosp:1;
- u16 ack_policy:2;
- u16 reserved:1;
- u16 txop:8;
- } field;
-} frameqos;
-
-static inline u8 Frame_QoSTID(u8 *buf)
-{
- struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- return (u8)((frameqos *)(buf +
- (((fc & IEEE80211_FCTL_TODS) &&
- (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
-}
-
-enum {
- ERP_NonERPpresent = 1,
- ERP_UseProtection = 2,
- ERP_BarkerPreambleMode = 4,
-};
-
-struct bandwidth_autoswitch {
- long threshold_20Mhzto40Mhz;
- long threshold_40Mhzto20Mhz;
- bool bforced_tx20Mhz;
- bool bautoswitch_enable;
-};
-
-#define REORDER_WIN_SIZE 128
-#define REORDER_ENTRY_NUM 128
-typedef struct _RX_REORDER_ENTRY {
- struct list_head List;
- u16 SeqNum;
- struct ieee80211_rxb *prxb;
-} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
-
-typedef enum _Fsync_State{
- Default_Fsync,
- HW_Fsync,
- SW_Fsync
-} Fsync_State;
-
-/* Power save mode configured. */
-typedef enum _RT_PS_MODE {
- eActive, /* Active/Continuous access. */
- eMaxPs, /* Max power save mode. */
- eFastPs /* Fast power save mode. */
-} RT_PS_MODE;
-
-typedef enum _IPS_CALLBACK_FUNCION {
- IPS_CALLBACK_NONE = 0,
- IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
- IPS_CALLBACK_JOIN_REQUEST = 2,
-} IPS_CALLBACK_FUNCION;
-
-typedef enum _RT_JOIN_ACTION {
- RT_JOIN_INFRA = 1,
- RT_JOIN_IBSS = 2,
- RT_START_IBSS = 3,
- RT_NO_ACTION = 4,
-} RT_JOIN_ACTION;
-
-struct ibss_parms {
- u16 atimWin;
-};
-
-/* Max num of support rates element: 8, Max num of ext. support rate: 255. */
-#define MAX_NUM_RATES 264
-
-typedef enum _RT_RF_POWER_STATE {
- eRfOn,
- eRfSleep,
- eRfOff
-} RT_RF_POWER_STATE;
-
-struct rt_power_save_control {
- /* Inactive Power Save (IPS): disable RF when disconnected */
- bool bInactivePs;
- bool bIPSModeBackup;
- bool bHaltAdapterClkRQ;
- bool bSwRfProcessing;
- RT_RF_POWER_STATE eInactivePowerState;
- struct work_struct InactivePsWorkItem;
- struct timer_list InactivePsTimer;
-
- /* return point for join action */
- IPS_CALLBACK_FUNCION ReturnPoint;
-
- /* Recored Parameters for rescheduled JoinRequest */
- bool bTmpBssDesc;
- RT_JOIN_ACTION tmpJoinAction;
- struct ieee80211_network tmpBssDesc;
-
- /* Recored Parameters for rescheduled MgntLinkRequest */
- bool bTmpScanOnly;
- bool bTmpActiveScan;
- bool bTmpFilterHiddenAP;
- bool bTmpUpdateParms;
- u8 tmpSsidBuf[33];
- OCTET_STRING tmpSsid2Scan;
- bool bTmpSsid2Scan;
- u8 tmpNetworkType;
- u8 tmpChannelNumber;
- u16 tmpBcnPeriod;
- u8 tmpDtimPeriod;
- u16 tmpmCap;
- OCTET_STRING tmpSuppRateSet;
- u8 tmpSuppRateBuf[MAX_NUM_RATES];
- bool bTmpSuppRate;
- struct ibss_parms tmpIbpm;
- bool bTmpIbpm;
-
- /* Leisre Poswer Save: disable RF if connected but traffic isn't busy */
- bool bLeisurePs;
- u32 PowerProfile;
- u8 LpsIdleCount;
- u8 RegMaxLPSAwakeIntvl;
- u8 LPSAwakeIntvl;
-
- /* RF OFF Level */
- u32 CurPsLevel;
- u32 RegRfPsLevel;
-
- /* Fw Control LPS */
- bool bFwCtrlLPS;
- u8 FWCtrlPSMode;
-
- /* Record if there is a link request in IPS RF off progress. */
- bool LinkReqInIPSRFOffPgs;
- /*
- * To make sure that connect info should be executed, so we set the
- * bit to filter the link info which comes after the connect info.
- */
- bool BufConnectinfoBefore;
-};
-
-enum {
- RF_CHANGE_BY_SW = BIT31,
- RF_CHANGE_BY_HW = BIT30,
- RF_CHANGE_BY_PS = BIT29,
- RF_CHANGE_BY_IPS = BIT28,
-};
-
-/* Firmware related CMD IO. */
-typedef enum _FW_CMD_IO_TYPE{
- FW_CMD_DIG_ENABLE = 0, /* for DIG DM */
- FW_CMD_DIG_DISABLE = 1,
- FW_CMD_DIG_HALT = 2,
- FW_CMD_DIG_RESUME = 3,
- FW_CMD_HIGH_PWR_ENABLE = 4, /* for DIG DM */
- FW_CMD_HIGH_PWR_DISABLE = 5,
- FW_CMD_RA_RESET = 6, /* for DIG DM */
- FW_CMD_RA_ACTIVE= 7,
- FW_CMD_RA_REFRESH_N= 8,
- FW_CMD_RA_REFRESH_BG= 9,
- FW_CMD_RA_INIT= 10, /* for FW supported IQK */
- FW_CMD_IQK_ENABLE = 11, /* Tx power tracking switch */
- FW_CMD_TXPWR_TRACK_ENABLE = 12, /* Tx power tracking switch */
- FW_CMD_TXPWR_TRACK_DISABLE = 13,
- FW_CMD_TXPWR_TRACK_THERMAL = 14,
- FW_CMD_PAUSE_DM_BY_SCAN = 15,
- /* indicate firmware that driver enters LPS, for PS-Poll hardware bug */
- FW_CMD_RESUME_DM_BY_SCAN = 16,
- /* indicate firmware that driver leave LPS */
- FW_CMD_RA_REFRESH_N_COMB = 17,
- FW_CMD_RA_REFRESH_BG_COMB = 18,
- FW_CMD_ANTENNA_SW_ENABLE = 19,
- FW_CMD_ANTENNA_SW_DISABLE = 20,
- FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
- FW_CMD_LPS_ENTER = 22,
- FW_CMD_LPS_LEAVE = 23,
- FW_CMD_DIG_MODE_SS = 24,
- FW_CMD_DIG_MODE_FA = 25,
- FW_CMD_ADD_A2_ENTRY = 26,
- FW_CMD_CTRL_DM_BY_DRIVER = 27,
- FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
-}FW_CMD_IO_TYPE,*PFW_CMD_IO_TYPE;
-
-#define RT_MAX_LD_SLOT_NUM 10
-struct rt_link_detect {
- u32 NumRecvBcnInPeriod;
- u32 NumRecvDataInPeriod;
-
- /* number of Rx beacon / CheckForHang_period to determine link status */
- u32 RxBcnNum[RT_MAX_LD_SLOT_NUM];
- /* number of Rx data / CheckForHang_period to determine link status */
- u32 RxDataNum[RT_MAX_LD_SLOT_NUM];
- /* number of CheckForHang period to determine link status */
- u16 SlotNum;
- u16 SlotIndex;
-
- u32 NumTxOkInPeriod;
- u32 NumRxOkInPeriod;
- bool bBusyTraffic;
-};
-
-/* HT */
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString);
-extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString);
-
-extern void HTSetConnectBwMode(struct ieee80211_device *ieee,
- HT_CHANNEL_WIDTH Bandwidth,
- HT_EXTCHNL_OFFSET Offset);
-extern void HTUpdateDefaultSetting(struct ieee80211_device *ieee);
-extern void HTConstructCapabilityElement(struct ieee80211_device *ieee,
- u8 *posHTCap, u8 *len, u8 isEncrypt);
-extern void HTConstructInfoElement(struct ieee80211_device *ieee,
- u8 *posHTInfo, u8 *len, u8 isEncrypt);
-extern void HTConstructRT2RTAggElement(struct ieee80211_device *ieee,
- u8 *posRT2RTAgg, u8 *len);
-extern void HTOnAssocRsp(struct ieee80211_device *ieee);
-extern void HTInitializeHTInfo(struct ieee80211_device *ieee);
-extern void HTInitializeBssDesc(PBSS_HT pBssHT);
-extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee,
- struct ieee80211_network *pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee,
- struct ieee80211_network *pNetwork);
-extern u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet,
- u8 *pMCSFilter);
-extern u8 MCS_FILTER_ALL[];
-extern u16 MCS_DATA_RATE[2][2][77] ;
-extern u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame);
-extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
-extern bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee);
-extern u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
-extern u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
-extern u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate);
-extern int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee,
- struct sk_buff *skb);
-extern int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee,
- struct sk_buff *skb);
-extern int ieee80211_rx_DELBA(struct ieee80211_device *ieee,
- struct sk_buff *skb);
-extern void TsInitAddBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTS,
- u8 Policy, u8 bOverwritePending);
-extern void TsInitDelBA(struct ieee80211_device *ieee,
- PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
-extern void BaSetupTimeOut(unsigned long data);
-extern void TxBaInactTimeout(unsigned long data);
-extern void RxBaInactTimeout(unsigned long data);
-extern void ResetBaEntry(PBA_RECORD pBA);
-extern bool GetTs(struct ieee80211_device *ieee, PTS_COMMON_INFO *ppTS,
- u8 *Addr, u8 TID, TR_SELECT TxRxSelect, /* Rx:1, Tx:0 */
- bool bAddNewTs);
-extern void TSInitialize(struct ieee80211_device *ieee);
-extern void TsStartAddBaProcess(struct ieee80211_device *ieee,
- PTX_TS_RECORD pTxTS);
-extern void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr);
-extern void RemoveAllTS(struct ieee80211_device *ieee);
-
-#endif /* __IEEE80211_R8192S_H */
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
deleted file mode 100644
index 09a02f7e39ff..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ /dev/null
@@ -1,2580 +0,0 @@
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, 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.
- ******************************************************************************
-
- Few modifications for Realtek's Wi-Fi drivers by
- Andrea Merello <andreamrl@tiscali.it>
-
- A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/ctype.h>
-
-#include "ieee80211.h"
-#include "dot11d.h"
-static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
-
- skb->dev = ieee->dev;
- skb_reset_mac_header(skb);
-
- skb_pull(skb, ieee80211_get_hdrlen(fc));
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_RAW);
- memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *
-ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- unsigned int frag, u8 tid,u8 *src, u8 *dst)
-{
- struct ieee80211_frag_entry *entry;
- int i;
-
- for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
- entry = &ieee->frag_cache[tid][i];
- if (entry->skb != NULL &&
- time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- IEEE80211_DEBUG_FRAG(
- "expiring fragment cache entry "
- "seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
- }
-
- if (entry->skb != NULL && entry->seq == seq &&
- (entry->last_frag + 1 == frag || frag == -1) &&
- memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
- memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
- return entry;
- }
-
- return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- struct sk_buff *skb = NULL;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else {
- tid = 0;
- }
-
- if (frag == 0) {
- /* Reserve enough space to fit maximum frame length */
- skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ +
- ETH_ALEN /* WDS */ +
- (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
- if (skb == NULL)
- return NULL;
-
- entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
- ieee->frag_next_idx[tid]++;
- if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
- ieee->frag_next_idx[tid] = 0;
-
- if (entry->skb != NULL)
- dev_kfree_skb_any(entry->skb);
-
- entry->first_frag_time = jiffies;
- entry->seq = seq;
- entry->last_frag = frag;
- entry->skb = skb;
- memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
- memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
- } else {
- /* received a fragment of a frame for which the head fragment
- * should have already been received */
- entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
- hdr->addr1);
- if (entry != NULL) {
- entry->last_frag = frag;
- skb = entry->skb;
- }
- }
-
- return skb;
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else {
- tid = 0;
- }
-
- entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
- hdr->addr1);
-
- if (entry == NULL) {
- IEEE80211_DEBUG_FRAG(
- "could not invalidate fragment cache "
- "entry (seq=%u)\n", seq);
- return -1;
- }
-
- entry->skb = NULL;
- return 0;
-}
-
-
-
-/* ieee80211_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by ieee80211_rtl_rx */
-static inline int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- /* On the struct stats definition there is written that
- * this is not mandatory.... but seems that the probe
- * response parser uses it
- */
- struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data;
-
- rx_stats->len = skb->len;
- ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats);
- //if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
- if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames
- {
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
-
- dev_kfree_skb_any(skb);
-
- return 0;
-
-}
-
-
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
- struct sk_buff *skb, size_t hdrlen)
-{
- struct net_device *dev = ieee->dev;
- u16 fc, ethertype;
- struct ieee80211_hdr_4addr *hdr;
- u8 *pos;
-
- if (skb->len < 24)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
- /* check that the frame is unicast frame to us */
- if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
- memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
- /* ToDS frame with own addr BSSID and DA */
- } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
- /* FromDS frame with own addr as DA */
- } else
- return 0;
-
- if (skb->len < 24 + 8)
- return 0;
-
- /* check for port access entity Ethernet type */
-// pos = skb->data + 24;
- pos = skb->data + hdrlen;
- ethertype = (pos[6] << 8) | pos[7];
- if (ethertype == ETH_P_PAE)
- return 1;
-
- return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rtl_rx */
-static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
- return 0;
-#if 1
- if (ieee->hwsec_active)
- {
- cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
- tcb_desc->bHwSec = 1;
- }
-#endif
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- if (ieee->tkip_countermeasures &&
- strcmp(crypt->ops->name, "TKIP") == 0) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "received packet from %pM\n",
- ieee->dev->name, hdr->addr2);
- }
- return -1;
- }
-#endif
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- IEEE80211_DEBUG_DROP(
- "decryption failed (SA=%pM"
- ") res=%d\n", hdr->addr2, res);
- if (res == -2)
- IEEE80211_DEBUG_DROP("Decryption failed ICV "
- "mismatch (key %d)\n",
- skb->data[hdrlen + 3] >> 6);
- ieee->ieee_stats.rx_discards_undecryptable++;
- return -1;
- }
-
- return res;
-}
-
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
- int keyidx, struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
- return 0;
- if (ieee->hwsec_active)
- {
- cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
- tcb_desc->bHwSec = 1;
- }
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv,ieee);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=%pM keyidx=%d)\n",
- ieee->dev->name, hdr->addr2, keyidx);
- return -1;
- }
-
- return 0;
-}
-
-
-/* this function is stolen from ipw2200 driver*/
-#define IEEE_PACKET_RETRY_TIME (5*HZ)
-static int is_duplicate_packet(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header)
-{
- u16 fc = le16_to_cpu(header->frame_ctl);
- u16 sc = le16_to_cpu(header->seq_ctl);
- u16 seq = WLAN_GET_SEQ_SEQ(sc);
- u16 frag = WLAN_GET_SEQ_FRAG(sc);
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
-
- //TO2DS and QoS
- if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
- tid = UP2AC(tid);
- tid ++;
- } else { // no QoS
- tid = 0;
- }
-
- switch (ieee->iw_mode) {
- case IW_MODE_ADHOC:
- {
- struct list_head *p;
- struct ieee_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
- //for (pos = (head)->next; pos != (head); pos = pos->next)
- //__list_for_each(p, &ieee->ibss_mac_hash[index]) {
- list_for_each(p, &ieee->ibss_mac_hash[index]) {
- entry = list_entry(p, struct ieee_ibss_seq, list);
- if (!memcmp(entry->mac, mac, ETH_ALEN))
- break;
- }
- // if (memcmp(entry->mac, mac, ETH_ALEN)){
- if (p == &ieee->ibss_mac_hash[index]) {
- entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
- if (!entry) {
- printk(KERN_WARNING "Cannot malloc new mac entry\n");
- return 0;
- }
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num[tid] = seq;
- entry->frag_num[tid] = frag;
- entry->packet_time[tid] = jiffies;
- list_add(&entry->list, &ieee->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num[tid];
- last_frag = &entry->frag_num[tid];
- last_time = &entry->packet_time[tid];
- break;
- }
-
- case IW_MODE_INFRA:
- last_seq = &ieee->last_rxseq_num[tid];
- last_frag = &ieee->last_rxfrag_num[tid];
- last_time = &ieee->last_packet_time[tid];
-
- break;
- default:
- return 0;
- }
-
-// if(tid != 0) {
-// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
-// }
- if ((*last_seq == seq) &&
- time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag){
- //printk(KERN_WARNING "[1] go drop!\n");
- goto drop;
-
- }
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- //printk(KERN_WARNING "[2] go drop!\n");
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
-drop:
-// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
-// printk("DUP\n");
-
- return 1;
-}
-bool
-AddReorderEntry(
- PRX_TS_RECORD pTS,
- PRX_REORDER_ENTRY pReorderEntry
- )
-{
- struct list_head *pList = &pTS->RxPendingPktList;
-#if 1
- while(pList->next != &pTS->RxPendingPktList)
- {
- if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
- {
- pList = pList->next;
- }
- else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
- {
- return false;
- }
- else
- {
- break;
- }
- }
-#endif
- pReorderEntry->List.next = pList->next;
- pReorderEntry->List.next->prev = &pReorderEntry->List;
- pReorderEntry->List.prev = pList;
- pList->next = &pReorderEntry->List;
-
- return true;
-}
-
-void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index)
-{
- u8 i = 0 , j=0;
- u16 ethertype;
-// if(index > 1)
-// IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index);
- for(j = 0; j<index; j++)
- {
-//added by amy for reorder
- struct ieee80211_rxb* prxb = prxbIndicateArray[j];
- for(i = 0; i<prxb->nr_subframes; i++) {
- struct sk_buff *sub_skb = prxb->subframes[i];
-
- /* convert hdr + possible LLC headers into Ethernet header */
- ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
- if (sub_skb->len >= 8 &&
- ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
- skb_pull(sub_skb, SNAP_SIZE);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr and full payload */
- len = htons(sub_skb->len);
- memcpy(skb_push(sub_skb, 2), &len, 2);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
- }
- //stats->rx_packets++;
- //stats->rx_bytes += sub_skb->len;
-
- /* Indicat the packets to upper layer */
- if (sub_skb) {
- //printk("0skb_len(%d)\n", skb->len);
- sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
- memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
- sub_skb->dev = ieee->dev;
- sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
- ieee->last_rx_ps_time = jiffies;
- //printk("1skb_len(%d)\n", skb->len);
- netif_rx(sub_skb);
- }
- }
- kfree(prxb);
- prxb = NULL;
- }
-}
-
-
-void RxReorderIndicatePacket( struct ieee80211_device *ieee,
- struct ieee80211_rxb* prxb,
- PRX_TS_RECORD pTS,
- u16 SeqNum)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- PRX_REORDER_ENTRY pReorderEntry = NULL;
- struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
- u8 WinSize = pHTInfo->RxReorderWinSize;
- u16 WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
- u8 index = 0;
- bool bMatchWinStart = false, bPktInBuf = false;
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
- /* Rx Reorder initialize condition.*/
- if(pTS->RxIndicateSeq == 0xffff) {
- pTS->RxIndicateSeq = SeqNum;
- }
-
- /* Drop out the packet which SeqNum is smaller than WinStart */
- if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
- pTS->RxIndicateSeq, SeqNum);
- pHTInfo->RxReorderDropCounter++;
- {
- int i;
- for(i =0; i < prxb->nr_subframes; i++) {
- dev_kfree_skb(prxb->subframes[i]);
- }
- kfree(prxb);
- prxb = NULL;
- }
- return;
- }
-
- /*
- * Sliding window manipulation. Conditions includes:
- * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
- * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
- */
- if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
- pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
- bMatchWinStart = true;
- } else if(SN_LESS(WinEnd, SeqNum)) {
- if(SeqNum >= (WinSize - 1)) {
- pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
- } else {
- pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
- }
- IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
- }
-
- /*
- * Indication process.
- * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
- * with the SeqNum smaller than latest WinStart and buffer other packets.
- */
- /* For Rx Reorder condition:
- * 1. All packets with SeqNum smaller than WinStart => Indicate
- * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
- */
- if(bMatchWinStart) {
- /* Current packet is going to be indicated.*/
- IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
- pTS->RxIndicateSeq, SeqNum);
- prxbIndicateArray[0] = prxb;
-// printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum);
- index = 1;
- } else {
- /* Current packet is going to be inserted into pending list.*/
- //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__);
- if(!list_empty(&ieee->RxReorder_Unused_List)) {
- pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
- list_del_init(&pReorderEntry->List);
-
- /* Make a reorder entry and insert into a the packet list.*/
- pReorderEntry->SeqNum = SeqNum;
- pReorderEntry->prxb = prxb;
- // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
-
-#if 1
- if(!AddReorderEntry(pTS, pReorderEntry)) {
- IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
- __FUNCTION__, pTS->RxIndicateSeq, SeqNum);
- list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
- {
- int i;
- for(i =0; i < prxb->nr_subframes; i++) {
- dev_kfree_skb(prxb->subframes[i]);
- }
- kfree(prxb);
- prxb = NULL;
- }
- } else {
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,
- "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
- }
-#endif
- }
- else {
- /*
- * Packets are dropped if there is not enough reorder entries.
- * This part shall be modified!! We can just indicate all the
- * packets in buffer and get reorder entries.
- */
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
- {
- int i;
- for(i =0; i < prxb->nr_subframes; i++) {
- dev_kfree_skb(prxb->subframes[i]);
- }
- kfree(prxb);
- prxb = NULL;
- }
- }
- }
-
- /* Check if there is any packet need indicate.*/
- while(!list_empty(&pTS->RxPendingPktList)) {
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__);
-#if 1
- pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
- if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
- SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
- {
- /* This protect buffer from overflow. */
- if(index >= REORDER_WIN_SIZE) {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
- bPktInBuf = true;
- break;
- }
-
- list_del_init(&pReorderEntry->List);
-
- if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
- pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
-
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
- prxbIndicateArray[index] = pReorderEntry->prxb;
- // printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
- index++;
-
- list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
- } else {
- bPktInBuf = true;
- break;
- }
-#endif
- }
-
- /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
- if(index>0) {
- // Cancel previous pending timer.
- if(timer_pending(&pTS->RxPktPendingTimer))
- {
- del_timer_sync(&pTS->RxPktPendingTimer);
- }
- // del_timer_sync(&pTS->RxPktPendingTimer);
- pTS->RxTimeoutIndicateSeq = 0xffff;
-
- // Indicate packets
- if(index>REORDER_WIN_SIZE){
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
- return;
- }
- ieee80211_indicate_packets(ieee, prxbIndicateArray, index);
- bPktInBuf = false;
- }
-
-#if 1
- if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
- // Set new pending timer.
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
- pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
- mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime));
- }
-#endif
-}
-
-u8 parse_subframe(struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats,
- struct ieee80211_rxb *rxb,u8* src,u8* dst)
-{
- struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr* )skb->data;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- u16 LLCOffset= sizeof(struct ieee80211_hdr_3addr);
- u16 ChkLength;
- bool bIsAggregateFrame = false;
- u16 nSubframe_Length;
- u8 nPadding_Length = 0;
- u16 SeqNum=0;
-
- struct sk_buff *sub_skb;
- u8 *data_ptr;
- /* just for debug purpose */
- SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctrl));
-
- if((IEEE80211_QOS_HAS_SEQ(fc))&&\
- (((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
- bIsAggregateFrame = true;
- }
-
- if(IEEE80211_QOS_HAS_SEQ(fc)) {
- LLCOffset += 2;
- }
-
- if(rx_stats->bContainHTC) {
- LLCOffset += sHTCLng;
- }
- //printk("ChkLength = %d\n", LLCOffset);
- // Null packet, don't indicate it to upper layer
- ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
-
- if( skb->len <= ChkLength ) {
- return 0;
- }
-
- skb_pull(skb, LLCOffset);
-
- if(!bIsAggregateFrame) {
- rxb->nr_subframes = 1;
-#ifdef JOHN_NOCPY
- rxb->subframes[0] = skb;
-#else
- rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC);
-#endif
-
- memcpy(rxb->src,src,ETH_ALEN);
- memcpy(rxb->dst,dst,ETH_ALEN);
- //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len);
- return 1;
- } else {
- rxb->nr_subframes = 0;
- memcpy(rxb->src,src,ETH_ALEN);
- memcpy(rxb->dst,dst,ETH_ALEN);
- while(skb->len > ETHERNET_HEADER_SIZE) {
- /* Offset 12 denote 2 mac address */
- nSubframe_Length = *((u16*)(skb->data + 12));
- //==m==>change the length order
- nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
-
- if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
- printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
- __FUNCTION__,rxb->nr_subframes);
- printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
- printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
- printk("The Packet SeqNum is %d\n",SeqNum);
- return 0;
- }
-
- /* move the data point to data content */
- skb_pull(skb, ETHERNET_HEADER_SIZE);
-
-#ifdef JOHN_NOCPY
- sub_skb = skb_clone(skb, GFP_ATOMIC);
- sub_skb->len = nSubframe_Length;
- sub_skb->tail = sub_skb->data + nSubframe_Length;
-#else
- /* Allocate new skb for releasing to upper layer */
- sub_skb = dev_alloc_skb(nSubframe_Length + 12);
- skb_reserve(sub_skb, 12);
- data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
- memcpy(data_ptr,skb->data,nSubframe_Length);
-#endif
- rxb->subframes[rxb->nr_subframes++] = sub_skb;
- if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
- IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
- break;
- }
- skb_pull(skb,nSubframe_Length);
-
- if(skb->len != 0) {
- nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
- if(nPadding_Length == 4) {
- nPadding_Length = 0;
- }
-
- if(skb->len < nPadding_Length) {
- return 0;
- }
-
- skb_pull(skb,nPadding_Length);
- }
- }
-#ifdef JOHN_NOCPY
- dev_kfree_skb(skb);
-#endif
- //{just for debug added by david
- //printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes);
- //}
- return rxb->nr_subframes;
- }
-}
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct net_device *dev = ieee->dev;
- struct ieee80211_hdr_4addr *hdr;
- //struct ieee80211_hdr_3addrqos *hdr;
-
- size_t hdrlen;
- u16 fc, type, stype, sc;
- struct net_device_stats *stats;
- unsigned int frag;
- u8 *payload;
- u16 ethertype;
- //added by amy for reorder
- u8 TID = 0;
- u16 SeqNum = 0;
- PRX_TS_RECORD pTS = NULL;
- //bool bIsAggregateFrame = false;
- //added by amy for reorder
-// u16 qos_ctl = 0;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- struct ieee80211_crypt_data *crypt = NULL;
- int keyidx = 0;
-
- int i;
- struct ieee80211_rxb* rxb = NULL;
- // cheat the the hdr type
- 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;
- }
-
- 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 = ieee80211_get_hdrlen(fc);
-
- if(HTCCheck(ieee, skb->data))
- {
- if(net_ratelimit())
- printk("find HTCControl\n");
- hdrlen += 4;
- rx_stats->bContainHTC = 1;
- }
-
- //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ieee80211_monitor_rx(ieee, skb, rx_stats);
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- return 1;
- }
-
- if (ieee->host_decrypt) {
- int idx = 0;
- if (skb->len >= hdrlen + 3)
- idx = skb->data[hdrlen + 3] >> 6;
- crypt = ieee->crypt[idx];
-
- /* allow NULL decrypt to indicate an station specific override
- * for default encryption */
- if (crypt && (crypt->ops == NULL ||
- crypt->ops->decrypt_mpdu == NULL))
- crypt = NULL;
-
- if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
- /* This seems to be triggered by some (multicast?)
- * frames from other than current BSS, so just drop the
- * frames silently instead of filling system log with
- * these reports. */
- IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=%pM)\n",
- hdr->addr2);
- ieee->ieee_stats.rx_discards_undecryptable++;
- goto rx_dropped;
- }
- }
-
- if (skb->len < IEEE80211_DATA_HDR3_LEN)
- goto rx_dropped;
-
- // if QoS enabled, should check the sequence for each of the AC
- if( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){
- if (is_duplicate_packet(ieee, hdr))
- goto rx_dropped;
-
- }
- else
- {
- PRX_TS_RECORD pRxTS = NULL;
- //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid);
-#if 1
- if(GetTs(
- ieee,
- (PTS_COMMON_INFO*) &pRxTS,
- hdr->addr2,
- (u8)Frame_QoSTID((u8*)(skb->data)),
- RX_DIR,
- true))
- {
-
- // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc));
- if( (fc & (1<<11)) &&
- (frag == pRxTS->RxLastFragNum) &&
- (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) )
- {
- goto rx_dropped;
- }
- else
- {
- pRxTS->RxLastFragNum = frag;
- pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
- }
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__);
- goto rx_dropped;
- }
- }
-#endif
- if (type == IEEE80211_FTYPE_MGMT) {
-
- //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
- if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- goto rx_dropped;
- else
- goto rx_exit;
- }
-
- /* Data frame - extract src/dst addresses */
- switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_FROMDS:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr3, ETH_ALEN);
- memcpy(bssid, hdr->addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_TODS:
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr1, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- if (skb->len < IEEE80211_DATA_HDR4_LEN)
- goto rx_dropped;
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr4, ETH_ALEN);
- memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
- break;
- case 0:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr3, ETH_ALEN);
- break;
- }
-
-
- dev->last_rx = jiffies;
-
- //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
- /* Nullfunc frames may have PS-bit set, so they must be passed to
- * hostap_handle_sta_rx() before being dropped here. */
- if (stype != IEEE80211_STYPE_DATA &&
- stype != IEEE80211_STYPE_DATA_CFACK &&
- stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
- stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
- ) {
- if (stype != IEEE80211_STYPE_NULLFUNC)
- IEEE80211_DEBUG_DROP(
- "RX: dropped data frame "
- "with no data (type=0x%02x, "
- "subtype=0x%02x, len=%d)\n",
- type, stype, skb->len);
- goto rx_dropped;
- }
- if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
- goto rx_dropped;
-
- /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
-
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- {
- printk("decrypt frame error\n");
- goto rx_dropped;
- }
-
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
-
- /* skb: hdr + (possibly fragmented) plaintext payload */
- // PR: FIXME: hostap has additional conditions in the "if" below:
- // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
- int flen;
- struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
- IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
-
- if (!frag_skb) {
- IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
- "Rx cannot get skb from fragment "
- "cache (morefrag=%d seq=%u frag=%u)\n",
- (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc), frag);
- goto rx_dropped;
- }
- flen = skb->len;
- if (frag != 0)
- flen -= hdrlen;
-
- if (frag_skb->tail + flen > frag_skb->end) {
- printk(KERN_WARNING "%s: host decrypted and "
- "reassembled frame did not fit skb\n",
- dev->name);
- ieee80211_frag_cache_invalidate(ieee, hdr);
- goto rx_dropped;
- }
-
- if (frag == 0) {
- /* copy first fragment (including full headers) into
- * beginning of the fragment cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data, flen);
- } else {
- /* append frame payload to the end of the fragment
- * cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
- flen);
- }
- dev_kfree_skb_any(skb);
- skb = NULL;
-
- if (fc & IEEE80211_FCTL_MOREFRAGS) {
- /* more fragments expected - leave the skb in fragment
- * cache for now; it will be delivered to upper layers
- * after all fragments have been received */
- goto rx_exit;
- }
-
- /* 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;
- ieee80211_frag_cache_invalidate(ieee, hdr);
- }
-
- /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- * encrypted/authenticated */
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
- {
- printk("==>decrypt msdu error\n");
- goto rx_dropped;
- }
-
- //added by amy for AP roaming
- ieee->LinkDetectInfo.NumRecvDataInPeriod++;
- ieee->LinkDetectInfo.NumRxOkInPeriod++;
-
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
- if (/*ieee->ieee802_1x &&*/
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-
-#ifdef CONFIG_IEEE80211_DEBUG
- /* pass unencrypted EAPOL frames even if encryption is
- * configured */
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
-#endif
- } else {
- IEEE80211_DEBUG_DROP(
- "encryption configured, but RX "
- "frame not encrypted (SA=%pM)\n",
- hdr->addr2);
- goto rx_dropped;
- }
- }
-
-#ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
-#endif
-
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
- !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- IEEE80211_DEBUG_DROP(
- "dropped unencrypted RX data "
- "frame from %pM"
- " (drop_unencrypted=1)\n",
- hdr->addr2);
- goto rx_dropped;
- }
-/*
- if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
- }
-*/
-//added by amy for reorder
-#if 1
- if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
- && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1))
- {
- TID = Frame_QoSTID(skb->data);
- SeqNum = WLAN_GET_SEQ_SEQ(sc);
- GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
- if(TID !=0 && TID !=3)
- {
- ieee->bis_any_nonbepkts = true;
- }
- }
-#endif
-//added by amy for reorder
- /* skb: hdr + (possible reassembled) full plaintext payload */
- payload = skb->data + hdrlen;
- //ethertype = (payload[6] << 8) | payload[7];
- rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC);
- if(rxb == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__);
- goto rx_dropped;
- }
- /* to parse amsdu packets */
- /* qos data packets & reserved bit is 1 */
- if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
- /* only to free rxb, and not submit the packets to upper layer */
- for(i =0; i < rxb->nr_subframes; i++) {
- dev_kfree_skb(rxb->subframes[i]);
- }
- kfree(rxb);
- rxb = NULL;
- goto rx_dropped;
- }
-
- ieee->last_rx_ps_time = jiffies;
-//added by amy for reorder
- if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
-//added by amy for reorder
- for(i = 0; i<rxb->nr_subframes; i++) {
- struct sk_buff *sub_skb = rxb->subframes[i];
-
- if (sub_skb) {
- /* convert hdr + possible LLC headers into Ethernet header */
- ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
- if (sub_skb->len >= 8 &&
- ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
- skb_pull(sub_skb, SNAP_SIZE);
- memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr and full payload */
- len = htons(sub_skb->len);
- memcpy(skb_push(sub_skb, 2), &len, 2);
- memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
- }
-
- stats->rx_packets++;
- stats->rx_bytes += sub_skb->len;
- if(is_multicast_ether_addr(dst)) {
- stats->multicast++;
- }
-
- /* Indicat the packets to upper layer */
- //printk("0skb_len(%d)\n", skb->len);
- sub_skb->protocol = eth_type_trans(sub_skb, dev);
- memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
- sub_skb->dev = dev;
- sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
- //printk("1skb_len(%d)\n", skb->len);
- netif_rx(sub_skb);
- }
- }
- kfree(rxb);
- rxb = NULL;
-
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__);
- RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
- }
-#ifndef JOHN_NOCPY
- dev_kfree_skb(skb);
-#endif
-
- rx_exit:
- return 1;
-
- rx_dropped:
- if (rxb != NULL)
- {
- kfree(rxb);
- rxb = NULL;
- }
- 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
- * hardware as a DMA target */
- return 0;
-}
-
-#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-
-static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
-
-/*
-* Make ther structure we read from the beacon packet has
-* the right values
-*/
-static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
- *info_element, int sub_type)
-{
-
- if (info_element->qui_subtype != sub_type)
- return -1;
- if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
- return -1;
- if (info_element->qui_type != QOS_OUI_TYPE)
- return -1;
- if (info_element->version != QOS_VERSION_1)
- return -1;
-
- return 0;
-}
-
-
-/*
- * Parse a QoS parameter element
- */
-static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
- *element_param, struct ieee80211_info_element
- *info_element)
-{
- int ret = 0;
- u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
-
- if ((info_element == NULL) || (element_param == NULL))
- return -1;
-
- if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
- memcpy(element_param->info_element.qui, info_element->data,
- info_element->len);
- element_param->info_element.elementID = info_element->id;
- element_param->info_element.length = info_element->len;
- } else
- ret = -1;
- if (ret == 0)
- ret = ieee80211_verify_qos_info(&element_param->info_element,
- QOS_OUI_PARAM_SUB_TYPE);
- return ret;
-}
-
-/*
- * Parse a QoS information element
- */
-static int ieee80211_read_qos_info_element(struct
- ieee80211_qos_information_element
- *element_info, struct ieee80211_info_element
- *info_element)
-{
- int ret = 0;
- u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
-
- if (element_info == NULL)
- return -1;
- if (info_element == NULL)
- return -1;
-
- if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
- memcpy(element_info->qui, info_element->data,
- info_element->len);
- element_info->elementID = info_element->id;
- element_info->length = info_element->len;
- } else
- ret = -1;
-
- if (ret == 0)
- ret = ieee80211_verify_qos_info(element_info,
- QOS_OUI_INFO_SUB_TYPE);
- return ret;
-}
-
-
-/*
- * Write QoS parameters from the ac parameters.
- */
-static int ieee80211_qos_convert_ac_to_parameters(struct
- ieee80211_qos_parameter_info
- *param_elm, struct
- ieee80211_qos_parameters
- *qos_param)
-{
- int rc = 0;
- int i;
- struct ieee80211_qos_ac_parameter *ac_params;
- u8 aci;
- //u8 cw_min;
- //u8 cw_max;
-
- for (i = 0; i < QOS_QUEUE_NUM; i++) {
- ac_params = &(param_elm->ac_params_record[i]);
-
- aci = (ac_params->aci_aifsn & 0x60) >> 5;
-
- if(aci >= QOS_QUEUE_NUM)
- continue;
- qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
-
- /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
- qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
-
- qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
-
- qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
-
- qos_param->flag[aci] =
- (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
- qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
- }
- return rc;
-}
-
-/*
- * we have a generic data element which it may contain QoS information or
- * parameters element. check the information element length to decide
- * which type to read
- */
-static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
- *info_element,
- struct ieee80211_network *network)
-{
- int rc = 0;
- struct ieee80211_qos_parameters *qos_param = NULL;
- struct ieee80211_qos_information_element qos_info_element;
-
- rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
-
- if (rc == 0) {
- network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
- network->flags |= NETWORK_HAS_QOS_INFORMATION;
- } else {
- struct ieee80211_qos_parameter_info param_element;
-
- rc = ieee80211_read_qos_param_element(&param_element,
- info_element);
- if (rc == 0) {
- qos_param = &(network->qos_data.parameters);
- ieee80211_qos_convert_ac_to_parameters(&param_element,
- qos_param);
- network->flags |= NETWORK_HAS_QOS_PARAMETERS;
- network->qos_data.param_count =
- param_element.info_element.ac_info & 0x0F;
- }
- }
-
- if (rc == 0) {
- IEEE80211_DEBUG_QOS("QoS is supported\n");
- network->qos_data.supported = 1;
- }
- return rc;
-}
-
-#ifdef CONFIG_IEEE80211_DEBUG
-#define MFIE_STRING(x) case MFIE_TYPE_ ##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(TIM);
- MFIE_STRING(IBSS_SET);
- MFIE_STRING(COUNTRY);
- MFIE_STRING(HOP_PARAMS);
- MFIE_STRING(HOP_TABLE);
- MFIE_STRING(REQUEST);
- MFIE_STRING(CHALLENGE);
- MFIE_STRING(POWER_CONSTRAINT);
- MFIE_STRING(POWER_CAPABILITY);
- MFIE_STRING(TPC_REQUEST);
- MFIE_STRING(TPC_REPORT);
- MFIE_STRING(SUPP_CHANNELS);
- MFIE_STRING(CSA);
- 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(GENERIC);
- MFIE_STRING(QOS_PARAMETER);
- default:
- return "UNKNOWN";
- }
-}
-#endif
-
-static inline void ieee80211_extract_country_ie(
- struct ieee80211_device *ieee,
- struct ieee80211_info_element *info_element,
- struct ieee80211_network *network,
- u8 * addr2
-)
-{
- if(IS_DOT11D_ENABLE(ieee))
- {
- if(info_element->len!= 0)
- {
- memcpy(network->CountryIeBuf, info_element->data, info_element->len);
- network->CountryIeLen = info_element->len;
-
- if(!IS_COUNTRY_IE_VALID(ieee))
- {
- Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
- }
- }
-
- //
- // 070305, rcnjko: I update country IE watch dog here because
- // some AP (e.g. Cisco 1242) don't include country IE in their
- // probe response frame.
- //
- if(IS_EQUAL_CIE_SRC(ieee, addr2) )
- {
- UPDATE_CIE_WATCHDOG(ieee);
- }
- }
-
-}
-
-int ieee80211_parse_info_param(struct ieee80211_device *ieee,
- struct ieee80211_info_element *info_element,
- u16 length,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
-{
- u8 i;
- short offset;
- u16 tmp_htcap_len=0;
- u16 tmp_htinfo_len=0;
- u16 ht_realtek_agg_len=0;
- u8 ht_realtek_agg_buf[MAX_IE_LEN];
-// u16 broadcom_len = 0;
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
-
- while (length >= sizeof(*info_element)) {
- if (sizeof(*info_element) + info_element->len > length) {
- IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
- "info_element->len + 2 > left : "
- "info_element->len+2=%zd left=%d, id=%d.\n",
- info_element->len +
- sizeof(*info_element),
- length, info_element->id);
- /* We stop processing but don't return an error here
- * because some misbehaviour APs break this rule. ie.
- * Orinoco AP1000. */
- break;
- }
-
- switch (info_element->id) {
- case MFIE_TYPE_SSID:
- if (ieee80211_is_empty_essid(info_element->data,
- info_element->len)) {
- network->flags |= NETWORK_EMPTY_ESSID;
- break;
- }
-
- network->ssid_len = min(info_element->len,
- (u8) IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data, network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
- IW_ESSID_MAX_SIZE - network->ssid_len);
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
- network->ssid, network->ssid_len);
- break;
-
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_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
- p += snprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
- rates_str, network->rates_len);
- break;
-
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_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
- p += snprintf(p, sizeof(rates_str) -
- (p - rates_str), "%02X ",
- network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate
- (info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- rates_str, network->rates_ex_len);
- break;
-
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %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");
- break;
-
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
- break;
-
- case MFIE_TYPE_TIM:
- if(info_element->len < 4)
- break;
-
- network->tim.tim_count = info_element->data[0];
- network->tim.tim_period = info_element->data[1];
-
- network->dtim_period = info_element->data[1];
- if(ieee->state != IEEE80211_LINKED)
- break;
- //we use jiffies for legacy Power save
- network->last_dtim_sta_time[0] = jiffies;
- network->last_dtim_sta_time[1] = stats->mac_time[1];
-
- network->dtim_data = IEEE80211_DTIM_VALID;
-
- if(info_element->data[0] != 0)
- break;
-
- if(info_element->data[2] & 1)
- network->dtim_data |= IEEE80211_DTIM_MBCAST;
-
- offset = (info_element->data[2] >> 1)*2;
-
- //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
-
- if(ieee->assoc_id < 8*offset ||
- ieee->assoc_id > 8*(offset + info_element->len -3))
-
- break;
-
- offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ;
-
- if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
- network->dtim_data |= IEEE80211_DTIM_UCAST;
-
- //IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
- break;
-
- case MFIE_TYPE_ERP:
- 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:
- network->atim_window = info_element->data[0];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
- network->atim_window);
- break;
-
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
- break;
-
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
- info_element->len);
- if (!ieee80211_parse_qos_info_param_IE(info_element,
- network))
- break;
-
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x01) {
- network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->wpa_ie, info_element,
- network->wpa_ie_len);
- break;
- }
-
- if (info_element->len == 7 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x01 &&
- info_element->data[4] == 0x02) {
- network->Turbo_Enable = 1;
- }
-
- //for HTcap and HTinfo parameters
- if(tmp_htcap_len == 0){
- if(info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x90 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x033){
-
- tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
- if(tmp_htcap_len != 0){
- network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
- network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
- sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
- memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
- }
- }
- if(tmp_htcap_len != 0){
- network->bssht.bdSupportHT = true;
- network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
- }else{
- network->bssht.bdSupportHT = false;
- network->bssht.bdHT1R = false;
- }
- }
-
-
- if(tmp_htinfo_len == 0){
- if(info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x90 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x034){
-
- tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
- if(tmp_htinfo_len != 0){
- network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
- if(tmp_htinfo_len){
- network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
- sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
- memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
- }
-
- }
-
- }
- }
-
- if(ieee->aggregation){
- if(network->bssht.bdSupportHT){
- if(info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x02){
-
- ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
- memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
-
- }
- if(ht_realtek_agg_len >= 5){
- network->realtek_cap_exit = true;
- network->bssht.bdRT2RTAggregation = true;
-
- if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
- network->bssht.bdRT2RTLongSlotTime = true;
-
- if((ht_realtek_agg_buf[4]==1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE))
- {
- network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE;
- //bssDesc->Vender = HT_IOT_PEER_REALTEK_92SE;
- }
- }
- }
-
- }
-
- //if(tmp_htcap_len !=0 || tmp_htinfo_len != 0)
- {
- if((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x05 &&
- info_element->data[2] == 0xb5) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x0a &&
- info_element->data[2] == 0xf7) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x10 &&
- info_element->data[2] == 0x18)){
-
- network->broadcom_cap_exist = true;
-
- }
- }
- if(info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x0c &&
- info_element->data[2] == 0x43)
- {
- network->ralink_cap_exist = true;
- }
- else
- network->ralink_cap_exist = false;
- //added by amy for atheros AP
- if((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x03 &&
- info_element->data[2] == 0x7f) ||
- (info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x13 &&
- info_element->data[2] == 0x74))
- {
- // printk("========>%s(): athros AP is exist\n",__FUNCTION__);
- network->atheros_cap_exist = true;
- }
- else
- network->atheros_cap_exist = false;
-
- if ((info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0x43) )
- {
- network->marvell_cap_exist = true;
- }
- else
- network->marvell_cap_exist = false;
-
- if(info_element->len >= 3 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96)
- {
- network->cisco_cap_exist = true;
- }
- else
- network->cisco_cap_exist = false;
- //added by amy for LEAP of cisco
- if(info_element->len > 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96 &&
- info_element->data[3] == 0x01)
- {
- if(info_element->len == 6)
- {
- memcpy(network->CcxRmState, &info_element[4], 2);
- if(network->CcxRmState[0] != 0)
- {
- network->bCcxRmEnable = true;
- }
- else
- network->bCcxRmEnable = false;
- //
- // CCXv4 Table 59-1 MBSSID Masks.
- //
- network->MBssidMask = network->CcxRmState[1] & 0x07;
- if(network->MBssidMask != 0)
- {
- network->bMBssidValid = true;
- network->MBssidMask = 0xff << (network->MBssidMask);
- cpMacAddr(network->MBssid, network->bssid);
- network->MBssid[5] &= network->MBssidMask;
- }
- else
- {
- network->bMBssidValid = false;
- }
- }
- else
- {
- network->bCcxRmEnable = false;
- }
- }
- if(info_element->len > 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x40 &&
- info_element->data[2] == 0x96 &&
- info_element->data[3] == 0x03)
- {
- if(info_element->len == 5)
- {
- network->bWithCcxVerNum = true;
- network->BssCcxVerNumber = info_element->data[4];
- }
- else
- {
- network->bWithCcxVerNum = false;
- network->BssCcxVerNumber = 0;
- }
- }
- break;
-
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
- info_element->len);
- network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->rsn_ie, info_element,
- network->rsn_ie_len);
- break;
-
- //HT related element.
- case MFIE_TYPE_HT_CAP:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
- info_element->len);
- tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
- if(tmp_htcap_len != 0){
- network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
- network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
- sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
- memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
-
- //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
- // windows driver will update WMM parameters each beacon received once connected
- // Linux driver is a bit different.
- network->bssht.bdSupportHT = true;
- network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
- }
- else{
- network->bssht.bdSupportHT = false;
- network->bssht.bdHT1R = false;
- }
- break;
-
-
- case MFIE_TYPE_HT_INFO:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
- info_element->len);
- tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
- if(tmp_htinfo_len){
- network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
- network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
- sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
- memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
- }
- break;
-
- case MFIE_TYPE_AIRONET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
- info_element->len);
- if(info_element->len >IE_CISCO_FLAG_POSITION)
- {
- network->bWithAironetIE = true;
-
- // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23):
- // "A Cisco access point advertises support for CKIP in beacon and probe response packets,
- // by adding an Aironet element and setting one or both of the CKIP negotiation bits."
- if( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) ||
- (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) )
- {
- network->bCkipSupported = true;
- }
- else
- {
- network->bCkipSupported = false;
- }
- }
- else
- {
- network->bWithAironetIE = false;
- network->bCkipSupported = false;
- }
- break;
- case MFIE_TYPE_QOS_PARAMETER:
- printk(KERN_ERR
- "QoS Error need to parse QOS_PARAMETER IE\n");
- break;
-
- case MFIE_TYPE_COUNTRY:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
- info_element->len);
- //printk("=====>Receive <%s> Country IE\n",network->ssid);
- ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP
- break;
- default:
- IEEE80211_DEBUG_MGMT
- ("Unsupported info element: %s (%d)\n",
- get_info_element_string(info_element->id),
- info_element->id);
- break;
- }
-
- length -= sizeof(*info_element) + info_element->len;
- info_element =
- (struct ieee80211_info_element *)&info_element->
- data[info_element->len];
- }
-
- if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
- !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
- {
- network->unknown_cap_exist = true;
- }
- else
- {
- network->unknown_cap_exist = false;
- }
- return 0;
-}
-
-static inline u8 ieee80211_SignalStrengthTranslate(
- u8 CurrSS
- )
-{
- u8 RetSS;
-
- // Step 1. Scale mapping.
- if(CurrSS >= 71 && CurrSS <= 100)
- {
- RetSS = 90 + ((CurrSS - 70) / 3);
- }
- else if(CurrSS >= 41 && CurrSS <= 70)
- {
- RetSS = 78 + ((CurrSS - 40) / 3);
- }
- else if(CurrSS >= 31 && CurrSS <= 40)
- {
- RetSS = 66 + (CurrSS - 30);
- }
- else if(CurrSS >= 21 && CurrSS <= 30)
- {
- RetSS = 54 + (CurrSS - 20);
- }
- else if(CurrSS >= 5 && CurrSS <= 20)
- {
- RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- }
- else if(CurrSS == 4)
- {
- RetSS = 36;
- }
- else if(CurrSS == 3)
- {
- RetSS = 27;
- }
- else if(CurrSS == 2)
- {
- RetSS = 18;
- }
- else if(CurrSS == 1)
- {
- RetSS = 9;
- }
- else
- {
- RetSS = CurrSS;
- }
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- // Step 2. Smoothing.
-
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- return RetSS;
-}
-
-long ieee80211_translate_todbm(u8 signal_strength_index )// 0-100 index.
-{
- long signal_power; // in dBm.
-
- // Translate to dBm (x=0.5y-95).
- signal_power = (long)((signal_strength_index + 1) >> 1);
- signal_power -= 95;
-
- return signal_power;
-}
-
-static inline int ieee80211_network_init(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
- //char rates_str[64];
- //char *p;
-#endif
-
- network->qos_data.active = 0;
- network->qos_data.supported = 0;
- network->qos_data.param_count = 0;
- network->qos_data.old_param_count = 0;
-
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = le16_to_cpu(beacon->capability);
- network->last_scanned = jiffies;
- network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
- network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
- network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
- /* Where to pull this? beacon->listen_interval;*/
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
- network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
- 0x3 : 0x0;
- network->berp_info_valid = false;
- network->broadcom_cap_exist = false;
- network->ralink_cap_exist = false;
- network->atheros_cap_exist = false;
- network->cisco_cap_exist = false;
- network->unknown_cap_exist = false;
- network->realtek_cap_exit = false;
- network->marvell_cap_exist = false;
- network->Turbo_Enable = 0;
- network->CountryIeLen = 0;
- memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-//Initialize HT parameters
- //ieee80211_ht_initialize(&network->bssht);
- HTInitializeBssDesc(&network->bssht);
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
- } else
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
-
- if (ieee80211_parse_info_param
- (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats))
- return 1;
-
- network->mode = 0;
- if (stats->freq == IEEE80211_52GHZ_BAND)
- network->mode = IEEE_A;
- else {
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= IEEE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= IEEE_B;
- }
-
- if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
- "network.\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid);
- return 1;
- }
-
- if(network->bssht.bdSupportHT){
- if(network->mode == IEEE_A)
- network->mode = IEEE_N_5G;
- else if(network->mode & (IEEE_G | IEEE_B))
- network->mode = IEEE_N_24G;
- }
- if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
-
-#if 1
- stats->signal = 30 + (stats->SignalStrength * 70) / 100;
- //stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
- stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25;
-#endif
-
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- return 0;
-}
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst, struct ieee80211_device* ieee)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network */
- return //((src->ssid_len == dst->ssid_len) &&
- (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
- (src->channel == dst->channel) &&
- !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
- (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
- ((src->capability & WLAN_CAPABILITY_IBSS) ==
- (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- ((src->capability & WLAN_CAPABILITY_BSS) ==
- (dst->capability & WLAN_CAPABILITY_BSS)));
-}
-
-static inline void update_network(struct ieee80211_network *dst,
- struct ieee80211_network *src)
-{
- int qos_active;
- u8 old_param;
-
- memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
- dst->capability = src->capability;
- memcpy(dst->rates, src->rates, src->rates_len);
- dst->rates_len = src->rates_len;
- memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- dst->rates_ex_len = src->rates_ex_len;
- if(src->ssid_len > 0)
- {
- memset(dst->ssid, 0, dst->ssid_len);
- dst->ssid_len = src->ssid_len;
- memcpy(dst->ssid, src->ssid, src->ssid_len);
- }
- dst->mode = src->mode;
- dst->flags = src->flags;
- dst->time_stamp[0] = src->time_stamp[0];
- dst->time_stamp[1] = src->time_stamp[1];
- if (src->flags & NETWORK_HAS_ERP_VALUE)
- {
- dst->erp_value = src->erp_value;
- dst->berp_info_valid = src->berp_info_valid = true;
- }
- dst->beacon_interval = src->beacon_interval;
- dst->listen_interval = src->listen_interval;
- dst->atim_window = src->atim_window;
- dst->dtim_period = src->dtim_period;
- dst->dtim_data = src->dtim_data;
- dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
- dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
- memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters));
-
- dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
- dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
- dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
- memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
- dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
- memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
- dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
- dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
- dst->broadcom_cap_exist = src->broadcom_cap_exist;
- dst->ralink_cap_exist = src->ralink_cap_exist;
- dst->atheros_cap_exist = src->atheros_cap_exist;
- dst->realtek_cap_exit = src->realtek_cap_exit;
- dst->marvell_cap_exist = src->marvell_cap_exist;
- dst->cisco_cap_exist = src->cisco_cap_exist;
- dst->unknown_cap_exist = src->unknown_cap_exist;
- memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- dst->wpa_ie_len = src->wpa_ie_len;
- memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- dst->rsn_ie_len = src->rsn_ie_len;
-
- dst->last_scanned = jiffies;
- /* qos related parameters */
- //qos_active = src->qos_data.active;
- qos_active = dst->qos_data.active;
- //old_param = dst->qos_data.old_param_count;
- old_param = dst->qos_data.param_count;
- if(dst->flags & NETWORK_HAS_QOS_MASK){
- //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB
- // printk("====>%s(), aifs:%x, %x\n", __FUNCTION__, dst->qos_data.parameters.aifs[0], src->qos_data.parameters.aifs[0]);
- // memcpy(&dst->qos_data, &src->qos_data,
- // sizeof(struct ieee80211_qos_data));
- }
- else {
- dst->qos_data.supported = src->qos_data.supported;
- dst->qos_data.param_count = src->qos_data.param_count;
- }
-
- if(dst->qos_data.supported == 1) {
- dst->QoS_Enable = 1;
- if(dst->ssid_len)
- IEEE80211_DEBUG_QOS
- ("QoS the network %s is QoS supported\n",
- dst->ssid);
- else
- IEEE80211_DEBUG_QOS
- ("QoS the network is QoS supported\n");
- }
- dst->qos_data.active = qos_active;
- dst->qos_data.old_param_count = old_param;
-
- /* dst->last_associate is not overwritten */
-#if 1
- dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
- if(src->wmm_param[0].ac_aci_acm_aifsn|| \
- src->wmm_param[1].ac_aci_acm_aifsn|| \
- src->wmm_param[2].ac_aci_acm_aifsn|| \
- src->wmm_param[1].ac_aci_acm_aifsn) {
- memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
- }
- //dst->QoS_Enable = src->QoS_Enable;
-#else
- dst->QoS_Enable = 1;//for Rtl8187 simulation
-#endif
- dst->Turbo_Enable = src->Turbo_Enable;
-
- dst->CountryIeLen = src->CountryIeLen;
- memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-
- //added by amy for LEAP
- dst->bWithAironetIE = src->bWithAironetIE;
- dst->bCkipSupported = src->bCkipSupported;
- memcpy(dst->CcxRmState,src->CcxRmState,2);
- dst->bCcxRmEnable = src->bCcxRmEnable;
- dst->MBssidMask = src->MBssidMask;
- dst->bMBssidValid = src->bMBssidValid;
- memcpy(dst->MBssid,src->MBssid,6);
- dst->bWithCcxVerNum = src->bWithCcxVerNum;
- dst->BssCcxVerNumber = src->BssCcxVerNumber;
-
-}
-
-static inline int is_beacon(__le16 fc)
-{
- return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
-}
-
-static inline void ieee80211_process_probe_response(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_rx_stats *stats)
-{
- struct ieee80211_network network;
- struct ieee80211_network *target;
- struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = &beacon->info_element[0];
-#endif
- unsigned long flags;
- short renew;
- //u8 wmm_info;
-
- memset(&network, 0, sizeof(struct ieee80211_network));
- IEEE80211_DEBUG_SCAN(
- "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- beacon->header.addr3,
- (beacon->capability & (1<<0xf)) ? '1' : '0',
- (beacon->capability & (1<<0xe)) ? '1' : '0',
- (beacon->capability & (1<<0xd)) ? '1' : '0',
- (beacon->capability & (1<<0xc)) ? '1' : '0',
- (beacon->capability & (1<<0xb)) ? '1' : '0',
- (beacon->capability & (1<<0xa)) ? '1' : '0',
- (beacon->capability & (1<<0x9)) ? '1' : '0',
- (beacon->capability & (1<<0x8)) ? '1' : '0',
- (beacon->capability & (1<<0x7)) ? '1' : '0',
- (beacon->capability & (1<<0x6)) ? '1' : '0',
- (beacon->capability & (1<<0x5)) ? '1' : '0',
- (beacon->capability & (1<<0x4)) ? '1' : '0',
- (beacon->capability & (1<<0x3)) ? '1' : '0',
- (beacon->capability & (1<<0x2)) ? '1' : '0',
- (beacon->capability & (1<<0x1)) ? '1' : '0',
- (beacon->capability & (1<<0x0)) ? '1' : '0');
-
- if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
- escape_essid(info_element->data,
- info_element->len),
- beacon->header.addr3,
- WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
- return;
- }
-
- // For Asus EeePc request,
- // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
- // wireless adapter should follow the country code.
- // (2) If there is no any country code in beacon,
- // then wireless adapter should do active scan from ch1~11 and
- // passive scan from ch12~14
-
- if( !IsLegalChannel(ieee, network.channel) )
- return;
- if(ieee->bGlobalDomain)
- {
- if (WLAN_FC_GET_STYPE(beacon->header.frame_control) == IEEE80211_STYPE_PROBE_RESP)
- {
- // Case 1: Country code
- if(IS_COUNTRY_IE_VALID(ieee) )
- {
- if( !IsLegalChannel(ieee, network.channel) )
- {
- printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else
- {
- // Filter over channel ch12~14
- if(network.channel > 11)
- {
- printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- }
- else
- {
- // Case 1: Country code
- if(IS_COUNTRY_IE_VALID(ieee) )
- {
- if( !IsLegalChannel(ieee, network.channel) )
- {
- printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else
- {
- // Filter over channel ch12~14
- if(network.channel > 14)
- {
- printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
- return;
- }
- }
- }
- }
-
- /* The network parsed correctly -- so now we scan our known networks
- * to see if we can find it in our list.
- *
- * NOTE: This search is definitely not optimized. Once its doing
- * the "right thing" we'll optimize it for efficiency if
- * necessary */
-
- /* Search for this entry in the list and update it if it is
- * already there. */
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if(is_same_network(&ieee->current_network, &network, ieee)) {
- update_network(&ieee->current_network, &network);
- if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
- && ieee->current_network.berp_info_valid){
- if(ieee->current_network.erp_value& ERP_UseProtection)
- ieee->current_network.buseprotection = true;
- else
- ieee->current_network.buseprotection = false;
- }
- if(is_beacon(beacon->header.frame_control))
- {
- if(ieee->state == IEEE80211_LINKED)
- ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
- }
- else //hidden AP
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
- }
-
- list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, &network, ieee))
- break;
- if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
- oldest = target;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
- if (&target->list == &ieee->network_list) {
- if (list_empty(&ieee->network_free_list)) {
- /* If there are no more slots, expire the oldest */
- list_del(&oldest->list);
- target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
- "network list.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid);
- } else {
- /* Otherwise just pull from the free list */
- target = list_entry(ieee->network_free_list.next,
- struct ieee80211_network, list);
- list_del(ieee->network_free_list.next);
- }
-
-
-#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
- escape_essid(network.ssid,
- network.ssid_len),
- network.bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-#endif
- memcpy(target, &network, sizeof(*target));
- list_add_tail(&target->list, &ieee->network_list);
- if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
- ieee80211_softmac_new_net(ieee,&network);
- } else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-
- /* we have an entry and we are going to update it. But this entry may
- * be already expired. In this case we do the same as we found a new
- * net and call the new_net handler
- */
- renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
- //YJ,add,080819,for hidden ap
- if(is_beacon(beacon->header.frame_control) == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
- //if(strncmp(network.ssid, "linksys-c",9) == 0)
- // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
- && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
- renew = 1;
- //YJ,add,080819,for hidden ap,end
-
- update_network(target, &network);
- if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
- ieee80211_softmac_new_net(ieee,&network);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- if (is_beacon(beacon->header.frame_control)&&is_same_network(&ieee->current_network, &network, ieee)&&\
- (ieee->state == IEEE80211_LINKED)) {
- if(ieee->handle_beacon != NULL) {
- ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
- }
- }
-}
-
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats)
-{
- if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
- ieee->iw_mode == IW_MODE_INFRA &&
- ieee->state == IEEE80211_LINKED))
- {
- tasklet_schedule(&ieee->ps_task);
- }
-
- if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
- WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
- ieee->last_rx_ps_time = jiffies;
-
- switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
-
- case IEEE80211_STYPE_BEACON:
- IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Beacon\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
-
- case IEEE80211_STYPE_PROBE_RESP:
- IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Probe response\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
-
- }
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
deleted file mode 100644
index 02850479dd62..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ /dev/null
@@ -1,3291 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Few lines might be stolen from other part of the ieee80211
- * stack. Copyright who own it's copyright
- *
- * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright.
- *
- * released under the GPL
- */
-
-
-#include "ieee80211.h"
-
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-#include <asm/uaccess.h>
-#include "dot11d.h"
-
-u8 rsn_authen_cipher_suite[16][4] = {
- {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
- {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
- {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
- {0x00,0x0F,0xAC,0x03}, //WRAP-historical
- {0x00,0x0F,0xAC,0x04}, //CCMP
- {0x00,0x0F,0xAC,0x05}, //WEP-104
-};
-
-short ieee80211_is_54g(struct ieee80211_network net)
-{
- return ((net.rates_ex_len > 0) || (net.rates_len > 4));
-}
-
-short ieee80211_is_shortslot(struct ieee80211_network net)
-{
- return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
-}
-
-/* returns the total length needed for pleacing the RATE MFIE
- * tag and the EXTENDED RATE MFIE tag if needed.
- * It encludes two bytes per tag for the tag itself and its len
- */
-unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
-{
- unsigned int rate_len = 0;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION)
- rate_len = IEEE80211_CCK_RATE_LEN + 2;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-
- rate_len += IEEE80211_OFDM_RATE_LEN + 2;
-
- return rate_len;
-}
-
-/* pleace the MFIE rate, tag to the memory (double) poined.
- * Then it updates the pointer so that
- * it points after the new MFIE tag added.
- */
-void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION){
- *tag++ = MFIE_TYPE_RATES;
- *tag++ = 4;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
- }
-
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION){
-
- *tag++ = MFIE_TYPE_RATES_EX;
- *tag++ = 8;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- }
-
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-
-void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC; //0
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0x50;
- *tag++ = 0xf2;
- *tag++ = 0x02;//5
- *tag++ = 0x00;
- *tag++ = 0x01;
-#ifdef SUPPORT_USPD
- if(ieee->current_network.wmm_info & 0x80) {
- *tag++ = 0x0f|MAX_SP_Len;
- } else {
- *tag++ = MAX_SP_Len;
- }
-#else
- *tag++ = MAX_SP_Len;
-#endif
- *tag_p = tag;
-}
-
-void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC; //0
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0xe0;
- *tag++ = 0x4c;
- *tag++ = 0x01;//5
- *tag++ = 0x02;
- *tag++ = 0x11;
- *tag++ = 0x00;
-
- *tag_p = tag;
- printk(KERN_ALERT "This is enable turbo mode IE process\n");
-}
-
-void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
- int nh;
- nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
-
-/*
- * if the queue is full but we have newer frames then
- * just overwrites the oldest.
- *
- * if (nh == ieee->mgmt_queue_tail)
- * return -1;
- */
- ieee->mgmt_queue_head = nh;
- ieee->mgmt_queue_ring[nh] = skb;
-
-}
-
-struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
-{
- struct sk_buff *ret;
-
- if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
- return NULL;
-
- ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
-
- ieee->mgmt_queue_tail =
- (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
-
- return ret;
-}
-
-void init_mgmt_queue(struct ieee80211_device *ieee)
-{
- ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
-}
-
-u8
-MgntQuery_TxRateExcludeCCKRates(struct ieee80211_device *ieee)
-{
- u16 i;
- u8 QueryRate = 0;
- u8 BasicRate;
-
-
- for( i = 0; i < ieee->current_network.rates_len; i++)
- {
- BasicRate = ieee->current_network.rates[i]&0x7F;
- if(!ieee80211_is_cck_rate(BasicRate))
- {
- if(QueryRate == 0)
- {
- QueryRate = BasicRate;
- }
- else
- {
- if(BasicRate < QueryRate)
- {
- QueryRate = BasicRate;
- }
- }
- }
- }
-
- if(QueryRate == 0)
- {
- QueryRate = 12;
- printk("No BasicRate found!!\n");
- }
- return QueryRate;
-}
-u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- u8 rate;
-
- if(pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
- {
- rate = MgntQuery_TxRateExcludeCCKRates(ieee);
- }
- else
- rate = ieee->basic_rate & 0x7f;
-
- if(rate == 0){
- if(ieee->mode == IEEE_A||
- ieee->mode== IEEE_N_5G||
- (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
- rate = 0x0c;
- else
- rate = 0x02;
- }
- return rate;
-}
-
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
-
-inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
-{
- unsigned long flags;
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header=
- (struct ieee80211_hdr_3addr *) skb->data;
-
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd param 0, no mgmt lock required */
- ieee80211_sta_wakeup(ieee,0);
-
- tcb_desc->queue_index = MGNT_QUEUE;
- tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
- tcb_desc->RATRIndex = 7;
- tcb_desc->bTxDisableRateFallBack = 1;
- tcb_desc->bTxUseDriverAssingedRate = 1;
-
- if(single){
- if(ieee->queue_stop){
- enqueue_mgmt(ieee,skb);
- }else{
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- }else{
- spin_unlock_irqrestore(&ieee->lock, flags);
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* check wether the managed packet queued greater than 5 */
- if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
- (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
- (ieee->queue_stop) ) {
- /* insert the skb packet to the management queue */
- /* as for the completion function, it does not need
- * to check it any more.
- * */
- printk("%s():insert to waitqueue!\n",__FUNCTION__);
- skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
- } else {
- ieee->softmac_hard_start_xmit(skb,ieee->dev);
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
- }
-}
-
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
-{
-
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
- u16 fc,type,stype;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
-
- fc = header->frame_control;
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
-
-
- if(stype != IEEE80211_STYPE_PSPOLL)
- tcb_desc->queue_index = MGNT_QUEUE;
- else
- tcb_desc->queue_index = HIGH_QUEUE;
- tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
- tcb_desc->RATRIndex = 7;
- tcb_desc->bTxDisableRateFallBack = 1;
- tcb_desc->bTxUseDriverAssingedRate = 1;
- if(single){
- if(!(type == IEEE80211_FTYPE_CTL)) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- }
- /* avoid watchdog triggers */
- ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
-
- }else{
- if(!(type == IEEE80211_FTYPE_CTL)) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- }
- ieee->softmac_hard_start_xmit(skb,ieee->dev);
-
- }
-}
-
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
-{
- unsigned int len,rate_len;
- u8 *tag;
- struct sk_buff *skb;
- struct ieee80211_probe_request *req;
-
- len = ieee->current_network.ssid_len;
-
- rate_len = ieee80211_MFIE_rate_len(ieee);
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- 2 + len + rate_len + ieee->tx_headroom);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
- req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- req->header.duration_id = 0; //FIXME: is this OK ?
-
- memset(req->header.addr1, 0xff, ETH_ALEN);
- memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memset(req->header.addr3, 0xff, ETH_ALEN);
-
- tag = (u8 *) skb_put(skb,len+2+rate_len);
-
- *tag++ = MFIE_TYPE_SSID;
- *tag++ = len;
- memcpy(tag, ieee->current_network.ssid, len);
- tag += len;
-
- ieee80211_MFIE_Brate(ieee,&tag);
- ieee80211_MFIE_Grate(ieee,&tag);
- return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
-void ieee80211_send_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- if(!ieee->ieee_up)
- return;
- skb = ieee80211_get_beacon_(ieee);
-
- if (skb){
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_beacons++;
- }
-
- if(ieee->beacon_txing && ieee->ieee_up){
- mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
- }
-}
-
-
-void ieee80211_send_beacon_cb(unsigned long _ieee)
-{
- struct ieee80211_device *ieee =
- (struct ieee80211_device *) _ieee;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
- ieee80211_send_beacon(ieee);
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-
-void ieee80211_send_probe(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = ieee80211_probe_req(ieee);
- if (skb){
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_probe_rq++;
- }
-}
-
-void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
-{
- if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
- ieee80211_send_probe(ieee);
- ieee80211_send_probe(ieee);
- }
-}
-
-/* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked.
- */
-void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
-{
- short ch = 0;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- ieee->be_scan_inprogress = true;
- down(&ieee->scan_sem);
-
- while(1)
- {
-
- do{
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
- }while(!channel_map[ch]);
-
- /* this fuction can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * IEEE80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to IEEE80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to IEEE80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarly 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in witch are interested is to check
- * if the state become LINKED because of the #1 situation
- */
-
- if (ieee->state == IEEE80211_LINKED)
- goto out;
- ieee->set_chan(ieee->dev, ch);
- if(channel_map[ch] == 1)
- ieee80211_send_probe_requests(ieee);
-
- /* this prevent excessive time wait when we
- * need to wait for a syncro scan to end..
- */
- if(ieee->state < IEEE80211_LINKED)
- ;
- else
- if (ieee->sync_scan_hurryup)
- goto out;
-
-
- msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
-
- }
-out:
- if(ieee->state < IEEE80211_LINKED){
- ieee->actscanning = false;
- up(&ieee->scan_sem);
- ieee->be_scan_inprogress = false;
- }
- else{
- ieee->sync_scan_hurryup = 0;
- if(IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
- up(&ieee->scan_sem);
- ieee->be_scan_inprogress = false;
-}
-}
-
-void ieee80211_softmac_scan_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
- u8 last_channel = ieee->current_network.channel; //recored init channel inorder not change current channel when comming out the scan unexpectedly. WB.
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- if(!ieee->ieee_up)
- return;
- down(&ieee->scan_sem);
- do{
- ieee->current_network.channel =
- (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER)
- {
- //if current channel is not in channel map, set to default channel.
- if (!channel_map[ieee->current_network.channel]);
- ieee->current_network.channel = 6;
- goto out; /* no good chans */
- }
- }while(!channel_map[ieee->current_network.channel]);
- if (ieee->scanning == 0 )
- goto out;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- if(channel_map[ieee->current_network.channel] == 1)
- ieee80211_send_probe_requests(ieee);
-
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
-
- up(&ieee->scan_sem);
- return;
-out:
- if(IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
- ieee->current_network.channel = last_channel;
- ieee->actscanning = false;
- ieee->scan_watch_dog = 0;
- ieee->scanning = 0;
- up(&ieee->scan_sem);
-}
-
-void ieee80211_beacons_start(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- spin_lock_irqsave(&ieee->beacon_lock,flags);
-
- ieee->beacon_txing = 1;
- ieee80211_send_beacon(ieee);
-
- spin_unlock_irqrestore(&ieee->beacon_lock,flags);
-}
-
-void ieee80211_beacons_stop(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock,flags);
-
- ieee->beacon_txing = 0;
- del_timer_sync(&ieee->beacon_timer);
-
- spin_unlock_irqrestore(&ieee->beacon_lock,flags);
-
-}
-
-
-void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
-{
- if(ieee->stop_send_beacons)
- ieee->stop_send_beacons(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_stop(ieee);
-}
-
-
-void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
-{
- if(ieee->start_send_beacons)
- ieee->start_send_beacons(ieee->dev);
- if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_start(ieee);
-}
-
-
-void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
-{
-
- down(&ieee->scan_sem);
- ieee->scan_watch_dog = 0;
- if (ieee->scanning == 1){
- ieee->scanning = 0;
-
- cancel_delayed_work(&ieee->softmac_scan_wq);
- }
-
- up(&ieee->scan_sem);
-}
-
-void ieee80211_stop_scan(struct ieee80211_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_stop_scan(ieee);
- else
- ieee->stop_scan(ieee->dev);
-}
-
-/* called with ieee->lock held */
-void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
-{
- if(IS_DOT11D_ENABLE(ieee) )
- {
- if(IS_COUNTRY_IE_VALID(ieee))
- {
- RESET_CIE_WATCHDOG(ieee);
- }
- }
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
- if (ieee->scanning == 0){
- ieee->scanning = 1;
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
- }
- }else
- ieee->start_scan(ieee->dev);
-
-}
-
-/* called with wx_sem held */
-void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
-{
- if(IS_DOT11D_ENABLE(ieee) )
- {
- if(IS_COUNTRY_IE_VALID(ieee))
- {
- RESET_CIE_WATCHDOG(ieee);
- }
- }
- ieee->sync_scan_hurryup = 0;
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_scan_syncro(ieee);
- else
- ieee->scan_syncro(ieee->dev);
-
-}
-
-inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee, int challengelen)
-{
- struct sk_buff *skb;
- struct ieee80211_authentication *auth;
- int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
-
-
- skb = dev_alloc_skb(len);
- if (!skb) return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
- auth = (struct ieee80211_authentication *)
- skb_put(skb, sizeof(struct ieee80211_authentication));
-
- auth->header.frame_control = IEEE80211_STYPE_AUTH;
- if (challengelen) auth->header.frame_control |= IEEE80211_FCTL_WEP;
-
- auth->header.duration_id = 0x013a; //FIXME
-
- memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
-
- if(ieee->auth_mode == 0)
- auth->algorithm = WLAN_AUTH_OPEN;
- else if(ieee->auth_mode == 1)
- auth->algorithm = WLAN_AUTH_SHARED_KEY;
- else if(ieee->auth_mode == 2)
- auth->algorithm = WLAN_AUTH_OPEN;//0x80;
- printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
- auth->transaction = cpu_to_le16(ieee->associate_seq);
- ieee->associate_seq++;
-
- auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-
- return skb;
-
-}
-
-void constructWMMIE(u8* wmmie, u8* wmm_len,u8 oui_subtype)
-{
- u8 szQoSOUI[] ={221, 0, 0x00, 0x50, 0xf2, 0x02, 0, 1};
-
- if (oui_subtype == OUI_SUBTYPE_QOS_CAPABI)
- {
- szQoSOUI[0] = 46;
- szQoSOUI[1] = *wmm_len;
- memcpy(wmmie,szQoSOUI,3);
- *wmm_len = 3;
- }
- else
- {
- szQoSOUI[1] = *wmm_len + 6;
- szQoSOUI[6] = oui_subtype;
- memcpy(wmmie, szQoSOUI, 8);
- *(wmmie+8) = 0;
- *wmm_len = 9;
- }
-}
-
-static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
-{
- u8 *tag;
- int beacon_size;
- struct ieee80211_probe_response *beacon_buf;
- struct sk_buff *skb = NULL;
- int encrypt;
- int atim_len,erp_len;
- struct ieee80211_crypt_data* crypt;
-
- char *ssid = ieee->current_network.ssid;
- int ssid_len = ieee->current_network.ssid_len;
- int rate_len = ieee->current_network.rates_len+2;
- int rate_ex_len = ieee->current_network.rates_ex_len;
- int wpa_ie_len = ieee->wpa_ie_len;
- u8 erpinfo_content = 0;
-
- u8* tmp_ht_cap_buf=NULL;
- u8 tmp_ht_cap_len=0;
- u8* tmp_ht_info_buf=NULL;
- u8 tmp_ht_info_len=0;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- u8* tmp_generic_ie_buf=NULL;
- u8 tmp_generic_ie_len=0;
-
-
- u8 wmmie[9] = {0};
- u8 wmm_len = 0;
-
- if(rate_ex_len > 0) rate_ex_len+=2;
-
- if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
- atim_len = 4;
- else
- atim_len = 0;
-
-#if 0
- if(ieee80211_is_54g(ieee->current_network))
- erp_len = 3;
- else
- erp_len = 0;
-#else
- if((ieee->current_network.mode == IEEE_G)
- ||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) {
- erp_len = 3;
- erpinfo_content = 0;
- if(ieee->current_network.buseprotection)
- erpinfo_content |= ERP_UseProtection;
- }
- else
- erp_len = 0;
-#endif
-
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
-
- encrypt = ieee->host_encrypt && crypt && crypt->ops &&
- ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
- //HT ralated element
-#if 1
- if(ieee->pHTInfo->bCurrentHTSupport){
- tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
- tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
- tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
- tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
-
- HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
-
- HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
-
-
- if(pHTInfo->bRegRT2RTAggregation)
- {
- tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
- tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
- HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
- }
- }
-#endif
-
- if(ieee->qos_support){
-
- if(ieee->iw_mode == IW_MODE_ADHOC)
- {
- wmm_len = 1;
- constructWMMIE(wmmie,&wmm_len,OUI_SUBTYPE_WMM_INFO);
- }
- }
-
- beacon_size = sizeof(struct ieee80211_probe_response)+2+
- ssid_len
- +3 //channel
- +rate_len
- +rate_ex_len
- +atim_len
- +erp_len
- +wpa_ie_len
- // +tmp_ht_cap_len
- // +tmp_ht_info_len
- // +tmp_generic_ie_len
-// +wmm_len+2
- +ieee->tx_headroom;
- skb = dev_alloc_skb(beacon_size);
- if (!skb)
- return NULL;
- skb_reserve(skb, ieee->tx_headroom);
- beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
- memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
- memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
-
- beacon_buf->header.duration_id = 0; //FIXME
- beacon_buf->beacon_interval =
- cpu_to_le16(ieee->current_network.beacon_interval);
- beacon_buf->capability =
- cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
- beacon_buf->capability |=
- cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
-
- if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
- cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- if (encrypt)
- beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-
- beacon_buf->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
- beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
- beacon_buf->info_element[0].len = ssid_len;
-
- tag = (u8*) beacon_buf->info_element[0].data;
-
- memcpy(tag, ssid, ssid_len);
-
- tag += ssid_len;
-
- *(tag++) = MFIE_TYPE_RATES;
- *(tag++) = rate_len-2;
- memcpy(tag,ieee->current_network.rates,rate_len-2);
- tag+=rate_len-2;
-
- *(tag++) = MFIE_TYPE_DS_SET;
- *(tag++) = 1;
- *(tag++) = ieee->current_network.channel;
-
- if(atim_len){
- u16 val16;
- *(tag++) = MFIE_TYPE_IBSS_SET;
- *(tag++) = 2;
- val16 = cpu_to_le16(ieee->current_network.atim_window);
- memcpy((u8 *)tag, (u8 *)&val16, 2);
- tag+=2;
- }
-
- if(erp_len){
- *(tag++) = MFIE_TYPE_ERP;
- *(tag++) = 1;
- *(tag++) = erpinfo_content;
- }
-
- if(rate_ex_len){
- *(tag++) = MFIE_TYPE_RATES_EX;
- *(tag++) = rate_ex_len-2;
- memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
- tag+=rate_ex_len-2;
- }
-
- if (wpa_ie_len)
- {
- if (ieee->iw_mode == IW_MODE_ADHOC)
- {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
- memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
- }
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- tag += wpa_ie_len;
- }
-
- return skb;
-}
-
-
-struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
-{
- struct sk_buff *skb;
- u8* tag;
-
- struct ieee80211_crypt_data* crypt;
- struct ieee80211_assoc_response_frame *assoc;
- short encrypt;
-
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- assoc = (struct ieee80211_assoc_response_frame *)
- skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
-
- assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
- memcpy(assoc->header.addr1, dest,ETH_ALEN);
- memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
- WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-
-
- if(ieee->short_slot)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- if (ieee->host_encrypt)
- crypt = ieee->crypt[ieee->tx_keyidx];
- else crypt = NULL;
-
- encrypt = ( crypt && crypt->ops);
-
- if (encrypt)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
- assoc->status = 0;
- assoc->aid = cpu_to_le16(ieee->assoc_id);
- if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
- else ieee->assoc_id++;
-
- tag = (u8*) skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- return skb;
-}
-
-struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
-{
- struct sk_buff *skb;
- struct ieee80211_authentication *auth;
- int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb->len = sizeof(struct ieee80211_authentication);
-
- auth = (struct ieee80211_authentication *)skb->data;
-
- auth->status = cpu_to_le16(status);
- auth->transaction = cpu_to_le16(2);
- auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
-
- memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr1, dest, ETH_ALEN);
- auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
- return skb;
-
-
-}
-
-struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr* hdr;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
-
- if (!skb)
- return NULL;
-
- hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
-
- memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
-
- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
- (pwr ? IEEE80211_FCTL_PM:0));
-
- return skb;
-
-
-}
-
-
-void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
-{
- struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
-
- if (buf)
- softmac_mgmt_xmit(buf, ieee);
-}
-
-
-void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
-{
- struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
-
- if (buf)
- softmac_mgmt_xmit(buf, ieee);
-}
-
-
-void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
-{
-
-
- struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
- if (buf)
- softmac_mgmt_xmit(buf, ieee);
-}
-
-
-inline int SecIsInPMKIDList(struct ieee80211_device *ieee, u8 *bssid)
-{
- int i = 0;
-
- do
- {
- if ((ieee->PMKIDList[i].bUsed) && (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
- {
- break;
- }
- else
- {
- i++;
- }
- } while (i < NUM_PMKID_CACHE);
-
- if (i == NUM_PMKID_CACHE)
- {
- i = -1;
- }
- else
- {
- }
-
- return (i);
-
-}
-inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- struct ieee80211_assoc_request_frame *hdr;
- u8 *tag;//,*rsn_ie;
- u8* ht_cap_buf = NULL;
- u8 ht_cap_len=0;
- u8* realtek_ie_buf=NULL;
- u8 realtek_ie_len=0;
- int wpa_ie_len= ieee->wpa_ie_len;
- unsigned int ckip_ie_len=0;
- unsigned int ccxrm_ie_len=0;
- unsigned int cxvernum_ie_len=0;
- struct ieee80211_crypt_data* crypt;
- int encrypt;
- int PMKCacheIdx;
-
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
- unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-
- int len = 0;
-
- crypt = ieee->crypt[ieee->tx_keyidx];
- encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
-
- //Include High Throuput capability && Realtek proprietary
- if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
- {
- ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
- ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
- HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
- if(ieee->pHTInfo->bCurrentRT2RTAggregation)
- {
- realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
- realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
- HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
-
- }
- }
- if(ieee->qos_support){
- wmm_info_len = beacon->qos_data.supported?9:0;
- }
-
-
- if(beacon->bCkipSupported)
- {
- ckip_ie_len = 30+2;
- }
- if(beacon->bCcxRmEnable)
- {
- ccxrm_ie_len = 6+2;
- }
- if( beacon->BssCcxVerNumber >= 2 )
- {
- cxvernum_ie_len = 5+2;
- }
-
- PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
- if (PMKCacheIdx >= 0)
- {
- wpa_ie_len += 18;
- printk("[PMK cache]: WPA2 IE length: %x\n", wpa_ie_len);
- }
-
- len = sizeof(struct ieee80211_assoc_request_frame)+ 2
- + beacon->ssid_len//essid tagged val
- + rate_len//rates tagged val
- + wpa_ie_len
- + wmm_info_len
- + turbo_info_len
- + ht_cap_len
- + realtek_ie_len
- + ckip_ie_len
- + ccxrm_ie_len
- + cxvernum_ie_len
- + ieee->tx_headroom;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- skb_reserve(skb, ieee->tx_headroom);
-
- hdr = (struct ieee80211_assoc_request_frame *)
- skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
-
-
- hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
- hdr->header.duration_id= 37; //FIXME
- memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
-
- memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
-
- hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
- if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
- if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
-
- if(ieee->short_slot)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
- if (wmm_info_len) //QOS
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
-
- hdr->listen_interval = 0xa; //FIXME
-
- hdr->info_element[0].id = MFIE_TYPE_SSID;
-
- hdr->info_element[0].len = beacon->ssid_len;
- tag = skb_put(skb, beacon->ssid_len);
- memcpy(tag, beacon->ssid, beacon->ssid_len);
-
- tag = skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
- // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
- if( beacon->bCkipSupported )
- {
- static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
- u8 CcxAironetBuf[30];
- OCTET_STRING osCcxAironetIE;
-
- memset(CcxAironetBuf, 0,30);
- osCcxAironetIE.Octet = CcxAironetBuf;
- osCcxAironetIE.Length = sizeof(CcxAironetBuf);
- //
- // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
- // We want to make the device type as "4500-client". 060926, by CCW.
- //
- memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
-
- // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
- // "The CKIP negotiation is started with the associate request from the client to the access point,
- // containing an Aironet element with both the MIC and KP bits set."
- osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
- tag = skb_put(skb, ckip_ie_len);
- *tag++ = MFIE_TYPE_AIRONET;
- *tag++ = osCcxAironetIE.Length;
- memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
- tag += osCcxAironetIE.Length;
- }
-
- if(beacon->bCcxRmEnable)
- {
- static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
- OCTET_STRING osCcxRmCap;
-
- osCcxRmCap.Octet = CcxRmCapBuf;
- osCcxRmCap.Length = sizeof(CcxRmCapBuf);
- tag = skb_put(skb,ccxrm_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = osCcxRmCap.Length;
- memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
- tag += osCcxRmCap.Length;
- }
-
- if( beacon->BssCcxVerNumber >= 2 )
- {
- u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
- OCTET_STRING osCcxVerNum;
- CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
- osCcxVerNum.Octet = CcxVerNumBuf;
- osCcxVerNum.Length = sizeof(CcxVerNumBuf);
- tag = skb_put(skb,cxvernum_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = osCcxVerNum.Length;
- memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
- tag += osCcxVerNum.Length;
- }
- //HT cap element
- if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
- if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
- {
- tag = skb_put(skb, ht_cap_len);
- *tag++ = MFIE_TYPE_HT_CAP;
- *tag++ = ht_cap_len - 2;
- memcpy(tag, ht_cap_buf,ht_cap_len -2);
- tag += ht_cap_len -2;
- }
- }
-
-
- //choose what wpa_supplicant gives to associate.
- tag = skb_put(skb, wpa_ie_len);
- if (wpa_ie_len){
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- if (PMKCacheIdx >= 0)
- {
- tag = skb_put(skb, 18);
- *tag = 1;
- *(tag + 1) = 0;
- memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, 16);
- }
- }
-
- tag = skb_put(skb,wmm_info_len);
- if(wmm_info_len) {
- ieee80211_WMM_Info(ieee, &tag);
- }
- tag = skb_put(skb,turbo_info_len);
- if(turbo_info_len) {
- ieee80211_TURBO_Info(ieee, &tag);
- }
-
- if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
- if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
- {
- tag = skb_put(skb, ht_cap_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = ht_cap_len - 2;
- memcpy(tag, ht_cap_buf,ht_cap_len - 2);
- tag += ht_cap_len -2;
- }
-
- if(ieee->pHTInfo->bCurrentRT2RTAggregation){
- tag = skb_put(skb, realtek_ie_len);
- *tag++ = MFIE_TYPE_GENERIC;
- *tag++ = realtek_ie_len - 2;
- memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
- }
- }
- return skb;
-}
-
-void ieee80211_associate_abort(struct ieee80211_device *ieee)
-{
-
- unsigned long flags;
- spin_lock_irqsave(&ieee->lock, flags);
-
- ieee->associate_seq++;
-
- /* don't scan, and avoid to have the RX path possibily
- * try again to associate. Even do not react to AUTH or
- * ASSOC response. Just wait for the retry wq to be scheduled.
- * Here we will check if there are good nets to associate
- * with, so we retry or just get back to NO_LINK and scanning
- */
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
- IEEE80211_DEBUG_MGMT("Authentication failed\n");
- ieee->softmac_stats.no_auth_rs++;
- }else{
- IEEE80211_DEBUG_MGMT("Association failed\n");
- ieee->softmac_stats.no_ass_rs++;
- }
-
- ieee->state = IEEE80211_ASSOCIATING_RETRY;
-
- queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
- IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_associate_abort_cb(unsigned long dev)
-{
- ieee80211_associate_abort((struct ieee80211_device *) dev);
-}
-
-
-void ieee80211_associate_step1(struct ieee80211_device *ieee)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
-
- IEEE80211_DEBUG_MGMT("Stopping scan\n");
-
- ieee->softmac_stats.tx_auth_rq++;
- skb=ieee80211_authentication_req(beacon, ieee, 0);
-
- if (!skb)
- ieee80211_associate_abort(ieee);
- else{
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
- IEEE80211_DEBUG_MGMT("Sending authentication request\n");
- softmac_mgmt_xmit(skb, ieee);
- //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
- if(!timer_pending(&ieee->associate_timer)){
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- //dev_kfree_skb_any(skb);//edit by thomas
- }
-}
-
-void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
-{
- u8 *c;
- struct sk_buff *skb;
- struct ieee80211_network *beacon = &ieee->current_network;
-
- ieee->associate_seq++;
- ieee->softmac_stats.tx_auth_rq++;
-
- skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else{
- c = skb_put(skb, chlen+2);
- *(c++) = MFIE_TYPE_CHALLENGE;
- *(c++) = chlen;
- memcpy(c, challenge, chlen);
-
- IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
-
- ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
-
- softmac_mgmt_xmit(skb, ieee);
- mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
- }
- kfree(challenge);
-}
-
-void ieee80211_associate_step2(struct ieee80211_device *ieee)
-{
- struct sk_buff* skb;
- struct ieee80211_network *beacon = &ieee->current_network;
-
- del_timer_sync(&ieee->associate_timer);
-
- IEEE80211_DEBUG_MGMT("Sending association request\n");
-
- ieee->softmac_stats.tx_ass_rq++;
- skb=ieee80211_association_req(beacon, ieee);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else{
- softmac_mgmt_xmit(skb, ieee);
- mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
- }
-}
-
-void ieee80211_associate_complete_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-
- printk(KERN_INFO "Associated successfully\n");
- ieee->is_roaming = false;
- if(ieee80211_is_54g(ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)){
-
- ieee->rate = 108;
- printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
- }else{
- ieee->rate = 22;
- printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
- }
- if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
- {
- printk("Successfully associated, ht enabled\n");
- HTOnAssocRsp(ieee);
- }
- else
- {
- printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
- memset(ieee->dot11HTOperationalRateSet, 0, 16);
- }
- ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
- // To prevent the immediately calling watch_dog after association.
- if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
- {
- ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
- ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
- }
- ieee->link_change(ieee->dev);
- if(ieee->is_silent_reset == 0){
- printk("============>normal associate\n");
- notify_wx_assoc_event(ieee);
- }
- else if(ieee->is_silent_reset == 1)
- {
- printk("==================>silent reset associate\n");
- ieee->is_silent_reset = 0;
- }
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
- netif_carrier_on(ieee->dev);
-}
-
-void ieee80211_associate_complete(struct ieee80211_device *ieee)
-{
-// int i;
-// struct net_device* dev = ieee->dev;
- del_timer_sync(&ieee->associate_timer);
-
- ieee->state = IEEE80211_LINKED;
- queue_work(ieee->wq, &ieee->associate_complete_wq);
-}
-
-void ieee80211_associate_procedure_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_scan(ieee);
- printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
- HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
-
- if(ieee->eRFPowerState == eRfOff)
- {
- printk("=============>%s():Rf state is eRfOff, schedule ipsleave wq again,return\n",__FUNCTION__);
- up(&ieee->wx_sem);
- return;
- }
- ieee->associate_seq = 1;
- ieee80211_associate_step1(ieee);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
-{
- u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
- int tmp_ssid_len = 0;
-
- short apset,ssidset,ssidbroad,apmatch,ssidmatch;
-
- /* we are interested in new new only if we are not associated
- * and we are not associating / authenticating
- */
- if (ieee->state != IEEE80211_NOLINK)
- return;
-
- if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
- return;
-
- if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
- return;
-
- if ((ieee->iw_mode == IW_MODE_ADHOC) && (net->channel > ieee->ibss_maxjoin_chal))
- return;
-
- if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
- /* if the user specified the AP MAC, we need also the essid
- * This could be obtained by beacons or, if the network does not
- * broadcast it, it can be put manually.
- */
- apset = ieee->wap_set;
- ssidset = ieee->ssid_set;
- ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
- apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
- ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
- (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
-
-
- if ( /* if the user set the AP check if match.
- * if the network does not broadcast essid we check the user supplyed ANY essid
- * if the network does broadcast and the user does not set essid it is OK
- * if the network does broadcast and the user did set essid chech if essid match
- */
- ( apset && apmatch &&
- ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
- /* if the ap is not set, check that the user set the bssid
- * and the network does bradcast and that those two bssid matches
- */
- (!apset && ssidset && ssidbroad && ssidmatch)
- ){
- /* if the essid is hidden replace it with the
- * essid provided by the user.
- */
- if (!ssidbroad){
- strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
- tmp_ssid_len = ieee->current_network.ssid_len;
- }
- memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
-
- if (!ssidbroad){
- strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
- ieee->current_network.ssid_len = tmp_ssid_len;
- }
- printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT, ieee->current_network.mode);
-
- //ieee->pHTInfo->IOTAction = 0;
- HTResetIOTSetting(ieee->pHTInfo);
- if (ieee->iw_mode == IW_MODE_INFRA){
- /* Join the network for the first time */
- ieee->AsocRetryCount = 0;
- //for HT by amy 080514
- if((ieee->current_network.qos_data.supported == 1) &&
- ieee->current_network.bssht.bdSupportHT)
-/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
- {
- // ieee->pHTInfo->bCurrentHTSupport = true;
- HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
- }
- else
- {
- ieee->pHTInfo->bCurrentHTSupport = false;
- }
-
- ieee->state = IEEE80211_ASSOCIATING;
- if(ieee->LedControlHandler != NULL)
- ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK);
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- }else{
- if(ieee80211_is_54g(ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)){
- ieee->rate = 108;
- ieee->SetWirelessMode(ieee->dev, IEEE_G);
- printk(KERN_INFO"Using G rates\n");
- }else{
- ieee->rate = 22;
- ieee->SetWirelessMode(ieee->dev, IEEE_B);
- printk(KERN_INFO"Using B rates\n");
- }
- memset(ieee->dot11HTOperationalRateSet, 0, 16);
- ieee->state = IEEE80211_LINKED;
- }
-
- }
- }
-
-}
-
-void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- struct ieee80211_network *target;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(target, &ieee->network_list, list) {
-
- /* if the state become different that NOLINK means
- * we had found what we are searching for
- */
-
- if (ieee->state != IEEE80211_NOLINK)
- break;
-
- if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
- ieee80211_softmac_new_net(ieee, target);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-
-static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
-{
- struct ieee80211_authentication *a;
- u8 *t;
- if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
- return 0xcafe;
- }
- *challenge = NULL;
- a = (struct ieee80211_authentication*) skb->data;
- if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
- t = skb->data + sizeof(struct ieee80211_authentication);
-
- if(*(t++) == MFIE_TYPE_CHALLENGE){
- *chlen = *(t++);
- *challenge = kmalloc(*chlen, GFP_ATOMIC);
- memcpy(*challenge, t, *chlen);
- }
- }
-
- return cpu_to_le16(a->status);
-
-}
-
-
-int auth_rq_parse(struct sk_buff *skb,u8* dest)
-{
- struct ieee80211_authentication *a;
-
- if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
- IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
- return -1;
- }
- a = (struct ieee80211_authentication*) skb->data;
-
- memcpy(dest,a->header.addr2, ETH_ALEN);
-
- if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
- return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-
- return WLAN_STATUS_SUCCESS;
-}
-
-static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
-{
- u8 *tag;
- u8 *skbend;
- u8 *ssid=NULL;
- u8 ssidlen = 0;
-
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
- return -1; /* corrupted */
-
- if((memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) != 0)&&
- (memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) != 0)) {
- return -1;
- }
-
- if(memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) == 0) {
- }
-
- if(memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) == 0) {
- }
- memcpy(src,header->addr2, ETH_ALEN);
-
- skbend = (u8*)skb->data + skb->len;
-
- tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
-
- while (tag+1 < skbend){
- if (*tag == 0){
- ssid = tag+2;
- ssidlen = *(tag+1);
- break;
- }
- tag++; /* point to the len field */
- tag = tag + *(tag); /* point to the last data byte of the tag */
- tag++; /* point to the next tag */
- }
-
- if (ssidlen == 0) return 1;
-
- if (!ssid) return 1; /* ssid not found in tagged param */
- return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
-
-}
-
-int assoc_rq_parse(struct sk_buff *skb,u8* dest)
-{
- struct ieee80211_assoc_request_frame *a;
-
- if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
- sizeof(struct ieee80211_info_element))) {
-
- IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
- return -1;
- }
-
- a = (struct ieee80211_assoc_request_frame*) skb->data;
-
- memcpy(dest,a->header.addr2,ETH_ALEN);
-
- return 0;
-}
-
-static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
-{
- struct ieee80211_assoc_response_frame *response_head;
- u16 status_code;
-
- if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- return 0xcafe;
- }
-
- response_head = (struct ieee80211_assoc_response_frame*) skb->data;
- *aid = le16_to_cpu(response_head->aid) & 0x3fff;
-
- status_code = le16_to_cpu(response_head->status);
- if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
- status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
- ((ieee->mode == IEEE_G) &&
- (ieee->current_network.mode == IEEE_N_24G) &&
- (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
- ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
- }else {
- ieee->AsocRetryCount = 0;
- }
-
- return le16_to_cpu(response_head->status);
-}
-
-static inline void
-ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_probe_rq++;
- if (probe_rq_parse(ieee, skb, dest)){
- ieee->softmac_stats.tx_probe_rs++;
- ieee80211_resp_to_probe(ieee, dest);
- }
-}
-
-static inline void
-ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
- int status;
- ieee->softmac_stats.rx_auth_rq++;
-
- status = auth_rq_parse(skb, dest);
- if (status != -1) {
- ieee80211_resp_to_auth(ieee, status, dest);
- }
-
-}
-
-static inline void
-ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
-
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_ass_rq++;
- if (assoc_rq_parse(skb,dest) != -1){
- ieee80211_resp_to_assoc_rq(ieee, dest);
- }
-
- printk(KERN_INFO"New client associated: %pM\n", dest);
- //FIXME
-}
-
-
-
-void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
-{
-
- struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
-
- if (buf)
- softmac_ps_mgmt_xmit(buf, ieee);
-
-}
-
-
-short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
-{
- int timeout = ieee->ps_timeout;
- u8 dtim;
- /*if(ieee->ps == IEEE80211_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->state != IEEE80211_LINKED)
-
- return 0;
- */
- dtim = ieee->current_network.dtim_data;
- if(!(dtim & IEEE80211_DTIM_VALID))
- return 0;
- timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
- //printk("VALID\n");
- ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
- if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
- return 2;
-
- if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
- return 0;
-
- if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
- return 0;
-
- if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
- (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
- return 0;
-
- if(time_l){
- *time_l = ieee->current_network.last_dtim_sta_time[0]
- + (ieee->current_network.beacon_interval);
- }
-
- if(time_h){
- *time_h = ieee->current_network.last_dtim_sta_time[1];
- if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
- *time_h += 1;
- }
-
- return 1;
-
-
-}
-
-inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
-{
-
- u32 th,tl;
- short sleep;
-
- unsigned long flags,flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if((ieee->ps == IEEE80211_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->state != IEEE80211_LINKED)){
-
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
- sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
- /* 2 wake, 1 sleep, 0 do nothing */
- if(sleep == 0)
- goto out;
-
- if(sleep == 1){
-
- if(ieee->sta_sleep == 1)
- ieee->enter_sleep_state(ieee->dev,th,tl);
-
- else if(ieee->sta_sleep == 0){
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- if(ieee->ps_is_queue_empty(ieee->dev)){
-
-
- ieee->sta_sleep = 2;
-
- ieee->ack_tx_to_ieee = 1;
-
- ieee80211_sta_ps_send_null_frame(ieee,1);
-
- ieee->ps_th = th;
- ieee->ps_tl = tl;
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-
- }
-
-
- }else if(sleep == 2){
-//#warning CHECK_LOCK_HERE
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee,1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
-{
- if(ieee->sta_sleep == 0){
- if(nl){
- printk("Warning: driver is probably failing to report TX ps error\n");
- ieee->ack_tx_to_ieee = 1;
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
- return;
-
- }
-
- if(ieee->sta_sleep == 1)
- ieee->sta_wake_up(ieee->dev);
-
- ieee->sta_sleep = 0;
-
- if(nl){
- ieee->ack_tx_to_ieee = 1;
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
-}
-
-void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
-{
- unsigned long flags,flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if(ieee->sta_sleep == 2){
- /* Null frame with PS bit set */
- if(success){
- ieee->sta_sleep = 1;
- ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
- }
- /* if the card report not success we can't be sure the AP
- * has not RXed so we can't assume the AP believe us awake
- */
- }
- /* 21112005 - tx again null without PS bit if lost */
- else {
-
- if((ieee->sta_sleep == 0) && !success){
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
-{
- struct rtl_ieee80211_hdr *header =
- (struct rtl_ieee80211_hdr *)skb->data;
- u8* act = ieee80211_get_payload(header);
- u8 tmp = 0;
-// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
- if (act == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
- return;
- }
- tmp = *act;
- act ++;
- switch (tmp)
- {
- case ACT_CAT_BA:
- if (*act == ACT_ADDBAREQ)
- ieee80211_rx_ADDBAReq(ieee, skb);
- else if (*act == ACT_ADDBARSP)
- ieee80211_rx_ADDBARsp(ieee, skb);
- else if (*act == ACT_DELBA)
- ieee80211_rx_DELBA(ieee, skb);
- break;
- default:
- break;
- }
- return;
-
-}
-inline int
-ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
- u16 errcode;
- u8* challenge;
- int chlen=0;
- int aid;
- struct ieee80211_assoc_response_frame *assoc_resp;
- bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
-
- if(!ieee->proto_started)
- return 0;
-
- switch (WLAN_FC_GET_STYPE(header->frame_control)) {
-
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:
-
- IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_control));
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
- ieee->iw_mode == IW_MODE_INFRA){
- struct ieee80211_network network_resp;
- struct ieee80211_network *network = &network_resp;
-
- if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
- ieee->state=IEEE80211_LINKED;
- ieee->assoc_id = aid;
- ieee->softmac_stats.rx_ass_ok++;
- /* station support qos */
- /* Let the register setting defaultly with Legacy station */
- if(ieee->qos_support) {
- assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
- memset(network, 0, sizeof(*network));
- if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
- rx_stats->len - sizeof(*assoc_resp),\
- network,rx_stats)){
- return 1;
- }
- else
- { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
- memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
- memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
- }
- if (ieee->handle_assoc_response != NULL)
- ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
- }
- ieee80211_associate_complete(ieee);
- } else {
- /* aid could not been allocated */
- ieee->softmac_stats.rx_ass_err++;
- printk(
- "Association response status code 0x%x\n",
- errcode);
- IEEE80211_DEBUG_MGMT(
- "Association response status code 0x%x\n",
- errcode);
- if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- } else {
- ieee80211_associate_abort(ieee);
- }
- }
- }
- break;
-
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
-
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->iw_mode == IW_MODE_MASTER)
-
- ieee80211_rx_assoc_rq(ieee, skb);
- break;
-
- case IEEE80211_STYPE_AUTH:
-
- if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
- ieee->iw_mode == IW_MODE_INFRA){
-
- IEEE80211_DEBUG_MGMT("Received authentication response");
-
- if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
- if(ieee->open_wep || !challenge){
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
- ieee->softmac_stats.rx_auth_rs_ok++;
- if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
- {
- if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
- {
- // WEP or TKIP encryption
- if(IsHTHalfNmodeAPs(ieee))
- {
- bSupportNmode = true;
- bHalfSupportNmode = true;
- }
- else
- {
- bSupportNmode = false;
- bHalfSupportNmode = false;
- }
- printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
- }
- }
- /* Dummy wirless mode setting to avoid encryption issue */
- if(bSupportNmode) {
- //N mode setting
- ieee->SetWirelessMode(ieee->dev, \
- ieee->current_network.mode);
- }else{
- //b/g mode setting
- /*TODO*/
- ieee->SetWirelessMode(ieee->dev, IEEE_G);
- }
-
- if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
- {
- printk("===============>entern half N mode\n");
- ieee->bHalfWirelessN24GMode = true;
- }
- else
- ieee->bHalfWirelessN24GMode = false;
-
- ieee80211_associate_step2(ieee);
- }else{
- ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
- }
- }else{
- ieee->softmac_stats.rx_auth_rs_err++;
- IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
-
- printk("Authentication respose status code 0x%x",errcode);
- ieee80211_associate_abort(ieee);
- }
-
- }else if (ieee->iw_mode == IW_MODE_MASTER){
- ieee80211_rx_auth_rq(ieee, skb);
- }
- }
- break;
-
- case IEEE80211_STYPE_PROBE_REQ:
-
- if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
- ((ieee->iw_mode == IW_MODE_ADHOC ||
- ieee->iw_mode == IW_MODE_MASTER) &&
- ieee->state == IEEE80211_LINKED)){
- ieee80211_rx_probe_rq(ieee, skb);
- }
- break;
-
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- /* FIXME for now repeat all the association procedure
- * both for disassociation and deauthentication
- */
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->state == IEEE80211_LINKED &&
- ieee->iw_mode == IW_MODE_INFRA){
- printk("==========>received disassoc/deauth(%x) frame, reason code:%x\n",WLAN_FC_GET_STYPE(header->frame_control), ((struct ieee80211_disassoc*)skb->data)->reason);
- ieee->state = IEEE80211_ASSOCIATING;
- ieee->softmac_stats.reassoc++;
- ieee->is_roaming = true;
- ieee80211_disassociate(ieee);
- RemovePeerTS(ieee, header->addr2);
- if(ieee->LedControlHandler != NULL)
- ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK); //added by amy for LED 090318
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- }
- break;
- case IEEE80211_STYPE_MANAGE_ACT:
- ieee80211_process_action(ieee,skb);
- break;
- default:
- return -1;
- break;
- }
-
- return 0;
-}
-
-/* following are for a simplier TX queue management.
- * Instead of using netif_[stop/wake]_queue the driver
- * will uses these two function (plus a reset one), that
- * will internally uses the kernel netif_* and takes
- * care of the ieee802.11 fragmentation.
- * So the driver receives a fragment per time and might
- * call the stop function when it want without take care
- * to have enough room to TX an entire packet.
- * This might be useful if each fragment need it's own
- * descriptor, thus just keep a total free memory > than
- * the max fragmentation threshold is not enough.. If the
- * ieee802.11 stack passed a TXB struct then you needed
- * to keep N free descriptors where
- * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to
- * to the driver later, when it wakes the queue.
- */
-void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
-{
-
- unsigned int queue_index = txb->queue_index;
- unsigned long flags;
- int i;
- cb_desc *tcb_desc = NULL;
-
- spin_lock_irqsave(&ieee->lock,flags);
-
- /* called with 2nd parm 0, no tx mgmt lock required */
- ieee80211_sta_wakeup(ieee,0);
-
- /* update the tx status */
- ieee->stats.tx_bytes += txb->payload_size;
- ieee->stats.tx_packets++;
- tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
- if(tcb_desc->bMulticast) {
- ieee->stats.multicast++;
- }
-#if 1
- /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
- for(i = 0; i < txb->nr_frags; i++) {
- if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
- (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
- (ieee->queue_stop)) {
- /* insert the skb packet to the wait queue */
- /* as for the completion function, it does not need
- * to check it any more.
- * */
- skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
- }else{
- ieee->softmac_data_hard_start_xmit(
- txb->fragments[i],
- ieee->dev,ieee->rate);
- }
- }
-#endif
- ieee80211_txb_free(txb);
-
- spin_unlock_irqrestore(&ieee->lock,flags);
-
-}
-
-/* called with ieee->lock acquired */
-void ieee80211_resume_tx(struct ieee80211_device *ieee)
-{
- int i;
- for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
-
- if (ieee->queue_stop){
- ieee->tx_pending.frag = i;
- return;
- }else{
-
- ieee->softmac_data_hard_start_xmit(
- ieee->tx_pending.txb->fragments[i],
- ieee->dev,ieee->rate);
- ieee->stats.tx_packets++;
- }
- }
-
-
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
-}
-
-
-void ieee80211_reset_queue(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock,flags);
- init_mgmt_queue(ieee);
- if (ieee->tx_pending.txb){
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
- }
- ieee->queue_stop = 0;
- spin_unlock_irqrestore(&ieee->lock,flags);
-
-}
-
-void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
-{
-
- unsigned long flags;
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *header;
-
- spin_lock_irqsave(&ieee->lock,flags);
- if (! ieee->queue_stop) goto exit;
-
- ieee->queue_stop = 0;
-
- if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
- while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
-
- header = (struct ieee80211_hdr_3addr *) skb->data;
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
- }
- }
- if (!ieee->queue_stop && ieee->tx_pending.txb)
- ieee80211_resume_tx(ieee);
-
- if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
- ieee->softmac_stats.swtxawake++;
- netif_wake_queue(ieee->dev);
- }
-
-exit :
- spin_unlock_irqrestore(&ieee->lock,flags);
-}
-
-
-void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
-{
-
- if (! netif_queue_stopped(ieee->dev)){
- netif_stop_queue(ieee->dev);
- ieee->softmac_stats.swtxstop++;
- }
- ieee->queue_stop = 1;
-
-}
-
-
-inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
-{
-
- get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
-
- /* an IBSS cell address must have the two less significant
- * bits of the first byte = 2
- */
- ieee->current_network.bssid[0] &= ~0x01;
- ieee->current_network.bssid[0] |= 0x02;
-}
-
-/* called in user context only */
-void ieee80211_start_master_bss(struct ieee80211_device *ieee)
-{
- ieee->assoc_id = 1;
-
- if (ieee->current_network.ssid_len == 0){
- strncpy(ieee->current_network.ssid,
- IEEE80211_DEFAULT_TX_ESSID,
- IW_ESSID_MAX_SIZE);
-
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
-
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
- notify_wx_assoc_event(ieee);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
-}
-
-void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
-{
- if(ieee->raw_tx){
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-}
-
-void ieee80211_start_ibss_wq(struct work_struct *work)
-{
-
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
- /* iwconfig mode ad-hoc will schedule this and return
- * on the other hand this will block further iwconfig SET
- * operations because of the wx_sem hold.
- * Anyway some most set operations set a flag to speed-up
- * (abort) this wq (when syncro scanning) before sleeping
- * on the semaphore
- */
- if(!ieee->proto_started){
- printk("==========oh driver down return\n");
- return;
- }
- down(&ieee->wx_sem);
- //FIXME:set back to 20M whenever HT for ibss is not ready. Otherwise,after being connected to 40M AP, it will still stay in 40M when set to ibss mode. WB 2009.02.04
- HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
-
- if (ieee->current_network.ssid_len == 0){
- strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- /* check if we have this cell in our network list */
- ieee80211_softmac_check_all_nets(ieee);
-
-
-// if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
- if (ieee->state == IEEE80211_NOLINK)
- ieee->current_network.channel = ieee->IbssStartChnl;
- /* if not then the state is not linked. Maybe the user swithced to
- * ad-hoc mode just after being in monitor mode, or just after
- * being very few time in managed mode (so the card have had no
- * time to scan all the chans..) or we have just run up the iface
- * after setting ad-hoc mode. So we have to give another try..
- * Here, in ibss mode, should be safe to do this without extra care
- * (in bss mode we had to make sure no-one tryed to associate when
- * we had just checked the ieee->state and we was going to start the
- * scan) beacause in ibss mode the ieee80211_new_net function, when
- * finds a good net, just set the ieee->state to IEEE80211_LINKED,
- * so, at worst, we waste a bit of time to initiate an unneeded syncro
- * scan, that will stop at the first round because it sees the state
- * associated.
- */
- if (ieee->state == IEEE80211_NOLINK)
- ieee80211_start_scan_syncro(ieee);
-
- /* the network definitively is not here.. create a new cell */
- if (ieee->state == IEEE80211_NOLINK){
- printk("creating new IBSS cell\n");
- if(!ieee->wap_set)
- ieee80211_randomize_cell(ieee);
-
- if(ieee->modulation & IEEE80211_CCK_MODULATION){
-
- ieee->current_network.rates_len = 4;
-
- ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
- }else
- ieee->current_network.rates_len = 0;
-
- if(ieee->modulation & IEEE80211_OFDM_MODULATION){
- ieee->current_network.rates_ex_len = 8;
-
- ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- ieee->rate = 108;
- }else{
- ieee->current_network.rates_ex_len = 0;
- ieee->rate = 22;
- }
-
- // By default, WMM function will be disabled in IBSS mode
- ieee->current_network.QoS_Enable = 0;
- ieee->SetWirelessMode(ieee->dev, IEEE_G);
- ieee->current_network.atim_window = 0;
- ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
- if(ieee->short_slot)
- ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
-
- }
-
- ieee->state = IEEE80211_LINKED;
-
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->link_change(ieee->dev);
- if(ieee->LedControlHandler != NULL)
- ieee->LedControlHandler(ieee->dev,LED_CTL_LINK);
- notify_wx_assoc_event(ieee);
-
- ieee80211_start_send_beacons(ieee);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
- netif_carrier_on(ieee->dev);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
-{
- queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
-}
-
-/* this is called only in user context, with wx_sem held */
-void ieee80211_start_bss(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- //
- // Ref: 802.11d 11.1.3.3
- // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
- //
- if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
- {
- if(! ieee->bGlobalDomain)
- {
- return;
- }
- }
- /* check if we have already found the net we
- * are interested in (if any).
- * if not (we are disassociated and we are not
- * in associating / authenticating phase) start the background scanning.
- */
- ieee80211_softmac_check_all_nets(ieee);
-
- /* ensure no-one start an associating process (thus setting
- * the ieee->state to ieee80211_ASSOCIATING) while we
- * have just cheked it and we are going to enable scan.
- * The ieee80211_new_net function is always called with
- * lock held (from both ieee80211_softmac_check_all_nets and
- * the rx path), so we cannot be in the middle of such function
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state == IEEE80211_NOLINK){
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_link_change_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, link_change_wq);
-
- ieee->link_change(ieee->dev);
-}
-/* called only in userspace context */
-void ieee80211_disassociate(struct ieee80211_device *ieee)
-{
-
-
- netif_carrier_off(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
- ieee80211_reset_queue(ieee);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
- if(IS_DOT11D_ENABLE(ieee))
- Dot11d_Reset(ieee);
- ieee->state = IEEE80211_NOLINK;
- ieee->is_set_key = false;
-
- queue_delayed_work(ieee->wq, &ieee->link_change_wq, 0);
-
-
- notify_wx_assoc_event(ieee);
-
-}
-
-void ieee80211_associate_retry_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
- unsigned long flags;
-
- down(&ieee->wx_sem);
- if(!ieee->proto_started)
- goto exit;
-
- if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
- goto exit;
-
- /* until we do not set the state to IEEE80211_NOLINK
- * there are no possibility to have someone else trying
- * to start an association procdure (we get here with
- * ieee->state = IEEE80211_ASSOCIATING).
- * When we set the state to IEEE80211_NOLINK it is possible
- * that the RX path run an attempt to associate, but
- * both ieee80211_softmac_check_all_nets and the
- * RX path works with ieee->lock held so there are no
- * problems. If we are still disassociated then start a scan.
- * the lock here is necessary to ensure no one try to start
- * an association procedure when we have just checked the
- * state and we are going to start the scan.
- */
- ieee->beinretry = true;
- ieee->state = IEEE80211_NOLINK;
-
- ieee80211_softmac_check_all_nets(ieee);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if(ieee->state == IEEE80211_NOLINK)
- {
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- ieee->beinretry = false;
-exit:
- up(&ieee->wx_sem);
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
-{
- u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
-
- struct sk_buff *skb;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_probe_resp(ieee, broadcast_addr);
-
- if (!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON);
-
- return skb;
-
-}
-
-struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_get_beacon_(ieee);
- if(!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- return skb;
-}
-
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
- ieee80211_stop_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
-{
- if (!ieee->proto_started)
- return;
-
- ieee->proto_started = 0;
-
- ieee80211_stop_send_beacons(ieee);
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
- cancel_delayed_work(&ieee->start_ibss_wq);
- cancel_delayed_work(&ieee->link_change_wq);
- ieee80211_stop_scan(ieee);
-
- ieee80211_disassociate(ieee);
- RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
-}
-
-void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 0;
- down(&ieee->wx_sem);
- ieee80211_start_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-void ieee80211_start_protocol(struct ieee80211_device *ieee)
-{
- short ch = 0;
- int i = 0;
- if (ieee->proto_started)
- return;
-
- ieee->proto_started = 1;
-
- if (ieee->current_network.channel == 0){
- do{
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- return; /* no channel found */
- }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
- ieee->current_network.channel = ch;
- }
-
- if (ieee->current_network.beacon_interval == 0)
- ieee->current_network.beacon_interval = 100;
-
- for(i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
- ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
-
-
- /* if the user set the MAC of the ad-hoc cell and then
- * switch to managed mode, shall we make sure that association
- * attempts does not fail just because the user provide the essid
- * and the nic is still checking for the AP MAC ??
- */
- if (ieee->iw_mode == IW_MODE_INFRA)
- ieee80211_start_bss(ieee);
-
- else if (ieee->iw_mode == IW_MODE_ADHOC)
- ieee80211_start_ibss(ieee);
-
- else if (ieee->iw_mode == IW_MODE_MASTER)
- ieee80211_start_master_bss(ieee);
-
- else if(ieee->iw_mode == IW_MODE_MONITOR)
- ieee80211_start_monitor_mode(ieee);
-}
-
-
-#define DRV_NAME "Ieee80211"
-void ieee80211_softmac_init(struct ieee80211_device *ieee)
-{
- int i;
- memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
-
- ieee->state = IEEE80211_NOLINK;
- ieee->sync_scan_hurryup = 0;
- for(i = 0; i < 5; i++) {
- ieee->seq_ctrl[i] = 0;
- }
- ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
- if (!ieee->pDot11dInfo)
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
- //added for AP roaming
- ieee->LinkDetectInfo.SlotNum = 2;
- ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
- ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
-
- ieee->assoc_id = 0;
- ieee->queue_stop = 0;
- ieee->scanning = 0;
- ieee->softmac_features = 0; //so IEEE2100-like driver are happy
- ieee->wap_set = 0;
- ieee->ssid_set = 0;
- ieee->proto_started = 0;
- ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
- ieee->rate = 22;
- ieee->ps = IEEE80211_PS_DISABLED;
- ieee->sta_sleep = 0;
- ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
- ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
- ieee->Regdot11HTOperationalRateSet[4]= 0x01;
- ieee->actscanning = false;
- ieee->beinretry = false;
- ieee->is_set_key = false;
- init_mgmt_queue(ieee);
-
- ieee->sta_edca_param[0] = 0x0000A403;
- ieee->sta_edca_param[1] = 0x0000A427;
- ieee->sta_edca_param[2] = 0x005E4342;
- ieee->sta_edca_param[3] = 0x002F3262;
- ieee->aggregation = true;
- ieee->enable_rx_imm_BA = 1;
- ieee->tx_pending.txb = NULL;
-
- init_timer(&ieee->associate_timer);
- ieee->associate_timer.data = (unsigned long)ieee;
- ieee->associate_timer.function = ieee80211_associate_abort_cb;
-
- init_timer(&ieee->beacon_timer);
- ieee->beacon_timer.data = (unsigned long) ieee;
- ieee->beacon_timer.function = ieee80211_send_beacon_cb;
-
-#ifdef PF_SYNCTHREAD
- ieee->wq = create_workqueue(DRV_NAME,0);
-#else
- ieee->wq = create_workqueue(DRV_NAME);
-#endif
-
- INIT_DELAYED_WORK(&ieee->link_change_wq,ieee80211_link_change_wq);
- INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
- INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
- INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
- INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
- INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
- INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
-
- sema_init(&ieee->wx_sem, 1);
- sema_init(&ieee->scan_sem, 1);
-
- spin_lock_init(&ieee->mgmt_tx_lock);
- spin_lock_init(&ieee->beacon_lock);
-
- tasklet_init(&ieee->ps_task,
- (void(*)(unsigned long)) ieee80211_sta_ps,
- (unsigned long)ieee);
-
-}
-
-void ieee80211_softmac_free(struct ieee80211_device *ieee)
-{
- down(&ieee->wx_sem);
- if(NULL != ieee->pDot11dInfo)
- {
- kfree(ieee->pDot11dInfo);
- ieee->pDot11dInfo = NULL;
- }
- del_timer_sync(&ieee->associate_timer);
-
- cancel_delayed_work(&ieee->associate_retry_wq);
- destroy_workqueue(ieee->wq);
-
- up(&ieee->wx_sem);
-}
-
-/********************************************************
- * Start of WPA code. *
- * this is stolen from the ipw2200 driver *
- ********************************************************/
-
-
-static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
-{
- /* This is called when wpa_supplicant loads and closes the driver
- * interface. */
- printk("%s WPA\n",value ? "enabling" : "disabling");
- ieee->wpa_enabled = value;
- memset(ieee->ap_mac_addr, 0, 6); //reset ap_mac_addr everytime it starts wpa.
- return 0;
-}
-
-
-void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
-{
- /* make sure WPA is enabled */
- ieee80211_wpa_enable(ieee, 1);
-
- ieee80211_disassociate(ieee);
-}
-
-
-static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
-{
-
- int ret = 0;
-
- switch (command) {
- case IEEE_MLME_STA_DEAUTH:
- // silently ignore
- break;
-
- case IEEE_MLME_STA_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
-
- default:
- printk("Unknown MLME request: %d\n", command);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-
-static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
- struct ieee_param *param, int plen)
-{
- u8 *buf;
-
- if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
- (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
- return -EINVAL;
-
- if (param->u.wpa_ie.len) {
- buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
- GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = param->u.wpa_ie.len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
- return 0;
-}
-
-#define AUTH_ALG_OPEN_SYSTEM 0x1
-#define AUTH_ALG_SHARED_KEY 0x2
-#define AUTH_ALG_LEAP 0x4
-static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
-{
-
- struct ieee80211_security sec = {
- .flags = SEC_AUTH_MODE,
- };
- int ret = 0;
-
- if (value & AUTH_ALG_SHARED_KEY) {
- sec.auth_mode = WLAN_AUTH_SHARED_KEY;
- ieee->open_wep = 0;
- ieee->auth_mode = 1;
- } else if (value & AUTH_ALG_OPEN_SYSTEM){
- sec.auth_mode = WLAN_AUTH_OPEN;
- ieee->open_wep = 1;
- ieee->auth_mode = 0;
- }
- else if (value & AUTH_ALG_LEAP){
- sec.auth_mode = RTL_WLAN_AUTH_LEAP;
- ieee->open_wep = 1;
- ieee->auth_mode = 2;
- }
-
-
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- return ret;
-}
-
-static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
-{
- int ret=0;
- unsigned long flags;
-
- switch (name) {
- case IEEE_PARAM_WPA_ENABLED:
- ret = ieee80211_wpa_enable(ieee, value);
- break;
-
- case IEEE_PARAM_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures=value;
- break;
-
- case IEEE_PARAM_DROP_UNENCRYPTED: {
- /* HACK:
- *
- * wpa_supplicant calls set_wpa_enabled when the driver
- * is loaded and unloaded, regardless of if WPA is being
- * used. No other calls are made which can be used to
- * determine if encryption will be used or not prior to
- * association being expected. If encryption is not being
- * used, drop_unencrypted is set to false, else true -- we
- * can use this to determine if the CAP_PRIVACY_ON bit should
- * be set.
- */
- struct ieee80211_security sec = {
- .flags = SEC_ENABLED,
- .enabled = value,
- };
- ieee->drop_unencrypted = value;
- /* We only change SEC_LEVEL for open mode. Others
- * are set by ipw_wpa_set_encryption.
- */
- if (!value) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_0;
- }
- else {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- }
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- break;
- }
-
- case IEEE_PARAM_PRIVACY_INVOKED:
- ieee->privacy_invoked=value;
- break;
-
- case IEEE_PARAM_AUTH_ALGS:
- ret = ieee80211_wpa_set_auth_algs(ieee, value);
- break;
-
- case IEEE_PARAM_IEEE_802_1X:
- ieee->ieee802_1x=value;
- break;
- case IEEE_PARAM_WPAX_SELECT:
- // added for WPA2 mixed mode
- spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
- ieee->wpax_type_set = 1;
- ieee->wpax_type_notify = value;
- spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
- break;
-
- default:
- printk("Unknown WPA param: %d\n",name);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
- struct ieee_param *param, int param_len)
-{
- int ret = 0;
-
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
-
- param->u.crypt.err = 0;
- param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
- if (param_len !=
- (int) ((char *) param->u.crypt.key - (char *) param) +
- param->u.crypt.key_len) {
- printk("Len mismatch %d, %d\n", param_len,
- param->u.crypt.key_len);
- return -EINVAL;
- }
- if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
- param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
- if (param->u.crypt.idx >= WEP_KEYS)
- return -EINVAL;
- crypt = &ieee->crypt[param->u.crypt.idx];
- } else {
- return -EINVAL;
- }
-
- if (strcmp(param->u.crypt.alg, "none") == 0) {
- if (crypt) {
- sec.enabled = 0;
- // FIXME FIXME
- //sec.encrypt = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
- goto done;
- }
- sec.enabled = 1;
-// FIXME FIXME
-// sec.encrypt = 1;
- sec.flags |= SEC_ENABLED;
-
- /* IPW HW cannot build TKIP MIC, host decryption still needed. */
- if (!(ieee->host_encrypt || ieee->host_decrypt) &&
- strcmp(param->u.crypt.alg, "TKIP"))
- goto skip_host_crypt;
-
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- /* set WEP40 first, it will be modified according to WEP104 or
- * WEP40 at other place */
- else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL) {
- printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
- param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
- new_crypt->ops = ops;
-
- if (new_crypt->ops)
- new_crypt->priv =
- new_crypt->ops->init(param->u.crypt.idx);
-
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- *crypt = new_crypt;
- }
-
- if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(param->u.crypt.key,
- param->u.crypt.key_len, param->u.crypt.seq,
- (*crypt)->priv) < 0) {
- printk("key setting failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- skip_host_crypt:
- if (param->u.crypt.set_tx) {
- ieee->tx_keyidx = param->u.crypt.idx;
- sec.active_key = param->u.crypt.idx;
- sec.flags |= SEC_ACTIVE_KEY;
- } else
- sec.flags &= ~SEC_ACTIVE_KEY;
-
- if (param->u.crypt.alg != NULL) {
- memcpy(sec.keys[param->u.crypt.idx],
- param->u.crypt.key,
- param->u.crypt.key_len);
- sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
- sec.flags |= (1 << param->u.crypt.idx);
-
- if (strcmp(param->u.crypt.alg, "WEP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- }
- done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack. */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port &&
- ieee->reset_port(ieee->dev)) {
- printk("reset_port failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
- return -EINVAL;
- }
-
- return ret;
-}
-
-inline struct sk_buff *ieee80211_disassociate_skb(
- struct ieee80211_network *beacon,
- struct ieee80211_device *ieee,
- u8 asRsn)
-{
- struct sk_buff *skb;
- struct ieee80211_disassoc *disass;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
- if (!skb)
- return NULL;
-
- disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
- disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
- disass->header.duration_id = 0;
-
- memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
-
- disass->reason = asRsn;
- return skb;
-}
-
-
-void
-SendDisassociation(
- struct ieee80211_device *ieee,
- u8* asSta,
- u8 asRsn
-)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
- skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
- if (skb){
- softmac_mgmt_xmit(skb, ieee);
- //dev_kfree_skb_any(skb);//edit by thomas
- }
-}
-
-int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
-{
- struct ieee_param *param;
- int ret=0;
-
- down(&ieee->wx_sem);
-
- if (p->length < sizeof(struct ieee_param) || !p->pointer){
- ret = -EINVAL;
- goto out;
- }
-
- param = kmalloc(p->length, GFP_KERNEL);
- if (param == NULL){
- ret = -ENOMEM;
- goto out;
- }
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- ret = -EFAULT;
- goto out;
- }
-
- switch (param->cmd) {
-
- case IEEE_CMD_SET_WPA_PARAM:
- ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
- param->u.wpa_param.value);
- break;
-
- case IEEE_CMD_SET_WPA_IE:
- ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
- break;
-
- case IEEE_CMD_SET_ENCRYPTION:
- ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
- break;
-
- case IEEE_CMD_MLME:
- ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
- param->u.mlme.reason_code);
- break;
-
- default:
- printk("Unknown WPA supplicant request: %d\n",param->cmd);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-out:
- up(&ieee->wx_sem);
-
- return ret;
-}
-
-void notify_wx_assoc_event(struct ieee80211_device *ieee)
-{
- union iwreq_data wrqu;
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- if (ieee->state == IEEE80211_LINKED)
- memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
- else
- memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
- wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
deleted file mode 100644
index 9ded253e1f9a..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Some pieces of code might be stolen from ipw2100 driver
- * copyright of who own it's copyright ;-)
- *
- * PS wx handler mostly stolen from hostap, copyright who
- * own it's copyright ;-)
- *
- * released under the GPL
- */
-
-
-#include "ieee80211.h"
-#include "dot11d.h"
-/* FIXME: add A freqs */
-
-const long ieee80211_wlan_frequencies[] = {
- 2412, 2417, 2422, 2427,
- 2432, 2437, 2442, 2447,
- 2452, 2457, 2462, 2467,
- 2472, 2484
-};
-
-
-int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct iw_freq *fwrq = & wrqu->freq;
-
- down(&ieee->wx_sem);
-
- if(ieee->iw_mode == IW_MODE_INFRA){
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- /* if setting by freq convert to channel */
- if (fwrq->e == 1) {
- if ((fwrq->m >= (int) 2.412e8 &&
- fwrq->m <= (int) 2.487e8)) {
- int f = fwrq->m / 100000;
- int c = 0;
-
- while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
- c++;
-
- /* hack to fall through */
- fwrq->e = 0;
- fwrq->m = c + 1;
- }
- }
-
- if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
- ret = -EOPNOTSUPP;
- goto out;
-
- }else { /* Set the channel */
-
- if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
- ret = -EINVAL;
- goto out;
- }
- ieee->current_network.channel = fwrq->m;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- if(ieee->state == IEEE80211_LINKED){
-
- ieee80211_stop_send_beacons(ieee);
- ieee80211_start_send_beacons(ieee);
- }
- }
-
- ret = 0;
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-
-int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct iw_freq *fwrq = & wrqu->freq;
-
- if (ieee->current_network.channel == 0)
- return -1;
- //NM 0.7.0 will not accept channel any more.
- fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000;
- fwrq->e = 1;
-// fwrq->m = ieee->current_network.channel;
-// fwrq->e = 0;
-
- return 0;
-}
-
-int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- unsigned long flags;
-
- wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->wap_set == 0)
-
- memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
- else
- memcpy(wrqu->ap_addr.sa_data,
- ieee->current_network.bssid, ETH_ALEN);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return 0;
-}
-
-
-int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra)
-{
-
- int ret = 0;
- u8 zero[] = {0,0,0,0,0,0};
- unsigned long flags;
-
- short ifup = ieee->proto_started;//dev->flags & IFF_UP;
- struct sockaddr *temp = (struct sockaddr *)awrq;
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
- /* use ifconfig hw ether */
- if (ieee->iw_mode == IW_MODE_MASTER){
- ret = -1;
- goto out;
- }
-
- if (temp->sa_family != ARPHRD_ETHER){
- ret = -EINVAL;
- goto out;
- }
-
- if (ifup)
- ieee80211_stop_protocol(ieee);
-
- /* just to avoid to give inconsistent infos in the
- * get wx method. not really needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
- ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (ifup)
- ieee80211_start_protocol(ieee);
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
- int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
-{
- int len,ret = 0;
- unsigned long flags;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->current_network.ssid[0] == '\0' ||
- ieee->current_network.ssid_len == 0){
- ret = -1;
- goto out;
- }
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->ssid_set == 0){
- ret = -1;
- goto out;
- }
- len = ieee->current_network.ssid_len;
- wrqu->essid.length = len;
- strncpy(b,ieee->current_network.ssid,len);
- wrqu->essid.flags = 1;
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return ret;
-
-}
-
-int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- u32 target_rate = wrqu->bitrate.value;
-
- ieee->rate = target_rate/100000;
- //FIXME: we might want to limit rate also in management protocols.
- return 0;
-}
-
-
-
-int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- u32 tmp_rate = 0;
- //printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode);
- if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
- tmp_rate = ieee->rate;
- else if (ieee->mode & IEEE_N_5G)
- tmp_rate = 580;
- else if (ieee->mode & IEEE_N_24G)
- {
- if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
- tmp_rate = HTHalfMcsToDataRate(ieee, 15);
- else
- tmp_rate = HTMcsToDataRate(ieee, 15);
- }
- wrqu->bitrate.value = tmp_rate * 500000;
-
- return 0;
-}
-
-
-int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- if (wrqu->rts.disabled || !wrqu->rts.fixed)
- ieee->rts = DEFAULT_RTS_THRESHOLD;
- else
- {
- if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
- wrqu->rts.value > MAX_RTS_THRESHOLD)
- return -EINVAL;
- ieee->rts = wrqu->rts.value;
- }
- return 0;
-}
-
-int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- wrqu->rts.value = ieee->rts;
- wrqu->rts.fixed = 0; /* no auto select */
- wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
- return 0;
-}
-int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
-
- if (wrqu->mode == ieee->iw_mode)
- goto out;
-
- if (wrqu->mode == IW_MODE_MONITOR){
-
- ieee->dev->type = ARPHRD_IEEE80211;
- }else{
- ieee->dev->type = ARPHRD_ETHER;
- }
-
- if (!ieee->proto_started){
- ieee->iw_mode = wrqu->mode;
- }else{
- ieee80211_stop_protocol(ieee);
- ieee->iw_mode = wrqu->mode;
- ieee80211_start_protocol(ieee);
- }
-
-out:
- up(&ieee->wx_sem);
- return 0;
-}
-
-void ieee80211_wx_sync_scan_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
- short chan;
- HT_EXTCHNL_OFFSET chan_offset=0;
- HT_CHANNEL_WIDTH bandwidth=0;
- int b40M = 0;
- static int count = 0;
- chan = ieee->current_network.channel;
- netif_carrier_off(ieee->dev);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_send_beacons(ieee);
-
- ieee->state = IEEE80211_LINKED_SCANNING;
- ieee->link_change(ieee->dev);
- ieee->InitialGainHandler(ieee->dev,IG_Backup);
- if (ieee->SetFwCmdHandler)
- {
- ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_HALT);
- ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_DISABLE);
- }
- if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
- b40M = 1;
- chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
- bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
- printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
- ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
- }
- ieee80211_start_scan_syncro(ieee);
- if (b40M) {
- printk("Scan in 20M, back to 40M\n");
- if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
- ieee->set_chan(ieee->dev, chan + 2);
- else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
- ieee->set_chan(ieee->dev, chan - 2);
- else
- ieee->set_chan(ieee->dev, chan);
- ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
- } else {
- ieee->set_chan(ieee->dev, chan);
- }
-
- ieee->InitialGainHandler(ieee->dev,IG_Restore);
- if (ieee->SetFwCmdHandler)
- {
- ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_RESUME);
- ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_ENABLE);
- }
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
- // To prevent the immediately calling watch_dog after scan.
- if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
- {
- ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
- ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
- }
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- ieee80211_start_send_beacons(ieee);
-
- netif_carrier_on(ieee->dev);
- count = 0;
- up(&ieee->wx_sem);
-
-}
-
-int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
- ret = -1;
- goto out;
- }
-
- if ( ieee->state == IEEE80211_LINKED){
- queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
- /* intentionally forget to up sem */
- return 0;
- }
-
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra)
-{
-
- int ret=0,len;
- short proto_started;
- unsigned long flags;
-
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
-
- proto_started = ieee->proto_started;
-
- if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
- ret= -E2BIG;
- goto out;
- }
-
- if (ieee->iw_mode == IW_MODE_MONITOR){
- ret= -1;
- goto out;
- }
-
- if(proto_started)
- ieee80211_stop_protocol(ieee);
-
-
- /* this is just to be sure that the GET wx callback
- * has consisten infos. not needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (wrqu->essid.flags && wrqu->essid.length) {
- //first flush current network.ssid
- len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
- strncpy(ieee->current_network.ssid, extra, len+1);
- ieee->current_network.ssid_len = len+1;
- ieee->ssid_set = 1;
- }
- else{
- ieee->ssid_set = 0;
- ieee->current_network.ssid[0] = '\0';
- ieee->current_network.ssid_len = 0;
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (proto_started)
- ieee80211_start_protocol(ieee);
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
- int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
-
- wrqu->mode = ieee->iw_mode;
- return 0;
-}
-
- int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = ieee->raw_tx;
-
- down(&ieee->wx_sem);
-
- if(enable)
- ieee->raw_tx = 1;
- else
- ieee->raw_tx = 0;
-
- printk(KERN_INFO"raw TX is %s\n",
- ieee->raw_tx ? "enabled" : "disabled");
-
- if(ieee->iw_mode == IW_MODE_MONITOR)
- {
- if(prev == 0 && ieee->raw_tx){
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-
- if(prev && ieee->raw_tx == 1)
- netif_carrier_off(ieee->dev);
- }
-
- up(&ieee->wx_sem);
-
- return 0;
-}
-
-int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- strlcpy(wrqu->name, "802.11", IFNAMSIZ);
- if(ieee->modulation & IEEE80211_CCK_MODULATION){
- strlcat(wrqu->name, "b", IFNAMSIZ);
- if(ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "/g", IFNAMSIZ);
- }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "g", IFNAMSIZ);
- if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
- strlcat(wrqu->name, "/n", IFNAMSIZ);
-
- if((ieee->state == IEEE80211_LINKED) ||
- (ieee->state == IEEE80211_LINKED_SCANNING))
- strlcat(wrqu->name, " link", IFNAMSIZ);
- else if(ieee->state != IEEE80211_NOLINK)
- strlcat(wrqu->name, " .....", IFNAMSIZ);
-
-
- return 0;
-}
-
-
-/* this is mostly stolen from hostap */
-int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-#if 1
- if(
- (!ieee->sta_wake_up) ||
- // (!ieee->ps_request_tx_ack) ||
- (!ieee->enter_sleep_state) ||
- (!ieee->ps_is_queue_empty)){
-
- // printk("ERROR. PS mode is tryied to be use but driver missed a callback\n\n");
-
- return -1;
- }
-#endif
- down(&ieee->wx_sem);
-
- if (wrqu->power.disabled){
- ieee->ps = IEEE80211_PS_DISABLED;
- goto exit;
- }
- if (wrqu->power.flags & IW_POWER_TIMEOUT) {
- //ieee->ps_period = wrqu->power.value / 1000;
- ieee->ps_timeout = wrqu->power.value / 1000;
- }
-
- if (wrqu->power.flags & IW_POWER_PERIOD) {
-
- //ieee->ps_timeout = wrqu->power.value / 1000;
- ieee->ps_period = wrqu->power.value / 1000;
- //wrq->value / 1024;
-
- }
- switch (wrqu->power.flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- ieee->ps = IEEE80211_PS_UNICAST;
- break;
- case IW_POWER_MULTICAST_R:
- ieee->ps = IEEE80211_PS_MBCAST;
- break;
- case IW_POWER_ALL_R:
- ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
- break;
-
- case IW_POWER_ON:
- // ieee->ps = IEEE80211_PS_DISABLED;
- break;
-
- default:
- ret = -EINVAL;
- goto exit;
-
- }
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
-
-/* this is stolen from hostap */
-int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret =0;
-
- down(&ieee->wx_sem);
-
- if(ieee->ps == IEEE80211_PS_DISABLED){
- wrqu->power.disabled = 1;
- goto exit;
- }
-
- wrqu->power.disabled = 0;
-
- if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrqu->power.flags = IW_POWER_TIMEOUT;
- wrqu->power.value = ieee->ps_timeout * 1000;
- } else {
-// ret = -EOPNOTSUPP;
-// goto exit;
- wrqu->power.flags = IW_POWER_PERIOD;
- wrqu->power.value = ieee->ps_period * 1000;
-//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024;
- }
-
- if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
- wrqu->power.flags |= IW_POWER_ALL_R;
- else if (ieee->ps & IEEE80211_PS_MBCAST)
- wrqu->power.flags |= IW_POWER_MULTICAST_R;
- else
- wrqu->power.flags |= IW_POWER_UNICAST_R;
-
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
deleted file mode 100644
index a6a5d68df3aa..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ /dev/null
@@ -1,916 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2003 - 2004 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************
-
- Few modifications for Realtek's Wi-Fi drivers by
- Andrea Merello <andreamrl@tiscali.it>
-
- A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/if_vlan.h>
-
-#include "ieee80211.h"
-
-
-/*
-
-
-802.11 Data Frame
-
-
-802.11 frame_contorl for data frames - 2 bytes
- ,-----------------------------------------------------------------------------------------.
-bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
- | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
- '-----------------------------------------------------------------------------------------'
- /\
- |
-802.11 Data Frame |
- ,--------- 'ctrl' expands to >-----------'
- |
- ,--'---,-------------------------------------------------------------.
-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 non-data bytes `----.----'
- |
- .- 'Frame data' expands to <---------------------------'
- |
- V
- ,---------------------------------------------------.
-Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- |------|------|---------|----------|------|---------|
-Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- | DSAP | SSAP | | | | Packet |
- | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- `-----------------------------------------| |
-Total: 8 non-data bytes `----.----'
- |
- .- 'IP Packet' expands, if WEP enabled, to <--'
- |
- V
- ,-----------------------.
-Bytes | 4 | 0-2296 | 4 |
- |-----|-----------|-----|
-Desc. | IV | Encrypted | ICV |
- | | IP Packet | |
- `-----------------------'
-Total: 8 non-data bytes
-
-
-802.3 Ethernet Data Frame
-
- ,-----------------------------------------.
-Bytes | 6 | 6 | 2 | Variable | 4 |
- |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet | fcs |
- | MAC | MAC | | | |
- `-----------------------------------------'
-Total: 18 non-data bytes
-
-In the event that fragmentation is required, the incoming payload is split into
-N parts of size ieee->fts. The first fragment contains the SNAP header and the
-remaining packets are just data.
-
-If encryption is enabled, each fragment payload size is reduced by enough space
-to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
-So if you have 1500 bytes of payload with ieee->fts set to 500 without
-encryption it will take 3 frames. With WEP it will take 4 frames as the
-payload of each frame is reduced to 492 bytes.
-
-* SKB visualization
-*
-* ,- skb->data
-* |
-* | ETHERNET HEADER ,-<-- PAYLOAD
-* | | 14 bytes from skb->data
-* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
-* | | | |
-* |,-Dest.--. ,--Src.---. | | |
-* | 6 bytes| | 6 bytes | | | |
-* v | | | | | |
-* 0 | v 1 | v | v 2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-* ^ | ^ | ^ |
-* | | | | | |
-* | | | | `T' <---- 2 bytes for Type
-* | | | |
-* | | '---SNAP--' <-------- 6 bytes for SNAP
-* | |
-* `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-* SNAP HEADER
-*
-*/
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
- struct ieee80211_snap_hdr *snap;
- u8 *oui;
-
- snap = (struct ieee80211_snap_hdr *)data;
- snap->dsap = 0xaa;
- snap->ssap = 0xaa;
- snap->ctrl = 0x03;
-
- if (h_proto == 0x8137 || h_proto == 0x80f3)
- oui = P802_1H_OUI;
- else
- oui = RFC1042_OUI;
- snap->oui[0] = oui[0];
- snap->oui[1] = oui[1];
- snap->oui[2] = oui[2];
-
- *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
- return SNAP_SIZE + sizeof(u16);
-}
-
-int ieee80211_encrypt_fragment(
- struct ieee80211_device *ieee,
- struct sk_buff *frag,
- int hdr_len)
-{
- struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
- int res;
-
- if (!(crypt && crypt->ops))
- {
- printk("=========>%s(), crypt is null\n", __FUNCTION__);
- return -1;
- }
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct rtl_ieee80211_hdr *header;
-
- if (ieee->tkip_countermeasures &&
- crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct rtl_ieee80211_hdr *)frag->data;
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- "TX packet to %pM\n",
- ieee->dev->name, header->addr1);
- }
- return -1;
- }
-#endif
- /* To encrypt, frame format is:
- * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
-
- /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here. */
- atomic_inc(&crypt->refcnt);
- res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
- res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
- ieee->dev->name, frag->len);
- ieee->ieee_stats.tx_discards++;
- return -1;
- }
-
- return 0;
-}
-
-
-void ieee80211_txb_free(struct ieee80211_txb *txb) {
- if (unlikely(!txb))
- return;
- kfree(txb);
-}
-
-struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- int gfp_mask)
-{
- struct ieee80211_txb *txb;
- int i;
- txb = kmalloc(
- sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
- gfp_mask);
- if (!txb)
- return NULL;
-
- memset(txb, 0, sizeof(struct ieee80211_txb));
- txb->nr_frags = nr_frags;
- txb->frag_size = txb_size;
-
- for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
- if (unlikely(!txb->fragments[i])) {
- i--;
- break;
- }
- memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
- }
- if (unlikely(i != nr_frags)) {
- while (i >= 0)
- dev_kfree_skb_any(txb->fragments[i--]);
- kfree(txb);
- return NULL;
- }
- return txb;
-}
-
-// Classify the to-be send data packet
-// Need to acquire the sent queue index.
-static int
-ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
-{
- struct ethhdr *eth;
- struct iphdr *ip;
- eth = (struct ethhdr *)skb->data;
- if (eth->h_proto != htons(ETH_P_IP))
- return 0;
-
- ip = ip_hdr(skb);
-
- switch (ip->tos & 0xfc) {
- case 0x20:
- return 2;
- case 0x40:
- return 1;
- case 0x60:
- return 3;
- case 0x80:
- return 4;
- case 0xa0:
- return 5;
- case 0xc0:
- return 6;
- case 0xe0:
- return 7;
- default:
- return 0;
- }
-}
-
-void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- PTX_TS_RECORD pTxTs = NULL;
- struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
-
- if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
- return;
- if (!IsQoSDataFrame(skb->data))
- return;
-
- if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
- return;
- //check packet and mode later
-#ifdef TO_DO_LIST
- if(pTcb->PacketLength >= 4096)
- return;
- // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
- if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
- return;
-#endif
-
- if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
- return;
-
-#if 1
- if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
- {
- return;
- }
-#endif
- if(pHTInfo->bCurrentAMPDUEnable)
- {
- if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
- {
- printk("===>can't get TS\n");
- return;
- }
- if (pTxTs->TxAdmittedBARecord.bValid == false)
- {
- //as some AP will refuse our action frame until key handshake has been finished. WB
- if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
- ;
- else
- TsStartAddBaProcess(ieee, pTxTs);
- goto FORCED_AGG_SETTING;
- }
- else if (pTxTs->bUsingBa == false)
- {
- if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
- pTxTs->bUsingBa = true;
- else
- goto FORCED_AGG_SETTING;
- }
-
- if (ieee->iw_mode == IW_MODE_INFRA)
- {
- tcb_desc->bAMPDUEnable = true;
- tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
- tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
- }
- }
-FORCED_AGG_SETTING:
- switch(pHTInfo->ForcedAMPDUMode )
- {
- case HT_AGG_AUTO:
- break;
-
- case HT_AGG_FORCE_ENABLE:
- tcb_desc->bAMPDUEnable = true;
- tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
- tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
- break;
-
- case HT_AGG_FORCE_DISABLE:
- tcb_desc->bAMPDUEnable = false;
- tcb_desc->ampdu_density = 0;
- tcb_desc->ampdu_factor = 0;
- break;
-
- }
- return;
-}
-
-extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
-{
- tcb_desc->bUseShortPreamble = false;
- if (tcb_desc->data_rate == 2)
- {//// 1M can only use Long Preamble. 11B spec
- return;
- }
- else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- {
- tcb_desc->bUseShortPreamble = true;
- }
- return;
-}
-extern void
-ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- tcb_desc->bUseShortGI = false;
-
- if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
- return;
-
- if(pHTInfo->bForcedShortGI)
- {
- tcb_desc->bUseShortGI = true;
- return;
- }
-
- if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
- tcb_desc->bUseShortGI = true;
- else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
- tcb_desc->bUseShortGI = true;
-}
-
-void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- tcb_desc->bPacketBW = false;
-
- if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
- return;
-
- if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
- return;
-
- if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
- return;
- //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
- if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
- tcb_desc->bPacketBW = true;
- return;
-}
-
-void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
-{
- // Common Settings
- tcb_desc->bRTSSTBC = false;
- tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
- tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
- tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
- tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
-
- if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
- return;
-
- if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
- return;
-
- if (ieee->mode < IEEE_N_24G) //b, g mode
- {
- // (1) RTS_Threshold is compared to the MPDU, not MSDU.
- // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
- // Other fragments are protected by previous fragment.
- // So we only need to check the length of first fragment.
- if (skb->len > ieee->rts)
- {
- tcb_desc->bRTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- }
- else if (ieee->current_network.buseprotection)
- {
- // Use CTS-to-SELF in protection mode.
- tcb_desc->bRTSEnable = true;
- tcb_desc->bCTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- }
- //otherwise return;
- return;
- }
- else
- {// 11n High throughput case.
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- while (true)
- {
- //check IOT action
- if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
- {
- tcb_desc->bCTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->bRTSEnable = false;
- break;
- }
- else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
- {
- tcb_desc->bRTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- break;
- }
- //check ERP protection
- if (ieee->current_network.buseprotection)
- {// CTS-to-SELF
- tcb_desc->bRTSEnable = true;
- tcb_desc->bCTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- break;
- }
- //check HT op mode
- if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
- {
- u8 HTOpMode = pHTInfo->CurrentOpMode;
- if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
- (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
- {
- tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
- tcb_desc->bRTSEnable = true;
- break;
- }
- }
- //check rts
- if (skb->len > ieee->rts)
- {
- tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
- tcb_desc->bRTSEnable = true;
- break;
- }
- //to do list: check MIMO power save condition.
- //check AMPDU aggregation for TXOP
- if(tcb_desc->bAMPDUEnable)
- {
- tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
- // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
- // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
- tcb_desc->bRTSEnable = false;
- break;
- }
- // Totally no protection case!!
- goto NO_PROTECTION;
- }
- }
- // For test , CTS replace with RTS
- if( 0 )
- {
- tcb_desc->bCTSEnable = true;
- tcb_desc->rts_rate = MGN_24M;
- tcb_desc->bRTSEnable = true;
- }
- if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- tcb_desc->bUseShortPreamble = true;
- if (ieee->mode == IW_MODE_MASTER)
- goto NO_PROTECTION;
- return;
-NO_PROTECTION:
- tcb_desc->bRTSEnable = false;
- tcb_desc->bCTSEnable = false;
- tcb_desc->rts_rate = 0;
- tcb_desc->RTSSC = 0;
- tcb_desc->bRTSBW = false;
-}
-
-
-void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
-{
-#ifdef TO_DO_LIST
- if(!IsDataFrame(pFrame))
- {
- pTcb->bTxDisableRateFallBack = TRUE;
- pTcb->bTxUseDriverAssingedRate = TRUE;
- pTcb->RATRIndex = 7;
- return;
- }
-
- if(pMgntInfo->ForcedDataRate!= 0)
- {
- pTcb->bTxDisableRateFallBack = TRUE;
- pTcb->bTxUseDriverAssingedRate = TRUE;
- return;
- }
-#endif
- if(ieee->bTxDisableRateFallBack)
- tcb_desc->bTxDisableRateFallBack = true;
-
- if(ieee->bTxUseDriverAssingedRate)
- tcb_desc->bTxUseDriverAssingedRate = true;
- if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
- {
- if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
- tcb_desc->RATRIndex = 0;
- }
-}
-
-void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
-{
- if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
- return;
- if (IsQoSDataFrame(skb->data)) //we deal qos data only
- {
- PTX_TS_RECORD pTS = NULL;
- if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
- {
- return;
- }
- pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
- }
-}
-
-int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr_3addrqos *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- int ether_type = 0, encrypt;
- int bytes, fc, qos_ctl = 0, hdr_len;
- struct sk_buff *skb_frag;
- struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
- .duration_id = 0,
- .seq_ctl = 0,
- .qos_ctl = 0
- };
- u8 dest[ETH_ALEN], src[ETH_ALEN];
- int qos_actived = ieee->current_network.qos_data.active;
-
- struct ieee80211_crypt_data* crypt;
-
- cb_desc *tcb_desc;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* If there is no driver handler to take the TXB, dont' bother
- * creating it... */
- if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
- ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
- printk(KERN_WARNING "%s: No xmit handler.\n",
- ieee->dev->name);
- goto success;
- }
-
-
- if(likely(ieee->raw_tx == 0)){
- if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- printk(KERN_WARNING "%s: skb too small (%d).\n",
- ieee->dev->name, skb->len);
- goto success;
- }
-
- memset(skb->cb, 0, sizeof(skb->cb));
- ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
-
- if (!encrypt && ieee->ieee802_1x &&
- ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
- stats->tx_dropped++;
- goto success;
- }
- #ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !encrypt && ether_type == ETH_P_PAE) {
- struct eapol *eap = (struct eapol *)(skb->data +
- sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
- IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
- #endif
-
- /* Save source and destination addresses */
- memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
- /* Advance the SKB to the start of the payload */
- skb_pull(skb, sizeof(struct ethhdr));
-
- /* Determine total amount of storage required for TXB packets */
- bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
- if (encrypt)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
- else
- fc = IEEE80211_FTYPE_DATA;
-
- if(qos_actived)
- fc |= IEEE80211_STYPE_QOS_DATA;
- else
- fc |= IEEE80211_STYPE_DATA;
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA,
- Addr3 = DA */
- memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(&header.addr2, &src, ETH_ALEN);
- memcpy(&header.addr3, &dest, ETH_ALEN);
- } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* not From/To DS: Addr1 = DA, Addr2 = SA,
- Addr3 = BSSID */
- memcpy(&header.addr1, dest, ETH_ALEN);
- memcpy(&header.addr2, src, ETH_ALEN);
- memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
- }
-
- header.frame_ctl = cpu_to_le16(fc);
-
- /* Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented) */
- if (is_multicast_ether_addr(header.addr1) ||
- is_broadcast_ether_addr(header.addr1)) {
- frag_size = MAX_FRAG_THRESHOLD;
- qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
- }
- else {
- frag_size = ieee->fts;//default:392
- qos_ctl = 0;
- }
-
- //if (ieee->current_network.QoS_Enable)
- if(qos_actived)
- {
- hdr_len = IEEE80211_3ADDR_LEN + 2;
-
- skb->priority = ieee80211_classify(skb, &ieee->current_network);
- qos_ctl |= skb->priority; //set in the ieee80211_classify
- header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
- } else {
- hdr_len = IEEE80211_3ADDR_LEN;
- }
- /* Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account for
- * it when determining the amount of payload space. */
- bytes_per_frag = frag_size - hdr_len;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryptiong pre/postfix */
- if (encrypt)
- bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
-
- /* Number of fragments is the total bytes_per_frag /
- * payload_per_fragment */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
- nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
-
- /* When we allocate the TXB we allocate enough space for the reserve
- * and full fragment bytes (bytes_per_frag doesn't include prefix,
- * postfix, header, FCS, etc.) */
- txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
- if (unlikely(!txb)) {
- printk(KERN_WARNING "%s: Could not allocate TXB\n",
- ieee->dev->name);
- goto failed;
- }
- txb->encrypted = encrypt;
- txb->payload_size = bytes;
-
- if(qos_actived)
- {
- txb->queue_index = UP2AC(skb->priority);
- } else {
- txb->queue_index = WME_AC_BK;;
- }
-
-
-
- for (i = 0; i < nr_frags; i++) {
- skb_frag = txb->fragments[i];
- tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
- if(qos_actived){
- skb_frag->priority = skb->priority;//UP2AC(skb->priority);
- tcb_desc->queue_index = UP2AC(skb->priority);
- } else {
- skb_frag->priority = WME_AC_BK;
- tcb_desc->queue_index = WME_AC_BK;
- }
- skb_reserve(skb_frag, ieee->tx_headroom);
-
- if (encrypt){
- if (ieee->hwsec_active)
- tcb_desc->bHwSec = 1;
- else
- tcb_desc->bHwSec = 0;
- skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
- }
- else
- {
- tcb_desc->bHwSec = 0;
- }
- frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
- memcpy(frag_hdr, &header, hdr_len);
-
- /* If this is not the last fragment, then add the MOREFRAGS
- * bit to the frame control */
- if (i != nr_frags - 1) {
- frag_hdr->frame_ctl = cpu_to_le16(
- fc | IEEE80211_FCTL_MOREFRAGS);
- bytes = bytes_per_frag;
-
- } else {
- /* The last fragment takes the remaining length */
- bytes = bytes_last_frag;
- }
- if(qos_actived)
- {
- // add 1 only indicate to corresponding seq number control 2006/7/12
- frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
- } else {
- frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
- }
-
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- ieee80211_put_snap(
- skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
- bytes -= SNAP_SIZE + sizeof(u16);
- }
-
- memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
-
- /* Advance the SKB... */
- skb_pull(skb, bytes);
-
- /* Encryption routine will move the header forward in order
- * to insert the IV between the header and the payload */
- if (encrypt)
- ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
- }
-
- if(qos_actived)
- {
- if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
- ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
- else
- ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
- } else {
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
- }else{
- if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
- printk(KERN_WARNING "%s: skb too small (%d).\n",
- ieee->dev->name, skb->len);
- goto success;
- }
-
- txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
- if(!txb){
- printk(KERN_WARNING "%s: Could not allocate TXB\n",
- ieee->dev->name);
- goto failed;
- }
-
- txb->encrypted = 0;
- txb->payload_size = skb->len;
- memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
- }
-
- success:
-//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
- if (txb)
- {
-#if 1
- cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
- tcb_desc->bTxEnableFwCalcDur = 1;
- if (is_multicast_ether_addr(header.addr1))
- tcb_desc->bMulticast = 1;
- if (is_broadcast_ether_addr(header.addr1))
- tcb_desc->bBroadcast = 1;
- ieee80211_txrate_selectmode(ieee, tcb_desc);
- if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
- tcb_desc->data_rate = ieee->basic_rate;
- else
- tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
- ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
- ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
- ieee80211_query_HTCapShortGI(ieee, tcb_desc);
- ieee80211_query_BandwidthMode(ieee, tcb_desc);
- ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
- ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
-#endif
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- dev_kfree_skb_any(skb);
- if (txb) {
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
- ieee80211_softmac_xmit(txb, ieee);
- }else{
- if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
- return 0;
- }
- ieee80211_txb_free(txb);
- }
- }
-
- return 0;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- netif_stop_queue(dev);
- stats->tx_errors++;
- return 1;
-
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
deleted file mode 100644
index 984a3608561c..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ /dev/null
@@ -1,772 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2004 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <jkmaline@cc.hut.fi>
- Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
-
- 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************/
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "ieee80211.h"
-
-struct modes_unit {
- char *mode_string;
- int mode_size;
-};
-struct modes_unit ieee80211_modes[] = {
- {"a",1},
- {"b",1},
- {"g",1},
- {"?",1},
- {"N-24G",5},
- {"N-5G",4},
-};
-
-#define iwe_stream_add_event_rsl iwe_stream_add_event
-
-#define MAX_CUSTOM_LEN 64
-static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network,
- struct iw_request_info *info)
-{
- char custom[MAX_CUSTOM_LEN];
- char proto_name[IFNAMSIZ];
- char *pname = proto_name;
- char *p;
- struct iw_event iwe;
- int i, j;
- u16 max_rate, rate;
- static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
-
- /* 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, network->bssid, ETH_ALEN);
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-
- /* Remaining entries will be displayed in the order we provide them */
-
- /* Add the ESSID */
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- if (network->ssid_len == 0) {
- iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
- } else {
- iwe.u.data.length = min(network->ssid_len, (u8)32);
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- }
- /* Add the protocol name */
- iwe.cmd = SIOCGIWNAME;
- for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
- if(network->mode&(1<<i)) {
- sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
- pname +=ieee80211_modes[i].mode_size;
- }
- }
- *pname = '\0';
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability &
- (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
- if (network->capability & WLAN_CAPABILITY_BSS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Add frequency/channel */
- iwe.cmd = SIOCGIWFREQ;
-/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
- iwe.u.freq.e = 3; */
- iwe.u.freq.m = network->channel;
- iwe.u.freq.e = 0;
- iwe.u.freq.i = 0;
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (network->capability & 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;
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- /* Add basic and extended rates */
- max_rate = 0;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- for (i = 0, j = 0; i < network->rates_len; ) {
- if (j < network->rates_ex_len &&
- ((network->rates_ex[j] & 0x7F) <
- (network->rates[i] & 0x7F)))
- rate = network->rates_ex[j++] & 0x7F;
- else
- rate = network->rates[i++] & 0x7F;
- if (rate > max_rate)
- max_rate = rate;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- }
- for (; j < network->rates_ex_len; j++) {
- rate = network->rates_ex[j] & 0x7F;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- if (rate > max_rate)
- max_rate = rate;
- }
-
- if (network->mode >= IEEE_N_24G)//add N rate here;
- {
- PHT_CAPABILITY_ELE ht_cap = NULL;
- bool is40M = false, isShortGI = false;
- u8 max_mcs = 0;
- if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
- ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
- else
- ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
- is40M = (ht_cap->ChlWidth)?1:0;
- isShortGI = (ht_cap->ChlWidth)?
- ((ht_cap->ShortGI40Mhz)?1:0):
- ((ht_cap->ShortGI20Mhz)?1:0);
-
- max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
- rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
- if (rate > max_rate)
- max_rate = rate;
- }
-
- iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- iwe.u.bitrate.value = max_rate * 500000;
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
- IW_EV_PARAM_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- /* Add quality statistics */
- /* TODO: Fix these values... */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signal;
- iwe.u.qual.level = network->stats.rssi;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
- iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
- iwe.u.qual.updated = 7;
- start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
- iwe.cmd = IWEVCUSTOM;
- p = custom;
-
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->wpa_ie_len)
- {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
- memset(&iwe, 0, sizeof(iwe));
- if (network->rsn_ie_len)
- {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- return start;
-}
-
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ieee80211_network *network;
- unsigned long flags;
-
- char *ev = extra;
- char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
- int i = 0;
- int err = 0;
- IEEE80211_DEBUG_WX("Getting scan\n");
- down(&ieee->wx_sem);
- spin_lock_irqsave(&ieee->lock, flags);
-
- list_for_each_entry(network, &ieee->network_list, list) {
- i++;
- if((stop-ev)<200)
- {
- err = -E2BIG;
- break;
- }
- if (ieee->scan_age == 0 ||
- time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
- else
- IEEE80211_DEBUG_SCAN(
- "Not showing network '%s ("
- "%pM)' due to age (%lums).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid,
- (jiffies - network->last_scanned) / (HZ / 100));
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- up(&ieee->wx_sem);
- wrqu->data.length = ev - extra;
- wrqu->data.flags = 0;
-
- IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
-
- return err;
-}
-
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- struct net_device *dev = ieee->dev;
- struct ieee80211_security sec = {
- .flags = 0
- };
- int i, key, key_provided, len;
- struct ieee80211_crypt_data **crypt;
-
- IEEE80211_DEBUG_WX("SET_ENCODE\n");
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- key_provided = 1;
- } else {
- key_provided = 0;
- key = ieee->tx_keyidx;
- }
-
- IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
- "provided" : "default");
- crypt = &ieee->crypt[key];
-
- if (erq->flags & IW_ENCODE_DISABLED) {
- if (key_provided && *crypt) {
- IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
- key);
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- } else
- IEEE80211_DEBUG_WX("Disabling encryption.\n");
-
- /* Check all the keys to see if any are still configured,
- * and if no key index was provided, de-init them all */
- for (i = 0; i < WEP_KEYS; i++) {
- if (ieee->crypt[i] != NULL) {
- if (key_provided)
- break;
- ieee80211_crypt_delayed_deinit(
- ieee, &ieee->crypt[i]);
- }
- }
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- }
-
- goto done;
- }
-
-
-
- sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
-
- if (*crypt != NULL && (*crypt)->ops != NULL &&
- strcmp((*crypt)->ops->name, "WEP") != 0) {
- /* changing to use WEP; deinit previously used algorithm
- * on this key */
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
-
- if (*crypt == NULL) {
- struct ieee80211_crypt_data *new_crypt;
-
- /* take WEP into use */
- new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
- GFP_KERNEL);
- if (new_crypt == NULL)
- return -ENOMEM;
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops)
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(key);
-
- if (!new_crypt->ops || !new_crypt->priv) {
- kfree(new_crypt);
- new_crypt = NULL;
-
- printk(KERN_WARNING "%s: could not initialize WEP: "
- "load module ieee80211_crypt_wep\n",
- dev->name);
- return -EOPNOTSUPP;
- }
- *crypt = new_crypt;
- }
-
- /* If a new key was provided, set it up */
- if (erq->length > 0) {
- len = erq->length <= 5 ? 5 : 13;
- memcpy(sec.keys[key], keybuf, erq->length);
- if (len > erq->length)
- memset(sec.keys[key] + erq->length, 0,
- len - erq->length);
- IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
- key, escape_essid(sec.keys[key], len),
- erq->length, len);
- sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
- sec.flags |= (1 << key);
- /* This ensures a key will be activated if no key is
- * explicitely set */
- if (key == sec.active_key)
- sec.flags |= SEC_ACTIVE_KEY;
- ieee->tx_keyidx = key;
-
- } else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- printk("Setting key %d to all zero.\n",
- key);
-
- IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
- }
-
- /* No key data - just set the default TX key index */
- if (key_provided) {
- IEEE80211_DEBUG_WX(
- "Setting key %d to default Tx key.\n", key);
- ieee->tx_keyidx = key;
- sec.active_key = key;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- }
-
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
-
- /* For now we just support WEP, so only set that security level...
- * TODO: When WPA is added this is one place that needs to change */
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
-
- if (ieee->set_security)
- ieee->set_security(dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack. */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
- return 0;
-}
-
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- int len, key;
- struct ieee80211_crypt_data *crypt;
-
- IEEE80211_DEBUG_WX("GET_ENCODE\n");
-
- if(ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- } else
- key = ieee->tx_keyidx;
-
- crypt = ieee->crypt[key];
- erq->flags = key + 1;
-
- if (crypt == NULL || crypt->ops == NULL) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
-
- len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
- erq->length = (len >= 0 ? len : 0);
-
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (ieee->open_wep)
- erq->flags |= IW_ENCODE_OPEN;
- else
- erq->flags |= IW_ENCODE_RESTRICTED;
-
- return 0;
-}
-
-int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct net_device *dev = ieee->dev;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int i, idx;
- int group_key = 0;
- const char *alg;
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > WEP_KEYS)
- return -EINVAL;
- idx--;
- } else
- idx = ieee->tx_keyidx;
-
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-
- crypt = &ieee->crypt[idx];
-
- group_key = 1;
- } else {
- /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
- if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- return -EINVAL;
- if (ieee->iw_mode == IW_MODE_INFRA)
-
- crypt = &ieee->crypt[idx];
-
- else
- return -EINVAL;
- }
-
- sec.flags |= SEC_ENABLED;
-
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- if (*crypt)
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- for (i = 0; i < WEP_KEYS; i++)
-
- if (ieee->crypt[i] != NULL)
-
- break;
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- // sec.encrypt = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_LEVEL;
- }
- //printk("disabled: flag:%x\n", encoding->flags);
- goto done;
- }
-
- sec.enabled = 1;
-
- switch (ext->alg) {
- case IW_ENCODE_ALG_WEP:
- alg = "WEP";
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = "TKIP";
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = "CCMP";
- break;
- default:
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- ret = -EINVAL;
- goto done;
- }
- IEEE80211_DEBUG_WX("alg name: %s\n", alg);
-
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL)
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- printk("========>unknown crypto alg %d\n", ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- new_crypt->ops = ops;
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(idx);
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- ret = -EINVAL;
- goto done;
- }
- *crypt = new_crypt;
-
- }
-
- if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- (*crypt)->priv) < 0) {
- IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
- printk("key setting failed\n");
- ret = -EINVAL;
- goto done;
- }
-#if 1
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- ieee->tx_keyidx = idx;
- sec.active_key = idx;
- sec.flags |= SEC_ACTIVE_KEY;
- }
-
- if (ext->alg != IW_ENCODE_ALG_NONE) {
- sec.key_sizes[idx] = ext->key_len;
- sec.flags |= (1 << idx);
- if (ext->alg == IW_ENCODE_ALG_WEP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- /* Don't set sec level for group keys. */
- if (group_key)
- sec.flags &= ~SEC_LEVEL;
- }
-#endif
-done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_mlme *mlme = (struct iw_mlme *) extra;
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- case IW_MLME_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
-{
- switch (data->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- /*need to support wpa2 here*/
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- /*
- * * Host AP driver does not use these parameters and allows
- * * wpa_supplicant to control them internally.
- * */
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = data->value;
- break;
- case IW_AUTH_DROP_UNENCRYPTED:
- ieee->drop_unencrypted = data->value;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if(data->value & IW_AUTH_ALG_SHARED_KEY){
- ieee->open_wep = 0;
- ieee->auth_mode = 1;
- }
- else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
- ieee->open_wep = 1;
- ieee->auth_mode = 0;
- }
- else if(data->value & IW_AUTH_ALG_LEAP){
- ieee->open_wep = 1;
- ieee->auth_mode = 2;
- }
- else
- return -EINVAL;
- break;
-
-#if 1
- case IW_AUTH_WPA_ENABLED:
- ieee->wpa_enabled = (data->value)?1:0;
- break;
-
-#endif
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ieee->ieee802_1x = data->value;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- ieee->privacy_invoked = data->value;
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-#if 1
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
-{
- u8 *buf;
-
- if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
- {
- return -EINVAL;
- }
-
-
- if (len)
- {
- if (len != ie[1]+2)
- {
- printk("len: %Zd, ie:%d\n", len, ie[1]);
- return -EINVAL;
- }
- buf = kmemdup(ie, len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = len;
- }
- else{
- if (ieee->wpa_ie)
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- return 0;
-
-}
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/readme b/drivers/staging/rtl8192su/ieee80211/readme
deleted file mode 100644
index 7ba177ba3e33..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/readme
+++ /dev/null
@@ -1,162 +0,0 @@
-What this layer should do
-
-- It mantain the old mechanism as alternative, so the
- ipw2100 driver works with really few changes.
-- Encapsulate / Decapsulate ieee80211 packet
-- Handle fragmentation
-- Optionally provide an alterantive mechanism for netif queue stop/wake,
- so that the ieee80211 layer will pass one fragment per time instead of
- one txb struct per time. so the driver can stop the queue in the middle
- of a packet.
-- Provide two different TX interfaces for cards that can handle management
- frames on one HW queue, and data on another, and for cards that have only
- one HW queue (the latter untested and very, very rough).
-- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
- and for the channel, essid and wap get/set wireless extension requests.
- so that the driver has only to change channel when the ieee stack tell it.
-- Optionally provide a scanning mechanism so that the driver has not to
- worry about this, just implement the set channel calback and pass
- frames to the upper layer
-- Optionally provide the bss client protocol handshaking (just with open
- authentication)
-- Optionally provide the probe request send mechanism
-- Optionally provide the bss master mode logic to handle association
- protocol (only open authentication) and probe responses.
-- SW wep encryption (with open authentication)
-- It collects some stats
-- It provides beacons to the card when it ask for them
-
-What this layer doesn't do (yet)
-- Perform shared authentication
-- Have full support for master mode (the AP should loop back in the air
- frames from an associated client to another. This could be done easily
- with few lines of code, and it is done in my previous version of the
- stach, but a table of association must be keept and a disassociation
- policy must be decided and implemented.
-- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
- disassociate clients, and it is really prone to always allow access.
- In bss client mode it is a bit rough with AP deauth and disassoc requests.
-- It has not any entry point to view the collected stats.
-- Although it takes care of the card supported rates in the management frame
- it sends, support for rate changing on TXed packet is not complete.
-- Give up once associated in bss client mode (it never detect a
- signal loss condition to disassociate and restart scanning)
-- Provide a mechanism for enabling the TX in monitor mode, so
- userspace programs can TX raw packets.
-- Provide a mechanism for cards that need that the SW take care of beacon
- TX completely, in sense that the SW has to enqueue by itself beacons
- to the card so it TX them (if any...)
-APIs
-
-Callback functions in the original stack has been mantained.
-following has been added (from ieee80211.h)
-
- /* Softmac-generated frames (mamagement) are TXed via this
- * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- * not set. As some cards may have different HW queues that
- * one might want to use for data and management frames
- * the option to have two callbacks might be useful.
- * This fucntion can't sleep.
- */
- int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- * then also management frames are sent via this callback.
- * This function can't sleep.
- */
- void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* stops the HW queue for DATA frames. Useful to avoid
- * waste time to TX data frame when we are reassociating
- * This function can sleep.
- */
- void (*data_hard_stop)(struct net_device *dev);
-
- /* OK this is complementar to data_poll_hard_stop */
- void (*data_hard_resume)(struct net_device *dev);
-
- /* ask to the driver to retune the radio .
- * This function can sleep. the driver should ensure
- * the radio has been swithced before return.
- */
- void (*set_chan)(struct net_device *dev,short ch);
-
- /* These are not used if the ieee stack takes care of
- * scanning (IEEE_SOFTMAC_SCAN feature set).
- * In this case only the set_chan is used.
- *
- * The syncro version is similar to the start_scan but
- * does not return until all channels has been scanned.
- * this is called in user context and should sleep,
- * it is called in a work_queue when swithcing to ad-hoc mode
- * or in behalf of iwlist scan when the card is associated
- * and root user ask for a scan.
- * the fucntion stop_scan should stop both the syncro and
- * background scanning and can sleep.
- * The fucntion start_scan should initiate the background
- * scanning and can't sleep.
- */
- void (*scan_syncro)(struct net_device *dev);
- void (*start_scan)(struct net_device *dev);
- void (*stop_scan)(struct net_device *dev);
-
- /* indicate the driver that the link state is changed
- * for example it may indicate the card is associated now.
- * Driver might be interested in this to apply RX filter
- * rules or simply light the LINK led
- */
- void (*link_change)(struct net_device *dev);
-
-Functions hard_data_[resume/stop] are optional and should not be used
-if the driver decides to uses data+management frames enqueue in a
-single HQ queue (thus using just the softmac_hard_data_start_xmit
-callback).
-
-Function that the driver can use are:
-
-ieee80211_get_beacon - this is called by the driver when
- the HW needs a beacon.
-ieee80211_softmac_start_protocol - this should normally be called in the
- driver open function
-ieee80211_softmac_stop_protocol - the opposite of the above
-ieee80211_wake_queue - this is similar to netif_wake_queue
-ieee80211_reset_queue - this throw away fragments pending(if any)
-ieee80211_stop_queue - this is similar to netif_stop_queue
-
-
-known BUGS:
-- When performing syncro scan (possiblily when swithcing to ad-hoc mode
- and when running iwlist scan when associated) there is still an odd
- behaviour.. I have not looked in this more accurately (yet).
-
-locking:
-locking is done by means of three structures.
-1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
-2- ieee->wx_sem
-3- ieee->scan_sem
-
-the lock 1 is what protect most of the critical sections in the ieee stack.
-the lock 2 is used to avoid that more than one of the SET wireless extension
-handlers (as well as start/stop protocol function) are running at the same time.
-the lock 1 is used when we need to modify or read the shared data in the wx handlers.
-In other words the lock 2 will prevent one SET action will run across another SET
-action (by make sleep the 2nd one) but allow GET actions, while the lock 1
-make atomic those little shared data access in both GET and SET operation.
-So get operation will be never be delayed really: they will never sleep..
-Furthermore in the top of some SET operations a flag is set before acquiring
-the lock. This is an help to make the previous running SET operation to
-finish faster if needed (just in case the second one will totally undo the
-first, so there is not need to complete the 1st really.. ).
-The background scanning mechaninsm is protected by the lock 1 except for the
-workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
-might be appreciated by USB network card driver developer). In this case the lock 3
-take its turn.
-Thus the stop function needs both the locks.
-Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
-function and the stop scan function are called with this semaphore held).
-
-
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_BA.h
deleted file mode 100644
index 1c2a40b75a19..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BA.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef _BATYPE_H_
-#define _BATYPE_H_
-
-#define TOTAL_TXBA_NUM 16
-#define TOTAL_RXBA_NUM 16
-
-#define BA_SETUP_TIMEOUT 200
-#define BA_INACT_TIMEOUT 60000
-
-#define BA_POLICY_DELAYED 0
-#define BA_POLICY_IMMEDIATE 1
-
-#define ADDBA_STATUS_SUCCESS 0
-#define ADDBA_STATUS_REFUSED 37
-#define ADDBA_STATUS_INVALID_PARAM 38
-
-#define DELBA_REASON_QSTA_LEAVING 36
-#define DELBA_REASON_END_BA 37
-#define DELBA_REASON_UNKNOWN_BA 38
-#define DELBA_REASON_TIMEOUT 39
-
-typedef union _SEQUENCE_CONTROL{
- u16 ShortData;
- struct
- {
- u16 FragNum:4;
- u16 SeqNum:12;
- }field;
-}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
-
-typedef union _BA_PARAM_SET {
- u8 charData[2];
- u16 shortData;
- struct {
- u16 AMSDU_Support:1;
- u16 BAPolicy:1;
- u16 TID:4;
- u16 BufferSize:10;
- } field;
-} BA_PARAM_SET, *PBA_PARAM_SET;
-
-typedef union _DELBA_PARAM_SET {
- u8 charData[2];
- u16 shortData;
- struct {
- u16 Reserved:11;
- u16 Initiator:1;
- u16 TID:4;
- } field;
-} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
-
-typedef struct _BA_RECORD {
- struct timer_list Timer;
- u8 bValid;
- u8 DialogToken;
- BA_PARAM_SET BaParamSet;
- u16 BaTimeoutValue;
- SEQUENCE_CONTROL BaStartSeqCtrl;
-} BA_RECORD, *PBA_RECORD;
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
deleted file mode 100644
index ca611faf17bc..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "ieee80211.h"
-#include "rtl819x_BA.h"
-
-/********************************************************************************************************************
- *function: Activate BA entry. And if Time is nozero, start timer.
- * input: PBA_RECORD pBA //BA entry to be enabled
- * u16 Time //indicate time delay.
- * output: none
-********************************************************************************************************************/
-void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
-{
- pBA->bValid = true;
- if(Time != 0)
- mod_timer(&pBA->Timer, jiffies + MSECS(Time));
-}
-
-/********************************************************************************************************************
- *function: deactivate BA entry, including its timer.
- * input: PBA_RECORD pBA //BA entry to be disabled
- * output: none
-********************************************************************************************************************/
-void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
-{
- pBA->bValid = false;
- del_timer_sync(&pBA->Timer);
-}
-/********************************************************************************************************************
- *function: deactivete BA entry in Tx Ts, and send DELBA.
- * input:
- * PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry.
- * output: none
- * notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
-********************************************************************************************************************/
-u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs)
-{
- PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure
- PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord;
- u8 bSendDELBA = false;
-
- // Delete pending BA
- if(pPendingBa->bValid)
- {
- DeActivateBAEntry(ieee, pPendingBa);
- bSendDELBA = true;
- }
-
- // Delete admitted BA
- if(pAdmittedBa->bValid)
- {
- DeActivateBAEntry(ieee, pAdmittedBa);
- bSendDELBA = true;
- }
-
- return bSendDELBA;
-}
-
-/********************************************************************************************************************
- *function: deactivete BA entry in Tx Ts, and send DELBA.
- * input:
- * PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry.
- * output: none
- * notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
-********************************************************************************************************************/
-u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs)
-{
- PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord;
- u8 bSendDELBA = false;
-
- if(pBa->bValid)
- {
- DeActivateBAEntry(ieee, pBa);
- bSendDELBA = true;
- }
-
- return bSendDELBA;
-}
-
-/********************************************************************************************************************
- *function: reset BA entry
- * input:
- * PBA_RECORD pBA //entry to be reset
- * output: none
-********************************************************************************************************************/
-void ResetBaEntry( PBA_RECORD pBA)
-{
- pBA->bValid = false;
- pBA->BaParamSet.shortData = 0;
- pBA->BaTimeoutValue = 0;
- pBA->DialogToken = 0;
- pBA->BaStartSeqCtrl.ShortData = 0;
-}
-//These functions need porting here or not?
-/*******************************************************************************************************************************
- *function: construct ADDBAREQ and ADDBARSP frame here together.
- * input: u8* Dst //ADDBA frame's destination
- * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA.
- * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
- * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
- * output: none
- * return: sk_buff* skb //return constructed skb to xmit
-*******************************************************************************************************************************/
-static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
-{
- struct sk_buff *skb = NULL;
- struct ieee80211_hdr_3addr* BAReq = NULL;
- u8* tag = NULL;
- u16 tmp = 0;
- u16 len = ieee->tx_headroom + 9;
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
- if (pBA == NULL||ieee == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
- return NULL;
- }
- skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
- if (skb == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
- return NULL;
- }
-
- memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
- skb_reserve(skb, ieee->tx_headroom);
-
- BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
-
- memcpy(BAReq->addr1, Dst, ETH_ALEN);
- memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
-
- memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
-
- BAReq->frame_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
-
- tag = (u8*)skb_put(skb, 9);
- *tag ++= ACT_CAT_BA;
- *tag ++= type;
- // Dialog Token
- *tag ++= pBA->DialogToken;
-
- if (ACT_ADDBARSP == type)
- {
- // Status Code
- printk("=====>to send ADDBARSP\n");
- tmp = cpu_to_le16(StatusCode);
- memcpy(tag, (u8*)&tmp, 2);
- tag += 2;
- }
- // BA Parameter Set
- tmp = cpu_to_le16(pBA->BaParamSet.shortData);
- memcpy(tag, (u8*)&tmp, 2);
- tag += 2;
- // BA Timeout Value
- tmp = cpu_to_le16(pBA->BaTimeoutValue);
- memcpy(tag, (u8*)&tmp, 2);
- tag += 2;
-
- if (ACT_ADDBAREQ == type)
- {
- // BA Start SeqCtrl
- memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
- tag += 2;
- }
-
- IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
- return skb;
-}
-
-/********************************************************************************************************************
- *function: construct DELBA frame
- * input: u8* dst //DELBA frame's destination
- * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
- * TR_SELECT TxRxSelect //TX RX direction
- * u16 ReasonCode //status code.
- * output: none
- * return: sk_buff* skb //return constructed skb to xmit
-********************************************************************************************************************/
-static struct sk_buff* ieee80211_DELBA(
- struct ieee80211_device* ieee,
- u8* dst,
- PBA_RECORD pBA,
- TR_SELECT TxRxSelect,
- u16 ReasonCode
- )
-{
- DELBA_PARAM_SET DelbaParamSet;
- struct sk_buff *skb = NULL;
- struct ieee80211_hdr_3addr* Delba = NULL;
- u8* tag = NULL;
- u16 tmp = 0;
- u16 len = 6 + ieee->tx_headroom;
-
- if (net_ratelimit())
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
-
- memset(&DelbaParamSet, 0, 2);
-
- DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0;
- DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
-
- skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
- if (skb == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
- return NULL;
- }
- skb_reserve(skb, ieee->tx_headroom);
-
- Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
-
- memcpy(Delba->addr1, dst, ETH_ALEN);
- memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
- Delba->frame_control = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
-
- tag = (u8*)skb_put(skb, 6);
-
- *tag ++= ACT_CAT_BA;
- *tag ++= ACT_DELBA;
-
- // DELBA Parameter Set
- tmp = cpu_to_le16(DelbaParamSet.shortData);
- memcpy(tag, (u8*)&tmp, 2);
- tag += 2;
- // Reason Code
- tmp = cpu_to_le16(ReasonCode);
- memcpy(tag, (u8*)&tmp, 2);
- tag += 2;
-
- IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
- if (net_ratelimit())
- IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
- return skb;
-}
-
-/********************************************************************************************************************
- *function: send ADDBAReq frame out
- * input: u8* dst //ADDBAReq frame's destination
- * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
- * output: none
- * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
-********************************************************************************************************************/
-void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA)
-{
- struct sk_buff *skb = NULL;
- skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
-
- if (skb)
- {
- softmac_mgmt_xmit(skb, ieee);
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
- }
- return;
-}
-
-/********************************************************************************************************************
- *function: send ADDBARSP frame out
- * input: u8* dst //DELBA frame's destination
- * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
- * u16 StatusCode //RSP StatusCode
- * output: none
- * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
-********************************************************************************************************************/
-void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
-{
- struct sk_buff *skb = NULL;
- skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
- if (skb)
- {
- softmac_mgmt_xmit(skb, ieee);
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
- }
-
- return;
-
-}
-/********************************************************************************************************************
- *function: send ADDBARSP frame out
- * input: u8* dst //DELBA frame's destination
- * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA
- * TR_SELECT TxRxSelect //TX or RX
- * u16 ReasonCode //DEL ReasonCode
- * output: none
- * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
-********************************************************************************************************************/
-
-void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
-{
- struct sk_buff *skb = NULL;
- skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
- if (skb)
- {
- softmac_mgmt_xmit(skb, ieee);
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
- }
- return ;
-}
-
-/********************************************************************************************************************
- *function: RX ADDBAReq
- * input: struct sk_buff * skb //incoming ADDBAReq skb.
- * return: 0(pass), other(fail)
- * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
-********************************************************************************************************************/
-int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr* req = NULL;
- u16 rc = 0;
- u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
- PBA_RECORD pBA = NULL;
- PBA_PARAM_SET pBaParamSet = NULL;
- u16* pBaTimeoutVal = NULL;
- PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
- PRX_TS_RECORD pTS = NULL;
-
- if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR,
- " Invalid skb len in BAREQ(%d / %zd)\n",
- skb->len,
- sizeof(struct ieee80211_hdr_3addr) + 9);
- return -1;
- }
-
- IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
-
- req = ( struct ieee80211_hdr_3addr*) skb->data;
- tag = (u8*)req;
- dst = (u8*)(&req->addr2[0]);
- tag += sizeof( struct ieee80211_hdr_3addr);
- pDialogToken = tag + 2; //category+action
- pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken
- pBaTimeoutVal = (u16*)(tag + 5);
- pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
-
- printk("====================>rx ADDBAREQ from :%pM\n", dst);
-//some other capability is not ready now.
- if( (ieee->current_network.qos_data.active == 0) ||
- (ieee->pHTInfo->bCurrentHTSupport == false) ||
- (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ))
- {
- rc = ADDBA_STATUS_REFUSED;
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
- goto OnADDBAReq_Fail;
- }
- // Search for related traffic stream.
- // If there is no matched TS, reject the ADDBA request.
- if( !GetTs(
- ieee,
- (PTS_COMMON_INFO*)(&pTS),
- dst,
- (u8)(pBaParamSet->field.TID),
- RX_DIR,
- true) )
- {
- rc = ADDBA_STATUS_REFUSED;
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
- goto OnADDBAReq_Fail;
- }
- pBA = &pTS->RxAdmittedBARecord;
- // To Determine the ADDBA Req content
- // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
- // I want to check StartSeqCtrl to make sure when we start aggregation!!!
- //
- if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
- {
- rc = ADDBA_STATUS_INVALID_PARAM;
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
- goto OnADDBAReq_Fail;
- }
- // Admit the ADDBA Request
- DeActivateBAEntry(ieee, pBA);
- pBA->DialogToken = *pDialogToken;
- pBA->BaParamSet = *pBaParamSet;
- pBA->BaTimeoutValue = *pBaTimeoutVal;
- pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
- //for half N mode we only aggregate 1 frame
- if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)||
- (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
- pBA->BaParamSet.field.BufferSize = 1;
- else
- pBA->BaParamSet.field.BufferSize = 32;
- ActivateBAEntry(ieee, pBA, 0);
- ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
-
- return 0;
-
-OnADDBAReq_Fail:
- {
- BA_RECORD BA;
- BA.BaParamSet = *pBaParamSet;
- BA.BaTimeoutValue = *pBaTimeoutVal;
- BA.DialogToken = *pDialogToken;
- BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
- ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
- return 0; //we send RSP out.
- }
-
-}
-
-/********************************************************************************************************************
- *function: RX ADDBARSP
- * input: struct sk_buff * skb //incoming ADDBAReq skb.
- * return: 0(pass), other(fail)
- * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
-********************************************************************************************************************/
-int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr* rsp = NULL;
- PBA_RECORD pPendingBA, pAdmittedBA;
- PTX_TS_RECORD pTS = NULL;
- u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
- u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
- PBA_PARAM_SET pBaParamSet = NULL;
- u16 ReasonCode;
-
- if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR,
- " Invalid skb len in BARSP(%d / %zd)\n",
- skb->len,
- sizeof(struct ieee80211_hdr_3addr) + 9);
- return -1;
- }
- rsp = ( struct ieee80211_hdr_3addr*)skb->data;
- tag = (u8*)rsp;
- dst = (u8*)(&rsp->addr2[0]);
- tag += sizeof( struct ieee80211_hdr_3addr);
- pDialogToken = tag + 2;
- pStatusCode = (u16*)(tag + 3);
- pBaParamSet = (PBA_PARAM_SET)(tag + 5);
- pBaTimeoutVal = (u16*)(tag + 7);
-
- // Check the capability
- // Since we can always receive A-MPDU, we just check if it is under HT mode.
- if( ieee->current_network.qos_data.active == 0 ||
- ieee->pHTInfo->bCurrentHTSupport == false ||
- ieee->pHTInfo->bCurrentAMPDUEnable == false )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
- ReasonCode = DELBA_REASON_UNKNOWN_BA;
- goto OnADDBARsp_Reject;
- }
-
-
- //
- // Search for related TS.
- // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
- //
- if (!GetTs(
- ieee,
- (PTS_COMMON_INFO*)(&pTS),
- dst,
- (u8)(pBaParamSet->field.TID),
- TX_DIR,
- false) )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
- ReasonCode = DELBA_REASON_UNKNOWN_BA;
- goto OnADDBARsp_Reject;
- }
-
- pTS->bAddBaReqInProgress = false;
- pPendingBA = &pTS->TxPendingBARecord;
- pAdmittedBA = &pTS->TxAdmittedBARecord;
-
-
- //
- // Check if related BA is waiting for setup.
- // If not, reject by sending DELBA frame.
- //
- if((pAdmittedBA->bValid==true))
- {
- // Since BA is already setup, we ignore all other ADDBA Response.
- IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
- return -1;
- }
- else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
- ReasonCode = DELBA_REASON_UNKNOWN_BA;
- goto OnADDBARsp_Reject;
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
- DeActivateBAEntry(ieee, pPendingBA);
- }
-
-
- if(*pStatusCode == ADDBA_STATUS_SUCCESS)
- {
- //
- // Determine ADDBA Rsp content here.
- // We can compare the value of BA parameter set that Peer returned and Self sent.
- // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
- //
- if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
- {
- // Since this is a kind of ADDBA failed, we delay next ADDBA process.
- pTS->bAddBaReqDelayed = true;
- DeActivateBAEntry(ieee, pAdmittedBA);
- ReasonCode = DELBA_REASON_END_BA;
- goto OnADDBARsp_Reject;
- }
-
-
- //
- // Admitted condition
- //
- pAdmittedBA->DialogToken = *pDialogToken;
- pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
- pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
- pAdmittedBA->BaParamSet = *pBaParamSet;
- DeActivateBAEntry(ieee, pAdmittedBA);
- ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
- } else {
- pTS->bAddBaReqDelayed = true;
- pTS->bDisable_AddBa = true;
- ReasonCode = DELBA_REASON_END_BA;
- goto OnADDBARsp_Reject;
- }
-
- // End of procedure
- return 0;
-
-OnADDBARsp_Reject:
- {
- BA_RECORD BA;
- BA.BaParamSet = *pBaParamSet;
- ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
- return 0;
- }
-
-}
-
-/********************************************************************************************************************
- *function: RX DELBA
- * input: struct sk_buff * skb //incoming ADDBAReq skb.
- * return: 0(pass), other(fail)
- * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
-********************************************************************************************************************/
-int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr* delba = NULL;
- PDELBA_PARAM_SET pDelBaParamSet = NULL;
- u16* pReasonCode = NULL;
- u8* dst = NULL;
-
- if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR,
- " Invalid skb len in DELBA(%d / %zd)\n",
- skb->len,
- sizeof(struct ieee80211_hdr_3addr) + 6);
- return -1;
- }
-
- if(ieee->current_network.qos_data.active == 0 ||
- ieee->pHTInfo->bCurrentHTSupport == false )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
- return -1;
- }
-
- IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
- delba = ( struct ieee80211_hdr_3addr*)skb->data;
- dst = (u8*)(&delba->addr2[0]);
- delba += sizeof( struct ieee80211_hdr_3addr);
- pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
- pReasonCode = (u16*)(delba+4);
-
- if(pDelBaParamSet->field.Initiator == 1)
- {
- PRX_TS_RECORD pRxTs;
-
- if( !GetTs(
- ieee,
- (PTS_COMMON_INFO*)&pRxTs,
- dst,
- (u8)pDelBaParamSet->field.TID,
- RX_DIR,
- false) )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __FUNCTION__);
- return -1;
- }
-
- RxTsDeleteBA(ieee, pRxTs);
- }
- else
- {
- PTX_TS_RECORD pTxTs;
-
- if(!GetTs(
- ieee,
- (PTS_COMMON_INFO*)&pTxTs,
- dst,
- (u8)pDelBaParamSet->field.TID,
- TX_DIR,
- false) )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__);
- return -1;
- }
-
- pTxTs->bUsingBa = false;
- pTxTs->bAddBaReqInProgress = false;
- pTxTs->bAddBaReqDelayed = false;
- del_timer_sync(&pTxTs->TsAddBaTimer);
- TxTsDeleteBA(ieee, pTxTs);
- }
- return 0;
-}
-
-//
-// ADDBA initiate. This can only be called by TX side.
-//
-void
-TsInitAddBA(
- struct ieee80211_device* ieee,
- PTX_TS_RECORD pTS,
- u8 Policy,
- u8 bOverwritePending
- )
-{
- PBA_RECORD pBA = &pTS->TxPendingBARecord;
-
- if(pBA->bValid==true && bOverwritePending==false)
- return;
-
- // Set parameters to "Pending" variable set
- DeActivateBAEntry(ieee, pBA);
-
- pBA->DialogToken++; // DialogToken: Only keep the latest dialog token
- pBA->BaParamSet.field.AMSDU_Support = 0; // Do not support A-MSDU with A-MPDU now!!
- pBA->BaParamSet.field.BAPolicy = Policy; // Policy: Delayed or Immediate
- pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; // TID
- // BufferSize: This need to be set according to A-MPDU vector
- pBA->BaParamSet.field.BufferSize = 32; // BufferSize: This need to be set according to A-MPDU vector
- pBA->BaTimeoutValue = 0; // Timeout value: Set 0 to disable Timer
- pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; // Block Ack will start after 3 packets later.
-
- ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
-
- ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
-}
-
-void
-TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
-{
-
- if(TxRxSelect == TX_DIR)
- {
- PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
-
- if(TxTsDeleteBA(ieee, pTxTs))
- ieee80211_send_DELBA(
- ieee,
- pTsCommonInfo->Addr,
- (pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
- TxRxSelect,
- DELBA_REASON_END_BA);
- }
- else if(TxRxSelect == RX_DIR)
- {
- PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
- if(RxTsDeleteBA(ieee, pRxTs))
- ieee80211_send_DELBA(
- ieee,
- pTsCommonInfo->Addr,
- &pRxTs->RxAdmittedBARecord,
- TxRxSelect,
- DELBA_REASON_END_BA );
- }
-}
-/********************************************************************************************************************
- *function: BA setup timer
- * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
- * return: NULL
- * notice:
-********************************************************************************************************************/
-void BaSetupTimeOut(unsigned long data)
-{
- PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
-
- pTxTs->bAddBaReqInProgress = false;
- pTxTs->bAddBaReqDelayed = true;
- pTxTs->TxPendingBARecord.bValid = false;
-}
-
-void TxBaInactTimeout(unsigned long data)
-{
- PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
- struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
- TxTsDeleteBA(ieee, pTxTs);
- ieee80211_send_DELBA(
- ieee,
- pTxTs->TsCommonInfo.Addr,
- &pTxTs->TxAdmittedBARecord,
- TX_DIR,
- DELBA_REASON_TIMEOUT);
-}
-
-void RxBaInactTimeout(unsigned long data)
-{
- PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
- struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
-
- RxTsDeleteBA(ieee, pRxTs);
- ieee80211_send_DELBA(
- ieee,
- pRxTs->TsCommonInfo.Addr,
- &pRxTs->RxAdmittedBARecord,
- RX_DIR,
- DELBA_REASON_TIMEOUT);
- return ;
-}
-
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
deleted file mode 100644
index 171218914332..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
+++ /dev/null
@@ -1,530 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef _RTL819XU_HTTYPE_H_
-#define _RTL819XU_HTTYPE_H_
-
-//------------------------------------------------------------
-// The HT Capability element is present in beacons, association request,
-// reassociation request and probe response frames
-//------------------------------------------------------------
-
-//
-// Operation mode value
-//
-#define HT_OPMODE_NO_PROTECT 0
-#define HT_OPMODE_OPTIONAL 1
-#define HT_OPMODE_40MHZ_PROTECT 2
-#define HT_OPMODE_MIXED 3
-
-//
-// MIMO Power Save Setings
-//
-#define MIMO_PS_STATIC 0
-#define MIMO_PS_DYNAMIC 1
-#define MIMO_PS_NOLIMIT 3
-
-
-//
-// There should be 128 bits to cover all of the MCS rates. However, since
-// 8190 does not support too much rates, one integer is quite enough.
-//
-
-#define sHTCLng 4
-
-
-#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff
-#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00
-#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
-
-
-typedef enum _HT_MCS_RATE{
- HT_MCS0 = 0x00000001,
- HT_MCS1 = 0x00000002,
- HT_MCS2 = 0x00000004,
- HT_MCS3 = 0x00000008,
- HT_MCS4 = 0x00000010,
- HT_MCS5 = 0x00000020,
- HT_MCS6 = 0x00000040,
- HT_MCS7 = 0x00000080,
- HT_MCS8 = 0x00000100,
- HT_MCS9 = 0x00000200,
- HT_MCS10 = 0x00000400,
- HT_MCS11 = 0x00000800,
- HT_MCS12 = 0x00001000,
- HT_MCS13 = 0x00002000,
- HT_MCS14 = 0x00004000,
- HT_MCS15 = 0x00008000,
- // Do not define MCS32 here although 8190 support MCS32
-}HT_MCS_RATE,*PHT_MCS_RATE;
-
-//
-// Represent Channel Width in HT Capabilities
-//
-typedef enum _HT_CHANNEL_WIDTH{
- HT_CHANNEL_WIDTH_20 = 0,
- HT_CHANNEL_WIDTH_20_40 = 1,
-}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
-
-//
-// Represent Extention Channel Offset in HT Capabilities
-// This is available only in 40Mhz mode.
-//
-typedef enum _HT_EXTCHNL_OFFSET{
- HT_EXTCHNL_OFFSET_NO_EXT = 0,
- HT_EXTCHNL_OFFSET_UPPER = 1,
- HT_EXTCHNL_OFFSET_NO_DEF = 2,
- HT_EXTCHNL_OFFSET_LOWER = 3,
-}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
-
-typedef enum _CHNLOP{
- CHNLOP_NONE = 0, // No Action now
- CHNLOP_SCAN = 1, // Scan in progress
- CHNLOP_SWBW = 2, // Bandwidth switching in progress
- CHNLOP_SWCHNL = 3, // Software Channel switching in progress
-} CHNLOP, *PCHNLOP;
-
-// Determine if the Channel Operation is in progress
-#define CHHLOP_IN_PROGRESS(_pHTInfo) \
- ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
-
-/*
-typedef union _HT_CAPABILITY{
- u16 ShortData;
- u8 CharData[2];
- struct
- {
- u16 AdvCoding:1;
- u16 ChlWidth:1;
- u16 MimoPwrSave:2;
- u16 GreenField:1;
- u16 ShortGI20Mhz:1;
- u16 ShortGI40Mhz:1;
- u16 STBC:1;
- u16 BeamForm:1;
- u16 DelayBA:1;
- u16 MaxAMSDUSize:1;
- u16 DssCCk:1;
- u16 PSMP:1;
- u16 Rsvd:3;
- }Field;
-}HT_CAPABILITY, *PHT_CAPABILITY;
-
-typedef union _HT_CAPABILITY_MACPARA{
- u8 ShortData;
- u8 CharData[1];
- struct
- {
- u8 MaxRxAMPDU:2;
- u8 MPDUDensity:2;
- u8 Rsvd:4;
- }Field;
-}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
-*/
-
-typedef enum _HT_ACTION{
- ACT_RECOMMAND_WIDTH = 0,
- ACT_MIMO_PWR_SAVE = 1,
- ACT_PSMP = 2,
- ACT_SET_PCO_PHASE = 3,
- ACT_MIMO_CHL_MEASURE = 4,
- ACT_RECIPROCITY_CORRECT = 5,
- ACT_MIMO_CSI_MATRICS = 6,
- ACT_MIMO_NOCOMPR_STEER = 7,
- ACT_MIMO_COMPR_STEER = 8,
- ACT_ANTENNA_SELECT = 9,
-} HT_ACTION, *PHT_ACTION;
-
-
-/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
-typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
- SC_MODE_DUPLICATE = 0,
- SC_MODE_LOWER = 1,
- SC_MODE_UPPER = 2,
- SC_MODE_FULL40MHZ = 3,
-}HT_BW40_SC_E;
-
-typedef struct _HT_CAPABILITY_ELE{
-
- //HT capability info
- u8 AdvCoding:1;
- u8 ChlWidth:1;
- u8 MimoPwrSave:2;
- u8 GreenField:1;
- u8 ShortGI20Mhz:1;
- u8 ShortGI40Mhz:1;
- u8 TxSTBC:1;
- u8 RxSTBC:2;
- u8 DelayBA:1;
- u8 MaxAMSDUSize:1;
- u8 DssCCk:1;
- u8 PSMP:1;
- u8 Rsvd1:1;
- u8 LSigTxopProtect:1;
-
- //MAC HT parameters info
- u8 MaxRxAMPDUFactor:2;
- u8 MPDUDensity:3;
- u8 Rsvd2:3;
-
- //Supported MCS set
- u8 MCS[16];
-
-
- //Extended HT Capability Info
- u16 ExtHTCapInfo;
-
- //TXBF Capabilities
- u8 TxBFCap[4];
-
- //Antenna Selection Capabilities
- u8 ASCap;
-
-} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
-
-//------------------------------------------------------------
-// The HT Information element is present in beacons
-// Only AP is required to include this element
-//------------------------------------------------------------
-
-typedef struct _HT_INFORMATION_ELE{
- u8 ControlChl;
-
- u8 ExtChlOffset:2;
- u8 RecommemdedTxWidth:1;
- u8 RIFS:1;
- u8 PSMPAccessOnly:1;
- u8 SrvIntGranularity:3;
-
- u8 OptMode:2;
- u8 NonGFDevPresent:1;
- u8 Revd1:5;
- u8 Revd2:8;
-
- u8 Rsvd3:6;
- u8 DualBeacon:1;
- u8 DualCTSProtect:1;
-
- u8 SecondaryBeacon:1;
- u8 LSigTxopProtectFull:1;
- u8 PcoActive:1;
- u8 PcoPhase:1;
- u8 Rsvd4:4;
-
- u8 BasicMSC[16];
-} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
-
-//
-// MIMO Power Save control field.
-// This is appear in MIMO Power Save Action Frame
-//
-typedef struct _MIMOPS_CTRL{
- u8 MimoPsEnable:1;
- u8 MimoPsMode:1;
- u8 Reserved:6;
-} MIMOPS_CTRL, *PMIMOPS_CTRL;
-
-typedef enum _HT_SPEC_VER{
- HT_SPEC_VER_IEEE = 0,
- HT_SPEC_VER_EWC = 1,
-}HT_SPEC_VER, *PHT_SPEC_VER;
-
-typedef enum _HT_AGGRE_MODE_E{
- HT_AGG_AUTO = 0,
- HT_AGG_FORCE_ENABLE = 1,
- HT_AGG_FORCE_DISABLE = 2,
-}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variables when card is
-// configured as non-AP STA mode. **Note** Current_xxx should be set
-// to default value in HTInitializeHTInfo()
-//------------------------------------------------------------
-
-typedef struct _RT_HIGH_THROUGHPUT{
- u8 bEnableHT;
- u8 bCurrentHTSupport;
-
- u8 bRegBW40MHz; // Tx 40MHz channel capablity
- u8 bCurBW40MHz; // Tx 40MHz channel capability
-
- u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz
- u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
-
- u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
- u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
-
- u8 bRegSuppCCK; // Tx CCK rate capability
- u8 bCurSuppCCK; // Tx CCK rate capability
-
- // 802.11n spec version for "peer"
- HT_SPEC_VER ePeerHTSpecVer;
-
-
- // HT related information for "Self"
- HT_CAPABILITY_ELE SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
- HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
-
- // HT related information for "Peer"
- u8 PeerHTCapBuf[32];
- u8 PeerHTInfoBuf[32];
-
-
- // A-MSDU related
- u8 bAMSDU_Support; // This indicates Tx A-MSDU capability
- u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability
- u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
- u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
-
-
- // AMPDU related <2006.08.10 Emily>
- u8 bAMPDUEnable; // This indicate Tx A-MPDU capability
- u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability
- u8 AMPDU_Factor; // This indicate Tx A-MPDU capability
- u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability
- u8 MPDU_Density; // This indicate Tx A-MPDU capability
- u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability
-
- // Forced A-MPDU enable
- HT_AGGRE_MODE_E ForcedAMPDUMode;
- u8 ForcedAMPDUFactor;
- u8 ForcedMPDUDensity;
-
- // Forced A-MSDU enable
- HT_AGGRE_MODE_E ForcedAMSDUMode;
- u16 ForcedAMSDUMaxSize;
-
- u8 bForcedShortGI;
-
- u8 CurrentOpMode;
-
- // MIMO PS related
- u8 SelfMimoPs;
- u8 PeerMimoPs;
-
- // 40MHz Channel Offset settings.
- HT_EXTCHNL_OFFSET CurSTAExtChnlOffset;
- u8 bCurTxBW40MHz; // If we use 40 MHz to Tx
- u8 PeerBandwidth;
-
- // For Bandwidth Switching
- u8 bSwBwInProgress;
- CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
- u8 SwBwStep;
- //struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here.
-
- // For Realtek proprietary A-MPDU factor for aggregation
- u8 bRegRT2RTAggregation;
- u8 RT2RT_HT_Mode;
- u8 bCurrentRT2RTAggregation;
- u8 bCurrentRT2RTLongSlotTime;
- u8 szRT2RTAggBuffer[10];
-
- // Rx Reorder control
- u8 bRegRxReorderEnable;
- u8 bCurRxReorderEnable;
- u8 RxReorderWinSize;
- u8 RxReorderPendingTime;
- u16 RxReorderDropCounter;
-
-
- // Add for Broadcom(Linksys) IOT. Joseph
- u8 bIsPeerBcm;
-
- // For IOT issue.
- u8 IOTPeer;
- u32 IOTAction;
- u8 IOTRaFunc;
-} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
-
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each Sta"
-// when card is configured as "AP mode"
-//------------------------------------------------------------
-
-typedef struct _RT_HTINFO_STA_ENTRY{
- u8 bEnableHT;
-
- u8 bSupportCck;
-
- u16 AMSDU_MaxSize;
-
- u8 AMPDU_Factor;
- u8 MPDU_Density;
-
- u8 HTHighestOperaRate;
-
- u8 bBw40MHz;
-
- u8 MimoPs;
-
- u8 McsRateSet[16];
-
-
-}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
-
-
-
-
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each AP"
-// when card is configured as "STA mode"
-//------------------------------------------------------------
-
-typedef struct _BSS_HT{
-
- u8 bdSupportHT;
-
- // HT related elements
- u8 bdHTCapBuf[32];
- u16 bdHTCapLen;
- u8 bdHTInfoBuf[32];
- u16 bdHTInfoLen;
-
- HT_SPEC_VER bdHTSpecVer;
- HT_CHANNEL_WIDTH bdBandWidth;
-
- u8 bdRT2RTAggregation;
- u8 bdRT2RTLongSlotTime;
- u8 RT2RT_HT_Mode;
- bool bdHT1R;
-} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
-
-typedef struct _MIMO_RSSI{
- u32 EnableAntenna;
- u32 AntennaA;
- u32 AntennaB;
- u32 AntennaC;
- u32 AntennaD;
- u32 Average;
-}MIMO_RSSI, *PMIMO_RSSI;
-
-typedef struct _MIMO_EVM{
- u32 EVM1;
- u32 EVM2;
-}MIMO_EVM, *PMIMO_EVM;
-
-typedef struct _FALSE_ALARM_STATISTICS{
- u32 Cnt_Parity_Fail;
- u32 Cnt_Rate_Illegal;
- u32 Cnt_Crc8_fail;
- u32 Cnt_all;
-}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
-
-
-extern u8 MCS_FILTER_ALL[16];
-extern u8 MCS_FILTER_1SS[16];
-
-/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
- STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
- to add a macro to judge wireless mode. */
-#define PICK_RATE(_nLegacyRate, _nMcsRate) \
- (_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
-/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
-#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK
-
-#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \
- ((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
- (LegacyRate):\
- (PICK_RATE(LegacyRate, HTRate))
-
-
-
-// MCS Bw 40 {1~7, 12~15,32}
-#define RATE_ADPT_1SS_MASK 0xFF
-#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
-#define RATE_ADPT_MCS32_MASK 0x01
-
-#define IS_11N_MCS_RATE(rate) (rate&0x80)
-
-typedef enum _HT_AGGRE_SIZE{
- HT_AGG_SIZE_8K = 0,
- HT_AGG_SIZE_16K = 1,
- HT_AGG_SIZE_32K = 2,
- HT_AGG_SIZE_64K = 3,
-}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
-
-/* Indicate different AP vendor for IOT issue */
-typedef enum _HT_IOT_PEER
-{
- HT_IOT_PEER_UNKNOWN = 0,
- HT_IOT_PEER_REALTEK = 1,
- HT_IOT_PEER_REALTEK_92SE = 2,
- HT_IOT_PEER_BROADCOM = 3,
- HT_IOT_PEER_RALINK = 4,
- HT_IOT_PEER_ATHEROS = 5,
- HT_IOT_PEER_CISCO= 6,
- HT_IOT_PEER_MARVELL=7,
- HT_IOT_PEER_92U_SOFTAP = 8,
- HT_IOT_PEER_SELF_SOFTAP = 9,
- HT_IOT_PEER_MAX = 10,
-}HT_IOT_PEER_E, *PHTIOT_PEER_E;
-
-//
-// IOT Action for different AP
-//
-typedef enum _HT_IOT_ACTION{
- HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
- HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
- HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
- HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
- HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
- HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
- HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
- HT_IOT_ACT_CDD_FSYNC = 0x00000080,
- HT_IOT_ACT_PURE_N_MODE = 0x00000100,
- HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
- HT_IOT_ACT_FORCED_RTS = 0x00000400,
- HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
- HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000,
- HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000,
- HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
-
- HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
- HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
- HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000,
- HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
- HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000,
- HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
-
- HT_IOT_ACT_MID_HIGHPOWER = 0x00400000,
- HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
-
- HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000,
- HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000,
- HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000,
-}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
-
-typedef enum _HT_IOT_RAFUNC{
- HT_IOT_RAFUNC_DISABLE_ALL = 0x00,
- HT_IOT_RAFUNC_PEER_1R = 0x01,
- HT_IOT_RAFUNC_TX_AMSDU = 0x02,
-}HT_IOT_RAFUNC, *PHT_IOT_RAFUNC;
-
-typedef enum _RT_HT_CAP{
- RT_HT_CAP_USE_TURBO_AGGR = 0x01,
- RT_HT_CAP_USE_LONG_PREAMBLE = 0x02,
- RT_HT_CAP_USE_AMPDU = 0x04,
- RT_HT_CAP_USE_WOW = 0x8,
- RT_HT_CAP_USE_SOFTAP = 0x10,
- RT_HT_CAP_USE_92SE = 0x20,
-}RT_HT_CAPBILITY, *PRT_HT_CAPBILITY;
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
deleted file mode 100644
index cfd9a1a5b38d..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
+++ /dev/null
@@ -1,1725 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "ieee80211.h"
-#include "rtl819x_HT.h"
-u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-u16 MCS_DATA_RATE[2][2][77] =
- { { {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
- 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
- 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
- 195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
- 286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},
- {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
- 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
- 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
- 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
- 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477} },
- { {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
- 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
- 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
- 405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
- 594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891},
- {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
- 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
- 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
- 450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
- 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} }
- };
-
-static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
-static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
-static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
-static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
-static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
-static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
-static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
-static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
-static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
-static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
-static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
-static u8 NETGEAR_BROADCOM[3] = {0x00, 0x1f, 0x33};
-static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
-
-/********************************************************************************************************************
- *function: This function update default settings in pHTInfo structure
- * input: PRT_HIGH_THROUGHPUT pHTInfo
- * output: none
- * return: none
- * notice: These value need be modified if any changes.
- * *****************************************************************************************************************/
-void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- // ShortGI support
- pHTInfo->bRegShortGI20MHz= 1;
- pHTInfo->bRegShortGI40MHz= 1;
-
- // 40MHz channel support
- pHTInfo->bRegBW40MHz = 1;
-
- // CCK rate support in 40MHz channel
- if(pHTInfo->bRegBW40MHz)
- pHTInfo->bRegSuppCCK = 1;
- else
- pHTInfo->bRegSuppCCK = true;
-
- // AMSDU related
- pHTInfo->nAMSDU_MaxSize = 7935UL;
- pHTInfo->bAMSDU_Support = 0;
-
- // AMPDU related
- pHTInfo->bAMPDUEnable = 1; //YJ,test,090311
- pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)
- pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
-
- // MIMO Power Save
- pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
- if(pHTInfo->SelfMimoPs == 2)
- pHTInfo->SelfMimoPs = 3;
- // 8190 only. Assign rate operation mode to firmware
- ieee->bTxDisableRateFallBack = 0;
- ieee->bTxUseDriverAssingedRate = 0;
-
-#ifdef TO_DO_LIST
- // 8190 only. Assign duration operation mode to firmware
- pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;
-#endif
- // 8190 only, Realtek proprietary aggregation mode
- // Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others
- pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others
-
- // For Rx Reorder Control
- pHTInfo->bRegRxReorderEnable = 1;//YJ,test,090311
- pHTInfo->RxReorderWinSize = 64;
- pHTInfo->RxReorderPendingTime = 30;
-
-
-
-}
-/********************************************************************************************************************
- *function: This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
- * input: u8* CapIE //Capability IE to be printed out
- * u8* TitleString //mainly print out caller function
- * output: none
- * return: none
- * notice: Driver should not print out this message by default.
- * *****************************************************************************************************************/
-void HTDebugHTCapability(u8* CapIE, u8* TitleString )
-{
-
- static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
- PHT_CAPABILITY_ELE pCapELE;
-
- if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
- {
- //EWC IE
- IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
- pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
- }else
- pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
- pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
- return;
-
-}
-/********************************************************************************************************************
- *function: This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
- * input: u8* InfoIE //Capability IE to be printed out
- * u8* TitleString //mainly print out caller function
- * output: none
- * return: none
- * notice: Driver should not print out this message by default.
- * *****************************************************************************************************************/
-void HTDebugHTInfo(u8* InfoIE, u8* TitleString)
-{
-
- static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily
- PHT_INFORMATION_ELE pHTInfoEle;
-
- if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
- {
- // Not EWC IE
- IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
- pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);
- }else
- pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
-
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
- switch(pHTInfoEle->ExtChlOffset)
- {
- case 0:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");
- break;
- case 1:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
- break;
- case 2:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");
- break;
- case 3:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");
- break;
- }
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
- switch(pHTInfoEle->OptMode)
- {
- case 0:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");
- break;
- case 1:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
- break;
- case 2:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");
- break;
- case 3:
- IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");
- break;
- }
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
- pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
- return;
-}
-
-/*
-* Return: true if station in half n mode and AP supports 40 bw
-*/
-bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee)
-{
- bool retValue = false;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode
- retValue = false;
- else if(pHTInfo->bRegBW40MHz == false) // station supports 40 bw
- retValue = false;
- else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode
- retValue = false;
- else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
- retValue = true;
- else
- retValue = false;
-
- return retValue;
-}
-
-bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz)
-{
- bool retValue = false;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode
- retValue = false;
- else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode
- retValue = false;
- else if(is40MHz) // ap support 40 bw
- {
- if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
- retValue = true;
- else
- retValue = false;
- }
- else
- {
- if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
- retValue = true;
- else
- retValue = false;
- }
-
- return retValue;
-}
-
-u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate)
-{
-
- u8 is40MHz;
- u8 isShortGI;
-
- is40MHz = (IsHTHalfNmode40Bandwidth(ieee))?1:0;
- isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
-
- return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
-}
-
-
-u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- u8 is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
- u8 isShortGI = (pHTInfo->bCurBW40MHz)?
- ((pHTInfo->bCurShortGI40MHz)?1:0):
- ((pHTInfo->bCurShortGI20MHz)?1:0);
- return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
-}
-
-/********************************************************************************************************************
- *function: This function returns current datarate.
- * input: struct ieee80211_device* ieee
- * u8 nDataRate
- * output: none
- * return: tx rate
- * notice: quite unsure about how to use this function //wb
- * *****************************************************************************************************************/
-u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
-{
- u16 CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
- u8 is40MHz = 0;
- u8 isShortGI = 0;
-
- if(nDataRate < 12)
- {
- return CCKOFDMRate[nDataRate];
- }
- else
- {
- if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
- {
- is40MHz = 0;
- isShortGI = 0;
-
- }
- else if(nDataRate >=0x20 && nDataRate <= 0x2f ) //(27, 44)
- {
- is40MHz = 1;
- isShortGI = 0;
-
- }
- else if(nDataRate >= 0x30 && nDataRate <= 0x3f ) //(43, 60)
- {
- is40MHz = 0;
- isShortGI = 1;
-
- }
- else if(nDataRate >= 0x40 && nDataRate <= 0x4f ) //(59, 76)
- {
- is40MHz = 1;
- isShortGI = 1;
-
- }
- return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
- }
-}
-
-
-
-bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
-{
- bool retValue = false;
- struct ieee80211_network* net = &ieee->current_network;
-
- if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
- (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
- (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
- (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
- (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
- (net->ralink_cap_exist))
- retValue = true;
- else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
- (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
- (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
- (net->broadcom_cap_exist))
- retValue = true;
- else if(net->bssht.bdRT2RTAggregation)
- retValue = true;
- else
- retValue = false;
-
- return retValue;
-}
-
-/********************************************************************************************************************
- *function: This function returns peer IOT.
- * input: struct ieee80211_device* ieee
- * output: none
- * return:
- * notice:
- * *****************************************************************************************************************/
-void HTIOTPeerDetermine(struct ieee80211_device* ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- struct ieee80211_network* net = &ieee->current_network;
- //FIXME: need to decide 92U_SOFTAP //LZM,090320
- if(net->bssht.bdRT2RTAggregation){
- pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
- if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE){
- pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
- }
- if(net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP){
- pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
- }
- }
- else if(net->broadcom_cap_exist)
- pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
- else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
- (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
- (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0))
- pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
- else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
- (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
- (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
- (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
- (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
- net->ralink_cap_exist)
- pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
- else if((net->atheros_cap_exist )||
- (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0)||
- (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0))
- pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
- else if ((memcmp(net->bssid, CISCO_BROADCOM, 3)==0)||net->cisco_cap_exist)
- pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
- else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
- net->marvell_cap_exist)
- pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
- else
- pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
-
- IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
-}
-/********************************************************************************************************************
- *function: Check whether driver should declare received rate up to MCS13 only since some chipset is not good
- * at receiving MCS14~15 frame from some AP.
- * input: struct ieee80211_device* ieee
- * u8 * PeerMacAddr
- * output: none
- * return: return 1 if driver should declare MCS13 only(otherwise return 0)
- * *****************************************************************************************************************/
-u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
-{
- u8 ret = 0;
-
- return ret;
- }
-
-
-/**
-* Function: HTIOTActIsDisableMCS15
-*
-* Overview: Check whether driver should declare capability of receving MCS15
-*
-* Input:
-* PADAPTER Adapter,
-*
-* Output: None
-* Return: true if driver should disable MCS15
-* 2008.04.15 Emily
-*/
-bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
-{
- bool retValue = false;
- return retValue;
-}
-
-/**
-* Function: HTIOTActIsDisableMCSTwoSpatialStream
-*
-* Overview: Check whether driver should declare capability of receving All 2 ss packets
-*
-* Input:
-* PADAPTER Adapter,
-*
-* Output: None
-* Return: true if driver should disable all two spatial stream packet
-* 2008.04.21 Emily
-*/
-bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee)
-{
- bool retValue = false;
-#ifdef TODO
- // Apply for 819u only
-//#if (HAL_CODE_BASE==RTL8192)
-
- //This rule only apply to Belkin(Ralink) AP
- if(IS_UNDER_11N_AES_MODE(Adapter))
- {
- if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) ||
- (PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) ||
- (PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0))
- {
- //Set True to disable this function. Disable by default, Emily, 2008.04.23
- retValue = false;
- }
- }
-
-//#endif
-#endif
-#if 1
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- if(ieee->is_ap_in_wep_tkip && ieee->is_ap_in_wep_tkip(ieee->dev))
- {
- if( (pHTInfo->IOTPeer != HT_IOT_PEER_ATHEROS) &&
- (pHTInfo->IOTPeer != HT_IOT_PEER_UNKNOWN) &&
- (pHTInfo->IOTPeer != HT_IOT_PEER_MARVELL) )
- retValue = true;
- }
-#endif
- return retValue;
-}
-
-/********************************************************************************************************************
- *function: Check whether driver should disable EDCA turbo mode
- * input: struct ieee80211_device* ieee
- * u8* PeerMacAddr
- * output: none
- * return: return 1 if driver should disable EDCA turbo mode(otherwise return 0)
- * *****************************************************************************************************************/
-u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* ieee, u8* PeerMacAddr)
-{
- u8 retValue = false; // default enable EDCA Turbo mode.
- // Set specific EDCA parameter for different AP in DM handler.
-
- return retValue;
-}
-
-/********************************************************************************************************************
- *function: Check whether we need to use OFDM to sned MGNT frame for broadcom AP
- * input: struct ieee80211_network *network //current network we live
- * output: none
- * return: return 1 if true
- * *****************************************************************************************************************/
-u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- // 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
- // 2008/01/28 MH We must prevent that we select null bssid to link.
-
- if(network->broadcom_cap_exist)
- {
- retValue = 1;
- }
-
- return retValue;
-}
-
-u8 HTIOTActIsForcedCTS2Self(struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- if(network->marvell_cap_exist)
- {
- retValue = 1;
- }
-
- return retValue;
-}
-
-u8 HTIOTActIsForcedRTSCTS(struct ieee80211_device *ieee, struct ieee80211_network *network)
-{
- u8 retValue = 0;
- printk("============>%s(), %d\n", __FUNCTION__, network->realtek_cap_exit);
- // Force protection
- if(ieee->pHTInfo->bCurrentHTSupport)
- {
- //if(!network->realtek_cap_exit)
- if((ieee->pHTInfo->IOTPeer != HT_IOT_PEER_REALTEK)&&
- (ieee->pHTInfo->IOTPeer != HT_IOT_PEER_REALTEK_92SE))
- {
- if((ieee->pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION) == 0)
- retValue = 1;
- }
- }
- return retValue;
-}
-
-u8
-HTIOTActIsForcedAMSDU8K(struct ieee80211_device *ieee, struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- return retValue;
-}
-
-u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
-{
- u8 retValue = 0;
- if( (memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
- (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
- (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
- {
- retValue = 1;
- }
- return retValue;
-}
-
-/*
- * 819xS single chip b-cut series cannot handle BAR
- */
-u8
-HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
-{
- u8 retValue = 0;
- //if(IS_HARDWARE_TYPE_8192SE(Adapter) ||
- // IS_HARDWARE_TYPE_8192SU(Adapter)
- //)
- {
- // Do not reject ADDBA REQ because some of the AP may
- // keep on sending ADDBA REQ qhich cause DHCP fail or ping loss!
- // by HPFan, 2008/12/30
-
- //if(pBssDesc->Vender == HT_IOT_PEER_MARVELL)
- // return FALSE;
-
- }
-
- return retValue;
-
-}
-
-/*
- * EDCA parameters bias on downlink
- */
- u8
- HTIOTActIsEDCABiasRx(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- {
- if(pHTInfo->IOTPeer==HT_IOT_PEER_ATHEROS ||
- pHTInfo->IOTPeer==HT_IOT_PEER_BROADCOM ||
- pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
- return 1;
-
- }
- return retValue;
-}
-
-u8
-HTIOTActDisableShortGI(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK)
- {
- retValue = 1;
- }
-
- return retValue;
-}
-
-u8
-HTIOTActDisableHighPower(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- if(pHTInfo->IOTPeer==HT_IOT_PEER_RALINK ||
- pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK ||
- pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK_92SE)
- {
- retValue = 1;
- }
-
- return retValue;
-}
-
-void
-HTIOTActDetermineRaFunc(struct ieee80211_device* ieee, bool bPeerRx2ss)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL;
-
- if(pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
- pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R;
-
- if(pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
- pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU;
-
- printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!IOTRaFunc = %8.8x\n", pHTInfo->IOTRaFunc);
-}
-
-
-u8
-HTIOTActIsDisableTx40MHz(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- if( (KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP104 == ieee->group_key_type) ||
- (KEY_TYPE_WEP40 == ieee->group_key_type) ||
- (KEY_TYPE_TKIP == ieee->pairwise_key_type) )
- {
- if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
- retValue = 1;
- }
-
- return retValue;
-}
-
-u8
-HTIOTActIsTxNoAggregation(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- if( (KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP104 == ieee->group_key_type) ||
- (KEY_TYPE_WEP40 == ieee->group_key_type) ||
- (KEY_TYPE_TKIP == ieee->pairwise_key_type) )
- {
- if(pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK)
- retValue = 1;
- }
-
- return retValue;
-}
-
-
-u8
-HTIOTActIsDisableTx2SS(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- u8 retValue = 0;
-
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- if( (KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
- (KEY_TYPE_WEP104 == ieee->group_key_type) ||
- (KEY_TYPE_WEP40 == ieee->group_key_type) ||
- (KEY_TYPE_TKIP == ieee->pairwise_key_type) )
- {
- if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
- retValue = 1;
- }
-
- return retValue;
-}
-
-
-bool HTIOCActAllowPeerAggOnePacket(struct ieee80211_device* ieee,struct ieee80211_network *network)
-{
- bool retValue = false;
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
- {
- if((memcmp(network->bssid, NETGEAR_BROADCOM, 3)==0)
- && (network->bssht.bdBandWidth == HT_CHANNEL_WIDTH_20_40))
- return true;
- }
- return retValue;
-}
-
-void HTResetIOTSetting(
- PRT_HIGH_THROUGHPUT pHTInfo
-)
-{
- pHTInfo->IOTAction = 0;
- pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
- pHTInfo->IOTRaFunc = 0;
-}
-
-
-/********************************************************************************************************************
- *function: Construct Capablility Element in Beacon... if HTEnable is turned on
- * input: struct ieee80211_device* ieee
- * u8* posHTCap //pointer to store Capability Ele
- * u8* len //store length of CE
- * u8 IsEncrypt //whether encrypt, needed further
- * output: none
- * return: none
- * notice: posHTCap can't be null and should be initialized before.
- * *****************************************************************************************************************/
-void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt)
-{
- PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo;
- PHT_CAPABILITY_ELE pCapELE = NULL;
-
- if ((posHTCap == NULL) || (pHT == NULL))
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
- return;
- }
- memset(posHTCap, 0, *len);
- if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
- {
- u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
- memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
- pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
- }else
- {
- pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
- }
-
-
- //HT capability info
- pCapELE->AdvCoding = 0; // This feature is not supported now!!
- if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
- {
- pCapELE->ChlWidth = 0;
- }
- else
- {
- pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
- }
-
- pCapELE->MimoPwrSave = pHT->SelfMimoPs;
- pCapELE->GreenField = 0; // This feature is not supported now!!
- pCapELE->ShortGI20Mhz = 1; // We can receive Short GI!!
- pCapELE->ShortGI40Mhz = 1; // We can receive Short GI!!
-
- pCapELE->TxSTBC = 1;
- pCapELE->RxSTBC = 0;
- pCapELE->DelayBA = 0; // Do not support now!!
- pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
- pCapELE->DssCCk = ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
- pCapELE->PSMP = 0; // Do not support now!!
- pCapELE->LSigTxopProtect = 0; // Do not support now!!
-
-
- //MAC HT parameters info
- // TODO: Nedd to take care of this part
- IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
-
- if( IsEncrypt)
- {
- pCapELE->MPDUDensity = 7; // 8us
- pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K
- }
- else
- {
- pCapELE->MaxRxAMPDUFactor = 3; // 2 is for 32 K and 3 is 64K
- pCapELE->MPDUDensity = 0; // no density
- }
-
- //Supported MCS set
- memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
- if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
- pCapELE->MCS[1] &= 0x7f;
-
- if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
- pCapELE->MCS[1] &= 0xbf;
-
- if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
- pCapELE->MCS[1] &= 0x00;
-
- // 2008.06.12
- // For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
- if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
- {
- int i;
- for(i = 1; i< 16; i++)
- pCapELE->MCS[i] = 0;
- }
-
- //Extended HT Capability Info
- memset(&pCapELE->ExtHTCapInfo, 0, 2);
-
-
- //TXBF Capabilities
- memset(pCapELE->TxBFCap, 0, 4);
-
- //Antenna Selection Capabilities
- pCapELE->ASCap = 0;
-//add 2 to give space for element ID and len when construct frames
- if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
- *len = 30 + 2;
- else
- *len = 26 + 2;
-
- return;
-
-}
-/********************************************************************************************************************
- *function: Construct Information Element in Beacon... if HTEnable is turned on
- * input: struct ieee80211_device* ieee
- * u8* posHTCap //pointer to store Information Ele
- * u8* len //store len of
- * u8 IsEncrypt //whether encrypt, needed further
- * output: none
- * return: none
- * notice: posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
- * *****************************************************************************************************************/
-void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt)
-{
- PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo;
- PHT_INFORMATION_ELE pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
- if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
- return;
- }
-
- memset(posHTInfo, 0, *len);
- if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
- {
- pHTInfoEle->ControlChl = ieee->current_network.channel;
- pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT:
- (ieee->current_network.channel<=6)?
- HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
- pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz;
- pHTInfoEle->RIFS = 0;
- pHTInfoEle->PSMPAccessOnly = 0;
- pHTInfoEle->SrvIntGranularity = 0;
- pHTInfoEle->OptMode = pHT->CurrentOpMode;
- pHTInfoEle->NonGFDevPresent = 0;
- pHTInfoEle->DualBeacon = 0;
- pHTInfoEle->SecondaryBeacon = 0;
- pHTInfoEle->LSigTxopProtectFull = 0;
- pHTInfoEle->PcoActive = 0;
- pHTInfoEle->PcoPhase = 0;
-
- memset(pHTInfoEle->BasicMSC, 0, 16);
-
-
- *len = 22 + 2; //same above
-
- }
- else
- {
- //STA should not generate High Throughput Information Element
- *len = 0;
- }
- return;
-}
-
-/*
- * According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance
- * if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2
- * (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set
- * limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP
- * will be much less than the traffic stream from AP to STA if both of the stream runs concurrently
- * at the same time.
- *
- * Frame Format
- * Element ID Length OUI Type1 Reserved
- * 1 byte 1 byte 3 bytes 1 byte 1 byte
- *
- * OUI = 0x00, 0xe0, 0x4c,
- * Type = 0x02
- * Reserved = 0x00
- *
- * 2007.8.21 by Emily
-*/
-/********************************************************************************************************************
- *function: Construct Information Element in Beacon... in RT2RT condition
- * input: struct ieee80211_device* ieee
- * u8* posRT2RTAgg //pointer to store Information Ele
- * u8* len //store len
- * output: none
- * return: none
- * notice:
- * *****************************************************************************************************************/
-void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len)
-{
- if (posRT2RTAgg == NULL) {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
- return;
- }
- memset(posRT2RTAgg, 0, *len);
- *posRT2RTAgg++ = 0x00;
- *posRT2RTAgg++ = 0xe0;
- *posRT2RTAgg++ = 0x4c;
- *posRT2RTAgg++ = 0x02;
- *posRT2RTAgg++ = 0x01;
- *posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
-
- if(ieee->bSupportRemoteWakeUp) {
- *posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
- }
-
- *len = 6 + 2;
- return;
-#ifdef TODO
-#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
- /*
- //Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this
- section of code.
- if(IS_UNDER_11N_AES_MODE(Adapter))
- {
- posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
- }else
- {
- posRT2RTAgg->Octet[5] &= 0xfb;
- }
- */
-
-#else
-#endif
-
- posRT2RTAgg->Length = 6;
-#endif
-
-
-
-
-}
-
-
-/********************************************************************************************************************
- *function: Pick the right Rate Adaptive table to use
- * input: struct ieee80211_device* ieee
- * u8* pOperateMCS //A pointer to MCS rate bitmap
- * return: always we return true
- * notice:
- * *****************************************************************************************************************/
-u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS)
-{
- u8 i;
- if (pOperateMCS == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
- return false;
- }
-
- switch(ieee->mode)
- {
- case IEEE_A:
- case IEEE_B:
- case IEEE_G:
- //legacy rate routine handled at selectedrate
-
- //no MCS rate
- for(i=0;i<=15;i++){
- pOperateMCS[i] = 0;
- }
- break;
-
- case IEEE_N_24G: //assume CCK rate ok
- case IEEE_N_5G:
- // Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
- // Legacy part shall be handled at SelectRateSet().
-
- //HT part
- // TODO: may be different if we have different number of antenna
- pOperateMCS[0] &=RATE_ADPT_1SS_MASK; //support MCS 0~7
- pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
- pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
- break;
-
- //should never reach here
- default:
-
- break;
-
- }
-
- return true;
-}
-
-/*
-* Description:
-* This function will get the highest speed rate in input MCS set.
-*
-* /param Adapter Pionter to Adapter entity
-* pMCSRateSet Pointer to MCS rate bitmap
-* pMCSFilter Pointer to MCS rate filter
-*
-* /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
-*
-*/
-/********************************************************************************************************************
- *function: This function will get the highest speed rate in input MCS set.
- * input: struct ieee80211_device* ieee
- * u8* pMCSRateSet //Pointer to MCS rate bitmap
- * u8* pMCSFilter //Pointer to MCS rate filter
- * return: Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
- * notice:
- * *****************************************************************************************************************/
-u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter)
-{
- u8 i, j;
- u8 bitMap;
- u8 mcsRate = 0;
- u8 availableMcsRate[16];
- if (pMCSRateSet == NULL || pMCSFilter == NULL)
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
- return false;
- }
- for(i=0; i<16; i++)
- availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
-
- for(i = 0; i < 16; i++)
- {
- if(availableMcsRate[i] != 0)
- break;
- }
- if(i == 16)
- return false;
-
- for(i = 0; i < 16; i++)
- {
- if(availableMcsRate[i] != 0)
- {
- bitMap = availableMcsRate[i];
- for(j = 0; j < 8; j++)
- {
- if((bitMap%2) != 0)
- {
- if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
- mcsRate = (8*i+j);
- }
- bitMap = bitMap>>1;
- }
- }
- }
- return (mcsRate|0x80);
-}
-
-
-
-/*
-**
-**1.Filter our operation rate set with AP's rate set
-**2.shall reference channel bandwidth, STBC, Antenna number
-**3.generate rate adative table for firmware
-**David 20060906
-**
-** \pHTSupportedCap: the connected STA's supported rate Capability element
-*/
-u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS)
-{
-
- u8 i=0;
-
- // filter out operational rate set not supported by AP, the lenth of it is 16
- for(i=0;i<=15;i++){
- pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
- }
-
-
- // TODO: adjust our operational rate set according to our channel bandwidth, STBC and Antenna number
-
- // TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
- // we also shall suggested the first start rate set according to our singal strength
- HT_PickMCSRate(ieee, pOperateMCS);
-
- // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
- if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
- pOperateMCS[1] = 0;
-
- //
- // For RTL819X, we support only MCS0~15.
- // And also, we do not know how to use MCS32 now.
- //
- for(i=2; i<=15; i++)
- pOperateMCS[i] = 0;
-
- return true;
-}
-void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-
-void HTOnAssocRsp(struct ieee80211_device *ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
- PHT_CAPABILITY_ELE pPeerHTCap = NULL;
- PHT_INFORMATION_ELE pPeerHTInfo = NULL;
- u16 nMaxAMSDUSize = 0;
- u8* pMcsFilter = NULL;
-
- static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
- static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily
-
- if( pHTInfo->bCurrentHTSupport == false )
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
- return;
- }
- IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
-
- if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
- pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
- else
- pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
-
- if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
- pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
- else
- pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
-
-
- ////////////////////////////////////////////////////////
- // Configurations:
- ////////////////////////////////////////////////////////
- IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
-
- HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
-
- if(pHTInfo->bCurBW40MHz == true)
- pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
-
- //
- // Update short GI/ long GI setting
- //
- // TODO:
- pHTInfo->bCurShortGI20MHz=
- ((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
- pHTInfo->bCurShortGI40MHz=
- ((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
-
- //
- // Config TX STBC setting
- //
- // TODO:
-
- //
- // Config DSSS/CCK mode in 40MHz mode
- //
- // TODO:
- pHTInfo->bCurSuppCCK =
- ((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
-
-
- //
- // Config and configure A-MSDU setting
- //
- pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
-
- nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
-
- if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
- pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
- else
- pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
-
- //
- // Config A-MPDU setting
- //
- pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
- if(ieee->is_ap_in_wep_tkip && ieee->is_ap_in_wep_tkip(ieee->dev))
- {
- if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) ||
- (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) )
- pHTInfo->bCurrentAMPDUEnable = false;
- }
-
- // <1> Decide AMPDU Factor
-
- // By Emily
- if(!pHTInfo->bRegRT2RTAggregation)
- {
- // Decide AMPDU Factor according to protocol handshake
- if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
- pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
- else
- pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
-
- }else
- {
- // Set MPDU density to 2 to Realtek AP, and set it to 0 for others
- // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
- if (ieee->current_network.bssht.bdRT2RTAggregation)
- {
- if( ieee->pairwise_key_type != KEY_TYPE_NA)
- // Realtek may set 32k in security mode and 64k for others
- pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
- else
- pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
- }else
- {
- if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
- pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
- else
- pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
- }
- }
-
- // <2> Set AMPDU Minimum MPDU Start Spacing
- // 802.11n 3.0 section 9.7d.3
-#if 0
- if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
- pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
- else
- pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
- if(ieee->pairwise_key_type != KEY_TYPE_NA )
- pHTInfo->CurrentMPDUDensity = 7; // 8us
-#else
- if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
- pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
- else
- pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
-#endif
- // Force TX AMSDU
-
- // Lanhsin: mark for tmp to avoid deauth by ap from s3
- //if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
- if(pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K)
- {
-
- pHTInfo->bCurrentAMPDUEnable = false;
- pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
- pHTInfo->ForcedAMSDUMaxSize = 7935;
- }
-
- // Rx Reorder Setting
- pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
-
- //
- // Filter out unsupported HT rate for this AP
- // Update RATR table
- // This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
- //
-
- // Handle Ralink AP bad MCS rate set condition. Joseph.
- // This fix the bug of Ralink AP. This may be removed in the future.
- if(pPeerHTCap->MCS[0] == 0)
- pPeerHTCap->MCS[0] = 0xff;
-
- // Joseph test //LZM ADD 090318
- HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1])!=0));
-
- HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
-
- //
- // Config MIMO Power Save setting
- //
- pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
- if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
- pMcsFilter = MCS_FILTER_1SS;
- else
- pMcsFilter = MCS_FILTER_ALL;
- //WB add for MCS8 bug
-// pMcsFilter = MCS_FILTER_1SS;
- ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
- ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
-
- //
- // Config current operation mode.
- //
- pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
-
-
-
-}
-
-void HTSetConnectBwModeCallback(struct ieee80211_device* ieee);
-/********************************************************************************************************************
- *function: initialize HT info(struct PRT_HIGH_THROUGHPUT)
- * input: struct ieee80211_device* ieee
- * output: none
- * return: none
- * notice: This function is called when * (1) MPInitialization Phase * (2) Receiving of Deauthentication from AP
-********************************************************************************************************************/
-// TODO: Should this funciton be called when receiving of Disassociation?
-void HTInitializeHTInfo(struct ieee80211_device* ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- //
- // These parameters will be reset when receiving deauthentication packet
- //
- IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__);
- pHTInfo->bCurrentHTSupport = false;
-
- // 40MHz channel support
- pHTInfo->bCurBW40MHz = false;
- pHTInfo->bCurTxBW40MHz = false;
-
- // Short GI support
- pHTInfo->bCurShortGI20MHz = false;
- pHTInfo->bCurShortGI40MHz = false;
- pHTInfo->bForcedShortGI = false;
-
- // CCK rate support
- // This flag is set to true to support CCK rate by default.
- // It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
- // 11N BSS.
- pHTInfo->bCurSuppCCK = true;
-
- // AMSDU related
- pHTInfo->bCurrent_AMSDU_Support = false;
- pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
-
- // AMPUD related
- pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
- pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
-
-
-
- // Initialize all of the parameters related to 11n
- memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
- memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
- memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
- memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
-
- pHTInfo->bSwBwInProgress = false;
- pHTInfo->ChnlOp = CHNLOP_NONE;
-
- // Set default IEEE spec for Draft N
- pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
-
- // Realtek proprietary aggregation mode
- pHTInfo->bCurrentRT2RTAggregation = false;
- pHTInfo->bCurrentRT2RTLongSlotTime = false;
- pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
-
- pHTInfo->IOTPeer = 0;
- pHTInfo->IOTAction = 0;
- pHTInfo->IOTRaFunc = 0;
-
- //MCS rate initialized here
- {
- u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
- RegHTSuppRateSets[0] = 0xFF; //support MCS 0~7
- RegHTSuppRateSets[1] = 0xFF; //support MCS 8~15
- RegHTSuppRateSets[4] = 0x01; //support MCS 32
- }
-}
-/********************************************************************************************************************
- *function: initialize Bss HT structure(struct PBSS_HT)
- * input: PBSS_HT pBssHT //to be initialized
- * output: none
- * return: none
- * notice: This function is called when initialize network structure
-********************************************************************************************************************/
-void HTInitializeBssDesc(PBSS_HT pBssHT)
-{
-
- pBssHT->bdSupportHT = false;
- memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
- pBssHT->bdHTCapLen = 0;
- memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
- pBssHT->bdHTInfoLen = 0;
-
- pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
-
- pBssHT->bdRT2RTAggregation = false;
- pBssHT->bdRT2RTLongSlotTime = false;
- pBssHT->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
-}
-
-/********************************************************************************************************************
- *function: initialize Bss HT structure(struct PBSS_HT)
- * input: struct ieee80211_device *ieee
- * struct ieee80211_network *pNetwork //usually current network we are live in
- * output: none
- * return: none
- * notice: This function should ONLY be called before association
-********************************************************************************************************************/
-void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-// u16 nMaxAMSDUSize;
-// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
-// PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
-// u8* pMcsFilter;
- u8 bIOTAction = 0;
-
- //
- // Save Peer Setting before Association
- //
- IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__);
- /*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
-// if( pHTInfo->bEnableHT && pNetwork->bssht.bdSupportHT)
- if (pNetwork->bssht.bdSupportHT)
- {
- pHTInfo->bCurrentHTSupport = true;
- pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
-
- // Save HTCap and HTInfo information Element
- if(pNetwork->bssht.bdHTCapLen > 0 && pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
- memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
-
- if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
- memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
-
- // Check whether RT to RT aggregation mode is enabled
- if(pHTInfo->bRegRT2RTAggregation)
- {
- pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
- pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
- pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode;
- }
- else
- {
- pHTInfo->bCurrentRT2RTAggregation = false;
- pHTInfo->bCurrentRT2RTLongSlotTime = false;
- pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
- }
-
- // Determine the IOT Peer Vendor.
- HTIOTPeerDetermine(ieee);
-
- // Decide IOT Action
- // Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
- pHTInfo->IOTAction = 0;
- bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
-
- bIOTAction = HTIOTActIsDisableMCS15(ieee);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
-
- bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
-
-
- bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
-
- bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
-
- bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
-
- bIOTAction = HTIOTActIsForcedCTS2Self(pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
-
- //bIOTAction = HTIOTActIsForcedRTSCTS(ieee, pNetwork);
- //if(bIOTAction)
- // pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_RTS;
-
- bIOTAction = HTIOCActRejcectADDBARequest(pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_REJECT_ADDBA_REQ;
-
- bIOTAction = HTIOCActAllowPeerAggOnePacket(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT;
-
- bIOTAction = HTIOTActIsEDCABiasRx(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_EDCA_BIAS_ON_RX;
-
- bIOTAction = HTIOTActDisableShortGI(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_SHORT_GI;
-
- bIOTAction = HTIOTActDisableHighPower(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_HIGH_POWER;
-
- bIOTAction = HTIOTActIsForcedAMSDU8K(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K;
-
- bIOTAction = HTIOTActIsTxNoAggregation(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_TX_NO_AGGREGATION;
-
- bIOTAction = HTIOTActIsDisableTx40MHz(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_40_MHZ;
-
- bIOTAction = HTIOTActIsDisableTx2SS(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_2SS;
- //must after HT_IOT_ACT_TX_NO_AGGREGATION
- bIOTAction = HTIOTActIsForcedRTSCTS(ieee, pNetwork);
- if(bIOTAction)
- pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_RTS;
-
- printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!IOTAction = %8.8x\n", pHTInfo->IOTAction);
- }
- else
- {
- pHTInfo->bCurrentHTSupport = false;
- pHTInfo->bCurrentRT2RTAggregation = false;
- pHTInfo->bCurrentRT2RTLongSlotTime = false;
- pHTInfo->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
-
- pHTInfo->IOTAction = 0;
- pHTInfo->IOTRaFunc = 0;
- }
-
-}
-
-void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
- PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
-
- if(pHTInfo->bCurrentHTSupport)
- {
- //
- // Config current operation mode.
- //
- if(pNetwork->bssht.bdHTInfoLen != 0)
- pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
-
- //
- // <TODO: Config according to OBSS non-HT STA present!!>
- //
- }
-}
-
-void HTUseDefaultSetting(struct ieee80211_device* ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-// u8 regBwOpMode;
-
- if(pHTInfo->bEnableHT)
- {
- pHTInfo->bCurrentHTSupport = true;
-
- pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
-
- pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
-
- pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz;
-
- pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz;
-
- pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
-
- pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
-
- pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
-
- pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
-
- pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
-
- // Set BWOpMode register
-
- //update RATR index0
- HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet);
- //function below is not implemented at all. WB
-#ifdef TODO
- Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet);
-#endif
- ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL);
- ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
-
- }
- else
- {
- pHTInfo->bCurrentHTSupport = false;
- }
- return;
-}
-/********************************************************************************************************************
- *function: check whether HT control field exists
- * input: struct ieee80211_device *ieee
- * u8* pFrame //coming skb->data
- * output: none
- * return: return true if HT control field exists(false otherwise)
- * notice:
-********************************************************************************************************************/
-u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame)
-{
- if(ieee->pHTInfo->bCurrentHTSupport)
- {
- if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1)
- {
- IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
- return true;
- }
- }
- return false;
-}
-
-//
-// This function set bandwidth mode in protocol layer.
-//
-void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-// u32 flags = 0;
-
- if(pHTInfo->bRegBW40MHz == false)
- return;
-
-
-
- // To reduce dummy operation
-// if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
-// (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
-// return;
-
-// spin_lock_irqsave(&(ieee->bw_spinlock), flags);
- if(pHTInfo->bSwBwInProgress) {
-// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
- return;
- }
- //if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
- if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
- {
- // Handle Illegal extention channel offset!!
- if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
- Offset = HT_EXTCHNL_OFFSET_NO_EXT;
- if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
- pHTInfo->bCurBW40MHz = true;
- pHTInfo->CurSTAExtChnlOffset = Offset;
- } else {
- pHTInfo->bCurBW40MHz = false;
- pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
- }
- } else {
- pHTInfo->bCurBW40MHz = false;
- pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
- }
-
- pHTInfo->bSwBwInProgress = true;
-
- // TODO: 2007.7.13 by Emily Wait 2000ms in order to garantee that switching
- // bandwidth is executed after scan is finished. It is a temporal solution
- // because software should ganrantee the last operation of switching bandwidth
- // is executed properlly.
- HTSetConnectBwModeCallback(ieee);
-
-// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
-}
-
-void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
-{
- PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
- IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__);
- if(pHTInfo->bCurBW40MHz)
- {
- if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
- ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
- else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
- ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
- else
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
- } else {
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
- }
-
- pHTInfo->bSwBwInProgress = false;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
deleted file mode 100644
index 928062f35713..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef __INC_QOS_TYPE_H
-#define __INC_QOS_TYPE_H
-
-#define BIT0 0x00000001
-#define BIT1 0x00000002
-#define BIT2 0x00000004
-#define BIT3 0x00000008
-#define BIT4 0x00000010
-#define BIT5 0x00000020
-#define BIT6 0x00000040
-#define BIT7 0x00000080
-#define BIT8 0x00000100
-#define BIT9 0x00000200
-#define BIT10 0x00000400
-#define BIT11 0x00000800
-#define BIT12 0x00001000
-#define BIT13 0x00002000
-#define BIT14 0x00004000
-#define BIT15 0x00008000
-#define BIT16 0x00010000
-#define BIT17 0x00020000
-#define BIT18 0x00040000
-#define BIT19 0x00080000
-#define BIT20 0x00100000
-#define BIT21 0x00200000
-#define BIT22 0x00400000
-#define BIT23 0x00800000
-#define BIT24 0x01000000
-#define BIT25 0x02000000
-#define BIT26 0x04000000
-#define BIT27 0x08000000
-#define BIT28 0x10000000
-#define BIT29 0x20000000
-#define BIT30 0x40000000
-#define BIT31 0x80000000
-
-#define MAX_WMMELE_LENGTH 64
-
-typedef u32 QOS_MODE, *PQOS_MODE;
-#define QOS_DISABLE 0
-#define QOS_WMM 1
-#define QOS_WMMSA 2
-#define QOS_EDCA 4
-#define QOS_HCCA 8
-#define QOS_WMM_UAPSD 16 //WMM Power Save, 2006-06-14 Isaiah
-
-#define AC_PARAM_SIZE 4
-#define WMM_PARAM_ELE_BODY_LEN 18
-
-//
-// QoS ACK Policy Field Values
-// Ref: WMM spec 2.1.6: QoS Control Field, p.10.
-//
-typedef enum _ACK_POLICY{
- eAckPlc0_ACK = 0x00,
- eAckPlc1_NoACK = 0x01,
-}ACK_POLICY,*PACK_POLICY;
-
-#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE))
-
-//
-// QoS Control Field
-// Ref:
-// 1. WMM spec 2.1.6: QoS Control Field, p.9.
-// 2. 802.11e/D13.0 7.1.3.5, p.26.
-//
-typedef union _QOS_CTRL_FIELD{
- u8 charData[2];
- u16 shortData;
-
- // WMM spec
- struct
- {
- u8 UP:3;
- u8 usRsvd1:1;
- u8 EOSP:1;
- u8 AckPolicy:2;
- u8 usRsvd2:1;
- u8 ucRsvdByte;
- }WMM;
-
- // 802.11e: QoS data type frame sent by non-AP QSTAs.
- struct
- {
- u8 TID:4;
- u8 bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size.
- u8 AckPolicy:2;
- u8 usRsvd:1;
- u8 TxopOrQsize; // (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size.
- }BySta;
-
- // 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC.
- struct
- {
- u8 TID:4;
- u8 EOSP:1;
- u8 AckPolicy:2;
- u8 usRsvd:1;
- u8 PSBufState; // QAP PS Buffer State.
- }ByHc_Data;
-
- // 802.11e: QoS (+) CF-Poll frames sent by HC.
- struct
- {
- u8 TID:4;
- u8 EOSP:1;
- u8 AckPolicy:2;
- u8 usRsvd:1;
- u8 TxopLimit; // TXOP Limit.
- }ByHc_CFP;
-
-}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD;
-
-
-//
-// QoS Info Field
-// Ref:
-// 1. WMM spec 2.2.1: WME Information Element, p.11.
-// 2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h]
-//
-typedef union _QOS_INFO_FIELD{
- u8 charData;
-
- struct
- {
- u8 ucParameterSetCount:4;
- u8 ucReserved:4;
- }WMM;
-
- struct
- {
- //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
- u8 ucAC_VO_UAPSD:1;
- u8 ucAC_VI_UAPSD:1;
- u8 ucAC_BE_UAPSD:1;
- u8 ucAC_BK_UAPSD:1;
- u8 ucReserved1:1;
- u8 ucMaxSPLen:2;
- u8 ucReserved2:1;
-
- }ByWmmPsSta;
-
- struct
- {
- //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
- u8 ucParameterSetCount:4;
- u8 ucReserved:3;
- u8 ucApUapsd:1;
- }ByWmmPsAp;
-
- struct
- {
- u8 ucAC3_UAPSD:1;
- u8 ucAC2_UAPSD:1;
- u8 ucAC1_UAPSD:1;
- u8 ucAC0_UAPSD:1;
- u8 ucQAck:1;
- u8 ucMaxSPLen:2;
- u8 ucMoreDataAck:1;
- } By11eSta;
-
- struct
- {
- u8 ucParameterSetCount:4;
- u8 ucQAck:1;
- u8 ucQueueReq:1;
- u8 ucTXOPReq:1;
- u8 ucReserved:1;
- } By11eAp;
-
- struct
- {
- u8 ucReserved1:4;
- u8 ucQAck:1;
- u8 ucReserved2:2;
- u8 ucMoreDataAck:1;
- } ByWmmsaSta;
-
- struct
- {
- u8 ucReserved1:4;
- u8 ucQAck:1;
- u8 ucQueueReq:1;
- u8 ucTXOPReq:1;
- u8 ucReserved2:1;
- } ByWmmsaAp;
-
- struct
- {
- u8 ucAC3_UAPSD:1;
- u8 ucAC2_UAPSD:1;
- u8 ucAC1_UAPSD:1;
- u8 ucAC0_UAPSD:1;
- u8 ucQAck:1;
- u8 ucMaxSPLen:2;
- u8 ucMoreDataAck:1;
- } ByAllSta;
-
- struct
- {
- u8 ucParameterSetCount:4;
- u8 ucQAck:1;
- u8 ucQueueReq:1;
- u8 ucTXOPReq:1;
- u8 ucApUapsd:1;
- } ByAllAp;
-
-}QOS_INFO_FIELD, *PQOS_INFO_FIELD;
-
-typedef u32 AC_CODING;
-#define AC0_BE 0 // ACI: 0x00 // Best Effort
-#define AC1_BK 1 // ACI: 0x01 // Background
-#define AC2_VI 2 // ACI: 0x10 // Video
-#define AC3_VO 3 // ACI: 0x11 // Voice
-#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
-
-//
-// ACI/AIFSN Field.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
-//
-typedef union _ACI_AIFSN{
- u8 charData;
-
- struct
- {
- u8 AIFSN:4;
- u8 ACM:1;
- u8 ACI:2;
- u8 Reserved:1;
- }f;
-}ACI_AIFSN, *PACI_AIFSN;
-
-//
-// ECWmin/ECWmax field.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
-//
-typedef union _ECW{
- u8 charData;
- struct
- {
- u8 ECWmin:4;
- u8 ECWmax:4;
- }f;
-}ECW, *PECW;
-
-//
-// AC Parameters Record Format.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
-//
-typedef union _AC_PARAM{
- u32 longData;
- u8 charData[4];
-
- struct
- {
- ACI_AIFSN AciAifsn;
- ECW Ecw;
- u16 TXOPLimit;
- }f;
-}AC_PARAM, *PAC_PARAM;
-
-
-
-//
-// QoS element subtype
-//
-typedef enum _QOS_ELE_SUBTYPE{
- QOSELE_TYPE_INFO = 0x00, // 0x00: Information element
- QOSELE_TYPE_PARAM = 0x01, // 0x01: parameter element
-}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
-
-
-//
-// Direction Field Values.
-// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
-//
-typedef enum _DIRECTION_VALUE{
- DIR_UP = 0, // 0x00 // UpLink
- DIR_DOWN = 1, // 0x01 // DownLink
- DIR_DIRECT = 2, // 0x10 // DirectLink
- DIR_BI_DIR = 3, // 0x11 // Bi-Direction
-}DIRECTION_VALUE,*PDIRECTION_VALUE;
-
-
-//
-// TS Info field in WMM TSPEC Element.
-// Ref:
-// 1. WMM spec 2.2.11: WME TSPEC Element, p.18.
-// 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
-//
-typedef union _QOS_TSINFO{
- u8 charData[3];
- struct {
- u8 ucTrafficType:1; //WMM is reserved
- u8 ucTSID:4;
- u8 ucDirection:2;
- u8 ucAccessPolicy:2; //WMM: bit8=0, bit7=1
- u8 ucAggregation:1; //WMM is reserved
- u8 ucPSB:1; //WMMSA is APSD
- u8 ucUP:3;
- u8 ucTSInfoAckPolicy:2; //WMM is reserved
- u8 ucSchedule:1; //WMM is reserved
- u8 ucReserved:7;
- }field;
-}QOS_TSINFO, *PQOS_TSINFO;
-
-//
-// WMM TSPEC Body.
-// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
-//
-typedef union _TSPEC_BODY{
- u8 charData[55];
-
- struct
- {
- QOS_TSINFO TSInfo; //u8 TSInfo[3];
- u16 NominalMSDUsize;
- u16 MaxMSDUsize;
- u32 MinServiceItv;
- u32 MaxServiceItv;
- u32 InactivityItv;
- u32 SuspenItv;
- u32 ServiceStartTime;
- u32 MinDataRate;
- u32 MeanDataRate;
- u32 PeakDataRate;
- u32 MaxBurstSize;
- u32 DelayBound;
- u32 MinPhyRate;
- u16 SurplusBandwidthAllowance;
- u16 MediumTime;
- } f;
-}TSPEC_BODY, *PTSPEC_BODY;
-
-
-//
-// WMM TSPEC Element.
-// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
-//
-typedef struct _WMM_TSPEC{
- u8 ID;
- u8 Length;
- u8 OUI[3];
- u8 OUI_Type;
- u8 OUI_SubType;
- u8 Version;
- TSPEC_BODY Body;
-} WMM_TSPEC, *PWMM_TSPEC;
-
-//
-// ACM implementation method.
-// Annie, 2005-12-13.
-//
-typedef enum _ACM_METHOD{
- eAcmWay0_SwAndHw = 0, // By SW and HW.
- eAcmWay1_HW = 1, // By HW.
- eAcmWay2_SW = 2, // By SW.
-}ACM_METHOD,*PACM_METHOD;
-
-
-typedef struct _ACM{
- u64 UsedTime;
- u64 MediumTime;
- u8 HwAcmCtl; // TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
-}ACM, *PACM;
-
-typedef u8 AC_UAPSD, *PAC_UAPSD;
-
-#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
-#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
-
-#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
-#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
-
-#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
-#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
-
-#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
-#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
-
-typedef union _QOS_TCLAS{
-
- struct _TYPE_GENERAL{
- u8 Priority;
- u8 ClassifierType;
- u8 Mask;
- } TYPE_GENERAL;
-
- struct _TYPE0_ETH{
- u8 Priority;
- u8 ClassifierType;
- u8 Mask;
- u8 SrcAddr[6];
- u8 DstAddr[6];
- u16 Type;
- } TYPE0_ETH;
-
- struct _TYPE1_IPV4{
- u8 Priority;
- u8 ClassifierType;
- u8 Mask;
- u8 Version;
- u8 SrcIP[4];
- u8 DstIP[4];
- u16 SrcPort;
- u16 DstPort;
- u8 DSCP;
- u8 Protocol;
- u8 Reserved;
- } TYPE1_IPV4;
-
- struct _TYPE1_IPV6{
- u8 Priority;
- u8 ClassifierType;
- u8 Mask;
- u8 Version;
- u8 SrcIP[16];
- u8 DstIP[16];
- u16 SrcPort;
- u16 DstPort;
- u8 FlowLabel[3];
- } TYPE1_IPV6;
-
- struct _TYPE2_8021Q{
- u8 Priority;
- u8 ClassifierType;
- u8 Mask;
- u16 TagType;
- } TYPE2_8021Q;
-} QOS_TCLAS, *PQOS_TCLAS;
-
-typedef struct _QOS_TSTREAM{
- u8 AC;
- WMM_TSPEC TSpec;
- QOS_TCLAS TClass;
-} QOS_TSTREAM, *PQOS_TSTREAM;
-
-//----------------------------------------------------------------------------
-// 802.11 Management frame Status Code field
-//----------------------------------------------------------------------------
-typedef struct _OCTET_STRING{
- u8 *Octet;
- u16 Length;
-}OCTET_STRING, *POCTET_STRING;
-
-//
-// STA QoS data.
-// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
-//
-typedef struct _STA_QOS{
- u8 WMMIEBuf[MAX_WMMELE_LENGTH];
- u8* WMMIE;
-
- // Part 1. Self QoS Mode.
- QOS_MODE QosCapability; //QoS Capability, 2006-06-14 Isaiah
- QOS_MODE CurrentQosMode;
-
- // For WMM Power Save Mode :
- // ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah
- AC_UAPSD b4ac_Uapsd; //VoUapsd(bit0), ViUapsd(bit1), BkUapsd(bit2), BeUapsd(bit3),
- AC_UAPSD Curr4acUapsd;
- u8 bInServicePeriod;
- u8 MaxSPLength;
- int NumBcnBeforeTrigger;
-
- // Part 2. EDCA Parameter (perAC)
- u8 * pWMMInfoEle;
- u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
- u8 WMMPELength;
-
- // <Bruce_Note>
- //2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element.
- // By Bruce, 2008-01-30.
- // Part 2. EDCA Parameter (perAC)
- QOS_INFO_FIELD QosInfoField_STA; // Maintained by STA
- QOS_INFO_FIELD QosInfoField_AP; // Retrieved from AP
-
- AC_PARAM CurAcParameters[4];
-
- // Part 3. ACM
- ACM acm[4];
- ACM_METHOD AcmMethod;
-
- // Part 4. Per TID (Part 5: TCLASS will be described by TStream)
- QOS_TSTREAM TStream[16];
- WMM_TSPEC TSpec;
-
- u32 QBssWirelessMode;
-
- // No Ack Setting
- u8 bNoAck;
-
- // Enable/Disable Rx immediate BA capability.
- u8 bEnableRxImmBA;
-
-}STA_QOS, *PSTA_QOS;
-
-//
-// BSS QOS data.
-// Ref: BssDscr in 8185 code. [def. in BssDscr.h]
-//
-typedef struct _BSS_QOS{
- QOS_MODE bdQoSMode;
-
- u8 bdWMMIEBuf[MAX_WMMELE_LENGTH];
- u8* bdWMMIE;
-
- QOS_ELE_SUBTYPE EleSubType;
-
- u8 * pWMMInfoEle;
- u8 * pWMMParamEle;
-
- QOS_INFO_FIELD QosInfoField;
- AC_PARAM AcParameter[4];
-}BSS_QOS, *PBSS_QOS;
-
-#define sQoSCtlLng 2
-#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
-
-#define IsACValid(ac) ((ac<=7 )?true:false )
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_TS.h
deleted file mode 100644
index a07b2344a6f8..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TS.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef _TSTYPE_H_
-#define _TSTYPE_H_
-#include "rtl819x_Qos.h"
-#define TS_SETUP_TIMEOUT 60 // In millisecond
-#define TS_INACT_TIMEOUT 60
-#define TS_ADDBA_DELAY 60
-
-#define TOTAL_TS_NUM 16
-#define TCLAS_NUM 4
-
-// This define the Tx/Rx directions
-typedef enum _TR_SELECT {
- TX_DIR = 0,
- RX_DIR = 1,
-} TR_SELECT, *PTR_SELECT;
-
-typedef struct _TS_COMMON_INFO{
- struct list_head List;
- struct timer_list SetupTimer;
- struct timer_list InactTimer;
- u8 Addr[6];
- TSPEC_BODY TSpec;
- QOS_TCLAS TClass[TCLAS_NUM];
- u8 TClasProc;
- u8 TClasNum;
-} TS_COMMON_INFO, *PTS_COMMON_INFO;
-
-typedef struct _TX_TS_RECORD{
- TS_COMMON_INFO TsCommonInfo;
- u16 TxCurSeq;
- BA_RECORD TxPendingBARecord; // For BA Originator
- BA_RECORD TxAdmittedBARecord; // For BA Originator
- u8 bAddBaReqInProgress;
- u8 bAddBaReqDelayed;
- u8 bUsingBa;
- u8 bDisable_AddBa;
- struct timer_list TsAddBaTimer;
- u8 num;
-} TX_TS_RECORD, *PTX_TS_RECORD;
-
-typedef struct _RX_TS_RECORD {
- TS_COMMON_INFO TsCommonInfo;
- u16 RxIndicateSeq;
- u16 RxTimeoutIndicateSeq;
- struct list_head RxPendingPktList;
- struct timer_list RxPktPendingTimer;
- BA_RECORD RxAdmittedBARecord; // For BA Recepient
- u16 RxLastSeqNum;
- u8 RxLastFragNum;
- u8 num;
-} RX_TS_RECORD, *PRX_TS_RECORD;
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
deleted file mode 100644
index 7ffc06ca89a8..000000000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "ieee80211.h"
-#include <linux/etherdevice.h>
-#include <linux/slab.h>
-#include "rtl819x_TS.h"
-
-void TsSetupTimeOut(unsigned long data)
-{
- // Not implement yet
- // This is used for WMMSA and ACM , that would send ADDTSReq frame.
-}
-
-void TsInactTimeout(unsigned long data)
-{
- // Not implement yet
- // This is used for WMMSA and ACM.
- // This function would be call when TS is no Tx/Rx for some period of time.
-}
-
-/********************************************************************************************************************
- *function: I still not understand this function, so wait for further implementation
- * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
- * return: NULL
- * notice:
-********************************************************************************************************************/
-void RxPktPendingTimeout(unsigned long data)
-{
- PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data;
- struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
-
- PRX_REORDER_ENTRY pReorderEntry = NULL;
-
- unsigned long flags = 0;
- struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
- u8 index = 0;
- bool bPktInBuf = false;
-
-
- spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
- if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
- {
- // Indicate the pending packets sequentially according to SeqNum until meet the gap.
- while(!list_empty(&pRxTs->RxPendingPktList))
- {
- pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
- if(index == 0)
- pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
-
- if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
- SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) )
- {
- list_del_init(&pReorderEntry->List);
-
- if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
- pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
-
- IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
- stats_IndicateArray[index] = pReorderEntry->prxb;
- index++;
-
- list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
- }
- else
- {
- bPktInBuf = true;
- break;
- }
- }
- }
-
- if(index>0)
- {
- pRxTs->RxTimeoutIndicateSeq = 0xffff;
-
- // Indicate packets
- if(index > REORDER_WIN_SIZE){
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
- return;
- }
- ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
- bPktInBuf = false;
- }
-
- if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
- {
- pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
- mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
- }
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
- //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
-}
-
-/********************************************************************************************************************
- *function: Add BA timer function
- * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
- * return: NULL
- * notice:
-********************************************************************************************************************/
-void TsAddBaProcess(unsigned long data)
-{
- PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data;
- u8 num = pTxTs->num;
- struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
-
- TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
- IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
-}
-
-
-void ResetTsCommonInfo(PTS_COMMON_INFO pTsCommonInfo)
-{
- memset(pTsCommonInfo->Addr, 0, 6);
- memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
- memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
- pTsCommonInfo->TClasProc = 0;
- pTsCommonInfo->TClasNum = 0;
-}
-
-void ResetTxTsEntry(PTX_TS_RECORD pTS)
-{
- ResetTsCommonInfo(&pTS->TsCommonInfo);
- pTS->TxCurSeq = 0;
- pTS->bAddBaReqInProgress = false;
- pTS->bAddBaReqDelayed = false;
- pTS->bUsingBa = false;
- pTS->bDisable_AddBa = false;
- ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
- ResetBaEntry(&pTS->TxPendingBARecord);
-}
-
-void ResetRxTsEntry(PRX_TS_RECORD pTS)
-{
- ResetTsCommonInfo(&pTS->TsCommonInfo);
- pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
- pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!!
- ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recepient
-}
-
-void TSInitialize(struct ieee80211_device *ieee)
-{
- PTX_TS_RECORD pTxTS = ieee->TxTsRecord;
- PRX_TS_RECORD pRxTS = ieee->RxTsRecord;
- PRX_REORDER_ENTRY pRxReorderEntry = ieee->RxReorderEntry;
- u8 count = 0;
- IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__);
- // Initialize Tx TS related info.
- INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
- INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
- INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
-
- for(count = 0; count < TOTAL_TS_NUM; count++)
- {
- //
- pTxTS->num = count;
- // The timers for the operation of Traffic Stream and Block Ack.
- // DLS related timer will be add here in the future!!
- init_timer(&pTxTS->TsCommonInfo.SetupTimer);
- pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS;
- pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
-
- init_timer(&pTxTS->TsCommonInfo.InactTimer);
- pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS;
- pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
-
- init_timer(&pTxTS->TsAddBaTimer);
- pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS;
- pTxTS->TsAddBaTimer.function = TsAddBaProcess;
-
- init_timer(&pTxTS->TxPendingBARecord.Timer);
- pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS;
- pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut;
-
- init_timer(&pTxTS->TxAdmittedBARecord.Timer);
- pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS;
- pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout;
-
- ResetTxTsEntry(pTxTS);
- list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List);
- pTxTS++;
- }
-
- // Initialize Rx TS related info.
- INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
- INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
- INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
- for(count = 0; count < TOTAL_TS_NUM; count++)
- {
- pRxTS->num = count;
- INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
-
- init_timer(&pRxTS->TsCommonInfo.SetupTimer);
- pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS;
- pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
-
- init_timer(&pRxTS->TsCommonInfo.InactTimer);
- pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS;
- pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
-
- init_timer(&pRxTS->RxAdmittedBARecord.Timer);
- pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS;
- pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout;
-
- init_timer(&pRxTS->RxPktPendingTimer);
- pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS;
- pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout;
-
- ResetRxTsEntry(pRxTS);
- list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
- pRxTS++;
- }
- // Initialize unused Rx Reorder List.
- INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
- for(count = 0; count < REORDER_ENTRY_NUM; count++)
- {
- list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
- if(count == (REORDER_ENTRY_NUM-1))
- break;
- pRxReorderEntry = &ieee->RxReorderEntry[count+1];
- }
-
-}
-
-void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
-{
- del_timer_sync(&pTsCommonInfo->SetupTimer);
- del_timer_sync(&pTsCommonInfo->InactTimer);
-
- if(InactTime!=0)
- mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
-}
-
-
-PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect)
-{
- u8 dir;
- bool search_dir[4] = {0, 0, 0, 0};
- struct list_head* psearch_list; //FIXME
- PTS_COMMON_INFO pRet = NULL;
- if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
- {
- if(TxRxSelect == TX_DIR)
- {
- search_dir[DIR_DOWN] = true;
- search_dir[DIR_BI_DIR]= true;
- }
- else
- {
- search_dir[DIR_UP] = true;
- search_dir[DIR_BI_DIR]= true;
- }
- }
- else if(ieee->iw_mode == IW_MODE_ADHOC)
- {
- if(TxRxSelect == TX_DIR)
- search_dir[DIR_UP] = true;
- else
- search_dir[DIR_DOWN] = true;
- }
- else
- {
- if(TxRxSelect == TX_DIR)
- {
- search_dir[DIR_UP] = true;
- search_dir[DIR_BI_DIR]= true;
- search_dir[DIR_DIRECT]= true;
- }
- else
- {
- search_dir[DIR_DOWN] = true;
- search_dir[DIR_BI_DIR]= true;
- search_dir[DIR_DIRECT]= true;
- }
- }
-
- if(TxRxSelect == TX_DIR)
- psearch_list = &ieee->Tx_TS_Admit_List;
- else
- psearch_list = &ieee->Rx_TS_Admit_List;
-
- for(dir = 0; dir <= DIR_BI_DIR; dir++)
- {
- if(search_dir[dir] ==false )
- continue;
- list_for_each_entry(pRet, psearch_list, List){
- if (memcmp(pRet->Addr, Addr, 6) == 0)
- if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
- if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
- {
- break;
- }
-
- }
- if(&pRet->List != psearch_list)
- break;
- }
-
- if(&pRet->List != psearch_list){
- return pRet ;
- }
- else
- return NULL;
-}
-
-void MakeTSEntry(
- PTS_COMMON_INFO pTsCommonInfo,
- u8* Addr,
- PTSPEC_BODY pTSPEC,
- PQOS_TCLAS pTCLAS,
- u8 TCLAS_Num,
- u8 TCLAS_Proc
- )
-{
- u8 count;
-
- if(pTsCommonInfo == NULL)
- return;
-
- memcpy(pTsCommonInfo->Addr, Addr, 6);
-
- if(pTSPEC != NULL)
- memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
-
- for(count = 0; count < TCLAS_Num; count++)
- memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
-
- pTsCommonInfo->TClasProc = TCLAS_Proc;
- pTsCommonInfo->TClasNum = TCLAS_Num;
-}
-
-
-bool GetTs(
- struct ieee80211_device* ieee,
- PTS_COMMON_INFO *ppTS,
- u8* Addr,
- u8 TID,
- TR_SELECT TxRxSelect, //Rx:1, Tx:0
- bool bAddNewTs
- )
-{
- u8 UP = 0;
- //
- // We do not build any TS for Broadcast or Multicast stream.
- // So reject these kinds of search here.
- //
- if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "ERR! get TS for Broadcast or Multicast\n");
- return false;
- }
- if (ieee->current_network.qos_data.supported == 0)
- UP = 0;
- else
- {
- // In WMM case: we use 4 TID only
- if (!IsACValid(TID))
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "ERR! in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
- return false;
- }
-
- switch(TID)
- {
- case 0:
- case 3:
- UP = 0;
- break;
-
- case 1:
- case 2:
- UP = 2;
- break;
-
- case 4:
- case 5:
- UP = 5;
- break;
-
- case 6:
- case 7:
- UP = 7;
- break;
- }
- }
-
- *ppTS = SearchAdmitTRStream(
- ieee,
- Addr,
- UP,
- TxRxSelect);
- if(*ppTS != NULL)
- {
- return true;
- }
- else
- {
- if(bAddNewTs == false)
- {
- IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
- return false;
- }
- else
- {
- //
- // Create a new Traffic stream for current Tx/Rx
- // This is for EDCA and WMM to add a new TS.
- // For HCCA or WMMSA, TS cannot be addmit without negotiation.
- //
- TSPEC_BODY TSpec;
- PQOS_TSINFO pTSInfo = &TSpec.f.TSInfo;
- struct list_head* pUnusedList =
- (TxRxSelect == TX_DIR)?
- (&ieee->Tx_TS_Unused_List):
- (&ieee->Rx_TS_Unused_List);
-
- struct list_head* pAddmitList =
- (TxRxSelect == TX_DIR)?
- (&ieee->Tx_TS_Admit_List):
- (&ieee->Rx_TS_Admit_List);
-
- DIRECTION_VALUE Dir = (ieee->iw_mode == IW_MODE_MASTER)?
- ((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
- ((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
- IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
- if(!list_empty(pUnusedList))
- {
- (*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
- list_del_init(&(*ppTS)->List);
- if(TxRxSelect==TX_DIR)
- {
- PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
- ResetTxTsEntry(tmp);
- }
- else{
- PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);
- ResetRxTsEntry(tmp);
- }
-
- IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
- // Prepare TS Info releated field
- pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
- pTSInfo->field.ucTSID = UP; // TSID
- pTSInfo->field.ucDirection = Dir; // Direction: if there is DirectLink, this need additional consideration.
- pTSInfo->field.ucAccessPolicy = 1; // Access policy
- pTSInfo->field.ucAggregation = 0; // Aggregation
- pTSInfo->field.ucPSB = 0; // Aggregation
- pTSInfo->field.ucUP = UP; // User priority
- pTSInfo->field.ucTSInfoAckPolicy = 0; // Ack policy
- pTSInfo->field.ucSchedule = 0; // Schedule
-
- MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
- AdmitTS(ieee, *ppTS, 0);
- list_add_tail(&((*ppTS)->List), pAddmitList);
- // if there is DirectLink, we need to do additional operation here!!
-
- return true;
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__);
- return false;
- }
- }
- }
-}
-
-void RemoveTsEntry(
- struct ieee80211_device* ieee,
- PTS_COMMON_INFO pTs,
- TR_SELECT TxRxSelect
- )
-{
- unsigned long flags = 0;
- del_timer_sync(&pTs->SetupTimer);
- del_timer_sync(&pTs->InactTimer);
- TsInitDelBA(ieee, pTs, TxRxSelect);
-
- if(TxRxSelect == RX_DIR)
- {
- PRX_REORDER_ENTRY pRxReorderEntry;
- PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs;
- if(timer_pending(&pRxTS->RxPktPendingTimer))
- del_timer_sync(&pRxTS->RxPktPendingTimer);
-
- while(!list_empty(&pRxTS->RxPendingPktList))
- {
- spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
- pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
- list_del_init(&pRxReorderEntry->List);
- {
- int i = 0;
- struct ieee80211_rxb * prxb = pRxReorderEntry->prxb;
- if (unlikely(!prxb))
- {
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
- return;
- }
- for(i =0; i < prxb->nr_subframes; i++) {
- dev_kfree_skb(prxb->subframes[i]);
- }
- kfree(prxb);
- prxb = NULL;
- }
- list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
- spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
- }
- }
- else
- {
- PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
- del_timer_sync(&pTxTS->TsAddBaTimer);
- }
-}
-
-void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
-{
- PTS_COMMON_INFO pTS, pTmpTS;
-
- printk("===========>RemovePeerTS,%pM\n", Addr);
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
- {
- if (memcmp(pTS->Addr, Addr, 6) == 0)
- {
- RemoveTsEntry(ieee, pTS, TX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
- {
- if (memcmp(pTS->Addr, Addr, 6) == 0)
- {
- printk("====>remove Tx_TS_admin_list\n");
- RemoveTsEntry(ieee, pTS, TX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
- {
- if (memcmp(pTS->Addr, Addr, 6) == 0)
- {
- RemoveTsEntry(ieee, pTS, RX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
- }
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
- {
- if (memcmp(pTS->Addr, Addr, 6) == 0)
- {
- RemoveTsEntry(ieee, pTS, RX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
- }
- }
-}
-
-void RemoveAllTS(struct ieee80211_device* ieee)
-{
- PTS_COMMON_INFO pTS, pTmpTS;
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
- {
- RemoveTsEntry(ieee, pTS, TX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
- {
- RemoveTsEntry(ieee, pTS, TX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
- {
- RemoveTsEntry(ieee, pTS, RX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
- }
-
- list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
- {
- RemoveTsEntry(ieee, pTS, RX_DIR);
- list_del_init(&pTS->List);
- list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
- }
-}
-
-void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS)
-{
- if(pTxTS->bAddBaReqInProgress == false)
- {
- pTxTS->bAddBaReqInProgress = true;
- if(pTxTS->bAddBaReqDelayed)
- {
- IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
- mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
- }
- else
- {
- IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
- mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks
- }
- }
- else
- IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
-}
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.c b/drivers/staging/rtl8192su/r8192SU_HWImg.c
deleted file mode 100644
index 7c4fd18d89c6..000000000000
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*Created on 2009/ 1/15, 3:10*/
-
-#include "r8192SU_HWImg.h"
-
-u8 Rtl8192SUFwMainArray[MainArrayLength] = {
-0x0, };
-
-u8 Rtl8192SUFwDataArray[DataArrayLength] = {
-0x0, };
-
-u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength] = {
-0x01c,0x07000000,
-0x800,0x00040000,
-0x804,0x00008003,
-0x808,0x0000fc00,
-0x80c,0x0000000a,
-0x810,0x10005088,
-0x814,0x020c3d10,
-0x818,0x00200185,
-0x81c,0x00000000,
-0x820,0x01000000,
-0x824,0x00390004,
-0x828,0x01000000,
-0x82c,0x00390004,
-0x830,0x00000004,
-0x834,0x00690200,
-0x838,0x00000004,
-0x83c,0x00690200,
-0x840,0x00010000,
-0x844,0x00010000,
-0x848,0x00000000,
-0x84c,0x00000000,
-0x850,0x00000000,
-0x854,0x00000000,
-0x858,0x48484848,
-0x85c,0x65a965a9,
-0x860,0x0f7f0130,
-0x864,0x0f7f0130,
-0x868,0x0f7f0130,
-0x86c,0x0f7f0130,
-0x870,0x03000700,
-0x874,0x03000300,
-0x878,0x00020002,
-0x87c,0x004f0201,
-0x880,0xa8300ac1,
-0x884,0x00000058,
-0x888,0x00000008,
-0x88c,0x00000004,
-0x890,0x00000000,
-0x894,0xfffffffe,
-0x898,0x40302010,
-0x89c,0x00706050,
-0x8b0,0x00000000,
-0x8e0,0x00000000,
-0x8e4,0x00000000,
-0xe00,0x30333333,
-0xe04,0x2a2d2e2f,
-0xe08,0x00003232,
-0xe10,0x30333333,
-0xe14,0x2a2d2e2f,
-0xe18,0x30333333,
-0xe1c,0x2a2d2e2f,
-0xe30,0x01007c00,
-0xe34,0x01004800,
-0xe38,0x1000dc1f,
-0xe3c,0x10008c1f,
-0xe40,0x021400a0,
-0xe44,0x281600a0,
-0xe48,0xf8000001,
-0xe4c,0x00002910,
-0xe50,0x01007c00,
-0xe54,0x01004800,
-0xe58,0x1000dc1f,
-0xe5c,0x10008c1f,
-0xe60,0x021400a0,
-0xe64,0x281600a0,
-0xe6c,0x00002910,
-0xe70,0x31ed92fb,
-0xe74,0x361536fb,
-0xe78,0x361536fb,
-0xe7c,0x361536fb,
-0xe80,0x361536fb,
-0xe84,0x000d92fb,
-0xe88,0x000d92fb,
-0xe8c,0x31ed92fb,
-0xed0,0x31ed92fb,
-0xed4,0x31ed92fb,
-0xed8,0x000d92fb,
-0xedc,0x000d92fb,
-0xee0,0x000d92fb,
-0xee4,0x015e5448,
-0xee8,0x21555448,
-0x900,0x00000000,
-0x904,0x00000023,
-0x908,0x00000000,
-0x90c,0x01121313,
-0xa00,0x00d047c8,
-0xa04,0x80ff0008,
-0xa08,0x8ccd8300,
-0xa0c,0x2e62120f,
-0xa10,0x9500bb78,
-0xa14,0x11144028,
-0xa18,0x00881117,
-0xa1c,0x89140f00,
-0xa20,0x1a1b0000,
-0xa24,0x090e1317,
-0xa28,0x00000204,
-0xa2c,0x10d30000,
-0xc00,0x40071d40,
-0xc04,0x00a05633,
-0xc08,0x000000e4,
-0xc0c,0x6c6c6c6c,
-0xc10,0x08800000,
-0xc14,0x40000100,
-0xc18,0x08000000,
-0xc1c,0x40000100,
-0xc20,0x08000000,
-0xc24,0x40000100,
-0xc28,0x08000000,
-0xc2c,0x40000100,
-0xc30,0x6de9ac44,
-0xc34,0x469652cf,
-0xc38,0x49795994,
-0xc3c,0x0a979764,
-0xc40,0x1f7c403f,
-0xc44,0x000100b7,
-0xc48,0xec020000,
-0xc4c,0x007f037f,
-0xc50,0x69543420,
-0xc54,0x433c0094,
-0xc58,0x69543420,
-0xc5c,0x433c0094,
-0xc60,0x69543420,
-0xc64,0x433c0094,
-0xc68,0x69543420,
-0xc6c,0x433c0094,
-0xc70,0x2c7f000d,
-0xc74,0x0186175b,
-0xc78,0x0000001f,
-0xc7c,0x00b91612,
-0xc80,0x40000100,
-0xc84,0x20f60000,
-0xc88,0x20000080,
-0xc8c,0x20200000,
-0xc90,0x40000100,
-0xc94,0x00000000,
-0xc98,0x40000100,
-0xc9c,0x00000000,
-0xca0,0x00492492,
-0xca4,0x00000000,
-0xca8,0x00000000,
-0xcac,0x00000000,
-0xcb0,0x00000000,
-0xcb4,0x00000000,
-0xcb8,0x00000000,
-0xcbc,0x28000000,
-0xcc0,0x00000000,
-0xcc4,0x00000000,
-0xcc8,0x00000000,
-0xccc,0x00000000,
-0xcd0,0x00000000,
-0xcd4,0x00000000,
-0xcd8,0x64b22427,
-0xcdc,0x00766932,
-0xce0,0x00222222,
-0xce4,0x00000000,
-0xce8,0x37644302,
-0xcec,0x2f97d40c,
-0xd00,0x00000750,
-0xd04,0x00000403,
-0xd08,0x0000907f,
-0xd0c,0x00000001,
-0xd10,0xa0633333,
-0xd14,0x33333c63,
-0xd18,0x6a8f5b6b,
-0xd1c,0x00000000,
-0xd20,0x00000000,
-0xd24,0x00000000,
-0xd28,0x00000000,
-0xd2c,0xcc979975,
-0xd30,0x00000000,
-0xd34,0x00000000,
-0xd38,0x00000000,
-0xd3c,0x00027293,
-0xd40,0x00000000,
-0xd44,0x00000000,
-0xd48,0x00000000,
-0xd50,0x6437140a,
-0xd54,0x024dbd02,
-0xd58,0x00000000,
-0xd5c,0x30032064,
-0xd60,0x4653de68,
-0xd64,0x00518a3c,
-0xd68,0x00002101,
-0xf14,0x00000003,
-0xf4c,0x00000000,
-0xf00,0x00000300,
-};
-
-u32 Rtl8192SUPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = {
-0x0, };
-
-u32 Rtl8192SUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength] = {
-0x844,0xffffffff,0x00010000,
-0x804,0x0000000f,0x00000001,
-0x824,0x00f0000f,0x00300004,
-0x82c,0x00f0000f,0x00100002,
-0x870,0x04000000,0x00000001,
-0x864,0x00000400,0x00000000,
-0x878,0x000f000f,0x00000002,
-0xe74,0x0f000000,0x00000002,
-0xe78,0x0f000000,0x00000002,
-0xe7c,0x0f000000,0x00000002,
-0xe80,0x0f000000,0x00000002,
-0x90c,0x000000ff,0x00000011,
-0xc04,0x000000ff,0x00000011,
-0xd04,0x0000000f,0x00000001,
-0x1f4,0xffff0000,0x00007777,
-0x234,0xf8000000,0x0000000a,
-};
-
-u32 Rtl8192SUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength] = {
-0x804,0x0000000f,0x00000003,
-0x824,0x00f0000f,0x00300004,
-0x82c,0x00f0000f,0x00300002,
-0x870,0x04000000,0x00000001,
-0x864,0x00000400,0x00000000,
-0x878,0x000f000f,0x00000002,
-0xe74,0x0f000000,0x00000002,
-0xe78,0x0f000000,0x00000002,
-0xe7c,0x0f000000,0x00000002,
-0xe80,0x0f000000,0x00000002,
-0x90c,0x000000ff,0x00000011,
-0xc04,0x000000ff,0x00000033,
-0xd04,0x0000000f,0x00000003,
-0x1f4,0xffff0000,0x00007777,
-0x234,0xf8000000,0x0000000a,
-};
-
-u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength] = {
-0x804,0x0000000f,0x00000003,
-0x824,0x00f0000f,0x00300004,
-0x82c,0x00f0000f,0x00300004,
-0x870,0x04000000,0x00000001,
-0x864,0x00000400,0x00000001,
-0x878,0x000f000f,0x00020002,
-0xe74,0x0f000000,0x00000006,
-0xe78,0x0f000000,0x00000006,
-0xe7c,0x0f000000,0x00000006,
-0xe80,0x0f000000,0x00000006,
-0x90c,0x000000ff,0x00000033,
-0xc04,0x000000ff,0x00000033,
-0xd04,0x0000000f,0x00000003,
-0x1f4,0xffff0000,0x0000ffff,
-0x234,0xf8000000,0x00000013,
-};
-
-u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength] = {
-0xe00,0xffffffff,0x04060606,
-0xe04,0xffffffff,0x00020204,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x0408080a,
-0xe14,0xffffffff,0x00020204,
-0xe18,0xffffffff,0x0408080a,
-0xe1c,0xffffffff,0x00020204,
-0xe00,0xffffffff,0x00000000,
-0xe04,0xffffffff,0x00000000,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x00000000,
-0xe14,0xffffffff,0x00000000,
-0xe18,0xffffffff,0x00000000,
-0xe1c,0xffffffff,0x00000000,
-0xe00,0xffffffff,0x00000000,
-0xe04,0xffffffff,0x00000000,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x00000000,
-0xe14,0xffffffff,0x00000000,
-0xe18,0xffffffff,0x00000000,
-0xe1c,0xffffffff,0x00000000,
-0xe00,0xffffffff,0x00000000,
-0xe04,0xffffffff,0x00000000,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x00000000,
-0xe14,0xffffffff,0x00000000,
-0xe18,0xffffffff,0x00000000,
-0xe1c,0xffffffff,0x00000000,
-};
-
-u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength] = {
-0x000,0x00030159,
-0x001,0x00030250,
-0x002,0x00010000,
-0x010,0x0008000f,
-0x011,0x000231fc,
-0x010,0x000c000f,
-0x011,0x0003f9f8,
-0x010,0x0002000f,
-0x011,0x00020101,
-0x014,0x0001093e,
-0x014,0x0009093e,
-0x015,0x000198f4,
-0x017,0x000f6500,
-0x01a,0x00013056,
-0x01b,0x00060000,
-0x01c,0x00000300,
-0x01e,0x00031059,
-0x021,0x00054000,
-0x022,0x0000083c,
-0x023,0x00001558,
-0x024,0x00000060,
-0x025,0x00022583,
-0x026,0x0000f200,
-0x027,0x000eacf1,
-0x028,0x0009bd54,
-0x029,0x00004582,
-0x02a,0x00000001,
-0x02b,0x00021334,
-0x02a,0x00000000,
-0x02b,0x0000000a,
-0x02a,0x00000001,
-0x02b,0x00000808,
-0x02b,0x00053333,
-0x02c,0x0000000c,
-0x02a,0x00000002,
-0x02b,0x00000808,
-0x02b,0x0005b333,
-0x02c,0x0000000d,
-0x02a,0x00000003,
-0x02b,0x00000808,
-0x02b,0x00063333,
-0x02c,0x0000000d,
-0x02a,0x00000004,
-0x02b,0x00000808,
-0x02b,0x0006b333,
-0x02c,0x0000000d,
-0x02a,0x00000005,
-0x02b,0x00000709,
-0x02b,0x00053333,
-0x02c,0x0000000d,
-0x02a,0x00000006,
-0x02b,0x00000709,
-0x02b,0x0005b333,
-0x02c,0x0000000d,
-0x02a,0x00000007,
-0x02b,0x00000709,
-0x02b,0x00063333,
-0x02c,0x0000000d,
-0x02a,0x00000008,
-0x02b,0x00000709,
-0x02b,0x0006b333,
-0x02c,0x0000000d,
-0x02a,0x00000009,
-0x02b,0x0000060a,
-0x02b,0x00053333,
-0x02c,0x0000000d,
-0x02a,0x0000000a,
-0x02b,0x0000060a,
-0x02b,0x0005b333,
-0x02c,0x0000000d,
-0x02a,0x0000000b,
-0x02b,0x0000060a,
-0x02b,0x00063333,
-0x02c,0x0000000d,
-0x02a,0x0000000c,
-0x02b,0x0000060a,
-0x02b,0x0006b333,
-0x02c,0x0000000d,
-0x02a,0x0000000d,
-0x02b,0x0000050b,
-0x02b,0x00053333,
-0x02c,0x0000000d,
-0x02a,0x0000000e,
-0x02b,0x0000050b,
-0x02b,0x00066623,
-0x02c,0x0000001a,
-0x02a,0x000e4000,
-0x030,0x00020000,
-0x031,0x000b9631,
-0x032,0x0000130d,
-0x033,0x00000187,
-0x013,0x00019e6c,
-0x013,0x00015e94,
-0x000,0x00010159,
-0x018,0x0000f401,
-0x0fe,0x00000000,
-0x01e,0x0003105b,
-0x0fe,0x00000000,
-0x000,0x00030159,
-0x010,0x0004000f,
-0x011,0x000203f9,
-};
-
-u32 Rtl8192SURadioB_Array[RadioB_ArrayLength] = {
-0x000,0x00030159,
-0x001,0x00001041,
-0x002,0x00011000,
-0x005,0x00080fc0,
-0x007,0x000fc803,
-0x013,0x00017cb0,
-0x013,0x00011cc0,
-0x013,0x0000dc60,
-0x013,0x00008c60,
-0x013,0x00004450,
-0x013,0x00000020,
-};
-
-u32 Rtl8192SURadioA_to1T_Array[RadioA_to1T_ArrayLength] = {
-0x000,0x00000000,
-};
-
-u32 Rtl8192SURadioA_to2T_Array[RadioA_to2T_ArrayLength] = {
-0x000,0x00000000,
-};
-
-u32 Rtl8192SURadioB_GM_Array[RadioB_GM_ArrayLength] = {
-0x000,0x00030159,
-0x001,0x00001041,
-0x002,0x00011000,
-0x005,0x00080fc0,
-0x007,0x000fc803,
-0x013,0x0000bef0,
-0x013,0x00007e90,
-0x013,0x00003e30,
-};
-
-u32 Rtl8192SUMAC_2T_Array[MAC_2T_ArrayLength] = {
-0x020,0x00000035,
-0x048,0x0000000e,
-0x049,0x000000f0,
-0x04a,0x00000077,
-0x04b,0x00000083,
-0x0b5,0x00000021,
-0x0dc,0x000000ff,
-0x0dd,0x000000ff,
-0x0de,0x000000ff,
-0x0df,0x000000ff,
-0x116,0x00000000,
-0x117,0x00000000,
-0x118,0x00000000,
-0x119,0x00000000,
-0x11a,0x00000000,
-0x11b,0x00000000,
-0x11c,0x00000000,
-0x11d,0x00000000,
-0x160,0x0000000b,
-0x161,0x0000000b,
-0x162,0x0000000b,
-0x163,0x0000000b,
-0x164,0x0000000b,
-0x165,0x0000000b,
-0x166,0x0000000b,
-0x167,0x0000000b,
-0x168,0x0000000b,
-0x169,0x0000000b,
-0x16a,0x0000000b,
-0x16b,0x0000000b,
-0x16c,0x0000000b,
-0x16d,0x0000000b,
-0x16e,0x0000000b,
-0x16f,0x0000000b,
-0x170,0x0000000b,
-0x171,0x0000000b,
-0x172,0x0000000b,
-0x173,0x0000000b,
-0x174,0x0000000b,
-0x175,0x0000000b,
-0x176,0x0000000b,
-0x177,0x0000000b,
-0x178,0x0000000b,
-0x179,0x0000000b,
-0x17a,0x0000000b,
-0x17b,0x0000000b,
-0x17c,0x0000000b,
-0x17d,0x0000000b,
-0x17e,0x0000000b,
-0x17f,0x0000000b,
-0x236,0x0000000c,
-0x503,0x00000022,
-0x560,0x00000009,
-};
-
-u32 Rtl8192SUMACPHY_Array_PG[MACPHY_Array_PGLength] = {
-0x0, };
-
-u32 Rtl8192SUAGCTAB_Array[AGCTAB_ArrayLength] = {
-0xc78,0x7f000001,
-0xc78,0x7f010001,
-0xc78,0x7e020001,
-0xc78,0x7d030001,
-0xc78,0x7c040001,
-0xc78,0x7b050001,
-0xc78,0x7a060001,
-0xc78,0x79070001,
-0xc78,0x78080001,
-0xc78,0x77090001,
-0xc78,0x760a0001,
-0xc78,0x750b0001,
-0xc78,0x740c0001,
-0xc78,0x730d0001,
-0xc78,0x720e0001,
-0xc78,0x710f0001,
-0xc78,0x70100001,
-0xc78,0x6f110001,
-0xc78,0x6f120001,
-0xc78,0x6e130001,
-0xc78,0x6d140001,
-0xc78,0x6d150001,
-0xc78,0x6c160001,
-0xc78,0x6b170001,
-0xc78,0x6a180001,
-0xc78,0x6a190001,
-0xc78,0x691a0001,
-0xc78,0x681b0001,
-0xc78,0x671c0001,
-0xc78,0x661d0001,
-0xc78,0x651e0001,
-0xc78,0x641f0001,
-0xc78,0x63200001,
-0xc78,0x4c210001,
-0xc78,0x4b220001,
-0xc78,0x4a230001,
-0xc78,0x49240001,
-0xc78,0x48250001,
-0xc78,0x47260001,
-0xc78,0x46270001,
-0xc78,0x45280001,
-0xc78,0x44290001,
-0xc78,0x2c2a0001,
-0xc78,0x2b2b0001,
-0xc78,0x2a2c0001,
-0xc78,0x292d0001,
-0xc78,0x282e0001,
-0xc78,0x272f0001,
-0xc78,0x26300001,
-0xc78,0x25310001,
-0xc78,0x24320001,
-0xc78,0x23330001,
-0xc78,0x22340001,
-0xc78,0x09350001,
-0xc78,0x08360001,
-0xc78,0x07370001,
-0xc78,0x06380001,
-0xc78,0x05390001,
-0xc78,0x043a0001,
-0xc78,0x033b0001,
-0xc78,0x023c0001,
-0xc78,0x013d0001,
-0xc78,0x003e0001,
-0xc78,0x003f0001,
-0xc78,0x7f400001,
-0xc78,0x7f410001,
-0xc78,0x7e420001,
-0xc78,0x7d430001,
-0xc78,0x7c440001,
-0xc78,0x7b450001,
-0xc78,0x7a460001,
-0xc78,0x79470001,
-0xc78,0x78480001,
-0xc78,0x77490001,
-0xc78,0x764a0001,
-0xc78,0x754b0001,
-0xc78,0x744c0001,
-0xc78,0x734d0001,
-0xc78,0x724e0001,
-0xc78,0x714f0001,
-0xc78,0x70500001,
-0xc78,0x6f510001,
-0xc78,0x6f520001,
-0xc78,0x6e530001,
-0xc78,0x6d540001,
-0xc78,0x6d550001,
-0xc78,0x6c560001,
-0xc78,0x6b570001,
-0xc78,0x6a580001,
-0xc78,0x6a590001,
-0xc78,0x695a0001,
-0xc78,0x685b0001,
-0xc78,0x675c0001,
-0xc78,0x665d0001,
-0xc78,0x655e0001,
-0xc78,0x645f0001,
-0xc78,0x63600001,
-0xc78,0x4c610001,
-0xc78,0x4b620001,
-0xc78,0x4a630001,
-0xc78,0x49640001,
-0xc78,0x48650001,
-0xc78,0x47660001,
-0xc78,0x46670001,
-0xc78,0x45680001,
-0xc78,0x44690001,
-0xc78,0x2c6a0001,
-0xc78,0x2b6b0001,
-0xc78,0x2a6c0001,
-0xc78,0x296d0001,
-0xc78,0x286e0001,
-0xc78,0x276f0001,
-0xc78,0x26700001,
-0xc78,0x25710001,
-0xc78,0x24720001,
-0xc78,0x23730001,
-0xc78,0x22740001,
-0xc78,0x09750001,
-0xc78,0x08760001,
-0xc78,0x07770001,
-0xc78,0x06780001,
-0xc78,0x05790001,
-0xc78,0x047a0001,
-0xc78,0x037b0001,
-0xc78,0x027c0001,
-0xc78,0x017d0001,
-0xc78,0x007e0001,
-0xc78,0x007f0001,
-0xc78,0x3000001e,
-0xc78,0x3001001e,
-0xc78,0x3002001e,
-0xc78,0x3003001e,
-0xc78,0x3004001e,
-0xc78,0x3405001e,
-0xc78,0x3806001e,
-0xc78,0x3e07001e,
-0xc78,0x3e08001e,
-0xc78,0x4409001e,
-0xc78,0x460a001e,
-0xc78,0x480b001e,
-0xc78,0x480c001e,
-0xc78,0x4e0d001e,
-0xc78,0x560e001e,
-0xc78,0x5a0f001e,
-0xc78,0x5e10001e,
-0xc78,0x6211001e,
-0xc78,0x6c12001e,
-0xc78,0x7213001e,
-0xc78,0x7214001e,
-0xc78,0x7215001e,
-0xc78,0x7216001e,
-0xc78,0x7217001e,
-0xc78,0x7218001e,
-0xc78,0x7219001e,
-0xc78,0x721a001e,
-0xc78,0x721b001e,
-0xc78,0x721c001e,
-0xc78,0x721d001e,
-0xc78,0x721e001e,
-0xc78,0x721f001e,
-};
-
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.h b/drivers/staging/rtl8192su/r8192SU_HWImg.h
deleted file mode 100644
index 69a66c399606..000000000000
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef __INC_HAL8192SU_FW_IMG_H
-#define __INC_HAL8192SU_FW_IMG_H
-
-#include <linux/types.h>
-
-/*Created on 2009/ 3/ 6, 5:29*/
-
-#define MainArrayLength 1
-extern u8 Rtl8192SUFwMainArray[MainArrayLength];
-#define DataArrayLength 1
-extern u8 Rtl8192SUFwDataArray[DataArrayLength];
-#define PHY_REG_2T2RArrayLength 372
-extern u32 Rtl8192SUPHY_REG_2T2RArray[PHY_REG_2T2RArrayLength];
-#define PHY_REG_1T2RArrayLength 1
-extern u32 Rtl8192SUPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength];
-#define PHY_ChangeTo_1T1RArrayLength 48
-extern u32 Rtl8192SUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength];
-#define PHY_ChangeTo_1T2RArrayLength 45
-extern u32 Rtl8192SUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength];
-#define PHY_ChangeTo_2T2RArrayLength 45
-extern u32 Rtl8192SUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength];
-#define PHY_REG_Array_PGLength 84
-extern u32 Rtl8192SUPHY_REG_Array_PG[PHY_REG_Array_PGLength];
-#define RadioA_1T_ArrayLength 202
-extern u32 Rtl8192SURadioA_1T_Array[RadioA_1T_ArrayLength];
-#define RadioB_ArrayLength 22
-extern u32 Rtl8192SURadioB_Array[RadioB_ArrayLength];
-#define RadioA_to1T_ArrayLength 2
-extern u32 Rtl8192SURadioA_to1T_Array[RadioA_to1T_ArrayLength];
-#define RadioA_to2T_ArrayLength 2
-extern u32 Rtl8192SURadioA_to2T_Array[RadioA_to2T_ArrayLength];
-#define RadioB_GM_ArrayLength 16
-extern u32 Rtl8192SURadioB_GM_Array[RadioB_GM_ArrayLength];
-#define MAC_2T_ArrayLength 106
-extern u32 Rtl8192SUMAC_2T_Array[MAC_2T_ArrayLength];
-#define MACPHY_Array_PGLength 1
-extern u32 Rtl8192SUMACPHY_Array_PG[MACPHY_Array_PGLength];
-#define AGCTAB_ArrayLength 320
-extern u32 Rtl8192SUAGCTAB_Array[AGCTAB_ArrayLength];
-
-#endif
-
diff --git a/drivers/staging/rtl8192su/r8192SU_led.c b/drivers/staging/rtl8192su/r8192SU_led.c
deleted file mode 100644
index 5d96b356bf12..000000000000
--- a/drivers/staging/rtl8192su/r8192SU_led.c
+++ /dev/null
@@ -1,2338 +0,0 @@
-/*
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
- */
-
-#include "r8192U.h"
-#include "r8192S_hw.h"
-#include "r8192SU_led.h"
-
-#define LED_BLINK_NORMAL_INTERVAL 100
-#define LED_BLINK_SLOWLY_INTERVAL 200
-#define LED_BLINK_LONG_INTERVAL 400
-
-#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000
-#define LED_BLINK_LINK_INTERVAL_ALPHA 500
-#define LED_BLINK_SCAN_INTERVAL_ALPHA 180
-#define LED_BLINK_FASTER_INTERVAL_ALPHA 50
-#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000
-
-
-
-static void BlinkTimerCallback (unsigned long data);
-
-static void BlinkWorkItemCallback (struct work_struct *work);
-
-void InitLed819xUsb (struct net_device *dev, PLED_819xUsb pLed,
- LED_PIN_819xUsb LedPin)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- pLed->dev = dev;
- pLed->LedPin = LedPin;
- pLed->CurrLedState = LED_OFF;
- pLed->bLedOn = FALSE;
-
- pLed->bLedBlinkInProgress = FALSE;
- pLed->BlinkTimes = 0;
- pLed->BlinkingLedState = LED_OFF;
-
- init_timer(&pLed->BlinkTimer);
- pLed->BlinkTimer.data = (unsigned long)dev;
- pLed->BlinkTimer.function = BlinkTimerCallback;
-
- INIT_WORK(&priv->BlinkWorkItem, (void*)BlinkWorkItemCallback);
- priv->pLed = pLed;
-}
-
-
-void DeInitLed819xUsb (PLED_819xUsb pLed)
-{
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
-}
-
-void SwLedOn (struct net_device *dev, PLED_819xUsb pLed)
-{
- u8 LedCfg;
-
- LedCfg = read_nic_byte(dev, LEDCFG);
- switch (pLed->LedPin) {
- case LED_PIN_GPIO0:
- break;
- case LED_PIN_LED0:
- write_nic_byte(dev, LEDCFG, LedCfg&0xf0);
- break;
- case LED_PIN_LED1:
- write_nic_byte(dev, LEDCFG, LedCfg&0x0f);
- break;
- default:
- break;
- }
- pLed->bLedOn = TRUE;
-}
-
-void SwLedOff (struct net_device *dev, PLED_819xUsb pLed)
-{
- u8 LedCfg;
-
- LedCfg = read_nic_byte(dev, LEDCFG);
- switch (pLed->LedPin) {
- case LED_PIN_GPIO0:
- break;
- case LED_PIN_LED0:
- LedCfg &= 0xf0;
- write_nic_byte(dev, LEDCFG, (LedCfg|BIT3));
- break;
- case LED_PIN_LED1:
- LedCfg &= 0x0f;
- write_nic_byte(dev, LEDCFG, (LedCfg|BIT7));
- break;
- default:
- break;
- }
- pLed->bLedOn = FALSE;
-}
-
-
-void
-InitSwLeds(
- struct net_device *dev
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- InitLed819xUsb(dev, &(priv->SwLed0), LED_PIN_LED0);
-
- InitLed819xUsb(dev,&(priv->SwLed1), LED_PIN_LED1);
-}
-
-
-void
-DeInitSwLeds(
- struct net_device *dev
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- DeInitLed819xUsb( &(priv->SwLed0) );
- DeInitLed819xUsb( &(priv->SwLed1) );
-}
-
-
-void
-SwLedBlink(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bStopBlinking = FALSE;
-
- if( pLed->BlinkingLedState == LED_ON )
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
- pLed->BlinkTimes--;
- switch(pLed->CurrLedState)
- {
-
- case LED_BLINK_NORMAL:
- if(pLed->BlinkTimes == 0)
- {
- bStopBlinking = TRUE;
- }
- break;
-
- case LED_BLINK_StartToBlink:
- if( (priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA))
- {
- bStopBlinking = TRUE;
- }
- else if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_ADHOC))
- {
- bStopBlinking = TRUE;
- }
- else if(pLed->BlinkTimes == 0)
- {
- bStopBlinking = TRUE;
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
- break;
-
-
- default:
- bStopBlinking = TRUE;
- break;
-
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if( (priv->ieee80211->state == IEEE80211_LINKED) && (pLed->bLedOn == false))
- {
- SwLedOn(dev, pLed);
- }
- else if( (priv->ieee80211->state != IEEE80211_LINKED) && pLed->bLedOn == true)
- {
- SwLedOff(dev, pLed);
- }
-
- pLed->BlinkTimes = 0;
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( pLed->BlinkingLedState == LED_ON )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
-
- switch( pLed->CurrLedState )
- {
- case LED_BLINK_NORMAL:
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- break;
-
- case LED_BLINK_SLOWLY:
- case LED_BLINK_StartToBlink:
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- break;
-
- case LED_BLINK_WPS:
- {
- if( pLed->BlinkingLedState == LED_ON )
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL));
- else
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL));
- }
- break;
-
- default:
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- break;
- }
- }
-}
-
-
-void
-SwLedBlink1(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed1 = &(priv->SwLed1);
- bool bStopBlinking = FALSE;
-
- if(priv->CustomerID == RT_CID_819x_CAMEO)
- pLed = &(priv->SwLed1);
-
- if( pLed->BlinkingLedState == LED_ON )
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
-
- if(priv->CustomerID == RT_CID_DEFAULT)
- {
- if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- if(!pLed1->bSWLedCtrl)
- {
- SwLedOn(dev, pLed1);
- pLed1->bSWLedCtrl = TRUE;
- }
- else if(!pLed1->bLedOn)
- SwLedOn(dev, pLed1);
- RT_TRACE(COMP_LED, "Blinktimes (): turn on pLed1\n");
- }
- else
- {
- if(!pLed1->bSWLedCtrl)
- {
- SwLedOff(dev, pLed1);
- pLed1->bSWLedCtrl = TRUE;
- }
- else if(pLed1->bLedOn)
- SwLedOff(dev, pLed1);
- RT_TRACE(COMP_LED, "Blinktimes (): turn off pLed1\n");
- }
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SLOWLY:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- break;
-
- case LED_BLINK_NORMAL:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- break;
-
- case LED_SCAN_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->bLedLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
-
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_TXRX_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->bLedLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->BlinkTimes = 0;
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- break;
-
- case LED_BLINK_WPS_STOP:
- if(pLed->BlinkingLedState == LED_ON)
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
- bStopBlinking = FALSE;
- }
- else
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->bLedLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
- break;
-
- default:
- break;
- }
-
-}
-
-void
-SwLedBlink2(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bStopBlinking = FALSE;
-
- if( pLed->BlinkingLedState == LED_ON)
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_SCAN_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "eRFPowerState %d\n", priv->ieee80211->eRFPowerState);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "stop scan blink CurrLedState %d\n", pLed->CurrLedState);
-
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "stop scan blink CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_TXRX_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "stop CurrLedState %d\n", pLed->CurrLedState);
-
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "stop CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- }
- break;
-
- default:
- break;
- }
-
-}
-
-void
-SwLedBlink3(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bStopBlinking = FALSE;
-
- if( pLed->BlinkingLedState == LED_ON )
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- if(pLed->CurrLedState != LED_BLINK_WPS_STOP)
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_SCAN_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- if( !pLed->bLedOn )
- SwLedOn(dev, pLed);
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- if( pLed->bLedOn )
- SwLedOff(dev, pLed);
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_TXRX_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
-
- if( !pLed->bLedOn )
- SwLedOn(dev, pLed);
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- else if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
-
- if( pLed->bLedOn )
- SwLedOff(dev, pLed);
-
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- break;
-
- case LED_BLINK_WPS_STOP:
- if(pLed->BlinkingLedState == LED_ON)
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
- bStopBlinking = FALSE;
- }
- else
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
- break;
-
-
- default:
- break;
- }
-
-}
-
-
-void
-SwLedBlink4(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed1 = &(priv->SwLed1);
- bool bStopBlinking = FALSE;
-
- if( pLed->BlinkingLedState == LED_ON )
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
- if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN)
- {
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
- SwLedOff(dev, pLed1);
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SLOWLY:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- break;
-
- case LED_BLINK_StartToBlink:
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
- break;
-
- case LED_SCAN_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- }
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_TXRX_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- }
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
- break;
-
- case LED_BLINK_WPS_STOP:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
-
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- break;
-
- case LED_BLINK_WPS_STOP_OVERLAP:
- pLed->BlinkTimes--;
- if(pLed->BlinkTimes == 0)
- {
- if(pLed->bLedOn)
- {
- pLed->BlinkTimes = 1;
- }
- else
- {
- bStopBlinking = TRUE;
- }
- }
-
- if(bStopBlinking)
- {
- pLed->BlinkTimes = 10;
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
-
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
- break;
-
-
- default:
- break;
- }
-
- RT_TRACE(COMP_LED, "SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState);
-
-
-}
-
-void
-SwLedBlink5(
- PLED_819xUsb pLed
- )
-{
- struct net_device *dev = (struct net_device *)(pLed->dev);
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bStopBlinking = FALSE;
-
- if( pLed->BlinkingLedState == LED_ON )
- {
- SwLedOn(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- }
- else
- {
- SwLedOff(dev, pLed);
- RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_SCAN_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- if(pLed->bLedOn)
- SwLedOff(dev, pLed);
- }
- else
- { pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- if(!pLed->bLedOn)
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
-
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
- }
- }
- break;
-
-
- case LED_TXRX_BLINK:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = TRUE;
- }
-
- if(bStopBlinking)
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- if(pLed->bLedOn)
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- if(!pLed->bLedOn)
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
-
- pLed->bLedBlinkInProgress = FALSE;
- }
- else
- {
- if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- }
- break;
-
- default:
- break;
- }
-
- RT_TRACE(COMP_LED, "SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState);
-
-
-}
-
-
-void
-BlinkTimerCallback(
- unsigned long data
- )
-{
- struct net_device *dev = (struct net_device *)data;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- schedule_work(&(priv->BlinkWorkItem));
-}
-
-
-void BlinkWorkItemCallback(struct work_struct *work)
-{
- struct r8192_priv *priv = container_of(work, struct r8192_priv, BlinkWorkItem);
-
- PLED_819xUsb pLed = priv->pLed;
-
- switch(priv->LedStrategy)
- {
- case SW_LED_MODE0:
- SwLedBlink(pLed);
- break;
-
- case SW_LED_MODE1:
- SwLedBlink1(pLed);
- break;
-
- case SW_LED_MODE2:
- SwLedBlink2(pLed);
- break;
-
- case SW_LED_MODE3:
- SwLedBlink3(pLed);
- break;
-
- case SW_LED_MODE4:
- SwLedBlink4(pLed);
- break;
-
- case SW_LED_MODE5:
- SwLedBlink5(pLed);
- break;
-
- default:
- SwLedBlink(pLed);
- break;
- }
-}
-
-
-
-
-void
-SwLedControlMode0(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed1);
-
- switch(LedAction)
- {
- case LED_CTL_TX:
- case LED_CTL_RX:
- if( pLed->bLedBlinkInProgress == FALSE )
- {
- pLed->bLedBlinkInProgress = TRUE;
-
- pLed->CurrLedState = LED_BLINK_NORMAL;
- pLed->BlinkTimes = 2;
-
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
- break;
-
- case LED_CTL_START_TO_LINK:
- if( pLed->bLedBlinkInProgress == FALSE )
- {
- pLed->bLedBlinkInProgress = TRUE;
-
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- pLed->BlinkTimes = 24;
-
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- }
- else
- {
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- }
- break;
-
- case LED_CTL_LINK:
- pLed->CurrLedState = LED_ON;
- if( pLed->bLedBlinkInProgress == FALSE )
- {
- SwLedOn(dev, pLed);
- }
- break;
-
- case LED_CTL_NO_LINK:
- pLed->CurrLedState = LED_OFF;
- if( pLed->bLedBlinkInProgress == FALSE )
- {
- SwLedOff(dev, pLed);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- if(pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- SwLedOff(dev, pLed);
- break;
-
- case LED_CTL_START_WPS:
- if( pLed->bLedBlinkInProgress == FALSE || pLed->CurrLedState == LED_ON)
- {
- pLed->bLedBlinkInProgress = TRUE;
-
- pLed->CurrLedState = LED_BLINK_WPS;
- pLed->BlinkTimes = 20;
-
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL));
- }
- }
- break;
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedBlinkInProgress)
- {
- pLed->CurrLedState = LED_OFF;
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- break;
-
-
- default:
- break;
- }
-
- RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState);
-
-}
-
-void
-SwLedControlMode1(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed0);
-
- if(priv->CustomerID == RT_CID_819x_CAMEO)
- pLed = &(priv->SwLed1);
-
- switch(LedAction)
- {
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if( pLed->bLedNoLinkBlinkInProgress == FALSE )
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if( pLed->bLedLinkBlinkInProgress == TRUE )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_LINK:
- if( pLed->bLedLinkBlinkInProgress == FALSE )
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED))
- ;
- else if(pLed->bLedScanBlinkInProgress ==FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == TRUE )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedScanBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_SCAN_BLINK;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==FALSE)
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- }
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == TRUE )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- pLed->bLedBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_TXRX_BLINK;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_START_WPS:
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==FALSE)
- {
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == TRUE )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- pLed->bLedWPSBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == TRUE )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- }
- else
- {
- pLed->bLedWPSBlinkInProgress = TRUE;
- }
-
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if(pLed->bLedOn)
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- if( pLed->bLedNoLinkBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
-
- SwLedOff(dev, pLed);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState);
-}
-
-void
-SwLedControlMode2(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed0);
-
- switch(LedAction)
- {
- case LED_CTL_SITE_SURVEY:
- if(priv->ieee80211->LinkDetectInfo.bBusyTraffic)
- ;
- else if(pLed->bLedScanBlinkInProgress ==FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedScanBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_SCAN_BLINK;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if((pLed->bLedBlinkInProgress ==FALSE) && (priv->ieee80211->state == IEEE80211_LINKED))
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
-
- pLed->bLedBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_TXRX_BLINK;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_LINK:
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
-
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_WPS:
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==FALSE)
- {
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- pLed->bLedWPSBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_STOP_WPS:
- pLed->bLedWPSBlinkInProgress = FALSE;
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- pLed->bLedWPSBlinkInProgress = FALSE;
- if( priv->ieee80211->eRFPowerState != eRfOn )
- {
- SwLedOff(dev, pLed);
- }
- else
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
- }
- break;
-
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if(!IS_LED_BLINKING(pLed))
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
-}
-
- void
- SwLedControlMode3(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed0);
-
- switch(LedAction)
- {
- case LED_CTL_SITE_SURVEY:
- if(priv->ieee80211->LinkDetectInfo.bBusyTraffic)
- ;
- else if(pLed->bLedScanBlinkInProgress ==FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedScanBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_SCAN_BLINK;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if((pLed->bLedBlinkInProgress ==FALSE) && (priv->ieee80211->state == IEEE80211_LINKED))
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
-
- pLed->bLedBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_TXRX_BLINK;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_LINK:
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
-
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_WPS:
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==FALSE)
- {
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- pLed->bLedWPSBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
- else
- {
- pLed->bLedWPSBlinkInProgress = TRUE;
- }
-
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if(pLed->bLedOn)
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), 0);
- }
-
- break;
-
-
- case LED_CTL_STOP_WPS_FAIL:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if(!IS_LED_BLINKING(pLed))
- {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState);
-}
-
-
-void
-SwLedControlMode4(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed0);
- PLED_819xUsb pLed1 = &(priv->SwLed1);
-
- switch(LedAction)
- {
- case LED_CTL_START_TO_LINK:
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = FALSE;
- del_timer_sync(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
-
- if(pLed1->bLedOn)
- mod_timer(&(pLed1->BlinkTimer), 0);
- }
-
- if( pLed->bLedStartToLinkBlinkInProgress == FALSE )
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedNoLinkBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
-
- pLed->bLedStartToLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
- }
- break;
-
- case LED_CTL_LINK:
- case LED_CTL_NO_LINK:
- if(LedAction == LED_CTL_LINK)
- {
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = FALSE;
- del_timer_sync(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
-
- if(pLed1->bLedOn)
- mod_timer(&(pLed1->BlinkTimer), 0);
- }
- }
-
- if( pLed->bLedNoLinkBlinkInProgress == FALSE )
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
- }
-
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED))
- ;
- else if(pLed->bLedScanBlinkInProgress ==FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedScanBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_SCAN_BLINK;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==FALSE)
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- pLed->bLedBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_TXRX_BLINK;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_START_WPS:
- case LED_CTL_START_WPS_BOTTON:
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = FALSE;
- del_timer_sync(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
-
- if(pLed1->bLedOn)
- mod_timer(&(pLed1->BlinkTimer), 0);
- }
-
- if(pLed->bLedWPSBlinkInProgress ==FALSE)
- {
- if(pLed->bLedNoLinkBlinkInProgress == TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- pLed->bLedWPSBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = LED_OFF;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- }
- else
- {
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- }
-
- }
- break;
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
-
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
-
- if(pLed1->bLedWPSBlinkInProgress)
- del_timer_sync(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = TRUE;
-
- pLed1->CurrLedState = LED_BLINK_WPS_STOP;
- if( pLed1->bLedOn )
- pLed1->BlinkingLedState = LED_OFF;
- else
- pLed1->BlinkingLedState = LED_ON;
- mod_timer(&(pLed1->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
-
- break;
-
- case LED_CTL_STOP_WPS_FAIL_OVERLAP:
- if(pLed->bLedWPSBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
-
- if(pLed1->bLedWPSBlinkInProgress)
- del_timer_sync(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = TRUE;
-
- pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
- pLed1->BlinkTimes = 10;
- if( pLed1->bLedOn )
- pLed1->BlinkingLedState = LED_OFF;
- else
- pLed1->BlinkingLedState = LED_ON;
- mod_timer(&(pLed1->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
-
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
-
- if( pLed->bLedNoLinkBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = FALSE;
- }
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = FALSE;
- }
- if( pLed->bLedStartToLinkBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedStartToLinkBlinkInProgress = FALSE;
- }
-
- if( pLed1->bLedWPSBlinkInProgress )
- {
- del_timer_sync(&(pLed1->BlinkTimer));
- pLed1->bLedWPSBlinkInProgress = FALSE;
- }
-
-
- pLed1->BlinkingLedState = LED_UNKNOWN;
- SwLedOff(dev, pLed);
- SwLedOff(dev, pLed1);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState);
-}
-
-
-
-void
-SwLedControlMode5(
- struct net_device *dev,
- LED_CTL_MODE LedAction
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PLED_819xUsb pLed = &(priv->SwLed0);
-
- if(priv->CustomerID == RT_CID_819x_CAMEO)
- pLed = &(priv->SwLed1);
-
- switch(LedAction)
- {
- case LED_CTL_POWER_ON:
- case LED_CTL_NO_LINK:
- case LED_CTL_LINK:
- if(pLed->CurrLedState == LED_SCAN_BLINK)
- {
- return;
- }
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
- pLed->bLedBlinkInProgress = FALSE;
- mod_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED))
- ;
- else if(pLed->bLedScanBlinkInProgress ==FALSE)
- {
- if(pLed->bLedBlinkInProgress ==TRUE)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
- pLed->bLedScanBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_SCAN_BLINK;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA));
-
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==FALSE)
- {
- if(pLed->CurrLedState == LED_SCAN_BLINK)
- {
- return;
- }
- pLed->bLedBlinkInProgress = TRUE;
- pLed->CurrLedState = LED_TXRX_BLINK;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = LED_OFF;
- else
- pLed->BlinkingLedState = LED_ON;
- mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA));
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
-
- if( pLed->bLedBlinkInProgress)
- {
- del_timer_sync(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = FALSE;
- }
-
- SwLedOff(dev, pLed);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState);
-}
-
-
-void
-LedControl8192SUsb(
- struct net_device *dev,
- LED_CTL_MODE LedAction
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if( priv->bRegUseLed == FALSE)
- return;
-
- if (!priv->up)
- return;
-
- if(priv->bInHctTest)
- return;
-
- if( priv->ieee80211->eRFPowerState != eRfOn &&
- (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
- LedAction == LED_CTL_SITE_SURVEY ||
- LedAction == LED_CTL_LINK ||
- LedAction == LED_CTL_NO_LINK ||
- LedAction == LED_CTL_POWER_ON) )
- {
- return;
- }
-
- switch(priv->LedStrategy)
- {
- case SW_LED_MODE0:
- break;
-
- case SW_LED_MODE1:
- SwLedControlMode1(dev, LedAction);
- break;
- case SW_LED_MODE2:
- SwLedControlMode2(dev, LedAction);
- break;
-
- case SW_LED_MODE3:
- SwLedControlMode3(dev, LedAction);
- break;
-
- case SW_LED_MODE4:
- SwLedControlMode4(dev, LedAction);
- break;
-
- case SW_LED_MODE5:
- SwLedControlMode5(dev, LedAction);
- break;
-
- default:
- break;
- }
-
- RT_TRACE(COMP_LED, "LedStrategy:%d, LedAction %d\n", priv->LedStrategy,LedAction);
-}
-
-
diff --git a/drivers/staging/rtl8192su/r8192SU_led.h b/drivers/staging/rtl8192su/r8192SU_led.h
deleted file mode 100644
index acedae4a59ca..000000000000
--- a/drivers/staging/rtl8192su/r8192SU_led.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef __INC_HAL8192USBLED_H
-#define __INC_HAL8192USBLED_H
-
-#include <linux/types.h>
-#include <linux/timer.h>
-
-typedef enum _LED_STATE_819xUsb{
- LED_UNKNOWN = 0,
- LED_ON = 1,
- LED_OFF = 2,
- LED_BLINK_NORMAL = 3,
- LED_BLINK_SLOWLY = 4,
- LED_POWER_ON_BLINK = 5,
- LED_SCAN_BLINK = 6,
- LED_NO_LINK_BLINK = 7,
- LED_BLINK_StartToBlink = 8,
- LED_BLINK_WPS = 9,
- LED_TXRX_BLINK = 10,
- LED_BLINK_WPS_STOP = 11,
- LED_BLINK_WPS_STOP_OVERLAP = 12,
-
-}LED_STATE_819xUsb;
-
-#define IS_LED_WPS_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS \
- || ((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS_STOP \
- || ((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress)
-
-#define IS_LED_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress \
- ||((PLED_819xUsb)_LED_819xUsb)->bLedScanBlinkInProgress)
-
-typedef enum _LED_PIN_819xUsb{
- LED_PIN_GPIO0,
- LED_PIN_LED0,
- LED_PIN_LED1
-}LED_PIN_819xUsb;
-
-typedef enum _LED_STRATEGY_819xUsb{
- SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */
- SW_LED_MODE1, /* SW control for PCI Express */
- SW_LED_MODE2, /* SW control for Cameo. */
- SW_LED_MODE3, /* SW contorl for RunTop. */
- SW_LED_MODE4, /* SW control for Netcore */
- SW_LED_MODE5,
- HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) */
-}LED_STRATEGY_819xUsb, *PLED_STRATEGY_819xUsb;
-
-typedef struct _LED_819xUsb{
- struct net_device *dev;
-
- LED_PIN_819xUsb LedPin;
-
- LED_STATE_819xUsb CurrLedState;
- bool bLedOn;
-
- bool bSWLedCtrl;
-
- bool bLedBlinkInProgress;
- bool bLedNoLinkBlinkInProgress;
- bool bLedLinkBlinkInProgress;
- bool bLedStartToLinkBlinkInProgress;
- bool bLedScanBlinkInProgress;
- bool bLedWPSBlinkInProgress;
-
- u32 BlinkTimes;
- LED_STATE_819xUsb BlinkingLedState;
-
- struct timer_list BlinkTimer;
-} LED_819xUsb, *PLED_819xUsb;
-
-void InitSwLeds(struct net_device *dev);
-void DeInitSwLeds(struct net_device *dev);
-void LedControl8192SUsb(struct net_device *dev,LED_CTL_MODE LedAction);
-
-#endif
-
diff --git a/drivers/staging/rtl8192su/r8192S_Efuse.c b/drivers/staging/rtl8192su/r8192S_Efuse.c
deleted file mode 100644
index bbefd0f30348..000000000000
--- a/drivers/staging/rtl8192su/r8192S_Efuse.c
+++ /dev/null
@@ -1,2199 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "r8192U.h"
-#include "r8192S_hw.h"
-#include "r8192S_phy.h"
-#include "r8192S_phyreg.h"
-#include "r8192S_Efuse.h"
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-
-#define _POWERON_DELAY_
-#define _PRE_EXECUTE_READ_CMD_
-
-#define EFUSE_REPEAT_THRESHOLD_ 3
-#define EFUSE_ERROE_HANDLE 1
-
-typedef struct _EFUSE_MAP_A{
- u8 offset; //0~15
- u8 word_start; //0~3
- u8 byte_start; //0 or 1
- u8 byte_cnts;
-
-}EFUSE_MAP, *PEFUSE_MAP;
-
-typedef struct PG_PKT_STRUCT_A{
- u8 offset;
- u8 word_en;
- u8 data[8];
-}PGPKT_STRUCT,*PPGPKT_STRUCT;
-
-typedef enum _EFUSE_DATA_ITEM{
- EFUSE_CHIP_ID=0,
- EFUSE_LDO_SETTING,
- EFUSE_CLK_SETTING,
- EFUSE_SDIO_SETTING,
- EFUSE_CCCR,
- EFUSE_SDIO_MODE,
- EFUSE_OCR,
- EFUSE_F0CIS,
- EFUSE_F1CIS,
- EFUSE_MAC_ADDR,
- EFUSE_EEPROM_VER,
- EFUSE_CHAN_PLAN,
- EFUSE_TXPW_TAB
-} EFUSE_DATA_ITEM;
-
-struct efuse_priv
-{
- u8 id[2];
- u8 ldo_setting[2];
- u8 clk_setting[2];
- u8 cccr;
- u8 sdio_mode;
- u8 ocr[3];
- u8 cis0[17];
- u8 cis1[48];
- u8 mac_addr[6];
- u8 eeprom_verno;
- u8 channel_plan;
- u8 tx_power_b[14];
- u8 tx_power_g[14];
-};
-
-const u8 MAX_PGPKT_SIZE = 9; //header+ 2* 4 words (BYTES)
-const u8 PGPKT_DATA_SIZE = 8; //BYTES sizeof(u8)*8
-const u32 EFUSE_MAX_SIZE = 512;
-
-const u8 EFUSE_OOB_PROTECT_BYTES = 14;
-
-const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE[]={
- //offset word_s byte_start byte_cnts
-/*ID*/ {0 ,0 ,0 ,2 }, // 00~01h
-/*LDO Setting*/ {0 ,1 ,0 ,2 }, // 02~03h
-/*CLK Setting*/ {0 ,2 ,0 ,2 }, // 04~05h
-/*SDIO Setting*/ {1 ,0 ,0 ,1 }, // 08h
-/*CCCR*/ {1 ,0 ,1 ,1 }, // 09h
-/*SDIO MODE*/ {1 ,1 ,0 ,1 }, // 0Ah
-/*OCR*/ {1 ,1 ,1 ,3 }, // 0B~0Dh
-/*CCIS*/ {1 ,3 ,0 ,17 }, // 0E~1Eh 2...1
-/*F1CIS*/ {3 ,3 ,1 ,48 }, // 1F~4Eh 6...0
-/*MAC Addr*/ {10 ,0 ,0 ,6 }, // 50~55h
-/*EEPROM ver*/ {10 ,3 ,0 ,1 }, // 56h
-/*Channel plan*/ {10 ,3 ,1 ,1 }, // 57h
-/*TxPwIndex */ {11 ,0 ,0 ,28 } // 58~73h 3...4
-};
-
-//
-// From WMAC Efuse one byte R/W
-//
-extern void
-EFUSE_Initialize(struct net_device* dev);
-extern u8
-EFUSE_Read1Byte(struct net_device* dev, u16 Address);
-extern void
-EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value);
-
-//
-// Efuse Shadow Area operation
-//
-static void
-efuse_ShadowRead1Byte(struct net_device* dev,u16 Offset,u8 *Value);
-static void
-efuse_ShadowRead2Byte(struct net_device* dev, u16 Offset,u16 *Value );
-static void
-efuse_ShadowRead4Byte(struct net_device* dev, u16 Offset,u32 *Value );
-static void
-efuse_ShadowWrite1Byte(struct net_device* dev, u16 Offset, u8 Value);
-static void
-efuse_ShadowWrite2Byte(struct net_device* dev, u16 Offset,u16 Value);
-static void
-efuse_ShadowWrite4Byte(struct net_device* dev, u16 Offset,u32 Value);
-
-//
-// Real Efuse operation
-//
-static u8
-efuse_OneByteRead(struct net_device* dev,u16 addr,u8 *data);
-static u8
-efuse_OneByteWrite(struct net_device* dev,u16 addr, u8 data);
-
-//
-// HW setting map file operation
-//
-static void
-efuse_ReadAllMap(struct net_device* dev,u8 *Efuse);
-#ifdef TO_DO_LIST
-static void
-efuse_WriteAllMap(struct net_device* dev,u8 *eeprom,u32 eeprom_size);
-static bool
-efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove);
-#endif
-//
-// Reald Efuse R/W or other operation API.
-//
-static u8
-efuse_PgPacketRead( struct net_device* dev,u8 offset,u8 *data);
-static u32
-efuse_PgPacketWrite(struct net_device* dev,u8 offset,u8 word_en,u8 *data);
-static void
-efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata);
-static u8
-efuse_WordEnableDataWrite( struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data);
-static void
-efuse_PowerSwitch(struct net_device* dev,u8 PwrState);
-static u16
-efuse_GetCurrentSize(struct net_device* dev);
-static u8
-efuse_CalculateWordCnts(u8 word_en);
-//
-// API for power on power off!!!
-//
-#ifdef TO_DO_LIST
-static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
-#endif
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_Initialize
- *
- * Overview: Copy from WMAC fot EFUSE testing setting init.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 09/23/2008 MHC Copy from WMAC.
- *
- *---------------------------------------------------------------------------*/
-extern void
-EFUSE_Initialize(struct net_device* dev)
-{
- u8 Bytetemp = {0x00};
- u8 temp = {0x00};
-
- //Enable Digital Core Vdd : 0x2[13]=1
- Bytetemp = read_nic_byte(dev, SYS_FUNC_EN+1);
- temp = Bytetemp | 0x20;
- write_nic_byte(dev, SYS_FUNC_EN+1, temp);
-
- //EE loader to retention path1: attach 0x0[8]=0
- Bytetemp = read_nic_byte(dev, SYS_ISO_CTRL+1);
- temp = Bytetemp & 0xFE;
- write_nic_byte(dev, SYS_ISO_CTRL+1, temp);
-
-
- //Enable E-fuse use 2.5V LDO : 0x37[7]=1
- Bytetemp = read_nic_byte(dev, EFUSE_TEST+3);
- temp = Bytetemp | 0x80;
- write_nic_byte(dev, EFUSE_TEST+3, temp);
-
- //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
- write_nic_byte(dev, 0x2F8, 0x3);
-
- //Set E-fuse program time & read time : 0x30[30:24]=1110010b
- write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_Read1Byte
- *
- * Overview: Copy from WMAC fot EFUSE read 1 byte.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 09/23/2008 MHC Copy from WMAC.
- *
- *---------------------------------------------------------------------------*/
-extern u8
-EFUSE_Read1Byte(struct net_device* dev, u16 Address)
-{
- u8 data;
- u8 Bytetemp = {0x00};
- u8 temp = {0x00};
- u32 k=0;
-
- if (Address < EFUSE_MAC_LEN) //E-fuse 512Byte
- {
- //Write E-fuse Register address bit0~7
- temp = Address & 0xFF;
- write_nic_byte(dev, EFUSE_CTRL+1, temp);
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
- //Write E-fuse Register address bit8~9
- temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
- write_nic_byte(dev, EFUSE_CTRL+2, temp);
-
- //Write 0x30[31]=0
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- temp = Bytetemp & 0x7F;
- write_nic_byte(dev, EFUSE_CTRL+3, temp);
-
- //Wait Write-ready (0x30[31]=1)
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- while(!(Bytetemp & 0x80))
- {
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- k++;
- if(k==1000)
- {
- k=0;
- break;
- }
- }
- data=read_nic_byte(dev, EFUSE_CTRL);
- return data;
- }
- else
- return 0xFF;
-
-}
-
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_Write1Byte
- *
- * Overview: Copy from WMAC fot EFUSE write 1 byte.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 09/23/2008 MHC Copy from WMAC.
- *
- *---------------------------------------------------------------------------*/
-extern void
-EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
-{
- u8 Bytetemp = {0x00};
- u8 temp = {0x00};
- u32 k=0;
-
- if( Address < EFUSE_MAC_LEN) //E-fuse 512Byte
- {
- write_nic_byte(dev, EFUSE_CTRL, Value);
-
- //Write E-fuse Register address bit0~7
- temp = Address & 0xFF;
- write_nic_byte(dev, EFUSE_CTRL+1, temp);
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
-
- //Write E-fuse Register address bit8~9
- temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
- write_nic_byte(dev, EFUSE_CTRL+2, temp);
-
- //Write 0x30[31]=1
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- temp = Bytetemp | 0x80;
- write_nic_byte(dev, EFUSE_CTRL+3, temp);
-
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- while(Bytetemp & 0x80)
- {
- Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
- k++;
- if(k==100)
- {
- k=0;
- break;
- }
- }
- }
-
-}
-
-#ifdef EFUSE_FOR_92SU
-//
-// Description:
-// 1. Process CR93C46 Data polling cycle.
-// 2. Refered from SD1 Richard.
-//
-// Assumption:
-// 1. Boot from E-Fuse and successfully auto-load.
-// 2. PASSIVE_LEVEL (USB interface)
-//
-// Created by Roger, 2008.10.21.
-//
-void do_93c46(struct net_device* dev, u8 addorvalue)
-{
- u8 cs[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
- u8 cssk[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
- u8 csdi[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
- u8 csskdi[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
- u8 count;
-
- for(count=0 ; count<8 ; count++)
- {
- if((addorvalue&0x80)!=0)
- {
- write_nic_byte(dev, EPROM_CMD, csdi[0]);
- write_nic_byte(dev, EPROM_CMD, csskdi[0]);
- }
- else
- {
- write_nic_byte(dev, EPROM_CMD, cs[0]);
- write_nic_byte(dev, EPROM_CMD, cssk[0]);
- }
- addorvalue = addorvalue << 1;
- }
-}
-
-
-//
-// Description:
-// Process CR93C46 Data read polling cycle.
-// Refered from SD1 Richard.
-//
-// Assumption:
-// 1. Boot from E-Fuse and successfully auto-load.
-// 2. PASSIVE_LEVEL (USB interface)
-//
-// Created by Roger, 2008.10.21.
-//
-u16 Read93C46(struct net_device* dev, u16 Reg )
-{
-
- u8 clear[1] = {0x0}; // cs=0 , sk=0 , di=0 , do=0
- u8 cs[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
- u8 cssk[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
- u8 csdi[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
- u8 csskdi[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
- u8 EepromSEL[1]={0x00};
- u8 address;
-
- u16 storedataF[1] = {0x0}; //93c46 data packet for 16bits
- u8 t,data[1],storedata[1];
-
-
- address = (u8)Reg;
-
- *EepromSEL= read_nic_byte(dev, EPROM_CMD);
-
- if((*EepromSEL & 0x10) == 0x10) // select 93c46
- {
- address = address | 0x80;
-
- write_nic_byte(dev, EPROM_CMD, csdi[0]);
- write_nic_byte(dev, EPROM_CMD, csskdi[0]);
- do_93c46(dev, address);
- }
-
-
- for(t=0 ; t<16 ; t++) //if read 93c46 , t=16
- {
- write_nic_byte(dev, EPROM_CMD, cs[0]);
- write_nic_byte(dev, EPROM_CMD, cssk[0]);
- *data= read_nic_byte(dev, EPROM_CMD);
-
- if(*data & 0x8d) //original code
- {
- *data = *data & 0x01;
- *storedata = *data;
- }
- else
- {
- *data = *data & 0x01 ;
- *storedata = *data;
- }
- *storedataF = (*storedataF << 1 ) + *storedata;
- }
- write_nic_byte(dev, EPROM_CMD, cs[0]);
- write_nic_byte(dev, EPROM_CMD, clear[0]);
-
- return *storedataF;
-}
-
-
-//
-// Description:
-// Execute E-Fuse read byte operation.
-// Refered from SD1 Richard.
-//
-// Assumption:
-// 1. Boot from E-Fuse and successfully auto-load.
-// 2. PASSIVE_LEVEL (USB interface)
-//
-// Created by Roger, 2008.10.21.
-//
-void
-ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
-{
- u32 value32;
- u8 readbyte;
- u16 retry;
-
- //Write Address
- write_nic_byte(dev, EFUSE_CTRL+1, (_offset & 0xff));
- readbyte = read_nic_byte(dev, EFUSE_CTRL+2);
- write_nic_byte(dev, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
-
- //Write bit 32 0
- readbyte = read_nic_byte(dev, EFUSE_CTRL+3);
- write_nic_byte(dev, EFUSE_CTRL+3, (readbyte & 0x7f));
-
- //Check bit 32 read-ready
- retry = 0;
- value32 = read_nic_dword(dev, EFUSE_CTRL);
- while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000))
- {
- value32 = read_nic_dword(dev, EFUSE_CTRL);
- retry++;
- }
- *pbuf = (u8)(value32 & 0xff);
-}
-
-
-#define EFUSE_READ_SWITCH 1
-//
-// Description:
-// 1. Execute E-Fuse read byte operation according as map offset and
-// save to E-Fuse table.
-// 2. Refered from SD1 Richard.
-//
-// Assumption:
-// 1. Boot from E-Fuse and successfully auto-load.
-// 2. PASSIVE_LEVEL (USB interface)
-//
-// Created by Roger, 2008.10.21.
-//
-void
-ReadEFuse(struct net_device* dev, u16 _offset, u16 _size_byte, u8 *pbuf)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 efuseTbl[EFUSE_MAP_LEN];
- u8 rtemp8[1];
- u16 eFuse_Addr = 0;
- u8 offset, wren;
- u16 i, j;
- u16 eFuseWord[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
- u16 efuse_utilized = 0;
- u16 efuse_usage = 0;
-
- if((_offset + _size_byte)>EFUSE_MAP_LEN)
- {
- printk("ReadEFuse(): Invalid offset with read bytes!!\n");
- return;
- }
-
- for(i = 0; i < EFUSE_MAX_SECTION; i++)
- for(j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
- eFuseWord[i][j]=0xFFFF;
-
-#if (EFUSE_READ_SWITCH == 1)
- ReadEFuseByte(dev, eFuse_Addr, rtemp8);
-#else
- rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);
-#endif
- if(*rtemp8 != 0xFF){
- efuse_utilized++;
- RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
- eFuse_Addr++;
- }
-
- while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN))
- {
- offset = ((*rtemp8 >> 4) & 0x0f);
- if(offset < EFUSE_MAX_SECTION)
- {
- wren = (*rtemp8 & 0x0f);
- RT_TRACE(COMP_EPROM, "Offset-%d Worden=%x\n", offset, wren);
-
- for(i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
- {
- if(!(wren & 0x01))
- {
- RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
-#if (EFUSE_READ_SWITCH == 1)
- ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
-#else
- rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
-#endif
- efuse_utilized++;
- eFuseWord[offset][i] = (*rtemp8 & 0xff);
- if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
- break;
-
- RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
-#if (EFUSE_READ_SWITCH == 1)
- ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
-#else
- rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
-#endif
- efuse_utilized++;
- eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
- if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
- break;
- }
- wren >>= 1;
- }
- }
-
- RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
-#if (EFUSE_READ_SWITCH == 1)
- ReadEFuseByte(dev, eFuse_Addr, rtemp8);
-#else
- rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
-#endif
- if(*rtemp8 != 0xFF && (eFuse_Addr < 512))
- {
- efuse_utilized++;
- eFuse_Addr++;
- }
- }
-
- for(i=0; i<EFUSE_MAX_SECTION; i++)
- {
- for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
- {
- efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
- efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
- }
- }
- for(i=0; i<_size_byte; i++)
- pbuf[i] = efuseTbl[_offset+i];
-
- efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN);
- priv->EfuseUsedBytes = efuse_utilized;
- priv->EfuseUsedPercentage = (u8)efuse_usage;
-}
-#endif
-
-extern bool
-EFUSE_ShadowUpdateChk(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 SectionIdx, i, Base;
- u16 WordsNeed = 0, HdrNum = 0, TotalBytes = 0, EfuseUsed = 0;
- bool bWordChanged, bResult = true;
-
- for (SectionIdx = 0; SectionIdx < 16; SectionIdx++)
- {
- Base = SectionIdx * 8;
- bWordChanged = false;
-
- for (i = 0; i < 8; i=i+2)
- {
- if((priv->EfuseMap[EFUSE_INIT_MAP][Base+i] !=
- priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i]) ||
- (priv->EfuseMap[EFUSE_INIT_MAP][Base+i+1] !=
- priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i+1]))
- {
- WordsNeed++;
- bWordChanged = true;
- }
- }
-
- if( bWordChanged==true )
- HdrNum++;
- }
-
- TotalBytes = HdrNum + WordsNeed*2;
- EfuseUsed = priv->EfuseUsedBytes;
-
- if( (TotalBytes + EfuseUsed) >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
- bResult = true;
-
- RT_TRACE(COMP_EPROM, "EFUSE_ShadowUpdateChk(): TotalBytes(%x), HdrNum(%x), WordsNeed(%x), EfuseUsed(%d)\n",
- TotalBytes, HdrNum, WordsNeed, EfuseUsed);
-
- return bResult;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowRead
- *
- * Overview: Read from efuse init map !!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void
-EFUSE_ShadowRead( struct net_device* dev, u8 Type, u16 Offset, u32 *Value)
-{
- if (Type == 1)
- efuse_ShadowRead1Byte(dev, Offset, (u8 *)Value);
- else if (Type == 2)
- efuse_ShadowRead2Byte(dev, Offset, (u16 *)Value);
- else if (Type == 4)
- efuse_ShadowRead4Byte(dev, Offset, (u32 *)Value);
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowWrite
- *
- * Overview: Write efuse modify map for later update operation to use!!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void
-EFUSE_ShadowWrite( struct net_device* dev, u8 Type, u16 Offset,u32 Value)
-{
- if (Offset >= 0x18 && Offset <= 0x1F)
- return;
-
- if (Type == 1)
- efuse_ShadowWrite1Byte(dev, Offset, (u8)Value);
- else if (Type == 2)
- efuse_ShadowWrite2Byte(dev, Offset, (u16)Value);
- else if (Type == 4)
- efuse_ShadowWrite4Byte(dev, Offset, (u32)Value);
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowUpdate
- *
- * Overview: Compare init and modify map to update Efuse!!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern bool
-EFUSE_ShadowUpdate(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 i, offset, base = 0;
- u8 word_en = 0x0F;
- bool first_pg = false;
-
- RT_TRACE(COMP_EPROM, "--->EFUSE_ShadowUpdate()\n");
-
- if(!EFUSE_ShadowUpdateChk(dev))
- {
- efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
- memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
- (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
-
- RT_TRACE(COMP_EPROM, "<---EFUSE_ShadowUpdate(): Efuse out of capacity!!\n");
- return false;
- }
- efuse_PowerSwitch(dev, TRUE);
-
- //
- // Efuse support 16 write are with PG header packet!!!!
- //
- for (offset = 0; offset < 16; offset++)
- {
- // Offset 0x18-1F are reserved now!!!
- word_en = 0x0F;
- base = offset * 8;
-
- //
- // Decide Word Enable Bit for the Efuse section
- // One section contain 4 words = 8 bytes!!!!!
- //
- for (i = 0; i < 8; i++)
- {
- if (first_pg == TRUE)
- {
- word_en &= ~(1<<(i/2));
- RT_TRACE(COMP_EPROM,"Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
- offset, base+i, priv->EfuseMap[EFUSE_INIT_MAP][base+i],
- priv->EfuseMap[EFUSE_MODIFY_MAP][base+i],word_en);
- priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
- priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
- }else
- {
- if ( priv->EfuseMap[EFUSE_INIT_MAP][base+i] !=
- priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
- {
- word_en &= ~(EFUSE_BIT(i/2));
- RT_TRACE(COMP_EPROM, "Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
- offset, base+i, priv->EfuseMap[0][base+i],
- priv->EfuseMap[1][base+i],word_en);
-
- // Update init table!!!
- priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
- priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
- }
- }
- }
-
- //
- // Call Efuse real write section !!!!
- //
- if (word_en != 0x0F)
- {
- u8 tmpdata[8];
-
- memcpy((void *)tmpdata, (void *)&(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
- RT_TRACE(COMP_INIT, "U-EFUSE\n");
-
- if(!efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata))
- {
- RT_TRACE(COMP_EPROM,"EFUSE_ShadowUpdate(): PG section(%x) fail!!\n", offset);
- break;
- }
- }
-
- }
- // For warm reboot, we must resume Efuse clock to 500K.
-
- efuse_PowerSwitch(dev, FALSE);
-
- efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
- memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
- (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
-
- return true;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowMapUpdate
- *
- * Overview: Transfer current EFUSE content to shadow init and modify map.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/13/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if (priv->AutoloadFailFlag == true){
- memset(&(priv->EfuseMap[EFUSE_INIT_MAP][0]), 0xff, 128);
- }else{
- efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
- }
- memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
- (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
-
-}
-
-extern void
-EFUSE_ForceWriteVendorId( struct net_device* dev)
-{
- u8 tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
-
- efuse_PowerSwitch(dev, TRUE);
-
- efuse_PgPacketWrite(dev, 1, 0xD, tmpdata);
-
- efuse_PowerSwitch(dev, FALSE);
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_ShadowRead1Byte
- * efuse_ShadowRead2Byte
- * efuse_ShadowRead4Byte
- *
- * Overview: Read from efuse init map by one/two/four bytes !!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_ShadowRead1Byte(struct net_device* dev, u16 Offset, u8 *Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
-
-}
-
-//---------------Read Two Bytes
-static void
-efuse_ShadowRead2Byte(struct net_device* dev, u16 Offset, u16 *Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
- *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
-
-}
-
-//---------------Read Four Bytes
-static void
-efuse_ShadowRead4Byte(struct net_device* dev, u16 Offset, u32 *Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
- *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
- *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2]<<16;
- *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3]<<24;
-
-}
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_ShadowWrite1Byte
- * efuse_ShadowWrite2Byte
- * efuse_ShadowWrite4Byte
- *
- * Overview: Write efuse modify map by one/two/four byte.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_ShadowWrite1Byte(struct net_device* dev, u16 Offset, u8 Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
-
-}
-
-//---------------Write Two Bytes
-static void
-efuse_ShadowWrite2Byte(struct net_device* dev, u16 Offset, u16 Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
-
-}
-
-//---------------Write Four Bytes
-static void
-efuse_ShadowWrite4Byte(struct net_device* dev, u16 Offset, u32 Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = (u8)(Value&0x000000FF);
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = (u8)((Value>>8)&0x0000FF);
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2] = (u8)((Value>>16)&0x00FF);
- priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3] = (u8)((Value>>24)&0xFF);
-
-}
-
-static u8
-efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
-{
- u8 tmpidx = 0;
- u8 bResult;
-
- // -----------------e-fuse reg ctrl ---------------------------------
- //address
- write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
- write_nic_byte(dev, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
- (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC ));
-
- write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
-
- while(!(0x80 &read_nic_byte(dev, EFUSE_CTRL+3))&&(tmpidx<100))
- {
- tmpidx++;
- }
- if(tmpidx<100)
- {
- *data=read_nic_byte(dev, EFUSE_CTRL);
- bResult = TRUE;
- }
- else
- {
- *data = 0xff;
- bResult = FALSE;
- }
- return bResult;
-}
-
-/* 11/16/2008 MH Write one byte to reald Efuse. */
-static u8
-efuse_OneByteWrite(struct net_device* dev, u16 addr, u8 data)
-{
- u8 tmpidx = 0;
- u8 bResult;
-
- // -----------------e-fuse reg ctrl ---------------------------------
- //address
- write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
- write_nic_byte(dev, EFUSE_CTRL+2,
- read_nic_byte(dev, EFUSE_CTRL+2)|(u8)((addr>>8)&0x03) );
-
- write_nic_byte(dev, EFUSE_CTRL, data);//data
- write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
-
- while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
- tmpidx++;
- }
-
- if(tmpidx<100)
- {
- bResult = TRUE;
- }
- else
- {
- bResult = FALSE;
- }
-
- return bResult;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_ReadAllMap
- *
- * Overview: Read All Efuse content
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/11/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_ReadAllMap(struct net_device* dev, u8 *Efuse)
-{
- //
- // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
- //
- efuse_PowerSwitch(dev, TRUE);
- ReadEFuse(dev, 0, 128, Efuse);
- efuse_PowerSwitch(dev, FALSE);
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_WriteAllMap
- *
- * Overview: Write All Efuse content
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/11/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-#ifdef TO_DO_LIST
-static void
-efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
-{
- unsigned char word_en = 0x00;
-
- unsigned char tmpdata[8];
- unsigned char offset;
-
- // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
- efuse_PowerSwitch(dev, TRUE);
-
- //sdio contents
- for(offset=0 ; offset< eeprom_size/PGPKT_DATA_SIZE ; offset++)
- {
- // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
- if (IS_HARDWARE_TYPE_8192SE(dev))
- {
- // Refer to
- // 0x18-1f Reserve >0x50 Reserve for tx power
- if (offset == 3/* || offset > 9*/)
- continue;//word_en = 0x0F;
- else
- word_en = 0x00;
- }
-
- memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
- efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
-
-
- }
-
- // For warm reboot, we must resume Efuse clock to 500K.
- efuse_PowerSwitch(dev, FALSE);
-
-}
-#endif
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_PgPacketRead
- *
- * Overview: Receive dedicated Efuse are content. For92s, we support 16
- * area now. It will return 8 bytes content for every area.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Reorganize code Arch and assign as local API.
- *
- *---------------------------------------------------------------------------*/
-static u8
-efuse_PgPacketRead( struct net_device* dev, u8 offset, u8 *data)
-{
- u8 ReadState = PG_STATE_HEADER;
-
- bool bContinual = TRUE;
- bool bDataEmpty = TRUE ;
-
- u8 efuse_data,word_cnts=0;
- u16 efuse_addr = 0;
- u8 hoffset=0,hworden=0;
- u8 tmpidx=0;
- u8 tmpdata[8];
-
- if(data==NULL) return FALSE;
- if(offset>15) return FALSE;
-
- memset(data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
- memset(tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
-
- while(bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
- {
- //------- Header Read -------------
- if(ReadState & PG_STATE_HEADER)
- {
- if(efuse_OneByteRead(dev, efuse_addr ,&efuse_data)&&(efuse_data!=0xFF)){
- hoffset = (efuse_data>>4) & 0x0F;
- hworden = efuse_data & 0x0F;
- word_cnts = efuse_CalculateWordCnts(hworden);
- bDataEmpty = TRUE ;
-
- if(hoffset==offset){
- for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++){
- if(efuse_OneByteRead(dev, efuse_addr+1+tmpidx ,&efuse_data) ){
- tmpdata[tmpidx] = efuse_data;
- if(efuse_data!=0xff){
- bDataEmpty = FALSE;
- }
- }
- }
- if(bDataEmpty==FALSE){
- ReadState = PG_STATE_DATA;
- }else{//read next header
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- ReadState = PG_STATE_HEADER;
- }
- }
- else{//read next header
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- ReadState = PG_STATE_HEADER;
- }
-
- }
- else{
- bContinual = FALSE ;
- }
- }
- //------- Data section Read -------------
- else if(ReadState & PG_STATE_DATA)
- {
- efuse_WordEnableDataRead(hworden,tmpdata,data);
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- ReadState = PG_STATE_HEADER;
- }
-
- }
-
- if( (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff) && (data[3]==0xff) &&
- (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff) && (data[7]==0xff))
- return FALSE;
- else
- return TRUE;
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_PgPacketWrite
- *
- * Overview: Send A G package for different section in real efuse area.
- * For 92S, One PG package contain 8 bytes content and 4 word
- * unit. PG header = 0x[bit7-4=offset][bit3-0word enable]
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Reorganize code Arch and assign as local API.
- *
- *---------------------------------------------------------------------------*/
-static u32 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
-{
- u8 WriteState = PG_STATE_HEADER;
-
- bool bContinual = TRUE,bDataEmpty=TRUE, bResult = TRUE;
- u16 efuse_addr = 0;
- u8 efuse_data;
-
- u8 pg_header = 0;
-
- u8 tmp_word_cnts=0,target_word_cnts=0;
- u8 tmp_header,match_word_en,tmp_word_en;
-
- PGPKT_STRUCT target_pkt;
- PGPKT_STRUCT tmp_pkt;
-
- u8 originaldata[sizeof(u8)*8];
- u8 tmpindex = 0,badworden = 0x0F;
-
- static u32 repeat_times = 0;
-
- if( efuse_GetCurrentSize(dev) >= EFUSE_MAX_SIZE)
- {
- printk("efuse_PgPacketWrite error \n");
- return FALSE;
- }
-
- // Init the 8 bytes content as 0xff
- target_pkt.offset = offset;
- target_pkt.word_en= word_en;
-
- //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
- memset(target_pkt.data,0xFF,sizeof(u8)*8);
-
- efuse_WordEnableDataRead(word_en,data,target_pkt.data);
- target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
-
- printk("EFUSE Power ON\n");
-
- while( bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
- {
-
- if(WriteState==PG_STATE_HEADER)
- {
- bDataEmpty=TRUE;
- badworden = 0x0F;
- //************ so *******************
- printk("EFUSE PG_STATE_HEADER\n");
- if ( efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
- (efuse_data!=0xFF))
- {
- tmp_header = efuse_data;
-
- tmp_pkt.offset = (tmp_header>>4) & 0x0F;
- tmp_pkt.word_en = tmp_header & 0x0F;
- tmp_word_cnts = efuse_CalculateWordCnts(tmp_pkt.word_en);
-
- //************ so-1 *******************
- if(tmp_pkt.offset != target_pkt.offset)
- {
- efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState = PG_STATE_HEADER;
- #endif
- }
- else
- {
- //************ so-2 *******************
- for(tmpindex=0 ; tmpindex<(tmp_word_cnts*2) ; tmpindex++)
- {
- if(efuse_OneByteRead(dev, (efuse_addr+1+tmpindex) ,&efuse_data)&&(efuse_data != 0xFF)){
- bDataEmpty = FALSE;
- }
- }
- //************ so-2-1 *******************
- if(bDataEmpty == FALSE)
- {
- efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState=PG_STATE_HEADER;
- #endif
- }
- else
- {//************ so-2-2 *******************
- match_word_en = 0x0F;
- if( !( (target_pkt.word_en&BIT0)|(tmp_pkt.word_en&BIT0) ))
- {
- match_word_en &= (~BIT0);
- }
- if( !( (target_pkt.word_en&BIT1)|(tmp_pkt.word_en&BIT1) ))
- {
- match_word_en &= (~BIT1);
- }
- if( !( (target_pkt.word_en&BIT2)|(tmp_pkt.word_en&BIT2) ))
- {
- match_word_en &= (~BIT2);
- }
- if( !( (target_pkt.word_en&BIT3)|(tmp_pkt.word_en&BIT3) ))
- {
- match_word_en &= (~BIT3);
- }
-
- //************ so-2-2-A *******************
- if((match_word_en&0x0F)!=0x0F)
- {
- badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1, tmp_pkt.word_en ,target_pkt.data);
-
- //************ so-2-2-A-1 *******************
- if(0x0F != (badworden&0x0F))
- {
- u8 reorg_offset = offset;
- u8 reorg_worden=badworden;
- efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
- }
-
- tmp_word_en = 0x0F;
- if( (target_pkt.word_en&BIT0)^(match_word_en&BIT0) )
- {
- tmp_word_en &= (~BIT0);
- }
- if( (target_pkt.word_en&BIT1)^(match_word_en&BIT1) )
- {
- tmp_word_en &= (~BIT1);
- }
- if( (target_pkt.word_en&BIT2)^(match_word_en&BIT2) )
- {
- tmp_word_en &= (~BIT2);
- }
- if( (target_pkt.word_en&BIT3)^(match_word_en&BIT3) )
- {
- tmp_word_en &=(~BIT3);
- }
-
- //************ so-2-2-A-2 *******************
- if((tmp_word_en&0x0F)!=0x0F){
- //reorganize other pg packet
-
- efuse_addr = efuse_GetCurrentSize(dev);
-
- target_pkt.offset = offset;
- target_pkt.word_en= tmp_word_en;
-
- }else{
- bContinual = FALSE;
- }
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState=PG_STATE_HEADER;
- repeat_times++;
- if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
- bContinual = FALSE;
- bResult = FALSE;
- }
- #endif
- }
- else{//************ so-2-2-B *******************
- //reorganize other pg packet
- efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
- target_pkt.offset = offset;
- target_pkt.word_en= target_pkt.word_en;
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState=PG_STATE_HEADER;
- #endif
- }
- }
- }
- printk("EFUSE PG_STATE_HEADER-1\n");
- }
- else //************ s1: header == oxff *******************
- {
- pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en;
-
- efuse_OneByteWrite(dev,efuse_addr, pg_header);
- efuse_OneByteRead(dev,efuse_addr, &tmp_header);
-
- if(tmp_header == pg_header)
- { //************ s1-1*******************
- WriteState = PG_STATE_DATA;
- }
- #if (EFUSE_ERROE_HANDLE == 1)
- else if(tmp_header == 0xFF){//************ s1-3: if Write or read func doesn't work *******************
- //efuse_addr doesn't change
- WriteState = PG_STATE_HEADER;
- repeat_times++;
- if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
- bContinual = FALSE;
- bResult = FALSE;
- }
- }
- #endif
- else
- {//************ s1-2 : fixed the header procedure *******************
- tmp_pkt.offset = (tmp_header>>4) & 0x0F;
- tmp_pkt.word_en= tmp_header & 0x0F;
- tmp_word_cnts = efuse_CalculateWordCnts(tmp_pkt.word_en);
-
- //************ s1-2-A :cover the exist data *******************
- memset(originaldata,0xff,sizeof(u8)*8);
-
- if(efuse_PgPacketRead( dev, tmp_pkt.offset,originaldata))
- { //check if data exist
- badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,tmp_pkt.word_en,originaldata);
- if(0x0F != (badworden&0x0F))
- {
- u8 reorg_offset = tmp_pkt.offset;
- u8 reorg_worden=badworden;
- efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
- efuse_addr = efuse_GetCurrentSize(dev);
- }
- else{
- efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
- }
- }
- //************ s1-2-B: wrong address*******************
- else
- {
- efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
- }
-
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState=PG_STATE_HEADER;
- repeat_times++;
- if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
- bContinual = FALSE;
- bResult = FALSE;
- }
- #endif
-
- printk("EFUSE PG_STATE_HEADER-2\n");
- }
-
- }
-
- }
- //write data state
- else if(WriteState==PG_STATE_DATA)
- { //************ s1-1 *******************
- printk("EFUSE PG_STATE_DATA\n");
- badworden = 0x0f;
- badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,target_pkt.word_en,target_pkt.data);
- if((badworden&0x0F)==0x0F)
- { //************ s1-1-A *******************
- bContinual = FALSE;
- }
- else
- {//reorganize other pg packet //************ s1-1-B *******************
- efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
-
- target_pkt.offset = offset;
- target_pkt.word_en= badworden;
- target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
- #if (EFUSE_ERROE_HANDLE == 1)
- WriteState=PG_STATE_HEADER;
- repeat_times++;
- if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
- bContinual = FALSE;
- bResult = FALSE;
- }
- #endif
- printk("EFUSE PG_STATE_HEADER-3\n");
- }
- }
- }
-
- if(efuse_addr >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
- {
- RT_TRACE(COMP_EPROM, "efuse_PgPacketWrite(): efuse_addr(%x) Out of size!!\n", efuse_addr);
- }
- return TRUE;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_WordEnableDataRead
- *
- * Overview: Read allowed word in current efuse section data.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Create Version 0.
- * 11/21/2008 MHC Fix Write bug when we only enable late word.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata)
-{
-
- if (!(word_en&BIT0))
- {
- targetdata[0] = sourdata[0];//sourdata[tmpindex++];
- targetdata[1] = sourdata[1];//sourdata[tmpindex++];
- }
- if (!(word_en&BIT1))
- {
- targetdata[2] = sourdata[2];//sourdata[tmpindex++];
- targetdata[3] = sourdata[3];//sourdata[tmpindex++];
- }
- if (!(word_en&BIT2))
- {
- targetdata[4] = sourdata[4];//sourdata[tmpindex++];
- targetdata[5] = sourdata[5];//sourdata[tmpindex++];
- }
- if (!(word_en&BIT3))
- {
- targetdata[6] = sourdata[6];//sourdata[tmpindex++];
- targetdata[7] = sourdata[7];//sourdata[tmpindex++];
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_WordEnableDataWrite
- *
- * Overview: Write necessary word unit into current efuse section!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Reorganize Efuse operate flow!!.
- *
- *---------------------------------------------------------------------------*/
-static u8
-efuse_WordEnableDataWrite( struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data)
-{
- u16 tmpaddr = 0;
- u16 start_addr = efuse_addr;
- u8 badworden = 0x0F;
- u8 tmpdata[8];
-
- memset(tmpdata,0xff,PGPKT_DATA_SIZE);
-
- if(!(word_en&BIT0))
- {
- tmpaddr = start_addr;
- efuse_OneByteWrite(dev,start_addr++, data[0]);
- efuse_OneByteWrite(dev,start_addr++, data[1]);
-
- efuse_OneByteRead(dev,tmpaddr, &tmpdata[0]);
- efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[1]);
- if((data[0]!=tmpdata[0])||(data[1]!=tmpdata[1])){
- badworden &= (~BIT0);
- }
- }
- if(!(word_en&BIT1))
- {
- tmpaddr = start_addr;
- efuse_OneByteWrite(dev,start_addr++, data[2]);
- efuse_OneByteWrite(dev,start_addr++, data[3]);
-
- efuse_OneByteRead(dev,tmpaddr , &tmpdata[2]);
- efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[3]);
- if((data[2]!=tmpdata[2])||(data[3]!=tmpdata[3])){
- badworden &=( ~BIT1);
- }
- }
- if(!(word_en&BIT2))
- {
- tmpaddr = start_addr;
- efuse_OneByteWrite(dev,start_addr++, data[4]);
- efuse_OneByteWrite(dev,start_addr++, data[5]);
-
- efuse_OneByteRead(dev,tmpaddr, &tmpdata[4]);
- efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[5]);
- if((data[4]!=tmpdata[4])||(data[5]!=tmpdata[5])){
- badworden &=( ~BIT2);
- }
- }
- if(!(word_en&BIT3))
- {
- tmpaddr = start_addr;
- efuse_OneByteWrite(dev,start_addr++, data[6]);
- efuse_OneByteWrite(dev,start_addr++, data[7]);
-
- efuse_OneByteRead(dev,tmpaddr, &tmpdata[6]);
- efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[7]);
- if((data[6]!=tmpdata[6])||(data[7]!=tmpdata[7])){
- badworden &=( ~BIT3);
- }
- }
- return badworden;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_PowerSwitch
- *
- * Overview: When we want to enable write operation, we should change to
- * pwr on state. When we stop write, we should switch to 500k mode
- * and disable LDO 2.5V.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/17/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
-{
- u8 tempval;
- if (PwrState == TRUE)
- {
- // Enable LDO 2.5V for write action
- tempval = read_nic_byte(dev, EFUSE_TEST+3);
- write_nic_byte(dev, EFUSE_TEST+3, (tempval | 0x80));
-
- // Change Efuse Clock for write action to 40MHZ
- write_nic_byte(dev, EFUSE_CLK, 0x03);
- }
- else
- {
- // Enable LDO 2.5V for write action
- tempval = read_nic_byte(dev, EFUSE_TEST+3);
- write_nic_byte(dev, EFUSE_TEST+3, (tempval & 0x7F));
-
- // Change Efuse Clock for write action to 500K
- write_nic_byte(dev, EFUSE_CLK, 0x02);
- }
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_GetCurrentSize
- *
- * Overview: Get current efuse size!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static u16
-efuse_GetCurrentSize(struct net_device* dev)
-{
- bool bContinual = TRUE;
-
- u16 efuse_addr = 0;
- u8 hoffset=0,hworden=0;
- u8 efuse_data,word_cnts=0;
-
- while ( bContinual &&
- efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
- (efuse_addr < EFUSE_MAX_SIZE) )
- {
- if(efuse_data!=0xFF)
- {
- hoffset = (efuse_data>>4) & 0x0F;
- hworden = efuse_data & 0x0F;
- word_cnts = efuse_CalculateWordCnts(hworden);
- //read next header
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- }
- else
- {
- bContinual = FALSE ;
- }
- }
-
- return efuse_addr;
-
-}
-
-/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
-static u8
-efuse_CalculateWordCnts(u8 word_en)
-{
- u8 word_cnts = 0;
- if(!(word_en & BIT0)) word_cnts++; // 0 : write enable
- if(!(word_en & BIT1)) word_cnts++;
- if(!(word_en & BIT2)) word_cnts++;
- if(!(word_en & BIT3)) word_cnts++;
- return word_cnts;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ProgramMap
- *
- * Overview: Read EFUSE map file and execute PG.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/10/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
- #ifdef TO_DO_LIST
-extern bool // 0=Shadow 1=Real Efuse
-EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8 TableType)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- s4Byte nLinesRead, ithLine;
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
- char* szLine;
- u32 u4bRegValue, u4RegMask;
- u32 u4bMove;
- u16 index = 0;
- u16 i;
- u8 eeprom[HWSET_MAX_SIZE_92S];
-
- rtStatus = PlatformReadFile(
- dev,
- pFileName,
- (u8*)(priv->BufOfLines),
- MAX_LINES_HWCONFIG_TXT,
- MAX_BYTES_LINE_HWCONFIG_TXT,
- &nLinesRead
- );
-
- if(rtStatus == RT_STATUS_SUCCESS)
- {
- memcp(pHalData->BufOfLines3, pHalData->BufOfLines,
- nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT);
- pHalData->nLinesRead3 = nLinesRead;
- }
-
- if(rtStatus == RT_STATUS_SUCCESS)
- {
- printk("szEepromFile(): read %s ok\n", pFileName);
- for(ithLine = 0; ithLine < nLinesRead; ithLine++)
- {
- szLine = pHalData->BufOfLines[ithLine];
- printk("Line-%d String =%s\n", ithLine, szLine);
-
- if(!IsCommentString(szLine))
- {
- // EEPROM map one line has 8 words content.
- for (i = 0; i < 8; i++)
- {
- u32 j;
-
- efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
-
- // Get next hex value as EEPROM value.
- szLine += u4bMove;
- eeprom[index++] = (u8)(u4bRegValue&0xff);
- eeprom[index++] = (u8)((u4bRegValue>>8)&0xff);
-
- printk("Addr-%d = %x\n", (ithLine*8+i), u4bRegValue);
- }
- }
-
- }
-
- }
- else
- {
- printk("szEepromFile(): Fail read%s\n", pFileName);
- return RT_STATUS_FAILURE;
- }
-
- // Use map file to update real Efuse or shadow modify table.
- if (TableType == 1)
- {
- efuse_WriteAllMap(dev, eeprom, HWSET_MAX_SIZE_92S);
- }
- else
- {
- // Modify shadow table.
- for (i = 0; i < HWSET_MAX_SIZE_92S; i++)
- EFUSE_ShadowWrite(dev, 1, i, (u32)eeprom[i]);
- }
-
- return rtStatus;
-}
-
-#endif
-
-/*-----------------------------------------------------------------------------
- * Function: efuse_ParsingMap
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/08/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-#ifdef TO_DO_LIST
-static bool
-efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
-{
- char* szScan = szStr;
-
- // Check input parameter.
- if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
- {
- return FALSE;
- }
-
- // Initialize output.
- *pu4bMove = 0;
- *pu4bVal = 0;
-
- // Skip leading space.
- while( *szScan != '\0' &&
- (*szScan == ' ' || *szScan == '\t') )
- {
- szScan++;
- (*pu4bMove)++;
- }
-
- // Check if szScan is now pointer to a character for hex digit,
- // if not, it means this is not a valid hex number.
- if (!isxdigit(*szScan))
- return FALSE;
-
- // Parse each digit.
- do
- {
- *pu4bVal = (*pu4bVal << 4) + hex_to_bin(*szScan);
-
- szScan++;
- (*pu4bMove)++;
- } while (isxdigit(*szScan));
-
- return TRUE;
-
-}
-#endif
-
-int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
-{
- u32 bResult;
- u8 tmpidx = 0;
- u8 tmpv8=0;
-
- // -----------------e-fuse reg ctrl ---------------------------------
-
- write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff)); //address
- tmpv8 = ((u8)((addr>>8) &0x03) ) | (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC );
- write_nic_byte(dev, EFUSE_CTRL+2, tmpv8);
-
- if(TRUE==bRead){
-
- write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
-
- while(!(0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
- tmpidx++;
- }
- if(tmpidx<100){
- *data=read_nic_byte(dev, EFUSE_CTRL);
- bResult = TRUE;
- }
- else
- {
- *data = 0;
- bResult = FALSE;
- }
-
- }
- else{
- write_nic_byte(dev, EFUSE_CTRL, *data);//data
-
- write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
-
- while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
- tmpidx++;
- }
- if(tmpidx<100)
- {
- *data=read_nic_byte(dev, EFUSE_CTRL);
- bResult = TRUE;
- }
- else
- {
- *data = 0;
- bResult = FALSE;
- }
-
- }
- return bResult;
-}
-
-void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
-{
- u8 efuse_clk_ori,efuse_clk_new;//,tmp8;
- u32 i = 0;
-
- if(start_addr>0x200) return;
- // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
- efuse_clk_ori = read_nic_byte(dev,SYS_FUNC_EN+1);
- efuse_clk_new = efuse_clk_ori|0x20;
-
- if(efuse_clk_new!= efuse_clk_ori){
- write_nic_byte(dev, SYS_FUNC_EN+1, efuse_clk_new);
- }
-#ifdef _POWERON_DELAY_
- mdelay(10);
-#endif
- // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
- write_nic_byte(dev, EFUSE_TEST+3, (read_nic_byte(dev, EFUSE_TEST+3)|0x80));
- write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
-
-#ifdef _PRE_EXECUTE_READ_CMD_
- {
- unsigned char tmpdata;
- efuse_OneByteRead(dev, 0,&tmpdata);
- }
-#endif
-
- //-----------------e-fuse one byte read / write ------------------------------
- for(i=0;i<cnts;i++){
- efuse_one_byte_rw(dev,bRead, start_addr+i , data+i);
-
- }
- write_nic_byte(dev, EFUSE_TEST+3, read_nic_byte(dev, EFUSE_TEST+3)&0x7f);
- write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
-
- // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
- if(efuse_clk_new != efuse_clk_ori) write_nic_byte(dev, 0x10250003, efuse_clk_ori);
-
-}
-
-#ifdef TO_DO_LIST
-static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
-{
- if(TRUE==bPowerOn){
- // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
- write_nic_byte(dev, SYS_FUNC_EN+1, read_nic_byte(dev,SYS_FUNC_EN+1)|0x20);
-#ifdef _POWERON_DELAY_
- mdelay(10);
-#endif
- // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
- write_nic_byte(dev, EFUSE_TEST+4, (read_nic_byte(dev, EFUSE_TEST+4)|0x80));
- write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
-#ifdef _PRE_EXECUTE_READ_CMD_
- {
- unsigned char tmpdata;
- efuse_OneByteRead(dev, 0,&tmpdata);
- }
-
-#endif
- }
- else{
- // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
- write_nic_byte(dev, EFUSE_TEST+4, read_nic_byte(dev, EFUSE_TEST+4)&0x7f);
- write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
- // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
-
- }
-
-
-}
-#endif
-
-void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
-{
- u8 offset, word_start,byte_start,byte_cnts;
- u8 efusedata[EFUSE_MAC_LEN];
- u8 *tmpdata = NULL;
-
- u8 pg_pkt_cnts ;
-
- u8 tmpidx;
- u8 pg_data[8];
-
- if(efuse_read_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
- return ;
- }
-
- offset = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].offset ;
- word_start = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].word_start;
- byte_start = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_start;
- byte_cnts = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_cnts;
-
- if(data_size!=byte_cnts){
- return;
- }
-
- pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
-
- if(pg_pkt_cnts > 1){
- tmpdata = efusedata;
-
- if(tmpdata!=NULL)
- {
- memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
-
- for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
- {
- memset(pg_data,0xff,PGPKT_DATA_SIZE);
- if(TRUE== efuse_PgPacketRead(dev,offset+tmpidx,pg_data))
- {
- memcpy(tmpdata+(PGPKT_DATA_SIZE*tmpidx),pg_data,PGPKT_DATA_SIZE);
- }
- }
- memcpy(data,(tmpdata+ (2*word_start)+byte_start ),data_size);
- }
- }
- else
- {
- memset(pg_data,0xff,PGPKT_DATA_SIZE);
- if(TRUE==efuse_PgPacketRead(dev,offset,pg_data)){
- memcpy(data,pg_data+ (2*word_start)+byte_start ,data_size);
- }
- }
-
-}
-
-//per interface doesn't alike
-void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 data_size,u32 bWordUnit)
-{
- u8 offset, word_start,byte_start,byte_cnts;
- u8 word_en = 0x0f,word_cnts;
- u8 pg_pkt_cnts ;
-
- u8 tmpidx,tmpbitmask;
- u8 pg_data[8],tmpbytes=0;
-
- if(efuse_write_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
- return ;
- }
-
- offset = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].offset ;
- word_start = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].word_start;
- byte_start = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_start;
- byte_cnts = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_cnts;
-
- if(data_size > byte_cnts){
- return;
- }
- pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
- word_cnts = byte_cnts /2 ;
-
- if(byte_cnts %2){
- word_cnts+=1;
- }
- if((byte_start==1)||((byte_cnts%2)==1)){//situation A
-
- if((efuse_write_item==EFUSE_F0CIS)||(efuse_write_item==EFUSE_F1CIS)){
- memset(pg_data,0xff,PGPKT_DATA_SIZE);
- efuse_PgPacketRead(dev,offset,pg_data);
-
- if(efuse_write_item==EFUSE_F0CIS){
- word_en = 0x07;
- memcpy(pg_data+word_start*2+byte_start,data,sizeof(u8)*2);
- efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
-
- word_en = 0x00;
- efuse_PgPacketWrite(dev,(offset+1),word_en,data+2);
-
- word_en = 0x00;
- efuse_PgPacketRead(dev,offset+2,pg_data);
- memcpy(pg_data,data+2+8,sizeof(u8)*7);
-
- efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
- }
- else if(efuse_write_item==EFUSE_F1CIS){
- word_en = 0x07;
- efuse_PgPacketRead(dev,offset,pg_data);
- pg_data[7] = data[0];
- efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
-
- word_en = 0x00;
- for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++){
- efuse_PgPacketWrite(dev,(offset+1+tmpidx),word_en,data+1+(tmpidx*PGPKT_DATA_SIZE));
- }
- }
-
- }
- else{
- memset(pg_data,0xff,PGPKT_DATA_SIZE);
- if((efuse_write_item==EFUSE_SDIO_SETTING)||(efuse_write_item==EFUSE_CCCR)){
- word_en = 0x0e ;
- tmpbytes = 2;
- }
- else if(efuse_write_item == EFUSE_SDIO_MODE){
- word_en = 0x0d ;
- tmpbytes = 2;
- }
- else if(efuse_write_item == EFUSE_OCR){
- word_en = 0x09 ;
- tmpbytes = 4;
- }
- else if((efuse_write_item == EFUSE_EEPROM_VER)||(efuse_write_item==EFUSE_CHAN_PLAN)){
- word_en = 0x07 ;
- tmpbytes = 2;
- }
- if(bWordUnit==TRUE){
- memcpy(pg_data+word_start*2 ,data,sizeof(u8)*tmpbytes);
- }
- else{
- efuse_PgPacketRead(dev,offset,pg_data);
- memcpy(pg_data+(2*word_start)+byte_start,data,sizeof(u8)*byte_cnts);
- }
-
- efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
-
- }
-
- }
- else if(pg_pkt_cnts>1){//situation B
- if(word_start==0){
- word_en = 0x00;
- for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++)
- {
- efuse_PgPacketWrite(dev,(offset+tmpidx),word_en,data+(tmpidx*PGPKT_DATA_SIZE));
- }
- word_en = 0x0f;
- for(tmpidx= 0; tmpidx<(word_cnts%4) ; tmpidx++)
- {
- tmpbitmask =tmpidx;
- word_en &= (~(EFUSE_BIT(tmpbitmask)));
- //BIT0
- }
- efuse_PgPacketWrite(dev,offset+(word_cnts/4),word_en,data+((word_cnts/4)*PGPKT_DATA_SIZE));
- }else
- {
-
- }
- }
- else{//situation C
- word_en = 0x0f;
- for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
- {
- tmpbitmask = word_start + tmpidx ;
- word_en &= (~(EFUSE_BIT(tmpbitmask)));
- }
- efuse_PgPacketWrite(dev,offset,word_en,data);
- }
-
-}
-
-void efuset_test_func_read(struct net_device* dev)
-{
- u8 chipid[2];
- u8 ocr[3];
- u8 macaddr[6];
- u8 txpowertable[28];
-
- memset(chipid,0,sizeof(u8)*2);
- efuse_read_data(dev,EFUSE_CHIP_ID,chipid,sizeof(chipid));
-
- memset(ocr,0,sizeof(u8)*3);
- efuse_read_data(dev,EFUSE_CCCR,ocr,sizeof(ocr));
-
- memset(macaddr,0,sizeof(u8)*6);
- efuse_read_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr));
-
- memset(txpowertable,0,sizeof(u8)*28);
- efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
-}
-
-void efuset_test_func_write(struct net_device* dev)
-{
- u32 bWordUnit = TRUE;
- u8 CCCR=0x02,SDIO_SETTING = 0xFF;
- u8 tmpdata[2];
-
- u8 macaddr[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
- efuse_write_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr),bWordUnit);
-
- bWordUnit = FALSE;
- efuse_write_data(dev,EFUSE_CCCR,&CCCR,sizeof(u8),bWordUnit);
-
- bWordUnit = FALSE;
- efuse_write_data(dev,EFUSE_SDIO_SETTING,&SDIO_SETTING,sizeof(u8),bWordUnit);
-
- bWordUnit = TRUE;
- tmpdata[0] =SDIO_SETTING ;
- tmpdata[1] =CCCR ;
- efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);
-
-}
diff --git a/drivers/staging/rtl8192su/r8192S_Efuse.h b/drivers/staging/rtl8192su/r8192S_Efuse.h
deleted file mode 100644
index c48a11bc06fe..000000000000
--- a/drivers/staging/rtl8192su/r8192S_Efuse.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-#ifndef __INC_EFUSE_H
-#define __INC_EFUSE_H
-
-#define EFUSE_FOR_92SU 1
-
-#define EFUSE_MAC_LEN 0x200
-#define EFUSE_REAL_CONTENT_LEN 512
-#define EFUSE_MAP_LEN 128
-#define EFUSE_MAX_SECTION 16
-#define EFUSE_MAX_WORD_UNIT 4
-
-#define EFUSE_INIT_MAP 0
-#define EFUSE_MODIFY_MAP 1
-
-#define EFUSE_CLK_CTRL EFUSE_CTRL
-#define EFUSE_BIT(x) (1 << (x))
-
-#define PG_STATE_HEADER 0x01
-#define PG_STATE_WORD_0 0x02
-#define PG_STATE_WORD_1 0x04
-#define PG_STATE_WORD_2 0x08
-#define PG_STATE_WORD_3 0x10
-#define PG_STATE_DATA 0x20
-
-#define PG_SWBYTE_H 0x01
-#define PG_SWBYTE_L 0x02
-
-extern void
-EFUSE_Initialize(struct net_device* dev);
-extern u8
-EFUSE_Read1Byte(struct net_device* dev,u16 Address);
-extern void
-EFUSE_Write1Byte(struct net_device* dev,u16 Address,u8 Value);
-
-#ifdef EFUSE_FOR_92SU
-extern void
-ReadEFuse(struct net_device* dev,u16 _offset,u16 _size_byte,u8* pbuf);
-extern void
-ReadEFuseByte(struct net_device* dev,u16 _offset,u8 *pbuf);
-#endif
-
-extern void
-EFUSE_ShadowRead(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 *Value);
-extern void
-EFUSE_ShadowWrite(struct net_device* dev,unsigned char Type,unsigned short Offset,u32 Value);
-extern bool
-EFUSE_ShadowUpdate(struct net_device* dev);
-extern void
-EFUSE_ShadowMapUpdate(struct net_device* dev);
-
-extern bool
-EFUSE_ProgramMap(struct net_device* dev,char* pFileName, u8 TableType); // 0=Shadow 1=Real Efuse
-
-#endif
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c
deleted file mode 100644
index db0d2d5fc61b..000000000000
--- a/drivers/staging/rtl8192su/r8192S_firmware.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-#include "r8192U.h"
-#include "r8192S_firmware.h"
-#include <linux/unistd.h>
-
-#include "r8192S_hw.h"
-#include "r8192SU_HWImg.h"
-
-#include <linux/firmware.h>
-
-#define byte(x,n) ( (x >> (8 * n)) & 0xff )
-
-//
-// Description: This routine will intialize firmware. If any error occurs during the initialization
-// process, the routine shall terminate immediately and return fail.
-//
-// Arguments: The pointer of the adapter
-// Code address (Virtual address, should fill descriptor with physical address)
-// Code size
-// Created by Roger, 2008.04.10.
-//
-bool FirmwareDownloadCode(struct net_device *dev,
- u8 *code_virtual_address,
- u32 buffer_len)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rt_status = true;
- /* Fragmentation might be required in 90/92 but not in 92S */
- u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
- u16 frag_length, frag_offset = 0;
- struct sk_buff *skb;
- unsigned char *seg_ptr;
- cb_desc *tcb_desc;
- u8 bLastIniPkt = 0;
- u16 ExtraDescOffset = 0;
-
- if (buffer_len >= MAX_FIRMWARE_CODE_SIZE - USB_HWDESC_HEADER_LEN) {
- RT_TRACE(COMP_ERR, "(%s): Firmware exceeds"
- " MAX_FIRMWARE_CODE_SIZE\n", __func__);
- goto cmdsend_downloadcode_fail;
- }
- ExtraDescOffset = USB_HWDESC_HEADER_LEN;
- do {
- if((buffer_len-frag_offset) > frag_threshold)
- frag_length = frag_threshold + ExtraDescOffset;
- else {
- frag_length = (u16)(buffer_len -
- frag_offset + ExtraDescOffset);
- bLastIniPkt = 1;
- }
- /*
- * Allocate skb buffer to contain firmware info
- * and tx descriptor info.
- */
- skb = dev_alloc_skb(frag_length);
- if (skb == NULL) {
- RT_TRACE(COMP_ERR, "(%s): unable to alloc skb buffer\n",
- __func__);
- goto cmdsend_downloadcode_fail;
- }
- memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
-
- tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
- tcb_desc->queue_index = TXCMD_QUEUE;
- tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
- tcb_desc->bLastIniPkt = bLastIniPkt;
-
- skb_reserve(skb, ExtraDescOffset);
-
- seg_ptr = (u8 *)skb_put(skb,
- (u32)(frag_length - ExtraDescOffset));
-
- memcpy(seg_ptr, code_virtual_address + frag_offset,
- (u32)(frag_length-ExtraDescOffset));
-
- tcb_desc->txbuf_size = frag_length;
-
- if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
- (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
- (priv->ieee80211->queue_stop)) {
- RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
- skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
- } else
- priv->ieee80211->softmac_hard_start_xmit(skb, dev);
-
- frag_offset += (frag_length - ExtraDescOffset);
-
- } while (frag_offset < buffer_len);
- return rt_status ;
-
-cmdsend_downloadcode_fail:
- rt_status = false;
- RT_TRACE(COMP_ERR, "(%s): failed\n", __func__);
- return rt_status;
-}
-
-
-bool FirmwareEnableCPU(struct net_device *dev)
-{
- bool rtStatus = true;
- u8 tmpU1b, CPUStatus = 0;
- u16 tmpU2b;
- u32 iCheckTime = 200;
-
- /* Enable CPU. */
- tmpU1b = read_nic_byte(dev, SYS_CLKR);
- /* AFE source */
- write_nic_byte(dev, SYS_CLKR, (tmpU1b|SYS_CPU_CLKSEL));
- tmpU2b = read_nic_word(dev, SYS_FUNC_EN);
- write_nic_word(dev, SYS_FUNC_EN, (tmpU2b|FEN_CPUEN));
- /* Poll IMEM Ready after CPU has refilled. */
- do {
- CPUStatus = read_nic_byte(dev, TCR);
- if (CPUStatus & IMEM_RDY)
- /* success */
- break;
- udelay(100);
- } while (iCheckTime--);
- if (!(CPUStatus & IMEM_RDY)) {
- RT_TRACE(COMP_ERR, "%s(): failed to enable CPU", __func__);
- rtStatus = false;
- }
- return rtStatus;
-}
-
-FIRMWARE_8192S_STATUS
-FirmwareGetNextStatus(FIRMWARE_8192S_STATUS FWCurrentStatus)
-{
- FIRMWARE_8192S_STATUS NextFWStatus = 0;
-
- switch(FWCurrentStatus)
- {
- case FW_STATUS_INIT:
- NextFWStatus = FW_STATUS_LOAD_IMEM;
- break;
-
- case FW_STATUS_LOAD_IMEM:
- NextFWStatus = FW_STATUS_LOAD_EMEM;
- break;
-
- case FW_STATUS_LOAD_EMEM:
- NextFWStatus = FW_STATUS_LOAD_DMEM;
- break;
-
- case FW_STATUS_LOAD_DMEM:
- NextFWStatus = FW_STATUS_READY;
- break;
-
- default:
- RT_TRACE(COMP_ERR,"Invalid FW Status(%#x)!!\n", FWCurrentStatus);
- break;
- }
- return NextFWStatus;
-}
-
-bool FirmwareCheckReady(struct net_device *dev, u8 LoadFWStatus)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rtStatus = true;
- rt_firmware *pFirmware = priv->pFirmware;
- int PollingCnt = 1000;
- u8 CPUStatus = 0;
- u32 tmpU4b;
-
- pFirmware->FWStatus = (FIRMWARE_8192S_STATUS)LoadFWStatus;
- switch (LoadFWStatus) {
- case FW_STATUS_LOAD_IMEM:
- do { /* Polling IMEM code done. */
- CPUStatus = read_nic_byte(dev, TCR);
- if(CPUStatus& IMEM_CODE_DONE)
- break;
- udelay(5);
- } while (PollingCnt--);
- if (!(CPUStatus & IMEM_CHK_RPT) || PollingCnt <= 0) {
- RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\r\n", CPUStatus);
- goto FirmwareCheckReadyFail;
- }
- break;
- case FW_STATUS_LOAD_EMEM: /* Check Put Code OK and Turn On CPU */
- do { /* Polling EMEM code done. */
- CPUStatus = read_nic_byte(dev, TCR);
- if(CPUStatus& EMEM_CODE_DONE)
- break;
- udelay(5);
- } while (PollingCnt--);
- if (!(CPUStatus & EMEM_CHK_RPT)) {
- RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\r\n", CPUStatus);
- goto FirmwareCheckReadyFail;
- }
- /* Turn On CPU */
- if (FirmwareEnableCPU(dev) != true) {
- RT_TRACE(COMP_ERR, "%s(): failed to enable CPU",
- __func__);
- goto FirmwareCheckReadyFail;
- }
- break;
- case FW_STATUS_LOAD_DMEM:
- do { /* Polling DMEM code done */
- CPUStatus = read_nic_byte(dev, TCR);
- if(CPUStatus& DMEM_CODE_DONE)
- break;
-
- udelay(5);
- } while (PollingCnt--);
-
- if (!(CPUStatus & DMEM_CODE_DONE)) {
- RT_TRACE(COMP_ERR, "Polling DMEM code done fail ! CPUStatus(%#x)\n", CPUStatus);
- goto FirmwareCheckReadyFail;
- }
-
- RT_TRACE(COMP_FIRMWARE, "%s(): DMEM code download success, "
- "CPUStatus(%#x)",
- __func__, CPUStatus);
-
- PollingCnt = 10000; /* Set polling cycle to 10ms. */
-
- do { /* Polling Load Firmware ready */
- CPUStatus = read_nic_byte(dev, TCR);
- if(CPUStatus & FWRDY)
- break;
- udelay(100);
- } while (PollingCnt--);
-
- RT_TRACE(COMP_FIRMWARE, "%s(): polling load firmware ready, "
- "CPUStatus(%x)",
- __func__, CPUStatus);
-
- if ((CPUStatus & LOAD_FW_READY) != LOAD_FW_READY) {
- RT_TRACE(COMP_ERR, "Polling Load Firmware ready failed "
- "CPUStatus(%x)\n", CPUStatus);
- goto FirmwareCheckReadyFail;
- }
- /*
- * USB interface will update
- * reserved followings parameters later
- */
-
- //
- // <Roger_Notes> If right here, we can set TCR/RCR to desired value
- // and config MAC lookback mode to normal mode. 2008.08.28.
- //
- tmpU4b = read_nic_dword(dev,TCR);
- write_nic_dword(dev, TCR, (tmpU4b&(~TCR_ICV)));
-
- tmpU4b = read_nic_dword(dev, RCR);
- write_nic_dword(dev, RCR,
- (tmpU4b|RCR_APPFCS|RCR_APP_ICV|RCR_APP_MIC));
-
- RT_TRACE(COMP_FIRMWARE, "%s(): Current RCR settings(%#x)",
- __func__, tmpU4b);
- // Set to normal mode.
- write_nic_byte(dev, LBKMD_SEL, LBK_NORMAL);
- break;
- default:
- break;
- }
- RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), success",
- __func__, LoadFWStatus);
- return rtStatus;
-
-FirmwareCheckReadyFail:
- rtStatus = false;
- RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), failed",
- __func__, LoadFWStatus);
- return rtStatus;
-}
-
-//
-// Description: This routine is to update the RF types in FW header partially.
-//
-// Created by Roger, 2008.12.24.
-//
-u8 FirmwareHeaderMapRfType(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- switch(priv->rf_type)
- {
- case RF_1T1R: return 0x11;
- case RF_1T2R: return 0x12;
- case RF_2T2R: return 0x22;
- case RF_2T2R_GREEN: return 0x92;
- default:
- RT_TRACE(COMP_INIT, "Unknown RF type(%x)\n",priv->rf_type);
- break;
- }
- return 0x22;
-}
-
-
-//
-// Description: This routine is to update the private parts in FW header partially.
-//
-// Created by Roger, 2008.12.18.
-//
-void FirmwareHeaderPriveUpdate(struct net_device *dev, PRT_8192S_FIRMWARE_PRIV pFwPriv)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- // Update USB endpoint number for RQPN settings.
- pFwPriv->usb_ep_num = priv->EEPROMUsbEndPointNumber; // endpoint number: 4, 6 and 11.
- RT_TRACE(COMP_INIT, "FirmwarePriveUpdate(): usb_ep_num(%#x)\n", pFwPriv->usb_ep_num);
-
- // Update RF types for RATR settings.
- pFwPriv->rf_config = FirmwareHeaderMapRfType(dev);
-}
-
-bool FirmwareRequest92S(struct net_device *dev, rt_firmware *pFirmware)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rtStatus = true;
- const char *pFwImageFileName[1] = {"RTL8192SU/rtl8192sfw.bin"};
- u8 *pucMappedFile = NULL;
- u32 ulInitStep = 0;
- u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE;
- PRT_8192S_FIRMWARE_HDR pFwHdr = NULL;
- u32 file_length = 0;
- int rc;
- const struct firmware *fw_entry;
-
- rc = request_firmware(&fw_entry,
- pFwImageFileName[ulInitStep],
- &priv->udev->dev);
- if (rc < 0)
- goto RequestFirmware_Fail;
-
- if (fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
- RT_TRACE(COMP_ERR, "%s(): image file too large"
- "for container buffer", __func__);
- release_firmware(fw_entry);
- goto RequestFirmware_Fail;
- }
-
- memcpy(pFirmware->szFwTmpBuffer, fw_entry->data, fw_entry->size);
- pFirmware->szFwTmpBufferLen = fw_entry->size;
- release_firmware(fw_entry);
-
- pucMappedFile = pFirmware->szFwTmpBuffer;
- file_length = pFirmware->szFwTmpBufferLen;
-
- /* Retrieve FW header. */
- pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
- pFwHdr = pFirmware->pFwHeader;
-
- RT_TRACE(COMP_FIRMWARE, "%s(): signature: %x, version: %x, "
- "size: %x, imemsize: %x, sram size: %x",
- __func__, pFwHdr->Signature, pFwHdr->Version,
- pFwHdr->DMEMSize, pFwHdr->IMG_IMEM_SIZE,
- pFwHdr->IMG_SRAM_SIZE);
-
- pFirmware->FirmwareVersion = byte(pFwHdr->Version , 0);
-
- if ((pFwHdr->IMG_IMEM_SIZE == 0) ||
- (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) {
- RT_TRACE(COMP_ERR, "%s(): memory for data image is less than"
- " IMEM requires", __func__);
- goto RequestFirmware_Fail;
- } else {
- pucMappedFile += FwHdrSize;
- /* Retrieve IMEM image. */
- memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
- pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
- }
-
- if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) {
- RT_TRACE(COMP_ERR, "%s(): memory for data image is less than"
- " EMEM requires", __func__);
- goto RequestFirmware_Fail;
- } else {
- pucMappedFile += pFirmware->FwIMEMLen;
- /* Retriecve EMEM image */
- memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);
- pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
- }
- return rtStatus;
-
-RequestFirmware_Fail:
- RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n",
- __func__, read_nic_word(dev, TCR));
- rtStatus = false;
- return rtStatus;
-}
-
-bool FirmwareDownload92S(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rtStatus = true;
- u8 *pucMappedFile = NULL;
- u32 ulFileLength;
- u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE;
- rt_firmware *pFirmware = priv->pFirmware;
- u8 FwStatus = FW_STATUS_INIT;
- PRT_8192S_FIRMWARE_HDR pFwHdr = NULL;
- PRT_8192S_FIRMWARE_PRIV pFwPriv = NULL;
-
- pFirmware->FWStatus = FW_STATUS_INIT;
- /*
- * Load the firmware from RTL8192SU/rtl8192sfw.bin if necessary
- */
- if (pFirmware->szFwTmpBufferLen == 0) {
- if (FirmwareRequest92S(dev, pFirmware) != true)
- goto DownloadFirmware_Fail;
- }
- FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
- while (FwStatus != FW_STATUS_READY) {
- /* Image buffer redirection. */
- switch (FwStatus) {
- case FW_STATUS_LOAD_IMEM:
- pucMappedFile = pFirmware->FwIMEM;
- ulFileLength = pFirmware->FwIMEMLen;
- break;
-
- case FW_STATUS_LOAD_EMEM:
- pucMappedFile = pFirmware->FwEMEM;
- ulFileLength = pFirmware->FwEMEMLen;
- break;
-
- case FW_STATUS_LOAD_DMEM:
- /* Partial update the content of private header */
- pFwHdr = pFirmware->pFwHeader;
- pFwPriv = (PRT_8192S_FIRMWARE_PRIV)&pFwHdr->FWPriv;
- FirmwareHeaderPriveUpdate(dev, pFwPriv);
- pucMappedFile = (u8 *)(pFirmware->pFwHeader) +
- RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
-
- ulFileLength = FwHdrSize -
- RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
- break;
-
- default:
- RT_TRACE(COMP_ERR, "Unexpected Download step!!\n");
- goto DownloadFirmware_Fail;
- break;
- }
-
- /* <2> Download image file */
-
- rtStatus = FirmwareDownloadCode(dev,
- pucMappedFile,
- ulFileLength);
-
- if(rtStatus != true)
- goto DownloadFirmware_Fail;
-
- /* <3> Check whether load FW process is ready */
-
- rtStatus = FirmwareCheckReady(dev, FwStatus);
-
- if(rtStatus != true)
- goto DownloadFirmware_Fail;
-
- FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
- }
-
- RT_TRACE(COMP_FIRMWARE, "%s(): Firmware Download Success", __func__);
- return rtStatus;
-
-DownloadFirmware_Fail:
- RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n",
- __func__, read_nic_word(dev, TCR));
- rtStatus = false;
- return rtStatus;
-}
-
-MODULE_FIRMWARE("RTL8192SU/rtl8192sfw.bin");
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.h b/drivers/staging/rtl8192su/r8192S_firmware.h
deleted file mode 100644
index 7f268a8de5e8..000000000000
--- a/drivers/staging/rtl8192su/r8192S_firmware.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef __INC_FIRMWARE_H
-#define __INC_FIRMWARE_H
-
-
-#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k
-#define MAX_FIRMWARE_CODE_SIZE 0xFF00 // Firmware Local buffer size.
-#define RTL8190_CPU_START_OFFSET 0x80
-#define RTL8192S_FW_PKT_FRAG_SIZE 0x4000
-#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
-
-
-#ifdef RTL8192S
-typedef enum _firmware_init_step{
- FW_INIT_STEP0_IMEM = 0,
- FW_INIT_STEP1_MAIN = 1,
- FW_INIT_STEP2_DATA = 2,
-}firmware_init_step_e;
-#else
-typedef enum _firmware_init_step{
- FW_INIT_STEP0_BOOT = 0,
- FW_INIT_STEP1_MAIN = 1,
- FW_INIT_STEP2_DATA = 2,
-}firmware_init_step_e;
-#endif
-
-/* due to rtl8192 firmware */
-typedef enum _desc_packet_type_e{
- DESC_PACKET_TYPE_INIT = 0,
- DESC_PACKET_TYPE_NORMAL = 1,
-}desc_packet_type_e;
-
-typedef enum _opt_rst_type{
- OPT_SYSTEM_RESET = 0,
- OPT_FIRMWARE_RESET = 1,
-}opt_rst_type_e;
-
-//--------------------------------------------------------------------------------
-// RTL8192S Firmware related
-//--------------------------------------------------------------------------------
-typedef struct _RT_8192S_FIRMWARE_PRIV { //8-bytes alignment required
-
- //--- long word 0 ----
- u8 signature_0; //0x12: CE product, 0x92: IT product
- u8 signature_1; //0x87: CE product, 0x81: IT product
- u8 hci_sel; //0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP, 0x12: 72S-U, 03:SDIO
- u8 chip_version; //the same value as reigster value
- u8 customer_ID_0; //customer ID low byte
- u8 customer_ID_1; //customer ID high byte
- u8 rf_config; //0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo, 0x22: 2T2R
- u8 usb_ep_num; // 4: 4EP, 6: 6EP, 11: 11EP
-
- //--- long word 1 ----
- u8 regulatory_class_0; //regulatory class bit map 0
- u8 regulatory_class_1; //regulatory class bit map 1
- u8 regulatory_class_2; //regulatory class bit map 2
- u8 regulatory_class_3; //regulatory class bit map 3
- u8 rfintfs; // 0:SWSI, 1:HWSI, 2:HWPI
- u8 def_nettype;
- u8 rsvd010;
- u8 rsvd011;
-
-
- //--- long word 2 ----
- u8 lbk_mode; //0x00: normal, 0x03: MACLBK, 0x01: PHYLBK
- u8 mp_mode; // 1: for MP use, 0: for normal driver (to be discussed)
- u8 rsvd020;
- u8 rsvd021;
- u8 rsvd022;
- u8 rsvd023;
- u8 rsvd024;
- u8 rsvd025;
-
- //--- long word 3 ----
- u8 qos_en; // QoS enable
- u8 bw_40MHz_en; // 40MHz BW enable
- u8 AMSDU2AMPDU_en; // 4181 convert AMSDU to AMPDU, 0: disable
- u8 AMPDU_en; // 11n AMPDU enable
- u8 rate_control_offload;//FW offloads, 0: driver handles
- u8 aggregation_offload; // FW offloads, 0: driver handles
- u8 rsvd030;
- u8 rsvd031;
-
-
- //--- long word 4 ----
- unsigned char beacon_offload; // 1. FW offloads, 0: driver handles
- unsigned char MLME_offload; // 2. FW offloads, 0: driver handles
- unsigned char hwpc_offload; // 3. FW offloads, 0: driver handles
- unsigned char tcp_checksum_offload; // 4. FW offloads, 0: driver handles
- unsigned char tcp_offload; // 5. FW offloads, 0: driver handles
- unsigned char ps_control_offload; // 6. FW offloads, 0: driver handles
- unsigned char WWLAN_offload; // 7. FW offloads, 0: driver handles
- unsigned char rsvd040;
-
- //--- long word 5 ----
- u8 tcp_tx_frame_len_L; //tcp tx packet length low byte
- u8 tcp_tx_frame_len_H; //tcp tx packet length high byte
- u8 tcp_rx_frame_len_L; //tcp rx packet length low byte
- u8 tcp_rx_frame_len_H; //tcp rx packet length high byte
- u8 rsvd050;
- u8 rsvd051;
- u8 rsvd052;
- u8 rsvd053;
-}RT_8192S_FIRMWARE_PRIV, *PRT_8192S_FIRMWARE_PRIV;
-
-typedef struct _RT_8192S_FIRMWARE_HDR {//8-byte alinment required
-
- //--- LONG WORD 0 ----
- u16 Signature;
- u16 Version; //0x8000 ~ 0x8FFF for FPGA version, 0x0000 ~ 0x7FFF for ASIC version,
- u32 DMEMSize; //define the size of boot loader
-
-
- //--- LONG WORD 1 ----
- u32 IMG_IMEM_SIZE; //define the size of FW in IMEM
- u32 IMG_SRAM_SIZE; //define the size of FW in SRAM
-
- //--- LONG WORD 2 ----
- u32 FW_PRIV_SIZE; //define the size of DMEM variable
- u32 Rsvd0;
-
- //--- LONG WORD 3 ----
- u32 Rsvd1;
- u32 Rsvd2;
-
- RT_8192S_FIRMWARE_PRIV FWPriv;
-
-}RT_8192S_FIRMWARE_HDR, *PRT_8192S_FIRMWARE_HDR;
-
-#define RT_8192S_FIRMWARE_HDR_SIZE 80
-#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32
-
-typedef enum _FIRMWARE_8192S_STATUS{
- FW_STATUS_INIT = 0,
- FW_STATUS_LOAD_IMEM = 1,
- FW_STATUS_LOAD_EMEM = 2,
- FW_STATUS_LOAD_DMEM = 3,
- FW_STATUS_READY = 4,
-}FIRMWARE_8192S_STATUS;
-
-#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k
-
-typedef struct _rt_firmware{
- PRT_8192S_FIRMWARE_HDR pFwHeader;
- FIRMWARE_8192S_STATUS FWStatus;
- u8 FwIMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
- u8 FwEMEM[RTL8190_MAX_FIRMWARE_CODE_SIZE];
- u32 FwIMEMLen;
- u32 FwEMEMLen;
- u8 szFwTmpBuffer[164000];
- u32 szFwTmpBufferLen;
- u16 CmdPacketFragThresold;
- u16 FirmwareVersion;
-}rt_firmware, *prt_firmware;
-
-#define FW_DIG_ENABLE_CTL BIT0
-#define FW_HIGH_PWR_ENABLE_CTL BIT1
-#define FW_SS_CTL BIT2
-#define FW_RA_INIT_CTL BIT3
-#define FW_RA_BG_CTL BIT4
-#define FW_RA_N_CTL BIT5
-#define FW_PWR_TRK_CTL BIT6
-#define FW_IQK_CTL BIT7
-#define FW_ANTENNA_SW BIT8
-#define FW_DISABLE_ALL_DM 0
-
-#define FW_PWR_TRK_PARAM_CLR 0x0000ffff
-#define FW_RA_PARAM_CLR 0xffff0000
-
-#define FW_CMD_IO_CLR(_pdev, _Bit) \
- udelay(1000); \
- ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap &= (~_Bit);
-
-#define FW_CMD_IO_UPDATE(_pdev, _val) \
- ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap = _val;
-
-#define FW_CMD_IO_SET(_pdev, _val) \
- write_nic_word(_pdev, LBUS_MON_ADDR, (u16)_val); \
- FW_CMD_IO_UPDATE(_pdev, _val);
-
-#define FW_CMD_PARA_SET(_pdev, _val) \
- write_nic_dword(_pdev, LBUS_ADDR_MASK, _val); \
- ((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam = _val;
-
-#define FW_CMD_IO_QUERY(_pdev) (u16)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOMap)
-#define FW_CMD_IO_PARA_QUERY(_pdev) (u32)(((struct r8192_priv *)ieee80211_priv(_pdev))->FwCmdIOParam)
-
-
-
-bool FirmwareDownload92S(struct net_device *dev);
-
-#endif
-
diff --git a/drivers/staging/rtl8192su/r8192S_hw.h b/drivers/staging/rtl8192su/r8192S_hw.h
deleted file mode 100644
index e62b79df5ba5..000000000000
--- a/drivers/staging/rtl8192su/r8192S_hw.h
+++ /dev/null
@@ -1,1445 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-#ifndef R8192S_HW
-#define R8192S_HW
-
-typedef enum _VERSION_8192S{
- VERSION_8192S_ACUT,
- VERSION_8192S_BCUT,
- VERSION_8192S_CCUT
-}VERSION_8192S,*PVERSION_8192S;
-
-typedef enum _VERSION_8192SUsb{
- VERSION_8192SU_A, //A-Cut
- VERSION_8192SU_B, //B-Cut
- VERSION_8192SU_C, //C-Cut
-}VERSION_8192SUsb, *PVERSION_8192SUsb;
-
-
-/* RF type. */
-typedef enum _RT_RF_TYPE_DEFINITION
-{
- RF_1T2R = 0,
- RF_2T4R,
- RF_2T2R,
- RF_1T1R,
- RF_2T2R_GREEN,
- RF_819X_MAX_TYPE
-}RT_RF_TYPE_DEF_E;
-
-typedef enum _BaseBand_Config_Type{
- BaseBand_Config_PHY_REG = 0, //Radio Path A
- BaseBand_Config_AGC_TAB = 1, //Radio Path B
-}BaseBand_Config_Type, *PBaseBand_Config_Type;
-
-#define RTL8187_REQT_READ 0xc0
-#define RTL8187_REQT_WRITE 0x40
-#define RTL8187_REQ_GET_REGS 0x05
-#define RTL8187_REQ_SET_REGS 0x05
-
-#define MAX_TX_URB 5
-#define MAX_RX_URB 8
-
-#define R8180_MAX_RETRY 255
-#define RX_URB_SIZE 0x4000
-
-#define BB_ANTATTEN_CHAN14 0x0c
-#define BB_ANTENNA_B 0x40
-
-#define BB_HOST_BANG (1<<30)
-#define BB_HOST_BANG_EN (1<<2)
-#define BB_HOST_BANG_CLK (1<<1)
-#define BB_HOST_BANG_RW (1<<3)
-#define BB_HOST_BANG_DATA 1
-
-
-//============================================================
-// 8192S Regsiter bit
-//============================================================
-#define BB_GLOBAL_RESET_BIT 0x1
-
-#define CR_RST 0x10
-#define CR_RE 0x08
-#define CR_TE 0x04
-#define CR_MulRW 0x01
-
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
- (1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_128 3
-#define RX_FIFO_THRESHOLD_256 4
-#define RX_FIFO_THRESHOLD_512 5
-#define RX_FIFO_THRESHOLD_1024 6
-#define RX_FIFO_THRESHOLD_NONE 7
-
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-
-//----------------------------------------------------------------------------
-// 8190 CPU General Register (offset 0x100, 4 byte)
-//----------------------------------------------------------------------------
-#define CPU_CCK_LOOPBACK 0x00030000
-#define CPU_GEN_SYSTEM_RESET 0x00000001
-#define CPU_GEN_FIRMWARE_RESET 0x00000008
-#define CPU_GEN_BOOT_RDY 0x00000010
-#define CPU_GEN_FIRM_RDY 0x00000020
-#define CPU_GEN_PUT_CODE_OK 0x00000080
-#define CPU_GEN_BB_RST 0x00000100
-#define CPU_GEN_PWR_STB_CPU 0x00000004
-#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
-#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1
-//----------------------------------------------------------------------------
-////
-//// 8190 AcmHwCtrl bits (offset 0x171, 1 byte)
-////----------------------------------------------------------------------------
-#define MSR_LINK_MASK ((1<<0)|(1<<1))
-#define MSR_LINK_MANAGED 2
-#define MSR_LINK_NONE 0
-#define MSR_LINK_SHIFT 0
-#define MSR_LINK_ADHOC 1
-#define MSR_LINK_MASTER 3
-#define MSR_LINK_ENEDCA (1<<4)
-
-
-#define EPROM_CMD_RESERVED_MASK (1<<5)
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-
-//============================================================
-// 8192S Regsiter offset definition
-//============================================================
-
-//
-// MAC register 0x0 - 0x5xx
-// 1. System configuration registers.
-// 2. Command Control Registers
-// 3. MACID Setting Registers
-// 4. Timing Control Registers
-// 5. FIFO Control Registers
-// 6. Adaptive Control Registers
-// 7. EDCA Setting Registers
-// 8. WMAC, BA and CCX related Register.
-// 9. Security Control Registers
-// 10. Power Save Control Registers
-// 11. General Purpose Registers
-// 12. Host Interrupt Status Registers
-// 13. Test Mode and Debug Control Registers
-// 14. PCIE config register
-//
-
-
-//
-// 1. System Configuration Registers (Offset: 0x0000 - 0x003F)
-//
-#define SYS_ISO_CTRL 0x0000 // System Isolation Interface Control.
-#define SYS_FUNC_EN 0x0002 // System Function Enable.
-#define PMC_FSM 0x0004 // Power Sequence Control.
-#define SYS_CLKR 0x0008 // System Clock.
-#define EPROM_CMD 0x000A // 93C46/93C56 Command Register. (win CR93C46)
-#define EE_VPD 0x000C // EEPROM VPD Data.
-#define AFE_MISC 0x0010 // AFE Misc.
-#define SPS0_CTRL 0x0011 // Switching Power Supply 0 Control.
-#define SPS1_CTRL 0x0018 // Switching Power Supply 1 Control.
-#define RF_CTRL 0x001F // RF Block Control.
-#define LDOA15_CTRL 0x0020 // V15 Digital LDO Control.
-#define LDOV12D_CTRL 0x0021 // V12 Digital LDO Control.
-#define LDOHCI12_CTRL 0x0022 // V12 Digital LDO Control.
-#define LDO_USB_SDIO 0x0023 // LDO USB Control.
-#define LPLDO_CTRL 0x0024 // Low Power LDO Control.
-#define AFE_XTAL_CTRL 0x0026 // AFE Crystal Control.
-#define AFE_PLL_CTRL 0x0028 // System Function Enable.
-#define EFUSE_CTRL 0x0030 // E-Fuse Control.
-#define EFUSE_TEST 0x0034 // E-Fuse Test.
-#define PWR_DATA 0x0038 // Power on date.
-#define DBG_PORT 0x003A // MAC debug port select
-#define DPS_TIMER 0x003C // Deep Power Save Timer Register.
-#define RCLK_MON 0x003E // Retention Clock Monitor.
-
-//
-// 2. Command Control Registers (Offset: 0x0040 - 0x004F)
-//
-#define CMDR 0x0040 // MAC Command Register.
-#define TXPAUSE 0x0042 // Transmission Pause Register.
-#define LBKMD_SEL 0x0043 // Loopback Mode Select Register.
-#define TCR 0x0044 // Transmit Configuration Register
-#define RCR 0x0048 // Receive Configuration Register
-#define MSR 0x004C // Media Status register
-#define SYSF_CFG 0x004D // System Function Configuration.
-#define RX_PKY_LIMIT 0x004E // RX packet length limit
-#define MBIDCTRL 0x004F // MBSSID Control.
-
-//
-// 3. MACID Setting Registers (Offset: 0x0050 - 0x007F)
-//
-#define MACIDR 0x0050 // MAC ID Register, Offset 0x0050-0x0055
-#define MACIDR0 0x0050 // MAC ID Register, Offset 0x0050-0x0053
-#define MACIDR4 0x0054 // MAC ID Register, Offset 0x0054-0x0055
-#define BSSIDR 0x0058 // BSSID Register, Offset 0x0058-0x005D
-#define HWVID 0x005E // HW Version ID.
-#define MAR 0x0060 // Multicase Address.
-#define MBIDCAMCONTENT 0x0068 // MBSSID CAM Content.
-#define MBIDCAMCFG 0x0070 // MBSSID CAM Configuration.
-#define BUILDTIME 0x0074 // Build Time Register.
-#define BUILDUSER 0x0078 // Build User Register.
-
-// Redifine MACID register, to compatible prior ICs.
-#define IDR0 MACIDR0
-#define IDR4 MACIDR4
-
-//
-// 4. Timing Control Registers (Offset: 0x0080 - 0x009F)
-//
-#define TSFR 0x0080 // Timing Sync Function Timer Register.
-#define SLOT_TIME 0x0089 // Slot Time Register, in us.
-#define USTIME 0x008A // EDCA/TSF clock unit time us unit.
-#define SIFS_CCK 0x008C // SIFS for CCK, in us.
-#define SIFS_OFDM 0x008E // SIFS for OFDM, in us.
-#define PIFS_TIME 0x0090 // PIFS time register.
-#define ACK_TIMEOUT 0x0091 // Ack Timeout Register
-#define EIFSTR 0x0092 // EIFS time regiser.
-#define BCN_INTERVAL 0x0094 // Beacon Interval, in TU.
-#define ATIMWND 0x0096 // ATIM Window width, in TU.
-#define BCN_DRV_EARLY_INT 0x0098 // Driver Early Interrupt.
-#define BCN_DMATIME 0x009A // Beacon DMA and ATIM INT Time.
-#define BCN_ERR_THRESH 0x009C // Beacon Error Threshold.
-#define MLT 0x009D // MSDU Lifetime.
-#define RSVD_MAC_TUNE_US 0x009E // MAC Internal USE.
-
-//
-// 5. FIFO Control Registers (Offset: 0x00A0 - 0x015F)
-//
-#define RQPN 0x00A0
-#define RQPN1 0x00A0 // Reserved Queue Page Number for BK
-#define RQPN2 0x00A1 // Reserved Queue Page Number for BE
-#define RQPN3 0x00A2 // Reserved Queue Page Number for VI
-#define RQPN4 0x00A3 // Reserved Queue Page Number for VO
-#define RQPN5 0x00A4 // Reserved Queue Page Number for HCCA
-#define RQPN6 0x00A5 // Reserved Queue Page Number for CMD
-#define RQPN7 0x00A6 // Reserved Queue Page Number for MGNT
-#define RQPN8 0x00A7 // Reserved Queue Page Number for HIGH
-#define RQPN9 0x00A8 // Reserved Queue Page Number for Beacon
-#define RQPN10 0x00A9 // Reserved Queue Page Number for Public
-#define LD_RQPN 0x00AB //
-#define RXFF_BNDY 0x00AC //
-#define RXRPT_BNDY 0x00B0 //
-#define TXPKTBUF_PGBNDY 0x00B4 //
-#define PBP 0x00B5 //
-#define RXDRVINFO_SZ 0x00B6 //
-#define TXFF_STATUS 0x00B7 //
-#define RXFF_STATUS 0x00B8 //
-#define TXFF_EMPTY_TH 0x00B9 //
-#define SDIO_RX_BLKSZ 0x00BC //
-#define RXDMA 0x00BD //
-#define RXPKT_NUM 0x00BE //
-#define C2HCMD_UDT_SIZE 0x00C0 //
-#define C2HCMD_UDT_ADDR 0x00C2 //
-#define FIFOPAGE1 0x00C4 // Available public queue page number
-#define FIFOPAGE2 0x00C8 //
-#define FIFOPAGE3 0x00CC //
-#define FIFOPAGE4 0x00D0 //
-#define FIFOPAGE5 0x00D4 //
-#define FW_RSVD_PG_CRTL 0x00D8 //
-#define RXDMA_AGG_PG_TH 0x00D9 //
-#define TXRPTFF_RDPTR 0x00E0 //
-#define TXRPTFF_WTPTR 0x00E4 //
-#define C2HFF_RDPTR 0x00E8 //FIFO Read pointer register.
-#define C2HFF_WTPTR 0x00EC //FIFO Write pointer register.
-#define RXFF0_RDPTR 0x00F0 //
-#define RXFF0_WTPTR 0x00F4 //
-#define RXFF1_RDPTR 0x00F8 //
-#define RXFF1_WTPTR 0x00FC //
-#define RXRPT0_RDPTR 0x0100 //
-#define RXRPT0_WTPTR 0x0104 //
-#define RXRPT1_RDPTR 0x0108 //
-#define RXRPT1_WTPTR 0x010C //
-#define RX0_UDT_SIZE 0x0110 //
-#define RX1PKTNUM 0x0114 //
-#define RXFILTERMAP 0x0116 //
-#define RXFILTERMAP_GP1 0x0118 //
-#define RXFILTERMAP_GP2 0x011A //
-#define RXFILTERMAP_GP3 0x011C //
-#define BCNQ_CTRL 0x0120 //
-#define MGTQ_CTRL 0x0124 //
-#define HIQ_CTRL 0x0128 //
-#define VOTID7_CTRL 0x012c //
-#define VOTID6_CTRL 0x0130 //
-#define VITID5_CTRL 0x0134 //
-#define VITID4_CTRL 0x0138 //
-#define BETID3_CTRL 0x013c //
-#define BETID0_CTRL 0x0140 //
-#define BKTID2_CTRL 0x0144 //
-#define BKTID1_CTRL 0x0148 //
-#define CMDQ_CTRL 0x014c //
-#define TXPKT_NUM_CTRL 0x0150 //
-#define TXQ_PGADD 0x0152 //
-#define TXFF_PG_NUM 0x0154 //
-#define TRXDMA_STATUS 0x0156 //
-
-//
-// 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF)
-//
-#define INIMCS_SEL 0x0160 // Init MCSrate for 32 MACID 0x160-17f
-#define TX_RATE_REG INIMCS_SEL //Current Tx rate register
-#define INIRTSMCS_SEL 0x0180 // Init RTSMCSrate
-#define RRSR 0x0181 // Response rate setting.
-#define ARFR0 0x0184 // Auto Rate Fallback 0 Register.
-#define ARFR1 0x0188 //
-#define ARFR2 0x018C //
-#define ARFR3 0x0190 //
-#define ARFR4 0x0194 //
-#define ARFR5 0x0198 //
-#define ARFR6 0x019C //
-#define ARFR7 0x01A0 //
-#define AGGLEN_LMT_H 0x01A7 // Aggregation Length Limit for High-MCS
-#define AGGLEN_LMT_L 0x01A8 // Aggregation Length Limit for Low-MCS.
-#define DARFRC 0x01B0 // Data Auto Rate Fallback Retry Count.
-#define RARFRC 0x01B8 // Response Auto Rate Fallback Count.
-#define MCS_TXAGC 0x01C0
-#define CCK_TXAGC 0x01C8
-
-//
-// 7. EDCA Setting Registers (Offset: 0x01D0 - 0x01FF)
-//
-#define EDCAPARA_VO 0x01D0 // EDCA Parameter Register for VO queue.
-#define EDCAPARA_VI 0x01D4 // EDCA Parameter Register for VI queue.
-#define EDCAPARA_BE 0x01D8 // EDCA Parameter Register for BE queue.
-#define EDCAPARA_BK 0x01DC // EDCA Parameter Register for BK queue.
-#define BCNTCFG 0x01E0 // Beacon Time Configuration Register.
-#define CWRR 0x01E2 // Contention Window Report Register.
-#define ACMAVG 0x01E4 // ACM Average Register.
-#define AcmHwCtrl 0x01E7
-#define VO_ADMTM 0x01E8 // Admission Time Register.
-#define VI_ADMTM 0x01EC
-#define BE_ADMTM 0x01F0
-#define RETRY_LIMIT 0x01F4 // Retry Limit Registers[15:8]-short, [7:0]-long
-#define SG_RATE 0x01F6 // Max MCS Rate Available Register, which we Set the hightst SG rate.
-
-//
-// 8. WMAC, BA and CCX related Register. (Offset: 0x0200 - 0x023F)
-//
-#define NAV_CTRL 0x0200
-#define BW_OPMODE 0x0203
-#define BACAMCMD 0x0204
-#define BACAMCONTENT 0x0208 // Block ACK CAM R/W Register.
-
-// Roger had defined the 0x2xx register WMAC definition
-#define LBDLY 0x0210 // Loopback Delay Register.
-#define FWDLY 0x0211 // FW Delay Register.
-#define HWPC_RX_CTRL 0x0218 // HW Packet Conversion RX Control Reg
-#define MQIR 0x0220 // Mesh Qos Type Indication Register.
-#define MAIR 0x0222 // Mesh ACK.
-#define MSIR 0x0224 // Mesh HW Security Requirement Indication Reg
-#define CLM_RESULT 0x0227 // CCA Busy Fraction(Channel Load)
-#define NHM_RPI_CNT 0x0228 // Noise Histogram Measurement (NHM) RPI Report.
-#define RXERR_RPT 0x0230 // Rx Error Report.
-#define NAV_PROT_LEN 0x0234 // NAV Protection Length.
-#define CFEND_TH 0x0236 // CF-End Threshold.
-#define AMPDU_MIN_SPACE 0x0237 // AMPDU Min Space.
-#define TXOP_STALL_CTRL 0x0238
-
-//
-// 9. Security Control Registers (Offset: 0x0240 - 0x025F)
-//
-#define RWCAM 0x0240 //IN 8190 Data Sheet is called CAMcmd
-#define WCAMI 0x0244 // Software write CAM input content
-#define RCAMO 0x0248 // Software read/write CAM config
-#define CAMDBG 0x024C
-#define SECR 0x0250 //Security Configuration Register
-
-//
-// 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF)
-//
-#define WOW_CTRL 0x0260 //Wake On WLAN Control.
-#define PSSTATUS 0x0261 // Power Save Status.
-#define PSSWITCH 0x0262 // Power Save Switch.
-#define MIMOPS_WAIT_PERIOD 0x0263
-#define LPNAV_CTRL 0x0264
-#define WFM0 0x0270 // Wakeup Frame Mask.
-#define WFM1 0x0280 //
-#define WFM2 0x0290 //
-#define WFM3 0x02A0 //
-#define WFM4 0x02B0 //
-#define WFM5 0x02C0 // FW Control register.
-#define WFCRC 0x02D0 // Wakeup Frame CRC.
-#define RPWM 0x02DC // Host Request Power Mode.
-#define CPWM 0x02DD // Current Power Mode.
-#define FW_RPT_REG 0x02c4
-
-//
-// 11. General Purpose Registers (Offset: 0x02E0 - 0x02FF)
-//
-#define PSTIME 0x02E0 // Power Save Timer Register
-#define TIMER0 0x02E4 //
-#define TIMER1 0x02E8 //
-#define GPIO_CTRL 0x02EC // GPIO Control Register
-#define GPIO_IN 0x02EC // GPIO pins input value
-#define GPIO_OUT 0x02ED // GPIO pins output value
-#define GPIO_IO_SEL 0x02EE // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured.
-#define GPIO_MOD 0x02EF //
-#define GPIO_INTCTRL 0x02F0 // GPIO Interrupt Control Register[7:0]
-#define MAC_PINMUX_CFG 0x02F1 // MAC PINMUX Configuration Reg[7:0]
-#define LEDCFG 0x02F2 // System PINMUX Configuration Reg[7:0]
-#define PHY_REG 0x02F3 // RPT: PHY REG Access Report Reg[7:0]
-#define PHY_REG_DATA 0x02F4 // PHY REG Read DATA Register [31:0]
-#define EFUSE_CLK 0x02F8 // CTRL: E-FUSE Clock Control Reg[7:0]
-//#define GPIO_INTCTRL 0x02F9 // GPIO Interrupt Control Register[7:0]
-
-//
-// 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F)
-//
-#define IMR 0x0300 // Interrupt Mask Register
-#define ISR 0x0308 // Interrupt Status Register
-
-//
-// 13. Test Mode and Debug Control Registers (Offset: 0x0310 - 0x034F)
-//
-#define DBG_PORT_SWITCH 0x003A
-#define BIST 0x0310 // Bist reg definition
-#define DBS 0x0314 // Debug Select ???
-#define CPUINST 0x0318 // CPU Instruction Read Register
-#define CPUCAUSE 0x031C // CPU Cause Register
-#define LBUS_ERR_ADDR 0x0320 // Lexra Bus Error Address Register
-#define LBUS_ERR_CMD 0x0324 // Lexra Bus Error Command Register
-#define LBUS_ERR_DATA_L 0x0328 // Lexra Bus Error Data Low DW Register
-#define LBUS_ERR_DATA_H 0x032C //
-#define LX_EXCEPTION_ADDR 0x0330 // Lexra Bus Exception Address Register
-#define WDG_CTRL 0x0334 // Watch Dog Control Register
-#define INTMTU 0x0338 // Interrupt Mitigation Time Unit Reg
-#define INTM 0x033A // Interrupt Mitigation Register
-#define FDLOCKTURN0 0x033C // FW/DRV Lock Turn 0 Register
-#define FDLOCKTURN1 0x033D // FW/DRV Lock Turn 1 Register
-#define TRXPKTBUF_DBG_DATA 0x0340 // TRX Packet Buffer Debug Data Register
-#define TRXPKTBUF_DBG_CTRL 0x0348 // TRX Packet Buffer Debug Control Reg
-#define DPLL 0x034A // DPLL Monitor Register [15:0]
-#define CBUS_ERR_ADDR 0x0350 // CPU Bus Error Address Register
-#define CBUS_ERR_CMD 0x0354 // CPU Bus Error Command Register
-#define CBUS_ERR_DATA_L 0x0358 // CPU Bus Error Data Low DW Register
-#define CBUS_ERR_DATA_H 0x035C //
-#define USB_SIE_INTF_ADDR 0x0360 // USB SIE Access Interface Address Reg
-#define USB_SIE_INTF_WD 0x0361 // USB SIE Access Interface WData Reg
-#define USB_SIE_INTF_RD 0x0362 // USB SIE Access Interface RData Reg
-#define USB_SIE_INTF_CTRL 0x0363 // USB SIE Access Interface Control Reg
-
-// Boundary is 0x37F
-
-//
-// 14. PCIE config register (Offset 0x500-)
-//
-#define TPPoll 0x0500 // Transmit Polling
-#define PM_CTRL 0x0502 // PCIE power management control Register
-#define PCIF 0x0503 // PCI Function Register 0x0009h~0x000bh
-
-#define THPDA 0x0514 // Transmit High Priority Desc Addr
-#define TMDA 0x0518 // Transmit Management Desc Addr
-#define TCDA 0x051C // Transmit Command Desc Addr
-#define HDA 0x0520 // HCCA Desc Addr
-#define TVODA 0x0524 // Transmit VO Desc Addr
-#define TVIDA 0x0528 // Transmit VI Desc Addr
-#define TBEDA 0x052C // Transmit BE Desc Addr
-#define TBKDA 0x0530 // Transmit BK Desc Addr
-#define TBDA 0x0534 // Transmit Beacon Desc Addr
-#define RCDA 0x0538 // Receive Command Desc Addr
-#define RDSA 0x053C // Receive Desc Starting Addr
-#define DBI_WDATA 0x0540 // DBI write data Register
-#define DBI_RDATA 0x0544 // DBI read data Register
-#define DBI_CTRL 0x0548 // PCIE DBI control Register
-#define MDIO_DATA 0x0550 // PCIE MDIO data Register
-#define MDIO_CTRL 0x0554 // PCIE MDIO control Register
-#define PCI_RPWM 0x0561 // PCIE RPWM register
-#define PCI_CPWM 0x0563 // Current Power Mode.
-
-//
-// Config register (Offset 0x800-)
-//
-#define PHY_CCA 0x803 // CCA related register
-
-//============================================================================
-// 8192S USB specific Regsiter Offset and Content definition,
-// 2008.08.28, added by Roger.
-//============================================================================
-// Rx Aggregation time-out reg.
-#define USB_RX_AGG_TIMEOUT 0xFE5B
-
-// Firware reserved Tx page control.
-#define FW_OFFLOAD_EN BIT7
-
-// Min Spacing related settings.
-#define MAX_MSS_DENSITY 0x13
-#define MAX_MSS_DENSITY_2T 0x13
-#define MAX_MSS_DENSITY_1T 0x0A
-
-// Rx DMA Control related settings
-#define RXDMA_AGG_EN BIT7
-
-// USB Rx Aggregation TimeOut settings
-#define RXDMA_AGG_TIMEOUT_DISABLE 0x00
-#define RXDMA_AGG_TIMEOUT_17MS 0x01
-#define RXDMA_AGG_TIMEOUT_17_2_MS 0x02
-#define RXDMA_AGG_TIMEOUT_17_4_MS 0x04
-#define RXDMA_AGG_TIMEOUT_17_10_MS 0x0A
-// USB RPWM register
-#define USB_RPWM 0xFE58
-
-//============================================================================
-// 8190 Regsiter offset definition
-//============================================================================
-#if 1 // Delete the register later
-#define AFR 0x010 // AutoLoad Function Register
-#define BCN_TCFG 0x062 // Beacon Time Configuration
-#define RATR0 0x320 // Rate Adaptive Table register1
-#endif
-// TODO: Remove unused register, We must declare backward compatiable
-//Undefined register set in 8192S. 0x320/350 DW is useless
-#define UnusedRegister 0x0320
-#define PSR UnusedRegister // Page Select Register
-//Security Related
-#define DCAM UnusedRegister // Debug CAM Interface
-//PHY Configuration related
-#define BBAddr UnusedRegister // Phy register address register
-#define PhyDataR UnusedRegister // Phy register data read
-#define UFWP UnusedRegister
-
-
-//============================================================================
-// 8192S Regsiter Bit and Content definition
-//============================================================================
-
-//
-// 1. System Configuration Registers (Offset: 0x0000 - 0x003F)
-//
-//----------------------------------------------------------------------------
-// 8192S SYS_ISO_CTRL bits (Offset 0x0, 16bit)
-//----------------------------------------------------------------------------
-#define ISO_MD2PP BIT0 // MACTOP/BB/PCIe Digital to Power On.
-#define ISO_PA2PCIE BIT3 // PCIe Analog 1.2V to PCIe 3.3V
-#define ISO_PLL2MD BIT4 // AFE PLL to MACTOP/BB/PCIe Digital.
-#define ISO_PWC_DV2RP BIT11 // Digital Vdd to Retention Path
-#define ISO_PWC_RV2RP BIT12 // LPLDOR12 to Retenrion Path, 1: isolation, 0: attach.
-
-//----------------------------------------------------------------------------
-// 8192S SYS_FUNC_EN bits (Offset 0x2, 16bit)
-//----------------------------------------------------------------------------
-#define FEN_MREGEN BIT15 // MAC I/O Registers Enable.
-#define FEN_DCORE BIT11 // Enable Core Digital.
-#define FEN_CPUEN BIT10 // Enable CPU Core Digital.
-// 8192S PMC_FSM bits (Offset 0x4, 32bit)
-//----------------------------------------------------------------------------
-#define PAD_HWPD_IDN BIT22 // HWPDN PAD status Indicator
-
-//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-// 8192S SYS_CLKR bits (Offset 0x8, 16bit)
-//----------------------------------------------------------------------------
-#define SYS_CLKSEL_80M BIT0 // System Clock 80MHz
-#define SYS_PS_CLKSEL BIT1 //System power save clock select.
-#define SYS_CPU_CLKSEL BIT2 // System Clock select, 1: AFE source, 0: System clock(L-Bus)
-#define SYS_MAC_CLK_EN BIT11 // MAC Clock Enable.
-#define SYS_SWHW_SEL BIT14 // Load done, control path seitch.
-#define SYS_FWHW_SEL BIT15 // Sleep exit, control path swith.
-
-
-//----------------------------------------------------------------------------
-// 8192S Cmd9346CR bits (Offset 0xA, 16bit)
-//----------------------------------------------------------------------------
-#define CmdEEPROM_En BIT5 // EEPROM enable when set 1
-#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346
-#define Cmd9346CR_9356SEL BIT4
-#define AutoLoadEEPROM (CmdEEPROM_En|CmdEERPOMSEL)
-#define AutoLoadEFUSE CmdEEPROM_En
-
-
-//----------------------------------------------------------------------------
-// 8192S AFE_MISC bits AFE Misc (Offset 0x10, 8bits)
-//----------------------------------------------------------------------------
-#define AFE_MBEN BIT1 // Enable AFE Macro Block's Mbias.
-#define AFE_BGEN BIT0 // Enable AFE Macro Block's Bandgap.
-
-//----------------------------------------------------------------------------
-// 8192S SPS1_CTRL bits (Offset 0x18-1E, 56bits)
-//----------------------------------------------------------------------------
-#define SPS1_SWEN BIT1 // Enable vsps18 SW Macro Block.
-#define SPS1_LDEN BIT0 // Enable VSPS12 LDO Macro block.
-
-//----------------------------------------------------------------------------
-// 8192S RF_CTRL bits (Offset 0x1F, 8bits)
-//----------------------------------------------------------------------------
-#define RF_EN BIT0 // Enable RF module.
-#define RF_RSTB BIT1 // Reset RF module.
-#define RF_SDMRSTB BIT2 // Reset RF SDM module.
-
-//----------------------------------------------------------------------------
-// 8192S LDOA15_CTRL bits (Offset 0x20, 8bits)
-//----------------------------------------------------------------------------
-#define LDA15_EN BIT0 // Enable LDOA15 Macro Block
-
-//----------------------------------------------------------------------------
-// 8192S LDOV12D_CTRL bits (Offset 0x21, 8bits)
-//----------------------------------------------------------------------------
-#define LDV12_EN BIT0 // Enable LDOVD12 Macro Block
-#define LDV12_SDBY BIT1 // LDOVD12 standby mode
-
-//----------------------------------------------------------------------------
-// 8192S AFE_XTAL_CTRL bits AFE Crystal Control. (Offset 0x26,16bits)
-//----------------------------------------------------------------------------
-#define XTAL_GATE_AFE BIT10
-// Gated Control. 1: AFE Clock source gated, 0: Clock enable.
-
-//----------------------------------------------------------------------------
-// 8192S AFE_PLL_CTRL bits System Function Enable (Offset 0x28,64bits)
-//----------------------------------------------------------------------------
-#define APLL_EN BIT0 // Enable AFE PLL Macro Block.
-
-// Find which card bus type
-#define AFR_CardBEn BIT0
-#define AFR_CLKRUN_SEL BIT1
-#define AFR_FuncRegEn BIT2
-
-//
-// 2. Command Control Registers (Offset: 0x0040 - 0x004F)
-//
-//----------------------------------------------------------------------------
-// 8192S (CMD) command register bits (Offset 0x40, 16 bits)
-//----------------------------------------------------------------------------
-#define APSDOFF_STATUS BIT15 //
-#define APSDOFF BIT14 //
-#define BBRSTn BIT13 //Enable OFDM/CCK
-#define BB_GLB_RSTn BIT12 //Enable BB
-#define SCHEDULE_EN BIT10 //Enable MAC scheduler
-#define MACRXEN BIT9 //
-#define MACTXEN BIT8 //
-#define DDMA_EN BIT7 //FW off load function enable
-#define FW2HW_EN BIT6 //MAC every module reset as below
-#define RXDMA_EN BIT5 //
-#define TXDMA_EN BIT4 //
-#define HCI_RXDMA_EN BIT3 //
-#define HCI_TXDMA_EN BIT2 //
-
-//----------------------------------------------------------------------------
-// 8192S (TXPAUSE) transmission pause (Offset 0x42, 8 bits)
-//----------------------------------------------------------------------------
-#define StopHCCA BIT6
-#define StopHigh BIT5
-#define StopMgt BIT4
-#define StopVO BIT3
-#define StopVI BIT2
-#define StopBE BIT1
-#define StopBK BIT0
-
-//----------------------------------------------------------------------------
-// 8192S (LBKMD) LoopBack Mode Select (Offset 0x43, 8 bits)
-//----------------------------------------------------------------------------
-//
-// [3] no buffer, 1: no delay, 0: delay; [2] dmalbk, [1] no_txphy, [0] diglbk.
-// 0000: Normal
-// 1011: MAC loopback (involving CPU)
-// 0011: MAC Delay Loopback
-// 0001: PHY loopback (not yet implemented)
-// 0111: DMA loopback (only uses TxPktBuffer and DMA engine)
-// All other combinations are reserved.
-// Default: 0000b.
-//
-#define LBK_NORMAL 0x00
-#define LBK_MAC_LB (BIT0|BIT1|BIT3)
-#define LBK_MAC_DLB (BIT0|BIT1)
-#define LBK_DMA_LB (BIT0|BIT1|BIT2)
-
-//----------------------------------------------------------------------------
-// 8192S (TCR) transmission Configuration Register (Offset 0x44, 32 bits)
-//----------------------------------------------------------------------------
-#define TCP_OFDL_EN BIT25 //For CE packet conversion
-#define HWPC_TX_EN BIT24 //""
-#define TXDMAPRE2FULL BIT23 //TXDMA enable pre2full sync
-#define DISCW BIT20 //CW disable
-#define TCRICV BIT19 //Append ICV or not
-#define CfendForm BIT17 //AP mode
-#define TCRCRC BIT16 //Append CRC32
-#define FAKE_IMEM_EN BIT15 //
-#define TSFRST BIT9 //
-#define TSFEN BIT8 //
-// For TCR FW download ready --> write by FW Bit0-7 must all one
-#define FWALLRDY (BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6|BIT7)
-#define FWRDY BIT7
-#define BASECHG BIT6
-#define IMEM BIT5
-#define DMEM_CODE_DONE BIT4
-#define EXT_IMEM_CHK_RPT BIT3
-#define EXT_IMEM_CODE_DONE BIT2
-#define IMEM_CHK_RPT BIT1
-#define IMEM_CODE_DONE BIT0
-// Copy fomr 92SU definition
-#define IMEM_CODE_DONE BIT0
-#define IMEM_CHK_RPT BIT1
-#define EMEM_CODE_DONE BIT2
-#define EMEM_CHK_RPT BIT3
-#define DMEM_CODE_DONE BIT4
-#define IMEM_RDY BIT5
-#define BASECHG BIT6
-#define FWRDY BIT7
-#define LOAD_FW_READY (IMEM_CODE_DONE|IMEM_CHK_RPT|EMEM_CODE_DONE|\
- EMEM_CHK_RPT|DMEM_CODE_DONE|IMEM_RDY|BASECHG|\
- FWRDY)
-#define TCR_TSFEN BIT8 // TSF function on or off.
-#define TCR_TSFRST BIT9 // Reset TSF function to zero.
-#define TCR_FAKE_IMEM_EN BIT15
-#define TCR_CRC BIT16
-#define TCR_ICV BIT19 // Integrity Check Value.
-#define TCR_DISCW BIT20 // Disable Contention Windows Backoff.
-#define TCR_HWPC_TX_EN BIT24
-#define TCR_TCP_OFDL_EN BIT25
-#define TXDMA_INIT_VALUE (IMEM_CHK_RPT|EXT_IMEM_CHK_RPT)
-//----------------------------------------------------------------------------
-// 8192S (RCR) Receive Configuration Register (Offset 0x48, 32 bits)
-//----------------------------------------------------------------------------
-#define RCR_APPFCS BIT31 //WMAC append FCS after pauload
-#define RCR_DIS_ENC_2BYTE BIT30 //HW encrypt 2 or 1 byte mode
-#define RCR_DIS_AES_2BYTE BIT29 //
-#define RCR_HTC_LOC_CTRL BIT28 //MFC<--HTC=1 MFC-->HTC=0
-#define RCR_ENMBID BIT27 //Enable Multiple BssId.
-#define RCR_RX_TCPOFDL_EN BIT26 //
-#define RCR_APP_PHYST_RXFF BIT25 //
-#define RCR_APP_PHYST_STAFF BIT24 //
-#define RCR_CBSSID BIT23 //Accept BSSID match packet
-#define RCR_APWRMGT BIT22 //Accept power management packet
-#define RCR_ADD3 BIT21 //Accept address 3 match packet
-#define RCR_AMF BIT20 //Accept management type frame
-#define RCR_ACF BIT19 //Accept control type frame
-#define RCR_ADF BIT18 //Accept data type frame
-#define RCR_APP_MIC BIT17 //
-#define RCR_APP_ICV BIT16 //
-#define RCR_RXFTH BIT13 //Rx FIFO Threshold Bot 13 - 15
-#define RCR_AICV BIT12 //Accept ICV error packet
-#define RCR_RXDESC_LK_EN BIT11 //Accept to update rx desc length
-#define RCR_APP_BA_SSN BIT6 //Accept BA SSN
-#define RCR_ACRC32 BIT5 //Accept CRC32 error packet
-#define RCR_RXSHFT_EN BIT4 //Accept broadcast packet
-#define RCR_AB BIT3 //Accept broadcast packet
-#define RCR_AM BIT2 //Accept multicast packet
-#define RCR_APM BIT1 //Accept physical match packet
-#define RCR_AAP BIT0 //Accept all unicast packet
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
-
-#define RCR_ONLYERLPKT BIT31 // Early Receiving based on Packet Size.
-#define RCR_ENCS2 BIT30 // Enable Carrier Sense Detection Method 2
-#define RCR_ENCS1 BIT29 // Enable Carrier Sense Detection Method 1
-#define RCR_ACKTXBW (BIT24|BIT25) // TXBW Setting of ACK frames
-
-//----------------------------------------------------------------------------
-// 8192S (MSR) Media Status Register (Offset 0x4C, 8 bits)
-//----------------------------------------------------------------------------
-/*
-Network Type
-00: No link
-01: Link in ad hoc network
-10: Link in infrastructure network
-11: AP mode
-Default: 00b.
-*/
-#define MSR_NOLINK 0x00
-#define MSR_ADHOC 0x01
-#define MSR_INFRA 0x02
-#define MSR_AP 0x03
-
-//----------------------------------------------------------------------------
-// 8192S (SYSF_CFG) system Fucntion Config Reg (Offset 0x4D, 8 bits)
-//----------------------------------------------------------------------------
-#define ENUART BIT7
-#define ENJTAG BIT3
-#define BTMODE (BIT2|BIT1)
-#define ENBT BIT0
-
-//----------------------------------------------------------------------------
-// 8192S (MBIDCTRL) MBSSID Control Register (Offset 0x4F, 8 bits)
-//----------------------------------------------------------------------------
-#define ENMBID BIT7
-#define BCNUM (BIT6|BIT5|BIT4)
-
-//
-// 3. MACID Setting Registers (Offset: 0x0050 - 0x007F)
-//
-
-//
-// 4. Timing Control Registers (Offset: 0x0080 - 0x009F)
-//
-//----------------------------------------------------------------------------
-// 8192S (USTIME) US Time Tunning Register (Offset 0x8A, 16 bits)
-//----------------------------------------------------------------------------
-#define USTIME_EDCA 0xFF00
-#define USTIME_TSF 0x00FF
-
-//----------------------------------------------------------------------------
-// 8192S (SIFS_CCK/OFDM) US Time Tunning Register (Offset 0x8C/8E,16 bits)
-//----------------------------------------------------------------------------
-#define SIFS_TRX 0xFF00
-#define SIFS_CTX 0x00FF
-
-//----------------------------------------------------------------------------
-// 8192S (DRVERLYINT) Driver Early Interrupt Reg (Offset 0x98, 16bit)
-//----------------------------------------------------------------------------
-#define ENSWBCN BIT15
-#define DRVERLY_TU 0x0FF0
-#define DRVERLY_US 0x000F
-#define BCN_TCFG_CW_SHIFT 8
-#define BCN_TCFG_IFS 0
-
-//
-// 5. FIFO Control Registers (Offset: 0x00A0 - 0x015F)
-//
-
-//
-// 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF)
-//
-//----------------------------------------------------------------------------
-// 8192S Response Rate Set Register (offset 0x181, 24bits)
-//----------------------------------------------------------------------------
-#define RRSR_RSC_OFFSET 21
-#define RRSR_SHORT_OFFSET 23
-#define RRSR_RSC_BW_40M 0x600000
-#define RRSR_RSC_UPSUBCHNL 0x400000
-#define RRSR_RSC_LOWSUBCHNL 0x200000
-#define RRSR_SHORT 0x800000
-#define RRSR_1M BIT0
-#define RRSR_2M BIT1
-#define RRSR_5_5M BIT2
-#define RRSR_11M BIT3
-#define RRSR_6M BIT4
-#define RRSR_9M BIT5
-#define RRSR_12M BIT6
-#define RRSR_18M BIT7
-#define RRSR_24M BIT8
-#define RRSR_36M BIT9
-#define RRSR_48M BIT10
-#define RRSR_54M BIT11
-#define RRSR_MCS0 BIT12
-#define RRSR_MCS1 BIT13
-#define RRSR_MCS2 BIT14
-#define RRSR_MCS3 BIT15
-#define RRSR_MCS4 BIT16
-#define RRSR_MCS5 BIT17
-#define RRSR_MCS6 BIT18
-#define RRSR_MCS7 BIT19
-#define BRSR_AckShortPmb BIT23
-
-#define RRSR_RSC_UPSUBCHANL 0x200000
-// CCK ACK: use Short Preamble or not
-
-//----------------------------------------------------------------------------
-// 8192S Rate Definition
-//----------------------------------------------------------------------------
-//CCK
-#define RATR_1M 0x00000001
-#define RATR_2M 0x00000002
-#define RATR_55M 0x00000004
-#define RATR_11M 0x00000008
-//OFDM
-#define RATR_6M 0x00000010
-#define RATR_9M 0x00000020
-#define RATR_12M 0x00000040
-#define RATR_18M 0x00000080
-#define RATR_24M 0x00000100
-#define RATR_36M 0x00000200
-#define RATR_48M 0x00000400
-#define RATR_54M 0x00000800
-//MCS 1 Spatial Stream
-#define RATR_MCS0 0x00001000
-#define RATR_MCS1 0x00002000
-#define RATR_MCS2 0x00004000
-#define RATR_MCS3 0x00008000
-#define RATR_MCS4 0x00010000
-#define RATR_MCS5 0x00020000
-#define RATR_MCS6 0x00040000
-#define RATR_MCS7 0x00080000
-//MCS 2 Spatial Stream
-#define RATR_MCS8 0x00100000
-#define RATR_MCS9 0x00200000
-#define RATR_MCS10 0x00400000
-#define RATR_MCS11 0x00800000
-#define RATR_MCS12 0x01000000
-#define RATR_MCS13 0x02000000
-#define RATR_MCS14 0x04000000
-#define RATR_MCS15 0x08000000
-// ALL CCK Rate
-#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M
-#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\
- RATR_36M|RATR_48M|RATR_54M
-#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\
- RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7
-#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\
- RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
-
-//
-// 7. EDCA Setting Registers (Offset: 0x01D0 - 0x01FF)
-//
-//----------------------------------------------------------------------------
-// 8192S EDCA Setting (offset 0x1D0-1DF, 4DW VO/VI/BE/BK)
-//----------------------------------------------------------------------------
-#define AC_PARAM_TXOP_LIMIT_OFFSET 16
-#define AC_PARAM_ECW_MAX_OFFSET 12
-#define AC_PARAM_ECW_MIN_OFFSET 8
-#define AC_PARAM_AIFS_OFFSET 0
-
-//----------------------------------------------------------------------------
-// 8192S AcmHwCtrl bits (offset 0x1E7, 1 byte)
-//----------------------------------------------------------------------------
-#define AcmHw_HwEn BIT0
-#define AcmHw_BeqEn BIT1
-#define AcmHw_ViqEn BIT2
-#define AcmHw_VoqEn BIT3
-#define AcmHw_BeqStatus BIT4
-#define AcmHw_ViqStatus BIT5
-#define AcmHw_VoqStatus BIT6
-
-//----------------------------------------------------------------------------
-// 8192S Retry Limit (Offset 0x1F4, 16bit)
-//----------------------------------------------------------------------------
-#define RETRY_LIMIT_SHORT_SHIFT 8
-#define RETRY_LIMIT_LONG_SHIFT 0
-
-//
-// 8. WMAC, BA and CCX related Register. (Offset: 0x0200 - 0x023F)
-//
-//----------------------------------------------------------------------------
-// 8192S NAV_CTRL bits (Offset 0x200, 24bit)
-//----------------------------------------------------------------------------
-#define NAV_UPPER_EN BIT16
-#define NAV_UPPER 0xFF00
-#define NAV_RTSRST 0xFF
-//----------------------------------------------------------------------------
-// 8192S BW_OPMODE bits (Offset 0x203, 8bit)
-//----------------------------------------------------------------------------
-#define BW_OPMODE_20MHZ BIT2
-#define BW_OPMODE_5G BIT1
-#define BW_OPMODE_11J BIT0
-//----------------------------------------------------------------------------
-// 8192S BW_OPMODE bits (Offset 0x230, 4 Byte)
-//----------------------------------------------------------------------------
-#define RXERR_RPT_RST BIT27 // Write "one" to set the counter to zero.
-// RXERR_RPT_SEL
-#define RXERR_OFDM_PPDU 0
-#define RXERR_OFDM_FALSE_ALARM 1
-#define RXERR_OFDM_MPDU_OK 2
-#define RXERR_OFDM_MPDU_FAIL 3
-#define RXERR_CCK_PPDU 4
-#define RXERR_CCK_FALSE_ALARM 5
-#define RXERR_CCK_MPDU_OK 6
-#define RXERR_CCK_MPDU_FAIL 7
-#define RXERR_HT_PPDU 8
-#define RXERR_HT_FALSE_ALARM 9
-#define RXERR_HT_MPDU_TOTAL 10
-#define RXERR_HT_MPDU_OK 11
-#define RXERR_HT_MPDU_FAIL 12
-#define RXERR_RX_FULL_DROP 15
-
-//
-// 9. Security Control Registers (Offset: 0x0240 - 0x025F)
-//
-//----------------------------------------------------------------------------
-// 8192S RWCAM CAM Command Register (offset 0x240, 4 byte)
-//----------------------------------------------------------------------------
-#define CAM_CM_SecCAMPolling BIT31 //Security CAM Polling
-#define CAM_CM_SecCAMClr BIT30 //Clear all bits in CAM
-#define CAM_CM_SecCAMWE BIT16 //Security CAM enable
-#define CAM_ADDR 0xFF //CAM Address Offset
-
-//----------------------------------------------------------------------------
-// 8192S CAMDBG Debug CAM Register (offset 0x24C, 4 byte)
-//----------------------------------------------------------------------------
-#define Dbg_CAM_TXSecCAMInfo BIT31 //Retrieve lastest Tx Info
-#define Dbg_CAM_SecKeyFound BIT30 //Security KEY Found
-
-
-//----------------------------------------------------------------------------
-// 8192S SECR Security Configuration Register (offset 0x250, 1 byte)
-//----------------------------------------------------------------------------
-#define SCR_TxUseDK BIT0 //Force Tx Use Default Key
-#define SCR_RxUseDK BIT1 //Force Rx Use Default Key
-#define SCR_TxEncEnable BIT2 //Enable Tx Encryption
-#define SCR_RxDecEnable BIT3 //Enable Rx Decryption
-#define SCR_SKByA2 BIT4 //Search kEY BY A2
-#define SCR_NoSKMC BIT5 //No Key Search Multicast
-//----------------------------------------------------------------------------
-// 8192S CAM Config Setting (offset 0x250, 1 byte)
-//----------------------------------------------------------------------------
-#define CAM_VALID BIT15
-#define CAM_NOTVALID 0x0000
-#define CAM_USEDK BIT5
-
-#define CAM_NONE 0x0
-#define CAM_WEP40 0x01
-#define CAM_TKIP 0x02
-#define CAM_AES 0x04
-#define CAM_WEP104 0x05
-
-#define TOTAL_CAM_ENTRY 32
-
-#define CAM_CONFIG_USEDK TRUE
-#define CAM_CONFIG_NO_USEDK FALSE
-
-#define CAM_WRITE BIT16
-#define CAM_READ 0x00000000
-#define CAM_POLLINIG BIT31
-
-#define SCR_UseDK 0x01
-#define SCR_TxSecEnable 0x02
-#define SCR_RxSecEnable 0x04
-
-//
-// 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF)
-//
-#define WOW_PMEN BIT0 // Power management Enable.
-#define WOW_WOMEN BIT1 // WoW function on or off.
-#define WOW_MAGIC BIT2 // Magic packet
-#define WOW_UWF BIT3 // Unicast Wakeup frame.
-
-//
-// 11. General Purpose Registers (Offset: 0x02E0 - 0x02FF)
-// 8192S GPIO Config Setting (offset 0x2F1, 1 byte)
-//----------------------------------------------------------------------------
-#define GPIOMUX_EN BIT3 // When this bit is set to "1", GPIO PINs will switch to MAC GPIO Function
-#define GPIOSEL_GPIO 0 // UART or JTAG or pure GPIO
-#define GPIOSEL_PHYDBG 1 // PHYDBG
-#define GPIOSEL_BT 2 // BT_coex
-#define GPIOSEL_WLANDBG 3 // WLANDBG
-#define GPIOSEL_GPIO_MASK ~(BIT0|BIT1)
-
-//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-// PHY REG Access Report Register definition
-//----------------------------------------------------------------------------
-#define HST_RDBUSY BIT0
-#define CPU_WTBUSY BIT1
-
-//
-// 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F)
-//
-//----------------------------------------------------------------------------
-// 8190 IMR/ISR bits (offset 0xfd, 8bits)
-//----------------------------------------------------------------------------
-#define IMR8190_DISABLED 0x0
-
-// IMR DW1 Bit 0-31
-#define IMR_CPUERR BIT5 // CPU error interrupt
-#define IMR_ATIMEND BIT4 // ATIM Window End Interrupt
-#define IMR_TBDOK BIT3 // Transmit Beacon OK Interrupt
-#define IMR_TBDER BIT2 // Transmit Beacon Error Interrupt
-#define IMR_BCNDMAINT8 BIT1 // Beacon DMA Interrupt 8
-#define IMR_BCNDMAINT7 BIT0 // Beacon DMA Interrupt 7
-// IMR DW0 Bit 0-31
-
-#define IMR_BCNDMAINT6 BIT31 // Beacon DMA Interrupt 6
-#define IMR_BCNDMAINT5 BIT30 // Beacon DMA Interrupt 5
-#define IMR_BCNDMAINT4 BIT29 // Beacon DMA Interrupt 4
-#define IMR_BCNDMAINT3 BIT28 // Beacon DMA Interrupt 3
-#define IMR_BCNDMAINT2 BIT27 // Beacon DMA Interrupt 2
-#define IMR_BCNDMAINT1 BIT26 // Beacon DMA Interrupt 1
-#define IMR_BCNDOK8 BIT25 // Beacon Queue DMA OK Interrup 8
-#define IMR_BCNDOK7 BIT24 // Beacon Queue DMA OK Interrup 7
-#define IMR_BCNDOK6 BIT23 // Beacon Queue DMA OK Interrup 6
-#define IMR_BCNDOK5 BIT22 // Beacon Queue DMA OK Interrup 5
-#define IMR_BCNDOK4 BIT21 // Beacon Queue DMA OK Interrup 4
-#define IMR_BCNDOK3 BIT20 // Beacon Queue DMA OK Interrup 3
-#define IMR_BCNDOK2 BIT19 // Beacon Queue DMA OK Interrup 2
-#define IMR_BCNDOK1 BIT18 // Beacon Queue DMA OK Interrup 1
-#define IMR_TIMEOUT2 BIT17 // Timeout interrupt 2
-#define IMR_TIMEOUT1 BIT16 // Timeout interrupt 1
-#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow
-#define IMR_PSTIMEOUT BIT14 // Power save time out interrupt
-#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0
-#define IMR_RXFOVW BIT12 // Receive FIFO Overflow
-#define IMR_RDU BIT11 // Receive Descriptor Unavailable
-#define IMR_RXCMDOK BIT10 // Receive Command Packet OK
-#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup
-#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt
-#define IMR_COMDOK BIT7 // Command Queue DMA OK Interrupt
-#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt
-#define IMR_HCCADOK BIT5 // HCCA Queue DMA OK Interrupt
-#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt
-#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt
-#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt
-#define IMR_VODOK BIT1 // AC_VO DMA Interrupt
-#define IMR_ROK BIT0 // Receive DMA OK Interrupt
-
-//
-// 13. Test Mode and Debug Control Registers (Offset: 0x0310 - 0x034F)
-//
-
-//
-// 14. PCIE config register (Offset 0x500-)
-//
-//----------------------------------------------------------------------------
-// 8190 TPPool bits (offset 0xd9, 2 byte)
-//----------------------------------------------------------------------------
-#define TPPoll_BKQ BIT0 // BK queue polling
-#define TPPoll_BEQ BIT1 // BE queue polling
-#define TPPoll_VIQ BIT2 // VI queue polling
-#define TPPoll_VOQ BIT3 // VO queue polling
-#define TPPoll_BQ BIT4 // Beacon queue polling
-#define TPPoll_CQ BIT5 // Command queue polling
-#define TPPoll_MQ BIT6 // Management queue polling
-#define TPPoll_HQ BIT7 // High queue polling
-#define TPPoll_HCCAQ BIT8 // HCCA queue polling
-#define TPPoll_StopBK BIT9 // Stop BK queue
-#define TPPoll_StopBE BIT10 // Stop BE queue
-#define TPPoll_StopVI BIT11 // Stop VI queue
-#define TPPoll_StopVO BIT12 // Stop VO queue
-#define TPPoll_StopMgt BIT13 // Stop Mgnt queue
-#define TPPoll_StopHigh BIT14 // Stop High queue
-#define TPPoll_StopHCCA BIT15 // Stop HCCA queue
-#define TPPoll_SHIFT 8 // Queue ID mapping
-
-//----------------------------------------------------------------------------
-// 8192S PCIF (Offset 0x500, 32bit)
-//----------------------------------------------------------------------------
-#define MXDMA2_16bytes 0x000
-#define MXDMA2_32bytes 0x001
-#define MXDMA2_64bytes 0x010
-#define MXDMA2_128bytes 0x011
-#define MXDMA2_256bytes 0x100
-#define MXDMA2_512bytes 0x101
-#define MXDMA2_1024bytes 0x110
-#define MXDMA2_NoLimit 0x7
-
-#define MULRW_SHIFT 3
-#define MXDMA2_RX_SHIFT 4
-#define MXDMA2_TX_SHIFT 0
-
-//----------------------------------------------------------------------------
-// 8190 CCX_COMMAND_REG Setting (offset 0x25A, 1 byte)
-//----------------------------------------------------------------------------
-#define CCX_CMD_CLM_ENABLE BIT0 // Enable Channel Load
-#define CCX_CMD_NHM_ENABLE BIT1 // Enable Noise Histogram
-#define CCX_CMD_FUNCTION_ENABLE BIT8
-// CCX function (Channel Load/RPI/Noise Histogram).
-#define CCX_CMD_IGNORE_CCA BIT9
-// Treat CCA period as IDLE time for NHM.
-#define CCX_CMD_IGNORE_TXON BIT10
-// Treat TXON period as IDLE time for NHM.
-#define CCX_CLM_RESULT_READY BIT16
-// 1: Indicate the result of Channel Load is ready.
-#define CCX_NHM_RESULT_READY BIT16
-// 1: Indicate the result of Noise histogram is ready.
-#define CCX_CMD_RESET 0x0
-// Clear all the result of CCX measurement and disable the CCX function.
-
-
-//----------------------------------------------------------------------------
-// 8192S EFUSE
-//----------------------------------------------------------------------------
-//#define HWSET_MAX_SIZE_92S 128
-
-
-//----------------------------------------------------------------------------
-// 8192S EEPROM/EFUSE share register definition.
-//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-// 8192S EEROM and Compatible E-Fuse definition. Added by Roger, 2008.10.21.
-//----------------------------------------------------------------------------
-#define RTL8190_EEPROM_ID 0x8129
-#define EEPROM_HPON 0x02 // LDO settings.
-#define EEPROM_VID 0x08 // USB Vendor ID.
-#define EEPROM_PID 0x0A // USB Product ID.
-#define EEPROM_USB_OPTIONAL 0x0C // For optional function.
-#define EEPROM_USB_PHY_PARA1 0x0D // For fine tune USB PHY.
-#define EEPROM_NODE_ADDRESS_BYTE_0 0x12 // MAC address.
-#define EEPROM_TxPowerDiff 0x1F
-
-#define EEPROM_Version 0x50
-#define EEPROM_ChannelPlan 0x51 // Map of supported channels.
-#define EEPROM_CustomID 0x52
-#define EEPROM_SubCustomID 0x53 // Reserved for customer use.
-
-
- // <Roger_Notes> The followin are for different version of EEPROM contents purpose. 2008.11.22.
-#define EEPROM_BoardType 0x54 //0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU
-#define EEPROM_TxPwIndex 0x55 //0x55-0x66, Tx Power index.
-#define EEPROM_PwDiff 0x67 // Difference of gain index between legacy and high throughput OFDM.
-#define EEPROM_ThermalMeter 0x68 // Thermal meter default value.
-#define EEPROM_CrystalCap 0x69 // Crystal Cap.
-#define EEPROM_TxPowerBase 0x6a // Tx Power of serving station.
-#define EEPROM_TSSI_A 0x6b //TSSI value of path A.
-#define EEPROM_TSSI_B 0x6c //TSSI value of path B.
-#define EEPROM_TxPwTkMode 0x6d //Tx Power tracking mode.
-//#define EEPROM_Reserved 0x6e //0x6e-0x7f, reserved.
-
-// 2009/02/09 Cosa Add for SD3 requirement
-#define EEPROM_TX_PWR_HT20_DIFF 0x6e// HT20 Tx Power Index Difference
-#define DEFAULT_HT20_TXPWR_DIFF 2 // HT20<->40 default Tx Power Index Difference
-#define EEPROM_TX_PWR_OFDM_DIFF 0x71// OFDM Tx Power Index Difference
-#define EEPROM_TX_PWR_BAND_EDGE 0x73// TX Power offset at band-edge channel
-#define TX_PWR_BAND_EDGE_CHK 0x79// Check if band-edge scheme is enabled
-#define EEPROM_Default_LegacyHTTxPowerDiff 0x3
-#define EEPROM_USB_Default_OPTIONAL_FUNC 0x8
-#define EEPROM_USB_Default_PHY_PARAM 0x0
-#define EEPROM_Default_TSSI 0x0
-#define EEPROM_Default_TxPwrTkMode 0x0
-#define EEPROM_Default_TxPowerDiff 0x0
-#define EEPROM_Default_TxPowerBase 0x0
-#define EEPROM_Default_ThermalMeter 0x7
-#define EEPROM_Default_PwDiff 0x4
-#define EEPROM_Default_CrystalCap 0x5
-#define EEPROM_Default_TxPower 0x1010
-#define EEPROM_Default_BoardType 0x02 // Default: 2X2, RTL8192SU(QFPN68)
-#define EEPROM_Default_HT2T_TxPwr 0x10
-#define EEPROM_USB_SN BIT0
-#define EEPROM_USB_REMOTE_WAKEUP BIT1
-#define EEPROM_USB_DEVICE_PWR BIT2
-#define EEPROM_EP_NUMBER (BIT3|BIT4)
-
-#define EEPROM_CHANNEL_PLAN_FCC 0x0
-#define EEPROM_CHANNEL_PLAN_IC 0x1
-#define EEPROM_CHANNEL_PLAN_ETSI 0x2
-#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
-#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
-#define EEPROM_CHANNEL_PLAN_MKK 0x5
-#define EEPROM_CHANNEL_PLAN_MKK1 0x6
-#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
-#define EEPROM_CHANNEL_PLAN_TELEC 0x8
-#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
-#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
-#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
-#define EEPROM_CID_DEFAULT 0x0
-#define EEPROM_CID_ALPHA 0x1
-#define EEPROM_CID_Senao 0x3
-#define EEPROM_CID_CAMEO 0X8
-#define EEPROM_CID_SITECOM 0x9
-#define EEPROM_CID_COREGA 0xB
-#define EEPROM_CID_EDIMAX_BELKIN 0xC
-#define EEPROM_CID_SERCOMM_BELKIN 0xE
-#define EEPROM_CID_CAMEO1 0xF
-#define EEPROM_CID_WHQL 0xFE
-#define EEPROM_CID_NetCore 0x5
-
-
-//-----------------------------------------------------------------
-// 0x2c0 FW Command Control register definition, added by Roger, 2008.11.27.
-//-----------------------------------------------------------------
-#define FW_DIG_DISABLE 0xfd00cc00
-#define FW_DIG_ENABLE 0xfd000000
-#define FW_DIG_HALT 0xfd000001
-#define FW_DIG_RESUME 0xfd000002
-#define FW_HIGH_PWR_DISABLE 0xfd000008
-#define FW_HIGH_PWR_ENABLE 0xfd000009
-#define FW_TXPWR_TRACK_ENABLE 0xfd000017
-#define FW_TXPWR_TRACK_DISABLE 0xfd000018
-#define FW_TXPWR_TRACK_THERMAL 0xfd000019
-#define FW_RA_INIT 0xfd000026
-#define FW_RA_IOT_BG_COMB 0xfd000030
-#define FW_RA_IOT_N_COMB 0xfd000031
-#define FW_RA_REFRESH 0xfd0000a0
-#define FW_RA_DISABLE 0xfd0000a4
-#define FW_RA_ACTIVE 0xfd0000a6
-#define FW_RA_DISABLE_RSSI_MASK 0xfd0000ac
-#define FW_RA_ENABLE_RSSI_MASK 0xfd0000ad
-#define FW_RA_RESET 0xfd0000af
-#define FW_DM_DISABLE 0xfd00aa00
-#define FW_IQK_ENABLE 0xf0000020
-#define FW_IQK_SUCCESS 0x0000dddd
-#define FW_IQK_FAIL 0x0000ffff
-#define FW_OP_FAILURE 0xffffffff
-#define FW_TX_FEEDBACK_NONE 0xfb000000
-#define FW_TX_FEEDBACK_DTM_ENABLE (FW_TX_FEEDBACK_NONE | 0x1)
-#define FW_TX_FEEDBACK_CCX_ENABLE (FW_TX_FEEDBACK_NONE | 0x2)
-#define FW_BB_RESET_ENABLE 0xff00000d
-#define FW_BB_RESET_DISABLE 0xff00000e
-#define FW_LPS_ENTER 0xfe000010
-#define FW_LPS_LEAVE 0xfe000011
-#define FW_INDIRECT_READ 0xf2000000
-#define FW_INDIRECT_WRITE 0xf2000001
-#define FW_TXANT_SWITCH_ENABLE 0xfd000023
-#define FW_TXANT_SWITCH_DISABLE 0xfd000024
-//
-//--------------92SU require delete or move to other place later
-//
-
-
-
-//
-//
-// 2008/08/06 MH For share the same 92S source/header files, we copy some
-// definition to pass 92SU compiler. But we must delete thm later.
-//
-//
-
-//============================================================================
-// 819xUsb Regsiter offset definition
-//============================================================================
-
-//2 define it temp!!!
-#define RFPC 0x5F // Rx FIFO Packet Count
-#define RCR_9356SEL BIT6
-#define TCR_LRL_OFFSET 0
-#define TCR_SRL_OFFSET 8
-#define TCR_MXDMA_OFFSET 21
-#define TCR_MXDMA_2048 7
-#define TCR_SAT BIT24 // Enable Rate depedent ack timeout timer
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
-#define RCR_OnlyErlPkt BIT31 // Rx Early mode is performed for packet size greater than 1536
-#define CWR 0xDC // Contention window register
-#define RetryCTR 0xDE // Retry Count register
-
-
-// For backward compatible for 9xUSB
-#define LED1Cfg UnusedRegister // LED1 Configuration Register
-#define LED0Cfg UnusedRegister // LED0 Configuration Register
-#define GPI UnusedRegister // LED0 Configuration Register
-#define BRSR UnusedRegister // LED0 Configuration Register
-#define CPU_GEN UnusedRegister // LED0 Configuration Register
-#define SIFS UnusedRegister // LED0 Configuration Register
-
-//----------------------------------------------------------------------------
-// 8190 CPU General Register (offset 0x100, 4 byte)
-//----------------------------------------------------------------------------
-//#define CPU_CCK_LOOPBACK 0x00030000
-#define CPU_GEN_SYSTEM_RESET 0x00000001
-//#define CPU_GEN_FIRMWARE_RESET 0x00000008
-//#define CPU_GEN_BOOT_RDY 0x00000010
-//#define CPU_GEN_FIRM_RDY 0x00000020
-//#define CPU_GEN_PUT_CODE_OK 0x00000080
-//#define CPU_GEN_BB_RST 0x00000100
-//#define CPU_GEN_PWR_STB_CPU 0x00000004
-//#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
-//#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1
-
-//----------------------------------------------------------------------------
-// 8192S EEROM
-//----------------------------------------------------------------------------
-
-//#define RTL8190_EEPROM_ID 0x8129
-//#define EEPROM_VID 0x08
-//#define EEPROM_PID 0x0A
-//#define EEPROM_USB_OPTIONAL 0x0C
-//#define EEPROM_NODE_ADDRESS_BYTE_0 0x12
-//
-//#define EEPROM_TxPowerDiff 0x1F
-//#define EEPROM_ThermalMeter 0x20
-//#define EEPROM_PwDiff 0x21 //0x21
-//#define EEPROM_CrystalCap 0x22 //0x22
-//
-//#define EEPROM_TxPwIndex_CCK 0x23 //0x23
-//#define EEPROM_TxPwIndex_OFDM_24G 0x24 //0x24~0x26
-#define EEPROM_TxPwIndex_CCK_V1 0x29 //0x29~0x2B
-#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C //0x2C~0x2E
-#define EEPROM_TxPwIndex_Ver 0x27 //0x27
-//
-//#define EEPROM_Default_TxPowerDiff 0x0
-//#define EEPROM_Default_ThermalMeter 0x7
-//#define EEPROM_Default_PwDiff 0x4
-//#define EEPROM_Default_CrystalCap 0x5
-//#define EEPROM_Default_TxPower 0x1010
-//#define EEPROM_Customer_ID 0x7B //0x7B:CustomerID
-//#define EEPROM_Version 0x50 // 0x50
-//#define EEPROM_CustomID 0x52
-//#define EEPROM_ChannelPlan 0x7c //0x7C
-//#define EEPROM_IC_VER 0x7d //0x7D
-//#define EEPROM_CRC 0x7e //0x7E~0x7F
-//
-//
-//#define EEPROM_CID_DEFAULT 0x0
-//#define EEPROM_CID_CAMEO 0x1
-//#define EEPROM_CID_RUNTOP 0x2
-//#define EEPROM_CID_Senao 0x3
-//#define EEPROM_CID_TOSHIBA 0x4 // Toshiba setting, Merge by Jacken, 2008/01/31
-//#define EEPROM_CID_NetCore 0x5
-
-
-//
-//--------------92SU require delete or move to other place later
-//
-
-//============================================================
-// CCX Related Register
-//============================================================
-#define CCX_COMMAND_REG 0x890
-// CCX Measurement Command Register. 4 Bytes.
-// Bit[0]: R_CLM_En, 1=enable, 0=disable. Enable or disable "Channel Load
-// Measurement (CLM)".
-// Bit[1]: R_NHM_En, 1=enable, 0=disable. Enable or disalbe "Noise Histogram
-// Measurement (NHM)".
-// Bit[2~7]: Reserved
-// Bit[8]: R_CCX_En: 1=enable, 0=disable. Enable or disable CCX function.
-// Note: After clearing this bit, all the result of all NHM_Result and CLM_
-// Result are cleared concurrently.
-// Bit[9]: R_Ignore_CCA: 1=enable, 0=disable. Enable means that treat CCA
-// period as idle time for NHM.
-// Bit[10]: R_Ignore_TXON: 1=enable, 0=disable. Enable means that treat TXON
-// period as idle time for NHM.
-// Bit[11~31]: Reserved.
-#define CLM_PERIOD_REG 0x894
-// CCX Measurement Period Register, in unit of 4us. 2 Bytes.
-#define NHM_PERIOD_REG 0x896
-// Noise Histogram Measurement Period Register, in unit of 4us. 2Bytes.
-#define NHM_THRESHOLD0 0x898 // Noise Histogram Meashorement0
-#define NHM_THRESHOLD1 0x899 // Noise Histogram Meashorement1
-#define NHM_THRESHOLD2 0x89A // Noise Histogram Meashorement2
-#define NHM_THRESHOLD3 0x89B // Noise Histogram Meashorement3
-#define NHM_THRESHOLD4 0x89C // Noise Histogram Meashorement4
-#define NHM_THRESHOLD5 0x89D // Noise Histogram Meashorement5
-#define NHM_THRESHOLD6 0x89E // Noise Histogram Meashorement6
-#define CLM_RESULT_REG 0x8D0
-// Channel Load result register. 4 Bytes.
-// Bit[0~15]: Total measured duration of CLM. The CCA busy fraction is caculate
-// by CLM_RESULT_REG/CLM_PERIOD_REG.
-// Bit[16]: Indicate the CLM result is ready.
-// Bit[17~31]: Reserved.
-#define NHM_RESULT_REG 0x8D4
-// Noise Histogram result register. 4 Bytes.
-// Bit[0~15]: Total measured duration of NHM. If R_Ignore_CCA=1 or
-// R_Ignore_TXON=1, this value will be less than NHM_PERIOD_REG.
-// Bit[16]: Indicate the NHM result is ready.
-// Bit[17~31]: Reserved.
-#define NHM_RPI_COUNTER0 0x8D8
-// NHM RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
-#define NHM_RPI_COUNTER1 0x8D9
-// NHM RPI counter1, the fraction of signal stren in NHM_THRESH0, NHM_THRESH1
-#define NHM_RPI_COUNTER2 0x8DA
-// NHM RPI counter2, the fraction of signal stren in NHM_THRESH2, NHM_THRESH3
-#define NHM_RPI_COUNTER3 0x8DB
-// NHM RPI counter3, the fraction of signal stren in NHM_THRESH4, NHM_THRESH5
-#define NHM_RPI_COUNTER4 0x8DC
-// NHM RPI counter4, the fraction of signal stren in NHM_THRESH6, NHM_THRESH7
-#define NHM_RPI_COUNTER5 0x8DD
-// NHM RPI counter5, the fraction of signal stren in NHM_THRESH8, NHM_THRESH9
-#define NHM_RPI_COUNTER6 0x8DE
-// NHM RPI counter6, the fraction of signal stren in NHM_THRESH10, NHM_THRESH11
-#define NHM_RPI_COUNTER7 0x8DF
-// NHM RPI counter7, the fraction of signal stren in NHM_THRESH12, NHM_THRESH13
-
-#define HAL_RETRY_LIMIT_INFRA 48
-#define HAL_RETRY_LIMIT_AP_ADHOC 7
-
-// HW Readio OFF switch (GPIO BIT)
-#define HAL_8192S_HW_GPIO_OFF_BIT BIT3
-#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7
-#define HAL_8192S_HW_GPIO_WPS_BIT BIT4
-
-#endif
diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c
deleted file mode 100644
index a5fc2d1cb062..000000000000
--- a/drivers/staging/rtl8192su/r8192S_phy.c
+++ /dev/null
@@ -1,3634 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "r8192U.h"
-#include "r8192U_dm.h"
-#include "r8192S_rtl6052.h"
-
-#include "r8192S_hw.h"
-#include "r8192S_phy.h"
-#include "r8192S_phyreg.h"
-#include "r8192SU_HWImg.h"
-
-#include "ieee80211/dot11d.h"
-
-/* Channel switch:The size of command tables for switch channel*/
-#define MAX_PRECMD_CNT 16
-#define MAX_RFDEPENDCMD_CNT 16
-#define MAX_POSTCMD_CNT 16
-#define MAX_DOZE_WAITING_TIMES_9x 64
-
-static u32
-phy_CalculateBitShift(u32 BitMask);
-static RT_STATUS
-phy_ConfigMACWithHeaderFile(struct net_device* dev);
-static void
-phy_InitBBRFRegisterDefinition(struct net_device* dev);
-static RT_STATUS
-phy_BB8192S_Config_ParaFile(struct net_device* dev);
-static RT_STATUS
-phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType);
-static bool
-phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE eRFPowerState);
-void
-SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
-void
-SetBWModeCallback8192SUsbWorkItem(struct net_device *dev);
-void
-SwChnlCallback8192SUsbWorkItem(struct net_device *dev );
-static void
-phy_FinishSwChnlNow(struct net_device* dev,u8 channel);
-static bool
-phy_SwChnlStepByStep(
- struct net_device* dev,
- u8 channel,
- u8 *stage,
- u8 *step,
- u32 *delay
- );
-static RT_STATUS
-phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType);
-static long phy_TxPwrIdxToDbm( struct net_device* dev, WIRELESS_MODE WirelessMode, u8 TxPwrIdx);
-static u8 phy_DbmToTxPwrIdx( struct net_device* dev, WIRELESS_MODE WirelessMode, long PowerInDbm);
-void phy_SetFwCmdIOCallback(struct net_device* dev);
-
-//
-// Description:
-// Base Band read by 4181 to make sure that operation could be done in unlimited cycle.
-//
-// Assumption:
-// - Only use on RTL8192S USB interface.
-// - PASSIVE LEVEL
-//
-//use in phy only
-u32 phy_QueryUsbBBReg(struct net_device* dev, u32 RegAddr)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 ReturnValue = 0xffffffff;
- u8 PollingCnt = 50;
- u8 BBWaitCounter = 0;
-
-
- //
- // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
- // We have to make sure that previous BB I/O has been done.
- // 2008.08.20.
- //
- while(priv->bChangeBBInProgress)
- {
- BBWaitCounter ++;
- RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): Wait 1 ms (%d times)...\n", BBWaitCounter);
- msleep(1); // 1 ms
-
- // Wait too long, return FALSE to avoid to be stuck here.
- if((BBWaitCounter > 100) )
- {
- RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): (%d) Wait too logn to query BB!!\n", BBWaitCounter);
- return ReturnValue;
- }
- }
-
- priv->bChangeBBInProgress = true;
-
- read_nic_dword(dev, RegAddr);
-
- do
- {// Make sure that access could be done.
- if((read_nic_byte(dev, PHY_REG)&HST_RDBUSY) == 0)
- break;
- }while( --PollingCnt );
-
- if(PollingCnt == 0)
- {
- RT_TRACE(COMP_RF, "Fail!!!phy_QueryUsbBBReg(): RegAddr(%#x) = %#x\n", RegAddr, ReturnValue);
- }
- else
- {
- // Data FW read back.
- ReturnValue = read_nic_dword(dev, PHY_REG_DATA);
- RT_TRACE(COMP_RF, "phy_QueryUsbBBReg(): RegAddr(%#x) = %#x, PollingCnt(%d)\n", RegAddr, ReturnValue, PollingCnt);
- }
-
- priv->bChangeBBInProgress = false;
-
- return ReturnValue;
-}
-
-
-
-//
-// Description:
-// Base Band wrote by 4181 to make sure that operation could be done in unlimited cycle.
-//
-// Assumption:
-// - Only use on RTL8192S USB interface.
-// - PASSIVE LEVEL
-//use in phy only
-void
-phy_SetUsbBBReg(struct net_device* dev,u32 RegAddr,u32 Data)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 BBWaitCounter = 0;
-
- RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): RegAddr(%#x) <= %#x\n", RegAddr, Data);
-
- //
- // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
- // We have to make sure that previous BB I/O has been done.
- // 2008.08.20.
- //
- while(priv->bChangeBBInProgress)
- {
- BBWaitCounter ++;
- RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): Wait 1 ms (%d times)...\n", BBWaitCounter);
- msleep(1); // 1 ms
-
- if((BBWaitCounter > 100))// || RT_USB_CANNOT_IO(Adapter))
- {
- RT_TRACE(COMP_RF, "phy_SetUsbBBReg(): (%d) Wait too logn to query BB!!\n", BBWaitCounter);
- return;
- }
- }
-
- priv->bChangeBBInProgress = true;
- write_nic_dword(dev, RegAddr, Data);
-
- priv->bChangeBBInProgress = false;
-}
-
-
-
-//
-// Description:
-// RF read by 4181 to make sure that operation could be done in unlimited cycle.
-//
-// Assumption:
-// - Only use on RTL8192S USB interface.
-// - PASSIVE LEVEL
-// - RT_RF_OPERATE_SPINLOCK is acquired and keep on holding to the end.FIXLZM
-//
-// Created by Roger, 2008.09.06.
-//
-//use in phy only
-u32 phy_QueryUsbRFReg( struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 ReturnValue = 0;
- u8 PollingCnt = 50;
- u8 RFWaitCounter = 0;
-
-
- //
- // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
- // We have to make sure that previous RF I/O has been done.
- // 2008.08.20.
- //
- while(priv->bChangeRFInProgress)
- {
- down(&priv->rf_sem);
-
- RFWaitCounter ++;
- RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): Wait 1 ms (%d times)...\n", RFWaitCounter);
- msleep(1); // 1 ms
-
- if((RFWaitCounter > 100)) //|| RT_USB_CANNOT_IO(Adapter))
- {
- RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
- return 0xffffffff;
- }
- else
- {
- }
- }
-
- priv->bChangeRFInProgress = true;
- Offset &= 0x3f; //RF_Offset= 0x00~0x3F
-
- write_nic_dword(dev, RF_BB_CMD_ADDR, 0xF0000002|
- (Offset<<8)| //RF_Offset= 0x00~0x3F
- (eRFPath<<16)); //RF_Path = 0(A) or 1(B)
-
- do
- {// Make sure that access could be done.
- if(read_nic_dword(dev, RF_BB_CMD_ADDR) == 0)
- break;
- }while( --PollingCnt );
-
- // Data FW read back.
- ReturnValue = read_nic_dword(dev, RF_BB_CMD_DATA);
-
- up(&priv->rf_sem);
- priv->bChangeRFInProgress = false;
-
- RT_TRACE(COMP_RF, "phy_QueryUsbRFReg(): eRFPath(%d), Offset(%#x) = %#x\n", eRFPath, Offset, ReturnValue);
-
- return ReturnValue;
-
-}
-
-
-//
-// Description:
-// RF wrote by 4181 to make sure that operation could be done in unlimited cycle.
-//
-// Assumption:
-// - Only use on RTL8192S USB interface.
-// - PASSIVE LEVEL
-// - RT_RF_OPERATE_SPINLOCK is acquired and keep on holding to the end.FIXLZM
-//
-// Created by Roger, 2008.09.06.
-//
-//use in phy only
-void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 RegAddr,u32 Data)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 PollingCnt = 50;
- u8 RFWaitCounter = 0;
-
-
- //
- // <Roger_Notes> Due to PASSIVE_LEVEL, so we ONLY simply busy waiting for a while here.
- // We have to make sure that previous BB I/O has been done.
- // 2008.08.20.
- //
- while(priv->bChangeRFInProgress)
- {
- down(&priv->rf_sem);
-
- RFWaitCounter ++;
- RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Wait 1 ms (%d times)...\n", RFWaitCounter);
- msleep(1); // 1 ms
-
- if((RFWaitCounter > 100))
- {
- RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): (%d) Wait too logn to query BB!!\n", RFWaitCounter);
- return;
- }
- else
- {
- }
- }
-
- priv->bChangeRFInProgress = true;
-
-
- RegAddr &= 0x3f; //RF_Offset= 0x00~0x3F
-
- write_nic_dword(dev, RF_BB_CMD_DATA, Data);
- write_nic_dword(dev, RF_BB_CMD_ADDR, 0xF0000003|
- (RegAddr<<8)| //RF_Offset= 0x00~0x3F
- (eRFPath<<16)); //RF_Path = 0(A) or 1(B)
-
- do
- {// Make sure that access could be done.
- if(read_nic_dword(dev, RF_BB_CMD_ADDR) == 0)
- break;
- }while( --PollingCnt );
-
- if(PollingCnt == 0)
- {
- RT_TRACE(COMP_RF, "phy_SetUsbRFReg(): Set RegAddr(%#x) = %#x Fail!!!\n", RegAddr, Data);
- }
-
- up(&priv->rf_sem);
- priv->bChangeRFInProgress = false;
-
-}
-
-//
-// 1. BB register R/W API
-//
-/**
-* Function: PHY_QueryBBReg
-*
-* OverView: Read "sepcific bits" from BB register
-*
-* Input:
-* PADAPTER Adapter,
-* u32 RegAddr, //The target address to be readback
-* u32 BitMask //The target bit position in the target address
-* //to be readback
-* Output: None
-* Return: u32 Data //The readback register value
-* Note: This function is equal to "GetRegSetting" in PHY programming guide
-*/
-u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
-{
-
- u32 ReturnValue = 0, OriginalValue, BitShift;
-
-
- RT_TRACE(COMP_RF, "--->PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x)\n", RegAddr, BitMask);
-
- //
- // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
- // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
- // infinite cycle.
- // 2008.09.06.
- //
- if(IS_BB_REG_OFFSET_92S(RegAddr))
- {
-
- if((RegAddr & 0x03) != 0)
- {
- printk("%s: Not DWORD alignment!!\n", __FUNCTION__);
- return 0;
- }
-
- OriginalValue = phy_QueryUsbBBReg(dev, RegAddr);
- }
- else
- {
- OriginalValue = read_nic_dword(dev, RegAddr);
- }
-
- BitShift = phy_CalculateBitShift(BitMask);
- ReturnValue = (OriginalValue & BitMask) >> BitShift;
-
-
- RT_TRACE(COMP_RF, "<---PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x), OriginalValue(%#x)\n", RegAddr, BitMask, OriginalValue);
- return (ReturnValue);
-}
-
-/**
-* Function: PHY_SetBBReg
-*
-* OverView: Write "Specific bits" to BB register (page 8~)
-*
-* Input:
-* PADAPTER Adapter,
-* u32 RegAddr, //The target address to be modified
-* u32 BitMask //The target bit position in the target address
-* //to be modified
-* u32 Data //The new register value in the target bit position
-* //of the target address
-*
-* Output: None
-* Return: None
-* Note: This function is equal to "PutRegSetting" in PHY programming guide
-*/
-void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data)
-{
- u32 OriginalValue, BitShift, NewValue;
-
-
- RT_TRACE(COMP_RF, "--->PHY_SetBBReg(): RegAddr(%#x), BitMask(%#x), Data(%#x)\n", RegAddr, BitMask, Data);
-
- //
- // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
- // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
- // infinite cycle.
- // 2008.09.06.
- //
- if(IS_BB_REG_OFFSET_92S(RegAddr))
- {
- if((RegAddr & 0x03) != 0)
- {
- printk("%s: Not DWORD alignment!!\n", __FUNCTION__);
- return;
- }
-
- if(BitMask!= bMaskDWord)
- {//if not "double word" write
- OriginalValue = phy_QueryUsbBBReg(dev, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- NewValue = (((OriginalValue) & (~BitMask))|(Data << BitShift));
- phy_SetUsbBBReg(dev, RegAddr, NewValue);
- }else
- phy_SetUsbBBReg(dev, RegAddr, Data);
- }
- else
- {
- if(BitMask!= bMaskDWord)
- {//if not "double word" write
- OriginalValue = read_nic_dword(dev, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- NewValue = (((OriginalValue) & (~BitMask)) | (Data << BitShift));
- write_nic_dword(dev, RegAddr, NewValue);
- }else
- write_nic_dword(dev, RegAddr, Data);
- }
-
-
- return;
-}
-
-
-//
-// 2. RF register R/W API
-//
-/**
-* Function: PHY_QueryRFReg
-*
-* OverView: Query "Specific bits" to RF register (page 8~)
-*
-* Input:
-* PADAPTER Adapter,
-* RF90_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D
-* u32 RegAddr, //The target address to be read
-* u32 BitMask //The target bit position in the target address
-* //to be read
-*
-* Output: None
-* Return: u32 Readback value
-* Note: This function is equal to "GetRFRegSetting" in PHY programming guide
-*/
-u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
-{
- u32 Original_Value, Readback_Value, BitShift;//, flags;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-
- RT_TRACE(COMP_RF, "--->PHY_QueryRFReg(): RegAddr(%#x), eRFPath(%#x), BitMask(%#x)\n", RegAddr, eRFPath,BitMask);
-
- if (!((priv->rf_pathmap >> eRFPath) & 0x1))
- {
- printk("EEEEEError: rfpath off! rf_pathmap=%x eRFPath=%x\n", priv->rf_pathmap, eRFPath);
- return 0;
- }
-
- if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
- {
- printk("EEEEEError: not legal rfpath! eRFPath=%x\n", eRFPath);
- return 0;
- }
-
- down(&priv->rf_sem);
- //
- // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
- // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
- // infinite cycle.
- // 2008.09.06.
- //
- Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
-
- BitShift = phy_CalculateBitShift(BitMask);
- Readback_Value = (Original_Value & BitMask) >> BitShift;
- up(&priv->rf_sem);
-
- return (Readback_Value);
-}
-
-/**
-* Function: PHY_SetRFReg
-*
-* OverView: Write "Specific bits" to RF register (page 8~)
-*
-* Input:
-* PADAPTER Adapter,
-* RF90_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D
-* u32 RegAddr, //The target address to be modified
-* u32 BitMask //The target bit position in the target address
-* //to be modified
-* u32 Data //The new register Data in the target bit position
-* //of the target address
-*
-* Output: None
-* Return: None
-* Note: This function is equal to "PutRFRegSetting" in PHY programming guide
-*/
-void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 Original_Value, BitShift, New_Value;//, flags;
-
- RT_TRACE(COMP_RF, "--->PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
- RegAddr, BitMask, Data, eRFPath);
-
- if (!((priv->rf_pathmap >> eRFPath) & 0x1))
- {
- printk("EEEEEError: rfpath off! rf_pathmap=%x eRFPath=%x\n", priv->rf_pathmap, eRFPath);
- return ;
- }
- if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
- {
- printk("EEEEEError: not legal rfpath! eRFPath=%x\n", eRFPath);
- return;
- }
-
- down(&priv->rf_sem);
- //
- // <Roger_Notes> Due to 8051 operation cycle (limitation cycle: 6us) and 1-Byte access issue, we should use
- // 4181 to access Base Band instead of 8051 on USB interface to make sure that access could be done in
- // infinite cycle.
-
- if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
- {
- Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- New_Value = (((Original_Value)&(~BitMask))|(Data<< BitShift));
- phy_SetUsbRFReg(dev, eRFPath, RegAddr, New_Value);
- }
- else
- phy_SetUsbRFReg(dev, eRFPath, RegAddr, Data);
- up(&priv->rf_sem);
- RT_TRACE(COMP_RF, "<---PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
- RegAddr, BitMask, Data, eRFPath);
-
-}
-
-/**
-* Function: phy_CalculateBitShift
-*
-* OverView: Get shifted position of the BitMask
-*
-* Input:
-* u32 BitMask,
-*
-* Output: none
-* Return: u32 Return the shift bit bit position of the mask
-*/
-//use in phy only
-static u32 phy_CalculateBitShift(u32 BitMask)
-{
- u32 i;
-
- for(i=0; i<=31; i++)
- {
- if ( ((BitMask>>i) & 0x1 ) == 1)
- break;
- }
-
- return (i);
-}
-
-
-//
-// 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt.
-//
-/*-----------------------------------------------------------------------------
- * Function: PHY_MACConfig8192S
- *
- * Overview: Condig MAC by header file or parameter file.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 08/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-//adapter_start
-extern bool PHY_MACConfig8192S(struct net_device* dev)
-{
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
-
- //
- // Config MAC
- //
- rtStatus = phy_ConfigMACWithHeaderFile(dev);
- return (rtStatus == RT_STATUS_SUCCESS) ? true:false;
-
-}
-
-//adapter_start
-extern bool
-PHY_BBConfig8192S(struct net_device* dev)
-{
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
-
- u8 PathMap = 0, index = 0, rf_num = 0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- phy_InitBBRFRegisterDefinition(dev);
-
-
- rtStatus = phy_BB8192S_Config_ParaFile(dev);
-
- PathMap = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_TxInfo, 0xf) |
- rtl8192_QueryBBReg(dev, rOFDM0_TRxPathEnable, 0xf));
- priv->rf_pathmap = PathMap;
- for(index = 0; index<4; index++)
- {
- if((PathMap>>index)&0x1)
- rf_num++;
- }
-
- if((priv->rf_type==RF_1T1R && rf_num!=1) ||
- (priv->rf_type==RF_1T2R && rf_num!=2) ||
- (priv->rf_type==RF_2T2R && rf_num!=2) ||
- (priv->rf_type==RF_2T2R_GREEN && rf_num!=2) ||
- (priv->rf_type==RF_2T4R && rf_num!=4))
- {
- RT_TRACE( COMP_INIT, "PHY_BBConfig8192S: RF_Type(%x) does not match RF_Num(%x)!!\n", priv->rf_type, rf_num);
- }
- return (rtStatus == RT_STATUS_SUCCESS) ? 1:0;
-}
-
-//adapter_start
-extern bool
-PHY_RFConfig8192S(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
-
- //Set priv->rf_chip = RF_8225 to do real PHY FPGA initilization
-
- //<Roger_EXP> We assign RF type here temporally. 2008.09.12.
- priv->rf_chip = RF_6052;
-
- //
- // RF config
- //
- switch(priv->rf_chip)
- {
- case RF_8225:
- case RF_6052:
- rtStatus = PHY_RF6052_Config(dev);
- break;
-
- case RF_8256:
- //rtStatus = PHY_RF8256_Config(dev);
- break;
-
- case RF_8258:
- break;
-
- case RF_PSEUDO_11N:
- //rtStatus = PHY_RF8225_Config(dev);
- break;
- default:
- break;
- }
-
- return (rtStatus == RT_STATUS_SUCCESS) ? 1:0;
-}
-
-
-#ifdef TO_DO_LIST
-static RT_STATUS
-phy_BB8190_Config_HardCode(struct net_device* dev)
-{
- return RT_STATUS_SUCCESS;
-}
-#endif
-
-/*-----------------------------------------------------------------------------
- * Function: phy_SetBBtoDiffRFWithHeaderFile()
- *
- * Overview: This function
- *
- *
- * Input: PADAPTER Adapter
- * u1Byte ConfigType 0 => PHY_CONFIG
- *
- * Output: NONE
- *
- * Return: RT_STATUS_SUCCESS: configuration file exist
- * When Who Remark
- * 2008/11/10 tynli
- * use in phy only
- *---------------------------------------------------------------------------*/
-static RT_STATUS
-phy_SetBBtoDiffRFWithHeaderFile(struct net_device* dev, u8 ConfigType)
-{
- int i;
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32* Rtl819XPHY_REGArraytoXTXR_Table;
- u16 PHY_REGArraytoXTXRLen;
-
-
- if(priv->rf_type == RF_1T1R)
- {
- Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to1T1R_Array;
- PHY_REGArraytoXTXRLen = PHY_ChangeTo_1T1RArrayLength;
- }
- else if(priv->rf_type == RF_1T2R)
- {
- Rtl819XPHY_REGArraytoXTXR_Table = Rtl819XPHY_REG_to1T2R_Array;
- PHY_REGArraytoXTXRLen = PHY_ChangeTo_1T2RArrayLength;
- }
- else
- {
- return RT_STATUS_FAILURE;
- }
-
- if(ConfigType == BaseBand_Config_PHY_REG)
- {
- for(i=0;i<PHY_REGArraytoXTXRLen;i=i+3)
- {
- if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfe)
- mdelay(50);
- else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfd)
- mdelay(5);
- else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfc)
- mdelay(1);
- else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfb)
- udelay(50);
- else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xfa)
- udelay(5);
- else if (Rtl819XPHY_REGArraytoXTXR_Table[i] == 0xf9)
- udelay(1);
- rtl8192_setBBreg(dev, Rtl819XPHY_REGArraytoXTXR_Table[i], Rtl819XPHY_REGArraytoXTXR_Table[i+1], Rtl819XPHY_REGArraytoXTXR_Table[i+2]);
- }
- }
- else {
- RT_TRACE(COMP_SEND, "phy_SetBBtoDiffRFWithHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
- }
- return RT_STATUS_SUCCESS;
-}
-
-
-//use in phy only
-static RT_STATUS
-phy_BB8192S_Config_ParaFile(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
-
- RT_TRACE(COMP_INIT, "==>phy_BB8192S_Config_ParaFile\n");
-
- //
- // 1. Read PHY_REG.TXT BB INIT!!
- // We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R
- //
- if (priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R ||
- priv->rf_type == RF_1T1R ||priv->rf_type == RF_2T2R_GREEN)
- {
- rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_PHY_REG);
- if(priv->rf_type != RF_2T2R && priv->rf_type != RF_2T2R_GREEN)
- {//2008.11.10 Added by tynli. The default PHY_REG.txt we read is for 2T2R,
- //so we should reconfig BB reg with the right PHY parameters.
- rtStatus = phy_SetBBtoDiffRFWithHeaderFile(dev,BaseBand_Config_PHY_REG);
- }
- }else
- rtStatus = RT_STATUS_FAILURE;
-
- if(rtStatus != RT_STATUS_SUCCESS){
- RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():Write BB Reg Fail!!");
- goto phy_BB8190_Config_ParaFile_Fail;
- }
-
- //
- // 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt
- //
- if (priv->AutoloadFailFlag == false)
- {
- rtStatus = phy_ConfigBBWithPgHeaderFile(dev,BaseBand_Config_PHY_REG);
- }
- if(rtStatus != RT_STATUS_SUCCESS){
- RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():BB_PG Reg Fail!!");
- goto phy_BB8190_Config_ParaFile_Fail;
- }
-
- //
- // 3. BB AGC table Initialization
- //
- rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_AGC_TAB);
-
- if(rtStatus != RT_STATUS_SUCCESS){
- printk( "phy_BB8192S_Config_ParaFile():AGC Table Fail\n");
- goto phy_BB8190_Config_ParaFile_Fail;
- }
-
-
- // Check if the CCK HighPower is turned ON.
- // This is used to calculate PWDB.
- priv->bCckHighPower = (bool)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
-
-
-phy_BB8190_Config_ParaFile_Fail:
- return rtStatus;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: phy_ConfigMACWithHeaderFile()
- *
- * Overview: This function read BB parameters from Header file we gen, and do register
- * Read/Write
- *
- * Input: PADAPTER Adapter
- * char* pFileName
- *
- * Output: NONE
- *
- * Return: RT_STATUS_SUCCESS: configuration file exist
- *
- * Note: The format of MACPHY_REG.txt is different from PHY and RF.
- * [Register][Mask][Value]
- *---------------------------------------------------------------------------*/
-//use in phy only
-static RT_STATUS
-phy_ConfigMACWithHeaderFile(struct net_device* dev)
-{
- u32 i = 0;
- u32 ArrayLength = 0;
- u32* ptrArray;
-
- { //2008.11.06 Modified by tynli.
- RT_TRACE(COMP_INIT, "Read Rtl819XMACPHY_Array\n");
- ArrayLength = MAC_2T_ArrayLength;
- ptrArray = Rtl819XMAC_Array;
- }
-
- for(i = 0 ;i < ArrayLength;i=i+2){ // Add by tynli for 2 column
- write_nic_byte(dev, ptrArray[i], (u8)ptrArray[i+1]);
- }
- return RT_STATUS_SUCCESS;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: phy_ConfigBBWithHeaderFile()
- *
- * Overview: This function read BB parameters from general file format, and do register
- * Read/Write
- *
- * Input: PADAPTER Adapter
- * u8 ConfigType 0 => PHY_CONFIG
- * 1 =>AGC_TAB
- *
- * Output: NONE
- *
- * Return: RT_STATUS_SUCCESS: configuration file exist
- *
- *---------------------------------------------------------------------------*/
-//use in phy only
-static RT_STATUS
-phy_ConfigBBWithHeaderFile(struct net_device* dev,u8 ConfigType)
-{
- int i;
- u32* Rtl819XPHY_REGArray_Table;
- u32* Rtl819XAGCTAB_Array_Table;
- u16 PHY_REGArrayLen, AGCTAB_ArrayLen;
-
- AGCTAB_ArrayLen = AGCTAB_ArrayLength;
- Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array;
- PHY_REGArrayLen = PHY_REG_2T2RArrayLength; // Default RF_type: 2T2R
- Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_Array;
-
- if(ConfigType == BaseBand_Config_PHY_REG)
- {
- for(i=0;i<PHY_REGArrayLen;i=i+2)
- {
- if (Rtl819XPHY_REGArray_Table[i] == 0xfe)
- mdelay(50);
- else if (Rtl819XPHY_REGArray_Table[i] == 0xfd)
- mdelay(5);
- else if (Rtl819XPHY_REGArray_Table[i] == 0xfc)
- mdelay(1);
- else if (Rtl819XPHY_REGArray_Table[i] == 0xfb)
- udelay(50);
- else if (Rtl819XPHY_REGArray_Table[i] == 0xfa)
- udelay(5);
- else if (Rtl819XPHY_REGArray_Table[i] == 0xf9)
- udelay(1);
- rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table[i], bMaskDWord, Rtl819XPHY_REGArray_Table[i+1]);
-
- }
- }
- else if(ConfigType == BaseBand_Config_AGC_TAB){
- for(i=0;i<AGCTAB_ArrayLen;i=i+2)
- {
- rtl8192_setBBreg(dev, Rtl819XAGCTAB_Array_Table[i], bMaskDWord, Rtl819XAGCTAB_Array_Table[i+1]);
- }
- }
- return RT_STATUS_SUCCESS;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: phy_ConfigBBWithPgHeaderFile
- *
- * Overview: Config PHY_REG_PG array
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!!
- * 11/10/2008 tynli Modify to mew files.
- //use in phy only
- *---------------------------------------------------------------------------*/
-static RT_STATUS
-phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType)
-{
- int i;
- u32* Rtl819XPHY_REGArray_Table_PG;
- u16 PHY_REGArrayPGLen;
-
- PHY_REGArrayPGLen = PHY_REG_Array_PGLength;
- Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG;
-
- if(ConfigType == BaseBand_Config_PHY_REG)
- {
- for(i=0;i<PHY_REGArrayPGLen;i=i+3)
- {
- if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfe)
- mdelay(50);
- else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfd)
- mdelay(5);
- else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfc)
- mdelay(1);
- else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfb)
- udelay(50);
- else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xfa)
- udelay(5);
- else if (Rtl819XPHY_REGArray_Table_PG[i] == 0xf9)
- udelay(1);
- rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table_PG[i], Rtl819XPHY_REGArray_Table_PG[i+1], Rtl819XPHY_REGArray_Table_PG[i+2]);
- }
- }else{
- RT_TRACE(COMP_SEND, "phy_ConfigBBWithPgHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n");
- }
- return RT_STATUS_SUCCESS;
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_ConfigRFWithHeaderFile()
- *
- * Overview: This function read RF parameters from general file format, and do RF 3-wire
- *
- * Input: PADAPTER Adapter
- * char* pFileName
- * RF90_RADIO_PATH_E eRFPath
- *
- * Output: NONE
- *
- * Return: RT_STATUS_SUCCESS: configuration file exist
- *
- * Note: Delay may be required for RF configuration
- *---------------------------------------------------------------------------*/
-u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- int i;
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
- u32 *Rtl819XRadioA_Array_Table;
- u32 *Rtl819XRadioB_Array_Table;
- u16 RadioA_ArrayLen,RadioB_ArrayLen;
-
- { //2008.11.06 Modified by tynli
- RadioA_ArrayLen = RadioA_1T_ArrayLength;
- Rtl819XRadioA_Array_Table=Rtl819XRadioA_Array;
- Rtl819XRadioB_Array_Table=Rtl819XRadioB_Array;
- RadioB_ArrayLen = RadioB_ArrayLength;
- }
-
- if( priv->rf_type == RF_2T2R_GREEN )
- {
- Rtl819XRadioB_Array_Table = Rtl819XRadioB_GM_Array;
- RadioB_ArrayLen = RadioB_GM_ArrayLength;
- }
- else
- {
- Rtl819XRadioB_Array_Table = Rtl819XRadioB_Array;
- RadioB_ArrayLen = RadioB_ArrayLength;
- }
-
- rtStatus = RT_STATUS_SUCCESS;
-
-
- switch(eRFPath){
- case RF90_PATH_A:
- for(i = 0;i<RadioA_ArrayLen; i=i+2){
- if(Rtl819XRadioA_Array_Table[i] == 0xfe)
- { // Deay specific ms. Only RF configuration require delay.
- mdelay(1000);
- }
- else if (Rtl819XRadioA_Array_Table[i] == 0xfd)
- mdelay(5);
- else if (Rtl819XRadioA_Array_Table[i] == 0xfc)
- mdelay(1);
- else if (Rtl819XRadioA_Array_Table[i] == 0xfb)
- udelay(50);
- else if (Rtl819XRadioA_Array_Table[i] == 0xfa)
- udelay(5);
- else if (Rtl819XRadioA_Array_Table[i] == 0xf9)
- udelay(1);
- else
- {
- rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioA_Array_Table[i], bRFRegOffsetMask, Rtl819XRadioA_Array_Table[i+1]);
- }
- }
- break;
- case RF90_PATH_B:
- for(i = 0;i<RadioB_ArrayLen; i=i+2){
- if(Rtl819XRadioB_Array_Table[i] == 0xfe)
- { // Deay specific ms. Only RF configuration require delay.
- mdelay(1000);
- }
- else if (Rtl819XRadioB_Array_Table[i] == 0xfd)
- mdelay(5);
- else if (Rtl819XRadioB_Array_Table[i] == 0xfc)
- mdelay(1);
- else if (Rtl819XRadioB_Array_Table[i] == 0xfb)
- udelay(50);
- else if (Rtl819XRadioB_Array_Table[i] == 0xfa)
- udelay(5);
- else if (Rtl819XRadioB_Array_Table[i] == 0xf9)
- udelay(1);
- else
- {
- rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioB_Array_Table[i], bRFRegOffsetMask, Rtl819XRadioB_Array_Table[i+1]);
- }
- }
- break;
- case RF90_PATH_C:
- break;
- case RF90_PATH_D:
- break;
- default:
- break;
- }
-
- return rtStatus;
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_CheckBBAndRFOK()
- *
- * Overview: This function is write register and then readback to make sure whether
- * BB[PHY0, PHY1], RF[Patha, path b, path c, path d] is Ok
- *
- * Input: PADAPTER Adapter
- * HW90_BLOCK_E CheckBlock
- * RF90_RADIO_PATH_E eRFPath // it is used only when CheckBlock is HW90_BLOCK_RF
- *
- * Output: NONE
- *
- * Return: RT_STATUS_SUCCESS: PHY is OK
- *
- * Note: This function may be removed in the ASIC
- *---------------------------------------------------------------------------*/
-//in 8256 phy_RF8256_Config_HardCode
-//but we don't use it temp
-RT_STATUS
-PHY_CheckBBAndRFOK(
- struct net_device* dev,
- HW90_BLOCK_E CheckBlock,
- RF90_RADIO_PATH_E eRFPath
- )
-{
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
- u32 i, CheckTimes = 4,ulRegRead = 0;
- u32 WriteAddr[4];
- u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
-
- // Initialize register address offset to be checked
- WriteAddr[HW90_BLOCK_MAC] = 0x100;
- WriteAddr[HW90_BLOCK_PHY0] = 0x900;
- WriteAddr[HW90_BLOCK_PHY1] = 0x800;
- WriteAddr[HW90_BLOCK_RF] = 0x3;
-
- for(i=0 ; i < CheckTimes ; i++)
- {
-
- //
- // Write Data to register and readback
- //
- switch(CheckBlock)
- {
- case HW90_BLOCK_MAC:
- RT_TRACE(COMP_INIT, "PHY_CheckBBRFOK(): Never Write 0x100 here!\n");
- break;
-
- case HW90_BLOCK_PHY0:
- case HW90_BLOCK_PHY1:
- write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
- ulRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]);
- break;
-
- case HW90_BLOCK_RF:
- WriteData[i] &= 0xfff;
- rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bRFRegOffsetMask, WriteData[i]);
- // TODO: we should not delay for such a long time. Ask SD3
- mdelay(10);
- ulRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord);
- mdelay(10);
- break;
-
- default:
- rtStatus = RT_STATUS_FAILURE;
- break;
- }
-
-
- //
- // Check whether readback data is correct
- //
- if(ulRegRead != WriteData[i])
- {
- RT_TRACE(COMP_ERR, "read back error(read:%x, write:%x)\n", ulRegRead, WriteData[i]);
- rtStatus = RT_STATUS_FAILURE;
- break;
- }
- }
-
- return rtStatus;
-}
-
-#ifdef TO_DO_LIST
-void
-PHY_SetRFPowerState8192SUsb(
- struct net_device* dev,
- RF_POWER_STATE RFPowerState
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool WaitShutDown = FALSE;
- u32 DWordContent;
- u8 eRFPath;
- BB_REGISTER_DEFINITION_T *pPhyReg;
-
- if(priv->SetRFPowerStateInProgress == TRUE)
- return;
-
- priv->SetRFPowerStateInProgress = TRUE;
-
-
- if(RFPowerState==RF_SHUT_DOWN)
- {
- RFPowerState=RF_OFF;
- WaitShutDown=TRUE;
- }
-
-
- priv->RFPowerState = RFPowerState;
- switch( priv->rf_chip )
- {
- case RF_8225:
- case RF_6052:
- switch( RFPowerState )
- {
- case RF_ON:
- break;
-
- case RF_SLEEP:
- break;
-
- case RF_OFF:
- break;
- }
- break;
-
- case RF_8256:
- switch( RFPowerState )
- {
- case RF_ON:
- break;
-
- case RF_SLEEP:
- break;
-
- case RF_OFF:
- for(eRFPath=(RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath < RF90_PATH_MAX; eRFPath++)
- {
- if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
- continue;
-
- pPhyReg = &priv->PHYRegDef[eRFPath];
- rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, bRFSI_RFENV);
- rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0);
- }
- break;
- }
- break;
-
- case RF_8258:
- break;
- }
-
- priv->SetRFPowerStateInProgress = FALSE;
-}
-#endif
-
-#ifdef RTL8192U
-void
-PHY_UpdateInitialGain(
- struct net_device* dev
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-
- switch(priv->rf_chip)
- {
- case RF_8225:
- break;
- case RF_8256:
- break;
- case RF_8258:
- break;
- case RF_PSEUDO_11N:
- break;
- case RF_6052:
- break;
- default:
- RT_TRACE(COMP_DBG, "PHY_UpdateInitialGain(): unknown rf_chip: %#X\n", priv->rf_chip);
- break;
- }
-}
-#endif
-
-void PHY_GetHWRegOriginalValue(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- // read tx power offset
- // Simulate 8192
- priv->MCSTxPowerLevelOriginalOffset[0] =
- rtl8192_QueryBBReg(dev, rTxAGC_Rate18_06, bMaskDWord);
- priv->MCSTxPowerLevelOriginalOffset[1] =
- rtl8192_QueryBBReg(dev, rTxAGC_Rate54_24, bMaskDWord);
- priv->MCSTxPowerLevelOriginalOffset[2] =
- rtl8192_QueryBBReg(dev, rTxAGC_Mcs03_Mcs00, bMaskDWord);
- priv->MCSTxPowerLevelOriginalOffset[3] =
- rtl8192_QueryBBReg(dev, rTxAGC_Mcs07_Mcs04, bMaskDWord);
- priv->MCSTxPowerLevelOriginalOffset[4] =
- rtl8192_QueryBBReg(dev, rTxAGC_Mcs11_Mcs08, bMaskDWord);
- priv->MCSTxPowerLevelOriginalOffset[5] =
- rtl8192_QueryBBReg(dev, rTxAGC_Mcs15_Mcs12, bMaskDWord);
-
- // Read CCK offset
- priv->MCSTxPowerLevelOriginalOffset[6] =
- rtl8192_QueryBBReg(dev, rTxAGC_CCK_Mcs32, bMaskDWord);
- RT_TRACE(COMP_INIT, "Legacy OFDM =%08x/%08x HT_OFDM=%08x/%08x/%08x/%08x\n",
- priv->MCSTxPowerLevelOriginalOffset[0], priv->MCSTxPowerLevelOriginalOffset[1] ,
- priv->MCSTxPowerLevelOriginalOffset[2], priv->MCSTxPowerLevelOriginalOffset[3] ,
- priv->MCSTxPowerLevelOriginalOffset[4], priv->MCSTxPowerLevelOriginalOffset[5] );
-
- // read rx initial gain
- priv->DefaultInitialGain[0] = rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bMaskByte0);
- priv->DefaultInitialGain[1] = rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bMaskByte0);
- priv->DefaultInitialGain[2] = rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bMaskByte0);
- priv->DefaultInitialGain[3] = rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bMaskByte0);
- RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
- priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
- priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
-
- // read framesync
- priv->framesync = rtl8192_QueryBBReg(dev, rOFDM0_RxDetector3, bMaskByte0);
- priv->framesyncC34 = rtl8192_QueryBBReg(dev, rOFDM0_RxDetector2, bMaskDWord);
- RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
- rOFDM0_RxDetector3, priv->framesync);
-}
-//YJ,modified,090107,end
-
-
-
-/**
-* Function: phy_InitBBRFRegisterDefinition
-*
-* OverView: Initialize Register definition offset for Radio Path A/B/C/D
-*
-* Input:
-* PADAPTER Adapter,
-*
-* Output: None
-* Return: None
-* Note: The initialization value is constant and it should never be changes
-*/
-//use in phy only
-static void phy_InitBBRFRegisterDefinition( struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- // RF Interface Sowrtware Control
- priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
- priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
- priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
- priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
-
- // RF Interface Readback Value
- priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
- priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
- priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
- priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
-
- // RF Interface Output (and Enable)
- priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
- priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
- priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
- priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
-
- // RF Interface (Output and) Enable
- priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
- priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
- priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
- priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
-
- //Addr of LSSI. Wirte RF register by driver
- priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
- priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
- priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
- priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
-
- // RF parameter
- priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select
- priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
- priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
- priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
-
- // Tx AGC Gain Stage (same for all path. Should we remove this?)
- priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
- priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
- priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
- priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
-
- // Tranceiver A~D HSSI Parameter-1
- priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1
- priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1
- priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1
- priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1
-
- // Tranceiver A~D HSSI Parameter-2
- priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2
- priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2
- priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2
- priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1
-
- // RF switch Control
- priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
- priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
- priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
- priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
-
- // AGC control 1
- priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
- priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
- priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
- priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
-
- // AGC control 2
- priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
- priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
- priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
- priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
-
- // RX AFE control 1
- priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
- priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
- priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
- priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
-
- // RX AFE control 1
- priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
- priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
- priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
- priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
-
- // Tx AFE control 1
- priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
- priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
- priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
- priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
-
- // Tx AFE control 2
- priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
- priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
- priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
- priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
-
- // Tranceiver LSSI Readback SI mode
- priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
- priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
- priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
- priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
-
- // Tranceiver LSSI Readback PI mode
- priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback;
- priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback;
-
-}
-
-
-//
-// Description: Change RF power state.
-//
-// Assumption: This function must be executed in re-schdulable context,
-// ie. PASSIVE_LEVEL.
-//
-
-bool PHY_SetRFPowerState(struct net_device* dev, RT_RF_POWER_STATE eRFPowerState)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bResult = FALSE;
-
- RT_TRACE(COMP_RF, "---------> PHY_SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
-
- if(eRFPowerState == priv->ieee80211->eRFPowerState)
- {
- RT_TRACE(COMP_RF, "<--------- PHY_SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
- return bResult;
- }
-
- bResult = phy_SetRFPowerState8192SU(dev, eRFPowerState);
-
- RT_TRACE(COMP_RF, "<--------- PHY_SetRFPowerState(): bResult(%d)\n", bResult);
-
- return bResult;
-}
-
-//use in phy only
-static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE eRFPowerState)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bResult = TRUE;
- u8 u1bTmp;
-
- if(priv->SetRFPowerStateInProgress == TRUE)
- return FALSE;
-
- priv->SetRFPowerStateInProgress = TRUE;
-
- switch(priv->rf_chip )
- {
- default:
- switch( eRFPowerState )
- {
- case eRfOn:
- write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
- write_nic_word(dev, CMDR, 0x37FC);
- write_nic_byte(dev, PHY_CCA, 0x3);
- write_nic_byte(dev, TXPAUSE, 0x00);
- write_nic_byte(dev, SPS1_CTRL, 0x64);
- break;
-
- //
- // In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
- // By Bruce, 2008-01-16.
- //
- case eRfSleep:
- case eRfOff:
- if (priv->ieee80211->eRFPowerState == eRfSleep || priv->ieee80211->eRFPowerState == eRfOff)
- break;
- //
- //RF Off/Sleep sequence. Designed/tested from SD4 Scott, SD1 Grent and Jonbon.
- // (0) Disable FW BB reset checking
- write_nic_dword(dev, WFM5, FW_BB_RESET_DISABLE);
-
- // (1) Switching Power Supply Register : Disable LD12 & SW12 (for IT)
- u1bTmp = read_nic_byte(dev, LDOV12D_CTRL);
- u1bTmp |= BIT0;
- write_nic_byte(dev, LDOV12D_CTRL, u1bTmp);
-
- write_nic_byte(dev, SPS1_CTRL, 0x0);
- write_nic_byte(dev, TXPAUSE, 0xFF);
-
- // (2) MAC Tx/Rx enable, BB enable, CCK/OFDM enable
- write_nic_word(dev, CMDR, 0x77FC);
- write_nic_byte(dev, PHY_CCA, 0x0);
- udelay(100);
-
- write_nic_word(dev, CMDR, 0x37FC);
- udelay(10);
-
- write_nic_word(dev, CMDR, 0x77FC);
- udelay(10);
-
- // (3) Reset BB TRX blocks
- write_nic_word(dev, CMDR, 0x57FC);
- break;
-
- default:
- bResult = FALSE;
- break;
- }
- break;
-
- }
- priv->ieee80211->eRFPowerState = eRFPowerState;
-#ifdef TO_DO_LIST
- if(bResult)
- {
- // Update current RF state variable.
- priv->ieee80211->eRFPowerState = eRFPowerState;
-
- switch(priv->rf_chip )
- {
- case RF_8256:
- switch(priv->ieee80211->eRFPowerState)
- {
- case eRfOff:
- //
- //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
- //
- if(pMgntInfo->RfOffReason==RF_CHANGE_BY_IPS )
- {
- dev->HalFunc.LedControlHandler(dev,LED_CTL_NO_LINK);
- }
- else
- {
- // Turn off LED if RF is not ON.
- dev->HalFunc.LedControlHandler(dev, LED_CTL_POWER_OFF);
- }
- break;
-
- case eRfOn:
- // Turn on RF we are still linked, which might happen when
- // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
- if( pMgntInfo->bMediaConnect == TRUE )
- {
- dev->HalFunc.LedControlHandler(dev, LED_CTL_LINK);
- }
- else
- {
- // Turn off LED if RF is not ON.
- dev->HalFunc.LedControlHandler(dev, LED_CTL_NO_LINK);
- }
- break;
-
- default:
- // do nothing.
- break;
- }// Switch RF state
-
- break;
-
- default:
- RT_TRACE(COMP_RF, "phy_SetRFPowerState8192SU(): Unknown RF type\n");
- break;
- }// Switch rf_chip
- }
-#endif
- priv->SetRFPowerStateInProgress = FALSE;
-
- return bResult;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: GetTxPowerLevel8190()
- *
- * Overview: This function is export to "common" moudule
- *
- * Input: PADAPTER Adapter
- * psByte Power Level
- *
- * Output: NONE
- *
- * Return: NONE
- *
- *---------------------------------------------------------------------------*/
- // no use temp
- void
-PHY_GetTxPowerLevel8192S(
- struct net_device* dev,
- long* powerlevel
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 TxPwrLevel = 0;
- long TxPwrDbm;
- //
- // Because the Tx power indexes are different, we report the maximum of them to
- // meet the CCX TPC request. By Bruce, 2008-01-31.
- //
-
- // CCK
- TxPwrLevel = priv->CurrentCckTxPwrIdx;
- TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_B, TxPwrLevel);
-
- // Legacy OFDM
- TxPwrLevel = priv->CurrentOfdm24GTxPwrIdx + priv->LegacyHTTxPowerDiff;
-
- // Compare with Legacy OFDM Tx power.
- if(phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_G, TxPwrLevel) > TxPwrDbm)
- TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_G, TxPwrLevel);
-
- // HT OFDM
- TxPwrLevel = priv->CurrentOfdm24GTxPwrIdx;
-
- // Compare with HT OFDM Tx power.
- if(phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_N_24G, TxPwrLevel) > TxPwrDbm)
- TxPwrDbm = phy_TxPwrIdxToDbm(dev, WIRELESS_MODE_N_24G, TxPwrLevel);
-
- *powerlevel = TxPwrDbm;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: SetTxPowerLevel8190()
- *
- * Overview: This function is export to "HalCommon" moudule
- *
- * Input: PADAPTER Adapter
- * u1Byte channel
- *
- * Output: NONE
- *
- * Return: NONE
- * 2008/11/04 MHC We remove EEPROM_93C56.
- * We need to move CCX relative code to independet file.
-* 2009/01/21 MHC Support new EEPROM format from SD3 requirement.
- *---------------------------------------------------------------------------*/
- void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8 channel)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 powerlevel = (u8)EEPROM_Default_TxPower, powerlevelOFDM24G = 0x10;
- s8 ant_pwr_diff = 0;
- u32 u4RegValue;
- u8 index = (channel -1);
- // 2009/01/22 MH Add for new EEPROM format from SD3
- u8 pwrdiff[2] = {0};
- u8 ht20pwr[2] = {0}, ht40pwr[2] = {0};
- u8 rfpath = 0, rfpathnum = 2;
-
- if(priv->bTXPowerDataReadFromEEPORM == FALSE)
- return;
-
- /*
- * Read predefined TX power index in EEPROM
- */
- {
- //
- // Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-B Tx
- // Power must be calculated by the antenna diff.
- // So we have to rewrite Antenna gain offset register here.
- // Please refer to BB register 0x80c
- // 1. For CCK.
- // 2. For OFDM 1T or 2T
- //
-
- // 1. CCK
- powerlevel = priv->RfTxPwrLevelCck[0][index];
-
- if (priv->rf_type == RF_1T2R || priv->rf_type == RF_1T1R)
- {
- // Read HT 40 OFDM TX power
- powerlevelOFDM24G = priv->RfTxPwrLevelOfdm1T[0][index];
- // RF B HT OFDM pwr-RFA HT OFDM pwr
- // Only one RF we need not to decide B <-> A pwr diff
-
- // Legacy<->HT pwr diff, we only care about path A.
-
- // We only assume 1T as RF path A
- rfpathnum = 1;
- ht20pwr[0] = ht40pwr[0] = priv->RfTxPwrLevelOfdm1T[0][index];
- }
- else if (priv->rf_type == RF_2T2R)
- {
- // Read HT 40 OFDM TX power
- powerlevelOFDM24G = priv->RfTxPwrLevelOfdm2T[0][index];
- // RF B HT OFDM pwr-RFA HT OFDM pwr
- ant_pwr_diff = priv->RfTxPwrLevelOfdm2T[1][index] -
- priv->RfTxPwrLevelOfdm2T[0][index];
-
- ht20pwr[0] = ht40pwr[0] = priv->RfTxPwrLevelOfdm2T[0][index];
- ht20pwr[1] = ht40pwr[1] = priv->RfTxPwrLevelOfdm2T[1][index];
- }
-
- //
- // 2009/01/21 MH Support new EEPROM format from SD3 requirement
- // 2009/02/10 Cosa, Here is only for reg B/C/D to A gain diff.
- //
- if (priv->EEPROMVersion == 2) // Defined by SD1 Jong
- {
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- {
- for (rfpath = 0; rfpath < rfpathnum; rfpath++)
- {
- // HT 20<->40 pwr diff
- pwrdiff[rfpath] = priv->TxPwrHt20Diff[rfpath][index];
-
- // Calculate Antenna pwr diff
- if (pwrdiff[rfpath] < 8) // 0~+7
- {
- ht20pwr[rfpath] += pwrdiff[rfpath];
- }
- else // index8-15=-8~-1
- {
- ht20pwr[rfpath] -= (15-pwrdiff[rfpath]);
- }
- }
-
- // RF B HT OFDM pwr-RFA HT OFDM pwr
- if (priv->rf_type == RF_2T2R)
- ant_pwr_diff = ht20pwr[1] - ht20pwr[0];
- }
-
- // Band Edge scheme is enabled for FCC mode
- if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
- {
- for (rfpath = 0; rfpath < rfpathnum; rfpath++)
- {
- pwrdiff[rfpath] = 0;
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
- {
- if (channel <= 3)
- pwrdiff[rfpath] = priv->TxPwrbandEdgeHt40[rfpath][0];
- else if (channel >= 9)
- pwrdiff[rfpath] = priv->TxPwrbandEdgeHt40[rfpath][1];
- else
- pwrdiff[rfpath] = 0;
-
- ht40pwr[rfpath] -= pwrdiff[rfpath];
- }
- else if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- {
- if (channel == 1)
- pwrdiff[rfpath] = priv->TxPwrbandEdgeHt20[rfpath][0];
- else if (channel >= 11)
- pwrdiff[rfpath] = priv->TxPwrbandEdgeHt20[rfpath][1];
- else
- pwrdiff[rfpath] = 0;
-
- ht20pwr[rfpath] -= pwrdiff[rfpath];
- }
- }
-
- if (priv->rf_type == RF_2T2R)
- {
- // HT 20/40 must decide if they need to minus BD pwr offset
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
- ant_pwr_diff = ht40pwr[1] - ht40pwr[0];
- else
- ant_pwr_diff = ht20pwr[1] - ht20pwr[0];
- }
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- {
- if (channel <= 1 || channel >= 11)
- {
- }
- }
- else
- {
- if (channel <= 3 || channel >= 9)
- {
- }
- }
- }
- }
-
- //Cosa added for protection, the reg rFPGA0_TxGainStage
- // range is from 7~-8, index = 0x0~0xf
- if(ant_pwr_diff > 7)
- ant_pwr_diff = 7;
- if(ant_pwr_diff < -8)
- ant_pwr_diff = -8;
-
- ant_pwr_diff &= 0xf;
-
- // Antenna TX power difference
- priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care
- priv->AntennaTxPwDiff[1] = 0;// RF-C, don't care
- priv->AntennaTxPwDiff[0] = (u8)(ant_pwr_diff); // RF-B
-
- // Antenna gain offset from B/C/D to A
- u4RegValue = ( priv->AntennaTxPwDiff[2]<<8 |
- priv->AntennaTxPwDiff[1]<<4 |
- priv->AntennaTxPwDiff[0] );
-
- // Notify Tx power difference for B/C/D to A!!!
- rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue);
- }
-
- //
- // CCX 2 S31, AP control of client transmit power:
- // 1. We shall not exceed Cell Power Limit as possible as we can.
- // 2. Tolerance is +/- 5dB.
- // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
- //
- // TODO:
- // 1. 802.11h power contraint
- //
- //
-#ifdef TODO //WB, 11h has not implemented now.
- if( priv->ieee80211->iw_mode != IW_MODE_INFRA && priv->bWithCcxCellPwr &&
- channel == priv->ieee80211->current_network.channel)// & priv->ieee80211->mAssoc )
- {
- u8 CckCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_B, priv->CcxCellPwr);
- u8 LegacyOfdmCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_G, priv->CcxCellPwr);
- u8 OfdmCellPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_N_24G, priv->CcxCellPwr);
-
- RT_TRACE(COMP_TXAGC,
- ("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
- priv->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx));
- RT_TRACE(COMP_TXAGC,
- ("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
- channel, powerlevel, powerlevelOFDM24G + priv->LegacyHTTxPowerDiff, powerlevelOFDM24G));
-
- // CCK
- if(powerlevel > CckCellPwrIdx)
- powerlevel = CckCellPwrIdx;
- // Legacy OFDM, HT OFDM
- if(powerlevelOFDM24G + priv->LegacyHTTxPowerDiff > LegacyOfdmCellPwrIdx)
- {
- if((OfdmCellPwrIdx - priv->LegacyHTTxPowerDiff) > 0)
- {
- powerlevelOFDM24G = OfdmCellPwrIdx - priv->LegacyHTTxPowerDiff;
- }
- else
- {
- powerlevelOFDM24G = 0;
- }
- }
-
- RT_TRACE(COMP_TXAGC,
- ("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n",
- powerlevel, powerlevelOFDM24G + priv->LegacyHTTxPowerDiff, powerlevelOFDM24G));
- }
-#endif
-
- priv->CurrentCckTxPwrIdx = powerlevel;
- priv->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G;
-
- switch(priv->rf_chip)
- {
- case RF_8225:
- break;
-
- case RF_8256:
- break;
-
- case RF_6052:
- PHY_RF6052SetCckTxPower(dev, powerlevel);
- PHY_RF6052SetOFDMTxPower(dev, powerlevelOFDM24G);
- break;
-
- case RF_8258:
- break;
- default:
- break;
- }
-
-}
-
-//
-// Description:
-// Update transmit power level of all channel supported.
-//
-// TODO:
-// A mode.
-bool PHY_UpdateTxPowerDbm8192S(struct net_device* dev, long powerInDbm)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 idx;
- u8 rf_path;
-
- // TODO: A mode Tx power.
- u8 CckTxPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_B, powerInDbm);
- u8 OfdmTxPwrIdx = phy_DbmToTxPwrIdx(dev, WIRELESS_MODE_N_24G, powerInDbm);
-
- if(OfdmTxPwrIdx - priv->LegacyHTTxPowerDiff > 0)
- OfdmTxPwrIdx -= priv->LegacyHTTxPowerDiff;
- else
- OfdmTxPwrIdx = 0;
-
- for(idx = 0; idx < 14; idx++)
- {
- priv->TxPowerLevelCCK[idx] = CckTxPwrIdx;
- priv->TxPowerLevelCCK_A[idx] = CckTxPwrIdx;
- priv->TxPowerLevelCCK_C[idx] = CckTxPwrIdx;
- priv->TxPowerLevelOFDM24G[idx] = OfdmTxPwrIdx;
- priv->TxPowerLevelOFDM24G_A[idx] = OfdmTxPwrIdx;
- priv->TxPowerLevelOFDM24G_C[idx] = OfdmTxPwrIdx;
-
- for (rf_path = 0; rf_path < 2; rf_path++)
- {
- priv->RfTxPwrLevelCck[rf_path][idx] = CckTxPwrIdx;
- priv->RfTxPwrLevelOfdm1T[rf_path][idx] = \
- priv->RfTxPwrLevelOfdm2T[rf_path][idx] = OfdmTxPwrIdx;
- }
- }
-
- PHY_SetTxPowerLevel8192S(dev, priv->chan);
-
- return TRUE;
-}
-
-/*
- Description:
- When beacon interval is changed, the values of the
- hw registers should be modified.
-*/
-
-extern void PHY_SetBeaconHwReg( struct net_device* dev, u16 BeaconInterval)
-{
- u32 NewBeaconNum;
-
- NewBeaconNum = BeaconInterval *32 - 64;
- write_nic_dword(dev, WFM3+4, NewBeaconNum);
- write_nic_dword(dev, WFM3, 0xB026007C);
-}
-
-//
-// Description:
-// Map dBm into Tx power index according to
-// current HW model, for example, RF and PA, and
-// current wireless mode.
-// use in phy only
-static u8 phy_DbmToTxPwrIdx(
- struct net_device* dev,
- WIRELESS_MODE WirelessMode,
- long PowerInDbm
- )
-{
- u8 TxPwrIdx = 0;
- long Offset = 0;
-
-
- //
- // Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to
- // 3dbm, and OFDM HT equals to 0dbm repectively.
- // Note:
- // The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
- //
- switch(WirelessMode)
- {
- case WIRELESS_MODE_B:
- Offset = -7;
- break;
-
- case WIRELESS_MODE_G:
- case WIRELESS_MODE_N_24G:
- Offset = -8;
- break;
- default:
- break;
- }
-
- if((PowerInDbm - Offset) > 0)
- {
- TxPwrIdx = (u8)((PowerInDbm - Offset) * 2);
- }
- else
- {
- TxPwrIdx = 0;
- }
-
- // Tx Power Index is too large.
- if(TxPwrIdx > MAX_TXPWR_IDX_NMODE_92S)
- TxPwrIdx = MAX_TXPWR_IDX_NMODE_92S;
-
- return TxPwrIdx;
-}
-//
-// Description:
-// Map Tx power index into dBm according to
-// current HW model, for example, RF and PA, and
-// current wireless mode.
-// use in phy only
-static long phy_TxPwrIdxToDbm(
- struct net_device* dev,
- WIRELESS_MODE WirelessMode,
- u8 TxPwrIdx
- )
-{
- //struct r8192_priv *priv = ieee80211_priv(dev);
- long Offset = 0;
- long PwrOutDbm = 0;
-
- //
- // Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to
- // 3dbm, and OFDM HT equals to 0dbm repectively.
- // Note:
- // The mapping may be different by different NICs. Do not use this formula for what needs accurate result.
- //
- switch(WirelessMode)
- {
- case WIRELESS_MODE_B:
- Offset = -7;
- break;
-
- case WIRELESS_MODE_G:
- case WIRELESS_MODE_N_24G:
- Offset = -8;
- break;
- default:
- break;
- }
-
- PwrOutDbm = TxPwrIdx / 2 + Offset; // Discard the decimal part.
-
- return PwrOutDbm;
-}
-
-#ifdef TO_DO_LIST
-extern VOID
-PHY_ScanOperationBackup8192S(
- IN PADAPTER Adapter,
- IN u1Byte Operation
- )
-{
-
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
- PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
- u4Byte BitMask;
- u1Byte initial_gain;
-
-
-
-
-
- if(!Adapter->bDriverStopped)
- {
- switch(Operation)
- {
- case SCAN_OPT_BACKUP:
- //
- // <Roger_Notes> We halt FW DIG and disable high ppower both two DMs here
- // and resume both two DMs while scan complete.
- // 2008.11.27.
- //
- Adapter->HalFunc.SetFwCmdHandler(Adapter, FW_CMD_PAUSE_DM_BY_SCAN);
- break;
-
- case SCAN_OPT_RESTORE:
- //
- // <Roger_Notes> We resume DIG and enable high power both two DMs here and
- // recover earlier DIG settings.
- // 2008.11.27.
- //
- Adapter->HalFunc.SetFwCmdHandler(Adapter, FW_CMD_RESUME_DM_BY_SCAN);
- break;
-
- default:
- RT_TRACE(COMP_SCAN, DBG_LOUD, ("Unknown Scan Backup Operation. \n"));
- break;
- }
- }
-}
-#endif
-
-//nouse temp
-void PHY_InitialGain8192S(struct net_device* dev,u8 Operation )
-{
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: SetBWModeCallback8190Pci()
- *
- * Overview: Timer callback function for SetSetBWMode
- *
- * Input: PRT_TIMER pTimer
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: (1) We do not take j mode into consideration now
- * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
- * concurrently?
- *---------------------------------------------------------------------------*/
-// use in phy only (in win it's timer)
-void PHY_SetBWModeCallback8192S(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 regBwOpMode;
-
- u8 regRRSR_RSC;
-
- RT_TRACE(COMP_SWBW, "==>SetBWModeCallback8190Pci() Switch to %s bandwidth\n", \
- priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
-
- if(priv->rf_chip == RF_PSEUDO_11N)
- {
- priv->SetBWModeInProgress= FALSE;
- return;
- }
-
- if(!priv->up)
- return;
-
-
- //3//
- //3//<1>Set MAC register
- //3//
- regBwOpMode = read_nic_byte(dev, BW_OPMODE);
- regRRSR_RSC = read_nic_byte(dev, RRSR+2);
-
- switch(priv->CurrentChannelBW)
- {
- case HT_CHANNEL_WIDTH_20:
-
- regBwOpMode |= BW_OPMODE_20MHZ;
- // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
-
- regBwOpMode &= ~BW_OPMODE_20MHZ;
- // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5);
- write_nic_byte(dev, RRSR+2, regRRSR_RSC);
- break;
-
- default:
- RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
- priv->CurrentChannelBW);
- break;
- }
-
- //3//
- //3//<2>Set PHY related register
- //3//
- switch(priv->CurrentChannelBW)
- {
- /* 20 MHz channel*/
- case HT_CHANNEL_WIDTH_20:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
-
- if (priv->card_8192_version >= VERSION_8192S_BCUT)
- write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
-
-
- break;
-
- /* 40 MHz channel*/
- case HT_CHANNEL_WIDTH_20_40:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
-
-
- // Set Control channel to upper or lower. These settings are required only for 40MHz
- rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
- rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
-
- if (priv->card_8192_version >= VERSION_8192S_BCUT)
- write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
-
- break;
-
- default:
- RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n"\
- ,priv->CurrentChannelBW);
- break;
-
- }
- //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
-
-
- //3<3>Set RF related register
- switch( priv->rf_chip )
- {
- case RF_8225:
- //PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
- break;
-
- case RF_8256:
- // Please implement this function in Hal8190PciPhy8256.c
- //PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
- break;
-
- case RF_8258:
- // Please implement this function in Hal8190PciPhy8258.c
- // PHY_SetRF8258Bandwidth();
- break;
-
- case RF_PSEUDO_11N:
- // Do Nothing
- break;
-
- case RF_6052:
- PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
- break;
- default:
- printk("Unknown rf_chip: %d\n", priv->rf_chip);
- break;
- }
-
- priv->SetBWModeInProgress= FALSE;
-
- RT_TRACE(COMP_SWBW, "<==SetBWModeCallback8190Pci() \n" );
-}
-
-
- /*-----------------------------------------------------------------------------
- * Function: SetBWMode8190Pci()
- *
- * Overview: This function is export to "HalCommon" moudule
- *
- * Input: PADAPTER Adapter
- * HT_CHANNEL_WIDTH Bandwidth //20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: We do not take j mode into consideration now
- *---------------------------------------------------------------------------*/
-void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- HT_CHANNEL_WIDTH tmpBW = priv->CurrentChannelBW;
-
- if(priv->SetBWModeInProgress)
- return;
-
- priv->SetBWModeInProgress= TRUE;
-
- priv->CurrentChannelBW = Bandwidth;
-
- if(Offset==HT_EXTCHNL_OFFSET_LOWER)
- priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
- else if(Offset==HT_EXTCHNL_OFFSET_UPPER)
- priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
- else
- priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- if((priv->up) )
- {
- SetBWModeCallback8192SUsbWorkItem(dev);
- }
- else
- {
- RT_TRACE(COMP_SCAN, "PHY_SetBWMode8192S() SetBWModeInProgress FALSE driver sleep or unload\n");
- priv->SetBWModeInProgress= FALSE;
- priv->CurrentChannelBW = tmpBW;
- }
-}
-
-// use in phy only (in win it's timer)
-void PHY_SwChnlCallback8192S(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 delay;
-
- RT_TRACE(COMP_CH, "==>SwChnlCallback8190Pci(), switch to channel %d\n", priv->chan);
-
- if(!priv->up)
- return;
-
- if(priv->rf_chip == RF_PSEUDO_11N)
- {
- priv->SwChnlInProgress=FALSE;
- return; //return immediately if it is peudo-phy
- }
-
- do{
- if(!priv->SwChnlInProgress)
- break;
-
- if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
- {
- if(delay>0)
- {
- mdelay(delay);
- }
- else
- continue;
- }
- else
- {
- priv->SwChnlInProgress=FALSE;
- break;
- }
- }while(true);
-}
-
-// Call after initialization
-u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if(!priv->up)
- return false;
-
- if(priv->SwChnlInProgress)
- return false;
-
- if(priv->SetBWModeInProgress)
- return false;
-
- switch(priv->ieee80211->mode)
- {
- case WIRELESS_MODE_A:
- case WIRELESS_MODE_N_5G:
- if (channel<=14){
- RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
- return false;
- }
- break;
-
- case WIRELESS_MODE_B:
- if (channel>14){
- RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
- return false;
- }
- break;
-
- case WIRELESS_MODE_G:
- case WIRELESS_MODE_N_24G:
- if (channel>14){
- RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
- return false;
- }
- break;
-
- default:
- ;
- break;
- }
-
- priv->SwChnlInProgress = TRUE;
- if( channel == 0)
- channel = 1;
-
- priv->chan=channel;
-
- priv->SwChnlStage=0;
- priv->SwChnlStep=0;
-
- if((priv->up))
- {
- SwChnlCallback8192SUsbWorkItem(dev);
-#ifdef TO_DO_LIST
- if(bResult)
- {
- RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress TRUE schdule workitem done\n");
- }
- else
- {
- RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress FALSE schdule workitem error\n");
- priv->SwChnlInProgress = false;
- priv->CurrentChannel = tmpchannel;
- }
-#endif
- }
- else
- {
- RT_TRACE(COMP_SCAN, "PHY_SwChnl8192S SwChnlInProgress FALSE driver sleep or unload\n");
- priv->SwChnlInProgress = false;
- }
- return true;
-}
-
-
-//
-// Description:
-// Switch channel synchronously. Called by SwChnlByDelayHandler.
-//
-// Implemented by Bruce, 2008-02-14.
-// The following procedure is operted according to SwChanlCallback8190Pci().
-// However, this procedure is performed synchronously which should be running under
-// passive level.
-
-void PHY_SwChnlPhy8192S( // Only called during initialize
- struct net_device* dev,
- u8 channel
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- RT_TRACE(COMP_SCAN, "==>PHY_SwChnlPhy8192S(), switch to channel %d.\n", priv->chan);
-
-#ifdef TO_DO_LIST
- // Cannot IO.
- if(RT_CANNOT_IO(dev))
- return;
-#endif
-
- // Channel Switching is in progress.
- if(priv->SwChnlInProgress)
- return;
-
- //return immediately if it is peudo-phy
- if(priv->rf_chip == RF_PSEUDO_11N)
- {
- priv->SwChnlInProgress=FALSE;
- return;
- }
-
- priv->SwChnlInProgress = TRUE;
- if( channel == 0)
- channel = 1;
-
- priv->chan=channel;
-
- priv->SwChnlStage = 0;
- priv->SwChnlStep = 0;
-
- phy_FinishSwChnlNow(dev,channel);
-
- priv->SwChnlInProgress = FALSE;
-}
-
-// use in phy only
-static bool
-phy_SetSwChnlCmdArray(
- SwChnlCmd* CmdTable,
- u32 CmdTableIdx,
- u32 CmdTableSz,
- SwChnlCmdID CmdID,
- u32 Para1,
- u32 Para2,
- u32 msDelay
- )
-{
- SwChnlCmd* pCmd;
-
- if(CmdTable == NULL)
- {
- return FALSE;
- }
- if(CmdTableIdx >= CmdTableSz)
- {
- return FALSE;
- }
-
- pCmd = CmdTable + CmdTableIdx;
- pCmd->CmdID = CmdID;
- pCmd->Para1 = Para1;
- pCmd->Para2 = Para2;
- pCmd->msDelay = msDelay;
-
- return TRUE;
-}
-
-// use in phy only
-static bool
-phy_SwChnlStepByStep(
- struct net_device* dev,
- u8 channel,
- u8 *stage,
- u8 *step,
- u32 *delay
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT];
- u32 PreCommonCmdCnt;
- SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT];
- u32 PostCommonCmdCnt;
- SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT];
- u32 RfDependCmdCnt;
- SwChnlCmd *CurrentCmd = NULL;
- u8 eRFPath;
-
- RT_TRACE(COMP_CH, "===========>%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
- if (!IsLegalChannel(priv->ieee80211, channel))
- {
- RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
- return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
- }
-
- // <1> Fill up pre common command.
- PreCommonCmdCnt = 0;
- phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
- CmdID_SetTxPowerLevel, 0, 0, 0);
- phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
- CmdID_End, 0, 0, 0);
-
- // <2> Fill up post common command.
- PostCommonCmdCnt = 0;
-
- phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
- CmdID_End, 0, 0, 0);
-
- // <3> Fill up RF dependent command.
- RfDependCmdCnt = 0;
- switch( priv->rf_chip )
- {
- case RF_8225:
- if (channel < 1 || channel > 14)
- RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
-
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_RF_WriteReg, rRfChannel, channel, 10);
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_End, 0, 0, 0);
- break;
-
- case RF_8256:
- if (channel < 1 || channel > 14)
- RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_RF_WriteReg, rRfChannel, channel, 10);
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_End, 0, 0, 0);
- break;
-
- case RF_6052:
- if (channel < 1 || channel > 14)
- RT_TRACE(COMP_ERR, "illegal channel for zebra:%d\n", channel);
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_RF_WriteReg, RF_CHNLBW, channel, 10);
- phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
- CmdID_End, 0, 0, 0);
- break;
-
- case RF_8258:
- break;
-
- default:
- return FALSE;
- break;
- }
-
-
- do{
- switch(*stage)
- {
- case 0:
- CurrentCmd=&PreCommonCmd[*step];
- break;
- case 1:
- CurrentCmd=&RfDependCmd[*step];
- break;
- case 2:
- CurrentCmd=&PostCommonCmd[*step];
- break;
- }
-
- if(CurrentCmd->CmdID==CmdID_End)
- {
- if((*stage)==2)
- {
- return TRUE;
- }
- else
- {
- (*stage)++;
- (*step)=0;
- continue;
- }
- }
-
- switch(CurrentCmd->CmdID)
- {
- case CmdID_SetTxPowerLevel:
- PHY_SetTxPowerLevel8192S(dev,channel);
- break;
- case CmdID_WritePortUlong:
- write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
- break;
- case CmdID_WritePortUshort:
- write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
- break;
- case CmdID_WritePortUchar:
- write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
- break;
- case CmdID_RF_WriteReg: // Only modify channel for the register now !!!!!
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
- // For new T65 RF 0222d register 0x18 bit 0-9 = channel number.
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f, (CurrentCmd->Para2));
- }
- break;
- default:
- break;
- }
-
- break;
- }while(TRUE);
-
- (*delay)=CurrentCmd->msDelay;
- (*step)++;
- RT_TRACE(COMP_CH, "<===========%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
- return FALSE;
-}
-
-//called PHY_SwChnlPhy8192S, SwChnlCallback8192SUsbWorkItem
-// use in phy only
-static void
-phy_FinishSwChnlNow( // We should not call this function directly
- struct net_device* dev,
- u8 channel
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 delay;
-
- while(!phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay))
- {
- if(delay>0)
- mdelay(delay);
- if(!priv->up)
- break;
- }
-}
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHYCheckIsLegalRfPath8190Pci()
- *
- * Overview: Check different RF type to execute legal judgement. If RF Path is illegal
- * We will return false.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/15/2007 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
-{
- bool rtValue = TRUE;
-
- // NOt check RF Path now.!
- return rtValue;
-
-} /* PHY_CheckIsLegalRfPath8192S */
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_IQCalibrate8192S()
- *
- * Overview: After all MAC/PHY/RF is configued. We must execute IQ calibration
- * to improve RF EVM!!?
- *
- * Input: IN PADAPTER pAdapter
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 10/07/2008 MHC Create. Document from SD3 RFSI Jenyu.
- *
- *---------------------------------------------------------------------------*/
- //called by InitializeAdapter8192SE
-void
-PHY_IQCalibrate( struct net_device* dev)
-{
- u32 i, reg;
- u32 old_value;
- long X, Y, TX0[4];
- u32 TXA[4];
-
- // 1. Check QFN68 or 64 92S (Read from EEPROM)
-
- //
- // 2. QFN 68
- //
- // For 1T2R IQK only now !!!
- for (i = 0; i < 10; i++)
- {
- // IQK
- rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05430);
- udelay(5);
- rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000800e4);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x80800000);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe40, bMaskDWord, 0x02140148);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe44, bMaskDWord, 0x681604a2);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe4c, bMaskDWord, 0x000028d1);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe60, bMaskDWord, 0x0214014d);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe64, bMaskDWord, 0x281608ba);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe6c, bMaskDWord, 0x000028d1);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000001);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000001);
- udelay(2000);
- rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05433);
- udelay(5);
- rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000000e4);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x0);
-
-
- reg = rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord);
-
- // Readback IQK value and rewrite
- if (!(reg&(BIT27|BIT28|BIT30|BIT31)))
- {
- old_value = (rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord) & 0x3FF);
-
- // Calibrate init gain for A path for TX0
- X = (rtl8192_QueryBBReg(dev, 0xe94, bMaskDWord) & 0x03FF0000)>>16;
- TXA[RF90_PATH_A] = (X * old_value)/0x100;
- reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
- reg = (reg & 0xFFFFFC00) | (u32)TXA[RF90_PATH_A];
- rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate init gain for C path for TX0
- Y = ( rtl8192_QueryBBReg(dev, 0xe9C, bMaskDWord) & 0x03FF0000)>>16;
- TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
- reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
- reg = (reg & 0xffc0ffff) |((u32) (TX0[RF90_PATH_C]&0x3F)<<16);
- rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
- reg = rtl8192_QueryBBReg(dev, 0xc94, bMaskDWord);
- reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
- rtl8192_setBBreg(dev, 0xc94, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate RX A and B for RX0
- reg = rtl8192_QueryBBReg(dev, 0xc14, bMaskDWord);
- X = (rtl8192_QueryBBReg(dev, 0xea4, bMaskDWord) & 0x03FF0000)>>16;
- reg = (reg & 0xFFFFFC00) |X;
- rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
- Y = (rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord) & 0x003F0000)>>16;
- reg = (reg & 0xFFFF03FF) |Y<<10;
- rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
- udelay(5);
- old_value = (rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord) & 0x3FF);
-
- // Calibrate init gain for A path for TX1 !!!!!!
- X = (rtl8192_QueryBBReg(dev, 0xeb4, bMaskDWord) & 0x03FF0000)>>16;
- reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
- TXA[RF90_PATH_A] = (X * old_value) / 0x100;
- reg = (reg & 0xFFFFFC00) | TXA[RF90_PATH_A];
- rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate init gain for C path for TX1
- Y = (rtl8192_QueryBBReg(dev, 0xebc, bMaskDWord)& 0x03FF0000)>>16;
- TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
- reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
- reg = (reg & 0xffc0ffff) |( (TX0[RF90_PATH_C]&0x3F)<<16);
- rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
- reg = rtl8192_QueryBBReg(dev, 0xc9c, bMaskDWord);
- reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
- rtl8192_setBBreg(dev, 0xc9c, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate RX A and B for RX1
- reg = rtl8192_QueryBBReg(dev, 0xc1c, bMaskDWord);
- X = (rtl8192_QueryBBReg(dev, 0xec4, bMaskDWord) & 0x03FF0000)>>16;
- reg = (reg & 0xFFFFFC00) |X;
- rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
-
- Y = (rtl8192_QueryBBReg(dev, 0xecc, bMaskDWord) & 0x003F0000)>>16;
- reg = (reg & 0xFFFF03FF) |Y<<10;
- rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
- udelay(5);
-
- RT_TRACE(COMP_INIT, "PHY_IQCalibrate OK\n");
- break;
- }
-
- }
-
-
- //
- // 3. QFN64. Not enabled now !!! We must use different gain table for 1T2R.
- //
-
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_IQCalibrateBcut()
- *
- * Overview: After all MAC/PHY/RF is configued. We must execute IQ calibration
- * to improve RF EVM!!?
- *
- * Input: IN PADAPTER pAdapter
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/18/2008 MHC Create. Document from SD3 RFSI Jenyu.
- * 92S B-cut QFN 68 pin IQ calibration procedure.doc
- *
- *---------------------------------------------------------------------------*/
-extern void PHY_IQCalibrateBcut(struct net_device* dev)
-{
- u32 i, reg;
- u32 old_value;
- long X, Y, TX0[4];
- u32 TXA[4];
- u32 calibrate_set[13] = {0};
- u32 load_value[13];
- u8 RfPiEnable=0;
-
- // 0. Check QFN68 or 64 92S (Read from EEPROM/EFUSE)
-
- //
- // 1. Save e70~ee0 register setting, and load calibration setting
- //
- calibrate_set [0] = 0xee0;
- calibrate_set [1] = 0xedc;
- calibrate_set [2] = 0xe70;
- calibrate_set [3] = 0xe74;
- calibrate_set [4] = 0xe78;
- calibrate_set [5] = 0xe7c;
- calibrate_set [6] = 0xe80;
- calibrate_set [7] = 0xe84;
- calibrate_set [8] = 0xe88;
- calibrate_set [9] = 0xe8c;
- calibrate_set [10] = 0xed0;
- calibrate_set [11] = 0xed4;
- calibrate_set [12] = 0xed8;
- for (i = 0; i < 13; i++)
- {
- load_value[i] = rtl8192_QueryBBReg(dev, calibrate_set[i], bMaskDWord);
- rtl8192_setBBreg(dev, calibrate_set[i], bMaskDWord, 0x3fed92fb);
-
- }
-
- RfPiEnable = (u8)rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter1, BIT8);
-
- //
- // 2. QFN 68
- //
- // For 1T2R IQK only now !!!
- for (i = 0; i < 10; i++)
- {
- RT_TRACE(COMP_INIT, "IQK -%d\n", i);
- //BB switch to PI mode. If default is PI mode, ignoring 2 commands below.
- if (!RfPiEnable) //if original is SI mode, then switch to PI mode.
- {
- rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000100);
- rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000100);
- }
-
- // IQK
- // 2. IQ calibration & LO leakage calibration
- rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05430);
- udelay(5);
- rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000800e4);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x80800000);
- udelay(5);
- //path-A IQ K and LO K gain setting
- rtl8192_setBBreg(dev, 0xe40, bMaskDWord, 0x02140102);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe44, bMaskDWord, 0x681604c2);
- udelay(5);
- //set LO calibration
- rtl8192_setBBreg(dev, 0xe4c, bMaskDWord, 0x000028d1);
- udelay(5);
- //path-B IQ K and LO K gain setting
- rtl8192_setBBreg(dev, 0xe60, bMaskDWord, 0x02140102);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe64, bMaskDWord, 0x28160d05);
- udelay(5);
- //K idac_I & IQ
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000000);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000000);
- udelay(5);
-
- // delay 2ms
- udelay(2000);
-
- //idac_Q setting
- rtl8192_setBBreg(dev, 0xe6c, bMaskDWord, 0x020028d1);
- udelay(5);
- //K idac_Q & IQ
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xfb000000);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe48, bMaskDWord, 0xf8000000);
-
- // delay 2ms
- udelay(2000);
-
- rtl8192_setBBreg(dev, 0xc04, bMaskDWord, 0x00a05433);
- udelay(5);
- rtl8192_setBBreg(dev, 0xc08, bMaskDWord, 0x000000e4);
- udelay(5);
- rtl8192_setBBreg(dev, 0xe28, bMaskDWord, 0x0);
-
- if (!RfPiEnable) //if original is SI mode, then switch to PI mode.
- {
- rtl8192_setBBreg(dev, 0x820, bMaskDWord, 0x01000000);
- rtl8192_setBBreg(dev, 0x828, bMaskDWord, 0x01000000);
- }
-
-
- reg = rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord);
-
- // 3. check fail bit, and fill BB IQ matrix
- // Readback IQK value and rewrite
- if (!(reg&(BIT27|BIT28|BIT30|BIT31)))
- {
- old_value = (rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord) & 0x3FF);
-
- // Calibrate init gain for A path for TX0
- X = (rtl8192_QueryBBReg(dev, 0xe94, bMaskDWord) & 0x03FF0000)>>16;
- TXA[RF90_PATH_A] = (X * old_value)/0x100;
- reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
- reg = (reg & 0xFFFFFC00) | (u32)TXA[RF90_PATH_A];
- rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate init gain for C path for TX0
- Y = ( rtl8192_QueryBBReg(dev, 0xe9C, bMaskDWord) & 0x03FF0000)>>16;
- TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
- reg = rtl8192_QueryBBReg(dev, 0xc80, bMaskDWord);
- reg = (reg & 0xffc0ffff) |((u32) (TX0[RF90_PATH_C]&0x3F)<<16);
- rtl8192_setBBreg(dev, 0xc80, bMaskDWord, reg);
- reg = rtl8192_QueryBBReg(dev, 0xc94, bMaskDWord);
- reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
- rtl8192_setBBreg(dev, 0xc94, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate RX A and B for RX0
- reg = rtl8192_QueryBBReg(dev, 0xc14, bMaskDWord);
- X = (rtl8192_QueryBBReg(dev, 0xea4, bMaskDWord) & 0x03FF0000)>>16;
- reg = (reg & 0xFFFFFC00) |X;
- rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
- Y = (rtl8192_QueryBBReg(dev, 0xeac, bMaskDWord) & 0x003F0000)>>16;
- reg = (reg & 0xFFFF03FF) |Y<<10;
- rtl8192_setBBreg(dev, 0xc14, bMaskDWord, reg);
- udelay(5);
- old_value = (rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord) & 0x3FF);
-
- // Calibrate init gain for A path for TX1 !!!!!!
- X = (rtl8192_QueryBBReg(dev, 0xeb4, bMaskDWord) & 0x03FF0000)>>16;
- reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
- TXA[RF90_PATH_A] = (X * old_value) / 0x100;
- reg = (reg & 0xFFFFFC00) | TXA[RF90_PATH_A];
- rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate init gain for C path for TX1
- Y = (rtl8192_QueryBBReg(dev, 0xebc, bMaskDWord)& 0x03FF0000)>>16;
- TX0[RF90_PATH_C] = ((Y * old_value)/0x100);
- reg = rtl8192_QueryBBReg(dev, 0xc88, bMaskDWord);
- reg = (reg & 0xffc0ffff) |( (TX0[RF90_PATH_C]&0x3F)<<16);
- rtl8192_setBBreg(dev, 0xc88, bMaskDWord, reg);
- reg = rtl8192_QueryBBReg(dev, 0xc9c, bMaskDWord);
- reg = (reg & 0x0fffffff) |(((Y&0x3c0)>>6)<<28);
- rtl8192_setBBreg(dev, 0xc9c, bMaskDWord, reg);
- udelay(5);
-
- // Calibrate RX A and B for RX1
- reg = rtl8192_QueryBBReg(dev, 0xc1c, bMaskDWord);
- X = (rtl8192_QueryBBReg(dev, 0xec4, bMaskDWord) & 0x03FF0000)>>16;
- reg = (reg & 0xFFFFFC00) |X;
- rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
-
- Y = (rtl8192_QueryBBReg(dev, 0xecc, bMaskDWord) & 0x003F0000)>>16;
- reg = (reg & 0xFFFF03FF) |Y<<10;
- rtl8192_setBBreg(dev, 0xc1c, bMaskDWord, reg);
- udelay(5);
-
- RT_TRACE(COMP_INIT, "PHY_IQCalibrate OK\n");
- break;
- }
-
- }
-
- //
- // 4. Reload e70~ee0 register setting.
- //
- for (i = 0; i < 13; i++)
- rtl8192_setBBreg(dev, calibrate_set[i], bMaskDWord, load_value[i]);
-
-
- //
- // 3. QFN64. Not enabled now !!! We must use different gain table for 1T2R.
- //
-
-
-
-}
-
-
-//
-// Move from phycfg.c to gen.c to be code independent later
-//
-
-// use in phy only (in win it's timer)
-void SwChnlCallback8192SUsb(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 delay;
-
- RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
- priv->chan);
-
-
- if(!priv->up)
- return;
-
- if(priv->rf_chip == RF_PSEUDO_11N)
- {
- priv->SwChnlInProgress=FALSE;
- return; //return immediately if it is peudo-phy
- }
-
- do{
- if(!priv->SwChnlInProgress)
- break;
-
- if(!phy_SwChnlStepByStep(dev, priv->chan, &priv->SwChnlStage, &priv->SwChnlStep, &delay))
- {
- if(delay>0)
- {
-
- }
- else
- continue;
- }
- else
- {
- priv->SwChnlInProgress=FALSE;
- }
- break;
- }while(TRUE);
-}
-
-
-//
-// Callback routine of the work item for switch channel.
-//
-// use in phy only (in win it's work)
-void SwChnlCallback8192SUsbWorkItem(struct net_device *dev )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- RT_TRACE(COMP_TRACE, "==> SwChnlCallback8192SUsbWorkItem()\n");
-#ifdef TO_DO_LIST
- if(pAdapter->bInSetPower && RT_USB_CANNOT_IO(pAdapter))
- {
- RT_TRACE(COMP_SCAN, DBG_LOUD, ("<== SwChnlCallback8192SUsbWorkItem() SwChnlInProgress FALSE driver sleep or unload\n"));
-
- pHalData->SwChnlInProgress = FALSE;
- return;
- }
-#endif
- phy_FinishSwChnlNow(dev, priv->chan);
- priv->SwChnlInProgress = FALSE;
-
- RT_TRACE(COMP_TRACE, "<== SwChnlCallback8192SUsbWorkItem()\n");
-}
-
-
-/*-----------------------------------------------------------------------------
- * Function: SetBWModeCallback8192SUsb()
- *
- * Overview: Timer callback function for SetSetBWMode
- *
- * Input: PRT_TIMER pTimer
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: (1) We do not take j mode into consideration now
- * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run
- * concurrently?
- *---------------------------------------------------------------------------*/
-// use in phy only
-void SetBWModeCallback8192SUsb(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 regBwOpMode;
-
- u8 regRRSR_RSC;
-
- RT_TRACE(COMP_SCAN, "==>SetBWModeCallback8190Pci() Switch to %s bandwidth\n", \
- priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz");
-
- if(priv->rf_chip == RF_PSEUDO_11N)
- {
- priv->SetBWModeInProgress= FALSE;
- return;
- }
-
- if(!priv->up)
- return;
-
-
- //3<1>Set MAC register
- regBwOpMode = read_nic_byte(dev, BW_OPMODE);
- regRRSR_RSC = read_nic_byte(dev, RRSR+2);
-
- switch(priv->CurrentChannelBW)
- {
- case HT_CHANNEL_WIDTH_20:
- regBwOpMode |= BW_OPMODE_20MHZ;
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- break;
-
- case HT_CHANNEL_WIDTH_20_40:
- regBwOpMode &= ~BW_OPMODE_20MHZ;
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
-
- regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5);
- write_nic_byte(dev, RRSR+2, regRRSR_RSC);
- break;
-
- default:
- RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
- priv->CurrentChannelBW);
- break;
- }
-
- //3 <2>Set PHY related register
- switch(priv->CurrentChannelBW)
- {
- case HT_CHANNEL_WIDTH_20:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
-
- if (priv->card_8192_version >= VERSION_8192S_BCUT)
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
-
- break;
- case HT_CHANNEL_WIDTH_20_40:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
- rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
- rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
-
- if (priv->card_8192_version >= VERSION_8192S_BCUT)
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
-
- break;
- default:
- RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n"\
- ,priv->CurrentChannelBW);
- break;
-
- }
- //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
-
-#if 1
- //3<3>Set RF related register
- switch( priv->rf_chip )
- {
- case RF_8225:
- PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
- break;
-
- case RF_8256:
- // Please implement this function in Hal8190PciPhy8256.c
- //PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
- break;
-
- case RF_6052:
- PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
- break;
-
- case RF_8258:
- // Please implement this function in Hal8190PciPhy8258.c
- // PHY_SetRF8258Bandwidth();
- break;
-
- case RF_PSEUDO_11N:
- // Do Nothing
- break;
-
- default:
- break;
- }
-#endif
- priv->SetBWModeInProgress= FALSE;
-
- RT_TRACE(COMP_SCAN, "<==SetBWMode8190Pci()" );
-}
-
-/*
- * Callback routine of the work item for set bandwidth mode.
- *
- * use in phy only (in win it's work)
- */
-void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 regBwOpMode;
- u8 regRRSR_RSC;
-
- RT_TRACE(COMP_SCAN, "%s(): Switch to %s bandwidth", __func__,
- priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ? "20MHz" : "40MHz");
-
- if (priv->rf_chip == RF_PSEUDO_11N) {
- priv->SetBWModeInProgress= FALSE;
- return;
- }
- if(!priv->up)
- return;
- /* Set MAC register */
- regBwOpMode = read_nic_byte(dev, BW_OPMODE);
- regRRSR_RSC = read_nic_byte(dev, RRSR+2);
- switch (priv->CurrentChannelBW) {
- case HT_CHANNEL_WIDTH_20:
- regBwOpMode |= BW_OPMODE_20MHZ;
- /* we have not verified whether this register works */
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- regBwOpMode &= ~BW_OPMODE_20MHZ;
- /* we have not verified whether this register works */
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- regRRSR_RSC = (regRRSR_RSC&0x90) | (priv->nCur40MhzPrimeSC<<5);
- write_nic_byte(dev, RRSR+2, regRRSR_RSC);
- break;
- default:
- RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__,
- priv->CurrentChannelBW);
- break;
- }
- /* Set PHY related register */
- switch (priv->CurrentChannelBW) {
- case HT_CHANNEL_WIDTH_20:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
- rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
- /*
- * Set Control channel to upper or lower.
- * These settings are required only for 40MHz
- */
- rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand,
- (priv->nCur40MhzPrimeSC>>1));
- rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00,
- priv->nCur40MhzPrimeSC);
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
- break;
- default:
- RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__,
- priv->CurrentChannelBW);
- break;
-
- }
- /*
- * Skip over setting of J-mode in BB register here.
- * Default value is "None J mode".
- */
-
- /* Set RF related register */
- switch (priv->rf_chip) {
- case RF_8225:
- PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW);
- break;
- case RF_8256:
- /* Please implement this function in Hal8190PciPhy8256.c */
- /* PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); */
- break;
- case RF_6052:
- PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW);
- break;
- case RF_8258:
- /* Please implement this function in Hal8190PciPhy8258.c */
- /* PHY_SetRF8258Bandwidth(); */
- break;
- case RF_PSEUDO_11N:
- /* Do Nothing */
- break;
- default:
- RT_TRACE(COMP_DBG, "%s(): unknown rf_chip: %d", __func__,
- priv->rf_chip);
- break;
- }
- priv->SetBWModeInProgress= FALSE;
-}
-
-void InitialGain8192S(struct net_device *dev, u8 Operation)
-{
-#ifdef TO_DO_LIST
- struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
-
-}
-
-void InitialGain819xUsb(struct net_device *dev, u8 Operation)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->InitialGainOperateType = Operation;
-
- if(priv->up)
- {
- queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
- }
-}
-
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
- struct net_device *dev = priv->ieee80211->dev;
-#define SCAN_RX_INITIAL_GAIN 0x17
-#define POWER_DETECTION_TH 0x08
- u32 BitMask;
- u8 initial_gain;
- u8 Operation;
-
- Operation = priv->InitialGainOperateType;
-
- switch(Operation)
- {
- case IG_Backup:
- RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
- initial_gain = SCAN_RX_INITIAL_GAIN;//priv->DefaultInitialGain[0];//
- BitMask = bMaskByte0;
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
- priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
- priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
- priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
- priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
- BitMask = bMaskByte2;
- priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
-
- RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
- RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
- RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
- RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
- RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
-
- RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
- write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
- RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
- write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
- break;
- case IG_Restore:
- RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
- BitMask = 0x7f; //Bit0~ Bit6
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF
-
- rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
- BitMask = bMaskByte2;
- rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
-
- RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
- RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
- RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
- RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
- RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
-
- PHY_SetTxPowerLevel8192S(dev,priv->ieee80211->current_network.channel);
-
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON
- break;
- default:
- RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
- break;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Description:
-// Schedule workitem to send specific CMD IO to FW.
-// Added by Roger, 2008.12.03.
-//
-//-----------------------------------------------------------------------------
-bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE FwCmdIO)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 FwCmdWaitCounter = 0;
-
- u16 FwCmdWaitLimit = 1000;
-
- if(priv->bInHctTest)
- return true;
-
- RT_TRACE(COMP_CMD, "-->HalSetFwCmd8192S(): Set FW Cmd(%x), SetFwCmdInProgress(%d)\n", (u32)FwCmdIO, priv->SetFwCmdInProgress);
-
- // Will be done by high power respectively.
- if(FwCmdIO==FW_CMD_DIG_HALT || FwCmdIO==FW_CMD_DIG_RESUME)
- {
- RT_TRACE(COMP_CMD, "<--HalSetFwCmd8192S(): Set FW Cmd(%x)\n", (u32)FwCmdIO);
- return false;
- }
-
-#if 1
- while(priv->SetFwCmdInProgress && FwCmdWaitCounter<FwCmdWaitLimit)
- {
-
- RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): previous workitem not finish!!\n");
- return false;
- FwCmdWaitCounter ++;
- RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait 10 ms (%d times)...\n", FwCmdWaitCounter);
- udelay(100);
- }
-
- if(FwCmdWaitCounter == FwCmdWaitLimit)
- {
- RT_TRACE(COMP_CMD, "HalSetFwCmd8192S(): Wait too logn to set FW CMD\n");
- }
-#endif
- if (priv->SetFwCmdInProgress)
- {
- RT_TRACE(COMP_ERR, "<--HalSetFwCmd8192S(): Set FW Cmd(%#x)\n", FwCmdIO);
- return false;
- }
- priv->SetFwCmdInProgress = TRUE;
- priv->CurrentFwCmdIO = FwCmdIO; // Update current FW Cmd for callback use.
-
- phy_SetFwCmdIOCallback(dev);
- return true;
-}
-void ChkFwCmdIoDone(struct net_device* dev)
-{
- u16 PollingCnt = 1000;
- u32 tmpValue;
-
- do
- {// Make sure that CMD IO has be accepted by FW.
-#ifdef TO_DO_LIST
- if(RT_USB_CANNOT_IO(Adapter))
- {
- RT_TRACE(COMP_CMD, "ChkFwCmdIoDone(): USB can NOT IO!!\n");
- return;
- }
-#endif
- udelay(10); // sleep 20us
- tmpValue = read_nic_dword(dev, WFM5);
- if(tmpValue == 0)
- {
- RT_TRACE(COMP_CMD, "[FW CMD] Set FW Cmd success!!\n");
- break;
- }
- else
- {
- RT_TRACE(COMP_CMD, "[FW CMD] Polling FW Cmd PollingCnt(%d)!!\n", PollingCnt);
- }
- }while( --PollingCnt );
-
- if(PollingCnt == 0)
- {
- RT_TRACE(COMP_ERR, "[FW CMD] Set FW Cmd fail!!\n");
- }
-}
-// Callback routine of the timer callback for FW Cmd IO.
-//
-// Description:
-// This routine will send specific CMD IO to FW and check whether it is done.
-//
-void phy_SetFwCmdIOCallback(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
- rt_firmware *pFirmware = priv->pFirmware;
- u32 input, CurrentAID = 0;;
- if(!priv->up)
- {
- RT_TRACE(COMP_CMD, "SetFwCmdIOTimerCallback(): driver is going to unload\n");
- return;
- }
-
- RT_TRACE(COMP_CMD, "--->SetFwCmdIOTimerCallback(): Cmd(%#x), SetFwCmdInProgress(%d)\n", priv->CurrentFwCmdIO, priv->SetFwCmdInProgress);
-
- if(pFirmware->FirmwareVersion >= 0x34)
- {
- switch(priv->CurrentFwCmdIO)
- {
- case FW_CMD_RA_REFRESH_N:
- priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_N_COMB;
- break;
- case FW_CMD_RA_REFRESH_BG:
- priv->CurrentFwCmdIO = FW_CMD_RA_REFRESH_BG_COMB;
- break;
- default:
- break;
- }
- }
- switch(priv->CurrentFwCmdIO)
- {
-
- case FW_CMD_RA_RESET:
- write_nic_dword(dev, WFM5, FW_RA_RESET);
- break;
-
- case FW_CMD_RA_ACTIVE:
- write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
- break;
-
- case FW_CMD_RA_REFRESH_N:
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA n refresh!!\n");
- if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
- input = FW_RA_REFRESH;
- else
- input = FW_RA_REFRESH | (pHTInfo->IOTRaFunc << 8);
- write_nic_dword(dev, WFM5, input);
- ChkFwCmdIoDone(dev);
- write_nic_dword(dev, WFM5, FW_RA_ENABLE_RSSI_MASK);
- ChkFwCmdIoDone(dev);
- break;
- case FW_CMD_RA_REFRESH_BG:
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA BG refresh!!\n");
- write_nic_dword(dev, WFM5, FW_RA_REFRESH);
- ChkFwCmdIoDone(dev);
- write_nic_dword(dev, WFM5, FW_RA_DISABLE_RSSI_MASK);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_RA_REFRESH_N_COMB:
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA n Combo refresh!!\n");
- if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
- input = FW_RA_IOT_N_COMB;
- else
- input = FW_RA_IOT_N_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
- input = input |((pHTInfo->IOTPeer & 0xf) <<12);
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in n mode!! input(%#x)\n", input);
- write_nic_dword(dev, WFM5, input);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_RA_REFRESH_BG_COMB:
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA B/G Combo refresh!!\n");
- if(pHTInfo->IOTRaFunc & HT_IOT_RAFUNC_DISABLE_ALL)
- input = FW_RA_IOT_BG_COMB;
- else
- input = FW_RA_IOT_BG_COMB | (((pHTInfo->IOTRaFunc)&0x0f) << 8);
- input = input |((pHTInfo->IOTPeer & 0xf) <<12);
- RT_TRACE(COMP_CMD, "[FW CMD] Set RA/IOT Comb in B/G mode!! input(%#x)\n", input);
- write_nic_dword(dev, WFM5, input);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_IQK_ENABLE:
- write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_TXPWR_TRACK_ENABLE:
- write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_ENABLE);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_TXPWR_TRACK_DISABLE:
- write_nic_dword(dev, WFM5, FW_TXPWR_TRACK_DISABLE);
- ChkFwCmdIoDone(dev);
- break;
-
- case FW_CMD_PAUSE_DM_BY_SCAN:
- RT_TRACE(COMP_CMD,"[FW CMD] Pause DM by Scan!!\n");
- rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
- rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
- rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
- break;
-
- case FW_CMD_RESUME_DM_BY_SCAN:
- RT_TRACE(COMP_CMD, "[FW CMD] Resume DM by Scan!!\n");
- rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
- PHY_SetTxPowerLevel8192S(dev, priv->chan);
- break;
- case FW_CMD_HIGH_PWR_DISABLE:
- RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Disable!!\n");
- if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
- break;
- rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bMaskByte0, 0x17);
- rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bMaskByte0, 0x17);
- rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x40);
- break;
-
- case FW_CMD_HIGH_PWR_ENABLE:
- RT_TRACE(COMP_CMD, "[FW CMD] High Pwr Enable!!\n");
- if(priv->DMFlag & HAL_DM_HIPWR_DISABLE)
- break;
- rtl8192_setBBreg(dev, rCCK0_CCA, bMaskByte2, 0x83);
- break;
-
- case FW_CMD_LPS_ENTER:
- RT_TRACE(COMP_CMD, "[FW CMD] Enter LPS mode!!\n");
- CurrentAID = priv->ieee80211->assoc_id;
- write_nic_dword(dev, WFM5, (FW_LPS_ENTER| ((CurrentAID|0xc000)<<8)) );
- ChkFwCmdIoDone(dev);
- pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
- break;
-
- case FW_CMD_LPS_LEAVE:
- RT_TRACE(COMP_CMD, "[FW CMD] Leave LPS mode!!\n");
- write_nic_dword(dev, WFM5, FW_LPS_LEAVE );
- ChkFwCmdIoDone(dev);
- pHTInfo->IOTAction &= (~HT_IOT_ACT_DISABLE_EDCA_TURBO);
- break;
-
- default:
- break;
- }
-
- priv->SetFwCmdInProgress = false;
- RT_TRACE(COMP_CMD, "<---SetFwCmdIOWorkItemCallback()\n");
-
-}
-
diff --git a/drivers/staging/rtl8192su/r8192S_phy.h b/drivers/staging/rtl8192su/r8192S_phy.h
deleted file mode 100644
index b752fa35a7ae..000000000000
--- a/drivers/staging/rtl8192su/r8192S_phy.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*****************************************************************************
- * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved.
- *
- * Module: __INC_HAL8192SPHYCFG_H
- *
- *
- * Note:
- *
- *
- * Export: Constants, macro, functions(API), global variables(None).
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h.
- * 2. Reorganize code architecture.
- *
- *****************************************************************************/
- /* Check to see if the file has been included already. */
-#ifndef _R8192S_PHY_H
-#define _R8192S_PHY_H
-
-
-/*--------------------------Define Parameters-------------------------------*/
-#define LOOP_LIMIT 5
-#define MAX_STALL_TIME 50 //us
-#define AntennaDiversityValue 0x80 //(dev->bSoftwareAntennaDiversity ? 0x00:0x80)
-#define MAX_TXPWR_IDX_NMODE_92S 63
-
-//#define delay_ms(_t) PlatformStallExecution(1000*(_t))
-//#define delay_us(_t) PlatformStallExecution(_t)
-
-/* Channel switch:The size of command tables for switch channel*/
-#define MAX_PRECMD_CNT 16
-#define MAX_RFDEPENDCMD_CNT 16
-#define MAX_POSTCMD_CNT 16
-
-
-/*------------------------------Define structure----------------------------*/
-typedef enum _SwChnlCmdID{
- CmdID_End,
- CmdID_SetTxPowerLevel,
- CmdID_BBRegWrite10,
- CmdID_WritePortUlong,
- CmdID_WritePortUshort,
- CmdID_WritePortUchar,
- CmdID_RF_WriteReg,
-}SwChnlCmdID;
-
-
-/* 1. Switch channel related */
-typedef struct _SwChnlCmd{
- SwChnlCmdID CmdID;
- u32 Para1;
- u32 Para2;
- u32 msDelay;
-}__attribute__ ((packed)) SwChnlCmd;
-
-extern u32 rtl819XMACPHY_Array_PG[];
-extern u32 rtl819XPHY_REG_1T2RArray[];
-extern u32 rtl819XAGCTAB_Array[];
-extern u32 rtl819XRadioA_Array[];
-extern u32 rtl819XRadioB_Array[];
-extern u32 rtl819XRadioC_Array[];
-extern u32 rtl819XRadioD_Array[];
-
-typedef enum _HW90_BLOCK{
- HW90_BLOCK_MAC = 0,
- HW90_BLOCK_PHY0 = 1,
- HW90_BLOCK_PHY1 = 2,
- HW90_BLOCK_RF = 3,
- HW90_BLOCK_MAXIMUM = 4, // Never use this
-}HW90_BLOCK_E, *PHW90_BLOCK_E;
-
-typedef enum _RF90_RADIO_PATH{
- RF90_PATH_A = 0, //Radio Path A
- RF90_PATH_B = 1, //Radio Path B
- RF90_PATH_C = 2, //Radio Path C
- RF90_PATH_D = 3, //Radio Path D
- RF90_PATH_MAX = 4, //Max RF number 90 support
-}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
-
-#define bMaskByte0 0xff
-#define bMaskByte1 0xff00
-#define bMaskByte2 0xff0000
-#define bMaskByte3 0xff000000
-#define bMaskHWord 0xffff0000
-#define bMaskLWord 0x0000ffff
-#define bMaskDWord 0xffffffff
-
-typedef enum _VERSION_8190{
- // RTL8190
- VERSION_8190_BD=0x3,
- VERSION_8190_BE
-}VERSION_8190,*PVERSION_8190;
-
-//
-// BB and RF register read/write
-//
-
-extern u32 rtl8192_QueryBBReg(struct net_device* dev,u32 RegAddr, u32 BitMask);
-extern void rtl8192_setBBreg(struct net_device* dev,u32 RegAddr, u32 BitMask,u32 Data);
-extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
-extern void rtl8192_phy_SetRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath, u32 RegAddr,u32 BitMask,u32 Data);
-
-bool rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
-
-
-/* MAC/BB/RF HAL config */
-extern bool PHY_MACConfig8192S(struct net_device* dev);
-extern bool PHY_BBConfig8192S(struct net_device* dev);
-extern bool PHY_RFConfig8192S(struct net_device* dev);
-
-extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev,RF90_RADIO_PATH_E eRFPath);
-extern void rtl8192_SetBWMode(struct net_device* dev,HT_CHANNEL_WIDTH ChnlWidth,HT_EXTCHNL_OFFSET Offset );
-extern u8 rtl8192_phy_SwChnl(struct net_device* dev,u8 channel);
-extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev,u32 eRFPath );
-extern void rtl8192_BBConfig(struct net_device* dev);
-extern void PHY_IQCalibrateBcut(struct net_device* dev);
-extern void PHY_IQCalibrate(struct net_device* dev);
-extern void PHY_GetHWRegOriginalValue(struct net_device* dev);
-
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work);
-
-void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8 channel);
-void PHY_InitialGain8192S(struct net_device* dev,u8 Operation );
-
-/*--------------------------Exported Function prototype---------------------*/
-bool HalSetFwCmd8192S(struct net_device* dev, FW_CMD_IO_TYPE FwCmdIO);
-extern void PHY_SetBeaconHwReg( struct net_device* dev, u16 BeaconInterval);
-void ChkFwCmdIoDone(struct net_device* dev);
-
-#endif // __INC_HAL8192SPHYCFG_H
-
diff --git a/drivers/staging/rtl8192su/r8192S_phyreg.h b/drivers/staging/rtl8192su/r8192S_phyreg.h
deleted file mode 100644
index 2e4d76d196aa..000000000000
--- a/drivers/staging/rtl8192su/r8192S_phyreg.h
+++ /dev/null
@@ -1,1033 +0,0 @@
-/*****************************************************************************
- * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved.
- *
- * Module: __INC_HAL8192SPHYREG_H
- *
- *
- * Note: 1. Define PMAC/BB register map
- * 2. Define RF register map
- * 3. PMAC/BB register bit mask.
- * 4. RF reg bit mask.
- * 5. Other BB/RF relative definition.
- *
- *
- * Export: Constants, macro, functions(API), global variables(None).
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h.
- * 2. Reorganize code architecture.
- * 09/25/2008 MH 1. Add RL6052 register definition
- *
- *****************************************************************************/
-#ifndef __INC_HAL8192SPHYREG_H
-#define __INC_HAL8192SPHYREG_H
-
-
-/*--------------------------Define Parameters-------------------------------*/
-
-//============================================================
-// 8192S Regsiter offset definition
-//============================================================
-
-//
-// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF
-// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
-// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00
-// 3. RF register 0x00-2E
-// 4. Bit Mask for BB/RF register
-// 5. Other definition for BB/RF R/W
-//
-
-
-//
-// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
-// 1. Page1(0x100)
-//
-#define rPMAC_Reset 0x100
-#define rPMAC_TxStart 0x104
-#define rPMAC_TxLegacySIG 0x108
-#define rPMAC_TxHTSIG1 0x10c
-#define rPMAC_TxHTSIG2 0x110
-#define rPMAC_PHYDebug 0x114
-#define rPMAC_TxPacketNum 0x118
-#define rPMAC_TxIdle 0x11c
-#define rPMAC_TxMACHeader0 0x120
-#define rPMAC_TxMACHeader1 0x124
-#define rPMAC_TxMACHeader2 0x128
-#define rPMAC_TxMACHeader3 0x12c
-#define rPMAC_TxMACHeader4 0x130
-#define rPMAC_TxMACHeader5 0x134
-#define rPMAC_TxDataType 0x138
-#define rPMAC_TxRandomSeed 0x13c
-#define rPMAC_CCKPLCPPreamble 0x140
-#define rPMAC_CCKPLCPHeader 0x144
-#define rPMAC_CCKCRC16 0x148
-#define rPMAC_OFDMRxCRC32OK 0x170
-#define rPMAC_OFDMRxCRC32Er 0x174
-#define rPMAC_OFDMRxParityEr 0x178
-#define rPMAC_OFDMRxCRC8Er 0x17c
-#define rPMAC_CCKCRxRC16Er 0x180
-#define rPMAC_CCKCRxRC32Er 0x184
-#define rPMAC_CCKCRxRC32OK 0x188
-#define rPMAC_TxStatus 0x18c
-
-//
-// 2. Page2(0x200)
-//
-// The following two definition are only used for USB interface.
-#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address.
-#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data.
-
-//
-// 3. Page8(0x800)
-//
-#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting??
-
-#define rFPGA0_TxInfo 0x804 // Status report??
-#define rFPGA0_PSDFunction 0x808
-
-#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain?
-
-#define rFPGA0_RFTiming1 0x810 // Useless now
-#define rFPGA0_RFTiming2 0x814
-//#define rFPGA0_XC_RFTiming 0x818
-//#define rFPGA0_XD_RFTiming 0x81c
-
-#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register
-#define rFPGA0_XA_HSSIParameter2 0x824
-#define rFPGA0_XB_HSSIParameter1 0x828
-#define rFPGA0_XB_HSSIParameter2 0x82c
-#define rFPGA0_XC_HSSIParameter1 0x830
-#define rFPGA0_XC_HSSIParameter2 0x834
-#define rFPGA0_XD_HSSIParameter1 0x838
-#define rFPGA0_XD_HSSIParameter2 0x83c
-#define rFPGA0_XA_LSSIParameter 0x840
-#define rFPGA0_XB_LSSIParameter 0x844
-#define rFPGA0_XC_LSSIParameter 0x848
-#define rFPGA0_XD_LSSIParameter 0x84c
-
-#define rFPGA0_RFWakeUpParameter 0x850 // Useless now
-#define rFPGA0_RFSleepUpParameter 0x854
-
-#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch
-#define rFPGA0_XCD_SwitchControl 0x85c
-
-#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch
-#define rFPGA0_XB_RFInterfaceOE 0x864
-#define rFPGA0_XC_RFInterfaceOE 0x868
-#define rFPGA0_XD_RFInterfaceOE 0x86c
-
-#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control
-#define rFPGA0_XCD_RFInterfaceSW 0x874
-
-#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter
-#define rFPGA0_XCD_RFParameter 0x87c
-
-#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4??
-#define rFPGA0_AnalogParameter2 0x884
-#define rFPGA0_AnalogParameter3 0x888 // Useless now
-#define rFPGA0_AnalogParameter4 0x88c
-
-#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback
-#define rFPGA0_XB_LSSIReadBack 0x8a4
-#define rFPGA0_XC_LSSIReadBack 0x8a8
-#define rFPGA0_XD_LSSIReadBack 0x8ac
-
-#define rFPGA0_PSDReport 0x8b4 // Useless now
-#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback
-#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback
-#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value
-#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now
-
-//
-// 4. Page9(0x900)
-//
-#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting??
-
-#define rFPGA1_TxBlock 0x904 // Useless now
-#define rFPGA1_DebugSelect 0x908 // Useless now
-#define rFPGA1_TxInfo 0x90c // Useless now // Status report??
-
-//
-// 5. PageA(0xA00)
-//
-// Set Control channel to upper or lower. These settings are required only for 40MHz
-#define rCCK0_System 0xa00
-
-#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI
-#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain
-
-#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series
-#define rCCK0_RxAGC2 0xa10 //AGC & DAGC
-
-#define rCCK0_RxHP 0xa14
-
-#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold
-#define rCCK0_DSPParameter2 0xa1c //SQ threshold
-
-#define rCCK0_TxFilter1 0xa20
-#define rCCK0_TxFilter2 0xa24
-#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3
-#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report
-#define rCCK0_TRSSIReport 0xa50
-#define rCCK0_RxReport 0xa54 //0xa57
-#define rCCK0_FACounterLower 0xa5c //0xa5b
-#define rCCK0_FACounterUpper 0xa58 //0xa5c
-
-//
-// 6. PageC(0xC00)
-//
-#define rOFDM0_LSTF 0xc00
-
-#define rOFDM0_TRxPathEnable 0xc04
-#define rOFDM0_TRMuxPar 0xc08
-#define rOFDM0_TRSWIsolation 0xc0c
-
-#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter
-#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix
-#define rOFDM0_XBRxAFE 0xc18
-#define rOFDM0_XBRxIQImbalance 0xc1c
-#define rOFDM0_XCRxAFE 0xc20
-#define rOFDM0_XCRxIQImbalance 0xc24
-#define rOFDM0_XDRxAFE 0xc28
-#define rOFDM0_XDRxIQImbalance 0xc2c
-
-#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain
-#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync.
-#define rOFDM0_RxDetector3 0xc38 //Frame Sync.
-#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI
-
-#define rOFDM0_RxDSP 0xc40 //Rx Sync Path
-#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC
-#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold
-#define rOFDM0_ECCAThreshold 0xc4c // energy CCA
-
-#define rOFDM0_XAAGCCore1 0xc50 // DIG
-#define rOFDM0_XAAGCCore2 0xc54
-#define rOFDM0_XBAGCCore1 0xc58
-#define rOFDM0_XBAGCCore2 0xc5c
-#define rOFDM0_XCAGCCore1 0xc60
-#define rOFDM0_XCAGCCore2 0xc64
-#define rOFDM0_XDAGCCore1 0xc68
-#define rOFDM0_XDAGCCore2 0xc6c
-
-#define rOFDM0_AGCParameter1 0xc70
-#define rOFDM0_AGCParameter2 0xc74
-#define rOFDM0_AGCRSSITable 0xc78
-#define rOFDM0_HTSTFAGC 0xc7c
-
-#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG
-#define rOFDM0_XATxAFE 0xc84
-#define rOFDM0_XBTxIQImbalance 0xc88
-#define rOFDM0_XBTxAFE 0xc8c
-#define rOFDM0_XCTxIQImbalance 0xc90
-#define rOFDM0_XCTxAFE 0xc94
-#define rOFDM0_XDTxIQImbalance 0xc98
-#define rOFDM0_XDTxAFE 0xc9c
-
-#define rOFDM0_RxHPParameter 0xce0
-#define rOFDM0_TxPseudoNoiseWgt 0xce4
-#define rOFDM0_FrameSync 0xcf0
-#define rOFDM0_DFSReport 0xcf4
-#define rOFDM0_TxCoeff1 0xca4
-#define rOFDM0_TxCoeff2 0xca8
-#define rOFDM0_TxCoeff3 0xcac
-#define rOFDM0_TxCoeff4 0xcb0
-#define rOFDM0_TxCoeff5 0xcb4
-#define rOFDM0_TxCoeff6 0xcb8
-
-
-//
-// 7. PageD(0xD00)
-//
-#define rOFDM1_LSTF 0xd00
-#define rOFDM1_TRxPathEnable 0xd04
-#define rOFDM1_CFO 0xd08 // No setting now
-#define rOFDM1_CSI1 0xd10
-#define rOFDM1_SBD 0xd14
-#define rOFDM1_CSI2 0xd18
-#define rOFDM1_CFOTracking 0xd2c
-#define rOFDM1_TRxMesaure1 0xd34
-#define rOFDM1_IntfDet 0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt 0xd58
-
-#define rOFDM_PHYCounter1 0xda0 //cca, parity fail
-#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail
-#define rOFDM_PHYCounter3 0xda8 //MCS not support
-#define rOFDM_ShortCFOAB 0xdac // No setting now
-#define rOFDM_ShortCFOCD 0xdb0
-#define rOFDM_LongCFOAB 0xdb4
-#define rOFDM_LongCFOCD 0xdb8
-#define rOFDM_TailCFOAB 0xdbc
-#define rOFDM_TailCFOCD 0xdc0
-#define rOFDM_PWMeasure1 0xdc4
-#define rOFDM_PWMeasure2 0xdc8
-#define rOFDM_BWReport 0xdcc
-#define rOFDM_AGCReport 0xdd0
-#define rOFDM_RxSNR 0xdd4
-#define rOFDM_RxEVMCSI 0xdd8
-#define rOFDM_SIGReport 0xddc
-
-
-//
-// 8. PageE(0xE00)
-//
-#define rTxAGC_Rate18_06 0xe00
-#define rTxAGC_Rate54_24 0xe04
-#define rTxAGC_CCK_Mcs32 0xe08
-#define rTxAGC_Mcs03_Mcs00 0xe10
-#define rTxAGC_Mcs07_Mcs04 0xe14
-#define rTxAGC_Mcs11_Mcs08 0xe18
-#define rTxAGC_Mcs15_Mcs12 0xe1c
-
-//
-// 7. RF Register 0x00-0x2E (RF 8256)
-// RF-0222D 0x00-3F
-//
-//Zebra1
-#define rZebra1_HSSIEnable 0x0 // Useless now
-#define rZebra1_TRxEnable1 0x1
-#define rZebra1_TRxEnable2 0x2
-#define rZebra1_AGC 0x4
-#define rZebra1_ChargePump 0x5
-//#if (RTL92SE_FPGA_VERIFY == 1)
-#define rZebra1_Channel 0x7 // RF channel switch
-//#else
-
-//#endif
-#define rZebra1_TxGain 0x8 // Useless now
-#define rZebra1_TxLPF 0x9
-#define rZebra1_RxLPF 0xb
-#define rZebra1_RxHPFCorner 0xc
-
-//Zebra4
-#define rGlobalCtrl 0 // Useless now
-#define rRTL8256_TxLPF 19
-#define rRTL8256_RxLPF 11
-
-//RTL8258
-#define rRTL8258_TxLPF 0x11 // Useless now
-#define rRTL8258_RxLPF 0x13
-#define rRTL8258_RSSILPF 0xa
-
-//
-// RL6052 Register definition
-//
-#define RF_AC 0x00 //
-
-#define RF_IQADJ_G1 0x01 //
-#define RF_IQADJ_G2 0x02 //
-#define RF_POW_TRSW 0x05 //
-
-#define RF_GAIN_RX 0x06 //
-#define RF_GAIN_TX 0x07 //
-
-#define RF_TXM_IDAC 0x08 //
-#define RF_BS_IQGEN 0x0F //
-
-#define RF_MODE1 0x10 //
-#define RF_MODE2 0x11 //
-
-#define RF_RX_AGC_HP 0x12 //
-#define RF_TX_AGC 0x13 //
-#define RF_BIAS 0x14 //
-#define RF_IPA 0x15 //
-#define RF_POW_ABILITY 0x17 //
-#define RF_MODE_AG 0x18 //
-#define rRfChannel 0x18 // RF channel and BW switch
-#define RF_CHNLBW 0x18 // RF channel and BW switch
-#define RF_TOP 0x19 //
-
-#define RF_RX_G1 0x1A //
-#define RF_RX_G2 0x1B //
-
-#define RF_RX_BB2 0x1C //
-#define RF_RX_BB1 0x1D //
-
-#define RF_RCK1 0x1E //
-#define RF_RCK2 0x1F //
-
-#define RF_TX_G1 0x20 //
-#define RF_TX_G2 0x21 //
-#define RF_TX_G3 0x22 //
-
-#define RF_TX_BB1 0x23 //
-
-#define RF_T_METER 0x24 //
-
-#define RF_SYN_G1 0x25 // RF TX Power control
-#define RF_SYN_G2 0x26 // RF TX Power control
-#define RF_SYN_G3 0x27 // RF TX Power control
-#define RF_SYN_G4 0x28 // RF TX Power control
-#define RF_SYN_G5 0x29 // RF TX Power control
-#define RF_SYN_G6 0x2A // RF TX Power control
-#define RF_SYN_G7 0x2B // RF TX Power control
-#define RF_SYN_G8 0x2C // RF TX Power control
-
-#define RF_RCK_OS 0x30 // RF TX PA control
-
-#define RF_TXPA_G1 0x31 // RF TX PA control
-#define RF_TXPA_G2 0x32 // RF TX PA control
-#define RF_TXPA_G3 0x33 // RF TX PA control
-
-//
-//Bit Mask
-//
-// 1. Page1(0x100)
-#define bBBResetB 0x100 // Useless now?
-#define bGlobalResetB 0x200
-#define bOFDMTxStart 0x4
-#define bCCKTxStart 0x8
-#define bCRC32Debug 0x100
-#define bPMACLoopback 0x10
-#define bTxLSIG 0xffffff
-#define bOFDMTxRate 0xf
-#define bOFDMTxReserved 0x10
-#define bOFDMTxLength 0x1ffe0
-#define bOFDMTxParity 0x20000
-#define bTxHTSIG1 0xffffff
-#define bTxHTMCSRate 0x7f
-#define bTxHTBW 0x80
-#define bTxHTLength 0xffff00
-#define bTxHTSIG2 0xffffff
-#define bTxHTSmoothing 0x1
-#define bTxHTSounding 0x2
-#define bTxHTReserved 0x4
-#define bTxHTAggreation 0x8
-#define bTxHTSTBC 0x30
-#define bTxHTAdvanceCoding 0x40
-#define bTxHTShortGI 0x80
-#define bTxHTNumberHT_LTF 0x300
-#define bTxHTCRC8 0x3fc00
-#define bCounterReset 0x10000
-#define bNumOfOFDMTx 0xffff
-#define bNumOfCCKTx 0xffff0000
-#define bTxIdleInterval 0xffff
-#define bOFDMService 0xffff0000
-#define bTxMACHeader 0xffffffff
-#define bTxDataInit 0xff
-#define bTxHTMode 0x100
-#define bTxDataType 0x30000
-#define bTxRandomSeed 0xffffffff
-#define bCCKTxPreamble 0x1
-#define bCCKTxSFD 0xffff0000
-#define bCCKTxSIG 0xff
-#define bCCKTxService 0xff00
-#define bCCKLengthExt 0x8000
-#define bCCKTxLength 0xffff0000
-#define bCCKTxCRC16 0xffff
-#define bCCKTxStatus 0x1
-#define bOFDMTxStatus 0x2
-
-#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff))
-
-// 2. Page8(0x800)
-#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD
-#define bJapanMode 0x2
-#define bCCKTxSC 0x30
-#define bCCKEn 0x1000000
-#define bOFDMEn 0x2000000
-
-#define bOFDMRxADCPhase 0x10000 // Useless now
-#define bOFDMTxDACPhase 0x40000
-#define bXATxAGC 0x3f
-
-#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage
-#define bXCTxAGC 0xf000
-#define bXDTxAGC 0xf0000
-
-#define bPAStart 0xf0000000 // Useless now
-#define bTRStart 0x00f00000
-#define bRFStart 0x0000f000
-#define bBBStart 0x000000f0
-#define bBBCCKStart 0x0000000f
-#define bPAEnd 0xf //Reg0x814
-#define bTREnd 0x0f000000
-#define bRFEnd 0x000f0000
-#define bCCAMask 0x000000f0 //T2R
-#define bR2RCCAMask 0x00000f00
-#define bHSSI_R2TDelay 0xf8000000
-#define bHSSI_T2RDelay 0xf80000
-#define bContTxHSSI 0x400 //channel gain at continue Tx
-#define bIGFromCCK 0x200
-#define bAGCAddress 0x3f
-#define bRxHPTx 0x7000
-#define bRxHPT2R 0x38000
-#define bRxHPCCKIni 0xc0000
-#define bAGCTxCode 0xc00000
-#define bAGCRxCode 0x300000
-
-#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1
-#define b3WireAddressLength 0x400
-
-#define b3WireRFPowerDown 0x1 // Useless now
-//#define bHWSISelect 0x8
-#define b5GPAPEPolarity 0x40000000
-#define b2GPAPEPolarity 0x80000000
-#define bRFSW_TxDefaultAnt 0x3
-#define bRFSW_TxOptionAnt 0x30
-#define bRFSW_RxDefaultAnt 0x300
-#define bRFSW_RxOptionAnt 0x3000
-#define bRFSI_3WireData 0x1
-#define bRFSI_3WireClock 0x2
-#define bRFSI_3WireLoad 0x4
-#define bRFSI_3WireRW 0x8
-#define bRFSI_3Wire 0xf
-
-#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW
-
-#define bRFSI_TRSW 0x20 // Useless now
-#define bRFSI_TRSWB 0x40
-#define bRFSI_ANTSW 0x100
-#define bRFSI_ANTSWB 0x200
-#define bRFSI_PAPE 0x400
-#define bRFSI_PAPE5G 0x800
-#define bBandSelect 0x1
-#define bHTSIG2_GI 0x80
-#define bHTSIG2_Smoothing 0x01
-#define bHTSIG2_Sounding 0x02
-#define bHTSIG2_Aggreaton 0x08
-#define bHTSIG2_STBC 0x30
-#define bHTSIG2_AdvCoding 0x40
-#define bHTSIG2_NumOfHTLTF 0x300
-#define bHTSIG2_CRC8 0x3fc
-#define bHTSIG1_MCS 0x7f
-#define bHTSIG1_BandWidth 0x80
-#define bHTSIG1_HTLength 0xffff
-#define bLSIG_Rate 0xf
-#define bLSIG_Reserved 0x10
-#define bLSIG_Length 0x1fffe
-#define bLSIG_Parity 0x20
-#define bCCKRxPhase 0x4
-#define bLSSIReadAddress 0x7f800000 // T65 RF
-#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal
-#define bLSSIReadBackData 0xfffff // T65 RF
-#define bLSSIReadOKFlag 0x1000 // Useless now
-#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz
-#define bRegulator0Standby 0x1
-#define bRegulatorPLLStandby 0x2
-#define bRegulator1Standby 0x4
-#define bPLLPowerUp 0x8
-#define bDPLLPowerUp 0x10
-#define bDA10PowerUp 0x20
-#define bAD7PowerUp 0x200
-#define bDA6PowerUp 0x2000
-#define bXtalPowerUp 0x4000
-#define b40MDClkPowerUP 0x8000
-#define bDA6DebugMode 0x20000
-#define bDA6Swing 0x380000
-
-#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ
-
-#define b80MClkDelay 0x18000000 // Useless
-#define bAFEWatchDogEnable 0x20000000
-
-#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap
-#define bXtalCap23 0x3
-#define bXtalCap92x 0x0f000000
-#define bXtalCap 0x0f000000
-
-#define bIntDifClkEnable 0x400 // Useless
-#define bExtSigClkEnable 0x800
-#define bBandgapMbiasPowerUp 0x10000
-#define bAD11SHGain 0xc0000
-#define bAD11InputRange 0x700000
-#define bAD11OPCurrent 0x3800000
-#define bIPathLoopback 0x4000000
-#define bQPathLoopback 0x8000000
-#define bAFELoopback 0x10000000
-#define bDA10Swing 0x7e0
-#define bDA10Reverse 0x800
-#define bDAClkSource 0x1000
-#define bAD7InputRange 0x6000
-#define bAD7Gain 0x38000
-#define bAD7OutputCMMode 0x40000
-#define bAD7InputCMMode 0x380000
-#define bAD7Current 0xc00000
-#define bRegulatorAdjust 0x7000000
-#define bAD11PowerUpAtTx 0x1
-#define bDA10PSAtTx 0x10
-#define bAD11PowerUpAtRx 0x100
-#define bDA10PSAtRx 0x1000
-#define bCCKRxAGCFormat 0x200
-#define bPSDFFTSamplepPoint 0xc000
-#define bPSDAverageNum 0x3000
-#define bIQPathControl 0xc00
-#define bPSDFreq 0x3ff
-#define bPSDAntennaPath 0x30
-#define bPSDIQSwitch 0x40
-#define bPSDRxTrigger 0x400000
-#define bPSDTxTrigger 0x80000000
-#define bPSDSineToneScale 0x7f000000
-#define bPSDReport 0xffff
-
-// 3. Page9(0x900)
-#define bOFDMTxSC 0x30000000 // Useless
-#define bCCKTxOn 0x1
-#define bOFDMTxOn 0x2
-#define bDebugPage 0xfff //reset debug page and also HWord, LWord
-#define bDebugItem 0xff //reset debug page and LWord
-#define bAntL 0x10
-#define bAntNonHT 0x100
-#define bAntHT1 0x1000
-#define bAntHT2 0x10000
-#define bAntHT1S1 0x100000
-#define bAntNonHTS1 0x1000000
-
-// 4. PageA(0xA00)
-#define bCCKBBMode 0x3 // Useless
-#define bCCKTxPowerSaving 0x80
-#define bCCKRxPowerSaving 0x40
-
-#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch
-
-#define bCCKScramble 0x8 // Useless
-#define bCCKAntDiversity 0x8000
-#define bCCKCarrierRecovery 0x4000
-#define bCCKTxRate 0x3000
-#define bCCKDCCancel 0x0800
-#define bCCKISICancel 0x0400
-#define bCCKMatchFilter 0x0200
-#define bCCKEqualizer 0x0100
-#define bCCKPreambleDetect 0x800000
-#define bCCKFastFalseCCA 0x400000
-#define bCCKChEstStart 0x300000
-#define bCCKCCACount 0x080000
-#define bCCKcs_lim 0x070000
-#define bCCKBistMode 0x80000000
-#define bCCKCCAMask 0x40000000
-#define bCCKTxDACPhase 0x4
-#define bCCKRxADCPhase 0x20000000 //r_rx_clk
-#define bCCKr_cp_mode0 0x0100
-#define bCCKTxDCOffset 0xf0
-#define bCCKRxDCOffset 0xf
-#define bCCKCCAMode 0xc000
-#define bCCKFalseCS_lim 0x3f00
-#define bCCKCS_ratio 0xc00000
-#define bCCKCorgBit_sel 0x300000
-#define bCCKPD_lim 0x0f0000
-#define bCCKNewCCA 0x80000000
-#define bCCKRxHPofIG 0x8000
-#define bCCKRxIG 0x7f00
-#define bCCKLNAPolarity 0x800000
-#define bCCKRx1stGain 0x7f0000
-#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity
-#define bCCKRxAGCSatLevel 0x1f000000
-#define bCCKRxAGCSatCount 0xe0
-#define bCCKRxRFSettle 0x1f //AGCsamp_dly
-#define bCCKFixedRxAGC 0x8000
-//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824
-#define bCCKAntennaPolarity 0x2000
-#define bCCKTxFilterType 0x0c00
-#define bCCKRxAGCReportType 0x0300
-#define bCCKRxDAGCEn 0x80000000
-#define bCCKRxDAGCPeriod 0x20000000
-#define bCCKRxDAGCSatLevel 0x1f000000
-#define bCCKTimingRecovery 0x800000
-#define bCCKTxC0 0x3f0000
-#define bCCKTxC1 0x3f000000
-#define bCCKTxC2 0x3f
-#define bCCKTxC3 0x3f00
-#define bCCKTxC4 0x3f0000
-#define bCCKTxC5 0x3f000000
-#define bCCKTxC6 0x3f
-#define bCCKTxC7 0x3f00
-#define bCCKDebugPort 0xff0000
-#define bCCKDACDebug 0x0f000000
-#define bCCKFalseAlarmEnable 0x8000
-#define bCCKFalseAlarmRead 0x4000
-#define bCCKTRSSI 0x7f
-#define bCCKRxAGCReport 0xfe
-#define bCCKRxReport_AntSel 0x80000000
-#define bCCKRxReport_MFOff 0x40000000
-#define bCCKRxRxReport_SQLoss 0x20000000
-#define bCCKRxReport_Pktloss 0x10000000
-#define bCCKRxReport_Lockedbit 0x08000000
-#define bCCKRxReport_RateError 0x04000000
-#define bCCKRxReport_RxRate 0x03000000
-#define bCCKRxFACounterLower 0xff
-#define bCCKRxFACounterUpper 0xff000000
-#define bCCKRxHPAGCStart 0xe000
-#define bCCKRxHPAGCFinal 0x1c00
-#define bCCKRxFalseAlarmEnable 0x8000
-#define bCCKFACounterFreeze 0x4000
-#define bCCKTxPathSel 0x10000000
-#define bCCKDefaultRxPath 0xc000000
-#define bCCKOptionRxPath 0x3000000
-
-// 5. PageC(0xC00)
-#define bNumOfSTF 0x3 // Useless
-#define bShift_L 0xc0
-#define bGI_TH 0xc
-#define bRxPathA 0x1
-#define bRxPathB 0x2
-#define bRxPathC 0x4
-#define bRxPathD 0x8
-#define bTxPathA 0x1
-#define bTxPathB 0x2
-#define bTxPathC 0x4
-#define bTxPathD 0x8
-#define bTRSSIFreq 0x200
-#define bADCBackoff 0x3000
-#define bDFIRBackoff 0xc000
-#define bTRSSILatchPhase 0x10000
-#define bRxIDCOffset 0xff
-#define bRxQDCOffset 0xff00
-#define bRxDFIRMode 0x1800000
-#define bRxDCNFType 0xe000000
-#define bRXIQImb_A 0x3ff
-#define bRXIQImb_B 0xfc00
-#define bRXIQImb_C 0x3f0000
-#define bRXIQImb_D 0xffc00000
-#define bDC_dc_Notch 0x60000
-#define bRxNBINotch 0x1f000000
-#define bPD_TH 0xf
-#define bPD_TH_Opt2 0xc000
-#define bPWED_TH 0x700
-#define bIfMF_Win_L 0x800
-#define bPD_Option 0x1000
-#define bMF_Win_L 0xe000
-#define bBW_Search_L 0x30000
-#define bwin_enh_L 0xc0000
-#define bBW_TH 0x700000
-#define bED_TH2 0x3800000
-#define bBW_option 0x4000000
-#define bRatio_TH 0x18000000
-#define bWindow_L 0xe0000000
-#define bSBD_Option 0x1
-#define bFrame_TH 0x1c
-#define bFS_Option 0x60
-#define bDC_Slope_check 0x80
-#define bFGuard_Counter_DC_L 0xe00
-#define bFrame_Weight_Short 0x7000
-#define bSub_Tune 0xe00000
-#define bFrame_DC_Length 0xe000000
-#define bSBD_start_offset 0x30000000
-#define bFrame_TH_2 0x7
-#define bFrame_GI2_TH 0x38
-#define bGI2_Sync_en 0x40
-#define bSarch_Short_Early 0x300
-#define bSarch_Short_Late 0xc00
-#define bSarch_GI2_Late 0x70000
-#define bCFOAntSum 0x1
-#define bCFOAcc 0x2
-#define bCFOStartOffset 0xc
-#define bCFOLookBack 0x70
-#define bCFOSumWeight 0x80
-#define bDAGCEnable 0x10000
-#define bTXIQImb_A 0x3ff
-#define bTXIQImb_B 0xfc00
-#define bTXIQImb_C 0x3f0000
-#define bTXIQImb_D 0xffc00000
-#define bTxIDCOffset 0xff
-#define bTxQDCOffset 0xff00
-#define bTxDFIRMode 0x10000
-#define bTxPesudoNoiseOn 0x4000000
-#define bTxPesudoNoise_A 0xff
-#define bTxPesudoNoise_B 0xff00
-#define bTxPesudoNoise_C 0xff0000
-#define bTxPesudoNoise_D 0xff000000
-#define bCCADropOption 0x20000
-#define bCCADropThres 0xfff00000
-#define bEDCCA_H 0xf
-#define bEDCCA_L 0xf0
-#define bLambda_ED 0x300
-#define bRxInitialGain 0x7f
-#define bRxAntDivEn 0x80
-#define bRxAGCAddressForLNA 0x7f00
-#define bRxHighPowerFlow 0x8000
-#define bRxAGCFreezeThres 0xc0000
-#define bRxFreezeStep_AGC1 0x300000
-#define bRxFreezeStep_AGC2 0xc00000
-#define bRxFreezeStep_AGC3 0x3000000
-#define bRxFreezeStep_AGC0 0xc000000
-#define bRxRssi_Cmp_En 0x10000000
-#define bRxQuickAGCEn 0x20000000
-#define bRxAGCFreezeThresMode 0x40000000
-#define bRxOverFlowCheckType 0x80000000
-#define bRxAGCShift 0x7f
-#define bTRSW_Tri_Only 0x80
-#define bPowerThres 0x300
-#define bRxAGCEn 0x1
-#define bRxAGCTogetherEn 0x2
-#define bRxAGCMin 0x4
-#define bRxHP_Ini 0x7
-#define bRxHP_TRLNA 0x70
-#define bRxHP_RSSI 0x700
-#define bRxHP_BBP1 0x7000
-#define bRxHP_BBP2 0x70000
-#define bRxHP_BBP3 0x700000
-#define bRSSI_H 0x7f0000 //the threshold for high power
-#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity
-#define bRxSettle_TRSW 0x7
-#define bRxSettle_LNA 0x38
-#define bRxSettle_RSSI 0x1c0
-#define bRxSettle_BBP 0xe00
-#define bRxSettle_RxHP 0x7000
-#define bRxSettle_AntSW_RSSI 0x38000
-#define bRxSettle_AntSW 0xc0000
-#define bRxProcessTime_DAGC 0x300000
-#define bRxSettle_HSSI 0x400000
-#define bRxProcessTime_BBPPW 0x800000
-#define bRxAntennaPowerShift 0x3000000
-#define bRSSITableSelect 0xc000000
-#define bRxHP_Final 0x7000000
-#define bRxHTSettle_BBP 0x7
-#define bRxHTSettle_HSSI 0x8
-#define bRxHTSettle_RxHP 0x70
-#define bRxHTSettle_BBPPW 0x80
-#define bRxHTSettle_Idle 0x300
-#define bRxHTSettle_Reserved 0x1c00
-#define bRxHTRxHPEn 0x8000
-#define bRxHTAGCFreezeThres 0x30000
-#define bRxHTAGCTogetherEn 0x40000
-#define bRxHTAGCMin 0x80000
-#define bRxHTAGCEn 0x100000
-#define bRxHTDAGCEn 0x200000
-#define bRxHTRxHP_BBP 0x1c00000
-#define bRxHTRxHP_Final 0xe0000000
-#define bRxPWRatioTH 0x3
-#define bRxPWRatioEn 0x4
-#define bRxMFHold 0x3800
-#define bRxPD_Delay_TH1 0x38
-#define bRxPD_Delay_TH2 0x1c0
-#define bRxPD_DC_COUNT_MAX 0x600
-//#define bRxMF_Hold 0x3800
-#define bRxPD_Delay_TH 0x8000
-#define bRxProcess_Delay 0xf0000
-#define bRxSearchrange_GI2_Early 0x700000
-#define bRxFrame_Guard_Counter_L 0x3800000
-#define bRxSGI_Guard_L 0xc000000
-#define bRxSGI_Search_L 0x30000000
-#define bRxSGI_TH 0xc0000000
-#define bDFSCnt0 0xff
-#define bDFSCnt1 0xff00
-#define bDFSFlag 0xf0000
-#define bMFWeightSum 0x300000
-#define bMinIdxTH 0x7f000000
-#define bDAFormat 0x40000
-#define bTxChEmuEnable 0x01000000
-#define bTRSWIsolation_A 0x7f
-#define bTRSWIsolation_B 0x7f00
-#define bTRSWIsolation_C 0x7f0000
-#define bTRSWIsolation_D 0x7f000000
-#define bExtLNAGain 0x7c00
-
-// 6. PageE(0xE00)
-#define bSTBCEn 0x4 // Useless
-#define bAntennaMapping 0x10
-#define bNss 0x20
-#define bCFOAntSumD 0x200
-#define bPHYCounterReset 0x8000000
-#define bCFOReportGet 0x4000000
-#define bOFDMContinueTx 0x10000000
-#define bOFDMSingleCarrier 0x20000000
-#define bOFDMSingleTone 0x40000000
-//#define bRxPath1 0x01
-//#define bRxPath2 0x02
-//#define bRxPath3 0x04
-//#define bRxPath4 0x08
-//#define bTxPath1 0x10
-//#define bTxPath2 0x20
-#define bHTDetect 0x100
-#define bCFOEn 0x10000
-#define bCFOValue 0xfff00000
-#define bSigTone_Re 0x3f
-#define bSigTone_Im 0x7f00
-#define bCounter_CCA 0xffff
-#define bCounter_ParityFail 0xffff0000
-#define bCounter_RateIllegal 0xffff
-#define bCounter_CRC8Fail 0xffff0000
-#define bCounter_MCSNoSupport 0xffff
-#define bCounter_FastSync 0xffff
-#define bShortCFO 0xfff
-#define bShortCFOTLength 12 //total
-#define bShortCFOFLength 11 //fraction
-#define bLongCFO 0x7ff
-#define bLongCFOTLength 11
-#define bLongCFOFLength 11
-#define bTailCFO 0x1fff
-#define bTailCFOTLength 13
-#define bTailCFOFLength 12
-#define bmax_en_pwdB 0xffff
-#define bCC_power_dB 0xffff0000
-#define bnoise_pwdB 0xffff
-#define bPowerMeasTLength 10
-#define bPowerMeasFLength 3
-#define bRx_HT_BW 0x1
-#define bRxSC 0x6
-#define bRx_HT 0x8
-#define bNB_intf_det_on 0x1
-#define bIntf_win_len_cfg 0x30
-#define bNB_Intf_TH_cfg 0x1c0
-#define bRFGain 0x3f
-#define bTableSel 0x40
-#define bTRSW 0x80
-#define bRxSNR_A 0xff
-#define bRxSNR_B 0xff00
-#define bRxSNR_C 0xff0000
-#define bRxSNR_D 0xff000000
-#define bSNREVMTLength 8
-#define bSNREVMFLength 1
-#define bCSI1st 0xff
-#define bCSI2nd 0xff00
-#define bRxEVM1st 0xff0000
-#define bRxEVM2nd 0xff000000
-#define bSIGEVM 0xff
-#define bPWDB 0xff00
-#define bSGIEN 0x10000
-
-#define bSFactorQAM1 0xf // Useless
-#define bSFactorQAM2 0xf0
-#define bSFactorQAM3 0xf00
-#define bSFactorQAM4 0xf000
-#define bSFactorQAM5 0xf0000
-#define bSFactorQAM6 0xf0000
-#define bSFactorQAM7 0xf00000
-#define bSFactorQAM8 0xf000000
-#define bSFactorQAM9 0xf0000000
-#define bCSIScheme 0x100000
-
-#define bNoiseLvlTopSet 0x3 // Useless
-#define bChSmooth 0x4
-#define bChSmoothCfg1 0x38
-#define bChSmoothCfg2 0x1c0
-#define bChSmoothCfg3 0xe00
-#define bChSmoothCfg4 0x7000
-#define bMRCMode 0x800000
-#define bTHEVMCfg 0x7000000
-
-#define bLoopFitType 0x1 // Useless
-#define bUpdCFO 0x40
-#define bUpdCFOOffData 0x80
-#define bAdvUpdCFO 0x100
-#define bAdvTimeCtrl 0x800
-#define bUpdClko 0x1000
-#define bFC 0x6000
-#define bTrackingMode 0x8000
-#define bPhCmpEnable 0x10000
-#define bUpdClkoLTF 0x20000
-#define bComChCFO 0x40000
-#define bCSIEstiMode 0x80000
-#define bAdvUpdEqz 0x100000
-#define bUChCfg 0x7000000
-#define bUpdEqz 0x8000000
-
-#define bTxAGCRate18_06 0x7f7f7f7f // Useless
-#define bTxAGCRate54_24 0x7f7f7f7f
-#define bTxAGCRateMCS32 0x7f
-#define bTxAGCRateCCK 0x7f00
-#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
-#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
-#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
-#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
-
-//Rx Pseduo noise
-#define bRxPesudoNoiseOn 0x20000000 // Useless
-#define bRxPesudoNoise_A 0xff
-#define bRxPesudoNoise_B 0xff00
-#define bRxPesudoNoise_C 0xff0000
-#define bRxPesudoNoise_D 0xff000000
-#define bPesudoNoiseState_A 0xffff
-#define bPesudoNoiseState_B 0xffff0000
-#define bPesudoNoiseState_C 0xffff
-#define bPesudoNoiseState_D 0xffff0000
-
-//7. RF Register
-//Zebra1
-#define bZebra1_HSSIEnable 0x8 // Useless
-#define bZebra1_TRxControl 0xc00
-#define bZebra1_TRxGainSetting 0x07f
-#define bZebra1_RxCorner 0xc00
-#define bZebra1_TxChargePump 0x38
-#define bZebra1_RxChargePump 0x7
-#define bZebra1_ChannelNum 0xf80
-#define bZebra1_TxLPFBW 0x400
-#define bZebra1_RxLPFBW 0x600
-
-//Zebra4
-#define bRTL8256RegModeCtrl1 0x100 // Useless
-#define bRTL8256RegModeCtrl0 0x40
-#define bRTL8256_TxLPFBW 0x18
-#define bRTL8256_RxLPFBW 0x600
-
-//RTL8258
-#define bRTL8258_TxLPFBW 0xc // Useless
-#define bRTL8258_RxLPFBW 0xc00
-#define bRTL8258_RSSILPFBW 0xc0
-
-
-//
-// Other Definition
-//
-
-//byte endable for sb_write
-#define bByte0 0x1 // Useless
-#define bByte1 0x2
-#define bByte2 0x4
-#define bByte3 0x8
-#define bWord0 0x3
-#define bWord1 0xc
-#define bDWord 0xf
-
-//for PutRegsetting & GetRegSetting BitMask
-#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f
-#define bMaskByte1 0xff00
-#define bMaskByte2 0xff0000
-#define bMaskByte3 0xff000000
-#define bMaskHWord 0xffff0000
-#define bMaskLWord 0x0000ffff
-#define bMaskDWord 0xffffffff
-
-//for PutRFRegsetting & GetRFRegSetting BitMask
-#define bMask12Bits 0xfffff // RF Reg mask bits
-#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF
-#define bRFRegOffsetMask 0xfffff
-
-#define bEnable 0x1 // Useless
-#define bDisable 0x0
-
-#define LeftAntenna 0x0 // Useless
-#define RightAntenna 0x1
-
-#define tCheckTxStatus 500 //500ms // Useless
-#define tUpdateRxCounter 100 //100ms
-
-#define rateCCK 0 // Useless
-#define rateOFDM 1
-#define rateHT 2
-
-//define Register-End
-#define bPMAC_End 0x1ff // Useless
-#define bFPGAPHY0_End 0x8ff
-#define bFPGAPHY1_End 0x9ff
-#define bCCKPHY0_End 0xaff
-#define bOFDMPHY0_End 0xcff
-#define bOFDMPHY1_End 0xdff
-
-//define max debug item in each debug page
-//#define bMaxItem_FPGA_PHY0 0x9
-//#define bMaxItem_FPGA_PHY1 0x3
-//#define bMaxItem_PHY_11B 0x16
-//#define bMaxItem_OFDM_PHY0 0x29
-//#define bMaxItem_OFDM_PHY1 0x0
-
-#define bPMACControl 0x0 // Useless
-#define bWMACControl 0x1
-#define bWNICControl 0x2
-
-#define PathA 0x0 // Useless
-#define PathB 0x1
-#define PathC 0x2
-#define PathD 0x3
-
-/*--------------------------Define Parameters-------------------------------*/
-
-
-#endif //__INC_HAL8192SPHYREG_H
-
diff --git a/drivers/staging/rtl8192su/r8192S_rtl6052.c b/drivers/staging/rtl8192su/r8192S_rtl6052.c
deleted file mode 100644
index 22398099adae..000000000000
--- a/drivers/staging/rtl8192su/r8192S_rtl6052.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/******************************************************************************
- *
- * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
- *
- * Module: HalRf6052.c ( Source C File)
- *
- * Note: Provide RF 6052 series relative API.
- *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- *
- * 09/25/2008 MHC Create initial version.
- * 11/05/2008 MHC Add API for tw power setting.
- *
- *
-******************************************************************************/
-#include "r8192U.h"
-#include "r8192S_rtl6052.h"
-
-#include "r8192S_hw.h"
-#include "r8192S_phyreg.h"
-#include "r8192S_phy.h"
-
-
-/*---------------------------Define Local Constant---------------------------*/
-// Define local structure for debug!!!!!
-typedef struct RF_Shadow_Compare_Map {
- // Shadow register value
- u32 Value;
- // Compare or not flag
- u8 Compare;
- // Record If it had ever modified unpredicted
- u8 ErrorOrNot;
- // Recorver Flag
- u8 Recorver;
- //
- u8 Driver_Write;
-}RF_SHADOW_T;
-/*---------------------------Define Local Constant---------------------------*/
-
-
-/*------------------------Define global variable-----------------------------*/
-/*------------------------Define global variable-----------------------------*/
-
-
-
-
-/*---------------------Define local function prototype-----------------------*/
-void phy_RF6052_Config_HardCode(struct net_device* dev);
-
-RT_STATUS phy_RF6052_Config_ParaFile(struct net_device* dev);
-/*---------------------Define local function prototype-----------------------*/
-
-/*------------------------Define function prototype--------------------------*/
-extern void RF_ChangeTxPath(struct net_device* dev, u16 DataRate);
-
-/*------------------------Define function prototype--------------------------*/
-
-/*------------------------Define local variable------------------------------*/
-// 2008/11/20 MH For Debug only, RF
-static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];// = {{0}};//FIXLZM
-/*------------------------Define local variable------------------------------*/
-
-/*------------------------Define function prototype--------------------------*/
-/*-----------------------------------------------------------------------------
- * Function: RF_ChangeTxPath
- *
- * Overview: For RL6052, we must change some RF settign for 1T or 2T.
- *
- * Input: u16 DataRate // 0x80-8f, 0x90-9f
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 09/25/2008 MHC Create Version 0.
- * Firmwaer support the utility later.
- *
- *---------------------------------------------------------------------------*/
-extern void RF_ChangeTxPath(struct net_device* dev, u16 DataRate)
-{
-} /* RF_ChangeTxPath */
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetBandwidth()
- *
- * Overview: This function is called by SetBWModeCallback8190Pci() only
- *
- * Input: PADAPTER Adapter
- * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: For RF type 0222D
- *---------------------------------------------------------------------------*/
-void PHY_RF6052SetBandwidth(struct net_device* dev, HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
-{
- //u8 eRFPath;
- //struct r8192_priv *priv = ieee80211_priv(dev);
-
-
- //if (priv->card_8192 == NIC_8192SE)
- {
- switch(Bandwidth)
- {
- case HT_CHANNEL_WIDTH_20:
- //if (priv->card_8192_version >= VERSION_8192S_BCUT)
- // rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
-
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x01);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- //if (priv->card_8192_version >= VERSION_8192S_BCUT)
- // rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18);
-
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x00);
- break;
- default:
- RT_TRACE(COMP_DBG, "PHY_SetRF6052Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth);
- break;
- }
- }
-// else
-}
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetCckTxPower
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/05/2008 MHC Simulate 8192series..
- *
- *---------------------------------------------------------------------------*/
-extern void PHY_RF6052SetCckTxPower(struct net_device* dev, u8 powerlevel)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 TxAGC=0;
-
- if(priv->ieee80211->scanning == 1)
- TxAGC = 0x3f;
- else if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
- TxAGC = 0x22;
- else
- TxAGC = powerlevel;
-
- //cosa add for lenovo, to pass the safety spec, don't increase power index for different rates.
- if(priv->bIgnoreDiffRateTxPowerOffset)
- TxAGC = powerlevel;
-
- if(TxAGC > RF6052_MAX_TX_PWR)
- TxAGC = RF6052_MAX_TX_PWR;
-
- //printk("CCK PWR= %x\n", TxAGC);
- rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
-
-} /* PHY_RF6052SetCckTxPower */
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetOFDMTxPower
- *
- * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for
- * different channel and read original value in TX power register area from
- * 0xe00. We increase offset and original value to be correct tx pwr.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/05/2008 MHC Simulate 8192 series method.
-* 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to
- * A/B pwr difference or legacy/HT pwr diff.
- * 2. We concern with path B legacy/HT OFDM difference.
- * 01/22/2009 MHC Support new EPRO format from SD3.
- *---------------------------------------------------------------------------*/
- #if 1
-extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 writeVal, powerBase0, powerBase1;
- u8 index = 0;
- u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
- //u8 byte0, byte1, byte2, byte3;
- u8 Channel = priv->ieee80211->current_network.channel;
- u8 rfa_pwr[4];
- u8 rfa_lower_bound = 0, rfa_upper_bound = 0 /*, rfa_htpwr, rfa_legacypwr*/;
- u8 i;
- u8 rf_pwr_diff = 0;
- u8 Legacy_pwrdiff=0, HT20_pwrdiff=0, BandEdge_Pwrdiff=0;
- u8 ofdm_bandedge_chnl_low=0, ofdm_bandedge_chnl_high=0;
-
-
- // We only care about the path A for legacy.
- if (priv->EEPROMVersion != 2)
- powerBase0 = powerlevel + (priv->LegacyHTTxPowerDiff & 0xf);
- else if (priv->EEPROMVersion == 2) // Defined by SD1 Jong
- {
- //
- // 2009/01/21 MH Support new EEPROM format from SD3 requirement
- //
- Legacy_pwrdiff = priv->TxPwrLegacyHtDiff[RF90_PATH_A][Channel-1];
- // For legacy OFDM, tx pwr always > HT OFDM pwr. We do not care Path B
- // legacy OFDM pwr diff. NO BB register to notify HW.
- powerBase0 = powerlevel + Legacy_pwrdiff;
- //RTPRINT(FPHY, PHY_TXPWR, (" [LagacyToHT40 pwr diff = %d]\n", Legacy_pwrdiff));
-
- // Band Edge scheme is enabled for FCC mode
- if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
- {
- ofdm_bandedge_chnl_low = 1;
- ofdm_bandedge_chnl_high = 11;
- BandEdge_Pwrdiff = 0;
- if (Channel <= ofdm_bandedge_chnl_low)
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0];
- else if (Channel >= ofdm_bandedge_chnl_high)
- {
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1];
- }
- powerBase0 -= BandEdge_Pwrdiff;
- if (Channel <= ofdm_bandedge_chnl_low || Channel >= ofdm_bandedge_chnl_high)
- {
- //RTPRINT(FPHY, PHY_TXPWR, (" [OFDM band-edge channel = %d, pwr diff = %d]\n",
- //Channel, BandEdge_Pwrdiff));
- }
- }
- //RTPRINT(FPHY, PHY_TXPWR, (" [OFDM power base index = 0x%x]\n", powerBase0));
- }
- powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
-
- //MCS rates
- if(priv->EEPROMVersion == 2)
- {
- //Cosa add for new EEPROM content. 02102009
-
- //Check HT20 to HT40 diff
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- {
- // HT 20<->40 pwr diff
- HT20_pwrdiff = priv->TxPwrHt20Diff[RF90_PATH_A][Channel-1];
-
- // Calculate Antenna pwr diff
- if (HT20_pwrdiff < 8) // 0~+7
- powerlevel += HT20_pwrdiff;
- else // index8-15=-8~-1
- powerlevel -= (16-HT20_pwrdiff);
-
- //RTPRINT(FPHY, PHY_TXPWR, (" [HT20 to HT40 pwrdiff = %d]\n", HT20_pwrdiff));
- //RTPRINT(FPHY, PHY_TXPWR, (" [MCS power base index = 0x%x]\n", powerlevel));
- }
-
- // Band Edge scheme is enabled for FCC mode
- if (priv->TxPwrbandEdgeFlag == 1/* && pHalData->ChannelPlan == 0*/)
- {
- BandEdge_Pwrdiff = 0;
- if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
- {
- if (Channel <= 3)
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt40[RF90_PATH_A][0];
- else if (Channel >= 9)
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt40[RF90_PATH_A][1];
- if (Channel <= 3 || Channel >= 9)
- {
- //RTPRINT(FPHY, PHY_TXPWR, (" [HT40 band-edge channel = %d, pwr diff = %d]\n",
- //Channel, BandEdge_Pwrdiff));
- }
- }
- else if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- {
- if (Channel <= 1)
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt20[RF90_PATH_A][0];
- else if (Channel >= 11)
- BandEdge_Pwrdiff = priv->TxPwrbandEdgeHt20[RF90_PATH_A][1];
- if (Channel <= 1 || Channel >= 11)
- {
- //RTPRINT(FPHY, PHY_TXPWR, (" [HT20 band-edge channel = %d, pwr diff = %d]\n",
- //Channel, BandEdge_Pwrdiff));
- }
- }
- powerlevel -= BandEdge_Pwrdiff;
- //RTPRINT(FPHY, PHY_TXPWR, (" [MCS power base index = 0x%x]\n", powerlevel));
- }
- }
- powerBase1 = powerlevel;
- powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
-
- //RTPRINT(FPHY, PHY_TXPWR, (" [Legacy/HT power index= %x/%x]\n", powerBase0, powerBase1));
-
- for(index=0; index<6; index++)
- {
- //
- // Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate
- //
- //cosa add for lenovo, to pass the safety spec, don't increase power index for different rates.
- if(priv->bIgnoreDiffRateTxPowerOffset)
- writeVal = ((index<2)?powerBase0:powerBase1);
- else
- writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
-
- //RTPRINT(FPHY, PHY_TXPWR, ("Reg 0x%x, Original=%x writeVal=%x\n",
- //RegOffset[index], priv->MCSTxPowerLevelOriginalOffset[index], writeVal));
-
- //
- // If path A and Path B coexist, we must limit Path A tx power.
- // Protect Path B pwr over or underflow. We need to calculate upper and
- // lower bound of path A tx power.
- //
- if (priv->rf_type == RF_2T2R)
- {
- rf_pwr_diff = priv->AntennaTxPwDiff[0];
- //RTPRINT(FPHY, PHY_TXPWR, ("2T2R RF-B to RF-A PWR DIFF=%d\n", rf_pwr_diff));
-
- if (rf_pwr_diff >= 8) // Diff=-8~-1
- { // Prevent underflow!!
- rfa_lower_bound = 0x10-rf_pwr_diff;
- //RTPRINT(FPHY, PHY_TXPWR, ("rfa_lower_bound= %d\n", rfa_lower_bound));
- }
- else if (rf_pwr_diff >= 0) // Diff = 0-7
- {
- rfa_upper_bound = RF6052_MAX_TX_PWR-rf_pwr_diff;
- //RTPRINT(FPHY, PHY_TXPWR, ("rfa_upper_bound= %d\n", rfa_upper_bound));
- }
- }
-
- for (i= 0; i <4; i++)
- {
- rfa_pwr[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8));
- if (rfa_pwr[i] > RF6052_MAX_TX_PWR)
- rfa_pwr[i] = RF6052_MAX_TX_PWR;
-
- //
- // If path A and Path B coexist, we must limit Path A tx power.
- // Protect Path B pwr under/over flow. We need to calculate upper and
- // lower bound of path A tx power.
- //
- if (priv->rf_type == RF_2T2R)
- {
- if (rf_pwr_diff >= 8) // Diff=-8~-1
- { // Prevent underflow!!
- if (rfa_pwr[i] <rfa_lower_bound)
- {
- //RTPRINT(FPHY, PHY_TXPWR, ("Underflow"));
- rfa_pwr[i] = rfa_lower_bound;
- }
- }
- else if (rf_pwr_diff >= 1) // Diff = 0-7
- { // Prevent overflow
- if (rfa_pwr[i] > rfa_upper_bound)
- {
- //RTPRINT(FPHY, PHY_TXPWR, ("Overflow"));
- rfa_pwr[i] = rfa_upper_bound;
- }
- }
- //RTPRINT(FPHY, PHY_TXPWR, ("rfa_pwr[%d]=%x\n", i, rfa_pwr[i]));
- }
-
- }
-
- //
- // Add description: PWDB > threshold!!!High power issue!!
- // We must decrease tx power !! Why is the value ???
- //
- if(priv->bDynamicTxHighPower == TRUE)
- {
- // For MCS rate
- if(index > 1)
- {
- writeVal = 0x03030303;
- }
- // For Legacy rate
- else
- {
- writeVal = (rfa_pwr[3]<<24) | (rfa_pwr[2]<<16) |(rfa_pwr[1]<<8) |rfa_pwr[0];
- }
- //RTPRINT(FPHY, PHY_TXPWR, ("HighPower=%08x\n", writeVal));
- }
- else
- {
- writeVal = (rfa_pwr[3]<<24) | (rfa_pwr[2]<<16) |(rfa_pwr[1]<<8) |rfa_pwr[0];
- //RTPRINT(FPHY, PHY_TXPWR, ("NormalPower=%08x\n", writeVal));
- }
-
- //
- // Write different rate set tx power index.
- //
- //if (DCMD_Test_Flag == 0)
- rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
- }
-
-} /* PHY_RF6052SetOFDMTxPower */
-#else
-extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 writeVal, powerBase0, powerBase1;
- u8 index = 0;
- u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
- u8 byte0, byte1, byte2, byte3;
- u8 channel = priv->ieee80211->current_network.channel;
-
- //Legacy OFDM rates
- powerBase0 = powerlevel + (priv->LegacyHTTxPowerDiff & 0xf);
- powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
-
- //MCS rates HT OFDM
- powerBase1 = powerlevel;
- powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
-
- //printk("Legacy/HT PWR= %x/%x\n", powerBase0, powerBase1);
-
- for(index=0; index<6; index++)
- {
- //
- // Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate
- //
- writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
-
- //printk("Index = %d Original=%x writeVal=%x\n", index, priv->MCSTxPowerLevelOriginalOffset[index], writeVal);
-
- byte0 = (u8)(writeVal & 0x7f);
- byte1 = (u8)((writeVal & 0x7f00)>>8);
- byte2 = (u8)((writeVal & 0x7f0000)>>16);
- byte3 = (u8)((writeVal & 0x7f000000)>>24);
-
- // Max power index = 0x3F Range = 0-0x3F
- if(byte0 > RF6052_MAX_TX_PWR)
- byte0 = RF6052_MAX_TX_PWR;
- if(byte1 > RF6052_MAX_TX_PWR)
- byte1 = RF6052_MAX_TX_PWR;
- if(byte2 > RF6052_MAX_TX_PWR)
- byte2 = RF6052_MAX_TX_PWR;
- if(byte3 > RF6052_MAX_TX_PWR)
- byte3 = RF6052_MAX_TX_PWR;
-
- //
- // Add description: PWDB > threshold!!!High power issue!!
- // We must decrease tx power !! Why is the value ???
- //
- if(priv->bDynamicTxHighPower == true)
- {
- // For MCS rate
- if(index > 1)
- {
- writeVal = 0x03030303;
- }
- // For Legacy rate
- else
- {
- writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
- }
- }
- else
- {
- writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
- }
-
- //
- // Write different rate set tx power index.
- //
- rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
- }
-
-} /* PHY_RF6052SetOFDMTxPower */
-#endif
-
-RT_STATUS PHY_RF6052_Config(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
- //RF90_RADIO_PATH_E eRFPath;
- //BB_REGISTER_DEFINITION_T *pPhyReg;
- //u32 OrgStoreRFIntSW[RF90_PATH_D+1];
-
- //
- // Initialize general global value
- //
- // TODO: Extend RF_PATH_C and RF_PATH_D in the future
- if(priv->rf_type == RF_1T1R)
- priv->NumTotalRFPath = 1;
- else
- priv->NumTotalRFPath = 2;
-
- //
- // Config BB and RF
- //
-// switch( priv->bRegHwParaFile )
-// {
-// case 0:
-// phy_RF6052_Config_HardCode(dev);
-// break;
-
-// case 1:
- rtStatus = phy_RF6052_Config_ParaFile(dev);
-// break;
-
-// case 2:
- // Partial Modify.
-// phy_RF6052_Config_HardCode(dev);
-// phy_RF6052_Config_ParaFile(dev);
-// break;
-
-// default:
-// phy_RF6052_Config_HardCode(dev);
-// break;
-// }
- return rtStatus;
-
-}
-
-void phy_RF6052_Config_HardCode(struct net_device* dev)
-{
-
- // Set Default Bandwidth to 20M
- //Adapter->HalFunc .SetBWModeHandler(Adapter, HT_CHANNEL_WIDTH_20);
-
- // TODO: Set Default Channel to channel one for RTL8225
-
-}
-
-RT_STATUS phy_RF6052_Config_ParaFile(struct net_device* dev)
-{
- u32 u4RegValue = 0;
- //static s1Byte szRadioAFile[] = RTL819X_PHY_RADIO_A;
- //static s1Byte szRadioBFile[] = RTL819X_PHY_RADIO_B;
- //static s1Byte szRadioBGMFile[] = RTL819X_PHY_RADIO_B_GM;
- u8 eRFPath;
- RT_STATUS rtStatus = RT_STATUS_SUCCESS;
- struct r8192_priv *priv = ieee80211_priv(dev);
- BB_REGISTER_DEFINITION_T *pPhyReg;
- //u8 eCheckItem;
-
-
- //3//-----------------------------------------------------------------
- //3// <2> Initialize RF
- //3//-----------------------------------------------------------------
- //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
-
- pPhyReg = &priv->PHYRegDef[eRFPath];
-
- /*----Store original RFENV control type----*/
- switch(eRFPath)
- {
- case RF90_PATH_A:
- case RF90_PATH_C:
- u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
- break;
- case RF90_PATH_B :
- case RF90_PATH_D:
- u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
- break;
- }
-
- /*----Set RF_ENV enable----*/
- rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
-
- /*----Set RF_ENV output high----*/
- rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
-
- /* Set bit number of Address and Data for RF register */
- rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 1 to 4 bits for 8255
- rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for 8255
-
-
- /*----Initialize RF fom connfiguration file----*/
- switch(eRFPath)
- {
- case RF90_PATH_A:
- rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
- break;
- case RF90_PATH_B:
- rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
- break;
- case RF90_PATH_C:
- break;
- case RF90_PATH_D:
- break;
- }
-
- /*----Restore RFENV control type----*/;
- switch(eRFPath)
- {
- case RF90_PATH_A:
- case RF90_PATH_C:
- rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
- break;
- case RF90_PATH_B :
- case RF90_PATH_D:
- rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
- break;
- }
-
- if(rtStatus != RT_STATUS_SUCCESS){
- printk("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
- goto phy_RF6052_Config_ParaFile_Fail;
- }
-
- }
-
- RT_TRACE(COMP_INIT, "<---phy_RF6052_Config_ParaFile()\n");
- return rtStatus;
-
-phy_RF6052_Config_ParaFile_Fail:
- return rtStatus;
-}
-
-
-//
-// ==> RF shadow Operation API Code Section!!!
-//
-/*-----------------------------------------------------------------------------
- * Function: PHY_RFShadowRead
- * PHY_RFShadowWrite
- * PHY_RFShadowCompare
- * PHY_RFShadowRecorver
- * PHY_RFShadowCompareAll
- * PHY_RFShadowRecorverAll
- * PHY_RFShadowCompareFlagSet
- * PHY_RFShadowRecorverFlagSet
- *
- * Overview: When we set RF register, we must write shadow at first.
- * When we are running, we must compare shadow abd locate error addr.
- * Decide to recorver or not.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/20/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern u32 PHY_RFShadowRead(
- struct net_device * dev,
- RF90_RADIO_PATH_E eRFPath,
- u32 Offset)
-{
- return RF_Shadow[eRFPath][Offset].Value;
-
-} /* PHY_RFShadowRead */
-
-
-extern void PHY_RFShadowWrite(
- struct net_device * dev,
- u32 eRFPath,
- u32 Offset,
- u32 Data)
-{
- //RF_Shadow[eRFPath][Offset].Value = (Data & bMask20Bits);
- RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask);
- RF_Shadow[eRFPath][Offset].Driver_Write = true;
-
-} /* PHY_RFShadowWrite */
-
-
-extern void PHY_RFShadowCompare(
- struct net_device * dev,
- RF90_RADIO_PATH_E eRFPath,
- u32 Offset)
-{
- u32 reg;
-
- // Check if we need to check the register
- if (RF_Shadow[eRFPath][Offset].Compare == true)
- {
- reg = rtl8192_phy_QueryRFReg(dev, eRFPath, Offset, bRFRegOffsetMask);
- // Compare shadow and real rf register for 20bits!!
- if (RF_Shadow[eRFPath][Offset].Value != reg)
- {
- // Locate error position.
- RF_Shadow[eRFPath][Offset].ErrorOrNot = true;
- RT_TRACE(COMP_INIT, "PHY_RFShadowCompare RF-%d Addr%02xErr = %05x", eRFPath, Offset, reg);
- }
- }
-
-} /* PHY_RFShadowCompare */
-
-extern void PHY_RFShadowRecorver(
- struct net_device * dev,
- RF90_RADIO_PATH_E eRFPath,
- u32 Offset)
-{
- // Check if the address is error
- if (RF_Shadow[eRFPath][Offset].ErrorOrNot == true)
- {
- // Check if we need to recorver the register.
- if (RF_Shadow[eRFPath][Offset].Recorver == true)
- {
- rtl8192_phy_SetRFReg(dev, eRFPath, Offset, bRFRegOffsetMask, RF_Shadow[eRFPath][Offset].Value);
- RT_TRACE(COMP_INIT, "PHY_RFShadowRecorver RF-%d Addr%02x=%05x",
- eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value);
- }
- }
-
-} /* PHY_RFShadowRecorver */
-
-
-extern void PHY_RFShadowCompareAll(struct net_device * dev)
-{
- u32 eRFPath;
- u32 Offset;
-
- for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
- {
- for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
- {
- PHY_RFShadowCompare(dev, (RF90_RADIO_PATH_E)eRFPath, Offset);
- }
- }
-
-} /* PHY_RFShadowCompareAll */
-
-
-extern void PHY_RFShadowRecorverAll(struct net_device * dev)
-{
- u32 eRFPath;
- u32 Offset;
-
- for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
- {
- for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
- {
- PHY_RFShadowRecorver(dev, (RF90_RADIO_PATH_E)eRFPath, Offset);
- }
- }
-
-} /* PHY_RFShadowRecorverAll */
-
-
-extern void PHY_RFShadowCompareFlagSet(
- struct net_device * dev,
- RF90_RADIO_PATH_E eRFPath,
- u32 Offset,
- u8 Type)
-{
- // Set True or False!!!
- RF_Shadow[eRFPath][Offset].Compare = Type;
-
-} /* PHY_RFShadowCompareFlagSet */
-
-
-extern void PHY_RFShadowRecorverFlagSet(
- struct net_device * dev,
- RF90_RADIO_PATH_E eRFPath,
- u32 Offset,
- u8 Type)
-{
- // Set True or False!!!
- RF_Shadow[eRFPath][Offset].Recorver= Type;
-
-} /* PHY_RFShadowRecorverFlagSet */
-
-
-extern void PHY_RFShadowCompareFlagSetAll(struct net_device * dev)
-{
- u32 eRFPath;
- u32 Offset;
-
- for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
- {
- for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
- {
- // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
- if (Offset != 0x26 && Offset != 0x27)
- PHY_RFShadowCompareFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, FALSE);
- else
- PHY_RFShadowCompareFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, TRUE);
- }
- }
-
-} /* PHY_RFShadowCompareFlagSetAll */
-
-
-extern void PHY_RFShadowRecorverFlagSetAll(struct net_device * dev)
-{
- u32 eRFPath;
- u32 Offset;
-
- for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
- {
- for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
- {
- // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!!
- if (Offset != 0x26 && Offset != 0x27)
- PHY_RFShadowRecorverFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, FALSE);
- else
- PHY_RFShadowRecorverFlagSet(dev, (RF90_RADIO_PATH_E)eRFPath, Offset, TRUE);
- }
- }
-
-} /* PHY_RFShadowCompareFlagSetAll */
-
-
-
-extern void PHY_RFShadowRefresh(struct net_device * dev)
-{
- u32 eRFPath;
- u32 Offset;
-
- for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++)
- {
- for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++)
- {
- RF_Shadow[eRFPath][Offset].Value = 0;
- RF_Shadow[eRFPath][Offset].Compare = false;
- RF_Shadow[eRFPath][Offset].Recorver = false;
- RF_Shadow[eRFPath][Offset].ErrorOrNot = false;
- RF_Shadow[eRFPath][Offset].Driver_Write = false;
- }
- }
-
-} /* PHY_RFShadowRead */
-
-/* End of HalRf6052.c */
diff --git a/drivers/staging/rtl8192su/r8192S_rtl6052.h b/drivers/staging/rtl8192su/r8192S_rtl6052.h
deleted file mode 100644
index 3dcc9bb76394..000000000000
--- a/drivers/staging/rtl8192su/r8192S_rtl6052.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/******************************************************************************
- *
- * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
- *
- * Module: HalRf.h ( Header File)
- *
- * Note: Collect every HAL RF type exter API or constant.
- *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- *
- * 09/25/2008 MHC Create initial version.
- *
- *
-******************************************************************************/
-/* Check to see if the file has been included already. */
-
-
-/*--------------------------Define Parameters-------------------------------*/
-
-//
-// For RF 6052 Series
-//
-#define RF6052_MAX_TX_PWR 0x3F
-#define RF6052_MAX_REG 0x3F
-#define RF6052_MAX_PATH 4
-/*--------------------------Define Parameters-------------------------------*/
-
-
-/*------------------------------Define structure----------------------------*/
-
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export global variable----------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-
-/*--------------------------Exported Function prototype---------------------*/
-//======================================================
-#if 1
-// Function prototypes for HalPhy8225.c
-//1======================================================
-extern void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); //20M or 40M;
-extern void PHY_SetRF8225Bandwidth( struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern bool PHY_RF8225_Config(struct net_device* dev );
-extern void phy_RF8225_Config_HardCode(struct net_device* dev);
-extern bool phy_RF8225_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8225CckTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel);
-
-//1======================================================
-// Function prototypes for HalPhy8256.c
-//1======================================================
-extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern void PHY_RF8256_Config(struct net_device* dev);
-extern void phy_RF8256_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel);
-extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
-#endif
-
-//
-// RF RL6052 Series API
-//
-extern void RF_ChangeTxPath(struct net_device * dev, u16 DataRate);
-extern void PHY_RF6052SetBandwidth(struct net_device * dev,HT_CHANNEL_WIDTH Bandwidth);
-extern void PHY_RF6052SetCckTxPower(struct net_device * dev, u8 powerlevel);
-extern void PHY_RF6052SetOFDMTxPower(struct net_device * dev, u8 powerlevel);
-extern RT_STATUS PHY_RF6052_Config(struct net_device * dev);
-extern void PHY_RFShadowRefresh( struct net_device * dev);
-extern void PHY_RFShadowWrite( struct net_device* dev, u32 eRFPath, u32 Offset, u32 Data);
-/*--------------------------Exported Function prototype---------------------*/
-
-
-/* End of HalRf.h */
diff --git a/drivers/staging/rtl8192su/r8192S_rtl8225.c b/drivers/staging/rtl8192su/r8192S_rtl8225.c
deleted file mode 100644
index 09465df2def6..000000000000
--- a/drivers/staging/rtl8192su/r8192S_rtl8225.c
+++ /dev/null
@@ -1,292 +0,0 @@
-
-#include "r8192U.h"
-#include "r8192S_hw.h"
-#include "r8192S_phyreg.h"
-#include "r8192S_phy.h"
-#include "r8192S_rtl8225.h"
-
-/*---------------------Define local function prototype-----------------------*/
-void phy_RF8225_Config_HardCode(struct net_device* dev );
-bool phy_RF8225_Config_ParaFile(struct net_device* dev );
-/*---------------------Define local function prototype-----------------------*/
-void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel)
-{
-
-}
-
-
-
-void PHY_SetRF8225CckTxPower( struct net_device* dev , u8 powerlevel)
-{
-
-}
-
-
-// TODO: The following RF 022D related function should be removed to HalPhy0222D.c.
-void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel)
-{
- //TODO: We should set RF TxPower for RF 0222D here!!
-}
-
-
-
-void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel)
-{
- //TODO: We should set RF TxPower for RF 0222D here!!
-}
-
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_SetRF0222DBandwidth()
- *
- * Overview: This function is called by SetBWModeCallback8190Pci() only
- *
- * Input: PADAPTER Adapter
- * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: For RF type 0222D
- *---------------------------------------------------------------------------*/
- //just in phy
-void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
-{
- u8 eRFPath;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-
- //if (IS_HARDWARE_TYPE_8192S(dev))
- if (1)
- {
-#ifndef RTL92SE_FPGA_VERIFY
- switch(Bandwidth)
- {
- case HT_CHANNEL_WIDTH_20:
-#ifdef FIB_MODIFICATION
- write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
-#endif
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x01);
- break;
- case HT_CHANNEL_WIDTH_20_40:
-#ifdef FIB_MODIFICATION
- write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x18);
-#endif
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, BIT10|BIT11, 0x00);
- break;
- default:
- ;//RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ));
- break;
- }
-#endif
- }
- else
- {
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
- switch(Bandwidth)
- {
- case HT_CHANNEL_WIDTH_20:
- //rtl8192_phy_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x01);
- break;
- case HT_CHANNEL_WIDTH_20_40:
- //rtl8192_phy_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x00);
- break;
- default:
- ;//RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ));
- break;
-
- }
- }
- }
-
-}
-
-// TODO: Aabove RF 022D related function should be removed to HalPhy0222D.c.
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_SetRF8225Bandwidth()
- *
- * Overview: This function is called by SetBWModeCallback8190Pci() only
- *
- * Input: PADAPTER Adapter
- * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: 8225(zebra1) support 20M only
- *---------------------------------------------------------------------------*/
- //just in phy
-void PHY_SetRF8225Bandwidth(struct net_device* dev ,HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
-{
- u8 eRFPath;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
- switch(Bandwidth)
- {
- case HT_CHANNEL_WIDTH_20:
- // TODO: Update the parameters here
- break;
- case HT_CHANNEL_WIDTH_20_40:
- RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():8225 does not support 40M mode\n");
- break;
- default:
- RT_TRACE(COMP_DBG, "PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
- break;
-
- }
- }
-
-}
-
-//just in phy
-bool PHY_RF8225_Config(struct net_device* dev )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool rtStatus = true;
- //RF90_RADIO_PATH_E eRFPath;
- //BB_REGISTER_DEFINITION_T *pPhyReg;
- //u32 OrgStoreRFIntSW[RF90_PATH_D+1];
-
- //
- // Initialize general global value
- //
- // TODO: Extend RF_PATH_C and RF_PATH_D in the future
- priv->NumTotalRFPath = 2;
-
- //
- // Config BB and RF
- //
- //switch( Adapter->MgntInfo.bRegHwParaFile )
- //{
- // case 0:
- // phy_RF8225_Config_HardCode(dev);
- // break;
-
- // case 1:
- // rtStatus = phy_RF8225_Config_ParaFile(dev);
- // break;
-
- // case 2:
- // Partial Modify.
- phy_RF8225_Config_HardCode(dev);
- phy_RF8225_Config_ParaFile(dev);
- // break;
-
- // default:
- // phy_RF8225_Config_HardCode(dev);
- // break;
- //}
- return rtStatus;
-
-}
-
-//just in 8225
-void phy_RF8225_Config_HardCode(struct net_device* dev)
-{
-
- // Set Default Bandwidth to 20M
- //Adapter->HalFunc .SetBWModeHandler(Adapter, HT_CHANNEL_WIDTH_20);
-
- // TODO: Set Default Channel to channel one for RTL8225
-
-}
-
-//just in 8225
-bool phy_RF8225_Config_ParaFile(struct net_device* dev)
-{
- u32 u4RegValue = 0;
- //static char szRadioAFile[] = RTL819X_PHY_RADIO_A;
- //static char szRadioBFile[] = RTL819X_PHY_RADIO_B;
- u8 eRFPath;
- bool rtStatus = true;
- struct r8192_priv *priv = ieee80211_priv(dev);
- BB_REGISTER_DEFINITION_T *pPhyReg;
- //u8 eCheckItem;
-
-#if 1
- //3//-----------------------------------------------------------------
- //3// <2> Initialize RF
- //3//-----------------------------------------------------------------
- //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
-
- pPhyReg = &priv->PHYRegDef[eRFPath];
-
- /*----Store original RFENV control type----*/
- switch(eRFPath)
- {
- case RF90_PATH_A:
- case RF90_PATH_C:
- u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
- break;
- case RF90_PATH_B :
- case RF90_PATH_D:
- u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
- break;
- }
-
- /*----Set RF_ENV enable----*/
- rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
-
- /*----Set RF_ENV output high----*/
- rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
-
- /* Set bit number of Address and Data for RF register */
- rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 1 to 4 bits for 8255
- rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for 8255
-
-
- /*----Initialize RF fom connfiguration file----*/
- switch(eRFPath)
- {
- case RF90_PATH_A:
- //rtStatus = PHY_ConfigRFWithParaFile(dev, (char* )&szRadioAFile, (RF90_RADIO_PATH_E)eRFPath);
- rtStatus = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
- break;
- case RF90_PATH_B:
- //rtStatus = PHY_ConfigRFWithParaFile(dev, (char* )&szRadioBFile, (RF90_RADIO_PATH_E)eRFPath);
- rtStatus = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
- break;
- case RF90_PATH_C:
- break;
- case RF90_PATH_D:
- break;
- }
-
- /*----Restore RFENV control type----*/;
- switch(eRFPath)
- {
- case RF90_PATH_A:
- case RF90_PATH_C:
- rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
- break;
- case RF90_PATH_B :
- case RF90_PATH_D:
- rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
- break;
- }
-
- if(rtStatus == false){
- //RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF8225_Config_ParaFile():Radio[%d] Fail!!", eRFPath));
- goto phy_RF8225_Config_ParaFile_Fail;
- }
-
- }
-
- //RT_TRACE(COMP_INIT, DBG_LOUD, ("<---phy_RF8225_Config_ParaFile()\n"));
- return rtStatus;
-
-phy_RF8225_Config_ParaFile_Fail:
-#endif
- return rtStatus;
-}
-
-
diff --git a/drivers/staging/rtl8192su/r8192S_rtl8225.h b/drivers/staging/rtl8192su/r8192S_rtl8225.h
deleted file mode 100644
index 8a647284af35..000000000000
--- a/drivers/staging/rtl8192su/r8192S_rtl8225.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- This is part of the rtl8180-sa2400 driver
- released under the GPL (See file COPYING for details).
- Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
- This files contains programming code for the rtl8256
- radio frontend.
-
- *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#ifndef RTL8225H
-#define RTL8225H
-
-#ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH 4 //for 90P
-#else
-#define RTL819X_TOTAL_RF_PATH 2 //for 8192U
-#endif
-extern void PHY_SetRF0222DBandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth); //20M or 40M;
-extern void PHY_SetRF8225Bandwidth( struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern bool PHY_RF8225_Config(struct net_device* dev );
-extern void phy_RF8225_Config_HardCode(struct net_device* dev);
-extern bool phy_RF8225_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8225CckTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF8225OfdmTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF0222DOfdmTxPower(struct net_device* dev ,u8 powerlevel);
-extern void PHY_SetRF0222DCckTxPower(struct net_device* dev ,u8 powerlevel);
-#endif
diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h
deleted file mode 100644
index 741c6bf9a018..000000000000
--- a/drivers/staging/rtl8192su/r8192U.h
+++ /dev/null
@@ -1,1519 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- * Linux device driver for RTL8192U
- *
- * Based on the r8187 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-#ifndef R819xU_H
-#define R819xU_H
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/usb.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h> //for rtnl_lock()
-#include <linux/wireless.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h> // Necessary because we use the proc fs
-#include <linux/if_arp.h>
-#include <linux/random.h>
-#include <linux/version.h>
-#include <asm/io.h>
-
-#include "ieee80211/ieee80211.h"
-
-#include "r8192S_firmware.h"
-#include "r8192SU_led.h"
-
-/* EEPROM defs for use with linux/eeprom_93cx6.h */
-#define RTL819X_EEPROM_CMD_READ (1 << 0)
-#define RTL819X_EEPROM_CMD_WRITE (1 << 1)
-#define RTL819X_EEPROM_CMD_CK (1 << 2)
-#define RTL819X_EEPROM_CMD_CS (1 << 3)
-
-#define RTL819xU_MODULE_NAME "rtl819xU"
-#define FALSE 0
-#define TRUE 1
-#define MAX_KEY_LEN 61
-#define KEY_BUF_SIZE 5
-
-#define BIT0 0x00000001
-#define BIT1 0x00000002
-#define BIT2 0x00000004
-#define BIT3 0x00000008
-#define BIT4 0x00000010
-#define BIT5 0x00000020
-#define BIT6 0x00000040
-#define BIT7 0x00000080
-#define BIT8 0x00000100
-#define BIT9 0x00000200
-#define BIT10 0x00000400
-#define BIT11 0x00000800
-#define BIT12 0x00001000
-#define BIT13 0x00002000
-#define BIT14 0x00004000
-#define BIT15 0x00008000
-#define BIT16 0x00010000
-#define BIT17 0x00020000
-#define BIT18 0x00040000
-#define BIT19 0x00080000
-#define BIT20 0x00100000
-#define BIT21 0x00200000
-#define BIT22 0x00400000
-#define BIT23 0x00800000
-#define BIT24 0x01000000
-#define BIT25 0x02000000
-#define BIT26 0x04000000
-#define BIT27 0x08000000
-#define BIT28 0x10000000
-#define BIT29 0x20000000
-#define BIT30 0x40000000
-#define BIT31 0x80000000
-
-// Rx smooth factor
-#define Rx_Smooth_Factor 20
-#define DMESG(x,a...)
-#define DMESGW(x,a...)
-#define DMESGE(x,a...)
-extern u32 rt_global_debug_component;
-#define RT_TRACE(component, x, args...) \
-do { if(rt_global_debug_component & component) \
- printk(KERN_DEBUG RTL819xU_MODULE_NAME ":" x "\n" , \
- ##args);\
-}while(0);
-//----------------------------------------------------------------------
-//// Get 8192SU Rx descriptor. Added by Roger, 2008.04.15.
-////----------------------------------------------------------------------
-#define RX_DESC_SIZE 24
-#define RX_DRV_INFO_SIZE_UNIT 8
-
-#define IS_UNDER_11N_AES_MODE(_ieee) ((_ieee->pHTInfo->bCurrentHTSupport==TRUE) &&\
- (_ieee->pairwise_key_type==KEY_TYPE_CCMP))
-
-#define COMP_TRACE BIT0 // For function call tracing.
-#define COMP_DBG BIT1 // Only for temporary debug message.
-#define COMP_MLME BIT1
-#define COMP_INIT BIT2 // during driver initialization / halt / reset.
-
-
-#define COMP_RECV BIT3 // Reveive part data path.
-#define COMP_SEND BIT4 // Send part path.
-#define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02.
-#define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related.
-#define COMP_EPROM BIT7 // 802.11 link related: join/start BSS, leave BSS.
-#define COMP_SWBW BIT8 // For bandwidth switch.
-#define COMP_POWER_TRACKING BIT9 //FOR 8190 TX POWER TRACKING
-#define COMP_TURBO BIT10 // For Turbo Mode related. By Annie, 2005-10-21.
-#define COMP_QOS BIT11 // For QoS.
-#define COMP_RATE BIT12 // For Rate Adaptive mechanism, 2006.07.02, by rcnjko.
-#define COMP_LPS BIT13 // For Radio Measurement.
-#define COMP_DIG BIT14 // For DIG, 2006.09.25, by rcnjko.
-#define COMP_PHY BIT15
-#define COMP_CH BIT16 //channel setting debug
-#define COMP_TXAGC BIT17 // For Tx power, 060928, by rcnjko.
-#define COMP_HIPWR BIT18 // For High Power Mechanism, 060928, by rcnjko.
-#define COMP_HALDM BIT19 // For HW Dynamic Mechanism, 061010, by rcnjko.
-#define COMP_SEC BIT20 // Event handling
-#define COMP_LED BIT21 // For LED.
-#define COMP_RF BIT22 // For RF.
-#define COMP_RXDESC BIT23
-
-#define COMP_RXDESC BIT23 // Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15.
-
-#define COMP_FIRMWARE BIT24 //for firmware downloading
-#define COMP_HT BIT25 // For 802.11n HT related information. by Emily 2006-8-11
-#define COMP_AMSDU BIT26 // For A-MSDU Debugging
-#define COMP_PS BIT26
-
-#define COMP_SCAN BIT27
-#define COMP_CMD BIT28
-#define COMP_DOWN BIT29 //for rm driver module
-#define COMP_RESET BIT30 //for silent reset
-#define COMP_ERR BIT31 //for error out, always on
-
-#define RTL819x_DEBUG
-#ifdef RTL819x_DEBUG
-#define assert(expr) \
- if (!(expr)) { \
- printk( "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
- }
-
-#define RT_DEBUG_DATA(level, data, datalen) \
- do{ if ((rt_global_debug_component & (level)) == (level)) \
- { \
- int i; \
- u8* pdata = (u8*) data; \
- printk(KERN_DEBUG RTL819xU_MODULE_NAME ": %s()\n", __FUNCTION__); \
- for(i=0; i<(int)(datalen); i++) \
- { \
- printk("%2x ", pdata[i]); \
- if ((i+1)%16 == 0) printk("\n"); \
- } \
- printk("\n"); \
- } \
- } while (0)
-#else
-#define assert(expr) do {} while (0)
-#define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
-#endif /* RTL8169_DEBUG */
-
- //2TODO: We should define 8192S firmware related macro settings here!!
- #define RTL819X_DEFAULT_RF_TYPE RF_1T2R
- #define RTL819X_TOTAL_RF_PATH 2
-
- #define Rtl819XMACPHY_Array_PG Rtl8192UsbMACPHY_Array_PG
- #define Rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
- #define Rtl819XPHY_REGArray Rtl8192UsbPHY_REGArray
- #define Rtl819XPHY_REG_1T2RArray Rtl8192UsbPHY_REG_1T2RArray
- #define Rtl819XRadioC_Array Rtl8192UsbRadioC_Array
- #define Rtl819XRadioD_Array Rtl8192UsbRadioD_Array
-
- #define Rtl819XFwImageArray Rtl8192SUFwImgArray
- #define Rtl819XMAC_Array Rtl8192SUMAC_2T_Array
- #define Rtl819XAGCTAB_Array Rtl8192SUAGCTAB_Array
- #define Rtl819XPHY_REG_Array Rtl8192SUPHY_REG_2T2RArray
- #define Rtl819XPHY_REG_to1T1R_Array Rtl8192SUPHY_ChangeTo_1T1RArray
- #define Rtl819XPHY_REG_to1T2R_Array Rtl8192SUPHY_ChangeTo_1T2RArray
- #define Rtl819XPHY_REG_to2T2R_Array Rtl8192SUPHY_ChangeTo_2T2RArray
- #define Rtl819XPHY_REG_Array_PG Rtl8192SUPHY_REG_Array_PG
- #define Rtl819XRadioA_Array Rtl8192SURadioA_1T_Array
- #define Rtl819XRadioB_Array Rtl8192SURadioB_Array
- #define Rtl819XRadioB_GM_Array Rtl8192SURadioB_GM_Array
- #define Rtl819XRadioA_to1T_Array Rtl8192SURadioA_to1T_Array
- #define Rtl819XRadioA_to2T_Array Rtl8192SURadioA_to2T_Array
-//
-// Queue Select Value in TxDesc
-//
-#define QSLT_BK 0x1
-#define QSLT_BE 0x0
-#define QSLT_VI 0x4
-#define QSLT_VO 0x6
-#define QSLT_BEACON 0x10
-#define QSLT_HIGH 0x11
-#define QSLT_MGNT 0x12
-#define QSLT_CMD 0x13
-
-#define DESC90_RATE1M 0x00
-#define DESC90_RATE2M 0x01
-#define DESC90_RATE5_5M 0x02
-#define DESC90_RATE11M 0x03
-#define DESC90_RATE6M 0x04
-#define DESC90_RATE9M 0x05
-#define DESC90_RATE12M 0x06
-#define DESC90_RATE18M 0x07
-#define DESC90_RATE24M 0x08
-#define DESC90_RATE36M 0x09
-#define DESC90_RATE48M 0x0a
-#define DESC90_RATE54M 0x0b
-#define DESC90_RATEMCS0 0x00
-#define DESC90_RATEMCS1 0x01
-#define DESC90_RATEMCS2 0x02
-#define DESC90_RATEMCS3 0x03
-#define DESC90_RATEMCS4 0x04
-#define DESC90_RATEMCS5 0x05
-#define DESC90_RATEMCS6 0x06
-#define DESC90_RATEMCS7 0x07
-#define DESC90_RATEMCS8 0x08
-#define DESC90_RATEMCS9 0x09
-#define DESC90_RATEMCS10 0x0a
-#define DESC90_RATEMCS11 0x0b
-#define DESC90_RATEMCS12 0x0c
-#define DESC90_RATEMCS13 0x0d
-#define DESC90_RATEMCS14 0x0e
-#define DESC90_RATEMCS15 0x0f
-#define DESC90_RATEMCS32 0x20
-
-// CCK Rates, TxHT = 0
-#define DESC92S_RATE1M 0x00
-#define DESC92S_RATE2M 0x01
-#define DESC92S_RATE5_5M 0x02
-#define DESC92S_RATE11M 0x03
-
-// OFDM Rates, TxHT = 0
-#define DESC92S_RATE6M 0x04
-#define DESC92S_RATE9M 0x05
-#define DESC92S_RATE12M 0x06
-#define DESC92S_RATE18M 0x07
-#define DESC92S_RATE24M 0x08
-#define DESC92S_RATE36M 0x09
-#define DESC92S_RATE48M 0x0a
-#define DESC92S_RATE54M 0x0b
-
-// MCS Rates, TxHT = 1
-#define DESC92S_RATEMCS0 0x0c
-#define DESC92S_RATEMCS1 0x0d
-#define DESC92S_RATEMCS2 0x0e
-#define DESC92S_RATEMCS3 0x0f
-#define DESC92S_RATEMCS4 0x10
-#define DESC92S_RATEMCS5 0x11
-#define DESC92S_RATEMCS6 0x12
-#define DESC92S_RATEMCS7 0x13
-#define DESC92S_RATEMCS8 0x14
-#define DESC92S_RATEMCS9 0x15
-#define DESC92S_RATEMCS10 0x16
-#define DESC92S_RATEMCS11 0x17
-#define DESC92S_RATEMCS12 0x18
-#define DESC92S_RATEMCS13 0x19
-#define DESC92S_RATEMCS14 0x1a
-#define DESC92S_RATEMCS15 0x1b
-#define DESC92S_RATEMCS15_SG 0x1c
-#define DESC92S_RATEMCS32 0x20
-
-#define RTL819X_DEFAULT_RF_TYPE RF_1T2R
-
-#define IEEE80211_WATCH_DOG_TIME 2000
-#define PHY_Beacon_RSSI_SLID_WIN_MAX 10
-//for txpowertracking
-#define OFDM_Table_Length 19
-#define CCK_Table_length 12
-
-//
-//Tx Descriptor for RLT8192SU(Normal mode)
-//
-typedef struct _tx_desc_819x_usb {
- // DWORD 0
- u16 PktSize;//:16;
- u8 Offset;//:8;
- u8 Type:2; // Reserved for MAC header Frame Type subfield.
- u8 LastSeg:1;
- u8 FirstSeg:1;
- u8 LINIP:1;
- u8 AMSDU:1;
- u8 GF:1;
- u8 OWN:1;
-
- // DWORD 1
- u8 MacID:5;
- u8 MoreData:1;
- u8 MOREFRAG:1;
- u8 PIFS:1;
- u8 QueueSelect:5;
- u8 AckPolicy:2;
- u8 NoACM:1;
- u8 NonQos:1;
- u8 KeyID:2;
- u8 OUI:1;
- u8 PktType:1;
- u8 EnDescID:1;
- u8 SecType:2;
- u8 HTC:1; //padding0
- u8 WDS:1; //padding1
- u8 PktOffset:5; //padding_len (hw)
- u8 HWPC:1;
-
- // DWORD 2
- u32 DataRetryLmt:6;
- u32 RetryLmtEn:1;
- u32 TSFL:5;
- u32 RTSRC:6; // Reserved for HW RTS Retry Count.
- u32 DATARC:6; // Reserved for HW DATA Retry Count.
- u32 Rsvd1:5;
- u32 AllowAggregation:1;
- u32 BK:1; //Aggregation break.
- u32 OwnMAC:1;
-
- // DWORD 3
- u8 NextHeadPage;//:8;
- u8 TailPage;//:8;
- u16 Seq:12;
- u16 Frag:4;
-
- // DWORD 4
- u32 RTSRate:6;
- u32 DisRTSFB:1;
- u32 RTSRateFBLmt:4;
- u32 CTS2Self:1;
- u32 RTSEn:1;
- u32 RaBRSRID:3; //Rate adaptive BRSR ID.
- u32 TxHT:1;
- u32 TxShort:1;//for data
- u32 TxBandwidth:1;
- u32 TxSubCarrier:2;
- u32 STBC:2;
- u32 RD:1;
- u32 RTSHT:1;
- u32 RTSShort:1;
- u32 RTSBW:1;
- u32 RTSSubcarrier:2;
- u32 RTSSTBC:2;
- u32 USERATE:1;
- // DWORD 5
- u32 PktID:9;
- u32 TxRate:6;
- u32 DISFB:1;
- u32 DataRateFBLmt:5;
- u32 TxAGC:11;
-
- // DWORD 6
- u16 IPChkSum;//:16;
- u16 TCPChkSum;//:16;
-
- // DWORD 7
- //u16 TxBuffSize;//:16;//pcie
- u16 TxBufferSize;
- u16 IPHdrOffset:8;
- u16 Rsvd2:7;
- u16 TCPEn:1;
-}tx_desc_819x_usb, *ptx_desc_819x_usb;
-typedef struct _tx_status_desc_8192s_usb{
-
- //DWORD 0
- u8 TxRate:6;
- u8 Rsvd1:1;
- u8 BandWidth:1;
- u8 RTSRate:6;
- u8 AGGLS:1;
- u8 AGG:1;
- u8 RTSRC:6;
- u8 DataRC:6;
- u8 FailCause:2;
- u8 TxOK:1;
- u8 Own:1;
-
- //DWORD 1
- u16 Seq:12;
- u8 QueueSel:5;
- u8 MACID:5;
- u8 PwrMgt:1;
- u8 MoreData:1;
- u8 Rsvd2;
-
- //DWORD 2
- u8 RxAGC1;
- u8 RxAGC2;
- u8 RxAGC3;
- u8 RxAGC4;
-}tx_status_desc_8192s_usb, *ptx_status_desc_8192s_usb;
-
-
-
-//
-//Tx Descriptor for RLT8192SU(Load FW mode)
-//
-typedef struct _tx_desc_cmd_819x_usb{
- // DWORD 0
- u16 PktSize;
- u8 Offset;
- u8 Rsvd0:4;
- u8 LINIP:1;
- u8 Rsvd1:2;
- u8 OWN:1;
-
- // DWORD 1, 2, 3, 4, 5, 6 are all reserved.
- u32 Rsvd2;
- u32 Rsvd3;
- u32 Rsvd4;
- u32 Rsvd5;
- u32 Rsvd6;
- u32 Rsvd7;
-
- // DWORD 7
- u16 TxBuffSize;//pcie
- u16 Rsvd8;
-}tx_desc_cmd_819x_usb, *ptx_desc_cmd_819x_usb;
-//
-//H2C Command for RLT8192SU(Host TxCmd)
-//
-typedef struct _tx_h2c_desc_cmd_8192s_usb{
- // DWORD 0
- u32 PktSize:16;
- u32 Offset:8;
- u32 Rsvd0:7;
- u32 OWN:1;
-
- // DWORD 1
- u32 Rsvd1:8;
- u32 QSEL:5;
- u32 Rsvd2:19;
-
- // DWORD 2
- u32 Rsvd3;
-
- // DWORD 3
- u32 NextHeadPage:8;
- u32 TailPage:8;
- u32 Rsvd4:16;
-
- // DWORD 4, 5, 6, 7
- u32 Rsvd5;
- u32 Rsvd6;
- u32 Rsvd7;
- u32 Rsvd8;
-}tx_h2c_desc_cmd_8192s_usb, *ptx_h2c_desc_cmd_8192s_usb;
-
-
-typedef struct _tx_h2c_cmd_hdr_8192s_usb{
- // DWORD 0
- u32 CmdLen:16;
- u32 ElementID:8;
- u32 CmdSeq:8;
-
- // DWORD 1
- u32 Rsvd0;
-}tx_h2c_cmd_hdr_8192s_usb, *ptx_h2c_cmd_hdr_8192s_usb;
-
-typedef struct _tx_fwinfo_819x_usb{
- //DWORD 0
- u8 TxRate:7;
- u8 CtsEnable:1;
- u8 RtsRate:7;
- u8 RtsEnable:1;
- u8 TxHT:1;
- u8 Short:1; //Short PLCP for CCK, or short GI for 11n MCS
- u8 TxBandwidth:1; // This is used for HT MCS rate only.
- u8 TxSubCarrier:2; // This is used for legacy OFDM rate only.
- u8 STBC:2;
- u8 AllowAggregation:1;
- u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate
- u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS
- u8 RtsBandwidth:1; // This is used for HT MCS rate only.
- u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only.
- u8 RtsSTBC:2;
- u8 EnableCPUDur:1; //Enable firmware to recalculate and assign packet duration
-
- //DWORD 1
- u32 RxMF:2;
- u32 RxAMD:3;
- u32 Reserved1:3;
- u32 TxAGCOffSet:4;//TxAGCOffset:4;
- u32 TxAGCSign:1;
- u32 Tx_INFO_RSVD:6;
- u32 PacketID:13;
-}tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
-
-typedef struct rtl8192_rx_info {
- struct urb *urb;
- struct net_device *dev;
- u8 out_pipe;
-}rtl8192_rx_info ;
-
-typedef struct rx_desc_819x_usb{
- //DWORD 0
- u16 Length:14;
- u16 CRC32:1;
- u16 ICV:1;
- u8 RxDrvInfoSize:4;
- u8 Security:3;
- u8 Qos:1;
- u8 Shift:2;
- u8 PHYStatus:1;
- u8 SWDec:1;
- u8 LastSeg:1;
- u8 FirstSeg:1;
- u8 EOR:1;
- u8 Own:1;
-
- //DWORD 1
- u16 MACID:5;
- u16 TID:4;
- u16 HwRsvd:5;
- u16 PAGGR:1;
- u16 FAGGR:1;
- u8 A1_FIT:4;
- u8 A2_FIT:4;
- u8 PAM:1;
- u8 PWR:1;
- u8 MoreData:1;
- u8 MoreFrag:1;
- u8 Type:2;
- u8 MC:1;
- u8 BC:1;
-
- //DWORD 2
- u16 Seq:12;
- u16 Frag:4;
- u8 NextPktLen;//:8;
- u8 Rsvd0:6;
- u8 NextIND:1;
- u8 Rsvd1:1;
-
- //DWORD 3
- u8 RxMCS:6;
- u8 RxHT:1;
- u8 AMSDU:1;
- u8 SPLCP:1;
- u8 BW:1;
- u8 HTC:1;
- u8 TCPChkRpt:1;
- u8 IPChkRpt:1;
- u8 TCPChkValID:1;
- u8 HwPCErr:1;
- u8 HwPCInd:1;
- u16 IV0;//:16;
-
- //DWORD 4
- u32 IV1;
-
- //DWORD 5
- u32 TSFL;
-}rx_desc_819x_usb, *prx_desc_819x_usb;
-
-
-//
-// Driver info are written to the begining of the RxBuffer
-//
-typedef struct rx_drvinfo_819x_usb{
- u8 gain_trsw[4];
-
- //DWORD 1
- u8 pwdb_all;
- u8 cfosho[4];
-
- //DWORD 2
- u8 cfotail[4];
-
- //DWORD 3
- char rxevm[2];
- char rxsnr[4];
-
- //DWORD 4
- u8 pdsnr[2];
-
- //DWORD 5
- u8 csi_current[2];
- u8 csi_target[2];
-
- //DWORD 6
- u8 sigevm;
- u8 max_ex_pwr;
- u8 ex_intf_flag:1;
- u8 sgi_en:1;
- u8 rxsc:2;
- u8 reserve:4;
-
-}rx_drvinfo_819x_usb, *prx_drvinfo_819x_usb;
-
- #define HWSET_MAX_SIZE_92S 128
- #define MAX_802_11_HEADER_LENGTH 40
- #define MAX_PKT_AGG_NUM 256
- #define TX_PACKET_SHIFT_BYTES USB_HWDESC_HEADER_LEN
-
-#define MAX_DEV_ADDR_SIZE 8 /* support till 64 bit bus width OS */
-#define MAX_FIRMWARE_INFORMATION_SIZE 32 /*2006/04/30 by Emily forRTL8190*/
-#define ENCRYPTION_MAX_OVERHEAD 128
-#define USB_HWDESC_HEADER_LEN sizeof(tx_desc_819x_usb)
-#define MAX_FRAGMENT_COUNT 8
-#ifdef RTL8192U
-#define MAX_TRANSMIT_BUFFER_SIZE 8000
-#else
-#define MAX_TRANSMIT_BUFFER_SIZE (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
-#endif
-#define scrclng 4 // octets for crc32 (FCS, ICV)
-
-#define HAL_DM_DIG_DISABLE BIT0
-#define HAL_DM_HIPWR_DISABLE BIT1
-
-typedef enum rf_optype
-{
- RF_OP_By_SW_3wire = 0,
- RF_OP_By_FW,
- RF_OP_MAX
-}rf_op_type;
-
-/* for rtl819x */
-typedef enum _RT_STATUS{
- RT_STATUS_SUCCESS = 0,
- RT_STATUS_FAILURE = 1,
- RT_STATUS_PENDING = 2,
- RT_STATUS_RESOURCE = 3
-}RT_STATUS,*PRT_STATUS;
-
-typedef enum _RTL8192SUSB_LOOPBACK{
- RTL8192SU_NO_LOOPBACK = 0,
- RTL8192SU_MAC_LOOPBACK = 1,
- RTL8192SU_DMA_LOOPBACK = 2,
- RTL8192SU_CCK_LOOPBACK = 3,
-}RTL8192SUSB_LOOPBACK_E;
-
-#define MAX_RECEIVE_BUFFER_SIZE 9100 // Add this to 9100 bytes to receive A-MSDU from RT-AP
-
-
-/* Firmware Queue Layout */
-#define NUM_OF_FIRMWARE_QUEUE 10
-#define NUM_OF_PAGES_IN_FW 0x100
-
-
-#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x020
-#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x020
-#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x040
-#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x040
-#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0
-#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x4
-#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x20
-#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0
-#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4
-#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0x18
-
-
-#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000
-#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00
-#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08
-#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10
-#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18
-#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10
-#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT 0x08
-#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00
-#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08
-
-#define DEFAULT_FRAG_THRESHOLD 2342U
-#define MIN_FRAG_THRESHOLD 256U
-#define DEFAULT_BEACONINTERVAL 0x64U
-#define DEFAULT_BEACON_ESSID "Rtl819xU"
-
-#define DEFAULT_SSID ""
-#define DEFAULT_RETRY_RTS 7
-#define DEFAULT_RETRY_DATA 7
-#define PRISM_HDR_SIZE 64
-
-#define PHY_RSSI_SLID_WIN_MAX 100
-
-
-typedef enum _WIRELESS_MODE {
- WIRELESS_MODE_UNKNOWN = 0x00,
- WIRELESS_MODE_A = 0x01,
- WIRELESS_MODE_B = 0x02,
- WIRELESS_MODE_G = 0x04,
- WIRELESS_MODE_AUTO = 0x08,
- WIRELESS_MODE_N_24G = 0x10,
- WIRELESS_MODE_N_5G = 0x20
-} WIRELESS_MODE;
-
-
-#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
-
-typedef struct buffer
-{
- struct buffer *next;
- u32 *buf;
-
-} buffer;
-
-typedef struct rtl_reg_debug{
- unsigned int cmd;
- struct {
- unsigned char type;
- unsigned char addr;
- unsigned char page;
- unsigned char length;
- } head;
- unsigned char buf[0xff];
-}rtl_reg_debug;
-
-typedef struct _rt_9x_tx_rate_history {
- u32 cck[4];
- u32 ofdm[8];
- u32 ht_mcs[4][16];
-}rt_tx_rahis_t, *prt_tx_rahis_t;
-typedef struct _RT_SMOOTH_DATA_4RF {
- char elements[4][100];//array to store values
- u32 index; //index to current array to store
- u32 TotalNum; //num of valid elements
- u32 TotalVal[4]; //sum of valid elements
-}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF;
-
-#define MAX_8192U_RX_SIZE 8192 // This maybe changed for D-cut larger aggregation size
-//stats seems messed up, clean it ASAP
-typedef struct Stats
-{
- unsigned long txrdu;
- unsigned long rxok;
- unsigned long rxframgment;
- unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query
- unsigned long rxurberr;
- unsigned long rxstaterr;
- unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa
- unsigned long received_preamble_GI[2][32]; //0: Long preamble/GI, 1:Short preamble/GI
- unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K)
- unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40)
- unsigned long numpacket_matchbssid; // debug use only.
- unsigned long numpacket_toself; // debug use only.
- unsigned long num_process_phyinfo; // debug use only.
- unsigned long numqry_phystatus;
- unsigned long numqry_phystatusCCK;
- unsigned long numqry_phystatusHT;
- unsigned long received_bwtype[5]; //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate
- unsigned long txnperr;
- unsigned long txnpdrop;
- unsigned long txresumed;
- unsigned long txnpokint;
- unsigned long txoverflow;
- unsigned long txlpokint;
- unsigned long txlpdrop;
- unsigned long txlperr;
- unsigned long txbeokint;
- unsigned long txbedrop;
- unsigned long txbeerr;
- unsigned long txbkokint;
- unsigned long txbkdrop;
- unsigned long txbkerr;
- unsigned long txviokint;
- unsigned long txvidrop;
- unsigned long txvierr;
- unsigned long txvookint;
- unsigned long txvodrop;
- unsigned long txvoerr;
- unsigned long txbeaconokint;
- unsigned long txbeacondrop;
- unsigned long txbeaconerr;
- unsigned long txmanageokint;
- unsigned long txmanagedrop;
- unsigned long txmanageerr;
- unsigned long txdatapkt;
- unsigned long txfeedback;
- unsigned long txfeedbackok;
-
- unsigned long txoktotal;
- unsigned long txokbytestotal;
- unsigned long txokinperiod;
- unsigned long txmulticast;
- unsigned long txbytesmulticast;
- unsigned long txbroadcast;
- unsigned long txbytesbroadcast;
- unsigned long txunicast;
- unsigned long txbytesunicast;
-
- unsigned long rxoktotal;
- unsigned long rxbytesunicast;
- unsigned long txfeedbackfail;
- unsigned long txerrtotal;
- unsigned long txerrbytestotal;
- unsigned long txerrmulticast;
- unsigned long txerrbroadcast;
- unsigned long txerrunicast;
- unsigned long txretrycount;
- unsigned long txfeedbackretry;
- u8 last_packet_rate;
- unsigned long slide_signal_strength[100];
- unsigned long slide_evm[100];
- unsigned long slide_rssi_total; // For recording sliding window's RSSI value
- unsigned long slide_evm_total; // For recording sliding window's EVM value
- long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct.
- long signal_quality;
- long last_signal_strength_inpercent;
- long recv_signal_power; // Correct smoothed ss in Dbm, only used in driver to report real power now.
- u8 rx_rssi_percentage[4];
- u8 rx_evm_percentage[2];
- long rxSNRdB[4];
- rt_tx_rahis_t txrate;
- u32 Slide_Beacon_pwdb[100]; //cosa add for beacon rssi
- u32 Slide_Beacon_Total; //cosa add for beacon rssi
- RT_SMOOTH_DATA_4RF cck_adc_pwdb;
-
- u32 CurrentShowTxate;
-} Stats;
-
-// Bandwidth Offset
-#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
-#define HAL_PRIME_CHNL_OFFSET_LOWER 1
-#define HAL_PRIME_CHNL_OFFSET_UPPER 2
-
-typedef struct ChnlAccessSetting {
- u16 SIFS_Timer;
- u16 DIFS_Timer;
- u16 SlotTimeTimer;
- u16 EIFS_Timer;
- u16 CWminIndex;
- u16 CWmaxIndex;
-}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
-
-typedef struct _BB_REGISTER_DEFINITION{
- u32 rfintfs; // set software control: // 0x870~0x877[8 bytes]
- u32 rfintfi; // readback data: // 0x8e0~0x8e7[8 bytes]
- u32 rfintfo; // output data: // 0x860~0x86f [16 bytes]
- u32 rfintfe; // output enable: // 0x860~0x86f [16 bytes]
- u32 rf3wireOffset; // LSSI data: // 0x840~0x84f [16 bytes]
- u32 rfLSSI_Select; // BB Band Select: // 0x878~0x87f [8 bytes]
- u32 rfTxGainStage; // Tx gain stage: // 0x80c~0x80f [4 bytes]
- u32 rfHSSIPara1; // wire parameter control1 : // 0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes]
- u32 rfHSSIPara2; // wire parameter control2 : // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes]
- u32 rfSwitchControl; //Tx Rx antenna control : // 0x858~0x85f [16 bytes]
- u32 rfAGCControl1; //AGC parameter control1 : // 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes]
- u32 rfAGCControl2; //AGC parameter control2 : // 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes]
- u32 rfRxIQImbalance; //OFDM Rx IQ imbalance matrix : // 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes]
- u32 rfRxAFE; //Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : // 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes]
- u32 rfTxIQImbalance; //OFDM Tx IQ imbalance matrix // 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes]
- u32 rfTxAFE; //Tx IQ DC Offset and Tx DFIR type // 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes]
- u32 rfLSSIReadBack; //LSSI RF readback data // 0x8a0~0x8af [16 bytes]
- u32 rfLSSIReadBackPi; //LSSI RF readback data PI mode 0x8b8-8bc for Path A and B
-}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T;
-
-typedef enum _RT_RF_TYPE_819xU{
- RF_TYPE_MIN = 0,
- RF_8225,
- RF_8256,
- RF_8258,
- RF_6052=4, // 4 11b/g/n RF
- RF_PSEUDO_11N = 5,
-}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
-
-typedef enum _RF_POWER_STATE{
- RF_ON,
- RF_SLEEP,
- RF_OFF,
- RF_SHUT_DOWN,
-}RF_POWER_STATE, *PRF_POWER_STATE;
-
-typedef struct _rate_adaptive
-{
- u8 rate_adaptive_disabled;
- u8 ratr_state;
- u16 reserve;
-
- u32 high_rssi_thresh_for_ra;
- u32 high2low_rssi_thresh_for_ra;
- u8 low2high_rssi_thresh_for_ra40M;
- u32 low_rssi_thresh_for_ra40M;
- u8 low2high_rssi_thresh_for_ra20M;
- u32 low_rssi_thresh_for_ra20M;
- u32 upper_rssi_threshold_ratr;
- u32 middle_rssi_threshold_ratr;
- u32 low_rssi_threshold_ratr;
- u32 low_rssi_threshold_ratr_40M;
- u32 low_rssi_threshold_ratr_20M;
- u8 ping_rssi_enable; //cosa add for test
- u32 ping_rssi_ratr; //cosa add for test
- u32 ping_rssi_thresh_for_ra;//cosa add for test
- u32 last_ratr;
-
-} rate_adaptive, *prate_adaptive;
-
-#define TxBBGainTableLength 37
-#define CCKTxBBGainTableLength 23
-
-typedef struct _txbbgain_struct
-{
- long txbb_iq_amplifygain;
- u32 txbbgain_value;
-} txbbgain_struct, *ptxbbgain_struct;
-
-typedef struct _ccktxbbgain_struct
-{
- //The Value is from a22 to a29 one Byte one time is much Safer
- u8 ccktxbb_valuearray[8];
-} ccktxbbgain_struct,*pccktxbbgain_struct;
-
-
-typedef struct _init_gain
-{
- u8 xaagccore1;
- u8 xbagccore1;
- u8 xcagccore1;
- u8 xdagccore1;
- u8 cca;
-
-} init_gain, *pinit_gain;
-
-typedef struct _phy_ofdm_rx_status_report_819xusb
-{
- u8 trsw_gain_X[4];
- u8 pwdb_all;
- u8 cfosho_X[4];
- u8 cfotail_X[4];
- u8 rxevm_X[2];
- u8 rxsnr_X[4];
- u8 pdsnr_X[2];
- u8 csi_current_X[2];
- u8 csi_target_X[2];
- u8 sigevm;
- u8 max_ex_pwr;
- u8 sgi_en;
- u8 rxsc_sgien_exflg;
-}phy_sts_ofdm_819xusb_t;
-
-typedef struct _phy_cck_rx_status_report_819xusb
-{
- /* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend
- 0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */
- u8 adc_pwdb_X[4];
- u8 sq_rpt;
- u8 cck_agc_rpt;
-}phy_sts_cck_819xusb_t;
-
-
-typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{
- u8 reserved:4;
- u8 rxsc:2;
- u8 sgi_en:1;
- u8 ex_intf_flag:1;
-}phy_ofdm_rx_status_rxsc_sgien_exintfflag;
-
-typedef enum _RT_CUSTOMER_ID
-{
- RT_CID_DEFAULT = 0,
- RT_CID_8187_ALPHA0 = 1,
- RT_CID_8187_SERCOMM_PS = 2,
- RT_CID_8187_HW_LED = 3,
- RT_CID_8187_NETGEAR = 4,
- RT_CID_WHQL = 5,
- RT_CID_819x_CAMEO = 6,
- RT_CID_819x_RUNTOP = 7,
- RT_CID_819x_Senao = 8,
- RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31.
- RT_CID_819x_Netcore = 10,
- RT_CID_Nettronix = 11,
- RT_CID_DLINK = 12,
- RT_CID_PRONET = 13,
- RT_CID_COREGA = 14,
- RT_CID_819x_ALPHA = 15,
- RT_CID_819x_Sitecom = 16,
- RT_CID_CCX = 17,
- RT_CID_819x_Lenovo = 18,
- RT_CID_819x_QMI = 19,
- RT_CID_819x_Edimax_Belkin = 20,
- RT_CID_819x_Sercomm_Belkin = 21,
- RT_CID_819x_CAMEO1 = 22,
- RT_CID_819x_MSI = 23,
- RT_CID_819x_Acer = 24,
-}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID;
-
-typedef enum _RT_OP_MODE{
- RT_OP_MODE_AP,
- RT_OP_MODE_INFRASTRUCTURE,
- RT_OP_MODE_IBSS,
- RT_OP_MODE_NO_LINK,
-}RT_OP_MODE, *PRT_OP_MODE;
-
-typedef enum _RESET_TYPE {
- RESET_TYPE_NORESET = 0x00,
- RESET_TYPE_NORMAL = 0x01,
- RESET_TYPE_SILENT = 0x02
-} RESET_TYPE;
-
-/* The simple tx command OP code. */
-typedef enum _tag_TxCmd_Config_Index{
- TXCMD_TXRA_HISTORY_CTRL = 0xFF900000,
- TXCMD_RESET_TX_PKT_BUFF = 0xFF900001,
- TXCMD_RESET_RX_PKT_BUFF = 0xFF900002,
- TXCMD_SET_TX_DURATION = 0xFF900003,
- TXCMD_SET_RX_RSSI = 0xFF900004,
- TXCMD_SET_TX_PWR_TRACKING = 0xFF900005,
- TXCMD_XXXX_CTRL,
-}DCMD_TXCMD_OP;
-
-typedef enum{
- NIC_8192U = 1,
- NIC_8190P = 2,
- NIC_8192E = 3,
- NIC_8192SE = 4,
- NIC_8192SU = 5,
- } nic_t;
-
-struct rtl819x_ops{
- nic_t nic_type;
- void (* rtl819x_read_eeprom_info)(struct net_device *dev);
- short (* rtl819x_tx)(struct net_device *dev, struct sk_buff* skb);
- short (* rtl819x_tx_cmd)(struct net_device *dev, struct sk_buff *skb);
- void (* rtl819x_rx_nomal)(struct sk_buff* skb);
- void (* rtl819x_rx_cmd)(struct sk_buff *skb);
- bool (* rtl819x_adapter_start)(struct net_device *dev);
- void (* rtl819x_link_change)(struct net_device *dev);
- void (* rtl819x_initial_gain)(struct net_device *dev,u8 Operation);
- void (* rtl819x_query_rxdesc_status)(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
-};
-
-typedef struct r8192_priv
-{
- struct rtl819x_ops* ops;
- struct usb_device *udev;
- /* added for maintain info from eeprom */
- short epromtype;
- u16 eeprom_vid;
- u16 eeprom_pid;
- u8 eeprom_CustomerID;
- u8 eeprom_SubCustomerID;
- u16 eeprom_ChannelPlan;
- RT_CUSTOMER_ID CustomerID;
- LED_STRATEGY_819xUsb LedStrategy;
- u8 txqueue_to_outpipemap[9];
- u8 RtOutPipes[16];
- u8 RtInPipes[16];
- u8 ep_in_num;
- u8 ep_out_num;
- u8 ep_num;
- int irq;
- struct ieee80211_device *ieee80211;
-
- u8 RATRTableBitmap;
-
- u32 IC_Cut;
- short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
- u32 card_8192_version; /* if TCR reports card V B/C this discriminates */
- short enable_gpio0;
- enum card_type {PCI,MINIPCI,CARDBUS,USB}card_type;
- short hw_plcp_len;
- short plcp_preamble_mode;
-
- spinlock_t irq_lock;
- spinlock_t tx_lock;
- spinlock_t ps_lock;
- struct mutex mutex;
- bool ps_force;
- spinlock_t rf_lock; //used to lock rf write operation added by wb
- spinlock_t rf_ps_lock;
-
- u16 irq_mask;
- short chan;
- short sens;
- short max_sens;
-
- short up;
- short crcmon; //if 1 allow bad crc frame reception in monitor mode
- bool bSurpriseRemoved;
-
- struct semaphore wx_sem;
- struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david
-
- u8 rf_type; //0 means 1T2R, 1 means 2T4R
- RT_RF_TYPE_819xU rf_chip;
-
- short (*rf_set_sens)(struct net_device *dev,short sens);
- u8 (*rf_set_chan)(struct net_device *dev,u8 ch);
- void (*rf_close)(struct net_device *dev);
- void (*rf_init)(struct net_device *dev);
- short promisc;
- u32 mc_filter[2];
- /*stats*/
- struct Stats stats;
- struct iw_statistics wstats;
- struct proc_dir_entry *dir_dev;
-
- /*RX stuff*/
- struct urb **rx_urb;
- struct urb **rx_cmd_urb;
-
-/* for Rx process */
- struct sk_buff_head rx_queue;
- struct sk_buff_head skb_queue;
-
- struct work_struct qos_activate;
-
- short tx_urb_index;
- atomic_t tx_pending[0x10];//UART_PRIORITY+1
-
-
- struct tasklet_struct irq_rx_tasklet;
- struct tasklet_struct irq_tx_tasklet;
- struct urb *rxurb_task;
-
- //2 Tx Related variables
- u16 ShortRetryLimit;
- u16 LongRetryLimit;
- u32 TransmitConfig;
- u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27.
-
- u32 LastRxDescTSFHigh;
- u32 LastRxDescTSFLow;
-
-
- //2 Rx Related variables
- u16 EarlyRxThreshold;
- u32 ReceiveConfig;
- u8 AcmControl;
-
- u8 RFProgType;
-
- u8 retry_data;
- u8 retry_rts;
- u16 rts;
-
- struct ChnlAccessSetting ChannelAccessSetting;
-
- struct work_struct reset_wq;
- struct work_struct mcast_wq;
-
-/**********************************************************/
- //for rtl819xUsb
- u16 basic_rate;
- u8 short_preamble;
- u8 slot_time;
- bool bDcut;
- bool bCurrentRxAggrEnable;
- u8 Rf_Mode; //add for Firmware RF -R/W switch
- u8 FwRsvdTxPageCfg;
- prt_firmware pFirmware;
- RTL8192SUSB_LOOPBACK_E LoopbackMode;
- bool usb_error;
-
- u16 EEPROMTxPowerDiff;
- u8 EEPROMThermalMeter;
- u8 EEPROMPwDiff;
- u8 EEPROMCrystalCap;
- u8 EEPROMBluetoothCoexist;
- u8 EEPROM_Def_Ver;
- u8 EEPROMTxPowerLevelCCK;// CCK channel 1~14
- u8 EEPROMTxPowerLevelCCK_V1[3];
- u8 EEPROMTxPowerLevelOFDM24G[3]; // OFDM 2.4G channel 1~14
- u8 EEPROMTxPowerLevelOFDM5G[24]; // OFDM 5G
-
- u8 EEPROMOptional;
- u8 ShowRateMode;
- bool bForcedShowRxRate;
-
- u32 RfRegChnlVal[2];
-
- bool bDmDisableProtect;
- bool bIgnoreDiffRateTxPowerOffset;
-
- // For EEPROM TX Power Index like 8190 series
- u8 EEPROMRfACCKChnl1TxPwLevel[3]; //RF-A CCK Tx Power Level at channel 7
- u8 EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13
- u8 EEPROMRfCCCKChnl1TxPwLevel[3]; //RF-C CCK Tx Power Level at channel 7
- u8 EEPROMRfCOfdmChnlTxPwLevel[3];//RF-C CCK Tx Power Level at [0],[1],[2] = channel 1,7,13
-
- // F92S new definition
- //RF-A&B CCK/OFDM Tx Power Level at three channel are [1-3] [4-9] [10-14]
- u8 RfCckChnlAreaTxPwr[2][3];
- u8 RfOfdmChnlAreaTxPwr1T[2][3];
- u8 RfOfdmChnlAreaTxPwr2T[2][3];
-
- // Add For EEPROM Efuse switch and Efuse Shadow map Setting
- bool EepromOrEfuse;
- bool bBootFromEfuse; // system boot form EFUSE
- u8 EfuseMap[2][HWSET_MAX_SIZE_92S];
- u16 EfuseUsedBytes;
- u8 EfuseUsedPercentage;
-
-
- u8 EEPROMUsbOption;
- u8 EEPROMUsbPhyParam[5];
- u8 EEPROMTxPwrBase;
- u8 EEPROMBoardType;
- bool bBootFromEEPROM; // system boot from EEPROM
- u8 EEPROMTSSI_A;
- u8 EEPROMTSSI_B;
- u8 EEPROMHT2T_TxPwr[6]; // For channel 1, 7 and 13 on path A/B.
- u8 EEPROMTxPwrTkMode;
-
- u8 bTXPowerDataReadFromEEPORM;
- u8 EEPROMRegulatory;
- u8 EEPROMPwrGroup[2][3];
-
- u8 EEPROMVersion;
- u8 EEPROMUsbEndPointNumber;
-
- bool AutoloadFailFlag;
- u8 RfTxPwrLevelCck[2][14];
- u8 RfTxPwrLevelOfdm1T[2][14];
- u8 RfTxPwrLevelOfdm2T[2][14];
- // new EEPROM format.
- u8 TxPwrHt20Diff[2][14]; // HT 20<->40 Pwr diff
- u8 TxPwrLegacyHtDiff[2][14]; // For HT<->legacy pwr diff
- u8 TxPwrbandEdgeHt40[2][2]; // Band edge for HY 40MHZlow/up channel
- u8 TxPwrbandEdgeHt20[2][2]; // Band edge for HY 40MHZ low/up channel
- u8 TxPwrbandEdgeLegacyOfdm[2][2]; // Band edge for legacy ofdm low/up channel
- u8 TxPwrbandEdgeFlag; // Band edge enable flag
-
- // L1 and L2 high power threshold.
- u8 MidHighPwrTHR_L1;
- u8 MidHighPwrTHR_L2;
- u8 TxPwrSafetyFlag; // for Tx power safety spec
-
-/*PHY related*/
- BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D
- // Read/write are allow for following hardware information variables
- u32 MCSTxPowerLevelOriginalOffset[7];//FIXLZM
- u32 CCKTxPowerLevelOriginalOffset;
- u8 TxPowerLevelCCK[14]; // CCK channel 1~14
- u8 TxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14
- u8 TxPowerLevelOFDM5G[14]; // OFDM 5G
- u32 Pwr_Track;
- u8 TxPowerDiff;
- u8 AntennaTxPwDiff[2]; // Antenna gain offset, index 0 for B, 1 for C, and 2 for D
- u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
- u8 ThermalValue;
- u8 CrystalCap; // CrystalCap.
- u8 BluetoothCoexist;
- u8 ExternalPA;
-
- u8 CckPwEnl;
- // Use to calculate PWBD.
- u8 bCckHighPower;
- long undecorated_smoothed_pwdb;
-
- //for set channel
- u8 SwChnlInProgress;
- u8 SwChnlStage;
- u8 SwChnlStep;
- u8 SetBWModeInProgress;
- HT_CHANNEL_WIDTH CurrentChannelBW;
- bool bChnlPlanFromHW;
- u8 ChannelPlan;
- u16 RegChannelPlan;
- u8 pwrGroupCnt;
- // 8190 40MHz mode
- //
- u8 nCur40MhzPrimeSC; // Control channel sub-carrier
-
- u32 RfReg0Value[4];
- u8 NumTotalRFPath;
- bool brfpath_rxenable[4];
- //RF set related
- bool SetRFPowerStateInProgress;
-
- struct timer_list watch_dog_timer;
-
- bool bdynamic_txpower; //bDynamicTxPower
- bool bDynamicTxHighPower; // Tx high power state
- bool bDynamicTxLowPower; // Tx low power state
- bool bLastDTPFlag_High;
- bool bLastDTPFlag_Low;
-
- bool bstore_last_dtpflag;
- bool bstart_txctrl_bydtp; //Define to discriminate on High power State or on sitesuvey to change Tx gain index
-
- rate_adaptive rate_adaptive;
- // TX power tracking
- txbbgain_struct txbbgain_table[TxBBGainTableLength];
- u8 EEPROMTxPowerTrackEnable;
- u8 txpower_count;//For 6 sec do tracking again
- bool btxpower_trackingInit;
- u8 OFDM_index;
- u8 CCK_index;
- u8 Record_CCK_20Mindex;
- u8 Record_CCK_40Mindex;
- // CCK TX Power Tracking
- ccktxbbgain_struct cck_txbbgain_table[CCKTxBBGainTableLength];
- ccktxbbgain_struct cck_txbbgain_ch14_table[CCKTxBBGainTableLength];
- u8 rfa_txpowertrackingindex;
- u8 rfa_txpowertrackingindex_real;
- u8 rfa_txpowertracking_default;
- u8 rfc_txpowertrackingindex;
- u8 rfc_txpowertrackingindex_real;
-
- s8 cck_present_attentuation;
- u8 cck_present_attentuation_20Mdefault;
- u8 cck_present_attentuation_40Mdefault;
- char cck_present_attentuation_difference;
- bool btxpower_tracking;
- bool bcck_in_ch14;
- bool btxpowerdata_readfromEEPORM;
- u16 TSSI_13dBm;
- u8 CCKPresentAttentuation_20Mdefault;
- u8 CCKPresentAttentuation_40Mdefault;
- char CCKPresentAttentuation_difference;
- char CCKPresentAttentuation;
- bool bDMInitialGainEnable;
- //For Backup Initial Gain
- init_gain initgain_backup;
- u8 DefaultInitialGain[4];
- // For EDCA Turbo mode
- bool bis_any_nonbepkts;
- bool bcurrent_turbo_EDCA;
- bool bis_cur_rdlstate;
- struct timer_list fsync_timer;
- bool bfsync_processing; // 500ms Fsync timer is active or not
- u32 rate_record;
- u32 rateCountDiffRecord;
- u32 ContiuneDiffCount;
- bool bswitch_fsync;
-
- u8 framesync;
- u32 framesyncC34;
- u8 framesyncMonitor;
- // RX related
- u16 nrxAMPDU_size;
- u8 nrxAMPDU_aggr_num;
-
- // gpio
- bool bHwRadioOff;
-
- bool isRFOff;
- bool bInPowerSaveMode;
-
- bool RFChangeInProgress;
- bool RegRfOff;
- u8 bHwRfOffAction;
-
- u32 reset_count;
- bool bpbc_pressed;
- // debug
- u32 txpower_checkcnt;
- u32 txpower_tracking_callback_cnt;
- u8 thermal_read_val[40];
- u8 thermal_readback_index;
- u32 ccktxpower_adjustcnt_not_ch14;
- u32 ccktxpower_adjustcnt_ch14;
- u8 tx_fwinfo_force_subcarriermode;
- u8 tx_fwinfo_force_subcarrierval;
- // silent reset
- RESET_TYPE ResetProgress;
- bool bForcedSilentReset;
- bool bDisableNormalResetCheck;
- u16 TxCounter;
- u16 RxCounter;
- int IrpPendingCount;
- bool bResetInProgress;
- bool force_reset;
- bool force_lps;
- u8 InitialGainOperateType;
-
- u16 SifsTime;
-
- struct delayed_work update_beacon_wq;
- struct delayed_work watch_dog_wq;
- struct delayed_work txpower_tracking_wq;
- struct delayed_work rfpath_check_wq;
- struct delayed_work gpio_change_rf_wq;
- struct delayed_work initialgain_operate_wq;
-
- struct workqueue_struct *priv_wq;
-
- u32 IntrMask;
- // RF and BB access related synchronization flags.
- bool bChangeBBInProgress; // BaseBand RW is still in progress.
- bool bChangeRFInProgress; // RF RW is still in progress.
-
- u32 CCKTxPowerAdjustCntCh14; //debug only
- u32 CCKTxPowerAdjustCntNotCh14; //debug only
- u32 TXPowerTrackingCallbackCnt; //debug only
- u32 TxPowerCheckCnt; //debug only
- u32 RFWritePageCnt[3]; //debug only
- u32 RFReadPageCnt[3]; //debug only
- u8 ThermalReadBackIndex; //debug only
- u8 ThermalReadVal[40]; //debug only
-
- // not realize true, just define it, set it 0 default, because some func use it
- bool bInHctTest;
-
- // The current Tx Power Level
- u8 CurrentCckTxPwrIdx;
- u8 CurrentOfdm24GTxPwrIdx;
-
- // For pass 92S common phycfg.c compiler
- u8 TxPowerLevelCCK_A[14]; // RF-A, CCK channel 1~14
- u8 TxPowerLevelOFDM24G_A[14]; // RF-A, OFDM 2.4G channel 1~14
- u8 TxPowerLevelCCK_C[14]; // RF-C, CCK channel 1~14
- u8 TxPowerLevelOFDM24G_C[14]; // RF-C, OFDM 2.4G channel 1~14
- u8 LegacyHTTxPowerDiff; // Legacy to HT rate power diff
- char RF_C_TxPwDiff; // Antenna gain offset, rf-c to rf-a
-
- bool bRFSiOrPi;//0=si, 1=pi.
-
- bool SetFwCmdInProgress; //is set FW CMD in Progress? 92S only
- u8 CurrentFwCmdIO;
-
- u8 MinSpaceCfg;
-
- u16 rf_pathmap;
-
- /* added for led control */
- PLED_819xUsb pLed;
- LED_819xUsb SwLed0;
- LED_819xUsb SwLed1;
- u8 bRegUseLed;
- struct work_struct BlinkWorkItem;
- /* added for led control */
- u16 FwCmdIOMap;
- u32 FwCmdIOParam;
- u8 DMFlag;
-
-
-
-
-}r8192_priv;
-
-//for rtl8187B
-typedef enum{
- BULK_PRIORITY = 0x01,
- //RSVD0,
- //RSVD1,
- LOW_PRIORITY,
- NORM_PRIORITY,
- VO_PRIORITY,
- VI_PRIORITY, //0x05
- BE_PRIORITY,
- BK_PRIORITY,
- RSVD2,
- RSVD3,
- BEACON_PRIORITY, //0x0A
- HIGH_PRIORITY,
- MANAGE_PRIORITY,
- RSVD4,
- RSVD5,
- UART_PRIORITY //0x0F
-} priority_t;
-
-#ifdef JOHN_HWSEC
-struct ssid_thread {
- struct net_device *dev;
- u8 name[IW_ESSID_MAX_SIZE + 1];
-};
-#endif
-
-void LedControl8192SUsb(struct net_device *dev, LED_CTL_MODE LedAction);
-void InitSwLeds(struct net_device *dev);
-void DeInitSwLeds(struct net_device *dev);
-short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
-short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
-bool FirmwareDownload92S(struct net_device *dev);
-
-short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
-short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
-
-u32 read_cam(struct net_device *dev, u8 addr);
-void write_cam(struct net_device *dev, u8 addr, u32 data);
-
-u8 read_nic_byte(struct net_device *dev, int x);
-u8 read_nic_byte_E(struct net_device *dev, int x);
-u32 read_nic_dword(struct net_device *dev, int x);
-u16 read_nic_word(struct net_device *dev, int x) ;
-void write_nic_byte(struct net_device *dev, int x,u8 y);
-void write_nic_byte_E(struct net_device *dev, int x,u8 y);
-void write_nic_word(struct net_device *dev, int x,u16 y);
-void write_nic_dword(struct net_device *dev, int x,u32 y);
-void force_pci_posting(struct net_device *dev);
-
-void rtl8192_rtx_disable(struct net_device *);
-void rtl8192_rx_enable(struct net_device *);
-void rtl8192_tx_enable(struct net_device *);
-
-void rtl8192_disassociate(struct net_device *dev);
-void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
-
-void rtl8192_set_anaparam(struct net_device *dev,u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
-void rtl8192_update_msr(struct net_device *dev);
-int rtl8192_down(struct net_device *dev);
-int rtl8192_up(struct net_device *dev);
-void rtl8192_commit(struct net_device *dev);
-void rtl8192_set_chan(struct net_device *dev,short ch);
-void write_phy(struct net_device *dev, u8 adr, u8 data);
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
-void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
-void rtl8192_set_rxconf(struct net_device *dev);
-extern void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate);
-void CamResetAllEntry(struct net_device* dev);
-void EnableHWSecurityConfig8192(struct net_device *dev);
-void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
-short rtl8192_is_tx_queue_empty(struct net_device *dev);
-
-#endif
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
deleted file mode 100644
index df5b52baf893..000000000000
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ /dev/null
@@ -1,7712 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- * Linux device driver for RTL8192U
- *
- * Based on the r8187 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * 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:
- * Jerry chuang <wlanfae@realtek.com>
- */
-
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/eeprom_93cx6.h>
-#include <linux/notifier.h>
-
-#undef LOOP_TEST
-#undef DUMP_RX
-#undef DUMP_TX
-#undef DEBUG_TX_DESC2
-#undef RX_DONT_PASS_UL
-#undef DEBUG_EPROM
-#undef DEBUG_RX_VERBOSE
-#undef DUMMY_RX
-#undef DEBUG_ZERO_RX
-#undef DEBUG_RX_SKB
-#undef DEBUG_TX_FRAG
-#undef DEBUG_RX_FRAG
-#undef DEBUG_TX_FILLDESC
-#undef DEBUG_TX
-#undef DEBUG_IRQ
-#undef DEBUG_RX
-#undef DEBUG_RXALLOC
-#undef DEBUG_REGISTERS
-#undef DEBUG_RING
-#undef DEBUG_IRQ_TASKLET
-#undef DEBUG_TX_ALLOC
-#undef DEBUG_TX_DESC
-
-#define CONFIG_RTL8192_IO_MAP
-
-#include <asm/uaccess.h>
-#include "r8192U.h"
-#include "r8192U_wx.h"
-
-#include "r8192S_rtl8225.h"
-#include "r8192S_hw.h"
-#include "r8192S_phy.h"
-#include "r8192S_phyreg.h"
-#include "r8192S_Efuse.h"
-
-#include "r819xU_cmdpkt.h"
-#include "r8192U_dm.h"
-//#include "r8192xU_phyreg.h"
-#include <linux/usb.h>
-
-#include "r8192U_pm.h"
-
-#include "ieee80211/dot11d.h"
-
-
-
-u32 rt_global_debug_component = \
-// COMP_TRACE |
-// COMP_DBG |
-// COMP_INIT |
-// COMP_RECV |
-// COMP_SEND |
-// COMP_IO |
- COMP_POWER |
-// COMP_EPROM |
- COMP_SWBW |
- COMP_POWER_TRACKING |
- COMP_TURBO |
- COMP_QOS |
-// COMP_RATE |
-// COMP_RM |
- COMP_DIG |
-// COMP_EFUSE |
-// COMP_CH |
-// COMP_TXAGC |
- COMP_HIPWR |
-// COMP_HALDM |
- COMP_SEC |
- COMP_LED |
-// COMP_RF |
-// COMP_RXDESC |
- COMP_FIRMWARE |
- COMP_HT |
- COMP_AMSDU |
- COMP_SCAN |
-// COMP_CMD |
- COMP_DOWN |
- COMP_RESET |
- COMP_ERR; //always open err flags on
-
-#define TOTAL_CAM_ENTRY 32
-#define CAM_CONTENT_COUNT 8
-
-static const struct usb_device_id rtl8192_usb_id_tbl[] = {
- {USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */
- {USB_DEVICE(0x0bda, 0x8172)},
- {USB_DEVICE(0x0bda, 0x8173)},
- {USB_DEVICE(0x0bda, 0x8174)},
- {USB_DEVICE(0x0bda, 0x8712)},
- {USB_DEVICE(0x0bda, 0x8713)},
- {USB_DEVICE(0x07aa, 0x0047)},
- {USB_DEVICE(0x07d1, 0x3303)},
- {USB_DEVICE(0x07d1, 0x3302)},
- {USB_DEVICE(0x07d1, 0x3300)},
- {USB_DEVICE(0x1740, 0x9603)},
- {USB_DEVICE(0x1740, 0x9605)},
- {USB_DEVICE(0x050d, 0x815F)},
- {USB_DEVICE(0x06f8, 0xe031)},
- {USB_DEVICE(0x7392, 0x7611)},
- {USB_DEVICE(0x7392, 0x7612)},
- {USB_DEVICE(0x7392, 0x7622)},
- {USB_DEVICE(0x0DF6, 0x0045)},
- {USB_DEVICE(0x0E66, 0x0015)},
- {USB_DEVICE(0x0E66, 0x0016)},
- {USB_DEVICE(0x0b05, 0x1786)},
- /* these are not in the official list */
- {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
- {}
-};
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION("V 1.1");
-MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
-MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
-
-static char ifname[IFNAMSIZ] = "wlan%d";
-static int hwwep = 1; //default use hw. set 0 to use software security
-static int channels = 0x3fff;
-
-
-
-module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
-//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
-module_param(hwwep,int, S_IRUGO|S_IWUSR);
-module_param(channels,int, S_IRUGO|S_IWUSR);
-
-MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
-//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
-MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
-MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
-
-static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id);
-static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
-static const struct net_device_ops rtl8192_netdev_ops;
-static struct notifier_block proc_netdev_notifier;
-
-static struct usb_driver rtl8192_usb_driver = {
- .name = RTL819xU_MODULE_NAME, /* Driver name */
- .id_table = rtl8192_usb_id_tbl, /* PCI_ID table */
- .probe = rtl8192_usb_probe, /* probe fn */
- .disconnect = rtl8192_usb_disconnect, /* remove fn */
- .suspend = rtl8192U_suspend, /* PM suspend fn */
- .resume = rtl8192U_resume, /* PM resume fn */
- .reset_resume = rtl8192U_resume, /* PM reset resume fn */
-};
-
-
-static void rtl8192SU_read_eeprom_info(struct net_device *dev);
-short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
-void rtl8192SU_rx_nomal(struct sk_buff* skb);
-void rtl8192SU_rx_cmd(struct sk_buff *skb);
-bool rtl8192SU_adapter_start(struct net_device *dev);
-short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
-void rtl8192SU_link_change(struct net_device *dev);
-void InitialGain8192S(struct net_device *dev,u8 Operation);
-void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
-
-struct rtl819x_ops rtl8192su_ops = {
- .nic_type = NIC_8192SU,
- .rtl819x_read_eeprom_info = rtl8192SU_read_eeprom_info,
- .rtl819x_tx = rtl8192SU_tx,
- .rtl819x_tx_cmd = rtl8192SU_tx_cmd,
- .rtl819x_rx_nomal = rtl8192SU_rx_nomal,
- .rtl819x_rx_cmd = rtl8192SU_rx_cmd,
- .rtl819x_adapter_start = rtl8192SU_adapter_start,
- .rtl819x_link_change = rtl8192SU_link_change,
- .rtl819x_initial_gain = InitialGain8192S,
- .rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
-};
-
-
-typedef struct _CHANNEL_LIST
-{
- u8 Channel[32];
- u8 Len;
-}CHANNEL_LIST, *PCHANNEL_LIST;
-
-static CHANNEL_LIST ChannelPlan[] = {
- {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
- {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
-};
-
-static void rtl819x_eeprom_register_read(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = read_nic_byte(dev, EPROM_CMD);
-
- eeprom->reg_data_in = reg & RTL819X_EEPROM_CMD_WRITE;
- eeprom->reg_data_out = reg & RTL819X_EEPROM_CMD_READ;
- eeprom->reg_data_clock = reg & RTL819X_EEPROM_CMD_CK;
- eeprom->reg_chip_select = reg & RTL819X_EEPROM_CMD_CS;
-}
-
-static void rtl819x_eeprom_register_write(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = 2 << 6;
-
- if (eeprom->reg_data_in)
- reg |= RTL819X_EEPROM_CMD_WRITE;
- if (eeprom->reg_data_out)
- reg |= RTL819X_EEPROM_CMD_READ;
- if (eeprom->reg_data_clock)
- reg |= RTL819X_EEPROM_CMD_CK;
- if (eeprom->reg_chip_select)
- reg |= RTL819X_EEPROM_CMD_CS;
-
- write_nic_byte(dev, EPROM_CMD, reg);
- read_nic_byte(dev, EPROM_CMD);
- udelay(10);
-}
-
-static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
-{
- int i, max_chan=-1, min_chan=-1;
- struct ieee80211_device* ieee = priv->ieee80211;
-
- ieee->bGlobalDomain = false;
- switch (priv->rf_chip) {
- case RF_8225:
- case RF_8256:
- case RF_6052:
- min_chan = 1;
- max_chan = 14;
- break;
- default:
- pr_err("%s(): unknown rf chip, can't set channel map\n",
- __func__);
- break;
- }
- if (ChannelPlan[channel_plan].Len != 0) {
- memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
- sizeof(GET_DOT11D_INFO(ieee)->channel_map));
-
- for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
- if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
- break;
- GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
- }
- }
- switch (channel_plan) {
- case COUNTRY_CODE_GLOBAL_DOMAIN:
- ieee->bGlobalDomain = true;
- for (i = 12; i <= 14; i++)
- GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
- ieee->IbssStartChnl = 10;
- ieee->ibss_maxjoin_chal = 11;
- break;
- case COUNTRY_CODE_WORLD_WIDE_13:
- printk(KERN_INFO "world wide 13\n");
- for (i = 12; i <= 13; i++)
- GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
- ieee->IbssStartChnl = 10;
- ieee->ibss_maxjoin_chal = 11;
- break;
- default:
- ieee->IbssStartChnl = 1;
- ieee->ibss_maxjoin_chal = 14;
- break;
- }
- return;
-}
-
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-
-#define rx_hal_is_cck_rate(_pDesc)\
- ((_pDesc->RxMCS == DESC92S_RATE1M ||\
- _pDesc->RxMCS == DESC92S_RATE2M ||\
- _pDesc->RxMCS == DESC92S_RATE5_5M ||\
- _pDesc->RxMCS == DESC92S_RATE11M) &&\
- !_pDesc->RxHT)
-
-#define tx_hal_is_cck_rate(_DataRate)\
- ( _DataRate == MGN_1M ||\
- _DataRate == MGN_2M ||\
- _DataRate == MGN_5_5M ||\
- _DataRate == MGN_11M )
-
-
-
-
-void CamResetAllEntry(struct net_device *dev)
-{
-#if 1
- u32 ulcommand = 0;
- //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
- // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
- // In this condition, Cam can not be reset because upper layer will not set this static key again.
- //if(Adapter->EncAlgorithm == WEP_Encryption)
- // return;
-//debug
- //DbgPrint("========================================\n");
- //DbgPrint(" Call ResetAllEntry \n");
- //DbgPrint("========================================\n\n");
- ulcommand |= BIT31|BIT30;
- write_nic_dword(dev, RWCAM, ulcommand);
-#else
- for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
- CAM_mark_invalid(dev, ucIndex);
- for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
- CAM_empty_entry(dev, ucIndex);
-#endif
-
-}
-
-
-void write_cam(struct net_device *dev, u8 addr, u32 data)
-{
- write_nic_dword(dev, WCAMI, data);
- write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
-}
-
-u32 read_cam(struct net_device *dev, u8 addr)
-{
- write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
- return read_nic_dword(dev, 0xa8);
-}
-
-void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
-{
- int status;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- indx|0xfe00, 0, &data, 1, HZ / 2);
-
- if (status < 0)
- {
- printk("write_nic_byte_E TimeOut! status:%d\n", status);
- }
-}
-
-u8 read_nic_byte_E(struct net_device *dev, int indx)
-{
- int status;
- u8 data;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- indx|0xfe00, 0, &data, 1, HZ / 2);
-
- if (status < 0)
- {
- printk("read_nic_byte_E TimeOut! status:%d\n", status);
- }
-
- return data;
-}
-//as 92U has extend page from 4 to 16, so modify functions below.
-void write_nic_byte(struct net_device *dev, int indx, u8 data)
-{
- int status;
-
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- indx, 0, &data, 1, HZ / 2);
-
- if (status < 0)
- {
- printk("write_nic_byte TimeOut! status:%d\n", status);
- }
-
-
-}
-
-
-void write_nic_word(struct net_device *dev, int indx, u16 data)
-{
-
- int status;
-
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- indx, 0, &data, 2, HZ / 2);
-
- if (status < 0)
- {
- printk("write_nic_word TimeOut! status:%d\n", status);
- }
-
-}
-
-
-void write_nic_dword(struct net_device *dev, int indx, u32 data)
-{
-
- int status;
-
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- indx, 0, &data, 4, HZ / 2);
-
-
- if (status < 0)
- {
- printk("write_nic_dword TimeOut! status:%d\n", status);
- }
-
-}
-
-
-
-u8 read_nic_byte(struct net_device *dev, int indx)
-{
- u8 data;
- int status;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- indx, 0, &data, 1, HZ / 2);
-
- if (status < 0)
- {
- printk("read_nic_byte TimeOut! status:%d\n", status);
- }
-
- return data;
-}
-
-
-
-u16 read_nic_word(struct net_device *dev, int indx)
-{
- u16 data;
- int status;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- indx, 0, &data, 2, HZ / 2);
-
- if (status < 0)
- {
- printk("read_nic_word TimeOut! status:%d\n", status);
- }
-
-
- return data;
-}
-
-u16 read_nic_word_E(struct net_device *dev, int indx)
-{
- u16 data;
- int status;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- indx|0xfe00, 0, &data, 2, HZ / 2);
-
- if (status < 0)
- {
- printk("read_nic_word TimeOut! status:%d\n", status);
- }
-
-
- return data;
-}
-
-u32 read_nic_dword(struct net_device *dev, int indx)
-{
- u32 data;
- int status;
-// int result;
-
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct usb_device *udev = priv->udev;
-
- status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- indx, 0, &data, 4, HZ / 2);
-// if(0 != result) {
-// printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
-// }
-
- if (status < 0)
- {
- printk("read_nic_dword TimeOut! status:%d\n", status);
- if(status == -ENODEV) {
- priv->usb_error = true;
- }
- }
-
-
-
- return data;
-}
-
-
-//u8 read_phy_cck(struct net_device *dev, u8 adr);
-//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
-/* this might still called in what was the PHY rtl8185/rtl8192 common code
- * plans are to possibilty turn it again in one common code...
- */
-inline void force_pci_posting(struct net_device *dev)
-{
-}
-
-
-static struct net_device_stats *rtl8192_stats(struct net_device *dev);
-void rtl8192_commit(struct net_device *dev);
-//void rtl8192_restart(struct net_device *dev);
-void rtl8192_restart(struct work_struct *work);
-//void rtl8192_rq_tx_ack(struct work_struct *work);
-
-void watch_dog_timer_callback(unsigned long data);
-
-/****************************************************************************
- -----------------------------PROCFS STUFF-------------------------
-*****************************************************************************/
-
-static struct proc_dir_entry *rtl8192_proc = NULL;
-
-
-
-static int proc_get_stats_ap(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- struct ieee80211_network *target;
-
- int len = 0;
-
- list_for_each_entry(target, &ieee->network_list, list) {
-
- len += snprintf(page + len, count - len,
- "%s ", target->ssid);
-
- if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
- len += snprintf(page + len, count - len,
- "WPA\n");
- }
- else{
- len += snprintf(page + len, count - len,
- "non_WPA\n");
- }
-
- }
-
- *eof = 1;
- return len;
-}
-
-static int proc_get_registers(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0,page1,page2;
-
- int max=0xff;
- page0 = 0x000;
- page1 = 0x100;
- page2 = 0x800;
-
- /* This dump the current register page */
- if(!IS_BB_REG_OFFSET_92S(page0)){
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len,
- "\nD: %2x > ",n);
- for(i=0;i<16 && n<=max;i++,n++)
- len += snprintf(page + len, count - len,
- "%2.2x ",read_nic_byte(dev,(page0|n)));
- }
- }else{
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-
-}
-static int proc_get_registers_1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0x100;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len,
- "\nD: %2x > ",n);
- for(i=0;i<16 && n<=max;i++,n++)
- len += snprintf(page + len, count - len,
- "%2.2x ",read_nic_byte(dev,(page0|n)));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-
-}
-static int proc_get_registers_2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0x200;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len,
- "\nD: %2x > ",n);
- for(i=0;i<16 && n<=max;i++,n++)
- len += snprintf(page + len, count - len,
- "%2.2x ",read_nic_byte(dev,(page0|n)));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-
-}
-static int proc_get_registers_8(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0x800;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-
- }
-static int proc_get_registers_9(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0x900;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-}
-static int proc_get_registers_a(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0xa00;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-}
-static int proc_get_registers_b(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0xb00;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
- }
-static int proc_get_registers_c(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0xc00;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-}
-static int proc_get_registers_d(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0xd00;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-}
-static int proc_get_registers_e(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
- int i,n,page0;
-
- int max=0xff;
- page0 = 0xe00;
-
- /* This dump the current register page */
- len += snprintf(page + len, count - len,
- "\n####################page %x##################\n ", (page0>>8));
- for(n=0;n<=max;)
- {
- len += snprintf(page + len, count - len, "\nD: %2x > ",n);
- for(i=0;i<4 && n<=max;n+=4,i++)
- len += snprintf(page + len, count - len,
- "%8.8x ",rtl8192_QueryBBReg(dev,(page0|n), bMaskDWord));
- }
- len += snprintf(page + len, count - len,"\n");
- *eof = 1;
- return len;
-}
-
-static int proc_get_stats_tx(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
-
- len += snprintf(page + len, count - len,
- "TX VI priority ok int: %lu\n"
- "TX VI priority error int: %lu\n"
- "TX VO priority ok int: %lu\n"
- "TX VO priority error int: %lu\n"
- "TX BE priority ok int: %lu\n"
- "TX BE priority error int: %lu\n"
- "TX BK priority ok int: %lu\n"
- "TX BK priority error int: %lu\n"
- "TX MANAGE priority ok int: %lu\n"
- "TX MANAGE priority error int: %lu\n"
- "TX BEACON priority ok int: %lu\n"
- "TX BEACON priority error int: %lu\n"
-// "TX high priority ok int: %lu\n"
-// "TX high priority failed error int: %lu\n"
- "TX queue resume: %lu\n"
- "TX queue stopped?: %d\n"
- "TX fifo overflow: %lu\n"
-// "TX beacon: %lu\n"
- "TX VI queue: %d\n"
- "TX VO queue: %d\n"
- "TX BE queue: %d\n"
- "TX BK queue: %d\n"
-// "TX HW queue: %d\n"
- "TX VI dropped: %lu\n"
- "TX VO dropped: %lu\n"
- "TX BE dropped: %lu\n"
- "TX BK dropped: %lu\n"
- "TX total data packets %lu\n",
-// "TX beacon aborted: %lu\n",
- priv->stats.txviokint,
- priv->stats.txvierr,
- priv->stats.txvookint,
- priv->stats.txvoerr,
- priv->stats.txbeokint,
- priv->stats.txbeerr,
- priv->stats.txbkokint,
- priv->stats.txbkerr,
- priv->stats.txmanageokint,
- priv->stats.txmanageerr,
- priv->stats.txbeaconokint,
- priv->stats.txbeaconerr,
-// priv->stats.txhpokint,
-// priv->stats.txhperr,
- priv->stats.txresumed,
- netif_queue_stopped(dev),
- priv->stats.txoverflow,
-// priv->stats.txbeacon,
- atomic_read(&(priv->tx_pending[VI_PRIORITY])),
- atomic_read(&(priv->tx_pending[VO_PRIORITY])),
- atomic_read(&(priv->tx_pending[BE_PRIORITY])),
- atomic_read(&(priv->tx_pending[BK_PRIORITY])),
-// read_nic_byte(dev, TXFIFOCOUNT),
- priv->stats.txvidrop,
- priv->stats.txvodrop,
- priv->stats.txbedrop,
- priv->stats.txbkdrop,
- priv->stats.txdatapkt
-// priv->stats.txbeaconerr
- );
-
- *eof = 1;
- return len;
-}
-
-
-
-static int proc_get_stats_rx(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- int len = 0;
-
- len += snprintf(page + len, count - len,
- "RX packets: %lu\n"
- "RX urb status error: %lu\n"
- "RX invalid urb error: %lu\n",
- priv->stats.rxoktotal,
- priv->stats.rxstaterr,
- priv->stats.rxurberr);
-
- *eof = 1;
- return len;
-}
-
-int rtl8192_proc_module_init(void)
-{
- int ret;
-
- RT_TRACE(COMP_INIT, "Initializing proc filesystem");
- rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
- if (!rtl8192_proc)
- return -ENOMEM;
- ret = register_netdevice_notifier(&proc_netdev_notifier);
- if (ret)
- remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
- return ret;
-}
-
-
-void rtl8192_proc_module_remove(void)
-{
- unregister_netdevice_notifier(&proc_netdev_notifier);
- remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
-}
-
-
-void rtl8192_proc_remove_one(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-
- if (priv->dir_dev) {
- // remove_proc_entry("stats-hw", priv->dir_dev);
- remove_proc_entry("stats-tx", priv->dir_dev);
- remove_proc_entry("stats-rx", priv->dir_dev);
- // remove_proc_entry("stats-ieee", priv->dir_dev);
- remove_proc_entry("stats-ap", priv->dir_dev);
- remove_proc_entry("registers", priv->dir_dev);
- remove_proc_entry("registers-1", priv->dir_dev);
- remove_proc_entry("registers-2", priv->dir_dev);
- remove_proc_entry("registers-8", priv->dir_dev);
- remove_proc_entry("registers-9", priv->dir_dev);
- remove_proc_entry("registers-a", priv->dir_dev);
- remove_proc_entry("registers-b", priv->dir_dev);
- remove_proc_entry("registers-c", priv->dir_dev);
- remove_proc_entry("registers-d", priv->dir_dev);
- remove_proc_entry("registers-e", priv->dir_dev);
- // remove_proc_entry("cck-registers",priv->dir_dev);
- // remove_proc_entry("ofdm-registers",priv->dir_dev);
- remove_proc_entry(priv->dir_dev->name, rtl8192_proc);
- priv->dir_dev = NULL;
- }
-}
-
-
-void rtl8192_proc_init_one(struct net_device *dev)
-{
- struct proc_dir_entry *e;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- priv->dir_dev = create_proc_entry(dev->name,
- S_IFDIR | S_IRUGO | S_IXUGO,
- rtl8192_proc);
- if (!priv->dir_dev) {
- RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
- dev->name);
- return;
- }
- e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_stats_rx, dev);
-
- if (!e) {
- RT_TRACE(COMP_ERR,"Unable to initialize "
- "/proc/net/rtl8192/%s/stats-rx\n",
- dev->name);
- }
-
-
- e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_stats_tx, dev);
-
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/stats-tx\n",
- dev->name);
- }
-
- e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_stats_ap, dev);
-
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/stats-ap\n",
- dev->name);
- }
-
- e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_1, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-1\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_2, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-2\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_8, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-8\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_9, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-9\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_a, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-a\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_b, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-b\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_c, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-c\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_d, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-d\n",
- dev->name);
- }
- e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO,
- priv->dir_dev, proc_get_registers_e, dev);
- if (!e) {
- RT_TRACE(COMP_ERR, "Unable to initialize "
- "/proc/net/rtl8192/%s/registers-e\n",
- dev->name);
- }
-}
-
-static int proc_netdev_event(struct notifier_block *this,
- unsigned long event, void *ptr)
-{
- struct net_device *net_dev = ptr;
-
- if (net_dev->netdev_ops == &rtl8192_netdev_ops &&
- event == NETDEV_CHANGENAME) {
- rtl8192_proc_remove_one(net_dev);
- rtl8192_proc_init_one(net_dev);
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block proc_netdev_notifier = {
- .notifier_call = proc_netdev_event,
-};
-
-/****************************************************************************
- -----------------------------MISC STUFF-------------------------
-*****************************************************************************/
-
-/* this is only for debugging */
-void print_buffer(u32 *buffer, int len)
-{
- int i;
- u8 *buf =(u8*)buffer;
-
- printk("ASCII BUFFER DUMP (len: %x):\n",len);
-
- for(i=0;i<len;i++)
- printk("%c",buf[i]);
-
- printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
-
- for(i=0;i<len;i++)
- printk("%x",buf[i]);
-
- printk("\n");
-}
-
-//short check_nic_enough_desc(struct net_device *dev, priority_t priority)
-short check_nic_enough_desc(struct net_device *dev,int queue_index)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int used = atomic_read(&priv->tx_pending[queue_index]);
-
- return (used < MAX_TX_URB);
-}
-
-void tx_timeout(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //rtl8192_commit(dev);
-
- schedule_work(&priv->reset_wq);
- //DMESG("TXTIMEOUT");
-}
-
-/* this is only for debug */
-void rtl8192_dump_reg(struct net_device *dev)
-{
- int i;
- int n;
- int max=0x1ff;
-
- RT_TRACE(COMP_PHY, "Dumping NIC register map");
-
- for(n=0;n<=max;)
- {
- printk( "\nD: %2x> ", n);
- for(i=0;i<16 && n<=max;i++,n++)
- printk("%2x ",read_nic_byte(dev,n));
- }
- printk("\n");
-}
-
-/****************************************************************************
- ------------------------------HW STUFF---------------------------
-*****************************************************************************/
-
-void rtl8192_set_mode(struct net_device *dev,int mode)
-{
- u8 ecmd;
- ecmd=read_nic_byte(dev, EPROM_CMD);
- ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
- ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
- ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
- ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
- write_nic_byte(dev, EPROM_CMD, ecmd);
-}
-
-
-void rtl8192_update_msr(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
- u8 msr;
-
- msr = read_nic_byte(dev, MSR);
- msr &= ~ MSR_LINK_MASK;
-
- /* do not change in link_state != WLAN_LINK_ASSOCIATED.
- * msr must be updated if the state is ASSOCIATING.
- * this is intentional and make sense for ad-hoc and
- * master (see the create BSS/IBSS func)
- */
- if (priv->ieee80211->state == IEEE80211_LINKED) {
-
- if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
- msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
- LedAction = LED_CTL_LINK;
- } else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
- else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
-
- } else
- msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
-
- write_nic_byte(dev, MSR, msr);
-
- if(priv->ieee80211->LedControlHandler != NULL)
- priv->ieee80211->LedControlHandler(dev, LedAction);
-}
-
-void rtl8192_set_chan(struct net_device *dev,short ch)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-// u32 tx;
- RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
- //printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
- priv->chan=ch;
-
- /* this hack should avoid frame TX during channel setting*/
-
-
-// tx = read_nic_dword(dev,TX_CONF);
-// tx &= ~TX_LOOPBACK_MASK;
-
-#ifndef LOOP_TEST
-// write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
-
- //need to implement rf set channel here WB
-
- if (priv->rf_set_chan)
- priv->rf_set_chan(dev,priv->chan);
- mdelay(10);
-// write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
-#endif
-}
-
-static void rtl8192_rx_isr(struct urb *urb);
-
-u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
-{
-
- return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
- + pstats->RxBufShift);
-
-}
-static int rtl8192_rx_initiate(struct net_device*dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct urb *entry;
- struct sk_buff *skb;
- struct rtl8192_rx_info *info;
-
- /* nomal packet rx procedure */
- while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB) {
- skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
- if (!skb)
- break;
- entry = usb_alloc_urb(0, GFP_KERNEL);
- if (!entry) {
- kfree_skb(skb);
- break;
- }
- usb_fill_bulk_urb(entry, priv->udev,
- usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
- RX_URB_SIZE, rtl8192_rx_isr, skb);
- info = (struct rtl8192_rx_info *) skb->cb;
- info->urb = entry;
- info->dev = dev;
- info->out_pipe = 3; //denote rx normal packet queue
- skb_queue_tail(&priv->rx_queue, skb);
- usb_submit_urb(entry, GFP_KERNEL);
- }
-
- /* command packet rx procedure */
- while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) {
- skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
- if (!skb)
- break;
- entry = usb_alloc_urb(0, GFP_KERNEL);
- if (!entry) {
- kfree_skb(skb);
- break;
- }
- usb_fill_bulk_urb(entry, priv->udev,
- usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
- RX_URB_SIZE, rtl8192_rx_isr, skb);
- info = (struct rtl8192_rx_info *) skb->cb;
- info->urb = entry;
- info->dev = dev;
- info->out_pipe = 9; //denote rx cmd packet queue
- skb_queue_tail(&priv->rx_queue, skb);
- usb_submit_urb(entry, GFP_KERNEL);
- }
-
- return 0;
-}
-
-void rtl8192_set_rxconf(struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- u32 rxconf;
-
- rxconf=read_nic_dword(dev,RCR);
- rxconf = rxconf &~ MAC_FILTER_MASK;
- rxconf = rxconf | RCR_AMF;
- rxconf = rxconf | RCR_ADF;
- rxconf = rxconf | RCR_AB;
- rxconf = rxconf | RCR_AM;
- //rxconf = rxconf | RCR_ACF;
-
- if (dev->flags & IFF_PROMISC) {DMESG ("NIC in promisc mode");}
-
- if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
- dev->flags & IFF_PROMISC){
- rxconf = rxconf | RCR_AAP;
- } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
- rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
- rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
- }*/else{
- rxconf = rxconf | RCR_APM;
- rxconf = rxconf | RCR_CBSSID;
- }
-
-
- if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
- rxconf = rxconf | RCR_AICV;
- rxconf = rxconf | RCR_APWRMGT;
- }
-
- if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- rxconf = rxconf | RCR_ACRC32;
-
-
- rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
- rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
- rxconf = rxconf &~ MAX_RX_DMA_MASK;
- rxconf = rxconf | ((u32)7<<RCR_MXDMA_OFFSET);
-
-// rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
- rxconf = rxconf | RCR_ONLYERLPKT;
-
-// rxconf = rxconf &~ RCR_CS_MASK;
-// rxconf = rxconf | (1<<RCR_CS_SHIFT);
-
- write_nic_dword(dev, RCR, rxconf);
-
- #ifdef DEBUG_RX
- DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RCR));
- #endif
-}
-//wait to be removed
-void rtl8192_rx_enable(struct net_device *dev)
-{
- //u8 cmd;
-
- //struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- rtl8192_rx_initiate(dev);
-
-// rtl8192_set_rxconf(dev);
-}
-
-
-void rtl8192_tx_enable(struct net_device *dev)
-{
-}
-
-void rtl8192_rtx_disable(struct net_device *dev)
-{
- u8 cmd;
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct sk_buff *skb;
- struct rtl8192_rx_info *info;
-
- cmd=read_nic_byte(dev,CMDR);
- write_nic_byte(dev, CMDR, cmd &~ \
- (CR_TE|CR_RE));
- force_pci_posting(dev);
- mdelay(10);
-
- while ((skb = __skb_dequeue(&priv->rx_queue))) {
- info = (struct rtl8192_rx_info *) skb->cb;
- if (!info->urb)
- continue;
-
- usb_kill_urb(info->urb);
- kfree_skb(skb);
- }
-
- if (skb_queue_len(&priv->skb_queue)) {
- printk(KERN_WARNING "skb_queue not empty\n");
- }
-
- skb_queue_purge(&priv->skb_queue);
- return;
-}
-
-
-int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
-{
- return 0;
-}
-
-inline u16 ieeerate2rtlrate(int rate)
-{
- switch(rate){
- case 10:
- return 0;
- case 20:
- return 1;
- case 55:
- return 2;
- case 110:
- return 3;
- case 60:
- return 4;
- case 90:
- return 5;
- case 120:
- return 6;
- case 180:
- return 7;
- case 240:
- return 8;
- case 360:
- return 9;
- case 480:
- return 10;
- case 540:
- return 11;
- default:
- return 3;
-
- }
-}
-static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
-inline u16 rtl8192_rate2rate(short rate)
-{
- if (rate >11) return 0;
- return rtl_rate[rate];
-}
-
-static void rtl8192_rx_isr(struct urb *urb)
-{
- struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
- struct net_device *dev = info->dev;
- struct r8192_priv *priv = ieee80211_priv(dev);
- int out_pipe = info->out_pipe;
- int err;
- if(!priv->up)
- return;
- if (unlikely(urb->status)) {
- info->urb = NULL;
- priv->stats.rxstaterr++;
- priv->ieee80211->stats.rx_errors++;
- usb_free_urb(urb);
- // printk("%s():rx status err\n",__FUNCTION__);
- return;
- }
-
- skb_unlink(skb, &priv->rx_queue);
- skb_put(skb, urb->actual_length);
-
- skb_queue_tail(&priv->skb_queue, skb);
- tasklet_schedule(&priv->irq_rx_tasklet);
-
- skb = dev_alloc_skb(RX_URB_SIZE);
- if (unlikely(!skb)) {
- usb_free_urb(urb);
- printk("%s():can,t alloc skb\n",__FUNCTION__);
- /* TODO check rx queue length and refill *somewhere* */
- return;
- }
-
- usb_fill_bulk_urb(urb, priv->udev,
- usb_rcvbulkpipe(priv->udev, out_pipe),
- skb_tail_pointer(skb),
- RX_URB_SIZE, rtl8192_rx_isr, skb);
-
- info = (struct rtl8192_rx_info *) skb->cb;
- info->urb = urb;
- info->dev = dev;
- info->out_pipe = out_pipe;
-
- urb->transfer_buffer = skb_tail_pointer(skb);
- urb->context = skb;
- skb_queue_tail(&priv->rx_queue, skb);
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if(err && err != -EPERM)
- printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
-}
-
-u32
-rtl819xusb_rx_command_packet(
- struct net_device *dev,
- struct ieee80211_rx_stats *pstats
- )
-{
- u32 status;
-
- //RT_TRACE(COMP_RECV, DBG_TRACE, ("---> RxCommandPacketHandle819xUsb()\n"));
-
- status = cmpk_message_handle_rx(dev, pstats);
- if (status)
- {
- DMESG("rxcommandpackethandle819xusb: It is a command packet\n");
- }
- else
- {
- //RT_TRACE(COMP_RECV, DBG_TRACE, ("RxCommandPacketHandle819xUsb: It is not a command packet\n"));
- }
-
- //RT_TRACE(COMP_RECV, DBG_TRACE, ("<--- RxCommandPacketHandle819xUsb()\n"));
- return status;
-}
-
-void rtl8192_data_hard_stop(struct net_device *dev)
-{
- //FIXME !!
-}
-
-
-void rtl8192_data_hard_resume(struct net_device *dev)
-{
- // FIXME !!
-}
-
-/* this function TX data frames when the ieee80211 stack requires this.
- * It checks also if we need to stop the ieee tx queue, eventually do it
- */
-void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- int ret;
- unsigned long flags;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
-
- /* shall not be referred by command packet */
- assert(queue_index != TXCMD_QUEUE);
-
- spin_lock_irqsave(&priv->tx_lock,flags);
-
- memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-// tcb_desc->RATRIndex = 7;
-// tcb_desc->bTxDisableRateFallBack = 1;
-// tcb_desc->bTxUseDriverAssingedRate = 1;
- tcb_desc->bTxEnableFwCalcDur = 1;
- skb_push(skb, priv->ieee80211->tx_headroom);
- ret = priv->ops->rtl819x_tx(dev, skb);
-
- //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
- //priv->ieee80211->stats.tx_packets++;
-
- spin_unlock_irqrestore(&priv->tx_lock,flags);
-
-// return ret;
- return;
-}
-
-/* This is a rough attempt to TX a frame
- * This is called by the ieee 80211 stack to TX management frames.
- * If the ring is full packet are dropped (for data frame the queue
- * is stopped before this can happen).
- */
-int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- int ret;
- unsigned long flags;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
-
-
- spin_lock_irqsave(&priv->tx_lock,flags);
-
- memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
- if(queue_index == TXCMD_QUEUE) {
- skb_push(skb, USB_HWDESC_HEADER_LEN);
- priv->ops->rtl819x_tx_cmd(dev, skb);
- ret = 1;
- spin_unlock_irqrestore(&priv->tx_lock,flags);
- return ret;
- } else {
- skb_push(skb, priv->ieee80211->tx_headroom);
- ret = priv->ops->rtl819x_tx(dev, skb);
- }
-
- spin_unlock_irqrestore(&priv->tx_lock,flags);
-
- return ret;
-}
-
-
-void rtl8192_try_wake_queue(struct net_device *dev, int pri);
-
-
-static void rtl8192_tx_isr(struct urb *tx_urb)
-{
- struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
- struct net_device *dev = NULL;
- struct r8192_priv *priv = NULL;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
-// bool bToSend0Byte;
-// u16 BufLen = skb->len;
-
- memcpy(&dev,(struct net_device*)(skb->cb),sizeof(struct net_device*));
- priv = ieee80211_priv(dev);
-
- if(tcb_desc->queue_index != TXCMD_QUEUE) {
- if(tx_urb->status == 0) {
- // dev->trans_start = jiffies;
- // As act as station mode, destion shall be unicast address.
- //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
- //priv->ieee80211->stats.tx_packets++;
- priv->stats.txoktotal++;
- priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
- priv->stats.txbytesunicast += (skb->len - priv->ieee80211->tx_headroom);
- } else {
- priv->ieee80211->stats.tx_errors++;
- //priv->stats.txmanageerr++;
- /* TODO */
- }
- }
-
- /* free skb and tx_urb */
- if(skb != NULL) {
- dev_kfree_skb_any(skb);
- usb_free_urb(tx_urb);
- atomic_dec(&priv->tx_pending[queue_index]);
- }
-
- {
- //
- // Handle HW Beacon:
- // We had transfer our beacon frame to host controler at this moment.
- //
- //
- // Caution:
- // Handling the wait queue of command packets.
- // For Tx command packets, we must not do TCB fragment because it is not handled right now.
- // We must cut the packets to match the size of TX_CMD_PKT before we send it.
- //
- if (queue_index == MGNT_QUEUE){
- if (priv->ieee80211->ack_tx_to_ieee){
- if (rtl8192_is_tx_queue_empty(dev)){
- priv->ieee80211->ack_tx_to_ieee = 0;
- ieee80211_ps_tx_ack(priv->ieee80211, 1);
- }
- }
- }
- /* Handle MPDU in wait queue. */
- if(queue_index != BEACON_QUEUE) {
- /* Don't send data frame during scanning.*/
- if((skb_queue_len(&priv->ieee80211->skb_waitQ[queue_index]) != 0)&&\
- (!(priv->ieee80211->queue_stop))) {
- if(NULL != (skb = skb_dequeue(&(priv->ieee80211->skb_waitQ[queue_index]))))
- priv->ieee80211->softmac_hard_start_xmit(skb, dev);
-
- return; //modified by david to avoid further processing AMSDU
- }
- }
- }
-}
-
-void rtl8192_beacon_stop(struct net_device *dev)
-{
- u8 msr, msrm, msr2;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- msr = read_nic_byte(dev, MSR);
- msrm = msr & MSR_LINK_MASK;
- msr2 = msr & ~MSR_LINK_MASK;
-
- if(NIC_8192U == priv->card_8192) {
- usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
- }
- if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
- (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
- write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
- write_nic_byte(dev, MSR, msr);
- }
-}
-
-void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_network *net;
- u8 i=0, basic_rate = 0;
- net = & priv->ieee80211->current_network;
-
- for (i=0; i<net->rates_len; i++)
- {
- basic_rate = net->rates[i]&0x7f;
- switch(basic_rate)
- {
- case MGN_1M: *rate_config |= RRSR_1M; break;
- case MGN_2M: *rate_config |= RRSR_2M; break;
- case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
- case MGN_11M: *rate_config |= RRSR_11M; break;
- case MGN_6M: *rate_config |= RRSR_6M; break;
- case MGN_9M: *rate_config |= RRSR_9M; break;
- case MGN_12M: *rate_config |= RRSR_12M; break;
- case MGN_18M: *rate_config |= RRSR_18M; break;
- case MGN_24M: *rate_config |= RRSR_24M; break;
- case MGN_36M: *rate_config |= RRSR_36M; break;
- case MGN_48M: *rate_config |= RRSR_48M; break;
- case MGN_54M: *rate_config |= RRSR_54M; break;
- }
- }
- for (i=0; i<net->rates_ex_len; i++)
- {
- basic_rate = net->rates_ex[i]&0x7f;
- switch(basic_rate)
- {
- case MGN_1M: *rate_config |= RRSR_1M; break;
- case MGN_2M: *rate_config |= RRSR_2M; break;
- case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
- case MGN_11M: *rate_config |= RRSR_11M; break;
- case MGN_6M: *rate_config |= RRSR_6M; break;
- case MGN_9M: *rate_config |= RRSR_9M; break;
- case MGN_12M: *rate_config |= RRSR_12M; break;
- case MGN_18M: *rate_config |= RRSR_18M; break;
- case MGN_24M: *rate_config |= RRSR_24M; break;
- case MGN_36M: *rate_config |= RRSR_36M; break;
- case MGN_48M: *rate_config |= RRSR_48M; break;
- case MGN_54M: *rate_config |= RRSR_54M; break;
- }
- }
-}
-
-
-#define SHORT_SLOT_TIME 9
-#define NON_SHORT_SLOT_TIME 20
-
-void rtl8192_update_cap(struct net_device* dev, u16 cap)
-{
- //u32 tmp = 0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_network *net = &priv->ieee80211->current_network;
- priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
-
- //LZM MOD 090303 HW_VAR_ACK_PREAMBLE
- if(0)
- {
- u8 tmp = 0;
- tmp = ((priv->nCur40MhzPrimeSC) << 5);
- if (priv->short_preamble)
- tmp |= 0x80;
- write_nic_byte(dev, RRSR+2, tmp);
- }
-
- if (net->mode & (IEEE_G|IEEE_N_24G))
- {
- u8 slot_time = 0;
- if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
- {//short slot time
- slot_time = SHORT_SLOT_TIME;
- }
- else //long slot time
- slot_time = NON_SHORT_SLOT_TIME;
- priv->slot_time = slot_time;
- write_nic_byte(dev, SLOT_TIME, slot_time);
- }
-
-}
-void rtl8192_net_update(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_network *net;
- u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
- u16 rate_config = 0;
- net = & priv->ieee80211->current_network;
-
- rtl8192_config_rate(dev, &rate_config);
- priv->basic_rate = rate_config &= 0x15f;
-
- write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
- write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
- //for(i=0;i<ETH_ALEN;i++)
- // write_nic_byte(dev,BSSID+i,net->bssid[i]);
-
- rtl8192_update_msr(dev);
-// rtl8192_update_cap(dev, net->capability);
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- {
- write_nic_word(dev, ATIMWND, 2);
- write_nic_word(dev, BCN_DMATIME, 1023);
- write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
-// write_nic_word(dev, BcnIntTime, 100);
- write_nic_word(dev, BCN_DRV_EARLY_INT, 1);
- write_nic_byte(dev, BCN_ERR_THRESH, 100);
- BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
- // TODO: BcnIFS may required to be changed on ASIC
- BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
-
- write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
- }
-
-
-
-}
-
-//temporary hw beacon is not used any more.
-//open it when necessary
-#if 1
-void rtl819xusb_beacon_tx(struct net_device *dev,u16 tx_rate)
-{
-}
-#endif
-inline u8 rtl8192_IsWirelessBMode(u16 rate)
-{
- if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
- return 1;
- else return 0;
-}
-
-u16 N_DBPSOfRate(u16 DataRate);
-
-u16 ComputeTxTime(
- u16 FrameLength,
- u16 DataRate,
- u8 bManagementFrame,
- u8 bShortPreamble
-)
-{
- u16 FrameTime;
- u16 N_DBPS;
- u16 Ceiling;
-
- if( rtl8192_IsWirelessBMode(DataRate) )
- {
- if( bManagementFrame || !bShortPreamble || DataRate == 10 )
- { // long preamble
- FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
- }
- else
- { // Short preamble
- FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
- }
- if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
- FrameTime ++;
- } else { //802.11g DSSS-OFDM PLCP length field calculation.
- N_DBPS = N_DBPSOfRate(DataRate);
- Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
- + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
- FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
- }
- return FrameTime;
-}
-
-u16 N_DBPSOfRate(u16 DataRate)
-{
- u16 N_DBPS = 24;
-
- switch(DataRate)
- {
- case 60:
- N_DBPS = 24;
- break;
-
- case 90:
- N_DBPS = 36;
- break;
-
- case 120:
- N_DBPS = 48;
- break;
-
- case 180:
- N_DBPS = 72;
- break;
-
- case 240:
- N_DBPS = 96;
- break;
-
- case 360:
- N_DBPS = 144;
- break;
-
- case 480:
- N_DBPS = 192;
- break;
-
- case 540:
- N_DBPS = 216;
- break;
-
- default:
- break;
- }
-
- return N_DBPS;
-}
-
-void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
-{
- usb_free_urb(tx_cmd_urb);
-}
-
-unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
-
- if(tx_queue >= 9)
- {
- RT_TRACE(COMP_ERR,"%s():Unknown queue ID!!!\n",__FUNCTION__);
- return 0x04;
- }
- return priv->txqueue_to_outpipemap[tx_queue];
-}
-
-short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int status;
- struct urb *tx_urb;
- unsigned int idx_pipe;
- tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- u8 queue_index = tcb_desc->queue_index;
- u32 PktSize = 0;
-
- //printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
- atomic_inc(&priv->tx_pending[queue_index]);
-
- tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
- if(!tx_urb){
- dev_kfree_skb(skb);
- return -ENOMEM;
- }
-
- memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
-
- /* Tx descriptor ought to be set according to the skb->cb */
- pdesc->LINIP = tcb_desc->bLastIniPkt;
- PktSize = (u16)(skb->len - USB_HWDESC_HEADER_LEN);
- pdesc->PktSize = PktSize;
- //printk("PKTSize = %d %x\n",pdesc->PktSize,pdesc->PktSize);
- //----------------------------------------------------------------------------
- // Fill up USB_OUT_CONTEXT.
- //----------------------------------------------------------------------------
- // Get index to out pipe from specified QueueID.
- idx_pipe = txqueue2outpipe(priv,queue_index);
- //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
-
- usb_fill_bulk_urb(tx_urb,
- priv->udev,
- usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
- skb->data,
- skb->len,
- rtl8192_tx_isr,
- skb);
-
- status = usb_submit_urb(tx_urb, GFP_ATOMIC);
- if (!status){
- return 0;
- }else{
- printk("Error TX CMD URB, error %d",
- status);
- return -1;
- }
-}
-
-/*
- * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
- * in TxFwInfo data structure
- * 2006.10.30 by Emily
- *
- * \param QUEUEID Software Queue
-*/
-u8 MapHwQueueToFirmwareQueue(u8 QueueID)
-{
- u8 QueueSelect = 0x0; //defualt set to
-
- switch(QueueID) {
- case BE_QUEUE:
- QueueSelect = QSLT_BE; //or QSelect = pTcb->priority;
- break;
-
- case BK_QUEUE:
- QueueSelect = QSLT_BK; //or QSelect = pTcb->priority;
- break;
-
- case VO_QUEUE:
- QueueSelect = QSLT_VO; //or QSelect = pTcb->priority;
- break;
-
- case VI_QUEUE:
- QueueSelect = QSLT_VI; //or QSelect = pTcb->priority;
- break;
- case MGNT_QUEUE:
- QueueSelect = QSLT_MGNT;
- break;
-
- case BEACON_QUEUE:
- QueueSelect = QSLT_BEACON;
- break;
-
- // TODO: 2006.10.30 mark other queue selection until we verify it is OK
- // TODO: Remove Assertions
-//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
- case TXCMD_QUEUE:
- QueueSelect = QSLT_CMD;
- break;
-//#endif
- case HIGH_QUEUE:
- QueueSelect = QSLT_HIGH;
- break;
-
- default:
- RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
- break;
- }
- return QueueSelect;
-}
-
-u8 MRateToHwRate8190Pci(u8 rate)
-{
- u8 ret = DESC92S_RATE1M;
-
- switch(rate)
- {
- // CCK and OFDM non-HT rates
- case MGN_1M: ret = DESC92S_RATE1M; break;
- case MGN_2M: ret = DESC92S_RATE2M; break;
- case MGN_5_5M: ret = DESC92S_RATE5_5M; break;
- case MGN_11M: ret = DESC92S_RATE11M; break;
- case MGN_6M: ret = DESC92S_RATE6M; break;
- case MGN_9M: ret = DESC92S_RATE9M; break;
- case MGN_12M: ret = DESC92S_RATE12M; break;
- case MGN_18M: ret = DESC92S_RATE18M; break;
- case MGN_24M: ret = DESC92S_RATE24M; break;
- case MGN_36M: ret = DESC92S_RATE36M; break;
- case MGN_48M: ret = DESC92S_RATE48M; break;
- case MGN_54M: ret = DESC92S_RATE54M; break;
-
- // HT rates since here
- case MGN_MCS0: ret = DESC92S_RATEMCS0; break;
- case MGN_MCS1: ret = DESC92S_RATEMCS1; break;
- case MGN_MCS2: ret = DESC92S_RATEMCS2; break;
- case MGN_MCS3: ret = DESC92S_RATEMCS3; break;
- case MGN_MCS4: ret = DESC92S_RATEMCS4; break;
- case MGN_MCS5: ret = DESC92S_RATEMCS5; break;
- case MGN_MCS6: ret = DESC92S_RATEMCS6; break;
- case MGN_MCS7: ret = DESC92S_RATEMCS7; break;
- case MGN_MCS8: ret = DESC92S_RATEMCS8; break;
- case MGN_MCS9: ret = DESC92S_RATEMCS9; break;
- case MGN_MCS10: ret = DESC92S_RATEMCS10; break;
- case MGN_MCS11: ret = DESC92S_RATEMCS11; break;
- case MGN_MCS12: ret = DESC92S_RATEMCS12; break;
- case MGN_MCS13: ret = DESC92S_RATEMCS13; break;
- case MGN_MCS14: ret = DESC92S_RATEMCS14; break;
- case MGN_MCS15: ret = DESC92S_RATEMCS15; break;
-
- // Set the highest SG rate
- case MGN_MCS0_SG:
- case MGN_MCS1_SG:
- case MGN_MCS2_SG:
- case MGN_MCS3_SG:
- case MGN_MCS4_SG:
- case MGN_MCS5_SG:
- case MGN_MCS6_SG:
- case MGN_MCS7_SG:
- case MGN_MCS8_SG:
- case MGN_MCS9_SG:
- case MGN_MCS10_SG:
- case MGN_MCS11_SG:
- case MGN_MCS12_SG:
- case MGN_MCS13_SG:
- case MGN_MCS14_SG:
- case MGN_MCS15_SG:
- {
- ret = DESC92S_RATEMCS15_SG;
- break;
- }
-
- default: break;
- }
- return ret;
-}
-
-u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
-{
- u8 tmp_Short;
-
- tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
-
- if(TxHT==1 && TxRate != DESC90_RATEMCS15)
- tmp_Short = 0;
-
- return tmp_Short;
-}
-
-static void tx_zero_isr(struct urb *tx_urb)
-{
- return;
-}
-
-
-/*
- * The tx procedure is just as following, skb->cb will contain all the following
- *information: * priority, morefrag, rate, &dev.
- * */
- // <Note> Buffer format for 8192S Usb bulk out:
-//
-// --------------------------------------------------
-// | 8192S Usb Tx Desc | 802_11_MAC_header | data |
-// --------------------------------------------------
-// | 32 bytes | 24 bytes |0-2318 bytes|
-// --------------------------------------------------
-// |<------------ BufferLen ------------------------->|
-
-short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
- struct usb_device *udev = priv->udev;
- int pend;
- int status;
- struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
- unsigned int idx_pipe;
- u16 MPDUOverhead = 0;
- u16 type = 0;
-
- pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
- /* we are locked here so the two atomic_read and inc are executed
- * without interleaves * !!! For debug purpose */
- if( pend > MAX_TX_URB){
- switch (tcb_desc->queue_index) {
- case VO_PRIORITY:
- priv->stats.txvodrop++;
- break;
- case VI_PRIORITY:
- priv->stats.txvidrop++;
- break;
- case BE_PRIORITY:
- priv->stats.txbedrop++;
- break;
- default://BK_PRIORITY
- priv->stats.txbkdrop++;
- break;
- }
- printk("To discard skb packet!\n");
- dev_kfree_skb_any(skb);
- return -1;
- }
-
- tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
- if(!tx_urb){
- dev_kfree_skb_any(skb);
- return -ENOMEM;
- }
-
- memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
-
-
- tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
-
- /* Fill Tx descriptor */
- //memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
-
- // This part can just fill to the first descriptor of the frame.
- /* DWORD 0 */
- tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
-
-
- tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
- //tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
- tx_desc->TxShort = QueryIsShort(tx_desc->TxHT, tx_desc->TxRate, tcb_desc);
-
-
- // Aggregation related
- if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
- tx_desc->AllowAggregation = 1;
- /* DWORD 1 */
- //tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
- //tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
- } else {
- tx_desc->AllowAggregation = 0;
- /* DWORD 1 */
- //tx_fwinfo->RxMF = 0;
- //tx_fwinfo->RxAMD = 0;
- }
-
- //
- // <Roger_Notes> For AMPDU case, we must insert SSN into TX_DESC,
- // FW according as this SSN to do necessary packet retry.
- // 2008.06.06.
- //
- {
- u8 *pSeq;
- u16 Temp;
- //pSeq = (u8 *)(VirtualAddress+USB_HWDESC_HEADER_LEN + FRAME_OFFSET_SEQUENCE);
- pSeq = (u8 *)(skb->data+USB_HWDESC_HEADER_LEN + 22);
- Temp = pSeq[0];
- Temp <<= 12;
- Temp |= (*(u16 *)pSeq)>>4;
- tx_desc->Seq = Temp;
- }
-
- /* Protection mode related */
- tx_desc->RTSEn = (tcb_desc->bRTSEnable)?1:0;
- tx_desc->CTS2Self = (tcb_desc->bCTSEnable)?1:0;
- tx_desc->RTSSTBC = (tcb_desc->bRTSSTBC)?1:0;
- tx_desc->RTSHT = (tcb_desc->rts_rate&0x80)?1:0;
- tx_desc->RTSRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
- tx_desc->RTSSubcarrier = (tx_desc->RTSHT==0)?(tcb_desc->RTSSC):0;
- tx_desc->RTSBW = (tx_desc->RTSHT==1)?((tcb_desc->bRTSBW)?1:0):0;
- tx_desc->RTSShort = (tx_desc->RTSHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
- (tcb_desc->bRTSUseShortGI?1:0);
- //LZM 090219
- tx_desc->DisRTSFB = 0;
- tx_desc->RTSRateFBLmt = 0xf;
-
- // <Roger_EXP> 2008.09.22. We disable RTS rate fallback temporarily.
- //tx_desc->DisRTSFB = 0x01;
-
- /* Set Bandwidth and sub-channel settings. */
- if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
- {
- if(tcb_desc->bPacketBW) {
- tx_desc->TxBandwidth = 1;
- tx_desc->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode
- } else {
- tx_desc->TxBandwidth = 0;
- tx_desc->TxSubCarrier = priv->nCur40MhzPrimeSC;
- }
- } else {
- tx_desc->TxBandwidth = 0;
- tx_desc->TxSubCarrier = 0;
- }
-
-
- //memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
- /* DWORD 0 */
- tx_desc->LINIP = 0;
- //tx_desc->CmdInit = 1; //92su del
- tx_desc->Offset = USB_HWDESC_HEADER_LEN;
-
- {
- tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
- }
-
- /*DWORD 1*/
- //tx_desc->SecCAMID= 0;//92su del
- tx_desc->RaBRSRID= tcb_desc->RATRIndex;
-//#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
-
- {
- MPDUOverhead = 0;
- //tx_desc->NoEnc = 1;//92su del
- }
-
- tx_desc->SecType = 0x0;
-
- if (tcb_desc->bHwSec)
- {
- switch (priv->ieee80211->pairwise_key_type)
- {
- case KEY_TYPE_WEP40:
- case KEY_TYPE_WEP104:
- tx_desc->SecType = 0x1;
- //tx_desc->NoEnc = 0;//92su del
- break;
- case KEY_TYPE_TKIP:
- tx_desc->SecType = 0x2;
- //tx_desc->NoEnc = 0;//92su del
- break;
- case KEY_TYPE_CCMP:
- tx_desc->SecType = 0x3;
- //tx_desc->NoEnc = 0;//92su del
- break;
- case KEY_TYPE_NA:
- tx_desc->SecType = 0x0;
- //tx_desc->NoEnc = 1;//92su del
- break;
- default:
- tx_desc->SecType = 0x0;
- //tx_desc->NoEnc = 1;//92su del
- break;
- }
- }
-
- //tx_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb);//92su del
-
-
- tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
- tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
- tx_desc->DataRateFBLmt = 0x1F;// Alwasy enable all rate fallback range
-
- tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
-
-
- /* Fill fields that are required to be initialized in all of the descriptors */
- //DWORD 0
- tx_desc->FirstSeg = 1;
- tx_desc->LastSeg = 1;
- tx_desc->OWN = 1;
-
- {
- //DWORD 2
- //tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
- tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
- }
-
- /* Get index to out pipe from specified QueueID */
- idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
- //printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
-
- //RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
- //RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
-
- /* To submit bulk urb */
- usb_fill_bulk_urb(tx_urb,
- udev,
- usb_sndbulkpipe(udev,priv->RtOutPipes[idx_pipe]),
- skb->data,
- skb->len, rtl8192_tx_isr, skb);
-
- if (type == IEEE80211_FTYPE_DATA) {
- if (priv->ieee80211->LedControlHandler != NULL)
- priv->ieee80211->LedControlHandler(dev, LED_CTL_TX);
- }
-
- status = usb_submit_urb(tx_urb, GFP_ATOMIC);
- if (!status) {
- /*
- * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted.
- * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
- */
- bool bSend0Byte = false;
- u8 zero = 0;
- if(udev->speed == USB_SPEED_HIGH) {
- if (skb->len > 0 && skb->len % 512 == 0)
- bSend0Byte = true;
- }
- else {
- if (skb->len > 0 && skb->len % 64 == 0)
- bSend0Byte = true;
- }
- if (bSend0Byte) {
- tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
- if(!tx_urb_zero) {
- RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
- return -ENOMEM;
- }
- usb_fill_bulk_urb(tx_urb_zero,udev,
- usb_sndbulkpipe(udev,idx_pipe), &zero,
- 0, tx_zero_isr, dev);
- status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
- switch (status) {
- case 0:
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- break;
- default:
- RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d",
- atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
- return -1;
- }
- }
- dev->trans_start = jiffies;
- atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
- return 0;
- } else {
- RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
- status);
- return -1;
- }
-}
-
-void rtl8192SU_net_update(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- struct ieee80211_network *net = &priv->ieee80211->current_network;
- //u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
- u16 rate_config = 0;
- u32 regTmp = 0;
- u8 rateIndex = 0;
- u8 retrylimit = 0x30;
- u16 cap = net->capability;
-
- priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
-
-//HW_VAR_BASIC_RATE
- //update Basic rate: RR, BRSR
- rtl8192_config_rate(dev, &rate_config); //HalSetBrateCfg
-
- priv->basic_rate = rate_config = rate_config & 0x15f;
-
- // Set RRSR rate table.
- write_nic_byte(dev, RRSR, rate_config&0xff);
- write_nic_byte(dev, RRSR+1, (rate_config>>8)&0xff);
-
- // Set RTS initial rate
- while(rate_config > 0x1)
- {
- rate_config = (rate_config>> 1);
- rateIndex++;
- }
- write_nic_byte(dev, INIRTSMCS_SEL, rateIndex);
-//HW_VAR_BASIC_RATE
-
- //set ack preample
- regTmp = (priv->nCur40MhzPrimeSC) << 5;
- if (priv->short_preamble)
- regTmp |= 0x80;
- write_nic_byte(dev, RRSR+2, regTmp);
-
- write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
- write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
-
- write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
- //2008.10.24 added by tynli for beacon changed.
- PHY_SetBeaconHwReg( dev, net->beacon_interval);
-
- rtl8192_update_cap(dev, cap);
-
- if (ieee->iw_mode == IW_MODE_ADHOC){
- retrylimit = 7;
- //we should enable ibss interrupt here, but disable it temporarily
- if (0){
- priv->irq_mask |= (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
- //rtl8192_irq_disable(dev);
- //rtl8192_irq_enable(dev);
- }
- }
- else{
- if (0){
- priv->irq_mask &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
- //rtl8192_irq_disable(dev);
- //rtl8192_irq_enable(dev);
- }
- }
-
- priv->ShortRetryLimit = priv->LongRetryLimit = retrylimit;
-
- write_nic_word(dev, RETRY_LIMIT,
- retrylimit << RETRY_LIMIT_SHORT_SHIFT | \
- retrylimit << RETRY_LIMIT_LONG_SHIFT);
-}
-
-void rtl8192SU_update_ratr_table(struct net_device* dev)
-{
- struct r8192_priv* priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- u8* pMcsRate = ieee->dot11HTOperationalRateSet;
- //struct ieee80211_network *net = &ieee->current_network;
- u32 ratr_value = 0;
-
- u8 rate_index = 0;
- int WirelessMode = ieee->mode;
- u8 MimoPs = ieee->pHTInfo->PeerMimoPs;
-
- u8 bNMode = 0;
-
- rtl8192_config_rate(dev, (u16*)(&ratr_value));
- ratr_value |= (*(u16*)(pMcsRate)) << 12;
-
- //switch (ieee->mode)
- switch (WirelessMode)
- {
- case IEEE_A:
- ratr_value &= 0x00000FF0;
- break;
- case IEEE_B:
- ratr_value &= 0x0000000D;
- break;
- case IEEE_G:
- ratr_value &= 0x00000FF5;
- break;
- case IEEE_N_24G:
- case IEEE_N_5G:
- {
- bNMode = 1;
-
- if (MimoPs == 0) //MIMO_PS_STATIC
- {
- ratr_value &= 0x0007F005;
- }
- else
- { // MCS rate only => for 11N mode.
- u32 ratr_mask;
-
- // 1T2R or 1T1R, Spatial Stream 2 should be disabled
- if ( priv->rf_type == RF_1T2R ||
- priv->rf_type == RF_1T1R ||
- (ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_2SS) )
- ratr_mask = 0x000ff005;
- else
- ratr_mask = 0x0f0ff005;
-
- if((ieee->pHTInfo->bCurTxBW40MHz) &&
- !(ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_TX_40_MHZ))
- ratr_mask |= 0x00000010; // Set 6MBps
-
- // Select rates for rate adaptive mechanism.
- ratr_value &= ratr_mask;
- }
- }
- break;
- default:
- if(0)
- {
- if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
- {
- ratr_value &= 0x000ff0f5;
- }
- else
- {
- ratr_value &= 0x0f0ff0f5;
- }
- }
- //printk("====>%s(), mode is not correct:%x\n", __FUNCTION__, ieee->mode);
- break;
- }
-
- ratr_value &= 0x0FFFFFFF;
-
- // Get MAX MCS available.
- if ( (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
- ((ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI40MHz) ||
- (!ieee->pHTInfo->bCurBW40MHz && ieee->pHTInfo->bCurShortGI20MHz)))
- {
- u8 shortGI_rate = 0;
- u32 tmp_ratr_value = 0;
- ratr_value |= 0x10000000;//???
- tmp_ratr_value = (ratr_value>>12);
- for(shortGI_rate=15; shortGI_rate>0; shortGI_rate--)
- {
- if((1<<shortGI_rate) & tmp_ratr_value)
- break;
- }
- shortGI_rate = (shortGI_rate<<12)|(shortGI_rate<<8)|(shortGI_rate<<4)|(shortGI_rate);
- write_nic_byte(dev, SG_RATE, shortGI_rate);
- //printk("==>SG_RATE:%x\n", read_nic_byte(dev, SG_RATE));
- }
- write_nic_dword(dev, ARFR0+rate_index*4, ratr_value);
- printk("=============>ARFR0+rate_index*4:%#x\n", ratr_value);
-
- //2 UFWP
- if (ratr_value & 0xfffff000){
- //printk("===>set to N mode\n");
- HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_N);
- }
- else {
- //printk("===>set to B/G mode\n");
- HalSetFwCmd8192S(dev, FW_CMD_RA_REFRESH_BG);
- }
-}
-
-void rtl8192SU_link_change(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- u32 reg = 0;
-
- reg = read_nic_dword(dev, RCR);
- if (ieee->state == IEEE80211_LINKED) {
- rtl8192SU_net_update(dev);
- rtl8192SU_update_ratr_table(dev);
- ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE);
- priv->ReceiveConfig = reg |= RCR_CBSSID;
-
- } else
- priv->ReceiveConfig = reg &= ~RCR_CBSSID;
- write_nic_dword(dev, RCR, reg);
- rtl8192_update_msr(dev);
-}
-
-static struct ieee80211_qos_parameters def_qos_parameters = {
- {3,3,3,3},/* cw_min */
- {7,7,7,7},/* cw_max */
- {2,2,2,2},/* aifs */
- {0,0,0,0},/* flags */
- {0,0,0,0} /* tx_op_limit */
-};
-
-
-void rtl8192_update_beacon(struct work_struct * work)
-{
- struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
- struct net_device *dev = priv->ieee80211->dev;
- struct ieee80211_device* ieee = priv->ieee80211;
- struct ieee80211_network* net = &ieee->current_network;
-
- if (ieee->pHTInfo->bCurrentHTSupport)
- HTUpdateSelfAndPeerSetting(ieee, net);
- ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
- // Joseph test for turbo mode with AP
- ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
- rtl8192_update_cap(dev, net->capability);
-}
-/*
-* background support to run QoS activate functionality
-*/
-int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
-
-void rtl8192_qos_activate(struct work_struct * work)
-{
- struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
- struct net_device *dev = priv->ieee80211->dev;
- struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
- u8 mode = priv->ieee80211->current_network.mode;
- //u32 size = sizeof(struct ieee80211_qos_parameters);
- u8 u1bAIFS;
- u32 u4bAcParam;
- int i;
-
- if (priv == NULL)
- return;
-
- mutex_lock(&priv->mutex);
-
- if(priv->ieee80211->state != IEEE80211_LINKED)
- goto success;
- RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
- /* It better set slot time at first */
- /* For we just support b/g mode at present, let the slot time at 9/20 selection */
- /* update the ac parameter to related registers */
- for(i = 0; i < QOS_QUEUE_NUM; i++) {
- //Mode G/A: slotTimeTimer = 9; Mode B: 20
- u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
- u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
- (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
- (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
- ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-
- write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
- //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4322);
- }
-
-success:
- mutex_unlock(&priv->mutex);
-}
-
-static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
- int active_network,
- struct ieee80211_network *network)
-{
- int ret = 0;
- u32 size = sizeof(struct ieee80211_qos_parameters);
-
- if(priv->ieee80211->state !=IEEE80211_LINKED)
- return ret;
-
- if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
- return ret;
-
- if (network->flags & NETWORK_HAS_QOS_MASK) {
- if (active_network &&
- (network->flags & NETWORK_HAS_QOS_PARAMETERS))
- network->qos_data.active = network->qos_data.supported;
-
- if ((network->qos_data.active == 1) && (active_network == 1) &&
- (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
- (network->qos_data.old_param_count !=
- network->qos_data.param_count)) {
- network->qos_data.old_param_count =
- network->qos_data.param_count;
- queue_work(priv->priv_wq, &priv->qos_activate);
- RT_TRACE (COMP_QOS, "QoS parameters change call "
- "qos_activate\n");
- }
- } else {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
- &def_qos_parameters, size);
-
- if ((network->qos_data.active == 1) && (active_network == 1)) {
- queue_work(priv->priv_wq, &priv->qos_activate);
- RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
- }
- network->qos_data.active = 0;
- network->qos_data.supported = 0;
- }
-
- return 0;
-}
-
-/* handle manage frame frame beacon and probe response */
-static int rtl8192_handle_beacon(struct net_device * dev,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- rtl8192_qos_handle_probe_response(priv,1,network);
- queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
-
- return 0;
-
-}
-
-/*
-* handling the beaconing responses. if we get different QoS setting
-* off the network from the associated setting, adjust the QoS
-* setting
-*/
-static int rtl8192_qos_association_resp(struct r8192_priv *priv,
- struct ieee80211_network *network)
-{
- int ret = 0;
- unsigned long flags;
- u32 size = sizeof(struct ieee80211_qos_parameters);
- int set_qos_param = 0;
-
- if ((priv == NULL) || (network == NULL))
- return ret;
-
- if(priv->ieee80211->state !=IEEE80211_LINKED)
- return ret;
-
- if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
- return ret;
-
- spin_lock_irqsave(&priv->ieee80211->lock, flags);
- if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
- &network->qos_data.parameters,\
- sizeof(struct ieee80211_qos_parameters));
- priv->ieee80211->current_network.qos_data.active = 1;
- {
- set_qos_param = 1;
- /* update qos parameter for current network */
- priv->ieee80211->current_network.qos_data.old_param_count = \
- priv->ieee80211->current_network.qos_data.param_count;
- priv->ieee80211->current_network.qos_data.param_count = \
- network->qos_data.param_count;
- }
- } else {
- memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
- &def_qos_parameters, size);
- priv->ieee80211->current_network.qos_data.active = 0;
- priv->ieee80211->current_network.qos_data.supported = 0;
- set_qos_param = 1;
- }
-
- spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
-
- RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
- if (set_qos_param == 1)
- queue_work(priv->priv_wq, &priv->qos_activate);
-
- return ret;
-}
-
-
-static int rtl8192_handle_assoc_response(struct net_device *dev,
- struct ieee80211_assoc_response_frame *resp,
- struct ieee80211_network *network)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- rtl8192_qos_association_resp(priv, network);
- return 0;
-}
-
-
-void rtl8192_update_ratr_table(struct net_device* dev)
- // POCTET_STRING posLegacyRate,
- // u8* pMcsRate)
- // PRT_WLAN_STA pEntry)
-{
- struct r8192_priv* priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- u8* pMcsRate = ieee->dot11HTOperationalRateSet;
- //struct ieee80211_network *net = &ieee->current_network;
- u32 ratr_value = 0;
- u8 rate_index = 0;
- rtl8192_config_rate(dev, (u16*)(&ratr_value));
- ratr_value |= (*(u16*)(pMcsRate)) << 12;
-// switch (net->mode)
- switch (ieee->mode)
- {
- case IEEE_A:
- ratr_value &= 0x00000FF0;
- break;
- case IEEE_B:
- ratr_value &= 0x0000000F;
- break;
- case IEEE_G:
- ratr_value &= 0x00000FF7;
- break;
- case IEEE_N_24G:
- case IEEE_N_5G:
- if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
- ratr_value &= 0x0007F007;
- else{
- if (priv->rf_type == RF_1T2R)
- ratr_value &= 0x000FF007;
- else
- ratr_value &= 0x0F81F007;
- }
- break;
- default:
- break;
- }
- ratr_value &= 0x0FFFFFFF;
- if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
- ratr_value |= 0x80000000;
- }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
- ratr_value |= 0x80000000;
- }
- write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
- write_nic_byte(dev, UFWP, 1);
-}
-
-static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
-static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
-bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
-{
-#if 1
- struct r8192_priv* priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- struct ieee80211_network * network = &ieee->current_network;
- int wpa_ie_len= ieee->wpa_ie_len;
- struct ieee80211_crypt_data* crypt;
- int encrypt;
- return TRUE;
-
- crypt = ieee->crypt[ieee->tx_keyidx];
- //we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
- encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
-
- /* simply judge */
- if(encrypt && (wpa_ie_len == 0)) {
- /* wep encryption, no N mode setting */
- return false;
-// } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
- } else if((wpa_ie_len != 0)) {
- /* parse pairwise key type */
- //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
- if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
- return true;
- else
- return false;
- } else {
- return true;
- }
-
- return true;
-#endif
-}
-
-bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
-{
- bool Reval;
- struct r8192_priv* priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
-
-// Added by Roger, 2008.08.29.
- return false;
-
- if(ieee->bHalfWirelessN24GMode == true)
- Reval = true;
- else
- Reval = false;
-
- return Reval;
-}
-
-void rtl8192_refresh_supportrate(struct r8192_priv* priv)
-{
- struct ieee80211_device* ieee = priv->ieee80211;
- //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
- if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
- {
- memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
- //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
- //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
- }
- else
- memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
- return;
-}
-
-u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 ret = 0;
- switch(priv->rf_chip)
- {
- case RF_8225:
- case RF_8256:
- case RF_PSEUDO_11N:
- case RF_6052:
- ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
- break;
- case RF_8258:
- ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
- break;
- default:
- ret = WIRELESS_MODE_B;
- break;
- }
- return ret;
-}
-void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
-
-#if 1
- if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
- {
- if(bSupportMode & WIRELESS_MODE_N_24G)
- {
- wireless_mode = WIRELESS_MODE_N_24G;
- }
- else if(bSupportMode & WIRELESS_MODE_N_5G)
- {
- wireless_mode = WIRELESS_MODE_N_5G;
- }
- else if((bSupportMode & WIRELESS_MODE_A))
- {
- wireless_mode = WIRELESS_MODE_A;
- }
- else if((bSupportMode & WIRELESS_MODE_G))
- {
- wireless_mode = WIRELESS_MODE_G;
- }
- else if((bSupportMode & WIRELESS_MODE_B))
- {
- wireless_mode = WIRELESS_MODE_B;
- }
- else{
- RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
- wireless_mode = WIRELESS_MODE_B;
- }
- }
-#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
- ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
-#endif
- //LZM 090306 usb crash here, mark it temp
- //write_nic_word(dev, SIFS_OFDM, 0x0e0e);
- priv->ieee80211->mode = wireless_mode;
-
- if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G))
- priv->ieee80211->pHTInfo->bEnableHT = 1;
- else
- priv->ieee80211->pHTInfo->bEnableHT = 0;
- RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
- rtl8192_refresh_supportrate(priv);
-#endif
-
-}
-
-
-short rtl8192_is_tx_queue_empty(struct net_device *dev)
-{
- int i=0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- //struct ieee80211_device* ieee = priv->ieee80211;
- for (i=0; i<=MGNT_QUEUE; i++)
- {
- if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
- continue;
- if (atomic_read(&priv->tx_pending[i]))
- {
- printk("===>tx queue is not empty:%d, %d\n", i, atomic_read(&priv->tx_pending[i]));
- return 0;
- }
- }
- return 1;
-}
-
-void rtl8192_hw_sleep_down(struct net_device *dev)
-{
- RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
-#ifdef TODO
-// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
-#endif
-}
-
-void rtl8192_hw_sleep_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
- struct net_device *dev = ieee->dev;
-
- //printk("=========>%s()\n", __FUNCTION__);
- rtl8192_hw_sleep_down(dev);
-}
-// printk("dev is %d\n",dev);
-// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
-void rtl8192_hw_wakeup(struct net_device* dev)
-{
-// u32 flags = 0;
-
-// spin_lock_irqsave(&priv->ps_lock,flags);
- RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
-#ifdef TODO
-// MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
-#endif
- //FIXME: will we send package stored while nic is sleep?
-// spin_unlock_irqrestore(&priv->ps_lock,flags);
-}
-
-void rtl8192_hw_wakeup_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8192_hw_wakeup(dev);
-}
-
-#define MIN_SLEEP_TIME 50
-#define MAX_SLEEP_TIME 10000
-void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- u32 rb = jiffies;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->ps_lock,flags);
-
- /* Writing HW register with 0 equals to disable
- * the timer, that is not really what we want
- */
- tl -= MSECS(4+16+7);
-
- //if(tl == 0) tl = 1;
-
- /* FIXME HACK FIXME HACK */
-// force_pci_posting(dev);
- //mdelay(1);
-
-// rb = read_nic_dword(dev, TSFTR);
-
- /* If the interval in witch we are requested to sleep is too
- * short then give up and remain awake
- */
- if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
- ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
- spin_unlock_irqrestore(&priv->ps_lock,flags);
- printk("too short to sleep\n");
- return;
- }
-
-// write_nic_dword(dev, TimerInt, tl);
-// rb = read_nic_dword(dev, TSFTR);
- {
- u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
- // if (tl<rb)
-
- queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
- }
- /* if we suspect the TimerInt is gone beyond tl
- * while setting it, then give up
- */
-#if 1
- if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
- ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
- printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
- spin_unlock_irqrestore(&priv->ps_lock,flags);
- return;
- }
-#endif
-// if(priv->rf_sleep)
-// priv->rf_sleep(dev);
-
- //printk("<=========%s()\n", __FUNCTION__);
- queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
-
- spin_unlock_irqrestore(&priv->ps_lock,flags);
-}
-//init priv variables here. only non_zero value should be initialized here.
-static void rtl8192_init_priv_variable(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 i;
- priv->card_8192 = NIC_8192U;
- priv->chan = 1; //set to channel 1
- priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
- priv->ieee80211->iw_mode = IW_MODE_INFRA;
- priv->ieee80211->ieee_up=0;
- priv->retry_rts = DEFAULT_RETRY_RTS;
- priv->retry_data = DEFAULT_RETRY_DATA;
- priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
- priv->ieee80211->rate = 110; //11 mbps
- priv->ieee80211->short_slot = 1;
- priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
- priv->CckPwEnl = 6;
- //for silent reset
- priv->IrpPendingCount = 1;
- priv->ResetProgress = RESET_TYPE_NORESET;
- priv->bForcedSilentReset = 0;
- priv->bDisableNormalResetCheck = false;
- priv->force_reset = false;
-
- priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
- priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
- priv->ieee80211->iw_mode = IW_MODE_INFRA;
- priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
- IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
- IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
- IEEE_SOFTMAC_BEACONS;//added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE;
-
- priv->ieee80211->active_scan = 1;
- priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
- priv->ieee80211->host_encrypt = 1;
- priv->ieee80211->host_decrypt = 1;
- priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
- priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
- priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
- priv->ieee80211->set_chan = rtl8192_set_chan;
- priv->ieee80211->link_change = priv->ops->rtl819x_link_change;
- priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
- priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
- priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
- priv->ieee80211->init_wmmparam_flag = 0;
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
- priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
- priv->ieee80211->qos_support = 1;
-
- //added by WB
-// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
- priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
- priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
- priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
- //for LPS
- priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
-// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
- priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
- priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
- //added by david
- priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
- priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
- priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
- //added by amy
- priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
- priv->card_type = USB;
-
-//1 RTL8192SU/
- priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
- priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
- priv->bRFSiOrPi = 0;//o=si,1=pi;
- //lzm add
- priv->bInHctTest = false;
-
- priv->MidHighPwrTHR_L1 = 0x3B;
- priv->MidHighPwrTHR_L2 = 0x40;
-
- if(priv->bInHctTest)
- {
- priv->ShortRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
- priv->LongRetryLimit = HAL_RETRY_LIMIT_AP_ADHOC;
- }
- else
- {
- priv->ShortRetryLimit = HAL_RETRY_LIMIT_INFRA;
- priv->LongRetryLimit = HAL_RETRY_LIMIT_INFRA;
- }
-
- priv->SetFwCmdInProgress = false; //is set FW CMD in Progress? 92S only
- priv->CurrentFwCmdIO = 0;
-
- priv->MinSpaceCfg = 0;
-
- priv->EarlyRxThreshold = 7;
- priv->enable_gpio0 = 0;
- priv->TransmitConfig =
- ((u32)TCR_MXDMA_2048<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
- (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
- (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
- (false ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
- if(priv->bInHctTest)
- priv->ReceiveConfig = //priv->CSMethod |
- RCR_AMF | RCR_ADF | //RCR_AAP | //accept management/data
- RCR_ACF |RCR_APPFCS| //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
- RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
- RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
- RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
- ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
- (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
- (priv->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
- else
- priv->ReceiveConfig = //priv->CSMethod |
- RCR_AMF | RCR_ADF | RCR_AB |
- RCR_AM | RCR_APM |RCR_AAP |RCR_ADD3|RCR_APP_ICV|
- RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF | // Accept PHY status
- RCR_APP_MIC | RCR_APPFCS;
-
- // <Roger_EXP> 2008.06.16.
- priv->IntrMask = (u16)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | \
- IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | \
- IMR_BDOK | IMR_RXCMDOK | /*IMR_TIMEOUT0 |*/ IMR_RDU | IMR_RXFOVW | \
- IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
-
-//1 End
-
-
- priv->AcmControl = 0;
- priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
- if (priv->pFirmware)
- memset(priv->pFirmware, 0, sizeof(rt_firmware));
-
- /* rx related queue */
- skb_queue_head_init(&priv->rx_queue);
- skb_queue_head_init(&priv->skb_queue);
-
- /* Tx related queue */
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
- }
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
- }
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
- }
- priv->rf_set_chan = rtl8192_phy_SwChnl;
-}
-
-//init lock here
-static void rtl8192_init_priv_lock(struct r8192_priv* priv)
-{
- spin_lock_init(&priv->tx_lock);
- spin_lock_init(&priv->irq_lock);//added by thomas
- //spin_lock_init(&priv->rf_lock);//use rf_sem, or will crash in some OS.
- sema_init(&priv->wx_sem,1);
- sema_init(&priv->rf_sem,1);
- spin_lock_init(&priv->ps_lock);
- mutex_init(&priv->mutex);
-}
-
-extern void rtl819x_watchdog_wqcallback(struct work_struct *work);
-
-void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
-//init tasklet and wait_queue here. only 2.6 above kernel is considered
-#define DRV_NAME "wlan0"
-static void rtl8192_init_priv_task(struct net_device* dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-#ifdef PF_SYNCTHREAD
- priv->priv_wq = create_workqueue(DRV_NAME,0);
-#else
- priv->priv_wq = create_workqueue(DRV_NAME);
-#endif
-
- INIT_WORK(&priv->reset_wq, rtl8192_restart);
-
- //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
- INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
- INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback);
-// INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
- INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback);
- INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
- INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
- //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem);
- //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem);
- INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
-
- tasklet_init(&priv->irq_rx_tasklet,
- (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
- (unsigned long)priv);
-}
-
-//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
-static inline u16 endian_swap(u16* data)
-{
- u16 tmp = *data;
- *data = (tmp >> 8) | (tmp << 8);
- return *data;
-}
-
-u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
-{
- u8 nEndPoint = 0;
- switch(UsbOption)
- {
- case 0:
- nEndPoint = 6;
- break;
- case 1:
- nEndPoint = 11;
- break;
- case 2:
- nEndPoint = 4;
- break;
- default:
- RT_TRACE(COMP_INIT, "UsbOptionToEndPointNumber(): Invalid UsbOption(%#x)\n", UsbOption);
- break;
- }
- return nEndPoint;
-}
-
-u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
-{
- u8 RFtype = RF_1T2R;
-
- switch(Boardtype)
- {
- case 0:
- RFtype = RF_1T1R;
- break;
- case 1:
- RFtype = RF_1T2R;
- break;
- case 2:
- RFtype = RF_2T2R;
- break;
- case 3:
- RFtype = RF_2T2R_GREEN;
- break;
- default:
- break;
- }
-
- return RFtype;
-}
-
-void update_hal_variables(struct r8192_priv *priv)
-{
- int rf_path;
- int i;
- u8 index;
-
- for (rf_path = 0; rf_path < 2; rf_path++) {
- for (i = 0; i < 3; i++) {
- RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
- RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
- RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
- }
- /* Assign dedicated channel tx power */
- for(i = 0; i < 14; i++) {
- /* channel 1-3 use the same Tx Power Level. */
- if (i < 3) /* Channel 1-3 */
- index = 0;
- else if (i < 9) /* Channel 4-9 */
- index = 1;
- else /* Channel 10-14 */
- index = 2;
- /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
- priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
- priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
- priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
- if (rf_path == 0) {
- priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
- priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
- }
- }
- for(i = 0; i < 14; i++) {
- RT_TRACE((COMP_INIT),
- "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
- rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
- priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
- priv->RfTxPwrLevelOfdm2T[rf_path][i] );
- }
- }
-}
-
-/*
- * Description:
- * Config HW adapter information into initial value.
- *
- * Assumption:
- * 1. After Auto load fail(i.e, check CR9346 fail)
- *
- */
-void rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 rf_path; /* For EEPROM/EFUSE After V0.6_1117 */
- int i;
-
- RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
-
- /* Isolation signals from Loader */
- write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8);
- mdelay(10);
- write_nic_byte(dev, PMC_FSM, 0x02); /* Enable Loader Data Keep */
-
- /* Initialize IC Version && Channel Plan */
- priv->eeprom_vid = 0;
- priv->eeprom_pid = 0;
- priv->card_8192_version = 0;
- priv->eeprom_ChannelPlan = 0;
- priv->eeprom_CustomerID = 0;
- priv->eeprom_SubCustomerID = 0;
- priv->bIgnoreDiffRateTxPowerOffset = false;
-
- RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
- RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
- RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n",
- priv->eeprom_CustomerID);
- RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n",
- priv->eeprom_SubCustomerID);
- RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n",
- priv->eeprom_ChannelPlan);
- RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n",
- priv->bIgnoreDiffRateTxPowerOffset);
-
- priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
- RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
-
- for(i=0; i<5; i++)
- priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
-
- {
- /*
- * In this case, we randomly assign a MAC address here.
- */
- static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = sMacAddr[i];
- }
- /* NicIFSetMacAddress(Adapter, Adapter->PermanentAddress); */
- write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
- write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
-
- RT_TRACE(COMP_INIT,
- "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
- dev->dev_addr);
-
- priv->EEPROMBoardType = EEPROM_Default_BoardType;
- priv->rf_type = RF_1T2R; /* RF_2T2R */
- priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
- priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
- priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
- priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
- priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
- priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
- priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
-
- for (rf_path = 0; rf_path < 2; rf_path++)
- {
- for (i = 0; i < 3; i++)
- {
- /* Read CCK RF A & B Tx power */
- priv->RfCckChnlAreaTxPwr[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
- priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
- (u8)(EEPROM_Default_TxPower & 0xff);
- }
- }
-
- update_hal_variables(priv);
-
- /*
- * Update remaining HAL variables.
- */
- priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
- priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff; /* new */
- priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
- /* Antenna B gain offset to antenna A, bit0~3 */
- /* priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf); */
- /* Antenna C gain offset to antenna A, bit4~7 */
- /* priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4); */
- /* CrystalCap, bit12~15 */
- priv->CrystalCap = priv->EEPROMCrystalCap;
- /* ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 */
- priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
- priv->LedStrategy = SW_LED_MODE0;
-
- init_rate_adaptive(dev);
-
- RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n");
-}
-
-/*
- * Description:
- * Read HW adapter information by E-Fuse
- * or EEPROM according CR9346 reported.
- *
- * Assumption:
- * 1. CR9346 regiser has verified.
- * 2. PASSIVE_LEVEL (USB interface)
- */
-void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 i;
- u8 tmpU1b, tempval;
- u16 EEPROMId;
- u8 hwinfo[HWSET_MAX_SIZE_92S];
- u8 rf_path, index; /* For EEPROM/EFUSE After V0.6_1117 */
- struct eeprom_93cx6 eeprom;
- u16 eeprom_val;
-
- eeprom.data = dev;
- eeprom.register_read = rtl819x_eeprom_register_read;
- eeprom.register_write = rtl819x_eeprom_register_write;
- eeprom.width = PCI_EEPROM_WIDTH_93C46;
-
- /*
- * The following operation are prevent Efuse leakage by turn on 2.5V.
- */
- tmpU1b = read_nic_byte(dev, EFUSE_TEST+3);
- write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80);
- mdelay(10);
- write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7)));
-
- /* Retrieve Chip version. */
- priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
- RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
-
- switch (priv->card_8192_version) {
- case 0:
- RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n");
- break;
- case 1:
- RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n");
- break;
- case 2:
- RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n");
- break;
- default:
- RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n");
- priv->card_8192_version = VERSION_8192S_BCUT;
- break;
- }
-
- if (priv->EepromOrEfuse) { /* Read from EEPROM */
- /* Isolation signals from Loader */
- write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8);
- mdelay(10);
- /* Enable Loader Data Keep */
- write_nic_byte(dev, PMC_FSM, 0x02);
- /* Read all Content from EEPROM or EFUSE. */
- for (i = 0; i < HWSET_MAX_SIZE_92S; i += 2) {
- eeprom_93cx6_read(&eeprom, (u16) (i>>1), &eeprom_val);
- *((u16 *)(&hwinfo[i])) = eeprom_val;
- }
- } else if (!(priv->EepromOrEfuse)) { /* Read from EFUSE */
- /* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate(dev);
- memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
- } else {
- RT_TRACE(COMP_INIT, "%s(): Invalid boot type", __func__);
- }
-
- /*
- * Even though CR9346 regiser can verify whether Autoload
- * is success or not, but we still double check ID codes for 92S here
- * (e.g., due to HW GPIO polling fail issue)
- */
- EEPROMId = *((u16 *)&hwinfo[0]);
- if (EEPROMId != RTL8190_EEPROM_ID) {
- RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId);
- priv->bTXPowerDataReadFromEEPORM = FALSE;
- priv->AutoloadFailFlag=TRUE;
- } else {
- priv->AutoloadFailFlag=FALSE;
- priv->bTXPowerDataReadFromEEPORM = TRUE;
- }
- /* Read IC Version && Channel Plan */
- if (!priv->AutoloadFailFlag) {
- /* VID, PID */
- priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
- priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID];
- priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test
-
-
- /* EEPROM Version ID, Channel plan */
- priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version];
- priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan];
-
- /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
- priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID];
- priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID];
- } else {
- rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
- return;
- }
-
- RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
- RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
- RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
- RT_TRACE(COMP_INIT, "EEPROM Version ID: 0x%2x\n", priv->EEPROMVersion);
- RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
- RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
- RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
- RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset);
-
- /* Read USB optional function. */
- if (!priv->AutoloadFailFlag) {
- priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL];
- } else {
- priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
- }
-
- priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3);
-
- RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
- RT_TRACE(COMP_INIT, "EndPoint Number = %#x\n", priv->EEPROMUsbEndPointNumber);
-
-#ifdef TO_DO_LIST
- //
- // Decide CustomerID according to VID/DID or EEPROM
- //
- switch(pHalData->EEPROMCustomerID)
- {
- case EEPROM_CID_ALPHA:
- pMgntInfo->CustomerID = RT_CID_819x_ALPHA;
- break;
-
- case EEPROM_CID_CAMEO:
- pMgntInfo->CustomerID = RT_CID_819x_CAMEO;
- break;
-
- case EEPROM_CID_SITECOM:
- pMgntInfo->CustomerID = RT_CID_819x_Sitecom;
- RT_TRACE(COMP_INIT, DBG_LOUD, ("CustomerID = 0x%4x\n", pMgntInfo->CustomerID));
-
- break;
-
- case EEPROM_CID_WHQL:
- Adapter->bInHctTest = TRUE;
-
- pMgntInfo->bSupportTurboMode = FALSE;
- pMgntInfo->bAutoTurboBy8186 = FALSE;
-
- pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
- pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
- pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
- pMgntInfo->keepAliveLevel = 0;
- break;
-
- default:
- pMgntInfo->CustomerID = RT_CID_DEFAULT;
- break;
-
- }
-
- //
- // Led mode
- //
- switch(pMgntInfo->CustomerID)
- {
- case RT_CID_DEFAULT:
- case RT_CID_819x_ALPHA:
- pHalData->LedStrategy = SW_LED_MODE1;
- pHalData->bRegUseLed = TRUE;
- pHalData->SwLed1.bLedOn = TRUE;
- break;
- case RT_CID_819x_CAMEO:
- pHalData->LedStrategy = SW_LED_MODE1;
- pHalData->bRegUseLed = TRUE;
- break;
-
- case RT_CID_819x_Sitecom:
- pHalData->LedStrategy = SW_LED_MODE2;
- pHalData->bRegUseLed = TRUE;
- break;
-
- default:
- pHalData->LedStrategy = SW_LED_MODE0;
- break;
- }
-#endif
-
- // Read USB PHY parameters.
- for(i=0; i<5; i++)
- priv->EEPROMUsbPhyParam[i] = *(u8 *)&hwinfo[EEPROM_USB_PHY_PARA1+i];
-
- //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("USB PHY Param: \n"), pHalData->EEPROMUsbPhyParam, 5);
-
-
- //Read Permanent MAC address
- for(i=0; i<6; i++)
- dev->dev_addr[i] = *(u8 *)&hwinfo[EEPROM_NODE_ADDRESS_BYTE_0+i];
-
- //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
- write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
- write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
-
- RT_TRACE(COMP_INIT,
- "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
- dev->dev_addr);
-
- //
- // Get CustomerID(Boad Type)
- // i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
- // Others: Reserved. Default is 0x2: RTL8192SU.
- //
- //if(!priv->AutoloadFailFlag)
- //{
- priv->EEPROMBoardType = *(u8 *)&hwinfo[EEPROM_BoardType];
- priv->rf_type = rtl8192SU_BoardTypeToRFtype(dev, priv->EEPROMBoardType);
- //}
- //else
- //{
- // priv->EEPROMBoardType = EEPROM_Default_BoardType;
- // priv->rf_type = RF_1T2R;
- //}
-
- priv->rf_chip = RF_6052;
-
- priv->rf_chip = RF_6052;//lzm test
- RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
- RT_TRACE(COMP_INIT, "RF_Type = 0x%2x\n", priv->rf_type);
-
- //
- // Read antenna tx power offset of B/C/D to A from EEPROM
- // and read ThermalMeter from EEPROM
- //
- //if(!priv->AutoloadFailFlag)
- {
- priv->EEPROMTxPowerDiff = *(u8 *)&hwinfo[EEPROM_PwDiff];
- priv->EEPROMThermalMeter = *(u8 *)&hwinfo[EEPROM_ThermalMeter];
- }
- //else
- //{
- // priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff;
- // priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
- //}
-
- RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMTxPowerDiff);
- RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
-
- //
- // Read Tx Power gain offset of legacy OFDM to HT rate.
- // Read CrystalCap from EEPROM
- //
- //if(!priv->AutoloadFailFlag)
- {
- priv->EEPROMCrystalCap = *(u8 *)&hwinfo[EEPROM_CrystalCap];
- }
- //else
- //{
- // priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
- //}
-
- RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
-
- //
- // Get Tx Power Base.
- //
- //if(!priv->AutoloadFailFlag)
- {
- priv->EEPROMTxPwrBase = *(u8 *)&hwinfo[EEPROM_TxPowerBase];
- }
- //else
- //{
- // priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
- //}
-
- RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
-
-
- //
- // Get TSSI value for each path.
- //
- //if(!priv->AutoloadFailFlag)
- {
- priv->EEPROMTSSI_A = *(u8 *)&hwinfo[EEPROM_TSSI_A];
- priv->EEPROMTSSI_B = *(u8 *)&hwinfo[EEPROM_TSSI_B];
- }
- //else
- //{ // Default setting for Empty EEPROM
- // priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
- // priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
- //}
-
- RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
-
- //
- // Get Tx Power tracking mode.
- //
- //if(!priv->AutoloadFailFlag)
- {
- priv->EEPROMTxPwrTkMode = *(u8 *)&hwinfo[EEPROM_TxPwTkMode];
- }
-
- RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
-
-
- {
- //
- // Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
- // Update CCK, OFDM (1T/2T)Tx Power Index from above buffer.
- //
-
- //
- // Get Tx Power Level by Channel
- //
- //if(!priv->AutoloadFailFlag)
- {
- // Read Tx power of Channel 1 ~ 14 from EFUSE.
- // 92S suupport RF A & B
- for (rf_path = 0; rf_path < 2; rf_path++)
- {
- for (i = 0; i < 3; i++)
- {
- // Read CCK RF A & B Tx power
- priv->RfCckChnlAreaTxPwr[rf_path][i] =
- hwinfo[EEPROM_TxPwIndex+rf_path*3+i];
-
- // Read OFDM RF A & B Tx power for 1T
- priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] =
- hwinfo[EEPROM_TxPwIndex+6+rf_path*3+i];
-
- // Read OFDM RF A & B Tx power for 2T
- priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] =
- hwinfo[EEPROM_TxPwIndex+12+rf_path*3+i];
- }
- }
-
- }
- update_hal_variables(priv);
- }
-
- //
- // 2009/02/09 Cosa add for new EEPROM format
- //
- for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
- {
- // Read tx power difference between HT OFDM 20/40 MHZ
- if (i < 3) // Cjanel 1-3
- index = 0;
- else if (i < 9) // Channel 4-9
- index = 1;
- else // Channel 10-14
- index = 2;
-
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF+index])&0xff;
- priv->TxPwrHt20Diff[RF90_PATH_A][i] = (tempval&0xF);
- priv->TxPwrHt20Diff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
-
- // Read OFDM<->HT tx power diff
- if (i < 3) // Cjanel 1-3
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF])&0xff;
- else if (i < 9) // Channel 4-9
- tempval = (*(u8 *)&hwinfo[EEPROM_PwDiff])&0xff;
- else // Channel 10-14
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+1])&0xff;
-
- //cosa tempval = (*(u1Byte *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF+index])&0xff;
- priv->TxPwrLegacyHtDiff[RF90_PATH_A][i] = (tempval&0xF);
- priv->TxPwrLegacyHtDiff[RF90_PATH_B][i] = ((tempval>>4)&0xF);
-
- //
- // Read Band Edge tx power offset and check if user enable the ability
- //
- // HT 40 band edge channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE])&0xff;
- priv->TxPwrbandEdgeHt40[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeHt40[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+1])&0xff;
- priv->TxPwrbandEdgeHt40[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeHt40[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
- // HT 20 band edge channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+2])&0xff;
- priv->TxPwrbandEdgeHt20[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeHt20[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+3])&0xff;
- priv->TxPwrbandEdgeHt20[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeHt20[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
- // OFDM band edge channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+4])&0xff;
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1] = ((tempval>>4)&0xF); // Band edge high channel
- tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_BAND_EDGE+5])&0xff;
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0] = (tempval&0xF); // Band edge low channel
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1] = ((tempval>>4)&0xF); // Band edge high channel
-
- priv->TxPwrbandEdgeFlag = (*(u8 *)&hwinfo[TX_PWR_BAND_EDGE_CHK]);
- }
-
- for(i=0; i<14; i++)
- RT_TRACE(COMP_INIT, "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_A][i]);
- for(i=0; i<14; i++)
- RT_TRACE(COMP_INIT, "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_A][i]);
- for(i=0; i<14; i++)
- RT_TRACE(COMP_INIT, "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrHt20Diff[RF90_PATH_B][i]);
- for(i=0; i<14; i++)
- RT_TRACE(COMP_INIT, "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, priv->TxPwrLegacyHtDiff[RF90_PATH_B][i]);
- RT_TRACE(COMP_INIT, "RF-A HT40 band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeHt40[RF90_PATH_A][0],
- priv->TxPwrbandEdgeHt40[RF90_PATH_A][1]);
- RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT40 band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeHt40[RF90_PATH_B][0],
- priv->TxPwrbandEdgeHt40[RF90_PATH_B][1]);
-
- RT_TRACE((COMP_INIT&COMP_DBG), "RF-A HT20 band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeHt20[RF90_PATH_A][0],
- priv->TxPwrbandEdgeHt20[RF90_PATH_A][1]);
- RT_TRACE((COMP_INIT&COMP_DBG), "RF-B HT20 band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeHt20[RF90_PATH_B][0],
- priv->TxPwrbandEdgeHt20[RF90_PATH_B][1]);
-
- RT_TRACE((COMP_INIT&COMP_DBG), "RF-A OFDM band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0],
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][1]);
- RT_TRACE((COMP_INIT&COMP_DBG), "RF-B OFDM band-edge low/high power diff = 0x%x/0x%x\n",
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
- priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
- RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
-
- //
- // Update remained HAL variables.
- //
- priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
- priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;
- priv->TxPowerDiff = priv->EEPROMTxPowerDiff;
- //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit[3:0]
- //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit[7:4]
- priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit[15:12]
- priv->ThermalMeter[0] = (priv->EEPROMThermalMeter&0x1f);// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
- priv->LedStrategy = SW_LED_MODE0;
-
- init_rate_adaptive(dev);
-
- RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
-
- //return RT_STATUS_SUCCESS;
-}
-
-
-//
-// Description:
-// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
-//
-// Assumption:
-// 1. CR9346 regiser has verified.
-// 2. PASSIVE_LEVEL (USB interface)
-//
-// Created by Roger, 2008.10.21.
-//
-static void rtl8192SU_read_eeprom_info(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 tmpU1b;
-
- RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n");
-
- // Retrieve Chip version.
- priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF);
- RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version);
-
- tmpU1b = read_nic_byte(dev, EPROM_CMD);//CR9346
-
- // To check system boot selection.
- if (tmpU1b & CmdEERPOMSEL)
- {
- RT_TRACE(COMP_INIT, "Boot from EEPROM\n");
- priv->EepromOrEfuse = TRUE;
- }
- else
- {
- RT_TRACE(COMP_INIT, "Boot from EFUSE\n");
- priv->EepromOrEfuse = FALSE;
- }
-
- // To check autoload success or not.
- if (tmpU1b & CmdEEPROM_En)
- {
- RT_TRACE(COMP_INIT, "Autoload OK!!\n");
- priv->AutoloadFailFlag=FALSE;
- rtl8192SU_ReadAdapterInfo8192SUsb(dev);//eeprom or e-fuse
- }
- else
- { // Auto load fail.
- RT_TRACE(COMP_INIT, "AutoLoad Fail reported from CR9346!!\n");
- priv->AutoloadFailFlag=TRUE;
- rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev);
-
- //if (IS_BOOT_FROM_EFUSE(Adapter))
- if(!priv->EepromOrEfuse)
- {
- RT_TRACE(COMP_INIT, "Update shadow map for EFuse future use!!\n");
- EFUSE_ShadowMapUpdate(dev);
- }
- }
-#ifdef TO_DO_LIST
- if((priv->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
- {
- pMgntInfo->ChannelPlan = HalMapChannelPlan8192S(Adapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
- pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? TRUE : FALSE; // User cannot change channel plan.
- }
- else
- {
- pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
- }
-
- switch(pMgntInfo->ChannelPlan)
- {
- case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
- {
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
-
- pDot11dInfo->bEnabled = TRUE;
- }
- RT_TRACE(COMP_INIT, DBG_LOUD, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
- break;
- }
-
- RT_TRACE(COMP_INIT, DBG_LOUD, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
- RT_TRACE(COMP_INIT, DBG_LOUD, ("ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
-
- RT_TRACE(COMP_INIT, DBG_LOUD, ("<==== ReadAdapterInfo8192S\n"));
-#endif
-
- RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SUsb\n");
-
- //return RT_STATUS_SUCCESS;
-}
-
-short rtl8192_get_channel_map(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
- printk("rtl8180_init:Error channel plan! Set to default.\n");
- priv->ChannelPlan= 0;
- }
- RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
-
- rtl819x_set_channel_map(priv->ChannelPlan, priv);
- return 0;
-}
-
-short rtl8192_init(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- rtl8192_init_priv_variable(dev);
- rtl8192_init_priv_lock(priv);
- rtl8192_init_priv_task(dev);
- priv->ops->rtl819x_read_eeprom_info(dev);
- rtl8192_get_channel_map(dev);
- init_hal_dm(dev);
- init_timer(&priv->watch_dog_timer);
- priv->watch_dog_timer.data = (unsigned long)dev;
- priv->watch_dog_timer.function = watch_dog_timer_callback;
- return 0;
-}
-
-/******************************************************************************
- *function: This function actually only set RRSR, RATR and BW_OPMODE registers
- * not to do all the hw config as its name says
- * input: net_device dev
- * output: none
- * return: none
- * notice: This part need to modified according to the rate set we filtered
- * ****************************************************************************/
-void rtl8192_hwconfig(struct net_device* dev)
-{
- u32 regRATR = 0, regRRSR = 0;
- u8 regBwOpMode = 0, regTmp = 0;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-// Set RRSR, RATR, and BW_OPMODE registers
- //
- switch(priv->ieee80211->mode)
- {
- case WIRELESS_MODE_B:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK;
- regRRSR = RATE_ALL_CCK;
- break;
- case WIRELESS_MODE_A:
- regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_G:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_AUTO:
-#ifdef TO_DO_LIST
- if (Adapter->bInHctTest)
- {
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- }
- else
-#endif
- {
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- }
- break;
- case WIRELESS_MODE_N_24G:
- // It support CCK rate by default.
- // CCK rate will be filtered out only when associated AP does not support it.
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_N_5G:
- regBwOpMode = BW_OPMODE_5G;
- regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_OFDM_AG;
- break;
- }
-
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
- {
- u32 ratr_value = 0;
- ratr_value = regRATR;
- if (priv->rf_type == RF_1T2R)
- {
- ratr_value &= ~(RATE_ALL_OFDM_2SS);
- }
- write_nic_dword(dev, RATR0, ratr_value);
- write_nic_byte(dev, UFWP, 1);
- }
- regTmp = read_nic_byte(dev, 0x313);
- regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
- write_nic_dword(dev, RRSR, regRRSR);
-
- //
- // Set Retry Limit here
- //
- write_nic_word(dev, RETRY_LIMIT,
- priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
- priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
- // Set Contention Window here
-
- // Set Tx AGC
-
- // Set Tx Antenna including Feedback control
-
- // Set Auto Rate fallback control
-
-
-}
-
-
-//
-// Description:
-// Initial HW relted registers.
-//
-// Assumption:
-// Config RTL8192S USB MAC, we should config MAC before download FW.
-//
-// 2008.09.03, Added by Roger.
-//
-static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
-{
- u8 tmpU1b;// i;
-// u16 tmpU2b;
-// u32 tmpU4b;
- u8 PollingCnt = 20;
-
- RT_TRACE(COMP_INIT, "--->MacConfigBeforeFwDownloadASIC()\n");
-
- //2MAC Initialization for power on sequence, Revised by Roger. 2008.09.03.
-
- //
- //<Roger_Notes> Set control path switch to HW control and reset Digital Core, CPU Core and
- // MAC I/O to solve FW download fail when system from resume sate.
- // 2008.11.04.
- //
- tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
- if(tmpU1b & 0x80)
- {
- tmpU1b &= 0x3f;
- write_nic_byte(dev, SYS_CLKR+1, tmpU1b);
- }
- // Clear FW RPWM for FW control LPS. by tynli. 2009.02.23
- write_nic_byte(dev, RPWM, 0x0);
-
- tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
- tmpU1b &= 0x73;
- write_nic_byte(dev, SYS_FUNC_EN+1, tmpU1b);
- udelay(1000);
-
- //Revised POS, suggested by SD1 Alex, 2008.09.27.
- write_nic_byte(dev, SPS0_CTRL+1, 0x53);
- write_nic_byte(dev, SPS0_CTRL, 0x57);
-
- //Enable AFE Macro Block's Bandgap adn Enable AFE Macro Block's Mbias
- tmpU1b = read_nic_byte(dev, AFE_MISC);
- write_nic_byte(dev, AFE_MISC, (tmpU1b|AFE_BGEN|AFE_MBEN));
-
- //Enable PLL Power (LDOA15V)
- tmpU1b = read_nic_byte(dev, LDOA15_CTRL);
- write_nic_byte(dev, LDOA15_CTRL, (tmpU1b|LDA15_EN));
-
- //Enable LDOV12D block
- tmpU1b = read_nic_byte(dev, LDOV12D_CTRL);
- write_nic_byte(dev, LDOV12D_CTRL, (tmpU1b|LDV12_EN));
-
- //mpU1b = read_nic_byte(Adapter, SPS1_CTRL);
- //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_LDEN));
-
- //PlatformSleepUs(2000);
-
- //Enable Switch Regulator Block
- //tmpU1b = read_nic_byte(Adapter, SPS1_CTRL);
- //write_nic_byte(dev, SPS1_CTRL, (tmpU1b|SPS1_SWEN));
-
- //write_nic_dword(Adapter, SPS1_CTRL, 0x00a7b267);
-
- tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
- write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b|0x08));
-
- //Engineer Packet CP test Enable
- tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
- write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x20));
-
- //Support 64k IMEM, suggested by SD1 Alex.
- tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL+1);
- write_nic_byte(dev, SYS_ISO_CTRL+1, (tmpU1b& 0x68));
-
- //Enable AFE clock
- tmpU1b = read_nic_byte(dev, AFE_XTAL_CTRL+1);
- write_nic_byte(dev, AFE_XTAL_CTRL+1, (tmpU1b& 0xfb));
-
- //Enable AFE PLL Macro Block
- tmpU1b = read_nic_byte(dev, AFE_PLL_CTRL);
- write_nic_byte(dev, AFE_PLL_CTRL, (tmpU1b|0x11));
-
- //Attatch AFE PLL to MACTOP/BB/PCIe Digital
- tmpU1b = read_nic_byte(dev, SYS_ISO_CTRL);
- write_nic_byte(dev, SYS_ISO_CTRL, (tmpU1b&0xEE));
-
- // Switch to 40M clock
- write_nic_byte(dev, SYS_CLKR, 0x00);
-
- //SSC Disable
- tmpU1b = read_nic_byte(dev, SYS_CLKR);
- //write_nic_byte(dev, SYS_CLKR, (tmpU1b&0x5f));
- write_nic_byte(dev, SYS_CLKR, (tmpU1b|0xa0));
-
- //Enable MAC clock
- tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
- write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x18));
-
- //Revised POS, suggested by SD1 Alex, 2008.09.27.
- write_nic_byte(dev, PMC_FSM, 0x02);
-
- //Enable Core digital and enable IOREG R/W
- tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
- write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x08));
-
- //Enable REG_EN
- tmpU1b = read_nic_byte(dev, SYS_FUNC_EN+1);
- write_nic_byte(dev, SYS_FUNC_EN+1, (tmpU1b|0x80));
-
- //Switch the control path to FW
- tmpU1b = read_nic_byte(dev, SYS_CLKR+1);
- write_nic_byte(dev, SYS_CLKR+1, (tmpU1b|0x80)& 0xBF);
-
- write_nic_byte(dev, CMDR, 0xFC);
- write_nic_byte(dev, CMDR+1, 0x37);
-
- //Fix the RX FIFO issue(usb error), 970410
- tmpU1b = read_nic_byte_E(dev, 0x5c);
- write_nic_byte_E(dev, 0x5c, (tmpU1b|BIT7));
-
- //For power save, used this in the bit file after 970621
- tmpU1b = read_nic_byte(dev, SYS_CLKR);
- write_nic_byte(dev, SYS_CLKR, tmpU1b&(~SYS_CPU_CLKSEL));
-
- // Revised for 8051 ROM code wrong operation. Added by Roger. 2008.10.16.
- write_nic_byte_E(dev, 0x1c, 0x80);
-
- //
- // <Roger_EXP> To make sure that TxDMA can ready to download FW.
- // We should reset TxDMA if IMEM RPT was not ready.
- // Suggested by SD1 Alex. 2008.10.23.
- //
- do
- {
- tmpU1b = read_nic_byte(dev, TCR);
- if((tmpU1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
- break;
- //PlatformStallExecution(5);
- udelay(5);
- }while(PollingCnt--); // Delay 1ms
-
- if(PollingCnt <= 0 )
- {
- RT_TRACE(COMP_INIT, "MacConfigBeforeFwDownloadASIC(): Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", tmpU1b);
- tmpU1b = read_nic_byte(dev, CMDR);
- write_nic_byte(dev, CMDR, tmpU1b&(~TXDMA_EN));
- udelay(2);
- write_nic_byte(dev, CMDR, tmpU1b|TXDMA_EN);// Reset TxDMA
- }
-
-
- RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
-}
-
-//
-// Description:
-// Initial HW relted registers.
-//
-// Assumption:
-// 1. This function is only invoked at driver intialization once.
-// 2. PASSIVE LEVEL.
-//
-// 2008.06.10, Added by Roger.
-//
-static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
- //PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
- //u8 tmpU1b, RxPageCfg, i;
- u16 tmpU2b;
- u8 tmpU1b;//, i;
-
-
- RT_TRACE(COMP_INIT, "--->MacConfigAfterFwDownload()\n");
-
- // Enable Tx/Rx
- tmpU2b = (BBRSTn|BB_GLB_RSTn|SCHEDULE_EN|MACRXEN|MACTXEN|DDMA_EN|
- FW2HW_EN|RXDMA_EN|TXDMA_EN|HCI_RXDMA_EN|HCI_TXDMA_EN); //3
- //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_COMMAND, &tmpU1b );
- write_nic_word(dev, CMDR, tmpU2b); //LZM REGISTER COM 090305
-
- // Loopback mode or not
- priv->LoopbackMode = RTL8192SU_NO_LOOPBACK; // Set no loopback as default.
- if(priv->LoopbackMode == RTL8192SU_NO_LOOPBACK)
- tmpU1b = LBK_NORMAL;
- else if (priv->LoopbackMode == RTL8192SU_MAC_LOOPBACK )
- tmpU1b = LBK_MAC_DLB;
- else
- RT_TRACE(COMP_INIT, "Serious error: wrong loopback mode setting\n");
-
- //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_LBK_MODE, &tmpU1b);
- write_nic_byte(dev, LBKMD_SEL, tmpU1b);
-
- // Set RCR
- write_nic_dword(dev, RCR, priv->ReceiveConfig);
- RT_TRACE(COMP_INIT, "MacConfigAfterFwDownload(): Current RCR settings(%#x)\n", priv->ReceiveConfig);
-
-
- // Set RQPN
- //
- // <Roger_Notes> 2008.08.18.
- // 6 endpoints:
- // (1) Page number on CMDQ is 0x03.
- // (2) Page number on BCNQ, HQ and MGTQ is 0.
- // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
- // (4) Page number on PUBQ is 0xdd
- //
- // 11 endpoints:
- // (1) Page number on CMDQ is 0x00.
- // (2) Page number on BCNQ is 0x02, HQ and MGTQ are 0x03.
- // (3) Page number on BKQ, BEQ, VIQ and VOQ are 0x07.
- // (4) Page number on PUBQ is 0xd8
- //
- //write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
- //write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
-
- // Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
- tmpU1b = read_nic_byte_E(dev, 0x5C);
- write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
-
- // For EFUSE init configuration.
- //if (IS_BOOT_FROM_EFUSE(Adapter)) // We may R/W EFUSE in EFUSE mode
- if (priv->bBootFromEfuse)
- {
- u8 tempval;
-
- tempval = read_nic_byte(dev, SYS_ISO_CTRL+1);
- tempval &= 0xFE;
- write_nic_byte(dev, SYS_ISO_CTRL+1, tempval);
-
- // Enable LDO 2.5V for write action
- //tempval = read_nic_byte(Adapter, EFUSE_TEST+3);
- //write_nic_byte(Adapter, EFUSE_TEST+3, (tempval | 0x80));
-
- // Change Efuse Clock for write action
- //write_nic_byte(Adapter, EFUSE_CLK, 0x03);
-
- // Change Program timing
- write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
- //printk("!!!!!!!!!!!!!!!!!!!!!%s: write 0x33 with 0x72\n",__FUNCTION__);
- RT_TRACE(COMP_INIT, "EFUSE CONFIG OK\n");
- }
-
-
- RT_TRACE(COMP_INIT, "<---MacConfigAfterFwDownload()\n");
-}
-
-void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 regBwOpMode = 0;
- u32 regRATR = 0, regRRSR = 0;
- u8 regTmp = 0;
- u32 i = 0;
-
- //1 This part need to modified according to the rate set we filtered!!
- //
- // Set RRSR, RATR, and BW_OPMODE registers
- //
- switch(priv->ieee80211->mode)
- {
- case WIRELESS_MODE_B:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK;
- regRRSR = RATE_ALL_CCK;
- break;
- case WIRELESS_MODE_A:
- regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_G:
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_AUTO:
- if (priv->bInHctTest)
- {
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- }
- else
- {
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- }
- break;
- case WIRELESS_MODE_N_24G:
- // It support CCK rate by default.
- // CCK rate will be filtered out only when associated AP does not support it.
- regBwOpMode = BW_OPMODE_20MHZ;
- regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
- break;
- case WIRELESS_MODE_N_5G:
- regBwOpMode = BW_OPMODE_5G;
- regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
- regRRSR = RATE_ALL_OFDM_AG;
- break;
- }
-
- //
- // <Roger_Notes> We disable CCK response rate until FIB CCK rate IC's back.
- // 2008.09.23.
- //
- regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
- regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
-
- //
- // Update SIFS timing.
- //
- //priv->SifsTime = 0x0e0e0a0a;
- //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SIFS, (pu1Byte)&pHalData->SifsTime);
- { u8 val[4] = {0x0e, 0x0e, 0x0a, 0x0a};
- // SIFS for CCK Data ACK
- write_nic_byte(dev, SIFS_CCK, val[0]);
- // SIFS for CCK consecutive tx like CTS data!
- write_nic_byte(dev, SIFS_CCK+1, val[1]);
-
- // SIFS for OFDM Data ACK
- write_nic_byte(dev, SIFS_OFDM, val[2]);
- // SIFS for OFDM consecutive tx like CTS data!
- write_nic_byte(dev, SIFS_OFDM+1, val[3]);
- }
-
- write_nic_dword(dev, INIRTSMCS_SEL, regRRSR);
- write_nic_byte(dev, BW_OPMODE, regBwOpMode);
-
- //
- // Suggested by SD1 Alex, 2008-06-14.
- //
- //PlatformEFIOWrite1Byte(Adapter, TXOP_STALL_CTRL, 0x80);//NAV to protect all TXOP.
-
- //
- // Set Data Auto Rate Fallback Retry Count register.
- //
- write_nic_dword(dev, DARFRC, 0x02010000);
- write_nic_dword(dev, DARFRC+4, 0x06050403);
- write_nic_dword(dev, RARFRC, 0x02010000);
- write_nic_dword(dev, RARFRC+4, 0x06050403);
-
- // Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
- for (i = 0; i < 8; i++)
- write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
-
- //
- // Aggregation length limit. Revised by Roger. 2008.09.22.
- //
- write_nic_byte(dev, AGGLEN_LMT_H, 0x0f); // Set AMPDU length to 12Kbytes for ShortGI case.
- write_nic_dword(dev, AGGLEN_LMT_L, 0xddd77442); // Long GI
- write_nic_dword(dev, AGGLEN_LMT_L+4, 0xfffdd772);
-
- // Set NAV protection length
- write_nic_word(dev, NAV_PROT_LEN, 0x0080);
-
- // Set TXOP stall control for several queue/HI/BCN/MGT/
- write_nic_byte(dev, TXOP_STALL_CTRL, 0x00); // NAV Protect next packet.
-
- // Set MSDU lifetime.
- write_nic_byte(dev, MLT, 0x8f);
-
- // Set CCK/OFDM SIFS
- write_nic_word(dev, SIFS_CCK, 0x0a0a); // CCK SIFS shall always be 10us.
- write_nic_word(dev, SIFS_OFDM, 0x0e0e);
-
- write_nic_byte(dev, ACK_TIMEOUT, 0x40);
-
- // CF-END Threshold
- write_nic_byte(dev, CFEND_TH, 0xFF);
-
- //
- // For Min Spacing configuration.
- //
- switch(priv->rf_type)
- {
- case RF_1T2R:
- case RF_1T1R:
- RT_TRACE(COMP_INIT, "Initializeadapter: RF_Type%s\n", (priv->rf_type==RF_1T1R? "(1T1R)":"(1T2R)"));
- priv->MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3);
- break;
- case RF_2T2R:
- case RF_2T2R_GREEN:
- RT_TRACE(COMP_INIT, "Initializeadapter:RF_Type(2T2R)\n");
- priv->MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3);
- break;
- }
- write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
-
- //LZM 090219
- //
- // For Min Spacing configuration.
- //
- //priv->MinSpaceCfg = 0x00;
- //rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
-}
-
-
-// Description: Initial HW relted registers.
-//
-// Assumption: This function is only invoked at driver intialization once.
-//
-// 2008.06.10, Added by Roger.
-bool rtl8192SU_adapter_start(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //u32 dwRegRead = 0;
- //bool init_status = true;
- //u32 ulRegRead;
- bool rtStatus = true;
- //u8 PipeIndex;
- //u8 eRFPath, tmpU1b;
- u8 fw_download_times = 1;
-
-
- RT_TRACE(COMP_INIT, "--->InitializeAdapter8192SUsb()\n");
-
- //pHalData->bGPIOChangeRF = FALSE;
-
-
- //
- // <Roger_Notes> 2008.06.15.
- //
- // Initialization Steps on RTL8192SU:
- // a. MAC initialization prior to sending down firmware code.
- // b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
- // c. MAC configuration after firmware has been download successfully.
- // d. Initialize BB related configurations.
- // e. Initialize RF related configurations.
- // f. Start to BulkIn transfer.
- //
-
- //
- //a. MAC initialization prior to send down firmware code.
- //
-start:
- rtl8192SU_MacConfigBeforeFwDownloadASIC(dev);
-
- //
- //b. Download firmware code step by step(i.e., IMEM, EMEM, DMEM).
- //
- rtStatus = FirmwareDownload92S(dev);
- if(rtStatus != true)
- {
- if(fw_download_times == 1){
- RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed once, Download again!!\n");
- fw_download_times = fw_download_times + 1;
- goto start;
- }else{
- RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Download Firmware failed twice, end!!\n");
- goto end;
- }
- }
- //
- //c. MAC configuration after firmware has been download successfully.
- //
- rtl8192SU_MacConfigAfterFwDownload(dev);
-
- //priv->bLbusEnable = TRUE;
- //if(priv->RegRfOff == TRUE)
- // priv->eRFPowerState = eRfOff;
-
- // Save target channel
- // <Roger_Notes> Current Channel will be updated again later.
- //priv->CurrentChannel = Channel;
- rtStatus = PHY_MACConfig8192S(dev);//===>ok
- if(rtStatus != true)
- {
- RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure MAC!!\n");
- goto end;
- }
- if (1){
- int i;
- for (i=0; i<4; i++)
- write_nic_dword(dev,WDCAPARA_ADD[i], 0x5e4322);
- write_nic_byte(dev,AcmHwCtrl, 0x01);
- }
-
-
- //
- //d. Initialize BB related configurations.
- //
-
- rtStatus = PHY_BBConfig8192S(dev);//===>ok
- if(rtStatus != true)
- {
- RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure BB!!\n");
- goto end;
- }
-
- rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);//===>ok
-
- //
- // e. Initialize RF related configurations.
- //
- // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
- priv->Rf_Mode = RF_OP_By_SW_3wire;
-
- // For RF test only from Scott's suggestion
- //write_nic_byte(dev, 0x27, 0xDB);
- //write_nic_byte(dev, 0x1B, 0x07);
-
-
- write_nic_byte(dev, AFE_XTAL_CTRL+1, 0xDB);
-
- // <Roger_Notes> The following IOs are configured for each RF modules.
- // Enable RF module and reset RF and SDM module. 2008.11.17.
- if(priv->card_8192_version == VERSION_8192S_ACUT)
- write_nic_byte(dev, SPS1_CTRL+3, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB)); // Fix A-Cut bug.
- else
- write_nic_byte(dev, RF_CTRL, (u8)(RF_EN|RF_RSTB|RF_SDMRSTB));
-
- rtStatus = PHY_RFConfig8192S(dev);//===>ok
- if(rtStatus != true)
- {
- RT_TRACE(COMP_INIT, "InitializeAdapter8192SUsb(): Fail to configure RF!!\n");
- goto end;
- }
-
-
- // Set CCK and OFDM Block "ON"
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
-
- //
- // Turn off Radio B while RF type is 1T1R by SD3 Wilsion's request.
- // Revised by Roger, 2008.12.18.
- //
- if(priv->rf_type == RF_1T1R)
- {
- // This is needed for PHY_REG after 20081219
- rtl8192_setBBreg(dev, rFPGA0_RFMOD, 0xff000000, 0x03);
- // This is needed for PHY_REG before 20081219
- //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
- }
-
-
- //LZM 090219
- // Set CCK and OFDM Block "ON"
- //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
- //rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
-
-
- //3//Get hardware version, do it in read eeprom?
- //GetHardwareVersion819xUsb(Adapter);
-
- //3//
- //3 //Set Hardware
- //3//
- rtl8192SU_HwConfigureRTL8192SUsb(dev);//==>ok
-
- //
- // <Roger_Notes> We set MAC address here if autoload was failed before,
- // otherwise IDR0 will NOT contain any value.
- //
- write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
- write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
- if(!priv->bInHctTest)
- {
- if(priv->ResetProgress == RESET_TYPE_NORESET)
- {
- //RT_TRACE(COMP_MLME, DBG_LOUD, ("Initializeadapter8192SUsb():RegWirelessMode(%#x) \n", Adapter->RegWirelessMode));
- //Adapter->HalFunc.SetWirelessModeHandler(Adapter, Adapter->RegWirelessMode);
- rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);//===>ok
- }
- }
- else
- {
- priv->ieee80211->mode = WIRELESS_MODE_G;
- rtl8192_SetWirelessMode(dev, WIRELESS_MODE_G);
- }
-
- //Security related.
- //-----------------------------------------------------------------------------
- // Set up security related. 070106, by rcnjko:
- // 1. Clear all H/W keys.
- // 2. Enable H/W encryption/decryption.
- //-----------------------------------------------------------------------------
- //CamResetAllEntry(Adapter);
- //Adapter->HalFunc.EnableHWSecCfgHandler(Adapter);
-
- //SecClearAllKeys(Adapter);
- CamResetAllEntry(dev);
- //SecInit(Adapter);
- {
- u8 SECR_value = 0x0;
- SECR_value |= SCR_TxEncEnable;
- SECR_value |= SCR_RxDecEnable;
- SECR_value |= SCR_NoSKMC;
- write_nic_byte(dev, SECR, SECR_value);
- }
-
-#ifdef TO_DO_LIST
-
- //PHY_UpdateInitialGain(dev);
-
- if(priv->RegRfOff == true)
- { // User disable RF via registry.
- u8 eRFPath = 0;
-
- RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RegRfOff ----------\n");
- MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
- // Those action will be discard in MgntActSet_RF_State because off the same state
- for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
- rtl8192_setBBreg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
- }
- else if(priv->RfOffReason > RF_CHANGE_BY_PS)
- { // H/W or S/W RF OFF before sleep.
- RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): Turn off RF for RfOffReason(%d) ----------\n", priv->RfOffReason);
- MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason);
- }
- else
- {
- priv->eRFPowerState = eRfOn;
- priv->RfOffReason = 0;
- RT_TRACE((COMP_INIT|COMP_RF), "InitializeAdapter8192SUsb(): RF is on ----------\n");
- }
-
-#endif
-
-
-//
-// f. Start to BulkIn transfer.
-//
-#ifdef TO_DO_LIST
-
-#ifndef UNDER_VISTA
- {
- u8 i;
- PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
-
- for(PipeIndex=0; PipeIndex < MAX_RX_QUEUE; PipeIndex++)
- {
- if (PipeIndex == 0)
- {
- for(i=0; i<32; i++)
- HalUsbInMpdu(Adapter, PipeIndex);
- }
- else
- {
- //HalUsbInMpdu(Adapter, PipeIndex);
- //HalUsbInMpdu(Adapter, PipeIndex);
- //HalUsbInMpdu(Adapter, PipeIndex);
- }
- }
- PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
- }
-#else
- // Joseph add to 819X code base for Vista USB platform.
- // This part may need to be add to Hal819xU code base. too.
- PlatformUsbEnableInPipes(Adapter);
-#endif
-
- RT_TRACE(COMP_INIT, "HighestOperaRate = %x\n", Adapter->MgntInfo.HighestOperaRate);
-
- PlatformStartWorkItem( &(pHalData->RtUsbCheckForHangWorkItem) );
-
- //
- // <Roger_EXP> The following configurations are for ASIC verification temporally.
- // 2008.07.10.
- //
-
-#endif
-
- //
- // Read EEPROM TX power index and PHY_REG_PG.txt to capture correct
- // TX power index for different rate set.
- //
- //if(priv->card_8192_version >= VERSION_8192S_ACUT)
- {
- // Get original hw reg values
- PHY_GetHWRegOriginalValue(dev);
-
- // Write correct tx power index//FIXLZM
- PHY_SetTxPowerLevel8192S(dev, priv->chan);
- }
-
- {
- u8 tmpU1b = 0;
- // EEPROM R/W workaround
- tmpU1b = read_nic_byte(dev, MAC_PINMUX_CFG);
- write_nic_byte(dev, MAC_PINMUX_CFG, tmpU1b&(~GPIOMUX_EN));
- }
-
-//
-//<Roger_Notes> 2008.08.19.
-// We return status here for temporal FPGA verification, 2008.08.19.
-
-#ifdef RTL8192SU_FW_IQK
- write_nic_dword(dev, WFM5, FW_IQK_ENABLE);
- ChkFwCmdIoDone(dev);
-#endif
-
- //
- // <Roger_Notes> We enable high power mechanism after NIC initialized.
- // 2008.11.27.
- //
- write_nic_dword(dev, WFM5, FW_RA_RESET);
- ChkFwCmdIoDone(dev);
- write_nic_dword(dev, WFM5, FW_RA_ACTIVE);
- ChkFwCmdIoDone(dev);
- write_nic_dword(dev, WFM5, FW_RA_REFRESH);
- ChkFwCmdIoDone(dev);
- write_nic_dword(dev, WFM5, FW_BB_RESET_ENABLE);
-
-// <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
-//
-
-end:
-return rtStatus;
-}
-
-/***************************************************************************
- -------------------------------NET STUFF---------------------------
-***************************************************************************/
-
-static struct net_device_stats *rtl8192_stats(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- return &priv->ieee80211->stats;
-}
-
-bool
-HalTxCheckStuck819xUsb(
- struct net_device *dev
- )
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 RegTxCounter = read_nic_word(dev, 0x128);
- bool bStuck = FALSE;
- RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
- if(priv->TxCounter==RegTxCounter)
- bStuck = TRUE;
-
- priv->TxCounter = RegTxCounter;
-
- return bStuck;
-}
-
-/*
-* <Assumption: RT_TX_SPINLOCK is acquired.>
-* First added: 2006.11.19 by emily
-*/
-RESET_TYPE
-TxCheckStuck(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 QueueID;
-// PRT_TCB pTcb;
-// u8 ResetThreshold;
- bool bCheckFwTxCnt = false;
- //unsigned long flags;
-
- //
- // Decide Stuch threshold according to current power save mode
- //
-
-// RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
-// PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
-// spin_lock_irqsave(&priv->ieee80211->lock,flags);
- for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
- {
- if(QueueID == TXCMD_QUEUE)
- continue;
-#if 1
- if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
- continue;
-#endif
-
- bCheckFwTxCnt = true;
- }
-// PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
-// spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
-// RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
-#if 1
- if(bCheckFwTxCnt)
- {
- if(HalTxCheckStuck819xUsb(dev))
- {
- RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
- return RESET_TYPE_SILENT;
- }
- }
-#endif
- return RESET_TYPE_NORESET;
-}
-
-bool
-HalRxCheckStuck819xUsb(struct net_device *dev)
-{
- u16 RegRxCounter = read_nic_word(dev, 0x130);
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bStuck = FALSE;
-//#ifdef RTL8192SU
-
-//#else
- static u8 rx_chk_cnt = 0;
- RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
- // If rssi is small, we should check rx for long time because of bad rx.
- // or maybe it will continuous silent reset every 2 seconds.
- rx_chk_cnt++;
- if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
- {
- rx_chk_cnt = 0; //high rssi, check rx stuck right now.
- }
- else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
- ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
- (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
- {
- if(rx_chk_cnt < 2)
- {
- return bStuck;
- }
- else
- {
- rx_chk_cnt = 0;
- }
- }
- else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
- (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
- priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
- {
- if(rx_chk_cnt < 4)
- {
- //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
- return bStuck;
- }
- else
- {
- rx_chk_cnt = 0;
- //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
- }
- }
- else
- {
- if(rx_chk_cnt < 8)
- {
- //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
- return bStuck;
- }
- else
- {
- rx_chk_cnt = 0;
- //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
- }
- }
-//#endif
-
- if(priv->RxCounter==RegRxCounter)
- bStuck = TRUE;
-
- priv->RxCounter = RegRxCounter;
-
- return bStuck;
-}
-
-RESET_TYPE
-RxCheckStuck(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //int i;
- bool bRxCheck = FALSE;
-
-// RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
- //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
-
- if(priv->IrpPendingCount > 1)
- bRxCheck = TRUE;
- //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
-
-// RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
- if(bRxCheck)
- {
- if(HalRxCheckStuck819xUsb(dev))
- {
- RT_TRACE(COMP_RESET, "RxStuck Condition\n");
- return RESET_TYPE_SILENT;
- }
- }
- return RESET_TYPE_NORESET;
-}
-
-
-/**
-* This function is called by Checkforhang to check whether we should ask OS to reset driver
-*
-* \param pAdapter The adapter context for this miniport
-*
-* Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
-* to judge whether there is tx stuck.
-* Note: This function may be required to be rewrite for Vista OS.
-* <<<Assumption: Tx spinlock has been acquired >>>
-*
-* 8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
-*/
-RESET_TYPE
-rtl819x_ifcheck_resetornot(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- RESET_TYPE TxResetType = RESET_TYPE_NORESET;
- RESET_TYPE RxResetType = RESET_TYPE_NORESET;
- RT_RF_POWER_STATE rfState;
-
- return RESET_TYPE_NORESET;
-
- rfState = priv->ieee80211->eRFPowerState;
-
- TxResetType = TxCheckStuck(dev);
-#if 1
- if( rfState != eRfOff ||
- /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
- (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
- {
- // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
- // in turned off state. Driver should check whether Rx stuck and do silent reset. And
- // if driver is in firmware download failure status, driver should initialize RF in the following
- // silent reset procedure Emily, 2008.01.21
-
- // Driver should not check RX stuck in IBSS mode because it is required to
- // set Check BSSID in order to send beacon, however, if check BSSID is
- // set, STA cannot hear any packet a all. Emily, 2008.04.12
- RxResetType = RxCheckStuck(dev);
- }
-#endif
- if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
- return RESET_TYPE_NORMAL;
- else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
- RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
- return RESET_TYPE_SILENT;
- }
- else
- return RESET_TYPE_NORESET;
-
-}
-
-void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
-int _rtl8192_up(struct net_device *dev);
-int rtl8192_close(struct net_device *dev);
-
-
-
-void
-CamRestoreAllEntry( struct net_device *dev)
-{
- u8 EntryId = 0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8* MacAddr = priv->ieee80211->current_network.bssid;
-
- static u8 CAM_CONST_ADDR[4][6] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
- static u8 CAM_CONST_BROAD[] =
- {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
-
-
- if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
- (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
- {
-
- for(EntryId=0; EntryId<4; EntryId++)
- {
- {
- MacAddr = CAM_CONST_ADDR[EntryId];
- setKey(dev,
- EntryId ,
- EntryId,
- priv->ieee80211->pairwise_key_type,
- MacAddr,
- 0,
- NULL);
- }
- }
-
- }
- else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
- {
-
- {
- if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- setKey(dev,
- 4,
- 0,
- priv->ieee80211->pairwise_key_type,
- (u8*)dev->dev_addr,
- 0,
- NULL);
- else
- setKey(dev,
- 4,
- 0,
- priv->ieee80211->pairwise_key_type,
- MacAddr,
- 0,
- NULL);
- }
- }
- else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
- {
-
- {
- if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- setKey(dev,
- 4,
- 0,
- priv->ieee80211->pairwise_key_type,
- (u8*)dev->dev_addr,
- 0,
- NULL);
- else
- setKey(dev,
- 4,
- 0,
- priv->ieee80211->pairwise_key_type,
- MacAddr,
- 0,
- NULL);
- }
- }
-
-
-
- if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
- {
- MacAddr = CAM_CONST_BROAD;
- for(EntryId=1 ; EntryId<4 ; EntryId++)
- {
- {
- setKey(dev,
- EntryId,
- EntryId,
- priv->ieee80211->group_key_type,
- MacAddr,
- 0,
- NULL);
- }
- }
- if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- setKey(dev,
- 0,
- 0,
- priv->ieee80211->group_key_type,
- CAM_CONST_ADDR[0],
- 0,
- NULL);
- }
- else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
- {
- MacAddr = CAM_CONST_BROAD;
- for(EntryId=1; EntryId<4 ; EntryId++)
- {
- {
- setKey(dev,
- EntryId ,
- EntryId,
- priv->ieee80211->group_key_type,
- MacAddr,
- 0,
- NULL);
- }
- }
-
- if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- setKey(dev,
- 0 ,
- 0,
- priv->ieee80211->group_key_type,
- CAM_CONST_ADDR[0],
- 0,
- NULL);
- }
-}
-//////////////////////////////////////////////////////////////
-// This function is used to fix Tx/Rx stop bug temporarily.
-// This function will do "system reset" to NIC when Tx or Rx is stuck.
-// The method checking Tx/Rx stuck of this function is supported by FW,
-// which reports Tx and Rx counter to register 0x128 and 0x130.
-//////////////////////////////////////////////////////////////
-void
-rtl819x_ifsilentreset(struct net_device *dev)
-{
- //OCTET_STRING asocpdu;
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 reset_times = 0;
- int reset_status = 0;
- struct ieee80211_device *ieee = priv->ieee80211;
-
-
- // 2007.07.20. If we need to check CCK stop, please uncomment this line.
- //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
-
- if(priv->ResetProgress==RESET_TYPE_NORESET)
- {
-RESET_START:
-
- RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
-
- // Set the variable for reset.
- priv->ResetProgress = RESET_TYPE_SILENT;
-// rtl8192_close(dev);
-#if 1
- down(&priv->wx_sem);
- if(priv->up == 0)
- {
- RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
- up(&priv->wx_sem);
- return ;
- }
- priv->up = 0;
- RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
-// if(!netif_queue_stopped(dev))
-// netif_stop_queue(dev);
-
- rtl8192_rtx_disable(dev);
- rtl8192_cancel_deferred_work(priv);
- deinit_hal_dm(dev);
- del_timer_sync(&priv->watch_dog_timer);
-
- ieee->sync_scan_hurryup = 1;
- if(ieee->state == IEEE80211_LINKED)
- {
- down(&ieee->wx_sem);
- printk("ieee->state is IEEE80211_LINKED\n");
- ieee80211_stop_send_beacons(priv->ieee80211);
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
- ieee80211_stop_scan(ieee);
- netif_carrier_off(dev);
- up(&ieee->wx_sem);
- }
- else{
- printk("ieee->state is NOT LINKED\n");
- ieee80211_softmac_stop_protocol(priv->ieee80211); }
- up(&priv->wx_sem);
- RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
- //rtl8192_irq_disable(dev);
- RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
- reset_status = _rtl8192_up(dev);
-
- RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
- if(reset_status == -EAGAIN)
- {
- if(reset_times < 3)
- {
- reset_times++;
- goto RESET_START;
- }
- else
- {
- RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n", __FUNCTION__);
- }
- }
-#endif
- ieee->is_silent_reset = 1;
-#if 1
- EnableHWSecurityConfig8192(dev);
-#if 1
- if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
- {
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-#if 1
- queue_work(ieee->wq, &ieee->associate_complete_wq);
-#endif
-
- }
- else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
- {
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->link_change(ieee->dev);
-
- // notify_wx_assoc_event(ieee);
-
- ieee80211_start_send_beacons(ieee);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
- netif_carrier_on(ieee->dev);
- }
-#endif
-
- CamRestoreAllEntry(dev);
-
- priv->ResetProgress = RESET_TYPE_NORESET;
- priv->reset_count++;
-
- priv->bForcedSilentReset =false;
- priv->bResetInProgress = false;
-
- // For test --> force write UFWP.
- write_nic_byte(dev, UFWP, 1);
- RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
-#endif
- }
-}
-
-void CAM_read_entry(
- struct net_device *dev,
- u32 iIndex
-)
-{
- u32 target_command=0;
- u32 target_content=0;
- u8 entry_i=0;
- u32 ulStatus;
- s32 i=100;
-// printk("=======>start read CAM\n");
- for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
- {
- // polling bit, and No Write enable, and address
- target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
- target_command= target_command | BIT31;
-
- //Check polling bit is clear
-// mdelay(1);
-#if 1
- while((i--)>=0)
- {
- ulStatus = read_nic_dword(dev, RWCAM);
- if(ulStatus & BIT31){
- continue;
- }
- else{
- break;
- }
- }
-#endif
- write_nic_dword(dev, RWCAM, target_command);
- RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
- // printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
- target_content = read_nic_dword(dev, RCAMO);
- RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
- // printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
- }
- printk("\n");
-}
-
-void rtl819x_update_rxcounts(
- struct r8192_priv *priv,
- u32* TotalRxBcnNum,
- u32* TotalRxDataNum
-)
-{
- u16 SlotIndex;
- u8 i;
-
- *TotalRxBcnNum = 0;
- *TotalRxDataNum = 0;
-
- SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
- priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
- priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
- for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
- *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
- *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
- }
-}
-
-void rtl819x_watchdog_wqcallback(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work,
- struct delayed_work,
- work);
- struct r8192_priv *priv = container_of(dwork,
- struct r8192_priv,
- watch_dog_wq);
- struct net_device *dev = priv->ieee80211->dev;
- struct ieee80211_device* ieee = priv->ieee80211;
- RESET_TYPE ResetType = RESET_TYPE_NORESET;
- static u8 check_reset_cnt;
- u32 TotalRxBcnNum = 0;
- u32 TotalRxDataNum = 0;
- bool bBusyTraffic = false;
-
- if(!priv->up)
- return;
- hal_dm_watchdog(dev);
- /* to get busy traffic condition */
- if (ieee->state == IEEE80211_LINKED) {
- if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 ||
- ieee->LinkDetectInfo.NumTxOkInPeriod > 666)
- bBusyTraffic = true;
-
- ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
- ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
- ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
- }
-
- if (priv->ieee80211->state == IEEE80211_LINKED &&
- priv->ieee80211->iw_mode == IW_MODE_INFRA) {
- rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
- if ((TotalRxBcnNum + TotalRxDataNum) == 0) {
- RT_TRACE(COMP_ERR, "%s(): AP is powered off,"
- "connect another one\n", __func__);
- /* Dot11d_Reset(dev); */
- priv->ieee80211->state = IEEE80211_ASSOCIATING;
- notify_wx_assoc_event(priv->ieee80211);
- RemovePeerTS(priv->ieee80211,
- priv->ieee80211->current_network.bssid);
- ieee->is_roaming = true;
- priv->ieee80211->link_change(dev);
- if(ieee->LedControlHandler != NULL)
- ieee->LedControlHandler(ieee->dev,
- LED_CTL_START_TO_LINK);
- queue_work(priv->ieee80211->wq,
- &priv->ieee80211->associate_procedure_wq);
- }
- }
- priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0;
- priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0;
-
- /*
- * CAM_read_entry(dev,4);
- * check if reset the driver
- */
- if (check_reset_cnt++ >= 3 && !ieee->is_roaming) {
- ResetType = rtl819x_ifcheck_resetornot(dev);
- check_reset_cnt = 3;
- }
- if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
- (priv->bForcedSilentReset ||
- (!priv->bDisableNormalResetCheck &&
- /* This is control by OID set in Pomelo */
- ResetType == RESET_TYPE_SILENT)))) {
- RT_TRACE(COMP_RESET, "%s(): priv->force_reset is %d,"
- "priv->ResetProgress is %d, "
- "priv->bForcedSilentReset is %d, "
- "priv->bDisableNormalResetCheck is %d, "
- "ResetType is %d",
- __func__,
- priv->force_reset,
- priv->ResetProgress,
- priv->bForcedSilentReset,
- priv->bDisableNormalResetCheck,
- ResetType);
- rtl819x_ifsilentreset(dev);
- }
- priv->force_reset = false;
- priv->bForcedSilentReset = false;
- priv->bResetInProgress = false;
-}
-
-void watch_dog_timer_callback(unsigned long data)
-{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
- //printk("===============>watch_dog timer\n");
- queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
- mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
-}
-int _rtl8192_up(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //int i;
- int init_status = 0;
- priv->up=1;
- priv->ieee80211->ieee_up=1;
- RT_TRACE(COMP_INIT, "Bringing up iface");
- init_status = priv->ops->rtl819x_adapter_start(dev);
- if(!init_status)
- {
- RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
- priv->up=priv->ieee80211->ieee_up = 0;
- return -EAGAIN;
- }
- RT_TRACE(COMP_INIT, "start adapter finished\n");
- rtl8192_rx_enable(dev);
-// rtl8192_tx_enable(dev);
- if(priv->ieee80211->state != IEEE80211_LINKED)
- ieee80211_softmac_start_protocol(priv->ieee80211);
- ieee80211_reset_queue(priv->ieee80211);
- watch_dog_timer_callback((unsigned long) dev);
- if(!netif_queue_stopped(dev))
- netif_start_queue(dev);
- else
- netif_wake_queue(dev);
-
- /*
- * Make sure that drop_unencrypted is initialized as "0"
- * No packets will be sent in non-security mode if we had set drop_unencrypted.
- * ex, After kill wpa_supplicant process, make the driver up again.
- * drop_unencrypted remains as "1", which is set by wpa_supplicant. 2008/12/04.john
- */
- priv->ieee80211->drop_unencrypted = 0;
-
- return 0;
-}
-
-
-int rtl8192_open(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int ret;
- down(&priv->wx_sem);
- ret = rtl8192_up(dev);
- up(&priv->wx_sem);
- return ret;
-
-}
-
-
-int rtl8192_up(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 1) return -1;
-
- return _rtl8192_up(dev);
-}
-
-
-int rtl8192_close(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
-
- ret = rtl8192_down(dev);
-
- up(&priv->wx_sem);
-
- return ret;
-
-}
-
-int rtl8192_down(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int i;
-
- if (priv->up == 0) return -1;
-
- priv->up=0;
- priv->ieee80211->ieee_up = 0;
- RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
-/* FIXME */
- if (!netif_queue_stopped(dev))
- netif_stop_queue(dev);
-
- rtl8192_rtx_disable(dev);
- //rtl8192_irq_disable(dev);
-
- /* Tx related queue release */
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
- }
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
- }
-
- for(i = 0; i < MAX_QUEUE_SIZE; i++) {
- skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
- }
-
- //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
-// flush_scheduled_work();
- rtl8192_cancel_deferred_work(priv);
- deinit_hal_dm(dev);
- del_timer_sync(&priv->watch_dog_timer);
-
-
- ieee80211_softmac_stop_protocol(priv->ieee80211);
- memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
- RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
-
- return 0;
-}
-
-
-void rtl8192_commit(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int reset_status = 0;
- //u8 reset_times = 0;
- if (priv->up == 0) return ;
- priv->up = 0;
-
- rtl8192_cancel_deferred_work(priv);
- del_timer_sync(&priv->watch_dog_timer);
- //cancel_delayed_work(&priv->SwChnlWorkItem);
-
- ieee80211_softmac_stop_protocol(priv->ieee80211);
-
- //rtl8192_irq_disable(dev);
- rtl8192_rtx_disable(dev);
- reset_status = _rtl8192_up(dev);
-
-}
-
-/*
-void rtl8192_restart(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-*/
-void rtl8192_restart(struct work_struct *work)
-{
- struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
- struct net_device *dev = priv->ieee80211->dev;
-
- down(&priv->wx_sem);
-
- rtl8192_commit(dev);
-
- up(&priv->wx_sem);
-}
-
-static void r8192_set_multicast(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- short promisc;
-
- //down(&priv->wx_sem);
-
- /* FIXME FIXME */
-
- promisc = (dev->flags & IFF_PROMISC) ? 1:0;
-
- if (promisc != priv->promisc)
- // rtl8192_commit(dev);
-
- priv->promisc = promisc;
-
- //schedule_work(&priv->reset_wq);
- //up(&priv->wx_sem);
-}
-
-
-int r8192_set_mac_adr(struct net_device *dev, void *mac)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct sockaddr *addr = mac;
-
- down(&priv->wx_sem);
-
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-
- schedule_work(&priv->reset_wq);
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-/* based on ipw2200 driver */
-int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct iwreq *wrq = (struct iwreq *)rq;
- int ret=-1;
- struct ieee80211_device *ieee = priv->ieee80211;
- u32 key[4];
- u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
- u8 zero_addr[6] = {0};
- struct iw_point *p = &wrq->u.data;
- struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
-
- down(&priv->wx_sem);
-
-
- if (p->length < sizeof(struct ieee_param) || !p->pointer){
- ret = -EINVAL;
- goto out;
- }
-
- ipw = kmalloc(p->length, GFP_KERNEL);
- if (ipw == NULL){
- ret = -ENOMEM;
- goto out;
- }
- if (copy_from_user(ipw, p->pointer, p->length)) {
- kfree(ipw);
- ret = -EFAULT;
- goto out;
- }
-
- switch (cmd) {
- case RTL_IOCTL_WPA_SUPPLICANT:
- //parse here for HW security
- if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
- {
- if (ipw->u.crypt.set_tx)
- {
- if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
- ieee->pairwise_key_type = KEY_TYPE_CCMP;
- else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
- ieee->pairwise_key_type = KEY_TYPE_TKIP;
- else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
- {
- if (ipw->u.crypt.key_len == 13)
- ieee->pairwise_key_type = KEY_TYPE_WEP104;
- else if (ipw->u.crypt.key_len == 5)
- ieee->pairwise_key_type = KEY_TYPE_WEP40;
- }
- else
- ieee->pairwise_key_type = KEY_TYPE_NA;
-
- if (ieee->pairwise_key_type)
- {
- // FIXME:these two lines below just to fix ipw interface bug, that is, it will never set mode down to driver. So treat it as ADHOC mode, if no association procedure. WB. 2009.02.04
- if (memcmp(ieee->ap_mac_addr, zero_addr, 6) == 0)
- ieee->iw_mode = IW_MODE_ADHOC;
- memcpy((u8*)key, ipw->u.crypt.key, 16);
- EnableHWSecurityConfig8192(dev);
- //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
- //added by WB.
- setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
- if (ieee->iw_mode == IW_MODE_ADHOC)
- setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
- }
- }
- else //if (ipw->u.crypt.idx) //group key use idx > 0
- {
- memcpy((u8*)key, ipw->u.crypt.key, 16);
- if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
- ieee->group_key_type= KEY_TYPE_CCMP;
- else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
- ieee->group_key_type = KEY_TYPE_TKIP;
- else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
- {
- if (ipw->u.crypt.key_len == 13)
- ieee->group_key_type = KEY_TYPE_WEP104;
- else if (ipw->u.crypt.key_len == 5)
- ieee->group_key_type = KEY_TYPE_WEP40;
- }
- else
- ieee->group_key_type = KEY_TYPE_NA;
-
- if (ieee->group_key_type)
- {
- setKey( dev,
- ipw->u.crypt.idx,
- ipw->u.crypt.idx, //KeyIndex
- ieee->group_key_type, //KeyType
- broadcast_addr, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
- }
- }
- }
-#ifdef JOHN_HWSEC_DEBUG
- //john's test 0711
- printk("@@ wrq->u pointer = ");
- for(i=0;i<wrq->u.data.length;i++){
- if(i%10==0) printk("\n");
- printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
- }
- printk("\n");
-#endif /*JOHN_HWSEC_DEBUG*/
- ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
- break;
-
- default:
- ret = -EOPNOTSUPP;
- break;
- }
- kfree(ipw);
- ipw = NULL;
-out:
- up(&priv->wx_sem);
- return ret;
-}
-
-u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
-{
-
- u8 ret_rate = 0x02;
-
- if( bFirstAMPDU )
- {
- if(!bIsHT)
- {
- switch(rate)
- {
-
- case DESC92S_RATE1M: ret_rate = MGN_1M; break;
- case DESC92S_RATE2M: ret_rate = MGN_2M; break;
- case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
- case DESC92S_RATE11M: ret_rate = MGN_11M; break;
- case DESC92S_RATE6M: ret_rate = MGN_6M; break;
- case DESC92S_RATE9M: ret_rate = MGN_9M; break;
- case DESC92S_RATE12M: ret_rate = MGN_12M; break;
- case DESC92S_RATE18M: ret_rate = MGN_18M; break;
- case DESC92S_RATE24M: ret_rate = MGN_24M; break;
- case DESC92S_RATE36M: ret_rate = MGN_36M; break;
- case DESC92S_RATE48M: ret_rate = MGN_48M; break;
- case DESC92S_RATE54M: ret_rate = MGN_54M; break;
-
- default:
- RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
- break;
- }
- }
- else
- {
- switch(rate)
- {
-
- case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
- case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
- case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
- case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
- case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
- case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
- case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
- case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
- case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
- case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
- case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
- case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
- case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
- case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
- case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
- case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
- case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
-
- default:
- RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
- break;
- }
-
- }
- }
- else
- {
- switch(rate)
- {
-
- case DESC92S_RATE1M: ret_rate = MGN_1M; break;
- case DESC92S_RATE2M: ret_rate = MGN_2M; break;
- case DESC92S_RATE5_5M: ret_rate = MGN_5_5M; break;
- case DESC92S_RATE11M: ret_rate = MGN_11M; break;
- case DESC92S_RATE6M: ret_rate = MGN_6M; break;
- case DESC92S_RATE9M: ret_rate = MGN_9M; break;
- case DESC92S_RATE12M: ret_rate = MGN_12M; break;
- case DESC92S_RATE18M: ret_rate = MGN_18M; break;
- case DESC92S_RATE24M: ret_rate = MGN_24M; break;
- case DESC92S_RATE36M: ret_rate = MGN_36M; break;
- case DESC92S_RATE48M: ret_rate = MGN_48M; break;
- case DESC92S_RATE54M: ret_rate = MGN_54M; break;
- case DESC92S_RATEMCS0: ret_rate = MGN_MCS0; break;
- case DESC92S_RATEMCS1: ret_rate = MGN_MCS1; break;
- case DESC92S_RATEMCS2: ret_rate = MGN_MCS2; break;
- case DESC92S_RATEMCS3: ret_rate = MGN_MCS3; break;
- case DESC92S_RATEMCS4: ret_rate = MGN_MCS4; break;
- case DESC92S_RATEMCS5: ret_rate = MGN_MCS5; break;
- case DESC92S_RATEMCS6: ret_rate = MGN_MCS6; break;
- case DESC92S_RATEMCS7: ret_rate = MGN_MCS7; break;
- case DESC92S_RATEMCS8: ret_rate = MGN_MCS8; break;
- case DESC92S_RATEMCS9: ret_rate = MGN_MCS9; break;
- case DESC92S_RATEMCS10: ret_rate = MGN_MCS10; break;
- case DESC92S_RATEMCS11: ret_rate = MGN_MCS11; break;
- case DESC92S_RATEMCS12: ret_rate = MGN_MCS12; break;
- case DESC92S_RATEMCS13: ret_rate = MGN_MCS13; break;
- case DESC92S_RATEMCS14: ret_rate = MGN_MCS14; break;
- case DESC92S_RATEMCS15: ret_rate = MGN_MCS15; break;
- case DESC92S_RATEMCS32: ret_rate = (0x80|0x20); break;
-
- default:
- RT_TRACE(COMP_RECV, "HwRateToMRate92S(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT );
- break;
- }
- }
- return ret_rate;
-}
-
-u8 HwRateToMRate90(bool bIsHT, u8 rate)
-{
- u8 ret_rate = 0xff;
-
- if(!bIsHT) {
- switch(rate) {
- case DESC90_RATE1M: ret_rate = MGN_1M; break;
- case DESC90_RATE2M: ret_rate = MGN_2M; break;
- case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
- case DESC90_RATE11M: ret_rate = MGN_11M; break;
- case DESC90_RATE6M: ret_rate = MGN_6M; break;
- case DESC90_RATE9M: ret_rate = MGN_9M; break;
- case DESC90_RATE12M: ret_rate = MGN_12M; break;
- case DESC90_RATE18M: ret_rate = MGN_18M; break;
- case DESC90_RATE24M: ret_rate = MGN_24M; break;
- case DESC90_RATE36M: ret_rate = MGN_36M; break;
- case DESC90_RATE48M: ret_rate = MGN_48M; break;
- case DESC90_RATE54M: ret_rate = MGN_54M; break;
-
- default:
- ret_rate = 0xff;
- RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
- break;
- }
-
- } else {
- switch(rate) {
- case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
- case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
- case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
- case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
- case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
- case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
- case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
- case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
- case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
- case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
- case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
- case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
- case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
- case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
- case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
- case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
- case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
-
- default:
- ret_rate = 0xff;
- RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
- break;
- }
- }
-
- return ret_rate;
-}
-
-/**
- * Function: UpdateRxPktTimeStamp
- * Overview: Recored down the TSF time stamp when receiving a packet
- *
- * Input:
- * PADAPTER Adapter
- * PRT_RFD pRfd,
- *
- * Output:
- * PRT_RFD pRfd
- * (pRfd->Status.TimeStampHigh is updated)
- * (pRfd->Status.TimeStampLow is updated)
- * Return:
- * None
- */
-void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- if(stats->bIsAMPDU && !stats->bFirstMPDU) {
- stats->mac_time[0] = priv->LastRxDescTSFLow;
- stats->mac_time[1] = priv->LastRxDescTSFHigh;
- } else {
- priv->LastRxDescTSFLow = stats->mac_time[0];
- priv->LastRxDescTSFHigh = stats->mac_time[1];
- }
-}
-
-//by amy 080606
-
-long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index.
-{
- long signal_power; // in dBm.
-
- // Translate to dBm (x=0.5y-95).
- signal_power = (long)((signal_strength_index + 1) >> 1);
- signal_power -= 95;
-
- return signal_power;
-}
-
-
-/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
- be a local static. Otherwise, it may increase when we return from S3/S4. The
- value will be kept in memory or disk. We must delcare the value in adapter
- and it will be reinitialized when return from S3/S4. */
-void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
-{
- bool bcheck = false;
- u8 rfpath;
- u32 nspatial_stream, tmp_val;
- //u8 i;
- static u32 slide_rssi_index=0, slide_rssi_statistics=0;
- static u32 slide_evm_index=0, slide_evm_statistics=0;
- static u32 last_rssi=0, last_evm=0;
-
- static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
- static u32 last_beacon_adc_pwdb=0;
-
- struct ieee80211_hdr_3addr *hdr;
- u16 sc ;
- unsigned int frag,seq;
- hdr = (struct ieee80211_hdr_3addr *)buffer;
- sc = le16_to_cpu(hdr->seq_ctrl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- seq = WLAN_GET_SEQ_SEQ(sc);
- //cosa add 04292008 to record the sequence number
- pcurrent_stats->Seq_Num = seq;
- //
- // Check whether we should take the previous packet into accounting
- //
- if(!pprevious_stats->bIsAMPDU)
- {
- // if previous packet is not aggregated packet
- bcheck = true;
- }else
- {
- }
-
-
- if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
- {
- slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
- last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
- priv->stats.slide_rssi_total -= last_rssi;
- }
- priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
-
- priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
- if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
- slide_rssi_index = 0;
-
- // <1> Showed on UI for user, in dbm
- tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
- priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
- pcurrent_stats->rssi = priv->stats.signal_strength;
- //
- // If the previous packet does not match the criteria, neglect it
- //
- if(!pprevious_stats->bPacketMatchBSSID)
- {
- if(!pprevious_stats->bToSelfBA)
- return;
- }
-
- if(!bcheck)
- return;
-
-
- //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
-
- //
- // Check RSSI
- //
- priv->stats.num_process_phyinfo++;
-
- /* record the general signal strength to the sliding window. */
-
-
- // <2> Showed on UI for engineering
- // hardware does not provide rssi information for each rf path in CCK
- if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
- {
- for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
- {
- if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
- continue;
-
- //Fixed by Jacken 2008-03-20
- if(priv->stats.rx_rssi_percentage[rfpath] == 0)
- {
- priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
- //DbgPrint("MIMO RSSI initialize \n");
- }
- if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath])
- {
- priv->stats.rx_rssi_percentage[rfpath] =
- ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
- (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
- priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1;
- }
- else
- {
- priv->stats.rx_rssi_percentage[rfpath] =
- ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
- (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
- }
- RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
- }
- }
-
-
- //
- // Check PWDB.
- //
- RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
- pprevious_stats->bIsCCK? "CCK": "OFDM",
- pprevious_stats->RxPWDBAll);
-
- if(pprevious_stats->bPacketBeacon)
- {
-/* record the beacon pwdb to the sliding window. */
- if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
- {
- slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
- last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
- priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
- //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
- // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
- }
- priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
- priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
- //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
- slide_beacon_adc_pwdb_index++;
- if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
- slide_beacon_adc_pwdb_index = 0;
- pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
- if(pprevious_stats->RxPWDBAll >= 3)
- pprevious_stats->RxPWDBAll -= 3;
- }
-
- RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
- pprevious_stats->bIsCCK? "CCK": "OFDM",
- pprevious_stats->RxPWDBAll);
-
-
- if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
- {
- if(priv->undecorated_smoothed_pwdb < 0) // initialize
- {
- priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
- //DbgPrint("First pwdb initialize \n");
- }
-#if 1
- if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
- {
- priv->undecorated_smoothed_pwdb =
- ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
- (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
- priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
- }
- else
- {
- priv->undecorated_smoothed_pwdb =
- ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
- (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
- }
-#else
- //Fixed by Jacken 2008-03-20
- if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
- {
- pHalData->UndecoratedSmoothedPWDB =
- ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
- pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
- }
- else
- {
- pHalData->UndecoratedSmoothedPWDB =
- ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
- }
-#endif
-
- }
-
- //
- // Check EVM
- //
- /* record the general EVM to the sliding window. */
- if(pprevious_stats->SignalQuality == 0)
- {
- }
- else
- {
- if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
- if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
- slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
- last_evm = priv->stats.slide_evm[slide_evm_index];
- priv->stats.slide_evm_total -= last_evm;
- }
-
- priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
-
- priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
- if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
- slide_evm_index = 0;
-
- // <1> Showed on UI for user, in percentage.
- tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
- priv->stats.signal_quality = tmp_val;
- //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
- priv->stats.last_signal_strength_inpercent = tmp_val;
- }
-
- // <2> Showed on UI for engineering
- if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
- {
- for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
- {
- if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
- {
- if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
- {
- priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
- }
- priv->stats.rx_evm_percentage[nspatial_stream] =
- ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
- (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
- }
- }
- }
- }
-
-
-}
-
-/*-----------------------------------------------------------------------------
- * Function: rtl819x_query_rxpwrpercentage()
- *
- * Overview:
- *
- * Input: char antpower
- *
- * Output: NONE
- *
- * Return: 0-100 percentage
- *
- * Revised History:
- * When Who Remark
- * 05/26/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static u8 rtl819x_query_rxpwrpercentage(
- char antpower
- )
-{
- if ((antpower <= -100) || (antpower >= 20))
- {
- return 0;
- }
- else if (antpower >= 0)
- {
- return 100;
- }
- else
- {
- return (100+antpower);
- }
-
-} /* QueryRxPwrPercentage */
-
-static u8
-rtl819x_evm_dbtopercentage(
- char value
- )
-{
- char ret_val;
-
- ret_val = value;
-
- if(ret_val >= 0)
- ret_val = 0;
- if(ret_val <= -33)
- ret_val = -33;
- ret_val = 0 - ret_val;
- ret_val*=3;
- if(ret_val == 99)
- ret_val = 100;
- return(ret_val);
-}
-//
-// Description:
-// We want good-looking for signal strength/quality
-// 2007/7/19 01:09, by cosa.
-//
-long
-rtl819x_signal_scale_mapping(
- long currsig
- )
-{
- long retsig;
-
- // Step 1. Scale mapping.
- if(currsig >= 61 && currsig <= 100)
- {
- retsig = 90 + ((currsig - 60) / 4);
- }
- else if(currsig >= 41 && currsig <= 60)
- {
- retsig = 78 + ((currsig - 40) / 2);
- }
- else if(currsig >= 31 && currsig <= 40)
- {
- retsig = 66 + (currsig - 30);
- }
- else if(currsig >= 21 && currsig <= 30)
- {
- retsig = 54 + (currsig - 20);
- }
- else if(currsig >= 5 && currsig <= 20)
- {
- retsig = 42 + (((currsig - 5) * 2) / 3);
- }
- else if(currsig == 4)
- {
- retsig = 36;
- }
- else if(currsig == 3)
- {
- retsig = 27;
- }
- else if(currsig == 2)
- {
- retsig = 18;
- }
- else if(currsig == 1)
- {
- retsig = 9;
- }
- else
- {
- retsig = currsig;
- }
-
- return retsig;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: QueryRxPhyStatus8192S()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 06/01/2007 MHC Create Version 0.
- * 06/05/2007 MHC Accordign to HW's new data sheet, we add CCK and OFDM
- * descriptor definition.
- * 07/04/2007 MHC According to Jerry and Bryant's document. We read
- * ir_isolation and ext_lna for RF's init value and use
- * to compensate RSSI after receiving packets.
- * 09/10/2008 MHC Modify name and PHY status field for 92SE.
- * 09/19/2008 MHC Add CCK/OFDM SS/SQ for 92S series.
- *
- *---------------------------------------------------------------------------*/
-static void rtl8192SU_query_rxphystatus(
- struct r8192_priv * priv,
- struct ieee80211_rx_stats * pstats,
- rx_desc_819x_usb *pDesc,
- rx_drvinfo_819x_usb * pdrvinfo,
- struct ieee80211_rx_stats * precord_stats,
- bool bpacket_match_bssid,
- bool bpacket_toself,
- bool bPacketBeacon,
- bool bToSelfBA
- )
-{
- //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status);
- //PHY_STS_CCK_8192S_T *pCck_buf;
- phy_sts_cck_819xusb_t * pcck_buf;
- phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
- //u8 *prxpkt;
- //u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
- u8 i, max_spatial_stream, rxsc_sgien_exflg;
- char rx_pwr[4], rx_pwr_all=0;
- //long rx_avg_pwr = 0;
- //char rx_snrX, rx_evmX;
- u8 evm, pwdb_all;
- u32 RSSI, total_rssi=0;//, total_evm=0;
-// long signal_strength_index = 0;
- u8 is_cck_rate=0;
- u8 rf_rx_num = 0;
-
-
-
- priv->stats.numqry_phystatus++;
-
- is_cck_rate = rx_hal_is_cck_rate(pDesc);
-
- // Record it for next packet processing
- memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
- pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
- pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
- pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
- pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
- pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
-
-
- pstats->RxMIMOSignalQuality[0] = -1;
- pstats->RxMIMOSignalQuality[1] = -1;
- precord_stats->RxMIMOSignalQuality[0] = -1;
- precord_stats->RxMIMOSignalQuality[1] = -1;
-
- if(is_cck_rate)
- {
- u8 report;//, tmp_pwdb;
- //char cck_adc_pwdb[4];
-
- // CCK Driver info Structure is not the same as OFDM packet.
- pcck_buf = (phy_sts_cck_819xusb_t *)pdrvinfo;
-
- //
- // (1)Hardware does not provide RSSI for CCK
- //
-
- //
- // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
- //
-
- priv->stats.numqry_phystatusCCK++;
-
- if(!priv->bCckHighPower)
- {
- report = pcck_buf->cck_agc_rpt & 0xc0;
- report = report>>6;
- switch(report)
- {
- //Fixed by Jacken from Bryant 2008-03-20
- //Original value is -38 , -26 , -14 , -2
- //Fixed value is -35 , -23 , -11 , 6
- case 0x3:
- rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
- break;
- case 0x2:
- rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
- break;
- case 0x1:
- rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
- break;
- case 0x0:
- rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);//6->8
- break;
- }
- }
- else
- {
- report = pdrvinfo->cfosho[0] & 0x60;
- report = report>>5;
- switch(report)
- {
- case 0x3:
- rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
- break;
- case 0x2:
- rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
- break;
- case 0x1:
- rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
- break;
- case 0x0:
- rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;//6->-8
- break;
- }
- }
-
- pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);//check it
- pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
- //pstats->RecvSignalPower = pwdb_all;
- pstats->RecvSignalPower = rx_pwr_all;
-
- //
- // (3) Get Signal Quality (EVM)
- //
- //if(bpacket_match_bssid)
- {
- u8 sq;
-
- if(pstats->RxPWDBAll > 40)
- {
- sq = 100;
- }else
- {
- sq = pcck_buf->sq_rpt;
-
- if(pcck_buf->sq_rpt > 64)
- sq = 0;
- else if (pcck_buf->sq_rpt < 20)
- sq = 100;
- else
- sq = ((64-sq) * 100) / 44;
- }
- pstats->SignalQuality = precord_stats->SignalQuality = sq;
- pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
- pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
- }
- }
- else
- {
- priv->stats.numqry_phystatusHT++;
-
- // 2008/09/19 MH For 92S debug, RX RF path always enable!!
- priv->brfpath_rxenable[0] = priv->brfpath_rxenable[1] = TRUE;
-
- //
- // (1)Get RSSI for HT rate
- //
- //for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
- for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
- {
- // 2008/01/30 MH we will judge RF RX path now.
- if (priv->brfpath_rxenable[i])
- rf_rx_num++;
- //else
- // continue;
-
- //if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
- // continue;
-
- //Fixed by Jacken from Bryant 2008-03-20
- //Original value is 106
- //rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
- rx_pwr[i] = ((pdrvinfo->gain_trsw[i]&0x3F)*2) - 110;
-
- /* Translate DBM to percentage. */
- RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); //check ok
- total_rssi += RSSI;
- RT_TRACE(COMP_RF, "RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], RSSI);
-
- //Get Rx snr value in DB
- //tmp_rxsnr = pofdm_buf->rxsnr_X[i];
- //rx_snrX = (char)(tmp_rxsnr);
- //rx_snrX /= 2;
- //priv->stats.rxSNRdB[i] = (long)rx_snrX;
- priv->stats.rxSNRdB[i] = (long)(pdrvinfo->rxsnr[i]/2);
-
- /* Translate DBM to percentage. */
- //RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
- //total_rssi += RSSI;
-
- /* Record Signal Strength for next packet */
- //if(bpacket_match_bssid)
- {
- pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
- precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
- }
- }
-
-
- //
- // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
- //
- //Fixed by Jacken from Bryant 2008-03-20
- //Original value is 106
- //rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
- rx_pwr_all = (((pdrvinfo->pwdb_all ) >> 1 )& 0x7f) -106;
- pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
-
- pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
- pstats->RxPower = precord_stats->RxPower = rx_pwr_all;
- pstats->RecvSignalPower = rx_pwr_all;
-
- //
- // (3)EVM of HT rate
- //
- //if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
- // pdrvinfo->RxRate<=DESC90_RATEMCS15)
- if(pDesc->RxHT && pDesc->RxMCS>=DESC92S_RATEMCS8 &&
- pDesc->RxMCS<=DESC92S_RATEMCS15)
- max_spatial_stream = 2; //both spatial stream make sense
- else
- max_spatial_stream = 1; //only spatial stream 1 makes sense
-
- for(i=0; i<max_spatial_stream; i++)
- {
- //tmp_rxevm = pofdm_buf->rxevm_X[i];
- //rx_evmX = (char)(tmp_rxevm);
-
- // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
- // fill most significant bit to "zero" when doing shifting operation which may change a negative
- // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
- //rx_evmX /= 2; //dbm
-
- //evm = rtl819x_evm_dbtopercentage(rx_evmX);
- evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/)); //dbm
- RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
-
- //if(bpacket_match_bssid)
- {
- if(i==0) // Fill value in RFD, Get the first spatial stream only
- pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
- pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
- }
- }
-
-
- /* record rx statistics for debug */
- //rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
- prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
- //if(pdrvinfo->BW) //40M channel
- if(pDesc->BW) //40M channel
- priv->stats.received_bwtype[1+pdrvinfo->rxsc]++;
- else //20M channel
- priv->stats.received_bwtype[0]++;
- }
-
- //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
- //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
- if(is_cck_rate)
- {
- pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;//check ok
-
- }
- else
- {
- //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
- // We can judge RX path number now.
- if (rf_rx_num != 0)
- pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
- }
-}/* QueryRxPhyStatus8192S */
-
-void
-rtl8192_record_rxdesc_forlateruse(
- struct ieee80211_rx_stats * psrc_stats,
- struct ieee80211_rx_stats * ptarget_stats
-)
-{
- ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
- ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
- ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
-}
-
-static void rtl8192SU_query_rxphystatus(
- struct r8192_priv * priv,
- struct ieee80211_rx_stats * pstats,
- rx_desc_819x_usb *pDesc,
- rx_drvinfo_819x_usb * pdrvinfo,
- struct ieee80211_rx_stats * precord_stats,
- bool bpacket_match_bssid,
- bool bpacket_toself,
- bool bPacketBeacon,
- bool bToSelfBA
- );
-void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
- struct ieee80211_rx_stats * pstats,
- rx_desc_819x_usb *pDesc,
- rx_drvinfo_819x_usb *pdrvinfo)
-{
- // TODO: We must only check packet for current MAC address. Not finish
- rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
- struct net_device *dev=info->dev;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- bool bpacket_match_bssid, bpacket_toself;
- bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
- static struct ieee80211_rx_stats previous_stats;
- struct ieee80211_hdr_3addr *hdr;//by amy
- u16 fc,type;
-
- // Get Signal Quality for only RX data queue (but not command queue)
-
- u8* tmp_buf;
- //u16 tmp_buf_len = 0;
- u8 *praddr;
-
- /* Get MAC frame start address. */
- tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
-
- hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
- fc = le16_to_cpu(hdr->frame_control);
- type = WLAN_FC_GET_TYPE(fc);
- praddr = hdr->addr1;
-
- /* Check if the received packet is acceptabe. */
- bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
- (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
- && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
- bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
-
-#if 1//cosa
- if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
- {
- bPacketBeacon = true;
- //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
- }
- if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
- {
- if((eqMacAddr(praddr,dev->dev_addr)))
- bToSelfBA = true;
- //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
- }
-
-#endif
-
-
- if(bpacket_match_bssid)
- {
- priv->stats.numpacket_matchbssid++;
- }
- if(bpacket_toself){
- priv->stats.numpacket_toself++;
- }
- //
- // Process PHY information for previous packet (RSSI/PWDB/EVM)
- //
- // Because phy information is contained in the last packet of AMPDU only, so driver
- // should process phy information of previous packet
- rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
- rtl8192SU_query_rxphystatus(priv, pstats, pDesc, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
- rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
-
-}
-
-/**
-* Function: UpdateReceivedRateHistogramStatistics
-* Overview: Recored down the received data rate
-*
-* Input:
-* struct net_device *dev
-* struct ieee80211_rx_stats *stats
-*
-* Output:
-*
-* (priv->stats.ReceivedRateHistogram[] is updated)
-* Return:
-* None
-*/
-void
-UpdateReceivedRateHistogramStatistics8190(
- struct net_device *dev,
- struct ieee80211_rx_stats *stats
- )
-{
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV
- u32 rateIndex;
- u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI
-
-
- if(stats->bCRC)
- rcvType = 2;
- else if(stats->bICV)
- rcvType = 3;
-
- if(stats->bShortPreamble)
- preamble_guardinterval = 1;// short
- else
- preamble_guardinterval = 0;// long
-
- switch(stats->rate)
- {
- //
- // CCK rate
- //
- case MGN_1M: rateIndex = 0; break;
- case MGN_2M: rateIndex = 1; break;
- case MGN_5_5M: rateIndex = 2; break;
- case MGN_11M: rateIndex = 3; break;
- //
- // Legacy OFDM rate
- //
- case MGN_6M: rateIndex = 4; break;
- case MGN_9M: rateIndex = 5; break;
- case MGN_12M: rateIndex = 6; break;
- case MGN_18M: rateIndex = 7; break;
- case MGN_24M: rateIndex = 8; break;
- case MGN_36M: rateIndex = 9; break;
- case MGN_48M: rateIndex = 10; break;
- case MGN_54M: rateIndex = 11; break;
- //
- // 11n High throughput rate
- //
- case MGN_MCS0: rateIndex = 12; break;
- case MGN_MCS1: rateIndex = 13; break;
- case MGN_MCS2: rateIndex = 14; break;
- case MGN_MCS3: rateIndex = 15; break;
- case MGN_MCS4: rateIndex = 16; break;
- case MGN_MCS5: rateIndex = 17; break;
- case MGN_MCS6: rateIndex = 18; break;
- case MGN_MCS7: rateIndex = 19; break;
- case MGN_MCS8: rateIndex = 20; break;
- case MGN_MCS9: rateIndex = 21; break;
- case MGN_MCS10: rateIndex = 22; break;
- case MGN_MCS11: rateIndex = 23; break;
- case MGN_MCS12: rateIndex = 24; break;
- case MGN_MCS13: rateIndex = 25; break;
- case MGN_MCS14: rateIndex = 26; break;
- case MGN_MCS15: rateIndex = 27; break;
- default: rateIndex = 28; break;
- }
- priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
- priv->stats.received_rate_histogram[0][rateIndex]++; //total
- priv->stats.received_rate_histogram[rcvType][rateIndex]++;
-}
-
-void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
-{
- rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
- struct net_device *dev=info->dev;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
- rx_drvinfo_819x_usb *driver_info = NULL;
-
- //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
- //PHAL_DATA_8192SUSB pHalData = GET_HAL_DATA(Adapter);
- //pu1Byte pDesc = (pu1Byte)pDescIn;
- //PRX_DRIVER_INFO_8192S pDrvInfo;
-
- rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
-
- if(0)
- {
- int m = 0;
- printk("========================");
- for(m=0; m<skb->len; m++){
- if((m%32) == 0)
- printk("\n");
- printk("%2x ",((u8*)skb->data)[m]);
- }
- printk("\n========================\n");
-
- }
-
-
- //
- //Get Rx Descriptor Raw Information
- //
- stats->Length = desc->Length ;
- stats->RxDrvInfoSize = desc->RxDrvInfoSize*RX_DRV_INFO_SIZE_UNIT;
- stats->RxBufShift = (desc->Shift)&0x03;
- stats->bICV = desc->ICV;
- stats->bCRC = desc->CRC32;
- stats->bHwError = stats->bCRC|stats->bICV;
- stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
- stats->bIsAMPDU = (desc->AMSDU==1);
- stats->bFirstMPDU = (desc->PAGGR==1) && (desc->FAGGR==1);
- stats->bShortPreamble = desc->SPLCP;
- stats->RxIs40MHzPacket = (desc->BW==1);
- stats->TimeStampLow = desc->TSFL;
-
- if((desc->FAGGR==1) || (desc->PAGGR==1))
- {// Rx A-MPDU
- RT_TRACE(COMP_RXDESC, "FirstAGGR = %d, PartAggr = %d\n", desc->FAGGR, desc->PAGGR);
- }
-//YJ,test,090310
-if(stats->bHwError)
-{
- if(stats->bICV)
- printk("%s: Receive ICV error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
- if(stats->bCRC)
- printk("%s: Receive CRC error!!!!!!!!!!!!!!!!!!!!!!\n", __FUNCTION__);
-}
-
- if(IS_UNDER_11N_AES_MODE(priv->ieee80211))
- {
- // Always received ICV error packets in AES mode.
- // This fixed HW later MIC write bug.
- if(stats->bICV && !stats->bCRC)
- {
- stats->bICV = FALSE;
- stats->bHwError = FALSE;
- }
- }
-
- // Transform HwRate to MRate
- if(!stats->bHwError)
- //stats->DataRate = HwRateToMRate(
- // (BOOLEAN)GET_RX_DESC_RXHT(pDesc),
- // (u1Byte)GET_RX_DESC_RXMCS(pDesc),
- // (BOOLEAN)GET_RX_DESC_PAGGR(pDesc));
- stats->rate = rtl8192SU_HwRateToMRate(desc->RxHT, desc->RxMCS, desc->PAGGR);
- else
- stats->rate = MGN_1M;
-
- //
- // Collect Rx rate/AMPDU/TSFL
- //
- //UpdateRxdRateHistogramStatistics8192S(Adapter, pRfd);
- //UpdateRxAMPDUHistogramStatistics8192S(Adapter, pRfd);
- //UpdateRxPktTimeStamp8192S(Adapter, pRfd);
- UpdateReceivedRateHistogramStatistics8190(dev, stats);
- //UpdateRxAMPDUHistogramStatistics8192S(dev, stats); //FIXLZM
- UpdateRxPktTimeStamp8190(dev, stats);
-
- //
- // Get PHY Status and RSVD parts.
- // <Roger_Notes> It only appears on last aggregated packet.
- //
- if (desc->PHYStatus)
- {
- //driver_info = (rx_drvinfo_819x_usb *)(skb->data + RX_DESC_SIZE + stats->RxBufShift);
- driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
- stats->RxBufShift);
- if(0)
- {
- int m = 0;
- printk("========================\n");
- printk("RX_DESC_SIZE:%d, RxBufShift:%d, RxDrvInfoSize:%d\n",
- RX_DESC_SIZE, stats->RxBufShift, stats->RxDrvInfoSize);
- for(m=0; m<32; m++){
- printk("%2x ",((u8*)driver_info)[m]);
- }
- printk("\n========================\n");
-
- }
-
- }
-
- //YJ,add,090107
- skb_pull(skb, sizeof(rx_desc_819x_usb));
- //YJ,add,090107,end
-
- //
- // Get Total offset of MPDU Frame Body
- //
- if((stats->RxBufShift + stats->RxDrvInfoSize) > 0)
- {
- stats->bShift = 1;
- //YJ,add,090107
- skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize);
- //YJ,add,090107,end
- }
-
- //
- // Get PHY Status and RSVD parts.
- // <Roger_Notes> It only appears on last aggregated packet.
- //
- if (desc->PHYStatus)
- {
- rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
- }
-}
-
-//
-// Description:
-// The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
-// (1) QoS control : shift 2 bytes
-// (2) Mesh Network : shift 1 or 3 bytes
-// (3) RxDriverInfo occupies the front parts of Rx Packets buffer(shift units is in 8Bytes)
-//
-// It is because Lextra CPU used by 8186 or 865x series assert exception if the statrting address
-// of IP header is not double word alignment.
-// This features is supported in 818xb and 8190 only, but not 818x.
-//
-// parameter: PRT_RFD, Pointer of Reeceive frame descriptor which is initialized according to
-// Rx Descriptor
-// return value: unsigned int, number of total shifted bytes
-//
-// Notes: 2008/06/28, created by Roger
-//
-u32 GetRxPacketShiftBytes8192SU(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe)
-{
- //PRT_RFD_STATUS pRtRfdStatus = &pRfd->Status;
-
- return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize + Status->RxBufShift);
-}
-
-void rtl8192SU_rx_nomal(struct sk_buff* skb)
-{
- rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
- struct net_device *dev=info->dev;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct ieee80211_rx_stats stats = {
- .signal = 0,
- .noise = -98,
- .rate = 0,
- // .mac_time = jiffies,
- .freq = IEEE80211_24GHZ_BAND,
- };
- u32 rx_pkt_len = 0;
- struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
- bool unicast_packet = false;
-
- //printk("**********skb->len = %d\n", skb->len);
- /* 20 is for ps-poll */
- if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
-
- /* first packet should not contain Rx aggregation header */
- rtl8192SU_query_rxdesc_status(skb, &stats, false);
- /* TODO */
-
- /* hardware related info */
- priv->stats.rxoktotal++; //YJ,test,090108
-
- /* Process the MPDU recevied */
- skb_trim(skb, skb->len - 4/*sCrcLng*/);//FIXLZM
-
- rx_pkt_len = skb->len;
- ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
- unicast_packet = false;
- if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
- //TODO
- }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
- //TODO
- }else {
- /* unicast packet */
- unicast_packet = true;
- }
-
- if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) {
- dev_kfree_skb_any(skb);
- } else {
- // priv->stats.rxoktotal++; //YJ,test,090108
- if(unicast_packet) {
- priv->stats.rxbytesunicast += rx_pkt_len;
- }
- }
-
- //up is firs pkt, follow is next and next
- }
- else
- {
- priv->stats.rxurberr++;
- printk("actual_length:%d\n", skb->len);
- dev_kfree_skb_any(skb);
- }
-
-}
-
-void
-rtl819xusb_process_received_packet(
- struct net_device *dev,
- struct ieee80211_rx_stats *pstats
- )
-{
-// bool bfreerfd=false, bqueued=false;
- u8* frame;
- u16 frame_len=0;
- struct r8192_priv *priv = ieee80211_priv(dev);
-// u8 index = 0;
-// u8 TID = 0;
- //u16 seqnum = 0;
- //PRX_TS_RECORD pts = NULL;
-
- // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
- //porting by amy 080508
- pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
- frame = pstats->virtual_address;
- frame_len = pstats->packetlength;
-#ifdef TODO // by amy about HCT
- if(!Adapter->bInHctTest)
- CountRxErrStatistics(Adapter, pRfd);
-#endif
- {
- #ifdef ENABLE_PS //by amy for adding ps function in future
- RT_RF_POWER_STATE rtState;
- // When RF is off, we should not count the packet for hw/sw synchronize
- // reason, ie. there may be a duration while sw switch is changed and hw
- // switch is being changed. 2006.12.04, by shien chang.
- Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
- if (rtState == eRfOff)
- {
- return;
- }
- #endif
- priv->stats.rxframgment++;
-
- }
-#ifdef TODO
- RmMonitorSignalStrength(Adapter, pRfd);
-#endif
- /* 2007/01/16 MH Add RX command packet handle here. */
- /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
- if (rtl819xusb_rx_command_packet(dev, pstats))
- {
- return;
- }
-
-#ifdef SW_CRC_CHECK
- SwCrcCheck();
-#endif
-
-
-}
-
-void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
-{
-// rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
-// struct net_device *dev=info->dev;
-// struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
-// rx_drvinfo_819x_usb *driver_info;
-
- //
- //Get Rx Descriptor Information
- //
- stats->virtual_address = (u8*)skb->data;
- stats->Length = desc->Length;
- stats->RxDrvInfoSize = 0;
- stats->RxBufShift = 0;
- stats->packetlength = stats->Length-scrclng;
- stats->fraglength = stats->packetlength;
- stats->fragoffset = 0;
- stats->ntotalfrag = 1;
-}
-
-void rtl8192SU_rx_cmd(struct sk_buff *skb)
-{
- struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
- struct net_device *dev = info->dev;
-
- /* TODO */
- struct ieee80211_rx_stats stats = {
- .signal = 0,
- .noise = -98,
- .rate = 0,
- // .mac_time = jiffies,
- .freq = IEEE80211_24GHZ_BAND,
- };
-
- //
- // Check buffer length to determine if this is a valid MPDU.
- //
- if( (skb->len >= sizeof(rx_desc_819x_usb)) && (skb->len <= RX_URB_SIZE) )//&&
- //(pHalData->SwChnlInProgress == FALSE))
- {
- //
- // Collection information in Rx descriptor.
- //
- query_rx_cmdpkt_desc_status(skb,&stats);
- // this is to be done by amy 080508 prfd->queue_id = 1;
-
- //
- // Process the MPDU recevied.
- //
- rtl819xusb_process_received_packet(dev,&stats);
-
- dev_kfree_skb_any(skb);
- }
- else
- {
- //RTInsertTailListWithCnt(&pAdapter->RfdIdleQueue, &pRfd->List, &pAdapter->NumIdleRfd);
- //RT_ASSERT(pAdapter->NumIdleRfd <= pAdapter->NumRfd, ("HalUsbInCommandComplete8192SUsb(): Adapter->NumIdleRfd(%d)\n", pAdapter->NumIdleRfd));
- //RT_TRACE(COMP_RECV, DBG_LOUD, ("HalUsbInCommandComplete8192SUsb(): NOT enough Resources!! BufLenUsed(%d), NumIdleRfd(%d)\n",
- //pContext->BufLenUsed, pAdapter->NumIdleRfd));
- }
-
- //
- // Reuse USB_IN_CONTEXT since we had finished processing the
- // buffer in USB_IN_CONTEXT.
- //
- //HalUsbReturnInContext(pAdapter, pContext);
-
- //
- // Issue another bulk IN transfer.
- //
- //HalUsbInMpdu(pAdapter, PipeIndex);
-
- RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
-
-}
-
-void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
-{
- struct sk_buff *skb;
- struct rtl8192_rx_info *info;
-
- while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
- info = (struct rtl8192_rx_info *)skb->cb;
- switch (info->out_pipe) {
- /* Nomal packet pipe */
- case 3:
- //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
- priv->IrpPendingCount--;
- priv->ops->rtl819x_rx_nomal(skb);
- break;
-
- /* Command packet pipe */
- case 9:
- RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
- info->out_pipe);
- priv->ops->rtl819x_rx_cmd(skb);
- break;
-
- default: /* should never get here! */
- RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
- info->out_pipe);
- dev_kfree_skb(skb);
- break;
-
- }
- }
-}
-
-
-
-/****************************************************************************
- ---------------------------- USB_STUFF---------------------------
-*****************************************************************************/
-//LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
-static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- u8 i = 0;
-
- priv->ep_in_num = 0;
- priv->ep_out_num = 0;
- memset(priv->RtOutPipes,0,16);
- memset(priv->RtInPipes,0,16);
-
- iface_desc = intf->cur_altsetting;
- priv->ep_num = iface_desc->desc.bNumEndpoints;
-
- for (i = 0; i < priv->ep_num; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (usb_endpoint_is_bulk_in(endpoint)) {
- priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
- priv->ep_in_num ++;
- //printk("in_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
- } else if (usb_endpoint_is_bulk_out(endpoint)) {
- priv->RtOutPipes[priv->ep_out_num] = usb_endpoint_num(endpoint);
- priv->ep_out_num ++;
- //printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
- }
- }
- {
- memset(priv->txqueue_to_outpipemap,0,9);
- if (priv->ep_num == 6) {
- // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
- u8 queuetopipe[] = {3, 2, 1, 0, 4, 4, 4, 4, 4};
-
- memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
- } else if (priv->ep_num == 4) {
- // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
- u8 queuetopipe[] = {1, 1, 0, 0, 2, 2, 2, 2, 2};
-
- memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
- } else if (priv->ep_num > 9) {
- // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
- u8 queuetopipe[] = {3, 2, 1, 0, 4, 8, 7, 6, 5};
-
- memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
- } else {//use sigle pipe
- // BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON
- u8 queuetopipe[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
- memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
- }
- }
- printk("==>ep_num:%d, in_ep_num:%d, out_ep_num:%d\n", priv->ep_num, priv->ep_in_num, priv->ep_out_num);
-
- printk("==>RtInPipes:");
- for(i=0; i < priv->ep_in_num; i++)
- printk("%d ", priv->RtInPipes[i]);
- printk("\n");
-
- printk("==>RtOutPipes:");
- for(i=0; i < priv->ep_out_num; i++)
- printk("%d ", priv->RtOutPipes[i]);
- printk("\n");
-
- printk("==>txqueue_to_outpipemap for BK, BE, VI, VO, HCCA, TXCMD, MGNT, HIGH, BEACON:\n");
- for(i=0; i < 9; i++)
- printk("%d ", priv->txqueue_to_outpipemap[i]);
- printk("\n");
-
- return;
-}
-
-static const struct net_device_ops rtl8192_netdev_ops = {
- .ndo_open = rtl8192_open,
- .ndo_stop = rtl8192_close,
- .ndo_get_stats = rtl8192_stats,
- .ndo_tx_timeout = tx_timeout,
- .ndo_do_ioctl = rtl8192_ioctl,
- .ndo_set_multicast_list = r8192_set_multicast,
- .ndo_set_mac_address = r8192_set_mac_adr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit,
-};
-
-static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
-// unsigned long ioaddr = 0;
- struct net_device *dev = NULL;
- struct r8192_priv *priv= NULL;
- struct usb_device *udev = interface_to_usbdev(intf);
-
- RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
-
- dev = alloc_ieee80211(sizeof(struct r8192_priv));
- if (dev == NULL)
- return -ENOMEM;
-
- usb_set_intfdata(intf, dev);
- SET_NETDEV_DEV(dev, &intf->dev);
- priv = ieee80211_priv(dev);
- priv->ieee80211 = netdev_priv(dev);
- priv->udev=udev;
-
- HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
-
- //printk("===============>NIC 8192SU\n");
- priv->ops = &rtl8192su_ops;
-
- dev->netdev_ops = &rtl8192_netdev_ops;
-
- //DMESG("Oops: i'm coming\n");
- dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
-
- dev->type=ARPHRD_ETHER;
-
- dev->watchdog_timeo = HZ*3; //modified by john, 0805
-
- if (dev_alloc_name(dev, ifname) < 0){
- RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
- strcpy(ifname, "wlan%d");
- dev_alloc_name(dev, ifname);
- }
-
- RT_TRACE(COMP_INIT, "Driver probe completed1\n");
-#if 1
- if(rtl8192_init(dev)!=0){
- RT_TRACE(COMP_ERR, "Initialization failed");
- goto fail;
- }
-#endif
- netif_carrier_off(dev);
- netif_stop_queue(dev);
-
- if (register_netdev(dev))
- goto fail;
- RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
- rtl8192_proc_init_one(dev);
-
-
- RT_TRACE(COMP_INIT, "Driver probe completed\n");
- return 0;
-fail:
- free_ieee80211(dev);
-
- RT_TRACE(COMP_ERR, "wlan driver load failed\n");
- return -ENODEV;
-}
-
-//detach all the work and timer structure declared or inititialize in r8192U_init function.
-void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
-{
- cancel_work_sync(&priv->reset_wq);
- cancel_work_sync(&priv->qos_activate);
- cancel_delayed_work(&priv->watch_dog_wq);
- cancel_delayed_work(&priv->update_beacon_wq);
- cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
- cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
- //cancel_work_sync(&priv->SetBWModeWorkItem);
- //cancel_work_sync(&priv->SwChnlWorkItem);
-}
-
-static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
-{
- struct net_device *dev = usb_get_intfdata(intf);
- struct r8192_priv *priv = ieee80211_priv(dev);
- if(dev){
-
- unregister_netdev(dev);
-
- RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
- rtl8192_proc_remove_one(dev);
-
- rtl8192_down(dev);
- if (priv->pFirmware)
- {
- vfree(priv->pFirmware);
- priv->pFirmware = NULL;
- }
- // priv->rf_close(dev);
-// rtl8192_SetRFPowerState(dev, eRfOff);
- destroy_workqueue(priv->priv_wq);
- //rtl8192_irq_disable(dev);
- //rtl8192_reset(dev);
- mdelay(10);
-
- }
- free_ieee80211(dev);
- RT_TRACE(COMP_DOWN, "wlan driver removed\n");
-}
-
-/* fun with the built-in ieee80211 stack... */
-extern int ieee80211_debug_init(void);
-extern void ieee80211_debug_exit(void);
-extern int ieee80211_crypto_init(void);
-extern void ieee80211_crypto_deinit(void);
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-extern int ieee80211_crypto_ccmp_init(void);
-extern void ieee80211_crypto_ccmp_exit(void);
-extern int ieee80211_crypto_wep_init(void);
-extern void ieee80211_crypto_wep_exit(void);
-
-static int __init rtl8192_usb_module_init(void)
-{
- int ret;
-
-#ifdef CONFIG_IEEE80211_DEBUG
- ret = ieee80211_debug_init();
- if (ret) {
- printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
- return ret;
- }
-#endif
- ret = ieee80211_crypto_init();
- if (ret) {
- printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
- goto fail_crypto;
- }
-
- ret = ieee80211_crypto_tkip_init();
- if (ret) {
- printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
- ret);
- goto fail_crypto_tkip;
- }
-
- ret = ieee80211_crypto_ccmp_init();
- if (ret) {
- printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
- ret);
- goto fail_crypto_ccmp;
- }
-
- ret = ieee80211_crypto_wep_init();
- if (ret) {
- printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
- goto fail_crypto_wep;
- }
-
- printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
- printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
- RT_TRACE(COMP_INIT, "Initializing module");
- RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
-
- ret = rtl8192_proc_module_init();
- if (ret) {
- pr_err("rtl8192_proc_module_init() failed %d\n", ret);
- goto fail_proc;
- }
-
- ret = usb_register(&rtl8192_usb_driver);
- if (ret) {
- pr_err("usb_register() failed %d\n", ret);
- goto fail_usb;
- }
-
- return 0;
-
-fail_usb:
- rtl8192_proc_module_remove();
-fail_proc:
- ieee80211_crypto_wep_exit();
-fail_crypto_wep:
- ieee80211_crypto_ccmp_exit();
-fail_crypto_ccmp:
- ieee80211_crypto_tkip_exit();
-fail_crypto_tkip:
- ieee80211_crypto_deinit();
-fail_crypto:
-#ifdef CONFIG_IEEE80211_DEBUG
- ieee80211_debug_exit();
-#endif
- return ret;
-}
-
-
-static void __exit rtl8192_usb_module_exit(void)
-{
- usb_deregister(&rtl8192_usb_driver);
-
- RT_TRACE(COMP_DOWN, "Exiting");
- rtl8192_proc_module_remove();
-
- ieee80211_crypto_tkip_exit();
- ieee80211_crypto_ccmp_exit();
- ieee80211_crypto_wep_exit();
- ieee80211_crypto_deinit();
-#ifdef CONFIG_IEEE80211_DEBUG
- ieee80211_debug_exit();
-#endif
-}
-
-
-void rtl8192_try_wake_queue(struct net_device *dev, int pri)
-{
- unsigned long flags;
- short enough_desc;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->tx_lock,flags);
- enough_desc = check_nic_enough_desc(dev,pri);
- spin_unlock_irqrestore(&priv->tx_lock,flags);
-
- if(enough_desc)
- ieee80211_rtl_wake_queue(priv->ieee80211);
-}
-
-void EnableHWSecurityConfig8192(struct net_device *dev)
-{
- u8 SECR_value = 0x0;
- struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
- switch (ieee->pairwise_key_type) {
- case KEY_TYPE_WEP40:
- case KEY_TYPE_WEP104:
- if (priv->ieee80211->auth_mode != 2) {
- SECR_value |= SCR_RxUseDK;
- SECR_value |= SCR_TxUseDK;
- }
- break;
- case KEY_TYPE_TKIP:
- case KEY_TYPE_CCMP:
- if (ieee->iw_mode == IW_MODE_ADHOC) {
- SECR_value |= SCR_RxUseDK;
- SECR_value |= SCR_TxUseDK;
- }
- break;
- default:
- break;
- }
-
- /*
- * add HWSec active enable here.
- * default using hwsec.
- * when peer AP is in N mode only and pairwise_key_type is none_aes
- * (which HT_IOT_ACT_PURE_N_MODE indicates it),
- * use software security.
- * when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes
- * use g mode hw security.
- */
- ieee->hwsec_active = 1;
-
- /* add hwsec_support flag to totol control hw_sec on/off */
- if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) {
- ieee->hwsec_active = 0;
- SECR_value &= ~SCR_RxDecEnable;
- }
-
- RT_TRACE(COMP_SEC, "%s(): hwsec: %d, pairwise_key: %d, "
- "SECR_value: %x",
- __func__, ieee->hwsec_active,
- ieee->pairwise_key_type, SECR_value);
-
- write_nic_byte(dev, SECR, SECR_value); /* SECR_value | SCR_UseDK ); */
-}
-
-
-void setKey(struct net_device *dev,
- u8 EntryNo,
- u8 KeyIndex,
- u16 KeyType,
- u8 *MacAddr,
- u8 DefaultKey,
- u32 *KeyContent)
-{
- u32 TargetCommand = 0;
- u32 TargetContent = 0;
- u16 usConfig = 0;
- u8 i;
-
- if (EntryNo >= TOTAL_CAM_ENTRY)
- RT_TRACE(COMP_ERR, "%s(): cam entry exceeds TOTAL_CAM_ENTRY",
- __func__);
-
- RT_TRACE(COMP_SEC, "%s(): dev: %p, EntryNo: %d, "
- "KeyIndex: %d, KeyType: %d, MacAddr: %pM",
- __func__, dev, EntryNo,
- KeyIndex, KeyType, MacAddr);
-
- if (DefaultKey)
- usConfig |= BIT15 | (KeyType << 2);
- else
- usConfig |= BIT15 | (KeyType << 2) | KeyIndex;
-
- for (i = 0 ; i < CAM_CONTENT_COUNT; i++) {
- TargetCommand = i + CAM_CONTENT_COUNT * EntryNo;
- TargetCommand |= BIT31|BIT16;
- switch (i) {
- case 0: /* MAC|Config */
- TargetContent = (u32)(*(MacAddr + 0)) << 16|
- (u32)(*(MacAddr + 1)) << 24|
- (u32)usConfig;
-
- write_nic_dword(dev, WCAMI, TargetContent);
- write_nic_dword(dev, RWCAM, TargetCommand);
- continue;
- case 1: /* MAC */
- TargetContent = (u32)(*(MacAddr + 2))|
- (u32)(*(MacAddr + 3)) << 8|
- (u32)(*(MacAddr + 4)) << 16|
- (u32)(*(MacAddr + 5)) << 24;
- write_nic_dword(dev, WCAMI, TargetContent);
- write_nic_dword(dev, RWCAM, TargetCommand);
- continue;
- default: /* Key Material */
- if (KeyContent != NULL) {
- write_nic_dword(dev, WCAMI,
- (u32)(*(KeyContent+i-2)));
- write_nic_dword(dev, RWCAM,
- TargetCommand);
- }
- continue;
- }
- }
-}
-
-/***************************************************************************
- ------------------- module init / exit stubs ----------------
-****************************************************************************/
-module_init(rtl8192_usb_module_init);
-module_exit(rtl8192_usb_module_exit);
diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c
deleted file mode 100644
index ce7e1ee4c3a7..000000000000
--- a/drivers/staging/rtl8192su/r8192U_dm.c
+++ /dev/null
@@ -1,3982 +0,0 @@
-/*++
-Copyright-c Realtek Semiconductor Corp. All rights reserved.
-
-Module Name:
- r8192U_dm.c
-
-Abstract:
- HW dynamic mechanism.
-
-Major Change History:
- When Who What
- ---------- --------------- -------------------------------
- 2008-05-14 amy create version 0 porting from windows code.
-
---*/
-
-
-#include "r8192U.h"
-#include "r8192U_dm.h"
-#include "r819xU_cmdpkt.h"
-#include "r8192S_hw.h"
-#include "r8192S_phy.h"
-#include "r8192S_phyreg.h"
-
-/*---------------------------Define Local Constant---------------------------*/
-//
-// Indicate different AP vendor for IOT issue.
-//
-#if 1
- static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
- // UNKNOWN REALTEK_90 /*REALTEK_92SE*/ BROADCOM RALINK ATHEROS CISCO MARVELL 92U_AP SELF_AP
- { 0xa44f, 0x5ea44f, 0x5ea44f, 0xa44f, 0xa44f, 0xa44f, 0xa630, 0xa42b, 0x5e4322, 0x5e4322};
- static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
- // UNKNOWN REALTEK /*REALTEK_92SE*/ BROADCOM RALINK ATHEROS CISCO MARVELL 92U_AP SELF_AP
- { 0x5ea44f, 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea422, 0x5e4322, 0x3ea44f, 0x5ea42b, 0x5e4322, 0x5e4322};
-
-#endif
-
-#define RTK_UL_EDCA 0xa44f
-#define RTK_DL_EDCA 0x5e4322
-/*---------------------------Define Local Constant---------------------------*/
-
-
-/*------------------------Define global variable-----------------------------*/
-// Debug variable ?
-dig_t dm_digtable;
-// Store current shoftware write register content for MAC PHY.
-u8 dm_shadow[16][256] = {{0}};
-// For Dynamic Rx Path Selection by Signal Strength
-DRxPathSel DM_RxPathSelTable;
-/*------------------------Define global variable-----------------------------*/
-
-
-/*------------------------Define local variable------------------------------*/
-/*------------------------Define local variable------------------------------*/
-
-
-/*--------------------Define export function prototype-----------------------*/
-#ifdef TO_DO_LIST
-static void dm_CheckProtection(struct net_device *dev);
-#endif
-extern void init_hal_dm(struct net_device *dev);
-extern void deinit_hal_dm(struct net_device *dev);
-
-extern void hal_dm_watchdog(struct net_device *dev);
-
-
-extern void init_rate_adaptive(struct net_device *dev);
-extern void dm_txpower_trackingcallback(struct work_struct *work);
-extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
-extern void dm_restore_dynamic_mechanism_state(struct net_device *dev);
-extern void dm_backup_dynamic_mechanism_state(struct net_device *dev);
-extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
- u32 dm_type,
- u32 dm_value);
-extern void DM_ChangeFsyncSetting(struct net_device *dev,
- s32 DM_Type,
- s32 DM_Value);
-extern void dm_force_tx_fw_info(struct net_device *dev,
- u32 force_type,
- u32 force_value);
-extern void dm_init_edca_turbo(struct net_device *dev);
-extern void dm_rf_operation_test_callback(unsigned long data);
-extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
-extern void dm_fsync_timer_callback(unsigned long data);
-extern void dm_check_fsync(struct net_device *dev);
-extern void dm_shadow_init(struct net_device *dev);
-
-
-/*--------------------Define export function prototype-----------------------*/
-
-
-/*---------------------Define local function prototype-----------------------*/
-// DM --> Rate Adaptive
-static void dm_check_rate_adaptive(struct net_device *dev);
-
-// DM --> Bandwidth switch
-static void dm_init_bandwidth_autoswitch(struct net_device *dev);
-static void dm_bandwidth_autoswitch( struct net_device *dev);
-
-// DM --> TX power control
-//static void dm_initialize_txpower_tracking(struct net_device *dev);
-
-static void dm_check_txpower_tracking(struct net_device *dev);
-
-
-
-//static void dm_txpower_reset_recovery(struct net_device *dev);
-
-
-// DM --> BB init gain restore
-#ifndef RTL8192U
-static void dm_bb_initialgain_restore(struct net_device *dev);
-
-
-// DM --> BB init gain backup
-static void dm_bb_initialgain_backup(struct net_device *dev);
-#endif
-// DM --> Dynamic Init Gain by RSSI
-static void dm_dig_init(struct net_device *dev);
-static void dm_ctrl_initgain_byrssi(struct net_device *dev);
-static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
-static void dm_ctrl_initgain_byrssi_by_driverrssi( struct net_device *dev);
-static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
-static void dm_initial_gain(struct net_device *dev);
-static void dm_pd_th(struct net_device *dev);
-static void dm_cs_ratio(struct net_device *dev);
-
-static void dm_init_ctstoself(struct net_device *dev);
-// DM --> EDCA turboe mode control
-static void dm_check_edca_turbo(struct net_device *dev);
-
-// DM --> HW RF control
-static void dm_check_rfctrl_gpio(struct net_device *dev);
-
-#ifndef RTL8190P
-//static void dm_gpio_change_rf(struct net_device *dev);
-#endif
-// DM --> Check PBC
-static void dm_check_pbc_gpio(struct net_device *dev);
-
-
-// DM --> Check current RX RF path state
-static void dm_check_rx_path_selection(struct net_device *dev);
-static void dm_init_rxpath_selection(struct net_device *dev);
-static void dm_rxpath_sel_byrssi(struct net_device *dev);
-
-
-// DM --> Fsync for broadcom ap
-static void dm_init_fsync(struct net_device *dev);
-static void dm_deInit_fsync(struct net_device *dev);
-
-//Added by vivi, 20080522
-static void dm_check_txrateandretrycount(struct net_device *dev);
-
-/*---------------------Define local function prototype-----------------------*/
-
-/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18
-static void dm_init_dynamic_txpower(struct net_device *dev);
-static void dm_dynamic_txpower(struct net_device *dev);
-
-
-// DM --> For rate adaptive and DIG, we must send RSSI to firmware
-static void dm_send_rssi_tofw(struct net_device *dev);
-static void dm_ctstoself(struct net_device *dev);
-/*---------------------------Define function prototype------------------------*/
-//================================================================================
-// HW Dynamic mechanism interface.
-//================================================================================
-static void dm_CheckAggrPolicy(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
- //u8 QueueId;
- //PRT_TCB pTcb;
- bool bAmsduEnable = false;
-
- static u8 lastTxOkCnt = 0;
- static u8 lastRxOkCnt = 0;
- u8 curTxOkCnt = 0;
- u8 curRxOkCnt = 0;
-
- // Determine if A-MSDU policy.
- if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_HYBRID_AGGREGATION)
- {
- if(read_nic_byte(dev, INIMCS_SEL) > DESC92S_RATE54M)
- bAmsduEnable = true;
- }
- else if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
- {
- if(read_nic_byte(dev, INIMCS_SEL) > DESC92S_RATE54M)
- {
- curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
- curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
-
- if(curRxOkCnt <= 4*curTxOkCnt)
- bAmsduEnable = true;
- }
- }
- else
- {
- // Do not need to switch aggregation policy.
- return;
- }
-
- // Switch A-MSDU
- if(bAmsduEnable && !pHTInfo->bCurrent_AMSDU_Support)
- {
- pHTInfo->bCurrent_AMSDU_Support = true;
- }
- else if(!bAmsduEnable && pHTInfo->bCurrent_AMSDU_Support)
- {
-#ifdef TO_DO_LIST
- //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
- for(QueueId = 0; QueueId < MAX_TX_QUEUE; QueueId++)
- {
- while(!RTIsListEmpty(&dev->TcbAggrQueue[QueueId]))
- {
- pTcb = (PRT_TCB)RTRemoveHeadList(&dev->TcbAggrQueue[QueueId]);
- dev->TcbCountInAggrQueue[QueueId]--;
- PreTransmitTCB(dev, pTcb);
- }
- }
- //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
- pHTInfo->bCurrent_AMSDU_Support = false;
-#endif
- }
-
- // Determine A-MPDU policy
- if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
- {
- if(!bAmsduEnable)
- pHTInfo->bCurrentAMPDUEnable = true;
- }
-
- // Update local static variables.
- lastTxOkCnt = priv->stats.txbytesunicast;
- lastRxOkCnt = priv->stats.rxbytesunicast;
-}
-//
-// Description:
-// Prepare SW resource for HW dynamic mechanism.
-//
-// Assumption:
-// This function is only invoked at driver intialization once.
-//
-//
-extern void
-init_hal_dm(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
- priv->undecorated_smoothed_pwdb = -1;
-
- //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
- dm_init_dynamic_txpower(dev);
- init_rate_adaptive(dev);
- dm_initialize_txpower_tracking(dev);
- dm_dig_init(dev);
- dm_init_edca_turbo(dev);
- dm_init_bandwidth_autoswitch(dev);
- dm_init_fsync(dev);
- dm_init_rxpath_selection(dev);
- dm_init_ctstoself(dev);
-
-} // InitHalDm
-
-extern void deinit_hal_dm(struct net_device *dev)
-{
-
- dm_deInit_fsync(dev);
-
-}
-
-
-
-
-//#if 0
-extern void hal_dm_watchdog(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if(priv->bInHctTest)
- return;
-
-
- dm_check_rfctrl_gpio(dev);
-
- // Add by hpfan 2008-03-11
- dm_check_pbc_gpio(dev);
- dm_check_txrateandretrycount(dev); //moved by tynli
- dm_check_edca_turbo(dev);
-
- dm_CheckAggrPolicy(dev);
-
-#ifdef TO_DO_LIST
- dm_CheckProtection(dev);
-#endif
-
- // ====================================================
- // If any dynamic mechanism is ready, put it above this return;
- // ====================================================
- //if (IS_HARDWARE_TYPE_8192S(dev))
- return;
-
-#ifdef TO_DO_LIST
- if(Adapter->MgntInfo.mActingAsAp)
- {
- AP_dm_CheckRateAdaptive(dev);
- //return;
- }
- else
-#endif
- {
- dm_check_rate_adaptive(dev);
- }
- dm_dynamic_txpower(dev);
-
- dm_check_txpower_tracking(dev);
- dm_ctrl_initgain_byrssi(dev);//LZM TMP 090302
-
- dm_bandwidth_autoswitch(dev);
-
- dm_check_rx_path_selection(dev);//LZM TMP 090302
- dm_check_fsync(dev);
-
- dm_send_rssi_tofw(dev);
-
- dm_ctstoself(dev);
-
-} //HalDmWatchDog
-
-/*
- * Decide Rate Adaptive Set according to distance (signal strength)
- * 01/11/2008 MHC Modify input arguments and RATR table level.
- * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call
- * the function after making sure RF_Type.
- */
-extern void init_rate_adaptive(struct net_device * dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
-
- pra->ratr_state = DM_RATR_STA_MAX;
- pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
- pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
- pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
-
- pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
- pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
- pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
-
- if(priv->CustomerID == RT_CID_819x_Netcore)
- pra->ping_rssi_enable = 1;
- else
- pra->ping_rssi_enable = 0;
- pra->ping_rssi_thresh_for_ra = 15;
-
-
- if (priv->rf_type == RF_2T4R)
- {
- // 07/10/08 MH Modify for RA smooth scheme.
- /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
- pra->upper_rssi_threshold_ratr = 0x8f0f0000;
- pra->middle_rssi_threshold_ratr = 0x8f0ff000;
- pra->low_rssi_threshold_ratr = 0x8f0ff001;
- pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
- pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
- pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
- }
- else if (priv->rf_type == RF_1T2R)
- {
- pra->upper_rssi_threshold_ratr = 0x000f0000;
- pra->middle_rssi_threshold_ratr = 0x000ff000;
- pra->low_rssi_threshold_ratr = 0x000ff001;
- pra->low_rssi_threshold_ratr_40M = 0x000ff005;
- pra->low_rssi_threshold_ratr_20M = 0x000ff001;
- pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
- }
-
-} // InitRateAdaptive
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rate_adaptive()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/26/08 amy Create version 0 proting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_rate_adaptive(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
- prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
- u32 currentRATR, targetRATR = 0;
- u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
- bool bshort_gi_enabled = false;
- static u8 ping_rssi_state=0;
-
-
- if(!priv->up)
- {
- RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
- return;
- }
-
- if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
- return;
-
- // TODO: Only 11n mode is implemented currently,
- if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
- priv->ieee80211->mode == WIRELESS_MODE_N_5G))
- return;
-
- if( priv->ieee80211->state == IEEE80211_LINKED )
- {
- // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
-
- //
- // Check whether Short GI is enabled
- //
- bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
- (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
-
-
- pra->upper_rssi_threshold_ratr =
- (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
-
- pra->middle_rssi_threshold_ratr =
- (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
-
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- pra->low_rssi_threshold_ratr =
- (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
- }
- else
- {
- pra->low_rssi_threshold_ratr =
- (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
- }
- //cosa add for test
- pra->ping_rssi_ratr =
- (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
-
- /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
- time to link with AP. We will not change upper/lower threshold. If
- STA stay in high or low level, we must change two different threshold
- to prevent jumping frequently. */
- if (pra->ratr_state == DM_RATR_STA_HIGH)
- {
- HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
- LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
- (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
- }
- else if (pra->ratr_state == DM_RATR_STA_LOW)
- {
- HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
- LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
- (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
- }
- else
- {
- HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
- LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
- (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
- }
-
- //DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
- if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
- {
- //DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
- pra->ratr_state = DM_RATR_STA_HIGH;
- targetRATR = pra->upper_rssi_threshold_ratr;
- }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
- {
- //DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
- pra->ratr_state = DM_RATR_STA_MIDDLE;
- targetRATR = pra->middle_rssi_threshold_ratr;
- }else
- {
- //DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
- pra->ratr_state = DM_RATR_STA_LOW;
- targetRATR = pra->low_rssi_threshold_ratr;
- }
-
- //cosa add for test
- if(pra->ping_rssi_enable)
- {
- //pHalData->UndecoratedSmoothedPWDB = 19;
- if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
- {
- if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
- ping_rssi_state )
- {
- //DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
- pra->ratr_state = DM_RATR_STA_LOW;
- targetRATR = pra->ping_rssi_ratr;
- ping_rssi_state = 1;
- }
- //else
- // DbgPrint("TestRSSI is between the range. \n");
- }
- else
- {
- //DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
- ping_rssi_state = 0;
- }
- }
-
- // 2008.04.01
-#if 1
- // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
- if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
- targetRATR &= 0xf00fffff;
-#endif
-
- //
- // Check whether updating of RATR0 is required
- //
- currentRATR = read_nic_dword(dev, RATR0);
- if( targetRATR != currentRATR )
- {
- u32 ratr_value;
- ratr_value = targetRATR;
- RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
- if(priv->rf_type == RF_1T2R)
- {
- ratr_value &= ~(RATE_ALL_OFDM_2SS);
- }
- write_nic_dword(dev, RATR0, ratr_value);
- write_nic_byte(dev, UFWP, 1);
-
- pra->last_ratr = targetRATR;
- }
-
- }
- else
- {
- pra->ratr_state = DM_RATR_STA_MAX;
- }
-
-} // dm_CheckRateAdaptive
-
-
-static void dm_init_bandwidth_autoswitch(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
- priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
- priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
- priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
-
-} // dm_init_bandwidth_autoswitch
-
-
-static void dm_bandwidth_autoswitch(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
- return;
- }else{
- if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
- if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
- priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
- }else{//in force send packets in 20 Mhz in 20/40
- if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
- priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
-
- }
- }
-} // dm_BandwidthAutoSwitch
-
-//OFDM default at 0db, index=6.
-static u32 OFDMSwingTable[OFDM_Table_Length] = {
- 0x7f8001fe, // 0, +6db
- 0x71c001c7, // 1, +5db
- 0x65400195, // 2, +4db
- 0x5a400169, // 3, +3db
- 0x50800142, // 4, +2db
- 0x47c0011f, // 5, +1db
- 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature
- 0x390000e4, // 7, -1db
- 0x32c000cb, // 8, -2db
- 0x2d4000b5, // 9, -3db
- 0x288000a2, // 10, -4db
- 0x24000090, // 11, -5db
- 0x20000080, // 12, -6db
- 0x1c800072, // 13, -7db
- 0x19800066, // 14, -8db
- 0x26c0005b, // 15, -9db
- 0x24400051, // 16, -10db
- 0x12000048, // 17, -11db
- 0x10000040 // 18, -12db
-};
-
-static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
- {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default
- {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db
- {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db
- {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db
- {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db
- {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db
- {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default
- {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db
- {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db
- {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db
- {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db
- {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db
-};
-
-static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
- {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default
- {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db
- {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db
- {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db
- {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db
- {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db
- {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default
- {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db
- {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db
- {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db
- {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db
- {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db
-};
-
-static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- bool bHighpowerstate, viviflag = FALSE;
- DCMD_TXCMD_T tx_cmd;
- u8 powerlevelOFDM24G;
- int i =0, j = 0, k = 0;
- u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
- u32 Value;
- u8 Pwr_Flag;
- u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
- //RT_STATUS rtStatus = RT_STATUS_SUCCESS;
-#ifdef RTL8192U
- bool rtStatus = true;
-#endif
- u32 delta=0;
-
- write_nic_byte(dev, 0x1ba, 0);
-
- priv->ieee80211->bdynamic_txpower_enable = false;
- bHighpowerstate = priv->bDynamicTxHighPower;
-
- powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
- RF_Type = priv->rf_type;
- Value = (RF_Type<<8) | powerlevelOFDM24G;
-
- RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
-
- for(j = 0; j<=30; j++)
-{ //fill tx_cmd
-
- tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
- tx_cmd.Length = 4;
- tx_cmd.Value = Value;
-#ifdef RTL8192U
- rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
- if (rtStatus == false)
- {
- RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
- }
-#else
- cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
- DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
-#endif
- mdelay(1);
- //DbgPrint("hi, vivi, strange\n");
- for(i = 0;i <= 30; i++)
- {
- Pwr_Flag = read_nic_byte(dev, 0x1ba);
-
- if (Pwr_Flag == 0)
- {
- mdelay(1);
- continue;
- }
-#ifdef RTL8190P
- Avg_TSSI_Meas = read_nic_word(dev, 0x1bc);
-#else
- Avg_TSSI_Meas = read_nic_word(dev, 0x13c);
-#endif
- if(Avg_TSSI_Meas == 0)
- {
- write_nic_byte(dev, 0x1ba, 0);
- break;
- }
-
- for(k = 0;k < 5; k++)
- {
-#ifdef RTL8190P
- tmp_report[k] = read_nic_byte(dev, 0x1d8+k);
-#else
- if(k !=4)
- tmp_report[k] = read_nic_byte(dev, 0x134+k);
- else
- tmp_report[k] = read_nic_byte(dev, 0x13e);
-#endif
- RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
- }
-
- //check if the report value is right
- for(k = 0;k < 5; k++)
- {
- if(tmp_report[k] <= 20)
- {
- viviflag =TRUE;
- break;
- }
- }
- if(viviflag ==TRUE)
- {
- write_nic_byte(dev, 0x1ba, 0);
- viviflag = FALSE;
- RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
- for(k = 0;k < 5; k++)
- tmp_report[k] = 0;
- break;
- }
-
- for(k = 0;k < 5; k++)
- {
- Avg_TSSI_Meas_from_driver += tmp_report[k];
- }
-
- Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
- RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
- TSSI_13dBm = priv->TSSI_13dBm;
- RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
-
- //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
- // For MacOS-compatible
- if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
- delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
- else
- delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
-
- if(delta <= E_FOR_TX_POWER_TRACK)
- {
- priv->ieee80211->bdynamic_txpower_enable = TRUE;
- write_nic_byte(dev, 0x1ba, 0);
- RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
- RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
- RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
- return;
- }
- else
- {
- if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
- {
- if((priv->rfa_txpowertrackingindex > 0)
-#ifdef RTL8190P
- &&(priv->rfc_txpowertrackingindex > 0)
-#endif
- )
- {
- priv->rfa_txpowertrackingindex--;
- if(priv->rfa_txpowertrackingindex_real > 4)
- {
- priv->rfa_txpowertrackingindex_real--;
- rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
- }
-#ifdef RTL8190P
- priv->rfc_txpowertrackingindex--;
- if(priv->rfc_txpowertrackingindex_real > 4)
- {
- priv->rfc_txpowertrackingindex_real--;
- rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
- }
-#endif
- }
- }
- else
- {
- if((priv->rfa_txpowertrackingindex < 36)
-#ifdef RTL8190P
- &&(priv->rfc_txpowertrackingindex < 36)
-#endif
- )
- {
- priv->rfa_txpowertrackingindex++;
- priv->rfa_txpowertrackingindex_real++;
- rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
-
-#ifdef RTL8190P
- priv->rfc_txpowertrackingindex++;
- priv->rfc_txpowertrackingindex_real++;
- rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
-#endif
- }
- }
- priv->cck_present_attentuation_difference
- = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
-
- if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
- priv->cck_present_attentuation
- = priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
- else
- priv->cck_present_attentuation
- = priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
-
- if(priv->cck_present_attentuation > -1&&priv->cck_present_attentuation <23)
- {
- if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
- {
- priv->bcck_in_ch14 = TRUE;
- dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
- }
- else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
- {
- priv->bcck_in_ch14 = FALSE;
- dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
- }
- else
- dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
- }
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
- RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
- RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
-
- if (priv->cck_present_attentuation_difference <= -12||priv->cck_present_attentuation_difference >= 24)
- {
- priv->ieee80211->bdynamic_txpower_enable = TRUE;
- write_nic_byte(dev, 0x1ba, 0);
- RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
- return;
- }
-
-
- }
- write_nic_byte(dev, 0x1ba, 0);
- Avg_TSSI_Meas_from_driver = 0;
- for(k = 0;k < 5; k++)
- tmp_report[k] = 0;
- break;
- }
-}
- priv->ieee80211->bdynamic_txpower_enable = TRUE;
- write_nic_byte(dev, 0x1ba, 0);
-}
-
-static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
-{
-#define ThermalMeterVal 9
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 tmpRegA, TempCCk;
- u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
- int i =0, CCKSwingNeedUpdate=0;
-
- if(!priv->btxpower_trackingInit)
- {
- //Query OFDM default setting
- tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
- for(i=0; i<OFDM_Table_Length; i++) //find the index
- {
- if(tmpRegA == OFDMSwingTable[i])
- {
- priv->OFDM_index= (u8)i;
- RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
- rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
- }
- }
-
- //Query CCK default setting From 0xa22
- TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
- for(i=0 ; i<CCK_Table_length ; i++)
- {
- if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
- {
- priv->CCK_index =(u8) i;
- RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
- rCCK0_TxFilter1, TempCCk, priv->CCK_index);
- break;
- }
- }
- priv->btxpower_trackingInit = TRUE;
- //pHalData->TXPowercount = 0;
- return;
- }
-
- // read and filter out unreasonable value
- tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7]
- RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
- if(tmpRegA < 3 || tmpRegA > 13)
- return;
- if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature
- tmpRegA = 12;
- RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
- priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
- priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
-
- //Get current RF-A temperature index
- if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature
- {
- tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
- tmpCCK40Mindex = tmpCCK20Mindex - 6;
- if(tmpOFDMindex >= OFDM_Table_Length)
- tmpOFDMindex = OFDM_Table_Length-1;
- if(tmpCCK20Mindex >= CCK_Table_length)
- tmpCCK20Mindex = CCK_Table_length-1;
- if(tmpCCK40Mindex >= CCK_Table_length)
- tmpCCK40Mindex = CCK_Table_length-1;
- }
- else
- {
- tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
- if(tmpval >= 6) // higher temperature
- tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB
- else
- tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
- tmpCCK40Mindex = 0;
- }
- //DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
- //((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
- //tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
- if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M
- tmpCCKindex = tmpCCK40Mindex;
- else
- tmpCCKindex = tmpCCK20Mindex;
-
- if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
- {
- priv->bcck_in_ch14 = TRUE;
- CCKSwingNeedUpdate = 1;
- }
- else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
- {
- priv->bcck_in_ch14 = FALSE;
- CCKSwingNeedUpdate = 1;
- }
-
- if(priv->CCK_index != tmpCCKindex)
- {
- priv->CCK_index = tmpCCKindex;
- CCKSwingNeedUpdate = 1;
- }
-
- if(CCKSwingNeedUpdate)
- {
- //DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
- dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
- }
- if(priv->OFDM_index != tmpOFDMindex)
- {
- priv->OFDM_index = tmpOFDMindex;
- rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
- RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
- priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
- }
- priv->txpower_count = 0;
-}
-
-extern void dm_txpower_trackingcallback(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
- struct net_device *dev = priv->ieee80211->dev;
-
-#ifdef RTL8190P
- dm_TXPowerTrackingCallback_TSSI(dev);
-#else
- if(priv->bDcut == TRUE)
- dm_TXPowerTrackingCallback_TSSI(dev);
- else
- dm_TXPowerTrackingCallback_ThermalMeter(dev);
-#endif
-}
-
-
-static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- //Initial the Tx BB index and mapping value
- priv->txbbgain_table[0].txbb_iq_amplifygain = 12;
- priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
- priv->txbbgain_table[1].txbb_iq_amplifygain = 11;
- priv->txbbgain_table[1].txbbgain_value=0x788001e2;
- priv->txbbgain_table[2].txbb_iq_amplifygain = 10;
- priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
- priv->txbbgain_table[3].txbb_iq_amplifygain = 9;
- priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
- priv->txbbgain_table[4].txbb_iq_amplifygain = 8;
- priv->txbbgain_table[4].txbbgain_value=0x65400195;
- priv->txbbgain_table[5].txbb_iq_amplifygain = 7;
- priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
- priv->txbbgain_table[6].txbb_iq_amplifygain = 6;
- priv->txbbgain_table[6].txbbgain_value=0x5a400169;
- priv->txbbgain_table[7].txbb_iq_amplifygain = 5;
- priv->txbbgain_table[7].txbbgain_value=0x55400155;
- priv->txbbgain_table[8].txbb_iq_amplifygain = 4;
- priv->txbbgain_table[8].txbbgain_value=0x50800142;
- priv->txbbgain_table[9].txbb_iq_amplifygain = 3;
- priv->txbbgain_table[9].txbbgain_value=0x4c000130;
- priv->txbbgain_table[10].txbb_iq_amplifygain = 2;
- priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
- priv->txbbgain_table[11].txbb_iq_amplifygain = 1;
- priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
- priv->txbbgain_table[12].txbb_iq_amplifygain = 0;
- priv->txbbgain_table[12].txbbgain_value=0x40000100;
- priv->txbbgain_table[13].txbb_iq_amplifygain = -1;
- priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
- priv->txbbgain_table[14].txbb_iq_amplifygain = -2;
- priv->txbbgain_table[14].txbbgain_value=0x390000e4;
- priv->txbbgain_table[15].txbb_iq_amplifygain = -3;
- priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
- priv->txbbgain_table[16].txbb_iq_amplifygain = -4;
- priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
- priv->txbbgain_table[17].txbb_iq_amplifygain = -5;
- priv->txbbgain_table[17].txbbgain_value=0x300000c0;
- priv->txbbgain_table[18].txbb_iq_amplifygain = -6;
- priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
- priv->txbbgain_table[19].txbb_iq_amplifygain = -7;
- priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
- priv->txbbgain_table[20].txbb_iq_amplifygain = -8;
- priv->txbbgain_table[20].txbbgain_value=0x288000a2;
- priv->txbbgain_table[21].txbb_iq_amplifygain = -9;
- priv->txbbgain_table[21].txbbgain_value=0x26000098;
- priv->txbbgain_table[22].txbb_iq_amplifygain = -10;
- priv->txbbgain_table[22].txbbgain_value=0x24000090;
- priv->txbbgain_table[23].txbb_iq_amplifygain = -11;
- priv->txbbgain_table[23].txbbgain_value=0x22000088;
- priv->txbbgain_table[24].txbb_iq_amplifygain = -12;
- priv->txbbgain_table[24].txbbgain_value=0x20000080;
- priv->txbbgain_table[25].txbb_iq_amplifygain = -13;
- priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
- priv->txbbgain_table[26].txbb_iq_amplifygain = -14;
- priv->txbbgain_table[26].txbbgain_value=0x1c800072;
- priv->txbbgain_table[27].txbb_iq_amplifygain = -15;
- priv->txbbgain_table[27].txbbgain_value=0x18000060;
- priv->txbbgain_table[28].txbb_iq_amplifygain = -16;
- priv->txbbgain_table[28].txbbgain_value=0x19800066;
- priv->txbbgain_table[29].txbb_iq_amplifygain = -17;
- priv->txbbgain_table[29].txbbgain_value=0x15800056;
- priv->txbbgain_table[30].txbb_iq_amplifygain = -18;
- priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
- priv->txbbgain_table[31].txbb_iq_amplifygain = -19;
- priv->txbbgain_table[31].txbbgain_value=0x14400051;
- priv->txbbgain_table[32].txbb_iq_amplifygain = -20;
- priv->txbbgain_table[32].txbbgain_value=0x24400051;
- priv->txbbgain_table[33].txbb_iq_amplifygain = -21;
- priv->txbbgain_table[33].txbbgain_value=0x1300004c;
- priv->txbbgain_table[34].txbb_iq_amplifygain = -22;
- priv->txbbgain_table[34].txbbgain_value=0x12000048;
- priv->txbbgain_table[35].txbb_iq_amplifygain = -23;
- priv->txbbgain_table[35].txbbgain_value=0x11000044;
- priv->txbbgain_table[36].txbb_iq_amplifygain = -24;
- priv->txbbgain_table[36].txbbgain_value=0x10000040;
-
- //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
- //This Table is for CH1~CH13
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
- priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
-
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
- priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
-
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
- priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
- priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
- priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
- priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
- priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
- priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
-
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
- priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
- priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
- priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
- priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
- priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
- priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
- priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
- priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
- priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
-
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
-
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
-
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
-
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
-
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
-
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
- priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
-
- //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
- //This Table is for CH14
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
-
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
- priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
-
- priv->btxpower_tracking = TRUE;
- priv->txpower_count = 0;
- priv->btxpower_trackingInit = FALSE;
-
-}
-
-
-void dm_initialize_txpower_tracking(struct net_device *dev)
-{
-#if (defined RTL8190P)
- dm_InitializeTXPowerTracking_TSSI(dev);
-#else
- // 2009/01/12 MH Enable for 92S series channel 1-14 CCK tx pwer setting for MP.
- //
- dm_InitializeTXPowerTracking_TSSI(dev);
-#endif
-}// dm_InitializeTXPowerTracking
-
-
-static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u32 tx_power_track_counter = 0;
-
- if(!priv->btxpower_tracking)
- return;
- else
- {
- if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0))
- {
- queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
- }
- tx_power_track_counter++;
- }
-
-}
-
-
-static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u8 TM_Trigger=0;
-
- //DbgPrint("dm_CheckTXPowerTracking() \n");
- if(!priv->btxpower_tracking)
- return;
- else
- {
- if(priv->txpower_count <= 2)
- {
- priv->txpower_count++;
- return;
- }
- }
-
- if(!TM_Trigger)
- {
- //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
- //actually write reg0x02 bit1=0, then bit1=1.
- //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
- rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
- rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
- rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
- rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
- TM_Trigger = 1;
- return;
- }
- else
- {
- //DbgPrint("Schedule TxPowerTrackingWorkItem\n");
- queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
- TM_Trigger = 0;
- }
-}
-
-
-static void dm_check_txpower_tracking(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //static u32 tx_power_track_counter = 0;
-
-#ifdef RTL8190P
- dm_CheckTXPowerTracking_TSSI(dev);
-#else
- if(priv->bDcut == TRUE)
- dm_CheckTXPowerTracking_TSSI(dev);
- else
- dm_CheckTXPowerTracking_ThermalMeter(dev);
-#endif
-
-} // dm_CheckTXPowerTracking
-
-
-static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
-{
- u32 TempVal;
- struct r8192_priv *priv = ieee80211_priv(dev);
- //Write 0xa22 0xa23
- TempVal = 0;
- if(!bInCH14){
- //Write 0xa22 0xa23
- TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
- (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
- //Write 0xa24 ~ 0xa27
- TempVal = 0;
- TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
- (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
- (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
- (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
- rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
- //Write 0xa28 0xa29
- TempVal = 0;
- TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
- (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
- }
- else
- {
- TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
- (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
- //Write 0xa24 ~ 0xa27
- TempVal = 0;
- TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
- (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
- (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
- (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
- rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
- //Write 0xa28 0xa29
- TempVal = 0;
- TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
- (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
- }
-
-
-}
-
-static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14)
-{
- u32 TempVal;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- TempVal = 0;
- if(!bInCH14)
- {
- //Write 0xa22 0xa23
- TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
- (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
- rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_TxFilter1, TempVal);
- //Write 0xa24 ~ 0xa27
- TempVal = 0;
- TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
- (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
- (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
- (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
- rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_TxFilter2, TempVal);
- //Write 0xa28 0xa29
- TempVal = 0;
- TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
- (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_DebugPort, TempVal);
- }
- else
- {
-// priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug.
- //Write 0xa22 0xa23
- TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
- (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_TxFilter1, TempVal);
- //Write 0xa24 ~ 0xa27
- TempVal = 0;
- TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
- (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
- (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
- (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
- rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_TxFilter2, TempVal);
- //Write 0xa28 0xa29
- TempVal = 0;
- TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
- (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
-
- rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
- RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
- rCCK0_DebugPort, TempVal);
- }
-}
-
-
-
-extern void dm_cck_txpower_adjust(
- struct net_device *dev,
- bool binch14
-)
-{ // dm_CCKTxPowerAdjust
-
- struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef RTL8190P
- dm_CCKTxPowerAdjust_TSSI(dev, binch14);
-#else
- if(priv->bDcut == TRUE)
- dm_CCKTxPowerAdjust_TSSI(dev, binch14);
- else
- dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
-#endif
-}
-
-
-#ifndef RTL8192U
-static void dm_txpower_reset_recovery(
- struct net_device *dev
-)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
- rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->cck_present_attentuation);
- dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-
- rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
- RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
-
-} // dm_TXPowerResetRecovery
-
-extern void dm_restore_dynamic_mechanism_state(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 reg_ratr = priv->rate_adaptive.last_ratr;
-
- if(!priv->up)
- {
- RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
- return;
- }
-
- //
- // Restore previous state for rate adaptive
- //
- if(priv->rate_adaptive.rate_adaptive_disabled)
- return;
- // TODO: Only 11n mode is implemented currently,
- if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
- priv->ieee80211->mode==WIRELESS_MODE_N_5G))
- return;
- {
- /* 2007/11/15 MH Copy from 8190PCI. */
- u32 ratr_value;
- ratr_value = reg_ratr;
- if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled
- {
- ratr_value &=~ (RATE_ALL_OFDM_2SS);
- //DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
- }
- //DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
- //cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
- write_nic_dword(dev, RATR0, ratr_value);
- write_nic_byte(dev, UFWP, 1);
- }
- //Resore TX Power Tracking Index
- if(priv->btxpower_trackingInit && priv->btxpower_tracking){
- dm_txpower_reset_recovery(dev);
- }
-
- //
- //Restore BB Initial Gain
- //
- dm_bb_initialgain_restore(dev);
-
-} // DM_RestoreDynamicMechanismState
-
-static void dm_bb_initialgain_restore(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 bit_mask = 0x7f; //Bit0~ Bit6
-
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
- return;
-
- //Disable Initial Gain
- //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
- rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
- rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
- bit_mask = bMaskByte2;
- rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
-
- RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
- RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
- RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
- RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
- RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
- //Enable Initial Gain
- //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
-
-} // dm_BBInitialGainRestore
-
-
-extern void dm_backup_dynamic_mechanism_state(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- // Fsync to avoid reset
- priv->bswitch_fsync = false;
- priv->bfsync_processing = false;
- //Backup BB InitialGain
- dm_bb_initialgain_backup(dev);
-
-} // DM_BackupDynamicMechanismState
-
-
-static void dm_bb_initialgain_backup(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 bit_mask = bMaskByte0; //Bit0~ Bit6
-
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
- return;
-
- //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
- priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
- priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
- priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
- priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
- bit_mask = bMaskByte2;
- priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
-
- RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
- RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
- RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
- RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
- RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
-
-} // dm_BBInitialGainBakcup
-
-#endif
-/*-----------------------------------------------------------------------------
- * Function: dm_change_dynamic_initgain_thresh()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/29/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
- u32 dm_type,
- u32 dm_value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- if(dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
- priv->MidHighPwrTHR_L2 = (u8)dm_value;
- else if(dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW)
- priv->MidHighPwrTHR_L1 = (u8)dm_value;
- return;
- if (dm_type == DIG_TYPE_THRESH_HIGH)
- {
- dm_digtable.rssi_high_thresh = dm_value;
- }
- else if (dm_type == DIG_TYPE_THRESH_LOW)
- {
- dm_digtable.rssi_low_thresh = dm_value;
- }
- else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
- {
- dm_digtable.rssi_high_power_highthresh = dm_value;
- }
- else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
- {
- dm_digtable.rssi_high_power_highthresh = dm_value;
- }
- else if (dm_type == DIG_TYPE_ENABLE)
- {
- dm_digtable.dig_state = DM_STA_DIG_MAX;
- dm_digtable.dig_enable_flag = true;
- }
- else if (dm_type == DIG_TYPE_DISABLE)
- {
- dm_digtable.dig_state = DM_STA_DIG_MAX;
- dm_digtable.dig_enable_flag = false;
- }
- else if (dm_type == DIG_TYPE_DBG_MODE)
- {
- if(dm_value >= DM_DBG_MAX)
- dm_value = DM_DBG_OFF;
- dm_digtable.dbg_mode = (u8)dm_value;
- }
- else if (dm_type == DIG_TYPE_RSSI)
- {
- if(dm_value > 100)
- dm_value = 30;
- dm_digtable.rssi_val = (long)dm_value;
- }
- else if (dm_type == DIG_TYPE_ALGORITHM)
- {
- if (dm_value >= DIG_ALGO_MAX)
- dm_value = DIG_ALGO_BY_FALSE_ALARM;
- if(dm_digtable.dig_algorithm != (u8)dm_value)
- dm_digtable.dig_algorithm_switch = 1;
- dm_digtable.dig_algorithm = (u8)dm_value;
- }
- else if (dm_type == DIG_TYPE_BACKOFF)
- {
- if(dm_value > 30)
- dm_value = 30;
- dm_digtable.backoff_val = (u8)dm_value;
- }
- else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
- {
- if(dm_value == 0)
- dm_value = 0x1;
- dm_digtable.rx_gain_range_min = (u8)dm_value;
- }
- else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
- {
- if(dm_value > 0x50)
- dm_value = 0x50;
- dm_digtable.rx_gain_range_max = (u8)dm_value;
- }
-} /* DM_ChangeDynamicInitGainThresh */
-extern void
-dm_change_fsync_setting(
- struct net_device *dev,
- s32 DM_Type,
- s32 DM_Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if (DM_Type == 0) // monitor 0xc38 register
- {
- if(DM_Value > 1)
- DM_Value = 1;
- priv->framesyncMonitor = (u8)DM_Value;
- //DbgPrint("pHalData->framesyncMonitor = %d", pHalData->framesyncMonitor);
- }
-}
-
-extern void
-dm_change_rxpath_selection_setting(
- struct net_device *dev,
- s32 DM_Type,
- s32 DM_Value)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- prate_adaptive pRA = (prate_adaptive)&(priv->rate_adaptive);
-
-
- if(DM_Type == 0)
- {
- if(DM_Value > 1)
- DM_Value = 1;
- DM_RxPathSelTable.Enable = (u8)DM_Value;
- }
- else if(DM_Type == 1)
- {
- if(DM_Value > 1)
- DM_Value = 1;
- DM_RxPathSelTable.DbgMode = (u8)DM_Value;
- }
- else if(DM_Type == 2)
- {
- if(DM_Value > 40)
- DM_Value = 40;
- DM_RxPathSelTable.SS_TH_low = (u8)DM_Value;
- }
- else if(DM_Type == 3)
- {
- if(DM_Value > 25)
- DM_Value = 25;
- DM_RxPathSelTable.diff_TH = (u8)DM_Value;
- }
- else if(DM_Type == 4)
- {
- if(DM_Value >= CCK_Rx_Version_MAX)
- DM_Value = CCK_Rx_Version_1;
- DM_RxPathSelTable.cck_method= (u8)DM_Value;
- }
- else if(DM_Type == 10)
- {
- if(DM_Value > 100)
- DM_Value = 50;
- DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value;
- }
- else if(DM_Type == 11)
- {
- if(DM_Value > 100)
- DM_Value = 50;
- DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value;
- }
- else if(DM_Type == 12)
- {
- if(DM_Value > 100)
- DM_Value = 50;
- DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value;
- }
- else if(DM_Type == 13)
- {
- if(DM_Value > 100)
- DM_Value = 50;
- DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value;
- }
- else if(DM_Type == 20)
- {
- if(DM_Value > 1)
- DM_Value = 1;
- pRA->ping_rssi_enable = (u8)DM_Value;
- }
- else if(DM_Type == 21)
- {
- if(DM_Value > 30)
- DM_Value = 30;
- pRA->ping_rssi_thresh_for_ra = DM_Value;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_dig_init()
- *
- * Overview: Set DIG scheme init value.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/15/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_dig_init(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
- dm_digtable.dig_enable_flag = true;
- dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
- dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
- dm_digtable.dig_algorithm_switch = 0;
-
- /* 2007/10/04 MH Define init gain threshol. */
- dm_digtable.dig_state = DM_STA_DIG_MAX;
- dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
- dm_digtable.initialgain_lowerbound_state = false;
-
- dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
- dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
-
- dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
- dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
-
- dm_digtable.rssi_val = 50; //for new dig debug rssi value
- dm_digtable.backoff_val = DM_DIG_BACKOFF;
- dm_digtable.rx_gain_range_max = DM_DIG_MAX;
- if(priv->CustomerID == RT_CID_819x_Netcore)
- dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
- else
- dm_digtable.rx_gain_range_min = DM_DIG_MIN;
-
-} /* dm_dig_init */
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_ctrl_initgain_byrssi()
- *
- * Overview: Driver must monitor RSSI and notify firmware to change initial
- * gain according to different threshold. BB team provide the
- * suggested solution.
- *
- * Input: struct net_device *dev
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/27/2008 amy Create Version 0 porting from windows code.
- *---------------------------------------------------------------------------*/
-static void dm_ctrl_initgain_byrssi(struct net_device *dev)
-{
-
- if (dm_digtable.dig_enable_flag == false)
- return;
-
- if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
- dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
- else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
- dm_ctrl_initgain_byrssi_by_driverrssi(dev);
-// ;
- else
- return;
-}
-
-
-static void dm_ctrl_initgain_byrssi_by_driverrssi(
- struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 i;
- static u8 fw_dig=0;
-
- if (dm_digtable.dig_enable_flag == false)
- return;
-
- //DbgPrint("Dig by Sw Rssi \n");
- if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig.
- fw_dig = 0;
- if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
- {// FW DIG Off
- for(i=0; i<3; i++)
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
- fw_dig++;
- dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
- }
-
- if(priv->ieee80211->state == IEEE80211_LINKED)
- dm_digtable.cur_connect_state = DIG_CONNECT;
- else
- dm_digtable.cur_connect_state = DIG_DISCONNECT;
-
- //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
- //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
-
- if(dm_digtable.dbg_mode == DM_DBG_OFF)
- dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
- //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
- dm_initial_gain(dev);
- dm_pd_th(dev);
- dm_cs_ratio(dev);
- if(dm_digtable.dig_algorithm_switch)
- dm_digtable.dig_algorithm_switch = 0;
- dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
-
-} /* dm_CtrlInitGainByRssi */
-
-static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
- struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u32 reset_cnt = 0;
- u8 i;
-
- if (dm_digtable.dig_enable_flag == false)
- return;
-
- if(dm_digtable.dig_algorithm_switch)
- {
- dm_digtable.dig_state = DM_STA_DIG_MAX;
- // Fw DIG On.
- for(i=0; i<3; i++)
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
- dm_digtable.dig_algorithm_switch = 0;
- }
-
- if (priv->ieee80211->state != IEEE80211_LINKED)
- return;
-
- // For smooth, we can not change DIG state.
- if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
- (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
- {
- return;
- }
- //DbgPrint("Dig by Fw False Alarm\n");
- //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
- /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
- pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
- DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
- /* 1. When RSSI decrease, We have to judge if it is smaller than a treshold
- and then execute below step. */
- if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
- {
- /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
- will be reset to init value. We must prevent the condition. */
- if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
- (priv->reset_count == reset_cnt))
- {
- return;
- }
- else
- {
- reset_cnt = priv->reset_count;
- }
-
- // If DIG is off, DIG high power state must reset.
- dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
- dm_digtable.dig_state = DM_STA_DIG_OFF;
-
- // 1.1 DIG Off.
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
-
- // 1.2 Set initial gain.
- write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
- write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
- write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
- write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
-
- // 1.3 Lower PD_TH for OFDM.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
- // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
- rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
- */
- //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
-
-
- //else
- //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-
- // 1.4 Lower CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0x08);
-
- // 1.5 Higher EDCCA.
- //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
- return;
-
- }
-
- /* 2. When RSSI increase, We have to judge if it is larger than a treshold
- and then execute below step. */
- if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
- {
- u8 reset_flag = 0;
-
- if (dm_digtable.dig_state == DM_STA_DIG_ON &&
- (priv->reset_count == reset_cnt))
- {
- dm_ctrl_initgain_byrssi_highpwr(dev);
- return;
- }
- else
- {
- if (priv->reset_count != reset_cnt)
- reset_flag = 1;
-
- reset_cnt = priv->reset_count;
- }
-
- dm_digtable.dig_state = DM_STA_DIG_ON;
- //DbgPrint("DIG ON\n\r");
-
- // 2.1 Set initial gain.
- // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
- if (reset_flag == 1)
- {
- write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
- write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
- write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
- write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
- }
- else
- {
- write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
- write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
- write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
- write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
- }
-
- // 2.2 Higher PD_TH for OFDM.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
- // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- #else
- write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
- #endif
- /*
- else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- */
- //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
-
- //else
- //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
-
- // 2.3 Higher CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0xcd);
-
- // 2.4 Lower EDCCA.
- /* 2008/01/11 MH 90/92 series are the same. */
- //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
-
- // 2.5 DIG On.
- rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
-
- }
-
- dm_ctrl_initgain_byrssi_highpwr(dev);
-
-} /* dm_CtrlInitGainByRssi */
-
-
-/*-----------------------------------------------------------------------------
- * Function: dm_ctrl_initgain_byrssi_highpwr()
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_ctrl_initgain_byrssi_highpwr(
- struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u32 reset_cnt_highpwr = 0;
-
- // For smooth, we can not change high power DIG state in the range.
- if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
- (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
- {
- return;
- }
-
- /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
- it is larger than a treshold and then execute below step. */
- // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
- if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
- {
- if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
- (priv->reset_count == reset_cnt_highpwr))
- return;
- else
- dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
-
- // 3.1 Higher PD_TH for OFDM for high power state.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x10);
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
- */
-
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
- }
- else
- {
- if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
- (priv->reset_count == reset_cnt_highpwr))
- return;
- else
- dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
-
- if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
- priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
- {
- // 3.2 Recover PD_TH for OFDM for normal power region.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- #else
- write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
- #endif
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- */
-
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
- }
- }
-
- reset_cnt_highpwr = priv->reset_count;
-
-} /* dm_CtrlInitGainByRssiHighPwr */
-
-
-static void dm_initial_gain(
- struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 initial_gain=0;
- static u8 initialized=0, force_write=0;
- static u32 reset_cnt=0;
-
- if(dm_digtable.dig_algorithm_switch)
- {
- initialized = 0;
- reset_cnt = 0;
- }
-
- if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
- {
- if(dm_digtable.cur_connect_state == DIG_CONNECT)
- {
- if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
- dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
- else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
- dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
- else
- dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
- }
- else //current state is disconnected
- {
- if(dm_digtable.cur_ig_value == 0)
- dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
- else
- dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
- }
- }
- else // disconnected -> connected or connected -> disconnected
- {
- dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
- dm_digtable.pre_ig_value = 0;
- }
- //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
-
- // if silent reset happened, we should rewrite the values back
- if(priv->reset_count != reset_cnt)
- {
- force_write = 1;
- reset_cnt = priv->reset_count;
- }
-
- if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
- force_write = 1;
-
- {
- if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
- || !initialized || force_write)
- {
- initial_gain = (u8)dm_digtable.cur_ig_value;
- //DbgPrint("Write initial gain = 0x%x\n", initial_gain);
- // Set initial gain.
- write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
- write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
- dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
- initialized = 1;
- force_write = 0;
- }
- }
-}
-
-static void dm_pd_th(
- struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u8 initialized=0, force_write=0;
- static u32 reset_cnt = 0;
-
- if(dm_digtable.dig_algorithm_switch)
- {
- initialized = 0;
- reset_cnt = 0;
- }
-
- if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
- {
- if(dm_digtable.cur_connect_state == DIG_CONNECT)
- {
- if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
- dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
- else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
- dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
- else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
- (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
- dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
- else
- dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
- }
- else
- {
- dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
- }
- }
- else // disconnected -> connected or connected -> disconnected
- {
- dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
- }
-
- // if silent reset happened, we should rewrite the values back
- if(priv->reset_count != reset_cnt)
- {
- force_write = 1;
- reset_cnt = priv->reset_count;
- }
-
- {
- if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
- (initialized<=3) || force_write)
- {
- //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
- if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
- {
- // Lower PD_TH for OFDM.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
- // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
- rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
- */
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- }
- else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
- {
- // Higher PD_TH for OFDM.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
- // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- #else
- write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
- #endif
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
- */
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
- }
- else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
- {
- // Higher PD_TH for OFDM for high power state.
- if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
- {
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
- #else
- write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
- #endif
- /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
- */
- }
- else
- write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
- }
- dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
- if(initialized <= 3)
- initialized++;
- force_write = 0;
- }
- }
-}
-
-static void dm_cs_ratio(
- struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- static u8 initialized=0,force_write=0;
- static u32 reset_cnt = 0;
-
- if(dm_digtable.dig_algorithm_switch)
- {
- initialized = 0;
- reset_cnt = 0;
- }
-
- if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
- {
- if(dm_digtable.cur_connect_state == DIG_CONNECT)
- {
- if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
- else
- dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
- }
- else
- {
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- }
- }
- else // disconnected -> connected or connected -> disconnected
- {
- dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
- }
-
- // if silent reset happened, we should rewrite the values back
- if(priv->reset_count != reset_cnt)
- {
- force_write = 1;
- reset_cnt = priv->reset_count;
- }
-
-
- {
- if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
- !initialized || force_write)
- {
- //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
- if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
- {
- // Lower CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0x08);
- }
- else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
- {
- // Higher CS ratio for CCK.
- write_nic_byte(dev, 0xa0a, 0xcd);
- }
- dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
- initialized = 1;
- force_write = 0;
- }
- }
-}
-
-extern void dm_init_edca_turbo(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->bcurrent_turbo_EDCA = false;
- priv->ieee80211->bis_any_nonbepkts = false;
- priv->bis_cur_rdlstate = false;
-} // dm_init_edca_turbo
-
-#if 1
-static void dm_check_edca_turbo(
- struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
-
- // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
- static unsigned long lastTxOkCnt = 0;
- static unsigned long lastRxOkCnt = 0;
- unsigned long curTxOkCnt = 0;
- unsigned long curRxOkCnt = 0;
-
- u32 EDCA_BE_UL = edca_setting_UL[pHTInfo->IOTPeer];
- u32 EDCA_BE_DL = edca_setting_DL[pHTInfo->IOTPeer];
- #if 1
- if(priv->ieee80211->state != IEEE80211_LINKED)
- goto dm_CheckEdcaTurbo_EXIT;
- #endif
- // We do not turn on EDCA turbo mode for some AP that has IOT issue
- if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
- goto dm_CheckEdcaTurbo_EXIT;
-
- if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_FORCED_ENABLE_BE_TXOP)
- {
- if(!(EDCA_BE_UL & 0xffff0000))
- EDCA_BE_UL |= 0x005e0000;
- if(!(EDCA_BE_DL & 0xffff0000))
- EDCA_BE_DL |= 0x005e0000;
- }
-
- {
- u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
- static int wb_tmp = 0;
- if (wb_tmp == 0){
- printk("%s():iot peer is %#x:%s, bssid:%pM\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], priv->ieee80211->current_network.bssid);
- wb_tmp = 1;
- }
- }
- // Check the status for current condition.
- if(!priv->ieee80211->bis_any_nonbepkts)
- {
- curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
- curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
- // Modify EDCA parameters selection bias
- // For some APs, use downlink EDCA parameters for uplink+downlink
- if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX)
- {
- if(curTxOkCnt > 4*curRxOkCnt)
- {
- if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
- {
- write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_UL);
- priv->bis_cur_rdlstate = false;
- }
- }
- else
- {
- if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
- {
- write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_DL);
- priv->bis_cur_rdlstate = true;
- }
- }
- priv->bcurrent_turbo_EDCA = true;
- }
- else
- {
- if(curRxOkCnt > 4*curTxOkCnt)
- {
- if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
- {
- write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_DL);
- priv->bis_cur_rdlstate = true;
- }
- }
- else
- {
- if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
- {
- write_nic_dword(dev, EDCAPARA_BE, EDCA_BE_UL);
- priv->bis_cur_rdlstate = false;
- }
- }
- priv->bcurrent_turbo_EDCA = true;
- }
- }
- else
- {
- //
- // Turn Off EDCA turbo here.
- // Restore original EDCA according to the declaration of AP.
- //
- if(priv->bcurrent_turbo_EDCA)
- {
-
- {
- u8 u1bAIFS;
- u32 u4bAcParam;
- struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
- u8 mode = priv->ieee80211->mode;
-
- // For Each time updating EDCA parameter, reset EDCA turbo mode status.
- dm_init_edca_turbo(dev);
- u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
- u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
- (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
- (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
- ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-
- write_nic_dword(dev, EDCAPARA_BE, u4bAcParam);
-
- // Check ACM bit.
- // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
- {
- // TODO: Modified this part and try to set acm control in only 1 IO processing!!
-
- PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
- u8 AcmCtrl = priv->AcmControl | 0x1;
- if( pAciAifsn->f.ACM )
- { // ACM bit is 1.
- AcmCtrl |= AcmHw_BeqEn;
- }
- else
- { // ACM bit is 0.
- AcmCtrl &= (~AcmHw_BeqEn);
- }
-
- RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
- write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
- }
- }
- priv->bcurrent_turbo_EDCA = false;
- }
- }
-
-
-dm_CheckEdcaTurbo_EXIT:
- // Set variables for next time.
- priv->ieee80211->bis_any_nonbepkts = false;
- lastTxOkCnt = priv->stats.txbytesunicast;
- lastRxOkCnt = priv->stats.rxbytesunicast;
-}
-#endif
-
-extern void DM_CTSToSelfSetting(struct net_device * dev,u32 DM_Type, u32 DM_Value)
-{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-
- if (DM_Type == 0) // CTS to self disable/enable
- {
- if(DM_Value > 1)
- DM_Value = 1;
- priv->ieee80211->bCTSToSelfEnable = (bool)DM_Value;
- //DbgPrint("pMgntInfo->bCTSToSelfEnable = %d\n", pMgntInfo->bCTSToSelfEnable);
- }
- else if(DM_Type == 1) //CTS to self Th
- {
- if(DM_Value >= 50)
- DM_Value = 50;
- priv->ieee80211->CTSToSelfTH = (u8)DM_Value;
- //DbgPrint("pMgntInfo->CTSToSelfTH = %d\n", pMgntInfo->CTSToSelfTH);
- }
-}
-
-static void dm_init_ctstoself(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-
- priv->ieee80211->bCTSToSelfEnable = TRUE;
- priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
-}
-
-static void dm_ctstoself(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
- PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
- static unsigned long lastTxOkCnt = 0;
- static unsigned long lastRxOkCnt = 0;
- unsigned long curTxOkCnt = 0;
- unsigned long curRxOkCnt = 0;
-
- if(priv->ieee80211->bCTSToSelfEnable != TRUE)
- {
- pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
- return;
- }
- /*
- 1. Uplink
- 2. Linksys350/Linksys300N
- 3. <50 disable, >55 enable
- */
-
- if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
- {
- curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
- curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
- if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self
- {
- pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
- //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
- }
- else //uplink
- {
- #if 1
- pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
- #else
- if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH) // disable CTS to self
- {
- pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
- //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n");
- }
- else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5)) // enable CTS to self
- {
- pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
- //DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n");
- }
- #endif
- }
-
- lastTxOkCnt = priv->stats.txbytesunicast;
- lastRxOkCnt = priv->stats.rxbytesunicast;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rfctrl_gpio()
- *
- * Overview: Copy 8187B template for 9xseries.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-#if 1
-static void dm_check_rfctrl_gpio(struct net_device * dev)
-{
- //struct r8192_priv *priv = ieee80211_priv(dev);
-
- // Walk around for DTM test, we will not enable HW - radio on/off because r/w
- // page 1 register before Lextra bus is enabled cause system fails when resuming
- // from S4. 20080218, Emily
-
- // Stop to execute workitem to prevent S3/S4 bug.
-#ifdef RTL8190P
- return;
-#endif
-#ifdef RTL8192U
- return;
-#endif
- return;
-#ifdef RTL8192E
- queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
-#endif
-
-} /* dm_CheckRfCtrlGPIO */
-
-#endif
-/*-----------------------------------------------------------------------------
- * Function: dm_check_pbc_gpio()
- *
- * Overview: Check if PBC button is pressed.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_pbc_gpio(struct net_device *dev)
-{
-#ifdef RTL8192U
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 tmp1byte;
-
-
- tmp1byte = read_nic_byte(dev,GPI);
- if(tmp1byte == 0xff)
- return;
-
- if (tmp1byte&BIT6 || tmp1byte&BIT0)
- {
- // Here we only set bPbcPressed to TRUE
- // After trigger PBC, the variable will be set to FALSE
- RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
- priv->bpbc_pressed = true;
- }
-#endif
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 tmp1byte;
-
- write_nic_byte(dev, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
-
- tmp1byte = read_nic_byte(dev, GPIO_IO_SEL);
- tmp1byte &= ~(HAL_8192S_HW_GPIO_WPS_BIT);
- write_nic_byte(dev, GPIO_IO_SEL, tmp1byte);
-
- tmp1byte = read_nic_byte(dev, GPIO_IN);
-
- RT_TRACE(COMP_IO, "CheckPbcGPIO - %x\n", tmp1byte);
-
- // Add by hpfan 2008.07.07 to fix read GPIO error from S3
- if (tmp1byte == 0xff)
- return ;
-
- if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT)
- {
- // Here we only set bPbcPressed to TRUE
- // After trigger PBC, the variable will be set to FALSE
- RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
- priv->bpbc_pressed = true;
- }
-
-
-
-}
-
-#ifdef RTL8192E
-
-/*-----------------------------------------------------------------------------
- * Function: dm_GPIOChangeRF
- * Overview: PCI will not support workitem call back HW radio on-off control.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 02/21/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void dm_gpio_change_rf_callback(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
- struct net_device *dev = priv->ieee80211->dev;
- u8 tmp1byte;
- RT_RF_POWER_STATE eRfPowerStateToSet;
- bool bActuallySet = false;
-
- do{
- bActuallySet=false;
-
- if(!priv->up)
- {
- RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
- }
- else
- {
- // 0x108 GPIO input register is read only
- //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
- tmp1byte = read_nic_byte(dev,GPI);
-
- eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
-
- if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
- {
- RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
-
- priv->bHwRadioOff = false;
- bActuallySet = true;
- }
- else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
- {
- RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
- priv->bHwRadioOff = true;
- bActuallySet = true;
- }
-
- if(bActuallySet)
- {
- #ifdef TO_DO
- MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
- //DrvIFIndicateCurrentPhyStatus(pAdapter);
- #endif
- }
- else
- {
- msleep(2000);
- }
-
- }
- }while(TRUE)
-
-} /* dm_GPIOChangeRF */
-
-#endif
-/*-----------------------------------------------------------------------------
- * Function: DM_RFPathCheckWorkItemCallBack()
- *
- * Overview: Check if Current RF RX path is enabled
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 01/30/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
- struct net_device *dev =priv->ieee80211->dev;
- //bool bactually_set = false;
- u8 rfpath = 0, i;
-
-
- /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
- always be the same. We only read 0xc04 now. */
- rfpath = read_nic_byte(dev, 0xc04);
-
- // Check Bit 0-3, it means if RF A-D is enabled.
- for (i = 0; i < RF90_PATH_MAX; i++)
- {
- if (rfpath & (0x01<<i))
- priv->brfpath_rxenable[i] = 1;
- else
- priv->brfpath_rxenable[i] = 0;
- }
- if(!DM_RxPathSelTable.Enable)
- return;
-
- dm_rxpath_sel_byrssi(dev);
-} /* DM_RFPathCheckWorkItemCallBack */
-
-static void dm_init_rxpath_selection(struct net_device * dev)
-{
- u8 i;
- struct r8192_priv *priv = ieee80211_priv(dev);
- DM_RxPathSelTable.Enable = 1; //default enabled
- DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
- DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
- if(priv->CustomerID == RT_CID_819x_Netcore)
- DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
- else
- DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
- DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
- DM_RxPathSelTable.disabledRF = 0;
- for(i=0; i<4; i++)
- {
- DM_RxPathSelTable.rf_rssi[i] = 50;
- DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
- DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
- }
-}
-
-static void dm_rxpath_sel_byrssi(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
- u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
- u8 cck_default_Rx=0x2; //RF-C
- u8 cck_optional_Rx=0x3;//RF-D
- long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
- u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
- u8 cur_rf_rssi;
- long cur_cck_pwdb;
- static u8 disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
- u8 update_cck_rx_path;
-
- if(priv->rf_type != RF_2T4R)
- return;
-
- if(!cck_Rx_Path_initialized)
- {
- DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
- cck_Rx_Path_initialized = 1;
- }
-
- DM_RxPathSelTable.disabledRF = 0xf;
- DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
-
- if(priv->ieee80211->mode == WIRELESS_MODE_B)
- {
- DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2
- //DbgPrint("Pure B mode, use cck rx version2 \n");
- }
-
- //decide max/sec/min rssi index
- for (i=0; i<RF90_PATH_MAX; i++)
- {
- if(!DM_RxPathSelTable.DbgMode)
- DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
-
- if(priv->brfpath_rxenable[i])
- {
- rf_num++;
- cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
-
- if(rf_num == 1) // find first enabled rf path and the rssi values
- { //initialize, set all rssi index to the same one
- max_rssi_index = min_rssi_index = sec_rssi_index = i;
- tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
- }
- else if(rf_num == 2)
- { // we pick up the max index first, and let sec and min to be the same one
- if(cur_rf_rssi >= tmp_max_rssi)
- {
- tmp_max_rssi = cur_rf_rssi;
- max_rssi_index = i;
- }
- else
- {
- tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
- sec_rssi_index = min_rssi_index = i;
- }
- }
- else
- {
- if(cur_rf_rssi > tmp_max_rssi)
- {
- tmp_sec_rssi = tmp_max_rssi;
- sec_rssi_index = max_rssi_index;
- tmp_max_rssi = cur_rf_rssi;
- max_rssi_index = i;
- }
- else if(cur_rf_rssi == tmp_max_rssi)
- { // let sec and min point to the different index
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- }
- else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
- {
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- }
- else if(cur_rf_rssi == tmp_sec_rssi)
- {
- if(tmp_sec_rssi == tmp_min_rssi)
- { // let sec and min point to the different index
- tmp_sec_rssi = cur_rf_rssi;
- sec_rssi_index = i;
- }
- else
- {
- // This case we don't need to set any index
- }
- }
- else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
- {
- // This case we don't need to set any index
- }
- else if(cur_rf_rssi == tmp_min_rssi)
- {
- if(tmp_sec_rssi == tmp_min_rssi)
- { // let sec and min point to the different index
- tmp_min_rssi = cur_rf_rssi;
- min_rssi_index = i;
- }
- else
- {
- // This case we don't need to set any index
- }
- }
- else if(cur_rf_rssi < tmp_min_rssi)
- {
- tmp_min_rssi = cur_rf_rssi;
- min_rssi_index = i;
- }
- }
- }
- }
-
- rf_num = 0;
- // decide max/sec/min cck pwdb index
- if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
- {
- for (i=0; i<RF90_PATH_MAX; i++)
- {
- if(priv->brfpath_rxenable[i])
- {
- rf_num++;
- cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i];
-
- if(rf_num == 1) // find first enabled rf path and the rssi values
- { //initialize, set all rssi index to the same one
- cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
- tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
- }
- else if(rf_num == 2)
- { // we pick up the max index first, and let sec and min to be the same one
- if(cur_cck_pwdb >= tmp_cck_max_pwdb)
- {
- tmp_cck_max_pwdb = cur_cck_pwdb;
- cck_rx_ver2_max_index = i;
- }
- else
- {
- tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
- }
- }
- else
- {
- if(cur_cck_pwdb > tmp_cck_max_pwdb)
- {
- tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
- cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
- tmp_cck_max_pwdb = cur_cck_pwdb;
- cck_rx_ver2_max_index = i;
- }
- else if(cur_cck_pwdb == tmp_cck_max_pwdb)
- { // let sec and min point to the different index
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- }
- else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
- {
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- }
- else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
- {
- if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
- { // let sec and min point to the different index
- tmp_cck_sec_pwdb = cur_cck_pwdb;
- cck_rx_ver2_sec_index = i;
- }
- else
- {
- // This case we don't need to set any index
- }
- }
- else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
- {
- // This case we don't need to set any index
- }
- else if(cur_cck_pwdb == tmp_cck_min_pwdb)
- {
- if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
- { // let sec and min point to the different index
- tmp_cck_min_pwdb = cur_cck_pwdb;
- cck_rx_ver2_min_index = i;
- }
- else
- {
- // This case we don't need to set any index
- }
- }
- else if(cur_cck_pwdb < tmp_cck_min_pwdb)
- {
- tmp_cck_min_pwdb = cur_cck_pwdb;
- cck_rx_ver2_min_index = i;
- }
- }
-
- }
- }
- }
-
-
- // Set CCK Rx path
- // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
- update_cck_rx_path = 0;
- if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
- {
- cck_default_Rx = cck_rx_ver2_max_index;
- cck_optional_Rx = cck_rx_ver2_sec_index;
- if(tmp_cck_max_pwdb != -64)
- update_cck_rx_path = 1;
- }
-
- if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
- {
- if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
- {
- //record the enabled rssi threshold
- DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
- //disable the BB Rx path, OFDM
- rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0]
- rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0]
- disabled_rf_cnt++;
- }
- if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
- {
- cck_default_Rx = max_rssi_index;
- cck_optional_Rx = sec_rssi_index;
- if(tmp_max_rssi)
- update_cck_rx_path = 1;
- }
- }
-
- if(update_cck_rx_path)
- {
- DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
- rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
- }
-
- if(DM_RxPathSelTable.disabledRF)
- {
- for(i=0; i<4; i++)
- {
- if((DM_RxPathSelTable.disabledRF>>i) & 0x1) //disabled rf
- {
- if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
- {
- //enable the BB Rx path
- //DbgPrint("RF-%d is enabled. \n", 0x1<<i);
- rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); // 0xc04[3:0]
- rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); // 0xd04[3:0]
- DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
- disabled_rf_cnt--;
- }
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_check_rx_path_selection()
- *
- * Overview: Call a workitem to check current RXRF path and Rx Path selection by RSSI.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/28/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_rx_path_selection(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
-} /* dm_CheckRxRFPath */
-
-
-static void dm_init_fsync (struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- priv->ieee80211->fsync_time_interval = 500;
- priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
- priv->ieee80211->fsync_rssi_threshold = 30;
-#ifdef RTL8190P
- priv->ieee80211->bfsync_enable = true;
-#else
- priv->ieee80211->bfsync_enable = false;
-#endif
- priv->ieee80211->fsync_multiple_timeinterval = 3;
- priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
- priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
- priv->ieee80211->fsync_state = Default_Fsync;
- priv->framesyncMonitor = 1; // current default 0xc38 monitor on
-
- init_timer(&priv->fsync_timer);
- priv->fsync_timer.data = (unsigned long)dev;
- priv->fsync_timer.function = dm_fsync_timer_callback;
-}
-
-
-static void dm_deInit_fsync(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- del_timer_sync(&priv->fsync_timer);
-}
-
-extern void dm_fsync_timer_callback(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
- u32 rate_index, rate_count = 0, rate_count_diff=0;
- bool bSwitchFromCountDiff = false;
- bool bDoubleTimeInterval = false;
-
- if( priv->ieee80211->state == IEEE80211_LINKED &&
- priv->ieee80211->bfsync_enable &&
- (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
- {
- // Count rate 54, MCS [7], [12, 13, 14, 15]
- u32 rate_bitmap;
- for(rate_index = 0; rate_index <= 27; rate_index++)
- {
- rate_bitmap = 1 << rate_index;
- if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap)
- rate_count+= priv->stats.received_rate_histogram[1][rate_index];
- }
-
- if(rate_count < priv->rate_record)
- rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
- else
- rate_count_diff = rate_count - priv->rate_record;
- if(rate_count_diff < priv->rateCountDiffRecord)
- {
-
- u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
- // Contiune count
- if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
- priv->ContiuneDiffCount++;
- else
- priv->ContiuneDiffCount = 0;
-
- // Contiune count over
- if(priv->ContiuneDiffCount >=2)
- {
- bSwitchFromCountDiff = true;
- priv->ContiuneDiffCount = 0;
- }
- }
- else
- {
- // Stop contiune count
- priv->ContiuneDiffCount = 0;
- }
-
- //If Count diff <= FsyncRateCountThreshold
- if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
- {
- bSwitchFromCountDiff = true;
- priv->ContiuneDiffCount = 0;
- }
- priv->rate_record = rate_count;
- priv->rateCountDiffRecord = rate_count_diff;
- RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
- // if we never receive those mcs rate and rssi > 30 % then switch fsyn
- if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
- {
- bDoubleTimeInterval = true;
- priv->bswitch_fsync = !priv->bswitch_fsync;
- if(priv->bswitch_fsync)
- {
- #ifdef RTL8190P
- write_nic_byte(dev, 0xC36, 0x00);
- #else
- write_nic_byte(dev,0xC36, 0x1c);
- #endif
- write_nic_byte(dev, 0xC3e, 0x90);
- }
- else
- {
- #ifdef RTL8190P
- write_nic_byte(dev, 0xC36, 0x40);
- #else
- write_nic_byte(dev, 0xC36, 0x5c);
- #endif
- write_nic_byte(dev, 0xC3e, 0x96);
- }
- }
- else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
- {
- if(priv->bswitch_fsync)
- {
- priv->bswitch_fsync = false;
- #ifdef RTL8190P
- write_nic_byte(dev, 0xC36, 0x40);
- #else
- write_nic_byte(dev, 0xC36, 0x5c);
- #endif
- write_nic_byte(dev, 0xC3e, 0x96);
- }
- }
- if(bDoubleTimeInterval){
- if(timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
- add_timer(&priv->fsync_timer);
- }
- else{
- if(timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
- add_timer(&priv->fsync_timer);
- }
- }
- else
- {
- // Let Register return to default value;
- if(priv->bswitch_fsync)
- {
- priv->bswitch_fsync = false;
- #ifdef RTL8190P
- write_nic_byte(dev, 0xC36, 0x40);
- #else
- write_nic_byte(dev, 0xC36, 0x5c);
- #endif
- write_nic_byte(dev, 0xC3e, 0x96);
- }
- priv->ContiuneDiffCount = 0;
- rtl8192_setBBreg(dev, rOFDM0_RxDetector2, bMaskDWord, 0x164052cd);
- }
- RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
- RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
-}
-
-static void dm_StartHWFsync(struct net_device *dev)
-{
- RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
- write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
- write_nic_byte(dev, 0xc3b, 0x41);
-}
-
-static void dm_EndSWFsync(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
- del_timer_sync(&(priv->fsync_timer));
-
- // Let Register return to default value;
- if(priv->bswitch_fsync)
- {
- priv->bswitch_fsync = false;
-
- #ifdef RTL8190P
- write_nic_byte(dev, 0xC36, 0x40);
- #else
- write_nic_byte(dev, 0xC36, 0x5c);
- #endif
-
- write_nic_byte(dev, 0xC3e, 0x96);
- }
-
- priv->ContiuneDiffCount = 0;
-#ifndef RTL8190P
- write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-#endif
-
-}
-
-static void dm_StartSWFsync(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 rateIndex;
- u32 rateBitmap;
-
- RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
- // Initial rate record to zero, start to record.
- priv->rate_record = 0;
- // Initial contiune diff count to zero, start to record.
- priv->ContiuneDiffCount = 0;
- priv->rateCountDiffRecord = 0;
- priv->bswitch_fsync = false;
-
- if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
- {
- priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
- priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
- }
- else
- {
- priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
- priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
- }
- for(rateIndex = 0; rateIndex <= 27; rateIndex++)
- {
- rateBitmap = 1 << rateIndex;
- if(priv->ieee80211->fsync_rate_bitmap & rateBitmap)
- priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
- }
- if(timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
- add_timer(&priv->fsync_timer);
-
-#ifndef RTL8190P
- write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
-#endif
-
-}
-
-static void dm_EndHWFsync(struct net_device *dev)
-{
- RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
- write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
- write_nic_byte(dev, 0xc3b, 0x49);
-
-}
-
-void dm_check_fsync(struct net_device *dev)
-{
-#define RegC38_Default 0
-#define RegC38_NonFsync_Other_AP 1
-#define RegC38_Fsync_AP_BCM 2
- struct r8192_priv *priv = ieee80211_priv(dev);
- //u32 framesyncC34;
- static u8 reg_c38_State=RegC38_Default;
- static u32 reset_cnt=0;
-
- RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
- RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
-
- if( priv->ieee80211->state == IEEE80211_LINKED &&
- (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
- {
- if(priv->ieee80211->bfsync_enable == 0)
- {
- switch(priv->ieee80211->fsync_state)
- {
- case Default_Fsync:
- dm_StartHWFsync(dev);
- priv->ieee80211->fsync_state = HW_Fsync;
- break;
- case SW_Fsync:
- dm_EndSWFsync(dev);
- dm_StartHWFsync(dev);
- priv->ieee80211->fsync_state = HW_Fsync;
- break;
- case HW_Fsync:
- default:
- break;
- }
- }
- else
- {
- switch(priv->ieee80211->fsync_state)
- {
- case Default_Fsync:
- dm_StartSWFsync(dev);
- priv->ieee80211->fsync_state = SW_Fsync;
- break;
- case HW_Fsync:
- dm_EndHWFsync(dev);
- dm_StartSWFsync(dev);
- priv->ieee80211->fsync_state = SW_Fsync;
- break;
- case SW_Fsync:
- default:
- break;
-
- }
- }
- if(priv->framesyncMonitor)
- {
- if(reg_c38_State != RegC38_Fsync_AP_BCM)
- { //For broadcom AP we write different default value
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
- #else
- write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
- #endif
-
- reg_c38_State = RegC38_Fsync_AP_BCM;
- }
- }
- }
- else
- {
- switch(priv->ieee80211->fsync_state)
- {
- case HW_Fsync:
- dm_EndHWFsync(dev);
- priv->ieee80211->fsync_state = Default_Fsync;
- break;
- case SW_Fsync:
- dm_EndSWFsync(dev);
- priv->ieee80211->fsync_state = Default_Fsync;
- break;
- case Default_Fsync:
- default:
- break;
- }
-
- if(priv->framesyncMonitor)
- {
- if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
- {
- if(reg_c38_State != RegC38_NonFsync_Other_AP)
- {
- #ifdef RTL8190P
- write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
- #else
- write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
- #endif
-
- reg_c38_State = RegC38_NonFsync_Other_AP;
- }
- }
- else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
- {
- if(reg_c38_State)
- {
- write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
- reg_c38_State = RegC38_Default;
- //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
- }
- }
- }
- else
- {
- if(reg_c38_State)
- {
- write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
- reg_c38_State = RegC38_Default;
- //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
- }
- }
- }
- }
- if(priv->framesyncMonitor)
- {
- if(priv->reset_count != reset_cnt)
- { //After silent reset, the reg_c38_State will be returned to default value
- write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
- reg_c38_State = RegC38_Default;
- reset_cnt = priv->reset_count;
- //DbgPrint("reg_c38_State = 0 for silent reset. \n");
- }
- }
- else
- {
- if(reg_c38_State)
- {
- write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
- reg_c38_State = RegC38_Default;
- //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: dm_shadow_init()
- *
- * Overview: Store all NIC MAC/BB register content.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/29/2008 amy Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-extern void dm_shadow_init(struct net_device *dev)
-{
- u8 page;
- u16 offset;
-
- for (page = 0; page < 5; page++)
- for (offset = 0; offset < 256; offset++)
- {
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
- //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
- }
-
- for (page = 8; page < 11; page++)
- for (offset = 0; offset < 256; offset++)
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
-
- for (page = 12; page < 15; page++)
- for (offset = 0; offset < 256; offset++)
- dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
-
-} /* dm_shadow_init */
-
-/*---------------------------Define function prototype------------------------*/
-/*-----------------------------------------------------------------------------
- * Function: DM_DynamicTxPower()
- *
- * Overview: Detect Signal strength to control TX Registry
- Tx Power Control For Near/Far Range
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 03/06/2008 Jacken Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void dm_init_dynamic_txpower(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
- priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control
- priv->bLastDTPFlag_High = false;
- priv->bLastDTPFlag_Low = false;
- priv->bDynamicTxHighPower = false;
- priv->bDynamicTxLowPower = false;
-}
-
-static void dm_dynamic_txpower(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- unsigned int txhipower_threshhold=0;
- unsigned int txlowpower_threshold=0;
- if(priv->ieee80211->bdynamic_txpower_enable != true)
- {
- priv->bDynamicTxHighPower = false;
- priv->bDynamicTxLowPower = false;
- return;
- }
- //printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
- if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
- txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
- txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
- }
- else
- {
- txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
- txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
- }
-
-// printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
- RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
-
- if(priv->ieee80211->state == IEEE80211_LINKED)
- {
- if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
- {
- priv->bDynamicTxHighPower = true;
- priv->bDynamicTxLowPower = false;
- }
- else
- {
- // high power state check
- if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
- {
- priv->bDynamicTxHighPower = false;
- }
- // low power state check
- if(priv->undecorated_smoothed_pwdb < 35)
- {
- priv->bDynamicTxLowPower = true;
- }
- else if(priv->undecorated_smoothed_pwdb >= 40)
- {
- priv->bDynamicTxLowPower = false;
- }
- }
- }
- else
- {
- //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
- priv->bDynamicTxHighPower = false;
- priv->bDynamicTxLowPower = false;
- }
-
- if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
- (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
- {
- RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190() channel = %d \n" , priv->ieee80211->current_network.channel);
- }
- priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
- priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
-
-} /* dm_dynamic_txpower */
-
-//added by vivi, for read tx rate and retrycount
-static void dm_check_txrateandretrycount(struct net_device * dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- //for 11n tx rate
-// priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
- ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, TX_RATE_REG);
- //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
- //for initial tx rate
-// priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
- ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
- //for tx tx retry count
-// priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
- ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
-}
-
-static void dm_send_rssi_tofw(struct net_device *dev)
-{
-}
-
-#ifdef TO_DO_LIST
-static void
-dm_CheckProtection(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
- u8 CurRate;
-
- if(priv->ieee80211->pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_FORCED_CTS2SELF))
- {
- CurRate = read_nic_byte(dev, INIMCS_SEL);
- if(CurRate <= DESC92S_RATE11M)
- priv->bDmDisableProtect = true;
- else
- priv->bDmDisableProtect = fasle;
- }
-}
-#endif
-
-/*---------------------------Define function prototype------------------------*/
-
diff --git a/drivers/staging/rtl8192su/r8192U_dm.h b/drivers/staging/rtl8192su/r8192U_dm.h
deleted file mode 100644
index 1b48436ce1ad..000000000000
--- a/drivers/staging/rtl8192su/r8192U_dm.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*****************************************************************************
- * Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved.
- *
- * Module: Hal819xUsbDM.h (RTL8192 Header H File)
- *
- *
- * Note: For dynamic control definition constant structure.
- *
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- * 10/04/2007 MHC Create initial version.
- *
- *****************************************************************************/
- /* Check to see if the file has been included already. */
-#ifndef __R8192UDM_H__
-#define __R8192UDM_H__
-
-
-/*--------------------------Define Parameters-------------------------------*/
-#define DM_DIG_THRESH_HIGH 40
-#define DM_DIG_THRESH_LOW 35
-
-#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
-#define DM_DIG_HIGH_PWR_THRESH_LOW 70
-
-#define BW_AUTO_SWITCH_HIGH_LOW 25
-#define BW_AUTO_SWITCH_LOW_HIGH 30
-
-#define DM_check_fsync_time_interval 500
-
-
-#define DM_DIG_BACKOFF 12
-#define DM_DIG_MAX 0x36
-#define DM_DIG_MIN 0x1c
-#define DM_DIG_MIN_Netcore 0x12
-
-#define RxPathSelection_SS_TH_low 30
-#define RxPathSelection_diff_TH 18
-
-#define RateAdaptiveTH_High 50
-#define RateAdaptiveTH_Low_20M 30
-#define RateAdaptiveTH_Low_40M 10
-#define VeryLowRSSI 15
-#define CTSToSelfTHVal 30
-
-//defined by vivi, for tx power track
-#define E_FOR_TX_POWER_TRACK 300
-//Dynamic Tx Power Control Threshold
-#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68
-#define TX_POWER_NEAR_FIELD_THRESH_LOW 62
-//added by amy for atheros AP
-#define TX_POWER_ATHEROAP_THRESH_HIGH 78
-#define TX_POWER_ATHEROAP_THRESH_LOW 72
-
-//defined by vivi, for showing on UI
-#define Current_Tx_Rate_Reg 0x1b8
-#define Initial_Tx_Rate_Reg 0x1b9
-#define Tx_Retry_Count_Reg 0x1ac
-#define RegC38_TH 20
-/*--------------------------Define Parameters-------------------------------*/
-
-
-/*------------------------------Define structure----------------------------*/
-/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */
-typedef struct _dynamic_initial_gain_threshold_
-{
- u8 dig_enable_flag;
- u8 dig_algorithm;
- u8 dbg_mode;
- u8 dig_algorithm_switch;
-
- long rssi_low_thresh;
- long rssi_high_thresh;
-
- long rssi_high_power_lowthresh;
- long rssi_high_power_highthresh;
-
- u8 dig_state;
- u8 dig_highpwr_state;
- u8 cur_connect_state;
- u8 pre_connect_state;
-
- u8 curpd_thstate;
- u8 prepd_thstate;
- u8 curcs_ratio_state;
- u8 precs_ratio_state;
-
- u32 pre_ig_value;
- u32 cur_ig_value;
-
- u8 backoff_val;
- u8 rx_gain_range_max;
- u8 rx_gain_range_min;
- bool initialgain_lowerbound_state;
-
- long rssi_val;
-}dig_t;
-
-typedef enum tag_dynamic_init_gain_state_definition
-{
- DM_STA_DIG_OFF = 0,
- DM_STA_DIG_ON,
- DM_STA_DIG_MAX
-}dm_dig_sta_e;
-
-
-/* 2007/10/08 MH Define RATR state. */
-typedef enum tag_dynamic_ratr_state_definition
-{
- DM_RATR_STA_HIGH = 0,
- DM_RATR_STA_MIDDLE = 1,
- DM_RATR_STA_LOW = 2,
- DM_RATR_STA_MAX
-}dm_ratr_sta_e;
-
-/* 2007/10/11 MH Define DIG operation type. */
-typedef enum tag_dynamic_init_gain_operation_type_definition
-{
- DIG_TYPE_THRESH_HIGH = 0,
- DIG_TYPE_THRESH_LOW = 1,
- DIG_TYPE_THRESH_HIGHPWR_HIGH = 2,
- DIG_TYPE_THRESH_HIGHPWR_LOW = 3,
- DIG_TYPE_DBG_MODE = 4,
- DIG_TYPE_RSSI = 5,
- DIG_TYPE_ALGORITHM = 6,
- DIG_TYPE_BACKOFF = 7,
- DIG_TYPE_PWDB_FACTOR = 8,
- DIG_TYPE_RX_GAIN_MIN = 9,
- DIG_TYPE_RX_GAIN_MAX = 10,
- DIG_TYPE_ENABLE = 20,
- DIG_TYPE_DISABLE = 30,
- DIG_OP_TYPE_MAX
-}dm_dig_op_e;
-
-typedef enum tag_dig_algorithm_definition
-{
- DIG_ALGO_BY_FALSE_ALARM = 0,
- DIG_ALGO_BY_RSSI = 1,
- DIG_ALGO_MAX
-}dm_dig_alg_e;
-
-typedef enum tag_dig_dbgmode_definition
-{
- DIG_DBG_OFF = 0,
- DIG_DBG_ON = 1,
- DIG_DBG_MAX
-}dm_dig_dbg_e;
-
-typedef enum tag_dig_connect_definition
-{
- DIG_DISCONNECT = 0,
- DIG_CONNECT = 1,
- DIG_CONNECT_MAX
-}dm_dig_connect_e;
-
-typedef enum tag_dig_packetdetection_threshold_definition
-{
- DIG_PD_AT_LOW_POWER = 0,
- DIG_PD_AT_NORMAL_POWER = 1,
- DIG_PD_AT_HIGH_POWER = 2,
- DIG_PD_MAX
-}dm_dig_pd_th_e;
-
-typedef enum tag_dig_cck_cs_ratio_state_definition
-{
- DIG_CS_RATIO_LOWER = 0,
- DIG_CS_RATIO_HIGHER = 1,
- DIG_CS_MAX
-}dm_dig_cs_ratio_e;
-typedef struct _Dynamic_Rx_Path_Selection_
-{
- u8 Enable;
- u8 DbgMode;
- u8 cck_method;
- u8 cck_Rx_path;
-
- u8 SS_TH_low;
- u8 diff_TH;
- u8 disabledRF;
- u8 reserved;
-
- u8 rf_rssi[4];
- u8 rf_enable_rssi_th[4];
- long cck_pwdb_sta[4];
-}DRxPathSel;
-
-typedef enum tag_CCK_Rx_Path_Method_Definition
-{
- CCK_Rx_Version_1 = 0,
- CCK_Rx_Version_2= 1,
- CCK_Rx_Version_MAX
-}DM_CCK_Rx_Path_Method;
-
-typedef enum tag_DM_DbgMode_Definition
-{
- DM_DBG_OFF = 0,
- DM_DBG_ON = 1,
- DM_DBG_MAX
-}DM_DBG_E;
-
-typedef struct tag_Tx_Config_Cmd_Format
-{
- u32 Op; /* Command packet type. */
- u32 Length; /* Command packet length. */
- u32 Value;
-}DCMD_TXCMD_T, *PDCMD_TXCMD_T;
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export global variable----------------------------*/
-extern dig_t dm_digtable;
-extern u8 dm_shadow[16][256];
-extern DRxPathSel DM_RxPathSelTable;
-/*------------------------Export global variable----------------------------*/
-
-
-/*------------------------Export Marco Definition---------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-
-/*--------------------------Exported Function prototype---------------------*/
-extern void init_hal_dm(struct net_device *dev);
-extern void deinit_hal_dm(struct net_device *dev);
-
-extern void hal_dm_watchdog(struct net_device *dev);
-
-extern void init_rate_adaptive(struct net_device *dev);
-extern void dm_txpower_trackingcallback(struct work_struct *work);
-extern void dm_restore_dynamic_mechanism_state(struct net_device *dev);
-extern void dm_backup_dynamic_mechanism_state(struct net_device *dev);
-extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
- u32 dm_type, u32 dm_value);
-extern void dm_force_tx_fw_info(struct net_device *dev,u32 force_type, u32 force_value);
-extern void dm_init_edca_turbo(struct net_device *dev);
-extern void dm_rf_operation_test_callback(unsigned long data);
-extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
-extern void dm_fsync_timer_callback(unsigned long data);
-extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14);
-extern void dm_shadow_init(struct net_device *dev);
-extern void dm_initialize_txpower_tracking(struct net_device *dev);
-/*--------------------------Exported Function prototype---------------------*/
-
-
-#endif /*__R8192UDM_H__ */
-
-
-/* End of r8192U_dm.h */
-
diff --git a/drivers/staging/rtl8192su/r8192U_pm.c b/drivers/staging/rtl8192su/r8192U_pm.c
deleted file mode 100644
index 60d739b85eb7..000000000000
--- a/drivers/staging/rtl8192su/r8192U_pm.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Power management interface routines.
- Written by Mariusz Matuszek.
- This code is currently just a placeholder for later work and
- does not do anything useful.
-
- This is part of rtl8180 OpenSource driver.
- Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- Released under the terms of GPL (General Public Licence)
-*/
-
-#include "r8192U.h"
-#include "r8192U_pm.h"
-
-/*****************************************************************************/
-int rtl8192U_save_state (struct pci_dev *dev, u32 state)
-{
- printk(KERN_NOTICE "r8192U save state call (state %u).\n", state);
- return(-EAGAIN);
-}
-
-int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state)
-{
- struct net_device *dev = usb_get_intfdata(intf);
-
- RT_TRACE(COMP_POWER, "============> r8192U suspend call.\n");
-
- if(dev) {
- if (!netif_running(dev)) {
- printk(KERN_WARNING "netif not running, go out suspend function\n");
- return 0;
- }
-
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
-
- mdelay(10);
-
- netif_device_detach(dev);
- }
-
- return 0;
-}
-
-int rtl8192U_resume (struct usb_interface *intf)
-{
- struct net_device *dev = usb_get_intfdata(intf);
-
- RT_TRACE(COMP_POWER, "================>r8192U resume call.");
-
- if(dev) {
- if (!netif_running(dev)){
- printk(KERN_WARNING "netif not running, go out resume function\n");
- return 0;
- }
-
- netif_device_attach(dev);
-
- if (dev->netdev_ops->ndo_open)
- dev->netdev_ops->ndo_open(dev);
- }
-
- return 0;
-}
-
-int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable)
-{
- printk(KERN_NOTICE "r8192U enable wake call (state %u, enable %d).\n",
- state, enable);
- return(-EAGAIN);
-}
-
diff --git a/drivers/staging/rtl8192su/r8192U_pm.h b/drivers/staging/rtl8192su/r8192U_pm.h
deleted file mode 100644
index d89e423ea5cd..000000000000
--- a/drivers/staging/rtl8192su/r8192U_pm.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- Power management interface routines.
- Written by Mariusz Matuszek.
- This code is currently just a placeholder for later work and
- does not do anything useful.
-
- This is part of rtl8180 OpenSource driver.
- Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- Released under the terms of GPL (General Public Licence)
-
-*/
-
-
-#ifndef R8192_PM_H
-#define R8192_PM_H
-
-#include <linux/types.h>
-#include <linux/usb.h>
-
-int rtl8192U_save_tate (struct pci_dev *dev, u32 state);
-int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state);
-int rtl8192U_resume (struct usb_interface *intf);
-int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable);
-
-#endif //R8192U_PM_H
diff --git a/drivers/staging/rtl8192su/r8192U_wx.c b/drivers/staging/rtl8192su/r8192U_wx.c
deleted file mode 100644
index 2005b811ebab..000000000000
--- a/drivers/staging/rtl8192su/r8192U_wx.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- * Linux device driver for RTL8192U
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-
-
-#include <linux/string.h>
-#include "r8192U.h"
-#include "r8192S_hw.h"
-
-#include "ieee80211/dot11d.h"
-
-#define RATE_COUNT 12
-u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
- 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
-
-
-#ifndef ENETDOWN
-#define ENETDOWN 1
-#endif
-
-static int r8192_wx_get_freq(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
-}
-
-static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv=ieee80211_priv(dev);
-
- return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
-}
-
-
-
-static int r8192_wx_get_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
-}
-
-
-
-static int r8192_wx_set_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8192_wx_set_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8192_wx_get_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
-}
-
-static int r8192_wx_set_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8192_wx_get_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
-}
-
-#ifdef JOHN_IOCTL
-u16 read_rtl8225(struct net_device *dev, u8 addr);
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-u32 john_read_rtl8225(struct net_device *dev, u8 adr);
-void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-
-static int r8192_wx_read_regs(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 addr;
- u16 data1;
-
- down(&priv->wx_sem);
-
-
- get_user(addr,(u8*)wrqu->data.pointer);
- data1 = read_rtl8225(dev, addr);
- wrqu->data.length = data1;
-
- up(&priv->wx_sem);
- return 0;
-
-}
-
-static int r8192_wx_write_regs(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 addr;
-
- down(&priv->wx_sem);
-
- get_user(addr, (u8*)wrqu->data.pointer);
- write_rtl8225(dev, addr, wrqu->data.length);
-
- up(&priv->wx_sem);
- return 0;
-
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
-
-static int r8192_wx_read_bb(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 databb;
-
- down(&priv->wx_sem);
-
- databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
- wrqu->data.length = databb;
-
- up(&priv->wx_sem);
- return 0;
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-static int r8192_wx_write_bb(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u8 databb;
-
- down(&priv->wx_sem);
-
- get_user(databb, (u8*)wrqu->data.pointer);
- rtl8187_write_phy(dev, wrqu->data.length, databb);
-
- up(&priv->wx_sem);
- return 0;
-
-}
-
-
-static int r8192_wx_write_nicb(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 addr;
-
- down(&priv->wx_sem);
-
- get_user(addr, (u32*)wrqu->data.pointer);
- write_nic_byte(dev, addr, wrqu->data.length);
-
- up(&priv->wx_sem);
- return 0;
-
-}
-static int r8192_wx_read_nicb(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u32 addr;
- u16 data1;
-
- down(&priv->wx_sem);
-
- get_user(addr,(u32*)wrqu->data.pointer);
- data1 = read_nic_byte(dev, addr);
- wrqu->data.length = data1;
-
- up(&priv->wx_sem);
- return 0;
-}
-
-static int r8192_wx_get_ap_status(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- struct ieee80211_network *target;
- struct ieee80211_network *latest = NULL;
- int name_len;
-
- down(&priv->wx_sem);
-
- //count the length of input ssid
- for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
-
- //search for the correspoding info which is received
- list_for_each_entry(target, &ieee->network_list, list) {
- if ( (target->ssid_len == name_len) &&
- (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
- if ((latest == NULL) ||(target->last_scanned > latest->last_scanned))
- latest = target;
-
- }
- }
-
- if(latest != NULL)
- {
- wrqu->data.length = latest->SignalStrength;
-
- if(latest->wpa_ie_len>0 || latest->rsn_ie_len>0 ) {
- wrqu->data.flags = 1;
- } else {
- wrqu->data.flags = 0;
- }
- }
-
- up(&priv->wx_sem);
- return 0;
-}
-
-
-
-#endif
-static int r8192_wx_force_reset(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
- priv->force_reset = *extra;
- up(&priv->wx_sem);
- return 0;
-
-}
-
-static int r8191su_wx_get_firm_version(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 firmware_version;
-
- down(&priv->wx_sem);
- firmware_version = priv->pFirmware->FirmwareVersion;
- wrqu->value = firmware_version;
- wrqu->fixed = 1;
-
- up(&priv->wx_sem);
- return 0;
-}
-
-
-
-static int r8192_wx_set_rawtx(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-
-}
-
-static int r8192_wx_set_crcmon(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = priv->crcmon;
-
- down(&priv->wx_sem);
-
- if(enable)
- priv->crcmon=1;
- else
- priv->crcmon=0;
-
- DMESG("bad CRC in monitor mode are %s",
- priv->crcmon ? "accepted" : "rejected");
-
- if(prev != priv->crcmon && priv->up){
- //rtl8180_down(dev);
- //rtl8180_up(dev);
- }
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int ret;
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
-
- rtl8192_set_rxconf(dev);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-struct iw_range_with_scan_capa
-{
- /* Informative stuff (to choose between different interface) */
- __u32 throughput; /* To give an idea... */
- /* In theory this value should be the maximum benchmarked
- * TCP/IP throughput, because with most of these devices the
- * bit rate is meaningless (overhead an co) to estimate how
- * fast the connection will go and pick the fastest one.
- * I suggest people to play with Netperf or any benchmark...
- */
-
- /* NWID (or domain id) */
- __u32 min_nwid; /* Minimal NWID we are able to set */
- __u32 max_nwid; /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
- __u16 old_num_channels;
- __u8 old_num_frequency;
-
- /* Scan capabilities */
- __u8 scan_capa;
-};
-static int rtl8180_wx_get_range(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_range *range = (struct iw_range *)extra;
- struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 val;
- int i;
-
- wrqu->data.length = sizeof(*range);
- memset(range, 0, sizeof(*range));
-
- /* Let's try to keep this struct in the same order as in
- * linux/include/wireless.h
- */
-
- /* TODO: See what values we can set, and remove the ones we can't
- * set, or fill them with some default data.
- */
-
- /* ~5 Mb/s real (802.11b) */
- range->throughput = 5 * 1000 * 1000;
-
- // TODO: Not used in 802.11b?
-// range->min_nwid; /* Minimal NWID we are able to set */
- // TODO: Not used in 802.11b?
-// range->max_nwid; /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
-// range->old_num_channels;
-// range->old_num_frequency;
-// range->old_freq[6]; /* Filler to keep "version" at the same offset */
- if(priv->rf_set_sens != NULL)
- range->sensitivity = priv->max_sens; /* signal level threshold range */
-
- range->max_qual.qual = 100;
- /* TODO: Find real max RSSI and stick here */
- range->max_qual.level = 0;
- range->max_qual.noise = -98;
- range->max_qual.updated = 7; /* Updated all three */
-
- range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
- /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
- range->avg_qual.level = 20 + -98;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = 7; /* Updated all three */
-
- range->num_bitrates = RATE_COUNT;
-
- for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
- range->bitrate[i] = rtl8180_rates[i];
- }
-
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
- range->min_pmp=0;
- range->max_pmp = 5000000;
- 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_ALL_R;
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
-
-
- for (i = 0, val = 0; i < 14; i++) {
-
- // Include only legal frequencies for some countries
- if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
- range->freq[val].i = i + 1;
- range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
- range->freq[val].e = 1;
- val++;
- } else {
- // FIXME: do we need to set anything for channels
- // we don't use ?
- }
-
- if (val == IW_MAX_FREQUENCIES)
- break;
- }
- range->num_frequency = val;
- range->num_channels = val;
- range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
- IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
- tmp->scan_capa = 0x01;
- return 0;
-}
-
-
-static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- int ret = 0;
-
- if(!priv->up) return -ENETDOWN;
-
- if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
- return -EAGAIN;
-
- if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
- {
- struct iw_scan_req* req = (struct iw_scan_req*)b;
- if (req->essid_len)
- {
- //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
- ieee->current_network.ssid_len = req->essid_len;
- memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
- //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
- }
- }
-
- down(&priv->wx_sem);
- if(priv->ieee80211->state != IEEE80211_LINKED){
- priv->ieee80211->scanning = 0;
- ieee80211_softmac_scan_syncro(priv->ieee80211);
- ret = 0;
- }
- else
- ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
-
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if(!priv->up) return -ENETDOWN;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8192_wx_set_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int ret;
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-
-
-static int r8192_wx_get_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-static int r8192_wx_get_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
-}
-
-
-static int r8192_wx_set_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- if (wrqu->frag.disabled)
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- else {
- if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- wrqu->frag.value > MAX_FRAG_THRESHOLD)
- return -EINVAL;
-
- priv->ieee80211->fts = wrqu->frag.value & ~0x1;
- }
-
- return 0;
-}
-
-
-static int r8192_wx_get_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- wrqu->frag.value = priv->ieee80211->fts;
- wrqu->frag.fixed = 0; /* no auto select */
- wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
-
- return 0;
-}
-
-
-static int r8192_wx_set_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra)
-{
-
- int ret;
- struct r8192_priv *priv = ieee80211_priv(dev);
-// struct sockaddr *temp = (struct sockaddr *)awrq;
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
-
- up(&priv->wx_sem);
-
- return ret;
-
-}
-
-
-static int r8192_wx_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
-}
-
-
-static int r8192_wx_get_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
-}
-
-static int r8192_wx_set_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- int ret;
-
- //u32 TargetContent;
- u32 hwkey[4]={0,0,0,0};
- u8 mask=0xff;
- u32 key_idx=0;
- //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
- u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x01},
- {0x00,0x00,0x00,0x00,0x00,0x02},
- {0x00,0x00,0x00,0x00,0x00,0x03} };
- int i;
-
- if(!priv->up) return -ENETDOWN;
-
- down(&priv->wx_sem);
-
- RT_TRACE(COMP_SEC, "Setting SW wep key");
- ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
-
- up(&priv->wx_sem);
-
-
-
- //sometimes, the length is zero while we do not type key value
- if(wrqu->encoding.length!=0){
-
- for(i=0 ; i<4 ; i++){
- hwkey[i] |= key[4*i+0]&mask;
- if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
- if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
- hwkey[i] |= (key[4*i+1]&mask)<<8;
- hwkey[i] |= (key[4*i+2]&mask)<<16;
- hwkey[i] |= (key[4*i+3]&mask)<<24;
- }
-
- #define CONF_WEP40 0x4
- #define CONF_WEP104 0x14
-
- switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
- case 0: key_idx = ieee->tx_keyidx; break;
- case 1: key_idx = 0; break;
- case 2: key_idx = 1; break;
- case 3: key_idx = 2; break;
- case 4: key_idx = 3; break;
- default: break;
- }
-
- if(wrqu->encoding.length==0x5){
- ieee->pairwise_key_type = KEY_TYPE_WEP40;
- EnableHWSecurityConfig8192(dev);
-
- setKey( dev,
- key_idx, //EntryNo
- key_idx, //KeyIndex
- KEY_TYPE_WEP40, //KeyType
- zero_addr[key_idx],
- 0, //DefaultKey
- hwkey); //KeyContent
-
- }
-
- else if(wrqu->encoding.length==0xd){
- ieee->pairwise_key_type = KEY_TYPE_WEP104;
- EnableHWSecurityConfig8192(dev);
-
- setKey( dev,
- key_idx, //EntryNo
- key_idx, //KeyIndex
- KEY_TYPE_WEP104, //KeyType
- zero_addr[key_idx],
- 0, //DefaultKey
- hwkey); //KeyContent
-
- }
- else printk("wrong type in WEP, not WEP40 and WEP104\n");
-
- }
-
- return ret;
-}
-
-
-static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
- iwreq_data *wrqu, char *p){
-
- struct r8192_priv *priv = ieee80211_priv(dev);
- int *parms=(int*)p;
- int mode=parms[0];
-
- priv->ieee80211->active_scan = mode;
-
- return 1;
-}
-
-
-
-static int r8192_wx_set_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int err = 0;
-
- down(&priv->wx_sem);
-
- if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- wrqu->retry.disabled){
- err = -EINVAL;
- goto exit;
- }
- if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
- err = -EINVAL;
- goto exit;
- }
-
- if(wrqu->retry.value > R8180_MAX_RETRY){
- err= -EINVAL;
- goto exit;
- }
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- priv->retry_rts = wrqu->retry.value;
- DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
-
- }else {
- priv->retry_data = wrqu->retry.value;
- DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
- }
-
- /* FIXME !
- * We might try to write directly the TX config register
- * or to restart just the (R)TX process.
- * I'm unsure if whole reset is really needed
- */
-
- rtl8192_commit(dev);
- /*
- if(priv->up){
- rtl8180_rtx_disable(dev);
- rtl8180_rx_enable(dev);
- rtl8180_tx_enable(dev);
-
- }
- */
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-static int r8192_wx_get_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-
- wrqu->retry.disabled = 0; /* can't be disabled */
-
- if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- IW_RETRY_LIFETIME)
- return -EINVAL;
-
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- wrqu->retry.value = priv->retry_rts;
- } else {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
- wrqu->retry.value = priv->retry_data;
- }
- //printk("returning %d",wrqu->retry.value);
-
-
- return 0;
-}
-
-static int r8192_wx_get_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- if(priv->rf_set_sens == NULL)
- return -1; /* we have not this support for this radio */
- wrqu->sens.value = priv->sens;
- return 0;
-}
-
-
-static int r8192_wx_set_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- short err = 0;
- down(&priv->wx_sem);
- //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
- if(priv->rf_set_sens == NULL) {
- err= -1; /* we have not this support for this radio */
- goto exit;
- }
- if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
- priv->sens = wrqu->sens.value;
- else
- err= -EINVAL;
-
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-//hw security need to reorganized.
-static int r8192_wx_set_enc_ext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret=0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- //printk("===>%s()\n", __FUNCTION__);
-
-
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
-
- {
- u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
- u8 zero[6] = {0};
- u32 key[4] = {0};
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- struct iw_point *encoding = &wrqu->encoding;
- u8 idx = 0, alg = 0, group = 0;
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
- {
- ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
- CamResetAllEntry(dev);
- goto end_hw_sec;
- }
- alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx)
- idx --;
- group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
-
- if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
- {
- if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
- alg = KEY_TYPE_WEP104;
- ieee->pairwise_key_type = alg;
- EnableHWSecurityConfig8192(dev);
- }
- memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
-
- if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
- {
-
- setKey( dev,
- idx,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- zero, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
- }
- else if (group)
- {
- ieee->group_key_type = alg;
- setKey( dev,
- idx,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- broadcast_addr, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
- }
- else //pairwise key
- {
- setKey( dev,
- 4,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- (u8*)ieee->ap_mac_addr, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
- }
-
-
- }
-
-end_hw_sec:
-
- up(&priv->wx_sem);
- return ret;
-}
-static int r8192_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *data, char *extra)
-{
- int ret=0;
-
- //printk("====>%s()\n", __FUNCTION__);
- struct r8192_priv *priv = ieee80211_priv(dev);
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
- up(&priv->wx_sem);
- return ret;
-}
-
-static int r8192_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- //printk("====>%s()\n", __FUNCTION__);
-
- int ret=0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
- up(&priv->wx_sem);
- return ret;
-}
-
-static int r8192_wx_set_pmkid(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int i;
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- struct iw_pmksa* pPMK = (struct iw_pmksa*)extra;
- int intReturn = false;
-
- switch (pPMK->cmd)
- {
- case IW_PMKSA_ADD:
- for (i = 0; i < NUM_PMKID_CACHE; i++)
- {
- if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0)
- {
- memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
- memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
- ieee->PMKIDList[i].bUsed = true;
- intReturn = true;
- goto __EXIT__;
- }
- }
-
- for (i = 0; i < NUM_PMKID_CACHE; i++)
- {
- if (ieee->PMKIDList[i].bUsed == false)
- {
- memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
- memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
- ieee->PMKIDList[i].bUsed = true;
- intReturn = true;
- goto __EXIT__;
- }
- }
- break;
-
- case IW_PMKSA_REMOVE:
- for (i = 0; i < NUM_PMKID_CACHE; i++)
- {
- if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true)
- {
- memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST));
- intReturn = true;
- break;
- }
- }
- break;
-
- case IW_PMKSA_FLUSH:
- memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE));
- intReturn = true;
- break;
-
- default:
- break;
- }
-
-__EXIT__:
- return (intReturn);
-
-}
-
-static int r8192_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *data, char *extra)
-{
- //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
- int ret=0;
- struct r8192_priv *priv = ieee80211_priv(dev);
- down(&priv->wx_sem);
-#if 1
- ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
-#endif
- up(&priv->wx_sem);
- //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
- return ret;
-
-
-}
-
-static int dummy(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu,char *b)
-{
- return -1;
-}
-
-
-static iw_handler r8192_wx_handlers[] =
-{
- NULL, /* SIOCSIWCOMMIT */
- r8192_wx_get_name, /* SIOCGIWNAME */
- dummy, /* SIOCSIWNWID */
- dummy, /* SIOCGIWNWID */
- r8192_wx_set_freq, /* SIOCSIWFREQ */
- r8192_wx_get_freq, /* SIOCGIWFREQ */
- r8192_wx_set_mode, /* SIOCSIWMODE */
- r8192_wx_get_mode, /* SIOCGIWMODE */
- r8192_wx_set_sens, /* SIOCSIWSENS */
- r8192_wx_get_sens, /* SIOCGIWSENS */
- NULL, /* SIOCSIWRANGE */
- rtl8180_wx_get_range, /* SIOCGIWRANGE */
- NULL, /* SIOCSIWPRIV */
- NULL, /* SIOCGIWPRIV */
- NULL, /* SIOCSIWSTATS */
- NULL, /* SIOCGIWSTATS */
- dummy, /* SIOCSIWSPY */
- dummy, /* SIOCGIWSPY */
- NULL, /* SIOCGIWTHRSPY */
- NULL, /* SIOCWIWTHRSPY */
- r8192_wx_set_wap, /* SIOCSIWAP */
- r8192_wx_get_wap, /* SIOCGIWAP */
- r8192_wx_set_mlme, /* MLME-- */
- dummy, /* SIOCGIWAPLIST -- depricated */
- r8192_wx_set_scan, /* SIOCSIWSCAN */
- r8192_wx_get_scan, /* SIOCGIWSCAN */
- r8192_wx_set_essid, /* SIOCSIWESSID */
- r8192_wx_get_essid, /* SIOCGIWESSID */
- dummy, /* SIOCSIWNICKN */
- dummy, /* SIOCGIWNICKN */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
- r8192_wx_set_rate, /* SIOCSIWRATE */
- r8192_wx_get_rate, /* SIOCGIWRATE */
- r8192_wx_set_rts, /* SIOCSIWRTS */
- r8192_wx_get_rts, /* SIOCGIWRTS */
- r8192_wx_set_frag, /* SIOCSIWFRAG */
- r8192_wx_get_frag, /* SIOCGIWFRAG */
- dummy, /* SIOCSIWTXPOW */
- dummy, /* SIOCGIWTXPOW */
- r8192_wx_set_retry, /* SIOCSIWRETRY */
- r8192_wx_get_retry, /* SIOCGIWRETRY */
- r8192_wx_set_enc, /* SIOCSIWENCODE */
- r8192_wx_get_enc, /* SIOCGIWENCODE */
- r8192_wx_set_power, /* SIOCSIWPOWER */
- r8192_wx_get_power, /* SIOCGIWPOWER */
- NULL, /*---hole---*/
- NULL, /*---hole---*/
- r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
- NULL, /* SIOCSIWGENIE */
-
- r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
- NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
- r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
- NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
- r8192_wx_set_pmkid, /* SIOCSIWPMKSA */
- NULL, /*---hole---*/
-
-};
-
-
-static const struct iw_priv_args r8192_private_args[] = {
-
- {
- SIOCIWFIRSTPRIV + 0x0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
- },
-
- {
- SIOCIWFIRSTPRIV + 0x1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x2,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
- }
-#ifdef JOHN_IOCTL
- ,
- {
- SIOCIWFIRSTPRIV + 0x3,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x5,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x6,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x7,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x8,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
- }
- ,
- {
- SIOCIWFIRSTPRIV + 0x9,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
- }
-
-#endif
- ,
- {
- SIOCIWFIRSTPRIV + 0x3,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
- }
-
- ,
- {
- SIOCIWFIRSTPRIV + 0x5,
- IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
- "firm_ver"
- }
-};
-
-
-static iw_handler r8192_private_handler[] = {
-// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
- r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
-// r8192_wx_set_forceassociate,
-// r8192_wx_set_beaconinterval,
-// r8192_wx_set_monitor_type,
- r8192_wx_set_scan_type,
- r8192_wx_set_rawtx,
-#ifdef JOHN_IOCTL
- r8192_wx_read_regs,
- r8192_wx_write_regs,
- r8192_wx_read_bb,
- r8192_wx_write_bb,
- r8192_wx_read_nicb,
- r8192_wx_write_nicb,
- r8192_wx_get_ap_status,
-#endif
- r8192_wx_force_reset,
- (iw_handler)NULL,
- (iw_handler)r8191su_wx_get_firm_version,
-};
-
-struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device* ieee = priv->ieee80211;
- struct iw_statistics* wstats = &priv->wstats;
- int tmp_level = 0;
- int tmp_qual = 0;
- int tmp_noise = 0;
- if(ieee->state < IEEE80211_LINKED)
- {
- wstats->qual.qual = 0;
- wstats->qual.level = 0;
- wstats->qual.noise = 0;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
- }
-
- tmp_level = (&ieee->current_network)->stats.rssi;
- tmp_qual = (&ieee->current_network)->stats.signal;
- tmp_noise = (&ieee->current_network)->stats.noise;
- //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
-
- wstats->qual.level = tmp_level;
- wstats->qual.qual = tmp_qual;
- wstats->qual.noise = tmp_noise;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
- return wstats;
-}
-
-struct iw_handler_def r8192_wx_handlers_def={
- .standard = r8192_wx_handlers,
- .num_standard = ARRAY_SIZE(r8192_wx_handlers),
- .private = r8192_private_handler,
- .num_private = ARRAY_SIZE(r8192_private_handler),
- .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
- .get_wireless_stats = r8192_get_wireless_stats,
- .private_args = (struct iw_priv_args *)r8192_private_args,
-};
diff --git a/drivers/staging/rtl8192su/r8192U_wx.h b/drivers/staging/rtl8192su/r8192U_wx.h
deleted file mode 100644
index 61a2c2652536..000000000000
--- a/drivers/staging/rtl8192su/r8192U_wx.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- This is part of rtl8180 OpenSource driver - v 0.3
- Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
- We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/* this file (will) contains wireless extension handlers*/
-
-#ifndef R8180_WX_H
-#define R8180_WX_H
-//#include <linux/wireless.h>
-extern struct iw_handler_def r8192_wx_handlers_def;
-/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
-extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
-
-#endif
diff --git a/drivers/staging/rtl8192su/r819xU_HTGen.h b/drivers/staging/rtl8192su/r819xU_HTGen.h
deleted file mode 100644
index 7a60480c4b8e..000000000000
--- a/drivers/staging/rtl8192su/r819xU_HTGen.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// IOT Action for different AP
-//
-typedef enum _HT_IOT_ACTION{
- HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
- HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
- HT_IOT_ACT_DECLARE_MCS13 = 0x00000004,
- HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000008,
- HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000010,
- HT_IOT_ACT_CDD_FSYNC = 0x00000020,
- HT_IOT_ACT_PURE_N_MODE = 0x00000040,
-
- //LZM ADD 090224
- HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000,
- HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000,
- HT_IOT_ACT_AMSDU_ENABLE = 0x00000800,
- HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000,
- HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000,
- HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000,
- HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000,
-}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
-
diff --git a/drivers/staging/rtl8192su/r819xU_HTType.h b/drivers/staging/rtl8192su/r819xU_HTType.h
deleted file mode 100644
index 3f379e0d9d31..000000000000
--- a/drivers/staging/rtl8192su/r819xU_HTType.h
+++ /dev/null
@@ -1,383 +0,0 @@
-#ifndef _R819XU_HTTYPE_H_
-#define _R819XU_HTTYPE_H_
-
-
-//------------------------------------------------------------
-// The HT Capability element is present in beacons, association request,
-// reassociation request and probe response frames
-//------------------------------------------------------------
-
-//
-// Operation mode value
-//
-#define HT_OPMODE_NO_PROTECT 0
-#define HT_OPMODE_OPTIONAL 1
-#define HT_OPMODE_40MHZ_PROTECT 2
-#define HT_OPMODE_MIXED 3
-
-//
-// MIMO Power Save Setings
-//
-#define MIMO_PS_STATIC 0
-#define MIMO_PS_DYNAMIC 1
-#define MIMO_PS_NOLIMIT 3
-
-
-//
-// There should be 128 bits to cover all of the MCS rates. However, since
-// 8190 does not support too much rates, one integer is quite enough.
-//
-
-#define sHTCLng 4
-
-
-#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff
-#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00
-#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
-
-
-typedef enum _HT_MCS_RATE{
- HT_MCS0 = 0x00000001,
- HT_MCS1 = 0x00000002,
- HT_MCS2 = 0x00000004,
- HT_MCS3 = 0x00000008,
- HT_MCS4 = 0x00000010,
- HT_MCS5 = 0x00000020,
- HT_MCS6 = 0x00000040,
- HT_MCS7 = 0x00000080,
- HT_MCS8 = 0x00000100,
- HT_MCS9 = 0x00000200,
- HT_MCS10 = 0x00000400,
- HT_MCS11 = 0x00000800,
- HT_MCS12 = 0x00001000,
- HT_MCS13 = 0x00002000,
- HT_MCS14 = 0x00004000,
- HT_MCS15 = 0x00008000,
- // Do not define MCS32 here although 8190 support MCS32
-}HT_MCS_RATE,*PHT_MCS_RATE;
-
-//
-// Represent Channel Width in HT Capabilities
-//
-typedef enum _HT_CHANNEL_WIDTH{
- HT_CHANNEL_WIDTH_20 = 0,
- HT_CHANNEL_WIDTH_20_40 = 1,
-}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
-
-//
-// Represent Extention Channel Offset in HT Capabilities
-// This is available only in 40Mhz mode.
-//
-typedef enum _HT_EXTCHNL_OFFSET{
- HT_EXTCHNL_OFFSET_NO_EXT = 0,
- HT_EXTCHNL_OFFSET_UPPER = 1,
- HT_EXTCHNL_OFFSET_NO_DEF = 2,
- HT_EXTCHNL_OFFSET_LOWER = 3,
-}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
-
-typedef enum _CHNLOP{
- CHNLOP_NONE = 0, // No Action now
- CHNLOP_SCAN = 1, // Scan in progress
- CHNLOP_SWBW = 2, // Bandwidth switching in progress
- CHNLOP_SWCHNL = 3, // Software Channel switching in progress
-} CHNLOP, *PCHNLOP;
-
-// Determine if the Channel Operation is in progress
-#define CHHLOP_IN_PROGRESS(_pHTInfo) \
- ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
-
-
-typedef enum _HT_ACTION{
- ACT_RECOMMAND_WIDTH = 0,
- ACT_MIMO_PWR_SAVE = 1,
- ACT_PSMP = 2,
- ACT_SET_PCO_PHASE = 3,
- ACT_MIMO_CHL_MEASURE = 4,
- ACT_RECIPROCITY_CORRECT = 5,
- ACT_MIMO_CSI_MATRICS = 6,
- ACT_MIMO_NOCOMPR_STEER = 7,
- ACT_MIMO_COMPR_STEER = 8,
- ACT_ANTENNA_SELECT = 9,
-} HT_ACTION, *PHT_ACTION;
-
-
-/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
-typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
- SC_MODE_DUPLICATE = 0,
- SC_MODE_LOWER = 1,
- SC_MODE_UPPER = 2,
- SC_MODE_FULL40MHZ = 3,
-}HT_BW40_SC_E;
-
-typedef struct _HT_CAPABILITY_ELE{
-
- //HT capability info
- u8 AdvCoding:1;
- u8 ChlWidth:1;
- u8 MimoPwrSave:2;
- u8 GreenField:1;
- u8 ShortGI20Mhz:1;
- u8 ShortGI40Mhz:1;
- u8 TxSTBC:1;
- u8 RxSTBC:2;
- u8 DelayBA:1;
- u8 MaxAMSDUSize:1;
- u8 DssCCk:1;
- u8 PSMP:1;
- u8 Rsvd1:1;
- u8 LSigTxopProtect:1;
-
- //MAC HT parameters info
- u8 MaxRxAMPDUFactor:2;
- u8 MPDUDensity:3;
- u8 Rsvd2:3;
-
- //Supported MCS set
- u8 MCS[16];
-
-
- //Extended HT Capability Info
- u16 ExtHTCapInfo;
-
- //TXBF Capabilities
- u8 TxBFCap[4];
-
- //Antenna Selection Capabilities
- u8 ASCap;
-
-}__attribute__((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
-
-//------------------------------------------------------------
-// The HT Information element is present in beacons
-// Only AP is required to include this element
-//------------------------------------------------------------
-
-typedef struct _HT_INFORMATION_ELE{
- u8 ControlChl;
-
- u8 ExtChlOffset:2;
- u8 RecommemdedTxWidth:1;
- u8 RIFS:1;
- u8 PSMPAccessOnly:1;
- u8 SrvIntGranularity:3;
-
- u8 OptMode:2;
- u8 NonGFDevPresent:1;
- u8 Revd1:5;
- u8 Revd2:8;
-
- u8 Rsvd3:6;
- u8 DualBeacon:1;
- u8 DualCTSProtect:1;
-
- u8 SecondaryBeacon:1;
- u8 LSigTxopProtectFull:1;
- u8 PcoActive:1;
- u8 PcoPhase:1;
- u8 Rsvd4:4;
-
- u8 BasicMSC[16];
-}__attribute__((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
-
-//
-// MIMO Power Save control field.
-// This is appear in MIMO Power Save Action Frame
-//
-typedef struct _MIMOPS_CTRL{
- u8 MimoPsEnable:1;
- u8 MimoPsMode:1;
- u8 Reserved:6;
-} MIMOPS_CTRL, *PMIMOPS_CTRL;
-
-typedef enum _HT_SPEC_VER{
- HT_SPEC_VER_IEEE = 0,
- HT_SPEC_VER_EWC = 1,
-}HT_SPEC_VER, *PHT_SPEC_VER;
-
-typedef enum _HT_AGGRE_MODE_E{
- HT_AGG_AUTO = 0,
- HT_AGG_FORCE_ENABLE = 1,
- HT_AGG_FORCE_DISABLE = 2,
-}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variables when card is
-// configured as non-AP STA mode. **Note** Current_xxx should be set
-// to default value in HTInitializeHTInfo()
-//------------------------------------------------------------
-
-typedef struct _RT_HIGH_THROUGHPUT{
-// DECLARE_RT_OBJECT(_RT_HIGH_THROUGHPUT);
- u8 bEnableHT;
- u8 bCurrentHTSupport;
-
- u8 bRegBW40MHz; // Tx 40MHz channel capablity
- u8 bCurBW40MHz; // Tx 40MHz channel capability
-
- u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz
- u8 bCurShortGI40MHz; // Tx Short GI for 40MHz
-
- u8 bRegShortGI20MHz; // Tx Short GI for 20MHz
- u8 bCurShortGI20MHz; // Tx Short GI for 20MHz
-
- u8 bRegSuppCCK; // Tx CCK rate capability
- u8 bCurSuppCCK; // Tx CCK rate capability
-
- // 802.11n spec version for "peer"
- HT_SPEC_VER ePeerHTSpecVer;
-
-
- // HT related information for "Self"
- HT_CAPABILITY_ELE SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
- HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
-
- // HT related information for "Peer"
- u8 PeerHTCapBuf[32];
- u8 PeerHTInfoBuf[32];
-
-
- // A-MSDU related
- u8 bAMSDU_Support; // This indicates Tx A-MSDU capability
- u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability
- u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
- u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
-
-
- // AMPDU related <2006.08.10 Emily>
- u8 bAMPDUEnable; // This indicate Tx A-MPDU capability
- u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability
- u8 AMPDU_Factor; // This indicate Tx A-MPDU capability
- u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability
- u8 MPDU_Density; // This indicate Tx A-MPDU capability
- u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability
-
- // Forced A-MPDU enable
- HT_AGGRE_MODE_E ForcedAMPDUMode;
- u8 ForcedAMPDUFactor;
- u8 ForcedMPDUDensity;
-
- // Forced A-MSDU enable
- HT_AGGRE_MODE_E ForcedAMSDUMode;
- u16 ForcedAMSDUMaxSize;
-
- u8 bForcedShortGI;
-
- u8 CurrentOpMode;
-
- // MIMO PS related
- u8 SelfMimoPs;
- u8 PeerMimoPs;
-
- // 40MHz Channel Offset settings.
- HT_EXTCHNL_OFFSET CurSTAExtChnlOffset;
- u8 bCurTxBW40MHz; // If we use 40 MHz to Tx
- u8 PeerBandwidth;
-
- // For Bandwidth Switching
- u8 bSwBwInProgress;
- CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
- u8 SwBwStep;
- //RT_TIMER SwBwTimer;
- struct timer_list SwBwTimer;
-
- // For Realtek proprietary A-MPDU factor for aggregation
- u8 bRegRT2RTAggregation;
- u8 bCurrentRT2RTAggregation;
- u8 bCurrentRT2RTLongSlotTime;
- u8 szRT2RTAggBuffer[10];
-
- // Rx Reorder control
- u8 bRegRxReorderEnable;
- u8 bCurRxReorderEnable;
- u8 RxReorderWinSize;
- u8 RxReorderPendingTime;
- u16 RxReorderDropCounter;
-
-
- // Add for Broadcom(Linksys) IOT. Joseph
- u8 bIsPeerBcm;
-
- // For IOT issue.
- u32 IOTAction;
-}RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
-
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each Sta"
-// when card is configured as "AP mode"
-//------------------------------------------------------------
-
-typedef struct _RT_HTINFO_STA_ENTRY{
- u8 bEnableHT;
-
- u8 bSupportCck;
-
- u16 AMSDU_MaxSize;
-
- u8 AMPDU_Factor;
- u8 MPDU_Density;
-
- u8 HTHighestOperaRate;
-
- u8 bBw40MHz;
-
- u8 MimoPs;
-
- u8 McsRateSet[16];
-
-
-}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
-
-
-
-
-
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each AP"
-// when card is configured as "STA mode"
-//------------------------------------------------------------
-
-typedef struct _BSS_HT{
-
- u8 bdSupportHT;
-
- // HT related elements
- u8 bdHTCapBuf[32];
- u16 bdHTCapLen;
- u8 bdHTInfoBuf[32];
- u16 bdHTInfoLen;
-
- HT_SPEC_VER bdHTSpecVer;
- //HT_CAPABILITY_ELE bdHTCapEle;
- //HT_INFORMATION_ELE bdHTInfoEle;
-
- u8 bdRT2RTAggregation;
- u8 bdRT2RTLongSlotTime;
- bool bdHT1R;
-}BSS_HT, *PBSS_HT;
-
-typedef struct _MIMO_RSSI{
- u32 EnableAntenna;
- u32 AntennaA;
- u32 AntennaB;
- u32 AntennaC;
- u32 AntennaD;
- u32 Average;
-}MIMO_RSSI, *PMIMO_RSSI;
-
-typedef struct _MIMO_EVM{
- u32 EVM1;
- u32 EVM2;
-}MIMO_EVM, *PMIMO_EVM;
-
-typedef struct _FALSE_ALARM_STATISTICS{
- u32 Cnt_Parity_Fail;
- u32 Cnt_Rate_Illegal;
- u32 Cnt_Crc8_fail;
- u32 Cnt_all;
-}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
-
-
-
-#endif //__INC_HTTYPE_H
-
diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c
deleted file mode 100644
index 7ab9e22f8957..000000000000
--- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- * Linux device driver for RTL8192U
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#include "r8192U.h"
-#include "r819xU_cmdpkt.h"
-
-bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
-{
- bool rtStatus = true;
- struct r8192_priv *priv = ieee80211_priv(dev);
- struct sk_buff *skb;
- cb_desc *tcb_desc;
- unsigned char *ptr_buf;
-
- /*
- * Get TCB and local buffer from common pool.
- * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
- */
- skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
- if (!skb)
- return false;
- memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
- tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
- tcb_desc->queue_index = TXCMD_QUEUE;
- tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
- tcb_desc->bLastIniPkt = 0;
- skb_reserve(skb, USB_HWDESC_HEADER_LEN);
- ptr_buf = skb_put(skb, DataLen);
- memcpy(ptr_buf, pData, DataLen);
- tcb_desc->txbuf_size = (u16)DataLen;
-
- if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
- (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
- (priv->ieee80211->queue_stop)) {
- RT_TRACE(COMP_FIRMWARE, "NULL packet => tx full\n");
- skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
- } else {
- priv->ieee80211->softmac_hard_start_xmit(skb, dev);
- }
-
- return rtStatus;
-}
-
-/*
- * Function: cmpk_message_handle_tx()
- *
- * Overview: Driver internal module can call the API to send message to
- * firmware side. For example, you can send a debug command packet.
- * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
- * Otherwise, you can change MAC/PHT/RF register by firmware at
- * run time. We do not support message more than one segment now.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- */
- extern bool cmpk_message_handle_tx(
- struct net_device *dev,
- u8 *codevirtualaddress,
- u32 packettype,
- u32 buffer_len)
-{
- bool rt_status = true;
- return rt_status;
-}
-
-/*
- * Function: cmpk_counttxstatistic()
- */
-static void
-cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef ENABLE_PS
- RT_RF_POWER_STATE rtState;
-
- pAdapter->HalFunc.GetHwRegHandler(pAdapter,
- HW_VAR_RF_STATE,
- (pu1Byte)(&rtState));
-
- /*
- * When RF is off, we should not count the packet for hw/sw synchronize
- * reason, ie. there may be a duration while sw switch is changed and hw
- * switch is being changed.
- */
- if (rtState == eRfOff)
- return;
-#endif
-
-#ifdef TODO
- if (pAdapter->bInHctTest)
- return;
-#endif
- /*
- * We can not know the packet length and transmit type:
- * broadcast or uni or multicast.
- * So the relative statistics must be collected in tx feedback info
- */
- if (pstx_fb->tok) {
- priv->stats.txfeedbackok++;
- priv->stats.txoktotal++;
- priv->stats.txokbytestotal += pstx_fb->pkt_length;
- priv->stats.txokinperiod++;
- /* We can not make sure broadcast/multicast or unicast mode. */
- if (pstx_fb->pkt_type == PACKET_MULTICAST) {
- priv->stats.txmulticast++;
- priv->stats.txbytesmulticast += pstx_fb->pkt_length;
- } else if (pstx_fb->pkt_type == PACKET_BROADCAST) {
- priv->stats.txbroadcast++;
- priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
- } else {
- priv->stats.txunicast++;
- priv->stats.txbytesunicast += pstx_fb->pkt_length;
- }
- } else {
- priv->stats.txfeedbackfail++;
- priv->stats.txerrtotal++;
- priv->stats.txerrbytestotal += pstx_fb->pkt_length;
- /* We can not make sure broadcast/multicast or unicast mode. */
- if (pstx_fb->pkt_type == PACKET_MULTICAST)
- priv->stats.txerrmulticast++;
- else if (pstx_fb->pkt_type == PACKET_BROADCAST)
- priv->stats.txerrbroadcast++;
- else
- priv->stats.txerrunicast++;
- }
- priv->stats.txretrycount += pstx_fb->retry_cnt;
- priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
-}
-
-/*
- * Function: cmpk_handle_tx_feedback()
- *
- * Overview: The function is responsible for extract the message inside TX
- * feedbck message from firmware. It will contain dedicated info in
- * ws-06-0063-rtl8190-command-packet-specification. Please
- * refer to chapter "TX Feedback Element". We have to read 20 bytes
- * in the command packet.
- *
- * Input: struct net_device * dev
- * u8 *pmsg - Msg Ptr of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- */
-static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- cmpk_txfb_t rx_tx_fb;
-
- priv->stats.txfeedback++;
-
- /* 1. Extract TX feedback info from RFD to temp structure buffer. */
- memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
-
- /* 2. Use tx feedback info to count TX statistics. */
- cmpk_count_txstatistic(dev, &rx_tx_fb);
-}
-
-void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- u16 tx_rate;
-
- if (priv->ieee80211->current_network.mode == IEEE_A ||
- priv->ieee80211->current_network.mode == IEEE_N_5G ||
- (priv->ieee80211->current_network.mode == IEEE_N_24G &&
- (!priv->ieee80211->pHTInfo->bCurSuppCCK))) {
- tx_rate = 60;
- DMESG("send beacon frame tx rate is 6Mbpm\n");
- } else {
- tx_rate = 10;
- DMESG("send beacon frame tx rate is 1Mbpm\n");
- }
- rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */
-}
-
-/*
- * Function: cmpk_handle_interrupt_status()
- *
- * Overview: The function is responsible for extract the message from
- * firmware. It will contain dedicated info in
- * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
- * Please refer to chapter "Interrupt Status Element".
- *
- * Input: struct net_device *dev,
- * u8* pmsg - Message Pointer of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- */
-static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
-{
- cmpk_intr_sta_t rx_intr_status; /* */
- struct r8192_priv *priv = ieee80211_priv(dev);
-
- DMESG("---> cmpk_Handle_Interrupt_Status()\n");
-
- /* 1. Extract TX feedback info from RFD to temp structure buffer. */
- rx_intr_status.length = pmsg[1];
- if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) {
- DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
- return;
- }
- /* Statistics of beacon for ad-hoc mode. */
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
- //2 maybe need endian transform?
- rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
-
- DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
-
- if (rx_intr_status.interrupt_status & ISR_TxBcnOk) {
- priv->ieee80211->bibsscoordinator = true;
- priv->stats.txbeaconokint++;
- } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) {
- priv->ieee80211->bibsscoordinator = false;
- priv->stats.txbeaconerr++;
- }
-
- if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
- cmdpkt_beacontimerinterrupt_819xusb(dev);
- }
- /* Other informations in interrupt status we need? */
- DMESG("<---- cmpk_handle_interrupt_status()\n");
-}
-
-/*
- * Function: cmpk_handle_query_config_rx()
- *
- * Overview: The function is responsible for extract the message from
- * firmware. It will contain dedicated info in
- * ws-06-0063-rtl8190-command-packet-specification
- * Please refer to chapter "Beacon State Element".
- *
- * Input: u8 * pmsg - Message Pointer of the command packet.
- *
- * Output: NONE
- *
- * Return: NONE
- *
- */
-static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg)
-{
- cmpk_query_cfg_t rx_query_cfg;
- /*
- * Extract TX feedback info from RFD to temp structure buffer.
- */
- rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000) >> 31;
- rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
- rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
- rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
- rx_query_cfg.cfg_offset = pmsg[7];
- rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) |
- (pmsg[10] << 8) | (pmsg[11] << 0);
- rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
- (pmsg[14] << 8) | (pmsg[15] << 0);
-}
-
-/*
- * Function: cmpk_count_tx_status()
- *
- * Overview: Count aggregated tx status from firmware of one type rx command
- * packet element id = RX_TX_STATUS.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- */
-static void cmpk_count_tx_status(struct net_device *dev,
- cmpk_tx_status_t *pstx_status)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-#ifdef ENABLE_PS
-
- RT_RF_POWER_STATE rtstate;
-
- pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
-
- /*
- * When RF is off, we should not count the packet for hw/sw synchronize
- * reason, ie. there may be a duration while sw switch is changed and hw
- * switch is being changed.
- */
- if (rtState == eRfOff)
- return;
-#endif
-
- priv->stats.txfeedbackok += pstx_status->txok;
- priv->stats.txoktotal += pstx_status->txok;
-
- priv->stats.txfeedbackfail += pstx_status->txfail;
- priv->stats.txerrtotal += pstx_status->txfail;
-
- priv->stats.txretrycount += pstx_status->txretry;
- priv->stats.txfeedbackretry += pstx_status->txretry;
-
- priv->stats.txmulticast += pstx_status->txmcok;
- priv->stats.txbroadcast += pstx_status->txbcok;
- priv->stats.txunicast += pstx_status->txucok;
-
- priv->stats.txerrmulticast += pstx_status->txmcfail;
- priv->stats.txerrbroadcast += pstx_status->txbcfail;
- priv->stats.txerrunicast += pstx_status->txucfail;
-
- priv->stats.txbytesmulticast += pstx_status->txmclength;
- priv->stats.txbytesbroadcast += pstx_status->txbclength;
- priv->stats.txbytesunicast += pstx_status->txuclength;
-
- priv->stats.last_packet_rate = pstx_status->rate;
-}
-
-/*
- * Function: cmpk_handle_tx_status()
- *
- * Overview: Firmware add a new tx feedback status to reduce rx command
- * packet buffer operation load.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- */
-static void
-cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg)
-{
- cmpk_tx_status_t rx_tx_sts;
-
- memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t));
- /* 2. Use tx feedback info to count TX statistics. */
- cmpk_count_tx_status(dev, &rx_tx_sts);
-}
-
-/*
- * Function: cmpk_handle_tx_rate_history()
- *
- * Overview: Firmware add a new tx rate history
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- */
-static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
-{
- cmpk_tx_rahis_t *ptxrate;
- u8 i, j;
- u16 length = sizeof(cmpk_tx_rahis_t);
- u32 *ptemp;
- struct r8192_priv *priv = ieee80211_priv(dev);
-
-#ifdef ENABLE_PS
- pAdapter->HalFunc.GetHwRegHandler(pAdapter,
- HW_VAR_RF_STATE,
- (pu1Byte)(&rtState));
- /*
- * When RF is off, we should not count the packet for hw/sw synchronize
- * reason, ie. there may be a duration while sw switch is changed and hw
- * switch is being changed.
- */
- if (rtState == eRfOff)
- return;
-#endif
- ptemp = (u32 *)pmsg;
-
- /*
- * Do endian transfer to word alignment(16 bits) for windows system.
- * You must do different endian transfer for linux and MAC OS
- */
- for (i = 0; i < (length/4); i++) {
- u16 temp1, temp2;
- temp1 = ptemp[i] & 0x0000FFFF;
- temp2 = ptemp[i] >> 16;
- ptemp[i] = (temp1 << 16) | temp2;
- }
-
- ptxrate = (cmpk_tx_rahis_t *)pmsg;
-
- if (ptxrate == NULL)
- return;
-
- for (i = 0; i < 16; i++) {
- /* Collect CCK rate packet num */
- if (i < 4)
- priv->stats.txrate.cck[i] += ptxrate->cck[i];
- /* Collect OFDM rate packet num */
- if (i < 8)
- priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
- for (j = 0; j < 4; j++)
- priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
- }
-
-}
-
-/*
- * Function: cmpk_message_handle_rx()
- *
- * Overview: In the function, we will capture different RX command packet
- * info. Every RX command packet element has different message
- * length and meaning in content. We only support three type of RX
- * command packet now. Please refer to document
- * ws-06-0063-rtl8190-command-packet-specification.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- */
-extern u32
-cmpk_message_handle_rx(
- struct net_device *dev,
- struct ieee80211_rx_stats *pstats)
-{
- struct r8192_priv *priv = ieee80211_priv(dev);
- int total_length;
- u8 cmd_length, exe_cnt = 0;
- u8 element_id;
- u8 *pcmd_buff;
-
- /*
- * 0. Check input arguments.
- * If is is a command queue message or pointer is null
- */
- if ((pstats == NULL))
- return 0; /* This is not a command packet. */
-
- /* 1. Read received command packet message length from RFD. */
- total_length = pstats->Length;
-
- /* 2. Read virtual address from RFD. */
- pcmd_buff = pstats->virtual_address;
-
- /* 3. Read command pakcet element id and length. */
- element_id = pcmd_buff[0];
-
- /*
- * 4. Check every received command packet conent according to different
- * element type. Because FW may aggregate RX command packet to minimize
- * transmit time between DRV and FW.
- */
-
- /* Add a counter to prevent to locked in the loop too long */
- while (total_length > 0 || exe_cnt++ > 100) {
- /* We support aggregation of different cmd in the same packet */
- element_id = pcmd_buff[0];
- switch (element_id) {
- case RX_TX_FEEDBACK:
- cmpk_handle_tx_feedback(dev, pcmd_buff);
- cmd_length = CMPK_RX_TX_FB_SIZE;
- break;
- case RX_INTERRUPT_STATUS:
- cmpk_handle_interrupt_status(dev, pcmd_buff);
- cmd_length = sizeof(cmpk_intr_sta_t);
- break;
- case BOTH_QUERY_CONFIG:
- cmpk_handle_query_config_rx(dev, pcmd_buff);
- cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
- break;
- case RX_TX_STATUS:
- cmpk_handle_tx_status(dev, pcmd_buff);
- cmd_length = CMPK_RX_TX_STS_SIZE;
- break;
- case RX_TX_PER_PKT_FEEDBACK:
- cmd_length = CMPK_RX_TX_FB_SIZE;
- break;
- case RX_TX_RATE_HISTORY:
- cmpk_handle_tx_rate_history(dev, pcmd_buff);
- cmd_length = CMPK_TX_RAHIS_SIZE;
- break;
- case RX_TX_TSSI_MEAN_BACK:
- {
- u32 *pMsg;
- pMsg = (u32 *)pcmd_buff;
- }
- cmd_length = 32;
- break;
- default:
- RT_TRACE(COMP_ERR, "(%s): unknown CMD Element\n",
- __func__);
- return 1; /* This is a command packet. */
- }
- priv->stats.rxcmdpkt[element_id]++;
- total_length -= cmd_length;
- pcmd_buff += cmd_length;
- }
- return 1; /* This is a command packet. */
-}
diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.h b/drivers/staging/rtl8192su/r819xU_cmdpkt.h
deleted file mode 100644
index 95885bee7a48..000000000000
--- a/drivers/staging/rtl8192su/r819xU_cmdpkt.h
+++ /dev/null
@@ -1,192 +0,0 @@
-#ifndef R819XUSB_CMDPKT_H
-#define R819XUSB_CMDPKT_H
-
-/*
- * Different command packets have dedicated message length and definition.
- */
-#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) /* 20 */
-#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */
-#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */
-#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)
-#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)
-#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t)
-
-/* For USB constant. */
-#define ISR_TxBcnOk BIT27 /* Transmit Beacon OK */
-#define ISR_TxBcnErr BIT26 /* Transmit Beacon Error */
-#define ISR_BcnTimerIntr BIT13 /* Beacon Timer Interrupt */
-
-/*
- * Define different command packet structures
- *
- * 1. RX side: TX feedback packet.
- */
-typedef struct tag_cmd_pkt_tx_feedback {
- /* DWORD 0 */
- u8 element_id; /* Command packet type. */
- u8 length; /* Command packet length. */
- /* TX Feedback Info Field */
- u8 TID:4;
- u8 fail_reason:3;
- u8 tok:1; /* Transmit ok. */
- u8 reserve1:4;
- u8 pkt_type:2;
- u8 bandwidth:1;
- u8 qos_pkt:1;
-
- /* DWORD 1 */
- u8 reserve2;
- /* TX Feedback Info Field */
- u8 retry_cnt;
- u16 pkt_id;
-
- /* DWORD 3 */
- u16 seq_num;
- u8 s_rate; /* Start rate. */
- u8 f_rate; /* Final rate. */
-
- /* DWORD 4 */
- u8 s_rts_rate;
- u8 f_rts_rate;
- u16 pkt_length;
-
- /* DWORD 5 */
- u16 reserve3;
- u16 duration;
-} cmpk_txfb_t;
-
-/*
- * 2. RX side: Interrupt status packet.
- * It includes Beacon State, Beacon Timer Interrupt
- * and other useful informations in MAC ISR Reg.
- */
-typedef struct tag_cmd_pkt_interrupt_status {
- u8 element_id; /* Command packet type. */
- u8 length; /* Command packet length. */
- u16 reserve;
- u32 interrupt_status; /* Interrupt Status. */
-} cmpk_intr_sta_t;
-
-
-/*
- * 3. TX side: Set configuration packet.
- */
-typedef struct tag_cmd_pkt_set_configuration {
- u8 element_id; /* Command packet type. */
- u8 length; /* Command packet length. */
- u16 reserve1;
- u8 cfg_reserve1:3;
- u8 cfg_size:2; /* Configuration info. */
- u8 cfg_type:2; /* Configuration info. */
- u8 cfg_action:1; /* Configuration info. */
- u8 cfg_reserve2; /* Configuration info. */
- u8 cfg_page:4; /* Configuration info. */
- u8 cfg_reserve3:4; /* Configuration info. */
- u8 cfg_offset; /* Configuration info. */
- u32 value;
- u32 mask;
-} cmpk_set_cfg_t;
-
-/*
- * 4. Both side : TX/RX query configuraton packet.
- * The query structure is the same as set configuration.
- */
-#define cmpk_query_cfg_t cmpk_set_cfg_t
-
-/*
- * 5. Multi packet feedback status.
- */
-typedef struct tag_tx_stats_feedback {
- /*
- * For endian transfer
- * Driver will not the same as firmware structure.
- */
- /* DW 0 */
- u16 reserve1;
- u8 length; /* Command packet length */
- u8 element_id; /* Command packet type */
-
- /* DW 1 */
- u16 txfail; /* Tx Fail count */
- u16 txok; /* Tx ok count */
-
- /* DW 2 */
- u16 txmcok; /* tx multicast */
- u16 txretry; /* Tx Retry count */
-
- /* DW 3 */
- u16 txucok; /* tx unicast */
- u16 txbcok; /* tx broadcast */
-
- /* DW 4 */
- u16 txbcfail;
- u16 txmcfail;
-
- /* DW 5 */
- u16 reserve2;
- u16 txucfail;
-
- /* DW 6-8 */
- u32 txmclength;
- u32 txbclength;
- u32 txuclength;
-
- /* DW 9 */
- u16 reserve3_23;
- u8 reserve3_1;
- u8 rate;
-} __attribute__((packed)) cmpk_tx_status_t;
-
-/*
- * 6. Debug feedback message.
- */
-typedef struct tag_rx_debug_message_feedback {
- /* For endian transfer --> for driver */
- /* DW 0 */
- u16 reserve1;
- u8 length; /* Command packet length */
- u8 element_id; /* Command packet type */
-} cmpk_rx_dbginfo_t;
-
-/*
- * Define transmit rate history. For big endian format.
- */
-typedef struct tag_tx_rate_history {
- /* For endian transfer --> for driver */
- /* DW 0 */
- u8 element_id; /* Command packet type */
- u8 length; /* Command packet length */
- u16 reserved1;
- /* DW 1-2 CCK rate counter */
- u16 cck[4];
- /* DW 3-6 */
- u16 ofdm[8];
- u16 ht_mcs[4][16];
-} __attribute__((packed)) cmpk_tx_rahis_t;
-
-typedef enum tag_command_packet_directories {
- RX_TX_FEEDBACK = 0,
- RX_INTERRUPT_STATUS = 1,
- TX_SET_CONFIG = 2,
- BOTH_QUERY_CONFIG = 3,
- RX_TX_STATUS = 4,
- RX_DBGINFO_FEEDBACK = 5,
- RX_TX_PER_PKT_FEEDBACK = 6,
- RX_TX_RATE_HISTORY = 7,
- RX_TX_TSSI_MEAN_BACK = 8,
- RX_CMD_ELE_MAX
-} cmpk_element_e;
-
-extern bool cmpk_message_handle_tx(struct net_device *dev,
- u8 *codevirtualaddress,
- u32 packettype,
- u32 buffer_len);
-
-extern u32 cmpk_message_handle_rx(struct net_device *dev,
- struct ieee80211_rx_stats *pstats);
-
-extern bool SendTxCommandPacket(struct net_device *dev,
- void *pData,
- u32 DataLen);
-
-#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index 192123fbec7f..c8ca9d8ed5d2 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -2391,7 +2391,7 @@ static inline void update_network(struct ieee80211_network *dst,
if(src->wmm_param[0].ac_aci_acm_aifsn|| \
src->wmm_param[1].ac_aci_acm_aifsn|| \
src->wmm_param[2].ac_aci_acm_aifsn|| \
- src->wmm_param[1].ac_aci_acm_aifsn) {
+ src->wmm_param[3].ac_aci_acm_aifsn) {
memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
}
//dst->QoS_Enable = src->QoS_Enable;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index a2e84c578579..bc8c42533693 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -449,7 +449,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
}while(!ieee->channel_map[ch]);
#endif
- /* this fuction can be called in two situations
+ /* this function can be called in two situations
* 1- We have switched to ad-hoc mode and we are
* performing a complete syncro scan before conclude
* there are no interesting cell and to create a
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 1ff7850cc1e7..494f180acc26 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -1534,7 +1534,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
* 1. check whether there's tx irq available, for it's a completion return
* function, it should contain enough tx irq;
* 2. check pakcet type;
- * 3. intialize sendlist, check whether the to-be send packet no greater than 1
+ * 3. initialize sendlist, check whether the to-be send packet no greater than 1
* 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
* 5. check whehter the packet could be sent, otherwise just insert to wait head
* */
@@ -5793,10 +5793,12 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
struct net_device *dev = NULL;
struct r8192_priv *priv= NULL;
struct usb_device *udev = interface_to_usbdev(intf);
+ int ret;
RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
dev = alloc_ieee80211(sizeof(struct r8192_priv));
-
+ if (dev == NULL)
+ return -ENOMEM;
usb_set_intfdata(intf, dev);
SET_NETDEV_DEV(dev, &intf->dev);
@@ -5826,12 +5828,16 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
RT_TRACE(COMP_INIT, "Driver probe completed1\n");
if(rtl8192_init(dev)!=0){
RT_TRACE(COMP_ERR, "Initialization failed");
+ ret = -ENODEV;
goto fail;
}
netif_carrier_off(dev);
netif_stop_queue(dev);
- register_netdev(dev);
+ ret = register_netdev(dev);
+ if (ret)
+ goto fail2;
+
RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
rtl8192_proc_init_one(dev);
@@ -5839,13 +5845,20 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
RT_TRACE(COMP_INIT, "Driver probe completed\n");
return 0;
-
+fail2:
+ rtl8192_down(dev);
+ if (priv->pFirmware) {
+ kfree(priv->pFirmware);
+ priv->pFirmware = NULL;
+ }
+ rtl8192_usb_deleteendpoints(dev);
+ destroy_workqueue(priv->priv_wq);
+ mdelay(10);
fail:
free_ieee80211(dev);
RT_TRACE(COMP_ERR, "wlan driver load failed\n");
- return -ENODEV;
-
+ return ret;
}
//detach all the work and timer structure declared or inititialize in r8192U_init function.
diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c
index b136ee48828a..49ae1705377b 100644
--- a/drivers/staging/rtl8192u/r819xU_firmware.c
+++ b/drivers/staging/rtl8192u/r819xU_firmware.c
@@ -1,7 +1,7 @@
/**************************************************************************************************
* Procedure: Init boot code/firmware code/data session
*
- * Description: This routine will intialize firmware. If any error occurs during the initialization
+ * Description: This routine will initialize firmware. If any error occurs during the initialization
* process, the routine shall terminate immediately and return fail.
* NIC driver should call NdisOpenFile only from MiniportInitialize.
*
diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig
new file mode 100644
index 000000000000..1e9a230a4db1
--- /dev/null
+++ b/drivers/staging/rtl8712/Kconfig
@@ -0,0 +1,18 @@
+config R8712U
+ tristate "RealTek RTL8712U (RTL8192SU) Wireless LAN NIC driver"
+ depends on WLAN && USB
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ default N
+ ---help---
+ This option adds the Realtek RTL8712 USB device such as the D-Link DWA-130.
+ If built as a module, it will be called r8712u.
+
+config R8712_AP
+ bool "Realtek RTL8712U AP code"
+ depends on R8712U
+ default N
+ ---help---
+ This option allows the Realtek RTL8712 USB device to be an Access Point.
+
+
diff --git a/drivers/staging/rtl8712/Makefile b/drivers/staging/rtl8712/Makefile
new file mode 100644
index 000000000000..1ccd251fde47
--- /dev/null
+++ b/drivers/staging/rtl8712/Makefile
@@ -0,0 +1,34 @@
+r8712u-objs := \
+ rtl871x_cmd.o \
+ rtl8712_cmd.o \
+ rtl871x_security.o \
+ rtl871x_eeprom.o \
+ rtl8712_efuse.o \
+ hal_init.o \
+ usb_halinit.o \
+ usb_ops.o \
+ usb_ops_linux.o \
+ rtl871x_io.o \
+ rtl8712_io.o \
+ rtl871x_ioctl_linux.o \
+ rtl871x_ioctl_rtl.o \
+ rtl871x_ioctl_set.o \
+ rtl8712_led.o \
+ rtl871x_mlme.o \
+ ieee80211.o \
+ rtl871x_mp_ioctl.o \
+ rtl871x_mp.o \
+ mlme_linux.o \
+ recv_linux.o \
+ xmit_linux.o \
+ usb_intf.o \
+ os_intfs.o \
+ rtl871x_pwrctrl.o \
+ rtl8712_recv.o \
+ rtl871x_recv.o \
+ rtl871x_sta_mgt.o \
+ rtl871x_xmit.o \
+ rtl8712_xmit.o
+
+obj-$(CONFIG_R8712U) := r8712u.o
+
diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO
new file mode 100644
index 000000000000..5c888214666e
--- /dev/null
+++ b/drivers/staging/rtl8712/TODO
@@ -0,0 +1,16 @@
+TODO:
+- merge Realtek's bugfixes and new features into the driver
+- switch to use LIB80211
+- switch to use MAC80211
+- checkpatch.pl fixes - only a few remain
+- sparse fixes
+- switch from large inline firmware file to use the firmware interface
+ and add the file to the linux-firmware package.
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
+Larry Finger <Larry.Finger@lwfinger.net> and
+Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
+
+
+
+
diff --git a/drivers/staging/rtl8712/basic_types.h b/drivers/staging/rtl8712/basic_types.h
new file mode 100644
index 000000000000..a0538a8a6703
--- /dev/null
+++ b/drivers/staging/rtl8712/basic_types.h
@@ -0,0 +1,23 @@
+#ifndef __BASIC_TYPES_H__
+#define __BASIC_TYPES_H__
+
+#define SUCCESS 0
+#define FAIL (-1)
+
+#include <linux/types.h>
+
+#define SIZE_T __kernel_size_t
+#define sint signed int
+#define FIELD_OFFSET(s, field) ((addr_t)&((s *)(0))->field)
+
+/* Should we extend this to be host_addr_t and target_addr_t for case:
+ * host : x86_64
+ * target : mips64
+ */
+#define addr_t unsigned long
+
+#define MEM_ALIGNMENT_OFFSET (sizeof(SIZE_T))
+#define MEM_ALIGNMENT_PADDING (sizeof(SIZE_T) - 1)
+
+#endif /*__BASIC_TYPES_H__*/
+
diff --git a/drivers/staging/rtl8712/big_endian.h b/drivers/staging/rtl8712/big_endian.h
new file mode 100644
index 000000000000..8512d1b5919d
--- /dev/null
+++ b/drivers/staging/rtl8712/big_endian.h
@@ -0,0 +1,69 @@
+#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H
+#define _LINUX_BYTEORDER_BIG_ENDIAN_H
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#include "swab.h"
+
+#define __constant_htonl(x) ((__u32)(x))
+#define __constant_ntohl(x) ((__u32)(x))
+#define __constant_htons(x) ((__u16)(x))
+#define __constant_ntohs(x) ((__u16)(x))
+#define __constant_cpu_to_le64(x) ___constant_swab64((x))
+#define __constant_le64_to_cpu(x) ___constant_swab64((x))
+#define __constant_cpu_to_le32(x) ___constant_swab32((x))
+#define __constant_le32_to_cpu(x) ___constant_swab32((x))
+#define __constant_cpu_to_le16(x) ___constant_swab16((x))
+#define __constant_le16_to_cpu(x) ___constant_swab16((x))
+#define __constant_cpu_to_be64(x) ((__u64)(x))
+#define __constant_be64_to_cpu(x) ((__u64)(x))
+#define __constant_cpu_to_be32(x) ((__u32)(x))
+#define __constant_be32_to_cpu(x) ((__u32)(x))
+#define __constant_cpu_to_be16(x) ((__u16)(x))
+#define __constant_be16_to_cpu(x) ((__u16)(x))
+#define __cpu_to_le64(x) __swab64((x))
+#define __le64_to_cpu(x) __swab64((x))
+#define __cpu_to_le32(x) __swab32((x))
+#define __le32_to_cpu(x) __swab32((x))
+#define __cpu_to_le16(x) __swab16((x))
+#define __le16_to_cpu(x) __swab16((x))
+#define __cpu_to_be64(x) ((__u64)(x))
+#define __be64_to_cpu(x) ((__u64)(x))
+#define __cpu_to_be32(x) ((__u32)(x))
+#define __be32_to_cpu(x) ((__u32)(x))
+#define __cpu_to_be16(x) ((__u16)(x))
+#define __be16_to_cpu(x) ((__u16)(x))
+#define __cpu_to_le64p(x) __swab64p((x))
+#define __le64_to_cpup(x) __swab64p((x))
+#define __cpu_to_le32p(x) __swab32p((x))
+#define __le32_to_cpup(x) __swab32p((x))
+#define __cpu_to_le16p(x) __swab16p((x))
+#define __le16_to_cpup(x) __swab16p((x))
+#define __cpu_to_be64p(x) (*(__u64 *)(x))
+#define __be64_to_cpup(x) (*(__u64 *)(x))
+#define __cpu_to_be32p(x) (*(__u32 *)(x))
+#define __be32_to_cpup(x) (*(__u32 *)(x))
+#define __cpu_to_be16p(x) (*(__u16 *)(x))
+#define __be16_to_cpup(x) (*(__u16 *)(x))
+#define __cpu_to_le64s(x) __swab64s((x))
+#define __le64_to_cpus(x) __swab64s((x))
+#define __cpu_to_le32s(x) __swab32s((x))
+#define __le32_to_cpus(x) __swab32s((x))
+#define __cpu_to_le16s(x) __swab16s((x))
+#define __le16_to_cpus(x) __swab16s((x))
+#define __cpu_to_be64s(x) do {} while (0)
+#define __be64_to_cpus(x) do {} while (0)
+#define __cpu_to_be32s(x) do {} while (0)
+#define __be32_to_cpus(x) do {} while (0)
+#define __cpu_to_be16s(x) do {} while (0)
+#define __be16_to_cpus(x) do {} while (0)
+
+#include "generic.h"
+
+#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */
+
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
new file mode 100644
index 000000000000..3bb66dc2eb2c
--- /dev/null
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------
+
+ For type defines and data structure defines
+
+-----------------------------------------------------------------------*/
+#ifndef __DRV_TYPES_H__
+#define __DRV_TYPES_H__
+
+struct _adapter;
+
+#include "osdep_service.h"
+#include "wlan_bssdef.h"
+#include "rtl8712_spec.h"
+#include "rtl8712_hal.h"
+
+enum _NIC_VERSION {
+ RTL8711_NIC,
+ RTL8712_NIC,
+ RTL8713_NIC,
+ RTL8716_NIC
+};
+
+struct _adapter;
+
+struct qos_priv {
+ /* bit mask option: u-apsd, s-apsd, ts, block ack... */
+ unsigned int qos_option;
+};
+
+#include "rtl871x_ht.h"
+#include "rtl871x_cmd.h"
+#include "wlan_bssdef.h"
+#include "rtl871x_xmit.h"
+#include "rtl871x_recv.h"
+#include "rtl871x_security.h"
+#include "rtl871x_pwrctrl.h"
+#include "rtl871x_io.h"
+#include "rtl871x_eeprom.h"
+#include "sta_info.h"
+#include "rtl871x_mlme.h"
+#include "rtl871x_mp.h"
+#include "rtl871x_debug.h"
+#include "rtl871x_rf.h"
+#include "rtl871x_event.h"
+#include "rtl871x_led.h"
+
+#define SPEC_DEV_ID_NONE BIT(0)
+#define SPEC_DEV_ID_DISABLE_HT BIT(1)
+#define SPEC_DEV_ID_ENABLE_PS BIT(2)
+
+struct specific_device_id {
+ u32 flags;
+ u16 idVendor;
+ u16 idProduct;
+
+};
+
+struct registry_priv {
+ u8 chip_version;
+ u8 rfintfs;
+ u8 lbkmode;
+ u8 hci;
+ u8 network_mode; /*infra, ad-hoc, auto*/
+ struct ndis_802_11_ssid ssid;
+ u8 channel;/* ad-hoc support requirement */
+ u8 wireless_mode;/* A, B, G, auto */
+ u8 vrtl_carrier_sense; /*Enable, Disable, Auto*/
+ u8 vcs_type;/*RTS/CTS, CTS-to-self*/
+ u16 rts_thresh;
+ u16 frag_thresh;
+ u8 preamble;/*long, short, auto*/
+ u8 scan_mode;/*active, passive*/
+ u8 adhoc_tx_pwr;
+ u8 soft_ap;
+ u8 smart_ps;
+ u8 power_mgnt;
+ u8 radio_enable;
+ u8 long_retry_lmt;
+ u8 short_retry_lmt;
+ u16 busy_thresh;
+ u8 ack_policy;
+ u8 mp_mode;
+ u8 software_encrypt;
+ u8 software_decrypt;
+ /* UAPSD */
+ u8 wmm_enable;
+ u8 uapsd_enable;
+ u8 uapsd_max_sp;
+ u8 uapsd_acbk_en;
+ u8 uapsd_acbe_en;
+ u8 uapsd_acvi_en;
+ u8 uapsd_acvo_en;
+
+ struct wlan_bssid_ex dev_network;
+
+ u8 ht_enable;
+ u8 cbw40_enable;
+ u8 ampdu_enable;/*for tx*/
+ u8 rf_config;
+ u8 low_power;
+ u8 wifi_test;
+};
+
+/* For registry parameters */
+#define RGTRY_OFT(field) ((addr_t)FIELD_OFFSET(struct registry_priv, field))
+#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field)
+#define BSSID_OFT(field) ((addr_t)FIELD_OFFSET(struct ndis_wlan_bssid_ex, \
+ field))
+#define BSSID_SZ(field) sizeof(((struct ndis_wlan_bssid_ex *)0)->field)
+
+struct dvobj_priv {
+ struct _adapter *padapter;
+ u32 nr_endpoint;
+ u8 ishighspeed;
+ uint(*inirp_init)(struct _adapter *adapter);
+ uint(*inirp_deinit)(struct _adapter *adapter);
+ struct semaphore usb_suspend_sema;
+ struct usb_device *pusbdev;
+};
+
+struct _adapter {
+ struct dvobj_priv dvobjpriv;
+ struct mlme_priv mlmepriv;
+ struct cmd_priv cmdpriv;
+ struct evt_priv evtpriv;
+ struct io_queue *pio_queue;
+ struct xmit_priv xmitpriv;
+ struct recv_priv recvpriv;
+ struct sta_priv stapriv;
+ struct security_priv securitypriv;
+ struct registry_priv registrypriv;
+ struct wlan_acl_pool acl_list;
+ struct pwrctrl_priv pwrctrlpriv;
+ struct eeprom_priv eeprompriv;
+ struct hal_priv halpriv;
+ struct led_priv ledpriv;
+ struct mp_priv mppriv;
+ s32 bDriverStopped;
+ s32 bSurpriseRemoved;
+ u32 IsrContent;
+ u32 ImrContent;
+ u8 EepromAddressSize;
+ u8 hw_init_completed;
+ struct task_struct *cmdThread;
+ pid_t evtThread;
+ struct task_struct *xmitThread;
+ pid_t recvThread;
+ uint(*dvobj_init)(struct _adapter *adapter);
+ void (*dvobj_deinit)(struct _adapter *adapter);
+ struct net_device *pnetdev;
+ int bup;
+ struct net_device_stats stats;
+ struct iw_statistics iwstats;
+ int pid; /*process id from UI*/
+};
+
+static inline u8 *myid(struct eeprom_priv *peepriv)
+{
+ return peepriv->mac_addr;
+}
+
+u8 r8712_usb_hal_bus_init(struct _adapter *adapter);
+
+#endif /*__DRV_TYPES_H__*/
+
diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h
new file mode 100644
index 000000000000..ba8d777d8e10
--- /dev/null
+++ b/drivers/staging/rtl8712/ethernet.h
@@ -0,0 +1,23 @@
+#ifndef __INC_ETHERNET_H
+#define __INC_ETHERNET_H
+
+#define ETHERNET_ADDRESS_LENGTH 6 /*!< Ethernet Address Length*/
+#define ETHERNET_HEADER_SIZE 14 /*!< Ethernet Header Length*/
+#define LLC_HEADER_SIZE 6 /*!< LLC Header Length*/
+#define TYPE_LENGTH_FIELD_SIZE 2 /*!< Type/Length Size*/
+#define MINIMUM_ETHERNET_PACKET_SIZE 60 /*!< Min Ethernet Packet Size*/
+#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 /*!< Max Ethernet Packet Size*/
+
+/*!< Is Multicast Address? */
+#define RT_ETH_IS_MULTICAST(_pAddr) ((((u8 *)(_pAddr))[0]&0x01) != 0)
+/*!< Is Broadcast Address? */
+#define RT_ETH_IS_BROADCAST(_pAddr) ( \
+ ((u8 *)(_pAddr))[0] == 0xff && \
+ ((u8 *)(_pAddr))[1] == 0xff && \
+ ((u8 *)(_pAddr))[2] == 0xff && \
+ ((u8 *)(_pAddr))[3] == 0xff && \
+ ((u8 *)(_pAddr))[4] == 0xff && \
+ ((u8 *)(_pAddr))[5] == 0xff)
+
+#endif /* #ifndef __INC_ETHERNET_H */
+
diff --git a/drivers/staging/rtl8712/farray.h b/drivers/staging/rtl8712/farray.h
new file mode 100644
index 000000000000..921777269709
--- /dev/null
+++ b/drivers/staging/rtl8712/farray.h
@@ -0,0 +1,10197 @@
+/* Firmware */
+static const unsigned char f_array[122328] = {
+0x12, 0x87, 0xEC, 0x11, 0x30, 0x00, 0x00, 0x00, 0x08, 0xE8, 0x00, 0x00,
+0x50, 0xF5, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x98, 0xF3, 0x00, 0x00,
+0xF2, 0x00, 0x00, 0x00, 0x05, 0x30, 0x16, 0x53, 0x87, 0x12, 0x12, 0x01,
+0x00, 0x00, 0x12, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01,
+0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x10,
+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,
+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,
+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,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x10, 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, 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, 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, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x1A, 0x3C, 0x80, 0x03, 0x5A, 0x37, 0x00, 0x80, 0x1B, 0x3C,
+0x80, 0x00, 0x7B, 0x37, 0x00, 0x00, 0x5B, 0xAF, 0x25, 0xB0, 0x1A, 0x3C,
+0x18, 0x03, 0x5A, 0x37, 0x00, 0x80, 0x1B, 0x3C, 0x80, 0x00, 0x7B, 0x37,
+0x00, 0x00, 0x5B, 0xAF, 0x01, 0x80, 0x1A, 0x3C, 0x24, 0xE2, 0x5A, 0x27,
+0x08, 0x00, 0x40, 0x03, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xA1, 0xAF, 0x08, 0x00, 0xA2, 0xAF,
+0x0C, 0x00, 0xA3, 0xAF, 0x10, 0x00, 0xA4, 0xAF, 0x14, 0x00, 0xA5, 0xAF,
+0x18, 0x00, 0xA6, 0xAF, 0x1C, 0x00, 0xA7, 0xAF, 0x20, 0x00, 0xA8, 0xAF,
+0x24, 0x00, 0xA9, 0xAF, 0x28, 0x00, 0xAA, 0xAF, 0x2C, 0x00, 0xAB, 0xAF,
+0x30, 0x00, 0xAC, 0xAF, 0x34, 0x00, 0xAD, 0xAF, 0x38, 0x00, 0xAE, 0xAF,
+0x3C, 0x00, 0xAF, 0xAF, 0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00,
+0x00, 0x70, 0x0A, 0x40, 0x40, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0xB1, 0xAF,
+0x48, 0x00, 0xB2, 0xAF, 0x4C, 0x00, 0xB3, 0xAF, 0x50, 0x00, 0xB4, 0xAF,
+0x54, 0x00, 0xB5, 0xAF, 0x58, 0x00, 0xB6, 0xAF, 0x5C, 0x00, 0xB7, 0xAF,
+0x60, 0x00, 0xB8, 0xAF, 0x64, 0x00, 0xB9, 0xAF, 0x68, 0x00, 0xBC, 0xAF,
+0x6C, 0x00, 0xBD, 0xAF, 0x70, 0x00, 0xBE, 0xAF, 0x74, 0x00, 0xBF, 0xAF,
+0x78, 0x00, 0xA8, 0xAF, 0x7C, 0x00, 0xA9, 0xAF, 0x80, 0x00, 0xAA, 0xAF,
+0x17, 0x38, 0x00, 0x08, 0x21, 0x20, 0xA0, 0x03, 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, 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, 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, 0xE0, 0xFF, 0xBD, 0x27,
+0x14, 0x00, 0xB1, 0xAF, 0x00, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x11, 0x3C,
+0x18, 0x03, 0x23, 0x36, 0x00, 0x03, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC,
+0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF,
+0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C,
+0x03, 0x00, 0x47, 0x34, 0x00, 0x00, 0xE3, 0x90, 0x02, 0x80, 0x0A, 0x3C,
+0x02, 0x80, 0x0B, 0x3C, 0xFF, 0x00, 0x70, 0x30, 0x00, 0x36, 0x10, 0x00,
+0x10, 0x00, 0x02, 0x32, 0x03, 0x36, 0x06, 0x00, 0x17, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x12, 0x3C, 0xFC, 0x5C, 0x42, 0x8D, 0x60, 0x1B, 0x44, 0x26,
+0x64, 0x37, 0x83, 0x94, 0x01, 0x00, 0x45, 0x24, 0x10, 0x00, 0x02, 0x24,
+0xB0, 0x03, 0x29, 0x36, 0x1C, 0x03, 0x28, 0x36, 0x00, 0x00, 0xE2, 0xA0,
+0x07, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x68, 0x37, 0x82, 0x94,
+0x64, 0x37, 0x80, 0xA4, 0x68, 0x37, 0x80, 0xA4, 0x00, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x02, 0xAD, 0x00, 0x00, 0x20, 0xAD, 0x10, 0x5E, 0x62, 0x8D,
+0x01, 0x00, 0x63, 0x24, 0xFC, 0x5C, 0x45, 0xAD, 0x01, 0x00, 0x42, 0x24,
+0x10, 0x5E, 0x62, 0xAD, 0x64, 0x37, 0x83, 0xA4, 0x29, 0x00, 0xC0, 0x04,
+0x42, 0xB0, 0x02, 0x3C, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x02, 0x32, 0x0F, 0x00, 0x40, 0x14, 0x60, 0x1B, 0x44, 0x26,
+0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x80, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x65, 0x00,
+0x08, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA4,
+0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4, 0x42, 0xB0, 0x02, 0x3C,
+0x40, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0,
+0x25, 0x62, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x44, 0x26,
+0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x80, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x65, 0x00,
+0x08, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA4,
+0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4, 0x80, 0xFF, 0x03, 0x24,
+0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x44, 0x22, 0x00, 0x74,
+0x00, 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x84, 0x30, 0x0B, 0x00, 0x82, 0x2C, 0xFF, 0xFF, 0xE7, 0x30,
+0x10, 0x00, 0xA8, 0x93, 0x19, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00, 0x88, 0xE6, 0x63, 0x24,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xB0, 0x02, 0x3C,
+0x78, 0x00, 0x44, 0x34, 0x07, 0x00, 0xE2, 0x30, 0x00, 0x00, 0x85, 0xAC,
+0x04, 0x00, 0x86, 0xAC, 0x04, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00,
+0xF8, 0xFF, 0xE2, 0x30, 0x08, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x47, 0x30,
+0x21, 0x10, 0xE8, 0x00, 0x00, 0x80, 0x03, 0x3C, 0x08, 0x00, 0x82, 0xAC,
+0x25, 0x10, 0x43, 0x00, 0x08, 0x00, 0x82, 0xAC, 0x01, 0x00, 0x03, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x6C, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x60, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x54, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x48, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x3C, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x30, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x24, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x18, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C,
+0x2E, 0x01, 0x00, 0x08, 0x0C, 0x00, 0x44, 0x34, 0x2E, 0x01, 0x00, 0x08,
+0x43, 0xB0, 0x04, 0x3C, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x18, 0x03, 0x42, 0x34, 0x6C, 0x05, 0x63, 0x24, 0x00, 0x00, 0x43, 0xAC,
+0x01, 0x00, 0x05, 0x24, 0x43, 0xB0, 0x02, 0x3C, 0x04, 0x28, 0x85, 0x00,
+0x88, 0x00, 0x44, 0x34, 0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
+0xFF, 0xFF, 0x42, 0x30, 0x05, 0x00, 0x43, 0x2C, 0xFD, 0xFF, 0x60, 0x14,
+0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0x42, 0x30, 0x24, 0x10, 0x45, 0x00, 0xF5, 0xFF, 0x40, 0x1C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x08, 0x3C, 0x00, 0x80, 0x02, 0x3C, 0xC8, 0xFF, 0xBD, 0x27,
+0x18, 0x03, 0x03, 0x35, 0xC8, 0x05, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC,
+0x30, 0x00, 0xB6, 0xAF, 0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x0C, 0x00, 0xF2, 0x84,
+0x08, 0x00, 0xF5, 0x8C, 0xFF, 0x00, 0xC6, 0x30, 0x00, 0x01, 0x02, 0x24,
+0x23, 0x10, 0x46, 0x00, 0xFF, 0xFF, 0x51, 0x30, 0xD0, 0x03, 0x08, 0x35,
+0xFF, 0x00, 0x96, 0x30, 0x00, 0x00, 0x12, 0xAD, 0x21, 0xA0, 0xA0, 0x00,
+0x21, 0x30, 0xC5, 0x00, 0x00, 0x00, 0x15, 0xAD, 0x21, 0x20, 0xC0, 0x02,
+0x21, 0x28, 0xA0, 0x02, 0x21, 0x38, 0x20, 0x02, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x23, 0x18, 0x51, 0x02, 0xFF, 0xFF, 0x82, 0x32,
+0x00, 0x94, 0x03, 0x00, 0x03, 0x94, 0x12, 0x00, 0xB4, 0x01, 0x00, 0x08,
+0x02, 0x9A, 0x02, 0x00, 0x28, 0xB0, 0x03, 0x3C, 0xC0, 0x10, 0x13, 0x00,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x25, 0xB0, 0x10, 0x3C,
+0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x93, 0x30, 0x00, 0x22, 0x13, 0x00,
+0xFF, 0xFF, 0x43, 0x32, 0x01, 0x01, 0x45, 0x2A, 0x21, 0xA0, 0x82, 0x00,
+0x21, 0xA8, 0xB1, 0x02, 0xD0, 0x03, 0x02, 0x36, 0x00, 0x01, 0x11, 0x24,
+0x0B, 0x88, 0x65, 0x00, 0x21, 0x20, 0xC0, 0x02, 0x00, 0x00, 0x53, 0xAC,
+0x5B, 0x01, 0x00, 0x0C, 0xB0, 0x03, 0x10, 0x36, 0x21, 0x30, 0x80, 0x02,
+0x21, 0x20, 0xC0, 0x02, 0x21, 0x28, 0xA0, 0x02, 0x21, 0x38, 0x20, 0x02,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x23, 0x18, 0x51, 0x02,
+0x00, 0x94, 0x03, 0x00, 0x03, 0x94, 0x12, 0x00, 0x00, 0x00, 0x12, 0xAE,
+0xE2, 0xFF, 0x40, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0x21, 0x50, 0x80, 0x00, 0x04, 0x00, 0x8D, 0x8C, 0x0C, 0x00, 0x4B, 0x8D,
+0x08, 0x00, 0x84, 0x8C, 0xFF, 0xE0, 0x02, 0x3C, 0x10, 0x00, 0x47, 0x8D,
+0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0xA9, 0x31, 0x24, 0x20, 0x82, 0x00,
+0x00, 0x1E, 0x09, 0x00, 0x02, 0x14, 0x0B, 0x00, 0x25, 0x40, 0x83, 0x00,
+0x21, 0x78, 0xA0, 0x00, 0xB7, 0x00, 0xE0, 0x04, 0x07, 0x00, 0x44, 0x30,
+0x00, 0x00, 0x42, 0x95, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0F, 0x42, 0x28,
+0xB9, 0x00, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C, 0x02, 0x80, 0x0E, 0x3C,
+0x08, 0x00, 0x48, 0xAD, 0x60, 0x1B, 0xC3, 0x25, 0xC6, 0x3D, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x40, 0x14, 0xC0, 0x30, 0x09, 0x00,
+0xC6, 0x40, 0x62, 0x90, 0xFF, 0xDF, 0x03, 0x3C, 0xFF, 0xFF, 0x63, 0x34,
+0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30, 0x24, 0x18, 0x03, 0x01,
+0x40, 0x17, 0x02, 0x00, 0x25, 0x40, 0x62, 0x00, 0x08, 0x00, 0x48, 0xAD,
+0xC0, 0x30, 0x09, 0x00, 0x21, 0x10, 0xC9, 0x00, 0x80, 0x10, 0x02, 0x00,
+0x21, 0x10, 0x49, 0x00, 0x80, 0x10, 0x02, 0x00, 0x60, 0x1B, 0xC9, 0x25,
+0x21, 0x28, 0x49, 0x00, 0x08, 0x25, 0xA3, 0x8C, 0x01, 0x00, 0x0C, 0x24,
+0x02, 0x13, 0x03, 0x00, 0x01, 0x00, 0x42, 0x30, 0xB5, 0x00, 0x4C, 0x10,
+0x42, 0x18, 0x03, 0x00, 0x82, 0x11, 0x08, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xC0, 0xFF, 0x02, 0x24,
+0x24, 0x10, 0x02, 0x01, 0x04, 0x00, 0x48, 0x34, 0x08, 0x00, 0x48, 0xAD,
+0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x6A, 0x00, 0x60, 0x14, 0x21, 0x20, 0xC9, 0x00, 0xD4, 0x23, 0x83, 0x8C,
+0xBF, 0xFF, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x40, 0x00, 0x63, 0x30,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0x83, 0x8C,
+0x7F, 0xF8, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x07, 0x63, 0x30,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xC6, 0x3D, 0x22, 0x91,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x14, 0x42, 0x17, 0x08, 0x00,
+0x01, 0x00, 0x44, 0x30, 0xB1, 0x00, 0x8C, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0xC4, 0x25, 0x21, 0x20, 0xC4, 0x00, 0xD4, 0x23, 0x83, 0x8C,
+0xFF, 0xF7, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x00, 0x08, 0x63, 0x30,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0x83, 0x8C,
+0xFF, 0xEF, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x00, 0x10, 0x63, 0x30,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x60, 0x1B, 0xC5, 0x25,
+0x21, 0x30, 0xC5, 0x00, 0xD4, 0x23, 0xC4, 0x8C, 0xFD, 0xFF, 0x02, 0x3C,
+0x02, 0x00, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00,
+0x24, 0x10, 0xE2, 0x00, 0x25, 0x38, 0x44, 0x00, 0x10, 0x00, 0x47, 0xAD,
+0xB0, 0x1B, 0xA3, 0x94, 0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0xC2, 0x1B, 0x03, 0x00, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x1C, 0x03, 0x00,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x3B, 0x41, 0xA3, 0x90,
+0xE7, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30,
+0x24, 0x10, 0xE2, 0x00, 0xC0, 0x1C, 0x03, 0x00, 0x25, 0x38, 0x43, 0x00,
+0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0xC4, 0x8C, 0xFF, 0xFD, 0x02, 0x3C,
+0x00, 0x02, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00,
+0x24, 0x10, 0xE2, 0x00, 0x25, 0x38, 0x44, 0x00, 0x10, 0x00, 0x47, 0xAD,
+0xB0, 0x1B, 0xA3, 0x94, 0xFF, 0xFB, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0xC2, 0x1B, 0x03, 0x00, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x1E, 0x03, 0x00,
+0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x3B, 0x41, 0xA3, 0x90,
+0xFF, 0xE7, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30,
+0x24, 0x10, 0xE2, 0x00, 0xC0, 0x1E, 0x03, 0x00, 0x25, 0x38, 0x43, 0x00,
+0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0xC3, 0x8C, 0xC0, 0xFF, 0x02, 0x24,
+0x24, 0x10, 0xE2, 0x00, 0x3F, 0x00, 0x63, 0x30, 0x25, 0x10, 0x43, 0x00,
+0x10, 0x00, 0x42, 0xAD, 0xD8, 0x23, 0xC4, 0x8C, 0x14, 0x00, 0x43, 0x8D,
+0xFF, 0xFF, 0x02, 0x3C, 0xFF, 0x7F, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x80, 0x84, 0x30, 0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0xAD,
+0xDA, 0x23, 0xC4, 0x94, 0xE0, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x1F, 0x00, 0x84, 0x30, 0x24, 0x18, 0x62, 0x00, 0x00, 0x24, 0x04, 0x00,
+0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0xAD, 0x02, 0x00, 0x43, 0x91,
+0x02, 0x14, 0x0D, 0x00, 0x01, 0x00, 0x42, 0x30, 0x27, 0x00, 0x40, 0x10,
+0x21, 0x30, 0x6F, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0xE4, 0x1D, 0x85, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA2, 0x24, 0xE4, 0x1D, 0x82, 0xA4,
+0x0C, 0x00, 0x43, 0x8D, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30,
+0xFF, 0xFF, 0x42, 0x34, 0x00, 0x24, 0x05, 0x00, 0x24, 0x18, 0x62, 0x00,
+0x25, 0x58, 0x83, 0x00, 0x0C, 0x00, 0x4B, 0xAD, 0x16, 0x00, 0xC2, 0x94,
+0x00, 0x19, 0x05, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0x0F, 0x00, 0x42, 0x30,
+0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x00, 0x00, 0x43, 0x95,
+0x40, 0x41, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC, 0x14, 0x00, 0x42, 0x8D,
+0x00, 0x00, 0x00, 0x00, 0x42, 0x12, 0x02, 0x00, 0x3F, 0x00, 0x42, 0x30,
+0x0C, 0x00, 0x42, 0x28, 0x44, 0xFF, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x40, 0x02, 0x01, 0x00, 0x40, 0x03, 0x3C,
+0x25, 0x40, 0x03, 0x01, 0xE3, 0x01, 0x00, 0x08, 0x02, 0x80, 0x0E, 0x3C,
+0x60, 0x1B, 0xC3, 0x25, 0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x13, 0x0B, 0x00,
+0x0E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x43, 0x00, 0xD4, 0x1D, 0x45, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24, 0xD4, 0x1D, 0x43, 0xA4,
+0x0C, 0x00, 0x44, 0x8D, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30,
+0xFF, 0xFF, 0x42, 0x34, 0x00, 0x1C, 0x05, 0x00, 0x77, 0x02, 0x00, 0x08,
+0x24, 0x20, 0x82, 0x00, 0x7F, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01,
+0x80, 0x00, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, 0x08, 0x00, 0x48, 0xAD,
+0x08, 0x25, 0xA3, 0x8C, 0xFF, 0xFF, 0x02, 0x3C, 0xFF, 0x1F, 0x42, 0x34,
+0x07, 0x00, 0x63, 0x30, 0x24, 0x10, 0xE2, 0x00, 0x40, 0x1B, 0x03, 0x00,
+0x25, 0x38, 0x43, 0x00, 0xF1, 0x01, 0x00, 0x08, 0x10, 0x00, 0x47, 0xAD,
+0x02, 0x14, 0x0B, 0x00, 0xFF, 0x0F, 0x45, 0x30, 0x16, 0x00, 0xC2, 0x94,
+0x00, 0x19, 0x05, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0x0F, 0x00, 0x42, 0x30,
+0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x00, 0x00, 0x43, 0x95,
+0x40, 0x41, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC, 0xCE, 0x5C, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0x64, 0x14, 0x60, 0x1B, 0xC4, 0x25,
+0x3C, 0x41, 0x22, 0x91, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x18, 0xE3, 0x00,
+0x01, 0x00, 0x42, 0x30, 0xC0, 0x12, 0x02, 0x00, 0x25, 0x38, 0x62, 0x00,
+0x10, 0x00, 0x47, 0xAD, 0x3D, 0x41, 0x22, 0x91, 0xFF, 0xEF, 0x03, 0x24,
+0x24, 0x18, 0xE3, 0x00, 0x01, 0x00, 0x42, 0x30, 0x00, 0x13, 0x02, 0x00,
+0x25, 0x38, 0x43, 0x00, 0x1F, 0x02, 0x00, 0x08, 0x10, 0x00, 0x47, 0xAD,
+0xD8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF,
+0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x04, 0x00, 0x8B, 0x8C,
+0x21, 0x80, 0x80, 0x00, 0x08, 0x00, 0x84, 0x8C, 0x0E, 0x00, 0x07, 0x96,
+0xFF, 0xE0, 0x02, 0x3C, 0x10, 0x00, 0x08, 0x8E, 0x1F, 0x00, 0x6A, 0x31,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0x00, 0x1E, 0x0A, 0x00,
+0x25, 0x48, 0x83, 0x00, 0x21, 0x90, 0xA0, 0x00, 0x21, 0x60, 0xC0, 0x00,
+0xCF, 0x00, 0x00, 0x05, 0x07, 0x00, 0xE7, 0x30, 0x00, 0x00, 0x02, 0x96,
+0x00, 0x00, 0x00, 0x00, 0xFD, 0x0F, 0x42, 0x28, 0xD1, 0x00, 0x40, 0x10,
+0xFF, 0xDF, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x08, 0x00, 0x09, 0xAE,
+0x60, 0x1B, 0x23, 0x26, 0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x40, 0x62, 0x90,
+0xFF, 0xDF, 0x03, 0x3C, 0xFF, 0xFF, 0x63, 0x34, 0x07, 0x10, 0xE2, 0x00,
+0x01, 0x00, 0x42, 0x30, 0x24, 0x18, 0x23, 0x01, 0x40, 0x17, 0x02, 0x00,
+0x25, 0x48, 0x62, 0x00, 0x08, 0x00, 0x09, 0xAE, 0x1C, 0x00, 0x02, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x40, 0x04, 0x04, 0x00, 0x03, 0x24,
+0xC0, 0x30, 0x0A, 0x00, 0x21, 0x10, 0xCA, 0x00, 0x80, 0x10, 0x02, 0x00,
+0x21, 0x10, 0x4A, 0x00, 0x80, 0x10, 0x02, 0x00, 0x60, 0x1B, 0x27, 0x26,
+0x21, 0x28, 0x47, 0x00, 0x08, 0x25, 0xA3, 0x8C, 0x01, 0x00, 0x0A, 0x24,
+0x02, 0x13, 0x03, 0x00, 0x01, 0x00, 0x42, 0x30, 0xE7, 0x00, 0x4A, 0x10,
+0x42, 0x18, 0x03, 0x00, 0x82, 0x11, 0x09, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xC0, 0xFF, 0x02, 0x24,
+0x24, 0x10, 0x22, 0x01, 0x04, 0x00, 0x49, 0x34, 0x08, 0x00, 0x09, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x6C, 0x00, 0x60, 0x14, 0x21, 0x28, 0xC7, 0x00, 0xD4, 0x23, 0xA4, 0x8C,
+0x10, 0x00, 0x02, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x40, 0x00, 0x84, 0x30,
+0x24, 0x10, 0x43, 0x00, 0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE,
+0xD4, 0x23, 0xA3, 0x8C, 0x7F, 0xF8, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01,
+0x80, 0x07, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE,
+0xC6, 0x3D, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x40, 0x14,
+0x60, 0x1B, 0x25, 0x26, 0x42, 0x17, 0x09, 0x00, 0x01, 0x00, 0x44, 0x30,
+0x08, 0x01, 0x8A, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x24, 0x26,
+0x21, 0x20, 0xC4, 0x00, 0xD4, 0x23, 0x83, 0x8C, 0xFF, 0xF7, 0x02, 0x24,
+0x24, 0x10, 0x02, 0x01, 0x00, 0x08, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00,
+0x10, 0x00, 0x08, 0xAE, 0xD4, 0x23, 0x83, 0x8C, 0xFF, 0xEF, 0x02, 0x24,
+0x24, 0x10, 0x02, 0x01, 0x00, 0x10, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00,
+0x10, 0x00, 0x08, 0xAE, 0x60, 0x1B, 0x25, 0x26, 0x21, 0x30, 0xC5, 0x00,
+0xD4, 0x23, 0xC4, 0x8C, 0xFD, 0xFF, 0x02, 0x3C, 0x02, 0x00, 0x03, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, 0x24, 0x10, 0x02, 0x01,
+0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE, 0xB0, 0x1B, 0xA3, 0x94,
+0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0xC2, 0x1B, 0x03, 0x00,
+0x24, 0x10, 0x02, 0x01, 0x80, 0x1C, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00,
+0x10, 0x00, 0x08, 0xAE, 0x3B, 0x41, 0xA3, 0x90, 0xE7, 0xFF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, 0x24, 0x10, 0x02, 0x01,
+0xC0, 0x1C, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE,
+0xD4, 0x23, 0xC4, 0x8C, 0xFF, 0xFD, 0x02, 0x3C, 0x00, 0x02, 0x03, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, 0x24, 0x10, 0x02, 0x01,
+0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE, 0xB0, 0x1B, 0xA3, 0x94,
+0xFF, 0xFB, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0xC2, 0x1B, 0x03, 0x00,
+0x24, 0x10, 0x02, 0x01, 0x80, 0x1E, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00,
+0x10, 0x00, 0x08, 0xAE, 0x3B, 0x41, 0xA3, 0x90, 0xFF, 0xE7, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, 0x24, 0x10, 0x02, 0x01,
+0xC0, 0x1E, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE,
+0xD4, 0x23, 0xC3, 0x8C, 0xC0, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01,
+0x3F, 0x00, 0x63, 0x30, 0x25, 0x10, 0x43, 0x00, 0x10, 0x00, 0x02, 0xAE,
+0xD8, 0x23, 0xC4, 0x8C, 0x14, 0x00, 0x03, 0x8E, 0xFF, 0xFF, 0x02, 0x3C,
+0xFF, 0x7F, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x80, 0x84, 0x30,
+0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x03, 0xAE, 0xDA, 0x23, 0xC4, 0x94,
+0xE0, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x84, 0x30,
+0x24, 0x18, 0x62, 0x00, 0x00, 0x24, 0x04, 0x00, 0x25, 0x18, 0x64, 0x00,
+0x14, 0x00, 0x03, 0xAE, 0x02, 0x00, 0x02, 0x92, 0x02, 0x24, 0x0B, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x21, 0x10, 0x4C, 0x00, 0xFF, 0xFF, 0x42, 0x30,
+0x01, 0x00, 0x84, 0x30, 0x36, 0x00, 0x80, 0x10, 0x25, 0x30, 0x43, 0x00,
+0x60, 0x1B, 0x24, 0x26, 0xE4, 0x1D, 0x85, 0x94, 0x80, 0x00, 0x07, 0x24,
+0x01, 0x00, 0xA2, 0x24, 0xE4, 0x1D, 0x82, 0xA4, 0x0C, 0x00, 0x03, 0x8E,
+0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30, 0xFF, 0xFF, 0x42, 0x34,
+0x00, 0x24, 0x05, 0x00, 0x24, 0x18, 0x62, 0x00, 0x25, 0x18, 0x64, 0x00,
+0x0C, 0x00, 0x03, 0xAE, 0x16, 0x00, 0xC2, 0x94, 0x00, 0x19, 0x05, 0x00,
+0x02, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x25, 0x10, 0x43, 0x00,
+0x16, 0x00, 0xC2, 0xA4, 0x21, 0x28, 0x80, 0x01, 0x21, 0x30, 0x40, 0x02,
+0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC,
+0x5B, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26,
+0x00, 0x00, 0x03, 0x96, 0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x43, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03,
+0x40, 0x41, 0x82, 0xAC, 0x14, 0x00, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x42, 0x12, 0x02, 0x00, 0x3F, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x42, 0x28,
+0x2C, 0xFF, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x48, 0x22, 0x01, 0x00, 0x40, 0x03, 0x3C, 0x25, 0x48, 0x23, 0x01,
+0xFC, 0x02, 0x00, 0x08, 0x02, 0x80, 0x11, 0x3C, 0x60, 0x1B, 0x23, 0x26,
+0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x40, 0x14,
+0x80, 0x00, 0x07, 0x24, 0x0E, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x42, 0x30, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00,
+0xD4, 0x1D, 0x45, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24,
+0xD4, 0x1D, 0x43, 0xA4, 0x0C, 0x00, 0x04, 0x8E, 0x00, 0xF0, 0x02, 0x3C,
+0xFF, 0x0F, 0xA5, 0x30, 0xFF, 0xFF, 0x42, 0x34, 0x00, 0x1C, 0x05, 0x00,
+0x24, 0x20, 0x82, 0x00, 0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x04, 0xAE,
+0x16, 0x00, 0xC2, 0x94, 0x00, 0x19, 0x05, 0x00, 0x02, 0x00, 0x04, 0x24,
+0x0F, 0x00, 0x42, 0x30, 0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4,
+0x21, 0x28, 0x80, 0x01, 0x21, 0x30, 0x40, 0x02, 0x01, 0x00, 0x02, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC, 0x5B, 0x01, 0x00, 0x0C,
+0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26, 0x00, 0x00, 0x03, 0x96,
+0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x43, 0x00,
+0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC,
+0x7F, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01, 0x80, 0x00, 0x63, 0x30,
+0x25, 0x48, 0x43, 0x00, 0x08, 0x00, 0x09, 0xAE, 0x08, 0x25, 0xA3, 0x8C,
+0x10, 0x00, 0x04, 0x8E, 0xFF, 0xFF, 0x02, 0x3C, 0x07, 0x00, 0x63, 0x30,
+0xFF, 0x1F, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0x40, 0x1B, 0x03, 0x00,
+0x25, 0x40, 0x83, 0x00, 0x0E, 0x03, 0x00, 0x08, 0x10, 0x00, 0x08, 0xAE,
+0x1E, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x50, 0x00,
+0x00, 0x00, 0xC4, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x82, 0x30,
+0x02, 0x29, 0x02, 0x00, 0x3F, 0x00, 0xA3, 0x10, 0x06, 0x00, 0x02, 0x24,
+0xF4, 0xFE, 0xA2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x02, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xC2, 0xA0, 0x1E, 0x00, 0x03, 0x92,
+0x1A, 0x00, 0x02, 0x96, 0x21, 0x18, 0x70, 0x00, 0x03, 0x12, 0x02, 0x00,
+0x38, 0x00, 0x62, 0xA0, 0x04, 0x00, 0x0B, 0x8E, 0x08, 0x00, 0x09, 0x8E,
+0x02, 0x03, 0x00, 0x08, 0xC0, 0x30, 0x0A, 0x00, 0x0E, 0x00, 0x02, 0x96,
+0x02, 0x00, 0x04, 0x24, 0xFF, 0x0F, 0x45, 0x30, 0x16, 0x00, 0xC2, 0x94,
+0x00, 0x19, 0x05, 0x00, 0x21, 0x28, 0x80, 0x01, 0x0F, 0x00, 0x42, 0x30,
+0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x21, 0x30, 0x40, 0x02,
+0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC,
+0x5B, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26,
+0x00, 0x00, 0x03, 0x96, 0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x43, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03,
+0x40, 0x41, 0x82, 0xAC, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xF7, 0xFE, 0x64, 0x14, 0x60, 0x1B, 0x24, 0x26, 0x3C, 0x41, 0xE2, 0x90,
+0xFF, 0xF7, 0x03, 0x24, 0x24, 0x18, 0x03, 0x01, 0x01, 0x00, 0x42, 0x30,
+0xC0, 0x12, 0x02, 0x00, 0x25, 0x40, 0x62, 0x00, 0x10, 0x00, 0x08, 0xAE,
+0x3D, 0x41, 0xE2, 0x90, 0xFF, 0xEF, 0x03, 0x24, 0x24, 0x18, 0x03, 0x01,
+0x01, 0x00, 0x42, 0x30, 0x00, 0x13, 0x02, 0x00, 0x25, 0x40, 0x43, 0x00,
+0x3E, 0x03, 0x00, 0x08, 0x10, 0x00, 0x08, 0xAE, 0x1A, 0x00, 0x05, 0x96,
+0x0F, 0x00, 0x84, 0x30, 0x80, 0x20, 0x04, 0x00, 0x21, 0x18, 0xC4, 0x00,
+0x11, 0x00, 0x65, 0xA0, 0x1E, 0x00, 0x02, 0x92, 0x1A, 0x00, 0x03, 0x96,
+0x21, 0x10, 0x50, 0x00, 0x21, 0x10, 0x44, 0x00, 0x03, 0x1A, 0x03, 0x00,
+0x10, 0x00, 0x43, 0xA0, 0x04, 0x00, 0x0B, 0x8E, 0x08, 0x00, 0x09, 0x8E,
+0x02, 0x03, 0x00, 0x08, 0xC0, 0x30, 0x0A, 0x00, 0x00, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x64, 0x11, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xC0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x2C, 0x00, 0xB5, 0xAF,
+0x25, 0xB0, 0x03, 0x3C, 0x60, 0x1B, 0x55, 0x24, 0x00, 0x80, 0x02, 0x3C,
+0x38, 0x00, 0xBE, 0xAF, 0x80, 0x11, 0x42, 0x24, 0xB0, 0x03, 0x7E, 0x34,
+0x18, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC, 0x3C, 0x00, 0xBF, 0xAF,
+0x34, 0x00, 0xB7, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x28, 0x00, 0xB4, 0xAF,
+0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x96, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xB0, 0xAF, 0x8E, 0x04, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0xAE, 0x08, 0x38, 0x46, 0x8E,
+0x21, 0x28, 0x60, 0x02, 0x80, 0x00, 0x07, 0x24, 0x01, 0x00, 0x04, 0x24,
+0x01, 0x00, 0x14, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB4, 0xAF,
+0x08, 0x38, 0x43, 0x8E, 0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0xC3, 0xAE,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x1C, 0x42, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x40, 0x10, 0x2A, 0xB0, 0x02, 0x3C,
+0x09, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x54, 0xA0,
+0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0x03, 0x24, 0x71, 0x00, 0x23, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x38, 0xA2, 0x8E, 0x70, 0x38, 0xB3, 0x8E,
+0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0xC2, 0xAF, 0x08, 0x38, 0xA2, 0xAE,
+0x00, 0x00, 0xD3, 0xAF, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x70, 0x38, 0xA4, 0x8E, 0x74, 0x38, 0xA3, 0x8E, 0x02, 0x80, 0x02, 0x3C,
+0xB4, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x52, 0x8C, 0x80, 0x00, 0x84, 0x24,
+0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00,
+0x70, 0x38, 0xA3, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0xB8, 0xE6, 0x63, 0x24,
+0x70, 0x38, 0x42, 0x8E, 0x00, 0x00, 0x76, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC2, 0xAE, 0x02, 0x80, 0x17, 0x3C, 0xFF, 0xFF, 0x62, 0x32,
+0x25, 0x80, 0x57, 0x00, 0x00, 0x00, 0xD0, 0xAE, 0x0C, 0x00, 0x02, 0x92,
+0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xAE, 0x02, 0x00, 0x04, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x93, 0x00, 0xFF, 0xFF, 0x84, 0x30,
+0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x97, 0x00, 0x0C, 0x00, 0x11, 0x92,
+0x20, 0x10, 0x02, 0x3C, 0x01, 0x00, 0x04, 0x24, 0x00, 0x1A, 0x11, 0x00,
+0x21, 0x18, 0x62, 0x00, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x30, 0x60, 0x00,
+0x06, 0x00, 0x22, 0x12, 0x80, 0x00, 0x07, 0x24, 0x70, 0x38, 0x45, 0x8E,
+0x04, 0x38, 0x43, 0xAE, 0xA8, 0x37, 0x51, 0xA2, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x04, 0x00, 0x04, 0x8E, 0x08, 0x00, 0x03, 0x8E,
+0xFF, 0xE0, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x84, 0x30,
+0x24, 0x18, 0x62, 0x00, 0x00, 0x26, 0x04, 0x00, 0xFF, 0xDF, 0x02, 0x3C,
+0x25, 0x18, 0x64, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x40, 0x04, 0x3C, 0x25, 0x18, 0x64, 0x00, 0xC0, 0xFF, 0x05, 0x24,
+0x82, 0x11, 0x03, 0x00, 0x24, 0x20, 0x65, 0x00, 0x01, 0x00, 0x42, 0x30,
+0xA3, 0xFF, 0x40, 0x10, 0x04, 0x00, 0x84, 0x34, 0x08, 0x00, 0x03, 0xAE,
+0x08, 0x38, 0x46, 0x8E, 0x21, 0x28, 0x60, 0x02, 0x80, 0x00, 0x07, 0x24,
+0x01, 0x00, 0x04, 0x24, 0x01, 0x00, 0x14, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xB4, 0xAF, 0x08, 0x38, 0x43, 0x8E, 0x01, 0x00, 0x04, 0x24,
+0x00, 0x00, 0xC3, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x2A, 0x1C, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xFF, 0x40, 0x14,
+0x2A, 0xB0, 0x02, 0x3C, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x2A, 0x1C, 0x54, 0xA2, 0x02, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0x53, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x25, 0x10, 0x57, 0x00,
+0x02, 0x00, 0x43, 0x94, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x64, 0x30,
+0x00, 0xC0, 0x84, 0x24, 0x2B, 0x1C, 0x43, 0xA2, 0xA3, 0x31, 0x00, 0x0C,
+0xFF, 0xFF, 0x84, 0x30, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x2A, 0xB0, 0x02, 0x3C, 0x09, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x54, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0x03, 0x24,
+0x91, 0xFF, 0x23, 0x16, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24,
+0xD0, 0x1B, 0x43, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F,
+0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x00, 0x38, 0x63, 0x34,
+0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x83, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0x43, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x14, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF,
+0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C,
+0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x18, 0x03, 0x42, 0x34, 0x68, 0x14, 0x63, 0x24, 0x40, 0x00, 0xA4, 0x30,
+0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10,
+0x7F, 0x00, 0xA2, 0x30, 0xBF, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24,
+0xC0, 0x5D, 0xC2, 0xA0, 0x96, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x1E, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x60, 0x1B, 0xD3, 0x27, 0xB0, 0x03, 0x55, 0x34,
+0x59, 0x05, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C, 0x84, 0x37, 0x91, 0xA2,
+0x60, 0x1B, 0xC2, 0x27, 0xBC, 0x37, 0x46, 0x8C, 0x28, 0x38, 0x45, 0x8C,
+0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27, 0xC0, 0x37, 0x85, 0x8E,
+0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02,
+0x2A, 0xB0, 0x07, 0x3C, 0x0D, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24,
+0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96,
+0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24,
+0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24,
+0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00,
+0xBC, 0x37, 0x62, 0x8E, 0x28, 0x38, 0x72, 0x8E, 0x03, 0x00, 0x04, 0x24,
+0x00, 0x00, 0xA2, 0xAE, 0xC0, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x38, 0x64, 0x8E,
+0x2C, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C, 0xBC, 0xE6, 0x42, 0x24,
+0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24,
+0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, 0x28, 0x38, 0x63, 0xAE,
+0x28, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE,
+0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00,
+0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92, 0x01, 0x00, 0x05, 0x24,
+0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C,
+0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C,
+0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12,
+0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16, 0xBC, 0x37, 0x84, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x3B, 0x05, 0x00, 0x08,
+0x80, 0x37, 0x51, 0xA0, 0x1E, 0x00, 0xE0, 0x12, 0x40, 0x00, 0xE4, 0x34,
+0x84, 0x37, 0x83, 0x92, 0x41, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34,
+0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA4, 0x8C, 0x01, 0x00, 0x02, 0x3C,
+0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x00, 0x80, 0x42, 0x34, 0x25, 0x20, 0x82, 0x00,
+0x41, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x64, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC, 0x80, 0x37, 0x83, 0x92,
+0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC,
+0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA4, 0x8C,
+0x01, 0x00, 0x02, 0x3C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F,
+0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x00, 0x80, 0x42, 0x34,
+0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC,
+0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF,
+0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C,
+0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x18, 0x03, 0x42, 0x34, 0x08, 0x17, 0x63, 0x24, 0x10, 0x00, 0xA4, 0x30,
+0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10,
+0xDF, 0x00, 0xA2, 0x30, 0xEF, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24,
+0xC0, 0x5D, 0xC2, 0xA0, 0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x1E, 0x3C,
+0x00, 0x00, 0x43, 0xAC, 0x21, 0xA8, 0x40, 0x00, 0x96, 0x40, 0x00, 0x0C,
+0x60, 0x1B, 0xD3, 0x27, 0x05, 0x06, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C,
+0x8C, 0x37, 0x91, 0xA2, 0x60, 0x1B, 0xC2, 0x27, 0xC8, 0x37, 0x46, 0x8C,
+0x34, 0x38, 0x45, 0x8C, 0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27,
+0xCC, 0x37, 0x85, 0x8E, 0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C,
+0x21, 0x30, 0x40, 0x02, 0x2A, 0xB0, 0x07, 0x3C, 0x15, 0x00, 0xE2, 0x34,
+0x04, 0x00, 0x43, 0x24, 0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24,
+0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0,
+0x0C, 0x5D, 0xC4, 0x96, 0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34,
+0x01, 0x00, 0x84, 0x24, 0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96,
+0xFF, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12,
+0x00, 0x00, 0x00, 0x00, 0xC8, 0x37, 0x62, 0x8E, 0x34, 0x38, 0x72, 0x8E,
+0x04, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0xAE, 0xCC, 0x37, 0x62, 0xAE,
+0x00, 0x00, 0xB2, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x34, 0x38, 0x64, 0x8E, 0x38, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C,
+0xC0, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24,
+0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00,
+0x34, 0x38, 0x63, 0xAE, 0x34, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32,
+0x25, 0x80, 0x43, 0x00, 0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92,
+0x02, 0x00, 0x05, 0x24, 0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30,
+0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92,
+0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00,
+0xC2, 0xFF, 0x23, 0x12, 0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16,
+0xC8, 0x37, 0x84, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0xE7, 0x05, 0x00, 0x08, 0x88, 0x37, 0x51, 0xA0, 0x1D, 0x00, 0xE0, 0x12,
+0x42, 0x00, 0xE4, 0x34, 0x8C, 0x37, 0x83, 0x92, 0x43, 0x00, 0xE4, 0x34,
+0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC,
+0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C,
+0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x06, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00,
+0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, 0x88, 0x37, 0x83, 0x92,
+0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC,
+0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C,
+0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x06, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00,
+0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, 0xC0, 0xFF, 0xBD, 0x27,
+0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xBE, 0xAF,
+0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF,
+0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C, 0xC0, 0x5D, 0xC5, 0x90,
+0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34,
+0xB0, 0x19, 0x63, 0x24, 0x01, 0x00, 0xA4, 0x30, 0x00, 0x00, 0x43, 0xAC,
+0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10, 0xF7, 0x00, 0xA2, 0x30,
+0xFE, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24, 0xC0, 0x5D, 0xC2, 0xA0,
+0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34,
+0x02, 0x80, 0x1E, 0x3C, 0x00, 0x00, 0x43, 0xAC, 0x21, 0xA8, 0x40, 0x00,
+0x96, 0x40, 0x00, 0x0C, 0x60, 0x1B, 0xD3, 0x27, 0xAE, 0x06, 0x00, 0x08,
+0x02, 0x80, 0x16, 0x3C, 0x9C, 0x37, 0x91, 0xA2, 0x60, 0x1B, 0xC2, 0x27,
+0xD4, 0x37, 0x46, 0x8C, 0x40, 0x38, 0x45, 0x8C, 0x05, 0x00, 0x04, 0x24,
+0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF,
+0x60, 0x1B, 0xD4, 0x27, 0xD8, 0x37, 0x85, 0x8E, 0x21, 0x20, 0x00, 0x02,
+0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, 0x2A, 0xB0, 0x07, 0x3C,
+0x1D, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24, 0x0B, 0x10, 0x77, 0x00,
+0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xA0,
+0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96, 0x25, 0xB0, 0x06, 0x3C,
+0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24, 0x0C, 0x5D, 0xC4, 0xA6,
+0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4,
+0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x37, 0x62, 0x8E,
+0x40, 0x38, 0x72, 0x8E, 0x05, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0xAE,
+0xD8, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE, 0x5B, 0x01, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x38, 0x64, 0x8E, 0x44, 0x38, 0x63, 0x8E,
+0x02, 0x80, 0x02, 0x3C, 0xC4, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x54, 0x8C,
+0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00,
+0x0A, 0x18, 0x82, 0x00, 0x40, 0x38, 0x63, 0xAE, 0x40, 0x38, 0x82, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE, 0x02, 0x80, 0x03, 0x3C,
+0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00, 0x00, 0x00, 0xB0, 0xAE,
+0x0C, 0x00, 0x02, 0x92, 0x08, 0x00, 0x05, 0x24, 0x00, 0x00, 0xA2, 0xAE,
+0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x92, 0x00,
+0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x83, 0x00,
+0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x03, 0x24,
+0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12, 0x21, 0x20, 0x82, 0x00,
+0xB8, 0xFF, 0xE0, 0x16, 0xD4, 0x37, 0x84, 0xAE, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x42, 0x24, 0x90, 0x06, 0x00, 0x08, 0x90, 0x37, 0x51, 0xA0,
+0x1D, 0x00, 0xE0, 0x12, 0x44, 0x00, 0xE4, 0x34, 0x9C, 0x37, 0x83, 0x92,
+0x45, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0,
+0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27,
+0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F,
+0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x03, 0x3C,
+0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC,
+0x90, 0x37, 0x83, 0x92, 0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0,
+0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27,
+0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F,
+0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x03, 0x3C,
+0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC,
+0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF,
+0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C,
+0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x18, 0x03, 0x42, 0x34, 0x54, 0x1C, 0x63, 0x24, 0x02, 0x00, 0xA4, 0x30,
+0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10,
+0xFB, 0x00, 0xA2, 0x30, 0xFD, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24,
+0xC0, 0x5D, 0xC2, 0xA0, 0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0x02, 0x80, 0x1E, 0x3C, 0x00, 0x00, 0x43, 0xAC,
+0x21, 0xA8, 0x40, 0x00, 0x96, 0x40, 0x00, 0x0C, 0x60, 0x1B, 0xD3, 0x27,
+0x57, 0x07, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C, 0x98, 0x37, 0x91, 0xA2,
+0x60, 0x1B, 0xC2, 0x27, 0xE0, 0x37, 0x46, 0x8C, 0x4C, 0x38, 0x45, 0x8C,
+0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27, 0xE4, 0x37, 0x85, 0x8E,
+0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02,
+0x2A, 0xB0, 0x07, 0x3C, 0x25, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24,
+0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96,
+0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24,
+0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24,
+0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00,
+0xE0, 0x37, 0x62, 0x8E, 0x4C, 0x38, 0x72, 0x8E, 0x06, 0x00, 0x04, 0x24,
+0x00, 0x00, 0xA2, 0xAE, 0xE4, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x38, 0x64, 0x8E,
+0x50, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C, 0xC8, 0xE6, 0x42, 0x24,
+0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24,
+0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, 0x4C, 0x38, 0x63, 0xAE,
+0x4C, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE,
+0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00,
+0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92, 0x04, 0x00, 0x05, 0x24,
+0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C,
+0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C,
+0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12,
+0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16, 0xE0, 0x37, 0x84, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x39, 0x07, 0x00, 0x08,
+0x94, 0x37, 0x51, 0xA0, 0x1D, 0x00, 0xE0, 0x12, 0x46, 0x00, 0xE4, 0x34,
+0x98, 0x37, 0x83, 0x92, 0x47, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34,
+0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F,
+0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x60, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C,
+0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xD0, 0x1B, 0xA2, 0xAC, 0x94, 0x37, 0x83, 0x92, 0xB0, 0x03, 0xC5, 0x34,
+0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F,
+0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x60, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C,
+0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xD0, 0x1B, 0xA2, 0xAC, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0xF8, 0x1E, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0xE8, 0xFF, 0xBD, 0x27,
+0x00, 0x00, 0x43, 0xAC, 0x10, 0x00, 0xBF, 0xAF, 0x96, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xD8, 0x1B, 0xA2, 0x8C,
+0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x08, 0x03, 0x3C, 0x10, 0x00, 0xBF, 0x8F,
+0x24, 0x10, 0x43, 0x00, 0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C,
+0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xD0, 0x1B, 0xA4, 0xAC, 0xC0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB0, 0xAF,
+0x00, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x10, 0x3C, 0x18, 0x03, 0x03, 0x36,
+0x58, 0x1F, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC, 0x34, 0x00, 0xB5, 0xAF,
+0x02, 0x80, 0x15, 0x3C, 0x38, 0x00, 0xBF, 0xAF, 0x2C, 0x00, 0xB3, 0xAF,
+0x28, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0xB3, 0x26, 0x24, 0x00, 0xB1, 0xAF,
+0x96, 0x40, 0x00, 0x0C, 0x30, 0x00, 0xB4, 0xAF, 0xFC, 0x00, 0x02, 0x36,
+0x00, 0x00, 0x45, 0x8C, 0xAC, 0x1B, 0x64, 0x96, 0xCC, 0x38, 0x63, 0x96,
+0xC4, 0x38, 0x66, 0x8E, 0x23, 0x28, 0xA4, 0x00, 0x21, 0x10, 0xA3, 0x00,
+0x23, 0x88, 0x46, 0x00, 0x23, 0x20, 0x23, 0x02, 0xB0, 0x03, 0x10, 0x36,
+0x2B, 0x10, 0x71, 0x00, 0x00, 0x00, 0x03, 0xAE, 0x00, 0x00, 0x11, 0xAE,
+0x0B, 0x88, 0x82, 0x00, 0x21, 0x20, 0x20, 0x02, 0x53, 0x21, 0x00, 0x0C,
+0xC8, 0x38, 0x65, 0xAE, 0x21, 0x90, 0x40, 0x00, 0x4D, 0x00, 0x40, 0x10,
+0x18, 0x00, 0xA4, 0x27, 0x0C, 0x00, 0x51, 0xAC, 0xC4, 0x38, 0x68, 0x8E,
+0xC8, 0x38, 0x62, 0x8E, 0x08, 0x00, 0x45, 0x8E, 0x20, 0xBD, 0x03, 0x3C,
+0x88, 0x03, 0x63, 0x34, 0x2B, 0x10, 0x48, 0x00, 0x40, 0x10, 0x14, 0x3C,
+0x21, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0x27, 0x32, 0x00, 0x00, 0x65, 0xAC,
+0x2A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x1B, 0x66, 0x96,
+0x08, 0x00, 0x42, 0x96, 0x40, 0x10, 0x05, 0x3C, 0x21, 0x20, 0x00, 0x00,
+0x21, 0x30, 0x06, 0x01, 0x25, 0x28, 0x45, 0x00, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27,
+0x02, 0x80, 0x02, 0x3C, 0x88, 0x54, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C,
+0x00, 0x00, 0x42, 0xAE, 0x04, 0x00, 0x52, 0xAC, 0x21, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x72, 0xAC, 0x5B, 0x01, 0x00, 0x0C, 0x04, 0x00, 0x43, 0xAE,
+0x60, 0x1B, 0xA5, 0x26, 0xC8, 0x38, 0xA6, 0x8C, 0xAC, 0x1B, 0xA3, 0x94,
+0x25, 0xB0, 0x02, 0x3C, 0xF8, 0x00, 0x42, 0x34, 0x21, 0x18, 0xC3, 0x00,
+0x00, 0x00, 0x43, 0xAC, 0x18, 0x00, 0xA4, 0x27, 0xC4, 0x38, 0xA6, 0xAC,
+0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xBF, 0x8F, 0x34, 0x00, 0xB5, 0x8F,
+0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F,
+0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x40, 0x00, 0xBD, 0x27, 0xCC, 0x38, 0x70, 0x8E, 0x08, 0x00, 0x45, 0x96,
+0xAC, 0x1B, 0x66, 0x96, 0x23, 0x80, 0x08, 0x02, 0xFF, 0xFF, 0x10, 0x32,
+0x21, 0x30, 0x06, 0x01, 0x25, 0x28, 0xB4, 0x00, 0x21, 0x38, 0x00, 0x02,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x5B, 0x01, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x00, 0x08, 0x00, 0x45, 0x96, 0xAC, 0x1B, 0x62, 0x96,
+0x23, 0x38, 0x30, 0x02, 0x25, 0x28, 0xB4, 0x00, 0x21, 0x10, 0x06, 0x3C,
+0x21, 0x28, 0xB0, 0x00, 0x21, 0x30, 0x46, 0x00, 0xFF, 0xFF, 0xE7, 0x30,
+0x0D, 0x08, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xC4, 0x5D, 0x62, 0x8C,
+0x18, 0x00, 0xA4, 0x27, 0x08, 0x00, 0x42, 0x34, 0x23, 0x08, 0x00, 0x08,
+0xC4, 0x5D, 0x62, 0xAC, 0x25, 0xB0, 0x05, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0xC0, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0xA4, 0x34, 0x38, 0x21, 0x42, 0x24,
+0x2A, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x82, 0xAC, 0x3C, 0x00, 0xBF, 0xAF,
+0x38, 0x00, 0xBE, 0xAF, 0x34, 0x00, 0xB7, 0xAF, 0x30, 0x00, 0xB6, 0xAF,
+0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF,
+0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF,
+0x2C, 0x00, 0x63, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x24, 0x31, 0x48, 0x00, 0x82, 0x10, 0x00, 0x80, 0x22, 0x31,
+0x37, 0x00, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x14, 0x00, 0x82, 0x10,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x70, 0x24, 0xFF, 0x00, 0x23, 0x31,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x7C, 0x38, 0x05, 0x8E, 0x25, 0xB0, 0x02, 0x3C, 0xFF, 0x00, 0x28, 0x31,
+0x7C, 0x03, 0x42, 0x34, 0x00, 0x00, 0x48, 0xA4, 0x21, 0x30, 0x60, 0x00,
+0x10, 0x38, 0x03, 0xAE, 0xAC, 0x37, 0x09, 0xA2, 0x0A, 0x00, 0x04, 0x24,
+0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF,
+0x01, 0x00, 0x03, 0x24, 0x84, 0x38, 0x03, 0xA2, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x50, 0x24, 0x84, 0x38, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24,
+0x31, 0x00, 0x62, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x90, 0x24,
+0x85, 0x38, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x10,
+0x00, 0x04, 0x03, 0x3C, 0xD8, 0x1B, 0x02, 0x8E, 0xD0, 0x1B, 0x04, 0x8E,
+0x24, 0x10, 0x43, 0x00, 0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0x64, 0xAC, 0xD0, 0x1B, 0x04, 0xAE, 0x3C, 0x00, 0xBF, 0x8F,
+0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0x24, 0x10, 0x22, 0x01,
+0xCB, 0xFF, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x43, 0x24, 0xAC, 0x37, 0x62, 0x90, 0x20, 0xB0, 0x03, 0x3C,
+0xB0, 0x03, 0xA4, 0x34, 0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00,
+0x0C, 0x00, 0x49, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xAC,
+0x69, 0x08, 0x00, 0x08, 0xFF, 0x00, 0x24, 0x31, 0x02, 0x80, 0x04, 0x3C,
+0x60, 0x1B, 0x82, 0x24, 0x84, 0x38, 0x40, 0xA0, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x50, 0x24, 0x84, 0x38, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24,
+0xD1, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x00, 0x0C,
+0x21, 0x88, 0x00, 0x02, 0x25, 0xB0, 0x02, 0x3C, 0x2A, 0xB0, 0x03, 0x3C,
+0x2C, 0x00, 0x7E, 0x34, 0x02, 0x80, 0x17, 0x3C, 0xB0, 0x03, 0x56, 0x34,
+0x01, 0x00, 0x13, 0x24, 0x21, 0xA0, 0x00, 0x02, 0x21, 0xA8, 0x00, 0x02,
+0x7C, 0x38, 0x30, 0x8E, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xD0, 0xAE,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0xFF, 0xFF, 0x08, 0x32, 0x25, 0x80, 0x02, 0x01, 0xC2, 0x5C, 0xE3, 0x92,
+0x02, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x63, 0x30,
+0x52, 0x00, 0x62, 0x10, 0x21, 0x38, 0x04, 0x02, 0x20, 0x00, 0x02, 0x24,
+0x54, 0x00, 0x82, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x54, 0xF5, 0x47, 0xAC,
+0x02, 0x00, 0xE2, 0x90, 0x85, 0x38, 0x84, 0x92, 0x03, 0x00, 0xE3, 0x90,
+0xFF, 0x00, 0x52, 0x30, 0x01, 0x00, 0x02, 0x24, 0x21, 0x28, 0xE0, 0x00,
+0x7F, 0x00, 0x66, 0x30, 0x08, 0x00, 0xE7, 0x24, 0x57, 0x00, 0x82, 0x10,
+0x02, 0x80, 0x09, 0x3C, 0x0E, 0x00, 0x02, 0x24, 0x51, 0x00, 0x42, 0x12,
+0x37, 0x00, 0x02, 0x24, 0x4F, 0x00, 0x42, 0x12, 0x10, 0x00, 0x02, 0x24,
+0x4E, 0x00, 0x42, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0x38, 0xD7, 0x42, 0x24, 0xC0, 0x18, 0x12, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x34, 0xD7, 0x26, 0xA1, 0x04, 0x00, 0x62, 0x8C, 0x02, 0x80, 0x03, 0x3C,
+0x21, 0x20, 0xE0, 0x00, 0x09, 0xF8, 0x40, 0x00, 0x4C, 0xF5, 0x62, 0xAC,
+0x03, 0x00, 0x40, 0x10, 0x39, 0x00, 0x02, 0x24, 0x3B, 0x00, 0x42, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x85, 0x38, 0x33, 0xA2, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x39, 0x00, 0x02, 0x24, 0x03, 0x00, 0x42, 0x12, 0x02, 0x00, 0x02, 0x24,
+0x01, 0x00, 0xD3, 0xA3, 0x01, 0x00, 0xC2, 0xA3, 0x85, 0x38, 0xA3, 0x92,
+0x01, 0x00, 0x02, 0x24, 0x42, 0x00, 0x62, 0x14, 0xFF, 0x00, 0x02, 0x24,
+0x0C, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x68, 0x30,
+0x3E, 0x00, 0x02, 0x11, 0x02, 0x80, 0x02, 0x3C, 0xAC, 0x37, 0xA3, 0xA2,
+0xAC, 0x37, 0x22, 0x92, 0x7C, 0x38, 0x25, 0x8E, 0x20, 0x10, 0x03, 0x3C,
+0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0xC8, 0xAE,
+0x21, 0x30, 0x40, 0x00, 0x10, 0x38, 0x22, 0xAE, 0x0A, 0x00, 0x04, 0x24,
+0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF,
+0x7C, 0x38, 0x30, 0x8E, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xD0, 0xAE,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0xFF, 0xFF, 0x08, 0x32, 0x25, 0x80, 0x02, 0x01, 0xC2, 0x5C, 0xE3, 0x92,
+0x02, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x63, 0x30,
+0xB0, 0xFF, 0x62, 0x14, 0x21, 0x38, 0x04, 0x02, 0x00, 0x00, 0x02, 0x8E,
+0x00, 0x0C, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0xAE, 0xFF, 0x43, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x95, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x7A, 0x37, 0x22, 0x96, 0x85, 0x38, 0x33, 0xA2, 0x01, 0x00, 0x42, 0x24,
+0xF5, 0x08, 0x00, 0x08, 0x7A, 0x37, 0x22, 0xA6, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xF3, 0x08, 0x00, 0x08, 0x85, 0x38, 0x20, 0xA2,
+0x02, 0x80, 0x02, 0x3C, 0xE2, 0x08, 0x00, 0x08, 0x25, 0x38, 0x02, 0x01,
+0x34, 0xD7, 0x22, 0x91, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x42, 0x30,
+0x13, 0x00, 0xC2, 0x10, 0x25, 0xB0, 0x04, 0x3C, 0x6A, 0x37, 0x82, 0x96,
+0x1E, 0x03, 0x84, 0x34, 0x10, 0x00, 0x42, 0x34, 0x3B, 0x00, 0x43, 0x2E,
+0x00, 0x00, 0x82, 0xA4, 0x9F, 0xFF, 0x60, 0x14, 0x6A, 0x37, 0x82, 0xA6,
+0xF6, 0x08, 0x00, 0x08, 0x39, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0xB0, 0x5D, 0x44, 0x8C, 0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x63, 0x34,
+0x00, 0x00, 0x64, 0xAC, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x85, 0x08, 0x00, 0x08, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0xA5, 0x90,
+0x34, 0xD7, 0x27, 0x91, 0x02, 0x80, 0x04, 0x3C, 0xCC, 0xE6, 0x84, 0x24,
+0xFF, 0x00, 0xA5, 0x30, 0x13, 0x58, 0x00, 0x0C, 0xFF, 0x00, 0xE7, 0x30,
+0xF6, 0x08, 0x00, 0x08, 0x39, 0x00, 0x02, 0x24, 0xC0, 0xFF, 0xBD, 0x27,
+0x34, 0x00, 0xB7, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x21, 0xB8, 0xA0, 0x00,
+0xFF, 0xFF, 0xA5, 0x30, 0x25, 0x40, 0xA2, 0x00, 0x20, 0x00, 0xB2, 0xAF,
+0x38, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x03, 0x8D, 0xFF, 0xFF, 0xD2, 0x30,
+0x08, 0x00, 0x45, 0x26, 0x00, 0xC0, 0x02, 0x24, 0x04, 0x00, 0x06, 0x8D,
+0x24, 0x18, 0x62, 0x00, 0xFF, 0x3F, 0xA5, 0x30, 0xF0, 0xFF, 0x02, 0x3C,
+0x25, 0x18, 0x65, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x80, 0x05, 0x3C, 0x25, 0x18, 0x65, 0x00, 0xFF, 0x01, 0xC6, 0x34,
+0x00, 0x00, 0x03, 0xAD, 0x04, 0x00, 0x06, 0xAD, 0x21, 0x48, 0x80, 0x00,
+0xFF, 0xFF, 0xE7, 0x30, 0x18, 0x00, 0x06, 0x25, 0x18, 0x00, 0x12, 0xA5,
+0x02, 0x00, 0xC7, 0xA0, 0x18, 0x00, 0x03, 0x8D, 0xFF, 0x7F, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x02, 0x80, 0x16, 0x3C,
+0x18, 0x00, 0x03, 0xAD, 0x60, 0x1B, 0xC5, 0x26, 0x66, 0x37, 0xA4, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x24, 0x66, 0x37, 0xA2, 0xA0,
+0x18, 0x00, 0x03, 0x8D, 0xFF, 0x80, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x7F, 0x00, 0x84, 0x30, 0x00, 0x26, 0x04, 0x00, 0x24, 0x18, 0x62, 0x00,
+0x25, 0x18, 0x64, 0x00, 0x18, 0x00, 0x03, 0xAD, 0x02, 0x80, 0x02, 0x3C,
+0xC2, 0x5C, 0x44, 0x90, 0x20, 0x00, 0x43, 0x26, 0xFF, 0xFF, 0x72, 0x30,
+0x02, 0x00, 0x84, 0x30, 0x04, 0x00, 0x80, 0x10, 0x21, 0x18, 0x40, 0x02,
+0x1F, 0x00, 0x42, 0x32, 0x5C, 0x00, 0x40, 0x10, 0x08, 0x00, 0x42, 0x26,
+0xFF, 0xFF, 0x63, 0x30, 0x5D, 0x00, 0x43, 0x12, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0xC2, 0x8C, 0x21, 0x90, 0x60, 0x00, 0x00, 0xC0, 0x04, 0x24,
+0x01, 0x00, 0x42, 0x34, 0x04, 0x00, 0xC2, 0xAC, 0x00, 0x00, 0x03, 0x8D,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x62, 0x30, 0x08, 0x00, 0x42, 0x24,
+0x24, 0x18, 0x64, 0x00, 0xFF, 0x3F, 0x42, 0x30, 0x25, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x03, 0xAD, 0x25, 0xB0, 0x02, 0x3C, 0xC0, 0x00, 0x42, 0x34,
+0x07, 0x00, 0x43, 0x32, 0x00, 0x00, 0x52, 0xA4, 0x03, 0x00, 0x60, 0x10,
+0xF8, 0xFF, 0x53, 0x32, 0x08, 0x00, 0x42, 0x26, 0xF8, 0xFF, 0x53, 0x30,
+0x60, 0x1B, 0xD5, 0x26, 0xEC, 0x38, 0xA6, 0x8E, 0xF0, 0x38, 0xB0, 0x8E,
+0x21, 0x10, 0xD3, 0x00, 0x2B, 0x10, 0x02, 0x02, 0x32, 0x00, 0x40, 0x10,
+0xFF, 0x00, 0x34, 0x31, 0x23, 0x80, 0x06, 0x02, 0x21, 0x28, 0xE0, 0x02,
+0xFF, 0xFF, 0x07, 0x32, 0x01, 0x00, 0x11, 0x24, 0x21, 0x20, 0x80, 0x02,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF, 0x23, 0x18, 0x70, 0x02,
+0xFF, 0xFF, 0x72, 0x30, 0x22, 0x10, 0x02, 0x3C, 0x21, 0x10, 0x42, 0x02,
+0x21, 0x20, 0x80, 0x02, 0x5B, 0x01, 0x00, 0x0C, 0xEC, 0x38, 0xA2, 0xAE,
+0x21, 0x28, 0xF0, 0x02, 0x21, 0x38, 0x40, 0x02, 0x21, 0x20, 0x80, 0x02,
+0x22, 0x10, 0x06, 0x3C, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF,
+0x60, 0x1B, 0xD1, 0x26, 0xEC, 0x38, 0x23, 0x8E, 0x25, 0xB0, 0x10, 0x3C,
+0xB0, 0x03, 0x02, 0x36, 0x21, 0x20, 0x80, 0x02, 0x00, 0x00, 0x43, 0xAC,
+0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x38, 0x25, 0x8E,
+0xEC, 0x00, 0x02, 0x36, 0xBD, 0x00, 0x04, 0x36, 0x00, 0x00, 0x45, 0xAC,
+0x00, 0x00, 0x83, 0x90, 0xC2, 0x00, 0x10, 0x36, 0x38, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0x63, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x34, 0x00, 0xB7, 0x8F,
+0x00, 0x00, 0x05, 0xA6, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x02, 0x24,
+0x21, 0x28, 0xE0, 0x02, 0x21, 0x20, 0x80, 0x02, 0x21, 0x38, 0x60, 0x02,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0xEC, 0x38, 0xA3, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x73, 0x00, 0xC4, 0x09, 0x00, 0x08,
+0xEC, 0x38, 0xA3, 0xAE, 0xFF, 0xFF, 0x43, 0x30, 0xFF, 0xFF, 0x63, 0x30,
+0xA5, 0xFF, 0x43, 0x16, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xC2, 0x8C,
+0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xA1, 0x09, 0x00, 0x08,
+0x04, 0x00, 0xC2, 0xAC, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x14, 0x00, 0x03, 0x8E, 0x16, 0x00, 0x02, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x0A, 0x00, 0x62, 0x10, 0x08, 0x00, 0x06, 0x24,
+0x08, 0x00, 0x02, 0x96, 0x02, 0x80, 0x04, 0x3C, 0xEC, 0x54, 0x00, 0x0C,
+0x25, 0x20, 0x44, 0x00, 0x08, 0x00, 0x05, 0x8E, 0x0C, 0x00, 0x06, 0x96,
+0x14, 0x00, 0x07, 0x96, 0x51, 0x09, 0x00, 0x0C, 0x09, 0x00, 0x04, 0x24,
+0x04, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x02, 0x8E, 0x21, 0x20, 0x00, 0x02,
+0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE,
+0x74, 0x21, 0x00, 0x0C, 0x04, 0x00, 0x10, 0xAE, 0x90, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x02, 0x3C,
+0xBF, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x63, 0x2C, 0x05, 0x00, 0x60, 0x10, 0x02, 0x80, 0x05, 0x3C,
+0x90, 0x54, 0xA3, 0x8C, 0x90, 0x54, 0xA2, 0x24, 0x0D, 0x00, 0x62, 0x10,
+0x21, 0x20, 0x00, 0x02, 0x90, 0x54, 0xA2, 0x24, 0x04, 0x00, 0x43, 0x8C,
+0x00, 0x00, 0x02, 0xAE, 0x04, 0x00, 0x50, 0xAC, 0x00, 0x00, 0x70, 0xAC,
+0x04, 0x00, 0x03, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xF5, 0x09, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x08, 0xE7, 0x84, 0x24, 0x24, 0x00, 0xBF, 0xAF,
+0x20, 0x00, 0xB2, 0xAF, 0x13, 0x58, 0x00, 0x0C, 0x1C, 0x00, 0xB1, 0xAF,
+0x00, 0x00, 0x04, 0x96, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x83, 0x24,
+0x07, 0x00, 0x62, 0x30, 0x6A, 0x00, 0x40, 0x10, 0xC2, 0x10, 0x03, 0x00,
+0x28, 0x00, 0x82, 0x24, 0xC2, 0x10, 0x02, 0x00, 0x53, 0x21, 0x00, 0x0C,
+0xC0, 0x20, 0x02, 0x00, 0x68, 0x00, 0x40, 0x10, 0x21, 0x88, 0x40, 0x00,
+0x02, 0x80, 0x12, 0x3C, 0x02, 0x00, 0x06, 0x92, 0x60, 0x1B, 0x50, 0x26,
+0x10, 0x38, 0x05, 0x8E, 0x08, 0x00, 0xC6, 0x24, 0x0A, 0x00, 0x04, 0x24,
+0x72, 0x01, 0x00, 0x0C, 0x21, 0x38, 0x40, 0x00, 0xB0, 0x1B, 0x03, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, 0x67, 0x00, 0x40, 0x14,
+0x01, 0x00, 0x62, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x4B, 0xF5, 0x43, 0x90,
+0x60, 0x1B, 0x50, 0x26, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0xE8, 0x39, 0x00, 0xAE, 0x04, 0x3A, 0x00, 0xAE, 0xFC, 0x40, 0x00, 0xAE,
+0xBC, 0x40, 0x00, 0xAE, 0xC6, 0x40, 0x00, 0xA2, 0x8A, 0x40, 0x00, 0x0C,
+0xC6, 0x5C, 0x43, 0xA0, 0xA3, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x87, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, 0xD2, 0x5C, 0x48, 0x90,
+0x25, 0xB0, 0x04, 0x3C, 0x2F, 0x00, 0x02, 0x3C, 0xD0, 0x01, 0x85, 0x34,
+0x17, 0x32, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xAC, 0x5E, 0x00, 0x03, 0x3C,
+0x10, 0x00, 0x02, 0x3C, 0xDC, 0x01, 0x87, 0x34, 0xD4, 0x01, 0x86, 0x34,
+0x17, 0x43, 0x63, 0x34, 0x20, 0x53, 0x42, 0x34, 0xD8, 0x01, 0x84, 0x34,
+0x00, 0x00, 0xC3, 0xAC, 0x00, 0x00, 0x82, 0xAC, 0x44, 0xA4, 0x03, 0x34,
+0x01, 0x00, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xAC, 0x52, 0x00, 0x02, 0x11,
+0xFF, 0xF7, 0x03, 0x24, 0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xEF, 0x04, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFC, 0x23, 0x02, 0xAE,
+0x60, 0x1B, 0x42, 0x8E, 0xDF, 0xFF, 0x03, 0x24, 0xFB, 0xFF, 0x04, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFE, 0xFF, 0x03, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x50, 0x0C, 0x04, 0x24, 0x60, 0x1B, 0x50, 0x26,
+0x30, 0x5C, 0x00, 0x0C, 0x60, 0x1B, 0x42, 0xAE, 0x38, 0x3E, 0x02, 0xA2,
+0x30, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24, 0x39, 0x3E, 0x02, 0xA2,
+0x50, 0x0C, 0x04, 0x24, 0x1A, 0x5C, 0x00, 0x0C, 0x17, 0x00, 0x05, 0x24,
+0x17, 0x00, 0x05, 0x24, 0x1A, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24,
+0x5B, 0x01, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, 0x08, 0x00, 0x22, 0x96,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x25, 0x28, 0x45, 0x00,
+0x74, 0x03, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0xB0, 0x55, 0x84, 0x24,
+0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x98, 0x3A, 0x02, 0x8E,
+0x49, 0x4B, 0x00, 0x0C, 0xC4, 0x3D, 0x02, 0xA2, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x53, 0x21, 0x00, 0x0C, 0xC0, 0x20, 0x02, 0x00, 0x9A, 0xFF, 0x40, 0x14,
+0x21, 0x88, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x18, 0xE7, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xFC, 0xE6, 0xA5, 0x24,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0x20, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x87, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x05, 0x3C,
+0x4C, 0x00, 0xA2, 0x34, 0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0xA5, 0x34,
+0xB0, 0x1B, 0x03, 0x96, 0x00, 0x00, 0xA4, 0x8C, 0x7B, 0xFF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0xFF, 0xFE, 0x63, 0x30,
+0xB0, 0x1B, 0x03, 0xA6, 0x00, 0x00, 0xA4, 0xAC, 0x5F, 0x0A, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90,
+0x02, 0x00, 0x03, 0x24, 0x06, 0x00, 0x83, 0x10, 0xFF, 0xF7, 0x03, 0x24,
+0xFC, 0x23, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00,
+0x89, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x42, 0x34, 0xFC, 0x23, 0x02, 0x8E,
+0xFF, 0xEF, 0x03, 0x24, 0x00, 0x08, 0x42, 0x34, 0x89, 0x0A, 0x00, 0x08,
+0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24,
+0x1C, 0x4F, 0x00, 0x0C, 0x03, 0x00, 0x05, 0x24, 0xC6, 0x0A, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x00, 0x00, 0x84, 0x90, 0x02, 0x80, 0x06, 0x3C, 0x01, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x83, 0x30, 0x0C, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xC5, 0x24,
+0x04, 0x00, 0x02, 0x24, 0x13, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xC2, 0x24,
+0xC6, 0x3D, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C,
+0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xC6, 0x3D, 0xA4, 0xA0,
+0x60, 0x1B, 0xC2, 0x24, 0xC6, 0x3D, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0x60, 0x1B, 0xC3, 0x24, 0xB0, 0x1B, 0x62, 0x94, 0xC6, 0x3D, 0x64, 0xA0,
+0x02, 0x80, 0x04, 0x3C, 0x04, 0x00, 0x42, 0x34, 0xB0, 0x1B, 0x62, 0xA4,
+0x60, 0x1B, 0xC2, 0x24, 0xC6, 0x3D, 0x45, 0x90, 0x13, 0x58, 0x00, 0x0C,
+0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27,
+0x20, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C, 0x24, 0x00, 0xB3, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, 0x28, 0x00, 0xB4, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x51, 0x26, 0xB0, 0x1B, 0x22, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10,
+0x21, 0x98, 0x80, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C,
+0x02, 0x80, 0x14, 0x3C, 0xEE, 0x5D, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, 0x89, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x60, 0x1B, 0x42, 0x8E, 0xDF, 0xFF, 0x03, 0x24, 0xFB, 0xFF, 0x04, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFE, 0xFF, 0x03, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x50, 0x0C, 0x04, 0x24, 0x30, 0x5C, 0x00, 0x0C,
+0x60, 0x1B, 0x42, 0xAE, 0x38, 0x3E, 0x22, 0xA2, 0x30, 0x5C, 0x00, 0x0C,
+0x58, 0x0C, 0x04, 0x24, 0x39, 0x3E, 0x22, 0xA2, 0x50, 0x0C, 0x04, 0x24,
+0x1A, 0x5C, 0x00, 0x0C, 0x17, 0x00, 0x05, 0x24, 0x17, 0x00, 0x05, 0x24,
+0x1A, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24, 0xB0, 0x1B, 0x22, 0x96,
+0x02, 0x80, 0x04, 0x3C, 0x34, 0xE7, 0x84, 0x24, 0x00, 0x10, 0x42, 0x34,
+0x13, 0x58, 0x00, 0x0C, 0xB0, 0x1B, 0x22, 0xA6, 0x01, 0x00, 0x02, 0x24,
+0x25, 0xB0, 0x03, 0x3C, 0x04, 0x3E, 0x22, 0xAE, 0x4C, 0x00, 0x63, 0x34,
+0xB0, 0x1B, 0x22, 0x96, 0x00, 0x00, 0x66, 0x90, 0x08, 0x00, 0x65, 0x8E,
+0xC4, 0x3D, 0x27, 0x92, 0xC5, 0x3D, 0x28, 0x92, 0x3B, 0x41, 0x29, 0x92,
+0xD0, 0x3D, 0x2A, 0x92, 0xFF, 0x3D, 0x2B, 0x92, 0x00, 0x80, 0x42, 0x30,
+0x37, 0x3E, 0x26, 0xA2, 0x0C, 0x3E, 0x25, 0xAE, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x60, 0xA0, 0x31, 0x3E, 0x27, 0xA2, 0x32, 0x3E, 0x28, 0xA2,
+0x34, 0x3E, 0x22, 0xA6, 0x36, 0x3E, 0x29, 0xA2, 0xC4, 0x3D, 0x2A, 0xA2,
+0xC5, 0x3D, 0x2B, 0xA2, 0x3C, 0x3E, 0x20, 0xAE, 0x40, 0x3E, 0x20, 0xAE,
+0x8A, 0x40, 0x00, 0x0C, 0x33, 0x3E, 0x20, 0xA2, 0x10, 0x00, 0xA4, 0x27,
+0x90, 0x40, 0x00, 0x0C, 0x52, 0x41, 0x20, 0xA2, 0x21, 0x20, 0x00, 0x00,
+0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0x66, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0xC0, 0x14, 0x0C, 0x00, 0x70, 0x26,
+0x00, 0x00, 0x62, 0x8E, 0x21, 0x20, 0x20, 0x02, 0x44, 0x3E, 0x23, 0x26,
+0x08, 0x3E, 0x22, 0xAE, 0x3F, 0x00, 0x02, 0x24, 0xFF, 0xFF, 0x42, 0x24,
+0x00, 0x00, 0x60, 0xA0, 0xFD, 0xFF, 0x41, 0x04, 0x07, 0x00, 0x63, 0x24,
+0xB0, 0x1B, 0x83, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30,
+0x09, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x50, 0x26, 0x01, 0x00, 0x62, 0x30,
+0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x82, 0x92,
+0x0C, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x37, 0x00, 0x43, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92, 0x75, 0x0D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C,
+0x01, 0x00, 0x05, 0x24, 0x25, 0xB0, 0x04, 0x3C, 0x48, 0x00, 0x84, 0x34,
+0x00, 0x00, 0x83, 0x8C, 0x08, 0x3E, 0x05, 0x8E, 0x7B, 0xFF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x83, 0xAC, 0x0C, 0x00, 0xA2, 0x10, 0x60, 0x1B, 0x43, 0x26,
+0x3C, 0x00, 0x02, 0x24, 0x94, 0x39, 0x62, 0xAC, 0x2C, 0x00, 0xBF, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0xC4, 0x3D, 0x02, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x42, 0x2C, 0xF1, 0xFF, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x49, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x43, 0x26, 0x3C, 0x00, 0x02, 0x24, 0xA0, 0x0B, 0x00, 0x08,
+0x94, 0x39, 0x62, 0xAC, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x00, 0x02,
+0xF4, 0x54, 0x00, 0x0C, 0x70, 0x59, 0x84, 0x24, 0x02, 0x80, 0x04, 0x3C,
+0x44, 0xE7, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02,
+0x77, 0x0B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x24,
+0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x36, 0x0B, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x8D, 0x0B, 0x00, 0x08, 0x60, 0x1B, 0x50, 0x26, 0xE8, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x00, 0x00, 0x02, 0x92, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x40, 0x00,
+0x04, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x14, 0x50, 0xE7, 0x84, 0x24,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x13, 0x58, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x92, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x02, 0x80, 0x02, 0x3C, 0x84, 0x5B, 0x43, 0xAC,
+0x18, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0xD0, 0xFF, 0xBD, 0x27,
+0x18, 0x03, 0x42, 0x34, 0x80, 0x2F, 0x63, 0x24, 0x24, 0x00, 0xB3, 0xAF,
+0x28, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x04, 0x3C,
+0xEC, 0x5D, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x60, 0x14, 0x01, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x0F, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C,
+0xED, 0x5D, 0x64, 0x90, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C,
+0xFF, 0x00, 0x84, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C,
+0x98, 0x54, 0x42, 0x24, 0xA2, 0x00, 0x62, 0x10, 0x02, 0x80, 0x13, 0x3C,
+0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x02, 0x3C,
+0x36, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x60, 0x1B, 0x66, 0x26,
+0xF4, 0x38, 0xC5, 0x8C, 0xC0, 0x18, 0x03, 0x00, 0x23, 0xB0, 0x04, 0x3C,
+0xF0, 0x07, 0x63, 0x30, 0xFF, 0x1F, 0x02, 0x3C, 0x21, 0x18, 0x64, 0x00,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x62, 0x00, 0x23, 0x88, 0x85, 0x00,
+0x00, 0x04, 0x22, 0x26, 0x2B, 0x28, 0x85, 0x00, 0x98, 0x38, 0xC3, 0x8C,
+0x0B, 0x88, 0x45, 0x00, 0xE1, 0x01, 0x22, 0x2E, 0x94, 0x38, 0xC3, 0xAC,
+0xF8, 0x38, 0xC4, 0xAC, 0x9E, 0x38, 0xC0, 0xA4, 0x14, 0x00, 0x40, 0x14,
+0x9D, 0x38, 0xC0, 0xA0, 0x20, 0xFE, 0x82, 0x24, 0x20, 0x02, 0x83, 0x24,
+0x0A, 0x18, 0x45, 0x00, 0x23, 0x10, 0x02, 0x3C, 0xFF, 0x03, 0x42, 0x34,
+0x2B, 0x10, 0x43, 0x00, 0x21, 0x28, 0x60, 0x00, 0x32, 0x00, 0x40, 0x14,
+0xF4, 0x38, 0xC3, 0xAC, 0xF8, 0x38, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x18, 0x45, 0x00, 0x23, 0x88, 0x45, 0x00, 0x03, 0x00, 0x60, 0x10,
+0xE1, 0x01, 0x22, 0x2E, 0x00, 0x04, 0x31, 0x26, 0xE1, 0x01, 0x22, 0x2E,
+0x0E, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x70, 0x26, 0x60, 0x1B, 0x70, 0x26,
+0xF8, 0x38, 0x03, 0x8E, 0xF4, 0x38, 0x04, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0x83, 0x00, 0x2C, 0x00, 0x40, 0x14, 0x2B, 0x10, 0x64, 0x00,
+0x56, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x02, 0x3C, 0x80, 0x00, 0x03, 0x24,
+0xD0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x60, 0x1B, 0x70, 0x26,
+0xF4, 0x38, 0x03, 0x96, 0x2A, 0xB0, 0x02, 0x3C, 0x35, 0x00, 0x42, 0x34,
+0xC2, 0x88, 0x03, 0x00, 0x00, 0x00, 0x51, 0xA0, 0x73, 0x23, 0x00, 0x74,
+0x00, 0x00, 0x00, 0x00, 0x9E, 0x38, 0x03, 0x96, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xD0, 0x1B, 0x02, 0x8E, 0x80, 0x00, 0x03, 0x3C,
+0x41, 0xB0, 0x04, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xAC,
+0x28, 0x00, 0xBF, 0x8F, 0xD0, 0x1B, 0x02, 0xAE, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x00, 0xFC, 0xA5, 0x24,
+0x23, 0x0C, 0x00, 0x08, 0xF4, 0x38, 0xC5, 0xAC, 0x24, 0x2D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xE2, 0x2C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0B, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0x94, 0x38, 0x05, 0x8E, 0x21, 0x30, 0x80, 0x00,
+0xFF, 0xFF, 0x27, 0x32, 0x09, 0x00, 0x04, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E, 0x9E, 0x38, 0x05, 0x96,
+0xF4, 0x38, 0x02, 0x8E, 0x21, 0x18, 0x71, 0x00, 0x21, 0x28, 0x25, 0x02,
+0x21, 0x10, 0x51, 0x00, 0x09, 0x00, 0x04, 0x24, 0xF4, 0x38, 0x02, 0xAE,
+0x94, 0x38, 0x03, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x9E, 0x38, 0x05, 0xA6,
+0x60, 0x1B, 0x70, 0x26, 0xF4, 0x38, 0x03, 0x96, 0x2A, 0xB0, 0x02, 0x3C,
+0x35, 0x00, 0x42, 0x34, 0xC2, 0x88, 0x03, 0x00, 0x00, 0x00, 0x51, 0xA0,
+0x73, 0x23, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x38, 0x03, 0x96,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x1B, 0x02, 0x8E,
+0x80, 0x00, 0x03, 0x3C, 0x41, 0xB0, 0x04, 0x3C, 0x25, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x82, 0xAC, 0x28, 0x00, 0xBF, 0x8F, 0xD0, 0x1B, 0x02, 0xAE,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xFC, 0x38, 0x02, 0x8E, 0x94, 0x38, 0x05, 0x8E, 0x21, 0x30, 0x80, 0x00,
+0x23, 0x88, 0x44, 0x00, 0xFF, 0xFF, 0x27, 0x32, 0x09, 0x00, 0x04, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E,
+0x9E, 0x38, 0x02, 0x96, 0xF8, 0x38, 0x12, 0x96, 0x21, 0x18, 0x71, 0x00,
+0x21, 0x10, 0x22, 0x02, 0x23, 0x10, 0x11, 0x3C, 0x94, 0x38, 0x03, 0xAE,
+0x9E, 0x38, 0x02, 0xA6, 0x15, 0x00, 0x40, 0x16, 0xF4, 0x38, 0x11, 0xAE,
+0x09, 0x00, 0x04, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0x60, 0x1B, 0x70, 0x26,
+0x71, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x63, 0x26,
+0x2A, 0x1C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x58, 0xFF, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0x3A, 0x64, 0x94, 0x2A, 0x1C, 0x60, 0xA0,
+0x00, 0xC0, 0x84, 0x24, 0xA3, 0x31, 0x00, 0x0C, 0xFF, 0xFF, 0x84, 0x30,
+0x01, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x01, 0x00, 0x0C,
+0x09, 0x00, 0x04, 0x24, 0x94, 0x38, 0x05, 0x8E, 0x09, 0x00, 0x04, 0x24,
+0x23, 0x10, 0x06, 0x3C, 0x21, 0x38, 0x40, 0x02, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E, 0x9E, 0x38, 0x02, 0x96,
+0x21, 0x20, 0x51, 0x02, 0x21, 0x18, 0x72, 0x00, 0x21, 0x10, 0x42, 0x02,
+0xF4, 0x38, 0x04, 0xAE, 0x09, 0x00, 0x04, 0x24, 0x94, 0x38, 0x03, 0xAE,
+0x9E, 0x0C, 0x00, 0x08, 0x9E, 0x38, 0x02, 0xA6, 0x08, 0x00, 0xE0, 0x03,
+0x09, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x86, 0x30, 0x02, 0x80, 0x02, 0x3C,
+0x40, 0x00, 0xC3, 0x2C, 0x4A, 0xF5, 0x47, 0x90, 0x00, 0x00, 0x63, 0x38,
+0x3F, 0x00, 0x02, 0x24, 0x0A, 0x30, 0x43, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x0E, 0x04, 0x24, 0x00, 0x7F, 0x05, 0x24, 0x03, 0x00, 0xE2, 0x10,
+0x31, 0x00, 0xC3, 0x2C, 0xC1, 0x43, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x30, 0x00, 0x02, 0x24, 0xC1, 0x43, 0x00, 0x08, 0x0A, 0x30, 0x43, 0x00,
+0xC0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x38, 0x00, 0xB4, 0xAF,
+0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0x2C, 0x00, 0xB1, 0xAF,
+0x28, 0x00, 0xB0, 0xAF, 0xA4, 0xE7, 0x62, 0x24, 0x3C, 0x00, 0xBF, 0xAF,
+0x0A, 0x00, 0x4A, 0x94, 0x02, 0x00, 0x48, 0x94, 0x06, 0x00, 0x49, 0x94,
+0xFF, 0x00, 0x84, 0x30, 0xFF, 0x00, 0xA5, 0x30, 0xA4, 0xE7, 0x6B, 0x94,
+0x04, 0x00, 0x4C, 0x94, 0x08, 0x00, 0x4D, 0x94, 0x00, 0x1C, 0x05, 0x00,
+0x00, 0x14, 0x04, 0x00, 0x00, 0x3E, 0x05, 0x00, 0x00, 0x36, 0x04, 0x00,
+0x25, 0x38, 0xE3, 0x00, 0x25, 0x30, 0xC2, 0x00, 0x00, 0x44, 0x08, 0x00,
+0x00, 0x12, 0x05, 0x00, 0x00, 0x4C, 0x09, 0x00, 0x00, 0x54, 0x0A, 0x00,
+0x00, 0x1A, 0x04, 0x00, 0x25, 0x38, 0xE2, 0x00, 0x25, 0x40, 0x0B, 0x01,
+0x25, 0x48, 0x2C, 0x01, 0x25, 0x50, 0x4D, 0x01, 0x25, 0x30, 0xC3, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xA8, 0xAF, 0x14, 0x00, 0xA9, 0xAF,
+0x18, 0x00, 0xAA, 0xAF, 0x25, 0x98, 0xE5, 0x00, 0x25, 0x90, 0xC4, 0x00,
+0x60, 0x1B, 0x54, 0x24, 0x21, 0x80, 0x00, 0x00, 0x10, 0x00, 0xB1, 0x27,
+0x02, 0x00, 0x02, 0x2E, 0x32, 0x00, 0x40, 0x10, 0x80, 0x10, 0x10, 0x00,
+0x21, 0x10, 0x54, 0x00, 0xF0, 0x1C, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x40, 0x73, 0x00, 0x21, 0x38, 0x00, 0x00, 0x7F, 0x00, 0x09, 0x24,
+0xC0, 0x20, 0x07, 0x00, 0x04, 0x10, 0x89, 0x00, 0x24, 0x10, 0x48, 0x00,
+0x06, 0x10, 0x82, 0x00, 0x01, 0x00, 0xE5, 0x24, 0xFF, 0x00, 0x43, 0x30,
+0x21, 0x30, 0x27, 0x02, 0x40, 0x00, 0x63, 0x2C, 0xFF, 0x00, 0xA7, 0x30,
+0x02, 0x00, 0x60, 0x14, 0x04, 0x00, 0xE4, 0x2C, 0x3F, 0x00, 0x02, 0x24,
+0xF3, 0xFF, 0x80, 0x14, 0x10, 0x00, 0xC2, 0xA0, 0x23, 0x00, 0xA6, 0x93,
+0x22, 0x00, 0xA2, 0x93, 0x21, 0x00, 0xA5, 0x93, 0x40, 0x18, 0x10, 0x00,
+0x00, 0x14, 0x02, 0x00, 0x21, 0x18, 0x71, 0x00, 0x20, 0x00, 0xA7, 0x93,
+0x00, 0x36, 0x06, 0x00, 0x25, 0x30, 0xC2, 0x00, 0x00, 0x2A, 0x05, 0x00,
+0x00, 0x00, 0x64, 0x94, 0x25, 0x30, 0xC5, 0x00, 0x7F, 0x7F, 0x05, 0x3C,
+0x25, 0x30, 0xC7, 0x00, 0xC1, 0x43, 0x00, 0x0C, 0x7F, 0x7F, 0xA5, 0x34,
+0x01, 0x00, 0x02, 0x26, 0xFF, 0x00, 0x50, 0x30, 0x06, 0x00, 0x03, 0x2E,
+0xD5, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xBF, 0x8F,
+0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F,
+0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x40, 0x00, 0xBD, 0x27, 0x21, 0x10, 0x54, 0x00, 0xF0, 0x1C, 0x43, 0x8C,
+0x07, 0x0D, 0x00, 0x08, 0x21, 0x40, 0x72, 0x00, 0xD8, 0xFF, 0xBD, 0x27,
+0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C,
+0xC6, 0x5C, 0x43, 0x90, 0x02, 0x80, 0x07, 0x3C, 0x60, 0x1B, 0xE2, 0x24,
+0xFF, 0x00, 0x91, 0x30, 0x21, 0x20, 0x22, 0x02, 0x20, 0x00, 0x62, 0x30,
+0x10, 0x00, 0x63, 0x30, 0x63, 0x1D, 0x93, 0x90, 0x27, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x8D, 0x1D, 0x82, 0x90, 0x7F, 0x1D, 0x83, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x00, 0x36, 0x02, 0x00,
+0x03, 0x36, 0x06, 0x00, 0xFF, 0x00, 0x70, 0x30, 0x60, 0x1B, 0xE7, 0x24,
+0x21, 0x40, 0x27, 0x02, 0xB7, 0x1D, 0x02, 0x91, 0xB0, 0x1B, 0xE3, 0x84,
+0x0F, 0x00, 0x05, 0x3C, 0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00,
+0x0C, 0x08, 0x04, 0x24, 0x0F, 0x00, 0xC6, 0x30, 0x00, 0xFF, 0xA5, 0x34,
+0x06, 0x00, 0x60, 0x04, 0xFF, 0x00, 0x52, 0x30, 0xC5, 0x1D, 0x02, 0x91,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00,
+0xFF, 0x00, 0x50, 0x30, 0xC1, 0x43, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xC5, 0x0C, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x00, 0x02,
+0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0xD6, 0x0C, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x1D, 0x82, 0x90,
+0x9B, 0x1D, 0x83, 0x90, 0x4D, 0x0D, 0x00, 0x08, 0x23, 0x10, 0x43, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C,
+0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0xD1, 0x5C, 0x43, 0x90,
+0x01, 0x00, 0x02, 0x24, 0x09, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x90, 0x30,
+0x21, 0x30, 0x00, 0x02, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x04, 0x24, 0xFF, 0x03, 0x05, 0x24,
+0x83, 0x45, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x0F, 0x00, 0x05, 0x3C,
+0xFF, 0xFF, 0xA5, 0x34, 0x15, 0x00, 0x04, 0x24, 0x0A, 0x00, 0x03, 0x12,
+0xF4, 0xA8, 0x06, 0x34, 0x0F, 0x00, 0x05, 0x3C, 0x0B, 0x00, 0x02, 0x24,
+0xFF, 0xFF, 0xA5, 0x34, 0x05, 0x00, 0x02, 0x12, 0xF5, 0xF8, 0x06, 0x34,
+0x0F, 0x00, 0x05, 0x3C, 0xF4, 0xF8, 0x06, 0x34, 0x15, 0x00, 0x04, 0x24,
+0xFF, 0xFF, 0xA5, 0x34, 0x83, 0x45, 0x00, 0x0C, 0x0F, 0x00, 0x11, 0x3C,
+0x02, 0x80, 0x02, 0x3C, 0x48, 0xF5, 0x46, 0x90, 0xFE, 0x00, 0x03, 0x24,
+0x15, 0x00, 0x04, 0x24, 0xE3, 0xFF, 0xC3, 0x14, 0xFF, 0xFF, 0x25, 0x36,
+0xAC, 0x45, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x46, 0x30,
+0x00, 0xFF, 0x23, 0x36, 0x24, 0x10, 0x43, 0x00, 0x01, 0x00, 0xC6, 0x24,
+0x25, 0x30, 0x46, 0x00, 0xFF, 0xFF, 0x25, 0x36, 0x83, 0x45, 0x00, 0x0C,
+0x15, 0x00, 0x04, 0x24, 0x7F, 0x0D, 0x00, 0x08, 0x21, 0x30, 0x00, 0x02,
+0xFC, 0x00, 0x84, 0x30, 0x80, 0x00, 0x02, 0x24, 0x11, 0x00, 0x82, 0x10,
+0x06, 0x00, 0x03, 0x24, 0x81, 0x00, 0x82, 0x28, 0x10, 0x00, 0x40, 0x10,
+0xB0, 0x00, 0x02, 0x24, 0x20, 0x00, 0x02, 0x24, 0x0B, 0x00, 0x82, 0x10,
+0x02, 0x00, 0x03, 0x24, 0x21, 0x00, 0x82, 0x28, 0x15, 0x00, 0x40, 0x10,
+0x40, 0x00, 0x02, 0x24, 0x06, 0x00, 0x80, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x01, 0x00, 0x03, 0x24, 0x10, 0x00, 0x02, 0x24, 0x02, 0x00, 0x82, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x60, 0x00, 0xFD, 0xFF, 0x82, 0x10, 0x09, 0x00, 0x03, 0x24,
+0xB1, 0x00, 0x82, 0x28, 0x0F, 0x00, 0x40, 0x10, 0xC8, 0x00, 0x02, 0x24,
+0x90, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x82, 0x10, 0x07, 0x00, 0x03, 0x24,
+0x08, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08, 0xA0, 0x00, 0x02, 0x24,
+0xF2, 0xFF, 0x82, 0x10, 0x04, 0x00, 0x03, 0x24, 0x41, 0x00, 0x82, 0x28,
+0x0F, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x24,
+0xB9, 0x0D, 0x00, 0x08, 0x30, 0x00, 0x02, 0x24, 0xEA, 0xFF, 0x82, 0x10,
+0x0C, 0x00, 0x03, 0x24, 0xC9, 0x00, 0x82, 0x28, 0x04, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08,
+0xC0, 0x00, 0x02, 0x24, 0x0B, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08,
+0xD0, 0x00, 0x02, 0x24, 0x05, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08,
+0x50, 0x00, 0x02, 0x24, 0xD0, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xBF, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0x83, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x08, 0x00, 0x90, 0x94, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x90, 0x80, 0x00,
+0x25, 0x80, 0x02, 0x02, 0xFF, 0x00, 0xB4, 0x30, 0x21, 0x20, 0x00, 0x02,
+0xFF, 0x00, 0xD1, 0x30, 0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0x06, 0x24,
+0xEC, 0x54, 0x00, 0x0C, 0xFF, 0x00, 0xF3, 0x30, 0x04, 0x00, 0x06, 0x8E,
+0x08, 0x00, 0x05, 0x8E, 0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xE0, 0x03, 0x24,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x30, 0xC3, 0x00, 0x24, 0x28, 0xA2, 0x00,
+0x3F, 0xFF, 0x02, 0x3C, 0x10, 0x00, 0x08, 0x8E, 0xFF, 0xFF, 0x42, 0x34,
+0x00, 0x12, 0xC6, 0x34, 0x00, 0x40, 0x03, 0x3C, 0x24, 0x30, 0xC2, 0x00,
+0x05, 0x00, 0x07, 0x24, 0x04, 0x00, 0x02, 0x24, 0x0B, 0x38, 0x54, 0x00,
+0x25, 0x28, 0xA3, 0x00, 0x01, 0x00, 0x84, 0x32, 0x7F, 0xFF, 0x03, 0x24,
+0x00, 0x80, 0x02, 0x3C, 0x14, 0x00, 0x09, 0x8E, 0x24, 0x28, 0xA3, 0x00,
+0xC0, 0x21, 0x04, 0x00, 0x25, 0x40, 0x02, 0x01, 0x03, 0x00, 0x31, 0x32,
+0xFF, 0xE0, 0x02, 0x3C, 0x80, 0x8D, 0x11, 0x00, 0x25, 0x28, 0xA4, 0x00,
+0xFF, 0xFF, 0x42, 0x34, 0x0C, 0x00, 0x4A, 0x8E, 0x25, 0x30, 0xD1, 0x00,
+0xFF, 0x81, 0x03, 0x24, 0xE0, 0xFF, 0x04, 0x24, 0x24, 0x28, 0xA2, 0x00,
+0x3F, 0x00, 0x73, 0x32, 0xFB, 0xFF, 0x02, 0x3C, 0x24, 0x48, 0x23, 0x01,
+0x24, 0x30, 0xC4, 0x00, 0x00, 0x1E, 0x07, 0x00, 0x40, 0x9A, 0x13, 0x00,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x40, 0x02, 0x01, 0x25, 0x48, 0x33, 0x01,
+0x25, 0x28, 0xA3, 0x00, 0x25, 0x30, 0xC7, 0x00, 0x20, 0x00, 0x02, 0x24,
+0x08, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x0A, 0xA6, 0x02, 0x00, 0x02, 0xA2,
+0x10, 0x00, 0x08, 0xAE, 0x14, 0x00, 0x09, 0xAE, 0x04, 0x00, 0x06, 0xAE,
+0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x98, 0x54, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x42, 0xAE,
+0x04, 0x00, 0x52, 0xAC, 0x00, 0x00, 0x72, 0xAC, 0x04, 0x00, 0x43, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x2C, 0x00, 0xBF, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0xFF, 0xFF, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0xFF, 0x00, 0xB1, 0x30,
+0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xD2, 0x30, 0x00, 0x80, 0x02, 0x34,
+0x20, 0x00, 0x02, 0x12, 0x21, 0x20, 0x20, 0x02, 0x75, 0x0D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x03, 0x02, 0x63, 0x34,
+0x00, 0x00, 0x62, 0x90, 0x00, 0x08, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24,
+0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x35, 0x45, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x00, 0x09, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24,
+0x35, 0x45, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x84, 0x08, 0x04, 0x24,
+0xFF, 0xFF, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x58, 0x00, 0x06, 0x24,
+0x18, 0x00, 0x04, 0x24, 0x00, 0x0C, 0x05, 0x24, 0x83, 0x45, 0x00, 0x0C,
+0x01, 0x00, 0x06, 0x24, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x01, 0x00, 0x02, 0x24, 0x02, 0x00, 0x42, 0x12, 0x02, 0x00, 0x24, 0x26,
+0xFE, 0xFF, 0x24, 0x26, 0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x07, 0x3C, 0x03, 0x02, 0xE7, 0x34, 0x00, 0x00, 0xE3, 0x90,
+0xFB, 0xFF, 0x02, 0x24, 0x00, 0x08, 0x04, 0x24, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x00, 0xE3, 0xA0, 0x01, 0x00, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C,
+0x01, 0x00, 0x06, 0x24, 0x03, 0x00, 0x50, 0x32, 0x00, 0x09, 0x04, 0x24,
+0x01, 0x00, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24,
+0x42, 0x30, 0x10, 0x00, 0x00, 0x0A, 0x04, 0x24, 0x35, 0x45, 0x00, 0x0C,
+0x10, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x02, 0x00, 0x0D, 0x04, 0x24,
+0x35, 0x45, 0x00, 0x0C, 0x00, 0x0C, 0x05, 0x24, 0x84, 0x08, 0x04, 0x24,
+0xFF, 0xFF, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x18, 0x00, 0x06, 0x24,
+0x18, 0x00, 0x04, 0x24, 0x00, 0x0C, 0x05, 0x24, 0x83, 0x45, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0xD0, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB3, 0xAF, 0x02, 0x80, 0x13, 0x3C,
+0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x72, 0x26,
+0xFF, 0xFF, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xB1, 0xAF,
+0x28, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB1, 0x30,
+0xB0, 0x1B, 0x42, 0x96, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x80, 0x42, 0x30,
+0x11, 0x00, 0x50, 0x10, 0x21, 0x30, 0x20, 0x02, 0xC4, 0x3D, 0x45, 0x92,
+0x3C, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, 0x00, 0x80, 0x02, 0x34,
+0x14, 0x00, 0x02, 0x12, 0x00, 0x80, 0x02, 0x24, 0xB0, 0x1B, 0x42, 0x96,
+0x3B, 0x41, 0x51, 0xA2, 0xFF, 0x7F, 0x42, 0x30, 0xB0, 0x1B, 0x42, 0xA6,
+0x60, 0x1B, 0x62, 0x26, 0xB0, 0x1B, 0x45, 0x94, 0xC4, 0x3D, 0x44, 0x90,
+0x38, 0x0D, 0x00, 0x0C, 0x00, 0x10, 0xA5, 0x30, 0x10, 0x00, 0xA4, 0x27,
+0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xB0, 0x1B, 0x43, 0x96, 0x3B, 0x41, 0x51, 0xA2, 0x25, 0x18, 0x62, 0x00,
+0xB0, 0x0E, 0x00, 0x08, 0xB0, 0x1B, 0x43, 0xA6, 0xE0, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C, 0x28, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x21, 0x28, 0x00, 0x02,
+0x06, 0x00, 0x06, 0x24, 0x15, 0x00, 0x40, 0x10, 0xAC, 0xE8, 0x84, 0x24,
+0x08, 0x00, 0x44, 0x94, 0x08, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x22, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0x0C, 0x00, 0x03, 0x24, 0x25, 0x20, 0x82, 0x00,
+0x14, 0x00, 0x23, 0xAE, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x84, 0x24,
+0x17, 0x0A, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0x04, 0xE9, 0x84, 0x24, 0x21, 0x10, 0x00, 0x00,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x05, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xEC, 0xE8, 0xA5, 0x24, 0xE0, 0x0E, 0x00, 0x08,
+0xFF, 0xFF, 0x02, 0x24, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF,
+0x21, 0x98, 0x80, 0x00, 0x2C, 0x00, 0x04, 0x24, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x21, 0x90, 0xA0, 0x00, 0x20, 0x00, 0xBF, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C,
+0x02, 0x80, 0x05, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x28, 0xE9, 0x84, 0x24,
+0x21, 0x30, 0x40, 0x02, 0x19, 0x00, 0x40, 0x10, 0x10, 0xE9, 0xA5, 0x24,
+0x05, 0x00, 0x65, 0x92, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x0B, 0x00, 0x03, 0x24,
+0x25, 0x80, 0x02, 0x02, 0x20, 0x00, 0x10, 0x26, 0x0C, 0x00, 0x02, 0x24,
+0x21, 0x20, 0x00, 0x02, 0x0C, 0x00, 0x22, 0xAE, 0x14, 0x00, 0x23, 0xAE,
+0x21, 0x28, 0x60, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x08, 0x00, 0x12, 0xAE, 0x21, 0x20, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27,
+0x02, 0x80, 0x04, 0x3C, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90,
+0x02, 0x80, 0x11, 0x3C, 0x04, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30,
+0x04, 0x00, 0x63, 0x28, 0x3A, 0x00, 0x60, 0x14, 0x01, 0x00, 0x05, 0x24,
+0x40, 0xDF, 0x23, 0x8E, 0x0F, 0x00, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x00, 0x04, 0x24, 0x60, 0x00, 0x06, 0x24,
+0x12, 0x00, 0x60, 0x14, 0x60, 0x1B, 0x50, 0x24, 0x83, 0x45, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x05, 0x92, 0xD0, 0x07, 0x02, 0x24,
+0x01, 0x00, 0x03, 0x24, 0x0A, 0x10, 0x05, 0x00, 0x3C, 0x3A, 0x02, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90, 0x40, 0xDF, 0x23, 0xAE,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08,
+0x20, 0x00, 0xBD, 0x27, 0x0F, 0x00, 0x05, 0x3C, 0xFF, 0xFF, 0xA5, 0x34,
+0xAC, 0x45, 0x00, 0x0C, 0x24, 0x00, 0x04, 0x24, 0x49, 0x41, 0x04, 0x92,
+0xFF, 0x00, 0x43, 0x30, 0x00, 0x2C, 0x03, 0x00, 0x0A, 0x00, 0x64, 0x10,
+0x4A, 0x41, 0x02, 0xA2, 0x02, 0x80, 0x02, 0x3C, 0x49, 0xF5, 0x44, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0x00, 0x12, 0x27, 0x00, 0x74,
+0x25, 0x20, 0xA4, 0x00, 0x4A, 0x41, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x49, 0x41, 0x03, 0xA2, 0x48, 0x41, 0x03, 0x92, 0x10, 0x27, 0x02, 0x24,
+0x40, 0xDF, 0x20, 0xAE, 0x0A, 0x10, 0x03, 0x00, 0x3C, 0x3A, 0x02, 0xAE,
+0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27,
+0x4B, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x0F, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xBE, 0xAF,
+0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x21, 0x80, 0x80, 0x00, 0x45, 0x00, 0xA0, 0x14, 0x21, 0x90, 0x00, 0x00,
+0x08, 0x00, 0x82, 0x90, 0x02, 0x80, 0x13, 0x3C, 0x60, 0x1B, 0x63, 0x26,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x40, 0x62, 0xAC, 0x25, 0xB0, 0x02, 0x3C,
+0x0A, 0x00, 0x10, 0x26, 0xD0, 0x01, 0x57, 0x34, 0x02, 0x80, 0x14, 0x3C,
+0xD8, 0x01, 0x5E, 0x34, 0xDC, 0x01, 0x55, 0x34, 0xD4, 0x01, 0x56, 0x34,
+0x03, 0x00, 0x11, 0x24, 0x00, 0x00, 0x06, 0x92, 0x60, 0x1B, 0x62, 0x26,
+0xB8, 0x40, 0x47, 0x90, 0x0F, 0x00, 0xC3, 0x30, 0x01, 0x00, 0x05, 0x92,
+0x18, 0x00, 0x67, 0x00, 0x03, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x92,
+0x0F, 0x00, 0xA7, 0x30, 0x00, 0x3A, 0x07, 0x00, 0x02, 0x29, 0x05, 0x00,
+0x00, 0x22, 0x04, 0x00, 0x25, 0x20, 0x82, 0x00, 0x00, 0x2B, 0x05, 0x00,
+0x42, 0x11, 0x06, 0x00, 0x00, 0x24, 0x04, 0x00, 0x03, 0x00, 0x49, 0x30,
+0x02, 0x31, 0x06, 0x00, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0xC6, 0x30,
+0x12, 0x18, 0x00, 0x00, 0x0A, 0x00, 0x63, 0x24, 0xFF, 0x00, 0x63, 0x30,
+0x25, 0x18, 0x67, 0x00, 0x25, 0x18, 0x65, 0x00, 0x30, 0x00, 0x22, 0x11,
+0x25, 0x38, 0x64, 0x00, 0x02, 0x00, 0x22, 0x29, 0x3E, 0x00, 0x40, 0x14,
+0x02, 0x00, 0x02, 0x24, 0x38, 0x00, 0x22, 0x11, 0x03, 0x00, 0x02, 0x24,
+0x40, 0x00, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x20, 0x01,
+0x64, 0xE9, 0x84, 0x26, 0x13, 0x58, 0x00, 0x0C, 0xFF, 0xFF, 0x31, 0x26,
+0xD9, 0xFF, 0x21, 0x06, 0x04, 0x00, 0x10, 0x26, 0x25, 0xB0, 0x02, 0x3C,
+0xE7, 0x01, 0x42, 0x34, 0x00, 0x00, 0x52, 0xA0, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x13, 0x3C,
+0x08, 0x00, 0x83, 0x90, 0x60, 0x1B, 0x62, 0x26, 0xC0, 0x40, 0x44, 0x8C,
+0x0F, 0x00, 0x63, 0x30, 0xBB, 0xFF, 0x83, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F,
+0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0xA7, 0xAE, 0x21, 0x20, 0x00, 0x00, 0x25, 0xB0, 0x08, 0x3C,
+0x07, 0x10, 0x92, 0x00, 0x01, 0x00, 0x42, 0x30, 0x01, 0x00, 0x84, 0x24,
+0x02, 0x00, 0x40, 0x10, 0x03, 0x00, 0x85, 0x2C, 0xD0, 0x01, 0x07, 0xAD,
+0xF9, 0xFF, 0xA0, 0x14, 0x04, 0x00, 0x08, 0x25, 0xA3, 0x0F, 0x00, 0x08,
+0x21, 0x28, 0x20, 0x01, 0x0D, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xA2, 0x0F, 0x00, 0x08, 0x02, 0x00, 0x52, 0x36, 0xC7, 0xFF, 0x20, 0x15,
+0x21, 0x28, 0x20, 0x01, 0x0D, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xA3, 0x0F, 0x00, 0x08, 0x04, 0x00, 0x52, 0x36, 0x06, 0x00, 0xC0, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xA2, 0x0F, 0x00, 0x08, 0x01, 0x00, 0x52, 0x36,
+0x00, 0x00, 0xC7, 0xAE, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01,
+0x00, 0x00, 0xE7, 0xAE, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01,
+0x00, 0x00, 0xC7, 0xAF, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01,
+0xB8, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00,
+0x00, 0x01, 0x04, 0x24, 0x2C, 0x00, 0xB3, 0xAF, 0x44, 0x00, 0xBF, 0xAF,
+0x40, 0x00, 0xBE, 0xAF, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF,
+0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF, 0x28, 0x00, 0xB2, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0x20, 0x00, 0xB0, 0xAF, 0xAC, 0x00, 0x40, 0x10,
+0x21, 0x98, 0x40, 0x00, 0x08, 0x00, 0x50, 0x94, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x28, 0x20, 0x02, 0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26,
+0x20, 0x00, 0x00, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x30, 0x00, 0x04, 0x26, 0x20, 0x00, 0x03, 0x96, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x54, 0x24, 0x03, 0xFF, 0x63, 0x30, 0x50, 0x00, 0x63, 0x34,
+0x20, 0x00, 0x03, 0xA6, 0xE4, 0x1D, 0x82, 0x96, 0x02, 0x80, 0x03, 0x3C,
+0xB0, 0x55, 0x63, 0x24, 0x74, 0x00, 0x72, 0x24, 0xFF, 0x0F, 0x43, 0x30,
+0x00, 0x19, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24, 0x02, 0x22, 0x03, 0x00,
+0xE4, 0x1D, 0x82, 0xA6, 0x20, 0x00, 0x11, 0x26, 0x20, 0x00, 0x02, 0x24,
+0x16, 0x00, 0x23, 0xA2, 0x17, 0x00, 0x24, 0xA2, 0x21, 0x20, 0x40, 0x02,
+0xFB, 0x51, 0x00, 0x0C, 0x0C, 0x00, 0x62, 0xAE, 0x40, 0x00, 0x11, 0x26,
+0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x40, 0x00, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x0C, 0x00, 0x63, 0x8E, 0x21, 0x20, 0x40, 0x02,
+0x42, 0x00, 0x11, 0x26, 0x02, 0x00, 0x63, 0x24, 0x16, 0x52, 0x00, 0x0C,
+0x0C, 0x00, 0x63, 0xAE, 0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0x20, 0x02,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x0C, 0x00, 0x63, 0x8E,
+0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x42, 0x24, 0x02, 0x00, 0x63, 0x24,
+0x0C, 0x00, 0x63, 0xAE, 0x0C, 0x00, 0x46, 0x8C, 0x44, 0x00, 0x04, 0x26,
+0x0C, 0x00, 0x76, 0x26, 0x60, 0x00, 0x50, 0x24, 0x21, 0x28, 0x00, 0x00,
+0x10, 0x00, 0x47, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF,
+0x21, 0x20, 0x00, 0x02, 0x1B, 0x53, 0x00, 0x0C, 0x21, 0x88, 0x40, 0x00,
+0x09, 0x00, 0x43, 0x2C, 0x08, 0x00, 0x06, 0x24, 0x21, 0x20, 0x20, 0x02,
+0x0B, 0x30, 0x43, 0x00, 0x21, 0x38, 0x00, 0x02, 0x01, 0x00, 0x05, 0x24,
+0x18, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xB6, 0xAF, 0x21, 0x20, 0x40, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0xB0, 0x55, 0x42, 0x24, 0x03, 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24,
+0x48, 0x00, 0x47, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF,
+0x21, 0x88, 0x40, 0x00, 0xC0, 0x3A, 0x82, 0x8E, 0x0C, 0x00, 0x10, 0x24,
+0x2B, 0x10, 0x02, 0x02, 0x3A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x26, 0x56, 0x5E, 0x24, 0x68, 0x10, 0x00, 0x08, 0x21, 0xA8, 0x80, 0x02,
+0x21, 0x10, 0x12, 0x02, 0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E,
+0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24, 0x2B, 0x20, 0x04, 0x02,
+0x2F, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x12, 0x02,
+0x00, 0x00, 0x47, 0x90, 0x02, 0x80, 0x14, 0x3C, 0x2D, 0x00, 0x03, 0x24,
+0x21, 0x28, 0x1E, 0x02, 0x64, 0x5C, 0x84, 0x26, 0xF1, 0xFF, 0xE3, 0x14,
+0x20, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x41, 0xA3, 0x96, 0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x47, 0x90,
+0xBD, 0xFF, 0x63, 0x30, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0x0C, 0x00, 0x63, 0x34, 0x01, 0x00, 0xE7, 0x30, 0x44, 0xDF, 0xA5, 0x24,
+0x67, 0x5C, 0x44, 0x24, 0x10, 0x00, 0x06, 0x24, 0x06, 0x00, 0xE0, 0x14,
+0x04, 0x41, 0xA3, 0xA6, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x54, 0xDF, 0xA5, 0x24, 0x67, 0x5C, 0x64, 0x24, 0x10, 0x00, 0x06, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x12, 0x02,
+0x01, 0x00, 0x46, 0x90, 0x21, 0x20, 0x20, 0x02, 0x64, 0x5C, 0x87, 0x26,
+0x2D, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF,
+0x21, 0x88, 0x40, 0x00, 0x21, 0x10, 0x12, 0x02, 0x01, 0x00, 0x43, 0x90,
+0xC0, 0x3A, 0xA4, 0x8E, 0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24,
+0x2B, 0x20, 0x04, 0x02, 0xD4, 0xFF, 0x80, 0x14, 0x21, 0x10, 0x12, 0x02,
+0x18, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x10,
+0x21, 0x20, 0x60, 0x02, 0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F,
+0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F,
+0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F,
+0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x08,
+0x48, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F,
+0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F,
+0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F,
+0x20, 0x00, 0xB0, 0x8F, 0x58, 0xE9, 0x84, 0x24, 0xAC, 0xE9, 0xA5, 0x24,
+0x13, 0x58, 0x00, 0x08, 0x48, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C,
+0xB0, 0x55, 0x63, 0x24, 0x21, 0x20, 0x20, 0x02, 0xF8, 0xFF, 0xE6, 0x26,
+0x68, 0x00, 0x67, 0x24, 0x32, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xB6, 0xAF, 0x21, 0x20, 0x60, 0x02, 0x44, 0x00, 0xBF, 0x8F,
+0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F,
+0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F,
+0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F,
+0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00,
+0xDF, 0x0D, 0x00, 0x08, 0x48, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x20, 0x00, 0xBF, 0xAF,
+0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x65, 0x94,
+0x0F, 0x00, 0x42, 0x30, 0x00, 0x00, 0x83, 0x8C, 0xC0, 0x10, 0x02, 0x00,
+0x21, 0x20, 0x44, 0x00, 0x00, 0x10, 0xA8, 0x30, 0x02, 0x80, 0x02, 0x3C,
+0x00, 0x08, 0xA5, 0x30, 0xB0, 0x55, 0x51, 0x24, 0xFF, 0x3F, 0x63, 0x30,
+0x06, 0x00, 0xA0, 0x10, 0x18, 0x00, 0x90, 0x24, 0xE8, 0xFF, 0x67, 0x24,
+0x30, 0x00, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x11,
+0x10, 0x00, 0xA6, 0x27, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xAB, 0x1A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xF7, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x44, 0x24,
+0x10, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x10,
+0x10, 0x00, 0x25, 0x26, 0x0C, 0x00, 0x26, 0x8E, 0x1D, 0x55, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xED, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x26, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, 0xEE, 0x0F, 0x00, 0x0C,
+0x21, 0x20, 0x40, 0x00, 0xE8, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0xA0, 0xFF, 0xBD, 0x27, 0x58, 0x00, 0xBE, 0xAF, 0x5C, 0x00, 0xBF, 0xAF,
+0x54, 0x00, 0xB7, 0xAF, 0x50, 0x00, 0xB6, 0xAF, 0x4C, 0x00, 0xB5, 0xAF,
+0x48, 0x00, 0xB4, 0xAF, 0x44, 0x00, 0xB3, 0xAF, 0x40, 0x00, 0xB2, 0xAF,
+0x3C, 0x00, 0xB1, 0xAF, 0x38, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x46, 0x30, 0xE8, 0xFF, 0xC5, 0x24,
+0x01, 0x03, 0xA2, 0x2C, 0x16, 0x00, 0x40, 0x14, 0x21, 0xF0, 0x80, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24, 0x40, 0x3E, 0x62, 0x8C,
+0x02, 0x80, 0x04, 0x3C, 0xD0, 0xE9, 0x84, 0x24, 0x01, 0x00, 0x42, 0x24,
+0x40, 0x3E, 0x62, 0xAC, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F, 0x54, 0x00, 0xB7, 0x8F,
+0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F, 0x48, 0x00, 0xB4, 0x8F,
+0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F, 0x3C, 0x00, 0xB1, 0x8F,
+0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x60, 0x00, 0xBD, 0x27,
+0x7C, 0x00, 0xC4, 0x24, 0x5C, 0x00, 0xC6, 0x24, 0x53, 0x21, 0x00, 0x0C,
+0x24, 0x00, 0xA6, 0xAF, 0x74, 0x00, 0x40, 0x10, 0x20, 0x00, 0xA2, 0xAF,
+0x20, 0x00, 0xA3, 0x8F, 0x24, 0x00, 0xA6, 0x8F, 0x21, 0x28, 0x00, 0x00,
+0x08, 0x00, 0x62, 0x94, 0x02, 0x80, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00,
+0x20, 0x00, 0x57, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02,
+0x02, 0x80, 0x03, 0x3C, 0xE8, 0xE9, 0x62, 0x24, 0xE8, 0xE9, 0x67, 0x90,
+0x01, 0x00, 0x44, 0x90, 0x02, 0x00, 0xC3, 0x93, 0x02, 0x00, 0x45, 0x90,
+0x03, 0x00, 0x46, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24,
+0x00, 0x00, 0xC2, 0x8F, 0x00, 0x22, 0x04, 0x00, 0x0F, 0x00, 0x63, 0x30,
+0x25, 0x20, 0x87, 0x00, 0x00, 0x2C, 0x05, 0x00, 0xC0, 0x18, 0x03, 0x00,
+0x4B, 0x41, 0x07, 0x92, 0x21, 0x18, 0x7E, 0x00, 0x25, 0x28, 0xA4, 0x00,
+0xFF, 0x3F, 0x42, 0x30, 0x00, 0x36, 0x06, 0x00, 0x25, 0x30, 0xC5, 0x00,
+0x30, 0x00, 0xA2, 0xAF, 0x22, 0x00, 0x64, 0x24, 0x18, 0x00, 0x62, 0x24,
+0x10, 0x00, 0xA6, 0xAF, 0x2C, 0x00, 0xA4, 0xAF, 0x28, 0x00, 0xA2, 0xAF,
+0x53, 0x00, 0xE0, 0x14, 0x28, 0x00, 0x76, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x54, 0x24, 0xA5, 0x59, 0x73, 0x24,
+0x21, 0x90, 0x00, 0x00, 0x01, 0x00, 0x15, 0x24, 0x64, 0x11, 0x00, 0x08,
+0x21, 0x80, 0x00, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x01, 0x00, 0x52, 0x26,
+0x07, 0x00, 0x10, 0x26, 0x32, 0x00, 0x40, 0x10, 0x40, 0x00, 0x43, 0x2A,
+0x0C, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88, 0x14, 0x02,
+0x44, 0x3E, 0x22, 0x92, 0x21, 0x20, 0x13, 0x02, 0x21, 0x28, 0xC0, 0x02,
+0xF4, 0xFF, 0x55, 0x10, 0x06, 0x00, 0x06, 0x24, 0x21, 0x20, 0x13, 0x02,
+0x21, 0x28, 0xC0, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x44, 0x3E, 0x35, 0xA2, 0x30, 0x00, 0xA4, 0x8F, 0x74, 0x00, 0xF4, 0x26,
+0x80, 0x00, 0xF3, 0x26, 0x5C, 0x00, 0x83, 0x24, 0xE8, 0xFF, 0x82, 0x24,
+0x1C, 0x00, 0xA2, 0xAF, 0x00, 0x00, 0xE3, 0xAE, 0x28, 0x00, 0xA3, 0x8F,
+0x1C, 0x00, 0xA2, 0x8F, 0x21, 0x20, 0x80, 0x02, 0x18, 0x00, 0x65, 0x24,
+0x21, 0x30, 0x40, 0x00, 0xF4, 0x54, 0x00, 0x0C, 0x70, 0x00, 0xE2, 0xAE,
+0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x21, 0x28, 0x00, 0x00,
+0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27,
+0x0F, 0x00, 0x40, 0x10, 0x21, 0x80, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x60, 0x1B, 0x91, 0x24, 0x0C, 0x3E, 0x26, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x32, 0x00, 0xC0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xA2, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xC2, 0x10, 0x02, 0x80, 0x04, 0x3C,
+0xC0, 0x10, 0x12, 0x00, 0x23, 0x10, 0x52, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x44, 0x3E, 0x40, 0xA0, 0x20, 0x00, 0xA4, 0x8F, 0x74, 0x21, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F,
+0x54, 0x00, 0xB7, 0x8F, 0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F,
+0x48, 0x00, 0xB4, 0x8F, 0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F,
+0x3C, 0x00, 0xB1, 0x8F, 0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x60, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0xAC, 0xE8, 0x84, 0x24, 0x1B, 0x11, 0x00, 0x08, 0xBC, 0xE9, 0xA5, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0xAC, 0x5C, 0x84, 0x24, 0x21, 0x28, 0xC0, 0x02,
+0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xA8, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27,
+0x52, 0x41, 0x02, 0x92, 0x18, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x42, 0x24,
+0x90, 0x40, 0x00, 0x0C, 0x52, 0x41, 0x02, 0xA2, 0x56, 0x11, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0x70, 0x59, 0x84, 0x24, 0x1D, 0x55, 0x00, 0x0C,
+0x02, 0x00, 0x05, 0x26, 0xD5, 0xFF, 0x40, 0x14, 0xC0, 0x10, 0x12, 0x00,
+0x01, 0x00, 0x06, 0x92, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0xC0, 0x14,
+0x10, 0x00, 0xE4, 0x26, 0x0C, 0x00, 0xE0, 0xAE, 0x02, 0x00, 0xC2, 0x97,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28,
+0x5E, 0x00, 0x40, 0x10, 0x21, 0x20, 0xC0, 0x03, 0x34, 0x00, 0xE0, 0xAE,
+0x60, 0x00, 0xF1, 0x26, 0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x00, 0x00,
+0xE3, 0x54, 0x00, 0x0C, 0x10, 0x00, 0x06, 0x24, 0x70, 0x00, 0xE7, 0x8E,
+0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x05, 0x24, 0xF4, 0xFF, 0xE7, 0x24,
+0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27, 0x06, 0x00, 0x40, 0x10,
+0x21, 0x90, 0x00, 0x00, 0x1C, 0x00, 0xA6, 0x8F, 0x02, 0x00, 0x45, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x1C, 0x00, 0xB2, 0x8F,
+0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x32, 0x00, 0x05, 0x24,
+0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27,
+0x05, 0x00, 0x40, 0x10, 0x21, 0x20, 0xF2, 0x02, 0x1C, 0x00, 0xA6, 0x8F,
+0x60, 0x00, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24,
+0x1C, 0x00, 0xA5, 0x8F, 0x21, 0x20, 0x20, 0x02, 0x61, 0x53, 0x00, 0x0C,
+0x21, 0x28, 0xB2, 0x00, 0x21, 0x18, 0x40, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x40, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, 0x38, 0x00, 0xE2, 0xAE,
+0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x03, 0x00, 0x05, 0x24,
+0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27,
+0x48, 0x00, 0xE0, 0xAE, 0x04, 0x00, 0x40, 0x10, 0x3C, 0x00, 0xE0, 0xAE,
+0x02, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xE2, 0xAE,
+0xFB, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x80, 0x02, 0x21, 0x28, 0x40, 0x00,
+0x40, 0x00, 0xE4, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24,
+0x18, 0x52, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, 0xFF, 0xFF, 0x50, 0x30,
+0x01, 0x00, 0x02, 0x32, 0x1A, 0x00, 0x40, 0x10, 0x21, 0x28, 0xC0, 0x02,
+0x01, 0x00, 0x02, 0x24, 0x5C, 0x00, 0xE2, 0xAE, 0x2C, 0x00, 0xA5, 0x8F,
+0x04, 0x00, 0xE4, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x10, 0x00, 0x02, 0x32, 0x13, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24,
+0x30, 0x00, 0xE2, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0x44, 0x00, 0xE0, 0xAE,
+0x60, 0x1B, 0x62, 0x24, 0x3C, 0x3E, 0x43, 0x8C, 0x20, 0x00, 0xA4, 0x8F,
+0x01, 0x00, 0x63, 0x24, 0x3C, 0x3E, 0x43, 0xAC, 0x24, 0x00, 0xA3, 0x8F,
+0x08, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0xA3, 0x8F,
+0x17, 0x0A, 0x00, 0x0C, 0x14, 0x00, 0x62, 0xAC, 0x1D, 0x11, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x12, 0x00, 0x08, 0x5C, 0x00, 0xE0, 0xAE,
+0x11, 0x12, 0x00, 0x08, 0x30, 0x00, 0xE0, 0xAE, 0xE3, 0x17, 0x00, 0x0C,
+0x18, 0x00, 0xC5, 0x27, 0xC8, 0x11, 0x00, 0x08, 0x34, 0x00, 0xE2, 0xAE,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x05, 0x26, 0x01, 0x00, 0x03, 0x92,
+0xC1, 0x11, 0x00, 0x08, 0x0C, 0x00, 0xE3, 0xAE, 0xEF, 0x11, 0x00, 0x08,
+0x38, 0x00, 0xE3, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24,
+0xFC, 0x40, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x60, 0x10,
+0x01, 0x00, 0x05, 0x24, 0xB6, 0x40, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x42, 0x2C, 0x07, 0x00, 0x40, 0x10, 0x21, 0x28, 0x00, 0x00,
+0xC7, 0x3D, 0x83, 0x90, 0x01, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x82, 0x24, 0x44, 0x41, 0x45, 0x8C,
+0x40, 0x41, 0x46, 0x8C, 0x21, 0x20, 0x40, 0x00, 0x40, 0x18, 0x05, 0x00,
+0x40, 0x10, 0x06, 0x00, 0x2B, 0x18, 0x66, 0x00, 0x2B, 0x38, 0x45, 0x00,
+0x04, 0x00, 0x60, 0x14, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x05, 0x24,
+0x02, 0x00, 0x02, 0x24, 0x0A, 0x28, 0x47, 0x00, 0x21, 0x10, 0xA0, 0x00,
+0x40, 0x41, 0x80, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x44, 0x41, 0x80, 0xAC,
+0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF,
+0x43, 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x12, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24, 0x0D, 0x00, 0x43, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x16, 0x5C, 0x44, 0x90, 0x02, 0x80, 0x02, 0x3C,
+0xD4, 0xDD, 0x42, 0x24, 0x40, 0x18, 0x04, 0x00, 0x21, 0x18, 0x64, 0x00,
+0x21, 0x18, 0x70, 0x00, 0x80, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x64, 0x8C, 0x25, 0xB0, 0x02, 0x3C, 0xD8, 0x01, 0x42, 0x34,
+0x00, 0x00, 0x44, 0xAC, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x02, 0x00, 0x84, 0x90, 0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24,
+0x0F, 0x00, 0x84, 0x30, 0xC0, 0x20, 0x04, 0x00, 0x21, 0x20, 0x90, 0x00,
+0x1C, 0x00, 0x84, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x10, 0x37, 0x43, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x63, 0x30, 0x06, 0x00, 0x60, 0x14,
+0x21, 0x20, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0x02, 0x11, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0xE0, 0xFF, 0xBD, 0x27, 0x54, 0x4A, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x18, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x43, 0xAC,
+0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00,
+0x28, 0x00, 0x44, 0x24, 0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C,
+0x18, 0x00, 0x50, 0x24, 0x06, 0x00, 0x40, 0x10, 0x21, 0x20, 0x00, 0x02,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24,
+0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0xF3, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30, 0xEE, 0xFF, 0x40, 0x10,
+0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0x05, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x63, 0x30, 0x05, 0x00, 0x62, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0xA9, 0x12, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x37, 0x43, 0x94, 0x02, 0x80, 0x04, 0x3C,
+0x00, 0x01, 0x63, 0x30, 0xF8, 0xFF, 0x60, 0x10, 0x01, 0x00, 0x05, 0x24,
+0x07, 0x5E, 0x83, 0x90, 0xFB, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00,
+0x07, 0x5E, 0x83, 0xA0, 0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90,
+0x4B, 0x2E, 0x00, 0x0C, 0xFF, 0x00, 0x84, 0x30, 0x90, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0xA9, 0x12, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0xD8, 0xFF, 0xBD, 0x27, 0x28, 0x00, 0xA4, 0xA3, 0x00, 0x01, 0x04, 0x24,
+0x18, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB4, 0xAF,
+0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x2C, 0x00, 0xA5, 0xA3, 0x53, 0x21, 0x00, 0x0C, 0x30, 0x00, 0xA6, 0xA7,
+0xA4, 0x00, 0x40, 0x10, 0x21, 0x90, 0x40, 0x00, 0x30, 0x00, 0xA7, 0x97,
+0x28, 0x00, 0xA5, 0x93, 0x2C, 0x00, 0xA6, 0x93, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xB0, 0xEA, 0x84, 0x24, 0x08, 0x00, 0x50, 0x96,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x25, 0x80, 0x02, 0x02,
+0xB4, 0x55, 0x31, 0x26, 0x21, 0x28, 0x20, 0x02, 0x24, 0x00, 0x04, 0x26,
+0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x00, 0xA6,
+0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24, 0x2A, 0x00, 0x04, 0x26,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x21, 0x28, 0x20, 0x02,
+0x30, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x14, 0x3C,
+0x03, 0xFF, 0x63, 0x30, 0xD0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6,
+0x60, 0x1B, 0x93, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x62, 0x96,
+0x20, 0x00, 0x05, 0x26, 0x0C, 0x00, 0x51, 0x26, 0xFF, 0x0F, 0x43, 0x30,
+0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24,
+0xE4, 0x1D, 0x62, 0xA6, 0x28, 0x00, 0xA6, 0x27, 0x16, 0x00, 0xA3, 0xA0,
+0x17, 0x00, 0xA4, 0xA0, 0x21, 0x38, 0x20, 0x02, 0x38, 0x00, 0x04, 0x26,
+0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x40, 0x00,
+0x01, 0x00, 0x05, 0x24, 0x2C, 0x00, 0xA6, 0x27, 0x4C, 0x52, 0x00, 0x0C,
+0x21, 0x38, 0x20, 0x02, 0x28, 0x00, 0xA3, 0x93, 0x21, 0x20, 0x40, 0x00,
+0x03, 0x00, 0x02, 0x24, 0x12, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x82, 0x26, 0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24,
+0x21, 0x20, 0x40, 0x02, 0x01, 0x00, 0x63, 0x38, 0x0B, 0x38, 0x03, 0x00,
+0x21, 0x28, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x2C, 0x00, 0xA3, 0x93,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x60, 0x14, 0x01, 0x00, 0x02, 0x24,
+0xC5, 0x40, 0x63, 0x92, 0x21, 0x80, 0x60, 0x02, 0x01, 0x00, 0x68, 0x24,
+0xFF, 0x00, 0x02, 0x31, 0xFD, 0xFF, 0x40, 0x10, 0x21, 0x18, 0x00, 0x01,
+0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0xC5, 0x40, 0x08, 0xA2,
+0x25, 0x5C, 0xC6, 0x24, 0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24,
+0xC8, 0x40, 0x08, 0x8E, 0x30, 0x00, 0xA4, 0x97, 0xC3, 0xFF, 0x03, 0x24,
+0x02, 0x00, 0x08, 0x35, 0x0F, 0x00, 0x84, 0x30, 0x24, 0x40, 0x03, 0x01,
+0x80, 0x20, 0x04, 0x00, 0xFF, 0xFF, 0x03, 0x3C, 0x3F, 0x00, 0x63, 0x34,
+0x25, 0x40, 0x04, 0x01, 0x24, 0x40, 0x03, 0x01, 0x00, 0x08, 0x08, 0x35,
+0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0xC8, 0x40, 0x08, 0xAE,
+0x28, 0x5C, 0xC6, 0x24, 0x21, 0x20, 0x40, 0x00, 0x4C, 0x52, 0x00, 0x0C,
+0x02, 0x00, 0x05, 0x24, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02,
+0x2A, 0x5C, 0xC6, 0x24, 0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24,
+0x4C, 0x52, 0x00, 0x0C, 0xCA, 0x40, 0x00, 0xA6, 0x30, 0x00, 0xA3, 0x97,
+0x21, 0x20, 0x40, 0x00, 0x02, 0x80, 0x06, 0x3C, 0x07, 0x00, 0x63, 0x30,
+0x40, 0x18, 0x03, 0x00, 0x21, 0x18, 0x70, 0x00, 0xD4, 0x1D, 0x62, 0x94,
+0x2C, 0x5C, 0xC6, 0x24, 0x21, 0x38, 0x20, 0x02, 0x00, 0x11, 0x02, 0x00,
+0x02, 0x00, 0x05, 0x24, 0x4C, 0x52, 0x00, 0x0C, 0xCC, 0x40, 0x02, 0xA6,
+0x22, 0x13, 0x00, 0x08, 0x60, 0x1B, 0x82, 0x26, 0xB5, 0xFF, 0x62, 0x14,
+0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0x24, 0x5C, 0xC6, 0x24,
+0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x40, 0x00,
+0x30, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C,
+0x02, 0x00, 0x05, 0x24, 0xC8, 0x40, 0x68, 0x8E, 0xFF, 0xFF, 0x03, 0x3C,
+0x3F, 0x00, 0x63, 0x34, 0x24, 0x40, 0x03, 0x01, 0x00, 0x08, 0x08, 0x35,
+0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0x21, 0x20, 0x40, 0x00,
+0x28, 0x5C, 0xC6, 0x24, 0x02, 0x00, 0x05, 0x24, 0x4C, 0x52, 0x00, 0x0C,
+0xC8, 0x40, 0x68, 0xAE, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x40, 0x00,
+0x2A, 0x5C, 0xC6, 0x24, 0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C,
+0x02, 0x00, 0x05, 0x24, 0x22, 0x13, 0x00, 0x08, 0x60, 0x1B, 0x82, 0x26,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0xA0, 0xEA, 0xA5, 0x24, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x82, 0x90,
+0x02, 0x80, 0x11, 0x3C, 0x21, 0x80, 0x80, 0x00, 0x60, 0x1B, 0x31, 0x26,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0x06, 0x24, 0x01, 0x00, 0x05, 0x26,
+0x28, 0x5C, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0xC4, 0x40, 0x22, 0xA2,
+0x04, 0x00, 0x03, 0x92, 0x03, 0x00, 0x02, 0x92, 0x00, 0x1A, 0x03, 0x00,
+0x25, 0x18, 0x62, 0x00, 0xCA, 0x40, 0x23, 0xA6, 0x06, 0x00, 0x02, 0x92,
+0x05, 0x00, 0x03, 0x92, 0x00, 0x12, 0x02, 0x00, 0x25, 0x10, 0x43, 0x00,
+0xCC, 0x40, 0x22, 0xA6, 0x01, 0x00, 0x05, 0x92, 0x06, 0x00, 0x04, 0x92,
+0x05, 0x00, 0x02, 0x92, 0x82, 0x28, 0x05, 0x00, 0x00, 0x22, 0x04, 0x00,
+0x25, 0x20, 0x82, 0x00, 0x6A, 0x48, 0x00, 0x0C, 0x0F, 0x00, 0xA5, 0x30,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x03, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00,
+0xD9, 0x12, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0x42, 0x34,
+0xFC, 0x4E, 0x63, 0x24, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x00, 0x00, 0x43, 0xAC,
+0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x88, 0x44, 0x00,
+0x28, 0x00, 0x24, 0x26, 0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C,
+0x18, 0x00, 0x30, 0x26, 0x08, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02,
+0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00,
+0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xF1, 0xFF, 0x40, 0x14,
+0x03, 0x00, 0x02, 0x24, 0x30, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xED, 0xFF, 0x62, 0x14, 0x30, 0x00, 0x24, 0x26, 0x02, 0x80, 0x07, 0x3C,
+0x60, 0x1B, 0xE5, 0x24, 0xFC, 0x40, 0xA2, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0xE7, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x06, 0x24, 0x01, 0x00, 0x83, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x66, 0x10, 0x02, 0x00, 0x62, 0x28,
+0x2E, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0xDF, 0xFF, 0x62, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x62, 0x30, 0x0A, 0x00, 0x40, 0x14, 0x02, 0x11, 0x03, 0x00,
+0xC6, 0x40, 0xA3, 0x90, 0x04, 0x10, 0x46, 0x00, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x10, 0x43, 0x00, 0xC6, 0x40, 0xA2, 0xA0, 0x05, 0x00, 0x83, 0x90,
+0x04, 0x00, 0x82, 0x90, 0x00, 0x1A, 0x03, 0x00, 0x25, 0x90, 0x62, 0x00,
+0xC6, 0x40, 0xA5, 0x90, 0x02, 0x80, 0x04, 0x3C, 0xCC, 0xEA, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, 0xD5, 0x13, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x82, 0x90, 0x05, 0x00, 0x83, 0x90,
+0x03, 0x00, 0x84, 0x90, 0x00, 0x12, 0x02, 0x00, 0x82, 0x18, 0x03, 0x00,
+0x25, 0x10, 0x44, 0x00, 0x15, 0x00, 0x40, 0x14, 0x07, 0x00, 0x64, 0x30,
+0xC6, 0x40, 0xA3, 0x90, 0x04, 0x10, 0x86, 0x00, 0x25, 0x10, 0x43, 0x00,
+0xC6, 0x40, 0xA2, 0xA0, 0x60, 0x1B, 0xE2, 0x24, 0xF8, 0x40, 0x43, 0x90,
+0xC6, 0x40, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x18, 0x62, 0x00,
+0xDC, 0xEA, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xF0, 0x40, 0x60, 0xA0,
+0xD5, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xFF, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x97, 0x13, 0x00, 0x0C, 0x32, 0x00, 0x24, 0x26,
+0xD5, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x40, 0xA3, 0x90,
+0x04, 0x10, 0x86, 0x00, 0x27, 0x10, 0x02, 0x00, 0x17, 0x14, 0x00, 0x08,
+0x24, 0x10, 0x43, 0x00, 0xB8, 0xFF, 0xBD, 0x27, 0x38, 0x00, 0xB6, 0xAF,
+0xFF, 0xFF, 0x96, 0x30, 0x00, 0x01, 0x04, 0x24, 0x3C, 0x00, 0xB7, 0xAF,
+0x28, 0x00, 0xB2, 0xAF, 0x40, 0x00, 0xBF, 0xAF, 0x34, 0x00, 0xB5, 0xAF,
+0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, 0x24, 0x00, 0xB1, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0x20, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0x40, 0x00,
+0x81, 0x00, 0x40, 0x10, 0x21, 0xB8, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xF8, 0xEA, 0x84, 0x24, 0x08, 0x00, 0x50, 0x96,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x25, 0x80, 0x02, 0x02,
+0xB4, 0x55, 0x31, 0x26, 0x24, 0x00, 0x04, 0x26, 0x21, 0x28, 0x20, 0x02,
+0x20, 0x00, 0x00, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x30, 0x00, 0x04, 0x26,
+0x21, 0x28, 0x20, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x15, 0x3C,
+0x03, 0xFF, 0x63, 0x30, 0xB0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6,
+0x60, 0x1B, 0xA8, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x02, 0x95,
+0x20, 0x00, 0x14, 0x26, 0x0C, 0x00, 0x51, 0x26, 0xFF, 0x0F, 0x43, 0x30,
+0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24,
+0xE4, 0x1D, 0x02, 0xA5, 0x17, 0x00, 0x84, 0xA2, 0x16, 0x00, 0x83, 0xA2,
+0x20, 0x40, 0x04, 0x8D, 0x03, 0x00, 0x02, 0x24, 0x31, 0x00, 0x82, 0x10,
+0x38, 0x00, 0x10, 0x26, 0x60, 0x1B, 0xB3, 0x26, 0x24, 0x40, 0x62, 0x8E,
+0x21, 0x20, 0x00, 0x02, 0x02, 0x00, 0x05, 0x24, 0x01, 0x00, 0x42, 0x38,
+0x01, 0x00, 0x42, 0x2C, 0x18, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02,
+0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xA2, 0xA7, 0x20, 0x40, 0x63, 0x8E,
+0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA6, 0x27,
+0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xA3, 0xA7,
+0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA6, 0x27,
+0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xB6, 0xA7,
+0x20, 0x40, 0x63, 0x8E, 0x21, 0x80, 0x40, 0x00, 0x03, 0x00, 0x02, 0x24,
+0x28, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xA2, 0x26,
+0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0x40, 0x02,
+0x01, 0x00, 0x63, 0x38, 0x21, 0x30, 0xE0, 0x02, 0x0B, 0x38, 0x03, 0x00,
+0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x40, 0x00, 0xBF, 0x8F,
+0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F,
+0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F,
+0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x48, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x95, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x42, 0x30, 0xCD, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0xB3, 0x26,
+0x2C, 0x40, 0x03, 0x8D, 0x30, 0x40, 0x02, 0x8D, 0x21, 0x20, 0x00, 0x02,
+0x80, 0x1F, 0x03, 0x00, 0x25, 0x18, 0x43, 0x00, 0x04, 0x00, 0x05, 0x24,
+0x01, 0x00, 0x42, 0x24, 0x1C, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02,
+0x30, 0x40, 0x02, 0xAD, 0x4C, 0x52, 0x00, 0x0C, 0x1C, 0x00, 0xA3, 0xAF,
+0x69, 0x14, 0x00, 0x08, 0x21, 0x80, 0x40, 0x00, 0xB0, 0x1B, 0x62, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0xD6, 0xFF, 0x40, 0x10,
+0x60, 0x1B, 0xA2, 0x26, 0x02, 0x80, 0x07, 0x3C, 0x21, 0x20, 0x00, 0x02,
+0x94, 0x5B, 0xE7, 0x24, 0x10, 0x00, 0x05, 0x24, 0x80, 0x00, 0x06, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF, 0x00, 0x00, 0x83, 0x96,
+0x01, 0x00, 0x17, 0x24, 0x00, 0x40, 0x63, 0x34, 0x85, 0x14, 0x00, 0x08,
+0x00, 0x00, 0x83, 0xA6, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xEC, 0xEA, 0xA5, 0x24,
+0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F,
+0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F,
+0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0xB0, 0xFF, 0xBD, 0x27,
+0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF,
+0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0x48, 0x00, 0xBF, 0xAF,
+0x44, 0x00, 0xB7, 0xAF, 0x40, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xB5, 0xAF,
+0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x12, 0x3C, 0x21, 0xA0, 0x80, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00,
+0x28, 0x00, 0x11, 0x26, 0xB4, 0x55, 0x45, 0x26, 0x21, 0x20, 0x20, 0x02,
+0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x18, 0x00, 0x13, 0x26,
+0x9F, 0x00, 0x40, 0x10, 0x21, 0x20, 0x60, 0x02, 0x02, 0x80, 0x15, 0x3C,
+0x60, 0x1B, 0xA2, 0x26, 0x4B, 0x41, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x82, 0x00, 0x60, 0x10, 0x3C, 0x00, 0x04, 0x26, 0x60, 0x1B, 0xB0, 0x26,
+0xB0, 0x1B, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0x30,
+0x6D, 0x00, 0x40, 0x14, 0x10, 0x00, 0x62, 0x30, 0x13, 0x00, 0x40, 0x14,
+0x10, 0x00, 0x76, 0x26, 0x60, 0x1B, 0xB0, 0x26, 0xB0, 0x1B, 0x02, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x8F, 0x00, 0x40, 0x14,
+0x21, 0x18, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F, 0x44, 0x00, 0xB7, 0x8F,
+0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F,
+0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F,
+0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x50, 0x00, 0xBD, 0x27, 0x21, 0x20, 0xC0, 0x02, 0xB4, 0x55, 0x45, 0x26,
+0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xE9, 0xFF, 0x40, 0x14,
+0x07, 0x00, 0x02, 0x24, 0xB6, 0x40, 0x02, 0xA2, 0xE8, 0x39, 0x00, 0xAE,
+0x00, 0x00, 0x84, 0x8E, 0x0C, 0x00, 0x12, 0x24, 0xFF, 0x3F, 0x82, 0x30,
+0xE8, 0xFF, 0x42, 0x24, 0x2A, 0x10, 0x42, 0x02, 0x9C, 0x00, 0x40, 0x10,
+0x21, 0xB8, 0x00, 0x02, 0x1F, 0x15, 0x00, 0x08, 0x21, 0x80, 0x72, 0x02,
+0x19, 0x00, 0x03, 0x92, 0xFF, 0x3F, 0x82, 0x30, 0xE8, 0xFF, 0x42, 0x24,
+0x21, 0x18, 0x72, 0x00, 0x02, 0x00, 0x72, 0x24, 0x2A, 0x10, 0x42, 0x02,
+0x93, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xB0, 0x26, 0x21, 0x80, 0x72, 0x02,
+0x18, 0x00, 0x03, 0x92, 0xDD, 0x00, 0x02, 0x24, 0xF4, 0xFF, 0x62, 0x14,
+0x1A, 0x00, 0x11, 0x26, 0x02, 0x80, 0x05, 0x3C, 0x64, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x55, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x60, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x4F, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x54, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x44, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x50, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x3E, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x4C, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x38, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x44, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x3B, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x40, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x53, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x48, 0xDE, 0xA5, 0x24,
+0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x47, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x21, 0x20, 0x20, 0x02,
+0x34, 0xDE, 0xA5, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x24,
+0x2F, 0x01, 0x40, 0x10, 0x02, 0x00, 0x02, 0x24, 0x00, 0x00, 0x84, 0x8E,
+0x16, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x0C,
+0x21, 0x20, 0x80, 0x02, 0x21, 0x18, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F,
+0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F,
+0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F,
+0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x87, 0x8E,
+0x07, 0x00, 0x05, 0x24, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24,
+0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x78, 0xFF, 0x40, 0x10,
+0x21, 0x38, 0x40, 0x00, 0x20, 0x00, 0xA5, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0xA2, 0x28, 0x73, 0xFF, 0x40, 0x14, 0xFD, 0xFF, 0xA5, 0x24,
+0x05, 0x00, 0xE4, 0x24, 0xE5, 0x4B, 0x00, 0x0C, 0xFF, 0x00, 0xA5, 0x30,
+0x02, 0x80, 0x04, 0x3C, 0xAC, 0x5C, 0x84, 0x24, 0x21, 0x28, 0x20, 0x02,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xEC, 0x14, 0x00, 0x08,
+0x60, 0x1B, 0xB0, 0x26, 0xB9, 0x2B, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02,
+0xE6, 0x14, 0x00, 0x08, 0x02, 0x80, 0x15, 0x3C, 0xB4, 0x55, 0x45, 0x26,
+0x10, 0x00, 0x64, 0x26, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0xD4, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, 0x21, 0x20, 0x80, 0x02,
+0xE3, 0x17, 0x00, 0x0C, 0x18, 0x00, 0x85, 0x26, 0x21, 0x20, 0x40, 0x00,
+0x8D, 0x17, 0x00, 0x0C, 0x05, 0x00, 0x05, 0x24, 0xB0, 0x1B, 0x03, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x0C, 0x00, 0x40, 0x14,
+0x04, 0x00, 0x62, 0x30, 0x4B, 0x00, 0x40, 0x14, 0x60, 0x1B, 0xB0, 0x26,
+0xB7, 0x40, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x24,
+0xFF, 0x00, 0x83, 0x30, 0x15, 0x00, 0x02, 0x24, 0x5D, 0x00, 0x62, 0x10,
+0x21, 0x18, 0x00, 0x00, 0xF9, 0x14, 0x00, 0x08, 0xB7, 0x40, 0x04, 0xA2,
+0x8A, 0x40, 0x00, 0x0C, 0x24, 0x00, 0xA4, 0x27, 0xE8, 0x1E, 0x03, 0x8E,
+0xEC, 0x1E, 0x02, 0x8E, 0x24, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x63, 0x24,
+0x01, 0x00, 0x42, 0x24, 0xEC, 0x1E, 0x02, 0xAE, 0x90, 0x40, 0x00, 0x0C,
+0xE8, 0x1E, 0x03, 0xAE, 0x9A, 0x15, 0x00, 0x08, 0x60, 0x1B, 0xB0, 0x26,
+0x60, 0x1B, 0xB0, 0x26, 0xB6, 0x40, 0x03, 0x92, 0x07, 0x00, 0x02, 0x24,
+0x21, 0x00, 0x62, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C,
+0x5C, 0xEB, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x46, 0x90, 0x01, 0x00, 0x03, 0x24,
+0x0F, 0x00, 0xC3, 0x10, 0x60, 0x1B, 0xA4, 0x26, 0xD5, 0x4E, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F, 0x44, 0x00, 0xB7, 0x8F,
+0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F,
+0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F,
+0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x50, 0x00, 0xBD, 0x27, 0xB6, 0x40, 0x83, 0x90, 0x03, 0x00, 0x02, 0x24,
+0x2A, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x41, 0x86, 0xA0,
+0xD5, 0x4E, 0x00, 0x0C, 0x3C, 0x41, 0x80, 0xA0, 0xBF, 0x15, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0xDE, 0xA5, 0x24, 0x21, 0x20, 0xC0, 0x02,
+0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, 0x07, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x05, 0x3C, 0x21, 0x20, 0xC0, 0x02, 0x58, 0xDE, 0xA5, 0x24,
+0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, 0xD5, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x70, 0xEB, 0x84, 0x24,
+0xB6, 0x15, 0x00, 0x08, 0xB6, 0x40, 0x00, 0xA2, 0x0A, 0x00, 0x76, 0x26,
+0x1F, 0x54, 0x00, 0x0C, 0x21, 0x20, 0xC0, 0x02, 0x20, 0x00, 0x10, 0x24,
+0x37, 0x00, 0x50, 0x10, 0x21, 0x88, 0x40, 0x00, 0x8A, 0x40, 0x00, 0x0C,
+0x24, 0x00, 0xA4, 0x27, 0x40, 0x10, 0x11, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x60, 0x1B, 0xA4, 0x26, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00,
+0xF8, 0x1D, 0x43, 0x8C, 0x24, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x63, 0x24,
+0x90, 0x40, 0x00, 0x0C, 0xF8, 0x1D, 0x43, 0xAC, 0x60, 0x15, 0x00, 0x08,
+0x21, 0x18, 0x00, 0x00, 0x3C, 0x41, 0x86, 0xA0, 0xD5, 0x4E, 0x00, 0x0C,
+0x3D, 0x41, 0x80, 0xA0, 0xBF, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x55, 0x12, 0x00, 0x0C, 0xB7, 0x40, 0x00, 0xA2, 0x02, 0x80, 0x02, 0x3C,
+0xD2, 0x5C, 0x44, 0x90, 0x02, 0x00, 0x03, 0x24, 0x5D, 0xFF, 0x83, 0x14,
+0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0x87, 0x8E, 0x24, 0x00, 0x64, 0x26,
+0x2A, 0x00, 0x05, 0x24, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24,
+0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x54, 0xFF, 0x40, 0x10,
+0x21, 0x18, 0x00, 0x00, 0x02, 0x00, 0x44, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x82, 0x30, 0x95, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xA5, 0x26,
+0x01, 0x00, 0x82, 0x30, 0x92, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C,
+0xD3, 0x5C, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24, 0x9F, 0x00, 0x83, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xEF, 0x03, 0x24,
+0x00, 0x08, 0x42, 0x34, 0x24, 0x10, 0x43, 0x00, 0xFC, 0x23, 0x02, 0xAE,
+0x60, 0x15, 0x00, 0x08, 0x21, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0x04, 0x24,
+0xC7, 0x53, 0x00, 0x0C, 0x21, 0x28, 0xC0, 0x02, 0xC6, 0xFF, 0x50, 0x10,
+0x21, 0x88, 0x40, 0x00, 0x00, 0x00, 0x87, 0x8E, 0x24, 0x00, 0x77, 0x26,
+0x21, 0x20, 0xE0, 0x02, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24,
+0x01, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27,
+0xCB, 0xFE, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0xA6, 0x8F,
+0x02, 0x00, 0x45, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x87, 0x8E, 0x21, 0x20, 0xE0, 0x02, 0x32, 0x00, 0x05, 0x24,
+0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, 0x20, 0x00, 0xB0, 0x8F,
+0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x08, 0x00, 0x40, 0x10,
+0x10, 0x00, 0xA4, 0x27, 0x20, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x90, 0x00,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24, 0x20, 0x00, 0xA3, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x03, 0x02, 0x10, 0x00, 0xA4, 0x27,
+0x61, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02, 0x21, 0x28, 0x00, 0x02,
+0x10, 0x00, 0xA4, 0x27, 0xA6, 0x53, 0x00, 0x0C, 0x0F, 0x00, 0x53, 0x30,
+0x00, 0x00, 0x87, 0x8E, 0x21, 0x20, 0xE0, 0x02, 0x2D, 0x00, 0x05, 0x24,
+0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, 0x20, 0x00, 0xA6, 0x27,
+0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x11, 0x00, 0x40, 0x10,
+0x00, 0x81, 0x11, 0x00, 0x06, 0x00, 0x44, 0x90, 0x05, 0x00, 0x43, 0x90,
+0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x45, 0x90, 0x00, 0x1B, 0x03, 0x00,
+0x00, 0x25, 0x04, 0x00, 0x25, 0x18, 0x64, 0x00, 0x10, 0x00, 0xA5, 0x30,
+0x25, 0x90, 0x43, 0x02, 0x02, 0x00, 0xA0, 0x14, 0x0F, 0x00, 0x02, 0x3C,
+0xFF, 0x0F, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x90, 0x42, 0x02,
+0x08, 0x00, 0x73, 0x36, 0x00, 0x81, 0x11, 0x00, 0x25, 0x80, 0x13, 0x02,
+0xFF, 0xFF, 0x10, 0x32, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x20, 0x02,
+0x21, 0x30, 0x00, 0x02, 0x21, 0x38, 0x40, 0x02, 0x13, 0x58, 0x00, 0x0C,
+0x8C, 0xEB, 0x84, 0x24, 0x21, 0x20, 0x00, 0x02, 0x63, 0x5E, 0x00, 0x74,
+0x21, 0x28, 0x40, 0x02, 0x60, 0x1B, 0xA3, 0x26, 0x3A, 0x41, 0x62, 0x90,
+0x21, 0x20, 0xC0, 0x02, 0x21, 0x28, 0x20, 0x02, 0x01, 0x00, 0x42, 0x24,
+0xEA, 0x0E, 0x00, 0x0C, 0x3A, 0x41, 0x62, 0xA0, 0xEA, 0x15, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x01, 0x00, 0x02, 0x24,
+0xA0, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, 0xB6, 0x40, 0xE2, 0xA2,
+0x02, 0x80, 0x04, 0x3C, 0xB8, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08,
+0xB6, 0x40, 0xE0, 0xA2, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26,
+0x03, 0x00, 0x02, 0x24, 0xCC, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08,
+0xB6, 0x40, 0x62, 0xA0, 0x1E, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x62, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x20, 0x00, 0x02, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0xC8, 0xDF, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x1A, 0x00, 0x60, 0x14, 0x11, 0x00, 0x03, 0x24, 0x13, 0x58, 0x00, 0x0C,
+0xE0, 0xEB, 0x84, 0x24, 0x05, 0x00, 0x02, 0x24, 0xB8, 0x15, 0x00, 0x08,
+0xB6, 0x40, 0xE2, 0xA2, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26,
+0x02, 0x00, 0x02, 0x24, 0xF8, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08,
+0xB6, 0x40, 0x62, 0xA0, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26,
+0x04, 0x00, 0x02, 0x24, 0x0C, 0xEC, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08,
+0xB6, 0x40, 0x62, 0xA0, 0xFC, 0x23, 0xA2, 0x8C, 0xFF, 0xEF, 0x03, 0x24,
+0xFF, 0xF7, 0x04, 0x24, 0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00,
+0x21, 0x18, 0x00, 0x00, 0x60, 0x15, 0x00, 0x08, 0xFC, 0x23, 0xA2, 0xAC,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x20, 0xEC, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0xC6, 0x5C, 0x43, 0xA0, 0x60, 0x1B, 0xA3, 0x26,
+0x06, 0x00, 0x02, 0x24, 0xB8, 0x15, 0x00, 0x08, 0xB6, 0x40, 0x62, 0xA0,
+0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x00, 0x10, 0x42, 0x34, 0x1E, 0x16, 0x00, 0x08, 0xFC, 0x23, 0x02, 0xAE,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x02, 0x26,
+0x14, 0x00, 0xBF, 0xAF, 0xB0, 0x1B, 0x43, 0x94, 0x21, 0x28, 0x00, 0x00,
+0x00, 0x01, 0x62, 0x30, 0x03, 0x00, 0x40, 0x10, 0x01, 0x00, 0x64, 0x30,
+0x06, 0x00, 0x80, 0x14, 0x00, 0x10, 0x62, 0x30, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0xA0, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x08, 0x00, 0x40, 0x14, 0x60, 0x1B, 0x04, 0x26,
+0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24,
+0x0F, 0x00, 0x63, 0x30, 0x09, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x00,
+0x60, 0x1B, 0x04, 0x26, 0x60, 0xEA, 0x03, 0x34, 0x04, 0x3A, 0x83, 0xAC,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0xA0, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x0E, 0x51, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x04, 0x26, 0x60, 0xEA, 0x03, 0x34,
+0xDB, 0x16, 0x00, 0x08, 0x04, 0x3A, 0x83, 0xAC, 0xD8, 0xFF, 0xBD, 0x27,
+0x1C, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C, 0x18, 0x00, 0xB0, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x60, 0x1B, 0x30, 0x26, 0x04, 0x3E, 0x02, 0x8E,
+0x00, 0x10, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x12, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x33, 0x3E, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x63, 0x24, 0xFF, 0x00, 0x62, 0x30, 0x21, 0x10, 0x50, 0x00,
+0xD0, 0x3D, 0x45, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xA4, 0x30,
+0x18, 0x00, 0x80, 0x10, 0x33, 0x3E, 0x03, 0xA2, 0xFF, 0x3D, 0x02, 0x92,
+0xC4, 0x3D, 0x05, 0xA2, 0x75, 0x0D, 0x00, 0x0C, 0xC5, 0x3D, 0x02, 0xA2,
+0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24,
+0x08, 0x3E, 0x03, 0x8E, 0x01, 0x00, 0x02, 0x24, 0x52, 0x00, 0x62, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x25, 0x26, 0x04, 0x3E, 0xA4, 0x8C,
+0x00, 0x10, 0x02, 0x3C, 0x3C, 0x00, 0x03, 0x24, 0x26, 0x20, 0x82, 0x00,
+0x94, 0x39, 0xA3, 0xAC, 0x04, 0x3E, 0xA4, 0xAC, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0xEF, 0x42, 0x30, 0x00, 0x01, 0x43, 0x30, 0x49, 0x00, 0x60, 0x14,
+0xB0, 0x1B, 0x02, 0xA6, 0x31, 0x3E, 0x06, 0x92, 0x37, 0x3E, 0x03, 0x92,
+0x32, 0x3E, 0x05, 0x92, 0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0xC4, 0x30, 0xC5, 0x3D, 0x05, 0xA2,
+0x75, 0x0D, 0x00, 0x0C, 0xC4, 0x3D, 0x06, 0xA2, 0xC4, 0x3D, 0x04, 0x92,
+0x38, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0xB0, 0x1B, 0x03, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, 0x09, 0x00, 0x40, 0x10,
+0x01, 0x00, 0x62, 0x30, 0x08, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x30, 0x26,
+0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24,
+0x0F, 0x00, 0x63, 0x30, 0x58, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x30, 0x26, 0x34, 0x3E, 0x04, 0x96, 0x36, 0x3E, 0x05, 0x92,
+0x95, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x11, 0x48, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C,
+0x04, 0x3E, 0x00, 0xAE, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x42, 0x30, 0x2A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0xEC, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x60, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28,
+0x3A, 0x00, 0x40, 0x14, 0x04, 0x00, 0x04, 0x24, 0x02, 0x80, 0x03, 0x3C,
+0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x42, 0x24, 0x0E, 0x5E, 0x62, 0xA0, 0x72, 0x17, 0x00, 0x08,
+0x60, 0x1B, 0x30, 0x26, 0xC4, 0x3D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0x42, 0x2C, 0xAB, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x49, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x07, 0x17, 0x00, 0x08,
+0x60, 0x1B, 0x25, 0x26, 0x25, 0xB0, 0x05, 0x3C, 0x48, 0x00, 0xA5, 0x34,
+0x00, 0x00, 0xA3, 0x8C, 0x60, 0x1B, 0x24, 0x8E, 0x84, 0x00, 0x02, 0x3C,
+0x25, 0x18, 0x62, 0x00, 0x25, 0x00, 0x84, 0x34, 0x00, 0x00, 0xA3, 0xAC,
+0x18, 0x17, 0x00, 0x08, 0x60, 0x1B, 0x24, 0xAE, 0x02, 0x80, 0x02, 0x3C,
+0x0E, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90,
+0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C, 0xFF, 0x00, 0x84, 0x30,
+0x60, 0x1B, 0x30, 0x26, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x52, 0x41, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x96, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x2C, 0x59, 0x84, 0x24,
+0xA0, 0xDD, 0xA5, 0x24, 0x34, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x4B, 0x41, 0x00, 0xA2, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x0D, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x2E, 0x00, 0x0C,
+0x01, 0x00, 0x05, 0x24, 0x4D, 0x17, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C,
+0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x33, 0x17, 0x00, 0x08,
+0x60, 0x1B, 0x30, 0x26, 0x02, 0x80, 0x09, 0x3C, 0x60, 0x1B, 0x28, 0x25,
+0x6C, 0x37, 0x06, 0x8D, 0xFF, 0xFF, 0x02, 0x34, 0x44, 0x00, 0xC2, 0x10,
+0x21, 0x38, 0x80, 0x00, 0x2B, 0x10, 0xC7, 0x00, 0x34, 0x00, 0x40, 0x10,
+0x02, 0x19, 0x06, 0x00, 0x21, 0x10, 0xC7, 0x00, 0x23, 0x10, 0x43, 0x00,
+0x10, 0x00, 0x46, 0x24, 0x6C, 0x37, 0x06, 0xAD, 0x70, 0x37, 0x02, 0xAD,
+0x60, 0x1B, 0x26, 0x25, 0x05, 0x00, 0xC4, 0x90, 0xFF, 0xFF, 0x02, 0x34,
+0xFF, 0x00, 0x83, 0x30, 0x33, 0x00, 0x62, 0x10, 0x00, 0x11, 0x07, 0x00,
+0xFF, 0x00, 0x84, 0x30, 0x2B, 0x10, 0x87, 0x00, 0x20, 0x00, 0x40, 0x10,
+0x03, 0x19, 0x04, 0x00, 0x03, 0x11, 0x04, 0x00, 0x21, 0x18, 0x87, 0x00,
+0x23, 0x18, 0x62, 0x00, 0x10, 0x00, 0x64, 0x24, 0x05, 0x00, 0xC4, 0xA0,
+0x70, 0x37, 0xC3, 0xAC, 0xC0, 0x10, 0x05, 0x00, 0x21, 0x10, 0x45, 0x00,
+0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x45, 0x00, 0x60, 0x1B, 0x23, 0x25,
+0x80, 0x10, 0x02, 0x00, 0x21, 0x28, 0x43, 0x00, 0xF8, 0x24, 0xA6, 0x8C,
+0x00, 0x21, 0x07, 0x00, 0xFF, 0xFF, 0xC2, 0x38, 0x0A, 0x30, 0x82, 0x00,
+0x2B, 0x18, 0xC7, 0x00, 0x07, 0x00, 0x60, 0x10, 0x21, 0x10, 0xC7, 0x00,
+0x02, 0x19, 0x06, 0x00, 0x23, 0x10, 0x43, 0x00, 0x10, 0x00, 0x46, 0x24,
+0xF8, 0x24, 0xA6, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xFC, 0x24, 0xA2, 0xAC,
+0x02, 0x19, 0x06, 0x00, 0x23, 0x10, 0x43, 0x00, 0xF8, 0x24, 0xA2, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xFC, 0x24, 0xA2, 0xAC, 0x21, 0x10, 0x87, 0x00,
+0x23, 0x10, 0x43, 0x00, 0x05, 0x00, 0xC2, 0xA0, 0xAB, 0x17, 0x00, 0x08,
+0x70, 0x37, 0xC2, 0xAC, 0x21, 0x10, 0xC7, 0x00, 0x23, 0x10, 0x43, 0x00,
+0x6C, 0x37, 0x02, 0xAD, 0x70, 0x37, 0x02, 0xAD, 0x60, 0x1B, 0x26, 0x25,
+0x05, 0x00, 0xC4, 0x90, 0xFF, 0xFF, 0x02, 0x34, 0xFF, 0x00, 0x83, 0x30,
+0xCF, 0xFF, 0x62, 0x14, 0x00, 0x11, 0x07, 0x00, 0x21, 0x20, 0x40, 0x00,
+0xA1, 0x17, 0x00, 0x08, 0x05, 0x00, 0xC2, 0xA0, 0x00, 0x31, 0x04, 0x00,
+0x93, 0x17, 0x00, 0x08, 0x6C, 0x37, 0x06, 0xAD, 0x63, 0x00, 0x82, 0x24,
+0x77, 0x00, 0x42, 0x2C, 0x00, 0x00, 0x85, 0x28, 0x04, 0x00, 0x40, 0x10,
+0x21, 0x18, 0x00, 0x00, 0x64, 0x00, 0x82, 0x24, 0x64, 0x00, 0x03, 0x24,
+0x0B, 0x18, 0x45, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x0C, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28,
+0x08, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0xA4, 0x8C,
+0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x3F, 0x00, 0x84, 0x30,
+0x40, 0x20, 0x04, 0x00, 0xD9, 0x17, 0x00, 0x08, 0x96, 0xFF, 0x84, 0x24,
+0x24, 0x08, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x63, 0x30, 0x1B, 0x00, 0x60, 0x14, 0x01, 0x00, 0x02, 0x24,
+0x05, 0x00, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x82, 0x31, 0x03, 0x00,
+0x3C, 0x00, 0xC2, 0x10, 0x02, 0x00, 0xC2, 0x28, 0x57, 0x00, 0x40, 0x14,
+0x02, 0x00, 0x02, 0x24, 0x46, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24,
+0x2E, 0x00, 0xC2, 0x10, 0x3E, 0x00, 0x63, 0x30, 0xD9, 0x17, 0x00, 0x0C,
+0x21, 0x20, 0xE0, 0x00, 0x06, 0x00, 0x45, 0x24, 0x65, 0x00, 0xA4, 0x2C,
+0x64, 0x00, 0x03, 0x24, 0x0A, 0x28, 0x64, 0x00, 0xDD, 0xFF, 0xA2, 0x24,
+0x08, 0x00, 0x42, 0x2C, 0x1F, 0x00, 0x40, 0x10, 0xE5, 0xFF, 0xA2, 0x24,
+0xFE, 0xFF, 0xA5, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0xA0, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x05, 0x00, 0xA3, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x66, 0x30, 0x42, 0x31, 0x06, 0x00,
+0x25, 0x00, 0xC2, 0x10, 0x02, 0x00, 0xC2, 0x28, 0x36, 0x00, 0x40, 0x14,
+0x02, 0x00, 0x02, 0x24, 0x2F, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24,
+0xE6, 0xFF, 0xC2, 0x14, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00,
+0xD8, 0xFF, 0x03, 0x24, 0x23, 0x38, 0x62, 0x00, 0xD9, 0x17, 0x00, 0x0C,
+0x21, 0x20, 0xE0, 0x00, 0x06, 0x00, 0x45, 0x24, 0x65, 0x00, 0xA4, 0x2C,
+0x64, 0x00, 0x03, 0x24, 0x0A, 0x28, 0x64, 0x00, 0xDD, 0xFF, 0xA2, 0x24,
+0x08, 0x00, 0x42, 0x2C, 0xE3, 0xFF, 0x40, 0x14, 0xE5, 0xFF, 0xA2, 0x24,
+0x08, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x10, 0xF1, 0xFF, 0xA2, 0x24,
+0x0E, 0x18, 0x00, 0x08, 0xFA, 0xFF, 0xA5, 0x24, 0xD8, 0xFF, 0x02, 0x24,
+0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x0C, 0x00, 0x42, 0x2C,
+0x0C, 0x00, 0x40, 0x10, 0xFB, 0xFF, 0xA2, 0x24, 0x0E, 0x18, 0x00, 0x08,
+0xF8, 0xFF, 0xA5, 0x24, 0x3E, 0x00, 0x63, 0x30, 0xFE, 0xFF, 0x02, 0x24,
+0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x1F, 0x00, 0x62, 0x30,
+0x40, 0x10, 0x02, 0x00, 0xFE, 0xFF, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08,
+0x23, 0x38, 0x62, 0x00, 0x0A, 0x00, 0x42, 0x2C, 0xCB, 0xFF, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x00, 0x08, 0xFC, 0xFF, 0xA5, 0x24,
+0x3E, 0x00, 0x63, 0x30, 0xEC, 0xFF, 0x02, 0x24, 0x03, 0x18, 0x00, 0x08,
+0x23, 0x38, 0x43, 0x00, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00,
+0xEC, 0xFF, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08, 0x23, 0x38, 0x62, 0x00,
+0xB3, 0xFF, 0xC0, 0x14, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00,
+0x0E, 0x00, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08, 0x23, 0x38, 0x62, 0x00,
+0xAD, 0xFF, 0xC0, 0x14, 0x3E, 0x00, 0x63, 0x30, 0x0E, 0x00, 0x02, 0x24,
+0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x98, 0xFF, 0xBD, 0x27,
+0x64, 0x00, 0xBF, 0xAF, 0x60, 0x00, 0xBE, 0xAF, 0x5C, 0x00, 0xB7, 0xAF,
+0x58, 0x00, 0xB6, 0xAF, 0x54, 0x00, 0xB5, 0xAF, 0x50, 0x00, 0xB4, 0xAF,
+0x4C, 0x00, 0xB3, 0xAF, 0x48, 0x00, 0xB2, 0xAF, 0x44, 0x00, 0xB1, 0xAF,
+0x40, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x88, 0x54, 0x45, 0x8C,
+0x00, 0x80, 0x04, 0x3C, 0x68, 0x61, 0x83, 0x24, 0x88, 0x54, 0x44, 0x24,
+0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x81, 0x00, 0xA4, 0x10, 0x02, 0x80, 0x02, 0x3C, 0xE8, 0xEC, 0x42, 0x24,
+0x00, 0x00, 0x5E, 0x8C, 0x02, 0x80, 0x03, 0x3C, 0xEC, 0xEC, 0x63, 0x24,
+0x00, 0x00, 0x75, 0x8C, 0x28, 0x39, 0xD6, 0x8F, 0x21, 0xB8, 0x00, 0x00,
+0x08, 0x00, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE,
+0x08, 0x00, 0xC3, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x9E, 0x18, 0x00, 0x08,
+0x25, 0xA0, 0x62, 0x00, 0x17, 0x00, 0x25, 0x92, 0x16, 0x00, 0x26, 0x92,
+0xC8, 0x3D, 0xC2, 0x97, 0xFF, 0x00, 0xA3, 0x30, 0x00, 0x1A, 0x03, 0x00,
+0xFF, 0x00, 0xC4, 0x30, 0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0x10,
+0xFF, 0x00, 0xA2, 0x30, 0xFF, 0x00, 0xC3, 0x30, 0x00, 0x12, 0x02, 0x00,
+0x25, 0x10, 0x43, 0x00, 0xC8, 0x3D, 0xC2, 0xA7, 0x01, 0x00, 0x24, 0x92,
+0x18, 0x00, 0x42, 0x92, 0x00, 0x22, 0x04, 0x00, 0xA8, 0x0D, 0x00, 0x0C,
+0x25, 0x20, 0x82, 0x00, 0x40, 0x18, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x98, 0xDE, 0x82, 0x24, 0x80, 0x18, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x08, 0x00, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x09, 0xF8, 0x40, 0x00, 0x21, 0x20, 0x60, 0x02, 0x0C, 0x00, 0xC2, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0xE2, 0x02, 0x41, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x8E, 0x02, 0x80, 0x03, 0x3C,
+0x48, 0x37, 0x64, 0x24, 0x42, 0x1B, 0x02, 0x00, 0x78, 0x00, 0x63, 0x30,
+0x02, 0x2E, 0x02, 0x00, 0xFF, 0x3F, 0x42, 0x30, 0x21, 0x10, 0x43, 0x00,
+0x03, 0x00, 0xA5, 0x30, 0x21, 0x10, 0x45, 0x00, 0x18, 0x00, 0x42, 0x24,
+0xFF, 0xFF, 0x50, 0x30, 0x7F, 0x00, 0x02, 0x32, 0x21, 0x98, 0x80, 0x02,
+0x06, 0x00, 0x06, 0x24, 0x80, 0x00, 0x03, 0x26, 0x00, 0x00, 0xB0, 0xAE,
+0x02, 0x00, 0x40, 0x10, 0x80, 0xFF, 0x05, 0x32, 0x80, 0xFF, 0x65, 0x30,
+0x00, 0x00, 0xA5, 0xAE, 0x02, 0x00, 0x62, 0x96, 0x21, 0x18, 0xE5, 0x02,
+0xFF, 0xFF, 0x77, 0x30, 0x0F, 0x00, 0x42, 0x30, 0x00, 0x00, 0xA2, 0xAE,
+0x00, 0x00, 0x63, 0x8E, 0x21, 0xA0, 0x85, 0x02, 0x42, 0x13, 0x03, 0x00,
+0x78, 0x00, 0x42, 0x30, 0x02, 0x1E, 0x03, 0x00, 0x03, 0x00, 0x63, 0x30,
+0x21, 0x10, 0x53, 0x00, 0x21, 0x90, 0x43, 0x00, 0x1C, 0x00, 0x50, 0x26,
+0x18, 0x00, 0x51, 0x26, 0x21, 0x28, 0x00, 0x02, 0x00, 0x00, 0xB1, 0xAE,
+0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x21, 0x28, 0x00, 0x02, 0x06, 0x00, 0x06, 0x24, 0x0B, 0x00, 0x40, 0x14,
+0x90, 0xDE, 0x64, 0x24, 0x01, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x02, 0x00, 0x00, 0x08, 0x42, 0x30, 0xAD, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x26, 0x92, 0x17, 0x00, 0x25, 0x92,
+0x86, 0x18, 0x00, 0x08, 0xFF, 0x00, 0xA2, 0x30, 0x1D, 0x55, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0xE2, 0x02,
+0xC1, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C,
+0x38, 0x00, 0xA4, 0x27, 0x04, 0x00, 0xC3, 0x8E, 0x00, 0x00, 0xC2, 0x8E,
+0x21, 0x20, 0xC0, 0x02, 0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC,
+0x00, 0x00, 0xD6, 0xAE, 0x74, 0x21, 0x00, 0x0C, 0x04, 0x00, 0xD6, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x38, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x88, 0x54, 0x43, 0x8C, 0x88, 0x54, 0x42, 0x24, 0x86, 0xFF, 0x62, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xE8, 0xEC, 0x63, 0x24,
+0x00, 0x00, 0x71, 0x8C, 0x25, 0xB0, 0x10, 0x3C, 0x04, 0x01, 0x02, 0x36,
+0x00, 0x00, 0x43, 0x8C, 0xDC, 0x38, 0x27, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x77, 0x00, 0xE3, 0x10, 0xE0, 0x38, 0x23, 0xAE, 0x2B, 0x10, 0x67, 0x00,
+0x81, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xE3, 0x00, 0xA9, 0x00, 0x40, 0x14,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0xB0, 0x38, 0x83, 0x94,
+0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x00, 0x00, 0x34, 0x00, 0xE0, 0x1A,
+0x25, 0x90, 0x62, 0x00, 0x21, 0x88, 0x80, 0x00, 0x21, 0x18, 0x00, 0x00,
+0x01, 0x00, 0x14, 0x24, 0x00, 0xC0, 0x15, 0x3C, 0x0E, 0x19, 0x00, 0x08,
+0x03, 0x00, 0x1E, 0x24, 0x80, 0x18, 0x10, 0x00, 0x2A, 0x10, 0x77, 0x00,
+0x2A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x98, 0x72, 0x00,
+0x00, 0x00, 0x62, 0x8E, 0x44, 0x41, 0x23, 0x8E, 0x38, 0x00, 0xA4, 0x27,
+0xFF, 0x3F, 0x42, 0x30, 0x21, 0x18, 0x62, 0x00, 0x8A, 0x40, 0x00, 0x0C,
+0x44, 0x41, 0x23, 0xAE, 0xE8, 0x1E, 0x22, 0x8E, 0xF0, 0x1E, 0x23, 0x8E,
+0x38, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x42, 0x24, 0x01, 0x00, 0x63, 0x24,
+0xE8, 0x1E, 0x22, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0xF0, 0x1E, 0x23, 0xAE,
+0xEC, 0x2C, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x00, 0x00, 0x63, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x14, 0x06, 0x00, 0x02, 0x26,
+0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x82, 0x16, 0x03, 0x00,
+0x01, 0x00, 0x42, 0x30, 0xE1, 0xFF, 0x54, 0x14, 0x02, 0x80, 0x04, 0x3C,
+0x60, 0x1B, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x42, 0x11, 0x02, 0x00,
+0x01, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x54, 0x10, 0xC2, 0x13, 0x03, 0x00,
+0x1E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00, 0xFF, 0xFF, 0x50, 0x30,
+0x80, 0x18, 0x10, 0x00, 0x2A, 0x10, 0x77, 0x00, 0xD8, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xC0, 0x02,
+0x75, 0x19, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x22, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x03, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0x11, 0x00, 0x40, 0x14, 0x02, 0x17, 0x03, 0x00,
+0x03, 0x00, 0x44, 0x30, 0x07, 0x00, 0x80, 0x10, 0x24, 0x10, 0x75, 0x00,
+0x0C, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x9E, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x28, 0x10, 0x00, 0x21, 0x28, 0xB2, 0x00, 0xE3, 0x17, 0x00, 0x0C,
+0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x40, 0x00, 0x8D, 0x17, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x7B, 0x00, 0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x23, 0x92,
+0x02, 0x00, 0x02, 0x24, 0x63, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x63, 0x30, 0x08, 0x00, 0x74, 0x10,
+0xD0, 0x02, 0x02, 0x24, 0x00, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0xC2, 0x13, 0x03, 0x00, 0x1E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00,
+0x33, 0x19, 0x00, 0x08, 0xFF, 0xFF, 0x50, 0x30, 0x6C, 0x37, 0x22, 0xAE,
+0x00, 0x00, 0x63, 0x8E, 0x67, 0x19, 0x00, 0x08, 0xC2, 0x13, 0x03, 0x00,
+0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x47, 0xAC, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x42, 0x24, 0xDC, 0x38, 0x47, 0xAC, 0x02, 0x80, 0x03, 0x3C,
+0x08, 0x04, 0x64, 0x24, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00,
+0x76, 0x39, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00, 0x66, 0x18, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0xE4, 0x38, 0x22, 0x8E, 0xFF, 0xFF, 0x73, 0x30,
+0x23, 0x10, 0x47, 0x00, 0xFF, 0xFF, 0x52, 0x30, 0x21, 0x18, 0x53, 0x02,
+0xFF, 0xFF, 0x77, 0x30, 0x53, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02,
+0xEF, 0xFF, 0x40, 0x10, 0x21, 0xB0, 0x40, 0x00, 0x08, 0x00, 0x42, 0x8C,
+0xDC, 0x38, 0x26, 0x8E, 0x21, 0x38, 0x40, 0x02, 0x21, 0x18, 0x57, 0x00,
+0xAC, 0x38, 0x23, 0xAE, 0x21, 0x28, 0x40, 0x00, 0x08, 0x00, 0x04, 0x24,
+0xB0, 0x38, 0x22, 0xAE, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF,
+0x5B, 0x01, 0x00, 0x0C, 0x08, 0x00, 0x04, 0x24, 0xB0, 0x38, 0x25, 0x8E,
+0x24, 0x10, 0x02, 0x3C, 0x00, 0x01, 0x10, 0x36, 0x00, 0x00, 0x02, 0xAE,
+0x21, 0x38, 0x60, 0x02, 0x21, 0x28, 0xB2, 0x00, 0x08, 0x00, 0x04, 0x24,
+0x24, 0x10, 0x06, 0x3C, 0xDC, 0x38, 0x22, 0xAE, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0xE0, 0x38, 0x23, 0x8E, 0x08, 0x00, 0x04, 0x24,
+0x5B, 0x01, 0x00, 0x0C, 0xDC, 0x38, 0x23, 0xAE, 0xDC, 0x38, 0x22, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAE, 0xFE, 0x18, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0x23, 0x10, 0x67, 0x00, 0xFF, 0xFF, 0x57, 0x30,
+0x53, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, 0x44, 0x00, 0x40, 0x10,
+0x21, 0xB0, 0x40, 0x00, 0x08, 0x00, 0x42, 0x8C, 0xDC, 0x38, 0x26, 0x8E,
+0x08, 0x00, 0x04, 0x24, 0x21, 0x18, 0x57, 0x00, 0xAC, 0x38, 0x23, 0xAE,
+0x21, 0x28, 0x40, 0x00, 0x21, 0x38, 0xE0, 0x02, 0xB0, 0x38, 0x22, 0xAE,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0xE0, 0x38, 0x23, 0x8E,
+0x08, 0x00, 0x04, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0xDC, 0x38, 0x23, 0xAE,
+0xDC, 0x38, 0x23, 0x8E, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x43, 0xAC,
+0xFE, 0x18, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x63, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x03, 0x00, 0x0F, 0x00, 0x42, 0x30,
+0x08, 0x00, 0x42, 0x28, 0x99, 0xFF, 0x40, 0x10, 0x25, 0xB0, 0x02, 0x3C,
+0x02, 0x17, 0x03, 0x00, 0x03, 0x00, 0x42, 0x30, 0x94, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x10, 0x00, 0x21, 0x28, 0xB2, 0x00,
+0xE3, 0x17, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x40, 0x00,
+0x8D, 0x17, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x5E, 0x19, 0x00, 0x08,
+0x25, 0xB0, 0x02, 0x3C, 0x04, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x14, 0x03, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x08, 0x00, 0x42, 0x28,
+0x06, 0x00, 0x40, 0x10, 0x24, 0x10, 0x75, 0x00, 0x02, 0x17, 0x03, 0x00,
+0x03, 0x00, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10, 0x80, 0x28, 0x10, 0x00,
+0x24, 0x10, 0x75, 0x00, 0x79, 0xFF, 0x40, 0x14, 0x02, 0x17, 0x03, 0x00,
+0x03, 0x00, 0x42, 0x30, 0x76, 0xFF, 0x5E, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x74, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x10, 0x00,
+0x21, 0x28, 0xB2, 0x00, 0xE3, 0x17, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02,
+0x21, 0x20, 0x40, 0x00, 0x8D, 0x17, 0x00, 0x0C, 0x05, 0x00, 0x05, 0x24,
+0x59, 0x19, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x23, 0x8E,
+0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x43, 0xAC, 0x74, 0x19, 0x00, 0x08,
+0xDC, 0x38, 0x23, 0xAE, 0xB8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C,
+0x44, 0x00, 0xBF, 0xAF, 0x40, 0x00, 0xBE, 0xAF, 0x3C, 0x00, 0xB7, 0xAF,
+0x38, 0x00, 0xB6, 0xAF, 0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF,
+0x2C, 0x00, 0xB3, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xB1, 0xAF,
+0x20, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x0E, 0x00, 0x40, 0x04, 0x1C, 0x00, 0xA0, 0xAF, 0x21, 0x20, 0x60, 0x00,
+0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30,
+0x64, 0x00, 0x43, 0x2C, 0xFD, 0xFF, 0x60, 0x14, 0x01, 0x00, 0x42, 0x24,
+0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00,
+0x03, 0x16, 0x02, 0x00, 0xF6, 0xFF, 0x41, 0x04, 0x21, 0x10, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C, 0x00, 0x80, 0x06, 0x3C,
+0xD0, 0x67, 0xC2, 0x24, 0x25, 0xB0, 0x05, 0x3C, 0x02, 0x80, 0x06, 0x3C,
+0x18, 0x03, 0xA4, 0x34, 0x98, 0x54, 0xD1, 0x24, 0x00, 0x00, 0x82, 0xAC,
+0x4B, 0x00, 0x71, 0x10, 0x01, 0x00, 0x15, 0x24, 0x11, 0x11, 0x02, 0x3C,
+0x2A, 0xB0, 0x03, 0x3C, 0x22, 0x22, 0x57, 0x34, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0xB0, 0x80, 0x00, 0x06, 0x00, 0x7E, 0x34, 0x05, 0x00, 0x73, 0x34,
+0x60, 0x1B, 0x54, 0x24, 0x01, 0x00, 0x12, 0x24, 0x00, 0x00, 0xD7, 0xAE,
+0x05, 0x00, 0xA0, 0x12, 0x02, 0x80, 0x03, 0x3C, 0xEC, 0x5D, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x40, 0x14, 0x21, 0xA8, 0x00, 0x00,
+0x00, 0x00, 0xC2, 0x97, 0x38, 0x39, 0x90, 0x8E, 0x25, 0xB0, 0x03, 0x3C,
+0xB0, 0x03, 0x63, 0x34, 0x00, 0xFF, 0x42, 0x30, 0x00, 0x00, 0x70, 0xAC,
+0x0F, 0x00, 0x40, 0x18, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xF0, 0xEC, 0xC6, 0x24, 0xF4, 0xEC, 0x42, 0x24, 0x00, 0x00, 0xC5, 0x8C,
+0x00, 0x00, 0x44, 0x8C, 0x02, 0x80, 0x06, 0x3C, 0xF8, 0xEC, 0xC6, 0x24,
+0x00, 0x00, 0xC3, 0x8C, 0x00, 0x00, 0xA4, 0xAC, 0x00, 0x00, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x30, 0xFB, 0xFF, 0x40, 0x1C,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x62, 0x30, 0x60, 0x00, 0x40, 0x14, 0x08, 0x00, 0x62, 0x24,
+0xC2, 0x10, 0x03, 0x00, 0x08, 0x00, 0x05, 0x8E, 0xF8, 0x37, 0x86, 0x8E,
+0xC0, 0x10, 0x02, 0x00, 0x20, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x47, 0x30,
+0x01, 0x00, 0x04, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF,
+0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x02, 0x24,
+0x18, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x72, 0xA2, 0x00, 0x00, 0x62, 0xA2,
+0x8A, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8E,
+0x04, 0x00, 0x03, 0x8E, 0x21, 0x20, 0x00, 0x02, 0x00, 0x00, 0x62, 0xAC,
+0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE, 0x74, 0x21, 0x00, 0x0C,
+0x04, 0x00, 0x10, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x51, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0xEC, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x40, 0x14,
+0x1C, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x08, 0x44, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0x76, 0x39, 0x00, 0x0C,
+0x21, 0x38, 0x00, 0x00, 0x15, 0x1A, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x06, 0x3C,
+0xEE, 0x5D, 0xC2, 0x90, 0x01, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30,
+0x04, 0x00, 0x42, 0x28, 0x0F, 0x00, 0x40, 0x14, 0x1C, 0x00, 0xA3, 0xAF,
+0x02, 0x80, 0x06, 0x3C, 0xC6, 0x5C, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x42, 0x30, 0x12, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C,
+0x01, 0x00, 0x06, 0x24, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x2F, 0x1A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x24,
+0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x06, 0x3C,
+0xC6, 0x5C, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30,
+0xF0, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x2D, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x8A, 0x1A, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x06, 0x3C,
+0xED, 0x5D, 0xC4, 0x90, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C,
+0xFF, 0x00, 0x84, 0x30, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x73, 0x1A, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x4B, 0x1A, 0x00, 0x08,
+0xC2, 0x10, 0x02, 0x00, 0x10, 0x00, 0xE0, 0x18, 0x21, 0x18, 0x00, 0x00,
+0x00, 0x00, 0xC0, 0xAC, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x82, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x45, 0x10, 0x21, 0x18, 0x80, 0x00,
+0x01, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x48, 0x00,
+0x02, 0x00, 0x68, 0x24, 0x21, 0x10, 0x82, 0x00, 0x2B, 0x18, 0x07, 0x01,
+0xF5, 0xFF, 0x60, 0x14, 0x02, 0x00, 0x44, 0x24, 0x21, 0x18, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0x01, 0x00, 0x82, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x60, 0x00, 0x02, 0x80, 0x07, 0x3C, 0x60, 0x1B, 0xE5, 0x24,
+0xCE, 0x40, 0xA3, 0x90, 0xFF, 0x00, 0x84, 0x30, 0x80, 0x10, 0x04, 0x00,
+0x0C, 0x00, 0x60, 0x14, 0x21, 0x30, 0x45, 0x00, 0xC8, 0x00, 0x02, 0x24,
+0x20, 0x3A, 0xA2, 0xAC, 0x01, 0x00, 0x03, 0x24, 0x60, 0x1B, 0xE2, 0x24,
+0x04, 0x18, 0x83, 0x00, 0xF8, 0x40, 0xA4, 0xA0, 0xCE, 0x40, 0x44, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0xCE, 0x40, 0x43, 0xA0, 0x20, 0x3A, 0xA3, 0x8C, 0xC8, 0x00, 0x02, 0x24,
+0x23, 0x10, 0x43, 0x00, 0xD0, 0x40, 0xC2, 0xAC, 0x01, 0x00, 0x03, 0x24,
+0x60, 0x1B, 0xE2, 0x24, 0x04, 0x18, 0x83, 0x00, 0xCE, 0x40, 0x44, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0xCE, 0x40, 0x43, 0xA0, 0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF,
+0x02, 0x80, 0x11, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x18, 0x00, 0xBF, 0xAF,
+0x60, 0x1B, 0x25, 0x26, 0xF8, 0x40, 0xA6, 0x90, 0x01, 0x00, 0x02, 0x24,
+0x04, 0x10, 0xC2, 0x00, 0x06, 0x00, 0x40, 0x14, 0xC9, 0x00, 0x10, 0x24,
+0xC6, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x23, 0x00, 0x40, 0x14, 0x21, 0x20, 0xC5, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x46, 0x24, 0x21, 0x20, 0x00, 0x00, 0xD0, 0x40, 0xC5, 0x24,
+0x00, 0x00, 0xA2, 0x8C, 0x04, 0x00, 0xA5, 0x24, 0x05, 0x00, 0x40, 0x10,
+0x2B, 0x18, 0x50, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x80, 0x40, 0x00, 0xF8, 0x40, 0xC4, 0xA0, 0x01, 0x00, 0x84, 0x24,
+0x08, 0x00, 0x82, 0x2C, 0xF5, 0xFF, 0x40, 0x14, 0xC9, 0x00, 0x02, 0x24,
+0x21, 0x00, 0x02, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x45, 0x24,
+0x07, 0x00, 0x04, 0x24, 0xD0, 0x40, 0xA2, 0x8C, 0xFF, 0xFF, 0x84, 0x24,
+0x02, 0x00, 0x40, 0x10, 0x23, 0x18, 0x50, 0x00, 0xD0, 0x40, 0xA3, 0xAC,
+0xFA, 0xFF, 0x81, 0x04, 0x04, 0x00, 0xA5, 0x24, 0x60, 0x1B, 0x22, 0x26,
+0x20, 0x3A, 0x50, 0xAC, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xF0, 0x40, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24,
+0xFF, 0x00, 0x62, 0x30, 0x03, 0x00, 0x42, 0x2C, 0xD8, 0xFF, 0x40, 0x10,
+0xF0, 0x40, 0x83, 0xA0, 0x80, 0x18, 0x06, 0x00, 0x21, 0x18, 0x65, 0x00,
+0xC8, 0x00, 0x02, 0x24, 0x03, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00,
+0xD9, 0x12, 0x00, 0x0C, 0xD0, 0x40, 0x62, 0xAC, 0xF2, 0x1A, 0x00, 0x08,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x22, 0x26, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x20, 0x00, 0xBD, 0x27,
+0xCE, 0x40, 0x40, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x3A, 0x40, 0xAC,
+0xB8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x08, 0x3C, 0x02, 0x80, 0x0B, 0x3C,
+0x02, 0x80, 0x0C, 0x3C, 0x40, 0x00, 0xBF, 0xAF, 0x3C, 0x00, 0xB5, 0xAF,
+0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF,
+0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0xE4, 0xEE, 0x63, 0x25,
+0xE0, 0xEE, 0x02, 0x25, 0xE8, 0xEE, 0x84, 0x25, 0x01, 0x00, 0x45, 0x90,
+0x01, 0x00, 0x66, 0x90, 0x01, 0x00, 0x87, 0x90, 0xE0, 0xEE, 0x0F, 0x91,
+0x02, 0x00, 0x4A, 0x90, 0xE4, 0xEE, 0x6E, 0x91, 0x02, 0x00, 0x69, 0x90,
+0xE8, 0xEE, 0x8D, 0x91, 0x02, 0x00, 0x88, 0x90, 0x03, 0x00, 0x4B, 0x90,
+0x03, 0x00, 0x6C, 0x90, 0x03, 0x00, 0x82, 0x90, 0x00, 0x2A, 0x05, 0x00,
+0x00, 0x32, 0x06, 0x00, 0x00, 0x3A, 0x07, 0x00, 0x25, 0x28, 0xAF, 0x00,
+0x25, 0x30, 0xCE, 0x00, 0x25, 0x38, 0xED, 0x00, 0x00, 0x54, 0x0A, 0x00,
+0x00, 0x4C, 0x09, 0x00, 0x00, 0x44, 0x08, 0x00, 0x25, 0x50, 0x45, 0x01,
+0x25, 0x48, 0x26, 0x01, 0x25, 0x40, 0x07, 0x01, 0x00, 0x5E, 0x0B, 0x00,
+0x00, 0x66, 0x0C, 0x00, 0x00, 0x16, 0x02, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x25, 0x58, 0x6A, 0x01, 0x25, 0x60, 0x89, 0x01, 0x25, 0x10, 0x48, 0x00,
+0xB0, 0x55, 0x84, 0x24, 0x10, 0x00, 0xAB, 0xAF, 0x18, 0x00, 0xAC, 0xAF,
+0x18, 0x52, 0x00, 0x0C, 0x20, 0x00, 0xA2, 0xAF, 0x10, 0x00, 0x42, 0x30,
+0x29, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x13, 0x3C,
+0x60, 0x1B, 0x63, 0x26, 0xC0, 0x3A, 0x62, 0x8C, 0x0C, 0x00, 0x10, 0x24,
+0x2B, 0x10, 0x02, 0x02, 0x2C, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x24, 0x56, 0x51, 0x24, 0x2E, 0x56, 0x72, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x26, 0x56, 0x54, 0x24,
+0x7C, 0x1B, 0x00, 0x08, 0x32, 0x56, 0x75, 0x24, 0xDD, 0x00, 0x02, 0x24,
+0x21, 0x20, 0x14, 0x02, 0x2B, 0x00, 0x62, 0x10, 0x10, 0x00, 0xA5, 0x27,
+0x21, 0x10, 0x11, 0x02, 0x01, 0x00, 0x43, 0x90, 0x60, 0x1B, 0x64, 0x26,
+0xC0, 0x3A, 0x82, 0x8C, 0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24,
+0x2B, 0x10, 0x02, 0x02, 0x17, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0x11, 0x02, 0x00, 0x00, 0x43, 0x90, 0x30, 0x00, 0x02, 0x24,
+0x21, 0x20, 0x12, 0x02, 0x20, 0x00, 0xA5, 0x27, 0xED, 0xFF, 0x62, 0x14,
+0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xEE, 0xFF, 0x40, 0x14, 0x21, 0x10, 0x11, 0x02, 0x01, 0x00, 0x03, 0x24,
+0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F,
+0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F,
+0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x48, 0x00, 0xBD, 0x27, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB5, 0x8F,
+0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F,
+0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x21, 0x18, 0x00, 0x00,
+0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27,
+0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x15, 0x02,
+0x18, 0x00, 0xA5, 0x27, 0xD1, 0xFF, 0x40, 0x14, 0x04, 0x00, 0x06, 0x24,
+0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xFF, 0x40, 0x14,
+0x21, 0x10, 0x11, 0x02, 0x88, 0x1B, 0x00, 0x08, 0x01, 0x00, 0x03, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x65, 0x24, 0xB0, 0x1B, 0xA2, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0x08, 0x00, 0x40, 0x10,
+0x70, 0x17, 0x04, 0x24, 0xB6, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFB, 0xFF, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x02, 0x00, 0x42, 0x2C,
+0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x40, 0xA3, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x03, 0x00, 0x70, 0x17, 0x62, 0x28,
+0x04, 0x00, 0x40, 0x14, 0x70, 0x17, 0x04, 0x24, 0x21, 0x4E, 0x62, 0x28,
+0x20, 0x4E, 0x04, 0x24, 0x0B, 0x20, 0x62, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x80, 0x00, 0x21, 0x38, 0x80, 0x00, 0x08, 0x00, 0xC0, 0x10,
+0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0xFF, 0x06, 0x24, 0x00, 0x00, 0xA2, 0x8C,
+0xFF, 0xFF, 0x63, 0x24, 0x04, 0x00, 0xA5, 0x24, 0x00, 0x00, 0xE2, 0xAC,
+0xFB, 0xFF, 0x66, 0x14, 0x04, 0x00, 0xE7, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x80, 0x00, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x10, 0xF0, 0x00, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x00, 0xF3,
+0x18, 0x4A, 0x2D, 0xF7, 0x19, 0x4B, 0xF9, 0x63, 0x60, 0xDA, 0x00, 0x6A,
+0x0C, 0x62, 0x0B, 0xD1, 0x0A, 0xD0, 0x07, 0xD2, 0xC9, 0xF7, 0x1B, 0x6A,
+0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0x10, 0xF0, 0x00, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x10, 0xF3, 0x68, 0x41, 0x2D, 0xF7, 0x19, 0x4A, 0x40, 0xDB,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x66, 0xF7, 0x48, 0xAB, 0x01, 0x4A, 0x66, 0xF7, 0x48, 0xCB, 0x00, 0x1C,
+0x9B, 0x40, 0x00, 0x65, 0xC0, 0xF0, 0x46, 0x41, 0x40, 0xAA, 0x11, 0x5A,
+0x12, 0x61, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0xF0,
+0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xAB, 0xF5, 0x50, 0x9C, 0xCB, 0xF5,
+0x68, 0x9D, 0x6D, 0xEA, 0xAB, 0xF5, 0x50, 0xDC, 0x00, 0x6A, 0xCB, 0xF5,
+0x48, 0xDD, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x70, 0xF3, 0x60, 0x41,
+0xE0, 0x9B, 0x06, 0x27, 0x07, 0x92, 0xFF, 0xF7, 0x1F, 0x6C, 0x01, 0x4A,
+0x8C, 0xEA, 0x07, 0xD2, 0xFF, 0x6D, 0x01, 0x4D, 0xA0, 0x36, 0xC0, 0x30,
+0x4F, 0x40, 0xE3, 0xEA, 0x0D, 0x65, 0x80, 0xF0, 0x1E, 0x60, 0xFF, 0x6A,
+0x01, 0x4A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0xF0, 0xF0, 0x4F, 0x45,
+0x62, 0x67, 0x2A, 0x65, 0x00, 0xF3, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x34,
+0x80, 0x34, 0x47, 0x44, 0xEC, 0xEB, 0x11, 0x4A, 0x4A, 0xEB, 0x80, 0xF0,
+0x17, 0x60, 0x63, 0xEA, 0xA0, 0xF0, 0x04, 0x61, 0x01, 0xF6, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0x41, 0x45, 0x4A, 0xEB, 0xC0, 0xF0,
+0x04, 0x60, 0x63, 0xEA, 0x00, 0xF1, 0x09, 0x61, 0x02, 0xF0, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x34, 0x80, 0x34, 0x43, 0x44, 0x4A, 0xEB, 0x40, 0xF1,
+0x17, 0x60, 0x63, 0xEA, 0xC0, 0xF1, 0x18, 0x61, 0x8A, 0xEB, 0x00, 0xF3,
+0x12, 0x60, 0x63, 0xEC, 0x80, 0xF3, 0x08, 0x61, 0x04, 0xF0, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x6E, 0xEA, 0xE0, 0xF3, 0x12, 0x22,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B,
+0x60, 0xF3, 0x10, 0x4A, 0x60, 0xDA, 0x07, 0xD3, 0xC9, 0xF7, 0x1B, 0x68,
+0x0B, 0xE8, 0x00, 0x30, 0x00, 0x30, 0x10, 0xF0, 0x00, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x10, 0xF3, 0x68, 0x40, 0x2E, 0xF0, 0x19, 0x4A, 0x40, 0xDB,
+0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x00, 0x1C, 0x9B, 0x40,
+0xFF, 0x69, 0x63, 0xF3, 0x00, 0x48, 0x10, 0x10, 0xC9, 0xF7, 0x1B, 0x6D,
+0xAB, 0xED, 0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x40, 0x4D, 0x40, 0xA5,
+0x2C, 0xEA, 0x04, 0x5A, 0x0F, 0x60, 0x27, 0xF1, 0x90, 0x98, 0x00, 0x1C,
+0xF5, 0x09, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x8A, 0xF4, 0x10, 0x4C, 0x00, 0x1C, 0x6A, 0x58, 0x00, 0x65, 0xE6, 0x22,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xEB, 0xF5, 0x4E, 0xA3,
+0x0F, 0x6B, 0xFF, 0x6C, 0x6C, 0xEA, 0x02, 0x72, 0x0B, 0x61, 0x10, 0xF0,
+0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xEB, 0xF5, 0x4D, 0xA5, 0x8C, 0xEA,
+0x6C, 0xEA, 0x01, 0x72, 0x40, 0xF4, 0x00, 0x60, 0x00, 0x1C, 0x96, 0x40,
+0x00, 0x65, 0x00, 0x6D, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x02, 0xF0, 0x08, 0x4C, 0xC5, 0x67, 0x00, 0x1C, 0x76, 0x39, 0xE5, 0x67,
+0x19, 0x17, 0x07, 0x94, 0x0A, 0xF0, 0x00, 0x5C, 0xA5, 0x61, 0x00, 0x6A,
+0x40, 0xDB, 0x07, 0xD2, 0x01, 0x6A, 0x70, 0xF3, 0x64, 0x41, 0x4B, 0xEA,
+0x40, 0xDB, 0x9C, 0x17, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x0C, 0xF0, 0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4D, 0x4B, 0xEA, 0x62, 0x9D,
+0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x62, 0xDD, 0x82, 0x17,
+0xA0, 0xF0, 0x4C, 0x44, 0x4A, 0xEB, 0x00, 0xF4, 0x17, 0x60, 0x63, 0xEA,
+0x39, 0x61, 0xA0, 0xF0, 0x42, 0x44, 0x4A, 0xEB, 0x20, 0xF4, 0x0D, 0x60,
+0x63, 0xEA, 0xE0, 0xF0, 0x02, 0x61, 0x47, 0x44, 0x21, 0x4A, 0x4A, 0xEB,
+0x40, 0xF4, 0x11, 0x60, 0x63, 0xEA, 0xC0, 0xF1, 0x1D, 0x61, 0x47, 0x44,
+0x12, 0x4A, 0x6E, 0xEA, 0x7F, 0xF7, 0x06, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0x60, 0xF3, 0x10, 0x4A,
+0x60, 0xDA, 0x00, 0x18, 0x12, 0x27, 0x87, 0x67, 0x59, 0x17, 0x70, 0xF3,
+0x44, 0x41, 0xE0, 0x9A, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32,
+0xFF, 0x4A, 0x4C, 0xEF, 0xE3, 0xEE, 0x5F, 0xF7, 0x0D, 0x60, 0x0A, 0xF0,
+0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x4D, 0xEF, 0x70, 0xF3,
+0x48, 0x41, 0xC0, 0x9A, 0xC0, 0xDF, 0x42, 0x17, 0x00, 0xF2, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x36, 0xC0, 0x36, 0x47, 0x46, 0x0B, 0x4A, 0x4A, 0xEB,
+0xC0, 0xF3, 0x17, 0x60, 0x63, 0xEA, 0xC0, 0xF0, 0x01, 0x61, 0xA0, 0xF0,
+0x4F, 0x44, 0x4A, 0xEB, 0x20, 0xF4, 0x15, 0x60, 0x63, 0xEA, 0x60, 0xF1,
+0x18, 0x61, 0xA0, 0xF0, 0x4D, 0x44, 0x6E, 0xEA, 0x60, 0xF4, 0x09, 0x22,
+0xA0, 0xF0, 0x4E, 0x44, 0x6E, 0xEA, 0x3F, 0xF7, 0x03, 0x2A, 0x1F, 0xF7,
+0x00, 0x6A, 0xE2, 0x34, 0x4C, 0xEC, 0x4C, 0xEF, 0x82, 0x34, 0x00, 0x18,
+0x3B, 0x5D, 0xE2, 0x35, 0xC9, 0xF7, 0x1B, 0x6B, 0x6B, 0xEB, 0x60, 0x33,
+0x60, 0x33, 0x60, 0xF3, 0x14, 0x4B, 0x40, 0xC3, 0x11, 0x17, 0x01, 0xF0,
+0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0x47, 0x45, 0x0F, 0x4A,
+0x4A, 0xEB, 0xC0, 0xF3, 0x1A, 0x60, 0x63, 0xEA, 0xA0, 0xF0, 0x19, 0x61,
+0x01, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x4A, 0xEB,
+0x00, 0xF4, 0x06, 0x60, 0x63, 0xEA, 0xE0, 0xF1, 0x13, 0x61, 0x01, 0xF5,
+0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x6E, 0xEA, 0xFF, 0xF6,
+0x11, 0x2A, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x30, 0x01, 0xF7,
+0x00, 0x6B, 0xE2, 0x32, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x6C, 0xEA, 0x63, 0xF3, 0x00, 0x4D, 0x42, 0x36, 0x28, 0xF1, 0xDB, 0xC5,
+0x20, 0xF3, 0x06, 0x26, 0xA3, 0xF3, 0x50, 0xAD, 0x10, 0xF0, 0x00, 0x6B,
+0x6B, 0xEB, 0x10, 0xF0, 0x00, 0x6C, 0x6D, 0xEA, 0xA3, 0xF3, 0x50, 0xCD,
+0x1E, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x4C, 0xEF, 0xFF, 0x6A, 0x4C, 0xE8,
+0x00, 0xF5, 0xE2, 0x31, 0x4C, 0xEE, 0x00, 0x1C, 0x3C, 0x0E, 0xB0, 0x67,
+0x90, 0x67, 0x00, 0x1C, 0x38, 0x0D, 0xB1, 0x67, 0xC9, 0xF7, 0x1B, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF3, 0x10, 0x4A, 0x00, 0x6B,
+0x60, 0xDA, 0xBA, 0x16, 0x1F, 0xF7, 0x00, 0x6B, 0xE2, 0x32, 0x6C, 0xEA,
+0x42, 0x32, 0xEC, 0xEB, 0x06, 0xD2, 0x62, 0x37, 0x80, 0xF3, 0x08, 0x22,
+0x01, 0x72, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C, 0x00, 0x1C, 0xF0, 0x42,
+0x09, 0xD7, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x09, 0x97, 0x70, 0xF3, 0x24, 0x42, 0xC0, 0x99, 0x02, 0xF0, 0x00, 0x68,
+0x00, 0x30, 0x87, 0x67, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45, 0x09, 0xD7,
+0x09, 0x97, 0xAF, 0x40, 0x00, 0x1C, 0xAC, 0x45, 0x87, 0x67, 0x40, 0xD9,
+0x91, 0x16, 0xA0, 0xF0, 0x45, 0x44, 0x4A, 0xEB, 0x60, 0xF3, 0x06, 0x60,
+0x63, 0xEA, 0x00, 0xF1, 0x0D, 0x61, 0xA0, 0xF0, 0x43, 0x44, 0x6E, 0xEA,
+0x40, 0xF1, 0x02, 0x22, 0xA0, 0xF0, 0x44, 0x44, 0x6E, 0xEA, 0x7F, 0xF6,
+0x1F, 0x2A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0xFF, 0xF7, 0x1F, 0x6A, 0x27, 0xF1, 0x44, 0xDB, 0x74, 0x16,
+0x47, 0x46, 0x13, 0x4A, 0x4A, 0xEB, 0x80, 0xF0, 0x16, 0x60, 0x63, 0xEA,
+0x00, 0xF1, 0x1B, 0x61, 0x47, 0x46, 0x11, 0x4A, 0x6E, 0xEA, 0xE0, 0xF3,
+0x05, 0x22, 0x47, 0x46, 0x12, 0x4A, 0x6E, 0xEA, 0x7F, 0xF6, 0x02, 0x2A,
+0x00, 0x1C, 0x9B, 0x40, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B,
+0x40, 0x32, 0x23, 0xF4, 0x6A, 0xA3, 0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A,
+0x60, 0xDA, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x4B, 0x16, 0x47, 0x44,
+0x4A, 0xEB, 0x80, 0xF3, 0x03, 0x60, 0x63, 0xEA, 0x00, 0xF1, 0x0C, 0x61,
+0x47, 0x45, 0x10, 0x4A, 0x6E, 0xEA, 0xC0, 0xF3, 0x11, 0x22, 0x47, 0x45,
+0x11, 0x4A, 0x6E, 0xEA, 0x3F, 0xF6, 0x1A, 0x2A, 0x00, 0x1C, 0x2B, 0x20,
+0x00, 0x65, 0x36, 0x16, 0x01, 0xF7, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x36,
+0xC0, 0x36, 0x42, 0x46, 0x4A, 0xEB, 0x3F, 0xF6, 0x0D, 0x60, 0x63, 0xEA,
+0x80, 0xF1, 0x04, 0x61, 0x47, 0x44, 0x01, 0x4A, 0x6E, 0xEA, 0xE0, 0xF1,
+0x01, 0x22, 0x43, 0x67, 0xCE, 0xEA, 0x3F, 0xF6, 0x01, 0x2A, 0xFF, 0x6A,
+0x01, 0x4A, 0x40, 0x32, 0x40, 0x32, 0x80, 0x4A, 0x80, 0x4A, 0x4C, 0xEF,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xE2, 0x33, 0x63, 0xF3,
+0x00, 0x4C, 0xA3, 0xF3, 0x7A, 0xCC, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC,
+0x80, 0x34, 0x80, 0x34, 0x90, 0xF0, 0x44, 0x44, 0x60, 0xCA, 0x90, 0xF0,
+0xAA, 0x44, 0x00, 0xF4, 0x00, 0x6A, 0x40, 0xCD, 0x90, 0xF0, 0xA8, 0x44,
+0xA0, 0x6A, 0x40, 0xCD, 0xC9, 0xF7, 0x1A, 0x6D, 0xAB, 0xED, 0xA0, 0x35,
+0x04, 0x6E, 0x90, 0xF0, 0x46, 0x44, 0xA0, 0x35, 0xC0, 0xCA, 0x47, 0x45,
+0x73, 0x4A, 0xC0, 0xC2, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEB, 0x74, 0x33,
+0xC8, 0x43, 0xC8, 0x4E, 0xB0, 0xF3, 0x40, 0x44, 0xC0, 0xDA, 0x60, 0xF0,
+0xDC, 0xCD, 0x40, 0xF0, 0x64, 0xAC, 0x00, 0xF2, 0x01, 0x6A, 0x4B, 0xEA,
+0x6C, 0xEA, 0x40, 0xF0, 0x44, 0xCC, 0x40, 0xF0, 0x64, 0xAC, 0x00, 0xF2,
+0x00, 0x6A, 0x6D, 0xEA, 0x40, 0xF0, 0x44, 0xCC, 0xD9, 0x15, 0x0F, 0xF7,
+0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x37, 0x87, 0x67, 0xFF, 0xF7, 0x1F, 0x6D,
+0xAC, 0xEC, 0x01, 0x74, 0x06, 0xD4, 0xA0, 0xF0, 0x18, 0x60, 0x02, 0x54,
+0x20, 0xF3, 0x13, 0x61, 0x06, 0x92, 0x03, 0x72, 0xE0, 0xF1, 0x19, 0x60,
+0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B, 0x40, 0x32, 0x23, 0xF4, 0x64, 0xAB,
+0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A, 0x60, 0xDA, 0xB5, 0x15, 0x47, 0x46,
+0x09, 0x4A, 0x6E, 0xEA, 0xE0, 0xF2, 0x16, 0x22, 0x47, 0x46, 0x0A, 0x4A,
+0x6E, 0xEA, 0xBF, 0xF5, 0x0B, 0x2A, 0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x00, 0x6A, 0x63, 0xF3,
+0x00, 0x4B, 0x23, 0xF4, 0x4A, 0xC3, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32,
+0x40, 0x32, 0x09, 0x97, 0x80, 0x4A, 0x80, 0x4A, 0x4C, 0xEF, 0xE0, 0x34,
+0x82, 0x34, 0x00, 0x1C, 0xA3, 0x31, 0x82, 0x34, 0x00, 0x1C, 0x96, 0x40,
+0x00, 0x65, 0x8E, 0x15, 0xA0, 0xF0, 0x40, 0x44, 0x6E, 0xEA, 0x80, 0xF0,
+0x1B, 0x22, 0xA0, 0xF0, 0x41, 0x44, 0x6E, 0xEA, 0x9F, 0xF5, 0x04, 0x2A,
+0xE2, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC, 0x00, 0x18, 0x11, 0x22,
+0x82, 0x34, 0x7C, 0x15, 0xA0, 0xF0, 0x46, 0x44, 0x6E, 0xEA, 0xC0, 0xF2,
+0x1B, 0x22, 0xA0, 0xF0, 0x47, 0x44, 0x6E, 0xEA, 0x7F, 0xF5, 0x12, 0x2A,
+0x1F, 0xF7, 0x00, 0x6A, 0xE2, 0x33, 0x4C, 0xEF, 0xE2, 0x36, 0x4C, 0xEB,
+0x01, 0x76, 0x62, 0x35, 0xA0, 0xF1, 0x17, 0x61, 0xAC, 0x32, 0xA9, 0xE2,
+0x48, 0x32, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xA9, 0xE2,
+0xC9, 0xF7, 0x1B, 0x6B, 0x63, 0xF3, 0x00, 0x4C, 0x48, 0x32, 0x6B, 0xEB,
+0x89, 0xE2, 0x60, 0x33, 0x04, 0xF5, 0x40, 0x9A, 0x60, 0x33, 0x60, 0xF3,
+0x14, 0x4B, 0x40, 0xDB, 0x51, 0x15, 0x47, 0x45, 0x08, 0x4A, 0x6E, 0xEA,
+0x71, 0x22, 0x47, 0x45, 0x09, 0x4A, 0x6E, 0xEA, 0x5F, 0xF5, 0x08, 0x2A,
+0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0x4A, 0xEF, 0xDF, 0xF6, 0x03, 0x60,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x00, 0x6A, 0x27, 0xF1, 0x44, 0xDB, 0x38, 0x15, 0x47, 0x44, 0x0D, 0x4A,
+0x6E, 0xEA, 0x69, 0x22, 0x47, 0x44, 0x10, 0x4A, 0x6E, 0xEA, 0x3F, 0xF5,
+0x0F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34,
+0x60, 0xF3, 0xA8, 0x44, 0x60, 0x9D, 0xFF, 0xF7, 0x1F, 0x6A, 0x60, 0xF3,
+0x04, 0x4C, 0x4C, 0xEB, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0xE0, 0x32,
+0x6D, 0xEA, 0x40, 0xDD, 0x60, 0xA4, 0xFF, 0x6A, 0x6C, 0xEA, 0x40, 0x6B,
+0x6D, 0xEA, 0x40, 0xC4, 0x15, 0x15, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x23, 0xF4, 0x42, 0xAA, 0xFF, 0xF7,
+0x1F, 0x6D, 0x70, 0xF3, 0x64, 0x41, 0xAC, 0xEA, 0x40, 0xDB, 0x06, 0x15,
+0x01, 0x4A, 0x6E, 0xEA, 0xA0, 0xF0, 0x0D, 0x22, 0x47, 0x45, 0x0E, 0x4A,
+0x6E, 0xEA, 0xFF, 0xF4, 0x1D, 0x2A, 0x00, 0x1C, 0xAE, 0x1F, 0x00, 0x65,
+0xF9, 0x14, 0x0F, 0xF7, 0x40, 0x40, 0xEC, 0xEA, 0x42, 0x37, 0x2D, 0xE7,
+0xC0, 0x9B, 0x70, 0xF3, 0x44, 0x41, 0xC0, 0xDA, 0xC0, 0x9B, 0xEE, 0x14,
+0x01, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0xE2, 0x32, 0x01, 0x72, 0x01, 0x6C,
+0x07, 0x60, 0x02, 0x72, 0x02, 0x6C, 0x04, 0x60, 0x03, 0x72, 0x03, 0x6C,
+0x01, 0x60, 0x00, 0x6C, 0x00, 0x18, 0x92, 0x5D, 0x00, 0x65, 0xDC, 0x14,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1,
+0x16, 0x4A, 0xFF, 0x6B, 0x60, 0xCA, 0x01, 0x6A, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0xEB, 0xF4, 0x50, 0xC3, 0xCB, 0x14, 0x0F, 0xF7,
+0x40, 0x40, 0xEC, 0xEA, 0xDF, 0xF4, 0x06, 0x22, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x44, 0x9B,
+0xA9, 0x67, 0x88, 0x67, 0xAC, 0xEA, 0x8D, 0xEA, 0x00, 0xF3, 0x44, 0xDB,
+0x1F, 0xF7, 0x00, 0x6C, 0xE2, 0x32, 0x8C, 0xEA, 0x42, 0x32, 0x00, 0xF3,
+0x5C, 0xC3, 0x8C, 0xEF, 0xFB, 0x4A, 0x00, 0xF3, 0x5D, 0xC3, 0xE2, 0x32,
+0x00, 0xF3, 0x5E, 0xC3, 0xFB, 0x4A, 0x00, 0xF3, 0x5F, 0xC3, 0xA6, 0x14,
+0x44, 0x46, 0x6E, 0xEA, 0x6D, 0x22, 0x43, 0x67, 0xAE, 0xEA, 0x9F, 0xF4,
+0x1F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x33, 0x60, 0x33,
+0x70, 0xF3, 0x44, 0x43, 0xE0, 0x9A, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32,
+0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEF, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32,
+0xE3, 0xEA, 0x9F, 0xF4, 0x0B, 0x60, 0x0A, 0xF0, 0x00, 0x6A, 0x4B, 0xEA,
+0x40, 0x32, 0x40, 0x32, 0x4D, 0xEF, 0xC0, 0x9F, 0x70, 0xF3, 0x48, 0x43,
+0xC0, 0xDA, 0x80, 0x14, 0x41, 0x44, 0x6E, 0xEA, 0x5E, 0x22, 0x42, 0x44,
+0x6E, 0xEA, 0x7F, 0xF4, 0x19, 0x2A, 0x1F, 0xF7, 0x00, 0x6B, 0xE2, 0x32,
+0x6C, 0xEA, 0x42, 0x32, 0xEC, 0xEB, 0x06, 0xD2, 0x62, 0x37, 0x20, 0xF2,
+0x0C, 0x22, 0x01, 0x72, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C, 0x00, 0x1C,
+0xF0, 0x42, 0x09, 0xD7, 0x09, 0x97, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30,
+0xAF, 0x40, 0x00, 0x1C, 0xAC, 0x45, 0x87, 0x67, 0xFF, 0x48, 0x4C, 0xE8,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF3,
+0x14, 0x4A, 0x00, 0xDA, 0x55, 0x14, 0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B,
+0x40, 0x32, 0xC4, 0xF7, 0x7C, 0xAB, 0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A,
+0x60, 0xDA, 0x44, 0x14, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x37,
+0x87, 0x67, 0x04, 0x27, 0x01, 0x77, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C,
+0x00, 0x1C, 0xF0, 0x42, 0x00, 0x65, 0x36, 0x14, 0x1F, 0xF7, 0x00, 0x6B,
+0x47, 0x67, 0x6C, 0xEA, 0x42, 0x32, 0x06, 0xD2, 0xE2, 0x32, 0x6C, 0xEA,
+0x42, 0x36, 0x07, 0x5E, 0x3F, 0xF4, 0x0A, 0x60, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0xC8, 0x32, 0x1D, 0xF7, 0x14, 0x4B, 0x69, 0xE2,
+0x40, 0x9A, 0x00, 0xEA, 0x00, 0x65, 0x0F, 0xF7, 0x40, 0x40, 0xEC, 0xEA,
+0x42, 0x37, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x70, 0xF3, 0x64, 0x42, 0xC0, 0x9B, 0x49, 0xE7, 0xC0, 0xDA, 0xC0, 0x9A,
+0xC0, 0xDB, 0x0E, 0x14, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x32,
+0xFF, 0x72, 0x71, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x60, 0xF3, 0x04, 0x4A, 0x60, 0xAA, 0x88, 0x67, 0x6D, 0xEC,
+0x80, 0xCA, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x06, 0xF0,
+0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4C, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C,
+0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0xE0, 0xF2, 0x64, 0xDC,
+0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0x19, 0xF4, 0x00, 0x77, 0xFF, 0xF3,
+0x05, 0x61, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x06, 0xF0,
+0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4C, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C,
+0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x02, 0xF0, 0x00, 0x6A,
+0x40, 0x32, 0x40, 0x32, 0x4D, 0xEB, 0xE0, 0xF2, 0x64, 0xDC, 0xDF, 0xF3,
+0x0D, 0x10, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7,
+0x1B, 0x6A, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xEA, 0x23, 0xF4, 0x66, 0xAB,
+0x40, 0x32, 0x40, 0x32, 0xFF, 0xF7, 0x1F, 0x6C, 0x60, 0xF3, 0x14, 0x4A,
+0x8C, 0xEB, 0x60, 0xDA, 0xBF, 0xF3, 0x18, 0x10, 0xA3, 0xF3, 0x50, 0xAD,
+0xEF, 0xF7, 0x1F, 0x6B, 0x86, 0x67, 0x6C, 0xEA, 0xDB, 0x14, 0x02, 0x76,
+0x27, 0x61, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0xA9, 0xE2, 0xC9, 0xF7, 0x1B, 0x6B, 0x63, 0xF3,
+0x00, 0x4C, 0x48, 0x32, 0x6B, 0xEB, 0x89, 0xE2, 0x60, 0x33, 0x04, 0xF5,
+0x44, 0x9A, 0x60, 0x33, 0x60, 0xF3, 0x14, 0x4B, 0x40, 0xDB, 0x9F, 0xF3,
+0x17, 0x10, 0xAA, 0x2A, 0xC9, 0xF7, 0x1B, 0x6B, 0x6B, 0xEB, 0x60, 0x33,
+0x60, 0x33, 0x60, 0xF3, 0x04, 0x4B, 0x80, 0xAB, 0xFF, 0x6A, 0x02, 0x4A,
+0x4B, 0xEA, 0x8C, 0xEA, 0x40, 0xCB, 0x8B, 0x17, 0x03, 0x76, 0x9F, 0xF3,
+0x05, 0x61, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32, 0xA9, 0xE2, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0x48, 0x32,
+0x68, 0xF0, 0x08, 0x4B, 0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x40, 0x9A,
+0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x40, 0xDC, 0x7F, 0xF3, 0x0E, 0x10,
+0xEB, 0xF5, 0x4D, 0xA5, 0x01, 0x6D, 0x00, 0x1C, 0x4B, 0x2E, 0x4C, 0xEC,
+0xBF, 0xF3, 0x18, 0x10, 0x00, 0x18, 0x84, 0x5C, 0x87, 0x67, 0x7F, 0xF3,
+0x01, 0x10, 0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7, 0x09, 0x97, 0x0F, 0xF7,
+0x40, 0x40, 0xFF, 0xF7, 0x1F, 0x6D, 0x4C, 0xEF, 0xE2, 0x32, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xAC, 0xEA, 0x63, 0xF3, 0x00, 0x4B,
+0x23, 0xF4, 0x4B, 0xC3, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x5F, 0xF3,
+0x09, 0x10, 0x0F, 0xF7, 0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x37, 0x87, 0x67,
+0xFF, 0xF7, 0x1F, 0x6D, 0xAC, 0xEC, 0x06, 0xD4, 0x70, 0xF3, 0x04, 0x41,
+0xA0, 0x98, 0x00, 0x18, 0x63, 0x5E, 0x00, 0x65, 0xC0, 0x98, 0x06, 0x95,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x3D, 0xF7, 0x10, 0x4C,
+0x00, 0x1C, 0x13, 0x58, 0x00, 0x65, 0x3F, 0xF3, 0x0D, 0x10, 0x00, 0x1C,
+0xFA, 0x1F, 0x00, 0x65, 0x3F, 0xF3, 0x08, 0x10, 0x06, 0x94, 0x7A, 0x14,
+0xE2, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC, 0x00, 0x18, 0x8F, 0x5E,
+0x82, 0x34, 0x1F, 0xF3, 0x1D, 0x10, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30,
+0x60, 0x6E, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45, 0x24, 0x6C, 0xE0, 0xF3,
+0x08, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x00, 0x65, 0x00, 0x1C, 0x9B, 0x40,
+0x00, 0x65, 0x24, 0x6C, 0x00, 0x1C, 0xAC, 0x45, 0xAF, 0x40, 0x1F, 0x6E,
+0x4C, 0xEE, 0x00, 0x1C, 0x96, 0x40, 0x08, 0xD6, 0x00, 0x1C, 0x5B, 0x1F,
+0x64, 0x6C, 0x08, 0x96, 0x70, 0xF3, 0x44, 0x41, 0xC0, 0xC2, 0xFF, 0xF2,
+0x1B, 0x10, 0x00, 0x18, 0x75, 0x5D, 0x00, 0x65, 0xFF, 0xF2, 0x16, 0x10,
+0x0F, 0xF7, 0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x32, 0x01, 0x6B, 0xA2, 0x67,
+0x6C, 0xED, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x46, 0x36,
+0x6C, 0xEE, 0xDB, 0xF7, 0xA8, 0xDC, 0x4A, 0x37, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x4E, 0x32, 0x6C, 0xEA, 0x6C, 0xEF, 0xCB, 0xF4,
+0xD9, 0xC4, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0,
+0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xDB, 0xF7, 0xE4, 0xDC, 0x63, 0xF3,
+0x00, 0x4B, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xC7, 0xF5,
+0x47, 0xC3, 0x5D, 0xF7, 0x0C, 0x4C, 0x00, 0x1C, 0x13, 0x58, 0x04, 0xD2,
+0xDF, 0xF2, 0x04, 0x10, 0x00, 0x18, 0xED, 0x60, 0x87, 0x67, 0xBF, 0xF2,
+0x1F, 0x10, 0x00, 0x18, 0x92, 0x5C, 0x87, 0x67, 0xBF, 0xF2, 0x1A, 0x10,
+0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x23, 0xF4, 0x4A, 0xA3, 0x09, 0x97,
+0x5F, 0xF4, 0x1D, 0x2A, 0x01, 0x6A, 0x23, 0xF4, 0x4A, 0xC3, 0x0F, 0xF7,
+0x40, 0x40, 0x4C, 0xEF, 0xE0, 0x32, 0x42, 0x32, 0x42, 0x32, 0x23, 0xF4,
+0x4B, 0xC3, 0x82, 0x67, 0x00, 0x1C, 0xA3, 0x31, 0x06, 0xD2, 0x0A, 0x15,
+0x00, 0x18, 0x94, 0x5E, 0x00, 0x65, 0x9F, 0xF2, 0x17, 0x10, 0xDF, 0xF4,
+0x0F, 0x2C, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7,
+0x1B, 0x6A, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xEA, 0x23, 0xF4, 0x60, 0xAB,
+0x40, 0x32, 0x40, 0x32, 0xFF, 0xF7, 0x1F, 0x6C, 0x60, 0xF3, 0x14, 0x4A,
+0x8C, 0xEB, 0xC7, 0x16, 0x00, 0x1C, 0x9B, 0x40, 0x00, 0x65, 0xC9, 0xF7,
+0x1B, 0x6A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA,
+0x63, 0xF3, 0x00, 0x4B, 0x40, 0x32, 0x23, 0xF4, 0x6B, 0xA3, 0x40, 0x32,
+0x60, 0xF3, 0x14, 0x4A, 0x60, 0xDA, 0x1F, 0x14, 0x00, 0x1C, 0x5C, 0x20,
+0x00, 0x65, 0x7F, 0xF2, 0x09, 0x10, 0x06, 0x95, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0xB0, 0x32, 0x63, 0xF3,
+0x00, 0x4B, 0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x55, 0xA2,
+0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0xE5, 0x16, 0x06, 0x93, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3,
+0x54, 0xA2, 0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0xD2, 0x16, 0x06, 0x94,
+0xD6, 0x15, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x56, 0xAA, 0x80, 0x34, 0x60, 0xF3,
+0x14, 0x4C, 0xBD, 0x16, 0x06, 0x95, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0xB0, 0x32, 0x63, 0xF3, 0x00, 0x4B,
+0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x52, 0xAA, 0x80, 0x34,
+0x60, 0xF3, 0x14, 0x4C, 0xAA, 0x16, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C,
+0x8B, 0xEC, 0x70, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x50, 0xAA,
+0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x97, 0x16, 0x06, 0x95, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0xB0, 0x32,
+0xC9, 0xF7, 0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC, 0x20, 0xF3, 0x4C, 0x9A,
+0x80, 0x34, 0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x40, 0xF6, 0x42, 0x32,
+0x82, 0x16, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x69, 0xE2, 0x20, 0xF3, 0x4F, 0xA2, 0x80, 0x34, 0x80, 0x34, 0x01, 0x6B,
+0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x6D, 0x16, 0x00, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34, 0xB0, 0x7C, 0x63, 0x24,
+0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x05, 0x3C, 0xCC, 0x5D, 0xA5, 0x8C,
+0x04, 0x00, 0x02, 0x24, 0x1E, 0x00, 0xA2, 0x10, 0x05, 0x00, 0xA2, 0x2C,
+0x10, 0x00, 0x40, 0x10, 0x05, 0x00, 0x02, 0x24, 0x03, 0x00, 0x02, 0x24,
+0x08, 0x00, 0xA2, 0x10, 0x00, 0x19, 0x04, 0x00, 0x80, 0x10, 0x04, 0x00,
+0x21, 0x10, 0x44, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00,
+0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, 0x40, 0x19, 0x02, 0x00,
+0xFF, 0xFF, 0x63, 0x24, 0xFE, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0xA2, 0x10,
+0x06, 0x00, 0x02, 0x24, 0xF2, 0xFF, 0xA2, 0x14, 0x80, 0x10, 0x04, 0x00,
+0x40, 0x11, 0x04, 0x00, 0x23, 0x10, 0x44, 0x00, 0x80, 0x10, 0x02, 0x00,
+0x21, 0x10, 0x44, 0x00, 0x00, 0x19, 0x02, 0x00, 0x23, 0x18, 0x62, 0x00,
+0x42, 0x1F, 0x00, 0x08, 0x00, 0x19, 0x03, 0x00, 0x80, 0x10, 0x04, 0x00,
+0x21, 0x10, 0x44, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00,
+0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, 0x42, 0x1F, 0x00, 0x08,
+0x00, 0x19, 0x02, 0x00, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x6C, 0x7D, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x02, 0x80, 0x05, 0x3C, 0xCC, 0x5D, 0xA3, 0x8C, 0x05, 0x00, 0x02, 0x24,
+0x06, 0x00, 0x62, 0x10, 0x06, 0x00, 0x62, 0x2C, 0x0C, 0x00, 0x40, 0x10,
+0x06, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x24, 0x0E, 0x00, 0x62, 0x10,
+0x80, 0x10, 0x04, 0x00, 0x80, 0x10, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00,
+0x80, 0x10, 0x02, 0x00, 0xFF, 0xFF, 0x42, 0x24, 0xFE, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xF7, 0xFF, 0x62, 0x14, 0x00, 0x11, 0x04, 0x00, 0x23, 0x10, 0x44, 0x00,
+0x6D, 0x1F, 0x00, 0x08, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00,
+0x6D, 0x1F, 0x00, 0x08, 0x40, 0x10, 0x02, 0x00, 0xFF, 0xFF, 0x85, 0x30,
+0x21, 0x30, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x2A, 0xB0, 0x04, 0x3C,
+0xB4, 0x00, 0x63, 0x34, 0x01, 0x00, 0xA2, 0x24, 0x31, 0x00, 0x84, 0x34,
+0x00, 0x00, 0x65, 0xA0, 0x00, 0x00, 0x85, 0xA0, 0xFF, 0xFF, 0x45, 0x30,
+0x12, 0x00, 0xA0, 0x10, 0x01, 0x00, 0x03, 0x24, 0x28, 0xB0, 0x07, 0x3C,
+0x8F, 0x1F, 0x00, 0x08, 0xFF, 0xFF, 0x08, 0x24, 0x00, 0x00, 0x83, 0xA0,
+0x01, 0x00, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30, 0x2B, 0x10, 0xA3, 0x00,
+0x09, 0x00, 0x40, 0x14, 0x08, 0x00, 0xC6, 0x24, 0xF9, 0xFF, 0x65, 0x14,
+0x21, 0x20, 0xC7, 0x00, 0x01, 0x00, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30,
+0x2B, 0x10, 0xA3, 0x00, 0x00, 0x00, 0x88, 0xA0, 0xF9, 0xFF, 0x40, 0x10,
+0x08, 0x00, 0xC6, 0x24, 0x00, 0x01, 0xA2, 0x2C, 0x13, 0x00, 0x40, 0x10,
+0x21, 0x18, 0xA0, 0x00, 0xFF, 0x00, 0x08, 0x24, 0x28, 0xB0, 0x07, 0x3C,
+0xA3, 0x1F, 0x00, 0x08, 0xFF, 0xFF, 0x09, 0x24, 0xFF, 0xFF, 0x43, 0x30,
+0x00, 0x00, 0xA2, 0xA0, 0x00, 0x01, 0x62, 0x2C, 0x0A, 0x00, 0x40, 0x10,
+0x08, 0x00, 0xC6, 0x24, 0x01, 0x00, 0x62, 0x24, 0xF9, 0xFF, 0x68, 0x14,
+0x21, 0x28, 0xC7, 0x00, 0x00, 0x01, 0x02, 0x24, 0xFF, 0xFF, 0x43, 0x30,
+0x00, 0x01, 0x62, 0x2C, 0x00, 0x00, 0xA9, 0xA0, 0xF8, 0xFF, 0x40, 0x14,
+0x08, 0x00, 0xC6, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xD0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, 0x25, 0xB0, 0x12, 0x3C,
+0xFF, 0xFF, 0x02, 0x24, 0x28, 0x00, 0xB6, 0xAF, 0x1C, 0x00, 0xB3, 0xAF,
+0x42, 0x00, 0x56, 0x36, 0x14, 0x00, 0xB1, 0xAF, 0xFC, 0x77, 0x13, 0x24,
+0x40, 0x00, 0x51, 0x36, 0x00, 0x00, 0xC2, 0xA2, 0x10, 0x00, 0xB0, 0xAF,
+0x00, 0x00, 0x33, 0xA6, 0xFC, 0x57, 0x10, 0x24, 0x32, 0x00, 0x04, 0x24,
+0x2C, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x5B, 0x1F, 0x00, 0x0C,
+0x20, 0x00, 0xB4, 0xAF, 0x00, 0x00, 0x30, 0xA6, 0x5B, 0x1F, 0x00, 0x0C,
+0x32, 0x00, 0x04, 0x24, 0xFC, 0x37, 0x02, 0x24, 0x00, 0x00, 0x22, 0xA6,
+0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x00, 0x33, 0xA6,
+0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x00, 0x30, 0xA6,
+0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x10, 0x02, 0x24,
+0x00, 0x00, 0x22, 0xA6, 0xD8, 0x00, 0x45, 0x36, 0x00, 0x00, 0xA2, 0x90,
+0xA0, 0x00, 0x54, 0x36, 0xA4, 0x00, 0x55, 0x36, 0x7F, 0x00, 0x42, 0x30,
+0x00, 0x00, 0xA2, 0xA0, 0xA8, 0x00, 0x53, 0x36, 0x00, 0x80, 0x02, 0x3C,
+0xFC, 0x17, 0x03, 0x24, 0x00, 0x00, 0x80, 0xAE, 0x00, 0x00, 0xA0, 0xAE,
+0x00, 0x00, 0x62, 0xAE, 0x00, 0x00, 0x23, 0xA6, 0x00, 0x00, 0xA3, 0x90,
+0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x10, 0x26, 0xAA, 0x1B, 0x04, 0x92,
+0x80, 0xFF, 0x02, 0x24, 0x25, 0x18, 0x62, 0x00, 0x56, 0x01, 0x52, 0x36,
+0xFF, 0x0F, 0x02, 0x24, 0x00, 0x00, 0xA3, 0xA0, 0x00, 0x00, 0x42, 0xA6,
+0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x04, 0x8E,
+0x14, 0x1C, 0x02, 0x8E, 0x18, 0x1C, 0x03, 0x8E, 0x2C, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x82, 0xAE, 0x18, 0x00, 0xB2, 0x8F, 0x00, 0x00, 0xA3, 0xAE,
+0x20, 0x00, 0xB4, 0x8F, 0x00, 0x00, 0x64, 0xAE, 0x24, 0x00, 0xB5, 0x8F,
+0x00, 0x00, 0xC0, 0xA2, 0x1C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x10, 0x3C, 0x34, 0x00, 0xBF, 0xAF,
+0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF,
+0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x1C, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0x05, 0x36, 0x00, 0x00, 0xA2, 0x94,
+0x24, 0xFA, 0x03, 0x24, 0xA8, 0x00, 0x13, 0x36, 0x24, 0x10, 0x43, 0x00,
+0x00, 0x00, 0xA2, 0xA4, 0xA0, 0x00, 0x12, 0x36, 0xA4, 0x00, 0x10, 0x36,
+0x00, 0x00, 0x55, 0x8E, 0x00, 0x00, 0x16, 0x8E, 0x00, 0x00, 0x71, 0x8E,
+0x00, 0x80, 0x14, 0x3C, 0xFC, 0x37, 0x02, 0x24, 0x00, 0x00, 0x40, 0xAE,
+0x21, 0x88, 0x34, 0x02, 0x00, 0x00, 0x00, 0xAE, 0xFD, 0x00, 0x04, 0x24,
+0x00, 0x00, 0x74, 0xAE, 0x00, 0x00, 0xA2, 0xA4, 0x7A, 0x1F, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAE, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x16, 0xAE, 0x00, 0x00, 0x71, 0xAE, 0x90, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x10, 0x3C,
+0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x1C, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0x05, 0x36,
+0x00, 0x00, 0xA2, 0x94, 0xAF, 0xFF, 0x03, 0x24, 0xA8, 0x00, 0x13, 0x36,
+0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0xA2, 0xA4, 0xA0, 0x00, 0x12, 0x36,
+0xA4, 0x00, 0x10, 0x36, 0x00, 0x00, 0x55, 0x8E, 0x00, 0x00, 0x16, 0x8E,
+0x00, 0x00, 0x71, 0x8E, 0x00, 0x80, 0x14, 0x3C, 0xFC, 0x37, 0x02, 0x24,
+0x00, 0x00, 0x40, 0xAE, 0x21, 0x88, 0x34, 0x02, 0x00, 0x00, 0x00, 0xAE,
+0xFD, 0x00, 0x04, 0x24, 0x00, 0x00, 0x74, 0xAE, 0x00, 0x00, 0xA2, 0xA4,
+0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAE,
+0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x16, 0xAE, 0x00, 0x00, 0x71, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x05, 0x3C, 0x40, 0x00, 0xA5, 0x34,
+0x00, 0x00, 0xA2, 0x94, 0xD8, 0xFD, 0x03, 0x24, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x10, 0x43, 0x00, 0xFC, 0x37, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4,
+0x00, 0x00, 0xA3, 0xA4, 0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, 0xFF, 0x00, 0x82, 0x30,
+0x10, 0x00, 0xA4, 0x27, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x88, 0xC0, 0x00,
+0x21, 0x80, 0xE0, 0x00, 0xC0, 0x90, 0x02, 0x00, 0x28, 0x00, 0xBF, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0xFF, 0xFF, 0xB3, 0x30, 0x25, 0xB0, 0x02, 0x3C,
+0x40, 0x02, 0x49, 0x34, 0xF8, 0xFF, 0x10, 0x26, 0x21, 0x30, 0x00, 0x00,
+0x01, 0x00, 0x0A, 0x24, 0x44, 0x02, 0x48, 0x34, 0x99, 0x20, 0x00, 0x08,
+0x01, 0x80, 0x07, 0x3C, 0x2E, 0x00, 0xCA, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x02, 0x92, 0x00, 0x00, 0x04, 0x92, 0x02, 0x00, 0x03, 0x92,
+0x03, 0x00, 0x05, 0x92, 0x00, 0x12, 0x02, 0x00, 0x25, 0x20, 0x82, 0x00,
+0x00, 0x1C, 0x03, 0x00, 0x25, 0x20, 0x83, 0x00, 0x21, 0x10, 0x46, 0x02,
+0x00, 0x2E, 0x05, 0x00, 0x01, 0x00, 0xC6, 0x24, 0x25, 0x20, 0x85, 0x00,
+0x25, 0x10, 0x47, 0x00, 0x06, 0x00, 0xC3, 0x2C, 0x00, 0x00, 0x04, 0xAD,
+0x04, 0x00, 0x10, 0x26, 0x00, 0x00, 0x22, 0xAD, 0x12, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x22, 0x92, 0x01, 0x00, 0x23, 0x92, 0x04, 0x00, 0x10, 0x26,
+0x00, 0x14, 0x02, 0x00, 0x25, 0x10, 0x62, 0x02, 0x00, 0x1E, 0x03, 0x00,
+0x25, 0x20, 0x43, 0x00, 0x21, 0x10, 0x46, 0x02, 0x01, 0x00, 0xC6, 0x24,
+0x25, 0x10, 0x47, 0x00, 0x06, 0x00, 0xC3, 0x2C, 0x00, 0x00, 0x04, 0xAD,
+0x00, 0x00, 0x22, 0xAD, 0xF0, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xBF, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0x03, 0x00, 0x22, 0x92, 0x02, 0x00, 0x24, 0x92, 0x04, 0x00, 0x23, 0x92,
+0x05, 0x00, 0x25, 0x92, 0x8B, 0x20, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00,
+0xFF, 0xFF, 0x84, 0x30, 0x42, 0xB0, 0x08, 0x3C, 0x80, 0x10, 0x04, 0x00,
+0x21, 0x10, 0x48, 0x00, 0x04, 0x00, 0x46, 0xAC, 0x00, 0x00, 0x07, 0x91,
+0x40, 0x18, 0x04, 0x00, 0x03, 0x00, 0x06, 0x24, 0xFF, 0x00, 0xE7, 0x30,
+0x04, 0x30, 0x66, 0x00, 0x01, 0x00, 0x02, 0x24, 0x04, 0x10, 0x62, 0x00,
+0x25, 0x30, 0xC7, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x25, 0x10, 0x47, 0x00,
+0x02, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0xC7, 0x30, 0xFF, 0x00, 0x47, 0x30,
+0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x47, 0xA0, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x83, 0x90, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x00, 0x86, 0xAC, 0x18, 0x00, 0x85, 0xAC, 0x00, 0x00, 0x84, 0xAC,
+0x03, 0x00, 0x62, 0x10, 0x04, 0x00, 0x84, 0xAC, 0x5F, 0x5C, 0x00, 0x08,
+0x0C, 0x00, 0x80, 0xAC, 0x0C, 0x00, 0x82, 0x8C, 0x5F, 0x5C, 0x00, 0x08,
+0x10, 0x00, 0x82, 0xAC, 0xC8, 0xFF, 0xBD, 0x27, 0x28, 0x00, 0xB6, 0xAF,
+0x25, 0xB0, 0x02, 0x3C, 0x02, 0x80, 0x16, 0x3C, 0x2C, 0x00, 0xB7, 0xAF,
+0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x30, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x18, 0x03, 0x55, 0x34, 0x01, 0x80, 0x17, 0x3C,
+0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x14, 0x3C, 0xD0, 0xDF, 0xD2, 0x26,
+0x6C, 0x83, 0xE2, 0x26, 0x00, 0x00, 0xA2, 0xAE, 0xD0, 0xDF, 0xD0, 0x8E,
+0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x5C, 0x71, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00,
+0x96, 0x40, 0x00, 0x0C, 0xFC, 0x5C, 0x60, 0xAE, 0x22, 0x00, 0x12, 0x12,
+0x08, 0x0C, 0x84, 0x26, 0x14, 0x00, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24,
+0x2A, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x60, 0x14,
+0x02, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0x23, 0x02, 0x1D, 0x00, 0x40, 0x10, 0x23, 0x10, 0x71, 0x00,
+0x0C, 0x00, 0x02, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x60, 0x10,
+0x2B, 0x10, 0x23, 0x02, 0xF5, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x71, 0x00,
+0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E, 0x09, 0xF8, 0x40, 0x00,
+0x0C, 0x00, 0x00, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x0C, 0x84, 0x26, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00,
+0x76, 0x39, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00, 0xED, 0x20, 0x00, 0x08,
+0x6C, 0x83, 0xE2, 0x26, 0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E,
+0x09, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x21, 0x00, 0x08,
+0x0C, 0x00, 0x02, 0xAE, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0x23, 0x02, 0xDA, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x71, 0x00,
+0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E, 0x09, 0xF8, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0x03, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0xC0, 0x54, 0x42, 0x24, 0x18, 0x00, 0xB0, 0xAF, 0xC0, 0x80, 0x04, 0x00,
+0x21, 0x80, 0x02, 0x02, 0x1C, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0x8E,
+0x10, 0x00, 0xA4, 0x27, 0x09, 0x00, 0x50, 0x10, 0x21, 0x88, 0x00, 0x00,
+0x04, 0x00, 0x43, 0x8C, 0x21, 0x88, 0x40, 0x00, 0x00, 0x00, 0x42, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC,
+0x00, 0x00, 0x31, 0xAE, 0x04, 0x00, 0x31, 0xAE, 0x90, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x01, 0x01, 0x82, 0x2C,
+0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x21, 0x18, 0x00, 0x00, 0x10, 0x00, 0x40, 0x14, 0x01, 0x00, 0x04, 0x24,
+0x01, 0x02, 0x02, 0x2E, 0x0D, 0x00, 0x40, 0x14, 0x02, 0x00, 0x04, 0x24,
+0x01, 0x08, 0x02, 0x2E, 0x0A, 0x00, 0x40, 0x14, 0x03, 0x00, 0x04, 0x24,
+0x01, 0x10, 0x02, 0x2E, 0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x04, 0x00, 0x04, 0x24,
+0x35, 0x21, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xFF, 0x40, 0x10,
+0x21, 0x18, 0x40, 0x00, 0x0C, 0x00, 0x50, 0xAC, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0x03, 0x8E, 0x02, 0x80, 0x02, 0x3C,
+0xC0, 0x54, 0x42, 0x24, 0xC0, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x64, 0x8C, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C,
+0x00, 0x00, 0x04, 0xAE, 0x04, 0x00, 0x90, 0xAC, 0x04, 0x00, 0x03, 0xAE,
+0xC4, 0x5D, 0xC5, 0x8C, 0x10, 0x00, 0xA4, 0x27, 0x05, 0x00, 0xA0, 0x10,
+0x00, 0x00, 0x70, 0xAC, 0xB0, 0x5D, 0xE2, 0x8C, 0xC4, 0x5D, 0xC0, 0xAC,
+0x25, 0x10, 0x45, 0x00, 0xB0, 0x5D, 0xE2, 0xAC, 0x90, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xC9, 0xF7, 0x1B, 0x6B,
+0x6B, 0xEB, 0x60, 0x33, 0xFF, 0x6A, 0x60, 0x33, 0x4C, 0xEC, 0x60, 0xF1,
+0x00, 0x4B, 0xAC, 0xEA, 0x69, 0xE2, 0x80, 0xC2, 0x20, 0xE8, 0x00, 0x65,
+0xFF, 0x6A, 0x8C, 0xEA, 0x15, 0x5A, 0x0E, 0x60, 0x01, 0x6B, 0x83, 0x67,
+0x84, 0xEA, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0xEE, 0xF0, 0x10, 0x4A,
+0x8C, 0xEA, 0x05, 0x2A, 0x0F, 0x6A, 0x8C, 0xEA, 0x02, 0x6B, 0x01, 0x2A,
+0x00, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x00, 0x00, 0xFF, 0x63, 0x00, 0xD0,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x8C, 0x30, 0x0A, 0x65,
+0x89, 0xE0, 0x48, 0x32, 0x89, 0xE2, 0x68, 0x67, 0x63, 0xF3, 0x00, 0x4B,
+0x48, 0x32, 0x69, 0xE2, 0x01, 0xD1, 0x00, 0x6B, 0x04, 0xF5, 0x6A, 0xC2,
+0x04, 0xF5, 0x6B, 0xC2, 0x04, 0xF5, 0x64, 0x9A, 0x1C, 0x6D, 0x22, 0x67,
+0x01, 0x6F, 0xFF, 0x6E, 0x02, 0x10, 0xFF, 0x4D, 0xCC, 0xED, 0x47, 0x67,
+0x44, 0xED, 0x6C, 0xEA, 0xFA, 0x22, 0x04, 0xF5, 0xAA, 0xC1, 0x00, 0x6D,
+0x1D, 0x5D, 0x13, 0x60, 0x89, 0xE0, 0x48, 0x32, 0x68, 0x67, 0x89, 0xE2,
+0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x79, 0xE2, 0x04, 0xF5, 0x44, 0x9E,
+0x01, 0x6B, 0x64, 0xED, 0x6C, 0xEA, 0x09, 0x2A, 0x01, 0x4D, 0xFF, 0x6A,
+0x4C, 0xED, 0x1D, 0x5D, 0xED, 0x61, 0x01, 0x91, 0x00, 0x90, 0x20, 0xE8,
+0x01, 0x63, 0x01, 0x91, 0x00, 0x90, 0x04, 0xF5, 0xAB, 0xC6, 0x20, 0xE8,
+0x01, 0x63, 0x00, 0x00, 0xFB, 0x63, 0x07, 0xD1, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0x00, 0x6A, 0x63, 0xF3, 0x00, 0x49, 0x08, 0x62,
+0x06, 0xD0, 0x04, 0xD2, 0x34, 0x10, 0x03, 0x54, 0x62, 0x60, 0x01, 0x74,
+0x6E, 0x60, 0x04, 0xF5, 0x88, 0x99, 0x07, 0x6A, 0xFF, 0x6B, 0x82, 0x34,
+0x86, 0x34, 0x4C, 0xEC, 0x04, 0x58, 0x6C, 0xEC, 0x12, 0x60, 0x00, 0x18,
+0xA1, 0x5C, 0xB0, 0x67, 0xC9, 0xF7, 0x1B, 0x6C, 0x04, 0xF5, 0x60, 0x99,
+0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x4C, 0xEB, 0x80, 0xF1, 0x04, 0x4C,
+0x08, 0x32, 0x89, 0xE2, 0x04, 0xF5, 0x64, 0xD9, 0x60, 0xDA, 0x00, 0x18,
+0xA5, 0x21, 0x04, 0x94, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x04, 0x93,
+0x80, 0x34, 0x80, 0x34, 0x60, 0xF1, 0x00, 0x4C, 0x89, 0xE3, 0x40, 0xA2,
+0x04, 0x92, 0x7F, 0x49, 0x15, 0x49, 0x01, 0x4A, 0x20, 0x5A, 0x04, 0xD2,
+0x48, 0x60, 0x04, 0xF5, 0xA8, 0x99, 0x01, 0x6B, 0xA2, 0x34, 0x92, 0x32,
+0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xF0, 0x22, 0xE4, 0xF4, 0x78, 0x99,
+0xFF, 0x6A, 0x86, 0x34, 0x72, 0x33, 0x4C, 0xEB, 0x7F, 0x6A, 0x4C, 0xEB,
+0x07, 0x6A, 0x4C, 0xEC, 0xFF, 0x6A, 0x4C, 0xEC, 0x07, 0x68, 0xAC, 0xE8,
+0x02, 0x74, 0x4C, 0xE8, 0xB2, 0x61, 0x38, 0x5B, 0x0A, 0x61, 0x01, 0xF6,
+0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF2, 0x00, 0x6B, 0x6D, 0xEA,
+0x04, 0xF5, 0x48, 0xD9, 0xAA, 0x17, 0x14, 0x5B, 0xA8, 0x60, 0x01, 0xF6,
+0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF6, 0x00, 0x6B, 0x6D, 0xEA,
+0xF3, 0x17, 0x03, 0x74, 0x9E, 0x61, 0x1A, 0x5B, 0x9C, 0x61, 0x01, 0xF6,
+0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF4, 0x00, 0x6C, 0x8D, 0xEA,
+0x04, 0xF5, 0x48, 0xD9, 0x92, 0x17, 0x32, 0x5B, 0x90, 0x60, 0x01, 0xF6,
+0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF4, 0x00, 0x6B, 0x6D, 0xEA,
+0xDB, 0x17, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF,
+0x05, 0x63, 0x00, 0x00, 0x20, 0xE8, 0x00, 0x65, 0xA4, 0x67, 0xC9, 0xF7,
+0x1B, 0x6C, 0xFC, 0x63, 0x8B, 0xEC, 0x06, 0xD0, 0x80, 0x34, 0xAC, 0x30,
+0xA1, 0xE0, 0x80, 0x34, 0x07, 0x62, 0x80, 0xF1, 0x40, 0x44, 0x08, 0x30,
+0x40, 0xA2, 0xA1, 0xE0, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0x08, 0x30, 0x41, 0xE0, 0x04, 0xF5, 0x48, 0x98,
+0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4C, 0x6C, 0xEA, 0x48, 0x32, 0x89, 0xE2,
+0x04, 0xF5, 0x60, 0x98, 0x40, 0x9A, 0x85, 0x67, 0x6C, 0xEA, 0x04, 0xF5,
+0x44, 0xD8, 0x00, 0x18, 0xA5, 0x21, 0x04, 0xD5, 0x04, 0x95, 0x04, 0xF5,
+0x8A, 0xA0, 0xFF, 0x6A, 0x00, 0x18, 0x93, 0x21, 0x4C, 0xED, 0x07, 0x97,
+0x06, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0xFF, 0xF7, 0x1F, 0x6B,
+0x8C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x0B, 0x6C, 0x6C, 0xEA, 0x6C, 0xEC,
+0x07, 0x6B, 0x0E, 0x2A, 0x0C, 0x5C, 0x0B, 0x60, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x88, 0x32, 0x7D, 0xF7, 0x08, 0x4B, 0x69, 0xE2,
+0x40, 0x9A, 0x00, 0xEA, 0x00, 0x65, 0x07, 0x6B, 0x20, 0xE8, 0x43, 0x67,
+0x06, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x05, 0x6B, 0x20, 0xE8, 0x43, 0x67,
+0x04, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x03, 0x6B, 0x20, 0xE8, 0x43, 0x67,
+0x02, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x01, 0x6B, 0x20, 0xE8, 0x43, 0x67,
+0x00, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x00, 0x00, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0xF7, 0x63, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0x6A,
+0x0F, 0xD1, 0x23, 0x67, 0x10, 0x62, 0x0E, 0xD0, 0x04, 0xD2, 0x05, 0xD3,
+0x06, 0xD3, 0x07, 0xD3, 0x08, 0xD2, 0x09, 0xD2, 0x0A, 0xD2, 0x0B, 0xD2,
+0x0C, 0xD2, 0xE4, 0xF4, 0x08, 0x49, 0x48, 0x99, 0x01, 0x6B, 0xFF, 0x6C,
+0x42, 0x32, 0x52, 0x32, 0x6C, 0xEA, 0x8C, 0xEA, 0x80, 0xF0, 0x11, 0x22,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x04, 0x96, 0x40, 0x32,
+0x60, 0xF1, 0x00, 0x4A, 0x49, 0xE6, 0x40, 0xA2, 0xFF, 0x6B, 0x4C, 0xEC,
+0x05, 0x92, 0x0C, 0x65, 0x51, 0xE4, 0xC0, 0xF4, 0x4A, 0xA4, 0x6C, 0xEA,
+0x61, 0x99, 0x58, 0xEB, 0xE0, 0xF4, 0x47, 0xA4, 0xFF, 0x6B, 0x6C, 0xEA,
+0x62, 0x99, 0x12, 0xED, 0x00, 0x65, 0x00, 0x65, 0x58, 0xEB, 0x12, 0xEA,
+0x55, 0xE5, 0xFF, 0xF7, 0x4C, 0x99, 0xA3, 0xEA, 0x40, 0xF1, 0x0F, 0x61,
+0xAB, 0xE2, 0xFF, 0xF7, 0x4C, 0xD9, 0x61, 0x99, 0x42, 0x99, 0xC8, 0x67,
+0xFF, 0xF7, 0xEC, 0x99, 0x55, 0xE3, 0xFF, 0xF7, 0x70, 0x99, 0xFF, 0xF7,
+0x54, 0x99, 0x51, 0xE3, 0xFF, 0xF7, 0x7C, 0x99, 0x40, 0x99, 0x41, 0xE3,
+0x05, 0x93, 0x69, 0xE6, 0x20, 0xF5, 0x5E, 0xA2, 0xFF, 0x6E, 0xCC, 0xEA,
+0xC5, 0x67, 0x0F, 0x25, 0xA3, 0xEA, 0xD8, 0x67, 0x0D, 0x2E, 0x48, 0x67,
+0x07, 0x5A, 0x04, 0x61, 0x0C, 0x72, 0x02, 0x60, 0x0D, 0x72, 0x05, 0x61,
+0xAC, 0x32, 0xAB, 0xE2, 0x4E, 0x32, 0x83, 0xEA, 0x10, 0x61, 0x79, 0x26,
+0x05, 0x92, 0x68, 0x67, 0x68, 0x34, 0x51, 0xE4, 0x06, 0x92, 0x69, 0xE2,
+0x44, 0xF5, 0x66, 0xA2, 0xFF, 0x6A, 0x4C, 0xEB, 0x60, 0xF5, 0x40, 0x9C,
+0x44, 0xEB, 0xE3, 0xEA, 0x6A, 0x60, 0x01, 0x68, 0x5F, 0x99, 0x70, 0x67,
+0x88, 0x67, 0x64, 0xEC, 0x6C, 0xEA, 0x00, 0xF1, 0x1C, 0x22, 0x06, 0x96,
+0x95, 0xE6, 0x44, 0xF5, 0x66, 0xA5, 0x04, 0xF5, 0xEC, 0xA5, 0xFF, 0x6E,
+0x46, 0x67, 0xCC, 0xEB, 0x0A, 0x6C, 0xEC, 0xEA, 0x84, 0xEB, 0x82, 0xEA,
+0x00, 0xF1, 0x0D, 0x60, 0x41, 0x47, 0x04, 0xF5, 0x4C, 0xC5, 0xCC, 0xEA,
+0x8E, 0xEA, 0x02, 0x2A, 0x24, 0xF5, 0x09, 0xC5, 0x05, 0x94, 0x68, 0x67,
+0x68, 0x32, 0x89, 0xE2, 0xC0, 0xF5, 0x94, 0x9A, 0x60, 0xF5, 0x40, 0x9A,
+0x84, 0x33, 0x8D, 0xE3, 0x69, 0xE2, 0x4A, 0x37, 0xFF, 0xF7, 0xEC, 0xD9,
+0x05, 0x96, 0x27, 0xF1, 0x44, 0x9E, 0xFF, 0xF7, 0x1F, 0x72, 0xC0, 0xF0,
+0x1B, 0x61, 0x00, 0x6B, 0x61, 0xD9, 0x62, 0xD9, 0xFF, 0xF7, 0x70, 0xD9,
+0xFF, 0xF7, 0x74, 0xD9, 0xFF, 0xF7, 0x78, 0xD9, 0xFF, 0xF7, 0x7C, 0xD9,
+0x60, 0xD9, 0x04, 0x94, 0x0C, 0x96, 0x0B, 0x92, 0x01, 0x4C, 0x0A, 0x93,
+0x04, 0xD4, 0x09, 0x94, 0x7F, 0x4E, 0x7F, 0x4A, 0x7F, 0x4B, 0x15, 0x4E,
+0x15, 0x4A, 0x15, 0x4B, 0x7F, 0x4C, 0x15, 0x4C, 0x0C, 0xD6, 0x0B, 0xD2,
+0x08, 0x96, 0x07, 0x92, 0x0A, 0xD3, 0x06, 0x93, 0x09, 0xD4, 0x04, 0x94,
+0x7F, 0x4E, 0x7F, 0x4A, 0x7F, 0x4B, 0x15, 0x4E, 0x15, 0x4A, 0x15, 0x4B,
+0x7F, 0x49, 0x20, 0x54, 0x08, 0xD6, 0x07, 0xD2, 0x06, 0xD3, 0x15, 0x49,
+0x3F, 0xF7, 0x15, 0x61, 0x10, 0x97, 0x0F, 0x91, 0x0E, 0x90, 0x00, 0xEF,
+0x09, 0x63, 0xA0, 0xF0, 0x0E, 0x25, 0xA0, 0xF0, 0x0E, 0x2E, 0xA4, 0x32,
+0xA9, 0xE2, 0x4A, 0x32, 0x03, 0xEA, 0xC1, 0x60, 0x06, 0x96, 0x48, 0x67,
+0x00, 0x6B, 0x51, 0xE6, 0x04, 0xF5, 0x6C, 0xC4, 0x01, 0x6B, 0x64, 0xEA,
+0x5F, 0x99, 0x6F, 0xEB, 0x6C, 0xEA, 0x5F, 0xD9, 0x24, 0xF5, 0x49, 0xA4,
+0xFF, 0x6C, 0x8C, 0xEA, 0x01, 0x72, 0x10, 0x60, 0x09, 0x96, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x00, 0x6D, 0x63, 0xF3, 0x00, 0x4A,
+0x4D, 0xE6, 0x85, 0x67, 0xA9, 0xE3, 0x01, 0x4D, 0x1D, 0x55, 0x44, 0xF5,
+0x86, 0xC2, 0xFA, 0x61, 0x06, 0x93, 0x88, 0x67, 0x00, 0x6E, 0x89, 0xE3,
+0x24, 0xF5, 0xC9, 0xC2, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x9D, 0xF7, 0x18, 0x4A, 0x00, 0x9A, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4,
+0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x00, 0x6D,
+0x5C, 0xF4, 0x00, 0x4F, 0xDC, 0xF3, 0x0C, 0x4E, 0xA8, 0x32, 0xED, 0xE2,
+0x60, 0x9B, 0x11, 0xE2, 0xC9, 0xE2, 0xC0, 0xF5, 0x74, 0xDC, 0x40, 0x9A,
+0x01, 0x4D, 0x1D, 0x55, 0x60, 0xF5, 0x40, 0xDC, 0xF3, 0x61, 0x68, 0x67,
+0x20, 0x23, 0x07, 0x94, 0xA8, 0x67, 0xFF, 0x4D, 0x04, 0xF5, 0x4B, 0xA4,
+0xFF, 0x68, 0x42, 0xED, 0x18, 0x61, 0x08, 0x96, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE6, 0x04, 0xF5,
+0x8B, 0xA2, 0x04, 0xF5, 0xC4, 0x9A, 0x01, 0x6F, 0x0C, 0xEC, 0x67, 0x67,
+0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA, 0x00, 0xF1, 0x03, 0x22,
+0xFF, 0x4D, 0x82, 0xED, 0xF6, 0x60, 0x88, 0x67, 0x10, 0xF0, 0x02, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x88, 0x32, 0x63, 0xF3, 0x00, 0x4E, 0xC9, 0xE2,
+0xC0, 0xF5, 0x94, 0x9A, 0x60, 0xF5, 0x40, 0x9A, 0x84, 0x33, 0x8D, 0xE3,
+0x69, 0xE2, 0x4A, 0x37, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0xCB, 0xF4, 0x46, 0xA2, 0xFF, 0x6B, 0x6C, 0xEA, 0x22, 0x72, 0xC0, 0xF0,
+0x17, 0x61, 0x88, 0x67, 0x13, 0x74, 0x3F, 0xF7, 0x0D, 0x60, 0x07, 0x96,
+0x01, 0x6B, 0x64, 0xEC, 0x64, 0xF5, 0x44, 0x9E, 0xFF, 0xF7, 0xEC, 0xD9,
+0x6D, 0xEA, 0x64, 0xF5, 0x44, 0xDE, 0x05, 0x96, 0x27, 0xF1, 0x44, 0x9E,
+0xFF, 0xF7, 0x1F, 0x72, 0x3F, 0xF7, 0x05, 0x60, 0x04, 0x95, 0xFF, 0x6A,
+0x88, 0x67, 0x00, 0x18, 0x93, 0x21, 0x4C, 0xED, 0x1E, 0x17, 0x00, 0x6B,
+0xFF, 0xF7, 0x6C, 0xD9, 0xB0, 0x16, 0x1F, 0xF7, 0x18, 0x26, 0x05, 0x94,
+0x68, 0x67, 0x68, 0x32, 0x89, 0xE2, 0xC0, 0xF5, 0x54, 0x9A, 0x43, 0xEF,
+0x4E, 0x17, 0x48, 0x67, 0x1C, 0x5A, 0xFF, 0xF6, 0x17, 0x60, 0x06, 0x94,
+0x4D, 0xE4, 0x24, 0xF5, 0x49, 0xA3, 0xFF, 0x6C, 0x01, 0x72, 0x53, 0x60,
+0x0C, 0x96, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x00, 0x6D,
+0x63, 0xF3, 0x00, 0x4A, 0x4D, 0xE6, 0x85, 0x67, 0xA9, 0xE3, 0x01, 0x4D,
+0x1D, 0x55, 0x44, 0xF5, 0x86, 0xC2, 0xFA, 0x61, 0x06, 0x93, 0x88, 0x67,
+0x00, 0x6E, 0x89, 0xE3, 0x01, 0x6C, 0x04, 0xF5, 0xCC, 0xC2, 0x24, 0xF5,
+0xC9, 0xC2, 0x64, 0x67, 0x48, 0x67, 0x64, 0xEA, 0x5F, 0x99, 0x6F, 0xEB,
+0x6C, 0xEA, 0x68, 0x67, 0x5F, 0xD9, 0x4E, 0x23, 0x20, 0xF0, 0x42, 0xA1,
+0xA8, 0x67, 0x01, 0x4D, 0xA2, 0xEA, 0xFF, 0x68, 0x17, 0x61, 0x0A, 0x93,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C,
+0x89, 0xE3, 0x04, 0xF5, 0x8A, 0xA2, 0x04, 0xF5, 0xC4, 0x9A, 0x01, 0x6F,
+0x0C, 0xEC, 0x67, 0x67, 0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA,
+0x6F, 0x22, 0x01, 0x4D, 0xA2, 0xEC, 0xF7, 0x60, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0xBF, 0xF6,
+0x07, 0x61, 0x48, 0x67, 0xEE, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x02, 0x5A,
+0xBF, 0xF6, 0x00, 0x60, 0x18, 0x6E, 0x0E, 0x65, 0x9D, 0x16, 0xC8, 0x67,
+0x18, 0x5E, 0x3F, 0x61, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x05, 0x5C,
+0x03, 0x60, 0x01, 0x4A, 0x44, 0xF5, 0x46, 0xC3, 0x06, 0x93, 0x88, 0x67,
+0x00, 0x6E, 0x89, 0xE3, 0x01, 0x6C, 0x04, 0xF5, 0xCC, 0xC2, 0x24, 0xF5,
+0xC9, 0xC2, 0x64, 0x67, 0x48, 0x67, 0x64, 0xEA, 0x5F, 0x99, 0x6F, 0xEB,
+0x6C, 0xEA, 0x68, 0x67, 0x5F, 0xD9, 0xB2, 0x2B, 0x20, 0xF0, 0x42, 0xA1,
+0xA4, 0x67, 0xFF, 0x68, 0xAD, 0x22, 0x0B, 0x94, 0x10, 0xF0, 0x02, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x63, 0xF3, 0x00, 0x4E, 0xC9, 0xE4, 0x04, 0xF5,
+0x8A, 0xA2, 0xE5, 0x67, 0x04, 0xF5, 0xC4, 0x9A, 0x0C, 0xEC, 0x67, 0x67,
+0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA, 0x09, 0x22, 0x01, 0x4D,
+0xA2, 0xEC, 0x96, 0x61, 0x67, 0x67, 0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA,
+0x6E, 0xEA, 0xF7, 0x2A, 0x0C, 0xED, 0x0D, 0x65, 0x8D, 0x17, 0x48, 0x67,
+0x05, 0x5A, 0x05, 0x60, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x03, 0x5C,
+0xBD, 0x17, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x04, 0x5C, 0xB8, 0x17,
+0x07, 0x94, 0x48, 0x67, 0x01, 0x6B, 0x64, 0xEA, 0x64, 0xF5, 0x44, 0x9C,
+0x6D, 0xEA, 0x64, 0xF5, 0x44, 0xDC, 0x50, 0x16, 0x0C, 0xED, 0x0D, 0x65,
+0x91, 0x17, 0x0C, 0xED, 0x0D, 0x65, 0xFD, 0x16, 0xFC, 0x63, 0x10, 0xF0,
+0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x05, 0xD1, 0x06, 0x62, 0x04, 0xD0,
+0x63, 0xF3, 0x00, 0x4C, 0x87, 0xF0, 0x58, 0x9C, 0x87, 0xF0, 0x7D, 0xA4,
+0x65, 0xE2, 0x87, 0xF0, 0x54, 0x9C, 0x43, 0xE9, 0xE0, 0xF0, 0x04, 0x60,
+0x04, 0x67, 0x0C, 0x10, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30,
+0x63, 0xF3, 0x00, 0x48, 0x87, 0xF0, 0x54, 0x98, 0x10, 0x49, 0x43, 0xE9,
+0xC0, 0xF0, 0x16, 0x60, 0x87, 0xF0, 0x5D, 0xA0, 0xFF, 0xF7, 0x1F, 0x6D,
+0x2C, 0xED, 0x10, 0x4A, 0x87, 0xF0, 0x5D, 0xC0, 0xEF, 0xF7, 0x1E, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4,
+0x80, 0x34, 0xAA, 0xF2, 0x14, 0x4C, 0x4D, 0xED, 0x00, 0x1C, 0xF4, 0x54,
+0x10, 0x6E, 0x46, 0xF7, 0xB8, 0x98, 0x1F, 0x6B, 0x40, 0xF4, 0xA2, 0x34,
+0x6C, 0xEC, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32, 0x89, 0xE2, 0x48, 0x32,
+0x19, 0xE2, 0x04, 0xF5, 0x48, 0x9E, 0x01, 0x6B, 0x42, 0x32, 0x52, 0x32,
+0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xC8, 0x22, 0xC9, 0xF7, 0x1B, 0x6B,
+0x6B, 0xEB, 0x60, 0x33, 0x60, 0x33, 0x60, 0xF1, 0x00, 0x4B, 0x69, 0xE4,
+0x40, 0xA2, 0xFF, 0x6B, 0xFF, 0x6F, 0x4C, 0xEB, 0x0B, 0x65, 0x46, 0xF7,
+0x74, 0x98, 0x3F, 0x68, 0x80, 0xF5, 0x62, 0x32, 0x0C, 0xEA, 0x05, 0x52,
+0x4C, 0xEF, 0x01, 0x61, 0x04, 0x6F, 0xC0, 0xF7, 0x62, 0x32, 0x0E, 0x2A,
+0xE4, 0xF4, 0x54, 0x9E, 0x04, 0x6F, 0x01, 0x4A, 0xE4, 0xF4, 0x54, 0xDE,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A,
+0x46, 0xF7, 0xB8, 0x9A, 0xA2, 0x32, 0x52, 0x32, 0x1F, 0x6B, 0x6C, 0xEA,
+0x08, 0x52, 0x52, 0x60, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x63, 0xF3, 0x00, 0x4D, 0x46, 0xF7, 0x54, 0x9D, 0x0C, 0xEA, 0x08, 0x67,
+0x0E, 0xEA, 0x46, 0x2A, 0x74, 0x27, 0x01, 0x77, 0x05, 0x61, 0xC4, 0xF4,
+0x5C, 0x9E, 0x01, 0x4A, 0xC4, 0xF4, 0x5C, 0xDE, 0x02, 0x77, 0x05, 0x61,
+0xE4, 0xF4, 0x40, 0x9E, 0x01, 0x4A, 0xE4, 0xF4, 0x40, 0xDE, 0x03, 0x77,
+0x05, 0x61, 0xE4, 0xF4, 0x44, 0x9E, 0x01, 0x4A, 0xE4, 0xF4, 0x44, 0xDE,
+0x04, 0x77, 0x05, 0x61, 0xE4, 0xF4, 0x48, 0x9E, 0x01, 0x4A, 0xE4, 0xF4,
+0x48, 0xDE, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0xA8, 0x67,
+0x63, 0xF3, 0x00, 0x48, 0x09, 0xE5, 0xE4, 0xF4, 0x78, 0x9E, 0x00, 0xF5,
+0x44, 0xA2, 0xFF, 0x6D, 0x72, 0x33, 0xAC, 0xEA, 0x43, 0xEB, 0x4D, 0x61,
+0xE4, 0xF4, 0x4C, 0x9E, 0x08, 0x67, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x01, 0x4A, 0xE4, 0xF4, 0x4C, 0xDE, 0x08, 0x32, 0x63, 0xF3,
+0x00, 0x4B, 0x09, 0xE2, 0x69, 0xE2, 0xE9, 0xE2, 0xA0, 0xF3, 0x68, 0xA2,
+0xAC, 0xEB, 0xC4, 0xF4, 0x54, 0x9E, 0x69, 0xE2, 0xC4, 0xF4, 0x54, 0xDE,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x08, 0xF0, 0x54, 0x9B, 0x3F, 0xF7, 0x1E, 0x22, 0x05, 0x74, 0x3F, 0xF7,
+0x1B, 0x61, 0x46, 0xF7, 0x54, 0x9B, 0xC0, 0xF7, 0x42, 0x32, 0x3F, 0xF7,
+0x15, 0x22, 0x00, 0x6A, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x08, 0xF0, 0x54, 0xDB,
+0x9D, 0xF7, 0x1C, 0x4C, 0x63, 0xF3, 0x00, 0x48, 0x00, 0x1C, 0x13, 0x58,
+0x10, 0x49, 0x87, 0xF0, 0x54, 0x98, 0x43, 0xE9, 0x3F, 0xF7, 0x0A, 0x61,
+0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x00, 0xEF, 0x04, 0x63, 0xC4, 0xF4,
+0x58, 0x9E, 0x01, 0x4A, 0xC4, 0xF4, 0x58, 0xDE, 0x86, 0x17, 0xE4, 0xF4,
+0x50, 0x9E, 0xA8, 0x67, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30,
+0x01, 0x4A, 0xE4, 0xF4, 0x50, 0xDE, 0xA8, 0x32, 0xA9, 0xE2, 0x63, 0xF3,
+0x00, 0x48, 0x09, 0xE2, 0xE9, 0xE2, 0x20, 0xF4, 0x79, 0xA2, 0xFF, 0x6A,
+0x4C, 0xEB, 0xB1, 0x17, 0xE0, 0x63, 0x00, 0x6A, 0x3E, 0x62, 0x3D, 0xD1,
+0x3C, 0xD0, 0xFC, 0x63, 0x1D, 0xD2, 0x62, 0x67, 0x1D, 0x94, 0x04, 0x05,
+0x07, 0x68, 0x94, 0x32, 0xA9, 0xE2, 0x1E, 0xD0, 0x60, 0xDA, 0x1E, 0x94,
+0x04, 0x4A, 0xFF, 0x4C, 0x00, 0x54, 0x1E, 0xD4, 0xF9, 0x60, 0x1D, 0x95,
+0x01, 0x4D, 0x03, 0x5D, 0x1D, 0xD5, 0xEE, 0x61, 0xC9, 0xF7, 0x1B, 0x6A,
+0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0xC0, 0xF2, 0x44, 0x41, 0x1D, 0xD3,
+0x60, 0xDA, 0x41, 0x99, 0x01, 0xF7, 0x00, 0x6B, 0x01, 0xF4, 0x84, 0x41,
+0x42, 0x32, 0x6C, 0xEA, 0x42, 0x32, 0x00, 0x1C, 0xFA, 0x5B, 0x33, 0xD2,
+0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x31, 0xD2, 0x9D, 0x67,
+0x70, 0x4C, 0x00, 0x1C, 0x8A, 0x40, 0x32, 0xD2, 0x1D, 0x94, 0x10, 0x6D,
+0xA4, 0xED, 0x00, 0x1C, 0xAC, 0x45, 0xFF, 0x4D, 0x9D, 0x67, 0x70, 0x4C,
+0x00, 0x1C, 0x90, 0x40, 0x1F, 0xD2, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40,
+0x70, 0x4C, 0x1D, 0x94, 0x10, 0x6D, 0xA4, 0xED, 0x00, 0x1C, 0xAC, 0x45,
+0xFF, 0x4D, 0x9D, 0x67, 0x70, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x20, 0xD2,
+0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x1D, 0x94,
+0xE1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xD1, 0xF6,
+0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x21, 0xD2, 0x71, 0xF6, 0x80, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x22, 0xD2, 0x71, 0xF6, 0x84, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x23, 0xD2, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x24, 0xD2, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x25, 0xD2,
+0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x26, 0xD2, 0x81, 0xF6,
+0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x27, 0xD2, 0x81, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x28, 0xD2, 0x81, 0xF6, 0x8C, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x29, 0xD2, 0xD1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x2A, 0xD2, 0xD1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x2B, 0xD2,
+0xD1, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x2C, 0xD2, 0x2D, 0xD2,
+0xE7, 0xF7, 0x0E, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA2, 0x67, 0xE1, 0xF6,
+0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x36, 0xD2,
+0x36, 0x95, 0xD1, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6, 0x80, 0x41, 0xF2, 0xF2,
+0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6,
+0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x36, 0x95, 0x71, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6, 0x8C, 0x41, 0xF2, 0xF2,
+0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6,
+0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x36, 0x95, 0x81, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6, 0x88, 0x41, 0xF2, 0xF2,
+0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6,
+0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x36, 0x95, 0xD1, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0xD1, 0xF6, 0x84, 0x41, 0xF2, 0xF2,
+0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0xD1, 0xF6,
+0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x33, 0x93, 0x01, 0x6A, 0x1D, 0x90, 0x4E, 0xEB, 0x43, 0xEB, 0x58, 0x67,
+0x39, 0xD2, 0x0F, 0xF7, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x10, 0xF0,
+0x00, 0x4A, 0x43, 0xD2, 0x00, 0xF5, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x1E, 0xD0, 0x37, 0xD2, 0x11, 0x67, 0x01, 0xF0, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x00, 0x6B, 0x40, 0x32, 0x1D, 0xD3, 0x38, 0xD2,
+0x33, 0x94, 0x60, 0xF1, 0x13, 0x24, 0x39, 0x95, 0xE0, 0xF1, 0x0C, 0x2D,
+0xA1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x05, 0xF0,
+0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33, 0x60, 0x33, 0x4C, 0xEB, 0x01, 0x5B,
+0x58, 0x67, 0x91, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x35, 0xD2,
+0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x42, 0x32,
+0x42, 0x32, 0xB1, 0xF6, 0x84, 0x40, 0x3D, 0xD3, 0x00, 0x1C, 0xFA, 0x5B,
+0x2E, 0xD2, 0x3D, 0x94, 0x8C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x91, 0xF6,
+0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x2F, 0xD2, 0x3D, 0x95, 0xB1, 0xF6,
+0x8C, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x00, 0x1C, 0xFA, 0x5B,
+0x30, 0xD2, 0x3D, 0x93, 0x2E, 0x94, 0x4C, 0xEB, 0x62, 0x32, 0x20, 0xF1,
+0x00, 0x74, 0x42, 0x32, 0xA0, 0xF2, 0x15, 0x60, 0x2F, 0x95, 0x20, 0xF1,
+0x00, 0x75, 0xA0, 0xF2, 0x10, 0x60, 0x30, 0x93, 0x20, 0x73, 0xA0, 0xF2,
+0x0C, 0x60, 0x20, 0x72, 0x01, 0x6B, 0xA0, 0xF2, 0x08, 0x60, 0x2E, 0x94,
+0x80, 0x74, 0xA0, 0xF2, 0x02, 0x60, 0x2F, 0x95, 0x80, 0x75, 0x80, 0xF2,
+0x1E, 0x60, 0x30, 0x94, 0xE0, 0xF3, 0x00, 0x74, 0x80, 0xF2, 0x19, 0x60,
+0xE0, 0xF3, 0x00, 0x72, 0x01, 0x6A, 0x80, 0xF2, 0x14, 0x60, 0x35, 0x95,
+0x03, 0x25, 0x02, 0x23, 0x20, 0xF4, 0x19, 0x2A, 0x1D, 0x95, 0x01, 0x4D,
+0x0A, 0x5D, 0x1D, 0xD5, 0x97, 0x61, 0x1E, 0x92, 0x01, 0x4A, 0x03, 0x5A,
+0x1E, 0xD2, 0x8A, 0x61, 0x04, 0x90, 0x20, 0xF4, 0x09, 0x28, 0x0C, 0x91,
+0x03, 0x29, 0x14, 0x92, 0xFF, 0x6C, 0x2B, 0x22, 0x90, 0x67, 0x00, 0x18,
+0xA1, 0x5E, 0xB1, 0x67, 0x03, 0x5A, 0x07, 0x60, 0x05, 0x94, 0x00, 0x18,
+0xA1, 0x5E, 0x0D, 0x95, 0x03, 0x5A, 0x00, 0x6C, 0x1E, 0x61, 0x14, 0x93,
+0x90, 0x67, 0xA3, 0x67, 0x00, 0x18, 0xA1, 0x5E, 0x40, 0xD3, 0x03, 0x5A,
+0x07, 0x60, 0x05, 0x94, 0x00, 0x18, 0xA1, 0x5E, 0x15, 0x95, 0x03, 0x5A,
+0x00, 0x6C, 0x0F, 0x61, 0x40, 0x95, 0x00, 0x18, 0xA1, 0x5E, 0x91, 0x67,
+0x03, 0x5A, 0x40, 0xF2, 0x1E, 0x60, 0x0D, 0x94, 0x00, 0x18, 0xA1, 0x5E,
+0x15, 0x95, 0x03, 0x5A, 0x01, 0x6C, 0x40, 0xF2, 0x16, 0x60, 0xFF, 0x74,
+0x40, 0xF2, 0x17, 0x60, 0x04, 0x05, 0x94, 0x34, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0xB1, 0xE4, 0x63, 0xF3, 0x00, 0x49, 0x60, 0x9C,
+0x43, 0x99, 0x00, 0xF4, 0x00, 0x68, 0xE0, 0xF3, 0x1F, 0x6F, 0x0B, 0xE8,
+0xEC, 0xEB, 0x0C, 0xEA, 0x6D, 0xEA, 0x61, 0x9C, 0x02, 0xF0, 0x00, 0x6E,
+0xCB, 0xEE, 0xEC, 0xEB, 0xC0, 0x36, 0xE0, 0xF3, 0x1F, 0x4E, 0x60, 0x33,
+0x68, 0x33, 0xCC, 0xEA, 0xE7, 0xF7, 0x10, 0x6D, 0x6D, 0xEA, 0xAB, 0xED,
+0x62, 0x9C, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0xEC, 0xEB, 0x00, 0xF5,
+0x60, 0x33, 0xAC, 0xEA, 0x6D, 0xEA, 0x43, 0xD9, 0x63, 0x9C, 0x44, 0x99,
+0xEC, 0xEB, 0x0C, 0xEA, 0x6D, 0xEA, 0x64, 0x9C, 0xCC, 0xEA, 0xEC, 0xEB,
+0x60, 0x33, 0x68, 0x33, 0x6D, 0xEA, 0x65, 0x9C, 0xAC, 0xEA, 0xEC, 0xEB,
+0x00, 0xF5, 0x60, 0x33, 0x6D, 0xEA, 0x44, 0xD9, 0x46, 0x9C, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x4A, 0xC9,
+0x47, 0x9C, 0x4B, 0xC9, 0x44, 0x9B, 0x80, 0xF7, 0x42, 0x32, 0x01, 0x72,
+0xC0, 0xF2, 0x1E, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x31,
+0x20, 0x31, 0xE1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x21, 0x95,
+0xD1, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x22, 0x95, 0x71, 0xF6,
+0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x23, 0x95, 0x71, 0xF6, 0x84, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x24, 0x95, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x25, 0x95, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x26, 0x95, 0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x27, 0x95,
+0x81, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x28, 0x95, 0x81, 0xF6,
+0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x29, 0x95, 0x81, 0xF6, 0x8C, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x2A, 0x95, 0xD1, 0xF6, 0x80, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x2B, 0x95, 0xD1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x2C, 0x95, 0x81, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x2D, 0x95,
+0x1F, 0x96, 0x10, 0x6D, 0xA4, 0xED, 0xFF, 0x4D, 0x00, 0x1C, 0x83, 0x45,
+0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42,
+0x01, 0x6C, 0x20, 0x96, 0x10, 0x6D, 0xA4, 0xED, 0xFF, 0x4D, 0x00, 0x1C,
+0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C,
+0xF0, 0x42, 0x00, 0x6C, 0x10, 0x6D, 0xA4, 0xED, 0x1E, 0x6C, 0x00, 0x1C,
+0xAC, 0x45, 0xFF, 0x4D, 0x01, 0x6E, 0x22, 0x67, 0x4D, 0xEE, 0x10, 0x6D,
+0x03, 0x6A, 0x4B, 0xEA, 0xA4, 0xED, 0x4C, 0xEE, 0xFF, 0x4D, 0x00, 0x1C,
+0x83, 0x45, 0x1E, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, 0x10, 0x6D,
+0x03, 0x6A, 0xD1, 0x67, 0xA4, 0xED, 0x1E, 0x6C, 0xFF, 0x4D, 0x00, 0x1C,
+0x83, 0x45, 0x4D, 0xEE, 0x04, 0x63, 0x3E, 0x97, 0x3D, 0x91, 0x3C, 0x90,
+0x00, 0xEF, 0x20, 0x63, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4,
+0x84, 0x40, 0x2A, 0xF4, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x08, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x01, 0xF4, 0x88, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x65, 0x4D, 0x8F, 0xF7, 0x00, 0x6D, 0xAB, 0xED,
+0xA0, 0x35, 0x21, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0xA0, 0x35,
+0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6, 0x80, 0x40,
+0x40, 0xF1, 0x08, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x0D, 0xF0,
+0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6, 0x84, 0x40, 0xA0, 0xF4,
+0x02, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6, 0x8C, 0x40,
+0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2,
+0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x80, 0x40, 0x40, 0xF1,
+0x0D, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x16, 0x6D,
+0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x84, 0x40, 0xA1, 0xF0, 0x1A, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x61, 0xF6, 0x8C, 0x40, 0xC5, 0xF0,
+0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x37, 0x95, 0x41, 0xF6,
+0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x01, 0x4D, 0x38, 0x95, 0x41, 0xF6,
+0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x01, 0x4D, 0x00, 0x1C, 0x2C, 0x1F,
+0x03, 0x6C, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4, 0x84, 0x40,
+0x2A, 0xF4, 0x13, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF4,
+0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0xE4, 0x6D, 0x21, 0xF6, 0x88, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x33, 0x95, 0x39, 0x95, 0x1F, 0xF6, 0x14, 0x25,
+0x21, 0xF0, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xFF, 0x6D,
+0x01, 0x4D, 0xAC, 0xEA, 0x42, 0x32, 0x34, 0xD2, 0x02, 0x22, 0x01, 0x6A,
+0x34, 0xD2, 0xA0, 0x35, 0xA0, 0x35, 0x21, 0xF0, 0x80, 0x41, 0x3A, 0xD5,
+0x00, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95,
+0x21, 0xF0, 0x88, 0x41, 0x00, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4, 0x84, 0x41,
+0x2A, 0xF4, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x08, 0x6D,
+0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x65, 0x4D, 0x43, 0x93, 0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x60, 0x35, 0x3A, 0x95, 0x31, 0xF6, 0x80, 0x41, 0x0F, 0xF4,
+0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x31, 0xF6,
+0x84, 0x41, 0x09, 0xF0, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x02, 0xF0, 0x01, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x31, 0xF6, 0x88, 0x41,
+0x3B, 0xD5, 0x1B, 0xF4, 0x1F, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x3B, 0x95, 0x31, 0xF6, 0x8C, 0x41, 0x11, 0xF4, 0x1F, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35,
+0x41, 0xF6, 0x80, 0x41, 0x00, 0xF1, 0x02, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x0D, 0xF0, 0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6,
+0x84, 0x41, 0xC0, 0xF4, 0x07, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x41, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x61, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x51, 0xF6, 0x80, 0x41, 0x0F, 0xF4,
+0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x51, 0xF6,
+0x84, 0x41, 0x09, 0xF0, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x3B, 0x95, 0x51, 0xF6, 0x88, 0x41, 0x3B, 0xF4, 0x03, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x3B, 0x95, 0x51, 0xF6, 0x8C, 0x41, 0x31, 0xF4,
+0x03, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2, 0x14, 0x6D,
+0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x80, 0x41, 0x00, 0xF1, 0x02, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x16, 0x6D, 0xA0, 0x35,
+0xA0, 0x35, 0x61, 0xF6, 0x84, 0x41, 0x01, 0xF5, 0x07, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x37, 0x95, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x38, 0x95,
+0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, 0x00, 0xF2, 0x00, 0x6A, 0x40, 0x32,
+0x40, 0x32, 0xA2, 0x67, 0x41, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x3C, 0xD2, 0x3C, 0x95, 0x61, 0xF6, 0x8C, 0x41,
+0xC5, 0xF0, 0x11, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6,
+0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x37, 0x95, 0x41, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x38, 0x95, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C,
+0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x31, 0x95, 0x01, 0xF4,
+0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x32, 0x95, 0x21, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D, 0x34, 0x93, 0x1F, 0xF5, 0x1E, 0x2B,
+0x21, 0xF0, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x3A, 0x95, 0x21, 0xF0,
+0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x3A, 0x95, 0x13, 0x15, 0x00, 0x6A,
+0x6A, 0x15, 0x00, 0x6B, 0x56, 0x15, 0xFF, 0x6C, 0xFF, 0x74, 0xBF, 0xF5,
+0x09, 0x61, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34,
+0x41, 0xD4, 0x81, 0xF6, 0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x31, 0x20, 0x31, 0x2C, 0xEA, 0x42, 0x32,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C,
+0x42, 0x32, 0x6C, 0xEA, 0x63, 0x9C, 0x00, 0xF4, 0x00, 0x6D, 0xAB, 0xED,
+0xAC, 0xEB, 0x4D, 0xEB, 0x63, 0xDC, 0x41, 0x94, 0xE0, 0xF3, 0x1F, 0x68,
+0x81, 0xF6, 0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0x6D, 0x63, 0xF3,
+0x00, 0x4C, 0x42, 0x32, 0xAB, 0xED, 0x63, 0x9C, 0x42, 0x32, 0xA0, 0x35,
+0x0C, 0xEA, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x40, 0x32, 0xAC, 0xEB,
+0x48, 0x32, 0x4D, 0xEB, 0x63, 0xDC, 0x41, 0x94, 0xA1, 0xF6, 0x04, 0x4C,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32, 0x42, 0x32,
+0x0C, 0xEA, 0xE7, 0xF7, 0x10, 0x6C, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4,
+0x00, 0x30, 0x63, 0xF3, 0x00, 0x48, 0x8B, 0xEC, 0x63, 0x98, 0x80, 0x34,
+0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB, 0x4D, 0xEB,
+0x63, 0xD8, 0x41, 0x94, 0xA1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x2C, 0xEA, 0x64, 0x98, 0x42, 0x32, 0x00, 0xF4, 0x00, 0x68,
+0xE0, 0xF3, 0x1F, 0x6D, 0x0B, 0xE8, 0x42, 0x32, 0xAC, 0xEA, 0x0C, 0xEB,
+0x4D, 0xEB, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3,
+0x00, 0x4A, 0x64, 0xDA, 0x41, 0x94, 0xE0, 0xF3, 0x1F, 0x68, 0xA1, 0xF6,
+0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0x6D, 0x63, 0xF3,
+0x00, 0x4C, 0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32, 0xAB, 0xED, 0x6C, 0xEA,
+0xA0, 0x35, 0x64, 0x9C, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x40, 0x32,
+0xAC, 0xEB, 0x48, 0x32, 0x4D, 0xEB, 0x64, 0xDC, 0x41, 0x94, 0xA1, 0xF6,
+0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0xE7, 0xF7, 0x10, 0x6D, 0x63, 0xF3, 0x00, 0x4C,
+0x2C, 0xEA, 0xAB, 0xED, 0x64, 0x9C, 0x42, 0x32, 0xA0, 0x35, 0x42, 0x32,
+0xA0, 0x35, 0xFF, 0x4D, 0x0C, 0xEA, 0xAC, 0xEB, 0x00, 0xF5, 0x40, 0x32,
+0x4D, 0xEB, 0x64, 0xDC, 0x41, 0x94, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4,
+0x00, 0x30, 0x63, 0xF3, 0x00, 0x48, 0xC1, 0xF6, 0x04, 0x4C, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x4A, 0xC8,
+0x41, 0x94, 0xC1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x4C, 0xE9, 0x22, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x42, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xC8, 0x44, 0x9B, 0x80, 0xF7,
+0x42, 0x32, 0x01, 0x72, 0x3F, 0xF5, 0x02, 0x60, 0xC9, 0xF7, 0x1B, 0x6A,
+0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x82, 0x67, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4,
+0x00, 0x30, 0x40, 0x6A, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x48, 0x40, 0x32,
+0xC3, 0x98, 0x40, 0x32, 0x8C, 0xEA, 0xE0, 0xF3, 0x1F, 0x6B, 0x80, 0xF5,
+0x42, 0x35, 0xCC, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x6C, 0xEA, 0x04, 0x22,
+0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xE0, 0xF3,
+0x1F, 0x68, 0x12, 0xEA, 0x42, 0x33, 0x0C, 0xEB, 0xC2, 0x30, 0xE0, 0xF3,
+0x1F, 0x6A, 0x0A, 0x30, 0x4C, 0xE8, 0x00, 0xF2, 0x00, 0x6A, 0x0C, 0xEA,
+0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xE8, 0xB8, 0xE8,
+0xE0, 0xF3, 0x1F, 0x6D, 0x12, 0xEA, 0x42, 0x30, 0x3F, 0x6A, 0x4B, 0xEA,
+0xAC, 0xE8, 0x40, 0x32, 0x3F, 0x6D, 0x42, 0xD5, 0x40, 0x32, 0x0C, 0xED,
+0x1F, 0xF4, 0x00, 0x4A, 0xA0, 0x35, 0x4C, 0xEC, 0xA0, 0x35, 0x8D, 0xED,
+0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x91, 0xF4,
+0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x02, 0xF0, 0x00, 0x6B,
+0x60, 0x33, 0x60, 0x33, 0xFF, 0x4B, 0xC0, 0xF3, 0x00, 0x6C, 0x6C, 0xEA,
+0x8C, 0xE8, 0x80, 0xF5, 0x00, 0x33, 0xA2, 0x67, 0x91, 0xF4, 0x84, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0xBD, 0xF7, 0x10, 0x4D, 0x82, 0x67, 0x40, 0x9D, 0x8C, 0xEA, 0x80, 0xF5,
+0x42, 0x35, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3,
+0x00, 0x4A, 0x04, 0x9A, 0xE0, 0xF3, 0x1F, 0x6A, 0x02, 0x33, 0x6A, 0x33,
+0x4C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x6C, 0xEA, 0x04, 0x22, 0x00, 0xF4,
+0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0x00, 0xF5, 0x02, 0x30,
+0x12, 0xEA, 0x42, 0x33, 0xE0, 0xF3, 0x1F, 0x6A, 0x4C, 0xE8, 0x4C, 0xEB,
+0x00, 0xF2, 0x00, 0x6A, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A,
+0x4B, 0xEA, 0x4D, 0xE8, 0xB8, 0xE8, 0xE0, 0xF3, 0x1F, 0x6D, 0x12, 0xEA,
+0x42, 0x30, 0xAC, 0xE8, 0x3F, 0x6A, 0x42, 0x95, 0x4B, 0xEA, 0x40, 0x32,
+0x0C, 0xED, 0x40, 0x32, 0x1F, 0xF4, 0x00, 0x4A, 0x42, 0xD5, 0xA0, 0x35,
+0x4C, 0xEC, 0xA0, 0x35, 0x8D, 0xED, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x6D, 0xED, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7,
+0x14, 0x4B, 0xA0, 0x9B, 0xC0, 0xF3, 0x00, 0x6C, 0x8C, 0xE8, 0x4C, 0xED,
+0x80, 0xF5, 0x00, 0x32, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x4D, 0xED, 0x58, 0x14, 0x0C, 0x91, 0xDF, 0xF3, 0x19, 0x10, 0x1E, 0x93,
+0x04, 0x04, 0x74, 0x32, 0x91, 0xE2, 0x3E, 0xD4, 0x91, 0xF6, 0x84, 0x40,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33,
+0x60, 0x33, 0x3E, 0x95, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x3F, 0xD3,
+0x91, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x40, 0xDD, 0x3F, 0x93,
+0x3E, 0x94, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x41, 0xDC, 0xA1, 0xF6,
+0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x95, 0x3E, 0x93,
+0xA1, 0xF6, 0x8C, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x00, 0x1C,
+0xFA, 0x5B, 0x42, 0xDB, 0x3F, 0x94, 0x3E, 0x95, 0x8C, 0xEA, 0x42, 0x32,
+0x42, 0x32, 0xB1, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x43, 0xDD,
+0x3F, 0x93, 0x3E, 0x94, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x44, 0xDC,
+0xB1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x95,
+0x3E, 0x93, 0xC1, 0xF6, 0x84, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32,
+0x00, 0x1C, 0xFA, 0x5B, 0x45, 0xDB, 0x3F, 0x94, 0x3E, 0x95, 0x8C, 0xEA,
+0x42, 0x32, 0x42, 0x32, 0xC1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B,
+0x46, 0xDD, 0x3F, 0x93, 0x3E, 0x94, 0x4C, 0xEB, 0x62, 0x32, 0x42, 0x32,
+0x47, 0xDC, 0x7F, 0xF3, 0x0E, 0x10, 0x00, 0x00, 0xFB, 0x63, 0x07, 0xD1,
+0x0C, 0xF0, 0x00, 0x6A, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31,
+0x63, 0xF3, 0x00, 0x49, 0x08, 0x62, 0x0A, 0xD4, 0x06, 0xD0, 0x4B, 0xEA,
+0x62, 0x99, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0xC9, 0xF7,
+0x1B, 0x6C, 0x04, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x8B, 0xEC, 0x40, 0x32,
+0x80, 0x34, 0x4D, 0xEB, 0x80, 0x34, 0x62, 0xD9, 0x04, 0xD4, 0x81, 0xF6,
+0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B,
+0x60, 0x30, 0x00, 0x30, 0x0C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x6C, 0xEA,
+0x63, 0x99, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x4D, 0xEB,
+0x63, 0xD9, 0x04, 0x94, 0x81, 0xF6, 0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x10, 0x6C, 0xE0, 0xF3, 0x1F, 0x6B,
+0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x63, 0x99, 0x80, 0x34,
+0xE0, 0xF3, 0x1F, 0x4C, 0x40, 0x32, 0x48, 0x32, 0x8C, 0xEB, 0x4D, 0xEB,
+0x63, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x04, 0x4C, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE7, 0xF7, 0x10, 0x6C, 0xE0, 0xF3,
+0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x63, 0x99,
+0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB, 0x4D, 0xEB,
+0x63, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32,
+0x6C, 0xEA, 0x64, 0x99, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB,
+0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x14, 0x4C, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x10, 0x6C, 0xE0, 0xF3,
+0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x64, 0x99,
+0x80, 0x34, 0xE0, 0xF3, 0x1F, 0x4C, 0x40, 0x32, 0x48, 0x32, 0x8C, 0xEB,
+0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x1C, 0x4C, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE7, 0xF7, 0x10, 0x6C,
+0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34,
+0x64, 0x99, 0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB,
+0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xC1, 0xF6, 0x04, 0x4C, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x4A, 0xC9,
+0x04, 0x94, 0xC1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x4C, 0xE8, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32, 0x40, 0x32, 0x0A, 0x93,
+0x80, 0x4A, 0x02, 0x30, 0x80, 0x4A, 0x02, 0x30, 0x6C, 0xEA, 0x0B, 0xC9,
+0x14, 0x22, 0x1F, 0xF7, 0x00, 0x6A, 0x0A, 0x94, 0x4C, 0xEB, 0x62, 0x33,
+0xC0, 0xF2, 0x63, 0xC1, 0x82, 0x33, 0x4C, 0xEB, 0x62, 0x33, 0xC0, 0xF2,
+0x67, 0xC1, 0x00, 0x18, 0x0A, 0x5F, 0x00, 0x65, 0x08, 0x97, 0x07, 0x91,
+0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0x12, 0x6A, 0xC0, 0xF2, 0x43, 0xC1,
+0xC0, 0xF2, 0x47, 0xC1, 0x00, 0x18, 0x0A, 0x5F, 0x00, 0x65, 0x08, 0x97,
+0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0xC9, 0xF7, 0x1B, 0x6A,
+0xFB, 0x63, 0x4B, 0xEA, 0x06, 0xD0, 0x40, 0x30, 0x07, 0xD1, 0x08, 0x62,
+0x00, 0x30, 0x40, 0xF0, 0x4C, 0xA0, 0x03, 0x69, 0x4C, 0xE9, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x62, 0x67, 0x04, 0xD2, 0x63, 0xF3,
+0x00, 0x4B, 0xC3, 0xF3, 0x41, 0xA3, 0x2E, 0xEA, 0x1A, 0x22, 0x05, 0x29,
+0xE0, 0xF2, 0x66, 0xA3, 0xFF, 0x6A, 0x4C, 0xEB, 0x1A, 0x23, 0x04, 0x92,
+0xC9, 0xF7, 0x17, 0x6C, 0x8B, 0xEC, 0x63, 0xF3, 0x00, 0x4A, 0x04, 0xD2,
+0xC3, 0xF3, 0x21, 0xC2, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x76, 0x9A, 0x80, 0x34, 0x80, 0x34, 0x60, 0xDC, 0x57, 0x9A,
+0x41, 0xDC, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF,
+0x05, 0x63, 0x51, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x1C, 0x6D,
+0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x1C, 0x6D, 0xDB, 0x17,
+0xF9, 0x63, 0x0A, 0xD0, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x00, 0x30,
+0x00, 0x30, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x0B, 0xD1,
+0xA1, 0xF5, 0x82, 0x40, 0x22, 0x67, 0x63, 0xF3, 0x00, 0x49, 0x0C, 0x62,
+0x00, 0x1C, 0xFD, 0x5B, 0x06, 0xD2, 0xC0, 0xF2, 0x58, 0xC9, 0xA1, 0xF5,
+0x84, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65, 0xC0, 0xF2, 0x5A, 0xC9,
+0xA1, 0xF5, 0x86, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65, 0xC0, 0xF2,
+0x5C, 0xC9, 0xA1, 0xF5, 0x88, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65,
+0x82, 0x67, 0xC0, 0xF2, 0x7A, 0xA9, 0xC0, 0xF2, 0x5E, 0xC9, 0xC0, 0xF2,
+0x58, 0xA9, 0x69, 0xE2, 0xC0, 0xF2, 0x7C, 0xA9, 0x69, 0xE2, 0x51, 0xE4,
+0x04, 0xD4, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65,
+0x00, 0xF6, 0x40, 0x35, 0x00, 0xF6, 0xA3, 0x35, 0x40, 0x6A, 0xFF, 0x6B,
+0x4D, 0xED, 0x6C, 0xED, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0x05, 0xD3, 0x51, 0xF2, 0x8B, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65,
+0x40, 0x32, 0x51, 0xF2, 0x8C, 0x40, 0xE0, 0xF2, 0x44, 0xC9, 0x00, 0x1C,
+0x00, 0x5C, 0x00, 0x65, 0xE0, 0xF2, 0x64, 0xA9, 0x61, 0xF4, 0x84, 0x40,
+0x75, 0xE2, 0x04, 0x93, 0xFF, 0xF7, 0x1F, 0x6A, 0xE0, 0xF2, 0xA4, 0xC9,
+0x4C, 0xED, 0x69, 0xE5, 0xE0, 0xF2, 0x40, 0xD9, 0xFF, 0xF7, 0x1F, 0x6A,
+0x00, 0x1C, 0xE6, 0x5B, 0x4C, 0xED, 0x43, 0xA9, 0xFF, 0xF7, 0x1F, 0x6B,
+0x6C, 0xEA, 0x10, 0x52, 0x05, 0x60, 0xE0, 0xF2, 0x40, 0x99, 0x1F, 0x5A,
+0xA0, 0xF0, 0x1E, 0x61, 0x00, 0x6A, 0xC0, 0xF2, 0x54, 0xC1, 0xC0, 0xF2,
+0x55, 0xA1, 0x05, 0x93, 0x01, 0x4A, 0x4C, 0xEB, 0x03, 0x53, 0xA0, 0xF0,
+0x0B, 0x60, 0xC0, 0xF2, 0x55, 0xC1, 0x06, 0x94, 0x00, 0x6A, 0x11, 0x6B,
+0x63, 0xF3, 0x00, 0x4C, 0x43, 0xCC, 0xE0, 0xF2, 0x44, 0xCC, 0x40, 0x9C,
+0x6C, 0xEA, 0x01, 0x72, 0x80, 0xF0, 0x13, 0x61, 0xE0, 0xF2, 0x44, 0x9C,
+0x03, 0x6B, 0x00, 0xF7, 0x42, 0x32, 0x6C, 0xEA, 0x80, 0xF0, 0x0B, 0x2A,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF0,
+0x4C, 0xA2, 0x4C, 0xEB, 0x01, 0x73, 0xA0, 0xF0, 0x04, 0x60, 0x06, 0x94,
+0x63, 0xF3, 0x00, 0x4C, 0xE0, 0xF2, 0x46, 0xA4, 0xA0, 0xF0, 0x0B, 0x2A,
+0x40, 0x9C, 0x01, 0x6B, 0x56, 0x32, 0x6C, 0xEA, 0xA0, 0xF0, 0x05, 0x22,
+0x3E, 0x6A, 0xC0, 0xF2, 0x50, 0xC4, 0x1C, 0x6A, 0xC0, 0xF2, 0x51, 0xC4,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF0,
+0x6C, 0xA2, 0xFF, 0x6A, 0x6C, 0xEA, 0x03, 0x6B, 0x6C, 0xEA, 0x61, 0x22,
+0x66, 0xF7, 0x4C, 0x9C, 0xFF, 0xF7, 0x1F, 0x72, 0x5C, 0x60, 0xE0, 0xF2,
+0x40, 0x9C, 0xE0, 0xF3, 0x09, 0x5A, 0x00, 0xF1, 0x03, 0x61, 0xC0, 0xF2,
+0x72, 0xA4, 0x00, 0xF6, 0x60, 0x32, 0x00, 0xF6, 0x43, 0x32, 0xFE, 0x4A,
+0xFF, 0xF7, 0x1C, 0x52, 0x04, 0x6A, 0x4B, 0xEA, 0x01, 0x61, 0x4E, 0x43,
+0xC0, 0xF2, 0x52, 0xC4, 0x06, 0x96, 0x7F, 0x6B, 0x63, 0xF3, 0x00, 0x4E,
+0x66, 0xF7, 0x4C, 0x9E, 0xC0, 0xF2, 0x8E, 0xA6, 0x52, 0x32, 0x6C, 0xEA,
+0xA7, 0x42, 0xC0, 0xF2, 0x52, 0xA6, 0x03, 0x4D, 0xFF, 0x6B, 0x4B, 0xE5,
+0x00, 0xF6, 0x40, 0x35, 0x43, 0x67, 0x00, 0xF6, 0xA3, 0x35, 0x8C, 0xEA,
+0xA2, 0xEA, 0xE0, 0xF0, 0x0C, 0x60, 0x00, 0xF6, 0x80, 0x35, 0x00, 0xF6,
+0xA3, 0x35, 0x06, 0x92, 0x63, 0xF3, 0x00, 0x4A, 0x06, 0xD2, 0xE0, 0xF2,
+0x40, 0x9A, 0x04, 0xF7, 0x11, 0x5A, 0xC0, 0xF0, 0x01, 0x61, 0x32, 0x55,
+0xA0, 0xF0, 0x1E, 0x60, 0x32, 0x6D, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA,
+0x40, 0x32, 0x40, 0x32, 0x21, 0xF4, 0x10, 0x4A, 0x44, 0x6B, 0xC9, 0xF7,
+0x1B, 0x68, 0x0B, 0xE8, 0x60, 0xC2, 0x00, 0x30, 0xFF, 0x6A, 0xAC, 0xEA,
+0x00, 0x30, 0xA2, 0x67, 0x51, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0x08, 0xD2, 0x08, 0x92, 0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0xA2, 0x67, 0x00, 0x18, 0x08, 0x61, 0x00, 0x65, 0x0C, 0x97, 0x0B, 0x91,
+0x0A, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x07, 0x63, 0x03, 0x6A, 0xC0, 0xF2,
+0x55, 0xC1, 0x40, 0x99, 0x08, 0x6B, 0x6D, 0xEA, 0x40, 0xD9, 0x4F, 0x17,
+0x00, 0x6A, 0xC0, 0xF2, 0x55, 0xC1, 0xC0, 0xF2, 0x54, 0xA1, 0x05, 0x93,
+0x01, 0x4A, 0x4C, 0xEB, 0x03, 0x53, 0x14, 0x61, 0x03, 0x6A, 0xC0, 0xF2,
+0x54, 0xC1, 0x40, 0x99, 0x09, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x40, 0xD9,
+0x3C, 0x17, 0xE0, 0xF2, 0x66, 0xA4, 0xFF, 0x6A, 0x4C, 0xEB, 0x5F, 0xF7,
+0x16, 0x2B, 0x01, 0x6A, 0x4B, 0xEA, 0xE0, 0xF2, 0x46, 0xC4, 0x51, 0x17,
+0xC0, 0xF2, 0x54, 0xC1, 0x2E, 0x17, 0x06, 0x90, 0xFF, 0x6D, 0x63, 0xF3,
+0x00, 0x48, 0xE0, 0xF2, 0x46, 0xA0, 0xAA, 0xEA, 0xC6, 0x61, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x41, 0xF4, 0x10, 0x4C,
+0x00, 0x1C, 0x00, 0x5C, 0x09, 0xD5, 0x09, 0x95, 0x00, 0xF6, 0x40, 0x31,
+0x00, 0xF6, 0x23, 0x31, 0x7F, 0x6A, 0xAC, 0xE9, 0x4C, 0xE9, 0xE0, 0xF2,
+0x60, 0x98, 0xC0, 0xF2, 0x48, 0xA8, 0xFF, 0xF7, 0x1F, 0x6C, 0x43, 0xEB,
+0x38, 0x61, 0xC0, 0xF2, 0x4A, 0xA8, 0x8C, 0xEA, 0x43, 0xEB, 0x07, 0x61,
+0xC0, 0xF2, 0x4C, 0xA8, 0x8C, 0xEA, 0x43, 0xEB, 0x69, 0x60, 0x01, 0x49,
+0xAC, 0xE9, 0x06, 0x93, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2, 0x50, 0xA3,
+0x23, 0xEA, 0x32, 0x60, 0x22, 0x67, 0x06, 0x93, 0x63, 0xF3, 0x00, 0x4B,
+0x06, 0xD3, 0xE0, 0xF2, 0x40, 0x9B, 0x04, 0xF7, 0x11, 0x5A, 0x1D, 0x61,
+0x32, 0x69, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x21, 0xF4, 0x10, 0x4A, 0x44, 0x6B, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8,
+0x00, 0x30, 0x00, 0x30, 0x51, 0xF4, 0x80, 0x40, 0xB1, 0x67, 0x60, 0xC2,
+0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C,
+0xF0, 0x5B, 0xB1, 0x67, 0x74, 0x17, 0xFF, 0x49, 0xD1, 0x17, 0x3A, 0x59,
+0xE2, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x21, 0xF4, 0x10, 0x4A, 0x48, 0x6B, 0xE1, 0x17, 0xC0, 0xF2, 0x71, 0xA3,
+0xFF, 0x6A, 0x4C, 0xEB, 0x63, 0xE9, 0xC9, 0x60, 0x23, 0x67, 0xC7, 0x17,
+0x3A, 0x55, 0x5F, 0xF7, 0x00, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA,
+0x40, 0x32, 0x40, 0x32, 0x21, 0xF4, 0x10, 0x4A, 0x48, 0x6B, 0x3F, 0x17,
+0x80, 0xF1, 0x10, 0x5A, 0x1F, 0xF7, 0x08, 0x60, 0xC0, 0xF2, 0x72, 0xA4,
+0x00, 0xF6, 0x60, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x02, 0x4A, 0x0D, 0x52,
+0x0C, 0x6A, 0xFF, 0xF6, 0x1B, 0x60, 0x42, 0x43, 0xF9, 0x16, 0xC0, 0xF2,
+0x4F, 0xA6, 0x4C, 0xEB, 0x62, 0xED, 0x1F, 0xF7, 0x12, 0x60, 0x00, 0xF6,
+0x40, 0x35, 0x0D, 0x17, 0x02, 0x49, 0x96, 0x17, 0xFB, 0x63, 0x06, 0xD0,
+0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40, 0xFF, 0xF0, 0x10, 0x6E,
+0x15, 0x6C, 0x08, 0x62, 0x00, 0x1C, 0x83, 0x45, 0x07, 0xD1, 0x00, 0x1C,
+0x5B, 0x1F, 0x64, 0x6C, 0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x6E, 0x00, 0x1C,
+0x83, 0x45, 0xAF, 0x40, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x04, 0xD2, 0x63, 0xF3, 0x40, 0x9A,
+0x01, 0x6B, 0x4E, 0x32, 0x6C, 0xEA, 0x0A, 0x22, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3,
+0x01, 0x72, 0x1C, 0x61, 0x04, 0x92, 0x63, 0xF3, 0x20, 0x9A, 0x01, 0x6A,
+0x2E, 0x31, 0x4C, 0xE9, 0x09, 0x29, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x5A, 0x2A,
+0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x63, 0xF3, 0x00, 0x4B,
+0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63,
+0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x31, 0x24, 0xF2, 0x02, 0x68,
+0x20, 0x31, 0x00, 0x30, 0x01, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0x02, 0x6D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x41, 0x24, 0xF2,
+0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF6, 0x84, 0x41,
+0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6,
+0x80, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x11, 0xF6, 0x84, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x11, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, 0x8C, 0x41, 0x24, 0xF2, 0xA2, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x01, 0x6B, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0x67, 0xC2,
+0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x63, 0xF3, 0x00, 0x4B,
+0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63,
+0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x00, 0xF3, 0xB4, 0x9B, 0x00, 0x30,
+0x00, 0x30, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A,
+0x00, 0xF3, 0xB4, 0x9A, 0x01, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0x00, 0xF3, 0xB8, 0x9B, 0x01, 0xF6, 0x88, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0xB4, 0x9A, 0x11, 0xF6, 0x80, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0xB4, 0x9B, 0x11, 0xF6,
+0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0xB4, 0x9A,
+0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3,
+0xB4, 0x9B, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A,
+0x00, 0xF3, 0x27, 0xC2, 0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90,
+0x63, 0xF3, 0x00, 0x4B, 0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3,
+0x00, 0xEF, 0x05, 0x63, 0xFB, 0x63, 0x06, 0xD0, 0x02, 0xF0, 0x00, 0x68,
+0x00, 0x30, 0xAF, 0x40, 0xFF, 0xF0, 0x10, 0x6E, 0x15, 0x6C, 0x08, 0x62,
+0x00, 0x1C, 0x83, 0x45, 0x07, 0xD1, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x6E, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40,
+0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x05, 0xD2, 0x63, 0xF3, 0x40, 0x9A, 0x01, 0x6B, 0x4E, 0x32,
+0x6C, 0xEA, 0x0A, 0x22, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x01, 0x72, 0x1D, 0x61,
+0x05, 0x92, 0x63, 0xF3, 0x20, 0x9A, 0x01, 0x6A, 0x2E, 0x31, 0x4C, 0xE9,
+0x09, 0x29, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x5C, 0x2A, 0x05, 0x92, 0x08, 0x97,
+0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2, 0x05, 0x93, 0x06, 0x90,
+0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x31, 0x24, 0xF2, 0x02, 0x68, 0x20, 0x31,
+0x00, 0x30, 0x01, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0x02, 0x6D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x41, 0x24, 0xF2, 0xA2, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF6, 0x84, 0x41, 0x24, 0xF2,
+0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, 0x80, 0x41,
+0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6,
+0x84, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x11, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x11, 0xF6, 0x8C, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x01, 0x6B, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0x67, 0xC2, 0x05, 0x92,
+0x08, 0x97, 0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2, 0x05, 0x93,
+0x06, 0x90, 0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63,
+0xC9, 0xF7, 0x1B, 0x68, 0x02, 0xF0, 0x10, 0x6A, 0x0B, 0xE8, 0x40, 0x32,
+0x40, 0x32, 0x00, 0x30, 0xA2, 0x67, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x40,
+0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x04, 0xD2, 0x04, 0x95,
+0x01, 0xF6, 0x84, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x01, 0xF6, 0x88, 0x40, 0x02, 0xF0, 0x10, 0x6D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6, 0x80, 0x40, 0x02, 0xF0,
+0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6,
+0x84, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x04, 0x95, 0x11, 0xF6, 0x88, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6, 0x8C, 0x40, 0x02, 0xF0,
+0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x27, 0xC3,
+0x05, 0x92, 0x08, 0x97, 0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2,
+0x05, 0x93, 0x06, 0x90, 0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF,
+0x05, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x05, 0xD1, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0x06, 0x62, 0x04, 0xD0, 0x63, 0xF3, 0x00, 0x49,
+0x00, 0xF3, 0xCC, 0x99, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40,
+0x00, 0x1C, 0x83, 0x45, 0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x00, 0xF3, 0xD0, 0x99, 0x1A, 0x6C, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40,
+0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0xF3, 0x44, 0xA1, 0x0E, 0x2A,
+0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x01, 0xF6,
+0x00, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x6C, 0x99,
+0x6E, 0xEA, 0x36, 0x22, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0xE0, 0xF2,
+0xA8, 0x99, 0x00, 0x30, 0x00, 0x30, 0x01, 0xF6, 0x88, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xAC, 0x99, 0x01, 0xF6, 0x80, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB0, 0x99, 0x01, 0xF6,
+0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB4, 0x99,
+0x11, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2,
+0xB8, 0x99, 0x11, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0xE0, 0xF2, 0xBC, 0x99, 0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x00, 0xF3, 0xA0, 0x99, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0x6B,
+0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3, 0x67, 0xC2, 0x00, 0xEF,
+0x04, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x05, 0xD1, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0x06, 0x62, 0x04, 0xD0, 0x63, 0xF3, 0x00, 0x49,
+0x00, 0xF3, 0xCC, 0x99, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40,
+0x00, 0x1C, 0x83, 0x45, 0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x00, 0xF3, 0xD0, 0x99, 0x1A, 0x6C, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40,
+0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0xF3, 0x44, 0xA1, 0x03, 0x72,
+0x5B, 0x60, 0xE0, 0xF2, 0xAC, 0x99, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA,
+0x40, 0x30, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xE0, 0xF2, 0xB0, 0x99, 0x01, 0xF6, 0x84, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB4, 0x99, 0x11, 0xF6, 0x80, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB8, 0x99, 0x11, 0xF6,
+0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xBC, 0x99,
+0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF3,
+0xA0, 0x99, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x00, 0xF3, 0x48, 0x99, 0xE0, 0xF2, 0x68, 0x99, 0x55, 0xE3, 0x1F, 0xF7,
+0x00, 0x6A, 0xAC, 0xEA, 0x07, 0xF7, 0x01, 0x5A, 0x16, 0x60, 0x01, 0xF6,
+0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3,
+0x00, 0x4A, 0x03, 0x6B, 0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3,
+0x67, 0xC2, 0x00, 0xEF, 0x04, 0x63, 0xFF, 0x6A, 0x01, 0x4A, 0x4B, 0xEA,
+0x40, 0x32, 0xE0, 0xF0, 0x1F, 0x4A, 0x4C, 0xED, 0x07, 0xF7, 0x00, 0x6A,
+0x4D, 0xED, 0xDF, 0x17, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34,
+0x80, 0x34, 0x01, 0xF6, 0x00, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0xE0, 0xF2, 0xAC, 0x99, 0xAA, 0xEA, 0x99, 0x61, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3,
+0x00, 0x4A, 0x03, 0x6B, 0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3,
+0x67, 0xC2, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x40, 0x9B, 0x10, 0x6B, 0xFB, 0x63,
+0x6D, 0xEA, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x40, 0xDB, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x07, 0xD1, 0x40, 0x31,
+0x20, 0x31, 0x51, 0xF4, 0x80, 0x41, 0x08, 0x62, 0x00, 0x1C, 0x00, 0x5C,
+0x06, 0xD0, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x51, 0xF4,
+0x80, 0x41, 0x1A, 0x6D, 0x00, 0x1C, 0xF0, 0x5B, 0x04, 0xD2, 0xF1, 0xF0,
+0x88, 0x41, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0x04, 0x93, 0x00, 0xF6,
+0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x49, 0xE3, 0x08, 0x42, 0x9A, 0x48,
+0xBF, 0xF7, 0x1B, 0x50, 0x09, 0x61, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x43, 0xAB, 0x01, 0x4A, 0x43, 0xCB,
+0x04, 0x95, 0xFF, 0x6A, 0x51, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xF0, 0x5B,
+0x4C, 0xED, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x40, 0x9B, 0x11, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x40, 0xDB, 0x0B, 0xED, 0xFF, 0x6A,
+0x91, 0xF4, 0x82, 0x41, 0x00, 0x1C, 0xF0, 0x5B, 0x4C, 0xED, 0x08, 0x97,
+0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x05, 0x63, 0x00, 0x00,
+0xF9, 0x63, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0x0C, 0x62, 0x0B, 0xD1, 0x0A, 0xD0, 0x66, 0xF7, 0x4C, 0x9B,
+0x52, 0x32, 0x05, 0xD2, 0x05, 0x94, 0x7F, 0x6A, 0x4C, 0xEC, 0x05, 0xD4,
+0x00, 0xF3, 0x44, 0xA3, 0x06, 0xD2, 0x40, 0x9B, 0x84, 0x6B, 0x6C, 0xEA,
+0x80, 0x72, 0x2A, 0x61, 0x06, 0x93, 0x01, 0x73, 0x02, 0x60, 0x04, 0x73,
+0x1B, 0x61, 0x02, 0xF0, 0x00, 0x68, 0x00, 0xF2, 0x00, 0x6E, 0x00, 0x30,
+0xC0, 0x36, 0xAF, 0x40, 0xF3, 0xF0, 0x14, 0x4E, 0x00, 0x1C, 0x83, 0x45,
+0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0xFF, 0x6E, 0x01, 0x4E,
+0xC0, 0x36, 0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x4E, 0x00, 0x1C, 0x83, 0x45,
+0xAF, 0x40, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x01, 0x6A, 0x4B, 0xEA,
+0x00, 0xF3, 0x44, 0xC3, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x30,
+0x00, 0x30, 0x40, 0xF0, 0x6C, 0xA0, 0x03, 0x6A, 0x6C, 0xEA, 0x0A, 0x22,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x40, 0x9C,
+0x01, 0x6B, 0x5E, 0x32, 0x6C, 0xEA, 0x7C, 0x22, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x00, 0xF3, 0x44, 0x9C,
+0xFF, 0xF7, 0x1F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x16, 0x2A, 0xC9, 0xF7,
+0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x04, 0x4A,
+0x40, 0x9A, 0x0D, 0x72, 0x58, 0x61, 0x46, 0x6A, 0x00, 0xF3, 0x5C, 0xC4,
+0x41, 0x6A, 0x00, 0xF3, 0x5D, 0xC4, 0x40, 0x6A, 0x00, 0xF3, 0x5E, 0xC4,
+0x3B, 0x6A, 0x00, 0xF3, 0x5F, 0xC4, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4,
+0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0xE4, 0xF4, 0xB8, 0x99, 0xC9, 0xF7,
+0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x30, 0xFF, 0x6E, 0xB2, 0x35, 0x00, 0x30,
+0xCC, 0xED, 0x61, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x08, 0xD6,
+0x60, 0x99, 0x84, 0x6A, 0x08, 0x96, 0x6C, 0xEA, 0x84, 0x72, 0x2B, 0x61,
+0xE4, 0xF4, 0x58, 0x99, 0xFF, 0xF7, 0x1F, 0x72, 0x26, 0x60, 0x76, 0x32,
+0x01, 0x6B, 0x6C, 0xEA, 0x22, 0x22, 0x40, 0xF0, 0x4C, 0xA0, 0x03, 0x6B,
+0xCC, 0xEA, 0x6C, 0xEA, 0x1C, 0x22, 0x06, 0x92, 0x6A, 0xEA, 0xA0, 0xF0,
+0x13, 0x60, 0x04, 0x52, 0xA0, 0xF0, 0x1B, 0x60, 0xC0, 0xF0, 0x18, 0x22,
+0x01, 0x72, 0x11, 0x61, 0x00, 0xF3, 0x5C, 0xA1, 0x05, 0x93, 0xCC, 0xEA,
+0x43, 0xEB, 0xC0, 0xF0, 0x0B, 0x60, 0x00, 0xF3, 0x5F, 0xA1, 0x05, 0x94,
+0xCC, 0xEA, 0x83, 0xEA, 0xA0, 0xF0, 0x1A, 0x61, 0x00, 0x18, 0x96, 0x29,
+0x00, 0x65, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90, 0x00, 0x6A, 0x00, 0xEF,
+0x07, 0x63, 0x4A, 0x6A, 0x00, 0xF3, 0x5C, 0xC4, 0x45, 0x6A, 0x00, 0xF3,
+0x5D, 0xC4, 0x46, 0x6A, 0x00, 0xF3, 0x5E, 0xC4, 0x40, 0x6A, 0x00, 0xF3,
+0x5F, 0xC4, 0xA7, 0x17, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x0E, 0x2A, 0x11, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x27, 0xF7, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x27, 0xF7,
+0x1F, 0x4B, 0x6E, 0xEA, 0x7F, 0xF7, 0x10, 0x22, 0x9D, 0x67, 0x00, 0x1C,
+0x8A, 0x40, 0x10, 0x4C, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31,
+0x01, 0xF6, 0x88, 0x40, 0x63, 0xF3, 0x00, 0x49, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0xE0, 0xF2, 0x48, 0xD9, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x4C, 0xD9, 0x01, 0xF6, 0x84, 0x40,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x50, 0xD9, 0x11, 0xF6,
+0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x54, 0xD9,
+0x11, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2,
+0x58, 0xD9, 0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0xE0, 0xF2, 0x5C, 0xD9, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x65, 0x00, 0xF3, 0x40, 0xD9, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0xFF, 0x6B, 0x6C, 0xEA, 0x22, 0x72,
+0x02, 0x60, 0x92, 0x72, 0x1A, 0x61, 0x01, 0xF0, 0x8D, 0x40, 0x00, 0x1C,
+0x00, 0x5C, 0x00, 0x65, 0x0F, 0x6B, 0x4C, 0xEB, 0x0F, 0x6A, 0x6E, 0xEA,
+0xFF, 0x6C, 0x8C, 0xEA, 0x08, 0x5B, 0xA1, 0x42, 0x0C, 0x61, 0xA0, 0x34,
+0x80, 0x33, 0x00, 0xF6, 0xA0, 0x32, 0x6D, 0xEA, 0x8D, 0xEA, 0xAD, 0xEA,
+0xAD, 0xEC, 0x00, 0xF3, 0x54, 0xD9, 0x00, 0xF3, 0x98, 0xD9, 0x9D, 0x67,
+0x00, 0x1C, 0x90, 0x40, 0x10, 0x4C, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x40, 0x9B, 0x80, 0x6B, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x6D, 0xEA, 0x63, 0xF3, 0x40, 0xDC, 0xFC, 0x16,
+0x20, 0xF3, 0x40, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x43, 0xEB, 0x5F, 0xF7,
+0x1B, 0x60, 0x00, 0x18, 0xD2, 0x29, 0x00, 0x65, 0x5A, 0x17, 0x06, 0x93,
+0x04, 0x73, 0x12, 0x60, 0xFF, 0x73, 0x5F, 0xF7, 0x14, 0x61, 0x00, 0xF3,
+0x5E, 0xA1, 0x05, 0x94, 0xCC, 0xEA, 0x43, 0xEC, 0x24, 0x61, 0x00, 0xF3,
+0x5C, 0xA1, 0xCC, 0xEA, 0x43, 0xEC, 0x0A, 0x60, 0x00, 0x18, 0x1E, 0x29,
+0x00, 0x65, 0x45, 0x17, 0x00, 0xF3, 0x5D, 0xA1, 0x05, 0x94, 0xCC, 0xEA,
+0x83, 0xEA, 0xF6, 0x60, 0x00, 0x18, 0x9B, 0x28, 0x00, 0x65, 0x3B, 0x17,
+0x00, 0xF3, 0x5E, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x43, 0xEB, 0xEC, 0x60,
+0x20, 0xF3, 0x41, 0xA1, 0x05, 0x94, 0xCC, 0xEA, 0x83, 0xEA, 0x3F, 0xF7,
+0x0B, 0x61, 0x00, 0x18, 0xD2, 0x29, 0x00, 0x65, 0x2A, 0x17, 0x20, 0xF3,
+0x41, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x63, 0xEA, 0xF6, 0x60, 0x20, 0x17,
+0xFB, 0x63, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x07, 0xD1,
+0x26, 0x67, 0x06, 0xD0, 0x08, 0x62, 0x63, 0xF3, 0x00, 0x49, 0x66, 0xF7,
+0x8C, 0x99, 0x7F, 0x6A, 0x92, 0x30, 0x4C, 0xE8, 0xE0, 0xF2, 0x46, 0xA1,
+0x0F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35,
+0x40, 0xF0, 0x4C, 0xA5, 0xFF, 0x6B, 0x6C, 0xEA, 0x03, 0x6B, 0x6C, 0xEA,
+0x03, 0x22, 0xFF, 0xF7, 0x1F, 0x74, 0x06, 0x61, 0x08, 0x97, 0x07, 0x91,
+0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x05, 0x63, 0x01, 0xF0, 0x80, 0x45,
+0x04, 0xD5, 0x00, 0x1C, 0x00, 0x5C, 0x05, 0xD6, 0x01, 0x6B, 0x6C, 0xEA,
+0x04, 0x95, 0x05, 0x96, 0x2C, 0x22, 0x4B, 0x58, 0x06, 0x61, 0xC0, 0xF2,
+0x53, 0xA1, 0xFF, 0x6C, 0x8C, 0xEA, 0x6A, 0xEA, 0x74, 0x61, 0x48, 0x40,
+0xE0, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x1E, 0x5A, 0x07, 0x60, 0x86, 0x67,
+0x63, 0xF3, 0x00, 0x4C, 0xC0, 0xF2, 0x53, 0xA4, 0x6C, 0xEA, 0x43, 0x2A,
+0x23, 0x58, 0xD8, 0x60, 0x66, 0x67, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2,
+0x53, 0xA3, 0x02, 0x72, 0xD1, 0x60, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC,
+0x80, 0x34, 0x02, 0x6A, 0x80, 0x34, 0xC0, 0xF2, 0x53, 0xC3, 0x81, 0xF4,
+0x07, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x6D, 0xC3, 0x17, 0x4B, 0x58,
+0x06, 0x61, 0xC0, 0xF2, 0x53, 0xA1, 0xFF, 0x6C, 0x8C, 0xEA, 0x01, 0x72,
+0x40, 0x61, 0x48, 0x40, 0xE0, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x1E, 0x5A,
+0x07, 0x60, 0x86, 0x67, 0x63, 0xF3, 0x00, 0x4C, 0xC0, 0xF2, 0x53, 0xA4,
+0x6C, 0xEA, 0x25, 0x2A, 0x23, 0x58, 0xAC, 0x60, 0x66, 0x67, 0x63, 0xF3,
+0x00, 0x4B, 0xC0, 0xF2, 0x53, 0xA3, 0x02, 0x72, 0xA5, 0x60, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x02, 0x6A, 0x80, 0x34, 0xC0, 0xF2,
+0x53, 0xC3, 0x21, 0xF4, 0x10, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x42, 0x6D,
+0x97, 0x17, 0x00, 0x6A, 0xC0, 0xF2, 0x53, 0xC4, 0xC9, 0xF7, 0x1B, 0x6C,
+0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x07, 0x4C, 0x00, 0x1C,
+0xF0, 0x5B, 0x20, 0x6D, 0x89, 0x17, 0x00, 0x6A, 0xC0, 0xF2, 0x53, 0xC4,
+0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x21, 0xF4,
+0x10, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x44, 0x6D, 0x7B, 0x17, 0x31, 0xF4,
+0x80, 0x45, 0xC0, 0xF2, 0x73, 0xC1, 0x00, 0x1C, 0xF0, 0x5B, 0x43, 0x6D,
+0x73, 0x17, 0x81, 0xF4, 0x87, 0x45, 0xC0, 0xF2, 0x73, 0xC1, 0x00, 0x1C,
+0xF0, 0x5B, 0x10, 0x6D, 0x6B, 0x17, 0x00, 0x65, 0xE8, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xBF, 0xAF, 0x24, 0x63, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00,
+0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x10, 0x3C, 0x14, 0xAE, 0x42, 0x24,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x03, 0x11, 0x36, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x22, 0xAE, 0x20, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x30, 0x03, 0x10, 0x36, 0x20, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x05, 0x3C,
+0x00, 0x00, 0x02, 0xAE, 0x01, 0x80, 0x02, 0x3C, 0x15, 0xAE, 0x44, 0x24,
+0x33, 0x03, 0xA3, 0x34, 0x00, 0x00, 0x24, 0xAE, 0x00, 0x00, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0xFB, 0xFF, 0x40, 0x10,
+0x30, 0x03, 0xA2, 0x34, 0x00, 0x00, 0x46, 0x8C, 0x0F, 0x00, 0x03, 0x3C,
+0xFF, 0xFF, 0x63, 0x34, 0x24, 0x30, 0xC3, 0x00, 0x40, 0x11, 0x06, 0x00,
+0x23, 0x10, 0x46, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x46, 0x00,
+0xAF, 0x0F, 0x05, 0x3C, 0xC0, 0x10, 0x02, 0x00, 0x00, 0xA0, 0xA5, 0x34,
+0x1B, 0x00, 0xA2, 0x00, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24,
+0xC2, 0x30, 0x06, 0x00, 0x10, 0x00, 0xA4, 0x27, 0x54, 0x41, 0x66, 0xAC,
+0x12, 0x28, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x58, 0x41, 0x65, 0xAC,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0xC0, 0xFF, 0xBD, 0x27,
+0x2C, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x21, 0xA8, 0x80, 0x00,
+0x02, 0x80, 0x12, 0x3C, 0x10, 0x00, 0xA4, 0x27, 0x38, 0x00, 0xBE, 0xAF,
+0x30, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, 0x34, 0x00, 0xB7, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x44, 0x00, 0xA5, 0xAF,
+0xEC, 0x5D, 0x42, 0x92, 0x21, 0xF0, 0x00, 0x00, 0xC5, 0x00, 0x40, 0x10,
+0x21, 0xB0, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24,
+0xB0, 0x1B, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30,
+0xBE, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3E, 0x62, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x40, 0x14, 0x02, 0x80, 0x17, 0x3C,
+0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0x42, 0x24, 0x0E, 0x5E, 0xE2, 0xA2, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xF2, 0x5D, 0x40, 0xA0, 0x14, 0x5E, 0x60, 0xAC,
+0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, 0xFD, 0xFF, 0x03, 0x24,
+0x42, 0xB0, 0x13, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x07, 0x5E, 0x62, 0xA0, 0x00, 0x00, 0x63, 0x92, 0xEF, 0xFF, 0x02, 0x24,
+0x03, 0x00, 0x64, 0x36, 0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x63, 0xA2, 0x00, 0x00, 0x82, 0xA0, 0x02, 0x80, 0x04, 0x3C,
+0xF4, 0x5D, 0x82, 0x94, 0x20, 0x00, 0xA3, 0x96, 0xFF, 0xFF, 0x42, 0x30,
+0x0A, 0x00, 0x43, 0x10, 0x02, 0x80, 0x14, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x94, 0x00, 0x42, 0x34, 0xF4, 0x5D, 0x83, 0xA4, 0x00, 0x00, 0x43, 0xA4,
+0xF4, 0x5D, 0x83, 0x94, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x63, 0x30,
+0x80, 0x1A, 0x03, 0x00, 0xF8, 0x5D, 0x83, 0xAE, 0x25, 0xB0, 0x04, 0x3C,
+0x84, 0x00, 0x82, 0x34, 0x00, 0x00, 0x50, 0x8C, 0x80, 0x00, 0x84, 0x34,
+0x00, 0x00, 0x82, 0x8C, 0x21, 0x18, 0x00, 0x00, 0xF8, 0x5D, 0x86, 0x8E,
+0x00, 0x88, 0x10, 0x00, 0x21, 0x80, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02,
+0x25, 0x88, 0x23, 0x02, 0x21, 0x20, 0x00, 0x02, 0x7D, 0x2B, 0x00, 0x0C,
+0x21, 0x28, 0x20, 0x02, 0xF8, 0x5D, 0x88, 0x8E, 0x02, 0x80, 0x0A, 0x3C,
+0xFC, 0x5D, 0x43, 0x95, 0x23, 0x48, 0x02, 0x01, 0x21, 0x20, 0x30, 0x01,
+0x21, 0x28, 0x00, 0x00, 0x2B, 0x10, 0x90, 0x00, 0xFF, 0xFF, 0x63, 0x30,
+0x21, 0x28, 0xB1, 0x00, 0x80, 0x1A, 0x03, 0x00, 0x21, 0x28, 0xA2, 0x00,
+0x21, 0x38, 0x00, 0x00, 0x2B, 0x40, 0x83, 0x00, 0x23, 0x28, 0xA7, 0x00,
+0x23, 0x20, 0x83, 0x00, 0x23, 0x28, 0xA8, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x18, 0x5E, 0x64, 0xAC, 0x1C, 0x5E, 0x65, 0xAC, 0xFC, 0x5D, 0x42, 0x95,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x80, 0x12, 0x02, 0x00,
+0x2B, 0x10, 0x49, 0x00, 0x97, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0x5D, 0x42, 0x95, 0x00, 0x00, 0x64, 0x92, 0xFB, 0xFF, 0x03, 0x24,
+0xFF, 0xFF, 0x42, 0x30, 0x80, 0x12, 0x02, 0x00, 0x24, 0x20, 0x83, 0x00,
+0x23, 0x48, 0x22, 0x01, 0x00, 0x00, 0x64, 0xA2, 0x01, 0x00, 0x06, 0x24,
+0x04, 0x00, 0x20, 0x11, 0x01, 0x00, 0x04, 0x24, 0x80, 0x10, 0x09, 0x00,
+0x21, 0x10, 0x49, 0x00, 0x80, 0x30, 0x02, 0x00, 0xB9, 0x20, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24,
+0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x44, 0x00, 0xA2, 0x8F,
+0x05, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA4, 0x26, 0x00, 0x00, 0x47, 0x8C,
+0x14, 0x00, 0xA6, 0x27, 0xFF, 0x3F, 0xE7, 0x30, 0xAB, 0x1A, 0x00, 0x0C,
+0xDC, 0xFF, 0xE7, 0x24, 0x2C, 0x00, 0x40, 0x10, 0x21, 0x28, 0x40, 0x00,
+0xEC, 0x5D, 0x42, 0x92, 0x02, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x83, 0x00, 0x43, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0xA2, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30,
+0x04, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x16, 0x24,
+0x0B, 0x5E, 0x56, 0xA0, 0x04, 0x00, 0xA3, 0x90, 0x14, 0x00, 0xA7, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xE2, 0x28, 0x16, 0x00, 0x40, 0x14,
+0xFE, 0x00, 0x66, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24,
+0x4C, 0x3A, 0x64, 0x94, 0xC0, 0x10, 0x06, 0x00, 0x2A, 0x10, 0x82, 0x00,
+0x10, 0x00, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x21, 0x10, 0xC7, 0x00,
+0xFD, 0xFF, 0x42, 0x24, 0xC0, 0x10, 0x02, 0x00, 0x2A, 0x10, 0x44, 0x00,
+0x0A, 0x00, 0x40, 0x14, 0xC2, 0x10, 0x04, 0x00, 0x23, 0x30, 0x46, 0x00,
+0x21, 0x18, 0xA6, 0x00, 0x05, 0x00, 0x62, 0x90, 0x07, 0x00, 0x84, 0x30,
+0x01, 0x00, 0x03, 0x24, 0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x0B, 0xF0, 0x62, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90,
+0xEF, 0xFF, 0x03, 0x24, 0x21, 0x20, 0xC0, 0x02, 0x24, 0x10, 0x43, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0xA0, 0xEC, 0x5D, 0x43, 0x92,
+0x02, 0x80, 0x02, 0x3C, 0xE0, 0xE4, 0x42, 0x24, 0xFF, 0x00, 0x63, 0x30,
+0x80, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x66, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x09, 0xF8, 0xC0, 0x00, 0x21, 0x28, 0xC0, 0x03,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x3C, 0x00, 0xBF, 0x8F,
+0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0xEC, 0x5D, 0x42, 0x92,
+0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C,
+0x60, 0x1B, 0x70, 0x24, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x42, 0x30, 0xE9, 0xFF, 0x40, 0x10, 0x05, 0x00, 0x05, 0x24,
+0x44, 0x00, 0xA2, 0x8F, 0x24, 0x00, 0xA4, 0x26, 0x00, 0x00, 0x47, 0x8C,
+0x14, 0x00, 0xA6, 0x27, 0xFF, 0x3F, 0xE7, 0x30, 0xAB, 0x1A, 0x00, 0x0C,
+0xDC, 0xFF, 0xE7, 0x24, 0xE0, 0xFF, 0x40, 0x10, 0x21, 0x28, 0x40, 0x00,
+0x14, 0x00, 0xA7, 0x8F, 0x04, 0x00, 0x42, 0x90, 0x04, 0x00, 0xE3, 0x28,
+0xDB, 0xFF, 0x60, 0x14, 0xFE, 0x00, 0x46, 0x30, 0x4C, 0x3A, 0x04, 0x96,
+0xC0, 0x10, 0x06, 0x00, 0x2A, 0x10, 0x82, 0x00, 0xD6, 0xFF, 0x40, 0x14,
+0x21, 0x10, 0xC7, 0x00, 0xFD, 0xFF, 0x42, 0x24, 0xC0, 0x10, 0x02, 0x00,
+0x2A, 0x10, 0x44, 0x00, 0xD1, 0xFF, 0x40, 0x14, 0xC2, 0x10, 0x04, 0x00,
+0x23, 0x30, 0x46, 0x00, 0x21, 0x18, 0xA6, 0x00, 0x05, 0x00, 0x62, 0x90,
+0x07, 0x00, 0x84, 0x30, 0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30,
+0xC9, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x00, 0x83, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x42, 0x24, 0x0E, 0x5E, 0xE2, 0xA2, 0x00, 0x00, 0x62, 0x92,
+0xFB, 0xFF, 0x03, 0x24, 0x01, 0x00, 0x06, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x62, 0xA2, 0x32, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0xA2, 0x90, 0x02, 0x80, 0x07, 0x3C, 0x09, 0x5E, 0xE2, 0xA0,
+0x02, 0x00, 0xA3, 0x90, 0x21, 0x30, 0x80, 0x00, 0x0A, 0x5E, 0x83, 0xA0,
+0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x09, 0x5E, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x5E, 0xC2, 0xA0, 0x4C, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x5E, 0xC2, 0xA0,
+0x4C, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x0D, 0x5E, 0x43, 0xA0, 0xD0, 0x07, 0x04, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xDC, 0x5D, 0x44, 0xAC,
+0x0C, 0x5E, 0x60, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x04, 0x00, 0x82, 0x8C, 0x02, 0x00, 0x03, 0x24,
+0x21, 0x80, 0x80, 0x00, 0x02, 0x17, 0x02, 0x00, 0x03, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x43, 0x10, 0x02, 0x80, 0x11, 0x3C, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xEC, 0x5D, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xF8, 0xFF, 0x40, 0x10, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xEC, 0x5D, 0x23, 0x92, 0x02, 0x80, 0x02, 0x3C,
+0xB4, 0xE4, 0x42, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x80, 0x18, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x66, 0x8C, 0x00, 0x00, 0x04, 0x8E,
+0x04, 0x00, 0x05, 0x8E, 0x09, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x63, 0x30, 0x05, 0x00, 0x62, 0x10, 0x10, 0x00, 0xA4, 0x27,
+0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x2C, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x60, 0x10, 0x02, 0x80, 0x05, 0x3C,
+0x0C, 0x5E, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
+0x0C, 0x5E, 0xA2, 0xA0, 0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xF7, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x04, 0x3C,
+0x28, 0x00, 0x85, 0x34, 0x02, 0x00, 0x82, 0x94, 0x04, 0x00, 0x84, 0x24,
+0x05, 0x00, 0x40, 0x14, 0x2B, 0x18, 0xA4, 0x00, 0xFB, 0xFF, 0x60, 0x10,
+0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C,
+0xBE, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0x94, 0x08, 0x00, 0xE0, 0x03,
+0x01, 0x00, 0x42, 0x2C, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x24, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x19, 0x00, 0x40, 0x10, 0x98, 0x54, 0x64, 0x24, 0x98, 0x54, 0x62, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x44, 0x14, 0x02, 0x80, 0x02, 0x3C,
+0x0D, 0x5E, 0x43, 0x90, 0x01, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x63, 0x30,
+0x10, 0x00, 0x62, 0x10, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x05, 0x00, 0x42, 0x28,
+0x0A, 0x00, 0x40, 0x10, 0x01, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x64, 0x59, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x14,
+0x21, 0x10, 0x80, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0x8F,
+0x21, 0x20, 0x00, 0x00, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x24, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C, 0x98, 0x54, 0x42, 0x24,
+0x28, 0x00, 0x62, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x05, 0x5E, 0x62, 0x90,
+0x01, 0x00, 0x04, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x23, 0x00, 0x44, 0x10,
+0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0x03, 0x00, 0x42, 0x28, 0x1D, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x42, 0x30, 0x18, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30,
+0x13, 0x00, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x0D, 0x5E, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x0E, 0x00, 0x44, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x0E, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x60, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0x04, 0x3E, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x14,
+0x21, 0x18, 0x00, 0x00, 0x3C, 0x3A, 0x42, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x40, 0x14, 0x01, 0x00, 0x03, 0x24, 0x21, 0x18, 0x00, 0x00,
+0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x30, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x0E, 0x00, 0x40, 0x10, 0x90, 0x54, 0x65, 0x24, 0x90, 0x54, 0x62, 0x8C,
+0x02, 0x80, 0x04, 0x3C, 0x88, 0x54, 0x86, 0x24, 0x09, 0x00, 0x45, 0x14,
+0x01, 0x00, 0x03, 0x24, 0x88, 0x54, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x00, 0x46, 0x14, 0x21, 0x10, 0x60, 0x00, 0x10, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0x10, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x00, 0x00, 0x21, 0x10, 0x60, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0xFF, 0x00, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27,
+0x20, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x12, 0x3C, 0x0F, 0x00, 0x00, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x3C, 0x5E, 0x43, 0x92, 0x01, 0x00, 0x02, 0x24,
+0x04, 0x0C, 0x04, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x2A, 0x00, 0x62, 0x10,
+0x80, 0x01, 0x10, 0x3C, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x3C, 0x5E, 0x43, 0x92, 0x02, 0x00, 0x02, 0x24, 0x21, 0x28, 0x00, 0x00,
+0xFF, 0x00, 0x63, 0x30, 0xF3, 0xFF, 0x62, 0x14, 0x44, 0x08, 0x04, 0x24,
+0x03, 0x5C, 0x00, 0x0C, 0x7F, 0xFE, 0x10, 0x3C, 0x30, 0x5C, 0x00, 0x0C,
+0x04, 0x0C, 0x04, 0x24, 0xFD, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C,
+0x04, 0x0C, 0x04, 0x24, 0x30, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24,
+0xFD, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24,
+0x26, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0xFF, 0xFF, 0x10, 0x36,
+0x24, 0x28, 0x50, 0x00, 0x03, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24,
+0x26, 0x5C, 0x00, 0x0C, 0x8C, 0x0E, 0x04, 0x24, 0x24, 0x28, 0x50, 0x00,
+0x03, 0x5C, 0x00, 0x0C, 0x8C, 0x0E, 0x04, 0x24, 0x01, 0x00, 0x02, 0x24,
+0x3C, 0x5E, 0x42, 0xA2, 0xB9, 0x2D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x30, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x34,
+0xFF, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0C, 0x04, 0x24,
+0x30, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24, 0x02, 0x00, 0x42, 0x34,
+0xFF, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24,
+0x26, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0x25, 0x28, 0x50, 0x00,
+0x03, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0x26, 0x5C, 0x00, 0x0C,
+0x8C, 0x0E, 0x04, 0x24, 0x25, 0x28, 0x50, 0x00, 0x03, 0x5C, 0x00, 0x0C,
+0x8C, 0x0E, 0x04, 0x24, 0x03, 0x00, 0x05, 0x3C, 0x59, 0x01, 0xA5, 0x34,
+0x03, 0x5C, 0x00, 0x0C, 0x44, 0x08, 0x04, 0x24, 0x02, 0x00, 0x02, 0x24,
+0x3C, 0x5E, 0x42, 0xA2, 0xB9, 0x2D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x42, 0x00, 0x46, 0x34, 0xFC, 0x37, 0x03, 0x24,
+0x40, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA4, 0x03, 0x08, 0x04, 0x24,
+0x03, 0x00, 0x05, 0x24, 0x00, 0x00, 0xC0, 0xA0, 0x1A, 0x5C, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0xFC, 0x57, 0x12, 0x24,
+0x0B, 0x00, 0x60, 0x10, 0xFC, 0x77, 0x11, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0xC6, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x63, 0x30,
+0x2A, 0x00, 0x60, 0x14, 0x21, 0x20, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00,
+0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x00, 0x08, 0x04, 0x24,
+0x25, 0xB0, 0x03, 0x3C, 0x21, 0x00, 0x65, 0x34, 0x00, 0x00, 0xA2, 0x90,
+0x18, 0x00, 0x66, 0x34, 0x40, 0x00, 0x70, 0x34, 0x01, 0x00, 0x42, 0x34,
+0x42, 0x00, 0x63, 0x34, 0x00, 0x00, 0xA2, 0xA0, 0xFF, 0xFF, 0x02, 0x24,
+0x00, 0x00, 0xC0, 0xA0, 0x64, 0x00, 0x04, 0x24, 0x00, 0x00, 0x62, 0xA0,
+0x00, 0x00, 0x12, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x1A, 0x5C, 0x00, 0x0C, 0x03, 0x08, 0x04, 0x24,
+0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, 0xFC, 0x37, 0x02, 0x24,
+0x00, 0x00, 0x02, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24,
+0x00, 0x00, 0x11, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24,
+0x00, 0x00, 0x12, 0xA6, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xA8, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x30, 0x00, 0x00, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C,
+0x00, 0x08, 0x04, 0x24, 0x1F, 0x2E, 0x00, 0x08, 0x25, 0xB0, 0x03, 0x3C,
+0xB8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x13, 0x3C, 0xFF, 0x00, 0x90, 0x30, 0x18, 0x00, 0xA4, 0x27,
+0x30, 0x00, 0xB4, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xB1, 0xAF,
+0x40, 0x00, 0xBF, 0xAF, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF,
+0x34, 0x00, 0xB5, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB2, 0x30,
+0xEE, 0x5D, 0x62, 0x92, 0x0F, 0x00, 0x11, 0x32, 0x0F, 0x00, 0x42, 0x30,
+0x13, 0x00, 0x51, 0x10, 0x21, 0xA0, 0x00, 0x00, 0x04, 0x00, 0x02, 0x32,
+0x40, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92,
+0x0C, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x8F, 0x00, 0x43, 0x10,
+0x08, 0x00, 0x02, 0x32, 0xEE, 0x5D, 0x62, 0x92, 0x04, 0x00, 0x03, 0x24,
+0x0F, 0x00, 0x42, 0x30, 0xD2, 0x01, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xEE, 0x5D, 0x62, 0x92, 0x02, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30,
+0x9B, 0x00, 0x43, 0x10, 0x06, 0x00, 0x02, 0x32, 0x02, 0x80, 0x10, 0x3C,
+0xED, 0x5D, 0x03, 0x92, 0xEE, 0x5D, 0x62, 0x92, 0x0F, 0x00, 0x63, 0x30,
+0x0F, 0x00, 0x42, 0x30, 0x2A, 0x10, 0x43, 0x00, 0x1C, 0x00, 0x40, 0x14,
+0x02, 0x80, 0x12, 0x3C, 0xED, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x42, 0x30, 0x17, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0xC2, 0x5C, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x43, 0x30,
+0x52, 0x00, 0x60, 0x14, 0x04, 0x00, 0x42, 0x30, 0x10, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x43, 0x92, 0x02, 0x80, 0x06, 0x3C,
+0x14, 0xE5, 0xC5, 0x90, 0x0F, 0x00, 0x63, 0x30, 0x25, 0xB0, 0x02, 0x3C,
+0x25, 0x18, 0x65, 0x00, 0xDD, 0x02, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0,
+0xED, 0x5D, 0x04, 0x92, 0x80, 0xFF, 0x02, 0x24, 0xBF, 0xFF, 0x03, 0x24,
+0x26, 0x28, 0xA2, 0x00, 0x24, 0x20, 0x83, 0x00, 0x14, 0xE5, 0xC5, 0xA0,
+0xED, 0x5D, 0x04, 0xA2, 0x90, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27,
+0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F,
+0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F,
+0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0xEE, 0x5D, 0x62, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x30, 0x4C, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0x08, 0x00, 0x02, 0x32,
+0x1B, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x40, 0x14,
+0x08, 0x00, 0x02, 0x32, 0x0A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x40, 0x12, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00,
+0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x25, 0x18, 0x23, 0x02, 0xEE, 0x5D, 0x63, 0xA2, 0x72, 0x2E, 0x00, 0x08,
+0x02, 0x80, 0x10, 0x3C, 0x10, 0x37, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x42, 0x30, 0xF2, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x0D, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x60, 0x14,
+0x01, 0x00, 0x04, 0x24, 0x0E, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xBD, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x53, 0x21, 0x00, 0x0C,
+0x24, 0x00, 0x04, 0x24, 0x76, 0x01, 0x40, 0x10, 0x21, 0x88, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x45, 0x90, 0xEE, 0x5D, 0x44, 0x92,
+0xED, 0x5D, 0x02, 0x92, 0xBF, 0xFF, 0x03, 0x24, 0x0F, 0x00, 0x84, 0x30,
+0x24, 0x10, 0x43, 0x00, 0xED, 0x5D, 0x02, 0xA2, 0x10, 0x00, 0xA5, 0xA3,
+0x11, 0x00, 0xA4, 0xA3, 0x08, 0x00, 0x24, 0x96, 0x02, 0x80, 0x02, 0x3C,
+0x10, 0x00, 0xA5, 0x27, 0x25, 0x20, 0x82, 0x00, 0x20, 0x00, 0x84, 0x24,
+0xC2, 0x1B, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, 0x04, 0x00, 0x03, 0x24,
+0x17, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x23, 0xAE, 0x14, 0x00, 0x22, 0xAE,
+0x17, 0x0A, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x94, 0x2E, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xA6, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x71, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x35, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x77, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92,
+0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xEE, 0x5D, 0x62, 0xA2,
+0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x92, 0x10, 0x37, 0x64, 0x94,
+0x04, 0x00, 0x42, 0x34, 0x00, 0x01, 0x84, 0x30, 0xEE, 0x5D, 0x62, 0xA2,
+0x61, 0xFF, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x67, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x65, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x2D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x61, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x41, 0xB0, 0x04, 0x3C,
+0x24, 0x10, 0x43, 0x00, 0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92,
+0x08, 0x00, 0x85, 0x34, 0x82, 0x00, 0x02, 0x24, 0x01, 0x00, 0x63, 0x34,
+0x02, 0x80, 0x17, 0x3C, 0xEE, 0x5D, 0x63, 0xA2, 0x00, 0x00, 0x80, 0xAC,
+0x00, 0x00, 0xA2, 0xA4, 0x42, 0xB0, 0x04, 0x3C, 0x60, 0x1B, 0xE2, 0x26,
+0xB0, 0x1B, 0x45, 0x94, 0x00, 0x00, 0x83, 0x90, 0xBE, 0xFF, 0x02, 0x24,
+0x03, 0x00, 0x86, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x01, 0xA5, 0x30,
+0x90, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xC2, 0xA0,
+0x38, 0x00, 0xA0, 0x10, 0x25, 0xB0, 0x06, 0x3C, 0x25, 0xB0, 0x04, 0x3C,
+0x84, 0x00, 0x82, 0x34, 0x00, 0x00, 0x46, 0x8C, 0x80, 0x00, 0x84, 0x34,
+0x00, 0x00, 0x82, 0x8C, 0x02, 0x80, 0x0B, 0x3C, 0x14, 0x5E, 0x64, 0x8D,
+0x00, 0x38, 0x06, 0x00, 0x21, 0x30, 0x00, 0x00, 0x25, 0xA0, 0xC2, 0x00,
+0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x0A, 0x3C, 0x25, 0xA8, 0xE3, 0x00,
+0x21, 0x28, 0x00, 0x00, 0x1C, 0x5E, 0x42, 0x8D, 0x21, 0x20, 0x94, 0x00,
+0x2B, 0x18, 0x94, 0x00, 0x21, 0x28, 0xB5, 0x00, 0x21, 0x28, 0xA3, 0x00,
+0x2B, 0x10, 0xA2, 0x00, 0x24, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x5E, 0x42, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x45, 0x10,
+0x01, 0x00, 0x05, 0x24, 0x60, 0x1B, 0xE2, 0x26, 0x58, 0x41, 0x43, 0x8C,
+0x42, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0xE6, 0x90, 0x18, 0x00, 0x65, 0x00,
+0xFB, 0xFF, 0x02, 0x24, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x00, 0xE6, 0xA0,
+0x67, 0x46, 0x06, 0x3C, 0xCF, 0xAC, 0xC6, 0x34, 0x01, 0x00, 0x04, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00, 0x82, 0x1A, 0x03, 0x00,
+0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xC0, 0x10, 0x02, 0x00,
+0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x19, 0x00, 0x46, 0x00,
+0x10, 0x30, 0x00, 0x00, 0x23, 0x10, 0x46, 0x00, 0x42, 0x10, 0x02, 0x00,
+0x21, 0x30, 0xC2, 0x00, 0x02, 0x33, 0x06, 0x00, 0x01, 0x00, 0x02, 0x24,
+0xB9, 0x20, 0x00, 0x0C, 0x0A, 0x30, 0x46, 0x00, 0x25, 0xB0, 0x06, 0x3C,
+0xF2, 0x02, 0xC3, 0x34, 0x88, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0,
+0x11, 0x00, 0xC7, 0x34, 0x00, 0x00, 0xE2, 0x90, 0x08, 0x00, 0xC5, 0x34,
+0x60, 0x1B, 0xE4, 0x26, 0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0xE2, 0xA0,
+0x00, 0x00, 0xA3, 0x94, 0xB0, 0x1B, 0x82, 0x94, 0xFF, 0xFF, 0x64, 0x30,
+0x10, 0x00, 0x84, 0x34, 0x00, 0x00, 0xA4, 0xA4, 0xFB, 0xFF, 0x84, 0x30,
+0x00, 0x00, 0xA4, 0xA4, 0x00, 0x01, 0x42, 0x30, 0x02, 0x00, 0x84, 0x34,
+0x00, 0x00, 0xA4, 0xA4, 0x04, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x02, 0x3C,
+0x22, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0,
+0xFF, 0xF7, 0x84, 0x30, 0x00, 0x00, 0xA4, 0xA4, 0x28, 0x00, 0xC4, 0x34,
+0x00, 0x00, 0x83, 0x94, 0xEF, 0xFE, 0x02, 0x24, 0xFE, 0xFF, 0x08, 0x24,
+0x24, 0x18, 0x62, 0x00, 0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0x82, 0x94,
+0x26, 0x00, 0xC5, 0x34, 0x02, 0x80, 0x03, 0x3C, 0x24, 0x10, 0x48, 0x00,
+0x00, 0x00, 0x82, 0xA4, 0xC2, 0x5C, 0x64, 0x90, 0x00, 0x00, 0xA2, 0x94,
+0x04, 0x00, 0x84, 0x30, 0x00, 0x24, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4,
+0x09, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x48, 0x00, 0x00, 0x00, 0xA2, 0xA4,
+0x00, 0x00, 0xE3, 0x90, 0xFD, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x00, 0xE3, 0xA0, 0x00, 0x68, 0x02, 0x40, 0x00, 0x08, 0x42, 0x30,
+0xFD, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x12, 0x3C,
+0x11, 0x00, 0x43, 0x36, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x44, 0x36, 0x00, 0x00, 0x82, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0x82, 0xA4,
+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, 0x83, 0x94,
+0xFF, 0xDB, 0x02, 0x24, 0x28, 0x00, 0x45, 0x36, 0x24, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0xA2, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4, 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, 0xA2, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x01, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4, 0x08, 0x00, 0x51, 0x36,
+0x00, 0x00, 0x23, 0x96, 0x60, 0x1B, 0xF6, 0x26, 0xB0, 0x1B, 0xC2, 0x96,
+0xFF, 0xFF, 0x70, 0x30, 0x00, 0x18, 0x10, 0x36, 0x00, 0x00, 0x30, 0xA6,
+0x00, 0x01, 0x42, 0x30, 0xFD, 0xFF, 0x10, 0x32, 0x00, 0x00, 0x30, 0xA6,
+0x05, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0x90,
+0xFB, 0xFF, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA0,
+0x04, 0x00, 0x10, 0x36, 0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24,
+0x00, 0x00, 0x30, 0xA6, 0x22, 0x00, 0x02, 0x24, 0xF2, 0x02, 0x43, 0x36,
+0xEF, 0xFF, 0x10, 0x32, 0x00, 0x00, 0x30, 0xA6, 0xC8, 0x00, 0x04, 0x24,
+0x00, 0x00, 0x62, 0xA0, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xB0, 0x1B, 0xC2, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30,
+0x41, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x06, 0x3C, 0x84, 0x00, 0x42, 0x36,
+0x00, 0x00, 0x44, 0x8C, 0x80, 0x00, 0x46, 0x36, 0x00, 0x00, 0xC2, 0x8C,
+0x00, 0x28, 0x04, 0x00, 0x21, 0x18, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00,
+0x25, 0x30, 0x82, 0x00, 0x25, 0x38, 0xA3, 0x00, 0x58, 0x41, 0xC3, 0x8E,
+0x23, 0x28, 0xD4, 0x00, 0x80, 0x12, 0x05, 0x00, 0x1B, 0x00, 0x43, 0x00,
+0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00,
+0x02, 0x80, 0x0B, 0x3C, 0x14, 0x5E, 0x63, 0x8D, 0x12, 0x10, 0x00, 0x00,
+0x23, 0x10, 0x45, 0x00, 0x21, 0x10, 0x43, 0x00, 0x14, 0x5E, 0x62, 0xAD,
+0x14, 0x5E, 0x63, 0x8D, 0x42, 0xB0, 0x02, 0x3C, 0x03, 0x00, 0x42, 0x34,
+0x58, 0x1B, 0x63, 0x24, 0x14, 0x5E, 0x63, 0xAD, 0x00, 0x00, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x63, 0x30, 0x20, 0x00, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x5E, 0x62, 0x8D, 0x02, 0x80, 0x0A, 0x3C,
+0x1C, 0x5E, 0x44, 0x8D, 0x21, 0x40, 0x46, 0x00, 0x2B, 0x28, 0x06, 0x01,
+0x21, 0x48, 0x67, 0x00, 0x21, 0x48, 0x25, 0x01, 0x2B, 0x20, 0x24, 0x01,
+0x59, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x5E, 0x42, 0x8D,
+0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x49, 0x10, 0x01, 0x00, 0x05, 0x24,
+0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0x90, 0xFB, 0xFF, 0x04, 0x24,
+0x01, 0x00, 0x06, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA0,
+0x04, 0x00, 0xA0, 0x10, 0x01, 0x00, 0x04, 0x24, 0x80, 0x10, 0x05, 0x00,
+0x21, 0x10, 0x45, 0x00, 0x80, 0x30, 0x02, 0x00, 0xB9, 0x20, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24,
+0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x42, 0xB0, 0x06, 0x3C,
+0x00, 0x00, 0xC2, 0x90, 0x60, 0x1B, 0xE5, 0x26, 0xD0, 0x1B, 0xA8, 0x8C,
+0xDC, 0x1B, 0xA7, 0x94, 0x41, 0xB0, 0x03, 0x3C, 0x41, 0x00, 0x42, 0x34,
+0x08, 0x00, 0x64, 0x34, 0x00, 0x00, 0xC2, 0xA0, 0x00, 0x00, 0x68, 0xAC,
+0x00, 0x00, 0x87, 0xA4, 0xEE, 0x5D, 0x63, 0x92, 0xF0, 0xFF, 0x02, 0x24,
+0xDC, 0x1B, 0xA7, 0xA4, 0x24, 0x18, 0x62, 0x00, 0xEE, 0x5D, 0x63, 0xA2,
+0xEE, 0x5D, 0x62, 0x92, 0xD0, 0x1B, 0xA8, 0xAC, 0x02, 0x00, 0x42, 0x34,
+0xEE, 0x5D, 0x62, 0xA2, 0x72, 0x2E, 0x00, 0x08, 0x02, 0x80, 0x10, 0x3C,
+0x59, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x31, 0xFE, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x63, 0x34, 0xEE, 0x5D, 0x63, 0xA2, 0x6C, 0x2E, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x97, 0x99, 0x63, 0x34, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x94, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x5E, 0x42, 0x8D,
+0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0x82, 0x00, 0x0C, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x5E, 0x42, 0x8D, 0x45, 0x2F, 0x00, 0x08,
+0x01, 0x00, 0x05, 0x24, 0x18, 0x5E, 0x42, 0x8D, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0x02, 0x01, 0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x5E, 0x42, 0x8D, 0x16, 0x30, 0x00, 0x08, 0x01, 0x00, 0x05, 0x24,
+0x18, 0x5E, 0x42, 0x8D, 0x1C, 0x5E, 0x43, 0x8D, 0x14, 0x5E, 0x64, 0x8D,
+0x23, 0x10, 0x54, 0x00, 0x45, 0x2F, 0x00, 0x08, 0x23, 0x28, 0x44, 0x00,
+0x18, 0x5E, 0x42, 0x8D, 0x1C, 0x5E, 0x43, 0x8D, 0x14, 0x5E, 0x64, 0x8D,
+0x23, 0x10, 0x46, 0x00, 0x16, 0x30, 0x00, 0x08, 0x23, 0x28, 0x44, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90,
+0x04, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x28,
+0x03, 0x00, 0x60, 0x14, 0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x4B, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0xE0, 0xFF, 0xBD, 0x27,
+0xFC, 0xC1, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x62, 0xAC, 0x18, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x0C, 0x5E, 0x82, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x01, 0x00, 0x05, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0xD0, 0x07, 0x03, 0x24, 0x0C, 0x5E, 0x80, 0xA0,
+0x10, 0x00, 0xA4, 0x27, 0x90, 0x40, 0x00, 0x0C, 0xDC, 0x5D, 0x43, 0xAC,
+0x18, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x0F, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x02, 0x3C,
+0x0D, 0x5E, 0x60, 0xA0, 0xED, 0x5D, 0x44, 0x90, 0x4B, 0x2E, 0x00, 0x0C,
+0xFF, 0x00, 0x84, 0x30, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x18, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x42, 0x11, 0x05, 0x00, 0x0F, 0x00, 0x46, 0x30,
+0xE8, 0xFF, 0xBD, 0x27, 0x09, 0x00, 0xC3, 0x28, 0x14, 0x00, 0xBF, 0xAF,
+0x14, 0x00, 0x60, 0x10, 0x10, 0x00, 0xB0, 0xAF, 0x82, 0x16, 0x05, 0x00,
+0x01, 0x00, 0x42, 0x30, 0x14, 0x00, 0x40, 0x10, 0x00, 0xC0, 0x02, 0x3C,
+0x24, 0x10, 0xA2, 0x00, 0x43, 0x00, 0x40, 0x14, 0xC2, 0x15, 0x04, 0x00,
+0x01, 0x00, 0x42, 0x30, 0x50, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x0C, 0xE5, 0x63, 0x24, 0x21, 0x18, 0xC3, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x08, 0x5E, 0x85, 0x90, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x10, 0x45, 0x00, 0x47, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x24, 0x10, 0xA2, 0x00, 0x1E, 0x00, 0x40, 0x10,
+0xC2, 0x15, 0x04, 0x00, 0x02, 0x80, 0x06, 0x3C, 0x07, 0x5E, 0xC2, 0x90,
+0xFD, 0xFF, 0x03, 0x24, 0x42, 0xB0, 0x04, 0x3C, 0x24, 0x10, 0x43, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0xC2, 0xA0, 0x0B, 0x5E, 0x60, 0xA0,
+0x00, 0x00, 0x82, 0x90, 0xEF, 0xFF, 0x03, 0x24, 0x03, 0x00, 0x85, 0x34,
+0x24, 0x10, 0x43, 0x00, 0x40, 0x00, 0x03, 0x24, 0x00, 0x00, 0x82, 0xA0,
+0x00, 0x00, 0xA3, 0xA0, 0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x42, 0x30, 0xE6, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C,
+0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0x01, 0x00, 0x42, 0x30, 0x25, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x0C, 0xE5, 0x63, 0x24, 0x21, 0x18, 0xC3, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x08, 0x5E, 0x85, 0x90, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x10, 0x45, 0x00, 0xE7, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x06, 0x3C,
+0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x07, 0x5E, 0xC2, 0xA0, 0xD7, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x42, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0xE3, 0x90, 0xEF, 0xFF, 0x02, 0x24,
+0x03, 0x00, 0xF0, 0x34, 0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24,
+0x00, 0x00, 0xE3, 0xA0, 0x02, 0x00, 0x04, 0x24, 0x00, 0x00, 0x02, 0xA2,
+0x21, 0x28, 0x00, 0x00, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0xF0, 0x06, 0x34,
+0x44, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, 0xA2, 0xC1, 0x30, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x01, 0x00, 0x04, 0x24, 0xE1, 0x51, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0x02, 0x80, 0x06, 0x3C, 0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x07, 0x5E, 0xC2, 0xA0, 0xD7, 0x30, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x82, 0x16, 0x05, 0x00, 0xE8, 0xFF, 0xBD, 0x27,
+0x01, 0x00, 0x42, 0x30, 0x14, 0x00, 0xBF, 0xAF, 0x0E, 0x00, 0x40, 0x10,
+0x10, 0x00, 0xB0, 0xAF, 0x00, 0xC0, 0x02, 0x3C, 0x24, 0x10, 0xA2, 0x00,
+0x37, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90,
+0x02, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x44, 0x00, 0x62, 0x10,
+0x01, 0x00, 0x04, 0x24, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0xE1, 0x51, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x00, 0xC0, 0x02, 0x3C,
+0x24, 0x10, 0xA2, 0x00, 0x0E, 0x00, 0x40, 0x14, 0x02, 0x80, 0x06, 0x3C,
+0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x07, 0x5E, 0xC2, 0xA0, 0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x00, 0x42, 0x30, 0x18, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x07, 0x5E, 0xC2, 0x90, 0xFD, 0xFF, 0x03, 0x24,
+0x42, 0xB0, 0x04, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x07, 0x5E, 0xC2, 0xA0, 0x0B, 0x5E, 0x60, 0xA0, 0x00, 0x00, 0x82, 0x90,
+0xEF, 0xFF, 0x03, 0x24, 0x03, 0x00, 0x85, 0x34, 0x24, 0x10, 0x43, 0x00,
+0x40, 0x00, 0x03, 0x24, 0x00, 0x00, 0x82, 0xA0, 0x00, 0x00, 0xA3, 0xA0,
+0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x42, 0x30,
+0xEA, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x05, 0x5E, 0x40, 0xA0,
+0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30,
+0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x42, 0xB0, 0x07, 0x3C,
+0x00, 0x00, 0xE3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x03, 0x00, 0xF0, 0x34,
+0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xA0,
+0x02, 0x00, 0x04, 0x24, 0x00, 0x00, 0x02, 0xA2, 0x21, 0x28, 0x00, 0x00,
+0xB9, 0x20, 0x00, 0x0C, 0x00, 0xF0, 0x06, 0x34, 0x44, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x02, 0xA2, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xE2, 0x2C, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x0C, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x08,
+0x18, 0x00, 0xBD, 0x27, 0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C,
+0xE8, 0xFF, 0xBD, 0x27, 0xB4, 0xC5, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34,
+0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x62, 0xAC, 0x02, 0x80, 0x10, 0x3C,
+0xED, 0x5D, 0x02, 0x92, 0x14, 0x00, 0xBF, 0xAF, 0x0F, 0x00, 0x42, 0x30,
+0x03, 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x05, 0x24,
+0x59, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10,
+0x01, 0x00, 0x05, 0x24, 0xED, 0x5D, 0x04, 0x92, 0x4B, 0x2E, 0x00, 0x0C,
+0xFF, 0x00, 0x84, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x84, 0x24,
+0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x02, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C,
+0x25, 0x18, 0x65, 0x00, 0x08, 0x00, 0x42, 0x34, 0x18, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0x43, 0xA4, 0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4,
+0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x01, 0x80, 0x03, 0x3C,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x03, 0x52, 0x34, 0x40, 0xC6, 0x71, 0x24,
+0x02, 0x80, 0x10, 0x3C, 0x08, 0x14, 0x04, 0x26, 0x21, 0x28, 0x00, 0x00,
+0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0x00, 0x00, 0x51, 0xAE,
+0x76, 0x39, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x31, 0x00, 0x08,
+0x08, 0x14, 0x04, 0x26, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0xFF, 0xFF, 0x90, 0x30, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x60, 0x1B, 0xCD, 0x24,
+0x2A, 0x1C, 0xA2, 0x91, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x10,
+0x2A, 0xB0, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0x38, 0x02, 0x64, 0x34,
+0x80, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x82, 0xA0, 0x34, 0x02, 0x6A, 0x34,
+0xD2, 0x01, 0x65, 0x34, 0xD6, 0x01, 0x66, 0x34, 0xDA, 0x01, 0x67, 0x34,
+0xDE, 0x01, 0x63, 0x34, 0x00, 0x00, 0xA8, 0x94, 0x00, 0x00, 0xC9, 0x94,
+0x00, 0x00, 0xEB, 0x94, 0x00, 0x00, 0x6C, 0x94, 0x00, 0x00, 0x44, 0x95,
+0xB0, 0xFE, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x28, 0x1C, 0xA4, 0xA5,
+0x00, 0x00, 0xA0, 0xA4, 0x10, 0x00, 0xA4, 0x27, 0x20, 0x1C, 0xA8, 0xA5,
+0x00, 0x00, 0xC0, 0xA4, 0x22, 0x1C, 0xA9, 0xA5, 0x00, 0x00, 0xE0, 0xA4,
+0x24, 0x1C, 0xAB, 0xA5, 0x00, 0x00, 0x60, 0xA4, 0x00, 0x00, 0x50, 0xA5,
+0x90, 0x40, 0x00, 0x0C, 0x26, 0x1C, 0xAC, 0xA5, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x0A, 0x00, 0x45, 0x34, 0x63, 0x00, 0x03, 0x24, 0xFF, 0xFF, 0x04, 0x34,
+0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x10,
+0x64, 0x00, 0x02, 0x24, 0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30,
+0xFE, 0xFF, 0x40, 0x14, 0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x62, 0x24,
+0xFF, 0xFF, 0x43, 0x30, 0xF5, 0xFF, 0x64, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0xC2, 0x24, 0x28, 0x1C, 0x48, 0x94, 0x26, 0x1C, 0x47, 0x94,
+0x20, 0x1C, 0x49, 0x94, 0x22, 0x1C, 0x4A, 0x94, 0x24, 0x1C, 0x4B, 0x94,
+0x25, 0xB0, 0x03, 0x3C, 0x38, 0x02, 0x6C, 0x34, 0x34, 0x02, 0x62, 0x34,
+0xD2, 0x01, 0x64, 0x34, 0xD6, 0x01, 0x65, 0x34, 0xDA, 0x01, 0x66, 0x34,
+0xDE, 0x01, 0x63, 0x34, 0x00, 0x00, 0x48, 0xA4, 0x00, 0x00, 0x89, 0xA4,
+0x00, 0x00, 0xAA, 0xA4, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0xCB, 0xA4,
+0x00, 0x00, 0x67, 0xA4, 0x00, 0x00, 0x80, 0xA1, 0x90, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27,
+0x28, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB3, 0xAF,
+0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF,
+0xFF, 0xFF, 0x14, 0x24, 0x02, 0x80, 0x13, 0x3C, 0x41, 0xB0, 0x02, 0x3C,
+0x60, 0x1B, 0x63, 0x26, 0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x45, 0x8C,
+0xD4, 0x1B, 0x64, 0x8C, 0xD0, 0x1B, 0x66, 0x8C, 0x02, 0x80, 0x02, 0x3C,
+0xF0, 0x5C, 0x47, 0x90, 0x25, 0xB0, 0x08, 0x3C, 0xB0, 0x03, 0x02, 0x35,
+0x25, 0x90, 0x85, 0x00, 0x00, 0x00, 0x52, 0xAC, 0x00, 0x00, 0x46, 0xAC,
+0x01, 0x00, 0x02, 0x24, 0x89, 0x03, 0xE2, 0x10, 0xD4, 0x1B, 0x72, 0xAC,
+0x60, 0x1B, 0x64, 0x26, 0xD0, 0x1B, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0E, 0x00, 0x40, 0x10,
+0x60, 0x1B, 0x67, 0x26, 0x25, 0xB0, 0x10, 0x3C, 0xB0, 0x03, 0x02, 0x36,
+0x01, 0x00, 0x05, 0x24, 0x00, 0x00, 0x45, 0xAC, 0x04, 0x00, 0x0B, 0x36,
+0xD4, 0x1B, 0x83, 0x8C, 0x00, 0x00, 0x69, 0x8D, 0x40, 0x00, 0x02, 0x3C,
+0x01, 0x00, 0x63, 0x38, 0x24, 0x10, 0x22, 0x01, 0x26, 0x01, 0x40, 0x10,
+0xD4, 0x1B, 0x83, 0xAC, 0x60, 0x1B, 0x67, 0x26, 0xD0, 0x1B, 0xE2, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00, 0x04, 0x00, 0x42, 0x30,
+0x14, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x71, 0x26, 0x25, 0xB0, 0x03, 0x3C,
+0xB0, 0x03, 0x64, 0x34, 0x04, 0x00, 0x02, 0x24, 0x00, 0x00, 0x82, 0xAC,
+0xD4, 0x1B, 0xE2, 0x8C, 0xC4, 0x38, 0xE6, 0x8C, 0xFC, 0x00, 0x63, 0x34,
+0xAC, 0x1B, 0xE4, 0x94, 0x00, 0x00, 0x65, 0x8C, 0x04, 0x00, 0x42, 0x38,
+0x21, 0x48, 0xC4, 0x00, 0x06, 0x00, 0xA9, 0x10, 0xD4, 0x1B, 0xE2, 0xAC,
+0x02, 0x80, 0x03, 0x3C, 0xB0, 0x5D, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x42, 0x34, 0xB0, 0x5D, 0x62, 0xAC, 0x60, 0x1B, 0x71, 0x26,
+0xD0, 0x1B, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00,
+0x08, 0x00, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xB0, 0x1B, 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x30,
+0x5D, 0x03, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xD4, 0x1B, 0x22, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42, 0x38, 0xD4, 0x1B, 0x22, 0xAE,
+0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x20, 0x52, 0x00, 0x00, 0x08, 0x83, 0x30, 0x06, 0x00, 0x60, 0x10,
+0x00, 0x10, 0x82, 0x30, 0xD4, 0x1B, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x08, 0x42, 0x38, 0xD4, 0x1B, 0x02, 0xAE, 0x00, 0x10, 0x82, 0x30,
+0x05, 0x03, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26,
+0xD0, 0x1B, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x72, 0x00,
+0x00, 0x20, 0x42, 0x30, 0xF7, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x10, 0x72, 0x00, 0x00, 0x80, 0x42, 0x30, 0xB9, 0x01, 0x40, 0x14,
+0x01, 0x00, 0x03, 0x3C, 0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00,
+0x24, 0x10, 0x43, 0x00, 0xF1, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0xD0, 0x1B, 0x02, 0x8E, 0x02, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x43, 0x00, 0x28, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x04, 0x00, 0x03, 0x3C,
+0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00,
+0x62, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26,
+0xD0, 0x1B, 0x02, 0x8E, 0x08, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x43, 0x00, 0x9B, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x10, 0x00, 0x03, 0x3C,
+0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00,
+0x5A, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26,
+0xD0, 0x1B, 0x02, 0x8E, 0x20, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x43, 0x00, 0x18, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x40, 0x00, 0x03, 0x3C,
+0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00,
+0xD6, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x65, 0x26,
+0xD0, 0x1B, 0xA2, 0x8C, 0x00, 0x04, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x43, 0x00, 0x3D, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x66, 0x26,
+0x2A, 0xB0, 0x02, 0x3C, 0x2C, 0x00, 0x43, 0x34, 0x00, 0x00, 0x69, 0x8C,
+0xFF, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x24, 0x31, 0x29, 0x03, 0x82, 0x10,
+0x00, 0x80, 0x22, 0x31, 0xF9, 0x02, 0x40, 0x14, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0xFF, 0x02, 0x3C, 0x24, 0x10, 0x22, 0x01, 0x0B, 0x00, 0x40, 0x10,
+0xFF, 0x00, 0x02, 0x24, 0xAC, 0x37, 0xA2, 0x90, 0x20, 0xB0, 0x03, 0x3C,
+0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x0C, 0x00, 0x49, 0x8C,
+0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x63, 0x34, 0x00, 0x00, 0x69, 0xAC,
+0xFF, 0x00, 0x24, 0x31, 0xFF, 0x00, 0x02, 0x24, 0x1B, 0x00, 0x82, 0x10,
+0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x7C, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x10, 0x38, 0x03, 0xAE, 0x0A, 0x00, 0x04, 0x24,
+0xAC, 0x37, 0x09, 0xA2, 0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0xD0, 0x1B, 0x05, 0x8E, 0x02, 0x80, 0x06, 0x3C,
+0xB0, 0x5D, 0xC4, 0x8C, 0x00, 0x04, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x28, 0xA2, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x84, 0x34,
+0xB0, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC,
+0x00, 0x00, 0x65, 0xAC, 0xB0, 0x5D, 0xC4, 0xAC, 0xD0, 0x1B, 0x05, 0xAE,
+0x60, 0x1B, 0x65, 0x26, 0xD4, 0x1B, 0xA4, 0x8C, 0x00, 0x04, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x26, 0x20, 0x83, 0x00, 0xB0, 0x03, 0x42, 0x34,
+0x00, 0x00, 0x44, 0xAC, 0xD4, 0x1B, 0xA4, 0xAC, 0x60, 0x1B, 0x66, 0x26,
+0xD0, 0x1B, 0xC7, 0x8C, 0x00, 0x08, 0x04, 0x3C, 0x24, 0x28, 0xF2, 0x00,
+0x24, 0x10, 0xA4, 0x00, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0x08, 0x3C,
+0xD4, 0x1B, 0xC3, 0x8C, 0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34,
+0x26, 0x18, 0x64, 0x00, 0x00, 0x00, 0x44, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC,
+0x80, 0x00, 0x08, 0x3C, 0x24, 0x10, 0xA8, 0x00, 0x21, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xD4, 0x1B, 0xC3, 0x8C, 0x25, 0xB0, 0x09, 0x3C,
+0xB0, 0x03, 0x2A, 0x35, 0x2A, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0xAD,
+0x36, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x23, 0xB0, 0x04, 0x3C,
+0xFF, 0x1F, 0x02, 0x3C, 0xC0, 0x18, 0x03, 0x00, 0xF0, 0x07, 0x63, 0x30,
+0xF4, 0x38, 0xC5, 0x8C, 0x21, 0x18, 0x64, 0x00, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x18, 0x62, 0x00, 0xCE, 0x02, 0x65, 0x10, 0xF8, 0x38, 0xC3, 0xAC,
+0x02, 0x80, 0x05, 0x3C, 0xB0, 0x5D, 0xA3, 0x8C, 0x27, 0x20, 0x08, 0x00,
+0x24, 0x20, 0xE4, 0x00, 0x00, 0x10, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C,
+0x00, 0x00, 0x43, 0xAD, 0x00, 0x00, 0x44, 0xAC, 0xB0, 0x5D, 0xA3, 0xAC,
+0xD0, 0x1B, 0xC4, 0xAC, 0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C,
+0x80, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC,
+0x60, 0x1B, 0x66, 0x26, 0xD0, 0x1B, 0xC3, 0x8C, 0x00, 0x01, 0x05, 0x3C,
+0x24, 0x20, 0x72, 0x00, 0x24, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40, 0x10,
+0x25, 0xB0, 0x02, 0x3C, 0xD4, 0x1B, 0xC3, 0x8C, 0xB0, 0x03, 0x42, 0x34,
+0x26, 0x18, 0x65, 0x00, 0x00, 0x00, 0x45, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC,
+0x00, 0x02, 0x05, 0x3C, 0x24, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40, 0x10,
+0x25, 0xB0, 0x02, 0x3C, 0xD4, 0x1B, 0xC3, 0x8C, 0xB0, 0x03, 0x42, 0x34,
+0x26, 0x18, 0x65, 0x00, 0x00, 0x00, 0x45, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC,
+0x00, 0x10, 0x05, 0x3C, 0x24, 0x10, 0x85, 0x00, 0x0C, 0x00, 0x40, 0x10,
+0x60, 0x1B, 0x63, 0x26, 0xB0, 0x1B, 0xC3, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x62, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00, 0x08, 0x62, 0x34,
+0xB0, 0x1B, 0xC2, 0xA4, 0xD4, 0x1B, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x26, 0x10, 0x45, 0x00, 0xD4, 0x1B, 0xC2, 0xAC, 0x60, 0x1B, 0x63, 0x26,
+0xD0, 0x1B, 0x62, 0x8C, 0x00, 0x20, 0x05, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x45, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xB0, 0x1B, 0x64, 0x94, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x82, 0x30,
+0x02, 0x00, 0x40, 0x10, 0xFF, 0xF7, 0x82, 0x30, 0xB0, 0x1B, 0x62, 0xA4,
+0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x45, 0x00,
+0xD4, 0x1B, 0x62, 0xAC, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0x20, 0xBD, 0x02, 0x3C, 0xEC, 0x02, 0x03, 0x36, 0x4D, 0x00, 0x07, 0x36,
+0xF1, 0x02, 0x08, 0x36, 0x08, 0x00, 0x06, 0x24, 0x78, 0x02, 0x42, 0x34,
+0x00, 0x00, 0x45, 0xA4, 0x00, 0x00, 0xE0, 0xA0, 0x00, 0x00, 0x06, 0xA1,
+0x00, 0x00, 0x60, 0xAC, 0x00, 0x00, 0x62, 0x8C, 0xFF, 0x00, 0x04, 0x3C,
+0x00, 0x00, 0xE0, 0xA0, 0xFF, 0x00, 0x49, 0x30, 0x25, 0x48, 0x24, 0x01,
+0x00, 0x00, 0x06, 0xA1, 0xF2, 0x02, 0x05, 0x36, 0x00, 0x00, 0x64, 0xAC,
+0x0A, 0x00, 0x0A, 0x36, 0x00, 0x00, 0x69, 0xAC, 0x80, 0xFF, 0x03, 0x24,
+0x00, 0x00, 0xA0, 0xA0, 0x00, 0x00, 0x43, 0xA1, 0x00, 0x00, 0x62, 0x8D,
+0x80, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x00, 0x40, 0x10,
+0x84, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x42, 0xA1, 0x2C, 0x1F, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x02, 0x36, 0x00, 0x00, 0x43, 0x94,
+0xFF, 0xBF, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA4,
+0x25, 0x32, 0x00, 0x08, 0x60, 0x1B, 0x67, 0x26, 0x70, 0x30, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x2A, 0xB0, 0x06, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x54, 0xAC, 0x28, 0x00, 0xC3, 0x34,
+0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x24, 0x31,
+0x6D, 0x03, 0x85, 0x10, 0x25, 0xBD, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31,
+0x59, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10,
+0xFF, 0x00, 0x23, 0x31, 0x60, 0x1B, 0x70, 0x26, 0x4C, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x98, 0x37, 0x09, 0xA2, 0xE0, 0x37, 0x03, 0xAE,
+0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91,
+0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E,
+0x60, 0x00, 0x02, 0x3C, 0x02, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x30, 0xC2, 0x00, 0x00, 0x08, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34,
+0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC,
+0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE,
+0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x40, 0x00, 0x04, 0x3C,
+0x26, 0x18, 0x64, 0x00, 0x9A, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC,
+0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C,
+0x24, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24,
+0xFF, 0x00, 0x24, 0x31, 0x48, 0x03, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C,
+0x00, 0x80, 0x22, 0x31, 0x64, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24,
+0x25, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31,
+0x4C, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x94, 0x37, 0x09, 0xA2,
+0xE0, 0x37, 0x03, 0xAE, 0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C,
+0xC0, 0x5D, 0x47, 0x91, 0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D,
+0xD0, 0x1B, 0x06, 0x8E, 0x60, 0x00, 0x02, 0x3C, 0x04, 0x00, 0xE7, 0x34,
+0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x08, 0xA5, 0x34,
+0x25, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00,
+0x26, 0xA0, 0x82, 0x02, 0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00,
+0x80, 0x03, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC,
+0x00, 0x00, 0x46, 0xAC, 0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1,
+0xD0, 0x1B, 0x06, 0xAE, 0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26,
+0xD4, 0x1B, 0x43, 0x8C, 0x20, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00,
+0x92, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, 0x70, 0x30, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x05, 0x3C, 0xB0, 0x03, 0xA2, 0x34,
+0x2A, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0x54, 0xAC, 0x20, 0x00, 0xE3, 0x34,
+0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31,
+0x07, 0x03, 0x86, 0x10, 0x90, 0x03, 0xA2, 0x34, 0x00, 0x80, 0x22, 0x31,
+0x05, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10,
+0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x40, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x9C, 0x37, 0x09, 0xA2, 0xD4, 0x37, 0x03, 0xAE,
+0x05, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91,
+0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E,
+0x18, 0x00, 0x02, 0x3C, 0x01, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x30, 0xC2, 0x00, 0x00, 0x04, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34,
+0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC,
+0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE,
+0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x10, 0x00, 0x04, 0x3C,
+0x26, 0x18, 0x64, 0x00, 0x8B, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC,
+0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C,
+0x0C, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24,
+0xFF, 0x00, 0x24, 0x31, 0xC6, 0x02, 0x86, 0x10, 0x00, 0x80, 0x22, 0x31,
+0x54, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x00, 0x82, 0x10,
+0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x28, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x80, 0x37, 0x09, 0xA2, 0xBC, 0x37, 0x03, 0xAE,
+0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, 0xC0, 0x5D, 0x47, 0x91,
+0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, 0xD0, 0x1B, 0x06, 0x8E,
+0x01, 0x00, 0x08, 0x3C, 0x80, 0xFF, 0x02, 0x24, 0x25, 0x38, 0xE2, 0x00,
+0x00, 0x80, 0x03, 0x35, 0x00, 0x01, 0xA5, 0x34, 0x27, 0x18, 0x03, 0x00,
+0x00, 0x26, 0x07, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x24, 0x30, 0xC3, 0x00,
+0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0x44, 0xAC, 0x27, 0xA0, 0x08, 0x00, 0x00, 0x00, 0x66, 0xAC,
+0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, 0xD0, 0x1B, 0x06, 0xAE,
+0x60, 0x1B, 0x63, 0x26, 0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x42, 0x38, 0xD4, 0x1B, 0x62, 0xAC, 0x60, 0x1B, 0x70, 0x26,
+0xD0, 0x1B, 0x02, 0x8E, 0x01, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, 0x11, 0xFE, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x2A, 0xB0, 0x05, 0x3C, 0x10, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C,
+0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31, 0x7C, 0x02, 0x86, 0x10,
+0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31, 0xD0, 0x01, 0x40, 0x10,
+0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24,
+0x22, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31,
+0x28, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x84, 0x37, 0x09, 0xA2,
+0xBC, 0x37, 0x03, 0xAE, 0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C,
+0xC0, 0x5D, 0x27, 0x91, 0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D,
+0xD0, 0x1B, 0x06, 0x8E, 0x01, 0x00, 0x02, 0x3C, 0x00, 0x80, 0x42, 0x34,
+0x40, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00,
+0x00, 0x01, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC, 0xB0, 0x5D, 0x05, 0xAD,
+0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, 0x60, 0x1B, 0x62, 0x26,
+0xD4, 0x1B, 0x43, 0x8C, 0x01, 0x00, 0x04, 0x3C, 0x60, 0x1B, 0x70, 0x26,
+0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC, 0xD0, 0x1B, 0x02, 0x8E,
+0x02, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x43, 0x00,
+0xDB, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C, 0x14, 0x00, 0xA3, 0x34,
+0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31,
+0x64, 0x02, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31,
+0xFA, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x25, 0x00, 0x82, 0x10,
+0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x34, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x88, 0x37, 0x09, 0xA2, 0xC8, 0x37, 0x03, 0xAE,
+0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, 0xC0, 0x5D, 0x47, 0x91,
+0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, 0xD0, 0x1B, 0x06, 0x8E,
+0x06, 0x00, 0x02, 0x3C, 0x20, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x30, 0xC2, 0x00, 0x00, 0x02, 0xA5, 0x34, 0x25, 0xB0, 0x03, 0x3C,
+0x04, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00, 0x26, 0xA0, 0x82, 0x02,
+0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x63, 0x34,
+0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x00, 0x00, 0x46, 0xAC,
+0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, 0xD0, 0x1B, 0x06, 0xAE,
+0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C,
+0x02, 0x00, 0x04, 0x3C, 0x60, 0x1B, 0x70, 0x26, 0x26, 0x18, 0x64, 0x00,
+0xD4, 0x1B, 0x43, 0xAC, 0xD0, 0x1B, 0x02, 0x8E, 0x04, 0x00, 0x03, 0x3C,
+0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00,
+0xA1, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x62, 0x34,
+0x2A, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0x54, 0xAC, 0x18, 0x00, 0xE5, 0x34,
+0x00, 0x00, 0xA9, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31,
+0x16, 0x02, 0x86, 0x10, 0x04, 0x00, 0x02, 0x24, 0x00, 0x80, 0x22, 0x31,
+0xD6, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0xA2, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10,
+0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x34, 0x38, 0x05, 0x8E,
+0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00,
+0x21, 0x30, 0x60, 0x00, 0x8C, 0x37, 0x09, 0xA2, 0xC8, 0x37, 0x03, 0xAE,
+0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C,
+0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91,
+0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E,
+0x06, 0x00, 0x02, 0x3C, 0x10, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x30, 0xC2, 0x00, 0x00, 0x02, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34,
+0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC,
+0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE,
+0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x04, 0x00, 0x04, 0x3C,
+0x60, 0x1B, 0x70, 0x26, 0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC,
+0xD0, 0x1B, 0x02, 0x8E, 0x08, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00,
+0x24, 0x10, 0x43, 0x00, 0x68, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C,
+0x1C, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24,
+0xFF, 0x00, 0x24, 0x31, 0xDD, 0x01, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C,
+0x00, 0x80, 0x22, 0x31, 0x33, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24,
+0x25, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31,
+0x40, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x90, 0x37, 0x09, 0xA2,
+0xD4, 0x37, 0x03, 0xAE, 0x05, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C,
+0xC0, 0x5D, 0x47, 0x91, 0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D,
+0xD0, 0x1B, 0x06, 0x8E, 0x18, 0x00, 0x02, 0x3C, 0x08, 0x00, 0xE7, 0x34,
+0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x04, 0xA5, 0x34,
+0x25, 0xB0, 0x03, 0x3C, 0x10, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00,
+0x26, 0xA0, 0x82, 0x02, 0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00,
+0x80, 0x03, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC,
+0x00, 0x00, 0x46, 0xAC, 0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1,
+0xD0, 0x1B, 0x06, 0xAE, 0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26,
+0xD4, 0x1B, 0x43, 0x8C, 0x08, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00,
+0x83, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, 0x70, 0x30, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xD4, 0x1B, 0x02, 0x8E, 0xD0, 0x1B, 0x03, 0x8E,
+0x00, 0x20, 0x42, 0x38, 0x62, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x02, 0xAE,
+0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x02, 0x3C,
+0x08, 0x00, 0x43, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x24, 0x31, 0x2C, 0x00, 0x82, 0x10, 0x00, 0x80, 0x22, 0x31,
+0x34, 0x01, 0x40, 0x14, 0x00, 0x80, 0x02, 0x3C, 0x00, 0xFF, 0x02, 0x3C,
+0x24, 0x10, 0x22, 0x01, 0x0B, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0xA8, 0x37, 0x02, 0x92, 0x20, 0xB0, 0x03, 0x3C, 0x00, 0x12, 0x02, 0x00,
+0x21, 0x10, 0x43, 0x00, 0x0C, 0x00, 0x49, 0x8C, 0x25, 0xB0, 0x03, 0x3C,
+0xB0, 0x03, 0x63, 0x34, 0x00, 0x00, 0x69, 0xAC, 0xFF, 0x00, 0x24, 0x31,
+0xFF, 0x00, 0x02, 0x24, 0x1A, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26,
+0xFF, 0x00, 0x23, 0x31, 0x70, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00,
+0x04, 0x38, 0x03, 0xAE, 0x01, 0x00, 0x04, 0x24, 0xA8, 0x37, 0x09, 0xA2,
+0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF,
+0xD0, 0x1B, 0x05, 0x8E, 0x02, 0x80, 0x06, 0x3C, 0xB0, 0x5D, 0xC4, 0x8C,
+0xFF, 0xC7, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x10, 0x00, 0x84, 0x34, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x65, 0xAC, 0xB0, 0x5D, 0xC4, 0xAC,
+0xD0, 0x1B, 0x05, 0xAE, 0x60, 0x1B, 0x63, 0x26, 0xD4, 0x1B, 0x62, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x38, 0x5B, 0x32, 0x00, 0x08,
+0xD4, 0x1B, 0x62, 0xAC, 0x56, 0x01, 0x02, 0x35, 0x00, 0x00, 0x43, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x74, 0xFC, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x7E, 0x58, 0x00, 0x0C, 0x07, 0x00, 0x04, 0x24, 0x12, 0x32, 0x00, 0x08,
+0x60, 0x1B, 0x64, 0x26, 0x00, 0x00, 0x62, 0xAC, 0xB8, 0x32, 0x00, 0x08,
+0xFF, 0x00, 0x02, 0x24, 0xE4, 0x1D, 0x24, 0x96, 0x58, 0x38, 0x26, 0x96,
+0x01, 0x00, 0x84, 0x24, 0x00, 0x19, 0x04, 0x00, 0x25, 0x30, 0xC2, 0x00,
+0xF0, 0xFF, 0x63, 0x30, 0x20, 0x00, 0xC5, 0x24, 0x02, 0x12, 0x03, 0x00,
+0xE4, 0x1D, 0x24, 0xA6, 0x17, 0x00, 0xA2, 0xA0, 0x16, 0x00, 0xA3, 0xA0,
+0x0C, 0x00, 0xC4, 0x8C, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0xFF, 0x0F, 0x63, 0x30, 0x00, 0x1C, 0x03, 0x00, 0x24, 0x20, 0x82, 0x00,
+0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0xC4, 0xAC, 0x58, 0x38, 0x25, 0x8E,
+0x01, 0x00, 0x10, 0x24, 0x01, 0x00, 0x04, 0x24, 0x31, 0x10, 0x06, 0x3C,
+0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF,
+0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x2A, 0xB0, 0x02, 0x3C,
+0x01, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x50, 0xA0,
+0x00, 0x00, 0x43, 0xA0, 0xD4, 0x1B, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x42, 0x38, 0x4D, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x22, 0xAE,
+0xD0, 0x03, 0x23, 0x35, 0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xAC,
+0x09, 0x33, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x25, 0xB0, 0x02, 0x3C,
+0x01, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0xD5, 0x32, 0x00, 0x08, 0x60, 0x1B, 0x65, 0x26, 0x24, 0x10, 0x22, 0x01,
+0xA9, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x47, 0x00, 0xC6, 0x34,
+0x00, 0x00, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30,
+0x0E, 0x00, 0x85, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x98, 0x37, 0x04, 0xA2,
+0x00, 0x00, 0xC2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30,
+0x07, 0x00, 0x83, 0x10, 0x21, 0x38, 0x00, 0x02, 0x21, 0x28, 0xC0, 0x00,
+0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14,
+0xFF, 0x00, 0x44, 0x30, 0x98, 0x37, 0xE3, 0xA0, 0x60, 0x1B, 0x62, 0x26,
+0x98, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC,
+0x81, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01,
+0xFD, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x45, 0x00, 0xE5, 0x34,
+0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30,
+0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x9C, 0x37, 0x04, 0xA2,
+0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30,
+0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x21, 0x30, 0x00, 0x02,
+0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14,
+0xFF, 0x00, 0x44, 0x30, 0x9C, 0x37, 0xC3, 0xA0, 0x60, 0x1B, 0x62, 0x26,
+0x9C, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC,
+0xF6, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01,
+0x9E, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x46, 0x00, 0xA5, 0x34,
+0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30,
+0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x94, 0x37, 0x04, 0xA2,
+0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30,
+0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x21, 0x30, 0x00, 0x02,
+0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14,
+0xFF, 0x00, 0x44, 0x30, 0x94, 0x37, 0xC3, 0xA0, 0x60, 0x1B, 0x62, 0x26,
+0x94, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C,
+0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC,
+0xB8, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x00, 0xFF, 0x02, 0x3C,
+0x24, 0x10, 0x22, 0x01, 0x30, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0x41, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x84, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30,
+0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00,
+0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x84, 0x37, 0xC3, 0xA0,
+0x60, 0x1B, 0x62, 0x26, 0x84, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31,
+0x00, 0x00, 0x49, 0xAC, 0x6C, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x24, 0x10, 0x22, 0x01, 0xCF, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0x44, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x90, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30,
+0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00,
+0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x90, 0x37, 0xC3, 0xA0,
+0x60, 0x1B, 0x62, 0x26, 0x90, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31,
+0x00, 0x00, 0x49, 0xAC, 0x2C, 0x35, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x24, 0x10, 0x22, 0x01, 0xAE, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0x40, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x80, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30,
+0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00,
+0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x80, 0x37, 0xC3, 0xA0,
+0x60, 0x1B, 0x62, 0x26, 0x80, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31,
+0x00, 0x00, 0x49, 0xAC, 0x2C, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x62, 0xAC, 0x78, 0x35, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x24, 0x10, 0x22, 0x01, 0x08, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0x42, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x88, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30,
+0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00,
+0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x88, 0x37, 0xC3, 0xA0,
+0x60, 0x1B, 0x62, 0x26, 0x88, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31,
+0x00, 0x00, 0x49, 0xAC, 0xAA, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x24, 0x10, 0x22, 0x01, 0x2C, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24,
+0x43, 0x00, 0xE5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x8C, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30,
+0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26,
+0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00,
+0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x8C, 0x37, 0xC3, 0xA0,
+0x60, 0x1B, 0x62, 0x26, 0x8C, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31,
+0x00, 0x00, 0x49, 0xAC, 0xEF, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24,
+0x06, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x90, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x01, 0x00, 0x03, 0x24,
+0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0xA4, 0x33, 0x00, 0x08,
+0x60, 0x1B, 0x62, 0x26, 0x25, 0xB0, 0x02, 0x3C, 0x07, 0x00, 0x03, 0x24,
+0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x60, 0x1B, 0x63, 0x26,
+0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, 0x38,
+0x56, 0x34, 0x00, 0x08, 0xD4, 0x1B, 0x62, 0xAC, 0x00, 0x00, 0x40, 0xAC,
+0x19, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x02, 0x00, 0x03, 0x24,
+0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0xDF, 0x33, 0x00, 0x08,
+0x60, 0x1B, 0x62, 0x26, 0x90, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC,
+0x12, 0x35, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x03, 0x00, 0x03, 0x24,
+0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x53, 0x35, 0x00, 0x08,
+0x60, 0x1B, 0x62, 0x26, 0x05, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0xD1, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26,
+0xE0, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x25, 0xB0, 0x0C, 0x3C,
+0x01, 0x80, 0x02, 0x3C, 0x18, 0x03, 0x83, 0x35, 0x30, 0xDC, 0x42, 0x24,
+0x02, 0x80, 0x12, 0x3C, 0x41, 0xB0, 0x0B, 0x3C, 0x00, 0x00, 0x62, 0xAC,
+0x60, 0x1B, 0x4A, 0x26, 0x0A, 0x00, 0x62, 0x35, 0x00, 0x00, 0x44, 0x94,
+0xDE, 0x1B, 0x43, 0x95, 0xDC, 0x1B, 0x49, 0x95, 0x25, 0x30, 0x64, 0x00,
+0xFF, 0xFF, 0xD0, 0x30, 0x24, 0x10, 0x09, 0x02, 0x02, 0x00, 0x42, 0x30,
+0xC2, 0x00, 0x40, 0x10, 0xC0, 0x03, 0x83, 0x35, 0x02, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x62, 0xAC, 0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x04, 0x8D,
+0xDC, 0x02, 0x82, 0x35, 0x00, 0x00, 0x47, 0x90, 0xFD, 0xFF, 0x03, 0x24,
+0x00, 0x80, 0x02, 0x3C, 0x24, 0x18, 0x23, 0x01, 0x25, 0x20, 0x82, 0x00,
+0x02, 0x00, 0xC6, 0x38, 0x08, 0x00, 0x65, 0x35, 0x02, 0x80, 0x02, 0x3C,
+0xED, 0x5D, 0x47, 0xA0, 0xB0, 0x5D, 0x04, 0xAD, 0xDE, 0x1B, 0x46, 0xA5,
+0x21, 0x48, 0x60, 0x00, 0x00, 0x00, 0xA3, 0xA4, 0xDC, 0x1B, 0x43, 0xA5,
+0x24, 0x38, 0x09, 0x02, 0x04, 0x00, 0xE2, 0x30, 0x0A, 0x00, 0x40, 0x10,
+0x08, 0x00, 0xE2, 0x30, 0xDE, 0x1B, 0x43, 0x95, 0x0C, 0x00, 0x64, 0x35,
+0xC0, 0x03, 0x85, 0x35, 0x04, 0x00, 0x63, 0x38, 0x04, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x86, 0x90, 0x00, 0x00, 0xA2, 0xAC, 0xDE, 0x1B, 0x43, 0xA5,
+0x08, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x10, 0x00, 0xE2, 0x30,
+0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x08, 0x00, 0x03, 0x24,
+0x08, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5,
+0x10, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x20, 0x00, 0xE2, 0x30,
+0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x10, 0x00, 0x03, 0x24,
+0x10, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5,
+0x20, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0xE2, 0x30,
+0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x20, 0x00, 0x03, 0x24,
+0x20, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5,
+0x80, 0x00, 0xE2, 0x30, 0x74, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x47, 0x26,
+0xC0, 0x03, 0x83, 0x35, 0x80, 0x00, 0x02, 0x24, 0x42, 0xB0, 0x0B, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0x03, 0x00, 0x71, 0x35, 0xDE, 0x1B, 0x42, 0x95,
+0x00, 0x00, 0x23, 0x92, 0x80, 0x00, 0x42, 0x38, 0x20, 0x00, 0x63, 0x30,
+0x59, 0x00, 0x60, 0x10, 0xDE, 0x1B, 0x42, 0xA5, 0x20, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x22, 0xA2, 0x02, 0x80, 0x03, 0x3C, 0x0F, 0x5E, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x40, 0x14, 0x21, 0x40, 0x00, 0x00,
+0xB0, 0x1B, 0x42, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30,
+0x4E, 0x00, 0x40, 0x10, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C,
+0xEC, 0x5D, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x09, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0xF8, 0x5D, 0x82, 0x8C,
+0x18, 0x5E, 0x24, 0x8D, 0x1C, 0x5E, 0x25, 0x8D, 0x21, 0x18, 0x00, 0x00,
+0x21, 0x10, 0x44, 0x00, 0x2B, 0x30, 0x44, 0x00, 0x21, 0x18, 0x65, 0x00,
+0x21, 0x18, 0x66, 0x00, 0x18, 0x5E, 0x22, 0xAD, 0x1C, 0x5E, 0x23, 0xAD,
+0xEC, 0x5D, 0xE4, 0x90, 0x02, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x84, 0x30,
+0x07, 0x00, 0x82, 0x10, 0x02, 0x80, 0x04, 0x3C, 0xEC, 0x5D, 0xE2, 0x90,
+0x03, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x5A, 0x00, 0x43, 0x14,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x0A, 0x5E, 0x82, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x42, 0x24, 0x0A, 0x5E, 0x82, 0xA0,
+0x0A, 0x5E, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x60, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0xF2, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x11,
+0x80, 0x00, 0x86, 0x35, 0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0x09, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x5E, 0x83, 0xA0,
+0x02, 0x80, 0x05, 0x3C, 0x07, 0x5E, 0xA2, 0x90, 0x02, 0x80, 0x03, 0x3C,
+0x02, 0x00, 0x04, 0x24, 0x10, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xA2, 0xA0,
+0xF1, 0x5D, 0x62, 0x90, 0x21, 0x28, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30,
+0x80, 0x30, 0x02, 0x00, 0x21, 0x30, 0xC2, 0x00, 0xB9, 0x20, 0x00, 0x0C,
+0x00, 0x33, 0x06, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x04, 0x24,
+0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C,
+0xEE, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30,
+0x04, 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x10, 0x02, 0x80, 0x06, 0x3C,
+0x04, 0x00, 0x04, 0x24, 0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24,
+0x02, 0x80, 0x06, 0x3C, 0xB0, 0x5D, 0xC4, 0x8C, 0x60, 0x1B, 0x47, 0x26,
+0xDC, 0x1B, 0xE5, 0x94, 0x10, 0x00, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00,
+0x41, 0xB0, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x7F, 0xFF, 0xA5, 0x30,
+0xB0, 0x03, 0x42, 0x34, 0x08, 0x00, 0x63, 0x34, 0x00, 0x00, 0x44, 0xAC,
+0x00, 0x00, 0x65, 0xA4, 0xB0, 0x5D, 0xC4, 0xAC, 0xDC, 0x1B, 0xE5, 0xA4,
+0x60, 0x1B, 0x47, 0x26, 0xDC, 0x1B, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x10, 0x50, 0x00, 0x00, 0x30, 0x42, 0x30, 0x06, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xDE, 0x1B, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x42, 0x38, 0x00, 0x20, 0x42, 0x34, 0xDE, 0x1B, 0xE2, 0xA4,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x36, 0x37, 0x00, 0x08, 0xDE, 0x1B, 0x46, 0xA5, 0x01, 0x00, 0x08, 0x24,
+0x0F, 0x5E, 0x60, 0xA0, 0x72, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x5E, 0xA2, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x00, 0x04, 0x24,
+0x10, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xA2, 0xA0, 0xF1, 0x5D, 0x62, 0x90,
+0x21, 0x28, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x80, 0x30, 0x02, 0x00,
+0x21, 0x30, 0xC2, 0x00, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0x33, 0x06, 0x00,
+0x44, 0x00, 0x02, 0x24, 0x00, 0x00, 0x22, 0xA2, 0xBA, 0x37, 0x00, 0x08,
+0x02, 0x80, 0x03, 0x3C, 0x84, 0x00, 0x84, 0x35, 0x00, 0x00, 0x82, 0x8C,
+0x02, 0x80, 0x08, 0x3C, 0x00, 0x00, 0xC4, 0x8C, 0x14, 0x5E, 0x06, 0x8D,
+0x21, 0x10, 0x00, 0x00, 0x18, 0x5E, 0x28, 0x8D, 0x1C, 0x5E, 0x29, 0x8D,
+0x00, 0x00, 0x65, 0x91, 0x25, 0x10, 0x44, 0x00, 0x21, 0x10, 0x46, 0x00,
+0xFB, 0xFF, 0x04, 0x24, 0x24, 0x28, 0xA4, 0x00, 0x23, 0x40, 0x02, 0x01,
+0x00, 0x00, 0x65, 0xA1, 0x04, 0x00, 0x00, 0x11, 0x01, 0x00, 0x06, 0x24,
+0x80, 0x10, 0x08, 0x00, 0x21, 0x10, 0x48, 0x00, 0x80, 0x30, 0x02, 0x00,
+0x01, 0x00, 0x04, 0x24, 0xB9, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xA0, 0xC4, 0x37, 0x00, 0x08, 0x02, 0x80, 0x06, 0x3C,
+0xF0, 0xFF, 0xBD, 0x27, 0x08, 0x00, 0xB2, 0xAF, 0x04, 0x00, 0xB1, 0xAF,
+0x00, 0x00, 0xB0, 0xAF, 0x00, 0x40, 0x09, 0x40, 0x00, 0x68, 0x0A, 0x40,
+0x00, 0x70, 0x02, 0x40, 0x00, 0x60, 0x0B, 0x40, 0x25, 0xB0, 0x05, 0x3C,
+0x18, 0x03, 0xA7, 0x34, 0x00, 0x00, 0xE6, 0x8C, 0x01, 0x80, 0x02, 0x3C,
+0x1C, 0x03, 0xA3, 0x34, 0x5C, 0xE0, 0x42, 0x24, 0x00, 0x00, 0x66, 0xAC,
+0x00, 0x00, 0xE2, 0xAC, 0x80, 0x00, 0x83, 0x8C, 0x7C, 0x02, 0xA2, 0x34,
+0x80, 0x02, 0xA6, 0x34, 0x84, 0x02, 0xA7, 0x34, 0x88, 0x02, 0xA8, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0x00, 0x00, 0xC9, 0xAC, 0x00, 0x00, 0xEA, 0xAC,
+0x00, 0x00, 0x0B, 0xAD, 0x74, 0x00, 0x83, 0x8C, 0x8C, 0x02, 0xA2, 0x34,
+0x90, 0x02, 0xA7, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0x86, 0x8C,
+0x94, 0x02, 0xA8, 0x34, 0x98, 0x02, 0xA9, 0x34, 0x00, 0x00, 0xE6, 0xAC,
+0x0C, 0x00, 0x82, 0x8C, 0x9C, 0x02, 0xA6, 0x34, 0xA0, 0x02, 0xA7, 0x34,
+0x00, 0x00, 0x02, 0xAD, 0x10, 0x00, 0x83, 0x8C, 0xA4, 0x02, 0xA8, 0x34,
+0xA8, 0x02, 0xAA, 0x34, 0x00, 0x00, 0x23, 0xAD, 0x14, 0x00, 0x82, 0x8C,
+0xAC, 0x02, 0xA9, 0x34, 0xB0, 0x02, 0xAB, 0x34, 0x00, 0x00, 0xC2, 0xAC,
+0x18, 0x00, 0x83, 0x8C, 0xB4, 0x02, 0xAC, 0x34, 0xB8, 0x02, 0xAD, 0x34,
+0x00, 0x00, 0xE3, 0xAC, 0x1C, 0x00, 0x82, 0x8C, 0xBC, 0x02, 0xA7, 0x34,
+0xC0, 0x02, 0xAE, 0x34, 0x00, 0x00, 0x02, 0xAD, 0x20, 0x00, 0x83, 0x8C,
+0xC4, 0x02, 0xA8, 0x34, 0xC8, 0x02, 0xAF, 0x34, 0x00, 0x00, 0x43, 0xAD,
+0x24, 0x00, 0x82, 0x8C, 0xCC, 0x02, 0xAA, 0x34, 0xD0, 0x02, 0xB0, 0x34,
+0x00, 0x00, 0x22, 0xAD, 0x28, 0x00, 0x83, 0x8C, 0xD4, 0x02, 0xA9, 0x34,
+0xD8, 0x02, 0xB1, 0x34, 0x00, 0x00, 0x63, 0xAD, 0x2C, 0x00, 0x86, 0x8C,
+0x70, 0x02, 0xAB, 0x34, 0x74, 0x02, 0xB2, 0x34, 0x00, 0x00, 0x86, 0xAD,
+0x30, 0x00, 0x82, 0x8C, 0x78, 0x02, 0xA6, 0x34, 0x6C, 0x03, 0xAC, 0x34,
+0x00, 0x00, 0xA2, 0xAD, 0x34, 0x00, 0x83, 0x8C, 0x02, 0x80, 0x02, 0x3C,
+0x00, 0x00, 0xE3, 0xAC, 0x38, 0x00, 0x85, 0x8C, 0xE0, 0xC8, 0x47, 0x8C,
+0x00, 0x00, 0xC5, 0xAD, 0x3C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xAD, 0x40, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xE3, 0xAD, 0x44, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x42, 0xAD, 0x48, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xAE, 0x4C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x22, 0xAD, 0x50, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x23, 0xAE, 0x54, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x62, 0xAD, 0x58, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x43, 0xAE, 0x5C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC2, 0xAC, 0x21, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x82, 0xAD,
+0x01, 0x00, 0xE7, 0x24, 0x21, 0x10, 0xE0, 0x00, 0x01, 0x00, 0xE7, 0x24,
+0x00, 0x00, 0x82, 0xAD, 0x82, 0x38, 0x00, 0x08, 0x21, 0x10, 0xE0, 0x00,
+0x01, 0x80, 0x1B, 0x3C, 0x24, 0xE2, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C,
+0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, 0x21, 0xD8, 0xA0, 0x03,
+0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00, 0x08, 0x00, 0x7B, 0x27,
+0x04, 0x00, 0x61, 0xAF, 0x08, 0x00, 0x62, 0xAF, 0x0C, 0x00, 0x63, 0xAF,
+0x10, 0x00, 0x64, 0xAF, 0x14, 0x00, 0x65, 0xAF, 0x18, 0x00, 0x66, 0xAF,
+0x1C, 0x00, 0x67, 0xAF, 0x20, 0x00, 0x68, 0xAF, 0x24, 0x00, 0x69, 0xAF,
+0x28, 0x00, 0x6A, 0xAF, 0x2C, 0x00, 0x6B, 0xAF, 0x30, 0x00, 0x6C, 0xAF,
+0x34, 0x00, 0x6D, 0xAF, 0x38, 0x00, 0x6E, 0xAF, 0x3C, 0x00, 0x6F, 0xAF,
+0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x40,
+0x40, 0x00, 0x70, 0xAF, 0x44, 0x00, 0x71, 0xAF, 0x48, 0x00, 0x72, 0xAF,
+0x4C, 0x00, 0x73, 0xAF, 0x50, 0x00, 0x74, 0xAF, 0x54, 0x00, 0x75, 0xAF,
+0x58, 0x00, 0x76, 0xAF, 0x5C, 0x00, 0x77, 0xAF, 0x60, 0x00, 0x78, 0xAF,
+0x64, 0x00, 0x79, 0xAF, 0x68, 0x00, 0x7C, 0xAF, 0x6C, 0x00, 0x7D, 0xAF,
+0x70, 0x00, 0x7E, 0xAF, 0x74, 0x00, 0x7F, 0xAF, 0x78, 0x00, 0x68, 0xAF,
+0x7C, 0x00, 0x69, 0xAF, 0x80, 0x00, 0x6A, 0xAF, 0x00, 0x68, 0x1A, 0x40,
+0x25, 0xB0, 0x1B, 0x3C, 0x1C, 0x03, 0x7B, 0x37, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7A, 0xAF, 0x7F, 0x00, 0x5B, 0x33, 0x30, 0x00, 0x60, 0x13,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x1B, 0x3C, 0x30, 0x03, 0x7B, 0x37,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xAF, 0x00, 0x00, 0x00, 0x00,
+0x21, 0xD8, 0xA0, 0x03, 0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00,
+0x08, 0x00, 0x7B, 0x27, 0x04, 0x00, 0x61, 0xAF, 0x08, 0x00, 0x62, 0xAF,
+0x0C, 0x00, 0x63, 0xAF, 0x10, 0x00, 0x64, 0xAF, 0x14, 0x00, 0x65, 0xAF,
+0x18, 0x00, 0x66, 0xAF, 0x1C, 0x00, 0x67, 0xAF, 0x20, 0x00, 0x68, 0xAF,
+0x24, 0x00, 0x69, 0xAF, 0x28, 0x00, 0x6A, 0xAF, 0x2C, 0x00, 0x6B, 0xAF,
+0x30, 0x00, 0x6C, 0xAF, 0x34, 0x00, 0x6D, 0xAF, 0x38, 0x00, 0x6E, 0xAF,
+0x3C, 0x00, 0x6F, 0xAF, 0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00,
+0x00, 0x70, 0x0A, 0x40, 0x40, 0x00, 0x70, 0xAF, 0x44, 0x00, 0x71, 0xAF,
+0x48, 0x00, 0x72, 0xAF, 0x4C, 0x00, 0x73, 0xAF, 0x50, 0x00, 0x74, 0xAF,
+0x54, 0x00, 0x75, 0xAF, 0x58, 0x00, 0x76, 0xAF, 0x5C, 0x00, 0x77, 0xAF,
+0x60, 0x00, 0x78, 0xAF, 0x64, 0x00, 0x79, 0xAF, 0x68, 0x00, 0x7C, 0xAF,
+0x6C, 0x00, 0x7D, 0xAF, 0x70, 0x00, 0x7E, 0xAF, 0x74, 0x00, 0x7F, 0xAF,
+0x78, 0x00, 0x68, 0xAF, 0x7C, 0x00, 0x69, 0xAF, 0x80, 0x00, 0x6A, 0xAF,
+0x17, 0x38, 0x00, 0x08, 0x21, 0x20, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x08, 0x3C, 0x20, 0x03, 0x08, 0x35, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1A, 0xAD, 0x00, 0x04, 0x5B, 0x33, 0x0A, 0x00, 0x60, 0x13,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3C, 0xE0, 0xC7, 0x08, 0x25,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x1B, 0x3C, 0x24, 0x03, 0x7B, 0x37,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xAF, 0x09, 0xF8, 0x00, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5B, 0x33, 0x25, 0xB0, 0x08, 0x3C,
+0x28, 0x03, 0x08, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xAD,
+0x06, 0x00, 0x60, 0x13, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3C,
+0x30, 0xDC, 0x08, 0x25, 0x00, 0x00, 0x00, 0x00, 0x09, 0xF8, 0x00, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x1A, 0x3C, 0xB0, 0x5D, 0x5A, 0x27,
+0x04, 0x00, 0x5B, 0x97, 0x25, 0xB0, 0x08, 0x3C, 0x30, 0x03, 0x08, 0x35,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xAD, 0x18, 0x00, 0x60, 0x13,
+0x00, 0x00, 0x00, 0x00, 0x08, 0xE8, 0x9B, 0x27, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x61, 0x8F, 0xFC, 0x03, 0x70, 0x7B, 0x7C, 0x00, 0x62, 0x7B,
+0xBC, 0x00, 0x64, 0x7B, 0xFC, 0x00, 0x66, 0x7B, 0x3C, 0x01, 0x68, 0x7B,
+0x13, 0x00, 0x00, 0x02, 0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x6A, 0x7B,
+0xBC, 0x01, 0x6C, 0x7B, 0xFC, 0x01, 0x6E, 0x7B, 0x3C, 0x02, 0x70, 0x7B,
+0x7C, 0x02, 0x72, 0x7B, 0xBC, 0x02, 0x74, 0x7B, 0xFC, 0x02, 0x76, 0x7B,
+0x3C, 0x03, 0x78, 0x7B, 0x7C, 0x03, 0x7C, 0x7B, 0xBC, 0x03, 0x7E, 0x7B,
+0x80, 0x00, 0x7B, 0x8F, 0x74, 0x39, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x21, 0xD8, 0xA0, 0x03, 0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00,
+0x08, 0x00, 0x7B, 0x27, 0x08, 0x00, 0x5B, 0xAF, 0xFC, 0xEB, 0x9D, 0x27,
+0x00, 0x00, 0x4A, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x11,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x08, 0x3C, 0x10, 0x5D, 0x08, 0x25,
+0x21, 0x48, 0x00, 0x00, 0x21, 0x58, 0x00, 0x00, 0x01, 0x00, 0x6B, 0x25,
+0x1A, 0x00, 0x40, 0x11, 0x24, 0x70, 0x4B, 0x01, 0x14, 0x00, 0xC0, 0x11,
+0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x44, 0xA3,
+0x26, 0x50, 0x4B, 0x01, 0x00, 0x00, 0x4A, 0xAF, 0x80, 0x80, 0x09, 0x00,
+0x21, 0x80, 0x08, 0x02, 0x00, 0x00, 0x10, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x09, 0xF8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1B, 0x3C,
+0xFC, 0xE4, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27,
+0x00, 0x00, 0x5B, 0xAF, 0x02, 0x80, 0x1A, 0x3C, 0xB0, 0x5D, 0x5A, 0x27,
+0xE1, 0xFF, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, 0x25,
+0x40, 0x58, 0x0B, 0x00, 0x37, 0x39, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x1B, 0x3C, 0xB0, 0x5D, 0x7B, 0x27, 0x21, 0x60, 0x00, 0x00,
+0x04, 0x00, 0x6C, 0xA7, 0x08, 0x00, 0x7A, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0xF8, 0xFF, 0x5A, 0x27, 0x00, 0x00, 0x5A, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x5A, 0x27, 0x84, 0x00, 0x44, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0xF9, 0xFF, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x8F,
+0xFC, 0x03, 0x50, 0x7B, 0x7C, 0x00, 0x42, 0x7B, 0xBC, 0x00, 0x44, 0x7B,
+0xFC, 0x00, 0x46, 0x7B, 0x3C, 0x01, 0x48, 0x7B, 0x13, 0x00, 0x00, 0x02,
+0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x4A, 0x7B, 0xBC, 0x01, 0x4C, 0x7B,
+0xFC, 0x01, 0x4E, 0x7B, 0x3C, 0x02, 0x50, 0x7B, 0x7C, 0x02, 0x52, 0x7B,
+0xBC, 0x02, 0x54, 0x7B, 0xFC, 0x02, 0x56, 0x7B, 0x3C, 0x03, 0x58, 0x7B,
+0x7C, 0x03, 0x5C, 0x7B, 0xBC, 0x03, 0x5E, 0x7B, 0x80, 0x00, 0x5B, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x03, 0x10, 0x00, 0x00, 0x42,
+0x00, 0x60, 0x05, 0x40, 0x42, 0x28, 0x05, 0x00, 0x40, 0x28, 0x05, 0x00,
+0x00, 0x60, 0x85, 0x40, 0x04, 0x00, 0x81, 0xAC, 0x08, 0x00, 0x82, 0xAC,
+0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0x88, 0xAC, 0x24, 0x00, 0x89, 0xAC,
+0x28, 0x00, 0x8A, 0xAC, 0x2C, 0x00, 0x8B, 0xAC, 0x30, 0x00, 0x8C, 0xAC,
+0x34, 0x00, 0x8D, 0xAC, 0x38, 0x00, 0x8E, 0xAC, 0x3C, 0x00, 0x8F, 0xAC,
+0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x40, 0x00, 0x90, 0xAC,
+0x44, 0x00, 0x91, 0xAC, 0x48, 0x00, 0x92, 0xAC, 0x4C, 0x00, 0x93, 0xAC,
+0x50, 0x00, 0x94, 0xAC, 0x54, 0x00, 0x95, 0xAC, 0x58, 0x00, 0x96, 0xAC,
+0x5C, 0x00, 0x97, 0xAC, 0x60, 0x00, 0x98, 0xAC, 0x64, 0x00, 0x99, 0xAC,
+0x68, 0x00, 0x9C, 0xAC, 0x6C, 0x00, 0x9D, 0xAC, 0x70, 0x00, 0x9E, 0xAC,
+0x74, 0x00, 0x9F, 0xAC, 0x78, 0x00, 0x88, 0xAC, 0x7C, 0x00, 0x89, 0xAC,
+0x80, 0x00, 0x9F, 0xAC, 0xF8, 0xFF, 0x84, 0x24, 0x00, 0x00, 0x84, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x84, 0x24, 0x84, 0x00, 0x86, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0xF9, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x21, 0xD8, 0x80, 0x00, 0x01, 0x00, 0xBA, 0x34, 0x04, 0x00, 0x61, 0x8F,
+0xFC, 0x03, 0x70, 0x7B, 0x7C, 0x00, 0x62, 0x7B, 0xBC, 0x00, 0x64, 0x7B,
+0xFC, 0x00, 0x66, 0x7B, 0x3C, 0x01, 0x68, 0x7B, 0x13, 0x00, 0x00, 0x02,
+0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x6A, 0x7B, 0xBC, 0x01, 0x6C, 0x7B,
+0xFC, 0x01, 0x6E, 0x7B, 0x3C, 0x02, 0x70, 0x7B, 0x7C, 0x02, 0x72, 0x7B,
+0xBC, 0x02, 0x74, 0x7B, 0xFC, 0x02, 0x76, 0x7B, 0x3C, 0x03, 0x78, 0x7B,
+0x7C, 0x03, 0x7C, 0x7B, 0xBC, 0x03, 0x7E, 0x7B, 0x80, 0x00, 0x7B, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x03, 0x00, 0x60, 0x9A, 0x40,
+0x00, 0x60, 0x05, 0x40, 0x42, 0x28, 0x05, 0x00, 0x40, 0x28, 0x05, 0x00,
+0x00, 0x60, 0x85, 0x40, 0x04, 0x00, 0x81, 0xAC, 0x08, 0x00, 0x82, 0xAC,
+0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0x88, 0xAC, 0x24, 0x00, 0x89, 0xAC,
+0x28, 0x00, 0x8A, 0xAC, 0x2C, 0x00, 0x8B, 0xAC, 0x30, 0x00, 0x8C, 0xAC,
+0x34, 0x00, 0x8D, 0xAC, 0x38, 0x00, 0x8E, 0xAC, 0x3C, 0x00, 0x8F, 0xAC,
+0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x40, 0x00, 0x90, 0xAC,
+0x44, 0x00, 0x91, 0xAC, 0x48, 0x00, 0x92, 0xAC, 0x4C, 0x00, 0x93, 0xAC,
+0x50, 0x00, 0x94, 0xAC, 0x54, 0x00, 0x94, 0xAC, 0x58, 0x00, 0x96, 0xAC,
+0x5C, 0x00, 0x96, 0xAC, 0x60, 0x00, 0x98, 0xAC, 0x64, 0x00, 0x99, 0xAC,
+0x68, 0x00, 0x9C, 0xAC, 0x6C, 0x00, 0x9D, 0xAC, 0x70, 0x00, 0x9E, 0xAC,
+0x78, 0x00, 0x88, 0xAC, 0x7C, 0x00, 0x89, 0xAC, 0x80, 0x00, 0x9F, 0xAC,
+0x84, 0x00, 0x80, 0xAC, 0xF8, 0xFF, 0x84, 0x24, 0x00, 0x00, 0x84, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x84, 0x24, 0x84, 0x00, 0x86, 0x8C,
+0xFA, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0xD8, 0x80, 0x00,
+0x01, 0x00, 0xBA, 0x24, 0x04, 0x00, 0x61, 0x8F, 0xFC, 0x03, 0x70, 0x7B,
+0x7C, 0x00, 0x62, 0x7B, 0xBC, 0x00, 0x64, 0x7B, 0xFC, 0x00, 0x66, 0x7B,
+0x3C, 0x01, 0x68, 0x7B, 0x13, 0x00, 0x00, 0x02, 0x11, 0x00, 0x20, 0x02,
+0x7C, 0x01, 0x6A, 0x7B, 0xBC, 0x01, 0x6C, 0x7B, 0xFC, 0x01, 0x6E, 0x7B,
+0x3C, 0x02, 0x70, 0x7B, 0x7C, 0x02, 0x72, 0x7B, 0xBC, 0x02, 0x74, 0x7B,
+0xFC, 0x02, 0x76, 0x7B, 0x3C, 0x03, 0x78, 0x7B, 0x7C, 0x03, 0x7C, 0x7B,
+0xBC, 0x03, 0x7E, 0x7B, 0x80, 0x00, 0x7B, 0x8F, 0x08, 0x00, 0x60, 0x03,
+0x00, 0x60, 0x9A, 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,
+0x23, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1B, 0x3C,
+0x00, 0x00, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27,
+0x00, 0x00, 0x5B, 0xAF, 0x00, 0x00, 0x05, 0x24, 0x03, 0x00, 0xA4, 0x24,
+0x00, 0xA0, 0x80, 0x40, 0x00, 0xA0, 0x84, 0x40, 0x01, 0x80, 0x04, 0x3C,
+0x40, 0x00, 0x84, 0x24, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x80, 0x1B, 0x3C, 0x40, 0x00, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C,
+0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, 0x02, 0x80, 0x1A, 0x3C,
+0x00, 0x00, 0x5A, 0x27, 0xFC, 0x03, 0x5D, 0x27, 0x02, 0x80, 0x1C, 0x3C,
+0x00, 0x18, 0x9C, 0x27, 0x00, 0xF0, 0x08, 0x3C, 0x00, 0x0C, 0x08, 0x35,
+0x00, 0x60, 0x88, 0x40, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x84, 0x24,
+0xFF, 0x7F, 0x05, 0x3C, 0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x20, 0x85, 0x00,
+0x00, 0x20, 0x84, 0x4C, 0xFF, 0xFF, 0x05, 0x34, 0x21, 0x28, 0xA4, 0x00,
+0x00, 0x28, 0x85, 0x4C, 0x02, 0x80, 0x08, 0x3C, 0x00, 0x00, 0x08, 0x25,
+0x00, 0x00, 0x00, 0xAD, 0x03, 0x80, 0x09, 0x3C, 0x04, 0xDD, 0x29, 0x25,
+0x04, 0x00, 0x08, 0x25, 0xFE, 0xFF, 0x09, 0x15, 0x00, 0x00, 0x00, 0xAD,
+0x00, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x84, 0x24, 0xFF, 0x7F, 0x05, 0x3C,
+0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x20, 0x85, 0x00, 0x00, 0x00, 0x84, 0x4C,
+0xFF, 0xFF, 0x06, 0x34, 0x21, 0x30, 0xC4, 0x00, 0x24, 0x30, 0xC5, 0x00,
+0x00, 0x08, 0x86, 0x4C, 0x00, 0xA0, 0x04, 0x40, 0x10, 0x00, 0x84, 0x34,
+0x00, 0xA0, 0x84, 0x40, 0x01, 0x80, 0x1B, 0x3C, 0xEC, 0x00, 0x7B, 0x27,
+0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x04, 0x3C, 0x44, 0x00, 0x84, 0x34,
+0x00, 0x00, 0x85, 0x84, 0x20, 0x00, 0x06, 0x24, 0x25, 0x28, 0xA6, 0x00,
+0x00, 0x00, 0x85, 0xA4, 0x01, 0x80, 0x1B, 0x3C, 0x1C, 0x01, 0x7B, 0x27,
+0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF,
+0x25, 0xB0, 0x04, 0x3C, 0x44, 0x00, 0x84, 0x34, 0x00, 0x00, 0x85, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA5, 0x30, 0xFC, 0xFF, 0xA0, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0x07, 0x3C, 0xFF, 0xFF, 0xE7, 0x34,
+0x02, 0x80, 0x05, 0x3C, 0xC0, 0x5C, 0xA5, 0x24, 0xFF, 0xFF, 0xA5, 0x30,
+0x40, 0xB0, 0x04, 0x3C, 0x25, 0x28, 0xA4, 0x00, 0x24, 0x28, 0xA7, 0x00,
+0x21, 0x30, 0x00, 0x00, 0x43, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x04, 0x3C,
+0x40, 0x00, 0x84, 0x34, 0x00, 0x00, 0x45, 0xAC, 0x04, 0x00, 0x46, 0xAC,
+0x08, 0x00, 0x44, 0xAC, 0x5F, 0x67, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64, 0x30, 0x02, 0x1C, 0x03, 0x00,
+0x08, 0x00, 0x80, 0x10, 0x0F, 0x00, 0x63, 0x30, 0x01, 0x00, 0x02, 0x24,
+0x0C, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, 0x0E, 0x00, 0x62, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x60, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x00, 0xE0, 0x03,
+0xC3, 0x5C, 0x40, 0xA0, 0x01, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0xC3, 0x5C, 0x43, 0xA0, 0x02, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x08, 0x00, 0xE0, 0x03, 0xC3, 0x5C, 0x43, 0xA0, 0x04, 0x00, 0x03, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x08, 0x00, 0xE0, 0x03, 0xC3, 0x5C, 0x43, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x24,
+0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x41, 0x04, 0xFF, 0xFF, 0x42, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x42, 0x24, 0x00, 0x60, 0x02, 0x40,
+0x01, 0x00, 0x41, 0x34, 0x01, 0x00, 0x21, 0x38, 0x00, 0x60, 0x81, 0x40,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00, 0x00, 0x60, 0x83, 0x40,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x60, 0x01, 0x40,
+0x01, 0x00, 0x21, 0x34, 0x00, 0x60, 0x81, 0x40, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x40, 0x01, 0x00, 0x21, 0x34,
+0x01, 0x00, 0x21, 0x38, 0x00, 0x60, 0x81, 0x40, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x84, 0x02, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x04, 0x00, 0x85, 0x8C, 0x00, 0xA0, 0x03, 0x3C, 0x01, 0x00, 0x02, 0x24,
+0x25, 0x28, 0xA3, 0x00, 0x00, 0x00, 0xA4, 0x8C, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0xB4, 0x02, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x04, 0x00, 0x82, 0x8C, 0x02, 0x00, 0x83, 0x94, 0x00, 0xA0, 0x07, 0x3C,
+0x25, 0x28, 0x47, 0x00, 0x00, 0x00, 0xA2, 0x8C, 0x10, 0x00, 0x02, 0x24,
+0x13, 0x00, 0x62, 0x10, 0x11, 0x00, 0x66, 0x28, 0x06, 0x00, 0xC0, 0x10,
+0x20, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0x24, 0x17, 0x00, 0x62, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24,
+0xFD, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x83, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xAC, 0x04, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x47, 0x00, 0x00, 0x00, 0x42, 0x8C,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xA4, 0x04, 0x00, 0x83, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x67, 0x00, 0x00, 0x00, 0x62, 0x94,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xA0, 0x04, 0x00, 0x83, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x67, 0x00, 0x00, 0x00, 0x62, 0x90,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x47, 0x24, 0x24, 0x38, 0xE3, 0x90, 0xFF, 0xFF, 0xA5, 0x30,
+0x09, 0x00, 0xA3, 0x10, 0x21, 0x20, 0xC0, 0x00, 0x94, 0x38, 0xE2, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xC2, 0xAC, 0x9E, 0x38, 0xE3, 0x94,
+0x0E, 0x00, 0x02, 0x24, 0x14, 0x00, 0xC2, 0xAC, 0x17, 0x0A, 0x00, 0x08,
+0x0C, 0x00, 0xC3, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C,
+0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x60, 0x1B, 0x31, 0x26, 0x7C, 0x38, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C,
+0x01, 0x80, 0x03, 0x3C, 0x25, 0x80, 0x02, 0x02, 0x25, 0xB0, 0x02, 0x3C,
+0xB8, 0x03, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x60, 0x00, 0x04, 0x26,
+0x80, 0x00, 0x05, 0x26, 0x00, 0x00, 0x43, 0xAC, 0xC2, 0x1B, 0x00, 0x0C,
+0x03, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x02, 0x21, 0x28, 0x00, 0x00,
+0xEC, 0x54, 0x00, 0x0C, 0x08, 0x00, 0x06, 0x24, 0x7C, 0x38, 0x22, 0x8E,
+0x0C, 0x00, 0x03, 0x24, 0x0C, 0x00, 0x43, 0xAE, 0x08, 0x00, 0x42, 0xAE,
+0x12, 0x00, 0x02, 0x24, 0x14, 0x00, 0x42, 0xAE, 0x21, 0x20, 0x40, 0x02,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xB1, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x0D, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x14,
+0x21, 0x88, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0xF0, 0x5D, 0x43, 0xA0, 0x0C, 0x00, 0x02, 0x92, 0x02, 0x80, 0x05, 0x3C,
+0x06, 0x5E, 0xA2, 0xA0, 0x00, 0x00, 0x04, 0x92, 0x05, 0x00, 0x02, 0x24,
+0xFF, 0x00, 0x83, 0x30, 0x41, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x02, 0x24, 0x31, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x84, 0x30,
+0x09, 0x00, 0x82, 0x2C, 0x25, 0x00, 0x40, 0x10, 0x02, 0x80, 0x10, 0x3C,
+0xEC, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30,
+0x21, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x99, 0x61, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xEC, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x37, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x54, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x0E, 0x5E, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
+0x0E, 0x5E, 0x62, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28,
+0x06, 0x00, 0x40, 0x10, 0x04, 0x00, 0x04, 0x24, 0x4B, 0x2E, 0x00, 0x0C,
+0x01, 0x00, 0x05, 0x24, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x11, 0x24, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x21, 0x10, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x0B, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x14,
+0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x02, 0x24,
+0x09, 0x5E, 0x62, 0xA0, 0x09, 0x5E, 0x63, 0x90, 0x02, 0x80, 0x02, 0x3C,
+0x0A, 0x5E, 0x43, 0xA0, 0x00, 0x00, 0x04, 0x92, 0x33, 0x41, 0x00, 0x08,
+0xFF, 0x00, 0x84, 0x30, 0x06, 0x5E, 0xA0, 0xA0, 0x0C, 0x00, 0x03, 0x92,
+0x02, 0x80, 0x02, 0x3C, 0x04, 0x5E, 0x43, 0xA0, 0x00, 0x00, 0x04, 0x92,
+0x30, 0x41, 0x00, 0x08, 0xFF, 0x00, 0x83, 0x30, 0x42, 0xB0, 0x06, 0x3C,
+0x00, 0x00, 0xC3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x03, 0x00, 0xC7, 0x34,
+0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, 0x00, 0x00, 0xC3, 0xA0,
+0x0C, 0x00, 0x04, 0x24, 0x00, 0x00, 0xE2, 0xA0, 0x4B, 0x2E, 0x00, 0x0C,
+0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x15, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C,
+0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x42, 0x24, 0x2A, 0x1C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xCA, 0xFF, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x3A, 0x44, 0x94,
+0x2A, 0x1C, 0x40, 0xA0, 0x00, 0xC0, 0x84, 0x24, 0xA3, 0x31, 0x00, 0x0C,
+0xFF, 0xFF, 0x84, 0x30, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x0E, 0x5E, 0x40, 0xA0, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0xA8, 0x2D, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x89, 0x41, 0x00, 0x08,
+0x00, 0x08, 0x04, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C,
+0x10, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x30, 0x26, 0xB0, 0x1B, 0x07, 0x96,
+0x18, 0x00, 0xBF, 0xAF, 0xFF, 0xFF, 0xE3, 0x30, 0x00, 0x01, 0x62, 0x30,
+0x0E, 0x00, 0x40, 0x10, 0x01, 0x00, 0x66, 0x30, 0x02, 0x80, 0x04, 0x3C,
+0xB4, 0x55, 0x84, 0x24, 0x03, 0x00, 0x05, 0x24, 0x1E, 0x00, 0xC0, 0x14,
+0x04, 0x00, 0x62, 0x30, 0x02, 0x00, 0x40, 0x10, 0xFB, 0xF6, 0xE3, 0x30,
+0xB0, 0x1B, 0x03, 0xA6, 0x87, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, 0x00, 0x00, 0x40, 0xA0,
+0x21, 0x20, 0x00, 0x00, 0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0x25, 0xB0, 0x06, 0x3C, 0x48, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC5, 0x8C,
+0x60, 0x1B, 0x24, 0x26, 0x7B, 0xFF, 0x03, 0x3C, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0x63, 0x34,
+0x21, 0x10, 0x00, 0x00, 0x24, 0x28, 0xA3, 0x00, 0x20, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0xC5, 0xAC, 0xBC, 0x40, 0x80, 0xAC, 0xE8, 0x39, 0x80, 0xAC,
+0x04, 0x3A, 0x80, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xFC, 0x40, 0x80, 0xAC,
+0x1C, 0x4F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x1B, 0x02, 0x96,
+0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x42, 0x30, 0x87, 0x54, 0x00, 0x0C,
+0xB0, 0x1B, 0x02, 0xA6, 0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x40, 0xA0, 0xBB, 0x41, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x01, 0x00, 0x83, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x38, 0x80, 0x00,
+0x8C, 0x5B, 0x43, 0xAC, 0x01, 0x00, 0x84, 0x90, 0x00, 0x00, 0xE2, 0x90,
+0x02, 0x80, 0x06, 0x3C, 0xFF, 0x00, 0x85, 0x30, 0x80, 0x10, 0x02, 0x00,
+0x25, 0x28, 0xA2, 0x00, 0x88, 0xDE, 0xC6, 0x24, 0xFF, 0x00, 0x84, 0x30,
+0x00, 0x80, 0xA5, 0x34, 0x6F, 0x20, 0x00, 0x0C, 0x03, 0x00, 0xE7, 0x24,
+0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x37, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x30, 0x00, 0x01, 0x42, 0x30,
+0x04, 0x00, 0x40, 0x10, 0x21, 0x80, 0x80, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x06, 0x00, 0x60, 0x14, 0x60, 0xE7, 0x84, 0x24, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x07, 0x92, 0x07, 0x00, 0x02, 0x26, 0x21, 0x20, 0x00, 0x02,
+0x80, 0x38, 0x07, 0x00, 0x00, 0x80, 0xE7, 0x34, 0x05, 0x00, 0x05, 0x24,
+0x21, 0x30, 0x00, 0x00, 0x02, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27,
+0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF,
+0x60, 0x1B, 0x45, 0x24, 0xFC, 0x40, 0xA3, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x60, 0x14, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xF8, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0x45, 0x00, 0xF0, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x84, 0x8C,
+0xC3, 0x1A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8E,
+0x03, 0x00, 0x04, 0x24, 0xD9, 0x12, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x84, 0x90,
+0x75, 0x0D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C,
+0x20, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0x02, 0x26, 0x24, 0x00, 0xBF, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0xB0, 0x1B, 0x45, 0x94, 0x21, 0x90, 0x80, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x80, 0xE7, 0x84, 0x24,
+0x00, 0x00, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x43, 0x24,
+0x20, 0x00, 0x42, 0x24, 0xC2, 0x18, 0x03, 0x00, 0xC2, 0x28, 0x02, 0x00,
+0x07, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0xC0, 0x20, 0x03, 0x00,
+0xC0, 0x20, 0x05, 0x00, 0x53, 0x21, 0x00, 0x0C, 0x60, 0x1B, 0x11, 0x26,
+0x02, 0x80, 0x05, 0x3C, 0x21, 0x38, 0x40, 0x00, 0x21, 0x80, 0x40, 0x00,
+0x0A, 0x00, 0x04, 0x24, 0x22, 0x00, 0x40, 0x10, 0x70, 0xE7, 0xA5, 0x24,
+0x02, 0x00, 0x46, 0x92, 0x10, 0x38, 0x25, 0x8E, 0x72, 0x01, 0x00, 0x0C,
+0x08, 0x00, 0xC6, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24,
+0x08, 0x00, 0x02, 0x96, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C,
+0x25, 0x28, 0x45, 0x00, 0x74, 0x03, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0xB0, 0x55, 0x84, 0x24, 0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02,
+0x31, 0x46, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x37, 0x26, 0x8E,
+0x58, 0x38, 0x25, 0x8E, 0x01, 0x00, 0x04, 0x24, 0x00, 0x01, 0x07, 0x24,
+0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF,
+0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x18, 0xE7, 0x84, 0x24,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0x90, 0x02, 0x80, 0x03, 0x3C,
+0x60, 0x1B, 0x63, 0x24, 0x07, 0x00, 0x40, 0x10, 0x21, 0x20, 0x60, 0x00,
+0xD0, 0x07, 0x02, 0x24, 0x3C, 0x3A, 0x62, 0xAC, 0x01, 0x00, 0x03, 0x24,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x41, 0x83, 0xA0,
+0x21, 0x10, 0x00, 0x00, 0x3C, 0x3A, 0x60, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x48, 0x41, 0x60, 0xA0, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x25, 0xB0, 0x10, 0x3C, 0x21, 0x28, 0x80, 0x00, 0x06, 0x00, 0x06, 0x24,
+0x14, 0x00, 0xBF, 0xAF, 0xF4, 0x54, 0x00, 0x0C, 0x50, 0x00, 0x04, 0x36,
+0x02, 0x80, 0x04, 0x3C, 0x50, 0x00, 0x05, 0x36, 0x48, 0x37, 0x84, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0x94, 0xE7, 0x84, 0x24, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x05, 0x3C, 0x01, 0x80, 0x03, 0x3C,
+0xE8, 0xFF, 0xBD, 0x27, 0x21, 0x30, 0x80, 0x00, 0x18, 0x03, 0xA2, 0x34,
+0xC0, 0x0B, 0x63, 0x24, 0x01, 0x00, 0x04, 0x24, 0x14, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x66, 0x00, 0xC4, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x09, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x02, 0x24,
+0x36, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24, 0x8B, 0x00, 0xC2, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x50, 0x24, 0x70, 0x08, 0x02, 0x24, 0x34, 0x1C, 0x02, 0xAE,
+0xE0, 0x08, 0x03, 0x24, 0x40, 0x08, 0x02, 0x24, 0x38, 0x1C, 0x03, 0xAE,
+0x44, 0x1C, 0x02, 0xAE, 0x78, 0x08, 0x03, 0x24, 0x0C, 0x08, 0x02, 0x24,
+0x48, 0x1C, 0x03, 0xAE, 0x4C, 0x1C, 0x02, 0xAE, 0x10, 0x08, 0x03, 0x24,
+0x20, 0x08, 0x02, 0x24, 0x50, 0x1C, 0x03, 0xAE, 0x54, 0x1C, 0x02, 0xAE,
+0x24, 0x08, 0x03, 0x24, 0x58, 0x08, 0x02, 0x24, 0x58, 0x1C, 0x03, 0xAE,
+0x5C, 0x1C, 0x02, 0xAE, 0x50, 0x0C, 0x03, 0x24, 0x54, 0x0C, 0x02, 0x24,
+0x60, 0x1C, 0x03, 0xAE, 0x64, 0x1C, 0x02, 0xAE, 0x14, 0x0C, 0x03, 0x24,
+0x10, 0x0C, 0x02, 0x24, 0x20, 0x08, 0xA4, 0x34, 0x68, 0x1C, 0x03, 0xAE,
+0x60, 0x08, 0x05, 0x24, 0x6C, 0x1C, 0x02, 0xAE, 0x80, 0x0C, 0x03, 0x24,
+0x84, 0x0C, 0x02, 0x24, 0x40, 0x1C, 0x05, 0xAE, 0x70, 0x1C, 0x03, 0xAE,
+0x74, 0x1C, 0x02, 0xAE, 0x31, 0x1C, 0x00, 0xA2, 0xFA, 0x5B, 0x00, 0x0C,
+0x3C, 0x1C, 0x05, 0xAE, 0x00, 0x01, 0x42, 0x30, 0x31, 0x00, 0x40, 0x14,
+0xB8, 0x08, 0x02, 0x24, 0xA0, 0x08, 0x02, 0x24, 0x78, 0x1C, 0x02, 0xAE,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0xA8, 0x08, 0x03, 0x24, 0x78, 0x1C, 0x43, 0xAC, 0x74, 0x08, 0x03, 0x24,
+0xE4, 0x08, 0x04, 0x24, 0x34, 0x1C, 0x43, 0xAC, 0x48, 0x08, 0x03, 0x24,
+0x38, 0x1C, 0x44, 0xAC, 0x44, 0x1C, 0x43, 0xAC, 0x7C, 0x08, 0x04, 0x24,
+0x0C, 0x08, 0x03, 0x24, 0x48, 0x1C, 0x44, 0xAC, 0x4C, 0x1C, 0x43, 0xAC,
+0x18, 0x08, 0x04, 0x24, 0x30, 0x08, 0x03, 0x24, 0x50, 0x1C, 0x44, 0xAC,
+0x54, 0x1C, 0x43, 0xAC, 0x34, 0x08, 0x04, 0x24, 0x5C, 0x08, 0x03, 0x24,
+0x58, 0x1C, 0x44, 0xAC, 0x5C, 0x1C, 0x43, 0xAC, 0x60, 0x0C, 0x04, 0x24,
+0x64, 0x0C, 0x03, 0x24, 0x60, 0x1C, 0x44, 0xAC, 0x64, 0x1C, 0x43, 0xAC,
+0x24, 0x0C, 0x04, 0x24, 0x20, 0x0C, 0x03, 0x24, 0x68, 0x08, 0x05, 0x24,
+0x68, 0x1C, 0x44, 0xAC, 0x6C, 0x1C, 0x43, 0xAC, 0x90, 0x0C, 0x04, 0x24,
+0x94, 0x0C, 0x03, 0x24, 0x31, 0x1C, 0x46, 0xA0, 0x40, 0x1C, 0x45, 0xAC,
+0x70, 0x1C, 0x44, 0xAC, 0x74, 0x1C, 0x43, 0xAC, 0x3C, 0x1C, 0x45, 0xAC,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x31, 0x43, 0x00, 0x08, 0x78, 0x1C, 0x02, 0xAE,
+0x60, 0x1B, 0x50, 0x24, 0x70, 0x08, 0x02, 0x24, 0x34, 0x1C, 0x02, 0xAE,
+0xE0, 0x08, 0x03, 0x24, 0x44, 0x08, 0x02, 0x24, 0x38, 0x1C, 0x03, 0xAE,
+0x44, 0x1C, 0x02, 0xAE, 0x78, 0x08, 0x03, 0x24, 0x0C, 0x08, 0x02, 0x24,
+0x48, 0x1C, 0x03, 0xAE, 0x4C, 0x1C, 0x02, 0xAE, 0x14, 0x08, 0x03, 0x24,
+0x28, 0x08, 0x02, 0x24, 0x50, 0x1C, 0x03, 0xAE, 0x54, 0x1C, 0x02, 0xAE,
+0x2C, 0x08, 0x03, 0x24, 0x58, 0x08, 0x02, 0x24, 0x58, 0x1C, 0x03, 0xAE,
+0x5C, 0x1C, 0x02, 0xAE, 0x58, 0x0C, 0x03, 0x24, 0x5C, 0x0C, 0x02, 0x24,
+0x60, 0x1C, 0x03, 0xAE, 0x64, 0x1C, 0x02, 0xAE, 0x1C, 0x0C, 0x03, 0x24,
+0x18, 0x0C, 0x02, 0x24, 0x28, 0x08, 0xA4, 0x34, 0x68, 0x1C, 0x03, 0xAE,
+0x64, 0x08, 0x05, 0x24, 0x6C, 0x1C, 0x02, 0xAE, 0x88, 0x0C, 0x03, 0x24,
+0x8C, 0x0C, 0x02, 0x24, 0x31, 0x1C, 0x06, 0xA2, 0x40, 0x1C, 0x05, 0xAE,
+0x70, 0x1C, 0x03, 0xAE, 0x74, 0x1C, 0x02, 0xAE, 0xFA, 0x5B, 0x00, 0x0C,
+0x3C, 0x1C, 0x05, 0xAE, 0x00, 0x01, 0x42, 0x30, 0x2B, 0x00, 0x40, 0x14,
+0xBC, 0x08, 0x02, 0x24, 0xA4, 0x08, 0x02, 0x24, 0x31, 0x43, 0x00, 0x08,
+0x78, 0x1C, 0x02, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0xAC, 0x08, 0x03, 0x24, 0x78, 0x1C, 0x43, 0xAC, 0x74, 0x08, 0x03, 0x24,
+0xE4, 0x08, 0x04, 0x24, 0x34, 0x1C, 0x43, 0xAC, 0x4C, 0x08, 0x03, 0x24,
+0x38, 0x1C, 0x44, 0xAC, 0x44, 0x1C, 0x43, 0xAC, 0x7C, 0x08, 0x04, 0x24,
+0x0C, 0x08, 0x03, 0x24, 0x48, 0x1C, 0x44, 0xAC, 0x4C, 0x1C, 0x43, 0xAC,
+0x1C, 0x08, 0x04, 0x24, 0x38, 0x08, 0x03, 0x24, 0x50, 0x1C, 0x44, 0xAC,
+0x54, 0x1C, 0x43, 0xAC, 0x3C, 0x08, 0x04, 0x24, 0x5C, 0x08, 0x03, 0x24,
+0x58, 0x1C, 0x44, 0xAC, 0x5C, 0x1C, 0x43, 0xAC, 0x68, 0x0C, 0x04, 0x24,
+0x6C, 0x0C, 0x03, 0x24, 0x60, 0x1C, 0x44, 0xAC, 0x64, 0x1C, 0x43, 0xAC,
+0x2C, 0x0C, 0x04, 0x24, 0x28, 0x0C, 0x03, 0x24, 0x6C, 0x08, 0x05, 0x24,
+0x68, 0x1C, 0x44, 0xAC, 0x6C, 0x1C, 0x43, 0xAC, 0x98, 0x0C, 0x04, 0x24,
+0x9C, 0x0C, 0x03, 0x24, 0x31, 0x1C, 0x46, 0xA0, 0x40, 0x1C, 0x45, 0xAC,
+0x70, 0x1C, 0x44, 0xAC, 0x74, 0x1C, 0x43, 0xAC, 0x5B, 0x43, 0x00, 0x08,
+0x3C, 0x1C, 0x45, 0xAC, 0x31, 0x43, 0x00, 0x08, 0x78, 0x1C, 0x02, 0xAE,
+0xBA, 0x43, 0x00, 0x08, 0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0x62, 0x2C,
+0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x64, 0x00,
+0x01, 0x00, 0x42, 0x30, 0xFA, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x63, 0x24,
+0xFF, 0xFF, 0x63, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0xD8, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0xFF, 0xFF, 0x02, 0x24,
+0x21, 0x88, 0xA0, 0x00, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xC0, 0x00,
+0x21, 0x28, 0xC0, 0x00, 0x0B, 0x00, 0x22, 0x12, 0x21, 0x98, 0x80, 0x00,
+0x26, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02,
+0xB5, 0x43, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00, 0x27, 0x28, 0x11, 0x00,
+0x24, 0x28, 0xB0, 0x00, 0x04, 0x10, 0x52, 0x00, 0x25, 0x28, 0xA2, 0x00,
+0x21, 0x20, 0x60, 0x02, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x03, 0x5C, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x30, 0x80, 0x00, 0xA4, 0x37, 0x44, 0x8C, 0xC1, 0x43, 0x00, 0x08,
+0xFF, 0xFF, 0x05, 0x24, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x26, 0x5C, 0x00, 0x0C,
+0x21, 0x88, 0xA0, 0x00, 0x21, 0x80, 0x40, 0x00, 0xB5, 0x43, 0x00, 0x0C,
+0x21, 0x20, 0x20, 0x02, 0x24, 0x80, 0x11, 0x02, 0x06, 0x10, 0x50, 0x00,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C, 0x60, 0x1B, 0x52, 0x26,
+0x14, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, 0x24, 0x08, 0x04, 0x24,
+0x24, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF,
+0x26, 0x5C, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x58, 0x1C, 0x44, 0x8E,
+0x21, 0xA0, 0x40, 0x00, 0x26, 0x5C, 0x00, 0x0C, 0xC0, 0x8D, 0x11, 0x00,
+0xFF, 0x7F, 0x05, 0x3C, 0x7F, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0xA5, 0x34,
+0xFF, 0xFF, 0x63, 0x34, 0x24, 0x28, 0x85, 0x02, 0x24, 0x08, 0x04, 0x24,
+0x03, 0x5C, 0x00, 0x0C, 0x24, 0x80, 0x43, 0x00, 0x2C, 0x1F, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x00, 0x80, 0x13, 0x3C, 0x58, 0x1C, 0x44, 0x8E,
+0x25, 0x80, 0x11, 0x02, 0x25, 0x80, 0x13, 0x02, 0x03, 0x5C, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x02, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x25, 0x28, 0x93, 0x02, 0x03, 0x5C, 0x00, 0x0C, 0x24, 0x08, 0x04, 0x24,
+0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x78, 0x1C, 0x44, 0x8E,
+0x0F, 0x00, 0x05, 0x3C, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0xA5, 0x34, 0xE3, 0x43, 0x00, 0x08,
+0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF,
+0x02, 0x80, 0x11, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x18, 0x00, 0xBF, 0xAF,
+0x60, 0x1B, 0x27, 0x26, 0x33, 0x1C, 0xE5, 0x90, 0x01, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x94, 0x10, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x02, 0x00, 0x06, 0x24, 0x00, 0x00, 0x43, 0xAC, 0x34, 0x00, 0xA6, 0x10,
+0x21, 0x80, 0x80, 0x00, 0x03, 0x00, 0x03, 0x24, 0x3A, 0x00, 0xA3, 0x10,
+0x2E, 0x00, 0x02, 0x2E, 0x10, 0x00, 0x02, 0x2E, 0x07, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04, 0x32, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xF3, 0x43, 0x00, 0x08,
+0x20, 0x00, 0xBD, 0x27, 0xFA, 0xFF, 0xA6, 0x14, 0xFF, 0x00, 0x04, 0x32,
+0x31, 0x1C, 0xE4, 0x90, 0x01, 0x00, 0x02, 0x24, 0x33, 0x00, 0x82, 0x10,
+0x02, 0x00, 0x82, 0x28, 0x38, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x38, 0x00, 0x85, 0x10, 0x60, 0x1B, 0x22, 0x26, 0x2E, 0x00, 0x83, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFC, 0x06, 0x3C, 0xFF, 0xFF, 0xC6, 0x34,
+0x24, 0x30, 0x46, 0x00, 0x00, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0x60, 0x1B, 0x22, 0x26, 0x31, 0x1C, 0x44, 0x90,
+0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x83, 0x10, 0x02, 0x00, 0x82, 0x28,
+0x2C, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0x2C, 0x00, 0x82, 0x10,
+0x03, 0x00, 0x02, 0x24, 0xDB, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x3B, 0x44, 0x00, 0x08,
+0xFF, 0x00, 0x04, 0x32, 0x25, 0x00, 0x82, 0x2C, 0xCC, 0xFF, 0x40, 0x14,
+0x03, 0x00, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xC7, 0xFF, 0x40, 0x14, 0x10, 0x00, 0x02, 0x2E,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C,
+0xC1, 0x43, 0x00, 0x0C, 0x0F, 0x00, 0x06, 0x24, 0x4D, 0x44, 0x00, 0x08,
+0x00, 0x08, 0x04, 0x24, 0xCC, 0xFF, 0x80, 0x14, 0x60, 0x1B, 0x22, 0x26,
+0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x0F, 0x00, 0x06, 0x24, 0x4D, 0x44, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24,
+0xB2, 0xFF, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x22, 0x26,
+0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x3B, 0x44, 0x00, 0x08, 0xFF, 0x00, 0x04, 0x32,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C,
+0x60, 0x1B, 0x28, 0x26, 0x33, 0x1C, 0x06, 0x91, 0x01, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x40, 0x12, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x02, 0x00, 0x07, 0x24, 0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x1C, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x21, 0x90, 0xA0, 0x00,
+0x39, 0x00, 0xC7, 0x10, 0xFF, 0x00, 0x90, 0x30, 0x03, 0x00, 0x03, 0x24,
+0x3F, 0x00, 0xC3, 0x10, 0x2E, 0x00, 0x02, 0x2E, 0x10, 0x00, 0x02, 0x2E,
+0x0C, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x04, 0x3C,
+0xFF, 0xFF, 0x84, 0x34, 0x24, 0x20, 0x44, 0x02, 0x00, 0x15, 0x10, 0x00,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x25, 0x20, 0x44, 0x00, 0xDE, 0x43, 0x00, 0x08,
+0x20, 0x00, 0xBD, 0x27, 0xF5, 0xFF, 0xC7, 0x14, 0x0F, 0x00, 0x04, 0x3C,
+0x31, 0x1C, 0x04, 0x91, 0x01, 0x00, 0x02, 0x24, 0x33, 0x00, 0x82, 0x10,
+0x02, 0x00, 0x82, 0x28, 0x38, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x38, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x22, 0x26, 0x2E, 0x00, 0x83, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFC, 0x06, 0x3C, 0xFF, 0xFF, 0xC6, 0x34,
+0x24, 0x30, 0x46, 0x00, 0x00, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0x60, 0x1B, 0x22, 0x26, 0x31, 0x1C, 0x44, 0x90,
+0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x83, 0x10, 0x02, 0x00, 0x82, 0x28,
+0x2C, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0x2C, 0x00, 0x82, 0x10,
+0x03, 0x00, 0x02, 0x24, 0xD6, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0xA8, 0x44, 0x00, 0x08,
+0x0F, 0x00, 0x04, 0x3C, 0x25, 0x00, 0x02, 0x2E, 0xC7, 0xFF, 0x40, 0x14,
+0x03, 0x00, 0x03, 0x24, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xC1, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C,
+0xC1, 0x43, 0x00, 0x0C, 0x0F, 0x00, 0x06, 0x24, 0xBF, 0x44, 0x00, 0x08,
+0x00, 0x08, 0x04, 0x24, 0xCC, 0xFF, 0x80, 0x14, 0x60, 0x1B, 0x22, 0x26,
+0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x0F, 0x00, 0x06, 0x24, 0xBF, 0x44, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24,
+0xAD, 0xFF, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x22, 0x26,
+0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0xA8, 0x44, 0x00, 0x08, 0x0F, 0x00, 0x04, 0x3C,
+0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x14, 0x00, 0xBF, 0xAF, 0xF3, 0x43, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00,
+0x40, 0x01, 0x44, 0x34, 0x21, 0x18, 0x40, 0x00, 0x1F, 0x00, 0x02, 0x2E,
+0x00, 0x23, 0x04, 0x00, 0x10, 0x00, 0x40, 0x10, 0x10, 0x00, 0x05, 0x2E,
+0x00, 0x01, 0x64, 0x34, 0x06, 0x00, 0xA0, 0x10, 0x00, 0x23, 0x04, 0x00,
+0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xDE, 0x43, 0x00, 0x0C,
+0xF1, 0xFF, 0x10, 0x26, 0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0xDE, 0x43, 0x00, 0x0C, 0xE2, 0xFF, 0x10, 0x26, 0x21, 0x10, 0x00, 0x02,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C,
+0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x90, 0x8C, 0x21, 0x88, 0xA0, 0x00,
+0xB5, 0x43, 0x00, 0x0C, 0x21, 0x20, 0xA0, 0x00, 0x24, 0x80, 0x11, 0x02,
+0x06, 0x10, 0x50, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xD8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x00, 0xB2, 0xAF,
+0x21, 0x90, 0x82, 0x00, 0xFF, 0xFF, 0x02, 0x24, 0x1C, 0x00, 0xB3, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x21, 0x88, 0xA0, 0x00, 0x21, 0x20, 0xA0, 0x00, 0x21, 0x18, 0x40, 0x02,
+0x10, 0x00, 0xA2, 0x10, 0x21, 0x98, 0xC0, 0x00, 0x00, 0x00, 0x50, 0x8E,
+0xB5, 0x43, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x27, 0x18, 0x11, 0x00,
+0x24, 0x18, 0x70, 0x00, 0x04, 0x10, 0x53, 0x00, 0x25, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x43, 0xAE, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x28, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x66, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x21, 0x38, 0x82, 0x00, 0xFF, 0xFF, 0x02, 0x24, 0x27, 0x40, 0x05, 0x00,
+0x08, 0x00, 0xA2, 0x10, 0x24, 0x18, 0xC5, 0x00, 0x00, 0x00, 0xE2, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x02, 0x01, 0x25, 0x10, 0x43, 0x00,
+0x00, 0x00, 0xE2, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xE6, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0xFF, 0xFF, 0x02, 0x24,
+0x21, 0x80, 0xA0, 0x00, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x88, 0xC0, 0x00, 0x21, 0x28, 0xC0, 0x00,
+0x08, 0x00, 0x02, 0x12, 0x21, 0x90, 0x80, 0x00, 0x26, 0x5C, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x27, 0x28, 0x10, 0x00, 0x24, 0x28, 0xA2, 0x00,
+0x24, 0x10, 0x30, 0x02, 0x25, 0x28, 0xA2, 0x00, 0x21, 0x20, 0x40, 0x02,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x03, 0x5C, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27,
+0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0xD0, 0xFF, 0xBD, 0x27,
+0x0C, 0x16, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x20, 0x00, 0xB2, 0xAF,
+0x00, 0x00, 0x62, 0xAC, 0x21, 0x90, 0x80, 0x00, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x21, 0x98, 0xC0, 0x00,
+0x21, 0x88, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x18, 0x00, 0xB0, 0xAF, 0x0F, 0x00, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x21, 0x20, 0x40, 0x02, 0x0A, 0x00, 0x22, 0x12, 0x21, 0x28, 0x60, 0x02,
+0x25, 0x44, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02,
+0xB5, 0x43, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00, 0x27, 0x28, 0x11, 0x00,
+0x24, 0x28, 0xB0, 0x00, 0x04, 0x10, 0x53, 0x00, 0x25, 0x28, 0xA2, 0x00,
+0x90, 0x44, 0x00, 0x0C, 0xFF, 0x00, 0x44, 0x32, 0x90, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x01, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x16, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0xE0, 0xFF, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xAC, 0x18, 0x00, 0xBF, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x25, 0x44, 0x00, 0x0C,
+0x21, 0x88, 0xA0, 0x00, 0x21, 0x80, 0x40, 0x00, 0xB5, 0x43, 0x00, 0x0C,
+0x21, 0x20, 0x20, 0x02, 0x24, 0x80, 0x11, 0x02, 0x06, 0x10, 0x50, 0x00,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27,
+0x24, 0x00, 0xB5, 0xAF, 0xFF, 0x00, 0x84, 0x30, 0x21, 0xA8, 0xC0, 0x00,
+0x28, 0x00, 0xB6, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x2C, 0x00, 0xBF, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x21, 0xB0, 0xA0, 0x00, 0xF0, 0x42, 0x00, 0x0C,
+0x21, 0x98, 0x00, 0x00, 0x21, 0x00, 0xA0, 0x16, 0x80, 0x10, 0x13, 0x00,
+0xFF, 0x45, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x02, 0x24,
+0x23, 0x00, 0x02, 0x12, 0x05, 0x00, 0x04, 0x24, 0xFC, 0x00, 0x02, 0x24,
+0x37, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x02, 0x24,
+0x30, 0x00, 0x02, 0x12, 0x32, 0x00, 0x04, 0x24, 0xFA, 0x00, 0x02, 0x24,
+0x2D, 0x00, 0x02, 0x12, 0x05, 0x00, 0x04, 0x24, 0xF9, 0x00, 0x02, 0x24,
+0x29, 0x00, 0x02, 0x12, 0x0F, 0x00, 0x05, 0x3C, 0x04, 0x00, 0xD1, 0x8C,
+0xFF, 0xFF, 0xA5, 0x34, 0x21, 0x20, 0x00, 0x02, 0x83, 0x45, 0x00, 0x0C,
+0x21, 0x30, 0x20, 0x02, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x19, 0x00, 0x02, 0x24, 0x28, 0x00, 0x02, 0x12, 0x21, 0x90, 0x00, 0x00,
+0x02, 0x00, 0x62, 0x26, 0xFF, 0x00, 0x53, 0x30, 0x2B, 0x18, 0x75, 0x02,
+0x0F, 0x00, 0x60, 0x10, 0x80, 0x10, 0x13, 0x00, 0x21, 0x30, 0x56, 0x00,
+0x00, 0x00, 0xD0, 0x8C, 0xFF, 0x00, 0x02, 0x24, 0x0A, 0x00, 0x02, 0x12,
+0xFE, 0x00, 0x02, 0x24, 0xDC, 0xFF, 0x02, 0x16, 0x32, 0x00, 0x04, 0x24,
+0x2C, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x26,
+0xFF, 0x00, 0x53, 0x30, 0x2B, 0x18, 0x75, 0x02, 0xF3, 0xFF, 0x60, 0x14,
+0x80, 0x10, 0x13, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0x01, 0x00, 0x04, 0x24, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xED, 0x45, 0x00, 0x08, 0x02, 0x00, 0x62, 0x26, 0x2C, 0x1F, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0xFB, 0x45, 0x00, 0x08, 0x02, 0x00, 0x62, 0x26,
+0x0F, 0x00, 0x14, 0x3C, 0x21, 0x20, 0x00, 0x02, 0xAC, 0x45, 0x00, 0x0C,
+0xFF, 0xFF, 0x85, 0x36, 0x21, 0x20, 0x00, 0x02, 0xFF, 0xFF, 0x85, 0x36,
+0xD2, 0xFF, 0x51, 0x10, 0x21, 0x30, 0x20, 0x02, 0x83, 0x45, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x01, 0x00, 0x42, 0x26, 0xFF, 0x00, 0x52, 0x30, 0x0A, 0x00, 0x43, 0x2E,
+0xF2, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x00, 0x02, 0xF0, 0x42, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xB0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x4C, 0x00, 0xBF, 0xAF,
+0x48, 0x00, 0xBE, 0xAF, 0x40, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xB5, 0xAF,
+0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF,
+0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x55, 0x24,
+0x44, 0x00, 0xB7, 0xAF, 0x58, 0x38, 0xA3, 0x96, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x05, 0x3C, 0x25, 0x98, 0x62, 0x00, 0x90, 0xDE, 0xA5, 0x24,
+0x24, 0x00, 0x64, 0x26, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x20, 0x00, 0x60, 0xA6, 0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24,
+0x2A, 0x00, 0x64, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x30, 0x00, 0x64, 0x26, 0x20, 0x00, 0x63, 0x96,
+0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x42, 0x24, 0x03, 0xFF, 0x63, 0x30,
+0x80, 0x00, 0x63, 0x34, 0x74, 0x00, 0x54, 0x24, 0x20, 0x00, 0x63, 0xA6,
+0x21, 0x20, 0x80, 0x02, 0x20, 0x00, 0x02, 0x24, 0x40, 0x00, 0x72, 0x26,
+0xFB, 0x51, 0x00, 0x0C, 0x1C, 0x00, 0xA2, 0xAF, 0x21, 0x28, 0x40, 0x00,
+0x21, 0x20, 0x40, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24,
+0x1C, 0x00, 0xA2, 0x8F, 0x21, 0x20, 0x80, 0x02, 0x42, 0x00, 0x72, 0x26,
+0x02, 0x00, 0x42, 0x24, 0x16, 0x52, 0x00, 0x0C, 0x1C, 0x00, 0xA2, 0xAF,
+0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0x40, 0x02, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xB0, 0x55, 0x63, 0x24,
+0x1C, 0x00, 0xA2, 0x8F, 0x0C, 0x00, 0x66, 0x8C, 0x60, 0x00, 0x71, 0x24,
+0x1C, 0x00, 0xB0, 0x27, 0x10, 0x00, 0x67, 0x24, 0x21, 0x28, 0x00, 0x00,
+0x02, 0x00, 0x42, 0x24, 0x44, 0x00, 0x64, 0x26, 0x1C, 0x00, 0xA2, 0xAF,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x20, 0x20, 0x02,
+0x1B, 0x53, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x21, 0xB0, 0x40, 0x00,
+0x08, 0x00, 0x06, 0x24, 0x09, 0x00, 0x42, 0x2C, 0x21, 0x20, 0x40, 0x02,
+0x21, 0x38, 0x20, 0x02, 0x0B, 0x30, 0xC2, 0x02, 0x01, 0x00, 0x05, 0x24,
+0x20, 0x00, 0xA2, 0xAF, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x03, 0x3C, 0xB0, 0x55, 0x63, 0x24, 0x48, 0x00, 0x67, 0x24,
+0x21, 0x20, 0x40, 0x00, 0x03, 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x20, 0x40, 0x00,
+0x06, 0x00, 0x05, 0x24, 0x02, 0x00, 0x06, 0x24, 0x18, 0x00, 0xA7, 0x27,
+0x18, 0x00, 0xA0, 0xA7, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF,
+0x18, 0x00, 0xA5, 0x97, 0x02, 0x80, 0x04, 0x3C, 0x58, 0xE8, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0xC0, 0x3A, 0xA2, 0x8E,
+0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02, 0x3B, 0x00, 0x40, 0x10,
+0x21, 0xF0, 0x00, 0x02, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x80, 0x02,
+0xAA, 0x46, 0x00, 0x08, 0x26, 0x56, 0x57, 0x24, 0x21, 0x10, 0x30, 0x02,
+0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E, 0x21, 0x18, 0x71, 0x00,
+0x02, 0x00, 0x71, 0x24, 0x2B, 0x20, 0x24, 0x02, 0x2F, 0x00, 0x80, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x30, 0x02, 0x00, 0x00, 0x47, 0x90,
+0x02, 0x80, 0x14, 0x3C, 0x2D, 0x00, 0x03, 0x24, 0x21, 0x28, 0x37, 0x02,
+0x64, 0x5C, 0x84, 0x26, 0xF1, 0xFF, 0xE3, 0x14, 0x20, 0x00, 0x06, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, 0xA3, 0x96,
+0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x47, 0x90, 0xBD, 0xFF, 0x63, 0x30,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x0C, 0x00, 0x63, 0x34,
+0x01, 0x00, 0xE7, 0x30, 0x44, 0xDF, 0xA5, 0x24, 0x67, 0x5C, 0x44, 0x24,
+0x10, 0x00, 0x06, 0x24, 0x06, 0x00, 0xE0, 0x14, 0x04, 0x41, 0xA3, 0xA6,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x54, 0xDF, 0xA5, 0x24,
+0x67, 0x5C, 0x64, 0x24, 0x10, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x30, 0x02, 0x01, 0x00, 0x46, 0x90,
+0x21, 0x20, 0x40, 0x02, 0x64, 0x5C, 0x87, 0x26, 0x2D, 0x00, 0x05, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xBE, 0xAF, 0x21, 0x90, 0x40, 0x00,
+0x21, 0x10, 0x30, 0x02, 0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E,
+0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x71, 0x24, 0x2B, 0x20, 0x24, 0x02,
+0xD4, 0xFF, 0x80, 0x14, 0x21, 0x10, 0x30, 0x02, 0x20, 0x00, 0xA2, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x24,
+0x01, 0x01, 0x42, 0x2C, 0x1A, 0x00, 0x40, 0x14, 0x21, 0x20, 0x60, 0x02,
+0x4C, 0x00, 0xBF, 0x8F, 0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F,
+0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F,
+0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F,
+0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27,
+0xB0, 0x55, 0x63, 0x24, 0x21, 0x20, 0x40, 0x02, 0xF8, 0xFF, 0xC6, 0x26,
+0x68, 0x00, 0x67, 0x24, 0x32, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xBE, 0xAF, 0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x00, 0x42, 0x24, 0x01, 0x01, 0x42, 0x2C, 0xE8, 0xFF, 0x40, 0x10,
+0x21, 0x20, 0x60, 0x02, 0x21, 0x28, 0x00, 0x00, 0xEC, 0x54, 0x00, 0x0C,
+0x08, 0x00, 0x06, 0x24, 0x08, 0x00, 0x64, 0x8E, 0x04, 0x00, 0x65, 0x8E,
+0xFF, 0xDF, 0x02, 0x3C, 0x10, 0x00, 0x66, 0x8E, 0x14, 0x00, 0x67, 0x8E,
+0xFF, 0xFF, 0x42, 0x34, 0x1C, 0x00, 0xA8, 0x8F, 0x24, 0x20, 0x82, 0x00,
+0x00, 0x40, 0x03, 0x3C, 0xFF, 0xE0, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00,
+0x25, 0x20, 0x83, 0x00, 0x00, 0x80, 0x02, 0x3C, 0xFF, 0x81, 0x03, 0x24,
+0x25, 0x30, 0xC2, 0x00, 0x24, 0x38, 0xE3, 0x00, 0x00, 0x10, 0xA5, 0x34,
+0x02, 0x80, 0x03, 0x3C, 0x80, 0x00, 0x84, 0x34, 0x20, 0x00, 0x02, 0x24,
+0x08, 0x00, 0x64, 0xAE, 0x00, 0x00, 0x68, 0xA6, 0x02, 0x00, 0x62, 0xA2,
+0x14, 0x00, 0x67, 0xAE, 0x04, 0x00, 0x65, 0xAE, 0x10, 0x00, 0x66, 0xAE,
+0x60, 0x1B, 0x62, 0x24, 0xEC, 0x37, 0x46, 0x8C, 0x58, 0x38, 0x45, 0x8C,
+0x01, 0x00, 0x04, 0x24, 0x00, 0x01, 0x07, 0x24, 0x01, 0x00, 0x02, 0x24,
+0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x5B, 0x01, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x4C, 0x00, 0xBF, 0x8F, 0x48, 0x00, 0xBE, 0x8F,
+0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F,
+0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F,
+0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x50, 0x00, 0xBD, 0x27, 0xA0, 0xFF, 0xBD, 0x27, 0x5C, 0x00, 0xBF, 0xAF,
+0x58, 0x00, 0xBE, 0xAF, 0x54, 0x00, 0xB7, 0xAF, 0x50, 0x00, 0xB6, 0xAF,
+0x4C, 0x00, 0xB5, 0xAF, 0x48, 0x00, 0xB4, 0xAF, 0x44, 0x00, 0xB3, 0xAF,
+0x40, 0x00, 0xB2, 0xAF, 0x3C, 0x00, 0xB1, 0xAF, 0x38, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x0B, 0x3C, 0x64, 0xE8, 0x82, 0x24,
+0x78, 0xE8, 0x63, 0x25, 0x78, 0xE8, 0x6B, 0x91, 0x01, 0x00, 0x45, 0x90,
+0x0D, 0x00, 0x48, 0x90, 0x0C, 0x00, 0x58, 0x90, 0x64, 0xE8, 0x97, 0x90,
+0x02, 0x00, 0x54, 0x90, 0x0E, 0x00, 0x50, 0x90, 0x01, 0x00, 0x69, 0x90,
+0x30, 0x00, 0xAB, 0xAF, 0x03, 0x00, 0x4B, 0x90, 0x04, 0x00, 0x76, 0x90,
+0x05, 0x00, 0x6A, 0x90, 0x02, 0x00, 0x6F, 0x90, 0x06, 0x00, 0x64, 0x90,
+0x07, 0x00, 0x75, 0x90, 0x03, 0x00, 0x71, 0x90, 0x00, 0x2A, 0x05, 0x00,
+0x30, 0x00, 0xA3, 0x8F, 0x00, 0x42, 0x08, 0x00, 0x25, 0x40, 0x18, 0x01,
+0x25, 0x28, 0xB7, 0x00, 0x00, 0xA4, 0x14, 0x00, 0x00, 0x84, 0x10, 0x00,
+0x25, 0xA0, 0x85, 0x02, 0x25, 0x80, 0x08, 0x02, 0x00, 0x4A, 0x09, 0x00,
+0x00, 0x5E, 0x0B, 0x00, 0x02, 0x80, 0x08, 0x3C, 0x05, 0x00, 0x46, 0x90,
+0x09, 0x00, 0x47, 0x90, 0x25, 0x48, 0x23, 0x01, 0x00, 0x52, 0x0A, 0x00,
+0x60, 0x1B, 0x03, 0x25, 0x25, 0x58, 0x74, 0x01, 0x04, 0x00, 0x5E, 0x90,
+0x06, 0x00, 0x53, 0x90, 0x08, 0x00, 0x59, 0x90, 0x0A, 0x00, 0x52, 0x90,
+0x07, 0x00, 0x4C, 0x90, 0x0B, 0x00, 0x4D, 0x90, 0x0F, 0x00, 0x4E, 0x90,
+0x11, 0x00, 0x58, 0x90, 0x25, 0x50, 0x56, 0x01, 0x10, 0x00, 0x56, 0x90,
+0x10, 0x00, 0xAB, 0xAF, 0x06, 0x41, 0x62, 0x90, 0x00, 0x32, 0x06, 0x00,
+0x00, 0x3A, 0x07, 0x00, 0x00, 0x7C, 0x0F, 0x00, 0x00, 0x24, 0x04, 0x00,
+0x25, 0x30, 0xDE, 0x00, 0x25, 0x38, 0xF9, 0x00, 0x25, 0x20, 0x8A, 0x00,
+0x1C, 0x00, 0x43, 0x30, 0x00, 0x9C, 0x13, 0x00, 0x00, 0x94, 0x12, 0x00,
+0x25, 0x78, 0xE9, 0x01, 0x00, 0x8E, 0x11, 0x00, 0x00, 0xAE, 0x15, 0x00,
+0x25, 0x98, 0x66, 0x02, 0x25, 0x90, 0x47, 0x02, 0x03, 0x00, 0x46, 0x30,
+0x25, 0xA8, 0xA4, 0x02, 0x25, 0x88, 0x2F, 0x02, 0x10, 0x00, 0xA7, 0x27,
+0x83, 0x18, 0x03, 0x00, 0x02, 0x00, 0xC4, 0x24, 0x28, 0x00, 0xB1, 0xAF,
+0x2C, 0x00, 0xB5, 0xAF, 0x21, 0x18, 0xE3, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x04, 0x10, 0x82, 0x00, 0x18, 0x00, 0x65, 0x90, 0xFF, 0x00, 0x46, 0x30,
+0x00, 0x66, 0x0C, 0x00, 0x00, 0x6E, 0x0D, 0x00, 0x00, 0x76, 0x0E, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0x25, 0x60, 0x93, 0x01, 0x25, 0x68, 0xB2, 0x01,
+0x25, 0x70, 0xD0, 0x01, 0x10, 0x00, 0xC4, 0x2C, 0x37, 0x02, 0x42, 0x34,
+0x0F, 0x00, 0x03, 0x24, 0x14, 0x00, 0xAC, 0xAF, 0x18, 0x00, 0xAD, 0xAF,
+0x1C, 0x00, 0xAE, 0xAF, 0x20, 0x00, 0xB6, 0xA3, 0x21, 0x00, 0xB8, 0xA3,
+0x0A, 0x30, 0x64, 0x00, 0x00, 0x00, 0x45, 0xA0, 0x21, 0x28, 0x00, 0x00,
+0x21, 0x20, 0xE5, 0x00, 0x00, 0x00, 0x82, 0x90, 0x01, 0x00, 0xA5, 0x24,
+0x2B, 0x10, 0xC2, 0x00, 0x02, 0x00, 0x40, 0x10, 0x11, 0x00, 0xA3, 0x2C,
+0x00, 0x00, 0x86, 0xA0, 0xF9, 0xFF, 0x60, 0x14, 0x21, 0x20, 0xE5, 0x00,
+0x21, 0x30, 0xE0, 0x00, 0x21, 0x28, 0x00, 0x00, 0x25, 0xB0, 0x07, 0x3C,
+0x01, 0x00, 0xC2, 0x90, 0x00, 0x00, 0xC3, 0x90, 0x21, 0x20, 0xA7, 0x00,
+0x00, 0x11, 0x02, 0x00, 0x25, 0x10, 0x43, 0x00, 0x01, 0x00, 0xA5, 0x24,
+0xFF, 0x00, 0x42, 0x30, 0x08, 0x00, 0xA3, 0x2C, 0xA8, 0x01, 0x82, 0xA0,
+0xF6, 0xFF, 0x60, 0x14, 0x02, 0x00, 0xC6, 0x24, 0x21, 0x00, 0xA2, 0x93,
+0x20, 0x00, 0xA4, 0x93, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x11, 0x02, 0x00,
+0xD9, 0x5C, 0x66, 0x90, 0x25, 0x10, 0x44, 0x00, 0xFF, 0x00, 0x42, 0x30,
+0xA7, 0x01, 0xE3, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x01, 0x00, 0x02, 0x24,
+0x0F, 0x00, 0xC2, 0x10, 0x60, 0x1B, 0x07, 0x25, 0x60, 0x1B, 0x02, 0x25,
+0x00, 0x41, 0x40, 0xAC, 0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F,
+0x54, 0x00, 0xB7, 0x8F, 0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F,
+0x48, 0x00, 0xB4, 0x8F, 0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F,
+0x3C, 0x00, 0xB1, 0x8F, 0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x60, 0x00, 0xBD, 0x27, 0x04, 0x41, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x42, 0x30, 0xEF, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x02, 0x25,
+0x25, 0x41, 0xE3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x30,
+0xEA, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x02, 0x25, 0x03, 0x00, 0x63, 0x30,
+0x10, 0x00, 0x66, 0x10, 0x03, 0x00, 0x02, 0x24, 0x07, 0x00, 0x62, 0x10,
+0x60, 0x1B, 0x02, 0x25, 0x00, 0x41, 0x40, 0xAC, 0x21, 0x20, 0x00, 0x00,
+0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0xBE, 0x47, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x34, 0x02, 0x00, 0x05, 0x24,
+0x00, 0x41, 0xE6, 0xAC, 0x95, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xBE, 0x47, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x34,
+0x01, 0x00, 0x05, 0x24, 0xE2, 0x47, 0x00, 0x08, 0x00, 0x41, 0xE6, 0xAC,
+0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x14, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0xB4, 0x55, 0xC2, 0x24, 0x01, 0x00, 0x44, 0x90,
+0xB4, 0x55, 0xC3, 0x90, 0x02, 0x00, 0x45, 0x90, 0x03, 0x00, 0x46, 0x90,
+0x05, 0x00, 0x47, 0x90, 0x04, 0x00, 0x48, 0x90, 0x00, 0x22, 0x04, 0x00,
+0x25, 0x18, 0x64, 0x00, 0x00, 0x2C, 0x05, 0x00, 0x25, 0xB0, 0x10, 0x3C,
+0x25, 0x18, 0x65, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3A, 0x07, 0x00,
+0x25, 0x18, 0x66, 0x00, 0x58, 0x00, 0x02, 0x36, 0x5C, 0x00, 0x05, 0x36,
+0x25, 0x40, 0x07, 0x01, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xAC,
+0xB0, 0x55, 0x84, 0x24, 0x00, 0x00, 0xA8, 0xAC, 0xFD, 0x51, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x03, 0x36, 0x00, 0x00, 0x62, 0xA4,
+0x48, 0x00, 0x10, 0x36, 0x00, 0x00, 0x02, 0x8E, 0x84, 0x00, 0x03, 0x3C,
+0x14, 0x00, 0xBF, 0x8F, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x02, 0xAE,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0x24, 0x00, 0x04, 0x24, 0x21, 0x30, 0x40, 0x00,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24,
+0x21, 0x20, 0xC0, 0x00, 0x13, 0x00, 0xC0, 0x10, 0x80, 0xE8, 0xA5, 0x24,
+0x04, 0x00, 0x02, 0x24, 0x09, 0x00, 0x03, 0x24, 0x0C, 0x00, 0xC2, 0xAC,
+0x14, 0x00, 0xC3, 0xAC, 0x08, 0x00, 0xC5, 0x94, 0x3C, 0x3E, 0x03, 0x8E,
+0x02, 0x80, 0x02, 0x3C, 0x25, 0x28, 0xA2, 0x00, 0x17, 0x0A, 0x00, 0x0C,
+0x20, 0x00, 0xA3, 0xAC, 0x40, 0x3E, 0x06, 0x8E, 0x3C, 0x3E, 0x05, 0x8E,
+0x02, 0x80, 0x04, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x94, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0x02, 0x80, 0x04, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x43, 0x8C, 0x21, 0x90, 0x80, 0x00,
+0x3C, 0x00, 0x64, 0x24, 0x53, 0x21, 0x00, 0x0C, 0x1C, 0x00, 0x73, 0x24,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00,
+0xB0, 0x55, 0xA5, 0x24, 0x74, 0x03, 0x06, 0x24, 0x19, 0x00, 0x40, 0x10,
+0xC8, 0xE8, 0x84, 0x24, 0x08, 0x00, 0x50, 0x94, 0x0A, 0x00, 0x02, 0x24,
+0x14, 0x00, 0x22, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x80, 0x02, 0x02,
+0x0C, 0x00, 0x33, 0xAE, 0x3C, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C,
+0x20, 0x00, 0x10, 0x26, 0x18, 0x00, 0x12, 0xAE, 0x21, 0x20, 0x20, 0x02,
+0x17, 0x0A, 0x00, 0x0C, 0x14, 0x00, 0x12, 0xAE, 0x02, 0x80, 0x04, 0x3C,
+0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x60, 0x02, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0xD8, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08,
+0x28, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x28, 0x60, 0x02,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xB8, 0xE8, 0xC6, 0x24,
+0x13, 0x58, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB2, 0xAF, 0xFF, 0xFF, 0x92, 0x30, 0x2A, 0x00, 0x04, 0x24,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0xFF, 0x00, 0xB1, 0x30, 0x02, 0x80, 0x05, 0x3C,
+0x21, 0x80, 0x40, 0x00, 0xB4, 0x55, 0xA5, 0x24, 0x13, 0x00, 0x40, 0x10,
+0x06, 0x00, 0x06, 0x24, 0x08, 0x00, 0x44, 0x94, 0x0A, 0x00, 0x02, 0x24,
+0x0C, 0x00, 0x02, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00,
+0x20, 0x00, 0x84, 0x24, 0x19, 0x00, 0x03, 0x24, 0x14, 0x00, 0x03, 0xAE,
+0x06, 0x00, 0x92, 0xA4, 0xF4, 0x54, 0x00, 0x0C, 0x08, 0x00, 0x91, 0xA0,
+0x21, 0x20, 0x00, 0x02, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08,
+0x20, 0x00, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x02, 0x00, 0x82, 0x90,
+0x02, 0x80, 0x12, 0x3C, 0x60, 0x1B, 0x51, 0x26, 0xB0, 0x1B, 0x25, 0x96,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00,
+0x00, 0x01, 0xA3, 0x30, 0x04, 0x00, 0x60, 0x10, 0x18, 0x00, 0x04, 0x26,
+0x00, 0x10, 0xA2, 0x30, 0x0B, 0x00, 0x40, 0x10, 0x04, 0x00, 0xA2, 0x30,
+0x21, 0x18, 0x00, 0x00, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xF5, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x39, 0x53, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0xED, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xB4, 0x55, 0x53, 0x24, 0x22, 0x00, 0x14, 0x26,
+0x21, 0x20, 0x80, 0x02, 0x21, 0x28, 0x60, 0x02, 0x1D, 0x55, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0xE4, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00,
+0x28, 0x00, 0x04, 0x26, 0x21, 0x28, 0x60, 0x02, 0x1D, 0x55, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0xDE, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x38, 0xE9, 0x84, 0x24,
+0xB0, 0x1B, 0x24, 0x96, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x83, 0x30,
+0x01, 0x00, 0x62, 0x30, 0x08, 0x00, 0x40, 0x10, 0x00, 0x20, 0x62, 0x30,
+0x1B, 0x00, 0x40, 0x10, 0xFF, 0xDE, 0x82, 0x30, 0xB0, 0x1B, 0x22, 0xA6,
+0xFE, 0xFF, 0x04, 0x24, 0xCC, 0x39, 0x20, 0xAE, 0x35, 0x48, 0x00, 0x0C,
+0xB0, 0x39, 0x20, 0xAE, 0x25, 0xB0, 0x10, 0x3C, 0x60, 0x1B, 0x51, 0x26,
+0x4C, 0x00, 0x02, 0x36, 0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0x10, 0x36,
+0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x95, 0x0E, 0x00, 0x0C,
+0x37, 0x3E, 0x20, 0xA2, 0x00, 0x00, 0x03, 0x8E, 0x7B, 0xFF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x00, 0x03, 0xAE,
+0xBC, 0x40, 0x20, 0xAE, 0xE8, 0x39, 0x20, 0xAE, 0x04, 0x3A, 0x20, 0xAE,
+0x87, 0x54, 0x00, 0x0C, 0xFC, 0x40, 0x20, 0xAE, 0xA5, 0x48, 0x00, 0x08,
+0x21, 0x18, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x80, 0x02,
+0xB5, 0xFF, 0x40, 0x14, 0xFF, 0xFF, 0x03, 0x24, 0xB0, 0x1B, 0x22, 0x96,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x42, 0x30, 0xD8, 0x48, 0x00, 0x08,
+0xB0, 0x1B, 0x22, 0xA6, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x10, 0x26, 0x02, 0x00, 0x02, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0x00, 0x80, 0x06, 0x3C, 0x44, 0x3A, 0x02, 0xA2,
+0x90, 0x55, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0x3C, 0x3A, 0x00, 0xAE,
+0x14, 0x00, 0xBF, 0xAF, 0xCF, 0x20, 0x00, 0x0C, 0x70, 0x3C, 0xC6, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x44, 0x90, 0x02, 0x80, 0x03, 0x3C,
+0x49, 0xF5, 0x65, 0x90, 0x10, 0x27, 0x02, 0x24, 0x0B, 0x10, 0x04, 0x00,
+0x01, 0x00, 0x84, 0x2C, 0x3C, 0x3A, 0x02, 0xAE, 0x49, 0x41, 0x05, 0xA2,
+0x48, 0x41, 0x04, 0xA2, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xB8, 0xFF, 0xBD, 0x27,
+0x00, 0x01, 0x04, 0x24, 0x3C, 0x00, 0xB3, 0xAF, 0x38, 0x00, 0xB2, 0xAF,
+0x34, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB0, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x04, 0x3C,
+0x21, 0x88, 0x40, 0x00, 0x90, 0xDE, 0x65, 0x26, 0x06, 0x00, 0x06, 0x24,
+0x0C, 0x00, 0x52, 0x24, 0x4D, 0x00, 0x40, 0x10, 0x58, 0xE9, 0x84, 0x24,
+0x08, 0x00, 0x50, 0x94, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x80, 0x02, 0x02,
+0x24, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x00, 0xA6,
+0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x30, 0x00, 0x04, 0x26,
+0x90, 0xDE, 0x65, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x04, 0x3C,
+0x03, 0xFF, 0x63, 0x30, 0x40, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6,
+0x60, 0x1B, 0x84, 0x24, 0x0C, 0x00, 0x22, 0xAE, 0xE4, 0x1D, 0x82, 0x94,
+0x20, 0x00, 0x06, 0x26, 0x02, 0x80, 0x07, 0x3C, 0xFF, 0x0F, 0x43, 0x30,
+0x00, 0x19, 0x03, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24,
+0xE4, 0x1D, 0x82, 0xA4, 0x16, 0x00, 0xC3, 0xA0, 0x17, 0x00, 0xC5, 0xA0,
+0x0C, 0x3E, 0x86, 0x8C, 0x70, 0x59, 0xE7, 0x24, 0x38, 0x00, 0x04, 0x26,
+0x21, 0x28, 0x00, 0x00, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF,
+0x18, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xA5, 0x27, 0x05, 0x53, 0x00, 0x0C,
+0x21, 0x80, 0x40, 0x00, 0x28, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0x00, 0x02,
+0x18, 0x00, 0xA7, 0x27, 0x09, 0x00, 0x62, 0x28, 0x01, 0x00, 0x05, 0x24,
+0x13, 0x00, 0x40, 0x10, 0x08, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x02,
+0x21, 0x30, 0x60, 0x00, 0x01, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA7, 0x27,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF, 0x21, 0x20, 0x20, 0x02,
+0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C,
+0x21, 0x38, 0x00, 0x00, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB3, 0x8F,
+0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xB2, 0xAF, 0x28, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x40, 0x00,
+0x32, 0x00, 0x05, 0x24, 0xF8, 0xFF, 0xC6, 0x24, 0x58, 0x49, 0x00, 0x08,
+0x20, 0x00, 0xA7, 0x27, 0x02, 0x80, 0x05, 0x3C, 0x13, 0x58, 0x00, 0x0C,
+0x48, 0xE9, 0xA5, 0x24, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB3, 0x8F,
+0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0xA8, 0xFF, 0xBD, 0x27, 0x48, 0x00, 0xB6, 0xAF,
+0x3C, 0x00, 0xB3, 0xAF, 0x38, 0x00, 0xB2, 0xAF, 0x30, 0x00, 0xB0, 0xAF,
+0x54, 0x00, 0xBF, 0xAF, 0x50, 0x00, 0xBE, 0xAF, 0x4C, 0x00, 0xB7, 0xAF,
+0x44, 0x00, 0xB5, 0xAF, 0x40, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB1, 0xAF,
+0x02, 0x00, 0x82, 0x90, 0x00, 0x00, 0x83, 0x8C, 0x21, 0xB0, 0x00, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00,
+0x18, 0x00, 0x12, 0x26, 0x21, 0x20, 0x40, 0x02, 0x39, 0x53, 0x00, 0x0C,
+0xFF, 0x3F, 0x73, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24,
+0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x0B, 0x00, 0x40, 0x14, 0x02, 0x80, 0x15, 0x3C, 0x60, 0x1B, 0xB1, 0x26,
+0xB0, 0x1B, 0x23, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30,
+0x05, 0x00, 0x40, 0x10, 0x00, 0x10, 0x62, 0x30, 0x03, 0x00, 0x40, 0x14,
+0x00, 0x01, 0x62, 0x30, 0x0E, 0x00, 0x40, 0x10, 0x20, 0x00, 0xB4, 0x27,
+0x54, 0x00, 0xBF, 0x8F, 0x50, 0x00, 0xBE, 0x8F, 0x4C, 0x00, 0xB7, 0x8F,
+0x48, 0x00, 0xB6, 0x8F, 0x44, 0x00, 0xB5, 0x8F, 0x40, 0x00, 0xB4, 0x8F,
+0x3C, 0x00, 0xB3, 0x8F, 0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F,
+0x30, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x58, 0x00, 0xBD, 0x27, 0x32, 0x00, 0x05, 0x26, 0x21, 0x20, 0x80, 0x02,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA5, 0x97,
+0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xA0, 0x14, 0x02, 0x80, 0x04, 0x3C,
+0x21, 0x20, 0x80, 0x02, 0x34, 0x00, 0x05, 0x26, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA2, 0x97, 0x21, 0x20, 0x80, 0x02,
+0x30, 0x00, 0x05, 0x26, 0xFF, 0x3F, 0x42, 0x30, 0x02, 0x00, 0x06, 0x24,
+0x4C, 0x3A, 0x22, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x28, 0x00, 0xA2, 0xAF,
+0x20, 0x00, 0xA3, 0x97, 0x21, 0x40, 0x20, 0x02, 0x00, 0x04, 0x63, 0x30,
+0x02, 0x00, 0x60, 0x14, 0x09, 0x00, 0x02, 0x24, 0x14, 0x00, 0x02, 0x24,
+0x1E, 0x00, 0x5E, 0x26, 0xE2, 0xFF, 0x77, 0x26, 0x21, 0x20, 0xC0, 0x03,
+0x01, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27, 0x21, 0x38, 0xE0, 0x02,
+0xAB, 0x1A, 0x00, 0x0C, 0xB8, 0x40, 0x02, 0xA1, 0x9E, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA6, 0x8F, 0x02, 0x00, 0x45, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x21, 0x20, 0xC0, 0x03,
+0x32, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27, 0x24, 0x00, 0xB4, 0x8F,
+0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, 0x08, 0x00, 0x40, 0x10,
+0x10, 0x00, 0xA4, 0x27, 0x24, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x94, 0x00,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24, 0x24, 0x00, 0xA3, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x21, 0xA0, 0x83, 0x02, 0x02, 0x80, 0x02, 0x3C,
+0xD2, 0x5C, 0x44, 0x90, 0x02, 0x00, 0x03, 0x24, 0xDA, 0x00, 0x83, 0x10,
+0x21, 0x20, 0xC0, 0x03, 0x60, 0x1B, 0xA4, 0x26, 0xBC, 0x40, 0x82, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xB1, 0x26,
+0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0x00, 0x60, 0x14, 0x23, 0x10, 0xD2, 0x03, 0x2B, 0x10, 0x53, 0x00,
+0x1A, 0x00, 0x40, 0x10, 0x21, 0x80, 0xC0, 0x03, 0x02, 0x80, 0x11, 0x3C,
+0x21, 0x20, 0x00, 0x02, 0xDD, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27,
+0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, 0x21, 0x80, 0x40, 0x00,
+0x02, 0x00, 0x44, 0x24, 0x68, 0xDE, 0x25, 0x26, 0x03, 0x01, 0x40, 0x10,
+0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x01, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA2, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x02, 0x02, 0x02, 0x00, 0x70, 0x24,
+0x23, 0x20, 0x12, 0x02, 0xF8, 0x00, 0x40, 0x10, 0x2B, 0x20, 0x93, 0x00,
+0xEB, 0xFF, 0x80, 0x14, 0x21, 0x20, 0x00, 0x02, 0x60, 0x1B, 0xB1, 0x26,
+0xFC, 0x40, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x40, 0x14,
+0x24, 0x00, 0xA6, 0x27, 0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB2, 0x26,
+0xB0, 0x1B, 0x45, 0x96, 0x25, 0xB0, 0x17, 0x3C, 0x02, 0x00, 0x03, 0x24,
+0x4C, 0x00, 0xE4, 0x36, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x01, 0xA5, 0x34,
+0xE8, 0x39, 0x42, 0xAE, 0x60, 0xEA, 0x02, 0x34, 0x04, 0x3A, 0x42, 0xAE,
+0xEA, 0x47, 0x00, 0x0C, 0xB0, 0x1B, 0x45, 0xA6, 0x10, 0x00, 0xA4, 0x27,
+0x61, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02, 0x0F, 0x00, 0x50, 0x30,
+0x10, 0x00, 0xA4, 0x27, 0x7A, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02,
+0x40, 0x02, 0x13, 0x36, 0x21, 0x20, 0x60, 0x02, 0x63, 0x5E, 0x00, 0x74,
+0x21, 0x28, 0x40, 0x00, 0x21, 0x28, 0x80, 0x02, 0xA6, 0x53, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x21, 0x88, 0x40, 0x00, 0xFC, 0x40, 0x42, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x10, 0x50, 0x00, 0x13, 0x36,
+0x07, 0x41, 0x42, 0x92, 0x08, 0x41, 0x43, 0x92, 0xB6, 0x40, 0x44, 0x92,
+0x00, 0x13, 0x02, 0x00, 0x00, 0x1D, 0x03, 0x00, 0x25, 0x10, 0x43, 0x00,
+0x04, 0x00, 0x03, 0x24, 0x9C, 0x00, 0x83, 0x10, 0x25, 0x88, 0x22, 0x02,
+0x00, 0x41, 0x43, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x60, 0x14,
+0x01, 0x00, 0x02, 0x24, 0x04, 0x41, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x00, 0x42, 0x30, 0x9D, 0x00, 0x40, 0x14, 0x00, 0x10, 0x02, 0x3C,
+0x01, 0x00, 0x02, 0x24, 0x94, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x94, 0xE9, 0x84, 0x24, 0x21, 0x28, 0x60, 0x02,
+0x21, 0x38, 0xC0, 0x02, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x30, 0x20, 0x02,
+0x21, 0x20, 0x60, 0x02, 0x63, 0x5E, 0x00, 0x74, 0x21, 0x28, 0x20, 0x02,
+0x60, 0x1B, 0xA2, 0x26, 0xB6, 0x40, 0x43, 0x90, 0xB0, 0x1B, 0x44, 0x94,
+0x60, 0x1B, 0xA5, 0x8E, 0xFC, 0xFF, 0x63, 0x24, 0xFF, 0x00, 0x63, 0x30,
+0xFF, 0xDF, 0x84, 0x30, 0x03, 0x00, 0x63, 0x2C, 0xB0, 0x1B, 0x44, 0xA4,
+0xB0, 0x39, 0x40, 0xAC, 0xCC, 0x39, 0x40, 0xAC, 0x40, 0x41, 0x40, 0xAC,
+0x44, 0x41, 0x40, 0xAC, 0x08, 0x00, 0x60, 0x10, 0x25, 0x00, 0xA5, 0x34,
+0x28, 0x00, 0xA4, 0x8F, 0xFB, 0xFF, 0x02, 0x24, 0x24, 0x10, 0xA2, 0x00,
+0x35, 0x48, 0x00, 0x0C, 0x60, 0x1B, 0xA2, 0xAE, 0xA0, 0x49, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xA4, 0x8F, 0x35, 0x48, 0x00, 0x0C,
+0x60, 0x1B, 0xA5, 0xAE, 0xA0, 0x49, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x13, 0x58, 0x00, 0x0C, 0x78, 0xE9, 0x84, 0x24, 0xFF, 0xFF, 0x02, 0x24,
+0x51, 0x4A, 0x00, 0x08, 0x28, 0x00, 0xA2, 0xAF, 0x21, 0x20, 0xC0, 0x03,
+0x2D, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02,
+0x91, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xAB, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x60, 0x19, 0x21, 0x40, 0x00, 0x00,
+0x02, 0x00, 0x49, 0x24, 0x21, 0x50, 0x20, 0x02, 0x02, 0x00, 0x0C, 0x24,
+0x89, 0x4A, 0x00, 0x08, 0x21, 0x68, 0x20, 0x01, 0x04, 0x41, 0x82, 0x90,
+0x00, 0x00, 0x23, 0x91, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00,
+0x04, 0x41, 0x82, 0xA0, 0x01, 0x00, 0x08, 0x25, 0x2A, 0x10, 0x0B, 0x01,
+0x11, 0x00, 0x40, 0x10, 0x01, 0x00, 0x29, 0x25, 0xF6, 0xFF, 0x0C, 0x15,
+0x21, 0x20, 0x0A, 0x01, 0x06, 0x41, 0x43, 0x91, 0x00, 0x00, 0x25, 0x91,
+0x02, 0x00, 0xA2, 0x91, 0x1C, 0x00, 0x64, 0x30, 0x1C, 0x00, 0xA5, 0x30,
+0x03, 0x00, 0x42, 0x30, 0x03, 0x00, 0x63, 0x30, 0x2A, 0x30, 0x43, 0x00,
+0x2A, 0x38, 0xA4, 0x00, 0x0A, 0x10, 0x66, 0x00, 0x0A, 0x20, 0xA7, 0x00,
+0x25, 0x10, 0x44, 0x00, 0x85, 0x4A, 0x00, 0x08, 0x06, 0x41, 0x42, 0xA1,
+0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x43, 0x90, 0x02, 0x80, 0x02, 0x3C,
+0x44, 0xDF, 0x47, 0x24, 0x10, 0x00, 0x65, 0x30, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x54, 0xDF, 0x66, 0x24, 0x60, 0x1B, 0x44, 0x24,
+0xAC, 0x4A, 0x00, 0x08, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90,
+0x07, 0x41, 0x82, 0x90, 0x01, 0x00, 0x08, 0x25, 0x24, 0x10, 0x43, 0x00,
+0x07, 0x41, 0x82, 0xA0, 0x10, 0x00, 0x02, 0x29, 0x07, 0x00, 0x40, 0x10,
+0x01, 0x00, 0x84, 0x24, 0x21, 0x10, 0x07, 0x01, 0xF6, 0xFF, 0xA0, 0x14,
+0x21, 0x18, 0x06, 0x01, 0x00, 0x00, 0x63, 0x90, 0xA5, 0x4A, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xC0, 0x03, 0x21, 0x38, 0xE0, 0x02,
+0x3D, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x24, 0x00, 0xA6, 0x27,
+0x48, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA6, 0x8F,
+0x02, 0x80, 0x04, 0x3C, 0x84, 0x5C, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x45, 0x24, 0x2E, 0x47, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x13, 0x4A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x05, 0x24,
+0x24, 0x00, 0xA6, 0x27, 0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02,
+0x30, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xA5, 0x26, 0x02, 0x00, 0x42, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x2B, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24,
+0x3E, 0x00, 0x83, 0x10, 0x60, 0x1B, 0xA2, 0x26, 0xFC, 0x23, 0x43, 0x8C,
+0xFF, 0xEF, 0x04, 0x24, 0x00, 0x08, 0x63, 0x34, 0x24, 0x18, 0x64, 0x00,
+0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0x43, 0xAC, 0xF6, 0x01, 0xE2, 0x36,
+0x00, 0x00, 0x40, 0xA4, 0x49, 0x4A, 0x00, 0x08, 0x02, 0x80, 0x04, 0x3C,
+0x04, 0x41, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30,
+0x6A, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x10, 0x02, 0x3C,
+0x25, 0x88, 0x22, 0x02, 0x0F, 0x00, 0x08, 0x24, 0x01, 0x00, 0x03, 0x24,
+0x0C, 0x00, 0x02, 0x25, 0x04, 0x10, 0x43, 0x00, 0x24, 0x10, 0x51, 0x00,
+0x16, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x08, 0x25,
+0xFA, 0xFF, 0x01, 0x05, 0x0C, 0x00, 0x02, 0x25, 0x00, 0x12, 0x16, 0x00,
+0x00, 0x1B, 0x16, 0x00, 0x25, 0x18, 0x62, 0x00, 0x00, 0x21, 0x16, 0x00,
+0x25, 0x18, 0x64, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x76, 0x00,
+0xF6, 0x01, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA4, 0x49, 0x4A, 0x00, 0x08,
+0x02, 0x80, 0x04, 0x3C, 0xFC, 0x23, 0xA2, 0x8C, 0xFF, 0xF7, 0x03, 0x24,
+0xFF, 0xEF, 0x04, 0x24, 0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00,
+0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0xA2, 0xAC, 0xEC, 0x4A, 0x00, 0x08,
+0xFF, 0x00, 0x16, 0x31, 0x60, 0x1B, 0xA2, 0x26, 0x13, 0x4A, 0x00, 0x08,
+0xFC, 0x40, 0x40, 0xAC, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0x0E, 0x4A, 0x00, 0x08, 0xBC, 0x40, 0x40, 0xAC, 0x13, 0x4A, 0x00, 0x08,
+0xFC, 0x40, 0x20, 0xAE, 0x21, 0x20, 0x00, 0x02, 0x65, 0x0F, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x00, 0x0F, 0x4A, 0x00, 0x08, 0x60, 0x1B, 0xB1, 0x26,
+0xFC, 0x23, 0x43, 0x8C, 0xFF, 0xF7, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00,
+0x00, 0x10, 0x63, 0x34, 0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0x43, 0xAC,
+0x02, 0x80, 0x04, 0x3C, 0xB0, 0x55, 0x84, 0x24, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24,
+0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x25, 0xB0, 0x04, 0x3C,
+0x94, 0x00, 0x85, 0x34, 0x9A, 0x00, 0x87, 0x34, 0x26, 0xB0, 0x06, 0x3C,
+0x00, 0x08, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, 0x0A, 0x00, 0x0B, 0x24,
+0x00, 0x00, 0xE3, 0xA4, 0x98, 0x00, 0x88, 0x34, 0x96, 0x00, 0x89, 0x34,
+0x7A, 0x00, 0xCA, 0x34, 0x50, 0x00, 0x02, 0x24, 0x04, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x02, 0xA5, 0x00, 0x00, 0x2B, 0xA5, 0x00, 0x00, 0x43, 0xA1,
+0x10, 0x00, 0xA2, 0x97, 0x89, 0x00, 0x83, 0x34, 0x14, 0x00, 0x07, 0x24,
+0x40, 0x11, 0x02, 0x00, 0xA0, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30,
+0x9C, 0x00, 0x85, 0x34, 0x7C, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC2, 0xA4,
+0x44, 0x00, 0x84, 0x34, 0x00, 0x00, 0x67, 0xA0, 0x00, 0x00, 0xAB, 0xA0,
+0x00, 0x00, 0x82, 0x94, 0xFF, 0xFD, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F,
+0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA4, 0x00, 0x00, 0x83, 0x94,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x00, 0x02, 0x63, 0x34,
+0x20, 0x00, 0xBD, 0x27, 0x3A, 0x41, 0x40, 0xA0, 0x00, 0x00, 0x83, 0xA4,
+0x08, 0x00, 0xE0, 0x03, 0xB8, 0x40, 0x47, 0xA0, 0xD0, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C, 0xB0, 0x55, 0x04, 0x26,
+0x28, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x52, 0x00, 0x0C,
+0x18, 0x00, 0xB2, 0xAF, 0xFF, 0xFF, 0x51, 0x30, 0xB0, 0x55, 0x04, 0x26,
+0xFD, 0x51, 0x00, 0x0C, 0x02, 0x80, 0x15, 0x3C, 0x60, 0x1B, 0xA3, 0x26,
+0x01, 0x00, 0x24, 0x32, 0xB4, 0x40, 0x62, 0xA4, 0x03, 0x00, 0x80, 0x14,
+0x02, 0x00, 0x05, 0x24, 0x40, 0x10, 0x11, 0x00, 0x04, 0x00, 0x45, 0x30,
+0x02, 0x00, 0x02, 0x24, 0x5F, 0x00, 0xA2, 0x10, 0x60, 0x1B, 0xA2, 0x26,
+0x10, 0x00, 0x80, 0x10, 0x02, 0x00, 0x03, 0x24, 0x04, 0x00, 0x02, 0x24,
+0x12, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xB3, 0x26, 0x02, 0x80, 0x04, 0x3C,
+0x21, 0x28, 0x20, 0x02, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB5, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xEC, 0xE9, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x08, 0x30, 0x00, 0xBD, 0x27, 0x40, 0x10, 0x11, 0x00,
+0x04, 0x00, 0x43, 0x30, 0x04, 0x00, 0x02, 0x24, 0xF0, 0xFF, 0x62, 0x14,
+0x60, 0x1B, 0xB3, 0x26, 0xB4, 0x40, 0x66, 0x96, 0xC4, 0x3D, 0x65, 0x92,
+0x02, 0x80, 0x04, 0x3C, 0xB0, 0x1B, 0x63, 0xA6, 0xFC, 0xE9, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x25, 0xB0, 0x10, 0x3C, 0x50, 0x02, 0x03, 0x36,
+0x0F, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0, 0x21, 0x28, 0x00, 0x00,
+0x95, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0xC4, 0x3D, 0x64, 0x92,
+0x01, 0x00, 0x14, 0x24, 0x75, 0x0D, 0x00, 0x0C, 0x4C, 0x00, 0x10, 0x36,
+0x02, 0x80, 0x11, 0x3C, 0x00, 0x00, 0x14, 0xA2, 0xEA, 0x47, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0x53, 0x00, 0x0C, 0x10, 0x56, 0x24, 0x26,
+0x21, 0x28, 0x40, 0x00, 0x10, 0x56, 0x24, 0x26, 0x61, 0x53, 0x00, 0x0C,
+0x21, 0x90, 0x40, 0x00, 0x0F, 0x00, 0x50, 0x30, 0x10, 0x56, 0x24, 0x26,
+0x7A, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x40, 0x02, 0x40, 0x02, 0x10, 0x36,
+0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x21, 0x30, 0x40, 0x00,
+0x21, 0x28, 0x00, 0x02, 0x13, 0x58, 0x00, 0x0C, 0x2C, 0xEA, 0x84, 0x24,
+0x21, 0x20, 0x00, 0x02, 0x63, 0x5E, 0x00, 0x74, 0x21, 0x28, 0x20, 0x02,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x37, 0x3A, 0x84, 0x24,
+0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0xD6, 0x1E, 0x74, 0xA2, 0x31, 0x46, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x1B, 0x62, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0xA9, 0x1B, 0x00, 0x0C,
+0xB0, 0x1B, 0x62, 0xA6, 0xE8, 0x39, 0x62, 0xAE, 0x35, 0x48, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0x60, 0x1B, 0xA2, 0x8E, 0x28, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x21, 0x00, 0x42, 0x34, 0x60, 0x1B, 0xA2, 0xAE,
+0x1C, 0x00, 0xB3, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0x24, 0x40, 0x44, 0x8C, 0x01, 0x20, 0x03, 0x24,
+0xB0, 0x1B, 0x43, 0xA4, 0x02, 0x00, 0x85, 0x10, 0x0C, 0x00, 0x03, 0x24,
+0x0F, 0x00, 0x03, 0x24, 0x25, 0xB0, 0x02, 0x3C, 0x50, 0x02, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xA0, 0x60, 0x1B, 0xB0, 0x26, 0xB0, 0x1B, 0x02, 0x96,
+0xB4, 0x40, 0x06, 0x96, 0xC4, 0x3D, 0x05, 0x92, 0x10, 0x00, 0x42, 0x34,
+0x02, 0x80, 0x04, 0x3C, 0xB0, 0x1B, 0x02, 0xA6, 0x40, 0xEA, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x14, 0x40, 0x00, 0xAE, 0x21, 0x28, 0x00, 0x00,
+0x95, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92,
+0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x1B, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0x39, 0x02, 0xAE, 0x28, 0x00, 0xBF, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27,
+0x20, 0x00, 0xB2, 0xAF, 0x21, 0x90, 0x80, 0x00, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB0, 0x30, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x51, 0x24, 0x10, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x02, 0x24,
+0x90, 0x40, 0x00, 0x0C, 0x4B, 0x41, 0x22, 0xA2, 0x02, 0x80, 0x04, 0x3C,
+0x30, 0x59, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0xE3, 0x54, 0x00, 0x0C,
+0x0F, 0x00, 0x06, 0x24, 0x21, 0x40, 0x00, 0x00, 0x18, 0x00, 0x00, 0x12,
+0x21, 0x60, 0x00, 0x00, 0x21, 0x68, 0x20, 0x02, 0x21, 0x10, 0x92, 0x01,
+0x01, 0x00, 0x49, 0x90, 0x00, 0x00, 0x4A, 0x90, 0x0D, 0x00, 0x20, 0x11,
+0x21, 0x30, 0x00, 0x00, 0x21, 0x58, 0xA0, 0x01, 0x01, 0x00, 0xC2, 0x24,
+0x21, 0x38, 0x46, 0x01, 0x01, 0x00, 0x03, 0x25, 0xFF, 0x00, 0x46, 0x30,
+0x0E, 0x00, 0x02, 0x2D, 0x21, 0x28, 0x0B, 0x01, 0x2B, 0x20, 0xC9, 0x00,
+0x08, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x68, 0x30, 0xF6, 0xFF, 0x80, 0x14,
+0xD0, 0x3D, 0xA7, 0xA0, 0x03, 0x00, 0x82, 0x25, 0xFF, 0x00, 0x4C, 0x30,
+0x2B, 0x18, 0x90, 0x01, 0xEC, 0xFF, 0x60, 0x14, 0x21, 0x10, 0x92, 0x01,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27,
+0x10, 0x00, 0xBF, 0xAF, 0x90, 0x48, 0x00, 0x0C, 0xFE, 0xFF, 0x05, 0x24,
+0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x90, 0x48, 0x00, 0x0C, 0xFF, 0xFF, 0x05, 0x24, 0x10, 0x00, 0xBF, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0x25, 0xB0, 0x03, 0x3C, 0x01, 0x80, 0x02, 0x3C, 0xB0, 0x03, 0x65, 0x34,
+0xAC, 0x30, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC,
+0x00, 0x00, 0xA4, 0xAC, 0x00, 0x00, 0x83, 0x8C, 0x21, 0x10, 0x00, 0x00,
+0xFF, 0x3F, 0x63, 0x30, 0x00, 0x00, 0xA3, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C,
+0x02, 0x80, 0x08, 0x3C, 0x78, 0x00, 0xBE, 0xAF, 0x7C, 0x00, 0xBF, 0xAF,
+0x74, 0x00, 0xB7, 0xAF, 0x70, 0x00, 0xB6, 0xAF, 0x6C, 0x00, 0xB5, 0xAF,
+0x68, 0x00, 0xB4, 0xAF, 0x64, 0x00, 0xB3, 0xAF, 0x60, 0x00, 0xB2, 0xAF,
+0x5C, 0x00, 0xB1, 0xAF, 0x58, 0x00, 0xB0, 0xAF, 0xE8, 0xE9, 0xC2, 0x24,
+0x74, 0xEA, 0x03, 0x25, 0x01, 0x00, 0x44, 0x90, 0x01, 0x00, 0x65, 0x90,
+0xE8, 0xE9, 0xCB, 0x90, 0x74, 0xEA, 0x0A, 0x91, 0x02, 0x00, 0x47, 0x90,
+0x02, 0x00, 0x66, 0x90, 0x03, 0x00, 0x48, 0x90, 0x03, 0x00, 0x69, 0x90,
+0x00, 0x22, 0x04, 0x00, 0x00, 0x2A, 0x05, 0x00, 0x25, 0x20, 0x8B, 0x00,
+0x25, 0x28, 0xAA, 0x00, 0x00, 0x3C, 0x07, 0x00, 0x00, 0x34, 0x06, 0x00,
+0x25, 0x38, 0xE4, 0x00, 0x25, 0x30, 0xC5, 0x00, 0x00, 0x46, 0x08, 0x00,
+0x00, 0x4E, 0x09, 0x00, 0x25, 0x40, 0x07, 0x01, 0x25, 0x48, 0x26, 0x01,
+0x00, 0x02, 0x04, 0x24, 0x40, 0x00, 0xA8, 0xAF, 0x53, 0x21, 0x00, 0x0C,
+0x48, 0x00, 0xA9, 0xAF, 0xCF, 0x01, 0x40, 0x10, 0x21, 0xF0, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x52, 0x24, 0xC0, 0x3A, 0x45, 0x8E,
+0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x78, 0xEA, 0x84, 0x24,
+0x08, 0x00, 0xD1, 0x97, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x10, 0x3C,
+0x25, 0x88, 0x22, 0x02, 0xB4, 0x55, 0x10, 0x26, 0x24, 0x00, 0x24, 0x26,
+0x21, 0x28, 0x00, 0x02, 0x20, 0x00, 0x20, 0xA6, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x24, 0x26,
+0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x21, 0x28, 0x00, 0x02, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x30, 0x00, 0x24, 0x26, 0x18, 0x00, 0x03, 0x24, 0x0C, 0x00, 0xC3, 0xAF,
+0xE4, 0x1D, 0x42, 0x96, 0x20, 0x00, 0x25, 0x26, 0x38, 0x00, 0x37, 0x26,
+0xFF, 0x0F, 0x43, 0x30, 0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00,
+0x01, 0x00, 0x42, 0x24, 0xE4, 0x1D, 0x42, 0xA6, 0x17, 0x00, 0xA4, 0xA0,
+0x02, 0x80, 0x04, 0x3C, 0x16, 0x00, 0xA3, 0xA0, 0x16, 0x52, 0x00, 0x0C,
+0x24, 0x56, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0xE0, 0x02,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x3A, 0x00, 0x24, 0x26,
+0x18, 0x00, 0xA5, 0x27, 0x02, 0x00, 0x06, 0x24, 0x03, 0x00, 0x02, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0x18, 0x00, 0xA2, 0xA7, 0x0C, 0x00, 0xC3, 0x8F,
+0x02, 0x80, 0x07, 0x3C, 0x3C, 0x00, 0x24, 0x26, 0x04, 0x00, 0x63, 0x24,
+0x0C, 0x00, 0xC3, 0xAF, 0x5C, 0x3A, 0x46, 0x8E, 0x0C, 0x00, 0xC3, 0x27,
+0xC0, 0x55, 0xE7, 0x24, 0x21, 0x28, 0x00, 0x00, 0x54, 0x00, 0xA3, 0xAF,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x20, 0x00, 0xA4, 0x27,
+0x50, 0x00, 0xA5, 0x27, 0x05, 0x53, 0x00, 0x0C, 0x21, 0xB8, 0x40, 0x00,
+0x50, 0x00, 0xA8, 0x8F, 0x21, 0x88, 0x00, 0x00, 0x52, 0x00, 0x00, 0x11,
+0x21, 0x80, 0x00, 0x00, 0x21, 0x38, 0x40, 0x02, 0x18, 0x00, 0xA9, 0x27,
+0x21, 0x10, 0x31, 0x01, 0x08, 0x00, 0x46, 0x90, 0x21, 0x20, 0x00, 0x00,
+0x7F, 0x00, 0xC5, 0x30, 0x21, 0x10, 0x87, 0x00, 0xB0, 0x3A, 0x43, 0x90,
+0x01, 0x00, 0x84, 0x24, 0x7F, 0x00, 0x63, 0x30, 0x3D, 0x00, 0xA3, 0x10,
+0x0D, 0x00, 0x82, 0x2C, 0xFA, 0xFF, 0x40, 0x14, 0x21, 0x10, 0x87, 0x00,
+0x01, 0x00, 0x31, 0x26, 0x2B, 0x10, 0x28, 0x02, 0xF2, 0xFF, 0x40, 0x14,
+0x21, 0x10, 0x31, 0x01, 0x09, 0x00, 0x02, 0x2E, 0x3D, 0x00, 0x40, 0x14,
+0x21, 0x20, 0xE0, 0x02, 0x54, 0x00, 0xA2, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0x08, 0x00, 0x06, 0x24, 0x30, 0x00, 0xA7, 0x27, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xA2, 0xAF, 0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0x40, 0x00,
+0xF8, 0xFF, 0x06, 0x26, 0x32, 0x00, 0x05, 0x24, 0x38, 0x00, 0xA7, 0x27,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C,
+0x02, 0x00, 0x02, 0x24, 0x37, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00,
+0xC0, 0x3A, 0x83, 0x8C, 0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x23, 0x02,
+0x32, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x24, 0x56, 0x46, 0x24,
+0x21, 0x20, 0x60, 0x00, 0xE0, 0x4C, 0x00, 0x08, 0x30, 0x00, 0x05, 0x24,
+0x01, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x24, 0x02, 0x27, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x26, 0x02, 0x00, 0x00, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xF5, 0xFF, 0x45, 0x14, 0x02, 0x80, 0x07, 0x3C,
+0x01, 0x00, 0x66, 0x90, 0x54, 0x00, 0xA2, 0x8F, 0x26, 0x56, 0xE7, 0x24,
+0x21, 0x20, 0xE0, 0x02, 0x21, 0x38, 0x27, 0x02, 0x30, 0x00, 0x05, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x06, 0x4D, 0x00, 0x08,
+0x21, 0xB8, 0x40, 0x00, 0x21, 0x10, 0x30, 0x01, 0x18, 0x00, 0x46, 0xA0,
+0x50, 0x00, 0xA8, 0x8F, 0x01, 0x00, 0x31, 0x26, 0x2B, 0x10, 0x28, 0x02,
+0xB4, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x10, 0x26, 0xBA, 0x4C, 0x00, 0x08,
+0x09, 0x00, 0x02, 0x2E, 0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0xE0, 0x02,
+0x21, 0x30, 0x00, 0x02, 0x01, 0x00, 0x05, 0x24, 0x30, 0x00, 0xA7, 0x27,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C,
+0x02, 0x00, 0x02, 0x24, 0xCB, 0xFF, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x1B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x40, 0x14,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24, 0xC0, 0x3A, 0x62, 0x8C,
+0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02, 0x11, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x60, 0x00, 0x24, 0x56, 0x52, 0x24,
+0x21, 0xA8, 0x60, 0x00, 0x02, 0x80, 0x13, 0x3C, 0x21, 0x20, 0x32, 0x02,
+0x00, 0x00, 0x83, 0x90, 0x2D, 0x00, 0x02, 0x24, 0xD6, 0x00, 0x62, 0x10,
+0x02, 0x80, 0x05, 0x3C, 0x01, 0x00, 0x82, 0x90, 0xC0, 0x3A, 0x03, 0x8E,
+0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x23, 0x02,
+0xF6, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x32, 0x02, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C, 0x02, 0x00, 0x02, 0x24,
+0x86, 0x00, 0x62, 0x10, 0x0C, 0x00, 0x11, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x43, 0x24, 0xC0, 0x3A, 0x62, 0x8C, 0x0C, 0x00, 0x11, 0x24,
+0x2B, 0x10, 0x22, 0x02, 0x26, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x24, 0x56, 0x56, 0x24, 0x21, 0xA8, 0x60, 0x00, 0xDD, 0x00, 0x14, 0x24,
+0x39, 0x4D, 0x00, 0x08, 0x02, 0x80, 0x13, 0x3C, 0x01, 0x00, 0x02, 0x92,
+0xC0, 0x3A, 0xA3, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24,
+0x2B, 0x18, 0x23, 0x02, 0x1B, 0x00, 0x60, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x02, 0x00, 0x12, 0x26,
+0x21, 0x20, 0x40, 0x02, 0x70, 0xDE, 0x65, 0x26, 0xF3, 0xFF, 0x54, 0x14,
+0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x54, 0x00, 0xA2, 0x8F,
+0xDD, 0x00, 0x05, 0x24, 0x21, 0x38, 0x40, 0x02, 0x07, 0x00, 0x06, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x08, 0x00, 0x04, 0x92,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x65, 0x24, 0x21, 0xB8, 0x40, 0x00,
+0x01, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x5E, 0x44, 0xA0,
+0xBC, 0x40, 0xA3, 0xAC, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x64, 0x24,
+0xC0, 0x3A, 0x82, 0x8C, 0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02,
+0x20, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x24, 0x56, 0x56, 0x24, 0x26, 0x56, 0x75, 0x24, 0x21, 0xA0, 0x80, 0x00,
+0x66, 0x4D, 0x00, 0x08, 0xDD, 0x00, 0x13, 0x24, 0x01, 0x00, 0x02, 0x92,
+0xC0, 0x3A, 0x83, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24,
+0x2B, 0x18, 0x23, 0x02, 0x14, 0x00, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x21, 0x90, 0x35, 0x02,
+0x21, 0x20, 0x40, 0x02, 0x48, 0x00, 0xA5, 0x27, 0xF3, 0xFF, 0x53, 0x14,
+0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x06, 0x92,
+0x54, 0x00, 0xA2, 0x8F, 0x21, 0x38, 0x40, 0x02, 0xDD, 0x00, 0x05, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x21, 0xB8, 0x40, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0xFC, 0x40, 0x83, 0x8C,
+0x01, 0x00, 0x02, 0x24, 0x61, 0x00, 0x62, 0x10, 0x06, 0x00, 0x02, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24, 0xC0, 0x3A, 0x43, 0x8C,
+0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x23, 0x02, 0x10, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x24, 0x56, 0x46, 0x24, 0x21, 0x20, 0x60, 0x00,
+0x44, 0x00, 0x05, 0x24, 0x21, 0x80, 0x26, 0x02, 0x00, 0x00, 0x02, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x45, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x24, 0x02, 0xF6, 0xFF, 0x60, 0x14,
+0x21, 0x80, 0x26, 0x02, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24,
+0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0xC0, 0x03,
+0x01, 0x00, 0x63, 0x38, 0x0B, 0x38, 0x03, 0x00, 0x21, 0x28, 0x00, 0x00,
+0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00,
+0x7C, 0x00, 0xBF, 0x8F, 0x78, 0x00, 0xBE, 0x8F, 0x74, 0x00, 0xB7, 0x8F,
+0x70, 0x00, 0xB6, 0x8F, 0x6C, 0x00, 0xB5, 0x8F, 0x68, 0x00, 0xB4, 0x8F,
+0x64, 0x00, 0xB3, 0x8F, 0x60, 0x00, 0xB2, 0x8F, 0x5C, 0x00, 0xB1, 0x8F,
+0x58, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x80, 0x00, 0xBD, 0x27,
+0xC0, 0x3A, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0x22, 0x02,
+0x77, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x24, 0x56, 0x56, 0x24, 0x26, 0x56, 0x75, 0x24, 0x21, 0xA0, 0x80, 0x00,
+0xBD, 0x4D, 0x00, 0x08, 0xDD, 0x00, 0x13, 0x24, 0x01, 0x00, 0x02, 0x92,
+0xC0, 0x3A, 0x83, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24,
+0x2B, 0x18, 0x23, 0x02, 0x6B, 0xFF, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x21, 0x90, 0x35, 0x02,
+0x21, 0x20, 0x40, 0x02, 0x40, 0x00, 0xA5, 0x27, 0xF3, 0xFF, 0x53, 0x14,
+0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x06, 0x92,
+0x54, 0x00, 0xA3, 0x8F, 0x21, 0x38, 0x40, 0x02, 0xDD, 0x00, 0x05, 0x24,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x26, 0x4D, 0x00, 0x08,
+0x21, 0xB8, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C,
+0x8C, 0xEA, 0x84, 0x24, 0x01, 0x00, 0x06, 0x92, 0x54, 0x00, 0xA2, 0x8F,
+0x02, 0x80, 0x07, 0x3C, 0x26, 0x56, 0xE7, 0x24, 0x21, 0x38, 0x27, 0x02,
+0x21, 0x20, 0xE0, 0x02, 0x44, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C,
+0x10, 0x00, 0xA2, 0xAF, 0x95, 0x4D, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C,
+0xB6, 0x40, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x62, 0x10,
+0x05, 0x00, 0x02, 0x24, 0x9C, 0xFF, 0x62, 0x14, 0x02, 0x80, 0x03, 0x3C,
+0x02, 0x80, 0x07, 0x3C, 0x21, 0x20, 0xE0, 0x02, 0x34, 0xDE, 0xE7, 0x24,
+0xDD, 0x00, 0x05, 0x24, 0x06, 0x00, 0x06, 0x24, 0x54, 0x00, 0xA3, 0x8F,
+0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x7E, 0x4D, 0x00, 0x08,
+0x21, 0xB8, 0x40, 0x00, 0x02, 0x80, 0x14, 0x3C, 0x26, 0x56, 0xA5, 0x24,
+0x21, 0x28, 0x25, 0x02, 0x64, 0x5C, 0x84, 0x26, 0xF4, 0x54, 0x00, 0x0C,
+0x20, 0x00, 0x06, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xD9, 0x5C, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x41, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xFF, 0x42, 0x30,
+0x04, 0x41, 0x02, 0xA6, 0x02, 0x80, 0x02, 0x3C, 0xC4, 0xDF, 0x44, 0x8C,
+0x04, 0x41, 0xA3, 0x96, 0x20, 0x00, 0x80, 0x10, 0x0C, 0x00, 0x62, 0x34,
+0x00, 0x01, 0x42, 0x34, 0x04, 0x41, 0xA2, 0xA6, 0x02, 0x80, 0x03, 0x3C,
+0xC6, 0x5C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x15, 0x00, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x67, 0x5C, 0x64, 0x26, 0x44, 0xDF, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x10, 0x00, 0x06, 0x24, 0x21, 0x10, 0x32, 0x02, 0x01, 0x00, 0x46, 0x90,
+0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0xE0, 0x02, 0x64, 0x5C, 0x87, 0x26,
+0x2D, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF,
+0x21, 0xB8, 0x40, 0x00, 0x01, 0x00, 0x02, 0x24, 0x20, 0x4D, 0x00, 0x08,
+0xFC, 0x40, 0x02, 0xAE, 0x04, 0x41, 0x02, 0x96, 0xFC, 0x4D, 0x00, 0x08,
+0x02, 0x00, 0x42, 0x34, 0x67, 0x5C, 0x64, 0x26, 0x0D, 0x4E, 0x00, 0x08,
+0x54, 0xDF, 0xA5, 0x24, 0x04, 0x4E, 0x00, 0x08, 0x04, 0x41, 0xA2, 0xA6,
+0x02, 0x80, 0x02, 0x3C, 0x34, 0xDE, 0x42, 0x24, 0x06, 0x00, 0x48, 0x90,
+0x02, 0x00, 0x03, 0x24, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x08, 0x35,
+0x21, 0x38, 0x40, 0x00, 0xDD, 0x00, 0x05, 0x24, 0x07, 0x00, 0x06, 0x24,
+0x04, 0x00, 0x43, 0xA0, 0xE9, 0x4D, 0x00, 0x08, 0x06, 0x00, 0x48, 0xA0,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x64, 0xEA, 0xA5, 0x24, 0x9F, 0x4D, 0x00, 0x08,
+0xFF, 0xFF, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0xB0, 0x1B, 0x43, 0x94, 0x32, 0x00, 0x04, 0x24, 0xCC, 0x39, 0x44, 0xAC,
+0x9F, 0xFE, 0x63, 0x30, 0x80, 0x00, 0x63, 0x34, 0xB0, 0x1B, 0x43, 0xA4,
+0x18, 0x40, 0x40, 0xAC, 0x1C, 0x40, 0x40, 0xAC, 0x38, 0x4C, 0x00, 0x08,
+0xB0, 0x39, 0x40, 0xAC, 0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x60, 0x1B, 0x50, 0x24,
+0x1C, 0x40, 0x03, 0x8E, 0xFE, 0xFF, 0x04, 0x24, 0x01, 0x00, 0x63, 0x24,
+0x03, 0x00, 0x62, 0x2C, 0x12, 0x00, 0x40, 0x10, 0x1C, 0x40, 0x03, 0xAE,
+0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30,
+0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0x38, 0x4C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x03, 0x24,
+0xCC, 0x39, 0x03, 0xAE, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x96,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C,
+0xB0, 0x1B, 0x02, 0xA6, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x2C, 0x00, 0xBF, 0xAF,
+0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x14, 0x3C, 0x60, 0x1B, 0x92, 0x26,
+0xB0, 0x1B, 0x43, 0x96, 0x00, 0x00, 0x85, 0x8C, 0x0F, 0x00, 0x42, 0x30,
+0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00, 0x01, 0x00, 0x63, 0x30,
+0xFF, 0x3F, 0xB3, 0x30, 0x18, 0x00, 0x11, 0x26, 0x0A, 0x00, 0x60, 0x14,
+0x21, 0x20, 0x00, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02,
+0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00,
+0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xEF, 0xFF, 0x40, 0x14,
+0x21, 0x20, 0x00, 0x00, 0xB0, 0x1B, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x42, 0x30, 0xEA, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x03, 0x96, 0x04, 0x00, 0x04, 0x24, 0x21, 0x10, 0x80, 0x00,
+0x00, 0x40, 0x63, 0x30, 0x0A, 0x10, 0x03, 0x00, 0x21, 0x10, 0x22, 0x02,
+0x1C, 0x00, 0x43, 0x94, 0x1A, 0x00, 0x45, 0x94, 0x2F, 0x00, 0x60, 0x14,
+0x02, 0x00, 0x02, 0x24, 0x14, 0x00, 0xA2, 0x10, 0x01, 0x00, 0x02, 0x24,
+0x0E, 0x00, 0xA4, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x24, 0x40, 0x43, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x10, 0x60, 0x1B, 0x83, 0x26,
+0xB0, 0x1B, 0x62, 0x94, 0xFF, 0xFF, 0x04, 0x24, 0xFF, 0xDF, 0x42, 0x30,
+0x7B, 0x4E, 0x00, 0x08, 0xB0, 0x1B, 0x62, 0xA4, 0x36, 0x4E, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x7B, 0x4E, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00,
+0x13, 0x58, 0x00, 0x0C, 0x04, 0xEB, 0x84, 0x24, 0xA4, 0x4E, 0x00, 0x08,
+0x60, 0x1B, 0x83, 0x26, 0x24, 0x40, 0x43, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0xF5, 0xFF, 0x62, 0x14, 0xE2, 0xFF, 0x67, 0x26, 0x36, 0x00, 0x04, 0x26,
+0x10, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x10, 0x00, 0xA6, 0x27,
+0x16, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA6, 0x8F,
+0x02, 0x80, 0x04, 0x3C, 0x94, 0x5B, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x45, 0x24, 0xB0, 0x1B, 0x43, 0x96, 0x21, 0x20, 0x00, 0x00,
+0x03, 0x00, 0x02, 0x24, 0xDF, 0xFF, 0x63, 0x30, 0x40, 0x00, 0x63, 0x34,
+0xB0, 0x1B, 0x43, 0xA6, 0x2D, 0x14, 0x00, 0x0C, 0x20, 0x40, 0x42, 0xAE,
+0x7B, 0x4E, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x2C, 0xEB, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x60, 0x00,
+0xA4, 0x4E, 0x00, 0x08, 0x60, 0x1B, 0x83, 0x26, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0x48, 0xEB, 0x84, 0x24, 0xA4, 0x4E, 0x00, 0x08,
+0x60, 0x1B, 0x83, 0x26, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24,
+0xB0, 0x1B, 0x62, 0x94, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x00, 0x00,
+0xEF, 0xFF, 0x42, 0x30, 0x20, 0x00, 0x42, 0x34, 0xB0, 0x1B, 0x62, 0xA4,
+0x32, 0x00, 0x02, 0x24, 0x20, 0x40, 0x65, 0xAC, 0xB0, 0x39, 0x62, 0xAC,
+0xCC, 0x39, 0x60, 0xAC, 0x18, 0x40, 0x60, 0xAC, 0x2D, 0x14, 0x00, 0x08,
+0x1C, 0x40, 0x60, 0xAC, 0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x07, 0x3C,
+0x14, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xE6, 0x24,
+0x18, 0x40, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, 0x24,
+0x03, 0x00, 0xA3, 0x2C, 0x0E, 0x00, 0x60, 0x14, 0x60, 0x1B, 0xF0, 0x24,
+0x24, 0x40, 0xC3, 0x8C, 0x03, 0x00, 0x02, 0x24, 0x16, 0x00, 0x62, 0x10,
+0xFF, 0xFF, 0x04, 0x24, 0xB0, 0x1B, 0xC2, 0x94, 0x18, 0x40, 0xC5, 0xAC,
+0xFF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C, 0xB0, 0x1B, 0xC2, 0xA4,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x03, 0x96, 0xBF, 0xFF, 0x02, 0x24,
+0x18, 0x40, 0xC5, 0xAC, 0x24, 0x10, 0x62, 0x00, 0x80, 0x00, 0x63, 0x30,
+0x21, 0x20, 0x00, 0x00, 0x0F, 0x00, 0x60, 0x10, 0x20, 0x00, 0x45, 0x34,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x03, 0x96, 0x01, 0x00, 0x02, 0x24,
+0x24, 0x40, 0xC2, 0xAC, 0xBF, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x62, 0x00,
+0x80, 0x00, 0x63, 0x30, 0x18, 0x40, 0xC0, 0xAC, 0x21, 0x20, 0x00, 0x00,
+0xF3, 0xFF, 0x60, 0x14, 0x20, 0x00, 0x45, 0x34, 0x01, 0x00, 0x02, 0x24,
+0x20, 0x40, 0x02, 0xAE, 0x2D, 0x14, 0x00, 0x0C, 0xB0, 0x1B, 0x05, 0xA6,
+0x32, 0x00, 0x03, 0x24, 0xB0, 0x39, 0x03, 0xAE, 0x14, 0x00, 0xBF, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0xD0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF, 0x21, 0x90, 0x80, 0x00,
+0x00, 0x01, 0x04, 0x24, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x21, 0x98, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C,
+0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x21, 0x88, 0x40, 0x00, 0x58, 0xEC, 0x84, 0x24, 0x38, 0x00, 0x40, 0x10,
+0x48, 0xEC, 0xA5, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x28, 0x40, 0x02,
+0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26, 0x20, 0x00, 0x00, 0xA6,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x30, 0x00, 0x04, 0x26,
+0xB4, 0x55, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0x03, 0xFF, 0x63, 0x30, 0xC0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6,
+0x60, 0x1B, 0xA5, 0x24, 0x0C, 0x00, 0x22, 0xAE, 0xE4, 0x1D, 0xA3, 0x94,
+0x20, 0x00, 0x07, 0x26, 0x38, 0x00, 0x04, 0x26, 0xFF, 0x0F, 0x62, 0x30,
+0x00, 0x11, 0x02, 0x00, 0x02, 0x32, 0x02, 0x00, 0x01, 0x00, 0x63, 0x24,
+0xE4, 0x1D, 0xA3, 0xA4, 0x17, 0x00, 0xE6, 0xA0, 0x16, 0x00, 0xE2, 0xA0,
+0x10, 0x00, 0xA6, 0x27, 0x0C, 0x00, 0x27, 0x26, 0x02, 0x00, 0x05, 0x24,
+0x4C, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB3, 0xA7, 0x21, 0x20, 0x20, 0x02,
+0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C,
+0x21, 0x38, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xAC, 0xE8, 0x84, 0x24, 0x28, 0x00, 0xBF, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xD0, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00,
+0x00, 0x01, 0x04, 0x24, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x21, 0x98, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C,
+0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x21, 0x90, 0x40, 0x00, 0x78, 0xEC, 0x84, 0x24, 0x3B, 0x00, 0x40, 0x10,
+0x68, 0xEC, 0xA5, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x50, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x28, 0x20, 0x02,
+0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26, 0x20, 0x00, 0x00, 0xA6,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x30, 0x00, 0x04, 0x26,
+0xB4, 0x55, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x11, 0x3C,
+0x03, 0xFF, 0x63, 0x30, 0xA0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6,
+0x60, 0x1B, 0x31, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x23, 0x96,
+0x20, 0x00, 0x06, 0x26, 0x38, 0x00, 0x04, 0x26, 0xFF, 0x0F, 0x62, 0x30,
+0x00, 0x11, 0x02, 0x00, 0x02, 0x2A, 0x02, 0x00, 0x01, 0x00, 0x63, 0x24,
+0xE4, 0x1D, 0x23, 0xA6, 0x0C, 0x00, 0x47, 0x26, 0x17, 0x00, 0xC5, 0xA0,
+0x16, 0x00, 0xC2, 0xA0, 0x02, 0x00, 0x05, 0x24, 0x10, 0x00, 0xA6, 0x27,
+0x4C, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB3, 0xA7, 0xB6, 0x40, 0x23, 0x92,
+0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0x40, 0x02, 0x01, 0x00, 0x63, 0x38,
+0x0B, 0x38, 0x03, 0x00, 0x21, 0x28, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xAC, 0xE8, 0x84, 0x24, 0x28, 0x00, 0xBF, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xC8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB1, 0xAF, 0xFF, 0xFF, 0x05, 0x24,
+0x21, 0x88, 0x80, 0x00, 0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA4, 0x27,
+0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0xEC, 0x54, 0x00, 0x0C,
+0x28, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x28, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02, 0x21, 0x20, 0x00, 0x02,
+0xEC, 0x54, 0x00, 0x0C, 0x10, 0x00, 0x06, 0x24, 0x20, 0x00, 0x02, 0x96,
+0x24, 0x00, 0x04, 0x26, 0x10, 0x00, 0xA5, 0x27, 0x03, 0xFF, 0x42, 0x30,
+0xC8, 0x00, 0x42, 0x34, 0x20, 0x00, 0x02, 0xA6, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x25, 0xB0, 0x03, 0x3C, 0x50, 0x00, 0x62, 0x34,
+0x00, 0x00, 0x44, 0x8C, 0x54, 0x00, 0x65, 0x34, 0x58, 0x00, 0x66, 0x34,
+0x18, 0x00, 0xA4, 0xAF, 0x00, 0x00, 0xA2, 0x8C, 0x5C, 0x00, 0x63, 0x34,
+0x2A, 0x00, 0x04, 0x26, 0x1C, 0x00, 0xA2, 0xAF, 0x00, 0x00, 0xC7, 0x8C,
+0x18, 0x00, 0xA5, 0x27, 0x06, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA7, 0xAF,
+0x00, 0x00, 0x62, 0x8C, 0x1A, 0x00, 0x12, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x24, 0x00, 0xA2, 0xAF, 0x30, 0x00, 0x04, 0x26, 0x20, 0x00, 0xA5, 0x27,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x13, 0x00, 0x03, 0x24,
+0x14, 0x00, 0x23, 0xAE, 0x0C, 0x00, 0x32, 0xAE, 0x08, 0x00, 0x05, 0x8E,
+0x04, 0x00, 0x04, 0x8E, 0xFF, 0xDF, 0x02, 0x3C, 0x14, 0x00, 0x06, 0x8E,
+0xFF, 0xFF, 0x42, 0x34, 0x10, 0x00, 0x07, 0x8E, 0xFF, 0xE0, 0x03, 0x24,
+0x24, 0x28, 0xA2, 0x00, 0x00, 0x40, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00,
+0x25, 0x28, 0xA2, 0x00, 0xFF, 0x81, 0x03, 0x24, 0xFE, 0xFF, 0x02, 0x3C,
+0x24, 0x30, 0xC3, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x00, 0x12, 0x84, 0x34,
+0x00, 0x80, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00, 0x25, 0x38, 0xE3, 0x00,
+0x00, 0x26, 0xC6, 0x34, 0x80, 0x00, 0xA5, 0x34, 0x20, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x12, 0xA6, 0x10, 0x00, 0x07, 0xAE, 0x02, 0x00, 0x02, 0xA2,
+0x14, 0x00, 0x06, 0xAE, 0x04, 0x00, 0x04, 0xAE, 0x08, 0x00, 0x05, 0xAE,
+0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F,
+0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0xB0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xB5, 0xAF, 0x34, 0x00, 0xB3, 0xAF,
+0xFF, 0xFF, 0xF5, 0x30, 0x25, 0xB0, 0x13, 0x3C, 0x01, 0x80, 0x02, 0x3C,
+0x2C, 0x00, 0xB1, 0xAF, 0x18, 0x03, 0x63, 0x36, 0x54, 0x40, 0x42, 0x24,
+0x20, 0x00, 0xB1, 0x26, 0x48, 0x00, 0xBE, 0xAF, 0x44, 0x00, 0xB7, 0xAF,
+0x38, 0x00, 0xB4, 0xAF, 0x64, 0x00, 0xB7, 0x93, 0x60, 0x00, 0xB4, 0x93,
+0x21, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x62, 0xAC, 0x21, 0x20, 0x20, 0x02,
+0x40, 0x00, 0xB6, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0x4C, 0x00, 0xBF, 0xAF,
+0x28, 0x00, 0xB0, 0xAF, 0xFF, 0x00, 0xB6, 0x30, 0x53, 0x21, 0x00, 0x0C,
+0xFF, 0x00, 0xD2, 0x30, 0x12, 0x00, 0x40, 0x14, 0x24, 0x00, 0xA2, 0xAF,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24,
+0x13, 0x58, 0x00, 0x0C, 0x88, 0xEC, 0xA5, 0x24, 0x4C, 0x00, 0xBF, 0x8F,
+0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F,
+0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F,
+0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x08, 0x00, 0x43, 0x8C,
+0xB0, 0x03, 0x62, 0x36, 0x02, 0x80, 0x10, 0x3C, 0x00, 0x00, 0x43, 0xAC,
+0x24, 0x00, 0xA2, 0x8F, 0x21, 0x30, 0x20, 0x02, 0x21, 0x28, 0x00, 0x00,
+0x08, 0x00, 0x44, 0x94, 0xE3, 0x54, 0x00, 0x0C, 0x25, 0x20, 0x90, 0x00,
+0x24, 0x00, 0xA3, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x88, 0x50, 0x00, 0x5C, 0x00, 0x80, 0x16,
+0x20, 0x00, 0x30, 0x26, 0x20, 0x00, 0x32, 0xA6, 0x48, 0x00, 0x02, 0x24,
+0x7A, 0x00, 0x42, 0x12, 0xC8, 0x00, 0x02, 0x24, 0x79, 0x00, 0x42, 0x12,
+0x50, 0x00, 0x62, 0x36, 0x04, 0x00, 0x02, 0x24, 0x56, 0x00, 0xC2, 0x16,
+0x21, 0x28, 0xC0, 0x03, 0xA4, 0x00, 0x02, 0x24, 0x9F, 0x00, 0x42, 0x12,
+0x02, 0x80, 0x02, 0x3C, 0x24, 0x00, 0xA2, 0x8F, 0x25, 0xB0, 0x10, 0x3C,
+0xB0, 0x03, 0x10, 0x36, 0x0C, 0x00, 0x55, 0xAC, 0x24, 0x00, 0xA2, 0x8F,
+0x12, 0x00, 0x03, 0x24, 0x21, 0x28, 0x00, 0x00, 0x14, 0x00, 0x43, 0xAC,
+0x00, 0x00, 0x15, 0xAE, 0x24, 0x00, 0xA2, 0x8F, 0x08, 0x00, 0x06, 0x24,
+0x08, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAE,
+0x24, 0x00, 0xA2, 0x8F, 0x02, 0x80, 0x03, 0x3C, 0x08, 0x00, 0x44, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x88, 0x83, 0x00, 0xEC, 0x54, 0x00, 0x0C,
+0x21, 0x20, 0x20, 0x02, 0x04, 0x00, 0x25, 0x8E, 0x08, 0x00, 0x24, 0x8E,
+0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xE0, 0x03, 0x24, 0xFF, 0xFF, 0x42, 0x34,
+0x14, 0x00, 0x26, 0x8E, 0x24, 0x28, 0xA3, 0x00, 0x24, 0x20, 0x82, 0x00,
+0x00, 0x40, 0x02, 0x3C, 0x10, 0x00, 0x27, 0x8E, 0x25, 0x20, 0x82, 0x00,
+0xE0, 0xFF, 0x03, 0x24, 0x00, 0x12, 0xA5, 0x34, 0xFF, 0xE0, 0x02, 0x3C,
+0x24, 0x28, 0xA3, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0xFF, 0x81, 0x03, 0x24,
+0x24, 0x30, 0xC3, 0x00, 0x24, 0x20, 0x82, 0x00, 0x00, 0x05, 0x03, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x25, 0x38, 0xE2, 0x00, 0x25, 0x20, 0x83, 0x00,
+0x05, 0x00, 0xA5, 0x34, 0x20, 0x00, 0x02, 0x24, 0x08, 0x00, 0x24, 0xAE,
+0x00, 0x00, 0x35, 0xA6, 0x02, 0x00, 0x22, 0xA2, 0x14, 0x00, 0x26, 0xAE,
+0x10, 0x00, 0x27, 0xAE, 0x04, 0x00, 0x25, 0xAE, 0x8A, 0x40, 0x00, 0x0C,
+0x20, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x24, 0x00, 0xA3, 0x8F,
+0x98, 0x54, 0x42, 0x24, 0x04, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x62, 0xAC,
+0x04, 0x00, 0x43, 0xAC, 0x24, 0x00, 0xA2, 0x27, 0x00, 0x00, 0x83, 0xAC,
+0x04, 0x00, 0x64, 0xAC, 0x20, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0xBF, 0x8F,
+0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F,
+0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F,
+0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x00, 0x10, 0x42, 0x36,
+0x53, 0x50, 0x00, 0x08, 0x20, 0x00, 0x22, 0xA6, 0x04, 0x00, 0x04, 0x26,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0x48, 0x37, 0xA5, 0x24, 0x0A, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24,
+0x10, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x00, 0x1E, 0x12, 0x00, 0x03, 0x1E, 0x03, 0x00, 0x28, 0x00, 0x60, 0x04,
+0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xE4, 0x1D, 0xA6, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC2, 0x24, 0x00, 0x21, 0x06, 0x00,
+0xFF, 0xFF, 0x46, 0x30, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x10, 0xC2, 0x2C,
+0x0A, 0x30, 0x02, 0x00, 0x02, 0x1A, 0x04, 0x00, 0x17, 0x00, 0x03, 0xA2,
+0x16, 0x00, 0x04, 0xA2, 0x5E, 0x50, 0x00, 0x08, 0xE4, 0x1D, 0xA6, 0xA4,
+0x50, 0x00, 0x62, 0x36, 0x00, 0x00, 0x43, 0x8C, 0x54, 0x00, 0x64, 0x36,
+0x58, 0x00, 0x65, 0x36, 0x10, 0x00, 0xA3, 0xAF, 0x00, 0x00, 0x82, 0x8C,
+0x5C, 0x00, 0x67, 0x36, 0x2A, 0x00, 0x24, 0x26, 0x14, 0x00, 0xA2, 0xAF,
+0x00, 0x00, 0xA3, 0x8C, 0x06, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA5, 0x27,
+0x18, 0x00, 0xA3, 0xAF, 0x00, 0x00, 0xE2, 0x8C, 0xF4, 0x54, 0x00, 0x0C,
+0x1C, 0x00, 0xA2, 0xAF, 0x30, 0x00, 0x24, 0x26, 0x18, 0x00, 0xA5, 0x27,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x20, 0x00, 0x23, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x34, 0x58, 0x50, 0x00, 0x08,
+0x20, 0x00, 0x23, 0xA6, 0x02, 0x80, 0x02, 0x3C, 0xFF, 0xFF, 0xE3, 0x32,
+0x60, 0x1B, 0x42, 0x24, 0x40, 0x28, 0x17, 0x00, 0x18, 0x00, 0x03, 0xA2,
+0x21, 0x28, 0xA2, 0x00, 0x19, 0x00, 0x00, 0xA2, 0xD4, 0x1D, 0xA6, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC2, 0x24, 0x00, 0x21, 0x06, 0x00,
+0xFF, 0xFF, 0x46, 0x30, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x10, 0xC2, 0x2C,
+0x0A, 0x30, 0x02, 0x00, 0x02, 0x1A, 0x04, 0x00, 0x17, 0x00, 0x03, 0xA2,
+0x16, 0x00, 0x04, 0xA2, 0x5E, 0x50, 0x00, 0x08, 0xD4, 0x1D, 0xA6, 0xA4,
+0xAC, 0x55, 0x43, 0x94, 0x02, 0x80, 0x05, 0x3C, 0x04, 0x00, 0x04, 0x26,
+0x00, 0xC0, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30, 0x02, 0x12, 0x03, 0x00,
+0xB4, 0x55, 0xA5, 0x24, 0x03, 0x00, 0x02, 0xA2, 0x02, 0x00, 0x03, 0xA2,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C,
+0x0A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x5E, 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x82, 0x30, 0x02, 0x80, 0x04, 0x3C, 0xE0, 0xFF, 0xBD, 0x27,
+0xB4, 0x55, 0x84, 0x24, 0x08, 0x00, 0x05, 0x24, 0x48, 0x00, 0x06, 0x24,
+0x18, 0x00, 0x07, 0x24, 0x18, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xA2, 0xAF,
+0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA0, 0xAF, 0x18, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xC8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB5, 0xAF, 0x02, 0x80, 0x15, 0x3C,
+0x1C, 0x00, 0xB1, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xB1, 0x26, 0xB0, 0x1B, 0x23, 0x96,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x62, 0x30, 0x37, 0x00, 0x40, 0x14,
+0x00, 0x01, 0x62, 0x30, 0x2A, 0x00, 0x40, 0x10, 0x00, 0x10, 0x62, 0x30,
+0x25, 0x00, 0x40, 0x14, 0x01, 0x00, 0x62, 0x30, 0x45, 0x00, 0x40, 0x14,
+0x04, 0x00, 0x62, 0x30, 0x21, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x21, 0x98, 0x20, 0x02, 0x47, 0x39, 0x56, 0x24, 0x01, 0x00, 0x14, 0x24,
+0x20, 0x01, 0x11, 0x24, 0x3E, 0x51, 0x00, 0x08, 0x19, 0x00, 0x12, 0x24,
+0xFF, 0xFF, 0x52, 0x26, 0x18, 0x00, 0x40, 0x06, 0x30, 0x00, 0x31, 0x26,
+0x21, 0x80, 0x33, 0x02, 0xE6, 0x1D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xF9, 0xFF, 0x54, 0x14, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1D, 0x02, 0x8E,
+0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x40, 0x14, 0x10, 0x00, 0xA4, 0x27,
+0x3A, 0x41, 0x62, 0x92, 0x21, 0x20, 0x36, 0x02, 0xFF, 0xFF, 0x42, 0x24,
+0x3A, 0x41, 0x62, 0xA2, 0xC4, 0x0E, 0x00, 0x0C, 0xE6, 0x1D, 0x00, 0xA2,
+0x3C, 0x51, 0x00, 0x08, 0xFF, 0xFF, 0x52, 0x26, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0xA4, 0x27, 0x14, 0x40, 0x20, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0xE8, 0x1E, 0x20, 0xAE, 0xA9, 0x1B, 0x00, 0x0C,
+0x60, 0x1B, 0xB0, 0x26, 0xE8, 0x39, 0x02, 0xAE, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F,
+0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C,
+0x98, 0xEC, 0x84, 0x24, 0xB0, 0x1B, 0x22, 0x96, 0xE8, 0x39, 0x20, 0xAE,
+0xFD, 0xFF, 0x04, 0x24, 0xEF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C,
+0xB0, 0x1B, 0x22, 0xA6, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
+0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
+0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0xE8, 0x1E, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xD5, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90,
+0x01, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30, 0x05, 0x00, 0x63, 0x28,
+0x0E, 0x00, 0x60, 0x10, 0x14, 0x40, 0x24, 0xAE, 0x0E, 0x51, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB0, 0x26,
+0x58, 0x51, 0x00, 0x08, 0xE8, 0x39, 0x02, 0xAE, 0x8A, 0x40, 0x00, 0x0C,
+0xFF, 0xFF, 0x52, 0x26, 0x10, 0x00, 0xA4, 0x27, 0x90, 0x40, 0x00, 0x0C,
+0xF8, 0x1D, 0x00, 0xAE, 0x3C, 0x51, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x87, 0x51, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C,
+0xB8, 0xEC, 0x84, 0x24, 0x25, 0xB0, 0x06, 0x3C, 0x4C, 0x00, 0xC2, 0x34,
+0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC3, 0x8C,
+0xB0, 0x1B, 0x27, 0x96, 0x7B, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x18, 0x62, 0x00, 0xFE, 0xFE, 0xE7, 0x30, 0x00, 0x00, 0xC3, 0xAC,
+0x21, 0x28, 0x00, 0x00, 0xB0, 0x1B, 0x27, 0xA6, 0x21, 0x20, 0x00, 0x00,
+0x37, 0x3E, 0x20, 0xA2, 0x95, 0x0E, 0x00, 0x0C, 0xD6, 0x1E, 0x20, 0xA2,
+0x02, 0x80, 0x04, 0x3C, 0xC4, 0x0E, 0x00, 0x0C, 0xB4, 0x55, 0x84, 0x24,
+0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB0, 0x26, 0x58, 0x51, 0x00, 0x08,
+0xE8, 0x39, 0x02, 0xAE, 0xFF, 0x00, 0x84, 0x30, 0x02, 0x00, 0x02, 0x24,
+0x03, 0x00, 0x83, 0x28, 0x0D, 0x00, 0x82, 0x10, 0x21, 0x28, 0x00, 0x00,
+0x06, 0x00, 0x60, 0x10, 0x04, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, 0x24,
+0x0B, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0xA0, 0x00, 0xFD, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x04, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x06, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0xFF, 0x00, 0x91, 0x30,
+0x02, 0x80, 0x04, 0x3C, 0x18, 0x00, 0xB0, 0xAF, 0xD4, 0xEC, 0x84, 0x24,
+0xFF, 0x00, 0xB0, 0x30, 0x20, 0x00, 0xBF, 0xAF, 0x13, 0x58, 0x00, 0x0C,
+0x21, 0x28, 0x20, 0x02, 0xB1, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02,
+0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24, 0x08, 0x00, 0x05, 0x24,
+0xC8, 0x00, 0x06, 0x24, 0x1A, 0x00, 0x07, 0x24, 0x10, 0x00, 0xB1, 0xAF,
+0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA2, 0xAF, 0x20, 0x00, 0xBF, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x05, 0x3C,
+0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xA5, 0x24,
+0x4C, 0x3A, 0xA2, 0x94, 0x01, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x90, 0x30,
+0x00, 0xC0, 0x42, 0x24, 0xFF, 0xFF, 0x44, 0x30, 0xA3, 0x31, 0x00, 0x0C,
+0x2A, 0x1C, 0xA3, 0xA0, 0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24,
+0x04, 0x00, 0x05, 0x24, 0xA4, 0x00, 0x06, 0x24, 0x10, 0x00, 0x07, 0x24,
+0x10, 0x00, 0xB0, 0xAF, 0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA0, 0xAF,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x08, 0x00, 0x82, 0x24, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24,
+0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x18, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C,
+0x10, 0x00, 0xA5, 0xA7, 0x21, 0x20, 0x40, 0x00, 0x10, 0x00, 0xA5, 0x27,
+0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x18, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0xE0, 0x03, 0x0A, 0x00, 0x82, 0x24, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xBF, 0xAF, 0x16, 0x52, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24,
+0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C,
+0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x18, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x00, 0x00, 0x05, 0xA2, 0x01, 0x00, 0x06, 0xA2, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x88, 0xC0, 0x00,
+0x02, 0x00, 0x84, 0x24, 0x30, 0x00, 0xB2, 0x8F, 0x0D, 0x00, 0xC0, 0x14,
+0x21, 0x28, 0xE0, 0x00, 0x00, 0x00, 0x43, 0x8E, 0x21, 0x10, 0x11, 0x02,
+0x1C, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x63, 0x24,
+0x00, 0x00, 0x43, 0xAE, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x02, 0x00, 0x42, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x43, 0x8E, 0x21, 0x10, 0x11, 0x02, 0x1C, 0x00, 0xBF, 0x8F,
+0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xAE,
+0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x02, 0x00, 0x42, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0xA0, 0x00,
+0x18, 0x00, 0xB2, 0xAF, 0x21, 0x28, 0xC0, 0x00, 0x21, 0x90, 0xE0, 0x00,
+0x21, 0x30, 0x00, 0x02, 0x1C, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0xF4, 0x54, 0x00, 0x0C, 0x21, 0x88, 0x80, 0x00, 0x00, 0x00, 0x43, 0x8E,
+0x21, 0x10, 0x30, 0x02, 0x1C, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x70, 0x00,
+0x00, 0x00, 0x43, 0xAE, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x7F, 0x00, 0x84, 0x30, 0x6D, 0x00, 0x82, 0x2C, 0x0A, 0x00, 0x40, 0x10,
+0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00,
+0xFC, 0xEC, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x0B, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x0A, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x09, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x08, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x07, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x06, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x03, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x05, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x04, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x02, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x7F, 0x00, 0x84, 0x30, 0x0C, 0x00, 0x82, 0x2C, 0x0A, 0x00, 0x40, 0x10,
+0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00,
+0xB0, 0xEE, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x6C, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x60, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x48, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x30, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x24, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x18, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x12, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x0C, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x16, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x0B, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x04, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x02, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0xC8, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB5, 0xAF, 0x02, 0x80, 0x15, 0x3C,
+0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x20, 0x00, 0xB4, 0xAF,
+0x1C, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0xB8, 0x80, 0x00,
+0x21, 0xA0, 0x00, 0x00, 0x21, 0x98, 0x00, 0x00, 0x60, 0x1B, 0xB6, 0x26,
+0x60, 0x1B, 0xA2, 0x26, 0x21, 0x10, 0x62, 0x02, 0xFB, 0x1B, 0x51, 0x90,
+0xFE, 0x00, 0x03, 0x24, 0x1E, 0x00, 0x23, 0x12, 0xFF, 0x00, 0x02, 0x24,
+0x21, 0x00, 0x22, 0x12, 0x21, 0x10, 0x80, 0x02, 0x91, 0x52, 0x00, 0x0C,
+0x21, 0x20, 0x20, 0x02, 0x21, 0x88, 0x40, 0x00, 0x21, 0x80, 0x00, 0x00,
+0x21, 0x90, 0xC0, 0x02, 0x21, 0x10, 0x12, 0x02, 0xEE, 0x1B, 0x44, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x02, 0x00, 0x42, 0x2C, 0x05, 0x00, 0x40, 0x14, 0x01, 0x00, 0x10, 0x26,
+0x91, 0x52, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x51, 0x10,
+0x01, 0x00, 0x03, 0x24, 0x0D, 0x00, 0x02, 0x2A, 0xF3, 0xFF, 0x40, 0x14,
+0x21, 0x10, 0x12, 0x02, 0x21, 0x18, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x14, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x22, 0x32, 0x21, 0x10, 0xF4, 0x02,
+0x00, 0x00, 0x51, 0xA0, 0x01, 0x00, 0x94, 0x26, 0x01, 0x00, 0x73, 0x26,
+0x0D, 0x00, 0x62, 0x2A, 0xDB, 0xFF, 0x40, 0x14, 0x60, 0x1B, 0xA2, 0x26,
+0x21, 0x10, 0x80, 0x02, 0x30, 0x00, 0xBF, 0x8F, 0x2C, 0x00, 0xB7, 0x8F,
+0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27,
+0xF0, 0x52, 0x00, 0x08, 0x80, 0x00, 0x51, 0x34, 0xD0, 0xFF, 0xBD, 0x27,
+0x24, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xB0, 0xAF, 0x21, 0x88, 0x80, 0x00,
+0x21, 0x80, 0xA0, 0x00, 0x0D, 0x00, 0x06, 0x24, 0x21, 0x28, 0x00, 0x00,
+0x28, 0x00, 0xBF, 0xAF, 0xE3, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0xC1, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0xAE,
+0x21, 0x20, 0x20, 0x02, 0x10, 0x00, 0xA5, 0x27, 0xF4, 0x54, 0x00, 0x0C,
+0x21, 0x30, 0x40, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB1, 0x8F,
+0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0x21, 0x28, 0x00, 0x00, 0x21, 0x10, 0x85, 0x00, 0x00, 0x00, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x60, 0x10, 0x0D, 0x00, 0xA2, 0x2C,
+0xFA, 0xFF, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xFF, 0xFF, 0xA5, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, 0x00, 0x00, 0x82, 0x94,
+0x21, 0x30, 0x80, 0x00, 0x10, 0x00, 0x85, 0x24, 0x42, 0x1A, 0x02, 0x00,
+0xC2, 0x11, 0x02, 0x00, 0x02, 0x00, 0x42, 0x30, 0x01, 0x00, 0x63, 0x30,
+0x25, 0x18, 0x43, 0x00, 0x01, 0x00, 0x04, 0x24, 0x07, 0x00, 0x64, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x10, 0x0A, 0x00, 0xC5, 0x24,
+0x02, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0xC5, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00,
+0x00, 0x00, 0x82, 0x94, 0x21, 0x30, 0x80, 0x00, 0x04, 0x00, 0x85, 0x24,
+0x42, 0x1A, 0x02, 0x00, 0xC2, 0x11, 0x02, 0x00, 0x02, 0x00, 0x42, 0x30,
+0x01, 0x00, 0x63, 0x30, 0x25, 0x18, 0x43, 0x00, 0x01, 0x00, 0x04, 0x24,
+0x04, 0x00, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xC5, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0xA0, 0x00, 0x13, 0x00, 0xA0, 0x18, 0x21, 0x30, 0x00, 0x00,
+0x02, 0x00, 0x07, 0x24, 0x04, 0x00, 0x08, 0x24, 0x0B, 0x00, 0x09, 0x24,
+0x16, 0x00, 0x0A, 0x24, 0x21, 0x10, 0x86, 0x00, 0x00, 0x00, 0x43, 0x90,
+0x01, 0x00, 0xC6, 0x24, 0x7F, 0x00, 0x63, 0x30, 0x07, 0x00, 0x67, 0x10,
+0x2A, 0x10, 0xC5, 0x00, 0x05, 0x00, 0x68, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x69, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x6A, 0x14,
+0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x14, 0x00, 0xBF, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x5C, 0x5C, 0x43, 0x8C,
+0x08, 0x00, 0x10, 0x24, 0x06, 0x00, 0xA0, 0x14, 0x0A, 0x80, 0x03, 0x00,
+0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x49, 0x53, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x36, 0x01, 0x00, 0x42, 0x38,
+0x03, 0x00, 0x04, 0x36, 0x21, 0x80, 0x60, 0x00, 0x0B, 0x80, 0x82, 0x00,
+0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27,
+0x14, 0x00, 0xB1, 0xAF, 0x0E, 0x00, 0xA3, 0x2C, 0x21, 0x88, 0xA0, 0x00,
+0x0D, 0x00, 0x02, 0x24, 0x0A, 0x88, 0x43, 0x00, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x21, 0x98, 0x80, 0x00, 0x21, 0x90, 0x00, 0x00,
+0x15, 0x00, 0x20, 0x12, 0x21, 0x80, 0x00, 0x00, 0x8E, 0x53, 0x00, 0x08,
+0x01, 0x00, 0x14, 0x24, 0x2B, 0x10, 0x11, 0x02, 0x11, 0x00, 0x40, 0x10,
+0x21, 0x10, 0x40, 0x02, 0x21, 0x18, 0x70, 0x02, 0x00, 0x00, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30, 0x00, 0x16, 0x02, 0x00,
+0x03, 0x16, 0x02, 0x00, 0xF6, 0xFF, 0x41, 0x04, 0x01, 0x00, 0x10, 0x26,
+0x61, 0x52, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x54, 0x00,
+0x25, 0x90, 0x42, 0x02, 0x2B, 0x10, 0x11, 0x02, 0xF3, 0xFF, 0x40, 0x14,
+0x21, 0x18, 0x70, 0x02, 0x21, 0x10, 0x40, 0x02, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF,
+0x0E, 0x00, 0xA3, 0x2C, 0x21, 0x88, 0xA0, 0x00, 0x0D, 0x00, 0x02, 0x24,
+0x0A, 0x88, 0x43, 0x00, 0x20, 0x00, 0xB4, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB3, 0xAF,
+0x21, 0xA0, 0x80, 0x00, 0x21, 0x90, 0x00, 0x00, 0x0A, 0x00, 0x20, 0x12,
+0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x13, 0x24, 0x21, 0x10, 0x90, 0x02,
+0x00, 0x00, 0x44, 0x90, 0x61, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x10, 0x26,
+0x04, 0x10, 0x53, 0x00, 0x2B, 0x18, 0x11, 0x02, 0xF9, 0xFF, 0x60, 0x14,
+0x25, 0x90, 0x42, 0x02, 0x21, 0x10, 0x40, 0x02, 0x24, 0x00, 0xBF, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0xFF, 0xFF, 0x02, 0x24,
+0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x30, 0xA0, 0x00,
+0x1B, 0x00, 0x82, 0x10, 0x20, 0x00, 0x10, 0x24, 0x20, 0x00, 0x82, 0x28,
+0x06, 0x00, 0x40, 0x14, 0x40, 0x18, 0x04, 0x00, 0x21, 0x10, 0x00, 0x02,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x21, 0x18, 0x64, 0x00, 0x21, 0x80, 0x80, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x19, 0x03, 0x00,
+0x60, 0x1B, 0x42, 0x24, 0x47, 0x39, 0x84, 0x24, 0x21, 0x20, 0x64, 0x00,
+0x21, 0x18, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, 0x06, 0x00, 0x06, 0x24,
+0xF4, 0x54, 0x00, 0x0C, 0xE6, 0x1D, 0x62, 0xA0, 0x21, 0x10, 0x00, 0x02,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0xF0, 0x00, 0x47, 0x24, 0x05, 0x00, 0x10, 0x24, 0xD6, 0x1E, 0x43, 0x24,
+0xF4, 0x53, 0x00, 0x08, 0xF0, 0x00, 0x05, 0x24, 0x01, 0x00, 0x10, 0x26,
+0x20, 0x00, 0x02, 0x2E, 0x30, 0x00, 0xA5, 0x24, 0xDE, 0xFF, 0x40, 0x10,
+0x30, 0x00, 0xE7, 0x24, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xF8, 0xFF, 0x40, 0x14, 0x30, 0x00, 0x63, 0x24, 0x02, 0x80, 0x04, 0x3C,
+0x47, 0x39, 0x84, 0x24, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0xA4, 0x00,
+0xE6, 0x1D, 0xE2, 0xA0, 0x21, 0x28, 0xC0, 0x00, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0xE4, 0x53, 0x00, 0x08, 0x21, 0x10, 0x00, 0x02,
+0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x30, 0x00, 0xB2, 0x8F, 0x21, 0x88, 0x80, 0x00, 0x21, 0x20, 0xA0, 0x00,
+0x21, 0x28, 0x20, 0x02, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF,
+0xC7, 0x53, 0x00, 0x0C, 0xFF, 0xFF, 0xF0, 0x30, 0x20, 0x00, 0x03, 0x24,
+0xFF, 0x00, 0x44, 0x30, 0x21, 0x28, 0x00, 0x02, 0x21, 0x30, 0x20, 0x02,
+0x07, 0x00, 0x43, 0x10, 0x21, 0x38, 0x40, 0x02, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x6F, 0x20, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x24, 0x00, 0xB5, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0xA8, 0x80, 0x00,
+0x60, 0x1B, 0x54, 0x24, 0x47, 0x39, 0x73, 0x24, 0x05, 0x00, 0x11, 0x24,
+0x01, 0x00, 0x12, 0x24, 0xF0, 0x00, 0x10, 0x24, 0x34, 0x54, 0x00, 0x08,
+0x28, 0x00, 0xBF, 0xAF, 0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0x22, 0x2A,
+0x0E, 0x00, 0x40, 0x10, 0x21, 0x10, 0x20, 0x02, 0x21, 0x10, 0x14, 0x02,
+0xE6, 0x1D, 0x43, 0x90, 0x21, 0x20, 0x13, 0x02, 0x21, 0x28, 0xA0, 0x02,
+0x06, 0x00, 0x06, 0x24, 0xF6, 0xFF, 0x72, 0x14, 0x30, 0x00, 0x10, 0x26,
+0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x31, 0x26, 0xFF, 0xFF, 0x31, 0x26, 0x21, 0x10, 0x20, 0x02,
+0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27,
+0xD0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF,
+0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x21, 0x98, 0x80, 0x00, 0x60, 0x1B, 0x56, 0x24, 0x47, 0x39, 0x75, 0x24,
+0x21, 0x88, 0x00, 0x00, 0x01, 0x00, 0x14, 0x24, 0x21, 0x80, 0x00, 0x00,
+0x2C, 0x00, 0xBF, 0xAF, 0x60, 0x54, 0x00, 0x08, 0x18, 0x00, 0xB2, 0xAF,
+0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0x22, 0x2A, 0x1E, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x16, 0x02, 0xE6, 0x1D, 0x42, 0x92,
+0x21, 0x20, 0x15, 0x02, 0x21, 0x28, 0x60, 0x02, 0x06, 0x00, 0x06, 0x24,
+0xF6, 0xFF, 0x54, 0x14, 0x30, 0x00, 0x10, 0x26, 0x1D, 0x55, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x31, 0x26,
+0xFF, 0xFF, 0x31, 0x26, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C,
+0xFF, 0x00, 0x24, 0x32, 0xE6, 0x1D, 0x40, 0xA2, 0x2C, 0x00, 0xBF, 0x8F,
+0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F,
+0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x88, 0xDE, 0xC6, 0x24, 0x78, 0xDE, 0xE7, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x6F, 0x20, 0x00, 0x08, 0x30, 0x00, 0xBD, 0x27,
+0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x30, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x18, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0x52, 0x24, 0x30, 0x00, 0xBE, 0xAF,
+0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF,
+0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x00, 0x00,
+0x02, 0x80, 0x1E, 0x3C, 0x02, 0x80, 0x17, 0x3C, 0x02, 0x80, 0x16, 0x3C,
+0x01, 0x00, 0x13, 0x24, 0xFF, 0xF7, 0x15, 0x24, 0xFF, 0xEF, 0x14, 0x24,
+0x21, 0x88, 0x40, 0x02, 0xE6, 0x1D, 0x22, 0x92, 0xC0, 0x48, 0x10, 0x00,
+0xD2, 0x5C, 0xC7, 0x93, 0x41, 0x00, 0x53, 0x10, 0x21, 0x30, 0x32, 0x01,
+0xD4, 0x23, 0xC2, 0x8C, 0xBF, 0xFF, 0x03, 0x24, 0x24, 0x28, 0x43, 0x00,
+0x80, 0x07, 0xA3, 0x34, 0x24, 0x10, 0x75, 0x00, 0x31, 0x00, 0xF3, 0x10,
+0x24, 0x10, 0x54, 0x00, 0xD4, 0x23, 0xC2, 0xAC, 0x21, 0x48, 0x32, 0x01,
+0xD4, 0x23, 0x23, 0x8D, 0xFD, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x18, 0x62, 0x00, 0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x18, 0x62, 0x00, 0xE7, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0x24, 0x18, 0x62, 0x00, 0xFF, 0xFD, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34,
+0xD8, 0x23, 0x28, 0x8D, 0x24, 0x18, 0x62, 0x00, 0xFF, 0xFB, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0xFF, 0xE7, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x06, 0x3C, 0x00, 0x80, 0x08, 0x35,
+0x24, 0x18, 0x62, 0x00, 0x25, 0x40, 0x06, 0x01, 0xFF, 0x00, 0x04, 0x32,
+0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x10, 0x26, 0x88, 0xDE, 0xE6, 0x26,
+0x78, 0xDE, 0xC7, 0x26, 0xD8, 0x23, 0x28, 0xAD, 0x6F, 0x20, 0x00, 0x0C,
+0xD4, 0x23, 0x23, 0xAD, 0x20, 0x00, 0x02, 0x2A, 0xD1, 0xFF, 0x40, 0x14,
+0x30, 0x00, 0x31, 0x26, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xBE, 0x8F,
+0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F,
+0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90,
+0x24, 0x18, 0x75, 0x00, 0x80, 0x0F, 0xA2, 0x34, 0x00, 0x10, 0x63, 0x34,
+0xCA, 0xFF, 0x87, 0x14, 0x24, 0x10, 0x54, 0x00, 0xA9, 0x54, 0x00, 0x08,
+0xD4, 0x23, 0xC3, 0xAC, 0xA1, 0x54, 0x00, 0x08, 0xE6, 0x1D, 0x20, 0xA2,
+0xE8, 0x54, 0x00, 0x08, 0xFF, 0x00, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA0,
+0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0x84, 0x24, 0xFC, 0xFF, 0xC0, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xAC,
+0xFF, 0xFF, 0xC6, 0x24, 0xFD, 0xFF, 0xC0, 0x14, 0x04, 0x00, 0x84, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x38, 0x80, 0x00,
+0x08, 0x00, 0xC0, 0x10, 0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0xFF, 0x06, 0x24,
+0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0x63, 0x24, 0x01, 0x00, 0xA5, 0x24,
+0x00, 0x00, 0xE2, 0xA0, 0xFB, 0xFF, 0x66, 0x14, 0x01, 0x00, 0xE7, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, 0x2B, 0x10, 0xA4, 0x00,
+0x0D, 0x00, 0x40, 0x14, 0xFF, 0xFF, 0x02, 0x24, 0xFF, 0xFF, 0xC6, 0x24,
+0x08, 0x00, 0xC2, 0x10, 0x21, 0x18, 0x80, 0x00, 0xFF, 0xFF, 0x07, 0x24,
+0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0xA5, 0x24,
+0x00, 0x00, 0x62, 0xA0, 0xFB, 0xFF, 0xC7, 0x14, 0x01, 0x00, 0x63, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, 0x21, 0x28, 0xA6, 0x00,
+0x21, 0x18, 0x86, 0x00, 0xFF, 0xFF, 0xC6, 0x24, 0xFA, 0xFF, 0xC2, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x24, 0xFF, 0xFF, 0xA5, 0x24,
+0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0x63, 0x24, 0xFF, 0xFF, 0xC6, 0x24,
+0xFB, 0xFF, 0xC7, 0x14, 0x00, 0x00, 0x62, 0xA0, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x80, 0x00, 0x0C, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0xA3, 0x90, 0x01, 0x00, 0x84, 0x24,
+0x23, 0x10, 0x43, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x04, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xFF, 0xFF, 0xC6, 0x24,
+0xF6, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0xC0, 0x00, 0x33, 0x55, 0x00, 0x08, 0x21, 0x18, 0x86, 0x00,
+0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x45, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x24, 0xFA, 0xFF, 0x83, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00,
+0x09, 0x00, 0xC0, 0x10, 0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0x00, 0xA5, 0x30,
+0xFF, 0xFF, 0x06, 0x24, 0x00, 0x00, 0x82, 0x90, 0xFF, 0xFF, 0x63, 0x24,
+0x05, 0x00, 0x45, 0x10, 0x01, 0x00, 0x84, 0x24, 0xFB, 0xFF, 0x66, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x82, 0x24, 0x21, 0x38, 0x00, 0x00,
+0x1F, 0x00, 0xC0, 0x10, 0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x40, 0xF4, 0x4B, 0x24, 0x00, 0x00, 0x87, 0x90, 0x00, 0x00, 0xA3, 0x90,
+0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0x84, 0x24, 0x21, 0x10, 0xEB, 0x00,
+0x16, 0x00, 0xE0, 0x10, 0x01, 0x00, 0xA5, 0x24, 0x14, 0x00, 0x60, 0x10,
+0x21, 0x48, 0x6B, 0x00, 0x10, 0x00, 0xE3, 0x10, 0x20, 0x00, 0xE8, 0x24,
+0x00, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x6A, 0x24, 0xFF, 0x00, 0x07, 0x31,
+0x00, 0x00, 0x22, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x02, 0x00, 0x40, 0x10, 0xFF, 0x00, 0xE7, 0x30, 0xFF, 0x00, 0x43, 0x31,
+0xFF, 0x00, 0x63, 0x30, 0x03, 0x00, 0xE3, 0x14, 0x00, 0x00, 0x00, 0x00,
+0xE5, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x23, 0x10, 0xE3, 0x00, 0x21, 0x18, 0x80, 0x00, 0x00, 0x00, 0xA2, 0x90,
+0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xFC, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x21, 0x38, 0x80, 0x00, 0xFF, 0xFF, 0x03, 0x24, 0xFF, 0xFF, 0xC6, 0x24,
+0x06, 0x00, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90,
+0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xF9, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xE0, 0x00,
+0x00, 0x00, 0x82, 0x80, 0x82, 0x55, 0x00, 0x08, 0x21, 0x18, 0x80, 0x00,
+0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90,
+0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xFC, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x12, 0x00, 0xC0, 0x10, 0x21, 0x18, 0x80, 0x00, 0x00, 0x00, 0x82, 0x80,
+0x93, 0x55, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x24,
+0x00, 0x00, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90, 0x01, 0x00, 0xA5, 0x24,
+0x00, 0x00, 0x82, 0xA0, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x84, 0x24,
+0xFF, 0xFF, 0xC6, 0x24, 0xF9, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x80, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0xA2, 0x90, 0x01, 0x00, 0x84, 0x24,
+0x23, 0x10, 0x62, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x03, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xF7, 0xFF, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0x00, 0x00, 0x0B, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x83, 0x90, 0xFF, 0xFF, 0xC6, 0x24,
+0x23, 0x10, 0x62, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x03, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xF5, 0xFF, 0x60, 0x14,
+0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x83, 0x80, 0x00, 0x2E, 0x05, 0x00, 0x21, 0x10, 0x80, 0x00,
+0xC4, 0x55, 0x00, 0x08, 0x03, 0x2E, 0x05, 0x00, 0x07, 0x00, 0x60, 0x10,
+0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00,
+0xFB, 0xFF, 0x65, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x82, 0x80, 0xD0, 0x55, 0x00, 0x08, 0x21, 0x18, 0x80, 0x00,
+0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x62, 0x80, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x21, 0x80, 0xA0, 0x00, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF,
+0x21, 0x88, 0x80, 0x00, 0xCA, 0x55, 0x00, 0x0C, 0x00, 0x86, 0x10, 0x00,
+0x21, 0x18, 0x51, 0x00, 0x03, 0x86, 0x10, 0x00, 0x00, 0x00, 0x62, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x50, 0x10, 0x21, 0x10, 0x60, 0x00,
+0xFF, 0xFF, 0x63, 0x24, 0x2B, 0x10, 0x71, 0x00, 0xF9, 0xFF, 0x40, 0x10,
+0x21, 0x10, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x21, 0x30, 0x80, 0x00,
+0x0D, 0x00, 0xA0, 0x10, 0xFF, 0xFF, 0xA3, 0x24, 0x00, 0x00, 0x82, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFF, 0x63, 0x24, 0x05, 0x00, 0x65, 0x10,
+0x01, 0x00, 0xC6, 0x24, 0x00, 0x00, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x00,
+0xFA, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x23, 0x10, 0xC4, 0x00, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x19, 0x00, 0x40, 0x10, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x20, 0x11, 0x21, 0x30, 0xA0, 0x00,
+0x00, 0x3E, 0x02, 0x00, 0x03, 0x3E, 0x07, 0x00, 0x21, 0x18, 0x20, 0x01,
+0x15, 0x00, 0xE3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC6, 0x24,
+0x00, 0x00, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x02, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x60, 0x14, 0x00, 0x16, 0x02, 0x00,
+0x03, 0x16, 0x02, 0x00, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xEB, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x08, 0x25, 0x08, 0x00, 0xE0, 0x03,
+0x21, 0x10, 0x00, 0x01, 0x00, 0x00, 0xA2, 0x90, 0x15, 0x56, 0x00, 0x08,
+0x00, 0x16, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x90, 0x15, 0x56, 0x00, 0x08,
+0x00, 0x16, 0x02, 0x00, 0x00, 0x00, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x00, 0xE0, 0x10, 0x21, 0x10, 0x80, 0x00, 0x00, 0x00, 0xA4, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x09, 0x00, 0x60, 0x10, 0x21, 0x30, 0xA0, 0x00, 0x00, 0x3E, 0x07, 0x00,
+0x03, 0x3E, 0x07, 0x00, 0x0B, 0x00, 0xE3, 0x10, 0x01, 0x00, 0xC6, 0x24,
+0x00, 0x00, 0xC3, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x47, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xE0, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x18, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x10,
+0x21, 0x88, 0xA0, 0x00, 0x01, 0x56, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02,
+0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02,
+0x21, 0x20, 0x00, 0x02, 0x22, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x25, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10,
+0x21, 0x18, 0x40, 0x00, 0x00, 0x00, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x58, 0xF5, 0x43, 0xAC, 0x21, 0x18, 0x00, 0x02, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x60, 0xA0,
+0x56, 0x56, 0x00, 0x08, 0x01, 0x00, 0x63, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x58, 0xF5, 0x50, 0x8C, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x00, 0x12,
+0x21, 0x18, 0x00, 0x00, 0x01, 0x56, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02,
+0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02,
+0x21, 0x20, 0x00, 0x02, 0xE0, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00,
+0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x02, 0x80, 0x02, 0x3C, 0x58, 0xF5, 0x40, 0xAC, 0x20, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x90, 0x8C, 0x21, 0x90, 0x80, 0x00,
+0x21, 0x88, 0xA0, 0x00, 0x21, 0x18, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x12,
+0x21, 0x20, 0x00, 0x02, 0x01, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02,
+0x21, 0x20, 0x00, 0x02, 0x07, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x25, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00,
+0x09, 0x00, 0x40, 0x14, 0x00, 0x00, 0x42, 0xAE, 0x21, 0x18, 0x00, 0x02,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00,
+0xF5, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x64, 0x24, 0x00, 0x00, 0x60, 0xA0,
+0x8F, 0x56, 0x00, 0x08, 0x00, 0x00, 0x44, 0xAE, 0xD8, 0xFF, 0xBD, 0x27,
+0x14, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, 0x21, 0x20, 0xA0, 0x00,
+0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x20, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0xCA, 0x55, 0x00, 0x0C, 0x21, 0x98, 0xA0, 0x00,
+0x21, 0x90, 0x40, 0x00, 0x08, 0x00, 0x40, 0x16, 0x21, 0x10, 0x20, 0x02,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xCA, 0x55, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02,
+0x21, 0x80, 0x40, 0x00, 0x2A, 0x10, 0x52, 0x00, 0x0A, 0x00, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x60, 0x02,
+0x21, 0x30, 0x40, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0xFF, 0xFF, 0x10, 0x26,
+0x0B, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x12, 0x02, 0xF8, 0xFF, 0x60, 0x10,
+0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0xAB, 0x56, 0x00, 0x08, 0x21, 0x10, 0x20, 0x02, 0x00, 0x00, 0x87, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0xE0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA6, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xC0, 0x10,
+0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00,
+0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0x0A, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00,
+0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00,
+0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x03, 0x16, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x23, 0x10, 0x43, 0x00,
+0xEE, 0x56, 0x00, 0x08, 0xDF, 0xFF, 0x08, 0x24, 0x00, 0x00, 0xA6, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x06, 0x01, 0x00, 0x16, 0x02, 0x00,
+0xF0, 0xFF, 0xC0, 0x10, 0x03, 0x16, 0x02, 0x00, 0xEF, 0xFF, 0x62, 0x14,
+0xDF, 0xFF, 0x02, 0x24, 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x87, 0x90,
+0x01, 0x00, 0xA5, 0x24, 0x24, 0x10, 0x07, 0x01, 0x00, 0x1E, 0x02, 0x00,
+0xF2, 0xFF, 0xE0, 0x14, 0x03, 0x1E, 0x03, 0x00, 0x00, 0x00, 0xA6, 0x90,
+0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00,
+0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x03, 0x16, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x23, 0x10, 0x43, 0x00,
+0xA8, 0xFF, 0xBD, 0x27, 0x44, 0x00, 0xB5, 0xAF, 0x40, 0x00, 0xB4, 0xAF,
+0x38, 0x00, 0xB2, 0xAF, 0x34, 0x00, 0xB1, 0xAF, 0x54, 0x00, 0xBF, 0xAF,
+0x50, 0x00, 0xBE, 0xAF, 0x4C, 0x00, 0xB7, 0xAF, 0x48, 0x00, 0xB6, 0xAF,
+0x3C, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xA0, 0x00,
+0x00, 0x00, 0xA5, 0x90, 0x21, 0xA0, 0x80, 0x00, 0x21, 0xA8, 0xC0, 0x00,
+0x00, 0x26, 0x05, 0x00, 0x03, 0x26, 0x04, 0x00, 0x11, 0x00, 0x80, 0x10,
+0x21, 0x88, 0x80, 0x02, 0x25, 0x00, 0x02, 0x24, 0x29, 0x00, 0x82, 0x10,
+0x0A, 0x00, 0x02, 0x24, 0x1B, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x1E, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xA2,
+0x01, 0x00, 0x31, 0x26, 0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x05, 0x00, 0x03, 0x26, 0x04, 0x00,
+0xF2, 0xFF, 0x80, 0x14, 0x25, 0x00, 0x02, 0x24, 0x02, 0x00, 0x80, 0x12,
+0x23, 0x10, 0x34, 0x02, 0x00, 0x00, 0x20, 0xA2, 0x54, 0x00, 0xBF, 0x8F,
+0x50, 0x00, 0xBE, 0x8F, 0x4C, 0x00, 0xB7, 0x8F, 0x48, 0x00, 0xB6, 0x8F,
+0x44, 0x00, 0xB5, 0x8F, 0x40, 0x00, 0xB4, 0x8F, 0x3C, 0x00, 0xB3, 0x8F,
+0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x58, 0x00, 0xBD, 0x27, 0xE7, 0xFF, 0x80, 0x16,
+0x00, 0x00, 0x00, 0x00, 0x57, 0x58, 0x00, 0x0C, 0x0D, 0x00, 0x04, 0x24,
+0x0A, 0x00, 0x04, 0x24, 0x57, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x52, 0x26,
+0x00, 0x00, 0x45, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x05, 0x00,
+0x20, 0x57, 0x00, 0x08, 0x03, 0x26, 0x04, 0x00, 0x01, 0x00, 0x52, 0x26,
+0x00, 0x00, 0x45, 0x92, 0x73, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x05, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0x2C, 0x00, 0x62, 0x10, 0x10, 0x00, 0xB3, 0x27,
+0x23, 0x00, 0x02, 0x24, 0x21, 0xF0, 0x60, 0x02, 0x21, 0x38, 0x00, 0x00,
+0x34, 0x00, 0x62, 0x10, 0x1C, 0x00, 0x04, 0x24, 0x00, 0x16, 0x05, 0x00,
+0x03, 0x16, 0x02, 0x00, 0x68, 0x00, 0x03, 0x24, 0x36, 0x00, 0x43, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x05, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x39, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA2, 0x34,
+0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, 0x78, 0x00, 0x03, 0x24,
+0x3C, 0x00, 0x43, 0x10, 0x20, 0x00, 0xA6, 0x30, 0x00, 0x1E, 0x05, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0x64, 0x00, 0x02, 0x24, 0x49, 0x00, 0x62, 0x10,
+0x40, 0x00, 0x02, 0x24, 0x81, 0x00, 0x62, 0x10, 0x21, 0x00, 0x02, 0x24,
+0x92, 0x00, 0x62, 0x10, 0x63, 0x00, 0x02, 0x24, 0xA2, 0x00, 0x62, 0x10,
+0x11, 0x00, 0xB3, 0x27, 0x10, 0x00, 0xA5, 0xA3, 0x21, 0x80, 0xC0, 0x03,
+0x2B, 0x10, 0x13, 0x02, 0xB4, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x6C, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92,
+0x01, 0x00, 0x10, 0x26, 0x00, 0x00, 0x22, 0xA2, 0x65, 0x57, 0x00, 0x08,
+0x01, 0x00, 0x31, 0x26, 0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26,
+0x21, 0x80, 0x40, 0x00, 0x00, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xA6, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x80, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA2, 0x01, 0x00, 0x10, 0x26,
+0x72, 0x57, 0x00, 0x08, 0x01, 0x00, 0x31, 0x26, 0x01, 0x00, 0x52, 0x26,
+0x00, 0x00, 0x45, 0x92, 0x68, 0x00, 0x03, 0x24, 0x00, 0x16, 0x05, 0x00,
+0x03, 0x16, 0x02, 0x00, 0xCC, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x07, 0x24,
+0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x16, 0x05, 0x00, 0x03, 0x16, 0x02, 0x00, 0xC9, 0xFF, 0x43, 0x14,
+0x0C, 0x00, 0x04, 0x24, 0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92,
+0x78, 0x00, 0x03, 0x24, 0x20, 0x00, 0xA2, 0x34, 0x00, 0x16, 0x02, 0x00,
+0x03, 0x16, 0x02, 0x00, 0xC7, 0xFF, 0x43, 0x14, 0x04, 0x00, 0x04, 0x24,
+0x20, 0x00, 0xA6, 0x30, 0x00, 0x00, 0xA5, 0x8E, 0x35, 0x00, 0xE0, 0x14,
+0x04, 0x00, 0xB5, 0x26, 0xCD, 0xFF, 0x80, 0x04, 0x02, 0x80, 0x02, 0x3C,
+0x0C, 0xEF, 0x42, 0x24, 0x00, 0x00, 0x47, 0x8C, 0x07, 0x10, 0x85, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x47, 0x00, 0x00, 0x00, 0x43, 0x90,
+0xFC, 0xFF, 0x84, 0x24, 0x25, 0x18, 0xC3, 0x00, 0x00, 0x00, 0x63, 0xA2,
+0xF8, 0xFF, 0x81, 0x04, 0x01, 0x00, 0x73, 0x26, 0x65, 0x57, 0x00, 0x08,
+0x21, 0x80, 0xC0, 0x03, 0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26,
+0x28, 0x00, 0x40, 0x04, 0x21, 0x28, 0x40, 0x00, 0x21, 0x80, 0x60, 0x02,
+0x02, 0x80, 0x02, 0x3C, 0x10, 0xEF, 0x42, 0x24, 0x00, 0x00, 0x46, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xA6, 0x00, 0xC3, 0x27, 0x05, 0x00,
+0x10, 0x10, 0x00, 0x00, 0x83, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00,
+0x80, 0x18, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0x40, 0x18, 0x03, 0x00,
+0x23, 0x18, 0xA3, 0x00, 0x30, 0x00, 0x63, 0x24, 0x00, 0x00, 0x63, 0xA2,
+0x21, 0x28, 0x40, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x73, 0x26,
+0xC5, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x63, 0x26, 0x00, 0x00, 0x65, 0x80,
+0x00, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xA0,
+0x00, 0x00, 0x05, 0xA2, 0xFF, 0xFF, 0x63, 0x24, 0x01, 0x00, 0x10, 0x26,
+0x2B, 0x10, 0x03, 0x02, 0xF7, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x65, 0x57, 0x00, 0x08, 0x21, 0x80, 0xC0, 0x03, 0x58, 0x00, 0xC3, 0x34,
+0x30, 0x00, 0x02, 0x24, 0x12, 0x00, 0xB3, 0x27, 0x10, 0x00, 0xA2, 0xA3,
+0x96, 0x57, 0x00, 0x08, 0x11, 0x00, 0xA3, 0xA3, 0x2D, 0x00, 0x02, 0x24,
+0x23, 0x28, 0x05, 0x00, 0x11, 0x00, 0xB3, 0x27, 0xA9, 0x57, 0x00, 0x08,
+0x10, 0x00, 0xA2, 0xA3, 0x00, 0x00, 0x04, 0x82, 0x57, 0x58, 0x00, 0x0C,
+0x01, 0x00, 0x10, 0x26, 0x66, 0x57, 0x00, 0x08, 0x2B, 0x10, 0x13, 0x02,
+0x00, 0x00, 0x04, 0x82, 0x57, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x10, 0x26,
+0x72, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x8E,
+0x28, 0x00, 0xB0, 0x27, 0x2C, 0x00, 0xA4, 0x27, 0x2B, 0x10, 0x04, 0x02,
+0x28, 0x00, 0xA3, 0xAF, 0x0B, 0x00, 0x40, 0x10, 0x04, 0x00, 0xB5, 0x26,
+0x21, 0xB8, 0x80, 0x00, 0x02, 0x80, 0x16, 0x3C, 0x00, 0x00, 0x06, 0x92,
+0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x10, 0x26, 0x08, 0x58, 0x00, 0x0C,
+0x00, 0xEF, 0xC5, 0x26, 0x2B, 0x18, 0x17, 0x02, 0xF9, 0xFF, 0x60, 0x14,
+0x21, 0x98, 0x62, 0x02, 0x64, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x73, 0x26,
+0x00, 0x00, 0xA2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x56, 0x24,
+0x21, 0x80, 0x40, 0x00, 0x2B, 0x10, 0x56, 0x00, 0xF8, 0xFF, 0x40, 0x10,
+0x04, 0x00, 0xB5, 0x26, 0x02, 0x80, 0x17, 0x3C, 0x00, 0x00, 0x06, 0x82,
+0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x10, 0x26, 0x08, 0x58, 0x00, 0x0C,
+0x04, 0xEF, 0xE5, 0x26, 0x2B, 0x18, 0x16, 0x02, 0xF9, 0xFF, 0x60, 0x14,
+0x21, 0x98, 0x62, 0x02, 0x64, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x73, 0x26,
+0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26, 0x64, 0x57, 0x00, 0x08,
+0x10, 0x00, 0xA2, 0xA3, 0xE8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xA6, 0xAF,
+0x20, 0x00, 0xA6, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xA7, 0xAF,
+0xFF, 0x56, 0x00, 0x0C, 0x1C, 0x00, 0xA5, 0xAF, 0x10, 0x00, 0xBF, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xA4, 0xAF, 0x10, 0x00, 0xA4, 0x27,
+0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xA5, 0xAF,
+0x28, 0x00, 0xA6, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x2C, 0x00, 0xA7, 0xAF,
+0x53, 0x21, 0x00, 0x0C, 0xA0, 0x00, 0x04, 0x24, 0x1F, 0x00, 0x40, 0x10,
+0x21, 0x80, 0x40, 0x00, 0x08, 0x00, 0x44, 0x94, 0x20, 0x00, 0xA5, 0x8F,
+0x02, 0x80, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00, 0x20, 0x00, 0x84, 0x24,
+0xFF, 0x56, 0x00, 0x0C, 0x24, 0x00, 0xA6, 0x27, 0x01, 0x00, 0x42, 0x24,
+0x13, 0x00, 0x03, 0x24, 0x81, 0x00, 0x44, 0x2C, 0x14, 0x00, 0x03, 0xAE,
+0x0A, 0x00, 0x80, 0x14, 0x0C, 0x00, 0x02, 0xAE, 0x9B, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x88, 0x88, 0x63, 0x34, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x34, 0x58, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x02, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x99, 0x99, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x99, 0x99, 0x63, 0x34,
+0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x3A, 0x58, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x02, 0x80, 0x06, 0x3C, 0x5C, 0xF5, 0xC5, 0x8C, 0x02, 0x80, 0x02, 0x3C,
+0x40, 0xF5, 0x42, 0x24, 0x03, 0x00, 0xA3, 0x30, 0x21, 0x18, 0x62, 0x00,
+0x00, 0x00, 0x64, 0x80, 0x01, 0x00, 0xA5, 0x24, 0x57, 0x58, 0x00, 0x0C,
+0x5C, 0xF5, 0xC5, 0xAC, 0x10, 0x00, 0xBF, 0x8F, 0x08, 0x00, 0x04, 0x24,
+0x57, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x00, 0x26, 0x04, 0x00,
+0x03, 0x26, 0x04, 0x00, 0x00, 0x00, 0x84, 0x48, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x04, 0x00, 0x03, 0x26, 0x04, 0x00,
+0xF7, 0xFF, 0x82, 0x24, 0x05, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x14,
+0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0x02, 0x24, 0x03, 0x00, 0x82, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x01, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00,
+0x00, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x44, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x42, 0x2C, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0xA4, 0x27,
+0x02, 0x80, 0x02, 0x3C, 0xCC, 0x5D, 0x50, 0xAC, 0x90, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x05, 0x3C,
+0x01, 0x00, 0x06, 0x24, 0x01, 0x80, 0x02, 0x3C, 0x04, 0x30, 0x86, 0x00,
+0xF1, 0x02, 0xA7, 0x34, 0xED, 0x02, 0xA4, 0x34, 0xF8, 0x61, 0x42, 0x24,
+0x18, 0x03, 0xA5, 0x34, 0x08, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xAC,
+0x00, 0x00, 0xE3, 0xA0, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0,
+0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0, 0x00, 0x00, 0x80, 0xA0,
+0x00, 0x00, 0x86, 0xA0, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0,
+0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xE0, 0xA0, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF,
+0xFF, 0xFF, 0x90, 0x30, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C,
+0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24,
+0x6A, 0x37, 0x62, 0x94, 0x10, 0x00, 0xA4, 0x27, 0x25, 0x80, 0x02, 0x02,
+0x25, 0xB0, 0x02, 0x3C, 0x1E, 0x03, 0x42, 0x34, 0x00, 0x00, 0x50, 0xA4,
+0x90, 0x40, 0x00, 0x0C, 0x6A, 0x37, 0x70, 0xA4, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0xFF, 0xFF, 0x90, 0x30,
+0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0x6A, 0x37, 0xA2, 0x94,
+0x78, 0x37, 0xA3, 0x94, 0x27, 0x80, 0x10, 0x00, 0x10, 0x00, 0xA4, 0x27,
+0x24, 0x18, 0x03, 0x02, 0x24, 0x80, 0x02, 0x02, 0x25, 0xB0, 0x02, 0x3C,
+0x1E, 0x03, 0x42, 0x34, 0x78, 0x37, 0xA3, 0xA4, 0x00, 0x00, 0x50, 0xA4,
+0x90, 0x40, 0x00, 0x0C, 0x6A, 0x37, 0xB0, 0xA4, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xC8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xBE, 0xAF, 0x2C, 0x00, 0xB7, 0xAF,
+0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF,
+0x0A, 0x00, 0x67, 0x34, 0x00, 0x00, 0xE2, 0x90, 0xFF, 0xFF, 0xB2, 0x30,
+0x21, 0x98, 0xC0, 0x00, 0xFF, 0x00, 0x91, 0x30, 0x20, 0x00, 0x40, 0x12,
+0xFF, 0x00, 0x50, 0x30, 0x21, 0xA0, 0xE0, 0x00, 0x0C, 0x00, 0x77, 0x34,
+0x0B, 0x00, 0x76, 0x34, 0x21, 0xF0, 0xE0, 0x00, 0xC0, 0xFF, 0x15, 0x24,
+0x25, 0x10, 0x15, 0x02, 0xFF, 0x00, 0x50, 0x30, 0x00, 0x00, 0xD1, 0xA2,
+0x00, 0x00, 0x90, 0xA2, 0x00, 0x00, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x50, 0x30, 0xC0, 0x00, 0x03, 0x32, 0x07, 0x00, 0x60, 0x10,
+0x21, 0x20, 0xC0, 0x03, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0x50, 0x30, 0xC0, 0x00, 0x03, 0x32, 0xFB, 0xFF, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x8E, 0x04, 0x00, 0x23, 0x26,
+0x64, 0x00, 0x04, 0x24, 0x00, 0x00, 0x62, 0xAE, 0x2C, 0x1F, 0x00, 0x0C,
+0xFF, 0x00, 0x71, 0x30, 0xFC, 0xFF, 0x42, 0x26, 0xFF, 0xFF, 0x52, 0x30,
+0xE7, 0xFF, 0x40, 0x16, 0x04, 0x00, 0x73, 0x26, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x06, 0x3C,
+0x31, 0x00, 0xC2, 0x34, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x00, 0x44, 0xA0,
+0x32, 0x00, 0xC7, 0x34, 0x00, 0x00, 0xE3, 0x90, 0xFC, 0xFF, 0x02, 0x24,
+0x02, 0x22, 0x04, 0x00, 0x24, 0x18, 0x62, 0x00, 0x03, 0x00, 0x84, 0x30,
+0x25, 0x20, 0x83, 0x00, 0x33, 0x00, 0xC6, 0x34, 0x72, 0x00, 0x02, 0x24,
+0x00, 0x00, 0xE4, 0xA0, 0x00, 0x00, 0xC2, 0xA0, 0x00, 0x00, 0xC3, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x05, 0x00, 0x61, 0x04, 0x21, 0x10, 0x00, 0x00, 0x23, 0x59, 0x00, 0x08,
+0x25, 0xB0, 0x02, 0x3C, 0x11, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC3, 0x90, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x61, 0x04,
+0x64, 0x00, 0x44, 0x2C, 0x64, 0x00, 0x44, 0x2C, 0x07, 0x00, 0x80, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x30, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x43, 0x90, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0xA3, 0xA0, 0xFF, 0xFF, 0x02, 0x24, 0x00, 0x00, 0xA2, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x25, 0xB0, 0x06, 0x3C,
+0x31, 0x00, 0xC2, 0x34, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x00, 0x44, 0xA0,
+0x32, 0x00, 0xC3, 0x34, 0x00, 0x00, 0x62, 0x90, 0x02, 0x22, 0x04, 0x00,
+0x03, 0x00, 0x84, 0x30, 0x25, 0x20, 0x82, 0x00, 0x00, 0x00, 0x64, 0xA0,
+0x33, 0x00, 0xC7, 0x34, 0xFF, 0x00, 0xA5, 0x30, 0x30, 0x00, 0xC6, 0x34,
+0xF2, 0xFF, 0x03, 0x24, 0x00, 0x00, 0xC5, 0xA0, 0x00, 0x00, 0xE3, 0xA0,
+0x00, 0x00, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00,
+0x03, 0x16, 0x02, 0x00, 0x03, 0x00, 0x40, 0x04, 0x21, 0x20, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x48, 0x59, 0x00, 0x08,
+0x21, 0x30, 0xE0, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC3, 0x90, 0x01, 0x00, 0x82, 0x24, 0xFF, 0x00, 0x44, 0x30,
+0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x60, 0x04,
+0x64, 0x00, 0x82, 0x2C, 0x64, 0x00, 0x82, 0x2C, 0xF1, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x00, 0xB0, 0xAF,
+0xF8, 0x02, 0x45, 0x34, 0x25, 0xB0, 0x10, 0x3C, 0xFF, 0x00, 0x83, 0x30,
+0x01, 0x00, 0x02, 0x24, 0x1C, 0x00, 0xBF, 0xAF, 0x03, 0x00, 0x06, 0x36,
+0x0A, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0x90,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0xFE, 0xFF, 0x03, 0x24,
+0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xA2, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x20, 0x00, 0x43, 0x34,
+0x20, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC3, 0xA0, 0x2C, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x36, 0x00, 0x00, 0x82, 0x90, 0xFE, 0xFF, 0x03, 0x24,
+0xF8, 0x02, 0x06, 0x36, 0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA0,
+0x00, 0x00, 0xC3, 0x90, 0x10, 0x00, 0xA5, 0x27, 0x21, 0x20, 0x00, 0x00,
+0x03, 0x00, 0x63, 0x34, 0x00, 0x00, 0xC3, 0xA0, 0xFF, 0x58, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xFF, 0x00, 0x84, 0x30,
+0x21, 0x38, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24,
+0x07, 0x10, 0xA4, 0x00, 0x01, 0x00, 0x42, 0x30, 0xFF, 0x00, 0x65, 0x30,
+0x01, 0x00, 0xE6, 0x24, 0x02, 0x00, 0x40, 0x14, 0x04, 0x00, 0xA3, 0x2C,
+0xFF, 0x00, 0xC7, 0x30, 0xF7, 0xFF, 0x60, 0x14, 0x21, 0x10, 0xE0, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x8C, 0x30,
+0x21, 0x48, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0x40, 0x10, 0x07, 0x00,
+0xFF, 0x00, 0x42, 0x30, 0x21, 0x50, 0x46, 0x00, 0x01, 0x00, 0xE3, 0x24,
+0x07, 0x10, 0xEC, 0x00, 0x01, 0x00, 0x42, 0x30, 0xFF, 0x00, 0x67, 0x30,
+0x21, 0x58, 0x25, 0x01, 0x01, 0x00, 0x24, 0x25, 0x09, 0x00, 0x40, 0x14,
+0x04, 0x00, 0xE8, 0x2C, 0x00, 0x00, 0x63, 0x91, 0xFF, 0x00, 0x89, 0x30,
+0x21, 0x20, 0x25, 0x01, 0x00, 0x00, 0x43, 0xA1, 0x00, 0x00, 0x83, 0x90,
+0x01, 0x00, 0x22, 0x25, 0xFF, 0x00, 0x49, 0x30, 0x01, 0x00, 0x43, 0xA1,
+0xED, 0xFF, 0x00, 0x15, 0x40, 0x10, 0x07, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF,
+0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF,
+0x01, 0x00, 0x12, 0x24, 0x21, 0x80, 0x00, 0x00, 0xC5, 0x59, 0x00, 0x08,
+0xFF, 0x00, 0x11, 0x24, 0xFF, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x40, 0x10, 0x00, 0x02, 0x03, 0x2E, 0x0F, 0x00, 0x60, 0x10,
+0x21, 0x10, 0x00, 0x02, 0x10, 0x00, 0xA2, 0x93, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x51, 0x10, 0x0F, 0x00, 0x44, 0x30, 0x83, 0x59, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x50, 0x00,
+0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x50, 0x30, 0x21, 0x20, 0x00, 0x02,
+0xEE, 0xFF, 0x40, 0x16, 0x10, 0x00, 0xA5, 0x27, 0x21, 0x10, 0x00, 0x02,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0xB8, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF,
+0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF,
+0x24, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0xBF, 0xAF,
+0x40, 0x00, 0xBE, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x21, 0x98, 0xA0, 0x00,
+0xFF, 0x00, 0x96, 0x30, 0x01, 0x00, 0x10, 0x24, 0x01, 0x00, 0x17, 0x24,
+0x21, 0xA0, 0x00, 0x00, 0x21, 0x88, 0x00, 0x00, 0x21, 0xA8, 0x00, 0x00,
+0x04, 0x00, 0xA0, 0x10, 0x21, 0x18, 0x00, 0x00, 0x10, 0x00, 0xC2, 0x2E,
+0x0E, 0x00, 0x40, 0x14, 0x21, 0x20, 0xA0, 0x00, 0x44, 0x00, 0xBF, 0x8F,
+0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F,
+0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F,
+0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F,
+0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0x06, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24,
+0x18, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24, 0xE3, 0x54, 0x00, 0x0C,
+0x08, 0x00, 0x06, 0x24, 0x54, 0x59, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x04, 0x5A, 0x00, 0x08, 0x10, 0x00, 0xBE, 0x27, 0x1C, 0x00, 0x40, 0x14,
+0x21, 0x20, 0xA0, 0x02, 0x37, 0x00, 0xE0, 0x12, 0x00, 0x02, 0x22, 0x2E,
+0x35, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x32,
+0xF8, 0xFF, 0x40, 0x10, 0x20, 0x00, 0x02, 0x32, 0x21, 0x20, 0x20, 0x02,
+0xFF, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA5, 0x27, 0x2D, 0x00, 0x40, 0x10,
+0xFF, 0x00, 0x02, 0x24, 0x10, 0x00, 0xB0, 0x93, 0x00, 0x00, 0x00, 0x00,
+0x29, 0x00, 0x02, 0x12, 0x0F, 0x00, 0x15, 0x32, 0x83, 0x59, 0x00, 0x0C,
+0x21, 0x20, 0xA0, 0x02, 0x02, 0x81, 0x10, 0x00, 0x10, 0x00, 0x16, 0x12,
+0x21, 0xA0, 0x40, 0x00, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x51, 0x30, 0x00, 0x5A, 0x00, 0x08,
+0x01, 0x00, 0x10, 0x24, 0x18, 0x00, 0xA5, 0x27, 0x92, 0x59, 0x00, 0x0C,
+0x21, 0x30, 0x60, 0x02, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x51, 0x00,
+0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x51, 0x30, 0x00, 0x5A, 0x00, 0x08,
+0x01, 0x00, 0x10, 0x24, 0x40, 0x90, 0x02, 0x00, 0x10, 0x00, 0x40, 0x1A,
+0x21, 0x80, 0x00, 0x00, 0x21, 0x20, 0x30, 0x02, 0x01, 0x00, 0x84, 0x24,
+0xFF, 0xFF, 0x84, 0x30, 0xFF, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA5, 0x27,
+0x01, 0x00, 0x03, 0x26, 0x21, 0x20, 0xD0, 0x03, 0xFF, 0x00, 0x70, 0x30,
+0x04, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x12, 0x02, 0x10, 0x00, 0xA2, 0x93,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x82, 0xA0, 0xF3, 0xFF, 0x60, 0x14,
+0x21, 0x20, 0x30, 0x02, 0x00, 0x5A, 0x00, 0x08, 0x20, 0x00, 0x10, 0x24,
+0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0x63, 0x92,
+0xFF, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x03, 0x24, 0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F,
+0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F,
+0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F,
+0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x62, 0x92,
+0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x03, 0x24,
+0x02, 0x00, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xFF, 0x62, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xE8, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x03, 0x24, 0x04, 0x00, 0x63, 0x92,
+0x00, 0x00, 0x00, 0x00, 0xE3, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0x43, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x67, 0x92, 0x00, 0x00, 0x00, 0x00,
+0xDC, 0xFF, 0xE2, 0x14, 0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x62, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x47, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x3F, 0x5A, 0x00, 0x08, 0x01, 0x00, 0x03, 0x24, 0xC0, 0xFF, 0xBD, 0x27,
+0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
+0x21, 0xF0, 0xC0, 0x00, 0xFF, 0x00, 0xB6, 0x30, 0xFF, 0xFF, 0x95, 0x30,
+0xFF, 0x00, 0x05, 0x24, 0x10, 0x00, 0xA4, 0x27, 0x08, 0x00, 0x06, 0x24,
+0x34, 0x00, 0xB7, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x3C, 0x00, 0xBF, 0xAF,
+0x28, 0x00, 0xB4, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0xE3, 0x54, 0x00, 0x0C, 0x0F, 0x00, 0x17, 0x24,
+0x21, 0x98, 0x00, 0x00, 0x40, 0x10, 0x13, 0x00, 0xFF, 0x00, 0x52, 0x30,
+0x07, 0x10, 0x76, 0x02, 0x01, 0x00, 0x42, 0x30, 0x21, 0xA0, 0x5E, 0x02,
+0x21, 0x88, 0xA0, 0x02, 0x21, 0x20, 0xA0, 0x02, 0x13, 0x00, 0x40, 0x10,
+0x01, 0x00, 0xA3, 0x26, 0x01, 0x00, 0x62, 0x26, 0xFF, 0x00, 0x53, 0x30,
+0x04, 0x00, 0x63, 0x2E, 0xF4, 0xFF, 0x60, 0x14, 0x40, 0x10, 0x13, 0x00,
+0x21, 0x10, 0xE0, 0x02, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F,
+0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x85, 0x92, 0xFF, 0xFF, 0x75, 0x30,
+0x2C, 0x59, 0x00, 0x0C, 0x21, 0x80, 0xA0, 0x02, 0x01, 0x00, 0x85, 0x92,
+0x21, 0x20, 0xA0, 0x02, 0x01, 0x00, 0xA2, 0x26, 0x2C, 0x59, 0x00, 0x0C,
+0xFF, 0xFF, 0x55, 0x30, 0x10, 0x00, 0xA3, 0x27, 0x21, 0x90, 0x72, 0x00,
+0x21, 0x20, 0x20, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x40, 0x02,
+0x21, 0x20, 0x00, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x45, 0x26,
+0x00, 0x00, 0x84, 0x92, 0x00, 0x00, 0x42, 0x92, 0x01, 0x00, 0x03, 0x24,
+0x04, 0x18, 0x63, 0x02, 0x03, 0x00, 0x82, 0x10, 0x27, 0x30, 0x03, 0x00,
+0x87, 0x5A, 0x00, 0x08, 0x24, 0xB8, 0xD7, 0x00, 0x01, 0x00, 0x83, 0x92,
+0x01, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0x62, 0x10,
+0x01, 0x00, 0x62, 0x26, 0x88, 0x5A, 0x00, 0x08, 0x24, 0xB8, 0xD7, 0x00,
+0x98, 0xFF, 0xBD, 0x27, 0x50, 0x00, 0xB4, 0xAF, 0xFF, 0x00, 0x94, 0x30,
+0x01, 0x00, 0x04, 0x24, 0x64, 0x00, 0xBF, 0xAF, 0x60, 0x00, 0xBE, 0xAF,
+0x5C, 0x00, 0xB7, 0xAF, 0x58, 0x00, 0xB6, 0xAF, 0x4C, 0x00, 0xB3, 0xAF,
+0x48, 0x00, 0xB2, 0xAF, 0x44, 0x00, 0xB1, 0xAF, 0x21, 0x98, 0xC0, 0x00,
+0xFF, 0x00, 0xB1, 0x30, 0x54, 0x00, 0xB5, 0xAF, 0x54, 0x59, 0x00, 0x0C,
+0x40, 0x00, 0xB0, 0xAF, 0xAC, 0x59, 0x00, 0x0C, 0x01, 0x00, 0x16, 0x24,
+0x21, 0x18, 0x40, 0x00, 0xFF, 0x01, 0x42, 0x2C, 0x01, 0x00, 0x17, 0x24,
+0x01, 0x00, 0x1E, 0x24, 0x21, 0x90, 0x00, 0x00, 0x0E, 0x00, 0x40, 0x14,
+0x21, 0x20, 0x00, 0x00, 0x64, 0x00, 0xBF, 0x8F, 0x60, 0x00, 0xBE, 0x8F,
+0x5C, 0x00, 0xB7, 0x8F, 0x58, 0x00, 0xB6, 0x8F, 0x54, 0x00, 0xB5, 0x8F,
+0x50, 0x00, 0xB4, 0x8F, 0x4C, 0x00, 0xB3, 0x8F, 0x48, 0x00, 0xB2, 0x8F,
+0x44, 0x00, 0xB1, 0x8F, 0x40, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x68, 0x00, 0xBD, 0x27, 0xFF, 0x01, 0x02, 0x24,
+0x23, 0x10, 0x43, 0x00, 0x1A, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24,
+0x08, 0x00, 0x06, 0x24, 0xFF, 0xFF, 0x50, 0x30, 0x18, 0x00, 0xB4, 0xA3,
+0xE3, 0x54, 0x00, 0x0C, 0x19, 0x00, 0xB1, 0xA3, 0x21, 0x20, 0x20, 0x02,
+0x21, 0x28, 0x60, 0x02, 0x92, 0x59, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27,
+0x19, 0x00, 0xA4, 0x93, 0x83, 0x59, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x21, 0xA8, 0x40, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x2B, 0x10, 0x02, 0x02,
+0xDF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x09, 0x00, 0xC2, 0x12, 0x20, 0x00, 0x02, 0x24, 0x22, 0x00, 0xC2, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x3B, 0x00, 0xE0, 0x12, 0x00, 0x02, 0x42, 0x2E,
+0x39, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0xF9, 0xFF, 0xC2, 0x16,
+0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x40, 0x02, 0x10, 0x00, 0xA5, 0x27,
+0xFF, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x24, 0x41, 0x00, 0x40, 0x10,
+0xFF, 0x00, 0x02, 0x24, 0x10, 0x00, 0xA5, 0x93, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0xA4, 0x30, 0x3C, 0x00, 0x82, 0x10, 0x0F, 0x00, 0xA3, 0x30,
+0x02, 0x11, 0x04, 0x00, 0x21, 0x20, 0x60, 0x00, 0x29, 0x00, 0xA3, 0xA3,
+0x28, 0x00, 0xA2, 0xA3, 0x83, 0x59, 0x00, 0x0C, 0x11, 0x00, 0xA5, 0xA3,
+0x21, 0x80, 0x40, 0x00, 0x28, 0x00, 0xA3, 0x93, 0x18, 0x00, 0xA2, 0x93,
+0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x62, 0x10, 0x40, 0x10, 0x10, 0x00,
+0x21, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x24, 0xF9, 0x5A, 0x00, 0x08,
+0xFF, 0xFF, 0x52, 0x30, 0x19, 0x00, 0xA5, 0x93, 0x01, 0x00, 0x44, 0x26,
+0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27,
+0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x43, 0x30, 0x0F, 0x00, 0x02, 0x24,
+0x12, 0x00, 0x62, 0x10, 0x40, 0x10, 0x15, 0x00, 0x21, 0x10, 0x52, 0x00,
+0x01, 0x00, 0x42, 0x24, 0x21, 0x20, 0xA0, 0x00, 0xFF, 0xFF, 0x52, 0x30,
+0x18, 0x00, 0xB4, 0xA3, 0x83, 0x59, 0x00, 0x0C, 0x19, 0x00, 0xA5, 0xA3,
+0x21, 0xA8, 0x40, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xCC, 0xDF, 0x62, 0x8C,
+0x02, 0x80, 0x04, 0x3C, 0x01, 0x00, 0x16, 0x24, 0x01, 0x00, 0x42, 0x24,
+0x04, 0x00, 0x43, 0x28, 0xC6, 0xFF, 0x60, 0x14, 0xCC, 0xDF, 0x82, 0xAC,
+0x21, 0xF0, 0x00, 0x00, 0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00,
+0x21, 0x20, 0xC0, 0x03, 0x64, 0x00, 0xBF, 0x8F, 0x60, 0x00, 0xBE, 0x8F,
+0x5C, 0x00, 0xB7, 0x8F, 0x58, 0x00, 0xB6, 0x8F, 0x54, 0x00, 0xB5, 0x8F,
+0x50, 0x00, 0xB4, 0x8F, 0x4C, 0x00, 0xB3, 0x8F, 0x48, 0x00, 0xB2, 0x8F,
+0x44, 0x00, 0xB1, 0x8F, 0x40, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x68, 0x00, 0xBD, 0x27, 0xAC, 0x59, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x03, 0x24, 0x23, 0x18, 0x62, 0x00,
+0xFF, 0xFF, 0x70, 0x30, 0xFF, 0xFF, 0xA2, 0x32, 0x2B, 0x10, 0x02, 0x02,
+0xE7, 0xFF, 0x40, 0x14, 0x21, 0x20, 0x40, 0x02, 0x18, 0x00, 0xB0, 0x93,
+0x19, 0x00, 0xA2, 0x93, 0x00, 0x81, 0x10, 0x00, 0x25, 0x80, 0x02, 0x02,
+0xFF, 0x00, 0x10, 0x32, 0x2C, 0x59, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02,
+0x21, 0x20, 0x40, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x11, 0x00, 0xA5, 0x27,
+0x11, 0x00, 0xA3, 0x93, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x64, 0x30,
+0x9D, 0xFF, 0x90, 0x10, 0x20, 0x00, 0x16, 0x24, 0xFF, 0x00, 0x02, 0x24,
+0xCD, 0xFF, 0x82, 0x10, 0x0F, 0x00, 0x63, 0x30, 0x02, 0x11, 0x04, 0x00,
+0x21, 0x20, 0x60, 0x00, 0x29, 0x00, 0xA3, 0xA3, 0x83, 0x59, 0x00, 0x0C,
+0x28, 0x00, 0xA2, 0xA3, 0x38, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24,
+0x08, 0x00, 0x06, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00,
+0x28, 0x00, 0xA4, 0x93, 0xCF, 0x59, 0x00, 0x0C, 0x38, 0x00, 0xA5, 0x27,
+0x1F, 0x00, 0x40, 0x14, 0x01, 0x00, 0x44, 0x26, 0x40, 0x10, 0x10, 0x00,
+0x21, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x24, 0x2C, 0x5B, 0x00, 0x08,
+0xFF, 0xFF, 0x52, 0x30, 0x40, 0x88, 0x10, 0x00, 0x27, 0x00, 0x20, 0x1A,
+0x21, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x16, 0x24, 0x21, 0x20, 0x50, 0x02,
+0x01, 0x00, 0x84, 0x24, 0xFF, 0xFF, 0x84, 0x30, 0xFF, 0x58, 0x00, 0x0C,
+0x10, 0x00, 0xA5, 0x27, 0x01, 0x00, 0x03, 0x26, 0xFF, 0x00, 0x70, 0x30,
+0x05, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x11, 0x02, 0x10, 0x00, 0xA2, 0x93,
+0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x56, 0x00, 0x0B, 0x98, 0x02, 0x00,
+0xF3, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x50, 0x02, 0x15, 0x00, 0x60, 0x16,
+0x21, 0x10, 0x32, 0x02, 0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x52, 0x30,
+0xF9, 0x5A, 0x00, 0x08, 0x01, 0x00, 0x16, 0x24, 0x29, 0x00, 0xA5, 0x93,
+0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27,
+0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x43, 0x30, 0x0F, 0x00, 0x02, 0x24,
+0xDB, 0xFF, 0x62, 0x10, 0x40, 0x10, 0x10, 0x00, 0x28, 0x00, 0xA4, 0x93,
+0xB9, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27, 0xAC, 0x59, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x2C, 0x5B, 0x00, 0x08, 0x21, 0x90, 0x40, 0x00,
+0x19, 0x00, 0xA3, 0x93, 0x29, 0x00, 0xA6, 0x93, 0x0F, 0x00, 0x13, 0x24,
+0x0E, 0x00, 0x10, 0x24, 0x25, 0x18, 0x66, 0x00, 0x01, 0x00, 0x62, 0x30,
+0x0A, 0x98, 0x02, 0x02, 0x02, 0x00, 0x64, 0x30, 0xFD, 0x00, 0x62, 0x32,
+0x0A, 0x98, 0x44, 0x00, 0x04, 0x00, 0x65, 0x30, 0xFB, 0x00, 0x62, 0x32,
+0x0A, 0x98, 0x45, 0x00, 0x08, 0x00, 0x63, 0x30, 0xF7, 0x00, 0x62, 0x32,
+0x0A, 0x98, 0x43, 0x00, 0x0F, 0x00, 0x64, 0x32, 0x0F, 0x00, 0x16, 0x24,
+0x25, 0x00, 0x96, 0x10, 0x21, 0x28, 0xC0, 0x00, 0x01, 0x00, 0x44, 0x26,
+0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27,
+0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x03, 0x00, 0x56, 0x10,
+0x21, 0x20, 0x80, 0x02, 0xB9, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27,
+0x19, 0x00, 0xA5, 0x93, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x65, 0x02,
+0x01, 0x00, 0x42, 0x30, 0x0A, 0x80, 0xC2, 0x02, 0x26, 0x18, 0x65, 0x02,
+0x02, 0x00, 0x63, 0x30, 0xFD, 0x00, 0x04, 0x32, 0x0B, 0x80, 0x83, 0x00,
+0x26, 0x10, 0x65, 0x02, 0x04, 0x00, 0x42, 0x30, 0xFB, 0x00, 0x03, 0x32,
+0x0B, 0x80, 0x62, 0x00, 0x26, 0x28, 0x65, 0x02, 0x08, 0x00, 0xA5, 0x30,
+0xF7, 0x00, 0x02, 0x32, 0x0B, 0x80, 0x45, 0x00, 0x0F, 0x00, 0x03, 0x32,
+0x0D, 0x00, 0x76, 0x10, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x59, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x19, 0x00, 0xB0, 0xA3,
+0x2C, 0x5B, 0x00, 0x08, 0x18, 0x00, 0xB4, 0xA3, 0x21, 0x10, 0x32, 0x02,
+0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x52, 0x30, 0x01, 0x00, 0x16, 0x24,
+0xF9, 0x5A, 0x00, 0x08, 0x18, 0x00, 0xB4, 0xA3, 0x2C, 0x5B, 0x00, 0x08,
+0x21, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x85, 0xAC, 0x21, 0x10, 0x00, 0x00,
+0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x06, 0x00, 0x43, 0x2C,
+0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA4,
+0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xA5, 0x30,
+0x00, 0x00, 0x85, 0xA0, 0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24,
+0xFF, 0x00, 0x42, 0x30, 0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x82, 0x8C, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x82, 0x94, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x42, 0x30,
+0x00, 0x00, 0x82, 0x90, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0x00, 0x42, 0x30,
+0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x85, 0xAC,
+0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x21, 0x20, 0x82, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA4,
+0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x21, 0x20, 0x82, 0x00, 0xFF, 0x00, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA0,
+0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C,
+0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x82, 0x8C, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00,
+0x00, 0x00, 0x82, 0x94, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x42, 0x30,
+0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x82, 0x90,
+0x08, 0x00, 0xE0, 0x03, 0xFF, 0x00, 0x42, 0x30, 0x01, 0x80, 0x02, 0x3C,
+0x25, 0xB0, 0x03, 0x3C, 0xD4, 0x70, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34,
+0x00, 0x00, 0x62, 0xAC, 0x00, 0x00, 0x83, 0x90, 0x30, 0x00, 0x02, 0x24,
+0x05, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x00, 0x31, 0x00, 0x02, 0x24,
+0x02, 0x00, 0x62, 0x10, 0x01, 0x00, 0x04, 0x24, 0x07, 0x00, 0x04, 0x24,
+0x7E, 0x58, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x3C,
+0x25, 0xB0, 0x03, 0x3C, 0x10, 0x71, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34,
+0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xFC, 0x5C, 0x80, 0xAC, 0x42, 0xB0, 0x02, 0x3C, 0x03, 0x00, 0x47, 0x34,
+0x00, 0x00, 0xE3, 0x90, 0xFF, 0x00, 0x84, 0x30, 0x04, 0x00, 0x84, 0x24,
+0xFF, 0x00, 0x65, 0x30, 0x01, 0x00, 0x02, 0x24, 0x04, 0x30, 0x82, 0x00,
+0x07, 0x18, 0x85, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0xE8, 0x03, 0x42, 0x34,
+0x01, 0x00, 0x63, 0x30, 0x21, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x45, 0xA0,
+0x02, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x24, 0x10, 0x85, 0x00, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF,
+0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0xD0, 0xDF, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x02, 0xAE,
+0x04, 0x00, 0x50, 0xAC, 0x00, 0x00, 0x70, 0xAC, 0x04, 0x00, 0x03, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00,
+0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27,
+0x04, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x02, 0x8E, 0x10, 0x00, 0xA4, 0x27,
+0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE,
+0x90, 0x40, 0x00, 0x0C, 0x04, 0x00, 0x10, 0xAE, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x1F, 0xF7, 0x00, 0x6A, 0x82, 0x34, 0x4C, 0xEC, 0x82, 0x34, 0x8C, 0x32,
+0x89, 0xE2, 0x48, 0x32, 0x89, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5,
+0x68, 0x9A, 0x01, 0xF6, 0x01, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x04, 0xF5,
+0x68, 0xDA, 0x20, 0xE8, 0x00, 0x65, 0x00, 0x00, 0x1F, 0xF7, 0x00, 0x6A,
+0x82, 0x34, 0x4C, 0xEC, 0x82, 0x34, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32,
+0x89, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, 0x68, 0x9A, 0x01, 0xF6,
+0x01, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x00, 0xF2, 0x00, 0x6C, 0x8D, 0xEB,
+0x04, 0xF5, 0x68, 0xDA, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x6B, 0x6C, 0xED,
+0x04, 0x5D, 0x6C, 0xEC, 0x69, 0x60, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0xEF, 0x4A, 0x6C, 0xEA, 0x02, 0x5A,
+0x0C, 0x60, 0x02, 0x74, 0x38, 0x60, 0x03, 0x54, 0x1D, 0x61, 0x03, 0x74,
+0x2C, 0x60, 0x04, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xE8,
+0xFF, 0x4A, 0x02, 0x74, 0x3D, 0x60, 0x03, 0x54, 0x18, 0x61, 0x03, 0x74,
+0xF4, 0x61, 0x01, 0x75, 0x43, 0x60, 0x02, 0x55, 0x31, 0x61, 0x02, 0x75,
+0x42, 0x60, 0x03, 0x75, 0xEC, 0x61, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32,
+0x1E, 0xF0, 0x00, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x01, 0x74, 0xE3, 0x61,
+0x02, 0xF0, 0x0F, 0x6A, 0x40, 0x32, 0x20, 0xE8, 0x40, 0x32, 0x01, 0x74,
+0xDC, 0x61, 0x03, 0xF7, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x10, 0xF0,
+0x00, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x01, 0x75, 0x1B, 0x60, 0x02, 0x55,
+0x08, 0x61, 0x02, 0x75, 0x29, 0x60, 0x03, 0x75, 0xCC, 0x61, 0x02, 0xF0,
+0x10, 0x6A, 0x40, 0x32, 0xDE, 0x17, 0xC7, 0x2D, 0x02, 0xF0, 0x10, 0x6A,
+0x40, 0x32, 0x40, 0x32, 0x1E, 0xF0, 0x15, 0x4A, 0x20, 0xE8, 0x00, 0x65,
+0xBE, 0x2D, 0x02, 0xF0, 0x00, 0x6A, 0xF7, 0x17, 0x03, 0xF7, 0x10, 0x6A,
+0x40, 0x32, 0xCD, 0x17, 0x02, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32,
+0x1E, 0xF0, 0x10, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x02, 0xF0, 0x00, 0x6A,
+0xF8, 0x17, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x1E, 0xF0, 0x05, 0x4A,
+0x20, 0xE8, 0x00, 0x65, 0x02, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0xF7, 0x17,
+0xFC, 0x63, 0x06, 0xD0, 0x8C, 0x30, 0x81, 0xE0, 0x08, 0x30, 0x81, 0xE0,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A,
+0x08, 0x30, 0x41, 0xE0, 0xC9, 0xF7, 0x1B, 0x6D, 0x04, 0xF0, 0x00, 0x6A,
+0x40, 0x32, 0xAB, 0xED, 0x40, 0x32, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4A,
+0x04, 0xF5, 0x40, 0xD8, 0x07, 0x62, 0x80, 0xF1, 0x44, 0x45, 0x40, 0x9A,
+0x08, 0x6B, 0x6B, 0xEB, 0x04, 0xF5, 0x44, 0xD8, 0x04, 0xF5, 0x48, 0x98,
+0xC4, 0x67, 0x6C, 0xEA, 0xFF, 0x6B, 0x02, 0x4B, 0x6B, 0xEB, 0x6C, 0xEA,
+0x02, 0xF0, 0x01, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x04, 0xF5, 0x48, 0xD8,
+0x04, 0xD5, 0x00, 0x18, 0xA5, 0x21, 0x05, 0xD6, 0x04, 0x95, 0x05, 0x96,
+0x04, 0xF5, 0x4A, 0xA0, 0x60, 0xF1, 0x00, 0x4D, 0xB9, 0xE6, 0x40, 0xC6,
+0x00, 0x6A, 0xC4, 0xF4, 0x58, 0xD8, 0xC4, 0xF4, 0x5C, 0xD8, 0xE4, 0xF4,
+0x40, 0xD8, 0xE4, 0xF4, 0x44, 0xD8, 0xE4, 0xF4, 0x48, 0xD8, 0xE4, 0xF4,
+0x4C, 0xD8, 0xE4, 0xF4, 0x50, 0xD8, 0xE4, 0xF4, 0x54, 0xD8, 0x07, 0x97,
+0x06, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0xFF, 0x63, 0x00, 0xD0,
+0x04, 0x67, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0xFF, 0x6F,
+0x80, 0x34, 0xA0, 0xF1, 0x4F, 0x44, 0xEC, 0xEE, 0x01, 0xD1, 0x59, 0xE6,
+0x40, 0xA6, 0xEC, 0xED, 0xC7, 0x67, 0x4C, 0xEE, 0xAC, 0x32, 0xA9, 0xE2,
+0x48, 0x32, 0xA9, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, 0x48, 0x9A,
+0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4C, 0x6C, 0xEA, 0xEC, 0xEA, 0x48, 0x32,
+0xEC, 0xE8, 0x89, 0xE2, 0x00, 0x6D, 0x80, 0x9A, 0x0D, 0x65, 0x70, 0x67,
+0x2E, 0x26, 0x32, 0x24, 0x65, 0x67, 0x01, 0x69, 0x51, 0x67, 0x44, 0xEB,
+0x8C, 0xEA, 0x36, 0x2A, 0x01, 0x4B, 0xEC, 0xEB, 0x1D, 0x5B, 0xF8, 0x61,
+0x6F, 0x40, 0xFF, 0x6A, 0x4C, 0xEB, 0xE8, 0x67, 0xE3, 0xEB, 0x10, 0x61,
+0x01, 0x69, 0xE2, 0x67, 0x51, 0x67, 0x44, 0xEB, 0x8C, 0xEA, 0x05, 0x22,
+0xCA, 0xED, 0x26, 0x60, 0x01, 0x4D, 0xEC, 0xED, 0x03, 0x67, 0xFF, 0x4B,
+0xEC, 0xEB, 0x48, 0x67, 0x43, 0xEB, 0xF2, 0x60, 0xC3, 0xED, 0x70, 0x67,
+0x0A, 0x60, 0x68, 0x67, 0xAB, 0xE6, 0x42, 0xEB, 0x00, 0x6B, 0x05, 0x61,
+0xE8, 0x67, 0xCB, 0xE7, 0xAD, 0xE2, 0xFF, 0x6A, 0x4C, 0xEB, 0x01, 0x91,
+0x00, 0x90, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63, 0xC3, 0xE8, 0x65, 0x67,
+0xF8, 0x61, 0xCF, 0xE0, 0x01, 0x91, 0x00, 0x90, 0xEC, 0xEB, 0x43, 0x67,
+0x20, 0xE8, 0x01, 0x63, 0x0B, 0x65, 0xCC, 0x17, 0x70, 0x67, 0xED, 0x17,
+0xC9, 0xF7, 0x1B, 0x6E, 0xCB, 0xEE, 0xC0, 0x36, 0xFF, 0x6F, 0xC0, 0x36,
+0xEC, 0xEC, 0xFF, 0x63, 0x60, 0xF1, 0x40, 0x46, 0x01, 0xD1, 0x00, 0xD0,
+0x49, 0xE4, 0x40, 0xA2, 0x07, 0x67, 0xEC, 0xED, 0x4C, 0xE8, 0xA0, 0xF1,
+0x4F, 0x46, 0x55, 0xE5, 0x40, 0xA5, 0x27, 0x67, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x4C, 0xE9, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32,
+0x89, 0xE2, 0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5,
+0x48, 0x9A, 0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4E, 0x6C, 0xEA, 0xEC, 0xEA,
+0x48, 0x32, 0xC9, 0xE2, 0x00, 0x6D, 0x80, 0x9A, 0x2D, 0x65, 0x70, 0x67,
+0x30, 0x21, 0x34, 0x24, 0x01, 0x6A, 0x65, 0x67, 0x0A, 0x65, 0xC7, 0x67,
+0x48, 0x67, 0x44, 0xEB, 0x8C, 0xEA, 0x36, 0x2A, 0x01, 0x4B, 0xCC, 0xEB,
+0x1D, 0x5B, 0xF8, 0x61, 0x6F, 0x40, 0xFF, 0x6A, 0x4C, 0xEB, 0xC9, 0x67,
+0xC3, 0xEB, 0x10, 0x61, 0x01, 0x6F, 0xC2, 0x67, 0x47, 0x67, 0x44, 0xEB,
+0x8C, 0xEA, 0x05, 0x22, 0x2A, 0xED, 0x26, 0x60, 0x01, 0x4D, 0xCC, 0xED,
+0x03, 0x67, 0xFF, 0x4B, 0xCC, 0xEB, 0x49, 0x67, 0x43, 0xEB, 0xF2, 0x60,
+0x23, 0xED, 0x70, 0x67, 0x0A, 0x60, 0x69, 0x67, 0xAB, 0xE1, 0x42, 0xEB,
+0x00, 0x6B, 0x05, 0x61, 0xC9, 0x67, 0x2B, 0xE6, 0xAD, 0xE2, 0xFF, 0x6A,
+0x4C, 0xEB, 0x01, 0x91, 0x00, 0x90, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63,
+0x23, 0xE8, 0x65, 0x67, 0xF8, 0x61, 0x2F, 0xE0, 0x01, 0x91, 0x00, 0x90,
+0xEC, 0xEB, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63, 0x2B, 0x65, 0xCC, 0x17,
+0x70, 0x67, 0xED, 0x17, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36,
+0xFB, 0x63, 0x00, 0x6D, 0x63, 0xF3, 0x00, 0x4E, 0x07, 0xD1, 0x06, 0xD0,
+0x08, 0x62, 0x05, 0x67, 0x26, 0x67, 0x85, 0x67, 0x04, 0xD5, 0x00, 0x18,
+0xDB, 0x5C, 0x05, 0xD6, 0x04, 0xF5, 0x4A, 0xA1, 0xFF, 0x6B, 0x05, 0x96,
+0x6C, 0xEA, 0x48, 0x32, 0xC9, 0xE2, 0xC0, 0xF5, 0x74, 0x9A, 0x60, 0xF5,
+0x40, 0x9A, 0x4D, 0xE3, 0x66, 0x33, 0xC4, 0xF4, 0x74, 0xD9, 0x04, 0x95,
+0x00, 0x6B, 0x69, 0xE1, 0x01, 0x4B, 0x1D, 0x53, 0x04, 0xF5, 0x0C, 0xC2,
+0x24, 0xF5, 0x09, 0xC2, 0x44, 0xF5, 0x06, 0xC2, 0xF6, 0x61, 0x00, 0x6A,
+0x01, 0x4D, 0x64, 0xF5, 0x44, 0xD9, 0x20, 0x55, 0x7F, 0x49, 0x15, 0x49,
+0xD8, 0x61, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63,
+0xF8, 0x63, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x07, 0xD2,
+0x0E, 0x62, 0x0D, 0xD1, 0x0C, 0xD0, 0x63, 0xF3, 0x00, 0x4A, 0x27, 0xF1,
+0x44, 0x9A, 0xFF, 0x6B, 0x6C, 0xEC, 0x6C, 0x65, 0xFF, 0xF7, 0x1F, 0x72,
+0x00, 0x6C, 0x05, 0xD4, 0x01, 0x61, 0x05, 0xD3, 0x07, 0x93, 0xFF, 0xF7,
+0x1F, 0x6A, 0x8B, 0x67, 0x63, 0xF3, 0x00, 0x4B, 0x27, 0xF1, 0x44, 0xDB,
+0x00, 0x6A, 0x04, 0xD2, 0x00, 0xF1, 0x18, 0x24, 0x10, 0xF0, 0x02, 0x6D,
+0x00, 0xF4, 0xA0, 0x35, 0x22, 0x67, 0xBC, 0xF3, 0x0C, 0x4D, 0xFF, 0x6E,
+0x00, 0xF5, 0x84, 0x43, 0x05, 0x10, 0x01, 0x49, 0x1D, 0x51, 0x60, 0xC4,
+0x01, 0x4C, 0x0B, 0x60, 0xA9, 0xE1, 0x60, 0xA2, 0x46, 0x67, 0x6C, 0xEA,
+0xF6, 0x22, 0x01, 0x49, 0x4D, 0x43, 0x1D, 0x51, 0x40, 0xC4, 0x01, 0x4C,
+0xF5, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4,
+0x80, 0x34, 0x00, 0x69, 0x63, 0xF3, 0x00, 0x4A, 0x5C, 0xF1, 0x04, 0x4B,
+0xDC, 0xF0, 0x0C, 0x4C, 0x0A, 0x65, 0x4B, 0x65, 0x2C, 0x65, 0x11, 0x67,
+0x48, 0x67, 0x6A, 0x67, 0x00, 0x6D, 0x5D, 0xE0, 0x79, 0xE0, 0xAD, 0xE6,
+0x40, 0xA3, 0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0,
+0x51, 0xA3, 0x05, 0x55, 0x20, 0xF4, 0x59, 0xC4, 0xF4, 0x61, 0x48, 0x67,
+0x51, 0xE1, 0x49, 0x67, 0x4D, 0xE1, 0x40, 0xA3, 0x01, 0x49, 0x1D, 0x51,
+0xC0, 0xF4, 0x4A, 0xC4, 0x5D, 0xA3, 0x05, 0x48, 0xE0, 0xF4, 0x47, 0xC4,
+0xE1, 0x61, 0x6B, 0x67, 0x00, 0xF1, 0x0A, 0x23, 0x10, 0xF0, 0x02, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37,
+0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x00, 0x69, 0x63, 0xF3,
+0x00, 0x4E, 0x5C, 0xF4, 0x00, 0x4F, 0xDC, 0xF3, 0x0C, 0x4D, 0x28, 0x32,
+0xED, 0xE2, 0x60, 0x9B, 0xD1, 0xE2, 0xA9, 0xE2, 0xC0, 0xF5, 0x74, 0xDC,
+0x40, 0x9A, 0x01, 0x49, 0x04, 0x51, 0x60, 0xF5, 0x40, 0xDC, 0xF3, 0x61,
+0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x04, 0x69, 0x63, 0xF3, 0x00, 0x4F, 0x5C, 0xF4, 0x00, 0x4E, 0xDC, 0xF3,
+0x0C, 0x4D, 0x28, 0x33, 0xC9, 0xE3, 0x40, 0x9A, 0xF1, 0xE3, 0xAD, 0xE3,
+0x4A, 0x32, 0xC0, 0xF5, 0x54, 0xDC, 0x40, 0x9B, 0x01, 0x49, 0x1D, 0x51,
+0x4A, 0x32, 0x60, 0xF5, 0x40, 0xDC, 0xF1, 0x61, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x00, 0x69, 0x04, 0x67,
+0xD1, 0x67, 0xC4, 0xF4, 0x14, 0x48, 0x06, 0xD4, 0x08, 0xD1, 0x09, 0x10,
+0x08, 0x94, 0x01, 0x49, 0x7F, 0x48, 0x7F, 0x4C, 0x15, 0x4C, 0x20, 0x51,
+0x15, 0x48, 0x08, 0xD4, 0x5E, 0x60, 0x8D, 0x98, 0x01, 0x6B, 0x82, 0x32,
+0x52, 0x32, 0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xEF, 0x22, 0x07, 0x6A,
+0x4C, 0xEC, 0x6C, 0xEC, 0x88, 0x32, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC,
+0x80, 0x34, 0x80, 0x34, 0x80, 0xF1, 0x04, 0x4C, 0x89, 0xE2, 0x6B, 0x98,
+0x40, 0x9A, 0x91, 0x67, 0x6C, 0xEA, 0x4C, 0xD8, 0x00, 0x18, 0xA5, 0x21,
+0x0A, 0xD6, 0x20, 0xF0, 0x96, 0xA0, 0xFF, 0x6A, 0xA2, 0x67, 0x4C, 0xEC,
+0x00, 0x18, 0x93, 0x21, 0x2C, 0xED, 0x20, 0xF0, 0x56, 0xA0, 0x04, 0x94,
+0xFF, 0x6B, 0x6C, 0xEA, 0x43, 0xEC, 0x0A, 0x96, 0x01, 0x60, 0x04, 0xD2,
+0xC1, 0xD8, 0xC2, 0xD8, 0xC3, 0xD8, 0xC4, 0xD8, 0xC5, 0xD8, 0xC6, 0xD8,
+0xC7, 0xD8, 0xC8, 0xD8, 0x06, 0x93, 0x48, 0x32, 0xA6, 0x67, 0x69, 0xE2,
+0xC0, 0xF5, 0x74, 0x9A, 0x60, 0xF5, 0x40, 0x9A, 0x4D, 0xE3, 0x66, 0x33,
+0x60, 0xD8, 0x08, 0x92, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33,
+0x63, 0xF3, 0x00, 0x4B, 0x71, 0xE2, 0x66, 0x67, 0xA9, 0xE4, 0x01, 0x4D,
+0x1D, 0x55, 0x04, 0xF5, 0x6C, 0xC2, 0x24, 0xF5, 0x69, 0xC2, 0x44, 0xF5,
+0x66, 0xC2, 0xF6, 0x61, 0x64, 0xF5, 0xC4, 0xDC, 0x08, 0x94, 0x01, 0x49,
+0x7F, 0x48, 0x7F, 0x4C, 0x15, 0x4C, 0x20, 0x51, 0x15, 0x48, 0x08, 0xD4,
+0xA2, 0x61, 0x05, 0x92, 0x06, 0x2A, 0x07, 0x93, 0x63, 0xF3, 0x00, 0x4B,
+0x07, 0xD3, 0x27, 0xF1, 0x44, 0xDB, 0x0E, 0x97, 0x0D, 0x91, 0x0C, 0x90,
+0x00, 0xEF, 0x08, 0x63, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x22, 0x67, 0xBC, 0xF3, 0x0C, 0x4C, 0x00, 0xF5, 0x04, 0x4B, 0x89, 0xE1,
+0x40, 0xA2, 0x01, 0x49, 0x1D, 0x51, 0x40, 0xC3, 0x01, 0x4B, 0xF9, 0x61,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x00, 0x69, 0x63, 0xF3, 0x00, 0x4B, 0x7C, 0xF2, 0x08, 0x4C, 0x1C, 0xF1,
+0x08, 0x4A, 0x0B, 0x65, 0x4C, 0x65, 0x2A, 0x65, 0x11, 0x67, 0x68, 0x67,
+0x8A, 0x67, 0x00, 0x6D, 0x7D, 0xE0, 0x99, 0xE0, 0xAD, 0xE6, 0x40, 0xA3,
+0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0, 0x51, 0xA3,
+0x05, 0x55, 0x20, 0xF4, 0x59, 0xC4, 0xF4, 0x61, 0x48, 0x67, 0x51, 0xE1,
+0x49, 0x67, 0x4D, 0xE1, 0x40, 0xA3, 0x01, 0x49, 0x1D, 0x51, 0xC0, 0xF4,
+0x4A, 0xC4, 0x5D, 0xA3, 0x05, 0x48, 0xE0, 0xF4, 0x47, 0xC4, 0xE1, 0x61,
+0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x2B, 0x67, 0x63, 0xF3, 0x00, 0x4F, 0x5C, 0xF4, 0x00, 0x4E, 0xDC, 0xF3,
+0x0C, 0x4D, 0x28, 0x32, 0xCD, 0xE2, 0x60, 0x9B, 0xF1, 0xE2, 0xA9, 0xE2,
+0xC0, 0xF5, 0x74, 0xDC, 0x40, 0x9A, 0x01, 0x49, 0x1D, 0x51, 0x60, 0xF5,
+0x40, 0xDC, 0xF3, 0x61, 0x17, 0x17, 0x00, 0x00, 0xFF, 0xF7, 0x1F, 0x6F,
+0x8C, 0xEF, 0xE0, 0xF1, 0x10, 0x6E, 0xEC, 0xEE, 0xFB, 0x63, 0xD2, 0x36,
+0x06, 0xD0, 0xCC, 0x30, 0xC1, 0xE0, 0x08, 0x30, 0xC1, 0xE0, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x08, 0x30,
+0x41, 0xE0, 0x08, 0x62, 0x07, 0xD1, 0x25, 0x67, 0x04, 0xF5, 0xA8, 0x98,
+0x02, 0xF0, 0x00, 0x6A, 0xFF, 0x6B, 0x4D, 0xED, 0x00, 0xF2, 0x00, 0x6A,
+0xEC, 0xEA, 0x43, 0x32, 0x02, 0x4B, 0x6B, 0xEB, 0x47, 0x32, 0x6C, 0xED,
+0x40, 0x32, 0x4D, 0xED, 0x04, 0xF5, 0x20, 0xD8, 0x04, 0xF5, 0xA8, 0xD8,
+0x87, 0x67, 0x04, 0xD5, 0x00, 0x18, 0x2C, 0x22, 0x05, 0xD6, 0x04, 0x95,
+0x08, 0x6B, 0x07, 0x6C, 0x6B, 0xEB, 0x8C, 0xEA, 0xAC, 0xEB, 0x4D, 0xEB,
+0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x04, 0xF5, 0x68, 0xD8,
+0x40, 0x32, 0x8C, 0xEB, 0x80, 0xF1, 0x04, 0x4A, 0x68, 0x33, 0x4D, 0xE3,
+0x40, 0x9B, 0x2C, 0xEA, 0x04, 0xF5, 0x44, 0xD8, 0x05, 0x96, 0x00, 0x18,
+0xA5, 0x21, 0x86, 0x67, 0x05, 0x96, 0x04, 0xF5, 0x8A, 0xA0, 0x00, 0x18,
+0x93, 0x21, 0xA6, 0x67, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0xEF,
+0x05, 0x63, 0x00, 0x00, 0xFF, 0x6A, 0xFD, 0x63, 0x04, 0x62, 0x00, 0x18,
+0xDB, 0x5C, 0x4C, 0xEC, 0x04, 0x97, 0x00, 0xEF, 0x03, 0x63, 0x00, 0x00,
+0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x02, 0xF0, 0x00, 0x6D,
+0x63, 0xF3, 0x00, 0x4C, 0x1F, 0x6B, 0x04, 0xF5, 0x48, 0x9C, 0xFF, 0x4B,
+0x00, 0x53, 0xAD, 0xEA, 0x04, 0xF5, 0x48, 0xDC, 0x7F, 0x4C, 0x15, 0x4C,
+0xF6, 0x60, 0x20, 0xE8, 0x00, 0x65, 0x00, 0x65, 0x00, 0x1C, 0xA1, 0x5E,
+0x00, 0x65, 0x00, 0x65, 0x83, 0xED, 0xAB, 0xE4, 0x01, 0x61, 0x8B, 0xE5,
+0x20, 0xE8, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0xF9, 0x63, 0x4B, 0xEA,
+0x0A, 0xD0, 0x40, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x0C, 0x62,
+0x00, 0x1C, 0x00, 0x5C, 0x0B, 0xD1, 0x05, 0xD2, 0x05, 0x93, 0x70, 0x6A,
+0x6C, 0xEA, 0x3A, 0x2A, 0x67, 0x40, 0x3B, 0x4B, 0x01, 0x6A, 0x4B, 0xEA,
+0x40, 0xC3, 0x05, 0x93, 0x70, 0x6A, 0x4C, 0xEB, 0x08, 0xD3, 0x3C, 0x2B,
+0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x10, 0x4C, 0x02, 0xF0, 0x00, 0x6A,
+0x40, 0x31, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x18, 0x6C, 0x9D, 0x67,
+0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x02, 0x67, 0x00, 0x1C, 0x5B, 0x1F,
+0x64, 0x6C, 0x10, 0xF0, 0x00, 0x6A, 0xD0, 0x67, 0x4D, 0xEE, 0x18, 0x6C,
+0x00, 0x1C, 0x83, 0x45, 0xAF, 0x41, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C,
+0x08, 0x92, 0x6A, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x7D, 0x67, 0x4B, 0xEA,
+0x40, 0x32, 0x20, 0xF0, 0x60, 0xA3, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90,
+0x40, 0x32, 0x42, 0x4A, 0x07, 0x63, 0x60, 0xC2, 0x00, 0xEF, 0x00, 0x65,
+0x8F, 0x6A, 0xA3, 0x67, 0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0x4C, 0xED, 0x05, 0x93, 0x70, 0x6A, 0x4C, 0xEB, 0x08, 0xD3, 0xC4, 0x23,
+0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x10, 0x4C, 0x02, 0xF0, 0x00, 0x6D,
+0xA0, 0x31, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x00, 0x6C, 0x9D, 0x67,
+0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x06, 0xD2, 0x00, 0x1C, 0x5B, 0x1F,
+0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x9D, 0x67, 0x00, 0x1C,
+0x8A, 0x40, 0x10, 0x4C, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x00, 0x6C,
+0x9D, 0x67, 0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x07, 0xD2, 0x00, 0x1C,
+0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x00, 0x6C, 0x01, 0xF1,
+0x00, 0x68, 0x06, 0x96, 0x00, 0x30, 0x01, 0x6A, 0xFF, 0x48, 0x40, 0x32,
+0x40, 0x32, 0x0C, 0xEE, 0x4D, 0xEE, 0xAF, 0x41, 0x00, 0x1C, 0x83, 0x45,
+0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42,
+0x01, 0x6C, 0x07, 0x93, 0x01, 0x6E, 0xC0, 0x36, 0x6C, 0xE8, 0xC0, 0x36,
+0xAF, 0x41, 0x0D, 0xEE, 0x00, 0x1C, 0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C,
+0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x00, 0x6C, 0x76, 0x17,
+0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x01, 0xF5,
+0x03, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x05, 0x95, 0x06, 0x96, 0xAF, 0x41,
+0x00, 0x1C, 0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x07, 0x96, 0xAF, 0x41, 0x00, 0x1C,
+0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C,
+0xF0, 0x42, 0x00, 0x6C, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90, 0x00, 0xEF,
+0x07, 0x63, 0x00, 0x00, 0xF8, 0x63, 0x0D, 0xD1, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0x0E, 0x62, 0x0C, 0xD0, 0x63, 0xF3, 0x00, 0x49,
+0x03, 0x99, 0x01, 0x6A, 0x80, 0xF7, 0x02, 0x30, 0x4C, 0xE8, 0x08, 0x28,
+0x42, 0x99, 0x03, 0x6B, 0x40, 0xF7, 0x42, 0x32, 0x6C, 0xEA, 0x01, 0x72,
+0x00, 0xF2, 0x07, 0x60, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x63, 0xF3, 0x00, 0x4D, 0x43, 0x9D, 0x01, 0x6B, 0x80, 0xF7, 0x42, 0x32,
+0x6C, 0xEA, 0xE0, 0xF1, 0x14, 0x22, 0x42, 0x9D, 0x03, 0x6B, 0x40, 0xF7,
+0x42, 0x32, 0x6C, 0xEA, 0x01, 0x72, 0xE0, 0xF1, 0x0C, 0x61, 0x44, 0x9D,
+0x80, 0xF7, 0x42, 0x32, 0x01, 0x72, 0xA0, 0xF2, 0x00, 0x60, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0xC0, 0xF2, 0xA7, 0xA5, 0x80, 0x34, 0x80, 0x34,
+0x61, 0xF4, 0x02, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x06, 0xD5, 0x10, 0xF0,
+0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0xC0, 0xF2,
+0x46, 0xA1, 0x07, 0x2A, 0xBD, 0x67, 0xAC, 0xAD, 0x01, 0x6A, 0xC0, 0xF2,
+0x46, 0xC1, 0xC0, 0xF2, 0xA4, 0xC9, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA,
+0x40, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0x00, 0x5C,
+0x00, 0x65, 0x70, 0x6B, 0x4C, 0xEB, 0x80, 0xF2, 0x16, 0x2B, 0xC0, 0xF2,
+0x44, 0xA9, 0x06, 0x93, 0x53, 0xE3, 0x63, 0xEA, 0x07, 0xD4, 0x02, 0x61,
+0x6B, 0xE2, 0x07, 0xD2, 0x07, 0x95, 0x03, 0x5D, 0x80, 0xF2, 0x0D, 0x60,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xC9, 0xF7, 0x1B, 0x6C,
+0x63, 0xF3, 0x00, 0x4A, 0x8B, 0xEC, 0x80, 0x34, 0xC0, 0xF2, 0xA4, 0xA2,
+0x80, 0x34, 0x61, 0xF4, 0x03, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x63, 0xF3, 0x00, 0x4D,
+0x9D, 0x67, 0x62, 0x9D, 0x98, 0xA4, 0x3F, 0x6E, 0x24, 0x6A, 0xC0, 0xF2,
+0x82, 0xC5, 0x83, 0x67, 0x62, 0x33, 0xCC, 0xEC, 0x62, 0x33, 0xCC, 0xEB,
+0x93, 0xE2, 0x20, 0x6A, 0x7B, 0xE2, 0xC0, 0xF2, 0x43, 0xA5, 0x06, 0x95,
+0x4F, 0xE5, 0x43, 0xED, 0x07, 0xD3, 0x02, 0x60, 0xAB, 0xE2, 0x07, 0xD2,
+0x07, 0x95, 0x60, 0xF1, 0x1C, 0x25, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2, 0x43, 0xA3, 0x06, 0x95,
+0x43, 0xED, 0x16, 0x60, 0x07, 0x92, 0x24, 0x68, 0x83, 0xEA, 0x40, 0xF2,
+0x18, 0x61, 0x07, 0x94, 0x20, 0x6D, 0x08, 0xD5, 0xC3, 0xEC, 0x24, 0x60,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A,
+0x45, 0xAA, 0x3F, 0x6B, 0x6C, 0xEA, 0x89, 0xE2, 0x08, 0xD2, 0x18, 0x10,
+0x42, 0x9B, 0x3F, 0x6B, 0x6C, 0xEA, 0x07, 0x93, 0x43, 0xEB, 0x63, 0xE2,
+0x01, 0x61, 0x00, 0x68, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0x45, 0xAA, 0x07, 0x94, 0x3F, 0x6B, 0x6C, 0xEA,
+0x43, 0xEC, 0x8B, 0xE2, 0x08, 0xD2, 0x02, 0x61, 0x00, 0x6D, 0x08, 0xD5,
+0x06, 0x6A, 0x03, 0xEA, 0x80, 0xF2, 0x06, 0x60, 0x10, 0xF0, 0x02, 0x6B,
+0x00, 0xF4, 0x60, 0x33, 0x08, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2,
+0xA6, 0x9A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3,
+0x00, 0x4B, 0xC3, 0x9B, 0xE0, 0xF3, 0x1F, 0x6F, 0x80, 0xF5, 0xA2, 0x35,
+0x86, 0x67, 0xEC, 0xEC, 0x40, 0xF2, 0x17, 0x24, 0x00, 0xF2, 0x00, 0x68,
+0x44, 0x67, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA,
+0x4D, 0xEC, 0xB8, 0xEC, 0xC2, 0x33, 0x6A, 0x33, 0xEC, 0xEB, 0x12, 0xEA,
+0x42, 0x34, 0x43, 0x67, 0x0C, 0xEA, 0xEC, 0xEC, 0x04, 0x22, 0x00, 0xF4,
+0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xC9, 0xF7, 0x1B, 0x68,
+0x0B, 0xE8, 0x80, 0xF5, 0xA0, 0x35, 0x00, 0x30, 0x00, 0x30, 0x12, 0xEA,
+0x42, 0x31, 0xEC, 0xE9, 0x3F, 0x6A, 0x2C, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x4D, 0xED, 0x8D, 0xED, 0x81, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x04, 0xD5, 0x91, 0xF4, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x02, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0x4C, 0xED,
+0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xE9, 0x80, 0xF5, 0x20, 0x32, 0x4D, 0xED,
+0x04, 0xD5, 0x91, 0xF4, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0x42, 0x9B, 0xC0, 0xF7, 0x42, 0x32, 0xC0, 0xF1, 0x0A, 0x2A, 0x08, 0x94,
+0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x8C, 0x32, 0x65, 0xE2, 0xA0, 0xF0,
+0xAC, 0xA1, 0x00, 0x30, 0x00, 0x30, 0x21, 0xF2, 0x82, 0x40, 0x00, 0x1C,
+0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAD, 0xA1, 0x21, 0xF2, 0x83, 0x40,
+0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAE, 0xA1, 0x21, 0xF2,
+0x84, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAF, 0xA1,
+0x21, 0xF2, 0x85, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0,
+0xB0, 0xA1, 0x21, 0xF2, 0x86, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65,
+0xA0, 0xF0, 0xB1, 0xA1, 0x21, 0xF2, 0x87, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0x00, 0x65, 0xA0, 0xF0, 0xB2, 0xA1, 0x21, 0xF2, 0x88, 0x40, 0x00, 0x1C,
+0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xB3, 0xA1, 0x21, 0xF2, 0x89, 0x40,
+0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0x03, 0x60, 0x92, 0x72,
+0x80, 0xF0, 0x0D, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0x42, 0x9A, 0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA,
+0x24, 0x6B, 0x53, 0xE3, 0x07, 0x92, 0x01, 0x6B, 0x6E, 0xEA, 0x6C, 0xEA,
+0x00, 0xF2, 0x0F, 0x22, 0x07, 0x95, 0xA6, 0x33, 0x64, 0x32, 0x69, 0xE2,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x07, 0xD2, 0x63, 0xF3,
+0x00, 0x4B, 0xC0, 0xF2, 0x43, 0xA3, 0x06, 0x95, 0x43, 0xED, 0xA0, 0xF1,
+0x19, 0x60, 0x07, 0x92, 0x24, 0x68, 0x83, 0xEA, 0x06, 0x60, 0x42, 0x9B,
+0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x07, 0x93, 0x61, 0xE2, 0x06, 0x6D,
+0x03, 0xED, 0xA0, 0xF1, 0x16, 0x60, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x08, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0xA6, 0x9A,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B,
+0xC4, 0x9B, 0xE0, 0xF3, 0x1F, 0x6F, 0x80, 0xF5, 0xA2, 0x35, 0xC2, 0x34,
+0x8A, 0x34, 0xEC, 0xEC, 0xA0, 0xF1, 0x1E, 0x24, 0x00, 0xF2, 0x00, 0x68,
+0x44, 0x67, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA,
+0x4D, 0xEC, 0xB8, 0xEC, 0x00, 0xF5, 0xC2, 0x33, 0xEC, 0xEB, 0x12, 0xEA,
+0x42, 0x34, 0x43, 0x67, 0x0C, 0xEA, 0xEC, 0xEC, 0x04, 0x22, 0x00, 0xF4,
+0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xC9, 0xF7, 0x1B, 0x68,
+0x0B, 0xE8, 0x80, 0xF5, 0xA0, 0x35, 0x00, 0x30, 0x00, 0x30, 0x12, 0xEA,
+0x42, 0x31, 0xEC, 0xE9, 0x3F, 0x6A, 0x2C, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0x4D, 0xED, 0x8D, 0xED, 0x81, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x04, 0xD5, 0x91, 0xF4, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x02, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0x4C, 0xED,
+0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xE9, 0x80, 0xF5, 0x20, 0x32, 0x4D, 0xED,
+0x91, 0xF4, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x04, 0xD5, 0x0E, 0x97,
+0x0D, 0x91, 0x0C, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x08, 0x63, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x00, 0x4C,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x08, 0xF0, 0x00, 0x6B, 0x6B, 0xEB,
+0x60, 0x33, 0xA2, 0x67, 0x6C, 0xED, 0xD1, 0x67, 0x03, 0x10, 0x01, 0x48,
+0x25, 0x58, 0x0E, 0x60, 0x08, 0x32, 0xC9, 0xE2, 0x46, 0x9A, 0x6C, 0xEA,
+0xAE, 0xEA, 0xF7, 0x2A, 0x62, 0x9E, 0x40, 0x6C, 0x3F, 0x6A, 0x8B, 0xEC,
+0x0C, 0xEA, 0x8C, 0xEB, 0x4D, 0xEB, 0x62, 0xDE, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0x02, 0x60,
+0x92, 0x72, 0x2A, 0x61, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34,
+0x80, 0x34, 0x81, 0xF4, 0x08, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x68,
+0x08, 0xF0, 0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33, 0xA2, 0x67, 0x10, 0xF0,
+0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x6C, 0xED, 0x63, 0xF3, 0x00, 0x4E,
+0x03, 0x10, 0x01, 0x48, 0x25, 0x58, 0x10, 0x60, 0x08, 0x32, 0xC9, 0xE2,
+0x46, 0x9A, 0x6C, 0xEA, 0xAE, 0xEA, 0xF7, 0x2A, 0x62, 0x9E, 0x3F, 0x6A,
+0x07, 0xF7, 0x01, 0x6C, 0x0C, 0xEA, 0x8B, 0xEC, 0x40, 0x32, 0x8C, 0xEB,
+0x4D, 0xEB, 0x62, 0xDE, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34,
+0x80, 0x34, 0x21, 0xF2, 0x04, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x68,
+0x27, 0xF7, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x27, 0xF7, 0x1F, 0x4B,
+0x4C, 0xEB, 0x04, 0xD3, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x03, 0xF4, 0x0E, 0x4A,
+0x03, 0xF5, 0x16, 0x4B, 0x09, 0xD2, 0x0A, 0xD3, 0x0C, 0x10, 0x0A, 0x93,
+0x9D, 0x67, 0x10, 0x4C, 0x75, 0xE1, 0x00, 0x1C, 0x1D, 0x55, 0x04, 0x6E,
+0xC0, 0xF0, 0x1B, 0x22, 0x01, 0x48, 0x21, 0x58, 0x22, 0x60, 0x09, 0x92,
+0x0C, 0x31, 0x9D, 0x67, 0x10, 0x4C, 0x55, 0xE1, 0x00, 0x1C, 0x1D, 0x55,
+0x04, 0x6E, 0xEB, 0x2A, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35,
+0x63, 0xF3, 0x00, 0x4D, 0x07, 0xF7, 0x00, 0x6A, 0x62, 0x9D, 0x4B, 0xEA,
+0x40, 0x32, 0xFF, 0x4A, 0x3F, 0x6C, 0x4C, 0xEB, 0x0C, 0xEC, 0x10, 0xF0,
+0x00, 0x6A, 0x80, 0x34, 0x40, 0x32, 0x80, 0x34, 0x40, 0x32, 0x8D, 0xEB,
+0xFF, 0x4A, 0x4C, 0xEB, 0x62, 0xDD, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4,
+0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x63, 0x9C, 0x08, 0xF0, 0x00, 0x6A,
+0x40, 0x32, 0x40, 0x32, 0x4D, 0xEB, 0x63, 0xDC, 0x45, 0x15, 0x02, 0xF0,
+0x00, 0x68, 0x00, 0x30, 0x60, 0x6E, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45,
+0x24, 0x6C, 0xE0, 0xF3, 0x08, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x00, 0x65,
+0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x14, 0x4C, 0xAF, 0x40, 0x00, 0x1C,
+0xAC, 0x45, 0x24, 0x6C, 0x1F, 0x6C, 0x4C, 0xEC, 0x06, 0xD4, 0x9D, 0x67,
+0x00, 0x1C, 0x90, 0x40, 0x14, 0x4C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C,
+0x4C, 0x15, 0x61, 0xF4, 0x83, 0x40, 0xCC, 0x6D, 0x82, 0x15, 0x00, 0x18,
+0xA4, 0x5E, 0x00, 0x65, 0x7D, 0x67, 0x6C, 0xAB, 0x10, 0xF0, 0x02, 0x6A,
+0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0xC0, 0xF2, 0x64, 0xCA,
+0x65, 0x15, 0x42, 0x9B, 0x3F, 0x6B, 0x6C, 0xEA, 0x07, 0x93, 0x61, 0xE2,
+0xA2, 0x15, 0x08, 0x95, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0xAC, 0x32,
+0x65, 0xE2, 0xA0, 0xF1, 0xB4, 0xA1, 0x00, 0x30, 0x00, 0x30, 0x21, 0xF2,
+0x82, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xB5, 0xA1,
+0x21, 0xF2, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1,
+0xB6, 0xA1, 0x21, 0xF2, 0x84, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65,
+0xA0, 0xF1, 0xB7, 0xA1, 0x21, 0xF2, 0x85, 0x40, 0x00, 0x1C, 0xF0, 0x5B,
+0x00, 0x65, 0xA0, 0xF1, 0xB8, 0xA1, 0x21, 0xF2, 0x86, 0x40, 0x00, 0x1C,
+0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xB9, 0xA1, 0x21, 0xF2, 0x87, 0x40,
+0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xBA, 0xA1, 0x21, 0xF2,
+0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xBB, 0xA1,
+0x21, 0xF2, 0x89, 0x40, 0x35, 0x16, 0x6A, 0x60, 0x08, 0x32, 0xC9, 0xF7,
+0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC, 0x80, 0x34, 0xA6, 0x9A, 0x80, 0x34,
+0x81, 0xF4, 0x00, 0x4C, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x14, 0x4C,
+0x00, 0x6D, 0xD3, 0x15, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0xAC, 0x9A, 0x7B, 0x15, 0x42, 0x9B, 0x07, 0x94,
+0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x43, 0xEC, 0x83, 0xE2, 0x5F, 0xF6,
+0x08, 0x61, 0x00, 0x68, 0x18, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0xAC, 0x9A, 0x4B, 0x16, 0x10, 0xF0,
+0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x63, 0xF3, 0x00, 0x4D, 0x07, 0xF7,
+0x00, 0x6A, 0x62, 0x9D, 0x4B, 0xEA, 0x3F, 0x6C, 0x40, 0x32, 0xFF, 0x4A,
+0x0C, 0xEC, 0x4C, 0xEB, 0x80, 0x34, 0x10, 0xF0, 0x00, 0x6A, 0x4B, 0xEA,
+0x80, 0x34, 0x40, 0x32, 0x8D, 0xEB, 0x40, 0x32, 0x4D, 0xEB, 0x30, 0x17,
+0x28, 0x60, 0x08, 0x32, 0xC9, 0xF7, 0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC,
+0x80, 0x34, 0xA6, 0x9A, 0x80, 0x34, 0x81, 0xF4, 0x08, 0x4C, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34,
+0x80, 0x34, 0x81, 0xF4, 0x1C, 0x4C, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D,
+0x6C, 0x16, 0x07, 0x93, 0xFF, 0x4B, 0x66, 0x33, 0x64, 0x32, 0x69, 0xE2,
+0x01, 0x4A, 0xEE, 0x15, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34,
+0xAC, 0x9B, 0x80, 0x34, 0x81, 0xF4, 0x00, 0x4C, 0x97, 0x17, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0xAC, 0x9B, 0x80, 0x34, 0x81, 0xF4,
+0x08, 0x4C, 0xD9, 0x17, 0x82, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC,
+0x82, 0x35, 0x20, 0x5D, 0x1B, 0x60, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xA9, 0xE2, 0x63, 0xF3,
+0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0xE4, 0xF4, 0x58, 0x9A, 0xC9, 0xF7,
+0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x52, 0x32, 0x7F, 0x6B,
+0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x40, 0xDC, 0x20, 0xE8, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xCA, 0xF2, 0x4C, 0x9A,
+0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x52, 0x32,
+0x7F, 0x6B, 0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x40, 0xDC, 0x20, 0xE8,
+0x00, 0x65, 0x00, 0x00, 0xFC, 0x63, 0x04, 0xD0, 0xC9, 0xF7, 0x1B, 0x68,
+0x0B, 0xE8, 0x00, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x06, 0x62,
+0x00, 0x1C, 0x00, 0x5C, 0x05, 0xD1, 0x08, 0x6D, 0x4D, 0xED, 0xFF, 0x69,
+0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x2C, 0xED, 0x01, 0xF5,
+0x83, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0xA2, 0x67, 0xF7, 0x6B,
+0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x6C, 0xED, 0x21, 0xF2,
+0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0xA2, 0x67, 0x3F, 0x6B,
+0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x6C, 0xED, 0x21, 0xF2,
+0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0x80, 0x6D, 0xAB, 0xED,
+0x4D, 0xED, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x2C, 0xED,
+0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x65,
+0x00, 0x1C, 0x2A, 0x61, 0x00, 0x65, 0x00, 0x65, 0x00, 0x1C, 0x2C, 0x61,
+0x00, 0x65, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x30, 0xF2, 0x63, 0x42, 0x90, 0x34, 0x80, 0xC3, 0x20, 0xF2,
+0x10, 0x4A, 0x40, 0x9A, 0x02, 0xF0, 0x00, 0x6B, 0x60, 0x33, 0xFF, 0x4B,
+0x20, 0xE8, 0x6C, 0xEA, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0xFF, 0x6D,
+0x40, 0x32, 0x8C, 0xED, 0x40, 0x32, 0x30, 0xF2, 0x83, 0x42, 0xB0, 0x33,
+0x60, 0xC4, 0x20, 0xF2, 0x10, 0x4A, 0x60, 0x9A, 0x02, 0xF0, 0x00, 0x6A,
+0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x83, 0x67, 0x05, 0x23, 0x01, 0x6C,
+0x84, 0xED, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEC, 0x20, 0xE8, 0x44, 0x67,
+0xC9, 0xF7, 0x1B, 0x6A, 0xFB, 0x63, 0x4B, 0xEA, 0x07, 0xD1, 0x40, 0x31,
+0x08, 0x62, 0x06, 0xD0, 0x20, 0x31, 0x40, 0xF0, 0x4C, 0xA1, 0xFF, 0x6C,
+0x8C, 0xEA, 0x02, 0x72, 0x14, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x04, 0xD2, 0x66, 0xF7, 0x56, 0xAA,
+0x01, 0x72, 0x09, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0xEB, 0xF5, 0x4C, 0xA2, 0x04, 0x67, 0x4C, 0xE8, 0x05, 0x20, 0x08, 0x97,
+0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0x00, 0x18, 0x2C, 0x61,
+0x04, 0x6C, 0x04, 0x94, 0x08, 0xF0, 0x64, 0x9C, 0x4D, 0xE3, 0x08, 0xF0,
+0x64, 0xDC, 0x00, 0x18, 0x2C, 0x61, 0x06, 0x6C, 0x04, 0x94, 0x08, 0xF0,
+0x68, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, 0x68, 0xDC, 0x00, 0x18, 0x2C, 0x61,
+0x07, 0x6C, 0x04, 0x94, 0x08, 0xF0, 0x6C, 0x9C, 0x4D, 0xE3, 0x08, 0xF0,
+0x6C, 0xDC, 0x00, 0x18, 0x2C, 0x61, 0x05, 0x6C, 0x04, 0x94, 0x08, 0xF0,
+0x70, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, 0x70, 0xDC, 0x00, 0x18, 0x35, 0x61,
+0x90, 0x67, 0x04, 0x6C, 0x00, 0x18, 0x35, 0x61, 0x02, 0x67, 0x4D, 0xE8,
+0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xE8, 0x30, 0xF2, 0x63, 0x41, 0x08, 0x6A,
+0x40, 0xC3, 0xC7, 0x28, 0x40, 0xF0, 0x40, 0xA9, 0xFF, 0xF7, 0x1F, 0x6B,
+0x6C, 0xEA, 0xFB, 0xF7, 0x1F, 0x6B, 0x6C, 0xEA, 0x04, 0xF0, 0x00, 0x6B,
+0x40, 0xF0, 0x40, 0xC9, 0x6D, 0xEA, 0x40, 0xF0, 0x40, 0xC9, 0x04, 0x94,
+0xFF, 0xF7, 0x1F, 0x6A, 0x66, 0xF7, 0xB4, 0xAC, 0x01, 0x4D, 0x66, 0xF7,
+0xB4, 0xCC, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x7E, 0xF2,
+0x08, 0x4C, 0x00, 0x1C, 0x13, 0x58, 0x4C, 0xED, 0xA6, 0x17, 0x00, 0x65,
+0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x85, 0x2B, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0x02, 0x80, 0x02, 0x3C,
+0xE8, 0x03, 0x03, 0x24, 0x2C, 0x5E, 0x43, 0xAC, 0x18, 0x00, 0xBD, 0x27,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x40, 0xA0, 0xFF, 0x00, 0x85, 0x30,
+0xF2, 0x5D, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x05, 0x5E, 0x40, 0xA0, 0x08, 0x00, 0xA4, 0x2C, 0x07, 0x5E, 0x60, 0xA0,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x0F, 0x5E, 0x40, 0xA0,
+0xEC, 0x5D, 0x65, 0xA0, 0x2C, 0x00, 0x80, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x80, 0x10, 0x05, 0x00, 0x78, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24,
+0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C, 0x02, 0x00, 0x42, 0x34,
+0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC, 0x02, 0x80, 0x05, 0x3C,
+0x60, 0x1B, 0xA5, 0x24, 0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C,
+0x02, 0x00, 0x42, 0x34, 0x27, 0x10, 0x02, 0x00, 0x24, 0x20, 0x82, 0x00,
+0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xD0, 0x1B, 0xA4, 0xAC, 0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24,
+0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00,
+0x24, 0x20, 0x82, 0x00, 0x02, 0x80, 0x07, 0x3C, 0x41, 0xB0, 0x02, 0x3C,
+0x01, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xAC, 0x09, 0x5E, 0xE3, 0xA0,
+0x09, 0x5E, 0xE6, 0x90, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x1B, 0xA4, 0xAC,
+0x0A, 0x5E, 0x46, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xD0, 0x1B, 0xA4, 0x8C,
+0x00, 0x70, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00, 0x24, 0x20, 0x82, 0x00,
+0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0xD0, 0x1B, 0xA4, 0xAC, 0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x10, 0x3C, 0xEC, 0x5D, 0x02, 0x92, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x90, 0x80, 0x00,
+0x1C, 0x00, 0x40, 0x10, 0xFF, 0x00, 0xB1, 0x30, 0x02, 0x80, 0x03, 0x3C,
+0xC6, 0x5C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30,
+0x1C, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24,
+0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x0F, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x42, 0x28, 0x06, 0x00, 0x40, 0x10,
+0x08, 0x00, 0x02, 0x24, 0x00, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0x83, 0x30, 0x1B, 0x00, 0x62, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0xEC, 0x5D, 0x02, 0x92, 0x05, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x0B, 0x00, 0x43, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xBF, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xA8, 0x2D, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0xF1, 0x61, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24,
+0x08, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x22, 0x02,
+0xF2, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x07, 0x5E, 0x62, 0xA0,
+0x05, 0x62, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5E, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0x10, 0x82, 0x34,
+0x00, 0x62, 0x00, 0x08, 0x00, 0x00, 0x42, 0xA6, 0x0C, 0x00, 0x04, 0x24,
+0x4B, 0x2E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x00, 0x62, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x40, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x0B, 0x5E, 0x60, 0xA0,
+0x02, 0x80, 0x04, 0x3C, 0x07, 0x5E, 0x83, 0x90, 0xFD, 0xFF, 0x02, 0x24,
+0x24, 0x18, 0x62, 0x00, 0x07, 0x5E, 0x83, 0xA0, 0x07, 0x5E, 0x82, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x42, 0x30, 0x49, 0x00, 0x40, 0x10,
+0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xF2, 0x5D, 0x82, 0x90,
+0x02, 0x80, 0x05, 0x3C, 0x01, 0x00, 0x42, 0x24, 0xF2, 0x5D, 0x82, 0xA0,
+0x07, 0x5E, 0xA3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00,
+0x07, 0x5E, 0xA3, 0xA0, 0xF2, 0x5D, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x42, 0x2C, 0x13, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x06, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x42, 0x30, 0x3A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00,
+0xE5, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0x62, 0x90,
+0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x42, 0x24,
+0x0E, 0x5E, 0x62, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x84, 0x00, 0xC4, 0x34, 0x80, 0x00, 0xC6, 0x34, 0x00, 0x00, 0x82, 0x8C,
+0x00, 0x00, 0xC4, 0x8C, 0x02, 0x80, 0x08, 0x3C, 0x21, 0x10, 0x00, 0x00,
+0x14, 0x5E, 0x06, 0x8D, 0x42, 0xB0, 0x0A, 0x3C, 0x25, 0x10, 0x44, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x18, 0x5E, 0x88, 0x8C, 0x1C, 0x5E, 0x89, 0x8C,
+0x00, 0x00, 0x45, 0x91, 0x21, 0x10, 0x46, 0x00, 0xFB, 0xFF, 0x04, 0x24,
+0x24, 0x28, 0xA4, 0x00, 0x23, 0x40, 0x02, 0x01, 0x00, 0x00, 0x45, 0xA1,
+0x04, 0x00, 0x00, 0x11, 0x01, 0x00, 0x06, 0x24, 0x80, 0x10, 0x08, 0x00,
+0x21, 0x10, 0x48, 0x00, 0x80, 0x30, 0x02, 0x00, 0x01, 0x00, 0x04, 0x24,
+0xB9, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C,
+0x22, 0x00, 0x04, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x44, 0xA0,
+0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x10, 0x00, 0xBF, 0x8F,
+0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08,
+0x18, 0x00, 0xBD, 0x27, 0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C,
+0xED, 0x5D, 0x64, 0x90, 0x10, 0x00, 0xBF, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x0E, 0x5E, 0x40, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27,
+0xFF, 0x00, 0xA5, 0x30, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF,
+0x18, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0x90, 0x30, 0x35, 0x00, 0x00, 0x12,
+0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x05, 0x24,
+0x05, 0x5E, 0x45, 0xA0, 0x02, 0x80, 0x07, 0x3C, 0x07, 0x5E, 0xE3, 0x90,
+0x02, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x63, 0x34,
+0x00, 0xF0, 0x06, 0x34, 0x07, 0x5E, 0xE3, 0xA0, 0xB9, 0x20, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34,
+0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA0, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x05, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x08, 0x5E, 0x65, 0x90,
+0x0F, 0x00, 0x02, 0x24, 0x02, 0x80, 0x06, 0x3C, 0x0F, 0x00, 0xA5, 0x30,
+0x0D, 0x00, 0xA2, 0x10, 0x01, 0x00, 0x04, 0x24, 0x07, 0x5E, 0xC2, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xC2, 0xA0,
+0xE1, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xFF, 0x00, 0x16,
+0x02, 0x80, 0x02, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C,
+0x04, 0x5E, 0x43, 0x90, 0x01, 0x00, 0x04, 0x24, 0xF6, 0xFF, 0x60, 0x10,
+0x01, 0x00, 0x05, 0x24, 0xC8, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xB9, 0x62, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0x00, 0x84, 0x30,
+0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27,
+0xFF, 0x00, 0xA5, 0x30, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x03, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0x91, 0x30,
+0x3A, 0x00, 0x20, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x10, 0x3C,
+0x07, 0x5E, 0x02, 0x92, 0xFB, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x07, 0x5E, 0x02, 0xA2, 0x10, 0x00, 0xA0, 0x14, 0x02, 0x80, 0x03, 0x3C,
+0x07, 0x5E, 0x02, 0x92, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00,
+0x07, 0x5E, 0x02, 0xA2, 0x19, 0x00, 0x20, 0x16, 0x02, 0x80, 0x02, 0x3C,
+0x07, 0x5E, 0x02, 0x92, 0xFD, 0xFF, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F,
+0x24, 0x10, 0x43, 0x00, 0x07, 0x5E, 0x02, 0xA2, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x01, 0x00, 0x04, 0x24, 0x05, 0x5E, 0x64, 0xA0, 0x07, 0x5E, 0x02, 0x92,
+0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x42, 0x34, 0x07, 0x5E, 0x02, 0xA2,
+0x06, 0x5E, 0x62, 0x90, 0x02, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30,
+0x23, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x51, 0x00, 0x0C,
+0x01, 0x00, 0x04, 0x24, 0xE9, 0xFF, 0x20, 0x12, 0x02, 0x80, 0x02, 0x3C,
+0x01, 0x00, 0x04, 0x24, 0x05, 0x5E, 0x44, 0xA0, 0x07, 0x5E, 0x03, 0x92,
+0x02, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x63, 0x34,
+0x00, 0xF0, 0x06, 0x34, 0x07, 0x5E, 0x03, 0xA2, 0xB9, 0x20, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x03, 0x24,
+0x03, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA0,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5E, 0x40, 0xA0,
+0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24,
+0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27,
+0xE2, 0x2C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x24,
+0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0xE5, 0x62, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB2, 0xAF,
+0x0C, 0x00, 0xB1, 0xAF, 0x08, 0x00, 0xB0, 0xAF, 0x21, 0x40, 0xE0, 0x00,
+0x21, 0x90, 0xA0, 0x03, 0x21, 0x60, 0xC0, 0x00, 0x21, 0x78, 0x80, 0x00,
+0x45, 0x00, 0xE0, 0x14, 0x21, 0x50, 0xA0, 0x00, 0x2B, 0x10, 0xA6, 0x00,
+0x78, 0x00, 0x40, 0x10, 0xFF, 0xFF, 0x02, 0x34, 0x2B, 0x10, 0x46, 0x00,
+0x8F, 0x01, 0x40, 0x10, 0x21, 0x28, 0xC0, 0x00, 0xFF, 0x00, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x10, 0x00, 0x03, 0x24, 0x2B, 0x10, 0x46, 0x00,
+0x18, 0x00, 0x04, 0x24, 0x21, 0x30, 0x60, 0x00, 0x0B, 0x30, 0x82, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x06, 0x10, 0xC5, 0x00, 0x98, 0xF2, 0x63, 0x24,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24,
+0x21, 0x20, 0x86, 0x00, 0x23, 0x30, 0x44, 0x00, 0x08, 0x00, 0xC0, 0x10,
+0x02, 0x4C, 0x0C, 0x00, 0x23, 0x10, 0x46, 0x00, 0x06, 0x10, 0x4F, 0x00,
+0x04, 0x18, 0xCA, 0x00, 0x25, 0x50, 0x62, 0x00, 0x04, 0x60, 0xCC, 0x00,
+0x04, 0x78, 0xCF, 0x00, 0x02, 0x4C, 0x0C, 0x00, 0x1B, 0x00, 0x49, 0x01,
+0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00,
+0xFF, 0xFF, 0x87, 0x31, 0x02, 0x24, 0x0F, 0x00, 0x12, 0x18, 0x00, 0x00,
+0x10, 0x28, 0x00, 0x00, 0x00, 0x14, 0x05, 0x00, 0x25, 0x28, 0x44, 0x00,
+0x18, 0x00, 0x67, 0x00, 0x12, 0x58, 0x00, 0x00, 0x2B, 0x18, 0xAB, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0x08, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xAC, 0x00, 0x2B, 0x10, 0xAC, 0x00,
+0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xAB, 0x00, 0x00, 0x00, 0x42, 0x38,
+0x21, 0x18, 0xAC, 0x00, 0x0B, 0x28, 0x62, 0x00, 0x23, 0x28, 0xAB, 0x00,
+0x1B, 0x00, 0xA9, 0x00, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xE4, 0x31, 0x12, 0x18, 0x00, 0x00,
+0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x63, 0x00, 0x08,
+0x18, 0x00, 0x67, 0x00, 0x2B, 0x10, 0xA7, 0x00, 0x0A, 0x00, 0x40, 0x10,
+0xFF, 0xFF, 0x02, 0x34, 0x10, 0x00, 0xB2, 0x8F, 0x0C, 0x00, 0xB1, 0x8F,
+0x08, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, 0x21, 0x18, 0xA0, 0x00,
+0x00, 0x00, 0xA4, 0xAF, 0x04, 0x00, 0xA5, 0xAF, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x2B, 0x10, 0x47, 0x00, 0xD2, 0x00, 0x40, 0x10,
+0x00, 0x01, 0xE3, 0x2C, 0xFF, 0x00, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24,
+0xFF, 0xFF, 0x42, 0x34, 0x2B, 0x10, 0x47, 0x00, 0x18, 0x00, 0x04, 0x24,
+0x21, 0x28, 0x60, 0x00, 0x0B, 0x28, 0x82, 0x00, 0x06, 0x10, 0xA8, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00,
+0x23, 0x30, 0x44, 0x00, 0xCE, 0x00, 0xC0, 0x14, 0x23, 0x38, 0x46, 0x00,
+0x2B, 0x10, 0x0A, 0x01, 0x04, 0x00, 0x40, 0x14, 0x23, 0x20, 0xEC, 0x01,
+0x2B, 0x10, 0xEC, 0x01, 0x05, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0xE4, 0x01, 0x23, 0x18, 0x48, 0x01, 0x23, 0x50, 0x62, 0x00,
+0x21, 0x78, 0x80, 0x00, 0x04, 0x00, 0x40, 0x12, 0x21, 0xC0, 0xE0, 0x01,
+0x21, 0xC8, 0x40, 0x01, 0x00, 0x00, 0x58, 0xAE, 0x04, 0x00, 0x59, 0xAE,
+0x00, 0x00, 0xA2, 0x8F, 0x04, 0x00, 0xA3, 0x8F, 0x10, 0x00, 0xB2, 0x8F,
+0x0C, 0x00, 0xB1, 0x8F, 0x08, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x53, 0x00, 0xC0, 0x10, 0x01, 0x00, 0x02, 0x24,
+0xFF, 0xFF, 0x02, 0x34, 0x2B, 0x10, 0x4C, 0x00, 0x59, 0x00, 0x40, 0x14,
+0xFF, 0x00, 0x02, 0x3C, 0x00, 0x01, 0x83, 0x2D, 0x08, 0x00, 0x02, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x0A, 0x28, 0x43, 0x00, 0x06, 0x10, 0xAC, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00,
+0x23, 0x30, 0x44, 0x00, 0x5B, 0x00, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x23, 0x50, 0x4C, 0x01, 0x02, 0x4C, 0x0C, 0x00, 0xFF, 0xFF, 0x8D, 0x31,
+0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x12, 0x18, 0x00, 0x00,
+0x10, 0x28, 0x00, 0x00, 0x00, 0x14, 0x05, 0x00, 0x25, 0x28, 0x44, 0x00,
+0x18, 0x00, 0x6D, 0x00, 0x12, 0x58, 0x00, 0x00, 0x2B, 0x18, 0xAB, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0x08, 0x00, 0x60, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xAC, 0x00, 0x2B, 0x10, 0xAC, 0x00,
+0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xAB, 0x00, 0x00, 0x00, 0x42, 0x38,
+0x21, 0x18, 0xAC, 0x00, 0x0B, 0x28, 0x62, 0x00, 0x23, 0x28, 0xAB, 0x00,
+0x1B, 0x00, 0xA9, 0x00, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xE4, 0x31, 0x12, 0x18, 0x00, 0x00,
+0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x6D, 0x00, 0x00, 0x14, 0x08, 0x00, 0x12, 0x58, 0x00, 0x00,
+0x25, 0x40, 0x44, 0x00, 0x2B, 0x18, 0x0B, 0x01, 0x1B, 0x00, 0xA9, 0x00,
+0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00,
+0x08, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x0C, 0x01,
+0x2B, 0x10, 0x0C, 0x01, 0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0x0B, 0x01,
+0x21, 0x18, 0x0C, 0x01, 0x00, 0x00, 0x42, 0x38, 0x0B, 0x40, 0x62, 0x00,
+0xAB, 0xFF, 0x40, 0x12, 0x23, 0x78, 0x0B, 0x01, 0x06, 0xC0, 0xCF, 0x00,
+0x21, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xAE, 0xA1, 0x63, 0x00, 0x08,
+0x04, 0x00, 0x59, 0xAE, 0x1B, 0x00, 0x47, 0x00, 0x02, 0x00, 0xE0, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x02, 0x34,
+0x12, 0x60, 0x00, 0x00, 0x2B, 0x10, 0x4C, 0x00, 0xAB, 0xFF, 0x40, 0x10,
+0x00, 0x01, 0x83, 0x2D, 0xFF, 0x00, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24,
+0xFF, 0xFF, 0x42, 0x34, 0x2B, 0x10, 0x4C, 0x00, 0x18, 0x00, 0x04, 0x24,
+0x21, 0x28, 0x60, 0x00, 0x0B, 0x28, 0x82, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x06, 0x10, 0xAC, 0x00, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00,
+0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00,
+0x23, 0x30, 0x44, 0x00, 0xA7, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x23, 0x38, 0x46, 0x00, 0x04, 0x60, 0xCC, 0x00, 0x06, 0x58, 0xEA, 0x00,
+0x02, 0x4C, 0x0C, 0x00, 0x1B, 0x00, 0x69, 0x01, 0x02, 0x00, 0x20, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x8D, 0x31,
+0x06, 0x18, 0xEF, 0x00, 0x04, 0x10, 0xCA, 0x00, 0x25, 0x50, 0x43, 0x00,
+0x02, 0x24, 0x0A, 0x00, 0x12, 0x28, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00,
+0x00, 0x14, 0x08, 0x00, 0x25, 0x40, 0x44, 0x00, 0x18, 0x00, 0xAD, 0x00,
+0x12, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x1B, 0x00, 0x69, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0x05, 0x00, 0x60, 0x10, 0x04, 0x78, 0xCF, 0x00,
+0x21, 0x40, 0x0C, 0x01, 0x2B, 0x10, 0x0C, 0x01, 0x93, 0x00, 0x40, 0x10,
+0x2B, 0x10, 0x05, 0x01, 0x23, 0x40, 0x05, 0x01, 0x1B, 0x00, 0x09, 0x01,
+0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00,
+0xFF, 0xFF, 0x44, 0x31, 0x12, 0x18, 0x00, 0x00, 0x10, 0x58, 0x00, 0x00,
+0x00, 0x14, 0x0B, 0x00, 0x25, 0x58, 0x44, 0x00, 0x18, 0x00, 0x6D, 0x00,
+0x12, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x65, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x1B, 0x00, 0x09, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0x77, 0xFF, 0x60, 0x10, 0x23, 0x50, 0x65, 0x01,
+0x21, 0x58, 0x6C, 0x01, 0x2B, 0x10, 0x6C, 0x01, 0x04, 0x00, 0x40, 0x14,
+0x2B, 0x10, 0x65, 0x01, 0x00, 0x00, 0x42, 0x38, 0x21, 0x18, 0x6C, 0x01,
+0x0B, 0x58, 0x62, 0x00, 0xBF, 0x63, 0x00, 0x08, 0x23, 0x50, 0x65, 0x01,
+0x08, 0x00, 0x02, 0x24, 0x21, 0x28, 0x00, 0x00, 0x0A, 0x28, 0x43, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x06, 0x10, 0xA8, 0x00, 0x98, 0xF2, 0x63, 0x24,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24,
+0x21, 0x20, 0x85, 0x00, 0x23, 0x30, 0x44, 0x00, 0x34, 0xFF, 0xC0, 0x10,
+0x23, 0x38, 0x46, 0x00, 0x06, 0x10, 0xEC, 0x00, 0x04, 0x18, 0xC8, 0x00,
+0x25, 0x40, 0x62, 0x00, 0x06, 0x58, 0xEA, 0x00, 0x02, 0x6C, 0x08, 0x00,
+0x1B, 0x00, 0x6D, 0x01, 0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x11, 0x31, 0x06, 0x10, 0xEF, 0x00,
+0x04, 0x18, 0xCA, 0x00, 0x25, 0x50, 0x62, 0x00, 0x02, 0x24, 0x0A, 0x00,
+0x04, 0x60, 0xCC, 0x00, 0x12, 0x80, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00,
+0x00, 0x14, 0x09, 0x00, 0x25, 0x48, 0x44, 0x00, 0x12, 0x28, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x11, 0x02,
+0x12, 0x70, 0x00, 0x00, 0x2B, 0x18, 0x2E, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x1B, 0x00, 0x6D, 0x01, 0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x07, 0x00, 0x0A, 0x00, 0x60, 0x10, 0x04, 0x78, 0xCF, 0x00,
+0x21, 0x48, 0x28, 0x01, 0x2B, 0x10, 0x28, 0x01, 0x06, 0x00, 0x40, 0x14,
+0xFF, 0xFF, 0xB0, 0x24, 0x2B, 0x10, 0x2E, 0x01, 0x03, 0x00, 0x40, 0x10,
+0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x26, 0x21, 0x48, 0x28, 0x01,
+0x23, 0x48, 0x2E, 0x01, 0x1B, 0x00, 0x2D, 0x01, 0x02, 0x00, 0xA0, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x44, 0x31,
+0x12, 0x28, 0x00, 0x00, 0x10, 0x58, 0x00, 0x00, 0x00, 0x14, 0x0B, 0x00,
+0x25, 0x58, 0x44, 0x00, 0x18, 0x00, 0xB1, 0x00, 0x12, 0x70, 0x00, 0x00,
+0x2B, 0x18, 0x6E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x2D, 0x01,
+0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00,
+0x0B, 0x00, 0x60, 0x10, 0x00, 0x14, 0x10, 0x00, 0x21, 0x58, 0x68, 0x01,
+0x2B, 0x10, 0x68, 0x01, 0x06, 0x00, 0x40, 0x14, 0xFF, 0xFF, 0xA5, 0x24,
+0x2B, 0x10, 0x6E, 0x01, 0x04, 0x00, 0x40, 0x10, 0x00, 0x14, 0x10, 0x00,
+0xFF, 0xFF, 0xA5, 0x24, 0x21, 0x58, 0x68, 0x01, 0x00, 0x14, 0x10, 0x00,
+0x25, 0x10, 0x45, 0x00, 0x23, 0x58, 0x6E, 0x01, 0x19, 0x00, 0x4C, 0x00,
+0x10, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x65, 0x01, 0x12, 0x48, 0x00, 0x00,
+0x05, 0x00, 0x60, 0x14, 0x23, 0x20, 0x2C, 0x01, 0x07, 0x00, 0xAB, 0x14,
+0x2B, 0x10, 0xE9, 0x01, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00,
+0x2B, 0x10, 0x24, 0x01, 0x23, 0x18, 0xA8, 0x00, 0x23, 0x28, 0x62, 0x00,
+0x21, 0x48, 0x80, 0x00, 0xEA, 0xFE, 0x40, 0x12, 0x23, 0x18, 0xE9, 0x01,
+0x23, 0x20, 0x65, 0x01, 0x2B, 0x10, 0xE3, 0x01, 0x23, 0x50, 0x82, 0x00,
+0x04, 0x28, 0xEA, 0x00, 0x06, 0x18, 0xC3, 0x00, 0x25, 0xC0, 0xA3, 0x00,
+0x06, 0xC8, 0xCA, 0x00, 0x00, 0x00, 0x58, 0xAE, 0xA1, 0x63, 0x00, 0x08,
+0x04, 0x00, 0x59, 0xAE, 0x00, 0x01, 0xC3, 0x2C, 0x08, 0x00, 0x02, 0x24,
+0x21, 0x30, 0x00, 0x00, 0x3B, 0x63, 0x00, 0x08, 0x0A, 0x30, 0x43, 0x00,
+0x00, 0x00, 0x42, 0x38, 0x21, 0x18, 0x0C, 0x01, 0x35, 0x64, 0x00, 0x08,
+0x0B, 0x40, 0x62, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x4D, 0x00, 0x64, 0x34,
+0xF1, 0x02, 0x65, 0x34, 0x08, 0x00, 0x02, 0x24, 0x00, 0x00, 0x80, 0xA0,
+0xEC, 0x02, 0x66, 0x34, 0x00, 0x00, 0xA2, 0xA0, 0xF0, 0x02, 0x63, 0x34,
+0xFF, 0x00, 0x02, 0x3C, 0x00, 0x00, 0x60, 0xA0, 0x00, 0x00, 0xC2, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x60, 0x93, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x7F, 0x00, 0x02, 0x3C, 0x0D, 0xB8, 0x44, 0x34, 0x80, 0x04, 0x03, 0x3C,
+0x25, 0x20, 0x83, 0x00, 0x00, 0x08, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00,
+0x00, 0x30, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0x25, 0x20, 0x83, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC,
+0xD8, 0x1B, 0x44, 0xAC, 0xD0, 0x1B, 0x44, 0xAC, 0x08, 0x00, 0x63, 0x34,
+0x86, 0x00, 0x04, 0x24, 0x00, 0x00, 0x64, 0xA4, 0xDC, 0x1B, 0x44, 0xA4,
+0xD4, 0x1B, 0x40, 0xAC, 0xDE, 0x1B, 0x40, 0xA4, 0x08, 0x00, 0xE0, 0x03,
+0xE0, 0x1B, 0x44, 0xA4, 0xF5, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x42, 0xB0, 0x03, 0x3C, 0x01, 0x00, 0x63, 0x34, 0x02, 0x00, 0x02, 0x24,
+0xE8, 0xFF, 0xBD, 0x27, 0x00, 0x00, 0x62, 0xA0, 0x10, 0x00, 0xBF, 0xAF,
+0x85, 0x2B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00,
+0x01, 0x00, 0x05, 0x24, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0x50, 0x06, 0x24,
+0x1F, 0x00, 0x06, 0x3C, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x40, 0xC6, 0x34,
+0x03, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0xB9, 0x20, 0x00, 0x08,
+0x18, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0x64, 0x34, 0x28, 0x94, 0x42, 0x24,
+0x00, 0x00, 0x82, 0xAC, 0x30, 0x00, 0xBE, 0xAF, 0x2C, 0x00, 0xB7, 0xAF,
+0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF,
+0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF,
+0x34, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0xB6, 0x00, 0x63, 0x34,
+0x00, 0x00, 0x64, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24,
+0x48, 0x01, 0x03, 0x24, 0x70, 0x37, 0x43, 0xAC, 0x6C, 0x37, 0x43, 0xAC,
+0xAB, 0x1B, 0x44, 0xA0, 0xC6, 0x3D, 0x40, 0xA0, 0x66, 0x37, 0x40, 0xA0,
+0x84, 0x6C, 0x00, 0x0C, 0x21, 0x98, 0x40, 0x00, 0xFD, 0xFF, 0x02, 0x3C,
+0xFB, 0xFF, 0x03, 0x3C, 0x21, 0xA0, 0x60, 0x02, 0xFF, 0xFF, 0x55, 0x34,
+0xFF, 0xFF, 0x76, 0x34, 0x21, 0x88, 0x00, 0x00, 0x02, 0x80, 0x1E, 0x3C,
+0x02, 0x80, 0x17, 0x3C, 0x21, 0x90, 0x60, 0x02, 0x40, 0x10, 0x11, 0x00,
+0x21, 0x10, 0x51, 0x00, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x53, 0x00,
+0xD4, 0x1D, 0x42, 0x24, 0x07, 0x00, 0x03, 0x24, 0xFF, 0xFF, 0x63, 0x24,
+0x00, 0x00, 0x40, 0xA4, 0xFD, 0xFF, 0x61, 0x04, 0x02, 0x00, 0x42, 0x24,
+0xC0, 0x80, 0x11, 0x00, 0x34, 0x3F, 0xC4, 0x27, 0x21, 0x20, 0x04, 0x02,
+0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x06, 0x24, 0xE4, 0x1D, 0x40, 0xA6,
+0xEC, 0x54, 0x00, 0x0C, 0xE6, 0x1D, 0x40, 0xA2, 0x21, 0x20, 0x13, 0x02,
+0xD4, 0x23, 0x83, 0x8C, 0xD2, 0x5C, 0xE7, 0x92, 0xBF, 0xFF, 0x02, 0x24,
+0x24, 0x28, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, 0x63, 0x00, 0xE2, 0x10,
+0x80, 0x07, 0xA6, 0x34, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x10, 0xC3, 0x00,
+0xFF, 0xEF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xD4, 0x23, 0x82, 0xAC,
+0x21, 0x30, 0x14, 0x02, 0xD4, 0x23, 0xC4, 0x8C, 0xE7, 0xFF, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x95, 0x00, 0x24, 0x20, 0x96, 0x00,
+0xFF, 0xFD, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00, 0xFF, 0xFF, 0x63, 0x34,
+0xFF, 0xFB, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00, 0xD8, 0x23, 0xC5, 0x8C,
+0xFF, 0xFF, 0x42, 0x34, 0xFF, 0xE7, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00,
+0xFF, 0xFF, 0x63, 0x34, 0xFF, 0xFF, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00,
+0xFF, 0x7F, 0x42, 0x34, 0xC0, 0xFF, 0x03, 0x24, 0x24, 0x28, 0xA2, 0x00,
+0x24, 0x20, 0x83, 0x00, 0x1F, 0x00, 0x02, 0x3C, 0x01, 0x00, 0x31, 0x26,
+0x25, 0x28, 0xA2, 0x00, 0x08, 0x00, 0x84, 0x34, 0x20, 0x00, 0x22, 0x2A,
+0xD4, 0x23, 0xC4, 0xAC, 0xD8, 0x23, 0xC5, 0xAC, 0xC3, 0xFF, 0x40, 0x14,
+0x30, 0x00, 0x52, 0x26, 0x25, 0xB0, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24,
+0xB0, 0x03, 0x42, 0x34, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xAC,
+0x88, 0x1E, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0xEC, 0x54, 0x00, 0x0C,
+0x20, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x60, 0x10, 0x02, 0x80, 0x03, 0x3C,
+0x60, 0x1B, 0x62, 0x24, 0x25, 0x03, 0x40, 0xA0, 0xC2, 0x6F, 0x00, 0x74,
+0x24, 0x03, 0x40, 0xA0, 0xD8, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x47, 0x6C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F,
+0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F,
+0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x02, 0x80, 0x09, 0x3C, 0x02, 0x80, 0x0A, 0x3C, 0x02, 0x80, 0x0B, 0x3C,
+0x02, 0x80, 0x0C, 0x3C, 0x02, 0x80, 0x0D, 0x3C, 0x02, 0x80, 0x0E, 0x3C,
+0x02, 0x80, 0x0F, 0x3C, 0x88, 0x54, 0x22, 0x25, 0x90, 0x54, 0x43, 0x25,
+0x98, 0x54, 0x64, 0x25, 0xA0, 0x54, 0x85, 0x25, 0xA8, 0x54, 0xA6, 0x25,
+0xB0, 0x54, 0xC7, 0x25, 0xB8, 0x54, 0xE8, 0x25, 0x38, 0x00, 0xBD, 0x27,
+0x04, 0x00, 0x42, 0xAC, 0x88, 0x54, 0x22, 0xAD, 0x04, 0x00, 0x63, 0xAC,
+0x90, 0x54, 0x43, 0xAD, 0x04, 0x00, 0x84, 0xAC, 0x98, 0x54, 0x64, 0xAD,
+0x04, 0x00, 0xA5, 0xAC, 0xA0, 0x54, 0x85, 0xAD, 0x04, 0x00, 0xC6, 0xAC,
+0xA8, 0x54, 0xA6, 0xAD, 0x04, 0x00, 0xE7, 0xAC, 0xB0, 0x54, 0xC7, 0xAD,
+0xB8, 0x54, 0xE8, 0xAD, 0x08, 0x00, 0xE0, 0x03, 0x04, 0x00, 0x08, 0xAD,
+0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x9C, 0xFF, 0x67, 0x14, 0x80, 0x0F, 0xA2, 0x34, 0xFF, 0xF7, 0x03, 0x24,
+0x24, 0x10, 0xC3, 0x00, 0x4D, 0x65, 0x00, 0x08, 0x00, 0x10, 0x42, 0x34,
+0x7A, 0x6D, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x6F, 0x00, 0x74,
+0x24, 0x39, 0x80, 0xAE, 0x26, 0x70, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x64, 0x90, 0x92, 0x00, 0x02, 0x24,
+0x03, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x74,
+0x00, 0x00, 0x00, 0x00, 0xC1, 0x70, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00,
+0x7B, 0x65, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0xC8, 0xFF, 0xBD, 0x27, 0x14, 0x97, 0x63, 0x24,
+0x18, 0x03, 0x42, 0x34, 0x18, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF,
+0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF,
+0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x00, 0x00, 0x43, 0xAC, 0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26,
+0xFF, 0xFF, 0x50, 0x30, 0x64, 0x00, 0x03, 0x2E, 0xFD, 0xFF, 0x60, 0x14,
+0x01, 0x00, 0x02, 0x26, 0x64, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x14, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xC3, 0x5C, 0x68, 0x90, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xC0, 0x5C, 0x4B, 0x94, 0xDB, 0x5C, 0x6A, 0x90,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xE2, 0x5C, 0x67, 0x90,
+0xD0, 0x5C, 0x49, 0x90, 0xC2, 0x5C, 0x83, 0x92, 0x02, 0x80, 0x0C, 0x3C,
+0x02, 0x80, 0x02, 0x3C, 0xDD, 0x5C, 0x46, 0x90, 0xE0, 0x5C, 0x85, 0x91,
+0x25, 0xB0, 0x04, 0x3C, 0xB0, 0x03, 0x82, 0x34, 0x00, 0x00, 0x4B, 0xAC,
+0x00, 0x00, 0x48, 0xAC, 0x00, 0x00, 0x49, 0xAC, 0x00, 0x00, 0x43, 0xAC,
+0x02, 0x80, 0x03, 0x3C, 0x00, 0x00, 0x4A, 0xAC, 0x0A, 0x00, 0x88, 0x34,
+0x00, 0x00, 0x46, 0xAC, 0x00, 0x00, 0x45, 0xAC, 0x00, 0x00, 0x47, 0xAC,
+0x0C, 0x5D, 0x60, 0xA4, 0x00, 0x00, 0x06, 0x91, 0x02, 0x80, 0x02, 0x3C,
+0x0B, 0x00, 0x04, 0x24, 0x02, 0x80, 0x13, 0x3C, 0xCD, 0x5C, 0x44, 0xA0,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x65, 0x26, 0x00, 0x70, 0x03, 0x24,
+0xF0, 0x5C, 0x40, 0xA0, 0xF0, 0xFF, 0x02, 0x24, 0x01, 0x00, 0x07, 0x24,
+0x02, 0x80, 0x16, 0x3C, 0xAC, 0x1B, 0xA3, 0xA4, 0xAA, 0x1B, 0xA2, 0xA0,
+0xFF, 0x07, 0x03, 0x24, 0xFF, 0xFF, 0x02, 0x24, 0x20, 0x00, 0xC6, 0x30,
+0xE0, 0x5C, 0x87, 0xA1, 0xA8, 0x1B, 0xA7, 0xA0, 0xAE, 0x1B, 0xA3, 0xA4,
+0x48, 0xF5, 0xC2, 0xA2, 0x9A, 0x00, 0xC0, 0x10, 0xB0, 0x1B, 0xA0, 0xA4,
+0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30,
+0x0B, 0x01, 0x40, 0x14, 0x02, 0x80, 0x15, 0x3C, 0x21, 0x80, 0x00, 0x00,
+0x21, 0x88, 0x00, 0x00, 0x98, 0xF3, 0xB2, 0x26, 0xFF, 0x00, 0x24, 0x32,
+0xCF, 0x59, 0x00, 0x0C, 0x21, 0x28, 0x12, 0x02, 0x08, 0x00, 0x03, 0x26,
+0xFF, 0xFF, 0x70, 0x30, 0x01, 0x00, 0x22, 0x26, 0x80, 0x00, 0x03, 0x2E,
+0xF8, 0xFF, 0x60, 0x14, 0xFF, 0xFF, 0x51, 0x30, 0xC2, 0x5C, 0x83, 0x92,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x30, 0xCA, 0x00, 0x40, 0x14,
+0x04, 0x00, 0x62, 0x30, 0x83, 0x00, 0x40, 0x10, 0x25, 0xB0, 0x03, 0x3C,
+0x25, 0xB0, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x50, 0x00, 0x84, 0x34,
+0xE7, 0xF3, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24,
+0x98, 0xF3, 0xA3, 0x26, 0x7B, 0x00, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0xE2, 0x2C, 0x04, 0x00, 0x40, 0x14, 0x02, 0x00, 0x0B, 0x24,
+0x79, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4B, 0x30,
+0x04, 0x00, 0xE2, 0x2C, 0xEC, 0x00, 0x40, 0x10, 0x98, 0xF3, 0xA2, 0x26,
+0x60, 0x1B, 0x62, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x02, 0x80, 0x12, 0x3C,
+0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x4A, 0xF5, 0x60, 0xA0,
+0x60, 0x1B, 0x62, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0xCF, 0x5C, 0x43, 0x90,
+0x01, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x10, 0xFC, 0xFF, 0x08, 0x24,
+0x21, 0x40, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x98, 0xF3, 0x4A, 0x24, 0x60, 0x1B, 0x69, 0x24, 0x21, 0x60, 0x00, 0x00,
+0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26, 0x21, 0x30, 0x30, 0x01,
+0x03, 0x00, 0x03, 0x2E, 0x08, 0x00, 0x04, 0x2E, 0xFF, 0xFF, 0x50, 0x30,
+0x0E, 0x00, 0x07, 0x2E, 0x04, 0x00, 0x60, 0x14, 0x21, 0x88, 0x00, 0x00,
+0x01, 0x00, 0x11, 0x24, 0x02, 0x00, 0x02, 0x24, 0x0A, 0x88, 0x44, 0x00,
+0x21, 0x10, 0x51, 0x01, 0x61, 0x00, 0x43, 0x90, 0x55, 0x00, 0x44, 0x90,
+0x5B, 0x00, 0x45, 0x90, 0x21, 0x18, 0x03, 0x01, 0x21, 0x20, 0x04, 0x01,
+0x21, 0x28, 0x05, 0x01, 0x9C, 0x1D, 0xC3, 0xA0, 0x64, 0x1D, 0xC4, 0xA0,
+0xEB, 0xFF, 0xE0, 0x14, 0x80, 0x1D, 0xC5, 0xA0, 0x01, 0x00, 0x8C, 0x25,
+0x02, 0x00, 0x82, 0x2D, 0x0E, 0x00, 0x29, 0x25, 0xE5, 0xFF, 0x40, 0x14,
+0x03, 0x00, 0x4A, 0x25, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x60, 0x1B, 0x47, 0x24, 0x98, 0xF3, 0x66, 0x24, 0x21, 0x80, 0x00, 0x00,
+0x03, 0x00, 0x02, 0x2E, 0x21, 0x20, 0x07, 0x02, 0xD1, 0x00, 0x40, 0x10,
+0x08, 0x00, 0x03, 0x2E, 0x71, 0x00, 0xC3, 0x90, 0x6E, 0x00, 0xC2, 0x90,
+0x00, 0x00, 0x00, 0x00, 0xC6, 0x1D, 0x82, 0xA0, 0xB8, 0x1D, 0x83, 0xA0,
+0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x03, 0x2E,
+0xF4, 0xFF, 0x60, 0x14, 0x03, 0x00, 0x02, 0x2E, 0x03, 0x00, 0x02, 0x24,
+0x51, 0x00, 0x62, 0x15, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x98, 0xF3, 0x4E, 0x24, 0xC0, 0xD9, 0x6F, 0x24, 0x21, 0x60, 0x00, 0x00,
+0x21, 0x68, 0x00, 0x00, 0x21, 0x10, 0xAE, 0x01, 0x74, 0x00, 0x43, 0x90,
+0x21, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x6A, 0x30, 0x02, 0x49, 0x03, 0x00,
+0x21, 0x10, 0xB0, 0x01, 0x00, 0x11, 0x02, 0x00, 0x21, 0x58, 0x4F, 0x00,
+0x21, 0x38, 0x00, 0x00, 0x21, 0x40, 0x67, 0x01, 0x00, 0x00, 0x03, 0x91,
+0x00, 0x31, 0x09, 0x00, 0x01, 0x00, 0xE7, 0x24, 0x02, 0x11, 0x03, 0x00,
+0x00, 0x21, 0x02, 0x00, 0x0F, 0x00, 0x63, 0x30, 0x2B, 0x10, 0x49, 0x00,
+0x0A, 0x20, 0xC2, 0x00, 0x2B, 0x28, 0x6A, 0x00, 0x00, 0x00, 0xA5, 0x38,
+0x25, 0x18, 0x83, 0x00, 0xFF, 0xFF, 0xE7, 0x30, 0x25, 0x20, 0x8A, 0x00,
+0x0A, 0x18, 0x85, 0x00, 0x10, 0x00, 0xE2, 0x2C, 0xEF, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x03, 0xA1, 0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30,
+0x03, 0x00, 0x03, 0x2E, 0xE7, 0xFF, 0x60, 0x14, 0x21, 0x10, 0xB0, 0x01,
+0x01, 0x00, 0x8C, 0x25, 0x02, 0x00, 0x82, 0x2D, 0xDD, 0xFF, 0x40, 0x14,
+0x03, 0x00, 0xAD, 0x25, 0xCC, 0x66, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x03, 0x3C, 0x4C, 0x87, 0x02, 0x3C, 0x54, 0x00, 0x65, 0x34,
+0x00, 0xE0, 0x42, 0x34, 0x50, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC,
+0x12, 0x01, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x00, 0x00, 0xA4, 0xAC,
+0x60, 0x1B, 0x46, 0x24, 0x21, 0x60, 0x00, 0x00, 0x10, 0x00, 0x05, 0x24,
+0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26, 0x21, 0x18, 0xD0, 0x00,
+0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x04, 0x2E, 0x80, 0x1D, 0x65, 0xA0,
+0x64, 0x1D, 0x65, 0xA0, 0xF9, 0xFF, 0x80, 0x14, 0x9C, 0x1D, 0x65, 0xA0,
+0x01, 0x00, 0x8C, 0x25, 0x02, 0x00, 0x82, 0x2D, 0xF4, 0xFF, 0x40, 0x14,
+0x0E, 0x00, 0xC6, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x46, 0x24,
+0x21, 0x80, 0x00, 0x00, 0x04, 0x00, 0x05, 0x24, 0x01, 0x00, 0x02, 0x26,
+0x21, 0x18, 0x06, 0x02, 0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x04, 0x2E,
+0xC6, 0x1D, 0x60, 0xA0, 0xFA, 0xFF, 0x80, 0x14, 0xB8, 0x1D, 0x65, 0xA0,
+0x02, 0x80, 0x12, 0x3C, 0xC6, 0x5C, 0x43, 0x92, 0x01, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x54, 0x59, 0x00, 0x0C, 0x4B, 0xF5, 0x43, 0xA0,
+0x48, 0xF5, 0xC5, 0x26, 0xFF, 0x58, 0x00, 0x0C, 0xFA, 0x01, 0x04, 0x24,
+0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x25, 0xB0, 0x05, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x50, 0x00, 0xA5, 0x34,
+0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x60, 0x1B, 0x65, 0x26,
+0x01, 0x00, 0x02, 0x24, 0x06, 0x00, 0x03, 0x24, 0x05, 0x00, 0x04, 0x24,
+0x33, 0x1C, 0xA2, 0xA0, 0x6F, 0x58, 0x00, 0x0C, 0xC4, 0x3D, 0xA3, 0xA0,
+0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F,
+0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F,
+0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x38, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x50, 0x00, 0x84, 0x34, 0xAA, 0xF3, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C,
+0x06, 0x00, 0x06, 0x24, 0x98, 0xF3, 0xA2, 0x92, 0x98, 0xF3, 0xA5, 0x26,
+0x01, 0x00, 0xA4, 0x90, 0x21, 0x18, 0x40, 0x00, 0x10, 0x00, 0xA2, 0xA3,
+0x29, 0x00, 0x02, 0x24, 0x11, 0x00, 0xA4, 0xA3, 0x50, 0x00, 0xA7, 0x90,
+0x4F, 0x00, 0x62, 0x10, 0x02, 0x80, 0x12, 0x3C, 0x98, 0xF3, 0xA6, 0x26,
+0x68, 0x00, 0xC2, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x04, 0x00, 0xE4, 0x2C,
+0x1F, 0x00, 0x42, 0x30, 0x34, 0x00, 0x80, 0x14, 0x49, 0xF5, 0x62, 0xA0,
+0x7A, 0x00, 0xC4, 0x90, 0x60, 0x1B, 0x65, 0x8E, 0x79, 0x00, 0xC6, 0x90,
+0x01, 0x00, 0x83, 0x30, 0xBF, 0xFF, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00,
+0x80, 0x19, 0x03, 0x00, 0x04, 0x00, 0x84, 0x30, 0x25, 0x28, 0xA3, 0x00,
+0x83, 0x20, 0x04, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x03, 0x00, 0xCB, 0x30,
+0x4A, 0xF5, 0x44, 0xA0, 0x60, 0x1B, 0x65, 0xAE, 0x06, 0x00, 0xE2, 0x2C,
+0x2C, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x98, 0xF3, 0xA3, 0x26,
+0x69, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30,
+0x26, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x45, 0x66, 0x00, 0x08,
+0x21, 0x40, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x80, 0x00, 0x05, 0x24,
+0xC1, 0x58, 0x00, 0x0C, 0x98, 0xF3, 0xA6, 0x26, 0x1F, 0x66, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x43, 0x90, 0x69, 0x00, 0x46, 0x90,
+0x7D, 0x00, 0x44, 0x90, 0x60, 0x1B, 0x65, 0x8E, 0xBF, 0xFF, 0x02, 0x24,
+0x01, 0x00, 0x63, 0x30, 0x24, 0x28, 0xA2, 0x00, 0x01, 0x00, 0xC6, 0x30,
+0x04, 0x00, 0x84, 0x30, 0x80, 0x19, 0x03, 0x00, 0x25, 0x28, 0xA3, 0x00,
+0x83, 0x20, 0x04, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0xC6, 0x2C,
+0x4A, 0xF5, 0x44, 0xA0, 0x60, 0x1B, 0x65, 0xAE, 0x0B, 0xFF, 0xC0, 0x10,
+0x02, 0x80, 0x12, 0x3C, 0x45, 0x66, 0x00, 0x08, 0x21, 0x40, 0x00, 0x00,
+0x60, 0x1B, 0x62, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x02, 0x80, 0x04, 0x3C,
+0x24, 0x10, 0x43, 0x00, 0x02, 0x00, 0x0B, 0x24, 0x4A, 0xF5, 0x80, 0xA0,
+0x12, 0x67, 0x00, 0x08, 0x60, 0x1B, 0x62, 0xAE, 0x21, 0x28, 0x07, 0x02,
+0x06, 0x00, 0x60, 0x10, 0x21, 0x20, 0xA0, 0x00, 0x67, 0x00, 0xC3, 0x90,
+0x6F, 0x00, 0xC2, 0x90, 0xB8, 0x1D, 0xA3, 0xA0, 0x74, 0x66, 0x00, 0x08,
+0xC6, 0x1D, 0xA2, 0xA0, 0x72, 0x00, 0xC3, 0x90, 0x70, 0x00, 0xC2, 0x90,
+0x73, 0x66, 0x00, 0x08, 0xC6, 0x1D, 0x82, 0xA0, 0xFF, 0x00, 0x83, 0x30,
+0x81, 0x00, 0x02, 0x24, 0xB0, 0xFF, 0x62, 0x14, 0x98, 0xF3, 0xA6, 0x26,
+0x54, 0x00, 0xA3, 0x90, 0x01, 0x00, 0x02, 0x24, 0x09, 0x00, 0x62, 0x10,
+0x02, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x10, 0x11, 0x00, 0x02, 0x24,
+0x02, 0x80, 0x12, 0x3C, 0xFE, 0x66, 0x00, 0x08, 0xC6, 0x5C, 0x42, 0xA2,
+0x22, 0x00, 0x02, 0x24, 0xFD, 0x66, 0x00, 0x08, 0xC6, 0x5C, 0x42, 0xA2,
+0x02, 0x80, 0x12, 0x3C, 0x12, 0x00, 0x02, 0x24, 0xFD, 0x66, 0x00, 0x08,
+0xC6, 0x5C, 0x42, 0xA2, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF,
+0x02, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x11, 0x3C, 0x18, 0x03, 0x23, 0x36,
+0x7C, 0x9D, 0x42, 0x24, 0x20, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C,
+0x00, 0x00, 0x62, 0xAC, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF,
+0xC5, 0x65, 0x00, 0x0C, 0x60, 0x1B, 0x50, 0x26, 0x08, 0x68, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xA3, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x87, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x6D, 0x00, 0x74,
+0x00, 0x00, 0x00, 0x00, 0xEF, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0xC4, 0x3D, 0x04, 0x92, 0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0xCB, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x82, 0x40, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x23, 0x36, 0x00, 0x00, 0x62, 0x94,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA4,
+0x0A, 0x65, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x64, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0xF7, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x53, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6B, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x3C, 0x68, 0x61, 0x84, 0x24,
+0x70, 0x6B, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x00, 0x80, 0x04, 0x3C,
+0xD0, 0x67, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C, 0x02, 0x00, 0x05, 0x24,
+0x00, 0x80, 0x04, 0x3C, 0x39, 0x6F, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C,
+0x04, 0x00, 0x05, 0x24, 0x44, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x80, 0x04, 0x3C, 0x6C, 0x83, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C,
+0x03, 0x00, 0x05, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xD0, 0x5C, 0x63, 0x90,
+0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x60, 0x10, 0x43, 0x00, 0x22, 0x36,
+0x07, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24,
+0x25, 0xB0, 0x04, 0x3C, 0x43, 0x00, 0x85, 0x34, 0x10, 0x02, 0x86, 0x34,
+0x10, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA0, 0xD8, 0x00, 0x84, 0x34,
+0x00, 0x00, 0xC3, 0xA0, 0x00, 0x00, 0x82, 0x90, 0x80, 0xFF, 0x03, 0x24,
+0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA0, 0xDF, 0x64, 0x00, 0x0C,
+0x25, 0xB0, 0x10, 0x3C, 0x44, 0x00, 0x03, 0x36, 0x00, 0x00, 0x62, 0x94,
+0x02, 0x80, 0x04, 0x3C, 0x18, 0xE5, 0x84, 0x24, 0xC0, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x62, 0xA4, 0x13, 0x58, 0x00, 0x0C, 0xF2, 0x00, 0x05, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0xC3, 0x5C, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0x5C, 0xE5, 0x84, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xC2, 0x5C, 0x45, 0x90, 0xC7, 0x5C, 0x66, 0x90,
+0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x6C, 0xE5, 0x84, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x45, 0x90,
+0x48, 0xF5, 0x66, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0xCF, 0x5C, 0x47, 0x90, 0x4A, 0xF5, 0x62, 0x90, 0x02, 0x80, 0x04, 0x3C,
+0x80, 0xE5, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF,
+0xFA, 0x5B, 0x00, 0x0C, 0x80, 0x0C, 0x04, 0x36, 0x02, 0x80, 0x03, 0x3C,
+0x02, 0x80, 0x04, 0x3C, 0xD1, 0x5C, 0x65, 0x90, 0xCE, 0x5C, 0x86, 0x90,
+0x02, 0x80, 0x04, 0x3C, 0x21, 0x38, 0x40, 0x00, 0x13, 0x58, 0x00, 0x0C,
+0x9C, 0xE5, 0x84, 0x24, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xD3, 0x5C, 0x66, 0x90, 0xD2, 0x5C, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xB8, 0xE5, 0x84, 0x24, 0x60, 0x1B, 0x42, 0x26,
+0x54, 0x41, 0x46, 0x8C, 0x58, 0x41, 0x45, 0x8C, 0x02, 0x80, 0x04, 0x3C,
+0x13, 0x58, 0x00, 0x0C, 0xCC, 0xE5, 0x84, 0x24, 0x60, 0x1B, 0x46, 0x8E,
+0x02, 0x80, 0x02, 0x3C, 0x49, 0xF5, 0x45, 0x90, 0x82, 0x31, 0x06, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0xEC, 0xE5, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C,
+0x01, 0x00, 0xC6, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x08, 0x00, 0x84, 0x24,
+0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0x76, 0x39, 0x00, 0x0C,
+0x21, 0x38, 0x00, 0x00, 0xF5, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F,
+0x18, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0xD8, 0x00, 0x24, 0x36, 0x00, 0x00, 0x40, 0xA0,
+0xB0, 0x67, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0xBD, 0x27,
+0x24, 0x00, 0xB1, 0xAF, 0x44, 0x00, 0xBF, 0xAF, 0x40, 0x00, 0xBE, 0xAF,
+0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF, 0x34, 0x00, 0xB5, 0xAF,
+0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, 0x28, 0x00, 0xB2, 0xAF,
+0x20, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0xC2, 0x5C, 0x42, 0x90,
+0x25, 0xB0, 0x11, 0x3C, 0x58, 0x00, 0x25, 0x36, 0x10, 0x00, 0xA2, 0xAF,
+0x4C, 0x81, 0x02, 0x3C, 0x00, 0xE0, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xAC,
+0xFF, 0xFF, 0x04, 0x24, 0x96, 0x01, 0x03, 0x24, 0x28, 0x28, 0x02, 0x24,
+0x5C, 0x00, 0x26, 0x36, 0x60, 0x00, 0x27, 0x36, 0x64, 0x00, 0x28, 0x36,
+0x8A, 0x00, 0x29, 0x36, 0x00, 0x00, 0xC3, 0xAC, 0x00, 0x00, 0xE4, 0xAC,
+0x00, 0x00, 0x04, 0xAD, 0x00, 0x00, 0x22, 0xA5, 0x0E, 0x0E, 0x02, 0x3C,
+0x09, 0x00, 0x03, 0x24, 0x0A, 0x0A, 0x42, 0x34, 0x89, 0x00, 0x2A, 0x36,
+0x8C, 0x00, 0x2B, 0x36, 0x00, 0x00, 0x43, 0xA1, 0x90, 0x00, 0x2C, 0x36,
+0x00, 0x00, 0x62, 0xAD, 0x13, 0x00, 0x03, 0x24, 0x40, 0x00, 0x02, 0x24,
+0x91, 0x00, 0x2D, 0x36, 0x00, 0x00, 0x83, 0xA1, 0x92, 0x00, 0x2E, 0x36,
+0x00, 0x00, 0xA2, 0xA1, 0x3A, 0x01, 0x03, 0x24, 0x21, 0x00, 0x02, 0x24,
+0xB5, 0x00, 0x2F, 0x36, 0x00, 0x00, 0xC3, 0xA5, 0x00, 0x00, 0xE2, 0xA1,
+0x10, 0x00, 0xA2, 0x8F, 0x12, 0x00, 0x03, 0x24, 0x87, 0x01, 0x43, 0x10,
+0x07, 0x07, 0x02, 0x3C, 0x07, 0x07, 0x42, 0x34, 0xA0, 0x00, 0x24, 0x36,
+0x00, 0x00, 0x82, 0xAC, 0xA4, 0x00, 0x25, 0x36, 0x00, 0x07, 0x03, 0x24,
+0x00, 0xC0, 0x02, 0x3C, 0xA8, 0x00, 0x26, 0x36, 0x00, 0x00, 0xA3, 0xAC,
+0x00, 0xC4, 0x42, 0x34, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x00, 0xC2, 0xAC,
+0x60, 0x1B, 0x62, 0x24, 0xAC, 0x1B, 0x45, 0x94, 0xAE, 0x1B, 0x46, 0x94,
+0xAA, 0x1B, 0x42, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x21, 0xB0, 0x07, 0x3C,
+0x14, 0x00, 0xA2, 0xA3, 0xD1, 0x5C, 0x63, 0x90, 0x20, 0xB0, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x18, 0x00, 0xA3, 0xAF, 0x23, 0xB0, 0x03, 0x3C,
+0xFF, 0xFF, 0x63, 0x34, 0x24, 0xB0, 0x08, 0x3C, 0xFF, 0x1F, 0x04, 0x3C,
+0x25, 0xB0, 0x1E, 0x3C, 0xFF, 0xFF, 0x84, 0x34, 0x21, 0x38, 0xA7, 0x00,
+0x21, 0x40, 0xC8, 0x00, 0x21, 0x28, 0xA2, 0x00, 0x21, 0x30, 0xC3, 0x00,
+0x24, 0x40, 0x04, 0x01, 0x24, 0x28, 0xA4, 0x00, 0x24, 0x38, 0xE4, 0x00,
+0x24, 0x30, 0xC4, 0x00, 0x35, 0x00, 0x02, 0x24, 0x20, 0x00, 0xC4, 0x37,
+0x00, 0x00, 0x82, 0xA0, 0x22, 0x00, 0x03, 0x24, 0x09, 0x00, 0x02, 0x24,
+0x03, 0x05, 0xC9, 0x37, 0x60, 0x05, 0xCA, 0x37, 0xAC, 0x00, 0xCB, 0x37,
+0xF8, 0x00, 0xCC, 0x37, 0xB0, 0x00, 0xCD, 0x37, 0x08, 0x01, 0xCE, 0x37,
+0xD8, 0x00, 0xCF, 0x37, 0x00, 0x00, 0x23, 0xA1, 0x00, 0x00, 0x42, 0xA1,
+0x00, 0x00, 0x65, 0xAD, 0x00, 0x00, 0x87, 0xAD, 0x00, 0x00, 0xA6, 0xAD,
+0x00, 0x00, 0xC8, 0xAD, 0x00, 0x00, 0xE0, 0xA1, 0x14, 0x00, 0xA3, 0x93,
+0x25, 0xB0, 0x02, 0x3C, 0xB4, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0,
+0xB6, 0x00, 0xD1, 0x37, 0x04, 0x00, 0x02, 0x24, 0x25, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0x22, 0xA2, 0xB9, 0x00, 0x63, 0x34, 0xFF, 0xFF, 0x02, 0x24,
+0x00, 0x00, 0x62, 0xA0, 0x25, 0xB0, 0x03, 0x3C, 0x0F, 0x00, 0x02, 0x24,
+0xBA, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0xA4, 0xDC, 0x00, 0xD4, 0x37,
+0xFF, 0xCF, 0x03, 0x24, 0x3F, 0x3F, 0x02, 0x24, 0x16, 0x01, 0xD5, 0x37,
+0x00, 0x00, 0x83, 0xAE, 0x00, 0x00, 0xA2, 0xA6, 0x2F, 0x00, 0x02, 0x3C,
+0x00, 0x10, 0x03, 0x24, 0x17, 0x32, 0x42, 0x34, 0x18, 0x01, 0xD6, 0x37,
+0x1A, 0x01, 0xD7, 0x37, 0xD0, 0x01, 0xD8, 0x37, 0x00, 0x00, 0xC0, 0xA6,
+0x00, 0x00, 0xE3, 0xA6, 0x00, 0x00, 0x02, 0xAF, 0x5E, 0x00, 0x03, 0x3C,
+0x25, 0xB0, 0x02, 0x3C, 0x17, 0x43, 0x63, 0x34, 0xD4, 0x01, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xAC, 0x10, 0x00, 0x02, 0x3C, 0x20, 0x53, 0x42, 0x34,
+0xD8, 0x01, 0xDF, 0x37, 0x00, 0x00, 0xE2, 0xAF, 0x25, 0xB0, 0x02, 0x3C,
+0x44, 0xA4, 0x03, 0x34, 0xDC, 0x01, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC,
+0x25, 0xB0, 0x03, 0x3C, 0x1A, 0x06, 0x02, 0x24, 0xE0, 0x01, 0x63, 0x34,
+0x00, 0x00, 0x62, 0xA4, 0xC2, 0x00, 0x02, 0x3C, 0x30, 0x30, 0x03, 0x24,
+0x51, 0x10, 0x42, 0x34, 0xF4, 0x01, 0xD0, 0x37, 0xF8, 0x01, 0xD3, 0x37,
+0x00, 0x00, 0x03, 0xA6, 0x00, 0x02, 0xD2, 0x37, 0x00, 0x00, 0x62, 0xAE,
+0x26, 0x00, 0x03, 0x24, 0x03, 0x02, 0xD9, 0x37, 0x04, 0x00, 0x02, 0x24,
+0x00, 0x00, 0x43, 0xA6, 0x00, 0x00, 0x22, 0xA3, 0x18, 0x00, 0xA3, 0x8F,
+0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x60, 0x14, 0x36, 0x02, 0xC2, 0x37,
+0x04, 0x00, 0x03, 0x24, 0x00, 0x00, 0x43, 0xA0, 0x02, 0x80, 0x0B, 0x3C,
+0xC6, 0x5C, 0x66, 0x91, 0x25, 0xB0, 0x09, 0x3C, 0x34, 0x02, 0x23, 0x35,
+0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA4, 0x38, 0x02, 0x24, 0x35,
+0x37, 0x02, 0x25, 0x35, 0x07, 0x00, 0x02, 0x24, 0x22, 0x00, 0x03, 0x24,
+0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xA2, 0xA0, 0xE1, 0x00, 0xC3, 0x10,
+0x1B, 0x1B, 0x02, 0x3C, 0x13, 0x13, 0x02, 0x3C, 0x13, 0x13, 0x42, 0x34,
+0x60, 0x01, 0x23, 0x35, 0x64, 0x01, 0x24, 0x35, 0x68, 0x01, 0x25, 0x35,
+0x7C, 0x01, 0x2A, 0x35, 0x6C, 0x01, 0x26, 0x35, 0x70, 0x01, 0x27, 0x35,
+0x74, 0x01, 0x28, 0x35, 0x78, 0x01, 0x29, 0x35, 0x00, 0x00, 0x62, 0xAC,
+0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA2, 0xAC, 0x00, 0x00, 0xC2, 0xAC,
+0x00, 0x00, 0xE2, 0xAC, 0x00, 0x00, 0x02, 0xAD, 0x00, 0x00, 0x22, 0xAD,
+0x00, 0x00, 0x42, 0xAD, 0xC6, 0x5C, 0x65, 0x91, 0x25, 0xB0, 0x0C, 0x3C,
+0x01, 0x00, 0x03, 0x3C, 0x80, 0x01, 0x82, 0x35, 0x08, 0x5F, 0x63, 0x34,
+0x22, 0x00, 0x04, 0x24, 0x00, 0x00, 0x43, 0xAC, 0xE0, 0x00, 0xA4, 0x10,
+0x0F, 0x1F, 0x02, 0x3C, 0x92, 0x00, 0x02, 0x24, 0xDD, 0x00, 0xA2, 0x10,
+0x0F, 0x1F, 0x02, 0x3C, 0x0F, 0x10, 0x02, 0x3C, 0x00, 0xF0, 0x4F, 0x34,
+0xF7, 0x01, 0x91, 0x35, 0x15, 0xF0, 0x4D, 0x34, 0x77, 0x00, 0x0E, 0x24,
+0x84, 0x01, 0x87, 0x35, 0x88, 0x01, 0x88, 0x35, 0x10, 0xF0, 0x44, 0x34,
+0x8C, 0x01, 0x85, 0x35, 0x05, 0xF0, 0x42, 0x34, 0x00, 0x00, 0xED, 0xAC,
+0x90, 0x01, 0x83, 0x35, 0x00, 0x00, 0x04, 0xAD, 0x94, 0x01, 0x86, 0x35,
+0x00, 0x00, 0xA2, 0xAC, 0xF5, 0x0F, 0x02, 0x24, 0x00, 0x00, 0x6F, 0xAC,
+0x98, 0x01, 0x89, 0x35, 0x00, 0x00, 0xC2, 0xAC, 0x9C, 0x01, 0x8A, 0x35,
+0xA0, 0x01, 0x8B, 0x35, 0xF0, 0x0F, 0x03, 0x24, 0xF6, 0x01, 0x8C, 0x35,
+0x0D, 0x00, 0x02, 0x24, 0x00, 0x00, 0x23, 0xAD, 0x00, 0x00, 0x42, 0xAD,
+0x00, 0x00, 0x6D, 0xAD, 0x02, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x8E, 0xA1,
+0x00, 0x00, 0x2E, 0xA2, 0xE3, 0x5C, 0x42, 0x90, 0x25, 0xB0, 0x1F, 0x3C,
+0xA7, 0x01, 0xE7, 0x37, 0x1C, 0x00, 0xA2, 0xAF, 0xFF, 0xFF, 0x02, 0x24,
+0x00, 0x00, 0xE2, 0xA0, 0x05, 0x06, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C,
+0x03, 0x04, 0x63, 0x34, 0x0C, 0x00, 0x04, 0x24, 0xFF, 0xFF, 0x05, 0x24,
+0x01, 0x02, 0x06, 0x3C, 0xC2, 0x01, 0x42, 0x34, 0xA8, 0x01, 0xE8, 0x37,
+0xAC, 0x01, 0xE9, 0x37, 0xB0, 0x01, 0xEA, 0x37, 0xB4, 0x01, 0xEB, 0x37,
+0xB8, 0x01, 0xEC, 0x37, 0xBC, 0x01, 0xED, 0x37, 0xC0, 0x01, 0xEE, 0x37,
+0xC1, 0x01, 0xEF, 0x37, 0x00, 0x00, 0x05, 0xAD, 0x00, 0x00, 0x25, 0xAD,
+0x00, 0x00, 0x46, 0xAD, 0x00, 0x00, 0x63, 0xAD, 0x00, 0x00, 0x86, 0xAD,
+0x00, 0x00, 0xA3, 0xAD, 0x00, 0x00, 0xC4, 0xA1, 0x25, 0xB0, 0x03, 0x3C,
+0x00, 0x00, 0xE4, 0xA1, 0x00, 0x00, 0x44, 0xA0, 0x25, 0xB0, 0x02, 0x3C,
+0x0D, 0x00, 0x17, 0x24, 0x0E, 0x00, 0x18, 0x24, 0xC4, 0x01, 0x63, 0x34,
+0xC5, 0x01, 0x42, 0x34, 0xC3, 0x01, 0xF1, 0x37, 0x00, 0x00, 0x37, 0xA2,
+0xC6, 0x01, 0xF4, 0x37, 0x00, 0x00, 0x77, 0xA0, 0xC7, 0x01, 0xF5, 0x37,
+0x00, 0x00, 0x58, 0xA0, 0x0F, 0x00, 0x02, 0x24, 0x00, 0x00, 0x98, 0xA2,
+0x00, 0x00, 0xA2, 0xA2, 0x53, 0x01, 0x02, 0x3C, 0x46, 0x00, 0xF6, 0x37,
+0x48, 0x00, 0xFE, 0x37, 0x0E, 0xF0, 0x42, 0x34, 0x00, 0x00, 0xC0, 0xA6,
+0x00, 0x00, 0xC2, 0xAF, 0x1C, 0x00, 0xA3, 0x8F, 0x00, 0x00, 0x00, 0x00,
+0x09, 0x00, 0x60, 0x10, 0x44, 0x00, 0xF7, 0x37, 0x00, 0x00, 0xE2, 0x8E,
+0x00, 0x02, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0xE2, 0xAE,
+0x00, 0x00, 0xC3, 0x8F, 0x00, 0x04, 0x02, 0x3C, 0x25, 0x18, 0x62, 0x00,
+0x00, 0x00, 0xC3, 0xAF, 0x4C, 0x00, 0xE2, 0x37, 0x00, 0x00, 0x40, 0xA0,
+0x40, 0x00, 0xE4, 0x37, 0xBC, 0x00, 0x03, 0x24, 0xFC, 0x37, 0x02, 0x24,
+0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0x82, 0xA4, 0x02, 0x80, 0x02, 0x3C,
+0xD8, 0x00, 0xE9, 0x37, 0x60, 0x1B, 0x43, 0x24, 0x00, 0x00, 0x26, 0x91,
+0xAA, 0x1B, 0x64, 0x90, 0x2A, 0xB0, 0x05, 0x3C, 0xA0, 0xFF, 0x02, 0x24,
+0x26, 0xB0, 0x07, 0x3C, 0x25, 0x30, 0xC2, 0x00, 0x30, 0x00, 0xAD, 0x34,
+0x34, 0x00, 0xA8, 0x34, 0x01, 0x00, 0x83, 0x24, 0x38, 0x00, 0xA5, 0x34,
+0x20, 0x20, 0x02, 0x24, 0x00, 0x00, 0x26, 0xA1, 0x79, 0x00, 0xEA, 0x34,
+0x00, 0x00, 0x03, 0xA1, 0x00, 0x00, 0xA2, 0xA4, 0x40, 0x00, 0x03, 0x24,
+0x16, 0x00, 0x02, 0x24, 0x00, 0x00, 0xA3, 0xA1, 0x94, 0x00, 0xEB, 0x37,
+0x00, 0x00, 0x42, 0xA1, 0x98, 0x00, 0xEC, 0x37, 0x64, 0x00, 0x03, 0x24,
+0x22, 0x00, 0x02, 0x24, 0x00, 0x00, 0x63, 0xA5, 0x7C, 0x00, 0xF4, 0x34,
+0x00, 0x00, 0x82, 0xA5, 0x7A, 0x00, 0xE7, 0x34, 0x04, 0x00, 0x03, 0x24,
+0x20, 0x0C, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xA0, 0x9C, 0x00, 0xEE, 0x37,
+0x00, 0x00, 0x82, 0xA6, 0x9A, 0x00, 0xEF, 0x37, 0x0A, 0x00, 0x03, 0x24,
+0xFF, 0x03, 0x02, 0x24, 0x00, 0x00, 0xC3, 0xA1, 0x00, 0x00, 0xE2, 0xA5,
+0x25, 0xB0, 0x02, 0x3C, 0x02, 0x00, 0x03, 0x24, 0x96, 0x00, 0x42, 0x34,
+0x00, 0x00, 0x43, 0xA4, 0x89, 0x00, 0xF5, 0x37, 0xB7, 0x00, 0xF1, 0x37,
+0x20, 0x00, 0x02, 0x24, 0x09, 0x00, 0x03, 0x24, 0x00, 0x00, 0x22, 0xA2,
+0x00, 0x00, 0xA3, 0xA2, 0x00, 0x00, 0xE2, 0x96, 0xFF, 0xFD, 0x03, 0x24,
+0x04, 0x02, 0x05, 0x24, 0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0xE2, 0xA6,
+0x00, 0x00, 0xE3, 0x96, 0x29, 0xB0, 0x02, 0x3C, 0x40, 0x00, 0x42, 0x34,
+0x00, 0x02, 0x63, 0x34, 0x00, 0x00, 0xE3, 0xA6, 0xFF, 0x00, 0x84, 0x30,
+0x00, 0x00, 0x45, 0xA4, 0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F,
+0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F,
+0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F,
+0x20, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03,
+0x48, 0x00, 0xBD, 0x27, 0xFF, 0xFF, 0x03, 0x24, 0x00, 0x00, 0x43, 0xA0,
+0x02, 0x80, 0x0B, 0x3C, 0xC6, 0x5C, 0x66, 0x91, 0x25, 0xB0, 0x09, 0x3C,
+0x34, 0x02, 0x23, 0x35, 0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA4,
+0x38, 0x02, 0x24, 0x35, 0x37, 0x02, 0x25, 0x35, 0x07, 0x00, 0x02, 0x24,
+0x22, 0x00, 0x03, 0x24, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xA2, 0xA0,
+0x23, 0xFF, 0xC3, 0x14, 0x13, 0x13, 0x02, 0x3C, 0x1B, 0x1B, 0x02, 0x3C,
+0x1B, 0x1B, 0x42, 0x34, 0x60, 0x01, 0x23, 0x35, 0x64, 0x01, 0x24, 0x35,
+0x68, 0x01, 0x25, 0x35, 0x7C, 0x01, 0x2A, 0x35, 0x6C, 0x01, 0x26, 0x35,
+0x70, 0x01, 0x27, 0x35, 0x74, 0x01, 0x28, 0x35, 0x78, 0x01, 0x29, 0x35,
+0x00, 0x00, 0x62, 0xAC, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA2, 0xAC,
+0x00, 0x00, 0xC2, 0xAC, 0x00, 0x00, 0xE2, 0xAC, 0x00, 0x00, 0x02, 0xAD,
+0x00, 0x00, 0x22, 0xAD, 0x00, 0x00, 0x42, 0xAD, 0xC6, 0x5C, 0x65, 0x91,
+0x25, 0xB0, 0x0C, 0x3C, 0x01, 0x00, 0x03, 0x3C, 0x80, 0x01, 0x82, 0x35,
+0x08, 0x5F, 0x63, 0x34, 0x22, 0x00, 0x04, 0x24, 0x00, 0x00, 0x43, 0xAC,
+0x22, 0xFF, 0xA4, 0x14, 0x0F, 0x1F, 0x02, 0x3C, 0x00, 0xF0, 0x4F, 0x34,
+0xF7, 0x01, 0x91, 0x35, 0x15, 0xF0, 0x4D, 0x34, 0xE7, 0x68, 0x00, 0x08,
+0xFF, 0xFF, 0x0E, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xC7, 0x5C, 0x44, 0x90,
+0x06, 0x00, 0x03, 0x24, 0x0C, 0x00, 0x83, 0x10, 0xA0, 0x00, 0x24, 0x36,
+0x00, 0x15, 0x02, 0x3C, 0x00, 0x07, 0x42, 0x34, 0x00, 0x00, 0x82, 0xAC,
+0x04, 0xE0, 0x02, 0x3C, 0xA4, 0x00, 0x25, 0x36, 0x00, 0x22, 0x03, 0x24,
+0xA8, 0x00, 0x26, 0x36, 0x00, 0xAE, 0x42, 0x34, 0x00, 0x00, 0xA3, 0xAC,
+0x47, 0x68, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x15, 0x02, 0x3C,
+0x00, 0x07, 0x42, 0x34, 0x00, 0x00, 0x82, 0xAC, 0x04, 0xC0, 0x02, 0x3C,
+0xA4, 0x00, 0x25, 0x36, 0x00, 0x22, 0x03, 0x24, 0xA8, 0x00, 0x26, 0x36,
+0x00, 0xB0, 0x42, 0x34, 0x00, 0x00, 0xA3, 0xAC, 0x47, 0x68, 0x00, 0x08,
+0x02, 0x80, 0x03, 0x3C, 0xE8, 0xFF, 0xBD, 0x27, 0x01, 0x00, 0x06, 0x24,
+0xE8, 0x0E, 0x04, 0x24, 0x10, 0x00, 0xBF, 0xAF, 0xC1, 0x43, 0x00, 0x0C,
+0x00, 0x10, 0x05, 0x3C, 0x60, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0x20, 0x04, 0x06, 0x3C, 0x20, 0x04, 0xC6, 0x34,
+0x25, 0x30, 0x46, 0x00, 0x60, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0x70, 0x08, 0x04, 0x24, 0x00, 0x04, 0x05, 0x24,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x00, 0x20, 0x06, 0x3C,
+0x80, 0x00, 0xC6, 0x34, 0x80, 0x0C, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0xFF, 0xFF, 0x05, 0x24, 0x00, 0x40, 0x06, 0x3C, 0x10, 0x00, 0xBF, 0x8F,
+0x00, 0x01, 0xC6, 0x34, 0x88, 0x0C, 0x04, 0x24, 0xFF, 0xFF, 0x05, 0x24,
+0xC1, 0x43, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF,
+0x10, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xA0, 0x00, 0x0A, 0x00, 0xA0, 0x10,
+0x21, 0x88, 0x00, 0x00, 0x21, 0x80, 0x80, 0x00, 0x00, 0x00, 0x04, 0x8E,
+0x04, 0x00, 0x05, 0x8E, 0x02, 0x00, 0x31, 0x26, 0x03, 0x5C, 0x00, 0x0C,
+0x08, 0x00, 0x10, 0x26, 0x2B, 0x10, 0x32, 0x02, 0xF9, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF,
+0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x21, 0x90, 0xA0, 0x00, 0x0B, 0x00, 0xA0, 0x10, 0x21, 0x88, 0x00, 0x00,
+0x21, 0x80, 0x80, 0x00, 0x00, 0x00, 0x04, 0x8E, 0x04, 0x00, 0x05, 0x8E,
+0x08, 0x00, 0x06, 0x8E, 0x03, 0x00, 0x31, 0x26, 0xC1, 0x43, 0x00, 0x0C,
+0x0C, 0x00, 0x10, 0x26, 0x2B, 0x10, 0x32, 0x02, 0xF8, 0xFF, 0x40, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x21, 0x40, 0x80, 0x00, 0x21, 0x48, 0x00, 0x00,
+0x1E, 0x00, 0xA0, 0x10, 0x21, 0x38, 0x00, 0x00, 0x80, 0x30, 0x07, 0x00,
+0x21, 0x10, 0xC8, 0x00, 0x00, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xF2, 0x63, 0x24, 0x1D, 0x00, 0x62, 0x2C, 0x12, 0x00, 0x40, 0x10,
+0x80, 0x10, 0x03, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x14, 0xE6, 0x63, 0x24,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00,
+0xC0, 0x18, 0x09, 0x00, 0x23, 0x18, 0x69, 0x00, 0x08, 0x00, 0x44, 0x8C,
+0x02, 0x80, 0x02, 0x3C, 0x80, 0x18, 0x03, 0x00, 0x60, 0x1B, 0x42, 0x24,
+0x21, 0x18, 0x62, 0x00, 0x04, 0x1D, 0x64, 0xAC, 0x01, 0x00, 0x29, 0x25,
+0x03, 0x00, 0xE7, 0x24, 0x2B, 0x10, 0xE5, 0x00, 0xE5, 0xFF, 0x40, 0x14,
+0x80, 0x30, 0x07, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C,
+0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00,
+0x2B, 0x10, 0xE5, 0x00, 0xD6, 0xFF, 0x40, 0x14, 0x00, 0x1D, 0x64, 0xAC,
+0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00,
+0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00,
+0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00,
+0xC8, 0xFF, 0x40, 0x14, 0xFC, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00,
+0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24,
+0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, 0xBA, 0xFF, 0x40, 0x14,
+0xF8, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C,
+0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24,
+0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00,
+0x2B, 0x10, 0xE5, 0x00, 0xAC, 0xFF, 0x40, 0x14, 0x08, 0x1D, 0x64, 0xAC,
+0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00,
+0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00,
+0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00,
+0x9E, 0xFF, 0x40, 0x14, 0xF4, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00,
+0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C,
+0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24,
+0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, 0x90, 0xFF, 0x40, 0x14,
+0xF0, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x25, 0xB0, 0x02, 0x3C, 0xFC, 0x37, 0x03, 0x24, 0x40, 0x00, 0x42, 0x34,
+0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xA4, 0xE8, 0xFF, 0xBD, 0x27,
+0x5C, 0xD1, 0x84, 0x24, 0x10, 0x00, 0xBF, 0xAF, 0xFD, 0x69, 0x00, 0x0C,
+0x74, 0x01, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x44, 0x90,
+0x12, 0x00, 0x03, 0x24, 0x34, 0x00, 0x83, 0x10, 0x13, 0x00, 0x82, 0x28,
+0x17, 0x00, 0x40, 0x14, 0x11, 0x00, 0x02, 0x24, 0x22, 0x00, 0x02, 0x24,
+0x36, 0x00, 0x82, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x04, 0x3C,
+0xE4, 0xCD, 0x84, 0x24, 0x2C, 0x6A, 0x00, 0x0C, 0x54, 0x00, 0x05, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0x4A, 0xF5, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24,
+0x1A, 0x00, 0x83, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0xE4, 0xC8, 0x84, 0x24, 0xFD, 0x69, 0x00, 0x0C, 0x40, 0x01, 0x05, 0x24,
+0x10, 0x00, 0xBF, 0x8F, 0x84, 0x08, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24,
+0x58, 0x00, 0x06, 0x24, 0x35, 0x45, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0xED, 0xFF, 0x82, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x04, 0x3C,
+0x9C, 0xD0, 0x84, 0x24, 0x14, 0x6A, 0x00, 0x0C, 0x30, 0x00, 0x05, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0xE4, 0xCD, 0x84, 0x24, 0x2C, 0x6A, 0x00, 0x0C,
+0x54, 0x00, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x4A, 0xF5, 0x44, 0x90,
+0x01, 0x00, 0x03, 0x24, 0xE8, 0xFF, 0x83, 0x14, 0x00, 0x00, 0x00, 0x00,
+0xDE, 0x69, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0xE4, 0xC8, 0x84, 0x24, 0xFD, 0x69, 0x00, 0x0C, 0x40, 0x01, 0x05, 0x24,
+0x10, 0x00, 0xBF, 0x8F, 0x84, 0x08, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24,
+0x58, 0x00, 0x06, 0x24, 0x35, 0x45, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0x02, 0x80, 0x04, 0x3C, 0xE8, 0xCF, 0x84, 0x24, 0x2D, 0x00, 0x05, 0x24,
+0x14, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x6A, 0x00, 0x08,
+0x02, 0x80, 0x04, 0x3C, 0x34, 0xCF, 0x84, 0x24, 0xE8, 0x6A, 0x00, 0x08,
+0x2D, 0x00, 0x05, 0x24, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF,
+0x50, 0x0C, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24, 0x02, 0x80, 0x10, 0x3C,
+0x14, 0x00, 0xBF, 0xAF, 0x24, 0x45, 0x00, 0x0C, 0x60, 0x1B, 0x10, 0x26,
+0x60, 0x1D, 0x02, 0xA2, 0x58, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C,
+0xFF, 0x00, 0x05, 0x24, 0x61, 0x1D, 0x02, 0xA2, 0x60, 0x0C, 0x04, 0x24,
+0x24, 0x45, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24, 0x62, 0x1D, 0x02, 0xA2,
+0x68, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24,
+0x63, 0x1D, 0x02, 0xA2, 0x38, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C,
+0xFF, 0x00, 0x05, 0x24, 0xE8, 0x1C, 0x02, 0xA2, 0x34, 0x0C, 0x04, 0x24,
+0x24, 0x45, 0x00, 0x0C, 0xFF, 0xFF, 0x05, 0x24, 0xEC, 0x1C, 0x02, 0xAE,
+0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x38, 0xAD, 0x42, 0x24, 0xB0, 0x5D, 0x60, 0xAC,
+0x10, 0x5D, 0xA2, 0xAC, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x80, 0x02, 0x3C,
+0xB4, 0x5D, 0x60, 0xA4, 0x10, 0x5D, 0xA4, 0x24, 0x64, 0x11, 0x42, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0xB6, 0x5D, 0x60, 0xA4, 0x08, 0x00, 0x82, 0xAC,
+0x00, 0x80, 0x03, 0x3C, 0x00, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x06, 0x3C,
+0x4C, 0x14, 0x42, 0x24, 0x80, 0x11, 0x63, 0x24, 0xB8, 0x5D, 0xC7, 0x24,
+0x14, 0x00, 0x82, 0xAC, 0x10, 0x00, 0x83, 0xAC, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xB8, 0x5D, 0xC0, 0xAC, 0x04, 0x00, 0xE0, 0xAC,
+0xC0, 0x5D, 0x40, 0xA0, 0xC4, 0x5D, 0x60, 0xAC, 0x01, 0x80, 0x02, 0x3C,
+0xB4, 0xC5, 0x42, 0x24, 0x7C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x68, 0x14, 0x63, 0x24, 0x08, 0x17, 0x42, 0x24,
+0x20, 0x00, 0x83, 0xAC, 0x24, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0xB0, 0x19, 0x63, 0x24, 0x54, 0x1C, 0x42, 0x24,
+0x28, 0x00, 0x83, 0xAC, 0x2C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x01, 0x80, 0x02, 0x3C, 0x80, 0x2F, 0x63, 0x24, 0x10, 0x02, 0x42, 0x24,
+0x30, 0x00, 0x83, 0xAC, 0x54, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x58, 0x1F, 0x63, 0x24, 0x38, 0x21, 0x42, 0x24,
+0x0C, 0x00, 0x83, 0xAC, 0x3C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C,
+0x00, 0x80, 0x02, 0x3C, 0x00, 0x03, 0x63, 0x24, 0xF8, 0x1E, 0x42, 0x24,
+0x50, 0x00, 0x83, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0x82, 0xAC,
+0x25, 0xB0, 0x02, 0x3C, 0x08, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C,
+0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x0E, 0x3C,
+0x02, 0x80, 0x08, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0xF8, 0x03, 0x4D, 0x24, 0x00, 0x18, 0x6C, 0x24, 0x01, 0x00, 0x07, 0x24,
+0x00, 0x00, 0xCB, 0x25, 0xFF, 0xFF, 0x0A, 0x24, 0x00, 0x04, 0x09, 0x25,
+0x80, 0x1A, 0x07, 0x00, 0x21, 0x10, 0x6B, 0x00, 0x00, 0x00, 0x42, 0xAC,
+0x90, 0x00, 0x4A, 0xAC, 0x00, 0x04, 0x04, 0x8D, 0x01, 0x00, 0xE7, 0x24,
+0x08, 0x00, 0x45, 0x24, 0x21, 0x18, 0x6D, 0x00, 0x06, 0x00, 0xE6, 0x28,
+0x04, 0x00, 0x82, 0xAC, 0x00, 0x00, 0x44, 0xAC, 0x04, 0x00, 0x49, 0xAC,
+0x00, 0x04, 0x02, 0xAD, 0x8C, 0x00, 0x40, 0xAC, 0x6C, 0x00, 0xA3, 0xAC,
+0xF0, 0xFF, 0xC0, 0x14, 0x68, 0x00, 0xAC, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0xC9, 0xAD, 0x06, 0x00, 0xA2, 0x2C, 0x13, 0x00, 0x40, 0x10,
+0xFF, 0xFF, 0x07, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x80, 0x1A, 0x05, 0x00,
+0x00, 0x00, 0x42, 0x24, 0x0E, 0x00, 0xA0, 0x10, 0x21, 0x30, 0x62, 0x00,
+0x90, 0x00, 0xC3, 0x8C, 0xFF, 0xFF, 0x02, 0x24, 0x0A, 0x00, 0x62, 0x14,
+0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24,
+0x88, 0x00, 0xC4, 0xAC, 0x8C, 0x00, 0xC2, 0xAC, 0x90, 0x00, 0xC5, 0xAC,
+0x21, 0x38, 0xA0, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xE0, 0x00,
+0xE0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x1C, 0x00, 0xBF, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0xC3, 0x5C, 0x46, 0x90, 0x25, 0xB0, 0x07, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xDB, 0xFF, 0x03, 0x24, 0x18, 0x03, 0xE4, 0x34, 0x27, 0x00, 0xE5, 0x34,
+0x1C, 0xAE, 0x42, 0x24, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA3, 0xA0,
+0x02, 0x00, 0xC0, 0x10, 0x1B, 0x00, 0xE3, 0x34, 0x1F, 0x00, 0xE3, 0x34,
+0x07, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0, 0xF0, 0x42, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24,
+0x34, 0x1C, 0x04, 0x8E, 0xE3, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x24,
+0x40, 0x1C, 0x04, 0x8E, 0x10, 0x00, 0x05, 0x3C, 0x01, 0x00, 0x06, 0x24,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x3C, 0x1C, 0x04, 0x8E,
+0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24,
+0x58, 0x1C, 0x04, 0x8E, 0x00, 0x04, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x58, 0x1C, 0x04, 0x8E, 0x00, 0x08, 0x05, 0x24,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C,
+0x78, 0xDA, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C,
+0xCA, 0x00, 0x06, 0x24, 0x31, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xCF, 0x5C, 0x43, 0x90, 0x01, 0x00, 0x11, 0x24,
+0x53, 0x00, 0x71, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0x4A, 0xF5, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x71, 0x10,
+0x02, 0x80, 0x05, 0x3C, 0x34, 0x1C, 0x04, 0x8E, 0x21, 0x30, 0x40, 0x02,
+0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x02, 0x80, 0x11, 0x3C,
+0xC6, 0x5C, 0x23, 0x92, 0x11, 0x00, 0x02, 0x24, 0x2A, 0x00, 0x62, 0x10,
+0x00, 0x08, 0x04, 0x24, 0xF0, 0x42, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24,
+0x34, 0x1C, 0x04, 0x8E, 0xE3, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x3C,
+0x40, 0x1C, 0x04, 0x8E, 0x10, 0x00, 0x05, 0x3C, 0x01, 0x00, 0x06, 0x24,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x3C, 0x1C, 0x04, 0x8E,
+0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24,
+0x58, 0x1C, 0x04, 0x8E, 0x00, 0x04, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C,
+0x21, 0x30, 0x00, 0x00, 0x58, 0x1C, 0x04, 0x8E, 0x00, 0x08, 0x05, 0x24,
+0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C,
+0x20, 0xDA, 0xA5, 0x24, 0x01, 0x00, 0x04, 0x24, 0xC1, 0x45, 0x00, 0x0C,
+0x16, 0x00, 0x06, 0x24, 0x08, 0x00, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00,
+0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F,
+0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x34, 0x1C, 0x04, 0x8E, 0x21, 0x30, 0x40, 0x02,
+0xC1, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x3C, 0x00, 0x08, 0x04, 0x24,
+0x00, 0x01, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24,
+0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C,
+0x01, 0x00, 0x06, 0x24, 0xC6, 0x5C, 0x23, 0x92, 0x11, 0x00, 0x02, 0x24,
+0x1D, 0x00, 0x62, 0x10, 0x00, 0x08, 0x04, 0x24, 0xF0, 0x42, 0x00, 0x0C,
+0x21, 0x20, 0x00, 0x00, 0x0F, 0x00, 0x05, 0x3C, 0x0C, 0x00, 0x06, 0x3C,
+0xFF, 0xFF, 0xA5, 0x34, 0x00, 0xB4, 0xC6, 0x34, 0x83, 0x45, 0x00, 0x0C,
+0x08, 0x00, 0x04, 0x24, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x03, 0x24,
+0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27,
+0x10, 0xD9, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C,
+0x16, 0x00, 0x06, 0x24, 0xC0, 0x6B, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C,
+0x68, 0xD9, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C,
+0x16, 0x00, 0x06, 0x24, 0xC4, 0x6B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFF, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24,
+0x01, 0x6C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x02, 0x80, 0x02, 0x3C, 0x25, 0x59, 0x47, 0x90, 0x02, 0x80, 0x04, 0x3C,
+0x02, 0x80, 0x05, 0x3C, 0x03, 0x00, 0x03, 0x24, 0x4E, 0x37, 0x84, 0x24,
+0xB4, 0xDF, 0xA5, 0x24, 0x0F, 0x00, 0xE3, 0x10, 0x0D, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x4E, 0x37, 0x84, 0x24,
+0x64, 0xDF, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x0D, 0x00, 0x06, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x10, 0x00, 0xBF, 0x8F,
+0x5B, 0x37, 0x84, 0x24, 0x74, 0xDF, 0xA5, 0x24, 0x0D, 0x00, 0x06, 0x24,
+0xF4, 0x54, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xF4, 0x54, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C,
+0x10, 0x00, 0xBF, 0x8F, 0x5B, 0x37, 0x84, 0x24, 0xA4, 0xDF, 0xA5, 0x24,
+0x0D, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27,
+0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x10, 0x3C, 0x02, 0x80, 0x11, 0x3C,
+0x60, 0x1B, 0x31, 0x26, 0x2C, 0x59, 0x04, 0x26, 0xA0, 0xDD, 0xA5, 0x24,
+0x34, 0x00, 0x06, 0x24, 0x18, 0x00, 0xBF, 0xAF, 0xF4, 0x54, 0x00, 0x0C,
+0x2C, 0x59, 0x10, 0x26, 0x24, 0x6C, 0x00, 0x0C, 0x00, 0x3E, 0x30, 0xAE,
+0x02, 0x00, 0x10, 0x24, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x80, 0x06, 0x3C,
+0x9C, 0x39, 0x30, 0xA2, 0xE8, 0x54, 0x84, 0x24, 0x98, 0x5B, 0xC6, 0x24,
+0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x01, 0x80, 0x06, 0x3C, 0xB8, 0x39, 0x30, 0xA2, 0x04, 0x55, 0x84, 0x24,
+0x90, 0x3B, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0x02, 0x80, 0x04, 0x3C, 0x01, 0x80, 0x06, 0x3C, 0xD4, 0x39, 0x30, 0xA2,
+0x20, 0x55, 0x84, 0x24, 0x08, 0x39, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C,
+0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x01, 0x80, 0x06, 0x3C,
+0xF0, 0x39, 0x30, 0xA2, 0x3C, 0x55, 0x84, 0x24, 0x74, 0x44, 0xC6, 0x24,
+0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C,
+0x00, 0x80, 0x06, 0x3C, 0x0C, 0x3A, 0x30, 0xA2, 0x58, 0x55, 0x84, 0x24,
+0xFC, 0x5A, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00,
+0x09, 0x00, 0x02, 0x24, 0xB8, 0x40, 0x22, 0xA2, 0xC7, 0x3D, 0x20, 0xA2,
+0x3A, 0x41, 0x20, 0xA2, 0xC8, 0x3D, 0x20, 0xA6, 0x18, 0x00, 0xBF, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x20, 0x00, 0xBD, 0x27, 0x03, 0x80, 0x05, 0x3C, 0x00, 0x80, 0xA5, 0x24,
+0xD8, 0xFF, 0xBD, 0x27, 0x40, 0x10, 0x0D, 0x3C, 0xFF, 0xFF, 0xA5, 0x30,
+0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x20, 0x00, 0xBE, 0xAF,
+0x25, 0xF0, 0xAD, 0x00, 0x2C, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27,
+0x38, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0x1C, 0x00, 0xB7, 0xAF,
+0x18, 0x00, 0xB6, 0xAF, 0x14, 0x00, 0xB5, 0xAF, 0x10, 0x00, 0xB4, 0xAF,
+0x0C, 0x00, 0xB3, 0xAF, 0x08, 0x00, 0xB2, 0xAF, 0x04, 0x00, 0xB1, 0xAF,
+0x00, 0x00, 0xB0, 0xAF, 0x44, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27,
+0x50, 0x38, 0x5E, 0xAC, 0xAA, 0x1B, 0x44, 0x90, 0x00, 0x01, 0xDE, 0x27,
+0x5C, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0x68, 0x38, 0x5E, 0xAC,
+0x20, 0xB0, 0x06, 0x3C, 0x38, 0x38, 0x48, 0x8C, 0x44, 0x38, 0x49, 0x8C,
+0x50, 0x38, 0x4A, 0x8C, 0x5C, 0x38, 0x4B, 0x8C, 0x68, 0x38, 0x4C, 0x8C,
+0x00, 0x22, 0x04, 0x00, 0x00, 0x01, 0xC7, 0x34, 0xFF, 0x1F, 0x03, 0x3C,
+0x00, 0x01, 0xDE, 0x27, 0xFF, 0xFF, 0x63, 0x34, 0x21, 0x38, 0x87, 0x00,
+0x21, 0x20, 0x86, 0x00, 0x24, 0x38, 0xE3, 0x00, 0x20, 0x10, 0x06, 0x3C,
+0x24, 0x20, 0x83, 0x00, 0x74, 0x38, 0x5E, 0xAC, 0x21, 0x70, 0xC0, 0x03,
+0x25, 0x28, 0xAD, 0x00, 0x25, 0xB0, 0x0F, 0x3C, 0x00, 0x01, 0xDE, 0x27,
+0x28, 0x38, 0x45, 0xAC, 0x34, 0x38, 0x48, 0xAC, 0x40, 0x38, 0x49, 0xAC,
+0x4C, 0x38, 0x4A, 0xAC, 0xEC, 0x37, 0x44, 0xAC, 0x58, 0x38, 0x4B, 0xAC,
+0xF8, 0x37, 0x47, 0xAC, 0x64, 0x38, 0x4C, 0xAC, 0xAC, 0x00, 0xE3, 0x35,
+0xC0, 0x37, 0x46, 0xAC, 0xBC, 0x37, 0x46, 0xAC, 0xCC, 0x37, 0x46, 0xAC,
+0xC8, 0x37, 0x46, 0xAC, 0x80, 0x38, 0x5E, 0xAC, 0xF0, 0x37, 0x44, 0xAC,
+0xFC, 0x37, 0x47, 0xAC, 0x70, 0x38, 0x4E, 0xAC, 0xD8, 0x37, 0x46, 0xAC,
+0xD4, 0x37, 0x46, 0xAC, 0xE4, 0x37, 0x46, 0xAC, 0xE0, 0x37, 0x46, 0xAC,
+0x08, 0x38, 0x46, 0xAC, 0x04, 0x38, 0x46, 0xAC, 0xAC, 0x1B, 0x47, 0x94,
+0x00, 0x02, 0xDE, 0x27, 0x00, 0x00, 0x69, 0x8C, 0x21, 0x10, 0x05, 0x3C,
+0x98, 0x38, 0x5E, 0xAC, 0xB0, 0x00, 0xE3, 0x35, 0x00, 0x00, 0x79, 0x8C,
+0x80, 0x38, 0x54, 0x8C, 0x00, 0x80, 0xA4, 0x34, 0x23, 0x10, 0x0D, 0x3C,
+0x22, 0x10, 0x10, 0x3C, 0x02, 0x80, 0x16, 0x3C, 0x02, 0x80, 0x17, 0x3C,
+0x02, 0x80, 0x18, 0x3C, 0x02, 0x80, 0x13, 0x3C, 0x23, 0x20, 0x87, 0x00,
+0x02, 0x80, 0x03, 0x3C, 0x24, 0x10, 0x07, 0x3C, 0xC0, 0x54, 0x68, 0x24,
+0xCC, 0x38, 0x44, 0xAC, 0x21, 0xA8, 0xC0, 0x03, 0xC8, 0x54, 0xCE, 0x26,
+0x00, 0x04, 0xDE, 0x27, 0xD0, 0x54, 0xEA, 0x26, 0xD8, 0x54, 0x0B, 0x27,
+0xE0, 0x54, 0x6C, 0x26, 0x00, 0x04, 0xB1, 0x35, 0x01, 0x00, 0x29, 0x25,
+0x00, 0x40, 0x12, 0x36, 0x00, 0x01, 0xEF, 0x35, 0x01, 0x00, 0x03, 0x24,
+0x02, 0x80, 0x04, 0x3C, 0x7C, 0x38, 0x54, 0xAC, 0x85, 0x38, 0x43, 0xA0,
+0x94, 0x38, 0x55, 0xAC, 0xFC, 0x38, 0x51, 0xAC, 0xC0, 0x38, 0x49, 0xAC,
+0xF0, 0x38, 0x52, 0xAC, 0xE4, 0x38, 0x59, 0xAC, 0x00, 0x00, 0xE7, 0xAD,
+0xE0, 0x38, 0x47, 0xAC, 0x00, 0x39, 0x46, 0xAC, 0x14, 0x38, 0x46, 0xAC,
+0x10, 0x38, 0x46, 0xAC, 0x9E, 0x38, 0x40, 0xA4, 0x9D, 0x38, 0x40, 0xA0,
+0x9C, 0x38, 0x40, 0xA0, 0xF4, 0x38, 0x4D, 0xAC, 0xF8, 0x38, 0x4D, 0xAC,
+0xB8, 0x38, 0x45, 0xAC, 0xBC, 0x38, 0x45, 0xAC, 0xC4, 0x38, 0x45, 0xAC,
+0xC8, 0x38, 0x45, 0xAC, 0xE8, 0x38, 0x50, 0xAC, 0xEC, 0x38, 0x50, 0xAC,
+0xDC, 0x38, 0x47, 0xAC, 0x04, 0x39, 0x46, 0xAC, 0x10, 0x39, 0x5E, 0xAC,
+0x0C, 0x39, 0x5E, 0xAC, 0x04, 0x00, 0x4A, 0xAD, 0xC8, 0x54, 0xCE, 0xAE,
+0x04, 0x00, 0x6B, 0xAD, 0xD0, 0x54, 0xEA, 0xAE, 0x04, 0x00, 0x8C, 0xAD,
+0xD8, 0x54, 0x0B, 0xAF, 0x04, 0x00, 0x08, 0xAD, 0xE0, 0x54, 0x6C, 0xAE,
+0xC0, 0x54, 0x88, 0xAC, 0x04, 0x00, 0xCE, 0xAD, 0x02, 0x80, 0x04, 0x3C,
+0x18, 0x18, 0x83, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x00, 0x18, 0xA2, 0x24,
+0x18, 0x18, 0x83, 0xAC, 0x02, 0x80, 0x04, 0x3C, 0x04, 0x00, 0x02, 0xAD,
+0x00, 0x18, 0xA8, 0xAC, 0xC0, 0x54, 0x82, 0xAC, 0x21, 0x48, 0x60, 0x00,
+0x08, 0x00, 0x5E, 0xAC, 0x01, 0x00, 0x07, 0x24, 0x04, 0x00, 0x63, 0xAC,
+0x00, 0x01, 0xDE, 0x27, 0x04, 0x00, 0x48, 0xAC, 0x10, 0x00, 0x40, 0xAC,
+0x21, 0x40, 0x40, 0x00, 0x21, 0x18, 0xC0, 0x01, 0x21, 0x28, 0x00, 0x00,
+0x0F, 0x00, 0x06, 0x24, 0x21, 0x20, 0xA9, 0x00, 0x21, 0x10, 0xA8, 0x00,
+0xFF, 0xFF, 0xC6, 0x24, 0x20, 0x00, 0x5E, 0xAC, 0x28, 0x00, 0x47, 0xAC,
+0x18, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x8E, 0xAC, 0x04, 0x00, 0x83, 0xAC,
+0x00, 0x00, 0x64, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0xF5, 0xFF, 0xC1, 0x04,
+0x21, 0x18, 0x80, 0x00, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x54, 0x48, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x07, 0x8D,
+0x98, 0x19, 0x4B, 0x24, 0x04, 0x00, 0xC4, 0xAD, 0x00, 0x18, 0x6A, 0x24,
+0x02, 0x00, 0x09, 0x24, 0x21, 0x28, 0x00, 0x00, 0x0F, 0x00, 0x06, 0x24,
+0x21, 0x20, 0xAB, 0x00, 0x21, 0x10, 0xAA, 0x00, 0xFF, 0xFF, 0xC6, 0x24,
+0xA0, 0x01, 0x5E, 0xAC, 0xA8, 0x01, 0x49, 0xAC, 0x18, 0x00, 0xA5, 0x24,
+0x00, 0x00, 0x88, 0xAC, 0x04, 0x00, 0x87, 0xAC, 0x00, 0x00, 0xE4, 0xAC,
+0x00, 0x02, 0xDE, 0x27, 0xF5, 0xFF, 0xC1, 0x04, 0x21, 0x38, 0x80, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xD8, 0x54, 0x49, 0x24, 0x02, 0x80, 0x03, 0x3C,
+0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x25, 0x8D, 0x18, 0x1B, 0x4B, 0x24,
+0x04, 0x00, 0x04, 0xAD, 0x00, 0x18, 0x6A, 0x24, 0x03, 0x00, 0x07, 0x24,
+0x21, 0x20, 0x00, 0x00, 0x01, 0x00, 0x06, 0x24, 0x21, 0x40, 0x8B, 0x00,
+0x21, 0x10, 0x8A, 0x00, 0xFF, 0xFF, 0xC6, 0x24, 0x20, 0x03, 0x5E, 0xAC,
+0x28, 0x03, 0x47, 0xAC, 0x18, 0x00, 0x84, 0x24, 0x00, 0x00, 0x09, 0xAD,
+0x04, 0x00, 0x05, 0xAD, 0x00, 0x00, 0xA8, 0xAC, 0x00, 0x08, 0xDE, 0x27,
+0xF5, 0xFF, 0xC1, 0x04, 0x21, 0x28, 0x00, 0x01, 0x02, 0x80, 0x05, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0xE0, 0x54, 0xA5, 0x24, 0x00, 0x18, 0x63, 0x24,
+0x04, 0x00, 0xA6, 0x8C, 0x1C, 0x00, 0xB7, 0x8F, 0x50, 0x03, 0x7E, 0xAC,
+0x18, 0x00, 0xB6, 0x8F, 0x20, 0x00, 0xBE, 0x8F, 0x14, 0x00, 0xB5, 0x8F,
+0x10, 0x00, 0xB4, 0x8F, 0x0C, 0x00, 0xB3, 0x8F, 0x08, 0x00, 0xB2, 0x8F,
+0x04, 0x00, 0xB1, 0x8F, 0x00, 0x00, 0xB0, 0x8F, 0x02, 0x80, 0x07, 0x3C,
+0x48, 0x1B, 0xE4, 0x24, 0x04, 0x00, 0x02, 0x24, 0x28, 0x00, 0xBD, 0x27,
+0x04, 0x00, 0x28, 0xAD, 0x04, 0x00, 0xA4, 0xAC, 0x58, 0x03, 0x62, 0xAC,
+0x48, 0x1B, 0xE5, 0xAC, 0x04, 0x00, 0x86, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0xC4, 0xAC, 0xFA, 0x63, 0x00, 0x6A, 0x09, 0xD1, 0x0A, 0x62,
+0x08, 0xD0, 0x06, 0xD2, 0x7D, 0x67, 0x18, 0xA3, 0x10, 0xF0, 0x02, 0x69,
+0x00, 0xF4, 0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0x00, 0x18, 0xDB, 0x5C,
+0x06, 0x94, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x5C, 0xF4, 0x00, 0x4A, 0xDC, 0xF3,
+0x0C, 0x4B, 0x7B, 0x9B, 0x5B, 0x9A, 0x00, 0x6D, 0x69, 0xE2, 0x46, 0x32,
+0xC4, 0xF4, 0x54, 0xD9, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0xBC, 0xF3, 0x0C, 0x4A, 0x5B, 0xA2, 0x01, 0xF6, 0x01, 0x6B, 0x6B, 0xEB,
+0x50, 0x32, 0xE4, 0xF4, 0x5C, 0xD9, 0xE4, 0xF4, 0x58, 0xD9, 0x04, 0xF5,
+0x48, 0x99, 0x6C, 0xEA, 0x00, 0xF2, 0x00, 0x6B, 0x6D, 0xEA, 0x04, 0xF5,
+0x48, 0xD9, 0xA9, 0xE1, 0x01, 0x4D, 0x1D, 0x55, 0x04, 0xF5, 0x0C, 0xC2,
+0x44, 0xF5, 0x06, 0xC2, 0x24, 0xF5, 0x09, 0xC2, 0xF6, 0x61, 0x00, 0x6A,
+0x64, 0xF5, 0x44, 0xD9, 0x06, 0x94, 0x7F, 0x49, 0x15, 0x49, 0x01, 0x4C,
+0x20, 0x54, 0x06, 0xD4, 0xBF, 0x61, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4,
+0xA0, 0x35, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, 0x10, 0xF0,
+0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4,
+0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x06, 0xD2,
+0x63, 0xF3, 0x00, 0x4D, 0x5C, 0xF4, 0x00, 0x49, 0xDC, 0xF3, 0x0C, 0x48,
+0xBC, 0xF3, 0x0C, 0x4F, 0x9C, 0xF3, 0x0C, 0x4E, 0x06, 0x93, 0x68, 0x32,
+0x2D, 0xE2, 0x60, 0x9B, 0xB1, 0xE2, 0x09, 0xE2, 0xC0, 0xF5, 0x74, 0xDC,
+0x40, 0x9A, 0x60, 0xF5, 0x40, 0xDC, 0x06, 0x94, 0xE9, 0xE4, 0x40, 0xA2,
+0xAD, 0xE4, 0x00, 0xF5, 0x44, 0xC3, 0xC9, 0xE4, 0x40, 0xA2, 0x01, 0x4C,
+0x1D, 0x54, 0x20, 0xF5, 0x5E, 0xC3, 0x06, 0xD4, 0xE7, 0x61, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4,
+0x60, 0x33, 0x00, 0x6D, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31,
+0x7C, 0xF2, 0x08, 0x4A, 0x1C, 0xF1, 0x08, 0x4B, 0x06, 0xD5, 0x63, 0xF3,
+0x00, 0x49, 0x2A, 0x65, 0x0B, 0x65, 0x05, 0x67, 0x89, 0x67, 0x00, 0x6D,
+0x3D, 0xE0, 0x99, 0xE0, 0xAD, 0xE6, 0x40, 0xA3, 0xB1, 0xE7, 0x01, 0x4D,
+0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0, 0x51, 0xA3, 0x05, 0x55, 0x20, 0xF4,
+0x59, 0xC4, 0xF4, 0x61, 0x06, 0x95, 0x48, 0x67, 0x05, 0x48, 0x4D, 0xE5,
+0x40, 0xA3, 0x31, 0xE5, 0x01, 0x4D, 0xC0, 0xF4, 0x4A, 0xC4, 0x5D, 0xA3,
+0x1D, 0x55, 0xE0, 0xF4, 0x47, 0xC4, 0x06, 0xD5, 0xE1, 0x61, 0x9D, 0x67,
+0x52, 0x6A, 0x50, 0xC4, 0x41, 0x6A, 0x51, 0xC4, 0x00, 0x6B, 0x4D, 0x6A,
+0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x7E, 0xF5, 0x00, 0x4C, 0xE0, 0xF3, 0x08, 0x6A, 0x43, 0xDC, 0xBD, 0x67,
+0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x54, 0xC4,
+0x30, 0xF7, 0x01, 0x4E, 0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D, 0x0A, 0x97,
+0x09, 0x91, 0x08, 0x90, 0x00, 0xEF, 0x06, 0x63, 0xC9, 0xF7, 0x1B, 0x6C,
+0xF1, 0x63, 0x8B, 0xEC, 0x1B, 0xD1, 0x80, 0x31, 0x20, 0x31, 0xE1, 0xF6,
+0x80, 0x41, 0x1C, 0x62, 0x00, 0x1C, 0xFA, 0x5B, 0x1A, 0xD0, 0xD1, 0xF6,
+0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x07, 0xD2, 0x71, 0xF6, 0x80, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x08, 0xD2, 0x71, 0xF6, 0x84, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x09, 0xD2, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x0A, 0xD2, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0B, 0xD2,
+0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0C, 0xD2, 0x81, 0xF6,
+0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0D, 0xD2, 0x81, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x0E, 0xD2, 0x81, 0xF6, 0x8C, 0x41, 0xE7, 0xF7,
+0x0E, 0x68, 0x00, 0x1C, 0xFA, 0x5B, 0x0F, 0xD2, 0xD1, 0xF6, 0x80, 0x41,
+0x10, 0xD2, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x30, 0xD1, 0xF6, 0x84, 0x41,
+0x00, 0x30, 0x00, 0x1C, 0xFA, 0x5B, 0x11, 0xD2, 0xD1, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x12, 0xD2, 0xB0, 0x67, 0xE1, 0xF6, 0x80, 0x41,
+0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x13, 0xD2, 0xB0, 0x67,
+0xD1, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x84, 0x41,
+0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67,
+0x71, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x80, 0x41,
+0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67,
+0x81, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x8C, 0x41,
+0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67,
+0xD1, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xB0, 0x67, 0xD1, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0xD1, 0xF6, 0x88, 0x41,
+0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x6A,
+0x04, 0xD2, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x30, 0x00, 0xF5, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x15, 0xD2, 0x01, 0xF0, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x30, 0x16, 0xD2, 0x21, 0xF0,
+0x80, 0x41, 0x00, 0xF1, 0xA0, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65,
+0x21, 0xF0, 0x88, 0x41, 0x00, 0xF1, 0xA0, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x2A, 0xF4, 0x10, 0x4D,
+0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C,
+0x5B, 0x1F, 0x05, 0x6C, 0x01, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0x7F, 0x4D,
+0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x65, 0x4D, 0x00, 0x1C,
+0x5B, 0x1F, 0x05, 0x6C, 0x8F, 0xF7, 0x00, 0x6D, 0xAB, 0xED, 0xA0, 0x35,
+0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0xA0, 0x35, 0x00, 0x1C,
+0x5B, 0x1F, 0x05, 0x6C, 0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35,
+0x00, 0xF1, 0x02, 0x4D, 0x41, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x0D, 0xF0, 0x16, 0x6D,
+0xA0, 0x35, 0xA0, 0x35, 0xC0, 0xF4, 0x02, 0x4D, 0x41, 0xF6, 0x84, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C,
+0xC5, 0xF0, 0x11, 0x6D, 0x41, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x00, 0xF2, 0x14, 0x6D,
+0xA0, 0x35, 0xA0, 0x35, 0x00, 0xF1, 0x02, 0x4D, 0x61, 0xF6, 0x80, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C,
+0x05, 0xF0, 0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF5, 0x05, 0x4D,
+0x61, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C,
+0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x15, 0x95, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0x16, 0x95, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C,
+0x00, 0x1C, 0x2C, 0x1F, 0x02, 0x6C, 0x00, 0xF2, 0x00, 0x6D, 0xA0, 0x35,
+0xA0, 0x35, 0xC5, 0xF0, 0x11, 0x4D, 0x61, 0xF6, 0x8C, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6,
+0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x15, 0x95, 0x00, 0x1C, 0x5B, 0x1F,
+0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x16, 0x95,
+0x00, 0x1C, 0x2C, 0x1F, 0x02, 0x6C, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35,
+0x2A, 0xF4, 0x13, 0x4D, 0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x01, 0xF4, 0x88, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0xE4, 0x6D, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C,
+0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D, 0x21, 0xF0,
+0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0xB0, 0x67, 0x21, 0xF0, 0x88, 0x41,
+0x00, 0x1C, 0xDD, 0x5B, 0xB0, 0x67, 0xA1, 0xF6, 0x8C, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33,
+0x60, 0x33, 0x4C, 0xEB, 0x51, 0x23, 0x04, 0x95, 0x01, 0x4D, 0x0A, 0x5D,
+0x04, 0xD5, 0x3F, 0xF7, 0x04, 0x61, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8,
+0x00, 0x30, 0x00, 0x30, 0xE1, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x07, 0x95, 0xD1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x08, 0x95,
+0x71, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x09, 0x95, 0x71, 0xF6,
+0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0A, 0x95, 0x71, 0xF6, 0x88, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x0B, 0x95, 0x71, 0xF6, 0x8C, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x0C, 0x95, 0x81, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x0D, 0x95, 0x81, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0E, 0x95,
+0x81, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0F, 0x95, 0x81, 0xF6,
+0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x10, 0x95, 0xD1, 0xF6, 0x80, 0x40,
+0x00, 0x1C, 0xDD, 0x5B, 0x11, 0x95, 0xD1, 0xF6, 0x84, 0x40, 0x00, 0x1C,
+0xDD, 0x5B, 0x12, 0x95, 0x81, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B,
+0x13, 0x95, 0x1C, 0x97, 0x1B, 0x91, 0x1A, 0x90, 0x00, 0xEF, 0x0F, 0x63,
+0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3,
+0x1F, 0x6B, 0x4C, 0xEB, 0x91, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x14, 0xD3, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x34, 0x80, 0x34, 0x8C, 0xEA,
+0x42, 0x33, 0x14, 0x92, 0x62, 0x33, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4,
+0xA0, 0x35, 0x58, 0xEB, 0x63, 0xF3, 0x00, 0x4D, 0x17, 0xD5, 0xE0, 0xF3,
+0x1F, 0x6D, 0x07, 0xF7, 0x00, 0x68, 0x12, 0xEC, 0x82, 0x33, 0x17, 0x94,
+0xAC, 0xEB, 0x00, 0xF4, 0x00, 0x6D, 0x43, 0x9C, 0xAB, 0xED, 0xAC, 0xEA,
+0x6D, 0xEA, 0x43, 0xDC, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x00, 0x30, 0x17, 0x94, 0x00, 0xF4, 0x00, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA,
+0x63, 0x9C, 0xE0, 0xF3, 0x1F, 0x6D, 0x81, 0xF4, 0x80, 0x41, 0xAC, 0xEB,
+0xA2, 0x67, 0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F,
+0x05, 0x6C, 0x91, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x14, 0x93,
+0x42, 0x32, 0x42, 0x32, 0x78, 0xEA, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x33,
+0x17, 0x94, 0x06, 0xD2, 0x43, 0x9C, 0x12, 0xED, 0xAC, 0xEB, 0x10, 0x6D,
+0xAB, 0xED, 0xA0, 0x35, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x68, 0x33,
+0xAC, 0xEA, 0x6D, 0xEA, 0x43, 0xDC, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x6B, 0x6B, 0xEB, 0x17, 0x94, 0x60, 0x33,
+0x60, 0x33, 0xFF, 0x4B, 0x6C, 0xEA, 0x63, 0x9C, 0xE0, 0xF3, 0x1F, 0x6D,
+0x3F, 0x6C, 0x62, 0x33, 0x6A, 0x33, 0xAC, 0xEB, 0x8C, 0xEB, 0x60, 0x33,
+0x60, 0x33, 0xA2, 0x67, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x6D, 0xED, 0x91, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x02, 0xF0, 0x00, 0x6D, 0x06, 0x93, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D,
+0xC0, 0xF3, 0x00, 0x6C, 0xAC, 0xEA, 0x8C, 0xEB, 0xA2, 0x67, 0x06, 0xD3,
+0x80, 0xF5, 0x60, 0x33, 0x91, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x11, 0xF4, 0x84, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xA1, 0xF6, 0x84, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x05, 0xD2, 0xE0, 0xF3, 0x1F, 0x6D, 0xA0, 0x35, 0xA0, 0x35,
+0xAC, 0xEA, 0x42, 0x33, 0x05, 0x92, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC,
+0x62, 0x33, 0x8C, 0xEA, 0x6D, 0xEA, 0x11, 0xF4, 0x84, 0x41, 0xA2, 0x67,
+0x00, 0x1C, 0xDD, 0x5B, 0x05, 0xD2, 0xA1, 0xF6, 0x8C, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0x01, 0x6B, 0x6B, 0xEB, 0x05, 0x95, 0x60, 0x33,
+0x60, 0x33, 0xE0, 0xF3, 0x1F, 0x4B, 0x0C, 0xEA, 0x6C, 0xED, 0x5A, 0x32,
+0x05, 0xD5, 0x11, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED,
+0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6C, 0x4C, 0xEC, 0x14, 0xD4,
+0xB1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3,
+0x1F, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xAC, 0xEA, 0x42, 0x33, 0x62, 0x33,
+0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x18, 0xD3, 0x18, 0x93,
+0x14, 0x94, 0x98, 0xEB, 0xE0, 0xF3, 0x1F, 0x6B, 0x12, 0xED, 0xA2, 0x34,
+0x17, 0x95, 0x6C, 0xEC, 0x63, 0x9D, 0x00, 0xF4, 0x00, 0x6D, 0xAB, 0xED,
+0xAC, 0xEB, 0x8D, 0xEB, 0x17, 0x94, 0xAC, 0xEA, 0xE0, 0xF3, 0x1F, 0x6D,
+0x63, 0xDC, 0xAC, 0xEB, 0xA2, 0x67, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C,
+0xDD, 0x5B, 0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0xB1, 0xF6,
+0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B,
+0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x14, 0x93, 0x42, 0x32, 0x42, 0x32,
+0x78, 0xEA, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x33, 0x17, 0x94, 0x06, 0xD2,
+0x43, 0x9C, 0x12, 0xED, 0xAC, 0xEB, 0x10, 0x6D, 0xAB, 0xED, 0xA0, 0x35,
+0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x68, 0x33, 0xAC, 0xEA, 0x6D, 0xEA,
+0x43, 0xDC, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65,
+0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7, 0x18, 0x4B,
+0x17, 0x94, 0xA0, 0x9B, 0xE0, 0xF3, 0x1F, 0x6B, 0x4C, 0xED, 0x43, 0x9C,
+0x3F, 0x6C, 0x42, 0x32, 0x4A, 0x32, 0x6C, 0xEA, 0x8C, 0xEA, 0x40, 0x32,
+0x40, 0x32, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED,
+0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0,
+0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7, 0x1C, 0x4B, 0xA0, 0x9B,
+0x06, 0x94, 0x4C, 0xED, 0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xEC, 0x80, 0xF5,
+0x80, 0x32, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED,
+0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x11, 0xF4, 0x8C, 0x41, 0x00, 0x1C,
+0xFA, 0x5B, 0x00, 0x65, 0xC1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B,
+0x05, 0xD2, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xDD, 0xF7,
+0x00, 0x4C, 0x60, 0x9C, 0x05, 0x95, 0x11, 0xF4, 0x8C, 0x41, 0x4C, 0xEB,
+0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x62, 0x33, 0x62, 0x33, 0x4C, 0xED,
+0x6D, 0xED, 0x00, 0x1C, 0xDD, 0x5B, 0x05, 0xD5, 0xC1, 0xF6, 0x8C, 0x41,
+0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x01, 0x6C, 0x8B, 0xEC, 0x05, 0x93,
+0x80, 0x34, 0x80, 0x34, 0xE0, 0xF3, 0x1F, 0x4C, 0x8C, 0xEB, 0x4C, 0xE8,
+0xA3, 0x67, 0x1A, 0x30, 0x11, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B,
+0x0D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x1E, 0x16, 0x00, 0x00,
+0xFC, 0x63, 0x00, 0x6B, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x9D, 0x67, 0x26, 0xF7, 0x61, 0xC2, 0x42, 0x6A, 0x50, 0xC4, 0x43, 0x6A,
+0x51, 0xC4, 0x4E, 0x6A, 0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x9E, 0xF5, 0x18, 0x4C, 0xC0, 0xF7, 0x10, 0x6A,
+0x43, 0xDC, 0xBD, 0x67, 0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4,
+0xC0, 0x36, 0x54, 0xC4, 0x13, 0xF6, 0x11, 0x4E, 0x06, 0x62, 0x00, 0x1C,
+0xCF, 0x20, 0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00,
+0xE0, 0x63, 0x3E, 0x62, 0x3C, 0xD0, 0x3D, 0xD1, 0x10, 0xF0, 0x02, 0x6D,
+0x00, 0xF4, 0xA0, 0x35, 0xC7, 0x63, 0x04, 0x04, 0xDD, 0xF7, 0x04, 0x4D,
+0x00, 0x1C, 0xF4, 0x54, 0x94, 0x6E, 0x9D, 0x67, 0x7F, 0x4C, 0x10, 0xF0,
+0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xFF, 0x6E, 0x29, 0x4C, 0x5E, 0xF0,
+0x18, 0x4D, 0x00, 0x1C, 0xF4, 0x54, 0x09, 0x4E, 0x9D, 0x67, 0x10, 0xF0,
+0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xFF, 0x6E, 0xA0, 0xF1, 0x10, 0x4C,
+0x7E, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xF4, 0x54, 0x09, 0x4E, 0x10, 0xF0,
+0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0x6B,
+0x63, 0xC2, 0x00, 0x68, 0xA2, 0x67, 0xFF, 0x6C, 0x08, 0x32, 0x04, 0x06,
+0xAD, 0xE2, 0xC9, 0xE2, 0x40, 0x9A, 0x01, 0x48, 0x8C, 0xE8, 0x25, 0x58,
+0x46, 0xDB, 0xF6, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32,
+0x63, 0xF3, 0x00, 0x4A, 0x00, 0x68, 0x0A, 0x65, 0xFF, 0x69, 0x0C, 0x32,
+0x68, 0x67, 0x04, 0x04, 0x00, 0x6D, 0x7D, 0xE2, 0x99, 0xE2, 0xAD, 0xE6,
+0x80, 0xF0, 0x58, 0xA3, 0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF0, 0x4C, 0xC4,
+0xA0, 0xF1, 0x40, 0xA3, 0x2C, 0xED, 0x08, 0x5D, 0xA0, 0xF1, 0x54, 0xC4,
+0xF2, 0x61, 0x01, 0x48, 0x2C, 0xE8, 0x21, 0x58, 0xE8, 0x61, 0xC8, 0x67,
+0x1F, 0x6A, 0xA0, 0xF2, 0x5E, 0xC6, 0x00, 0x6F, 0x01, 0x6A, 0x62, 0x9E,
+0xA0, 0xF2, 0xFF, 0xC6, 0xC0, 0xF2, 0x40, 0xC6, 0x10, 0xF0, 0x00, 0x6E,
+0xC0, 0x36, 0xC0, 0x36, 0xFF, 0x4E, 0x40, 0x6A, 0xCC, 0xEB, 0x4B, 0xEA,
+0x4C, 0xEB, 0x0C, 0x6A, 0x4D, 0xEB, 0x07, 0xF7, 0x01, 0x6A, 0x4B, 0xEA,
+0x4C, 0xEB, 0x03, 0xF0, 0x00, 0x6A, 0x4D, 0xEB, 0x07, 0xF7, 0x00, 0x6A,
+0x4B, 0xEA, 0x08, 0xF0, 0x00, 0x6C, 0x40, 0x32, 0x8B, 0xEC, 0xFF, 0x4A,
+0x80, 0x34, 0x4C, 0xEB, 0x4F, 0x44, 0x4C, 0xEB, 0x10, 0xF0, 0x00, 0x6A,
+0x4B, 0xEA, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x40, 0x6A, 0x4D, 0xEB,
+0x08, 0xF0, 0x00, 0x6D, 0x81, 0x6A, 0xAD, 0xEB, 0x4B, 0xEA, 0x4C, 0xEB,
+0xFF, 0x6A, 0x01, 0x4A, 0x4B, 0xEA, 0x40, 0x32, 0xEF, 0xF7, 0x1F, 0x4A,
+0x4C, 0xEB, 0x0C, 0xF0, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32,
+0xFF, 0x4A, 0x4C, 0xEB, 0x48, 0x67, 0x62, 0xDA, 0xA0, 0x35, 0x63, 0x9A,
+0x44, 0x9A, 0x80, 0x34, 0xA0, 0x35, 0xFF, 0x4C, 0xFF, 0x4D, 0xAC, 0xEA,
+0x8C, 0xEB, 0x88, 0x67, 0x44, 0xDC, 0x01, 0x6A, 0x4B, 0xEA, 0xC0, 0xF2,
+0x42, 0xC4, 0xFF, 0x6A, 0xCC, 0xEB, 0xC0, 0xF2, 0x44, 0xCC, 0x12, 0x6A,
+0xC0, 0xF2, 0xE6, 0xC4, 0x63, 0xDC, 0xC0, 0xF2, 0x47, 0xC4, 0x00, 0x1C,
+0xF6, 0x48, 0x00, 0x65, 0x39, 0x63, 0x3E, 0x97, 0x3D, 0x91, 0x3C, 0x90,
+0x00, 0xEF, 0x20, 0x63, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34,
+0x63, 0xF3, 0x00, 0x4C, 0xFF, 0xF7, 0x1F, 0x6A, 0x66, 0xF7, 0x4C, 0xDC,
+0x01, 0x6A, 0x4B, 0xEA, 0xFC, 0x63, 0x45, 0xC4, 0x1C, 0x6A, 0x06, 0x62,
+0xC0, 0xF2, 0x4F, 0xC4, 0xC0, 0xF2, 0x51, 0xC4, 0x0A, 0x6A, 0x3E, 0x6B,
+0xC0, 0xF2, 0x52, 0xC4, 0x40, 0x9C, 0xC0, 0xF2, 0x6E, 0xC4, 0xC0, 0xF2,
+0x70, 0xC4, 0x02, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x21, 0x6B, 0x6B, 0xEB,
+0x6C, 0xEA, 0x00, 0x6D, 0x40, 0xDC, 0x06, 0xF0, 0x00, 0x6A, 0xE0, 0xF2,
+0xA6, 0xC4, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C, 0x40, 0x32, 0x40, 0x32,
+0xFF, 0x4A, 0x4C, 0xEB, 0x20, 0x6A, 0xC0, 0xF2, 0x57, 0xC4, 0x08, 0xF0,
+0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB,
+0x10, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB,
+0x20, 0x6A, 0xC0, 0xF2, 0x48, 0xCC, 0xFF, 0x6A, 0x01, 0x4A, 0xE0, 0xF2,
+0x64, 0xDC, 0xC0, 0xF2, 0x4A, 0xCC, 0x01, 0x6B, 0x00, 0xF2, 0x00, 0x6A,
+0xC0, 0xF2, 0xB6, 0xC4, 0xC0, 0xF2, 0xB4, 0xC4, 0xC0, 0xF2, 0xB5, 0xC4,
+0xC0, 0xF2, 0x4C, 0xCC, 0x61, 0xC4, 0x44, 0x6A, 0x9D, 0x67, 0x50, 0xC4,
+0x49, 0x6A, 0x51, 0xC4, 0x47, 0x6A, 0x52, 0xC4, 0xB3, 0xC4, 0x10, 0xF0,
+0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x7E, 0xF5, 0x1C, 0x4C, 0xC0, 0xF7,
+0x10, 0x6A, 0xBD, 0x67, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36,
+0x43, 0xDC, 0x74, 0xC4, 0x93, 0xF6, 0x19, 0x4E, 0x00, 0x1C, 0xCF, 0x20,
+0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0xFA, 0x63, 0x08, 0xD0,
+0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x63, 0xF3, 0x00, 0x48,
+0x40, 0x98, 0x11, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x09, 0x6B, 0x6B, 0xEB,
+0x6C, 0xEA, 0x40, 0xD8, 0x7D, 0x67, 0x44, 0x6A, 0x50, 0xC3, 0x49, 0x6A,
+0x09, 0xD1, 0x51, 0xC3, 0x00, 0x69, 0x47, 0x6A, 0x10, 0xF0, 0x02, 0x6C,
+0x00, 0xF4, 0x80, 0x34, 0x1E, 0xF6, 0x08, 0x4C, 0x52, 0xC3, 0x33, 0xC3,
+0x14, 0x6A, 0x01, 0x6B, 0xBD, 0x67, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4,
+0xC0, 0x36, 0x43, 0xDC, 0x74, 0xC4, 0x10, 0x4D, 0x95, 0xF0, 0x05, 0x4E,
+0x0A, 0x62, 0x00, 0x1C, 0xCF, 0x20, 0x23, 0xC8, 0x5D, 0x67, 0x47, 0x6B,
+0x78, 0xC2, 0x7D, 0x67, 0x3B, 0x6A, 0x59, 0xC3, 0x43, 0x6A, 0x5A, 0xC3,
+0x01, 0x6A, 0x4B, 0xEA, 0x00, 0xF3, 0x44, 0xC0, 0xFF, 0x6A, 0x01, 0x4A,
+0x3B, 0xC3, 0x4B, 0xEA, 0x00, 0xF3, 0x64, 0x98, 0x40, 0x32, 0x40, 0x32,
+0xE0, 0xF0, 0x1F, 0x4A, 0x4C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x40, 0x32,
+0xF3, 0xF0, 0x14, 0x4A, 0x00, 0xF3, 0x4C, 0xD8, 0xFF, 0x6A, 0x01, 0x4A,
+0x40, 0x32, 0x46, 0xF0, 0x16, 0x4A, 0x00, 0xF3, 0x64, 0xD8, 0x00, 0xF3,
+0x50, 0xD8, 0x60, 0x98, 0x02, 0x6A, 0x00, 0xF3, 0x47, 0xC0, 0x05, 0x6A,
+0x4B, 0xEA, 0x00, 0x6C, 0x4C, 0xEB, 0x81, 0x6A, 0x00, 0xF3, 0x88, 0xD8,
+0x00, 0xF3, 0x94, 0xD8, 0x00, 0xF3, 0x98, 0xD8, 0x4B, 0xEA, 0x10, 0xF0,
+0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x4C, 0xEB, 0xBE, 0xF5, 0x14, 0x4C,
+0xC0, 0xF7, 0x10, 0x6A, 0x60, 0xD8, 0xBD, 0x67, 0x43, 0xDC, 0x10, 0xF0,
+0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x01, 0x6A, 0x54, 0xC4, 0x55, 0xF1,
+0x09, 0x4E, 0x00, 0x1C, 0xCF, 0x20, 0x18, 0x4D, 0x4A, 0x6A, 0x00, 0xF3,
+0x5C, 0xC0, 0x45, 0x6A, 0x00, 0xF3, 0x5D, 0xC0, 0x46, 0x6A, 0x00, 0xF3,
+0x5E, 0xC0, 0x40, 0x6A, 0x00, 0xF3, 0x5F, 0xC0, 0x23, 0x6A, 0x20, 0xF3,
+0x40, 0xC0, 0x1E, 0x6A, 0x20, 0xF3, 0x41, 0xC0, 0x0A, 0x97, 0x09, 0x91,
+0x08, 0x90, 0x00, 0xEF, 0x06, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x7D, 0x67,
+0x3B, 0x6A, 0x50, 0xC3, 0x43, 0x6A, 0x51, 0xC3, 0x36, 0x6A, 0x52, 0xC3,
+0x00, 0x6B, 0x5D, 0x67, 0x73, 0xC2, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4,
+0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4,
+0x80, 0x34, 0xDE, 0xF5, 0x10, 0x4C, 0xC0, 0xF2, 0x73, 0xC2, 0xC0, 0xF7,
+0x10, 0x6A, 0x43, 0xDC, 0xBD, 0x67, 0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E,
+0x00, 0xF4, 0xC0, 0x36, 0x54, 0xC4, 0x95, 0xF4, 0x05, 0x4E, 0x06, 0x62,
+0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63,
+0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xFC, 0x63, 0x63, 0xF3,
+0x00, 0x4A, 0x01, 0x6D, 0x00, 0x6B, 0x9D, 0x67, 0x66, 0xF7, 0xB6, 0xCA,
+0x66, 0xF7, 0x74, 0xCA, 0x52, 0x6A, 0x50, 0xC4, 0x53, 0x6A, 0x51, 0xC4,
+0x54, 0x6A, 0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4,
+0x80, 0x34, 0x3E, 0xF6, 0x04, 0x4C, 0xE0, 0xF1, 0x14, 0x6A, 0xB4, 0xC4,
+0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0xBD, 0x67, 0x43, 0xDC,
+0x10, 0xF5, 0x0D, 0x4E, 0x06, 0x62, 0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D,
+0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x65, 0xD8, 0xFF, 0xBD, 0x27,
+0x02, 0x80, 0x03, 0x3C, 0x20, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF,
+0x18, 0x00, 0xB0, 0xAF, 0x74, 0xF2, 0x62, 0x24, 0x02, 0x00, 0x48, 0x90,
+0x74, 0xF2, 0x67, 0x94, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x5D, 0x42, 0x24,
+0x02, 0x00, 0x10, 0x24, 0x01, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x40, 0x00,
+0x14, 0x00, 0x50, 0xA0, 0x10, 0x00, 0xA5, 0x27, 0xFC, 0xC1, 0xC6, 0x24,
+0x02, 0x80, 0x11, 0x3C, 0x20, 0x5E, 0x31, 0x26, 0x10, 0x00, 0xA7, 0xA7,
+0x12, 0x00, 0xA8, 0xA3, 0xCF, 0x20, 0x00, 0x0C, 0x13, 0x00, 0xA0, 0xA3,
+0x02, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x20, 0x02, 0x10, 0x00, 0xA5, 0x27,
+0x14, 0x00, 0x30, 0xA2, 0xCF, 0x20, 0x00, 0x0C, 0x08, 0x86, 0xC6, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x40, 0xA0, 0x0C, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x64, 0xA0,
+0xEE, 0x5D, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0x04, 0x5E, 0x60, 0xA0, 0x06, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C,
+0x02, 0x80, 0x02, 0x3C, 0x0C, 0x5E, 0x60, 0xA0, 0x01, 0x00, 0x06, 0x24,
+0x0D, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C,
+0xF0, 0x5D, 0x66, 0xA0, 0x12, 0x00, 0x04, 0x24, 0x0E, 0x5E, 0x40, 0xA0,
+0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xEF, 0x5D, 0x66, 0xA0,
+0xF1, 0x5D, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x0C, 0x00, 0x04, 0x24,
+0x02, 0x80, 0x02, 0x3C, 0xF2, 0x5D, 0x60, 0xA0, 0x02, 0x80, 0x05, 0x3C,
+0xFC, 0x5D, 0x44, 0xA4, 0x64, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0xF4, 0x5D, 0xA3, 0xA4, 0xC6, 0x5C, 0x43, 0x90, 0xF4, 0x5D, 0xA4, 0x94,
+0x02, 0x00, 0x05, 0x24, 0x02, 0x00, 0x63, 0x30, 0x01, 0x00, 0x63, 0x2C,
+0xFF, 0xFF, 0x84, 0x30, 0x23, 0x28, 0xA3, 0x00, 0x80, 0x22, 0x04, 0x00,
+0x02, 0x80, 0x02, 0x3C, 0xE8, 0x03, 0x03, 0x24, 0xF8, 0x5D, 0x44, 0xAC,
+0x0C, 0x00, 0x23, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x00, 0x5E, 0x40, 0xAC, 0x05, 0x5E, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x40, 0xA0, 0x0F, 0x5E, 0x60, 0xA0,
+0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x3C, 0x5E, 0x45, 0xA0,
+0x20, 0x00, 0xBF, 0x8F, 0x08, 0x5E, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F,
+0x09, 0x5E, 0x46, 0xA0, 0x0A, 0x5E, 0x66, 0xA0, 0x02, 0x80, 0x02, 0x3C,
+0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x40, 0xA0, 0x21, 0x20, 0x00, 0x00,
+0x10, 0x5E, 0x60, 0xAC, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C,
+0x21, 0x28, 0x00, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x14, 0x5E, 0x40, 0xAC,
+0x18, 0x5E, 0x64, 0xAC, 0x1C, 0x5E, 0x65, 0xAC, 0x08, 0x00, 0xE0, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x21, 0x98, 0xA0, 0x00,
+0x21, 0x88, 0xC0, 0x00, 0x21, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82,
+0x5C, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x10, 0x26, 0xFF, 0xFF, 0x10, 0x26, 0x00, 0x00, 0x04, 0x92,
+0x2B, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x41, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x24,
+0x30, 0x00, 0x22, 0x12, 0x00, 0x1E, 0x04, 0x00, 0x07, 0x00, 0x20, 0x16,
+0x21, 0x18, 0x80, 0x00, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x30, 0x00, 0x02, 0x24, 0x3B, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x11, 0x24,
+0x21, 0x18, 0x80, 0x00, 0x00, 0x16, 0x03, 0x00, 0x03, 0x16, 0x02, 0x00,
+0x1A, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x64, 0x30, 0xA9, 0xFF, 0x82, 0x24,
+0x61, 0x00, 0x83, 0x2C, 0xFF, 0x00, 0x45, 0x30, 0x09, 0x00, 0x60, 0x10,
+0x41, 0x00, 0x86, 0x2C, 0xC9, 0xFF, 0x82, 0x24, 0xFF, 0x00, 0x45, 0x30,
+0x05, 0x00, 0xC0, 0x10, 0x3A, 0x00, 0x87, 0x2C, 0xD0, 0xFF, 0x82, 0x24,
+0x02, 0x00, 0xE0, 0x10, 0xFF, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x45, 0x30,
+0x2A, 0x10, 0xB1, 0x00, 0x0A, 0x00, 0x40, 0x10, 0x18, 0x00, 0x51, 0x02,
+0x01, 0x00, 0x10, 0x26, 0x12, 0x10, 0x00, 0x00, 0x2B, 0x18, 0x52, 0x00,
+0x23, 0x00, 0x60, 0x14, 0x21, 0x90, 0xA2, 0x00, 0x00, 0x00, 0x03, 0x92,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0x60, 0x14, 0xFF, 0x00, 0x64, 0x30,
+0x02, 0x00, 0x60, 0x12, 0x21, 0x10, 0x40, 0x02, 0x00, 0x00, 0x70, 0xAE,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03,
+0x28, 0x00, 0xBD, 0x27, 0x03, 0x1E, 0x03, 0x00, 0x30, 0x00, 0x02, 0x24,
+0xCE, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x82,
+0x78, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x10, 0x58, 0x00, 0x02, 0x24,
+0xD0, 0xFF, 0x62, 0x14, 0x21, 0x18, 0x80, 0x00, 0x02, 0x00, 0x10, 0x26,
+0x00, 0x00, 0x04, 0x92, 0x63, 0x71, 0x00, 0x08, 0x10, 0x00, 0x11, 0x24,
+0x01, 0x00, 0x10, 0x26, 0x00, 0x00, 0x04, 0x92, 0x5A, 0x71, 0x00, 0x08,
+0x10, 0x00, 0x02, 0x24, 0x8F, 0x71, 0x00, 0x08, 0x08, 0x00, 0x11, 0x24,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0x02, 0x24,
+0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x21, 0x48, 0x80, 0x00,
+0x31, 0x00, 0xC0, 0x14, 0x21, 0x50, 0x00, 0x00, 0x00, 0x00, 0x87, 0x90,
+0x30, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x07, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x2E, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C,
+0x40, 0xF4, 0x4B, 0x24, 0xFF, 0x00, 0xE8, 0x30, 0x21, 0x10, 0x0B, 0x01,
+0x00, 0x00, 0x44, 0x90, 0x00, 0x1E, 0x07, 0x00, 0x03, 0x1E, 0x03, 0x00,
+0x44, 0x00, 0x82, 0x30, 0x02, 0x00, 0x87, 0x30, 0xD0, 0xFF, 0x63, 0x24,
+0x1A, 0x00, 0x40, 0x10, 0x04, 0x00, 0x84, 0x30, 0x07, 0x00, 0x80, 0x14,
+0x2B, 0x10, 0x66, 0x00, 0x21, 0x10, 0x00, 0x01, 0x02, 0x00, 0xE0, 0x10,
+0xE0, 0xFF, 0x03, 0x25, 0xFF, 0x00, 0x62, 0x30, 0xC9, 0xFF, 0x43, 0x24,
+0x2B, 0x10, 0x66, 0x00, 0x10, 0x00, 0x40, 0x10, 0x18, 0x00, 0x46, 0x01,
+0x01, 0x00, 0x29, 0x25, 0x00, 0x00, 0x27, 0x91, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0x00, 0xE8, 0x30, 0x12, 0x10, 0x00, 0x00, 0x21, 0x50, 0x43, 0x00,
+0x21, 0x10, 0x0B, 0x01, 0x00, 0x00, 0x44, 0x90, 0x00, 0x1E, 0x07, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0x44, 0x00, 0x82, 0x30, 0x02, 0x00, 0x87, 0x30,
+0xD0, 0xFF, 0x63, 0x24, 0xE8, 0xFF, 0x40, 0x14, 0x04, 0x00, 0x84, 0x30,
+0x02, 0x00, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC,
+0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x40, 0x01, 0x00, 0x00, 0x87, 0x90,
+0xB1, 0x71, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x89, 0x24,
+0x00, 0x00, 0x27, 0x91, 0x78, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x07, 0x00,
+0x03, 0x1E, 0x03, 0x00, 0xCD, 0xFF, 0x62, 0x14, 0x08, 0x00, 0x06, 0x24,
+0x01, 0x00, 0x22, 0x91, 0x02, 0x80, 0x03, 0x3C, 0x40, 0xF4, 0x63, 0x24,
+0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x00, 0x00, 0x00, 0x00,
+0x44, 0x00, 0x84, 0x30, 0xC5, 0xFF, 0x80, 0x10, 0x02, 0x80, 0x02, 0x3C,
+0x01, 0x00, 0x29, 0x25, 0x00, 0x00, 0x27, 0x91, 0xB1, 0x71, 0x00, 0x08,
+0x10, 0x00, 0x06, 0x24, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF,
+0x00, 0x00, 0x83, 0x80, 0x2D, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0xA7, 0x71, 0x00, 0x08,
+0x18, 0x00, 0xBD, 0x27, 0xA7, 0x71, 0x00, 0x0C, 0x01, 0x00, 0x84, 0x24,
+0x10, 0x00, 0xBF, 0x8F, 0x23, 0x10, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03,
+0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF,
+0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF,
+0x20, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x21, 0x90, 0xA0, 0x00,
+0x21, 0x98, 0xC0, 0x00, 0x21, 0x88, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82,
+0x5C, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14,
+0x01, 0x00, 0x10, 0x26, 0xFF, 0xFF, 0x10, 0x26, 0x00, 0x00, 0x03, 0x82,
+0x2D, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x02,
+0x21, 0x28, 0x40, 0x02, 0x43, 0x71, 0x00, 0x0C, 0x21, 0x30, 0x60, 0x02,
+0x12, 0x00, 0x40, 0x04, 0x21, 0x18, 0x40, 0x00, 0x23, 0x10, 0x02, 0x00,
+0x0A, 0x10, 0x71, 0x00, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F,
+0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F,
+0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x10, 0x26,
+0x21, 0x20, 0x00, 0x02, 0x21, 0x28, 0x40, 0x02, 0x43, 0x71, 0x00, 0x0C,
+0x21, 0x30, 0x60, 0x02, 0xFF, 0xFF, 0x11, 0x24, 0xF0, 0xFF, 0x41, 0x04,
+0x21, 0x18, 0x40, 0x00, 0xF0, 0xFF, 0x20, 0x16, 0x00, 0x80, 0x02, 0x3C,
+0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F,
+0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0x7F, 0x02, 0x3C,
+0xFF, 0xFF, 0x42, 0x34, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7F,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x02, 0x7E, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x03, 0x7D,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x04, 0x7C, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x05, 0x7B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x06, 0x7A,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x07, 0x79, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x08, 0x78, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x09, 0x77,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x76, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x0B, 0x75, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0C, 0x74,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x73, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x0E, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x71,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x10, 0x70, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x11, 0x6F, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x12, 0x6F,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x13, 0x6E, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x14, 0x6D, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x15, 0x6D,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x16, 0x6C, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x17, 0x6B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x18, 0x6A,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x19, 0x6A, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x1A, 0x69, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1B, 0x68,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1C, 0x67, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x1D, 0x66, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1E, 0x65,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x64, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x20, 0x63, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x21, 0x4C,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x22, 0x4B, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x23, 0x4A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x24, 0x49,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x25, 0x48, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x26, 0x47, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x27, 0x46,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x28, 0x45, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x29, 0x44, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2A, 0x2C,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2B, 0x2B, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x2C, 0x2A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2D, 0x29,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2E, 0x28, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x2F, 0x27, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x30, 0x26,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x31, 0x25, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x32, 0x24, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x33, 0x23,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x34, 0x22, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x35, 0x09, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x36, 0x08,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x37, 0x07, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x38, 0x06, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x39, 0x05,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3A, 0x04, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x3B, 0x03, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3C, 0x02,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3D, 0x01, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x3E, 0x00, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3F, 0x00,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x40, 0x7F, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x41, 0x7F, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x42, 0x7E,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x43, 0x7D, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x44, 0x7C, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x45, 0x7B,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x46, 0x7A, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x47, 0x79, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x48, 0x78,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x49, 0x77, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x4A, 0x76, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4B, 0x75,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4C, 0x74, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x4D, 0x73, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4E, 0x72,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4F, 0x71, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x50, 0x70, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x51, 0x6F,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x52, 0x6F, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x53, 0x6E, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x54, 0x6D,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x55, 0x6D, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x56, 0x6C, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x57, 0x6B,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x58, 0x6A, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x59, 0x6A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5A, 0x69,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5B, 0x68, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x5C, 0x67, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5D, 0x66,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5E, 0x65, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x5F, 0x64, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x60, 0x63,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x61, 0x4C, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x62, 0x4B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x63, 0x4A,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x64, 0x49, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x65, 0x48, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x66, 0x47,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x67, 0x46, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x68, 0x45, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x69, 0x44,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6A, 0x2C, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x6B, 0x2B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6C, 0x2A,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6D, 0x29, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x6E, 0x28, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6F, 0x27,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x70, 0x26, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x71, 0x25, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x72, 0x24,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x73, 0x23, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x74, 0x22, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x75, 0x09,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x76, 0x08, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x77, 0x07, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x78, 0x06,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x79, 0x05, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x7A, 0x04, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7B, 0x03,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7C, 0x02, 0x78, 0x0C, 0x00, 0x00,
+0x01, 0x00, 0x7D, 0x01, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7E, 0x00,
+0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7F, 0x00, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x00, 0x30, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x01, 0x30,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x02, 0x30, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x03, 0x30, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x30,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x05, 0x34, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x06, 0x38, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x07, 0x3E,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x08, 0x3E, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x09, 0x44, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0A, 0x46,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0B, 0x48, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x0C, 0x48, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0D, 0x4E,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0E, 0x56, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x0F, 0x5A, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x10, 0x5E,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x11, 0x62, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x12, 0x6C, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x13, 0x72,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x14, 0x72, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x15, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x16, 0x72,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x17, 0x72, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x18, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x19, 0x72,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1A, 0x72, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x1B, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1C, 0x72,
+0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1D, 0x72, 0x78, 0x0C, 0x00, 0x00,
+0x1E, 0x00, 0x1E, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1F, 0x72,
+0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x06, 0x06, 0x04,
+0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00,
+0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x08, 0x08, 0x04,
+0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00,
+0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x08, 0x08, 0x04,
+0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00,
+0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00,
+0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00,
+0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x02, 0x00,
+0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
+0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
+0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
+0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
+0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
+0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x13, 0x00, 0x00, 0x00,
+0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00,
+0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x02, 0x00, 0x30, 0x00,
+0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
+0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x77, 0x77, 0x00, 0x00,
+0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0A, 0x00, 0x00, 0x00,
+0x44, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00,
+0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x02, 0x00, 0x10, 0x00,
+0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
+0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00,
+0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x77, 0x77, 0x00, 0x00,
+0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0A, 0x00, 0x00, 0x00,
+0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x00, 0x04, 0x08, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00,
+0x08, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x0C, 0x08, 0x00, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x88, 0x50, 0x00, 0x10,
+0x14, 0x08, 0x00, 0x00, 0x10, 0x3D, 0x0C, 0x02, 0x18, 0x08, 0x00, 0x00,
+0x85, 0x01, 0x20, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, 0x08, 0x00, 0x00,
+0x04, 0x00, 0x39, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x2C, 0x08, 0x00, 0x00, 0x04, 0x00, 0x39, 0x00, 0x30, 0x08, 0x00, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0x00, 0x02, 0x69, 0x00,
+0x38, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3C, 0x08, 0x00, 0x00,
+0x00, 0x02, 0x69, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x44, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x4C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48,
+0x5C, 0x08, 0x00, 0x00, 0xA9, 0x65, 0xA9, 0x65, 0x60, 0x08, 0x00, 0x00,
+0x30, 0x01, 0x7F, 0x0F, 0x64, 0x08, 0x00, 0x00, 0x30, 0x01, 0x7F, 0x0F,
+0x68, 0x08, 0x00, 0x00, 0x30, 0x01, 0x7F, 0x0F, 0x6C, 0x08, 0x00, 0x00,
+0x30, 0x01, 0x7F, 0x0F, 0x70, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03,
+0x74, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x78, 0x08, 0x00, 0x00,
+0x02, 0x00, 0x02, 0x00, 0x7C, 0x08, 0x00, 0x00, 0x01, 0x02, 0x4F, 0x00,
+0x80, 0x08, 0x00, 0x00, 0xC1, 0x0A, 0x30, 0xA8, 0x84, 0x08, 0x00, 0x00,
+0x58, 0x00, 0x00, 0x00, 0x88, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x8C, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x90, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x94, 0x08, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF,
+0x98, 0x08, 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x9C, 0x08, 0x00, 0x00,
+0x50, 0x60, 0x70, 0x00, 0xB0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x33, 0x33, 0x33, 0x30,
+0x04, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A, 0x08, 0x0E, 0x00, 0x00,
+0x32, 0x32, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x33, 0x33, 0x33, 0x30,
+0x14, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A, 0x18, 0x0E, 0x00, 0x00,
+0x33, 0x33, 0x33, 0x30, 0x1C, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A,
+0x30, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01, 0x34, 0x0E, 0x00, 0x00,
+0x00, 0x48, 0x00, 0x01, 0x38, 0x0E, 0x00, 0x00, 0x1F, 0xDC, 0x00, 0x10,
+0x3C, 0x0E, 0x00, 0x00, 0x1F, 0x8C, 0x00, 0x10, 0x40, 0x0E, 0x00, 0x00,
+0xA0, 0x00, 0x14, 0x02, 0x44, 0x0E, 0x00, 0x00, 0xA0, 0x00, 0x16, 0x28,
+0x48, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF8, 0x4C, 0x0E, 0x00, 0x00,
+0x10, 0x29, 0x00, 0x00, 0x50, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01,
+0x54, 0x0E, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x58, 0x0E, 0x00, 0x00,
+0x1F, 0xDC, 0x00, 0x10, 0x5C, 0x0E, 0x00, 0x00, 0x1F, 0x8C, 0x00, 0x10,
+0x60, 0x0E, 0x00, 0x00, 0xA0, 0x00, 0x14, 0x02, 0x64, 0x0E, 0x00, 0x00,
+0xA0, 0x00, 0x16, 0x28, 0x6C, 0x0E, 0x00, 0x00, 0x10, 0x29, 0x00, 0x00,
+0x70, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31, 0x74, 0x0E, 0x00, 0x00,
+0xFB, 0x36, 0x15, 0x36, 0x78, 0x0E, 0x00, 0x00, 0xFB, 0x36, 0x15, 0x36,
+0x7C, 0x0E, 0x00, 0x00, 0xFB, 0x36, 0x15, 0x36, 0x80, 0x0E, 0x00, 0x00,
+0xFB, 0x36, 0x15, 0x36, 0x84, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00,
+0x88, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, 0x8C, 0x0E, 0x00, 0x00,
+0xFB, 0x92, 0xED, 0x31, 0xD0, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31,
+0xD4, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31, 0xD8, 0x0E, 0x00, 0x00,
+0xFB, 0x92, 0x0D, 0x00, 0xDC, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00,
+0xE0, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, 0xE4, 0x0E, 0x00, 0x00,
+0x48, 0x54, 0x5E, 0x01, 0xE8, 0x0E, 0x00, 0x00, 0x48, 0x54, 0x55, 0x21,
+0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0x00,
+0x23, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x0C, 0x09, 0x00, 0x00, 0x13, 0x13, 0x12, 0x01, 0x00, 0x0A, 0x00, 0x00,
+0xC8, 0x47, 0xD0, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x08, 0x00, 0xFF, 0x80,
+0x08, 0x0A, 0x00, 0x00, 0x00, 0x83, 0xCD, 0x88, 0x0C, 0x0A, 0x00, 0x00,
+0x0F, 0x12, 0x62, 0x2E, 0x10, 0x0A, 0x00, 0x00, 0x78, 0xBB, 0x00, 0x95,
+0x14, 0x0A, 0x00, 0x00, 0x28, 0x40, 0x14, 0x11, 0x18, 0x0A, 0x00, 0x00,
+0x17, 0x11, 0x88, 0x00, 0x1C, 0x0A, 0x00, 0x00, 0x00, 0x0F, 0x14, 0x89,
+0x20, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1A, 0x24, 0x0A, 0x00, 0x00,
+0x17, 0x13, 0x0E, 0x09, 0x28, 0x0A, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00,
+0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x10, 0x00, 0x0C, 0x00, 0x00,
+0x40, 0x1D, 0x07, 0x40, 0x04, 0x0C, 0x00, 0x00, 0x33, 0x56, 0xA0, 0x00,
+0x08, 0x0C, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00,
+0x6C, 0x6C, 0x6C, 0x6C, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+0x14, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x18, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x08, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x0C, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x40, 0x28, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+0x2C, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x30, 0x0C, 0x00, 0x00,
+0x44, 0xAC, 0xE9, 0x6D, 0x34, 0x0C, 0x00, 0x00, 0xCF, 0x52, 0x96, 0x46,
+0x38, 0x0C, 0x00, 0x00, 0x94, 0x59, 0x79, 0x49, 0x3C, 0x0C, 0x00, 0x00,
+0x64, 0x97, 0x97, 0x0A, 0x40, 0x0C, 0x00, 0x00, 0x3F, 0x40, 0x7C, 0x1F,
+0x44, 0x0C, 0x00, 0x00, 0xB7, 0x00, 0x01, 0x00, 0x48, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xEC, 0x4C, 0x0C, 0x00, 0x00, 0x7F, 0x03, 0x7F, 0x00,
+0x50, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69, 0x54, 0x0C, 0x00, 0x00,
+0x94, 0x00, 0x3C, 0x43, 0x58, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69,
+0x5C, 0x0C, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x43, 0x60, 0x0C, 0x00, 0x00,
+0x20, 0x34, 0x54, 0x69, 0x64, 0x0C, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x43,
+0x68, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69, 0x6C, 0x0C, 0x00, 0x00,
+0x94, 0x00, 0x3C, 0x43, 0x70, 0x0C, 0x00, 0x00, 0x0D, 0x00, 0x7F, 0x2C,
+0x74, 0x0C, 0x00, 0x00, 0x5B, 0x17, 0x86, 0x01, 0x78, 0x0C, 0x00, 0x00,
+0x1F, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, 0x12, 0x16, 0xB9, 0x00,
+0x80, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x84, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0xF6, 0x20, 0x88, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20,
+0x8C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x90, 0x0C, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x40, 0x94, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x98, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x9C, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x00, 0x92, 0x24, 0x49, 0x00,
+0xA4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xB0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xB8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xBC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xC0, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xC4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xD0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xD4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x0C, 0x00, 0x00,
+0x27, 0x24, 0xB2, 0x64, 0xDC, 0x0C, 0x00, 0x00, 0x32, 0x69, 0x76, 0x00,
+0xE0, 0x0C, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0xE4, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xE8, 0x0C, 0x00, 0x00, 0x02, 0x43, 0x64, 0x37,
+0xEC, 0x0C, 0x00, 0x00, 0x0C, 0xD4, 0x97, 0x2F, 0x00, 0x0D, 0x00, 0x00,
+0x50, 0x07, 0x00, 0x00, 0x04, 0x0D, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00,
+0x08, 0x0D, 0x00, 0x00, 0x7F, 0x90, 0x00, 0x00, 0x0C, 0x0D, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x33, 0x33, 0x63, 0xA0,
+0x14, 0x0D, 0x00, 0x00, 0x63, 0x3C, 0x33, 0x33, 0x18, 0x0D, 0x00, 0x00,
+0x6B, 0x5B, 0x8F, 0x6A, 0x1C, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x0D, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x28, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x2C, 0x0D, 0x00, 0x00, 0x75, 0x99, 0x97, 0xCC, 0x30, 0x0D, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x38, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x00, 0x00,
+0x93, 0x72, 0x02, 0x00, 0x40, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x44, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0D, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x50, 0x0D, 0x00, 0x00, 0x0A, 0x14, 0x37, 0x64,
+0x54, 0x0D, 0x00, 0x00, 0x02, 0xBD, 0x4D, 0x02, 0x58, 0x0D, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, 0x64, 0x20, 0x03, 0x30,
+0x60, 0x0D, 0x00, 0x00, 0x68, 0xDE, 0x53, 0x46, 0x64, 0x0D, 0x00, 0x00,
+0x3C, 0x8A, 0x51, 0x00, 0x68, 0x0D, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00,
+0x14, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4C, 0x0F, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+0x40, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x00, 0x00, 0x84, 0x02, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00,
+0xB4, 0x02, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x01, 0x80,
+0x10, 0x00, 0x00, 0x00, 0xC8, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00,
+0xD0, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x01, 0x80,
+0x10, 0x00, 0x00, 0x00, 0xB0, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00,
+0xB8, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x01, 0x80,
+0x10, 0x00, 0x00, 0x00, 0x18, 0x09, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00,
+0x58, 0x04, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x50, 0x04, 0x01, 0x80,
+0x10, 0x00, 0x00, 0x00, 0x20, 0x09, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00,
+0x28, 0x09, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00, 0xF0, 0x28, 0x00, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x88, 0x06, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00,
+0xF0, 0x28, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0xAC, 0x2B, 0x00, 0x80,
+0x30, 0x00, 0x00, 0x00, 0x58, 0x2C, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
+0x1C, 0x2F, 0x00, 0x80, 0x13, 0x00, 0x00, 0x00, 0x7C, 0x07, 0x01, 0x80,
+0x17, 0x00, 0x00, 0x00, 0xD0, 0x07, 0x01, 0x80, 0x06, 0x00, 0x00, 0x00,
+0x58, 0x08, 0x01, 0x80, 0x06, 0x00, 0x00, 0x00, 0x60, 0x08, 0x01, 0x80,
+0x08, 0x00, 0x00, 0x00, 0x68, 0x08, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00,
+0x70, 0x08, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0x78, 0x08, 0x01, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x80, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00,
+0x88, 0x08, 0x01, 0x80, 0x38, 0x00, 0x00, 0x00, 0x90, 0x08, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x98, 0x08, 0x01, 0x80, 0x02, 0x00, 0x00, 0x00,
+0xA0, 0x08, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xA8, 0x08, 0x01, 0x80,
+0x01, 0x00, 0x00, 0x00, 0xE8, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00,
+0xF0, 0x08, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00, 0x60, 0x04, 0x01, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x68, 0x04, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00,
+0x80, 0x06, 0x01, 0x80, 0x34, 0x00, 0x00, 0x00, 0xF8, 0x08, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00,
+0x30, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0x38, 0x09, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x40, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00,
+0x08, 0x09, 0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x03, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x48, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00,
+0xC0, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xCC, 0x09, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0xD4, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00,
+0xDC, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0xEC, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00,
+0xF4, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x01, 0x80,
+0x04, 0x00, 0x00, 0x00, 0x04, 0x0A, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00,
+0x0C, 0x0A, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x30, 0x0B, 0x01, 0x80,
+0x10, 0x00, 0x00, 0x00, 0x0C, 0x33, 0x00, 0x80, 0x06, 0x00, 0x00, 0x00,
+0x6C, 0x0B, 0x01, 0x80, 0x13, 0x00, 0x00, 0x00, 0xF8, 0x9E, 0x02, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xC8, 0x5E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xF8, 0x0E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xC8, 0xCE, 0x01, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xD4, 0x8E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xA4, 0x4E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0xD0, 0x0E, 0x01, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xA0, 0xCE, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xD0, 0x86, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xA0, 0x46, 0x00, 0x00,
+0x13, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xA4, 0x9E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0x74, 0x5E, 0x02, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xA4, 0x0E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xD0, 0xCE, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0x40, 0x9F, 0x01, 0x00,
+0x13, 0x00, 0x00, 0x00, 0x70, 0x4E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00,
+0xA0, 0x06, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0x70, 0xC6, 0x00, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xA0, 0x82, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+0x70, 0x42, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00,
+0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44,
+0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00,
+0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44,
+0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00,
+0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44,
+0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00,
+0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44,
+0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x41, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00,
+0x05, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00,
+0x03, 0xC8, 0x0F, 0x00, 0x13, 0x00, 0x00, 0x00, 0xB0, 0x7C, 0x01, 0x00,
+0x13, 0x00, 0x00, 0x00, 0xC0, 0x1C, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00,
+0x60, 0xDC, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x60, 0x8C, 0x00, 0x00,
+0x13, 0x00, 0x00, 0x00, 0x50, 0x44, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x03, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x50, 0x02, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00,
+0x11, 0x00, 0x00, 0x00, 0xFC, 0x31, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00,
+0x0F, 0x00, 0x0C, 0x00, 0x11, 0x00, 0x00, 0x00, 0xF8, 0xF9, 0x03, 0x00,
+0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00,
+0x01, 0x01, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3E, 0x09, 0x01, 0x00,
+0x14, 0x00, 0x00, 0x00, 0x3E, 0x09, 0x09, 0x00, 0x15, 0x00, 0x00, 0x00,
+0xF4, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0F, 0x00,
+0x1A, 0x00, 0x00, 0x00, 0x56, 0x30, 0x01, 0x00, 0x1B, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x06, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+0x1E, 0x00, 0x00, 0x00, 0x59, 0x10, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3C, 0x08, 0x00, 0x00,
+0x23, 0x00, 0x00, 0x00, 0x58, 0x15, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+0x60, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x83, 0x25, 0x02, 0x00,
+0x26, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
+0xF1, 0xAC, 0x0E, 0x00, 0x28, 0x00, 0x00, 0x00, 0x54, 0xBD, 0x09, 0x00,
+0x29, 0x00, 0x00, 0x00, 0x82, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x34, 0x13, 0x02, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x05, 0x00,
+0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x33, 0xB3, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00,
+0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x09, 0x07, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x33, 0x33, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x06, 0x00,
+0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x09, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x33, 0xB3, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x0A, 0x06, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x06, 0x00,
+0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00,
+0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+0x2B, 0x00, 0x00, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+0x2A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
+0x0B, 0x05, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x23, 0x66, 0x06, 0x00,
+0x2C, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x0E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+0x31, 0x00, 0x00, 0x00, 0x31, 0x96, 0x0B, 0x00, 0x32, 0x00, 0x00, 0x00,
+0x0D, 0x13, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00,
+0x13, 0x00, 0x00, 0x00, 0x6C, 0x9E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00,
+0x94, 0x5E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x01, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x01, 0xF4, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x5B, 0x10, 0x03, 0x00,
+0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x59, 0x01, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x04, 0x00,
+0x11, 0x00, 0x00, 0x00, 0xF9, 0x03, 0x02, 0x00, 0x6C, 0x09, 0x00, 0x00,
+0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
+0x0D, 0x00, 0x00, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
+0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x17, 0x05, 0x03,
+0x22, 0x43, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x00, 0x00,
+0x22, 0x43, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x22, 0x43, 0x5E, 0x00,
+0x4F, 0xA4, 0x3E, 0x00, 0x30, 0xA6, 0x00, 0x00, 0x4F, 0xA4, 0x3E, 0x00,
+0x2B, 0xA4, 0x5E, 0x00, 0x2B, 0xA4, 0x00, 0x00, 0x2B, 0xA4, 0x5E, 0x00,
+0x22, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x00, 0x00,
+0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00,
+0x1C, 0x42, 0x2F, 0x00, 0x4F, 0x64, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00,
+0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x5E, 0x00,
+0x00, 0xE0, 0x4C, 0x02, 0x01, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x4C, 0x00,
+0x00, 0x0C, 0x43, 0x00, 0x00, 0x50, 0x43, 0x00, 0x00, 0x40, 0x96, 0x00,
+0x00, 0x05, 0xB5, 0x00, 0x00, 0x0A, 0xF7, 0x00, 0x00, 0x10, 0x18, 0x00,
+0x00, 0x21, 0x91, 0x00, 0x00, 0x1C, 0xF0, 0x00, 0x00, 0x13, 0x74, 0x00,
+0x00, 0x03, 0x7F, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x01, 0x01, 0x00, 0x00,
+0x00, 0x50, 0xF2, 0x02, 0x00, 0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xE7, 0x01, 0x80,
+0xE0, 0x25, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x01, 0x80,
+0xE8, 0x25, 0x01, 0x80, 0x20, 0x00, 0x00, 0x00, 0xC8, 0xE7, 0x01, 0x80,
+0xE0, 0x25, 0x01, 0x80, 0x30, 0x00, 0x00, 0x00, 0xD8, 0xE7, 0x01, 0x80,
+0xE8, 0x25, 0x01, 0x80, 0x40, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0x01, 0x80,
+0x44, 0x43, 0x00, 0x80, 0x50, 0x00, 0x00, 0x00, 0xF4, 0xE7, 0x01, 0x80,
+0xD4, 0x49, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x01, 0x80,
+0x34, 0x53, 0x00, 0x80, 0x90, 0x00, 0x00, 0x00, 0x0C, 0xE8, 0x01, 0x80,
+0x64, 0x30, 0x01, 0x80, 0xA0, 0x00, 0x00, 0x00, 0x14, 0xE8, 0x01, 0x80,
+0x6C, 0x30, 0x01, 0x80, 0xB0, 0x00, 0x00, 0x00, 0x20, 0xE8, 0x01, 0x80,
+0x9C, 0x39, 0x01, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x28, 0xE8, 0x01, 0x80,
+0x8C, 0x30, 0x01, 0x80, 0xD0, 0x00, 0x00, 0x00, 0x34, 0xE8, 0x01, 0x80,
+0xFC, 0x4E, 0x00, 0x80, 0xC8, 0x00, 0x00, 0x00, 0x40, 0xE8, 0x01, 0x80,
+0x54, 0x4A, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x00, 0x4C, 0xE8, 0x01, 0x80,
+0xAC, 0x30, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0xFF, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
+0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0x00, 0x00, 0x00,
+0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0xFF, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
+0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x01, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xD0, 0xDF, 0x01, 0x80, 0xD0, 0xDF, 0x01, 0x80,
+0x31, 0x10, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x31, 0x20, 0x10, 0x00,
+0x00, 0x30, 0x00, 0x00, 0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00,
+0x31, 0x2C, 0x10, 0x10, 0x00, 0x30, 0x00, 0x00, 0x31, 0x2F, 0x10, 0x10,
+0x00, 0x30, 0x00, 0x00, 0x31, 0x30, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00,
+0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x00, 0x00, 0x22, 0x20, 0x18, 0x08,
+0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x20, 0x00, 0x00,
+0x22, 0x21, 0x1C, 0x08, 0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x20, 0x08,
+0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20, 0x00, 0x00,
+0x22, 0x21, 0x20, 0x18, 0x00, 0x20, 0x00, 0x00, 0x1A, 0x19, 0x18, 0x10,
+0x00, 0x18, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x00, 0x00,
+0x0A, 0x09, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x02,
+0x00, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00,
+0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x00, 0x00, 0x08, 0x07, 0x06, 0x04,
+0x00, 0x06, 0x00, 0x00, 0x06, 0x05, 0x04, 0x02, 0x00, 0x04, 0x00, 0x00,
+0x06, 0x05, 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x05, 0x04, 0x03, 0x02,
+0x00, 0x03, 0x00, 0x00, 0x09, 0x08, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05,
+0x05, 0x04, 0x04, 0x03, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03,
+0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x00, 0x09, 0x08, 0x07,
+0x06, 0x07, 0x06, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04,
+0x03, 0x03, 0x02, 0x02, 0x02, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01,
+0x01, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x10, 0x10, 0x20, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x30, 0x08, 0x08, 0x08,
+0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x30, 0x30, 0x10, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x30, 0x30, 0x08, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x10, 0x10, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20, 0x08, 0x08, 0x08,
+0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x30, 0x30, 0x10, 0x20, 0x20,
+0x20, 0x20, 0x20, 0x30, 0x30, 0x08, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08,
+0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00,
+0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09,
+0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00,
+0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22,
+0x21, 0x20, 0x18, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08,
+0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00,
+0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21,
+0x1C, 0x08, 0x00, 0x22, 0x20, 0x18, 0x08, 0x00, 0x0A, 0x09, 0x08, 0x02,
+0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A,
+0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x22, 0x21, 0x20,
+0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x22, 0x21, 0x1C, 0x08, 0x00,
+0x31, 0x30, 0x18, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09,
+0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04,
+0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A,
+0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18,
+0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00,
+0x31, 0x28, 0x10, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, 0x21,
+0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x08,
+0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x22, 0x20, 0x18, 0x08, 0x00, 0x31,
+0x30, 0x20, 0x10, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x0A, 0x09, 0x08,
+0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00,
+0x22, 0x21, 0x20, 0x18, 0x00, 0x31, 0x30, 0x20, 0x10, 0x00, 0x31, 0x2F,
+0x10, 0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00, 0x31, 0x10, 0x10, 0x00,
+0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04,
+0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A,
+0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08,
+0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00,
+0x0A, 0x09, 0x08, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x12, 0x11,
+0x10, 0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x0A, 0x09, 0x08, 0x04,
+0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A,
+0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x22, 0x21, 0x20,
+0x18, 0x00, 0x22, 0x21, 0x1C, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00,
+0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09,
+0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x00,
+0x00, 0x22, 0x21, 0x20, 0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x22,
+0x21, 0x14, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x0A, 0x09, 0x08,
+0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00,
+0x0A, 0x09, 0x08, 0x04, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19,
+0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10,
+0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x31,
+0x2C, 0x10, 0x10, 0x00, 0x31, 0x28, 0x10, 0x00, 0x00, 0x12, 0x11, 0x10,
+0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00,
+0x22, 0x21, 0x20, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x22, 0x20,
+0x18, 0x08, 0x00, 0x31, 0x30, 0x20, 0x10, 0x00, 0x31, 0x2C, 0x10, 0x10,
+0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22,
+0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x31, 0x30, 0x20,
+0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00,
+0x31, 0x10, 0x10, 0x00, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x00, 0x00,
+0x01, 0x02, 0x04, 0x08, 0x02, 0x04, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30,
+0x02, 0x04, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x06, 0x0C, 0x10, 0x18,
+0x24, 0x30, 0x3C, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x27, 0x2C, 0x19, 0x1B, 0x1E, 0x20,
+0x23, 0x29, 0x2A, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x25, 0x29, 0x2B, 0x2E,
+0x2E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
+0x60, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
+0xD8, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+0xA0, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
+0x90, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00,
+0x2C, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00,
+0xD0, 0x02, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00,
+0x80, 0x0C, 0x00, 0x00, 0xA0, 0x0F, 0x00, 0x00, 0xA0, 0x0F, 0x00, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+0x48, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
+0x28, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
+0x64, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00,
+0xF0, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+0xA0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00,
+0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00,
+0xD0, 0x07, 0x00, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x54, 0x86, 0x01, 0x80,
+0x4C, 0xC4, 0x00, 0x80, 0x4C, 0xC4, 0x00, 0x80, 0x4C, 0xC4, 0x00, 0x80,
+0x4C, 0xC4, 0x00, 0x80, 0x9C, 0xC2, 0x00, 0x80, 0x5C, 0x86, 0x01, 0x80,
+0x54, 0x86, 0x01, 0x80, 0x54, 0x86, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x44, 0x8B, 0x01, 0x80, 0x44, 0x8B, 0x01, 0x80,
+0x44, 0x8B, 0x01, 0x80, 0x44, 0x8B, 0x01, 0x80, 0x34, 0x86, 0x01, 0x80,
+0x30, 0x8A, 0x01, 0x80, 0x3C, 0x86, 0x01, 0x80, 0x44, 0x86, 0x01, 0x80,
+0x4C, 0x86, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x04, 0x04, 0x08, 0x02, 0x02, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00,
+0x52, 0x54, 0x4C, 0x38, 0x37, 0x31, 0x32, 0x20, 0x46, 0x57, 0x20, 0x76,
+0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x30, 0x2E, 0x30, 0x2E, 0x31,
+0x23, 0x20, 0xE4, 0xB8, 0x80, 0x20, 0x35, 0xE6, 0x9C, 0x88, 0x20, 0x33,
+0x31, 0x20, 0x31, 0x35, 0x3A, 0x32, 0x35, 0x3A, 0x33, 0x39, 0x20, 0x43,
+0x53, 0x54, 0x20, 0x32, 0x30, 0x31, 0x30, 0x20, 0x20, 0x53, 0x56, 0x4E,
+0x3A, 0x20, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, 0x43, 0x68, 0x69, 0x70,
+0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x25, 0x78, 0x00,
+0x48, 0x43, 0x49, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x25, 0x78,
+0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x66, 0x5F, 0x63,
+0x6F, 0x66, 0x69, 0x67, 0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x2C,
+0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00,
+0x6D, 0x70, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, 0x25, 0x78, 0x28,
+0x25, 0x78, 0x29, 0x2C, 0x20, 0x49, 0x51, 0x4B, 0x3A, 0x20, 0x25, 0x78,
+0x0A, 0x00, 0x00, 0x00, 0x76, 0x63, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65,
+0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00,
+0x33, 0x32, 0x6B, 0x20, 0x63, 0x61, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x3A,
+0x20, 0x25, 0x64, 0x2C, 0x20, 0x33, 0x32, 0x4B, 0x20, 0x54, 0x53, 0x46,
+0x3A, 0x20, 0x25, 0x78, 0x00, 0x00, 0x00, 0x00, 0x74, 0x61, 0x72, 0x67,
+0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x72, 0x6D, 0x61, 0x6C, 0x3A, 0x20,
+0x25, 0x78, 0x2C, 0x20, 0x20, 0x62, 0x74, 0x5F, 0x63, 0x6F, 0x65, 0x78,
+0x69, 0x73, 0x74, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x54, 0xAA, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x1C, 0xAA, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0xE4, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0xAC, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x74, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x3C, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80,
+0x24, 0xA9, 0x01, 0x80, 0xFC, 0xA8, 0x01, 0x80, 0x64, 0x05, 0x00, 0x80,
+0x58, 0x05, 0x00, 0x80, 0x4C, 0x05, 0x00, 0x80, 0x40, 0x05, 0x00, 0x80,
+0x34, 0x05, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0x1C, 0x05, 0x00, 0x80,
+0x10, 0x05, 0x00, 0x80, 0x04, 0x05, 0x00, 0x80, 0xF8, 0x04, 0x00, 0x80,
+0xB0, 0x04, 0x00, 0x80, 0x60, 0x1B, 0x02, 0x80, 0xB0, 0x03, 0x25, 0xB0,
+0x60, 0x1B, 0x02, 0x80, 0x60, 0x1B, 0x02, 0x80, 0x60, 0x1B, 0x02, 0x80,
+0x60, 0x1B, 0x02, 0x80, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64,
+0x20, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x49, 0x44, 0x3A,
+0x20, 0x25, 0x78, 0x2C, 0x20, 0x63, 0x6D, 0x64, 0x20, 0x73, 0x65, 0x71,
+0x3D, 0x25, 0x78, 0x2C, 0x20, 0x68, 0x32, 0x64, 0x73, 0x65, 0x71, 0x3D,
+0x25, 0x78, 0x0A, 0x00, 0x6A, 0x6F, 0x69, 0x6E, 0x62, 0x73, 0x73, 0x5F,
+0x68, 0x64, 0x6C, 0x00, 0x67, 0x65, 0x74, 0x20, 0x6A, 0x6F, 0x69, 0x6E,
+0x20, 0x63, 0x6D, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69,
+0x72, 0x70, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20,
+0x6F, 0x70, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00,
+0x67, 0x65, 0x74, 0x20, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x20, 0x63,
+0x6D, 0x64, 0x0A, 0x00, 0x53, 0x53, 0x49, 0x44, 0x3A, 0x20, 0x25, 0x73,
+0x0A, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x3A,
+0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x63, 0x76, 0x20,
+0x73, 0x65, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x6B, 0x65, 0x79, 0x0A, 0x00,
+0x54, 0x78, 0x5F, 0x42, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x5F, 0x68, 0x64,
+0x6C, 0x00, 0x00, 0x00, 0x74, 0x78, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F,
+0x6E, 0x20, 0x63, 0x6D, 0x64, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00,
+0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x4D, 0x61, 0x63, 0x41, 0x64,
+0x64, 0x72, 0x0A, 0x00, 0x00, 0x0E, 0x04, 0x0E, 0x10, 0x0E, 0x14, 0x0E,
+0x18, 0x0E, 0x1C, 0x0E, 0x4F, 0x6E, 0x41, 0x73, 0x73, 0x6F, 0x63, 0x52,
+0x65, 0x71, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x73, 0x73, 0x6F, 0x63, 0x52,
+0x73, 0x70, 0x00, 0x00, 0x4F, 0x6E, 0x52, 0x65, 0x41, 0x73, 0x73, 0x6F,
+0x63, 0x52, 0x65, 0x71, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x52, 0x65,
+0x41, 0x73, 0x73, 0x6F, 0x63, 0x52, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x4F, 0x6E, 0x50, 0x72, 0x6F, 0x62, 0x65, 0x52, 0x65, 0x71, 0x00, 0x00,
+0x4F, 0x6E, 0x50, 0x72, 0x6F, 0x62, 0x65, 0x52, 0x73, 0x70, 0x00, 0x00,
+0x4F, 0x6E, 0x42, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00,
+0x4F, 0x6E, 0x41, 0x54, 0x49, 0x4D, 0x00, 0x00, 0x4F, 0x6E, 0x44, 0x69,
+0x73, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x75,
+0x74, 0x68, 0x00, 0x00, 0x4F, 0x6E, 0x44, 0x65, 0x41, 0x75, 0x74, 0x68,
+0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x51, 0x6F, 0x73, 0x4E, 0x75, 0x6C,
+0x6C, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74,
+0x69, 0x6F, 0x6E, 0x00, 0x41, 0x54, 0x49, 0x4D, 0x3A, 0x20, 0x25, 0x78,
+0x0A, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x07, 0x07, 0x0D, 0x0D, 0x0D,
+0x02, 0x07, 0x07, 0x0D, 0x0D, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00,
+0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x10, 0x72, 0x65, 0x70, 0x6F,
+0x72, 0x74, 0x5F, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x5F, 0x64, 0x6F,
+0x6E, 0x65, 0x00, 0x00, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x20, 0x64,
+0x6F, 0x6E, 0x65, 0x28, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69, 0x72, 0x70, 0x20, 0x25,
+0x73, 0x0A, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x6A,
+0x6F, 0x69, 0x6E, 0x5F, 0x72, 0x65, 0x73, 0x00, 0x4E, 0x6F, 0x20, 0x69,
+0x72, 0x70, 0x28, 0x25, 0x78, 0x29, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00,
+0x6A, 0x6F, 0x69, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x28, 0x25, 0x78, 0x2C,
+0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F,
+0x72, 0x74, 0x5F, 0x64, 0x65, 0x6C, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x65,
+0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6C, 0x20,
+0x73, 0x74, 0x61, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F,
+0x72, 0x74, 0x5F, 0x61, 0x64, 0x64, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x65,
+0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x20,
+0x73, 0x74, 0x61, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00,
+0x72, 0x63, 0x76, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65,
+0x63, 0x74, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x70, 0x72,
+0x6F, 0x62, 0x65, 0x72, 0x65, 0x71, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69,
+0x72, 0x70, 0x20, 0x40, 0x25, 0x73, 0x0A, 0x00, 0x57, 0x4D, 0x4D, 0x28,
+0x25, 0x78, 0x29, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x20, 0x72, 0x65,
+0x6A, 0x65, 0x63, 0x74, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20,
+0x69, 0x64, 0x20, 0x23, 0x35, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25,
+0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75,
+0x65, 0x5F, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x72, 0x73, 0x70, 0x00, 0x00,
+0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x42, 0x53, 0x53, 0x49, 0x44,
+0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x00, 0x00, 0x70, 0x61, 0x63, 0x6B,
+0x65, 0x74, 0x20, 0x74, 0x6F, 0x6F, 0x20, 0x6C, 0x61, 0x72, 0x67, 0x65,
+0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x50, 0xF2, 0x01,
+0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x63, 0x61, 0x70, 0x3A,
+0x25, 0x78, 0x0A, 0x00, 0x49, 0x42, 0x53, 0x53, 0x20, 0x6D, 0x6F, 0x64,
+0x65, 0x2C, 0x20, 0x63, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E,
+0x65, 0x6C, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x63, 0x6E, 0x20,
+0x69, 0x6E, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6C, 0x3A, 0x20, 0x25, 0x78,
+0x0A, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20, 0x69, 0x64, 0x20, 0x23,
+0x34, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00,
+0x63, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3A,
+0x20, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x63, 0x6E, 0x20, 0x69, 0x6E, 0x74,
+0x65, 0x72, 0x76, 0x61, 0x6C, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00,
+0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x72,
+0x65, 0x71, 0x00, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x69, 0x73, 0x73, 0x75,
+0x65, 0x20, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x72, 0x65, 0x71, 0x28, 0x25,
+0x78, 0x29, 0x0A, 0x00, 0x5B, 0x57, 0x41, 0x50, 0x49, 0x5D, 0x20, 0x67,
+0x65, 0x74, 0x20, 0x77, 0x61, 0x70, 0x69, 0x20, 0x49, 0x45, 0x0A, 0x00,
+0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E,
+0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x61, 0x63,
+0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78,
+0x2C, 0x20, 0x25, 0x78, 0x20, 0x0A, 0x00, 0x00, 0x44, 0x45, 0x4C, 0x42,
+0x41, 0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00,
+0x41, 0x44, 0x44, 0x42, 0x41, 0x20, 0x52, 0x53, 0x50, 0x3A, 0x20, 0x25,
+0x78, 0x0A, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x75,
+0x74, 0x68, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x61, 0x75,
+0x74, 0x68, 0x0A, 0x00, 0x63, 0x6C, 0x6E, 0x74, 0x20, 0x61, 0x75, 0x74,
+0x68, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x64, 0x75, 0x65,
+0x20, 0x74, 0x6F, 0x20, 0x69, 0x6C, 0x6C, 0x65, 0x67, 0x61, 0x6C, 0x20,
+0x73, 0x65, 0x71, 0x3D, 0x25, 0x78, 0x0A, 0x00, 0x63, 0x6C, 0x6E, 0x74,
+0x20, 0x61, 0x75, 0x74, 0x68, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x2C, 0x20,
+0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00,
+0x6E, 0x6F, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65,
+0x20, 0x74, 0x65, 0x78, 0x74, 0x3F, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B,
+0x20, 0x74, 0x6F, 0x20, 0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x20,
+0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20,
+0x41, 0x74, 0x68, 0x65, 0x72, 0x6F, 0x73, 0x20, 0x41, 0x50, 0x28, 0x4D,
+0x41, 0x43, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20,
+0x69, 0x64, 0x20, 0x23, 0x25, 0x78, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20,
+0x25, 0x78, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20,
+0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x6F, 0x6D, 0x20, 0x41, 0x50, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20,
+0x41, 0x74, 0x68, 0x65, 0x72, 0x6F, 0x73, 0x20, 0x41, 0x50, 0x0A, 0x00,
+0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x4D, 0x61, 0x72, 0x76,
+0x65, 0x6C, 0x6C, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B,
+0x20, 0x74, 0x6F, 0x20, 0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x6B, 0x20,
+0x39, 0x36, 0x42, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B,
+0x20, 0x74, 0x6F, 0x20, 0x43, 0x69, 0x73, 0x63, 0x6F, 0x20, 0x41, 0x50,
+0x0A, 0x00, 0x00, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20,
+0x52, 0x61, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x00,
+0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x52, 0x65, 0x61, 0x6C,
+0x74, 0x65, 0x6B, 0x20, 0x39, 0x36, 0x42, 0x20, 0x41, 0x50, 0x20, 0x77,
+0x69, 0x74, 0x68, 0x20, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x20, 0x6D, 0x6F,
+0x64, 0x65, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x65,
+0x61, 0x75, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75,
+0x65, 0x5F, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x0A, 0x00, 0x00, 0x00,
+0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x69, 0x73, 0x61, 0x73, 0x73,
+0x6F, 0x63, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x69,
+0x73, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75,
+0x65, 0x5F, 0x66, 0x72, 0x61, 0x6D, 0x65, 0x5F, 0x6C, 0x65, 0x6E, 0x00,
+0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74,
+0x69, 0x6D, 0x65, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x65, 0x61,
+0x63, 0x6F, 0x6E, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x63,
+0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x28, 0x6E, 0x6F, 0x20, 0x64, 0x61,
+0x74, 0x61, 0x20, 0x72, 0x63, 0x76, 0x64, 0x29, 0x0A, 0x00, 0x00, 0x00,
+0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x51, 0x6F, 0x73, 0x4E, 0x75, 0x6C,
+0x6C, 0x28, 0x25, 0x64, 0x29, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x02, 0x80,
+0xB0, 0x03, 0x25, 0xB0, 0x18, 0x03, 0x25, 0xB0, 0x44, 0x44, 0x33, 0x33,
+0x06, 0x00, 0x2A, 0xB0, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB4, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0x38, 0x4A, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0x2C, 0x4A, 0x01, 0x80, 0x20, 0x4A, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0x14, 0x4A, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0x08, 0x4A, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xFC, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xF0, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xE4, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xD8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xCC, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80,
+0xB8, 0x49, 0x01, 0x80, 0xC0, 0x49, 0x01, 0x80, 0xF8, 0x4A, 0x01, 0x80,
+0xEC, 0x4A, 0x01, 0x80, 0xE0, 0x4A, 0x01, 0x80, 0xD4, 0x4A, 0x01, 0x80,
+0xC8, 0x4A, 0x01, 0x80, 0xBC, 0x4A, 0x01, 0x80, 0xB0, 0x4A, 0x01, 0x80,
+0xA4, 0x4A, 0x01, 0x80, 0x98, 0x4A, 0x01, 0x80, 0x8C, 0x4A, 0x01, 0x80,
+0x80, 0x4A, 0x01, 0x80, 0x74, 0x4A, 0x01, 0x80, 0x00, 0x50, 0xF2, 0x01,
+0x00, 0x50, 0xF2, 0x02, 0x00, 0x0F, 0xAC, 0x02, 0x30, 0x31, 0x32, 0x33,
+0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+0x00, 0x00, 0x00, 0x00, 0x25, 0x64, 0x2E, 0x00, 0x25, 0x68, 0x68, 0x58,
+0x3A, 0x00, 0x00, 0x00, 0xEC, 0xEE, 0x01, 0x80, 0x67, 0x66, 0x66, 0x66,
+0x87, 0x7C, 0x00, 0x80, 0x5D, 0x7C, 0x00, 0x80, 0x37, 0x7C, 0x00, 0x80,
+0x11, 0x7C, 0x00, 0x80, 0xC1, 0x7B, 0x00, 0x80, 0x9B, 0x7B, 0x00, 0x80,
+0xEB, 0x7B, 0x00, 0x80, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x63,
+0x61, 0x6D, 0x20, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x28, 0x25, 0x78,
+0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x2D, 0x3E, 0x28, 0x25,
+0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25,
+0x78, 0x29, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00,
+0xDF, 0x88, 0x00, 0x80, 0xE5, 0x88, 0x00, 0x80, 0xEB, 0x88, 0x00, 0x80,
+0xF1, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80,
+0xDF, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80, 0xF7, 0x88, 0x00, 0x80,
+0xFD, 0x88, 0x00, 0x80, 0x03, 0x89, 0x00, 0x80, 0x09, 0x89, 0x00, 0x80,
+0x60, 0x1B, 0x02, 0x80, 0x55, 0x6E, 0x69, 0x20, 0x4F, 0x6B, 0x3A, 0x20,
+0x41, 0x50, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF,
+0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x03, 0xFE, 0x01, 0x80, 0x7F,
+0xE2, 0x01, 0x80, 0x78, 0xC7, 0x01, 0xC0, 0x71, 0xAE, 0x01, 0x80, 0x6B,
+0x95, 0x01, 0x40, 0x65, 0x7F, 0x01, 0xC0, 0x5F, 0x69, 0x01, 0x40, 0x5A,
+0x55, 0x01, 0x40, 0x55, 0x42, 0x01, 0x80, 0x50, 0x30, 0x01, 0x00, 0x4C,
+0x1F, 0x01, 0xC0, 0x47, 0x0F, 0x01, 0xC0, 0x43, 0x00, 0x01, 0x00, 0x40,
+0xF2, 0x00, 0x80, 0x3C, 0xE4, 0x00, 0x00, 0x39, 0xD7, 0x00, 0xC0, 0x35,
+0xCB, 0x00, 0xC0, 0x32, 0xC0, 0x00, 0x00, 0x30, 0xB5, 0x00, 0x40, 0x2D,
+0xAB, 0x00, 0xC0, 0x2A, 0xA2, 0x00, 0x80, 0x28, 0x98, 0x00, 0x00, 0x26,
+0x90, 0x00, 0x00, 0x24, 0x88, 0x00, 0x00, 0x22, 0x80, 0x00, 0x00, 0x20,
+0x79, 0x00, 0x40, 0x1E, 0x72, 0x00, 0x80, 0x1C, 0x6C, 0x00, 0x00, 0x1B,
+0x66, 0x00, 0x80, 0x19, 0x60, 0x00, 0x00, 0x18, 0x5B, 0x00, 0xC0, 0x16,
+0x56, 0x00, 0x80, 0x15, 0x51, 0x00, 0x40, 0x14, 0x4C, 0x00, 0x00, 0x13,
+0x48, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10,
+0x36, 0x35, 0x2E, 0x25, 0x1C, 0x12, 0x09, 0x04, 0x33, 0x32, 0x2B, 0x23,
+0x1A, 0x11, 0x08, 0x04, 0x30, 0x2F, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
+0x2D, 0x2D, 0x27, 0x1F, 0x18, 0x0F, 0x08, 0x03, 0x2B, 0x2A, 0x25, 0x1E,
+0x16, 0x0E, 0x07, 0x03, 0x28, 0x28, 0x22, 0x1C, 0x15, 0x0D, 0x07, 0x03,
+0x26, 0x25, 0x21, 0x1B, 0x14, 0x0D, 0x06, 0x03, 0x24, 0x23, 0x1F, 0x19,
+0x13, 0x0C, 0x06, 0x03, 0x22, 0x21, 0x1D, 0x18, 0x11, 0x0B, 0x06, 0x02,
+0x20, 0x20, 0x1B, 0x16, 0x11, 0x08, 0x05, 0x02, 0x1F, 0x1E, 0x1A, 0x15,
+0x10, 0x0A, 0x05, 0x02, 0x1D, 0x1C, 0x18, 0x14, 0x0F, 0x0A, 0x05, 0x02,
+0x1B, 0x1A, 0x17, 0x13, 0x0E, 0x09, 0x04, 0x02, 0x1A, 0x19, 0x16, 0x12,
+0x0D, 0x09, 0x04, 0x02, 0x18, 0x17, 0x15, 0x11, 0x0C, 0x08, 0x04, 0x02,
+0x17, 0x16, 0x13, 0x10, 0x0C, 0x08, 0x04, 0x02, 0x16, 0x15, 0x12, 0x0F,
+0x0B, 0x07, 0x04, 0x01, 0x14, 0x14, 0x11, 0x0E, 0x0B, 0x07, 0x03, 0x02,
+0x13, 0x13, 0x10, 0x0D, 0x0A, 0x06, 0x03, 0x01, 0x12, 0x12, 0x0F, 0x0C,
+0x09, 0x06, 0x03, 0x01, 0x11, 0x11, 0x0F, 0x0C, 0x09, 0x06, 0x03, 0x01,
+0x10, 0x10, 0x0E, 0x0B, 0x08, 0x05, 0x03, 0x01, 0x0F, 0x0F, 0x0D, 0x0B,
+0x08, 0x05, 0x03, 0x01, 0x0E, 0x0E, 0x0C, 0x0A, 0x08, 0x05, 0x02, 0x01,
+0x0D, 0x0D, 0x0C, 0x0A, 0x07, 0x05, 0x02, 0x01, 0x0D, 0x0C, 0x0B, 0x09,
+0x07, 0x04, 0x02, 0x01, 0x0C, 0x0C, 0x0A, 0x09, 0x06, 0x04, 0x02, 0x01,
+0x0B, 0x0B, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x01, 0x0B, 0x0A, 0x09, 0x08,
+0x06, 0x04, 0x02, 0x01, 0x0A, 0x0A, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01,
+0x0A, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x09, 0x09, 0x08, 0x06,
+0x05, 0x03, 0x01, 0x01, 0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01,
+0x36, 0x35, 0x2E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x33, 0x32, 0x2B, 0x19,
+0x00, 0x00, 0x00, 0x00, 0x30, 0x2F, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x2D, 0x2D, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2A, 0x25, 0x15,
+0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00,
+0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x24, 0x23, 0x1F, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x22, 0x21, 0x1D, 0x11, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x20, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1E, 0x1A, 0x0F,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0x1C, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x1B, 0x1A, 0x17, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x19, 0x16, 0x0D,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x17, 0x15, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x17, 0x16, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x16, 0x15, 0x12, 0x0B,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x11, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x13, 0x13, 0x10, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x0F, 0x09,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x0F, 0x09, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x10, 0x0E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0D, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x0D, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x0B, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x0B, 0x0B, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x0A, 0x09, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00,
+0x0A, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x08, 0x05,
+0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x72, 0x65, 0x73, 0x65, 0x74, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00,
+0x50, 0x53, 0x00, 0x00, 0xE8, 0x86, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80,
+0x14, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80,
+0x58, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, 0xC0, 0x86, 0x01, 0x80,
+0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
+0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x28, 0x28, 0x28, 0x28, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+0xA0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x10, 0x10, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x41, 0x41, 0x41,
+0x41, 0x41, 0x41, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
+0x10, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x08,
+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, 0xA0, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10,
+0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x2D, 0x5C, 0x7C, 0x2F,
+0x00, 0x00, 0x00, 0x00, 0x0A, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xF0, 0xF4, 0x5E, 0x00, 0xF0, 0xF4, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE5, 0x5E, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xB8, 0xA0, 0xFC, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
+};
diff --git a/drivers/staging/rtl8712/generic.h b/drivers/staging/rtl8712/generic.h
new file mode 100644
index 000000000000..742424bdf16b
--- /dev/null
+++ b/drivers/staging/rtl8712/generic.h
@@ -0,0 +1,153 @@
+#ifndef _LINUX_BYTEORDER_GENERIC_H
+#define _LINUX_BYTEORDER_GENERIC_H
+
+/*
+ * linux/byteorder_generic.h
+ * Generic Byte-reordering support
+ *
+ * Francois-Rene Rideau <fare@tunes.org> 19970707
+ * gathered all the good ideas from all asm-foo/byteorder.h into one file,
+ * cleaned them up.
+ * I hope it is compliant with non-GCC compilers.
+ * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h,
+ * because I wasn't sure it would be ok to put it in types.h
+ * Upgraded it to 2.1.43
+ * Francois-Rene Rideau <fare@tunes.org> 19971012
+ * Upgraded it to 2.1.57
+ * to please Linus T., replaced huge #ifdef's between little/big endian
+ * by nestedly #include'd files.
+ * Francois-Rene Rideau <fare@tunes.org> 19971205
+ * Made it to 2.1.71; now a facelift:
+ * Put files under include/linux/byteorder/
+ * Split swab from generic support.
+ *
+ * TODO:
+ * = Regular kernel maintainers could also replace all these manual
+ * byteswap macros that remain, disseminated among drivers,
+ * after some grep or the sources...
+ * = Linus might want to rename all these macros and files to fit his taste,
+ * to fit his personal naming scheme.
+ * = it seems that a few drivers would also appreciate
+ * nybble swapping support...
+ * = every architecture could add their byteswap macro in asm/byteorder.h
+ * see how some architectures already do (i386, alpha, ppc, etc)
+ * = cpu_to_beXX and beXX_to_cpu might some day need to be well
+ * distinguished throughout the kernel. This is not the case currently,
+ * since little endian, big endian, and pdp endian machines needn't it.
+ * But this might be the case for, say, a port of Linux to 20/21 bit
+ * architectures (and F21 Linux addict around?).
+ */
+
+/*
+ * The following macros are to be defined by <asm/byteorder.h>:
+ *
+ * Conversion of long and short int between network and host format
+ * ntohl(__u32 x)
+ * ntohs(__u16 x)
+ * htonl(__u32 x)
+ * htons(__u16 x)
+ * It seems that some programs (which? where? or perhaps a standard? POSIX?)
+ * might like the above to be functions, not macros (why?).
+ * if that's true, then detect them, and take measures.
+ * Anyway, the measure is: define only ___ntohl as a macro instead,
+ * and in a separate file, have
+ * unsigned long inline ntohl(x){return ___ntohl(x);}
+ *
+ * The same for constant arguments
+ * __constant_ntohl(__u32 x)
+ * __constant_ntohs(__u16 x)
+ * __constant_htonl(__u32 x)
+ * __constant_htons(__u16 x)
+ *
+ * Conversion of XX-bit integers (16- 32- or 64-)
+ * between native CPU format and little/big endian format
+ * 64-bit stuff only defined for proper architectures
+ * cpu_to_[bl]eXX(__uXX x)
+ * [bl]eXX_to_cpu(__uXX x)
+ *
+ * The same, but takes a pointer to the value to convert
+ * cpu_to_[bl]eXXp(__uXX x)
+ * [bl]eXX_to_cpup(__uXX x)
+ *
+ * The same, but change in situ
+ * cpu_to_[bl]eXXs(__uXX x)
+ * [bl]eXX_to_cpus(__uXX x)
+ *
+ * See asm-foo/byteorder.h for examples of how to provide
+ * architecture-optimized versions
+ *
+ */
+
+
+/*
+ * inside the kernel, we can use nicknames;
+ * outside of it, we must avoid POSIX namespace pollution...
+ */
+#define cpu_to_le64 __cpu_to_le64
+#define le64_to_cpu __le64_to_cpu
+#define cpu_to_le32 __cpu_to_le32
+#define le32_to_cpu __le32_to_cpu
+#define cpu_to_le16 __cpu_to_le16
+#define le16_to_cpu __le16_to_cpu
+#define cpu_to_be64 __cpu_to_be64
+#define be64_to_cpu __be64_to_cpu
+#define cpu_to_be32 __cpu_to_be32
+#define be32_to_cpu __be32_to_cpu
+#define cpu_to_be16 __cpu_to_be16
+#define be16_to_cpu __be16_to_cpu
+#define cpu_to_le64p __cpu_to_le64p
+#define le64_to_cpup __le64_to_cpup
+#define cpu_to_le32p __cpu_to_le32p
+#define le32_to_cpup __le32_to_cpup
+#define cpu_to_le16p __cpu_to_le16p
+#define le16_to_cpup __le16_to_cpup
+#define cpu_to_be64p __cpu_to_be64p
+#define be64_to_cpup __be64_to_cpup
+#define cpu_to_be32p __cpu_to_be32p
+#define be32_to_cpup __be32_to_cpup
+#define cpu_to_be16p __cpu_to_be16p
+#define be16_to_cpup __be16_to_cpup
+#define cpu_to_le64s __cpu_to_le64s
+#define le64_to_cpus __le64_to_cpus
+#define cpu_to_le32s __cpu_to_le32s
+#define le32_to_cpus __le32_to_cpus
+#define cpu_to_le16s __cpu_to_le16s
+#define le16_to_cpus __le16_to_cpus
+#define cpu_to_be64s __cpu_to_be64s
+#define be64_to_cpus __be64_to_cpus
+#define cpu_to_be32s __cpu_to_be32s
+#define be32_to_cpus __be32_to_cpus
+#define cpu_to_be16s __cpu_to_be16s
+#define be16_to_cpus __be16_to_cpus
+
+
+/*
+ * Handle ntohl and suches. These have various compatibility
+ * issues - like we want to give the prototype even though we
+ * also have a macro for them in case some strange program
+ * wants to take the address of the thing or something..
+ *
+ * Note that these used to return a "long" in libc5, even though
+ * long is often 64-bit these days.. Thus the casts.
+ *
+ * They have to be macros in order to do the constant folding
+ * correctly - if the argument passed into a inline function
+ * it is no longer constant according to gcc..
+ */
+
+#undef ntohl
+#undef ntohs
+#undef htonl
+#undef htons
+
+/*
+ * Do the prototypes. Somebody might want to take the
+ * address or some such sick thing..
+ */
+extern __u32 ntohl(__u32);
+extern __u32 htonl(__u32);
+extern unsigned short int ntohs(unsigned short int);
+extern unsigned short int htons(unsigned short int);
+
+#endif /* _LINUX_BYTEORDER_GENERIC_H */
+
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
new file mode 100644
index 000000000000..32088a641eba
--- /dev/null
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -0,0 +1,358 @@
+/******************************************************************************
+ * hal_init.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _HAL_INIT_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_byteorder.h"
+#include "farray.h"
+#include "usb_osintf.h"
+
+#define FWBUFF_ALIGN_SZ 512
+#define MAX_DUMP_FWSZ 49152 /*default = 49152 (48k)*/
+
+static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl,
+ const u8 **ppmappedfw)
+{
+ u32 len;
+
+ *ppmappedfw = f_array;
+ len = sizeof(f_array);
+ return len;
+}
+
+static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
+{
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
+ struct registry_priv *pregpriv = &padapter->registrypriv;
+
+ memset(pfwpriv, 0, sizeof(struct fw_priv));
+ /* todo: check if needs endian conversion */
+ pfwpriv->hci_sel = RTL8712_HCI_TYPE_72USB;
+ pfwpriv->usb_ep_num = (u8)pdvobj->nr_endpoint;
+ pfwpriv->bw_40MHz_en = pregpriv->cbw40_enable;
+ switch (pregpriv->rf_config) {
+ case RTL8712_RF_1T1R:
+ pfwpriv->rf_config = RTL8712_RFC_1T1R;
+ break;
+ case RTL8712_RF_2T2R:
+ pfwpriv->rf_config = RTL8712_RFC_2T2R;
+ break;
+ case RTL8712_RF_1T2R:
+ default:
+ pfwpriv->rf_config = RTL8712_RFC_1T2R;
+ }
+ pfwpriv->mp_mode = (pregpriv->mp_mode == 1) ? 1 : 0;
+ pfwpriv->vcsType = pregpriv->vrtl_carrier_sense; /* 0:off 1:on 2:auto */
+ pfwpriv->vcsMode = pregpriv->vcs_type; /* 1:RTS/CTS 2:CTS to self */
+ /* default enable turboMode */
+ pfwpriv->turboMode = ((pregpriv->wifi_test == 1) ? 0 : 1);
+ pfwpriv->lowPowerMode = pregpriv->low_power;
+}
+
+static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw)
+{
+ pfwhdr->signature = le16_to_cpu(*(u16 *)pmappedfw);
+ pfwhdr->version = le16_to_cpu(*(u16 *)(pmappedfw+2));
+ /* define the size of boot loader */
+ pfwhdr->dmem_size = le32_to_cpu(*(uint *)(pmappedfw+4));
+ /* define the size of FW in IMEM */
+ pfwhdr->img_IMEM_size = le32_to_cpu(*(uint *)(pmappedfw+8));
+ /* define the size of FW in SRAM */
+ pfwhdr->img_SRAM_size = le32_to_cpu(*(uint *)(pmappedfw+12));
+ /* define the size of DMEM variable */
+ pfwhdr->fw_priv_sz = le32_to_cpu(*(uint *)(pmappedfw+16));
+}
+
+static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength)
+{
+ u32 fwhdrsz, fw_sz;
+ u8 intf, rfconf;
+
+ /* check signature */
+ if ((pfwhdr->signature != 0x8712) && (pfwhdr->signature != 0x8192))
+ return _FAIL;
+ /* check interface */
+ intf = (u8)((pfwhdr->version&0x3000) >> 12);
+ /* check rf_conf */
+ rfconf = (u8)((pfwhdr->version&0xC000) >> 14);
+ /* check fw_priv_sze & sizeof(struct fw_priv) */
+ if (pfwhdr->fw_priv_sz != sizeof(struct fw_priv))
+ return _FAIL;
+ /* check fw_sz & image_fw_sz */
+ fwhdrsz = FIELD_OFFSET(struct fw_hdr, fwpriv) + pfwhdr->fw_priv_sz;
+ fw_sz = fwhdrsz + pfwhdr->img_IMEM_size + pfwhdr->img_SRAM_size +
+ pfwhdr->dmem_size;
+ if (fw_sz != ulfilelength)
+ return _FAIL;
+ return _SUCCESS;
+}
+
+static u8 rtl8712_dl_fw(struct _adapter *padapter)
+{
+ sint i;
+ u8 tmp8, tmp8_a;
+ u16 tmp16;
+ u32 maxlen = 0, tmp32; /* for compare usage */
+ uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */
+ struct fw_hdr fwhdr;
+ u32 ulfilelength; /* FW file size */
+ void *phfwfile_hdl = NULL;
+ const u8 *pmappedfw = NULL;
+ u8 *ptmpchar = NULL, *ppayload, *ptr;
+ struct tx_desc *ptx_desc;
+ u32 txdscp_sz = sizeof(struct tx_desc);
+
+ ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw);
+ if (pmappedfw && (ulfilelength > 0)) {
+ update_fwhdr(&fwhdr, pmappedfw);
+ if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
+ goto exit_fail;
+ fill_fwpriv(padapter, &fwhdr.fwpriv);
+ /* firmware check ok */
+ maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
+ fwhdr.img_IMEM_size : fwhdr.img_SRAM_size;
+ maxlen += txdscp_sz;
+ ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
+ if (ptmpchar == NULL)
+ return _FAIL;
+
+ ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
+ ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
+ ppayload = (u8 *)(ptx_desc) + txdscp_sz;
+ ptr = (u8 *)pmappedfw + FIELD_OFFSET(struct fw_hdr, fwpriv) +
+ fwhdr.fw_priv_sz;
+ /* Download FirmWare */
+ /* 1. determine IMEM code size and Load IMEM Code Section */
+ imem_sz = fwhdr.img_IMEM_size;
+ do {
+ memset(ptx_desc, 0, TXDESC_SIZE);
+ if (imem_sz > MAX_DUMP_FWSZ/*49152*/)
+ dump_imem_sz = MAX_DUMP_FWSZ;
+ else {
+ dump_imem_sz = imem_sz;
+ ptx_desc->txdw0 |= cpu_to_le32(BIT(28));
+ }
+ ptx_desc->txdw0 |= cpu_to_le32(dump_imem_sz &
+ 0x0000ffff);
+ memcpy(ppayload, ptr, dump_imem_sz);
+ r8712_write_mem(padapter, RTL8712_DMA_VOQ,
+ dump_imem_sz + TXDESC_SIZE,
+ (u8 *)ptx_desc);
+ ptr += dump_imem_sz;
+ imem_sz -= dump_imem_sz;
+ } while (imem_sz > 0);
+ i = 10;
+ tmp16 = r8712_read16(padapter, TCR);
+ while (((tmp16 & _IMEM_CODE_DONE) == 0) && (i > 0)) {
+ udelay(10);
+ tmp16 = r8712_read16(padapter, TCR);
+ i--;
+ }
+ if (i == 0 || (tmp16 & _IMEM_CHK_RPT) == 0)
+ goto exit_fail;
+
+ /* 2.Download EMEM code size and Load EMEM Code Section */
+ emem_sz = fwhdr.img_SRAM_size;
+ do {
+ memset(ptx_desc, 0, TXDESC_SIZE);
+ if (emem_sz > MAX_DUMP_FWSZ) /* max=48k */
+ dump_emem_sz = MAX_DUMP_FWSZ;
+ else {
+ dump_emem_sz = emem_sz;
+ ptx_desc->txdw0 |= cpu_to_le32(BIT(28));
+ }
+ ptx_desc->txdw0 |= cpu_to_le32(dump_emem_sz &
+ 0x0000ffff);
+ memcpy(ppayload, ptr, dump_emem_sz);
+ r8712_write_mem(padapter, RTL8712_DMA_VOQ,
+ dump_emem_sz+TXDESC_SIZE, (u8 *)ptx_desc);
+ ptr += dump_emem_sz;
+ emem_sz -= dump_emem_sz;
+ } while (emem_sz > 0);
+ i = 5;
+ tmp16 = r8712_read16(padapter, TCR);
+ while (((tmp16 & _EMEM_CODE_DONE) == 0) && (i > 0)) {
+ udelay(10);
+ tmp16 = r8712_read16(padapter, TCR);
+ i--;
+ }
+ if (i == 0 || (tmp16 & _EMEM_CHK_RPT) == 0)
+ goto exit_fail;
+
+ /* 3.Enable CPU */
+ tmp8 = r8712_read8(padapter, SYS_CLKR);
+ r8712_write8(padapter, SYS_CLKR, tmp8|BIT(2));
+ tmp8_a = r8712_read8(padapter, SYS_CLKR);
+ if (tmp8_a != (tmp8|BIT(2)))
+ goto exit_fail;
+
+ tmp8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN+1, tmp8|BIT(2));
+ tmp8_a = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ if (tmp8_a != (tmp8|BIT(2)))
+ goto exit_fail;
+
+ tmp32 = r8712_read32(padapter, TCR);
+
+ /* 4.polling IMEM Ready */
+ i = 100;
+ tmp16 = r8712_read16(padapter, TCR);
+ while (((tmp16 & _IMEM_RDY) == 0) && (i > 0)) {
+ msleep(20);
+ tmp16 = r8712_read16(padapter, TCR);
+ i--;
+ }
+ if (i == 0) {
+ r8712_write16(padapter, 0x10250348, 0xc000);
+ r8712_write16(padapter, 0x10250348, 0xc001);
+ r8712_write16(padapter, 0x10250348, 0x2000);
+ r8712_write16(padapter, 0x10250348, 0x2001);
+ r8712_write16(padapter, 0x10250348, 0x2002);
+ r8712_write16(padapter, 0x10250348, 0x2003);
+ goto exit_fail;
+ }
+ /* 5.Download DMEM code size and Load EMEM Code Section */
+ memset(ptx_desc, 0, TXDESC_SIZE);
+ ptx_desc->txdw0 |= cpu_to_le32(fwhdr.fw_priv_sz&0x0000ffff);
+ ptx_desc->txdw0 |= cpu_to_le32(BIT(28));
+ memcpy(ppayload, &fwhdr.fwpriv, fwhdr.fw_priv_sz);
+ r8712_write_mem(padapter, RTL8712_DMA_VOQ,
+ fwhdr.fw_priv_sz + TXDESC_SIZE, (u8 *)ptx_desc);
+
+ /* polling dmem code done */
+ i = 100;
+ tmp16 = r8712_read16(padapter, TCR);
+ while (((tmp16 & _DMEM_CODE_DONE) == 0) && (i > 0)) {
+ msleep(20);
+ tmp16 = r8712_read16(padapter, TCR);
+ i--;
+ }
+ if (i == 0)
+ goto exit_fail;
+
+ tmp8 = r8712_read8(padapter, 0x1025000A);
+ if (tmp8 & BIT(4)) /* When boot from EEPROM,
+ & FW need more time to read EEPROM */
+ i = 60;
+ else /* boot from EFUSE */
+ i = 30;
+ tmp16 = r8712_read16(padapter, TCR);
+ while (((tmp16 & _FWRDY) == 0) && (i > 0)) {
+ msleep(100);
+ tmp16 = r8712_read16(padapter, TCR);
+ i--;
+ }
+ if (i == 0)
+ goto exit_fail;
+ } else
+ goto exit_fail;
+ return _SUCCESS;
+
+exit_fail:
+ kfree(ptmpchar);
+ return _FAIL;
+}
+
+uint rtl8712_hal_init(struct _adapter *padapter)
+{
+ u32 val32;
+ int i;
+
+ /* r8712 firmware download */
+ if (rtl8712_dl_fw(padapter) != _SUCCESS)
+ return _FAIL;
+
+ printk(KERN_INFO "r8712u: 1 RCR=0x%x\n", r8712_read32(padapter, RCR));
+ val32 = r8712_read32(padapter, RCR);
+ r8712_write32(padapter, RCR, (val32 | BIT(26))); /* Enable RX TCP
+ Checksum offload */
+ printk(KERN_INFO "r8712u: 2 RCR=0x%x\n", r8712_read32(padapter, RCR));
+ val32 = r8712_read32(padapter, RCR);
+ r8712_write32(padapter, RCR, (val32|BIT(25))); /* Append PHY status */
+ val32 = 0;
+ val32 = r8712_read32(padapter, 0x10250040);
+ r8712_write32(padapter, 0x10250040, (val32&0x00FFFFFF));
+ /* for usb rx aggregation */
+ r8712_write8(padapter, 0x102500B5, r8712_read8(padapter, 0x102500B5) |
+ BIT(0)); /* page = 128bytes */
+ r8712_write8(padapter, 0x102500BD, r8712_read8(padapter, 0x102500BD) |
+ BIT(7)); /* enable usb rx aggregation */
+ r8712_write8(padapter, 0x102500D9, 1); /* TH=1 => means that invalidate
+ * usb rx aggregation */
+ r8712_write8(padapter, 0x1025FE5B, 0x04); /* 1.7ms/4 */
+ /* Fix the RX FIFO issue(USB error) */
+ r8712_write8(padapter, 0x1025fe5C, r8712_read8(padapter, 0x1025fe5C)
+ | BIT(7));
+ for (i = 0; i < 6; i++)
+ padapter->eeprompriv.mac_addr[i] = r8712_read8(padapter,
+ MACID + i);
+ return _SUCCESS;
+}
+
+uint rtl8712_hal_deinit(struct _adapter *padapter)
+{
+ r8712_write8(padapter, RF_CTRL, 0x00);
+ /* Turn off BB */
+ msleep(20);
+ /* Turn off MAC */
+ r8712_write8(padapter, SYS_CLKR+1, 0x38); /* Switch Control Path */
+ r8712_write8(padapter, SYS_FUNC_EN+1, 0x70);
+ r8712_write8(padapter, PMC_FSM, 0x06); /* Enable Loader Data Keep */
+ r8712_write8(padapter, SYS_ISO_CTRL, 0xF9); /* Isolation signals from
+ * CORE, PLL */
+ r8712_write8(padapter, SYS_ISO_CTRL+1, 0xe8); /* Enable EFUSE 1.2V */
+ r8712_write8(padapter, AFE_PLL_CTRL, 0x00); /* Disable AFE PLL. */
+ r8712_write8(padapter, LDOA15_CTRL, 0x54); /* Disable A15V */
+ r8712_write8(padapter, SYS_FUNC_EN+1, 0x50); /* Disable E-Fuse 1.2V */
+ r8712_write8(padapter, LDOV12D_CTRL, 0x24); /* Disable LDO12(for CE) */
+ r8712_write8(padapter, AFE_MISC, 0x30); /* Disable AFE BG&MB */
+ /* Option for Disable 1.6V LDO. */
+ r8712_write8(padapter, SPS0_CTRL, 0x56); /* Disable 1.6V LDO */
+ r8712_write8(padapter, SPS0_CTRL+1, 0x43); /* Set SW PFM */
+ return _SUCCESS;
+}
+
+uint rtl871x_hal_init(struct _adapter *padapter)
+{
+ padapter->hw_init_completed = false;
+ if (padapter->halpriv.hal_bus_init == NULL)
+ return _FAIL;
+ else {
+ if (padapter->halpriv.hal_bus_init(padapter) != _SUCCESS)
+ return _FAIL;
+ }
+ if (rtl8712_hal_init(padapter) == _SUCCESS)
+ padapter->hw_init_completed = true;
+ else {
+ padapter->hw_init_completed = false;
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c
new file mode 100644
index 000000000000..f06addcf063e
--- /dev/null
+++ b/drivers/staging/rtl8712/ieee80211.c
@@ -0,0 +1,454 @@
+/******************************************************************************
+ * ieee80211.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _IEEE80211_C
+
+#include "drv_types.h"
+#include "ieee80211.h"
+#include "wifi.h"
+#include "osdep_service.h"
+#include "wlan_bssdef.h"
+
+static const u8 WPA_OUI_TYPE[] = {0x00, 0x50, 0xf2, 1};
+static const u8 WPA_CIPHER_SUITE_NONE[] = {0x00, 0x50, 0xf2, 0};
+static const u8 WPA_CIPHER_SUITE_WEP40[] = {0x00, 0x50, 0xf2, 1};
+static const u8 WPA_CIPHER_SUITE_TKIP[] = {0x00, 0x50, 0xf2, 2};
+static const u8 WPA_CIPHER_SUITE_CCMP[] = {0x00, 0x50, 0xf2, 4};
+static const u8 WPA_CIPHER_SUITE_WEP104[] = {0x00, 0x50, 0xf2, 5};
+
+static const u8 RSN_CIPHER_SUITE_NONE[] = {0x00, 0x0f, 0xac, 0};
+static const u8 RSN_CIPHER_SUITE_WEP40[] = {0x00, 0x0f, 0xac, 1};
+static const u8 RSN_CIPHER_SUITE_TKIP[] = {0x00, 0x0f, 0xac, 2};
+static const u8 RSN_CIPHER_SUITE_CCMP[] = {0x00, 0x0f, 0xac, 4};
+static const u8 RSN_CIPHER_SUITE_WEP104[] = {0x00, 0x0f, 0xac, 5};
+
+/*-----------------------------------------------------------
+ * for adhoc-master to generate ie and provide supported-rate to fw
+ *-----------------------------------------------------------
+ */
+
+static u8 WIFI_CCKRATES[] = {
+ (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK),
+ (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK),
+ (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK),
+ (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK)
+};
+
+static u8 WIFI_OFDMRATES[] = {
+ (IEEE80211_OFDM_RATE_6MB),
+ (IEEE80211_OFDM_RATE_9MB),
+ (IEEE80211_OFDM_RATE_12MB),
+ (IEEE80211_OFDM_RATE_18MB),
+ (IEEE80211_OFDM_RATE_24MB),
+ (IEEE80211_OFDM_RATE_36MB),
+ (IEEE80211_OFDM_RATE_48MB),
+ (IEEE80211_OFDM_RATE_54MB)
+};
+
+uint r8712_is_cckrates_included(u8 *rate)
+{
+ u32 i = 0;
+
+ while (rate[i] != 0) {
+ if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
+ (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22))
+ return true;
+ i++;
+ }
+ return false;
+}
+
+uint r8712_is_cckratesonly_included(u8 *rate)
+{
+ u32 i = 0;
+
+ while (rate[i] != 0) {
+ if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
+ (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22))
+ return false;
+ i++;
+ }
+ return true;
+}
+
+/* r8712_set_ie will update frame length */
+u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen)
+{
+ *pbuf = (u8)index;
+ *(pbuf + 1) = (u8)len;
+ if (len > 0)
+ memcpy((void *)(pbuf + 2), (void *)source, len);
+ *frlen = *frlen + (len + 2);
+ return pbuf + len + 2;
+}
+
+/*----------------------------------------------------------------------------
+index: the information element id index, limit is the limit for search
+-----------------------------------------------------------------------------*/
+u8 *r8712_get_ie(u8 *pbuf, sint index, sint *len, sint limit)
+{
+ sint tmp, i;
+ u8 *p;
+
+ if (limit < 1)
+ return NULL;
+ p = pbuf;
+ i = 0;
+ *len = 0;
+ while (1) {
+ if (*p == index) {
+ *len = *(p + 1);
+ return p;
+ } else {
+ tmp = *(p + 1);
+ p += (tmp + 2);
+ i += (tmp + 2);
+ }
+ if (i >= limit)
+ break;
+ }
+ return NULL;
+}
+
+static void set_supported_rate(u8 *SupportedRates, uint mode)
+{
+ memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
+ switch (mode) {
+ case WIRELESS_11B:
+ memcpy(SupportedRates, WIFI_CCKRATES,
+ IEEE80211_CCK_RATE_LEN);
+ break;
+ case WIRELESS_11G:
+ case WIRELESS_11A:
+ memcpy(SupportedRates, WIFI_OFDMRATES,
+ IEEE80211_NUM_OFDM_RATESLEN);
+ break;
+ case WIRELESS_11BG:
+ memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
+ memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES,
+ IEEE80211_NUM_OFDM_RATESLEN);
+ break;
+ }
+}
+
+static uint r8712_get_rateset_len(u8 *rateset)
+{
+ uint i = 0;
+
+ while (1) {
+ if ((rateset[i]) == 0)
+ break;
+ if (i > 12)
+ break;
+ i++;
+ }
+ return i;
+}
+
+int r8712_generate_ie(struct registry_priv *pregistrypriv,
+ struct _adapter *padapter)
+{
+ int sz = 0, rateLen;
+ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
+ u8 *ie = pdev_network->IEs;
+ struct ieee80211_ht_cap ht_capie;
+ struct ieee80211_ht_addt_info ht_addt_info;
+ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+
+ /*timestamp will be inserted by hardware*/
+ sz += 8;
+ ie += sz;
+ /*beacon interval : 2bytes*/
+ *(u16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);
+ sz += 2;
+ ie += 2;
+ /*capability info*/
+ *(u16 *)ie = 0;
+ *(u16 *)ie |= cpu_to_le16(cap_IBSS);
+ if (pregistrypriv->preamble == PREAMBLE_SHORT)
+ *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
+ if (pdev_network->Privacy)
+ *(u16 *)ie |= cpu_to_le16(cap_Privacy);
+ sz += 2;
+ ie += 2;
+ /*SSID*/
+ ie = r8712_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength,
+ pdev_network->Ssid.Ssid, &sz);
+ /*supported rates*/
+ set_supported_rate(pdev_network->SupportedRates,
+ pregistrypriv->wireless_mode);
+ rateLen = r8712_get_rateset_len(pdev_network->SupportedRates);
+ if (rateLen > 8) {
+ ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_, 8,
+ pdev_network->SupportedRates, &sz);
+ ie = r8712_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8),
+ (pdev_network->SupportedRates + 8), &sz);
+ } else
+ ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_,
+ rateLen, pdev_network->SupportedRates, &sz);
+ /*DS parameter set*/
+ ie = r8712_set_ie(ie, _DSSET_IE_, 1,
+ (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
+ /*IBSS Parameter Set*/
+ ie = r8712_set_ie(ie, _IBSS_PARA_IE_, 2,
+ (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
+ if (pregistrypriv->ht_enable == 1) {
+ if (pqospriv->qos_option == 0) {
+ ie = r8712_set_ie(ie, _VENDOR_SPECIFIC_IE_,
+ _WMM_IE_Length_, WMM_IE, &sz);
+ pqospriv->qos_option = 1;
+ }
+ memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
+ ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_MAX_AMSDU |
+ IEEE80211_HT_CAP_DSSSCCK40;
+ ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR &
+ 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
+ ie = r8712_set_ie(ie, _HT_CAPABILITY_IE_,
+ sizeof(struct ieee80211_ht_cap),
+ (unsigned char *)&ht_capie, &sz);
+ /*add HT info ie*/
+ memset(&ht_addt_info, 0,
+ sizeof(struct ieee80211_ht_addt_info));
+ /*need to add the HT additional IEs*/
+ ht_addt_info.control_chan = pregistrypriv->channel;
+ ie = r8712_set_ie(ie, _HT_ADD_INFO_IE_,
+ sizeof(struct ieee80211_ht_addt_info),
+ (unsigned char *)&ht_addt_info, &sz);
+ }
+ return sz;
+}
+
+unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)
+{
+ int len;
+ u16 val16;
+ unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01};
+ u8 *pbuf = pie;
+
+ while (1) {
+ pbuf = r8712_get_ie(pbuf, _WPA_IE_ID_, &len, limit);
+ if (pbuf) {
+ /*check if oui matches...*/
+ if (memcmp((pbuf + 2), wpa_oui_type,
+ sizeof(wpa_oui_type)))
+ goto check_next_ie;
+ /*check version...*/
+ memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16));
+ val16 = le16_to_cpu(val16);
+ if (val16 != 0x0001)
+ goto check_next_ie;
+ *wpa_ie_len = *(pbuf + 1);
+ return pbuf;
+ } else {
+ *wpa_ie_len = 0;
+ return NULL;
+ }
+check_next_ie:
+ limit = limit - (pbuf - pie) - 2 - len;
+ if (limit <= 0)
+ break;
+ pbuf += (2 + len);
+ }
+ *wpa_ie_len = 0;
+ return NULL;
+}
+
+unsigned char *r8712_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit)
+{
+ return r8712_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit);
+}
+
+static int r8712_get_wpa_cipher_suite(u8 *s)
+{
+ if (!memcmp(s, (void *)WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN))
+ return WPA_CIPHER_NONE;
+ if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN))
+ return WPA_CIPHER_WEP40;
+ if (!memcmp(s, (void *)WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN))
+ return WPA_CIPHER_TKIP;
+ if (!memcmp(s, (void *)WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN))
+ return WPA_CIPHER_CCMP;
+ if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN))
+ return WPA_CIPHER_WEP104;
+ return 0;
+}
+
+static int r8712_get_wpa2_cipher_suite(u8 *s)
+{
+ if (!memcmp(s, (void *)RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN))
+ return WPA_CIPHER_NONE;
+ if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN))
+ return WPA_CIPHER_WEP40;
+ if (!memcmp(s, (void *)RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN))
+ return WPA_CIPHER_TKIP;
+ if (!memcmp(s, (void *)RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN))
+ return WPA_CIPHER_CCMP;
+ if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN))
+ return WPA_CIPHER_WEP104;
+ return 0;
+}
+
+int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
+ int *pairwise_cipher)
+{
+ int i, ret = _SUCCESS;
+ int left, count;
+ u8 *pos;
+
+ if (wpa_ie_len <= 0) {
+ /* No WPA IE - fail silently */
+ return _FAIL;
+ }
+ if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2))
+ || (memcmp(wpa_ie + 2, (void *)WPA_OUI_TYPE, WPA_SELECTOR_LEN)))
+ return _FAIL;
+ pos = wpa_ie;
+ pos += 8;
+ left = wpa_ie_len - 8;
+ /*group_cipher*/
+ if (left >= WPA_SELECTOR_LEN) {
+ *group_cipher = r8712_get_wpa_cipher_suite(pos);
+ pos += WPA_SELECTOR_LEN;
+ left -= WPA_SELECTOR_LEN;
+ } else if (left > 0)
+ return _FAIL;
+ /*pairwise_cipher*/
+ if (left >= 2) {
+ count = le16_to_cpu(*(u16 *)pos);
+ pos += 2;
+ left -= 2;
+ if (count == 0 || left < count * WPA_SELECTOR_LEN)
+ return _FAIL;
+ for (i = 0; i < count; i++) {
+ *pairwise_cipher |= r8712_get_wpa_cipher_suite(pos);
+ pos += WPA_SELECTOR_LEN;
+ left -= WPA_SELECTOR_LEN;
+ }
+ } else if (left == 1)
+ return _FAIL;
+ return ret;
+}
+
+int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
+ int *pairwise_cipher)
+{
+ int i, ret = _SUCCESS;
+ int left, count;
+ u8 *pos;
+
+ if (rsn_ie_len <= 0) {
+ /* No RSN IE - fail silently */
+ return _FAIL;
+ }
+ if ((*rsn_ie != _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2)))
+ return _FAIL;
+ pos = rsn_ie;
+ pos += 4;
+ left = rsn_ie_len - 4;
+ /*group_cipher*/
+ if (left >= RSN_SELECTOR_LEN) {
+ *group_cipher = r8712_get_wpa2_cipher_suite(pos);
+ pos += RSN_SELECTOR_LEN;
+ left -= RSN_SELECTOR_LEN;
+ } else if (left > 0)
+ return _FAIL;
+ /*pairwise_cipher*/
+ if (left >= 2) {
+ count = le16_to_cpu(*(u16 *)pos);
+ pos += 2;
+ left -= 2;
+ if (count == 0 || left < count * RSN_SELECTOR_LEN)
+ return _FAIL;
+ for (i = 0; i < count; i++) {
+ *pairwise_cipher |= r8712_get_wpa2_cipher_suite(pos);
+ pos += RSN_SELECTOR_LEN;
+ left -= RSN_SELECTOR_LEN;
+ }
+ } else if (left == 1)
+ return _FAIL;
+ return ret;
+}
+
+int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
+ u8 *wpa_ie, u16 *wpa_len)
+{
+ u8 authmode, sec_idx;
+ u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
+ uint cnt;
+
+ /*Search required WPA or WPA2 IE and copy to sec_ie[ ]*/
+ cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
+ sec_idx = 0;
+ while (cnt < in_len) {
+ authmode = in_ie[cnt];
+ if ((authmode == _WPA_IE_ID_) &&
+ (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
+ memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
+ *wpa_len = in_ie[cnt+1]+2;
+ cnt += in_ie[cnt + 1] + 2; /*get next */
+ } else {
+ if (authmode == _WPA2_IE_ID_) {
+ memcpy(rsn_ie, &in_ie[cnt],
+ in_ie[cnt + 1] + 2);
+ *rsn_len = in_ie[cnt+1] + 2;
+ cnt += in_ie[cnt+1] + 2; /*get next*/
+ } else
+ cnt += in_ie[cnt+1] + 2; /*get next*/
+ }
+ }
+ return *rsn_len + *wpa_len;
+}
+
+int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
+{
+ int match;
+ uint cnt;
+ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
+
+ cnt = 12;
+ match = false;
+ while (cnt < in_len) {
+ eid = in_ie[cnt];
+ if ((eid == _WPA_IE_ID_) &&
+ (!memcmp(&in_ie[cnt+2], wps_oui, 4))) {
+ memcpy(wps_ie, &in_ie[cnt], in_ie[cnt+1]+2);
+ *wps_ielen = in_ie[cnt+1]+2;
+ cnt += in_ie[cnt+1]+2;
+ match = true;
+ break;
+ } else
+ cnt += in_ie[cnt+1]+2; /* goto next */
+ }
+ return match;
+}
diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h
new file mode 100644
index 000000000000..432cf8a7605f
--- /dev/null
+++ b/drivers/staging/rtl8712/ieee80211.h
@@ -0,0 +1,770 @@
+#ifndef __IEEE80211_H
+#define __IEEE80211_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wifi.h"
+#include <linux/wireless.h>
+
+#define MGMT_QUEUE_NUM 5
+#define ETH_ALEN 6
+#define IEEE_CMD_SET_WPA_PARAM 1
+#define IEEE_CMD_SET_WPA_IE 2
+#define IEEE_CMD_SET_ENCRYPTION 3
+#define IEEE_CMD_MLME 4
+
+#define IEEE_PARAM_WPA_ENABLED 1
+#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
+#define IEEE_PARAM_DROP_UNENCRYPTED 3
+#define IEEE_PARAM_PRIVACY_INVOKED 4
+#define IEEE_PARAM_AUTH_ALGS 5
+#define IEEE_PARAM_IEEE_802_1X 6
+#define IEEE_PARAM_WPAX_SELECT 7
+
+#define AUTH_ALG_OPEN_SYSTEM 0x1
+#define AUTH_ALG_SHARED_KEY 0x2
+#define AUTH_ALG_LEAP 0x00000004
+
+#define IEEE_MLME_STA_DEAUTH 1
+#define IEEE_MLME_STA_DISASSOC 2
+
+#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
+#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
+#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
+#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
+#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
+#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
+
+
+#define IEEE_CRYPT_ALG_NAME_LEN 16
+
+#define WPA_CIPHER_NONE BIT(0)
+#define WPA_CIPHER_WEP40 BIT(1)
+#define WPA_CIPHER_WEP104 BIT(2)
+#define WPA_CIPHER_TKIP BIT(3)
+#define WPA_CIPHER_CCMP BIT(4)
+
+
+
+#define WPA_SELECTOR_LEN 4
+#define RSN_HEADER_LEN 4
+
+#define RSN_SELECTOR_LEN 4
+
+enum NETWORK_TYPE {
+ WIRELESS_INVALID = 0,
+ WIRELESS_11B = 1,
+ WIRELESS_11G = 2,
+ WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G),
+ WIRELESS_11A = 4,
+ WIRELESS_11N = 8,
+ WIRELESS_11GN = (WIRELESS_11G | WIRELESS_11N),
+ WIRELESS_11BGN = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11N),
+};
+
+
+struct ieee_param {
+ u32 cmd;
+ u8 sta_addr[ETH_ALEN];
+ union {
+ struct {
+ u8 name;
+ u32 value;
+ } wpa_param;
+ struct {
+ u32 len;
+ u8 reserved[32];
+ u8 data[0];
+ } wpa_ie;
+ struct{
+ int command;
+ int reason_code;
+ } mlme;
+ struct {
+ u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
+ u8 set_tx;
+ u32 err;
+ u8 idx;
+ u8 seq[8]; /* sequence counter (set: RX, get: TX) */
+ u16 key_len;
+ u8 key[0];
+ } crypt;
+ } u;
+};
+
+#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_HLEN 30
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+/* this is stolen from ipw2200 driver */
+#define IEEE_IBSS_MAC_HASH_SIZE 31
+
+struct ieee_ibss_seq {
+ u8 mac[ETH_ALEN];
+ u16 seq_num;
+ u16 frag_num;
+ unsigned int packet_time;
+ struct list_head list;
+};
+
+struct ieee80211_hdr {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u16 seq_ctl;
+} __attribute__ ((packed));
+
+
+struct ieee80211_hdr_qos {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+ u16 qc;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr_qos {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u16 seq_ctl;
+ u16 qc;
+} __attribute__ ((packed));
+
+struct eapol {
+ u8 snap[6];
+ u16 ethertype;
+ u8 version;
+ u8 type;
+ u16 length;
+} __attribute__ ((packed));
+
+
+enum eap_type {
+ EAP_PACKET = 0,
+ EAPOL_START,
+ EAPOL_LOGOFF,
+ EAPOL_KEY,
+ EAPOL_ENCAP_ASF_ALERT
+};
+
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN 4
+
+#define MIN_FRAG_THRESHOLD 256U
+#define MAX_FRAG_THRESHOLD 2346U
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS 0x0002
+#define IEEE80211_FCTL_FTYPE 0x000c
+#define IEEE80211_FCTL_STYPE 0x00f0
+#define IEEE80211_FCTL_TODS 0x0100
+#define IEEE80211_FCTL_FROMDS 0x0200
+#define IEEE80211_FCTL_MOREFRAGS 0x0400
+#define IEEE80211_FCTL_RETRY 0x0800
+#define IEEE80211_FCTL_PM 0x1000
+#define IEEE80211_FCTL_MOREDATA 0x2000
+#define IEEE80211_FCTL_WEP 0x4000
+#define IEEE80211_FCTL_ORDER 0x8000
+
+#define IEEE80211_FTYPE_MGMT 0x0000
+#define IEEE80211_FTYPE_CTL 0x0004
+#define IEEE80211_FTYPE_DATA 0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ 0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 0x0010
+#define IEEE80211_STYPE_REASSOC_REQ 0x0020
+#define IEEE80211_STYPE_REASSOC_RESP 0x0030
+#define IEEE80211_STYPE_PROBE_REQ 0x0040
+#define IEEE80211_STYPE_PROBE_RESP 0x0050
+#define IEEE80211_STYPE_BEACON 0x0080
+#define IEEE80211_STYPE_ATIM 0x0090
+#define IEEE80211_STYPE_DISASSOC 0x00A0
+#define IEEE80211_STYPE_AUTH 0x00B0
+#define IEEE80211_STYPE_DEAUTH 0x00C0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL 0x00A0
+#define IEEE80211_STYPE_RTS 0x00B0
+#define IEEE80211_STYPE_CTS 0x00C0
+#define IEEE80211_STYPE_ACK 0x00D0
+#define IEEE80211_STYPE_CFEND 0x00E0
+#define IEEE80211_STYPE_CFENDACK 0x00F0
+
+/* data */
+#define IEEE80211_STYPE_DATA 0x0000
+#define IEEE80211_STYPE_DATA_CFACK 0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
+#define IEEE80211_STYPE_NULLFUNC 0x0040
+#define IEEE80211_STYPE_CFACK 0x0050
+#define IEEE80211_STYPE_CFPOLL 0x0060
+#define IEEE80211_STYPE_CFACKPOLL 0x0070
+#define IEEE80211_QOS_DATAGRP 0x0080
+#define IEEE80211_QoS_DATAGRP IEEE80211_QOS_DATAGRP
+
+#define IEEE80211_SCTL_FRAG 0x000F
+#define IEEE80211_SCTL_SEQ 0xFFF0
+
+/* QoS,QOS */
+#define NORMAL_ACK 0
+#define NO_ACK 1
+#define NON_EXPLICIT_ACK 2
+#define BLOCK_ACK 3
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+
+#define ETH_P_ECONET 0x0018
+
+#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_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f)
+
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+
+/* Status codes */
+#define WLAN_STATUS_SUCCESS 0
+#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
+#define WLAN_STATUS_CAPS_UNSUPPORTED 10
+#define WLAN_STATUS_REASSOC_NO_ASSOC 11
+#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
+#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
+#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
+#define WLAN_STATUS_CHALLENGE_FAIL 15
+#define WLAN_STATUS_AUTH_TIMEOUT 16
+#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
+#define WLAN_STATUS_ASSOC_DENIED_RATES 18
+/* 802.11b */
+#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
+#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
+#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
+
+/* Reason codes */
+#define WLAN_REASON_UNSPECIFIED 1
+#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
+#define WLAN_REASON_DEAUTH_LEAVING 3
+#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
+#define WLAN_REASON_DISASSOC_AP_BUSY 5
+#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
+#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
+#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
+#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
+
+
+/* Information Element IDs */
+#define WLAN_EID_SSID 0
+#define WLAN_EID_SUPP_RATES 1
+#define WLAN_EID_FH_PARAMS 2
+#define WLAN_EID_DS_PARAMS 3
+#define WLAN_EID_CF_PARAMS 4
+#define WLAN_EID_TIM 5
+#define WLAN_EID_IBSS_PARAMS 6
+#define WLAN_EID_CHALLENGE 16
+#define WLAN_EID_RSN 48
+#define WLAN_EID_GENERIC 221
+
+#define IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+
+#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_LEN 4
+#define IEEE80211_NUM_OFDM_RATESLEN 8
+
+
+#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_LEN 8
+#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. Not setting these will not cause
+ * any adverse affects. */
+struct ieee80211_rx_stats {
+ s8 rssi;
+ u8 signal;
+ u8 noise;
+ u8 received_channel;
+ u16 rate; /* in 100 kbps */
+ u8 mask;
+ u8 freq;
+ u16 len;
+};
+
+/* 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 {
+ u32 first_frag_time;
+ uint seq;
+ uint last_frag;
+ uint qos; /*jackson*/
+ uint tid; /*jackson*/
+ struct sk_buff *skb;
+ u8 src_addr[ETH_ALEN];
+ u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+ uint tx_unicast_frames;
+ uint tx_multicast_frames;
+ uint tx_fragments;
+ uint tx_unicast_octets;
+ uint tx_multicast_octets;
+ uint tx_deferred_transmissions;
+ uint tx_single_retry_frames;
+ uint tx_multiple_retry_frames;
+ uint tx_retry_limit_exceeded;
+ uint tx_discards;
+ uint rx_unicast_frames;
+ uint rx_multicast_frames;
+ uint rx_fragments;
+ uint rx_unicast_octets;
+ uint rx_multicast_octets;
+ uint rx_fcs_errors;
+ uint rx_discards_no_buffer;
+ uint tx_discards_wrong_sa;
+ uint rx_discards_undecryptable;
+ uint rx_message_in_msg_fragments;
+ uint rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_softmac_stats{
+ uint rx_ass_ok;
+ uint rx_ass_err;
+ uint rx_probe_rq;
+ uint tx_probe_rs;
+ uint tx_beacons;
+ uint rx_auth_rq;
+ uint rx_auth_rs_ok;
+ uint rx_auth_rs_err;
+ uint tx_auth_rq;
+ uint no_auth_rs;
+ uint no_ass_rs;
+ uint tx_ass_rq;
+ uint rx_ass_rq;
+ uint tx_probe_rq;
+ uint reassoc;
+ uint swtxstop;
+ uint swtxawake;
+};
+
+#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_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 WEP_KEYS 4
+#define WEP_KEY_LEN 13
+
+struct ieee80211_security {
+ u16 active_key:2,
+ enabled:1,
+ auth_mode:2,
+ auth_algo:4,
+ unicast_uses_group:1;
+ u8 key_sizes[WEP_KEYS];
+ u8 keys[WEP_KEYS][WEP_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
+
+*/
+
+struct ieee80211_header_data {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[6];
+ u8 addr2[6];
+ u8 addr3[6];
+ u16 seq_ctrl;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+/* Management Frame Information Element Types */
+#define MFIE_TYPE_SSID 0
+#define MFIE_TYPE_RATES 1
+#define MFIE_TYPE_FH_SET 2
+#define MFIE_TYPE_DS_SET 3
+#define MFIE_TYPE_CF_SET 4
+#define MFIE_TYPE_TIM 5
+#define MFIE_TYPE_IBSS_SET 6
+#define MFIE_TYPE_CHALLENGE 16
+#define MFIE_TYPE_ERP 42
+#define MFIE_TYPE_RSN 48
+#define MFIE_TYPE_RATES_EX 50
+#define MFIE_TYPE_GENERIC 221
+
+struct ieee80211_info_element_hdr {
+ u8 id;
+ u8 len;
+} __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;
+*/
+
+#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
+#define IEEE80211_DEFAULT_BASIC_RATE 10
+
+struct ieee80211_authentication {
+ struct ieee80211_header_data header;
+ u16 algorithm;
+ u16 transaction;
+ u16 status;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+ struct ieee80211_header_data header;
+ u32 time_stamp[2];
+ u16 beacon_interval;
+ u16 capability;
+ struct ieee80211_info_element info_element;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+ struct ieee80211_header_data header;
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_request_frame {
+ struct ieee80211_hdr_3addr header;
+ u16 capability;
+ u16 listen_interval;
+ struct ieee80211_info_element_hdr info_element;
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+ struct ieee80211_hdr_3addr header;
+ u16 capability;
+ u16 status;
+ u16 aid;
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+ u8 nr_frags;
+ u8 encrypted;
+ u16 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 MAX_CHANNEL_NUMBER 161
+#define IEEE80211_SOFTMAC_SCAN_TIME 400
+/*(HZ / 2)*/
+#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
+
+#define CRC_LENGTH 4U
+
+#define MAX_WPA_IE_LEN 128
+#define MAX_WPS_IE_LEN 512
+
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM (1<<1)
+#define NETWORK_HAS_CCK (1<<2)
+
+#define IEEE80211_DTIM_MBCAST 4
+#define IEEE80211_DTIM_UCAST 2
+#define IEEE80211_DTIM_VALID 1
+#define IEEE80211_DTIM_INVALID 0
+
+#define IEEE80211_PS_DISABLED 0
+#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
+#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
+#define IW_ESSID_MAX_SIZE 32
+/*
+ * join_res:
+ * -1: authentication fail
+ * -2: association fail
+ * > 0: TID
+ */
+
+enum ieee80211_state {
+ /* the card is not linked at all */
+ IEEE80211_NOLINK = 0,
+ /* IEEE80211_ASSOCIATING* are for BSS client mode
+ * the driver shall not perform RX filtering unless
+ * the state is LINKED.
+ * The driver shall just check for the state LINKED and
+ * defaults to NOLINK for ALL the other states (including
+ * LINKED_SCANNING)
+ */
+ /* the association procedure will start (wq scheduling)*/
+ IEEE80211_ASSOCIATING,
+ IEEE80211_ASSOCIATING_RETRY,
+ /* the association procedure is sending AUTH request*/
+ IEEE80211_ASSOCIATING_AUTHENTICATING,
+ /* the association procedure has successfully authentcated
+ * and is sending association request
+ */
+ IEEE80211_ASSOCIATING_AUTHENTICATED,
+ /* the link is ok. the card associated to a BSS or linked
+ * to a ibss cell or acting as an AP and creating the bss
+ */
+ IEEE80211_LINKED,
+ /* same as LINKED, but the driver shall apply RX filter
+ * rules as we are in NO_LINK mode. As the card is still
+ * logically linked, but it is doing a syncro site survey
+ * then it will be back to LINKED state.
+ */
+ IEEE80211_LINKED_SCANNING,
+};
+
+#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 MAXTID 16
+
+#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)
+
+extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+{
+ /* Single white space is for Linksys APs */
+ if (essid_len == 1 && essid[0] == ' ')
+ return 1;
+ /* Otherwise, if the entire essid is 0, we assume it is hidden */
+ while (essid_len) {
+ essid_len--;
+ if (essid[essid_len] != '\0')
+ return 0;
+ }
+ return 1;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+ int hdrlen = 24;
+
+ switch (WLAN_FC_GET_TYPE(fc)) {
+ case IEEE80211_FTYPE_DATA:
+ if (fc & IEEE80211_QOS_DATAGRP)
+ hdrlen += 2;
+ if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+ hdrlen += 6; /* 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 registry_priv;
+
+u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen);
+u8 *r8712_get_ie(u8*pbuf, sint index, sint *len, sint limit);
+unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *rsn_ie_len, int limit);
+unsigned char *r8712_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit);
+int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
+ int *pairwise_cipher);
+int r8712_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
+ int *pairwise_cipher);
+int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie,
+ u16 *wpa_len);
+int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen);
+int r8712_generate_ie(struct registry_priv *pregistrypriv, struct _adapter *padapter);
+uint r8712_is_cckrates_included(u8 *rate);
+uint r8712_is_cckratesonly_included(u8 *rate);
+
+#endif /* IEEE80211_H */
+
diff --git a/drivers/staging/rtl8712/if_ether.h b/drivers/staging/rtl8712/if_ether.h
new file mode 100644
index 000000000000..36a2ba5c86f1
--- /dev/null
+++ b/drivers/staging/rtl8712/if_ether.h
@@ -0,0 +1,116 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the Ethernet IEEE 802.3 interface.
+ *
+ * Version: @(#)if_ether.h 1.0.1a 02/08/94
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
+ * Alan Cox, <alan@redhat.com>
+ * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_IF_ETHER_H
+#define _LINUX_IF_ETHER_H
+
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
+#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#define ETH_P_X25 0x0805 /* CCITT X.25 */
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet
+ * [ NOT AN OFFICIAL ID ] */
+#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
+#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr
+ * Trans packet */
+#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+#define ETH_P_LAT 0x6004 /* DEC LAT */
+#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+#define ETH_P_CUST 0x6006 /* DEC Customer use */
+#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
+#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
+#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
+#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
+ * over Ethernet
+ */
+
+/*
+ * Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+#define ETH_P_802_2 0x0004 /* 802.2 frames */
+#define ETH_P_SNAP 0x0005 /* Internal only */
+#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011i /* 802.2 frames */
+#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
+#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
+#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
+#define ETH_P_ECONET 0x0018 /* Acorn Econet */
+
+/*
+ * This is an Ethernet frame header.
+ */
+
+struct ethhdr {
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ unsigned short h_proto; /* packet type ID field */
+};
+
+struct _vlan {
+ unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID*/
+ unsigned short h_vlan_encapsulated_proto;
+};
+
+
+
+#define get_vlan_id(pvlan) ((ntohs((unsigned short)pvlan->h_vlan_TCI)) & 0xfff)
+#define get_vlan_priority(pvlan) ((ntohs((unsigned short)\
+ pvlan->h_vlan_TCI)) >> 13)
+#define get_vlan_encap_proto(pvlan) (ntohs((unsigned short)\
+ pvlan->h_vlan_encapsulated_proto))
+
+
+#endif /* _LINUX_IF_ETHER_H */
+
diff --git a/drivers/staging/rtl8712/ip.h b/drivers/staging/rtl8712/ip.h
new file mode 100644
index 000000000000..4785a591486c
--- /dev/null
+++ b/drivers/staging/rtl8712/ip.h
@@ -0,0 +1,137 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the IP protocol.
+ *
+ * Version: @(#)ip.h 1.0.2 04/28/93
+ *
+ * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.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.
+ */
+#ifndef _LINUX_IP_H
+#define _LINUX_IP_H
+
+#include "rtl871x_byteorder.h"
+
+/* SOL_IP socket options */
+
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_MINCOST 0x02
+
+#define IPTOS_PREC_MASK 0xE0
+#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/* IP options */
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_MEASUREMENT 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_END (0 | IPOPT_CONTROL)
+#define IPOPT_NOOP (1 | IPOPT_CONTROL)
+#define IPOPT_SEC (2 | IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_LSRR (3 | IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_TIMESTAMP (4 | IPOPT_MEASUREMENT)
+#define IPOPT_RR (7 | IPOPT_CONTROL)
+#define IPOPT_SID (8 | IPOPT_CONTROL | IPOPT_COPY)
+#define IPOPT_SSRR (9 | IPOPT_CONTROL | IPOPT_COPY)
+#define IPOPT_RA (20 | IPOPT_CONTROL | IPOPT_COPY)
+
+#define IPVERSION 4
+#define MAXTTL 255
+#define IPDEFTTL 64
+
+/* struct timestamp, struct route and MAX_ROUTES are removed.
+ *
+ * REASONS: it is clear that nobody used them because:
+ * - MAX_ROUTES value was wrong.
+ * - "struct route" was wrong.
+ * - "struct timestamp" had fatally misaligned bitfields and was completely
+ * unusable.
+ */
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN 1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+#define MAX_IPOPTLEN 40
+#define IPOPT_NOP IPOPT_NOOP
+#define IPOPT_EOL IPOPT_END
+#define IPOPT_TS IPOPT_TIMESTAMP
+
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+struct ip_options {
+ __u32 faddr; /* Saved first hop address */
+ unsigned char optlen;
+ unsigned char srr;
+ unsigned char rr;
+ unsigned char ts;
+ unsigned char is_setbyuser:1, /* Set by setsockopt? */
+ is_data:1, /* Options in __data, rather than skb */
+ is_strictroute:1, /* Strict source route */
+ srr_is_hit:1, /* Packet destination addr was our one */
+ is_changed:1, /* IP checksum more not valid */
+ rr_needaddr:1, /* Need to record addr of outgoing dev */
+ ts_needtime:1, /* Need to record timestamp */
+ ts_needaddr:1; /* Need to record addr of outgoing dev */
+ unsigned char router_alert;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __data[0];
+};
+
+#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
+
+struct iphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 ihl:4,
+ version:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 version:4,
+ ihl:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 tos;
+ __u16 tot_len;
+ __u16 id;
+ __u16 frag_off;
+ __u8 ttl;
+ __u8 protocol;
+ __u16 check;
+ __u32 saddr;
+ __u32 daddr;
+ /*The options start here. */
+};
+
+#endif /* _LINUX_IP_H */
+
diff --git a/drivers/staging/rtl8712/little_endian.h b/drivers/staging/rtl8712/little_endian.h
new file mode 100644
index 000000000000..0248c143c6df
--- /dev/null
+++ b/drivers/staging/rtl8712/little_endian.h
@@ -0,0 +1,69 @@
+#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __LITTLE_ENDIAN_BITFIELD
+#define __LITTLE_ENDIAN_BITFIELD
+#endif
+
+#include "swab.h"
+
+#define __constant_htonl(x) ___constant_swab32((x))
+#define __constant_ntohl(x) ___constant_swab32((x))
+#define __constant_htons(x) ___constant_swab16((x))
+#define __constant_ntohs(x) ___constant_swab16((x))
+#define __constant_cpu_to_le64(x) ((__u64)(x))
+#define __constant_le64_to_cpu(x) ((__u64)(x))
+#define __constant_cpu_to_le32(x) ((__u32)(x))
+#define __constant_le32_to_cpu(x) ((__u32)(x))
+#define __constant_cpu_to_le16(x) ((__u16)(x))
+#define __constant_le16_to_cpu(x) ((__u16)(x))
+#define __constant_cpu_to_be64(x) ___constant_swab64((x))
+#define __constant_be64_to_cpu(x) ___constant_swab64((x))
+#define __constant_cpu_to_be32(x) ___constant_swab32((x))
+#define __constant_be32_to_cpu(x) ___constant_swab32((x))
+#define __constant_cpu_to_be16(x) ___constant_swab16((x))
+#define __constant_be16_to_cpu(x) ___constant_swab16((x))
+#define __cpu_to_le64(x) ((__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(x))
+#define __cpu_to_le32(x) ((__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(x))
+#define __cpu_to_le16(x) ((__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(x))
+#define __cpu_to_be64(x) __swab64((x))
+#define __be64_to_cpu(x) __swab64((x))
+#define __cpu_to_be32(x) __swab32((x))
+#define __be32_to_cpu(x) __swab32((x))
+#define __cpu_to_be16(x) __swab16((x))
+#define __be16_to_cpu(x) __swab16((x))
+#define __cpu_to_le64p(x) (*(__u64 *)(x))
+#define __le64_to_cpup(x) (*(__u64 *)(x))
+#define __cpu_to_le32p(x) (*(__u32 *)(x))
+#define __le32_to_cpup(x) (*(__u32 *)(x))
+#define __cpu_to_le16p(x) (*(__u16 *)(x))
+#define __le16_to_cpup(x) (*(__u16 *)(x))
+#define __cpu_to_be64p(x) __swab64p((x))
+#define __be64_to_cpup(x) __swab64p((x))
+#define __cpu_to_be32p(x) __swab32p((x))
+#define __be32_to_cpup(x) __swab32p((x))
+#define __cpu_to_be16p(x) __swab16p((x))
+#define __be16_to_cpup(x) __swab16p((x))
+#define __cpu_to_le64s(x) do {} while (0)
+#define __le64_to_cpus(x) do {} while (0)
+#define __cpu_to_le32s(x) do {} while (0)
+#define __le32_to_cpus(x) do {} while (0)
+#define __cpu_to_le16s(x) do {} while (0)
+#define __le16_to_cpus(x) do {} while (0)
+#define __cpu_to_be64s(x) __swab64s((x))
+#define __be64_to_cpus(x) __swab64s((x))
+#define __cpu_to_be32s(x) __swab32s((x))
+#define __be32_to_cpus(x) __swab32s((x))
+#define __cpu_to_be16s(x) __swab16s((x))
+#define __be16_to_cpus(x) __swab16s((x))
+
+#include "generic.h"
+
+#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */
+
diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c
new file mode 100644
index 000000000000..abf96c14df93
--- /dev/null
+++ b/drivers/staging/rtl8712/mlme_linux.c
@@ -0,0 +1,170 @@
+/******************************************************************************
+ * mlme_linux.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _MLME_OSDEP_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "mlme_osdep.h"
+
+static void sitesurvey_ctrl_handler(void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+
+ _r8712_sitesurvey_ctrl_handler(adapter);
+ _set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer,
+ 3000);
+}
+
+static void join_timeout_handler (void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+ _r8712_join_timeout_handler(adapter);
+}
+
+static void _scan_timeout_handler (void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+ r8712_scan_timeout_handler(adapter);
+}
+
+static void dhcp_timeout_handler (void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+ _r8712_dhcp_timeout_handler(adapter);
+}
+
+static void wdg_timeout_handler (void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+
+ _r8712_wdg_timeout_handler(adapter);
+
+ _set_timer(&adapter->mlmepriv.wdg_timer, 2000);
+}
+
+void r8712_init_mlme_timer(struct _adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev,
+ join_timeout_handler, (pmlmepriv->nic_hdl));
+ _init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer),
+ padapter->pnetdev, sitesurvey_ctrl_handler,
+ (u8 *)(pmlmepriv->nic_hdl));
+ _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev,
+ _scan_timeout_handler, (pmlmepriv->nic_hdl));
+ _init_timer(&(pmlmepriv->dhcp_timer), padapter->pnetdev,
+ dhcp_timeout_handler, (u8 *)(pmlmepriv->nic_hdl));
+ _init_timer(&(pmlmepriv->wdg_timer), padapter->pnetdev,
+ wdg_timeout_handler, (u8 *)(pmlmepriv->nic_hdl));
+}
+
+void r8712_os_indicate_connect(struct _adapter *adapter)
+{
+ r8712_indicate_wx_assoc_event(adapter);
+ netif_carrier_on(adapter->pnetdev);
+}
+
+static struct RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE];
+void r8712_os_indicate_disconnect(struct _adapter *adapter)
+{
+ u8 backupPMKIDIndex = 0;
+ u8 backupTKIPCountermeasure = 0x00;
+
+ r8712_indicate_wx_disassoc_event(adapter);
+ netif_carrier_off(adapter->pnetdev);
+ if (adapter->securitypriv.AuthAlgrthm == 2) { /*/802.1x*/
+ /* We have to backup the PMK information for WiFi PMK Caching
+ * test item. Backup the btkip_countermeasure information.
+ * When the countermeasure is trigger, the driver have to
+ * disconnect with AP for 60 seconds.
+ */
+
+ memset(&backupPMKIDList[0], 0x00, sizeof(
+ struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
+ memcpy(&backupPMKIDList[0], &adapter->securitypriv.
+ PMKIDList[0], sizeof(struct RT_PMKID_LIST) *
+ NUM_PMKID_CACHE);
+ backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
+ backupTKIPCountermeasure = adapter->securitypriv.
+ btkip_countermeasure;
+ memset((unsigned char *)&adapter->securitypriv, 0,
+ sizeof(struct security_priv));
+ _init_timer(&(adapter->securitypriv.tkip_timer),
+ adapter->pnetdev, r8712_use_tkipkey_handler,
+ adapter);
+ /* Restore the PMK information to securitypriv structure
+ * for the following connection. */
+ memcpy(&adapter->securitypriv.PMKIDList[0],
+ &backupPMKIDList[0],
+ sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
+ adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
+ adapter->securitypriv.btkip_countermeasure =
+ backupTKIPCountermeasure;
+ } else { /*reset values in securitypriv*/
+ struct security_priv *psec_priv = &adapter->securitypriv;
+
+ psec_priv->AuthAlgrthm = 0; /*open system*/
+ psec_priv->PrivacyAlgrthm = _NO_PRIVACY_;
+ psec_priv->PrivacyKeyIndex = 0;
+ psec_priv->XGrpPrivacy = _NO_PRIVACY_;
+ psec_priv->XGrpKeyid = 1;
+ psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
+ psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
+ psec_priv->wps_phase = false;
+ }
+}
+
+void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie)
+{
+ uint len;
+ u8 *buff, *p, i;
+ union iwreq_data wrqu;
+
+ buff = NULL;
+ if (authmode == _WPA_IE_ID_) {
+ buff = _malloc(IW_CUSTOM_MAX);
+ if (buff == NULL)
+ return;
+ memset(buff, 0, IW_CUSTOM_MAX);
+ p = buff;
+ p += sprintf(p, "ASSOCINFO(ReqIEs=");
+ len = sec_ie[1] + 2;
+ len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX;
+ for (i = 0; i < len; i++)
+ p += sprintf(p, "%02x", sec_ie[i]);
+ p += sprintf(p, ")");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = p-buff;
+ wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ?
+ wrqu.data.length : IW_CUSTOM_MAX;
+ wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
+ kfree(buff);
+ }
+}
diff --git a/drivers/staging/rtl8712/mlme_osdep.h b/drivers/staging/rtl8712/mlme_osdep.h
new file mode 100644
index 000000000000..7013a4980802
--- /dev/null
+++ b/drivers/staging/rtl8712/mlme_osdep.h
@@ -0,0 +1,18 @@
+#ifndef __MLME_OSDEP_H_
+#define __MLME_OSDEP_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+void r8712_init_mlme_timer(struct _adapter *padapter);
+void r8712_os_indicate_disconnect(struct _adapter *adapter);
+void r8712_os_indicate_connect(struct _adapter *adapter);
+void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie);
+int r8712_recv_indicatepkts_in_order(struct _adapter *adapter,
+ struct recv_reorder_ctrl *precvreorder_ctrl,
+ int bforced);
+void r8712_indicate_wx_assoc_event(struct _adapter *padapter);
+void r8712_indicate_wx_disassoc_event(struct _adapter *padapter);
+
+#endif /*_MLME_OSDEP_H_*/
+
diff --git a/drivers/staging/rtl8712/mp_custom_oid.h b/drivers/staging/rtl8712/mp_custom_oid.h
new file mode 100644
index 000000000000..a9e0b3483e3c
--- /dev/null
+++ b/drivers/staging/rtl8712/mp_custom_oid.h
@@ -0,0 +1,274 @@
+#ifndef __CUSTOM_OID_H
+#define __CUSTOM_OID_H
+
+/* 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit
+ * 0xFF818500 - 0xFF81850F RTL8185 Setup Utility
+ * 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility
+ *
+ * by Owen for Production Kit
+ * For Production Kit with Agilent Equipments
+ * in order to make our custom oids hopefully somewhat unique
+ * we will use 0xFF (indicating implementation specific OID)
+ * 81(first byte of non zero Realtek unique identifier)
+ * 80 (second byte of non zero Realtek unique identifier)
+ * XX (the custom OID number - providing 255 possible custom oids)
+ */
+#define OID_RT_PRO_RESET_DUT 0xFF818000
+#define OID_RT_PRO_SET_DATA_RATE 0xFF818001
+#define OID_RT_PRO_START_TEST 0xFF818002
+#define OID_RT_PRO_STOP_TEST 0xFF818003
+#define OID_RT_PRO_SET_PREAMBLE 0xFF818004
+#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005
+#define OID_RT_PRO_SET_FILTER_BB 0xFF818006
+#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007
+#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008
+#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009
+#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A
+
+#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D
+#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E
+#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F
+#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010
+#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011
+#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012
+#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013
+#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014
+#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015
+#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016
+#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017
+#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018
+#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019
+#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A
+#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B
+#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C
+#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D
+#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E
+#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F
+#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020
+#define OID_RT_PRO_WRITE_EEPROM 0xFF818021
+#define OID_RT_PRO_READ_EEPROM 0xFF818022
+#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023
+#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024
+#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025
+#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026
+#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027
+#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028
+#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029
+#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A
+#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C
+#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D
+#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E
+#define OID_RT_PRO_SET_MODULATION 0xFF81802F
+#define OID_RT_DRIVER_OPTION 0xFF818080
+#define OID_RT_RF_OFF 0xFF818081
+#define OID_RT_AUTH_STATUS 0xFF818082
+#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B
+#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C
+#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B
+#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043
+#define OID_RT_UTILITY_FALSE_ALARM_COUNTERS 0xFF818580
+#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581
+#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582
+#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583
+#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584
+#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS \
+ 0xFF818585
+#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586
+#define OID_RT_WIRELESS_MODE 0xFF818500
+#define OID_RT_SUPPORTED_RATES 0xFF818501
+#define OID_RT_DESIRED_RATES 0xFF818502
+#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503
+#define OID_RT_GET_CONNECT_STATE 0xFF030001
+#define OID_RT_RESCAN 0xFF030002
+#define OID_RT_SET_KEY_LENGTH 0xFF030003
+#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004
+#define OID_RT_SET_CHANNEL 0xFF010182
+#define OID_RT_SET_SNIFFER_MODE 0xFF010183
+#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184
+#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185
+#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186
+#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187
+#define OID_RT_GET_TX_RETRY 0xFF010188
+#define OID_RT_GET_RX_RETRY 0xFF010189
+#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A
+#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B
+#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190
+#define OID_RT_GET_TX_BEACON_OK 0xFF010191
+#define OID_RT_GET_TX_BEACON_ERR 0xFF010192
+#define OID_RT_GET_RX_ICV_ERR 0xFF010193
+#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194
+#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195
+#define OID_RT_GET_PREAMBLE_MODE 0xFF010196
+#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197
+#define OID_RT_GET_AP_IP 0xFF010198
+#define OID_RT_GET_CHANNELPLAN 0xFF010199
+#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A
+#define OID_RT_SET_BCN_INTVL 0xFF01019B
+#define OID_RT_GET_RF_VENDER 0xFF01019C
+#define OID_RT_DEDICATE_PROBE 0xFF01019D
+#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E
+#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F
+#define OID_RT_GET_CCA_ERR 0xFF0101A0
+#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1
+#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2
+#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3
+#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4
+#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5
+#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5
+#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6
+#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7
+#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8
+#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9
+#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA
+#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB
+#define OID_RT_GET_CHANNEL 0xFF0101AC
+#define OID_RT_SET_CHANNELPLAN 0xFF0101AD
+#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE
+#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF
+#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0
+#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1
+#define OID_RT_GET_IS_ROAMING 0xFF0101B2
+#define OID_RT_GET_IS_PRIVACY 0xFF0101B3
+#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4
+#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5
+#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6
+#define OID_RT_RESET_LOG 0xFF0101B7
+#define OID_RT_GET_LOG 0xFF0101B8
+#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9
+#define OID_RT_GET_HEADER_FAIL 0xFF0101BA
+#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB
+#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC
+#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD
+#define OID_RT_GET_TX_INFO 0xFF0101BE
+#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF
+#define OID_RT_RF_READ_WRITE 0xFF0101C0
+#define OID_RT_FORCED_DATA_RATE 0xFF0101C1
+#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2
+#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3
+#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4
+#define OID_RT_PRO_RX_FILTER 0xFF0111C0
+#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1
+#define OID_CE_USB_READ_REGISTRY 0xFF0111C2
+#define OID_RT_PRO_SET_INITIAL_GAIN 0xFF0111C3
+#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4
+#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5
+#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6
+#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7
+#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8
+#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9
+#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA
+#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300
+#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301
+#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302
+#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303
+#define OID_RT_AP_SUPPORTED 0xFF010304
+#define OID_RT_AP_SET_PASSPHRASE 0xFF010305
+#define OID_RT_PRO8187_WI_POLL 0xFF818780
+#define OID_RT_PRO_WRITE_BB_REG 0xFF818781
+#define OID_RT_PRO_READ_BB_REG 0xFF818782
+#define OID_RT_PRO_WRITE_RF_REG 0xFF818783
+#define OID_RT_PRO_READ_RF_REG 0xFF818784
+#define OID_RT_MH_VENDER_ID 0xFFEDC100
+#define OID_RT_PRO8711_JOIN_BSS 0xFF871100
+#define OID_RT_PRO_READ_REGISTER 0xFF871101
+#define OID_RT_PRO_WRITE_REGISTER 0xFF871102
+#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103
+#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104
+#define OID_RT_PRO_WRITE_TXCMD 0xFF871105
+#define OID_RT_PRO_READ16_EEPROM 0xFF871106
+#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107
+#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108
+#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109
+#define OID_RT_PRO8711_WI_POLL 0xFF87110A
+#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B
+#define OID_RT_RD_ATTRIB_MEM 0xFF87110C
+#define OID_RT_WR_ATTRIB_MEM 0xFF87110D
+/*Method 2 for H2C/C2H*/
+#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110
+#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111
+#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112
+#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113
+#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114
+#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115
+#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116
+#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117
+#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118
+#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119
+#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A
+#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B
+#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C
+#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D
+#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E
+#define OID_RT_POLL_RX_STATUS 0xFF87111F
+#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120
+#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121
+#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122
+#define OID_RT_PRO_READ_TSSI 0xFF871123
+#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124
+#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150
+#define OID_RT_PRO_SET_PWRSTATE 0xFF871151
+/*Method 2 , using workitem */
+#define OID_RT_SET_READ_REG 0xFF871181
+#define OID_RT_SET_WRITE_REG 0xFF871182
+#define OID_RT_SET_BURST_READ_REG 0xFF871183
+#define OID_RT_SET_BURST_WRITE_REG 0xFF871184
+#define OID_RT_SET_WRITE_TXCMD 0xFF871185
+#define OID_RT_SET_READ16_EEPROM 0xFF871186
+#define OID_RT_SET_WRITE16_EEPROM 0xFF871187
+#define OID_RT_QRY_POLL_WKITEM 0xFF871188
+
+/*For SDIO INTERFACE only*/
+#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0
+#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1
+
+/*For USB INTERFACE only*/
+#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0
+#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1
+#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2
+#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3
+#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4
+
+#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB
+#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC
+#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE
+
+#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200
+#define OID_RT_PRO_ADD_STA_INFO 0xFF871201
+#define OID_RT_PRO_DELE_STA_INFO 0xFF871202
+#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203
+
+#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204
+
+#define OID_RT_PRO_READ_EFUSE 0xFF871205
+#define OID_RT_PRO_WRITE_EFUSE 0xFF871206
+#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207
+#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208
+
+#define OID_RT_SET_BANDWIDTH 0xFF871209
+#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A
+
+#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B
+
+#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C
+
+#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D
+
+#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E
+
+#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F
+
+#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210
+
+#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211
+#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212
+#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213
+
+#define OID_RT_SET_POWER_DOWN 0xFF871214
+
+#define OID_RT_GET_POWER_MODE 0xFF871215
+
+#define OID_RT_PRO_EFUSE 0xFF871216
+#define OID_RT_PRO_EFUSE_MAP 0xFF871217
+
+#endif /*#ifndef __CUSTOM_OID_H */
+
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
new file mode 100644
index 000000000000..3f38e8eca3f1
--- /dev/null
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -0,0 +1,464 @@
+/******************************************************************************
+ * os_intfs.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _OS_INTFS_C_
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "xmit_osdep.h"
+#include "recv_osdep.h"
+#include "rtl871x_ioctl.h"
+#include "usb_osintf.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("rtl871x wireless lan driver");
+MODULE_AUTHOR("Larry Finger");
+
+static char ifname[IFNAMSIZ] = "wlan%d";
+
+/* module param defaults */
+static int chip_version = RTL8712_2ndCUT;
+static int rfintfs = HWPI;
+static int lbkmode = RTL8712_AIR_TRX;
+static int hci = RTL8712_USB;
+static int ampdu_enable = 1;/*for enable tx_ampdu*/
+
+/* The video_mode variable is for vedio mode.*/
+/* It may be specify when inserting module with video_mode=1 parameter.*/
+static int video_mode = 1; /* enable video mode*/
+
+/*Ndis802_11Infrastructure; infra, ad-hoc, auto*/
+static int network_mode = Ndis802_11IBSS;
+static int channel = 1;/*ad-hoc support requirement*/
+static int wireless_mode = WIRELESS_11BG;
+static int vrtl_carrier_sense = AUTO_VCS;
+static int vcs_type = RTS_CTS;
+static int frag_thresh = 2346;
+static int preamble = PREAMBLE_LONG;/*long, short, auto*/
+static int scan_mode = 1;/*active, passive*/
+static int adhoc_tx_pwr = 1;
+static int soft_ap;
+static int smart_ps = 1;
+static int power_mgnt = PS_MODE_ACTIVE;
+static int radio_enable = 1;
+static int long_retry_lmt = 7;
+static int short_retry_lmt = 7;
+static int busy_thresh = 40;
+static int ack_policy = NORMAL_ACK;
+static int mp_mode;
+static int software_encrypt;
+static int software_decrypt;
+
+static int wmm_enable;/* default is set to disable the wmm.*/
+static int uapsd_enable;
+static int uapsd_max_sp = NO_LIMIT;
+static int uapsd_acbk_en;
+static int uapsd_acbe_en;
+static int uapsd_acvi_en;
+static int uapsd_acvo_en;
+
+static int ht_enable = 1;
+static int cbw40_enable = 1;
+static int rf_config = RTL8712_RF_1T2R; /* 1T2R*/
+static int low_power;
+/* mac address to use instead of the one stored in Efuse */
+char *r8712_initmac;
+static char *initmac;
+/* if wifi_test = 1, driver will disable the turbo mode and pass it to
+ * firmware private.
+ */
+static int wifi_test = 0;
+
+module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
+module_param(wifi_test, int, 0644);
+module_param(initmac, charp, 0644);
+module_param(video_mode, int, 0644);
+module_param(chip_version, int, 0644);
+module_param(rfintfs, int, 0644);
+module_param(lbkmode, int, 0644);
+module_param(hci, int, 0644);
+module_param(network_mode, int, 0644);
+module_param(channel, int, 0644);
+module_param(mp_mode, int, 0644);
+module_param(wmm_enable, int, 0644);
+module_param(vrtl_carrier_sense, int, 0644);
+module_param(vcs_type, int, 0644);
+module_param(busy_thresh, int, 0644);
+module_param(ht_enable, int, 0644);
+module_param(cbw40_enable, int, 0644);
+module_param(ampdu_enable, int, 0644);
+module_param(rf_config, int, 0644);
+module_param(power_mgnt, int, 0644);
+module_param(low_power, int, 0644);
+
+MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
+MODULE_PARM_DESC(initmac, "MAC-Address, default: use FUSE");
+
+static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev);
+static int netdev_open(struct net_device *pnetdev);
+static int netdev_close(struct net_device *pnetdev);
+
+static uint loadparam(struct _adapter *padapter, struct net_device *pnetdev)
+{
+ uint status = _SUCCESS;
+ struct registry_priv *registry_par = &padapter->registrypriv;
+
+ registry_par->chip_version = (u8)chip_version;
+ registry_par->rfintfs = (u8)rfintfs;
+ registry_par->lbkmode = (u8)lbkmode;
+ registry_par->hci = (u8)hci;
+ registry_par->network_mode = (u8)network_mode;
+ memcpy(registry_par->ssid.Ssid, "ANY", 3);
+ registry_par->ssid.SsidLength = 3;
+ registry_par->channel = (u8)channel;
+ registry_par->wireless_mode = (u8)wireless_mode;
+ registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense ;
+ registry_par->vcs_type = (u8)vcs_type;
+ registry_par->frag_thresh = (u16)frag_thresh;
+ registry_par->preamble = (u8)preamble;
+ registry_par->scan_mode = (u8)scan_mode;
+ registry_par->adhoc_tx_pwr = (u8)adhoc_tx_pwr;
+ registry_par->soft_ap = (u8)soft_ap;
+ registry_par->smart_ps = (u8)smart_ps;
+ registry_par->power_mgnt = (u8)power_mgnt;
+ registry_par->radio_enable = (u8)radio_enable;
+ registry_par->long_retry_lmt = (u8)long_retry_lmt;
+ registry_par->short_retry_lmt = (u8)short_retry_lmt;
+ registry_par->busy_thresh = (u16)busy_thresh;
+ registry_par->ack_policy = (u8)ack_policy;
+ registry_par->mp_mode = (u8)mp_mode;
+ registry_par->software_encrypt = (u8)software_encrypt;
+ registry_par->software_decrypt = (u8)software_decrypt;
+ /*UAPSD*/
+ registry_par->wmm_enable = (u8)wmm_enable;
+ registry_par->uapsd_enable = (u8)uapsd_enable;
+ registry_par->uapsd_max_sp = (u8)uapsd_max_sp;
+ registry_par->uapsd_acbk_en = (u8)uapsd_acbk_en;
+ registry_par->uapsd_acbe_en = (u8)uapsd_acbe_en;
+ registry_par->uapsd_acvi_en = (u8)uapsd_acvi_en;
+ registry_par->uapsd_acvo_en = (u8)uapsd_acvo_en;
+ registry_par->ht_enable = (u8)ht_enable;
+ registry_par->cbw40_enable = (u8)cbw40_enable;
+ registry_par->ampdu_enable = (u8)ampdu_enable;
+ registry_par->rf_config = (u8)rf_config;
+ registry_par->low_power = (u8)low_power;
+ registry_par->wifi_test = (u8) wifi_test;
+ r8712_initmac = initmac;
+ return status;
+}
+
+static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev);
+ struct sockaddr *addr = p;
+
+ if (padapter->bup == false)
+ memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN);
+ return 0;
+}
+
+static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev);
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
+
+ padapter->stats.tx_packets = pxmitpriv->tx_pkts;
+ padapter->stats.rx_packets = precvpriv->rx_pkts;
+ padapter->stats.tx_dropped = pxmitpriv->tx_drop;
+ padapter->stats.rx_dropped = precvpriv->rx_drop;
+ padapter->stats.tx_bytes = pxmitpriv->tx_bytes;
+ padapter->stats.rx_bytes = precvpriv->rx_bytes;
+ return &padapter->stats;
+}
+
+static const struct net_device_ops rtl8712_netdev_ops = {
+ .ndo_open = netdev_open,
+ .ndo_stop = netdev_close,
+ .ndo_start_xmit = r8712_xmit_entry,
+ .ndo_set_mac_address = r871x_net_set_mac_address,
+ .ndo_get_stats = r871x_net_get_stats,
+ .ndo_do_ioctl = r871x_ioctl,
+};
+
+struct net_device *r8712_init_netdev(void)
+{
+ struct _adapter *padapter;
+ struct net_device *pnetdev;
+
+ pnetdev = alloc_etherdev(sizeof(struct _adapter));
+ if (!pnetdev)
+ return NULL;
+ if (dev_alloc_name(pnetdev, ifname) < 0) {
+ strcpy(ifname, "wlan%d");
+ dev_alloc_name(pnetdev, ifname);
+ }
+ padapter = (struct _adapter *) _netdev_priv(pnetdev);
+ padapter->pnetdev = pnetdev;
+ printk(KERN_INFO "r8712u: register rtl8712_netdev_ops to"
+ " netdev_ops\n");
+ pnetdev->netdev_ops = &rtl8712_netdev_ops;
+ pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
+ pnetdev->wireless_handlers = (struct iw_handler_def *)
+ &r871x_handlers_def;
+ /*step 2.*/
+ loadparam(padapter, pnetdev);
+ netif_carrier_off(pnetdev);
+ padapter->pid = 0; /* Initial the PID value used for HW PBC.*/
+ return pnetdev;
+}
+
+static u32 start_drv_threads(struct _adapter *padapter)
+{
+ padapter->cmdThread = kthread_run(r8712_cmd_thread, padapter,
+ padapter->pnetdev->name);
+ if (IS_ERR(padapter->cmdThread) < 0)
+ return _FAIL;
+ return _SUCCESS;
+}
+
+void r8712_stop_drv_threads(struct _adapter *padapter)
+{
+ /*Below is to termindate r8712_cmd_thread & event_thread...*/
+ up(&padapter->cmdpriv.cmd_queue_sema);
+ if (padapter->cmdThread)
+ _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
+ padapter->cmdpriv.cmd_seq = 1;
+}
+
+static void start_drv_timers(struct _adapter *padapter)
+{
+ _set_timer(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer,
+ 5000);
+ _set_timer(&padapter->mlmepriv.wdg_timer, 2000);
+}
+
+static void stop_drv_timers(struct _adapter *padapter)
+{
+ _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
+ _cancel_timer_ex(&padapter->mlmepriv.sitesurveyctrl.
+ sitesurvey_ctrl_timer);
+ _cancel_timer_ex(&padapter->securitypriv.tkip_timer);
+ _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
+ _cancel_timer_ex(&padapter->mlmepriv.dhcp_timer);
+ _cancel_timer_ex(&padapter->mlmepriv.wdg_timer);
+}
+
+static u8 init_default_value(struct _adapter *padapter)
+{
+ u8 ret = _SUCCESS;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ /*xmit_priv*/
+ pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
+ pxmitpriv->vcs = pregistrypriv->vcs_type;
+ pxmitpriv->vcs_type = pregistrypriv->vcs_type;
+ pxmitpriv->rts_thresh = pregistrypriv->rts_thresh;
+ pxmitpriv->frag_len = pregistrypriv->frag_thresh;
+ /*ht_priv*/
+ {
+ int i;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+
+ phtpriv->ampdu_enable = false;/*set to disabled*/
+ for (i = 0; i < 16; i++)
+ phtpriv->baddbareq_issued[i] = false;
+ }
+ /*security_priv*/
+ psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt;
+ psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt;
+ psecuritypriv->binstallGrpkey = _FAIL;
+ /*pwrctrl_priv*/
+ /*registry_priv*/
+ r8712_init_registrypriv_dev_network(padapter);
+ r8712_update_registrypriv_dev_network(padapter);
+ /*misc.*/
+ return ret;
+}
+
+u8 r8712_init_drv_sw(struct _adapter *padapter)
+{
+ if ((r8712_init_cmd_priv(&padapter->cmdpriv)) == _FAIL)
+ return _FAIL;
+ padapter->cmdpriv.padapter = padapter;
+ if ((r8712_init_evt_priv(&padapter->evtpriv)) == _FAIL)
+ return _FAIL;
+ if (r8712_init_mlme_priv(padapter) == _FAIL)
+ return _FAIL;
+ _r8712_init_xmit_priv(&padapter->xmitpriv, padapter);
+ _r8712_init_recv_priv(&padapter->recvpriv, padapter);
+ memset((unsigned char *)&padapter->securitypriv, 0,
+ sizeof(struct security_priv));
+ _init_timer(&(padapter->securitypriv.tkip_timer), padapter->pnetdev,
+ r8712_use_tkipkey_handler, padapter);
+ _r8712_init_sta_priv(&padapter->stapriv);
+ padapter->stapriv.padapter = padapter;
+ r8712_init_bcmc_stainfo(padapter);
+ r8712_init_pwrctrl_priv(padapter);
+ sema_init(&(padapter->pwrctrlpriv.pnp_pwr_mgnt_sema), 0);
+ mp871xinit(padapter);
+ if (init_default_value(padapter) != _SUCCESS)
+ return _FAIL;
+ r8712_InitSwLeds(padapter);
+ return _SUCCESS;
+}
+
+u8 r8712_free_drv_sw(struct _adapter *padapter)
+{
+ struct net_device *pnetdev = (struct net_device *)padapter->pnetdev;
+
+ r8712_free_cmd_priv(&padapter->cmdpriv);
+ r8712_free_evt_priv(&padapter->evtpriv);
+ r8712_DeInitSwLeds(padapter);
+ r8712_free_mlme_priv(&padapter->mlmepriv);
+ r8712_free_io_queue(padapter);
+ _free_xmit_priv(&padapter->xmitpriv);
+ _r8712_free_sta_priv(&padapter->stapriv);
+ _r8712_free_recv_priv(&padapter->recvpriv);
+ mp871xdeinit(padapter);
+ if (pnetdev)
+ os_free_netdev(pnetdev);
+ return _SUCCESS;
+}
+
+
+static void enable_video_mode(struct _adapter *padapter, int cbw40_value)
+{
+ /* bit 8:
+ * 1 -> enable video mode to 96B AP
+ * 0 -> disable video mode to 96B AP
+ * bit 9:
+ * 1 -> enable 40MHz mode
+ * 0 -> disable 40MHz mode
+ * bit 10:
+ * 1 -> enable STBC
+ * 0 -> disable STBC
+ */
+ u32 intcmd = 0xf4000500; /* enable bit8, bit10*/
+
+ if (cbw40_value) {
+ /* if the driver supports the 40M bandwidth,
+ * we can enable the bit 9.*/
+ intcmd |= 0x200;
+ }
+ r8712_fw_cmd(padapter, intcmd);
+}
+
+static int netdev_open(struct net_device *pnetdev)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev);
+
+ if (padapter->bup == false) {
+ padapter->bDriverStopped = false;
+ padapter->bSurpriseRemoved = false;
+ padapter->bup = true;
+ if (rtl871x_hal_init(padapter) != _SUCCESS)
+ goto netdev_open_error;
+ if (r8712_initmac == NULL)
+ /* Use the mac address stored in the Efuse */
+ memcpy(pnetdev->dev_addr,
+ padapter->eeprompriv.mac_addr, ETH_ALEN);
+ else {
+ /* We have to inform f/w to use user-supplied MAC
+ * address.
+ */
+ msleep(200);
+ r8712_setMacAddr_cmd(padapter, (u8 *)pnetdev->dev_addr);
+ /*
+ * The "myid" function will get the wifi mac address
+ * from eeprompriv structure instead of netdev
+ * structure. So, we have to overwrite the mac_addr
+ * stored in the eeprompriv structure. In this case,
+ * the real mac address won't be used anymore. So that,
+ * the eeprompriv.mac_addr should store the mac which
+ * users specify.
+ */
+ memcpy(padapter->eeprompriv.mac_addr,
+ pnetdev->dev_addr, ETH_ALEN);
+ }
+ if (start_drv_threads(padapter) != _SUCCESS)
+ goto netdev_open_error;
+ if (padapter->dvobjpriv.inirp_init == NULL)
+ goto netdev_open_error;
+ else
+ padapter->dvobjpriv.inirp_init(padapter);
+ r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
+ padapter->registrypriv.smart_ps);
+ }
+ if (!netif_queue_stopped(pnetdev))
+ netif_start_queue(pnetdev);
+ else
+ netif_wake_queue(pnetdev);
+
+ if (video_mode)
+ enable_video_mode(padapter, cbw40_enable);
+ /* start driver mlme relation timer */
+ start_drv_timers(padapter);
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
+ return 0;
+netdev_open_error:
+ padapter->bup = false;
+ netif_carrier_off(pnetdev);
+ netif_stop_queue(pnetdev);
+ return -1;
+}
+
+static int netdev_close(struct net_device *pnetdev)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev);
+
+ /* Close LED*/
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF);
+ msleep(200);
+
+ /*s1.*/
+ if (pnetdev) {
+ if (!netif_queue_stopped(pnetdev))
+ netif_stop_queue(pnetdev);
+ }
+ /*s2.*/
+ /*s2-1. issue disassoc_cmd to fw*/
+ r8712_disassoc_cmd(padapter);
+ /*s2-2. indicate disconnect to os*/
+ r8712_ind_disconnect(padapter);
+ /*s2-3.*/
+ r8712_free_assoc_resources(padapter);
+ /*s2-4.*/
+ r8712_free_network_queue(padapter);
+ /*Stop driver mlme relation timer*/
+ stop_drv_timers(padapter);
+ return 0;
+}
+
+#include "mlme_osdep.h"
diff --git a/drivers/staging/rtl8712/osdep_intf.h b/drivers/staging/rtl8712/osdep_intf.h
new file mode 100644
index 000000000000..3bc20257b034
--- /dev/null
+++ b/drivers/staging/rtl8712/osdep_intf.h
@@ -0,0 +1,19 @@
+#ifndef __OSDEP_INTF_H_
+#define __OSDEP_INTF_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0 : 1)) << 2)
+
+struct intf_priv {
+ u8 *intf_dev;
+ /* when in USB, IO is through interrupt in/out endpoints */
+ struct usb_device *udev;
+ struct urb *piorw_urb;
+ struct semaphore io_retevt;
+};
+
+int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+
+#endif /*_OSDEP_INTF_H_*/
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
new file mode 100644
index 000000000000..73509dad2107
--- /dev/null
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -0,0 +1,260 @@
+#ifndef __OSDEP_SERVICE_H_
+#define __OSDEP_SERVICE_H_
+
+#define _SUCCESS 1
+#define _FAIL 0
+
+#include "basic_types.h"
+#include <linux/version.h>
+#include <linux/spinlock.h>
+
+#include <linux/semaphore.h>
+#include <linux/sem.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/iw_handler.h>
+#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/smp_lock.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/usb.h>
+#include <linux/usb/ch9.h>
+#include <linux/io.h>
+#include <linux/circ_buf.h>
+#include <linux/uaccess.h>
+#include <asm/byteorder.h>
+#include <asm/atomic.h>
+#include <linux/wireless.h>
+#include <linux/rtnetlink.h>
+#include "ethernet.h"
+#include <linux/if_arp.h>
+#include <linux/firmware.h>
+#define _usb_alloc_urb(x, y) usb_alloc_urb(x, y)
+#define _usb_submit_urb(x, y) usb_submit_urb(x, y)
+
+struct __queue {
+ struct list_head queue;
+ spinlock_t lock;
+};
+
+#define _pkt struct sk_buff
+#define _buffer unsigned char
+#define thread_exit() complete_and_exit(NULL, 0)
+#define _workitem struct work_struct
+#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
+
+#define _init_queue(pqueue) \
+ do { \
+ _init_listhead(&((pqueue)->queue)); \
+ spin_lock_init(&((pqueue)->lock)); \
+ } while (0)
+
+static inline void *_netdev_priv(struct net_device *dev)
+{
+ return netdev_priv(dev);
+}
+
+static inline void os_free_netdev(struct net_device *dev)
+{
+ free_netdev(dev);
+}
+
+static inline struct list_head *get_next(struct list_head *list)
+{
+ return list->next;
+}
+
+static inline struct list_head *get_list_head(struct __queue *queue)
+{
+ return &(queue->queue);
+}
+
+#define LIST_CONTAINOR(ptr, type, member) \
+ ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
+
+static inline void _enter_hwio_critical(struct semaphore *prwlock,
+ unsigned long *pirqL)
+{
+ down(prwlock);
+}
+
+static inline void _exit_hwio_critical(struct semaphore *prwlock,
+ unsigned long *pirqL)
+{
+ up(prwlock);
+}
+
+static inline void list_delete(struct list_head *plist)
+{
+ list_del_init(plist);
+}
+
+static inline void _init_timer(struct timer_list *ptimer,
+ struct net_device *padapter,
+ void *pfunc, void *cntx)
+{
+ ptimer->function = pfunc;
+ ptimer->data = (addr_t)cntx;
+ init_timer(ptimer);
+}
+
+static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
+{
+ mod_timer(ptimer, (jiffies+(delay_time*HZ/1000)));
+}
+
+static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled)
+{
+ del_timer(ptimer);
+ *bcancelled = true; /*true ==1; false==0*/
+}
+
+static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx)
+{
+ INIT_WORK(pwork, pfunc);
+}
+
+static inline void _set_workitem(_workitem *pwork)
+{
+ schedule_work(pwork);
+}
+
+#include "rtl871x_byteorder.h"
+
+#ifndef BIT
+ #define BIT(x) (1 << (x))
+#endif
+
+/*
+For the following list_xxx operations,
+caller must guarantee the atomic context.
+Otherwise, there will be racing condition.
+*/
+static inline u32 is_list_empty(struct list_head *phead)
+{
+ if (list_empty(phead))
+ return true;
+ else
+ return false;
+}
+
+static inline void list_insert_tail(struct list_head *plist, struct list_head *phead)
+{
+ list_add_tail(plist, phead);
+}
+
+static inline u32 _down_sema(struct semaphore *sema)
+{
+ if (down_interruptible(sema))
+ return _FAIL;
+ else
+ return _SUCCESS;
+}
+
+static inline void _rtl_rwlock_init(struct semaphore *prwlock)
+{
+ init_MUTEX(prwlock);
+}
+
+static inline void _init_listhead(struct list_head *list)
+{
+ INIT_LIST_HEAD(list);
+}
+
+static inline u32 _queue_empty(struct __queue *pqueue)
+{
+ return is_list_empty(&(pqueue->queue));
+}
+
+static inline u32 end_of_queue_search(struct list_head *head, struct list_head *plist)
+{
+ if (head == plist)
+ return true;
+ else
+ return false;
+}
+
+static inline void sleep_schedulable(int ms)
+{
+ u32 delta;
+
+ delta = (ms * HZ) / 1000;/*(ms)*/
+ if (delta == 0)
+ delta = 1;/* 1 ms */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(delta) != 0)
+ return ;
+}
+
+static inline u8 *_malloc(u32 sz)
+{
+ u8 *pbuf;
+
+ pbuf = kmalloc(sz, GFP_ATOMIC);
+ return pbuf;
+}
+
+static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
+{
+ return del_timer(ptimer);
+}
+
+static inline void thread_enter(void *context)
+{
+ daemonize("%s", "RTKTHREAD");
+ allow_signal(SIGTERM);
+}
+
+static inline void flush_signals_thread(void)
+{
+ if (signal_pending(current))
+ flush_signals(current);
+}
+
+static inline u32 _RND8(u32 sz)
+{
+ u32 val;
+
+ val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3;
+ return val;
+}
+
+static inline u32 _RND128(u32 sz)
+{
+ u32 val;
+
+ val = ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7;
+ return val;
+}
+
+static inline u32 _RND256(u32 sz)
+{
+ u32 val;
+
+ val = ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8;
+ return val;
+}
+
+static inline u32 _RND512(u32 sz)
+{
+ u32 val;
+
+ val = ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9;
+ return val;
+}
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+#define STRUCT_PACKED __attribute__ ((packed))
+
+#endif
+
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c
new file mode 100644
index 000000000000..1f0949ed7ee0
--- /dev/null
+++ b/drivers/staging/rtl8712/recv_linux.c
@@ -0,0 +1,169 @@
+/******************************************************************************
+ * recv_linux.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RECV_OSDEP_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wifi.h"
+#include "recv_osdep.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+/*init os related resource in struct recv_priv*/
+/*alloc os related resource in union recv_frame*/
+int r8712_os_recv_resource_alloc(struct _adapter *padapter,
+ union recv_frame *precvframe)
+{
+ precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL;
+ return _SUCCESS;
+}
+
+/*alloc os related resource in struct recv_buf*/
+int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
+ struct recv_buf *precvbuf)
+{
+ int res = _SUCCESS;
+
+ precvbuf->irp_pending = false;
+ precvbuf->purb = _usb_alloc_urb(0, GFP_KERNEL);
+ if (precvbuf->purb == NULL)
+ res = _FAIL;
+ precvbuf->pskb = NULL;
+ precvbuf->reuse = false;
+ precvbuf->pallocated_buf = NULL;
+ precvbuf->pbuf = NULL;
+ precvbuf->pdata = NULL;
+ precvbuf->phead = NULL;
+ precvbuf->ptail = NULL;
+ precvbuf->pend = NULL;
+ precvbuf->transfer_len = 0;
+ precvbuf->len = 0;
+ return res;
+}
+
+/*free os related resource in struct recv_buf*/
+int r8712_os_recvbuf_resource_free(struct _adapter *padapter,
+ struct recv_buf *precvbuf)
+{
+ if (precvbuf->pskb)
+ dev_kfree_skb_any(precvbuf->pskb);
+ if (precvbuf->purb) {
+ usb_kill_urb(precvbuf->purb);
+ usb_free_urb(precvbuf->purb);
+ }
+ return _SUCCESS;
+}
+
+void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup)
+{
+ union iwreq_data wrqu;
+ struct iw_michaelmicfailure ev;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ memset(&ev, 0x00, sizeof(ev));
+ if (bgroup)
+ ev.flags |= IW_MICFAILURE_GROUP;
+ else
+ ev.flags |= IW_MICFAILURE_PAIRWISE;
+ ev.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
+ memset(&wrqu, 0x00, sizeof(wrqu));
+ wrqu.data.length = sizeof(ev);
+ wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu,
+ (char *)&ev);
+}
+
+void r8712_recv_indicatepkt(struct _adapter *padapter,
+ union recv_frame *precv_frame)
+{
+ struct recv_priv *precvpriv;
+ struct __queue *pfree_recv_queue;
+ _pkt *skb;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+
+ precvpriv = &(padapter->recvpriv);
+ pfree_recv_queue = &(precvpriv->free_recv_queue);
+ skb = precv_frame->u.hdr.pkt;
+ if (skb == NULL)
+ goto _recv_indicatepkt_drop;
+ skb->data = precv_frame->u.hdr.rx_data;
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+ skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail -
+ precv_frame->u.hdr.rx_head);
+#else
+ skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail;
+#endif
+ skb->len = precv_frame->u.hdr.len;
+ if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->dev = padapter->pnetdev;
+ skb->protocol = eth_type_trans(skb, padapter->pnetdev);
+ netif_rx(skb);
+ precv_frame->u.hdr.pkt = NULL; /* pointers to NULL before
+ * r8712_free_recvframe() */
+ r8712_free_recvframe(precv_frame, pfree_recv_queue);
+ return;
+_recv_indicatepkt_drop:
+ /*enqueue back to free_recv_queue*/
+ if (precv_frame)
+ r8712_free_recvframe(precv_frame, pfree_recv_queue);
+ precvpriv->rx_drop++;
+}
+
+void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf)
+{
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ precvbuf->ref_cnt--;
+ /*free skb in recv_buf*/
+ dev_kfree_skb_any(precvbuf->pskb);
+ precvbuf->pskb = NULL;
+ precvbuf->reuse = false;
+ if (precvbuf->irp_pending == false)
+ r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
+ (unsigned char *)precvbuf);
+}
+
+static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext)
+{
+ struct recv_reorder_ctrl *preorder_ctrl =
+ (struct recv_reorder_ctrl *)FunctionContext;
+
+ r8712_reordering_ctrl_timeout_handler(preorder_ctrl);
+}
+
+void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
+{
+ struct _adapter *padapter = preorder_ctrl->padapter;
+
+ _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev,
+ _r8712_reordering_ctrl_timeout_handler, preorder_ctrl);
+}
diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h
new file mode 100644
index 000000000000..b23dd6b159f4
--- /dev/null
+++ b/drivers/staging/rtl8712/recv_osdep.h
@@ -0,0 +1,27 @@
+#ifndef __RECV_OSDEP_H_
+#define __RECV_OSDEP_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include <linux/skbuff.h>
+
+sint _r8712_init_recv_priv(struct recv_priv *precvpriv,
+ struct _adapter *padapter);
+void _r8712_free_recv_priv(struct recv_priv *precvpriv);
+s32 r8712_recv_entry(union recv_frame *precv_frame);
+void r8712_recv_indicatepkt(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup);
+int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter);
+void r8712_free_recv_priv(struct recv_priv *precvpriv);
+int r8712_os_recv_resource_alloc(struct _adapter *padapter,
+ union recv_frame *precvframe);
+int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
+ struct recv_buf *precvbuf);
+int r8712_os_recvbuf_resource_free(struct _adapter *padapter,
+ struct recv_buf *precvbuf);
+void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf);
+void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl8712_bitdef.h b/drivers/staging/rtl8712/rtl8712_bitdef.h
new file mode 100644
index 000000000000..356184fa0606
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_bitdef.h
@@ -0,0 +1,19 @@
+#ifndef __RTL8712_BITDEF_H__
+#define __RTL8712_BITDEF_H__
+
+#include "rtl8712_cmdctrl_bitdef.h"
+#include "rtl8712_syscfg_bitdef.h"
+#include "rtl8712_macsetting_bitdef.h"
+#include "rtl8712_timectrl_bitdef.h"
+#include "rtl8712_fifoctrl_bitdef.h"
+#include "rtl8712_ratectrl_bitdef.h"
+#include "rtl8712_edcasetting_bitdef.h"
+#include "rtl8712_wmac_bitdef.h"
+#include "rtl8712_security_bitdef.h"
+#include "rtl8712_powersave_bitdef.h"
+#include "rtl8712_gp_bitdef.h"
+#include "rtl8712_interrupt_bitdef.h"
+#include "rtl8712_debugctrl_bitdef.h"
+
+#endif /* __RTL8712_BITDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c
new file mode 100644
index 000000000000..26c605e8cd6f
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -0,0 +1,465 @@
+/******************************************************************************
+ * rtl8712_cmd.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL8712_CMD_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "mlme_osdep.h"
+#include "rtl871x_byteorder.h"
+#include "rtl871x_ioctl_set.h"
+
+static void check_hw_pbc(struct _adapter *padapter)
+{
+ u8 tmp1byte;
+
+ r8712_write8(padapter, MAC_PINMUX_CTRL, (GPIOMUX_EN | GPIOSEL_GPIO));
+ tmp1byte = r8712_read8(padapter, GPIO_IO_SEL);
+ tmp1byte &= ~(HAL_8192S_HW_GPIO_WPS_BIT);
+ r8712_write8(padapter, GPIO_IO_SEL, tmp1byte);
+ tmp1byte = r8712_read8(padapter, GPIO_CTRL);
+ if (tmp1byte == 0xff)
+ return ;
+ if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT) {
+ /* Here we only set bPbcPressed to true
+ * After trigger PBC, the variable will be set to false */
+ DBG_8712("CheckPbcGPIO - PBC is pressed !!!!\n");
+ /* 0 is the default value and it means the application monitors
+ * the HW PBC doesn't privde its pid to driver. */
+ if (padapter->pid == 0)
+ return;
+ kill_pid(find_vpid(padapter->pid), SIGUSR1, 1);
+ }
+}
+
+/* query rx phy status from fw.
+ * Adhoc mode: beacon.
+ * Infrastructure mode: beacon , data. */
+static void query_fw_rx_phy_status(struct _adapter *padapter)
+{
+ u32 val32 = 0;
+ int pollingcnts = 50;
+
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == true) {
+ r8712_write32(padapter, IOCMD_CTRL_REG, 0xf4000001);
+ msleep(100);
+ /* Wait FW complete IO Cmd */
+ while ((r8712_read32(padapter, IOCMD_CTRL_REG)) &&
+ (pollingcnts > 0)) {
+ pollingcnts--;
+ msleep(20);
+ }
+ if (pollingcnts != 0)
+ val32 = r8712_read32(padapter, IOCMD_DATA_REG);
+ else /* time out */
+ val32 = 0;
+ val32 = val32 >> 4;
+ padapter->recvpriv.fw_rssi =
+ (u8)r8712_signal_scale_mapping(val32);
+ }
+}
+
+/* check mlme, hw, phy, or dynamic algorithm status. */
+static void StatusWatchdogCallback(struct _adapter *padapter)
+{
+ check_hw_pbc(padapter);
+ query_fw_rx_phy_status(padapter);
+}
+
+static void r871x_internal_cmd_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ struct drvint_cmd_parm *pdrvcmd;
+
+ if (!pbuf)
+ return;
+ pdrvcmd = (struct drvint_cmd_parm *)pbuf;
+ switch (pdrvcmd->i_cid) {
+ case WDG_WK_CID:
+ StatusWatchdogCallback(padapter);
+ break;
+ default:
+ break;
+ }
+ kfree(pdrvcmd->pbuf);
+}
+
+static u8 read_macreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ /* invoke cmd->callback function */
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 write_macreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ /* invoke cmd->callback function */
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ u32 val;
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct readBB_parm *prdbbparm;
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ prdbbparm = (struct readBB_parm *)pcmd->parmbuf;
+ if (pcmd->rsp && pcmd->rspsz > 0)
+ memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz);
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct writeBB_parm *pwritebbparm;
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ pwritebbparm = (struct writeBB_parm *)pcmd->parmbuf;
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ u32 val;
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct readRF_parm *prdrfparm;
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ prdrfparm = (struct readRF_parm *)pcmd->parmbuf;
+ if (pcmd->rsp && pcmd->rspsz > 0)
+ memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz);
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct writeRF_parm *pwriterfparm;
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+
+ pwriterfparm = (struct writeRF_parm *)pcmd->parmbuf;
+ pcmd_callback = cmd_callback[pcmd->cmdcode].callback;
+ if (pcmd_callback == NULL)
+ r8712_free_cmd_obj(pcmd);
+ else
+ pcmd_callback(padapter, pcmd);
+ return H2C_SUCCESS;
+}
+
+static u8 sys_suspend_hdl(struct _adapter *padapter, u8 *pbuf)
+{
+ struct cmd_obj *pcmd = (struct cmd_obj *)pbuf;
+ struct usb_suspend_parm *psetusbsuspend;
+
+ psetusbsuspend = (struct usb_suspend_parm *)pcmd->parmbuf;
+ r8712_free_cmd_obj(pcmd);
+ return H2C_SUCCESS;
+}
+
+static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ struct cmd_obj *pcmd_r;
+
+ if (pcmd == NULL)
+ return pcmd;
+ pcmd_r = NULL;
+
+ switch (pcmd->cmdcode) {
+ case GEN_CMD_CODE(_Read_MACREG):
+ read_macreg_hdl(padapter, (u8 *)pcmd);
+ pcmd_r = pcmd;
+ break;
+ case GEN_CMD_CODE(_Write_MACREG):
+ write_macreg_hdl(padapter, (u8 *)pcmd);
+ pcmd_r = pcmd;
+ break;
+ case GEN_CMD_CODE(_Read_BBREG):
+ read_bbreg_hdl(padapter, (u8 *)pcmd);
+ break;
+ case GEN_CMD_CODE(_Write_BBREG):
+ write_bbreg_hdl(padapter, (u8 *)pcmd);
+ break;
+ case GEN_CMD_CODE(_Read_RFREG):
+ read_rfreg_hdl(padapter, (u8 *)pcmd);
+ break;
+ case GEN_CMD_CODE(_Write_RFREG):
+ write_rfreg_hdl(padapter, (u8 *)pcmd);
+ break;
+ case GEN_CMD_CODE(_SetUsbSuspend):
+ sys_suspend_hdl(padapter, (u8 *)pcmd);
+ break;
+ case GEN_CMD_CODE(_JoinBss):
+ r8712_joinbss_reset(padapter);
+ /* Before set JoinBss_CMD to FW, driver must ensure FW is in
+ * PS_MODE_ACTIVE. Directly write rpwm to radio on and assign
+ * new pwr_mode to Driver, instead of use workitem to change
+ * state. */
+ if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) {
+ padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE;
+ _enter_pwrlock(&(padapter->pwrctrlpriv.lock));
+ r8712_set_rpwm(padapter, PS_STATE_S4);
+ up(&(padapter->pwrctrlpriv.lock));
+ }
+ pcmd_r = pcmd;
+ break;
+ case _DRV_INT_CMD_:
+ r871x_internal_cmd_hdl(padapter, pcmd->parmbuf);
+ r8712_free_cmd_obj(pcmd);
+ pcmd_r = NULL;
+ break;
+ default:
+ pcmd_r = pcmd;
+ break;
+ }
+ return pcmd_r; /* if returning pcmd_r == NULL, pcmd must be free. */
+}
+
+static u8 check_cmd_fifo(struct _adapter *padapter, uint sz)
+{
+ u8 res = _SUCCESS;
+ return res;
+}
+
+u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd)
+{
+ int pollingcnts = 50;
+
+ r8712_write32(pAdapter, IOCMD_CTRL_REG, cmd);
+ msleep(100);
+ while ((0 != r8712_read32(pAdapter, IOCMD_CTRL_REG)) &&
+ (pollingcnts > 0)) {
+ pollingcnts--;
+ msleep(20);
+ }
+ if (pollingcnts == 0)
+ return false;
+ return true;
+}
+
+void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag)
+{
+ if (flag == 0) /* set */
+ r8712_write32(pAdapter, IOCMD_DATA_REG, *value);
+ else /* query */
+ *value = r8712_read32(pAdapter, IOCMD_DATA_REG);
+}
+
+int r8712_cmd_thread(void *context)
+{
+ struct cmd_obj *pcmd;
+ unsigned int cmdsz, wr_sz, *pcmdbuf, *prspbuf;
+ struct tx_desc *pdesc;
+ void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
+ struct _adapter *padapter = (struct _adapter *)context;
+ struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
+
+ thread_enter(padapter);
+ while (1) {
+ if ((_down_sema(&(pcmdpriv->cmd_queue_sema))) == _FAIL)
+ break;
+ if ((padapter->bDriverStopped == true) ||
+ (padapter->bSurpriseRemoved == true))
+ break;
+ if (r8712_register_cmd_alive(padapter) != _SUCCESS)
+ continue;
+_next:
+ pcmd = r8712_dequeue_cmd(&(pcmdpriv->cmd_queue));
+ if (!(pcmd)) {
+ r8712_unregister_cmd_alive(padapter);
+ continue;
+ }
+ pcmdbuf = (unsigned int *)pcmdpriv->cmd_buf;
+ prspbuf = (unsigned int *)pcmdpriv->rsp_buf;
+ pdesc = (struct tx_desc *)pcmdbuf;
+ memset(pdesc, 0, TXDESC_SIZE);
+ pcmd = cmd_hdl_filter(padapter, pcmd);
+ if (pcmd) { /* if pcmd != NULL, cmd will be handled by f/w */
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)
+ &padapter->dvobjpriv;
+ u8 blnPending = 0;
+ pcmdpriv->cmd_issued_cnt++;
+ cmdsz = _RND8((pcmd->cmdsz)); /* _RND8 */
+ wr_sz = TXDESC_SIZE + 8 + cmdsz;
+ pdesc->txdw0 |= cpu_to_le32((wr_sz-TXDESC_SIZE) &
+ 0x0000ffff);
+ if (pdvobj->ishighspeed) {
+ if ((wr_sz % 512) == 0)
+ blnPending = 1;
+ } else {
+ if ((wr_sz % 64) == 0)
+ blnPending = 1;
+ }
+ if (blnPending) /* 32 bytes for TX Desc - 8 offset */
+ pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE +
+ OFFSET_SZ + 8) << OFFSET_SHT) &
+ 0x00ff0000);
+ else {
+ pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE +
+ OFFSET_SZ) <<
+ OFFSET_SHT) &
+ 0x00ff0000);
+ }
+ pdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
+ pdesc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) &
+ 0x00001f00);
+ pcmdbuf += (TXDESC_SIZE >> 2);
+ *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) |
+ (pcmd->cmdcode << 16) |
+ (pcmdpriv->cmd_seq << 24));
+ pcmdbuf += 2 ; /* 8 bytes aligment */
+ memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
+ while (check_cmd_fifo(padapter, wr_sz) == _FAIL) {
+ if ((padapter->bDriverStopped == true) ||
+ (padapter->bSurpriseRemoved == true))
+ break;
+ msleep(100);
+ continue;
+ }
+ if (blnPending)
+ wr_sz += 8; /* Append 8 bytes */
+ r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz,
+ (u8 *)pdesc);
+ pcmdpriv->cmd_seq++;
+ if (pcmd->cmdcode == GEN_CMD_CODE(_CreateBss)) {
+ pcmd->res = H2C_SUCCESS;
+ pcmd_callback = cmd_callback[pcmd->
+ cmdcode].callback;
+ if (pcmd_callback)
+ pcmd_callback(padapter, pcmd);
+ continue;
+ }
+ if (pcmd->cmdcode == GEN_CMD_CODE(_SetPwrMode)) {
+ if (padapter->pwrctrlpriv.bSleep) {
+ _enter_pwrlock(&(padapter->
+ pwrctrlpriv.lock));
+ r8712_set_rpwm(padapter, PS_STATE_S2);
+ up(&padapter->pwrctrlpriv.lock);
+ }
+ }
+ r8712_free_cmd_obj(pcmd);
+ if (_queue_empty(&(pcmdpriv->cmd_queue))) {
+ r8712_unregister_cmd_alive(padapter);
+ continue;
+ } else
+ goto _next;
+ } else
+ goto _next;
+ flush_signals_thread();
+ }
+ /* free all cmd_obj resources */
+ do {
+ pcmd = r8712_dequeue_cmd(&(pcmdpriv->cmd_queue));
+ if (pcmd == NULL)
+ break;
+ r8712_free_cmd_obj(pcmd);
+ } while (1);
+ up(&pcmdpriv->terminate_cmdthread_sema);
+ thread_exit();
+}
+
+void r8712_event_handle(struct _adapter *padapter, uint *peventbuf)
+{
+ u8 evt_code, evt_seq;
+ u16 evt_sz;
+ void (*event_callback)(struct _adapter *dev, u8 *pbuf);
+ struct evt_priv *pevt_priv = &(padapter->evtpriv);
+
+ if (peventbuf == NULL)
+ goto _abort_event_;
+ evt_sz = (u16)(le32_to_cpu(*peventbuf) & 0xffff);
+ evt_seq = (u8)((le32_to_cpu(*peventbuf) >> 24) & 0x7f);
+ evt_code = (u8)((le32_to_cpu(*peventbuf) >> 16) & 0xff);
+ /* checking event sequence... */
+ if ((evt_seq & 0x7f) != pevt_priv->event_seq) {
+ pevt_priv->event_seq = ((evt_seq + 1) & 0x7f);
+ goto _abort_event_;
+ }
+ /* checking if event code is valid */
+ if (evt_code >= MAX_C2HEVT) {
+ pevt_priv->event_seq = ((evt_seq+1) & 0x7f);
+ goto _abort_event_;
+ } else if ((evt_code == GEN_EVT_CODE(_Survey)) &&
+ (evt_sz > sizeof(struct wlan_bssid_ex))) {
+ pevt_priv->event_seq = ((evt_seq+1)&0x7f);
+ goto _abort_event_;
+ }
+ /* checking if event size match the event parm size */
+ if ((wlanevents[evt_code].parmsize) &&
+ (wlanevents[evt_code].parmsize != evt_sz)) {
+ pevt_priv->event_seq = ((evt_seq+1)&0x7f);
+ goto _abort_event_;
+ } else if ((evt_sz == 0) && (evt_code != GEN_EVT_CODE(_WPS_PBC))) {
+ pevt_priv->event_seq = ((evt_seq+1)&0x7f);
+ goto _abort_event_;
+ }
+ pevt_priv->event_seq++; /* update evt_seq */
+ if (pevt_priv->event_seq > 127)
+ pevt_priv->event_seq = 0;
+ peventbuf = peventbuf + 2; /* move to event content, 8 bytes aligment */
+ if (peventbuf) {
+ event_callback = wlanevents[evt_code].event_callback;
+ if (event_callback)
+ event_callback(padapter, (u8 *)peventbuf);
+ }
+ pevt_priv->evt_done_cnt++;
+_abort_event_:
+ return;
+}
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h
new file mode 100644
index 000000000000..13ef0626b280
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_cmd.h
@@ -0,0 +1,157 @@
+#ifndef __RTL8712_CMD_H_
+#define __RTL8712_CMD_H_
+
+u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd);
+void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag);
+
+
+enum rtl8712_h2c_cmd {
+ GEN_CMD_CODE(_Read_MACREG), /*0*/
+ GEN_CMD_CODE(_Write_MACREG),
+ GEN_CMD_CODE(_Read_BBREG),
+ GEN_CMD_CODE(_Write_BBREG),
+ GEN_CMD_CODE(_Read_RFREG),
+ GEN_CMD_CODE(_Write_RFREG), /*5*/
+ GEN_CMD_CODE(_Read_EEPROM),
+ GEN_CMD_CODE(_Write_EEPROM),
+ GEN_CMD_CODE(_Read_EFUSE),
+ GEN_CMD_CODE(_Write_EFUSE),
+
+ GEN_CMD_CODE(_Read_CAM), /*10*/
+ GEN_CMD_CODE(_Write_CAM),
+ GEN_CMD_CODE(_setBCNITV),
+ GEN_CMD_CODE(_setMBIDCFG),
+ GEN_CMD_CODE(_JoinBss), /*14*/
+ GEN_CMD_CODE(_DisConnect), /*15*/
+ GEN_CMD_CODE(_CreateBss),
+ GEN_CMD_CODE(_SetOpMode),
+ GEN_CMD_CODE(_SiteSurvey), /*18*/
+ GEN_CMD_CODE(_SetAuth),
+
+ GEN_CMD_CODE(_SetKey), /*20*/
+ GEN_CMD_CODE(_SetStaKey),
+ GEN_CMD_CODE(_SetAssocSta),
+ GEN_CMD_CODE(_DelAssocSta),
+ GEN_CMD_CODE(_SetStaPwrState),
+ GEN_CMD_CODE(_SetBasicRate), /*25*/
+ GEN_CMD_CODE(_GetBasicRate),
+ GEN_CMD_CODE(_SetDataRate),
+ GEN_CMD_CODE(_GetDataRate),
+ GEN_CMD_CODE(_SetPhyInfo),
+
+ GEN_CMD_CODE(_GetPhyInfo), /*30*/
+ GEN_CMD_CODE(_SetPhy),
+ GEN_CMD_CODE(_GetPhy),
+ GEN_CMD_CODE(_readRssi),
+ GEN_CMD_CODE(_readGain),
+ GEN_CMD_CODE(_SetAtim), /*35*/
+ GEN_CMD_CODE(_SetPwrMode),
+ GEN_CMD_CODE(_JoinbssRpt),
+ GEN_CMD_CODE(_SetRaTable),
+ GEN_CMD_CODE(_GetRaTable),
+
+ GEN_CMD_CODE(_GetCCXReport), /*40*/
+ GEN_CMD_CODE(_GetDTMReport),
+ GEN_CMD_CODE(_GetTXRateStatistics),
+ GEN_CMD_CODE(_SetUsbSuspend),
+ GEN_CMD_CODE(_SetH2cLbk),
+ GEN_CMD_CODE(_AddBAReq), /*45*/
+
+ GEN_CMD_CODE(_SetChannel), /*46*/
+/* MP_OFFLOAD Start (47~54)*/
+ GEN_CMD_CODE(_SetTxPower),
+ GEN_CMD_CODE(_SwitchAntenna),
+ GEN_CMD_CODE(_SetCrystalCap),
+ GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/
+ GEN_CMD_CODE(_SetSingleToneTx),
+ GEN_CMD_CODE(_SetCarrierSuppressionTx),
+ GEN_CMD_CODE(_SetContinuousTx),
+ GEN_CMD_CODE(_SwitchBandwidth), /*54*/
+/* MP_OFFLOAD End*/
+ GEN_CMD_CODE(_TX_Beacon), /*55*/
+ GEN_CMD_CODE(_SetPowerTracking),
+ GEN_CMD_CODE(_AMSDU_TO_AMPDU), /*57*/
+ GEN_CMD_CODE(_SetMacAddress), /*58*/
+ MAX_H2CCMD
+};
+
+
+#define _GetBBReg_CMD_ _Read_BBREG_CMD_
+#define _SetBBReg_CMD_ _Write_BBREG_CMD_
+#define _GetRFReg_CMD_ _Read_RFREG_CMD_
+#define _SetRFReg_CMD_ _Write_RFREG_CMD_
+#define _DRV_INT_CMD_ (MAX_H2CCMD+1)
+#define _SetRFIntFs_CMD_ (MAX_H2CCMD+2)
+
+#ifdef _RTL8712_CMD_C_
+static struct _cmd_callback cmd_callback[] = {
+ {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
+ {GEN_CMD_CODE(_Write_MACREG), NULL},
+ {GEN_CMD_CODE(_Read_BBREG), &r8712_getbbrfreg_cmdrsp_callback},
+ {GEN_CMD_CODE(_Write_BBREG), NULL},
+ {GEN_CMD_CODE(_Read_RFREG), &r8712_getbbrfreg_cmdrsp_callback},
+ {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
+ {GEN_CMD_CODE(_Read_EEPROM), NULL},
+ {GEN_CMD_CODE(_Write_EEPROM), NULL},
+ {GEN_CMD_CODE(_Read_EFUSE), NULL},
+ {GEN_CMD_CODE(_Write_EFUSE), NULL},
+
+ {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/
+ {GEN_CMD_CODE(_Write_CAM), NULL},
+ {GEN_CMD_CODE(_setBCNITV), NULL},
+ {GEN_CMD_CODE(_setMBIDCFG), NULL},
+ {GEN_CMD_CODE(_JoinBss), &r8712_joinbss_cmd_callback}, /*14*/
+ {GEN_CMD_CODE(_DisConnect), &r8712_disassoc_cmd_callback}, /*15*/
+ {GEN_CMD_CODE(_CreateBss), &r8712_createbss_cmd_callback},
+ {GEN_CMD_CODE(_SetOpMode), NULL},
+ {GEN_CMD_CODE(_SiteSurvey), &r8712_survey_cmd_callback}, /*18*/
+ {GEN_CMD_CODE(_SetAuth), NULL},
+
+ {GEN_CMD_CODE(_SetKey), NULL}, /*20*/
+ {GEN_CMD_CODE(_SetStaKey), &r8712_setstaKey_cmdrsp_callback},
+ {GEN_CMD_CODE(_SetAssocSta), &r8712_setassocsta_cmdrsp_callback},
+ {GEN_CMD_CODE(_DelAssocSta), NULL},
+ {GEN_CMD_CODE(_SetStaPwrState), NULL},
+ {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
+ {GEN_CMD_CODE(_GetBasicRate), NULL},
+ {GEN_CMD_CODE(_SetDataRate), NULL},
+ {GEN_CMD_CODE(_GetDataRate), NULL},
+ {GEN_CMD_CODE(_SetPhyInfo), NULL},
+
+ {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
+ {GEN_CMD_CODE(_SetPhy), NULL},
+ {GEN_CMD_CODE(_GetPhy), NULL},
+ {GEN_CMD_CODE(_readRssi), NULL},
+ {GEN_CMD_CODE(_readGain), NULL},
+ {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
+ {GEN_CMD_CODE(_SetPwrMode), NULL},
+ {GEN_CMD_CODE(_JoinbssRpt), NULL},
+ {GEN_CMD_CODE(_SetRaTable), NULL},
+ {GEN_CMD_CODE(_GetRaTable), NULL},
+
+ {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
+ {GEN_CMD_CODE(_GetDTMReport), NULL},
+ {GEN_CMD_CODE(_GetTXRateStatistics), NULL},
+ {GEN_CMD_CODE(_SetUsbSuspend), NULL},
+ {GEN_CMD_CODE(_SetH2cLbk), NULL},
+ {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
+
+ {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/
+/* MP_OFFLOAD Start (47~54)*/
+ {GEN_CMD_CODE(_SetTxPower), NULL},
+ {GEN_CMD_CODE(_SwitchAntenna), NULL},
+ {GEN_CMD_CODE(_SetCrystalCap), NULL},
+ {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/
+ {GEN_CMD_CODE(_SetSingleToneTx), NULL},
+ {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
+ {GEN_CMD_CODE(_SetContinuousTx), NULL},
+ {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/
+/* MP_OFFLOAD End*/
+ {GEN_CMD_CODE(_TX_Beacon), NULL}, /*55*/
+ {GEN_CMD_CODE(_SetPowerTracking), NULL},
+ {GEN_CMD_CODE(_AMSDU_TO_AMPDU), NULL}, /*57*/
+ {GEN_CMD_CODE(_SetMacAddress), NULL}, /*58*/
+};
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h
new file mode 100644
index 000000000000..6c49903a42f2
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h
@@ -0,0 +1,89 @@
+#ifndef __RTL8712_CMDCTRL_BITDEF_H__
+#define __RTL8712_CMDCTRL_BITDEF_H__
+
+/*
+ * 2. Command Control Registers (Offset: 0x0040 - 0x004F)*/
+/*--------------------------------------------------------------------------*/
+/* 8192S (CMD) command register bits (Offset 0x40, 16 bits)*/
+/*--------------------------------------------------------------------------*/
+#define _APSDOFF_STATUS BIT(15)
+#define _APSDOFF BIT(14)
+#define _BBRSTn BIT(13) /*Enable OFDM/CCK*/
+#define _BB_GLB_RSTn BIT(12) /*Enable BB*/
+#define _SCHEDULE_EN BIT(10) /*Enable MAC scheduler*/
+#define _MACRXEN BIT(9)
+#define _MACTXEN BIT(8)
+#define _DDMA_EN BIT(7) /*FW off load function enable*/
+#define _FW2HW_EN BIT(6) /*MAC every module reset */
+#define _RXDMA_EN BIT(5)
+#define _TXDMA_EN BIT(4)
+#define _HCI_RXDMA_EN BIT(3)
+#define _HCI_TXDMA_EN BIT(2)
+
+/*TXPAUSE*/
+#define _STOPHCCA BIT(6)
+#define _STOPHIGH BIT(5)
+#define _STOPMGT BIT(4)
+#define _STOPVO BIT(3)
+#define _STOPVI BIT(2)
+#define _STOPBE BIT(1)
+#define _STOPBK BIT(0)
+
+/*TCR*/
+#define _DISCW BIT(20)
+#define _ICV BIT(19)
+#define _CFEND_FMT BIT(17)
+#define _CRC BIT(16)
+#define _FWRDY BIT(7)
+#define _BASECHG BIT(6)
+#define _IMEM_RDY BIT(5)
+#define _DMEM_CODE_DONE BIT(4)
+#define _EMEM_CHK_RPT BIT(3)
+#define _EMEM_CODE_DONE BIT(2)
+#define _IMEM_CHK_RPT BIT(1)
+#define _IMEM_CODE_DONE BIT(0)
+
+#define _TXDMA_INIT_VALUE (_IMEM_CHK_RPT|_EMEM_CHK_RPT)
+
+/*RCR*/
+#define _ENMBID BIT(27)
+#define _APP_PHYST_RXFF BIT(25)
+#define _APP_PHYST_STAFF BIT(24)
+#define _CBSSID BIT(23)
+#define _APWRMGT BIT(22)
+#define _ADD3 BIT(21)
+#define _AMF BIT(20)
+#define _ACF BIT(19)
+#define _ADF BIT(18)
+#define _APP_MIC BIT(17)
+#define _APP_ICV BIT(16)
+#define _RXFTH_MSK 0x0000E000
+#define _RXFTH_SHT 13
+#define _AICV BIT(12)
+#define _RXPKTLMT_MSK 0x00000FC0
+#define _RXPKTLMT_SHT 6
+#define _ACRC32 BIT(5)
+#define _AB BIT(3)
+#define _AM BIT(2)
+#define _APM BIT(1)
+#define _AAP BIT(0)
+
+/*MSR*/
+#define _NETTYPE_MSK 0x03
+#define _NETTYPE_SHT 0
+
+/*BT*/
+#define _BTMODE_MSK 0x06
+#define _BTMODE_SHT 1
+#define _ENBT BIT(0)
+
+/*MBIDCTRL*/
+#define _ENMBID_MODE BIT(15)
+#define _BCNNO_MSK 0x7000
+#define _BCNNO_SHT 12
+#define _BCNSPACE_MSK 0x0FFF
+#define _BCNSPACE_SHT 0
+
+
+#endif /* __RTL8712_CMDCTRL_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h
new file mode 100644
index 000000000000..5d9a3f20ea6e
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h
@@ -0,0 +1,15 @@
+#ifndef __RTL8712_CMDCTRL_REGDEF_H__
+#define __RTL8712_CMDCTRL_REGDEF_H__
+
+
+#define CR (RTL8712_CMDCTRL_ + 0x0000)
+#define TXPAUSE (RTL8712_CMDCTRL_ + 0x0002)
+#define TCR (RTL8712_CMDCTRL_ + 0x0004)
+#define RCR (RTL8712_CMDCTRL_ + 0x0008)
+#define MSR (RTL8712_CMDCTRL_ + 0x000C)
+#define SYSF_CFG (RTL8712_CMDCTRL_ + 0x000D)
+#define MBIDCTRL (RTL8712_CMDCTRL_ + 0x000E)
+
+
+#endif /* __RTL8712_CMDCTRL_REGDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h
new file mode 100644
index 000000000000..7b34d4025e3e
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h
@@ -0,0 +1,36 @@
+#ifndef __RTL8712_DEBUGCTRL_BITDEF_H__
+#define __RTL8712_DEBUGCTRL_BITDEF_H__
+
+/*BIST*/
+#define _BIST_RST BIT(0)
+
+/*LMS*/
+#define _LMS_MSK 0x03
+
+/*WDG_CTRL*/
+#define _OVSEL_MSK 0x0600
+#define _OVSEL_SHT 9
+#define _WDGCLR BIT(8)
+#define _WDGEN_MSK 0x00FF
+#define _WDGEN_SHT 0
+
+/*INTM*/
+#define _TXTIMER_MSK 0xF000
+#define _TXTIMER_SHT 12
+#define _TXNUM_MSK 0x0F00
+#define _TXNUM_SHT 8
+#define _RXTIMER_MSK 0x00F0
+#define _RXTIMER_SHT 4
+#define _RXNUM_MSK 0x000F
+#define _RXNUM_SHT 0
+
+/*FDLOCKTURN0*/
+/*FDLOCKTURN1*/
+#define _TURN1 BIT(0)
+
+/*FDLOCKFLAG0*/
+/*FDLOCKFLAG1*/
+#define _LOCKFLAG1_MSK 0x03
+
+
+#endif /* __RTL8712_DEBUGCTRL_BITDEF_H__ */
diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h
new file mode 100644
index 000000000000..27cad716868c
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h
@@ -0,0 +1,28 @@
+#ifndef __RTL8712_DEBUGCTRL_REGDEF_H__
+#define __RTL8712_DEBUGCTRL_REGDEF_H__
+
+#define BIST (RTL8712_DEBUGCTRL_ + 0x00)
+#define DBS (RTL8712_DEBUGCTRL_ + 0x04)
+#define LMS (RTL8712_DEBUGCTRL_ + 0x05)
+#define CPUINST (RTL8712_DEBUGCTRL_ + 0x08)
+#define CPUCAUSE (RTL8712_DEBUGCTRL_ + 0x0C)
+#define LBUS_ERR_ADDR (RTL8712_DEBUGCTRL_ + 0x10)
+#define LBUS_ERR_CMD (RTL8712_DEBUGCTRL_ + 0x14)
+#define LBUS_ERR_DATA_L (RTL8712_DEBUGCTRL_ + 0x18)
+#define LBUS_ERR_DATA_H (RTL8712_DEBUGCTRL_ + 0x1C)
+#define LBUS_EXCEPTION_ADDR (RTL8712_DEBUGCTRL_ + 0x20)
+#define WDG_CTRL (RTL8712_DEBUGCTRL_ + 0x24)
+#define INTMTU (RTL8712_DEBUGCTRL_ + 0x28)
+#define INTM (RTL8712_DEBUGCTRL_ + 0x2A)
+#define FDLOCKTURN0 (RTL8712_DEBUGCTRL_ + 0x2C)
+#define FDLOCKTURN1 (RTL8712_DEBUGCTRL_ + 0x2D)
+#define FDLOCKFLAG0 (RTL8712_DEBUGCTRL_ + 0x2E)
+#define FDLOCKFLAG1 (RTL8712_DEBUGCTRL_ + 0x2F)
+#define TRXPKTBUF_DBG_DATA (RTL8712_DEBUGCTRL_ + 0x30)
+#define TRXPKTBUF_DBG_CTRL (RTL8712_DEBUGCTRL_ + 0x38)
+#define DPLL_MON (RTL8712_DEBUGCTRL_ + 0x3A)
+
+
+
+#endif /* __RTL8712_DEBUGCTRL_REGDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h
new file mode 100644
index 000000000000..c69b1b72c28c
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h
@@ -0,0 +1,52 @@
+#ifndef __RTL8712_EDCASETTING_BITDEF_H__
+#define __RTL8712_EDCASETTING_BITDEF_H__
+
+/*EDCAPARAM*/
+#define _TXOPLIMIT_MSK 0xFFFF0000
+#define _TXOPLIMIT_SHT 16
+#define _ECWIN_MSK 0x0000FF00
+#define _ECWIN_SHT 8
+#define _AIFS_MSK 0x000000FF
+#define _AIFS_SHT 0
+
+/*BCNTCFG*/
+#define _BCNECW_MSK 0xFF00
+#define _BCNECW_SHT 8
+#define _BCNIFS_MSK 0x00FF
+#define _BCNIFS_SHT 0
+
+/*CWRR*/
+#define _CWRR_MSK 0x03FF
+
+/*ACMAVG*/
+#define _AVG_TIME_UP BIT(3)
+#define _AVGPERIOD_MSK 0x03
+
+/*ACMHWCTRL*/
+#define _VOQ_ACM_STATUS BIT(6)
+#define _VIQ_ACM_STATUS BIT(5)
+#define _BEQ_ACM_STATUS BIT(4)
+#define _VOQ_ACM_EN BIT(3)
+#define _VIQ_ACM_EN BIT(2)
+#define _BEQ_ACM_EN BIT(1)
+#define _ACMHWEN BIT(0)
+
+/*VO_ADMTIME*/
+#define _VO_ACM_RUT BIT(18)
+#define _VO_ADMTIME_MSK 0x0003FFF
+
+/*VI_ADMTIME*/
+#define _VI_ACM_RUT BIT(18)
+#define _VI_ADMTIME_MSK 0x0003FFF
+
+/*BE_ADMTIME*/
+#define _BE_ACM_RUT BIT(18)
+#define _BE_ADMTIME_MSK 0x0003FFF
+
+/*Retry limit reg*/
+#define _SRL_MSK 0xFF00
+#define _SRL_SHT 8
+#define _LRL_MSK 0x00FF
+#define _LRL_SHT 0
+
+#endif /* __RTL8712_EDCASETTING_BITDEF_H__*/
diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h
new file mode 100644
index 000000000000..de3d3e23ba95
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h
@@ -0,0 +1,18 @@
+#ifndef __RTL8712_EDCASETTING_REGDEF_H__
+#define __RTL8712_EDCASETTING_REGDEF_H__
+
+#define EDCA_VO_PARAM (RTL8712_EDCASETTING_ + 0x00)
+#define EDCA_VI_PARAM (RTL8712_EDCASETTING_ + 0x04)
+#define EDCA_BE_PARAM (RTL8712_EDCASETTING_ + 0x08)
+#define EDCA_BK_PARAM (RTL8712_EDCASETTING_ + 0x0C)
+#define BCNTCFG (RTL8712_EDCASETTING_ + 0x10)
+#define CWRR (RTL8712_EDCASETTING_ + 0x12)
+#define ACMAVG (RTL8712_EDCASETTING_ + 0x16)
+#define ACMHWCTRL (RTL8712_EDCASETTING_ + 0x17)
+#define VO_ADMTIME (RTL8712_EDCASETTING_ + 0x18)
+#define VI_ADMTIME (RTL8712_EDCASETTING_ + 0x1C)
+#define BE_ADMTIME (RTL8712_EDCASETTING_ + 0x20)
+#define RL (RTL8712_EDCASETTING_ + 0x24)
+
+#endif /* __RTL8712_EDCASETTING_REGDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c
new file mode 100644
index 000000000000..9730ae1c58d5
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_efuse.c
@@ -0,0 +1,568 @@
+/*
+ * rtl8712_efuse.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL8712_EFUSE_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl8712_efuse.h"
+
+/* reserve 3 bytes for HW stop read */
+static int efuse_available_max_size = EFUSE_MAX_SIZE - 3 /*0x1FD*/;
+
+static void efuse_reg_ctrl(struct _adapter *padapter, u8 bPowerOn)
+{
+ u8 tmpu8 = 0;
+
+ if (true == bPowerOn) {
+ /* -----------------e-fuse pwr & clk reg ctrl ---------------
+ * Enable LDOE25 Macro Block
+ */
+ tmpu8 = r8712_read8(padapter, EFUSE_TEST + 3);
+ tmpu8 |= 0x80;
+ r8712_write8(padapter, EFUSE_TEST + 3, tmpu8);
+ msleep(20); /* for some platform , need some delay time */
+ /* Change Efuse Clock for write action to 40MHZ */
+ r8712_write8(padapter, EFUSE_CLK_CTRL, 0x03);
+ msleep(20); /* for some platform , need some delay time */
+ } else {
+ /* -----------------e-fuse pwr & clk reg ctrl -----------------
+ * Disable LDOE25 Macro Block
+ */
+ tmpu8 = r8712_read8(padapter, EFUSE_TEST + 3);
+ tmpu8 &= 0x7F;
+ r8712_write8(padapter, EFUSE_TEST + 3, tmpu8);
+ /* Change Efuse Clock for write action to 500K */
+ r8712_write8(padapter, EFUSE_CLK_CTRL, 0x02);
+ }
+}
+
+/*
+ * Before write E-Fuse, this function must be called.
+ */
+u8 r8712_efuse_reg_init(struct _adapter *padapter)
+{
+ return true;
+}
+
+void r8712_efuse_reg_uninit(struct _adapter *padapter)
+{
+ efuse_reg_ctrl(padapter, false);
+}
+
+static u8 efuse_one_byte_read(struct _adapter *padapter, u16 addr, u8 *data)
+{
+ u8 tmpidx = 0, bResult;
+
+ /* -----------------e-fuse reg ctrl --------------------------------- */
+ r8712_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xFF)); /* address */
+ r8712_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8)&0x03)) |
+ (r8712_read8(padapter, EFUSE_CTRL+2)&0xFC));
+ r8712_write8(padapter, EFUSE_CTRL+3, 0x72); /* read cmd */
+ /* wait for complete */
+ while (!(0x80 & r8712_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100))
+ tmpidx++;
+ if (tmpidx < 100) {
+ *data = r8712_read8(padapter, EFUSE_CTRL);
+ bResult = true;
+ } else {
+ *data = 0xff;
+ bResult = false;
+ }
+ return bResult;
+}
+
+static u8 efuse_one_byte_write(struct _adapter *padapter, u16 addr, u8 data)
+{
+ u8 tmpidx = 0, bResult;
+
+ /* -----------------e-fuse reg ctrl -------------------------------- */
+ r8712_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xFF)); /* address */
+ r8712_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8)&0x03)) |
+ (r8712_read8(padapter, EFUSE_CTRL+2)&0xFC));
+ r8712_write8(padapter, EFUSE_CTRL, data); /* data */
+ r8712_write8(padapter, EFUSE_CTRL+3, 0xF2); /* write cmd */
+ /* wait for complete */
+ while ((0x80 & r8712_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100))
+ tmpidx++;
+ if (tmpidx < 100)
+ bResult = true;
+ else
+ bResult = false;
+ return bResult;
+}
+
+static u8 efuse_one_byte_rw(struct _adapter *padapter, u8 bRead, u16 addr,
+ u8 *data)
+{
+ u8 tmpidx = 0, tmpv8 = 0, bResult;
+
+ /* -----------------e-fuse reg ctrl --------------------------------- */
+ r8712_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xFF)); /* address */
+ tmpv8 = ((u8)((addr >> 8) & 0x03)) |
+ (r8712_read8(padapter, EFUSE_CTRL + 2) & 0xFC);
+ r8712_write8(padapter, EFUSE_CTRL+2, tmpv8);
+ if (true == bRead) {
+ r8712_write8(padapter, EFUSE_CTRL+3, 0x72); /* read cmd */
+ while (!(0x80 & r8712_read8(padapter, EFUSE_CTRL+3)) &&
+ (tmpidx < 100))
+ tmpidx++;
+ if (tmpidx < 100) {
+ *data = r8712_read8(padapter, EFUSE_CTRL);
+ bResult = true;
+ } else {
+ *data = 0;
+ bResult = false;
+ }
+ } else {
+ r8712_write8(padapter, EFUSE_CTRL, *data); /* data */
+ r8712_write8(padapter, EFUSE_CTRL+3, 0xF2); /* write cmd */
+ while ((0x80 & r8712_read8(padapter, EFUSE_CTRL+3)) &&
+ (tmpidx < 100))
+ tmpidx++;
+ if (tmpidx < 100)
+ bResult = true;
+ else
+ bResult = false;
+ }
+ return bResult;
+}
+
+static u8 efuse_is_empty(struct _adapter *padapter, u8 *empty)
+{
+ u8 value, ret = true;
+
+ /* read one byte to check if E-Fuse is empty */
+ if (efuse_one_byte_rw(padapter, true, 0, &value) == true) {
+ if (0xFF == value)
+ *empty = true;
+ else
+ *empty = false;
+ } else
+ ret = false;
+ return ret;
+}
+
+void r8712_efuse_change_max_size(struct _adapter *padapter)
+{
+ u16 pre_pg_data_saddr = 0x1FB;
+ u16 i;
+ u16 pre_pg_data_size = 5;
+ u8 pre_pg_data[5];
+
+ for (i = 0; i < pre_pg_data_size; i++)
+ efuse_one_byte_read(padapter, pre_pg_data_saddr + i,
+ &pre_pg_data[i]);
+ if ((pre_pg_data[0] == 0x03) && (pre_pg_data[1] == 0x00) &&
+ (pre_pg_data[2] == 0x00) && (pre_pg_data[3] == 0x00) &&
+ (pre_pg_data[4] == 0x0C))
+ efuse_available_max_size -= pre_pg_data_size;
+}
+
+int r8712_efuse_get_max_size(struct _adapter *padapter)
+{
+ return efuse_available_max_size;
+}
+
+static u8 calculate_word_cnts(const u8 word_en)
+{
+ u8 word_cnts = 0;
+ u8 word_idx;
+
+ for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++)
+ if (!(word_en & BIT(word_idx)))
+ word_cnts++; /* 0 : write enable */
+ return word_cnts;
+}
+
+static void pgpacket_copy_data(const u8 word_en, const u8 *sourdata,
+ u8 *targetdata)
+{
+ u8 tmpindex = 0;
+ u8 word_idx, byte_idx;
+
+ for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) {
+ if (!(word_en&BIT(word_idx))) {
+ byte_idx = word_idx * 2;
+ targetdata[byte_idx] = sourdata[tmpindex++];
+ targetdata[byte_idx + 1] = sourdata[tmpindex++];
+ }
+ }
+}
+
+u16 r8712_efuse_get_current_size(struct _adapter *padapter)
+{
+ int bContinual = true;
+ u16 efuse_addr = 0;
+ u8 hoffset = 0, hworden = 0;
+ u8 efuse_data, word_cnts = 0;
+
+ while (bContinual && efuse_one_byte_read(padapter, efuse_addr,
+ &efuse_data) && (efuse_addr < efuse_available_max_size)) {
+ if (efuse_data != 0xFF) {
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = calculate_word_cnts(hworden);
+ /* read next header */
+ efuse_addr = efuse_addr + (word_cnts * 2) + 1;
+ } else
+ bContinual = false ;
+ }
+ return efuse_addr;
+}
+
+u8 r8712_efuse_pg_packet_read(struct _adapter *padapter, u8 offset, u8 *data)
+{
+ u8 hoffset = 0, hworden = 0, word_cnts = 0;
+ u16 efuse_addr = 0;
+ u8 efuse_data;
+ u8 tmpidx = 0;
+ u8 tmpdata[PGPKT_DATA_SIZE];
+ u8 ret = true;
+
+ if (data == NULL)
+ return false;
+ if (offset > 0x0f)
+ return false;
+ memset(data, 0xFF, sizeof(u8)*PGPKT_DATA_SIZE);
+ while (efuse_addr < efuse_available_max_size) {
+ if (efuse_one_byte_read(padapter, efuse_addr, &efuse_data) ==
+ true) {
+ if (efuse_data == 0xFF)
+ break;
+ hoffset = (efuse_data >> 4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ word_cnts = calculate_word_cnts(hworden);
+ if (hoffset == offset) {
+ memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
+ for (tmpidx = 0; tmpidx < word_cnts * 2;
+ tmpidx++) {
+ if (efuse_one_byte_read(padapter,
+ efuse_addr+1+tmpidx, &efuse_data) ==
+ true) {
+ tmpdata[tmpidx] = efuse_data;
+ } else
+ ret = false;
+ }
+ pgpacket_copy_data(hworden, tmpdata, data);
+ }
+ efuse_addr += 1 + (word_cnts*2);
+ } else {
+ ret = false;
+ break;
+ }
+ }
+ return ret;
+}
+
+static u8 fix_header(struct _adapter *padapter, u8 header, u16 header_addr)
+{
+ struct PGPKT_STRUCT pkt;
+ u8 offset, word_en, value;
+ u16 addr;
+ int i;
+ u8 ret = true;
+
+ pkt.offset = GET_EFUSE_OFFSET(header);
+ pkt.word_en = GET_EFUSE_WORD_EN(header);
+ addr = header_addr + 1 + calculate_word_cnts(pkt.word_en) * 2;
+ if (addr > efuse_available_max_size)
+ return false;
+ /* retrieve original data */
+ addr = 0;
+ while (addr < header_addr) {
+ if (efuse_one_byte_read(padapter, addr++, &value) == false) {
+ ret = false;
+ break;
+ }
+ offset = GET_EFUSE_OFFSET(value);
+ word_en = GET_EFUSE_WORD_EN(value);
+ if (pkt.offset != offset) {
+ addr += calculate_word_cnts(word_en)*2;
+ continue;
+ }
+ for (i = 0; i < PGPKG_MAX_WORDS; i++) {
+ if (BIT(i) & word_en)
+ continue;
+ if (!(BIT(i) & pkt.word_en)) {
+ if (efuse_one_byte_read(padapter, addr,
+ &value) == true)
+ pkt.data[i*2] = value;
+ else
+ return false;
+ if (efuse_one_byte_read(padapter, addr + 1,
+ &value) == true)
+ pkt.data[i*2 + 1] = value;
+ else
+ return false;
+ }
+ addr += 2;
+ }
+ }
+ if (addr != header_addr)
+ return false;
+ addr++;
+ /* fill original data */
+ for (i = 0; i < PGPKG_MAX_WORDS; i++) {
+ if (BIT(i) & pkt.word_en)
+ continue;
+ efuse_one_byte_write(padapter, addr, pkt.data[i*2]);
+ efuse_one_byte_write(padapter, addr+1, pkt.data[i*2 + 1]);
+ /* additional check */
+ if (efuse_one_byte_read(padapter, addr, &value) == false)
+ ret = false;
+ else if (pkt.data[i*2] != value) {
+ ret = false;
+ if (0xFF == value) /* write again */
+ efuse_one_byte_write(padapter, addr,
+ pkt.data[i * 2]);
+ }
+ if (efuse_one_byte_read(padapter, addr+1, &value) == false)
+ ret = false;
+ else if (pkt.data[i*2 + 1] != value) {
+ ret = false;
+ if (0xFF == value) /* write again */
+ efuse_one_byte_write(padapter, addr+1,
+ pkt.data[i*2 + 1]);
+ }
+ addr += 2;
+ }
+ return ret;
+}
+
+u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset,
+ const u8 word_en, const u8 *data)
+{
+ u8 pg_header = 0;
+ u16 efuse_addr = 0, curr_size = 0;
+ u8 efuse_data, target_word_cnts = 0;
+ static int repeat_times;
+ int sub_repeat;
+ u8 bResult = true;
+
+ /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */
+ efuse_data = r8712_read8(padapter, EFUSE_CLK_CTRL);
+ if (efuse_data != 0x03)
+ return false;
+ pg_header = MAKE_EFUSE_HEADER(offset, word_en);
+ target_word_cnts = calculate_word_cnts(word_en);
+ repeat_times = 0;
+ efuse_addr = 0;
+ while (efuse_addr < efuse_available_max_size) {
+ curr_size = r8712_efuse_get_current_size(padapter);
+ if ((curr_size + 1 + target_word_cnts * 2) >
+ efuse_available_max_size)
+ return false; /*target_word_cnts + pg header(1 byte)*/
+ efuse_addr = curr_size; /* current size is also the last addr*/
+ efuse_one_byte_write(padapter, efuse_addr, pg_header); /*hdr*/
+ sub_repeat = 0;
+ /* check if what we read is what we write */
+ while (efuse_one_byte_read(padapter, efuse_addr,
+ &efuse_data) == false) {
+ if (++sub_repeat > _REPEAT_THRESHOLD_) {
+ bResult = false; /* continue to blind write */
+ break; /* continue to blind write */
+ }
+ }
+ if ((sub_repeat > _REPEAT_THRESHOLD_) ||
+ (pg_header == efuse_data)) {
+ /* write header ok OR can't check header(creep) */
+ u8 i;
+
+ /* go to next address */
+ efuse_addr++;
+ for (i = 0; i < target_word_cnts*2; i++) {
+ efuse_one_byte_write(padapter,
+ efuse_addr + i,
+ *(data + i));
+ if (efuse_one_byte_read(padapter,
+ efuse_addr + i, &efuse_data) == false)
+ bResult = false;
+ else if (*(data+i) != efuse_data) /* fail */
+ bResult = false;
+ }
+ break;
+ } else { /* write header fail */
+ bResult = false;
+ if (0xFF == efuse_data)
+ return bResult; /* not thing damaged. */
+ /* call rescue procedure */
+ if (fix_header(padapter, efuse_data, efuse_addr) ==
+ false)
+ return false; /* rescue fail */
+
+ if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */
+ break;
+ /* otherwise, take another risk... */
+ }
+ }
+ return bResult;
+}
+
+u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead, u16 start_addr,
+ u16 cnts, u8 *data)
+{
+ int i;
+ u8 res = true;;
+
+ if (start_addr > EFUSE_MAX_SIZE)
+ return false;
+ if ((bRead == false) && ((start_addr + cnts) >
+ efuse_available_max_size))
+ return false;
+ if ((false == bRead) && (r8712_efuse_reg_init(padapter) == false))
+ return false;
+ /* -----------------e-fuse one byte read / write ---------------------*/
+ for (i = 0; i < cnts; i++) {
+ if ((start_addr + i) > EFUSE_MAX_SIZE) {
+ res = false;
+ break;
+ }
+ res = efuse_one_byte_rw(padapter, bRead, start_addr + i,
+ data + i);
+ if ((false == bRead) && (false == res))
+ break;
+ }
+ if (false == bRead)
+ r8712_efuse_reg_uninit(padapter);
+ return res;
+}
+
+u8 r8712_efuse_map_read(struct _adapter *padapter, u16 addr, u16 cnts, u8 *data)
+{
+ u8 offset, ret = true;
+ u8 pktdata[PGPKT_DATA_SIZE];
+ int i, idx;
+
+ if ((addr + cnts) > EFUSE_MAP_MAX_SIZE)
+ return false;
+ if ((efuse_is_empty(padapter, &offset) == true) && (offset ==
+ true)) {
+ for (i = 0; i < cnts; i++)
+ data[i] = 0xFF;
+ return ret;
+ }
+ offset = (addr >> 3) & 0xF;
+ ret = r8712_efuse_pg_packet_read(padapter, offset, pktdata);
+ i = addr & 0x7; /* pktdata index */
+ idx = 0; /* data index */
+
+ do {
+ for (; i < PGPKT_DATA_SIZE; i++) {
+ data[idx++] = pktdata[i];
+ if (idx == cnts)
+ return ret;
+ }
+ offset++;
+ if (!r8712_efuse_pg_packet_read(padapter, offset, pktdata))
+ ret = false;
+ i = 0;
+ } while (1);
+ return ret;
+}
+
+u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, u16 cnts,
+ u8 *data)
+{
+ u8 offset, word_en, empty;
+ u8 pktdata[PGPKT_DATA_SIZE], newdata[PGPKT_DATA_SIZE];
+ int i, j, idx;
+
+ if ((addr + cnts) > EFUSE_MAP_MAX_SIZE)
+ return false;
+ /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */
+ empty = r8712_read8(padapter, EFUSE_CLK_CTRL);
+ if (empty != 0x03)
+ return false;
+ if (efuse_is_empty(padapter, &empty) == true) {
+ if (true == empty)
+ memset(pktdata, 0xFF, PGPKT_DATA_SIZE);
+ } else
+ return false;
+ offset = (addr >> 3) & 0xF;
+ if (empty == false)
+ if (!r8712_efuse_pg_packet_read(padapter, offset, pktdata))
+ return false;
+ word_en = 0xF;
+ memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+ i = addr & 0x7; /* pktdata index */
+ j = 0; /* newdata index */
+ idx = 0; /* data index */
+
+ if (i & 0x1) {
+ /* odd start */
+ if (data[idx] != pktdata[i]) {
+ word_en &= ~BIT(i >> 1);
+ newdata[j++] = pktdata[i - 1];
+ newdata[j++] = data[idx];
+ }
+ i++;
+ idx++;
+ }
+ do {
+ for (; i < PGPKT_DATA_SIZE; i += 2) {
+ if ((cnts - idx) == 1) {
+ if (data[idx] != pktdata[i]) {
+ word_en &= ~BIT(i >> 1);
+ newdata[j++] = data[idx];
+ newdata[j++] = pktdata[1 + 1];
+ }
+ idx++;
+ break;
+ } else {
+ if ((data[idx] != pktdata[i]) || (data[idx+1] !=
+ pktdata[i+1])) {
+ word_en &= ~BIT(i >> 1);
+ newdata[j++] = data[idx];
+ newdata[j++] = data[idx + 1];
+ }
+ idx += 2;
+ }
+ if (idx == cnts)
+ break;
+ }
+
+ if (word_en != 0xF)
+ if (r8712_efuse_pg_packet_write(padapter, offset,
+ word_en, newdata) == false)
+ return false;
+ if (idx == cnts)
+ break;
+ offset++;
+ if (empty == false)
+ if (!r8712_efuse_pg_packet_read(padapter, offset,
+ pktdata))
+ return false;
+ i = 0;
+ j = 0;
+ word_en = 0xF;
+ memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+ } while (1);
+
+ return true;
+}
diff --git a/drivers/staging/rtl8712/rtl8712_efuse.h b/drivers/staging/rtl8712/rtl8712_efuse.h
new file mode 100644
index 000000000000..6a64f91ad75f
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_efuse.h
@@ -0,0 +1,43 @@
+#ifndef __RTL8712_EFUSE_H__
+#define __RTL8712_EFUSE_H__
+
+#include "osdep_service.h"
+
+
+#define _REPEAT_THRESHOLD_ 3
+
+#define EFUSE_MAX_SIZE 512
+#define EFUSE_MAP_MAX_SIZE 128
+
+#define PGPKG_MAX_WORDS 4
+#define PGPKT_DATA_SIZE 8 /* PGPKG_MAX_WORDS*2; BYTES sizeof(u8)*8*/
+#define MAX_PGPKT_SIZE 9 /* 1 + PGPKT_DATA_SIZE; header + 2 * 4 words (BYTES)*/
+
+#define GET_EFUSE_OFFSET(header) ((header & 0xF0) >> 4)
+#define GET_EFUSE_WORD_EN(header) (header & 0x0F)
+#define MAKE_EFUSE_HEADER(offset, word_en) (((offset & 0x0F) << 4) | \
+ (word_en & 0x0F))
+/*--------------------------------------------------------------------------*/
+struct PGPKT_STRUCT {
+ u8 offset;
+ u8 word_en;
+ u8 data[PGPKT_DATA_SIZE];
+};
+/*--------------------------------------------------------------------------*/
+u8 r8712_efuse_reg_init(struct _adapter *padapter);
+void r8712_efuse_reg_uninit(struct _adapter *padapter);
+u16 r8712_efuse_get_current_size(struct _adapter *padapter);
+int r8712_efuse_get_max_size(struct _adapter *padapter);
+void r8712_efuse_change_max_size(struct _adapter *padapter);
+u8 r8712_efuse_pg_packet_read(struct _adapter *padapter,
+ u8 offset, u8 *data);
+u8 r8712_efuse_pg_packet_write(struct _adapter *padapter,
+ const u8 offset, const u8 word_en,
+ const u8 *data);
+u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead,
+ u16 start_addr, u16 cnts, u8 *data);
+u8 r8712_efuse_map_read(struct _adapter *padapter, u16 addr,
+ u16 cnts, u8 *data);
+u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr,
+ u16 cnts, u8 *data);
+#endif
diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h
new file mode 100644
index 000000000000..48408f72546c
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_event.h
@@ -0,0 +1,73 @@
+#ifndef _RTL8712_EVENT_H_
+#define _RTL8712_EVENT_H_
+
+void r8712_event_handle(struct _adapter *padapter, uint *peventbuf);
+void r8712_got_addbareq_event_callback(struct _adapter *adapter , u8 *pbuf);
+
+enum rtl8712_c2h_event {
+ GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
+ GEN_EVT_CODE(_Read_BBREG),
+ GEN_EVT_CODE(_Read_RFREG),
+ GEN_EVT_CODE(_Read_EEPROM),
+ GEN_EVT_CODE(_Read_EFUSE),
+ GEN_EVT_CODE(_Read_CAM), /*5*/
+ GEN_EVT_CODE(_Get_BasicRate),
+ GEN_EVT_CODE(_Get_DataRate),
+ GEN_EVT_CODE(_Survey), /*8*/
+ GEN_EVT_CODE(_SurveyDone), /*9*/
+
+ GEN_EVT_CODE(_JoinBss) , /*10*/
+ GEN_EVT_CODE(_AddSTA),
+ GEN_EVT_CODE(_DelSTA),
+ GEN_EVT_CODE(_AtimDone) ,
+ GEN_EVT_CODE(_TX_Report),
+ GEN_EVT_CODE(_CCX_Report), /*15*/
+ GEN_EVT_CODE(_DTM_Report),
+ GEN_EVT_CODE(_TX_Rate_Statistics),
+ GEN_EVT_CODE(_C2HLBK),
+ GEN_EVT_CODE(_FWDBG),
+ GEN_EVT_CODE(_C2HFEEDBACK), /*20*/
+ GEN_EVT_CODE(_ADDBA),
+ GEN_EVT_CODE(_C2HBCN),
+ GEN_EVT_CODE(_ReportPwrState), /*filen: only for PCIE, USB*/
+ GEN_EVT_CODE(_WPS_PBC), /*24*/
+ GEN_EVT_CODE(_ADDBAReq_Report), /*25*/
+ MAX_C2HEVT
+};
+
+
+#ifdef _RTL8712_CMD_C_
+
+static struct fwevent wlanevents[] = {
+ {0, NULL}, /*0*/
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, &r8712_survey_event_callback}, /*8*/
+ {sizeof(struct surveydone_event), &r8712_surveydone_event_callback},/*9*/
+
+ {0, &r8712_joinbss_event_callback}, /*10*/
+ {sizeof(struct stassoc_event), &r8712_stassoc_event_callback},
+ {sizeof(struct stadel_event), &r8712_stadel_event_callback},
+ {0, &r8712_atimdone_event_callback},
+ {0, NULL},
+ {0, NULL}, /*15*/
+ {0, NULL},
+ {0, NULL},
+ {0, NULL},
+ {0, NULL}, /*fwdbg_event_callback},*/
+ {0, NULL}, /*20*/
+ {0, NULL},
+ {0, NULL},
+ {0, &r8712_cpwm_event_callback},
+ {0, &r8712_wpspbc_event_callback},
+ {0, &r8712_got_addbareq_event_callback},
+};
+
+#endif/*_RTL8712_CMD_C_*/
+
+#endif
diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h
new file mode 100644
index 000000000000..e5df19f4b02b
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h
@@ -0,0 +1,126 @@
+#ifndef __RTL8712_FIFOCTRL_BITDEF_H__
+#define __RTL8712_FIFOCTRL_BITDEF_H__
+
+/*PBP*/
+#define _PSTX_MSK 0xF0
+#define _PSTX_SHT 4
+#define _PSRX_MSK 0x0F
+#define _PSRX_SHT 0
+
+/*TXFF_STATUS*/
+#define _TXSTATUS_OVF BIT(15)
+
+/*RXFF_STATUS*/
+#define _STATUSFF1_OVF BIT(7)
+#define _STATUSFF1_EMPTY BIT(6)
+#define _STATUSFF0_OVF BIT(5)
+#define _STATUSFF0_EMPTY BIT(4)
+#define _RXFF1_OVF BIT(3)
+#define _RXFF1_EMPTY BIT(2)
+#define _RXFF0_OVF BIT(1)
+#define _RXFF0_EMPTY BIT(0)
+
+/*TXFF_EMPTY_TH*/
+#define _BKQ_EMPTY_TH_MSK 0x0F0000
+#define _BKQ_EMPTY_TH_SHT 16
+#define _BEQ_EMPTY_TH_MSK 0x00F000
+#define _BEQ_EMPTY_TH_SHT 12
+#define _VIQ_EMPTY_TH_MSK 0x000F00
+#define _VIQ_EMPTY_TH_SHT 8
+#define _VOQ_EMPTY_TH_MSK 0x0000F0
+#define _VOQ_EMPTY_TH_SHT 4
+#define _BMCQ_EMPTY_TH_MSK 0x00000F
+#define _BMCQ_EMPTY_TH_SHT 0
+
+/*SDIO_RX_BLKSZ*/
+#define _SDIO_RX_BLKSZ_MSK 0x07
+
+/*RXDMA_CTRL*/
+#define _C2HFF_POLL BIT(4)
+#define _RXPKT_POLL BIT(0)
+
+/*RXPKT_NUM*/
+#define _RXCMD_NUM_MSK 0xFF00
+#define _RXCMD_NUM_SHT 8
+#define _RXFF0_NUM_MSK 0x00FF
+#define _RXFF0_NUM_SHT 0
+
+/*FIFOPAGE2*/
+#define _PUB_AVAL_PG_MSK 0xFFFF0000
+#define _PUB_AVAL_PG_SHT 16
+#define _BCN_AVAL_PG_MSK 0x0000FFFF
+#define _BCN_AVAL_PG_SHT 0
+
+/*RX0PKTNUM*/
+#define _RXFF0_DEC_POLL BIT(15)
+#define _RXFF0_PKT_DEC_NUM_MSK 0x3F00
+#define _RXFF0_PKT_DEC_NUM_SHT 8
+#define _RXFF0_PKTNUM_RPT_MSK 0x00FF
+#define _RXFF0_PKTNUM_RPT_SHT 0
+
+/*RX1PKTNUM*/
+#define _RXFF1_DEC_POLL BIT(15)
+#define _RXFF1_PKT_DEC_NUM_MSK 0x3F00
+#define _RXFF1_PKT_DEC_NUM_SHT 8
+#define _RXFF1_PKTNUM_RPT_MSK 0x00FF
+#define _RXFF1_PKTNUM_RPT_SHT 0
+
+/*RXFLTMAP0*/
+#define _MGTFLT13EN BIT(13)
+#define _MGTFLT12EN BIT(12)
+#define _MGTFLT11EN BIT(11)
+#define _MGTFLT10EN BIT(10)
+#define _MGTFLT9EN BIT(9)
+#define _MGTFLT8EN BIT(8)
+#define _MGTFLT5EN BIT(5)
+#define _MGTFLT4EN BIT(4)
+#define _MGTFLT3EN BIT(3)
+#define _MGTFLT2EN BIT(2)
+#define _MGTFLT1EN BIT(1)
+#define _MGTFLT0EN BIT(0)
+
+/*RXFLTMAP1*/
+#define _CTRLFLT15EN BIT(15)
+#define _CTRLFLT14EN BIT(14)
+#define _CTRLFLT13EN BIT(13)
+#define _CTRLFLT12EN BIT(12)
+#define _CTRLFLT11EN BIT(11)
+#define _CTRLFLT10EN BIT(10)
+#define _CTRLFLT9EN BIT(9)
+#define _CTRLFLT8EN BIT(8)
+#define _CTRLFLT7EN BIT(7)
+#define _CTRLFLT6EN BIT(6)
+
+/*RXFLTMAP2*/
+#define _DATAFLT15EN BIT(15)
+#define _DATAFLT14EN BIT(14)
+#define _DATAFLT13EN BIT(13)
+#define _DATAFLT12EN BIT(12)
+#define _DATAFLT11EN BIT(11)
+#define _DATAFLT10EN BIT(10)
+#define _DATAFLT9EN BIT(9)
+#define _DATAFLT8EN BIT(8)
+#define _DATAFLT7EN BIT(7)
+#define _DATAFLT6EN BIT(6)
+#define _DATAFLT5EN BIT(5)
+#define _DATAFLT4EN BIT(4)
+#define _DATAFLT3EN BIT(3)
+#define _DATAFLT2EN BIT(2)
+#define _DATAFLT1EN BIT(1)
+#define _DATAFLT0EN BIT(0)
+
+/*RXFLTMAP3*/
+#define _MESHAFLT1EN BIT(1)
+#define _MESHAFLT0EN BIT(0)
+
+/*TXPKT_NUM_CTRL*/
+#define _TXPKTNUM_DEC BIT(8)
+#define _TXPKTNUM_MSK 0x00FF
+#define _TXPKTNUM_SHT 0
+
+/*TXFF_PG_NUM*/
+#define _TXFF_PG_NUM_MSK 0x0FFF
+
+
+#endif /* __RTL8712_FIFOCTRL_BITDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h
new file mode 100644
index 000000000000..c2e3af2c79f6
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h
@@ -0,0 +1,57 @@
+#ifndef __RTL8712_FIFOCTRL_REGDEF_H__
+#define __RTL8712_FIFOCTRL_REGDEF_H__
+
+#define RQPN (RTL8712_FIFOCTRL_ + 0x00)
+#define RXFF_BNDY (RTL8712_FIFOCTRL_ + 0x0C)
+#define RXRPT_BNDY (RTL8712_FIFOCTRL_ + 0x10)
+#define TXPKTBUF_PGBNDY (RTL8712_FIFOCTRL_ + 0x14)
+#define PBP (RTL8712_FIFOCTRL_ + 0x15)
+#define RX_DRVINFO_SZ (RTL8712_FIFOCTRL_ + 0x16)
+#define TXFF_STATUS (RTL8712_FIFOCTRL_ + 0x17)
+#define RXFF_STATUS (RTL8712_FIFOCTRL_ + 0x18)
+#define TXFF_EMPTY_TH (RTL8712_FIFOCTRL_ + 0x19)
+#define SDIO_RX_BLKSZ (RTL8712_FIFOCTRL_ + 0x1C)
+#define RXDMA_RXCTRL (RTL8712_FIFOCTRL_ + 0x1D)
+#define RXPKT_NUM (RTL8712_FIFOCTRL_ + 0x1E)
+#define RXPKT_NUM_C2H (RTL8712_FIFOCTRL_ + 0x1F)
+#define C2HCMD_UDT_SIZE (RTL8712_FIFOCTRL_ + 0x20)
+#define C2HCMD_UDT_ADDR (RTL8712_FIFOCTRL_ + 0x22)
+#define FIFOPAGE2 (RTL8712_FIFOCTRL_ + 0x24)
+#define FIFOPAGE1 (RTL8712_FIFOCTRL_ + 0x28)
+#define FW_RSVD_PG_CTRL (RTL8712_FIFOCTRL_ + 0x30)
+#define TXRPTFF_RDPTR (RTL8712_FIFOCTRL_ + 0x40)
+#define TXRPTFF_WTPTR (RTL8712_FIFOCTRL_ + 0x44)
+#define C2HFF_RDPTR (RTL8712_FIFOCTRL_ + 0x48)
+#define C2HFF_WTPTR (RTL8712_FIFOCTRL_ + 0x4C)
+#define RXFF0_RDPTR (RTL8712_FIFOCTRL_ + 0x50)
+#define RXFF0_WTPTR (RTL8712_FIFOCTRL_ + 0x54)
+#define RXFF1_RDPTR (RTL8712_FIFOCTRL_ + 0x58)
+#define RXFF1_WTPTR (RTL8712_FIFOCTRL_ + 0x5C)
+#define RXRPT0FF_RDPTR (RTL8712_FIFOCTRL_ + 0x60)
+#define RXRPT0FF_WTPTR (RTL8712_FIFOCTRL_ + 0x64)
+#define RXRPT1FF_RDPTR (RTL8712_FIFOCTRL_ + 0x68)
+#define RXRPT1FF_WTPTR (RTL8712_FIFOCTRL_ + 0x6C)
+#define RX0PKTNUM (RTL8712_FIFOCTRL_ + 0x72)
+#define RX1PKTNUM (RTL8712_FIFOCTRL_ + 0x74)
+#define RXFLTMAP0 (RTL8712_FIFOCTRL_ + 0x76)
+#define RXFLTMAP1 (RTL8712_FIFOCTRL_ + 0x78)
+#define RXFLTMAP2 (RTL8712_FIFOCTRL_ + 0x7A)
+#define RXFLTMAP3 (RTL8712_FIFOCTRL_ + 0x7c)
+#define TBDA (RTL8712_FIFOCTRL_ + 0x84)
+#define THPDA (RTL8712_FIFOCTRL_ + 0x88)
+#define TCDA (RTL8712_FIFOCTRL_ + 0x8C)
+#define TMDA (RTL8712_FIFOCTRL_ + 0x90)
+#define HDA (RTL8712_FIFOCTRL_ + 0x94)
+#define TVODA (RTL8712_FIFOCTRL_ + 0x98)
+#define TVIDA (RTL8712_FIFOCTRL_ + 0x9C)
+#define TBEDA (RTL8712_FIFOCTRL_ + 0xA0)
+#define TBKDA (RTL8712_FIFOCTRL_ + 0xA4)
+#define RCDA (RTL8712_FIFOCTRL_ + 0xA8)
+#define RDSA (RTL8712_FIFOCTRL_ + 0xAC)
+#define TXPKT_NUM_CTRL (RTL8712_FIFOCTRL_ + 0xB0)
+#define TXQ_PGADD (RTL8712_FIFOCTRL_ + 0xB3)
+#define TXFF_PG_NUM (RTL8712_FIFOCTRL_ + 0xB4)
+
+
+
+#endif /* __RTL8712_FIFOCTRL_REGDEF_H__ */
diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h
new file mode 100644
index 000000000000..35ca809e1799
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h
@@ -0,0 +1,54 @@
+#ifndef __RTL8712_GP_BITDEF_H__
+#define __RTL8712_GP_BITDEF_H__
+
+/*GPIO_CTRL*/
+#define _GPIO_MOD_MSK 0xFF000000
+#define _GPIO_MOD_SHT 24
+#define _GPIO_IO_SEL_MSK 0x00FF0000
+#define _GPIO_IO_SEL_SHT 16
+#define _GPIO_OUT_MSK 0x0000FF00
+#define _GPIO_OUT_SHT 8
+#define _GPIO_IN_MSK 0x000000FF
+#define _GPIO_IN_SHT 0
+
+/*SYS_PINMUX_CFG*/
+#define _GPIOSEL_MSK 0x0003
+#define _GPIOSEL_SHT 0
+
+/*LED_CFG*/
+#define _LED1SV BIT(7)
+#define _LED1CM_MSK 0x0070
+#define _LED1CM_SHT 4
+#define _LED0SV BIT(3)
+#define _LED0CM_MSK 0x0007
+#define _LED0CM_SHT 0
+
+/*PHY_REG*/
+#define _HST_RDRDY_SHT 0
+#define _HST_RDRDY_MSK 0xFF
+#define _HST_RDRDY BIT(_HST_RDRDY_SHT)
+#define _CPU_WTBUSY_SHT 1
+#define _CPU_WTBUSY_MSK 0xFF
+#define _CPU_WTBUSY BIT(_CPU_WTBUSY_SHT)
+
+/* 11. General Purpose Registers (Offset: 0x02E0 - 0x02FF)*/
+
+/* 8192S GPIO Config Setting (offset 0x2F1, 1 byte)*/
+
+/*----------------------------------------------------------------------------*/
+
+#define GPIOMUX_EN BIT(3) /* When this bit is set to "1",
+ * GPIO PINs will switch to MAC
+ * GPIO Function*/
+#define GPIOSEL_GPIO 0 /* UART or JTAG or pure GPIO*/
+#define GPIOSEL_PHYDBG 1 /* PHYDBG*/
+#define GPIOSEL_BT 2 /* BT_coex*/
+#define GPIOSEL_WLANDBG 3 /* WLANDBG*/
+#define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1)))
+/* HW Readio OFF switch (GPIO BIT) */
+#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3)
+#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7
+#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4)
+
+#endif /*__RTL8712_GP_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_gp_regdef.h b/drivers/staging/rtl8712/rtl8712_gp_regdef.h
new file mode 100644
index 000000000000..17e72bda617e
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_gp_regdef.h
@@ -0,0 +1,17 @@
+#ifndef __RTL8712_GP_REGDEF_H__
+#define __RTL8712_GP_REGDEF_H__
+
+#define PSTIMER (RTL8712_GP_ + 0x00)
+#define TIMER1 (RTL8712_GP_ + 0x04)
+#define TIMER2 (RTL8712_GP_ + 0x08)
+#define GPIO_CTRL (RTL8712_GP_ + 0x0C)
+#define GPIO_IO_SEL (RTL8712_GP_ + 0x0E)
+#define GPIO_INTCTRL (RTL8712_GP_ + 0x10)
+#define MAC_PINMUX_CTRL (RTL8712_GP_ + 0x11)
+#define LEDCFG (RTL8712_GP_ + 0x12)
+#define PHY_REG_RPT (RTL8712_GP_ + 0x13)
+#define PHY_REG_DATA (RTL8712_GP_ + 0x14)
+
+
+#endif /*__RTL8712_GP_REGDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h
new file mode 100644
index 000000000000..13df2001e9ad
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_hal.h
@@ -0,0 +1,124 @@
+#ifndef __RTL8712_HAL_H__
+#define __RTL8712_HAL_H__
+
+enum _HW_VERSION {
+ RTL8712_FPGA,
+ RTL8712_1stCUT, /*A Cut (RTL8712_ASIC)*/
+ RTL8712_2ndCUT, /*B Cut*/
+ RTL8712_3rdCUT, /*C Cut*/
+};
+
+enum _LOOPBACK_TYPE {
+ RTL8712_AIR_TRX = 0,
+ RTL8712_MAC_LBK,
+ RTL8712_BB_LBK,
+ RTL8712_MAC_FW_LBK = 4,
+ RTL8712_BB_FW_LBK = 8,
+};
+
+enum RTL871X_HCI_TYPE {
+ RTL8712_SDIO,
+ RTL8712_USB,
+};
+
+enum RTL8712_RF_CONFIG{
+ RTL8712_RF_1T1R,
+ RTL8712_RF_1T2R,
+ RTL8712_RF_2T2R
+};
+
+enum _RTL8712_HCI_TYPE_{
+ RTL8712_HCI_TYPE_PCIE = 0x01,
+ RTL8712_HCI_TYPE_AP_PCIE = 0x81,
+ RTL8712_HCI_TYPE_USB = 0x02,
+ RTL8712_HCI_TYPE_92USB = 0x02,
+ RTL8712_HCI_TYPE_AP_USB = 0x82,
+ RTL8712_HCI_TYPE_72USB = 0x12,
+ RTL8712_HCI_TYPE_SDIO = 0x04,
+ RTL8712_HCI_TYPE_72SDIO = 0x14
+};
+
+struct fw_priv { /*8-bytes alignment required*/
+ /*--- long word 0 ----*/
+ unsigned char signature_0; /*0x12: CE product, 0x92: IT product*/
+ unsigned char signature_1; /*0x87: CE product, 0x81: IT product*/
+ unsigned char hci_sel; /*0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP,
+ * 0x12: 72S-U, 03:SDIO*/
+ unsigned char chip_version; /*the same value as register value*/
+ unsigned char customer_ID_0; /*customer ID low byte*/
+ unsigned char customer_ID_1; /*customer ID high byte*/
+ unsigned char rf_config; /*0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo,
+ * 0x22: 2T2R*/
+ unsigned char usb_ep_num; /* 4: 4EP, 6: 6EP, 11: 11EP*/
+ /*--- long word 1 ----*/
+ unsigned char regulatory_class_0; /*regulatory class bit map 0*/
+ unsigned char regulatory_class_1; /*regulatory class bit map 1*/
+ unsigned char regulatory_class_2; /*regulatory class bit map 2*/
+ unsigned char regulatory_class_3; /*regulatory class bit map 3*/
+ unsigned char rfintfs; /* 0:SWSI, 1:HWSI, 2:HWPI*/
+ unsigned char def_nettype;
+ unsigned char turboMode;
+ unsigned char lowPowerMode;/* 0: noral mode, 1: low power mode*/
+ /*--- long word 2 ----*/
+ unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/
+ unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */
+ unsigned char vcsType; /* 0:off 1:on 2:auto */
+ unsigned char vcsMode; /* 1:RTS/CTS 2:CTS to self */
+ unsigned char rsvd022;
+ unsigned char rsvd023;
+ unsigned char rsvd024;
+ unsigned char rsvd025;
+ /*--- long word 3 ----*/
+ unsigned char qos_en; /*1: QoS enable*/
+ unsigned char bw_40MHz_en; /*1: 40MHz BW enable*/
+ unsigned char AMSDU2AMPDU_en; /*1: 4181 convert AMSDU to AMPDU,
+ * 0: disable*/
+ unsigned char AMPDU_en; /*1: 11n AMPDU enable*/
+ unsigned char rate_control_offload; /*1: FW offloads, 0: driver handles*/
+ unsigned char aggregation_offload; /*1: FW offloads, 0: driver handles*/
+ unsigned char rsvd030;
+ unsigned char rsvd031;
+ /*--- long word 4 ----*/
+ unsigned char beacon_offload; /* 1. FW offloads, 0: driver handles*/
+ unsigned char MLME_offload; /* 2. FW offloads, 0: driver handles*/
+ unsigned char hwpc_offload; /* 3. FW offloads, 0: driver handles*/
+ unsigned char tcp_checksum_offload; /* 4. FW offloads, 0: driver handles*/
+ unsigned char tcp_offload; /* 5. FW offloads, 0: driver handles*/
+ unsigned char ps_control_offload; /* 6. FW offloads, 0: driver handles*/
+ unsigned char WWLAN_offload; /* 7. FW offloads, 0: driver handles*/
+ unsigned char rsvd040;
+ /*--- long word 5 ----*/
+ unsigned char tcp_tx_frame_len_L; /*tcp tx packet length low byte*/
+ unsigned char tcp_tx_frame_len_H; /*tcp tx packet length high byte*/
+ unsigned char tcp_rx_frame_len_L; /*tcp rx packet length low byte*/
+ unsigned char tcp_rx_frame_len_H; /*tcp rx packet length high byte*/
+ unsigned char rsvd050;
+ unsigned char rsvd051;
+ unsigned char rsvd052;
+ unsigned char rsvd053;
+};
+
+struct fw_hdr {/*8-byte alinment required*/
+ unsigned short signature;
+ unsigned short version; /*0x8000 ~ 0x8FFF for FPGA version,
+ *0x0000 ~ 0x7FFF for ASIC version,*/
+ unsigned int dmem_size; /*define the size of boot loader*/
+ unsigned int img_IMEM_size; /*define the size of FW in IMEM*/
+ unsigned int img_SRAM_size; /*define the size of FW in SRAM*/
+ unsigned int fw_priv_sz; /*define the size of DMEM variable*/
+ unsigned short efuse_addr;
+ unsigned short h2ccnd_resp_addr;
+ unsigned int SVNRevision;
+ unsigned int release_time; /*Mon:Day:Hr:Min*/
+ struct fw_priv fwpriv;
+};
+
+struct hal_priv{
+ /*Endpoint handles*/
+ struct net_device *pipehdls_r8712[10];
+ u8 (*hal_bus_init)(struct _adapter *adapter);
+};
+
+uint rtl8712_hal_init(struct _adapter *padapter);
+
+#endif
diff --git a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h
new file mode 100644
index 000000000000..02f24809814d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h
@@ -0,0 +1,39 @@
+#ifndef __RTL8712_INTERRUPT_BITDEF_H__
+#define __RTL8712_INTERRUPT_BITDEF_H__
+
+/*HIMR*/
+/*HISR*/
+#define _CPUERR BIT(29)
+#define _ATIMEND BIT(28)
+#define _TXBCNOK BIT(27)
+#define _TXBCNERR BIT(26)
+#define _BCNDMAINT4 BIT(25)
+#define _BCNDMAINT3 BIT(24)
+#define _BCNDMAINT2 BIT(23)
+#define _BCNDMAINT1 BIT(22)
+#define _BCNDOK4 BIT(21)
+#define _BCNDOK3 BIT(20)
+#define _BCNDOK2 BIT(19)
+#define _BCNDOK1 BIT(18)
+#define _TIMEOUT2 BIT(17)
+#define _TIMEOUT1 BIT(16)
+#define _TXFOVW BIT(15)
+#define _PSTIMEOUT BIT(14)
+#define _BCNDMAINT0 BIT(13)
+#define _FOVW BIT(12)
+#define _RDU BIT(11)
+#define _RXCMDOK BIT(10)
+#define _BCNDOK0 BIT(9)
+#define _HIGHDOK BIT(8)
+#define _COMDOK BIT(7)
+#define _MGTDOK BIT(6)
+#define _HCCADOK BIT(5)
+#define _BKDOK BIT(4)
+#define _BEDOK BIT(3)
+#define _VIDOK BIT(2)
+#define _VODOK BIT(1)
+#define _RXOK BIT(0)
+
+
+#endif /*__RTL8712_INTERRUPT_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_io.c b/drivers/staging/rtl8712/rtl8712_io.c
new file mode 100644
index 000000000000..c7346008def0
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_io.c
@@ -0,0 +1,151 @@
+/******************************************************************************
+ * rtl8712_io.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>.
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL8712_IO_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_io.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+u8 r8712_read8(struct _adapter *adapter, u32 addr)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+ u8 r_val;
+
+ _read8 = pintfhdl->io_ops._read8;
+ r_val = _read8(pintfhdl, addr);
+ return r_val;
+}
+
+u16 r8712_read16(struct _adapter *adapter, u32 addr)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ u16 r_val;
+
+ _read16 = pintfhdl->io_ops._read16;
+ r_val = _read16(pintfhdl, addr);
+ return r_val;
+}
+
+u32 r8712_read32(struct _adapter *adapter, u32 addr)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ u32 r_val;
+
+ _read32 = pintfhdl->io_ops._read32;
+ r_val = _read32(pintfhdl, addr);
+ return r_val;
+}
+
+void r8712_write8(struct _adapter *adapter, u32 addr, u8 val)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+ void (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
+
+ _write8 = pintfhdl->io_ops._write8;
+ _write8(pintfhdl, addr, val);
+}
+
+void r8712_write16(struct _adapter *adapter, u32 addr, u16 val)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+
+ void (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
+ _write16 = pintfhdl->io_ops._write16;
+ _write16(pintfhdl, addr, val);
+}
+
+void r8712_write32(struct _adapter *adapter, u32 addr, u32 val)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_queue->intf));
+
+ void (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
+ _write32 = pintfhdl->io_ops._write32;
+ _write32(pintfhdl, addr, val);
+}
+
+void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+
+ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ if ((adapter->bDriverStopped == true) ||
+ (adapter->bSurpriseRemoved == true))
+ return;
+ _read_mem = pintfhdl->io_ops._read_mem;
+ _read_mem(pintfhdl, addr, cnt, pmem);
+}
+
+void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+
+ _write_mem = pintfhdl->io_ops._write_mem;
+ _write_mem(pintfhdl, addr, cnt, pmem);
+}
+
+void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+
+ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ if ((adapter->bDriverStopped == true) ||
+ (adapter->bSurpriseRemoved == true))
+ return;
+ _read_port = pintfhdl->io_ops._read_port;
+ _read_port(pintfhdl, addr, cnt, pmem);
+}
+
+void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
+{
+ struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
+ struct intf_hdl *pintfhdl = &(pio_queue->intf);
+
+ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ _write_port = pintfhdl->io_ops._write_port;
+ _write_port(pintfhdl, addr, cnt, pmem);
+}
diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c
new file mode 100644
index 000000000000..5024ee42b04b
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_led.c
@@ -0,0 +1,1815 @@
+/******************************************************************************
+ * rtl8712_led.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#include "drv_types.h"
+
+/*===========================================================================
+ * Constant.
+ *===========================================================================
+
+ *
+ * Default LED behavior.
+ */
+#define LED_BLINK_NORMAL_INTERVAL 100
+#define LED_BLINK_SLOWLY_INTERVAL 200
+#define LED_BLINK_LONG_INTERVAL 400
+
+#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000
+#define LED_BLINK_LINK_INTERVAL_ALPHA 500
+#define LED_BLINK_SCAN_INTERVAL_ALPHA 180
+#define LED_BLINK_FASTER_INTERVAL_ALPHA 50
+#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000
+
+/*===========================================================================
+ * LED object.
+ *===========================================================================
+ */
+enum _LED_STATE_871x{
+ LED_UNKNOWN = 0,
+ LED_ON = 1,
+ LED_OFF = 2,
+ LED_BLINK_NORMAL = 3,
+ LED_BLINK_SLOWLY = 4,
+ LED_POWER_ON_BLINK = 5,
+ LED_SCAN_BLINK = 6, /* LED is blinking during scanning period,
+ * the # of times to blink is depend on time
+ * for scanning. */
+ LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */
+ LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer
+ * Server case */
+ LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */
+ LED_TXRX_BLINK = 10,
+ LED_BLINK_WPS_STOP = 11, /*for ALPHA */
+ LED_BLINK_WPS_STOP_OVERLAP = 12, /*for BELKIN */
+};
+
+/*===========================================================================
+ * Prototype of protected function.
+ *===========================================================================
+ */
+static void BlinkTimerCallback(unsigned long data);
+
+static void BlinkWorkItemCallback(struct work_struct *work);
+/*===========================================================================
+ * LED_819xUsb routines.
+ *===========================================================================
+ *
+ *
+ *
+ * Description:
+ * Initialize an LED_871x object.
+ */
+static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
+ enum LED_PIN_871x LedPin)
+{
+ struct net_device *nic;
+
+ nic = padapter->pnetdev;
+ pLed->padapter = padapter;
+ pLed->LedPin = LedPin;
+ pLed->CurrLedState = LED_OFF;
+ pLed->bLedOn = false;
+ pLed->bLedBlinkInProgress = false;
+ pLed->BlinkTimes = 0;
+ pLed->BlinkingLedState = LED_UNKNOWN;
+ _init_timer(&(pLed->BlinkTimer), nic, BlinkTimerCallback, pLed);
+ _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
+}
+
+/*
+ * Description:
+ * DeInitialize an LED_871x object.
+ */
+static void DeInitLed871x(struct LED_871x *pLed)
+{
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ /* We should reset bLedBlinkInProgress if we cancel
+ * the LedControlTimer, */
+ pLed->bLedBlinkInProgress = false;
+}
+
+/*
+ * Description:
+ * Turn on LED according to LedPin specified.
+ */
+static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed)
+{
+ u8 LedCfg;
+
+ if ((padapter->bSurpriseRemoved == true) ||
+ (padapter->bDriverStopped == true))
+ return;
+ LedCfg = r8712_read8(padapter, LEDCFG);
+ switch (pLed->LedPin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ /* SW control led0 on.*/
+ r8712_write8(padapter, LEDCFG, LedCfg&0xf0);
+ break;
+ case LED_PIN_LED1:
+ /* SW control led1 on.*/
+ r8712_write8(padapter, LEDCFG, LedCfg&0x0f);
+ break;
+ default:
+ break;
+ }
+ pLed->bLedOn = true;
+}
+
+/*
+ * Description:
+ * Turn off LED according to LedPin specified.
+ */
+static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed)
+{
+ u8 LedCfg;
+
+ if ((padapter->bSurpriseRemoved == true) ||
+ (padapter->bDriverStopped == true))
+ return;
+ LedCfg = r8712_read8(padapter, LEDCFG);
+ switch (pLed->LedPin) {
+ case LED_PIN_GPIO0:
+ break;
+ case LED_PIN_LED0:
+ LedCfg &= 0xf0; /* Set to software control.*/
+ r8712_write8(padapter, LEDCFG, (LedCfg|BIT(3)));
+ break;
+ case LED_PIN_LED1:
+ LedCfg &= 0x0f; /* Set to software control.*/
+ r8712_write8(padapter, LEDCFG, (LedCfg|BIT(7)));
+ break;
+ default:
+ break;
+ }
+ pLed->bLedOn = false;
+}
+
+/*===========================================================================
+ * Interface to manipulate LED objects.
+ *===========================================================================
+ *
+ * Description:
+ * Initialize all LED_871x objects.
+ */
+void r8712_InitSwLeds(struct _adapter *padapter)
+{
+ struct led_priv *pledpriv = &(padapter->ledpriv);
+
+ pledpriv->LedControlHandler = LedControl871x;
+ InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
+ InitLed871x(padapter, &(pledpriv->SwLed1), LED_PIN_LED1);
+}
+
+/* Description:
+ * DeInitialize all LED_819xUsb objects.
+ */
+void r8712_DeInitSwLeds(struct _adapter *padapter)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ DeInitLed871x(&(ledpriv->SwLed0));
+ DeInitLed871x(&(ledpriv->SwLed1));
+}
+
+/* Description:
+ * Implementation of LED blinking behavior.
+ * It toggle off LED and schedule corresponding timer if necessary.
+ */
+static void SwLedBlink(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ /* Determine if we shall change LED state again. */
+ pLed->BlinkTimes--;
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_NORMAL:
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+ case LED_BLINK_StartToBlink:
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) &&
+ (pmlmepriv->fw_state & WIFI_STATION_STATE))
+ bStopBlinking = true;
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) &&
+ ((pmlmepriv->fw_state & WIFI_ADHOC_STATE) ||
+ (pmlmepriv->fw_state & WIFI_ADHOC_MASTER_STATE)))
+ bStopBlinking = true;
+ else if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ break;
+ default:
+ bStopBlinking = true;
+ break;
+ }
+ if (bStopBlinking) {
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) &&
+ (pLed->bLedOn == false))
+ SwLedOn(padapter, pLed);
+ else if ((check_fwstate(pmlmepriv, _FW_LINKED) ==
+ true) && pLed->bLedOn == true)
+ SwLedOff(padapter, pLed);
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ /* Assign LED state to toggle. */
+ if (pLed->BlinkingLedState == LED_ON)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+
+ /* Schedule a timer to toggle LED state. */
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_NORMAL:
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ break;
+ case LED_BLINK_SLOWLY:
+ case LED_BLINK_StartToBlink:
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->BlinkingLedState == LED_ON)
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LONG_INTERVAL);
+ else
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LONG_INTERVAL);
+ break;
+ default:
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ break;
+ }
+ }
+}
+
+static void SwLedBlink1(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct eeprom_priv *peeprompriv = &(padapter->eeprompriv);
+ struct LED_871x *pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = false;
+
+ if (peeprompriv->CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ if (peeprompriv->CustomerID == RT_CID_DEFAULT) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ if (!pLed1->bSWLedCtrl) {
+ SwLedOn(padapter, pLed1);
+ pLed1->bSWLedCtrl = true;
+ } else if (!pLed1->bLedOn)
+ SwLedOn(padapter, pLed1);
+ } else {
+ if (!pLed1->bSWLedCtrl) {
+ SwLedOff(padapter, pLed1);
+ pLed1->bSWLedCtrl = true;
+ } else if (pLed1->bLedOn)
+ SwLedOff(padapter, pLed1);
+ }
+ }
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+ case LED_BLINK_NORMAL:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ break;
+ case LED_SCAN_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+ case LED_BLINK_WPS_STOP: /* WPS success */
+ if (pLed->BlinkingLedState == LED_ON) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ bStopBlinking = false;
+ } else
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedWPSBlinkInProgress = false;
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedBlink2(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ switch (pLed->CurrLedState) {
+ case LED_SCAN_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ SwLedOn(padapter, pLed);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ SwLedOn(padapter, pLed);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedBlink3(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(padapter, pLed);
+ switch (pLed->CurrLedState) {
+ case LED_SCAN_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (!pLed->bLedOn)
+ SwLedOn(padapter, pLed);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (!pLed->bLedOn)
+ SwLedOn(padapter, pLed);
+ } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ }
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+ case LED_BLINK_WPS_STOP: /*WPS success*/
+ if (pLed->BlinkingLedState == LED_ON) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ bStopBlinking = false;
+ } else
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ SwLedOn(padapter, pLed);
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedBlink4(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct LED_871x *pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ if (!pLed1->bLedWPSBlinkInProgress &&
+ pLed1->BlinkingLedState == LED_UNKNOWN) {
+ pLed1->BlinkingLedState = LED_OFF;
+ pLed1->CurrLedState = LED_OFF;
+ SwLedOff(padapter, pLed1);
+ }
+ switch (pLed->CurrLedState) {
+ case LED_BLINK_SLOWLY:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+ case LED_BLINK_StartToBlink:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+ case LED_SCAN_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+ case LED_BLINK_WPS_STOP: /*WPS authentication fail*/
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+ case LED_BLINK_WPS_STOP_OVERLAP: /*WPS session overlap */
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0) {
+ if (pLed->bLedOn)
+ pLed->BlinkTimes = 1;
+ else
+ bStopBlinking = true;
+ }
+ if (bStopBlinking) {
+ pLed->BlinkTimes = 10;
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedBlink5(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ switch (pLed->CurrLedState) {
+ case LED_SCAN_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ pLed->bLedScanBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedBlink6(struct LED_871x *pLed)
+{
+ struct _adapter *padapter = pLed->padapter;
+ u8 bStopBlinking = false;
+
+ /* Change LED according to BlinkingLedState specified. */
+ if (pLed->BlinkingLedState == LED_ON)
+ SwLedOn(padapter, pLed);
+ else
+ SwLedOff(padapter, pLed);
+ switch (pLed->CurrLedState) {
+ case LED_TXRX_BLINK:
+ pLed->BlinkTimes--;
+ if (pLed->BlinkTimes == 0)
+ bStopBlinking = true;
+ if (bStopBlinking) {
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (!pLed->bLedOn)
+ SwLedOn(padapter, pLed);
+ pLed->bLedBlinkInProgress = false;
+ } else {
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_BLINK_WPS:
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Description:
+ * Callback function of LED BlinkTimer,
+ * it just schedules to corresponding BlinkWorkItem.
+ */
+static void BlinkTimerCallback(unsigned long data)
+{
+ struct LED_871x *pLed = (struct LED_871x *)data;
+
+ /* This fixed the crash problem on Fedora 12 when trying to do thei
+ * insmod;ifconfig up;rmmod commands. */
+ if ((pLed->padapter->bSurpriseRemoved == true) ||
+ (pLed->padapter->bDriverStopped == true))
+ return;
+ _set_workitem(&(pLed->BlinkWorkItem));
+}
+
+/* Description:
+ * Callback function of LED BlinkWorkItem.
+ * We dispatch acture LED blink action according to LedStrategy.
+ */
+static void BlinkWorkItemCallback(struct work_struct *work)
+{
+ struct LED_871x *pLed = container_of(work, struct LED_871x,
+ BlinkWorkItem);
+ struct led_priv *ledpriv = &(pLed->padapter->ledpriv);
+
+ switch (ledpriv->LedStrategy) {
+ case SW_LED_MODE0:
+ SwLedBlink(pLed);
+ break;
+ case SW_LED_MODE1:
+ SwLedBlink1(pLed);
+ break;
+ case SW_LED_MODE2:
+ SwLedBlink2(pLed);
+ break;
+ case SW_LED_MODE3:
+ SwLedBlink3(pLed);
+ break;
+ case SW_LED_MODE4:
+ SwLedBlink4(pLed);
+ break;
+ case SW_LED_MODE5:
+ SwLedBlink5(pLed);
+ break;
+ case SW_LED_MODE6:
+ SwLedBlink6(pLed);
+ break;
+ default:
+ SwLedBlink(pLed);
+ break;
+ }
+}
+
+/*============================================================================
+ * Default LED behavior.
+ *============================================================================
+ *
+ * Description:
+ * Implement each led action for SW_LED_MODE0.
+ * This is default strategy.
+ */
+
+static void SwLedControlMode1(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sitesurvey_ctrl *psitesurveyctrl = &(pmlmepriv->sitesurveyctrl);
+
+ if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+ switch (LedAction) {
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_LINK:
+ if (pLed->bLedLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_SITE_SURVEY:
+ if ((psitesurveyctrl->traffic_busy) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ; /* dummy branch */
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_SCAN_BLINK;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: /*wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ else
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+ case LED_CTL_STOP_WPS_FAIL:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedControlMode2(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_SITE_SURVEY:
+ if (pmlmepriv->sitesurveyctrl.traffic_busy)
+ ; /* dummy branch */
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_SCAN_BLINK;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if ((pLed->bLedBlinkInProgress == false) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: /*wait until xinpin finish*/
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ pLed->bLedWPSBlinkInProgress = false;
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (!IS_LED_BLINKING(pLed)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedControlMode3(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_SITE_SURVEY:
+ if (pmlmepriv->sitesurveyctrl.traffic_busy)
+ ; /* dummy branch */
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_SCAN_BLINK;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if ((pLed->bLedBlinkInProgress == false) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_LINK:
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ case LED_CTL_START_WPS: /* wait until xinpin finish */
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ } else
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+ case LED_CTL_STOP_WPS_FAIL:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if (!IS_LED_BLINKING(pLed)) {
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedControlMode4(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+ struct LED_871x *pLed1 = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_START_TO_LINK:
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->BlinkingLedState = LED_OFF;
+ pLed1->CurrLedState = LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ if (pLed->bLedStartToLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedStartToLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ /*LED1 settings*/
+ if (LedAction == LED_CTL_LINK) {
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->BlinkingLedState = LED_OFF;
+ pLed1->CurrLedState = LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ }
+ if (pLed->bLedNoLinkBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->sitesurveyctrl.traffic_busy) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ;
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_SCAN_BLINK;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK ||
+ IS_LED_WPS_BLINKING(pLed))
+ return;
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_START_WPS: /*wait until xinpin finish*/
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed1->bLedWPSBlinkInProgress) {
+ pLed1->bLedWPSBlinkInProgress = false;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->BlinkingLedState = LED_OFF;
+ pLed1->CurrLedState = LED_OFF;
+ if (pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedNoLinkBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn) {
+ pLed->BlinkingLedState = LED_OFF;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SLOWLY_INTERVAL);
+ } else {
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+ case LED_CTL_STOP_WPS: /*WPS connect success*/
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+ case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ /*LED1 settings*/
+ if (pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = true;
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = LED_OFF;
+ else
+ pLed1->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->bLedNoLinkBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ /*LED1 settings*/
+ if (pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = true;
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
+ pLed1->BlinkTimes = 10;
+ if (pLed1->bLedOn)
+ pLed1->BlinkingLedState = LED_OFF;
+ else
+ pLed1->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedNoLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = false;
+ }
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ if (pLed->bLedScanBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = false;
+ }
+ if (pLed->bLedStartToLinkBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedStartToLinkBlinkInProgress = false;
+ }
+ if (pLed1->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedWPSBlinkInProgress = false;
+ }
+ pLed1->BlinkingLedState = LED_UNKNOWN;
+ SwLedOff(padapter, pLed);
+ SwLedOff(padapter, pLed1);
+ break;
+ default:
+ break;
+ }
+}
+
+static void SwLedControlMode5(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+
+ if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_NO_LINK:
+ case LED_CTL_LINK: /* solid blue */
+ if (pLed->CurrLedState == LED_SCAN_BLINK)
+ return;
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ pLed->bLedBlinkInProgress = false;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ case LED_CTL_SITE_SURVEY:
+ if ((pmlmepriv->sitesurveyctrl.traffic_busy) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true))
+ ; /* dummy branch */
+ else if (pLed->bLedScanBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedScanBlinkInProgress = true;
+ pLed->CurrLedState = LED_SCAN_BLINK;
+ pLed->BlinkTimes = 24;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false) {
+ if (pLed->CurrLedState == LED_SCAN_BLINK)
+ return;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ SwLedOff(padapter, pLed);
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void SwLedControlMode6(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct LED_871x *pLed = &(ledpriv->SwLed0);
+
+ switch (LedAction) {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_NO_LINK:
+ case LED_CTL_LINK: /*solid blue*/
+ case LED_CTL_SITE_SURVEY:
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ pLed->bLedBlinkInProgress = false;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if (pLed->bLedBlinkInProgress == false &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ if (IS_LED_WPS_BLINKING(pLed))
+ return;
+ pLed->bLedBlinkInProgress = true;
+ pLed->CurrLedState = LED_TXRX_BLINK;
+ pLed->BlinkTimes = 2;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_START_WPS: /*wait until xinpin finish*/
+ case LED_CTL_START_WPS_BOTTON:
+ if (pLed->bLedWPSBlinkInProgress == false) {
+ if (pLed->bLedBlinkInProgress == true) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ pLed->bLedWPSBlinkInProgress = true;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if (pLed->bLedOn)
+ pLed->BlinkingLedState = LED_OFF;
+ else
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer),
+ LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+ case LED_CTL_STOP_WPS_FAIL:
+ case LED_CTL_STOP_WPS:
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ pLed->CurrLedState = LED_ON;
+ pLed->BlinkingLedState = LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_OFF;
+ if (pLed->bLedBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = false;
+ }
+ if (pLed->bLedWPSBlinkInProgress) {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = false;
+ }
+ SwLedOff(padapter, pLed);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Description:
+ * Dispatch LED action according to pHalData->LedStrategy.
+ */
+void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ if (ledpriv == NULL || ledpriv->bRegUseLed == false)
+ return;
+ switch (ledpriv->LedStrategy) {
+ case SW_LED_MODE0:
+ break;
+ case SW_LED_MODE1:
+ SwLedControlMode1(padapter, LedAction);
+ break;
+ case SW_LED_MODE2:
+ SwLedControlMode2(padapter, LedAction);
+ break;
+ case SW_LED_MODE3:
+ SwLedControlMode3(padapter, LedAction);
+ break;
+ case SW_LED_MODE4:
+ SwLedControlMode4(padapter, LedAction);
+ break;
+ case SW_LED_MODE5:
+ SwLedControlMode5(padapter, LedAction);
+ break;
+ case SW_LED_MODE6:
+ SwLedControlMode6(padapter, LedAction);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h
new file mode 100644
index 000000000000..74800cd2340d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h
@@ -0,0 +1,28 @@
+#ifndef __RTL8712_MACSETTING_BITDEF_H__
+#define __RTL8712_MACSETTING_BITDEF_H__
+
+
+/*MACID*/
+/*BSSID*/
+
+/*HWVID*/
+#define _HWVID_MSK 0x0F
+
+/*MAR*/
+/*MBIDCANCONTENT*/
+
+/*MBIDCANCFG*/
+#define _POOLING BIT(31)
+#define _WRITE_EN BIT(16)
+#define _CAM_ADDR_MSK 0x001F
+#define _CAM_ADDR_SHT 0
+
+/*BUILDTIME*/
+#define _BUILDTIME_MSK 0x3FFFFFFF
+
+/*BUILDUSER*/
+
+
+
+#endif /* __RTL8712_MACSETTING_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h
new file mode 100644
index 000000000000..00b003bd6900
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h
@@ -0,0 +1,16 @@
+#ifndef __RTL8712_MACSETTING_REGDEF_H__
+#define __RTL8712_MACSETTING_REGDEF_H__
+
+#define MACID (RTL8712_MACIDSETTING_ + 0x0000)
+#define BSSIDR (RTL8712_MACIDSETTING_ + 0x0008)
+#define HWVID (RTL8712_MACIDSETTING_ + 0x000E)
+#define MAR (RTL8712_MACIDSETTING_ + 0x0010)
+#define MBIDCANCONTENT (RTL8712_MACIDSETTING_ + 0x0018)
+#define MBIDCANCFG (RTL8712_MACIDSETTING_ + 0x0020)
+#define BUILDTIME (RTL8712_MACIDSETTING_ + 0x0024)
+#define BUILDUSER (RTL8712_MACIDSETTING_ + 0x0028)
+
+
+
+#endif /*__RTL8712_MACSETTING_REGDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h
new file mode 100644
index 000000000000..0922a8dc1322
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h
@@ -0,0 +1,33 @@
+#ifndef __RTL8712_POWERSAVE_BITDEF_H__
+#define __RTL8712_POWERSAVE_BITDEF_H__
+
+/*WOWCTRL*/
+#define _UWF BIT(3)
+#define _MAGIC BIT(2)
+#define _WOW_EN BIT(1)
+#define _PMEN BIT(0)
+
+/*PSSTATUS*/
+#define _PSSTATUS_SEL_MSK 0x0F
+
+/*PSSWITCH*/
+#define _PSSWITCH_ACT BIT(7)
+#define _PSSWITCH_SEL_MSK 0x0F
+#define _PSSWITCH_SEL_SHT 0
+
+/*LPNAV_CTRL*/
+#define _LPNAV_EN BIT(31)
+#define _LPNAV_EARLY_MSK 0x7FFF0000
+#define _LPNAV_EARLY_SHT 16
+#define _LPNAV_TH_MSK 0x0000FFFF
+#define _LPNAV_TH_SHT 0
+
+/*RPWM*/
+/*CPWM*/
+#define _TOGGLING BIT(7)
+#define _WWLAN BIT(3)
+#define _RPS_ST BIT(2)
+#define _WLAN_TRX BIT(1)
+#define _SYS_CLK BIT(0)
+
+#endif /* __RTL8712_POWERSAVE_BITDEF_H__*/
diff --git a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h
new file mode 100644
index 000000000000..72927df3db24
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h
@@ -0,0 +1,20 @@
+#ifndef __RTL8712_POWERSAVE_REGDEF_H__
+#define __RTL8712_POWERSAVE_REGDEF_H__
+
+#define WOWCTRL (RTL8712_POWERSAVE_ + 0x00)
+#define PSSTATUS (RTL8712_POWERSAVE_ + 0x01)
+#define PSSWITCH (RTL8712_POWERSAVE_ + 0x02)
+#define MIMOPS_WAITPERIOD (RTL8712_POWERSAVE_ + 0x03)
+#define LPNAV_CTRL (RTL8712_POWERSAVE_ + 0x04)
+#define WFM0 (RTL8712_POWERSAVE_ + 0x10)
+#define WFM1 (RTL8712_POWERSAVE_ + 0x20)
+#define WFM2 (RTL8712_POWERSAVE_ + 0x30)
+#define WFM3 (RTL8712_POWERSAVE_ + 0x40)
+#define WFM4 (RTL8712_POWERSAVE_ + 0x50)
+#define WFM5 (RTL8712_POWERSAVE_ + 0x60)
+#define WFCRC (RTL8712_POWERSAVE_ + 0x70)
+#define RPWM (RTL8712_POWERSAVE_ + 0x7C)
+#define CPWM (RTL8712_POWERSAVE_ + 0x7D)
+
+#endif /* __RTL8712_POWERSAVE_REGDEF_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h
new file mode 100644
index 000000000000..87048b3fe04f
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h
@@ -0,0 +1,30 @@
+#ifndef __RTL8712_RATECTRL_BITDEF_H__
+#define __RTL8712_RATECTRL_BITDEF_H__
+
+/*INIRTSMCS_SEL*/
+#define _INIRTSMCS_SEL_MSK 0x3F
+
+/* RRSR*/
+#define _RRSR_SHORT BIT(23)
+#define _RRSR_RSC_MSK 0x600000
+#define _RRSR_RSC_SHT 21
+#define _RRSR_BITMAP_MSK 0x0FFFFF
+#define _RRSR_BITMAP_SHT 0
+
+/* AGGLEN_LMT_H*/
+#define _AGGLMT_MCS32_MSK 0xF0
+#define _AGGLMT_MCS32_SHT 4
+#define _AGGLMT_MCS15_SGI_MSK 0x0F
+#define _AGGLMT_MCS15_SGI_SHT 0
+
+/* DARFRC*/
+/* RARFRC*/
+/* MCS_TXAGC*/
+/* CCK_TXAGC*/
+#define _CCK_MSK 0xFF00
+#define _CCK_SHT 8
+#define _BARKER_MSK 0x00FF
+#define _BARKER_SHT 0
+
+#endif /* __RTL8712_RATECTRL_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h
new file mode 100644
index 000000000000..31c8363e5bc6
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h
@@ -0,0 +1,31 @@
+#ifndef __RTL8712_RATECTRL_REGDEF_H__
+#define __RTL8712_RATECTRL_REGDEF_H__
+
+#define INIMCS_SEL (RTL8712_RATECTRL_ + 0x00)
+#define INIRTSMCS_SEL (RTL8712_RATECTRL_ + 0x20)
+#define RRSR (RTL8712_RATECTRL_ + 0x21)
+#define ARFR0 (RTL8712_RATECTRL_ + 0x24)
+#define ARFR1 (RTL8712_RATECTRL_ + 0x28)
+#define ARFR2 (RTL8712_RATECTRL_ + 0x2C)
+#define ARFR3 (RTL8712_RATECTRL_ + 0x30)
+#define ARFR4 (RTL8712_RATECTRL_ + 0x34)
+#define ARFR5 (RTL8712_RATECTRL_ + 0x38)
+#define ARFR6 (RTL8712_RATECTRL_ + 0x3C)
+#define ARFR7 (RTL8712_RATECTRL_ + 0x40)
+#define AGGLEN_LMT_H (RTL8712_RATECTRL_ + 0x47)
+#define AGGLEN_LMT_L (RTL8712_RATECTRL_ + 0x48)
+#define DARFRC (RTL8712_RATECTRL_ + 0x50)
+#define RARFRC (RTL8712_RATECTRL_ + 0x58)
+#define MCS_TXAGC0 (RTL8712_RATECTRL_ + 0x60)
+#define MCS_TXAGC1 (RTL8712_RATECTRL_ + 0x61)
+#define MCS_TXAGC2 (RTL8712_RATECTRL_ + 0x62)
+#define MCS_TXAGC3 (RTL8712_RATECTRL_ + 0x63)
+#define MCS_TXAGC4 (RTL8712_RATECTRL_ + 0x64)
+#define MCS_TXAGC5 (RTL8712_RATECTRL_ + 0x65)
+#define MCS_TXAGC6 (RTL8712_RATECTRL_ + 0x66)
+#define MCS_TXAGC7 (RTL8712_RATECTRL_ + 0x67)
+#define CCK_TXAGC (RTL8712_RATECTRL_ + 0x68)
+
+
+#endif /*__RTL8712_RATECTRL_REGDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
new file mode 100644
index 000000000000..569e14b599b4
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -0,0 +1,1131 @@
+/******************************************************************************
+ * rtl8712_recv.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL8712_RECV_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "mlme_osdep.h"
+#include "ip.h"
+#include "if_ether.h"
+#include "ethernet.h"
+#include "usb_ops.h"
+#include "wifi.h"
+
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+static u8 bridge_tunnel_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+static u8 rfc1042_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+
+static void recv_tasklet(void *priv);
+
+int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter)
+{
+ int i;
+ struct recv_buf *precvbuf;
+ int res = _SUCCESS;
+ addr_t tmpaddr = 0;
+ int alignment = 0;
+ struct sk_buff *pskb = NULL;
+
+ sema_init(&precvpriv->recv_sema, 0);
+ sema_init(&precvpriv->terminate_recvthread_sema, 0);
+ /*init recv_buf*/
+ _init_queue(&precvpriv->free_recv_buf_queue);
+ precvpriv->pallocated_recv_buf = _malloc(NR_RECVBUFF *
+ sizeof(struct recv_buf) + 4);
+ if (precvpriv->pallocated_recv_buf == NULL)
+ return _FAIL;
+ memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF *
+ sizeof(struct recv_buf) + 4);
+ precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 -
+ ((addr_t) (precvpriv->pallocated_recv_buf) & 3);
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+ for (i = 0; i < NR_RECVBUFF; i++) {
+ _init_listhead(&precvbuf->list);
+ spin_lock_init(&precvbuf->recvbuf_lock);
+ res = r8712_os_recvbuf_resource_alloc(padapter, precvbuf);
+ if (res == _FAIL)
+ break;
+ precvbuf->ref_cnt = 0;
+ precvbuf->adapter = padapter;
+ list_insert_tail(&precvbuf->list,
+ &(precvpriv->free_recv_buf_queue.queue));
+ precvbuf++;
+ }
+ precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
+ tasklet_init(&precvpriv->recv_tasklet,
+ (void(*)(unsigned long))recv_tasklet,
+ (unsigned long)padapter);
+ skb_queue_head_init(&precvpriv->rx_skb_queue);
+
+ skb_queue_head_init(&precvpriv->free_recv_skb_queue);
+ for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) {
+ pskb = netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ +
+ RECVBUFF_ALIGN_SZ);
+ if (pskb) {
+ pskb->dev = padapter->pnetdev;
+ tmpaddr = (addr_t)pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+ skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
+ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
+ }
+ pskb = NULL;
+ }
+ return res;
+}
+
+void r8712_free_recv_priv(struct recv_priv *precvpriv)
+{
+ int i;
+ struct recv_buf *precvbuf;
+ struct _adapter *padapter = precvpriv->adapter;
+
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+ for (i = 0; i < NR_RECVBUFF ; i++) {
+ r8712_os_recvbuf_resource_free(padapter, precvbuf);
+ precvbuf++;
+ }
+ kfree(precvpriv->pallocated_recv_buf);
+ skb_queue_purge(&precvpriv->rx_skb_queue);
+ if (skb_queue_len(&precvpriv->rx_skb_queue))
+ printk(KERN_WARNING "r8712u: rx_skb_queue not empty\n");
+ skb_queue_purge(&precvpriv->free_recv_skb_queue);
+ if (skb_queue_len(&precvpriv->free_recv_skb_queue))
+ printk(KERN_WARNING "r8712u: free_recv_skb_queue not empty "
+ "%d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
+}
+
+int r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf)
+{
+ int res = _SUCCESS;
+
+ precvbuf->transfer_len = 0;
+ precvbuf->len = 0;
+ precvbuf->ref_cnt = 0;
+ if (precvbuf->pbuf) {
+ precvbuf->pdata = precvbuf->pbuf;
+ precvbuf->phead = precvbuf->pbuf;
+ precvbuf->ptail = precvbuf->pbuf;
+ precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ;
+ }
+ return res;
+}
+
+int r8712_free_recvframe(union recv_frame *precvframe,
+ struct __queue *pfree_recv_queue)
+{
+ unsigned long irqL;
+ struct _adapter *padapter = precvframe->u.hdr.adapter;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ if (precvframe->u.hdr.pkt) {
+ dev_kfree_skb_any(precvframe->u.hdr.pkt);/*free skb by driver*/
+ precvframe->u.hdr.pkt = NULL;
+ }
+ spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
+ list_delete(&(precvframe->u.hdr.list));
+ list_insert_tail(&(precvframe->u.hdr.list),
+ get_list_head(pfree_recv_queue));
+ if (padapter != NULL) {
+ if (pfree_recv_queue == &precvpriv->free_recv_queue)
+ precvpriv->free_recvframe_cnt++;
+ }
+ spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL);
+ return _SUCCESS;
+}
+
+static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib,
+ struct recv_stat *prxstat)
+{
+ u32 *pphy_info;
+ struct phy_stat *pphy_stat;
+ u16 drvinfo_sz = 0;
+
+ drvinfo_sz = (le32_to_cpu(prxstat->rxdw0)&0x000f0000)>>16;
+ drvinfo_sz = drvinfo_sz<<3;
+ /*TODO:
+ * Offset 0 */
+ pattrib->bdecrypted = ((le32_to_cpu(prxstat->rxdw0) & BIT(27)) >> 27)
+ ? 0 : 1;
+ pattrib->crc_err = ((le32_to_cpu(prxstat->rxdw0) & BIT(14)) >> 14);
+ /*Offset 4*/
+ /*Offset 8*/
+ /*Offset 12*/
+ if (le32_to_cpu(prxstat->rxdw3) & BIT(13)) {
+ pattrib->tcpchk_valid = 1; /* valid */
+ if (le32_to_cpu(prxstat->rxdw3) & BIT(11))
+ pattrib->tcp_chkrpt = 1; /* correct */
+ else
+ pattrib->tcp_chkrpt = 0; /* incorrect */
+ if (le32_to_cpu(prxstat->rxdw3) & BIT(12))
+ pattrib->ip_chkrpt = 1; /* correct */
+ else
+ pattrib->ip_chkrpt = 0; /* incorrect */
+ } else
+ pattrib->tcpchk_valid = 0; /* invalid */
+ pattrib->mcs_rate = (u8)((le32_to_cpu(prxstat->rxdw3)) & 0x3f);
+ pattrib->htc = (u8)((le32_to_cpu(prxstat->rxdw3) >> 6) & 0x1);
+ /*Offset 16*/
+ /*Offset 20*/
+ /*phy_info*/
+ if (drvinfo_sz) {
+ pphy_stat = (struct phy_stat *)(prxstat+1);
+ pphy_info = (u32 *)prxstat+1;
+ }
+}
+
+/*perform defrag*/
+static union recv_frame *recvframe_defrag(struct _adapter *adapter,
+ struct __queue *defrag_q)
+{
+ struct list_head *plist, *phead;
+ u8 wlanhdr_offset;
+ u8 curfragnum;
+ struct recv_frame_hdr *pfhdr, *pnfhdr;
+ union recv_frame *prframe, *pnextrframe;
+ struct __queue *pfree_recv_queue;
+
+ pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
+ phead = get_list_head(defrag_q);
+ plist = get_next(phead);
+ prframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ list_delete(&prframe->u.list);
+ pfhdr = &prframe->u.hdr;
+ curfragnum = 0;
+ if (curfragnum != pfhdr->attrib.frag_num) {
+ /*the first fragment number must be 0
+ *free the whole queue*/
+ r8712_free_recvframe(prframe, pfree_recv_queue);
+ prframe = NULL;
+ goto exit;
+ }
+ plist = get_next(phead);
+ while (end_of_queue_search(phead, plist) == false) {
+ pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ /*check the fragment sequence (2nd ~n fragment frame) */
+ pnfhdr = &pnextrframe->u.hdr;
+ curfragnum++;
+ if (curfragnum != pnfhdr->attrib.frag_num) {
+ /* the fragment number must increase (after decache)
+ * release the defrag_q & prframe */
+ r8712_free_recvframe(prframe, pfree_recv_queue);
+ prframe = NULL;
+ goto exit;
+ }
+ /* copy the 2nd~n fragment frame's payload to the first fragment
+ * get the 2nd~last fragment frame's payload */
+ wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
+ recvframe_pull(pnextrframe, wlanhdr_offset);
+ /* append to first fragment frame's tail (if privacy frame,
+ * pull the ICV) */
+ recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
+ memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
+ recvframe_put(prframe, pnfhdr->len);
+ pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
+ plist = get_next(plist);
+ };
+exit:
+ /* free the defrag_q queue and return the prframe */
+ r8712_free_recvframe_queue(defrag_q, pfree_recv_queue);
+ return prframe;
+}
+
+/* check if need to defrag, if needed queue the frame to defrag_q */
+union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
+ union recv_frame *precv_frame)
+{
+ u8 ismfrag;
+ u8 fragnum;
+ u8 *psta_addr;
+ struct recv_frame_hdr *pfhdr;
+ struct sta_info *psta;
+ struct sta_priv *pstapriv ;
+ struct list_head *phead;
+ union recv_frame *prtnframe = NULL;
+ struct __queue *pfree_recv_queue, *pdefrag_q;
+
+ pstapriv = &padapter->stapriv;
+ pfhdr = &precv_frame->u.hdr;
+ pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
+ /* need to define struct of wlan header frame ctrl */
+ ismfrag = pfhdr->attrib.mfrag;
+ fragnum = pfhdr->attrib.frag_num;
+ psta_addr = pfhdr->attrib.ta;
+ psta = r8712_get_stainfo(pstapriv, psta_addr);
+ if (psta == NULL)
+ pdefrag_q = NULL;
+ else
+ pdefrag_q = &psta->sta_recvpriv.defrag_q;
+
+ if ((ismfrag == 0) && (fragnum == 0))
+ prtnframe = precv_frame;/*isn't a fragment frame*/
+ if (ismfrag == 1) {
+ /* 0~(n-1) fragment frame
+ * enqueue to defraf_g */
+ if (pdefrag_q != NULL) {
+ if (fragnum == 0) {
+ /*the first fragment*/
+ if (_queue_empty(pdefrag_q) == false) {
+ /*free current defrag_q */
+ r8712_free_recvframe_queue(pdefrag_q,
+ pfree_recv_queue);
+ }
+ }
+ /* Then enqueue the 0~(n-1) fragment to the defrag_q */
+ phead = get_list_head(pdefrag_q);
+ list_insert_tail(&pfhdr->list, phead);
+ prtnframe = NULL;
+ } else {
+ /* can't find this ta's defrag_queue, so free this
+ * recv_frame */
+ r8712_free_recvframe(precv_frame, pfree_recv_queue);
+ prtnframe = NULL;
+ }
+
+ }
+ if ((ismfrag == 0) && (fragnum != 0)) {
+ /* the last fragment frame
+ * enqueue the last fragment */
+ if (pdefrag_q != NULL) {
+ phead = get_list_head(pdefrag_q);
+ list_insert_tail(&pfhdr->list, phead);
+ /*call recvframe_defrag to defrag*/
+ precv_frame = recvframe_defrag(padapter, pdefrag_q);
+ prtnframe = precv_frame;
+ } else {
+ /* can't find this ta's defrag_queue, so free this
+ * recv_frame */
+ r8712_free_recvframe(precv_frame, pfree_recv_queue);
+ prtnframe = NULL;
+ }
+ }
+ if ((prtnframe != NULL) && (prtnframe->u.hdr.attrib.privacy)) {
+ /* after defrag we must check tkip mic code */
+ if (r8712_recvframe_chkmic(padapter, prtnframe) == _FAIL) {
+ r8712_free_recvframe(prtnframe, pfree_recv_queue);
+ prtnframe = NULL;
+ }
+ }
+ return prtnframe;
+}
+
+static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe)
+{
+ int a_len, padding_len;
+ u16 eth_type, nSubframe_Length;
+ u8 nr_subframes, i;
+ unsigned char *data_ptr, *pdata;
+ struct rx_pkt_attrib *pattrib;
+ _pkt *sub_skb, *subframes[MAX_SUBFRAME_COUNT];
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
+ int ret = _SUCCESS;
+
+ nr_subframes = 0;
+ pattrib = &prframe->u.hdr.attrib;
+ recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
+ if (prframe->u.hdr.attrib.iv_len > 0)
+ recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
+ a_len = prframe->u.hdr.len;
+ pdata = prframe->u.hdr.rx_data;
+ while (a_len > ETH_HLEN) {
+ /* Offset 12 denote 2 mac address */
+ nSubframe_Length = *((u16 *)(pdata + 12));
+ /*==m==>change the length order*/
+ nSubframe_Length = (nSubframe_Length >> 8) +
+ (nSubframe_Length << 8);
+ if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
+ printk(KERN_WARNING "r8712u: nRemain_Length is %d and"
+ " nSubframe_Length is: %d\n",
+ a_len, nSubframe_Length);
+ goto exit;
+ }
+ /* move the data point to data content */
+ pdata += ETH_HLEN;
+ a_len -= ETH_HLEN;
+ /* Allocate new skb for releasing to upper layer */
+ sub_skb = dev_alloc_skb(nSubframe_Length + 12);
+ skb_reserve(sub_skb, 12);
+ data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
+ memcpy(data_ptr, pdata, nSubframe_Length);
+ subframes[nr_subframes++] = sub_skb;
+ if (nr_subframes >= MAX_SUBFRAME_COUNT) {
+ printk(KERN_WARNING "r8712u: ParseSubframe(): Too"
+ " many Subframes! Packets dropped!\n");
+ break;
+ }
+ pdata += nSubframe_Length;
+ a_len -= nSubframe_Length;
+ if (a_len != 0) {
+ padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & 3);
+ if (padding_len == 4)
+ padding_len = 0;
+ if (a_len < padding_len)
+ goto exit;
+ pdata += padding_len;
+ a_len -= padding_len;
+ }
+ }
+ for (i = 0; i < nr_subframes; i++) {
+ sub_skb = subframes[i];
+ /* convert hdr + possible LLC headers into Ethernet header */
+ eth_type = (sub_skb->data[6] << 8) | sub_skb->data[7];
+ if (sub_skb->len >= 8 &&
+ ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) &&
+ eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
+ !memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) {
+ /* remove RFC1042 or Bridge-Tunnel encapsulation and
+ * replace EtherType */
+ skb_pull(sub_skb, SNAP_SIZE);
+ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src,
+ ETH_ALEN);
+ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst,
+ ETH_ALEN);
+ } else {
+ u16 len;
+ /* Leave Ethernet header part of hdr and full payload */
+ len = htons(sub_skb->len);
+ memcpy(skb_push(sub_skb, 2), &len, 2);
+ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src,
+ ETH_ALEN);
+ memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst,
+ ETH_ALEN);
+ }
+ /* Indicate the packets to upper layer */
+ if (sub_skb) {
+ sub_skb->protocol =
+ eth_type_trans(sub_skb, padapter->pnetdev);
+ sub_skb->dev = padapter->pnetdev;
+ if ((pattrib->tcpchk_valid == 1) &&
+ (pattrib->tcp_chkrpt == 1)) {
+ sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else
+ sub_skb->ip_summed = CHECKSUM_NONE;
+ netif_rx(sub_skb);
+ }
+ }
+exit:
+ prframe->u.hdr.len = 0;
+ r8712_free_recvframe(prframe, pfree_recv_queue);
+ return ret;
+}
+
+void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf)
+{
+ uint voffset;
+ u8 *poffset;
+ u16 pkt_len, cmd_len, drvinfo_sz;
+ u8 eid, cmd_seq;
+ struct recv_stat *prxstat;
+
+ poffset = (u8 *)prxcmdbuf;
+ voffset = *(uint *)poffset;
+ pkt_len = le32_to_cpu(voffset) & 0x00003fff;
+ prxstat = (struct recv_stat *)prxcmdbuf;
+ drvinfo_sz = ((le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16);
+ drvinfo_sz = drvinfo_sz << 3;
+ poffset += RXDESC_SIZE + drvinfo_sz;
+ do {
+ voffset = *(uint *)poffset;
+ cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff);
+ cmd_seq = (u8)((le32_to_cpu(voffset) >> 24) & 0x7f);
+ eid = (u8)((le32_to_cpu(voffset) >> 16) & 0xff);
+ r8712_event_handle(padapter, (uint *)poffset);
+ poffset += (cmd_len + 8);/*8 bytes aligment*/
+ } while (le32_to_cpu(voffset) & BIT(31));
+
+}
+
+static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl,
+ u16 seq_num)
+{
+ u8 wsize = preorder_ctrl->wsize_b;
+ u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) % 4096;
+
+ /* Rx Reorder initialize condition.*/
+ if (preorder_ctrl->indicate_seq == 0xffff)
+ preorder_ctrl->indicate_seq = seq_num;
+ /* Drop out the packet which SeqNum is smaller than WinStart */
+ if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
+ return false;
+ /*
+ * Sliding window manipulation. Conditions includes:
+ * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
+ * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
+ */
+ if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq))
+ preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq +
+ 1) % 4096;
+ else if (SN_LESS(wend, seq_num)) {
+ if (seq_num >= (wsize - 1))
+ preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
+ else
+ preorder_ctrl->indicate_seq = 4095 - (wsize -
+ (seq_num + 1)) + 1;
+ }
+ return true;
+}
+
+static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl,
+ union recv_frame *prframe)
+{
+ struct list_head *phead, *plist;
+ union recv_frame *pnextrframe;
+ struct rx_pkt_attrib *pnextattrib;
+ struct __queue *ppending_recvframe_queue =
+ &preorder_ctrl->pending_recvframe_queue;
+ struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
+
+ phead = get_list_head(ppending_recvframe_queue);
+ plist = get_next(phead);
+ while (end_of_queue_search(phead, plist) == false) {
+ pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ pnextattrib = &pnextrframe->u.hdr.attrib;
+ if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
+ plist = get_next(plist);
+ else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
+ return false;
+ else
+ break;
+ }
+ list_delete(&(prframe->u.hdr.list));
+ list_insert_tail(&(prframe->u.hdr.list), plist);
+ return true;
+}
+
+int r8712_recv_indicatepkts_in_order(struct _adapter *padapter,
+ struct recv_reorder_ctrl *preorder_ctrl,
+ int bforced)
+{
+ struct list_head *phead, *plist;
+ union recv_frame *prframe;
+ struct rx_pkt_attrib *pattrib;
+ int bPktInBuf = false;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+ struct __queue *ppending_recvframe_queue =
+ &preorder_ctrl->pending_recvframe_queue;
+
+ phead = get_list_head(ppending_recvframe_queue);
+ plist = get_next(phead);
+ /* Handling some condition for forced indicate case.*/
+ if (bforced == true) {
+ if (is_list_empty(phead))
+ return true;
+ else {
+ prframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ pattrib = &prframe->u.hdr.attrib;
+ preorder_ctrl->indicate_seq = pattrib->seq_num;
+ }
+ }
+ /* Prepare indication list and indication.
+ * Check if there is any packet need indicate. */
+ while (!is_list_empty(phead)) {
+ prframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ pattrib = &prframe->u.hdr.attrib;
+ if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
+ plist = get_next(plist);
+ list_delete(&(prframe->u.hdr.list));
+ if (SN_EQUAL(preorder_ctrl->indicate_seq,
+ pattrib->seq_num))
+ preorder_ctrl->indicate_seq =
+ (preorder_ctrl->indicate_seq + 1) % 4096;
+ /*indicate this recv_frame*/
+ if (!pattrib->amsdu) {
+ if ((padapter->bDriverStopped == false) &&
+ (padapter->bSurpriseRemoved == false)) {
+ /* indicate this recv_frame */
+ r8712_recv_indicatepkt(padapter,
+ prframe);
+ }
+ } else if (pattrib->amsdu == 1) {
+ if (amsdu_to_msdu(padapter, prframe) !=
+ _SUCCESS)
+ r8712_free_recvframe(prframe,
+ &precvpriv->free_recv_queue);
+ }
+ /* Update local variables. */
+ bPktInBuf = false;
+ } else {
+ bPktInBuf = true;
+ break;
+ }
+ }
+ return bPktInBuf;
+}
+
+static int recv_indicatepkt_reorder(struct _adapter *padapter,
+ union recv_frame *prframe)
+{
+ unsigned long irql;
+ struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
+ struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
+ struct __queue *ppending_recvframe_queue =
+ &preorder_ctrl->pending_recvframe_queue;
+
+ if (!pattrib->amsdu) {
+ /* s1. */
+ r8712_wlanhdr_to_ethhdr(prframe);
+ if (pattrib->qos != 1) {
+ if ((padapter->bDriverStopped == false) &&
+ (padapter->bSurpriseRemoved == false)) {
+ r8712_recv_indicatepkt(padapter, prframe);
+ return _SUCCESS;
+ } else
+ return _FAIL;
+ }
+ }
+ spin_lock_irqsave(&ppending_recvframe_queue->lock, irql);
+ /*s2. check if winstart_b(indicate_seq) needs to been updated*/
+ if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num))
+ goto _err_exit;
+ /*s3. Insert all packet into Reorder Queue to maintain its ordering.*/
+ if (!enqueue_reorder_recvframe(preorder_ctrl, prframe))
+ goto _err_exit;
+ /*s4.
+ * Indication process.
+ * After Packet dropping and Sliding Window shifting as above, we can
+ * now just indicate the packets with the SeqNum smaller than latest
+ * WinStart and buffer other packets.
+ *
+ * For Rx Reorder condition:
+ * 1. All packets with SeqNum smaller than WinStart => Indicate
+ * 2. All packets with SeqNum larger than or equal to
+ * WinStart => Buffer it.
+ */
+ if (r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, false) ==
+ true) {
+ _set_timer(&preorder_ctrl->reordering_ctrl_timer,
+ REORDER_WAIT_TIME);
+ spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql);
+ } else {
+ spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql);
+ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
+ }
+ return _SUCCESS;
+_err_exit:
+ spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql);
+ return _FAIL;
+}
+
+void r8712_reordering_ctrl_timeout_handler(void *pcontext)
+{
+ unsigned long irql;
+ struct recv_reorder_ctrl *preorder_ctrl =
+ (struct recv_reorder_ctrl *)pcontext;
+ struct _adapter *padapter = preorder_ctrl->padapter;
+ struct __queue *ppending_recvframe_queue =
+ &preorder_ctrl->pending_recvframe_queue;
+
+ if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
+ return;
+ spin_lock_irqsave(&ppending_recvframe_queue->lock, irql);
+ r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, true);
+ spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql);
+}
+
+static int r8712_process_recv_indicatepkts(struct _adapter *padapter,
+ union recv_frame *prframe)
+{
+ int retval = _SUCCESS;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+
+ if (phtpriv->ht_option == 1) { /*B/G/N Mode*/
+ if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
+ /* including perform A-MPDU Rx Ordering Buffer Control*/
+ if ((padapter->bDriverStopped == false) &&
+ (padapter->bSurpriseRemoved == false))
+ return _FAIL;
+ }
+ } else { /*B/G mode*/
+ retval = r8712_wlanhdr_to_ethhdr(prframe);
+ if (retval != _SUCCESS)
+ return retval;
+ if ((padapter->bDriverStopped == false) &&
+ (padapter->bSurpriseRemoved == false)) {
+ /* indicate this recv_frame */
+ r8712_recv_indicatepkt(padapter, prframe);
+ } else
+ return _FAIL;
+ }
+ return retval;
+}
+
+static u8 query_rx_pwr_percentage(s8 antpower)
+{
+ if ((antpower <= -100) || (antpower >= 20))
+ return 0;
+ else if (antpower >= 0)
+ return 100;
+ else
+ return 100 + antpower;
+}
+
+static u8 evm_db2percentage(s8 value)
+{
+ /*
+ * -33dB~0dB to 0%~99%
+ */
+ s8 ret_val;
+
+ ret_val = value;
+ if (ret_val >= 0)
+ ret_val = 0;
+ if (ret_val <= -33)
+ ret_val = -33;
+ ret_val = -ret_val;
+ ret_val *= 3;
+ if (ret_val == 99)
+ ret_val = 100;
+ return ret_val;
+}
+
+s32 r8712_signal_scale_mapping(s32 cur_sig)
+{
+ s32 ret_sig;
+
+ if (cur_sig >= 51 && cur_sig <= 100)
+ ret_sig = 100;
+ else if (cur_sig >= 41 && cur_sig <= 50)
+ ret_sig = 80 + ((cur_sig - 40) * 2);
+ else if (cur_sig >= 31 && cur_sig <= 40)
+ ret_sig = 66 + (cur_sig - 30);
+ else if (cur_sig >= 21 && cur_sig <= 30)
+ ret_sig = 54 + (cur_sig - 20);
+ else if (cur_sig >= 10 && cur_sig <= 20)
+ ret_sig = 42 + (((cur_sig - 10) * 2) / 3);
+ else if (cur_sig >= 5 && cur_sig <= 9)
+ ret_sig = 22 + (((cur_sig - 5) * 3) / 2);
+ else if (cur_sig >= 1 && cur_sig <= 4)
+ ret_sig = 6 + (((cur_sig - 1) * 3) / 2);
+ else
+ ret_sig = cur_sig;
+ return ret_sig;
+}
+
+static s32 translate2dbm(struct _adapter *padapter, u8 signal_strength_idx)
+{
+ s32 signal_power; /* in dBm.*/
+ /* Translate to dBm (x=0.5y-95).*/
+ signal_power = (s32)((signal_strength_idx + 1) >> 1);
+ signal_power -= 95;
+ return signal_power;
+}
+
+static void query_rx_phy_status(struct _adapter *padapter,
+ union recv_frame *prframe)
+{
+ u8 i, max_spatial_stream, evm;
+ struct recv_stat *prxstat = (struct recv_stat *)prframe->u.hdr.rx_head;
+ struct phy_stat *pphy_stat = (struct phy_stat *)(prxstat + 1);
+ u8 *pphy_head = (u8 *)(prxstat + 1);
+ s8 rx_pwr[4], rx_pwr_all;
+ u8 pwdb_all;
+ u32 rssi, total_rssi = 0;
+ u8 bcck_rate = 0, rf_rx_num = 0, cck_highpwr = 0;
+ struct phy_cck_rx_status *pcck_buf;
+ u8 sq;
+
+ /* Record it for next packet processing*/
+ bcck_rate = (prframe->u.hdr.attrib.mcs_rate <= 3 ? 1 : 0);
+ if (bcck_rate) {
+ u8 report;
+
+ /* CCK Driver info Structure is not the same as OFDM packet.*/
+ pcck_buf = (struct phy_cck_rx_status *)pphy_stat;
+ /* (1)Hardware does not provide RSSI for CCK
+ * (2)PWDB, Average PWDB cacluated by hardware
+ * (for rate adaptive)
+ */
+ if (!cck_highpwr) {
+ report = pcck_buf->cck_agc_rpt & 0xc0;
+ report = report >> 6;
+ switch (report) {
+ /* Modify the RF RNA gain value to -40, -20,
+ * -2, 14 by Jenyu's suggestion
+ * Note: different RF with the different
+ * RNA gain. */
+ case 0x3:
+ rx_pwr_all = -40 - (pcck_buf->cck_agc_rpt &
+ 0x3e);
+ break;
+ case 0x2:
+ rx_pwr_all = -20 - (pcck_buf->cck_agc_rpt &
+ 0x3e);
+ break;
+ case 0x1:
+ rx_pwr_all = -2 - (pcck_buf->cck_agc_rpt &
+ 0x3e);
+ break;
+ case 0x0:
+ rx_pwr_all = 14 - (pcck_buf->cck_agc_rpt &
+ 0x3e);
+ break;
+ }
+ } else {
+ report = ((u8)(le32_to_cpu(pphy_stat->phydw1) >> 8)) &
+ 0x60;
+ report = report >> 5;
+ switch (report) {
+ case 0x3:
+ rx_pwr_all = -40 - ((pcck_buf->cck_agc_rpt &
+ 0x1f) << 1);
+ break;
+ case 0x2:
+ rx_pwr_all = -20 - ((pcck_buf->cck_agc_rpt &
+ 0x1f) << 1);
+ break;
+ case 0x1:
+ rx_pwr_all = -2 - ((pcck_buf->cck_agc_rpt &
+ 0x1f) << 1);
+ break;
+ case 0x0:
+ rx_pwr_all = 14 - ((pcck_buf->cck_agc_rpt &
+ 0x1f) << 1);
+ break;
+ }
+ }
+ pwdb_all = query_rx_pwr_percentage(rx_pwr_all);
+ /* CCK gain is smaller than OFDM/MCS gain,*/
+ /* so we add gain diff by experiences, the val is 6 */
+ pwdb_all += 6;
+ if (pwdb_all > 100)
+ pwdb_all = 100;
+ /* modify the offset to make the same gain index with OFDM.*/
+ if (pwdb_all > 34 && pwdb_all <= 42)
+ pwdb_all -= 2;
+ else if (pwdb_all > 26 && pwdb_all <= 34)
+ pwdb_all -= 6;
+ else if (pwdb_all > 14 && pwdb_all <= 26)
+ pwdb_all -= 8;
+ else if (pwdb_all > 4 && pwdb_all <= 14)
+ pwdb_all -= 4;
+ /*
+ * (3) Get Signal Quality (EVM)
+ */
+ if (pwdb_all > 40)
+ sq = 100;
+ else {
+ sq = pcck_buf->sq_rpt;
+ if (pcck_buf->sq_rpt > 64)
+ sq = 0;
+ else if (pcck_buf->sq_rpt < 20)
+ sq = 100;
+ else
+ sq = ((64-sq) * 100) / 44;
+ }
+ prframe->u.hdr.attrib.signal_qual = sq;
+ prframe->u.hdr.attrib.rx_mimo_signal_qual[0] = sq;
+ prframe->u.hdr.attrib.rx_mimo_signal_qual[1] = -1;
+ } else {
+ /* (1)Get RSSI for HT rate */
+ for (i = 0; i < ((padapter->registrypriv.rf_config) &
+ 0x0f) ; i++) {
+ rf_rx_num++;
+ rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i]
+ & 0x3F) * 2) - 110;
+ /* Translate DBM to percentage. */
+ rssi = query_rx_pwr_percentage(rx_pwr[i]);
+ total_rssi += rssi;
+ }
+ /* (2)PWDB, Average PWDB cacluated by hardware (for
+ * rate adaptive) */
+ rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f)
+ - 106;
+ pwdb_all = query_rx_pwr_percentage(rx_pwr_all);
+
+ {
+ /* (3)EVM of HT rate */
+ if (prframe->u.hdr.attrib.htc &&
+ prframe->u.hdr.attrib.mcs_rate >= 20 &&
+ prframe->u.hdr.attrib.mcs_rate <= 27) {
+ /* both spatial stream make sense */
+ max_spatial_stream = 2;
+ } else {
+ /* only spatial stream 1 makes sense */
+ max_spatial_stream = 1;
+ }
+ for (i = 0; i < max_spatial_stream; i++) {
+ evm = evm_db2percentage((pphy_head
+ [PHY_STAT_RXEVM_SHT + i]));/*dbm*/
+ prframe->u.hdr.attrib.signal_qual =
+ (u8)(evm & 0xff);
+ prframe->u.hdr.attrib.rx_mimo_signal_qual[i] =
+ (u8)(evm & 0xff);
+ }
+ }
+ }
+ /* UI BSS List signal strength(in percentage), make it good looking,
+ * from 0~100. It is assigned to the BSS List in
+ * GetValueFromBeaconOrProbeRsp(). */
+ if (bcck_rate)
+ prframe->u.hdr.attrib.signal_strength =
+ (u8)r8712_signal_scale_mapping(pwdb_all);
+ else {
+ if (rf_rx_num != 0)
+ prframe->u.hdr.attrib.signal_strength =
+ (u8)(r8712_signal_scale_mapping(total_rssi /=
+ rf_rx_num));
+ }
+}
+
+static void process_link_qual(struct _adapter *padapter,
+ union recv_frame *prframe)
+{
+ u32 last_evm = 0, tmpVal;
+ struct rx_pkt_attrib *pattrib;
+
+ if (prframe == NULL || padapter == NULL)
+ return;
+ pattrib = &prframe->u.hdr.attrib;
+ if (pattrib->signal_qual != 0) {
+ /*
+ * 1. Record the general EVM to the sliding window.
+ */
+ if (padapter->recvpriv.signal_qual_data.total_num++ >=
+ PHY_LINKQUALITY_SLID_WIN_MAX) {
+ padapter->recvpriv.signal_qual_data.total_num =
+ PHY_LINKQUALITY_SLID_WIN_MAX;
+ last_evm = padapter->recvpriv.signal_qual_data.elements
+ [padapter->recvpriv.signal_qual_data.index];
+ padapter->recvpriv.signal_qual_data.total_val -=
+ last_evm;
+ }
+ padapter->recvpriv.signal_qual_data.total_val +=
+ pattrib->signal_qual;
+ padapter->recvpriv.signal_qual_data.elements[padapter->
+ recvpriv.signal_qual_data.index++] =
+ pattrib->signal_qual;
+ if (padapter->recvpriv.signal_qual_data.index >=
+ PHY_LINKQUALITY_SLID_WIN_MAX)
+ padapter->recvpriv.signal_qual_data.index = 0;
+
+ /* <1> Showed on UI for user, in percentage. */
+ tmpVal = padapter->recvpriv.signal_qual_data.total_val /
+ padapter->recvpriv.signal_qual_data.total_num;
+ padapter->recvpriv.signal = (u8)tmpVal;
+ }
+}
+
+static void process_rssi(struct _adapter *padapter, union recv_frame *prframe)
+{
+ u32 last_rssi, tmp_val;
+ struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
+
+ if (padapter->recvpriv.signal_strength_data.total_num++ >=
+ PHY_RSSI_SLID_WIN_MAX) {
+ padapter->recvpriv.signal_strength_data.total_num =
+ PHY_RSSI_SLID_WIN_MAX;
+ last_rssi = padapter->recvpriv.signal_strength_data.elements
+ [padapter->recvpriv.signal_strength_data.index];
+ padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
+ }
+ padapter->recvpriv.signal_strength_data.total_val +=
+ pattrib->signal_strength;
+ padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.
+ signal_strength_data.index++] =
+ pattrib->signal_strength;
+ if (padapter->recvpriv.signal_strength_data.index >=
+ PHY_RSSI_SLID_WIN_MAX)
+ padapter->recvpriv.signal_strength_data.index = 0;
+ tmp_val = padapter->recvpriv.signal_strength_data.total_val /
+ padapter->recvpriv.signal_strength_data.total_num;
+ padapter->recvpriv.rssi = (s8)translate2dbm(padapter, (u8)tmp_val);
+}
+
+static void process_phy_info(struct _adapter *padapter,
+ union recv_frame *prframe)
+{
+ query_rx_phy_status(padapter, prframe);
+ process_rssi(padapter, prframe);
+ process_link_qual(padapter, prframe);
+}
+
+int recv_func(struct _adapter *padapter, void *pcontext)
+{
+ struct rx_pkt_attrib *pattrib;
+ union recv_frame *prframe, *orig_prframe;
+ int retval = _SUCCESS;
+ struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ prframe = (union recv_frame *)pcontext;
+ orig_prframe = prframe;
+ pattrib = &prframe->u.hdr.attrib;
+ if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) {
+ if (pattrib->crc_err == 1)
+ padapter->mppriv.rx_crcerrpktcount++;
+ else
+ padapter->mppriv.rx_pktcount++;
+ if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == false) {
+ /* free this recv_frame */
+ r8712_free_recvframe(orig_prframe, pfree_recv_queue);
+ goto _exit_recv_func;
+ }
+ }
+ /* check the frame crtl field and decache */
+ retval = r8712_validate_recv_frame(padapter, prframe);
+ if (retval != _SUCCESS) {
+ /* free this recv_frame */
+ r8712_free_recvframe(orig_prframe, pfree_recv_queue);
+ goto _exit_recv_func;
+ }
+ process_phy_info(padapter, prframe);
+ prframe = r8712_decryptor(padapter, prframe);
+ if (prframe == NULL) {
+ retval = _FAIL;
+ goto _exit_recv_func;
+ }
+ prframe = r8712_recvframe_chk_defrag(padapter, prframe);
+ if (prframe == NULL)
+ goto _exit_recv_func;
+ prframe = r8712_portctrl(padapter, prframe);
+ if (prframe == NULL) {
+ retval = _FAIL;
+ goto _exit_recv_func;
+ }
+ retval = r8712_process_recv_indicatepkts(padapter, prframe);
+ if (retval != _SUCCESS) {
+ r8712_free_recvframe(orig_prframe, pfree_recv_queue);
+ goto _exit_recv_func;
+ }
+_exit_recv_func:
+ return retval;
+}
+
+static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
+{
+ u8 *pbuf, shift_sz = 0;
+ u8 frag, mf;
+ uint pkt_len;
+ u32 transfer_len;
+ struct recv_stat *prxstat;
+ u16 pkt_cnt, drvinfo_sz, pkt_offset, tmp_len, alloc_sz;
+ struct __queue *pfree_recv_queue;
+ _pkt *pkt_copy = NULL;
+ union recv_frame *precvframe = NULL;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ pfree_recv_queue = &(precvpriv->free_recv_queue);
+ pbuf = pskb->data;
+ prxstat = (struct recv_stat *)pbuf;
+ pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16)&0xff;
+ pkt_len = le32_to_cpu(prxstat->rxdw0)&0x00003fff;
+ transfer_len = pskb->len;
+ /* Test throughput with Netgear 3700 (No security) with Chariot 3T3R
+ * pairs. The packet count will be a big number so that the containing
+ * packet will effect the Rx reordering. */
+ if (transfer_len < pkt_len) {
+ /* In this case, it means the MAX_RECVBUF_SZ is too small to
+ * get the data from 8712u. */
+ return _FAIL;
+ }
+ do {
+ prxstat = (struct recv_stat *)pbuf;
+ pkt_len = le32_to_cpu(prxstat->rxdw0)&0x00003fff;
+ /* more fragment bit */
+ mf = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1;
+ /* ragmentation number */
+ frag = (le32_to_cpu(prxstat->rxdw2) >> 12) & 0xf;
+ /* uint 2^3 = 8 bytes */
+ drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16;
+ drvinfo_sz = drvinfo_sz<<3;
+ if (pkt_len <= 0)
+ goto _exit_recvbuf2recvframe;
+ /* Qos data, wireless lan header length is 26 */
+ if ((le32_to_cpu(prxstat->rxdw0) >> 23) & 0x01)
+ shift_sz = 2;
+ precvframe = r8712_alloc_recvframe(pfree_recv_queue);
+ if (precvframe == NULL)
+ goto _exit_recvbuf2recvframe;
+ _init_listhead(&precvframe->u.hdr.list);
+ precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/
+ precvframe->u.hdr.len = 0;
+ tmp_len = pkt_len + drvinfo_sz + RXDESC_SIZE;
+ pkt_offset = (u16)_RND128(tmp_len);
+ /* for first fragment packet, driver need allocate 1536 +
+ * drvinfo_sz + RXDESC_SIZE to defrag packet. */
+ if ((mf == 1) && (frag == 0))
+ alloc_sz = 1658;
+ else
+ alloc_sz = tmp_len;
+ /* 2 is for IP header 4 bytes alignment in QoS packet case.
+ * 4 is for skb->data 4 bytes alignment. */
+ alloc_sz += 6;
+ pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
+ if (pkt_copy) {
+ pkt_copy->dev = padapter->pnetdev;
+ precvframe->u.hdr.pkt = pkt_copy;
+ skb_reserve(pkt_copy, 4 - ((addr_t)(pkt_copy->data)
+ % 4));
+ skb_reserve(pkt_copy, shift_sz);
+ memcpy(pkt_copy->data, pbuf, tmp_len);
+ precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data =
+ precvframe->u.hdr.rx_tail = pkt_copy->data;
+ precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
+ } else {
+ precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
+ precvframe->u.hdr.rx_head = pbuf;
+ precvframe->u.hdr.rx_data = pbuf;
+ precvframe->u.hdr.rx_tail = pbuf;
+ precvframe->u.hdr.rx_end = pbuf + alloc_sz;
+ }
+ recvframe_put(precvframe, tmp_len);
+ recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
+ /* because the endian issue, driver avoid reference to the
+ * rxstat after calling update_recvframe_attrib_from_recvstat();
+ */
+ update_recvframe_attrib_from_recvstat(&precvframe->u.hdr.attrib,
+ prxstat);
+ r8712_recv_entry(precvframe);
+ transfer_len -= pkt_offset;
+ pbuf += pkt_offset;
+ pkt_cnt--;
+ precvframe = NULL;
+ pkt_copy = NULL;
+ } while ((transfer_len > 0) && pkt_cnt > 0);
+_exit_recvbuf2recvframe:
+ return _SUCCESS;
+}
+
+static void recv_tasklet(void *priv)
+{
+ struct sk_buff *pskb;
+ struct _adapter *padapter = (struct _adapter *)priv;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
+ recvbuf2recvframe(padapter, pskb);
+ skb_reset_tail_pointer(pskb);
+ pskb->len = 0;
+ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
+ }
+}
diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h
new file mode 100644
index 000000000000..4ba52b9c1697
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_recv.h
@@ -0,0 +1,128 @@
+#ifndef _RTL8712_RECV_H_
+#define _RTL8712_RECV_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+#define NR_RECVBUFF (8)
+#define NR_PREALLOC_RECV_SKB (8)
+#define RXDESC_SIZE 24
+#define RXDESC_OFFSET RXDESC_SIZE
+#define RECV_BLK_SZ 512
+#define RECV_BLK_CNT 16
+#define RECV_BLK_TH RECV_BLK_CNT
+#define MAX_RECVBUF_SZ (30720) /* 30K */
+#define RECVBUFF_ALIGN_SZ 512
+#define RSVD_ROOM_SZ (0)
+/*These definition is used for Rx packet reordering.*/
+#define SN_LESS(a, b) (((a-b) & 0x800) != 0)
+#define SN_EQUAL(a, b) (a == b)
+#define REORDER_WAIT_TIME 30 /* (ms)*/
+
+struct recv_stat {
+ unsigned int rxdw0;
+ unsigned int rxdw1;
+ unsigned int rxdw2;
+ unsigned int rxdw3;
+ unsigned int rxdw4;
+ unsigned int rxdw5;
+};
+
+struct phy_cck_rx_status {
+ /* For CCK rate descriptor. This is a unsigned 8:1 variable.
+ * LSB bit present 0.5. And MSB 7 bts present a signed value.
+ * Range from -64~+63.5. */
+ u8 adc_pwdb_X[4];
+ u8 sq_rpt;
+ u8 cck_agc_rpt;
+};
+
+struct phy_stat {
+ unsigned int phydw0;
+ unsigned int phydw1;
+ unsigned int phydw2;
+ unsigned int phydw3;
+ unsigned int phydw4;
+ unsigned int phydw5;
+ unsigned int phydw6;
+ unsigned int phydw7;
+};
+#define PHY_STAT_GAIN_TRSW_SHT 0
+#define PHY_STAT_PWDB_ALL_SHT 4
+#define PHY_STAT_CFOSHO_SHT 5
+#define PHY_STAT_CCK_AGC_RPT_SHT 5
+#define PHY_STAT_CFOTAIL_SHT 9
+#define PHY_STAT_RXEVM_SHT 13
+#define PHY_STAT_RXSNR_SHT 15
+#define PHY_STAT_PDSNR_SHT 19
+#define PHY_STAT_CSI_CURRENT_SHT 21
+#define PHY_STAT_CSI_TARGET_SHT 23
+#define PHY_STAT_SIGEVM_SHT 25
+#define PHY_STAT_MAX_EX_PWR_SHT 26
+
+union recvstat {
+ struct recv_stat recv_stat;
+ unsigned int value[RXDESC_SIZE>>2];
+};
+
+
+struct recv_buf {
+ struct list_head list;
+ spinlock_t recvbuf_lock;
+ u32 ref_cnt;
+ struct _adapter *adapter;
+ struct urb *purb;
+ _pkt *pskb;
+ u8 reuse;
+ u8 irp_pending;
+ u32 transfer_len;
+ uint len;
+ u8 *phead;
+ u8 *pdata;
+ u8 *ptail;
+ u8 *pend;
+ u8 *pbuf;
+ u8 *pallocated_buf;
+};
+
+/*
+ head ----->
+ data ----->
+ payload
+ tail ----->
+ end ----->
+ len = (unsigned int )(tail - data);
+*/
+struct recv_frame_hdr{
+ struct list_head list;
+ _pkt *pkt;
+ _pkt *pkt_newalloc;
+ struct _adapter *adapter;
+ u8 fragcnt;
+ struct rx_pkt_attrib attrib;
+ uint len;
+ u8 *rx_head;
+ u8 *rx_data;
+ u8 *rx_tail;
+ u8 *rx_end;
+ void *precvbuf;
+ struct sta_info *psta;
+ /*for A-MPDU Rx reordering buffer control*/
+ struct recv_reorder_ctrl *preorder_ctrl;
+};
+
+union recv_frame {
+ union {
+ struct list_head list;
+ struct recv_frame_hdr hdr;
+ addr_t mem[RECVFRAME_HDR_ALIGN>>2];
+ } u;
+};
+
+int r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf);
+void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf);
+s32 r8712_signal_scale_mapping(s32 cur_sig);
+void r8712_reordering_ctrl_timeout_handler(void *pcontext);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl8712_regdef.h b/drivers/staging/rtl8712/rtl8712_regdef.h
new file mode 100644
index 000000000000..5b0de2ab6b61
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_regdef.h
@@ -0,0 +1,19 @@
+#ifndef __RTL8712_REGDEF_H__
+#define __RTL8712_REGDEF_H__
+
+#include "rtl8712_syscfg_regdef.h"
+#include "rtl8712_cmdctrl_regdef.h"
+#include "rtl8712_macsetting_regdef.h"
+#include "rtl8712_timectrl_regdef.h"
+#include "rtl8712_fifoctrl_regdef.h"
+#include "rtl8712_ratectrl_regdef.h"
+#include "rtl8712_edcasetting_regdef.h"
+#include "rtl8712_wmac_regdef.h"
+#include "rtl8712_powersave_regdef.h"
+#include "rtl8712_gp_regdef.h"
+#include "rtl8712_debugctrl_regdef.h"
+
+#define HIMR (RTL8712_INTERRUPT_ + 0x08)
+
+#endif /* __RTL8712_REGDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_security_bitdef.h b/drivers/staging/rtl8712/rtl8712_security_bitdef.h
new file mode 100644
index 000000000000..8df4bf4a0699
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_security_bitdef.h
@@ -0,0 +1,29 @@
+#ifndef __RTL8712_SECURITY_BITDEF_H__
+#define __RTL8712_SECURITY_BITDEF_H__
+
+/*CAMCMD*/
+#define _SECCAM_POLLING BIT(31)
+#define _SECCAM_CLR BIT(30)
+#define _SECCAM_WE BIT(16)
+#define _SECCAM_ADR_MSK 0x000000FF
+#define _SECCAM_ADR_SHT 0
+
+/*CAMDBG*/
+#define _SECCAM_INFO BIT(31)
+#define _SEC_KEYFOUND BIT(30)
+#define _SEC_CONFIG_MSK 0x3F000000
+#define _SEC_CONFIG_SHT 24
+#define _SEC_KEYCONTENT_MSK 0x00FFFFFF
+#define _SEC_KEYCONTENT_SHT 0
+
+/*SECCFG*/
+#define _NOSKMC BIT(5)
+#define _SKBYA2 BIT(4)
+#define _RXDEC BIT(3)
+#define _TXENC BIT(2)
+#define _RXUSEDK BIT(1)
+#define _TXUSEDK BIT(0)
+
+
+#endif /*__RTL8712_SECURITY_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_spec.h b/drivers/staging/rtl8712/rtl8712_spec.h
new file mode 100644
index 000000000000..3f181eed4ee9
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_spec.h
@@ -0,0 +1,110 @@
+#ifndef __RTL8712_SPEC_H__
+#define __RTL8712_SPEC_H__
+
+#define RTL8712_IOBASE_TXPKT 0x10200000 /*IOBASE_TXPKT*/
+#define RTL8712_IOBASE_RXPKT 0x10210000 /*IOBASE_RXPKT*/
+#define RTL8712_IOBASE_RXCMD 0x10220000 /*IOBASE_RXCMD*/
+#define RTL8712_IOBASE_TXSTATUS 0x10230000 /*IOBASE_TXSTATUS*/
+#define RTL8712_IOBASE_RXSTATUS 0x10240000 /*IOBASE_RXSTATUS*/
+#define RTL8712_IOBASE_IOREG 0x10250000 /*IOBASE_IOREG ADDR*/
+#define RTL8712_IOBASE_SCHEDULER 0x10260000 /*IOBASE_SCHEDULE*/
+
+#define RTL8712_IOBASE_TRXDMA 0x10270000 /*IOBASE_TRXDMA*/
+#define RTL8712_IOBASE_TXLLT 0x10280000 /*IOBASE_TXLLT*/
+#define RTL8712_IOBASE_WMAC 0x10290000 /*IOBASE_WMAC*/
+#define RTL8712_IOBASE_FW2HW 0x102A0000 /*IOBASE_FW2HW*/
+#define RTL8712_IOBASE_ACCESS_PHYREG 0x102B0000 /*IOBASE_ACCESS_PHYREG*/
+
+#define RTL8712_IOBASE_FF 0x10300000 /*IOBASE_FIFO 0x1031000~0x103AFFFF*/
+
+
+/*IOREG Offset for 8712*/
+#define RTL8712_SYSCFG_ RTL8712_IOBASE_IOREG
+#define RTL8712_CMDCTRL_ (RTL8712_IOBASE_IOREG + 0x40)
+#define RTL8712_MACIDSETTING_ (RTL8712_IOBASE_IOREG + 0x50)
+#define RTL8712_TIMECTRL_ (RTL8712_IOBASE_IOREG + 0x80)
+#define RTL8712_FIFOCTRL_ (RTL8712_IOBASE_IOREG + 0xA0)
+#define RTL8712_RATECTRL_ (RTL8712_IOBASE_IOREG + 0x160)
+#define RTL8712_EDCASETTING_ (RTL8712_IOBASE_IOREG + 0x1D0)
+#define RTL8712_WMAC_ (RTL8712_IOBASE_IOREG + 0x200)
+#define RTL8712_SECURITY_ (RTL8712_IOBASE_IOREG + 0x240)
+#define RTL8712_POWERSAVE_ (RTL8712_IOBASE_IOREG + 0x260)
+#define RTL8712_GP_ (RTL8712_IOBASE_IOREG + 0x2E0)
+#define RTL8712_INTERRUPT_ (RTL8712_IOBASE_IOREG + 0x300)
+#define RTL8712_DEBUGCTRL_ (RTL8712_IOBASE_IOREG + 0x310)
+#define RTL8712_OFFLOAD_ (RTL8712_IOBASE_IOREG + 0x2D0)
+
+
+/*FIFO for 8712*/
+#define RTL8712_DMA_BCNQ (RTL8712_IOBASE_FF + 0x10000)
+#define RTL8712_DMA_MGTQ (RTL8712_IOBASE_FF + 0x20000)
+#define RTL8712_DMA_BMCQ (RTL8712_IOBASE_FF + 0x30000)
+#define RTL8712_DMA_VOQ (RTL8712_IOBASE_FF + 0x40000)
+#define RTL8712_DMA_VIQ (RTL8712_IOBASE_FF + 0x50000)
+#define RTL8712_DMA_BEQ (RTL8712_IOBASE_FF + 0x60000)
+#define RTL8712_DMA_BKQ (RTL8712_IOBASE_FF + 0x70000)
+#define RTL8712_DMA_RX0FF (RTL8712_IOBASE_FF + 0x80000)
+#define RTL8712_DMA_H2CCMD (RTL8712_IOBASE_FF + 0x90000)
+#define RTL8712_DMA_C2HCMD (RTL8712_IOBASE_FF + 0xA0000)
+
+
+/*------------------------------*/
+
+/*BIT 16 15*/
+#define DID_SDIO_LOCAL 0 /* 0 0*/
+#define DID_WLAN_IOREG 1 /* 0 1*/
+#define DID_WLAN_FIFO 3 /* 1 1*/
+#define DID_UNDEFINE (-1)
+
+#define CMD_ADDR_MAPPING_SHIFT 2 /*SDIO CMD ADDR MAPPING,
+ *shift 2 bit for match
+ * offset[14:2]*/
+
+/*Offset for SDIO LOCAL*/
+#define OFFSET_SDIO_LOCAL 0x0FFF
+
+/*Offset for WLAN IOREG*/
+#define OFFSET_WLAN_IOREG 0x0FFF
+
+/*Offset for WLAN FIFO*/
+#define OFFSET_TX_BCNQ 0x0300
+#define OFFSET_TX_HIQ 0x0310
+#define OFFSET_TX_CMDQ 0x0320
+#define OFFSET_TX_MGTQ 0x0330
+#define OFFSET_TX_HCCAQ 0x0340
+#define OFFSET_TX_VOQ 0x0350
+#define OFFSET_TX_VIQ 0x0360
+#define OFFSET_TX_BEQ 0x0370
+#define OFFSET_TX_BKQ 0x0380
+#define OFFSET_RX_RX0FFQ 0x0390
+#define OFFSET_RX_C2HFFQ 0x03A0
+
+#define BK_QID_01 1
+#define BK_QID_02 2
+#define BE_QID_01 0
+#define BE_QID_02 3
+#define VI_QID_01 4
+#define VI_QID_02 5
+#define VO_QID_01 6
+#define VO_QID_02 7
+#define HCCA_QID_01 8
+#define HCCA_QID_02 9
+#define HCCA_QID_03 10
+#define HCCA_QID_04 11
+#define HCCA_QID_05 12
+#define HCCA_QID_06 13
+#define HCCA_QID_07 14
+#define HCCA_QID_08 15
+#define HI_QID 17
+#define CMD_QID 19
+#define MGT_QID 18
+#define BCN_QID 16
+
+#include "rtl8712_regdef.h"
+
+#include "rtl8712_bitdef.h"
+
+#include "basic_types.h"
+
+#endif /* __RTL8712_SPEC_H__ */
+
diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
new file mode 100644
index 000000000000..dce15c2ff503
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
@@ -0,0 +1,145 @@
+#ifndef __RTL8712_SYSCFG_BITDEF_H__
+#define __RTL8712_SYSCFG_BITDEF_H__
+
+/*SYS_PWR_CTRL*/
+/*SRCTRL0*/
+/*SRCTRL1*/
+/*SYS_CLKR*/
+
+/*SYS_IOS_CTRL*/
+#define iso_LDR2RP_SHT 8 /* EE Loader to Retention Path*/
+#define iso_LDR2RP BIT(iso_LDR2RP_SHT) /* 1:isolation, 0:attach*/
+
+/*SYS_CTRL*/
+#define FEN_DIO_SDIO_SHT 0
+#define FEN_DIO_SDIO BIT(FEN_DIO_SDIO_SHT)
+#define FEN_SDIO_SHT 1
+#define FEN_SDIO BIT(FEN_SDIO_SHT)
+#define FEN_USBA_SHT 2
+#define FEN_USBA BIT(FEN_USBA_SHT)
+#define FEN_UPLL_SHT 3
+#define FEN_UPLL BIT(FEN_UPLL_SHT)
+#define FEN_USBD_SHT 4
+#define FEN_USBD BIT(FEN_USBD_SHT)
+#define FEN_DIO_PCIE_SHT 5
+#define FEN_DIO_PCIE BIT(FEN_DIO_PCIE_SHT)
+#define FEN_PCIEA_SHT 6
+#define FEN_PCIEA BIT(FEN_PCIEA_SHT)
+#define FEN_PPLL_SHT 7
+#define FEN_PPLL BIT(FEN_PPLL_SHT)
+#define FEN_PCIED_SHT 8
+#define FEN_PCIED BIT(FEN_PCIED_SHT)
+#define FEN_CPUEN_SHT 10
+#define FEN_CPUEN BIT(FEN_CPUEN_SHT)
+#define FEN_DCORE_SHT 11
+#define FEN_DCORE BIT(FEN_DCORE_SHT)
+#define FEN_ELDR_SHT 12
+#define FEN_ELDR BIT(FEN_ELDR_SHT)
+#define PWC_DV2LDR_SHT 13
+#define PWC_DV2LDR BIT(PWC_DV2LDR_SHT) /* Loader Power Enable*/
+
+/*=== SYS_CLKR ===*/
+#define SYS_CLKSEL_SHT 0
+#define SYS_CLKSEL BIT(SYS_CLKSEL_SHT) /* System Clock 80MHz*/
+#define PS_CLKSEL_SHT 1
+#define PS_CLKSEL BIT(PS_CLKSEL_SHT) /*System power save
+ * clock select.*/
+#define CPU_CLKSEL_SHT 2
+#define CPU_CLKSEL BIT(CPU_CLKSEL_SHT) /* System Clock select,
+ * 1: AFE source,
+ * 0: System clock(L-Bus)*/
+#define INT32K_EN_SHT 3
+#define INT32K_EN BIT(INT32K_EN_SHT)
+#define MACSLP_SHT 4
+#define MACSLP BIT(MACSLP_SHT)
+#define MAC_CLK_EN_SHT 11
+#define MAC_CLK_EN BIT(MAC_CLK_EN_SHT) /* MAC Clock Enable.*/
+#define SYS_CLK_EN_SHT 12
+#define SYS_CLK_EN BIT(SYS_CLK_EN_SHT)
+#define RING_CLK_EN_SHT 13
+#define RING_CLK_EN BIT(RING_CLK_EN_SHT)
+#define SWHW_SEL_SHT 14
+#define SWHW_SEL BIT(SWHW_SEL_SHT) /* Load done,
+ * control path switch.*/
+#define FWHW_SEL_SHT 15
+#define FWHW_SEL BIT(FWHW_SEL_SHT) /* Sleep exit,
+ * control path switch.*/
+
+/*9346CR*/
+#define _VPDIDX_MSK 0xFF00
+#define _VPDIDX_SHT 8
+#define _EEM_MSK 0x00C0
+#define _EEM_SHT 6
+#define _EEM0 BIT(6)
+#define _EEM1 BIT(7)
+#define _EEPROM_EN BIT(5)
+#define _9356SEL BIT(4)
+#define _EECS BIT(3)
+#define _EESK BIT(2)
+#define _EEDI BIT(1)
+#define _EEDO BIT(0)
+
+/*AFE_MISC*/
+#define AFE_MISC_USB_MBEN_SHT 7
+#define AFE_MISC_USB_MBEN BIT(AFE_MISC_USB_MBEN_SHT)
+#define AFE_MISC_USB_BGEN_SHT 6
+#define AFE_MISC_USB_BGEN BIT(AFE_MISC_USB_BGEN_SHT)
+#define AFE_MISC_LD12_VDAJ_SHT 4
+#define AFE_MISC_LD12_VDAJ_MSK 0X0030
+#define AFE_MISC_LD12_VDAJ BIT(AFE_MISC_LD12_VDAJ_SHT)
+#define AFE_MISC_I32_EN_SHT 3
+#define AFE_MISC_I32_EN BIT(AFE_MISC_I32_EN_SHT)
+#define AFE_MISC_E32_EN_SHT 2
+#define AFE_MISC_E32_EN BIT(AFE_MISC_E32_EN_SHT)
+#define AFE_MISC_MBEN_SHT 1
+#define AFE_MISC_MBEN BIT(AFE_MISC_MBEN_SHT)/* Enable AFE Macro
+ * Block's Mbias.*/
+#define AFE_MISC_BGEN_SHT 0
+#define AFE_MISC_BGEN BIT(AFE_MISC_BGEN_SHT)/* Enable AFE Macro
+ * Block's Bandgap.*/
+
+
+/*--------------------------------------------------------------------------*/
+/* SPS1_CTRL bits (Offset 0x18-1E, 56bits)*/
+/*--------------------------------------------------------------------------*/
+#define SPS1_SWEN BIT(1) /* Enable vsps18 SW Macro Block.*/
+#define SPS1_LDEN BIT(0) /* Enable VSPS12 LDO Macro block.*/
+
+
+/*----------------------------------------------------------------------------*/
+/* LDOA15_CTRL bits (Offset 0x20, 8bits)*/
+/*----------------------------------------------------------------------------*/
+#define LDA15_EN BIT(0) /* Enable LDOA15 Macro Block*/
+
+
+/*----------------------------------------------------------------------------*/
+/* 8192S LDOV12D_CTRL bit (Offset 0x21, 8bits)*/
+/*----------------------------------------------------------------------------*/
+#define LDV12_EN BIT(0) /* Enable LDOVD12 Macro Block*/
+#define LDV12_SDBY BIT(1) /* LDOVD12 standby mode*/
+
+/*CLK_PS_CTRL*/
+#define _CLK_GATE_EN BIT(0)
+
+
+/* EFUSE_CTRL*/
+#define EF_FLAG BIT(31) /* Access Flag, Write:1;
+ * Read:0*/
+#define EF_PGPD 0x70000000 /* E-fuse Program time*/
+#define EF_RDT 0x0F000000 /* E-fuse read time: in the
+ * unit of cycle time*/
+#define EF_PDN_EN BIT(19) /* EFuse Power down enable*/
+#define ALD_EN BIT(18) /* Autoload Enable*/
+#define EF_ADDR 0x0003FF00 /* Access Address*/
+#define EF_DATA 0x000000FF /* Access Data*/
+
+/* EFUSE_TEST*/
+#define LDOE25_EN BIT(31) /* Enable LDOE25 Macro Block*/
+
+/* EFUSE_CLK_CTRL*/
+#define EFUSE_CLK_EN BIT(1) /* E-Fuse Clock Enable*/
+#define EFUSE_CLK_SEL BIT(0) /* E-Fuse Clock Select,
+ * 0:500K, 1:40M*/
+
+#endif /*__RTL8712_SYSCFG_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h
new file mode 100644
index 000000000000..687e1b7a03f5
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h
@@ -0,0 +1,31 @@
+#ifndef __RTL8712_SYSCFG_REGDEF_H__
+#define __RTL8712_SYSCFG_REGDEF_H__
+
+
+#define SYS_ISO_CTRL (RTL8712_SYSCFG_ + 0x0000)
+#define SYS_FUNC_EN (RTL8712_SYSCFG_ + 0x0002)
+#define PMC_FSM (RTL8712_SYSCFG_ + 0x0004)
+#define SYS_CLKR (RTL8712_SYSCFG_ + 0x0008)
+#define EE_9346CR (RTL8712_SYSCFG_ + 0x000A)
+#define EE_VPD (RTL8712_SYSCFG_ + 0x000C)
+#define AFE_MISC (RTL8712_SYSCFG_ + 0x0010)
+#define SPS0_CTRL (RTL8712_SYSCFG_ + 0x0011)
+#define SPS1_CTRL (RTL8712_SYSCFG_ + 0x0018)
+#define RF_CTRL (RTL8712_SYSCFG_ + 0x001F)
+#define LDOA15_CTRL (RTL8712_SYSCFG_ + 0x0020)
+#define LDOV12D_CTRL (RTL8712_SYSCFG_ + 0x0021)
+#define LDOHCI12_CTRL (RTL8712_SYSCFG_ + 0x0022)
+#define LDO_USB_CTRL (RTL8712_SYSCFG_ + 0x0023)
+#define LPLDO_CTRL (RTL8712_SYSCFG_ + 0x0024)
+#define AFE_XTAL_CTRL (RTL8712_SYSCFG_ + 0x0026)
+#define AFE_PLL_CTRL (RTL8712_SYSCFG_ + 0x0028)
+#define EFUSE_CTRL (RTL8712_SYSCFG_ + 0x0030)
+#define EFUSE_TEST (RTL8712_SYSCFG_ + 0x0034)
+#define PWR_DATA (RTL8712_SYSCFG_ + 0x0038)
+#define DPS_TIMER (RTL8712_SYSCFG_ + 0x003C)
+#define RCLK_MON (RTL8712_SYSCFG_ + 0x003E)
+#define EFUSE_CLK_CTRL (RTL8712_SYSCFG_ + 0x02F8)
+
+
+#endif /*__RTL8712_SYSCFG_REGDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h
new file mode 100644
index 000000000000..32ce9fab5dbe
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h
@@ -0,0 +1,44 @@
+#ifndef __RTL8712_TIMECTRL_BITDEF_H__
+#define __RTL8712_TIMECTRL_BITDEF_H__
+
+/*TSFTR*/
+/*SLOT*/
+/*USTIME*/
+
+/*TUBASE*/
+#define _TUBASE_MSK 0x07FF
+
+/*SIFS_CCK*/
+#define _SIFS_CCK_TRX_MSK 0xFF00
+#define _SIFS_CCK_TRX_SHT 0x8
+#define _SIFS_CCK_CTX_MSK 0x00FF
+#define _SIFS_CCK_CTX_SHT 0
+
+/*SIFS_OFDM*/
+#define _SIFS_OFDM_TRX_MSK 0xFF00
+#define _SIFS_OFDM_TRX_SHT 0x8
+#define _SIFS_OFDM_CTX_MSK 0x00FF
+#define _SIFS_OFDM_CTX_SHT 0
+
+/*PIFS*/
+/*ACKTO*/
+/*EIFS*/
+/*BCNITV*/
+/*ATIMWND*/
+
+/*DRVERLYINT*/
+#define _ENSWBCN BIT(15)
+#define _DRVERLY_TU_MSK 0x0FF0
+#define _DRVERLY_TU_SHT 4
+#define _DRVERLY_US_MSK 0x000F
+#define _DRVERLY_US_SHT 0
+
+/*BCNDMATIM*/
+#define _BCNDMATIM_MSK 0x03FF
+
+/*BCNERRTH*/
+/*MLT*/
+
+
+#endif /* __RTL8712_TIMECTRL_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h
new file mode 100644
index 000000000000..8a3dd562ba89
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h
@@ -0,0 +1,20 @@
+#ifndef __RTL8712_TIMECTRL_REGDEF_H__
+#define __RTL8712_TIMECTRL_REGDEF_H__
+
+#define TSFTR (RTL8712_TIMECTRL_ + 0x00)
+#define USTIME (RTL8712_TIMECTRL_ + 0x08)
+#define SLOT (RTL8712_TIMECTRL_ + 0x09)
+#define TUBASE (RTL8712_TIMECTRL_ + 0x0A)
+#define SIFS_CCK (RTL8712_TIMECTRL_ + 0x0C)
+#define SIFS_OFDM (RTL8712_TIMECTRL_ + 0x0E)
+#define PIFS (RTL8712_TIMECTRL_ + 0x10)
+#define ACKTO (RTL8712_TIMECTRL_ + 0x11)
+#define EIFS (RTL8712_TIMECTRL_ + 0x12)
+#define BCNITV (RTL8712_TIMECTRL_ + 0x14)
+#define ATIMWND (RTL8712_TIMECTRL_ + 0x16)
+#define DRVERLYINT (RTL8712_TIMECTRL_ + 0x18)
+#define BCNDMATIM (RTL8712_TIMECTRL_ + 0x1A)
+#define BCNERRTH (RTL8712_TIMECTRL_ + 0x1C)
+#define MLT (RTL8712_TIMECTRL_ + 0x1D)
+
+#endif /* __RTL8712_TIMECTRL_REGDEF_H__ */
diff --git a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h
new file mode 100644
index 000000000000..6d3be2a24226
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h
@@ -0,0 +1,37 @@
+#ifndef __RTL8712_WMAC_BITDEF_H__
+#define __RTL8712_WMAC_BITDEF_H__
+
+/*NAVCTRL*/
+#define _NAV_UPPER_EN BIT(18)
+#define _NAV_MTO_EN BIT(17)
+#define _NAV_UPPER BIT(16)
+#define _NAV_MTO_MSK 0xFF00
+#define _NAV_MTO_SHT 8
+#define _RTSRST_MSK 0x00FF
+#define _RTSRST_SHT 0
+
+/*BWOPMODE*/
+#define _20MHZBW BIT(2)
+
+/*BACAMCMD*/
+#define _BACAM_POLL BIT(31)
+#define _BACAM_RST BIT(17)
+#define _BACAM_RW BIT(16)
+#define _BACAM_ADDR_MSK 0x0000007F
+#define _BACAM_ADDR_SHT 0
+
+/*LBDLY*/
+#define _LBDLY_MSK 0x1F
+
+/*FWDLY*/
+#define _FWDLY_MSK 0x0F
+
+/*RXERR_RPT*/
+#define _RXERR_RPT_SEL_MSK 0xF0000000
+#define _RXERR_RPT_SEL_SHT 28
+#define _RPT_CNT_MSK 0x000FFFFF
+#define _RPT_CNT_SHT 0
+
+
+#endif /*__RTL8712_WMAC_BITDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h
new file mode 100644
index 000000000000..ac80dfb317cb
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h
@@ -0,0 +1,24 @@
+#ifndef __RTL8712_WMAC_REGDEF_H__
+#define __RTL8712_WMAC_REGDEF_H__
+
+#define NAVCTRL (RTL8712_WMAC_ + 0x00)
+#define BWOPMODE (RTL8712_WMAC_ + 0x03)
+#define BACAMCMD (RTL8712_WMAC_ + 0x04)
+#define BACAMCONTENT (RTL8712_WMAC_ + 0x08)
+#define LBDLY (RTL8712_WMAC_ + 0x10)
+#define FWDLY (RTL8712_WMAC_ + 0x11)
+#define HWPC_RX_CTRL (RTL8712_WMAC_ + 0x18)
+#define MQ (RTL8712_WMAC_ + 0x20)
+#define MA (RTL8712_WMAC_ + 0x22)
+#define MS (RTL8712_WMAC_ + 0x24)
+#define CLM_RESULT (RTL8712_WMAC_ + 0x27)
+#define NHM_RPI_CNT (RTL8712_WMAC_ + 0x28)
+#define RXERR_RPT (RTL8712_WMAC_ + 0x30)
+#define NAV_PROT_LEN (RTL8712_WMAC_ + 0x34)
+#define CFEND_TH (RTL8712_WMAC_ + 0x36)
+#define AMPDU_MIN_SPACE (RTL8712_WMAC_ + 0x37)
+#define TXOP_STALL_CTRL (RTL8712_WMAC_ + 0x38)
+
+
+#endif /*__RTL8712_WMAC_REGDEF_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c
new file mode 100644
index 000000000000..8edc518536f9
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_xmit.c
@@ -0,0 +1,509 @@
+/******************************************************************************
+ * rtl8712_xmit.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL8712_XMIT_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_byteorder.h"
+#include "wifi.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+static void dump_xframe(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe);
+
+sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag)
+{
+ phw_txqueue->ac_tag = ac_tag;
+ switch (ac_tag) {
+ case BE_QUEUE_INX:
+ phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ;
+ break;
+ case BK_QUEUE_INX:
+ phw_txqueue->ff_hwaddr = RTL8712_DMA_BKQ;
+ break;
+ case VI_QUEUE_INX:
+ phw_txqueue->ff_hwaddr = RTL8712_DMA_VIQ;
+ break;
+ case VO_QUEUE_INX:
+ phw_txqueue->ff_hwaddr = RTL8712_DMA_VOQ;
+ break;
+ case BMC_QUEUE_INX:
+ phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ;
+ break;
+ }
+ return _SUCCESS;
+}
+
+int r8712_txframes_sta_ac_pending(struct _adapter *padapter,
+ struct pkt_attrib *pattrib)
+{
+ struct sta_info *psta;
+ struct tx_servq *ptxservq;
+ int priority = pattrib->priority;
+
+ psta = pattrib->psta;
+ switch (priority) {
+ case 1:
+ case 2:
+ ptxservq = &(psta->sta_xmitpriv.bk_q);
+ break;
+ case 4:
+ case 5:
+ ptxservq = &(psta->sta_xmitpriv.vi_q);
+ break;
+ case 6:
+ case 7:
+ ptxservq = &(psta->sta_xmitpriv.vo_q);
+ break;
+ case 0:
+ case 3:
+ default:
+ ptxservq = &(psta->sta_xmitpriv.be_q);
+ break;
+ }
+ return ptxservq->qcnt;
+}
+
+static u32 get_ff_hwaddr(struct xmit_frame *pxmitframe)
+{
+ u32 addr = 0;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct _adapter *padapter = pxmitframe->padapter;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
+
+ if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
+ addr = RTL8712_DMA_H2CCMD;
+ else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
+ addr = RTL8712_DMA_MGTQ;
+ else if (pdvobj->nr_endpoint == 6) {
+ switch (pattrib->priority) {
+ case 0:
+ case 3:
+ addr = RTL8712_DMA_BEQ;
+ break;
+ case 1:
+ case 2:
+ addr = RTL8712_DMA_BKQ;
+ break;
+ case 4:
+ case 5:
+ addr = RTL8712_DMA_VIQ;
+ break;
+ case 6:
+ case 7:
+ addr = RTL8712_DMA_VOQ;
+ break;
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ addr = RTL8712_DMA_H2CCMD;
+ break;
+ default:
+ addr = RTL8712_DMA_BEQ;
+ break;
+ }
+ } else if (pdvobj->nr_endpoint == 4) {
+ switch (pattrib->qsel) {
+ case 0:
+ case 3:
+ case 1:
+ case 2:
+ addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ addr = RTL8712_DMA_VOQ;/*RTL8712_EP_HI;*/
+ break;
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ addr = RTL8712_DMA_H2CCMD;;
+ break;
+ default:
+ addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/
+ break;
+ }
+ }
+ return addr;
+}
+
+static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv,
+ struct hw_xmit *phwxmit,
+ struct tx_servq *ptxservq,
+ struct __queue *pframe_queue)
+{
+ struct list_head *xmitframe_plist, *xmitframe_phead;
+ struct xmit_frame *pxmitframe = NULL;
+
+ xmitframe_phead = get_list_head(pframe_queue);
+ xmitframe_plist = get_next(xmitframe_phead);
+ if ((end_of_queue_search(xmitframe_phead, xmitframe_plist)) == false) {
+ pxmitframe = LIST_CONTAINOR(xmitframe_plist,
+ struct xmit_frame, list);
+ list_delete(&pxmitframe->list);
+ ptxservq->qcnt--;
+ phwxmit->txcmdcnt++;
+ }
+ return pxmitframe;
+}
+
+static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv,
+ struct hw_xmit *phwxmit_i, sint entry)
+{
+ unsigned long irqL0;
+ struct list_head *sta_plist, *sta_phead;
+ struct hw_xmit *phwxmit;
+ struct tx_servq *ptxservq = NULL;
+ struct __queue *pframe_queue = NULL;
+ struct xmit_frame *pxmitframe = NULL;
+ int i, inx[4];
+ int j, tmp, acirp_cnt[4];
+
+ /*entry indx: 0->vo, 1->vi, 2->be, 3->bk.*/
+ inx[0] = 0; acirp_cnt[0] = pxmitpriv->voq_cnt;
+ inx[1] = 1; acirp_cnt[1] = pxmitpriv->viq_cnt;
+ inx[2] = 2; acirp_cnt[2] = pxmitpriv->beq_cnt;
+ inx[3] = 3; acirp_cnt[3] = pxmitpriv->bkq_cnt;
+ for (i = 0; i < 4; i++) {
+ for (j = i + 1; j < 4; j++) {
+ if (acirp_cnt[j] < acirp_cnt[i]) {
+ tmp = acirp_cnt[i];
+ acirp_cnt[i] = acirp_cnt[j];
+ acirp_cnt[j] = tmp;
+ tmp = inx[i];
+ inx[i] = inx[j];
+ inx[j] = tmp;
+ }
+ }
+ }
+ spin_lock_irqsave(&pxmitpriv->lock, irqL0);
+ for (i = 0; i < entry; i++) {
+ phwxmit = phwxmit_i + inx[i];
+ sta_phead = get_list_head(phwxmit->sta_queue);
+ sta_plist = get_next(sta_phead);
+ while ((end_of_queue_search(sta_phead, sta_plist)) == false) {
+ ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq,
+ tx_pending);
+ pframe_queue = &ptxservq->sta_pending;
+ pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit,
+ ptxservq, pframe_queue);
+ if (pxmitframe) {
+ phwxmit->accnt--;
+ goto exit_dequeue_xframe_ex;
+ }
+ sta_plist = get_next(sta_plist);
+ /*Remove sta node when there are no pending packets.*/
+ if (_queue_empty(pframe_queue)) {
+ /*must be done after get_next and before break*/
+ list_delete(&ptxservq->tx_pending);
+ }
+ }
+ }
+exit_dequeue_xframe_ex:
+ spin_unlock_irqrestore(&pxmitpriv->lock, irqL0);
+ return pxmitframe;
+}
+
+void r8712_do_queue_select(struct _adapter *padapter,
+ struct pkt_attrib *pattrib)
+{
+ u8 qsel = 0;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
+
+ if (pdvobj->nr_endpoint == 6)
+ qsel = pattrib->priority;
+ else if (pdvobj->nr_endpoint == 4)
+ qsel = pattrib->priority;
+ pattrib->qsel = qsel;
+}
+
+static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz)
+{
+ uint qsel;
+ struct _adapter *padapter = pxmitframe->padapter;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
+ u8 blnSetTxDescOffset;
+ sint bmcst = IS_MCAST(pattrib->ra);
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+ struct tx_desc txdesc_mp;
+
+ memcpy(&txdesc_mp, ptxdesc, sizeof(struct tx_desc));
+ memset(ptxdesc, 0, sizeof(struct tx_desc));
+ /* offset 0 */
+ ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
+ if (pdvobj->ishighspeed) {
+ if (((sz + TXDESC_SIZE) % 512) == 0)
+ blnSetTxDescOffset = 1;
+ else
+ blnSetTxDescOffset = 0;
+ } else {
+ if (((sz + TXDESC_SIZE) % 64) == 0)
+ blnSetTxDescOffset = 1;
+ else
+ blnSetTxDescOffset = 0;
+ }
+ if (blnSetTxDescOffset) {
+ /* 32 bytes for TX Desc + 8 bytes pending */
+ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ + 8) <<
+ OFFSET_SHT) & 0x00ff0000);
+ } else {
+ /* default = 32 bytes for TX Desc */
+ ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ) <<
+ OFFSET_SHT) & 0x00ff0000);
+ }
+ ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
+ if (pxmitframe->frame_tag == DATA_FRAMETAG) {
+ /* offset 4 */
+ ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f);
+ qsel = (uint)(pattrib->qsel & 0x0000001f);
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+ if (!pqospriv->qos_option)
+ ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/*Non-QoS*/
+ if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
+ switch (pattrib->encrypt) { /*SEC_TYPE*/
+ case _WEP40_:
+ case _WEP104_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) &
+ 0x00c00000);
+ /*KEY_ID when WEP is used;*/
+ ptxdesc->txdw1 |= cpu_to_le32((psecuritypriv->
+ PrivacyKeyIndex << 17) &
+ 0x00060000);
+ break;
+ case _TKIP_:
+ case _TKIP_WTMIC_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x02 << 22) &
+ 0x00c00000);
+ break;
+ case _AES_:
+ ptxdesc->txdw1 |= cpu_to_le32((0x03 << 22) &
+ 0x00c00000);
+ break;
+ case _NO_PRIVACY_:
+ default:
+ break;
+ }
+ }
+ /*offset 8*/
+ if (bmcst)
+ ptxdesc->txdw2 |= cpu_to_le32(BMC);
+
+ /*offset 12*/
+ /* f/w will increase the seqnum by itself, driver pass the
+ * correct priority to fw
+ * fw will check the correct priority for increasing the
+ * seqnum per tid. about usb using 4-endpoint, qsel points out
+ * the correct mapping between AC&Endpoint,
+ * the purpose is that correct mapping lets the MAC release
+ * the AC Queue list correctly. */
+ ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
+ 0x0fff0000);
+ if ((pattrib->ether_type != 0x888e) &&
+ (pattrib->ether_type != 0x0806) &&
+ (pattrib->dhcp_pkt != 1)) {
+ /*Not EAP & ARP type data packet*/
+ if (phtpriv->ht_option == 1) { /*B/G/N Mode*/
+ if (phtpriv->ampdu_enable != true)
+ ptxdesc->txdw2 |= cpu_to_le32(BK);
+ }
+ } else {
+ /* EAP data packet and ARP packet.
+ * Use the 1M data rate to send the EAP/ARP packet.
+ * This will maybe make the handshake smooth.
+ */
+ /*driver uses data rate*/
+ ptxdesc->txdw4 = cpu_to_le32(0x80000000);
+ ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/*1M*/
+ }
+ if (pattrib->pctrl == 1) { /* mp tx packets */
+ struct tx_desc *ptxdesc_mp;
+ ptxdesc_mp = &txdesc_mp;
+ /* offset 8 */
+ ptxdesc->txdw2 = cpu_to_le32(ptxdesc_mp->txdw2);
+ if (bmcst)
+ ptxdesc->txdw2 |= cpu_to_le32(BMC);
+ ptxdesc->txdw2 |= cpu_to_le32(BK);
+ /* offset 16 */
+ ptxdesc->txdw4 = cpu_to_le32(ptxdesc_mp->txdw4);
+ /* offset 20 */
+ ptxdesc->txdw5 = cpu_to_le32(ptxdesc_mp->txdw5);
+ pattrib->pctrl = 0;/* reset to zero; */
+ }
+ } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
+ /* offset 4 */
+ ptxdesc->txdw1 |= (0x05) & 0x1f;/*CAM_ID(MAC_ID), default=5;*/
+ qsel = (uint)(pattrib->qsel & 0x0000001f);
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+ ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */
+ /* offset 8 */
+ if (bmcst)
+ ptxdesc->txdw2 |= cpu_to_le32(BMC);
+ /* offset 12 */
+ /* f/w will increase the seqnum by itself, driver pass the
+ * correct priority to fw
+ * fw will check the correct priority for increasing the seqnum
+ * per tid. about usb using 4-endpoint, qsel points out the
+ * correct mapping between AC&Endpoint,
+ * the purpose is that correct mapping let the MAC releases
+ * the AC Queue list correctly. */
+ ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
+ 0x0fff0000);
+ /* offset 16 */
+ ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/
+ /* offset 20 */
+ ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/* gtest 1M */
+ } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
+ /* offset 4 */
+ qsel = 0x13;
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+ } else {
+ /* offset 4 */
+ qsel = (uint)(pattrib->priority&0x0000001f);
+ ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
+ /*offset 8*/
+ /*offset 12*/
+ ptxdesc->txdw3 = cpu_to_le32((pattrib->seqnum << SEQ_SHT) &
+ 0x0fff0000);
+ /*offset 16*/
+ ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/
+ /*offset 20*/
+ ptxdesc->txdw5 = cpu_to_le32(0x001f9600);/*gtest*/
+ }
+}
+
+int r8712_xmitframe_complete(struct _adapter *padapter,
+ struct xmit_priv *pxmitpriv,
+ struct xmit_buf *pxmitbuf)
+{
+ struct hw_xmit *phwxmits;
+ sint hwentry;
+ struct xmit_frame *pxmitframe = NULL;
+ int res = _SUCCESS, xcnt = 0;
+
+ phwxmits = pxmitpriv->hwxmits;
+ hwentry = pxmitpriv->hwxmit_entry;
+ if (pxmitbuf == NULL) {
+ pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
+ if (!pxmitbuf)
+ return false;
+ }
+ do {
+ pxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry);
+ if (pxmitframe) {
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+ if (pxmitframe->frame_tag == DATA_FRAMETAG) {
+ if (pxmitframe->attrib.priority <= 15)
+ res = r8712_xmitframe_coalesce(padapter,
+ pxmitframe->pkt, pxmitframe);
+ /* always return ndis_packet after
+ * r8712_xmitframe_coalesce */
+ r8712_xmit_complete(padapter, pxmitframe);
+ }
+ if (res == _SUCCESS)
+ dump_xframe(padapter, pxmitframe);
+ else
+ r8712_free_xmitframe_ex(pxmitpriv, pxmitframe);
+ xcnt++;
+ } else {
+ r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
+ return false;
+ }
+ break;
+ } while (0);
+ return true;
+}
+
+static void dump_xframe(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe)
+{
+ int t, sz, w_sz;
+ u8 *mem_addr;
+ u32 ff_hwaddr;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ if (pxmitframe->attrib.ether_type != 0x0806) {
+ if (pxmitframe->attrib.ether_type != 0x888e)
+ r8712_issue_addbareq_cmd(padapter, pattrib->priority);
+ }
+ mem_addr = pxmitframe->buf_addr;
+ for (t = 0; t < pattrib->nr_frags; t++) {
+ if (t != (pattrib->nr_frags - 1)) {
+ sz = pxmitpriv->frag_len;
+ sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 :
+ pattrib->icv_len);
+ pxmitframe->last[t] = 0;
+ } else {
+ sz = pattrib->last_txcmdsz;
+ pxmitframe->last[t] = 1;
+ }
+ update_txdesc(pxmitframe, (uint *)mem_addr, sz);
+ w_sz = sz + TXDESC_SIZE;
+ pxmitframe->mem_addr = mem_addr;
+ pxmitframe->bpending[t] = false;
+ ff_hwaddr = get_ff_hwaddr(pxmitframe);
+ r8712_write_port(padapter, ff_hwaddr, w_sz,
+ (unsigned char *)pxmitframe);
+ mem_addr += w_sz;
+ mem_addr = (u8 *)RND4(((addr_t)(mem_addr)));
+ }
+}
+
+int r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ int res = _SUCCESS;
+
+ res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
+ pxmitframe->pkt = NULL;
+ if (res == _SUCCESS)
+ dump_xframe(padapter, pxmitframe);
+ return res;
+}
+
+int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ if (r8712_xmit_classifier(padapter, pxmitframe) == _FAIL) {
+ pxmitframe->pkt = NULL;
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h
new file mode 100644
index 000000000000..5d77c5107242
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl8712_xmit.h
@@ -0,0 +1,95 @@
+#ifndef _RTL8712_XMIT_H_
+#define _RTL8712_XMIT_H_
+
+#define HWXMIT_ENTRY 4
+
+#define VO_QUEUE_INX 0
+#define VI_QUEUE_INX 1
+#define BE_QUEUE_INX 2
+#define BK_QUEUE_INX 3
+#define TS_QUEUE_INX 4
+#define MGT_QUEUE_INX 5
+#define BMC_QUEUE_INX 6
+#define BCN_QUEUE_INX 7
+
+#define HW_QUEUE_ENTRY 8
+
+#define TXDESC_SIZE 32
+#define TXDESC_OFFSET TXDESC_SIZE
+
+#define NR_AMSDU_XMITFRAME 8
+#define NR_TXAGG_XMITFRAME 8
+
+#define MAX_AMSDU_XMITBUF_SZ 8704
+#define MAX_TXAGG_XMITBUF_SZ 16384 /*16k*/
+
+
+#define tx_cmd tx_desc
+
+
+/*
+ *defined for TX DESC Operation
+ */
+
+#define MAX_TID (15)
+
+/*OFFSET 0*/
+#define OFFSET_SZ (0)
+#define OFFSET_SHT (16)
+#define OWN BIT(31)
+#define FSG BIT(27)
+#define LSG BIT(26)
+
+/*OFFSET 4*/
+#define PKT_OFFSET_SZ (0)
+#define QSEL_SHT (8)
+#define HWPC BIT(31)
+
+/*OFFSET 8*/
+#define BMC BIT(7)
+#define BK BIT(30)
+#define AGG_EN BIT(29)
+
+/*OFFSET 12*/
+#define SEQ_SHT (16)
+
+/*OFFSET 16*/
+#define TXBW BIT(18)
+
+/*OFFSET 20*/
+#define DISFB BIT(15)
+
+struct tx_desc{
+
+ /*DWORD 0*/
+ unsigned int txdw0;
+
+ unsigned int txdw1;
+
+ unsigned int txdw2;
+
+ unsigned int txdw3;
+
+ unsigned int txdw4;
+
+ unsigned int txdw5;
+
+ unsigned int txdw6;
+
+ unsigned int txdw7;
+
+};
+
+
+union txdesc {
+ struct tx_desc txdesc;
+ unsigned int value[TXDESC_SIZE>>2];
+};
+
+int r8712_xmitframe_complete(struct _adapter *padapter,
+ struct xmit_priv *pxmitpriv,
+ struct xmit_buf *pxmitbuf);
+void r8712_do_queue_select(struct _adapter *padapter,
+ struct pkt_attrib *pattrib);
+
+#endif
diff --git a/drivers/staging/rtl8712/rtl871x_byteorder.h b/drivers/staging/rtl8712/rtl871x_byteorder.h
new file mode 100644
index 000000000000..07707e23dbed
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_byteorder.h
@@ -0,0 +1,13 @@
+#ifndef _RTL871X_BYTEORDER_H_
+#define _RTL871X_BYTEORDER_H_
+
+#if defined(__LITTLE_ENDIAN)
+# include "little_endian.h"
+#elif defined(__BIG_ENDIAN)
+# include "big_endian.h"
+#else
+# error "Must be LITTLE/BIG Endian Host"
+#endif
+
+#endif /* _RTL871X_BYTEORDER_H_ */
+
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c
new file mode 100644
index 000000000000..fbb2e4eaae51
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_cmd.c
@@ -0,0 +1,926 @@
+/******************************************************************************
+ * rtl871x_cmd.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_CMD_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "mlme_osdep.h"
+#include "rtl871x_byteorder.h"
+
+/*
+Caller and the r8712_cmd_thread can protect cmd_q by spin_lock.
+No irqsave is necessary.
+*/
+
+static sint _init_cmd_priv(struct cmd_priv *pcmdpriv)
+{
+ sema_init(&(pcmdpriv->cmd_queue_sema), 0);
+ sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
+
+ _init_queue(&(pcmdpriv->cmd_queue));
+
+ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
+ pcmdpriv->cmd_seq = 1;
+ pcmdpriv->cmd_allocated_buf = _malloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
+ if (pcmdpriv->cmd_allocated_buf == NULL)
+ return _FAIL;
+ pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ -
+ ((addr_t)(pcmdpriv->cmd_allocated_buf) &
+ (CMDBUFF_ALIGN_SZ-1));
+ pcmdpriv->rsp_allocated_buf = _malloc(MAX_RSPSZ + 4);
+ if (pcmdpriv->rsp_allocated_buf == NULL)
+ return _FAIL;
+ pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 -
+ ((addr_t)(pcmdpriv->rsp_allocated_buf) & 3);
+ pcmdpriv->cmd_issued_cnt = 0;
+ pcmdpriv->cmd_done_cnt = 0;
+ pcmdpriv->rsp_cnt = 0;
+ return _SUCCESS;
+}
+
+static sint _init_evt_priv(struct evt_priv *pevtpriv)
+{
+ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
+ pevtpriv->event_seq = 0;
+ pevtpriv->evt_allocated_buf = _malloc(MAX_EVTSZ + 4);
+
+ if (pevtpriv->evt_allocated_buf == NULL)
+ return _FAIL;
+ pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 -
+ ((addr_t)(pevtpriv->evt_allocated_buf) & 3);
+ pevtpriv->evt_done_cnt = 0;
+ return _SUCCESS;
+}
+
+static void _free_evt_priv(struct evt_priv *pevtpriv)
+{
+ kfree(pevtpriv->evt_allocated_buf);
+}
+
+static void _free_cmd_priv(struct cmd_priv *pcmdpriv)
+{
+ if (pcmdpriv) {
+ kfree(pcmdpriv->cmd_allocated_buf);
+ kfree(pcmdpriv->rsp_allocated_buf);
+ }
+}
+
+/*
+Calling Context:
+
+_enqueue_cmd can only be called between kernel thread,
+since only spin_lock is used.
+
+ISR/Call-Back functions can't call this sub-function.
+
+*/
+
+static sint _enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
+{
+ unsigned long irqL;
+
+ if (obj == NULL)
+ return _SUCCESS;
+ spin_lock_irqsave(&queue->lock, irqL);
+ list_insert_tail(&obj->list, &queue->queue);
+ spin_unlock_irqrestore(&queue->lock, irqL);
+ return _SUCCESS;
+}
+
+static struct cmd_obj *_dequeue_cmd(struct __queue *queue)
+{
+ unsigned long irqL;
+ struct cmd_obj *obj;
+
+ spin_lock_irqsave(&(queue->lock), irqL);
+ if (is_list_empty(&(queue->queue)))
+ obj = NULL;
+ else {
+ obj = LIST_CONTAINOR(get_next(&(queue->queue)),
+ struct cmd_obj, list);
+ list_delete(&obj->list);
+ }
+ spin_unlock_irqrestore(&(queue->lock), irqL);
+ return obj;
+}
+
+u32 r8712_init_cmd_priv(struct cmd_priv *pcmdpriv)
+{
+ return _init_cmd_priv(pcmdpriv);
+}
+
+u32 r8712_init_evt_priv(struct evt_priv *pevtpriv)
+{
+ return _init_evt_priv(pevtpriv);
+}
+
+void r8712_free_evt_priv(struct evt_priv *pevtpriv)
+{
+ _free_evt_priv(pevtpriv);
+}
+
+void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv)
+{
+ _free_cmd_priv(pcmdpriv);
+}
+
+u32 r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
+{
+ int res;
+
+ if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag == true)
+ return _FAIL;
+ res = _enqueue_cmd(&pcmdpriv->cmd_queue, obj);
+ up(&pcmdpriv->cmd_queue_sema);
+ return res;
+}
+
+u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
+{
+ unsigned long irqL;
+ struct __queue *queue;
+
+ if (obj == NULL)
+ return _SUCCESS;
+ if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag == true)
+ return _FAIL;
+ queue = &pcmdpriv->cmd_queue;
+ spin_lock_irqsave(&queue->lock, irqL);
+ list_insert_tail(&obj->list, &queue->queue);
+ spin_unlock_irqrestore(&queue->lock, irqL);
+ up(&pcmdpriv->cmd_queue_sema);
+ return _SUCCESS;
+}
+
+struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue)
+{
+ return _dequeue_cmd(queue);
+}
+
+void r8712_free_cmd_obj(struct cmd_obj *pcmd)
+{
+ if ((pcmd->cmdcode != _JoinBss_CMD_) &&
+ (pcmd->cmdcode != _CreateBss_CMD_))
+ kfree((unsigned char *)pcmd->parmbuf);
+ if (pcmd->rsp != NULL) {
+ if (pcmd->rspsz != 0)
+ kfree((unsigned char *)pcmd->rsp);
+ }
+ kfree((unsigned char *)pcmd);
+}
+
+/*
+r8712_sitesurvey_cmd(~)
+ ### NOTE:#### (!!!!)
+ MUST TAKE CARE THAT BEFORE CALLING THIS FUNC,
+ YOU SHOULD HAVE LOCKED pmlmepriv->lock
+*/
+u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
+ struct ndis_802_11_ssid *pssid)
+{
+ struct cmd_obj *ph2c;
+ struct sitesurvey_parm *psurveyPara;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psurveyPara = (struct sitesurvey_parm *)_malloc(
+ sizeof(struct sitesurvey_parm));
+ if (psurveyPara == NULL) {
+ kfree((unsigned char *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
+ GEN_CMD_CODE(_SiteSurvey));
+ psurveyPara->bsslimit = cpu_to_le32(48);
+ psurveyPara->passive_mode = cpu_to_le32(1);
+ psurveyPara->ss_ssidlen = 0;
+ memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1);
+ if ((pssid != NULL) && (pssid->SsidLength)) {
+ memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength);
+ psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength);
+ }
+ set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_SITE_SURVEY);
+ return _SUCCESS;
+}
+
+u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset)
+{
+ struct cmd_obj *ph2c;
+ struct setdatarate_parm *pbsetdataratepara;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ pbsetdataratepara = (struct setdatarate_parm *)_malloc(
+ sizeof(struct setdatarate_parm));
+ if (pbsetdataratepara == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara,
+ GEN_CMD_CODE(_SetDataRate));
+ pbsetdataratepara->mac_id = 5;
+ memcpy(pbsetdataratepara->datarates, rateset, NumRates);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset)
+{
+ struct cmd_obj *ph2c;
+ struct setbasicrate_parm *pssetbasicratepara;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ pssetbasicratepara = (struct setbasicrate_parm *)_malloc(
+ sizeof(struct setbasicrate_parm));
+ if (pssetbasicratepara == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara,
+ _SetBasicRate_CMD_);
+ memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+/* power tracking mechanism setting */
+u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type)
+{
+ struct cmd_obj *ph2c;
+ struct PT_param *pptparm;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ pptparm = (struct PT_param *)_malloc(sizeof(struct PT_param));
+ if (pptparm == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pptparm,
+ GEN_CMD_CODE(_SetPowerTracking));
+ pptparm->PT_En = type;
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val)
+{
+ struct cmd_obj *ph2c;
+ struct writeRF_parm *pwriterfparm;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ pwriterfparm = (struct writeRF_parm *)_malloc(
+ sizeof(struct writeRF_parm));
+ if (pwriterfparm == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
+ pwriterfparm->offset = offset;
+ pwriterfparm->value = val;
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval)
+{
+ struct cmd_obj *ph2c;
+ struct readRF_parm *prdrfparm;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ prdrfparm = (struct readRF_parm *)_malloc(sizeof(struct readRF_parm));
+ if (prdrfparm == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ _init_listhead(&ph2c->list);
+ ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
+ ph2c->parmbuf = (unsigned char *)prdrfparm;
+ ph2c->cmdsz = sizeof(struct readRF_parm);
+ ph2c->rsp = pval;
+ ph2c->rspsz = sizeof(struct readRF_rsp);
+ prdrfparm->offset = offset;
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ kfree((unsigned char *) pcmd->parmbuf);
+ kfree((unsigned char *) pcmd);
+ padapter->mppriv.workparam.bcompleted = true;
+}
+
+u8 r8712_createbss_cmd(struct _adapter *padapter)
+{
+ struct cmd_obj *pcmd;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct wlan_bssid_ex *pdev_network =
+ &padapter->registrypriv.dev_network;
+
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
+ pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pcmd == NULL)
+ return _FAIL;
+ _init_listhead(&pcmd->list);
+ pcmd->cmdcode = _CreateBss_CMD_;
+ pcmd->parmbuf = (unsigned char *)pdev_network;
+ pcmd->cmdsz = r8712_get_ndis_wlan_bssid_ex_sz((
+ struct ndis_wlan_bssid_ex *)
+ pdev_network);
+ pcmd->rsp = NULL;
+ pcmd->rspsz = 0;
+ /* notes: translate IELength & Length after assign to cmdsz; */
+ pdev_network->Length = cpu_to_le32(pcmd->cmdsz);
+ pdev_network->IELength = cpu_to_le32(pdev_network->IELength);
+ pdev_network->Ssid.SsidLength = cpu_to_le32(
+ pdev_network->Ssid.SsidLength);
+ r8712_enqueue_cmd(pcmdpriv, pcmd);
+ return _SUCCESS;
+}
+
+u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
+{
+ u8 *auth;
+ uint t_len = 0;
+ struct ndis_wlan_bssid_ex *psecnetwork;
+ struct cmd_obj *pcmd;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->
+ network.InfrastructureMode;
+
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
+ pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pcmd == NULL)
+ return _FAIL;
+ t_len = sizeof(u32) + 6 * sizeof(unsigned char) + 2 +
+ sizeof(struct ndis_802_11_ssid) + sizeof(u32) +
+ sizeof(s32) +
+ sizeof(enum NDIS_802_11_NETWORK_TYPE) +
+ sizeof(struct NDIS_802_11_CONFIGURATION) +
+ sizeof(enum NDIS_802_11_NETWORK_INFRASTRUCTURE) +
+ sizeof(NDIS_802_11_RATES_EX) +
+ sizeof(u32) + MAX_IE_SZ;
+
+ /* for hidden ap to set fw_state here */
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) !=
+ true) {
+ switch (ndis_network_mode) {
+ case Ndis802_11IBSS:
+ pmlmepriv->fw_state |= WIFI_ADHOC_STATE;
+ break;
+ case Ndis802_11Infrastructure:
+ pmlmepriv->fw_state |= WIFI_STATION_STATE;
+ break;
+ case Ndis802_11APMode:
+ case Ndis802_11AutoUnknown:
+ case Ndis802_11InfrastructureMax:
+ break;
+ }
+ }
+ psecnetwork = (struct ndis_wlan_bssid_ex *)&psecuritypriv->sec_bss;
+ if (psecnetwork == NULL) {
+ if (pcmd != NULL)
+ kfree((unsigned char *)pcmd);
+ return _FAIL;
+ }
+ memset(psecnetwork, 0, t_len);
+ memcpy(psecnetwork, &pnetwork->network, t_len);
+ auth = &psecuritypriv->authenticator_ie[0];
+ psecuritypriv->authenticator_ie[0] = (unsigned char)
+ psecnetwork->IELength;
+ if ((psecnetwork->IELength-12) < (256 - 1))
+ memcpy(&psecuritypriv->authenticator_ie[1],
+ &psecnetwork->IEs[12], psecnetwork->IELength-12);
+ else
+ memcpy(&psecuritypriv->authenticator_ie[1],
+ &psecnetwork->IEs[12], (256-1));
+ psecnetwork->IELength = 0;
+ /* If the the driver wants to use the bssid to create the connection.
+ * If not, we copy the connecting AP's MAC address to it so that
+ * the driver just has the bssid information for PMKIDList searching.
+ */
+ if (pmlmepriv->assoc_by_bssid == false)
+ memcpy(&pmlmepriv->assoc_bssid[0],
+ &pnetwork->network.MacAddress[0], ETH_ALEN);
+ psecnetwork->IELength = r8712_restruct_sec_ie(padapter,
+ &pnetwork->network.IEs[0],
+ &psecnetwork->IEs[0],
+ pnetwork->network.IELength);
+ pqospriv->qos_option = 0;
+ if (pregistrypriv->wmm_enable) {
+ u32 tmp_len;
+
+ tmp_len = r8712_restruct_wmm_ie(padapter,
+ &pnetwork->network.IEs[0],
+ &psecnetwork->IEs[0],
+ pnetwork->network.IELength,
+ psecnetwork->IELength);
+ if (psecnetwork->IELength != tmp_len) {
+ psecnetwork->IELength = tmp_len;
+ pqospriv->qos_option = 1; /* WMM IE in beacon */
+ } else
+ pqospriv->qos_option = 0; /* no WMM IE in beacon */
+ }
+ if (pregistrypriv->ht_enable) {
+ /* For WEP mode, we will use the bg mode to do the connection
+ * to avoid some IOT issues, especially for Realtek 8192u
+ * SoftAP.
+ */
+ if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_ ) &&
+ (padapter->securitypriv.PrivacyAlgrthm != _WEP104_ )) {
+ /* restructure_ht_ie */
+ r8712_restructure_ht_ie(padapter,
+ &pnetwork->network.IEs[0],
+ &psecnetwork->IEs[0],
+ pnetwork->network.IELength,
+ &psecnetwork->IELength);
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
+ r8712_add_ht_addt_info(padapter,
+ &pnetwork->network.IEs[0],
+ &psecnetwork->IEs[0],
+ pnetwork->network.IELength,
+ &psecnetwork->IELength);
+ }
+ }
+ psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength;
+ if (psecnetwork->IELength < 255)
+ memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
+ psecnetwork->IELength);
+ else
+ memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
+ 255);
+ /* get cmdsz before endian conversion */
+ pcmd->cmdsz = r8712_get_ndis_wlan_bssid_ex_sz(psecnetwork);
+#ifdef __BIG_ENDIAN
+ /* wlan_network endian conversion */
+ psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
+ psecnetwork->Ssid.SsidLength = cpu_to_le32(
+ psecnetwork->Ssid.SsidLength);
+ psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
+ psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
+ psecnetwork->NetworkTypeInUse = cpu_to_le32(
+ psecnetwork->NetworkTypeInUse);
+ psecnetwork->Configuration.ATIMWindow = cpu_to_le32(
+ psecnetwork->Configuration.ATIMWindow);
+ psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(
+ psecnetwork->Configuration.BeaconPeriod);
+ psecnetwork->Configuration.DSConfig = cpu_to_le32(
+ psecnetwork->Configuration.DSConfig);
+ psecnetwork->Configuration.FHConfig.DwellTime = cpu_to_le32(
+ psecnetwork->Configuration.FHConfig.DwellTime);
+ psecnetwork->Configuration.FHConfig.HopPattern = cpu_to_le32(
+ psecnetwork->Configuration.FHConfig.HopPattern);
+ psecnetwork->Configuration.FHConfig.HopSet = cpu_to_le32(
+ psecnetwork->Configuration.FHConfig.HopSet);
+ psecnetwork->Configuration.FHConfig.Length = cpu_to_le32(
+ psecnetwork->Configuration.FHConfig.Length);
+ psecnetwork->Configuration.Length = cpu_to_le32(
+ psecnetwork->Configuration.Length);
+ psecnetwork->InfrastructureMode = cpu_to_le32(
+ psecnetwork->InfrastructureMode);
+ psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
+#endif
+ _init_listhead(&pcmd->list);
+ pcmd->cmdcode = _JoinBss_CMD_;
+ pcmd->parmbuf = (unsigned char *)psecnetwork;
+ pcmd->rsp = NULL;
+ pcmd->rspsz = 0;
+ r8712_enqueue_cmd(pcmdpriv, pcmd);
+ return _SUCCESS;
+}
+
+u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */
+{
+ struct cmd_obj *pdisconnect_cmd;
+ struct disconnect_parm *pdisconnect;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ pdisconnect_cmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pdisconnect_cmd == NULL)
+ return _FAIL;
+ pdisconnect = (struct disconnect_parm *)_malloc(
+ sizeof(struct disconnect_parm));
+ if (pdisconnect == NULL) {
+ kfree((u8 *)pdisconnect_cmd);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect,
+ _DisConnect_CMD_);
+ r8712_enqueue_cmd(pcmdpriv, pdisconnect_cmd);
+ return _SUCCESS;
+}
+
+u8 r8712_setopmode_cmd(struct _adapter *padapter,
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
+{
+ struct cmd_obj *ph2c;
+ struct setopmode_parm *psetop;
+
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetop = (struct setopmode_parm *)_malloc(
+ sizeof(struct setopmode_parm));
+ if (psetop == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
+ psetop->mode = (u8)networktype;
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key)
+{
+ struct cmd_obj *ph2c;
+ struct set_stakey_parm *psetstakey_para;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct set_stakey_rsp *psetstakey_rsp = NULL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct sta_info *sta = (struct sta_info *)psta;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetstakey_para = (struct set_stakey_parm *)_malloc(
+ sizeof(struct set_stakey_parm));
+ if (psetstakey_para == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ psetstakey_rsp = (struct set_stakey_rsp *)_malloc(
+ sizeof(struct set_stakey_rsp));
+ if (psetstakey_rsp == NULL) {
+ kfree((u8 *) ph2c);
+ kfree((u8 *) psetstakey_para);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
+ ph2c->rsp = (u8 *) psetstakey_rsp;
+ ph2c->rspsz = sizeof(struct set_stakey_rsp);
+ memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
+ psetstakey_para->algorithm = (unsigned char)
+ psecuritypriv->PrivacyAlgrthm;
+ else
+ GET_ENCRY_ALGO(psecuritypriv, sta,
+ psetstakey_para->algorithm, false);
+ if (unicast_key == true)
+ memcpy(&psetstakey_para->key, &sta->x_UncstKey, 16);
+ else
+ memcpy(&psetstakey_para->key,
+ &psecuritypriv->XGrpKey[
+ psecuritypriv->XGrpKeyid - 1]. skey, 16);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode)
+{
+ struct cmd_obj *ph2c;
+ struct setrfintfs_parm *psetrfintfsparm;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetrfintfsparm = (struct setrfintfs_parm *)_malloc(
+ sizeof(struct setrfintfs_parm));
+ if (psetrfintfsparm == NULL) {
+ kfree((unsigned char *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetrfintfsparm,
+ GEN_CMD_CODE(_SetRFIntFs));
+ psetrfintfsparm->rfintfs = mode;
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setrttbl_cmd(struct _adapter *padapter,
+ struct setratable_parm *prate_table)
+{
+ struct cmd_obj *ph2c;
+ struct setratable_parm *psetrttblparm;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetrttblparm = (struct setratable_parm *)_malloc(
+ sizeof(struct setratable_parm));
+ if (psetrttblparm == NULL) {
+ kfree((unsigned char *)ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm,
+ GEN_CMD_CODE(_SetRaTable));
+ memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm));
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr)
+{
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct cmd_obj *ph2c;
+ struct SetMacAddr_param *psetMacAddr_para;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetMacAddr_para = (struct SetMacAddr_param *)_malloc(
+ sizeof(struct SetMacAddr_param));
+ if (psetMacAddr_para == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para,
+ _SetMacAddress_CMD_);
+ memcpy(psetMacAddr_para->MacAddr, mac_addr, ETH_ALEN);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr)
+{
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct cmd_obj *ph2c;
+ struct set_assocsta_parm *psetassocsta_para;
+ struct set_stakey_rsp *psetassocsta_rsp = NULL;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ psetassocsta_para = (struct set_assocsta_parm *)
+ _malloc(sizeof(struct set_assocsta_parm));
+ if (psetassocsta_para == NULL) {
+ kfree((u8 *) ph2c);
+ return _FAIL;
+ }
+ psetassocsta_rsp = (struct set_stakey_rsp *)_malloc(
+ sizeof(struct set_assocsta_rsp));
+ if (psetassocsta_rsp == NULL) {
+ kfree((u8 *)ph2c);
+ kfree((u8 *)psetassocsta_para);
+ return _FAIL;
+ }
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
+ ph2c->rsp = (u8 *) psetassocsta_rsp;
+ ph2c->rspsz = sizeof(struct set_assocsta_rsp);
+ memcpy(psetassocsta_para->addr, mac_addr, ETH_ALEN);
+ r8712_enqueue_cmd(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid)
+{
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+ struct cmd_obj *ph2c;
+ struct addBaReq_parm *paddbareq_parm;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ paddbareq_parm = (struct addBaReq_parm *)_malloc(
+ sizeof(struct addBaReq_parm));
+ if (paddbareq_parm == NULL) {
+ kfree((unsigned char *)ph2c);
+ return _FAIL;
+ }
+ paddbareq_parm->tid = tid;
+ init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm,
+ GEN_CMD_CODE(_AddBAReq));
+ r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+u8 r8712_wdg_wk_cmd(struct _adapter *padapter)
+{
+ struct cmd_obj *ph2c;
+ struct drvint_cmd_parm *pdrvintcmd_param;
+ struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+
+ ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (ph2c == NULL)
+ return _FAIL;
+ pdrvintcmd_param = (struct drvint_cmd_parm *)_malloc(
+ sizeof(struct drvint_cmd_parm));
+ if (pdrvintcmd_param == NULL) {
+ kfree((unsigned char *)ph2c);
+ return _FAIL;
+ }
+ pdrvintcmd_param->i_cid = WDG_WK_CID;
+ pdrvintcmd_param->sz = 0;
+ pdrvintcmd_param->pbuf = NULL;
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvintcmd_param, _DRV_INT_CMD_);
+ r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
+ return _SUCCESS;
+}
+
+void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if (pcmd->res != H2C_SUCCESS)
+ clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
+ r8712_free_cmd_obj(pcmd);
+}
+
+void r8712_disassoc_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if (pcmd->res != H2C_SUCCESS) {
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ set_fwstate(pmlmepriv, _FW_LINKED);
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return;
+ }
+ r8712_free_cmd_obj(pcmd);
+}
+
+void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if ((pcmd->res != H2C_SUCCESS))
+ _set_timer(&pmlmepriv->assoc_timer, 1);
+ r8712_free_cmd_obj(pcmd);
+}
+
+void r8712_createbss_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ unsigned long irqL;
+ u8 timer_cancelled;
+ struct sta_info *psta = NULL;
+ struct wlan_network *pwlan = NULL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ndis_wlan_bssid_ex *pnetwork = (struct ndis_wlan_bssid_ex *)
+ pcmd->parmbuf;
+ struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
+
+ if ((pcmd->res != H2C_SUCCESS))
+ _set_timer(&pmlmepriv->assoc_timer, 1);
+ _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
+#ifdef __BIG_ENDIAN
+ /* endian_convert */
+ pnetwork->Length = le32_to_cpu(pnetwork->Length);
+ pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
+ pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
+ pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
+ pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
+ pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->
+ Configuration.ATIMWindow);
+ pnetwork->Configuration.DSConfig = le32_to_cpu(pnetwork->
+ Configuration.DSConfig);
+ pnetwork->Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork->
+ Configuration.FHConfig.DwellTime);
+ pnetwork->Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork->
+ Configuration.FHConfig.HopPattern);
+ pnetwork->Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork->
+ Configuration.FHConfig.HopSet);
+ pnetwork->Configuration.FHConfig.Length = le32_to_cpu(pnetwork->
+ Configuration.FHConfig.Length);
+ pnetwork->Configuration.Length = le32_to_cpu(pnetwork->
+ Configuration.Length);
+ pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->
+ InfrastructureMode);
+ pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
+#endif
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((pmlmepriv->fw_state) & WIFI_AP_STATE) {
+ psta = r8712_get_stainfo(&padapter->stapriv,
+ pnetwork->MacAddress);
+ if (!psta) {
+ psta = r8712_alloc_stainfo(&padapter->stapriv,
+ pnetwork->MacAddress);
+ if (psta == NULL)
+ goto createbss_cmd_fail ;
+ }
+ r8712_indicate_connect(padapter);
+ } else {
+ pwlan = _r8712_alloc_network(pmlmepriv);
+ if (pwlan == NULL) {
+ pwlan = r8712_get_oldest_wlan_network(
+ &pmlmepriv->scanned_queue);
+ if (pwlan == NULL)
+ goto createbss_cmd_fail;
+ pwlan->last_scanned = jiffies;
+ } else
+ list_insert_tail(&(pwlan->list),
+ &pmlmepriv->scanned_queue.queue);
+ pnetwork->Length = r8712_get_ndis_wlan_bssid_ex_sz(pnetwork);
+ memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
+ pwlan->fixed = true;
+ memcpy(&tgt_network->network, pnetwork,
+ (r8712_get_ndis_wlan_bssid_ex_sz(pnetwork)));
+ if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
+ pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
+ /* we will set _FW_LINKED when there is one more sat to
+ * join us (stassoc_event_callback) */
+ }
+createbss_cmd_fail:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ r8712_free_cmd_obj(pcmd);
+}
+
+void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)
+ (pcmd->rsp);
+ struct sta_info *psta = r8712_get_stainfo(pstapriv,
+ psetstakey_rsp->addr);
+
+ if (psta == NULL)
+ goto exit;
+ psta->aid = psta->mac_id = psetstakey_rsp->keyid; /*CAM_ID(CAM_ENTRY)*/
+exit:
+ r8712_free_cmd_obj(pcmd);
+}
+
+void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd)
+{
+ unsigned long irqL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct set_assocsta_parm *passocsta_parm =
+ (struct set_assocsta_parm *)(pcmd->parmbuf);
+ struct set_assocsta_rsp *passocsta_rsp =
+ (struct set_assocsta_rsp *) (pcmd->rsp);
+ struct sta_info *psta = r8712_get_stainfo(pstapriv,
+ passocsta_parm->addr);
+
+ if (psta == NULL)
+ return;
+ psta->aid = psta->mac_id = passocsta_rsp->cam_id;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((check_fwstate(pmlmepriv, WIFI_MP_STATE)) &&
+ (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)))
+ pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
+ set_fwstate(pmlmepriv, _FW_LINKED);
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ r8712_free_cmd_obj(pcmd);
+}
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h
new file mode 100644
index 000000000000..3a945b5f0e01
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_cmd.h
@@ -0,0 +1,719 @@
+#ifndef __RTL871X_CMD_H_
+#define __RTL871X_CMD_H_
+
+#include "wlan_bssdef.h"
+#include "rtl871x_rf.h"
+#define C2H_MEM_SZ (16*1024)
+
+#include "osdep_service.h"
+#include "ieee80211.h"
+
+#define FREE_CMDOBJ_SZ 128
+#define MAX_CMDSZ 512
+#define MAX_RSPSZ 512
+#define MAX_EVTSZ 1024
+#define CMDBUFF_ALIGN_SZ 512
+
+struct cmd_obj {
+ u16 cmdcode;
+ u8 res;
+ u8 *parmbuf;
+ u32 cmdsz;
+ u8 *rsp;
+ u32 rspsz;
+ struct list_head list;
+};
+
+struct cmd_priv {
+ struct semaphore cmd_queue_sema;
+ struct semaphore terminate_cmdthread_sema;
+ struct __queue cmd_queue;
+ u8 cmd_seq;
+ u8 *cmd_buf; /*shall be non-paged, and 4 bytes aligned*/
+ u8 *cmd_allocated_buf;
+ u8 *rsp_buf; /*shall be non-paged, and 4 bytes aligned*/
+ u8 *rsp_allocated_buf;
+ u32 cmd_issued_cnt;
+ u32 cmd_done_cnt;
+ u32 rsp_cnt;
+ struct _adapter *padapter;
+};
+
+struct evt_obj {
+ u16 evtcode;
+ u8 res;
+ u8 *parmbuf;
+ u32 evtsz;
+ struct list_head list;
+};
+
+struct evt_priv {
+ struct __queue evt_queue;
+ u8 event_seq;
+ u8 *evt_buf; /*shall be non-paged, and 4 bytes aligned*/
+ u8 *evt_allocated_buf;
+ u32 evt_done_cnt;
+ struct tasklet_struct event_tasklet;
+};
+
+#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
+do {\
+ _init_listhead(&pcmd->list);\
+ pcmd->cmdcode = code;\
+ pcmd->parmbuf = (u8 *)(pparm);\
+ pcmd->cmdsz = sizeof(*pparm);\
+ pcmd->rsp = NULL;\
+ pcmd->rspsz = 0;\
+} while (0)
+
+u32 r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
+u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
+struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue);
+void r8712_free_cmd_obj(struct cmd_obj *pcmd);
+int r8712_cmd_thread(void *context);
+u32 r8712_init_cmd_priv(struct cmd_priv *pcmdpriv);
+void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv);
+u32 r8712_init_evt_priv(struct evt_priv *pevtpriv);
+void r8712_free_evt_priv(struct evt_priv *pevtpriv);
+
+enum rtl871x_drvint_cid {
+ NONE_WK_CID,
+ WDG_WK_CID,
+ MAX_WK_CID
+};
+
+enum RFINTFS {
+ SWSI,
+ HWSI,
+ HWPI,
+};
+
+/*
+ * Caller Mode: Infra, Ad-HoC(C)
+ * Notes: To enter USB suspend mode
+ * Command Mode
+ */
+struct usb_suspend_parm {
+ u32 action; /* 1: sleep, 0:resume */
+};
+
+/*
+ * Caller Mode: Infra, Ad-Hoc
+ * Notes: To join the specified bss
+ * Command Event Mode
+ */
+struct joinbss_parm {
+ struct ndis_wlan_bssid_ex network;
+};
+
+/*
+ * Caller Mode: Infra, Ad-HoC(C)
+ * Notes: To disconnect the current associated BSS
+ * Command Mode
+ */
+struct disconnect_parm {
+ u32 rsvd;
+};
+
+/*
+ * Caller Mode: AP, Ad-HoC(M)
+ * Notes: To create a BSS
+ * Command Mode
+ */
+struct createbss_parm {
+ struct ndis_wlan_bssid_ex network;
+};
+
+/*
+ * Caller Mode: AP, Ad-HoC, Infra
+ * Notes: To set the NIC mode of RTL8711
+ * Command Mode
+ * The definition of mode:
+ *
+ * #define IW_MODE_AUTO 0 // Let the driver decides which AP to join
+ * #define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients)
+ * #define IW_MODE_INFRA 2 // Multi cell network, roaming, ..
+ * #define IW_MODE_MASTER 3 // Synchronisation master or AP
+ * #define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder)
+ * #define IW_MODE_SECOND 5 // Secondary master/repeater (backup)
+ * #define IW_MODE_MONITOR 6 // Passive monitor (listen only)
+*/
+struct setopmode_parm {
+ u8 mode;
+ u8 rsvd[3];
+};
+
+/*
+ * Caller Mode: AP, Ad-HoC, Infra
+ * Notes: To ask RTL8711 performing site-survey
+ * Command-Event Mode
+ */
+struct sitesurvey_parm {
+ sint passive_mode; /*active: 1, passive: 0 */
+ sint bsslimit; /* 1 ~ 48 */
+ sint ss_ssidlen;
+ u8 ss_ssid[IW_ESSID_MAX_SIZE + 1];
+};
+
+/*
+ * Caller Mode: Any
+ * Notes: To set the auth type of RTL8711. open/shared/802.1x
+ * Command Mode
+ */
+struct setauth_parm {
+ u8 mode; /*0: legacy open, 1: legacy shared 2: 802.1x*/
+ u8 _1x; /*0: PSK, 1: TLS*/
+ u8 rsvd[2];
+};
+
+/*
+ * Caller Mode: Infra
+ * a. algorithm: wep40, wep104, tkip & aes
+ * b. keytype: grp key/unicast key
+ * c. key contents
+ *
+ * when shared key ==> keyid is the camid
+ * when 802.1x ==> keyid [0:1] ==> grp key
+ * when 802.1x ==> keyid > 2 ==> unicast key
+ */
+struct setkey_parm {
+ u8 algorithm; /* encryption algorithm, could be none, wep40,
+ * TKIP, CCMP, wep104 */
+ u8 keyid;
+ u8 grpkey; /* 1: this is the grpkey for 802.1x.
+ * 0: this is the unicast key for 802.1x */
+ u8 key[16]; /* this could be 40 or 104 */
+};
+
+/*
+ * When in AP or Ad-Hoc mode, this is used to
+ * allocate an sw/hw entry for a newly associated sta.
+ * Command
+ * when shared key ==> algorithm/keyid
+ */
+struct set_stakey_parm {
+ u8 addr[ETH_ALEN];
+ u8 algorithm;
+ u8 key[16];
+};
+
+struct set_stakey_rsp {
+ u8 addr[ETH_ALEN];
+ u8 keyid;
+ u8 rsvd;
+};
+
+struct SetMacAddr_param {
+ u8 MacAddr[ETH_ALEN];
+};
+
+/*
+Caller Ad-Hoc/AP
+
+Command -Rsp(AID == CAMID) mode
+
+This is to force fw to add an sta_data entry per driver's request.
+
+FW will write an cam entry associated with it.
+
+*/
+struct set_assocsta_parm {
+ u8 addr[ETH_ALEN];
+};
+
+struct set_assocsta_rsp {
+ u8 cam_id;
+ u8 rsvd[3];
+};
+
+/*
+ Caller Ad-Hoc/AP
+
+ Command mode
+
+ This is to force fw to del an sta_data entry per driver's request
+
+ FW will invalidate the cam entry associated with it.
+
+*/
+struct del_assocsta_parm {
+ u8 addr[ETH_ALEN];
+};
+
+/*
+Caller Mode: AP/Ad-HoC(M)
+
+Notes: To notify fw that given staid has changed its power state
+
+Command Mode
+
+*/
+struct setstapwrstate_parm {
+ u8 staid;
+ u8 status;
+ u8 hwaddr[6];
+};
+
+/*
+Caller Mode: Any
+
+Notes: To setup the basic rate of RTL8711
+
+Command Mode
+
+*/
+struct setbasicrate_parm {
+ u8 basicrates[NumRates];
+};
+
+/*
+Caller Mode: Any
+
+Notes: To read the current basic rate
+
+Command-Rsp Mode
+
+*/
+struct getbasicrate_parm {
+ u32 rsvd;
+};
+
+struct getbasicrate_rsp {
+ u8 basicrates[NumRates];
+};
+
+/*
+Caller Mode: Any
+
+Notes: To setup the data rate of RTL8711
+
+Command Mode
+
+*/
+struct setdatarate_parm {
+ u8 mac_id;
+ u8 datarates[NumRates];
+};
+
+/*
+Caller Mode: Any
+
+Notes: To read the current data rate
+
+Command-Rsp Mode
+
+*/
+struct getdatarate_parm {
+ u32 rsvd;
+
+};
+struct getdatarate_rsp {
+ u8 datarates[NumRates];
+};
+
+
+/*
+Caller Mode: Any
+AP: AP can use the info for the contents of beacon frame
+Infra: STA can use the info when sitesurveying
+Ad-HoC(M): Like AP
+Ad-HoC(C): Like STA
+
+
+Notes: To set the phy capability of the NIC
+
+Command Mode
+
+*/
+
+/*
+Caller Mode: Any
+
+Notes: To set the channel/modem/band
+This command will be used when channel/modem/band is changed.
+
+Command Mode
+
+*/
+/*
+Caller Mode: Any
+
+Notes: To get the current setting of channel/modem/band
+
+Command-Rsp Mode
+
+*/
+struct getphy_rsp {
+ u8 rfchannel;
+ u8 modem;
+};
+
+struct readBB_parm {
+ u8 offset;
+};
+struct readBB_rsp {
+ u8 value;
+};
+
+struct readTSSI_parm {
+ u8 offset;
+};
+struct readTSSI_rsp {
+ u8 value;
+};
+
+struct writeBB_parm {
+ u8 offset;
+ u8 value;
+};
+
+struct readRF_parm {
+ u8 offset;
+};
+struct readRF_rsp {
+ u32 value;
+};
+
+struct writeRF_parm {
+ u32 offset;
+ u32 value;
+};
+
+struct setrfintfs_parm {
+ u8 rfintfs;
+};
+
+struct getrfintfs_parm {
+ u8 rfintfs;
+};
+
+/*
+ Notes: This command is used for H2C/C2H loopback testing
+
+ mac[0] == 0
+ ==> CMD mode, return H2C_SUCCESS.
+ The following condition must be ture under CMD mode
+ mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0;
+ s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7;
+ s2 == (b1 << 8 | b0);
+
+ mac[0] == 1
+ ==> CMD_RSP mode, return H2C_SUCCESS_RSP
+
+ The rsp layout shall be:
+ rsp: parm:
+ mac[0] = mac[5];
+ mac[1] = mac[4];
+ mac[2] = mac[3];
+ mac[3] = mac[2];
+ mac[4] = mac[1];
+ mac[5] = mac[0];
+ s0 = s1;
+ s1 = swap16(s0);
+ w0 = swap32(w1);
+ b0 = b1
+ s2 = s0 + s1
+ b1 = b0
+ w1 = w0
+
+ mac[0] == 2
+ ==> CMD_EVENT mode, return H2C_SUCCESS
+ The event layout shall be:
+ event: parm:
+ mac[0] = mac[5];
+ mac[1] = mac[4];
+ mac[2] = event's sequence number, starting from 1 to parm's marc[3]
+ mac[3] = mac[2];
+ mac[4] = mac[1];
+ mac[5] = mac[0];
+ s0 = swap16(s0) - event.mac[2];
+ s1 = s1 + event.mac[2];
+ w0 = swap32(w0);
+ b0 = b1
+ s2 = s0 + event.mac[2]
+ b1 = b0
+ w1 = swap32(w1) - event.mac[2];
+
+ parm->mac[3] is the total event counts that host requested.
+
+
+ event will be the same with the cmd's param.
+
+*/
+
+/* CMD param Formart for DRV INTERNAL CMD HDL*/
+struct drvint_cmd_parm {
+ int i_cid; /*internal cmd id*/
+ int sz; /* buf sz*/
+ unsigned char *pbuf;
+};
+
+/*------------------- Below are used for RF/BB tunning ---------------------*/
+
+struct setantenna_parm {
+ u8 tx_antset;
+ u8 rx_antset;
+ u8 tx_antenna;
+ u8 rx_antenna;
+};
+
+struct enrateadaptive_parm {
+ u32 en;
+};
+
+struct settxagctbl_parm {
+ u32 txagc[MAX_RATES_LENGTH];
+};
+
+struct gettxagctbl_parm {
+ u32 rsvd;
+};
+struct gettxagctbl_rsp {
+ u32 txagc[MAX_RATES_LENGTH];
+};
+
+struct setagcctrl_parm {
+ u32 agcctrl; /* 0: pure hw, 1: fw */
+};
+
+struct setssup_parm {
+ u32 ss_ForceUp[MAX_RATES_LENGTH];
+};
+
+struct getssup_parm {
+ u32 rsvd;
+};
+struct getssup_rsp {
+ u8 ss_ForceUp[MAX_RATES_LENGTH];
+};
+
+struct setssdlevel_parm {
+ u8 ss_DLevel[MAX_RATES_LENGTH];
+};
+
+struct getssdlevel_parm {
+ u32 rsvd;
+};
+struct getssdlevel_rsp {
+ u8 ss_DLevel[MAX_RATES_LENGTH];
+};
+
+struct setssulevel_parm {
+ u8 ss_ULevel[MAX_RATES_LENGTH];
+};
+
+struct getssulevel_parm {
+ u32 rsvd;
+};
+struct getssulevel_rsp {
+ u8 ss_ULevel[MAX_RATES_LENGTH];
+};
+
+struct setcountjudge_parm {
+ u8 count_judge[MAX_RATES_LENGTH];
+};
+
+struct getcountjudge_parm {
+ u32 rsvd;
+};
+
+struct getcountjudge_rsp {
+ u8 count_judge[MAX_RATES_LENGTH];
+};
+
+struct setpwrmode_parm {
+ u8 mode;
+ u8 flag_low_traffic_en;
+ u8 flag_lpnav_en;
+ u8 flag_rf_low_snr_en;
+ u8 flag_dps_en; /* 1: dps, 0: 32k */
+ u8 bcn_rx_en;
+ u8 bcn_pass_cnt; /* fw report one beacon information to
+ * driver when it receives bcn_pass_cnt
+ * beacons. */
+ u8 bcn_to; /* beacon TO (ms). ¡§=0¡¨ no limit.*/
+ u16 bcn_itv;
+ u8 app_itv; /* only for VOIP mode. */
+ u8 awake_bcn_itv;
+ u8 smart_ps;
+ u8 bcn_pass_time; /* unit: 100ms */
+};
+
+struct setatim_parm {
+ u8 op; /*0: add, 1:del*/
+ u8 txid; /* id of dest station.*/
+};
+
+struct setratable_parm {
+ u8 ss_ForceUp[NumRates];
+ u8 ss_ULevel[NumRates];
+ u8 ss_DLevel[NumRates];
+ u8 count_judge[NumRates];
+};
+
+struct getratable_parm {
+ uint rsvd;
+};
+struct getratable_rsp {
+ u8 ss_ForceUp[NumRates];
+ u8 ss_ULevel[NumRates];
+ u8 ss_DLevel[NumRates];
+ u8 count_judge[NumRates];
+};
+
+/*to get TX,RX retry count*/
+struct gettxretrycnt_parm{
+ unsigned int rsvd;
+};
+
+struct gettxretrycnt_rsp{
+ unsigned long tx_retrycnt;
+};
+
+struct getrxretrycnt_parm{
+ unsigned int rsvd;
+};
+
+struct getrxretrycnt_rsp{
+ unsigned long rx_retrycnt;
+};
+
+/*to get BCNOK,BCNERR count*/
+struct getbcnokcnt_parm{
+ unsigned int rsvd;
+};
+
+struct getbcnokcnt_rsp{
+ unsigned long bcnokcnt;
+};
+
+struct getbcnerrcnt_parm{
+ unsigned int rsvd;
+};
+struct getbcnerrcnt_rsp{
+ unsigned long bcnerrcnt;
+};
+
+/* to get current TX power level*/
+struct getcurtxpwrlevel_parm{
+ unsigned int rsvd;
+};
+
+struct getcurtxpwrlevel_rsp{
+ unsigned short tx_power;
+};
+
+/*dynamic on/off DIG*/
+struct setdig_parm{
+ unsigned char dig_on; /* 1:on , 0:off */
+};
+
+/*dynamic on/off RA*/
+struct setra_parm{
+ unsigned char ra_on; /* 1:on , 0:off */
+};
+
+struct setprobereqextraie_parm {
+ unsigned char e_id;
+ unsigned char ie_len;
+ unsigned char ie[0];
+};
+
+struct setassocreqextraie_parm {
+ unsigned char e_id;
+ unsigned char ie_len;
+ unsigned char ie[0];
+};
+
+struct setproberspextraie_parm {
+ unsigned char e_id;
+ unsigned char ie_len;
+ unsigned char ie[0];
+};
+
+struct setassocrspextraie_parm {
+ unsigned char e_id;
+ unsigned char ie_len;
+ unsigned char ie[0];
+};
+
+struct addBaReq_parm {
+ unsigned int tid;
+};
+
+/*H2C Handler index: 46 */
+struct SetChannel_parm {
+ u32 curr_ch;
+};
+
+/*H2C Handler index: 56 */
+struct PT_param {
+ u8 PT_En;
+};
+
+#define GEN_CMD_CODE(cmd) cmd ## _CMD_
+
+/*
+ * Result:
+ * 0x00: success
+ * 0x01: sucess, and check Response.
+ * 0x02: cmd ignored due to duplicated sequcne number
+ * 0x03: cmd dropped due to invalid cmd code
+ * 0x04: reserved.
+ */
+
+#define H2C_RSP_OFFSET 512
+#define H2C_SUCCESS 0x00
+#define H2C_SUCCESS_RSP 0x01
+#define H2C_DUPLICATED 0x02
+#define H2C_DROPPED 0x03
+#define H2C_PARAMETERS_ERROR 0x04
+#define H2C_REJECTED 0x05
+#define H2C_CMD_OVERFLOW 0x06
+#define H2C_RESERVED 0x07
+
+u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr);
+u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr);
+u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
+ struct ndis_802_11_ssid *pssid);
+u8 r8712_createbss_cmd(struct _adapter *padapter);
+u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key);
+u8 r8712_joinbss_cmd(struct _adapter *padapter,
+ struct wlan_network *pnetwork);
+u8 r8712_disassoc_cmd(struct _adapter *padapter);
+u8 r8712_setopmode_cmd(struct _adapter *padapter,
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype);
+u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset);
+u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset);
+u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 * pval);
+u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode);
+u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val);
+u8 r8712_setrttbl_cmd(struct _adapter *padapter,
+ struct setratable_parm *prate_table);
+u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type);
+u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid);
+u8 r8712_wdg_wk_cmd(struct _adapter *padapter);
+void r8712_survey_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_disassoc_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_joinbss_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_createbss_cmd_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
+ struct cmd_obj *pcmd);
+
+struct _cmd_callback {
+ u32 cmd_code;
+ void (*callback)(struct _adapter *padapter, struct cmd_obj *cmd);
+};
+
+#include "rtl8712_cmd.h"
+
+#endif /* _CMD_H_ */
+
diff --git a/drivers/staging/rtl8712/rtl871x_debug.h b/drivers/staging/rtl8712/rtl871x_debug.h
new file mode 100644
index 000000000000..c392fd958e43
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_debug.h
@@ -0,0 +1,142 @@
+#ifndef __RTL871X_DEBUG_H__
+#define __RTL871X_DEBUG_H__
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+
+#define _drv_emerg_ 1
+#define _drv_alert_ 2
+#define _drv_crit_ 3
+#define _drv_err_ 4
+#define _drv_warning_ 5
+#define _drv_notice_ 6
+#define _drv_info_ 7
+#define _drv_dump_ 8
+#define _drv_debug_ 9
+
+
+#define _module_rtl871x_xmit_c_ BIT(0)
+#define _module_xmit_osdep_c_ BIT(1)
+#define _module_rtl871x_recv_c_ BIT(2)
+#define _module_recv_osdep_c_ BIT(3)
+#define _module_rtl871x_mlme_c_ BIT(4)
+#define _module_mlme_osdep_c_ BIT(5)
+#define _module_rtl871x_sta_mgt_c_ BIT(6)
+#define _module_rtl871x_cmd_c_ BIT(7)
+#define _module_cmd_osdep_c_ BIT(8)
+#define _module_rtl871x_io_c_ BIT(9)
+#define _module_io_osdep_c_ BIT(10)
+#define _module_os_intfs_c_ BIT(11)
+#define _module_rtl871x_security_c_ BIT(12)
+#define _module_rtl871x_eeprom_c_ BIT(13)
+#define _module_hal_init_c_ BIT(14)
+#define _module_hci_hal_init_c_ BIT(15)
+#define _module_rtl871x_ioctl_c_ BIT(16)
+#define _module_rtl871x_ioctl_set_c_ BIT(17)
+#define _module_rtl871x_pwrctrl_c_ BIT(19)
+#define _module_hci_intfs_c_ BIT(20)
+#define _module_hci_ops_c_ BIT(21)
+#define _module_osdep_service_c_ BIT(22)
+#define _module_rtl871x_mp_ioctl_c_ BIT(23)
+#define _module_hci_ops_os_c_ BIT(24)
+#define _module_rtl871x_ioctl_os_c BIT(25)
+#define _module_rtl8712_cmd_c_ BIT(26)
+#define _module_rtl871x_mp_c_ BIT(27)
+#define _module_rtl8712_xmit_c_ BIT(28)
+#define _module_rtl8712_efuse_c_ BIT(29)
+#define _module_rtl8712_recv_c_ BIT(30)
+#define _module_rtl8712_led_c_ BIT(31)
+
+#undef _MODULE_DEFINE_
+
+#if defined _RTL871X_XMIT_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_
+#elif defined _XMIT_OSDEP_C_
+ #define _MODULE_DEFINE_ _module_xmit_osdep_c_
+#elif defined _RTL871X_RECV_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_recv_c_
+#elif defined _RECV_OSDEP_C_
+ #define _MODULE_DEFINE_ _module_recv_osdep_c_
+#elif defined _RTL871X_MLME_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_
+#elif defined _MLME_OSDEP_C_
+ #define _MODULE_DEFINE_ _module_mlme_osdep_c_
+#elif defined _RTL871X_STA_MGT_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_
+#elif defined _RTL871X_CMD_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_
+#elif defined _CMD_OSDEP_C_
+ #define _MODULE_DEFINE_ _module_cmd_osdep_c_
+#elif defined _RTL871X_IO_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_io_c_
+#elif defined _IO_OSDEP_C_
+ #define _MODULE_DEFINE_ _module_io_osdep_c_
+#elif defined _OS_INTFS_C_
+ #define _MODULE_DEFINE_ _module_os_intfs_c_
+#elif defined _RTL871X_SECURITY_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_security_c_
+#elif defined _RTL871X_EEPROM_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_
+#elif defined _HAL_INIT_C_
+ #define _MODULE_DEFINE_ _module_hal_init_c_
+#elif defined _HCI_HAL_INIT_C_
+ #define _MODULE_DEFINE_ _module_hci_hal_init_c_
+#elif defined _RTL871X_IOCTL_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_
+#elif defined _RTL871X_IOCTL_SET_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_
+#elif defined _RTL871X_PWRCTRL_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_
+#elif defined _HCI_INTF_C_
+ #define _MODULE_DEFINE_ _module_hci_intfs_c_
+#elif defined _HCI_OPS_C_
+ #define _MODULE_DEFINE_ _module_hci_ops_c_
+#elif defined _OSDEP_HCI_INTF_C_
+ #define _MODULE_DEFINE_ _module_hci_intfs_c_
+#elif defined _OSDEP_SERVICE_C_
+ #define _MODULE_DEFINE_ _module_osdep_service_c_
+#elif defined _RTL871X_MP_IOCTL_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_mp_ioctl_c_
+#elif defined _HCI_OPS_OS_C_
+ #define _MODULE_DEFINE_ _module_hci_ops_os_c_
+#elif defined _RTL871X_IOCTL_LINUX_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c
+#elif defined _RTL871X_MP_C_
+ #define _MODULE_DEFINE_ _module_rtl871x_mp_c_
+#elif defined _RTL8712_CMD_C_
+ #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_
+#elif defined _RTL8712_XMIT_C_
+ #define _MODULE_DEFINE_ _module_rtl8712_xmit_c_
+#elif defined _RTL8712_EFUSE_C_
+ #define _MODULE_DEFINE_ _module_rtl8712_efuse_c_
+#elif defined _RTL8712_RECV_C_
+ #define _MODULE_DEFINE_ _module_rtl8712_recv_c_
+#else
+ #undef _MODULE_DEFINE_
+#endif
+
+#define _dbgdump printk
+
+#define MSG_8712(x, ...) {}
+
+#define DBG_8712(x, ...) {}
+
+#define WRN_8712(x, ...) {}
+
+#define ERR_8712(x, ...) {}
+
+#undef MSG_8712
+#define MSG_8712 _dbgdump
+
+#undef DBG_8712
+#define DBG_8712 _dbgdump
+
+#undef WRN_8712
+#define WRN_8712 _dbgdump
+
+#undef ERR_8712
+#define ERR_8712 _dbgdump
+
+#endif /*__RTL871X_DEBUG_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.c b/drivers/staging/rtl8712/rtl871x_eeprom.c
new file mode 100644
index 000000000000..2f145d63fcec
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_eeprom.c
@@ -0,0 +1,233 @@
+/******************************************************************************
+ * rtl871x_eeprom.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_EEPROM_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+static void up_clk(struct _adapter *padapter, u16 *x)
+{
+ *x = *x | _EESK;
+ r8712_write8(padapter, EE_9346CR, (u8)*x);
+ udelay(CLOCK_RATE);
+}
+
+static void down_clk(struct _adapter *padapter, u16 *x)
+{
+ *x = *x & ~_EESK;
+ r8712_write8(padapter, EE_9346CR, (u8)*x);
+ udelay(CLOCK_RATE);
+}
+
+static void shift_out_bits(struct _adapter *padapter, u16 data, u16 count)
+{
+ u16 x, mask;
+
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ mask = 0x01 << (count - 1);
+ x = r8712_read8(padapter, EE_9346CR);
+ x &= ~(_EEDO | _EEDI);
+ do {
+ x &= ~_EEDI;
+ if (data & mask)
+ x |= _EEDI;
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ r8712_write8(padapter, EE_9346CR, (u8)x);
+ udelay(CLOCK_RATE);
+ up_clk(padapter, &x);
+ down_clk(padapter, &x);
+ mask = mask >> 1;
+ } while (mask);
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ x &= ~_EEDI;
+ r8712_write8(padapter, EE_9346CR, (u8)x);
+out:;
+}
+
+static u16 shift_in_bits(struct _adapter *padapter)
+{
+ u16 x, d = 0, i;
+
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ x = r8712_read8(padapter, EE_9346CR);
+ x &= ~(_EEDO | _EEDI);
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d = d << 1;
+ up_clk(padapter, &x);
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ x = r8712_read8(padapter, EE_9346CR);
+ x &= ~(_EEDI);
+ if (x & _EEDO)
+ d |= 1;
+ down_clk(padapter, &x);
+ }
+out:
+ return d;
+}
+
+static void standby(struct _adapter *padapter)
+{
+ u8 x;
+
+ x = r8712_read8(padapter, EE_9346CR);
+ x &= ~(_EECS | _EESK);
+ r8712_write8(padapter, EE_9346CR, x);
+ udelay(CLOCK_RATE);
+ x |= _EECS;
+ r8712_write8(padapter, EE_9346CR, x);
+ udelay(CLOCK_RATE);
+}
+
+static u16 wait_eeprom_cmd_done(struct _adapter *padapter)
+{
+ u8 x;
+ u16 i;
+
+ standby(padapter);
+ for (i = 0; i < 200; i++) {
+ x = r8712_read8(padapter, EE_9346CR);
+ if (x & _EEDO)
+ return true;
+ udelay(CLOCK_RATE);
+ }
+ return false;
+}
+
+static void eeprom_clean(struct _adapter *padapter)
+{
+ u16 x;
+
+ if (padapter->bSurpriseRemoved == true)
+ return;
+ x = r8712_read8(padapter, EE_9346CR);
+ if (padapter->bSurpriseRemoved == true)
+ return;
+ x &= ~(_EECS | _EEDI);
+ r8712_write8(padapter, EE_9346CR, (u8)x);
+ if (padapter->bSurpriseRemoved == true)
+ return;
+ up_clk(padapter, &x);
+ if (padapter->bSurpriseRemoved == true)
+ return;
+ down_clk(padapter, &x);
+}
+
+void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data)
+{
+ u8 x;
+ u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
+
+ tmp8_ori = r8712_read8(padapter, 0x102502f1);
+ tmp8_new = tmp8_ori & 0xf7;
+ if (tmp8_ori != tmp8_new)
+ r8712_write8(padapter, 0x102502f1, tmp8_new);
+ tmp8_clk_ori = r8712_read8(padapter, 0x10250003);
+ tmp8_clk_new = tmp8_clk_ori | 0x20;
+ if (tmp8_clk_new != tmp8_clk_ori)
+ r8712_write8(padapter, 0x10250003, tmp8_clk_new);
+ x = r8712_read8(padapter, EE_9346CR);
+ x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
+ x |= _EEM1 | _EECS;
+ r8712_write8(padapter, EE_9346CR, x);
+ shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
+ if (padapter->EepromAddressSize == 8) /*CF+ and SDIO*/
+ shift_out_bits(padapter, 0, 6);
+ else /* USB */
+ shift_out_bits(padapter, 0, 4);
+ standby(padapter);
+ /* Erase this particular word. Write the erase opcode and register
+ * number in that order. The opcode is 3bits in length; reg is 6
+ * bits long.
+ */
+ standby(padapter);
+ /* write the new word to the EEPROM
+ * send the write opcode the EEPORM
+ */
+ shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
+ /* select which word in the EEPROM that we are writing to. */
+ shift_out_bits(padapter, reg, padapter->EepromAddressSize);
+ /* write the data to the selected EEPROM word. */
+ shift_out_bits(padapter, data, 16);
+ if (wait_eeprom_cmd_done(padapter)) {
+ standby(padapter);
+ shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
+ shift_out_bits(padapter, reg, 4);
+ eeprom_clean(padapter);
+ }
+ if (tmp8_clk_new != tmp8_clk_ori)
+ r8712_write8(padapter, 0x10250003, tmp8_clk_ori);
+ if (tmp8_new != tmp8_ori)
+ r8712_write8(padapter, 0x102502f1, tmp8_ori);
+}
+
+u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg) /*ReadEEprom*/
+{
+ u16 x;
+ u16 data = 0;
+ u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new;
+
+ tmp8_ori = r8712_read8(padapter, 0x102502f1);
+ tmp8_new = tmp8_ori & 0xf7;
+ if (tmp8_ori != tmp8_new)
+ r8712_write8(padapter, 0x102502f1, tmp8_new);
+ tmp8_clk_ori = r8712_read8(padapter, 0x10250003);
+ tmp8_clk_new = tmp8_clk_ori | 0x20;
+ if (tmp8_clk_new != tmp8_clk_ori)
+ r8712_write8(padapter, 0x10250003, tmp8_clk_new);
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ /* select EEPROM, reset bits, set _EECS */
+ x = r8712_read8(padapter, EE_9346CR);
+ if (padapter->bSurpriseRemoved == true)
+ goto out;
+ x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
+ x |= _EEM1 | _EECS;
+ r8712_write8(padapter, EE_9346CR, (unsigned char)x);
+ /* write the read opcode and register number in that order
+ * The opcode is 3bits in length, reg is 6 bits long
+ */
+ shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
+ shift_out_bits(padapter, reg, padapter->EepromAddressSize);
+ /* Now read the data (16 bits) in from the selected EEPROM word */
+ data = shift_in_bits(padapter);
+ eeprom_clean(padapter);
+out:
+ if (tmp8_clk_new != tmp8_clk_ori)
+ r8712_write8(padapter, 0x10250003, tmp8_clk_ori);
+ if (tmp8_new != tmp8_ori)
+ r8712_write8(padapter, 0x102502f1, tmp8_ori);
+ return data;
+}
+
diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.h b/drivers/staging/rtl8712/rtl871x_eeprom.h
new file mode 100644
index 000000000000..fb15f5bde426
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_eeprom.h
@@ -0,0 +1,82 @@
+#ifndef __RTL871X_EEPROM_H__
+#define __RTL871X_EEPROM_H__
+
+#include "osdep_service.h"
+
+#define RTL8712_EEPROM_ID 0x8712
+#define EEPROM_MAX_SIZE 256
+#define CLOCK_RATE 50 /*100us*/
+
+/*- EEPROM opcodes*/
+#define EEPROM_READ_OPCODE 06
+#define EEPROM_WRITE_OPCODE 05
+#define EEPROM_ERASE_OPCODE 07
+#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable*/
+#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable*/
+
+#define EEPROM_CID_DEFAULT 0x0
+#define EEPROM_CID_ALPHA 0x1
+#define EEPROM_CID_Senao 0x3
+#define EEPROM_CID_NetCore 0x5
+#define EEPROM_CID_CAMEO 0X8
+#define EEPROM_CID_SITECOM 0x9
+#define EEPROM_CID_COREGA 0xB
+#define EEPROM_CID_EDIMAX_BELKIN 0xC
+#define EEPROM_CID_SERCOMM_BELKIN 0xE
+#define EEPROM_CID_CAMEO1 0xF
+#define EEPROM_CID_WNC_COREGA 0x12
+#define EEPROM_CID_CLEVO 0x13
+#define EEPROM_CID_WHQL 0xFE
+
+enum RT_CUSTOMER_ID {
+ RT_CID_DEFAULT = 0,
+ RT_CID_8187_ALPHA0 = 1,
+ RT_CID_8187_SERCOMM_PS = 2,
+ RT_CID_8187_HW_LED = 3,
+ RT_CID_8187_NETGEAR = 4,
+ RT_CID_WHQL = 5,
+ RT_CID_819x_CAMEO = 6,
+ RT_CID_819x_RUNTOP = 7,
+ RT_CID_819x_Senao = 8,
+ RT_CID_TOSHIBA = 9,
+ RT_CID_819x_Netcore = 10,
+ RT_CID_Nettronix = 11,
+ RT_CID_DLINK = 12,
+ RT_CID_PRONET = 13,
+ RT_CID_COREGA = 14,
+ RT_CID_819x_ALPHA = 15,
+ RT_CID_819x_Sitecom = 16,
+ RT_CID_CCX = 17,
+ RT_CID_819x_Lenovo = 18,
+ RT_CID_819x_QMI = 19,
+ RT_CID_819x_Edimax_Belkin = 20,
+ RT_CID_819x_Sercomm_Belkin = 21,
+ RT_CID_819x_CAMEO1 = 22,
+ RT_CID_819x_MSI = 23,
+ RT_CID_819x_Acer = 24,
+ RT_CID_819x_AzWave_ASUS = 25,
+ RT_CID_819x_AzWave = 26,
+ RT_CID_819x_WNC_COREGA = 27,
+ RT_CID_819x_CLEVO = 28,
+};
+
+struct eeprom_priv {
+ u8 bautoload_fail_flag;
+ u8 bempty;
+ u8 sys_config;
+ u8 mac_addr[6];
+ u8 config0;
+ u16 channel_plan;
+ u8 country_string[3];
+ u8 tx_power_b[15];
+ u8 tx_power_g[15];
+ u8 tx_power_a[201];
+ u8 efuse_eeprom_data[EEPROM_MAX_SIZE];
+ enum RT_CUSTOMER_ID CustomerID;
+};
+
+void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data);
+u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg);
+
+#endif /*__RTL871X_EEPROM_H__*/
+
diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h
new file mode 100644
index 000000000000..d45229356bf6
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_event.h
@@ -0,0 +1,95 @@
+#ifndef _RTL871x_EVENT_H_
+#define _RTL871x_EVENT_H_
+
+#include "osdep_service.h"
+
+#include "wlan_bssdef.h"
+#include <linux/semaphore.h>
+#include <linux/sem.h>
+
+/*
+ * Used to report a bss has been scanned
+*/
+struct survey_event {
+ struct ndis_wlan_bssid_ex bss;
+};
+
+/*
+ * Used to report that the requested site survey has been done.
+ * bss_cnt indicates the number of bss that has been reported.
+*/
+struct surveydone_event {
+ unsigned int bss_cnt;
+
+};
+
+/*
+ * Used to report the link result of joinning the given bss
+ * join_res:
+ * -1: authentication fail
+ * -2: association fail
+ * > 0: TID
+*/
+struct joinbss_event {
+ struct wlan_network network;
+};
+
+/*
+ * Used to report a given STA has joinned the created BSS.
+ * It is used in AP/Ad-HoC(M) mode.
+*/
+struct stassoc_event {
+ unsigned char macaddr[6];
+ unsigned char rsvd[2];
+ int cam_id;
+};
+
+struct stadel_event {
+ unsigned char macaddr[6];
+ unsigned char rsvd[2];
+};
+
+struct addba_event {
+ unsigned int tid;
+};
+
+#define GEN_EVT_CODE(event) event ## _EVT_
+
+struct fwevent {
+ u32 parmsize;
+ void (*event_callback)(struct _adapter *dev, u8 *pbuf);
+};
+
+#define C2HEVENT_SZ 32
+struct event_node{
+ unsigned char *node;
+ unsigned char evt_code;
+ unsigned short evt_sz;
+ /*volatile*/ int *caller_ff_tail;
+ int caller_ff_sz;
+};
+
+struct c2hevent_queue {
+ /*volatile*/ int head;
+ /*volatile*/ int tail;
+ struct event_node nodes[C2HEVENT_SZ];
+ unsigned char seq;
+};
+
+#define NETWORK_QUEUE_SZ 4
+
+struct network_queue {
+ /*volatile*/ int head;
+ /*volatile*/ int tail;
+ struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ];
+};
+
+struct ADDBA_Req_Report_parm {
+ unsigned char MacAddress[ETH_ALEN];
+ unsigned short StartSeqNum;
+ unsigned char tid;
+};
+#include "rtl8712_event.h"
+
+#endif /* _WLANEVENT_H_ */
+
diff --git a/drivers/staging/rtl8712/rtl871x_ht.h b/drivers/staging/rtl8712/rtl871x_ht.h
new file mode 100644
index 000000000000..612203deea73
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ht.h
@@ -0,0 +1,19 @@
+#ifndef _RTL871X_HT_H_
+#define _RTL871X_HT_H_
+
+#include "osdep_service.h"
+#include "wifi.h"
+
+struct ht_priv {
+ unsigned int ht_option;
+ unsigned int ampdu_enable;/*for enable Tx A-MPDU*/
+ unsigned char baddbareq_issued[16];
+ unsigned int tx_amsdu_enable;/*for enable Tx A-MSDU */
+ unsigned int tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */
+ unsigned int rx_ampdu_maxlen; /* for rx reordering ctrl win_sz,
+ * updated when join_callback. */
+ struct ieee80211_ht_cap ht_cap;
+};
+
+#endif /*_RTL871X_HT_H_ */
+
diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c
new file mode 100644
index 000000000000..e6e3c3752a97
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_io.c
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * rtl871x_io.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+/*
+ *
+ * The purpose of rtl871x_io.c
+ *
+ * a. provides the API
+ * b. provides the protocol engine
+ * c. provides the software interface between caller and the hardware interface
+ *
+ * For r8712u, both sync/async operations are provided.
+ *
+ * Only sync read/write_mem operations are provided.
+ *
+ */
+
+#define _RTL871X_IO_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_io.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+static uint _init_intf_hdl(struct _adapter *padapter,
+ struct intf_hdl *pintf_hdl)
+{
+ struct intf_priv *pintf_priv;
+ void (*set_intf_option)(u32 *poption) = NULL;
+ void (*set_intf_funs)(struct intf_hdl *pintf_hdl);
+ void (*set_intf_ops)(struct _io_ops *pops);
+ uint (*init_intf_priv)(struct intf_priv *pintfpriv);
+
+ set_intf_option = &(r8712_usb_set_intf_option);
+ set_intf_funs = &(r8712_usb_set_intf_funs);
+ set_intf_ops = &r8712_usb_set_intf_ops;
+ init_intf_priv = &r8712_usb_init_intf_priv;
+ pintf_priv = pintf_hdl->pintfpriv = (struct intf_priv *)
+ _malloc(sizeof(struct intf_priv));
+ if (pintf_priv == NULL)
+ goto _init_intf_hdl_fail;
+ pintf_hdl->adapter = (u8 *)padapter;
+ set_intf_option(&pintf_hdl->intf_option);
+ set_intf_funs(pintf_hdl);
+ set_intf_ops(&pintf_hdl->io_ops);
+ pintf_priv->intf_dev = (u8 *)&(padapter->dvobjpriv);
+ if (init_intf_priv(pintf_priv) == _FAIL)
+ goto _init_intf_hdl_fail;
+ return _SUCCESS;
+_init_intf_hdl_fail:
+ if (pintf_priv)
+ kfree((u8 *)pintf_priv);
+ return _FAIL;
+}
+
+static void _unload_intf_hdl(struct intf_priv *pintfpriv)
+{
+ void (*unload_intf_priv)(struct intf_priv *pintfpriv);
+
+ unload_intf_priv = &r8712_usb_unload_intf_priv;
+ unload_intf_priv(pintfpriv);
+ if (pintfpriv)
+ kfree((u8 *)pintfpriv);
+}
+
+static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl)
+{
+ struct _adapter *adapter = (struct _adapter *)dev;
+
+ pintfhdl->intf_option = 0;
+ pintfhdl->adapter = dev;
+ pintfhdl->intf_dev = (u8 *)&(adapter->dvobjpriv);
+ if (_init_intf_hdl(adapter, pintfhdl) == false)
+ goto register_intf_hdl_fail;
+ return _SUCCESS;
+register_intf_hdl_fail:
+ return false;
+}
+
+static void unregister_intf_hdl(struct intf_hdl *pintfhdl)
+{
+ _unload_intf_hdl(pintfhdl->pintfpriv);
+ memset((u8 *)pintfhdl, 0, sizeof(struct intf_hdl));
+}
+
+uint r8712_alloc_io_queue(struct _adapter *adapter)
+{
+ u32 i;
+ struct io_queue *pio_queue;
+ struct io_req *pio_req;
+
+ pio_queue = (struct io_queue *)_malloc(sizeof(struct io_queue));
+ if (pio_queue == NULL)
+ goto alloc_io_queue_fail;
+ _init_listhead(&pio_queue->free_ioreqs);
+ _init_listhead(&pio_queue->processing);
+ _init_listhead(&pio_queue->pending);
+ spin_lock_init(&pio_queue->lock);
+ pio_queue->pallocated_free_ioreqs_buf = (u8 *)_malloc(NUM_IOREQ *
+ (sizeof(struct io_req)) + 4);
+ if ((pio_queue->pallocated_free_ioreqs_buf) == NULL)
+ goto alloc_io_queue_fail;
+ memset(pio_queue->pallocated_free_ioreqs_buf, 0,
+ (NUM_IOREQ * (sizeof(struct io_req)) + 4));
+ pio_queue->free_ioreqs_buf = pio_queue->pallocated_free_ioreqs_buf + 4
+ - ((addr_t)(pio_queue->pallocated_free_ioreqs_buf)
+ & 3);
+ pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf);
+ for (i = 0; i < NUM_IOREQ; i++) {
+ _init_listhead(&pio_req->list);
+ sema_init(&pio_req->sema, 0);
+ list_insert_tail(&pio_req->list, &pio_queue->free_ioreqs);
+ pio_req++;
+ }
+ if ((register_intf_hdl((u8 *)adapter, &(pio_queue->intf))) == _FAIL)
+ goto alloc_io_queue_fail;
+ adapter->pio_queue = pio_queue;
+ return _SUCCESS;
+alloc_io_queue_fail:
+ if (pio_queue) {
+ kfree(pio_queue->pallocated_free_ioreqs_buf);
+ kfree((u8 *)pio_queue);
+ }
+ adapter->pio_queue = NULL;
+ return _FAIL;
+}
+
+void r8712_free_io_queue(struct _adapter *adapter)
+{
+ struct io_queue *pio_queue = (struct io_queue *)(adapter->pio_queue);
+
+ if (pio_queue) {
+ kfree(pio_queue->pallocated_free_ioreqs_buf);
+ adapter->pio_queue = NULL;
+ unregister_intf_hdl(&pio_queue->intf);
+ kfree((u8 *)pio_queue);
+ }
+}
diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h
new file mode 100644
index 000000000000..b70cb2b6296c
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_io.h
@@ -0,0 +1,233 @@
+#ifndef _IO_H_
+#define _IO_H_
+
+#include "osdep_service.h"
+#include "osdep_intf.h"
+
+#define NUM_IOREQ 8
+
+#define MAX_PROT_SZ (64-16)
+
+#define _IOREADY 0
+#define _IO_WAIT_COMPLETE 1
+#define _IO_WAIT_RSP 2
+
+/* IO COMMAND TYPE */
+#define _IOSZ_MASK_ (0x7F)
+#define _IO_WRITE_ BIT(7)
+#define _IO_FIXED_ BIT(8)
+#define _IO_BURST_ BIT(9)
+#define _IO_BYTE_ BIT(10)
+#define _IO_HW_ BIT(11)
+#define _IO_WORD_ BIT(12)
+#define _IO_SYNC_ BIT(13)
+#define _IO_CMDMASK_ (0x1F80)
+
+/*
+ For prompt mode accessing, caller shall free io_req
+ Otherwise, io_handler will free io_req
+*/
+/* IO STATUS TYPE */
+#define _IO_ERR_ BIT(2)
+#define _IO_SUCCESS_ BIT(1)
+#define _IO_DONE_ BIT(0)
+#define IO_RD32 (_IO_SYNC_ | _IO_WORD_)
+#define IO_RD16 (_IO_SYNC_ | _IO_HW_)
+#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_)
+#define IO_RD32_ASYNC (_IO_WORD_)
+#define IO_RD16_ASYNC (_IO_HW_)
+#define IO_RD8_ASYNC (_IO_BYTE_)
+#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_)
+#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_)
+#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_)
+#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_)
+#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_)
+#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_)
+/*
+ Only Sync. burst accessing is provided.
+*/
+#define IO_WR_BURST(x) (IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | \
+ ((x) & _IOSZ_MASK_))
+#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_))
+/*below is for the intf_option bit defition...*/
+#define _INTF_ASYNC_ BIT(0) /*support async io*/
+struct intf_priv;
+struct intf_hdl;
+struct io_queue;
+struct _io_ops {
+ uint (*_sdbus_read_bytes_to_membuf)(struct intf_priv *pintfpriv,
+ u32 addr, u32 cnt, u8 *pbuf);
+ uint (*_sdbus_read_blocks_to_membuf)(struct intf_priv *pintfpriv,
+ u32 addr, u32 cnt, u8 *pbuf);
+ u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+ u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+ u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+ uint (*_sdbus_write_blocks_from_membuf)(struct intf_priv *pintfpriv,
+ u32 addr, u32 cnt, u8 *pbuf,
+ u8 async);
+ uint (*_sdbus_write_bytes_from_membuf)(struct intf_priv *pintfpriv,
+ u32 addr, u32 cnt, u8 *pbuf);
+ u8 (*_cmd52r)(struct intf_priv *pintfpriv, u32 addr);
+ void (*_cmd52w)(struct intf_priv *pintfpriv, u32 addr, u8 val8);
+ u8 (*_cmdfunc152r)(struct intf_priv *pintfpriv, u32 addr);
+ void (*_cmdfunc152w)(struct intf_priv *pintfpriv, u32 addr, u8 val8);
+ void (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
+ void (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
+ void (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
+ void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ void (*_sync_irp_protocol_rw)(struct io_queue *pio_q);
+ u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+ u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
+ u8 *pmem);
+};
+
+struct io_req {
+ struct list_head list;
+ u32 addr;
+ /*volatile*/ u32 val;
+ u32 command;
+ u32 status;
+ u8 *pbuf;
+ struct semaphore sema;
+ void (*_async_io_callback)(struct _adapter *padater,
+ struct io_req *pio_req, u8 *cnxt);
+ u8 *cnxt;
+};
+
+struct intf_hdl {
+ u32 intf_option;
+ u8 *adapter;
+ u8 *intf_dev;
+ struct intf_priv *pintfpriv;
+ void (*intf_hdl_init)(u8 *priv);
+ void (*intf_hdl_unload)(u8 *priv);
+ void (*intf_hdl_open)(u8 *priv);
+ void (*intf_hdl_close)(u8 *priv);
+ struct _io_ops io_ops;
+};
+
+struct reg_protocol_rd {
+
+#ifdef __LITTLE_ENDIAN
+ /* DW1 */
+ u32 NumOfTrans:4;
+ u32 Reserved1:4;
+ u32 Reserved2:24;
+ /* DW2 */
+ u32 ByteCount:7;
+ u32 WriteEnable:1; /*0:read, 1:write*/
+ u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/
+ u32 BurstMode:1;
+ u32 Byte1Access:1;
+ u32 Byte2Access:1;
+ u32 Byte4Access:1;
+ u32 Reserved3:3;
+ u32 Reserved4:16;
+ /*DW3*/
+ u32 BusAddress;
+ /*DW4*/
+#else
+/*DW1*/
+ u32 Reserved1:4;
+ u32 NumOfTrans:4;
+ u32 Reserved2:24;
+ /*DW2*/
+ u32 WriteEnable:1;
+ u32 ByteCount:7;
+ u32 Reserved3:3;
+ u32 Byte4Access:1;
+ u32 Byte2Access:1;
+ u32 Byte1Access:1;
+ u32 BurstMode:1 ;
+ u32 FixOrContinuous:1;
+ u32 Reserved4:16;
+ /*DW3*/
+ u32 BusAddress;
+ /*DW4*/
+#endif
+};
+
+struct reg_protocol_wt {
+#ifdef __LITTLE_ENDIAN
+ /*DW1*/
+ u32 NumOfTrans:4;
+ u32 Reserved1:4;
+ u32 Reserved2:24;
+ /*DW2*/
+ u32 ByteCount:7;
+ u32 WriteEnable:1; /*0:read, 1:write*/
+ u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/
+ u32 BurstMode:1;
+ u32 Byte1Access:1;
+ u32 Byte2Access:1;
+ u32 Byte4Access:1;
+ u32 Reserved3:3;
+ u32 Reserved4:16;
+ /*DW3*/
+ u32 BusAddress;
+ /*DW4*/
+ u32 Value;
+#else
+ /*DW1*/
+ u32 Reserved1:4;
+ u32 NumOfTrans:4;
+ u32 Reserved2:24;
+ /*DW2*/
+ u32 WriteEnable:1;
+ u32 ByteCount:7;
+ u32 Reserved3:3;
+ u32 Byte4Access:1;
+ u32 Byte2Access:1;
+ u32 Byte1Access:1;
+ u32 BurstMode:1;
+ u32 FixOrContinuous:1;
+ u32 Reserved4:16;
+ /*DW3*/
+ u32 BusAddress;
+ /*DW4*/
+ u32 Value;
+#endif
+};
+
+/*
+Below is the data structure used by _io_handler
+*/
+
+struct io_queue {
+ spinlock_t lock;
+ struct list_head free_ioreqs;
+ /*The io_req list that will be served in the single protocol r/w.*/
+ struct list_head pending;
+ struct list_head processing;
+ u8 *free_ioreqs_buf; /* 4-byte aligned */
+ u8 *pallocated_free_ioreqs_buf;
+ struct intf_hdl intf;
+};
+
+static inline u32 _RND4(u32 sz)
+{
+ u32 val;
+ val = ((sz >> 2) + ((sz & 3) ? 1 : 0)) << 2;
+ return val;
+}
+
+u8 r8712_read8(struct _adapter *adapter, u32 addr);
+u16 r8712_read16(struct _adapter *adapter, u32 addr);
+u32 r8712_read32(struct _adapter *adapter, u32 addr);
+void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+void r8712_write8(struct _adapter *adapter, u32 addr, u8 val);
+void r8712_write16(struct _adapter *adapter, u32 addr, u16 val);
+void r8712_write32(struct _adapter *adapter, u32 addr, u32 val);
+void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+/*ioreq */
+uint r8712_alloc_io_queue(struct _adapter *adapter);
+void r8712_free_io_queue(struct _adapter *adapter);
+
+#endif /*_RTL8711_IO_H_*/
+
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl.h b/drivers/staging/rtl8712/rtl871x_ioctl.h
new file mode 100644
index 000000000000..20168028d39d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl.h
@@ -0,0 +1,97 @@
+#ifndef __IOCTL_H
+#define __IOCTL_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+#ifndef OID_802_11_CAPABILITY
+ #define OID_802_11_CAPABILITY 0x0d010122
+#endif
+
+#ifndef OID_802_11_PMKID
+ #define OID_802_11_PMKID 0x0d010123
+#endif
+
+
+/* For DDK-defined OIDs*/
+#define OID_NDIS_SEG1 0x00010100
+#define OID_NDIS_SEG2 0x00010200
+#define OID_NDIS_SEG3 0x00020100
+#define OID_NDIS_SEG4 0x01010100
+#define OID_NDIS_SEG5 0x01020100
+#define OID_NDIS_SEG6 0x01020200
+#define OID_NDIS_SEG7 0xFD010100
+#define OID_NDIS_SEG8 0x0D010100
+#define OID_NDIS_SEG9 0x0D010200
+#define OID_NDIS_SEG10 0x0D020200
+#define SZ_OID_NDIS_SEG1 23
+#define SZ_OID_NDIS_SEG2 3
+#define SZ_OID_NDIS_SEG3 6
+#define SZ_OID_NDIS_SEG4 6
+#define SZ_OID_NDIS_SEG5 4
+#define SZ_OID_NDIS_SEG6 8
+#define SZ_OID_NDIS_SEG7 7
+#define SZ_OID_NDIS_SEG8 36
+#define SZ_OID_NDIS_SEG9 24
+#define SZ_OID_NDIS_SEG10 19
+
+/* For Realtek-defined OIDs*/
+#define OID_MP_SEG1 0xFF871100
+#define OID_MP_SEG2 0xFF818000
+#define OID_MP_SEG3 0xFF818700
+#define OID_MP_SEG4 0xFF011100
+
+enum oid_type {
+ QUERY_OID,
+ SET_OID
+};
+
+struct oid_funs_node {
+ unsigned int oid_start; /*the starting number for OID*/
+ unsigned int oid_end; /*the ending number for OID*/
+ struct oid_obj_priv *node_array;
+ unsigned int array_sz; /*the size of node_array*/
+ int query_counter; /*count the number of query hits for this segment*/
+ int set_counter; /*count the number of set hits for this segment*/
+};
+
+struct oid_par_priv {
+ void *adapter_context;
+ uint oid;
+ void *information_buf;
+ unsigned long information_buf_len;
+ unsigned long *bytes_rw;
+ unsigned long *bytes_needed;
+ enum oid_type type_of_oid;
+ unsigned int dbg;
+};
+
+struct oid_obj_priv {
+ unsigned char dbg; /* 0: without OID debug message
+ * 1: with OID debug message */
+ uint(*oidfuns)(struct oid_par_priv *poid_par_priv);
+};
+
+uint oid_null_function(struct oid_par_priv *poid_par_priv);
+
+extern struct iw_handler_def r871x_handlers_def;
+
+extern uint drv_query_info(
+ struct net_device *MiniportAdapterContext,
+ uint Oid,
+ void *InformationBuffer,
+ u32 InformationBufferLength,
+ u32 *BytesWritten,
+ u32 *BytesNeeded
+);
+
+extern uint drv_set_info(
+ struct net_device *MiniportAdapterContext,
+ uint Oid,
+ void *InformationBuffer,
+ u32 InformationBufferLength,
+ u32 *BytesRead,
+ u32 *BytesNeeded
+);
+
+#endif
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
new file mode 100644
index 000000000000..eac049b12d53
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -0,0 +1,2247 @@
+/******************************************************************************
+ * rtl871x_ioctl_linux.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_IOCTL_LINUX_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wlan_bssdef.h"
+#include "rtl871x_debug.h"
+#include "wifi.h"
+#include "rtl871x_mlme.h"
+#include "rtl871x_ioctl.h"
+#include "rtl871x_ioctl_set.h"
+#include "rtl871x_mp_ioctl.h"
+#include "mlme_osdep.h"
+
+#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
+
+#define SCAN_ITEM_SIZE 768
+#define MAX_CUSTOM_LEN 64
+#define RATE_COUNT 4
+
+
+static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
+ 6000000, 9000000, 12000000, 18000000,
+ 24000000, 36000000, 48000000, 54000000};
+
+static const long ieee80211_wlan_frequencies[] = {
+ 2412, 2417, 2422, 2427,
+ 2432, 2437, 2442, 2447,
+ 2452, 2457, 2462, 2467,
+ 2472, 2484
+};
+
+static const char * const iw_operation_mode[] = {
+ "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
+ "Monitor"
+};
+
+/**
+ * hwaddr_aton - Convert ASCII string to MAC address
+ * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
+ * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
+ * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
+ */
+static int hwaddr_aton_i(const char *txt, u8 *addr)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ int a, b;
+
+ a = hex_to_bin(*txt++);
+ if (a < 0)
+ return -1;
+ b = hex_to_bin(*txt++);
+ if (b < 0)
+ return -1;
+ *addr++ = (a << 4) | b;
+ if (i < 5 && *txt++ != ':')
+ return -1;
+ }
+ return 0;
+}
+
+void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
+{
+ union iwreq_data wrqu;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
+ ETH_ALEN);
+ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
+}
+
+void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
+{
+ union iwreq_data wrqu;
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static inline void handle_pairwise_key(struct sta_info *psta,
+ struct ieee_param *param,
+ struct _adapter *padapter)
+{
+ /* pairwise key */
+ memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
+ (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
+ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
+ memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
+ key[16]), 8);
+ memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
+ key[24]), 8);
+ padapter->securitypriv. busetkipkey = false;
+ _set_timer(&padapter->securitypriv.tkip_timer, 50);
+ }
+ r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
+}
+
+static inline void handle_group_key(struct ieee_param *param,
+ struct _adapter *padapter)
+{
+ if (0 < param->u.crypt.idx &&
+ param->u.crypt.idx < 3) {
+ /* group key idx is 1 or 2 */
+ memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
+ idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
+ > 16 ? 16 : param->u.crypt.key_len));
+ memcpy(padapter->securitypriv.XGrptxmickey[param->
+ u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
+ memcpy(padapter->securitypriv. XGrprxmickey[param->
+ u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
+ padapter->securitypriv.binstallGrpkey = true;
+ r8712_set_key(padapter, &padapter->securitypriv,
+ param->u.crypt.idx);
+ if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
+ if (padapter->registrypriv.power_mgnt != padapter->
+ pwrctrlpriv.pwr_mode)
+ _set_timer(&(padapter->mlmepriv.dhcp_timer),
+ 60000);
+ }
+ }
+}
+
+static inline char *translate_scan(struct _adapter *padapter,
+ struct iw_request_info *info,
+ struct wlan_network *pnetwork,
+ char *start, char *stop)
+{
+ struct iw_event iwe;
+ struct ieee80211_ht_cap *pht_capie;
+ char *current_val;
+ u8 *buf = (u8 *)_malloc(pnetwork->network.IELength * 2);
+ u8 *wpa_ie = (u8 *)_malloc(255);
+ u8 *rsn_ie = (u8 *)_malloc(255);
+ u8 *wps_ie = (u8 *)_malloc(MAX_WPS_IE_LEN);
+ s8 *p;
+ u32 i = 0, ht_ielen = 0;
+ u16 cap, ht_cap = false, mcs_rate;
+ u8 rssi, bw_40MHz = 0, short_GI = 0;
+
+ if ((pnetwork->network.Configuration.DSConfig < 1) ||
+ (pnetwork->network.Configuration.DSConfig > 14)) {
+ if (pnetwork->network.Configuration.DSConfig < 1)
+ pnetwork->network.Configuration.DSConfig = 1;
+ else
+ pnetwork->network.Configuration.DSConfig = 14;
+ }
+ /* AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
+ /* Add the ESSID */
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ iwe.u.data.length = (u16)min((u16)pnetwork->network.Ssid.SsidLength,
+ (u16)32);
+ start = iwe_stream_add_point(info, start, stop, &iwe,
+ pnetwork->network.Ssid.Ssid);
+ /* parsing HT_CAP_IE */
+ p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
+ &ht_ielen, pnetwork->network.IELength - 12);
+ if (p && ht_ielen > 0) {
+ ht_cap = true;
+ pht_capie = (struct ieee80211_ht_cap *)(p + 2);
+ memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
+ bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
+ ? 1 : 0;
+ short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
+ }
+ /* Add the protocol name */
+ iwe.cmd = SIOCGIWNAME;
+ if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
+ SupportedRates)) == true) {
+ if (ht_cap == true)
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
+ else
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
+ } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
+ SupportedRates)) == true) {
+ if (ht_cap == true)
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
+ else
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
+ } else {
+ if (ht_cap == true)
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
+ else
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
+ }
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
+ 2);
+ cap = le16_to_cpu(cap);
+ if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
+ if (cap & WLAN_CAPABILITY_BSS)
+ iwe.u.mode = (u32)IW_MODE_MASTER;
+ else
+ iwe.u.mode = (u32)IW_MODE_ADHOC;
+ start = iwe_stream_add_event(info, start, stop, &iwe,
+ IW_EV_UINT_LEN);
+ }
+ /* Add frequency/channel */
+ iwe.cmd = SIOCGIWFREQ;
+ {
+ /* check legel index */
+ u8 dsconfig = pnetwork->network.Configuration.DSConfig;
+ if (dsconfig >= 1 && dsconfig <= sizeof(
+ ieee80211_wlan_frequencies) / sizeof(long))
+ iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
+ pnetwork->network.Configuration.
+ DSConfig - 1] * 100000);
+ else
+ iwe.u.freq.m = 0;
+ }
+ iwe.u.freq.e = (s16)1;
+ iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
+ start = iwe_stream_add_event(info, start, stop, &iwe,
+ IW_EV_FREQ_LEN);
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (cap & WLAN_CAPABILITY_PRIVACY)
+ iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
+ IW_ENCODE_NOKEY);
+ else
+ iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
+ iwe.u.data.length = (u16)0;
+ start = iwe_stream_add_point(info, start, stop, &iwe,
+ pnetwork->network.Ssid.Ssid);
+ /*Add basic and extended rates */
+ current_val = start + iwe_stream_lcp_len(info);
+ iwe.cmd = SIOCGIWRATE;
+ iwe.u.bitrate.fixed = 0;
+ iwe.u.bitrate.disabled = 0;
+ iwe.u.bitrate.value = 0;
+ i = 0;
+ while (pnetwork->network.SupportedRates[i] != 0) {
+ /* Bit rate given in 500 kb/s units */
+ iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
+ 0x7F) * 500000;
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if ((current_val - start) > iwe_stream_lcp_len(info))
+ start = current_val;
+ /* parsing WPA/WPA2 IE */
+ {
+ u16 wpa_len = 0, rsn_len = 0;
+ u8 *p;
+ sint out_len = 0;
+ out_len = r8712_get_sec_ie(pnetwork->network.IEs,
+ pnetwork->network.
+ IELength, rsn_ie, &rsn_len,
+ wpa_ie, &wpa_len);
+ if (wpa_len > 0) {
+ p = buf;
+ memset(buf, 0, MAX_WPA_IE_LEN);
+ p += snprintf(p, 7, "wpa_ie=");
+ for (i = 0; i < wpa_len; i++)
+ p += snprintf(p, 2, "%02x", wpa_ie[i]);
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = (u16)strlen(buf);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, buf);
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = (u16)wpa_len;
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, wpa_ie);
+ }
+ if (rsn_len > 0) {
+ p = buf;
+ memset(buf, 0, MAX_WPA_IE_LEN);
+ p += snprintf(p, 7, "rsn_ie=");
+ for (i = 0; i < rsn_len; i++)
+ p += snprintf(p, 2, "%02x", rsn_ie[i]);
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = strlen(buf);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, buf);
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = rsn_len;
+ start = iwe_stream_add_point(info, start, stop, &iwe,
+ rsn_ie);
+ }
+ }
+
+ { /* parsing WPS IE */
+ uint wps_ielen;
+
+ if (r8712_get_wps_ie(pnetwork->network.IEs,
+ pnetwork->network.IELength,
+ wps_ie, &wps_ielen) == true) {
+ if (wps_ielen > 2) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = (u16)wps_ielen;
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, wps_ie);
+ }
+ }
+ }
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
+ /* we only update signal_level (signal strength) that is rssi. */
+ iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
+ IW_QUAL_NOISE_INVALID);
+ iwe.u.qual.level = rssi; /* signal strength */
+ iwe.u.qual.qual = 0; /* signal quality */
+ iwe.u.qual.noise = 0; /* noise level */
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
+ /* how to translate rssi to ?% */
+ kfree(buf);
+ kfree(wpa_ie);
+ kfree(rsn_ie);
+ kfree(wps_ie);
+ return start;
+}
+
+static int wpa_set_auth_algs(struct net_device *dev, u32 value)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ int ret = 0;
+
+ if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeAutoSwitch;
+ padapter->securitypriv.AuthAlgrthm = 3;
+ } else if (value & AUTH_ALG_SHARED_KEY) {
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
+ padapter->securitypriv.AuthAlgrthm = 1;
+ } else if (value & AUTH_ALG_OPEN_SYSTEM) {
+ if (padapter->securitypriv.ndisauthtype <
+ Ndis802_11AuthModeWPAPSK) {
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeOpen;
+ padapter->securitypriv.AuthAlgrthm = 0;
+ }
+ } else
+ ret = -EINVAL;
+ return ret;
+}
+
+static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+ u32 param_len)
+{
+ int ret = 0;
+ u32 wep_key_idx, wep_key_len = 0;
+ struct NDIS_802_11_WEP *pwep = NULL;
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ param->u.crypt.err = 0;
+ param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+ if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
+ param->u.crypt.key_len)
+ return -EINVAL;
+ if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+ param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+ if (param->u.crypt.idx >= WEP_KEYS) {
+ /* for large key indices, set the default (0) */
+ param->u.crypt.idx = 0;
+ }
+ } else
+ return -EINVAL;
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ printk(KERN_INFO "r8712u: wpa_set_encryption, crypt.alg ="
+ " WEP\n");
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
+ padapter->securitypriv.XGrpPrivacy = _WEP40_;
+ wep_key_idx = param->u.crypt.idx;
+ wep_key_len = param->u.crypt.key_len;
+ if (wep_key_idx >= WEP_KEYS)
+ wep_key_idx = 0;
+ if (wep_key_len > 0) {
+ wep_key_len = wep_key_len <= 5 ? 5 : 13;
+ pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
+ (wep_key_len +
+ FIELD_OFFSET(struct NDIS_802_11_WEP,
+ KeyMaterial)));
+ if (pwep == NULL)
+ return -ENOMEM;
+ memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
+ pwep->KeyLength = wep_key_len;
+ pwep->Length = wep_key_len +
+ FIELD_OFFSET(struct NDIS_802_11_WEP,
+ KeyMaterial);
+ if (wep_key_len == 13) {
+ padapter->securitypriv.PrivacyAlgrthm =
+ _WEP104_;
+ padapter->securitypriv.XGrpPrivacy =
+ _WEP104_;
+ }
+ } else
+ return -EINVAL;
+ pwep->KeyIndex = wep_key_idx;
+ pwep->KeyIndex |= 0x80000000;
+ memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
+ if (param->u.crypt.set_tx) {
+ if (r8712_set_802_11_add_wep(padapter, pwep) ==
+ (u8)_FAIL)
+ ret = -EOPNOTSUPP;
+ } else {
+ /* don't update "psecuritypriv->PrivacyAlgrthm" and
+ * "psecuritypriv->PrivacyKeyIndex=keyid", but can
+ * r8712_set_key to fw/cam
+ */
+ if (wep_key_idx >= WEP_KEYS) {
+ ret = -EOPNOTSUPP;
+ goto exit;
+ }
+ memcpy(&(psecuritypriv->DefKey[wep_key_idx].
+ skey[0]), pwep->KeyMaterial,
+ pwep->KeyLength);
+ psecuritypriv->DefKeylen[wep_key_idx] =
+ pwep->KeyLength;
+ r8712_set_key(padapter, psecuritypriv, wep_key_idx);
+ }
+ goto exit;
+ }
+ if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */
+ struct sta_info *psta, *pbcmc_sta;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
+ WIFI_MP_STATE) == true) { /* sta mode */
+ psta = r8712_get_stainfo(pstapriv,
+ get_bssid(pmlmepriv));
+ if (psta) {
+ psta->ieee8021x_blocked = false;
+ if ((padapter->securitypriv.ndisencryptstatus ==
+ Ndis802_11Encryption2Enabled) ||
+ (padapter->securitypriv.ndisencryptstatus ==
+ Ndis802_11Encryption3Enabled))
+ psta->XPrivacy = padapter->
+ securitypriv.PrivacyAlgrthm;
+ if (param->u.crypt.set_tx == 1)
+ handle_pairwise_key(psta, param,
+ padapter);
+ else /* group key */
+ handle_group_key(param, padapter);
+ }
+ pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
+ if (pbcmc_sta) {
+ pbcmc_sta->ieee8021x_blocked = false;
+ if ((padapter->securitypriv.ndisencryptstatus ==
+ Ndis802_11Encryption2Enabled) ||
+ (padapter->securitypriv.ndisencryptstatus ==
+ Ndis802_11Encryption3Enabled))
+ pbcmc_sta->XPrivacy =
+ padapter->securitypriv.
+ PrivacyAlgrthm;
+ }
+ }
+ }
+exit:
+ kfree((u8 *)pwep);
+ return ret;
+}
+
+static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
+ unsigned short ielen)
+{
+ u8 *buf = NULL, *pos = NULL;
+ int group_cipher = 0, pairwise_cipher = 0;
+ int ret = 0;
+
+ if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
+ return -EINVAL;
+ if (ielen) {
+ buf = _malloc(ielen);
+ if (buf == NULL)
+ return -ENOMEM;
+ memcpy(buf, pie , ielen);
+ pos = buf;
+ if (ielen < RSN_HEADER_LEN) {
+ ret = -1;
+ goto exit;
+ }
+ if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
+ &pairwise_cipher) == _SUCCESS) {
+ padapter->securitypriv.AuthAlgrthm = 2;
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeWPAPSK;
+ }
+ if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
+ &pairwise_cipher) == _SUCCESS) {
+ padapter->securitypriv.AuthAlgrthm = 2;
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeWPA2PSK;
+ }
+ switch (group_cipher) {
+ case WPA_CIPHER_NONE:
+ padapter->securitypriv.XGrpPrivacy =
+ _NO_PRIVACY_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11EncryptionDisabled;
+ break;
+ case WPA_CIPHER_WEP40:
+ padapter->securitypriv.XGrpPrivacy = _WEP40_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ break;
+ case WPA_CIPHER_TKIP:
+ padapter->securitypriv.XGrpPrivacy = _TKIP_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption2Enabled;
+ break;
+ case WPA_CIPHER_CCMP:
+ padapter->securitypriv.XGrpPrivacy = _AES_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption3Enabled;
+ break;
+ case WPA_CIPHER_WEP104:
+ padapter->securitypriv.XGrpPrivacy = _WEP104_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ break;
+ }
+ switch (pairwise_cipher) {
+ case WPA_CIPHER_NONE:
+ padapter->securitypriv.PrivacyAlgrthm =
+ _NO_PRIVACY_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11EncryptionDisabled;
+ break;
+ case WPA_CIPHER_WEP40:
+ padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ break;
+ case WPA_CIPHER_TKIP:
+ padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption2Enabled;
+ break;
+ case WPA_CIPHER_CCMP:
+ padapter->securitypriv.PrivacyAlgrthm = _AES_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption3Enabled;
+ break;
+ case WPA_CIPHER_WEP104:
+ padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ break;
+ }
+ padapter->securitypriv.wps_phase = false;
+ {/* set wps_ie */
+ u16 cnt = 0;
+ u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
+
+ while (cnt < ielen) {
+ eid = buf[cnt];
+
+ if ((eid == _VENDOR_SPECIFIC_IE_) &&
+ (!memcmp(&buf[cnt+2], wps_oui, 4))) {
+ printk(KERN_INFO "r8712u: "
+ "SET WPS_IE\n");
+ padapter->securitypriv.wps_ie_len =
+ ((buf[cnt+1] + 2) <
+ (MAX_WPA_IE_LEN << 2)) ?
+ (buf[cnt + 1] + 2) :
+ (MAX_WPA_IE_LEN << 2);
+ memcpy(padapter->securitypriv.wps_ie,
+ &buf[cnt],
+ padapter->securitypriv.wps_ie_len);
+ padapter->securitypriv.wps_phase =
+ true;
+ printk(KERN_INFO "r8712u: SET WPS_IE,"
+ " wps_phase==true\n");
+ cnt += buf[cnt+1]+2;
+ break;
+ } else
+ cnt += buf[cnt + 1] + 2;
+ }
+ }
+ }
+exit:
+ kfree(buf);
+ return ret;
+}
+
+static int r8711_wx_get_name(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ u32 ht_ielen = 0;
+ char *p;
+ u8 ht_cap = false;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+ NDIS_802_11_RATES_EX *prates = NULL;
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
+ true) {
+ /* parsing HT_CAP_IE */
+ p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
+ &ht_ielen, pcur_bss->IELength - 12);
+ if (p && ht_ielen > 0)
+ ht_cap = true;
+ prates = &pcur_bss->SupportedRates;
+ if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
+ if (ht_cap == true)
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11bn");
+ else
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11b");
+ } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
+ if (ht_cap == true)
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11bgn");
+ else
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11bg");
+ } else {
+ if (ht_cap == true)
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11gn");
+ else
+ snprintf(wrqu->name, IFNAMSIZ,
+ "IEEE 802.11g");
+ }
+ } else
+ snprintf(wrqu->name, IFNAMSIZ, "unassociated");
+ return 0;
+}
+
+static const long frequency_list[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
+ 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+ 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
+ 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
+ 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
+ 5825
+};
+
+static int r8711_wx_set_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct iw_freq *fwrq = &wrqu->freq;
+ int rc = 0;
+
+/* If setting by frequency, convert to a channel */
+ if ((fwrq->e == 1) &&
+ (fwrq->m >= (int) 2.412e8) &&
+ (fwrq->m <= (int) 2.487e8)) {
+ int f = fwrq->m / 100000;
+ int c = 0;
+ while ((c < 14) && (f != frequency_list[c]))
+ c++;
+ fwrq->e = 0;
+ fwrq->m = c + 1;
+ }
+ /* Setting by channel number */
+ if ((fwrq->m > 14) || (fwrq->e > 0))
+ rc = -EOPNOTSUPP;
+ else {
+ int channel = fwrq->m;
+ if ((channel < 1) || (channel > 14))
+ rc = -EINVAL;
+ else {
+ /* Yes ! We can set it !!! */
+ padapter->registrypriv.channel = channel;
+ }
+ }
+ return rc;
+}
+
+static int r8711_wx_get_freq(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ wrqu->freq.m = ieee80211_wlan_frequencies[
+ pcur_bss->Configuration.DSConfig-1] * 100000;
+ wrqu->freq.e = 1;
+ wrqu->freq.i = pcur_bss->Configuration.DSConfig;
+ } else
+ return -1;
+ return 0;
+}
+
+static int r8711_wx_set_mode(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *b)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
+
+ switch (wrqu->mode) {
+ case IW_MODE_AUTO:
+ networkType = Ndis802_11AutoUnknown;
+ break;
+ case IW_MODE_ADHOC:
+ networkType = Ndis802_11IBSS;
+ break;
+ case IW_MODE_MASTER:
+ networkType = Ndis802_11APMode;
+ break;
+ case IW_MODE_INFRA:
+ networkType = Ndis802_11Infrastructure;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (Ndis802_11APMode == networkType)
+ r8712_setopmode_cmd(padapter, networkType);
+ else
+ r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
+ if (!r8712_set_802_11_infrastructure_mode(padapter, networkType))
+ return -1;
+ return 0;
+}
+
+static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
+ union iwreq_data *wrqu, char *b)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+ wrqu->mode = IW_MODE_INFRA;
+ else if (check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
+ wrqu->mode = IW_MODE_ADHOC;
+ else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+ wrqu->mode = IW_MODE_MASTER;
+ else
+ wrqu->mode = IW_MODE_AUTO;
+ return 0;
+}
+
+static int r871x_wx_set_pmkid(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
+ u8 strZeroMacAddress[ETH_ALEN] = {0x00};
+ u8 strIssueBssid[ETH_ALEN] = {0x00};
+ u8 j, blInserted = false;
+ int intReturn = false;
+
+/*
+ There are the BSSID information in the bssid.sa_data array.
+ If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear
+ all the PMKID information. If cmd is IW_PMKSA_ADD, it means the
+ wpa_supplicant wants to add a PMKID/BSSID to driver.
+ If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to
+ remove a PMKID/BSSID from driver.
+*/
+ if (pPMK == NULL)
+ return -EINVAL;
+ memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
+ switch (pPMK->cmd) {
+ case IW_PMKSA_ADD:
+ if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
+ return intReturn;
+ else
+ intReturn = true;
+ blInserted = false;
+ /* overwrite PMKID */
+ for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
+ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
+ strIssueBssid, ETH_ALEN)) {
+ /* BSSID is matched, the same AP => rewrite
+ * with new PMKID. */
+ printk(KERN_INFO "r8712u: r871x_wx_set_pmkid:"
+ " BSSID exists in the PMKList.\n");
+ memcpy(psecuritypriv->PMKIDList[j].PMKID,
+ pPMK->pmkid, IW_PMKID_LEN);
+ psecuritypriv->PMKIDList[j].bUsed = true;
+ psecuritypriv->PMKIDIndex = j + 1;
+ blInserted = true;
+ break;
+ }
+ }
+ if (!blInserted) {
+ /* Find a new entry */
+ printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: Use the"
+ " new entry index = %d for this PMKID.\n",
+ psecuritypriv->PMKIDIndex);
+ memcpy(psecuritypriv->PMKIDList[psecuritypriv->
+ PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
+ memcpy(psecuritypriv->PMKIDList[psecuritypriv->
+ PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
+ psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
+ bUsed = true;
+ psecuritypriv->PMKIDIndex++ ;
+ if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
+ psecuritypriv->PMKIDIndex = 0;
+ }
+ break;
+ case IW_PMKSA_REMOVE:
+ intReturn = true;
+ for (j = 0; j < NUM_PMKID_CACHE; j++) {
+ if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
+ strIssueBssid, ETH_ALEN)) {
+ /* BSSID is matched, the same AP => Remove
+ * this PMKID information and reset it. */
+ memset(psecuritypriv->PMKIDList[j].Bssid,
+ 0x00, ETH_ALEN);
+ psecuritypriv->PMKIDList[j].bUsed = false;
+ break;
+ }
+ }
+ break;
+ case IW_PMKSA_FLUSH:
+ memset(psecuritypriv->PMKIDList, 0,
+ sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
+ psecuritypriv->PMKIDIndex = 0;
+ intReturn = true;
+ break;
+ default:
+ printk(KERN_INFO "r8712u: r871x_wx_set_pmkid: "
+ "unknown Command\n");
+ intReturn = false;
+ break;
+ }
+ return intReturn;
+}
+
+static int r8711_wx_get_sens(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wrqu->sens.value = 0;
+ wrqu->sens.fixed = 0; /* no auto select */
+ wrqu->sens.disabled = 1;
+ return 0;
+}
+
+static int r8711_wx_get_range(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_range *range = (struct iw_range *)extra;
+ u16 val;
+ int i;
+
+ wrqu->data.length = sizeof(*range);
+ memset(range, 0, sizeof(*range));
+ /* Let's try to keep this struct in the same order as in
+ * linux/include/wireless.h
+ */
+
+ /* TODO: See what values we can set, and remove the ones we can't
+ * set, or fill them with some default data.
+ */
+ /* ~5 Mb/s real (802.11b) */
+ range->throughput = 5 * 1000 * 1000;
+ /* TODO: 8711 sensitivity ? */
+ /* signal level threshold range */
+ /* percent values between 0 and 100. */
+ range->max_qual.qual = 100;
+ range->max_qual.level = 100;
+ range->max_qual.noise = 100;
+ range->max_qual.updated = 7; /* Updated all three */
+ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
+ /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+ range->avg_qual.level = 20 + -98;
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = 7; /* Updated all three */
+ range->num_bitrates = RATE_COUNT;
+ for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
+ range->bitrate[i] = rtl8180_rates[i];
+ range->min_frag = MIN_FRAG_THRESHOLD;
+ range->max_frag = MAX_FRAG_THRESHOLD;
+ range->pm_capa = 0;
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 16;
+ range->num_channels = 14;
+ for (i = 0, val = 0; i < 14; i++) {
+ /* Include only legal frequencies for some countries */
+ range->freq[val].i = i + 1;
+ range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
+ range->freq[val].e = 1;
+ val++;
+ if (val == IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = val;
+ range->enc_capa = IW_ENC_CAPA_WPA |
+ IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP |
+ IW_ENC_CAPA_CIPHER_CCMP;
+ return 0;
+}
+
+static int r871x_wx_set_priv(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *awrq,
+ char *extra)
+{
+ int ret = 0, len = 0;
+ char *ext;
+ struct iw_point *dwrq = (struct iw_point *)awrq;
+
+ len = dwrq->length;
+ ext = _malloc(len);
+ if (!_malloc(len))
+ return -ENOMEM;
+ if (copy_from_user(ext, dwrq->pointer, len)) {
+ kfree(ext);
+ return -EFAULT;
+ }
+ kfree(ext);
+ return ret;
+}
+
+/* set bssid flow
+ * s1. set_802_11_infrastructure_mode()
+ * s2. set_802_11_authentication_mode()
+ * s3. set_802_11_encryption_mode()
+ * s4. set_802_11_bssid()
+ */
+static int r8711_wx_set_wap(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *awrq,
+ char *extra)
+{
+ int ret = -EINPROGRESS;
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+ struct sockaddr *temp = (struct sockaddr *)awrq;
+ unsigned long irqL;
+ struct list_head *phead;
+ u8 *dst_bssid;
+ struct wlan_network *pnetwork = NULL;
+ enum NDIS_802_11_AUTHENTICATION_MODE authmode;
+
+ if (padapter->bup == false)
+ return -1;
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
+ return -1;
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
+ return ret;
+ if (temp->sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+ authmode = padapter->securitypriv.ndisauthtype;
+ spin_lock_irqsave(&queue->lock, irqL);
+ phead = get_list_head(queue);
+ pmlmepriv->pscanned = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
+ break;
+ pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
+ struct wlan_network, list);
+ pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ dst_bssid = pnetwork->network.MacAddress;
+ if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
+ if (r8712_set_802_11_infrastructure_mode(padapter,
+ pnetwork->network.InfrastructureMode) == false)
+ ret = -1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&queue->lock, irqL);
+ if (!ret) {
+ if (!r8712_set_802_11_authentication_mode(padapter, authmode))
+ ret = -1;
+ else {
+ if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
+static int r8711_wx_get_wap(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
+ if (check_fwstate(pmlmepriv, _FW_LINKED |
+ WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
+ memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
+ }
+ return 0;
+}
+
+static int r871x_wx_set_mlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int ret = 0;
+ u16 reason;
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct iw_mlme *mlme = (struct iw_mlme *) extra;
+
+ if (mlme == NULL)
+ return -1;
+ reason = cpu_to_le16(mlme->reason_code);
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ if (!r8712_set_802_11_disassociate(padapter))
+ ret = -1;
+ break;
+ case IW_MLME_DISASSOC:
+ if (!r8712_set_802_11_disassociate(padapter))
+ ret = -1;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+static int r8711_wx_set_scan(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 status = true;
+
+ if (padapter->bDriverStopped == true) {
+ printk(KERN_WARNING "r8712u: in r8711_wx_set_scan: "
+ "bDriverStopped=%d\n", padapter->bDriverStopped);
+ return -1;
+ }
+ if (padapter->bup == false)
+ return -1;
+ if (padapter->hw_init_completed == false)
+ return -1;
+ if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
+ (pmlmepriv->sitesurveyctrl.traffic_busy == true))
+ return 0;
+ if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ struct ndis_802_11_ssid ssid;
+ unsigned long irqL;
+ u32 len = (u32) min((u8)req->essid_len,
+ (u8)IW_ESSID_MAX_SIZE);
+ memset((unsigned char *)&ssid, 0,
+ sizeof(struct ndis_802_11_ssid));
+ memcpy(ssid.Ssid, req->essid, len);
+ ssid.SsidLength = len;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
+ _FW_UNDER_LINKING)) ||
+ (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
+ status = false;
+ } else
+ status = r8712_sitesurvey_cmd(padapter, &ssid);
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ }
+ } else
+ status = r8712_set_802_11_bssid_list_scan(padapter);
+ if (status == false)
+ return -1;
+ return 0;
+}
+
+static int r8711_wx_get_scan(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+ struct wlan_network *pnetwork = NULL;
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ char *ev = extra;
+ char *stop = ev + wrqu->data.length;
+ u32 ret = 0, cnt = 0;
+
+ if (padapter->bDriverStopped)
+ return -EINVAL;
+ while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
+ msleep(30);
+ cnt++;
+ if (cnt > 1000)
+ break;
+ }
+ spin_lock_irqsave(&queue->lock, irqL);
+ phead = get_list_head(queue);
+ plist = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, plist) == true)
+ break;
+ if ((stop - ev) < SCAN_ITEM_SIZE) {
+ ret = -E2BIG;
+ break;
+ }
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+ ev = translate_scan(padapter, a, pnetwork, ev, stop);
+ plist = get_next(plist);
+ }
+ spin_unlock_irqrestore(&queue->lock, irqL);
+ wrqu->data.length = ev - extra;
+ wrqu->data.flags = 0;
+ return ret;
+}
+
+/* set ssid flow
+ * s1. set_802_11_infrastructure_mode()
+ * s2. set_802_11_authenticaion_mode()
+ * s3. set_802_11_encryption_mode()
+ * s4. set_802_11_ssid()
+ */
+static int r8711_wx_set_essid(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+ struct wlan_network *pnetwork = NULL;
+ enum NDIS_802_11_AUTHENTICATION_MODE authmode;
+ struct ndis_802_11_ssid ndis_ssid;
+ u8 *dst_ssid, *src_ssid;
+ struct list_head *phead;
+ u32 len;
+
+ if (padapter->bup == false)
+ return -1;
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
+ return -1;
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
+ return 0;
+ if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
+ return -E2BIG;
+ authmode = padapter->securitypriv.ndisauthtype;
+ if (wrqu->essid.flags && wrqu->essid.length) {
+ len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
+ wrqu->essid.length : IW_ESSID_MAX_SIZE;
+ memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
+ ndis_ssid.SsidLength = len;
+ memcpy(ndis_ssid.Ssid, extra, len);
+ src_ssid = ndis_ssid.Ssid;
+ phead = get_list_head(queue);
+ pmlmepriv->pscanned = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, pmlmepriv->pscanned))
+ break;
+ pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
+ struct wlan_network, list);
+ pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ dst_ssid = pnetwork->network.Ssid.Ssid;
+ if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
+ && (pnetwork->network.Ssid.SsidLength ==
+ ndis_ssid.SsidLength)) {
+ if (!r8712_set_802_11_infrastructure_mode(
+ padapter,
+ pnetwork->network.InfrastructureMode))
+ return -1;
+ break;
+ }
+ }
+ r8712_set_802_11_authentication_mode(padapter, authmode);
+ r8712_set_802_11_ssid(padapter, &ndis_ssid);
+ }
+ return -EINPROGRESS;
+}
+
+static int r8711_wx_get_essid(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+ u32 len, ret = 0;
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+ len = pcur_bss->Ssid.SsidLength;
+ wrqu->essid.length = len;
+ memcpy(extra, pcur_bss->Ssid.Ssid, len);
+ wrqu->essid.flags = 1;
+ } else
+ ret = -1;
+ return ret;
+}
+
+static int r8711_wx_set_rate(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ u32 target_rate = wrqu->bitrate.value;
+ u32 fixed = wrqu->bitrate.fixed;
+ u32 ratevalue = 0;
+ u8 datarates[NumRates];
+ u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
+ int i, ret = 0;
+
+ if (target_rate == -1) {
+ ratevalue = 11;
+ goto set_rate;
+ }
+ target_rate = target_rate / 100000;
+ switch (target_rate) {
+ case 10:
+ ratevalue = 0;
+ break;
+ case 20:
+ ratevalue = 1;
+ break;
+ case 55:
+ ratevalue = 2;
+ break;
+ case 60:
+ ratevalue = 3;
+ break;
+ case 90:
+ ratevalue = 4;
+ break;
+ case 110:
+ ratevalue = 5;
+ break;
+ case 120:
+ ratevalue = 6;
+ break;
+ case 180:
+ ratevalue = 7;
+ break;
+ case 240:
+ ratevalue = 8;
+ break;
+ case 360:
+ ratevalue = 9;
+ break;
+ case 480:
+ ratevalue = 10;
+ break;
+ case 540:
+ ratevalue = 11;
+ break;
+ default:
+ ratevalue = 11;
+ break;
+ }
+set_rate:
+ for (i = 0; i < NumRates; i++) {
+ if (ratevalue == mpdatarate[i]) {
+ datarates[i] = mpdatarate[i];
+ if (fixed == 0)
+ break;
+ } else
+ datarates[i] = 0xff;
+ }
+ if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
+ ret = -1;
+ return ret;
+}
+
+static int r8711_wx_get_rate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+ struct ieee80211_ht_cap *pht_capie;
+ int i;
+ u8 *p;
+ u16 rate, max_rate = 0, ht_cap = false;
+ u32 ht_ielen = 0;
+ u8 bw_40MHz = 0, short_GI = 0;
+ u16 mcs_rate = 0;
+
+ i = 0;
+ if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+ p = r8712_get_ie(&pcur_bss->IEs[12],
+ _HT_CAPABILITY_IE_, &ht_ielen,
+ pcur_bss->IELength - 12);
+ if (p && ht_ielen > 0) {
+ ht_cap = true;
+ pht_capie = (struct ieee80211_ht_cap *)(p + 2);
+ memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
+ bw_40MHz = (pht_capie->cap_info &
+ IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
+ short_GI = (pht_capie->cap_info &
+ (IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
+ }
+ while ((pcur_bss->SupportedRates[i] != 0) &&
+ (pcur_bss->SupportedRates[i] != 0xFF)) {
+ rate = pcur_bss->SupportedRates[i] & 0x7F;
+ if (rate > max_rate)
+ max_rate = rate;
+ wrqu->bitrate.fixed = 0; /* no auto select */
+ wrqu->bitrate.value = rate*500000;
+ i++;
+ }
+ if (ht_cap == true) {
+ if (mcs_rate & 0x8000) /* MCS15 */
+ max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
+ 270) : ((short_GI) ? 144 : 130);
+ else if (mcs_rate & 0x0080) /* MCS7 */
+ max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
+ 135) : ((short_GI) ? 72 : 65);
+ else /* default MCS7 */
+ max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
+ 135) : ((short_GI) ? 72 : 65);
+ max_rate *= 2; /* Mbps/2 */
+ wrqu->bitrate.value = max_rate * 500000;
+ } else {
+ wrqu->bitrate.value = max_rate * 500000;
+ }
+ } else
+ return -1;
+ return 0;
+}
+
+static int r8711_wx_get_rts(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+
+ wrqu->rts.value = padapter->registrypriv.rts_thresh;
+ wrqu->rts.fixed = 0; /* no auto select */
+ return 0;
+}
+
+static int r8711_wx_set_frag(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+
+ if (wrqu->frag.disabled)
+ padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
+ else {
+ if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
+ wrqu->frag.value > MAX_FRAG_THRESHOLD)
+ return -EINVAL;
+ padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
+ }
+ return 0;
+}
+
+static int r8711_wx_get_frag(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+
+ wrqu->frag.value = padapter->xmitpriv.frag_len;
+ wrqu->frag.fixed = 0; /* no auto select */
+ return 0;
+}
+
+static int r8711_wx_get_retry(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wrqu->retry.value = 7;
+ wrqu->retry.fixed = 0; /* no auto select */
+ wrqu->retry.disabled = 1;
+ return 0;
+}
+
+static int r8711_wx_set_enc(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *keybuf)
+{
+ u32 key;
+ u32 keyindex_provided;
+ struct NDIS_802_11_WEP wep;
+ enum NDIS_802_11_AUTHENTICATION_MODE authmode;
+ struct iw_point *erq = &(wrqu->encoding);
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+
+ key = erq->flags & IW_ENCODE_INDEX;
+ memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
+ "EncryptionDisabled\n");
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11EncryptionDisabled;
+ padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
+ padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
+ padapter->securitypriv.AuthAlgrthm = 0; /* open system */
+ authmode = Ndis802_11AuthModeOpen;
+ padapter->securitypriv.ndisauthtype = authmode;
+ return 0;
+ }
+ if (key) {
+ if (key > WEP_KEYS)
+ return -EINVAL;
+ key--;
+ keyindex_provided = 1;
+ } else {
+ keyindex_provided = 0;
+ key = padapter->securitypriv.PrivacyKeyIndex;
+ }
+ /* set authentication mode */
+ if (erq->flags & IW_ENCODE_OPEN) {
+ printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
+ "IW_ENCODE_OPEN\n");
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.AuthAlgrthm = 0; /* open system */
+ padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
+ padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
+ authmode = Ndis802_11AuthModeOpen;
+ padapter->securitypriv.ndisauthtype = authmode;
+ } else if (erq->flags & IW_ENCODE_RESTRICTED) {
+ printk(KERN_INFO "r8712u: r8711_wx_set_enc: "
+ "IW_ENCODE_RESTRICTED\n");
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.AuthAlgrthm = 1; /* shared system */
+ padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
+ padapter->securitypriv.XGrpPrivacy = _WEP40_;
+ authmode = Ndis802_11AuthModeShared;
+ padapter->securitypriv.ndisauthtype = authmode;
+ } else {
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption1Enabled;
+ padapter->securitypriv.AuthAlgrthm = 0; /* open system */
+ padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
+ padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
+ authmode = Ndis802_11AuthModeOpen;
+ padapter->securitypriv.ndisauthtype = authmode;
+ }
+ wep.KeyIndex = key;
+ if (erq->length > 0) {
+ wep.KeyLength = erq->length <= 5 ? 5 : 13;
+ wep.Length = wep.KeyLength +
+ FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
+ } else {
+ wep.KeyLength = 0 ;
+ if (keyindex_provided == 1) { /* set key_id only, no given
+ * KeyMaterial(erq->length==0).*/
+ padapter->securitypriv.PrivacyKeyIndex = key;
+ switch (padapter->securitypriv.DefKeylen[key]) {
+ case 5:
+ padapter->securitypriv.PrivacyAlgrthm =
+ _WEP40_;
+ break;
+ case 13:
+ padapter->securitypriv.PrivacyAlgrthm =
+ _WEP104_;
+ break;
+ default:
+ padapter->securitypriv.PrivacyAlgrthm =
+ _NO_PRIVACY_;
+ break;
+ }
+ return 0;
+ }
+ }
+ wep.KeyIndex |= 0x80000000; /* transmit key */
+ memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
+ if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
+ return -EOPNOTSUPP;
+ return 0;
+}
+
+static int r8711_wx_get_enc(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *keybuf)
+{
+ uint key, ret = 0;
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ struct iw_point *erq = &(wrqu->encoding);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ return 0;
+ }
+ }
+ key = erq->flags & IW_ENCODE_INDEX;
+ if (key) {
+ if (key > WEP_KEYS)
+ return -EINVAL;
+ key--;
+ } else {
+ key = padapter->securitypriv.PrivacyKeyIndex;
+ }
+ erq->flags = key + 1;
+ switch (padapter->securitypriv.ndisencryptstatus) {
+ case Ndis802_11EncryptionNotSupported:
+ case Ndis802_11EncryptionDisabled:
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ break;
+ case Ndis802_11Encryption1Enabled:
+ erq->length = padapter->securitypriv.DefKeylen[key];
+ if (erq->length) {
+ memcpy(keybuf, padapter->securitypriv.DefKey[
+ key].skey, padapter->securitypriv.
+ DefKeylen[key]);
+ erq->flags |= IW_ENCODE_ENABLED;
+ if (padapter->securitypriv.ndisauthtype ==
+ Ndis802_11AuthModeOpen)
+ erq->flags |= IW_ENCODE_OPEN;
+ else if (padapter->securitypriv.ndisauthtype ==
+ Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ } else {
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ }
+ break;
+ case Ndis802_11Encryption2Enabled:
+ case Ndis802_11Encryption3Enabled:
+ erq->length = 16;
+ erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
+ IW_ENCODE_NOKEY);
+ break;
+ default:
+ erq->length = 0;
+ erq->flags |= IW_ENCODE_DISABLED;
+ break;
+ }
+ return ret;
+}
+
+static int r8711_wx_get_power(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wrqu->power.value = 0;
+ wrqu->power.fixed = 0; /* no auto select */
+ wrqu->power.disabled = 1;
+ return 0;
+}
+
+static int r871x_wx_set_gen_ie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+
+ return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
+}
+
+static int r871x_wx_set_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct iw_param *param = (struct iw_param *)&(wrqu->param);
+ int paramid;
+ int paramval;
+ int ret = 0;
+
+ paramid = param->flags & IW_AUTH_INDEX;
+ paramval = param->value;
+ switch (paramid) {
+ case IW_AUTH_WPA_VERSION:
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ break;
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * ??? does not use these parameters
+ */
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ if (paramval) {
+ /* wpa_supplicant is enabling tkip countermeasure. */
+ padapter->securitypriv.btkip_countermeasure = true;
+ } else {
+ /* wpa_supplicant is disabling tkip countermeasure. */
+ padapter->securitypriv.btkip_countermeasure = false;
+ }
+ break;
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /* HACK:
+ *
+ * wpa_supplicant calls set_wpa_enabled when the driver
+ * is loaded and unloaded, regardless of if WPA is being
+ * used. No other calls are made which can be used to
+ * determine if encryption will be used or not prior to
+ * association being expected. If encryption is not being
+ * used, drop_unencrypted is set to false, else true -- we
+ * can use this to determine if the CAP_PRIVACY_ON bit should
+ * be set.
+ */
+ if (padapter->securitypriv.ndisencryptstatus ==
+ Ndis802_11Encryption1Enabled) {
+ /* it means init value, or using wep,
+ * ndisencryptstatus =
+ * Ndis802_11Encryption1Enabled,
+ * then it needn't reset it;
+ */
+ break;
+ }
+
+ if (paramval) {
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11EncryptionDisabled;
+ padapter->securitypriv.PrivacyAlgrthm =
+ _NO_PRIVACY_;
+ padapter->securitypriv.XGrpPrivacy =
+ _NO_PRIVACY_;
+ padapter->securitypriv.AuthAlgrthm = 0;
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeOpen;
+ }
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ ret = wpa_set_auth_algs(dev, (u32)paramval);
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+static int r871x_wx_set_enc_ext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *pencoding = &wrqu->encoding;
+ struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
+ struct ieee_param *param = NULL;
+ char *alg_name;
+ u32 param_len;
+ int ret = 0;
+
+ param_len = sizeof(struct ieee_param) + pext->key_len;
+ param = (struct ieee_param *)_malloc(param_len);
+ if (param == NULL)
+ return -1;
+ memset(param, 0, param_len);
+ param->cmd = IEEE_CMD_SET_ENCRYPTION;
+ memset(param->sta_addr, 0xff, ETH_ALEN);
+ switch (pext->alg) {
+ case IW_ENCODE_ALG_NONE:
+ alg_name = "none";
+ break;
+ case IW_ENCODE_ALG_WEP:
+ alg_name = "WEP";
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ alg_name = "TKIP";
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ alg_name = "CCMP";
+ break;
+ default:
+ return -1;
+ }
+ strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
+ if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ param->u.crypt.set_tx = 0;
+ if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ param->u.crypt.set_tx = 1;
+ param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
+ if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ memcpy(param->u.crypt.seq, pext->rx_seq, 8);
+ if (pext->key_len) {
+ param->u.crypt.key_len = pext->key_len;
+ memcpy(param + 1, pext + 1, pext->key_len);
+ }
+ ret = wpa_set_encryption(dev, param, param_len);
+ if (param)
+ kfree((u8 *)param);
+ return ret;
+}
+
+static int r871x_wx_get_nick(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ if (extra) {
+ wrqu->data.length = 8;
+ wrqu->data.flags = 1;
+ memcpy(extra, "rtl_wifi", 8);
+ }
+ return 0;
+}
+
+static int r8711_wx_read32(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *keybuf)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ u32 addr;
+ u32 data32;
+
+ get_user(addr, (u32 __user *)wrqu->data.pointer);
+ data32 = r8712_read32(padapter, addr);
+ put_user(data32, (u32 __user *)wrqu->data.pointer);
+ wrqu->data.length = (data32 & 0xffff0000) >> 16;
+ wrqu->data.flags = data32 & 0xffff;
+ get_user(addr, (u32 __user *)wrqu->data.pointer);
+ return 0;
+}
+
+static int r8711_wx_write32(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *keybuf)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ u32 addr;
+ u32 data32;
+
+ get_user(addr, (u32 __user *)wrqu->data.pointer);
+ data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
+ r8712_write32(padapter, addr, data32);
+ return 0;
+}
+
+static int dummy(struct net_device *dev,
+ struct iw_request_info *a,
+ union iwreq_data *wrqu, char *b)
+{
+ return -1;
+}
+
+static int r8711_drvext_hdl(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+}
+
+static int r871x_mp_ioctl_hdl(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct iw_point *p = &wrqu->data;
+ struct oid_par_priv oid_par;
+ struct mp_ioctl_handler *phandler;
+ struct mp_ioctl_param *poidparam;
+ unsigned long BytesRead, BytesWritten, BytesNeeded;
+ u8 *pparmbuf = NULL, bset;
+ u16 len;
+ uint status;
+ int ret = 0;
+
+ if ((!p->length) || (!p->pointer)) {
+ ret = -EINVAL;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ bset = (u8)(p->flags & 0xFFFF);
+ len = p->length;
+ pparmbuf = NULL;
+ pparmbuf = (u8 *)_malloc(len);
+ if (pparmbuf == NULL) {
+ ret = -ENOMEM;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ if (copy_from_user(pparmbuf, p->pointer, len)) {
+ ret = -EFAULT;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ poidparam = (struct mp_ioctl_param *)pparmbuf;
+ if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
+ ret = -EINVAL;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ phandler = mp_ioctl_hdl + poidparam->subcode;
+ if ((phandler->paramsize != 0) &&
+ (poidparam->len < phandler->paramsize)) {
+ ret = -EINVAL;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ if (phandler->oid == 0 && phandler->handler)
+ status = phandler->handler(&oid_par);
+ else if (phandler->handler) {
+ oid_par.adapter_context = padapter;
+ oid_par.oid = phandler->oid;
+ oid_par.information_buf = poidparam->data;
+ oid_par.information_buf_len = poidparam->len;
+ oid_par.dbg = 0;
+ BytesWritten = 0;
+ BytesNeeded = 0;
+ if (bset) {
+ oid_par.bytes_rw = &BytesRead;
+ oid_par.bytes_needed = &BytesNeeded;
+ oid_par.type_of_oid = SET_OID;
+ } else {
+ oid_par.bytes_rw = &BytesWritten;
+ oid_par.bytes_needed = &BytesNeeded;
+ oid_par.type_of_oid = QUERY_OID;
+ }
+ status = phandler->handler(&oid_par);
+ /* todo:check status, BytesNeeded, etc. */
+ } else {
+ printk(KERN_INFO "r8712u: r871x_mp_ioctl_hdl(): err!,"
+ " subcode=%d, oid=%d, handler=%p\n",
+ poidparam->subcode, phandler->oid, phandler->handler);
+ ret = -EFAULT;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+ if (bset == 0x00) { /* query info */
+ if (copy_to_user(p->pointer, pparmbuf, len))
+ ret = -EFAULT;
+ }
+ if (status) {
+ ret = -EFAULT;
+ goto _r871x_mp_ioctl_hdl_exit;
+ }
+_r871x_mp_ioctl_hdl_exit:
+ if (pparmbuf != NULL)
+ kfree(pparmbuf);
+ return ret;
+}
+
+static int r871x_get_ap_info(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+ struct iw_point *pdata = &wrqu->data;
+ struct wlan_network *pnetwork = NULL;
+ u32 cnt = 0, wpa_ielen;
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ unsigned char *pbuf;
+ u8 bssid[ETH_ALEN];
+ char data[32];
+
+ if (padapter->bDriverStopped || (pdata == NULL))
+ return -EINVAL;
+ while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
+ msleep(30);
+ cnt++;
+ if (cnt > 100)
+ break;
+ }
+ pdata->flags = 0;
+ if (pdata->length >= 32) {
+ if (copy_from_user(data, pdata->pointer, 32))
+ return -EINVAL;
+ } else
+ return -EINVAL;
+ spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
+ phead = get_list_head(queue);
+ plist = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, plist) == true)
+ break;
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+ if (hwaddr_aton_i(data, bssid)) {
+ printk(KERN_INFO "r8712u: Invalid BSSID '%s'.\n",
+ (u8 *)data);
+ spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
+ irqL);
+ return -EINVAL;
+ }
+ printk(KERN_INFO "r8712u: BSSID:" MACSTR "\n",
+ MAC2STR(bssid));
+ if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
+ /* BSSID match, then check if supporting wpa/wpa2 */
+ pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
+ &wpa_ielen, pnetwork->network.IELength-12);
+ if (pbuf && (wpa_ielen > 0)) {
+ pdata->flags = 1;
+ break;
+ }
+ pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
+ &wpa_ielen, pnetwork->network.IELength-12);
+ if (pbuf && (wpa_ielen > 0)) {
+ pdata->flags = 2;
+ break;
+ }
+ }
+ plist = get_next(plist);
+ }
+ spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
+ if (pdata->length >= 34) {
+ if (copy_to_user((u8 __user *)pdata->pointer + 32,
+ (u8 *)&pdata->flags, 1))
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int r871x_set_pid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ struct iw_point *pdata = &wrqu->data;
+
+ if ((padapter->bDriverStopped) || (pdata == NULL))
+ return -EINVAL;
+ if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
+ return -EINVAL;
+ return 0;
+}
+
+static int r871x_wps_start(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev);
+ struct iw_point *pdata = &wrqu->data;
+ u32 u32wps_start = 0;
+ unsigned int uintRet = 0;
+
+ uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
+ if ((padapter->bDriverStopped) || (pdata == NULL))
+ return -EINVAL;
+ if (u32wps_start == 0)
+ u32wps_start = *extra;
+ if (u32wps_start == 1) /* WPS Start */
+ padapter->ledpriv.LedControlHandler(padapter,
+ LED_CTL_START_WPS);
+ else if (u32wps_start == 2) /* WPS Stop because of wps success */
+ padapter->ledpriv.LedControlHandler(padapter,
+ LED_CTL_STOP_WPS);
+ else if (u32wps_start == 3) /* WPS Stop because of wps fail */
+ padapter->ledpriv.LedControlHandler(padapter,
+ LED_CTL_STOP_WPS_FAIL);
+ return 0;
+}
+
+static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+
+ switch (name) {
+ case IEEE_PARAM_WPA_ENABLED:
+ padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */
+ switch ((value)&0xff) {
+ case 1: /* WPA */
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption2Enabled;
+ break;
+ case 2: /* WPA2 */
+ padapter->securitypriv.ndisauthtype =
+ Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
+ padapter->securitypriv.ndisencryptstatus =
+ Ndis802_11Encryption3Enabled;
+ break;
+ }
+ break;
+ case IEEE_PARAM_TKIP_COUNTERMEASURES:
+ break;
+ case IEEE_PARAM_DROP_UNENCRYPTED:
+ /* HACK:
+ *
+ * wpa_supplicant calls set_wpa_enabled when the driver
+ * is loaded and unloaded, regardless of if WPA is being
+ * used. No other calls are made which can be used to
+ * determine if encryption will be used or not prior to
+ * association being expected. If encryption is not being
+ * used, drop_unencrypted is set to false, else true -- we
+ * can use this to determine if the CAP_PRIVACY_ON bit should
+ * be set.
+ */
+ break;
+ case IEEE_PARAM_PRIVACY_INVOKED:
+ break;
+ case IEEE_PARAM_AUTH_ALGS:
+ return wpa_set_auth_algs(dev, value);
+ break;
+ case IEEE_PARAM_IEEE_802_1X:
+ break;
+ case IEEE_PARAM_WPAX_SELECT:
+ /* added for WPA2 mixed mode */
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+
+ switch (command) {
+ case IEEE_MLME_STA_DEAUTH:
+ if (!r8712_set_802_11_disassociate(padapter))
+ return -1;
+ break;
+ case IEEE_MLME_STA_DISASSOC:
+ if (!r8712_set_802_11_disassociate(padapter))
+ return -1;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
+{
+ struct ieee_param *param;
+ int ret = 0;
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+
+ if (p->length < sizeof(struct ieee_param) || !p->pointer)
+ return -EINVAL;
+ param = (struct ieee_param *)_malloc(p->length);
+ if (param == NULL)
+ return -ENOMEM;
+ if (copy_from_user(param, p->pointer, p->length))
+ kfree((u8 *)param);
+ return -EFAULT;
+ switch (param->cmd) {
+ case IEEE_CMD_SET_WPA_PARAM:
+ ret = wpa_set_param(dev, param->u.wpa_param.name,
+ param->u.wpa_param.value);
+ break;
+ case IEEE_CMD_SET_WPA_IE:
+ ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
+ (u16)param->u.wpa_ie.len);
+ break;
+ case IEEE_CMD_SET_ENCRYPTION:
+ ret = wpa_set_encryption(dev, param, p->length);
+ break;
+ case IEEE_CMD_MLME:
+ ret = wpa_mlme(dev, param->u.mlme.command,
+ param->u.mlme.reason_code);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ if (ret == 0 && copy_to_user(p->pointer, param, p->length))
+ ret = -EFAULT;
+ kfree((u8 *)param);
+ return ret;
+}
+
+/* based on "driver_ipw" and for hostapd */
+int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct iwreq *wrq = (struct iwreq *)rq;
+
+ switch (cmd) {
+ case RTL_IOCTL_WPA_SUPPLICANT:
+ return wpa_supplicant_ioctl(dev, &wrq->u.data);
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static iw_handler r8711_handlers[] = {
+ NULL, /* SIOCSIWCOMMIT */
+ r8711_wx_get_name, /* SIOCGIWNAME */
+ dummy, /* SIOCSIWNWID */
+ dummy, /* SIOCGIWNWID */
+ r8711_wx_set_freq, /* SIOCSIWFREQ */
+ r8711_wx_get_freq, /* SIOCGIWFREQ */
+ r8711_wx_set_mode, /* SIOCSIWMODE */
+ r8711_wx_get_mode, /* SIOCGIWMODE */
+ dummy, /* SIOCSIWSENS */
+ r8711_wx_get_sens, /* SIOCGIWSENS */
+ NULL, /* SIOCSIWRANGE */
+ r8711_wx_get_range, /* SIOCGIWRANGE */
+ r871x_wx_set_priv, /* SIOCSIWPRIV */
+ NULL, /* SIOCGIWPRIV */
+ NULL, /* SIOCSIWSTATS */
+ NULL, /* SIOCGIWSTATS */
+ dummy, /* SIOCSIWSPY */
+ dummy, /* SIOCGIWSPY */
+ NULL, /* SIOCGIWTHRSPY */
+ NULL, /* SIOCWIWTHRSPY */
+ r8711_wx_set_wap, /* SIOCSIWAP */
+ r8711_wx_get_wap, /* SIOCGIWAP */
+ r871x_wx_set_mlme, /* request MLME operation;
+ * uses struct iw_mlme */
+ dummy, /* SIOCGIWAPLIST -- deprecated */
+ r8711_wx_set_scan, /* SIOCSIWSCAN */
+ r8711_wx_get_scan, /* SIOCGIWSCAN */
+ r8711_wx_set_essid, /* SIOCSIWESSID */
+ r8711_wx_get_essid, /* SIOCGIWESSID */
+ dummy, /* SIOCSIWNICKN */
+ r871x_wx_get_nick, /* SIOCGIWNICKN */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ r8711_wx_set_rate, /* SIOCSIWRATE */
+ r8711_wx_get_rate, /* SIOCGIWRATE */
+ dummy, /* SIOCSIWRTS */
+ r8711_wx_get_rts, /* SIOCGIWRTS */
+ r8711_wx_set_frag, /* SIOCSIWFRAG */
+ r8711_wx_get_frag, /* SIOCGIWFRAG */
+ dummy, /* SIOCSIWTXPOW */
+ dummy, /* SIOCGIWTXPOW */
+ dummy, /* SIOCSIWRETRY */
+ r8711_wx_get_retry, /* SIOCGIWRETRY */
+ r8711_wx_set_enc, /* SIOCSIWENCODE */
+ r8711_wx_get_enc, /* SIOCGIWENCODE */
+ dummy, /* SIOCSIWPOWER */
+ r8711_wx_get_power, /* SIOCGIWPOWER */
+ NULL, /*---hole---*/
+ NULL, /*---hole---*/
+ r871x_wx_set_gen_ie, /* SIOCSIWGENIE */
+ NULL, /* SIOCGIWGENIE */
+ r871x_wx_set_auth, /* SIOCSIWAUTH */
+ NULL, /* SIOCGIWAUTH */
+ r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
+ NULL, /* SIOCGIWENCODEEXT */
+ r871x_wx_set_pmkid, /* SIOCSIWPMKSA */
+ NULL, /*---hole---*/
+};
+
+static const struct iw_priv_args r8711_private_args[] = {
+ {
+ SIOCIWFIRSTPRIV + 0x0,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x1,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x4,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x5,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
+ },
+ {
+ SIOCIWFIRSTPRIV + 0x6,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
+ }
+};
+
+static iw_handler r8711_private_handler[] = {
+ r8711_wx_read32,
+ r8711_wx_write32,
+ r8711_drvext_hdl,
+ r871x_mp_ioctl_hdl,
+ r871x_get_ap_info, /*for MM DTV platform*/
+ r871x_set_pid,
+ r871x_wps_start,
+};
+
+static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
+{
+ struct _adapter *padapter = (struct _adapter *) _netdev_priv(dev);
+ struct iw_statistics *piwstats = &padapter->iwstats;
+ int tmp_level = 0;
+ int tmp_qual = 0;
+ int tmp_noise = 0;
+
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
+ piwstats->qual.qual = 0;
+ piwstats->qual.level = 0;
+ piwstats->qual.noise = 0;
+ } else {
+ /* show percentage, we need transfer dbm to orignal value. */
+ tmp_level = padapter->recvpriv.fw_rssi;
+ tmp_qual = padapter->recvpriv.signal;
+ tmp_noise = padapter->recvpriv.noise;
+ piwstats->qual.level = tmp_level;
+ piwstats->qual.qual = tmp_qual;
+ piwstats->qual.noise = tmp_noise;
+ }
+ piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
+ return &padapter->iwstats;
+}
+
+struct iw_handler_def r871x_handlers_def = {
+ .standard = r8711_handlers,
+ .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler),
+ .private = r8711_private_handler,
+ .private_args = (struct iw_priv_args *)r8711_private_args,
+ .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(r8711_private_args) /
+ sizeof(struct iw_priv_args),
+ .get_wireless_stats = r871x_get_wireless_stats,
+};
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
new file mode 100644
index 000000000000..7adbe82cd085
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
@@ -0,0 +1,535 @@
+/******************************************************************************
+ * rtl871x_ioctl_rtl.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_IOCTL_RTL_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wlan_bssdef.h"
+#include "wifi.h"
+#include "rtl871x_ioctl.h"
+#include "rtl871x_ioctl_set.h"
+#include "rtl871x_ioctl_rtl.h"
+#include "mp_custom_oid.h"
+#include "rtl871x_mp.h"
+#include "rtl871x_mp_ioctl.h"
+
+uint oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_smallpacket_crcerr;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_middlepacket_crcerr;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_largepacket_crcerr;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_pkts +
+ padapter->recvpriv.rx_drop;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(uint *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_icv_err;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH ;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 preamblemode = 0 ;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ if (padapter->registrypriv.preamble == PREAMBLE_LONG)
+ preamblemode = 0;
+ else if (padapter->registrypriv.preamble == PREAMBLE_AUTO)
+ preamblemode = 1;
+ else if (padapter->registrypriv.preamble == PREAMBLE_SHORT)
+ preamblemode = 2;
+ *(u32 *)poid_par_priv->information_buf = preamblemode;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct eeprom_priv *peeprompriv = &padapter->eeprompriv;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ *(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_set_channelplan_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct eeprom_priv *peeprompriv = &padapter->eeprompriv;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_set_preamble_mode_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 preamblemode = 0;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ preamblemode = *(u32 *)poid_par_priv->information_buf;
+ if (preamblemode == 0)
+ padapter->registrypriv.preamble = PREAMBLE_LONG;
+ else if (preamblemode == 1)
+ padapter->registrypriv.preamble = PREAMBLE_AUTO;
+ else if (preamblemode == 2)
+ padapter->registrypriv.preamble = PREAMBLE_SHORT;
+ *(u32 *)poid_par_priv->information_buf = preamblemode;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_dedicate_probe_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->xmitpriv.tx_bytes;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ padapter->recvpriv.rx_bytes;
+ *poid_par_priv->bytes_rw = poid_par_priv->
+ information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_current_tx_power_level_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct NDIS_802_11_CONFIGURATION *pnic_Config;
+ u32 channelnum;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
+ pnic_Config = &pmlmepriv->cur_network.network.Configuration;
+ else
+ pnic_Config = &padapter->registrypriv.dev_network.
+ Configuration;
+ channelnum = pnic_Config->DSConfig;
+ *(u32 *)poid_par_priv->information_buf = channelnum;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_supported_wireless_mode_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ u32 ulInfo = 0;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len >= sizeof(u32)) {
+ ulInfo |= 0x0100; /* WIRELESS_MODE_B */
+ ulInfo |= 0x0200; /* WIRELESS_MODE_G */
+ ulInfo |= 0x0400; /* WIRELESS_MODE_A */
+ *(u32 *) poid_par_priv->information_buf = ulInfo;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ return NDIS_STATUS_INVALID_LENGTH;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+uint oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv*
+ poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv*
+ poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len ==
+ (sizeof(unsigned long) * 3)) {
+ if (!r8712_setrfreg_cmd(Adapter,
+ *(unsigned char *)poid_par_priv->information_buf,
+ (unsigned long)(*((unsigned long *)
+ poid_par_priv->information_buf + 2))))
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+uint oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len == (sizeof(unsigned long)*3)) {
+ if (Adapter->mppriv.act_in_progress == true)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ else {
+ /* init workparam */
+ Adapter->mppriv.act_in_progress = true;
+ Adapter->mppriv.workparam.bcompleted = false;
+ Adapter->mppriv.workparam.act_type = MPT_READ_RF;
+ Adapter->mppriv.workparam.io_offset = *(unsigned long *)
+ poid_par_priv->information_buf;
+ Adapter->mppriv.workparam.io_value = 0xcccccccc;
+
+ /* RegOffsetValue - The offset of RF register to read.
+ * RegDataWidth - The data width of RF register to read.
+ * RegDataValue - The value to read.
+ * RegOffsetValue = *((unsigned long *)InformationBuffer);
+ * RegDataWidth = *((unsigned long *)InformationBuffer+1);
+ * RegDataValue = *((unsigned long *)InformationBuffer+2);
+ */
+ if (!r8712_getrfreg_cmd(Adapter,
+ *(unsigned char *)poid_par_priv->information_buf,
+ (unsigned char *)&Adapter->mppriv.workparam.
+ io_value))
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ }
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+enum _CONNECT_STATE_{
+ CHECKINGSTATUS,
+ ASSOCIATED,
+ ADHOCMODE,
+ NOTASSOCIATED
+};
+
+uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *padapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u32 ulInfo;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ /* nStatus==0 CheckingStatus
+ * nStatus==1 Associated
+ * nStatus==2 AdHocMode
+ * nStatus==3 NotAssociated
+ */
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
+ ulInfo = CHECKINGSTATUS;
+ else if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+ ulInfo = ASSOCIATED;
+ else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
+ ulInfo = ADHOCMODE;
+ else
+ ulInfo = NOTASSOCIATED ;
+ *(u32 *)poid_par_priv->information_buf = ulInfo;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h
new file mode 100644
index 000000000000..4f1aa876d75d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h
@@ -0,0 +1,96 @@
+#ifndef _RTL871X_IOCTL_RTL_H
+#define _RTL871X_IOCTL_RTL_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+/*************** oid_rtl_seg_01_01 **************/
+uint oid_rt_get_signal_quality_hdl(
+ struct oid_par_priv *poid_par_priv);/*84*/
+uint oid_rt_get_small_packet_crc_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_middle_packet_crc_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_large_packet_crc_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_tx_retry_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_rx_retry_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_rx_total_packet_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_tx_beacon_ok_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_tx_beacon_err_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_rx_icv_err_hdl(
+ struct oid_par_priv *poid_par_priv);/*93*/
+uint oid_rt_set_encryption_algorithm_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_preamble_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_ap_ip_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_channelplan_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_channelplan_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_preamble_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_bcn_intvl_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_dedicate_probe_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_total_tx_bytes_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_total_rx_bytes_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_current_tx_power_level_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_enc_key_mismatch_count_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_enc_key_match_count_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_channel_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_hardware_radio_off_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_key_mismatch_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_supported_wireless_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_channel_list_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_scan_in_progress_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_forced_data_rate_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_wireless_mode_for_scan_list_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_bss_wireless_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_scan_with_magic_packet_hdl(
+ struct oid_par_priv *poid_par_priv);
+
+/************** oid_rtl_seg_01_03 section start **************/
+uint oid_rt_ap_get_associated_station_list_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_ap_switch_into_ap_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_ap_supported_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_ap_set_passphrase_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_01_11 */
+uint oid_rt_pro_rf_write_registry_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_rf_read_registry_hdl(
+ struct oid_par_priv *poid_par_priv);
+/*************** oid_rtl_seg_03_00 section start **************/
+uint oid_rt_get_connect_state_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_default_key_id_hdl(
+ struct oid_par_priv *poid_par_priv);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
new file mode 100644
index 000000000000..8b1451d03069
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
@@ -0,0 +1,379 @@
+/******************************************************************************
+ * rtl871x_ioctl_set.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_IOCTL_SET_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_ioctl_set.h"
+#include "usb_osintf.h"
+#include "usb_ops.h"
+
+#define IS_MAC_ADDRESS_BROADCAST(addr) \
+( \
+ ((addr[0] == 0xff) && (addr[1] == 0xff) && \
+ (addr[2] == 0xff) && (addr[3] == 0xff) && \
+ (addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \
+)
+
+static u8 validate_ssid(struct ndis_802_11_ssid *ssid)
+{
+ u8 i;
+
+ if (ssid->SsidLength > 32)
+ return false;
+ for (i = 0; i < ssid->SsidLength; i++) {
+ /* wifi, printable ascii code must be supported */
+ if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e)))
+ return false;
+ }
+ return true;
+}
+
+static u8 do_join(struct _adapter *padapter)
+{
+ struct list_head *plist, *phead;
+ u8 *pibss = NULL;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct __queue *queue = &(pmlmepriv->scanned_queue);
+
+ phead = get_list_head(queue);
+ plist = get_next(phead);
+ pmlmepriv->cur_network.join_res = -2;
+ pmlmepriv->fw_state |= _FW_UNDER_LINKING;
+ pmlmepriv->pscanned = plist;
+ pmlmepriv->to_join = true;
+ if (_queue_empty(queue) == true) {
+ if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
+ pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
+ /* when set_ssid/set_bssid for do_join(), but scanning queue
+ * is empty we try to issue sitesurvey firstly
+ */
+ if (pmlmepriv->sitesurveyctrl.traffic_busy == false)
+ r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid);
+ return true;
+ } else {
+ int ret;
+
+ ret = r8712_select_and_join_from_scan(pmlmepriv);
+ if (ret == _SUCCESS)
+ _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
+ else {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ /* submit r8712_createbss_cmd to change to an
+ * ADHOC_MASTER pmlmepriv->lock has been
+ * acquired by caller...
+ */
+ struct wlan_bssid_ex *pdev_network =
+ &(padapter->registrypriv.dev_network);
+ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
+ pibss = padapter->registrypriv.dev_network.
+ MacAddress;
+ memset(&pdev_network->Ssid, 0,
+ sizeof(struct ndis_802_11_ssid));
+ memcpy(&pdev_network->Ssid,
+ &pmlmepriv->assoc_ssid,
+ sizeof(struct ndis_802_11_ssid));
+ r8712_update_registrypriv_dev_network(padapter);
+ r8712_generate_random_ibss(pibss);
+ if (r8712_createbss_cmd(padapter) != _SUCCESS)
+ return false;
+ pmlmepriv->to_join = false;
+ } else {
+ /* can't associate ; reset under-linking */
+ if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
+ pmlmepriv->fw_state ^=
+ _FW_UNDER_LINKING;
+ /* when set_ssid/set_bssid for do_join(), but
+ * there are no desired bss in scanning queue
+ * we try to issue sitesurvey first
+ */
+ if (!pmlmepriv->sitesurveyctrl.traffic_busy)
+ r8712_sitesurvey_cmd(padapter,
+ &pmlmepriv->assoc_ssid);
+ }
+ }
+ }
+ return true;
+}
+
+u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid)
+{
+ unsigned long irqL;
+ u8 status = true;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 &&
+ bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
+ (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF &&
+ bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
+ status = false;
+ return status;
+ }
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
+ _FW_UNDER_LINKING) == true) {
+ status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+ goto _Abort_Set_BSSID;
+ }
+ if (check_fwstate(pmlmepriv,
+ _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
+ if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid,
+ ETH_ALEN)) {
+ if (check_fwstate(pmlmepriv,
+ WIFI_STATION_STATE) == false)
+ goto _Abort_Set_BSSID; /* driver is in
+ * WIFI_ADHOC_MASTER_STATE */
+ } else {
+ r8712_disassoc_cmd(padapter);
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+ r8712_ind_disconnect(padapter);
+ r8712_free_assoc_resources(padapter);
+ if ((check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE))) {
+ _clr_fwstate_(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE);
+ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
+ }
+ }
+ }
+ memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
+ pmlmepriv->assoc_by_bssid = true;
+ status = do_join(padapter);
+ goto done;
+_Abort_Set_BSSID:
+done:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return status;
+}
+
+void r8712_set_802_11_ssid(struct _adapter *padapter,
+ struct ndis_802_11_ssid *ssid)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *pnetwork = &pmlmepriv->cur_network;
+
+ if (padapter->hw_init_completed == false)
+ return;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
+ check_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+ goto _Abort_Set_SSID;
+ }
+ if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+ if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
+ (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid,
+ ssid->SsidLength))) {
+ if ((check_fwstate(pmlmepriv,
+ WIFI_STATION_STATE) == false)) {
+ if (r8712_is_same_ibss(padapter,
+ pnetwork) == false) {
+ /* if in WIFI_ADHOC_MASTER_STATE or
+ * WIFI_ADHOC_STATE, create bss or
+ * rejoin again
+ */
+ r8712_disassoc_cmd(padapter);
+ if (check_fwstate(pmlmepriv,
+ _FW_LINKED) == true)
+ r8712_ind_disconnect(padapter);
+ r8712_free_assoc_resources(padapter);
+ if (check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE)) {
+ _clr_fwstate_(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE);
+ set_fwstate(pmlmepriv,
+ WIFI_ADHOC_STATE);
+ }
+ } else
+ goto _Abort_Set_SSID; /* driver is in
+ * WIFI_ADHOC_MASTER_STATE */
+ }
+ } else {
+ r8712_disassoc_cmd(padapter);
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+ r8712_ind_disconnect(padapter);
+ r8712_free_assoc_resources(padapter);
+ if (check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE) == true) {
+ _clr_fwstate_(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE);
+ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
+ }
+ }
+ }
+ if (padapter->securitypriv.btkip_countermeasure == true)
+ goto _Abort_Set_SSID;
+ if (validate_ssid(ssid) == false)
+ goto _Abort_Set_SSID;
+ memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
+ pmlmepriv->assoc_by_bssid = false;
+ do_join(padapter);
+ goto done;
+_Abort_Set_SSID:
+done:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+u8 r8712_set_802_11_infrastructure_mode(struct _adapter *padapter,
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *cur_network = &pmlmepriv->cur_network;
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state =
+ &(cur_network->network.InfrastructureMode);
+
+ if (*pold_state != networktype) {
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
+ (*pold_state == Ndis802_11IBSS))
+ r8712_disassoc_cmd(padapter);
+ if (check_fwstate(pmlmepriv,
+ _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true)
+ r8712_free_assoc_resources(padapter);
+ if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
+ (*pold_state == Ndis802_11Infrastructure) ||
+ (*pold_state == Ndis802_11IBSS)) {
+ /* will clr Linked_state before this function,
+ * we must have chked whether issue dis-assoc_cmd or
+ * not */
+ r8712_ind_disconnect(padapter);
+ }
+ *pold_state = networktype;
+ /* clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE;
+ * WIFI_ADHOC_MASTER_STATE */
+ _clr_fwstate_(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE |
+ WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE |
+ WIFI_AP_STATE);
+ switch (networktype) {
+ case Ndis802_11IBSS:
+ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
+ break;
+ case Ndis802_11Infrastructure:
+ set_fwstate(pmlmepriv, WIFI_STATION_STATE);
+ break;
+ case Ndis802_11APMode:
+ set_fwstate(pmlmepriv, WIFI_AP_STATE);
+ break;
+ case Ndis802_11AutoUnknown:
+ case Ndis802_11InfrastructureMax:
+ break;
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ }
+ return true;
+}
+
+u8 r8712_set_802_11_disassociate(struct _adapter *padapter)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ r8712_disassoc_cmd(padapter);
+ r8712_ind_disconnect(padapter);
+ r8712_free_assoc_resources(padapter);
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return true;
+}
+
+u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = NULL;
+ unsigned long irqL;
+ u8 ret = true;
+
+ if (padapter == NULL)
+ return false;
+ pmlmepriv = &padapter->mlmepriv;
+ if (padapter->hw_init_completed == false)
+ return false;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
+ (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
+ /* Scan or linking is in progress, do nothing. */
+ ret = (u8)check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
+ } else {
+ r8712_free_network_queue(padapter);
+ ret = r8712_sitesurvey_cmd(padapter, NULL);
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return ret;
+}
+
+u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter,
+ enum NDIS_802_11_AUTHENTICATION_MODE authmode)
+{
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ u8 ret;
+
+ psecuritypriv->ndisauthtype = authmode;
+ if (psecuritypriv->ndisauthtype > 3)
+ psecuritypriv->AuthAlgrthm = 2; /* 802.1x */
+ if (r8712_set_auth(padapter, psecuritypriv) == _SUCCESS)
+ ret = true;
+ else
+ ret = false;
+ return ret;
+}
+
+u8 r8712_set_802_11_add_wep(struct _adapter *padapter,
+ struct NDIS_802_11_WEP *wep)
+{
+ u8 bdefaultkey;
+ u8 btransmitkey;
+ sint keyid;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? false : true;
+ btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? true : false;
+ keyid = wep->KeyIndex & 0x3fffffff;
+ if (keyid >= WEP_KEYS)
+ return false;
+ switch (wep->KeyLength) {
+ case 5:
+ psecuritypriv->PrivacyAlgrthm = _WEP40_;
+ break;
+ case 13:
+ psecuritypriv->PrivacyAlgrthm = _WEP104_;
+ break;
+ default:
+ psecuritypriv->PrivacyAlgrthm = _NO_PRIVACY_;
+ break;
+ }
+ memcpy(psecuritypriv->DefKey[keyid].skey, &wep->KeyMaterial,
+ wep->KeyLength);
+ psecuritypriv->DefKeylen[keyid] = wep->KeyLength;
+ psecuritypriv->PrivacyKeyIndex = keyid;
+ if (r8712_set_key(padapter, psecuritypriv, keyid) == _FAIL)
+ return false;
+ return _SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.h b/drivers/staging/rtl8712/rtl871x_ioctl_set.h
new file mode 100644
index 000000000000..283afbfc1d02
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.h
@@ -0,0 +1,24 @@
+#ifndef __IOCTL_SET_H
+#define __IOCTL_SET_H
+
+#include "drv_types.h"
+
+typedef u8 NDIS_802_11_PMKID_VALUE[16];
+
+struct BSSIDInfo {
+ unsigned char BSSID[6];
+ NDIS_802_11_PMKID_VALUE PMKID;
+};
+
+u8 r8712_set_802_11_authentication_mode(struct _adapter *pdapter,
+ enum NDIS_802_11_AUTHENTICATION_MODE authmode);
+u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid);
+u8 r8712_set_802_11_add_wep(struct _adapter *padapter, struct NDIS_802_11_WEP *wep);
+u8 r8712_set_802_11_disassociate(struct _adapter *padapter);
+u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter);
+u8 r8712_set_802_11_infrastructure_mode(struct _adapter *padapter,
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype);
+void r8712_set_802_11_ssid(struct _adapter *padapter, struct ndis_802_11_ssid *ssid);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h
new file mode 100644
index 000000000000..994ef82141ab
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_led.h
@@ -0,0 +1,99 @@
+#ifndef __RTL8712_LED_H
+#define __RTL8712_LED_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+/*===========================================================================
+ * LED customization.
+ *===========================================================================
+ */
+enum LED_CTL_MODE {
+ LED_CTL_POWER_ON = 1,
+ LED_CTL_LINK = 2,
+ LED_CTL_NO_LINK = 3,
+ LED_CTL_TX = 4,
+ LED_CTL_RX = 5,
+ LED_CTL_SITE_SURVEY = 6,
+ LED_CTL_POWER_OFF = 7,
+ LED_CTL_START_TO_LINK = 8,
+ LED_CTL_START_WPS = 9,
+ LED_CTL_STOP_WPS = 10,
+ LED_CTL_START_WPS_BOTTON = 11,
+ LED_CTL_STOP_WPS_FAIL = 12,
+ LED_CTL_STOP_WPS_FAIL_OVERLAP = 13,
+};
+
+#define IS_LED_WPS_BLINKING(_LED_871x) \
+ (((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS \
+ || ((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP \
+ || ((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress)
+
+#define IS_LED_BLINKING(_LED_871x) \
+ (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress \
+ || ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress)
+
+enum LED_PIN_871x {
+ LED_PIN_GPIO0,
+ LED_PIN_LED0,
+ LED_PIN_LED1
+};
+
+/*===========================================================================
+ * LED customization.
+ *===========================================================================
+ */
+enum LED_STRATEGY_871x {
+ SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */
+ SW_LED_MODE1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */
+ SW_LED_MODE2, /* SW control 1 LED via GPIO0,
+ * custom for AzWave 8187 minicard. */
+ SW_LED_MODE3, /* SW control 1 LED via GPIO0,
+ * customized for Sercomm Printer Server case.*/
+ SW_LED_MODE4, /*for Edimax / Belkin*/
+ SW_LED_MODE5, /*for Sercomm / Belkin*/
+ SW_LED_MODE6, /*for WNC / Corega*/
+ HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different
+ * control modes, see MAC.CONFIG1 for details.)*/
+};
+
+struct LED_871x {
+ struct _adapter *padapter;
+ enum LED_PIN_871x LedPin; /* Implementation for this SW led. */
+ u32 CurrLedState; /* Current LED state. */
+ u8 bLedOn; /* true if LED is ON */
+ u8 bSWLedCtrl;
+ u8 bLedBlinkInProgress; /*true if blinking */
+ u8 bLedNoLinkBlinkInProgress;
+ u8 bLedLinkBlinkInProgress;
+ u8 bLedStartToLinkBlinkInProgress;
+ u8 bLedScanBlinkInProgress;
+ u8 bLedWPSBlinkInProgress;
+ u32 BlinkTimes; /* No. times to toggle for blink.*/
+ u32 BlinkingLedState; /* Next state for blinking,
+ * either LED_ON or OFF.*/
+
+ struct timer_list BlinkTimer; /* Timer object for led blinking.*/
+ _workitem BlinkWorkItem; /* Workitem used by BlinkTimer */
+};
+
+struct led_priv {
+ /* add for led controll */
+ struct LED_871x SwLed0;
+ struct LED_871x SwLed1;
+ enum LED_STRATEGY_871x LedStrategy;
+ u8 bRegUseLed;
+ void (*LedControlHandler)(struct _adapter *padapter,
+ enum LED_CTL_MODE LedAction);
+ /* add for led controll */
+};
+
+/*===========================================================================
+ * Interface to manipulate LED objects.
+ *===========================================================================*/
+void r8712_InitSwLeds(struct _adapter *padapter);
+void r8712_DeInitSwLeds(struct _adapter *padapter);
+void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
new file mode 100644
index 000000000000..98ba7602e250
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -0,0 +1,1840 @@
+/******************************************************************************
+ * rtl871x_mlme.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_MLME_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "xmit_osdep.h"
+#include "mlme_osdep.h"
+#include "sta_info.h"
+#include "wifi.h"
+#include "wlan_bssdef.h"
+
+static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len);
+
+static sint _init_mlme_priv(struct _adapter *padapter)
+{
+ sint i;
+ u8 *pbuf;
+ struct wlan_network *pnetwork;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
+ pmlmepriv->nic_hdl = (u8 *)padapter;
+ pmlmepriv->pscanned = NULL;
+ pmlmepriv->fw_state = 0;
+ pmlmepriv->cur_network.network.InfrastructureMode =
+ Ndis802_11AutoUnknown;
+ spin_lock_init(&(pmlmepriv->lock));
+ spin_lock_init(&(pmlmepriv->lock2));
+ _init_queue(&(pmlmepriv->free_bss_pool));
+ _init_queue(&(pmlmepriv->scanned_queue));
+ set_scanned_network_val(pmlmepriv, 0);
+ memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
+ pbuf = _malloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
+ if (pbuf == NULL)
+ return _FAIL;
+ pmlmepriv->free_bss_buf = pbuf;
+ pnetwork = (struct wlan_network *)pbuf;
+ for (i = 0; i < MAX_BSS_CNT; i++) {
+ _init_listhead(&(pnetwork->list));
+ list_insert_tail(&(pnetwork->list),
+ &(pmlmepriv->free_bss_pool.queue));
+ pnetwork++;
+ }
+ pmlmepriv->sitesurveyctrl.last_rx_pkts = 0;
+ pmlmepriv->sitesurveyctrl.last_tx_pkts = 0;
+ pmlmepriv->sitesurveyctrl.traffic_busy = false;
+ /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
+ r8712_init_mlme_timer(padapter);
+ return _SUCCESS;
+}
+
+struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
+{
+ unsigned long irqL;
+ struct wlan_network *pnetwork;
+ struct __queue *free_queue = &pmlmepriv->free_bss_pool;
+ struct list_head *plist = NULL;
+
+ if (_queue_empty(free_queue) == true)
+ return NULL;
+ spin_lock_irqsave(&free_queue->lock, irqL);
+ plist = get_next(&(free_queue->queue));
+ pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
+ list_delete(&pnetwork->list);
+ pnetwork->last_scanned = jiffies;
+ pmlmepriv->num_of_scanned++;
+ spin_unlock_irqrestore(&free_queue->lock, irqL);
+ return pnetwork;
+}
+
+static void _free_network(struct mlme_priv *pmlmepriv,
+ struct wlan_network *pnetwork)
+{
+ u32 curr_time, delta_time;
+ unsigned long irqL;
+ struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
+
+ if (pnetwork == NULL)
+ return;
+ if (pnetwork->fixed == true)
+ return;
+ curr_time = jiffies;
+ delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ;
+ if (delta_time < SCANQUEUE_LIFETIME)
+ return;
+ spin_lock_irqsave(&free_queue->lock, irqL);
+ list_delete(&pnetwork->list);
+ list_insert_tail(&pnetwork->list, &free_queue->queue);
+ pmlmepriv->num_of_scanned--;
+ spin_unlock_irqrestore(&free_queue->lock, irqL);
+}
+
+static void _free_network_nolock(struct mlme_priv *pmlmepriv,
+ struct wlan_network *pnetwork)
+{
+ struct __queue *free_queue = &pmlmepriv->free_bss_pool;
+
+ if (pnetwork == NULL)
+ return;
+ if (pnetwork->fixed == true)
+ return;
+ list_delete(&pnetwork->list);
+ list_insert_tail(&pnetwork->list, get_list_head(free_queue));
+ pmlmepriv->num_of_scanned--;
+}
+
+
+/*
+ return the wlan_network with the matching addr
+ Shall be calle under atomic context...
+ to avoid possible racing condition...
+*/
+static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue,
+ u8 *addr)
+{
+ unsigned long irqL;
+ struct list_head *phead, *plist;
+ struct wlan_network *pnetwork = NULL;
+ u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+
+ if (!memcmp(zero_addr, addr, ETH_ALEN))
+ return NULL;
+ spin_lock_irqsave(&scanned_queue->lock, irqL);
+ phead = get_list_head(scanned_queue);
+ plist = get_next(phead);
+ while (plist != phead) {
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+ plist = get_next(plist);
+ if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
+ break;
+ }
+ spin_unlock_irqrestore(&scanned_queue->lock, irqL);
+ return pnetwork;
+}
+
+static void _free_network_queue(struct _adapter *padapter)
+{
+ unsigned long irqL;
+ struct list_head *phead, *plist;
+ struct wlan_network *pnetwork;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
+
+ spin_lock_irqsave(&scanned_queue->lock, irqL);
+ phead = get_list_head(scanned_queue);
+ plist = get_next(phead);
+ while (end_of_queue_search(phead, plist) == false) {
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+ plist = get_next(plist);
+ _free_network(pmlmepriv, pnetwork);
+ }
+ spin_unlock_irqrestore(&scanned_queue->lock, irqL);
+}
+
+sint r8712_if_up(struct _adapter *padapter)
+{
+ sint res;
+
+ if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
+ (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false)) {
+ res = false;
+ } else
+ res = true;
+ return res;
+}
+
+void r8712_generate_random_ibss(u8 *pibss)
+{
+ u32 curtime = jiffies;
+
+ pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */
+ pibss[1] = 0x11;
+ pibss[2] = 0x87;
+ pibss[3] = (u8)(curtime & 0xff);
+ pibss[4] = (u8)((curtime>>8) & 0xff);
+ pibss[5] = (u8)((curtime>>16) & 0xff);
+}
+
+uint r8712_get_ndis_wlan_bssid_ex_sz(struct ndis_wlan_bssid_ex *bss)
+{
+ uint t_len;
+
+ t_len = sizeof(u32) + 6 * sizeof(unsigned long) + 2 +
+ sizeof(struct ndis_802_11_ssid) + sizeof(u32) +
+ sizeof(s32) +
+ sizeof(enum NDIS_802_11_NETWORK_TYPE) +
+ sizeof(struct NDIS_802_11_CONFIGURATION) +
+ sizeof(enum NDIS_802_11_NETWORK_INFRASTRUCTURE) +
+ sizeof(NDIS_802_11_RATES_EX) +
+ sizeof(u32) + bss->IELength;
+ return t_len;
+}
+
+u8 *r8712_get_capability_from_ie(u8 *ie)
+{
+ return ie + 8 + 2;
+}
+
+int r8712_init_mlme_priv(struct _adapter *padapter)
+{
+ return _init_mlme_priv(padapter);
+}
+
+void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv)
+{
+ kfree(pmlmepriv->free_bss_buf);
+}
+
+static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv)
+{
+ return _r8712_alloc_network(pmlmepriv);
+}
+
+static void free_network_nolock(struct mlme_priv *pmlmepriv,
+ struct wlan_network *pnetwork)
+{
+ _free_network_nolock(pmlmepriv, pnetwork);
+}
+
+void r8712_free_network_queue(struct _adapter *dev)
+{
+ _free_network_queue(dev);
+}
+
+/*
+ return the wlan_network with the matching addr
+
+ Shall be calle under atomic context...
+ to avoid possible racing condition...
+*/
+static struct wlan_network *r8712_find_network(struct __queue *scanned_queue,
+ u8 *addr)
+{
+ struct wlan_network *pnetwork = _r8712_find_network(scanned_queue,
+ addr);
+
+ return pnetwork;
+}
+
+int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork)
+{
+ int ret = true;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+
+ if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
+ (pnetwork->network.Privacy == 0))
+ ret = false;
+ else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) &&
+ (pnetwork->network.Privacy == 1))
+ ret = false;
+ else
+ ret = true;
+ return ret;
+
+}
+
+static int is_same_network(struct ndis_wlan_bssid_ex *src,
+ struct ndis_wlan_bssid_ex *dst)
+{
+ u16 s_cap, d_cap;
+
+ memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2);
+ memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2);
+ return (src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
+ (src->Configuration.DSConfig ==
+ dst->Configuration.DSConfig) &&
+ ((!memcmp(src->MacAddress, dst->MacAddress,
+ ETH_ALEN))) &&
+ ((!memcmp(src->Ssid.Ssid,
+ dst->Ssid.Ssid,
+ src->Ssid.SsidLength))) &&
+ ((s_cap & WLAN_CAPABILITY_IBSS) ==
+ (d_cap & WLAN_CAPABILITY_IBSS)) &&
+ ((s_cap & WLAN_CAPABILITY_BSS) ==
+ (d_cap & WLAN_CAPABILITY_BSS));
+
+}
+
+struct wlan_network *r8712_get_oldest_wlan_network(
+ struct __queue *scanned_queue)
+{
+ struct list_head *plist, *phead;
+ struct wlan_network *pwlan = NULL;
+ struct wlan_network *oldest = NULL;
+
+ phead = get_list_head(scanned_queue);
+ plist = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, plist) == true)
+ break;
+ pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
+ if (pwlan->fixed != true) {
+ if (oldest == NULL ||
+ time_after((unsigned long)oldest->last_scanned,
+ (unsigned long)pwlan->last_scanned))
+ oldest = pwlan;
+ }
+ plist = get_next(plist);
+ }
+ return oldest;
+}
+
+static void update_network(struct ndis_wlan_bssid_ex *dst,
+ struct ndis_wlan_bssid_ex *src,
+ struct _adapter *padapter)
+{
+ u32 last_evm = 0, tmpVal;
+
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
+ is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
+ if (padapter->recvpriv.signal_qual_data.total_num++ >=
+ PHY_LINKQUALITY_SLID_WIN_MAX) {
+ padapter->recvpriv.signal_qual_data.total_num =
+ PHY_LINKQUALITY_SLID_WIN_MAX;
+ last_evm = padapter->recvpriv.signal_qual_data.
+ elements[padapter->recvpriv.
+ signal_qual_data.index];
+ padapter->recvpriv.signal_qual_data.total_val -=
+ last_evm;
+ }
+ padapter->recvpriv.signal_qual_data.total_val += src->Rssi;
+
+ padapter->recvpriv.signal_qual_data.
+ elements[padapter->recvpriv.signal_qual_data.
+ index++] = src->Rssi;
+ if (padapter->recvpriv.signal_qual_data.index >=
+ PHY_LINKQUALITY_SLID_WIN_MAX)
+ padapter->recvpriv.signal_qual_data.index = 0;
+ /* <1> Showed on UI for user, in percentage. */
+ tmpVal = padapter->recvpriv.signal_qual_data.total_val /
+ padapter->recvpriv.signal_qual_data.total_num;
+ padapter->recvpriv.signal = (u8)tmpVal;
+
+ src->Rssi = padapter->recvpriv.signal;
+ } else
+ src->Rssi = (src->Rssi + dst->Rssi) / 2;
+ memcpy((u8 *)dst, (u8 *)src, r8712_get_ndis_wlan_bssid_ex_sz(src));
+}
+
+static void update_current_network(struct _adapter *adapter,
+ struct ndis_wlan_bssid_ex *pnetwork)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) {
+ update_network(&(pmlmepriv->cur_network.network),
+ pnetwork, adapter);
+ r8712_update_protection(adapter,
+ (pmlmepriv->cur_network.network.IEs) +
+ sizeof(struct NDIS_802_11_FIXED_IEs),
+ pmlmepriv->cur_network.network.IELength);
+ }
+}
+
+/*
+Caller must hold pmlmepriv->lock first.
+*/
+static void update_scanned_network(struct _adapter *adapter,
+ struct ndis_wlan_bssid_ex *target)
+{
+ struct list_head *plist, *phead;
+
+ u32 bssid_ex_sz;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+ struct wlan_network *pnetwork = NULL;
+ struct wlan_network *oldest = NULL;
+
+ phead = get_list_head(queue);
+ plist = get_next(phead);
+
+ while (1) {
+ if (end_of_queue_search(phead, plist) == true)
+ break;
+
+ pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
+ if (is_same_network(&pnetwork->network, target))
+ break;
+ if ((oldest == ((struct wlan_network *)0)) ||
+ time_after((unsigned long)oldest->last_scanned,
+ (unsigned long)pnetwork->last_scanned))
+ oldest = pnetwork;
+
+ plist = get_next(plist);
+ }
+
+
+ /* If we didn't find a match, then get a new network slot to initialize
+ * with this beacon's information */
+ if (end_of_queue_search(phead, plist) == true) {
+ if (_queue_empty(&pmlmepriv->free_bss_pool) == true) {
+ /* If there are no more slots, expire the oldest */
+ pnetwork = oldest;
+ target->Rssi = (pnetwork->network.Rssi +
+ target->Rssi) / 2;
+ memcpy(&pnetwork->network, target,
+ r8712_get_ndis_wlan_bssid_ex_sz(target));
+ pnetwork->last_scanned = jiffies;
+ } else {
+ /* Otherwise just pull from the free list */
+ /* update scan_time */
+ pnetwork = alloc_network(pmlmepriv);
+ if (pnetwork == NULL)
+ return;
+ bssid_ex_sz = r8712_get_ndis_wlan_bssid_ex_sz(target);
+ target->Length = bssid_ex_sz;
+ memcpy(&pnetwork->network, target, bssid_ex_sz);
+ list_insert_tail(&pnetwork->list, &queue->queue);
+ }
+ } else {
+ /* we have an entry and we are going to update it. But
+ * this entry may be already expired. In this case we
+ * do the same as we found a new net and call the new_net
+ * handler
+ */
+ update_network(&pnetwork->network, target, adapter);
+ pnetwork->last_scanned = jiffies;
+ }
+}
+
+static void rtl8711_add_network(struct _adapter *adapter,
+ struct ndis_wlan_bssid_ex *pnetwork)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv);
+ struct __queue *queue = &pmlmepriv->scanned_queue;
+
+ spin_lock_irqsave(&queue->lock, irqL);
+ update_current_network(adapter, pnetwork);
+ update_scanned_network(adapter, pnetwork);
+ spin_unlock_irqrestore(&queue->lock, irqL);
+}
+
+/*select the desired network based on the capability of the (i)bss.
+ * check items: (1) security
+ * (2) network_type
+ * (3) WMM
+ * (4) HT
+ * (5) others
+ */
+static int is_desired_network(struct _adapter *adapter,
+ struct wlan_network *pnetwork)
+{
+ u8 wps_ie[512];
+ uint wps_ielen;
+ int bselected = true;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+
+ if (psecuritypriv->wps_phase == true) {
+ if (r8712_get_wps_ie(pnetwork->network.IEs,
+ pnetwork->network.IELength, wps_ie,
+ &wps_ielen) == true)
+ return true;
+ else
+ return false;
+ }
+ if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
+ (pnetwork->network.Privacy == 0))
+ bselected = false;
+ return bselected;
+}
+
+/* TODO: Perry : For Power Management */
+void r8712_atimdone_event_callback(struct _adapter *adapter , u8 *pbuf)
+{
+}
+
+void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ unsigned long flags;
+ u32 len;
+ struct ndis_wlan_bssid_ex *pnetwork;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ pnetwork = (struct ndis_wlan_bssid_ex *)pbuf;
+#ifdef __BIG_ENDIAN
+ /* endian_convert */
+ pnetwork->Length = le32_to_cpu(pnetwork->Length);
+ pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
+ pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
+ pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
+ pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
+ pnetwork->Configuration.ATIMWindow =
+ le32_to_cpu(pnetwork->Configuration.ATIMWindow);
+ pnetwork->Configuration.BeaconPeriod =
+ le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
+ pnetwork->Configuration.DSConfig =
+ le32_to_cpu(pnetwork->Configuration.DSConfig);
+ pnetwork->Configuration.FHConfig.DwellTime =
+ le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
+ pnetwork->Configuration.FHConfig.HopPattern =
+ le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
+ pnetwork->Configuration.FHConfig.HopSet =
+ le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
+ pnetwork->Configuration.FHConfig.Length =
+ le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
+ pnetwork->Configuration.Length =
+ le32_to_cpu(pnetwork->Configuration.Length);
+ pnetwork->InfrastructureMode =
+ le32_to_cpu(pnetwork->InfrastructureMode);
+ pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
+#endif
+ len = r8712_get_ndis_wlan_bssid_ex_sz(pnetwork);
+ if (len > sizeof(struct wlan_bssid_ex))
+ return;
+ spin_lock_irqsave(&pmlmepriv->lock2, flags);
+ /* update IBSS_network 's timestamp */
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
+ if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress),
+ pnetwork->MacAddress, ETH_ALEN)) {
+ struct wlan_network *ibss_wlan = NULL;
+
+ memcpy(pmlmepriv->cur_network.network.IEs,
+ pnetwork->IEs, 8);
+ ibss_wlan = r8712_find_network(
+ &pmlmepriv->scanned_queue,
+ pnetwork->MacAddress);
+ if (!ibss_wlan) {
+ memcpy(ibss_wlan->network.IEs,
+ pnetwork->IEs, 8);
+ goto exit;
+ }
+ }
+ }
+ /* lock pmlmepriv->lock when you accessing network_q */
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == false) {
+ if (pnetwork->Ssid.Ssid[0] != 0)
+ rtl8711_add_network(adapter, pnetwork);
+ else {
+ pnetwork->Ssid.SsidLength = 8;
+ memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8);
+ rtl8711_add_network(adapter, pnetwork);
+ }
+ }
+exit:
+ spin_unlock_irqrestore(&pmlmepriv->lock2, flags);
+}
+
+void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
+ u8 timer_cancelled;
+
+ _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
+
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+ }
+
+ if (pmlmepriv->to_join == true) {
+ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+
+ if (r8712_select_and_join_from_scan(pmlmepriv)
+ == _SUCCESS)
+ _set_timer(&pmlmepriv->assoc_timer,
+ MAX_JOIN_TIMEOUT);
+ else {
+ struct wlan_bssid_ex *pdev_network =
+ &(adapter->registrypriv.dev_network);
+ u8 *pibss =
+ adapter->registrypriv.
+ dev_network.MacAddress;
+ pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;
+ memset(&pdev_network->Ssid, 0,
+ sizeof(struct
+ ndis_802_11_ssid));
+ memcpy(&pdev_network->Ssid,
+ &pmlmepriv->assoc_ssid,
+ sizeof(struct
+ ndis_802_11_ssid));
+ r8712_update_registrypriv_dev_network
+ (adapter);
+ r8712_generate_random_ibss(pibss);
+ pmlmepriv->fw_state =
+ WIFI_ADHOC_MASTER_STATE;
+ pmlmepriv->to_join = false;
+ }
+ }
+ } else {
+ pmlmepriv->to_join = false;
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+ if (r8712_select_and_join_from_scan(pmlmepriv) ==
+ _SUCCESS)
+ _set_timer(&pmlmepriv->assoc_timer,
+ MAX_JOIN_TIMEOUT);
+ else
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+ }
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+/*
+ *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock
+ */
+void r8712_free_assoc_resources(struct _adapter *adapter)
+{
+ unsigned long irqL;
+ struct wlan_network *pwlan = NULL;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+
+ pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
+ tgt_network->network.MacAddress);
+
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
+ struct sta_info *psta;
+
+ psta = r8712_get_stainfo(&adapter->stapriv,
+ tgt_network->network.MacAddress);
+
+ spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
+ r8712_free_stainfo(adapter, psta);
+ spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
+ }
+
+ if (check_fwstate(pmlmepriv,
+ WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE))
+ r8712_free_all_stainfo(adapter);
+ if (pwlan)
+ pwlan->fixed = false;
+
+ if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) &&
+ (adapter->stapriv.asoc_sta_count == 1)))
+ free_network_nolock(pmlmepriv, pwlan);
+}
+
+/*
+*r8712_indicate_connect: the caller has to lock pmlmepriv->lock
+*/
+void r8712_indicate_connect(struct _adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ pmlmepriv->to_join = false;
+ set_fwstate(pmlmepriv, _FW_LINKED);
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK);
+ r8712_os_indicate_connect(padapter);
+ if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE)
+ _set_timer(&pmlmepriv->dhcp_timer, 60000);
+}
+
+
+/*
+*r8712_ind_disconnect: the caller has to lock pmlmepriv->lock
+*/
+void r8712_ind_disconnect(struct _adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ _clr_fwstate_(pmlmepriv, _FW_LINKED);
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
+ r8712_os_indicate_disconnect(padapter);
+ if (padapter->pwrctrlpriv.pwr_mode !=
+ padapter->registrypriv.power_mgnt) {
+ _cancel_timer_ex(&pmlmepriv->dhcp_timer);
+ r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
+ padapter->registrypriv.smart_ps);
+ }
+}
+
+/*Notes:
+ *pnetwork : returns from r8712_joinbss_event_callback
+ *ptarget_wlan: found from scanned_queue
+ *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if
+ * "ptarget_sta" & "ptarget_wlan" exist.
+ *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check
+ * if "ptarget_wlan" exist.
+ *if join_res > 0, update "cur_network->network" from
+ * "pnetwork->network" if (ptarget_wlan !=NULL).
+ */
+void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ unsigned long irqL = 0, irqL2;
+ u8 timer_cancelled;
+ struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct wlan_network *cur_network = &pmlmepriv->cur_network;
+ struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
+ unsigned int the_same_macaddr = false;
+ struct wlan_network *pnetwork;
+
+ if (sizeof(struct list_head) == 4 * sizeof(u32)) {
+ pnetwork = (struct wlan_network *)
+ _malloc(sizeof(struct wlan_network));
+ memcpy((u8 *)pnetwork+16, (u8 *)pbuf + 8,
+ sizeof(struct wlan_network) - 16);
+ } else
+ pnetwork = (struct wlan_network *)pbuf;
+
+#ifdef __BIG_ENDIAN
+ /* endian_convert */
+ pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
+ pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
+ pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
+ pnetwork->network.Ssid.SsidLength =
+ le32_to_cpu(pnetwork->network.Ssid.SsidLength);
+ pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
+ pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
+ pnetwork->network.NetworkTypeInUse =
+ le32_to_cpu(pnetwork->network.NetworkTypeInUse);
+ pnetwork->network.Configuration.ATIMWindow =
+ le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
+ pnetwork->network.Configuration.BeaconPeriod =
+ le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
+ pnetwork->network.Configuration.DSConfig =
+ le32_to_cpu(pnetwork->network.Configuration.DSConfig);
+ pnetwork->network.Configuration.FHConfig.DwellTime =
+ le32_to_cpu(pnetwork->network.Configuration.FHConfig.
+ DwellTime);
+ pnetwork->network.Configuration.FHConfig.HopPattern =
+ le32_to_cpu(pnetwork->network.Configuration.
+ FHConfig.HopPattern);
+ pnetwork->network.Configuration.FHConfig.HopSet =
+ le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
+ pnetwork->network.Configuration.FHConfig.Length =
+ le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
+ pnetwork->network.Configuration.Length =
+ le32_to_cpu(pnetwork->network.Configuration.Length);
+ pnetwork->network.InfrastructureMode =
+ le32_to_cpu(pnetwork->network.InfrastructureMode);
+ pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
+#endif
+
+ the_same_macaddr = !memcmp(pnetwork->network.MacAddress,
+ cur_network->network.MacAddress, ETH_ALEN);
+ pnetwork->network.Length =
+ r8712_get_ndis_wlan_bssid_ex_sz(&pnetwork->network);
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
+ goto ignore_joinbss_callback;
+ if (pnetwork->join_res > 0) {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
+ /*s1. find ptarget_wlan*/
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ if (the_same_macaddr == true)
+ ptarget_wlan =
+ r8712_find_network(&pmlmepriv->
+ scanned_queue,
+ cur_network->network.MacAddress);
+ else {
+ pcur_wlan =
+ r8712_find_network(&pmlmepriv->
+ scanned_queue,
+ cur_network->network.MacAddress);
+ pcur_wlan->fixed = false;
+
+ pcur_sta = r8712_get_stainfo(pstapriv,
+ cur_network->network.MacAddress);
+ spin_lock_irqsave(&pstapriv->
+ sta_hash_lock, irqL2);
+ r8712_free_stainfo(adapter, pcur_sta);
+ spin_unlock_irqrestore(&(pstapriv->
+ sta_hash_lock), irqL2);
+
+ ptarget_wlan =
+ r8712_find_network(&pmlmepriv->
+ scanned_queue,
+ pnetwork->network.
+ MacAddress);
+ if (ptarget_wlan)
+ ptarget_wlan->fixed = true;
+ }
+ } else {
+ ptarget_wlan = r8712_find_network(&pmlmepriv->
+ scanned_queue,
+ pnetwork->network.MacAddress);
+ if (ptarget_wlan)
+ ptarget_wlan->fixed = true;
+ }
+
+ if (ptarget_wlan == NULL) {
+ if (check_fwstate(pmlmepriv,
+ _FW_UNDER_LINKING))
+ pmlmepriv->fw_state ^=
+ _FW_UNDER_LINKING;
+ goto ignore_joinbss_callback;
+ }
+
+ /*s2. find ptarget_sta & update ptarget_sta*/
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
+ if (the_same_macaddr == true) {
+ ptarget_sta =
+ r8712_get_stainfo(pstapriv,
+ pnetwork->network.MacAddress);
+ if (ptarget_sta == NULL)
+ ptarget_sta =
+ r8712_alloc_stainfo(pstapriv,
+ pnetwork->network.MacAddress);
+ } else
+ ptarget_sta =
+ r8712_alloc_stainfo(pstapriv,
+ pnetwork->network.MacAddress);
+ if (ptarget_sta) /*update ptarget_sta*/ {
+ ptarget_sta->aid = pnetwork->join_res;
+ ptarget_sta->qos_option = 1;
+ ptarget_sta->mac_id = 5;
+ if (adapter->securitypriv.
+ AuthAlgrthm == 2) {
+ adapter->securitypriv.
+ binstallGrpkey =
+ false;
+ adapter->securitypriv.
+ busetkipkey =
+ false;
+ adapter->securitypriv.
+ bgrpkey_handshake =
+ false;
+ ptarget_sta->ieee8021x_blocked
+ = true;
+ ptarget_sta->XPrivacy =
+ adapter->securitypriv.
+ PrivacyAlgrthm;
+ memset((u8 *)&ptarget_sta->
+ x_UncstKey,
+ 0,
+ sizeof(union Keytype));
+ memset((u8 *)&ptarget_sta->
+ tkiprxmickey,
+ 0,
+ sizeof(union Keytype));
+ memset((u8 *)&ptarget_sta->
+ tkiptxmickey,
+ 0,
+ sizeof(union Keytype));
+ memset((u8 *)&ptarget_sta->
+ txpn, 0,
+ sizeof(union pn48));
+ memset((u8 *)&ptarget_sta->
+ rxpn, 0,
+ sizeof(union pn48));
+ }
+ } else {
+ if (check_fwstate(pmlmepriv,
+ _FW_UNDER_LINKING))
+ pmlmepriv->fw_state ^=
+ _FW_UNDER_LINKING;
+ goto ignore_joinbss_callback;
+ }
+ }
+
+ /*s3. update cur_network & indicate connect*/
+ memcpy(&cur_network->network, &pnetwork->network,
+ pnetwork->network.Length);
+ cur_network->aid = pnetwork->join_res;
+ /*update fw_state will clr _FW_UNDER_LINKING*/
+ switch (pnetwork->network.InfrastructureMode) {
+ case Ndis802_11Infrastructure:
+ pmlmepriv->fw_state = WIFI_STATION_STATE;
+ break;
+ case Ndis802_11IBSS:
+ pmlmepriv->fw_state = WIFI_ADHOC_STATE;
+ break;
+ default:
+ pmlmepriv->fw_state = WIFI_NULL_STATE;
+ break;
+ }
+ r8712_update_protection(adapter,
+ (cur_network->network.IEs) +
+ sizeof(struct NDIS_802_11_FIXED_IEs),
+ (cur_network->network.IELength));
+ /*TODO: update HT_Capability*/
+ update_ht_cap(adapter, cur_network->network.IEs,
+ cur_network->network.IELength);
+ /*indicate connect*/
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
+ == true)
+ r8712_indicate_connect(adapter);
+ _cancel_timer(&pmlmepriv->assoc_timer,
+ &timer_cancelled);
+ } else
+ goto ignore_joinbss_callback;
+ } else {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
+ _set_timer(&pmlmepriv->assoc_timer, 1);
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+ }
+ }
+ignore_joinbss_callback:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ if (sizeof(struct list_head) == 4 * sizeof(u32))
+ kfree((u8 *)pnetwork);
+}
+
+void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ unsigned long irqL;
+ struct sta_info *psta;
+ struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
+ struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
+
+ /* to do: */
+ if (r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr) == false)
+ return;
+ psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
+ if (psta != NULL) {
+ /*the sta have been in sta_info_queue => do nothing
+ *(between drv has received this event before and
+ * fw have not yet to set key to CAM_ENTRY) */
+ return;
+ }
+
+ psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
+ if (psta == NULL)
+ return;
+ /* to do : init sta_info variable */
+ psta->qos_option = 0;
+ psta->mac_id = le32_to_cpu((uint)pstassoc->cam_id);
+ /* psta->aid = (uint)pstassoc->cam_id; */
+
+ if (adapter->securitypriv.AuthAlgrthm == 2)
+ psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm;
+ psta->ieee8021x_blocked = false;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
+ if (adapter->stapriv.asoc_sta_count == 2) {
+ /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
+ r8712_indicate_connect(adapter);
+ }
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ unsigned long irqL, irqL2;
+ struct sta_info *psta;
+ struct wlan_network *pwlan = NULL;
+ struct wlan_bssid_ex *pdev_network = NULL;
+ u8 *pibss = NULL;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct stadel_event *pstadel = (struct stadel_event *)pbuf;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL2);
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
+ r8712_ind_disconnect(adapter);
+ r8712_free_assoc_resources(adapter);
+ }
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE |
+ WIFI_ADHOC_STATE)) {
+ psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr);
+ spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
+ r8712_free_stainfo(adapter, psta);
+ spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
+ if (adapter->stapriv.asoc_sta_count == 1) {
+ /*a sta + bc/mc_stainfo (not Ibss_stainfo) */
+ pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
+ tgt_network->network.MacAddress);
+ if (pwlan) {
+ pwlan->fixed = false;
+ free_network_nolock(pmlmepriv, pwlan);
+ }
+ /*re-create ibss*/
+ pdev_network = &(adapter->registrypriv.dev_network);
+ pibss = adapter->registrypriv.dev_network.MacAddress;
+ memcpy(pdev_network, &tgt_network->network,
+ r8712_get_ndis_wlan_bssid_ex_sz(&tgt_network->
+ network));
+ memset(&pdev_network->Ssid, 0,
+ sizeof(struct ndis_802_11_ssid));
+ memcpy(&pdev_network->Ssid,
+ &pmlmepriv->assoc_ssid,
+ sizeof(struct ndis_802_11_ssid));
+ r8712_update_registrypriv_dev_network(adapter);
+ r8712_generate_random_ibss(pibss);
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
+ set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL2);
+}
+
+void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ struct reportpwrstate_parm *preportpwrstate =
+ (struct reportpwrstate_parm *)pbuf;
+
+ preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80);
+ r8712_cpwm_int_hdl(adapter, preportpwrstate);
+}
+
+/* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send
+ * the ADDBA req frame with start seq control = 0 to wifi client after
+ * the WPA handshake and the seqence number of following data packet
+ * will be 0. In this case, the Rx reorder sequence is not longer than 0
+ * and the WiFi client will drop the data with seq number 0.
+ * So, the 8712 firmware has to inform driver with receiving the
+ * ADDBA-Req frame so that the driver can reset the
+ * sequence value of Rx reorder contorl.
+ */
+void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ struct ADDBA_Req_Report_parm *pAddbareq_pram =
+ (struct ADDBA_Req_Report_parm *)pbuf;
+ struct sta_info *psta;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct recv_reorder_ctrl *precvreorder_ctrl = NULL;
+
+ printk(KERN_INFO "r8712u: [%s] mac = %pM, seq = %d, tid = %d\n",
+ __func__, pAddbareq_pram->MacAddress,
+ pAddbareq_pram->StartSeqNum, pAddbareq_pram->tid);
+ psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress);
+ if (psta) {
+ precvreorder_ctrl =
+ &psta->recvreorder_ctrl[pAddbareq_pram->tid];
+ /* set the indicate_seq to 0xffff so that the rx reorder
+ * can store any following data packet.
+ */
+ precvreorder_ctrl->indicate_seq = 0xffff;
+ }
+}
+
+void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf)
+{
+ if (adapter->securitypriv.wps_hw_pbc_pressed == false)
+ adapter->securitypriv.wps_hw_pbc_pressed = true;
+}
+
+void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl;
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ u64 current_tx_pkts;
+ uint current_rx_pkts;
+
+ current_tx_pkts = (adapter->xmitpriv.tx_pkts) -
+ (psitesurveyctrl->last_tx_pkts);
+ current_rx_pkts = (adapter->recvpriv.rx_pkts) -
+ (psitesurveyctrl->last_rx_pkts);
+ psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts;
+ psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts;
+ if ((current_tx_pkts > pregistrypriv->busy_thresh) ||
+ (current_rx_pkts > pregistrypriv->busy_thresh))
+ psitesurveyctrl->traffic_busy = true;
+ else
+ psitesurveyctrl->traffic_busy = false;
+}
+
+void _r8712_join_timeout_handler(struct _adapter *adapter)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
+ return;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+ pmlmepriv->to_join = false;
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
+ r8712_os_indicate_disconnect(adapter);
+ _clr_fwstate_(pmlmepriv, _FW_LINKED);
+ }
+ if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) {
+ r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
+ adapter->registrypriv.smart_ps);
+ }
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+void r8712_scan_timeout_handler (struct _adapter *adapter)
+{
+ unsigned long irqL;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+ pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+void _r8712_dhcp_timeout_handler (struct _adapter *adapter)
+{
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
+ return;
+ if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt)
+ r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
+ adapter->registrypriv.smart_ps);
+}
+
+void _r8712_wdg_timeout_handler(struct _adapter *adapter)
+{
+ r8712_wdg_wk_cmd(adapter);
+}
+
+int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
+{
+ struct list_head *phead;
+ unsigned char *dst_ssid, *src_ssid;
+ struct _adapter *adapter;
+ struct __queue *queue = NULL;
+ struct wlan_network *pnetwork = NULL;
+ struct wlan_network *pnetwork_max_rssi = NULL;
+
+ adapter = (struct _adapter *)pmlmepriv->nic_hdl;
+ queue = &pmlmepriv->scanned_queue;
+ phead = get_list_head(queue);
+ pmlmepriv->pscanned = get_next(phead);
+ while (1) {
+ if (end_of_queue_search(phead, pmlmepriv->pscanned) == true) {
+ if ((pmlmepriv->assoc_by_rssi == true) &&
+ (pnetwork_max_rssi != NULL)) {
+ pnetwork = pnetwork_max_rssi;
+ goto ask_for_joinbss;
+ }
+ return _FAIL;
+ }
+ pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
+ struct wlan_network, list);
+ if (pnetwork == NULL)
+ return _FAIL;
+ pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ if (pmlmepriv->assoc_by_bssid == true) {
+ dst_ssid = pnetwork->network.MacAddress;
+ src_ssid = pmlmepriv->assoc_bssid;
+ if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ if (is_same_network(&pmlmepriv->
+ cur_network.network,
+ &pnetwork->network)) {
+ _clr_fwstate_(pmlmepriv,
+ _FW_UNDER_LINKING);
+ /*r8712_indicate_connect again*/
+ r8712_indicate_connect(adapter);
+ return 2;
+ }
+ r8712_disassoc_cmd(adapter);
+ r8712_ind_disconnect(adapter);
+ r8712_free_assoc_resources(adapter);
+ }
+ goto ask_for_joinbss;
+ }
+ } else if (pmlmepriv->assoc_ssid.SsidLength == 0)
+ goto ask_for_joinbss;
+ dst_ssid = pnetwork->network.Ssid.Ssid;
+ src_ssid = pmlmepriv->assoc_ssid.Ssid;
+ if ((pnetwork->network.Ssid.SsidLength ==
+ pmlmepriv->assoc_ssid.SsidLength) &&
+ (!memcmp(dst_ssid, src_ssid,
+ pmlmepriv->assoc_ssid.SsidLength))) {
+ if (pmlmepriv->assoc_by_rssi == true) {
+ /* if the ssid is the same, select the bss
+ * which has the max rssi*/
+ if (pnetwork_max_rssi) {
+ if (pnetwork->network.Rssi >
+ pnetwork_max_rssi->network.Rssi)
+ pnetwork_max_rssi = pnetwork;
+ } else
+ pnetwork_max_rssi = pnetwork;
+ } else if (is_desired_network(adapter, pnetwork)) {
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ r8712_disassoc_cmd(adapter);
+ r8712_free_assoc_resources(adapter);
+ }
+ goto ask_for_joinbss;
+ }
+ }
+ }
+ return _FAIL;
+ask_for_joinbss:
+ return r8712_joinbss_cmd(adapter, pnetwork);
+}
+
+sint r8712_set_auth(struct _adapter *adapter,
+ struct security_priv *psecuritypriv)
+{
+ struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
+ struct cmd_obj *pcmd;
+ struct setauth_parm *psetauthparm;
+ sint ret = _SUCCESS;
+
+ pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pcmd == NULL)
+ return _FAIL;
+
+ psetauthparm = (struct setauth_parm *)_malloc(
+ sizeof(struct setauth_parm));
+ if (psetauthparm == NULL) {
+ kfree((unsigned char *)pcmd);
+ return _FAIL;
+ }
+ memset(psetauthparm, 0, sizeof(struct setauth_parm));
+ psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm;
+ pcmd->cmdcode = _SetAuth_CMD_;
+ pcmd->parmbuf = (unsigned char *)psetauthparm;
+ pcmd->cmdsz = sizeof(struct setauth_parm);
+ pcmd->rsp = NULL;
+ pcmd->rspsz = 0;
+ _init_listhead(&pcmd->list);
+ r8712_enqueue_cmd(pcmdpriv, pcmd);
+ return ret;
+}
+
+sint r8712_set_key(struct _adapter *adapter,
+ struct security_priv *psecuritypriv,
+ sint keyid)
+{
+ struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
+ struct cmd_obj *pcmd;
+ struct setkey_parm *psetkeyparm;
+ u8 keylen;
+
+ pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pcmd == NULL)
+ return _FAIL;
+ psetkeyparm = (struct setkey_parm *)_malloc(sizeof(struct setkey_parm));
+ if (psetkeyparm == NULL) {
+ kfree((unsigned char *)pcmd);
+ return _FAIL;
+ }
+ memset(psetkeyparm, 0, sizeof(struct setkey_parm));
+ if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */
+ psetkeyparm->algorithm =
+ (u8)psecuritypriv->XGrpPrivacy;
+ } else { /* WEP */
+ psetkeyparm->algorithm =
+ (u8)psecuritypriv->PrivacyAlgrthm;
+ }
+ psetkeyparm->keyid = (u8)keyid;
+
+ switch (psetkeyparm->algorithm) {
+ case _WEP40_:
+ keylen = 5;
+ memcpy(psetkeyparm->key,
+ psecuritypriv->DefKey[keyid].skey, keylen);
+ break;
+ case _WEP104_:
+ keylen = 13;
+ memcpy(psetkeyparm->key,
+ psecuritypriv->DefKey[keyid].skey, keylen);
+ break;
+ case _TKIP_:
+ keylen = 16;
+ memcpy(psetkeyparm->key,
+ &psecuritypriv->XGrpKey[keyid - 1], keylen);
+ psetkeyparm->grpkey = 1;
+ break;
+ case _AES_:
+ keylen = 16;
+ memcpy(psetkeyparm->key,
+ &psecuritypriv->XGrpKey[keyid - 1], keylen);
+ psetkeyparm->grpkey = 1;
+ break;
+ default:
+ return _FAIL;
+ }
+ pcmd->cmdcode = _SetKey_CMD_;
+ pcmd->parmbuf = (u8 *)psetkeyparm;
+ pcmd->cmdsz = (sizeof(struct setkey_parm));
+ pcmd->rsp = NULL;
+ pcmd->rspsz = 0;
+ _init_listhead(&pcmd->list);
+ r8712_enqueue_cmd(pcmdpriv, pcmd);
+ return _SUCCESS;
+}
+
+/* adjust IEs for r8712_joinbss_cmd in WMM */
+int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie,
+ uint in_len, uint initial_out_len)
+{
+ unsigned int ielength = 0;
+ unsigned int i, j;
+
+ i = 12; /* after the fixed IE */
+ while (i < in_len) {
+ ielength = initial_out_len;
+ if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
+ in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
+ in_ie[i + 5] == 0x02 && i + 5 < in_len) {
+ /*WMM element ID and OUI*/
+ for (j = i; j < i + 9; j++) {
+ out_ie[ielength] = in_ie[j];
+ ielength++;
+ }
+ out_ie[initial_out_len + 1] = 0x07;
+ out_ie[initial_out_len + 6] = 0x00;
+ out_ie[initial_out_len + 8] = 0x00;
+ break;
+ }
+ i += (in_ie[i + 1] + 2); /* to the next IE element */
+ }
+ return ielength;
+}
+
+/*
+ * Ported from 8185: IsInPreAuthKeyList().
+ *
+ * Search by BSSID,
+ * Return Value:
+ * -1 :if there is no pre-auth key in the table
+ * >=0 :if there is pre-auth key, and return the entry id
+ */
+static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
+{
+ struct security_priv *psecuritypriv = &Adapter->securitypriv;
+ int i = 0;
+
+ do {
+ if (psecuritypriv->PMKIDList[i].bUsed &&
+ (!memcmp(psecuritypriv->PMKIDList[i].Bssid,
+ bssid, ETH_ALEN)))
+ break;
+ else
+ i++;
+ } while (i < NUM_PMKID_CACHE);
+
+ if (i == NUM_PMKID_CACHE) {
+ i = -1; /* Could not find. */
+ } else {
+ ; /* There is one Pre-Authentication Key for the
+ * specific BSSID. */
+ }
+ return i;
+}
+
+sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
+ u8 *out_ie, uint in_len)
+{
+ u8 authmode = 0, securitytype, match;
+ u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
+ u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
+ uint ielength, cnt, remove_cnt;
+ int iEntry;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ uint ndisauthmode = psecuritypriv->ndisauthtype;
+ uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
+
+ if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
+ (ndisauthmode == Ndis802_11AuthModeWPAPSK)) {
+ authmode = _WPA_IE_ID_;
+ uncst_oui[0] = 0x0;
+ uncst_oui[1] = 0x50;
+ uncst_oui[2] = 0xf2;
+ }
+ if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
+ (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) {
+ authmode = _WPA2_IE_ID_;
+ uncst_oui[0] = 0x0;
+ uncst_oui[1] = 0x0f;
+ uncst_oui[2] = 0xac;
+ }
+ switch (ndissecuritytype) {
+ case Ndis802_11Encryption1Enabled:
+ case Ndis802_11Encryption1KeyAbsent:
+ securitytype = _WEP40_;
+ uncst_oui[3] = 0x1;
+ break;
+ case Ndis802_11Encryption2Enabled:
+ case Ndis802_11Encryption2KeyAbsent:
+ securitytype = _TKIP_;
+ uncst_oui[3] = 0x2;
+ break;
+ case Ndis802_11Encryption3Enabled:
+ case Ndis802_11Encryption3KeyAbsent:
+ securitytype = _AES_;
+ uncst_oui[3] = 0x4;
+ break;
+ default:
+ securitytype = _NO_PRIVACY_;
+ break;
+ }
+ /*Search required WPA or WPA2 IE and copy to sec_ie[] */
+ cnt = 12;
+ match = false;
+ while (cnt < in_len) {
+ if (in_ie[cnt] == authmode) {
+ if ((authmode == _WPA_IE_ID_) &&
+ (!memcmp(&in_ie[cnt+2], &wpa_oui[0], 4))) {
+ memcpy(&sec_ie[0], &in_ie[cnt],
+ in_ie[cnt + 1] + 2);
+ match = true;
+ break;
+ }
+ if (authmode == _WPA2_IE_ID_) {
+ memcpy(&sec_ie[0], &in_ie[cnt],
+ in_ie[cnt + 1] + 2);
+ match = true;
+ break;
+ }
+ if (((authmode == _WPA_IE_ID_) &&
+ (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) ||
+ (authmode == _WPA2_IE_ID_))
+ memcpy(&bkup_ie[0], &in_ie[cnt],
+ in_ie[cnt + 1] + 2);
+ }
+ cnt += in_ie[cnt+1] + 2; /*get next*/
+ }
+ /*restruct WPA IE or WPA2 IE in sec_ie[] */
+ if (match == true) {
+ if (sec_ie[0] == _WPA_IE_ID_) {
+ /* parsing SSN IE to select required encryption
+ * algorithm, and set the bc/mc encryption algorithm */
+ while (true) {
+ /*check wpa_oui tag*/
+ if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
+ match = false;
+ break;
+ }
+ if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) {
+ /*IE Ver error*/
+ match = false;
+ break;
+ }
+ if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
+ /* get bc/mc encryption type (group
+ * key type)*/
+ switch (sec_ie[11]) {
+ case 0x0: /*none*/
+ psecuritypriv->XGrpPrivacy =
+ _NO_PRIVACY_;
+ break;
+ case 0x1: /*WEP_40*/
+ psecuritypriv->XGrpPrivacy =
+ _WEP40_;
+ break;
+ case 0x2: /*TKIP*/
+ psecuritypriv->XGrpPrivacy =
+ _TKIP_;
+ break;
+ case 0x3: /*AESCCMP*/
+ case 0x4:
+ psecuritypriv->XGrpPrivacy =
+ _AES_;
+ break;
+ case 0x5: /*WEP_104*/
+ psecuritypriv->XGrpPrivacy =
+ _WEP104_;
+ break;
+ }
+ } else {
+ match = false;
+ break;
+ }
+ if (sec_ie[12] == 0x01) {
+ /*check the unicast encryption type*/
+ if (memcmp(&sec_ie[14],
+ &uncst_oui[0], 4)) {
+ match = false;
+ break;
+
+ } /*else the uncst_oui is match*/
+ } else { /*mixed mode, unicast_enc_type > 1*/
+ /*select the uncst_oui and remove
+ * the other uncst_oui*/
+ cnt = sec_ie[12];
+ remove_cnt = (cnt-1) * 4;
+ sec_ie[12] = 0x01;
+ memcpy(&sec_ie[14], &uncst_oui[0], 4);
+ /*remove the other unicast suit*/
+ memcpy(&sec_ie[18],
+ &sec_ie[18 + remove_cnt],
+ sec_ie[1] - 18 + 2 -
+ remove_cnt);
+ sec_ie[1] = sec_ie[1] - remove_cnt;
+ }
+ break;
+ }
+ }
+ if (authmode == _WPA2_IE_ID_) {
+ /* parsing RSN IE to select required encryption
+ * algorithm, and set the bc/mc encryption algorithm */
+ while (true) {
+ if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
+ /*IE Ver error*/
+ match = false;
+ break;
+ }
+ if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) {
+ /*get bc/mc encryption type*/
+ switch (sec_ie[7]) {
+ case 0x1: /*WEP_40*/
+ psecuritypriv->XGrpPrivacy =
+ _WEP40_;
+ break;
+ case 0x2: /*TKIP*/
+ psecuritypriv->XGrpPrivacy =
+ _TKIP_;
+ break;
+ case 0x4: /*AESWRAP*/
+ psecuritypriv->XGrpPrivacy =
+ _AES_;
+ break;
+ case 0x5: /*WEP_104*/
+ psecuritypriv->XGrpPrivacy =
+ _WEP104_;
+ break;
+ default: /*one*/
+ psecuritypriv->XGrpPrivacy =
+ _NO_PRIVACY_;
+ break;
+ }
+ } else {
+ match = false;
+ break;
+ }
+ if (sec_ie[8] == 0x01) {
+ /*check the unicast encryption type*/
+ if (memcmp(&sec_ie[10],
+ &uncst_oui[0], 4)) {
+ match = false;
+ break;
+ } /*else the uncst_oui is match*/
+ } else { /*mixed mode, unicast_enc_type > 1*/
+ /*select the uncst_oui and remove the
+ * other uncst_oui*/
+ cnt = sec_ie[8];
+ remove_cnt = (cnt-1)*4;
+ sec_ie[8] = 0x01;
+ memcpy(&sec_ie[10], &uncst_oui[0], 4);
+ /*remove the other unicast suit*/
+ memcpy(&sec_ie[14],
+ &sec_ie[14 + remove_cnt],
+ (sec_ie[1] - 14 + 2 -
+ remove_cnt));
+ sec_ie[1] = sec_ie[1]-remove_cnt;
+ }
+ break;
+ }
+ }
+ }
+ if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
+ /*copy fixed ie*/
+ memcpy(out_ie, in_ie, 12);
+ ielength = 12;
+ /*copy RSN or SSN*/
+ if (match == true) {
+ memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1]+2);
+ ielength += sec_ie[1] + 2;
+ if (authmode == _WPA2_IE_ID_) {
+ /*the Pre-Authentication bit should be zero*/
+ out_ie[ielength - 1] = 0;
+ out_ie[ielength - 2] = 0;
+ }
+ r8712_report_sec_ie(adapter, authmode, sec_ie);
+ }
+ } else {
+ /*copy fixed ie only*/
+ memcpy(out_ie, in_ie, 12);
+ ielength = 12;
+ if (psecuritypriv->wps_phase == true) {
+ memcpy(out_ie+ielength, psecuritypriv->wps_ie,
+ psecuritypriv->wps_ie_len);
+ ielength += psecuritypriv->wps_ie_len;
+ }
+ }
+ iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
+ if (iEntry < 0)
+ return ielength;
+ else {
+ if (authmode == _WPA2_IE_ID_) {
+ out_ie[ielength] = 1;
+ ielength++;
+ out_ie[ielength] = 0; /*PMKID count = 0x0100*/
+ ielength++;
+ memcpy(&out_ie[ielength],
+ &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
+ ielength += 16;
+ out_ie[13] += 18;/*PMKID length = 2+16*/
+ }
+ }
+ return ielength;
+}
+
+void r8712_init_registrypriv_dev_network(struct _adapter *adapter)
+{
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ struct eeprom_priv *peepriv = &adapter->eeprompriv;
+ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
+ u8 *myhwaddr = myid(peepriv);
+
+ memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
+ memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
+ sizeof(struct ndis_802_11_ssid));
+ pdev_network->Configuration.Length =
+ sizeof(struct NDIS_802_11_CONFIGURATION);
+ pdev_network->Configuration.BeaconPeriod = 100;
+ pdev_network->Configuration.FHConfig.Length = 0;
+ pdev_network->Configuration.FHConfig.HopPattern = 0;
+ pdev_network->Configuration.FHConfig.HopSet = 0;
+ pdev_network->Configuration.FHConfig.DwellTime = 0;
+}
+
+void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
+{
+ int sz = 0;
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
+
+ pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
+ > 0 ? 1 : 0) ; /* adhoc no 802.1x */
+ pdev_network->Rssi = 0;
+ switch (pregistrypriv->wireless_mode) {
+ case WIRELESS_11B:
+ pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11DS);
+ break;
+ case WIRELESS_11G:
+ case WIRELESS_11BG:
+ pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM24);
+ break;
+ case WIRELESS_11A:
+ pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM5);
+ break;
+ default:
+ /* TODO */
+ break;
+ }
+ pdev_network->Configuration.DSConfig = cpu_to_le32(
+ pregistrypriv->channel);
+ if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
+ pdev_network->Configuration.ATIMWindow = cpu_to_le32(3);
+ pdev_network->InfrastructureMode = cpu_to_le32(
+ cur_network->network.InfrastructureMode);
+ /* 1. Supported rates
+ * 2. IE
+ */
+ sz = r8712_generate_ie(pregistrypriv, adapter);
+ pdev_network->IELength = sz;
+ pdev_network->Length = r8712_get_ndis_wlan_bssid_ex_sz(
+ (struct ndis_wlan_bssid_ex *)pdev_network);
+}
+
+/*the fucntion is at passive_level*/
+void r8712_joinbss_reset(struct _adapter *padapter)
+{
+ int i;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+
+ /* todo: if you want to do something io/reg/hw setting before join_bss,
+ * please add code here */
+ phtpriv->ampdu_enable = false;/*reset to disabled*/
+ for (i = 0; i < 16; i++)
+ phtpriv->baddbareq_issued[i] = false;/*reset it*/
+ if (phtpriv->ht_option) {
+ /* validate usb rx aggregation */
+ r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/
+ } else {
+ /* invalidate usb rx aggregation */
+ /* TH=1 => means that invalidate usb rx aggregation */
+ r8712_write8(padapter, 0x102500D9, 1);
+ }
+}
+
+/*the function is >= passive_level*/
+unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint *pout_len)
+{
+ u32 ielen, out_len;
+ unsigned char *p, *pframe;
+ struct ieee80211_ht_cap ht_capie;
+ unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+
+ phtpriv->ht_option = 0;
+ p = r8712_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12);
+ if (p && (ielen > 0)) {
+ if (pqospriv->qos_option == 0) {
+ out_len = *pout_len;
+ pframe = r8712_set_ie(out_ie+out_len,
+ _VENDOR_SPECIFIC_IE_,
+ _WMM_IE_Length_,
+ WMM_IE, pout_len);
+ pqospriv->qos_option = 1;
+ }
+ out_len = *pout_len;
+ memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
+ ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_MAX_AMSDU |
+ IEEE80211_HT_CAP_DSSSCCK40;
+ ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR &
+ 0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
+ pframe = r8712_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_,
+ sizeof(struct ieee80211_ht_cap),
+ (unsigned char *)&ht_capie, pout_len);
+ phtpriv->ht_option = 1;
+ }
+ return phtpriv->ht_option;
+}
+
+/* the fucntion is > passive_level (in critical_section) */
+static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
+{
+ u8 *p, max_ampdu_sz;
+ int i, len;
+ struct sta_info *bmc_sta, *psta;
+ struct ieee80211_ht_cap *pht_capie;
+ struct ieee80211_ht_addt_info *pht_addtinfo;
+ struct recv_reorder_ctrl *preorder_ctrl;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ struct wlan_network *pcur_network = &(pmlmepriv->cur_network);
+
+ if (!phtpriv->ht_option)
+ return;
+ /* maybe needs check if ap supports rx ampdu. */
+ if ((phtpriv->ampdu_enable == false) &&
+ (pregistrypriv->ampdu_enable == 1))
+ phtpriv->ampdu_enable = true;
+ /*check Max Rx A-MPDU Size*/
+ len = 0;
+ p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
+ _HT_CAPABILITY_IE_,
+ &len, ie_len -
+ sizeof(struct NDIS_802_11_FIXED_IEs));
+ if (p && len > 0) {
+ pht_capie = (struct ieee80211_ht_cap *)(p+2);
+ max_ampdu_sz = (pht_capie->ampdu_params_info &
+ IEEE80211_HT_CAP_AMPDU_FACTOR);
+ /* max_ampdu_sz (kbytes); */
+ max_ampdu_sz = 1 << (max_ampdu_sz+3);
+ phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
+ }
+ /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
+ * if A-MPDU Rx is enabled, reseting rx_ordering_ctrl
+ * wstart_b(indicate_seq) to default value=0xffff
+ * todo: check if AP can send A-MPDU packets
+ */
+ bmc_sta = r8712_get_bcmc_stainfo(padapter);
+ if (bmc_sta) {
+ for (i = 0; i < 16; i++) {
+ preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
+ preorder_ctrl->indicate_seq = 0xffff;
+ preorder_ctrl->wend_b = 0xffff;
+ }
+ }
+ psta = r8712_get_stainfo(&padapter->stapriv,
+ pcur_network->network.MacAddress);
+ if (psta) {
+ for (i = 0; i < 16 ; i++) {
+ preorder_ctrl = &psta->recvreorder_ctrl[i];
+ preorder_ctrl->indicate_seq = 0xffff;
+ preorder_ctrl->wend_b = 0xffff;
+ }
+ }
+ len = 0;
+ p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
+ _HT_ADD_INFO_IE_, &len,
+ ie_len-sizeof(struct NDIS_802_11_FIXED_IEs));
+ if (p && len > 0)
+ pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
+}
+
+void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+
+ if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable == true)) {
+ if (phtpriv->baddbareq_issued[priority] == false) {
+ r8712_addbareq_cmd(padapter, (u8)priority);
+ phtpriv->baddbareq_issued[priority] = true;
+ }
+ }
+}
+
+/*the fucntion is >= passive_level*/
+unsigned int r8712_add_ht_addt_info(struct _adapter *padapter,
+ u8 *in_ie, u8 *out_ie,
+ uint in_len, uint *pout_len)
+{
+ u32 ielen, out_len = 0;
+ unsigned char *p, *pframe;
+ struct ieee80211_ht_addt_info ht_addt_info;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ out_len = *pout_len;
+
+ if (pregistrypriv->ht_enable == 1) {
+ p = r8712_get_ie(in_ie+12, _HT_ADD_INFO_IE_,
+ &ielen, in_len - 12);
+ if (p && (ielen > 0)) {
+ ; /* dummy branch */
+ } else {
+ if (p == NULL) {
+ int sz = sizeof(struct ieee80211_ht_addt_info);
+ memset(&ht_addt_info, 0, sz);
+ /*need to add the HT additional IEs*/
+ ht_addt_info.control_chan =
+ pregistrypriv->channel;
+ pframe = r8712_set_ie(out_ie + out_len,
+ _HT_ADD_INFO_IE_,
+ sz,
+ (unsigned char *)&ht_addt_info,
+ pout_len);
+ }
+ }
+ }
+ return phtpriv->ht_option;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h
new file mode 100644
index 000000000000..2b35b740ab89
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mlme.h
@@ -0,0 +1,208 @@
+#ifndef __RTL871X_MLME_H_
+#define __RTL871X_MLME_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wlan_bssdef.h"
+
+#define MAX_BSS_CNT 64
+#define MAX_JOIN_TIMEOUT 6000
+
+#define SCANNING_TIMEOUT 4500
+
+#define SCANQUEUE_LIFETIME 20 /* unit:sec */
+
+#define WIFI_NULL_STATE 0x00000000
+#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state...*/
+#define WIFI_REASOC_STATE 0x00000002
+#define WIFI_SLEEP_STATE 0x00000004
+#define WIFI_STATION_STATE 0x00000008
+#define WIFI_AP_STATE 0x00000010
+#define WIFI_ADHOC_STATE 0x00000020
+#define WIFI_ADHOC_MASTER_STATE 0x00000040
+#define WIFI_UNDER_LINKING 0x00000080
+#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station
+ * is under site surveying*/
+#define WIFI_MP_STATE 0x00010000
+#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in cont. tx background*/
+#define WIFI_MP_CTX_ST 0x00040000 /* in cont. tx with
+ * single-tone*/
+#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx
+ * background due to out of skb*/
+#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continous tx*/
+#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier
+ * suppression*/
+#define WIFI_MP_LPBK_STATE 0x00400000
+
+#define _FW_UNDER_LINKING WIFI_UNDER_LINKING
+#define _FW_LINKED WIFI_ASOC_STATE
+#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR
+
+/*
+there are several "locks" in mlme_priv,
+since mlme_priv is a shared resource between many threads,
+like ISR/Call-Back functions, the OID handlers, and even timer functions.
+Each _queue has its own locks, already.
+Other items are protected by mlme_priv.lock.
+To avoid possible dead lock, any thread trying to modifiying mlme_priv
+SHALL not lock up more than one locks at a time!
+*/
+
+#define traffic_threshold 10
+#define traffic_scan_period 500
+
+struct sitesurvey_ctrl {
+ u64 last_tx_pkts;
+ uint last_rx_pkts;
+ sint traffic_busy;
+ struct timer_list sitesurvey_ctrl_timer;
+};
+
+struct mlme_priv {
+
+ spinlock_t lock;
+ spinlock_t lock2;
+ sint fw_state; /*shall we protect this variable? */
+ u8 to_join; /*flag*/
+ u8 *nic_hdl;
+ struct list_head *pscanned;
+ struct __queue free_bss_pool;
+ struct __queue scanned_queue;
+ u8 *free_bss_buf;
+ unsigned long num_of_scanned;
+ struct ndis_802_11_ssid assoc_ssid;
+ u8 assoc_bssid[6];
+ struct wlan_network cur_network;
+ struct sitesurvey_ctrl sitesurveyctrl;
+ struct timer_list assoc_timer;
+ uint assoc_by_bssid;
+ uint assoc_by_rssi;
+ struct timer_list scan_to_timer; /* driver handles scan_timeout.*/
+ struct timer_list dhcp_timer; /* set dhcp to if driver in ps mode.*/
+ struct qos_priv qospriv;
+ struct ht_priv htpriv;
+ struct timer_list wdg_timer; /*watchdog periodic timer*/
+};
+
+static inline u8 *get_bssid(struct mlme_priv *pmlmepriv)
+{
+ return pmlmepriv->cur_network.network.MacAddress;
+}
+
+static inline u8 check_fwstate(struct mlme_priv *pmlmepriv, sint state)
+{
+ if (pmlmepriv->fw_state & state)
+ return true;
+ return false;
+}
+
+static inline sint get_fwstate(struct mlme_priv *pmlmepriv)
+{
+ return pmlmepriv->fw_state;
+}
+
+/*
+ * No Limit on the calling context,
+ * therefore set it to be the critical section...
+ *
+ * ### NOTE:#### (!!!!)
+ * TAKE CARE THAT BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock
+ */
+static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state)
+{
+ pmlmepriv->fw_state |= state;
+}
+
+static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state)
+{
+ pmlmepriv->fw_state &= ~state;
+}
+
+/*
+ * No Limit on the calling context,
+ * therefore set it to be the critical section...
+ */
+static inline void clr_fwstate(struct mlme_priv *pmlmepriv, sint state)
+{
+ unsigned long irqL;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, state) == true)
+ pmlmepriv->fw_state ^= state;
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+static inline void up_scanned_network(struct mlme_priv *pmlmepriv)
+{
+ unsigned long irqL;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ pmlmepriv->num_of_scanned++;
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+static inline void down_scanned_network(struct mlme_priv *pmlmepriv)
+{
+ unsigned long irqL;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ pmlmepriv->num_of_scanned--;
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv,
+ sint val)
+{
+ unsigned long irqL;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ pmlmepriv->num_of_scanned = val;
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+}
+
+void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf);
+void r8712_free_network_queue(struct _adapter *adapter);
+int r8712_init_mlme_priv(struct _adapter *adapter);
+void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv);
+sint r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv);
+sint r8712_set_key(struct _adapter *adapter,
+ struct security_priv *psecuritypriv, sint keyid);
+sint r8712_set_auth(struct _adapter *adapter,
+ struct security_priv *psecuritypriv);
+uint r8712_get_ndis_wlan_bssid_ex_sz(struct ndis_wlan_bssid_ex *bss);
+void r8712_generate_random_ibss(u8 *pibss);
+u8 *r8712_get_capability_from_ie(u8 *ie);
+struct wlan_network *r8712_get_oldest_wlan_network(
+ struct __queue *scanned_queue);
+void r8712_free_assoc_resources(struct _adapter *adapter);
+void r8712_ind_disconnect(struct _adapter *adapter);
+void r8712_indicate_connect(struct _adapter *adapter);
+int r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
+ u8 *out_ie, uint in_len);
+int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint initial_out_len);
+void r8712_init_registrypriv_dev_network(struct _adapter *adapter);
+void r8712_update_registrypriv_dev_network(struct _adapter *adapter);
+void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter);
+void _r8712_join_timeout_handler(struct _adapter *adapter);
+void r8712_scan_timeout_handler(struct _adapter *adapter);
+void _r8712_dhcp_timeout_handler(struct _adapter *adapter);
+void _r8712_wdg_timeout_handler(struct _adapter *adapter);
+struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv);
+sint r8712_if_up(struct _adapter *padapter);
+void r8712_joinbss_reset(struct _adapter *padapter);
+unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint *pout_len);
+void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority);
+unsigned int r8712_add_ht_addt_info(struct _adapter *padapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint *pout_len);
+int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork);
+
+#endif /*__RTL871X_MLME_H_*/
diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c
new file mode 100644
index 000000000000..427467cb10bd
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mp.c
@@ -0,0 +1,736 @@
+/******************************************************************************
+ * rtl871x_mp.c
+ *
+ * Description :
+ *
+ * Author :
+ *
+ * History :
+ *
+ * Copyright 2007, Realtek Corp.
+ *
+ * The contents of this file is the sole property of Realtek Corp. It can not be
+ * be used, copied or modified without written permission from Realtek Corp.
+ *
+*******************************************************************************/
+#define _RTL871X_MP_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_mp_phy_regdef.h"
+#include "rtl8712_cmd.h"
+
+static void _init_mp_priv_(struct mp_priv *pmp_priv)
+{
+ pmp_priv->mode = _LOOPBOOK_MODE_;
+ pmp_priv->curr_ch = 1;
+ pmp_priv->curr_modem = MIXED_PHY;
+ pmp_priv->curr_rateidx = 0;
+ pmp_priv->curr_txpoweridx = 0x14;
+ pmp_priv->antenna_tx = ANTENNA_A;
+ pmp_priv->antenna_rx = ANTENNA_AB;
+ pmp_priv->check_mp_pkt = 0;
+ pmp_priv->tx_pktcount = 0;
+ pmp_priv->rx_pktcount = 0;
+ pmp_priv->rx_crcerrpktcount = 0;
+}
+
+static int init_mp_priv(struct mp_priv *pmp_priv)
+{
+ int i, res;
+ struct mp_xmit_frame *pmp_xmitframe;
+
+ _init_mp_priv_(pmp_priv);
+ _init_queue(&pmp_priv->free_mp_xmitqueue);
+ pmp_priv->pallocated_mp_xmitframe_buf = NULL;
+ pmp_priv->pallocated_mp_xmitframe_buf = _malloc(NR_MP_XMITFRAME *
+ sizeof(struct mp_xmit_frame) + 4);
+ if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) {
+ res = _FAIL;
+ goto _exit_init_mp_priv;
+ }
+ pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf +
+ 4 -
+ ((addr_t)(pmp_priv->pallocated_mp_xmitframe_buf) & 3);
+ pmp_xmitframe = (struct mp_xmit_frame *)pmp_priv->pmp_xmtframe_buf;
+ for (i = 0; i < NR_MP_XMITFRAME; i++) {
+ _init_listhead(&(pmp_xmitframe->list));
+ list_insert_tail(&(pmp_xmitframe->list),
+ &(pmp_priv->free_mp_xmitqueue.queue));
+ pmp_xmitframe->pkt = NULL;
+ pmp_xmitframe->frame_tag = MP_FRAMETAG;
+ pmp_xmitframe->padapter = pmp_priv->papdater;
+ pmp_xmitframe++;
+ }
+ pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME;
+ res = _SUCCESS;
+_exit_init_mp_priv:
+ return res;
+}
+
+static int free_mp_priv(struct mp_priv *pmp_priv)
+{
+ int res = 0;
+ kfree(pmp_priv->pallocated_mp_xmitframe_buf);
+ return res;
+}
+
+void mp871xinit(struct _adapter *padapter)
+{
+ struct mp_priv *pmppriv = &padapter->mppriv;
+
+ pmppriv->papdater = padapter;
+ init_mp_priv(pmppriv);
+}
+
+void mp871xdeinit(struct _adapter *padapter)
+{
+ struct mp_priv *pmppriv = &padapter->mppriv;
+
+ free_mp_priv(pmppriv);
+}
+
+/*
+ * Special for bb and rf reg read/write
+ */
+static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd)
+{
+ u32 cmd32 = 0, val32 = 0;
+ u8 iocmd_class = iocmd.cmdclass;
+ u16 iocmd_value = iocmd.value;
+ u8 iocmd_idx = iocmd.index;
+
+ cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+ if (r8712_fw_cmd(pAdapter, cmd32))
+ r8712_fw_cmd_data(pAdapter, &val32, 1);
+ else
+ val32 = 0;
+ return val32;
+}
+
+static u8 fw_iocmd_write(struct _adapter *pAdapter,
+ struct IOCMD_STRUCT iocmd, u32 value)
+{
+ u32 cmd32 = 0;
+ u8 iocmd_class = iocmd.cmdclass;
+ u32 iocmd_value = iocmd.value;
+ u8 iocmd_idx = iocmd.index;
+
+ r8712_fw_cmd_data(pAdapter, &value, 0);
+ msleep(100);
+ cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+ return r8712_fw_cmd(pAdapter, cmd32);
+}
+
+/* offset : 0X800~0XFFF */
+u32 r8712_bb_reg_read(struct _adapter *pAdapter, u16 offset)
+{
+ u8 shift = offset & 0x0003; /* 4 byte access */
+ u16 bb_addr = offset & 0x0FFC; /* 4 byte access */
+ u32 bb_val = 0;
+ struct IOCMD_STRUCT iocmd;
+
+ iocmd.cmdclass = IOCMD_CLASS_BB_RF;
+ iocmd.value = bb_addr;
+ iocmd.index = IOCMD_BB_READ_IDX;
+ bb_val = fw_iocmd_read(pAdapter, iocmd);
+ if (shift != 0) {
+ u32 bb_val2 = 0;
+ bb_val >>= (shift * 8);
+ iocmd.value += 4;
+ bb_val2 = fw_iocmd_read(pAdapter, iocmd);
+ bb_val2 <<= ((4 - shift) * 8);
+ bb_val |= bb_val2;
+ }
+ return bb_val;
+}
+
+/* offset : 0X800~0XFFF */
+u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value)
+{
+ u8 shift = offset & 0x0003; /* 4 byte access */
+ u16 bb_addr = offset & 0x0FFC; /* 4 byte access */
+ struct IOCMD_STRUCT iocmd;
+
+ iocmd.cmdclass = IOCMD_CLASS_BB_RF;
+ iocmd.value = bb_addr;
+ iocmd.index = IOCMD_BB_WRITE_IDX;
+ if (shift != 0) {
+ u32 oldValue = 0;
+ u32 newValue = value;
+
+ oldValue = r8712_bb_reg_read(pAdapter, iocmd.value);
+ oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8));
+ value = oldValue | (newValue << (shift * 8));
+ if (fw_iocmd_write(pAdapter, iocmd, value) == false)
+ return false;
+ iocmd.value += 4;
+ oldValue = r8712_bb_reg_read(pAdapter, iocmd.value);
+ oldValue &= (0xFFFFFFFF << (shift * 8));
+ value = oldValue | (newValue >> ((4 - shift) * 8));
+ }
+ return fw_iocmd_write(pAdapter, iocmd, value);
+}
+
+/* offset : 0x00 ~ 0xFF */
+u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset)
+{
+ u16 rf_addr = (path << 8) | offset;
+ u32 rf_data;
+ struct IOCMD_STRUCT iocmd;
+
+ iocmd.cmdclass = IOCMD_CLASS_BB_RF ;
+ iocmd.value = rf_addr ;
+ iocmd.index = IOCMD_RF_READ_IDX;
+ rf_data = fw_iocmd_read(pAdapter, iocmd);
+ return rf_data;
+}
+
+u8 r8712_rf_reg_write(struct _adapter *pAdapter, u8 path, u8 offset, u32 value)
+{
+ u16 rf_addr = (path << 8) | offset;
+ struct IOCMD_STRUCT iocmd;
+
+ iocmd.cmdclass = IOCMD_CLASS_BB_RF;
+ iocmd.value = rf_addr;
+ iocmd.index = IOCMD_RF_WRIT_IDX;
+ return fw_iocmd_write(pAdapter, iocmd, value);
+}
+
+static u32 bitshift(u32 bitmask)
+{
+ u32 i;
+
+ for (i = 0; i <= 31; i++)
+ if (((bitmask>>i) & 0x1) == 1)
+ break;
+ return i;
+}
+
+static u32 get_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask)
+{
+ u32 org_value, bit_shift, new_value;
+
+ org_value = r8712_bb_reg_read(pAdapter, offset);
+ bit_shift = bitshift(bitmask);
+ new_value = (org_value & bitmask) >> bit_shift;
+ return new_value;
+}
+
+static u8 set_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask, u32 value)
+{
+ u32 org_value, bit_shift, new_value;
+
+ if (bitmask != bMaskDWord) {
+ org_value = r8712_bb_reg_read(pAdapter, offset);
+ bit_shift = bitshift(bitmask);
+ new_value = ((org_value & (~bitmask)) | (value << bit_shift));
+ } else
+ new_value = value;
+ return r8712_bb_reg_write(pAdapter, offset, new_value);
+}
+
+static u32 get_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset,
+ u32 bitmask)
+{
+ u32 org_value, bit_shift, new_value;
+
+ org_value = r8712_rf_reg_read(pAdapter, path, offset);
+ bit_shift = bitshift(bitmask);
+ new_value = (org_value & bitmask) >> bit_shift;
+ return new_value;
+}
+
+static u8 set_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, u32 bitmask,
+ u32 value)
+{
+ u32 org_value, bit_shift, new_value;
+
+ if (bitmask != bMaskDWord) {
+ org_value = r8712_rf_reg_read(pAdapter, path, offset);
+ bit_shift = bitshift(bitmask);
+ new_value = ((org_value & (~bitmask)) | (value << bit_shift));
+ } else
+ new_value = value;
+ return r8712_rf_reg_write(pAdapter, path, offset, new_value);
+}
+
+/*
+ * SetChannel
+ * Description
+ * Use H2C command to change channel,
+ * not only modify rf register, but also other setting need to be done.
+ */
+void r8712_SetChannel(struct _adapter *pAdapter)
+{
+ struct cmd_priv *pcmdpriv = &pAdapter->cmdpriv;
+ struct cmd_obj *pcmd = NULL;
+ struct SetChannel_parm *pparm = NULL;
+ u16 code = GEN_CMD_CODE(_SetChannel);
+
+ pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj));
+ if (pcmd == NULL)
+ return;
+ pparm = (struct SetChannel_parm *)_malloc(sizeof(struct
+ SetChannel_parm));
+ if (pparm == NULL) {
+ if (pcmd != NULL)
+ kfree((u8 *)pcmd);
+ return;
+ }
+ pparm->curr_ch = pAdapter->mppriv.curr_ch;
+ init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code);
+ r8712_enqueue_cmd(pcmdpriv, pcmd);
+}
+
+static void SetCCKTxPower(struct _adapter *pAdapter, u8 TxPower)
+{
+ u16 TxAGC = 0;
+
+ TxAGC = TxPower;
+ set_bb_reg(pAdapter, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
+}
+
+static void SetOFDMTxPower(struct _adapter *pAdapter, u8 TxPower)
+{
+ u32 TxAGC = 0;
+
+ TxAGC |= ((TxPower<<24)|(TxPower<<16)|(TxPower<<8)|TxPower);
+ set_bb_reg(pAdapter, rTxAGC_Rate18_06, bTxAGCRate18_06, TxAGC);
+ set_bb_reg(pAdapter, rTxAGC_Rate54_24, bTxAGCRate54_24, TxAGC);
+ set_bb_reg(pAdapter, rTxAGC_Mcs03_Mcs00, bTxAGCRateMCS3_MCS0, TxAGC);
+ set_bb_reg(pAdapter, rTxAGC_Mcs07_Mcs04, bTxAGCRateMCS7_MCS4, TxAGC);
+ set_bb_reg(pAdapter, rTxAGC_Mcs11_Mcs08, bTxAGCRateMCS11_MCS8, TxAGC);
+ set_bb_reg(pAdapter, rTxAGC_Mcs15_Mcs12, bTxAGCRateMCS15_MCS12, TxAGC);
+}
+
+void r8712_SetTxPower(struct _adapter *pAdapter)
+{
+ u8 TxPower = pAdapter->mppriv.curr_txpoweridx;
+ SetCCKTxPower(pAdapter, TxPower);
+ SetOFDMTxPower(pAdapter, TxPower);
+}
+
+void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset)
+{
+ u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC;
+
+ TxAGCOffset_B = (ulTxAGCOffset&0x000000ff);
+ TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8);
+ TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16);
+ tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B);
+ set_bb_reg(pAdapter, rFPGA0_TxGainStage,
+ (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC);
+}
+
+void r8712_SetDataRate(struct _adapter *pAdapter)
+{
+ u8 path = RF_PATH_A;
+ u8 offset = RF_SYN_G2;
+ u32 value;
+
+ value = (pAdapter->mppriv.curr_rateidx < 4) ? 0x4440 : 0xF200;
+ r8712_rf_reg_write(pAdapter, path, offset, value);
+}
+
+void r8712_SwitchBandwidth(struct _adapter *pAdapter)
+{
+ /* 3 1.Set MAC register : BWOPMODE bit2:1 20MhzBW */
+ u8 regBwOpMode = 0;
+ u8 Bandwidth = pAdapter->mppriv.curr_bandwidth;
+
+ regBwOpMode = r8712_read8(pAdapter, 0x10250203);
+ if (Bandwidth == HT_CHANNEL_WIDTH_20)
+ regBwOpMode |= BIT(2);
+ else
+ regBwOpMode &= ~(BIT(2));
+ r8712_write8(pAdapter, 0x10250203, regBwOpMode);
+ /* 3 2.Set PHY related register */
+ switch (Bandwidth) {
+ /* 20 MHz channel*/
+ case HT_CHANNEL_WIDTH_20:
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x0);
+ set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x0);
+ /* Use PHY_REG.txt default value. Do not need to change.
+ * Correct the tx power for CCK rate in 40M.
+ * It is set in Tx descriptor for 8192x series
+ */
+ set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x58);
+ break;
+ /* 40 MHz channel*/
+ case HT_CHANNEL_WIDTH_40:
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x1);
+ set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x1);
+ /* Use PHY_REG.txt default value. Do not need to change.
+ * Correct the tx power for CCK rate in 40M.
+ * Set Control channel to upper or lower. These settings are
+ * required only for 40MHz */
+ set_bb_reg(pAdapter, rCCK0_System, bCCKSideBand,
+ (HAL_PRIME_CHNL_OFFSET_DONT_CARE>>1));
+ set_bb_reg(pAdapter, rOFDM1_LSTF, 0xC00,
+ HAL_PRIME_CHNL_OFFSET_DONT_CARE);
+ set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x18);
+ break;
+ default:
+ break;
+ }
+
+ /* 3 3.Set RF related register */
+ switch (Bandwidth) {
+ case HT_CHANNEL_WIDTH_20:
+ set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW,
+ BIT(10) | BIT(11), 0x01);
+ break;
+ case HT_CHANNEL_WIDTH_40:
+ set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW,
+ BIT(10) | BIT(11), 0x00);
+ break;
+ default:
+ break;
+ }
+}
+/*------------------------------Define structure----------------------------*/
+struct R_ANTENNA_SELECT_OFDM {
+ u32 r_tx_antenna:4;
+ u32 r_ant_l:4;
+ u32 r_ant_non_ht:4;
+ u32 r_ant_ht1:4;
+ u32 r_ant_ht2:4;
+ u32 r_ant_ht_s1:4;
+ u32 r_ant_non_ht_s1:4;
+ u32 OFDM_TXSC:2;
+ u32 Reserved:2;
+};
+
+struct R_ANTENNA_SELECT_CCK {
+ u8 r_cckrx_enable_2:2;
+ u8 r_cckrx_enable:2;
+ u8 r_ccktx_enable:4;
+};
+
+void r8712_SwitchAntenna(struct _adapter *pAdapter)
+{
+ u32 ofdm_tx_en_val = 0, ofdm_tx_ant_sel_val = 0;
+ u8 ofdm_rx_ant_sel_val = 0;
+ u8 cck_ant_select_val = 0;
+ u32 cck_ant_sel_val = 0;
+ struct R_ANTENNA_SELECT_CCK *p_cck_txrx;
+
+ p_cck_txrx = (struct R_ANTENNA_SELECT_CCK *)&cck_ant_select_val;
+
+ switch (pAdapter->mppriv.antenna_tx) {
+ case ANTENNA_A:
+ /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/
+ set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+ set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1);
+ ofdm_tx_en_val = 0x3;
+ ofdm_tx_ant_sel_val = 0x11111111;/* Power save */
+ p_cck_txrx->r_ccktx_enable = 0x8;
+ break;
+ case ANTENNA_B:
+ set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1);
+ set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+ ofdm_tx_en_val = 0x3;
+ ofdm_tx_ant_sel_val = 0x22222222;/* Power save */
+ p_cck_txrx->r_ccktx_enable = 0x4;
+ break;
+ case ANTENNA_AB: /* For 8192S */
+ set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
+ set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
+ ofdm_tx_en_val = 0x3;
+ ofdm_tx_ant_sel_val = 0x3321333; /* Disable Power save */
+ p_cck_txrx->r_ccktx_enable = 0xC;
+ break;
+ default:
+ break;
+ }
+ /*OFDM Tx*/
+ set_bb_reg(pAdapter, rFPGA1_TxInfo, 0xffffffff, ofdm_tx_ant_sel_val);
+ /*OFDM Tx*/
+ set_bb_reg(pAdapter, rFPGA0_TxInfo, 0x0000000f, ofdm_tx_en_val);
+ switch (pAdapter->mppriv.antenna_rx) {
+ case ANTENNA_A:
+ ofdm_rx_ant_sel_val = 0x1; /* A */
+ p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */
+ p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */
+ break;
+ case ANTENNA_B:
+ ofdm_rx_ant_sel_val = 0x2; /* B */
+ p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */
+ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */
+ break;
+ case ANTENNA_AB:
+ ofdm_rx_ant_sel_val = 0x3; /* AB */
+ p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */
+ p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */
+ break;
+ default:
+ break;
+ }
+ /*OFDM Rx*/
+ set_bb_reg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f,
+ ofdm_rx_ant_sel_val);
+ /*OFDM Rx*/
+ set_bb_reg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f,
+ ofdm_rx_ant_sel_val);
+
+ cck_ant_sel_val = cck_ant_select_val;
+ /*CCK TxRx*/
+ set_bb_reg(pAdapter, rCCK0_AFESetting, bMaskByte3, cck_ant_sel_val);
+}
+
+void r8712_SetCrystalCap(struct _adapter *pAdapter)
+{
+ set_bb_reg(pAdapter, rFPGA0_AnalogParameter1, bXtalCap,
+ pAdapter->mppriv.curr_crystalcap);
+}
+
+static void TriggerRFThermalMeter(struct _adapter *pAdapter)
+{
+ /* 0x24: RF Reg[6:5] */
+ set_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60);
+}
+
+static u32 ReadRFThermalMeter(struct _adapter *pAdapter)
+{
+ u32 ThermalValue = 0;
+
+ /* 0x24: RF Reg[4:0] */
+ ThermalValue = get_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, 0x1F);
+ return ThermalValue;
+}
+
+void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value)
+{
+ TriggerRFThermalMeter(pAdapter);
+ msleep(1000);
+ *value = ReadRFThermalMeter(pAdapter);
+}
+
+void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart)
+{
+ if (bStart) { /* Start Single Carrier. */
+ /* 1. if OFDM block on? */
+ if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
+ /*set OFDM block on*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);
+ /* 2. set CCK test mode off, set to CCK normal mode */
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable);
+ /* 3. turn on scramble setting */
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
+ /* 4. Turn On Single Carrier Tx and off the other test modes. */
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
+ } else { /* Stop Single Carrier.*/
+ /* Turn off all test modes.*/
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier,
+ bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
+ msleep(20);
+ /*BB Reset*/
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+}
+
+void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart)
+{
+ u8 rfPath = pAdapter->mppriv.curr_rfpath;
+ switch (pAdapter->mppriv.antenna_tx) {
+ case ANTENNA_B:
+ rfPath = RF_PATH_B;
+ break;
+ case ANTENNA_A:
+ default:
+ rfPath = RF_PATH_A;
+ break;
+ }
+ if (bStart) { /* Start Single Tone.*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bDisable);
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bDisable);
+ set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask,
+ 0xd4000);
+ msleep(100);
+ /* PAD all on.*/
+ set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x2001f);
+ msleep(100);
+ } else { /* Stop Single Tone.*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);
+ set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask,
+ 0x54000);
+ msleep(100);
+ /* PAD all on.*/
+ set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x30000);
+ msleep(100);
+ }
+}
+
+void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart)
+{
+ if (bStart) { /* Start Carrier Suppression.*/
+ if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) {
+ /* 1. if CCK block on? */
+ if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) {
+ /*set CCK block on*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn,
+ bEnable);
+ }
+ /* Turn Off All Test Mode */
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx,
+ bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier,
+ bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone,
+ bDisable);
+ /*transmit mode*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2);
+ /*turn off scramble setting*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble,
+ bDisable);
+ /*Set CCK Tx Test Rate*/
+ /*Set FTxRate to 1Mbps*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, 0x0);
+ }
+ } else { /* Stop Carrier Suppression. */
+ if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) {
+ /*normal mode*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0);
+ /*turn on scramble setting*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble,
+ bEnable);
+ /*BB Reset*/
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+ }
+}
+
+static void SetCCKContinuousTx(struct _adapter *pAdapter, u8 bStart)
+{
+ u32 cckrate;
+
+ if (bStart) {
+ /* 1. if CCK block on? */
+ if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) {
+ /*set CCK block on*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);
+ }
+ /* Turn Off All Test Mode */
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
+ /*Set CCK Tx Test Rate*/
+ cckrate = pAdapter->mppriv.curr_rateidx;
+ set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, cckrate);
+ /*transmit mode*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2);
+ /*turn on scramble setting*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
+ } else {
+ /*normal mode*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0);
+ /*turn on scramble setting*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
+ /*BB Reset*/
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+} /* mpt_StartCckContTx */
+
+static void SetOFDMContinuousTx(struct _adapter *pAdapter, u8 bStart)
+{
+ if (bStart) {
+ /* 1. if OFDM block on? */
+ if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) {
+ /*set OFDM block on*/
+ set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);
+ }
+ /* 2. set CCK test mode off, set to CCK normal mode*/
+ set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable);
+ /* 3. turn on scramble setting */
+ set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
+ /* 4. Turn On Continue Tx and turn off the other test modes.*/
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
+ } else {
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier,
+ bDisable);
+ set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
+ msleep(20);
+ /*BB Reset*/
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
+ set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
+ }
+} /* mpt_StartOfdmContTx */
+
+void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart)
+{
+ /* ADC turn off [bit24-21] adc port0 ~ port1 */
+ if (bStart) {
+ r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA,
+ r8712_bb_reg_read(pAdapter,
+ rRx_Wait_CCCA) & 0xFE1FFFFF);
+ msleep(100);
+ }
+ if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M)
+ SetCCKContinuousTx(pAdapter, bStart);
+ else if ((pAdapter->mppriv.curr_rateidx >= MPT_RATE_6M) &&
+ (pAdapter->mppriv.curr_rateidx <= MPT_RATE_MCS15))
+ SetOFDMContinuousTx(pAdapter, bStart);
+ /* ADC turn on [bit24-21] adc port0 ~ port1 */
+ if (!bStart)
+ r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA,
+ r8712_bb_reg_read(pAdapter,
+ rRx_Wait_CCCA) | 0x01E00000);
+}
+
+void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter)
+{
+ u32 i, phyrx_set = 0;
+
+ for (i = OFDM_PPDU_BIT; i <= HT_MPDU_FAIL_BIT; i++) {
+ phyrx_set = 0;
+ phyrx_set |= (i << 28); /*select*/
+ phyrx_set |= 0x08000000; /* set counter to zero*/
+ r8712_write32(pAdapter, RXERR_RPT, phyrx_set);
+ }
+}
+
+static u32 GetPhyRxPktCounts(struct _adapter *pAdapter, u32 selbit)
+{
+ /*selection*/
+ u32 phyrx_set = 0, count = 0;
+ u32 SelectBit;
+
+ SelectBit = selbit << 28;
+ phyrx_set |= (SelectBit & 0xF0000000);
+ r8712_write32(pAdapter, RXERR_RPT, phyrx_set);
+ /*Read packet count*/
+ count = r8712_read32(pAdapter, RXERR_RPT) & RPTMaxCount;
+ return count;
+}
+
+u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter)
+{
+ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
+
+ OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_OK_BIT);
+ CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_OK_BIT);
+ HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_OK_BIT);
+ return OFDM_cnt + CCK_cnt + HT_cnt;
+}
+
+u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter)
+{
+ u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
+
+ OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_FAIL_BIT);
+ CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_FAIL_BIT);
+ HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_FAIL_BIT);
+ return OFDM_cnt + CCK_cnt + HT_cnt;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_mp.h b/drivers/staging/rtl8712/rtl871x_mp.h
new file mode 100644
index 000000000000..805aba07159e
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mp.h
@@ -0,0 +1,318 @@
+#ifndef __RTL871X_MP_H_
+#define __RTL871X_MP_H_
+
+/* 00 - Success */
+/* 11 - Error */
+#define STATUS_SUCCESS (0x00000000L)
+#define STATUS_PENDING (0x00000103L)
+#define STATUS_UNSUCCESSFUL (0xC0000001L)
+#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL)
+#define STATUS_NOT_SUPPORTED (0xC00000BBL)
+#define NDIS_STATUS_SUCCESS ((uint)STATUS_SUCCESS)
+#define NDIS_STATUS_PENDING ((uint) STATUS_PENDING)
+#define NDIS_STATUS_NOT_RECOGNIZED ((uint)0x00010001L)
+#define NDIS_STATUS_NOT_COPIED ((uint)0x00010002L)
+#define NDIS_STATUS_NOT_ACCEPTED ((uint)0x00010003L)
+#define NDIS_STATUS_CALL_ACTIVE ((uint)0x00010007L)
+#define NDIS_STATUS_FAILURE ((uint) STATUS_UNSUCCESSFUL)
+#define NDIS_STATUS_RESOURCES ((uint)\
+ STATUS_INSUFFICIENT_RESOURCES)
+#define NDIS_STATUS_CLOSING ((uint)0xC0010002L)
+#define NDIS_STATUS_BAD_VERSION ((uint)0xC0010004L)
+#define NDIS_STATUS_BAD_CHARACTERISTICS ((uint)0xC0010005L)
+#define NDIS_STATUS_ADAPTER_NOT_FOUND ((uint)0xC0010006L)
+#define NDIS_STATUS_OPEN_FAILED ((uint)0xC0010007L)
+#define NDIS_STATUS_DEVICE_FAILED ((uint)0xC0010008L)
+#define NDIS_STATUS_MULTICAST_FULL ((uint)0xC0010009L)
+#define NDIS_STATUS_MULTICAST_EXISTS ((uint)0xC001000AL)
+#define NDIS_STATUS_MULTICAST_NOT_FOUND ((uint)0xC001000BL)
+#define NDIS_STATUS_REQUEST_ABORTED ((uint)0xC001000CL)
+#define NDIS_STATUS_RESET_IN_PROGRESS ((uint)0xC001000DL)
+#define NDIS_STATUS_CLOSING_INDICATING ((uint)0xC001000EL)
+#define NDIS_STATUS_NOT_SUPPORTED ((uint)STATUS_NOT_SUPPORTED)
+#define NDIS_STATUS_INVALID_PACKET ((uint)0xC001000FL)
+#define NDIS_STATUS_OPEN_LIST_FULL ((uint)0xC0010010L)
+#define NDIS_STATUS_ADAPTER_NOT_READY ((uint)0xC0010011L)
+#define NDIS_STATUS_ADAPTER_NOT_OPEN ((uint)0xC0010012L)
+#define NDIS_STATUS_NOT_INDICATING ((uint)0xC0010013L)
+#define NDIS_STATUS_INVALID_LENGTH ((uint)0xC0010014L)
+#define NDIS_STATUS_INVALID_DATA ((uint)0xC0010015L)
+#define NDIS_STATUS_BUFFER_TOO_SHORT ((uint)0xC0010016L)
+#define NDIS_STATUS_INVALID_OID ((uint)0xC0010017L)
+#define NDIS_STATUS_ADAPTER_REMOVED ((uint)0xC0010018L)
+#define NDIS_STATUS_UNSUPPORTED_MEDIA ((uint)0xC0010019L)
+#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((uint)0xC001001AL)
+#define NDIS_STATUS_FILE_NOT_FOUND ((uint)0xC001001BL)
+#define NDIS_STATUS_ERROR_READING_FILE ((uint)0xC001001CL)
+#define NDIS_STATUS_ALREADY_MAPPED ((uint)0xC001001DL)
+#define NDIS_STATUS_RESOURCE_CONFLICT ((uint)0xC001001EL)
+#define NDIS_STATUS_NO_CABLE ((uint)0xC001001FL)
+#define NDIS_STATUS_INVALID_SAP ((uint)0xC0010020L)
+#define NDIS_STATUS_SAP_IN_USE ((uint)0xC0010021L)
+#define NDIS_STATUS_INVALID_ADDRESS ((uint)0xC0010022L)
+#define NDIS_STATUS_VC_NOT_ACTIVATED ((uint)0xC0010023L)
+#define NDIS_STATUS_DEST_OUT_OF_ORDER ((uint)0xC0010024L) /* cause 27*/
+#define NDIS_STATUS_VC_NOT_AVAILABLE ((uint)0xC0010025L) /* 35,45*/
+#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((uint)0xC0010026L) /* 37*/
+#define NDIS_STATUS_INCOMPATABLE_QOS ((uint)0xC0010027L) /* 49*/
+#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((uint)0xC0010028L) /* 93*/
+#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((uint)0xC0010029L) /* 3*/
+#define MPT_NOOP 0
+#define MPT_READ_MAC_1BYTE 1
+#define MPT_READ_MAC_2BYTE 2
+#define MPT_READ_MAC_4BYTE 3
+#define MPT_WRITE_MAC_1BYTE 4
+#define MPT_WRITE_MAC_2BYTE 5
+#define MPT_WRITE_MAC_4BYTE 6
+#define MPT_READ_BB_CCK 7
+#define MPT_WRITE_BB_CCK 8
+#define MPT_READ_BB_OFDM 9
+#define MPT_WRITE_BB_OFDM 10
+#define MPT_READ_RF 11
+#define MPT_WRITE_RF 12
+#define MPT_READ_EEPROM_1BYTE 13
+#define MPT_WRITE_EEPROM_1BYTE 14
+#define MPT_READ_EEPROM_2BYTE 15
+#define MPT_WRITE_EEPROM_2BYTE 16
+#define MPT_SET_CSTHRESHOLD 21
+#define MPT_SET_INITGAIN 22
+#define MPT_SWITCH_BAND 23
+#define MPT_SWITCH_CHANNEL 24
+#define MPT_SET_DATARATE 25
+#define MPT_SWITCH_ANTENNA 26
+#define MPT_SET_TX_POWER 27
+#define MPT_SET_CONT_TX 28
+#define MPT_SET_SINGLE_CARRIER 29
+#define MPT_SET_CARRIER_SUPPRESSION 30
+#define MPT_GET_RATE_TABLE 31
+#define MPT_READ_TSSI 32
+#define MPT_GET_THERMAL_METER 33
+#define MAX_MP_XMITBUF_SZ 2048
+#define NR_MP_XMITFRAME 8
+
+struct mp_xmit_frame {
+ struct list_head list;
+ struct pkt_attrib attrib;
+ _pkt *pkt;
+ int frame_tag;
+ struct _adapter *padapter;
+ u8 *mem_addr;
+ u16 sz[8];
+ struct urb *pxmit_urb[8];
+ u8 bpending[8];
+ u8 last[8];
+ uint mem[(MAX_MP_XMITBUF_SZ >> 2)];
+};
+
+struct mp_wiparam {
+ u32 bcompleted;
+ u32 act_type;
+ u32 io_offset;
+ u32 io_value;
+};
+
+struct mp_priv {
+ struct _adapter *papdater;
+ /*OID cmd handler*/
+ struct mp_wiparam workparam;
+ u8 act_in_progress;
+ /*Tx Section*/
+ u8 TID;
+ u32 tx_pktcount;
+ /*Rx Section*/
+ u32 rx_pktcount;
+ u32 rx_crcerrpktcount;
+ u32 rx_pktloss;
+ struct recv_stat rxstat;
+ /*RF/BB relative*/
+ u32 curr_ch;
+ u32 curr_rateidx;
+ u8 curr_bandwidth;
+ u8 curr_modem;
+ u8 curr_txpoweridx;
+ u32 curr_crystalcap;
+ u16 antenna_tx;
+ u16 antenna_rx;
+ u8 curr_rfpath;
+ u8 check_mp_pkt;
+ uint ForcedDataRate;
+ struct wlan_network mp_network;
+ unsigned char network_macaddr[6];
+ /*Testing Flag*/
+ u32 mode;/*0 for normal type packet,
+ * 1 for loopback packet (16bytes TXCMD)*/
+ sint prev_fw_state;
+ u8 *pallocated_mp_xmitframe_buf;
+ u8 *pmp_xmtframe_buf;
+ struct __queue free_mp_xmitqueue;
+ u32 free_mp_xmitframe_cnt;
+};
+
+struct IOCMD_STRUCT {
+ u8 cmdclass;
+ u16 value;
+ u8 index;
+};
+
+struct rf_reg_param {
+ u32 path;
+ u32 offset;
+ u32 value;
+};
+
+struct bb_reg_param {
+ u32 offset;
+ u32 value;
+};
+/* ======================================================================= */
+
+#define LOWER true
+#define RAISE false
+#define IOCMD_CTRL_REG 0x10250370
+#define IOCMD_DATA_REG 0x10250374
+#define IOCMD_GET_THERMAL_METER 0xFD000028
+#define IOCMD_CLASS_BB_RF 0xF0
+#define IOCMD_BB_READ_IDX 0x00
+#define IOCMD_BB_WRITE_IDX 0x01
+#define IOCMD_RF_READ_IDX 0x02
+#define IOCMD_RF_WRIT_IDX 0x03
+#define BB_REG_BASE_ADDR 0x800
+#define RF_PATH_A 0
+#define RF_PATH_B 1
+#define RF_PATH_C 2
+#define RF_PATH_D 3
+#define MAX_RF_PATH_NUMS 2
+#define _2MAC_MODE_ 0
+#define _LOOPBOOK_MODE_ 1
+
+/* MP set force data rate base on the definition. */
+enum {
+ /* CCK rate. */
+ MPT_RATE_1M, /* 0 */
+ MPT_RATE_2M,
+ MPT_RATE_55M,
+ MPT_RATE_11M, /* 3 */
+
+ /* OFDM rate. */
+ MPT_RATE_6M, /* 4 */
+ MPT_RATE_9M,
+ MPT_RATE_12M,
+ MPT_RATE_18M,
+ MPT_RATE_24M,
+ MPT_RATE_36M,
+ MPT_RATE_48M,
+ MPT_RATE_54M, /* 11 */
+
+ /* HT rate. */
+ MPT_RATE_MCS0, /* 12 */
+ MPT_RATE_MCS1,
+ MPT_RATE_MCS2,
+ MPT_RATE_MCS3,
+ MPT_RATE_MCS4,
+ MPT_RATE_MCS5,
+ MPT_RATE_MCS6,
+ MPT_RATE_MCS7, /* 19 */
+ MPT_RATE_MCS8,
+ MPT_RATE_MCS9,
+ MPT_RATE_MCS10,
+ MPT_RATE_MCS11,
+ MPT_RATE_MCS12,
+ MPT_RATE_MCS13,
+ MPT_RATE_MCS14,
+ MPT_RATE_MCS15, /* 27 */
+ MPT_RATE_LAST
+};
+
+/* Represent Channel Width in HT Capabilities */
+enum HT_CHANNEL_WIDTH {
+ HT_CHANNEL_WIDTH_20 = 0,
+ HT_CHANNEL_WIDTH_40 = 1,
+};
+
+#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */
+
+enum POWER_MODE {
+ POWER_LOW = 0,
+ POWER_NORMAL
+};
+
+#define RX_PKT_BROADCAST 1
+#define RX_PKT_DEST_ADDR 2
+#define RX_PKT_PHY_MATCH 3
+
+#define RPTMaxCount 0x000FFFFF;
+
+/* parameter 1 : BitMask
+ * bit 0 : OFDM PPDU
+ * bit 1 : OFDM False Alarm
+ * bit 2 : OFDM MPDU OK
+ * bit 3 : OFDM MPDU Fail
+ * bit 4 : CCK PPDU
+ * bit 5 : CCK False Alarm
+ * bit 6 : CCK MPDU ok
+ * bit 7 : CCK MPDU fail
+ * bit 8 : HT PPDU counter
+ * bit 9 : HT false alarm
+ * bit 10 : HT MPDU total
+ * bit 11 : HT MPDU OK
+ * bit 12 : HT MPDU fail
+ * bit 15 : RX full drop
+ */
+enum RXPHY_BITMASK {
+ OFDM_PPDU_BIT = 0,
+ OFDM_MPDU_OK_BIT,
+ OFDM_MPDU_FAIL_BIT,
+ CCK_PPDU_BIT,
+ CCK_MPDU_OK_BIT,
+ CCK_MPDU_FAIL_BIT,
+ HT_PPDU_BIT,
+ HT_MPDU_BIT,
+ HT_MPDU_OK_BIT,
+ HT_MPDU_FAIL_BIT,
+};
+
+enum ENCRY_CTRL_STATE {
+ HW_CONTROL, /*hw encryption& decryption*/
+ SW_CONTROL, /*sw encryption& decryption*/
+ HW_ENCRY_SW_DECRY, /*hw encryption & sw decryption*/
+ SW_ENCRY_HW_DECRY /*sw encryption & hw decryption*/
+};
+
+/* Bandwidth Offset */
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
+#define HAL_PRIME_CHNL_OFFSET_LOWER 1
+#define HAL_PRIME_CHNL_OFFSET_UPPER 2
+/*=======================================================================*/
+void mp871xinit(struct _adapter *padapter);
+void mp871xdeinit(struct _adapter *padapter);
+u32 r8712_bb_reg_read(struct _adapter *Adapter, u16 offset);
+u8 r8712_bb_reg_write(struct _adapter *Adapter, u16 offset, u32 value);
+u32 r8712_rf_reg_read(struct _adapter *Adapter, u8 path, u8 offset);
+u8 r8712_rf_reg_write(struct _adapter *Adapter, u8 path,
+ u8 offset, u32 value);
+u32 r8712_get_bb_reg(struct _adapter *Adapter, u16 offset, u32 bitmask);
+u8 r8712_set_bb_reg(struct _adapter *Adapter, u16 offset,
+ u32 bitmask, u32 value);
+u32 r8712_get_rf_reg(struct _adapter *Adapter, u8 path, u8 offset,
+ u32 bitmask);
+u8 r8712_set_rf_reg(struct _adapter *Adapter, u8 path, u8 offset,
+ u32 bitmask, u32 value);
+
+void r8712_SetChannel(struct _adapter *pAdapter);
+void r8712_SetTxPower(struct _adapter *pAdapte);
+void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset);
+void r8712_SetDataRate(struct _adapter *pAdapter);
+void r8712_SwitchBandwidth(struct _adapter *pAdapter);
+void r8712_SwitchAntenna(struct _adapter *pAdapter);
+void r8712_SetCrystalCap(struct _adapter *pAdapter);
+void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value);
+void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart);
+void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart);
+void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart);
+void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart);
+void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter);
+u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter);
+u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter);
+
+#endif /*__RTL871X_MP_H_*/
+
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
new file mode 100644
index 000000000000..d60aaa9c4872
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
@@ -0,0 +1,1475 @@
+/******************************************************************************
+ * rtl871x_mp_ioctl.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_MP_IOCTL_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "mlme_osdep.h"
+#include "rtl871x_mp.h"
+#include "rtl871x_mp_ioctl.h"
+
+uint oid_null_function(struct oid_par_priv *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid == SET_OID) {
+ if (poid_par_priv->information_buf_len >= sizeof(u8))
+ Adapter->registrypriv.wireless_mode =
+ *(u8 *)poid_par_priv->information_buf;
+ else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ } else if (poid_par_priv->type_of_oid == QUERY_OID) {
+ if (poid_par_priv->information_buf_len >= sizeof(u8)) {
+ *(u8 *)poid_par_priv->information_buf =
+ Adapter->registrypriv.wireless_mode;
+ *poid_par_priv->bytes_rw =
+ poid_par_priv->information_buf_len;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ } else {
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ }
+ return status;
+}
+
+uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct bb_reg_param *pbbreg;
+ u16 offset;
+ u32 value;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
+ return NDIS_STATUS_INVALID_LENGTH;
+ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
+ offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
+ if (offset < BB_REG_BASE_ADDR)
+ offset |= BB_REG_BASE_ADDR;
+ value = pbbreg->value;
+ r8712_bb_reg_write(Adapter, offset, value);
+ return status;
+}
+
+uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct bb_reg_param *pbbreg;
+ u16 offset;
+ u32 value;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
+ return NDIS_STATUS_INVALID_LENGTH;
+ pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
+ offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/
+ if (offset < BB_REG_BASE_ADDR)
+ offset |= BB_REG_BASE_ADDR;
+ value = r8712_bb_reg_read(Adapter, offset);
+ pbbreg->value = value;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct rf_reg_param *pbbreg;
+ u8 path;
+ u8 offset;
+ u32 value;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
+ return NDIS_STATUS_INVALID_LENGTH;
+ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
+ path = (u8)pbbreg->path;
+ if (path > RF_PATH_B)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ offset = (u8)pbbreg->offset;
+ value = pbbreg->value;
+ r8712_rf_reg_write(Adapter, path, offset, value);
+ return status;
+}
+
+uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct rf_reg_param *pbbreg;
+ u8 path;
+ u8 offset;
+ u32 value;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
+ return NDIS_STATUS_INVALID_LENGTH;
+ pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
+ path = (u8)pbbreg->path;
+ if (path > RF_PATH_B) /* 1T2R path_a /path_b */
+ return NDIS_STATUS_NOT_ACCEPTED;
+ offset = (u8)pbbreg->offset;
+ value = r8712_rf_reg_read(Adapter, path, offset);
+ pbbreg->value = value;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+/*This function initializes the DUT to the MP test mode*/
+static int mp_start_test(struct _adapter *padapter)
+{
+ struct mp_priv *pmppriv = &padapter->mppriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+ struct ndis_wlan_bssid_ex bssid;
+ struct sta_info *psta;
+ unsigned long length;
+ unsigned long irqL;
+ int res = _SUCCESS;
+
+ /* 3 1. initialize a new struct ndis_wlan_bssid_ex */
+ memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
+ bssid.Ssid.SsidLength = 16;
+ memcpy(bssid.Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc",
+ bssid.Ssid.SsidLength);
+ bssid.InfrastructureMode = Ndis802_11IBSS;
+ bssid.NetworkTypeInUse = Ndis802_11DS;
+ bssid.IELength = 0;
+ length = r8712_get_ndis_wlan_bssid_ex_sz(&bssid);
+ if (length % 4) {
+ /*round up to multiple of 4 bytes.*/
+ bssid.Length = ((length >> 2) + 1) << 2;
+ } else
+ bssid.Length = length;
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
+ goto end_of_mp_start_test;
+ /*init mp_start_test status*/
+ pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
+ pmlmepriv->fw_state = WIFI_MP_STATE;
+ if (pmppriv->mode == _LOOPBOOK_MODE_)
+ set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+ /* 3 2. create a new psta for mp driver */
+ /* clear psta in the cur_network, if any */
+ psta = r8712_get_stainfo(&padapter->stapriv,
+ tgt_network->network.MacAddress);
+ if (psta)
+ r8712_free_stainfo(padapter, psta);
+ psta = r8712_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
+ if (psta == NULL) {
+ res = _FAIL;
+ goto end_of_mp_start_test;
+ }
+ /* 3 3. join psudo AdHoc */
+ tgt_network->join_res = 1;
+ tgt_network->aid = psta->aid = 1;
+ memcpy(&tgt_network->network, &bssid, length);
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+ r8712_os_indicate_connect(padapter);
+ /* Set to LINKED STATE for MP TRX Testing */
+ set_fwstate(pmlmepriv, _FW_LINKED);
+end_of_mp_start_test:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return res;
+}
+
+/*This function change the DUT from the MP test mode into normal mode */
+static int mp_stop_test(struct _adapter *padapter)
+{
+ struct mp_priv *pmppriv = &padapter->mppriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+ struct sta_info *psta;
+ unsigned long irqL;
+
+ spin_lock_irqsave(&pmlmepriv->lock, irqL);
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
+ goto end_of_mp_stop_test;
+ /* 3 1. disconnect psudo AdHoc */
+ r8712_os_indicate_disconnect(padapter);
+ /* 3 2. clear psta used in mp test mode. */
+ psta = r8712_get_stainfo(&padapter->stapriv,
+ tgt_network->network.MacAddress);
+ if (psta)
+ r8712_free_stainfo(padapter, psta);
+ /* 3 3. return to normal state (default:station mode) */
+ pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/
+ /*flush the cur_network*/
+ memset(tgt_network, 0, sizeof(struct wlan_network));
+end_of_mp_stop_test:
+ spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
+ return _SUCCESS;
+}
+
+int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid)
+{
+ struct mp_priv *pmppriv = &padapter->mppriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ unsigned char res = _SUCCESS;
+
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
+ return _FAIL;
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == false)
+ return _FAIL;
+ _clr_fwstate_(pmlmepriv, _FW_LINKED);
+ res = r8712_setassocsta_cmd(padapter, pmppriv->network_macaddr);
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+ return res;
+}
+
+uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 ratevalue;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ ratevalue = *((u32 *)poid_par_priv->information_buf);
+ if (ratevalue >= MPT_RATE_LAST)
+ return NDIS_STATUS_INVALID_DATA;
+ Adapter->mppriv.curr_rateidx = ratevalue;
+ r8712_SetDataRate(Adapter);
+ return status;
+}
+
+uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 mode;
+ u8 val8;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ mode = *((u32 *)poid_par_priv->information_buf);
+ Adapter->mppriv.mode = mode;/* 1 for loopback*/
+ if (mp_start_test(Adapter) == _FAIL)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */
+ r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */
+ /* RCR disable Check BSSID, 0x1025004a */
+ r8712_write8(Adapter, RCR+2, 0x57);
+ /* disable RX filter map , mgt frames will put in RX FIFO 0 */
+ r8712_write16(Adapter, RXFLTMAP0, 0x0);
+ val8 = r8712_read8(Adapter, EE_9346CR);
+ if (!(val8 & _9356SEL)) { /*boot from EFUSE*/
+ r8712_efuse_reg_init(Adapter);
+ r8712_efuse_change_max_size(Adapter);
+ r8712_efuse_reg_uninit(Adapter);
+ }
+ return status;
+}
+
+uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (mp_stop_test(Adapter) == _FAIL)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+
+uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 Channel;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ Channel = *((u32 *)poid_par_priv->information_buf);
+ if (Channel > 14)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ Adapter->mppriv.curr_ch = Channel;
+ r8712_SetChannel(Adapter);
+ return status;
+}
+
+uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 antenna;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ antenna = *((u32 *)poid_par_priv->information_buf);
+ Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16);
+ Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF);
+ r8712_SwitchAntenna(Adapter);
+ return status;
+}
+
+uint oid_rt_pro_set_tx_power_control_hdl(
+ struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 tx_pwr_idx;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ tx_pwr_idx = *((u32 *)poid_par_priv->information_buf);
+ if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx;
+ r8712_SetTxPower(Adapter);
+ return status;
+}
+
+uint oid_rt_pro_query_tx_packet_sent_hdl(
+ struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID) {
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+ }
+ if (poid_par_priv->information_buf_len == sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ Adapter->mppriv.tx_pktcount;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+uint oid_rt_pro_query_rx_packet_received_hdl(
+ struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID) {
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+ }
+ if (poid_par_priv->information_buf_len == sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ Adapter->mppriv.rx_pktcount;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+uint oid_rt_pro_query_rx_packet_crc32_error_hdl(
+ struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID) {
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+ }
+ if (poid_par_priv->information_buf_len == sizeof(u32)) {
+ *(u32 *)poid_par_priv->information_buf =
+ Adapter->mppriv.rx_crcerrpktcount;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ Adapter->mppriv.tx_pktcount = 0;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len == sizeof(u32)) {
+ Adapter->mppriv.rx_pktcount = 0;
+ Adapter->mppriv.rx_crcerrpktcount = 0;
+ } else
+ status = NDIS_STATUS_INVALID_LENGTH;
+ return status;
+}
+
+uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ r8712_ResetPhyRxPktCount(Adapter);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ *(u32 *)poid_par_priv->information_buf =
+ r8712_GetPhyRxPktReceived(Adapter);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len != sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ *(u32 *)poid_par_priv->information_buf =
+ r8712_GetPhyRxPktCRC32Error(Adapter);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 bStartTest;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ bStartTest = *((u32 *)poid_par_priv->information_buf);
+ r8712_SetContinuousTx(Adapter, (u8)bStartTest);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 bStartTest;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ bStartTest = *((u32 *)poid_par_priv->information_buf);
+ r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 bStartTest;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ bStartTest = *((u32 *)poid_par_priv->information_buf);
+ r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 bStartTest;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ bStartTest = *((u32 *)poid_par_priv->information_buf);
+ r8712_SetSingleToneTx(Adapter, (u8)bStartTest);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct ndis_802_11_ssid *pssid;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_needed = (u32)sizeof(struct ndis_802_11_ssid);
+ *poid_par_priv->bytes_rw = 0;
+ if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
+ return NDIS_STATUS_INVALID_LENGTH;
+ pssid = (struct ndis_802_11_ssid *)poid_par_priv->information_buf;
+ if (mp_start_joinbss(Adapter, pssid) == _FAIL)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_rw = sizeof(struct ndis_802_11_ssid);
+ return status;
+}
+
+uint oid_rt_pro_read_register_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct mp_rw_reg *RegRWStruct;
+ u16 offset;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
+ if ((RegRWStruct->offset >= 0x10250800) &&
+ (RegRWStruct->offset <= 0x10250FFF)) {
+ /*baseband register*/
+ /*0ffset :0x800~0xfff*/
+ offset = (u16)(RegRWStruct->offset) & 0xFFF;
+ RegRWStruct->value = r8712_bb_reg_read(Adapter, offset);
+ } else {
+ switch (RegRWStruct->width) {
+ case 1:
+ RegRWStruct->value = r8712_read8(Adapter,
+ RegRWStruct->offset);
+ break;
+ case 2:
+ RegRWStruct->value = r8712_read16(Adapter,
+ RegRWStruct->offset);
+ break;
+ case 4:
+ RegRWStruct->value = r8712_read32(Adapter,
+ RegRWStruct->offset);
+ break;
+ default:
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ break;
+ }
+ }
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct mp_rw_reg *RegRWStruct;
+ u16 offset;
+ u32 value;
+ u32 oldValue = 0;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
+ if ((RegRWStruct->offset >= 0x10250800) &&
+ (RegRWStruct->offset <= 0x10250FFF)) {
+ /*baseband register*/
+ offset = (u16)(RegRWStruct->offset) & 0xFFF;
+ value = RegRWStruct->value;
+ switch (RegRWStruct->width) {
+ case 1:
+ oldValue = r8712_bb_reg_read(Adapter, offset);
+ oldValue &= 0xFFFFFF00;
+ value &= 0x000000FF;
+ value |= oldValue;
+ break;
+ case 2:
+ oldValue = r8712_bb_reg_read(Adapter, offset);
+ oldValue &= 0xFFFF0000;
+ value &= 0x0000FFFF;
+ value |= oldValue;
+ break;
+ }
+ r8712_bb_reg_write(Adapter, offset, value);
+ } else {
+ switch (RegRWStruct->width) {
+ case 1:
+ r8712_write8(Adapter, RegRWStruct->offset,
+ (unsigned char)RegRWStruct->value);
+ break;
+ case 2:
+ r8712_write16(Adapter, RegRWStruct->offset,
+ (unsigned short)RegRWStruct->value);
+ break;
+ case 4:
+ r8712_write32(Adapter, RegRWStruct->offset,
+ (unsigned int)RegRWStruct->value);
+ break;
+ default:
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ break;
+ }
+
+ if ((status == NDIS_STATUS_SUCCESS) &&
+ (RegRWStruct->offset == HIMR) &&
+ (RegRWStruct->width == 4))
+ Adapter->ImrContent = RegRWStruct->value;
+ }
+ return status;
+}
+
+uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct burst_rw_reg *pBstRwReg;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
+ r8712_read_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
+ pBstRwReg->Data);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct burst_rw_reg *pBstRwReg;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
+ r8712_write_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
+ pBstRwReg->Data);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct eeprom_rw_param *pEEPROM;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
+ pEEPROM->value = r8712_eeprom_read16(Adapter,
+ (u16)(pEEPROM->offset >> 1));
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct eeprom_rw_param *pEEPROM;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
+ r8712_eeprom_write16(Adapter, (u16)(pEEPROM->offset >> 1),
+ pEEPROM->value);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct mp_wiparam *pwi_param;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam))
+ return NDIS_STATUS_INVALID_LENGTH;
+ if (Adapter->mppriv.workparam.bcompleted == false)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf;
+ memcpy(pwi_param, &Adapter->mppriv.workparam,
+ sizeof(struct mp_wiparam));
+ Adapter->mppriv.act_in_progress = false;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(uint) * 2)
+ return NDIS_STATUS_INVALID_LENGTH;
+ if (*(uint *)poid_par_priv->information_buf == 1)
+ Adapter->mppriv.rx_pktloss = 0;
+ *((uint *)poid_par_priv->information_buf+1) =
+ Adapter->mppriv.rx_pktloss;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (r8712_setrfintfs_cmd(Adapter, *(unsigned char *)
+ poid_par_priv->information_buf) == _FAIL)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+
+uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ memcpy(poid_par_priv->information_buf,
+ (unsigned char *)&Adapter->mppriv.rxstat,
+ sizeof(struct recv_stat));
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+uint oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (r8712_setdatarate_cmd(Adapter,
+ poid_par_priv->information_buf) != _SUCCESS)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+
+uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ if (Adapter->mppriv.act_in_progress == true)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ if (poid_par_priv->information_buf_len < sizeof(u8))
+ return NDIS_STATUS_INVALID_LENGTH;
+ /*init workparam*/
+ Adapter->mppriv.act_in_progress = true;
+ Adapter->mppriv.workparam.bcompleted = false;
+ Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER;
+ Adapter->mppriv.workparam.io_offset = 0;
+ Adapter->mppriv.workparam.io_value = 0xFFFFFFFF;
+ r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value);
+ Adapter->mppriv.workparam.bcompleted = true;
+ Adapter->mppriv.act_in_progress = false;
+ *(u32 *)poid_par_priv->information_buf =
+ Adapter->mppriv.workparam.io_value;
+ *poid_par_priv->bytes_rw = sizeof(u32);
+ return status;
+}
+
+uint oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u8))
+ return NDIS_STATUS_INVALID_LENGTH;
+ if (!r8712_setptm_cmd(Adapter, *((u8 *)poid_par_priv->information_buf)))
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+
+uint oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 ratevalue;
+ u8 datarates[NumRates];
+ int i;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ ratevalue = *((u32 *)poid_par_priv->information_buf);
+ for (i = 0; i < NumRates; i++) {
+ if (ratevalue == mpdatarate[i])
+ datarates[i] = mpdatarate[i];
+ else
+ datarates[i] = 0xff;
+ }
+ if (r8712_setbasicrate_cmd(Adapter, datarates) != _SUCCESS)
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+
+uint oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < 8)
+ return NDIS_STATUS_INVALID_LENGTH;
+ *poid_par_priv->bytes_rw = 8;
+ memcpy(poid_par_priv->information_buf,
+ &(Adapter->pwrctrlpriv.pwr_mode), 8);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint pwr_mode, smart_ps;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_rw = 0;
+ *poid_par_priv->bytes_needed = 8;
+ if (poid_par_priv->information_buf_len < 8)
+ return NDIS_STATUS_INVALID_LENGTH;
+ pwr_mode = *(uint *)(poid_par_priv->information_buf);
+ smart_ps = *(uint *)((addr_t)poid_par_priv->information_buf + 4);
+ if (pwr_mode != Adapter->pwrctrlpriv.pwr_mode || smart_ps !=
+ Adapter->pwrctrlpriv.smart_ps)
+ r8712_set_ps_mode(Adapter, pwr_mode, smart_ps);
+ *poid_par_priv->bytes_rw = 8;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct setratable_parm *prate_table;
+ u8 res;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_needed = sizeof(struct setratable_parm);
+ if (poid_par_priv->information_buf_len <
+ sizeof(struct setratable_parm))
+ return NDIS_STATUS_INVALID_LENGTH;
+ prate_table = (struct setratable_parm *)poid_par_priv->information_buf;
+ res = r8712_setrttbl_cmd(Adapter, prate_table);
+ if (res == _FAIL)
+ status = NDIS_STATUS_FAILURE;
+ return status;
+}
+
+uint oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ struct security_priv *psecuritypriv = &Adapter->securitypriv;
+ enum ENCRY_CTRL_STATE encry_mode = 0;
+
+ *poid_par_priv->bytes_needed = sizeof(u8);
+ if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
+ return NDIS_STATUS_INVALID_LENGTH;
+
+ if (poid_par_priv->type_of_oid == SET_OID) {
+ encry_mode = *((u8 *)poid_par_priv->information_buf);
+ switch (encry_mode) {
+ case HW_CONTROL:
+ psecuritypriv->sw_decrypt = false;
+ psecuritypriv->sw_encrypt = false;
+ break;
+ case SW_CONTROL:
+ psecuritypriv->sw_decrypt = true;
+ psecuritypriv->sw_encrypt = true;
+ break;
+ case HW_ENCRY_SW_DECRY:
+ psecuritypriv->sw_decrypt = true;
+ psecuritypriv->sw_encrypt = false;
+ break;
+ case SW_ENCRY_HW_DECRY:
+ psecuritypriv->sw_decrypt = false;
+ psecuritypriv->sw_encrypt = true;
+ break;
+ }
+ } else {
+ if ((psecuritypriv->sw_encrypt == false) &&
+ (psecuritypriv->sw_decrypt == false))
+ encry_mode = HW_CONTROL;
+ else if ((psecuritypriv->sw_encrypt == false) &&
+ (psecuritypriv->sw_decrypt == true))
+ encry_mode = HW_ENCRY_SW_DECRY;
+ else if ((psecuritypriv->sw_encrypt == true) &&
+ (psecuritypriv->sw_decrypt == false))
+ encry_mode = SW_ENCRY_HW_DECRY;
+ else if ((psecuritypriv->sw_encrypt == true) &&
+ (psecuritypriv->sw_decrypt == true))
+ encry_mode = SW_CONTROL;
+ *(u8 *)poid_par_priv->information_buf = encry_mode;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ }
+ return NDIS_STATUS_SUCCESS;
+}
+/*----------------------------------------------------------------------*/
+uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ uint status = NDIS_STATUS_SUCCESS;
+
+ struct sta_info *psta = NULL;
+ u8 *macaddr;
+
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ *poid_par_priv->bytes_needed = ETH_ALEN;
+ if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
+ return NDIS_STATUS_INVALID_LENGTH;
+ macaddr = (u8 *) poid_par_priv->information_buf;
+ psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
+ if (psta == NULL) { /* the sta in sta_info_queue => do nothing*/
+ psta = r8712_alloc_stainfo(&Adapter->stapriv, macaddr);
+ if (psta == NULL)
+ status = NDIS_STATUS_FAILURE;
+ }
+ return status;
+}
+/*-------------------------------------------------------------------------*/
+uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ unsigned long irqL;
+ uint status = NDIS_STATUS_SUCCESS;
+
+ struct sta_info *psta = NULL;
+ u8 *macaddr;
+
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ *poid_par_priv->bytes_needed = ETH_ALEN;
+ if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
+ return NDIS_STATUS_INVALID_LENGTH;
+
+ macaddr = (u8 *)poid_par_priv->information_buf;
+
+ psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
+ if (psta != NULL) {
+ spin_lock_irqsave(&(Adapter->stapriv.sta_hash_lock), irqL);
+ r8712_free_stainfo(Adapter, psta);
+ spin_unlock_irqrestore(&(Adapter->stapriv.sta_hash_lock), irqL);
+ }
+
+ return status;
+}
+/*--------------------------------------------------------------------------*/
+static u32 mp_query_drv_var(struct _adapter *padapter, u8 offset, u32 var)
+{
+ return var;
+}
+
+uint oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ uint status = NDIS_STATUS_SUCCESS;
+
+ struct DR_VARIABLE_STRUCT *pdrv_var;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ *poid_par_priv->bytes_needed = sizeof(struct DR_VARIABLE_STRUCT);
+ if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
+ return NDIS_STATUS_INVALID_LENGTH;
+ pdrv_var = (struct DR_VARIABLE_STRUCT *)poid_par_priv->information_buf;
+ pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset,
+ pdrv_var->variable);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+/*--------------------------------------------------------------------------*/
+uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+/*------------------------------------------------------------------------*/
+uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ uint status = NDIS_STATUS_SUCCESS;
+
+ struct EFUSE_ACCESS_STRUCT *pefuse;
+ u8 *data;
+ u16 addr = 0, cnts = 0;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len <
+ sizeof(struct EFUSE_ACCESS_STRUCT))
+ return NDIS_STATUS_INVALID_LENGTH;
+ pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
+ addr = pefuse->start_addr;
+ cnts = pefuse->cnts;
+ data = pefuse->data;
+ memset(data, 0xFF, cnts);
+ if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) >
+ EFUSE_MAX_SIZE)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (r8712_efuse_access(Adapter, true, addr, cnts, data) == false)
+ status = NDIS_STATUS_FAILURE;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+/*------------------------------------------------------------------------*/
+uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ uint status = NDIS_STATUS_SUCCESS;
+
+ struct EFUSE_ACCESS_STRUCT *pefuse;
+ u8 *data;
+ u16 addr = 0, cnts = 0;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf;
+ addr = pefuse->start_addr;
+ cnts = pefuse->cnts;
+ data = pefuse->data;
+
+ if ((addr > 511) || (cnts < 1) || (cnts > 512) ||
+ (addr + cnts) > r8712_efuse_get_max_size(Adapter))
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (r8712_efuse_access(Adapter, false, addr, cnts, data) == false)
+ status = NDIS_STATUS_FAILURE;
+ return status;
+}
+/*----------------------------------------------------------------------*/
+uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct PGPKT_STRUCT *ppgpkt;
+
+ *poid_par_priv->bytes_rw = 0;
+ if (poid_par_priv->information_buf_len < sizeof(struct PGPKT_STRUCT))
+ return NDIS_STATUS_INVALID_LENGTH;
+ ppgpkt = (struct PGPKT_STRUCT *)poid_par_priv->information_buf;
+ if (poid_par_priv->type_of_oid == QUERY_OID) {
+ if (r8712_efuse_pg_packet_read(Adapter, ppgpkt->offset,
+ ppgpkt->data) == true)
+ *poid_par_priv->bytes_rw =
+ poid_par_priv->information_buf_len;
+ else
+ status = NDIS_STATUS_FAILURE;
+ } else {
+ if (r8712_efuse_reg_init(Adapter) == true) {
+ if (r8712_efuse_pg_packet_write(Adapter, ppgpkt->offset,
+ ppgpkt->word_en, ppgpkt->data) == true)
+ *poid_par_priv->bytes_rw =
+ poid_par_priv->information_buf_len;
+ else
+ status = NDIS_STATUS_FAILURE;
+ r8712_efuse_reg_uninit(Adapter);
+ } else
+ status = NDIS_STATUS_FAILURE;
+ }
+ return status;
+}
+
+uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(int))
+ return NDIS_STATUS_INVALID_LENGTH;
+ r8712_efuse_reg_init(Adapter);
+ *(int *)poid_par_priv->information_buf =
+ r8712_efuse_get_current_size(Adapter);
+ r8712_efuse_reg_uninit(Adapter);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ *(int *)poid_par_priv->information_buf =
+ r8712_efuse_get_max_size(Adapter);
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return status;
+}
+
+uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv)
+{
+ uint status = NDIS_STATUS_SUCCESS;
+
+ if (poid_par_priv->type_of_oid == QUERY_OID)
+ status = oid_rt_pro_read_efuse_hdl(poid_par_priv);
+ else
+ status = oid_rt_pro_write_efuse_hdl(poid_par_priv);
+ return status;
+}
+
+uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u8 *data;
+
+ *poid_par_priv->bytes_rw = 0;
+ if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE)
+ return NDIS_STATUS_INVALID_LENGTH;
+ data = (u8 *)poid_par_priv->information_buf;
+ if (poid_par_priv->type_of_oid == QUERY_OID) {
+ if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data))
+ *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
+ else
+ status = NDIS_STATUS_FAILURE;
+ } else {
+ /* SET_OID */
+ if (r8712_efuse_reg_init(Adapter) == true) {
+ if (r8712_efuse_map_write(Adapter, 0,
+ EFUSE_MAP_MAX_SIZE, data))
+ *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE;
+ else
+ status = NDIS_STATUS_FAILURE;
+ r8712_efuse_reg_uninit(Adapter);
+ } else {
+ status = NDIS_STATUS_FAILURE;
+ }
+ }
+ return status;
+}
+
+uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 bandwidth;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/
+ if (bandwidth != HT_CHANNEL_WIDTH_20)
+ bandwidth = HT_CHANNEL_WIDTH_40;
+ Adapter->mppriv.curr_bandwidth = (u8)bandwidth;
+ r8712_SwitchBandwidth(Adapter);
+ return status;
+}
+
+uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ u32 crystal_cap = 0;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ crystal_cap = *((u32 *)poid_par_priv->information_buf);/*4*/
+ if (crystal_cap > 0xf)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ Adapter->mppriv.curr_crystalcap = crystal_cap;
+ r8712_SetCrystalCap(Adapter);
+ return status;
+}
+
+uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u8 rx_pkt_type;
+ u32 rcr_val32;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u8))
+ return NDIS_STATUS_INVALID_LENGTH;
+ rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/
+ rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/
+ rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP);
+ switch (rx_pkt_type) {
+ case RX_PKT_BROADCAST:
+ rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
+ break;
+ case RX_PKT_DEST_ADDR:
+ rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32);
+ break;
+ case RX_PKT_PHY_MATCH:
+ rcr_val32 |= (RCR_APM|RCR_ACRC32);
+ break;
+ default:
+ rcr_val32 &= ~(RCR_AAP |
+ RCR_APM |
+ RCR_AM |
+ RCR_AB |
+ RCR_ACRC32);
+ break;
+ }
+ if (rx_pkt_type == RX_PKT_DEST_ADDR)
+ Adapter->mppriv.check_mp_pkt = 1;
+ else
+ Adapter->mppriv.check_mp_pkt = 0;
+ r8712_write32(Adapter, RCR, rcr_val32);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ u32 txagc;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ txagc = *(u32 *)poid_par_priv->information_buf;
+ r8712_SetTxAGCOffset(Adapter, txagc);
+ return NDIS_STATUS_SUCCESS;
+}
+
+uint oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv
+ *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+ uint status = NDIS_STATUS_SUCCESS;
+ struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
+ struct mp_priv *pmppriv = &Adapter->mppriv;
+ u32 type;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+
+ type = *(u32 *)poid_par_priv->information_buf;
+
+ if (_LOOPBOOK_MODE_ == type) {
+ pmppriv->mode = type;
+ set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
+ } else if (_2MAC_MODE_ == type) {
+ pmppriv->mode = type;
+ _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE);
+ } else
+ status = NDIS_STATUS_NOT_ACCEPTED;
+ return status;
+}
+/*--------------------------------------------------------------------------*/
+/*Linux*/
+unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
+{
+ return _SUCCESS;
+}
+/*-------------------------------------------------------------------------*/
+uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv)
+{
+ u8 bpwrup;
+
+ if (poid_par_priv->type_of_oid != SET_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ bpwrup = *(u8 *)poid_par_priv->information_buf;
+ /*CALL the power_down function*/
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*-------------------------------------------------------------------------- */
+uint oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv)
+{
+ struct _adapter *Adapter = (struct _adapter *)
+ (poid_par_priv->adapter_context);
+
+ if (poid_par_priv->type_of_oid != QUERY_OID)
+ return NDIS_STATUS_NOT_ACCEPTED;
+ if (poid_par_priv->information_buf_len < sizeof(u32))
+ return NDIS_STATUS_INVALID_LENGTH;
+ *(int *)poid_par_priv->information_buf =
+ Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL;
+ *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
+ return NDIS_STATUS_SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
new file mode 100644
index 000000000000..2225bd15466b
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
@@ -0,0 +1,457 @@
+#ifndef _RTL871X_MP_IOCTL_H
+#define _RTL871X_MP_IOCTL_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "mp_custom_oid.h"
+#include "rtl871x_ioctl.h"
+#include "rtl871x_ioctl_rtl.h"
+#include "rtl8712_efuse.h"
+
+#define TESTFWCMDNUMBER 1000000
+#define TEST_H2CINT_WAIT_TIME 500
+#define TEST_C2HINT_WAIT_TIME 500
+#define HCI_TEST_SYSCFG_HWMASK 1
+#define _BUSCLK_40M (4 << 2)
+
+struct CFG_DBG_MSG_STRUCT {
+ u32 DebugLevel;
+ u32 DebugComponent_H32;
+ u32 DebugComponent_L32;
+};
+
+struct mp_rw_reg {
+ uint offset;
+ uint width;
+ u32 value;
+};
+
+/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */
+struct eeprom_rw_param {
+ uint offset;
+ u16 value;
+};
+
+struct EFUSE_ACCESS_STRUCT {
+ u16 start_addr;
+ u16 cnts;
+ u8 data[0];
+};
+
+struct burst_rw_reg {
+ uint offset;
+ uint len;
+ u8 Data[256];
+};
+
+struct usb_vendor_req {
+ u8 bRequest;
+ u16 wValue;
+ u16 wIndex;
+ u16 wLength;
+ u8 u8Dir;/*0:OUT, 1:IN */
+ u8 u8InData;
+};
+
+struct DR_VARIABLE_STRUCT {
+ u8 offset;
+ u32 variable;
+};
+
+int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid);
+
+/* oid_rtl_seg_87_11_00 */
+uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv*
+ poid_par_priv);
+uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv*
+ poid_par_priv);
+uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_87_11_20 */
+uint oid_rt_pro_cfg_debug_message_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_data_rate_ex_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_basic_rate_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_power_tracking_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_87_11_50 */
+uint oid_rt_pro_qry_pwrstate_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_pwrstate_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_87_11_F0 */
+uint oid_rt_pro_h2c_set_rate_table_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_h2c_get_rate_table_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_81_80_00 */
+uint oid_rt_pro_set_data_rate_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_channel_direct_call_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_antenna_bb_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_tx_power_control_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_81_80_20 */
+uint oid_rt_pro_query_tx_packet_sent_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_query_rx_packet_received_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_query_rx_packet_crc32_error_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_reset_tx_packet_sent_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_reset_rx_packet_received_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_continuous_tx_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_single_carrier_tx_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_carrier_suppression_tx_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_single_tone_tx_hdl(
+ struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_81_87 */
+uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_81_85 */
+uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv);
+/* oid_rtl_seg_87_12_00 */
+uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_query_dr_variable_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_efuse_current_size_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_tx_agc_offset_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_pro_set_pkt_test_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_thermal_meter_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_reset_phy_rx_packet_count_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_phy_rx_packet_received_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_phy_rx_packet_crc32_error_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_set_power_down_hdl(
+ struct oid_par_priv *poid_par_priv);
+uint oid_rt_get_power_mode_hdl(
+ struct oid_par_priv *poid_par_priv);
+#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */
+/* This ifdef _MUST_ be left in!! */
+static const struct oid_obj_priv oid_rtl_seg_81_80_00[] = {
+ {1, &oid_null_function}, /*0x00 OID_RT_PRO_RESET_DUT */
+ {1, &oid_rt_pro_set_data_rate_hdl}, /*0x01*/
+ {1, &oid_rt_pro_start_test_hdl},/*0x02*/
+ {1, &oid_rt_pro_stop_test_hdl}, /*0x03*/
+ {1, &oid_null_function}, /*0x04 OID_RT_PRO_SET_PREAMBLE*/
+ {1, &oid_null_function}, /*0x05 OID_RT_PRO_SET_SCRAMBLER*/
+ {1, &oid_null_function}, /*0x06 OID_RT_PRO_SET_FILTER_BB*/
+ {1, &oid_null_function}, /*0x07
+ * OID_RT_PRO_SET_MANUAL_DIVERS_BB*/
+ {1, &oid_rt_pro_set_channel_direct_call_hdl}, /*0x08*/
+ {1, &oid_null_function}, /*0x09
+ * OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL*/
+ {1, &oid_null_function}, /*0x0A
+ * OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL*/
+ {1, &oid_rt_pro_set_continuous_tx_hdl}, /*0x0B
+ * OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL*/
+ {1, &oid_rt_pro_set_single_carrier_tx_hdl}, /*0x0C
+ * OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS*/
+ {1, &oid_null_function}, /*0x0D
+ * OID_RT_PRO_SET_TX_ANTENNA_BB*/
+ {1, &oid_rt_pro_set_antenna_bb_hdl}, /*0x0E*/
+ {1, &oid_null_function}, /*0x0F OID_RT_PRO_SET_CR_SCRAMBLER*/
+ {1, &oid_null_function}, /*0x10 OID_RT_PRO_SET_CR_NEW_FILTER*/
+ {1, &oid_rt_pro_set_tx_power_control_hdl}, /*0x11
+ * OID_RT_PRO_SET_TX_POWER_CONTROL*/
+ {1, &oid_null_function}, /*0x12 OID_RT_PRO_SET_CR_TX_CONFIG*/
+ {1, &oid_null_function}, /*0x13
+ * OID_RT_PRO_GET_TX_POWER_CONTROL*/
+ {1, &oid_null_function}, /*0x14
+ * OID_RT_PRO_GET_CR_SIGNAL_QUALITY*/
+ {1, &oid_null_function}, /*0x15 OID_RT_PRO_SET_CR_SETPOINT*/
+ {1, &oid_null_function}, /*0x16 OID_RT_PRO_SET_INTEGRATOR*/
+ {1, &oid_null_function}, /*0x17 OID_RT_PRO_SET_SIGNAL_QUALITY*/
+ {1, &oid_null_function}, /*0x18 OID_RT_PRO_GET_INTEGRATOR*/
+ {1, &oid_null_function}, /*0x19 OID_RT_PRO_GET_SIGNAL_QUALITY*/
+ {1, &oid_null_function}, /*0x1A OID_RT_PRO_QUERY_EEPROM_TYPE*/
+ {1, &oid_null_function}, /*0x1B OID_RT_PRO_WRITE_MAC_ADDRESS*/
+ {1, &oid_null_function}, /*0x1C OID_RT_PRO_READ_MAC_ADDRESS*/
+ {1, &oid_null_function}, /*0x1D OID_RT_PRO_WRITE_CIS_DATA*/
+ {1, &oid_null_function}, /*0x1E OID_RT_PRO_READ_CIS_DATA*/
+ {1, &oid_null_function} /*0x1F OID_RT_PRO_WRITE_POWER_CONTROL*/
+};
+
+static const struct oid_obj_priv oid_rtl_seg_81_80_20[] = {
+ {1, &oid_null_function}, /*0x20 OID_RT_PRO_READ_POWER_CONTROL*/
+ {1, &oid_null_function}, /*0x21 OID_RT_PRO_WRITE_EEPROM*/
+ {1, &oid_null_function}, /*0x22 OID_RT_PRO_READ_EEPROM*/
+ {1, &oid_rt_pro_reset_tx_packet_sent_hdl}, /*0x23*/
+ {1, &oid_rt_pro_query_tx_packet_sent_hdl}, /*0x24*/
+ {1, &oid_rt_pro_reset_rx_packet_received_hdl}, /*0x25*/
+ {1, &oid_rt_pro_query_rx_packet_received_hdl}, /*0x26*/
+ {1, &oid_rt_pro_query_rx_packet_crc32_error_hdl},/*0x27*/
+ {1, &oid_null_function}, /*0x28
+ *OID_RT_PRO_QUERY_CURRENT_ADDRESS*/
+ {1, &oid_null_function}, /*0x29
+ *OID_RT_PRO_QUERY_PERMANENT_ADDRESS*/
+ {1, &oid_null_function}, /*0x2A
+ *OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS*/
+ {1, &oid_rt_pro_set_carrier_suppression_tx_hdl},/*0x2B
+ *OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX*/
+ {1, &oid_null_function}, /*0x2C OID_RT_PRO_RECEIVE_PACKET*/
+ {1, &oid_null_function}, /*0x2D OID_RT_PRO_WRITE_EEPROM_BYTE*/
+ {1, &oid_null_function}, /*0x2E OID_RT_PRO_READ_EEPROM_BYTE*/
+ {1, &oid_rt_pro_set_modulation_hdl} /*0x2F*/
+};
+
+static const struct oid_obj_priv oid_rtl_seg_81_80_40[] = {
+ {1, &oid_null_function}, /*0x40*/
+ {1, &oid_null_function}, /*0x41*/
+ {1, &oid_null_function}, /*0x42*/
+ {1, &oid_rt_pro_set_single_tone_tx_hdl}, /*0x43*/
+ {1, &oid_null_function}, /*0x44*/
+ {1, &oid_null_function} /*0x45*/
+};
+
+static const struct oid_obj_priv oid_rtl_seg_81_80_80[] = {
+ {1, &oid_null_function}, /*0x80 OID_RT_DRIVER_OPTION*/
+ {1, &oid_null_function}, /*0x81 OID_RT_RF_OFF*/
+ {1, &oid_null_function} /*0x82 OID_RT_AUTH_STATUS*/
+
+};
+
+static const struct oid_obj_priv oid_rtl_seg_81_85[] = {
+ {1, &oid_rt_wireless_mode_hdl} /*0x00 OID_RT_WIRELESS_MODE*/
+};
+
+#else /* _RTL871X_MP_IOCTL_C_ */
+extern struct oid_obj_priv oid_rtl_seg_81_80_00[32];
+extern struct oid_obj_priv oid_rtl_seg_81_80_20[16];
+extern struct oid_obj_priv oid_rtl_seg_81_80_40[6];
+extern struct oid_obj_priv oid_rtl_seg_81_80_80[3];
+extern struct oid_obj_priv oid_rtl_seg_81_85[1];
+extern struct oid_obj_priv oid_rtl_seg_81_87[5];
+extern struct oid_obj_priv oid_rtl_seg_87_11_00[32];
+extern struct oid_obj_priv oid_rtl_seg_87_11_20[5];
+extern struct oid_obj_priv oid_rtl_seg_87_11_50[2];
+extern struct oid_obj_priv oid_rtl_seg_87_11_80[1];
+extern struct oid_obj_priv oid_rtl_seg_87_11_B0[1];
+extern struct oid_obj_priv oid_rtl_seg_87_11_F0[16];
+extern struct oid_obj_priv oid_rtl_seg_87_12_00[32];
+
+#endif /* _RTL871X_MP_IOCTL_C_ */
+
+
+enum MP_MODE {
+ MP_START_MODE,
+ MP_STOP_MODE,
+ MP_ERR_MODE
+};
+
+struct rwreg_param{
+ unsigned int offset;
+ unsigned int width;
+ unsigned int value;
+};
+
+struct bbreg_param{
+ unsigned int offset;
+ unsigned int phymask;
+ unsigned int value;
+};
+
+struct txpower_param{
+ unsigned int pwr_index;
+};
+
+struct datarate_param{
+ unsigned int rate_index;
+};
+
+struct rfintfs_parm {
+ unsigned int rfintfs;
+};
+
+struct mp_xmit_packet {
+ unsigned int len;
+ unsigned int mem[MAX_MP_XMITBUF_SZ >> 2];
+};
+
+struct psmode_param {
+ unsigned int ps_mode;
+ unsigned int smart_ps;
+};
+
+struct mp_ioctl_handler {
+ unsigned int paramsize;
+ unsigned int (*handler)(struct oid_par_priv *poid_par_priv);
+ unsigned int oid;
+};
+
+struct mp_ioctl_param{
+ unsigned int subcode;
+ unsigned int len;
+ unsigned char data[0];
+};
+
+#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_
+
+enum RTL871X_MP_IOCTL_SUBCODE {
+ GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/
+ GEN_MP_IOCTL_SUBCODE(MP_STOP), /*1*/
+ GEN_MP_IOCTL_SUBCODE(READ_REG), /*2*/
+ GEN_MP_IOCTL_SUBCODE(WRITE_REG),
+ GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), /*4*/
+ GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), /*5*/
+ GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*6*/
+ GEN_MP_IOCTL_SUBCODE(READ_BB_REG), /*7*/
+ GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG),
+ GEN_MP_IOCTL_SUBCODE(READ_RF_REG), /*9*/
+ GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG),
+ GEN_MP_IOCTL_SUBCODE(SET_RF_INTFS),
+ GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), /*12*/
+ GEN_MP_IOCTL_SUBCODE(PS_STATE), /*13*/
+ GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), /*14*/
+ GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), /*15*/
+ GEN_MP_IOCTL_SUBCODE(SET_PTM), /*16*/
+ GEN_MP_IOCTL_SUBCODE(READ_TSSI), /*17*/
+ GEN_MP_IOCTL_SUBCODE(CNTU_TX), /*18*/
+ GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), /*19*/
+ GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), /*20*/
+ GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), /*21*/
+ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*22*/
+ GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), /*23*/
+ GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*24*/
+ GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), /*25*/
+ GEN_MP_IOCTL_SUBCODE(GET_POWER_MODE), /*26*/
+ GEN_MP_IOCTL_SUBCODE(EFUSE), /*27*/
+ GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*28*/
+ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), /*29*/
+ GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), /*30*/
+ GEN_MP_IOCTL_SUBCODE(SC_TX), /*31*/
+ GEN_MP_IOCTL_SUBCODE(CS_TX), /*32*/
+ GEN_MP_IOCTL_SUBCODE(ST_TX), /*33*/
+ GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), /*34*/
+ MAX_MP_IOCTL_SUBCODE,
+};
+
+unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv);
+
+#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */
+/* This ifdef _MUST_ be left in!! */
+
+struct mp_ioctl_handler mp_ioctl_hdl[] = {
+ {sizeof(u32), oid_rt_pro_start_test_hdl,
+ OID_RT_PRO_START_TEST},/*0*/
+ {sizeof(u32), oid_rt_pro_stop_test_hdl,
+ OID_RT_PRO_STOP_TEST},/*1*/
+ {sizeof(struct rwreg_param),
+ oid_rt_pro_read_register_hdl,
+ OID_RT_PRO_READ_REGISTER},/*2*/
+ {sizeof(struct rwreg_param),
+ oid_rt_pro_write_register_hdl,
+ OID_RT_PRO_WRITE_REGISTER},
+ {sizeof(u32),
+ oid_rt_pro_set_channel_direct_call_hdl,
+ OID_RT_PRO_SET_CHANNEL_DIRECT_CALL},
+ {sizeof(struct txpower_param),
+ oid_rt_pro_set_tx_power_control_hdl,
+ OID_RT_PRO_SET_TX_POWER_CONTROL},
+ {sizeof(u32),
+ oid_rt_pro_set_data_rate_hdl,
+ OID_RT_PRO_SET_DATA_RATE},
+ {sizeof(struct bb_reg_param),
+ oid_rt_pro_read_bb_reg_hdl,
+ OID_RT_PRO_READ_BB_REG},/*7*/
+ {sizeof(struct bb_reg_param),
+ oid_rt_pro_write_bb_reg_hdl,
+ OID_RT_PRO_WRITE_BB_REG},
+ {sizeof(struct rwreg_param),
+ oid_rt_pro_read_rf_reg_hdl,
+ OID_RT_PRO_RF_READ_REGISTRY},/*9*/
+ {sizeof(struct rwreg_param),
+ oid_rt_pro_write_rf_reg_hdl,
+ OID_RT_PRO_RF_WRITE_REGISTRY},
+ {sizeof(struct rfintfs_parm), NULL, 0},
+ {0, &mp_ioctl_xmit_packet_hdl, 0},/*12*/
+ {sizeof(struct psmode_param), NULL, 0},/*13*/
+ {sizeof(struct eeprom_rw_param), NULL, 0},/*14*/
+ {sizeof(struct eeprom_rw_param), NULL, 0},/*15*/
+ {sizeof(u8), oid_rt_pro_set_power_tracking_hdl,
+ OID_RT_PRO_SET_POWER_TRACKING},/*16*/
+ {sizeof(u32), NULL, 0},/*17*/
+ {sizeof(u32), oid_rt_pro_set_continuous_tx_hdl,
+ OID_RT_PRO_SET_CONTINUOUS_TX},/*18*/
+ {sizeof(u32), oid_rt_set_bandwidth_hdl,
+ OID_RT_SET_BANDWIDTH},/*19*/
+ {sizeof(u32), oid_rt_set_rx_packet_type_hdl,
+ OID_RT_SET_RX_PACKET_TYPE},/*20*/
+ {0, oid_rt_reset_phy_rx_packet_count_hdl,
+ OID_RT_RESET_PHY_RX_PACKET_COUNT},/*21*/
+ {sizeof(u32), oid_rt_get_phy_rx_packet_received_hdl,
+ OID_RT_GET_PHY_RX_PACKET_RECEIVED},/*22*/
+ {sizeof(u32), oid_rt_get_phy_rx_packet_crc32_error_hdl,
+ OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR},/*23*/
+ {sizeof(unsigned char), oid_rt_set_power_down_hdl,
+ OID_RT_SET_POWER_DOWN},/*24*/
+ {sizeof(u32), oid_rt_get_thermal_meter_hdl,
+ OID_RT_PRO_GET_THERMAL_METER},/*25*/
+ {sizeof(u32), oid_rt_get_power_mode_hdl,
+ OID_RT_GET_POWER_MODE},/*26*/
+ {sizeof(struct EFUSE_ACCESS_STRUCT),
+ oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE},/*27*/
+ {EFUSE_MAP_MAX_SIZE, oid_rt_pro_efuse_map_hdl,
+ OID_RT_PRO_EFUSE_MAP},/*28*/
+ {sizeof(u32), oid_rt_get_efuse_max_size_hdl,
+ OID_RT_GET_EFUSE_MAX_SIZE},/*29*/
+ {sizeof(u32), oid_rt_get_efuse_current_size_hdl,
+ OID_RT_GET_EFUSE_CURRENT_SIZE},/*30*/
+ {sizeof(u32), oid_rt_pro_set_single_carrier_tx_hdl,
+ OID_RT_PRO_SET_SINGLE_CARRIER_TX},/*31*/
+ {sizeof(u32), oid_rt_pro_set_carrier_suppression_tx_hdl,
+ OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX},/*32*/
+ {sizeof(u32), oid_rt_pro_set_single_tone_tx_hdl,
+ OID_RT_PRO_SET_SINGLE_TONE_TX},/*33*/
+ {sizeof(u32), oid_rt_pro_set_antenna_bb_hdl,
+ OID_RT_PRO_SET_ANTENNA_BB},/*34*/
+};
+
+#else /* _RTL871X_MP_IOCTL_C_ */
+extern struct mp_ioctl_handler mp_ioctl_hdl[];
+#endif /* _RTL871X_MP_IOCTL_C_ */
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h
new file mode 100644
index 000000000000..e386fb0aac3e
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h
@@ -0,0 +1,1025 @@
+/*****************************************************************************
+ * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved.
+ *
+ * Module: __INC_HAL8192SPHYREG_H
+ *
+ *
+ * Note: 1. Define PMAC/BB register map
+ * 2. Define RF register map
+ * 3. PMAC/BB register bit mask.
+ * 4. RF reg bit mask.
+ * 5. Other BB/RF relative definition.
+ *
+ *
+ * Export: Constants, macro, functions(API), global variables(None).
+ *
+ * Abbrev:
+ *
+ * History:
+ * Data Who Remark
+ * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h.
+ * 2. Reorganize code architecture.
+ * 09/25/2008 MH 1. Add RL6052 register definition
+ *
+ *****************************************************************************/
+#ifndef __RTL871X_MP_PHY_REGDEF_H
+#define __RTL871X_MP_PHY_REGDEF_H
+
+
+/*--------------------------Define Parameters-------------------------------*/
+
+/*============================================================
+ * 8192S Regsiter offset definition
+ *============================================================
+ *
+ *
+ * BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF
+ * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
+ * 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00
+ * 3. RF register 0x00-2E
+ * 4. Bit Mask for BB/RF register
+ * 5. Other defintion for BB/RF R/W
+ *
+ * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
+ * 1. Page1(0x100)
+ */
+#define rPMAC_Reset 0x100
+#define rPMAC_TxStart 0x104
+#define rPMAC_TxLegacySIG 0x108
+#define rPMAC_TxHTSIG1 0x10c
+#define rPMAC_TxHTSIG2 0x110
+#define rPMAC_PHYDebug 0x114
+#define rPMAC_TxPacketNum 0x118
+#define rPMAC_TxIdle 0x11c
+#define rPMAC_TxMACHeader0 0x120
+#define rPMAC_TxMACHeader1 0x124
+#define rPMAC_TxMACHeader2 0x128
+#define rPMAC_TxMACHeader3 0x12c
+#define rPMAC_TxMACHeader4 0x130
+#define rPMAC_TxMACHeader5 0x134
+#define rPMAC_TxDataType 0x138
+#define rPMAC_TxRandomSeed 0x13c
+#define rPMAC_CCKPLCPPreamble 0x140
+#define rPMAC_CCKPLCPHeader 0x144
+#define rPMAC_CCKCRC16 0x148
+#define rPMAC_OFDMRxCRC32OK 0x170
+#define rPMAC_OFDMRxCRC32Er 0x174
+#define rPMAC_OFDMRxParityEr 0x178
+#define rPMAC_OFDMRxCRC8Er 0x17c
+#define rPMAC_CCKCRxRC16Er 0x180
+#define rPMAC_CCKCRxRC32Er 0x184
+#define rPMAC_CCKCRxRC32OK 0x188
+#define rPMAC_TxStatus 0x18c
+
+/*
+ * 2. Page2(0x200)
+ *
+ * The following two definition are only used for USB interface.
+ *#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address.
+ *#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data.
+ *
+ *
+ * 3. Page8(0x800)
+ */
+#define rFPGA0_RFMOD 0x800 /*RF mode & CCK TxSC RF
+ * BW Setting?? */
+#define rFPGA0_TxInfo 0x804 /* Status report?? */
+#define rFPGA0_PSDFunction 0x808
+#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */
+#define rFPGA0_RFTiming1 0x810 /* Useless now */
+#define rFPGA0_RFTiming2 0x814
+#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */
+#define rFPGA0_XA_HSSIParameter2 0x824
+#define rFPGA0_XB_HSSIParameter1 0x828
+#define rFPGA0_XB_HSSIParameter2 0x82c
+#define rFPGA0_XC_HSSIParameter1 0x830
+#define rFPGA0_XC_HSSIParameter2 0x834
+#define rFPGA0_XD_HSSIParameter1 0x838
+#define rFPGA0_XD_HSSIParameter2 0x83c
+#define rFPGA0_XA_LSSIParameter 0x840
+#define rFPGA0_XB_LSSIParameter 0x844
+#define rFPGA0_XC_LSSIParameter 0x848
+#define rFPGA0_XD_LSSIParameter 0x84c
+
+#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */
+#define rFPGA0_RFSleepUpParameter 0x854
+
+#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */
+#define rFPGA0_XCD_SwitchControl 0x85c
+
+#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */
+#define rFPGA0_XB_RFInterfaceOE 0x864
+#define rFPGA0_XC_RFInterfaceOE 0x868
+#define rFPGA0_XD_RFInterfaceOE 0x86c
+#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Ctrl */
+#define rFPGA0_XCD_RFInterfaceSW 0x874
+
+#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */
+#define rFPGA0_XCD_RFParameter 0x87c
+
+#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting
+ * RF-R/W protection
+ * for parameter4?? */
+#define rFPGA0_AnalogParameter2 0x884
+#define rFPGA0_AnalogParameter3 0x888 /* Useless now */
+#define rFPGA0_AnalogParameter4 0x88c
+
+#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */
+#define rFPGA0_XB_LSSIReadBack 0x8a4
+#define rFPGA0_XC_LSSIReadBack 0x8a8
+#define rFPGA0_XD_LSSIReadBack 0x8ac
+
+#define rFPGA0_PSDReport 0x8b4 /* Useless now */
+#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now */
+#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */
+
+/*
+ * 4. Page9(0x900)
+ */
+#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC */
+
+#define rFPGA1_TxBlock 0x904 /* Useless now */
+#define rFPGA1_DebugSelect 0x908 /* Useless now */
+#define rFPGA1_TxInfo 0x90c /* Useless now */
+
+/*
+ * 5. PageA(0xA00)
+ *
+ * Set Control channel to upper or lower.
+ * These settings are required only for 40MHz */
+#define rCCK0_System 0xa00
+
+#define rCCK0_AFESetting 0xa04 /* Disable init gain now */
+#define rCCK0_CCA 0xa08 /* Disable init gain now */
+
+#define rCCK0_RxAGC1 0xa0c
+/* AGC default value, saturation level
+ * Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now.
+ * Not the same as 90 series */
+#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */
+
+#define rCCK0_RxHP 0xa14
+
+#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel
+ * estimation threshold */
+#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */
+
+#define rCCK0_TxFilter1 0xa20
+#define rCCK0_TxFilter2 0xa24
+#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */
+#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f
+ * channel report */
+#define rCCK0_TRSSIReport 0xa50
+#define rCCK0_RxReport 0xa54 /* 0xa57 */
+#define rCCK0_FACounterLower 0xa5c /* 0xa5b */
+#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */
+
+/*
+ * 6. PageC(0xC00)
+ */
+#define rOFDM0_LSTF 0xc00
+#define rOFDM0_TRxPathEnable 0xc04
+#define rOFDM0_TRMuxPar 0xc08
+#define rOFDM0_TRSWIsolation 0xc0c
+
+/*RxIQ DC offset, Rx digital filter, DC notch filter */
+#define rOFDM0_XARxAFE 0xc10
+#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */
+#define rOFDM0_XBRxAFE 0xc18
+#define rOFDM0_XBRxIQImbalance 0xc1c
+#define rOFDM0_XCRxAFE 0xc20
+#define rOFDM0_XCRxIQImbalance 0xc24
+#define rOFDM0_XDRxAFE 0xc28
+#define rOFDM0_XDRxIQImbalance 0xc2c
+
+#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune
+ * init gain */
+#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */
+#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */
+#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync &
+ * Short-GI */
+
+#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */
+#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */
+#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */
+#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */
+
+#define rOFDM0_XAAGCCore1 0xc50 /* DIG */
+#define rOFDM0_XAAGCCore2 0xc54
+#define rOFDM0_XBAGCCore1 0xc58
+#define rOFDM0_XBAGCCore2 0xc5c
+#define rOFDM0_XCAGCCore1 0xc60
+#define rOFDM0_XCAGCCore2 0xc64
+#define rOFDM0_XDAGCCore1 0xc68
+#define rOFDM0_XDAGCCore2 0xc6c
+#define rOFDM0_AGCParameter1 0xc70
+#define rOFDM0_AGCParameter2 0xc74
+#define rOFDM0_AGCRSSITable 0xc78
+#define rOFDM0_HTSTFAGC 0xc7c
+
+#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */
+#define rOFDM0_XATxAFE 0xc84
+#define rOFDM0_XBTxIQImbalance 0xc88
+#define rOFDM0_XBTxAFE 0xc8c
+#define rOFDM0_XCTxIQImbalance 0xc90
+#define rOFDM0_XCTxAFE 0xc94
+#define rOFDM0_XDTxIQImbalance 0xc98
+#define rOFDM0_XDTxAFE 0xc9c
+
+#define rOFDM0_RxHPParameter 0xce0
+#define rOFDM0_TxPseudoNoiseWgt 0xce4
+#define rOFDM0_FrameSync 0xcf0
+#define rOFDM0_DFSReport 0xcf4
+#define rOFDM0_TxCoeff1 0xca4
+#define rOFDM0_TxCoeff2 0xca8
+#define rOFDM0_TxCoeff3 0xcac
+#define rOFDM0_TxCoeff4 0xcb0
+#define rOFDM0_TxCoeff5 0xcb4
+#define rOFDM0_TxCoeff6 0xcb8
+
+/*
+ * 7. PageD(0xD00)
+ */
+#define rOFDM1_LSTF 0xd00
+#define rOFDM1_TRxPathEnable 0xd04
+
+#define rOFDM1_CFO 0xd08 /* No setting now */
+#define rOFDM1_CSI1 0xd10
+#define rOFDM1_SBD 0xd14
+#define rOFDM1_CSI2 0xd18
+#define rOFDM1_CFOTracking 0xd2c
+#define rOFDM1_TRxMesaure1 0xd34
+#define rOFDM1_IntfDet 0xd3c
+#define rOFDM1_PseudoNoiseStateAB 0xd50
+#define rOFDM1_PseudoNoiseStateCD 0xd54
+#define rOFDM1_RxPseudoNoiseWgt 0xd58
+
+#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */
+#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */
+#define rOFDM_PHYCounter3 0xda8 /* MCS not support */
+#define rOFDM_ShortCFOAB 0xdac /* No setting now */
+#define rOFDM_ShortCFOCD 0xdb0
+#define rOFDM_LongCFOAB 0xdb4
+#define rOFDM_LongCFOCD 0xdb8
+#define rOFDM_TailCFOAB 0xdbc
+#define rOFDM_TailCFOCD 0xdc0
+#define rOFDM_PWMeasure1 0xdc4
+#define rOFDM_PWMeasure2 0xdc8
+#define rOFDM_BWReport 0xdcc
+#define rOFDM_AGCReport 0xdd0
+#define rOFDM_RxSNR 0xdd4
+#define rOFDM_RxEVMCSI 0xdd8
+#define rOFDM_SIGReport 0xddc
+
+/*
+ * 8. PageE(0xE00)
+ */
+#define rTxAGC_Rate18_06 0xe00
+#define rTxAGC_Rate54_24 0xe04
+#define rTxAGC_CCK_Mcs32 0xe08
+#define rTxAGC_Mcs03_Mcs00 0xe10
+#define rTxAGC_Mcs07_Mcs04 0xe14
+#define rTxAGC_Mcs11_Mcs08 0xe18
+#define rTxAGC_Mcs15_Mcs12 0xe1c
+
+/* Analog- control in RX_WAIT_CCA : REG: EE0
+ * [Analog- Power & Control Register] */
+#define rRx_Wait_CCCA 0xe70
+#define rAnapar_Ctrl_BB 0xee0
+
+/*
+ * 7. RF Register 0x00-0x2E (RF 8256)
+ * RF-0222D 0x00-3F
+ *
+ * Zebra1
+ */
+#define rZebra1_HSSIEnable 0x0 /* Useless now */
+#define rZebra1_TRxEnable1 0x1
+#define rZebra1_TRxEnable2 0x2
+#define rZebra1_AGC 0x4
+#define rZebra1_ChargePump 0x5
+#define rZebra1_Channel 0x7 /* RF channel switch */
+#define rZebra1_TxGain 0x8 /* Useless now */
+#define rZebra1_TxLPF 0x9
+#define rZebra1_RxLPF 0xb
+#define rZebra1_RxHPFCorner 0xc
+
+/* Zebra4 */
+#define rGlobalCtrl 0 /* Useless now */
+#define rRTL8256_TxLPF 19
+#define rRTL8256_RxLPF 11
+
+/* RTL8258 */
+#define rRTL8258_TxLPF 0x11 /* Useless now */
+#define rRTL8258_RxLPF 0x13
+#define rRTL8258_RSSILPF 0xa
+
+/* RL6052 Register definition */
+#define RF_AC 0x00
+#define RF_IQADJ_G1 0x01
+#define RF_IQADJ_G2 0x02
+#define RF_POW_TRSW 0x05
+
+#define RF_GAIN_RX 0x06
+#define RF_GAIN_TX 0x07
+
+#define RF_TXM_IDAC 0x08
+#define RF_BS_IQGEN 0x0F
+
+#define RF_MODE1 0x10
+#define RF_MODE2 0x11
+
+#define RF_RX_AGC_HP 0x12
+#define RF_TX_AGC 0x13
+#define RF_BIAS 0x14
+#define RF_IPA 0x15
+#define RF_POW_ABILITY 0x17
+#define RF_MODE_AG 0x18
+#define rRfChannel 0x18 /* RF channel and BW switch */
+#define RF_CHNLBW 0x18 /* RF channel and BW switch */
+#define RF_TOP 0x19
+#define RF_RX_G1 0x1A
+#define RF_RX_G2 0x1B
+#define RF_RX_BB2 0x1C
+#define RF_RX_BB1 0x1D
+
+#define RF_RCK1 0x1E
+#define RF_RCK2 0x1F
+
+#define RF_TX_G1 0x20
+#define RF_TX_G2 0x21
+#define RF_TX_G3 0x22
+
+#define RF_TX_BB1 0x23
+#define RF_T_METER 0x24
+
+#define RF_SYN_G1 0x25 /* RF TX Power control */
+#define RF_SYN_G2 0x26 /* RF TX Power control */
+#define RF_SYN_G3 0x27 /* RF TX Power control */
+#define RF_SYN_G4 0x28 /* RF TX Power control */
+#define RF_SYN_G5 0x29 /* RF TX Power control */
+#define RF_SYN_G6 0x2A /* RF TX Power control */
+#define RF_SYN_G7 0x2B /* RF TX Power control */
+#define RF_SYN_G8 0x2C /* RF TX Power control */
+
+#define RF_RCK_OS 0x30 /* RF TX PA control */
+
+#define RF_TXPA_G1 0x31 /* RF TX PA control */
+#define RF_TXPA_G2 0x32 /* RF TX PA control */
+#define RF_TXPA_G3 0x33 /* RF TX PA control */
+
+/*
+ * Bit Mask
+ *
+ * 1. Page1(0x100) */
+#define bBBResetB 0x100 /* Useless now? */
+#define bGlobalResetB 0x200
+#define bOFDMTxStart 0x4
+#define bCCKTxStart 0x8
+#define bCRC32Debug 0x100
+#define bPMACLoopback 0x10
+#define bTxLSIG 0xffffff
+#define bOFDMTxRate 0xf
+#define bOFDMTxReserved 0x10
+#define bOFDMTxLength 0x1ffe0
+#define bOFDMTxParity 0x20000
+#define bTxHTSIG1 0xffffff
+#define bTxHTMCSRate 0x7f
+#define bTxHTBW 0x80
+#define bTxHTLength 0xffff00
+#define bTxHTSIG2 0xffffff
+#define bTxHTSmoothing 0x1
+#define bTxHTSounding 0x2
+#define bTxHTReserved 0x4
+#define bTxHTAggreation 0x8
+#define bTxHTSTBC 0x30
+#define bTxHTAdvanceCoding 0x40
+#define bTxHTShortGI 0x80
+#define bTxHTNumberHT_LTF 0x300
+#define bTxHTCRC8 0x3fc00
+#define bCounterReset 0x10000
+#define bNumOfOFDMTx 0xffff
+#define bNumOfCCKTx 0xffff0000
+#define bTxIdleInterval 0xffff
+#define bOFDMService 0xffff0000
+#define bTxMACHeader 0xffffffff
+#define bTxDataInit 0xff
+#define bTxHTMode 0x100
+#define bTxDataType 0x30000
+#define bTxRandomSeed 0xffffffff
+#define bCCKTxPreamble 0x1
+#define bCCKTxSFD 0xffff0000
+#define bCCKTxSIG 0xff
+#define bCCKTxService 0xff00
+#define bCCKLengthExt 0x8000
+#define bCCKTxLength 0xffff0000
+#define bCCKTxCRC16 0xffff
+#define bCCKTxStatus 0x1
+#define bOFDMTxStatus 0x2
+#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && \
+ (_Offset <= 0xfff))
+
+/* 2. Page8(0x800) */
+#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */
+#define bJapanMode 0x2
+#define bCCKTxSC 0x30
+#define bCCKEn 0x1000000
+#define bOFDMEn 0x2000000
+
+#define bOFDMRxADCPhase 0x10000 /* Useless now */
+#define bOFDMTxDACPhase 0x40000
+#define bXATxAGC 0x3f
+#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */
+#define bXCTxAGC 0xf000
+#define bXDTxAGC 0xf0000
+
+#define bPAStart 0xf0000000 /* Useless now */
+#define bTRStart 0x00f00000
+#define bRFStart 0x0000f000
+#define bBBStart 0x000000f0
+#define bBBCCKStart 0x0000000f
+#define bPAEnd 0xf /* Reg0x814 */
+#define bTREnd 0x0f000000
+#define bRFEnd 0x000f0000
+#define bCCAMask 0x000000f0 /* T2R */
+#define bR2RCCAMask 0x00000f00
+#define bHSSI_R2TDelay 0xf8000000
+#define bHSSI_T2RDelay 0xf80000
+#define bContTxHSSI 0x400 /* change gain at continue Tx */
+#define bIGFromCCK 0x200
+#define bAGCAddress 0x3f
+#define bRxHPTx 0x7000
+#define bRxHPT2R 0x38000
+#define bRxHPCCKIni 0xc0000
+#define bAGCTxCode 0xc00000
+#define bAGCRxCode 0x300000
+#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParm1 */
+#define b3WireAddressLength 0x400
+#define b3WireRFPowerDown 0x1 /* Useless now */
+#define b5GPAPEPolarity 0x40000000
+#define b2GPAPEPolarity 0x80000000
+#define bRFSW_TxDefaultAnt 0x3
+#define bRFSW_TxOptionAnt 0x30
+#define bRFSW_RxDefaultAnt 0x300
+#define bRFSW_RxOptionAnt 0x3000
+#define bRFSI_3WireData 0x1
+#define bRFSI_3WireClock 0x2
+#define bRFSI_3WireLoad 0x4
+#define bRFSI_3WireRW 0x8
+#define bRFSI_3Wire 0xf
+#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */
+#define bRFSI_TRSW 0x20 /* Useless now */
+#define bRFSI_TRSWB 0x40
+#define bRFSI_ANTSW 0x100
+#define bRFSI_ANTSWB 0x200
+#define bRFSI_PAPE 0x400
+#define bRFSI_PAPE5G 0x800
+#define bBandSelect 0x1
+#define bHTSIG2_GI 0x80
+#define bHTSIG2_Smoothing 0x01
+#define bHTSIG2_Sounding 0x02
+#define bHTSIG2_Aggreaton 0x08
+#define bHTSIG2_STBC 0x30
+#define bHTSIG2_AdvCoding 0x40
+#define bHTSIG2_NumOfHTLTF 0x300
+#define bHTSIG2_CRC8 0x3fc
+#define bHTSIG1_MCS 0x7f
+#define bHTSIG1_BandWidth 0x80
+#define bHTSIG1_HTLength 0xffff
+#define bLSIG_Rate 0xf
+#define bLSIG_Reserved 0x10
+#define bLSIG_Length 0x1fffe
+#define bLSIG_Parity 0x20
+#define bCCKRxPhase 0x4
+#define bLSSIReadAddress 0x7f800000 /* T65 RF */
+#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */
+#define bLSSIReadBackData 0xfffff /* T65 RF */
+#define bLSSIReadOKFlag 0x1000 /* Useless now */
+#define bCCKSampleRate 0x8 /*0: 44MHz, 1:88MHz*/
+#define bRegulator0Standby 0x1
+#define bRegulatorPLLStandby 0x2
+#define bRegulator1Standby 0x4
+#define bPLLPowerUp 0x8
+#define bDPLLPowerUp 0x10
+#define bDA10PowerUp 0x20
+#define bAD7PowerUp 0x200
+#define bDA6PowerUp 0x2000
+#define bXtalPowerUp 0x4000
+#define b40MDClkPowerUP 0x8000
+#define bDA6DebugMode 0x20000
+#define bDA6Swing 0x380000
+
+/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */
+#define bADClkPhase 0x4000000
+
+#define b80MClkDelay 0x18000000 /* Useless */
+#define bAFEWatchDogEnable 0x20000000
+
+/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */
+#define bXtalCap01 0xc0000000
+#define bXtalCap23 0x3
+#define bXtalCap92x 0x0f000000
+#define bXtalCap 0x0f000000
+#define bIntDifClkEnable 0x400 /* Useless */
+#define bExtSigClkEnable 0x800
+#define bBandgapMbiasPowerUp 0x10000
+#define bAD11SHGain 0xc0000
+#define bAD11InputRange 0x700000
+#define bAD11OPCurrent 0x3800000
+#define bIPathLoopback 0x4000000
+#define bQPathLoopback 0x8000000
+#define bAFELoopback 0x10000000
+#define bDA10Swing 0x7e0
+#define bDA10Reverse 0x800
+#define bDAClkSource 0x1000
+#define bAD7InputRange 0x6000
+#define bAD7Gain 0x38000
+#define bAD7OutputCMMode 0x40000
+#define bAD7InputCMMode 0x380000
+#define bAD7Current 0xc00000
+#define bRegulatorAdjust 0x7000000
+#define bAD11PowerUpAtTx 0x1
+#define bDA10PSAtTx 0x10
+#define bAD11PowerUpAtRx 0x100
+#define bDA10PSAtRx 0x1000
+#define bCCKRxAGCFormat 0x200
+#define bPSDFFTSamplepPoint 0xc000
+#define bPSDAverageNum 0x3000
+#define bIQPathControl 0xc00
+#define bPSDFreq 0x3ff
+#define bPSDAntennaPath 0x30
+#define bPSDIQSwitch 0x40
+#define bPSDRxTrigger 0x400000
+#define bPSDTxTrigger 0x80000000
+#define bPSDSineToneScale 0x7f000000
+#define bPSDReport 0xffff
+
+/* 3. Page9(0x900) */
+#define bOFDMTxSC 0x30000000 /* Useless */
+#define bCCKTxOn 0x1
+#define bOFDMTxOn 0x2
+#define bDebugPage 0xfff /* reset debug page and HWord, LWord */
+#define bDebugItem 0xff /* reset debug page and LWord */
+#define bAntL 0x10
+#define bAntNonHT 0x100
+#define bAntHT1 0x1000
+#define bAntHT2 0x10000
+#define bAntHT1S1 0x100000
+#define bAntNonHTS1 0x1000000
+
+/* 4. PageA(0xA00) */
+#define bCCKBBMode 0x3 /* Useless */
+#define bCCKTxPowerSaving 0x80
+#define bCCKRxPowerSaving 0x40
+
+#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 switch*/
+#define bCCKScramble 0x8 /* Useless */
+#define bCCKAntDiversity 0x8000
+#define bCCKCarrierRecovery 0x4000
+#define bCCKTxRate 0x3000
+#define bCCKDCCancel 0x0800
+#define bCCKISICancel 0x0400
+#define bCCKMatchFilter 0x0200
+#define bCCKEqualizer 0x0100
+#define bCCKPreambleDetect 0x800000
+#define bCCKFastFalseCCA 0x400000
+#define bCCKChEstStart 0x300000
+#define bCCKCCACount 0x080000
+#define bCCKcs_lim 0x070000
+#define bCCKBistMode 0x80000000
+#define bCCKCCAMask 0x40000000
+#define bCCKTxDACPhase 0x4
+#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */
+#define bCCKr_cp_mode0 0x0100
+#define bCCKTxDCOffset 0xf0
+#define bCCKRxDCOffset 0xf
+#define bCCKCCAMode 0xc000
+#define bCCKFalseCS_lim 0x3f00
+#define bCCKCS_ratio 0xc00000
+#define bCCKCorgBit_sel 0x300000
+#define bCCKPD_lim 0x0f0000
+#define bCCKNewCCA 0x80000000
+#define bCCKRxHPofIG 0x8000
+#define bCCKRxIG 0x7f00
+#define bCCKLNAPolarity 0x800000
+#define bCCKRx1stGain 0x7f0000
+#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */
+#define bCCKRxAGCSatLevel 0x1f000000
+#define bCCKRxAGCSatCount 0xe0
+#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */
+#define bCCKFixedRxAGC 0x8000
+#define bCCKAntennaPolarity 0x2000
+#define bCCKTxFilterType 0x0c00
+#define bCCKRxAGCReportType 0x0300
+#define bCCKRxDAGCEn 0x80000000
+#define bCCKRxDAGCPeriod 0x20000000
+#define bCCKRxDAGCSatLevel 0x1f000000
+#define bCCKTimingRecovery 0x800000
+#define bCCKTxC0 0x3f0000
+#define bCCKTxC1 0x3f000000
+#define bCCKTxC2 0x3f
+#define bCCKTxC3 0x3f00
+#define bCCKTxC4 0x3f0000
+#define bCCKTxC5 0x3f000000
+#define bCCKTxC6 0x3f
+#define bCCKTxC7 0x3f00
+#define bCCKDebugPort 0xff0000
+#define bCCKDACDebug 0x0f000000
+#define bCCKFalseAlarmEnable 0x8000
+#define bCCKFalseAlarmRead 0x4000
+#define bCCKTRSSI 0x7f
+#define bCCKRxAGCReport 0xfe
+#define bCCKRxReport_AntSel 0x80000000
+#define bCCKRxReport_MFOff 0x40000000
+#define bCCKRxRxReport_SQLoss 0x20000000
+#define bCCKRxReport_Pktloss 0x10000000
+#define bCCKRxReport_Lockedbit 0x08000000
+#define bCCKRxReport_RateError 0x04000000
+#define bCCKRxReport_RxRate 0x03000000
+#define bCCKRxFACounterLower 0xff
+#define bCCKRxFACounterUpper 0xff000000
+#define bCCKRxHPAGCStart 0xe000
+#define bCCKRxHPAGCFinal 0x1c00
+#define bCCKRxFalseAlarmEnable 0x8000
+#define bCCKFACounterFreeze 0x4000
+#define bCCKTxPathSel 0x10000000
+#define bCCKDefaultRxPath 0xc000000
+#define bCCKOptionRxPath 0x3000000
+
+/* 5. PageC(0xC00) */
+#define bNumOfSTF 0x3 /* Useless */
+#define bShift_L 0xc0
+#define bGI_TH 0xc
+#define bRxPathA 0x1
+#define bRxPathB 0x2
+#define bRxPathC 0x4
+#define bRxPathD 0x8
+#define bTxPathA 0x1
+#define bTxPathB 0x2
+#define bTxPathC 0x4
+#define bTxPathD 0x8
+#define bTRSSIFreq 0x200
+#define bADCBackoff 0x3000
+#define bDFIRBackoff 0xc000
+#define bTRSSILatchPhase 0x10000
+#define bRxIDCOffset 0xff
+#define bRxQDCOffset 0xff00
+#define bRxDFIRMode 0x1800000
+#define bRxDCNFType 0xe000000
+#define bRXIQImb_A 0x3ff
+#define bRXIQImb_B 0xfc00
+#define bRXIQImb_C 0x3f0000
+#define bRXIQImb_D 0xffc00000
+#define bDC_dc_Notch 0x60000
+#define bRxNBINotch 0x1f000000
+#define bPD_TH 0xf
+#define bPD_TH_Opt2 0xc000
+#define bPWED_TH 0x700
+#define bIfMF_Win_L 0x800
+#define bPD_Option 0x1000
+#define bMF_Win_L 0xe000
+#define bBW_Search_L 0x30000
+#define bwin_enh_L 0xc0000
+#define bBW_TH 0x700000
+#define bED_TH2 0x3800000
+#define bBW_option 0x4000000
+#define bRatio_TH 0x18000000
+#define bWindow_L 0xe0000000
+#define bSBD_Option 0x1
+#define bFrame_TH 0x1c
+#define bFS_Option 0x60
+#define bDC_Slope_check 0x80
+#define bFGuard_Counter_DC_L 0xe00
+#define bFrame_Weight_Short 0x7000
+#define bSub_Tune 0xe00000
+#define bFrame_DC_Length 0xe000000
+#define bSBD_start_offset 0x30000000
+#define bFrame_TH_2 0x7
+#define bFrame_GI2_TH 0x38
+#define bGI2_Sync_en 0x40
+#define bSarch_Short_Early 0x300
+#define bSarch_Short_Late 0xc00
+#define bSarch_GI2_Late 0x70000
+#define bCFOAntSum 0x1
+#define bCFOAcc 0x2
+#define bCFOStartOffset 0xc
+#define bCFOLookBack 0x70
+#define bCFOSumWeight 0x80
+#define bDAGCEnable 0x10000
+#define bTXIQImb_A 0x3ff
+#define bTXIQImb_B 0xfc00
+#define bTXIQImb_C 0x3f0000
+#define bTXIQImb_D 0xffc00000
+#define bTxIDCOffset 0xff
+#define bTxQDCOffset 0xff00
+#define bTxDFIRMode 0x10000
+#define bTxPesudoNoiseOn 0x4000000
+#define bTxPesudoNoise_A 0xff
+#define bTxPesudoNoise_B 0xff00
+#define bTxPesudoNoise_C 0xff0000
+#define bTxPesudoNoise_D 0xff000000
+#define bCCADropOption 0x20000
+#define bCCADropThres 0xfff00000
+#define bEDCCA_H 0xf
+#define bEDCCA_L 0xf0
+#define bLambda_ED 0x300
+#define bRxInitialGain 0x7f
+#define bRxAntDivEn 0x80
+#define bRxAGCAddressForLNA 0x7f00
+#define bRxHighPowerFlow 0x8000
+#define bRxAGCFreezeThres 0xc0000
+#define bRxFreezeStep_AGC1 0x300000
+#define bRxFreezeStep_AGC2 0xc00000
+#define bRxFreezeStep_AGC3 0x3000000
+#define bRxFreezeStep_AGC0 0xc000000
+#define bRxRssi_Cmp_En 0x10000000
+#define bRxQuickAGCEn 0x20000000
+#define bRxAGCFreezeThresMode 0x40000000
+#define bRxOverFlowCheckType 0x80000000
+#define bRxAGCShift 0x7f
+#define bTRSW_Tri_Only 0x80
+#define bPowerThres 0x300
+#define bRxAGCEn 0x1
+#define bRxAGCTogetherEn 0x2
+#define bRxAGCMin 0x4
+#define bRxHP_Ini 0x7
+#define bRxHP_TRLNA 0x70
+#define bRxHP_RSSI 0x700
+#define bRxHP_BBP1 0x7000
+#define bRxHP_BBP2 0x70000
+#define bRxHP_BBP3 0x700000
+#define bRSSI_H 0x7f0000 /* the threshold for high power */
+#define bRSSI_Gen 0x7f000000 /* the threshold for ant divers */
+#define bRxSettle_TRSW 0x7
+#define bRxSettle_LNA 0x38
+#define bRxSettle_RSSI 0x1c0
+#define bRxSettle_BBP 0xe00
+#define bRxSettle_RxHP 0x7000
+#define bRxSettle_AntSW_RSSI 0x38000
+#define bRxSettle_AntSW 0xc0000
+#define bRxProcessTime_DAGC 0x300000
+#define bRxSettle_HSSI 0x400000
+#define bRxProcessTime_BBPPW 0x800000
+#define bRxAntennaPowerShift 0x3000000
+#define bRSSITableSelect 0xc000000
+#define bRxHP_Final 0x7000000
+#define bRxHTSettle_BBP 0x7
+#define bRxHTSettle_HSSI 0x8
+#define bRxHTSettle_RxHP 0x70
+#define bRxHTSettle_BBPPW 0x80
+#define bRxHTSettle_Idle 0x300
+#define bRxHTSettle_Reserved 0x1c00
+#define bRxHTRxHPEn 0x8000
+#define bRxHTAGCFreezeThres 0x30000
+#define bRxHTAGCTogetherEn 0x40000
+#define bRxHTAGCMin 0x80000
+#define bRxHTAGCEn 0x100000
+#define bRxHTDAGCEn 0x200000
+#define bRxHTRxHP_BBP 0x1c00000
+#define bRxHTRxHP_Final 0xe0000000
+#define bRxPWRatioTH 0x3
+#define bRxPWRatioEn 0x4
+#define bRxMFHold 0x3800
+#define bRxPD_Delay_TH1 0x38
+#define bRxPD_Delay_TH2 0x1c0
+#define bRxPD_DC_COUNT_MAX 0x600
+#define bRxPD_Delay_TH 0x8000
+#define bRxProcess_Delay 0xf0000
+#define bRxSearchrange_GI2_Early 0x700000
+#define bRxFrame_Guard_Counter_L 0x3800000
+#define bRxSGI_Guard_L 0xc000000
+#define bRxSGI_Search_L 0x30000000
+#define bRxSGI_TH 0xc0000000
+#define bDFSCnt0 0xff
+#define bDFSCnt1 0xff00
+#define bDFSFlag 0xf0000
+#define bMFWeightSum 0x300000
+#define bMinIdxTH 0x7f000000
+#define bDAFormat 0x40000
+#define bTxChEmuEnable 0x01000000
+#define bTRSWIsolation_A 0x7f
+#define bTRSWIsolation_B 0x7f00
+#define bTRSWIsolation_C 0x7f0000
+#define bTRSWIsolation_D 0x7f000000
+#define bExtLNAGain 0x7c00
+
+/* 6. PageE(0xE00) */
+#define bSTBCEn 0x4 /* Useless */
+#define bAntennaMapping 0x10
+#define bNss 0x20
+#define bCFOAntSumD 0x200
+#define bPHYCounterReset 0x8000000
+#define bCFOReportGet 0x4000000
+#define bOFDMContinueTx 0x10000000
+#define bOFDMSingleCarrier 0x20000000
+#define bOFDMSingleTone 0x40000000
+#define bHTDetect 0x100
+#define bCFOEn 0x10000
+#define bCFOValue 0xfff00000
+#define bSigTone_Re 0x3f
+#define bSigTone_Im 0x7f00
+#define bCounter_CCA 0xffff
+#define bCounter_ParityFail 0xffff0000
+#define bCounter_RateIllegal 0xffff
+#define bCounter_CRC8Fail 0xffff0000
+#define bCounter_MCSNoSupport 0xffff
+#define bCounter_FastSync 0xffff
+#define bShortCFO 0xfff
+#define bShortCFOTLength 12 /* total */
+#define bShortCFOFLength 11 /* fraction */
+#define bLongCFO 0x7ff
+#define bLongCFOTLength 11
+#define bLongCFOFLength 11
+#define bTailCFO 0x1fff
+#define bTailCFOTLength 13
+#define bTailCFOFLength 12
+#define bmax_en_pwdB 0xffff
+#define bCC_power_dB 0xffff0000
+#define bnoise_pwdB 0xffff
+#define bPowerMeasTLength 10
+#define bPowerMeasFLength 3
+#define bRx_HT_BW 0x1
+#define bRxSC 0x6
+#define bRx_HT 0x8
+#define bNB_intf_det_on 0x1
+#define bIntf_win_len_cfg 0x30
+#define bNB_Intf_TH_cfg 0x1c0
+#define bRFGain 0x3f
+#define bTableSel 0x40
+#define bTRSW 0x80
+#define bRxSNR_A 0xff
+#define bRxSNR_B 0xff00
+#define bRxSNR_C 0xff0000
+#define bRxSNR_D 0xff000000
+#define bSNREVMTLength 8
+#define bSNREVMFLength 1
+#define bCSI1st 0xff
+#define bCSI2nd 0xff00
+#define bRxEVM1st 0xff0000
+#define bRxEVM2nd 0xff000000
+#define bSIGEVM 0xff
+#define bPWDB 0xff00
+#define bSGIEN 0x10000
+
+#define bSFactorQAM1 0xf /* Useless */
+#define bSFactorQAM2 0xf0
+#define bSFactorQAM3 0xf00
+#define bSFactorQAM4 0xf000
+#define bSFactorQAM5 0xf0000
+#define bSFactorQAM6 0xf0000
+#define bSFactorQAM7 0xf00000
+#define bSFactorQAM8 0xf000000
+#define bSFactorQAM9 0xf0000000
+#define bCSIScheme 0x100000
+
+#define bNoiseLvlTopSet 0x3 /* Useless */
+#define bChSmooth 0x4
+#define bChSmoothCfg1 0x38
+#define bChSmoothCfg2 0x1c0
+#define bChSmoothCfg3 0xe00
+#define bChSmoothCfg4 0x7000
+#define bMRCMode 0x800000
+#define bTHEVMCfg 0x7000000
+
+#define bLoopFitType 0x1 /* Useless */
+#define bUpdCFO 0x40
+#define bUpdCFOOffData 0x80
+#define bAdvUpdCFO 0x100
+#define bAdvTimeCtrl 0x800
+#define bUpdClko 0x1000
+#define bFC 0x6000
+#define bTrackingMode 0x8000
+#define bPhCmpEnable 0x10000
+#define bUpdClkoLTF 0x20000
+#define bComChCFO 0x40000
+#define bCSIEstiMode 0x80000
+#define bAdvUpdEqz 0x100000
+#define bUChCfg 0x7000000
+#define bUpdEqz 0x8000000
+
+#define bTxAGCRate18_06 0x7f7f7f7f /* Useless */
+#define bTxAGCRate54_24 0x7f7f7f7f
+#define bTxAGCRateMCS32 0x7f
+#define bTxAGCRateCCK 0x7f00
+#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
+#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
+#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
+#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
+
+/* Rx Pseduo noise */
+#define bRxPesudoNoiseOn 0x20000000 /* Useless */
+#define bRxPesudoNoise_A 0xff
+#define bRxPesudoNoise_B 0xff00
+#define bRxPesudoNoise_C 0xff0000
+#define bRxPesudoNoise_D 0xff000000
+#define bPesudoNoiseState_A 0xffff
+#define bPesudoNoiseState_B 0xffff0000
+#define bPesudoNoiseState_C 0xffff
+#define bPesudoNoiseState_D 0xffff0000
+
+/* 7. RF Register
+ * Zebra1 */
+#define bZebra1_HSSIEnable 0x8 /* Useless */
+#define bZebra1_TRxControl 0xc00
+#define bZebra1_TRxGainSetting 0x07f
+#define bZebra1_RxCorner 0xc00
+#define bZebra1_TxChargePump 0x38
+#define bZebra1_RxChargePump 0x7
+#define bZebra1_ChannelNum 0xf80
+#define bZebra1_TxLPFBW 0x400
+#define bZebra1_RxLPFBW 0x600
+
+/*Zebra4 */
+#define bRTL8256RegModeCtrl1 0x100 /* Useless */
+#define bRTL8256RegModeCtrl0 0x40
+#define bRTL8256_TxLPFBW 0x18
+#define bRTL8256_RxLPFBW 0x600
+
+/* RTL8258 */
+#define bRTL8258_TxLPFBW 0xc /* Useless */
+#define bRTL8258_RxLPFBW 0xc00
+#define bRTL8258_RSSILPFBW 0xc0
+
+/*
+ * Other Definition
+ */
+
+/* byte endable for sb_write */
+#define bByte0 0x1 /* Useless */
+#define bByte1 0x2
+#define bByte2 0x4
+#define bByte3 0x8
+#define bWord0 0x3
+#define bWord1 0xc
+#define bDWord 0xf
+
+/* for PutRegsetting & GetRegSetting BitMask */
+#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */
+#define bMaskByte1 0xff00
+#define bMaskByte2 0xff0000
+#define bMaskByte3 0xff000000
+#define bMaskHWord 0xffff0000
+#define bMaskLWord 0x0000ffff
+#define bMaskDWord 0xffffffff
+
+/* for PutRFRegsetting & GetRFRegSetting BitMask */
+#define bRFRegOffsetMask 0xfffff
+#define bEnable 0x1 /* Useless */
+#define bDisable 0x0
+
+#define LeftAntenna 0x0 /* Useless */
+#define RightAntenna 0x1
+
+#define tCheckTxStatus 500 /* 500ms Useless */
+#define tUpdateRxCounter 100 /* 100ms */
+
+#define rateCCK 0 /* Useless */
+#define rateOFDM 1
+#define rateHT 2
+
+/* define Register-End */
+#define bPMAC_End 0x1ff /* Useless */
+#define bFPGAPHY0_End 0x8ff
+#define bFPGAPHY1_End 0x9ff
+#define bCCKPHY0_End 0xaff
+#define bOFDMPHY0_End 0xcff
+#define bOFDMPHY1_End 0xdff
+
+#define bPMACControl 0x0 /* Useless */
+#define bWMACControl 0x1
+#define bWNICControl 0x2
+
+#define ANTENNA_A 0x1 /* Useless */
+#define ANTENNA_B 0x2
+#define ANTENNA_AB 0x3 /* ANTENNA_A |ANTENNA_B */
+
+#define ANTENNA_C 0x4
+#define ANTENNA_D 0x8
+
+
+/* accept all physical address */
+#define RCR_AAP BIT(0)
+#define RCR_APM BIT(1) /* accept physical match */
+#define RCR_AM BIT(2) /* accept multicast */
+#define RCR_AB BIT(3) /* accept broadcast */
+#define RCR_ACRC32 BIT(5) /* accept error packet */
+#define RCR_9356SEL BIT(6)
+#define RCR_AICV BIT(12) /* Accept ICV error packet */
+#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) /* Rx FIFO threshold */
+#define RCR_ADF BIT(18) /* Accept Data(frame type) frame */
+#define RCR_ACF BIT(19) /* Accept control frame */
+#define RCR_AMF BIT(20) /* Accept management frame */
+#define RCR_ADD3 BIT(21)
+#define RCR_APWRMGT BIT(22) /* Accept power management packet */
+#define RCR_CBSSID BIT(23) /* Accept BSSID match packet */
+#define RCR_ENMARP BIT(28) /* enable mac auto reset phy */
+#define RCR_EnCS1 BIT(29) /* enable carrier sense method 1 */
+#define RCR_EnCS2 BIT(30) /* enable carrier sense method 2 */
+/* Rx Early mode is performed for packet size greater than 1536 */
+#define RCR_OnlyErlPkt BIT(31)
+
+/*--------------------------Define Parameters-------------------------------*/
+
+
+#endif /*__INC_HAL8192SPHYREG_H */
+
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
new file mode 100644
index 000000000000..9244c8a6d943
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -0,0 +1,250 @@
+/******************************************************************************
+ * rtl871x_pwrctrl.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_PWRCTRL_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "osdep_intf.h"
+
+#define RTL8712_SDIO_LOCAL_BASE 0X10100000
+#define SDIO_HCPWM (RTL8712_SDIO_LOCAL_BASE + 0x0081)
+
+void r8712_set_rpwm(struct _adapter *padapter, u8 val8)
+{
+ u8 rpwm;
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+
+ if (pwrpriv->rpwm == val8) {
+ if (pwrpriv->rpwm_retry == 0)
+ return;
+ }
+ if ((padapter->bDriverStopped == true) ||
+ (padapter->bSurpriseRemoved == true))
+ return;
+ rpwm = val8 | pwrpriv->tog;
+ switch (val8) {
+ case PS_STATE_S1:
+ pwrpriv->cpwm = val8;
+ break;
+ case PS_STATE_S2:/* only for USB normal powersave mode use,
+ * temp mark some code. */
+ case PS_STATE_S3:
+ case PS_STATE_S4:
+ pwrpriv->cpwm = val8;
+ break;
+ default:
+ break;
+ }
+ pwrpriv->rpwm_retry = 0;
+ pwrpriv->rpwm = val8;
+ r8712_write8(padapter, 0x1025FE58, rpwm);
+ pwrpriv->tog += 0x80;
+}
+
+void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, uint smart_ps)
+{
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+
+ if (ps_mode > PM_Card_Disable)
+ return;
+ /* if driver is in active state, we dont need set smart_ps.*/
+ if (ps_mode == PS_MODE_ACTIVE)
+ smart_ps = 0;
+ if ((pwrpriv->pwr_mode != ps_mode) || (pwrpriv->smart_ps != smart_ps)) {
+ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
+ pwrpriv->bSleep = true;
+ else
+ pwrpriv->bSleep = false;
+ pwrpriv->pwr_mode = ps_mode;
+ pwrpriv->smart_ps = smart_ps;
+ _set_workitem(&(pwrpriv->SetPSModeWorkItem));
+ }
+}
+
+/*
+ * Caller:ISR handler...
+ *
+ * This will be called when CPWM interrupt is up.
+ *
+ * using to update cpwn of drv; and drv willl make a decision to up or
+ * down pwr level
+ */
+void r8712_cpwm_int_hdl(struct _adapter *padapter,
+ struct reportpwrstate_parm *preportpwrstate)
+{
+ struct pwrctrl_priv *pwrpriv = &(padapter->pwrctrlpriv);
+ struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+
+ if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80))
+ return;
+ _cancel_timer_ex(&padapter->pwrctrlpriv. rpwm_check_timer);
+ _enter_pwrlock(&pwrpriv->lock);
+ pwrpriv->cpwm = (preportpwrstate->state) & 0xf;
+ if (pwrpriv->cpwm >= PS_STATE_S2) {
+ if (pwrpriv->alives & CMD_ALIVE)
+ up(&(pcmdpriv->cmd_queue_sema));
+ if (pwrpriv->alives & XMIT_ALIVE)
+ up(&(pxmitpriv->xmit_sema));
+ }
+ pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80;
+ up(&pwrpriv->lock);
+}
+
+static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag)
+{
+ pwrctrl->alives |= tag;
+}
+
+static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, uint tag)
+{
+ if (pwrctrl->alives & tag)
+ pwrctrl->alives ^= tag;
+}
+
+static void _rpwm_check_handler (struct _adapter *padapter)
+{
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+
+ if (padapter->bDriverStopped == true ||
+ padapter->bSurpriseRemoved == true)
+ return;
+ if (pwrpriv->cpwm != pwrpriv->rpwm)
+ _set_workitem(&(pwrpriv->rpwm_workitem));
+}
+
+static void SetPSModeWorkItemCallback(struct work_struct *work)
+{
+ struct pwrctrl_priv *pwrpriv = container_of(work,
+ struct pwrctrl_priv, SetPSModeWorkItem);
+ struct _adapter *padapter = container_of(pwrpriv,
+ struct _adapter, pwrctrlpriv);
+ _enter_pwrlock(&pwrpriv->lock);
+ if (!pwrpriv->bSleep) {
+ if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
+ r8712_set_rpwm(padapter, PS_STATE_S4);
+ }
+ up(&pwrpriv->lock);
+}
+
+static void rpwm_workitem_callback(struct work_struct *work)
+{
+ struct pwrctrl_priv *pwrpriv = container_of(work,
+ struct pwrctrl_priv, rpwm_workitem);
+ struct _adapter *padapter = container_of(pwrpriv,
+ struct _adapter, pwrctrlpriv);
+ u8 cpwm = pwrpriv->cpwm;
+ _enter_pwrlock(&pwrpriv->lock);
+ if (pwrpriv->cpwm != pwrpriv->rpwm) {
+ cpwm = r8712_read8(padapter, SDIO_HCPWM);
+ pwrpriv->rpwm_retry = 1;
+ r8712_set_rpwm(padapter, pwrpriv->rpwm);
+ }
+ up(&pwrpriv->lock);
+}
+
+static void rpwm_check_handler (void *FunctionContext)
+{
+ struct _adapter *adapter = (struct _adapter *)FunctionContext;
+ _rpwm_check_handler(adapter);
+}
+
+void r8712_init_pwrctrl_priv(struct _adapter *padapter)
+{
+ struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+
+ memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv));
+ sema_init(&pwrctrlpriv->lock, 1);
+ pwrctrlpriv->cpwm = PS_STATE_S4;
+ pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
+ pwrctrlpriv->smart_ps = 0;
+ pwrctrlpriv->tog = 0x80;
+/* clear RPWM to ensure driver and fw back to initial state. */
+ r8712_write8(padapter, 0x1025FE58, 0);
+ _init_workitem(&(pwrctrlpriv->SetPSModeWorkItem),
+ SetPSModeWorkItemCallback, padapter);
+ _init_workitem(&(pwrctrlpriv->rpwm_workitem),
+ rpwm_workitem_callback, padapter);
+ _init_timer(&(pwrctrlpriv->rpwm_check_timer),
+ padapter->pnetdev, rpwm_check_handler, (u8 *)padapter);
+}
+
+/*
+Caller: r8712_cmd_thread
+
+Check if the fw_pwrstate is okay for issuing cmd.
+If not (cpwm should be is less than P2 state), then the sub-routine
+will raise the cpwm to be greater than or equal to P2.
+
+Calling Context: Passive
+
+Return Value:
+
+_SUCCESS: r8712_cmd_thread can issue cmds to firmware afterwards.
+_FAIL: r8712_cmd_thread can not do anything.
+*/
+sint r8712_register_cmd_alive(struct _adapter *padapter)
+{
+ uint res = _SUCCESS;
+ struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
+
+ _enter_pwrlock(&pwrctrl->lock);
+ register_task_alive(pwrctrl, CMD_ALIVE);
+ if (pwrctrl->cpwm < PS_STATE_S2) {
+ r8712_set_rpwm(padapter, PS_STATE_S3);
+ res = _FAIL;
+ }
+ up(&pwrctrl->lock);
+ return res;
+}
+
+/*
+Caller: ISR
+
+If ISR's txdone,
+No more pkts for TX,
+Then driver shall call this fun. to power down firmware again.
+*/
+
+void r8712_unregister_cmd_alive(struct _adapter *padapter)
+{
+ struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
+
+ _enter_pwrlock(&pwrctrl->lock);
+ unregister_task_alive(pwrctrl, CMD_ALIVE);
+ if ((pwrctrl->cpwm > PS_STATE_S2) &&
+ (pwrctrl->pwr_mode > PS_MODE_ACTIVE)) {
+ if ((pwrctrl->alives == 0) &&
+ (check_fwstate(&padapter->mlmepriv,
+ _FW_UNDER_LINKING) != true)) {
+ r8712_set_rpwm(padapter, PS_STATE_S0);
+ }
+ }
+ up(&pwrctrl->lock);
+}
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
new file mode 100644
index 000000000000..34f074aebd69
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -0,0 +1,127 @@
+#ifndef __RTL871X_PWRCTRL_H_
+#define __RTL871X_PWRCTRL_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+
+#define FW_PWR0 0
+#define FW_PWR1 1
+#define FW_PWR2 2
+#define FW_PWR3 3
+
+
+#define HW_PWR0 7
+#define HW_PWR1 6
+#define HW_PWR2 2
+#define HW_PWR3 0
+#define HW_PWR4 8
+
+#define FW_PWRMSK 0x7
+
+
+#define XMIT_ALIVE BIT(0)
+#define RECV_ALIVE BIT(1)
+#define CMD_ALIVE BIT(2)
+#define EVT_ALIVE BIT(3)
+
+
+enum Power_Mgnt {
+ PS_MODE_ACTIVE = 0 ,
+ PS_MODE_MIN ,
+ PS_MODE_MAX ,
+ PS_MODE_DTIM ,
+ PS_MODE_VOIP ,
+ PS_MODE_UAPSD_WMM ,
+ PS_MODE_UAPSD ,
+ PS_MODE_IBSS ,
+ PS_MODE_WWLAN ,
+ PM_Radio_Off ,
+ PM_Card_Disable ,
+ PS_MODE_NUM
+};
+
+
+/*
+ BIT[2:0] = HW state
+ BIT[3] = Protocol PS state, 0: register active state,
+ 1: register sleep state
+ BIT[4] = sub-state
+*/
+
+#define PS_DPS BIT(0)
+#define PS_LCLK (PS_DPS)
+#define PS_RF_OFF BIT(1)
+#define PS_ALL_ON BIT(2)
+#define PS_ST_ACTIVE BIT(3)
+#define PS_LP BIT(4) /* low performance */
+
+#define PS_STATE_MASK (0x0F)
+#define PS_STATE_HW_MASK (0x07)
+#define PS_SEQ_MASK (0xc0)
+
+#define PS_STATE(x) (PS_STATE_MASK & (x))
+#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x))
+#define PS_SEQ(x) (PS_SEQ_MASK & (x))
+
+#define PS_STATE_S0 (PS_DPS)
+#define PS_STATE_S1 (PS_LCLK)
+#define PS_STATE_S2 (PS_RF_OFF)
+#define PS_STATE_S3 (PS_ALL_ON)
+#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON))
+
+
+#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON))
+#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE))
+#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
+
+
+struct reportpwrstate_parm {
+ unsigned char mode;
+ unsigned char state; /* the CPWM value */
+ unsigned short rsvd;
+};
+
+static inline void _enter_pwrlock(struct semaphore *plock)
+{
+ _down_sema(plock);
+}
+
+struct pwrctrl_priv {
+ struct semaphore lock;
+ /*volatile*/ u8 rpwm; /* requested power state for fw */
+ /* fw current power state. updated when 1. read from HCPWM or
+ * 2. driver lowers power level */
+ /*volatile*/ u8 cpwm;
+ /*volatile*/ u8 tog; /* toggling */
+ /*volatile*/ u8 cpwm_tog; /* toggling */
+ /*volatile*/ u8 tgt_rpwm; /* wanted power state */
+ uint pwr_mode;
+ uint smart_ps;
+ uint alives;
+ uint ImrContent; /* used to store original imr. */
+ uint bSleep; /* sleep -> active is different from active -> sleep. */
+
+ _workitem SetPSModeWorkItem;
+ _workitem rpwm_workitem;
+ struct timer_list rpwm_check_timer;
+ u8 rpwm_retry;
+ uint bSetPSModeWorkItemInProgress;
+
+ struct semaphore pnp_pwr_mgnt_sema;
+ spinlock_t pnp_pwr_mgnt_lock;
+ s32 pnp_current_pwr_state;
+ u8 pnp_bstop_trx;
+ u8 pnp_wwirp_pending;
+};
+
+void r8712_init_pwrctrl_priv(struct _adapter *adapter);
+sint r8712_register_cmd_alive(struct _adapter *padapter);
+void r8712_unregister_cmd_alive(struct _adapter *padapter);
+void r8712_cpwm_int_hdl(struct _adapter *padapter,
+ struct reportpwrstate_parm *preportpwrstate);
+void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode,
+ uint smart_ps);
+void r8712_set_rpwm(struct _adapter *padapter, u8 val8);
+
+#endif /* __RTL871X_PWRCTRL_H_ */
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
new file mode 100644
index 000000000000..a3165e67f857
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -0,0 +1,693 @@
+/******************************************************************************
+ * rtl871x_recv.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_RECV_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "mlme_osdep.h"
+#include "ip.h"
+#include "if_ether.h"
+#include "ethernet.h"
+#include "usb_ops.h"
+#include "wifi.h"
+
+static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
+
+/* Datagram Delivery Protocol */
+static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
+
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+static const u8 bridge_tunnel_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+static const u8 rfc1042_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+
+void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
+{
+ memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
+ spin_lock_init(&psta_recvpriv->lock);
+ _init_queue(&psta_recvpriv->defrag_q);
+}
+
+sint _r8712_init_recv_priv(struct recv_priv *precvpriv,
+ struct _adapter *padapter)
+{
+ sint i;
+ union recv_frame *precvframe;
+
+ memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv));
+ spin_lock_init(&precvpriv->lock);
+ _init_queue(&precvpriv->free_recv_queue);
+ _init_queue(&precvpriv->recv_pending_queue);
+ precvpriv->adapter = padapter;
+ precvpriv->free_recvframe_cnt = NR_RECVFRAME;
+ precvpriv->pallocated_frame_buf = _malloc(NR_RECVFRAME *
+ sizeof(union recv_frame) +
+ RXFRAME_ALIGN_SZ);
+ if (precvpriv->pallocated_frame_buf == NULL)
+ return _FAIL;
+ memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME *
+ sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
+ precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf +
+ RXFRAME_ALIGN_SZ -
+ ((addr_t)(precvpriv->pallocated_frame_buf) &
+ (RXFRAME_ALIGN_SZ-1));
+ precvframe = (union recv_frame *)precvpriv->precv_frame_buf;
+ for (i = 0; i < NR_RECVFRAME; i++) {
+ _init_listhead(&(precvframe->u.list));
+ list_insert_tail(&(precvframe->u.list),
+ &(precvpriv->free_recv_queue.queue));
+ r8712_os_recv_resource_alloc(padapter, precvframe);
+ precvframe->u.hdr.adapter = padapter;
+ precvframe++;
+ }
+ precvpriv->rx_pending_cnt = 1;
+ sema_init(&precvpriv->allrxreturnevt, 0);
+ return r8712_init_recv_priv(precvpriv, padapter);
+}
+
+void _r8712_free_recv_priv(struct recv_priv *precvpriv)
+{
+ kfree(precvpriv->pallocated_frame_buf);
+ r8712_free_recv_priv(precvpriv);
+}
+
+union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue)
+{
+ unsigned long irqL;
+ union recv_frame *precvframe;
+ struct list_head *plist, *phead;
+ struct _adapter *padapter;
+ struct recv_priv *precvpriv;
+
+ spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
+ if (_queue_empty(pfree_recv_queue) == true)
+ precvframe = NULL;
+ else {
+ phead = get_list_head(pfree_recv_queue);
+ plist = get_next(phead);
+ precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ list_delete(&precvframe->u.hdr.list);
+ padapter = precvframe->u.hdr.adapter;
+ if (padapter != NULL) {
+ precvpriv = &padapter->recvpriv;
+ if (pfree_recv_queue == &precvpriv->free_recv_queue)
+ precvpriv->free_recvframe_cnt--;
+ }
+ }
+ spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL);
+ return precvframe;
+}
+
+/*
+caller : defrag; recvframe_chk_defrag in recv_thread (passive)
+pframequeue: defrag_queue : will be accessed in recv_thread (passive)
+
+using spin_lock to protect
+
+*/
+
+void r8712_free_recvframe_queue(struct __queue *pframequeue,
+ struct __queue *pfree_recv_queue)
+{
+ union recv_frame *precvframe;
+ struct list_head *plist, *phead;
+
+ spin_lock(&pframequeue->lock);
+ phead = get_list_head(pframequeue);
+ plist = get_next(phead);
+ while (end_of_queue_search(phead, plist) == false) {
+ precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
+ plist = get_next(plist);
+ r8712_free_recvframe(precvframe, pfree_recv_queue);
+ }
+ spin_unlock(&pframequeue->lock);
+}
+
+sint r8712_recvframe_chkmic(struct _adapter *adapter,
+ union recv_frame *precvframe)
+{
+ sint i, res = _SUCCESS;
+ u32 datalen;
+ u8 miccode[8];
+ u8 bmic_err = false;
+ u8 *pframe, *payload, *pframemic;
+ u8 *mickey, idx, *iv;
+ struct sta_info *stainfo;
+ struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+
+ stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
+ if (prxattrib->encrypt == _TKIP_) {
+ /* calculate mic code */
+ if (stainfo != NULL) {
+ if (IS_MCAST(prxattrib->ra)) {
+ iv = precvframe->u.hdr.rx_data +
+ prxattrib->hdrlen;
+ idx = iv[3];
+ mickey = &psecuritypriv->XGrprxmickey[(((idx >>
+ 6) & 0x3)) - 1].skey[0];
+ if (psecuritypriv->binstallGrpkey == false)
+ return _FAIL;
+ } else
+ mickey = &stainfo->tkiprxmickey.skey[0];
+ /*icv_len included the mic code*/
+ datalen = precvframe->u.hdr.len - prxattrib->hdrlen -
+ prxattrib->iv_len - prxattrib->icv_len - 8;
+ pframe = precvframe->u.hdr.rx_data;
+ payload = pframe + prxattrib->hdrlen +
+ prxattrib->iv_len;
+ seccalctkipmic(mickey, pframe, payload, datalen,
+ &miccode[0],
+ (unsigned char)prxattrib->priority);
+ pframemic = payload + datalen;
+ bmic_err = false;
+ for (i = 0; i < 8; i++) {
+ if (miccode[i] != *(pframemic + i))
+ bmic_err = true;
+ }
+ if (bmic_err == true) {
+ if (prxattrib->bdecrypted == true)
+ r8712_handle_tkip_mic_err(adapter,
+ (u8)IS_MCAST(prxattrib->ra));
+ res = _FAIL;
+ } else {
+ /* mic checked ok */
+ if ((psecuritypriv->bcheck_grpkey ==
+ false) && (IS_MCAST(prxattrib->ra) ==
+ true))
+ psecuritypriv->bcheck_grpkey = true;
+ }
+ recvframe_pull_tail(precvframe, 8);
+ }
+ }
+ return res;
+}
+
+/* decrypt and set the ivlen,icvlen of the recv_frame */
+union recv_frame *r8712_decryptor(struct _adapter *padapter,
+ union recv_frame *precv_frame)
+{
+ struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ union recv_frame *return_packet = precv_frame;
+
+ if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) ||
+ (psecuritypriv->sw_decrypt == true))) {
+ psecuritypriv->hw_decrypted = false;
+ switch (prxattrib->encrypt) {
+ case _WEP40_:
+ case _WEP104_:
+ r8712_wep_decrypt(padapter, (u8 *)precv_frame);
+ break;
+ case _TKIP_:
+ r8712_tkip_decrypt(padapter, (u8 *)precv_frame);
+ break;
+ case _AES_:
+ r8712_aes_decrypt(padapter, (u8 *)precv_frame);
+ break;
+ default:
+ break;
+ }
+ } else if (prxattrib->bdecrypted == 1)
+ psecuritypriv->hw_decrypted = true;
+ return return_packet;
+}
+/*###set the security information in the recv_frame */
+union recv_frame *r8712_portctrl(struct _adapter *adapter,
+ union recv_frame *precv_frame)
+{
+ u8 *psta_addr, *ptr;
+ uint auth_alg;
+ struct recv_frame_hdr *pfhdr;
+ struct sta_info *psta;
+ struct sta_priv *pstapriv;
+ union recv_frame *prtnframe;
+ u16 ether_type = 0;
+
+ pstapriv = &adapter->stapriv;
+ ptr = get_recvframe_data(precv_frame);
+ pfhdr = &precv_frame->u.hdr;
+ psta_addr = pfhdr->attrib.ta;
+ psta = r8712_get_stainfo(pstapriv, psta_addr);
+ auth_alg = adapter->securitypriv.AuthAlgrthm;
+ if (auth_alg == 2) {
+ if ((psta != NULL) && (psta->ieee8021x_blocked)) {
+ /* blocked
+ * only accept EAPOL frame */
+ prtnframe = precv_frame;
+ /*get ether_type */
+ ptr = ptr + pfhdr->attrib.hdrlen +
+ pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
+ memcpy(&ether_type, ptr, 2);
+ ether_type = ntohs((unsigned short)ether_type);
+ if (ether_type == 0x888e)
+ prtnframe = precv_frame;
+ else {
+ /*free this frame*/
+ r8712_free_recvframe(precv_frame,
+ &adapter->recvpriv.free_recv_queue);
+ prtnframe = NULL;
+ }
+ } else {
+ /* allowed
+ * check decryption status, and decrypt the
+ * frame if needed */
+ prtnframe = precv_frame;
+ /* check is the EAPOL frame or not (Rekey) */
+ if (ether_type == 0x888e) {
+ /* check Rekey */
+ prtnframe = precv_frame;
+ }
+ }
+ } else
+ prtnframe = precv_frame;
+ return prtnframe;
+}
+
+static sint recv_decache(union recv_frame *precv_frame, u8 bretry,
+ struct stainfo_rxcache *prxcache)
+{
+ sint tid = precv_frame->u.hdr.attrib.priority;
+ u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
+ (precv_frame->u.hdr.attrib.frag_num & 0xf);
+
+ if (tid > 15)
+ return _FAIL;
+ if (seq_ctrl == prxcache->tid_rxseq[tid])
+ return _FAIL;
+ prxcache->tid_rxseq[tid] = seq_ctrl;
+ return _SUCCESS;
+}
+
+static sint sta2sta_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
+ struct sta_info **psta
+)
+{
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ sint ret = _SUCCESS;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ u8 *mybssid = get_bssid(pmlmepriv);
+ u8 *myhwaddr = myid(&adapter->eeprompriv);
+ u8 *sta_addr = NULL;
+ sint bmcast = IS_MCAST(pattrib->dst);
+
+ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
+ /* filter packets that SA is myself or multicast or broadcast */
+ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
+ return _FAIL;
+ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
+ return _FAIL;
+ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
+ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
+ (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
+ return _FAIL;
+ sta_addr = pattrib->src;
+ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
+ /* For Station mode, sa and bssid should always be BSSID,
+ * and DA is my mac-address */
+ if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN))
+ return _FAIL;
+ sta_addr = pattrib->bssid;
+ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+ if (bmcast) {
+ /* For AP mode, if DA == MCAST, then BSSID should
+ * be also MCAST */
+ if (!IS_MCAST(pattrib->bssid))
+ return _FAIL;
+ } else { /* not mc-frame */
+ /* For AP mode, if DA is non-MCAST, then it must be
+ * BSSID, and bssid == BSSID */
+ if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN))
+ return _FAIL;
+ sta_addr = pattrib->src;
+ }
+ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
+ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
+ memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ sta_addr = mybssid;
+ } else
+ ret = _FAIL;
+ if (bmcast)
+ *psta = r8712_get_bcmc_stainfo(adapter);
+ else
+ *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */
+ if (*psta == NULL) {
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
+ adapter->mppriv.rx_pktloss++;
+ return _FAIL;
+ }
+ return ret;
+}
+
+static sint ap2sta_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
+ struct sta_info **psta)
+{
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ u8 *mybssid = get_bssid(pmlmepriv);
+ u8 *myhwaddr = myid(&adapter->eeprompriv);
+ sint bmcast = IS_MCAST(pattrib->dst);
+
+ if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+ && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ /* if NULL-frame, drop packet */
+ if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL)
+ return _FAIL;
+ /* drop QoS-SubType Data, including QoS NULL,
+ * excluding QoS-Data */
+ if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) ==
+ WIFI_QOS_DATA_TYPE) {
+ if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6)))
+ return _FAIL;
+ }
+
+ /* filter packets that SA is myself or multicast or broadcast */
+ if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
+ return _FAIL;
+
+ /* da should be for me */
+ if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
+ return _FAIL;
+ /* check BSSID */
+ if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
+ !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
+ (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
+ return _FAIL;
+ if (bmcast)
+ *psta = r8712_get_bcmc_stainfo(adapter);
+ else
+ *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
+ if (*psta == NULL)
+ return _FAIL;
+ } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) &&
+ (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
+ memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
+ memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ memcpy(pattrib->bssid, mybssid, ETH_ALEN);
+ *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
+ if (*psta == NULL)
+ return _FAIL;
+ } else
+ return _FAIL;
+ return _SUCCESS;
+}
+
+static sint sta2ap_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
+ struct sta_info **psta)
+{
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ unsigned char *mybssid = get_bssid(pmlmepriv);
+
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+ /* For AP mode, if DA is non-MCAST, then it must be BSSID,
+ * and bssid == BSSID
+ * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
+ if (memcmp(pattrib->bssid, mybssid, ETH_ALEN))
+ return _FAIL;
+ *psta = r8712_get_stainfo(pstapriv, pattrib->src);
+ if (*psta == NULL)
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
+
+static sint validate_recv_ctrl_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame)
+{
+ return _FAIL;
+}
+
+static sint validate_recv_mgnt_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame)
+{
+ return _FAIL;
+}
+
+
+static sint validate_recv_data_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame)
+{
+ int res;
+ u8 bretry;
+ u8 *psa, *pda, *pbssid;
+ struct sta_info *psta = NULL;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+
+ bretry = GetRetry(ptr);
+ pda = get_da(ptr);
+ psa = get_sa(ptr);
+ pbssid = get_hdr_bssid(ptr);
+ if (pbssid == NULL)
+ return _FAIL;
+ memcpy(pattrib->dst, pda, ETH_ALEN);
+ memcpy(pattrib->src, psa, ETH_ALEN);
+ memcpy(pattrib->bssid, pbssid, ETH_ALEN);
+ switch (pattrib->to_fr_ds) {
+ case 0:
+ memcpy(pattrib->ra, pda, ETH_ALEN);
+ memcpy(pattrib->ta, psa, ETH_ALEN);
+ res = sta2sta_data_frame(adapter, precv_frame, &psta);
+ break;
+ case 1:
+ memcpy(pattrib->ra, pda, ETH_ALEN);
+ memcpy(pattrib->ta, pbssid, ETH_ALEN);
+ res = ap2sta_data_frame(adapter, precv_frame, &psta);
+ break;
+ case 2:
+ memcpy(pattrib->ra, pbssid, ETH_ALEN);
+ memcpy(pattrib->ta, psa, ETH_ALEN);
+ res = sta2ap_data_frame(adapter, precv_frame, &psta);
+ break;
+ case 3:
+ memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
+ memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
+ return _FAIL;
+ default:
+ return _FAIL;
+ }
+ if (res == _FAIL)
+ return _FAIL;
+ if (psta == NULL)
+ return _FAIL;
+ else
+ precv_frame->u.hdr.psta = psta;
+ pattrib->amsdu = 0;
+ /* parsing QC field */
+ if (pattrib->qos == 1) {
+ pattrib->priority = GetPriority((ptr + 24));
+ pattrib->ack_policy = GetAckpolicy((ptr + 24));
+ pattrib->amsdu = GetAMsdu((ptr + 24));
+ pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
+ } else {
+ pattrib->priority = 0;
+ pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24;
+ }
+
+ if (pattrib->order)/*HT-CTRL 11n*/
+ pattrib->hdrlen += 4;
+ precv_frame->u.hdr.preorder_ctrl =
+ &psta->recvreorder_ctrl[pattrib->priority];
+
+ /* decache, drop duplicate recv packets */
+ if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
+ _FAIL)
+ return _FAIL;
+
+ if (pattrib->privacy) {
+ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
+ IS_MCAST(pattrib->ra));
+ SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len,
+ pattrib->encrypt);
+ } else {
+ pattrib->encrypt = 0;
+ pattrib->iv_len = pattrib->icv_len = 0;
+ }
+ return _SUCCESS;
+}
+
+sint r8712_validate_recv_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame)
+{
+ /*shall check frame subtype, to / from ds, da, bssid */
+ /*then call check if rx seq/frag. duplicated.*/
+
+ u8 type;
+ u8 subtype;
+ sint retval = _SUCCESS;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ u8 ver = (unsigned char)(*ptr) & 0x3;
+
+ /*add version chk*/
+ if (ver != 0)
+ return _FAIL;
+ type = GetFrameType(ptr);
+ subtype = GetFrameSubType(ptr); /*bit(7)~bit(2)*/
+ pattrib->to_fr_ds = get_tofr_ds(ptr);
+ pattrib->frag_num = GetFragNum(ptr);
+ pattrib->seq_num = GetSequence(ptr);
+ pattrib->pw_save = GetPwrMgt(ptr);
+ pattrib->mfrag = GetMFrag(ptr);
+ pattrib->mdata = GetMData(ptr);
+ pattrib->privacy = GetPrivacy(ptr);
+ pattrib->order = GetOrder(ptr);
+ switch (type) {
+ case WIFI_MGT_TYPE: /*mgnt*/
+ retval = validate_recv_mgnt_frame(adapter, precv_frame);
+ break;
+ case WIFI_CTRL_TYPE:/*ctrl*/
+ retval = validate_recv_ctrl_frame(adapter, precv_frame);
+ break;
+ case WIFI_DATA_TYPE: /*data*/
+ pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
+ retval = validate_recv_data_frame(adapter, precv_frame);
+ break;
+ default:
+ return _FAIL;
+ }
+ return retval;
+}
+
+sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
+{
+ /*remove the wlanhdr and add the eth_hdr*/
+ sint rmv_len;
+ u16 eth_type, len;
+ u8 bsnaphdr;
+ u8 *psnap_type;
+ struct ieee80211_snap_hdr *psnap;
+
+ sint ret = _SUCCESS;
+ struct _adapter *adapter = precvframe->u.hdr.adapter;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+
+ u8 *ptr = get_recvframe_data(precvframe); /*point to frame_ctrl field*/
+ struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
+
+ if (pattrib->encrypt)
+ recvframe_pull_tail(precvframe, pattrib->icv_len);
+ psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen +
+ pattrib->iv_len);
+ psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
+ /* convert hdr + possible LLC headers into Ethernet header */
+ if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) &&
+ (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) &&
+ (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
+ !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) {
+ /* remove RFC1042 or Bridge-Tunnel encapsulation and
+ * replace EtherType */
+ bsnaphdr = true;
+ } else {
+ /* Leave Ethernet header part of hdr and full payload */
+ bsnaphdr = false;
+ }
+ rmv_len = pattrib->hdrlen + pattrib->iv_len +
+ (bsnaphdr ? SNAP_SIZE : 0);
+ len = precvframe->u.hdr.len - rmv_len;
+ if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) {
+ ptr += rmv_len;
+ *ptr = 0x87;
+ *(ptr+1) = 0x12;
+ eth_type = 0x8712;
+ /* append rx status for mp test packets */
+ ptr = recvframe_pull(precvframe, (rmv_len -
+ sizeof(struct ethhdr) + 2) - 24);
+ memcpy(ptr, get_rxmem(precvframe), 24);
+ ptr += 24;
+ } else
+ ptr = recvframe_pull(precvframe, (rmv_len -
+ sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+
+ memcpy(ptr, pattrib->dst, ETH_ALEN);
+ memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
+ if (!bsnaphdr) {
+ len = htons(len);
+ memcpy(ptr + 12, &len, 2);
+ }
+ return ret;
+}
+
+s32 r8712_recv_entry(union recv_frame *precvframe)
+{
+ struct _adapter *padapter;
+ struct recv_priv *precvpriv;
+ struct mlme_priv *pmlmepriv;
+ struct recv_stat *prxstat;
+ struct dvobj_priv *pdev;
+ u8 *phead, *pdata, *ptail, *pend;
+
+ struct __queue *pfree_recv_queue, *ppending_recv_queue;
+ s32 ret = _SUCCESS;
+ struct intf_hdl *pintfhdl;
+
+ padapter = precvframe->u.hdr.adapter;
+ pintfhdl = &padapter->pio_queue->intf;
+ pmlmepriv = &padapter->mlmepriv;
+ precvpriv = &(padapter->recvpriv);
+ pdev = &padapter->dvobjpriv;
+ pfree_recv_queue = &(precvpriv->free_recv_queue);
+ ppending_recv_queue = &(precvpriv->recv_pending_queue);
+ phead = precvframe->u.hdr.rx_head;
+ pdata = precvframe->u.hdr.rx_data;
+ ptail = precvframe->u.hdr.rx_tail;
+ pend = precvframe->u.hdr.rx_end;
+ prxstat = (struct recv_stat *)phead;
+
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX);
+
+ ret = recv_func(padapter, precvframe);
+ if (ret == _FAIL)
+ goto _recv_entry_drop;
+ precvpriv->rx_pkts++;
+ precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail -
+ precvframe->u.hdr.rx_data);
+ return ret;
+_recv_entry_drop:
+ precvpriv->rx_drop++;
+ padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
+ return ret;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h
new file mode 100644
index 000000000000..bf8115dbcb61
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_recv.h
@@ -0,0 +1,330 @@
+#ifndef _RTL871X_RECV_H_
+#define _RTL871X_RECV_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+#define NR_RECVFRAME 256
+
+#define RXFRAME_ALIGN 8
+#define RXFRAME_ALIGN_SZ (1 << RXFRAME_ALIGN)
+
+#define MAX_RXFRAME_CNT 512
+#define MAX_RX_NUMBLKS (32)
+#define RECVFRAME_HDR_ALIGN 128
+#define MAX_SUBFRAME_COUNT 64
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+/* for Rx reordering buffer control */
+struct recv_reorder_ctrl {
+ struct _adapter *padapter;
+ u16 indicate_seq;/* =wstart_b, init_value=0xffff */
+ u16 wend_b;
+ u8 wsize_b;
+ struct __queue pending_recvframe_queue;
+ struct timer_list reordering_ctrl_timer;
+};
+
+struct stainfo_rxcache {
+ u16 tid_rxseq[16];
+};
+
+#define PHY_RSSI_SLID_WIN_MAX 100
+#define PHY_LINKQUALITY_SLID_WIN_MAX 20
+
+
+struct smooth_rssi_data {
+ u32 elements[100]; /* array to store values */
+ u32 index; /* index to current array to store */
+ u32 total_num; /* num of valid elements */
+ u32 total_val; /* sum of valid elements */
+};
+
+struct rx_pkt_attrib {
+
+ u8 amsdu;
+ u8 order;
+ u8 qos;
+ u8 to_fr_ds;
+ u8 frag_num;
+ u16 seq_num;
+ u8 pw_save;
+ u8 mfrag;
+ u8 mdata;
+ u8 privacy; /* in frame_ctrl field */
+ u8 bdecrypted;
+ int hdrlen; /* the WLAN Header Len */
+ int encrypt; /* 0 no encrypt. != 0 encrypt algorith */
+ int iv_len;
+ int icv_len;
+ int priority;
+ int ack_policy;
+ u8 crc_err;
+ u8 dst[ETH_ALEN];
+ u8 src[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+ u8 ra[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ u8 tcpchk_valid; /* 0: invalid, 1: valid */
+ u8 ip_chkrpt; /* 0: incorrect, 1: correct */
+ u8 tcp_chkrpt; /* 0: incorrect, 1: correct */
+ u8 signal_qual;
+ s8 rx_mimo_signal_qual[2];
+ u8 mcs_rate;
+ u8 htc;
+ u8 signal_strength;
+};
+
+/*
+accesser of recv_priv: recv_entry(dispatch / passive level);
+recv_thread(passive) ; returnpkt(dispatch)
+; halt(passive) ;
+
+using enter_critical section to protect
+*/
+struct recv_priv {
+ spinlock_t lock;
+ struct semaphore recv_sema;
+ struct semaphore terminate_recvthread_sema;
+ struct __queue free_recv_queue;
+ struct __queue recv_pending_queue;
+ u8 *pallocated_frame_buf;
+ u8 *precv_frame_buf;
+ uint free_recvframe_cnt;
+ struct _adapter *adapter;
+ uint rx_bytes;
+ uint rx_pkts;
+ uint rx_drop;
+ uint rx_icv_err;
+ uint rx_largepacket_crcerr;
+ uint rx_smallpacket_crcerr;
+ uint rx_middlepacket_crcerr;
+ struct semaphore allrxreturnevt;
+ u8 rx_pending_cnt;
+ uint ff_hwaddr;
+ struct tasklet_struct recv_tasklet;
+ struct sk_buff_head free_recv_skb_queue;
+ struct sk_buff_head rx_skb_queue;
+ u8 *pallocated_recv_buf;
+ u8 *precv_buf; /* 4 alignment */
+ struct __queue free_recv_buf_queue;
+ u32 free_recv_buf_queue_cnt;
+ /* For the phy informatiom */
+ s8 rssi;
+ u8 signal;
+ u8 noise;
+ u8 fw_rssi;
+ struct smooth_rssi_data signal_qual_data;
+ struct smooth_rssi_data signal_strength_data;
+};
+
+struct sta_recv_priv {
+ spinlock_t lock;
+ sint option;
+ struct __queue defrag_q; /* keeping the fragment frame until defrag */
+ struct stainfo_rxcache rxcache;
+ uint sta_rx_bytes;
+ uint sta_rx_pkts;
+ uint sta_rx_fail;
+};
+
+#include "rtl8712_recv.h"
+
+/* get a free recv_frame from pfree_recv_queue */
+union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue);
+union recv_frame *r8712_dequeue_recvframe(struct __queue *queue);
+int r8712_enqueue_recvframe(union recv_frame *precvframe,
+ struct __queue *queue);
+int r8712_free_recvframe(union recv_frame *precvframe,
+ struct __queue *pfree_recv_queue);
+void r8712_free_recvframe_queue(struct __queue *pframequeue,
+ struct __queue *pfree_recv_queue);
+void r8712_init_recvframe(union recv_frame *precvframe,
+ struct recv_priv *precvpriv);
+int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe);
+int recv_func(struct _adapter *padapter, void *pcontext);
+
+static inline u8 *get_rxmem(union recv_frame *precvframe)
+{
+ /* always return rx_head... */
+ if (precvframe == NULL)
+ return NULL;
+ return precvframe->u.hdr.rx_head;
+}
+
+static inline u8 *get_rx_status(union recv_frame *precvframe)
+{
+ return get_rxmem(precvframe);
+}
+
+static inline u8 *get_recvframe_data(union recv_frame *precvframe)
+{
+ /* always return rx_data */
+ if (precvframe == NULL)
+ return NULL;
+ return precvframe->u.hdr.rx_data;
+}
+
+static inline u8 *recvframe_push(union recv_frame *precvframe, sint sz)
+{
+ /* append data before rx_data */
+
+ /* add data to the start of recv_frame
+ *
+ * This function extends the used data area of the recv_frame at the
+ * buffer start. rx_data must be still larger than rx_head, after
+ * pushing.
+ */
+
+ if (precvframe == NULL)
+ return NULL;
+ precvframe->u.hdr.rx_data -= sz ;
+ if (precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head) {
+ precvframe->u.hdr.rx_data += sz ;
+ return NULL;
+ }
+ precvframe->u.hdr.len += sz;
+ return precvframe->u.hdr.rx_data;
+}
+
+static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz)
+{
+ /* used for extract sz bytes from rx_data, update rx_data and return
+ * the updated rx_data to the caller */
+ if (precvframe == NULL)
+ return NULL;
+ precvframe->u.hdr.rx_data += sz;
+ if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) {
+ precvframe->u.hdr.rx_data -= sz;
+ return NULL;
+ }
+ precvframe->u.hdr.len -= sz;
+ return precvframe->u.hdr.rx_data;
+}
+
+static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz)
+{
+ /* used for append sz bytes from ptr to rx_tail, update rx_tail and
+ * return the updated rx_tail to the caller
+ * after putting, rx_tail must be still larger than rx_end. */
+ unsigned char *prev_rx_tail;
+
+ if (precvframe == NULL)
+ return NULL;
+ prev_rx_tail = precvframe->u.hdr.rx_tail;
+ precvframe->u.hdr.rx_tail += sz;
+ if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) {
+ precvframe->u.hdr.rx_tail -= sz;
+ return NULL;
+ }
+ precvframe->u.hdr.len += sz;
+ return precvframe->u.hdr.rx_tail;
+}
+
+static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz)
+{
+ /* rmv data from rx_tail (by yitsen)
+ * used for extract sz bytes from rx_end, update rx_end and return the
+ * updated rx_end to the caller
+ * after pulling, rx_end must be still larger than rx_data. */
+ if (precvframe == NULL)
+ return NULL;
+ precvframe->u.hdr.rx_tail -= sz;
+ if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) {
+ precvframe->u.hdr.rx_tail += sz;
+ return NULL;
+ }
+ precvframe->u.hdr.len -= sz;
+ return precvframe->u.hdr.rx_tail;
+}
+
+static inline _buffer *get_rxbuf_desc(union recv_frame *precvframe)
+{
+ _buffer *buf_desc;
+ if (precvframe == NULL)
+ return NULL;
+ return buf_desc;
+}
+
+static inline union recv_frame *rxmem_to_recvframe(u8 *rxmem)
+{
+ /* due to the design of 2048 bytes alignment of recv_frame, we can
+ * reference the union recv_frame from any given member of recv_frame.
+ * rxmem indicates the any member/address in recv_frame */
+ return (union recv_frame *)(((addr_t)rxmem >> RXFRAME_ALIGN) <<
+ RXFRAME_ALIGN);
+}
+
+static inline union recv_frame *pkt_to_recvframe(_pkt *pkt)
+{
+ u8 *buf_star;
+ union recv_frame *precv_frame;
+
+ precv_frame = rxmem_to_recvframe((unsigned char *)buf_star);
+ return precv_frame;
+}
+
+static inline u8 *pkt_to_recvmem(_pkt *pkt)
+{
+ /* return the rx_head */
+ union recv_frame *precv_frame = pkt_to_recvframe(pkt);
+
+ return precv_frame->u.hdr.rx_head;
+}
+
+static inline u8 *pkt_to_recvdata(_pkt *pkt)
+{
+ /* return the rx_data */
+ union recv_frame *precv_frame = pkt_to_recvframe(pkt);
+
+ return precv_frame->u.hdr.rx_data;
+}
+
+static inline sint get_recvframe_len(union recv_frame *precvframe)
+{
+ return precvframe->u.hdr.len;
+}
+
+struct sta_info;
+
+void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
+sint r8712_recvframe_chkmic(struct _adapter *adapter,
+ union recv_frame *precvframe);
+union recv_frame *r8712_decryptor(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+union recv_frame *r8712_recvframe_defrag(struct _adapter *adapter,
+ struct __queue *defrag_q);
+union recv_frame *r8712_recvframe_chk_defrag_new(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+union recv_frame *r8712_recvframe_defrag_new(struct _adapter *adapter,
+ struct __queue *defrag_q,
+ union recv_frame *precv_frame);
+int r8712_recv_decache(union recv_frame *precv_frame, u8 bretry,
+ struct stainfo_rxcache *prxcache);
+int r8712_sta2sta_data_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame,
+ struct sta_info **psta);
+int r8712_ap2sta_data_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame,
+ struct sta_info **psta);
+int r8712_sta2ap_data_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame,
+ struct sta_info **psta);
+int r8712_validate_recv_ctrl_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+int r8712_validate_recv_mgnt_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+int r8712_validate_recv_data_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+int r8712_validate_recv_frame(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+union recv_frame *r8712_portctrl(struct _adapter *adapter,
+ union recv_frame *precv_frame);
+void r8712_mgt_dispatcher(struct _adapter *padapter, u8 *pframe, uint len);
+int r8712_amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_rf.h b/drivers/staging/rtl8712/rtl871x_rf.h
new file mode 100644
index 000000000000..c709d8cadf0c
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_rf.h
@@ -0,0 +1,43 @@
+#ifndef __RTL871X_RF_H_
+#define __RTL871X_RF_H_
+
+#include "rtl871x_cmd.h"
+#include "rtl871x_mp_phy_regdef.h"
+
+#define OFDM_PHY 1
+#define MIXED_PHY 2
+#define CCK_PHY 3
+#define NumRates (13)
+#define RTL8711_RF_MAX_SENS 6
+#define RTL8711_RF_DEF_SENS 4
+#define NUM_CHANNELS 15
+
+struct regulatory_class {
+ u32 starting_freq; /*MHz, */
+ u8 channel_set[NUM_CHANNELS];
+ u8 channel_cck_power[NUM_CHANNELS]; /*dbm*/
+ u8 channel_ofdm_power[NUM_CHANNELS];/*dbm*/
+ u8 txpower_limit; /*dbm*/
+ u8 channel_spacing; /*MHz*/
+ u8 modem;
+};
+
+enum _REG_PREAMBLE_MODE{
+ PREAMBLE_LONG = 1,
+ PREAMBLE_AUTO = 2,
+ PREAMBLE_SHORT = 3,
+};
+
+enum {
+ RTL8712_RFC_1T = 0x10,
+ RTL8712_RFC_2T = 0x20,
+ RTL8712_RFC_1R = 0x01,
+ RTL8712_RFC_2R = 0x02,
+ RTL8712_RFC_1T1R = 0x11,
+ RTL8712_RFC_1T2R = 0x12,
+ RTL8712_RFC_TURBO = 0x92,
+ RTL8712_RFC_2T2R = 0x22
+};
+
+#endif /*_RTL8711_RF_H_*/
+
diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c
new file mode 100644
index 000000000000..65321bed4d5d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_security.c
@@ -0,0 +1,1389 @@
+/******************************************************************************
+ * rtl871x_security.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_SECURITY_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wifi.h"
+#include "osdep_intf.h"
+
+/* =====WEP related===== */
+
+#define CRC32_POLY 0x04c11db7
+
+struct arc4context {
+ u32 x;
+ u32 y;
+ u8 state[256];
+};
+
+static void arcfour_init(struct arc4context *parc4ctx, u8 * key, u32 key_len)
+{
+ u32 t, u;
+ u32 keyindex;
+ u32 stateindex;
+ u8 *state;
+ u32 counter;
+
+ state = parc4ctx->state;
+ parc4ctx->x = 0;
+ parc4ctx->y = 0;
+ for (counter = 0; counter < 256; counter++)
+ state[counter] = (u8)counter;
+ keyindex = 0;
+ stateindex = 0;
+ for (counter = 0; counter < 256; counter++) {
+ t = state[counter];
+ stateindex = (stateindex + key[keyindex] + t) & 0xff;
+ u = state[stateindex];
+ state[stateindex] = (u8)t;
+ state[counter] = (u8)u;
+ if (++keyindex >= key_len)
+ keyindex = 0;
+ }
+}
+
+static u32 arcfour_byte(struct arc4context *parc4ctx)
+{
+ u32 x;
+ u32 y;
+ u32 sx, sy;
+ u8 *state;
+
+ state = parc4ctx->state;
+ x = (parc4ctx->x + 1) & 0xff;
+ sx = state[x];
+ y = (sx + parc4ctx->y) & 0xff;
+ sy = state[y];
+ parc4ctx->x = x;
+ parc4ctx->y = y;
+ state[y] = (u8)sx;
+ state[x] = (u8)sy;
+ return state[(sx + sy) & 0xff];
+}
+
+static void arcfour_encrypt(struct arc4context *parc4ctx,
+ u8 *dest, u8 *src, u32 len)
+{
+ u32 i;
+
+ for (i = 0; i < len; i++)
+ dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
+}
+
+static sint bcrc32initialized;
+static u32 crc32_table[256];
+
+static u8 crc32_reverseBit(u8 data)
+{
+ return ((u8)(data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3)
+ & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) |
+ ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((data >> 7) &
+ 0x01);
+}
+
+static void crc32_init(void)
+{
+ if (bcrc32initialized == 1)
+ return;
+ else {
+ sint i, j;
+ u32 c;
+ u8 *p = (u8 *)&c, *p1;
+ u8 k;
+
+ c = 0x12340000;
+ for (i = 0; i < 256; ++i) {
+ k = crc32_reverseBit((u8)i);
+ for (c = ((u32)k) << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY :
+ (c << 1);
+ p1 = (u8 *)&crc32_table[i];
+ p1[0] = crc32_reverseBit(p[3]);
+ p1[1] = crc32_reverseBit(p[2]);
+ p1[2] = crc32_reverseBit(p[1]);
+ p1[3] = crc32_reverseBit(p[0]);
+ }
+ bcrc32initialized = 1;
+ }
+}
+
+static u32 getcrc32(u8 *buf, u32 len)
+{
+ u8 *p;
+ u32 crc;
+
+ if (bcrc32initialized == 0)
+ crc32_init();
+ crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
+ for (p = buf; len > 0; ++p, --len)
+ crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
+ return ~crc; /* transmit complement, per CRC-32 spec */
+}
+
+/*
+ Need to consider the fragment situation
+*/
+void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe)
+{ /* exclude ICV */
+ unsigned char crc[4];
+ struct arc4context mycontext;
+ u32 curfragnum, length, keylength;
+ u8 *pframe, *payload, *iv; /*,*wepkey*/
+ u8 wepkey[16];
+ struct pkt_attrib *pattrib = &((struct xmit_frame *)
+ pxmitframe)->attrib;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
+ return;
+ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr+TXDESC_OFFSET;
+ /*start to encrypt each fragment*/
+ if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
+ keylength = psecuritypriv->DefKeylen[psecuritypriv->
+ PrivacyKeyIndex];
+ for (curfragnum = 0; curfragnum < pattrib->nr_frags;
+ curfragnum++) {
+ iv = pframe+pattrib->hdrlen;
+ memcpy(&wepkey[0], iv, 3);
+ memcpy(&wepkey[3], &psecuritypriv->DefKey[
+ psecuritypriv->PrivacyKeyIndex].skey[0],
+ keylength);
+ payload = pframe+pattrib->iv_len+pattrib->hdrlen;
+ if ((curfragnum + 1) == pattrib->nr_frags) {
+ length = pattrib->last_txcmdsz-pattrib->
+ hdrlen-pattrib->iv_len -
+ pattrib->icv_len;
+ *((u32 *)crc) = cpu_to_le32(getcrc32(
+ payload, length));
+ arcfour_init(&mycontext, wepkey, 3 + keylength);
+ arcfour_encrypt(&mycontext, payload, payload,
+ length);
+ arcfour_encrypt(&mycontext, payload + length,
+ crc, 4);
+ } else {
+ length = pxmitpriv->frag_len-pattrib->hdrlen -
+ pattrib->iv_len-pattrib->icv_len;
+ *((u32 *)crc) = cpu_to_le32(getcrc32(
+ payload, length));
+ arcfour_init(&mycontext, wepkey, 3 + keylength);
+ arcfour_encrypt(&mycontext, payload, payload,
+ length);
+ arcfour_encrypt(&mycontext, payload+length,
+ crc, 4);
+ pframe += pxmitpriv->frag_len;
+ pframe = (u8 *)RND4((addr_t)(pframe));
+ }
+ }
+ }
+}
+
+void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe)
+{
+ /* exclude ICV */
+ u8 crc[4];
+ struct arc4context mycontext;
+ u32 length, keylength;
+ u8 *pframe, *payload, *iv, wepkey[16];
+ u8 keyindex;
+ struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)
+ precvframe)->u.hdr.attrib);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ pframe = (unsigned char *)((union recv_frame *)precvframe)->
+ u.hdr.rx_data;
+ /* start to decrypt recvframe */
+ if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt ==
+ _WEP104_)) {
+ iv = pframe + prxattrib->hdrlen;
+ keyindex = (iv[3] & 0x3);
+ keylength = psecuritypriv->DefKeylen[keyindex];
+ memcpy(&wepkey[0], iv, 3);
+ memcpy(&wepkey[3], &psecuritypriv->DefKey[
+ psecuritypriv->PrivacyKeyIndex].skey[0],
+ keylength);
+ length = ((union recv_frame *)precvframe)->
+ u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
+ payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
+ /* decrypt payload include icv */
+ arcfour_init(&mycontext, wepkey, 3 + keylength);
+ arcfour_encrypt(&mycontext, payload, payload, length);
+ /* calculate icv and compare the icv */
+ *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4));
+ }
+ return;
+}
+
+/* 3 =====TKIP related===== */
+
+static u32 secmicgetuint32(u8 *p)
+/* Convert from Byte[] to Us4Byte32 in a portable way */
+{
+ s32 i;
+ u32 res = 0;
+
+ for (i = 0; i < 4; i++)
+ res |= ((u32)(*p++)) << (8 * i);
+ return res;
+}
+
+static void secmicputuint32(u8 *p, u32 val)
+/* Convert from Us4Byte32 to Byte[] in a portable way */
+{
+ long i;
+ for (i = 0; i < 4; i++) {
+ *p++ = (u8) (val & 0xff);
+ val >>= 8;
+ }
+}
+
+static void secmicclear(struct mic_data *pmicdata)
+{
+/* Reset the state to the empty message. */
+ pmicdata->L = pmicdata->K0;
+ pmicdata->R = pmicdata->K1;
+ pmicdata->nBytesInM = 0;
+ pmicdata->M = 0;
+}
+
+void r8712_secmicsetkey(struct mic_data *pmicdata, u8 * key)
+{
+ /* Set the key */
+ pmicdata->K0 = secmicgetuint32(key);
+ pmicdata->K1 = secmicgetuint32(key + 4);
+ /* and reset the message */
+ secmicclear(pmicdata);
+}
+
+static void secmicappendbyte(struct mic_data *pmicdata, u8 b)
+{
+ /* Append the byte to our word-sized buffer */
+ pmicdata->M |= ((u32)b) << (8 * pmicdata->nBytesInM);
+ pmicdata->nBytesInM++;
+ /* Process the word if it is full. */
+ if (pmicdata->nBytesInM >= 4) {
+ pmicdata->L ^= pmicdata->M;
+ pmicdata->R ^= ROL32(pmicdata->L, 17);
+ pmicdata->L += pmicdata->R;
+ pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) |
+ ((pmicdata->L & 0x00ff00ff) << 8);
+ pmicdata->L += pmicdata->R;
+ pmicdata->R ^= ROL32(pmicdata->L, 3);
+ pmicdata->L += pmicdata->R;
+ pmicdata->R ^= ROR32(pmicdata->L, 2);
+ pmicdata->L += pmicdata->R;
+ /* Clear the buffer */
+ pmicdata->M = 0;
+ pmicdata->nBytesInM = 0;
+ }
+}
+
+void r8712_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes)
+{
+ /* This is simple */
+ while (nbytes > 0) {
+ secmicappendbyte(pmicdata, *src++);
+ nbytes--;
+ }
+}
+
+void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst)
+{
+ /* Append the minimum padding */
+ secmicappendbyte(pmicdata, 0x5a);
+ secmicappendbyte(pmicdata, 0);
+ secmicappendbyte(pmicdata, 0);
+ secmicappendbyte(pmicdata, 0);
+ secmicappendbyte(pmicdata, 0);
+ /* and then zeroes until the length is a multiple of 4 */
+ while (pmicdata->nBytesInM != 0)
+ secmicappendbyte(pmicdata, 0);
+ /* The appendByte function has already computed the result. */
+ secmicputuint32(dst, pmicdata->L);
+ secmicputuint32(dst + 4, pmicdata->R);
+ /* Reset to the empty message. */
+ secmicclear(pmicdata);
+}
+
+void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code,
+ u8 pri)
+{
+
+ struct mic_data micdata;
+ u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
+
+ r8712_secmicsetkey(&micdata, key);
+ priority[0] = pri;
+ /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
+ if (header[1] & 1) { /* ToDS==1 */
+ r8712_secmicappend(&micdata, &header[16], 6); /* DA */
+ if (header[1] & 2) /* From Ds==1 */
+ r8712_secmicappend(&micdata, &header[24], 6);
+ else
+ r8712_secmicappend(&micdata, &header[10], 6);
+ } else { /* ToDS==0 */
+ r8712_secmicappend(&micdata, &header[4], 6); /* DA */
+ if (header[1] & 2) /* From Ds==1 */
+ r8712_secmicappend(&micdata, &header[16], 6);
+ else
+ r8712_secmicappend(&micdata, &header[10], 6);
+ }
+ r8712_secmicappend(&micdata, &priority[0], 4);
+ r8712_secmicappend(&micdata, data, data_len);
+ r8712_secgetmic(&micdata, mic_code);
+}
+
+/* macros for extraction/creation of unsigned char/unsigned short values */
+#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
+#define Lo8(v16) ((u8)((v16) & 0x00FF))
+#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
+#define Lo16(v32) ((u16)((v32) & 0xFFFF))
+#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
+#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
+
+/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
+#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
+
+/* S-box lookup: 16 bits --> 16 bits */
+#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
+
+/* fixed algorithm "parameters" */
+#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
+#define TA_SIZE 6 /* 48-bit transmitter address */
+#define TK_SIZE 16 /* 128-bit temporal key */
+#define P1K_SIZE 10 /* 80-bit Phase1 key */
+#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
+
+
+/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
+static const unsigned short Sbox1[2][256] = {/* Sbox for hash (can be in ROM) */
+ {
+ 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
+ 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
+ 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
+ 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
+ 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
+ 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
+ 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
+ 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
+ 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
+ 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
+ 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
+ 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
+ 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
+ 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
+ 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
+ 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
+ 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
+ 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
+ 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
+ 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
+ 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
+ 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
+ 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
+ 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
+ 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
+ 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
+ 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
+ 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
+ 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
+ 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
+ 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
+ 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
+ },
+ { /* second half is unsigned char-reversed version of first! */
+ 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
+ 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
+ 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
+ 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
+ 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
+ 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
+ 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
+ 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
+ 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
+ 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
+ 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
+ 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
+ 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
+ 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
+ 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
+ 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
+ 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
+ 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
+ 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
+ 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
+ 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
+ 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
+ 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
+ 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
+ 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
+ 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
+ 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
+ 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
+ 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
+ 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
+ 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
+ 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
+ }
+};
+
+/*
+**********************************************************************
+* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
+*
+* Inputs:
+* tk[] = temporal key [128 bits]
+* ta[] = transmitter's MAC address [ 48 bits]
+* iv32 = upper 32 bits of IV [ 32 bits]
+* Output:
+* p1k[] = Phase 1 key [ 80 bits]
+*
+* Note:
+* This function only needs to be called every 2**16 packets,
+* although in theory it could be called every packet.
+*
+**********************************************************************
+*/
+static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
+{
+ sint i;
+
+ /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
+ p1k[0] = Lo16(iv32);
+ p1k[1] = Hi16(iv32);
+ p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
+ p1k[3] = Mk16(ta[3], ta[2]);
+ p1k[4] = Mk16(ta[5], ta[4]);
+ /* Now compute an unbalanced Feistel cipher with 80-bit block */
+ /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
+ for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add is mod 2**16 */
+ p1k[0] += _S_(p1k[4] ^ TK16((i&1) + 0));
+ p1k[1] += _S_(p1k[0] ^ TK16((i&1) + 2));
+ p1k[2] += _S_(p1k[1] ^ TK16((i&1) + 4));
+ p1k[3] += _S_(p1k[2] ^ TK16((i&1) + 6));
+ p1k[4] += _S_(p1k[3] ^ TK16((i&1) + 0));
+ p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
+ }
+}
+
+/*
+**********************************************************************
+* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
+*
+* Inputs:
+* tk[] = Temporal key [128 bits]
+* p1k[] = Phase 1 output key [ 80 bits]
+* iv16 = low 16 bits of IV counter [ 16 bits]
+* Output:
+* rc4key[] = the key used to encrypt the packet [128 bits]
+*
+* Note:
+* The value {TA,IV32,IV16} for Phase1/Phase2 must be unique
+* across all packets using the same key TK value. Then, for a
+* given value of TK[], this TKIP48 construction guarantees that
+* the final RC4KEY value is unique across all packets.
+*
+* Suggested implementation optimization: if PPK[] is "overlaid"
+* appropriately on RC4KEY[], there is no need for the final
+* for loop below that copies the PPK[] result into RC4KEY[].
+*
+**********************************************************************
+*/
+static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
+{
+ sint i;
+ u16 PPK[6]; /* temporary key for mixing */
+
+ /* Note: all adds in the PPK[] equations below are mod 2**16 */
+ for (i = 0; i < 5; i++)
+ PPK[i] = p1k[i]; /* first, copy P1K to PPK */
+ PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
+ /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
+ PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
+ PPK[1] += _S_(PPK[0] ^ TK16(1));
+ PPK[2] += _S_(PPK[1] ^ TK16(2));
+ PPK[3] += _S_(PPK[2] ^ TK16(3));
+ PPK[4] += _S_(PPK[3] ^ TK16(4));
+ PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
+ /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
+ PPK[0] += RotR1(PPK[5] ^ TK16(6));
+ PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
+ PPK[2] += RotR1(PPK[1]);
+ PPK[3] += RotR1(PPK[2]);
+ PPK[4] += RotR1(PPK[3]);
+ PPK[5] += RotR1(PPK[4]);
+ /* Note: At this point, for a given key TK[0..15], the 96-bit output */
+ /* value PPK[0..5] is guaranteed to be unique, as a function */
+ /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */
+ /* is now a keyed permutation of {TA,IV32,IV16}. */
+ /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
+ rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
+ rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
+ rc4key[2] = Lo8(iv16);
+ rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
+ /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
+ for (i = 0; i < 6; i++) {
+ rc4key[4 + 2 * i] = Lo8(PPK[i]);
+ rc4key[5 + 2 * i] = Hi8(PPK[i]);
+ }
+}
+
+/*The hlen isn't include the IV*/
+u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe)
+{ /* exclude ICV */
+ u16 pnl;
+ u32 pnh;
+ u8 rc4key[16];
+ u8 ttkey[16];
+ u8 crc[4];
+ struct arc4context mycontext;
+ u32 curfragnum, length, prwskeylen;
+
+ u8 *pframe, *payload, *iv, *prwskey;
+ union pn48 txpn;
+ struct sta_info *stainfo;
+ struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ u32 res = _SUCCESS;
+
+ if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
+ return _FAIL;
+
+ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr+TXDESC_OFFSET;
+ /* 4 start to encrypt each fragment */
+ if (pattrib->encrypt == _TKIP_) {
+ if (pattrib->psta)
+ stainfo = pattrib->psta;
+ else
+ stainfo = r8712_get_stainfo(&padapter->stapriv,
+ &pattrib->ra[0]);
+ if (stainfo != NULL) {
+ prwskey = &stainfo->x_UncstKey.skey[0];
+ prwskeylen = 16;
+ for (curfragnum = 0; curfragnum < pattrib->nr_frags;
+ curfragnum++) {
+ iv = pframe + pattrib->hdrlen;
+ payload = pframe+pattrib->iv_len +
+ pattrib->hdrlen;
+ GET_TKIP_PN(iv, txpn);
+ pnl = (u16)(txpn.val);
+ pnh = (u32)(txpn.val >> 16);
+ phase1((u16 *)&ttkey[0], prwskey, &pattrib->
+ ta[0], pnh);
+ phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0],
+ pnl);
+ if ((curfragnum + 1) == pattrib->nr_frags) {
+ /* 4 the last fragment */
+ length = pattrib->last_txcmdsz -
+ pattrib->hdrlen-pattrib->iv_len -
+ pattrib->icv_len;
+ *((u32 *)crc) = cpu_to_le32(
+ getcrc32(payload, length));
+ arcfour_init(&mycontext, rc4key, 16);
+ arcfour_encrypt(&mycontext, payload,
+ payload, length);
+ arcfour_encrypt(&mycontext, payload +
+ length, crc, 4);
+ } else {
+ length = pxmitpriv->frag_len-pattrib->
+ hdrlen-pattrib->
+ iv_len-pattrib->icv_len;
+ *((u32 *)crc) = cpu_to_le32(getcrc32(
+ payload, length));
+ arcfour_init(&mycontext, rc4key, 16);
+ arcfour_encrypt(&mycontext, payload,
+ payload, length);
+ arcfour_encrypt(&mycontext,
+ payload+length, crc, 4);
+ pframe += pxmitpriv->frag_len;
+ pframe = (u8 *)RND4((addr_t)(pframe));
+ }
+ }
+ } else
+ res = _FAIL;
+ }
+ return res;
+}
+
+/* The hlen doesn't include the IV */
+u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe)
+{ /* exclude ICV */
+ u16 pnl;
+ u32 pnh;
+ u8 rc4key[16];
+ u8 ttkey[16];
+ u8 crc[4];
+ struct arc4context mycontext;
+ u32 length, prwskeylen;
+ u8 *pframe, *payload, *iv, *prwskey, idx = 0;
+ union pn48 txpn;
+ struct sta_info *stainfo;
+ struct rx_pkt_attrib *prxattrib = &((union recv_frame *)
+ precvframe)->u.hdr.attrib;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ pframe = (unsigned char *)((union recv_frame *)
+ precvframe)->u.hdr.rx_data;
+ /* 4 start to decrypt recvframe */
+ if (prxattrib->encrypt == _TKIP_) {
+ stainfo = r8712_get_stainfo(&padapter->stapriv,
+ &prxattrib->ta[0]);
+ if (stainfo != NULL) {
+ iv = pframe+prxattrib->hdrlen;
+ payload = pframe+prxattrib->iv_len + prxattrib->hdrlen;
+ length = ((union recv_frame *)precvframe)->
+ u.hdr.len - prxattrib->hdrlen -
+ prxattrib->iv_len;
+ if (IS_MCAST(prxattrib->ra)) {
+ idx = iv[3];
+ prwskey = &psecuritypriv->XGrpKey[
+ ((idx >> 6) & 0x3) - 1].skey[0];
+ if (psecuritypriv->binstallGrpkey == false)
+ return _FAIL;
+ } else
+ prwskey = &stainfo->x_UncstKey.skey[0];
+ prwskeylen = 16;
+ GET_TKIP_PN(iv, txpn);
+ pnl = (u16)(txpn.val);
+ pnh = (u32)(txpn.val >> 16);
+ phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0],
+ pnh);
+ phase2(&rc4key[0], prwskey, (unsigned short *)
+ &ttkey[0], pnl);
+ /* 4 decrypt payload include icv */
+ arcfour_init(&mycontext, rc4key, 16);
+ arcfour_encrypt(&mycontext, payload, payload, length);
+ *((u32 *)crc) = cpu_to_le32(getcrc32(payload,
+ length - 4));
+ if (crc[3] != payload[length - 1] ||
+ crc[2] != payload[length - 2] ||
+ crc[1] != payload[length - 3] ||
+ crc[0] != payload[length - 4])
+ return _FAIL;
+ } else
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
+
+/* 3 =====AES related===== */
+
+#define MAX_MSG_SIZE 2048
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+static const u8 sbox_table[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+/****************************************/
+/* aes128k128d() */
+/* Performs a 128 bit AES encrypt with */
+/* 128 bit data. */
+/****************************************/
+static void xor_128(u8 *a, u8 *b, u8 *out)
+{
+ sint i;
+
+ for (i = 0; i < 16; i++)
+ out[i] = a[i] ^ b[i];
+}
+
+static void xor_32(u8 *a, u8 *b, u8 *out)
+{
+ sint i;
+ for (i = 0; i < 4; i++)
+ out[i] = a[i] ^ b[i];
+}
+
+static u8 sbox(u8 a)
+{
+ return sbox_table[(sint)a];
+}
+
+static void next_key(u8 *key, sint round)
+{
+ u8 rcon;
+ u8 sbox_key[4];
+ u8 rcon_table[12] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1b, 0x36, 0x36, 0x36
+ };
+
+ sbox_key[0] = sbox(key[13]);
+ sbox_key[1] = sbox(key[14]);
+ sbox_key[2] = sbox(key[15]);
+ sbox_key[3] = sbox(key[12]);
+ rcon = rcon_table[round];
+ xor_32(&key[0], sbox_key, &key[0]);
+ key[0] = key[0] ^ rcon;
+ xor_32(&key[4], &key[0], &key[4]);
+ xor_32(&key[8], &key[4], &key[8]);
+ xor_32(&key[12], &key[8], &key[12]);
+}
+
+static void byte_sub(u8 *in, u8 *out)
+{
+ sint i;
+ for (i = 0; i < 16; i++)
+ out[i] = sbox(in[i]);
+}
+
+static void shift_row(u8 *in, u8 *out)
+{
+ out[0] = in[0];
+ out[1] = in[5];
+ out[2] = in[10];
+ out[3] = in[15];
+ out[4] = in[4];
+ out[5] = in[9];
+ out[6] = in[14];
+ out[7] = in[3];
+ out[8] = in[8];
+ out[9] = in[13];
+ out[10] = in[2];
+ out[11] = in[7];
+ out[12] = in[12];
+ out[13] = in[1];
+ out[14] = in[6];
+ out[15] = in[11];
+}
+
+static void mix_column(u8 *in, u8 *out)
+{
+ sint i;
+ u8 add1b[4];
+ u8 add1bf7[4];
+ u8 rotl[4];
+ u8 swap_halfs[4];
+ u8 andf7[4];
+ u8 rotr[4];
+ u8 temp[4];
+ u8 tempb[4];
+
+ for (i = 0 ; i < 4; i++) {
+ if ((in[i] & 0x80) == 0x80)
+ add1b[i] = 0x1b;
+ else
+ add1b[i] = 0x00;
+ }
+ swap_halfs[0] = in[2]; /* Swap halves */
+ swap_halfs[1] = in[3];
+ swap_halfs[2] = in[0];
+ swap_halfs[3] = in[1];
+ rotl[0] = in[3]; /* Rotate left 8 bits */
+ rotl[1] = in[0];
+ rotl[2] = in[1];
+ rotl[3] = in[2];
+ andf7[0] = in[0] & 0x7f;
+ andf7[1] = in[1] & 0x7f;
+ andf7[2] = in[2] & 0x7f;
+ andf7[3] = in[3] & 0x7f;
+ for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
+ andf7[i] = andf7[i] << 1;
+ if ((andf7[i-1] & 0x80) == 0x80)
+ andf7[i] = (andf7[i] | 0x01);
+ }
+ andf7[0] = andf7[0] << 1;
+ andf7[0] = andf7[0] & 0xfe;
+ xor_32(add1b, andf7, add1bf7);
+ xor_32(in, add1bf7, rotr);
+ temp[0] = rotr[0]; /* Rotate right 8 bits */
+ rotr[0] = rotr[1];
+ rotr[1] = rotr[2];
+ rotr[2] = rotr[3];
+ rotr[3] = temp[0];
+ xor_32(add1bf7, rotr, temp);
+ xor_32(swap_halfs, rotl, tempb);
+ xor_32(temp, tempb, out);
+}
+
+static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
+{
+ sint round;
+ sint i;
+ u8 intermediatea[16];
+ u8 intermediateb[16];
+ u8 round_key[16];
+
+ for (i = 0; i < 16; i++)
+ round_key[i] = key[i];
+ for (round = 0; round < 11; round++) {
+ if (round == 0) {
+ xor_128(round_key, data, ciphertext);
+ next_key(round_key, round);
+ } else if (round == 10) {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ xor_128(intermediateb, round_key, ciphertext);
+ } else { /* 1 - 9 */
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ mix_column(&intermediateb[0], &intermediatea[0]);
+ mix_column(&intermediateb[4], &intermediatea[4]);
+ mix_column(&intermediateb[8], &intermediatea[8]);
+ mix_column(&intermediateb[12], &intermediatea[12]);
+ xor_128(intermediatea, round_key, ciphertext);
+ next_key(round_key, round);
+ }
+ }
+}
+
+/************************************************/
+/* construct_mic_iv() */
+/* Builds the MIC IV from header fields and PN */
+/************************************************/
+static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists,
+ u8 *mpdu, uint payload_length, u8 *pn_vector)
+{
+ sint i;
+
+ mic_iv[0] = 0x59;
+ if (qc_exists && a4_exists)
+ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
+ if (qc_exists && !a4_exists)
+ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
+ if (!qc_exists)
+ mic_iv[1] = 0x00;
+ for (i = 2; i < 8; i++)
+ mic_iv[i] = mpdu[i + 8];
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
+ mic_iv[14] = (unsigned char) (payload_length / 256);
+ mic_iv[15] = (unsigned char) (payload_length % 256);
+}
+
+/************************************************/
+/* construct_mic_header1() */
+/* Builds the first MIC header block from */
+/* header fields. */
+/************************************************/
+static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu)
+{
+ mic_header1[0] = (u8)((header_length - 2) / 256);
+ mic_header1[1] = (u8)((header_length - 2) % 256);
+ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+ /* Mute retry, more data and pwr mgt bits */
+ mic_header1[3] = mpdu[1] & 0xc7;
+ mic_header1[4] = mpdu[4]; /* A1 */
+ mic_header1[5] = mpdu[5];
+ mic_header1[6] = mpdu[6];
+ mic_header1[7] = mpdu[7];
+ mic_header1[8] = mpdu[8];
+ mic_header1[9] = mpdu[9];
+ mic_header1[10] = mpdu[10]; /* A2 */
+ mic_header1[11] = mpdu[11];
+ mic_header1[12] = mpdu[12];
+ mic_header1[13] = mpdu[13];
+ mic_header1[14] = mpdu[14];
+ mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2() */
+/* Builds the last MIC header block from */
+/* header fields. */
+/************************************************/
+static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists,
+ sint qc_exists)
+{
+ sint i;
+
+ for (i = 0; i < 16; i++)
+ mic_header2[i] = 0x00;
+ mic_header2[0] = mpdu[16]; /* A3 */
+ mic_header2[1] = mpdu[17];
+ mic_header2[2] = mpdu[18];
+ mic_header2[3] = mpdu[19];
+ mic_header2[4] = mpdu[20];
+ mic_header2[5] = mpdu[21];
+ mic_header2[6] = 0x00;
+ mic_header2[7] = 0x00; /* mpdu[23]; */
+ if (!qc_exists && a4_exists)
+ for (i = 0; i < 6; i++)
+ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
+ if (qc_exists && !a4_exists) {
+ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+ mic_header2[9] = mpdu[25] & 0x00;
+ }
+ if (qc_exists && a4_exists) {
+ for (i = 0; i < 6; i++)
+ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
+ mic_header2[14] = mpdu[30] & 0x0f;
+ mic_header2[15] = mpdu[31] & 0x00;
+ }
+}
+
+/************************************************/
+/* construct_mic_header2() */
+/* Builds the last MIC header block from */
+/* header fields. */
+/************************************************/
+static void construct_ctr_preload(u8 *ctr_preload, sint a4_exists, sint qc_exists,
+ u8 *mpdu, u8 *pn_vector, sint c)
+{
+ sint i;
+
+ for (i = 0; i < 16; i++)
+ ctr_preload[i] = 0x00;
+ i = 0;
+ ctr_preload[0] = 0x01; /* flag */
+ if (qc_exists && a4_exists)
+ ctr_preload[1] = mpdu[30] & 0x0f;
+ if (qc_exists && !a4_exists)
+ ctr_preload[1] = mpdu[24] & 0x0f;
+ for (i = 2; i < 8; i++)
+ ctr_preload[i] = mpdu[i + 8];
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[13 - i];
+ ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
+ ctr_preload[15] = (unsigned char) (c % 256);
+}
+
+/************************************/
+/* bitwise_xor() */
+/* A 128 bit, bitwise exclusive or */
+/************************************/
+static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
+{
+ sint i;
+
+ for (i = 0; i < 16; i++)
+ out[i] = ina[i] ^ inb[i];
+}
+
+static sint aes_cipher(u8 *key, uint hdrlen,
+ u8 *pframe, uint plen)
+{
+ uint qc_exists, a4_exists, i, j, payload_remainder;
+ uint num_blocks, payload_index;
+
+ u8 pn_vector[6];
+ u8 mic_iv[16];
+ u8 mic_header1[16];
+ u8 mic_header2[16];
+ u8 ctr_preload[16];
+
+ /* Intermediate Buffers */
+ u8 chain_buffer[16];
+ u8 aes_out[16];
+ u8 padded_buffer[16];
+ u8 mic[8];
+ uint frtype = GetFrameType(pframe);
+ uint frsubtype = GetFrameSubType(pframe);
+
+ frsubtype = frsubtype >> 4;
+ memset((void *)mic_iv, 0, 16);
+ memset((void *)mic_header1, 0, 16);
+ memset((void *)mic_header2, 0, 16);
+ memset((void *)ctr_preload, 0, 16);
+ memset((void *)chain_buffer, 0, 16);
+ memset((void *)aes_out, 0, 16);
+ memset((void *)padded_buffer, 0, 16);
+
+ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
+ a4_exists = 0;
+ else
+ a4_exists = 1;
+
+ if ((frtype == WIFI_DATA_CFACK) ||
+ (frtype == WIFI_DATA_CFPOLL) ||
+ (frtype == WIFI_DATA_CFACKPOLL)) {
+ qc_exists = 1;
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+ } else if ((frsubtype == 0x08) ||
+ (frsubtype == 0x09) ||
+ (frsubtype == 0x0a) ||
+ (frsubtype == 0x0b)) {
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+ qc_exists = 1;
+ } else
+ qc_exists = 0;
+ pn_vector[0] = pframe[hdrlen];
+ pn_vector[1] = pframe[hdrlen+1];
+ pn_vector[2] = pframe[hdrlen+4];
+ pn_vector[3] = pframe[hdrlen+5];
+ pn_vector[4] = pframe[hdrlen+6];
+ pn_vector[5] = pframe[hdrlen+7];
+ construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
+ construct_mic_header1(mic_header1, hdrlen, pframe);
+ construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
+ payload_remainder = plen % 16;
+ num_blocks = plen / 16;
+ /* Find start of payload */
+ payload_index = (hdrlen + 8);
+ /* Calculate MIC */
+ aes128k128d(key, mic_iv, aes_out);
+ bitwise_xor(aes_out, mic_header1, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ bitwise_xor(aes_out, mic_header2, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ for (i = 0; i < num_blocks; i++) {
+ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
+ payload_index += 16;
+ aes128k128d(key, chain_buffer, aes_out);
+ }
+ /* Add on the final payload block if it needs padding */
+ if (payload_remainder > 0) {
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < payload_remainder; j++)
+ padded_buffer[j] = pframe[payload_index++];
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ }
+ for (j = 0; j < 8; j++)
+ mic[j] = aes_out[j];
+ /* Insert MIC into payload */
+ for (j = 0; j < 8; j++)
+ pframe[payload_index+j] = mic[j];
+ payload_index = hdrlen + 8;
+ for (i = 0; i < num_blocks; i++) {
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ pframe, pn_vector, i + 1);
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
+ for (j = 0; j < 16; j++)
+ pframe[payload_index++] = chain_buffer[j];
+ }
+ if (payload_remainder > 0) { /* If short final block, then pad it,*/
+ /* encrypt and copy unpadded part back */
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ pframe, pn_vector, num_blocks+1);
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < payload_remainder; j++)
+ padded_buffer[j] = pframe[payload_index+j];
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ for (j = 0; j < payload_remainder; j++)
+ pframe[payload_index++] = chain_buffer[j];
+ }
+ /* Encrypt the MIC */
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ pframe, pn_vector, 0);
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < 8; j++)
+ padded_buffer[j] = pframe[j+hdrlen+8+plen];
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ for (j = 0; j < 8; j++)
+ pframe[payload_index++] = chain_buffer[j];
+ return _SUCCESS;
+}
+
+u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
+{ /* exclude ICV */
+ /* Intermediate Buffers */
+ sint curfragnum, length;
+ u32 prwskeylen;
+ u8 *pframe, *prwskey;
+ struct sta_info *stainfo;
+ struct pkt_attrib *pattrib = &((struct xmit_frame *)
+ pxmitframe)->attrib;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ u32 res = _SUCCESS;
+
+ if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
+ return _FAIL;
+ pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
+ /* 4 start to encrypt each fragment */
+ if ((pattrib->encrypt == _AES_)) {
+ if (pattrib->psta)
+ stainfo = pattrib->psta;
+ else
+ stainfo = r8712_get_stainfo(&padapter->stapriv,
+ &pattrib->ra[0]);
+ if (stainfo != NULL) {
+ prwskey = &stainfo->x_UncstKey.skey[0];
+ prwskeylen = 16;
+ for (curfragnum = 0; curfragnum < pattrib->nr_frags;
+ curfragnum++) {
+ if ((curfragnum + 1) == pattrib->nr_frags) {\
+ length = pattrib->last_txcmdsz -
+ pattrib->hdrlen -
+ pattrib->iv_len -
+ pattrib->icv_len;
+ aes_cipher(prwskey, pattrib->
+ hdrlen, pframe, length);
+ } else {
+ length = pxmitpriv->frag_len -
+ pattrib->hdrlen -
+ pattrib->iv_len -
+ pattrib->icv_len ;
+ aes_cipher(prwskey, pattrib->
+ hdrlen, pframe, length);
+ pframe += pxmitpriv->frag_len;
+ pframe = (u8 *)RND4((addr_t)(pframe));
+ }
+ }
+ } else
+ res = _FAIL;
+ }
+ return res;
+}
+
+static sint aes_decipher(u8 *key, uint hdrlen,
+ u8 *pframe, uint plen)
+{
+ static u8 message[MAX_MSG_SIZE];
+ uint qc_exists, a4_exists, i, j, payload_remainder;
+ uint num_blocks, payload_index;
+ u8 pn_vector[6];
+ u8 mic_iv[16];
+ u8 mic_header1[16];
+ u8 mic_header2[16];
+ u8 ctr_preload[16];
+ /* Intermediate Buffers */
+ u8 chain_buffer[16];
+ u8 aes_out[16];
+ u8 padded_buffer[16];
+ u8 mic[8];
+ uint frtype = GetFrameType(pframe);
+ uint frsubtype = GetFrameSubType(pframe);
+
+ frsubtype = frsubtype >> 4;
+ memset((void *)mic_iv, 0, 16);
+ memset((void *)mic_header1, 0, 16);
+ memset((void *)mic_header2, 0, 16);
+ memset((void *)ctr_preload, 0, 16);
+ memset((void *)chain_buffer, 0, 16);
+ memset((void *)aes_out, 0, 16);
+ memset((void *)padded_buffer, 0, 16);
+ /* start to decrypt the payload */
+ /*(plen including llc, payload and mic) */
+ num_blocks = (plen - 8) / 16;
+ payload_remainder = (plen-8) % 16;
+ pn_vector[0] = pframe[hdrlen];
+ pn_vector[1] = pframe[hdrlen+1];
+ pn_vector[2] = pframe[hdrlen+4];
+ pn_vector[3] = pframe[hdrlen+5];
+ pn_vector[4] = pframe[hdrlen+6];
+ pn_vector[5] = pframe[hdrlen+7];
+ if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
+ a4_exists = 0;
+ else
+ a4_exists = 1;
+ if ((frtype == WIFI_DATA_CFACK) ||
+ (frtype == WIFI_DATA_CFPOLL) ||
+ (frtype == WIFI_DATA_CFACKPOLL)) {
+ qc_exists = 1;
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+ } else if ((frsubtype == 0x08) ||
+ (frsubtype == 0x09) ||
+ (frsubtype == 0x0a) ||
+ (frsubtype == 0x0b)) {
+ if (hdrlen != WLAN_HDR_A3_QOS_LEN)
+ hdrlen += 2;
+ qc_exists = 1;
+ } else
+ qc_exists = 0;
+ /* now, decrypt pframe with hdrlen offset and plen long */
+ payload_index = hdrlen + 8; /* 8 is for extiv */
+ for (i = 0; i < num_blocks; i++) {
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ pframe, pn_vector, i + 1);
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
+ for (j = 0; j < 16; j++)
+ pframe[payload_index++] = chain_buffer[j];
+ }
+ if (payload_remainder > 0) { /* If short final block, pad it,*/
+ /* encrypt it and copy the unpadded part back */
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ pframe, pn_vector, num_blocks+1);
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < payload_remainder; j++)
+ padded_buffer[j] = pframe[payload_index + j];
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ for (j = 0; j < payload_remainder; j++)
+ pframe[payload_index++] = chain_buffer[j];
+ }
+ /* start to calculate the mic */
+ memcpy((void *)message, pframe, (hdrlen + plen + 8));
+ pn_vector[0] = pframe[hdrlen];
+ pn_vector[1] = pframe[hdrlen+1];
+ pn_vector[2] = pframe[hdrlen+4];
+ pn_vector[3] = pframe[hdrlen+5];
+ pn_vector[4] = pframe[hdrlen+6];
+ pn_vector[5] = pframe[hdrlen+7];
+ construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8,
+ pn_vector);
+ construct_mic_header1(mic_header1, hdrlen, message);
+ construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
+ payload_remainder = (plen - 8) % 16;
+ num_blocks = (plen - 8) / 16;
+ /* Find start of payload */
+ payload_index = (hdrlen + 8);
+ /* Calculate MIC */
+ aes128k128d(key, mic_iv, aes_out);
+ bitwise_xor(aes_out, mic_header1, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ bitwise_xor(aes_out, mic_header2, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ for (i = 0; i < num_blocks; i++) {
+ bitwise_xor(aes_out, &message[payload_index], chain_buffer);
+ payload_index += 16;
+ aes128k128d(key, chain_buffer, aes_out);
+ }
+ /* Add on the final payload block if it needs padding */
+ if (payload_remainder > 0) {
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < payload_remainder; j++)
+ padded_buffer[j] = message[payload_index++];
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ aes128k128d(key, chain_buffer, aes_out);
+ }
+ for (j = 0 ; j < 8; j++)
+ mic[j] = aes_out[j];
+ /* Insert MIC into payload */
+ for (j = 0; j < 8; j++)
+ message[payload_index+j] = mic[j];
+ payload_index = hdrlen + 8;
+ for (i = 0; i < num_blocks; i++) {
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ message, pn_vector, i + 1);
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, &message[payload_index], chain_buffer);
+ for (j = 0; j < 16; j++)
+ message[payload_index++] = chain_buffer[j];
+ }
+ if (payload_remainder > 0) { /* If short final block, pad it,*/
+ /* encrypt and copy unpadded part back */
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
+ message, pn_vector, num_blocks+1);
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < payload_remainder; j++)
+ padded_buffer[j] = message[payload_index + j];
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ for (j = 0; j < payload_remainder; j++)
+ message[payload_index++] = chain_buffer[j];
+ }
+ /* Encrypt the MIC */
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message,
+ pn_vector, 0);
+ for (j = 0; j < 16; j++)
+ padded_buffer[j] = 0x00;
+ for (j = 0; j < 8; j++)
+ padded_buffer[j] = message[j + hdrlen + plen];
+ aes128k128d(key, ctr_preload, aes_out);
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ for (j = 0; j < 8; j++)
+ message[payload_index++] = chain_buffer[j];
+ /* compare the mic */
+ return _SUCCESS;
+}
+
+u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe)
+{ /* exclude ICV */
+ /* Intermediate Buffers */
+ sint length;
+ u32 prwskeylen;
+ u8 *pframe, *prwskey, *iv, idx;
+ struct sta_info *stainfo;
+ struct rx_pkt_attrib *prxattrib = &((union recv_frame *)
+ precvframe)->u.hdr.attrib;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ pframe = (unsigned char *)((union recv_frame*)precvframe)->
+ u.hdr.rx_data;
+ /* 4 start to encrypt each fragment */
+ if ((prxattrib->encrypt == _AES_)) {
+ stainfo = r8712_get_stainfo(&padapter->stapriv,
+ &prxattrib->ta[0]);
+ if (stainfo != NULL) {
+ if (IS_MCAST(prxattrib->ra)) {
+ iv = pframe+prxattrib->hdrlen;
+ idx = iv[3];
+ prwskey = &psecuritypriv->XGrpKey[
+ ((idx >> 6) & 0x3) - 1].skey[0];
+ if (psecuritypriv->binstallGrpkey == false)
+ return _FAIL;
+
+ } else
+ prwskey = &stainfo->x_UncstKey.skey[0];
+ prwskeylen = 16;
+ length = ((union recv_frame *)precvframe)->
+ u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
+ aes_decipher(prwskey, prxattrib->hdrlen, pframe,
+ length);
+ } else
+ return _FAIL;
+ }
+ return _SUCCESS;
+}
+
+void r8712_use_tkipkey_handler(void *FunctionContext)
+{
+ struct _adapter *padapter = (struct _adapter *)FunctionContext;
+
+ padapter->securitypriv.busetkipkey = true;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h
new file mode 100644
index 000000000000..782b70a352fb
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_security.h
@@ -0,0 +1,196 @@
+#ifndef __RTL871X_SECURITY_H_
+#define __RTL871X_SECURITY_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+#define _NO_PRIVACY_ 0x0
+#define _WEP40_ 0x1
+#define _TKIP_ 0x2
+#define _TKIP_WTMIC_ 0x3
+#define _AES_ 0x4
+#define _WEP104_ 0x5
+
+#define _WPA_IE_ID_ 0xdd
+#define _WPA2_IE_ID_ 0x30
+
+#ifndef Ndis802_11AuthModeWPA2
+#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1)
+#endif
+
+#ifndef Ndis802_11AuthModeWPA2PSK
+#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2)
+#endif
+union pn48 {
+ u64 val;
+#if defined(__BIG_ENDIAN)
+struct {
+ u8 TSC7;
+ u8 TSC6;
+ u8 TSC5;
+ u8 TSC4;
+ u8 TSC3;
+ u8 TSC2;
+ u8 TSC1;
+ u8 TSC0;
+} _byte_;
+#else
+struct {
+ u8 TSC0;
+ u8 TSC1;
+ u8 TSC2;
+ u8 TSC3;
+ u8 TSC4;
+ u8 TSC5;
+ u8 TSC6;
+ u8 TSC7;
+} _byte_;
+#endif
+};
+
+union Keytype {
+ u8 skey[16];
+ u32 lkey[4];
+};
+
+struct RT_PMKID_LIST {
+ u8 bUsed;
+ u8 Bssid[6];
+ u8 PMKID[16];
+ u8 SsidBuf[33];
+ u8 *ssid_octet;
+ u16 ssid_length;
+};
+
+struct security_priv {
+ u32 AuthAlgrthm; /* 802.11 auth, could be open, shared,
+ * 8021x and authswitch */
+ u32 PrivacyAlgrthm; /* This specify the privacy for shared
+ * auth. algorithm. */
+ u32 PrivacyKeyIndex; /* this is only valid for legendary
+ * wep, 0~3 for key id. */
+ union Keytype DefKey[4]; /* this is only valid for def. key */
+ u32 DefKeylen[4];
+ u32 XGrpPrivacy; /* This specify the privacy algthm.
+ * used for Grp key */
+ u32 XGrpKeyid; /* key id used for Grp Key */
+ union Keytype XGrpKey[2]; /* 802.1x Group Key, for
+ * inx0 and inx1 */
+ union Keytype XGrptxmickey[2];
+ union Keytype XGrprxmickey[2];
+ union pn48 Grptxpn; /* PN48 used for Grp Key xmit. */
+ union pn48 Grprxpn; /* PN48 used for Grp Key recv. */
+ u8 wps_hw_pbc_pressed;/*for hw pbc pressed*/
+ u8 wps_phase;/*for wps*/
+ u8 wps_ie[MAX_WPA_IE_LEN<<2];
+ int wps_ie_len;
+ u8 binstallGrpkey;
+ u8 busetkipkey;
+ struct timer_list tkip_timer;
+ u8 bcheck_grpkey;
+ u8 bgrpkey_handshake;
+ s32 sw_encrypt; /* from registry_priv */
+ s32 sw_decrypt; /* from registry_priv */
+ s32 hw_decrypted; /* if the rx packets is hw_decrypted==false,
+ * it means the hw has not been ready. */
+ u32 ndisauthtype; /* keeps the auth_type & enc_status from upper
+ * layer ioctl(wpa_supplicant or wzc) */
+ u32 ndisencryptstatus;
+ struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */
+ struct NDIS_802_11_WEP ndiswep;
+ u8 assoc_info[600];
+ u8 szofcapability[256]; /* for wpa2 usage */
+ u8 oidassociation[512]; /* for wpa/wpa2 usage */
+ u8 authenticator_ie[256]; /* store ap security information element */
+ u8 supplicant_ie[256]; /* store sta security information element */
+ /* for tkip countermeasure */
+ u32 last_mic_err_time;
+ u8 btkip_countermeasure;
+ u8 btkip_wait_report;
+ u32 btkip_countermeasure_time;
+ /*-------------------------------------------------------------------
+ * For WPA2 Pre-Authentication.
+ *------------------------------------------------------------------ */
+ struct RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE];
+ u8 PMKIDIndex;
+};
+
+#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \
+do { \
+ switch (psecuritypriv->AuthAlgrthm) { \
+ case 0: \
+ case 1: \
+ case 3: \
+ encry_algo = (u8)psecuritypriv->PrivacyAlgrthm; \
+ break; \
+ case 2: \
+ if (bmcst) \
+ encry_algo = (u8)psecuritypriv->XGrpPrivacy; \
+ else \
+ encry_algo = (u8)psta->XPrivacy; \
+ break; \
+ } \
+} while (0)
+#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt)\
+do {\
+ switch (encrypt) { \
+ case _WEP40_: \
+ case _WEP104_: \
+ iv_len = 4; \
+ icv_len = 4; \
+ break; \
+ case _TKIP_: \
+ iv_len = 8; \
+ icv_len = 4; \
+ break; \
+ case _AES_: \
+ iv_len = 8; \
+ icv_len = 8; \
+ break; \
+ default: \
+ iv_len = 0; \
+ icv_len = 0; \
+ break; \
+ } \
+} while (0)
+#define GET_TKIP_PN(iv, txpn) \
+do {\
+ txpn._byte_.TSC0 = iv[2];\
+ txpn._byte_.TSC1 = iv[0];\
+ txpn._byte_.TSC2 = iv[4];\
+ txpn._byte_.TSC3 = iv[5];\
+ txpn._byte_.TSC4 = iv[6];\
+ txpn._byte_.TSC5 = iv[7];\
+} while (0)
+
+#define ROL32(A, n) (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1)))
+#define ROR32(A, n) ROL32((A), 32 - (n))
+
+struct mic_data {
+ u32 K0, K1; /* Key */
+ u32 L, R; /* Current state */
+ u32 M; /* Message accumulator (single word) */
+ u32 nBytesInM; /* # bytes in M */
+};
+
+void seccalctkipmic(
+ u8 *key,
+ u8 *header,
+ u8 *data,
+ u32 data_len,
+ u8 *Miccode,
+ u8 priority);
+
+void r8712_secmicsetkey(struct mic_data *pmicdata, u8 * key);
+void r8712_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nBytes);
+void r8712_secgetmic(struct mic_data *pmicdata, u8 * dst);
+u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe);
+u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe);
+void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe);
+u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe);
+u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe);
+void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe);
+void r8712_use_tkipkey_handler(void *FunctionContext);
+
+#endif /*__RTL871X_SECURITY_H_ */
+
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
new file mode 100644
index 000000000000..64f569618839
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -0,0 +1,299 @@
+/******************************************************************************
+ * rtl871x_sta_mgt.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_STA_MGT_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "xmit_osdep.h"
+#include "sta_info.h"
+
+static void _init_stainfo(struct sta_info *psta)
+{
+ memset((u8 *)psta, 0, sizeof(struct sta_info));
+ spin_lock_init(&psta->lock);
+ _init_listhead(&psta->list);
+ _init_listhead(&psta->hash_list);
+ _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
+ _r8712_init_sta_recv_priv(&psta->sta_recvpriv);
+#ifdef CONFIG_R8712_AP
+ _init_listhead(&psta->auth_list);
+#endif
+}
+
+u32 _r8712_init_sta_priv(struct sta_priv *pstapriv)
+{
+ struct sta_info *psta;
+ s32 i;
+
+ pstapriv->pallocated_stainfo_buf = _malloc(sizeof(struct sta_info) *
+ NUM_STA + 4);
+ if (pstapriv->pallocated_stainfo_buf == NULL)
+ return _FAIL;
+ pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
+ ((addr_t)(pstapriv->pallocated_stainfo_buf) & 3);
+ _init_queue(&pstapriv->free_sta_queue);
+ spin_lock_init(&pstapriv->sta_hash_lock);
+ pstapriv->asoc_sta_count = 0;
+ _init_queue(&pstapriv->sleep_q);
+ _init_queue(&pstapriv->wakeup_q);
+ psta = (struct sta_info *)(pstapriv->pstainfo_buf);
+ for (i = 0; i < NUM_STA; i++) {
+ _init_stainfo(psta);
+ _init_listhead(&(pstapriv->sta_hash[i]));
+ list_insert_tail(&psta->list,
+ get_list_head(&pstapriv->free_sta_queue));
+ psta++;
+ }
+#ifdef CONFIG_R8712_AP
+ _init_listhead(&pstapriv->asoc_list);
+ _init_listhead(&pstapriv->auth_list);
+#endif
+ return _SUCCESS;
+}
+
+/* this function is used to free the memory of lock || sema for all stainfos */
+static void mfree_all_stainfo(struct sta_priv *pstapriv)
+{
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ struct sta_info *psta = NULL;
+
+ spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
+ phead = get_list_head(&pstapriv->free_sta_queue);
+ plist = get_next(phead);
+ while ((end_of_queue_search(phead, plist)) == false) {
+ psta = LIST_CONTAINOR(plist, struct sta_info, list);
+ plist = get_next(plist);
+ }
+
+ spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
+}
+
+
+static void mfree_sta_priv_lock(struct sta_priv *pstapriv)
+{
+ mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
+}
+
+u32 _r8712_free_sta_priv(struct sta_priv *pstapriv)
+{
+ if (pstapriv) {
+ mfree_sta_priv_lock(pstapriv);
+ kfree(pstapriv->pallocated_stainfo_buf);
+ }
+ return _SUCCESS;
+}
+
+struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
+{
+ uint tmp_aid;
+ s32 index;
+ struct list_head *phash_list;
+ struct sta_info *psta;
+ struct __queue *pfree_sta_queue;
+ struct recv_reorder_ctrl *preorder_ctrl;
+ int i = 0;
+ u16 wRxSeqInitialValue = 0xffff;
+ unsigned long flags;
+
+ pfree_sta_queue = &pstapriv->free_sta_queue;
+ spin_lock_irqsave(&(pfree_sta_queue->lock), flags);
+ if (_queue_empty(pfree_sta_queue) == true)
+ psta = NULL;
+ else {
+ psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue),
+ struct sta_info, list);
+ list_delete(&(psta->list));
+ tmp_aid = psta->aid;
+ _init_stainfo(psta);
+ memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
+ index = wifi_mac_hash(hwaddr);
+ if (index >= NUM_STA) {
+ psta = NULL;
+ goto exit;
+ }
+ phash_list = &(pstapriv->sta_hash[index]);
+ list_insert_tail(&psta->hash_list, phash_list);
+ pstapriv->asoc_sta_count++ ;
+
+/* For the SMC router, the sequence number of first packet of WPS handshake
+ * will be 0. In this case, this packet will be dropped by recv_decache function
+ * if we use the 0x00 as the default value for tid_rxseq variable. So, we
+ * initialize the tid_rxseq variable as the 0xffff.
+ */
+ for (i = 0; i < 16; i++)
+ memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
+ &wRxSeqInitialValue, 2);
+ /* for A-MPDU Rx reordering buffer control */
+ for (i = 0; i < 16 ; i++) {
+ preorder_ctrl = &psta->recvreorder_ctrl[i];
+ preorder_ctrl->padapter = pstapriv->padapter;
+ preorder_ctrl->indicate_seq = 0xffff;
+ preorder_ctrl->wend_b = 0xffff;
+ preorder_ctrl->wsize_b = 64;
+ _init_queue(&preorder_ctrl->pending_recvframe_queue);
+ r8712_init_recv_timer(preorder_ctrl);
+ }
+ }
+exit:
+ spin_unlock_irqrestore(&(pfree_sta_queue->lock), flags);
+ return psta;
+}
+
+/* using pstapriv->sta_hash_lock to protect */
+void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta)
+{
+ int i;
+ unsigned long irqL0;
+ struct __queue *pfree_sta_queue;
+ struct recv_reorder_ctrl *preorder_ctrl;
+ struct sta_xmit_priv *pstaxmitpriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ if (psta == NULL)
+ return;
+ pfree_sta_queue = &pstapriv->free_sta_queue;
+ pstaxmitpriv = &psta->sta_xmitpriv;
+ spin_lock_irqsave(&(pxmitpriv->vo_pending.lock), irqL0);
+ r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
+ list_delete(&(pstaxmitpriv->vo_q.tx_pending));
+ spin_unlock_irqrestore(&(pxmitpriv->vo_pending.lock), irqL0);
+ spin_lock_irqsave(&(pxmitpriv->vi_pending.lock), irqL0);
+ r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
+ list_delete(&(pstaxmitpriv->vi_q.tx_pending));
+ spin_unlock_irqrestore(&(pxmitpriv->vi_pending.lock), irqL0);
+ spin_lock_irqsave(&(pxmitpriv->bk_pending.lock), irqL0);
+ r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
+ list_delete(&(pstaxmitpriv->bk_q.tx_pending));
+ spin_unlock_irqrestore(&(pxmitpriv->bk_pending.lock), irqL0);
+ spin_lock_irqsave(&(pxmitpriv->be_pending.lock), irqL0);
+ r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
+ list_delete(&(pstaxmitpriv->be_q.tx_pending));
+ spin_unlock_irqrestore(&(pxmitpriv->be_pending.lock), irqL0);
+ list_delete(&psta->hash_list);
+ pstapriv->asoc_sta_count--;
+ /* re-init sta_info; 20061114 */
+ _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
+ _r8712_init_sta_recv_priv(&psta->sta_recvpriv);
+ /* for A-MPDU Rx reordering buffer control,
+ * cancel reordering_ctrl_timer */
+ for (i = 0; i < 16; i++) {
+ preorder_ctrl = &psta->recvreorder_ctrl[i];
+ _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
+ }
+ spin_lock(&(pfree_sta_queue->lock));
+ /* insert into free_sta_queue; 20061114 */
+ list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
+ spin_unlock(&(pfree_sta_queue->lock));
+}
+
+/* free all stainfo which in sta_hash[all] */
+void r8712_free_all_stainfo(struct _adapter *padapter)
+{
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ s32 index;
+ struct sta_info *psta = NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *pbcmc_stainfo = r8712_get_bcmc_stainfo(padapter);
+
+ if (pstapriv->asoc_sta_count == 1)
+ return;
+ spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
+ for (index = 0; index < NUM_STA; index++) {
+ phead = &(pstapriv->sta_hash[index]);
+ plist = get_next(phead);
+ while ((end_of_queue_search(phead, plist)) == false) {
+ psta = LIST_CONTAINOR(plist,
+ struct sta_info, hash_list);
+ plist = get_next(plist);
+ if (pbcmc_stainfo != psta)
+ r8712_free_stainfo(padapter , psta);
+ }
+ }
+ spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
+}
+
+/* any station allocated can be searched by hash list */
+struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
+{
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ struct sta_info *psta = NULL;
+ u32 index;
+
+ if (hwaddr == NULL)
+ return NULL;
+ index = wifi_mac_hash(hwaddr);
+ spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
+ phead = &(pstapriv->sta_hash[index]);
+ plist = get_next(phead);
+ while ((end_of_queue_search(phead, plist)) == false) {
+ psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
+ if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) {
+ /* if found the matched address */
+ break;
+ }
+ psta = NULL;
+ plist = get_next(plist);
+ }
+ spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
+ return psta;
+}
+
+void r8712_init_bcmc_stainfo(struct _adapter *padapter)
+{
+ struct sta_info *psta;
+ struct tx_servq *ptxservq;
+ unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ psta = r8712_alloc_stainfo(pstapriv, bcast_addr);
+ if (psta == NULL)
+ return;
+ ptxservq = &(psta->sta_xmitpriv.be_q);
+}
+
+struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter)
+{
+ struct sta_info *psta;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ psta = r8712_get_stainfo(pstapriv, bc_addr);
+ return psta;
+}
+
+
+u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 *mac_addr)
+{
+ return true;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_wlan_sme.h b/drivers/staging/rtl8712/rtl871x_wlan_sme.h
new file mode 100644
index 000000000000..d9733ac6a43a
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_wlan_sme.h
@@ -0,0 +1,22 @@
+#ifndef _RTL871X_WLAN_SME_H_
+#define _RTL871X_WLAN_SME_H_
+
+#define MSR_APMODE 0x0C
+#define MSR_STAMODE 0x08
+#define MSR_ADHOCMODE 0x04
+#define MSR_NOLINKMODE 0x00
+#define _1M_RATE_ 0
+#define _2M_RATE_ 1
+#define _5M_RATE_ 2
+#define _11M_RATE_ 3
+#define _6M_RATE_ 4
+#define _9M_RATE_ 5
+#define _12M_RATE_ 6
+#define _18M_RATE_ 7
+#define _24M_RATE_ 8
+#define _36M_RATE_ 9
+#define _48M_RATE_ 10
+#define _54M_RATE_ 11
+
+#endif
+
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
new file mode 100644
index 000000000000..b8195e3a72d4
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -0,0 +1,1052 @@
+/******************************************************************************
+ * rtl871x_xmit.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _RTL871X_XMIT_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "rtl871x_byteorder.h"
+#include "wifi.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+
+static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
+static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
+static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
+static void alloc_hwxmits(struct _adapter *padapter);
+static void free_hwxmits(struct _adapter *padapter);
+
+static void _init_txservq(struct tx_servq *ptxservq)
+{
+ _init_listhead(&ptxservq->tx_pending);
+ _init_queue(&ptxservq->sta_pending);
+ ptxservq->qcnt = 0;
+}
+
+void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
+{
+ memset((unsigned char *)psta_xmitpriv, 0,
+ sizeof(struct sta_xmit_priv));
+ spin_lock_init(&psta_xmitpriv->lock);
+ _init_txservq(&psta_xmitpriv->be_q);
+ _init_txservq(&psta_xmitpriv->bk_q);
+ _init_txservq(&psta_xmitpriv->vi_q);
+ _init_txservq(&psta_xmitpriv->vo_q);
+ _init_listhead(&psta_xmitpriv->legacy_dz);
+ _init_listhead(&psta_xmitpriv->apsd);
+}
+
+sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
+ struct _adapter *padapter)
+{
+ sint i;
+ struct xmit_buf *pxmitbuf;
+ struct xmit_frame *pxframe;
+
+ memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
+ spin_lock_init(&pxmitpriv->lock);
+ sema_init(&pxmitpriv->xmit_sema, 0);
+ sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
+ /*
+ Please insert all the queue initializaiton using _init_queue below
+ */
+ pxmitpriv->adapter = padapter;
+ _init_queue(&pxmitpriv->be_pending);
+ _init_queue(&pxmitpriv->bk_pending);
+ _init_queue(&pxmitpriv->vi_pending);
+ _init_queue(&pxmitpriv->vo_pending);
+ _init_queue(&pxmitpriv->bm_pending);
+ _init_queue(&pxmitpriv->legacy_dz_queue);
+ _init_queue(&pxmitpriv->apsd_queue);
+ _init_queue(&pxmitpriv->free_xmit_queue);
+ /*
+ Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
+ and initialize free_xmit_frame below.
+ Please also apply free_txobj to link_up all the xmit_frames...
+ */
+ pxmitpriv->pallocated_frame_buf = _malloc(NR_XMITFRAME *
+ sizeof(struct xmit_frame) + 4);
+ if (pxmitpriv->pallocated_frame_buf == NULL) {
+ pxmitpriv->pxmit_frame_buf = NULL;
+ return _FAIL;
+ }
+ pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
+ ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
+ pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
+ for (i = 0; i < NR_XMITFRAME; i++) {
+ _init_listhead(&(pxframe->list));
+ pxframe->padapter = padapter;
+ pxframe->frame_tag = DATA_FRAMETAG;
+ pxframe->pkt = NULL;
+ pxframe->buf_addr = NULL;
+ pxframe->pxmitbuf = NULL;
+ list_insert_tail(&(pxframe->list),
+ &(pxmitpriv->free_xmit_queue.queue));
+ pxframe++;
+ }
+ pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
+ /*
+ init xmit hw_txqueue
+ */
+ _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
+ _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
+ _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
+ _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
+ _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
+ pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
+ pxmitpriv->txirp_cnt = 1;
+ sema_init(&(pxmitpriv->tx_retevt), 0);
+ /*per AC pending irp*/
+ pxmitpriv->beq_cnt = 0;
+ pxmitpriv->bkq_cnt = 0;
+ pxmitpriv->viq_cnt = 0;
+ pxmitpriv->voq_cnt = 0;
+ /*init xmit_buf*/
+ _init_queue(&pxmitpriv->free_xmitbuf_queue);
+ _init_queue(&pxmitpriv->pending_xmitbuf_queue);
+ pxmitpriv->pallocated_xmitbuf = _malloc(NR_XMITBUFF *
+ sizeof(struct xmit_buf) + 4);
+ if (pxmitpriv->pallocated_xmitbuf == NULL)
+ return _FAIL;
+ pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
+ ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
+ pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
+ for (i = 0; i < NR_XMITBUFF; i++) {
+ _init_listhead(&pxmitbuf->list);
+ pxmitbuf->pallocated_buf = _malloc(MAX_XMITBUF_SZ +
+ XMITBUF_ALIGN_SZ);
+ if (pxmitbuf->pallocated_buf == NULL)
+ return _FAIL;
+ pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
+ ((addr_t) (pxmitbuf->pallocated_buf) &
+ (XMITBUF_ALIGN_SZ - 1));
+ r8712_xmit_resource_alloc(padapter, pxmitbuf);
+ list_insert_tail(&pxmitbuf->list,
+ &(pxmitpriv->free_xmitbuf_queue.queue));
+ pxmitbuf++;
+ }
+ pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
+ alloc_hwxmits(padapter);
+ init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
+ tasklet_init(&pxmitpriv->xmit_tasklet,
+ (void(*)(addr_t))r8712_xmit_bh,
+ (addr_t)padapter);
+ return _SUCCESS;
+}
+
+void _free_xmit_priv(struct xmit_priv *pxmitpriv)
+{
+ int i;
+ struct _adapter *padapter = pxmitpriv->adapter;
+ struct xmit_frame *pxmitframe = (struct xmit_frame *)
+ pxmitpriv->pxmit_frame_buf;
+ struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
+
+ if (pxmitpriv->pxmit_frame_buf == NULL)
+ return;
+ for (i = 0; i < NR_XMITFRAME; i++) {
+ r8712_xmit_complete(padapter, pxmitframe);
+ pxmitframe++;
+ }
+ for (i = 0; i < NR_XMITBUFF; i++) {
+ r8712_xmit_resource_free(padapter, pxmitbuf);
+ kfree(pxmitbuf->pallocated_buf);
+ pxmitbuf++;
+ }
+ kfree(pxmitpriv->pallocated_frame_buf);
+ kfree(pxmitpriv->pallocated_xmitbuf);
+ free_hwxmits(padapter);
+}
+
+sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
+ struct pkt_attrib *pattrib)
+{
+ uint i;
+ struct pkt_file pktfile;
+ struct sta_info *psta = NULL;
+ struct ethhdr etherhdr;
+
+ struct tx_cmd txdesc;
+
+ sint bmcast;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+
+ _r8712_open_pktfile(pkt, &pktfile);
+
+ i = _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
+
+ pattrib->ether_type = ntohs(etherhdr.h_proto);
+
+{
+ u8 bool;
+ /*If driver xmit ARP packet, driver can set ps mode to initial
+ * setting. It stands for getting DHCP or fix IP.*/
+ if (pattrib->ether_type == 0x0806) {
+ if (padapter->pwrctrlpriv.pwr_mode !=
+ padapter->registrypriv.power_mgnt) {
+ _cancel_timer(&(pmlmepriv->dhcp_timer), &bool);
+ r8712_set_ps_mode(padapter, padapter->registrypriv.
+ power_mgnt, padapter->registrypriv.smart_ps);
+ }
+ }
+}
+ memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
+ memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
+ pattrib->pctrl = 0;
+ if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
+ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
+ memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
+ memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
+ memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
+ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
+ /*firstly, filter packet not belongs to mp*/
+ if (pattrib->ether_type != 0x8712)
+ return _FAIL;
+ /* for mp storing the txcmd per packet,
+ * according to the info of txcmd to update pattrib */
+ /*get MP_TXDESC_SIZE bytes txcmd per packet*/
+ i = _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
+ memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
+ memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+ pattrib->pctrl = 1;
+ }
+ /* r8712_xmitframe_coalesce() overwrite this!*/
+ pattrib->pktlen = pktfile.pkt_len;
+ if (ETH_P_IP == pattrib->ether_type) {
+ /* The following is for DHCP and ARP packet, we use cck1M to
+ * tx these packets and let LPS awake some time
+ * to prevent DHCP protocol fail */
+ u8 tmp[24];
+ _r8712_pktfile_read(&pktfile, &tmp[0], 24);
+ pattrib->dhcp_pkt = 0;
+ if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
+ if (ETH_P_IP == pattrib->ether_type) {/* IP header*/
+ if (((tmp[21] == 68) && (tmp[23] == 67)) ||
+ ((tmp[21] == 67) && (tmp[23] == 68))) {
+ /* 68 : UDP BOOTP client
+ * 67 : UDP BOOTP server
+ * Use low rate to send DHCP packet.*/
+ pattrib->dhcp_pkt = 1;
+ }
+ }
+ }
+ }
+ bmcast = IS_MCAST(pattrib->ra);
+ /* get sta_info*/
+ if (bmcast) {
+ psta = r8712_get_bcmc_stainfo(padapter);
+ pattrib->mac_id = 4;
+ } else {
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
+ psta = r8712_get_stainfo(pstapriv,
+ get_bssid(pmlmepriv));
+ pattrib->mac_id = 5;
+ } else {
+ psta = r8712_get_stainfo(pstapriv, pattrib->ra);
+ if (psta == NULL) /* drop the pkt */
+ return _FAIL;
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
+ pattrib->mac_id = 5;
+ else
+ pattrib->mac_id = psta->mac_id;
+ }
+ }
+
+ if (psta) {
+ pattrib->psta = psta;
+ } else {
+ /* if we cannot get psta => drrp the pkt */
+ return _FAIL;
+ }
+
+ pattrib->ack_policy = 0;
+ /* get ether_hdr_len */
+ pattrib->pkt_hdrlen = ETH_HLEN;
+
+ if (pqospriv->qos_option)
+ r8712_set_qos(&pktfile, pattrib);
+ else {
+ pattrib->hdrlen = WLAN_HDR_A3_LEN;
+ pattrib->subtype = WIFI_DATA_TYPE;
+ pattrib->priority = 0;
+ }
+ if (psta->ieee8021x_blocked == true) {
+ pattrib->encrypt = 0;
+ if ((pattrib->ether_type != 0x888e) &&
+ (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false))
+ return _FAIL;
+ } else
+ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
+ switch (pattrib->encrypt) {
+ case _WEP40_:
+ case _WEP104_:
+ pattrib->iv_len = 4;
+ pattrib->icv_len = 4;
+ break;
+ case _TKIP_:
+ pattrib->iv_len = 8;
+ pattrib->icv_len = 4;
+ if (padapter->securitypriv.busetkipkey == _FAIL)
+ return _FAIL;
+ break;
+ case _AES_:
+ pattrib->iv_len = 8;
+ pattrib->icv_len = 8;
+ break;
+ default:
+ pattrib->iv_len = 0;
+ pattrib->icv_len = 0;
+ break;
+ }
+
+ if (pattrib->encrypt &&
+ ((padapter->securitypriv.sw_encrypt == true) ||
+ (psecuritypriv->hw_decrypted == false)))
+ pattrib->bswenc = true;
+ else
+ pattrib->bswenc = false;
+ /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
+ * some settings above.*/
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
+ pattrib->priority = (txdesc.txdw1 >> QSEL_SHT) & 0x1f;
+ return _SUCCESS;
+}
+
+static sint xmitframe_addmic(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe)
+{
+ u32 curfragnum, length, datalen;
+ u8 *pframe, *payload, mic[8];
+ struct mic_data micdata;
+ struct sta_info *stainfo;
+ struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
+ sint bmcst = IS_MCAST(pattrib->ra);
+
+ if (pattrib->psta)
+ stainfo = pattrib->psta;
+ else
+ stainfo = r8712_get_stainfo(&padapter->stapriv,
+ &pattrib->ra[0]);
+ if (pattrib->encrypt == _TKIP_) {
+ /*encode mic code*/
+ if (stainfo != NULL) {
+ u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0};
+ datalen = pattrib->pktlen - pattrib->hdrlen;
+ pframe = pxmitframe->buf_addr + TXDESC_OFFSET;;
+ if (bmcst) {
+ if (!memcmp(psecuritypriv->XGrptxmickey
+ [psecuritypriv->XGrpKeyid].skey,
+ null_key, 16))
+ return _FAIL;
+ /*start to calculate the mic code*/
+ r8712_secmicsetkey(&micdata,
+ psecuritypriv->
+ XGrptxmickey[psecuritypriv->
+ XGrpKeyid].skey);
+ } else {
+ if (!memcmp(&stainfo->tkiptxmickey.skey[0],
+ null_key, 16))
+ return _FAIL;
+ /* start to calculate the mic code */
+ r8712_secmicsetkey(&micdata,
+ &stainfo->tkiptxmickey.skey[0]);
+ }
+ if (pframe[1] & 1) { /* ToDS==1 */
+ r8712_secmicappend(&micdata,
+ &pframe[16], 6); /*DA*/
+ if (pframe[1]&2) /* From Ds==1 */
+ r8712_secmicappend(&micdata,
+ &pframe[24], 6);
+ else
+ r8712_secmicappend(&micdata,
+ &pframe[10], 6);
+ } else { /* ToDS==0 */
+ r8712_secmicappend(&micdata,
+ &pframe[4], 6); /* DA */
+ if (pframe[1]&2) /* From Ds==1 */
+ r8712_secmicappend(&micdata,
+ &pframe[16], 6);
+ else
+ r8712_secmicappend(&micdata,
+ &pframe[10], 6);
+ }
+ if (pqospriv->qos_option == 1)
+ priority[0] = (u8)pxmitframe->
+ attrib.priority;
+ r8712_secmicappend(&micdata, &priority[0], 4);
+ payload = pframe;
+ for (curfragnum = 0; curfragnum < pattrib->nr_frags;
+ curfragnum++) {
+ payload = (u8 *)RND4((addr_t)(payload));
+ payload = payload+pattrib->
+ hdrlen+pattrib->iv_len;
+ if ((curfragnum + 1) == pattrib->nr_frags) {
+ length = pattrib->last_txcmdsz -
+ pattrib->hdrlen -
+ pattrib->iv_len -
+ ((psecuritypriv->sw_encrypt)
+ ? pattrib->icv_len : 0);
+ r8712_secmicappend(&micdata, payload,
+ length);
+ payload = payload+length;
+ } else{
+ length = pxmitpriv->frag_len -
+ pattrib->hdrlen-pattrib->iv_len -
+ ((psecuritypriv->sw_encrypt) ?
+ pattrib->icv_len : 0);
+ r8712_secmicappend(&micdata, payload,
+ length);
+ payload = payload + length +
+ pattrib->icv_len;
+ }
+ }
+ r8712_secgetmic(&micdata, &(mic[0]));
+ /* add mic code and add the mic code length in
+ * last_txcmdsz */
+ memcpy(payload, &(mic[0]), 8);
+ pattrib->last_txcmdsz += 8;
+ payload = payload-pattrib->last_txcmdsz + 8;
+ }
+ }
+ return _SUCCESS;
+}
+
+static sint xmitframe_swencrypt(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe)
+{
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+
+ if (pattrib->bswenc) {
+ switch (pattrib->encrypt) {
+ case _WEP40_:
+ case _WEP104_:
+ r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
+ break;
+ case _TKIP_:
+ r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
+ break;
+ case _AES_:
+ r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
+ break;
+ default:
+ break;
+ }
+ }
+ return _SUCCESS;
+}
+
+static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr,
+ struct pkt_attrib *pattrib)
+{
+ u16 *qc;
+
+ struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv = &pmlmepriv->qospriv;
+ u16 *fctrl = &pwlanhdr->frame_ctl;
+ memset(hdr, 0, WLANHDR_OFFSET);
+ SetFrameSubType(fctrl, pattrib->subtype);
+ if (pattrib->subtype & WIFI_DATA_TYPE) {
+ if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)) {
+ /* to_ds = 1, fr_ds = 0; */
+ SetToDs(fctrl);
+ memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
+ ETH_ALEN);
+ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
+ memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
+ } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)) {
+ /* to_ds = 0, fr_ds = 1; */
+ SetFrDs(fctrl);
+ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
+ ETH_ALEN);
+ memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
+ } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
+ || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
+ == true)) {
+ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
+ ETH_ALEN);
+ } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
+ memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
+ memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
+ memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
+ ETH_ALEN);
+ } else
+ return _FAIL;
+
+ if (pattrib->encrypt)
+ SetPrivacy(fctrl);
+ if (pqospriv->qos_option) {
+ qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
+ if (pattrib->priority)
+ SetPriority(qc, pattrib->priority);
+ SetAckpolicy(qc, pattrib->ack_policy);
+ }
+ /* TODO: fill HT Control Field */
+ /* Update Seq Num will be handled by f/w */
+ {
+ struct sta_info *psta;
+
+ sint bmcst = IS_MCAST(pattrib->ra);
+ if (pattrib->psta)
+ psta = pattrib->psta;
+ else {
+ if (bmcst)
+ psta = r8712_get_bcmc_stainfo(padapter);
+ else
+ psta =
+ r8712_get_stainfo(&padapter->stapriv,
+ pattrib->ra);
+ }
+ if (psta) {
+ psta->sta_xmitpriv.txseq_tid
+ [pattrib->priority]++;
+ psta->sta_xmitpriv.txseq_tid[pattrib->priority]
+ &= 0xFFF;
+ pattrib->seqnum = psta->sta_xmitpriv.
+ txseq_tid[pattrib->priority];
+ SetSeqNum(hdr, pattrib->seqnum);
+ }
+ }
+ }
+ return _SUCCESS;
+}
+
+static sint r8712_put_snap(u8 *data, u16 h_proto)
+{
+ struct ieee80211_snap_hdr *snap;
+ const u8 *oui;
+
+ snap = (struct ieee80211_snap_hdr *)data;
+ snap->dsap = 0xaa;
+ snap->ssap = 0xaa;
+ snap->ctrl = 0x03;
+ if (h_proto == 0x8137 || h_proto == 0x80f3)
+ oui = P802_1H_OUI;
+ else
+ oui = RFC1042_OUI;
+ snap->oui[0] = oui[0];
+ snap->oui[1] = oui[1];
+ snap->oui[2] = oui[2];
+ *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
+ return SNAP_SIZE + sizeof(u16);
+}
+
+/*
+ * This sub-routine will perform all the following:
+ * 1. remove 802.3 header.
+ * 2. create wlan_header, based on the info in pxmitframe
+ * 3. append sta's iv/ext-iv
+ * 4. append LLC
+ * 5. move frag chunk from pframe to pxmitframe->mem
+ * 6. apply sw-encrypt, if necessary.
+ */
+sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
+ struct xmit_frame *pxmitframe)
+{
+ struct pkt_file pktfile;
+
+ sint frg_len, mpdu_len, llc_sz;
+ u32 mem_sz;
+ u8 frg_inx;
+ addr_t addr;
+ u8 *pframe, *mem_start, *ptxdesc;
+ struct sta_info *psta;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 *pbuf_start;
+ sint bmcst = IS_MCAST(pattrib->ra);
+
+ if (pattrib->psta == NULL)
+ return _FAIL;
+ psta = pattrib->psta;
+ if (pxmitframe->buf_addr == NULL)
+ return _FAIL;
+ pbuf_start = pxmitframe->buf_addr;
+ ptxdesc = pbuf_start;
+ mem_start = pbuf_start + TXDESC_OFFSET;
+ if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL)
+ return _FAIL;
+ _r8712_open_pktfile(pkt, &pktfile);
+ _r8712_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
+ /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
+ if (pattrib->ether_type == 0x8712) {
+ /* take care - update_txdesc overwrite this */
+ _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
+ }
+ }
+ pattrib->pktlen = pktfile.pkt_len;
+ frg_inx = 0;
+ frg_len = pxmitpriv->frag_len - 4;
+ while (1) {
+ llc_sz = 0;
+ mpdu_len = frg_len;
+ pframe = mem_start;
+ SetMFrag(mem_start);
+ pframe += pattrib->hdrlen;
+ mpdu_len -= pattrib->hdrlen;
+ /* adding icv, if necessary...*/
+ if (pattrib->iv_len) {
+ if (psta != NULL) {
+ switch (pattrib->encrypt) {
+ case _WEP40_:
+ case _WEP104_:
+ WEP_IV(pattrib->iv, psta->txpn,
+ (u8)psecuritypriv->
+ PrivacyKeyIndex);
+ break;
+ case _TKIP_:
+ if (bmcst)
+ TKIP_IV(pattrib->iv,
+ psta->txpn,
+ (u8)psecuritypriv->
+ XGrpKeyid);
+ else
+ TKIP_IV(pattrib->iv, psta->txpn,
+ 0);
+ break;
+ case _AES_:
+ if (bmcst)
+ AES_IV(pattrib->iv, psta->txpn,
+ (u8)psecuritypriv->
+ XGrpKeyid);
+ else
+ AES_IV(pattrib->iv, psta->txpn,
+ 0);
+ break;
+ }
+ }
+ memcpy(pframe, pattrib->iv, pattrib->iv_len);
+ pframe += pattrib->iv_len;
+ mpdu_len -= pattrib->iv_len;
+ }
+ if (frg_inx == 0) {
+ llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
+ pframe += llc_sz;
+ mpdu_len -= llc_sz;
+ }
+ if ((pattrib->icv_len > 0) && (pattrib->bswenc))
+ mpdu_len -= pattrib->icv_len;
+ if (bmcst)
+ mem_sz = _r8712_pktfile_read(&pktfile, pframe,
+ pattrib->pktlen);
+ else
+ mem_sz = _r8712_pktfile_read(&pktfile, pframe,
+ mpdu_len);
+ pframe += mem_sz;
+ if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
+ memcpy(pframe, pattrib->icv, pattrib->icv_len);
+ pframe += pattrib->icv_len;
+ }
+ frg_inx++;
+ if (bmcst || (r8712_endofpktfile(&pktfile) == true)) {
+ pattrib->nr_frags = frg_inx;
+ pattrib->last_txcmdsz = pattrib->hdrlen +
+ pattrib->iv_len +
+ ((pattrib->nr_frags == 1) ?
+ llc_sz : 0) +
+ ((pattrib->bswenc) ?
+ pattrib->icv_len : 0) + mem_sz;
+ ClearMFrag(mem_start);
+ break;
+ }
+ addr = (addr_t)(pframe);
+ mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
+ memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
+ }
+
+ if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
+ return _FAIL;
+ xmitframe_swencrypt(padapter, pxmitframe);
+ return _SUCCESS;
+}
+
+void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
+{
+ uint protection;
+ u8 *perp;
+ sint erp_len;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+
+ switch (pxmitpriv->vcs_setting) {
+ case DISABLE_VCS:
+ pxmitpriv->vcs = NONE_VCS;
+ break;
+ case ENABLE_VCS:
+ break;
+ case AUTO_VCS:
+ default:
+ perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
+ if (perp == NULL)
+ pxmitpriv->vcs = NONE_VCS;
+ else {
+ protection = (*(perp + 2)) & BIT(1);
+ if (protection) {
+ if (pregistrypriv->vcs_type == RTS_CTS)
+ pxmitpriv->vcs = RTS_CTS;
+ else
+ pxmitpriv->vcs = CTS_TO_SELF;
+ } else
+ pxmitpriv->vcs = NONE_VCS;
+ }
+ break;
+ }
+}
+
+struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
+{
+ unsigned long irqL;
+ struct xmit_buf *pxmitbuf = NULL;
+ struct list_head *plist, *phead;
+ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
+
+ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
+ if (_queue_empty(pfree_xmitbuf_queue) == true)
+ pxmitbuf = NULL;
+ else {
+ phead = get_list_head(pfree_xmitbuf_queue);
+ plist = get_next(phead);
+ pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
+ list_delete(&(pxmitbuf->list));
+ }
+ if (pxmitbuf != NULL)
+ pxmitpriv->free_xmitbuf_cnt--;
+ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
+ return pxmitbuf;
+}
+
+int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
+{
+ unsigned long irqL;
+ struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
+
+ if (pxmitbuf == NULL)
+ return _FAIL;
+ spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
+ list_delete(&pxmitbuf->list);
+ list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
+ pxmitpriv->free_xmitbuf_cnt++;
+ spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
+ return _SUCCESS;
+}
+
+/*
+Calling context:
+1. OS_TXENTRY
+2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
+
+If we turn on USE_RXTHREAD, then, no need for critical section.
+Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
+
+Must be very very cautious...
+
+*/
+
+struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
+{
+ /*
+ Please remember to use all the osdep_service api,
+ and lock/unlock or _enter/_exit critical to protect
+ pfree_xmit_queue
+ */
+ unsigned long irqL;
+ struct xmit_frame *pxframe = NULL;
+ struct list_head *plist, *phead;
+ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
+
+ spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
+ if (_queue_empty(pfree_xmit_queue) == true)
+ pxframe = NULL;
+ else {
+ phead = get_list_head(pfree_xmit_queue);
+ plist = get_next(phead);
+ pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
+ list_delete(&(pxframe->list));
+ }
+ if (pxframe != NULL) {
+ pxmitpriv->free_xmitframe_cnt--;
+ pxframe->buf_addr = NULL;
+ pxframe->pxmitbuf = NULL;
+ pxframe->attrib.psta = NULL;
+ pxframe->pkt = NULL;
+ }
+ spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
+ return pxframe;
+}
+
+void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
+ struct xmit_frame *pxmitframe)
+{
+ unsigned long irqL;
+ struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
+ struct _adapter *padapter = pxmitpriv->adapter;
+
+ if (pxmitframe == NULL)
+ return;
+ if (pxmitframe->pkt)
+ r8712_xmit_complete(padapter, pxmitframe);
+ spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
+ list_delete(&pxmitframe->list);
+ list_insert_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
+ pxmitpriv->free_xmitframe_cnt++;
+ spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
+ if (netif_queue_stopped(padapter->pnetdev))
+ netif_wake_queue(padapter->pnetdev);
+}
+
+void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
+ struct xmit_frame *pxmitframe)
+{
+ if (pxmitframe == NULL)
+ return;
+ if (pxmitframe->frame_tag == DATA_FRAMETAG)
+ r8712_free_xmitframe(pxmitpriv, pxmitframe);
+}
+
+void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
+ struct __queue *pframequeue)
+{
+ unsigned long irqL;
+ struct list_head *plist, *phead;
+ struct xmit_frame *pxmitframe;
+
+ spin_lock_irqsave(&(pframequeue->lock), irqL);
+ phead = get_list_head(pframequeue);
+ plist = get_next(phead);
+ while (end_of_queue_search(phead, plist) == false) {
+ pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
+ plist = get_next(plist);
+ r8712_free_xmitframe(pxmitpriv, pxmitframe);
+ }
+ spin_unlock_irqrestore(&(pframequeue->lock), irqL);
+}
+
+static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
+ struct __queue **ppstapending,
+ struct sta_info *psta, sint up)
+{
+
+ struct tx_servq *ptxservq;
+ struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
+
+ switch (up) {
+ case 1:
+ case 2:
+ ptxservq = &(psta->sta_xmitpriv.bk_q);
+ *ppstapending = &padapter->xmitpriv.bk_pending;
+ (phwxmits+3)->accnt++;
+ break;
+ case 4:
+ case 5:
+ ptxservq = &(psta->sta_xmitpriv.vi_q);
+ *ppstapending = &padapter->xmitpriv.vi_pending;
+ (phwxmits+1)->accnt++;
+ break;
+ case 6:
+ case 7:
+ ptxservq = &(psta->sta_xmitpriv.vo_q);
+ *ppstapending = &padapter->xmitpriv.vo_pending;
+ (phwxmits+0)->accnt++;
+ break;
+ case 0:
+ case 3:
+ default:
+ ptxservq = &(psta->sta_xmitpriv.be_q);
+ *ppstapending = &padapter->xmitpriv.be_pending;
+ (phwxmits + 2)->accnt++;
+ break;
+ }
+ return ptxservq;
+}
+
+/*
+ * Will enqueue pxmitframe to the proper queue, and indicate it
+ * to xx_pending list.....
+ */
+sint r8712_xmit_classifier(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe)
+{
+ unsigned long irqL0;
+ struct __queue *pstapending;
+ struct sta_info *psta;
+ struct tx_servq *ptxservq;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ sint bmcst = IS_MCAST(pattrib->ra);
+
+ if (pattrib->psta)
+ psta = pattrib->psta;
+ else {
+ if (bmcst)
+ psta = r8712_get_bcmc_stainfo(padapter);
+ else {
+ if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
+ psta = r8712_get_stainfo(pstapriv,
+ get_bssid(pmlmepriv));
+ else
+ psta = r8712_get_stainfo(pstapriv, pattrib->ra);
+ }
+ }
+ if (psta == NULL)
+ return _FAIL;
+ ptxservq = get_sta_pending(padapter, &pstapending,
+ psta, pattrib->priority);
+ spin_lock_irqsave(&pstapending->lock, irqL0);
+ if (is_list_empty(&ptxservq->tx_pending))
+ list_insert_tail(&ptxservq->tx_pending,
+ get_list_head(pstapending));
+ list_insert_tail(&pxmitframe->list,
+ get_list_head(&ptxservq->sta_pending));
+ ptxservq->qcnt++;
+ spin_unlock_irqrestore(&pstapending->lock, irqL0);
+ return _SUCCESS;
+}
+
+static void alloc_hwxmits(struct _adapter *padapter)
+{
+ struct hw_xmit *hwxmits;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
+ pxmitpriv->hwxmits = (struct hw_xmit *)_malloc(sizeof(struct hw_xmit) *
+ pxmitpriv->hwxmit_entry);
+ if (pxmitpriv->hwxmits == NULL)
+ return;
+ hwxmits = pxmitpriv->hwxmits;
+ if (pxmitpriv->hwxmit_entry == 5) {
+ pxmitpriv->bmc_txqueue.head = 0;
+ hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
+ hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
+ pxmitpriv->vo_txqueue.head = 0;
+ hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
+ hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
+ pxmitpriv->vi_txqueue.head = 0;
+ hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
+ hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
+ pxmitpriv->bk_txqueue.head = 0;
+ hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
+ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
+ pxmitpriv->be_txqueue.head = 0;
+ hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
+ hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
+ } else if (pxmitpriv->hwxmit_entry == 4) {
+ pxmitpriv->vo_txqueue.head = 0;
+ hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
+ hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
+ pxmitpriv->vi_txqueue.head = 0;
+ hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
+ hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
+ pxmitpriv->be_txqueue.head = 0;
+ hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
+ hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
+ pxmitpriv->bk_txqueue.head = 0;
+ hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
+ hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
+ }
+}
+
+static void free_hwxmits(struct _adapter *padapter)
+{
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ if (pxmitpriv->hwxmits)
+ kfree((u8 *)pxmitpriv->hwxmits);
+}
+
+static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
+{
+ sint i;
+
+ for (i = 0; i < entry; i++, phwxmit++) {
+ spin_lock_init(&phwxmit->xmit_lock);
+ _init_listhead(&phwxmit->pending);
+ phwxmit->txcmdcnt = 0;
+ phwxmit->accnt = 0;
+ }
+}
+
+/*
+ * tx_action == 0 == no frames to transmit
+ * tx_action > 0 ==> we have frames to transmit
+ * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
+ * to transmit 1 frame.
+ */
+
+int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
+{
+ unsigned long irqL;
+ int ret;
+ struct xmit_buf *pxmitbuf = NULL;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+
+ r8712_do_queue_select(padapter, pattrib);
+ spin_lock_irqsave(&pxmitpriv->lock, irqL);
+ if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
+ ret = false;
+ r8712_xmit_enqueue(padapter, pxmitframe);
+ spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
+ return ret;
+ }
+ pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL) { /*enqueue packet*/
+ ret = false;
+ r8712_xmit_enqueue(padapter, pxmitframe);
+ spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
+ } else { /*dump packet directly*/
+ spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
+ ret = true;
+ pxmitframe->pxmitbuf = pxmitbuf;
+ pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
+ pxmitframe->buf_addr = pxmitbuf->pbuf;
+ r8712_xmit_direct(padapter, pxmitframe);
+ }
+ return ret;
+}
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h
new file mode 100644
index 000000000000..d518ce85585d
--- /dev/null
+++ b/drivers/staging/rtl8712/rtl871x_xmit.h
@@ -0,0 +1,260 @@
+#ifndef _RTL871X_XMIT_H_
+#define _RTL871X_XMIT_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "xmit_osdep.h"
+
+#define MAX_XMITBUF_SZ (2048)
+#define NR_XMITBUFF (4)
+#define XMITBUF_ALIGN_SZ 512
+#define TX_GUARD_BAND 5
+#define MAX_NUMBLKS (1)
+
+/* Fixed the Big Endian bug when using the software driver encryption.*/
+#define WEP_IV(pattrib_iv, txpn, keyidx)\
+do { \
+ pattrib_iv[0] = txpn._byte_.TSC0;\
+ pattrib_iv[1] = txpn._byte_.TSC1;\
+ pattrib_iv[2] = txpn._byte_.TSC2;\
+ pattrib_iv[3] = ((keyidx & 0x3)<<6);\
+ txpn.val = (txpn.val == 0xffffff) ? 0 : (txpn.val+1);\
+} while (0)
+
+/* Fixed the Big Endian bug when doing the Tx.
+ * The Linksys WRH54G will check this.*/
+#define TKIP_IV(pattrib_iv, txpn, keyidx)\
+do { \
+ pattrib_iv[0] = txpn._byte_.TSC1;\
+ pattrib_iv[1] = (txpn._byte_.TSC1 | 0x20) & 0x7f;\
+ pattrib_iv[2] = txpn._byte_.TSC0;\
+ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\
+ pattrib_iv[4] = txpn._byte_.TSC2;\
+ pattrib_iv[5] = txpn._byte_.TSC3;\
+ pattrib_iv[6] = txpn._byte_.TSC4;\
+ pattrib_iv[7] = txpn._byte_.TSC5;\
+ txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \
+ (txpn.val+1);\
+} while (0)
+
+#define AES_IV(pattrib_iv, txpn, keyidx)\
+do { \
+ pattrib_iv[0] = txpn._byte_.TSC0;\
+ pattrib_iv[1] = txpn._byte_.TSC1;\
+ pattrib_iv[2] = 0;\
+ pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\
+ pattrib_iv[4] = txpn._byte_.TSC2;\
+ pattrib_iv[5] = txpn._byte_.TSC3;\
+ pattrib_iv[6] = txpn._byte_.TSC4;\
+ pattrib_iv[7] = txpn._byte_.TSC5;\
+ txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \
+ (txpn.val+1);\
+} while (0)
+
+struct hw_xmit {
+ spinlock_t xmit_lock;
+ struct list_head pending;
+ struct __queue *sta_queue;
+ struct hw_txqueue *phwtxqueue;
+ sint txcmdcnt;
+ int accnt;
+};
+
+struct pkt_attrib {
+ u8 type;
+ u8 subtype;
+ u8 bswenc;
+ u8 dhcp_pkt;
+
+ u16 seqnum;
+ u16 ether_type;
+ u32 pktlen; /* the original 802.3 pkt raw_data len
+ * (not include ether_hdr data) */
+ u32 last_txcmdsz;
+
+ u8 pkt_hdrlen; /*the original 802.3 pkt header len*/
+ u8 hdrlen; /*the WLAN Header Len*/
+ u8 nr_frags;
+ u8 ack_policy;
+ u8 mac_id;
+ u8 vcs_mode; /*virtual carrier sense method*/
+ u8 pctrl;/*per packet txdesc control enable*/
+ u8 qsel;
+
+ u8 priority;
+ u8 encrypt; /* when 0 indicate no encrypt. when non-zero,
+ * indicate the encrypt algorith*/
+ u8 iv_len;
+ u8 icv_len;
+ unsigned char iv[8];
+ unsigned char icv[8];
+ u8 dst[ETH_ALEN];
+ u8 src[ETH_ALEN];
+ u8 ta[ETH_ALEN];
+ u8 ra[ETH_ALEN];
+ struct sta_info *psta;
+};
+
+#define WLANHDR_OFFSET 64
+#define DATA_FRAMETAG 0x01
+#define L2_FRAMETAG 0x02
+#define MGNT_FRAMETAG 0x03
+#define AMSDU_FRAMETAG 0x04
+#define EII_FRAMETAG 0x05
+#define IEEE8023_FRAMETAG 0x06
+#define MP_FRAMETAG 0x07
+#define TXAGG_FRAMETAG 0x08
+
+struct xmit_buf {
+ struct list_head list;
+
+ u8 *pallocated_buf;
+ u8 *pbuf;
+ struct urb *pxmit_urb[8];
+};
+
+struct xmit_frame {
+ struct list_head list;
+ struct pkt_attrib attrib;
+ _pkt *pkt;
+ int frame_tag;
+ struct _adapter *padapter;
+ u8 *buf_addr;
+ struct xmit_buf *pxmitbuf;
+ u8 *mem_addr;
+ u16 sz[8];
+ struct urb *pxmit_urb[8];
+ u8 bpending[8];
+ u8 last[8];
+};
+
+struct tx_servq {
+ struct list_head tx_pending;
+ struct __queue sta_pending;
+ int qcnt;
+};
+
+struct sta_xmit_priv {
+ spinlock_t lock;
+ sint option;
+ sint apsd_setting; /* When bit mask is on, the associated edca
+ * queue supports APSD.*/
+ struct tx_servq be_q; /* priority == 0,3 */
+ struct tx_servq bk_q; /* priority == 1,2*/
+ struct tx_servq vi_q; /*priority == 4,5*/
+ struct tx_servq vo_q; /*priority == 6,7*/
+ struct list_head legacy_dz;
+ struct list_head apsd;
+ u16 txseq_tid[16];
+ uint sta_tx_bytes;
+ u64 sta_tx_pkts;
+ uint sta_tx_fail;
+};
+
+struct hw_txqueue {
+ /*volatile*/ sint head;
+ /*volatile*/ sint tail;
+ /*volatile*/ sint free_sz; /*in units of 64 bytes*/
+ /*volatile*/ sint free_cmdsz;
+ /*volatile*/ sint txsz[8];
+ uint ff_hwaddr;
+ uint cmd_hwaddr;
+ sint ac_tag;
+};
+
+struct xmit_priv {
+ spinlock_t lock;
+ struct semaphore xmit_sema;
+ struct semaphore terminate_xmitthread_sema;
+ struct __queue be_pending;
+ struct __queue bk_pending;
+ struct __queue vi_pending;
+ struct __queue vo_pending;
+ struct __queue bm_pending;
+ struct __queue legacy_dz_queue;
+ struct __queue apsd_queue;
+ u8 *pallocated_frame_buf;
+ u8 *pxmit_frame_buf;
+ uint free_xmitframe_cnt;
+ uint mapping_addr;
+ uint pkt_sz;
+ struct __queue free_xmit_queue;
+ struct hw_txqueue be_txqueue;
+ struct hw_txqueue bk_txqueue;
+ struct hw_txqueue vi_txqueue;
+ struct hw_txqueue vo_txqueue;
+ struct hw_txqueue bmc_txqueue;
+ uint frag_len;
+ struct _adapter *adapter;
+ u8 vcs_setting;
+ u8 vcs;
+ u8 vcs_type;
+ u16 rts_thresh;
+ uint tx_bytes;
+ u64 tx_pkts;
+ uint tx_drop;
+ struct hw_xmit *hwxmits;
+ u8 hwxmit_entry;
+ struct semaphore tx_retevt;/*all tx return event;*/
+ u8 txirp_cnt;
+ struct tasklet_struct xmit_tasklet;
+ /*per AC pending irp*/
+ int beq_cnt;
+ int bkq_cnt;
+ int viq_cnt;
+ int voq_cnt;
+ struct __queue free_amsdu_xmit_queue;
+ u8 *pallocated_amsdu_frame_buf;
+ u8 *pxmit_amsdu_frame_buf;
+ uint free_amsdu_xmitframe_cnt;
+ struct __queue free_txagg_xmit_queue;
+ u8 *pallocated_txagg_frame_buf;
+ u8 *pxmit_txagg_frame_buf;
+ uint free_txagg_xmitframe_cnt;
+ int cmdseq;
+ struct __queue free_xmitbuf_queue;
+ struct __queue pending_xmitbuf_queue;
+ u8 *pallocated_xmitbuf;
+ u8 *pxmitbuf;
+ uint free_xmitbuf_cnt;
+};
+
+static inline struct __queue *get_free_xmit_queue(
+ struct xmit_priv *pxmitpriv)
+{
+ return &(pxmitpriv->free_xmit_queue);
+}
+
+int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv,
+ struct xmit_buf *pxmitbuf);
+struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv);
+void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len);
+struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv);
+void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
+ struct xmit_frame *pxmitframe);
+void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
+ struct __queue *pframequeue);
+sint r8712_xmit_classifier(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe);
+sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
+ struct xmit_frame *pxmitframe);
+sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag);
+void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv);
+sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
+ struct pkt_attrib *pattrib);
+int r8712_txframes_sta_ac_pending(struct _adapter *padapter,
+ struct pkt_attrib *pattrib);
+sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, struct _adapter *padapter);
+void _free_xmit_priv(struct xmit_priv *pxmitpriv);
+void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
+ struct xmit_frame *pxmitframe);
+int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe);
+int r8712_xmit_enqueue(struct _adapter *padapter,
+ struct xmit_frame *pxmitframe);
+int r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe);
+void r8712_xmit_bh(void *priv);
+
+#include "rtl8712_xmit.h"
+
+#endif /*_RTL871X_XMIT_H_*/
+
diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h
new file mode 100644
index 000000000000..79ad1593214f
--- /dev/null
+++ b/drivers/staging/rtl8712/sta_info.h
@@ -0,0 +1,125 @@
+#ifndef __STA_INFO_H_
+#define __STA_INFO_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "wifi.h"
+
+#define NUM_STA 32
+#define NUM_ACL 64
+
+
+/* if mode ==0, then the sta is allowed once the addr is hit.
+ * if mode ==1, then the sta is rejected once the addr is non-hit.
+ */
+struct wlan_acl_node {
+ struct list_head list;
+ u8 addr[ETH_ALEN];
+ u8 mode;
+};
+
+struct wlan_acl_pool {
+ struct wlan_acl_node aclnode[NUM_ACL];
+};
+
+struct stainfo_stats {
+
+ uint rx_pkts;
+ uint rx_bytes;
+ u64 tx_pkts;
+ uint tx_bytes;
+};
+
+struct sta_info {
+ spinlock_t lock;
+ struct list_head list; /*free_sta_queue*/
+ struct list_head hash_list; /*sta_hash*/
+ struct sta_xmit_priv sta_xmitpriv;
+ struct sta_recv_priv sta_recvpriv;
+ uint state;
+ uint aid;
+ u8 mac_id;
+ u8 qos_option;
+ u8 hwaddr[ETH_ALEN];
+ uint ieee8021x_blocked; /*0: allowed, 1:blocked */
+ uint XPrivacy; /*aes, tkip...*/
+ union Keytype tkiptxmickey;
+ union Keytype tkiprxmickey;
+ union Keytype x_UncstKey;
+ union pn48 txpn; /* PN48 used for Unicast xmit.*/
+ union pn48 rxpn; /* PN48 used for Unicast recv.*/
+ u8 bssrateset[16];
+ uint bssratelen;
+ s32 rssi;
+ s32 signal_quality;
+ struct stainfo_stats sta_stats;
+ /*for A-MPDU Rx reordering buffer control */
+ struct recv_reorder_ctrl recvreorder_ctrl[16];
+ struct ht_priv htpriv;
+ /* Notes:
+ * STA_Mode:
+ * curr_network(mlme_priv/security_priv/qos/ht)
+ * + sta_info: (STA & AP) CAP/INFO
+ * scan_q: AP CAP/INFO
+ * AP_Mode:
+ * curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO
+ * sta_info: (AP & STA) CAP/INFO
+ */
+#ifdef CONFIG_R8712_AP
+ struct list_head asoc_list;
+ struct list_head auth_list;
+ unsigned int expire_to;
+ unsigned int auth_seq;
+ unsigned int authalg;
+ unsigned char chg_txt[128];
+ unsigned int tx_ra_bitmap;
+#endif
+};
+
+struct sta_priv {
+ u8 *pallocated_stainfo_buf;
+ u8 *pstainfo_buf;
+ struct __queue free_sta_queue;
+ spinlock_t sta_hash_lock;
+ struct list_head sta_hash[NUM_STA];
+ int asoc_sta_count;
+ struct __queue sleep_q;
+ struct __queue wakeup_q;
+ struct _adapter *padapter;
+#ifdef CONFIG_R8712_AP
+ struct list_head asoc_list;
+ struct list_head auth_list;
+ unsigned int auth_to; /* sec, time to expire in authenticating. */
+ unsigned int assoc_to; /* sec, time to expire before associating. */
+ unsigned int expire_to; /* sec , time to expire after associated. */
+#endif
+};
+
+static inline u32 wifi_mac_hash(u8 *mac)
+{
+ u32 x;
+
+ x = mac[0];
+ x = (x << 2) ^ mac[1];
+ x = (x << 2) ^ mac[2];
+ x = (x << 2) ^ mac[3];
+ x = (x << 2) ^ mac[4];
+ x = (x << 2) ^ mac[5];
+ x ^= x >> 8;
+ x = x & (NUM_STA - 1);
+ return x;
+}
+
+u32 _r8712_init_sta_priv(struct sta_priv *pstapriv);
+u32 _r8712_free_sta_priv(struct sta_priv *pstapriv);
+struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv,
+ u8 *hwaddr);
+void r8712_free_stainfo(struct _adapter *padapter , struct sta_info *psta);
+void r8712_free_all_stainfo(struct _adapter *padapter);
+struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr);
+void r8712_init_bcmc_stainfo(struct _adapter *padapter);
+struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter);
+u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 * mac_addr);
+
+#endif /* _STA_INFO_H_ */
+
diff --git a/drivers/staging/rtl8712/swab.h b/drivers/staging/rtl8712/swab.h
new file mode 100644
index 000000000000..44709a91bafc
--- /dev/null
+++ b/drivers/staging/rtl8712/swab.h
@@ -0,0 +1,106 @@
+#ifndef _LINUX_BYTEORDER_SWAB_H
+#define _LINUX_BYTEORDER_SWAB_H
+
+#ifndef __u16
+ #define __u16 unsigned short
+#endif
+
+#ifndef __u32
+ #define __u32 unsigned int
+#endif
+
+#ifndef __u8
+ #define __u8 unsigned char
+#endif
+
+#ifndef __u64
+ #define __u64 unsigned long long
+#endif
+
+
+static inline __u16 ___swab16(__u16 x)
+{
+ __u16 __x = x;
+ return (__u16)(
+ (((__u16)(__x) & (__u16)0x00ffU) << 8) |
+ (((__u16)(__x) & (__u16)0xff00U) >> 8));
+
+}
+
+static inline __u32 ___swab32(__u32 x)
+{
+ __u32 __x = (x);
+ return (__u32)(
+ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) |
+ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) |
+ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) |
+ (((__u32)(__x) & (__u32)0xff000000UL) >> 24));
+}
+
+static inline __u64 ___swab64(__u64 x)
+{
+ __u64 __x = (x);
+
+ return (__u64)( \
+ (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
+ (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
+ (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
+ (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
+ (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
+ (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
+ (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+ (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56));
+}
+
+#ifndef __arch__swab16
+static inline __u16 __arch__swab16(__u16 x)
+{
+ return ___swab16(x);
+}
+
+#endif
+
+#ifndef __arch__swab32
+static inline __u32 __arch__swab32(__u32 x)
+{
+ __u32 __tmp = (x) ;
+ return ___swab32(__tmp);
+}
+#endif
+
+#ifndef __arch__swab64
+
+static inline __u64 __arch__swab64(__u64 x)
+{
+ __u64 __tmp = (x) ;
+ return ___swab64(__tmp);
+}
+
+
+#endif
+
+#define __swab16(x) __fswab16(x)
+#define __swab32(x) __fswab32(x)
+#define __swab64(x) __fswab64(x)
+
+static inline const __u16 __fswab16(__u16 x)
+{
+ return __arch__swab16(x);
+}
+static inline const __u32 __fswab32(__u32 x)
+{
+ return __arch__swab32(x);
+}
+
+#define swab16 __swab16
+#define swab32 __swab32
+#define swab64 __swab64
+#define swab16p __swab16p
+#define swab32p __swab32p
+#define swab64p __swab64p
+#define swab16s __swab16s
+#define swab32s __swab32s
+#define swab64s __swab64s
+
+#endif /* _LINUX_BYTEORDER_SWAB_H */
+
diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c
new file mode 100644
index 000000000000..f6569dce3012
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_halinit.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+ * usb_halinit.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _HCI_HAL_INIT_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "usb_ops.h"
+#include "usb_osintf.h"
+
+u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
+{
+ u8 val8 = 0;
+ u8 ret = _SUCCESS;
+ u8 PollingCnt = 20;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+
+ if (pregistrypriv->chip_version == RTL8712_FPGA) {
+ val8 = 0x01;
+ /* switch to 80M clock */
+ r8712_write8(padapter, SYS_CLKR, val8);
+ val8 = r8712_read8(padapter, SPS1_CTRL);
+ val8 = val8 | 0x01;
+ /* enable VSPS12 LDO Macro block */
+ r8712_write8(padapter, SPS1_CTRL, val8);
+ val8 = r8712_read8(padapter, AFE_MISC);
+ val8 = val8 | 0x01;
+ /* Enable AFE Macro Block's Bandgap */
+ r8712_write8(padapter, AFE_MISC, val8);
+ val8 = r8712_read8(padapter, LDOA15_CTRL);
+ val8 = val8 | 0x01;
+ /* enable LDOA15 block */
+ r8712_write8(padapter, LDOA15_CTRL, val8);
+ val8 = r8712_read8(padapter, SPS1_CTRL);
+ val8 = val8 | 0x02;
+ /* Enable VSPS12_SW Macro Block */
+ r8712_write8(padapter, SPS1_CTRL, val8);
+ val8 = r8712_read8(padapter, AFE_MISC);
+ val8 = val8 | 0x02;
+ /* Enable AFE Macro Block's Mbias */
+ r8712_write8(padapter, AFE_MISC, val8);
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ val8 = val8 | 0x08;
+ /* isolate PCIe Analog 1.2V to PCIe 3.3V and PCIE Digital */
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, val8);
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ val8 = val8 & 0xEF;
+ /* attatch AFE PLL to MACTOP/BB/PCIe Digital */
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, val8);
+ val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1);
+ val8 = val8 & 0xFB;
+ /* enable AFE clock */
+ r8712_write8(padapter, AFE_XTAL_CTRL + 1, val8);
+ val8 = r8712_read8(padapter, AFE_PLL_CTRL);
+ val8 = val8 | 0x01;
+ /* Enable AFE PLL Macro Block */
+ r8712_write8(padapter, AFE_PLL_CTRL, val8);
+ val8 = 0xEE;
+ /* release isolation AFE PLL & MD */
+ r8712_write8(padapter, SYS_ISO_CTRL, val8);
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ val8 = val8 | 0x08;
+ /* enable MAC clock */
+ r8712_write8(padapter, SYS_CLKR + 1, val8);
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ val8 = val8 | 0x08;
+ /* enable Core digital and enable IOREG R/W */
+ r8712_write8(padapter, SYS_FUNC_EN + 1, val8);
+ val8 = val8 | 0x80;
+ /* enable REG_EN */
+ r8712_write8(padapter, SYS_FUNC_EN + 1, val8);
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ val8 = (val8 | 0x80) & 0xBF;
+ /* switch the control path */
+ r8712_write8(padapter, SYS_CLKR + 1, val8);
+ val8 = 0xFC;
+ r8712_write8(padapter, CR, val8);
+ val8 = 0x37;
+ r8712_write8(padapter, CR + 1, val8);
+ /* reduce EndPoint & init it */
+ r8712_write8(padapter, 0x102500ab, r8712_read8(padapter,
+ 0x102500ab) | BIT(6) | BIT(7));
+ /* consideration of power consumption - init */
+ r8712_write8(padapter, 0x10250008, r8712_read8(padapter,
+ 0x10250008) & 0xfffffffb);
+ } else if (pregistrypriv->chip_version == RTL8712_1stCUT) {
+ /* Initialization for power on sequence, */
+ r8712_write8(padapter, SPS0_CTRL + 1, 0x53);
+ r8712_write8(padapter, SPS0_CTRL, 0x57);
+ /* Enable AFE Macro Block's Bandgap adn Enable AFE Macro
+ * Block's Mbias
+ */
+ val8 = r8712_read8(padapter, AFE_MISC);
+ r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
+ AFE_MISC_MBEN));
+ /* Enable LDOA15 block */
+ val8 = r8712_read8(padapter, LDOA15_CTRL);
+ r8712_write8(padapter, LDOA15_CTRL, (val8 | LDA15_EN));
+ val8 = r8712_read8(padapter, SPS1_CTRL);
+ r8712_write8(padapter, SPS1_CTRL, (val8 | SPS1_LDEN));
+ msleep(20);
+ /* Enable Switch Regulator Block */
+ val8 = r8712_read8(padapter, SPS1_CTRL);
+ r8712_write8(padapter, SPS1_CTRL, (val8 | SPS1_SWEN));
+ r8712_write32(padapter, SPS1_CTRL, 0x00a7b267);
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 | 0x08));
+ /* Engineer Packet CP test Enable */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x20));
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 & 0x6F));
+ /* Enable AFE clock */
+ val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1);
+ r8712_write8(padapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb));
+ /* Enable AFE PLL Macro Block */
+ val8 = r8712_read8(padapter, AFE_PLL_CTRL);
+ r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11));
+ /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL);
+ r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE));
+ /* Switch to 40M clock */
+ val8 = r8712_read8(padapter, SYS_CLKR);
+ r8712_write8(padapter, SYS_CLKR, val8 & (~SYS_CLKSEL));
+ /* SSC Disable */
+ val8 = r8712_read8(padapter, SYS_CLKR);
+ /* Enable MAC clock */
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x18));
+ /* Revised POS, */
+ r8712_write8(padapter, PMC_FSM, 0x02);
+ /* Enable Core digital and enable IOREG R/W */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x08));
+ /* Enable REG_EN */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x80));
+ /* Switch the control path to FW */
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF);
+ r8712_write8(padapter, CR, 0xFC);
+ r8712_write8(padapter, CR + 1, 0x37);
+ /* Fix the RX FIFO issue(usb error), */
+ val8 = r8712_read8(padapter, 0x1025FE5c);
+ r8712_write8(padapter, 0x1025FE5c, (val8|BIT(7)));
+ val8 = r8712_read8(padapter, 0x102500ab);
+ r8712_write8(padapter, 0x102500ab, (val8|BIT(6)|BIT(7)));
+ /* For power save, used this in the bit file after 970621 */
+ val8 = r8712_read8(padapter, SYS_CLKR);
+ r8712_write8(padapter, SYS_CLKR, val8&(~CPU_CLKSEL));
+ } else if (pregistrypriv->chip_version == RTL8712_2ndCUT ||
+ pregistrypriv->chip_version == RTL8712_3rdCUT) {
+ /* Initialization for power on sequence,
+ * E-Fuse leakage prevention sequence
+ */
+ r8712_write8(padapter, 0x37, 0xb0);
+ msleep(20);
+ r8712_write8(padapter, 0x37, 0x30);
+ /* Set control path switch to HW control and reset Digital Core,
+ * CPU Core and MAC I/O to solve FW download fail when system
+ * from resume sate.
+ */
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ if (val8 & 0x80) {
+ val8 &= 0x3f;
+ r8712_write8(padapter, SYS_CLKR + 1, val8);
+ }
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ val8 &= 0x73;
+ r8712_write8(padapter, SYS_FUNC_EN + 1, val8);
+ msleep(20);
+ /* Revised POS, */
+ /* Enable AFE Macro Block's Bandgap and Enable AFE Macro
+ * Block's Mbias */
+ r8712_write8(padapter, SPS0_CTRL + 1, 0x53);
+ r8712_write8(padapter, SPS0_CTRL, 0x57);
+ val8 = r8712_read8(padapter, AFE_MISC);
+ /*Bandgap*/
+ r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN));
+ r8712_write8(padapter, AFE_MISC, (val8 | AFE_MISC_BGEN |
+ AFE_MISC_MBEN | AFE_MISC_I32_EN));
+ /* Enable PLL Power (LDOA15V) */
+ val8 = r8712_read8(padapter, LDOA15_CTRL);
+ r8712_write8(padapter, LDOA15_CTRL, (val8 | LDA15_EN));
+ /* Enable LDOV12D block */
+ val8 = r8712_read8(padapter, LDOV12D_CTRL);
+ r8712_write8(padapter, LDOV12D_CTRL, (val8 | LDV12_EN));
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 | 0x08));
+ /* Engineer Packet CP test Enable */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x20));
+ /* Support 64k IMEM */
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL + 1);
+ r8712_write8(padapter, SYS_ISO_CTRL + 1, (val8 & 0x68));
+ /* Enable AFE clock */
+ val8 = r8712_read8(padapter, AFE_XTAL_CTRL + 1);
+ r8712_write8(padapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb));
+ /* Enable AFE PLL Macro Block */
+ val8 = r8712_read8(padapter, AFE_PLL_CTRL);
+ r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11));
+ /* Some sample will download fw failure. The clock will be
+ * stable with 500 us delay after reset the PLL
+ * TODO: When usleep is added to kernel, change next 3
+ * udelay(500) to usleep(500)
+ */
+ udelay(500);
+ r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x51));
+ udelay(500);
+ r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11));
+ udelay(500);
+ /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */
+ val8 = r8712_read8(padapter, SYS_ISO_CTRL);
+ r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE));
+ /* Switch to 40M clock */
+ r8712_write8(padapter, SYS_CLKR, 0x00);
+ /* CPU Clock and 80M Clock SSC Disable to overcome FW download
+ * fail timing issue.
+ */
+ val8 = r8712_read8(padapter, SYS_CLKR);
+ r8712_write8(padapter, SYS_CLKR, (val8 | 0xa0));
+ /* Enable MAC clock */
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x18));
+ /* Revised POS, */
+ r8712_write8(padapter, PMC_FSM, 0x02);
+ /* Enable Core digital and enable IOREG R/W */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x08));
+ /* Enable REG_EN */
+ val8 = r8712_read8(padapter, SYS_FUNC_EN + 1);
+ r8712_write8(padapter, SYS_FUNC_EN + 1, (val8 | 0x80));
+ /* Switch the control path to FW */
+ val8 = r8712_read8(padapter, SYS_CLKR + 1);
+ r8712_write8(padapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF);
+ r8712_write8(padapter, CR, 0xFC);
+ r8712_write8(padapter, CR + 1, 0x37);
+ /* Fix the RX FIFO issue(usb error), 970410 */
+ val8 = r8712_read8(padapter, 0x1025FE5c);
+ r8712_write8(padapter, 0x1025FE5c, (val8 | BIT(7)));
+ /* For power save, used this in the bit file after 970621 */
+ val8 = r8712_read8(padapter, SYS_CLKR);
+ r8712_write8(padapter, SYS_CLKR, val8 & (~CPU_CLKSEL));
+ /* Revised for 8051 ROM code wrong operation. */
+ r8712_write8(padapter, 0x1025fe1c, 0x80);
+ /* To make sure that TxDMA can ready to download FW.
+ * We should reset TxDMA if IMEM RPT was not ready.
+ */
+ do {
+ val8 = r8712_read8(padapter, TCR);
+ if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE)
+ break;
+ udelay(5); /* PlatformStallExecution(5); */
+ } while (PollingCnt--); /* Delay 1ms */
+
+ if (PollingCnt <= 0) {
+ val8 = r8712_read8(padapter, CR);
+ r8712_write8(padapter, CR, val8&(~_TXDMA_EN));
+ udelay(2); /* PlatformStallExecution(2); */
+ /* Reset TxDMA */
+ r8712_write8(padapter, CR, val8|_TXDMA_EN);
+ }
+ } else
+ ret = _FAIL;
+ return ret;
+}
+
+unsigned int r8712_usb_inirp_init(struct _adapter *padapter)
+{
+ u8 i;
+ struct recv_buf *precvbuf;
+ struct intf_hdl *pintfhdl = &padapter->pio_queue->intf;
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
+
+ precvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */
+ /* issue Rx irp to receive data */
+ precvbuf = (struct recv_buf *)precvpriv->precv_buf;
+ for (i = 0; i < NR_RECVBUFF; i++) {
+ if (r8712_usb_read_port(pintfhdl, precvpriv->ff_hwaddr, 0,
+ (unsigned char *)precvbuf) == false)
+ return _FAIL;
+ precvbuf++;
+ precvpriv->free_recv_buf_queue_cnt--;
+ }
+ return _SUCCESS;
+}
+
+unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter)
+{
+ r8712_usb_read_port_cancel(padapter);
+ return _SUCCESS;
+}
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
new file mode 100644
index 000000000000..f1f0c63e5bbc
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -0,0 +1,571 @@
+/******************************************************************************
+ * usb_intf.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _HCI_INTF_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "recv_osdep.h"
+#include "xmit_osdep.h"
+#include "rtl8712_efuse.h"
+#include "usb_vendor_req.h"
+#include "usb_ops.h"
+#include "usb_osintf.h"
+
+#define DRVER "v7_0.20100831"
+
+static struct usb_interface *pintf;
+
+static int r871xu_drv_init(struct usb_interface *pusb_intf,
+ const struct usb_device_id *pdid);
+
+static void r871xu_dev_remove(struct usb_interface *pusb_intf);
+
+static struct usb_device_id rtl871x_usb_id_tbl[] = {
+ /*92SU
+ * Realtek */
+ {USB_DEVICE(0x0bda, 0x8171)},
+ {USB_DEVICE(0x0bda, 0x8172)},
+ {USB_DEVICE(0x0bda, 0x8173)},
+ {USB_DEVICE(0x0bda, 0x8174)},
+ {USB_DEVICE(0x0bda, 0x8712)},
+ {USB_DEVICE(0x0bda, 0x8713)},
+ {USB_DEVICE(0x0bda, 0xC512)},
+ /* Abocom */
+ {USB_DEVICE(0x07B8, 0x8188)},
+ /* Corega */
+ {USB_DEVICE(0x07aa, 0x0047)},
+ /* Dlink */
+ {USB_DEVICE(0x07d1, 0x3303)},
+ {USB_DEVICE(0x07d1, 0x3302)},
+ {USB_DEVICE(0x07d1, 0x3300)},
+ /* Dlink for Skyworth */
+ {USB_DEVICE(0x14b2, 0x3300)},
+ {USB_DEVICE(0x14b2, 0x3301)},
+ {USB_DEVICE(0x14b2, 0x3302)},
+ /* EnGenius */
+ {USB_DEVICE(0x1740, 0x9603)},
+ {USB_DEVICE(0x1740, 0x9605)},
+ /* Belkin */
+ {USB_DEVICE(0x050d, 0x815F)},
+ {USB_DEVICE(0x050d, 0x945A)},
+ {USB_DEVICE(0x050d, 0x845A)},
+ /* Guillemot */
+ {USB_DEVICE(0x06f8, 0xe031)},
+ /* Edimax */
+ {USB_DEVICE(0x7392, 0x7611)},
+ {USB_DEVICE(0x7392, 0x7612)},
+ {USB_DEVICE(0x7392, 0x7622)},
+ /* Sitecom */
+ {USB_DEVICE(0x0DF6, 0x0045)},
+ /* Hawking */
+ {USB_DEVICE(0x0E66, 0x0015)},
+ {USB_DEVICE(0x0E66, 0x0016)},
+ {USB_DEVICE(0x0b05, 0x1786)},
+ {USB_DEVICE(0x0b05, 0x1791)}, /* 11n mode disable */
+
+ {USB_DEVICE(0x13D3, 0x3306)},
+ {USB_DEVICE(0x13D3, 0x3309)},
+ {USB_DEVICE(0x13D3, 0x3310)},
+ {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */
+ {USB_DEVICE(0x13D3, 0x3325)},
+ {USB_DEVICE(0x083A, 0xC512)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl);
+
+static struct specific_device_id specific_device_id_tbl[] = {
+ {.idVendor = 0x0b05, .idProduct = 0x1791,
+ .flags = SPEC_DEV_ID_DISABLE_HT},
+ {.idVendor = 0x13D3, .idProduct = 0x3311,
+ .flags = SPEC_DEV_ID_DISABLE_HT},
+ {}
+};
+
+struct drv_priv {
+ struct usb_driver r871xu_drv;
+ int drv_registered;
+};
+
+#ifdef CONFIG_PM
+static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state)
+{
+ struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
+
+ printk(KERN_INFO "r8712: suspending...\n");
+ if (!pnetdev || !netif_running(pnetdev)) {
+ printk(KERN_INFO "r8712: unable to suspend\n");
+ return 0;
+ }
+ if (pnetdev->netdev_ops->ndo_stop)
+ pnetdev->netdev_ops->ndo_stop(pnetdev);
+ mdelay(10);
+ netif_device_detach(pnetdev);
+ return 0;
+}
+
+static int r871x_resume(struct usb_interface *pusb_intf)
+{
+ struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
+
+ printk(KERN_INFO "r8712: resuming...\n");
+ if (!pnetdev || !netif_running(pnetdev)) {
+ printk(KERN_INFO "r8712: unable to resume\n");
+ return 0;
+ }
+ netif_device_attach(pnetdev);
+ if (pnetdev->netdev_ops->ndo_open)
+ pnetdev->netdev_ops->ndo_open(pnetdev);
+ return 0;
+}
+
+static int r871x_reset_resume(struct usb_interface *pusb_intf)
+{
+ /* dummy routine */
+ return 0;
+}
+
+#endif
+
+static struct drv_priv drvpriv = {
+ .r871xu_drv.name = "r8712u",
+ .r871xu_drv.id_table = rtl871x_usb_id_tbl,
+ .r871xu_drv.probe = r871xu_drv_init,
+ .r871xu_drv.disconnect = r871xu_dev_remove,
+#ifdef CONFIG_PM
+ .r871xu_drv.suspend = r871x_suspend,
+ .r871xu_drv.resume = r871x_resume,
+ .r871xu_drv.reset_resume = r871x_reset_resume,
+#endif
+};
+
+static uint r8712_usb_dvobj_init(struct _adapter *padapter)
+{
+ uint status = _SUCCESS;
+ struct usb_device_descriptor *pdev_desc;
+ struct usb_host_config *phost_conf;
+ struct usb_config_descriptor *pconf_desc;
+ struct usb_host_interface *phost_iface;
+ struct usb_interface_descriptor *piface_desc;
+ struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv;
+ struct usb_device *pusbd = pdvobjpriv->pusbdev;
+
+ pdvobjpriv->padapter = padapter;
+ padapter->EepromAddressSize = 6;
+ pdev_desc = &pusbd->descriptor;
+ phost_conf = pusbd->actconfig;
+ pconf_desc = &phost_conf->desc;
+ phost_iface = &pintf->altsetting[0];
+ piface_desc = &phost_iface->desc;
+ pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
+ if (pusbd->speed == USB_SPEED_HIGH) {
+ pdvobjpriv->ishighspeed = true;
+ printk(KERN_INFO "r8712u: USB_SPEED_HIGH with %d endpoints\n",
+ pdvobjpriv->nr_endpoint);
+ } else {
+ pdvobjpriv->ishighspeed = false;
+ printk(KERN_INFO "r8712u: USB_SPEED_LOW with %d endpoints\n",
+ pdvobjpriv->nr_endpoint);
+ }
+ if ((r8712_alloc_io_queue(padapter)) == _FAIL)
+ status = _FAIL;
+ sema_init(&(padapter->dvobjpriv.usb_suspend_sema), 0);
+ return status;
+}
+
+static void r8712_usb_dvobj_deinit(struct _adapter *padapter)
+{
+}
+
+void rtl871x_intf_stop(struct _adapter *padapter)
+{
+ /*disable_hw_interrupt*/
+ if (padapter->bSurpriseRemoved == false) {
+ /*device still exists, so driver can do i/o operation
+ * TODO: */
+ }
+
+ /* cancel in irp */
+ if (padapter->dvobjpriv.inirp_deinit != NULL)
+ padapter->dvobjpriv.inirp_deinit(padapter);
+ /* cancel out irp */
+ r8712_usb_write_port_cancel(padapter);
+ /* TODO:cancel other irps */
+}
+
+void r871x_dev_unload(struct _adapter *padapter)
+{
+ if (padapter->bup == true) {
+ /*s1.*/
+ padapter->bDriverStopped = true;
+
+ /*s3.*/
+ rtl871x_intf_stop(padapter);
+
+ /*s4.*/
+ r8712_stop_drv_threads(padapter);
+
+ /*s5.*/
+ if (padapter->bSurpriseRemoved == false) {
+ padapter->hw_init_completed = false;
+ rtl8712_hal_deinit(padapter);
+ }
+
+ /*s6.*/
+ if (padapter->dvobj_deinit)
+ padapter->dvobj_deinit(padapter);
+ padapter->bup = false;
+ }
+}
+
+static void disable_ht_for_spec_devid(const struct usb_device_id *pdid,
+ struct _adapter *padapter)
+{
+ u16 vid, pid;
+ u32 flags;
+ int i;
+ int num = sizeof(specific_device_id_tbl) /
+ sizeof(struct specific_device_id);
+
+ for (i = 0; i < num; i++) {
+ vid = specific_device_id_tbl[i].idVendor;
+ pid = specific_device_id_tbl[i].idProduct;
+ flags = specific_device_id_tbl[i].flags;
+
+ if ((pdid->idVendor == vid) && (pdid->idProduct == pid) &&
+ (flags&SPEC_DEV_ID_DISABLE_HT)) {
+ padapter->registrypriv.ht_enable = 0;
+ padapter->registrypriv.cbw40_enable = 0;
+ padapter->registrypriv.ampdu_enable = 0;
+ }
+ }
+}
+
+static u8 key_2char2num(u8 hch, u8 lch)
+{
+ return (hex_to_bin(hch) << 4) | hex_to_bin(lch);
+}
+
+/*
+ * drv_init() - a device potentially for us
+ *
+ * notes: drv_init() is called when the bus driver has located a card for us
+ * to support. We accept the new device by returning 0.
+*/
+static int r871xu_drv_init(struct usb_interface *pusb_intf,
+ const struct usb_device_id *pdid)
+{
+ uint status;
+ struct _adapter *padapter = NULL;
+ struct dvobj_priv *pdvobjpriv;
+ struct net_device *pnetdev;
+
+ printk(KERN_INFO "r8712u: DriverVersion: %s\n", DRVER);
+ /* In this probe function, O.S. will provide the usb interface pointer
+ * to driver. We have to increase the reference count of the usb device
+ * structure by using the usb_get_dev function.
+ */
+ usb_get_dev(interface_to_usbdev(pusb_intf));
+ pintf = pusb_intf;
+ /* step 1. */
+ pnetdev = r8712_init_netdev();
+ if (!pnetdev)
+ goto error;
+ padapter = (struct _adapter *)_netdev_priv(pnetdev);
+ disable_ht_for_spec_devid(pdid, padapter);
+ pdvobjpriv = &padapter->dvobjpriv;
+ pdvobjpriv->padapter = padapter;
+ padapter->dvobjpriv.pusbdev = interface_to_usbdev(pusb_intf);
+ usb_set_intfdata(pusb_intf, pnetdev);
+ SET_NETDEV_DEV(pnetdev, &pusb_intf->dev);
+ /* step 2. */
+ padapter->dvobj_init = &r8712_usb_dvobj_init;
+ padapter->dvobj_deinit = &r8712_usb_dvobj_deinit;
+ padapter->halpriv.hal_bus_init = &r8712_usb_hal_bus_init;
+ padapter->dvobjpriv.inirp_init = &r8712_usb_inirp_init;
+ padapter->dvobjpriv.inirp_deinit = &r8712_usb_inirp_deinit;
+ /* step 3.
+ * initialize the dvobj_priv
+ */
+ if (padapter->dvobj_init == NULL)
+ goto error;
+ else {
+ status = padapter->dvobj_init(padapter);
+ if (status != _SUCCESS)
+ goto error;
+ }
+ /* step 4. */
+ status = r8712_init_drv_sw(padapter);
+ if (status == _FAIL)
+ goto error;
+ /* step 5. read efuse/eeprom data and get mac_addr */
+ {
+ int i, offset;
+ u8 mac[6];
+ u8 tmpU1b, AutoloadFail, eeprom_CustomerID;
+ u8 *pdata = padapter->eeprompriv.efuse_eeprom_data;
+
+ tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/
+
+ /* To check system boot selection.*/
+ printk(KERN_INFO "r8712u: Boot from %s: Autoload %s\n",
+ (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE",
+ (tmpU1b & _EEPROM_EN) ? "OK" : "Failed");
+
+ /* To check autoload success or not.*/
+ if (tmpU1b & _EEPROM_EN) {
+ AutoloadFail = true;
+ /* The following operations prevent Efuse leakage by
+ * turning on 2.5V.
+ */
+ tmpU1b = r8712_read8(padapter, EFUSE_TEST+3);
+ r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80);
+ msleep(20);
+ r8712_write8(padapter, EFUSE_TEST + 3,
+ (tmpU1b & (~BIT(7))));
+
+ /* Retrieve Chip version.
+ * Recognize IC version by Reg0x4 BIT15.
+ */
+ tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) &
+ 0x1F);
+ if (tmpU1b == 0x3)
+ padapter->registrypriv.chip_version =
+ RTL8712_3rdCUT;
+ else
+ padapter->registrypriv.chip_version =
+ (tmpU1b >> 1) + 1;
+ switch (padapter->registrypriv.chip_version) {
+ case RTL8712_1stCUT:
+ case RTL8712_2ndCUT:
+ case RTL8712_3rdCUT:
+ break;
+ default:
+ padapter->registrypriv.chip_version =
+ RTL8712_2ndCUT;
+ break;
+ }
+
+ for (i = 0, offset = 0; i < 128; i += 8, offset++)
+ r8712_efuse_pg_packet_read(padapter, offset,
+ &pdata[i]);
+
+ if (r8712_initmac) {
+ /* Users specify the mac address */
+ int jj, kk;
+
+ for (jj = 0, kk = 0; jj < ETH_ALEN;
+ jj++, kk += 3)
+ mac[jj] =
+ key_2char2num(r8712_initmac[kk],
+ r8712_initmac[kk + 1]);
+ } else {
+ /* Use the mac address stored in the Efuse
+ * offset = 0x12 for usb in efuse
+ */
+ memcpy(mac, &pdata[0x12], ETH_ALEN);
+ }
+ eeprom_CustomerID = pdata[0x52];
+ switch (eeprom_CustomerID) {
+ case EEPROM_CID_ALPHA:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_ALPHA;
+ break;
+ case EEPROM_CID_CAMEO:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_CAMEO;
+ break;
+ case EEPROM_CID_SITECOM:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_Sitecom;
+ break;
+ case EEPROM_CID_COREGA:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_COREGA;
+ break;
+ case EEPROM_CID_Senao:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_Senao;
+ break;
+ case EEPROM_CID_EDIMAX_BELKIN:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_Edimax_Belkin;
+ break;
+ case EEPROM_CID_SERCOMM_BELKIN:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_Sercomm_Belkin;
+ break;
+ case EEPROM_CID_WNC_COREGA:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_WNC_COREGA;
+ break;
+ case EEPROM_CID_WHQL:
+ break;
+ case EEPROM_CID_NetCore:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_Netcore;
+ break;
+ case EEPROM_CID_CAMEO1:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_CAMEO1;
+ break;
+ case EEPROM_CID_CLEVO:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_819x_CLEVO;
+ break;
+ default:
+ padapter->eeprompriv.CustomerID =
+ RT_CID_DEFAULT;
+ break;
+ }
+ printk(KERN_INFO "r8712u: CustomerID = 0x%.4x\n",
+ padapter->eeprompriv.CustomerID);
+ /* Led mode */
+ switch (padapter->eeprompriv.CustomerID) {
+ case RT_CID_DEFAULT:
+ case RT_CID_819x_ALPHA:
+ case RT_CID_819x_CAMEO:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE1;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ case RT_CID_819x_Sitecom:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE2;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ case RT_CID_COREGA:
+ case RT_CID_819x_Senao:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE3;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ case RT_CID_819x_Edimax_Belkin:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE4;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ case RT_CID_819x_Sercomm_Belkin:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE5;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ case RT_CID_819x_WNC_COREGA:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE6;
+ padapter->ledpriv.bRegUseLed = true;
+ break;
+ default:
+ padapter->ledpriv.LedStrategy = SW_LED_MODE0;
+ padapter->ledpriv.bRegUseLed = false;
+ break;
+ }
+ } else
+ AutoloadFail = false;
+ if (((mac[0] == 0xff) && (mac[1] == 0xff) &&
+ (mac[2] == 0xff) && (mac[3] == 0xff) &&
+ (mac[4] == 0xff) && (mac[5] == 0xff)) ||
+ ((mac[0] == 0x00) && (mac[1] == 0x00) &&
+ (mac[2] == 0x00) && (mac[3] == 0x00) &&
+ (mac[4] == 0x00) && (mac[5] == 0x00)) ||
+ (AutoloadFail == false)) {
+ mac[0] = 0x00;
+ mac[1] = 0xe0;
+ mac[2] = 0x4c;
+ mac[3] = 0x87;
+ mac[4] = 0x00;
+ mac[5] = 0x00;
+ }
+ if (r8712_initmac) {
+ /* Make sure the user did not select a multicast
+ * address by setting bit 1 of first octet.
+ */
+ mac[0] &= 0xFE;
+ printk(KERN_INFO "r8712u: MAC Address from user = "
+ "%pM\n", mac);
+ } else
+ printk(KERN_INFO "r8712u: MAC Address from efuse = "
+ "%pM\n", mac);
+ memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
+ }
+ /* step 6. Tell the network stack we exist */
+ if (register_netdev(pnetdev) != 0)
+ goto error;
+ return 0;
+error:
+ usb_put_dev(interface_to_usbdev(pusb_intf));
+ usb_set_intfdata(pusb_intf, NULL);
+ if (padapter->dvobj_deinit != NULL)
+ padapter->dvobj_deinit(padapter);
+ if (pnetdev)
+ os_free_netdev(pnetdev);
+ return -ENODEV;
+}
+
+/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove()
+ * => how to recognize both */
+static void r871xu_dev_remove(struct usb_interface *pusb_intf)
+{
+ struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
+ struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev);
+ struct usb_device *udev = interface_to_usbdev(pusb_intf);
+
+ if (padapter) {
+ if (drvpriv.drv_registered == true)
+ padapter->bSurpriseRemoved = true;
+ if (pnetdev != NULL) {
+ /* will call netdev_close() */
+ unregister_netdev(pnetdev);
+ }
+ flush_scheduled_work();
+ udelay(1);
+ r871x_dev_unload(padapter);
+ r8712_free_drv_sw(padapter);
+ }
+ usb_set_intfdata(pusb_intf, NULL);
+ /* decrease the reference count of the usb device structure
+ * when disconnect */
+ usb_put_dev(udev);
+ /* If we didn't unplug usb dongle and remove/insert modlue, driver
+ * fails on sitesurvey for the first time when device is up.
+ * Reset usb port for sitesurvey fail issue. */
+ if (udev->state != USB_STATE_NOTATTACHED)
+ usb_reset_device(udev);
+ return;
+}
+
+static int __init r8712u_drv_entry(void)
+{
+ drvpriv.drv_registered = true;
+ return usb_register(&drvpriv.r871xu_drv);
+}
+
+static void __exit r8712u_drv_halt(void)
+{
+ drvpriv.drv_registered = false;
+ usb_deregister(&drvpriv.r871xu_drv);
+ printk(KERN_INFO "r8712u: Driver unloaded\n");
+}
+
+module_init(r8712u_drv_entry);
+module_exit(r8712u_drv_halt);
diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c
new file mode 100644
index 000000000000..5a8b0ebd0b79
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_ops.c
@@ -0,0 +1,201 @@
+/******************************************************************************
+ * usb_ops.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _HCI_OPS_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+#include "recv_osdep.h"
+#include "rtl871x_byteorder.h"
+
+static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x01; /* read_in */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 1;
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+ return (u8)(le32_to_cpu(data)&0x0ff);
+}
+
+static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x01; /* read_in */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 2;
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+ return (u16)(le32_to_cpu(data)&0xffff);
+}
+
+static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x01; /* read_in */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 4;
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+ return le32_to_cpu(data);
+}
+
+static void usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x00; /* write_out */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 1;
+ data = val;
+ data = cpu_to_le32(data&0x000000ff);
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+}
+
+static void usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x00; /* write_out */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 2;
+ data = val;
+ data = cpu_to_le32(data&0x0000ffff);
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+}
+
+static void usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u32 data;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+
+ request = 0x05;
+ requesttype = 0x00; /* write_out */
+ index = 0;
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 4;
+ data = cpu_to_le32(val);
+ r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
+ requesttype);
+}
+
+void r8712_usb_set_intf_option(u32 *poption)
+{
+ *poption = ((*poption) | _INTF_ASYNC_);
+}
+
+static void usb_intf_hdl_init(u8 *priv)
+{
+}
+
+static void usb_intf_hdl_unload(u8 *priv)
+{
+}
+
+static void usb_intf_hdl_open(u8 *priv)
+{
+}
+
+static void usb_intf_hdl_close(u8 *priv)
+{
+}
+
+void r8712_usb_set_intf_funs(struct intf_hdl *pintf_hdl)
+{
+ pintf_hdl->intf_hdl_init = &usb_intf_hdl_init;
+ pintf_hdl->intf_hdl_unload = &usb_intf_hdl_unload;
+ pintf_hdl->intf_hdl_open = &usb_intf_hdl_open;
+ pintf_hdl->intf_hdl_close = &usb_intf_hdl_close;
+}
+
+void r8712_usb_set_intf_ops(struct _io_ops *pops)
+{
+ memset((u8 *)pops, 0, sizeof(struct _io_ops));
+ pops->_read8 = &usb_read8;
+ pops->_read16 = &usb_read16;
+ pops->_read32 = &usb_read32;
+ pops->_read_port = &r8712_usb_read_port;
+ pops->_write8 = &usb_write8;
+ pops->_write16 = &usb_write16;
+ pops->_write32 = &usb_write32;
+ pops->_write_mem = &r8712_usb_write_mem;
+ pops->_write_port = &r8712_usb_write_port;
+}
diff --git a/drivers/staging/rtl8712/usb_ops.h b/drivers/staging/rtl8712/usb_ops.h
new file mode 100644
index 000000000000..dc0611a2a0df
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_ops.h
@@ -0,0 +1,25 @@
+#ifndef __USB_OPS_H_
+#define __USB_OPS_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "osdep_intf.h"
+
+void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr,
+ u32 cnt, u8 *wmem);
+u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr,
+ u32 cnt, u8 *wmem);
+u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr,
+ u32 cnt, u8 *rmem);
+void r8712_usb_set_intf_option(u32 *poption);
+void r8712_usb_set_intf_funs(struct intf_hdl *pintf_hdl);
+uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv);
+void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv);
+void r8712_usb_set_intf_ops(struct _io_ops *pops);
+void r8712_usb_read_port_cancel(struct _adapter *padapter);
+void r8712_usb_write_port_cancel(struct _adapter *padapter);
+int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value,
+ u16 index, void *pdata, u16 len, u8 requesttype);
+
+#endif
+
diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c
new file mode 100644
index 000000000000..7933ea4f632b
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_ops_linux.c
@@ -0,0 +1,529 @@
+/******************************************************************************
+ * usb_ops_linux.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _HCI_OPS_OS_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "osdep_intf.h"
+#include "usb_ops.h"
+
+#define RTL871X_VENQT_READ 0xc0
+#define RTL871X_VENQT_WRITE 0x40
+
+struct zero_bulkout_context {
+ void *pbuf;
+ void *purb;
+ void *pirp;
+ void *padapter;
+};
+
+#define usb_write_cmd r8712_usb_write_mem
+#define usb_write_cmd_complete usb_write_mem_complete
+
+uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv)
+{
+ pintfpriv->piorw_urb = _usb_alloc_urb(0, GFP_ATOMIC);
+ if (!pintfpriv->piorw_urb)
+ return _FAIL;
+ sema_init(&(pintfpriv->io_retevt), 0);
+ return _SUCCESS;
+}
+
+void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv)
+{
+ if (pintfpriv->piorw_urb) {
+ usb_kill_urb(pintfpriv->piorw_urb);
+ usb_free_urb(pintfpriv->piorw_urb);
+ }
+}
+
+static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
+{
+ unsigned int pipe = 0;
+ struct usb_device *pusbd = pdvobj->pusbdev;
+
+ if (pdvobj->nr_endpoint == 11) {
+ switch (addr) {
+ case RTL8712_DMA_BKQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x07);
+ break;
+ case RTL8712_DMA_BEQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x06);
+ break;
+ case RTL8712_DMA_VIQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x05);
+ break;
+ case RTL8712_DMA_VOQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x04);
+ break;
+ case RTL8712_DMA_BCNQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x0a);
+ break;
+ case RTL8712_DMA_BMCQ: /* HI Queue */
+ pipe = usb_sndbulkpipe(pusbd, 0x0b);
+ break;
+ case RTL8712_DMA_MGTQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x0c);
+ break;
+ case RTL8712_DMA_RX0FF:
+ pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */
+ break;
+ case RTL8712_DMA_C2HCMD:
+ pipe = usb_rcvbulkpipe(pusbd, 0x09); /* in */
+ break;
+ case RTL8712_DMA_H2CCMD:
+ pipe = usb_sndbulkpipe(pusbd, 0x0d);
+ break;
+ }
+ } else if (pdvobj->nr_endpoint == 6) {
+ switch (addr) {
+ case RTL8712_DMA_BKQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x07);
+ break;
+ case RTL8712_DMA_BEQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x06);
+ break;
+ case RTL8712_DMA_VIQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x05);
+ break;
+ case RTL8712_DMA_VOQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x04);
+ break;
+ case RTL8712_DMA_RX0FF:
+ case RTL8712_DMA_C2HCMD:
+ pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */
+ break;
+ case RTL8712_DMA_H2CCMD:
+ case RTL8712_DMA_BCNQ:
+ case RTL8712_DMA_BMCQ:
+ case RTL8712_DMA_MGTQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x0d);
+ break;
+ }
+ } else if (pdvobj->nr_endpoint == 4) {
+ switch (addr) {
+ case RTL8712_DMA_BEQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x06);
+ break;
+ case RTL8712_DMA_VOQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x04);
+ break;
+ case RTL8712_DMA_RX0FF:
+ case RTL8712_DMA_C2HCMD:
+ pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */
+ break;
+ case RTL8712_DMA_H2CCMD:
+ case RTL8712_DMA_BCNQ:
+ case RTL8712_DMA_BMCQ:
+ case RTL8712_DMA_MGTQ:
+ pipe = usb_sndbulkpipe(pusbd, 0x0d);
+ break;
+ }
+ } else
+ pipe = 0;
+ return pipe;
+}
+
+static void usb_write_mem_complete(struct urb *purb)
+{
+ struct io_queue *pio_q = (struct io_queue *)purb->context;
+ struct intf_hdl *pintf = &(pio_q->intf);
+ struct intf_priv *pintfpriv = pintf->pintfpriv;
+ struct _adapter *padapter = (struct _adapter *)pintf->adapter;
+
+ if (purb->status != 0) {
+ if (purb->status == (-ESHUTDOWN))
+ padapter->bDriverStopped = true;
+ else
+ padapter->bSurpriseRemoved = true;
+ }
+ up(&pintfpriv->io_retevt);
+}
+
+void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+{
+ unsigned int pipe;
+ int status;
+ struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+ struct io_queue *pio_queue = (struct io_queue *)padapter->pio_queue;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev;
+ struct usb_device *pusbd = pdvobj->pusbdev;
+ struct urb *piorw_urb = pintfpriv->piorw_urb;
+
+ if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||
+ (padapter->pwrctrlpriv.pnp_bstop_trx))
+ return;
+ /* translate DMA FIFO addr to pipehandle */
+ pipe = ffaddr2pipehdl(pdvobj, addr);
+ if (pipe == 0)
+ return;
+ usb_fill_bulk_urb(piorw_urb, pusbd, pipe,
+ wmem, cnt, usb_write_mem_complete,
+ pio_queue);
+ status = _usb_submit_urb(piorw_urb, GFP_ATOMIC);
+ _down_sema(&pintfpriv->io_retevt);
+}
+
+static void r8712_usb_read_port_complete(struct urb *purb)
+{
+ uint isevt, *pbuf;
+ struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
+ struct _adapter *padapter = (struct _adapter *)precvbuf->adapter;
+ struct recv_priv *precvpriv = &padapter->recvpriv;
+
+ if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
+ return;
+ if (purb->status == 0) { /* SUCCESS */
+ if ((purb->actual_length > (MAX_RECVBUF_SZ)) ||
+ (purb->actual_length < RXDESC_SIZE)) {
+ precvbuf->reuse = true;
+ r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
+ (unsigned char *)precvbuf);
+ } else {
+ precvbuf->transfer_len = purb->actual_length;
+ pbuf = (uint *)precvbuf->pbuf;
+ isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff;
+ if ((isevt & 0x1ff) == 0x1ff) {
+ r8712_rxcmd_event_hdl(padapter, pbuf);
+ precvbuf->reuse = true;
+ r8712_read_port(padapter, precvpriv->ff_hwaddr,
+ 0, (unsigned char *)precvbuf);
+ } else {
+ _pkt *pskb = precvbuf->pskb;
+ skb_put(pskb, purb->actual_length);
+ skb_queue_tail(&precvpriv->rx_skb_queue, pskb);
+ tasklet_hi_schedule(&precvpriv->recv_tasklet);
+ precvbuf->pskb = NULL;
+ precvbuf->reuse = false;
+ r8712_read_port(padapter, precvpriv->ff_hwaddr,
+ 0, (unsigned char *)precvbuf);
+ }
+ }
+ } else {
+ switch (purb->status) {
+ case -EINVAL:
+ case -EPIPE:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ case -ENOENT:
+ padapter->bDriverStopped = true;
+ break;
+ case -EPROTO:
+ precvbuf->reuse = true;
+ r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
+ (unsigned char *)precvbuf);
+ break;
+ case -EINPROGRESS:
+ printk(KERN_ERR "r8712u: ERROR: URB IS IN"
+ " PROGRESS!/n");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
+{
+ unsigned int pipe;
+ int err;
+ u32 tmpaddr = 0;
+ int alignment = 0;
+ u32 ret = _SUCCESS;
+ struct urb *purb = NULL;
+ struct recv_buf *precvbuf = (struct recv_buf *)rmem;
+ struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev;
+ struct _adapter *adapter = (struct _adapter *)pdvobj->padapter;
+ struct recv_priv *precvpriv = &adapter->recvpriv;
+ struct usb_device *pusbd = pdvobj->pusbdev;
+
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
+ adapter->pwrctrlpriv.pnp_bstop_trx)
+ return _FAIL;
+ if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) {
+ precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
+ if (NULL != precvbuf->pskb)
+ precvbuf->reuse = true;
+ }
+ if (precvbuf != NULL) {
+ r8712_init_recvbuf(adapter, precvbuf);
+ /* re-assign for linux based on skb */
+ if ((precvbuf->reuse == false) || (precvbuf->pskb == NULL)) {
+ precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev,
+ MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+ if (precvbuf->pskb == NULL)
+ return _FAIL;
+ tmpaddr = (addr_t)precvbuf->pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+ skb_reserve(precvbuf->pskb,
+ (RECVBUFF_ALIGN_SZ - alignment));
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->pbuf = precvbuf->pskb->data;
+ } else { /* reuse skb */
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->pbuf = precvbuf->pskb->data;
+ precvbuf->reuse = false;
+ }
+ purb = precvbuf->purb;
+ /* translate DMA FIFO addr to pipehandle */
+ pipe = ffaddr2pipehdl(pdvobj, addr);
+ usb_fill_bulk_urb(purb, pusbd, pipe,
+ precvbuf->pbuf, MAX_RECVBUF_SZ,
+ r8712_usb_read_port_complete,
+ precvbuf);
+ err = _usb_submit_urb(purb, GFP_ATOMIC);
+ if ((err) && (err != (-EPERM)))
+ ret = _FAIL;
+ } else
+ ret = _FAIL;
+ return ret;
+}
+
+void r8712_usb_read_port_cancel(struct _adapter *padapter)
+{
+ int i;
+ struct recv_buf *precvbuf;
+
+ precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
+ for (i = 0; i < NR_RECVBUFF; i++) {
+ if (precvbuf->purb)
+ usb_kill_urb(precvbuf->purb);
+ precvbuf++;
+ }
+}
+
+void r8712_xmit_bh(void *priv)
+{
+ int ret = false;
+ struct _adapter *padapter = (struct _adapter *)priv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ while (1) {
+ if ((padapter->bDriverStopped == true) ||
+ (padapter->bSurpriseRemoved == true)) {
+ printk(KERN_ERR "r8712u: xmit_bh => bDriverStopped"
+ " or bSurpriseRemoved\n");
+ break;
+ }
+ ret = r8712_xmitframe_complete(padapter, pxmitpriv, NULL);
+ if (ret == false)
+ break;
+ }
+}
+
+static void usb_write_port_complete(struct urb *purb)
+{
+ int i;
+ struct xmit_frame *pxmitframe = (struct xmit_frame *)purb->context;
+ struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
+ struct _adapter *padapter = pxmitframe->padapter;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+
+ switch (pattrib->priority) {
+ case 1:
+ case 2:
+ pxmitpriv->bkq_cnt--;
+ break;
+ case 4:
+ case 5:
+ pxmitpriv->viq_cnt--;
+ break;
+ case 6:
+ case 7:
+ pxmitpriv->voq_cnt--;
+ break;
+ case 0:
+ case 3:
+ default:
+ pxmitpriv->beq_cnt--;
+ break;
+ }
+ pxmitpriv->txirp_cnt--;
+ for (i = 0; i < 8; i++) {
+ if (purb == pxmitframe->pxmit_urb[i]) {
+ pxmitframe->bpending[i] = false;
+ break;
+ }
+ }
+ if (padapter->bSurpriseRemoved)
+ return;
+ switch (purb->status) {
+ case 0:
+ break;
+ default:
+ printk(KERN_WARNING "r8712u: pipe error: (%d)\n", purb->status);
+ break;
+ }
+ /* not to consider tx fragment */
+ r8712_free_xmitframe_ex(pxmitpriv, pxmitframe);
+ r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+}
+
+u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+{
+ unsigned long irqL;
+ int i, status;
+ unsigned int pipe;
+ u32 ret, bwritezero;
+ struct urb *purb = NULL;
+ struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter;
+ struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem;
+ struct usb_device *pusbd = pdvobj->pusbdev;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+
+ if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||
+ (padapter->pwrctrlpriv.pnp_bstop_trx))
+ return _FAIL;
+ for (i = 0; i < 8; i++) {
+ if (pxmitframe->bpending[i] == false) {
+ spin_lock_irqsave(&pxmitpriv->lock, irqL);
+ pxmitpriv->txirp_cnt++;
+ pxmitframe->bpending[i] = true;
+ switch (pattrib->priority) {
+ case 1:
+ case 2:
+ pxmitpriv->bkq_cnt++;
+ break;
+ case 4:
+ case 5:
+ pxmitpriv->viq_cnt++;
+ break;
+ case 6:
+ case 7:
+ pxmitpriv->voq_cnt++;
+ break;
+ case 0:
+ case 3:
+ default:
+ pxmitpriv->beq_cnt++;
+ break;
+ }
+ spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
+ pxmitframe->sz[i] = (u16)cnt;
+ purb = pxmitframe->pxmit_urb[i];
+ break;
+ }
+ }
+ bwritezero = false;
+ if (pdvobj->ishighspeed) {
+ if (cnt > 0 && cnt % 512 == 0)
+ bwritezero = true;
+ } else {
+ if (cnt > 0 && cnt % 64 == 0)
+ bwritezero = true;
+ }
+ /* translate DMA FIFO addr to pipehandle */
+ pipe = ffaddr2pipehdl(pdvobj, addr);
+ if (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0)
+ purb->transfer_flags &= (~URB_NO_INTERRUPT);
+ else
+ purb->transfer_flags |= URB_NO_INTERRUPT;
+ if (bwritezero)
+ cnt += 8;
+ usb_fill_bulk_urb(purb, pusbd, pipe,
+ pxmitframe->mem_addr,
+ cnt, usb_write_port_complete,
+ pxmitframe); /* context is xmit_frame */
+ status = _usb_submit_urb(purb, GFP_ATOMIC);
+ if (!status)
+ ret = _SUCCESS;
+ else
+ ret = _FAIL;
+ return ret;
+}
+
+void r8712_usb_write_port_cancel(struct _adapter *padapter)
+{
+ int i, j;
+ struct xmit_buf *pxmitbuf = (struct xmit_buf *)
+ padapter->xmitpriv.pxmitbuf;
+
+ for (i = 0; i < NR_XMITBUFF; i++) {
+ for (j = 0; j < 8; j++) {
+ if (pxmitbuf->pxmit_urb[j])
+ usb_kill_urb(pxmitbuf->pxmit_urb[j]);
+ }
+ pxmitbuf++;
+ }
+}
+
+int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value,
+ u16 index, void *pdata, u16 len, u8 requesttype)
+{
+ unsigned int pipe;
+ int status;
+ u8 reqtype;
+ struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)
+ pintfpriv->intf_dev;
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+ /* For mstar platform, mstar suggests the address for USB IO
+ * should be 16 bytes alignment. Trying to fix it here.
+ */
+ u8 *palloc_buf, *pIo_buf;
+
+ palloc_buf = _malloc((u32) len + 16);
+ if (palloc_buf == NULL) {
+ printk(KERN_ERR "r8712u: [%s] Can't alloc memory for vendor"
+ " request\n", __func__);
+ return -1;
+ }
+ pIo_buf = palloc_buf + 16 - ((addr_t)(palloc_buf) & 0x0f);
+ if (requesttype == 0x01) {
+ pipe = usb_rcvctrlpipe(udev, 0); /* read_in */
+ reqtype = RTL871X_VENQT_READ;
+ } else {
+ pipe = usb_sndctrlpipe(udev, 0); /* write_out */
+ reqtype = RTL871X_VENQT_WRITE;
+ memcpy(pIo_buf, pdata, len);
+ }
+ status = usb_control_msg(udev, pipe, request, reqtype, value, index,
+ pIo_buf, len, HZ / 2);
+ if (status > 0) { /* Success this control transfer. */
+ if (requesttype == 0x01) {
+ /* For Control read transfer, we have to copy the read
+ * data from pIo_buf to pdata.
+ */
+ memcpy(pdata, pIo_buf, status);
+ }
+ }
+ kfree(palloc_buf);
+ return status;
+}
diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h
new file mode 100644
index 000000000000..0da6c1db048e
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_osintf.h
@@ -0,0 +1,24 @@
+#ifndef __USB_OSINTF_H
+#define __USB_OSINTF_H
+
+#include "osdep_service.h"
+#include "drv_types.h"
+#include "usb_vendor_req.h"
+
+#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3)
+
+extern char *r8712_initmac;
+
+unsigned int r8712_usb_inirp_init(struct _adapter *padapter);
+unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter);
+uint rtl871x_hal_init(struct _adapter *padapter);
+uint rtl8712_hal_deinit(struct _adapter *padapter);
+
+void rtl871x_intf_stop(struct _adapter *padapter);
+void r871x_dev_unload(struct _adapter *padapter);
+void r8712_stop_drv_threads(struct _adapter *padapter);
+u8 r8712_init_drv_sw(struct _adapter *padapter);
+u8 r8712_free_drv_sw(struct _adapter *padapter);
+struct net_device *r8712_init_netdev(void);
+
+#endif
diff --git a/drivers/staging/rtl8712/usb_vendor_req.h b/drivers/staging/rtl8712/usb_vendor_req.h
new file mode 100644
index 000000000000..d35c538c47a1
--- /dev/null
+++ b/drivers/staging/rtl8712/usb_vendor_req.h
@@ -0,0 +1,33 @@
+#ifndef _USB_VENDOR_REQUEST_H_
+#define _USB_VENDOR_REQUEST_H_
+
+/*4 Set/Get Register related wIndex/Data */
+#define RT_USB_RESET_MASK_OFF 0
+#define RT_USB_RESET_MASK_ON 1
+#define RT_USB_SLEEP_MASK_OFF 0
+#define RT_USB_SLEEP_MASK_ON 1
+#define RT_USB_LDO_ON 1
+#define RT_USB_LDO_OFF 0
+
+/*4 Set/Get SYSCLK related wValue or Data */
+#define RT_USB_SYSCLK_32KHZ 0
+#define RT_USB_SYSCLK_40MHZ 1
+#define RT_USB_SYSCLK_60MHZ 2
+
+enum RT_USB_BREQUEST {
+ RT_USB_SET_REGISTER = 1,
+ RT_USB_SET_SYSCLK = 2,
+ RT_USB_GET_SYSCLK = 3,
+ RT_USB_GET_REGISTER = 4
+};
+
+enum RT_USB_WVALUE {
+ RT_USB_RESET_MASK = 1,
+ RT_USB_SLEEP_MASK = 2,
+ RT_USB_USB_HRCPWM = 3,
+ RT_USB_LDO = 4,
+ RT_USB_BOOT_TYPE = 5
+};
+
+#endif
+
diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h
new file mode 100644
index 000000000000..86d4b98e2439
--- /dev/null
+++ b/drivers/staging/rtl8712/wifi.h
@@ -0,0 +1,622 @@
+#ifndef _WIFI_H_
+#define _WIFI_H_
+
+#include "rtl871x_byteorder.h"
+
+#ifdef BIT
+#undef BIT
+#endif
+#define BIT(x) (1 << (x))
+
+#define WLAN_ETHHDR_LEN 14
+#define WLAN_ETHADDR_LEN 6
+#define WLAN_IEEE_OUI_LEN 3
+#define WLAN_ADDR_LEN 6
+#define WLAN_CRC_LEN 4
+#define WLAN_BSSID_LEN 6
+#define WLAN_BSS_TS_LEN 8
+#define WLAN_HDR_A3_LEN 24
+#define WLAN_HDR_A4_LEN 30
+#define WLAN_HDR_A3_QOS_LEN 26
+#define WLAN_HDR_A4_QOS_LEN 32
+#define WLAN_SSID_MAXLEN 32
+#define WLAN_DATA_MAXLEN 2312
+
+#define WLAN_A3_PN_OFFSET 24
+#define WLAN_A4_PN_OFFSET 30
+
+#define WLAN_MIN_ETHFRM_LEN 60
+#define WLAN_MAX_ETHFRM_LEN 1514
+#define WLAN_ETHHDR_LEN 14
+
+#define P80211CAPTURE_VERSION 0x80211001
+
+enum WIFI_FRAME_TYPE {
+ WIFI_MGT_TYPE = (0),
+ WIFI_CTRL_TYPE = (BIT(2)),
+ WIFI_DATA_TYPE = (BIT(3)),
+ WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), /*!< QoS Data */
+};
+
+enum WIFI_FRAME_SUBTYPE {
+
+ /* below is for mgt frame */
+ WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE),
+ WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE),
+ WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE),
+ WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE),
+ WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE),
+ WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE),
+ WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE),
+ WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE),
+ WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE),
+ WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE),
+ WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE),
+ WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE),
+
+ /* below is for control frame */
+ WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE),
+ WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
+ WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE),
+ WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE),
+ WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE),
+ WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
+
+ /* below is for data frame */
+ WIFI_DATA = (0 | WIFI_DATA_TYPE),
+ WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE),
+ WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE),
+ WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE),
+ WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE),
+ WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE),
+ WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE),
+ WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE),
+};
+
+enum WIFI_REASON_CODE {
+ _RSON_RESERVED_ = 0,
+ _RSON_UNSPECIFIED_ = 1,
+ _RSON_AUTH_NO_LONGER_VALID_ = 2,
+ _RSON_DEAUTH_STA_LEAVING_ = 3,
+ _RSON_INACTIVITY_ = 4,
+ _RSON_UNABLE_HANDLE_ = 5,
+ _RSON_CLS2_ = 6,
+ _RSON_CLS3_ = 7,
+ _RSON_DISAOC_STA_LEAVING_ = 8,
+ _RSON_ASOC_NOT_AUTH_ = 9,
+
+ /* WPA reason */
+ _RSON_INVALID_IE_ = 13,
+ _RSON_MIC_FAILURE_ = 14,
+ _RSON_4WAY_HNDSHK_TIMEOUT_ = 15,
+ _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16,
+ _RSON_DIFF_IE_ = 17,
+ _RSON_MLTCST_CIPHER_NOT_VALID_ = 18,
+ _RSON_UNICST_CIPHER_NOT_VALID_ = 19,
+ _RSON_AKMP_NOT_VALID_ = 20,
+ _RSON_UNSUPPORT_RSNE_VER_ = 21,
+ _RSON_INVALID_RSNE_CAP_ = 22,
+ _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23,
+
+ /* below are Realtek definitions */
+ _RSON_PMK_NOT_AVAILABLE_ = 24,
+};
+
+enum WIFI_STATUS_CODE {
+ _STATS_SUCCESSFUL_ = 0,
+ _STATS_FAILURE_ = 1,
+ _STATS_CAP_FAIL_ = 10,
+ _STATS_NO_ASOC_ = 11,
+ _STATS_OTHER_ = 12,
+ _STATS_NO_SUPP_ALG_ = 13,
+ _STATS_OUT_OF_AUTH_SEQ_ = 14,
+ _STATS_CHALLENGE_FAIL_ = 15,
+ _STATS_AUTH_TIMEOUT_ = 16,
+ _STATS_UNABLE_HANDLE_STA_ = 17,
+ _STATS_RATE_FAIL_ = 18,
+};
+
+enum WIFI_REG_DOMAIN {
+ DOMAIN_FCC = 1,
+ DOMAIN_IC = 2,
+ DOMAIN_ETSI = 3,
+ DOMAIN_SPAIN = 4,
+ DOMAIN_FRANCE = 5,
+ DOMAIN_MKK = 6,
+ DOMAIN_ISRAEL = 7,
+ DOMAIN_MKK1 = 8,
+ DOMAIN_MKK2 = 9,
+ DOMAIN_MKK3 = 10,
+ DOMAIN_MAX
+};
+
+#define _TO_DS_ BIT(8)
+#define _FROM_DS_ BIT(9)
+#define _MORE_FRAG_ BIT(10)
+#define _RETRY_ BIT(11)
+#define _PWRMGT_ BIT(12)
+#define _MORE_DATA_ BIT(13)
+#define _PRIVACY_ BIT(14)
+#define _ORDER_ BIT(15)
+
+#define SetToDs(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_TO_DS_); \
+ } while (0)
+
+#define GetToDs(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_TO_DS_)) != 0)
+
+#define ClearToDs(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \
+ } while (0)
+
+#define SetFrDs(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_FROM_DS_); \
+ } while (0)
+
+#define GetFrDs(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_FROM_DS_)) != 0)
+
+#define ClearFrDs(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \
+ } while (0)
+
+#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe))
+
+
+#define SetMFrag(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \
+ } while (0)
+
+#define GetMFrag(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_MORE_FRAG_)) != 0)
+
+#define ClearMFrag(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \
+ } while (0)
+
+#define SetRetry(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_RETRY_); \
+ } while (0)
+
+#define GetRetry(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_RETRY_)) != 0)
+
+#define ClearRetry(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \
+ } while (0)
+
+#define SetPwrMgt(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_PWRMGT_); \
+ } while (0)
+
+#define GetPwrMgt(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_PWRMGT_)) != 0)
+
+#define ClearPwrMgt(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \
+ } while (0)
+
+#define SetMData(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \
+ } while (0)
+
+#define GetMData(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_MORE_DATA_)) != 0)
+
+#define ClearMData(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \
+ } while (0)
+
+#define SetPrivacy(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_PRIVACY_); \
+ } while (0)
+
+#define GetPrivacy(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_PRIVACY_)) != 0)
+
+#define ClearPrivacy(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)); \
+ } while (0)
+
+
+#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_ORDER_)) != 0)
+
+#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & \
+ (BIT(3) | BIT(2)))
+
+#define SetFrameType(pbuf, type) \
+ do { \
+ *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | \
+ BIT(2))); \
+ *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \
+ } while (0)
+
+#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & \
+ (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | \
+ BIT(2)))
+
+#define SetFrameSubType(pbuf, type) \
+ do { \
+ *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \
+ BIT(5) | BIT(4) | BIT(3) | BIT(2))); \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(type); \
+ } while (0)
+
+#define GetSequence(pbuf) (cpu_to_le16(*(unsigned short *)\
+ ((addr_t)(pbuf) + 22)) >> 4)
+
+#define GetFragNum(pbuf) (cpu_to_le16(*(unsigned short *)((addr_t)\
+ (pbuf) + 22)) & 0x0f)
+
+#define GetTupleCache(pbuf) (cpu_to_le16(*(unsigned short *)\
+ ((addr_t)(pbuf) + 22)))
+
+#define SetFragNum(pbuf, num) \
+ do { \
+ *(unsigned short *)((addr_t)(pbuf) + 22) = \
+ ((*(unsigned short *)((addr_t)(pbuf) + 22)) & \
+ le16_to_cpu(~(0x000f))) | \
+ cpu_to_le16(0x0f & (num)); \
+ } while (0)
+
+#define SetSeqNum(pbuf, num) \
+ do { \
+ *(unsigned short *)((addr_t)(pbuf) + 22) = \
+ ((*(unsigned short *)((addr_t)(pbuf) + 22)) & \
+ le16_to_cpu((unsigned short)0x000f)) | \
+ le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \
+ } while (0)
+
+#define SetDuration(pbuf, dur) \
+ do { \
+ *(unsigned short *)((addr_t)(pbuf) + 2) |= \
+ cpu_to_le16(0xffff & (dur)); \
+ } while (0)
+
+#define SetPriority(pbuf, tid) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf); \
+ } while (0)
+
+#define GetPriority(pbuf) ((le16_to_cpu(*(unsigned short *)(pbuf))) & 0xf)
+
+#define SetAckpolicy(pbuf, ack) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16((ack & 3) << 5); \
+ } while (0)
+
+#define GetAckpolicy(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 5) & 0x3)
+
+#define GetAMsdu(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 7) & 0x1)
+
+#define SetAMsdu(pbuf, amsdu) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16((amsdu & 1) << 7); \
+ } while (0)
+
+#define GetAid(pbuf) (cpu_to_le16(*(unsigned short *)((addr_t)(pbuf) + 2)) \
+ & 0x3fff)
+
+#define GetTid(pbuf) (cpu_to_le16(*(unsigned short *)((addr_t)(pbuf) + \
+ (((GetToDs(pbuf) << 1)|GetFrDs(pbuf)) == 3 ? \
+ 30 : 24))) & 0x000f)
+
+#define GetAddr1Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 4))
+
+#define GetAddr2Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 10))
+
+#define GetAddr3Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 16))
+
+#define GetAddr4Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 24))
+
+
+
+static inline int IS_MCAST(unsigned char *da)
+{
+ if ((*da) & 0x01)
+ return true;
+ else
+ return false;
+}
+
+
+static inline unsigned char *get_da(unsigned char *pframe)
+{
+ unsigned char *da;
+ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe);
+
+ switch (to_fr_ds) {
+ case 0x00: /* ToDs=0, FromDs=0 */
+ da = GetAddr1Ptr(pframe);
+ break;
+ case 0x01: /* ToDs=0, FromDs=1 */
+ da = GetAddr1Ptr(pframe);
+ break;
+ case 0x02: /* ToDs=1, FromDs=0 */
+ da = GetAddr3Ptr(pframe);
+ break;
+ default: /* ToDs=1, FromDs=1 */
+ da = GetAddr3Ptr(pframe);
+ break;
+ }
+ return da;
+}
+
+
+static inline unsigned char *get_sa(unsigned char *pframe)
+{
+ unsigned char *sa;
+ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe);
+
+ switch (to_fr_ds) {
+ case 0x00: /* ToDs=0, FromDs=0 */
+ sa = GetAddr2Ptr(pframe);
+ break;
+ case 0x01: /* ToDs=0, FromDs=1 */
+ sa = GetAddr3Ptr(pframe);
+ break;
+ case 0x02: /* ToDs=1, FromDs=0 */
+ sa = GetAddr2Ptr(pframe);
+ break;
+ default: /* ToDs=1, FromDs=1 */
+ sa = GetAddr4Ptr(pframe);
+ break;
+ }
+
+ return sa;
+}
+
+static inline unsigned char *get_hdr_bssid(unsigned char *pframe)
+{
+ unsigned char *sa;
+ unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe);
+
+ switch (to_fr_ds) {
+ case 0x00: /* ToDs=0, FromDs=0 */
+ sa = GetAddr3Ptr(pframe);
+ break;
+ case 0x01: /* ToDs=0, FromDs=1 */
+ sa = GetAddr2Ptr(pframe);
+ break;
+ case 0x02: /* ToDs=1, FromDs=0 */
+ sa = GetAddr1Ptr(pframe);
+ break;
+ default: /* ToDs=1, FromDs=1 */
+ sa = NULL;
+ break;
+ }
+ return sa;
+}
+
+
+
+/*-----------------------------------------------------------------------------
+ Below is for the security related definition
+------------------------------------------------------------------------------*/
+#define _RESERVED_FRAME_TYPE_ 0
+#define _SKB_FRAME_TYPE_ 2
+#define _PRE_ALLOCMEM_ 1
+#define _PRE_ALLOCHDR_ 3
+#define _PRE_ALLOCLLCHDR_ 4
+#define _PRE_ALLOCICVHDR_ 5
+#define _PRE_ALLOCMICHDR_ 6
+
+#define _SIFSTIME_ ((priv->pmib->BssType.net_work_type & \
+ WIRELESS_11A) ? 16 : 10)
+#define _ACKCTSLNG_ 14 /*14 bytes long, including crclng */
+#define _CRCLNG_ 4
+
+#define _ASOCREQ_IE_OFFSET_ 4 /* excluding wlan_hdr */
+#define _ASOCRSP_IE_OFFSET_ 6
+#define _REASOCREQ_IE_OFFSET_ 10
+#define _REASOCRSP_IE_OFFSET_ 6
+#define _PROBEREQ_IE_OFFSET_ 0
+#define _PROBERSP_IE_OFFSET_ 12
+#define _AUTH_IE_OFFSET_ 6
+#define _DEAUTH_IE_OFFSET_ 0
+#define _BEACON_IE_OFFSET_ 12
+
+#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_
+
+#define _SSID_IE_ 0
+#define _SUPPORTEDRATES_IE_ 1
+#define _DSSET_IE_ 3
+#define _TIM_IE_ 5
+#define _IBSS_PARA_IE_ 6
+#define _CHLGETXT_IE_ 16
+#define _RSN_IE_2_ 48`
+#define _SSN_IE_1_ 221
+#define _ERPINFO_IE_ 42
+#define _EXT_SUPPORTEDRATES_IE_ 50
+
+#define _HT_CAPABILITY_IE_ 45
+#define _HT_EXTRA_INFO_IE_ 61
+#define _HT_ADD_INFO_IE_ 61 /* _HT_EXTRA_INFO_IE_ */
+
+#define _VENDOR_SPECIFIC_IE_ 221
+
+#define _RESERVED47_ 47
+
+
+/* ---------------------------------------------------------------------------
+ Below is the fixed elements...
+-----------------------------------------------------------------------------*/
+#define _AUTH_ALGM_NUM_ 2
+#define _AUTH_SEQ_NUM_ 2
+#define _BEACON_ITERVAL_ 2
+#define _CAPABILITY_ 2
+#define _CURRENT_APADDR_ 6
+#define _LISTEN_INTERVAL_ 2
+#define _RSON_CODE_ 2
+#define _ASOC_ID_ 2
+#define _STATUS_CODE_ 2
+#define _TIMESTAMP_ 8
+
+#define AUTH_ODD_TO 0
+#define AUTH_EVEN_TO 1
+
+#define WLAN_ETHCONV_ENCAP 1
+#define WLAN_ETHCONV_RFC1042 2
+#define WLAN_ETHCONV_8021h 3
+
+#define cap_ESS BIT(0)
+#define cap_IBSS BIT(1)
+#define cap_CFPollable BIT(2)
+#define cap_CFRequest BIT(3)
+#define cap_Privacy BIT(4)
+#define cap_ShortPremble BIT(5)
+
+/*-----------------------------------------------------------------------------
+ Below is the definition for 802.11i / 802.1x
+------------------------------------------------------------------------------*/
+#define _IEEE8021X_MGT_ 1 /*WPA */
+#define _IEEE8021X_PSK_ 2 /* WPA with pre-shared key */
+
+/*-----------------------------------------------------------------------------
+ Below is the definition for WMM
+------------------------------------------------------------------------------*/
+#define _WMM_IE_Length_ 7 /* for WMM STA */
+#define _WMM_Para_Element_Length_ 24
+
+
+/*-----------------------------------------------------------------------------
+ Below is the definition for 802.11n
+------------------------------------------------------------------------------*/
+
+/* block-ack parameters */
+#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
+#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
+#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
+
+#define SetOrderBit(pbuf) \
+ do { \
+ *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \
+ } while (0)
+
+#define GetOrderBit(pbuf) (((*(unsigned short *)(pbuf)) & \
+ le16_to_cpu(_ORDER_)) != 0)
+
+
+/**
+ * struct ieee80211_bar - HT Block Ack Request
+ *
+ * This structure refers to "HT BlockAckReq" as
+ * described in 802.11n draft section 7.2.1.7.1
+ */
+struct ieee80211_bar {
+ unsigned short frame_control;
+ unsigned short duration;
+ unsigned char ra[6];
+ unsigned char ta[6];
+ unsigned short control;
+ unsigned short start_seq_num;
+} __attribute__((packed));
+
+/* 802.11 BAR control masks */
+#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
+#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
+
+
+ /**
+ * struct ieee80211_ht_cap - HT capabilities
+ *
+ * This structure refers to "HT capabilities element" as
+ * described in 802.11n draft section 7.3.2.52
+ */
+
+struct ieee80211_ht_cap {
+ unsigned short cap_info;
+ unsigned char ampdu_params_info;
+ unsigned char supp_mcs_set[16];
+ unsigned short extended_ht_cap_info;
+ unsigned int tx_BF_cap_info;
+ unsigned char antenna_selection_info;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_ht_cap - HT additional information
+ *
+ * This structure refers to "HT information element" as
+ * described in 802.11n draft section 7.3.2.53
+ */
+struct ieee80211_ht_addt_info {
+ unsigned char control_chan;
+ unsigned char ht_param;
+ unsigned short operation_mode;
+ unsigned short stbc_param;
+ unsigned char basic_set[16];
+} __attribute__ ((packed));
+
+/* 802.11n HT capabilities masks */
+#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002
+#define IEEE80211_HT_CAP_SM_PS 0x000C
+#define IEEE80211_HT_CAP_GRN_FLD 0x0010
+#define IEEE80211_HT_CAP_SGI_20 0x0020
+#define IEEE80211_HT_CAP_SGI_40 0x0040
+#define IEEE80211_HT_CAP_TX_STBC 0x0080
+#define IEEE80211_HT_CAP_DELAY_BA 0x0400
+#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800
+#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
+/* 802.11n HT capability AMPDU settings */
+#define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03
+#define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C
+/* 802.11n HT capability MSC set */
+#define IEEE80211_SUPP_MCS_SET_UEQM 4
+#define IEEE80211_HT_CAP_MAX_STREAMS 4
+#define IEEE80211_SUPP_MCS_SET_LEN 10
+/* maximum streams the spec allows */
+#define IEEE80211_HT_CAP_MCS_TX_DEFINED 0x01
+#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF 0x02
+#define IEEE80211_HT_CAP_MCS_TX_STREAMS 0x0C
+#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10
+/* 802.11n HT IE masks */
+#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03
+#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00
+#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01
+#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03
+#define IEEE80211_HT_IE_CHA_WIDTH 0x04
+#define IEEE80211_HT_IE_HT_PROTECTION 0x0003
+#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
+#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010
+
+/* block-ack parameters */
+#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
+#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
+#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
+
+/*
+ * A-PMDU buffer sizes
+ * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2)
+ */
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_MAX_AMPDU_BUF 0x40
+
+
+/* Spatial Multiplexing Power Save Modes */
+#define WLAN_HT_CAP_SM_PS_STATIC 0
+#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
+#define WLAN_HT_CAP_SM_PS_INVALID 2
+#define WLAN_HT_CAP_SM_PS_DISABLED 3
+
+#endif /* _WIFI_H_ */
+
diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h
new file mode 100644
index 000000000000..6d9295270f83
--- /dev/null
+++ b/drivers/staging/rtl8712/wlan_bssdef.h
@@ -0,0 +1,242 @@
+#ifndef __WLAN_BSSDEF_H__
+#define __WLAN_BSSDEF_H__
+
+#define MAX_IE_SZ 768
+
+#define NDIS_802_11_LENGTH_SSID 32
+#define NDIS_802_11_LENGTH_RATES 8
+#define NDIS_802_11_LENGTH_RATES_EX 16
+
+/* Set of 8 data rates*/
+typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];
+/* Set of 16 data rates */
+typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
+
+struct ndis_802_11_ssid {
+ u32 SsidLength;
+ u8 Ssid[32];
+};
+
+enum NDIS_802_11_NETWORK_TYPE {
+ Ndis802_11FH,
+ Ndis802_11DS,
+ Ndis802_11OFDM5,
+ Ndis802_11OFDM24,
+ Ndis802_11NetworkTypeMax /* not a real type, defined as an upper bound */
+};
+
+struct NDIS_802_11_CONFIGURATION_FH {
+ u32 Length; /* Length of structure */
+ u32 HopPattern; /* As defined by 802.11, MSB set */
+ u32 HopSet; /* to one if non-802.11 */
+ u32 DwellTime; /* units are Kusec */
+};
+
+/*
+ FW will only save the channel number in DSConfig.
+ ODI Handler will convert the channel number to freq. number.
+*/
+struct NDIS_802_11_CONFIGURATION {
+ u32 Length; /* Length of structure */
+ u32 BeaconPeriod; /* units are Kusec */
+ u32 ATIMWindow; /* units are Kusec */
+ u32 DSConfig; /* Frequency, units are kHz */
+ struct NDIS_802_11_CONFIGURATION_FH FHConfig;
+};
+
+enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
+ Ndis802_11IBSS,
+ Ndis802_11Infrastructure,
+ Ndis802_11AutoUnknown,
+ Ndis802_11InfrastructureMax, /* Not a real value, defined as upper bound */
+ Ndis802_11APMode
+};
+
+struct NDIS_802_11_FIXED_IEs {
+ u8 Timestamp[8];
+ u16 BeaconInterval;
+ u16 Capabilities;
+};
+
+/*
+ * Length is the 4 bytes multiples of the sume of
+ * 6 * sizeof (unsigned char) + 2 + sizeof (ndis_802_11_ssid) + sizeof (u32)
+ * + sizeof (s32) + sizeof (NDIS_802_11_NETWORK_TYPE)
+ * + sizeof (struct NDIS_802_11_CONFIGURATION)
+ * + sizeof (NDIS_802_11_RATES_EX) + IELength
+
+ * Except the IELength, all other fields are fixed length. Therefore, we can
+ * define a macro to present the partial sum.
+ */
+
+struct ndis_wlan_bssid_ex {
+ u32 Length;
+ unsigned char MacAddress[6];
+ u8 Reserved[2];
+ struct ndis_802_11_ssid Ssid;
+ u32 Privacy;
+ s32 Rssi;
+ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ struct NDIS_802_11_CONFIGURATION Configuration;
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES_EX SupportedRates;
+ u32 IELength;
+/*(timestamp, beacon interval, and capability information) */
+ u8 IEs[MAX_IE_SZ];
+};
+
+enum NDIS_802_11_AUTHENTICATION_MODE {
+ Ndis802_11AuthModeOpen,
+ Ndis802_11AuthModeShared,
+ Ndis802_11AuthModeAutoSwitch,
+ Ndis802_11AuthModeWPA,
+ Ndis802_11AuthModeWPAPSK,
+ Ndis802_11AuthModeWPANone,
+ Ndis802_11AuthModeMax /* Not a real mode, defined as upper bound */
+};
+
+enum {
+ Ndis802_11WEPEnabled,
+ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+ Ndis802_11WEPDisabled,
+ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+ Ndis802_11WEPKeyAbsent,
+ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+ Ndis802_11WEPNotSupported,
+ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+ Ndis802_11Encryption2Enabled,
+ Ndis802_11Encryption2KeyAbsent,
+ Ndis802_11Encryption3Enabled,
+ Ndis802_11Encryption3KeyAbsent
+};
+
+#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
+#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
+#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
+
+#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
+#define NDIS_802_11_AI_RESFI_STATUSCODE 2
+#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
+
+struct NDIS_802_11_AI_REQFI {
+ u16 Capabilities;
+ u16 ListenInterval;
+ unsigned char CurrentAPAddress[6];
+};
+
+struct NDIS_802_11_AI_RESFI {
+ u16 Capabilities;
+ u16 StatusCode;
+ u16 AssociationId;
+};
+
+struct NDIS_802_11_ASSOCIATION_INFORMATION {
+ u32 Length;
+ u16 AvailableRequestFixedIEs;
+ struct NDIS_802_11_AI_REQFI RequestFixedIEs;
+ u32 RequestIELength;
+ u32 OffsetRequestIEs;
+ u16 AvailableResponseFixedIEs;
+ struct NDIS_802_11_AI_RESFI ResponseFixedIEs;
+ u32 ResponseIELength;
+ u32 OffsetResponseIEs;
+};
+
+/* Key mapping keys require a BSSID*/
+struct NDIS_802_11_KEY {
+ u32 Length; /* Length of this structure */
+ u32 KeyIndex;
+ u32 KeyLength; /* length of key in bytes */
+ unsigned char BSSID[6];
+ unsigned long long KeyRSC;
+ u8 KeyMaterial[32]; /* variable length */
+};
+
+struct NDIS_802_11_REMOVE_KEY {
+ u32 Length; /* Length of this structure */
+ u32 KeyIndex;
+ unsigned char BSSID[6];
+};
+
+struct NDIS_802_11_WEP {
+ u32 Length; /* Length of this structure */
+ u32 KeyIndex; /* 0 is the per-client key,
+ * 1-N are the global keys */
+ u32 KeyLength; /* length of key in bytes */
+ u8 KeyMaterial[16];/* variable length depending on above field */
+};
+
+/* mask for authentication/integrity fields */
+#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
+#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
+#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
+#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
+#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
+
+/* MIC check time, 60 seconds. */
+#define MIC_CHECK_TIME 60000000
+
+#ifndef Ndis802_11APMode
+#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1)
+#endif
+
+struct wlan_network {
+ struct list_head list;
+ int network_type; /*refer to ieee80211.h for WIRELESS_11A/B/G */
+ int fixed; /* set to fixed when not to be removed asi
+ * site-surveying */
+ unsigned int last_scanned; /*timestamp for the network */
+ int aid; /*will only be valid when a BSS is joined. */
+ int join_res;
+ struct ndis_wlan_bssid_ex network; /*must be the last item */
+};
+
+enum VRTL_CARRIER_SENSE {
+ DISABLE_VCS,
+ ENABLE_VCS,
+ AUTO_VCS
+};
+
+enum VCS_TYPE {
+ NONE_VCS,
+ RTS_CTS,
+ CTS_TO_SELF
+};
+
+#define PWR_CAM 0
+#define PWR_MINPS 1
+#define PWR_MAXPS 2
+#define PWR_UAPSD 3
+#define PWR_VOIP 4
+
+enum UAPSD_MAX_SP {
+ NO_LIMIT,
+ TWO_MSDU,
+ FOUR_MSDU,
+ SIX_MSDU
+};
+
+#define NUM_PRE_AUTH_KEY 16
+#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY
+
+/*
+ * WPA2
+ */
+struct wlan_bssid_ex {
+ u32 Length;
+ unsigned char MacAddress[6];
+ u8 Reserved[2];
+ struct ndis_802_11_ssid Ssid;
+ u32 Privacy;
+ s32 Rssi;
+ enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ struct NDIS_802_11_CONFIGURATION Configuration;
+ enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES_EX SupportedRates;
+ u32 IELength;
+ u8 IEs[MAX_IE_SZ]; /* (timestamp, beacon interval, and capability
+ * information) */
+};
+
+#endif /* #ifndef WLAN_BSSDEF_H_ */
+
diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c
new file mode 100644
index 000000000000..7dea8b5b7e75
--- /dev/null
+++ b/drivers/staging/rtl8712/xmit_linux.c
@@ -0,0 +1,182 @@
+/******************************************************************************
+ * xmit_linux.c
+ *
+ * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8192SU
+ *
+ * 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
+ *
+ * Modifications for inclusion into the Linux staging tree are
+ * Copyright(c) 2010 Larry Finger. All rights reserved.
+ *
+ * Contact information:
+ * WLAN FAE <wlanfae@realtek.com>
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+
+#define _XMIT_OSDEP_C_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+
+#include "if_ether.h"
+#include "ip.h"
+#include "rtl871x_byteorder.h"
+#include "wifi.h"
+#include "mlme_osdep.h"
+#include "xmit_osdep.h"
+#include "osdep_intf.h"
+
+static uint remainder_len(struct pkt_file *pfile)
+{
+ /* Kovich: Need to extend the buf_len to 64 bit ?(unsigned long long) */
+ return (uint)(pfile->buf_len - ((addr_t)(pfile->cur_addr) -
+ (addr_t)(pfile->buf_start)));
+}
+
+void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile)
+{
+ pfile->pkt = pktptr;
+ pfile->cur_addr = pfile->buf_start = pktptr->data;
+ pfile->pkt_len = pfile->buf_len = pktptr->len;
+ pfile->cur_buffer = pfile->buf_start ;
+}
+
+uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
+{
+ uint len;
+
+ len = remainder_len(pfile);
+ len = (rlen > len) ? len : rlen;
+ if (rmem)
+ skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len,
+ rmem, len);
+ pfile->cur_addr += len;
+ pfile->pkt_len -= len;
+ return len;
+}
+
+sint r8712_endofpktfile(struct pkt_file *pfile)
+{
+ if (pfile->pkt_len == 0)
+ return true;
+ else
+ return false;
+}
+
+
+void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
+{
+ int i;
+ struct ethhdr etherhdr;
+ struct iphdr ip_hdr;
+ u16 UserPriority = 0;
+
+ _r8712_open_pktfile(ppktfile->pkt, ppktfile);
+ _r8712_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
+
+ /* get UserPriority from IP hdr*/
+ if (pattrib->ether_type == 0x0800) {
+ i = _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr,
+ sizeof(ip_hdr));
+ /*UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/
+ UserPriority = ip_hdr.tos >> 5;
+ } else {
+ /* "When priority processing of data frames is supported,
+ * a STA's SME should send EAPOL-Key frames at the highest
+ * priority." */
+
+ if (pattrib->ether_type == 0x888e)
+ UserPriority = 7;
+ }
+ pattrib->priority = UserPriority;
+ pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
+ pattrib->subtype = WIFI_QOS_DATA_TYPE;
+}
+
+int r8712_xmit_resource_alloc(struct _adapter *padapter,
+ struct xmit_buf *pxmitbuf)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ pxmitbuf->pxmit_urb[i] = _usb_alloc_urb(0, GFP_KERNEL);
+ if (pxmitbuf->pxmit_urb[i] == NULL) {
+ printk(KERN_ERR "r8712u: pxmitbuf->pxmit_urb[i]"
+ " == NULL");
+ return _FAIL;
+ }
+ }
+ return _SUCCESS;
+}
+
+void r8712_xmit_resource_free(struct _adapter *padapter,
+ struct xmit_buf *pxmitbuf)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (pxmitbuf->pxmit_urb[i]) {
+ usb_kill_urb(pxmitbuf->pxmit_urb[i]);
+ usb_free_urb(pxmitbuf->pxmit_urb[i]);
+ }
+ }
+}
+
+void r8712_xmit_complete(struct _adapter *padapter, struct xmit_frame *pxframe)
+{
+ if (pxframe->pkt)
+ dev_kfree_skb_any(pxframe->pkt);
+ pxframe->pkt = NULL;
+}
+
+int r8712_xmit_entry(_pkt *pkt, struct net_device *pnetdev)
+{
+ struct xmit_frame *pxmitframe = NULL;
+ struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev);
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ int ret = 0;
+
+ if (r8712_if_up(padapter) == false) {
+ ret = 0;
+ goto _xmit_entry_drop;
+ }
+ pxmitframe = r8712_alloc_xmitframe(pxmitpriv);
+ if (pxmitframe == NULL) {
+ ret = 0;
+ goto _xmit_entry_drop;
+ }
+ if ((!r8712_update_attrib(padapter, pkt, &pxmitframe->attrib))) {
+ ret = 0;
+ goto _xmit_entry_drop;
+ }
+ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_TX);
+ pxmitframe->pkt = pkt;
+ if (r8712_pre_xmit(padapter, pxmitframe) == true) {
+ /*dump xmitframe directly or drop xframe*/
+ dev_kfree_skb_any(pkt);
+ pxmitframe->pkt = NULL;
+ }
+ pxmitpriv->tx_pkts++;
+ pxmitpriv->tx_bytes += pxmitframe->attrib.last_txcmdsz;
+ return ret;
+_xmit_entry_drop:
+ if (pxmitframe)
+ r8712_free_xmitframe(pxmitpriv, pxmitframe);
+ pxmitpriv->tx_drop++;
+ dev_kfree_skb_any(pkt);
+ return ret;
+}
diff --git a/drivers/staging/rtl8712/xmit_osdep.h b/drivers/staging/rtl8712/xmit_osdep.h
new file mode 100644
index 000000000000..ca439378953d
--- /dev/null
+++ b/drivers/staging/rtl8712/xmit_osdep.h
@@ -0,0 +1,38 @@
+#ifndef __XMIT_OSDEP_H_
+#define __XMIT_OSDEP_H_
+
+#include "osdep_service.h"
+#include "drv_types.h"
+
+struct pkt_file {
+ _pkt *pkt;
+ u32 pkt_len; /*the remainder length of the open_file*/
+ _buffer *cur_buffer;
+ u8 *buf_start;
+ u8 *cur_addr;
+ u32 buf_len;
+};
+
+#define NR_XMITFRAME 256
+
+struct xmit_priv;
+struct pkt_attrib;
+struct sta_xmit_priv;
+struct xmit_frame;
+struct xmit_buf;
+
+int r8712_xmit_entry(_pkt *pkt, struct net_device *pnetdev);
+int r8712_xmit_resource_alloc(struct _adapter *padapter,
+ struct xmit_buf *pxmitbuf);
+void r8712_xmit_resource_free(struct _adapter *padapter,
+ struct xmit_buf *pxmitbuf);
+
+void r8712_set_qos(struct pkt_file *ppktfile,
+ struct pkt_attrib *pattrib);
+void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile);
+uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen);
+sint r8712_endofpktfile(struct pkt_file *pfile);
+void r8712_xmit_complete(struct _adapter *padapter,
+ struct xmit_frame *pxframe);
+
+#endif
diff --git a/drivers/staging/sbe-2t3e3/2t3e3.h b/drivers/staging/sbe-2t3e3/2t3e3.h
new file mode 100644
index 000000000000..fe9f086b6e7a
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/2t3e3.h
@@ -0,0 +1,894 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#ifndef T3E3_H
+#define T3E3_H
+
+#include <linux/hdlc.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include "ctrl.h"
+
+/**************************************************************
+ * 21143
+ **************************************************************/
+
+/* CSR */
+#define SBE_2T3E3_21143_REG_BUS_MODE 0
+#define SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND 1
+#define SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND 2
+#define SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS 3
+#define SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS 4
+#define SBE_2T3E3_21143_REG_STATUS 5
+#define SBE_2T3E3_21143_REG_OPERATION_MODE 6
+#define SBE_2T3E3_21143_REG_INTERRUPT_ENABLE 7
+#define SBE_2T3E3_21143_REG_MISSED_FRAMES_AND_OVERFLOW_COUNTER 8
+#define SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT 9
+#define SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS 10
+#define SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL 11
+#define SBE_2T3E3_21143_REG_SIA_STATUS 12
+#define SBE_2T3E3_21143_REG_SIA_CONNECTIVITY 13
+#define SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE 14
+#define SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT 15
+#define SBE_2T3E3_21143_REG_MAX 16
+
+/* CSR0 - BUS_MODE */
+#define SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE 0x01000000
+#define SBE_2T3E3_21143_VAL_READ_LINE_ENABLE 0x00800000
+#define SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE 0x00200000
+#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us 0x00020000
+#define SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_DISABLED 0x00000000
+#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32 0x0000c000
+#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16 0x00008000
+#define SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8 0x00004000
+#define SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR 0x00000002
+#define SBE_2T3E3_21143_VAL_SOFTWARE_RESET 0x00000001
+
+/* CSR5 - STATUS */
+#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_INTERRUPT 0x04000000
+#define SBE_2T3E3_21143_VAL_ERROR_BITS 0x03800000
+#define SBE_2T3E3_21143_VAL_PARITY_ERROR 0x00000000
+#define SBE_2T3E3_21143_VAL_MASTER_ABORT 0x00800000
+#define SBE_2T3E3_21143_VAL_TARGET_ABORT 0x01000000
+#define SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE 0x00700000
+#define SBE_2T3E3_21143_VAL_TX_STOPPED 0x00000000
+#define SBE_2T3E3_21143_VAL_TX_SUSPENDED 0x00600000
+#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE 0x000e0000
+#define SBE_2T3E3_21143_VAL_RX_STOPPED 0x00000000
+#define SBE_2T3E3_21143_VAL_RX_SUSPENDED 0x000a0000
+#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY 0x00010000
+#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY 0x00008000
+#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT 0x00004000
+#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR 0x00002000
+#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_EXPIRED 0x00000800
+#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT 0x00000400
+#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT 0x00000200
+#define SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED 0x00000100
+#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE 0x00000080
+#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT 0x00000040
+#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW 0x00000020
+#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT 0x00000008
+#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE 0x00000004
+#define SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED 0x00000002
+#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT 0x00000001
+
+/* CSR6 - OPERATION_MODE */
+#define SBE_2T3E3_21143_VAL_SPECIAL_CAPTURE_EFFECT_ENABLE 0x80000000
+#define SBE_2T3E3_21143_VAL_RECEIVE_ALL 0x40000000
+#define SBE_2T3E3_21143_VAL_MUST_BE_ONE 0x02000000
+#define SBE_2T3E3_21143_VAL_SCRAMBLER_MODE 0x01000000
+#define SBE_2T3E3_21143_VAL_PCS_FUNCTION 0x00800000
+#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_10Mbs 0x00400000
+#define SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs 0x00000000
+#define SBE_2T3E3_21143_VAL_STORE_AND_FORWARD 0x00200000
+#define SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE 0x00080000
+#define SBE_2T3E3_21143_VAL_PORT_SELECT 0x00040000
+#define SBE_2T3E3_21143_VAL_CAPTURE_EFFECT_ENABLE 0x00020000
+#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS 0x0000c000
+#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 0x00000000
+#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2 0x00004000
+#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3 0x00008000
+#define SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4 0x0000c000
+#define SBE_2T3E3_21143_VAL_TRANSMISSION_START 0x00002000
+#define SBE_2T3E3_21143_VAL_OPERATING_MODE 0x00000c00
+#define SBE_2T3E3_21143_VAL_LOOPBACK_OFF 0x00000000
+#define SBE_2T3E3_21143_VAL_LOOPBACK_EXTERNAL 0x00000800
+#define SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL 0x00000400
+#define SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE 0x00000200
+#define SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST 0x00000080
+#define SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE 0x00000040
+#define SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES 0x00000008
+#define SBE_2T3E3_21143_VAL_RECEIVE_START 0x00000002
+
+/* CSR7 - INTERRUPT_ENABLE */
+#define SBE_2T3E3_21143_VAL_LINK_CHANGED_ENABLE 0x08000000
+#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_PORT_ENABLE 0x04000000
+#define SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE 0x00010000
+#define SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE 0x00008000
+#define SBE_2T3E3_21143_VAL_EARLY_RECEIVE_INTERRUPT_ENABLE 0x00004000
+#define SBE_2T3E3_21143_VAL_FATAL_BUS_ERROR_ENABLE 0x00002000
+#define SBE_2T3E3_21143_VAL_LINK_FAIL_ENABLE 0x00001000
+#define SBE_2T3E3_21143_VAL_GENERAL_PURPOSE_TIMER_ENABLE 0x00000800
+#define SBE_2T3E3_21143_VAL_EARLY_TRANSMIT_INTERRUPT_ENABLE 0x00000400
+#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_TIMEOUT_ENABLE 0x00000200
+#define SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE 0x00000100
+#define SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE 0x00000080
+#define SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE 0x00000040
+#define SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE 0x00000020
+#define SBE_2T3E3_21143_VAL_TRANSMIT_JABBER_TIMEOUT_ENABLE 0x00000008
+#define SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE 0x00000004
+#define SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE 0x00000002
+#define SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE 0x00000001
+
+/* CSR8 - MISSED_FRAMES_AND_OVERFLOW_COUNTER */
+#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER_OVERFLOW 0x10000000
+#define SBE_2T3E3_21143_VAL_OVERFLOW_COUNTER 0x0ffe0000
+#define SBE_2T3E3_21143_VAL_MISSED_FRAME_OVERFLOW 0x00010000
+#define SBE_2T3E3_21143_VAL_MISSED_FRAMES_COUNTER 0x0000ffff
+
+/* CSR9 - BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT */
+#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_IN 0x00080000
+#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_READ_MODE 0x00040000
+#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_DATA_OUT 0x00020000
+#define SBE_2T3E3_21143_VAL_MII_MANAGEMENT_CLOCK 0x00010000
+#define SBE_2T3E3_21143_VAL_READ_OPERATION 0x00004000
+#define SBE_2T3E3_21143_VAL_WRITE_OPERATION 0x00002000
+#define SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT 0x00001000
+#define SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT 0x00000800
+#define SBE_2T3E3_21143_VAL_BOOT_ROM_DATA 0x000000ff
+#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT 0x00000008
+#define SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_IN 0x00000004
+#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK 0x00000002
+#define SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT 0x00000001
+
+/* CSR11 - GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL */
+#define SBE_2T3E3_21143_VAL_CYCLE_SIZE 0x80000000
+#define SBE_2T3E3_21143_VAL_TRANSMIT_TIMER 0x78000000
+#define SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS 0x07000000
+#define SBE_2T3E3_21143_VAL_RECEIVE_TIMER 0x00f00000
+#define SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS 0x000e0000
+#define SBE_2T3E3_21143_VAL_CONTINUOUS_MODE 0x00010000
+#define SBE_2T3E3_21143_VAL_TIMER_VALUE 0x0000ffff
+
+/* CSR12 - SIA_STATUS */
+#define SBE_2T3E3_21143_VAL_10BASE_T_RECEIVE_PORT_ACTIVITY 0x00000200
+#define SBE_2T3E3_21143_VAL_AUI_RECEIVE_PORT_ACTIVITY 0x00000100
+#define SBE_2T3E3_21143_VAL_10Mbs_LINK_STATUS 0x00000004
+#define SBE_2T3E3_21143_VAL_100Mbs_LINK_STATUS 0x00000002
+#define SBE_2T3E3_21143_VAL_MII_RECEIVE_PORT_ACTIVITY 0x00000001
+
+/* CSR13 - SIA_CONNECTIVITY */
+#define SBE_2T3E3_21143_VAL_10BASE_T_OR_AUI 0x00000008
+#define SBE_2T3E3_21143_VAL_SIA_RESET 0x00000001
+
+/* CSR14 - SIA_TRANSMIT_AND_RECEIVE */
+#define SBE_2T3E3_21143_VAL_100BASE_TX_FULL_DUPLEX 0x00020000
+#define SBE_2T3E3_21143_VAL_COLLISION_DETECT_ENABLE 0x00000400
+#define SBE_2T3E3_21143_VAL_COLLISION_SQUELCH_ENABLE 0x00000200
+#define SBE_2T3E3_21143_VAL_RECEIVE_SQUELCH_ENABLE 0x00000100
+#define SBE_2T3E3_21143_VAL_LINK_PULSE_SEND_ENABLE 0x00000004
+#define SBE_2T3E3_21143_VAL_ENCODER_ENABLE 0x00000001
+
+/* CSR15 - SIA_AND_GENERAL_PURPOSE_PORT */
+#define SBE_2T3E3_21143_VAL_RECEIVE_WATCHDOG_DISABLE 0x00000010
+#define SBE_2T3E3_21143_VAL_AUI_BNC_MODE 0x00000008
+#define SBE_2T3E3_21143_VAL_HOST_UNJAB 0x00000002
+#define SBE_2T3E3_21143_VAL_JABBER_DISABLE 0x00000001
+
+/**************************************************************
+ * CPLD
+ **************************************************************/
+
+/* reg_map indexes */
+#define SBE_2T3E3_CPLD_REG_PCRA 0
+#define SBE_2T3E3_CPLD_REG_PCRB 1
+#define SBE_2T3E3_CPLD_REG_PLCR 2
+#define SBE_2T3E3_CPLD_REG_PLTR 3
+#define SBE_2T3E3_CPLD_REG_PPFR 4
+#define SBE_2T3E3_CPLD_REG_BOARD_ID 5
+#define SBE_2T3E3_CPLD_REG_FPGA_VERSION 6
+#define SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS 7
+#define SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT 8
+#define SBE_2T3E3_CPLD_REG_STATIC_RESET 9
+#define SBE_2T3E3_CPLD_REG_PULSE_RESET 10
+#define SBE_2T3E3_CPLD_REG_FPGA_RECONFIGURATION 11
+#define SBE_2T3E3_CPLD_REG_LEDR 12
+#define SBE_2T3E3_CPLD_REG_PICSR 13
+#define SBE_2T3E3_CPLD_REG_PIER 14
+#define SBE_2T3E3_CPLD_REG_PCRC 15
+#define SBE_2T3E3_CPLD_REG_PBWF 16
+#define SBE_2T3E3_CPLD_REG_PBWL 17
+
+#define SBE_2T3E3_CPLD_REG_MAX 18
+
+/**********/
+
+/* val_map indexes */
+#define SBE_2T3E3_CPLD_VAL_LIU_SELECT 0
+#define SBE_2T3E3_CPLD_VAL_DAC_SELECT 1
+#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE 2
+#define SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET 3
+
+/* PCRA */
+#define SBE_2T3E3_CPLD_VAL_CRC32 0x40
+#define SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE 0x20
+#define SBE_2T3E3_CPLD_VAL_REAR_PANEL 0x10
+#define SBE_2T3E3_CPLD_VAL_RAW_MODE 0x08
+#define SBE_2T3E3_CPLD_VAL_ALT 0x04
+#define SBE_2T3E3_CPLD_VAL_LOOP_TIMING 0x02
+#define SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3 0x01
+
+/* PCRB */
+#define SBE_2T3E3_CPLD_VAL_PAD_COUNT 0x30
+#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_1 0x00
+#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_2 0x10
+#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_3 0x20
+#define SBE_2T3E3_CPLD_VAL_PAD_COUNT_4 0x30
+#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE 0x02
+#define SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE 0x01
+
+/* PCRC */
+#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE 0x00
+#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0 0x01
+#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1 0x11
+#define SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2 0x21
+
+/* PLTR */
+#define SBE_2T3E3_CPLD_VAL_LCV_COUNTER 0xff
+
+/* SCSR */
+#define SBE_2T3E3_CPLD_VAL_EEPROM_SELECT 0x10
+
+/* PICSR */
+#define SBE_2T3E3_CPLD_VAL_LOSS_OF_SIGNAL_THRESHOLD_LEVEL_1 0x80
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE 0x40
+#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED 0x20
+#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED 0x10
+#define SBE_2T3E3_CPLD_VAL_LCV_LIMIT_EXCEEDED 0x08
+#define SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED 0x04
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED 0x02
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED 0x01
+
+/* PIER */
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOS_CHANGE_ENABLE 0x40
+#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE 0x20
+#define SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE 0x10
+#define SBE_2T3E3_CPLD_VAL_LCV_INTERRUPT_ENABLE 0x08
+#define SBE_2T3E3_CPLD_VAL_DMO_ENABLE 0x04
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_ENABLE 0x02
+#define SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_ENABLE 0x01
+
+/**************************************************************
+ * Framer
+ **************************************************************/
+
+/* reg_map indexes */
+/* common */
+#define SBE_2T3E3_FRAMER_REG_OPERATING_MODE 0
+#define SBE_2T3E3_FRAMER_REG_IO_CONTROL 1
+#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE 2
+#define SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS 3
+#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB 28
+#define SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_LSB 29
+#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB 30
+#define SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB 31
+#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB 32
+#define SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_LSB 33
+#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB 34
+#define SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_LSB 35
+#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB 36
+#define SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_LSB 37
+#define SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER 38
+#define SBE_2T3E3_FRAMER_REG_ONE_SECOND_ERROR_STATUS 39
+#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_MSB 40
+#define SBE_2T3E3_FRAMER_REG_LCV_ONE_SECOND_ACCUMULATOR_LSB 41
+#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB 42
+#define SBE_2T3E3_FRAMER_REG_FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB 43
+#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB 44
+#define SBE_2T3E3_FRAMER_REG_FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB 45
+#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_DRIVE 46
+#define SBE_2T3E3_FRAMER_REG_LINE_INTERFACE_SCAN 47
+
+/* T3 */
+#define SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS 4
+#define SBE_2T3E3_FRAMER_REG_T3_RX_STATUS 5
+#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE 6
+#define SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS 7
+#define SBE_2T3E3_FRAMER_REG_T3_RX_SYNC_DETECT_ENABLE 8
+#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC 10
+#define SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS 11
+#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL 12
+#define SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_STATUS 13
+#define SBE_2T3E3_FRAMER_REG_T3_TX_CONFIGURATION 16
+#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS 17
+#define SBE_2T3E3_FRAMER_REG_T3_TX_FEAC 18
+#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_CONFIGURATION 19
+#define SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS 20
+#define SBE_2T3E3_FRAMER_REG_T3_TX_MBIT_MASK 21
+#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK 22
+#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_2 23
+#define SBE_2T3E3_FRAMER_REG_T3_TX_FBIT_MASK_3 24
+
+/* E3 */
+#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_1 4
+#define SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2 5
+#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1 6
+#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2 7
+#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1 8
+#define SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2 9
+#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL 12
+#define SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_STATUS 13
+#define SBE_2T3E3_FRAMER_REG_E3_RX_NR_BYTE 14
+#define SBE_2T3E3_FRAMER_REG_E3_RX_SERVICE_BITS 14
+#define SBE_2T3E3_FRAMER_REG_E3_RX_GC_BYTE 15
+#define SBE_2T3E3_FRAMER_REG_E3_TX_CONFIGURATION 16
+#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_CONFIGURATION 19
+#define SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS 19
+#define SBE_2T3E3_FRAMER_REG_E3_TX_GC_BYTE 21
+#define SBE_2T3E3_FRAMER_REG_E3_TX_SERVICE_BITS 21
+#define SBE_2T3E3_FRAMER_REG_E3_TX_MA_BYTE 22
+#define SBE_2T3E3_FRAMER_REG_E3_TX_NR_BYTE 23
+#define SBE_2T3E3_FRAMER_REG_E3_TX_FA1_ERROR_MASK 25
+#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_UPPER 25
+#define SBE_2T3E3_FRAMER_REG_E3_TX_FA2_ERROR_MASK 26
+#define SBE_2T3E3_FRAMER_REG_E3_TX_FAS_ERROR_MASK_LOWER 26
+#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP8_MASK 27
+#define SBE_2T3E3_FRAMER_REG_E3_TX_BIP4_MASK 27
+
+#define SBE_2T3E3_FRAMER_REG_MAX 48
+
+/**********/
+
+/* OPERATING_MODE */
+#define SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE 0x80
+#define SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT 0x40
+#define SBE_2T3E3_FRAMER_VAL_INTERNAL_LOS_ENABLE 0x20
+#define SBE_2T3E3_FRAMER_VAL_RESET 0x10
+#define SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET 0x08
+#define SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT 0x04
+#define SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK 0x03
+#define SBE_2T3E3_FRAMER_VAL_E3_G751 0x00
+#define SBE_2T3E3_FRAMER_VAL_E3_G832 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_CBIT 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_M13 0x44
+#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON 0x80
+#define SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF 0x00
+
+/* IO_CONTROL */
+#define SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK 0x80
+#define SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS 0x40
+#define SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK 0x20
+#define SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE 0x10
+#define SBE_2T3E3_FRAMER_VAL_UNIPOLAR 0x08
+#define SBE_2T3E3_FRAMER_VAL_TX_LINE_CLOCK_INVERT 0x04
+#define SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT 0x02
+#define SBE_2T3E3_FRAMER_VAL_REFRAME 0x01
+
+/* BLOCK_INTERRUPT_ENABLE */
+#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE 0x80
+#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_ENABLE 0x01
+
+/* BLOCK_INTERRUPT_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS 0x80
+#define SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS 0x02
+#define SBE_2T3E3_FRAMER_VAL_ONE_SECOND_INTERRUPT_STATUS 0x01
+
+/**********/
+
+/* T3_RX_CONFIGURATION_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS 0x80
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE 0x20
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FRAMING_ON_PARITY 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_F_SYNC_ALGO 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_M_SYNC_ALGO 0x01
+
+/* T3_RX_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE 0x07
+
+/* T3_RX_INTERRUPT_ENABLE */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE 0x80
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE 0x20
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE 0x01
+
+/* T3_RX_INTERRUPT_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_STATUS 0x80
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_STATUS 0x20
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_STATUS 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_STATUS 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_STATUS 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_STATUS 0x01
+
+/* T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_STATUS 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_STATUS 0x01
+
+/* T3_RX_LAPD_CONTROL */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_INTERRUPT_STATUS 0x01
+
+/* T3_RX_LAPD_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_ABORT 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_LAPD_TYPE 0x30
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_CR_TYPE 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FCS_ERROR 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_END_OF_MESSAGE 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_RX_FLAG_PRESENT 0x01
+
+/* T3_TX_CONFIGURATION */
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_YELLOW_ALARM 0x80
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_X_BIT 0x40
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_IDLE 0x20
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_AIS 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_LOS 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_LOS 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_OOF 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FERF_ON_AIS 0x01
+
+/* T3_TX_FEAC_CONFIGURATION_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_ENABLE 0x10
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_INTERRUPT_STATUS 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_GO 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_FEAC_BUSY 0x01
+
+/* T3_TX_LAPD_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_START 0x08
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_DL_BUSY 0x04
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_T3_TX_LAPD_INTERRUPT_STATUS 0x01
+
+/**********/
+
+/* E3_RX_CONFIGURATION_STATUS_1 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_TYPE 0xe0
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_ALGO 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK_ALGO 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_EXPECTED 0x07
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4 0x01
+
+/* E3_RX_CONFIGURATION_STATUS_2 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_ALGO 0x80
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF 0x40
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF 0x20
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_UNSTABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_T_MARK 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF 0x01
+
+/* E3_RX_INTERRUPT_ENABLE_1 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE 0x01
+
+/* E3_RX_INTERRUPT_ENABLE_2 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_ENABLE 0x40
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_ENABLE 0x01
+
+/* E3_RX_INTERRUPT_STATUS_1 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_STATUS 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_STATUS 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_STATUS 0x01
+
+/* E3_RX_INTERRUPT_STATUS_2 */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_TTB_CHANGE_INTERRUPT_STATUS 0x40
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_STATUS 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_STATUS 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP8_ERROR_INTERRUPT_STATUS 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_BIP4_ERROR_INTERRUPT_STATUS 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_STATUS 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_PAYLOAD_MISMATCH_INTERRUPT_STATUS 0x01
+
+/* E3_RX_LAPD_CONTROL */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_DL_FROM_NR 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_INTERRUPT_STATUS 0x01
+
+/* E3_RX_LAPD_STATUS */
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_ABORT 0x40
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_LAPD_TYPE 0x30
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_CR_TYPE 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FCS_ERROR 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_END_OF_MESSAGE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_RX_FLAG_PRESENT 0x01
+
+/* E3_TX_CONFIGURATION */
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_BIP4_ENABLE 0x80
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_A_SOURCE_SELECT 0x60
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_IN_NR 0x10
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_N_SOURCE_SELECT 0x18
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_AIS_ENABLE 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_LOS_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_MA_RX 0x01
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_FAS_SOURCE_SELECT 0x01
+
+/* E3_TX_LAPD_CONFIGURATION */
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_AUTO_RETRANSMIT 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_MESSAGE_LENGTH 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_ENABLE 0x01
+
+/* E3_TX_LAPD_STATUS_INTERRUPT */
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_START 0x08
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_DL_BUSY 0x04
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_ENABLE 0x02
+#define SBE_2T3E3_FRAMER_VAL_E3_TX_LAPD_INTERRUPT_STATUS 0x01
+
+
+
+
+
+
+/**************************************************************
+ * LIU
+ **************************************************************/
+
+/* reg_map indexes */
+#define SBE_2T3E3_LIU_REG_REG0 0
+#define SBE_2T3E3_LIU_REG_REG1 1
+#define SBE_2T3E3_LIU_REG_REG2 2
+#define SBE_2T3E3_LIU_REG_REG3 3
+#define SBE_2T3E3_LIU_REG_REG4 4
+
+#define SBE_2T3E3_LIU_REG_MAX 5
+
+/**********/
+
+/* REG0 */
+#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_LOCK_STATUS 0x10
+#define SBE_2T3E3_LIU_VAL_RECEIVE_LOSS_OF_SIGNAL_STATUS 0x08
+#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_STATUS 0x04
+#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_STATUS 0x02
+#define SBE_2T3E3_LIU_VAL_DMO_STATUS 0x01
+
+/* REG1 */
+#define SBE_2T3E3_LIU_VAL_TRANSMITTER_OFF 0x10
+#define SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES 0x08
+#define SBE_2T3E3_LIU_VAL_TRANSMIT_CLOCK_INVERT 0x04
+#define SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT 0x02
+#define SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA 0x01
+
+/* REG2 */
+#define SBE_2T3E3_LIU_VAL_DECODER_DISABLE 0x10
+#define SBE_2T3E3_LIU_VAL_ENCODER_DISABLE 0x08
+#define SBE_2T3E3_LIU_VAL_ANALOG_LOSS_OF_SIGNAL_DISABLE 0x04
+#define SBE_2T3E3_LIU_VAL_DIGITAL_LOSS_OF_SIGNAL_DISABLE 0x02
+#define SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE 0x01
+
+/* REG3 */
+#define SBE_2T3E3_LIU_VAL_RECEIVE_BINARY_DATA 0x10
+#define SBE_2T3E3_LIU_VAL_RECOVERED_DATA_MUTING 0x08
+#define SBE_2T3E3_LIU_VAL_RECEIVE_CLOCK_OUTPUT_2 0x04
+#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_2 0x02
+#define SBE_2T3E3_LIU_VAL_INVERT_RECEIVE_CLOCK_1 0x01
+
+/* REG4 */
+#define SBE_2T3E3_LIU_VAL_T3_MODE_SELECT 0x00
+#define SBE_2T3E3_LIU_VAL_E3_MODE_SELECT 0x04
+#define SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK 0x02
+#define SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK 0x01
+#define SBE_2T3E3_LIU_VAL_LOOPBACK_OFF 0x00
+#define SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE 0x01
+#define SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG 0x02
+#define SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL 0x03
+
+/**********************************************************************
+ *
+ * descriptor list and data buffer
+ *
+ **********************************************************************/
+typedef struct {
+ u32 rdes0;
+ u32 rdes1;
+ u32 rdes2;
+ u32 rdes3;
+} t3e3_rx_desc_t;
+
+#define SBE_2T3E3_RX_DESC_RING_SIZE 64
+
+/* RDES0 */
+#define SBE_2T3E3_RX_DESC_21143_OWN 0X80000000
+#define SBE_2T3E3_RX_DESC_FRAME_LENGTH 0x3fff0000
+#define SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT 16
+#define SBE_2T3E3_RX_DESC_ERROR_SUMMARY 0x00008000
+#define SBE_2T3E3_RX_DESC_DESC_ERROR 0x00004000
+#define SBE_2T3E3_RX_DESC_DATA_TYPE 0x00003000
+#define SBE_2T3E3_RX_DESC_RUNT_FRAME 0x00000800
+#define SBE_2T3E3_RX_DESC_FIRST_DESC 0x00000200
+#define SBE_2T3E3_RX_DESC_LAST_DESC 0x00000100
+#define SBE_2T3E3_RX_DESC_FRAME_TOO_LONG 0x00000080
+#define SBE_2T3E3_RX_DESC_COLLISION_SEEN 0x00000040
+#define SBE_2T3E3_RX_DESC_FRAME_TYPE 0x00000020
+#define SBE_2T3E3_RX_DESC_RECEIVE_WATCHDOG 0x00000010
+#define SBE_2T3E3_RX_DESC_MII_ERROR 0x00000008
+#define SBE_2T3E3_RX_DESC_DRIBBLING_BIT 0x00000004
+#define SBE_2T3E3_RX_DESC_CRC_ERROR 0x00000002
+
+/* RDES1 */
+#define SBE_2T3E3_RX_DESC_END_OF_RING 0x02000000
+#define SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
+#define SBE_2T3E3_RX_DESC_BUFFER_2_SIZE 0x003ff800
+#define SBE_2T3E3_RX_DESC_BUFFER_1_SIZE 0x000007ff
+
+/*********************/
+
+typedef struct {
+ u32 tdes0;
+ u32 tdes1;
+ u32 tdes2;
+ u32 tdes3;
+} t3e3_tx_desc_t;
+
+#define SBE_2T3E3_TX_DESC_RING_SIZE 256
+
+/* TDES0 */
+#define SBE_2T3E3_TX_DESC_21143_OWN 0x80000000
+#define SBE_2T3E3_TX_DESC_ERROR_SUMMARY 0x00008000
+#define SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT 0x00004000
+#define SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER 0x00000800
+#define SBE_2T3E3_TX_DESC_NO_CARRIER 0x00000400
+#define SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT 0x00000004
+#define SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR 0x00000002
+#define SBE_2T3E3_TX_DESC_DEFFERED 0x00000001
+
+/* TDES1 */
+#define SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION 0x80000000
+#define SBE_2T3E3_TX_DESC_LAST_SEGMENT 0x40000000
+#define SBE_2T3E3_TX_DESC_FIRST_SEGMENT 0x20000000
+#define SBE_2T3E3_TX_DESC_CRC_DISABLE 0x04000000
+#define SBE_2T3E3_TX_DESC_END_OF_RING 0x02000000
+#define SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED 0x01000000
+#define SBE_2T3E3_TX_DESC_DISABLE_PADDING 0x00800000
+#define SBE_2T3E3_TX_DESC_BUFFER_2_SIZE 0x003ff800
+#define SBE_2T3E3_TX_DESC_BUFFER_1_SIZE 0x000007ff
+
+
+#define SBE_2T3E3_MTU 1600
+#define SBE_2T3E3_CRC16_LENGTH 2
+#define SBE_2T3E3_CRC32_LENGTH 4
+
+#define MCLBYTES (SBE_2T3E3_MTU + 128)
+
+struct channel {
+ struct pci_dev *pdev;
+ struct net_device *dev;
+ struct card *card;
+ unsigned long addr; /* DECchip */
+
+ int leds;
+
+ /* pci specific */
+ struct {
+ u32 slot; /* should be 0 or 1 */
+ u32 command;
+ u8 cache_size;
+ } h;
+
+ /* statistics */
+ t3e3_stats_t s;
+
+ /* running */
+ struct {
+ u32 flags;
+ } r;
+
+ /* parameters */
+ t3e3_param_t p;
+
+ u32 liu_regs[SBE_2T3E3_LIU_REG_MAX]; /* LIU registers */
+ u32 framer_regs[SBE_2T3E3_FRAMER_REG_MAX]; /* Framer registers */
+
+ /* Ethernet Controller */
+ struct {
+ u_int16_t card_serial_number[3];
+
+ u32 reg[SBE_2T3E3_21143_REG_MAX]; /* registers i.e. CSR */
+
+ u32 interrupt_enable_mask;
+
+ /* receive chain/ring */
+ t3e3_rx_desc_t *rx_ring;
+ struct sk_buff *rx_data[SBE_2T3E3_RX_DESC_RING_SIZE];
+ u32 rx_ring_current_read;
+
+ /* transmit chain/ring */
+ t3e3_tx_desc_t *tx_ring;
+ struct sk_buff *tx_data[SBE_2T3E3_TX_DESC_RING_SIZE];
+ u32 tx_ring_current_read;
+ u32 tx_ring_current_write;
+ int tx_full;
+ int tx_free_cnt;
+ spinlock_t tx_lock;
+ } ether;
+
+ int32_t interrupt_active;
+ int32_t rcv_count;
+};
+
+struct card {
+ spinlock_t bootrom_lock;
+ unsigned long bootrom_addr;
+ struct timer_list timer; /* for updating LEDs */
+ struct channel channels[0];
+};
+
+#define SBE_2T3E3_FLAG_NETWORK_UP 0x00000001
+#define SBE_2T3E3_FLAG_NO_ERROR_MESSAGES 0x00000002
+
+extern const u32 cpld_reg_map[][2];
+extern const u32 cpld_val_map[][2];
+extern const u32 t3e3_framer_reg_map[];
+extern const u32 t3e3_liu_reg_map[];
+
+void t3e3_init(struct channel *);
+void t3e3_if_up(struct channel *);
+void t3e3_if_down(struct channel *);
+int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev);
+void t3e3_if_config(struct channel *, u32, char *,
+ t3e3_resp_t *, int *);
+void t3e3_set_frame_type(struct channel *, u32);
+u32 t3e3_eeprom_read_word(struct channel *, u32);
+void t3e3_read_card_serial_number(struct channel *);
+
+/* interrupt handlers */
+irqreturn_t t3e3_intr(int irq, void *dev_instance);
+void dc_intr(struct channel *);
+void dc_intr_rx(struct channel *);
+void dc_intr_tx(struct channel *);
+void dc_intr_tx_underflow(struct channel *);
+void exar7250_intr(struct channel *);
+void exar7250_E3_intr(struct channel *, u32);
+void exar7250_T3_intr(struct channel *, u32);
+
+/* Ethernet controller */
+u32 bootrom_read(struct channel *, u32);
+void bootrom_write(struct channel *, u32, u32);
+void dc_init(struct channel *);
+void dc_start(struct channel *);
+void dc_stop(struct channel *);
+void dc_start_intr(struct channel *);
+void dc_stop_intr(struct channel *);
+void dc_reset(struct channel *);
+void dc_restart(struct channel *);
+void dc_receiver_onoff(struct channel *, u32);
+void dc_transmitter_onoff(struct channel *, u32);
+void dc_set_loopback(struct channel *, u32);
+u32 dc_init_descriptor_list(struct channel *);
+void dc_clear_descriptor_list(struct channel *);
+void dc_drop_descriptor_list(struct channel *);
+void dc_set_output_port(struct channel *);
+void t3e3_sc_init(struct channel *);
+
+/* CPLD */
+void cpld_init(struct channel *sc);
+u32 cpld_read(struct channel *sc, u32 reg);
+void cpld_set_crc(struct channel *, u32);
+void cpld_start_intr(struct channel *);
+void cpld_stop_intr(struct channel *);
+#if 0
+void cpld_led_onoff(struct channel *, u32, u32, u32, u32);
+#endif
+void cpld_set_clock(struct channel *sc, u32 mode);
+void cpld_set_scrambler(struct channel *, u32);
+void cpld_select_panel(struct channel *, u32);
+void cpld_set_frame_mode(struct channel *, u32);
+void cpld_set_frame_type(struct channel *, u32);
+void cpld_set_pad_count(struct channel *, u32);
+void cpld_set_fractional_mode(struct channel *, u32, u32, u32);
+void cpld_LOS_update(struct channel *);
+
+/* Framer */
+extern u32 exar7250_read(struct channel *, u32);
+extern void exar7250_write(struct channel *, u32, u32);
+void exar7250_init(struct channel *);
+void exar7250_start_intr(struct channel *, u32);
+void exar7250_stop_intr(struct channel *, u32);
+void exar7250_set_frame_type(struct channel *, u32);
+void exar7250_set_loopback(struct channel *, u32);
+void exar7250_unipolar_onoff(struct channel *, u32);
+
+/* LIU */
+u32 exar7300_read(struct channel *, u32);
+void exar7300_write(struct channel *, u32, u32);
+void exar7300_init(struct channel *);
+void exar7300_line_build_out_onoff(struct channel *, u32);
+void exar7300_set_frame_type(struct channel *, u32);
+void exar7300_set_loopback(struct channel *, u32);
+void exar7300_transmit_all_ones_onoff(struct channel *, u32);
+void exar7300_receive_equalization_onoff(struct channel *, u32);
+void exar7300_unipolar_onoff(struct channel *, u32);
+
+void update_led(struct channel *, int);
+int setup_device(struct net_device *dev, struct channel *sc);
+
+static inline int has_two_ports(struct pci_dev *pdev)
+{
+ return pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0;
+}
+
+#define dev_to_priv(dev) (*(struct channel **) ((hdlc_device*)(dev) + 1))
+
+static inline u32 dc_read(unsigned long addr, u32 reg)
+{
+ return inl(addr + (reg << 3));
+}
+
+static inline void dc_write(unsigned long addr, u32 reg, u32 val)
+{
+ outl(val, addr + (reg << 3));
+}
+
+static inline void dc_set_bits(unsigned long addr, u32 reg, u32 bits)
+{
+ dc_write(addr, reg, dc_read(addr, reg) | bits);
+}
+
+static inline void dc_clear_bits(unsigned long addr, u32 reg, u32 bits)
+{
+ dc_write(addr, reg, dc_read(addr, reg) & ~bits);
+}
+
+#define CPLD_MAP_REG(reg, sc) (cpld_reg_map[(reg)][(sc)->h.slot])
+
+static inline void cpld_write(struct channel *channel, unsigned reg, u32 val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+ bootrom_write(channel, CPLD_MAP_REG(reg, channel), val);
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+}
+
+#define exar7250_set_bit(sc, reg, bit) \
+ exar7250_write((sc), (reg), \
+ exar7250_read(sc, reg) | (bit))
+
+#define exar7250_clear_bit(sc, reg, bit) \
+ exar7250_write((sc), (reg), \
+ exar7250_read(sc, reg) & ~(bit))
+
+#define exar7300_set_bit(sc, reg, bit) \
+ exar7300_write((sc), (reg), \
+ exar7300_read(sc, reg) | (bit))
+
+#define exar7300_clear_bit(sc, reg, bit) \
+ exar7300_write((sc), (reg), \
+ exar7300_read(sc, reg) & ~(bit))
+
+
+#endif /* T3E3_H */
diff --git a/drivers/staging/sbe-2t3e3/Kconfig b/drivers/staging/sbe-2t3e3/Kconfig
new file mode 100644
index 000000000000..8ec86cfc6bf8
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/Kconfig
@@ -0,0 +1,13 @@
+config SBE_2T3E3
+ tristate "SBE wanPMC-2T3E3 support"
+ depends on HDLC && PCI
+ help
+ Driver for wanPMC-2T3E3 cards by SBE Inc.
+
+ If you have such a card, say Y here and see
+ <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
+
+ To compile this as a module, choose M here: the
+ module will be called sbe-2t3e3.
+
+ If unsure, say N.
diff --git a/drivers/staging/sbe-2t3e3/Makefile b/drivers/staging/sbe-2t3e3/Makefile
new file mode 100644
index 000000000000..2c7b0978b478
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3.o
+
+sbe-2t3e3-objs := module.o netdev.o maps.o \
+ main.o cpld.o intr.o ctrl.o io.o dc.o exar7250.o exar7300.o
diff --git a/drivers/staging/sbe-2t3e3/TODO b/drivers/staging/sbe-2t3e3/TODO
new file mode 100644
index 000000000000..624b20f70cf8
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/TODO
@@ -0,0 +1,6 @@
+TODO:
+ - additional cleaning and tests
+ - wait for the new configuration interface in generic HDLC layer and
+ when available, convert the driver to it
+
+Please send patches to Krzysztof Halasa <khc@pm.waw.pl>. \ No newline at end of file
diff --git a/drivers/staging/sbe-2t3e3/cpld.c b/drivers/staging/sbe-2t3e3/cpld.c
new file mode 100644
index 000000000000..b0fc2ddad329
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/cpld.c
@@ -0,0 +1,366 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/delay.h>
+#include "2t3e3.h"
+#include "ctrl.h"
+
+#define bootrom_set_bit(sc, reg, bit) \
+ bootrom_write((sc), (reg), \
+ bootrom_read((sc), (reg)) | (bit))
+
+#define bootrom_clear_bit(sc, reg, bit) \
+ bootrom_write((sc), (reg), \
+ bootrom_read((sc), (reg)) & ~(bit))
+
+static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+ bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+}
+
+static inline void cpld_clear_bit(struct channel *channel, unsigned reg, u32 bit)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+ bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+}
+
+void cpld_init(struct channel *sc)
+{
+ u32 val;
+#if 0
+ /* reset LIU and Framer */
+ val = cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_FRAMER_RESET][sc->h.slot];
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val);
+ udelay(10000); /* TODO - how long? */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_STATIC_RESET, val);
+#endif
+
+ /* PCRA */
+ val = SBE_2T3E3_CPLD_VAL_CRC32 |
+ cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
+
+ /* PCRB */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
+
+ /* PCRC */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
+
+ /* PBWF */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
+
+ /* PBWL */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
+
+ /* PLTR */
+ val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
+ udelay(1000);
+
+ /* PLCR */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
+ udelay(1000);
+
+ /* PPFR */
+ val = 0x55;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
+ /* TODO: this doesn't work!!! */
+
+ /* SERIAL_CHIP_SELECT */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
+
+ /* PICSR */
+ val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
+ SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
+ SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
+
+ cpld_start_intr(sc);
+
+ udelay(1000);
+}
+
+void cpld_start_intr(struct channel *sc)
+{
+ u32 val;
+
+ /* PIER */
+ val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
+ SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
+#if 0
+ /*
+ do you want to hang up your computer?
+ ENABLE REST OF INTERRUPTS !!!
+ you have been warned :).
+ */
+#endif
+}
+
+void cpld_stop_intr(struct channel *sc)
+{
+ u32 val;
+
+ /* PIER */
+ val = 0;
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
+}
+
+void cpld_set_frame_mode(struct channel *sc, u32 mode)
+{
+ if (sc->p.frame_mode == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_FRAME_MODE_HDLC:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
+ SBE_2T3E3_CPLD_VAL_RAW_MODE);
+ exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
+ exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
+ break;
+ case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_RAW_MODE);
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
+ exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
+ exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
+ break;
+ case SBE_2T3E3_FRAME_MODE_RAW:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_RAW_MODE);
+ exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
+ exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.frame_mode = mode;
+}
+
+/* set rate of the local clock */
+void cpld_set_frame_type(struct channel *sc, u32 type)
+{
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
+ break;
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
+ break;
+ default:
+ return;
+ }
+}
+
+void cpld_set_scrambler(struct channel *sc, u32 mode)
+{
+ if (sc->p.scrambler == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_SCRAMBLER_OFF:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
+ break;
+ case SBE_2T3E3_SCRAMBLER_LARSCOM:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
+ break;
+ case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.scrambler = mode;
+}
+
+
+void cpld_set_crc(struct channel *sc, u32 crc)
+{
+ if (sc->p.crc == crc)
+ return;
+
+ switch (crc) {
+ case SBE_2T3E3_CRC_16:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_CRC32);
+ break;
+ case SBE_2T3E3_CRC_32:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_CRC32);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.crc = crc;
+}
+
+
+void cpld_select_panel(struct channel *sc, u32 panel)
+{
+ if (sc->p.panel == panel)
+ return;
+ switch (panel) {
+ case SBE_2T3E3_PANEL_FRONT:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_REAR_PANEL);
+ break;
+ case SBE_2T3E3_PANEL_REAR:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_REAR_PANEL);
+ break;
+ default:
+ return;
+ }
+
+ udelay(100);
+
+ sc->p.panel = panel;
+}
+
+
+extern void cpld_set_clock(struct channel *sc, u32 mode)
+{
+ if (sc->p.clock_source == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_TIMING_LOCAL:
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_ALT);
+ break;
+ case SBE_2T3E3_TIMING_LOOP:
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
+ SBE_2T3E3_CPLD_VAL_ALT);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.clock_source = mode;
+}
+
+void cpld_set_pad_count(struct channel *sc, u32 count)
+{
+ u32 val;
+
+ if (sc->p.pad_count == count)
+ return;
+
+ switch (count) {
+ case SBE_2T3E3_PAD_COUNT_1:
+ val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
+ break;
+ case SBE_2T3E3_PAD_COUNT_2:
+ val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
+ break;
+ case SBE_2T3E3_PAD_COUNT_3:
+ val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
+ break;
+ case SBE_2T3E3_PAD_COUNT_4:
+ val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
+ break;
+ default:
+ return;
+ }
+
+ cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
+ SBE_2T3E3_CPLD_VAL_PAD_COUNT);
+ cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
+ sc->p.pad_count = count;
+}
+
+void cpld_LOS_update(struct channel *sc)
+{
+ u_int8_t los;
+
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
+ SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
+ SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
+ SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
+ los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
+ SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
+
+ if (los != sc->s.LOS)
+ dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
+ los ? "Loss of signal" : "Signal OK");
+ sc->s.LOS = los;
+}
+
+void cpld_set_fractional_mode(struct channel *sc, u32 mode,
+ u32 start, u32 stop)
+{
+ if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
+ start = 0;
+ stop = 0;
+ }
+
+ if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
+ sc->p.bandwidth_stop == stop)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_FRACTIONAL_MODE_NONE:
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
+ SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
+ break;
+ case SBE_2T3E3_FRACTIONAL_MODE_0:
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
+ SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
+ break;
+ case SBE_2T3E3_FRACTIONAL_MODE_1:
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
+ SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
+ break;
+ case SBE_2T3E3_FRACTIONAL_MODE_2:
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
+ SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
+ break;
+ default:
+ printk(KERN_ERR "wrong mode in set_fractional_mode\n");
+ return;
+ }
+
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
+
+ sc->p.fractional_mode = mode;
+ sc->p.bandwidth_start = start;
+ sc->p.bandwidth_stop = stop;
+}
diff --git a/drivers/staging/sbe-2t3e3/ctrl.c b/drivers/staging/sbe-2t3e3/ctrl.c
new file mode 100644
index 000000000000..d9dd216e9ae0
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/ctrl.c
@@ -0,0 +1,362 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/types.h>
+#include "2t3e3.h"
+#include "ctrl.h"
+
+void t3e3_set_frame_type(struct channel *sc, u32 mode)
+{
+ if (sc->p.frame_type == mode)
+ return;
+
+ if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: changing frame type during active connection\n");
+ return;
+ }
+
+ exar7300_set_frame_type(sc, mode);
+ exar7250_set_frame_type(sc, mode);
+ cpld_set_frame_type(sc, mode);
+
+ sc->p.frame_type = mode;
+}
+
+void t3e3_set_loopback(struct channel *sc, u32 mode)
+{
+ u32 tx, rx;
+
+ if (sc->p.loopback == mode)
+ return;
+
+ tx = sc->p.transmitter_on;
+ rx = sc->p.receiver_on;
+ if (tx == SBE_2T3E3_ON)
+ dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
+ if (rx == SBE_2T3E3_ON)
+ dc_receiver_onoff(sc, SBE_2T3E3_OFF);
+
+ /* stop current loopback if any exists */
+ switch (sc->p.loopback) {
+ case SBE_2T3E3_LOOPBACK_NONE:
+ break;
+ case SBE_2T3E3_LOOPBACK_ETHERNET:
+ dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_OFF);
+ break;
+ case SBE_2T3E3_LOOPBACK_FRAMER:
+ exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF);
+ break;
+ case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
+ case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
+ case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
+ exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
+ break;
+ default:
+ return;
+ }
+
+ switch (mode) {
+ case SBE_2T3E3_LOOPBACK_NONE:
+ break;
+ case SBE_2T3E3_LOOPBACK_ETHERNET:
+ dc_set_loopback(sc, SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL);
+ break;
+ case SBE_2T3E3_LOOPBACK_FRAMER:
+ exar7250_set_loopback(sc, SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON);
+ break;
+ case SBE_2T3E3_LOOPBACK_LIU_DIGITAL:
+ exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL);
+ break;
+ case SBE_2T3E3_LOOPBACK_LIU_ANALOG:
+ exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG);
+ break;
+ case SBE_2T3E3_LOOPBACK_LIU_REMOTE:
+ exar7300_set_loopback(sc, SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.loopback = mode;
+
+ if (tx == SBE_2T3E3_ON)
+ dc_transmitter_onoff(sc, SBE_2T3E3_ON);
+ if (rx == SBE_2T3E3_ON)
+ dc_receiver_onoff(sc, SBE_2T3E3_ON);
+}
+
+
+void t3e3_reg_read(struct channel *sc, u32 *reg, u32 *val)
+{
+ u32 i;
+
+ *val = 0;
+
+ switch (reg[0]) {
+ case SBE_2T3E3_CHIP_21143:
+ if (!(reg[1] & 7))
+ *val = dc_read(sc->addr, reg[1] / 8);
+ break;
+ case SBE_2T3E3_CHIP_CPLD:
+ for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
+ if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
+ *val = cpld_read(sc, i);
+ break;
+ }
+ break;
+ case SBE_2T3E3_CHIP_FRAMER:
+ for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
+ if (t3e3_framer_reg_map[i] == reg[1]) {
+ *val = exar7250_read(sc, i);
+ break;
+ }
+ break;
+ case SBE_2T3E3_CHIP_LIU:
+ for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
+ if (t3e3_liu_reg_map[i] == reg[1]) {
+ *val = exar7300_read(sc, i);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void t3e3_reg_write(struct channel *sc, u32 *reg)
+{
+ u32 i;
+
+ switch (reg[0]) {
+ case SBE_2T3E3_CHIP_21143:
+ dc_write(sc->addr, reg[1], reg[2]);
+ break;
+ case SBE_2T3E3_CHIP_CPLD:
+ for (i = 0; i < SBE_2T3E3_CPLD_REG_MAX; i++)
+ if (cpld_reg_map[i][sc->h.slot] == reg[1]) {
+ cpld_write(sc, i, reg[2]);
+ break;
+ }
+ break;
+ case SBE_2T3E3_CHIP_FRAMER:
+ for (i = 0; i < SBE_2T3E3_FRAMER_REG_MAX; i++)
+ if (t3e3_framer_reg_map[i] == reg[1]) {
+ exar7250_write(sc, i, reg[2]);
+ break;
+ }
+ break;
+ case SBE_2T3E3_CHIP_LIU:
+ for (i = 0; i < SBE_2T3E3_LIU_REG_MAX; i++)
+ if (t3e3_liu_reg_map[i] == reg[1]) {
+ exar7300_write(sc, i, reg[2]);
+ break;
+ }
+ break;
+ }
+}
+
+void t3e3_port_get(struct channel *sc, t3e3_param_t *param)
+{
+ memcpy(param, &(sc->p), sizeof(t3e3_param_t));
+}
+
+void t3e3_port_set(struct channel *sc, t3e3_param_t *param)
+{
+ if (param->frame_mode != 0xff)
+ cpld_set_frame_mode(sc, param->frame_mode);
+
+ if (param->fractional_mode != 0xff)
+ cpld_set_fractional_mode(sc, param->fractional_mode,
+ param->bandwidth_start,
+ param->bandwidth_stop);
+
+ if (param->pad_count != 0xff)
+ cpld_set_pad_count(sc, param->pad_count);
+
+ if (param->crc != 0xff)
+ cpld_set_crc(sc, param->crc);
+
+ if (param->receiver_on != 0xff)
+ dc_receiver_onoff(sc, param->receiver_on);
+
+ if (param->transmitter_on != 0xff)
+ dc_transmitter_onoff(sc, param->transmitter_on);
+
+ if (param->frame_type != 0xff)
+ t3e3_set_frame_type(sc, param->frame_type);
+
+ if (param->panel != 0xff)
+ cpld_select_panel(sc, param->panel);
+
+ if (param->line_build_out != 0xff)
+ exar7300_line_build_out_onoff(sc, param->line_build_out);
+
+ if (param->receive_equalization != 0xff)
+ exar7300_receive_equalization_onoff(sc, param->receive_equalization);
+
+ if (param->transmit_all_ones != 0xff)
+ exar7300_transmit_all_ones_onoff(sc, param->transmit_all_ones);
+
+ if (param->loopback != 0xff)
+ t3e3_set_loopback(sc, param->loopback);
+
+ if (param->clock_source != 0xff)
+ cpld_set_clock(sc, param->clock_source);
+
+ if (param->scrambler != 0xff)
+ cpld_set_scrambler(sc, param->scrambler);
+}
+
+void t3e3_port_get_stats(struct channel *sc,
+ t3e3_stats_t *stats)
+{
+ u32 result;
+
+ sc->s.LOC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL)
+ & SBE_2T3E3_FRAMER_VAL_LOSS_OF_CLOCK_STATUS ? 1 : 0;
+
+ switch (sc->p.frame_type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
+ sc->s.LOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOF ? 1 : 0;
+ sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
+#if 0
+ sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
+#else
+ cpld_LOS_update(sc);
+#endif
+ sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_AIS ? 1 : 0;
+ sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_FERF ? 1 : 0;
+ break;
+
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
+ sc->s.AIS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIS ? 1 : 0;
+#if 0
+ sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
+#else
+ cpld_LOS_update(sc);
+#endif
+ sc->s.IDLE = result & SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE ? 1 : 0;
+ sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_STATUS);
+ sc->s.FERF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FERF ? 1 : 0;
+ sc->s.AIC = result & SBE_2T3E3_FRAMER_VAL_T3_RX_AIC ? 1 : 0;
+ sc->s.FEBE_code = result & SBE_2T3E3_FRAMER_VAL_T3_RX_FEBE;
+
+ sc->s.FEAC = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC);
+ break;
+
+ default:
+ break;
+ }
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_LCV_EVENT_COUNT_MSB) << 8;
+ result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
+ sc->s.LCV += result;
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB) << 8;
+ result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
+ sc->s.FRAMING_BIT += result;
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_PARITY_ERROR_EVENT_COUNT_MSB) << 8;
+ result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
+ sc->s.PARITY_ERROR += result;
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_FEBE_EVENT_COUNT_MSB) << 8;
+ result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
+ sc->s.FEBE_count += result;
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_CP_BIT_ERROR_EVENT_COUNT_MSB) << 8;
+ result += exar7250_read(sc, SBE_2T3E3_FRAMER_REG_PMON_HOLDING_REGISTER);
+ sc->s.CP_BIT += result;
+
+ memcpy(stats, &(sc->s), sizeof(t3e3_stats_t));
+}
+
+void t3e3_port_del_stats(struct channel *sc)
+{
+ memset(&(sc->s), 0, sizeof(t3e3_stats_t));
+}
+
+void t3e3_if_config(struct channel *sc, u32 cmd, char *set,
+ t3e3_resp_t *ret, int *rlen)
+{
+ t3e3_param_t *param = (t3e3_param_t *)set;
+ u32 *data = (u32 *)set;
+
+ /* turn off all interrupt */
+ /* cpld_stop_intr(sc); */
+
+ switch (cmd) {
+ case SBE_2T3E3_PORT_GET:
+ t3e3_port_get(sc, &(ret->u.param));
+ *rlen = sizeof(ret->u.param);
+ break;
+ case SBE_2T3E3_PORT_SET:
+ t3e3_port_set(sc, param);
+ *rlen = 0;
+ break;
+ case SBE_2T3E3_PORT_GET_STATS:
+ t3e3_port_get_stats(sc, &(ret->u.stats));
+ *rlen = sizeof(ret->u.stats);
+ break;
+ case SBE_2T3E3_PORT_DEL_STATS:
+ t3e3_port_del_stats(sc);
+ *rlen = 0;
+ break;
+ case SBE_2T3E3_PORT_READ_REGS:
+ t3e3_reg_read(sc, data, &(ret->u.data));
+ *rlen = sizeof(ret->u.data);
+ break;
+ case SBE_2T3E3_PORT_WRITE_REGS:
+#if 0
+ printk(KERN_DEBUG "SBE_2T3E3_PORT_WRITE_REGS, 0x%x, 0x%x, 0x%x\n",
+ ((int*)data)[0], ((int*)data)[1], ((int*)data)[2]);
+#endif
+ t3e3_reg_write(sc, data);
+ *rlen = 0;
+ break;
+ case SBE_2T3E3_LOG_LEVEL:
+ *rlen = 0;
+ break;
+ default:
+ *rlen = 0;
+ break;
+ }
+
+ /* turn on interrupt */
+ /* cpld_start_intr(sc); */
+}
+
+void t3e3_sc_init(struct channel *sc)
+{
+ memset(sc, 0, sizeof(*sc));
+
+ sc->p.frame_mode = SBE_2T3E3_FRAME_MODE_HDLC;
+ sc->p.fractional_mode = SBE_2T3E3_FRACTIONAL_MODE_NONE;
+ sc->p.crc = SBE_2T3E3_CRC_32;
+ sc->p.receiver_on = SBE_2T3E3_OFF;
+ sc->p.transmitter_on = SBE_2T3E3_OFF;
+ sc->p.frame_type = SBE_2T3E3_FRAME_TYPE_T3_CBIT;
+ sc->p.panel = SBE_2T3E3_PANEL_FRONT;
+ sc->p.line_build_out = SBE_2T3E3_OFF;
+ sc->p.receive_equalization = SBE_2T3E3_OFF;
+ sc->p.transmit_all_ones = SBE_2T3E3_OFF;
+ sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
+ sc->p.clock_source = SBE_2T3E3_TIMING_LOCAL;
+ sc->p.scrambler = SBE_2T3E3_SCRAMBLER_OFF;
+ sc->p.pad_count = SBE_2T3E3_PAD_COUNT_1;
+}
diff --git a/drivers/staging/sbe-2t3e3/ctrl.h b/drivers/staging/sbe-2t3e3/ctrl.h
new file mode 100644
index 000000000000..c11a58871845
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/ctrl.h
@@ -0,0 +1,131 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#ifndef CTRL_H
+#define CTRL_H
+
+#define SBE_2T3E3_OFF 0
+#define SBE_2T3E3_ON 1
+
+#define SBE_2T3E3_LED_NONE 0
+#define SBE_2T3E3_LED_GREEN 1
+#define SBE_2T3E3_LED_YELLOW 2
+
+#define SBE_2T3E3_CABLE_LENGTH_LESS_THAN_255_FEET 0
+#define SBE_2T3E3_CABLE_LENGTH_GREATER_THAN_255_FEET 1
+
+#define SBE_2T3E3_CRC_16 0
+#define SBE_2T3E3_CRC_32 1
+
+#define SBE_2T3E3_PANEL_FRONT 0
+#define SBE_2T3E3_PANEL_REAR 1
+
+#define SBE_2T3E3_FRAME_MODE_HDLC 0
+#define SBE_2T3E3_FRAME_MODE_TRANSPARENT 1
+#define SBE_2T3E3_FRAME_MODE_RAW 2
+
+#define SBE_2T3E3_FRAME_TYPE_E3_G751 0
+#define SBE_2T3E3_FRAME_TYPE_E3_G832 1
+#define SBE_2T3E3_FRAME_TYPE_T3_CBIT 2
+#define SBE_2T3E3_FRAME_TYPE_T3_M13 3
+
+#define SBE_2T3E3_FRACTIONAL_MODE_NONE 0
+#define SBE_2T3E3_FRACTIONAL_MODE_0 1
+#define SBE_2T3E3_FRACTIONAL_MODE_1 2
+#define SBE_2T3E3_FRACTIONAL_MODE_2 3
+
+#define SBE_2T3E3_SCRAMBLER_OFF 0
+#define SBE_2T3E3_SCRAMBLER_LARSCOM 1
+#define SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL 2
+
+#define SBE_2T3E3_TIMING_LOCAL 0
+#define SBE_2T3E3_TIMING_LOOP 1
+
+#define SBE_2T3E3_LOOPBACK_NONE 0
+#define SBE_2T3E3_LOOPBACK_ETHERNET 1
+#define SBE_2T3E3_LOOPBACK_FRAMER 2
+#define SBE_2T3E3_LOOPBACK_LIU_DIGITAL 3
+#define SBE_2T3E3_LOOPBACK_LIU_ANALOG 4
+#define SBE_2T3E3_LOOPBACK_LIU_REMOTE 5
+
+#define SBE_2T3E3_PAD_COUNT_1 1
+#define SBE_2T3E3_PAD_COUNT_2 2
+#define SBE_2T3E3_PAD_COUNT_3 3
+#define SBE_2T3E3_PAD_COUNT_4 4
+
+#define SBE_2T3E3_CHIP_21143 0
+#define SBE_2T3E3_CHIP_CPLD 1
+#define SBE_2T3E3_CHIP_FRAMER 2
+#define SBE_2T3E3_CHIP_LIU 3
+
+#define SBE_2T3E3_LOG_LEVEL_NONE 0
+#define SBE_2T3E3_LOG_LEVEL_ERROR 1
+#define SBE_2T3E3_LOG_LEVEL_WARNING 2
+#define SBE_2T3E3_LOG_LEVEL_INFO 3
+
+/* commands */
+#define SBE_2T3E3_PORT_GET 0
+#define SBE_2T3E3_PORT_SET 1
+#define SBE_2T3E3_PORT_GET_STATS 2
+#define SBE_2T3E3_PORT_DEL_STATS 3
+#define SBE_2T3E3_PORT_READ_REGS 4
+#define SBE_2T3E3_LOG_LEVEL 5
+#define SBE_2T3E3_PORT_WRITE_REGS 6
+
+#define NG_SBE_2T3E3_NODE_TYPE "sbe2T3E3"
+#define NG_SBE_2T3E3_COOKIE 0x03800891
+
+typedef struct t3e3_param {
+ u_int8_t frame_mode; /* FRAME_MODE_* */
+ u_int8_t crc; /* CRC_* */
+ u_int8_t receiver_on; /* ON/OFF */
+ u_int8_t transmitter_on; /* ON/OFF */
+ u_int8_t frame_type; /* FRAME_TYPE_* */
+ u_int8_t panel; /* PANEL_* */
+ u_int8_t line_build_out; /* ON/OFF */
+ u_int8_t receive_equalization; /* ON/OFF */
+ u_int8_t transmit_all_ones; /* ON/OFF */
+ u_int8_t loopback; /* LOOPBACK_* */
+ u_int8_t clock_source; /* TIMING_* */
+ u_int8_t scrambler; /* SCRAMBLER_* */
+ u_int8_t pad_count; /* PAD_COUNT_* */
+ u_int8_t log_level; /* LOG_LEVEL_* - unused */
+ u_int8_t fractional_mode; /* FRACTIONAL_MODE_* */
+ u_int8_t bandwidth_start; /* 0-255 */
+ u_int8_t bandwidth_stop; /* 0-255 */
+} t3e3_param_t;
+
+typedef struct t3e3_stats {
+ u_int64_t in_bytes;
+ u32 in_packets, in_dropped;
+ u32 in_errors, in_error_desc, in_error_coll, in_error_drib,
+ in_error_crc, in_error_mii;
+ u_int64_t out_bytes;
+ u32 out_packets, out_dropped;
+ u32 out_errors, out_error_jab, out_error_lost_carr,
+ out_error_no_carr, out_error_link_fail, out_error_underflow,
+ out_error_dereferred;
+ u_int8_t LOC, LOF, OOF, LOS, AIS, FERF, IDLE, AIC, FEAC;
+ u_int16_t FEBE_code;
+ u32 LCV, FRAMING_BIT, PARITY_ERROR, FEBE_count, CP_BIT;
+} t3e3_stats_t;
+
+
+typedef struct t3e3_resp {
+ union {
+ t3e3_param_t param;
+ t3e3_stats_t stats;
+ u32 data;
+ } u;
+} t3e3_resp_t;
+
+#endif /* CTRL_H */
diff --git a/drivers/staging/sbe-2t3e3/dc.c b/drivers/staging/sbe-2t3e3/dc.c
new file mode 100644
index 000000000000..126a9720c6b8
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/dc.c
@@ -0,0 +1,502 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include "2t3e3.h"
+#include "ctrl.h"
+
+void dc_init(struct channel *sc)
+{
+ u32 val;
+
+ dc_stop(sc);
+ /*dc_reset(sc);*/ /* do not want to reset here */
+
+ /*
+ * BUS_MODE (CSR0)
+ */
+ val = SBE_2T3E3_21143_VAL_READ_LINE_ENABLE |
+ SBE_2T3E3_21143_VAL_READ_MULTIPLE_ENABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_AUTOMATIC_POLLING_200us |
+ SBE_2T3E3_21143_VAL_BUS_ARBITRATION_RR;
+
+ if (sc->h.command & 16)
+ val |= SBE_2T3E3_21143_VAL_WRITE_AND_INVALIDATE_ENABLE;
+
+ switch (sc->h.cache_size) {
+ case 32:
+ val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_32;
+ break;
+ case 16:
+ val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_16;
+ break;
+ case 8:
+ val |= SBE_2T3E3_21143_VAL_CACHE_ALIGNMENT_8;
+ break;
+ default:
+ break;
+ }
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, val);
+
+ /* OPERATION_MODE (CSR6) */
+ val = SBE_2T3E3_21143_VAL_RECEIVE_ALL |
+ SBE_2T3E3_21143_VAL_MUST_BE_ONE |
+ SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1 |
+ SBE_2T3E3_21143_VAL_LOOPBACK_OFF |
+ SBE_2T3E3_21143_VAL_PASS_ALL_MULTICAST |
+ SBE_2T3E3_21143_VAL_PROMISCUOUS_MODE |
+ SBE_2T3E3_21143_VAL_PASS_BAD_FRAMES;
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
+ if (sc->p.loopback == SBE_2T3E3_LOOPBACK_ETHERNET)
+ sc->p.loopback = SBE_2T3E3_LOOPBACK_NONE;
+
+#if 0 /* No need to clear this register - and it may be in use */
+ /*
+ * BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT (CSR9)
+ */
+ val = 0;
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, val);
+#endif
+
+ /*
+ * GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL (CSR11)
+ */
+ val = SBE_2T3E3_21143_VAL_CYCLE_SIZE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_TIMER |
+ SBE_2T3E3_21143_VAL_NUMBER_OF_TRANSMIT_PACKETS |
+ SBE_2T3E3_21143_VAL_RECEIVE_TIMER |
+ SBE_2T3E3_21143_VAL_NUMBER_OF_RECEIVE_PACKETS;
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_GENERAL_PURPOSE_TIMER_AND_INTERRUPT_MITIGATION_CONTROL, val);
+
+ /* prepare descriptors and data for receive and transmit procecsses */
+ if (dc_init_descriptor_list(sc) != 0)
+ return;
+
+ /* clear ethernet interrupts status */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
+
+ /* SIA mode registers */
+ dc_set_output_port(sc);
+}
+
+void dc_start(struct channel *sc)
+{
+ u32 val;
+
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP))
+ return;
+
+ dc_init(sc);
+
+ /* get actual LOS and OOF status */
+ switch (sc->p.frame_type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
+ dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
+ sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
+ break;
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
+ dev_dbg(&sc->pdev->dev, "Start Framer Rx Status = %02X\n", val);
+ sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
+ break;
+ default:
+ break;
+ }
+ cpld_LOS_update(sc);
+
+ /* start receive and transmit processes */
+ dc_transmitter_onoff(sc, SBE_2T3E3_ON);
+ dc_receiver_onoff(sc, SBE_2T3E3_ON);
+
+ /* start interrupts */
+ dc_start_intr(sc);
+}
+
+#define MAX_INT_WAIT_CNT 12000
+void dc_stop(struct channel *sc)
+{
+ int wcnt;
+
+ /* stop receive and transmit processes */
+ dc_receiver_onoff(sc, SBE_2T3E3_OFF);
+ dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
+
+ /* turn off ethernet interrupts */
+ dc_stop_intr(sc);
+
+ /* wait to ensure the interrupts have been completed */
+ for (wcnt = 0; wcnt < MAX_INT_WAIT_CNT; wcnt++) {
+ udelay(5);
+ if (!sc->interrupt_active)
+ break;
+ }
+ if (wcnt >= MAX_INT_WAIT_CNT)
+ dev_warn(&sc->pdev->dev, "SBE 2T3E3: Interrupt active too long\n");
+
+ /* clear all receive/transmit data */
+ dc_drop_descriptor_list(sc);
+}
+
+void dc_start_intr(struct channel *sc)
+{
+ if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE && sc->s.OOF)
+ return;
+
+ if (sc->p.receiver_on || sc->p.transmitter_on) {
+ if (!sc->ether.interrupt_enable_mask)
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
+
+ sc->ether.interrupt_enable_mask =
+ SBE_2T3E3_21143_VAL_NORMAL_INTERRUPT_SUMMARY_ENABLE |
+ SBE_2T3E3_21143_VAL_ABNORMAL_INTERRUPT_SUMMARY_ENABLE |
+ SBE_2T3E3_21143_VAL_RECEIVE_STOPPED_ENABLE |
+ SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE_ENABLE |
+ SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT_ENABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW_INTERRUPT_ENABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE_ENABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_STOPPED_ENABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT_ENABLE;
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
+ sc->ether.interrupt_enable_mask);
+ }
+}
+
+void dc_stop_intr(struct channel *sc)
+{
+ sc->ether.interrupt_enable_mask = 0;
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
+}
+
+void dc_reset(struct channel *sc)
+{
+ /* turn off ethernet interrupts */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, 0xFFFFFFFF);
+
+ /* software reset */
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE,
+ SBE_2T3E3_21143_VAL_SOFTWARE_RESET);
+ udelay(4); /* 50 PCI cycles < 2us */
+
+ /* clear hardware configuration */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_BUS_MODE, 0);
+
+ /* clear software configuration */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, 0);
+
+ /* turn off SIA reset */
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
+ SBE_2T3E3_21143_VAL_SIA_RESET);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0);
+}
+
+
+void dc_receiver_onoff(struct channel *sc, u32 mode)
+{
+ u32 i, state = 0;
+
+ if (sc->p.receiver_on == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
+ SBE_2T3E3_21143_VAL_RECEIVE_START) {
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_RECEIVE_START);
+
+ for (i = 0; i < 16; i++) {
+ state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
+ SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STATE;
+ if (state == SBE_2T3E3_21143_VAL_RX_STOPPED)
+ break;
+ udelay(5);
+ }
+ if (state != SBE_2T3E3_21143_VAL_RX_STOPPED)
+ dev_warn(&sc->pdev->dev, "SBE 2T3E3: Rx failed to stop\n");
+ else
+ dev_info(&sc->pdev->dev, "SBE 2T3E3: Rx off\n");
+ }
+ break;
+ case SBE_2T3E3_ON:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_RECEIVE_START);
+ udelay(100);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.receiver_on = mode;
+}
+
+void dc_transmitter_onoff(struct channel *sc, u32 mode)
+{
+ u32 i, state = 0;
+
+ if (sc->p.transmitter_on == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ if (dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
+ SBE_2T3E3_21143_VAL_TRANSMISSION_START) {
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_TRANSMISSION_START);
+
+ for (i = 0; i < 16; i++) {
+ state = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS) &
+ SBE_2T3E3_21143_VAL_TRANSMISSION_PROCESS_STATE;
+ if (state == SBE_2T3E3_21143_VAL_TX_STOPPED)
+ break;
+ udelay(5);
+ }
+ if (state != SBE_2T3E3_21143_VAL_TX_STOPPED)
+ dev_warn(&sc->pdev->dev, "SBE 2T3E3: Tx failed to stop\n");
+ }
+ break;
+ case SBE_2T3E3_ON:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_TRANSMISSION_START);
+ udelay(100);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND, 0xFFFFFFFF);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.transmitter_on = mode;
+}
+
+
+
+void dc_set_loopback(struct channel *sc, u32 mode)
+{
+ u32 val;
+
+ switch (mode) {
+ case SBE_2T3E3_21143_VAL_LOOPBACK_OFF:
+ case SBE_2T3E3_21143_VAL_LOOPBACK_INTERNAL:
+ break;
+ default:
+ return;
+ }
+
+#if 0
+ /* restart SIA */
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
+ SBE_2T3E3_21143_VAL_SIA_RESET);
+ udelay(1000);
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY,
+ SBE_2T3E3_21143_VAL_SIA_RESET);
+#endif
+
+ /* select loopback mode */
+ val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE) &
+ ~SBE_2T3E3_21143_VAL_OPERATING_MODE;
+ val |= mode;
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE, val);
+
+ if (mode == SBE_2T3E3_21143_VAL_LOOPBACK_OFF)
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
+ else
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
+}
+
+u32 dc_init_descriptor_list(struct channel *sc)
+{
+ u32 i, j;
+ struct sk_buff *m;
+
+ if (sc->ether.rx_ring == NULL)
+ sc->ether.rx_ring = kzalloc(SBE_2T3E3_RX_DESC_RING_SIZE *
+ sizeof(t3e3_rx_desc_t), GFP_KERNEL);
+ if (sc->ether.rx_ring == NULL) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
+ return ENOMEM;
+ }
+
+ if (sc->ether.tx_ring == NULL)
+ sc->ether.tx_ring = kzalloc(SBE_2T3E3_TX_DESC_RING_SIZE *
+ sizeof(t3e3_tx_desc_t), GFP_KERNEL);
+ if (sc->ether.tx_ring == NULL) {
+#ifdef T3E3_USE_CONTIGMALLOC
+ t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
+ sizeof(t3e3_rx_desc_t);
+#endif
+ kfree(sc->ether.rx_ring);
+ sc->ether.rx_ring = NULL;
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
+ return ENOMEM;
+ }
+
+
+ /*
+ * Receive ring
+ */
+ for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
+ sc->ether.rx_ring[i].rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
+ sc->ether.rx_ring[i].rdes1 =
+ SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED | SBE_2T3E3_MTU;
+
+ if (sc->ether.rx_data[i] == NULL) {
+ if (!(m = dev_alloc_skb(MCLBYTES))) {
+ for (j = 0; j < i; j++) {
+ dev_kfree_skb_any(sc->ether.rx_data[j]);
+ sc->ether.rx_data[j] = NULL;
+ }
+#ifdef T3E3_USE_CONTIGMALLOC
+ t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
+ sizeof(t3e3_rx_desc_t);
+#endif
+ kfree(sc->ether.rx_ring);
+ sc->ether.rx_ring = NULL;
+#ifdef T3E3_USE_CONTIGMALLOC
+ t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
+ sizeof(t3e3_tx_desc_t);
+#endif
+ kfree(sc->ether.tx_ring);
+ sc->ether.tx_ring = NULL;
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:"
+ " no buffer space for RX ring\n");
+ return ENOBUFS;
+ }
+ sc->ether.rx_data[i] = m;
+ }
+ sc->ether.rx_ring[i].rdes2 = virt_to_phys(sc->ether.rx_data[i]->data);
+
+ sc->ether.rx_ring[i].rdes3 = virt_to_phys(
+ &sc->ether.rx_ring[(i + 1) % SBE_2T3E3_RX_DESC_RING_SIZE]);
+ }
+ sc->ether.rx_ring[SBE_2T3E3_RX_DESC_RING_SIZE - 1].rdes1 |=
+ SBE_2T3E3_RX_DESC_END_OF_RING;
+ sc->ether.rx_ring_current_read = 0;
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS,
+ virt_to_phys(&sc->ether.rx_ring[0]));
+
+ /*
+ * Transmit ring
+ */
+ for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
+ sc->ether.tx_ring[i].tdes0 = 0;
+ sc->ether.tx_ring[i].tdes1 = SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED |
+ SBE_2T3E3_TX_DESC_DISABLE_PADDING;
+
+ sc->ether.tx_ring[i].tdes2 = 0;
+ sc->ether.tx_data[i] = NULL;
+
+ sc->ether.tx_ring[i].tdes3 = virt_to_phys(
+ &sc->ether.tx_ring[(i + 1) % SBE_2T3E3_TX_DESC_RING_SIZE]);
+ }
+ sc->ether.tx_ring[SBE_2T3E3_TX_DESC_RING_SIZE - 1].tdes1 |=
+ SBE_2T3E3_TX_DESC_END_OF_RING;
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS,
+ virt_to_phys(&sc->ether.tx_ring[0]));
+ sc->ether.tx_ring_current_read = 0;
+ sc->ether.tx_ring_current_write = 0;
+ sc->ether.tx_free_cnt = SBE_2T3E3_TX_DESC_RING_SIZE;
+ spin_lock_init(&sc->ether.tx_lock);
+
+ return 0;
+}
+
+void dc_clear_descriptor_list(struct channel *sc)
+{
+ u32 i;
+
+ /* clear CSR3 and CSR4 */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_LIST_BASE_ADDRESS, 0);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_LIST_BASE_ADDRESS, 0);
+
+ /* free all data buffers on TX ring */
+ for (i = 0; i < SBE_2T3E3_TX_DESC_RING_SIZE; i++) {
+ if (sc->ether.tx_data[i] != NULL) {
+ dev_kfree_skb_any(sc->ether.tx_data[i]);
+ sc->ether.tx_data[i] = NULL;
+ }
+ }
+}
+
+void dc_drop_descriptor_list(struct channel *sc)
+{
+ u32 i;
+
+ dc_clear_descriptor_list(sc);
+
+ /* free all data buffers on RX ring */
+ for (i = 0; i < SBE_2T3E3_RX_DESC_RING_SIZE; i++) {
+ if (sc->ether.rx_data[i] != NULL) {
+ dev_kfree_skb_any(sc->ether.rx_data[i]);
+ sc->ether.rx_data[i] = NULL;
+ }
+ }
+
+ if (sc->ether.rx_ring != NULL) {
+#ifdef T3E3_USE_CONTIGMALLOC
+ t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
+ sizeof(t3e3_rx_desc_t);
+#endif
+ kfree(sc->ether.rx_ring);
+ sc->ether.rx_ring = NULL;
+ }
+
+ if (sc->ether.tx_ring != NULL) {
+#ifdef T3E3_USE_CONTIGMALLOC
+ t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
+ sizeof(t3e3_tx_desc_t);
+#endif
+ kfree(sc->ether.tx_ring);
+ sc->ether.tx_ring = NULL;
+ }
+}
+
+
+void dc_set_output_port(struct channel *sc)
+{
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_PORT_SELECT);
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_STATUS, 0x00000301);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_CONNECTIVITY, 0);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_TRANSMIT_AND_RECEIVE, 0);
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_SIA_AND_GENERAL_PURPOSE_PORT, 0x08000011);
+
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_TRANSMIT_THRESHOLD_MODE_100Mbs |
+ SBE_2T3E3_21143_VAL_HEARTBEAT_DISABLE |
+ SBE_2T3E3_21143_VAL_PORT_SELECT |
+ SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
+}
+
+void dc_restart(struct channel *sc)
+{
+ dev_warn(&sc->pdev->dev, "SBE 2T3E3: 21143 restart\n");
+
+ dc_stop(sc);
+ dc_reset(sc);
+ dc_init(sc); /* stop + reset + init */
+ dc_start(sc);
+}
diff --git a/drivers/staging/sbe-2t3e3/exar7250.c b/drivers/staging/sbe-2t3e3/exar7250.c
new file mode 100644
index 000000000000..809f446bdc3a
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/exar7250.c
@@ -0,0 +1,217 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include "2t3e3.h"
+#include "ctrl.h"
+
+void exar7250_init(struct channel *sc)
+{
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
+ SBE_2T3E3_FRAMER_VAL_T3_CBIT |
+ SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET |
+ SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK);
+
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
+ SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK |
+ SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK |
+ SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE |
+ SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT);
+
+ exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT);
+}
+
+void exar7250_set_frame_type(struct channel *sc, u32 type)
+{
+ u32 val;
+
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ break;
+ default:
+ return;
+ }
+
+ exar7250_stop_intr(sc, type);
+
+ val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE);
+ val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE |
+ SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT |
+ SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT);
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ val |= SBE_2T3E3_FRAMER_VAL_E3_G751;
+ break;
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ val |= SBE_2T3E3_FRAMER_VAL_E3_G832;
+ break;
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT;
+ break;
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ val |= SBE_2T3E3_FRAMER_VAL_T3_M13;
+ break;
+ default:
+ return;
+ }
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val);
+ exar7250_start_intr(sc, type);
+}
+
+
+void exar7250_start_intr(struct channel *sc, u32 type)
+{
+ u32 val;
+
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
+#if 0
+ sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
+#else
+ cpld_LOS_update(sc);
+#endif
+ sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
+ SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE);
+#if 0
+ /*SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE);*/
+#endif
+
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
+#if 0
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2,
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE);
+#endif
+ break;
+
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
+#if 0
+ sc->s.LOS = val & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
+#else
+ cpld_LOS_update(sc);
+#endif
+ sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
+
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
+ SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
+#if 0
+ /* SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE);*/
+#endif
+
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
+#if 0
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS,
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE);
+#endif
+
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
+ break;
+
+ default:
+ return;
+ }
+
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
+ SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE);
+}
+
+
+void exar7250_stop_intr(struct channel *sc, u32 type)
+{
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
+
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
+ break;
+
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0);
+ exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
+ break;
+ }
+}
+
+
+
+
+void exar7250_unipolar_onoff(struct channel *sc, u32 mode)
+{
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
+ SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
+ break;
+ case SBE_2T3E3_ON:
+ exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
+ SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
+ break;
+ }
+}
+
+void exar7250_set_loopback(struct channel *sc, u32 mode)
+{
+ switch (mode) {
+ case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF:
+ exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
+ SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
+ break;
+ case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON:
+ exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
+ SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
+ break;
+ }
+}
diff --git a/drivers/staging/sbe-2t3e3/exar7300.c b/drivers/staging/sbe-2t3e3/exar7300.c
new file mode 100644
index 000000000000..d10d696cf6fb
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/exar7300.c
@@ -0,0 +1,182 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include "2t3e3.h"
+#include "ctrl.h"
+
+void exar7300_init(struct channel *sc)
+{
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG1, 0);
+
+ /* enable line decodeer and encoder */
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG2, 0);
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG3, 0);
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4,
+ SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
+ SBE_2T3E3_LIU_VAL_LOOPBACK_OFF);
+}
+
+void exar7300_set_loopback(struct channel *sc, u32 mode)
+{
+ u32 val;
+
+ switch (mode) {
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF:
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE:
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG:
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL:
+ break;
+ default:
+ return;
+ }
+
+ val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
+ val &= ~(SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK | SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK);
+ val |= mode;
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
+
+#if 0
+ /* TODO - is it necessary? idea from 2T3E3_HW_Test_code */
+ switch (mode) {
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF:
+ break;
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE:
+ exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
+ break;
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG:
+ exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF);
+ break;
+ case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL:
+ exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
+ break;
+ }
+#endif
+}
+
+void exar7300_set_frame_type(struct channel *sc, u32 type)
+{
+ u32 val;
+
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ break;
+ default:
+ return;
+ }
+
+ val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4);
+ val &= ~(SBE_2T3E3_LIU_VAL_T3_MODE_SELECT |
+ SBE_2T3E3_LIU_VAL_E3_MODE_SELECT);
+
+ switch (type) {
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ val |= SBE_2T3E3_LIU_VAL_T3_MODE_SELECT;
+ break;
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ val |= SBE_2T3E3_LIU_VAL_E3_MODE_SELECT;
+ break;
+ default:
+ return;
+ }
+
+ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val);
+}
+
+
+void exar7300_transmit_all_ones_onoff(struct channel *sc, u32 mode)
+{
+ if (sc->p.transmit_all_ones == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_ON:
+ exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
+ break;
+ case SBE_2T3E3_OFF:
+ exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.transmit_all_ones = mode;
+}
+
+void exar7300_receive_equalization_onoff(struct channel *sc, u32 mode)
+{
+ if (sc->p.receive_equalization == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG2,
+ SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
+ break;
+ case SBE_2T3E3_ON:
+ exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG2,
+ SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.receive_equalization = mode;
+}
+
+void exar7300_line_build_out_onoff(struct channel *sc, u32 mode)
+{
+ if (sc->p.line_build_out == mode)
+ return;
+
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
+ exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF);
+ break;
+ case SBE_2T3E3_ON:
+ exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT);
+ exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON);
+ break;
+ default:
+ return;
+ }
+
+ sc->p.line_build_out = mode;
+}
+
+/* TODO - what about encoder in raw mode??? disable it too? */
+void exar7300_unipolar_onoff(struct channel *sc, u32 mode)
+{
+ switch (mode) {
+ case SBE_2T3E3_OFF:
+ exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG3,
+ SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
+ exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
+ break;
+ case SBE_2T3E3_ON:
+ exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG3,
+ SBE_2T3E3_LIU_VAL_DECODER_DISABLE);
+ exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1,
+ SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA);
+ break;
+ }
+}
diff --git a/drivers/staging/sbe-2t3e3/intr.c b/drivers/staging/sbe-2t3e3/intr.c
new file mode 100644
index 000000000000..7ad1a8382037
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/intr.c
@@ -0,0 +1,635 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/hdlc.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include "2t3e3.h"
+
+irqreturn_t t3e3_intr(int irq, void *dev_instance)
+{
+ struct channel *sc = dev_to_priv(dev_instance);
+ u32 val;
+ irqreturn_t ret = IRQ_NONE;
+
+ sc->interrupt_active = 1;
+
+ val = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR);
+
+ if (val & SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_CHANGE) {
+ dev_dbg(&sc->pdev->dev,
+ "Rx LOS Chng Int r=%02x (LOS|OOF=%02x)\n",
+ val, (sc->s.LOS << 4) | sc->s.OOF);
+ cpld_LOS_update(sc);
+ ret = IRQ_HANDLED;
+ }
+
+ if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ASSERTED) {
+ dc_intr(sc);
+ ret = IRQ_HANDLED;
+ }
+
+ if (val & SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ASSERTED) {
+ exar7250_intr(sc);
+ ret = IRQ_HANDLED;
+ }
+
+ /*
+ we don't care about other interrupt sources (DMO, LOS, LCV) because
+ they are handled by Framer too
+ */
+
+ sc->interrupt_active = 0;
+ return ret;
+}
+
+void dc_intr(struct channel *sc)
+{
+ u32 val;
+
+ /* disable ethernet interrupts */
+ /* grrr this clears interrupt summary bits !!! */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE, 0);
+
+ while ((val = dc_read(sc->addr, SBE_2T3E3_21143_REG_STATUS)) &
+ (SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED |
+ SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
+ SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
+ SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW |
+ SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED |
+ SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)) {
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_STATUS, val);
+
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Ethernet controller interrupt! (CSR5 = %08X)\n",
+ val);
+
+ if (val & (SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT |
+ SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE |
+ SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)) {
+ if (val & SBE_2T3E3_21143_VAL_RECEIVE_INTERRUPT)
+ dev_dbg(&sc->pdev->dev,
+ "Receive interrupt (LOS=%d, OOF=%d)\n",
+ sc->s.LOS, sc->s.OOF);
+ if (val & SBE_2T3E3_21143_VAL_RECEIVE_BUFFER_UNAVAILABLE)
+ dev_dbg(&sc->pdev->dev,
+ "Receive buffer unavailable\n");
+ if (val & SBE_2T3E3_21143_VAL_RECEIVE_PROCESS_STOPPED)
+ dev_dbg(&sc->pdev->dev,
+ "Receive process stopped\n");
+ dc_intr_rx(sc);
+ }
+
+ if (val & SBE_2T3E3_21143_VAL_TRANSMIT_UNDERFLOW) {
+ dev_dbg(&sc->pdev->dev, "Transmit underflow\n");
+ dc_intr_tx_underflow(sc);
+ }
+
+ if (val & (SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE |
+ SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT |
+ SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)) {
+ if (val & SBE_2T3E3_21143_VAL_TRANSMIT_INTERRUPT)
+ dev_dbg(&sc->pdev->dev, "Transmit interrupt\n");
+ if (val & SBE_2T3E3_21143_VAL_TRANSMIT_BUFFER_UNAVAILABLE)
+ dev_dbg(&sc->pdev->dev,
+ "Transmit buffer unavailable\n");
+ if (val & SBE_2T3E3_21143_VAL_TRANSMIT_PROCESS_STOPPED)
+ dev_dbg(&sc->pdev->dev,
+ "Transmit process stopped\n");
+ dc_intr_tx(sc);
+ }
+ }
+
+ /* enable ethernet interrupts */
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_INTERRUPT_ENABLE,
+ sc->ether.interrupt_enable_mask);
+}
+
+void dc_intr_rx(struct channel *sc)
+{
+ u32 current_read;
+ u32 error_mask, error;
+ t3e3_rx_desc_t *current_desc;
+ struct sk_buff *m, *m2;
+ unsigned rcv_len;
+
+ sc->rcv_count++; /* for the activity LED */
+
+ current_read = sc->ether.rx_ring_current_read;
+ dev_dbg(&sc->pdev->dev, "intr_rx current_read = %d\n", current_read);
+
+ /* when ethernet loopback is set, ignore framer signals */
+ if ((sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) && sc->s.OOF) {
+ while (!(sc->ether.rx_ring[current_read].rdes0 &
+ SBE_2T3E3_RX_DESC_21143_OWN)) {
+ current_desc = &sc->ether.rx_ring[current_read];
+ current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
+ SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
+ current_desc->rdes1 |= SBE_2T3E3_MTU;
+ current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
+ current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
+ }
+ sc->ether.rx_ring_current_read = current_read;
+ return;
+ }
+
+ while (!(sc->ether.rx_ring[current_read].rdes0 &
+ SBE_2T3E3_RX_DESC_21143_OWN)) {
+ current_desc = &sc->ether.rx_ring[current_read];
+
+ dev_dbg(&sc->pdev->dev, "rdes0: %08X rdes1: %08X\n",
+ current_desc->rdes0, current_desc->rdes1);
+
+ m = sc->ether.rx_data[current_read];
+ rcv_len = (current_desc->rdes0 & SBE_2T3E3_RX_DESC_FRAME_LENGTH) >>
+ SBE_2T3E3_RX_DESC_FRAME_LENGTH_SHIFT;
+
+ dev_dbg(&sc->pdev->dev, "mbuf was received (mbuf len = %d)\n",
+ rcv_len);
+
+ switch (sc->p.crc) {
+ case SBE_2T3E3_CRC_16:
+ rcv_len -= SBE_2T3E3_CRC16_LENGTH;
+ break;
+ case SBE_2T3E3_CRC_32:
+ rcv_len -= SBE_2T3E3_CRC32_LENGTH;
+ break;
+ default:
+ break;
+ }
+
+ if (current_desc->rdes0 & SBE_2T3E3_RX_DESC_LAST_DESC) {
+
+ /* TODO: is collision possible? */
+ error_mask = SBE_2T3E3_RX_DESC_DESC_ERROR |
+ SBE_2T3E3_RX_DESC_COLLISION_SEEN |
+ SBE_2T3E3_RX_DESC_DRIBBLING_BIT;
+
+ switch (sc->p.frame_mode) {
+ case SBE_2T3E3_FRAME_MODE_HDLC:
+ error_mask |= SBE_2T3E3_RX_DESC_MII_ERROR;
+ if (sc->p.crc == SBE_2T3E3_CRC_32)
+ error_mask |= SBE_2T3E3_RX_DESC_CRC_ERROR;
+ break;
+ case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
+ case SBE_2T3E3_FRAME_MODE_RAW:
+ break;
+ default:
+ error_mask = 0;
+ }
+
+ if (sc->s.LOS) {
+ error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT ||
+ SBE_2T3E3_RX_DESC_MII_ERROR);
+ }
+
+ error = current_desc->rdes0 & error_mask;
+ if (error) {
+ sc->s.in_errors++;
+ dev_dbg(&sc->pdev->dev,
+ "error interrupt: NO_ERROR_MESSAGE = %d\n",
+ sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES ? 1 : 0);
+
+ current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
+ SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
+ current_desc->rdes1 |= SBE_2T3E3_MTU;
+ current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
+
+ if (error & SBE_2T3E3_RX_DESC_DESC_ERROR) {
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev,
+ "SBE 2T3E3: descriptor error\n");
+ sc->s.in_error_desc++;
+ }
+
+ if (error & SBE_2T3E3_RX_DESC_COLLISION_SEEN) {
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev,
+ "SBE 2T3E3: collision seen\n");
+ sc->s.in_error_coll++;
+ } else {
+ if (error & SBE_2T3E3_RX_DESC_DRIBBLING_BIT) {
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev,
+ "SBE 2T3E3: dribbling bits error\n");
+ sc->s.in_error_drib++;
+ }
+
+ if (error & SBE_2T3E3_RX_DESC_CRC_ERROR) {
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev,
+ "SBE 2T3E3: crc error\n");
+ sc->s.in_error_crc++;
+ }
+ }
+
+ if (error & SBE_2T3E3_RX_DESC_MII_ERROR) {
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: mii error\n");
+ sc->s.in_error_mii++;
+ }
+
+ current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
+ sc->r.flags |= SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
+ continue;
+ }
+ }
+
+ current_desc->rdes1 &= SBE_2T3E3_RX_DESC_END_OF_RING |
+ SBE_2T3E3_RX_DESC_SECOND_ADDRESS_CHAINED;
+ current_desc->rdes1 |= SBE_2T3E3_MTU;
+
+ if (rcv_len > 1600) {
+ sc->s.in_errors++;
+ sc->s.in_dropped++;
+ if (!(sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES))
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: oversized rx: rdes0 = %08X\n",
+ current_desc->rdes0);
+ } else {
+ m2 = dev_alloc_skb(MCLBYTES);
+ if (m2 != NULL) {
+ current_desc->rdes2 = virt_to_phys(m2->data);
+ sc->ether.rx_data[current_read] = m2;
+ sc->s.in_packets++;
+ sc->s.in_bytes += rcv_len;
+ m->dev = sc->dev;
+ skb_put(m, rcv_len);
+ skb_reset_mac_header(m);
+ m->protocol = hdlc_type_trans(m, m->dev);
+ netif_rx(m);
+
+ /* good packet was received so we will show error messages again... */
+ if (sc->r.flags & SBE_2T3E3_FLAG_NO_ERROR_MESSAGES) {
+ dev_dbg(&sc->pdev->dev,
+ "setting ERROR_MESSAGES->0\n");
+ sc->r.flags &= ~SBE_2T3E3_FLAG_NO_ERROR_MESSAGES;
+ }
+
+ } else {
+ sc->s.in_errors++;
+ sc->s.in_dropped++;
+ }
+ }
+ current_desc->rdes0 = SBE_2T3E3_RX_DESC_21143_OWN;
+ current_read = (current_read + 1) % SBE_2T3E3_RX_DESC_RING_SIZE;
+ }
+
+ sc->ether.rx_ring_current_read = current_read;
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_RECEIVE_POLL_DEMAND, 0xFFFFFFFF);
+}
+
+void dc_intr_tx(struct channel *sc)
+{
+ u32 current_read, current_write;
+ u32 last_segment, error;
+ t3e3_tx_desc_t *current_desc;
+
+ spin_lock(&sc->ether.tx_lock);
+
+ current_read = sc->ether.tx_ring_current_read;
+ current_write = sc->ether.tx_ring_current_write;
+
+ while (current_read != current_write) {
+ current_desc = &sc->ether.tx_ring[current_read];
+
+ if (current_desc->tdes0 & SBE_2T3E3_RX_DESC_21143_OWN)
+ break;
+
+ dev_dbg(&sc->pdev->dev,
+ "txeof: tdes0 = %08X tdes1 = %08X\n",
+ current_desc->tdes0, current_desc->tdes1);
+
+ error = current_desc->tdes0 & (SBE_2T3E3_TX_DESC_ERROR_SUMMARY |
+ SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT |
+ SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER |
+ SBE_2T3E3_TX_DESC_NO_CARRIER |
+ SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT |
+ SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR |
+ SBE_2T3E3_TX_DESC_DEFFERED);
+
+ last_segment = current_desc->tdes1 & SBE_2T3E3_TX_DESC_LAST_SEGMENT;
+
+ current_desc->tdes0 = 0;
+ current_desc->tdes1 &= SBE_2T3E3_TX_DESC_END_OF_RING |
+ SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
+ current_desc->tdes2 = 0;
+ sc->ether.tx_free_cnt++;
+
+ if (last_segment != SBE_2T3E3_TX_DESC_LAST_SEGMENT) {
+ current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
+ continue;
+ }
+
+
+ if (sc->ether.tx_data[current_read]) {
+ sc->s.out_packets++;
+ sc->s.out_bytes += sc->ether.tx_data[current_read]->len;
+ dev_kfree_skb_any(sc->ether.tx_data[current_read]);
+ sc->ether.tx_data[current_read] = NULL;
+ }
+
+ if (error > 0) {
+ sc->s.out_errors++;
+
+ if (error & SBE_2T3E3_TX_DESC_TRANSMIT_JABBER_TIMEOUT) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: transmit jabber timeout\n");
+ sc->s.out_error_jab++;
+ }
+
+ if (sc->p.loopback != SBE_2T3E3_LOOPBACK_ETHERNET) {
+ if (error & SBE_2T3E3_TX_DESC_LOSS_OF_CARRIER) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: loss of carrier\n");
+ sc->s.out_error_lost_carr++;
+ }
+
+ if (error & SBE_2T3E3_TX_DESC_NO_CARRIER) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: no carrier\n");
+ sc->s.out_error_no_carr++;
+ }
+ }
+
+ if (error & SBE_2T3E3_TX_DESC_LINK_FAIL_REPORT) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: link fail report\n");
+ sc->s.out_error_link_fail++;
+ }
+
+ if (error & SBE_2T3E3_TX_DESC_UNDERFLOW_ERROR) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3:"
+ " transmission underflow error\n");
+ sc->s.out_error_underflow++;
+ spin_unlock(&sc->ether.tx_lock);
+
+ dc_restart(sc);
+ return;
+ }
+
+ if (error & SBE_2T3E3_TX_DESC_DEFFERED) {
+ dev_err(&sc->pdev->dev, "SBE 2T3E3: transmission deferred\n");
+ sc->s.out_error_dereferred++;
+ }
+ }
+
+ current_read = (current_read + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
+ }
+
+ sc->ether.tx_ring_current_read = current_read;
+
+ /* Relieve flow control when the TX queue is drained at least half way */
+ if (sc->ether.tx_full &&
+ (sc->ether.tx_free_cnt >= (SBE_2T3E3_TX_DESC_RING_SIZE / 2))) {
+ sc->ether.tx_full = 0;
+ netif_wake_queue(sc->dev);
+ }
+ spin_unlock(&sc->ether.tx_lock);
+}
+
+
+void dc_intr_tx_underflow(struct channel *sc)
+{
+ u32 val;
+
+ dc_transmitter_onoff(sc, SBE_2T3E3_OFF);
+
+ val = dc_read(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE);
+ dc_clear_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS);
+
+ switch (val & SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS) {
+ case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_1:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2);
+ break;
+ case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_2:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3);
+ break;
+ case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_3:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4);
+ break;
+ case SBE_2T3E3_21143_VAL_THRESHOLD_CONTROL_BITS_4:
+ default:
+ dc_set_bits(sc->addr, SBE_2T3E3_21143_REG_OPERATION_MODE,
+ SBE_2T3E3_21143_VAL_STORE_AND_FORWARD);
+ break;
+ }
+
+ dc_transmitter_onoff(sc, SBE_2T3E3_ON);
+}
+
+
+
+
+void exar7250_intr(struct channel *sc)
+{
+ u32 status, old_OOF;
+
+#if 0
+ /* disable interrupts */
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
+#endif
+
+ old_OOF = sc->s.OOF;
+
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt! (REG[0x05] = %02X)\n", status);
+
+ switch (sc->p.frame_type) {
+ case SBE_2T3E3_FRAME_TYPE_E3_G751:
+ case SBE_2T3E3_FRAME_TYPE_E3_G832:
+ exar7250_E3_intr(sc, status);
+ break;
+
+ case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
+ case SBE_2T3E3_FRAME_TYPE_T3_M13:
+ exar7250_T3_intr(sc, status);
+ break;
+
+ default:
+ break;
+ }
+
+ if (sc->s.OOF != old_OOF) {
+ if (sc->s.OOF) {
+ if (sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Disabling eth interrupts\n");
+ /* turn off ethernet interrupts */
+ dc_stop_intr(sc);
+ }
+ } else if (sc->r.flags & SBE_2T3E3_FLAG_NETWORK_UP) {
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Enabling eth interrupts\n");
+ /* start interrupts */
+ sc->s.OOF = 1;
+ dc_intr_rx(sc);
+ sc->s.OOF = 0;
+ if (sc->p.receiver_on) {
+ dc_receiver_onoff(sc, SBE_2T3E3_OFF);
+ dc_receiver_onoff(sc, SBE_2T3E3_ON);
+ }
+ dc_start_intr(sc);
+ }
+ }
+#if 0
+ /* reenable interrupts */
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
+ SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE
+ );
+#endif
+}
+
+
+void exar7250_T3_intr(struct channel *sc, u32 block_status)
+{
+ u32 status, result;
+
+ if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
+
+ if (status) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt T3 RX (REG[0x13] = %02X)\n",
+ status);
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);
+
+#if 0
+ if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_STATUS) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt T3: LOS\n");
+ sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_T3_RX_LOS ? 1 : 0;
+
+ }
+#else
+ cpld_LOS_update(sc);
+#endif
+ if (status & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_STATUS) {
+ sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt T3: OOF (%d)\n",
+ sc->s.OOF);
+ }
+
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
+ SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);
+#if 0
+ SBE_2T3E3_FRAMER_VAL_T3_RX_CP_BIT_ERROR_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_AIS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_IDLE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FERF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_AIC_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_P_BIT_INTERRUPT_ENABLE
+#endif
+ }
+
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
+ if (status) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt T3 RX (REG[0x17] = %02X)\n",
+ status);
+#if 0
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS,
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_REMOVE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_T3_RX_FEAC_VALID_INTERRUPT_ENABLE
+ );
+#endif
+ }
+
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
+ if (status)
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt T3 RX (REG[0x18] = %02X)\n",
+ status);
+ }
+
+
+ if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x31] = %02X)\n",
+ status);
+
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt T3 TX (REG[0x34] = %02X)\n",
+ status);
+ }
+}
+
+
+void exar7250_E3_intr(struct channel *sc, u32 block_status)
+{
+ u32 status, result;
+
+ if (block_status & SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_STATUS) {
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
+
+ if (status) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt E3 RX (REG[0x14] = %02X)\n",
+ status);
+
+ result = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);
+
+#if 0
+ if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_STATUS) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt E3: LOS\n");
+ sc->s.LOS = result & SBE_2T3E3_FRAMER_VAL_E3_RX_LOS ? 1 : 0;
+ }
+#else
+ cpld_LOS_update(sc);
+#endif
+ if (status & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_STATUS) {
+ sc->s.OOF = result & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt E3: OOF (%d)\n",
+ sc->s.OOF);
+ }
+
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
+ SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE
+ );
+#if 0
+ SBE_2T3E3_FRAMER_VAL_E3_RX_COFA_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_AIS_INTERRUPT_ENABLE
+#endif
+ }
+
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
+ if (status) {
+ dev_dbg(&sc->pdev->dev,
+ "Framer interrupt E3 RX (REG[0x15] = %02X)\n",
+ status);
+
+#if 0
+ exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2,
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FEBE_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FERF_INTERRUPT_ENABLE |
+ SBE_2T3E3_FRAMER_VAL_E3_RX_FRAMING_BYTE_ERROR_INTERRUPT_ENABLE);
+#endif
+ }
+
+ }
+
+ if (block_status & SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_STATUS) {
+ status = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: Framer interrupt E3 TX (REG[0x34] = %02X)\n",
+ status);
+ }
+}
diff --git a/drivers/staging/sbe-2t3e3/io.c b/drivers/staging/sbe-2t3e3/io.c
new file mode 100644
index 000000000000..b458ff034067
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/io.c
@@ -0,0 +1,352 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/ip.h>
+#include <asm/system.h>
+#include "2t3e3.h"
+#include "ctrl.h"
+
+/* All access to registers done via the 21143 on port 0 must be
+ * protected via the card->bootrom_lock. */
+
+/* priviate define to be used here only - must be protected by card->bootrom_lock */
+#define cpld_write_nolock(channel, reg, val) \
+ bootrom_write((channel), CPLD_MAP_REG(reg, channel), val)
+
+u32 cpld_read(struct channel *channel, u32 reg)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+ val = bootrom_read((channel), CPLD_MAP_REG(reg, channel));
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+ return val;
+}
+
+/****************************************
+ * Access via BootROM port
+ ****************************************/
+
+u32 bootrom_read(struct channel *channel, u32 reg)
+{
+ unsigned long addr = channel->card->bootrom_addr;
+ u32 result;
+
+ /* select BootROM address */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
+
+ /* select reading from BootROM */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT);
+
+ udelay(2); /* 20 PCI cycles */
+
+ /* read from BootROM */
+ result = dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) & 0xff;
+
+ /* reset CSR9 */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
+
+ return result;
+}
+
+void bootrom_write(struct channel *channel, u32 reg, u32 val)
+{
+ unsigned long addr = channel->card->bootrom_addr;
+
+ /* select BootROM address */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_PROGRAMMING_ADDRESS, reg & 0x3FFFF);
+
+ /* select writting to BootROM */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_BOOT_ROM_SELECT |
+ (val & 0xff));
+
+ udelay(2); /* 20 PCI cycles */
+
+ /* reset CSR9 */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
+}
+
+
+/****************************************
+ * Access via Serial I/O port
+ ****************************************/
+
+static u32 serialrom_read_bit(struct channel *channel)
+{
+ unsigned long addr = channel->card->bootrom_addr;
+ u32 bit;
+
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock high */
+
+ bit = (dc_read(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT) &
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_DATA_OUT) > 0 ? 1 : 0;
+
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+
+ return bit;
+}
+
+static void serialrom_write_bit(struct channel *channel, u32 bit)
+{
+ unsigned long addr = channel->card->bootrom_addr;
+ u32 lastbit = -1;
+
+ bit &= 1;
+
+ if (bit != lastbit) {
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
+ (bit << 2)); /* clock low */
+
+ lastbit = bit;
+ }
+
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CLOCK |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
+ (bit << 2)); /* clock high */
+
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT |
+ (bit << 2)); /* clock low */
+}
+
+/****************************************
+ * Access to SerialROM (eeprom)
+ ****************************************/
+
+u32 t3e3_eeprom_read_word(struct channel *channel, u32 address)
+{
+ unsigned long addr = channel->card->bootrom_addr;
+ u32 i, val;
+ unsigned long flags;
+
+ address &= 0x3f;
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+
+ /* select correct Serial Chip */
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
+ SBE_2T3E3_CPLD_VAL_EEPROM_SELECT);
+
+ /* select reading from Serial I/O Bus */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+
+ /* select read operation */
+ serialrom_write_bit(channel, 0);
+ serialrom_write_bit(channel, 1);
+ serialrom_write_bit(channel, 1);
+ serialrom_write_bit(channel, 0);
+
+ for (i = 0x20; i; i >>= 1)
+ serialrom_write_bit(channel, address & i ? 1 : 0);
+
+ val = 0;
+ for (i = 0x8000; i; i >>= 1)
+ val |= (serialrom_read_bit(channel) ? i : 0);
+
+ /* Reset 21143's CSR9 */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
+
+ /* Unselect Serial Chip */
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
+
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+
+ return ntohs(val);
+}
+
+
+/****************************************
+ * Access to Framer
+ ****************************************/
+
+u32 exar7250_read(struct channel *channel, u32 reg)
+{
+ u32 result;
+ unsigned long flags;
+
+#if 0
+ switch (reg) {
+ case SBE_2T3E3_FRAMER_REG_OPERATING_MODE:
+ return channel->framer_regs[reg];
+ break;
+ default:
+ }
+#endif
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+
+ result = bootrom_read(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
+ [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2));
+
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+
+ return result;
+}
+
+void exar7250_write(struct channel *channel, u32 reg, u32 val)
+{
+ unsigned long flags;
+
+ val &= 0xff;
+ channel->framer_regs[reg] = val;
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+
+ bootrom_write(channel, cpld_reg_map[SBE_2T3E3_CPLD_REG_FRAMER_BASE_ADDRESS]
+ [channel->h.slot] + (t3e3_framer_reg_map[reg] << 2), val);
+
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+}
+
+
+/****************************************
+ * Access to LIU
+ ****************************************/
+
+u32 exar7300_read(struct channel *channel, u32 reg)
+{
+ unsigned long addr = channel->card->bootrom_addr, flags;
+ u32 i, val;
+
+#if 0
+ switch (reg) {
+ case SBE_2T3E3_LIU_REG_REG1:
+ case SBE_2T3E3_LIU_REG_REG2:
+ case SBE_2T3E3_LIU_REG_REG3:
+ case SBE_2T3E3_LIU_REG_REG4:
+ return channel->liu_regs[reg];
+ break;
+ default:
+ }
+#endif
+
+ /* select correct Serial Chip */
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
+ cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
+
+ /* select reading from Serial I/O Bus */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+
+ /* select read operation */
+ serialrom_write_bit(channel, 1);
+
+ /* Exar7300 register address is 4 bit long */
+ reg = t3e3_liu_reg_map[reg];
+ for (i = 0; i < 4; i++, reg >>= 1) /* 4 bits of SerialROM address */
+ serialrom_write_bit(channel, reg & 1);
+ for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
+ serialrom_write_bit(channel, 0);
+
+ val = 0; /* Exar7300 register value is 5 bit long */
+ for (i = 0; i < 8; i++) /* 8 bits of SerialROM value */
+ val += (serialrom_read_bit(channel) << i);
+
+ /* Reset 21143's CSR9 */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_READ_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
+
+ /* Unselect Serial Chip */
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
+
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+
+ return val;
+}
+
+void exar7300_write(struct channel *channel, u32 reg, u32 val)
+{
+ unsigned long addr = channel->card->bootrom_addr, flags;
+ u32 i;
+
+ channel->liu_regs[reg] = val;
+
+ /* select correct Serial Chip */
+
+ spin_lock_irqsave(&channel->card->bootrom_lock, flags);
+
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT,
+ cpld_val_map[SBE_2T3E3_CPLD_VAL_LIU_SELECT][channel->h.slot]);
+
+ /* select writting to Serial I/O Bus */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+
+ /* select write operation */
+ serialrom_write_bit(channel, 0);
+
+ /* Exar7300 register address is 4 bit long */
+ reg = t3e3_liu_reg_map[reg];
+ for (i = 0; i < 4; i++) { /* 4 bits */
+ serialrom_write_bit(channel, reg & 1);
+ reg >>= 1;
+ }
+ for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM address */
+ serialrom_write_bit(channel, 0);
+
+ /* Exar7300 register value is 5 bit long */
+ for (i = 0; i < 5; i++) {
+ serialrom_write_bit(channel, val & 1);
+ val >>= 1;
+ }
+ for (i = 0; i < 3; i++) /* remaining 3 bits of SerialROM value */
+ serialrom_write_bit(channel, 0);
+
+ /* Reset 21143_CSR9 */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT,
+ SBE_2T3E3_21143_VAL_WRITE_OPERATION |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_SELECT |
+ SBE_2T3E3_21143_VAL_SERIAL_ROM_CHIP_SELECT); /* clock low */
+ dc_write(addr, SBE_2T3E3_21143_REG_BOOT_ROM_SERIAL_ROM_AND_MII_MANAGEMENT, 0);
+
+ /* Unselect Serial Chip */
+ cpld_write_nolock(channel, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, 0);
+
+ spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
+}
diff --git a/drivers/staging/sbe-2t3e3/main.c b/drivers/staging/sbe-2t3e3/main.c
new file mode 100644
index 000000000000..f3dbef6b0eef
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/main.c
@@ -0,0 +1,171 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include "2t3e3.h"
+
+void t3e3_init(struct channel *sc)
+{
+ cpld_init(sc);
+ dc_reset(sc);
+ dc_init(sc);
+ exar7250_init(sc);
+ exar7300_init(sc);
+}
+
+int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct channel *sc = dev_to_priv(dev);
+ u32 current_write, last_write;
+ unsigned long flags;
+ struct sk_buff *skb2;
+
+ if (skb == NULL) {
+ sc->s.out_errors++;
+ return 0;
+ }
+
+ if (sc->p.transmitter_on != SBE_2T3E3_ON) {
+ sc->s.out_errors++;
+ sc->s.out_dropped++;
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
+ if (sc->s.OOF && sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
+ sc->s.out_dropped++;
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
+ spin_lock_irqsave(&sc->ether.tx_lock, flags);
+
+ current_write = sc->ether.tx_ring_current_write;
+ for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
+ if (skb2->len) {
+ if ((sc->ether.tx_ring[current_write].tdes1 &
+ SBE_2T3E3_TX_DESC_BUFFER_1_SIZE) > 0)
+ break;
+ current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
+ /*
+ * Leave at least 1 tx desc free so that dc_intr_tx() can
+ * identify empty list
+ */
+ if (current_write == sc->ether.tx_ring_current_read)
+ break;
+ }
+ }
+ if (skb2 != NULL) {
+ netif_stop_queue(sc->dev);
+ sc->ether.tx_full = 1;
+ dev_dbg(&sc->pdev->dev, "SBE 2T3E3: out of descriptors\n");
+ spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ current_write = last_write = sc->ether.tx_ring_current_write;
+ dev_dbg(&sc->pdev->dev, "sending mbuf (current_write = %d)\n",
+ current_write);
+
+ for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
+ if (skb2->len) {
+ dev_dbg(&sc->pdev->dev,
+ "sending mbuf (len = %d, next = %p)\n",
+ skb2->len, NULL);
+
+ sc->ether.tx_free_cnt--;
+ sc->ether.tx_ring[current_write].tdes0 = 0;
+ sc->ether.tx_ring[current_write].tdes1 &=
+ SBE_2T3E3_TX_DESC_END_OF_RING |
+ SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
+/* DISABLE_PADDING sometimes gets lost somehow, hands off... */
+ sc->ether.tx_ring[current_write].tdes1 |=
+ SBE_2T3E3_TX_DESC_DISABLE_PADDING | skb2->len;
+
+ if (current_write == sc->ether.tx_ring_current_write) {
+ sc->ether.tx_ring[current_write].tdes1 |=
+ SBE_2T3E3_TX_DESC_FIRST_SEGMENT;
+ } else {
+ sc->ether.tx_ring[current_write].tdes0 =
+ SBE_2T3E3_TX_DESC_21143_OWN;
+ }
+
+ sc->ether.tx_ring[current_write].tdes2 = virt_to_phys(skb2->data);
+ sc->ether.tx_data[current_write] = NULL;
+
+ last_write = current_write;
+ current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
+ }
+ }
+
+ sc->ether.tx_data[last_write] = skb;
+ sc->ether.tx_ring[last_write].tdes1 |=
+ SBE_2T3E3_TX_DESC_LAST_SEGMENT |
+ SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION;
+ sc->ether.tx_ring[sc->ether.tx_ring_current_write].tdes0 |=
+ SBE_2T3E3_TX_DESC_21143_OWN;
+ sc->ether.tx_ring_current_write = current_write;
+
+ dev_dbg(&sc->pdev->dev, "txput: tdes0 = %08X tdes1 = %08X\n",
+ sc->ether.tx_ring[last_write].tdes0,
+ sc->ether.tx_ring[last_write].tdes1);
+
+ dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND,
+ 0xffffffff);
+
+ spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
+ return 0;
+}
+
+
+void t3e3_read_card_serial_number(struct channel *sc)
+{
+ u32 i;
+
+ for (i = 0; i < 3; i++)
+ sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i);
+
+ printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
+ sc->ether.card_serial_number[0], sc->ether.card_serial_number[1],
+ sc->ether.card_serial_number[2]);
+}
+
+/*
+ bit 0 led1 (green)
+ bit 1 led1 (yellow)
+
+ bit 2 led2 (green)
+ bit 3 led2 (yellow)
+
+ bit 4 led3 (green)
+ bit 5 led3 (yellow)
+
+ bit 6 led4 (green)
+ bit 7 led4 (yellow)
+*/
+
+void update_led(struct channel *sc, int blinker)
+{
+ int leds;
+ if (sc->s.LOS)
+ leds = 0; /* led1 = off */
+ else if (sc->s.OOF)
+ leds = 2; /* led1 = yellow */
+ else if ((blinker & 1) && sc->rcv_count) {
+ leds = 0; /* led1 = off */
+ sc->rcv_count = 0;
+ } else
+ leds = 1; /* led1 = green */
+ cpld_write(sc, SBE_2T3E3_CPLD_REG_LEDR, leds);
+ sc->leds = leds;
+}
diff --git a/drivers/staging/sbe-2t3e3/maps.c b/drivers/staging/sbe-2t3e3/maps.c
new file mode 100644
index 000000000000..7084fbe7b794
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/maps.c
@@ -0,0 +1,104 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/kernel.h>
+#include "2t3e3.h"
+
+const u32 cpld_reg_map[][2] =
+{
+ { 0x0000, 0x0080 }, /* 0 - Port Control Register A (PCRA) */
+ { 0x0004, 0x0084 }, /* 1 - Port Control Register B (PCRB) */
+ { 0x0008, 0x0088 }, /* 2 - LCV Count Register (PLCR) */
+ { 0x000c, 0x008c }, /* 3 - LCV Threshold register (PLTR) */
+ { 0x0010, 0x0090 }, /* 4 - Payload Fill Register (PPFR) */
+ { 0x0200, 0x0200 }, /* 5 - Board ID / FPGA Programming Status Register */
+ { 0x0204, 0x0204 }, /* 6 - FPGA Version Register */
+ { 0x0800, 0x1000 }, /* 7 - Framer Registers Base Address */
+ { 0x2000, 0x2000 }, /* 8 - Serial Chip Select Register */
+ { 0x2004, 0x2004 }, /* 9 - Static Reset Register */
+ { 0x2008, 0x2008 }, /* 10 - Pulse Reset Register */
+ { 0x200c, 0x200c }, /* 11 - FPGA Reconfiguration Register */
+ { 0x2010, 0x2014 }, /* 12 - LED Register (LEDR) */
+ { 0x2018, 0x201c }, /* 13 - LIU Control and Status Register (PISCR) */
+ { 0x2020, 0x2024 }, /* 14 - Interrupt Enable Register (PIER) */
+ { 0x0068, 0x00e8 }, /* 15 - Port Control Register C (PCRC) */
+ { 0x006c, 0x00ec }, /* 16 - Port Bandwidth Start (PBWF) */
+ { 0x0070, 0x00f0 }, /* 17 - Port Bandwidth Stop (PBWL) */
+};
+
+const u32 cpld_val_map[][2] =
+{
+ { 0x01, 0x02 }, /* LIU1 / LIU2 select for Serial Chip Select */
+ { 0x04, 0x08 }, /* DAC1 / DAC2 select for Serial Chip Select */
+ { 0x00, 0x04 }, /* LOOP1 / LOOP2 - select of loop timing source */
+ { 0x01, 0x02 } /* PORT1 / PORT2 - select LIU and Framer for reset */
+};
+
+const u32 t3e3_framer_reg_map[] = {
+ 0x00, /* 0 - OPERATING_MODE */
+ 0x01, /* 1 - IO_CONTROL */
+ 0x04, /* 2 - BLOCK_INTERRUPT_ENABLE */
+ 0x05, /* 3 - BLOCK_INTERRUPT_STATUS */
+ 0x10, /* 4 - T3_RX_CONFIGURATION_STATUS, E3_RX_CONFIGURATION_STATUS_1 */
+ 0x11, /* 5 - T3_RX_STATUS, E3_RX_CONFIGURATION_STATUS_2 */
+ 0x12, /* 6 - T3_RX_INTERRUPT_ENABLE, E3_RX_INTERRUPT_ENABLE_1 */
+ 0x13, /* 7 - T3_RX_INTERRUPT_STATUS, E3_RX_INTERRUPT_ENABLE_2 */
+ 0x14, /* 8 - T3_RX_SYNC_DETECT_ENABLE, E3_RX_INTERRUPT_STATUS_1 */
+ 0x15, /* 9 - E3_RX_INTERRUPT_STATUS_2 */
+ 0x16, /* 10 - T3_RX_FEAC */
+ 0x17, /* 11 - T3_RX_FEAC_INTERRUPT_ENABLE_STATUS */
+ 0x18, /* 12 - T3_RX_LAPD_CONTROL, E3_RX_LAPD_CONTROL */
+ 0x19, /* 13 - T3_RX_LAPD_STATUS, E3_RX_LAPD_STATUS */
+ 0x1a, /* 14 - E3_RX_NR_BYTE, E3_RX_SERVICE_BITS */
+ 0x1b, /* 15 - E3_RX_GC_BYTE */
+ 0x30, /* 16 - T3_TX_CONFIGURATION, E3_TX_CONFIGURATION */
+ 0x31, /* 17 - T3_TX_FEAC_CONFIGURATION_STATUS */
+ 0x32, /* 18 - T3_TX_FEAC */
+ 0x33, /* 19 - T3_TX_LAPD_CONFIGURATION, E3_TX_LAPD_CONFIGURATION */
+ 0x34, /* 20 - T3_TX_LAPD_STATUS, E3_TX_LAPD_STATUS_INTERRUPT */
+ 0x35, /* 21 - T3_TX_MBIT_MASK, E3_TX_GC_BYTE, E3_TX_SERVICE_BITS */
+ 0x36, /* 22 - T3_TX_FBIT_MASK, E3_TX_MA_BYTE */
+ 0x37, /* 23 - T3_TX_FBIT_MASK_2, E3_TX_NR_BYTE */
+ 0x38, /* 24 - T3_TX_FBIT_MASK_3 */
+ 0x48, /* 25 - E3_TX_FA1_ERROR_MASK, E3_TX_FAS_ERROR_MASK_UPPER */
+ 0x49, /* 26 - E3_TX_FA2_ERROR_MASK, E3_TX_FAS_ERROR_MASK_LOWER */
+ 0x4a, /* 27 - E3_TX_BIP8_MASK, E3_TX_BIP4_MASK */
+ 0x50, /* 28 - PMON_LCV_EVENT_COUNT_MSB */
+ 0x51, /* 29 - PMON_LCV_EVENT_COUNT_LSB */
+ 0x52, /* 30 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_MSB */
+ 0x53, /* 31 - PMON_FRAMING_BIT_ERROR_EVENT_COUNT_LSB */
+ 0x54, /* 32 - PMON_PARITY_ERROR_EVENT_COUNT_MSB */
+ 0x55, /* 33 - PMON_PARITY_ERROR_EVENT_COUNT_LSB */
+ 0x56, /* 34 - PMON_FEBE_EVENT_COUNT_MSB */
+ 0x57, /* 35 - PMON_FEBE_EVENT_COUNT_LSB */
+ 0x58, /* 36 - PMON_CP_BIT_ERROR_EVENT_COUNT_MSB */
+ 0x59, /* 37 - PMON_CP_BIT_ERROR_EVENT_COUNT_LSB */
+ 0x6c, /* 38 - PMON_HOLDING_REGISTER */
+ 0x6d, /* 39 - ONE_SECOND_ERROR_STATUS */
+ 0x6e, /* 40 - LCV_ONE_SECOND_ACCUMULATOR_MSB */
+ 0x6f, /* 41 - LCV_ONE_SECOND_ACCUMULATOR_LSB */
+ 0x70, /* 42 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
+ 0x71, /* 43 - FRAME_PARITY_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
+ 0x72, /* 44 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_MSB */
+ 0x73, /* 45 - FRAME_CP_BIT_ERROR_ONE_SECOND_ACCUMULATOR_LSB */
+ 0x80, /* 46 - LINE_INTERFACE_DRIVE */
+ 0x81 /* 47 - LINE_INTERFACE_SCAN */
+};
+
+const u32 t3e3_liu_reg_map[] =
+{
+ 0x00, /* REG0 */
+ 0x01, /* REG1 */
+ 0x02, /* REG2 */
+ 0x03, /* REG3 */
+ 0x04 /* REG4 */
+};
diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c
new file mode 100644
index 000000000000..e87fe81f6bb3
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/module.c
@@ -0,0 +1,210 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/hdlc.h>
+#include <linux/if_arp.h>
+#include <linux/interrupt.h>
+#include "2t3e3.h"
+
+static void check_leds(unsigned long arg)
+{
+ struct card *card = (struct card *)arg;
+ struct channel *channel0 = &card->channels[0];
+ static int blinker;
+
+ update_led(channel0, ++blinker);
+ if (has_two_ports(channel0->pdev))
+ update_led(&card->channels[1], blinker);
+
+ card->timer.expires = jiffies + HZ / 10;
+ add_timer(&card->timer);
+}
+
+static void t3e3_remove_channel(struct channel *channel)
+{
+ struct pci_dev *pdev = channel->pdev;
+ struct net_device *dev = channel->dev;
+
+ /* system hangs if board asserts irq while module is unloaded */
+ cpld_stop_intr(channel);
+ free_irq(dev->irq, dev);
+ dc_drop_descriptor_list(channel);
+ unregister_hdlc_device(dev);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *pdev, struct card *card)
+{
+ struct net_device *dev;
+ unsigned int val;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ err = pci_request_regions(pdev, "SBE 2T3E3");
+ if (err)
+ goto disable;
+
+ dev = alloc_hdlcdev(channel);
+ if (!dev) {
+ printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
+ goto free_regions;
+ }
+
+ t3e3_sc_init(channel);
+ dev_to_priv(dev) = channel;
+
+ channel->pdev = pdev;
+ channel->dev = dev;
+ channel->card = card;
+ channel->addr = pci_resource_start(pdev, 0);
+ if (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)
+ channel->h.slot = 1;
+ else
+ channel->h.slot = 0;
+
+ if (setup_device(dev, channel))
+ goto free_regions;
+
+ pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
+ pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);
+
+ pci_read_config_byte(channel->pdev, PCI_CACHE_LINE_SIZE, &channel->h.cache_size);
+ pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
+ t3e3_init(channel);
+
+ if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) {
+ printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
+ goto free_regions;
+ }
+
+ pci_set_drvdata(pdev, channel);
+ return 0;
+
+free_regions:
+ pci_release_regions(pdev);
+disable:
+ pci_disable_device(pdev);
+ return err;
+}
+
+static void __devexit t3e3_remove_card(struct pci_dev *pdev)
+{
+ struct channel *channel0 = pci_get_drvdata(pdev);
+ struct card *card = channel0->card;
+
+ del_timer(&card->timer);
+ if (has_two_ports(channel0->pdev)) {
+ t3e3_remove_channel(&card->channels[1]);
+ pci_dev_put(card->channels[1].pdev);
+ }
+ t3e3_remove_channel(channel0);
+ kfree(card);
+}
+
+static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ /* pdev points to channel #0 */
+ struct pci_dev *pdev1 = NULL;
+ struct card *card;
+ int channels = 1, err;
+
+ if (has_two_ports(pdev)) {
+ while ((pdev1 = pci_get_subsys(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P1,
+ pdev1)))
+ if (pdev1->bus == pdev->bus &&
+ pdev1->devfn == pdev->devfn + 8 /* next device on the same bus */)
+ break; /* found the second channel */
+
+ if (!pdev1) {
+ printk(KERN_ERR "SBE 2T3E3" ": Can't find the second channel\n");
+ return -EFAULT;
+ }
+ channels = 2;
+ /* holds the reference for pdev1 */
+ }
+
+ card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel), GFP_KERNEL);
+ if (!card) {
+ printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
+ return -ENOBUFS;
+ }
+
+ spin_lock_init(&card->bootrom_lock);
+ card->bootrom_addr = pci_resource_start(pdev, 0);
+
+ err = t3e3_init_channel(&card->channels[0], pdev, card);
+ if (err)
+ goto free_card;
+
+ if (channels == 2) {
+ err = t3e3_init_channel(&card->channels[1], pdev1, card);
+ if (err) {
+ t3e3_remove_channel(&card->channels[0]);
+ goto free_card;
+ }
+ }
+
+ /* start LED timer */
+ init_timer(&card->timer);
+ card->timer.function = check_leds;
+ card->timer.expires = jiffies + HZ / 10;
+ card->timer.data = (unsigned long)card;
+ add_timer(&card->timer);
+ return 0;
+
+free_card:
+ kfree(card);
+ return err;
+}
+
+static struct pci_device_id t3e3_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_T3E3, 0, 0, 0 },
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ PCI_VENDOR_ID_SBE, PCI_SUBDEVICE_ID_SBE_2T3E3_P0, 0, 0, 0 },
+ /* channel 1 will be initialized after channel 0 */
+ { 0, }
+};
+
+static struct pci_driver t3e3_pci_driver = {
+ .name = "SBE T3E3",
+ .id_table = t3e3_pci_tbl,
+ .probe = t3e3_init_card,
+ .remove = t3e3_remove_card,
+};
+
+static int __init t3e3_init_module(void)
+{
+ return pci_register_driver(&t3e3_pci_driver);
+}
+
+static void __exit t3e3_cleanup_module(void)
+{
+ pci_unregister_driver(&t3e3_pci_driver);
+}
+
+module_init(t3e3_init_module);
+module_exit(t3e3_cleanup_module);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, t3e3_pci_tbl);
diff --git a/drivers/staging/sbe-2t3e3/netdev.c b/drivers/staging/sbe-2t3e3/netdev.c
new file mode 100644
index 000000000000..c7b5e8bb04ff
--- /dev/null
+++ b/drivers/staging/sbe-2t3e3/netdev.c
@@ -0,0 +1,142 @@
+/*
+ * SBE 2T3E3 synchronous serial card driver for Linux
+ *
+ * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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 code is based on a driver written by SBE Inc.
+ */
+
+#include <linux/capability.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/hdlc.h>
+#include <linux/if_arp.h>
+#include <linux/interrupt.h>
+#include "2t3e3.h"
+
+int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct channel *sc = dev_to_priv(dev);
+ int cmd_2t3e3, len, rlen;
+ t3e3_param_t param;
+ t3e3_resp_t resp;
+ void *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len);
+
+ if (cmd == SIOCWANDEV)
+ return hdlc_ioctl(dev, ifr, cmd);
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (cmd != SIOCDEVPRIVATE + 15)
+ return -EINVAL;
+
+ if (copy_from_user(&cmd_2t3e3, ifr->ifr_data, sizeof(cmd_2t3e3)))
+ return -EFAULT;
+ if (copy_from_user(&len, ifr->ifr_data + sizeof(cmd_2t3e3), sizeof(len)))
+ return -EFAULT;
+
+ if (len > sizeof(param))
+ return -EFAULT;
+
+ if (len)
+ if (copy_from_user(&param, data, len))
+ return -EFAULT;
+
+ t3e3_if_config(sc, cmd_2t3e3, (char *)&param, &resp, &rlen);
+
+ if (rlen)
+ if (copy_to_user(data, &resp, rlen))
+ return -EFAULT;
+
+ return 0;
+}
+
+static struct net_device_stats* t3e3_get_stats(struct net_device *dev)
+{
+ struct net_device_stats *nstats = &dev->stats;
+ struct channel *sc = dev_to_priv(dev);
+ t3e3_stats_t *stats = &sc->s;
+
+ memset(nstats, 0, sizeof(struct net_device_stats));
+ nstats->rx_packets = stats->in_packets;
+ nstats->tx_packets = stats->out_packets;
+ nstats->rx_bytes = stats->in_bytes;
+ nstats->tx_bytes = stats->out_bytes;
+
+ nstats->rx_errors = stats->in_errors;
+ nstats->tx_errors = stats->out_errors;
+ nstats->rx_crc_errors = stats->in_error_crc;
+
+
+ nstats->rx_dropped = stats->in_dropped;
+ nstats->tx_dropped = stats->out_dropped;
+ nstats->tx_carrier_errors = stats->out_error_lost_carr +
+ stats->out_error_no_carr;
+
+ return nstats;
+}
+
+int t3e3_open(struct net_device *dev)
+{
+ struct channel *sc = dev_to_priv(dev);
+ int ret = hdlc_open(dev);
+
+ if (ret)
+ return ret;
+
+ sc->r.flags |= SBE_2T3E3_FLAG_NETWORK_UP;
+ dc_start(dev_to_priv(dev));
+ netif_start_queue(dev);
+ try_module_get(THIS_MODULE);
+ return 0;
+}
+
+int t3e3_close(struct net_device *dev)
+{
+ struct channel *sc = dev_to_priv(dev);
+ hdlc_close(dev);
+ netif_stop_queue(dev);
+ dc_stop(sc);
+ sc->r.flags &= ~SBE_2T3E3_FLAG_NETWORK_UP;
+ module_put(THIS_MODULE);
+ return 0;
+}
+
+static int t3e3_attach(struct net_device *dev, unsigned short foo1,
+ unsigned short foo2)
+{
+ return 0;
+}
+
+static const struct net_device_ops t3e3_ops = {
+ .ndo_open = t3e3_open,
+ .ndo_stop = t3e3_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = t3e3_ioctl,
+ .ndo_get_stats = t3e3_get_stats,
+};
+
+int setup_device(struct net_device *dev, struct channel *sc)
+{
+ hdlc_device *hdlc = dev_to_hdlc(dev);
+ int retval;
+
+ dev->base_addr = pci_resource_start(sc->pdev, 0);
+ dev->irq = sc->pdev->irq;
+ dev->netdev_ops = &t3e3_ops;
+ dev->tx_queue_len = 100;
+ hdlc->xmit = t3e3_if_start_xmit;
+ hdlc->attach = t3e3_attach;
+ if ((retval = register_hdlc_device(dev))) {
+ dev_err(&sc->pdev->dev, "error registering HDLC device\n");
+ return retval;
+ }
+ return 0;
+}
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index beab400805af..ebdcc6f91fdc 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -515,14 +515,16 @@ struct adapter {
(largestat) += ((newstat) - (oldstat)); \
}
-#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+#if BITS_PER_LONG == 64
#define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \
0x00000000FFFFFFFF)
#define SLIC_GET_ADDR_HIGH(_addr) (u32)(((u64)(_addr) >> 32) & \
0x00000000FFFFFFFF)
-#else
-#define SLIC_GET_ADDR_LOW(_addr) (u32)_addr
+#elif BITS_PER_LONG == 32
+#define SLIC_GET_ADDR_LOW(_addr) (u32)(_addr)
#define SLIC_GET_ADDR_HIGH(_addr) (u32)0
+#else
+#error BITS_PER_LONG must be 32 or 64
#endif
#define FLUSH true
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index f8c4b127e83a..58ff1233270c 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -1099,19 +1099,17 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
struct slic_shmem *pshmem;
pshmem = (struct slic_shmem *)adapter->phys_shmem;
-#if defined(CONFIG_X86_64)
+#if BITS_PER_LONG == 64
slic_upr_queue_request(adapter,
SLIC_UPR_RLSR,
SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
0, 0);
-#elif defined(CONFIG_X86)
+#else
slic_upr_queue_request(adapter,
SLIC_UPR_RLSR,
(u32) &pshmem->linkstatus,
SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
-#else
- Stop Compilation;
#endif
return;
}
@@ -1327,7 +1325,7 @@ static ushort slic_eeprom_cksum(char *m, int len)
s_util.s = 0;
w = (u16 *)m;
-#ifdef CONFIG_X86_64
+#if BITS_PER_LONG == 64
w_int = (u32) ((ulong) w & 0x00000000FFFFFFFF);
#else
w_int = (u32) (w);
@@ -1439,12 +1437,16 @@ static int slic_rspqueue_init(struct adapter *adapter)
slic_rspqueue_free(adapter);
return -ENOMEM;
}
+ /* FIXME:
+ * do we really need this assertions (4K PAGE_SIZE aligned addr)? */
+#if 0
#ifndef CONFIG_X86_64
ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) ==
(u32) rspq->vaddr[i]);
ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) ==
(u32) rspq->paddr[i]);
#endif
+#endif
memset(rspq->vaddr[i], 0, PAGE_SIZE);
if (paddrh == 0) {
@@ -1473,13 +1475,13 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
return NULL;
buf = rspq->rspbuf;
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT((buf->status & 0xFFFFFFE0) == 0);
#endif
ASSERT(buf->hosthandle);
if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
rspq->rspbuf++;
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) ==
(u32) rspq->rspbuf);
#endif
@@ -1492,12 +1494,12 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
rspq->offset = 0;
rspq->rspbuf = (struct slic_rspbuf *)
rspq->vaddr[rspq->pageindex];
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) ==
(u32) rspq->rspbuf);
#endif
}
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf);
#endif
return buf;
@@ -1538,7 +1540,7 @@ static u32 *slic_cmdqmem_addpage(struct adapter *adapter)
&cmdqmem->dma_pages[cmdqmem->pagecnt]);
if (!pageaddr)
return NULL;
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
#endif
cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
@@ -1650,7 +1652,7 @@ static int slic_cmdq_init(struct adapter *adapter)
adapter->slic_handle_ix = 1;
for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
pageaddr = slic_cmdqmem_addpage(adapter);
-#ifndef CONFIG_X86_64
+#if BITS_PER_LONG == 32
ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
#endif
if (!pageaddr) {
@@ -2447,18 +2449,16 @@ static void slic_link_event_handler(struct adapter *adapter)
pshmem = (struct slic_shmem *)adapter->phys_shmem;
-#if defined(CONFIG_X86_64)
+#if BITS_PER_LONG == 64
status = slic_upr_request(adapter,
SLIC_UPR_RLSR,
SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
0, 0);
-#elif defined(CONFIG_X86)
+#else
status = slic_upr_request(adapter, SLIC_UPR_RLSR,
(u32) &pshmem->linkstatus, /* no 4GB wrap guaranteed */
0, 0, 0);
-#else
- Stop compilation;
#endif
ASSERT(status == 0);
}
@@ -2575,14 +2575,12 @@ static void slic_xmit_build_request(struct adapter *adapter,
ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr);
ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr);
ihcmd->u.slic_buffers.bufs[0].length = skb->len;
-#if defined(CONFIG_X86_64)
+#if BITS_PER_LONG == 64
hcmd->cmdsize = (u32) ((((u64)&ihcmd->u.slic_buffers.bufs[1] -
(u64) hcmd) + 31) >> 5);
-#elif defined(CONFIG_X86)
+#else
hcmd->cmdsize = ((((u32) &ihcmd->u.slic_buffers.bufs[1] -
(u32) hcmd) + 31) >> 5);
-#else
- Stop Compilation;
#endif
}
@@ -3078,16 +3076,14 @@ static int slic_if_init(struct adapter *adapter)
spin_lock_irqsave(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
-#if defined(CONFIG_X86_64)
+#if BITS_PER_LONG == 64
slic_reg32_write(&slic_regs->slic_addr_upper,
SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
slic_reg32_write(&slic_regs->slic_isp,
SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
-#elif defined(CONFIG_X86)
+#else
slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
-#else
- Stop Compilations
#endif
spin_unlock_irqrestore(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index f6b401c0ccc9..24f47d6388f4 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -848,7 +848,6 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
"Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n");
err = pci_enable_device(pdev); /* enable SMTC chip */
-
if (err)
return err;
err = -ENOMEM;
@@ -859,7 +858,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
sfb = smtc_alloc_fb_info(pdev, name);
if (!sfb)
- goto failed;
+ goto failed_free;
/* Jason (08/13/2009)
* Store fb_info to be further used when suspending and resuming
*/
@@ -917,7 +916,8 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
printk(KERN_INFO
"%s: unable to map memory mapped IO\n",
sfb->fb.fix.id);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto failed_fb;
}
/* set MCLK = 14.31818 * (0x16 / 0x2) */
@@ -951,8 +951,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
printk(KERN_INFO
"No valid Silicon Motion display chip was detected!\n");
- smtc_free_fb_info(sfb);
- return err;
+ goto failed_fb;
}
/* can support 32 bpp */
@@ -986,8 +985,12 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
smtc_unmap_smem(sfb);
smtc_unmap_mmio(sfb);
+failed_fb:
smtc_free_fb_info(sfb);
+failed_free:
+ pci_disable_device(pdev);
+
return err;
}
diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c
index 98c6739fc196..4a051cde55da 100644
--- a/drivers/staging/solo6x10/solo6010-core.c
+++ b/drivers/staging/solo6x10/solo6010-core.c
@@ -136,23 +136,26 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev,
int ret;
int sdram;
u8 chip_id;
-
- if ((solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL)) == NULL)
+ solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL);
+ if (solo_dev == NULL)
return -ENOMEM;
solo_dev->pdev = pdev;
spin_lock_init(&solo_dev->reg_io_lock);
pci_set_drvdata(pdev, solo_dev);
- if ((ret = pci_enable_device(pdev)))
+ ret = pci_enable_device(pdev);
+ if (ret)
goto fail_probe;
pci_set_master(pdev);
- if ((ret = pci_request_regions(pdev, SOLO6010_NAME)))
+ ret = pci_request_regions(pdev, SOLO6010_NAME);
+ if (ret)
goto fail_probe;
- if ((solo_dev->reg_base = pci_ioremap_bar(pdev, 0)) == NULL) {
+ solo_dev->reg_base = pci_ioremap_bar(pdev, 0);
+ if (solo_dev->reg_base == NULL) {
ret = -ENOMEM;
goto fail_probe;
}
@@ -198,7 +201,8 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev,
/* Handle this from the start */
solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR);
- if ((ret = solo_i2c_init(solo_dev)))
+ ret = solo_i2c_init(solo_dev);
+ if (ret)
goto fail_probe;
/* Setup the DMA engine */
@@ -210,28 +214,36 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev,
SOLO_DMA_CTRL_READ_CLK_SELECT |
SOLO_DMA_CTRL_LATENCY(1));
- if ((ret = solo_p2m_init(solo_dev)))
+ ret = solo_p2m_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_disp_init(solo_dev)))
+ ret = solo_disp_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_gpio_init(solo_dev)))
+ ret = solo_gpio_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_tw28_init(solo_dev)))
+ ret = solo_tw28_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_v4l2_init(solo_dev)))
+ ret = solo_v4l2_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_enc_init(solo_dev)))
+ ret = solo_enc_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_enc_v4l2_init(solo_dev)))
+ ret = solo_enc_v4l2_init(solo_dev);
+ if (ret)
goto fail_probe;
- if ((ret = solo_g723_init(solo_dev)))
+ ret = solo_g723_init(solo_dev);
+ if (ret)
goto fail_probe;
return 0;
diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c
index e82846c1d6c6..82fbcb845878 100644
--- a/drivers/staging/solo6x10/solo6010-g723.c
+++ b/drivers/staging/solo6x10/solo6010-g723.c
@@ -233,7 +233,7 @@ static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
solo_pcm->g723_buf, G723_PERIOD_BYTES);
if (err)
- return err;
+ return -EFAULT;
}
return 0;
diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c
index 2bb86fa9e9e8..cadd5120d575 100644
--- a/drivers/staging/solo6x10/solo6010-i2c.c
+++ b/drivers/staging/solo6x10/solo6010-i2c.c
@@ -284,7 +284,7 @@ int solo_i2c_init(struct solo6010_dev *solo_dev)
solo_dev->i2c_id = -1;
solo_dev->i2c_state = IIC_STATE_IDLE;
init_waitqueue_head(&solo_dev->i2c_wait);
- init_MUTEX(&solo_dev->i2c_sem);
+ sema_init(&solo_dev->i2c_sem, 1);
for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
struct i2c_adapter *adap = &solo_dev->i2c_adap[i];
diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c
index 1b81f069c7f5..7ed3ed4b8f7e 100644
--- a/drivers/staging/solo6x10/solo6010-p2m.c
+++ b/drivers/staging/solo6x10/solo6010-p2m.c
@@ -188,7 +188,7 @@ int solo_p2m_init(struct solo6010_dev *solo_dev)
for (i = 0; i < SOLO_NR_P2M; i++) {
p2m_dev = &solo_dev->p2m_dev[i];
- init_MUTEX(&p2m_dev->sem);
+ sema_init(&p2m_dev->sem, 1);
init_completion(&p2m_dev->completion);
solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i),
diff --git a/drivers/staging/spectra/Kconfig b/drivers/staging/spectra/Kconfig
index 5e2ffefb60af..4fc206484830 100644
--- a/drivers/staging/spectra/Kconfig
+++ b/drivers/staging/spectra/Kconfig
@@ -2,10 +2,11 @@
menuconfig SPECTRA
tristate "Denali Spectra Flash Translation Layer"
depends on BLOCK
+ depends on X86_MRST
default n
---help---
Enable the FTL pseudo-filesystem used with the NAND Flash
- controller on Intel Moorestown Platform to pretend to be a disk
+ controller on Intel Moorestown Platform to pretend to be a disk.
choice
prompt "Compile for"
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
index 44a7fbe7eccd..c7932da03c56 100644
--- a/drivers/staging/spectra/ffsport.c
+++ b/drivers/staging/spectra/ffsport.c
@@ -27,7 +27,7 @@
#include <linux/kthread.h>
#include <linux/log2.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
+#include <linux/slab.h>
/**** Helper functions used for Div, Remainder operation on u64 ****/
@@ -589,14 +589,16 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
return -ENOTTY;
}
+static DEFINE_MUTEX(ffsport_mutex);
+
int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
int ret;
- lock_kernel();
+ mutex_lock(&ffsport_mutex);
ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ffsport_mutex);
return ret;
}
diff --git a/drivers/staging/spectra/flash.h b/drivers/staging/spectra/flash.h
index 5ed05805cf65..e59cf4ede551 100644
--- a/drivers/staging/spectra/flash.h
+++ b/drivers/staging/spectra/flash.h
@@ -104,7 +104,7 @@ struct flash_cache_tag {
};
/*
- *Data structure for each list node of the managment table
+ *Data structure for each list node of the management table
* used for the Level 2 Cache. Each node maps one logical NAND block.
*/
struct spectra_l2_cache_list {
diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c
index 13c3ad2db394..0d647a8fd2b6 100644
--- a/drivers/staging/spectra/lld_nand.c
+++ b/drivers/staging/spectra/lld_nand.c
@@ -2411,13 +2411,15 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
csr_base = pci_resource_start(dev, 0);
if (!csr_base) {
printk(KERN_ERR "Spectra: pci_resource_start failed!\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto failed_req_csr;
}
csr_len = pci_resource_len(dev, 0);
if (!csr_len) {
printk(KERN_ERR "Spectra: pci_resource_len failed!\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto failed_req_csr;
}
ret = pci_request_regions(dev, SPECTRA_NAND_NAME);
@@ -2464,6 +2466,7 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
failed_remap_csr:
pci_release_regions(dev);
failed_req_csr:
+ pci_disable_device(dev);
return ret;
}
diff --git a/drivers/staging/ti-st/st.h b/drivers/staging/ti-st/st.h
index 9952579425b9..1b3060eb2921 100644
--- a/drivers/staging/ti-st/st.h
+++ b/drivers/staging/ti-st/st.h
@@ -80,5 +80,4 @@ struct st_proto_s {
extern long st_register(struct st_proto_s *);
extern long st_unregister(enum proto_type);
-extern struct platform_device *st_get_plat_device(void);
#endif /* ST_H */
diff --git a/drivers/staging/ti-st/st_core.c b/drivers/staging/ti-st/st_core.c
index 063c9b1db1ab..fad97d7f0421 100644
--- a/drivers/staging/ti-st/st_core.c
+++ b/drivers/staging/ti-st/st_core.c
@@ -38,7 +38,6 @@
#include "st_ll.h"
#include "st.h"
-#define VERBOSE
/* strings to be used for rfkill entries and by
* ST Core to be used for sysfs debug entry
*/
@@ -581,7 +580,7 @@ long st_register(struct st_proto_s *new_proto)
long err = 0;
unsigned long flags = 0;
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
pr_info("%s(%d) ", __func__, new_proto->type);
if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
|| new_proto->reg_complete_cb == NULL) {
@@ -686,9 +685,8 @@ long st_register(struct st_proto_s *new_proto)
default:
pr_err("%d protocol not supported",
new_proto->type);
- err = -EPROTONOSUPPORT;
- /* something wrong */
- break;
+ spin_unlock_irqrestore(&st_gdata->lock, flags);
+ return -EPROTONOSUPPORT;
}
st_gdata->list[new_proto->type] = new_proto;
st_gdata->protos_registered++;
@@ -713,7 +711,7 @@ long st_unregister(enum proto_type type)
pr_debug("%s: %d ", __func__, type);
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
if (type < ST_BT || type >= ST_MAX) {
pr_err(" protocol %d not supported", type);
return -EPROTONOSUPPORT;
@@ -767,7 +765,7 @@ long st_write(struct sk_buff *skb)
#endif
long len;
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
if (unlikely(skb == NULL || st_gdata == NULL
|| st_gdata->tty == NULL)) {
pr_err("data/tty unavailable to perform write");
@@ -818,7 +816,7 @@ static int st_tty_open(struct tty_struct *tty)
struct st_data_s *st_gdata;
pr_info("%s ", __func__);
- st_kim_ref(&st_gdata);
+ st_kim_ref(&st_gdata, 0);
st_gdata->tty = tty;
tty->disc_data = st_gdata;
diff --git a/drivers/staging/ti-st/st_core.h b/drivers/staging/ti-st/st_core.h
index e0c32d149f5f..8601320a679e 100644
--- a/drivers/staging/ti-st/st_core.h
+++ b/drivers/staging/ti-st/st_core.h
@@ -117,7 +117,7 @@ int st_core_init(struct st_data_s **);
void st_core_exit(struct st_data_s *);
/* ask for reference from KIM */
-void st_kim_ref(struct st_data_s **);
+void st_kim_ref(struct st_data_s **, int);
#define GPS_STUB_TEST
#ifdef GPS_STUB_TEST
diff --git a/drivers/staging/ti-st/st_kim.c b/drivers/staging/ti-st/st_kim.c
index b4a6c7fdc4e6..9e99463f76e8 100644
--- a/drivers/staging/ti-st/st_kim.c
+++ b/drivers/staging/ti-st/st_kim.c
@@ -72,11 +72,26 @@ const unsigned char *protocol_names[] = {
PROTO_ENTRY(ST_GPS, "GPS"),
};
+#define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */
+struct platform_device *st_kim_devices[MAX_ST_DEVICES];
/**********************************************************************/
/* internal functions */
/**
+ * st_get_plat_device -
+ * function which returns the reference to the platform device
+ * requested by id. As of now only 1 such device exists (id=0)
+ * the context requesting for reference can get the id to be
+ * requested by a. The protocol driver which is registering or
+ * b. the tty device which is opened.
+ */
+static struct platform_device *st_get_plat_device(int id)
+{
+ return st_kim_devices[id];
+}
+
+/**
* validate_firmware_response -
* function to return whether the firmware response was proper
* in case of error don't complete so that waiting for proper
@@ -353,7 +368,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state)
struct kim_data_s *kim_gdata;
pr_info(" %s ", __func__);
- kim_pdev = st_get_plat_device();
+ kim_pdev = st_get_plat_device(0);
kim_gdata = dev_get_drvdata(&kim_pdev->dev);
if (kim_gdata->gpios[type] == -1) {
@@ -574,12 +589,12 @@ static int kim_toggle_radio(void *data, bool blocked)
* This would enable multiple such platform devices to exist
* on a given platform
*/
-void st_kim_ref(struct st_data_s **core_data)
+void st_kim_ref(struct st_data_s **core_data, int id)
{
struct platform_device *pdev;
struct kim_data_s *kim_gdata;
/* get kim_gdata reference from platform device */
- pdev = st_get_plat_device();
+ pdev = st_get_plat_device(id);
kim_gdata = dev_get_drvdata(&pdev->dev);
*core_data = kim_gdata->core_data;
}
@@ -623,6 +638,7 @@ static int kim_probe(struct platform_device *pdev)
long *gpios = pdev->dev.platform_data;
struct kim_data_s *kim_gdata;
+ st_kim_devices[pdev->id] = pdev;
kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
if (!kim_gdata) {
pr_err("no mem to allocate");
diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
index 65671724e6f9..8082d5c7be48 100644
--- a/drivers/staging/tidspbridge/Makefile
+++ b/drivers/staging/tidspbridge/Makefile
@@ -1,11 +1,9 @@
obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o
libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o
-libservices = services/sync.o services/cfg.o \
- services/ntfy.o services/services.o
libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
core/tiomap3430_pwr.o core/tiomap_io.o \
- core/ue_deh.o core/wdt.o core/dsp-clock.o
+ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c
index bee2b23a09a1..662a5b5a58e3 100644
--- a/drivers/staging/tidspbridge/core/chnl_sm.c
+++ b/drivers/staging/tidspbridge/core/chnl_sm.c
@@ -54,7 +54,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/sync.h>
/* ----------------------------------- Bridge Driver */
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c
index 5b1a0c5bb143..46d17c777b88 100644
--- a/drivers/staging/tidspbridge/core/dsp-clock.c
+++ b/drivers/staging/tidspbridge/core/dsp-clock.c
@@ -25,7 +25,6 @@
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
-#include <dspbridge/cfg.h>
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>
#include "_tiomap.h"
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 02c660dbcf68..571864555ddd 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -36,7 +36,6 @@
#include <dspbridge/dbc.h>
/* Services Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/ntfy.h>
#include <dspbridge/sync.h>
diff --git a/drivers/staging/tidspbridge/services/sync.c b/drivers/staging/tidspbridge/core/sync.c
index 9010b37bf5b1..995986a9d03b 100644
--- a/drivers/staging/tidspbridge/services/sync.c
+++ b/drivers/staging/tidspbridge/core/sync.c
@@ -21,6 +21,7 @@
/* ----------------------------------- This */
#include <dspbridge/sync.h>
+#include <dspbridge/ntfy.h>
DEFINE_SPINLOCK(sync_lock);
@@ -102,3 +103,19 @@ func_end:
return status;
}
+/**
+ * dsp_notifier_event() - callback function to nofity events
+ * @this: pointer to itself struct notifier_block
+ * @event: event to be notified.
+ * @data: Currently not used.
+ *
+ */
+int dsp_notifier_event(struct notifier_block *this, unsigned long event,
+ void *data)
+{
+ struct ntfy_event *ne = container_of(this, struct ntfy_event,
+ noti_block);
+ if (ne->event & event)
+ sync_set_event(&ne->sync_obj);
+ return NOTIFY_OK;
+}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index f914829c70f5..f1e59e84ea38 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -30,7 +30,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/drv.h>
#include <dspbridge/sync.h>
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
index b789f8fdd89b..b9d07535ef71 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
@@ -16,9 +16,11 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+/* ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
-#include <dspbridge/cfg.h>
#include <dspbridge/drv.h>
#include <dspbridge/io_sm.h>
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
index 190c028afe9b..e78a7cd31526 100644
--- a/drivers/staging/tidspbridge/core/tiomap_io.c
+++ b/drivers/staging/tidspbridge/core/tiomap_io.c
@@ -27,7 +27,6 @@
#include <dspbridge/drv.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/wdt.h>
/* ----------------------------------- specific to this file */
diff --git a/drivers/staging/tidspbridge/gen/gb.c b/drivers/staging/tidspbridge/gen/gb.c
index 06eb3d361225..9f590230473b 100644
--- a/drivers/staging/tidspbridge/gen/gb.c
+++ b/drivers/staging/tidspbridge/gen/gb.c
@@ -15,7 +15,6 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#include <linux/types.h>
/* ----------------------------------- DSP/BIOS Bridge */
#include <linux/types.h>
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfg.h b/drivers/staging/tidspbridge/include/dspbridge/cfg.h
deleted file mode 100644
index 05a8999070f8..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/cfg.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * cfg.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * PM Configuration module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CFG_
-#define CFG_
-#include <dspbridge/host_os.h>
-#include <dspbridge/cfgdefs.h>
-
-/*
- * ======== cfg_exit ========
- * Purpose:
- * Discontinue usage of the CFG module.
- * Parameters:
- * Returns:
- * Requires:
- * cfg_init(void) was previously called.
- * Ensures:
- * Resources acquired in cfg_init(void) are freed.
- */
-extern void cfg_exit(void);
-
-/*
- * ======== cfg_get_auto_start ========
- * Purpose:
- * Retreive the autostart mask, if any, for this board.
- * Parameters:
- * dev_node_obj: Handle to the dev_node who's driver we are querying.
- * auto_start: Ptr to location for 32 bit autostart mask.
- * Returns:
- * 0: Success.
- * -EFAULT: dev_node_obj is invalid.
- * -ENODATA: Unable to retreive resource.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: *auto_start contains autostart mask for this devnode.
- */
-extern int cfg_get_auto_start(struct cfg_devnode *dev_node_obj,
- u32 *auto_start);
-
-/*
- * ======== cfg_get_cd_version ========
- * Purpose:
- * Retrieves the version of the PM Class Driver.
- * Parameters:
- * version: Ptr to u32 to contain version number upon return.
- * Returns:
- * 0: Success. version contains Class Driver version in
- * the form: 0xAABBCCDD where AABB is Major version and
- * CCDD is Minor.
- * -EPERM: Failure.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: Success.
- * else: *version is NULL.
- */
-extern int cfg_get_cd_version(u32 *version);
-
-/*
- * ======== cfg_get_dev_object ========
- * Purpose:
- * Retrieve the Device Object handle for a given devnode.
- * Parameters:
- * dev_node_obj: Platform's dev_node handle from which to retrieve
- * value.
- * value: Ptr to location to store the value.
- * Returns:
- * 0: Success.
- * -EFAULT: dev_node_obj is invalid or device_obj is invalid.
- * -ENODATA: The resource is not available.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: *value is set to the retrieved u32.
- * else: *value is set to 0L.
- */
-extern int cfg_get_dev_object(struct cfg_devnode *dev_node_obj,
- u32 *value);
-
-/*
- * ======== cfg_get_exec_file ========
- * Purpose:
- * Retreive the default executable, if any, for this board.
- * Parameters:
- * dev_node_obj: Handle to the dev_node who's driver we are querying.
- * buf_size: Size of buffer.
- * str_exec_file: Ptr to character buf to hold ExecFile.
- * Returns:
- * 0: Success.
- * -EFAULT: dev_node_obj is invalid or str_exec_file is invalid.
- * -ENODATA: The resource is not available.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: Not more than buf_size bytes were copied into str_exec_file,
- * and *str_exec_file contains default executable for this
- * devnode.
- */
-extern int cfg_get_exec_file(struct cfg_devnode *dev_node_obj,
- u32 buf_size, char *str_exec_file);
-
-/*
- * ======== cfg_get_object ========
- * Purpose:
- * Retrieve the Driver Object handle From the Registry
- * Parameters:
- * value: Ptr to location to store the value.
- * dw_type Type of Object to Get
- * Returns:
- * 0: Success.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: *value is set to the retrieved u32(non-Zero).
- * else: *value is set to 0L.
- */
-extern int cfg_get_object(u32 *value, u8 dw_type);
-
-/*
- * ======== cfg_get_perf_value ========
- * Purpose:
- * Retrieve a flag indicating whether PERF should log statistics for the
- * PM class driver.
- * Parameters:
- * enable_perf: Location to store flag. 0 indicates the key was
- * not found, or had a zero value. A nonzero value
- * means the key was found and had a nonzero value.
- * Returns:
- * Requires:
- * enable_perf != NULL;
- * Ensures:
- */
-extern void cfg_get_perf_value(bool *enable_perf);
-
-/*
- * ======== cfg_get_zl_file ========
- * Purpose:
- * Retreive the ZLFile, if any, for this board.
- * Parameters:
- * dev_node_obj: Handle to the dev_node who's driver we are querying.
- * buf_size: Size of buffer.
- * str_zl_file_name: Ptr to character buf to hold ZLFileName.
- * Returns:
- * 0: Success.
- * -EFAULT: str_zl_file_name is invalid or dev_node_obj is invalid.
- * -ENODATA: couldn't find the ZLFileName.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: Not more than buf_size bytes were copied into
- * str_zl_file_name, and *str_zl_file_name contains ZLFileName
- * for this devnode.
- */
-extern int cfg_get_zl_file(struct cfg_devnode *dev_node_obj,
- u32 buf_size, char *str_zl_file_name);
-
-/*
- * ======== cfg_init ========
- * Purpose:
- * Initialize the CFG module's private state.
- * Parameters:
- * Returns:
- * TRUE if initialized; FALSE if error occured.
- * Requires:
- * Ensures:
- * A requirement for each of the other public CFG functions.
- */
-extern bool cfg_init(void);
-
-/*
- * ======== cfg_set_dev_object ========
- * Purpose:
- * Store the Device Object handle for a given devnode.
- * Parameters:
- * dev_node_obj: Platform's dev_node handle we are storing value with.
- * value: Arbitrary value to store.
- * Returns:
- * 0: Success.
- * -EFAULT: dev_node_obj is invalid.
- * -EPERM: Internal Error.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: The Private u32 was successfully set.
- */
-extern int cfg_set_dev_object(struct cfg_devnode *dev_node_obj,
- u32 value);
-
-/*
- * ======== CFG_SetDrvObject ========
- * Purpose:
- * Store the Driver Object handle.
- * Parameters:
- * value: Arbitrary value to store.
- * dw_type Type of Object to Store
- * Returns:
- * 0: Success.
- * -EPERM: Internal Error.
- * Requires:
- * CFG initialized.
- * Ensures:
- * 0: The Private u32 was successfully set.
- */
-extern int cfg_set_object(u32 value, u8 dw_type);
-
-#endif /* CFG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
index f3650153ef35..c1f363ec9afa 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/drv.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h
@@ -193,7 +193,7 @@ struct process_context {
* Ensures:
* 0: - *drv_obj is a valid DRV interface to the device.
* - List of DevObject Created and Initialized.
- * - List of dev_node String created and intialized.
+ * - List of dev_node String created and initialized.
* - Registry is updated with the DRV Object.
* !0: DRV Object not created
* Details:
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgr.h b/drivers/staging/tidspbridge/include/dspbridge/mgr.h
index 99f7dc0116b5..e506c4d49472 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/mgr.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/mgr.h
@@ -192,7 +192,7 @@ extern int mgr_get_dcd_handle(struct mgr_object
* ======== mgr_init ========
* Purpose:
* Initialize MGR's private state, keeping a reference count on each
- * call. Intializes the DCD.
+ * call. Initializes the DCD.
* Parameters:
* Returns:
* TRUE if initialized; FALSE if error occured.
diff --git a/drivers/staging/tidspbridge/include/dspbridge/services.h b/drivers/staging/tidspbridge/include/dspbridge/services.h
deleted file mode 100644
index eb26c867c931..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/services.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * services.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Provide loading and unloading of SERVICES modules.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef SERVICES_
-#define SERVICES_
-
-#include <dspbridge/host_os.h>
-/*
- * ======== services_exit ========
- * Purpose:
- * Discontinue usage of module; free resources when reference count
- * reaches 0.
- * Parameters:
- * Returns:
- * Requires:
- * SERVICES initialized.
- * Ensures:
- * Resources used by module are freed when cRef reaches zero.
- */
-extern void services_exit(void);
-
-/*
- * ======== services_init ========
- * Purpose:
- * Initializes SERVICES modules.
- * Parameters:
- * Returns:
- * TRUE if all modules initialized; otherwise FALSE.
- * Requires:
- * Ensures:
- * SERVICES modules initialized.
- */
-extern bool services_init(void);
-
-#endif /* SERVICES_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/wdt.h b/drivers/staging/tidspbridge/include/dspbridge/wdt.h
index 4c00ba5fa5bf..36193db2e9a3 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/wdt.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/wdt.h
@@ -44,7 +44,7 @@ struct dsp_wdt_setting {
/**
* dsp_wdt_init() - initialize wdt3 module.
*
- * This function initilize to wdt3 module, so that
+ * This function initialize to wdt3 module, so that
* other wdt3 function can be used.
*/
int dsp_wdt_init(void);
diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c
index 90317b58f8eb..78b0d0f303d7 100644
--- a/drivers/staging/tidspbridge/pmgr/chnl.c
+++ b/drivers/staging/tidspbridge/pmgr/chnl.c
@@ -28,7 +28,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/sync.h>
/* ----------------------------------- Platform Manager */
diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c
index ce3dc8822afa..e3f77bd453f7 100644
--- a/drivers/staging/tidspbridge/pmgr/cmm.c
+++ b/drivers/staging/tidspbridge/pmgr/cmm.c
@@ -38,7 +38,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/list.h>
#include <dspbridge/sync.h>
#include <dspbridge/utildefs.h>
diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c
index 23406386f61a..878aa50718ee 100644
--- a/drivers/staging/tidspbridge/pmgr/dbll.c
+++ b/drivers/staging/tidspbridge/pmgr/dbll.c
@@ -1501,7 +1501,7 @@ static void release(struct dynamic_loader_initialize *this)
#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
/**
* find_symbol_context - Basic symbol context structure
- * @address: Symbol Adress
+ * @address: Symbol Address
* @offset_range: Offset range where the search for the DSP symbol
* started.
* @cur_best_offset: Best offset to start looking for the DSP symbol
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
index 4ddf03d3b1ab..132e960967b9 100644
--- a/drivers/staging/tidspbridge/pmgr/dev.c
+++ b/drivers/staging/tidspbridge/pmgr/dev.c
@@ -27,7 +27,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/ldr.h>
#include <dspbridge/list.h>
@@ -85,6 +84,11 @@ struct dev_object {
struct node_mgr *hnode_mgr;
};
+struct drv_ext {
+ struct list_head link;
+ char sz_string[MAXREGPATHLENGTH];
+};
+
/* ----------------------------------- Globals */
static u32 refs; /* Module reference count */
@@ -143,6 +147,7 @@ int dev_create_device(struct dev_object **device_obj,
struct io_attrs io_mgr_attrs;
u32 num_windows;
struct drv_object *hdrv_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
int status = 0;
DBC_REQUIRE(refs > 0);
DBC_REQUIRE(device_obj != NULL);
@@ -158,10 +163,15 @@ int dev_create_device(struct dev_object **device_obj,
/* Get the Bridge driver interface functions */
bridge_drv_entry(&drv_fxns, driver_file_name);
- if (cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT)) {
- /* don't propogate CFG errors from this PROC function */
+
+ /* Retrieve the Object handle from the driver data */
+ if (drv_datap && drv_datap->drv_object) {
+ hdrv_obj = drv_datap->drv_object;
+ } else {
status = -EPERM;
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
}
+
/* Create the device object, and pass a handle to the Bridge driver for
* storage. */
if (!status) {
@@ -812,18 +822,31 @@ int dev_remove_device(struct cfg_devnode *dev_node_obj)
{
struct dev_object *hdev_obj; /* handle to device object */
int status = 0;
- struct dev_object *dev_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
+
+ if (!drv_datap)
+ status = -ENODATA;
+
+ if (!dev_node_obj)
+ status = -EFAULT;
/* Retrieve the device object handle originaly stored with
* the dev_node: */
- status = cfg_get_dev_object(dev_node_obj, (u32 *) &hdev_obj);
if (!status) {
- /* Remove the Processor List */
- dev_obj = (struct dev_object *)hdev_obj;
- /* Destroy the device object. */
- status = dev_destroy_device(hdev_obj);
+ /* check the device string and then store dev object */
+ if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string,
+ "TIOMAP1510")) {
+ hdev_obj = drv_datap->dev_object;
+ /* Destroy the device object. */
+ status = dev_destroy_device(hdev_obj);
+ } else {
+ status = -EPERM;
+ }
}
+ if (status)
+ pr_err("%s: Failed, status 0x%x\n", __func__, status);
+
return status;
}
@@ -874,6 +897,7 @@ int dev_start_device(struct cfg_devnode *dev_node_obj)
char bridge_file_name[CFG_MAXSEARCHPATHLEN] = "UMA";
int status;
struct mgr_object *hmgr_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(refs > 0);
@@ -882,24 +906,27 @@ int dev_start_device(struct cfg_devnode *dev_node_obj)
dev_node_obj);
if (!status) {
/* Store away the hdev_obj with the DEVNODE */
- status = cfg_set_dev_object(dev_node_obj, (u32) hdev_obj);
+ if (!drv_datap || !dev_node_obj) {
+ status = -EFAULT;
+ pr_err("%s: Failed, status 0x%x\n", __func__, status);
+ } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) {
+ drv_datap->dev_object = (void *) hdev_obj;
+ }
+ if (!status) {
+ /* Create the Manager Object */
+ status = mgr_create(&hmgr_obj, dev_node_obj);
+ if (status && !(strcmp((char *)dev_node_obj,
+ "TIOMAP1510"))) {
+ /* Ensure the device extension is NULL */
+ drv_datap->dev_object = NULL;
+ }
+ }
if (status) {
/* Clean up */
dev_destroy_device(hdev_obj);
hdev_obj = NULL;
}
}
- if (!status) {
- /* Create the Manager Object */
- status = mgr_create(&hmgr_obj, dev_node_obj);
- }
- if (status) {
- if (hdev_obj)
- dev_destroy_device(hdev_obj);
-
- /* Ensure the device extension is NULL */
- cfg_set_dev_object(dev_node_obj, 0L);
- }
return status;
}
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
index 7b42f72a97b2..faf8304f55e2 100644
--- a/drivers/staging/tidspbridge/pmgr/dspapi.c
+++ b/drivers/staging/tidspbridge/pmgr/dspapi.c
@@ -28,9 +28,7 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/ntfy.h>
-#include <dspbridge/services.h>
/* ----------------------------------- Platform Manager */
#include <dspbridge/chnl.h>
@@ -381,8 +379,8 @@ int api_init_complete2(void)
int status = 0;
struct cfg_devnode *dev_node;
struct dev_object *hdev_obj;
+ struct drv_data *drv_datap;
u8 dev_type;
- u32 tmp;
DBC_REQUIRE(api_c_refs > 0);
@@ -397,10 +395,12 @@ int api_init_complete2(void)
if (dev_get_dev_type(hdev_obj, &dev_type))
continue;
- if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT))
- if (cfg_get_auto_start(dev_node, &tmp) == 0
- && tmp)
+ if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
+ drv_datap = dev_get_drvdata(bridge);
+
+ if (drv_datap && drv_datap->base_img)
proc_auto_start(dev_node, hdev_obj);
+ }
}
return status;
@@ -872,7 +872,11 @@ u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
/* number of elements in the envp array including NULL */
count = 0;
do {
- get_user(temp, args->args_proc_load.user_envp + count);
+ if (get_user(temp,
+ args->args_proc_load.user_envp + count)) {
+ status = -EFAULT;
+ goto func_cont;
+ }
count++;
} while (temp);
envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c
index 7970fe55648e..20cbb9fe40c2 100644
--- a/drivers/staging/tidspbridge/pmgr/io.c
+++ b/drivers/staging/tidspbridge/pmgr/io.c
@@ -26,9 +26,6 @@
/* ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
-
/* ----------------------------------- Platform Manager */
#include <dspbridge/dev.h>
diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c
index f71e8606f953..3581a55ed4dd 100644
--- a/drivers/staging/tidspbridge/rmgr/dbdcd.c
+++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c
@@ -487,6 +487,10 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
/* Allocate zeroed buffer. */
psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
+ if (psz_coff_buf == NULL) {
+ status = -ENOMEM;
+ goto func_end;
+ }
#ifdef _DB_TIOMAP
if (strstr(dcd_key->path, "iva") == NULL) {
/* Locate section by objectID and read its content. */
@@ -571,6 +575,10 @@ int dcd_get_objects(struct dcd_manager *hdcd_mgr,
/* Allocate zeroed buffer. */
psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
+ if (psz_coff_buf == NULL) {
+ status = -ENOMEM;
+ goto func_cont;
+ }
#ifdef _DB_TIOMAP
if (strstr(sz_coff_path, "iva") == NULL) {
/* Locate section by objectID and read its content. */
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index 8a8dea6efeda..81b1b9013550 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -27,7 +27,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/list.h>
/* ----------------------------------- This */
@@ -309,6 +308,7 @@ int drv_create(struct drv_object **drv_obj)
{
int status = 0;
struct drv_object *pdrv_object = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(drv_obj != NULL);
DBC_REQUIRE(refs > 0);
@@ -335,9 +335,16 @@ int drv_create(struct drv_object **drv_obj)
} else {
status = -ENOMEM;
}
- /* Store the DRV Object in the Registry */
- if (!status)
- status = cfg_set_object((u32) pdrv_object, REG_DRV_OBJECT);
+ /* Store the DRV Object in the driver data */
+ if (!status) {
+ if (drv_datap) {
+ drv_datap->drv_object = (void *)pdrv_object;
+ } else {
+ status = -EPERM;
+ pr_err("%s: Failed to store DRV object\n", __func__);
+ }
+ }
+
if (!status) {
*drv_obj = pdrv_object;
} else {
@@ -374,6 +381,7 @@ int drv_destroy(struct drv_object *driver_obj)
{
int status = 0;
struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(refs > 0);
DBC_REQUIRE(pdrv_object);
@@ -386,8 +394,13 @@ int drv_destroy(struct drv_object *driver_obj)
kfree(pdrv_object->dev_list);
kfree(pdrv_object->dev_node_string);
kfree(pdrv_object);
- /* Update the DRV Object in Registry to be 0 */
- (void)cfg_set_object(0, REG_DRV_OBJECT);
+ /* Update the DRV Object in the driver data */
+ if (drv_datap) {
+ drv_datap->drv_object = NULL;
+ } else {
+ status = -EPERM;
+ pr_err("%s: Failed to store DRV object\n", __func__);
+ }
return status;
}
@@ -438,11 +451,15 @@ u32 drv_get_first_dev_object(void)
{
u32 dw_dev_object = 0;
struct drv_object *pdrv_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
- if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+ if (drv_datap && drv_datap->drv_object) {
+ pdrv_obj = drv_datap->drv_object;
if ((pdrv_obj->dev_list != NULL) &&
!LST_IS_EMPTY(pdrv_obj->dev_list))
dw_dev_object = (u32) lst_first(pdrv_obj->dev_list);
+ } else {
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
}
return dw_dev_object;
@@ -458,14 +475,17 @@ u32 drv_get_first_dev_extension(void)
{
u32 dw_dev_extension = 0;
struct drv_object *pdrv_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
- if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
-
+ if (drv_datap && drv_datap->drv_object) {
+ pdrv_obj = drv_datap->drv_object;
if ((pdrv_obj->dev_node_string != NULL) &&
!LST_IS_EMPTY(pdrv_obj->dev_node_string)) {
dw_dev_extension =
(u32) lst_first(pdrv_obj->dev_node_string);
}
+ } else {
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
}
return dw_dev_extension;
@@ -482,18 +502,22 @@ u32 drv_get_next_dev_object(u32 hdev_obj)
{
u32 dw_next_dev_object = 0;
struct drv_object *pdrv_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(hdev_obj != 0);
- if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
-
+ if (drv_datap && drv_datap->drv_object) {
+ pdrv_obj = drv_datap->drv_object;
if ((pdrv_obj->dev_list != NULL) &&
!LST_IS_EMPTY(pdrv_obj->dev_list)) {
dw_next_dev_object = (u32) lst_next(pdrv_obj->dev_list,
(struct list_head *)
hdev_obj);
}
+ } else {
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
}
+
return dw_next_dev_object;
}
@@ -509,16 +533,20 @@ u32 drv_get_next_dev_extension(u32 dev_extension)
{
u32 dw_dev_extension = 0;
struct drv_object *pdrv_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(dev_extension != 0);
- if (!cfg_get_object((u32 *) &pdrv_obj, REG_DRV_OBJECT)) {
+ if (drv_datap && drv_datap->drv_object) {
+ pdrv_obj = drv_datap->drv_object;
if ((pdrv_obj->dev_node_string != NULL) &&
!LST_IS_EMPTY(pdrv_obj->dev_node_string)) {
dw_dev_extension =
(u32) lst_next(pdrv_obj->dev_node_string,
(struct list_head *)dev_extension);
}
+ } else {
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
}
return dw_dev_extension;
@@ -616,6 +644,7 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
int status = 0;
struct drv_object *pdrv_object;
struct drv_ext *pszdev_node;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(dw_context != 0);
DBC_REQUIRE(dev_node_strg != NULL);
@@ -626,7 +655,11 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
* list.
*/
- status = cfg_get_object((u32 *) &pdrv_object, REG_DRV_OBJECT);
+ if (!drv_datap || !drv_datap->drv_object)
+ status = -ENODATA;
+ else
+ pdrv_object = drv_datap->drv_object;
+
if (!status) {
pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL);
if (pszdev_node) {
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index 7ee89492a755..24576c9036c7 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -39,7 +39,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/services.h>
#include <dspbridge/clk.h>
#include <dspbridge/sync.h>
@@ -54,7 +53,6 @@
/* ----------------------------------- This */
#include <drv_interface.h>
-#include <dspbridge/cfg.h>
#include <dspbridge/resourcecleanup.h>
#include <dspbridge/chnl.h>
#include <dspbridge/proc.h>
@@ -144,6 +142,7 @@ static const struct file_operations bridge_fops = {
.release = bridge_release,
.unlocked_ioctl = bridge_ioctl,
.mmap = bridge_mmap,
+ .llseek = noop_llseek,/* no read or write fn */
};
#ifdef CONFIG_PM
@@ -271,7 +270,6 @@ static int omap3_bridge_startup(struct platform_device *pdev)
#endif
dsp_clk_init();
- services_init();
drv_datap = kzalloc(sizeof(struct drv_data), GFP_KERNEL);
if (!drv_datap) {
@@ -328,7 +326,6 @@ err1:
CPUFREQ_TRANSITION_NOTIFIER);
#endif
dsp_clk_exit();
- services_exit();
return err;
}
@@ -394,11 +391,14 @@ static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
dev_t devno;
bool ret;
int status = 0;
- void *hdrv_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
- status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
- if (status)
+ /* Retrieve the Object handle from the driver data */
+ if (!drv_datap || !drv_datap->drv_object) {
+ status = -ENODATA;
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
goto func_cont;
+ }
#ifdef CONFIG_TIDSPBRIDGE_DVFS
if (cpufreq_unregister_notifier(&iva_clk_notifier,
@@ -418,7 +418,6 @@ func_cont:
mem_ext_phys_pool_release();
dsp_clk_exit();
- services_exit();
devno = MKDEV(driver_major, 0);
cdev_del(&bridge_cdev);
diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c
index 714f348f526a..7a6fc737872c 100644
--- a/drivers/staging/tidspbridge/rmgr/dspdrv.c
+++ b/drivers/staging/tidspbridge/rmgr/dspdrv.c
@@ -26,9 +26,6 @@
/* ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
-
/* ----------------------------------- Platform Manager */
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>
@@ -121,6 +118,7 @@ bool dsp_deinit(u32 device_context)
bool ret = true;
u32 device_node;
struct mgr_object *mgr_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
while ((device_node = drv_get_first_dev_extension()) != 0) {
(void)dev_remove_device((struct cfg_devnode *)device_node);
@@ -131,10 +129,14 @@ bool dsp_deinit(u32 device_context)
(void)drv_destroy((struct drv_object *)device_context);
- /* Get the Manager Object from Registry
+ /* Get the Manager Object from driver data
* MGR Destroy will unload the DCD dll */
- if (!cfg_get_object((u32 *) &mgr_obj, REG_MGR_OBJECT))
+ if (drv_datap && drv_datap->mgr_object) {
+ mgr_obj = drv_datap->mgr_object;
(void)mgr_destroy(mgr_obj);
+ } else {
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
+ }
api_exit();
diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c
index 57a39b9c274b..0ea89a1bb77c 100644
--- a/drivers/staging/tidspbridge/rmgr/mgr.c
+++ b/drivers/staging/tidspbridge/rmgr/mgr.c
@@ -20,6 +20,9 @@
#include <linux/types.h>
+/* ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
/* ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
@@ -27,7 +30,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/sync.h>
/* ----------------------------------- Others */
@@ -58,6 +60,7 @@ int mgr_create(struct mgr_object **mgr_obj,
{
int status = 0;
struct mgr_object *pmgr_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(mgr_obj != NULL);
DBC_REQUIRE(refs > 0);
@@ -67,7 +70,14 @@ int mgr_create(struct mgr_object **mgr_obj,
status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr);
if (!status) {
/* If succeeded store the handle in the MGR Object */
- status = cfg_set_object((u32) pmgr_obj, REG_MGR_OBJECT);
+ if (drv_datap) {
+ drv_datap->mgr_object = (void *)pmgr_obj;
+ } else {
+ status = -EPERM;
+ pr_err("%s: Failed to store MGR object\n",
+ __func__);
+ }
+
if (!status) {
*mgr_obj = pmgr_obj;
} else {
@@ -94,6 +104,7 @@ int mgr_destroy(struct mgr_object *hmgr_obj)
{
int status = 0;
struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(refs > 0);
DBC_REQUIRE(hmgr_obj);
@@ -103,8 +114,13 @@ int mgr_destroy(struct mgr_object *hmgr_obj)
dcd_destroy_manager(hmgr_obj->hdcd_mgr);
kfree(pmgr_obj);
- /* Update the Registry with NULL for MGR Object */
- (void)cfg_set_object(0, REG_MGR_OBJECT);
+ /* Update the driver data with NULL for MGR Object */
+ if (drv_datap) {
+ drv_datap->mgr_object = NULL;
+ } else {
+ status = -EPERM;
+ pr_err("%s: Failed to store MGR object\n", __func__);
+ }
return status;
}
@@ -123,6 +139,7 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
u32 node_index = 0;
struct dcd_genericobj gen_obj;
struct mgr_object *pmgr_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
DBC_REQUIRE(pndb_props != NULL);
DBC_REQUIRE(pu_num_nodes != NULL);
@@ -130,10 +147,14 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
DBC_REQUIRE(refs > 0);
*pu_num_nodes = 0;
- /* Get The Manager Object from the Registry */
- status = cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT);
- if (status)
+ /* Get the Manager Object from the driver data */
+ if (!drv_datap || !drv_datap->mgr_object) {
+ status = -ENODATA;
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
goto func_cont;
+ } else {
+ pmgr_obj = drv_datap->mgr_object;
+ }
DBC_ASSERT(pmgr_obj);
/* Forever loop till we hit failed or no more items in the
@@ -195,6 +216,7 @@ int mgr_enum_processor_info(u32 processor_id,
struct drv_object *hdrv_obj;
u8 dev_type;
struct cfg_devnode *dev_node;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
bool proc_detect = false;
DBC_REQUIRE(processor_info != NULL);
@@ -203,7 +225,15 @@ int mgr_enum_processor_info(u32 processor_id,
DBC_REQUIRE(refs > 0);
*pu_num_procs = 0;
- status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
+
+ /* Retrieve the Object handle from the driver data */
+ if (!drv_datap || !drv_datap->drv_object) {
+ status = -ENODATA;
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
+ } else {
+ hdrv_obj = drv_datap->drv_object;
+ }
+
if (!status) {
status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
if (!status) {
@@ -219,8 +249,10 @@ int mgr_enum_processor_info(u32 processor_id,
if (status)
goto func_end;
- /* Get The Manager Object from the Registry */
- if (cfg_get_object((u32 *) &pmgr_obj, REG_MGR_OBJECT)) {
+ /* Get The Manager Object from the driver data */
+ if (drv_datap && drv_datap->mgr_object) {
+ pmgr_obj = drv_datap->mgr_object;
+ } else {
dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
goto func_end;
}
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index 6e9441e21265..84882dc29a50 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -27,7 +27,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/list.h>
#include <dspbridge/memdefs.h>
#include <dspbridge/proc.h>
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 44c26e11fc4a..b47d7aa747b1 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -29,7 +29,6 @@
#include <dspbridge/dbc.h>
/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
#include <dspbridge/list.h>
#include <dspbridge/ntfy.h>
#include <dspbridge/sync.h>
@@ -280,6 +279,7 @@ proc_attach(u32 processor_id,
struct proc_object *p_proc_object = NULL;
struct mgr_object *hmgr_obj = NULL;
struct drv_object *hdrv_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
u8 dev_type;
DBC_REQUIRE(refs > 0);
@@ -291,9 +291,13 @@ proc_attach(u32 processor_id,
}
/* Get the Driver and Manager Object Handles */
- status = cfg_get_object((u32 *) &hdrv_obj, REG_DRV_OBJECT);
- if (!status)
- status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
+ if (!drv_datap || !drv_datap->drv_object || !drv_datap->mgr_object) {
+ status = -ENODATA;
+ pr_err("%s: Failed to get object handles\n", __func__);
+ } else {
+ hdrv_obj = drv_datap->drv_object;
+ hmgr_obj = drv_datap->mgr_object;
+ }
if (!status) {
/* Get the Device Object */
@@ -393,18 +397,29 @@ static int get_exec_file(struct cfg_devnode *dev_node_obj,
{
u8 dev_type;
s32 len;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
+
+ if (!exec_file)
+ return -EFAULT;
+
if (dev_type == DSP_UNIT) {
- return cfg_get_exec_file(dev_node_obj, size, exec_file);
- } else if (dev_type == IVA_UNIT) {
- if (iva_img) {
- len = strlen(iva_img);
- strncpy(exec_file, iva_img, len + 1);
- return 0;
- }
+ if (!drv_datap || !drv_datap->base_img)
+ return -EFAULT;
+
+ if (strlen(drv_datap->base_img) > size)
+ return -EINVAL;
+
+ strcpy(exec_file, drv_datap->base_img);
+ } else if (dev_type == IVA_UNIT && iva_img) {
+ len = strlen(iva_img);
+ strncpy(exec_file, iva_img, len + 1);
+ } else {
+ return -ENOENT;
}
- return -ENOENT;
+
+ return 0;
}
/*
@@ -429,6 +444,7 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj,
char sz_exec_file[MAXCMDLINELEN];
char *argv[2];
struct mgr_object *hmgr_obj = NULL;
+ struct drv_data *drv_datap = dev_get_drvdata(bridge);
u8 dev_type;
DBC_REQUIRE(refs > 0);
@@ -436,9 +452,13 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj,
DBC_REQUIRE(hdev_obj != NULL);
/* Create a Dummy PROC Object */
- status = cfg_get_object((u32 *) &hmgr_obj, REG_MGR_OBJECT);
- if (status)
+ if (!drv_datap || !drv_datap->mgr_object) {
+ status = -ENODATA;
+ pr_err("%s: Failed to retrieve the object handle\n", __func__);
goto func_end;
+ } else {
+ hmgr_obj = drv_datap->mgr_object;
+ }
p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
if (p_proc_object == NULL) {
diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c
index ef2ec9497b1c..f4986b7cc9e5 100644
--- a/drivers/staging/tidspbridge/rmgr/strm.c
+++ b/drivers/staging/tidspbridge/rmgr/strm.c
@@ -42,7 +42,6 @@
/* ----------------------------------- This */
#include <dspbridge/strm.h>
-#include <dspbridge/cfg.h>
#include <dspbridge/resourcecleanup.h>
/* ----------------------------------- Defines, Data Structures, Typedefs */
diff --git a/drivers/staging/tidspbridge/services/cfg.c b/drivers/staging/tidspbridge/services/cfg.c
deleted file mode 100644
index a7af74f482dd..000000000000
--- a/drivers/staging/tidspbridge/services/cfg.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * cfg.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation of platform specific config services.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-
-/* ----------------------------------- This */
-#include <dspbridge/cfg.h>
-#include <dspbridge/drv.h>
-
-struct drv_ext {
- struct list_head link;
- char sz_string[MAXREGPATHLENGTH];
-};
-
-/*
- * ======== cfg_exit ========
- * Purpose:
- * Discontinue usage of the CFG module.
- */
-void cfg_exit(void)
-{
- /* Do nothing */
-}
-
-/*
- * ======== cfg_get_auto_start ========
- * Purpose:
- * Retreive the autostart mask, if any, for this board.
- */
-int cfg_get_auto_start(struct cfg_devnode *dev_node_obj,
- u32 *auto_start)
-{
- int status = 0;
- u32 dw_buf_size;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- dw_buf_size = sizeof(*auto_start);
- if (!dev_node_obj)
- status = -EFAULT;
- if (!auto_start || !drv_datap)
- status = -EFAULT;
- if (!status)
- *auto_start = (drv_datap->base_img) ? 1 : 0;
-
- DBC_ENSURE((status == 0 &&
- (*auto_start == 0 || *auto_start == 1))
- || status != 0);
- return status;
-}
-
-/*
- * ======== cfg_get_dev_object ========
- * Purpose:
- * Retrieve the Device Object handle for a given devnode.
- */
-int cfg_get_dev_object(struct cfg_devnode *dev_node_obj,
- u32 *value)
-{
- int status = 0;
- u32 dw_buf_size;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (!drv_datap)
- status = -EPERM;
-
- if (!dev_node_obj)
- status = -EFAULT;
-
- if (!value)
- status = -EFAULT;
-
- dw_buf_size = sizeof(value);
- if (!status) {
-
- /* check the device string and then store dev object */
- if (!
- (strcmp
- ((char *)((struct drv_ext *)dev_node_obj)->sz_string,
- "TIOMAP1510")))
- *value = (u32)drv_datap->dev_object;
- }
- if (status)
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- return status;
-}
-
-/*
- * ======== cfg_get_exec_file ========
- * Purpose:
- * Retreive the default executable, if any, for this board.
- */
-int cfg_get_exec_file(struct cfg_devnode *dev_node_obj, u32 buf_size,
- char *str_exec_file)
-{
- int status = 0;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (!dev_node_obj)
- status = -EFAULT;
-
- else if (!str_exec_file || !drv_datap)
- status = -EFAULT;
-
- if (strlen(drv_datap->base_img) > buf_size)
- status = -EINVAL;
-
- if (!status && drv_datap->base_img)
- strcpy(str_exec_file, drv_datap->base_img);
-
- if (status)
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- DBC_ENSURE(((status == 0) &&
- (strlen(str_exec_file) <= buf_size))
- || (status != 0));
- return status;
-}
-
-/*
- * ======== cfg_get_object ========
- * Purpose:
- * Retrieve the Object handle from the Registry
- */
-int cfg_get_object(u32 *value, u8 dw_type)
-{
- int status = -EINVAL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- DBC_REQUIRE(value != NULL);
-
- if (!drv_datap)
- return -EPERM;
-
- switch (dw_type) {
- case (REG_DRV_OBJECT):
- if (drv_datap->drv_object) {
- *value = (u32)drv_datap->drv_object;
- status = 0;
- } else {
- status = -ENODATA;
- }
- break;
- case (REG_MGR_OBJECT):
- if (drv_datap->mgr_object) {
- *value = (u32)drv_datap->mgr_object;
- status = 0;
- } else {
- status = -ENODATA;
- }
- break;
-
- default:
- break;
- }
- if (status) {
- *value = 0;
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- }
- DBC_ENSURE((!status && *value != 0) || (status && *value == 0));
- return status;
-}
-
-/*
- * ======== cfg_init ========
- * Purpose:
- * Initialize the CFG module's private state.
- */
-bool cfg_init(void)
-{
- return true;
-}
-
-/*
- * ======== cfg_set_dev_object ========
- * Purpose:
- * Store the Device Object handle and dev_node pointer for a given devnode.
- */
-int cfg_set_dev_object(struct cfg_devnode *dev_node_obj, u32 value)
-{
- int status = 0;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (!drv_datap) {
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- return -EPERM;
- }
-
- if (!dev_node_obj)
- status = -EFAULT;
-
- if (!status) {
- /* Store the Bridge device object in the Registry */
-
- if (!(strcmp((char *)dev_node_obj, "TIOMAP1510")))
- drv_datap->dev_object = (void *) value;
- }
- if (status)
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
-
- return status;
-}
-
-/*
- * ======== cfg_set_object ========
- * Purpose:
- * Store the Driver Object handle
- */
-int cfg_set_object(u32 value, u8 dw_type)
-{
- int status = -EINVAL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (!drv_datap)
- return -EPERM;
-
- switch (dw_type) {
- case (REG_DRV_OBJECT):
- drv_datap->drv_object = (void *)value;
- status = 0;
- break;
- case (REG_MGR_OBJECT):
- drv_datap->mgr_object = (void *)value;
- status = 0;
- break;
- default:
- break;
- }
- if (status)
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- return status;
-}
diff --git a/drivers/staging/tidspbridge/services/ntfy.c b/drivers/staging/tidspbridge/services/ntfy.c
deleted file mode 100644
index a2ea698be24e..000000000000
--- a/drivers/staging/tidspbridge/services/ntfy.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * ntfy.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Manage lists of notification events.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- This */
-#include <dspbridge/ntfy.h>
-
-int dsp_notifier_event(struct notifier_block *this, unsigned long event,
- void *data)
-{
- struct ntfy_event *ne = container_of(this, struct ntfy_event,
- noti_block);
- if (ne->event & event)
- sync_set_event(&ne->sync_obj);
- return NOTIFY_OK;
-}
-
diff --git a/drivers/staging/tidspbridge/services/services.c b/drivers/staging/tidspbridge/services/services.c
deleted file mode 100644
index 6a7dd6f3ecba..000000000000
--- a/drivers/staging/tidspbridge/services/services.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * services.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Provide SERVICES loading.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/cfg.h>
-#include <dspbridge/ntfy.h>
-#include <dspbridge/sync.h>
-#include <dspbridge/clk.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/services.h>
-
-/*
- * ======== services_exit ========
- * Purpose:
- * Discontinue usage of module; free resources when reference count
- * reaches 0.
- */
-void services_exit(void)
-{
- cfg_exit();
-}
-
-/*
- * ======== services_init ========
- * Purpose:
- * Initializes SERVICES modules.
- */
-bool services_init(void)
-{
- bool ret = true;
- bool fcfg;
-
- /* Perform required initialization of SERVICES modules. */
- fcfg = cfg_init();
-
- ret = fcfg;
-
- if (!ret) {
- if (fcfg)
- cfg_exit();
- }
-
- return ret;
-}
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index c725356cc346..de7ebb99d8f6 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_TM6000
tristate "TV Master TM5600/6000/6010 driver"
- depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL
+ depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL
select VIDEO_TUNER
select MEDIA_TUNER_XC2028
select MEDIA_TUNER_XC5000
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 087137d9164d..6c09ef3c71ea 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -403,7 +403,7 @@ int tm6000_audio_init(struct tm6000_core *dev)
rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm);
if (rc < 0)
- goto error;
+ goto error_chip;
pcm->info_flags = 0;
pcm->private_data = chip;
@@ -413,12 +413,15 @@ int tm6000_audio_init(struct tm6000_core *dev)
rc = snd_card_register(card);
if (rc < 0)
- goto error;
+ goto error_chip;
dprintk(1,"Registered audio driver for %s\n", card->longname);
return 0;
+error_chip:
+ kfree(chip);
+ dev->adev = NULL;
error:
snd_card_free(card);
return rc;
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index cded411d8bba..80f2bf084505 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -702,10 +702,8 @@ void tm6000_unregister_extension(struct tm6000_ops *ops)
struct tm6000_core *dev = NULL;
mutex_lock(&tm6000_devlist_mutex);
- list_for_each_entry(dev, &tm6000_devlist, devlist) {
- if (dev)
- ops->fini(dev);
- }
+ list_for_each_entry(dev, &tm6000_devlist, devlist)
+ ops->fini(dev);
mutex_lock(&tm6000_extension_devlist_lock);
printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
index 32f7a0af6938..7b0709694873 100644
--- a/drivers/staging/tm6000/tm6000-input.c
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug message [IR]");
static unsigned int enable_ir = 1;
module_param(enable_ir, int, 0644);
-MODULE_PARM_DESC(enable_ir, "enable ir (default is enable");
+MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
#undef dprintk
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index c7e061e5e04d..5969e848d297 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -25,6 +25,7 @@
#include <linux/fb.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include "udlfb.h"
@@ -57,19 +58,9 @@ static struct usb_device_id id_table[] = {
};
MODULE_DEVICE_TABLE(usb, id_table);
-#ifndef CONFIG_FB_DEFERRED_IO
-#warning Please set CONFIG_FB_DEFFERRED_IO option to support generic fbdev apps
-#endif
-
-#ifndef CONFIG_FB_SYS_IMAGEBLIT
-#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE
-#warning Please set CONFIG_FB_SYS_IMAGEBLIT option to support fb console
-#endif
-#endif
-
-#ifndef CONFIG_FB_MODE_HELPERS
-#warning CONFIG_FB_MODE_HELPERS required. Expect build break
-#endif
+/* module options */
+static int console; /* Optionally allow fbcon to consume first framebuffer */
+static int fb_defio; /* Optionally enable experimental fb_defio mmap support */
/* dlfb keeps a list of urbs for efficient bulk transfers */
static void dlfb_urb_completion(struct urb *urb);
@@ -78,11 +69,6 @@ static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
static void dlfb_free_urb_list(struct dlfb_data *dev);
-/* other symbols with dependents */
-#ifdef CONFIG_FB_DEFERRED_IO
-static struct fb_deferred_io dlfb_defio;
-#endif
-
/*
* All DisplayLink bulk operations start with 0xAF, followed by specific code
* All operations are written to buffers which then later get sent to device
@@ -108,13 +94,16 @@ static char *dlfb_vidreg_unlock(char *buf)
/*
* On/Off for driving the DisplayLink framebuffer to the display
+ * 0x00 H and V sync on
+ * 0x01 H and V sync off (screen blank but powered)
+ * 0x07 DPMS powerdown (requires modeset to come back)
*/
static char *dlfb_enable_hvsync(char *buf, bool enable)
{
if (enable)
return dlfb_set_register(buf, 0x1F, 0x00);
else
- return dlfb_set_register(buf, 0x1F, 0x01);
+ return dlfb_set_register(buf, 0x1F, 0x07);
}
static char *dlfb_set_color_depth(char *buf, u8 selection)
@@ -266,6 +255,7 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
urb = dlfb_get_urb(dev);
if (!urb)
return -ENOMEM;
+
buf = (char *) urb->transfer_buffer;
/*
@@ -297,15 +287,15 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
unsigned long size = vma->vm_end - vma->vm_start;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long page, pos;
- struct dlfb_data *dev = info->par;
-
- dl_notice("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
if (offset + size > info->fix.smem_len)
return -EINVAL;
pos = (unsigned long)info->fix.smem_start + offset;
+ dl_notice("mmap() framebuffer addr:%lu size:%lu\n",
+ pos, size);
+
while (size > 0) {
page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
@@ -321,7 +311,6 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
-
}
/*
@@ -383,13 +372,13 @@ static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
* A single command can transmit a maximum of 256 pixels,
* regardless of the compression ratio (protocol design limit).
* To the hardware, 0 for a size byte means 256
- *
+ *
* Rather than 256 pixel commands which are either rl or raw encoded,
* the rlx command simply assumes alternating raw and rl spans within one cmd.
* This has a slightly larger header overhead, but produces more even results.
* It also processes all data (read and write) in a single pass.
* Performance benchmarks of common cases show it having just slightly better
- * compression than 256 pixel raw -or- rle commands, with similar CPU consumpion.
+ * compression than 256 pixel raw or rle commands, with similar CPU consumpion.
* But for very rl friendly data, will compress not quite as well.
*/
static void dlfb_compress_hline(
@@ -410,15 +399,14 @@ static void dlfb_compress_hline(
uint8_t *cmd_pixels_count_byte = 0;
const uint16_t *raw_pixel_start = 0;
const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0;
- const uint32_t be_dev_addr = cpu_to_be32(dev_addr);
prefetchw((void *) cmd); /* pull in one cache line at least */
*cmd++ = 0xAF;
*cmd++ = 0x6B;
- *cmd++ = (uint8_t) ((be_dev_addr >> 8) & 0xFF);
- *cmd++ = (uint8_t) ((be_dev_addr >> 16) & 0xFF);
- *cmd++ = (uint8_t) ((be_dev_addr >> 24) & 0xFF);
+ *cmd++ = (uint8_t) ((dev_addr >> 16) & 0xFF);
+ *cmd++ = (uint8_t) ((dev_addr >> 8) & 0xFF);
+ *cmd++ = (uint8_t) ((dev_addr) & 0xFF);
cmd_pixels_count_byte = cmd++; /* we'll know this later */
cmd_pixel_start = pixel;
@@ -488,7 +476,7 @@ static void dlfb_compress_hline(
* (that we can only write to, slowly, and can never read), and (optionally)
* our shadow copy that tracks what's been sent to that hardware buffer.
*/
-static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
+static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
const char *front, char **urb_buf_ptr,
u32 byte_offset, u32 byte_width,
int *ident_ptr, int *sent_ptr)
@@ -530,11 +518,11 @@ static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
if (cmd >= cmd_end) {
int len = cmd - (u8 *) urb->transfer_buffer;
if (dlfb_submit_urb(dev, urb, len))
- return; /* lost pixels is set */
+ return 1; /* lost pixels is set */
*sent_ptr += len;
urb = dlfb_get_urb(dev);
if (!urb)
- return; /* lost_pixels is set */
+ return 1; /* lost_pixels is set */
*urb_ptr = urb;
cmd = urb->transfer_buffer;
cmd_end = &cmd[urb->transfer_buffer_length];
@@ -542,6 +530,8 @@ static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
}
*urb_buf_ptr = cmd;
+
+ return 0;
}
int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
@@ -578,9 +568,11 @@ int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
const int line_offset = dev->info->fix.line_length * i;
const int byte_offset = line_offset + (x * BPP);
- dlfb_render_hline(dev, &urb, (char *) dev->info->fix.smem_start,
- &cmd, byte_offset, width * BPP,
- &bytes_identical, &bytes_sent);
+ if (dlfb_render_hline(dev, &urb,
+ (char *) dev->info->fix.smem_start,
+ &cmd, byte_offset, width * BPP,
+ &bytes_identical, &bytes_sent))
+ goto error;
}
if (cmd > (char *) urb->transfer_buffer) {
@@ -591,6 +583,7 @@ int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
} else
dlfb_urb_completion(urb);
+error:
atomic_add(bytes_sent, &dev->bytes_sent);
atomic_add(bytes_identical, &dev->bytes_identical);
atomic_add(width*height*2, &dev->bytes_rendered);
@@ -602,6 +595,48 @@ int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
return 0;
}
+static ssize_t dlfb_ops_read(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t result = -ENOSYS;
+
+#if defined CONFIG_FB_SYS_FOPS || defined CONFIG_FB_SYS_FOPS_MODULE
+ result = fb_sys_read(info, buf, count, ppos);
+#endif
+
+ return result;
+}
+
+/*
+ * Path triggered by usermode clients who write to filesystem
+ * e.g. cat filename > /dev/fb1
+ * Not used by X Windows or text-mode console. But useful for testing.
+ * Slow because of extra copy and we must assume all pixels dirty.
+ */
+static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t result = -ENOSYS;
+ struct dlfb_data *dev = info->par;
+ u32 offset = (u32) *ppos;
+
+#if defined CONFIG_FB_SYS_FOPS || defined CONFIG_FB_SYS_FOPS_MODULE
+
+ result = fb_sys_write(info, buf, count, ppos);
+
+ if (result > 0) {
+ int start = max((int)(offset / info->fix.line_length) - 1, 0);
+ int lines = min((u32)((result / info->fix.line_length) + 1),
+ (u32)info->var.yres);
+
+ dlfb_handle_damage(dev, 0, start, info->var.xres,
+ lines, info->screen_base);
+ }
+#endif
+
+ return result;
+}
+
/* hardware has native COPY command (see libdlo), but not worth it for fbcon */
static void dlfb_ops_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
@@ -616,7 +651,6 @@ static void dlfb_ops_copyarea(struct fb_info *info,
dlfb_handle_damage(dev, area->dx, area->dy,
area->width, area->height, info->screen_base);
#endif
- atomic_inc(&dev->copy_count);
}
@@ -634,7 +668,6 @@ static void dlfb_ops_imageblit(struct fb_info *info,
#endif
- atomic_inc(&dev->blit_count);
}
static void dlfb_ops_fillrect(struct fb_info *info,
@@ -650,23 +683,98 @@ static void dlfb_ops_fillrect(struct fb_info *info,
rect->height, info->screen_base);
#endif
- atomic_inc(&dev->fill_count);
+}
+#ifdef CONFIG_FB_DEFERRED_IO
+/*
+ * NOTE: fb_defio.c is holding info->fbdefio.mutex
+ * Touching ANY framebuffer memory that triggers a page fault
+ * in fb_defio will cause a deadlock, when it also tries to
+ * grab the same mutex.
+ */
+static void dlfb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+ struct dlfb_data *dev = info->par;
+ struct urb *urb;
+ char *cmd;
+ cycles_t start_cycles, end_cycles;
+ int bytes_sent = 0;
+ int bytes_identical = 0;
+ int bytes_rendered = 0;
+
+ if (!fb_defio)
+ return;
+
+ if (!atomic_read(&dev->usb_active))
+ return;
+
+ start_cycles = get_cycles();
+
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return;
+
+ cmd = urb->transfer_buffer;
+
+ /* walk the written page list and render each to device */
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+
+ if (dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
+ &cmd, cur->index << PAGE_SHIFT,
+ PAGE_SIZE, &bytes_identical, &bytes_sent))
+ goto error;
+ bytes_rendered += PAGE_SIZE;
+ }
+
+ if (cmd > (char *) urb->transfer_buffer) {
+ /* Send partial buffer remaining before exiting */
+ int len = cmd - (char *) urb->transfer_buffer;
+ dlfb_submit_urb(dev, urb, len);
+ bytes_sent += len;
+ } else
+ dlfb_urb_completion(urb);
+
+error:
+ atomic_add(bytes_sent, &dev->bytes_sent);
+ atomic_add(bytes_identical, &dev->bytes_identical);
+ atomic_add(bytes_rendered, &dev->bytes_rendered);
+ end_cycles = get_cycles();
+ atomic_add(((unsigned int) ((end_cycles - start_cycles)
+ >> 10)), /* Kcycles */
+ &dev->cpu_kcycles_used);
}
-static void dlfb_get_edid(struct dlfb_data *dev)
+#endif
+
+static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
{
int i;
int ret;
- char rbuf[2];
+ char *rbuf;
- for (i = 0; i < sizeof(dev->edid); i++) {
+ rbuf = kmalloc(2, GFP_KERNEL);
+ if (!rbuf)
+ return 0;
+
+ for (i = 0; i < len; i++) {
ret = usb_control_msg(dev->udev,
usb_rcvctrlpipe(dev->udev, 0), (0x02),
(0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
- 0);
- dev->edid[i] = rbuf[1];
+ HZ);
+ if (ret < 1) {
+ dl_err("Read EDID byte %d failed err %x\n", i, ret);
+ i--;
+ break;
+ }
+ edid[i] = rbuf[1];
}
+
+ kfree(rbuf);
+
+ return i;
}
static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
@@ -682,8 +790,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
/* TODO: Update X server to get this from sysfs instead */
if (cmd == DLFB_IOCTL_RETURN_EDID) {
char *edid = (char *)arg;
- dlfb_get_edid(dev);
- if (copy_to_user(edid, dev->edid, sizeof(dev->edid)))
+ if (copy_to_user(edid, dev->edid, dev->edid_size))
return -EFAULT;
return 0;
}
@@ -691,6 +798,16 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
/* TODO: Help propose a standard fb.h ioctl to report mmap damage */
if (cmd == DLFB_IOCTL_REPORT_DAMAGE) {
+ /*
+ * If we have a damage-aware client, turn fb_defio "off"
+ * To avoid perf imact of unecessary page fault handling.
+ * Done by resetting the delay for this fb_info to a very
+ * long period. Pages will become writable and stay that way.
+ * Reset to normal value when all clients have closed this fb.
+ */
+ if (info->fbdefio)
+ info->fbdefio->delay = DL_DEFIO_WRITE_DISABLE;
+
area = (struct dloarea *)arg;
if (area->x < 0)
@@ -705,11 +822,8 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
if (area->y > info->var.yres)
area->y = info->var.yres;
- atomic_set(&dev->use_defio, 0);
-
dlfb_handle_damage(dev, area->x, area->y, area->w, area->h,
info->screen_base);
- atomic_inc(&dev->damage_count);
}
return 0;
@@ -745,55 +859,48 @@ dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
/*
* It's common for several clients to have framebuffer open simultaneously.
* e.g. both fbcon and X. Makes things interesting.
+ * Assumes caller is holding info->lock (for open and release at least)
*/
static int dlfb_ops_open(struct fb_info *info, int user)
{
struct dlfb_data *dev = info->par;
-/* if (user == 0)
- * We could special case kernel mode clients (fbcon) here
- */
+ /*
+ * fbcon aggressively connects to first framebuffer it finds,
+ * preventing other clients (X) from working properly. Usually
+ * not what the user wants. Fail by default with option to enable.
+ */
+ if ((user == 0) & (!console))
+ return -EBUSY;
- mutex_lock(&dev->fb_open_lock);
+ /* If the USB device is gone, we don't accept new opens */
+ if (dev->virtualized)
+ return -ENODEV;
dev->fb_count++;
-#ifdef CONFIG_FB_DEFERRED_IO
- if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) {
- /* enable defio */
- info->fbdefio = &dlfb_defio;
- fb_deferred_io_init(info);
- }
-#endif
-
- dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
- info->node, user, info, dev->fb_count);
-
- mutex_unlock(&dev->fb_open_lock);
+ kref_get(&dev->kref);
- return 0;
-}
+#ifdef CONFIG_FB_DEFERRED_IO
+ if (fb_defio && (info->fbdefio == NULL)) {
+ /* enable defio at last moment if not disabled by client */
-static int dlfb_ops_release(struct fb_info *info, int user)
-{
- struct dlfb_data *dev = info->par;
+ struct fb_deferred_io *fbdefio;
- mutex_lock(&dev->fb_open_lock);
+ fbdefio = kmalloc(GFP_KERNEL, sizeof(struct fb_deferred_io));
- dev->fb_count--;
+ if (fbdefio) {
+ fbdefio->delay = DL_DEFIO_WRITE_DELAY;
+ fbdefio->deferred_io = dlfb_dpy_deferred_io;
+ }
-#ifdef CONFIG_FB_DEFERRED_IO
- if ((dev->fb_count == 0) && (info->fbdefio)) {
- fb_deferred_io_cleanup(info);
- info->fbdefio = NULL;
- info->fbops->fb_mmap = dlfb_ops_mmap;
+ info->fbdefio = fbdefio;
+ fb_deferred_io_init(info);
}
#endif
- dl_notice("release /dev/fb%d user=%d count=%d\n",
- info->node, user, dev->fb_count);
-
- mutex_unlock(&dev->fb_open_lock);
+ dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
+ info->node, user, info, dev->fb_count);
return 0;
}
@@ -803,25 +910,40 @@ static int dlfb_ops_release(struct fb_info *info, int user)
* and all references to our device instance (dlfb_data) are released.
* Every transaction must have a reference, so we know are fully spun down
*/
-static void dlfb_delete(struct kref *kref)
+static void dlfb_free(struct kref *kref)
{
struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
+ /* this function will wait for all in-flight urbs to complete */
+ if (dev->urbs.count > 0)
+ dlfb_free_urb_list(dev);
+
if (dev->backing_buffer)
vfree(dev->backing_buffer);
- mutex_destroy(&dev->fb_open_lock);
+ kfree(dev->edid);
+
+ dl_warn("freeing dlfb_data %p\n", dev);
kfree(dev);
}
-/*
- * Called by fbdev as last part of unregister_framebuffer() process
- * No new clients can open connections. Deallocate everything fb_info.
- */
-static void dlfb_ops_destroy(struct fb_info *info)
+static void dlfb_release_urb_work(struct work_struct *work)
{
- struct dlfb_data *dev = info->par;
+ struct urb_node *unode = container_of(work, struct urb_node,
+ release_urb_work.work);
+
+ up(&unode->dev->urbs.limit_sem);
+}
+
+static void dlfb_free_framebuffer_work(struct work_struct *work)
+{
+ struct dlfb_data *dev = container_of(work, struct dlfb_data,
+ free_framebuffer_work.work);
+ struct fb_info *info = dev->info;
+ int node = info->node;
+
+ unregister_framebuffer(info);
if (info->cmap.len != 0)
fb_dealloc_cmap(&info->cmap);
@@ -832,10 +954,45 @@ static void dlfb_ops_destroy(struct fb_info *info)
fb_destroy_modelist(&info->modelist);
+ dev->info = 0;
+
+ /* Assume info structure is freed after this point */
framebuffer_release(info);
- /* ref taken before register_framebuffer() for dlfb_data clients */
- kref_put(&dev->kref, dlfb_delete);
+ dl_warn("fb_info for /dev/fb%d has been freed\n", node);
+
+ /* ref taken in probe() as part of registering framebfufer */
+ kref_put(&dev->kref, dlfb_free);
+}
+
+/*
+ * Assumes caller is holding info->lock mutex (for open and release at least)
+ */
+static int dlfb_ops_release(struct fb_info *info, int user)
+{
+ struct dlfb_data *dev = info->par;
+
+ dev->fb_count--;
+
+ /* We can't free fb_info here - fbmem will touch it when we return */
+ if (dev->virtualized && (dev->fb_count == 0))
+ schedule_delayed_work(&dev->free_framebuffer_work, HZ);
+
+#ifdef CONFIG_FB_DEFERRED_IO
+ if ((dev->fb_count == 0) && (info->fbdefio)) {
+ fb_deferred_io_cleanup(info);
+ kfree(info->fbdefio);
+ info->fbdefio = NULL;
+ info->fbops->fb_mmap = dlfb_ops_mmap;
+ }
+#endif
+
+ dl_warn("released /dev/fb%d user=%d count=%d\n",
+ info->node, user, dev->fb_count);
+
+ kref_put(&dev->kref, dlfb_free);
+
+ return 0;
}
/*
@@ -847,8 +1004,13 @@ static int dlfb_is_valid_mode(struct fb_videomode *mode,
{
struct dlfb_data *dev = info->par;
- if (mode->xres * mode->yres > dev->sku_pixel_limit)
+ if (mode->xres * mode->yres > dev->sku_pixel_limit) {
+ dl_warn("%dx%d beyond chip capabilities\n",
+ mode->xres, mode->yres);
return 0;
+ }
+
+ dl_info("%dx%d valid mode\n", mode->xres, mode->yres);
return 1;
}
@@ -888,42 +1050,62 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
static int dlfb_ops_set_par(struct fb_info *info)
{
struct dlfb_data *dev = info->par;
+ int result;
+ u16 *pix_framebuffer;
+ int i;
dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
- return dlfb_set_video_mode(dev, &info->var);
+ result = dlfb_set_video_mode(dev, &info->var);
+
+ if ((result == 0) && (dev->fb_count == 0)) {
+
+ /* paint greenscreen */
+
+ pix_framebuffer = (u16 *) info->screen_base;
+ for (i = 0; i < info->fix.smem_len / 2; i++)
+ pix_framebuffer[i] = 0x37e6;
+
+ dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
+ info->screen_base);
+ }
+
+ return result;
}
+/*
+ * In order to come back from full DPMS off, we need to set the mode again
+ */
static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
{
struct dlfb_data *dev = info->par;
- char *bufptr;
- struct urb *urb;
- urb = dlfb_get_urb(dev);
- if (!urb)
- return 0;
- bufptr = (char *) urb->transfer_buffer;
+ if (blank_mode != FB_BLANK_UNBLANK) {
+ char *bufptr;
+ struct urb *urb;
- /* overloading usb_active. UNBLANK can conflict with teardown */
+ urb = dlfb_get_urb(dev);
+ if (!urb)
+ return 0;
- bufptr = dlfb_vidreg_lock(bufptr);
- if (blank_mode != FB_BLANK_UNBLANK) {
- atomic_set(&dev->usb_active, 0);
+ bufptr = (char *) urb->transfer_buffer;
+ bufptr = dlfb_vidreg_lock(bufptr);
bufptr = dlfb_enable_hvsync(bufptr, false);
+ bufptr = dlfb_vidreg_unlock(bufptr);
+
+ dlfb_submit_urb(dev, urb, bufptr -
+ (char *) urb->transfer_buffer);
} else {
- atomic_set(&dev->usb_active, 1);
- bufptr = dlfb_enable_hvsync(bufptr, true);
+ dlfb_set_video_mode(dev, &info->var);
}
- bufptr = dlfb_vidreg_unlock(bufptr);
-
- dlfb_submit_urb(dev, urb, bufptr - (char *) urb->transfer_buffer);
return 0;
}
static struct fb_ops dlfb_ops = {
.owner = THIS_MODULE,
+ .fb_read = dlfb_ops_read,
+ .fb_write = dlfb_ops_write,
.fb_setcolreg = dlfb_ops_setcolreg,
.fb_fillrect = dlfb_ops_fillrect,
.fb_copyarea = dlfb_ops_copyarea,
@@ -937,46 +1119,166 @@ static struct fb_ops dlfb_ops = {
.fb_set_par = dlfb_ops_set_par,
};
+
+/*
+ * Assumes &info->lock held by caller
+ * Assumes no active clients have framebuffer open
+ */
+static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
+{
+ int retval = -ENOMEM;
+ int old_len = info->fix.smem_len;
+ int new_len;
+ unsigned char *old_fb = info->screen_base;
+ unsigned char *new_fb;
+ unsigned char *new_back;
+
+ dl_warn("Reallocating framebuffer. Addresses will change!\n");
+
+ new_len = info->fix.line_length * info->var.yres;
+
+ if (PAGE_ALIGN(new_len) > old_len) {
+ /*
+ * Alloc system memory for virtual framebuffer
+ */
+ new_fb = vmalloc(new_len);
+ if (!new_fb) {
+ dl_err("Virtual framebuffer alloc failed\n");
+ goto error;
+ }
+
+ if (info->screen_base) {
+ memcpy(new_fb, old_fb, old_len);
+ vfree(info->screen_base);
+ }
+
+ info->screen_base = new_fb;
+ info->fix.smem_len = PAGE_ALIGN(new_len);
+ info->fix.smem_start = (unsigned long) new_fb;
+ info->flags = udlfb_info_flags;
+
+ /*
+ * Second framebuffer copy to mirror the framebuffer state
+ * on the physical USB device. We can function without this.
+ * But with imperfect damage info we may send pixels over USB
+ * that were, in fact, unchanged - wasting limited USB bandwidth
+ */
+ new_back = vmalloc(new_len);
+ if (!new_back)
+ dl_info("No shadow/backing buffer allcoated\n");
+ else {
+ if (dev->backing_buffer)
+ vfree(dev->backing_buffer);
+ dev->backing_buffer = new_back;
+ memset(dev->backing_buffer, 0, new_len);
+ }
+ }
+
+ retval = 0;
+
+error:
+ return retval;
+}
+
/*
- * Calls dlfb_get_edid() to query the EDID of attached monitor via usb cmds
- * Then parses EDID into three places used by various parts of fbdev:
+ * 1) Get EDID from hw, or use sw default
+ * 2) Parse into various fb_info structs
+ * 3) Allocate virtual framebuffer memory to back highest res mode
+ *
+ * Parses EDID into three places used by various parts of fbdev:
* fb_var_screeninfo contains the timing of the monitor's preferred mode
* fb_info.monspecs is full parsed EDID info, including monspecs.modedb
* fb_info.modelist is a linked list of all monitor & VESA modes which work
*
* If EDID is not readable/valid, then modelist is all VESA modes,
* monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
- * Returns 0 if EDID parses successfully
+ * Returns 0 if successful
*/
-static int dlfb_parse_edid(struct dlfb_data *dev,
- struct fb_var_screeninfo *var,
- struct fb_info *info)
+static int dlfb_setup_modes(struct dlfb_data *dev,
+ struct fb_info *info,
+ char *default_edid, size_t default_edid_size)
{
int i;
const struct fb_videomode *default_vmode = NULL;
int result = 0;
+ char *edid;
+ int tries = 3;
+
+ if (info->dev) /* only use mutex if info has been registered */
+ mutex_lock(&info->lock);
+
+ edid = kmalloc(MAX_EDID_SIZE, GFP_KERNEL);
+ if (!edid) {
+ result = -ENOMEM;
+ goto error;
+ }
fb_destroy_modelist(&info->modelist);
memset(&info->monspecs, 0, sizeof(info->monspecs));
- dlfb_get_edid(dev);
- fb_edid_to_monspecs(dev->edid, &info->monspecs);
+ /*
+ * Try to (re)read EDID from hardware first
+ * EDID data may return, but not parse as valid
+ * Try again a few times, in case of e.g. analog cable noise
+ */
+ while (tries--) {
+
+ i = dlfb_get_edid(dev, edid, MAX_EDID_SIZE);
+
+ if (i >= MIN_EDID_SIZE)
+ fb_edid_to_monspecs(edid, &info->monspecs);
+
+ if (info->monspecs.modedb_len > 0) {
+ dev->edid = edid;
+ dev->edid_size = i;
+ break;
+ }
+ }
+
+ /* If that fails, use a previously returned EDID if available */
+ if (info->monspecs.modedb_len == 0) {
+
+ dl_err("Unable to get valid EDID from device/display\n");
+
+ if (dev->edid) {
+ fb_edid_to_monspecs(dev->edid, &info->monspecs);
+ if (info->monspecs.modedb_len > 0)
+ dl_err("Using previously queried EDID\n");
+ }
+ }
+
+ /* If that fails, use the default EDID we were handed */
+ if (info->monspecs.modedb_len == 0) {
+ if (default_edid_size >= MIN_EDID_SIZE) {
+ fb_edid_to_monspecs(default_edid, &info->monspecs);
+ if (info->monspecs.modedb_len > 0) {
+ memcpy(edid, default_edid, default_edid_size);
+ dev->edid = edid;
+ dev->edid_size = default_edid_size;
+ dl_err("Using default/backup EDID\n");
+ }
+ }
+ }
+ /* If we've got modes, let's pick a best default mode */
if (info->monspecs.modedb_len > 0) {
for (i = 0; i < info->monspecs.modedb_len; i++) {
if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
fb_add_videomode(&info->monspecs.modedb[i],
&info->modelist);
+ else /* if we've removed top/best mode */
+ info->monspecs.misc &= ~FB_MISC_1ST_DETAIL;
}
default_vmode = fb_find_best_display(&info->monspecs,
&info->modelist);
- } else {
- struct fb_videomode fb_vmode = {0};
+ }
- dl_err("Unable to get valid EDID from device/display\n");
- result = 1;
+ /* If everything else has failed, fall back to safe default mode */
+ if (default_vmode == NULL) {
+
+ struct fb_videomode fb_vmode = {0};
/*
* Add the standard VESA modes to our modelist
@@ -1002,8 +1304,30 @@ static int dlfb_parse_edid(struct dlfb_data *dev,
&info->modelist);
}
- fb_videomode_to_var(var, default_vmode);
- dlfb_var_color_format(var);
+ /* If we have good mode and no active clients*/
+ if ((default_vmode != NULL) && (dev->fb_count == 0)) {
+
+ fb_videomode_to_var(&info->var, default_vmode);
+ dlfb_var_color_format(&info->var);
+
+ /*
+ * with mode size info, we can now alloc our framebuffer.
+ */
+ memcpy(&info->fix, &dlfb_fix, sizeof(dlfb_fix));
+ info->fix.line_length = info->var.xres *
+ (info->var.bits_per_pixel / 8);
+
+ result = dlfb_realloc_framebuffer(dev, info);
+
+ } else
+ result = -EINVAL;
+
+error:
+ if (edid && (dev->edid != edid))
+ kfree(edid);
+
+ if (info->dev)
+ mutex_unlock(&info->lock);
return result;
}
@@ -1040,101 +1364,76 @@ static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
atomic_read(&dev->cpu_kcycles_used));
}
-static ssize_t metrics_misc_show(struct device *fbdev,
- struct device_attribute *a, char *buf) {
- struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
- return snprintf(buf, PAGE_SIZE,
- "Calls to\ndamage: %u\nblit: %u\n"
- "defio faults: %u\ncopy: %u\n"
- "fill: %u\n\n"
- "active framebuffer clients: %d\n"
- "urbs available %d(%d)\n"
- "Shadow framebuffer in use? %s\n"
- "Any lost pixels? %s\n",
- atomic_read(&dev->damage_count),
- atomic_read(&dev->blit_count),
- atomic_read(&dev->defio_fault_count),
- atomic_read(&dev->copy_count),
- atomic_read(&dev->fill_count),
- dev->fb_count,
- dev->urbs.available, dev->urbs.limit_sem.count,
- (dev->backing_buffer) ? "yes" : "no",
- atomic_read(&dev->lost_pixels) ? "yes" : "no");
-}
-
-static ssize_t edid_show(struct file *filp, struct kobject *kobj,
- struct bin_attribute *a,
+static ssize_t edid_show(
+ struct file *filp,
+ struct kobject *kobj, struct bin_attribute *a,
char *buf, loff_t off, size_t count) {
struct device *fbdev = container_of(kobj, struct device, kobj);
struct fb_info *fb_info = dev_get_drvdata(fbdev);
struct dlfb_data *dev = fb_info->par;
- char *edid = &dev->edid[0];
- const size_t size = sizeof(dev->edid);
- if (dlfb_parse_edid(dev, &fb_info->var, fb_info))
+ if (dev->edid == NULL)
return 0;
- if (off >= size)
+ if ((off >= dev->edid_size) || (count > dev->edid_size))
return 0;
- if (off + count > size)
- count = size - off;
- memcpy(buf, edid + off, count);
+ if (off + count > dev->edid_size)
+ count = dev->edid_size - off;
+
+ dl_info("sysfs edid copy %p to %p, %d bytes\n",
+ dev->edid, buf, (int) count);
+
+ memcpy(buf, dev->edid, count);
return count;
}
-
-static ssize_t metrics_reset_store(struct device *fbdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
+static ssize_t edid_store(
+ struct file *filp,
+ struct kobject *kobj, struct bin_attribute *a,
+ char *src, loff_t src_off, size_t src_size) {
+ struct device *fbdev = container_of(kobj, struct device, kobj);
struct fb_info *fb_info = dev_get_drvdata(fbdev);
struct dlfb_data *dev = fb_info->par;
- atomic_set(&dev->bytes_rendered, 0);
- atomic_set(&dev->bytes_identical, 0);
- atomic_set(&dev->bytes_sent, 0);
- atomic_set(&dev->cpu_kcycles_used, 0);
- atomic_set(&dev->blit_count, 0);
- atomic_set(&dev->copy_count, 0);
- atomic_set(&dev->fill_count, 0);
- atomic_set(&dev->defio_fault_count, 0);
- atomic_set(&dev->damage_count, 0);
+ /* We only support write of entire EDID at once, no offset*/
+ if ((src_size < MIN_EDID_SIZE) ||
+ (src_size > MAX_EDID_SIZE) ||
+ (src_off != 0))
+ return 0;
- return count;
-}
+ dlfb_setup_modes(dev, fb_info, src, src_size);
-static ssize_t use_defio_show(struct device *fbdev,
- struct device_attribute *a, char *buf) {
- struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
- return snprintf(buf, PAGE_SIZE, "%d\n",
- atomic_read(&dev->use_defio));
+ if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) {
+ dl_info("sysfs written EDID is new default\n");
+ dlfb_ops_set_par(fb_info);
+ return src_size;
+ } else
+ return 0;
}
-static ssize_t use_defio_store(struct device *fbdev,
+static ssize_t metrics_reset_store(struct device *fbdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fb_info *fb_info = dev_get_drvdata(fbdev);
struct dlfb_data *dev = fb_info->par;
- if (count > 0) {
- if (buf[0] == '0')
- atomic_set(&dev->use_defio, 0);
- if (buf[0] == '1')
- atomic_set(&dev->use_defio, 1);
- }
+ atomic_set(&dev->bytes_rendered, 0);
+ atomic_set(&dev->bytes_identical, 0);
+ atomic_set(&dev->bytes_sent, 0);
+ atomic_set(&dev->cpu_kcycles_used, 0);
+
return count;
}
static struct bin_attribute edid_attr = {
.attr.name = "edid",
- .attr.mode = 0444,
- .size = 128,
+ .attr.mode = 0666,
+ .size = MAX_EDID_SIZE,
.read = edid_show,
+ .write = edid_store
};
static struct device_attribute fb_device_attrs[] = {
@@ -1142,73 +1441,9 @@ static struct device_attribute fb_device_attrs[] = {
__ATTR_RO(metrics_bytes_identical),
__ATTR_RO(metrics_bytes_sent),
__ATTR_RO(metrics_cpu_kcycles_used),
- __ATTR_RO(metrics_misc),
__ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
- __ATTR_RW(use_defio),
-};
-
-#ifdef CONFIG_FB_DEFERRED_IO
-static void dlfb_dpy_deferred_io(struct fb_info *info,
- struct list_head *pagelist)
-{
- struct page *cur;
- struct fb_deferred_io *fbdefio = info->fbdefio;
- struct dlfb_data *dev = info->par;
- struct urb *urb;
- char *cmd;
- cycles_t start_cycles, end_cycles;
- int bytes_sent = 0;
- int bytes_identical = 0;
- int bytes_rendered = 0;
- int fault_count = 0;
-
- if (!atomic_read(&dev->use_defio))
- return;
-
- if (!atomic_read(&dev->usb_active))
- return;
-
- start_cycles = get_cycles();
-
- urb = dlfb_get_urb(dev);
- if (!urb)
- return;
- cmd = urb->transfer_buffer;
-
- /* walk the written page list and render each to device */
- list_for_each_entry(cur, &fbdefio->pagelist, lru) {
- dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
- &cmd, cur->index << PAGE_SHIFT,
- PAGE_SIZE, &bytes_identical, &bytes_sent);
- bytes_rendered += PAGE_SIZE;
- fault_count++;
- }
-
- if (cmd > (char *) urb->transfer_buffer) {
- /* Send partial buffer remaining before exiting */
- int len = cmd - (char *) urb->transfer_buffer;
- dlfb_submit_urb(dev, urb, len);
- bytes_sent += len;
- } else
- dlfb_urb_completion(urb);
-
- atomic_add(fault_count, &dev->defio_fault_count);
- atomic_add(bytes_sent, &dev->bytes_sent);
- atomic_add(bytes_identical, &dev->bytes_identical);
- atomic_add(bytes_rendered, &dev->bytes_rendered);
- end_cycles = get_cycles();
- atomic_add(((unsigned int) ((end_cycles - start_cycles)
- >> 10)), /* Kcycles */
- &dev->cpu_kcycles_used);
-}
-
-static struct fb_deferred_io dlfb_defio = {
- .delay = 5,
- .deferred_io = dlfb_dpy_deferred_io,
};
-#endif
-
/*
* This is necessary before we can communicate with the display controller.
*/
@@ -1227,20 +1462,82 @@ static int dlfb_select_std_channel(struct dlfb_data *dev)
return ret;
}
+static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
+ struct usb_device *usbdev)
+{
+ char *desc;
+ char *buf;
+ char *desc_end;
+
+ u8 total_len = 0;
+
+ buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
+ if (!buf)
+ return false;
+ desc = buf;
+
+ total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */
+ 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
+ if (total_len > 5) {
+ dl_info("vendor descriptor length:%x data:%02x %02x %02x %02x" \
+ "%02x %02x %02x %02x %02x %02x %02x\n",
+ total_len, desc[0],
+ desc[1], desc[2], desc[3], desc[4], desc[5], desc[6],
+ desc[7], desc[8], desc[9], desc[10]);
+
+ if ((desc[0] != total_len) || /* descriptor length */
+ (desc[1] != 0x5f) || /* vendor descriptor type */
+ (desc[2] != 0x01) || /* version (2 bytes) */
+ (desc[3] != 0x00) ||
+ (desc[4] != total_len - 2)) /* length after type */
+ goto unrecognized;
+
+ desc_end = desc + total_len;
+ desc += 5; /* the fixed header we've already parsed */
+
+ while (desc < desc_end) {
+ u8 length;
+ u16 key;
+
+ key = *((u16 *) desc);
+ desc += sizeof(u16);
+ length = *desc;
+ desc++;
+
+ switch (key) {
+ case 0x0200: { /* max_area */
+ u32 max_area;
+ max_area = le32_to_cpu(*((u32 *)desc));
+ dl_warn("DL chip limited to %d pixel modes\n",
+ max_area);
+ dev->sku_pixel_limit = max_area;
+ break;
+ }
+ default:
+ break;
+ }
+ desc += length;
+ }
+ }
+
+ goto success;
+unrecognized:
+ /* allow udlfb to load for now even if firmware unrecognized */
+ dl_err("Unrecognized vendor firmware descriptor\n");
+
+success:
+ kfree(buf);
+ return true;
+}
static int dlfb_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct usb_device *usbdev;
- struct dlfb_data *dev;
- struct fb_info *info;
- int videomemorysize;
- int i;
- unsigned char *videomemory;
+ struct dlfb_data *dev = 0;
+ struct fb_info *info = 0;
int retval = -ENOMEM;
- struct fb_var_screeninfo *var;
- int registered = 0;
- u16 *pix_framebuffer;
+ int i;
/* usb initialization */
@@ -1254,20 +1551,33 @@ static int dlfb_usb_probe(struct usb_interface *interface,
/* we need to wait for both usb and fbdev to spin down on disconnect */
kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
- kref_get(&dev->kref); /* matching kref_put in .fb_destroy function*/
+ kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
dev->udev = usbdev;
dev->gdev = &usbdev->dev; /* our generic struct device * */
usb_set_intfdata(interface, dev);
+ dl_info("%s %s - serial #%s\n",
+ usbdev->manufacturer, usbdev->product, usbdev->serial);
+ dl_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
+ usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
+ usbdev->descriptor.bcdDevice, dev);
+ dl_info("console enable=%d\n", console);
+ dl_info("fb_defio enable=%d\n", fb_defio);
+
+ dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */
+
+ if (!dlfb_parse_vendor_descriptor(dev, usbdev)) {
+ dl_err("firmware not recognized. Assume incompatible device\n");
+ goto error;
+ }
+
if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
retval = -ENOMEM;
dl_err("dlfb_alloc_urb_list failed\n");
goto error;
}
- mutex_init(&dev->fb_open_lock);
-
/* We don't register a new USB class. Our client interface is fbdev */
/* allocates framebuffer driver structure, not framebuffer memory */
@@ -1277,110 +1587,76 @@ static int dlfb_usb_probe(struct usb_interface *interface,
dl_err("framebuffer_alloc failed\n");
goto error;
}
+
dev->info = info;
info->par = dev;
info->pseudo_palette = dev->pseudo_palette;
info->fbops = &dlfb_ops;
- var = &info->var;
-
- /* TODO set limit based on actual SKU detection */
- dev->sku_pixel_limit = 2048 * 1152;
-
- INIT_LIST_HEAD(&info->modelist);
- dlfb_parse_edid(dev, var, info);
-
- /*
- * ok, now that we've got the size info, we can alloc our framebuffer.
- */
- info->fix = dlfb_fix;
- info->fix.line_length = var->xres * (var->bits_per_pixel / 8);
- videomemorysize = info->fix.line_length * var->yres;
-
- /*
- * The big chunk of system memory we use as a virtual framebuffer.
- * TODO: Handle fbcon cursor code calling blit in interrupt context
- */
- videomemory = vmalloc(videomemorysize);
- if (!videomemory) {
- retval = -ENOMEM;
- dl_err("Virtual framebuffer alloc failed\n");
+ retval = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (retval < 0) {
+ dl_err("fb_alloc_cmap failed %x\n", retval);
goto error;
}
- info->screen_base = videomemory;
- info->fix.smem_len = PAGE_ALIGN(videomemorysize);
- info->fix.smem_start = (unsigned long) videomemory;
- info->flags = udlfb_info_flags;
-
+ INIT_DELAYED_WORK(&dev->free_framebuffer_work,
+ dlfb_free_framebuffer_work);
- /*
- * Second framebuffer copy, mirroring the state of the framebuffer
- * on the physical USB device. We can function without this.
- * But with imperfect damage info we may end up sending pixels over USB
- * that were, in fact, unchanged -- wasting limited USB bandwidth
- */
- dev->backing_buffer = vmalloc(videomemorysize);
- if (!dev->backing_buffer)
- dl_warn("No shadow/backing buffer allcoated\n");
- else
- memset(dev->backing_buffer, 0, videomemorysize);
+ INIT_LIST_HEAD(&info->modelist);
- retval = fb_alloc_cmap(&info->cmap, 256, 0);
- if (retval < 0) {
- dl_err("fb_alloc_cmap failed %x\n", retval);
+ retval = dlfb_setup_modes(dev, info, NULL, 0);
+ if (retval != 0) {
+ dl_err("unable to find common mode for display and adapter\n");
goto error;
}
/* ready to begin using device */
-#ifdef CONFIG_FB_DEFERRED_IO
- atomic_set(&dev->use_defio, 1);
-#endif
atomic_set(&dev->usb_active, 1);
dlfb_select_std_channel(dev);
- dlfb_ops_check_var(var, info);
+ dlfb_ops_check_var(&info->var, info);
dlfb_ops_set_par(info);
- /* paint greenscreen */
- pix_framebuffer = (u16 *) videomemory;
- for (i = 0; i < videomemorysize / 2; i++)
- pix_framebuffer[i] = 0x37e6;
-
- dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
- videomemory);
-
retval = register_framebuffer(info);
if (retval < 0) {
dl_err("register_framebuffer failed %d\n", retval);
goto error;
}
- registered = 1;
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
device_create_file(info->dev, &fb_device_attrs[i]);
device_create_bin_file(info->dev, &edid_attr);
- dl_err("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
+ dl_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
" Using %dK framebuffer memory\n", info->node,
- var->xres, var->yres,
+ info->var.xres, info->var.yres,
((dev->backing_buffer) ?
- videomemorysize * 2 : videomemorysize) >> 10);
+ info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
return 0;
error:
if (dev) {
- if (registered) {
- unregister_framebuffer(info);
- dlfb_ops_destroy(info);
- } else
- kref_put(&dev->kref, dlfb_delete);
- if (dev->urbs.count > 0)
- dlfb_free_urb_list(dev);
- kref_put(&dev->kref, dlfb_delete); /* last ref from kref_init */
+ if (info) {
+ if (info->cmap.len != 0)
+ fb_dealloc_cmap(&info->cmap);
+ if (info->monspecs.modedb)
+ fb_destroy_modedb(info->monspecs.modedb);
+ if (info->screen_base)
+ vfree(info->screen_base);
+
+ fb_destroy_modelist(&info->modelist);
+
+ framebuffer_release(info);
+ }
+
+ if (dev->backing_buffer)
+ vfree(dev->backing_buffer);
+
+ kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
+ kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
/* dev has been deallocated. Do not dereference */
}
@@ -1397,27 +1673,27 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
dev = usb_get_intfdata(interface);
info = dev->info;
- /* when non-active we'll update virtual framebuffer, but no new urbs */
- atomic_set(&dev->usb_active, 0);
+ dl_info("USB disconnect starting\n");
- usb_set_intfdata(interface, NULL);
+ /* we virtualize until all fb clients release. Then we free */
+ dev->virtualized = true;
+ /* When non-active we'll update virtual framebuffer, but no new urbs */
+ atomic_set(&dev->usb_active, 0);
+
+ /* remove udlfb's sysfs interfaces */
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
device_remove_file(info->dev, &fb_device_attrs[i]);
-
device_remove_bin_file(info->dev, &edid_attr);
- /* this function will wait for all in-flight urbs to complete */
- dlfb_free_urb_list(dev);
+ usb_set_intfdata(interface, NULL);
- if (info) {
- dl_notice("Detaching /dev/fb%d\n", info->node);
- unregister_framebuffer(info);
- dlfb_ops_destroy(info);
- }
+ /* if clients still have us open, will be freed on last close */
+ if (dev->fb_count == 0)
+ schedule_delayed_work(&dev->free_framebuffer_work, 0);
/* release reference taken by kref_init in probe() */
- kref_put(&dev->kref, dlfb_delete);
+ kref_put(&dev->kref, dlfb_free);
/* consider dlfb_data freed */
@@ -1439,8 +1715,6 @@ static int __init dlfb_module_init(void)
if (res)
err("usb_register failed. Error number %d", res);
- printk(KERN_INFO "VMODES initialized\n");
-
return res;
}
@@ -1476,7 +1750,14 @@ static void dlfb_urb_completion(struct urb *urb)
dev->urbs.available++;
spin_unlock_irqrestore(&dev->urbs.lock, flags);
- up(&dev->urbs.limit_sem);
+ /*
+ * When using fb_defio, we deadlock if up() is called
+ * while another is waiting. So queue to another process.
+ */
+ if (fb_defio)
+ schedule_delayed_work(&unode->release_urb_work, 0);
+ else
+ up(&dev->urbs.limit_sem);
}
static void dlfb_free_urb_list(struct dlfb_data *dev)
@@ -1492,12 +1773,12 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
/* keep waiting and freeing, until we've got 'em all */
while (count--) {
- /* Timeout means a memory leak and/or fault */
- ret = down_timeout(&dev->urbs.limit_sem, FREE_URB_TIMEOUT);
- if (ret) {
- BUG_ON(ret);
+
+ /* Getting interrupted means a leak, but ok at shutdown*/
+ ret = down_interruptible(&dev->urbs.limit_sem);
+ if (ret)
break;
- }
+
spin_lock_irqsave(&dev->urbs.lock, flags);
node = dev->urbs.list.next; /* have reserved one with sem */
@@ -1515,8 +1796,6 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
kfree(node);
}
- kref_put(&dev->kref, dlfb_delete);
-
}
static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
@@ -1537,6 +1816,9 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
break;
unode->dev = dev;
+ INIT_DELAYED_WORK(&unode->release_urb_work,
+ dlfb_release_urb_work);
+
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
kfree(unode);
@@ -1566,8 +1848,6 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
dev->urbs.count = i;
dev->urbs.available = i;
- kref_get(&dev->kref); /* released in free_render_urbs() */
-
dl_notice("allocated %d %d byte urbs\n", i, (int) size);
return i;
@@ -1585,7 +1865,8 @@ static struct urb *dlfb_get_urb(struct dlfb_data *dev)
ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
if (ret) {
atomic_set(&dev->lost_pixels, 1);
- dl_err("wait for urb interrupted: %x\n", ret);
+ dl_warn("wait for urb interrupted: %x available: %d\n",
+ ret, dev->urbs.available);
goto error;
}
@@ -1621,6 +1902,12 @@ static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
return ret;
}
+module_param(console, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
+MODULE_PARM_DESC(console, "Allow fbcon to consume first framebuffer found");
+
+module_param(fb_defio, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
+MODULE_PARM_DESC(fb_defio, "Enable fb_defio mmap support. *Experimental*");
+
MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
"Jaya Kumar <jayakumar.lkml@gmail.com>, "
"Bernie Thompson <bernie@plugable.com>");
diff --git a/drivers/staging/udlfb/udlfb.h b/drivers/staging/udlfb/udlfb.h
index b07a69371f1f..6f9785e9d62e 100644
--- a/drivers/staging/udlfb/udlfb.h
+++ b/drivers/staging/udlfb/udlfb.h
@@ -19,6 +19,7 @@ struct dloarea {
struct urb_node {
struct list_head entry;
struct dlfb_data *dev;
+ struct delayed_work release_urb_work;
struct urb *urb;
};
@@ -38,13 +39,13 @@ struct dlfb_data {
struct urb_list urbs;
struct kref kref;
char *backing_buffer;
- struct delayed_work deferred_work;
- struct mutex fb_open_lock;
int fb_count;
+ bool virtualized; /* true when physical usb device not present */
+ struct delayed_work free_framebuffer_work;
atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
- atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */
- char edid[128];
+ char *edid; /* null until we read edid from hw or get from sysfs */
+ size_t edid_size;
int sku_pixel_limit;
int base16;
int base8;
@@ -54,12 +55,6 @@ struct dlfb_data {
atomic_t bytes_identical; /* saved effort with backbuffer comparison */
atomic_t bytes_sent; /* to usb, after compression including overhead */
atomic_t cpu_kcycles_used; /* transpired during pixel processing */
- /* interface usage metrics. Clients can call driver via several */
- atomic_t blit_count;
- atomic_t copy_count;
- atomic_t fill_count;
- atomic_t damage_count;
- atomic_t defio_fault_count;
};
#define NR_USB_REQUEST_I2C_SUB_IO 0x02
@@ -70,6 +65,11 @@ struct dlfb_data {
#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
#define WRITES_IN_FLIGHT (4)
+#define MIN_EDID_SIZE 128
+#define MAX_EDID_SIZE 128
+
+#define MAX_VENDOR_DESCRIPTOR_SIZE 256
+
#define GET_URB_TIMEOUT HZ
#define FREE_URB_TIMEOUT (HZ*2)
@@ -88,6 +88,9 @@ struct dlfb_data {
#define MIN_RAW_PIX_BYTES 2
#define MIN_RAW_CMD_BYTES (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
+#define DL_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */
+#define DL_DEFIO_WRITE_DISABLE (HZ*60) /* "disable" with long delay */
+
/* remove these once align.h patch is taken into kernel */
#define DL_ALIGN_UP(x, a) ALIGN(x, a)
#define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a)
@@ -95,12 +98,20 @@ struct dlfb_data {
/* remove once this gets added to sysfs.h */
#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
+/*
+ * udlfb is both a usb device, and a framebuffer device.
+ * They may exist at the same time, but during various stages
+ * inactivity, teardown, or "virtual" operation, only one or the
+ * other will exist (one will outlive the other). So we can't
+ * call the dev_*() macros, because we don't have a stable dev object.
+ */
#define dl_err(format, arg...) \
- dev_err(dev->gdev, "dlfb: " format, ## arg)
+ pr_err("udlfb: " format, ## arg)
#define dl_warn(format, arg...) \
- dev_warn(dev->gdev, "dlfb: " format, ## arg)
+ pr_warning("udlfb: " format, ## arg)
#define dl_notice(format, arg...) \
- dev_notice(dev->gdev, "dlfb: " format, ## arg)
+ pr_notice("udlfb: " format, ## arg)
#define dl_info(format, arg...) \
- dev_info(dev->gdev, "dlfb: " format, ## arg)
+ pr_info("udlfb: " format, ## arg)
+
#endif
diff --git a/drivers/staging/udlfb/udlfb.txt b/drivers/staging/udlfb/udlfb.txt
new file mode 100644
index 000000000000..7fdde2a02a27
--- /dev/null
+++ b/drivers/staging/udlfb/udlfb.txt
@@ -0,0 +1,144 @@
+
+What is udlfb?
+===============
+
+This is a driver for DisplayLink USB 2.0 era graphics chips.
+
+DisplayLink chips provide simple hline/blit operations with some compression,
+pairing that with a hardware framebuffer (16MB) on the other end of the
+USB wire. That hardware framebuffer is able to drive the VGA, DVI, or HDMI
+monitor with no CPU involvement until a pixel has to change.
+
+The CPU or other local resource does all the rendering; optinally compares the
+result with a local shadow of the remote hardware framebuffer to identify
+the minimal set of pixels that have changed; and compresses and sends those
+pixels line-by-line via USB bulk transfers.
+
+Because of the efficiency of bulk transfers and a protocol on top that
+does not require any acks - the effect is very low latency that
+can support surprisingly high resolutions with good performance for
+non-gaming and non-video applications.
+
+Mode setting, EDID read, etc are other bulk or control transfers. Mode
+setting is very flexible - able to set nearly arbitrary modes from any timing.
+
+Advantages of USB graphics in general:
+
+ * Ability to add a nearly arbitrary number of displays to any USB 2.0
+ capable system. On Linux, number of displays is limited by fbdev interface
+ (FB_MAX is currently 32). Of course, all USB devices on the same
+ host controller share the same 480Mbs USB 2.0 interface.
+
+Advantages of supporting DisplayLink chips with kernel framebuffer interface:
+
+ * The actual hardware functionality of DisplayLink chips matches nearly
+ one-to-one with the fbdev interface, making the driver quite small and
+ tight relative to the functionality it provides.
+ * X servers and other applications can use the standard fbdev interface
+ from user mode to talk to the device, without needing to know anything
+ about USB or DisplayLink's protocol at all. A "displaylink" X driver
+ and a slightly modified "fbdev" X driver are among those that already do.
+
+Disadvantages:
+
+ * Fbdev's mmap interface assumes a real hardware framebuffer is mapped.
+ In the case of USB graphics, it is just an allocated (virtual) buffer.
+ Writes need to be detected and encoded into USB bulk transfers by the CPU.
+ Accurate damage/changed area notifications work around this problem.
+ In the future, hopefully fbdev will be enhanced with an small standard
+ interface to allow mmap clients to report damage, for the benefit
+ of virtual or remote framebuffers.
+ * Fbdev does not arbitrate client ownership of the framebuffer well.
+ * Fbcon assumes the first framebuffer it finds should be consumed for console.
+ * It's not clear what the future of fbdev is, given the rise of KMS/DRM.
+
+How to use it?
+==============
+
+Udlfb, when loaded as a module, will match against all USB 2.0 generation
+DisplayLink chips (Alex and Ollie family). It will then attempt to read the EDID
+of the monitor, and set the best common mode between the DisplayLink device
+and the monitor's capabilities.
+
+If the DisplayLink device is successful, it will paint a "green screen" which
+means that from a hardware and fbdev software perspective, everything is good.
+
+At that point, a /dev/fb? interface will be present for user-mode applications
+to open and begin writing to the framebuffer of the DisplayLink device using
+standard fbdev calls. Note that if mmap() is used, by default the user mode
+application must send down damage notifcations to trigger repaints of the
+changed regions. Alternatively, udlfb can be recompiled with experimental
+defio support enabled, to support a page-fault based detection mechanism
+that can work without explicit notifcation.
+
+The most common client of udlfb is xf86-video-displaylink or a modified
+xf86-video-fbdev X server. These servers have no real DisplayLink specific
+code. They write to the standard framebuffer interface and rely on udlfb
+to do its thing. The one extra feature they have is the ability to report
+rectangles from the X DAMAGE protocol extension down to udlfb via udlfb's
+damage interface (which will hopefully be standardized for all virtual
+framebuffers that need damage info). These damage notifications allow
+udlfb to efficiently process the changed pixels.
+
+Module Options
+==============
+
+Special configuration for udlfb is usually unnecessary. There are a few
+options, however.
+
+From the command line, pass options to modprobe
+modprobe udlfb defio=1 console=1
+
+Or for permanent option, create file like /etc/modprobe.d/options with text
+options udlfb defio=1 console=1
+
+Accepted options:
+
+fb_defio Make use of the fb_defio (CONFIG_FB_DEFERRED_IO) kernel
+ module to track changed areas of the framebuffer by page faults.
+ Standard fbdev applications that use mmap but that do not
+ report damage, may be able to work with this enabled.
+ Disabled by default because of overhead and other issues.
+
+console Allow fbcon to attach to udlfb provided framebuffers. This
+ is disabled by default because fbcon will aggressively consume
+ the first framebuffer it finds, which isn't usually what the
+ user wants in the case of USB displays.
+
+Sysfs Attributes
+================
+
+Udlfb creates several files in /sys/class/graphics/fb?
+Where ? is the sequential framebuffer id of the particular DisplayLink device
+
+edid If a valid EDID blob is written to this file (typically
+ by a udev rule), then udlfb will use this EDID as a
+ backup in case reading the actual EDID of the monitor
+ attached to the DisplayLink device fails. This is
+ especially useful for fixed panels, etc. that cannot
+ communicate their capabilities via EDID. Reading
+ this file returns the current EDID of the attached
+ monitor (or last backup value written). This is
+ useful to get the EDID of the attached monitor,
+ which can be passed to utilities like parse-edid.
+
+metrics_bytes_rendered 32-bit count of pixel bytes rendered
+
+metrics_bytes_identical 32-bit count of how many of those bytes were found to be
+ unchanged, based on a shadow framebuffer check
+
+metrics_bytes_sent 32-bit count of how many bytes were transferred over
+ USB to communicate the resulting changed pixels to the
+ hardware. Includes compression and protocol overhead
+
+metrics_cpu_kcycles_used 32-bit count of CPU cycles used in processing the
+ above pixels (in thousands of cycles).
+
+metrics_reset Write-only. Any write to this file resets all metrics
+ above to zero. Note that the 32-bit counters above
+ roll over very quickly. To get reliable results, design
+ performance tests to start and finish in a very short
+ period of time (one minute or less is safe).
+
+--
+Bernie Thompson <bernie@plugable.com>
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index b6b753a49346..b186b5fed2b9 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -427,11 +427,11 @@ static int stub_probe(struct usb_interface *interface,
if (busid_priv->status == STUB_BUSID_ALLOC) {
- busid_priv->interf_count++;
sdev = busid_priv->sdev;
if (!sdev)
return -ENODEV;
+ busid_priv->interf_count++;
dev_info(&interface->dev,
"USB/IP Stub: register a new interface "
"(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 8f77bd24630c..71bbc526626c 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -683,7 +683,7 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
for (i = 0; i < VME_DEVS; i++) {
image[i].kern_buf = NULL;
image[i].pci_buf = 0;
- init_MUTEX(&(image[i].sem));
+ sema_init(&(image[i].sem), 1);
image[i].device = NULL;
image[i].resource = NULL;
image[i].users = 0;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 4d6b66a4fd9d..f5028d9d7d9b 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -955,12 +955,13 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
pDevice->dev = dev;
pDevice->next_module = root_device_dev;
root_device_dev = dev;
- dev->irq = pcid->irq;
if (pci_enable_device(pcid)) {
device_free_info(pDevice);
return -ENODEV;
}
+ dev->irq = pcid->irq;
+
#ifdef DEBUG
printk("Before get pci_info memaddr is %x\n",pDevice->memaddr);
#endif
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index 43227617aabe..4009c0b5bb27 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -1900,7 +1900,7 @@ int iwctl_siwgenie(struct net_device *dev,
}
out://not completely ...not necessary in wpa_supplicant 0.5.8
- return 0;
+ return ret;
}
int iwctl_giwgenie(struct net_device *dev,
diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c
index 0142338bcafe..4bdb8362de82 100644
--- a/drivers/staging/vt6655/wpactl.c
+++ b/drivers/staging/vt6655/wpactl.c
@@ -766,9 +766,14 @@ static int wpa_set_associate(PSDevice pDevice,
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
- if (param->u.wpa_associate.wpa_ie &&
- copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
- return -EINVAL;
+ if (param->u.wpa_associate.wpa_ie_len) {
+ if (!param->u.wpa_associate.wpa_ie)
+ return -EINVAL;
+ if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
+ return -EINVAL;
+ if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
+ return -EFAULT;
+ }
if (param->u.wpa_associate.mode == 1)
pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h
index 3d57f793986d..515b9c1d4d10 100644
--- a/drivers/staging/vt6656/80211mgr.h
+++ b/drivers/staging/vt6656/80211mgr.h
@@ -66,9 +66,9 @@
#define WLAN_EID_RSN_WPA 221
#ifdef Cisco_ccx
-#define WLAN_EID_CCX 133 //DavidWang
-#define WLAN_EID_CCX_IP 149 //DavidWang
-#define WLAN_EID_CCX_Ver 221 //DavidWang
+#define WLAN_EID_CCX 133
+#define WLAN_EID_CCX_IP 149
+#define WLAN_EID_CCX_Ver 221
#endif
#define WLAN_EID_ERP_NONERP_PRESENT 0x01
@@ -348,7 +348,7 @@ typedef struct tagWLAN_IE_RSN {
BYTE abyRSN[WLAN_MIN_ARRAY];
} WLAN_IE_RSN, *PWLAN_IE_RSN;
-//DavidWang
+
// CCX Identity DavidWang
#pragma pack(1)
typedef struct tagWLAN_IE_CCX {
@@ -371,7 +371,7 @@ BYTE len;
BYTE abyCCXVer[5];
} WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver;
-//DavidWang
+
// ERP
#pragma pack(1)
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
index 29902492975c..e5add2046375 100644
--- a/drivers/staging/vt6656/baseband.c
+++ b/drivers/staging/vt6656/baseband.c
@@ -1010,11 +1010,9 @@ BOOL BBbVT3184Init(PSDevice pDevice)
}
- //20080215-01,<Add> by Mike Liu
// if ((pDevice->abyEEPROM[EEP_OFS_RADIOCTL]&0x06)==0x04)
// return FALSE;
-//20080804-01,<Add> by Mike Liu
//zonetype initial
pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
if(pDevice->config_file.ZoneType >= 0) { //read zonetype file ok!
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
index a9f68bd5afa6..2bdd0a2028d2 100644
--- a/drivers/staging/vt6656/bssdb.c
+++ b/drivers/staging/vt6656/bssdb.c
@@ -148,7 +148,6 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
for (ii = 0; ii <MAX_BSS_NUM; ii++) {
pCurrBSS = &(pMgmt->sBSSList[ii]);
- //2008-0718-01<Add>by MikeLiu
pCurrBSS->bSelected = FALSE;
if ((pCurrBSS->bActive) &&
@@ -188,7 +187,6 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
// if ((pCurrBSS->bActive) &&
// (pCurrBSS->bSelected == FALSE)) {
- //2007-0721-01<Add>by MikeLiu
pCurrBSS->bSelected = FALSE;
if (pCurrBSS->bActive) {
@@ -238,12 +236,12 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
}
}
*/
-//DavidWang
+
pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList pSelect1[%02X %02X %02X-%02X %02X %02X]\n",*pCurrBSS->abyBSSID,*(pCurrBSS->abyBSSID+1),*(pCurrBSS->abyBSSID+2),*(pCurrBSS->abyBSSID+3),*(pCurrBSS->abyBSSID+4),*(pCurrBSS->abyBSSID+5));
jj++;
-//DavidWang
+
if (pSelect == NULL) {
pSelect = pCurrBSS;
} else {
@@ -254,9 +252,9 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext,
}
}
}
-//DavidWang
+
pDevice->bSameBSSMaxNum = jj;
-//DavidWang
+
if (pSelect != NULL) {
pSelect->bSelected = TRUE;
if (pDevice->bRoaming == FALSE) {
@@ -956,7 +954,7 @@ void BSSvSecondCallBack(void *hDeviceContext)
unsigned int uSleepySTACnt = 0;
unsigned int uNonShortSlotSTACnt = 0;
unsigned int uLongPreambleSTACnt = 0;
- viawget_wpa_header *wpahdr; //DavidWang
+ viawget_wpa_header *wpahdr;
spin_lock_irq(&pDevice->lock);
@@ -1180,7 +1178,7 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
pDevice->bIsRoaming = FALSE;
DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
- //let wpa supplicant know AP may disconnect.//20080717-01,<Add> by James Li
+ /* let wpa supplicant know AP may disconnect */
if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
wpahdr = (viawget_wpa_header *)pDevice->skb->data;
wpahdr->type = VIAWGET_DISASSOC_MSG;
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
index 6ad03e492edb..a2460ae1ec42 100644
--- a/drivers/staging/vt6656/channel.c
+++ b/drivers/staging/vt6656/channel.c
@@ -34,6 +34,7 @@
*
*/
+#include <linux/kernel.h>
#include "country.h"
#include "channel.h"
#include "rf.h"
@@ -367,7 +368,7 @@ static struct
/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */
};
-#define NUM_RULES (sizeof(ChannelRuleTab) / sizeof(ChannelRuleTab[0]))
+#define NUM_RULES ARRAY_SIZE(ChannelRuleTab)
/*--------------------- Export function -------------------------*/
/************************************************************************
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index b9852aa22c06..e8d0b4203cad 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -258,8 +258,6 @@ typedef enum _VIA_PKT_TYPE
//++ NDIS related
-#define NDIS_STATUS int
-
typedef enum __DEVICE_NDIS_STATUS {
STATUS_SUCCESS = 0,
STATUS_FAILURE,
@@ -267,7 +265,6 @@ typedef enum __DEVICE_NDIS_STATUS {
STATUS_PENDING,
} DEVICE_NDIS_STATUS, *PDEVICE_NDIS_STATUS;
-
#define MAX_BSSIDINFO_4_PMKID 16
#define MAX_PMKIDLIST 5
//Flags for PMKID Candidate list structure
@@ -713,11 +710,11 @@ typedef struct __device_info {
BOOL bCmdClear;
BOOL bNeedRadioOFF;
- BOOL bEnableRoaming; //DavidWang
- BOOL bIsRoaming; //DavidWang
- BOOL bFastRoaming; //DavidWang
- BYTE bSameBSSMaxNum; //Davidwang
- BYTE bSameBSSCurNum; //DavidWang
+ BOOL bEnableRoaming;
+ BOOL bIsRoaming;
+ BOOL bFastRoaming;
+ BYTE bSameBSSMaxNum;
+ BYTE bSameBSSCurNum;
BOOL bRoaming;
BOOL b11hEable;
unsigned long ulTxPower;
@@ -726,7 +723,6 @@ typedef struct __device_info {
NDIS_802_11_WEP_STATUS eEncryptionStatus;
BOOL bTransmitKey;
-//2007-0925-01<Add>by MikeLiu
//mike add :save old Encryption
NDIS_802_11_WEP_STATUS eOldEncryptionStatus;
@@ -891,11 +887,8 @@ typedef struct __device_info {
#define fMP_CONTROL_READS 0x00000400
#define fMP_CONTROL_WRITES 0x00000800
-
-
#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
-#define MP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
#define MP_IS_READY(_M) (((_M)->Flags & \
@@ -909,5 +902,3 @@ typedef struct __device_info {
BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
#endif
-
-
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 5e88349d3b95..1f9d29636803 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -200,10 +200,9 @@ s_vProcessRxMACHeader (
} else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
cbHeaderSize += 6;
pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
- if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
- }
- else {
- cbHeaderSize -= 8;
+ if ((*pwType == cpu_to_le16(ETH_P_IPX)) ||
+ (*pwType == cpu_to_le16(0xF380))) {
+ cbHeaderSize -= 8;
pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
if (bIsWEP) {
if (bExtIV) {
@@ -377,9 +376,9 @@ RXbBulkInProcessData (
return FALSE;
}
- if ((BytesToIndicate > 2372)||(BytesToIndicate <= 40)) {
+ if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) {
// Frame Size error drop this packet.
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n");
return FALSE;
}
@@ -865,7 +864,6 @@ RXbBulkInProcessData (
pDevice->dev->name);
}
}
- //2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//send event to wpa_supplicant
//if(pDevice->bWPASuppWextEnabled == TRUE)
@@ -1524,7 +1522,8 @@ void RXvWorkItem(void *Context)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
spin_lock_irq(&pDevice->lock);
- while ( MP_TEST_FLAG(pDevice, fMP_POST_READS) &&
+
+ while ((pDevice->Flags & fMP_POST_READS) &&
MP_IS_READY(pDevice) &&
(pDevice->NumRecvFreeList != 0) ) {
pRCB = pDevice->FirstRecvFreeList;
@@ -1569,7 +1568,7 @@ RXvFreeRCB(
pDevice->NumRecvFreeList++;
- if (MP_TEST_FLAG(pDevice, fMP_POST_READS) && MP_IS_READY(pDevice) &&
+ if ((pDevice->Flags & fMP_POST_READS) && MP_IS_READY(pDevice) &&
(pDevice->bIsRxWorkItemQueued == FALSE) ) {
pDevice->bIsRxWorkItemQueued = TRUE;
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
index ebb9c99df70c..ad06fd1398e6 100644
--- a/drivers/staging/vt6656/firmware.c
+++ b/drivers/staging/vt6656/firmware.c
@@ -773,7 +773,7 @@ FIRMWAREbDownload(
PSDevice pDevice
)
{
- NDIS_STATUS NdisStatus;
+ int NdisStatus;
PBYTE pBuffer = NULL;
WORD wLength;
int ii;
@@ -823,7 +823,7 @@ FIRMWAREbBrach2Sram(
PSDevice pDevice
)
{
- NDIS_STATUS NdisStatus;
+ int NdisStatus;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
index d532618639bc..2fe071ca42fa 100644
--- a/drivers/staging/vt6656/ioctl.c
+++ b/drivers/staging/vt6656/ioctl.c
@@ -670,7 +670,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
pMgmt->Cisco_cckm =1;
else
pMgmt->Cisco_cckm =0;
-//DavidWang
+
if(wpa_Result.authenticated==TRUE) {
{
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index 016b8e7766f3..0004be8e3957 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -49,7 +49,6 @@
/*--------------------- Static Definitions -------------------------*/
-//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
#define SUPPORTED_WIRELESS_EXT 18
#else
@@ -155,7 +154,6 @@ int iwctl_siwscan(struct net_device *dev,
BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
PWLAN_IE_SSID pItemSSID=NULL;
-//2008-0920-01<Add>by MikeLiu
if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
return -EINVAL;
@@ -285,7 +283,6 @@ int iwctl_giwscan(struct net_device *dev,
iwe.u.freq.e = 0;
iwe.u.freq.i = 0;
current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
- //2008-0409-04, <Add> by Einsn Liu
{
int f = (int)pBSS->uChannel - 1;
if(f < 0)f = 0;
@@ -299,7 +296,7 @@ int iwctl_giwscan(struct net_device *dev,
RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
iwe.u.qual.level = ldBm;
iwe.u.qual.noise = 0;
-//2008-0409-01, <Add> by Einsn Liu
+
if(-ldBm<50){
iwe.u.qual.qual = 100;
}else if(-ldBm > 90) {
@@ -803,7 +800,6 @@ int iwctl_siwessid(struct net_device *dev,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PWLAN_IE_SSID pItemSSID;
-//2008-0920-01<Add>by MikeLiu
if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
return -EINVAL;
@@ -931,11 +927,10 @@ int iwctl_giwessid(struct net_device *dev,
//pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
extra[pItemSSID->len] = '\0';
- //2008-0409-03, <Add> by Einsn Liu
+
wrq->length = pItemSSID->len;
wrq->flags = 1; // active
-
return 0;
}
@@ -1392,8 +1387,6 @@ int iwctl_giwencode(struct net_device *dev,
}
*/
-//2008-0409-06, <Add> by Einsn Liu
-
int iwctl_giwencode(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
@@ -1561,7 +1554,6 @@ int iwctl_giwsens(struct net_device *dev,
return 0;
}
-//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
int iwctl_siwauth(struct net_device *dev,
@@ -1598,7 +1590,8 @@ int iwctl_siwauth(struct net_device *dev,
pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
}else if(pairwise == IW_AUTH_CIPHER_TKIP){
pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- }else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){
+ } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
+ pairwise == IW_AUTH_CIPHER_WEP104) {
pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
}else if(pairwise == IW_AUTH_CIPHER_NONE){
//do nothing,einsn liu
@@ -1726,7 +1719,7 @@ int iwctl_siwgenie(struct net_device *dev,
}
out://not completely ...not necessary in wpa_supplicant 0.5.8
- return 0;
+ return ret;
}
int iwctl_giwgenie(struct net_device *dev,
@@ -1933,9 +1926,6 @@ int iwctl_siwmlme(struct net_device *dev,
}
#endif
-//End Add --//2008-0409-07, <Add> by Einsn Liu
-
-
/*------------------------------------------------------------------*/
/*
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
index d601e9220219..cc48954783fc 100644
--- a/drivers/staging/vt6656/iwctl.h
+++ b/drivers/staging/vt6656/iwctl.h
@@ -178,7 +178,6 @@ int iwctl_siwscan(struct net_device *dev,
struct iw_param *wrq,
char *extra);
-//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
int iwctl_siwauth(struct net_device *dev,
struct iw_request_info *info,
@@ -215,8 +214,6 @@ int iwctl_siwmlme(struct net_device *dev,
struct iw_point *wrq,
char *extra);
#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-//End Add -- //2008-0409-07, <Add> by Einsn Liu
-
extern const struct iw_handler_def iwctl_handler_def;
extern const struct iw_priv_args iwctl_private_args;
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index d181a2f66266..27bb523c8a97 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -559,7 +559,7 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType,
int i, ii;
*pKey = NULL;
- for (i=0;i<MAX_KEY_TABLE;i++) {
+ for (i = 0; i < MAX_KEY_TABLE; i++) {
if ((pTable->KeyTable[i].bInUse == TRUE) &&
!compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index c528ef0f8ed4..e992d5d9e15b 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -282,7 +282,6 @@ static int Config_FileGetParameter(unsigned char *string,
unsigned char *dest,
unsigned char *source);
-//2008-0714<Add>by Mike Liu
static BOOL device_release_WPADEV(PSDevice pDevice);
static void usb_device_reset(PSDevice pDevice);
@@ -771,10 +770,9 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
udev = usb_get_dev(udev);
netdev = alloc_etherdev(sizeof(DEVICE_INFO));
-
if (!netdev) {
printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
- kfree(pDevice);
+ rc = -ENOMEM;
goto err_nomem;
}
@@ -800,9 +798,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
rc = register_netdev(netdev);
if (rc) {
printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
- free_netdev(netdev);
- kfree(pDevice);
- return -ENODEV;
+ goto err_netdev;
}
usb_device_reset(pDevice);
@@ -820,10 +816,12 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0;
+err_netdev:
+ free_netdev(netdev);
err_nomem:
usb_put_dev(udev);
- return -ENOMEM;
+ return rc;
}
static void device_free_tx_bufs(PSDevice pDevice)
@@ -869,7 +867,6 @@ static void device_free_rx_bufs(PSDevice pDevice)
return;
}
-//2007-1107-02<Add>by MikeLiu
static void usb_device_reset(PSDevice pDevice)
{
int status;
@@ -1091,8 +1088,8 @@ static int device_open(struct net_device *dev) {
memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
pDevice->bStopTx0Pkt = FALSE;
pDevice->bStopDataPkt = FALSE;
- pDevice->bRoaming = FALSE; //DavidWang
- pDevice->bIsRoaming = FALSE;//DavidWang
+ pDevice->bRoaming = FALSE;
+ pDevice->bIsRoaming = FALSE;
pDevice->bEnableRoaming = FALSE;
if (pDevice->bDiversityRegCtlON) {
device_init_diversity_timer(pDevice);
@@ -1195,14 +1192,11 @@ static int device_close(struct net_device *dev) {
wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
}
-//2007-1121-02<Add>by EinsnLiu
if (pDevice->bLinkPass) {
bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
mdelay(30);
}
-//End Add
-//2008-0714-01<Add>by MikeLiu
device_release_WPADEV(pDevice);
memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
@@ -1236,8 +1230,8 @@ device_release_WPADEV(pDevice);
tasklet_kill(&pDevice->ReadWorkItem);
tasklet_kill(&pDevice->EventWorkItem);
- pDevice->bRoaming = FALSE; //DavidWang
- pDevice->bIsRoaming = FALSE;//DavidWang
+ pDevice->bRoaming = FALSE;
+ pDevice->bIsRoaming = FALSE;
pDevice->bEnableRoaming = FALSE;
pDevice->bCmdRunning = FALSE;
pDevice->bLinkPass = FALSE;
@@ -1914,11 +1908,9 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
*/
break;
-
-//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
case SIOCSIWAUTH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
break;
@@ -1970,7 +1962,6 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
break;
#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-//End Add -- //2008-0409-07, <Add> by Einsn Liu
case IOCTL_CMD_TEST:
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index 4d7d4e014d00..0c12fd36d0f9 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -77,12 +77,12 @@ void PSvEnablePowerSaving(void *hDeviceContext,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
WORD wAID = pMgmt->wCurrAID | BIT14 | BIT15;
- // set period of power up before TBTT
+ /* set period of power up before TBTT */
MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT);
if (pDevice->eOPMode != OP_MODE_ADHOC) {
- // set AID
- MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
+ /* set AID */
+ MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
} else {
// set ATIM Window
//MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index deca2137d921..bbdc127a987d 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -841,8 +841,8 @@ s_uFillDataHead (
}
if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
- if((uDMAIdx==TYPE_ATIMDMA)||(uDMAIdx==TYPE_BEACONDMA)) {
- PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+ if ((uDMAIdx == TYPE_ATIMDMA) || (uDMAIdx == TYPE_BEACONDMA)) {
+ PSTxDataHead_ab pBuf = (PSTxDataHead_ab) pTxDataHead;
//Get SignalField,ServiceField,Length
BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
(PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
@@ -1701,10 +1701,11 @@ s_bPacketToWirelessUsb(
// 802.1H
if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {
- if (pDevice->dwDiagRefCount == 0) {
- if ( (psEthHeader->wType == TYPE_PKT_IPX) ||
- (psEthHeader->wType == cpu_to_le16(0xF380))) {
- memcpy((PBYTE) (pbyPayloadHead), &abySNAP_Bridgetunnel[0], 6);
+ if (pDevice->dwDiagRefCount == 0) {
+ if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) ||
+ (psEthHeader->wType == cpu_to_le16(0xF380))) {
+ memcpy((PBYTE) (pbyPayloadHead),
+ abySNAP_Bridgetunnel, 6);
} else {
memcpy((PBYTE) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
}
@@ -2840,9 +2841,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
Packet_Type = skb->data[ETH_HLEN+1];
Descriptor_type = skb->data[ETH_HLEN+1+1+2];
Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
- if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
- if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
- (Packet_Type==3)) { //802.1x OR eapol-key challenge frame transfer
+ if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) {
+ /* 802.1x OR eapol-key challenge frame transfer */
+ if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
+ (Packet_Type == 3)) {
bTxeapol_key = TRUE;
if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
(Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
@@ -2988,7 +2990,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
}
}
- if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
+ if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) {
if (pDevice->byBBType != BB_TYPE_11A) {
pDevice->wCurrentRate = RATE_1M;
pDevice->byACKRate = RATE_1M;
@@ -3016,8 +3018,8 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)
if (bNeedEncryption == TRUE) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
- if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
- bNeedEncryption = FALSE;
+ if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) {
+ bNeedEncryption = FALSE;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
if (pTransmitKey == NULL) {
diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h
index be87020d5323..4ec05237469b 100644
--- a/drivers/staging/vt6656/tether.h
+++ b/drivers/staging/vt6656/tether.h
@@ -42,22 +42,8 @@
#ifdef __BIG_ENDIAN
-#define TYPE_PKT_IP 0x0800 //
-#define TYPE_PKT_ARP 0x0806 //
-#define TYPE_PKT_RARP 0x8035 //
-#define TYPE_PKT_IPX 0x8137 //
-#define TYPE_PKT_802_1x 0x888e
-#define TYPE_PKT_PreAuth 0x88C7
-
-#define TYPE_PKT_PING_M_REQ 0x8011 // master reguest
-#define TYPE_PKT_PING_S_GNT 0x8022 // slave grant
-#define TYPE_PKT_PING_M 0x8077 // pingpong master packet
-#define TYPE_PKT_PING_S 0x8088 // pingpong slave packet
-#define TYPE_PKT_WOL_M_REQ 0x8033 // WOL waker request
-#define TYPE_PKT_WOL_S_GNT 0x8044 // WOL sleeper grant
#define TYPE_MGMT_PROBE_RSP 0x5000
-#define TYPE_PKT_VNT_DIAG 0x8011 // Diag Pkt
-#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt
+
//
// wFrameCtl field in the S802_11Header
//
@@ -94,23 +80,9 @@
//
// NOTE....
// in network byte order, high byte is going first
-#define TYPE_PKT_IP 0x0008 //
-#define TYPE_PKT_ARP 0x0608 //
-#define TYPE_PKT_RARP 0x3580 //
-#define TYPE_PKT_IPX 0x3781 //
-
-#define TYPE_PKT_802_1x 0x8e88
-#define TYPE_PKT_PreAuth 0xC788
-
-#define TYPE_PKT_PING_M_REQ 0x1180 // master reguest
-#define TYPE_PKT_PING_S_GNT 0x2280 // slave grant
-#define TYPE_PKT_PING_M 0x7780 // pingpong master packet
-#define TYPE_PKT_PING_S 0x8880 // pingpong slave packet
-#define TYPE_PKT_WOL_M_REQ 0x3380 // WOL waker request
-#define TYPE_PKT_WOL_S_GNT 0x4480 // WOL sleeper grant
+
#define TYPE_MGMT_PROBE_RSP 0x0050
-#define TYPE_PKT_VNT_DIAG 0x1180 // Diag Pkt
-#define TYPE_PKT_VNT_PER 0x8888 // Diag PER Pkt
+
//
// wFrameCtl field in the S802_11Header
//
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index a32785cb9d18..c612ab58f389 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -118,13 +118,11 @@ int PIPEnsControlOutAsyn(
{
int ntStatus;
- if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+ if (pDevice->Flags & fMP_DISCONNECTED)
return STATUS_FAILURE;
-
- if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
return STATUS_FAILURE;
- }
if (in_interrupt()) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
@@ -164,12 +162,11 @@ int PIPEnsControlOut(
int ntStatus = 0;
int ii;
- if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+ if (pDevice->Flags & fMP_DISCONNECTED)
return STATUS_FAILURE;
- if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
return STATUS_FAILURE;
- }
pDevice->sUsbCtlRequest.bRequestType = 0x40;
pDevice->sUsbCtlRequest.bRequest = byRequest;
@@ -193,12 +190,15 @@ int PIPEnsControlOut(
}
spin_unlock_irq(&pDevice->lock);
for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
- if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES))
- mdelay(1);
+
+ if (pDevice->Flags & fMP_CONTROL_WRITES)
+ mdelay(1);
else
- break;
+ break;
+
if (ii >= USB_CTL_WAIT) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission timeout \n");
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "control send request submission timeout\n");
spin_lock_irq(&pDevice->lock);
MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
return STATUS_FAILURE;
@@ -221,12 +221,12 @@ int PIPEnsControlIn(
int ntStatus = 0;
int ii;
- if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+ if (pDevice->Flags & fMP_DISCONNECTED)
return STATUS_FAILURE;
- if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) {
- return STATUS_FAILURE;
- }
+ if (pDevice->Flags & fMP_CONTROL_READS)
+ return STATUS_FAILURE;
+
pDevice->sUsbCtlRequest.bRequestType = 0xC0;
pDevice->sUsbCtlRequest.bRequest = byRequest;
pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
@@ -247,13 +247,15 @@ int PIPEnsControlIn(
spin_unlock_irq(&pDevice->lock);
for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
- if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS))
- mdelay(1);
- else {
- break;
- }
- if (ii >= USB_CTL_WAIT) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control rcv request submission timeout \n");
+
+ if (pDevice->Flags & fMP_CONTROL_READS)
+ mdelay(1);
+ else
+ break;
+
+ if (ii >= USB_CTL_WAIT) {
+ DBG_PRT(MSG_LEVEL_DEBUG,
+ KERN_INFO "control rcv request submission timeout\n");
spin_lock_irq(&pDevice->lock);
MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
return STATUS_FAILURE;
@@ -492,7 +494,7 @@ int PIPEnsBulkInUsbRead(PSDevice pDevice, PRCB pRCB)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
- if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+ if (pDevice->Flags & fMP_DISCONNECTED)
return STATUS_FAILURE;
pDevice->ulBulkInPosted++;
@@ -618,7 +620,7 @@ s_nsBulkInUsbIoCompleteRead(
* Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
*
*/
-NDIS_STATUS
+int
PIPEnsSendBulkOut(
PSDevice pDevice,
PUSB_SEND_CONTEXT pContext
@@ -643,7 +645,7 @@ PIPEnsSendBulkOut(
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
- if(MP_IS_READY(pDevice) && MP_TEST_FLAG(pDevice, fMP_POST_WRITES)) {
+ if (MP_IS_READY(pDevice) && (pDevice->Flags & fMP_POST_WRITES)) {
pUrb = pContext->pUrb;
pDevice->ulBulkOutPosted++;
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 686747a09294..b83b660b1f0f 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -500,7 +500,7 @@ void vRunCommand(void *hDeviceContext)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
pMgmt->eScanState = WMAC_NO_SCANNING;
pDevice->bStopDataPkt = FALSE;
-//2008-0409-07, <Add> by Einsn Liu
+
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
if(pMgmt->eScanType == WMAC_SCAN_PASSIVE)
{
@@ -876,7 +876,7 @@ void vRunCommand(void *hDeviceContext)
// CARDbRadioPowerOn(pDevice);
// else
// CARDbRadioPowerOff(pDevice);
- //2008-09-09<Add> BY Mike:Hot Key for Radio On/Off
+
{
int ntStatus = STATUS_SUCCESS;
BYTE byTmp;
diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c
index e4eca9b060b1..2ec200d8b736 100644
--- a/drivers/staging/vt6656/wmgr.c
+++ b/drivers/staging/vt6656/wmgr.c
@@ -92,7 +92,7 @@ static int msglevel =MSG_LEVEL_INFO;
//static int msglevel =MSG_LEVEL_DEBUG;
/*--------------------- Static Functions --------------------------*/
-//2008-0730-01<Add>by MikeLiu
+
static BOOL ChannelExceedZoneType(
PSDevice pDevice,
BYTE byCurrChannel
@@ -997,7 +997,7 @@ s_vMgrRxAssocResponse(
netif_rx(pDevice->skb);
pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
}
-//2008-0409-07, <Add> by Einsn Liu
+
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//if(pDevice->bWPASuppWextEnabled == TRUE)
{
@@ -1038,7 +1038,7 @@ s_vMgrRxAssocResponse(
}
#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-//End Add -- //2008-0409-07, <Add> by Einsn Liu
+
}
else {
if (bReAssocType) {
@@ -1745,7 +1745,6 @@ s_vMgrRxDeauthentication(
return;
}
-//2008-0730-01<Add>by MikeLiu
/*+
*
* Routine Description:
@@ -1868,7 +1867,6 @@ s_vMgrRxBeacon(
}
}
-//2008-0730-01<Add>by MikeLiu
if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
return;
@@ -2638,8 +2636,9 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus)
if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
- if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA)||(pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
-/*
+ if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+ (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
+ /*
if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
@@ -4239,7 +4238,6 @@ s_vMgrRxProbeResponse(
}
//RobertYu:20050201
-//2008-0730-01<Add>by MikeLiu
if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
return;
@@ -4767,8 +4765,9 @@ s_bCipherMatch (
if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
(pBSSNode->bWPA2Valid == TRUE) &&
- //20080123-01,<Add> by Einsn Liu
- ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
+
+ ((EncStatus == Ndis802_11Encryption3Enabled) ||
+ (EncStatus == Ndis802_11Encryption2Enabled))) {
//WPA2
// check Group Key Cipher
if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h
index 683840c0ac45..594f3a89d8a7 100644
--- a/drivers/staging/vt6656/wmgr.h
+++ b/drivers/staging/vt6656/wmgr.h
@@ -355,7 +355,7 @@ typedef struct tagSMgmtObject
// link list of known bss's (scan results)
KnownBSS sBSSList[MAX_BSS_NUM];
- //link list of same bss's //DavidWang
+ /* link list of same bss's */
KnownBSS pSameBSS[6] ;
BOOL Cisco_cckm ;
BYTE Roam_dbm;
diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c
index f492778ee8b6..7dde3d6941ab 100644
--- a/drivers/staging/vt6656/wpa.c
+++ b/drivers/staging/vt6656/wpa.c
@@ -69,7 +69,7 @@ const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
-*/
void
-WPA_ClearRSN (
+WPA_ClearRSN(
PKnownBSS pBSSList
)
{
@@ -105,7 +105,7 @@ WPA_ClearRSN (
*
-*/
void
-WPA_ParseRSN (
+WPA_ParseRSN(
PKnownBSS pBSSList,
PWLAN_IE_RSN_EXT pRSN
)
@@ -240,7 +240,7 @@ WPA_ParseRSN (
*
-*/
BOOL
-WPA_SearchRSN (
+WPA_SearchRSN(
BYTE byCmd,
BYTE byEncrypt,
PKnownBSS pBSSList
@@ -300,7 +300,7 @@ WPA_SearchRSN (
*
-*/
BOOL
-WPAb_Is_RSN (
+WPAb_Is_RSN(
PWLAN_IE_RSN_EXT pRSN
)
{
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
index b407ae536bf5..7fd300f2e7c3 100644
--- a/drivers/staging/vt6656/wpactl.c
+++ b/drivers/staging/vt6656/wpactl.c
@@ -515,7 +515,6 @@ static int wpa_set_scan(PSDevice pDevice,
{
int ret = 0;
-//2007-0919-01<Add>by MikeLiu
/**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PWLAN_IE_SSID pItemSSID;
@@ -695,7 +694,7 @@ static int wpa_get_scan(PSDevice pDevice,
scan_buf->ssid_len = pItemSSID->len;
scan_buf->freq = frequency_list[pBSS->uChannel-1];
scan_buf->caps = pBSS->wCapInfo; //DavidWang for sharemode
-//20080717-05,<Add> by James Li
+
RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
if(-ldBm<50){
scan_buf->qual = 100;
@@ -710,7 +709,7 @@ static int wpa_get_scan(PSDevice pDevice,
//scan_buf->qual =
scan_buf->noise = 0;
scan_buf->level = ldBm;
- //20080717-05,<Add> by James Li--End
+
//scan_buf->maxrate =
if (pBSS->wWPALen != 0) {
scan_buf->wpa_ie_len = pBSS->wWPALen;
@@ -873,7 +872,6 @@ static int wpa_set_associate(PSDevice pDevice,
pMgmt->eCurrState = WMAC_STATE_IDLE;
netif_stop_queue(pDevice->dev);
-//20080701-02,<Add> by Mike Liu
/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
{
PKnownBSS pCurr = NULL;
diff --git a/drivers/staging/westbridge/Kconfig b/drivers/staging/westbridge/Kconfig
new file mode 100644
index 000000000000..2b1c2ae557b6
--- /dev/null
+++ b/drivers/staging/westbridge/Kconfig
@@ -0,0 +1,53 @@
+#
+# West Bridge configuration
+#
+
+menuconfig WESTBRIDGE
+ tristate "West Bridge support"
+ depends on WESTBRIDGE_HAL_SELECTED
+ help
+ This selects West Bridge Peripheral controller support.
+
+ If you want West Bridge support, you should say Y here.
+
+menuconfig WESTBRIDGE_ASTORIA
+ bool "West Bridge Astoria support"
+ depends on WESTBRIDGE != n && WESTBRIDGE_HAL_SELECTED
+ help
+ This option enables support for West Bridge Astoria
+
+if WESTBRIDGE_ASTORIA
+source "drivers/staging/westbridge/astoria/Kconfig"
+endif #WESTBRIDGE_ASTORIA
+
+config WESTBRIDGE_HAL_SELECTED
+ boolean
+
+choice
+ prompt "West Bridge HAL"
+ help
+ West Bridge HAL/processor interface to be used
+
+#
+# HAL Layers
+#
+
+config MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ bool "WESTBRIDGE OMAP3430 Astoria PNAND HAL"
+ depends on ARCH_OMAP3
+ select WESTBRIDGE_HAL_SELECTED
+ help
+ Include the OMAP3430 HAL for PNAND interface
+
+config MACH_NO_WESTBRIDGE
+ bool "no West Bridge HAL selected"
+ help
+ Do not include any HAL layer(de-activates West Bridge option)
+endchoice
+
+config WESTBRIDGE_DEBUG
+ bool "West Bridge debugging"
+ depends on WESTBRIDGE != n
+ help
+ This is an option for use by developers; most people should
+ say N here. This enables WESTBRIDGE core and driver debugging.
diff --git a/drivers/staging/westbridge/TODO b/drivers/staging/westbridge/TODO
new file mode 100644
index 000000000000..6ca80581bbe2
--- /dev/null
+++ b/drivers/staging/westbridge/TODO
@@ -0,0 +1,7 @@
+TODO:
+- checkpatch.pl fixes
+- determine where to put the hal and common api code
+- modify the driver directory structure in an intuitive way
+
+Please send any patches to Greg Kroah-Hartman <gregkh@suse.de>
+and David Cross <david.cross@cypress.com>.
diff --git a/drivers/staging/westbridge/astoria/Kconfig b/drivers/staging/westbridge/astoria/Kconfig
new file mode 100644
index 000000000000..1ce388acbfeb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/Kconfig
@@ -0,0 +1,9 @@
+#
+# West Bridge configuration
+#
+source "drivers/staging/westbridge/astoria/device/Kconfig"
+
+source "drivers/staging/westbridge/astoria/block/Kconfig"
+
+source "drivers/staging/westbridge/astoria/gadget/Kconfig"
+
diff --git a/drivers/staging/westbridge/astoria/Makefile b/drivers/staging/westbridge/astoria/Makefile
new file mode 100644
index 000000000000..907bdb25804b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the kernel westbridge device drivers.
+#
+
+ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
+ EXTRA_CFLAGS += -WESTBRIDGE_NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE) += device/
+obj-$(CONFIG_WESTBRIDGE) += block/
+obj-$(CONFIG_WESTBRIDGE) += gadget/ \ No newline at end of file
diff --git a/drivers/staging/westbridge/astoria/api/Makefile b/drivers/staging/westbridge/astoria/api/Makefile
new file mode 100644
index 000000000000..1c94bc7bb310
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the kernel westbridge core.
+#
+
+ifeq ($(CONFIG_WESTBRIDGE_DEBUG),n)
+ EXTRA_CFLAGS += -NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasapi.o
+cyasapi-y := src/cyasdma.o src/cyasintr.o src/cyaslep2pep.o \
+ src/cyaslowlevel.o src/cyasmisc.o src/cyasmtp.o \
+ src/cyasstorage.o src/cyasusb.o
+
+
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasdma.c b/drivers/staging/westbridge/astoria/api/src/cyasdma.c
new file mode 100644
index 000000000000..152591d93ec2
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasdma.c
@@ -0,0 +1,1107 @@
+/* Cypress West Bridge API source file (cyasdma.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+
+/*
+ * Add the DMA queue entry to the free list to be re-used later
+ */
+static void
+cy_as_dma_add_request_to_free_queue(cy_as_device *dev_p,
+ cy_as_dma_queue_entry *req_p)
+{
+ uint32_t imask ;
+ imask = cy_as_hal_disable_interrupts() ;
+
+ req_p->next_p = dev_p->dma_freelist_p ;
+ dev_p->dma_freelist_p = req_p ;
+
+ cy_as_hal_enable_interrupts(imask) ;
+}
+
+/*
+ * Get a DMA queue entry from the free list.
+ */
+static cy_as_dma_queue_entry *
+cy_as_dma_get_dma_queue_entry(cy_as_device *dev_p)
+{
+ cy_as_dma_queue_entry *req_p ;
+ uint32_t imask ;
+
+ cy_as_hal_assert(dev_p->dma_freelist_p != 0) ;
+
+ imask = cy_as_hal_disable_interrupts() ;
+ req_p = dev_p->dma_freelist_p ;
+ dev_p->dma_freelist_p = req_p->next_p ;
+ cy_as_hal_enable_interrupts(imask) ;
+
+ return req_p ;
+}
+
+/*
+ * Set the maximum size that the West Bridge hardware
+ * can handle in a single DMA operation. This size
+ * may change for the P <-> U endpoints as a function
+ * of the endpoint type and whether we are running
+ * at full speed or high speed.
+ */
+cy_as_return_status_t
+cy_as_dma_set_max_dma_size(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, uint32_t size)
+{
+ /* In MTP mode, EP2 is allowed to have all max sizes. */
+ if ((!dev_p->is_mtp_firmware) || (ep != 0x02)) {
+ if (size < 64 || size > 1024)
+ return CY_AS_ERROR_INVALID_SIZE ;
+ }
+
+ CY_AS_NUM_EP(dev_p, ep)->maxhwdata = (uint16_t)size ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+ * The callback for requests sent to West Bridge
+ * to relay endpoint data. Endpoint data for EP0
+ * and EP1 are sent using mailbox requests. This
+ * is the callback that is called when a response
+ * to a mailbox request to send data is received.
+ */
+static void
+cy_as_dma_request_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *resp_p,
+ cy_as_return_status_t ret)
+{
+ uint16_t v ;
+ uint16_t datacnt ;
+ cy_as_end_point_number_t ep ;
+
+ (void)context ;
+
+ cy_as_log_debug_message(5, "cy_as_dma_request_callback called") ;
+
+ /*
+ * extract the return code from the firmware
+ */
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp_p) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(resp_p, 0) ;
+ }
+
+ /*
+ * extract the endpoint number and the transferred byte count
+ * from the request.
+ */
+ v = cy_as_ll_request_response__get_word(req_p, 0) ;
+ ep = (cy_as_end_point_number_t)((v >> 13) & 0x01) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ /*
+ * if the firmware returns success,
+ * all of the data requested was
+ * transferred. there are no partial
+ * transfers.
+ */
+ datacnt = v & 0x3FF ;
+ } else {
+ /*
+ * if the firmware returned an error, no data was transferred.
+ */
+ datacnt = 0 ;
+ }
+
+ /*
+ * queue the request and response data structures for use with the
+ * next EP0 or EP1 request.
+ */
+ if (ep == 0) {
+ dev_p->usb_ep0_dma_req = req_p ;
+ dev_p->usb_ep0_dma_resp = resp_p ;
+ } else {
+ dev_p->usb_ep1_dma_req = req_p ;
+ dev_p->usb_ep1_dma_resp = resp_p ;
+ }
+
+ /*
+ * call the DMA complete function so we can
+ * signal that this portion of the transfer
+ * has completed. if the low level request
+ * was canceled, we do not need to signal
+ * the completed function as the only way a
+ * cancel can happen is via the DMA cancel
+ * function.
+ */
+ if (ret != CY_AS_ERROR_CANCELED)
+ cy_as_dma_completed_callback(dev_p->tag, ep, datacnt, ret) ;
+}
+
+/*
+ * Set the DRQ mask register for the given endpoint number. If state is
+ * CyTrue, the DRQ interrupt for the given endpoint is enabled, otherwise
+ * it is disabled.
+ */
+static void
+cy_as_dma_set_drq(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, cy_bool state)
+{
+ uint16_t mask ;
+ uint16_t v ;
+ uint32_t intval ;
+
+ /*
+ * there are not DRQ register bits for EP0 and EP1
+ */
+ if (ep == 0 || ep == 1)
+ return ;
+
+ /*
+ * disable interrupts while we do this to be sure the state of the
+ * DRQ mask register is always well defined.
+ */
+ intval = cy_as_hal_disable_interrupts() ;
+
+ /*
+ * set the DRQ bit to the given state for the ep given
+ */
+ mask = (1 << ep) ;
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK) ;
+
+ if (state)
+ v |= mask ;
+ else
+ v &= ~mask ;
+
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK, v) ;
+ cy_as_hal_enable_interrupts(intval) ;
+}
+
+/*
+* Send the next DMA request for the endpoint given
+*/
+static void
+cy_as_dma_send_next_dma_request(cy_as_device *dev_p, cy_as_dma_end_point *ep_p)
+{
+ uint32_t datacnt ;
+ void *buf_p ;
+ cy_as_dma_queue_entry *dma_p ;
+
+ cy_as_log_debug_message(6, "cy_as_dma_send_next_dma_request called") ;
+
+ /* If the queue is empty, nothing to do */
+ dma_p = ep_p->queue_p ;
+ if (dma_p == 0) {
+ /*
+ * there are no pending DMA requests
+ * for this endpoint. disable the DRQ
+ * mask bits to insure no interrupts
+ * will be triggered by this endpoint
+ * until someone is interested in the data.
+ */
+ cy_as_dma_set_drq(dev_p, ep_p->ep, cy_false) ;
+ return ;
+ }
+
+ cy_as_dma_end_point_set_running(ep_p) ;
+
+ /*
+ * get the number of words that still
+ * need to be xferred in this request.
+ */
+ datacnt = dma_p->size - dma_p->offset ;
+ cy_as_hal_assert(datacnt >= 0) ;
+
+ /*
+ * the HAL layer should never limit the size
+ * of the transfer to something less than the
+ * maxhwdata otherwise, the data will be sent
+ * in packets that are not correct in size.
+ */
+ cy_as_hal_assert(ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE
+ || ep_p->maxhaldata >= ep_p->maxhwdata) ;
+
+ /*
+ * update the number of words that need to be xferred yet
+ * based on the limits of the HAL layer.
+ */
+ if (ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE) {
+ if (datacnt > ep_p->maxhwdata)
+ datacnt = ep_p->maxhwdata ;
+ } else {
+ if (datacnt > ep_p->maxhaldata)
+ datacnt = ep_p->maxhaldata ;
+ }
+
+ /*
+ * find a pointer to the data that needs to be transferred
+ */
+ buf_p = (((char *)dma_p->buf_p) + dma_p->offset);
+
+ /*
+ * mark a request in transit
+ */
+ cy_as_dma_end_point_set_in_transit(ep_p) ;
+
+ if (ep_p->ep == 0 || ep_p->ep == 1) {
+ /*
+ * if this is a WRITE request on EP0 and EP1
+ * we write the data via an EP_DATA request
+ * to west bridge via the mailbox registers.
+ * if this is a READ request, we do nothing
+ * and the data will arrive via an EP_DATA
+ * request from west bridge. in the request
+ * handler for the USB context we will pass
+ * the data back into the DMA module.
+ */
+ if (dma_p->readreq == cy_false) {
+ uint16_t v ;
+ uint16_t len ;
+ cy_as_ll_request_response *resp_p ;
+ cy_as_ll_request_response *req_p ;
+ cy_as_return_status_t ret ;
+
+ len = (uint16_t)(datacnt / 2) ;
+ if (datacnt % 2)
+ len++ ;
+
+ len++ ;
+
+ if (ep_p->ep == 0) {
+ req_p = dev_p->usb_ep0_dma_req ;
+ resp_p = dev_p->usb_ep0_dma_resp ;
+ dev_p->usb_ep0_dma_req = 0 ;
+ dev_p->usb_ep0_dma_resp = 0 ;
+ } else {
+ req_p = dev_p->usb_ep1_dma_req ;
+ resp_p = dev_p->usb_ep1_dma_resp ;
+ dev_p->usb_ep1_dma_req = 0 ;
+ dev_p->usb_ep1_dma_resp = 0 ;
+ }
+
+ cy_as_hal_assert(req_p != 0) ;
+ cy_as_hal_assert(resp_p != 0) ;
+ cy_as_hal_assert(len <= 64) ;
+
+ cy_as_ll_init_request(req_p, CY_RQT_USB_EP_DATA,
+ CY_RQT_USB_RQT_CONTEXT, len) ;
+
+ v = (uint16_t)(datacnt | (ep_p->ep << 13) | (1 << 14)) ;
+ if (dma_p->offset == 0)
+ v |= (1 << 12) ;/* Set the first packet bit */
+ if (dma_p->offset + datacnt == dma_p->size)
+ v |= (1 << 11) ;/* Set the last packet bit */
+
+ cy_as_ll_request_response__set_word(req_p, 0, v) ;
+ cy_as_ll_request_response__pack(req_p,
+ 1, datacnt, buf_p) ;
+
+ cy_as_ll_init_response(resp_p, 1) ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p, resp_p,
+ cy_false, cy_as_dma_request_callback) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ cy_as_log_debug_message(5,
+ "+++ send EP 0/1 data via mailbox registers") ;
+ else
+ cy_as_log_debug_message(5,
+ "+++ error sending EP 0/1 data via mailbox "
+ "registers - CY_AS_ERROR_TIMEOUT") ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_dma_completed_callback(dev_p->tag,
+ ep_p->ep, 0, ret) ;
+ }
+ } else {
+ /*
+ * this is a DMA request on an endpoint that is accessible
+ * via the P port. ask the HAL DMA capabilities to
+ * perform this. the amount of data sent is limited by the
+ * HAL max size as well as what we need to send. if the
+ * ep_p->maxhaldata is set to a value larger than the
+ * endpoint buffer size, then we will pass more than a
+ * single buffer worth of data to the HAL layer and expect
+ * the HAL layer to divide the data into packets. the last
+ * parameter here (ep_p->maxhwdata) gives the packet size for
+ * the data so the HAL layer knows what the packet size should
+ * be.
+ */
+ if (cy_as_dma_end_point_is_direction_in(ep_p))
+ cy_as_hal_dma_setup_write(dev_p->tag,
+ ep_p->ep, buf_p, datacnt, ep_p->maxhwdata) ;
+ else
+ cy_as_hal_dma_setup_read(dev_p->tag,
+ ep_p->ep, buf_p, datacnt, ep_p->maxhwdata) ;
+
+ /*
+ * the DRQ interrupt for this endpoint should be enabled
+ * so that the data transfer progresses at interrupt time.
+ */
+ cy_as_dma_set_drq(dev_p, ep_p->ep, cy_true) ;
+ }
+}
+
+/*
+ * This function is called when the HAL layer has
+ * completed the last requested DMA operation.
+ * This function sends/receives the next batch of
+ * data associated with the current DMA request,
+ * or it is is complete, moves to the next DMA request.
+ */
+void
+cy_as_dma_completed_callback(cy_as_hal_device_tag tag,
+ cy_as_end_point_number_t ep, uint32_t cnt, cy_as_return_status_t status)
+{
+ uint32_t mask ;
+ cy_as_dma_queue_entry *req_p ;
+ cy_as_dma_end_point *ep_p ;
+ cy_as_device *dev_p = cy_as_device_find_from_tag(tag) ;
+
+ /* Make sure the HAL layer gave us good parameters */
+ cy_as_hal_assert(dev_p != 0) ;
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+ cy_as_hal_assert(ep < 16) ;
+
+
+ /* Get the endpoint ptr */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+ cy_as_hal_assert(ep_p->queue_p != 0) ;
+
+ /* Get a pointer to the current entry in the queue */
+ mask = cy_as_hal_disable_interrupts() ;
+ req_p = ep_p->queue_p ;
+
+ /* Update the offset to reflect the data actually received or sent */
+ req_p->offset += cnt ;
+
+ /*
+ * if we are still sending/receiving the current packet,
+ * send/receive the next chunk basically we keep going
+ * if we have not sent/received enough data, and we are
+ * not doing a packet operation, and the last packet
+ * sent or received was a full sized packet. in other
+ * words, when we are NOT doing a packet operation, a
+ * less than full size packet (a short packet) will
+ * terminate the operation.
+ *
+ * note: if this is EP1 request and the request has
+ * timed out, it means the buffer is not free.
+ * we have to resend the data.
+ *
+ * note: for the MTP data transfers, the DMA transfer
+ * for the next packet can only be started asynchronously,
+ * after a firmware event notifies that the device is ready.
+ */
+ if (((req_p->offset != req_p->size) && (req_p->packet == cy_false) &&
+ ((cnt == ep_p->maxhaldata) || ((cnt == ep_p->maxhwdata) &&
+ ((ep != CY_AS_MTP_READ_ENDPOINT) ||
+ (cnt == dev_p->usb_max_tx_size)))))
+ || ((ep == 1) && (status == CY_AS_ERROR_TIMEOUT))) {
+ cy_as_hal_enable_interrupts(mask) ;
+
+ /*
+ * and send the request again to send the next block of
+ * data. special handling for MTP transfers on E_ps 2
+ * and 6. the send_next_request will be processed based
+ * on the event sent by the firmware.
+ */
+ if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || (
+ (ep == CY_AS_MTP_READ_ENDPOINT) &&
+ (!cy_as_dma_end_point_is_direction_in(ep_p))))
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+ else
+ cy_as_dma_send_next_dma_request(dev_p, ep_p) ;
+ } else {
+ /*
+ * we get here if ...
+ * we have sent or received all of the data
+ * or
+ * we are doing a packet operation
+ * or
+ * we receive a short packet
+ */
+
+ /*
+ * remove this entry from the DMA queue for this endpoint.
+ */
+ cy_as_dma_end_point_clear_in_transit(ep_p) ;
+ ep_p->queue_p = req_p->next_p ;
+ if (ep_p->last_p == req_p) {
+ /*
+ * we have removed the last packet from the DMA queue,
+ * disable the interrupt associated with this interrupt.
+ */
+ ep_p->last_p = 0 ;
+ cy_as_hal_enable_interrupts(mask) ;
+ cy_as_dma_set_drq(dev_p, ep, cy_false) ;
+ } else
+ cy_as_hal_enable_interrupts(mask) ;
+
+ if (req_p->cb) {
+ /*
+ * if the request has a callback associated with it,
+ * call the callback to tell the interested party that
+ * this DMA request has completed.
+ *
+ * note, we set the in_callback bit to insure that we
+ * cannot recursively call an API function that is
+ * synchronous only from a callback.
+ */
+ cy_as_device_set_in_callback(dev_p) ;
+ (*req_p->cb)(dev_p, ep, req_p->buf_p,
+ req_p->offset, status) ;
+ cy_as_device_clear_in_callback(dev_p) ;
+ }
+
+ /*
+ * we are done with this request, put it on the freelist to be
+ * reused at a later time.
+ */
+ cy_as_dma_add_request_to_free_queue(dev_p, req_p) ;
+
+ if (ep_p->queue_p == 0) {
+ /*
+ * if the endpoint is out of DMA entries, set the
+ * endpoint as stopped.
+ */
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+
+ /*
+ * the DMA queue is empty, wake any task waiting on
+ * the QUEUE to drain.
+ */
+ if (cy_as_dma_end_point_is_sleeping(ep_p)) {
+ cy_as_dma_end_point_set_wake_state(ep_p) ;
+ cy_as_hal_wake(&ep_p->channel) ;
+ }
+ } else {
+ /*
+ * if the queued operation is a MTP transfer,
+ * wait until firmware event before sending
+ * down the next DMA request.
+ */
+ if ((ep == CY_AS_MTP_WRITE_ENDPOINT) ||
+ ((ep == CY_AS_MTP_READ_ENDPOINT) &&
+ (!cy_as_dma_end_point_is_direction_in(ep_p))) ||
+ ((ep == dev_p->storage_read_endpoint) &&
+ (!cy_as_device_is_p2s_dma_start_recvd(dev_p)))
+ || ((ep == dev_p->storage_write_endpoint) &&
+ (!cy_as_device_is_p2s_dma_start_recvd(dev_p))))
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+ else
+ cy_as_dma_send_next_dma_request(dev_p, ep_p) ;
+ }
+ }
+}
+
+/*
+* This function is used to kick start DMA on a given
+* channel. If DMA is already running on the given
+* endpoint, nothing happens. If DMA is not running,
+* the first entry is pulled from the DMA queue and
+* sent/recevied to/from the West Bridge device.
+*/
+cy_as_return_status_t
+cy_as_dma_kick_start(cy_as_device *dev_p, cy_as_end_point_number_t ep)
+{
+ cy_as_dma_end_point *ep_p ;
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ /* We are already running */
+ if (cy_as_dma_end_point_is_running(ep_p))
+ return CY_AS_ERROR_SUCCESS ;
+
+ cy_as_dma_send_next_dma_request(dev_p, ep_p);
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+ * This function stops the given endpoint. Stopping and endpoint cancels
+ * any pending DMA operations and frees all resources associated with the
+ * given endpoint.
+ */
+static cy_as_return_status_t
+cy_as_dma_stop_end_point(cy_as_device *dev_p, cy_as_end_point_number_t ep)
+{
+ cy_as_return_status_t ret ;
+ cy_as_dma_end_point *ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ /*
+ * cancel any pending DMA requests associated with this endpoint. this
+ * cancels any DMA requests at the HAL layer as well as dequeues any
+ * request that is currently pending.
+ */
+ ret = cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * destroy the sleep channel
+ */
+ if (!cy_as_hal_destroy_sleep_channel(&ep_p->channel)
+ && ret == CY_AS_ERROR_SUCCESS)
+ ret = CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED ;
+
+ /*
+ * free the memory associated with this endpoint
+ */
+ cy_as_hal_free(ep_p) ;
+
+ /*
+ * set the data structure ptr to something sane since the
+ * previous pointer is now free.
+ */
+ dev_p->endp[ep] = 0 ;
+
+ return ret ;
+}
+
+/*
+ * This method stops the USB stack. This is an internal function that does
+ * all of the work of destroying the USB stack without the protections that
+ * we provide to the API (i.e. stopping at stack that is not running).
+ */
+static cy_as_return_status_t
+cy_as_dma_stop_internal(cy_as_device *dev_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_return_status_t lret ;
+ cy_as_end_point_number_t i ;
+
+ /*
+ * stop all of the endpoints. this cancels all DMA requests, and
+ * frees all resources associated with each endpoint.
+ */
+ for (i = 0 ; i < sizeof(dev_p->endp)/(sizeof(dev_p->endp[0])) ; i++) {
+ lret = cy_as_dma_stop_end_point(dev_p, i) ;
+ if (lret != CY_AS_ERROR_SUCCESS && ret == CY_AS_ERROR_SUCCESS)
+ ret = lret ;
+ }
+
+ /*
+ * now, free the list of DMA requests structures that we use to manage
+ * DMA requests.
+ */
+ while (dev_p->dma_freelist_p) {
+ cy_as_dma_queue_entry *req_p ;
+ uint32_t imask = cy_as_hal_disable_interrupts() ;
+
+ req_p = dev_p->dma_freelist_p ;
+ dev_p->dma_freelist_p = req_p->next_p ;
+
+ cy_as_hal_enable_interrupts(imask) ;
+
+ cy_as_hal_free(req_p) ;
+ }
+
+ cy_as_ll_destroy_request(dev_p, dev_p->usb_ep0_dma_req) ;
+ cy_as_ll_destroy_request(dev_p, dev_p->usb_ep1_dma_req) ;
+ cy_as_ll_destroy_response(dev_p, dev_p->usb_ep0_dma_resp) ;
+ cy_as_ll_destroy_response(dev_p, dev_p->usb_ep1_dma_resp) ;
+
+ return ret ;
+}
+
+
+/*
+ * CyAsDmaStop()
+ *
+ * This function shuts down the DMA module. All resources
+ * associated with the DMA module will be freed. This
+ * routine is the API stop function. It insures that we
+ * are stopping a stack that is actually running and then
+ * calls the internal function to do the work.
+ */
+cy_as_return_status_t
+cy_as_dma_stop(cy_as_device *dev_p)
+{
+ cy_as_return_status_t ret ;
+
+ ret = cy_as_dma_stop_internal(dev_p) ;
+ cy_as_device_set_dma_stopped(dev_p) ;
+
+ return ret ;
+}
+
+/*
+ * CyAsDmaStart()
+ *
+ * This function intializes the DMA module to insure it is up and running.
+ */
+cy_as_return_status_t
+cy_as_dma_start(cy_as_device *dev_p)
+{
+ cy_as_end_point_number_t i ;
+ uint16_t cnt ;
+
+ if (cy_as_device_is_dma_running(dev_p))
+ return CY_AS_ERROR_ALREADY_RUNNING ;
+
+ /*
+ * pre-allocate DMA queue structures to be used in the interrupt context
+ */
+ for (cnt = 0 ; cnt < 32 ; cnt++) {
+ cy_as_dma_queue_entry *entry_p = (cy_as_dma_queue_entry *)
+ cy_as_hal_alloc(sizeof(cy_as_dma_queue_entry)) ;
+ if (entry_p == 0) {
+ cy_as_dma_stop_internal(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ cy_as_dma_add_request_to_free_queue(dev_p, entry_p) ;
+ }
+
+ /*
+ * pre-allocate the DMA requests for sending EP0
+ * and EP1 data to west bridge
+ */
+ dev_p->usb_ep0_dma_req = cy_as_ll_create_request(dev_p,
+ CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64) ;
+ dev_p->usb_ep1_dma_req = cy_as_ll_create_request(dev_p,
+ CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64) ;
+
+ if (dev_p->usb_ep0_dma_req == 0 || dev_p->usb_ep1_dma_req == 0) {
+ cy_as_dma_stop_internal(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ dev_p->usb_ep0_dma_req_save = dev_p->usb_ep0_dma_req ;
+
+ dev_p->usb_ep0_dma_resp = cy_as_ll_create_response(dev_p, 1) ;
+ dev_p->usb_ep1_dma_resp = cy_as_ll_create_response(dev_p, 1) ;
+ if (dev_p->usb_ep0_dma_resp == 0 || dev_p->usb_ep1_dma_resp == 0) {
+ cy_as_dma_stop_internal(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ dev_p->usb_ep0_dma_resp_save = dev_p->usb_ep0_dma_resp ;
+
+ /*
+ * set the dev_p->endp to all zeros to insure cleanup is possible if
+ * an error occurs during initialization.
+ */
+ cy_as_hal_mem_set(dev_p->endp, 0, sizeof(dev_p->endp)) ;
+
+ /*
+ * now, iterate through each of the endpoints and initialize each
+ * one.
+ */
+ for (i = 0 ; i < sizeof(dev_p->endp)/sizeof(dev_p->endp[0]) ; i++) {
+ dev_p->endp[i] = (cy_as_dma_end_point *)
+ cy_as_hal_alloc(sizeof(cy_as_dma_end_point)) ;
+ if (dev_p->endp[i] == 0) {
+ cy_as_dma_stop_internal(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ cy_as_hal_mem_set(dev_p->endp[i], 0,
+ sizeof(cy_as_dma_end_point)) ;
+
+ dev_p->endp[i]->ep = i ;
+ dev_p->endp[i]->queue_p = 0 ;
+ dev_p->endp[i]->last_p = 0 ;
+
+ cy_as_dma_set_drq(dev_p, i, cy_false) ;
+
+ if (!cy_as_hal_create_sleep_channel(&dev_p->endp[i]->channel))
+ return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED ;
+ }
+
+ /*
+ * tell the HAL layer who to call when the
+ * HAL layer completes a DMA request
+ */
+ cy_as_hal_dma_register_callback(dev_p->tag,
+ cy_as_dma_completed_callback) ;
+
+ /*
+ * mark DMA as up and running on this device
+ */
+ cy_as_device_set_dma_running(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* Wait for all entries in the DMA queue associated
+* the given endpoint to be drained. This function
+* will not return until all the DMA data has been
+* transferred.
+*/
+cy_as_return_status_t
+cy_as_dma_drain_queue(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, cy_bool kickstart)
+{
+ cy_as_dma_end_point *ep_p ;
+ int loopcount = 1000 ;
+ uint32_t mask ;
+
+ /*
+ * make sure the endpoint is valid
+ */
+ if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ /*
+ * if the endpoint is empty of traffic, we return
+ * with success immediately
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+ if (ep_p->queue_p == 0) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_SUCCESS ;
+ } else {
+ /*
+ * add 10 seconds to the time out value for each 64 KB segment
+ * of data to be transferred.
+ */
+ if (ep_p->queue_p->size > 0x10000)
+ loopcount += ((ep_p->queue_p->size / 0x10000) * 1000) ;
+ }
+ cy_as_hal_enable_interrupts(mask) ;
+
+ /* If we are already sleeping on this endpoint, it is an error */
+ if (cy_as_dma_end_point_is_sleeping(ep_p))
+ return CY_AS_ERROR_NESTED_SLEEP ;
+
+ /*
+ * we disable the endpoint while the queue drains to
+ * prevent any additional requests from being queued while we are waiting
+ */
+ cy_as_dma_enable_end_point(dev_p, ep,
+ cy_false, cy_as_direction_dont_change) ;
+
+ if (kickstart) {
+ /*
+ * now, kick start the DMA if necessary
+ */
+ cy_as_dma_kick_start(dev_p, ep) ;
+ }
+
+ /*
+ * check one last time before we begin sleeping to see if the
+ * queue is drained.
+ */
+ if (ep_p->queue_p == 0) {
+ cy_as_dma_enable_end_point(dev_p, ep, cy_true,
+ cy_as_direction_dont_change) ;
+ return CY_AS_ERROR_SUCCESS ;
+ }
+
+ while (loopcount-- > 0) {
+ /*
+ * sleep for 10 ms maximum (per loop) while
+ * waiting for the transfer to complete.
+ */
+ cy_as_dma_end_point_set_sleep_state(ep_p) ;
+ cy_as_hal_sleep_on(&ep_p->channel, 10) ;
+
+ /* If we timed out, the sleep bit will still be set */
+ cy_as_dma_end_point_set_wake_state(ep_p) ;
+
+ /* Check the queue to see if is drained */
+ if (ep_p->queue_p == 0) {
+ /*
+ * clear the endpoint running and in transit flags
+ * for the endpoint, now that its DMA queue is empty.
+ */
+ cy_as_dma_end_point_clear_in_transit(ep_p) ;
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+
+ cy_as_dma_enable_end_point(dev_p, ep,
+ cy_true, cy_as_direction_dont_change) ;
+ return CY_AS_ERROR_SUCCESS ;
+ }
+ }
+
+ /*
+ * the DMA operation that has timed out can be cancelled, so that later
+ * operations on this queue can proceed.
+ */
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_TIMEOUT) ;
+ cy_as_dma_enable_end_point(dev_p, ep,
+ cy_true, cy_as_direction_dont_change) ;
+ return CY_AS_ERROR_TIMEOUT ;
+}
+
+/*
+* This function queues a write request in the DMA queue
+* for a given endpoint. The direction of the
+* entry will be inferred from the endpoint direction.
+*/
+cy_as_return_status_t
+cy_as_dma_queue_request(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *mem_p,
+ uint32_t size, cy_bool pkt, cy_bool readreq, cy_as_dma_callback cb)
+{
+ uint32_t mask ;
+ cy_as_dma_queue_entry *entry_p ;
+ cy_as_dma_end_point *ep_p ;
+
+ /*
+ * make sure the endpoint is valid
+ */
+ if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ if (!cy_as_dma_end_point_is_enabled(ep_p))
+ return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+ entry_p = cy_as_dma_get_dma_queue_entry(dev_p) ;
+
+ entry_p->buf_p = mem_p ;
+ entry_p->cb = cb ;
+ entry_p->size = size ;
+ entry_p->offset = 0 ;
+ entry_p->packet = pkt ;
+ entry_p->readreq = readreq ;
+
+ mask = cy_as_hal_disable_interrupts() ;
+ entry_p->next_p = 0 ;
+ if (ep_p->last_p)
+ ep_p->last_p->next_p = entry_p ;
+ ep_p->last_p = entry_p ;
+ if (ep_p->queue_p == 0)
+ ep_p->queue_p = entry_p ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* This function enables or disables and endpoint for DMA
+* queueing. If an endpoint is disabled, any queue requests
+* continue to be processed, but no new requests can be queued.
+*/
+cy_as_return_status_t
+cy_as_dma_enable_end_point(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, cy_bool enable, cy_as_dma_direction dir)
+{
+ cy_as_dma_end_point *ep_p ;
+
+ /*
+ * make sure the endpoint is valid
+ */
+ if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ if (dir == cy_as_direction_out)
+ cy_as_dma_end_point_set_direction_out(ep_p) ;
+ else if (dir == cy_as_direction_in)
+ cy_as_dma_end_point_set_direction_in(ep_p) ;
+
+ /*
+ * get the maximum size of data buffer the HAL
+ * layer can accept. this is used when the DMA
+ * module is sending DMA requests to the HAL.
+ * the DMA module will never send down a request
+ * that is greater than this value.
+ *
+ * for EP0 and EP1, we can send no more than 64
+ * bytes of data at one time as this is the maximum
+ * size of a packet that can be sent via these
+ * endpoints.
+ */
+ if (ep == 0 || ep == 1)
+ ep_p->maxhaldata = 64 ;
+ else
+ ep_p->maxhaldata = cy_as_hal_dma_max_request_size(
+ dev_p->tag, ep) ;
+
+ if (enable)
+ cy_as_dma_end_point_enable(ep_p) ;
+ else
+ cy_as_dma_end_point_disable(ep_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+ * This function cancels any DMA operations pending with the HAL layer as well
+ * as any DMA operation queued on the endpoint.
+ */
+cy_as_return_status_t
+cy_as_dma_cancel(
+ cy_as_device *dev_p,
+ cy_as_end_point_number_t ep,
+ cy_as_return_status_t err)
+{
+ uint32_t mask ;
+ cy_as_dma_end_point *ep_p ;
+ cy_as_dma_queue_entry *entry_p ;
+ cy_bool epstate ;
+
+ /*
+ * make sure the endpoint is valid
+ */
+ if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ if (ep_p) {
+ /* Remember the state of the endpoint */
+ epstate = cy_as_dma_end_point_is_enabled(ep_p) ;
+
+ /*
+ * disable the endpoint so no more DMA packets can be
+ * queued.
+ */
+ cy_as_dma_enable_end_point(dev_p, ep,
+ cy_false, cy_as_direction_dont_change) ;
+
+ /*
+ * don't allow any interrupts from this endpoint
+ * while we get the most current request off of
+ * the queue.
+ */
+ cy_as_dma_set_drq(dev_p, ep, cy_false) ;
+
+ /*
+ * cancel any pending request queued in the HAL layer
+ */
+ if (cy_as_dma_end_point_in_transit(ep_p))
+ cy_as_hal_dma_cancel_request(dev_p->tag, ep_p->ep) ;
+
+ /*
+ * shutdown the DMA for this endpoint so no
+ * more data is transferred
+ */
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+
+ /*
+ * mark the endpoint as not in transit, because we are
+ * going to consume any queued requests
+ */
+ cy_as_dma_end_point_clear_in_transit(ep_p) ;
+
+ /*
+ * now, remove each entry in the queue and call the
+ * associated callback stating that the request was
+ * canceled.
+ */
+ ep_p->last_p = 0 ;
+ while (ep_p->queue_p != 0) {
+ /* Disable interrupts to manipulate the queue */
+ mask = cy_as_hal_disable_interrupts() ;
+
+ /* Remove an entry from the queue */
+ entry_p = ep_p->queue_p ;
+ ep_p->queue_p = entry_p->next_p ;
+
+ /* Ok, the queue has been updated, we can
+ * turn interrupts back on */
+ cy_as_hal_enable_interrupts(mask) ;
+
+ /* Call the callback indicating we have
+ * canceled the DMA */
+ if (entry_p->cb)
+ entry_p->cb(dev_p, ep,
+ entry_p->buf_p, entry_p->size, err) ;
+
+ cy_as_dma_add_request_to_free_queue(dev_p, entry_p) ;
+ }
+
+ if (ep == 0 || ep == 1) {
+ /*
+ * if this endpoint is zero or one, we need to
+ * clear the queue of any pending CY_RQT_USB_EP_DATA
+ * requests as these are pending requests to send
+ * data to the west bridge device.
+ */
+ cy_as_ll_remove_ep_data_requests(dev_p, ep) ;
+ }
+
+ if (epstate) {
+ /*
+ * the endpoint started out enabled, so we
+ * re-enable the endpoint here.
+ */
+ cy_as_dma_enable_end_point(dev_p, ep,
+ cy_true, cy_as_direction_dont_change) ;
+ }
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_dma_received_data(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, uint32_t dsize, void *data)
+{
+ cy_as_dma_queue_entry *dma_p ;
+ uint8_t *src_p, *dest_p ;
+ cy_as_dma_end_point *ep_p ;
+ uint32_t xfersize ;
+
+ /*
+ * make sure the endpoint is valid
+ */
+ if (ep != 0 && ep != 1)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+ dma_p = ep_p->queue_p ;
+ if (dma_p == 0)
+ return CY_AS_ERROR_SUCCESS ;
+
+ /*
+ * if the data received exceeds the size of the DMA buffer,
+ * clip the data to the size of the buffer. this can lead
+ * to loosing some data, but is not different than doing
+ * non-packet reads on the other endpoints.
+ */
+ if (dsize > dma_p->size - dma_p->offset)
+ dsize = dma_p->size - dma_p->offset ;
+
+ /*
+ * copy the data from the request packet to the DMA buffer
+ * for the endpoint
+ */
+ src_p = (uint8_t *)data ;
+ dest_p = ((uint8_t *)(dma_p->buf_p)) + dma_p->offset ;
+ xfersize = dsize ;
+ while (xfersize-- > 0)
+ *dest_p++ = *src_p++ ;
+
+ /* Signal the DMA module that we have
+ * received data for this EP request */
+ cy_as_dma_completed_callback(dev_p->tag,
+ ep, dsize, CY_AS_ERROR_SUCCESS) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasintr.c b/drivers/staging/westbridge/astoria/api/src/cyasintr.c
new file mode 100644
index 000000000000..aea6c3ebf067
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasintr.c
@@ -0,0 +1,143 @@
+/* Cypress West Bridge API source file (cyasintr.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasdevice.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+
+extern void cy_as_mail_box_interrupt_handler(cy_as_device *) ;
+
+void
+cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
+{
+ /* Read and clear the interrupt. */
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT) ;
+ v = v ;
+}
+
+void
+cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
+{
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT) ;
+ v = v ;
+}
+
+void
+cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
+{
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT) ;
+ v = v ;
+}
+
+uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr)
+{
+ uint16_t v ;
+
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ if (cy_as_device_is_intr_running(dev_p) != 0)
+ return CY_AS_ERROR_ALREADY_RUNNING ;
+
+ v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT |
+ CY_AS_MEM_P0_INT_MASK_REG_MMBINT |
+ CY_AS_MEM_P0_INT_MASK_REG_MPMINT ;
+
+ if (dmaintr)
+ v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT ;
+
+ /* Enable the interrupts of interest */
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v) ;
+
+ /* Mark the interrupt module as initialized */
+ cy_as_device_set_intr_running(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+uint32_t cy_as_intr_stop(cy_as_device *dev_p)
+{
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ if (cy_as_device_is_intr_running(dev_p) == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0) ;
+ cy_as_device_set_intr_stopped(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
+{
+ uint16_t v ;
+ cy_as_device *dev_p ;
+
+ dev_p = cy_as_device_find_from_tag(tag) ;
+
+ /*
+ * only power management interrupts can occur before the
+ * antioch API setup is complete. if this is a PM interrupt
+ * handle it here; otherwise output a warning message.
+ */
+ if (dev_p == 0) {
+ v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG) ;
+ if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
+ /* Read the PWR_MAGT_STAT register
+ * to clear this interrupt. */
+ v = cy_as_hal_read_register(tag,
+ CY_AS_MEM_PWR_MAGT_STAT) ;
+ } else
+ cy_as_hal_print_message("stray antioch "
+ "interrupt detected"
+ ", tag not associated "
+ "with any created device.") ;
+ return ;
+ }
+
+ /* Make sure we got a valid object from CyAsDeviceFindFromTag */
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
+ cy_as_mcu_interrupt_handler(dev_p) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
+ cy_as_power_management_interrupt_handler(dev_p) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
+ cy_as_pll_lock_loss_interrupt_handler(dev_p) ;
+
+ /* If the interrupt module is not running, no mailbox
+ * interrupts are expected from the west bridge. */
+ if (cy_as_device_is_intr_running(dev_p) == 0)
+ return ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
+ cy_as_mail_box_interrupt_handler(dev_p) ;
+}
diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c b/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c
new file mode 100644
index 000000000000..b28e33a1ce9d
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c
@@ -0,0 +1,358 @@
+/* Cypress West Bridge API source file (cyaslep2pep.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasusb.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+
+typedef enum cy_as_physical_endpoint_state {
+ cy_as_e_p_free,
+ cy_as_e_p_in,
+ cy_as_e_p_out,
+ cy_as_e_p_iso_in,
+ cy_as_e_p_iso_out
+} cy_as_physical_endpoint_state;
+
+
+/*
+* This map is used to map an index between 1 and 10
+* to a logical endpoint number. This is used to map
+* LEP register indexes into actual EP numbers.
+*/
+static cy_as_end_point_number_t end_point_map[] = {
+ 3, 5, 7, 9, 10, 11, 12, 13, 14, 15 } ;
+
+#define CY_AS_EPCFG_1024 (1 << 3)
+#define CY_AS_EPCFG_DBL (0x02)
+#define CY_AS_EPCFG_TRIPLE (0x03)
+#define CY_AS_EPCFG_QUAD (0x00)
+
+/*
+ * NB: This table contains the register values for PEP1
+ * and PEP3. PEP2 and PEP4 only have a bit to change the
+ * direction of the PEP and therefre are not represented
+ * in this table.
+ */
+static uint8_t pep_register_values[12][4] = {
+ /* Bit 1:0 buffering, 0 = quad, 2 = double, 3 = triple */
+ /* Bit 3 size, 0 = 512, 1 = 1024 */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL,
+ },/* Config 1 - PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_QUAD,
+ }, /* Config 2 - PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL | CY_AS_EPCFG_1024,
+ },/* Config 3 - PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (2 * 1024), PEP4(N/A) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_DBL,
+ },/* Config 4 - PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_QUAD,
+ },/* Config 5 - PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_QUAD,
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ },/* Config 6 - PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (2 * 1024), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_DBL,
+ },/* Config 7 - PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (2 * 512), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_QUAD,
+ },/* Config 8 - PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (4 * 512), PEP4 (N/A) */
+ {
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
+ },/* Config 9 - PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (2 * 1024), PEP4 (N/A)*/
+ {
+ CY_AS_EPCFG_TRIPLE,
+ CY_AS_EPCFG_TRIPLE,
+ },/* Config 10 - PEP1 (3 * 512), PEP2 (N/A),
+ * PEP3 (3 * 512), PEP4 (2 * 512)*/
+ {
+ CY_AS_EPCFG_TRIPLE | CY_AS_EPCFG_1024,
+ CY_AS_EPCFG_DBL,
+ },/* Config 11 - PEP1 (3 * 1024), PEP2 (N/A),
+ * PEP3 (N/A), PEP4 (2 * 512) */
+ {
+ CY_AS_EPCFG_QUAD | CY_AS_EPCFG_1024,
+ CY_AS_EPCFG_DBL,
+ },/* Config 12 - PEP1 (4 * 1024), PEP2 (N/A),
+ * PEP3 (N/A), PEP4 (N/A) */
+} ;
+
+static cy_as_return_status_t
+find_endpoint_directions(cy_as_device *dev_p,
+ cy_as_physical_endpoint_state epstate[4])
+{
+ int i ;
+ cy_as_physical_endpoint_state desired ;
+
+ /*
+ * note, there is no error checking here becuase
+ * ISO error checking happens when the API is called.
+ */
+ for (i = 0 ; i < 10 ; i++) {
+ int epno = end_point_map[i] ;
+ if (dev_p->usb_config[epno].enabled) {
+ int pep = dev_p->usb_config[epno].physical ;
+ if (dev_p->usb_config[epno].type == cy_as_usb_iso) {
+ /*
+ * marking this as an ISO endpoint, removes the
+ * physical EP from consideration when
+ * mapping the remaining E_ps.
+ */
+ if (dev_p->usb_config[epno].dir == cy_as_usb_in)
+ desired = cy_as_e_p_iso_in ;
+ else
+ desired = cy_as_e_p_iso_out ;
+ } else {
+ if (dev_p->usb_config[epno].dir == cy_as_usb_in)
+ desired = cy_as_e_p_in ;
+ else
+ desired = cy_as_e_p_out ;
+ }
+
+ /*
+ * NB: Note the API calls insure that an ISO endpoint
+ * has a physical and logical EP number that are the
+ * same, therefore this condition is not enforced here.
+ */
+ if (epstate[pep - 1] !=
+ cy_as_e_p_free && epstate[pep - 1] != desired)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ epstate[pep - 1] = desired ;
+ }
+ }
+
+ /*
+ * create the EP1 config values directly.
+ * both EP1OUT and EP1IN are invalid by default.
+ */
+ dev_p->usb_ep1cfg[0] = 0 ;
+ dev_p->usb_ep1cfg[1] = 0 ;
+ if (dev_p->usb_config[1].enabled) {
+ if ((dev_p->usb_config[1].dir == cy_as_usb_out) ||
+ (dev_p->usb_config[1].dir == cy_as_usb_in_out)) {
+ /* Set the valid bit and type field. */
+ dev_p->usb_ep1cfg[0] = (1 << 7) ;
+ if (dev_p->usb_config[1].type == cy_as_usb_bulk)
+ dev_p->usb_ep1cfg[0] |= (2 << 4) ;
+ else
+ dev_p->usb_ep1cfg[0] |= (3 << 4) ;
+ }
+
+ if ((dev_p->usb_config[1].dir == cy_as_usb_in) ||
+ (dev_p->usb_config[1].dir == cy_as_usb_in_out)) {
+ /* Set the valid bit and type field. */
+ dev_p->usb_ep1cfg[1] = (1 << 7) ;
+ if (dev_p->usb_config[1].type == cy_as_usb_bulk)
+ dev_p->usb_ep1cfg[1] |= (2 << 4) ;
+ else
+ dev_p->usb_ep1cfg[1] |= (3 << 4) ;
+ }
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+create_register_settings(cy_as_device *dev_p,
+ cy_as_physical_endpoint_state epstate[4])
+{
+ int i ;
+ uint8_t v ;
+
+ for (i = 0 ; i < 4 ; i++) {
+ if (i == 0) {
+ /* Start with the values that specify size */
+ dev_p->usb_pepcfg[i] =
+ pep_register_values
+ [dev_p->usb_phy_config - 1][0] ;
+ } else if (i == 2) {
+ /* Start with the values that specify size */
+ dev_p->usb_pepcfg[i] =
+ pep_register_values
+ [dev_p->usb_phy_config - 1][1] ;
+ } else
+ dev_p->usb_pepcfg[i] = 0 ;
+
+ /* Adjust direction if it is in */
+ if (epstate[i] == cy_as_e_p_iso_in ||
+ epstate[i] == cy_as_e_p_in)
+ dev_p->usb_pepcfg[i] |= (1 << 6) ;
+ }
+
+ /* Configure the logical EP registers */
+ for (i = 0 ; i < 10 ; i++) {
+ int val ;
+ int epnum = end_point_map[i] ;
+
+ v = 0x10 ; /* PEP 1, Bulk Endpoint, EP not valid */
+ if (dev_p->usb_config[epnum].enabled) {
+ v |= (1 << 7) ; /* Enabled */
+
+ val = dev_p->usb_config[epnum].physical - 1 ;
+ cy_as_hal_assert(val >= 0 && val <= 3) ;
+ v |= (val << 5) ;
+
+ switch (dev_p->usb_config[epnum].type) {
+ case cy_as_usb_bulk:
+ val = 2 ;
+ break ;
+ case cy_as_usb_int:
+ val = 3 ;
+ break ;
+ case cy_as_usb_iso:
+ val = 1 ;
+ break ;
+ default:
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+ v |= (val << 3) ;
+ }
+
+ dev_p->usb_lepcfg[i] = v ;
+ }
+}
+
+
+cy_as_return_status_t
+cy_as_usb_map_logical2_physical(cy_as_device *dev_p)
+{
+ cy_as_return_status_t ret ;
+
+ /* Physical EPs 3 5 7 9 respectively in the array */
+ cy_as_physical_endpoint_state epstate[4] = {
+ cy_as_e_p_free, cy_as_e_p_free,
+ cy_as_e_p_free, cy_as_e_p_free } ;
+
+ /* Find the direction for the endpoints */
+ ret = find_endpoint_directions(dev_p, epstate) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * now create the register settings based on the given
+ * assigned of logical E_ps to physical endpoints.
+ */
+ create_register_settings(dev_p, epstate) ;
+
+ return ret ;
+}
+
+static uint16_t
+get_max_dma_size(cy_as_device *dev_p, cy_as_end_point_number_t ep)
+{
+ uint16_t size = dev_p->usb_config[ep].size ;
+
+ if (size == 0) {
+ switch (dev_p->usb_config[ep].type) {
+ case cy_as_usb_control:
+ size = 64 ;
+ break ;
+
+ case cy_as_usb_bulk:
+ size = cy_as_device_is_usb_high_speed(dev_p) ?
+ 512 : 64 ;
+ break ;
+
+ case cy_as_usb_int:
+ size = cy_as_device_is_usb_high_speed(dev_p) ?
+ 1024 : 64 ;
+ break ;
+
+ case cy_as_usb_iso:
+ size = cy_as_device_is_usb_high_speed(dev_p) ?
+ 1024 : 1023 ;
+ break ;
+ }
+ }
+
+ return size ;
+}
+
+cy_as_return_status_t
+cy_as_usb_set_dma_sizes(cy_as_device *dev_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t i ;
+
+ for (i = 0 ; i < 10 ; i++) {
+ cy_as_usb_end_point_config *config_p =
+ &dev_p->usb_config[end_point_map[i]] ;
+ if (config_p->enabled) {
+ ret = cy_as_dma_set_max_dma_size(dev_p,
+ end_point_map[i],
+ get_max_dma_size(dev_p, end_point_map[i])) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ break ;
+ }
+ }
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_setup_dma(cy_as_device *dev_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t i ;
+
+ for (i = 0 ; i < 10 ; i++) {
+ cy_as_usb_end_point_config *config_p =
+ &dev_p->usb_config[end_point_map[i]] ;
+ if (config_p->enabled) {
+ /* Map the endpoint direction to the DMA direction */
+ cy_as_dma_direction dir = cy_as_direction_out ;
+ if (config_p->dir == cy_as_usb_in)
+ dir = cy_as_direction_in ;
+
+ ret = cy_as_dma_enable_end_point(dev_p,
+ end_point_map[i], cy_true, dir) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ break ;
+ }
+ }
+
+ return ret ;
+}
diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c b/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c
new file mode 100644
index 000000000000..70d56e9b060c
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c
@@ -0,0 +1,1264 @@
+/* Cypress West Bridge API source file (cyaslowlevel.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyascast.h"
+#include "../../include/linux/westbridge/cyasdevice.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyasintr.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+
+static const uint32_t cy_as_low_level_timeout_count = 65536 * 4 ;
+
+/* Forward declaration */
+static cy_as_return_status_t cy_as_send_one(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p) ;
+
+/*
+* This array holds the size of the largest request we will ever recevie from
+* the West Bridge device per context. The size is in 16 bit words. Note a
+* size of 0xffff indicates that there will be no requests on this context
+* from West Bridge.
+*/
+static uint16_t max_request_length[CY_RQT_CONTEXT_COUNT] = {
+ 8, /* CY_RQT_GENERAL_RQT_CONTEXT - CY_RQT_INITIALIZATION_COMPLETE */
+ 8, /* CY_RQT_RESOURCE_RQT_CONTEXT - none */
+ 8, /* CY_RQT_STORAGE_RQT_CONTEXT - CY_RQT_MEDIA_CHANGED */
+ 128, /* CY_RQT_USB_RQT_CONTEXT - CY_RQT_USB_EVENT */
+ 8 /* CY_RQT_TUR_RQT_CONTEXT - CY_RQT_TURBO_CMD_FROM_HOST */
+} ;
+
+/*
+* For the given context, this function removes the request node at the head
+* of the queue from the context. This is called after all processing has
+* occurred on the given request and response and we are ready to remove this
+* entry from the queue.
+*/
+static void
+cy_as_ll_remove_request_queue_head(cy_as_device *dev_p, cy_as_context *ctxt_p)
+{
+ uint32_t mask, state ;
+ cy_as_ll_request_list_node *node_p ;
+
+ (void)dev_p ;
+ cy_as_hal_assert(ctxt_p->request_queue_p != 0) ;
+
+ mask = cy_as_hal_disable_interrupts() ;
+ node_p = ctxt_p->request_queue_p ;
+ ctxt_p->request_queue_p = node_p->next ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+ node_p->callback = 0 ;
+ node_p->rqt = 0 ;
+ node_p->resp = 0 ;
+
+ /*
+ * note that the caller allocates and destroys the request and
+ * response. generally the destroy happens in the callback for
+ * async requests and after the wait returns for sync. the
+ * request and response may not actually be destroyed but may be
+ * managed in other ways as well. it is the responsibilty of
+ * the caller to deal with these in any case. the caller can do
+ * this in the request/response callback function.
+ */
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+/*
+* For the context given, this function sends the next request to
+* West Bridge via the mailbox register, if the next request is
+* ready to be sent and has not already been sent.
+*/
+static void
+cy_as_ll_send_next_request(cy_as_device *dev_p, cy_as_context *ctxt_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ /*
+ * ret == ret is equivalent to while (1) but eliminates compiler
+ * warnings for some compilers.
+ */
+ while (ret == ret) {
+ cy_as_ll_request_list_node *node_p = ctxt_p->request_queue_p ;
+ if (node_p == 0)
+ break ;
+
+ if (cy_as_request_get_node_state(node_p) !=
+ CY_AS_REQUEST_LIST_STATE_QUEUED)
+ break ;
+
+ cy_as_request_set_node_state(node_p,
+ CY_AS_REQUEST_LIST_STATE_WAITING) ;
+ ret = cy_as_send_one(dev_p, node_p->rqt) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ break ;
+
+ /*
+ * if an error occurs in sending the request, tell the requester
+ * about the error and remove the request from the queue.
+ */
+ cy_as_request_set_node_state(node_p,
+ CY_AS_REQUEST_LIST_STATE_RECEIVED) ;
+ node_p->callback(dev_p, ctxt_p->number,
+ node_p->rqt, node_p->resp, ret) ;
+ cy_as_ll_remove_request_queue_head(dev_p, ctxt_p) ;
+
+ /*
+ * this falls through to the while loop to send the next request
+ * since the previous request did not get sent.
+ */
+ }
+}
+
+/*
+* This method removes an entry from the request queue of a given context.
+* The entry is removed only if it is not in transit.
+*/
+cy_as_remove_request_result_t
+cy_as_ll_remove_request(cy_as_device *dev_p, cy_as_context *ctxt_p,
+ cy_as_ll_request_response *req_p, cy_bool force)
+{
+ uint32_t imask ;
+ cy_as_ll_request_list_node *node_p ;
+ cy_as_ll_request_list_node *tmp_p ;
+ uint32_t state ;
+
+ imask = cy_as_hal_disable_interrupts() ;
+ if (ctxt_p->request_queue_p != 0 &&
+ ctxt_p->request_queue_p->rqt == req_p) {
+ node_p = ctxt_p->request_queue_p ;
+ if ((cy_as_request_get_node_state(node_p) ==
+ CY_AS_REQUEST_LIST_STATE_WAITING) && (!force)) {
+ cy_as_hal_enable_interrupts(imask) ;
+ return cy_as_remove_request_in_transit ;
+ }
+
+ ctxt_p->request_queue_p = node_p->next ;
+ } else {
+ tmp_p = ctxt_p->request_queue_p ;
+ while (tmp_p != 0 && tmp_p->next != 0 &&
+ tmp_p->next->rqt != req_p)
+ tmp_p = tmp_p->next ;
+
+ if (tmp_p == 0 || tmp_p->next == 0) {
+ cy_as_hal_enable_interrupts(imask) ;
+ return cy_as_remove_request_not_found ;
+ }
+
+ node_p = tmp_p->next ;
+ tmp_p->next = node_p->next ;
+ }
+
+ if (node_p->callback)
+ node_p->callback(dev_p, ctxt_p->number, node_p->rqt,
+ node_p->resp, CY_AS_ERROR_CANCELED) ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+
+ cy_as_hal_enable_interrupts(imask) ;
+ return cy_as_remove_request_sucessful ;
+}
+
+void
+cy_as_ll_remove_all_requests(cy_as_device *dev_p, cy_as_context *ctxt_p)
+{
+ cy_as_ll_request_list_node *node = ctxt_p->request_queue_p ;
+
+ while (node) {
+ if (cy_as_request_get_node_state(ctxt_p->request_queue_p) !=
+ CY_AS_REQUEST_LIST_STATE_RECEIVED)
+ cy_as_ll_remove_request(dev_p, ctxt_p,
+ node->rqt, cy_true) ;
+ node = node->next ;
+ }
+}
+
+static cy_bool
+cy_as_ll_is_in_queue(cy_as_context *ctxt_p, cy_as_ll_request_response *req_p)
+{
+ uint32_t mask ;
+ cy_as_ll_request_list_node *node_p ;
+
+ mask = cy_as_hal_disable_interrupts() ;
+ node_p = ctxt_p->request_queue_p ;
+ while (node_p) {
+ if (node_p->rqt == req_p) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return cy_true ;
+ }
+ node_p = node_p->next ;
+ }
+ cy_as_hal_enable_interrupts(mask) ;
+ return cy_false ;
+}
+
+/*
+* This is the handler for mailbox data when we are trying to send data
+* to the West Bridge firmware. The firmware may be trying to send us
+* data and we need to queue this data to allow the firmware to move
+* forward and be in a state to receive our request. Here we just queue
+* the data and it is processed at a later time by the mailbox interrupt
+* handler.
+*/
+void
+cy_as_ll_queue_mailbox_data(cy_as_device *dev_p)
+{
+ cy_as_context *ctxt_p ;
+ uint8_t context ;
+ uint16_t data[4] ;
+ int32_t i ;
+
+ /* Read the data from mailbox 0 to determine what to do with the data */
+ for (i = 3 ; i >= 0 ; i--)
+ data[i] = cy_as_hal_read_register(dev_p->tag,
+ cy_cast_int2U_int16(CY_AS_MEM_P0_MAILBOX0 + i)) ;
+
+ context = cy_as_mbox_get_context(data[0]) ;
+ if (context >= CY_RQT_CONTEXT_COUNT) {
+ cy_as_hal_print_message("mailbox request/response received "
+ "with invalid context value (%d)\n", context) ;
+ return ;
+ }
+
+ ctxt_p = dev_p->context[context] ;
+
+ /*
+ * if we have queued too much data, drop future data.
+ */
+ cy_as_hal_assert(ctxt_p->queue_index * sizeof(uint16_t) +
+ sizeof(data) <= sizeof(ctxt_p->data_queue)) ;
+
+ for (i = 0 ; i < 4 ; i++)
+ ctxt_p->data_queue[ctxt_p->queue_index++] = data[i] ;
+
+ cy_as_hal_assert((ctxt_p->queue_index % 4) == 0) ;
+ dev_p->ll_queued_data = cy_true ;
+}
+
+void
+cy_as_mail_box_process_data(cy_as_device *dev_p, uint16_t *data)
+{
+ cy_as_context *ctxt_p ;
+ uint8_t context ;
+ uint16_t *len_p ;
+ cy_as_ll_request_response *rec_p ;
+ uint8_t st ;
+ uint16_t src, dest ;
+
+ context = cy_as_mbox_get_context(data[0]) ;
+ if (context >= CY_RQT_CONTEXT_COUNT) {
+ cy_as_hal_print_message("mailbox request/response received "
+ "with invalid context value (%d)\n", context) ;
+ return ;
+ }
+
+ ctxt_p = dev_p->context[context] ;
+
+ if (cy_as_mbox_is_request(data[0])) {
+ cy_as_hal_assert(ctxt_p->req_p != 0) ;
+ rec_p = ctxt_p->req_p ;
+ len_p = &ctxt_p->request_length ;
+
+ } else {
+ if (ctxt_p->request_queue_p == 0 ||
+ cy_as_request_get_node_state(ctxt_p->request_queue_p)
+ != CY_AS_REQUEST_LIST_STATE_WAITING) {
+ cy_as_hal_print_message("mailbox response received on "
+ "context that was not expecting a response\n") ;
+ cy_as_hal_print_message(" context: %d\n", context);
+ cy_as_hal_print_message(" contents: 0x%04x 0x%04x "
+ "0x%04x 0x%04x\n",
+ data[0], data[1], data[2], data[3]) ;
+ if (ctxt_p->request_queue_p != 0)
+ cy_as_hal_print_message(" state: 0x%02x\n",
+ ctxt_p->request_queue_p->state) ;
+ return ;
+ }
+
+ /* Make sure the request has an associated response */
+ cy_as_hal_assert(ctxt_p->request_queue_p->resp != 0) ;
+
+ rec_p = ctxt_p->request_queue_p->resp ;
+ len_p = &ctxt_p->request_queue_p->length ;
+ }
+
+ if (rec_p->stored == 0) {
+ /*
+ * this is the first cycle of the response
+ */
+ cy_as_ll_request_response__set_code(rec_p,
+ cy_as_mbox_get_code(data[0])) ;
+ cy_as_ll_request_response__set_context(rec_p, context) ;
+
+ if (cy_as_mbox_is_last(data[0])) {
+ /* This is a single cycle response */
+ *len_p = rec_p->length ;
+ st = 1 ;
+ } else {
+ /* Ensure that enough memory has been
+ * reserved for the response. */
+ cy_as_hal_assert(rec_p->length >= data[1]) ;
+ *len_p = (data[1] < rec_p->length) ?
+ data[1] : rec_p->length ;
+ st = 2 ;
+ }
+ } else
+ st = 1 ;
+
+ /* Trasnfer the data from the mailboxes to the response */
+ while (rec_p->stored < *len_p && st < 4)
+ rec_p->data[rec_p->stored++] = data[st++] ;
+
+ if (cy_as_mbox_is_last(data[0])) {
+ /* NB: The call-back that is made below can cause the
+ * addition of more data in this queue, thus causing
+ * a recursive overflow of the queue. this is prevented
+ * by removing the request entry that is currently
+ * being passed up from the data queue. if this is done,
+ * the queue only needs to be as long as two request
+ * entries from west bridge.
+ */
+ if ((ctxt_p->rqt_index > 0) &&
+ (ctxt_p->rqt_index <= ctxt_p->queue_index)) {
+ dest = 0 ;
+ src = ctxt_p->rqt_index ;
+
+ while (src < ctxt_p->queue_index)
+ ctxt_p->data_queue[dest++] =
+ ctxt_p->data_queue[src++] ;
+
+ ctxt_p->rqt_index = 0 ;
+ ctxt_p->queue_index = dest ;
+ cy_as_hal_assert((ctxt_p->queue_index % 4) == 0) ;
+ }
+
+ if (ctxt_p->request_queue_p != 0 && rec_p ==
+ ctxt_p->request_queue_p->resp) {
+ /*
+ * if this is the last cycle of the response, call the
+ * callback and reset for the next response.
+ */
+ cy_as_ll_request_response *resp_p =
+ ctxt_p->request_queue_p->resp ;
+ resp_p->length = ctxt_p->request_queue_p->length ;
+ cy_as_request_set_node_state(ctxt_p->request_queue_p,
+ CY_AS_REQUEST_LIST_STATE_RECEIVED) ;
+
+ cy_as_device_set_in_callback(dev_p) ;
+ ctxt_p->request_queue_p->callback(dev_p, context,
+ ctxt_p->request_queue_p->rqt,
+ resp_p, CY_AS_ERROR_SUCCESS) ;
+
+ cy_as_device_clear_in_callback(dev_p) ;
+
+ cy_as_ll_remove_request_queue_head(dev_p, ctxt_p) ;
+ cy_as_ll_send_next_request(dev_p, ctxt_p) ;
+ } else {
+ /* Send the request to the appropriate
+ * module to handle */
+ cy_as_ll_request_response *request_p = ctxt_p->req_p ;
+ ctxt_p->req_p = 0 ;
+ if (ctxt_p->request_callback) {
+ cy_as_device_set_in_callback(dev_p) ;
+ ctxt_p->request_callback(dev_p, context,
+ request_p, 0, CY_AS_ERROR_SUCCESS) ;
+ cy_as_device_clear_in_callback(dev_p) ;
+ }
+ cy_as_ll_init_request(request_p, 0,
+ context, request_p->length) ;
+ ctxt_p->req_p = request_p ;
+ }
+ }
+}
+
+/*
+* This is the handler for processing queued mailbox data
+*/
+void
+cy_as_mail_box_queued_data_handler(cy_as_device *dev_p)
+{
+ uint16_t i ;
+
+ /*
+ * if more data gets queued in between our entering this call
+ * and the end of the iteration on all contexts; we should
+ * continue processing the queued data.
+ */
+ while (dev_p->ll_queued_data) {
+ dev_p->ll_queued_data = cy_false ;
+ for (i = 0 ; i < CY_RQT_CONTEXT_COUNT ; i++) {
+ uint16_t offset ;
+ cy_as_context *ctxt_p = dev_p->context[i] ;
+ cy_as_hal_assert((ctxt_p->queue_index % 4) == 0) ;
+
+ offset = 0 ;
+ while (offset < ctxt_p->queue_index) {
+ ctxt_p->rqt_index = offset + 4 ;
+ cy_as_mail_box_process_data(dev_p,
+ ctxt_p->data_queue + offset) ;
+ offset = ctxt_p->rqt_index ;
+ }
+ ctxt_p->queue_index = 0 ;
+ }
+ }
+}
+
+/*
+* This is the handler for the mailbox interrupt. This function reads
+* data from the mailbox registers until a complete request or response
+* is received. When a complete request is received, the callback
+* associated with requests on that context is called. When a complete
+* response is recevied, the callback associated with the request that
+* generated the reponse is called.
+*/
+void
+cy_as_mail_box_interrupt_handler(cy_as_device *dev_p)
+{
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ /*
+ * queue the mailbox data to preserve
+ * order for later processing.
+ */
+ cy_as_ll_queue_mailbox_data(dev_p) ;
+
+ /*
+ * process what was queued and anything that may be pending
+ */
+ cy_as_mail_box_queued_data_handler(dev_p) ;
+}
+
+cy_as_return_status_t
+cy_as_ll_start(cy_as_device *dev_p)
+{
+ uint16_t i ;
+
+ if (cy_as_device_is_low_level_running(dev_p))
+ return CY_AS_ERROR_ALREADY_RUNNING ;
+
+ dev_p->ll_sending_rqt = cy_false ;
+ dev_p->ll_abort_curr_rqt = cy_false ;
+
+ for (i = 0 ; i < CY_RQT_CONTEXT_COUNT ; i++) {
+ dev_p->context[i] = (cy_as_context *)
+ cy_as_hal_alloc(sizeof(cy_as_context)) ;
+ if (dev_p->context[i] == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ dev_p->context[i]->number = (uint8_t)i ;
+ dev_p->context[i]->request_callback = 0 ;
+ dev_p->context[i]->request_queue_p = 0 ;
+ dev_p->context[i]->last_node_p = 0 ;
+ dev_p->context[i]->req_p = cy_as_ll_create_request(dev_p,
+ 0, (uint8_t)i, max_request_length[i]) ;
+ dev_p->context[i]->queue_index = 0 ;
+
+ if (!cy_as_hal_create_sleep_channel
+ (&dev_p->context[i]->channel))
+ return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED ;
+ }
+
+ cy_as_device_set_low_level_running(dev_p) ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* Shutdown the low level communications module. This operation will
+* also cancel any queued low level requests.
+*/
+cy_as_return_status_t
+cy_as_ll_stop(cy_as_device *dev_p)
+{
+ uint8_t i ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_context *ctxt_p ;
+ uint32_t mask ;
+
+ for (i = 0 ; i < CY_RQT_CONTEXT_COUNT ; i++) {
+ ctxt_p = dev_p->context[i] ;
+ if (!cy_as_hal_destroy_sleep_channel(&ctxt_p->channel))
+ return CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED ;
+
+ /*
+ * now, free any queued requests and assocaited responses
+ */
+ while (ctxt_p->request_queue_p) {
+ uint32_t state ;
+ cy_as_ll_request_list_node *node_p =
+ ctxt_p->request_queue_p ;
+
+ /* Mark this pair as in a cancel operation */
+ cy_as_request_set_node_state(node_p,
+ CY_AS_REQUEST_LIST_STATE_CANCELING) ;
+
+ /* Tell the caller that we are canceling this request */
+ /* NB: The callback is responsible for destroying the
+ * request and the response. we cannot count on the
+ * contents of these two after calling the callback.
+ */
+ node_p->callback(dev_p, i, node_p->rqt,
+ node_p->resp, CY_AS_ERROR_CANCELED) ;
+
+ /* Remove the pair from the queue */
+ mask = cy_as_hal_disable_interrupts() ;
+ ctxt_p->request_queue_p = node_p->next ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+ /* Free the list node */
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+ }
+
+ cy_as_ll_destroy_request(dev_p, dev_p->context[i]->req_p) ;
+ cy_as_hal_free(dev_p->context[i]) ;
+ dev_p->context[i] = 0 ;
+
+ }
+ cy_as_device_set_low_level_stopped(dev_p) ;
+
+ return ret ;
+}
+
+void
+cy_as_ll_init_request(cy_as_ll_request_response *req_p,
+ uint16_t code, uint16_t context, uint16_t length)
+{
+ uint16_t totallen = sizeof(cy_as_ll_request_response) +
+ (length - 1) * sizeof(uint16_t) ;
+
+ cy_as_hal_mem_set(req_p, 0, totallen) ;
+ req_p->length = length ;
+ cy_as_ll_request_response__set_code(req_p, code) ;
+ cy_as_ll_request_response__set_context(req_p, context) ;
+ cy_as_ll_request_response__set_request(req_p) ;
+}
+
+/*
+* Create a new request.
+*/
+cy_as_ll_request_response *
+cy_as_ll_create_request(cy_as_device *dev_p, uint16_t code,
+ uint8_t context, uint16_t length)
+{
+ cy_as_ll_request_response *req_p ;
+ uint32_t state ;
+ uint16_t totallen = sizeof(cy_as_ll_request_response) +
+ (length - 1) * sizeof(uint16_t) ;
+
+ (void)dev_p ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ req_p = cy_as_hal_c_b_alloc(totallen) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (req_p)
+ cy_as_ll_init_request(req_p, code, context, length) ;
+
+ return req_p ;
+}
+
+/*
+* Destroy a request.
+*/
+void
+cy_as_ll_destroy_request(cy_as_device *dev_p, cy_as_ll_request_response *req_p)
+{
+ uint32_t state ;
+ (void)dev_p ;
+ (void)req_p ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(req_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+
+}
+
+void
+cy_as_ll_init_response(cy_as_ll_request_response *req_p, uint16_t length)
+{
+ uint16_t totallen = sizeof(cy_as_ll_request_response) +
+ (length - 1) * sizeof(uint16_t) ;
+
+ cy_as_hal_mem_set(req_p, 0, totallen) ;
+ req_p->length = length ;
+ cy_as_ll_request_response__set_response(req_p) ;
+}
+
+/*
+* Create a new response
+*/
+cy_as_ll_request_response *
+cy_as_ll_create_response(cy_as_device *dev_p, uint16_t length)
+{
+ cy_as_ll_request_response *req_p ;
+ uint32_t state ;
+ uint16_t totallen = sizeof(cy_as_ll_request_response) +
+ (length - 1) * sizeof(uint16_t) ;
+
+ (void)dev_p ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ req_p = cy_as_hal_c_b_alloc(totallen) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (req_p)
+ cy_as_ll_init_response(req_p, length) ;
+
+ return req_p ;
+}
+
+/*
+* Destroy the new response
+*/
+void
+cy_as_ll_destroy_response(cy_as_device *dev_p, cy_as_ll_request_response *req_p)
+{
+ uint32_t state ;
+ (void)dev_p ;
+ (void)req_p ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(req_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+static uint16_t
+cy_as_read_intr_status(
+ cy_as_device *dev_p)
+{
+ uint32_t mask ;
+ cy_bool bloop = cy_true ;
+ uint16_t v = 0, last = 0xffff;
+
+ /*
+ * before determining if the mailboxes are ready for more data,
+ * we first check the mailbox interrupt to see if we need to
+ * receive data. this prevents a dead-lock condition that can
+ * occur when both sides are trying to receive data.
+ */
+ while (last == last) {
+ /*
+ * disable interrupts to be sure we don't process the mailbox
+ * here and have the interrupt routine try to read this data
+ * as well.
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+
+ /*
+ * see if there is data to be read.
+ */
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG) ;
+ if ((v & CY_AS_MEM_P0_INTR_REG_MBINT) == 0) {
+ cy_as_hal_enable_interrupts(mask) ;
+ break ;
+ }
+
+ /*
+ * queue the mailbox data for later processing.
+ * this allows the firmware to move forward and
+ * service the requst from the P port.
+ */
+ cy_as_ll_queue_mailbox_data(dev_p) ;
+
+ /*
+ * enable interrupts again to service mailbox
+ * interrupts appropriately
+ */
+ cy_as_hal_enable_interrupts(mask) ;
+ }
+
+ /*
+ * now, all data is received
+ */
+ last = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD ;
+ while (bloop) {
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD ;
+ if (v == last)
+ break ;
+
+ last = v ;
+ }
+
+ return v ;
+}
+
+/*
+* Send a single request or response using the mail box register.
+* This function does not deal with the internal queues at all,
+* but only sends the request or response across to the firmware
+*/
+static cy_as_return_status_t
+cy_as_send_one(
+ cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ int i ;
+ uint16_t mb0, v ;
+ int32_t loopcount ;
+ uint32_t int_stat ;
+
+#ifdef _DEBUG
+ if (cy_as_ll_request_response__is_request(req_p)) {
+ switch (cy_as_ll_request_response__get_context(req_p)) {
+ case CY_RQT_GENERAL_RQT_CONTEXT:
+ cy_as_hal_assert(req_p->length * 2 + 2 <
+ CY_CTX_GEN_MAX_DATA_SIZE) ;
+ break ;
+
+ case CY_RQT_RESOURCE_RQT_CONTEXT:
+ cy_as_hal_assert(req_p->length * 2 + 2 <
+ CY_CTX_RES_MAX_DATA_SIZE) ;
+ break ;
+
+ case CY_RQT_STORAGE_RQT_CONTEXT:
+ cy_as_hal_assert(req_p->length * 2 + 2 <
+ CY_CTX_STR_MAX_DATA_SIZE) ;
+ break ;
+
+ case CY_RQT_USB_RQT_CONTEXT:
+ cy_as_hal_assert(req_p->length * 2 + 2 <
+ CY_CTX_USB_MAX_DATA_SIZE) ;
+ break ;
+ }
+ }
+#endif
+
+ /* Write the request to the mail box registers */
+ if (req_p->length > 3) {
+ uint16_t length = req_p->length ;
+ int which = 0 ;
+ int st = 1 ;
+
+ dev_p->ll_sending_rqt = cy_true ;
+ while (which < length) {
+ loopcount = cy_as_low_level_timeout_count ;
+ do {
+ v = cy_as_read_intr_status(dev_p) ;
+
+ } while (v && loopcount-- > 0) ;
+
+ if (v) {
+ cy_as_hal_print_message(
+ ">>>>>> LOW LEVEL TIMEOUT "
+ "%x %x %x %x\n",
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX0),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX1),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX2),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX3)) ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+
+ if (dev_p->ll_abort_curr_rqt) {
+ dev_p->ll_sending_rqt = cy_false ;
+ dev_p->ll_abort_curr_rqt = cy_false ;
+ return CY_AS_ERROR_CANCELED ;
+ }
+
+ int_stat = cy_as_hal_disable_interrupts() ;
+
+ /*
+ * check again whether the mailbox is free.
+ * it is possible that an ISR came in and
+ * wrote into the mailboxes since we last
+ * checked the status.
+ */
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MB_STAT) &
+ CY_AS_MEM_P0_MCU_MBNOTRD ;
+ if (v) {
+ /* Go back to the original check since
+ * the mailbox is not free. */
+ cy_as_hal_enable_interrupts(int_stat) ;
+ continue ;
+ }
+
+ if (which == 0) {
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX1, length) ;
+ st = 2 ;
+ } else {
+ st = 1;
+ }
+
+ while ((which < length) && (st < 4)) {
+ cy_as_hal_write_register(dev_p->tag,
+ cy_cast_int2U_int16
+ (CY_AS_MEM_MCU_MAILBOX0 + st),
+ req_p->data[which++]) ;
+ st++ ;
+ }
+
+ mb0 = req_p->box0 ;
+ if (which == length) {
+ dev_p->ll_sending_rqt = cy_false ;
+ mb0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK ;
+ }
+
+ if (dev_p->ll_abort_curr_rqt) {
+ dev_p->ll_sending_rqt = cy_false ;
+ dev_p->ll_abort_curr_rqt = cy_false ;
+ cy_as_hal_enable_interrupts(int_stat) ;
+ return CY_AS_ERROR_CANCELED ;
+ }
+
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX0, mb0) ;
+
+ /* Wait for the MBOX interrupt to be high */
+ cy_as_hal_sleep150() ;
+ cy_as_hal_enable_interrupts(int_stat) ;
+ }
+ } else {
+check_mailbox_availability:
+ /*
+ * wait for the mailbox registers to become available. this
+ * should be a very quick wait as the firmware is designed
+ * to accept requests at interrupt time and queue them for
+ * future processing.
+ */
+ loopcount = cy_as_low_level_timeout_count ;
+ do {
+ v = cy_as_read_intr_status(dev_p) ;
+
+ } while (v && loopcount-- > 0) ;
+
+ if (v) {
+ cy_as_hal_print_message(
+ ">>>>>> LOW LEVEL TIMEOUT %x %x %x %x\n",
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX0),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX1),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX2),
+ cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_MCU_MAILBOX3)) ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+
+ int_stat = cy_as_hal_disable_interrupts();
+
+ /*
+ * check again whether the mailbox is free. it is
+ * possible that an ISR came in and wrote into the
+ * mailboxes since we last checked the status.
+ */
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_MCU_MB_STAT) &
+ CY_AS_MEM_P0_MCU_MBNOTRD ;
+ if (v) {
+ /* Go back to the original check
+ * since the mailbox is not free. */
+ cy_as_hal_enable_interrupts(int_stat) ;
+ goto check_mailbox_availability ;
+ }
+
+ /* Write the data associated with the request
+ * into the mbox registers 1 - 3 */
+ v = 0 ;
+ for (i = req_p->length - 1 ; i >= 0 ; i--)
+ cy_as_hal_write_register(dev_p->tag,
+ cy_cast_int2U_int16(CY_AS_MEM_MCU_MAILBOX1 + i),
+ req_p->data[i]) ;
+
+ /* Write the mbox register 0 to trigger the interrupt */
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_MCU_MAILBOX0,
+ req_p->box0 | CY_AS_REQUEST_RESPONSE_LAST_MASK) ;
+
+ cy_as_hal_sleep150() ;
+ cy_as_hal_enable_interrupts(int_stat);
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* This function queues a single request to be sent to the firmware.
+*/
+extern cy_as_return_status_t
+cy_as_ll_send_request(
+ cy_as_device *dev_p,
+ /* The request to send */
+ cy_as_ll_request_response *req,
+ /* Storage for a reply, must be sure
+ * it is of sufficient size */
+ cy_as_ll_request_response *resp,
+ /* If true, this is a synchronous request */
+ cy_bool sync,
+ /* Callback to call when reply is received */
+ cy_as_response_callback cb
+)
+{
+ cy_as_context *ctxt_p ;
+ uint16_t box0 = req->box0 ;
+ uint8_t context ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_list_node *node_p ;
+ uint32_t mask, state ;
+
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
+
+ context = cy_as_mbox_get_context(box0) ;
+ cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT) ;
+ ctxt_p = dev_p->context[context] ;
+
+ /* Allocate the list node */
+ state = cy_as_hal_disable_interrupts() ;
+ node_p = cy_as_hal_c_b_alloc(sizeof(cy_as_ll_request_list_node)) ;
+ cy_as_hal_enable_interrupts(state) ;
+
+ if (node_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Initialize the list node */
+ node_p->callback = cb ;
+ node_p->length = 0 ;
+ node_p->next = 0 ;
+ node_p->resp = resp ;
+ node_p->rqt = req ;
+ node_p->state = CY_AS_REQUEST_LIST_STATE_QUEUED ;
+ if (sync)
+ cy_as_request_node_set_sync(node_p) ;
+
+ /* Put the request into the queue */
+ mask = cy_as_hal_disable_interrupts() ;
+ if (ctxt_p->request_queue_p == 0) {
+ /* Empty queue */
+ ctxt_p->request_queue_p = node_p ;
+ ctxt_p->last_node_p = node_p ;
+ } else {
+ ctxt_p->last_node_p->next = node_p ;
+ ctxt_p->last_node_p = node_p ;
+ }
+ cy_as_hal_enable_interrupts(mask) ;
+ cy_as_ll_send_next_request(dev_p, ctxt_p) ;
+
+ if (!cy_as_device_is_in_callback(dev_p)) {
+ mask = cy_as_hal_disable_interrupts() ;
+ cy_as_mail_box_queued_data_handler(dev_p) ;
+ cy_as_hal_enable_interrupts(mask) ;
+ }
+
+ return ret ;
+}
+
+static void
+cy_as_ll_send_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ (void)rqt ;
+ (void)resp ;
+ (void)ret ;
+
+
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ /*
+ * storage the state to return to the caller
+ */
+ dev_p->ll_error = ret ;
+
+ /*
+ * now wake the caller
+ */
+ cy_as_hal_wake(&dev_p->context[context]->channel) ;
+}
+
+cy_as_return_status_t
+cy_as_ll_send_request_wait_reply(
+ cy_as_device *dev_p,
+ /* The request to send */
+ cy_as_ll_request_response *req,
+ /* Storage for a reply, must be
+ * sure it is of sufficient size */
+ cy_as_ll_request_response *resp
+ )
+{
+ cy_as_return_status_t ret ;
+ uint8_t context ;
+ /* Larger 8 sec time-out to handle the init
+ * delay for slower storage devices in USB FS. */
+ uint32_t loopcount = 800 ;
+ cy_as_context *ctxt_p ;
+
+ /* Get the context for the request */
+ context = cy_as_ll_request_response__get_context(req) ;
+ cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT) ;
+ ctxt_p = dev_p->context[context] ;
+
+ ret = cy_as_ll_send_request(dev_p, req, resp,
+ cy_true, cy_as_ll_send_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ while (loopcount-- > 0) {
+ /*
+ * sleep while we wait on the response. receiving the reply will
+ * wake this thread. we will wait, at most 2 seconds (10 ms*200
+ * tries) before we timeout. note if the reply arrives, we will
+ * not sleep the entire 10 ms, just til the reply arrives.
+ */
+ cy_as_hal_sleep_on(&ctxt_p->channel, 10) ;
+
+ /*
+ * if the request has left the queue, it means the request has
+ * been sent and the reply has been received. this means we can
+ * return to the caller and be sure the reply has been received.
+ */
+ if (!cy_as_ll_is_in_queue(ctxt_p, req))
+ return dev_p->ll_error ;
+ }
+
+ /* Remove the QueueListNode for this request. */
+ cy_as_ll_remove_request(dev_p, ctxt_p, req, cy_true) ;
+
+ return CY_AS_ERROR_TIMEOUT ;
+}
+
+cy_as_return_status_t
+cy_as_ll_register_request_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_response_callback cb)
+{
+ cy_as_context *ctxt_p ;
+ cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT) ;
+ ctxt_p = dev_p->context[context] ;
+
+ ctxt_p->request_callback = cb ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+void
+cy_as_ll_request_response__pack(
+ cy_as_ll_request_response *req_p,
+ uint32_t offset,
+ uint32_t length,
+ void *data_p)
+{
+ uint16_t dt ;
+ uint8_t *dp = (uint8_t *)data_p ;
+
+ while (length > 1) {
+ dt = ((*dp++) << 8) ;
+ dt |= (*dp++) ;
+ cy_as_ll_request_response__set_word(req_p, offset, dt) ;
+ offset++ ;
+ length -= 2 ;
+ }
+
+ if (length == 1) {
+ dt = (*dp << 8) ;
+ cy_as_ll_request_response__set_word(req_p, offset, dt) ;
+ }
+}
+
+void
+cy_as_ll_request_response__unpack(
+ cy_as_ll_request_response *req_p,
+ uint32_t offset,
+ uint32_t length,
+ void *data_p)
+{
+ uint8_t *dp = (uint8_t *)data_p ;
+
+ while (length-- > 0) {
+ uint16_t val = cy_as_ll_request_response__get_word
+ (req_p, offset++) ;
+ *dp++ = (uint8_t)((val >> 8) & 0xff) ;
+
+ if (length) {
+ length-- ;
+ *dp++ = (uint8_t)(val & 0xff) ;
+ }
+ }
+}
+
+extern cy_as_return_status_t
+cy_as_ll_send_status_response(
+ cy_as_device *dev_p,
+ uint8_t context,
+ uint16_t code,
+ uint8_t clear_storage)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response resp ;
+ cy_as_ll_request_response *resp_p = &resp ;
+
+ cy_as_hal_mem_set(resp_p, 0, sizeof(resp)) ;
+ resp_p->length = 1 ;
+ cy_as_ll_request_response__set_response(resp_p) ;
+ cy_as_ll_request_response__set_context(resp_p, context) ;
+
+ if (clear_storage)
+ cy_as_ll_request_response__set_clear_storage_flag(resp_p) ;
+
+ cy_as_ll_request_response__set_code(resp_p, CY_RESP_SUCCESS_FAILURE) ;
+ cy_as_ll_request_response__set_word(resp_p, 0, code) ;
+
+ ret = cy_as_send_one(dev_p, resp_p) ;
+
+ return ret ;
+}
+
+extern cy_as_return_status_t
+cy_as_ll_send_data_response(
+ cy_as_device *dev_p,
+ uint8_t context,
+ uint16_t code,
+ uint16_t length,
+ void *data)
+{
+ cy_as_ll_request_response *resp_p ;
+ uint16_t wlen ;
+ uint8_t respbuf[256] ;
+
+ if (length > 192)
+ return CY_AS_ERROR_INVALID_SIZE ;
+
+ /* Word length for bytes */
+ wlen = length / 2 ;
+
+ /* If byte length odd, add one more */
+ if (length % 2)
+ wlen++ ;
+
+ /* One for the length of field */
+ wlen++ ;
+
+ resp_p = (cy_as_ll_request_response *)respbuf ;
+ cy_as_hal_mem_set(resp_p, 0, sizeof(respbuf)) ;
+ resp_p->length = wlen ;
+ cy_as_ll_request_response__set_context(resp_p, context) ;
+ cy_as_ll_request_response__set_code(resp_p, code) ;
+
+ cy_as_ll_request_response__set_word(resp_p, 0, length) ;
+ cy_as_ll_request_response__pack(resp_p, 1, length, data) ;
+
+ return cy_as_send_one(dev_p, resp_p) ;
+}
+
+static cy_bool
+cy_as_ll_is_e_p_transfer_related_request(cy_as_ll_request_response *rqt_p,
+ cy_as_end_point_number_t ep)
+{
+ uint16_t v ;
+ uint8_t type = cy_as_ll_request_response__get_code(rqt_p) ;
+
+ if (cy_as_ll_request_response__get_context(rqt_p) !=
+ CY_RQT_USB_RQT_CONTEXT)
+ return cy_false ;
+
+ /*
+ * when cancelling outstanding EP0 data transfers, any pending
+ * setup ACK requests also need to be cancelled.
+ */
+ if ((ep == 0) && (type == CY_RQT_ACK_SETUP_PACKET))
+ return cy_true ;
+
+ if (type != CY_RQT_USB_EP_DATA)
+ return cy_false ;
+
+ v = cy_as_ll_request_response__get_word(rqt_p, 0) ;
+ if ((cy_as_end_point_number_t)((v >> 13) & 1) != ep)
+ return cy_false ;
+
+ return cy_true ;
+}
+
+cy_as_return_status_t
+cy_as_ll_remove_ep_data_requests(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep)
+{
+ cy_as_context *ctxt_p ;
+ cy_as_ll_request_list_node *node_p ;
+ uint32_t imask ;
+
+ /*
+ * first, remove any queued requests
+ */
+ ctxt_p = dev_p->context[CY_RQT_USB_RQT_CONTEXT] ;
+ if (ctxt_p) {
+ for (node_p = ctxt_p->request_queue_p; node_p;
+ node_p = node_p->next) {
+ if (cy_as_ll_is_e_p_transfer_related_request
+ (node_p->rqt, ep)) {
+ cy_as_ll_remove_request(dev_p, ctxt_p,
+ node_p->rqt, cy_false) ;
+ break ;
+ }
+ }
+
+ /*
+ * now, deal with any request that may be in transit
+ */
+ imask = cy_as_hal_disable_interrupts() ;
+
+ if (ctxt_p->request_queue_p != 0 &&
+ cy_as_ll_is_e_p_transfer_related_request
+ (ctxt_p->request_queue_p->rqt, ep) &&
+ cy_as_request_get_node_state(ctxt_p->request_queue_p) ==
+ CY_AS_REQUEST_LIST_STATE_WAITING) {
+ cy_as_hal_print_message("need to remove an in-transit "
+ "request to antioch\n") ;
+
+ /*
+ * if the request has not been fully sent to west bridge
+ * yet, abort sending. otherwise, terminate the request
+ * with a CANCELED status. firmware will already have
+ * terminated this transfer.
+ */
+ if (dev_p->ll_sending_rqt)
+ dev_p->ll_abort_curr_rqt = cy_true ;
+ else {
+ uint32_t state ;
+
+ node_p = ctxt_p->request_queue_p ;
+ if (node_p->callback)
+ node_p->callback(dev_p, ctxt_p->number,
+ node_p->rqt, node_p->resp,
+ CY_AS_ERROR_CANCELED) ;
+
+ ctxt_p->request_queue_p = node_p->next ;
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+ }
+ }
+
+ cy_as_hal_enable_interrupts(imask) ;
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c
new file mode 100644
index 000000000000..7c1c945873d5
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c
@@ -0,0 +1,3474 @@
+/* Cypress West Bridge API source file (cyasmisc.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasmisc.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+#include "../../include/linux/westbridge/cyasintr.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyasprotocol.h"
+
+/*
+* The device list, the only global in the API
+*/
+static cy_as_device *g_device_list;
+
+/*
+ * The current debug level
+ */
+static uint8_t debug_level;
+
+/*
+ * This function sets the debug level for the API
+ *
+ */
+void
+cy_as_misc_set_log_level(uint8_t level)
+{
+ debug_level = level ;
+}
+
+#ifdef CY_AS_LOG_SUPPORT
+
+/*
+ * This function is a low level logger for the API.
+ */
+void
+cy_as_log_debug_message(int level, const char *str)
+{
+ if (level <= debug_level)
+ cy_as_hal_print_message("log %d: %s\n", level, str) ;
+}
+
+#endif
+
+#define cy_as_check_device_ready(dev_p) \
+{\
+ if (!(dev_p) || ((dev_p)->sig != \
+ CY_AS_DEVICE_HANDLE_SIGNATURE)) \
+ return CY_AS_ERROR_INVALID_HANDLE ; \
+\
+ if (!cy_as_device_is_configured(dev_p)) \
+ return CY_AS_ERROR_NOT_CONFIGURED ; \
+\
+ if (!cy_as_device_is_firmware_loaded(dev_p))\
+ return CY_AS_ERROR_NO_FIRMWARE ; \
+}
+
+/* Find an West Bridge device based on a TAG */
+cy_as_device *
+cy_as_device_find_from_tag(cy_as_hal_device_tag tag)
+{
+ cy_as_device *dev_p ;
+
+ for (dev_p = g_device_list; dev_p != 0; dev_p = dev_p->next_p) {
+ if (dev_p->tag == tag)
+ return dev_p ;
+ }
+
+ return 0 ;
+}
+
+/* Map a pre-V1.2 media type to the V1.2+ bus number */
+static void
+cy_as_bus_from_media_type(cy_as_media_type type,
+ cy_as_bus_number_t *bus)
+{
+ if (type == cy_as_media_nand)
+ *bus = 0 ;
+ else
+ *bus = 1 ;
+}
+
+static cy_as_return_status_t
+my_handle_response_no_data(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+* Create a new West Bridge device
+*/
+cy_as_return_status_t
+cy_as_misc_create_device(cy_as_device_handle *handle_p,
+ cy_as_hal_device_tag tag)
+{
+ cy_as_device *dev_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_create_device called") ;
+
+ dev_p = (cy_as_device *)cy_as_hal_alloc(sizeof(cy_as_device)) ;
+ if (dev_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ cy_as_hal_mem_set(dev_p, 0, sizeof(cy_as_device)) ;
+
+ /*
+ * dynamically allocating this buffer to ensure that it is
+ * word aligned.
+ */
+ dev_p->usb_ep_data = (uint8_t *)cy_as_hal_alloc(64 * sizeof(uint8_t)) ;
+ if (dev_p->usb_ep_data == 0) {
+ cy_as_hal_free(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ dev_p->sig = CY_AS_DEVICE_HANDLE_SIGNATURE ;
+ dev_p->tag = tag ;
+ dev_p->usb_max_tx_size = 0x40 ;
+
+ dev_p->storage_write_endpoint = CY_AS_P2S_WRITE_ENDPOINT ;
+ dev_p->storage_read_endpoint = CY_AS_P2S_READ_ENDPOINT ;
+
+ dev_p->func_cbs_misc = cy_as_create_c_b_queue(CYAS_FUNC_CB) ;
+ if (dev_p->func_cbs_misc == 0)
+ goto destroy ;
+
+ dev_p->func_cbs_res = cy_as_create_c_b_queue(CYAS_FUNC_CB) ;
+ if (dev_p->func_cbs_res == 0)
+ goto destroy ;
+
+ dev_p->func_cbs_stor = cy_as_create_c_b_queue(CYAS_FUNC_CB) ;
+ if (dev_p->func_cbs_stor == 0)
+ goto destroy ;
+
+ dev_p->func_cbs_usb = cy_as_create_c_b_queue(CYAS_FUNC_CB) ;
+ if (dev_p->func_cbs_usb == 0)
+ goto destroy ;
+
+ dev_p->func_cbs_mtp = cy_as_create_c_b_queue(CYAS_FUNC_CB) ;
+ if (dev_p->func_cbs_mtp == 0)
+ goto destroy ;
+
+ /*
+ * allocate memory for the DMA module here. it is then marked idle, and
+ * will be activated when cy_as_misc_configure_device is called.
+ */
+ ret = cy_as_dma_start(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ cy_as_device_set_dma_stopped(dev_p) ;
+
+ /*
+ * allocate memory for the low level module here. this module is also
+ * activated only when cy_as_misc_configure_device is called.
+ */
+ ret = cy_as_ll_start(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ cy_as_device_set_low_level_stopped(dev_p) ;
+
+ dev_p->next_p = g_device_list ;
+ g_device_list = dev_p ;
+
+ *handle_p = dev_p ;
+ cy_as_hal_init_dev_registers(tag, cy_false) ;
+ return CY_AS_ERROR_SUCCESS ;
+
+destroy:
+ /* Free any queues that were successfully allocated. */
+ if (dev_p->func_cbs_misc)
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_misc) ;
+
+ if (dev_p->func_cbs_res)
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_res) ;
+
+ if (dev_p->func_cbs_stor)
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_stor) ;
+
+ if (dev_p->func_cbs_usb)
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_usb) ;
+
+ if (dev_p->func_cbs_mtp)
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp) ;
+
+ cy_as_hal_free(dev_p->usb_ep_data) ;
+ cy_as_hal_free(dev_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ else
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+}
+
+/*
+* Destroy an existing West Bridge device
+*/
+cy_as_return_status_t
+cy_as_misc_destroy_device(cy_as_device_handle handle)
+{
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_destroy_device called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * if the USB stack is still running,
+ * it must be stopped first
+ */
+ if (dev_p->usb_count > 0)
+ return CY_AS_ERROR_STILL_RUNNING ;
+
+ /*
+ * if the STORAGE stack is still running,
+ * it must be stopped first
+ */
+ if (dev_p->storage_count > 0)
+ return CY_AS_ERROR_STILL_RUNNING ;
+
+ if (cy_as_device_is_intr_running(dev_p))
+ ret = cy_as_intr_stop(dev_p) ;
+
+ ret = cy_as_ll_stop(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_intr_start(dev_p, dev_p->use_int_drq) ;
+ return ret ;
+ }
+
+ ret = cy_as_dma_stop(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_intr_start(dev_p, dev_p->use_int_drq) ;
+ return ret ;
+ }
+
+ /* Reset the West Bridge device. */
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG,
+ CY_AS_MEM_RST_CTRL_REG_HARD) ;
+
+ /*
+ * remove the device from the device list
+ */
+ if (g_device_list == dev_p) {
+ g_device_list = dev_p->next_p ;
+ } else {
+ cy_as_device *tmp_p = g_device_list ;
+ while (tmp_p && tmp_p->next_p != dev_p)
+ tmp_p = tmp_p->next_p ;
+
+ cy_as_hal_assert(tmp_p != 0) ;
+ tmp_p->next_p = dev_p->next_p ;
+ }
+
+ /*
+ * reset the signature so this will not be detected
+ * as a valid handle
+ */
+ dev_p->sig = 0 ;
+
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_misc) ;
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_res) ;
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_stor) ;
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_usb) ;
+ cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp) ;
+
+ /*
+ * free the memory associated with the device
+ */
+ cy_as_hal_free(dev_p->usb_ep_data) ;
+ cy_as_hal_free(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* Determine the endian mode for the processor we are
+* running on, then set the endian mode register
+*/
+static void
+cy_as_setup_endian_mode(cy_as_device *dev_p)
+{
+ /*
+ * In general, we always set west bridge intothe little
+ * endian mode. this causes the data on bit 0 internally
+ * to come out on data line 0 externally and it is generally
+ * what we want regardless of the endian mode of the
+ * processor. this capability in west bridge should be
+ * labeled as a "SWAP" capability and can be used to swap the
+ * bytes of data in and out of west bridge. this is
+ * useful if there is DMA hardware that requires this for some
+ * reason I cannot imagine at this time. basically if the
+ * wires are connected correctly, we should never need to
+ * change the endian-ness of west bridge.
+ */
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_ENDIAN,
+ CY_AS_LITTLE_ENDIAN) ;
+}
+
+/*
+* Query the West Bridge device and determine if we are an standby mode
+*/
+cy_as_return_status_t
+cy_as_misc_in_standby(cy_as_device_handle handle, cy_bool *standby)
+{
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_in_standby called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (cy_as_device_is_pin_standby(dev_p) ||
+ cy_as_device_is_register_standby(dev_p)) {
+ *standby = cy_true ;
+ } else
+ *standby = cy_false ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+cy_as_misc_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret) ;
+
+
+static void
+my_misc_callback(cy_as_device *dev_p, uint8_t context,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *resp_p,
+ cy_as_return_status_t ret)
+{
+ (void)resp_p ;
+ (void)context ;
+ (void)ret ;
+
+ switch (cy_as_ll_request_response__get_code(req_p)) {
+ case CY_RQT_INITIALIZATION_COMPLETE:
+ {
+ uint16_t v ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_GENERAL_RQT_CONTEXT,
+ CY_AS_ERROR_SUCCESS, 0) ;
+ cy_as_device_set_firmware_loaded(dev_p) ;
+
+ if (cy_as_device_is_waking(dev_p)) {
+ /*
+ * this is a callback from a
+ * cy_as_misc_leave_standby()
+ * request. in this case we call
+ * the standby callback and clear
+ * the waking state.
+ */
+ if (dev_p->misc_event_cb)
+ dev_p->misc_event_cb(
+ (cy_as_device_handle)dev_p,
+ cy_as_event_misc_awake, 0) ;
+ cy_as_device_clear_waking(dev_p) ;
+ } else {
+ v = cy_as_ll_request_response__get_word
+ (req_p, 3) ;
+
+ /*
+ * store the media supported on
+ * each of the device buses.
+ */
+ dev_p->media_supported[0] =
+ (uint8_t)(v & 0xFF) ;
+ dev_p->media_supported[1] =
+ (uint8_t)((v >> 8) & 0xFF) ;
+
+ v = cy_as_ll_request_response__get_word
+ (req_p, 4) ;
+
+ dev_p->is_mtp_firmware =
+ (cy_bool)((v >> 8) & 0xFF) ;
+
+ if (dev_p->misc_event_cb)
+ dev_p->misc_event_cb(
+ (cy_as_device_handle)dev_p,
+ cy_as_event_misc_initialized, 0) ;
+ }
+
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_P0_VM_SET) ;
+
+ if (v & CY_AS_MEM_P0_VM_SET_CFGMODE)
+ cy_as_hal_print_message(
+ "initialization message "
+ "recieved, but config bit "
+ "still set\n") ;
+
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG) ;
+ if ((v & CY_AS_MEM_RST_RSTCMPT) == 0)
+ cy_as_hal_print_message(
+ "initialization message "
+ "recieved, but reset complete "
+ "bit still not set\n") ;
+ }
+ break ;
+
+ case CY_RQT_OUT_OF_SUSPEND:
+ cy_as_ll_send_status_response(dev_p, CY_RQT_GENERAL_RQT_CONTEXT,
+ CY_AS_ERROR_SUCCESS, 0) ;
+ cy_as_device_clear_suspend_mode(dev_p) ;
+
+ /*
+ * if the wakeup was caused by an async cy_as_misc_leave_suspend
+ * call, we have to call the corresponding callback.
+ */
+ if (dev_p->func_cbs_misc->count > 0) {
+ cy_as_func_c_b_node *node = (cy_as_func_c_b_node *)
+ dev_p->func_cbs_misc->head_p ;
+ cy_as_hal_assert(node) ;
+
+ if (cy_as_funct_c_b_type_get_type(node->data_type) ==
+ CY_FUNCT_CB_MISC_LEAVESUSPEND) {
+ cy_as_hal_assert(node->cb_p != 0) ;
+
+ node->cb_p((cy_as_device_handle)dev_p,
+ CY_AS_ERROR_SUCCESS, node->client_data,
+ CY_FUNCT_CB_MISC_LEAVESUSPEND, 0) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_misc) ;
+ }
+ }
+
+ if (dev_p->misc_event_cb)
+ dev_p->misc_event_cb((cy_as_device_handle)dev_p,
+ cy_as_event_misc_wakeup, 0) ;
+ break ;
+
+ case CY_RQT_DEBUG_MESSAGE:
+ if ((req_p->data[0] == 0) && (req_p->data[1] == 0) &&
+ (req_p->data[2] == 0)) {
+ if (dev_p->misc_event_cb)
+ dev_p->misc_event_cb((cy_as_device_handle)dev_p,
+ cy_as_event_misc_heart_beat, 0) ;
+ } else {
+ cy_as_hal_print_message(
+ "**** debug message: %02x "
+ "%02x %02x %02x %02x %02x\n",
+ req_p->data[0] & 0xff,
+ (req_p->data[0] >> 8) & 0xff,
+ req_p->data[1] & 0xff,
+ (req_p->data[1] >> 8) & 0xff,
+ req_p->data[2] & 0xff,
+ (req_p->data[2] >> 8) & 0xff) ;
+ }
+ break ;
+
+ case CY_RQT_WB_DEVICE_MISMATCH:
+ {
+ if (dev_p->misc_event_cb)
+ dev_p->misc_event_cb((cy_as_device_handle)dev_p,
+ cy_as_event_misc_device_mismatch, 0) ;
+ }
+ break ;
+
+ case CY_RQT_BOOTLOAD_NO_FIRMWARE:
+ {
+ /* TODO Handle case when firmware is
+ * not found during bootloading. */
+ cy_as_hal_print_message("no firmware image found "
+ "during bootload. device not started\n") ;
+ }
+ break ;
+
+ default:
+ cy_as_hal_assert(0) ;
+ }
+}
+
+static cy_bool
+is_valid_silicon_id(uint16_t v)
+{
+ cy_bool idok = cy_false ;
+
+ /*
+ * remove the revision number from the ID value
+ */
+ v = v & CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK ;
+
+ /*
+ * if this is west bridge, then we are OK.
+ */
+ if (v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE ||
+ v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE ||
+ v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE)
+ idok = cy_true ;
+
+ return idok ;
+}
+
+/*
+* Configure the West Bridge device hardware
+*/
+cy_as_return_status_t
+cy_as_misc_configure_device(cy_as_device_handle handle,
+ cy_as_device_config *config_p)
+{
+ cy_as_return_status_t ret ;
+ cy_bool standby ;
+ cy_as_device *dev_p ;
+ uint16_t v ;
+ uint16_t fw_present;
+ cy_as_log_debug_message(6, "cy_as_misc_configure_device called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /* Setup big endian vs little endian */
+ cy_as_setup_endian_mode(dev_p) ;
+
+ /* Now, confirm that we can talk to the West Bridge device */
+ dev_p->silicon_id = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+ fw_present = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG) ;
+ if (!(fw_present & CY_AS_MEM_RST_RSTCMPT)) {
+ if (!is_valid_silicon_id(dev_p->silicon_id))
+ return CY_AS_ERROR_NO_ANTIOCH ;
+ }
+ /* Check for standby mode */
+ ret = cy_as_misc_in_standby(handle, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ if (ret)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ /* Setup P-port interface mode (CRAM / SRAM). */
+ if (cy_as_device_is_astoria_dev(dev_p)) {
+ if (config_p->srammode)
+ v = CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM ;
+ else
+ v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM ;
+ } else
+ v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM ;
+
+ /* Setup synchronous versus asynchronous mode */
+ if (config_p->sync)
+ v |= CY_AS_MEM_P0_VM_SET_IFMODE ;
+ if (config_p->dackmode == cy_as_device_dack_ack)
+ v |= CY_AS_MEM_P0_VM_SET_DACKEOB ;
+ if (config_p->drqpol)
+ v |= CY_AS_MEM_P0_VM_SET_DRQPOL ;
+ if (config_p->dackpol)
+ v |= CY_AS_MEM_P0_VM_SET_DACKPOL ;
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_VM_SET, v) ;
+
+ if (config_p->crystal)
+ cy_as_device_set_crystal(dev_p) ;
+ else
+ cy_as_device_set_external_clock(dev_p) ;
+
+ /* Register a callback to handle MISC requests from the firmware */
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_GENERAL_RQT_CONTEXT, my_misc_callback) ;
+
+ /* Now mark the DMA and low level modules as active. */
+ cy_as_device_set_dma_running(dev_p) ;
+ cy_as_device_set_low_level_running(dev_p) ;
+
+ /* Now, initialize the interrupt module */
+ dev_p->use_int_drq = config_p->dmaintr ;
+ ret = cy_as_intr_start(dev_p, config_p->dmaintr) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Mark the interface as initialized */
+ cy_as_device_set_configured(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+my_dma_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep,
+ void *mem_p,
+ uint32_t size,
+ cy_as_return_status_t ret
+ )
+{
+ cy_as_dma_end_point *ep_p ;
+
+ (void)size ;
+
+ /* Get the endpoint pointer based on the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, ep) ;
+
+ /* Check the queue to see if is drained */
+ if (ep_p->queue_p == 0) {
+ cy_as_func_c_b_node *node =
+ (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p ;
+
+ cy_as_hal_assert(node) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ /*
+ * disable endpoint 2. the storage module
+ * will enable this EP if necessary.
+ */
+ cy_as_dma_enable_end_point(dev_p,
+ CY_AS_FIRMWARE_ENDPOINT,
+ cy_false, cy_as_direction_in) ;
+
+ /*
+ * clear the reset register. this releases the
+ * antioch micro-controller from reset and begins
+ * running the code at address zero.
+ */
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG, 0x00) ;
+ }
+
+ /* Call the user Callback */
+ node->cb_p((cy_as_device_handle)dev_p, ret, node->client_data,
+ node->data_type, node->data) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_misc) ;
+ } else {
+ /* This is the header data that was allocated in the
+ * download firmware function, and can be safely freed
+ * here. */
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(mem_p) ;
+ cy_as_hal_enable_interrupts(state) ;
+ }
+}
+
+cy_as_return_status_t
+cy_as_misc_download_firmware(cy_as_device_handle handle,
+ const void *mem_p,
+ uint16_t size,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ uint8_t *header ;
+ cy_as_return_status_t ret ;
+ cy_bool standby ;
+ cy_as_device *dev_p ;
+ cy_as_dma_callback dmacb = 0 ;
+ uint32_t state ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_download_firmware called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * if the device has not been initialized, we cannot download firmware
+ * to the device.
+ */
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ /*
+ * make sure west bridge is not in standby
+ */
+ ret = cy_as_misc_in_standby(dev_p, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (standby)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /*
+ * make sure we are in configuration mode
+ */
+ if ((cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_VM_SET) &
+ CY_AS_MEM_P0_VM_SET_CFGMODE) == 0)
+ return CY_AS_ERROR_NOT_IN_CONFIG_MODE ;
+
+ /* Maximum firmware size is 24k */
+ if (size > CY_AS_MAXIMUM_FIRMWARE_SIZE)
+ return CY_AS_ERROR_INVALID_SIZE ;
+
+ /* Make sure the size is an even number of bytes as well */
+ if (size & 0x01)
+ return CY_AS_ERROR_ALIGNMENT_ERROR ;
+
+ /*
+ * write the two word header that gives the base address and
+ * size of the firmware image to download
+ */
+ state = cy_as_hal_disable_interrupts() ;
+ header = (uint8_t *)cy_as_hal_c_b_alloc(4) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (header == NULL)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ header[0] = 0x00 ;
+ header[1] = 0x00 ;
+ header[2] = (uint8_t)(size & 0xff) ;
+ header[3] = (uint8_t)((size >> 8) & 0xff) ;
+
+ /* Enable the firmware endpoint */
+ ret = cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT,
+ cy_true, cy_as_direction_in) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * setup DMA for 64 byte packets. this is the requirement for downloading
+ * firmware to west bridge.
+ */
+ cy_as_dma_set_max_dma_size(dev_p, CY_AS_FIRMWARE_ENDPOINT, 64) ;
+
+ if (cb)
+ dmacb = my_dma_callback ;
+
+ ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT, header,
+ 4, cy_false, cy_false, dmacb) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * write the firmware image to the west bridge device
+ */
+ ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT,
+ (void *)mem_p, size, cy_false, cy_false, dmacb) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cb) {
+ cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data(
+ cb, client, CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE, 0) ;
+
+ if (cbnode == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ else
+ cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode) ;
+
+ ret = cy_as_dma_kick_start(dev_p, CY_AS_FIRMWARE_ENDPOINT) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ } else {
+ ret = cy_as_dma_drain_queue(dev_p,
+ CY_AS_FIRMWARE_ENDPOINT, cy_true) ;
+
+ /* Free the header memory that was allocated earlier. */
+ cy_as_hal_c_b_free(header) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * disable EP 2. the storage module will
+ * enable this EP if necessary.
+ */
+ cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT,
+ cy_false, cy_as_direction_in) ;
+
+ /*
+ * clear the reset register. this releases the west bridge
+ * micro-controller from reset and begins running the code at
+ * address zero.
+ */
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG, 0x00) ;
+ }
+
+ /*
+ * the firmware is not marked as loaded until the firmware
+ * initializes west bridge and a request is sent from west bridge
+ * to the P port processor indicating that west bridge is ready.
+ */
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+
+static cy_as_return_status_t
+my_handle_response_get_firmware_version(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_get_firmware_version_data *data_p)
+{
+
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t val ;
+
+ if (cy_as_ll_request_response__get_code(reply_p)
+ != CY_RESP_FIRMWARE_VERSION) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ data_p->major = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ data_p->minor = cy_as_ll_request_response__get_word(reply_p, 1) ;
+ data_p->build = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ val = cy_as_ll_request_response__get_word(reply_p, 3) ;
+ data_p->media_type = (uint8_t)(((val >> 8) & 0xFF) | (val & 0xFF)) ;
+ val = cy_as_ll_request_response__get_word(reply_p, 4) ;
+ data_p->is_debug_mode = (cy_bool)(val & 0xFF) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_get_firmware_version(cy_as_device_handle handle,
+ cy_as_get_firmware_version_data *data,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_bool standby ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ cy_as_device *dev_p ;
+
+ (void)client ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_get_firmware_version called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /*
+ * make sure antioch is not in standby
+ */
+ ret = cy_as_misc_in_standby(dev_p, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ if (standby)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ /* Make sure the Antioch is not in suspend mode. */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_FIRMWARE_VERSION,
+ CY_RQT_GENERAL_RQT_CONTEXT, 0) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*
+ * Reserve space for the reply, the reply data
+ * will not exceed three words
+ */
+ reply_p = cy_as_ll_create_response(dev_p, 5) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* Request and response are freed in
+ * MyHandleResponseGetFirmwareVersion. */
+ ret = my_handle_response_get_firmware_version(dev_p,
+ req_p, reply_p, data) ;
+ return ret ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_GETFIRMWAREVERSION, data,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+static cy_as_return_status_t
+my_handle_response_read_m_c_u_register(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ uint8_t *data_p)
+{
+
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p)
+ != CY_RESP_MCU_REGISTER_DATA) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ *data_p = (uint8_t)
+ (cy_as_ll_request_response__get_word(reply_p, 0)) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_get_gpio_value(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ uint8_t *data_p)
+{
+
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p)
+ != CY_RESP_GPIO_STATE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ } else
+ *data_p = (uint8_t)
+ (cy_as_ll_request_response__get_word(reply_p, 0)) ;
+
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+
+cy_as_return_status_t cy_as_misc_set_sd_power_polarity(
+ cy_as_device_handle handle,
+ cy_as_misc_signal_polarity polarity,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDPOLARITY,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)polarity) ;
+
+ /*
+ * Reserve space for the reply, the reply data will
+ * not exceed one word
+ */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return (my_handle_response_no_data(dev_p, req_p, reply_p)) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_SETSDPOLARITY, 0, dev_p->func_cbs_misc,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the FuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_misc_read_m_c_u_register(cy_as_device_handle handle,
+ uint16_t address,
+ uint8_t *value,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_read_m_c_u_register called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /* Check whether the firmware supports this command. */
+ if (cy_as_device_is_nand_storage_supported(dev_p))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ /* Make sure the Antioch is not in suspend mode. */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_READ_MCU_REGISTER,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_MCU_REGISTER_DATA) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ *value = (uint8_t)(cy_as_ll_request_response__get_word
+ (reply_p, 0)) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_READMCUREGISTER, value,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_misc_write_m_c_u_register(cy_as_device_handle handle,
+ uint16_t address,
+ uint8_t mask,
+ uint8_t value,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_write_m_c_u_register called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /* Check whether the firmware supports this command. */
+ if (cy_as_device_is_nand_storage_supported(dev_p))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ /* Make sure the Antioch is not in suspend mode. */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_WRITE_MCU_REGISTER,
+ CY_RQT_GENERAL_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((mask << 8) | value)) ;
+
+ /*
+ * Reserve space for the reply, the reply data
+ * will not exceed one word
+ */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_WRITEMCUREGISTER, 0,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /*
+ * The request and response are freed as part of the
+ * MiscFuncCallback
+ */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+my_handle_response_reset(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_reset_type type)
+{
+ uint16_t v ;
+
+ (void)req_p ;
+ (void)reply_p ;
+
+ /*
+ * if the device is in suspend mode, it needs to be woken up
+ * so that the write to the reset control register succeeds.
+ * we need not however wait for the wake up procedure to be
+ * complete.
+ */
+ if (cy_as_device_is_in_suspend_mode(dev_p)) {
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+ cy_as_hal_sleep(1) ;
+ }
+
+ if (type == cy_as_reset_hard) {
+ cy_as_misc_cancel_ex_requests(dev_p) ;
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG,
+ CY_AS_MEM_RST_CTRL_REG_HARD) ;
+ cy_as_device_set_unconfigured(dev_p) ;
+ cy_as_device_set_firmware_not_loaded(dev_p) ;
+ cy_as_device_set_dma_stopped(dev_p) ;
+ cy_as_device_set_low_level_stopped(dev_p) ;
+ cy_as_device_set_intr_stopped(dev_p) ;
+ cy_as_device_clear_suspend_mode(dev_p) ;
+ cy_as_usb_cleanup(dev_p) ;
+ cy_as_storage_cleanup(dev_p) ;
+
+ /*
+ * wait for a small amount of time to
+ * allow reset to be complete.
+ */
+ cy_as_hal_sleep(100) ;
+ }
+
+ cy_as_device_clear_reset_pending(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_misc_reset(cy_as_device_handle handle,
+ cy_as_reset_type type,
+ cy_bool flush,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ cy_as_end_point_number_t i ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ (void)client ;
+ (void)cb ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_reset_e_x called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /*
+ * soft reset is not supported until we close on the issues
+ * in the firmware with what needs to happen.
+ */
+ if (type == cy_as_reset_soft)
+ return CY_AS_ERROR_NOT_YET_SUPPORTED ;
+
+ cy_as_device_set_reset_pending(dev_p) ;
+
+ if (flush) {
+ /* Unable to DrainQueues in polling mode */
+ if ((dev_p->storage_cb || dev_p->storage_cb_ms) &&
+ cy_as_hal_is_polling())
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ /*
+ * shutdown the endpoints so no more traffic can be queued
+ */
+ for (i = 0; i < 15; i++)
+ cy_as_dma_enable_end_point(dev_p, i, cy_false,
+ cy_as_direction_dont_change) ;
+
+ /*
+ * if we are in normal mode, drain all traffic across all
+ * endpoints to be sure all traffic is flushed. if the
+ * device is suspended, data will not be coming in on any
+ * endpoint and all outstanding DMA operations can be
+ * cancelled.
+ */
+ if (cy_as_device_is_in_suspend_mode(dev_p)) {
+ for (i = 0; i < 15; i++)
+ cy_as_dma_cancel(dev_p, i,
+ CY_AS_ERROR_CANCELED) ;
+ } else {
+ for (i = 0; i < 15; i++) {
+ if ((i == CY_AS_P2S_WRITE_ENDPOINT) ||
+ (i == CY_AS_P2S_READ_ENDPOINT))
+ cy_as_dma_drain_queue(dev_p, i,
+ cy_false) ;
+ else
+ cy_as_dma_drain_queue(dev_p, i,
+ cy_true) ;
+ }
+ }
+ } else {
+ /* No flush was requested, so cancel any outstanding DMAs
+ * so the user callbacks are called as needed
+ */
+ if (cy_as_device_is_storage_async_pending(dev_p)) {
+ for (i = 0; i < 15; i++)
+ cy_as_dma_cancel(dev_p, i,
+ CY_AS_ERROR_CANCELED) ;
+ }
+ }
+
+ ret = my_handle_response_reset(dev_p, 0, 0, type) ;
+
+ if (cb)
+ /* Even though no mailbox communication was needed,
+ * issue the callback so the user does not need to
+ * special case their code. */
+ cb((cy_as_device_handle)dev_p, ret, client,
+ CY_FUNCT_CB_MISC_RESET, 0) ;
+
+ /*
+ * initialize any registers that may have been
+ * changed when the device was reset.
+ */
+ cy_as_hal_init_dev_registers(dev_p->tag, cy_false) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+get_unallocated_resource(cy_as_device *dev_p, cy_as_resource_type resource)
+{
+ uint8_t shift = 0 ;
+ uint16_t v ;
+ cy_as_return_status_t ret = CY_AS_ERROR_NOT_ACQUIRED ;
+
+ switch (resource) {
+ case cy_as_bus_u_s_b:
+ shift = 4 ;
+ break ;
+ case cy_as_bus_1:
+ shift = 0 ;
+ break ;
+ case cy_as_bus_0:
+ shift = 2 ;
+ break ;
+ default:
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /* Get the semaphore value for this resource */
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE) ;
+ v = (v >> shift) & 0x03 ;
+
+ if (v == 0x03) {
+ ret = CY_AS_ERROR_RESOURCE_ALREADY_OWNED ;
+ } else if ((v & 0x01) == 0) {
+ /* The resource is not owned by anyone, we can try to get it */
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)) ;
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK) ;
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_ALLOCATE, (0x01 << shift)) ;
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK) ;
+
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_ALLOCATE) ;
+ v = (v >> shift) & 0x03 ;
+ if (v == 0x03)
+ ret = CY_AS_ERROR_SUCCESS ;
+ }
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_acquire_resource(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_resource_type *resource)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ ret = get_unallocated_resource(dev_p, *resource) ;
+ if (ret != CY_AS_ERROR_NOT_ACQUIRED)
+ ret = CY_AS_ERROR_SUCCESS ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_acquire_resource(cy_as_device_handle handle,
+ cy_as_resource_type *resource,
+ cy_bool force,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret ;
+
+ cy_as_device *dev_p ;
+
+ (void)client ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_acquire_resource called") ;
+
+ if (*resource != cy_as_bus_u_s_b && *resource !=
+ cy_as_bus_0 && *resource != cy_as_bus_1)
+ return CY_AS_ERROR_INVALID_RESOURCE ;
+
+
+ /* Make sure the device is ready to accept the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+
+ ret = get_unallocated_resource(dev_p, *resource) ;
+
+ /*
+ * make sure that the callback is called if the resource is
+ * successfully acquired at this point.
+ */
+ if ((ret == CY_AS_ERROR_SUCCESS) && (cb != 0))
+ cb(handle, ret, client,
+ CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource) ;
+
+ if (ret != CY_AS_ERROR_NOT_ACQUIRED)
+ return ret ;
+
+ if (!force)
+ return CY_AS_ERROR_NOT_ACQUIRED ;
+
+ /* Create the request to acquire the resource */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_ACQUIRE_RESOURCE,
+ CY_RQT_RESOURCE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)(*resource)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource,
+ dev_p->func_cbs_res, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ ret = get_unallocated_resource(dev_p, *resource) ;
+ if (ret != CY_AS_ERROR_NOT_ACQUIRED)
+ ret = CY_AS_ERROR_SUCCESS ;
+ }
+
+ return ret ;
+}
+cy_as_return_status_t
+cy_as_misc_release_resource(cy_as_device_handle handle,
+ cy_as_resource_type resource)
+{
+ uint8_t shift = 0 ;
+ uint16_t v ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_release_resource called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (resource != cy_as_bus_u_s_b && resource !=
+ cy_as_bus_0 && resource != cy_as_bus_1)
+ return CY_AS_ERROR_INVALID_RESOURCE ;
+
+ switch (resource) {
+ case cy_as_bus_u_s_b:
+ shift = 4 ;
+ break ;
+ case cy_as_bus_1:
+ shift = 0 ;
+ break ;
+ case cy_as_bus_0:
+ shift = 2 ;
+ break ;
+ default:
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /* Get the semaphore value for this resource */
+ v = (cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_ALLOCATE) >> shift) & 0x03 ;
+ if (v == 0 || v == 1 || v == 2)
+ return CY_AS_ERROR_RESOURCE_NOT_OWNED ;
+
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)) ;
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_ALLOCATE, (0x02 << shift)) ;
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_P0_RSE_MASK, 0) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_misc_set_trace_level(cy_as_device_handle handle,
+ uint8_t level,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint32_t unit,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_set_trace_level called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (unit > 255)
+ return CY_AS_ERROR_NO_SUCH_UNIT ;
+
+ if (level >= CYAS_FW_TRACE_MAX_LEVEL)
+ return CY_AS_ERROR_INVALID_TRACE_LEVEL ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_TRACE_LEVEL,
+ CY_RQT_GENERAL_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)level) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((bus << 12) | (device << 8) | (unit))) ;
+
+ /*
+ * Reserve space for the reply, the reply data will not
+ * exceed three words
+ */
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_NOT_SUPPORTED ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_SETTRACELEVEL, 0, dev_p->func_cbs_misc,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_heart_beat_control(cy_as_device_handle handle,
+ cy_bool enable,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_heart_beat_control called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_CONTROL_ANTIOCH_HEARTBEAT,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)enable) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_HEARTBEATCONTROL, 0,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_set_sd_clock_freq(
+ cy_as_device *dev_p,
+ uint8_t card_type,
+ uint8_t setting,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ if (cy_as_device_is_in_callback(dev_p) && (cb == 0))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_SD_CLOCK_FREQ,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((card_type << 8) | setting)) ;
+
+ /* Reserve space for the reply, which will not exceed one word. */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_SETSDFREQ, 0, dev_p->func_cbs_misc,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_set_low_speed_sd_freq(
+ cy_as_device_handle handle,
+ cy_as_low_speed_sd_freq setting,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_set_low_speed_sd_freq called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if ((setting != CY_AS_SD_DEFAULT_FREQ) &&
+ (setting != CY_AS_SD_RATED_FREQ))
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ return my_set_sd_clock_freq(dev_p, 0, (uint8_t)setting, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_misc_set_high_speed_sd_freq(
+ cy_as_device_handle handle,
+ cy_as_high_speed_sd_freq setting,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_set_high_speed_sd_freq called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if ((setting != CY_AS_HS_SD_FREQ_24) &&
+ (setting != CY_AS_HS_SD_FREQ_48))
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ return my_set_sd_clock_freq(dev_p, 1, (uint8_t)setting, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_misc_get_gpio_value(cy_as_device_handle handle,
+ cy_as_misc_gpio pin,
+ uint8_t *value,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_device *dev_p ;
+ uint16_t v ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_get_gpio_value called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /* If the pin specified is UVALID, there is no need
+ * for firmware to be loaded. */
+ if (pin == cy_as_misc_gpio_U_valid) {
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE) ;
+ *value = (uint8_t)(v & CY_AS_MEM_PMU_UPDATE_UVALID) ;
+
+ if (cb != 0)
+ cb(dev_p, ret, client,
+ CY_FUNCT_CB_MISC_GETGPIOVALUE, value) ;
+
+ return ret ;
+ }
+
+ /* Check whether the firmware supports this command. */
+ if (cy_as_device_is_nand_storage_supported(dev_p))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Make sure the pin selected is valid */
+ if ((pin != cy_as_misc_gpio_1) && (pin != cy_as_misc_gpio_0))
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_GPIO_STATE,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, ((uint8_t)pin << 8)) ;
+
+ /* Reserve space for the reply, which will not exceed one word. */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_GPIO_STATE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ *value = (uint8_t)
+ cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_GETGPIOVALUE, value,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_misc_set_gpio_value(cy_as_device_handle handle,
+ cy_as_misc_gpio pin,
+ uint8_t value,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_device *dev_p ;
+ uint16_t v ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_set_gpio_value called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /* If the pin specified is UVALID, there is
+ * no need for firmware to be loaded. */
+ if (pin == cy_as_misc_gpio_U_valid) {
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE) ;
+ if (value)
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_PMU_UPDATE,
+ (v | CY_AS_MEM_PMU_UPDATE_UVALID)) ;
+ else
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_PMU_UPDATE,
+ (v & ~CY_AS_MEM_PMU_UPDATE_UVALID)) ;
+
+ if (cb != 0)
+ cb(dev_p, ret, client,
+ CY_FUNCT_CB_MISC_SETGPIOVALUE, 0) ;
+ return ret ;
+ }
+
+ /* Check whether the firmware supports this command. */
+ if (cy_as_device_is_nand_storage_supported(dev_p))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Make sure the pin selected is valid */
+ if ((pin < cy_as_misc_gpio_0) || (pin > cy_as_misc_gpio_U_valid))
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ /* Create and initialize the low level request to the firmware. */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_GPIO_STATE,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ v = (uint16_t)(((uint8_t)pin << 8) | (value > 0)) ;
+ cy_as_ll_request_response__set_word(req_p, 0, v) ;
+
+ /* Reserve space for the reply, which will not exceed one word. */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_SETGPIOVALUE, 0,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_enter_standby(cy_as_device *dev_p, cy_bool pin)
+{
+ cy_as_misc_cancel_ex_requests(dev_p) ;
+
+ /* Save the current values in the critical P-port
+ * registers, where necessary. */
+ cy_as_hal_read_regs_before_standby(dev_p->tag) ;
+
+ if (pin) {
+ if (cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false))
+ cy_as_device_set_pin_standby(dev_p) ;
+ else
+ return CY_AS_ERROR_SETTING_WAKEUP_PIN ;
+ } else {
+ /*
+ * put antioch in the standby mode
+ */
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_PWR_MAGT_STAT, 0x02) ;
+ cy_as_device_set_register_standby(dev_p) ;
+ }
+
+ /*
+ * when the antioch comes out of standby, we have to wait until
+ * the firmware initialization completes before sending other
+ * requests down.
+ */
+ cy_as_device_set_firmware_not_loaded(dev_p) ;
+
+ /*
+ * keep west bridge interrupt disabled until the device is being woken
+ * up from standby.
+ */
+ dev_p->stby_int_mask = cy_as_hal_disable_interrupts();
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static cy_as_return_status_t
+my_handle_response_enter_standby(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_bool pin)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ ret = my_enter_standby(dev_p, pin) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_enter_standby(cy_as_device_handle handle,
+ cy_bool pin,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_bool standby ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_enter_standby called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * if we already are in standby, do not do it again and let the
+ * user know via the error return.
+ */
+ ret = cy_as_misc_in_standby(handle, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (standby == cy_true)
+ return CY_AS_ERROR_ALREADY_STANDBY ;
+
+ /*
+ * if the user wants to transition from suspend mode to standby mode,
+ * the device needs to be woken up so that it can complete all pending
+ * operations.
+ */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ cy_as_misc_leave_suspend(dev_p, 0, 0) ;
+
+ if (dev_p->usb_count) {
+ /*
+ * we do not allow west bridge to go into standby mode when the
+ * USB stack is initialized. you must stop the USB stack in
+ * order to enter standby mode.
+ */
+ return CY_AS_ERROR_USB_RUNNING ;
+ }
+
+ /*
+ * if the storage stack is not running, the device can directly be
+ * put into sleep mode. otherwise, the firmware needs to be signaled
+ * to prepare for going into sleep mode.
+ */
+ if (dev_p->storage_count) {
+ /*
+ * if there are async storage operations pending,
+ * make one attempt to complete them.
+ */
+ if (cy_as_device_is_storage_async_pending(dev_p)) {
+ /* DrainQueue will not work in polling mode */
+ if (cy_as_hal_is_polling())
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ cy_as_dma_drain_queue(dev_p,
+ CY_AS_P2S_READ_ENDPOINT, cy_false) ;
+ cy_as_dma_drain_queue(dev_p,
+ CY_AS_P2S_WRITE_ENDPOINT, cy_false) ;
+
+ /*
+ * if more storage operations were queued
+ * at this stage, return an error.
+ */
+ if (cy_as_device_is_storage_async_pending(dev_p))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_PREPARE_FOR_STANDBY,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (!cb) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * in the HandleResponse */
+ return my_handle_response_enter_standby(dev_p,
+ req_p, reply_p, pin) ;
+
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_ENTERSTANDBY, (void *)pin,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else {
+ ret = my_enter_standby(dev_p, pin) ;
+ if (cb)
+ /* Even though no mailbox communication was
+ * needed, issue the callback so the user
+ * does not need to special case their code. */
+ cb((cy_as_device_handle)dev_p, ret, client,
+ CY_FUNCT_CB_MISC_ENTERSTANDBY, 0) ;
+ }
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_enter_standby_e_x_u(cy_as_device_handle handle,
+ cy_bool pin,
+ cy_bool uvalid_special,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (uvalid_special)
+ cy_as_hal_write_register(dev_p->tag, 0xc5, 0x4) ;
+
+ return cy_as_misc_enter_standby(handle, pin, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_misc_leave_standby(cy_as_device_handle handle,
+ cy_as_resource_type resource)
+{
+ cy_as_device *dev_p ;
+ uint16_t v ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t count = 8 ;
+ uint8_t retry = 1 ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_leave_standby called") ;
+ (void)resource ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (cy_as_device_is_register_standby(dev_p)) {
+ /*
+ * set a flag to indicate that the west bridge is waking
+ * up from standby.
+ */
+ cy_as_device_set_waking(dev_p) ;
+
+ /*
+ * the initial read will not succeed, but will just wake
+ * the west bridge device from standby. successive reads
+ * should succeed and in that way we know west bridge is awake.
+ */
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+
+ do {
+ /*
+ * we have initiated the operation to leave standby, now
+ * we need to wait at least N ms before trying to access
+ * the west bridge device to insure the PLLs have locked
+ * and we can talk to the device.
+ */
+ if (cy_as_device_is_crystal(dev_p))
+ cy_as_hal_sleep(
+ CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL) ;
+ else
+ cy_as_hal_sleep(
+ CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+
+ /*
+ * if the P-SPI interface mode is in use, there may be a
+ * need to re-synchronise the serial clock used for
+ * astoria access.
+ */
+ if (!is_valid_silicon_id(v)) {
+ if (cy_as_hal_sync_device_clocks(dev_p->tag) !=
+ cy_true) {
+ cy_as_hal_enable_interrupts(
+ dev_p->stby_int_mask) ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+ }
+ } while (!is_valid_silicon_id(v) && count-- > 0) ;
+
+ /*
+ * if we tried to read the register and could not,
+ * return a timeout
+ */
+ if (count == 0) {
+ cy_as_hal_enable_interrupts(
+ dev_p->stby_int_mask) ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+
+ /*
+ * the standby flag is cleared here, after the action to
+ * exit standby has been taken. the wait for firmware
+ * initialization, is ensured by marking the firmware as
+ * not loaded until the init event is received.
+ */
+ cy_as_device_clear_register_standby(dev_p) ;
+
+ /*
+ * initialize any registers that may have been changed
+ * while the device was in standby mode.
+ */
+ cy_as_hal_init_dev_registers(dev_p->tag, cy_true) ;
+ } else if (cy_as_device_is_pin_standby(dev_p)) {
+ /*
+ * set a flag to indicate that the west bridge is waking
+ * up from standby.
+ */
+ cy_as_device_set_waking(dev_p) ;
+
+try_wakeup_again:
+ /*
+ * try to set the wakeup pin, if this fails in the HAL
+ * layer, return this failure to the user.
+ */
+ if (!cy_as_hal_set_wakeup_pin(dev_p->tag, cy_true)) {
+ cy_as_hal_enable_interrupts(dev_p->stby_int_mask) ;
+ return CY_AS_ERROR_SETTING_WAKEUP_PIN ;
+ }
+
+ /*
+ * we have initiated the operation to leave standby, now
+ * we need to wait at least N ms before trying to access
+ * the west bridge device to insure the PL_ls have locked
+ * and we can talk to the device.
+ */
+ if (cy_as_device_is_crystal(dev_p))
+ cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL) ;
+ else
+ cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
+
+ /*
+ * initialize any registers that may have been changed
+ * while the device was in standby mode.
+ */
+ cy_as_hal_init_dev_registers(dev_p->tag, cy_true) ;
+
+ /*
+ * the standby flag is cleared here, after the action to
+ * exit standby has been taken. the wait for firmware
+ * initialization, is ensured by marking the firmware as
+ * not loaded until the init event is received.
+ */
+ cy_as_device_clear_pin_standby(dev_p) ;
+ } else {
+ return CY_AS_ERROR_NOT_IN_STANDBY ;
+ }
+
+ /*
+ * the west bridge interrupt can be enabled now.
+ */
+ cy_as_hal_enable_interrupts(dev_p->stby_int_mask) ;
+
+ /*
+ * release the west bridge micro-_controller from reset,
+ * so that firmware initialization can complete. the attempt
+ * to release antioch reset is made upto 8 times.
+ */
+ v = 0x03 ;
+ count = 0x08 ;
+ while ((v & 0x03) && (count)) {
+ cy_as_hal_write_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG, 0x00) ;
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_RST_CTRL_REG) ;
+ count-- ;
+ }
+
+ if (v & 0x03) {
+ cy_as_hal_print_message("failed to clear antioch reset\n") ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+
+ /*
+ * if the wake-up pin is being used, wait here to make
+ * sure that the wake-up event is received within a
+ * reasonable delay. otherwise, toggle the wake-up pin
+ * again in an attempt to start the firmware properly.
+ */
+ if (retry) {
+ count = 10 ;
+ while (count) {
+ /* If the wake-up event has been received,
+ * we can return. */
+ if (cy_as_device_is_firmware_loaded(dev_p))
+ break ;
+ /* If we are in polling mode, the interrupt may
+ * not have been serviced as yet. read the
+ * interrupt status register. if a pending mailbox
+ * interrupt is seen, we can assume that the
+ * wake-up event will be received soon. */
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_P0_INTR_REG) ;
+ if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
+ break ;
+
+ cy_as_hal_sleep(10) ;
+ count-- ;
+ }
+
+ if (!count) {
+ retry = 0 ;
+ dev_p->stby_int_mask = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false) ;
+ cy_as_hal_sleep(10) ;
+ goto try_wakeup_again ;
+ }
+ }
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_register_callback(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The function to call */
+ cy_as_misc_event_callback callback
+ )
+{
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_register_callback called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ dev_p->misc_event_cb = callback ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_misc_storage_changed(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_bool standby ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_storage_changed called") ;
+
+ /* Make sure the device is ready for the command. */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /*
+ * make sure antioch is not in standby
+ */
+ ret = cy_as_misc_in_standby(dev_p, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (standby)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ /*
+ * make sure westbridge is not in suspend mode.
+ */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_STORAGE_MEDIA_CHANGED,
+ CY_RQT_GENERAL_RQT_CONTEXT, 0) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_STORAGECHANGED, 0,
+ dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_misc_enter_suspend(
+ cy_as_device_handle handle,
+ cy_bool usb_wakeup_en,
+ cy_bool gpio_wakeup_en,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_bool standby ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ uint16_t value ;
+ uint32_t int_state ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_enter_suspend called") ;
+
+ /*
+ * basic sanity checks to ensure that the device is initialised.
+ */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /*
+ * make sure west bridge is not already in standby
+ */
+ cy_as_misc_in_standby(dev_p, &standby) ;
+ if (standby)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ /*
+ * make sure that the device is not already in suspend mode.
+ */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /*
+ * make sure there is no active USB connection.
+ */
+ if ((cy_as_device_is_usb_connected(dev_p)) && (dev_p->usb_last_event
+ != cy_as_event_usb_suspend))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ /*
+ * make sure that there are no async requests at this point in time.
+ */
+ int_state = cy_as_hal_disable_interrupts() ;
+ if ((dev_p->func_cbs_misc->count) || (dev_p->func_cbs_res->count) ||
+ (dev_p->func_cbs_stor->count) || (dev_p->func_cbs_usb->count)) {
+ cy_as_hal_enable_interrupts(int_state) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+ cy_as_hal_enable_interrupts(int_state) ;
+
+ /* Create the request to send to the Antioch device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_ENTER_SUSPEND_MODE,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply data will not
+ * exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Wakeup control flags. */
+ value = 0x0001 ;
+ if (usb_wakeup_en)
+ value |= 0x04 ;
+ if (gpio_wakeup_en)
+ value |= 0x02 ;
+ cy_as_ll_request_response__set_word(req_p, 0, value) ;
+
+ if (cb != 0) {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_ENTERSUSPEND,
+ 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p,
+ cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return CY_AS_ERROR_SUCCESS ;
+ } else {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ }
+
+destroy:
+ if (ret == CY_AS_ERROR_SUCCESS)
+ cy_as_device_set_suspend_mode(dev_p) ;
+
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_leave_suspend(
+ cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ uint16_t v, count ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_leave_suspend called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /* Make sure we are in suspend mode. */
+ if (cy_as_device_is_in_suspend_mode(dev_p)) {
+ if (cb) {
+ cy_as_func_c_b_node *cbnode =
+ cy_as_create_func_c_b_node_data(cb, client,
+ CY_FUNCT_CB_MISC_LEAVESUSPEND, 0) ;
+ if (cbnode == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode) ;
+ }
+
+ /*
+ * do a read from the ID register so that the CE assertion
+ * will wake west bridge. the read is repeated until the
+ * read comes back with valid data.
+ */
+ count = 8 ;
+
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+
+ while (!is_valid_silicon_id(v) && count-- > 0) {
+ cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
+ v = cy_as_hal_read_register(dev_p->tag,
+ CY_AS_MEM_CM_WB_CFG_ID) ;
+ }
+
+ /*
+ * if we tried to read the register and could not,
+ * return a timeout
+ */
+ if (count == 0)
+ return CY_AS_ERROR_TIMEOUT ;
+ } else
+ return CY_AS_ERROR_NOT_IN_SUSPEND ;
+
+ if (cb == 0) {
+ /*
+ * wait until the in suspend mode flag is cleared.
+ */
+ count = 20 ;
+ while ((cy_as_device_is_in_suspend_mode(dev_p))
+ && (count--)) {
+ cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK) ;
+ }
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ ret = CY_AS_ERROR_TIMEOUT ;
+ }
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_misc_reserve_l_n_a_boot_area(cy_as_device_handle handle,
+ uint8_t numzones,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_bool standby ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ cy_as_device *dev_p ;
+
+ (void)client ;
+
+ cy_as_log_debug_message(6, "cy_as_misc_switch_pnand_mode called") ;
+
+ /* Make sure we have a valid device */
+ dev_p = (cy_as_device *)handle ;
+ cy_as_check_device_ready(dev_p) ;
+
+ /*
+ * make sure antioch is not in standby
+ */
+ ret = cy_as_misc_in_standby(dev_p, &standby) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ if (standby)
+ return CY_AS_ERROR_IN_STANDBY ;
+
+ /* Make sure the Antioch is not in suspend mode. */
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_RESERVE_LNA_BOOT_AREA,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ cy_as_ll_request_response__set_word(req_p,
+ 0, (uint16_t)numzones) ;
+
+ /* Reserve space for the reply, the reply data will not
+ * exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MISC_RESERVELNABOOTAREA,
+ 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_misc_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_func_c_b_node*
+cy_as_create_func_c_b_node_data(cy_as_function_callback cb,
+ uint32_t client,
+ cy_as_funct_c_b_type type,
+ void *data)
+{
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_func_c_b_node *node = cy_as_hal_c_b_alloc(
+ sizeof(cy_as_func_c_b_node)) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (node != 0) {
+ node->node_type = CYAS_FUNC_CB ;
+ node->cb_p = cb ;
+ node->client_data = client ;
+ node->data_type = type ;
+ if (data != 0)
+ node->data_type |= CY_FUNCT_CB_DATA ;
+ else
+ node->data_type |= CY_FUNCT_CB_NODATA ;
+ node->data = data ;
+ node->next_p = 0 ;
+ }
+ return node ;
+}
+
+cy_as_func_c_b_node*
+cy_as_create_func_c_b_node(cy_as_function_callback cb,
+ uint32_t client)
+{
+ return cy_as_create_func_c_b_node_data(cb, client,
+ CY_FUNCT_CB_NODATA, 0) ;
+}
+
+void
+cy_as_destroy_func_c_b_node(cy_as_func_c_b_node *node)
+{
+ uint32_t state ;
+
+ node->node_type = CYAS_INVALID ;
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+cy_as_usb_func_c_b_node*
+cy_as_create_usb_func_c_b_node(
+ cy_as_usb_function_callback cb, uint32_t client)
+{
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_usb_func_c_b_node *node = cy_as_hal_c_b_alloc(
+ sizeof(cy_as_usb_func_c_b_node)) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (node != 0) {
+ node->type = CYAS_USB_FUNC_CB ;
+ node->cb_p = cb ;
+ node->client_data = client ;
+ node->next_p = 0 ;
+ }
+ return node ;
+}
+
+void
+cy_as_destroy_usb_func_c_b_node(cy_as_usb_func_c_b_node *node)
+{
+ uint32_t state ;
+
+ node->type = CYAS_INVALID ;
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+cy_as_usb_io_c_b_node*
+cy_as_create_usb_io_c_b_node(cy_as_usb_io_callback cb)
+{
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_usb_io_c_b_node *node = cy_as_hal_c_b_alloc(
+ sizeof(cy_as_usb_io_c_b_node)) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (node != 0) {
+ node->type = CYAS_USB_IO_CB ;
+ node->cb_p = cb ;
+ node->next_p = 0 ;
+ }
+ return node ;
+}
+
+void
+cy_as_destroy_usb_io_c_b_node(cy_as_usb_io_c_b_node *node)
+{
+ uint32_t state ;
+
+ node->type = CYAS_INVALID ;
+
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+cy_as_storage_io_c_b_node*
+cy_as_create_storage_io_c_b_node(cy_as_storage_callback cb,
+ cy_as_media_type media, uint32_t device_index,
+ uint32_t unit, uint32_t block_addr, cy_as_oper_type oper,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_storage_io_c_b_node *node = cy_as_hal_c_b_alloc(
+ sizeof(cy_as_storage_io_c_b_node)) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (node != 0) {
+ node->type = CYAS_STORAGE_IO_CB ;
+ node->cb_p = cb ;
+ node->media = media ;
+ node->device_index = device_index ;
+ node->unit = unit ;
+ node->block_addr = block_addr ;
+ node->oper = oper ;
+ node->req_p = req_p ;
+ node->reply_p = reply_p ;
+ node->next_p = 0 ;
+ }
+ return node ;
+}
+
+void
+cy_as_destroy_storage_io_c_b_node(cy_as_storage_io_c_b_node *node)
+{
+ uint32_t state ;
+ node->type = CYAS_INVALID ;
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(node) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+cy_as_c_b_queue *
+cy_as_create_c_b_queue(cy_as_c_b_node_type type)
+{
+ uint32_t state = cy_as_hal_disable_interrupts() ;
+ cy_as_c_b_queue *queue = cy_as_hal_c_b_alloc(
+ sizeof(cy_as_c_b_queue)) ;
+ cy_as_hal_enable_interrupts(state) ;
+ if (queue) {
+ queue->type = type ;
+ queue->head_p = 0 ;
+ queue->tail_p = 0 ;
+ queue->count = 0 ;
+ }
+
+ return queue ;
+}
+
+void
+cy_as_destroy_c_b_queue(cy_as_c_b_queue *queue)
+{
+ uint32_t state ;
+ queue->type = CYAS_INVALID ;
+ queue->head_p = 0 ;
+ queue->tail_p = 0 ;
+ queue->count = 0 ;
+ state = cy_as_hal_disable_interrupts() ;
+ cy_as_hal_c_b_free(queue) ;
+ cy_as_hal_enable_interrupts(state) ;
+}
+
+/* Inserts a CyAsCBNode into the queue, the
+ * node type must match the queue type*/
+void
+cy_as_insert_c_b_node(cy_as_c_b_queue *queue_p, void*cbnode)
+{
+ uint32_t int_state ;
+
+ int_state = cy_as_hal_disable_interrupts() ;
+
+ cy_as_hal_assert(queue_p != 0) ;
+
+ switch (queue_p->type) {
+ case CYAS_USB_FUNC_CB:
+ {
+ cy_as_usb_func_c_b_node *node =
+ (cy_as_usb_func_c_b_node *)cbnode ;
+ cy_as_usb_func_c_b_node *tail =
+ (cy_as_usb_func_c_b_node *)queue_p->tail_p ;
+
+ cy_as_hal_assert(node->type == CYAS_USB_FUNC_CB) ;
+ cy_as_hal_assert(tail == 0 ||
+ tail->type == CYAS_USB_FUNC_CB) ;
+ if (queue_p->head_p == 0)
+ queue_p->head_p = node ;
+ else
+ tail->next_p = node ;
+
+ queue_p->tail_p = node ;
+ }
+ break ;
+
+ case CYAS_USB_IO_CB:
+ {
+ cy_as_usb_io_c_b_node *node =
+ (cy_as_usb_io_c_b_node *)cbnode ;
+ cy_as_usb_io_c_b_node *tail =
+ (cy_as_usb_io_c_b_node *)queue_p->tail_p ;
+
+ cy_as_hal_assert(node->type == CYAS_USB_IO_CB) ;
+ cy_as_hal_assert(tail == 0 ||
+ tail->type == CYAS_USB_IO_CB) ;
+ if (queue_p->head_p == 0)
+ queue_p->head_p = node ;
+ else
+ tail->next_p = node ;
+
+ queue_p->tail_p = node ;
+ }
+ break ;
+
+ case CYAS_STORAGE_IO_CB:
+ {
+ cy_as_storage_io_c_b_node *node =
+ (cy_as_storage_io_c_b_node *)cbnode ;
+ cy_as_storage_io_c_b_node *tail =
+ (cy_as_storage_io_c_b_node *)queue_p->tail_p ;
+
+ cy_as_hal_assert(node->type == CYAS_STORAGE_IO_CB) ;
+ cy_as_hal_assert(tail == 0 ||
+ tail->type == CYAS_STORAGE_IO_CB) ;
+ if (queue_p->head_p == 0)
+ queue_p->head_p = node ;
+ else
+ tail->next_p = node ;
+
+ queue_p->tail_p = node ;
+ }
+ break ;
+
+ case CYAS_FUNC_CB:
+ {
+ cy_as_func_c_b_node *node =
+ (cy_as_func_c_b_node *)cbnode ;
+ cy_as_func_c_b_node *tail =
+ (cy_as_func_c_b_node *)queue_p->tail_p ;
+
+ cy_as_hal_assert(node->node_type == CYAS_FUNC_CB) ;
+ cy_as_hal_assert(tail == 0 ||
+ tail->node_type == CYAS_FUNC_CB) ;
+ if (queue_p->head_p == 0)
+ queue_p->head_p = node ;
+ else
+ tail->next_p = node ;
+
+ queue_p->tail_p = node ;
+ }
+ break ;
+
+ default:
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ queue_p->count++ ;
+
+ cy_as_hal_enable_interrupts(int_state) ;
+}
+
+/* Removes the tail node from the queue and frees it */
+void
+cy_as_remove_c_b_tail_node(cy_as_c_b_queue *queue_p)
+{
+ uint32_t int_state ;
+
+ int_state = cy_as_hal_disable_interrupts() ;
+
+ if (queue_p->count > 0) {
+ /*
+ * the worst case length of the queue should be
+ * under 10 elements, and the average case should
+ * be just 1 element. so, we just employ a linear
+ * search to find the node to be freed.
+ */
+ switch (queue_p->type) {
+ case CYAS_FUNC_CB:
+ {
+ cy_as_func_c_b_node *node =
+ (cy_as_func_c_b_node *)
+ queue_p->head_p ;
+ cy_as_func_c_b_node *tail =
+ (cy_as_func_c_b_node *)
+ queue_p->tail_p ;
+ if (node != tail) {
+ while (node->next_p != tail)
+ node = node->next_p ;
+ node->next_p = 0 ;
+ queue_p->tail_p = node ;
+ }
+ cy_as_destroy_func_c_b_node(tail) ;
+ }
+ break ;
+
+ case CYAS_USB_FUNC_CB:
+ {
+ cy_as_usb_func_c_b_node *node =
+ (cy_as_usb_func_c_b_node *)
+ queue_p->head_p ;
+ cy_as_usb_func_c_b_node *tail =
+ (cy_as_usb_func_c_b_node *)
+ queue_p->tail_p ;
+ if (node != tail) {
+ while (node->next_p != tail)
+ node = node->next_p ;
+ node->next_p = 0 ;
+ queue_p->tail_p = node ;
+ }
+
+ cy_as_destroy_usb_func_c_b_node(tail) ;
+ }
+ break ;
+
+ case CYAS_USB_IO_CB:
+ {
+ cy_as_usb_io_c_b_node *node =
+ (cy_as_usb_io_c_b_node *)
+ queue_p->head_p ;
+ cy_as_usb_io_c_b_node *tail =
+ (cy_as_usb_io_c_b_node *)
+ queue_p->tail_p ;
+ if (node != tail) {
+ while (node->next_p != tail)
+ node = node->next_p ;
+ node->next_p = 0 ;
+ queue_p->tail_p = node ;
+ }
+ cy_as_destroy_usb_io_c_b_node(tail) ;
+ }
+ break ;
+
+ case CYAS_STORAGE_IO_CB:
+ {
+ cy_as_storage_io_c_b_node *node =
+ (cy_as_storage_io_c_b_node *)
+ queue_p->head_p ;
+ cy_as_storage_io_c_b_node *tail =
+ (cy_as_storage_io_c_b_node *)
+ queue_p->tail_p ;
+ if (node != tail) {
+ while (node->next_p != tail)
+ node = node->next_p ;
+ node->next_p = 0 ;
+ queue_p->tail_p = node ;
+ }
+ cy_as_destroy_storage_io_c_b_node(tail) ;
+ }
+ break ;
+
+ default:
+ cy_as_hal_assert(cy_false) ;
+ }
+
+ queue_p->count-- ;
+ if (queue_p->count == 0) {
+ queue_p->head_p = 0 ;
+ queue_p->tail_p = 0 ;
+ }
+ }
+
+ cy_as_hal_enable_interrupts(int_state) ;
+}
+
+/* Removes the first CyAsCBNode from the queue and frees it */
+void
+cy_as_remove_c_b_node(cy_as_c_b_queue *queue_p)
+{
+ uint32_t int_state ;
+
+ int_state = cy_as_hal_disable_interrupts() ;
+
+ cy_as_hal_assert(queue_p->count >= 0) ;
+ if (queue_p->count > 0) {
+ if (queue_p->type == CYAS_USB_FUNC_CB) {
+ cy_as_usb_func_c_b_node *node =
+ (cy_as_usb_func_c_b_node *)
+ queue_p->head_p ;
+ queue_p->head_p = node->next_p ;
+ cy_as_destroy_usb_func_c_b_node(node) ;
+ } else if (queue_p->type == CYAS_USB_IO_CB) {
+ cy_as_usb_io_c_b_node *node =
+ (cy_as_usb_io_c_b_node *)
+ queue_p->head_p ;
+ queue_p->head_p = node->next_p ;
+ cy_as_destroy_usb_io_c_b_node(node) ;
+ } else if (queue_p->type == CYAS_STORAGE_IO_CB) {
+ cy_as_storage_io_c_b_node *node =
+ (cy_as_storage_io_c_b_node *)
+ queue_p->head_p ;
+ queue_p->head_p = node->next_p ;
+ cy_as_destroy_storage_io_c_b_node(node) ;
+ } else if (queue_p->type == CYAS_FUNC_CB) {
+ cy_as_func_c_b_node *node =
+ (cy_as_func_c_b_node *)
+ queue_p->head_p ;
+ queue_p->head_p = node->next_p ;
+ cy_as_destroy_func_c_b_node(node) ;
+ } else {
+ cy_as_hal_assert(cy_false) ;
+ }
+
+ queue_p->count-- ;
+ if (queue_p->count == 0) {
+ queue_p->head_p = 0 ;
+ queue_p->tail_p = 0 ;
+ }
+ }
+
+ cy_as_hal_enable_interrupts(int_state) ;
+}
+
+void my_print_func_c_b_node(cy_as_func_c_b_node *node)
+{
+ cy_as_funct_c_b_type type =
+ cy_as_funct_c_b_type_get_type(node->data_type) ;
+ cy_as_hal_print_message("[cd:%2u dt:%2u cb:0x%08x "
+ "d:0x%08x nt:%1i]", node->client_data, type,
+ (uint32_t)node->cb_p, (uint32_t)node->data,
+ node->node_type) ;
+}
+
+void my_print_c_b_queue(cy_as_c_b_queue *queue_p)
+{
+ uint32_t i = 0 ;
+
+ cy_as_hal_print_message("| count: %u type: ", queue_p->count) ;
+
+ if (queue_p->type == CYAS_USB_FUNC_CB) {
+ cy_as_hal_print_message("USB_FUNC_CB\n") ;
+ } else if (queue_p->type == CYAS_USB_IO_CB) {
+ cy_as_hal_print_message("USB_IO_CB\n") ;
+ } else if (queue_p->type == CYAS_STORAGE_IO_CB) {
+ cy_as_hal_print_message("STORAGE_IO_CB\n") ;
+ } else if (queue_p->type == CYAS_FUNC_CB) {
+ cy_as_func_c_b_node *node = queue_p->head_p ;
+ cy_as_hal_print_message("FUNC_CB\n") ;
+ if (queue_p->count > 0) {
+ cy_as_hal_print_message("| head->") ;
+
+ for (i = 0; i < queue_p->count; i++) {
+ if (node) {
+ cy_as_hal_print_message("->") ;
+ my_print_func_c_b_node(node) ;
+ node = node->next_p ;
+ } else
+ cy_as_hal_print_message("->[NULL]\n") ;
+ }
+
+ cy_as_hal_print_message("\n| tail->") ;
+ my_print_func_c_b_node(queue_p->tail_p) ;
+ cy_as_hal_print_message("\n") ;
+ }
+ } else {
+ cy_as_hal_print_message("INVALID\n") ;
+ }
+
+ cy_as_hal_print_message("|----------\n") ;
+}
+
+
+/* Removes and frees all pending callbacks */
+void
+cy_as_clear_c_b_queue(cy_as_c_b_queue *queue_p)
+{
+ uint32_t int_state = cy_as_hal_disable_interrupts() ;
+
+ while (queue_p->count != 0)
+ cy_as_remove_c_b_node(queue_p) ;
+
+ cy_as_hal_enable_interrupts(int_state) ;
+}
+
+cy_as_return_status_t
+cy_as_misc_send_request(cy_as_device *dev_p,
+ cy_as_function_callback cb,
+ uint32_t client,
+ cy_as_funct_c_b_type type,
+ void *data,
+ cy_as_c_b_queue *queue,
+ uint16_t req_type,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_response_callback rcb)
+{
+
+ cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data(cb,
+ client, type, data) ;
+ cy_as_return_status_t ret ;
+
+ if (cbnode == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ else
+ cy_as_insert_c_b_node(queue, cbnode) ;
+
+ req_p->flags |= req_type ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_false, rcb) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_remove_c_b_tail_node(queue) ;
+
+ return ret ;
+}
+
+void
+cy_as_misc_cancel_ex_requests(cy_as_device *dev_p)
+{
+ int i ;
+ for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++)
+ cy_as_ll_remove_all_requests(dev_p, dev_p->context[i]) ;
+}
+
+
+static void
+cy_as_misc_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ cy_as_func_c_b_node *node = NULL ;
+ cy_as_return_status_t ret ;
+
+ cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX)
+ == CY_AS_REQUEST_RESPONSE_EX ;
+ cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS)
+ == CY_AS_REQUEST_RESPONSE_MS ;
+ uint8_t code ;
+ uint32_t type ;
+ uint8_t cntxt ;
+
+ cy_as_hal_assert(ex_request || ms_request) ;
+ (void) ex_request;
+ (void) ms_request;
+ (void)context ;
+
+ cntxt = cy_as_ll_request_response__get_context(rqt) ;
+ code = cy_as_ll_request_response__get_code(rqt) ;
+
+ switch (cntxt) {
+ case CY_RQT_GENERAL_RQT_CONTEXT:
+ cy_as_hal_assert(dev_p->func_cbs_misc->count != 0) ;
+ cy_as_hal_assert(dev_p->func_cbs_misc->type == CYAS_FUNC_CB) ;
+ node = (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p ;
+ type = cy_as_funct_c_b_type_get_type(node->data_type) ;
+
+ switch (code) {
+ case CY_RQT_GET_FIRMWARE_VERSION:
+ cy_as_hal_assert(node->data != 0) ;
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_GETFIRMWAREVERSION) ;
+ ret = my_handle_response_get_firmware_version(dev_p,
+ rqt, resp,
+ (cy_as_get_firmware_version_data *)node->data);
+ break ;
+ case CY_RQT_READ_MCU_REGISTER:
+ cy_as_hal_assert(node->data != 0) ;
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_READMCUREGISTER) ;
+ ret = my_handle_response_read_m_c_u_register(dev_p, rqt,
+ resp, (uint8_t *)node->data) ;
+ break ;
+ case CY_RQT_GET_GPIO_STATE:
+ cy_as_hal_assert(node->data != 0) ;
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_GETGPIOVALUE) ;
+ ret = my_handle_response_get_gpio_value(dev_p, rqt,
+ resp, (uint8_t *)node->data) ;
+ break ;
+ case CY_RQT_SET_SD_CLOCK_FREQ:
+ cy_as_hal_assert(type == CY_FUNCT_CB_MISC_SETSDFREQ) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_CONTROL_ANTIOCH_HEARTBEAT:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_HEARTBEATCONTROL) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_WRITE_MCU_REGISTER:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_WRITEMCUREGISTER) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_STORAGE_MEDIA_CHANGED:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_STORAGECHANGED) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_SET_GPIO_STATE:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_SETGPIOVALUE) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_SET_TRACE_LEVEL:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_SETTRACELEVEL) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ if (ret == CY_AS_ERROR_INVALID_RESPONSE)
+ ret = CY_AS_ERROR_NOT_SUPPORTED ;
+ break ;
+ case CY_RQT_PREPARE_FOR_STANDBY:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_ENTERSTANDBY) ;
+ ret = my_handle_response_enter_standby(dev_p, rqt, resp,
+ (cy_bool)node->data) ;
+ break ;
+ case CY_RQT_ENTER_SUSPEND_MODE:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_ENTERSUSPEND) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ cy_as_device_set_suspend_mode(dev_p) ;
+
+ break ;
+ case CY_RQT_RESERVE_LNA_BOOT_AREA:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_RESERVELNABOOTAREA) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_SDPOLARITY:
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_SETSDPOLARITY) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+ break ;
+
+ case CY_RQT_RESOURCE_RQT_CONTEXT:
+ cy_as_hal_assert(dev_p->func_cbs_res->count != 0) ;
+ cy_as_hal_assert(dev_p->func_cbs_res->type == CYAS_FUNC_CB) ;
+ node = (cy_as_func_c_b_node *)dev_p->func_cbs_res->head_p ;
+ type = cy_as_funct_c_b_type_get_type(node->data_type) ;
+
+ switch (code) {
+ case CY_RQT_ACQUIRE_RESOURCE:
+ /* The node->data field is actually an enum value
+ * which could be 0, thus no assert is done */
+ cy_as_hal_assert(type ==
+ CY_FUNCT_CB_MISC_ACQUIRERESOURCE) ;
+ ret = my_handle_response_acquire_resource(dev_p, rqt,
+ resp, (cy_as_resource_type *)node->data) ;
+ break ;
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+ break ;
+
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /*
+ * if the low level layer returns a direct error, use the
+ * corresponding error code. if not, use the error code
+ * based on the response from firmware.
+ */
+ if (stat == CY_AS_ERROR_SUCCESS)
+ stat = ret ;
+
+ /* Call the user Callback */
+ node->cb_p((cy_as_device_handle)dev_p, stat, node->client_data,
+ node->data_type, node->data) ;
+ if (cntxt == CY_RQT_GENERAL_RQT_CONTEXT)
+ cy_as_remove_c_b_node(dev_p->func_cbs_misc) ;
+ else
+ cy_as_remove_c_b_node(dev_p->func_cbs_res) ;
+
+}
+
+
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c
new file mode 100644
index 000000000000..3725800aa7be
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c
@@ -0,0 +1,1128 @@
+/* Cypress West Bridge API header file (cyasmtp.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasmtp.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+
+static void
+cy_as_mtp_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat) ;
+
+static cy_as_return_status_t
+is_mtp_active(cy_as_device *dev_p)
+{
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->mtp_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+my_mtp_request_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *resp_p,
+ cy_as_return_status_t ret)
+{
+ uint16_t val, ev, status ;
+ uint16_t mtp_datalen = 0 ;
+ uint32_t bytecount_l, bytecount_h ;
+ cy_as_mtp_send_object_complete_data send_obj_data ;
+ cy_as_mtp_get_object_complete_data get_obj_data ;
+ cy_as_dma_end_point *ep_p ;
+
+ uint8_t code = cy_as_ll_request_response__get_code(req_p) ;
+
+ (void)resp_p ;
+ (void)context ;
+ (void)ret ;
+
+ switch (code) {
+ case CY_RQT_MTP_EVENT:
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ /* MSB indicates status of read/write */
+ status = (val >> 8) & 0xFF ;
+ /* event type */
+ ev = val & 0xFF ;
+ switch (ev) {
+ case 0: /* SendObject Complete */
+ {
+ bytecount_l =
+ cy_as_ll_request_response__get_word
+ (req_p, 1) ;
+ bytecount_h =
+ cy_as_ll_request_response__get_word
+ (req_p, 2) ;
+ send_obj_data.byte_count =
+ (bytecount_h << 16) | bytecount_l ;
+
+ send_obj_data.status = status ;
+
+ /* use the byte count again */
+ bytecount_l =
+ cy_as_ll_request_response__get_word
+ (req_p, 3) ;
+ bytecount_h =
+ cy_as_ll_request_response__get_word
+ (req_p, 4) ;
+ send_obj_data.transaction_id =
+ (bytecount_h << 16) | bytecount_l ;
+
+ dev_p->mtp_turbo_active = cy_false ;
+
+ if (dev_p->mtp_event_cb)
+ dev_p->mtp_event_cb(
+ (cy_as_device_handle) dev_p,
+ cy_as_mtp_send_object_complete,
+ &send_obj_data) ;
+ }
+ break ;
+
+ case 1: /* GetObject Complete */
+ {
+ bytecount_l =
+ cy_as_ll_request_response__get_word
+ (req_p, 1) ;
+ bytecount_h =
+ cy_as_ll_request_response__get_word
+ (req_p, 2) ;
+
+ get_obj_data.byte_count =
+ (bytecount_h << 16) | bytecount_l ;
+
+ get_obj_data.status = status ;
+
+ dev_p->mtp_turbo_active = cy_false ;
+
+ if (dev_p->mtp_event_cb)
+ dev_p->mtp_event_cb(
+ (cy_as_device_handle) dev_p,
+ cy_as_mtp_get_object_complete,
+ &get_obj_data);
+ }
+ break ;
+
+ case 2: /* BlockTable Needed */
+ {
+ if (dev_p->mtp_event_cb)
+ dev_p->mtp_event_cb(
+ (cy_as_device_handle) dev_p,
+ cy_as_mtp_block_table_needed, 0);
+ }
+ break ;
+ default:
+ cy_as_hal_print_message("invalid event type\n") ;
+ cy_as_ll_send_data_response(dev_p,
+ CY_RQT_TUR_RQT_CONTEXT,
+ CY_RESP_MTP_INVALID_EVENT,
+ sizeof(ev), &ev) ;
+ break ;
+ }
+ break ;
+
+ case CY_RQT_TURBO_CMD_FROM_HOST:
+ {
+ mtp_datalen =
+ cy_as_ll_request_response__get_word(req_p, 1) ;
+
+ /* Get the endpoint pointer based on
+ * the endpoint number */
+ ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_READ_ENDPOINT) ;
+
+ /* The event should arrive only after the DMA operation
+ * has been queued. */
+ cy_as_hal_assert(ep_p->queue_p != 0) ;
+
+ /* Put the len in ep data information in
+ * dmaqueue and kick start the queue */
+ cy_as_hal_assert(ep_p->queue_p->size >= mtp_datalen) ;
+
+ if (mtp_datalen == 0) {
+ cy_as_dma_completed_callback(dev_p->tag,
+ CY_AS_MTP_READ_ENDPOINT, 0,
+ CY_AS_ERROR_SUCCESS) ;
+ } else {
+ ep_p->maxhwdata = mtp_datalen ;
+
+ /*
+ * make sure that the DMA status for this
+ * EP is not running, so that the call to
+ * cy_as_dma_kick_start gets this transfer
+ * going. note: in MTP mode, we never leave
+ * a DMA transfer of greater than one packet
+ * running. so, it is okay to override the
+ * status here and start the next packet
+ * transfer.
+ */
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+
+ /* Kick start the queue if it is not running */
+ cy_as_dma_kick_start(dev_p,
+ CY_AS_MTP_READ_ENDPOINT);
+ }
+ }
+ break ;
+
+ case CY_RQT_TURBO_START_WRITE_DMA:
+ {
+ /*
+ * now that the firmware is ready to receive the
+ * next packet of data, start the corresponding
+ * DMA transfer. first, ensure that a DMA
+ * operation is still pending in the queue for the
+ * write endpoint.
+ */
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_TUR_RQT_CONTEXT,
+ CY_AS_ERROR_SUCCESS, 0) ;
+
+ ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ;
+ cy_as_hal_assert(ep_p->queue_p != 0) ;
+
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+ cy_as_dma_kick_start(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ;
+ }
+ break ;
+
+ default:
+ cy_as_hal_print_message("invalid request received "
+ "on TUR context\n") ;
+ val = req_p->box0 ;
+ cy_as_ll_send_data_response(dev_p, CY_RQT_TUR_RQT_CONTEXT,
+ CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
+ break ;
+ }
+}
+
+static cy_as_return_status_t
+my_handle_response_no_data(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_mtp_start(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ dev_p->mtp_count++ ;
+
+ cy_as_dma_enable_end_point(dev_p, CY_AS_MTP_READ_ENDPOINT,
+ cy_true, cy_as_direction_out) ;
+ dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].enabled = cy_true ;
+ dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].dir = cy_as_usb_out ;
+ dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].type = cy_as_usb_bulk ;
+
+ cy_as_dma_enable_end_point(dev_p, CY_AS_MTP_WRITE_ENDPOINT,
+ cy_true, cy_as_direction_in) ;
+ dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].enabled = cy_true ;
+ dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].dir = cy_as_usb_in ;
+ dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].type = cy_as_usb_bulk ;
+
+ /* Packet size is 512 bytes */
+ cy_as_dma_set_max_dma_size(dev_p, 0x02, 0x0200) ;
+ /* Packet size is 64 bytes until a switch to high speed happens.*/
+ cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x40) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_TUR_RQT_CONTEXT, 0) ;
+
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_mtp_start(cy_as_device_handle handle,
+ cy_as_mtp_event_callback event_c_b,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (cy_as_device_is_m_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ if (dev_p->storage_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (dev_p->usb_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (dev_p->is_mtp_firmware == 0)
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ cy_as_device_set_m_s_s_pending(dev_p) ;
+
+ if (dev_p->mtp_count == 0) {
+
+ dev_p->mtp_event_cb = event_c_b ;
+ /*
+ * we register here becuase the start request may cause
+ * events to occur before the response to the start request.
+ */
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_TUR_RQT_CONTEXT, my_mtp_request_callback) ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_START_MTP, CY_RQT_TUR_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_mtp_start(dev_p, req_p,
+ reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_START, 0, dev_p->func_cbs_mtp,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else {
+ dev_p->mtp_count++ ;
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_MTP_START, 0) ;
+ }
+
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_mtp_stop(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /*
+ * we sucessfully shutdown the stack, so decrement
+ * to make the count zero.
+ */
+ dev_p->mtp_count-- ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_TUR_RQT_CONTEXT, 0) ;
+
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_stop(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p = 0, *reply_p = 0 ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_mtp_stop called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_mtp_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (cy_as_device_is_m_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ cy_as_device_set_m_s_s_pending(dev_p) ;
+
+ if (dev_p->mtp_count == 1) {
+ /* Create the request to send to the West
+ * Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_STOP_MTP,
+ CY_RQT_TUR_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_mtp_stop(dev_p, req_p,
+ reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_STOP, 0, dev_p->func_cbs_mtp,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else if (dev_p->mtp_count > 1) {
+
+ dev_p->mtp_count-- ;
+
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_MTP_STOP, 0) ;
+ }
+
+ cy_as_device_clear_m_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+static void
+mtp_write_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ cy_as_hal_assert(context == CY_RQT_TUR_RQT_CONTEXT) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ /* Firmware failed the request. Cancel the DMA transfer. */
+ cy_as_dma_cancel(dev_p, 0x04, CY_AS_ERROR_CANCELED) ;
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ }
+
+ cy_as_ll_destroy_response(dev_p, resp) ;
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+}
+
+static void
+async_write_request_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p, uint32_t size,
+ cy_as_return_status_t err)
+{
+ cy_as_device_handle h ;
+ cy_as_function_callback cb ;
+
+ (void)size ;
+ (void)buf_p ;
+ (void)ep ;
+
+
+ cy_as_log_debug_message(6, "async_write_request_callback called") ;
+
+ h = (cy_as_device_handle)dev_p ;
+
+ cb = dev_p->mtp_cb ;
+ dev_p->mtp_cb = 0 ;
+
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+
+ if (cb)
+ cb(h, err, dev_p->mtp_client, dev_p->mtp_op, 0) ;
+
+}
+
+static void
+sync_mtp_callback(cy_as_device *dev_p, cy_as_end_point_number_t ep,
+ void *buf_p, uint32_t size, cy_as_return_status_t err)
+{
+ (void)ep ;
+ (void)buf_p ;
+ (void)size ;
+
+ dev_p->mtp_error = err ;
+}
+
+static cy_as_return_status_t
+cy_as_mtp_operation(cy_as_device *dev_p,
+ cy_as_mtp_block_table *blk_table,
+ uint32_t num_bytes,
+ uint32_t transaction_id,
+ cy_as_function_callback cb,
+ uint32_t client,
+ uint8_t rqttype
+ )
+{
+ cy_as_ll_request_response *req_p = 0, *reply_p = 0 ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t mask = 0 ;
+ cy_as_funct_c_b_type mtp_cb_op = 0 ;
+ uint16_t size = 2 ;
+
+ if (dev_p->mtp_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (rqttype == CY_RQT_INIT_SEND_OBJECT) {
+ mtp_cb_op = CY_FUNCT_CB_MTP_INIT_SEND_OBJECT ;
+ dev_p->mtp_turbo_active = cy_true ;
+ } else if (rqttype == CY_RQT_INIT_GET_OBJECT) {
+ mtp_cb_op = CY_FUNCT_CB_MTP_INIT_GET_OBJECT ;
+ dev_p->mtp_turbo_active = cy_true ;
+ } else
+ mtp_cb_op = CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE ;
+
+ ret = is_mtp_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (CY_RQT_INIT_GET_OBJECT == rqttype)
+ size = 4 ;
+
+ /* Create the request to send to the West
+ * Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, rqttype,
+ CY_RQT_TUR_RQT_CONTEXT, size) ;
+ if (req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)(num_bytes & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((num_bytes >> 16) & 0xFFFF)) ;
+
+ /* If it is GET_OBJECT, send transaction id as well*/
+ if (CY_RQT_INIT_GET_OBJECT == rqttype) {
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(transaction_id & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 3,
+ (uint16_t)((transaction_id >> 16) & 0xFFFF)) ;
+ }
+
+ if (cb == 0) {
+ /* Queue the DMA request for block table write */
+ ret = cy_as_dma_queue_request(dev_p, 4, blk_table,
+ sizeof(cy_as_mtp_block_table), cy_false,
+ cy_false, sync_mtp_callback) ;
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, 4, CY_AS_ERROR_CANCELED) ;
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+
+ goto destroy ;
+ }
+
+ ret = cy_as_dma_drain_queue(dev_p, 4, cy_true) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = dev_p->mtp_error ;
+ goto destroy ;
+ } else {
+#if 0
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_INIT_SEND_OBJECT,
+ 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+#endif
+
+ /* Protection from interrupt driven code */
+ /* since we are using storage EP4 check if any
+ * storage activity is pending */
+ mask = cy_as_hal_disable_interrupts() ;
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait)) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+ cy_as_device_set_storage_async_pending(dev_p) ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+ dev_p->mtp_cb = cb ;
+ dev_p->mtp_client = client ;
+ dev_p->mtp_op = mtp_cb_op ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_false, mtp_write_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = cy_as_dma_queue_request(dev_p, 4, blk_table,
+ sizeof(cy_as_mtp_block_table), cy_false, cy_false,
+ async_write_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Kick start the queue if it is not running */
+ cy_as_dma_kick_start(dev_p, 4) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_init_send_object(cy_as_device_handle handle,
+ cy_as_mtp_block_table *blk_table,
+ uint32_t num_bytes,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_device *dev_p ;
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ return cy_as_mtp_operation(dev_p, blk_table, num_bytes, 0, cb,
+ client, CY_RQT_INIT_SEND_OBJECT) ;
+
+}
+
+cy_as_return_status_t
+cy_as_mtp_init_get_object(cy_as_device_handle handle,
+ cy_as_mtp_block_table *blk_table,
+ uint32_t num_bytes,
+ uint32_t transaction_id,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_device *dev_p ;
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ return cy_as_mtp_operation(dev_p, blk_table, num_bytes,
+ transaction_id, cb, client, CY_RQT_INIT_GET_OBJECT) ;
+
+}
+
+static cy_as_return_status_t
+my_handle_response_cancel_send_object(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_cancel_send_object(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p = 0, *reply_p = 0 ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (dev_p->mtp_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_CANCEL_SEND_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_cancel_send_object(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT, 0,
+ dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_cancel_get_object(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_cancel_get_object(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p = 0, *reply_p = 0 ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (dev_p->mtp_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_CANCEL_GET_OBJECT,
+ CY_RQT_TUR_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_cancel_get_object(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT, 0,
+ dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_send_block_table(cy_as_device_handle handle,
+ cy_as_mtp_block_table *blk_table,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p ;
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ return cy_as_mtp_operation(dev_p, blk_table, 0, 0, cb,
+ client, CY_RQT_SEND_BLOCK_TABLE) ;
+}
+
+static void
+cy_as_mtp_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ cy_as_func_c_b_node* node = (cy_as_func_c_b_node *)
+ dev_p->func_cbs_mtp->head_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code ;
+ cy_bool delay_callback = cy_false ;
+
+ cy_as_hal_assert(dev_p->func_cbs_mtp->count != 0) ;
+ cy_as_hal_assert(dev_p->func_cbs_mtp->type == CYAS_FUNC_CB) ;
+
+ (void)context ;
+
+ /* The Handlers are responsible for Deleting the
+ * rqt and resp when they are finished
+ */
+ code = cy_as_ll_request_response__get_code(rqt) ;
+ switch (code) {
+ case CY_RQT_START_MTP:
+ ret = my_handle_response_mtp_start(dev_p, rqt,
+ resp, stat) ;
+ break ;
+ case CY_RQT_STOP_MTP:
+ ret = my_handle_response_mtp_stop(dev_p, rqt,
+ resp, stat) ;
+ break ;
+#if 0
+ case CY_RQT_INIT_SEND_OBJECT:
+ ret = my_handle_response_init_send_object(dev_p,
+ rqt, resp, stat, cy_true) ;
+ delay_callback = cy_true ;
+ break ;
+#endif
+ case CY_RQT_CANCEL_SEND_OBJECT:
+ ret = my_handle_response_cancel_send_object(dev_p,
+ rqt, resp, stat) ;
+ break ;
+#if 0
+ case CY_RQT_INIT_GET_OBJECT:
+ ret = my_handle_response_init_get_object(dev_p,
+ rqt, resp, stat, cy_true) ;
+ delay_callback = cy_true ;
+ break ;
+#endif
+ case CY_RQT_CANCEL_GET_OBJECT:
+ ret = my_handle_response_cancel_get_object(dev_p,
+ rqt, resp, stat) ;
+ break ;
+#if 0
+ case CY_RQT_SEND_BLOCK_TABLE:
+ ret = my_handle_response_send_block_table(dev_p, rqt,
+ resp, stat, cy_true) ;
+ delay_callback = cy_true ;
+ break ;
+#endif
+ case CY_RQT_ENABLE_USB_PATH:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ dev_p->is_storage_only_mode = cy_false ;
+ break ;
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /*
+ * if the low level layer returns a direct error, use the
+ * corresponding error code. if not, use the error code
+ * based on the response from firmware.
+ */
+ if (stat == CY_AS_ERROR_SUCCESS)
+ stat = ret ;
+
+ if (!delay_callback) {
+ node->cb_p((cy_as_device_handle)dev_p, stat, node->client_data,
+ node->data_type, node->data) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_mtp) ;
+ }
+}
+
+cy_as_return_status_t
+cy_as_mtp_storage_only_start(cy_as_device_handle handle)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->storage_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ dev_p->is_storage_only_mode = cy_true ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_mtp_storage_only_stop(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->storage_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (dev_p->is_storage_only_mode == cy_false)
+ return CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_ENABLE_USB_PATH, CY_RQT_TUR_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = my_handle_response_no_data(dev_p, req_p,
+ reply_p) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ dev_p->is_storage_only_mode = cy_false ;
+ return ret ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY, 0,
+ dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_mtp_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c
new file mode 100644
index 000000000000..c7c3cda261db
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c
@@ -0,0 +1,4104 @@
+/* Cypress West Bridge API source file (cyasstorage.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+* Storage Design
+*
+* The storage module is fairly straight forward once the
+* DMA and LOWLEVEL modules have been designed. The
+* storage module simple takes requests from the user, queues
+* the associated DMA requests for action, and then sends
+* the low level requests to the West Bridge firmware.
+*
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasstorage.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasdevice.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+
+/* Map a pre-V1.2 media type to the V1.2+ bus number */
+cy_as_return_status_t
+cy_an_map_bus_from_media_type(cy_as_device *dev_p,
+ cy_as_media_type type, cy_as_bus_number_t *bus)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code = (uint8_t)(1 << type) ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+
+ if (dev_p->media_supported[0] & code) {
+ if (dev_p->media_supported[1] & code) {
+ /*
+ * this media type could be supported on multiple
+ * buses. so, report an address resolution error.
+ */
+ ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR ;
+ } else
+ *bus = 0 ;
+ } else {
+ if (dev_p->media_supported[1] & code)
+ *bus = 1 ;
+ else
+ ret = CY_AS_ERROR_NO_SUCH_MEDIA ;
+ }
+
+ return ret ;
+}
+
+static uint16_t
+create_address(cy_as_bus_number_t bus, uint32_t device, uint8_t unit)
+{
+ cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES) ;
+ cy_as_hal_assert(device < 16) ;
+
+ return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit) ;
+}
+
+cy_as_media_type
+cy_as_storage_get_media_from_address(uint16_t v)
+{
+ cy_as_media_type media = cy_as_media_max_media_value ;
+
+ switch (v & 0xFF) {
+ case 0x00:
+ break;
+ case 0x01:
+ media = cy_as_media_nand ;
+ break ;
+ case 0x02:
+ media = cy_as_media_sd_flash ;
+ break ;
+ case 0x04:
+ media = cy_as_media_mmc_flash ;
+ break ;
+ case 0x08:
+ media = cy_as_media_ce_ata ;
+ break ;
+ case 0x10:
+ media = cy_as_media_sdio ;
+ break ;
+ default:
+ cy_as_hal_assert(0) ;
+ break ;
+ }
+
+ return media ;
+}
+
+cy_as_bus_number_t
+cy_as_storage_get_bus_from_address(uint16_t v)
+{
+ cy_as_bus_number_t bus = (cy_as_bus_number_t)((v >> 12) & 0x0f) ;
+ cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES) ;
+ return bus ;
+}
+
+uint32_t
+cy_as_storage_get_device_from_address(uint16_t v)
+{
+ return (uint32_t)((v >> 8) & 0x0f) ;
+}
+
+static uint8_t
+get_unit_from_address(uint16_t v)
+{
+ return (uint8_t)(v & 0xff) ;
+}
+
+static cy_as_return_status_t
+cy_as_map_bad_addr(uint16_t val)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_INVALID_RESPONSE ;
+
+ switch (val) {
+ case 0:
+ ret = CY_AS_ERROR_NO_SUCH_BUS ;
+ break ;
+ case 1:
+ ret = CY_AS_ERROR_NO_SUCH_DEVICE ;
+ break ;
+ case 2:
+ ret = CY_AS_ERROR_NO_SUCH_UNIT ;
+ break ;
+ case 3:
+ ret = CY_AS_ERROR_INVALID_BLOCK ;
+ break ;
+ }
+
+ return ret ;
+}
+
+static void
+my_storage_request_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *resp_p,
+ cy_as_return_status_t ret)
+{
+ uint16_t val ;
+ uint16_t addr ;
+ cy_as_bus_number_t bus;
+ uint32_t device;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+ cy_as_dma_end_point *ep_p = NULL ;
+
+ (void)resp_p ;
+ (void)context ;
+ (void)ret ;
+
+ switch (cy_as_ll_request_response__get_code(req_p)) {
+ case CY_RQT_MEDIA_CHANGED:
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+
+ /* Media has either been inserted or removed */
+ addr = cy_as_ll_request_response__get_word(req_p, 0) ;
+
+ bus = cy_as_storage_get_bus_from_address(addr);
+ device = cy_as_storage_get_device_from_address(addr);
+
+ /* Clear the entry for this device to force re-query later */
+ cy_as_hal_mem_set(&(dev_p->storage_device_info[bus][device]), 0,
+ sizeof(dev_p->storage_device_info[bus][device])) ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ if (dev_p->storage_event_cb_ms) {
+ if (val == 1)
+ dev_p->storage_event_cb_ms(h, bus,
+ device, cy_as_storage_removed, 0) ;
+ else
+ dev_p->storage_event_cb_ms(h, bus,
+ device, cy_as_storage_inserted, 0) ;
+ } else if (dev_p->storage_event_cb) {
+ if (val == 1)
+ dev_p->storage_event_cb(h, bus,
+ cy_as_storage_removed, 0) ;
+ else
+ dev_p->storage_event_cb(h, bus,
+ cy_as_storage_inserted, 0) ;
+ }
+
+ break ;
+
+ case CY_RQT_ANTIOCH_CLAIM:
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ if (dev_p->storage_event_cb || dev_p->storage_event_cb_ms) {
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ if (dev_p->storage_event_cb_ms) {
+ if (val & 0x0100)
+ dev_p->storage_event_cb_ms(h, 0, 0,
+ cy_as_storage_antioch, 0) ;
+ if (val & 0x0200)
+ dev_p->storage_event_cb_ms(h, 1, 0,
+ cy_as_storage_antioch, 0) ;
+ } else {
+ if (val & 0x01)
+ dev_p->storage_event_cb(h,
+ cy_as_media_nand,
+ cy_as_storage_antioch, 0) ;
+ if (val & 0x02)
+ dev_p->storage_event_cb(h,
+ cy_as_media_sd_flash,
+ cy_as_storage_antioch, 0) ;
+ if (val & 0x04)
+ dev_p->storage_event_cb(h,
+ cy_as_media_mmc_flash,
+ cy_as_storage_antioch, 0) ;
+ if (val & 0x08)
+ dev_p->storage_event_cb(h,
+ cy_as_media_ce_ata,
+ cy_as_storage_antioch, 0) ;
+ }
+ }
+ break ;
+
+ case CY_RQT_ANTIOCH_RELEASE:
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ if (dev_p->storage_event_cb_ms) {
+ if (val & 0x0100)
+ dev_p->storage_event_cb_ms(h, 0, 0,
+ cy_as_storage_processor, 0) ;
+ if (val & 0x0200)
+ dev_p->storage_event_cb_ms(h, 1, 0,
+ cy_as_storage_processor, 0) ;
+ } else if (dev_p->storage_event_cb) {
+ if (val & 0x01)
+ dev_p->storage_event_cb(h,
+ cy_as_media_nand,
+ cy_as_storage_processor, 0) ;
+ if (val & 0x02)
+ dev_p->storage_event_cb(h,
+ cy_as_media_sd_flash,
+ cy_as_storage_processor, 0) ;
+ if (val & 0x04)
+ dev_p->storage_event_cb(h,
+ cy_as_media_mmc_flash,
+ cy_as_storage_processor, 0) ;
+ if (val & 0x08)
+ dev_p->storage_event_cb(h,
+ cy_as_media_ce_ata,
+ cy_as_storage_processor, 0) ;
+ }
+ break ;
+
+
+ case CY_RQT_SDIO_INTR:
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ if (dev_p->storage_event_cb_ms) {
+ if (val & 0x0100)
+ dev_p->storage_event_cb_ms(h, 1, 0,
+ cy_as_sdio_interrupt, 0) ;
+ else
+ dev_p->storage_event_cb_ms(h, 0, 0,
+ cy_as_sdio_interrupt, 0) ;
+
+ } else if (dev_p->storage_event_cb) {
+ dev_p->storage_event_cb(h,
+ cy_as_media_sdio, cy_as_sdio_interrupt, 0) ;
+ }
+ break;
+
+ case CY_RQT_P2S_DMA_START:
+ /* Do the DMA setup for the waiting operation. */
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ cy_as_device_set_p2s_dma_start_recvd(dev_p) ;
+ if (dev_p->storage_oper == cy_as_op_read) {
+ ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+ cy_as_dma_kick_start(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
+ } else {
+ ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
+ cy_as_dma_end_point_set_stopped(ep_p) ;
+ cy_as_dma_kick_start(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
+ }
+ break ;
+
+ default:
+ cy_as_hal_print_message("invalid request received "
+ "on storage context\n") ;
+ val = req_p->box0 ;
+ cy_as_ll_send_data_response(dev_p, CY_RQT_STORAGE_RQT_CONTEXT,
+ CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
+ break ;
+ }
+}
+
+static cy_as_return_status_t
+is_storage_active(cy_as_device *dev_p)
+{
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->storage_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+cy_as_storage_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret) ;
+
+static cy_as_return_status_t
+my_handle_response_no_data(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_storage_start(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (dev_p->storage_count > 0 && ret ==
+ CY_AS_ERROR_ALREADY_RUNNING)
+ ret = CY_AS_ERROR_SUCCESS ;
+
+ ret = cy_as_dma_enable_end_point(dev_p,
+ CY_AS_P2S_WRITE_ENDPOINT, cy_true, cy_as_direction_in) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = cy_as_dma_set_max_dma_size(dev_p,
+ CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = cy_as_dma_enable_end_point(dev_p,
+ CY_AS_P2S_READ_ENDPOINT, cy_true, cy_as_direction_out) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = cy_as_dma_set_max_dma_size(dev_p,
+ CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_STORAGE_RQT_CONTEXT, my_storage_request_callback) ;
+
+ /* Create the request/response used for storage reads and writes. */
+ dev_p->storage_rw_req_p = cy_as_ll_create_request(dev_p,
+ 0, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
+ if (dev_p->storage_rw_req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY;
+ goto destroy;
+ }
+
+ dev_p->storage_rw_resp_p = cy_as_ll_create_response(dev_p, 5) ;
+ if (dev_p->storage_rw_resp_p == 0) {
+ cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p) ;
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ /* Increment the storage count only if
+ * the above functionality succeeds.*/
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (dev_p->storage_count == 0) {
+ cy_as_hal_mem_set(dev_p->storage_device_info,
+ 0, sizeof(dev_p->storage_device_info)) ;
+ dev_p->is_storage_only_mode = cy_false ;
+ }
+
+ dev_p->storage_count++ ;
+ }
+
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_start(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (cy_as_device_is_s_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ cy_as_device_set_s_s_s_pending(dev_p) ;
+
+ if (dev_p->storage_count == 0) {
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0) {
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_storage_start(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_START, 0, dev_p->func_cbs_stor,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as
+ * part of the FuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else {
+ dev_p->storage_count++ ;
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0) ;
+ }
+
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+
+static cy_as_return_status_t
+my_handle_response_storage_stop(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p) ;
+ cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p) ;
+ dev_p->storage_count-- ;
+ }
+
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+cy_as_return_status_t
+cy_as_storage_stop(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_storage_async_pending(dev_p))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ if (cy_as_device_is_s_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ cy_as_device_set_s_s_s_pending(dev_p) ;
+
+ if (dev_p->storage_count == 1) {
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_storage_stop(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_STOP, 0, dev_p->func_cbs_stor,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else if (dev_p->storage_count > 1) {
+ dev_p->storage_count-- ;
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0) ;
+ }
+
+ cy_as_device_clear_s_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_register_callback(cy_as_device_handle handle,
+ cy_as_storage_event_callback callback)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->storage_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ dev_p->storage_event_cb = NULL ;
+ dev_p->storage_event_cb_ms = callback ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+
+
+static cy_as_return_status_t
+my_handle_response_storage_claim(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_NO_SUCH_ADDRESS) {
+ ret = cy_as_map_bad_addr(
+ cy_as_ll_request_response__get_word(reply_p, 3)) ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_MEDIA_CLAIMED_RELEASED) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* The response must be about the address I am
+ * trying to claim or the firmware is broken */
+ if ((cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(req_p, 0)) !=
+ cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 0))) ||
+ (cy_as_storage_get_device_from_address(
+ cy_as_ll_request_response__get_word(req_p, 0)) !=
+ cy_as_storage_get_device_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 0)))) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_word(reply_p, 1) != 1)
+ ret = CY_AS_ERROR_NOT_ACQUIRED ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_storage_claim(cy_as_device *dev_p,
+ void *data,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint16_t req_flags,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (dev_p->mtp_count > 0)
+ return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, create_address(bus, device, 0)) ;
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 4) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_storage_claim(dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_CLAIM, data, dev_p->func_cbs_stor,
+ req_flags, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of
+ * the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_claim(cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ return my_storage_claim(dev_p, NULL, bus, device,
+ CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
+}
+
+static cy_as_return_status_t
+my_handle_response_storage_release(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_NO_SUCH_ADDRESS) {
+ ret = cy_as_map_bad_addr(
+ cy_as_ll_request_response__get_word(reply_p, 3)) ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_MEDIA_CLAIMED_RELEASED) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* The response must be about the address I am
+ * trying to release or the firmware is broken */
+ if ((cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(req_p, 0)) !=
+ cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 0))) ||
+ (cy_as_storage_get_device_from_address(
+ cy_as_ll_request_response__get_word(req_p, 0)) !=
+ cy_as_storage_get_device_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 0)))) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+
+ if (cy_as_ll_request_response__get_word(reply_p, 1) != 0)
+ ret = CY_AS_ERROR_NOT_RELEASED ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_storage_release(cy_as_device *dev_p,
+ void *data,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint16_t req_flags,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (dev_p->mtp_count > 0)
+ return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_RELEASE_STORAGE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(
+ req_p, 0, create_address(bus, device, 0)) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 4) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_storage_release(
+ dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_RELEASE, data, dev_p->func_cbs_stor,
+ req_flags, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as
+ * part of the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_release(cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ return my_storage_release(dev_p, NULL, bus, device,
+ CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
+}
+
+static cy_as_return_status_t
+my_handle_response_storage_query_bus(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ uint32_t *count)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code = cy_as_ll_request_response__get_code(reply_p) ;
+ uint16_t v ;
+
+ if (code == CY_RESP_NO_SUCH_ADDRESS) {
+ ret = CY_AS_ERROR_NO_SUCH_BUS ;
+ goto destroy ;
+ }
+
+ if (code != CY_RESP_BUS_DESCRIPTOR) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /*
+ * verify that the response corresponds to the bus that was queried.
+ */
+ if (cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(req_p, 0)) !=
+ cy_as_storage_get_bus_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 0))) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ v = cy_as_ll_request_response__get_word(reply_p, 1) ;
+ if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
+ /*
+ * this request is only for the count of devices
+ * on the bus. there is no need to check the media type.
+ */
+ if (v)
+ *count = 1 ;
+ else
+ *count = 0 ;
+ } else {
+ /*
+ * this request is for the count of devices of a
+ * particular type. we need to check whether the media
+ * type found matches the queried type.
+ */
+ cy_as_media_type queried = (cy_as_media_type)
+ cy_as_ll_request_response__get_word(req_p, 1) ;
+ cy_as_media_type found =
+ cy_as_storage_get_media_from_address(v);
+
+ if (queried == found)
+ *count = 1 ;
+ else
+ *count = 0 ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+my_storage_query_bus(cy_as_device *dev_p,
+ cy_as_bus_number_t bus,
+ cy_as_media_type type,
+ uint16_t req_flags,
+ uint32_t *count,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_funct_c_b_type cb_type = CY_FUNCT_CB_STOR_QUERYBUS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Create the request to send to the Antioch device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, create_address(bus, 0, 0)) ;
+ cy_as_ll_request_response__set_word(req_p, 1, (uint16_t)type) ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed two words. */
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ req_p->flags |= req_flags;
+ return my_handle_response_storage_query_bus(dev_p,
+ req_p, reply_p, count) ;
+ } else {
+ if (req_flags == CY_AS_REQUEST_RESPONSE_EX)
+ cb_type = CY_FUNCT_CB_STOR_QUERYMEDIA ;
+
+ ret = cy_as_misc_send_request(dev_p, cb, client, cb_type,
+ count, dev_p->func_cbs_stor, req_flags,
+ req_p, reply_p, cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of
+ * the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_query_bus(cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t *count,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ return my_storage_query_bus(dev_p, bus, cy_as_media_max_media_value,
+ CY_AS_REQUEST_RESPONSE_MS, count, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_storage_query_media(cy_as_device_handle handle,
+ cy_as_media_type type,
+ uint32_t *count,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_bus_number_t bus ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ ret = cy_an_map_bus_from_media_type(dev_p, type, &bus) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ return my_storage_query_bus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX,
+ count, cb, client) ;
+}
+
+static cy_as_return_status_t
+my_handle_response_storage_query_device(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ void *data_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t v ;
+ cy_as_bus_number_t bus ;
+ cy_as_media_type type ;
+ uint32_t device ;
+ cy_bool removable ;
+ cy_bool writeable ;
+ cy_bool locked ;
+ uint16_t block_size ;
+ uint32_t number_units ;
+ uint32_t number_eus ;
+
+ if (cy_as_ll_request_response__get_code(reply_p)
+ == CY_RESP_NO_SUCH_ADDRESS) {
+ ret = cy_as_map_bad_addr(
+ cy_as_ll_request_response__get_word(reply_p, 3)) ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_DEVICE_DESCRIPTOR) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* Unpack the response */
+ v = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ type = cy_as_storage_get_media_from_address(v) ;
+ bus = cy_as_storage_get_bus_from_address(v) ;
+ device = cy_as_storage_get_device_from_address(v) ;
+
+ block_size = cy_as_ll_request_response__get_word(reply_p, 1) ;
+
+ v = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ removable = (v & 0x8000) ? cy_true : cy_false ;
+ writeable = (v & 0x0100) ? cy_true : cy_false ;
+ locked = (v & 0x0200) ? cy_true : cy_false ;
+ number_units = (v & 0xff) ;
+
+ number_eus = (cy_as_ll_request_response__get_word(reply_p, 3) << 16)
+ | cy_as_ll_request_response__get_word(reply_p, 4) ;
+
+ /* Store the results based on the version of originating function */
+ if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
+ cy_as_storage_query_device_data *store_p =
+ (cy_as_storage_query_device_data *)data_p ;
+
+ /* Make sure the response is about the address we asked
+ * about - if not, firmware error */
+ if ((bus != store_p->bus) || (device != store_p->device)) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ store_p->desc_p.type = type ;
+ store_p->desc_p.removable = removable ;
+ store_p->desc_p.writeable = writeable ;
+ store_p->desc_p.block_size = block_size ;
+ store_p->desc_p.number_units = number_units ;
+ store_p->desc_p.locked = locked ;
+ store_p->desc_p.erase_unit_size = number_eus ;
+ dev_p->storage_device_info[bus][device] = store_p->desc_p ;
+ } else {
+ cy_as_storage_query_device_data_dep *store_p =
+ (cy_as_storage_query_device_data_dep *)data_p ;
+
+ /* Make sure the response is about the address we asked
+ * about - if not, firmware error */
+ if ((type != store_p->type) || (device != store_p->device)) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ store_p->desc_p.type = type ;
+ store_p->desc_p.removable = removable ;
+ store_p->desc_p.writeable = writeable ;
+ store_p->desc_p.block_size = block_size ;
+ store_p->desc_p.number_units = number_units ;
+ store_p->desc_p.locked = locked ;
+ store_p->desc_p.erase_unit_size = number_eus ;
+ dev_p->storage_device_info[bus][device] = store_p->desc_p ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_storage_query_device(cy_as_device *dev_p,
+ void *data_p,
+ uint16_t req_flags,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Create the request to send to the Antioch device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, device, 0)) ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed five words. */
+ reply_p = cy_as_ll_create_response(dev_p, 5) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ req_p->flags |= req_flags;
+ return my_handle_response_storage_query_device(dev_p,
+ req_p, reply_p, data_p) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_QUERYDEVICE, data_p,
+ dev_p->func_cbs_stor, req_flags, req_p,
+ reply_p, cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_query_device(cy_as_device_handle handle,
+ cy_as_storage_query_device_data *data_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ return my_storage_query_device(dev_p, data_p,
+ CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
+ data_p->device, cb, client) ;
+}
+
+static cy_as_return_status_t
+my_handle_response_storage_query_unit(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ void *data_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_bus_number_t bus ;
+ uint32_t device ;
+ uint32_t unit ;
+ cy_as_media_type type ;
+ uint16_t block_size ;
+ uint32_t start_block ;
+ uint32_t unit_size ;
+ uint16_t v ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_NO_SUCH_ADDRESS) {
+ ret = cy_as_map_bad_addr(
+ cy_as_ll_request_response__get_word(reply_p, 3)) ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_UNIT_DESCRIPTOR) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* Unpack the response */
+ v = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ bus = cy_as_storage_get_bus_from_address(v) ;
+ device = cy_as_storage_get_device_from_address(v) ;
+ unit = get_unit_from_address(v) ;
+
+ type = cy_as_storage_get_media_from_address(
+ cy_as_ll_request_response__get_word(reply_p, 1));
+
+ block_size = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ start_block = cy_as_ll_request_response__get_word(reply_p, 3)
+ | (cy_as_ll_request_response__get_word(reply_p, 4) << 16) ;
+ unit_size = cy_as_ll_request_response__get_word(reply_p, 5)
+ | (cy_as_ll_request_response__get_word(reply_p, 6) << 16) ;
+
+ /* Store the results based on the version of
+ * originating function */
+ if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
+ cy_as_storage_query_unit_data *store_p =
+ (cy_as_storage_query_unit_data *)data_p ;
+
+ /* Make sure the response is about the address we
+ * asked about - if not, firmware error */
+ if (bus != store_p->bus || device != store_p->device ||
+ unit != store_p->unit) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ store_p->desc_p.type = type ;
+ store_p->desc_p.block_size = block_size ;
+ store_p->desc_p.start_block = start_block ;
+ store_p->desc_p.unit_size = unit_size ;
+ } else {
+ cy_as_storage_query_unit_data_dep *store_p =
+ (cy_as_storage_query_unit_data_dep *)data_p ;
+
+ /* Make sure the response is about the media type we asked
+ * about - if not, firmware error */
+ if ((type != store_p->type) || (device != store_p->device) ||
+ (unit != store_p->unit)) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ store_p->desc_p.type = type ;
+ store_p->desc_p.block_size = block_size ;
+ store_p->desc_p.start_block = start_block ;
+ store_p->desc_p.unit_size = unit_size ;
+ }
+
+ dev_p->storage_device_info[bus][device].type = type ;
+ dev_p->storage_device_info[bus][device].block_size = block_size ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_storage_query_unit(cy_as_device *dev_p,
+ void *data_p,
+ uint16_t req_flags,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint32_t unit,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ if (device > 255)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (unit > 255)
+ return CY_AS_ERROR_NO_SUCH_UNIT ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, device, (uint8_t)unit)) ;
+
+ /* Reserve space for the reply, the reply data
+ * will be of seven words. */
+ reply_p = cy_as_ll_create_response(dev_p, 7) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ req_p->flags |= req_flags ;
+ return my_handle_response_storage_query_unit(dev_p,
+ req_p, reply_p, data_p) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_QUERYUNIT, data_p,
+ dev_p->func_cbs_stor, req_flags, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_query_unit(cy_as_device_handle handle,
+ cy_as_storage_query_unit_data *data_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ return my_storage_query_unit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS,
+ data_p->bus, data_p->device, data_p->unit, cb, client) ;
+}
+
+
+static cy_as_return_status_t
+cy_as_get_block_size(cy_as_device *dev_p,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_function_callback cb)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_QUERY_DEVICE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, device, 0)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 4) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p)
+ == CY_RESP_NO_SUCH_ADDRESS) {
+ ret = CY_AS_ERROR_NO_SUCH_BUS ;
+ goto destroy ;
+ }
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_DEVICE_DESCRIPTOR) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* Make sure the response is about the media type we asked
+ * about - if not, firmware error */
+ if ((cy_as_storage_get_bus_from_address
+ (cy_as_ll_request_response__get_word(reply_p, 0))
+ != bus) || (cy_as_storage_get_device_from_address
+ (cy_as_ll_request_response__get_word(reply_p, 0))
+ != device)) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+
+ dev_p->storage_device_info[bus][device].block_size =
+ cy_as_ll_request_response__get_word(reply_p, 1) ;
+ } else
+ ret = CY_AS_ERROR_INVALID_REQUEST ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+my_storage_device_control(
+ cy_as_device *dev_p,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_bool card_detect_en,
+ cy_bool write_prot_en,
+ cy_as_storage_card_detect config_detect,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret ;
+ cy_bool use_gpio = cy_false ;
+
+ (void)device ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ /* If SD is not supported on the specified bus,
+ * then return ERROR */
+ if ((dev_p->media_supported[bus] == 0) ||
+ (dev_p->media_supported[bus] & (1<<cy_as_media_nand)))
+ return CY_AS_ERROR_NOT_SUPPORTED;
+
+ if (config_detect == cy_as_storage_detect_GPIO)
+ use_gpio = cy_true ;
+ else if (config_detect == cy_as_storage_detect_SDAT_3)
+ use_gpio = cy_false ;
+ else
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, create_address(bus, device, 0)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 1, (((uint16_t)card_detect_en << 8) |
+ ((uint16_t)use_gpio << 1) | (uint16_t)write_prot_en)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ } else {
+
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_DEVICECONTROL,
+ 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_device_control(cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_bool card_detect_en,
+ cy_bool write_prot_en,
+ cy_as_storage_card_detect config_detect,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ return my_storage_device_control(dev_p, bus, device, card_detect_en,
+ write_prot_en, config_detect, cb, client);
+}
+
+static void
+cy_as_async_storage_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p, uint32_t size,
+ cy_as_return_status_t ret)
+{
+ cy_as_storage_callback_dep cb ;
+ cy_as_storage_callback cb_ms ;
+
+ (void)size ;
+ (void)buf_p ;
+ (void)ep ;
+
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+
+ /*
+ * if the LL request callback has already been called,
+ * the user callback has to be called from here.
+ */
+ if (!dev_p->storage_wait) {
+ cy_as_hal_assert(dev_p->storage_cb != NULL ||
+ dev_p->storage_cb_ms != NULL) ;
+ cb = dev_p->storage_cb ;
+ cb_ms = dev_p->storage_cb_ms ;
+
+ dev_p->storage_cb = 0 ;
+ dev_p->storage_cb_ms = 0 ;
+
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = dev_p->storage_error ;
+
+ if (cb_ms) {
+ cb_ms((cy_as_device_handle)dev_p,
+ dev_p->storage_bus_index,
+ dev_p->storage_device_index,
+ dev_p->storage_unit,
+ dev_p->storage_block_addr,
+ dev_p->storage_oper, ret) ;
+ } else {
+ cb((cy_as_device_handle)dev_p,
+ dev_p->storage_device_info
+ [dev_p->storage_bus_index]
+ [dev_p->storage_device_index].type,
+ dev_p->storage_device_index,
+ dev_p->storage_unit,
+ dev_p->storage_block_addr,
+ dev_p->storage_oper, ret) ;
+ }
+ } else
+ dev_p->storage_error = ret ;
+}
+
+static void
+cy_as_async_storage_reply_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ cy_as_storage_callback_dep cb ;
+ cy_as_storage_callback cb_ms ;
+ uint8_t reqtype ;
+ (void)rqt ;
+ (void)context ;
+
+ reqtype = cy_as_ll_request_response__get_code(rqt) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_ANTIOCH_DEFERRED_ERROR) {
+ ret = cy_as_ll_request_response__get_word
+ (resp, 0) & 0x00FF ;
+ } else if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (reqtype == CY_RQT_READ_BLOCK)
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_read_endpoint, ret) ;
+ else
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_write_endpoint, ret) ;
+ }
+
+ dev_p->storage_wait = cy_false ;
+
+ /*
+ * if the DMA callback has already been called, the
+ * user callback has to be called from here.
+ */
+ if (!cy_as_device_is_storage_async_pending(dev_p)) {
+ cy_as_hal_assert(dev_p->storage_cb != NULL ||
+ dev_p->storage_cb_ms != NULL) ;
+ cb = dev_p->storage_cb ;
+ cb_ms = dev_p->storage_cb_ms ;
+
+ dev_p->storage_cb = 0 ;
+ dev_p->storage_cb_ms = 0 ;
+
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = dev_p->storage_error ;
+
+ if (cb_ms) {
+ cb_ms((cy_as_device_handle)dev_p,
+ dev_p->storage_bus_index,
+ dev_p->storage_device_index,
+ dev_p->storage_unit,
+ dev_p->storage_block_addr,
+ dev_p->storage_oper, ret) ;
+ } else {
+ cb((cy_as_device_handle)dev_p,
+ dev_p->storage_device_info
+ [dev_p->storage_bus_index]
+ [dev_p->storage_device_index].type,
+ dev_p->storage_device_index,
+ dev_p->storage_unit,
+ dev_p->storage_block_addr,
+ dev_p->storage_oper, ret) ;
+ }
+ } else
+ dev_p->storage_error = ret ;
+}
+
+static cy_as_return_status_t
+cy_as_storage_async_oper(cy_as_device *dev_p, cy_as_end_point_number_t ep,
+ uint8_t reqtype, uint16_t req_flags, cy_as_bus_number_t bus,
+ uint32_t device, uint32_t unit, uint32_t block, void *data_p,
+ uint16_t num_blocks, cy_as_storage_callback_dep callback,
+ cy_as_storage_callback callback_ms)
+{
+ uint32_t mask ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (unit > 255)
+ return CY_AS_ERROR_NO_SUCH_UNIT ;
+
+ /* We are supposed to return sucess if the number of
+ * blocks is zero
+ */
+ if (num_blocks == 0) {
+ if (callback_ms)
+ callback_ms((cy_as_device_handle)dev_p,
+ bus, device, unit, block,
+ ((reqtype == CY_RQT_WRITE_BLOCK)
+ ? cy_as_op_write : cy_as_op_read),
+ CY_AS_ERROR_SUCCESS) ;
+ else
+ callback((cy_as_device_handle)dev_p,
+ dev_p->storage_device_info[bus][device].type,
+ device, unit, block,
+ ((reqtype == CY_RQT_WRITE_BLOCK) ?
+ cy_as_op_write : cy_as_op_read),
+ CY_AS_ERROR_SUCCESS) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+ }
+
+ if (dev_p->storage_device_info[bus][device].block_size == 0)
+ return CY_AS_ERROR_QUERY_DEVICE_NEEDED ;
+
+ /*
+ * since async operations can be triggered by interrupt
+ * code, we must insure that we do not get multiple
+ * async operations going at one time and protect this
+ * test and set operation from interrupts. also need to
+ * check for pending async MTP writes
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait) ||
+ (cy_as_device_is_usb_async_pending(dev_p, 6))) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+
+ cy_as_device_set_storage_async_pending(dev_p) ;
+ cy_as_device_clear_p2s_dma_start_recvd(dev_p) ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+ /*
+ * storage information about the currently outstanding request
+ */
+ dev_p->storage_cb = callback ;
+ dev_p->storage_cb_ms = callback_ms ;
+ dev_p->storage_bus_index = bus ;
+ dev_p->storage_device_index = device ;
+ dev_p->storage_unit = unit ;
+ dev_p->storage_block_addr = block ;
+
+ /* Initialise the request to send to the West Bridge. */
+ req_p = dev_p->storage_rw_req_p ;
+ cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
+
+ /* Initialise the space for reply from the West Bridge. */
+ reply_p = dev_p->storage_rw_resp_p ;
+ cy_as_ll_init_response(reply_p, 5) ;
+
+ /* Remember which version of the API originated the request */
+ req_p->flags |= req_flags ;
+
+ /* Setup the DMA request and adjust the storage
+ * operation if we are reading */
+ if (reqtype == CY_RQT_READ_BLOCK) {
+ ret = cy_as_dma_queue_request(dev_p, ep, data_p,
+ dev_p->storage_device_info[bus][device].block_size
+ * num_blocks, cy_false, cy_true,
+ cy_as_async_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_read ;
+ } else if (reqtype == CY_RQT_WRITE_BLOCK) {
+ ret = cy_as_dma_queue_request(dev_p, ep, data_p,
+ dev_p->storage_device_info[bus][device].block_size *
+ num_blocks, cy_false, cy_false,
+ cy_as_async_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_write ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ return ret ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, create_address(bus, (uint8_t)device, (uint8_t)unit)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 1, (uint16_t)((block >> 16) & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 2, (uint16_t)(block & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 4, (uint16_t)((num_blocks << 8) & 0xff00)) ;
+
+ /* Set the burst mode flag. */
+ if (dev_p->is_storage_only_mode)
+ req_p->data[4] |= 0x0001;
+
+ /* Send the request and wait for completion
+ * of storage request */
+ dev_p->storage_wait = cy_true ;
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_true, cy_as_async_storage_reply_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ }
+
+ return ret ;
+}
+
+static void
+cy_as_sync_storage_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p,
+ uint32_t size, cy_as_return_status_t err)
+{
+ (void)ep ;
+ (void)buf_p ;
+ (void)size ;
+
+ dev_p->storage_error = err ;
+}
+
+static void
+cy_as_sync_storage_reply_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ uint8_t reqtype ;
+ (void)rqt ;
+
+ reqtype = cy_as_ll_request_response__get_code(rqt) ;
+
+ if (cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_ANTIOCH_DEFERRED_ERROR) {
+ ret = cy_as_ll_request_response__get_word(resp, 0) & 0x00FF ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (reqtype == CY_RQT_READ_BLOCK)
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_read_endpoint, ret) ;
+ else
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_write_endpoint, ret) ;
+ }
+ } else if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+
+ dev_p->storage_wait = cy_false ;
+ dev_p->storage_error = ret ;
+
+ /* Wake any threads/processes that are waiting on
+ * the read/write completion. */
+ cy_as_hal_wake(&dev_p->context[context]->channel) ;
+}
+
+static cy_as_return_status_t
+cy_as_storage_sync_oper(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, uint8_t reqtype,
+ cy_as_bus_number_t bus, uint32_t device,
+ uint32_t unit, uint32_t block, void *data_p,
+ uint16_t num_blocks)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_context *ctxt_p ;
+ uint32_t loopcount = 200 ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (unit > 255)
+ return CY_AS_ERROR_NO_SUCH_UNIT ;
+
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ /* Also need to check for pending Async MTP writes */
+ if (cy_as_device_is_usb_async_pending(dev_p, 6))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ /* We are supposed to return sucess if the number of
+ * blocks is zero
+ */
+ if (num_blocks == 0)
+ return CY_AS_ERROR_SUCCESS ;
+
+ if (dev_p->storage_device_info[bus][device].block_size == 0) {
+ /*
+ * normally, a given device has been queried via
+ * the query device call before a read request is issued.
+ * therefore, this normally will not be run.
+ */
+ ret = cy_as_get_block_size(dev_p, bus, device, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ /* Initialise the request to send to the West Bridge. */
+ req_p = dev_p->storage_rw_req_p ;
+ cy_as_ll_init_request(req_p, reqtype,
+ CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
+
+ /* Initialise the space for reply from
+ * the West Bridge. */
+ reply_p = dev_p->storage_rw_resp_p ;
+ cy_as_ll_init_response(reply_p, 5) ;
+ cy_as_device_clear_p2s_dma_start_recvd(dev_p) ;
+
+ /* Setup the DMA request */
+ if (reqtype == CY_RQT_READ_BLOCK) {
+ ret = cy_as_dma_queue_request(dev_p, ep, data_p,
+ dev_p->storage_device_info[bus][device].block_size *
+ num_blocks, cy_false,
+ cy_true, cy_as_sync_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_read ;
+ } else if (reqtype == CY_RQT_WRITE_BLOCK) {
+ ret = cy_as_dma_queue_request(dev_p, ep, data_p,
+ dev_p->storage_device_info[bus][device].block_size *
+ num_blocks, cy_false, cy_false,
+ cy_as_sync_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_write ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, (uint8_t)unit)) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((block >> 16) & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(block & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p, 3,
+ (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
+ cy_as_ll_request_response__set_word(req_p, 4,
+ (uint16_t)((num_blocks << 8) & 0xff00)) ;
+
+ /* Set the burst mode flag. */
+ if (dev_p->is_storage_only_mode)
+ req_p->data[4] |= 0x0001;
+
+ /* Send the request and wait for
+ * completion of storage request */
+ dev_p->storage_wait = cy_true ;
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
+ cy_as_sync_storage_reply_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ } else {
+ /* Setup the DMA request */
+ ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_false) ;
+
+ while (loopcount-- > 0) {
+ if (dev_p->storage_wait == cy_false)
+ break ;
+ cy_as_hal_sleep_on(&ctxt_p->channel, 10) ;
+ }
+
+ if (dev_p->storage_wait == cy_true) {
+ dev_p->storage_wait = cy_false ;
+ cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true) ;
+ ret = CY_AS_ERROR_TIMEOUT ;
+ }
+
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = dev_p->storage_error ;
+ }
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_read(cy_as_device_handle handle,
+ cy_as_bus_number_t bus, uint32_t device,
+ uint32_t unit, uint32_t block,
+ void *data_p, uint16_t num_blocks)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ return cy_as_storage_sync_oper(dev_p, dev_p->storage_read_endpoint,
+ CY_RQT_READ_BLOCK, bus, device,
+ unit, block, data_p, num_blocks) ;
+}
+
+cy_as_return_status_t
+cy_as_storage_write(cy_as_device_handle handle,
+ cy_as_bus_number_t bus, uint32_t device,
+ uint32_t unit, uint32_t block, void *data_p,
+ uint16_t num_blocks)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (dev_p->mtp_turbo_active)
+ return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+ return cy_as_storage_sync_oper(dev_p,
+ dev_p->storage_write_endpoint,
+ CY_RQT_WRITE_BLOCK, bus, device,
+ unit, block, data_p, num_blocks) ;
+}
+
+
+cy_as_return_status_t
+cy_as_storage_read_async(cy_as_device_handle handle,
+ cy_as_bus_number_t bus, uint32_t device, uint32_t unit,
+ uint32_t block, void *data_p, uint16_t num_blocks,
+ cy_as_storage_callback callback)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (callback == 0)
+ return CY_AS_ERROR_NULL_CALLBACK ;
+
+ return cy_as_storage_async_oper(dev_p,
+ dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK,
+ CY_AS_REQUEST_RESPONSE_MS, bus, device, unit,
+ block, data_p, num_blocks, NULL, callback);
+}
+
+cy_as_return_status_t
+cy_as_storage_write_async(cy_as_device_handle handle,
+ cy_as_bus_number_t bus, uint32_t device, uint32_t unit,
+ uint32_t block, void *data_p, uint16_t num_blocks,
+ cy_as_storage_callback callback)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (callback == 0)
+ return CY_AS_ERROR_NULL_CALLBACK ;
+
+ if (dev_p->mtp_turbo_active)
+ return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+ return cy_as_storage_async_oper(dev_p,
+ dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK,
+ CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block,
+ data_p, num_blocks, NULL, callback);
+}
+
+
+static void
+my_storage_cancel_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ (void)context ;
+ (void)stat ;
+
+ /* Nothing to do here, except free up the
+ * request and response structures. */
+ cy_as_ll_destroy_response(dev_p, resp) ;
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+}
+
+
+cy_as_return_status_t
+cy_as_storage_cancel_async(cy_as_device_handle handle)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (!cy_as_device_is_storage_async_pending(dev_p))
+ return CY_AS_ERROR_ASYNC_NOT_PENDING ;
+
+ /*
+ * create and send a mailbox request to firmware
+ * asking it to abort processing of the current
+ * P2S operation. the rest of the cancel processing will be
+ * driven through the callbacks for the read/write call.
+ */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_ABORT_P2S_XFER,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ ret = cy_as_ll_send_request(dev_p, req_p,
+ reply_p, cy_false, my_storage_cancel_callback) ;
+ if (ret) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+ * This function does all the API side clean-up associated with
+ * CyAsStorageStop, without any communication with the firmware.
+ */
+void cy_as_storage_cleanup(cy_as_device *dev_p)
+{
+ if (dev_p->storage_count) {
+ cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p) ;
+ cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p) ;
+ dev_p->storage_count = 0 ;
+ cy_as_device_clear_scsi_messages(dev_p) ;
+ cy_as_hal_mem_set(dev_p->storage_device_info,
+ 0, sizeof(dev_p->storage_device_info)) ;
+
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ dev_p->storage_cb = 0 ;
+ dev_p->storage_cb_ms = 0 ;
+ dev_p->storage_wait = cy_false ;
+ }
+}
+
+static cy_as_return_status_t
+my_handle_response_sd_reg_read(
+ cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_storage_sd_reg_read_data *info)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t resp_type, i ;
+ uint16_t resp_len ;
+ uint8_t length = info->length ;
+ uint8_t *data_p = info->buf_p ;
+
+ resp_type = cy_as_ll_request_response__get_code(reply_p) ;
+ if (resp_type == CY_RESP_SD_REGISTER_DATA) {
+ uint16_t *resp_p = reply_p->data + 1 ;
+ uint16_t temp ;
+
+ resp_len = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ cy_as_hal_assert(resp_len >= length) ;
+
+ /*
+ * copy the values into the output buffer after doing the
+ * necessary bit shifting. the bit shifting is required because
+ * the data comes out of the west bridge with a 6 bit offset.
+ */
+ i = 0 ;
+ while (length) {
+ temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10)) ;
+ i++ ;
+
+ *data_p++ = (uint8_t)(temp >> 8) ;
+ length-- ;
+
+ if (length) {
+ *data_p++ = (uint8_t)(temp & 0xFF) ;
+ length-- ;
+ }
+ }
+ } else {
+ if (resp_type == CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_sd_register_read(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint8_t device,
+ cy_as_sd_card_reg_type reg_type,
+ cy_as_storage_sd_reg_read_data *data_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t length ;
+
+ /*
+ * sanity checks required before sending the request to the
+ * firmware.
+ */
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (reg_type > cy_as_sd_reg_CSD)
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ /* If SD/MMC media is not supported on the
+ * addressed bus, return error. */
+ if ((dev_p->media_supported[bus] & (1 << cy_as_media_sd_flash)) == 0)
+ return CY_AS_ERROR_INVALID_PARAMETER ;
+
+ /*
+ * find the amount of data to be returned. this will be the minimum of
+ * the actual data length, and the length requested.
+ */
+ switch (reg_type) {
+ case cy_as_sd_reg_OCR:
+ length = CY_AS_SD_REG_OCR_LENGTH ;
+ break ;
+ case cy_as_sd_reg_CID:
+ length = CY_AS_SD_REG_CID_LENGTH ;
+ break ;
+ case cy_as_sd_reg_CSD:
+ length = CY_AS_SD_REG_CSD_LENGTH ;
+ break ;
+
+ default:
+ length = 0 ;
+ cy_as_hal_assert(0) ;
+ }
+
+ if (length < data_p->length)
+ data_p->length = length ;
+ length = data_p->length ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SD_REGISTER_READ,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (create_address(bus, device, 0) | (uint16_t)reg_type)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p,
+ CY_AS_SD_REG_MAX_RESP_LENGTH) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_sd_reg_read(dev_p,
+ req_p, reply_p, data_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_SDREGISTERREAD, data_p,
+ dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * MiscFuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_create_p_partition(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ /* of P-port only partition in blocks */
+ uint32_t size,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Partitions cannot be created or deleted while
+ * the USB stack is active. */
+ if (dev_p->usb_count)
+ return CY_AS_ERROR_USB_RUNNING ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_STORAGE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, 0x00));
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((size >> 16) & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(size & 0xffff)) ;
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_no_data(dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_PARTITION, 0, dev_p->func_cbs_stor,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * FuncCallback */
+ return ret ;
+
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_remove_p_partition(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Partitions cannot be created or deleted while
+ * the USB stack is active. */
+ if (dev_p->usb_count)
+ return CY_AS_ERROR_USB_RUNNING ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_ERASE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, create_address(bus, (uint8_t)device, 0x00));
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_no_data(dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_NODATA, 0, dev_p->func_cbs_stor,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the FuncCallback */
+ return ret ;
+
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_get_transfer_amount(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_m_s_c_progress_data *data)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code = cy_as_ll_request_response__get_code(reply_p) ;
+ uint16_t v1, v2 ;
+
+ if (code != CY_RESP_TRANSFER_COUNT) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ v1 = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ v2 = cy_as_ll_request_response__get_word(reply_p, 1) ;
+ data->wr_count = (uint32_t)((v1 << 16) | v2) ;
+
+ v1 = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ v2 = cy_as_ll_request_response__get_word(reply_p, 3) ;
+ data->rd_count = (uint32_t)((v1 << 16) | v2) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_storage_get_transfer_amount(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_m_s_c_progress_data *data_p,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* Check if the firmware image supports this feature. */
+ if ((dev_p->media_supported[0]) && (dev_p->media_supported[0]
+ == (1 << cy_as_media_nand)))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_TRANSFER_AMOUNT,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed four words. */
+ reply_p = cy_as_ll_create_response(dev_p, 4) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, 0x00));
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_get_transfer_amount(dev_p,
+ req_p, reply_p, data_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT, (void *)data_p,
+ dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed as part of the
+ * FuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+
+}
+
+cy_as_return_status_t
+cy_as_storage_erase(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint32_t erase_unit,
+ uint16_t num_erase_units,
+ cy_as_function_callback cb,
+ uint32_t client
+ )
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_storage_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (dev_p->storage_device_info[bus][device].block_size == 0)
+ return CY_AS_ERROR_QUERY_DEVICE_NEEDED ;
+
+ /* If SD is not supported on the specified bus, then return ERROR */
+ if (dev_p->storage_device_info[bus][device].type !=
+ cy_as_media_sd_flash)
+ return CY_AS_ERROR_NOT_SUPPORTED;
+
+ if (num_erase_units == 0)
+ return CY_AS_ERROR_SUCCESS ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_ERASE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed four words. */
+ reply_p = cy_as_ll_create_response(dev_p, 4) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, 0x00));
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((erase_unit >> 16) & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(erase_unit & 0xffff)) ;
+ cy_as_ll_request_response__set_word(req_p, 3,
+ (uint16_t)((num_erase_units >> 8) & 0x00ff)) ;
+ cy_as_ll_request_response__set_word(req_p, 4,
+ (uint16_t)((num_erase_units << 8) & 0xff00)) ;
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = my_handle_response_no_data(dev_p, req_p, reply_p) ;
+
+ /* If error = "invalid response", this (very likely) means
+ * that we are not using the SD-only firmware module which
+ * is the only one supporting storage_erase. in this case
+ * force a "non supported" error code */
+ if (ret == CY_AS_ERROR_INVALID_RESPONSE)
+ ret = CY_AS_ERROR_NOT_SUPPORTED;
+
+ return ret ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_STOR_ERASE, 0, dev_p->func_cbs_stor,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_storage_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* The request and response are freed
+ * as part of the FuncCallback */
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static void
+cy_as_storage_func_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ cy_as_func_c_b_node *node = (cy_as_func_c_b_node *)
+ dev_p->func_cbs_stor->head_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX)
+ == CY_AS_REQUEST_RESPONSE_EX ;
+ cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS)
+ == CY_AS_REQUEST_RESPONSE_MS ;
+ uint8_t code ;
+ uint8_t cntxt ;
+
+ cy_as_hal_assert(ex_request || ms_request) ;
+ cy_as_hal_assert(dev_p->func_cbs_stor->count != 0) ;
+ cy_as_hal_assert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB) ;
+ (void) ex_request;
+ (void) ms_request;
+
+ (void)context ;
+
+ cntxt = cy_as_ll_request_response__get_context(rqt) ;
+ cy_as_hal_assert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT) ;
+
+ code = cy_as_ll_request_response__get_code(rqt) ;
+ switch (code) {
+ case CY_RQT_START_STORAGE:
+ ret = my_handle_response_storage_start(dev_p, rqt, resp, stat) ;
+ break ;
+ case CY_RQT_STOP_STORAGE:
+ ret = my_handle_response_storage_stop(dev_p, rqt, resp, stat) ;
+ break ;
+ case CY_RQT_CLAIM_STORAGE:
+ ret = my_handle_response_storage_claim(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_RELEASE_STORAGE:
+ ret = my_handle_response_storage_release(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_QUERY_MEDIA:
+ cy_as_hal_assert(cy_false) ;/* Not used any more. */
+ break ;
+ case CY_RQT_QUERY_BUS:
+ cy_as_hal_assert(node->data != 0) ;
+ ret = my_handle_response_storage_query_bus(dev_p,
+ rqt, resp, (uint32_t *)node->data) ;
+ break ;
+ case CY_RQT_QUERY_DEVICE:
+ cy_as_hal_assert(node->data != 0) ;
+ ret = my_handle_response_storage_query_device(dev_p,
+ rqt, resp, node->data) ;
+ break ;
+ case CY_RQT_QUERY_UNIT:
+ cy_as_hal_assert(node->data != 0) ;
+ ret = my_handle_response_storage_query_unit(dev_p,
+ rqt, resp, node->data) ;
+ break ;
+ case CY_RQT_SD_INTERFACE_CONTROL:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_SD_REGISTER_READ:
+ cy_as_hal_assert(node->data != 0) ;
+ ret = my_handle_response_sd_reg_read(dev_p, rqt, resp,
+ (cy_as_storage_sd_reg_read_data *)node->data) ;
+ break ;
+ case CY_RQT_PARTITION_STORAGE:
+ ret = my_handle_response_no_data(dev_p, rqt, resp);
+ break ;
+ case CY_RQT_PARTITION_ERASE:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_GET_TRANSFER_AMOUNT:
+ cy_as_hal_assert(node->data != 0) ;
+ ret = my_handle_response_get_transfer_amount(dev_p,
+ rqt, resp, (cy_as_m_s_c_progress_data *)node->data) ;
+ break ;
+ case CY_RQT_ERASE:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+
+ /* If error = "invalid response", this (very likely)
+ * means that we are not using the SD-only firmware
+ * module which is the only one supporting storage_erase.
+ * in this case force a "non supported" error code */
+ if (ret == CY_AS_ERROR_INVALID_RESPONSE)
+ ret = CY_AS_ERROR_NOT_SUPPORTED;
+
+ break ;
+
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /*
+ * if the low level layer returns a direct error, use the
+ * corresponding error code. if not, use the error code
+ * based on the response from firmware.
+ */
+ if (stat == CY_AS_ERROR_SUCCESS)
+ stat = ret ;
+
+ /* Call the user callback, if there is one */
+ if (node->cb_p)
+ node->cb_p((cy_as_device_handle)dev_p, stat,
+ node->client_data, node->data_type, node->data) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_stor) ;
+}
+
+
+static void
+cy_as_sdio_sync_reply_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ (void)rqt ;
+
+ if ((cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_SDIO_GET_TUPLE) ||
+ (cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_SDIO_EXT)) {
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(rqt) ==
+ CY_RQT_SDIO_READ_EXTENDED)
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_read_endpoint, ret) ;
+ else
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_write_endpoint, ret) ;
+ }
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+
+ dev_p->storage_rw_resp_p = resp;
+ dev_p->storage_wait = cy_false ;
+ if (((ret & 0x00FF) == CY_AS_ERROR_IO_ABORTED) || ((ret & 0x00FF)
+ == CY_AS_ERROR_IO_SUSPENDED))
+ dev_p->storage_error = (ret & 0x00FF);
+ else
+ dev_p->storage_error = (ret & 0x00FF) ?
+ CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS ;
+
+ /* Wake any threads/processes that are waiting on
+ * the read/write completion. */
+ cy_as_hal_wake(&dev_p->context[context]->channel);
+}
+
+cy_as_return_status_t
+cy_as_sdio_device_check(
+ cy_as_device *dev_p,
+ cy_as_bus_number_t bus,
+ uint32_t device)
+{
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+ return CY_AS_ERROR_NO_SUCH_BUS ;
+
+ if (device >= CY_AS_MAX_STORAGE_DEVICES)
+ return CY_AS_ERROR_NO_SUCH_DEVICE ;
+
+ if (!cy_as_device_is_astoria_dev(dev_p))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ return (is_storage_active(dev_p)) ;
+}
+
+cy_as_return_status_t
+cy_as_sdio_direct_io(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t is_write,
+ uint8_t *data_p)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t resp_data;
+
+ /*
+ * sanity checks required before sending the request to the
+ * firmware.
+ */
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+
+ if (!(cy_as_sdio_check_function_initialized(handle,
+ bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
+ return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+ req_p = cy_as_ll_create_request(dev_p, (is_write == cy_true) ?
+ CY_RQT_SDIO_WRITE_DIRECT : CY_RQT_SDIO_READ_DIRECT,
+ CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*Setting up request*/
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+ /* D1 */
+ if (is_write == cy_true) {
+ cy_as_ll_request_response__set_word(req_p, 1,
+ ((argument<<8) | 0x0080 | (n_function_no<<4) |
+ ((misc_buf&CY_SDIO_RAW)<<3) |
+ ((misc_buf&CY_SDIO_REARM_INT)>>5) |
+ (uint16_t)(address>>15)));
+ } else {
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (n_function_no<<4) | ((misc_buf&CY_SDIO_REARM_INT)>>5) |
+ (uint16_t)(address>>15));
+ }
+ /* D2 */
+ cy_as_ll_request_response__set_word(req_p, 2,
+ ((uint16_t)((address&0x00007fff)<<1))) ;
+
+ /*Create response*/
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /*Sending the request*/
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /*Check reply type*/
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SDIO_DIRECT) {
+ resp_data = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (resp_data >> 8)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else if (data_p != 0)
+ *(uint8_t *)(data_p) = (uint8_t)(resp_data&0x00ff);
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+
+destroy:
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_sdio_direct_read(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint8_t *data_p)
+{
+ return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
+ address, misc_buf, 0x00, cy_false, data_p);
+}
+
+cy_as_return_status_t
+cy_as_sdio_direct_write(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t *data_p)
+{
+ return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
+ address, misc_buf, argument, cy_true, data_p);
+}
+
+/*Cmd53 IO*/
+cy_as_return_status_t
+cy_as_sdio_extended_i_o(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t is_write,
+ uint8_t *data_p ,
+ uint8_t is_resume)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t resp_type;
+ uint8_t reqtype;
+ uint16_t resp_data;
+ cy_as_context *ctxt_p ;
+ uint32_t dmasize, loopcount = 200;
+ cy_as_end_point_number_t ep;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle,
+ bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
+ return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+ /* Request for 0 bytes of blocks is returned as a success*/
+ if (argument == 0)
+ return CY_AS_ERROR_SUCCESS;
+
+ /* Initialise the request to send to the West Bridge device. */
+ if (is_write == cy_true) {
+ reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
+ ep = dev_p->storage_write_endpoint;
+ } else {
+ reqtype = CY_RQT_SDIO_READ_EXTENDED;
+ ep = dev_p->storage_read_endpoint;
+ }
+
+ req_p = dev_p->storage_rw_req_p ;
+ cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
+
+ /* Initialise the space for reply from the Antioch. */
+ reply_p = dev_p->storage_rw_resp_p ;
+ cy_as_ll_init_response(reply_p, 2) ;
+
+ /* Setup the DMA request */
+ if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
+ if (argument >
+ dev_p->sdiocard[bus].
+ function[n_function_no-1].blocksize)
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+
+ } else {
+ if (argument > 511)
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+ }
+
+ if (argument == 512)
+ argument = 0;
+
+ dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
+ dev_p->sdiocard[bus].function[n_function_no-1].blocksize
+ * argument : argument;
+
+ ret = cy_as_dma_queue_request(dev_p, ep, (void *)(data_p),
+ dmasize, cy_false, (is_write & cy_true) ? cy_false :
+ cy_true, cy_as_sync_storage_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device,
+ n_function_no | ((is_resume) ? 0x80 : 0x00))) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ ((uint16_t)n_function_no)<<12|
+ ((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))
+ << 9 | (uint16_t)(address >> 7) |
+ ((is_write == cy_true) ? 0x8000 : 0x0000)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ ((uint16_t)(address&0x0000ffff) << 9) | argument) ;
+
+
+ /* Send the request and wait for completion of storage request */
+ dev_p->storage_wait = cy_true ;
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_true, cy_as_sdio_sync_reply_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ } else {
+ /* Setup the DMA request */
+ ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_true) ;
+
+ while (loopcount-- > 0) {
+ if (dev_p->storage_wait == cy_false)
+ break;
+ cy_as_hal_sleep_on(&ctxt_p->channel, 10) ;
+ }
+ if (dev_p->storage_wait == cy_true) {
+ dev_p->storage_wait = cy_false ;
+ cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true) ;
+ dev_p->storage_error = CY_AS_ERROR_TIMEOUT ;
+ }
+
+ ret = dev_p->storage_error;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ resp_type = cy_as_ll_request_response__get_code(
+ dev_p->storage_rw_resp_p) ;
+ if (resp_type == CY_RESP_SDIO_EXT) {
+ resp_data = cy_as_ll_request_response__get_word
+ (reply_p, 0)&0x00ff ;
+ if (resp_data)
+ ret = CY_AS_ERROR_INVALID_REQUEST ;
+
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+ }
+ return ret;
+
+}
+
+static void
+cy_as_sdio_async_reply_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ cy_as_storage_callback cb_ms ;
+ uint8_t reqtype ;
+ uint32_t pendingblocks;
+ (void)rqt ;
+ (void)context ;
+
+ pendingblocks = 0;
+ reqtype = cy_as_ll_request_response__get_code(rqt) ;
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if ((cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_SUCCESS_FAILURE) ||
+ (cy_as_ll_request_response__get_code(resp) ==
+ CY_RESP_SDIO_EXT)) {
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ ret &= 0x00FF ;
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (reqtype == CY_RQT_SDIO_READ_EXTENDED)
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_read_endpoint, ret) ;
+ else
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_write_endpoint, ret) ;
+
+ dev_p->storage_error = ret;
+ }
+
+ dev_p->storage_wait = cy_false ;
+
+ /*
+ * if the DMA callback has already been called,
+ * the user callback has to be called from here.
+ */
+ if (!cy_as_device_is_storage_async_pending(dev_p)) {
+ cy_as_hal_assert(dev_p->storage_cb_ms != NULL) ;
+ cb_ms = dev_p->storage_cb_ms ;
+
+ dev_p->storage_cb = 0 ;
+ dev_p->storage_cb_ms = 0 ;
+
+ if ((ret == CY_AS_ERROR_SUCCESS) ||
+ (ret == CY_AS_ERROR_IO_ABORTED) ||
+ (ret == CY_AS_ERROR_IO_SUSPENDED)) {
+ ret = dev_p->storage_error ;
+ pendingblocks = ((uint32_t)
+ cy_as_ll_request_response__get_word
+ (resp, 1)) << 16;
+ } else
+ ret = CY_AS_ERROR_INVALID_RESPONSE;
+
+ cb_ms((cy_as_device_handle)dev_p, dev_p->storage_bus_index,
+ dev_p->storage_device_index,
+ (dev_p->storage_unit | pendingblocks),
+ dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
+ } else
+ dev_p->storage_error = ret ;
+}
+
+
+cy_as_return_status_t
+cy_as_sdio_extended_i_o_async(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t is_write,
+ uint8_t *data_p,
+ cy_as_storage_callback callback)
+{
+
+ uint32_t mask ;
+ uint32_t dmasize;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ uint8_t reqtype;
+ cy_as_end_point_number_t ep;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle,
+ bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
+ return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+ if (callback == 0)
+ return CY_AS_ERROR_NULL_CALLBACK ;
+
+ /* We are supposed to return sucess if the number of
+ * blocks is zero
+ */
+ if (((misc_buf&CY_SDIO_BLOCKMODE) != 0) && (argument == 0)) {
+ callback(handle, bus, device, n_function_no, address,
+ ((is_write) ? cy_as_op_write : cy_as_op_read),
+ CY_AS_ERROR_SUCCESS) ;
+ return CY_AS_ERROR_SUCCESS ;
+ }
+
+
+ /*
+ * since async operations can be triggered by interrupt
+ * code, we must insure that we do not get multiple async
+ * operations going at one time and protect this test and
+ * set operation from interrupts.
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait)) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+ cy_as_device_set_storage_async_pending(dev_p) ;
+ cy_as_hal_enable_interrupts(mask) ;
+
+
+ /*
+ * storage information about the currently
+ * outstanding request
+ */
+ dev_p->storage_cb_ms = callback ;
+ dev_p->storage_bus_index = bus ;
+ dev_p->storage_device_index = device ;
+ dev_p->storage_unit = n_function_no ;
+ dev_p->storage_block_addr = address ;
+
+ if (is_write == cy_true) {
+ reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
+ ep = dev_p->storage_write_endpoint;
+ } else {
+ reqtype = CY_RQT_SDIO_READ_EXTENDED;
+ ep = dev_p->storage_read_endpoint;
+ }
+
+ /* Initialise the request to send to the West Bridge. */
+ req_p = dev_p->storage_rw_req_p ;
+ cy_as_ll_init_request(req_p, reqtype,
+ CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
+
+ /* Initialise the space for reply from the West Bridge. */
+ reply_p = dev_p->storage_rw_resp_p ;
+ cy_as_ll_init_response(reply_p, 2) ;
+
+ if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
+ if (argument >
+ dev_p->sdiocard[bus].function[n_function_no-1].blocksize)
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+
+ } else {
+ if (argument > 511)
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+ }
+
+ if (argument == 512)
+ argument = 0;
+ dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
+ dev_p->sdiocard[bus].function[n_function_no-1].blocksize *
+ argument : argument;
+
+ /* Setup the DMA request and adjust the storage
+ * operation if we are reading */
+ if (reqtype == CY_RQT_SDIO_READ_EXTENDED) {
+ ret = cy_as_dma_queue_request(dev_p, ep,
+ (void *)data_p, dmasize , cy_false, cy_true,
+ cy_as_async_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_read ;
+ } else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED) {
+ ret = cy_as_dma_queue_request(dev_p, ep, (void *)data_p,
+ dmasize, cy_false, cy_false, cy_as_async_storage_callback) ;
+ dev_p->storage_oper = cy_as_op_write ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ return ret ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ ((uint16_t)n_function_no) << 12 |
+ ((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE | CY_SDIO_OP_INCR)))
+ << 9 | (uint16_t)(address>>7) |
+ ((is_write == cy_true) ? 0x8000 : 0x0000)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ ((uint16_t)(address&0x0000ffff) << 9) | argument) ;
+
+
+ /* Send the request and wait for completion of storage request */
+ dev_p->storage_wait = cy_true ;
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
+ cy_as_sdio_async_reply_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ cy_as_device_clear_storage_async_pending(dev_p) ;
+ } else {
+ cy_as_dma_kick_start(dev_p, ep) ;
+ }
+
+ return ret ;
+}
+
+/* CMD53 Extended Read*/
+cy_as_return_status_t
+cy_as_sdio_extended_read(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t *data_p,
+ cy_as_sdio_callback callback)
+{
+ if (callback == 0)
+ return cy_as_sdio_extended_i_o(handle, bus, device,
+ n_function_no, address, misc_buf, argument,
+ cy_false, data_p, 0);
+
+ return cy_as_sdio_extended_i_o_async(handle, bus, device,
+ n_function_no, address, misc_buf, argument, cy_false,
+ data_p, callback);
+}
+
+/* CMD53 Extended Write*/
+cy_as_return_status_t
+cy_as_sdio_extended_write(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint32_t address,
+ uint8_t misc_buf,
+ uint16_t argument,
+ uint8_t *data_p,
+ cy_as_sdio_callback callback)
+{
+ if (callback == 0)
+ return cy_as_sdio_extended_i_o(handle, bus, device,
+ n_function_no, address, misc_buf, argument, cy_true,
+ data_p, 0);
+
+ return cy_as_sdio_extended_i_o_async(handle, bus, device,
+ n_function_no, address, misc_buf, argument, cy_true,
+ data_p, callback);
+}
+
+
+/* Read the CIS info tuples for the given function and Tuple ID*/
+cy_as_return_status_t
+cy_as_sdio_get_c_i_s_info(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint16_t tuple_id,
+ uint8_t *data_p)
+{
+
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t resp_data;
+ cy_as_context *ctxt_p ;
+ uint32_t loopcount = 200;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle, bus, 0)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait))
+ return CY_AS_ERROR_ASYNC_PENDING ;
+
+
+ /* Initialise the request to send to the Antioch. */
+ req_p = dev_p->storage_rw_req_p ;
+ cy_as_ll_init_request(req_p, CY_RQT_SDIO_GET_TUPLE,
+ CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
+
+ /* Initialise the space for reply from the Antioch. */
+ reply_p = dev_p->storage_rw_resp_p ;
+ cy_as_ll_init_response(reply_p, 3) ;
+
+ /* Setup the DMA request */
+ ret = cy_as_dma_queue_request(dev_p, dev_p->storage_read_endpoint,
+ data_p+1, 255, cy_false, cy_true, cy_as_sync_storage_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+
+ /* Set tuple id to fetch. */
+ cy_as_ll_request_response__set_word(req_p, 1, tuple_id<<8) ;
+
+ /* Send the request and wait for completion of storage request */
+ dev_p->storage_wait = cy_true ;
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
+ cy_as_sdio_sync_reply_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p,
+ dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED) ;
+ } else {
+ /* Setup the DMA request */
+ ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
+ ret = cy_as_dma_drain_queue(dev_p,
+ dev_p->storage_read_endpoint, cy_true) ;
+
+ while (loopcount-- > 0) {
+ if (dev_p->storage_wait == cy_false)
+ break;
+ cy_as_hal_sleep_on(&ctxt_p->channel, 10) ;
+ }
+
+ if (dev_p->storage_wait == cy_true) {
+ dev_p->storage_wait = cy_false ;
+ cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true) ;
+ return CY_AS_ERROR_TIMEOUT ;
+ }
+ ret = dev_p->storage_error ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_ll_request_response__get_code
+ (dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE) {
+ resp_data = cy_as_ll_request_response__get_word
+ (reply_p, 0) ;
+ if (resp_data) {
+ ret = CY_AS_ERROR_INVALID_REQUEST ;
+ } else if (data_p != 0)
+ *(uint8_t *)data_p = (uint8_t)
+ (cy_as_ll_request_response__get_word
+ (reply_p, 0)&0x00ff);
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+ }
+ return ret;
+}
+
+/*Query Device*/
+cy_as_return_status_t
+cy_as_sdio_query_card(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_sdio_card *data_p)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ uint8_t resp_type;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ /* Allocating memory to the SDIO device structure in dev_p */
+
+ cy_as_hal_mem_set(&dev_p->sdiocard[bus], 0, sizeof(cy_as_sdio_device));
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_QUERY_CARD,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, 0)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 5) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ resp_type = cy_as_ll_request_response__get_code(reply_p);
+ if (resp_type == CY_RESP_SDIO_QUERY_CARD) {
+ dev_p->sdiocard[bus].card.num_functions =
+ (uint8_t)((reply_p->data[0]&0xff00)>>8);
+ dev_p->sdiocard[bus].card.memory_present =
+ (uint8_t)reply_p->data[0]&0x0001;
+ dev_p->sdiocard[bus].card.manufacturer__id =
+ reply_p->data[1];
+ dev_p->sdiocard[bus].card.manufacturer_info =
+ reply_p->data[2];
+ dev_p->sdiocard[bus].card.blocksize =
+ reply_p->data[3];
+ dev_p->sdiocard[bus].card.maxblocksize =
+ reply_p->data[3];
+ dev_p->sdiocard[bus].card.card_capability =
+ (uint8_t)((reply_p->data[4]&0xff00)>>8);
+ dev_p->sdiocard[bus].card.sdio_version =
+ (uint8_t)(reply_p->data[4]&0x00ff);
+ dev_p->sdiocard[bus].function_init_map = 0x01;
+ data_p->num_functions =
+ dev_p->sdiocard[bus].card.num_functions;
+ data_p->memory_present =
+ dev_p->sdiocard[bus].card.memory_present;
+ data_p->manufacturer__id =
+ dev_p->sdiocard[bus].card.manufacturer__id;
+ data_p->manufacturer_info =
+ dev_p->sdiocard[bus].card.manufacturer_info;
+ data_p->blocksize = dev_p->sdiocard[bus].card.blocksize;
+ data_p->maxblocksize =
+ dev_p->sdiocard[bus].card.maxblocksize;
+ data_p->card_capability =
+ dev_p->sdiocard[bus].card.card_capability;
+ data_p->sdio_version =
+ dev_p->sdiocard[bus].card.sdio_version;
+ } else {
+ if (resp_type == CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+destroy:
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+/*Reset SDIO card. */
+cy_as_return_status_t
+cy_as_sdio_reset_card(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device)
+{
+
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t resp_type;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (dev_p->sdiocard != 0) {
+ dev_p->sdiocard[bus].function_init_map = 0;
+ dev_p->sdiocard[bus].function_suspended_map = 0;
+ }
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_RESET_DEV,
+ CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*Setup mailbox */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, 0)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ resp_type = cy_as_ll_request_response__get_code(reply_p) ;
+
+ if (resp_type == CY_RESP_SUCCESS_FAILURE) {
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = cy_as_sdio_query_card(handle, bus, device, 0);
+ } else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+
+destroy:
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+/* Initialise an IO function*/
+cy_as_return_status_t
+cy_as_sdio_init_function(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint8_t misc_buf)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t resp_type;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized
+ (handle, bus, 0)))
+ return CY_AS_ERROR_NOT_RUNNING;
+
+ if ((cy_as_sdio_check_function_initialized
+ (handle, bus, n_function_no))) {
+ if (misc_buf&CY_SDIO_FORCE_INIT)
+ dev_p->sdiocard[bus].function_init_map &=
+ (~(1 << n_function_no));
+ else
+ return CY_AS_ERROR_ALREADY_RUNNING;
+ }
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 5) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ resp_type = cy_as_ll_request_response__get_code(reply_p) ;
+
+ if (resp_type == CY_RESP_SDIO_INIT_FUNCTION) {
+ dev_p->sdiocard[bus].function[n_function_no-1].function_code =
+ (uint8_t)((reply_p->data[0]&0xff00)>>8);
+ dev_p->sdiocard[bus].function[n_function_no-1].
+ extended_func_code = (uint8_t)reply_p->data[0]&0x00ff;
+ dev_p->sdiocard[bus].function[n_function_no-1].blocksize =
+ reply_p->data[1];
+ dev_p->sdiocard[bus].function[n_function_no-1].
+ maxblocksize = reply_p->data[1];
+ dev_p->sdiocard[bus].function[n_function_no-1].card_psn =
+ (uint32_t)(reply_p->data[2])<<16;
+ dev_p->sdiocard[bus].function[n_function_no-1].card_psn |=
+ (uint32_t)(reply_p->data[3]);
+ dev_p->sdiocard[bus].function[n_function_no-1].csa_bits =
+ (uint8_t)((reply_p->data[4]&0xff00)>>8);
+ dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support =
+ (uint8_t)(reply_p->data[4]&0x0001);
+ dev_p->sdiocard[bus].function_init_map |= (1 << n_function_no);
+ cy_as_sdio_clear_function_suspended(handle, bus, n_function_no);
+
+ } else {
+ if (resp_type == CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_FUNCTION ;
+ }
+
+destroy:
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+/*Query individual functions. */
+cy_as_return_status_t
+cy_as_sdio_query_function(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ cy_as_sdio_func *data_p)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ cy_as_return_status_t ret;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle,
+ bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ data_p->blocksize =
+ dev_p->sdiocard[bus].function[n_function_no-1].blocksize;
+ data_p->card_psn =
+ dev_p->sdiocard[bus].function[n_function_no-1].card_psn;
+ data_p->csa_bits =
+ dev_p->sdiocard[bus].function[n_function_no-1].csa_bits;
+ data_p->extended_func_code =
+ dev_p->sdiocard[bus].function[n_function_no-1].
+ extended_func_code;
+ data_p->function_code =
+ dev_p->sdiocard[bus].function[n_function_no-1].function_code;
+ data_p->maxblocksize =
+ dev_p->sdiocard[bus].function[n_function_no-1].maxblocksize;
+ data_p->wakeup_support =
+ dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support;
+
+ return CY_AS_ERROR_SUCCESS;
+}
+
+/* Abort the Current Extended IO Operation*/
+cy_as_return_status_t
+cy_as_sdio_abort_function(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t resp_type;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle,
+ bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ if ((cy_as_device_is_storage_async_pending(dev_p)) ||
+ (dev_p->storage_wait)) {
+ if (!(cy_as_sdio_get_card_capability(handle, bus) &
+ CY_SDIO_SDC))
+ return CY_AS_ERROR_INVALID_COMMAND;
+ }
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_ABORT_IO,
+ CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*Setup mailbox */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ resp_type = cy_as_ll_request_response__get_code(reply_p) ;
+
+ if (resp_type == CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+
+
+destroy:
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+}
+
+/* Suspend IO to current function*/
+cy_as_return_status_t
+cy_as_sdio_suspend(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized(handle, bus,
+ n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (!(cy_as_sdio_check_support_bus_suspend(handle, bus)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (!(cy_as_sdio_get_card_capability(handle, bus) & CY_SDIO_SDC))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
+ return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*Setup mailbox */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ ret = cy_as_ll_request_response__get_code(reply_p) ;
+ cy_as_sdio_set_function_suspended(handle, bus, n_function_no);
+ }
+
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*Resume suspended function*/
+cy_as_return_status_t
+cy_as_sdio_resume(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ cy_as_oper_type op,
+ uint8_t misc_buf,
+ uint16_t pendingblockcount,
+ uint8_t *data_p
+ )
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t resp_data, ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized
+ (handle, bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ /* If suspend resume is not supported return */
+ if (!(cy_as_sdio_check_support_bus_suspend(handle, bus)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ /* if the function is not suspended return. */
+ if (!(cy_as_sdio_check_function_suspended
+ (handle, bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /*Setup mailbox */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ create_address(bus, (uint8_t)device, n_function_no)) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 2) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SDIO_RESUME) {
+ resp_data = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (resp_data & 0x00ff) {
+ /* Send extended read request to resume the read. */
+ if (op == cy_as_op_read) {
+ ret = cy_as_sdio_extended_i_o(handle, bus,
+ device, n_function_no, 0, misc_buf,
+ pendingblockcount, cy_false, data_p, 1);
+ } else {
+ ret = cy_as_sdio_extended_i_o(handle, bus,
+ device, n_function_no, 0, misc_buf,
+ pendingblockcount, cy_true, data_p, 1);
+ }
+ } else {
+ ret = CY_AS_ERROR_SUCCESS;
+ }
+ } else {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ }
+
+destroy:
+ cy_as_sdio_clear_function_suspended(handle, bus, n_function_no);
+ if (req_p != 0)
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ if (reply_p != 0)
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+
+}
+
+/*Set function blocksize. Size cannot exceed max
+ * block size for the function*/
+cy_as_return_status_t
+cy_as_sdio_set_blocksize(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no,
+ uint16_t blocksize)
+{
+ cy_as_return_status_t ret;
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ ret = cy_as_sdio_device_check(dev_p, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized
+ (handle, bus, n_function_no)))
+ return CY_AS_ERROR_INVALID_FUNCTION;
+ if (n_function_no == 0) {
+ if (blocksize > cy_as_sdio_get_card_max_blocksize(handle, bus))
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+ else if (blocksize == cy_as_sdio_get_card_blocksize
+ (handle, bus))
+ return CY_AS_ERROR_SUCCESS;
+ } else {
+ if (blocksize >
+ cy_as_sdio_get_function_max_blocksize(handle,
+ bus, n_function_no))
+ return CY_AS_ERROR_INVALID_BLOCKSIZE;
+ else if (blocksize ==
+ cy_as_sdio_get_function_blocksize(handle,
+ bus, n_function_no))
+ return CY_AS_ERROR_SUCCESS;
+ }
+
+ ret = cy_as_sdio_direct_write(handle, bus, device, 0,
+ (uint16_t)(n_function_no << 8) |
+ 0x10, 0, blocksize & 0x00ff, 0);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ ret = cy_as_sdio_direct_write(handle, bus, device, 0,
+ (uint16_t)(n_function_no << 8) |
+ 0x11, 0, (blocksize & 0xff00) >> 8, 0);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (n_function_no == 0)
+ cy_as_sdio_set_card_block_size(handle, bus, blocksize);
+ else
+ cy_as_sdio_set_function_block_size(handle,
+ bus, n_function_no, blocksize);
+ return ret;
+}
+
+/* Deinitialize an SDIO function*/
+cy_as_return_status_t
+cy_as_sdio_de_init_function(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ uint8_t n_function_no)
+{
+ cy_as_return_status_t ret;
+ uint8_t temp;
+
+ if (n_function_no == 0)
+ return CY_AS_ERROR_INVALID_FUNCTION;
+
+ ret = cy_as_sdio_device_check((cy_as_device *)handle, bus, device);
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret;
+
+ if (!(cy_as_sdio_check_function_initialized
+ (handle, bus, n_function_no)))
+ return CY_AS_ERROR_SUCCESS;
+
+ temp = (uint8_t)(((cy_as_device *)handle)->sdiocard[bus].
+ function_init_map & (~(1 << n_function_no)));
+
+ cy_as_sdio_direct_write(handle, bus, device, 0, 0x02, 0, temp, 0);
+
+ ((cy_as_device *)handle)->sdiocard[bus].function_init_map &=
+ (~(1 << n_function_no));
+
+ return CY_AS_ERROR_SUCCESS;
+}
+
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c
new file mode 100644
index 000000000000..d0ffc2cfe77a
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasusb.c
@@ -0,0 +1,3718 @@
+/* Cypress West Bridge API source file (cyasusb.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasusb.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+#include "../../include/linux/westbridge/cyasdma.h"
+#include "../../include/linux/westbridge/cyaslowlevel.h"
+#include "../../include/linux/westbridge/cyaslep2pep.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+#include "../../include/linux/westbridge/cyasstorage.h"
+
+static cy_as_return_status_t
+cy_as_usb_ack_setup_packet(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+static void
+cy_as_usb_func_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret) ;
+/*
+* Reset the USB EP0 state
+*/
+static void
+cy_as_usb_reset_e_p0_state(cy_as_device *dev_p)
+{
+ cy_as_log_debug_message(6, "cy_as_usb_reset_e_p0_state called") ;
+
+ cy_as_device_clear_ack_delayed(dev_p) ;
+ cy_as_device_clear_setup_packet(dev_p) ;
+ if (cy_as_device_is_usb_async_pending(dev_p, 0))
+ cy_as_usb_cancel_async((cy_as_device_handle)dev_p, 0) ;
+
+ dev_p->usb_pending_buffer = 0 ;
+}
+
+/*
+* External function to map logical endpoints to physical endpoints
+*/
+static cy_as_return_status_t
+is_usb_active(cy_as_device *dev_p)
+{
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (dev_p->usb_count == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+usb_ack_callback(cy_as_device_handle h,
+ cy_as_return_status_t status,
+ uint32_t client,
+ cy_as_funct_c_b_type type,
+ void *data)
+{
+ cy_as_device *dev_p = (cy_as_device *)h ;
+
+ (void)client ;
+ (void)status ;
+ (void)data ;
+
+ cy_as_hal_assert(type == CY_FUNCT_CB_NODATA) ;
+
+ if (dev_p->usb_pending_buffer) {
+ cy_as_usb_io_callback cb ;
+
+ cb = dev_p->usb_cb[0] ;
+ dev_p->usb_cb[0] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p, 0) ;
+ if (cb)
+ cb(h, 0, dev_p->usb_pending_size,
+ dev_p->usb_pending_buffer, dev_p->usb_error) ;
+
+ dev_p->usb_pending_buffer = 0 ;
+ }
+
+ cy_as_device_clear_setup_packet(dev_p) ;
+}
+
+static void
+my_usb_request_callback_usb_event(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ uint16_t ev ;
+ uint16_t val ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+
+ ev = cy_as_ll_request_response__get_word(req_p, 0) ;
+ switch (ev) {
+ case 0: /* Reserved */
+ cy_as_ll_send_status_response(dev_p, CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_INVALID_REQUEST, 0) ;
+ break ;
+
+ case 1: /* Reserved */
+ cy_as_ll_send_status_response(dev_p, CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_INVALID_REQUEST, 0) ;
+ break ;
+
+ case 2: /* USB Suspend */
+ dev_p->usb_last_event = cy_as_event_usb_suspend ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h, cy_as_event_usb_suspend, 0) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h, cy_as_event_usb_suspend, 0) ;
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ break;
+
+ case 3: /* USB Resume */
+ dev_p->usb_last_event = cy_as_event_usb_resume ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h, cy_as_event_usb_resume, 0) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h, cy_as_event_usb_resume, 0) ;
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ break ;
+
+ case 4: /* USB Reset */
+ /*
+ * if we get a USB reset, the USB host did not understand
+ * our response or we timed out for some reason. reset
+ * our internal state to be ready for another set of
+ * enumeration based requests.
+ */
+ if (cy_as_device_is_ack_delayed(dev_p))
+ cy_as_usb_reset_e_p0_state(dev_p) ;
+
+ dev_p->usb_last_event = cy_as_event_usb_reset ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h, cy_as_event_usb_reset, 0) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h, cy_as_event_usb_reset, 0) ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ cy_as_device_clear_usb_high_speed(dev_p) ;
+ cy_as_usb_set_dma_sizes(dev_p) ;
+ dev_p->usb_max_tx_size = 0x40 ;
+ cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x40) ;
+ break ;
+
+ case 5: /* USB Set Configuration */
+ /* The configuration to set */
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ dev_p->usb_last_event = cy_as_event_usb_set_config ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_set_config, &val) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_set_config, &val) ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ break ;
+
+ case 6: /* USB Speed change */
+ /* Connect speed */
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ dev_p->usb_last_event = cy_as_event_usb_speed_change ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_speed_change, &val) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_speed_change, &val) ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ cy_as_device_set_usb_high_speed(dev_p) ;
+ cy_as_usb_set_dma_sizes(dev_p) ;
+ dev_p->usb_max_tx_size = 0x200 ;
+ cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x200) ;
+ break ;
+
+ case 7: /* USB Clear Feature */
+ /* EP Number */
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_clear_feature, &val) ;
+ if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_clear_feature, &val) ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ break ;
+
+ default:
+ cy_as_hal_print_message("invalid event type\n") ;
+ cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT,
+ CY_RESP_USB_INVALID_EVENT, sizeof(ev), &ev) ;
+ break ;
+ }
+}
+
+static void
+my_usb_request_callback_usb_data(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ cy_as_end_point_number_t ep ;
+ uint8_t type ;
+ uint16_t len ;
+ uint16_t val ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ ep = (cy_as_end_point_number_t)((val >> 13) & 0x01) ;
+ len = (val & 0x1ff) ;
+
+ cy_as_hal_assert(len <= 64) ;
+ cy_as_ll_request_response__unpack(req_p,
+ 1, len, dev_p->usb_ep_data) ;
+
+ type = (uint8_t)((val >> 14) & 0x03) ;
+ if (type == 0) {
+ if (cy_as_device_is_ack_delayed(dev_p)) {
+ /*
+ * A setup packet has arrived while we are
+ * processing a previous setup packet. reset
+ * our state with respect to EP0 to be ready
+ * to process the new packet.
+ */
+ cy_as_usb_reset_e_p0_state(dev_p) ;
+ }
+
+ if (len != 8)
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_INVALID_REQUEST, 0) ;
+ else {
+ cy_as_device_clear_ep0_stalled(dev_p) ;
+ cy_as_device_set_setup_packet(dev_p) ;
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_SUCCESS, 0) ;
+
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_setup_packet,
+ dev_p->usb_ep_data) ;
+ else
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_setup_packet,
+ dev_p->usb_ep_data) ;
+
+ if ((!cy_as_device_is_ack_delayed(dev_p)) &&
+ (!cy_as_device_is_ep0_stalled(dev_p)))
+ cy_as_usb_ack_setup_packet(h,
+ usb_ack_callback, 0) ;
+ }
+ } else if (type == 2) {
+ if (len != 0)
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_INVALID_REQUEST, 0) ;
+ else {
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_status_packet, 0) ;
+ else
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_status_packet, 0) ;
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT,
+ CY_AS_ERROR_SUCCESS, 0) ;
+ }
+ } else if (type == 1) {
+ /*
+ * we need to hand the data associated with these
+ * endpoints to the DMA module.
+ */
+ cy_as_dma_received_data(dev_p, ep, len, dev_p->usb_ep_data) ;
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+ }
+}
+
+static void
+my_usb_request_callback_inquiry(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ cy_as_usb_inquiry_data_dep cbdata ;
+ cy_as_usb_inquiry_data cbdata_ms ;
+ void *data ;
+ uint16_t val ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+ uint8_t def_inq_data[64] ;
+ uint8_t evpd ;
+ uint8_t codepage ;
+ cy_bool updated ;
+ uint16_t length ;
+
+ cy_as_bus_number_t bus ;
+ uint32_t device ;
+ cy_as_media_type media ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ bus = cy_as_storage_get_bus_from_address(val) ;
+ device = cy_as_storage_get_device_from_address(val) ;
+ media = cy_as_storage_get_media_from_address(val) ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ evpd = (uint8_t)((val >> 8) & 0x01) ;
+ codepage = (uint8_t)(val & 0xff) ;
+
+ length = cy_as_ll_request_response__get_word(req_p, 2) ;
+ data = (void *)def_inq_data ;
+
+ updated = cy_false ;
+
+ if (dev_p->usb_event_cb_ms) {
+ cbdata_ms.bus = bus ;
+ cbdata_ms.device = device ;
+ cbdata_ms.updated = updated ;
+ cbdata_ms.evpd = evpd ;
+ cbdata_ms.codepage = codepage ;
+ cbdata_ms.length = length ;
+ cbdata_ms.data = data ;
+
+ cy_as_hal_assert(cbdata_ms.length <= sizeof(def_inq_data)) ;
+ cy_as_ll_request_response__unpack(req_p,
+ 3, cbdata_ms.length, cbdata_ms.data) ;
+
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_inquiry_before, &cbdata_ms) ;
+
+ updated = cbdata_ms.updated;
+ data = cbdata_ms.data ;
+ length = cbdata_ms.length ;
+ } else if (dev_p->usb_event_cb) {
+ cbdata.media = media ;
+ cbdata.updated = updated ;
+ cbdata.evpd = evpd ;
+ cbdata.codepage = codepage ;
+ cbdata.length = length ;
+ cbdata.data = data ;
+
+ cy_as_hal_assert(cbdata.length <=
+ sizeof(def_inq_data)) ;
+ cy_as_ll_request_response__unpack(req_p, 3,
+ cbdata.length, cbdata.data) ;
+
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_inquiry_before, &cbdata) ;
+
+ updated = cbdata.updated ;
+ data = cbdata.data ;
+ length = cbdata.length ;
+ }
+
+ if (updated && length > 192)
+ cy_as_hal_print_message("an inquiry result from a "
+ "cy_as_event_usb_inquiry_before event "
+ "was greater than 192 bytes.") ;
+
+ /* Now send the reply with the data back
+ * to the West Bridge device */
+ if (updated && length <= 192) {
+ /*
+ * the callback function modified the inquiry
+ * data, ship the data back to the west bridge firmware.
+ */
+ cy_as_ll_send_data_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT,
+ CY_RESP_INQUIRY_DATA, length, data) ;
+ } else {
+ /*
+ * the callback did not modify the data, just acknowledge
+ * that we processed the request
+ */
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1) ;
+ }
+
+ if (dev_p->usb_event_cb_ms)
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_inquiry_after, &cbdata_ms) ;
+ else if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_inquiry_after, &cbdata) ;
+}
+
+static void
+my_usb_request_callback_start_stop(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ cy_as_bus_number_t bus ;
+ cy_as_media_type media ;
+ uint32_t device ;
+ uint16_t val ;
+
+ if (dev_p->usb_event_cb_ms || dev_p->usb_event_cb) {
+ cy_bool loej ;
+ cy_bool start ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ bus = cy_as_storage_get_bus_from_address(val) ;
+ device = cy_as_storage_get_device_from_address(val) ;
+ media = cy_as_storage_get_media_from_address(val) ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 1) ;
+ loej = (val & 0x02) ? cy_true : cy_false ;
+ start = (val & 0x01) ? cy_true : cy_false ;
+
+ if (dev_p->usb_event_cb_ms) {
+ cy_as_usb_start_stop_data cbdata_ms ;
+
+ cbdata_ms.bus = bus ;
+ cbdata_ms.device = device ;
+ cbdata_ms.loej = loej ;
+ cbdata_ms.start = start ;
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_start_stop, &cbdata_ms) ;
+
+ } else if (dev_p->usb_event_cb) {
+ cy_as_usb_start_stop_data_dep cbdata ;
+
+ cbdata.media = media ;
+ cbdata.loej = loej ;
+ cbdata.start = start ;
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_start_stop, &cbdata) ;
+ }
+ }
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1) ;
+}
+
+static void
+my_usb_request_callback_uknown_c_b_w(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ uint16_t val ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+ uint8_t buf[16] ;
+
+ uint8_t response[4] ;
+ uint16_t reqlen ;
+ void *request ;
+ uint8_t status ;
+ uint8_t key ;
+ uint8_t asc ;
+ uint8_t ascq ;
+
+ val = cy_as_ll_request_response__get_word(req_p, 0) ;
+ /* Failed by default */
+ status = 1 ;
+ /* Invalid command */
+ key = 0x05 ;
+ /* Invalid command */
+ asc = 0x20 ;
+ /* Invalid command */
+ ascq = 0x00 ;
+ reqlen = cy_as_ll_request_response__get_word(req_p, 1) ;
+ request = buf ;
+
+ cy_as_hal_assert(reqlen <= sizeof(buf)) ;
+ cy_as_ll_request_response__unpack(req_p, 2, reqlen, request) ;
+
+ if (dev_p->usb_event_cb_ms) {
+ cy_as_usb_unknown_command_data cbdata_ms ;
+ cbdata_ms.bus = cy_as_storage_get_bus_from_address(val) ;
+ cbdata_ms.device =
+ cy_as_storage_get_device_from_address(val) ;
+ cbdata_ms.reqlen = reqlen ;
+ cbdata_ms.request = request ;
+ cbdata_ms.status = status ;
+ cbdata_ms.key = key ;
+ cbdata_ms.asc = asc ;
+ cbdata_ms.ascq = ascq ;
+
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_unknown_storage, &cbdata_ms) ;
+ status = cbdata_ms.status ;
+ key = cbdata_ms.key ;
+ asc = cbdata_ms.asc ;
+ ascq = cbdata_ms.ascq ;
+ } else if (dev_p->usb_event_cb) {
+ cy_as_usb_unknown_command_data_dep cbdata ;
+ cbdata.media =
+ cy_as_storage_get_media_from_address(val) ;
+ cbdata.reqlen = reqlen ;
+ cbdata.request = request ;
+ cbdata.status = status ;
+ cbdata.key = key ;
+ cbdata.asc = asc ;
+ cbdata.ascq = ascq ;
+
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_unknown_storage, &cbdata) ;
+ status = cbdata.status ;
+ key = cbdata.key ;
+ asc = cbdata.asc ;
+ ascq = cbdata.ascq ;
+ }
+
+ response[0] = status ;
+ response[1] = key ;
+ response[2] = asc ;
+ response[3] = ascq ;
+ cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT,
+ CY_RESP_UNKNOWN_SCSI_COMMAND, sizeof(response), response) ;
+}
+
+static void
+my_usb_request_callback_m_s_c_progress(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p)
+{
+ uint16_t val1, val2 ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+
+ if ((dev_p->usb_event_cb) || (dev_p->usb_event_cb_ms)) {
+ cy_as_m_s_c_progress_data cbdata ;
+
+ val1 = cy_as_ll_request_response__get_word(req_p, 0) ;
+ val2 = cy_as_ll_request_response__get_word(req_p, 1) ;
+ cbdata.wr_count = (uint32_t)((val1 << 16) | val2) ;
+
+ val1 = cy_as_ll_request_response__get_word(req_p, 2) ;
+ val2 = cy_as_ll_request_response__get_word(req_p, 3) ;
+ cbdata.rd_count = (uint32_t)((val1 << 16) | val2) ;
+
+ if (dev_p->usb_event_cb)
+ dev_p->usb_event_cb(h,
+ cy_as_event_usb_m_s_c_progress, &cbdata) ;
+ else
+ dev_p->usb_event_cb_ms(h,
+ cy_as_event_usb_m_s_c_progress, &cbdata) ;
+ }
+
+ cy_as_ll_send_status_response(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+}
+
+/*
+* This function processes the requests delivered from the
+* firmware within the West Bridge device that are delivered
+* in the USB context. These requests generally are EP0 and
+* EP1 related requests or USB events.
+*/
+static void
+my_usb_request_callback(cy_as_device *dev_p, uint8_t context,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *resp_p,
+ cy_as_return_status_t ret)
+{
+ uint16_t val ;
+ uint8_t code = cy_as_ll_request_response__get_code(req_p) ;
+
+ (void)resp_p ;
+ (void)context ;
+ (void)ret ;
+
+ switch (code) {
+ case CY_RQT_USB_EVENT:
+ my_usb_request_callback_usb_event(dev_p, req_p) ;
+ break ;
+
+ case CY_RQT_USB_EP_DATA:
+ dev_p->usb_last_event = cy_as_event_usb_setup_packet ;
+ my_usb_request_callback_usb_data(dev_p, req_p) ;
+ break ;
+
+ case CY_RQT_SCSI_INQUIRY_COMMAND:
+ dev_p->usb_last_event = cy_as_event_usb_inquiry_after ;
+ my_usb_request_callback_inquiry(dev_p, req_p) ;
+ break ;
+
+ case CY_RQT_SCSI_START_STOP_COMMAND:
+ dev_p->usb_last_event = cy_as_event_usb_start_stop ;
+ my_usb_request_callback_start_stop(dev_p, req_p) ;
+ break ;
+
+ case CY_RQT_SCSI_UNKNOWN_COMMAND:
+ dev_p->usb_last_event = cy_as_event_usb_unknown_storage ;
+ my_usb_request_callback_uknown_c_b_w(dev_p, req_p) ;
+ break ;
+
+ case CY_RQT_USB_ACTIVITY_UPDATE:
+ dev_p->usb_last_event = cy_as_event_usb_m_s_c_progress ;
+ my_usb_request_callback_m_s_c_progress(dev_p, req_p) ;
+ break ;
+
+ default:
+ cy_as_hal_print_message("invalid request "
+ "received on USB context\n") ;
+ val = req_p->box0 ;
+ cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT,
+ CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
+ break ;
+ }
+}
+
+static cy_as_return_status_t
+my_handle_response_usb_start(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /*
+ * mark EP 0 and EP1 as 64 byte endpoints
+ */
+ cy_as_dma_set_max_dma_size(dev_p, 0, 64) ;
+ cy_as_dma_set_max_dma_size(dev_p, 1, 64) ;
+
+ dev_p->usb_count++ ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_destroy_c_b_queue(dev_p->usb_func_cbs) ;
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, 0) ;
+ }
+
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+
+ return ret ;
+
+}
+
+/*
+* This function starts the USB stack. The stack is reference
+* counted so if the stack is already started, this function
+* just increments the count. If the stack has not been started,
+* a start request is sent to the West Bridge device.
+*
+* Note: Starting the USB stack does not cause the USB signals
+* to be connected to the USB pins. To do this and therefore
+* initiate enumeration, CyAsUsbConnect() must be called.
+*/
+cy_as_return_status_t
+cy_as_usb_start(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p, *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_start called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (cy_as_device_is_u_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ cy_as_device_set_u_s_s_pending(dev_p) ;
+
+ if (dev_p->usb_count == 0) {
+ /*
+ * since we are just starting the stack,
+ * mark USB as not connected to the remote host
+ */
+ cy_as_device_clear_usb_connected(dev_p) ;
+ dev_p->usb_phy_config = 0 ;
+
+ /* Queue for 1.0 Async Requests, kept for
+ * backwards compatibility */
+ dev_p->usb_func_cbs = cy_as_create_c_b_queue(CYAS_USB_FUNC_CB) ;
+ if (dev_p->usb_func_cbs == 0) {
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Reset the EP0 state */
+ cy_as_usb_reset_e_p0_state(dev_p) ;
+
+ /*
+ * we register here becuase the start request may cause
+ * events to occur before the response to the start request.
+ */
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, my_usb_request_callback) ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_START_USB, CY_RQT_USB_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ cy_as_destroy_c_b_queue(dev_p->usb_func_cbs) ;
+ dev_p->usb_func_cbs = 0 ;
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_destroy_c_b_queue(dev_p->usb_func_cbs) ;
+ dev_p->usb_func_cbs = 0 ;
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_usb_start(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb,
+ client, CY_FUNCT_CB_USB_START, 0,
+ dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else {
+ dev_p->usb_count++ ;
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_USB_START, 0) ;
+ }
+
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+void
+cy_as_usb_reset(cy_as_device *dev_p)
+{
+ int i ;
+
+ cy_as_device_clear_usb_connected(dev_p) ;
+
+ for (i = 0 ; i < sizeof(dev_p->usb_config) /
+ sizeof(dev_p->usb_config[0]) ; i++) {
+ /*
+ * cancel all pending USB read/write operations, as it is
+ * possible that the USB stack comes up in a different
+ * configuration with a different set of endpoints.
+ */
+ if (cy_as_device_is_usb_async_pending(dev_p, i))
+ cy_as_usb_cancel_async(dev_p,
+ (cy_as_end_point_number_t)i) ;
+
+ dev_p->usb_cb[i] = 0 ;
+ dev_p->usb_config[i].enabled = cy_false ;
+ }
+
+ dev_p->usb_phy_config = 0 ;
+}
+
+/*
+ * This function does all the API side clean-up associated
+ * with CyAsUsbStop, without any communication with firmware.
+ * This needs to be done when the device is being reset while
+ * the USB stack is active.
+ */
+void
+cy_as_usb_cleanup(cy_as_device *dev_p)
+{
+ if (dev_p->usb_count) {
+ cy_as_usb_reset_e_p0_state(dev_p) ;
+ cy_as_usb_reset(dev_p) ;
+ cy_as_hal_mem_set(dev_p->usb_config, 0,
+ sizeof(dev_p->usb_config)) ;
+ cy_as_destroy_c_b_queue(dev_p->usb_func_cbs) ;
+
+ dev_p->usb_count = 0 ;
+ }
+}
+
+static cy_as_return_status_t
+my_handle_response_usb_stop(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /*
+ * we sucessfully shutdown the stack, so
+ * decrement to make the count zero.
+ */
+ cy_as_usb_cleanup(dev_p) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_ll_register_request_callback(dev_p,
+ CY_RQT_USB_RQT_CONTEXT, 0) ;
+
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+/*
+* This function stops the USB stack. The USB stack is reference
+* counted so first is reference count is decremented. If the
+* reference count is then zero, a request is sent to the West
+* Bridge device to stop the USB stack on the West Bridge device.
+*/
+cy_as_return_status_t
+cy_as_usb_stop(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p = 0, *reply_p = 0 ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_stop called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (cy_as_device_is_u_s_s_pending(dev_p))
+ return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+ cy_as_device_set_u_s_s_pending(dev_p) ;
+
+ if (dev_p->usb_count == 1) {
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_STOP_USB,
+ CY_RQT_USB_RQT_CONTEXT, 0) ;
+ if (req_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ /* Reserve space for the reply, the reply data will not
+ * exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_usb_stop(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_STOP, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ } else if (dev_p->usb_count > 1) {
+ /*
+ * reset all LE_ps to inactive state, after cleaning
+ * up any pending async read/write calls.
+ */
+ cy_as_usb_reset(dev_p) ;
+ dev_p->usb_count-- ;
+
+ if (cb)
+ cb(handle, ret, client, CY_FUNCT_CB_USB_STOP, 0) ;
+ }
+
+ cy_as_device_clear_u_s_s_pending(dev_p) ;
+
+ return ret ;
+}
+
+/*
+* This function registers a callback to be called when
+* USB events are processed
+*/
+cy_as_return_status_t
+cy_as_usb_register_callback(cy_as_device_handle handle,
+ cy_as_usb_event_callback callback)
+{
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_register_callback called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (!cy_as_device_is_configured(dev_p))
+ return CY_AS_ERROR_NOT_CONFIGURED ;
+
+ if (!cy_as_device_is_firmware_loaded(dev_p))
+ return CY_AS_ERROR_NO_FIRMWARE ;
+
+ dev_p->usb_event_cb = NULL ;
+ dev_p->usb_event_cb_ms = callback ;
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+
+static cy_as_return_status_t
+my_handle_response_no_data(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_connect(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ cy_as_device_set_usb_connected(dev_p) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+
+/*
+* This method asks the West Bridge device to connect the
+* internal USB D+ and D- signals to the USB pins, thus
+* starting the enumeration processes if the external pins
+* are connnected to a USB host. If the external pins are
+* not connect to a USB host, enumeration will begin as soon
+* as the USB pins are connected to a host.
+*/
+cy_as_return_status_t
+cy_as_usb_connect(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_connect called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* 1 = Connect request */
+ cy_as_ll_request_response__set_word(req_p, 0, 1) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_connect(dev_p, req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_CONNECT, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_disconnect(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_return_status_t ret)
+{
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ cy_as_device_clear_usb_connected(dev_p) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+/*
+* This method forces a disconnect of the D+ and D- pins
+* external to the West Bridge device from the D+ and D-
+* signals internally, effectively disconnecting the West
+* Bridge device from any connected USB host.
+*/
+cy_as_return_status_t
+cy_as_usb_disconnect(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_disconnect called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (!cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_NOT_CONNECTED ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0, 0) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed two bytes */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_disconnect(dev_p,
+ req_p, reply_p, ret) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_DISCONNECT, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_set_enum_config(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ /*
+ * we configured the west bridge device and
+ * enumeration is going to happen on the P port
+ * processor. now we must enable endpoint zero
+ */
+ cy_as_usb_end_point_config config ;
+
+ config.dir = cy_as_usb_in_out ;
+ config.type = cy_as_usb_control ;
+ config.enabled = cy_true ;
+
+ ret = cy_as_usb_set_end_point_config((cy_as_device_handle *)
+ dev_p, 0, &config) ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+* This method sets how the USB is enumerated and should
+* be called before the CyAsUsbConnect() is called.
+*/
+static cy_as_return_status_t
+my_usb_set_enum_config(cy_as_device *dev_p,
+ uint8_t bus_mask,
+ uint8_t media_mask,
+ cy_bool use_antioch_enumeration,
+ uint8_t mass_storage_interface,
+ uint8_t mtp_interface,
+ cy_bool mass_storage_callbacks,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_set_enum_config called") ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* if we are using MTP firmware: */
+ if (dev_p->is_mtp_firmware == 1) {
+ /* we cannot enumerate MSC */
+ if (mass_storage_interface != 0)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (bus_mask == 0) {
+ if (mtp_interface != 0)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+ } else if (bus_mask == 2) {
+ /* enable EP 1 as it will be used */
+ cy_as_dma_enable_end_point(dev_p, 1, cy_true,
+ cy_as_direction_in) ;
+ dev_p->usb_config[1].enabled = cy_true ;
+ dev_p->usb_config[1].dir = cy_as_usb_in ;
+ dev_p->usb_config[1].type = cy_as_usb_int ;
+ } else {
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+ }
+ /* if we are not using MTP firmware, we cannot enumerate MTP */
+ } else if (mtp_interface != 0)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ /*
+ * if we are not enumerating mass storage, we should
+ * not be providing an interface number.
+ */
+ if (bus_mask == 0 && mass_storage_interface != 0)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ /*
+ * if we are going to use mtp_interface, bus mask must be 2.
+ */
+ if (mtp_interface != 0 && bus_mask != 2)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 4) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Marshal the structure */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((media_mask << 8) | bus_mask)) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)use_antioch_enumeration) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ dev_p->is_mtp_firmware ? mtp_interface :
+ mass_storage_interface) ;
+ cy_as_ll_request_response__set_word(req_p, 3,
+ (uint16_t)mass_storage_callbacks) ;
+
+ /* Reserve space for the reply, the reply
+ * data will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_set_enum_config(dev_p,
+ req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_SETENUMCONFIG, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+ * This method sets how the USB is enumerated and should
+ * be called before the CyAsUsbConnect() is called.
+ */
+cy_as_return_status_t
+cy_as_usb_set_enum_config(cy_as_device_handle handle,
+ cy_as_usb_enum_control *config_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ uint8_t bus_mask, media_mask ;
+ uint32_t bus, device ;
+ cy_as_return_status_t ret ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if ((cy_as_device_is_in_callback(dev_p)) && (cb != 0))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Since we are mapping the media types to bus with NAND to 0
+ * and the rest to 1, and we are only allowing for enumerating
+ * all the devices on a bus we just scan the array for any
+ * positions where there a device is enabled and mark the bus
+ * to be enumerated.
+ */
+ bus_mask = 0 ;
+ media_mask = 0 ;
+ media_mask = 0 ;
+ for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) {
+ for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++) {
+ if (config_p->devices_to_enumerate[bus][device] ==
+ cy_true) {
+ bus_mask |= (0x01 << bus) ;
+ media_mask |= dev_p->media_supported[bus] ;
+ media_mask |= dev_p->media_supported[bus] ;
+ }
+ }
+ }
+
+ return my_usb_set_enum_config(dev_p, bus_mask, media_mask,
+ config_p->antioch_enumeration,
+ config_p->mass_storage_interface,
+ config_p->mtp_interface,
+ config_p->mass_storage_callbacks,
+ cb,
+ client
+ ) ;
+}
+
+
+static cy_as_return_status_t
+my_handle_response_get_enum_config(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ void *config_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t val ;
+ uint8_t bus_mask ;
+ uint32_t bus ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_USB_CONFIG) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ /* Marshal the reply */
+ if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
+ uint32_t device ;
+ cy_bool state;
+ cy_as_usb_enum_control *ms_config_p =
+ (cy_as_usb_enum_control *)config_p;
+
+ bus_mask = (uint8_t)
+ (cy_as_ll_request_response__get_word
+ (reply_p, 0) & 0xFF) ;
+ for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) {
+ if (bus_mask & (1 << bus))
+ state = cy_true ;
+ else
+ state = cy_false ;
+
+ for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES;
+ device++)
+ ms_config_p->devices_to_enumerate[bus][device]
+ = state ;
+ }
+
+ ms_config_p->antioch_enumeration =
+ (cy_bool)cy_as_ll_request_response__get_word
+ (reply_p, 1) ;
+
+ val = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ if (dev_p->is_mtp_firmware) {
+ ms_config_p->mass_storage_interface = 0 ;
+ ms_config_p->mtp_interface = (uint8_t)(val & 0xFF) ;
+ } else {
+ ms_config_p->mass_storage_interface =
+ (uint8_t)(val & 0xFF) ;
+ ms_config_p->mtp_interface = 0 ;
+ }
+ ms_config_p->mass_storage_callbacks = (cy_bool)(val >> 8) ;
+
+ /*
+ * firmware returns an invalid interface number for mass storage,
+ * if mass storage is not enabled. this needs to be converted to
+ * zero to match the input configuration.
+ */
+ if (bus_mask == 0) {
+ if (dev_p->is_mtp_firmware)
+ ms_config_p->mtp_interface = 0 ;
+ else
+ ms_config_p->mass_storage_interface = 0 ;
+ }
+ } else {
+ cy_as_usb_enum_control_dep *ex_config_p =
+ (cy_as_usb_enum_control_dep *)config_p;
+
+ ex_config_p->enum_mass_storage = (uint8_t)
+ ((cy_as_ll_request_response__get_word
+ (reply_p, 0) >> 8) & 0xFF) ;
+ ex_config_p->antioch_enumeration = (cy_bool)
+ cy_as_ll_request_response__get_word(reply_p, 1) ;
+
+ val = cy_as_ll_request_response__get_word(reply_p, 2) ;
+ ex_config_p->mass_storage_interface = (uint8_t)(val & 0xFF) ;
+ ex_config_p->mass_storage_callbacks = (cy_bool)(val >> 8) ;
+
+ /*
+ * firmware returns an invalid interface number for mass
+ * storage, if mass storage is not enabled. this needs to
+ * be converted to zero to match the input configuration.
+ */
+ if (ex_config_p->enum_mass_storage == 0)
+ ex_config_p->mass_storage_interface = 0 ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+* This sets up the request for the enumerateion configuration
+* information, based on if the request is from the old pre-1.2
+* functions.
+*/
+static cy_as_return_status_t
+my_usb_get_enum_config(cy_as_device_handle handle,
+ uint16_t req_flags,
+ void *config_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_get_enum_config called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_GET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 0) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed two bytes */
+ reply_p = cy_as_ll_create_response(dev_p, 3) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ /* we need to know the type of request to
+ * know how to manage the data */
+ req_p->flags |= req_flags;
+ return my_handle_response_get_enum_config(dev_p,
+ req_p, reply_p, config_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_GETENUMCONFIG, config_p,
+ dev_p->func_cbs_usb, req_flags, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+ * This method returns the enumerateion configuration information
+ * from the West Bridge device. Generally this is not used by
+ * client software but is provided mostly for debug information.
+ * We want a method to read all state information from the device.
+ */
+cy_as_return_status_t
+cy_as_usb_get_enum_config(cy_as_device_handle handle,
+ cy_as_usb_enum_control *config_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ return my_usb_get_enum_config(handle,
+ CY_AS_REQUEST_RESPONSE_MS, config_p, cb, client);
+}
+
+
+/*
+* This method sets the USB descriptor for a given entity.
+*/
+cy_as_return_status_t
+cy_as_usb_set_descriptor(cy_as_device_handle handle,
+ cy_as_usb_desc_type type,
+ uint8_t index,
+ void *desc_p,
+ uint16_t length,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint16_t pktlen ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_set_descriptor called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (length > CY_AS_MAX_USB_DESCRIPTOR_SIZE)
+ return CY_AS_ERROR_INVALID_DESCRIPTOR ;
+
+ pktlen = (uint16_t)length / 2 ;
+ if (length % 2)
+ pktlen++ ;
+ pktlen += 2 ; /* 1 for type, 1 for length */
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_DESCRIPTOR,
+ CY_RQT_USB_RQT_CONTEXT, (uint16_t)pktlen) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((uint8_t)type | (index << 8))) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)length) ;
+ cy_as_ll_request_response__pack(req_p, 2, length, desc_p) ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_no_data(dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_SETDESCRIPTOR, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+ * This method clears all descriptors that were previously
+ * stored on the West Bridge through CyAsUsbSetDescriptor calls.
+ */
+cy_as_return_status_t
+cy_as_usb_clear_descriptors(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_clear_descriptors called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if ((cy_as_device_is_in_callback(dev_p)) && (cb == 0))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_CLEAR_DESCRIPTORS, CY_RQT_USB_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_no_data(dev_p, req_p, reply_p) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_CLEARDESCRIPTORS, 0,
+ dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_get_descriptor(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_get_descriptor_data *data)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint32_t retlen ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ goto destroy ;
+ } else if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_USB_DESCRIPTOR) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ retlen = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ if (retlen > data->length) {
+ ret = CY_AS_ERROR_INVALID_SIZE ;
+ goto destroy ;
+ }
+
+ ret = CY_AS_ERROR_SUCCESS ;
+ cy_as_ll_request_response__unpack(reply_p, 1,
+ retlen, data->desc_p) ;
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+/*
+* This method retreives the USB descriptor for a given type.
+*/
+cy_as_return_status_t
+cy_as_usb_get_descriptor(cy_as_device_handle handle,
+ cy_as_usb_desc_type type,
+ uint8_t index,
+ cy_as_get_descriptor_data *data,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_get_descriptor called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_GET_DESCRIPTOR, CY_RQT_USB_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((uint8_t)type | (index << 8))) ;
+
+ /* Add one for the length field */
+ reply_p = cy_as_ll_create_response(dev_p,
+ CY_AS_MAX_USB_DESCRIPTOR_SIZE + 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(
+ dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return my_handle_response_get_descriptor(dev_p,
+ req_p, reply_p, data) ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_GETDESCRIPTOR, data,
+ dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p,
+ reply_p, cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_set_physical_configuration(cy_as_device_handle handle,
+ uint8_t config)
+{
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6,
+ "cy_as_usb_set_physical_configuration called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ if (config < 1 || config > 12)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ dev_p->usb_phy_config = config ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static cy_bool
+is_physical_valid(uint8_t config, cy_as_end_point_number_t ep)
+{
+ static uint8_t validmask[12] = {
+ 0x0f, /* Config 1 - 1, 2, 3, 4 */
+ 0x07, /* Config 2 - 1, 2, 3 */
+ 0x07, /* Config 3 - 1, 2, 3 */
+ 0x0d, /* Config 4 - 1, 3, 4 */
+ 0x05, /* Config 5 - 1, 3 */
+ 0x05, /* Config 6 - 1, 3 */
+ 0x0d, /* Config 7 - 1, 3, 4 */
+ 0x05, /* Config 8 - 1, 3 */
+ 0x05, /* Config 9 - 1, 3 */
+ 0x0d, /* Config 10 - 1, 3, 4 */
+ 0x09, /* Config 11 - 1, 4 */
+ 0x01 /* Config 12 - 1 */
+ } ;
+
+ return (validmask[config - 1] & (1 << (ep - 1))) ? cy_true : cy_false ;
+}
+
+/*
+* This method sets the configuration for an endpoint
+*/
+cy_as_return_status_t
+cy_as_usb_set_end_point_config(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, cy_as_usb_end_point_config *config_p)
+{
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_set_end_point_config called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ if (ep == 0) {
+ /* Endpoint 0 must be 64 byte, dir IN/OUT,
+ * and control type */
+ if (config_p->dir != cy_as_usb_in_out ||
+ config_p->type != cy_as_usb_control)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+ } else if (ep == 1) {
+ if ((dev_p->is_mtp_firmware == 1) &&
+ (dev_p->usb_config[1].enabled == cy_true)) {
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+ }
+
+ /*
+ * EP1 can only be used either as an OUT ep, or as an IN ep.
+ */
+ if ((config_p->type == cy_as_usb_control) ||
+ (config_p->type == cy_as_usb_iso) ||
+ (config_p->dir == cy_as_usb_in_out))
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+ } else {
+ if (config_p->dir == cy_as_usb_in_out ||
+ config_p->type == cy_as_usb_control)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (!is_physical_valid(dev_p->usb_phy_config,
+ config_p->physical))
+ return CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT ;
+
+ /*
+ * ISO endpoints must be on E_ps 3, 5, 7 or 9 as
+ * they need to align directly with the underlying
+ * physical endpoint.
+ */
+ if (config_p->type == cy_as_usb_iso) {
+ if (ep != 3 && ep != 5 && ep != 7 && ep != 9)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (ep == 3 && config_p->physical != 1)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (ep == 5 && config_p->physical != 2)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (ep == 7 && config_p->physical != 3)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+ if (ep == 9 && config_p->physical != 4)
+ return CY_AS_ERROR_INVALID_CONFIGURATION ;
+ }
+ }
+
+ /* Store the configuration information until a
+ * CyAsUsbCommitConfig is done */
+ dev_p->usb_config[ep] = *config_p ;
+
+ /* If the endpoint is enabled, enable DMA associated
+ * with the endpoint */
+ /*
+ * we make some assumptions that we check here. we assume
+ * that the direction fields for the DMA module are the same
+ * values as the direction values for the USB module.
+ */
+ cy_as_hal_assert((int)cy_as_usb_in == (int)cy_as_direction_in);
+ cy_as_hal_assert((int)cy_as_usb_out == (int)cy_as_direction_out);
+ cy_as_hal_assert((int)cy_as_usb_in_out == (int)cy_as_direction_in_out) ;
+
+ return cy_as_dma_enable_end_point(dev_p, ep,
+ config_p->enabled, (cy_as_dma_direction)config_p->dir) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_get_end_point_config(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, cy_as_usb_end_point_config *config_p)
+{
+ cy_as_return_status_t ret ;
+
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_get_end_point_config called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ *config_p = dev_p->usb_config[ep] ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* Commit the configuration of the various endpoints to the hardware.
+*/
+cy_as_return_status_t
+cy_as_usb_commit_config(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ uint32_t i ;
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ cy_as_device *dev_p ;
+ uint16_t data ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_commit_config called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_usb_connected(dev_p))
+ return CY_AS_ERROR_USB_CONNECTED ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /*
+ * this performs the mapping based on informatation that was
+ * previously stored on the device about the various endpoints
+ * and how they are configured. the output of this mapping is
+ * setting the the 14 register values contained in usb_lepcfg
+ * and usb_pepcfg
+ */
+ ret = cy_as_usb_map_logical2_physical(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /*
+ * now, package the information about the various logical and
+ * physical endpoint configuration registers and send it
+ * across to the west bridge device.
+ */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_SET_USB_CONFIG_REGISTERS, CY_RQT_USB_RQT_CONTEXT, 8) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_hal_print_message("USB configuration: %d\n",
+ dev_p->usb_phy_config) ;
+ cy_as_hal_print_message("EP1OUT: 0x%02x EP1IN: 0x%02x\n",
+ dev_p->usb_ep1cfg[0], dev_p->usb_ep1cfg[1]) ;
+ cy_as_hal_print_message("PEP registers: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ dev_p->usb_pepcfg[0], dev_p->usb_pepcfg[1],
+ dev_p->usb_pepcfg[2], dev_p->usb_pepcfg[3]) ;
+
+ cy_as_hal_print_message("LEP registers: 0x%02x 0x%02x 0x%02x "
+ "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ dev_p->usb_lepcfg[0], dev_p->usb_lepcfg[1],
+ dev_p->usb_lepcfg[2], dev_p->usb_lepcfg[3],
+ dev_p->usb_lepcfg[4], dev_p->usb_lepcfg[5],
+ dev_p->usb_lepcfg[6], dev_p->usb_lepcfg[7],
+ dev_p->usb_lepcfg[8], dev_p->usb_lepcfg[9]) ;
+
+ /* Write the EP1OUTCFG and EP1INCFG data in the first word. */
+ data = (uint16_t)((dev_p->usb_ep1cfg[0] << 8) |
+ dev_p->usb_ep1cfg[1]) ;
+ cy_as_ll_request_response__set_word(req_p, 0, data) ;
+
+ /* Write the PEP CFG data in the next 2 words */
+ for (i = 0 ; i < 4 ; i += 2) {
+ data = (uint16_t)((dev_p->usb_pepcfg[i] << 8) |
+ dev_p->usb_pepcfg[i + 1]) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 1 + i / 2, data) ;
+ }
+
+ /* Write the LEP CFG data in the next 5 words */
+ for (i = 0 ; i < 10 ; i += 2) {
+ data = (uint16_t)((dev_p->usb_lepcfg[i] << 8) |
+ dev_p->usb_lepcfg[i + 1]) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 3 + i / 2, data) ;
+ }
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ ret = my_handle_response_no_data(dev_p,
+ req_p, reply_p) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = cy_as_usb_setup_dma(dev_p) ;
+
+ return ret ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_COMMITCONFIG, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static void
+sync_request_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p,
+ uint32_t size, cy_as_return_status_t err)
+{
+ (void)ep ;
+ (void)buf_p ;
+
+ dev_p->usb_error = err ;
+ dev_p->usb_actual_cnt = size ;
+}
+
+static void
+async_read_request_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p,
+ uint32_t size, cy_as_return_status_t err)
+{
+ cy_as_device_handle h ;
+
+ cy_as_log_debug_message(6,
+ "async_read_request_callback called") ;
+
+ h = (cy_as_device_handle)dev_p ;
+
+ if (ep == 0 && cy_as_device_is_ack_delayed(dev_p)) {
+ dev_p->usb_pending_buffer = buf_p ;
+ dev_p->usb_pending_size = size ;
+ dev_p->usb_error = err ;
+ cy_as_usb_ack_setup_packet(h, usb_ack_callback, 0) ;
+ } else {
+ cy_as_usb_io_callback cb ;
+
+ cb = dev_p->usb_cb[ep] ;
+ dev_p->usb_cb[ep] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p, ep) ;
+ if (cb)
+ cb(h, ep, size, buf_p, err) ;
+ }
+}
+
+static void
+async_write_request_callback(cy_as_device *dev_p,
+ cy_as_end_point_number_t ep, void *buf_p,
+ uint32_t size, cy_as_return_status_t err)
+{
+ cy_as_device_handle h ;
+
+ cy_as_log_debug_message(6,
+ "async_write_request_callback called") ;
+
+ h = (cy_as_device_handle)dev_p ;
+
+ if (ep == 0 && cy_as_device_is_ack_delayed(dev_p)) {
+ dev_p->usb_pending_buffer = buf_p ;
+ dev_p->usb_pending_size = size ;
+ dev_p->usb_error = err ;
+
+ /* The west bridge protocol generates ZLPs as required. */
+ cy_as_usb_ack_setup_packet(h, usb_ack_callback, 0) ;
+ } else {
+ cy_as_usb_io_callback cb ;
+
+ cb = dev_p->usb_cb[ep] ;
+ dev_p->usb_cb[ep] = 0 ;
+
+ cy_as_device_clear_usb_async_pending(dev_p, ep) ;
+ if (cb)
+ cb(h, ep, size, buf_p, err) ;
+ }
+}
+
+static void
+my_turbo_rqt_callback(cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ uint8_t code ;
+
+ (void)context ;
+ (void)stat ;
+
+ /* The Handlers are responsible for Deleting the rqt and resp when
+ * they are finished
+ */
+ code = cy_as_ll_request_response__get_code(rqt) ;
+ switch (code) {
+ case CY_RQT_TURBO_SWITCH_ENDPOINT:
+ cy_as_hal_assert(stat == CY_AS_ERROR_SUCCESS) ;
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+ cy_as_ll_destroy_response(dev_p, resp) ;
+ break;
+ default:
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+}
+
+/* Send a mailbox request to prepare the endpoint for switching */
+static cy_as_return_status_t
+my_send_turbo_switch(cy_as_device *dev_p, uint32_t size, cy_bool pktread)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+
+ /* Create the request to send to the West Bridge device */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_TURBO_SWITCH_ENDPOINT, CY_RQT_TUR_RQT_CONTEXT, 3) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Reserve space for the reply, the reply data will
+ * not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)pktread) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((size >> 16) & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(size & 0xFFFF)) ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p,
+ reply_p, cy_false, my_turbo_rqt_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_request(dev_p, reply_p) ;
+ return ret ;
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+cy_as_return_status_t
+cy_as_usb_read_data(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, cy_bool pktread,
+ uint32_t dsize, uint32_t *dataread, void *data)
+{
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_read_data called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (ep >= 16 || ep == 4 || ep == 6 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* EP2 is available for reading when MTP is active */
+ if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* If the endpoint is disabled, we cannot
+ * write data to the endpoint */
+ if (!dev_p->usb_config[ep].enabled)
+ return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+ if (dev_p->usb_config[ep].dir != cy_as_usb_out)
+ return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+ ret = cy_as_dma_queue_request(dev_p, ep, data, dsize,
+ pktread, cy_true, sync_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (ep == CY_AS_MTP_READ_ENDPOINT) {
+ ret = my_send_turbo_switch(dev_p, dsize, pktread) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, ret) ;
+ return ret ;
+ }
+
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_false) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ } else {
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_true) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ ret = dev_p->usb_error ;
+ *dataread = dev_p->usb_actual_cnt ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_read_data_async(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, cy_bool pktread,
+ uint32_t dsize, void *data, cy_as_usb_io_callback cb)
+{
+ cy_as_return_status_t ret ;
+ uint32_t mask ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_read_data_async called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (ep >= 16 || ep == 4 || ep == 6 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* EP2 is available for reading when MTP is active */
+ if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* If the endpoint is disabled, we cannot
+ * write data to the endpoint */
+ if (!dev_p->usb_config[ep].enabled)
+ return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+ if (dev_p->usb_config[ep].dir != cy_as_usb_out &&
+ dev_p->usb_config[ep].dir != cy_as_usb_in_out)
+ return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+ /*
+ * since async operations can be triggered by interrupt
+ * code, we must insure that we do not get multiple async
+ * operations going at one time and protect this test and
+ * set operation from interrupts.
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+ if (cy_as_device_is_usb_async_pending(dev_p, ep)) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+ cy_as_device_set_usb_async_pending(dev_p, ep) ;
+
+ /*
+ * if this is for EP0, we set this bit to delay the
+ * ACK response until after this read has completed.
+ */
+ if (ep == 0)
+ cy_as_device_set_ack_delayed(dev_p) ;
+
+ cy_as_hal_enable_interrupts(mask) ;
+
+ cy_as_hal_assert(dev_p->usb_cb[ep] == 0) ;
+ dev_p->usb_cb[ep] = cb ;
+
+ ret = cy_as_dma_queue_request(dev_p, ep, data, dsize,
+ pktread, cy_true, async_read_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (ep == CY_AS_MTP_READ_ENDPOINT) {
+ ret = my_send_turbo_switch(dev_p, dsize, pktread) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, ret) ;
+ return ret ;
+ }
+ } else {
+ /* Kick start the queue if it is not running */
+ cy_as_dma_kick_start(dev_p, ep) ;
+ }
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_write_data(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, uint32_t dsize, void *data)
+{
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_write_data called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (ep >= 16 || ep == 2 || ep == 4 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* EP6 is available for writing when MTP is active */
+ if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* If the endpoint is disabled, we cannot
+ * write data to the endpoint */
+ if (!dev_p->usb_config[ep].enabled)
+ return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+ if (dev_p->usb_config[ep].dir != cy_as_usb_in &&
+ dev_p->usb_config[ep].dir != cy_as_usb_in_out)
+ return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+ /* Write on Turbo endpoint */
+ if (ep == CY_AS_MTP_WRITE_ENDPOINT) {
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST,
+ CY_RQT_TUR_RQT_CONTEXT, 3) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p,
+ 0, 0x0006) ; /* EP number to use. */
+ cy_as_ll_request_response__set_word(req_p,
+ 1, (uint16_t)((dsize >> 16) & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p,
+ 2, (uint16_t)(dsize & 0xFFFF)) ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (dsize) {
+ ret = cy_as_dma_queue_request(dev_p,
+ ep, data, dsize, cy_false,
+ cy_false, sync_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word
+ (reply_p, 0);
+ }
+
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (dsize)
+ cy_as_dma_cancel(dev_p, ep, ret) ;
+ return ret ;
+ }
+
+ /* If this is a zero-byte write, firmware will
+ * handle it. there is no need to do any work here.
+ */
+ if (!dsize)
+ return CY_AS_ERROR_SUCCESS ;
+ } else {
+ ret = cy_as_dma_queue_request(dev_p, ep, data, dsize,
+ cy_false, cy_false, sync_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ if (ep != CY_AS_MTP_WRITE_ENDPOINT)
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_true) ;
+ else
+ ret = cy_as_dma_drain_queue(dev_p, ep, cy_false) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ ret = dev_p->usb_error ;
+ return ret ;
+}
+
+static void
+mtp_write_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ cy_as_usb_io_callback cb ;
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+
+ cy_as_hal_assert(context == CY_RQT_TUR_RQT_CONTEXT) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ }
+
+ /* If this was a zero byte transfer request, we can
+ * call the callback from here. */
+ if ((cy_as_ll_request_response__get_word(rqt, 1) == 0) &&
+ (cy_as_ll_request_response__get_word(rqt, 2) == 0)) {
+ cb = dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT] ;
+ dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p,
+ CY_AS_MTP_WRITE_ENDPOINT) ;
+ if (cb)
+ cb(h, CY_AS_MTP_WRITE_ENDPOINT, 0, 0, ret) ;
+
+ goto destroy ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ /* Firmware failed the request. Cancel the DMA transfer. */
+ cy_as_dma_cancel(dev_p, 0x06, CY_AS_ERROR_CANCELED) ;
+ dev_p->usb_cb[0x06] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p, 0x06) ;
+ }
+
+destroy:
+ cy_as_ll_destroy_response(dev_p, resp) ;
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_write_data_async(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep, uint32_t dsize, void *data,
+ cy_bool spacket, cy_as_usb_io_callback cb)
+{
+ uint32_t mask ;
+ cy_as_return_status_t ret ;
+ cy_as_device *dev_p ;
+
+ cy_as_log_debug_message(6, "cy_as_usb_write_data_async called") ;
+
+ dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (ep >= 16 || ep == 2 || ep == 4 || ep == 8)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* EP6 is available for writing when MTP is active */
+ if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT)
+ return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+ /* If the endpoint is disabled, we cannot
+ * write data to the endpoint */
+ if (!dev_p->usb_config[ep].enabled)
+ return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+ if (dev_p->usb_config[ep].dir != cy_as_usb_in &&
+ dev_p->usb_config[ep].dir != cy_as_usb_in_out)
+ return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+ /*
+ * since async operations can be triggered by interrupt
+ * code, we must insure that we do not get multiple
+ * async operations going at one time and
+ * protect this test and set operation from interrupts.
+ */
+ mask = cy_as_hal_disable_interrupts() ;
+ if (cy_as_device_is_usb_async_pending(dev_p, ep)) {
+ cy_as_hal_enable_interrupts(mask) ;
+ return CY_AS_ERROR_ASYNC_PENDING ;
+ }
+
+ cy_as_device_set_usb_async_pending(dev_p, ep) ;
+
+ if (ep == 0)
+ cy_as_device_set_ack_delayed(dev_p) ;
+
+ cy_as_hal_enable_interrupts(mask) ;
+
+ cy_as_hal_assert(dev_p->usb_cb[ep] == 0) ;
+ dev_p->usb_cb[ep] = cb ;
+ dev_p->usb_spacket[ep] = spacket ;
+
+ /* Write on Turbo endpoint */
+ if (ep == CY_AS_MTP_WRITE_ENDPOINT) {
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST,
+ CY_RQT_TUR_RQT_CONTEXT, 3) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ 0x0006) ; /* EP number to use. */
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)((dsize >> 16) & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)(dsize & 0xFFFF)) ;
+
+ /* Reserve space for the reply, the reply data
+ * will not exceed one word */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (dsize) {
+ ret = cy_as_dma_queue_request(dev_p, ep, data,
+ dsize, cy_false, cy_false,
+ async_write_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_false, mtp_write_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (dsize)
+ cy_as_dma_cancel(dev_p, ep, ret) ;
+ return ret ;
+ }
+
+ /* Firmware will handle a zero byte transfer
+ * without any DMA transfers. */
+ if (!dsize)
+ return CY_AS_ERROR_SUCCESS ;
+ } else {
+ ret = cy_as_dma_queue_request(dev_p, ep, data, dsize,
+ cy_false, cy_false, async_write_request_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+ }
+
+ /* Kick start the queue if it is not running */
+ if (ep != CY_AS_MTP_WRITE_ENDPOINT)
+ cy_as_dma_kick_start(dev_p, ep) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+my_usb_cancel_async_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ uint8_t ep ;
+ (void)context ;
+
+ ep = (uint8_t)cy_as_ll_request_response__get_word(rqt, 0) ;
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ }
+
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+ cy_as_ll_destroy_response(dev_p, resp) ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ dev_p->usb_cb[ep] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p, ep) ;
+ }
+}
+
+cy_as_return_status_t
+cy_as_usb_cancel_async(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p, *reply_p ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ep &= 0x7F; /* Remove the direction bit. */
+ if (!cy_as_device_is_usb_async_pending(dev_p, ep))
+ return CY_AS_ERROR_ASYNC_NOT_PENDING;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_suspend_mode(dev_p))
+ return CY_AS_ERROR_IN_SUSPEND ;
+
+ if ((ep == CY_AS_MTP_WRITE_ENDPOINT) ||
+ (ep == CY_AS_MTP_READ_ENDPOINT)) {
+ /* Need firmware support for the cancel operation. */
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_CANCEL_ASYNC_TRANSFER,
+ CY_RQT_TUR_RQT_CONTEXT, 1) ;
+
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)ep) ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_false, my_usb_cancel_async_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ return ret ;
+ }
+ } else {
+ ret = cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ dev_p->usb_cb[ep] = 0 ;
+ cy_as_device_clear_usb_async_pending(dev_p, ep) ;
+ }
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+cy_as_usb_ack_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t ret)
+{
+ cy_as_func_c_b_node *node = (cy_as_func_c_b_node *)
+ dev_p->func_cbs_usb->head_p ;
+
+ (void)context ;
+
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ if (cy_as_ll_request_response__get_code(resp) !=
+ CY_RESP_SUCCESS_FAILURE)
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ else
+ ret = cy_as_ll_request_response__get_word(resp, 0) ;
+ }
+
+ node->cb_p((cy_as_device_handle)dev_p, ret,
+ node->client_data, node->data_type, node->data) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_usb) ;
+
+ cy_as_ll_destroy_request(dev_p, rqt) ;
+ cy_as_ll_destroy_response(dev_p, resp) ;
+ cy_as_device_clear_ack_delayed(dev_p) ;
+}
+
+static cy_as_return_status_t
+cy_as_usb_ack_setup_packet(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p ;
+ cy_as_ll_request_response *reply_p ;
+ cy_as_func_c_b_node *cbnode ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p) && cb == 0)
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ cy_as_hal_assert(cb != 0) ;
+
+ cbnode = cy_as_create_func_c_b_node(cb, client);
+ if (cbnode == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ req_p = cy_as_ll_create_request(dev_p, 0,
+ CY_RQT_USB_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ cy_as_ll_init_request(req_p, CY_RQT_ACK_SETUP_PACKET,
+ CY_RQT_USB_RQT_CONTEXT, 1) ;
+ cy_as_ll_init_response(reply_p, 1) ;
+
+ req_p->flags |= CY_AS_REQUEST_RESPONSE_EX ;
+
+ cy_as_insert_c_b_node(dev_p->func_cbs_usb, cbnode) ;
+
+ ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
+ cy_false, cy_as_usb_ack_callback) ;
+
+ return ret ;
+}
+
+/*
+ * Flush all data in logical EP that is being NAK-ed or
+ * Stall-ed, so that this does not continue to block data
+ * on other LEPs that use the same physical EP.
+ */
+static void
+cy_as_usb_flush_logical_e_p(
+ cy_as_device *dev_p,
+ uint16_t ep)
+{
+ uint16_t addr, val, count ;
+
+ addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
+ val = cy_as_hal_read_register(dev_p->tag, addr) ;
+
+ while (val) {
+ count = ((val & 0xFFF) + 1) / 2 ;
+ while (count--)
+ val = cy_as_hal_read_register(dev_p->tag, ep) ;
+
+ cy_as_hal_write_register(dev_p->tag, addr, 0) ;
+ val = cy_as_hal_read_register(dev_p->tag, addr) ;
+ }
+}
+
+static cy_as_return_status_t
+cy_as_usb_nak_stall_request(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ uint16_t request,
+ cy_bool state,
+ cy_as_usb_function_callback cb,
+ cy_as_function_callback fcb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ uint16_t data ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ if (cb)
+ cy_as_hal_assert(fcb == 0) ;
+ if (fcb)
+ cy_as_hal_assert(cb == 0) ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p) && cb == 0 && fcb == 0)
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ request, CY_RQT_USB_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Set the endpoint */
+ data = (uint8_t)ep ;
+ cy_as_ll_request_response__set_word(req_p, 0, data) ;
+
+ /* Set stall state to stalled */
+ cy_as_ll_request_response__set_word(req_p, 1, (uint8_t)state) ;
+
+ if (cb || fcb) {
+ void *cbnode ;
+ cy_as_c_b_queue *queue ;
+ if (cb) {
+ cbnode = cy_as_create_usb_func_c_b_node(cb, client) ;
+ queue = dev_p->usb_func_cbs ;
+ } else {
+ cbnode = cy_as_create_func_c_b_node(fcb, client) ;
+ queue = dev_p->func_cbs_usb ;
+ req_p->flags |= CY_AS_REQUEST_RESPONSE_EX ;
+ }
+
+ if (cbnode == 0) {
+ ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+ goto destroy ;
+ } else
+ cy_as_insert_c_b_node(queue, cbnode) ;
+
+
+ if (cy_as_device_is_setup_packet(dev_p)) {
+ /* No Ack is needed on a stall request on EP0 */
+ if ((state == cy_true) && (ep == 0)) {
+ cy_as_device_set_ep0_stalled(dev_p) ;
+ } else {
+ cy_as_device_set_ack_delayed(dev_p) ;
+ req_p->flags |=
+ CY_AS_REQUEST_RESPONSE_DELAY_ACK ;
+ }
+ }
+
+ ret = cy_as_ll_send_request(dev_p, req_p,
+ reply_p, cy_false, cy_as_usb_func_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ if (req_p->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK)
+ cy_as_device_rem_ack_delayed(dev_p) ;
+ cy_as_remove_c_b_tail_node(queue) ;
+
+ goto destroy ;
+ }
+ } else {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) !=
+ CY_RESP_SUCCESS_FAILURE) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+
+ if ((ret == CY_AS_ERROR_SUCCESS) &&
+ (request == CY_RQT_STALL_ENDPOINT)) {
+ if ((ep > 1) && (state != 0) &&
+ (dev_p->usb_config[ep].dir == cy_as_usb_out))
+ cy_as_usb_flush_logical_e_p(dev_p, ep) ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+ }
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_get_stall(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_bool *state_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code = cy_as_ll_request_response__get_code(reply_p) ;
+
+ if (code == CY_RESP_SUCCESS_FAILURE) {
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ goto destroy ;
+ } else if (code != CY_RESP_ENDPOINT_STALL) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ *state_p = (cy_bool)cy_as_ll_request_response__get_word(reply_p, 0) ;
+ ret = CY_AS_ERROR_SUCCESS ;
+
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+my_handle_response_get_nak(cy_as_device *dev_p,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_bool *state_p)
+{
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+ uint8_t code = cy_as_ll_request_response__get_code(reply_p) ;
+
+ if (code == CY_RESP_SUCCESS_FAILURE) {
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ goto destroy ;
+ } else if (code != CY_RESP_ENDPOINT_NAK) {
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ goto destroy ;
+ }
+
+ *state_p = (cy_bool)cy_as_ll_request_response__get_word(reply_p, 0) ;
+ ret = CY_AS_ERROR_SUCCESS ;
+
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static cy_as_return_status_t
+cy_as_usb_get_nak_stall(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ uint16_t request,
+ uint16_t response,
+ cy_bool *state_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ uint16_t data ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+
+ (void)response ;
+
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p) && !cb)
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ req_p = cy_as_ll_create_request(dev_p, request,
+ CY_RQT_USB_RQT_CONTEXT, 1) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* Set the endpoint */
+ data = (uint8_t)ep ;
+ cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)ep) ;
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p,
+ req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (request == CY_RQT_GET_STALL)
+ return my_handle_response_get_stall(dev_p,
+ req_p, reply_p, state_p) ;
+ else
+ return my_handle_response_get_nak(dev_p,
+ req_p, reply_p, state_p) ;
+
+ } else {
+ cy_as_funct_c_b_type type ;
+
+ if (request == CY_RQT_GET_STALL)
+ type = CY_FUNCT_CB_USB_GETSTALL ;
+ else
+ type = CY_FUNCT_CB_USB_GETNAK ;
+
+ ret = cy_as_misc_send_request(dev_p, cb, client, type,
+ state_p, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_set_nak(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate direction
+ * bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_count > 0)
+ return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+ return cy_as_usb_nak_stall_request(handle, ep,
+ CY_RQT_ENDPOINT_SET_NAK, cy_true, 0, cb, client) ;
+}
+
+
+cy_as_return_status_t
+cy_as_usb_clear_nak(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate
+ * direction bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_count > 0)
+ return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+ return cy_as_usb_nak_stall_request(handle, ep,
+ CY_RQT_ENDPOINT_SET_NAK, cy_false, 0, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_get_nak(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_bool *nak_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate
+ * direction bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_count > 0)
+ return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+ return cy_as_usb_get_nak_stall(handle, ep,
+ CY_RQT_GET_ENDPOINT_NAK, CY_RESP_ENDPOINT_NAK,
+ nak_p, cb, client) ;
+}
+
+
+cy_as_return_status_t
+cy_as_usb_set_stall(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate
+ * direction bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_turbo_active)
+ return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+ return cy_as_usb_nak_stall_request(handle, ep,
+ CY_RQT_STALL_ENDPOINT, cy_true, 0, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_clear_stall(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate
+ * direction bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_turbo_active)
+ return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+ return cy_as_usb_nak_stall_request(handle, ep,
+ CY_RQT_STALL_ENDPOINT, cy_false, 0, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_get_stall(cy_as_device_handle handle,
+ cy_as_end_point_number_t ep,
+ cy_bool *stall_p,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ /*
+ * we send the firmware the EP# with the appropriate
+ * direction bit, regardless of what the user gave us.
+ */
+ ep &= 0x0f ;
+ if (dev_p->usb_config[ep].dir == cy_as_usb_in)
+ ep |= 0x80 ;
+
+ if (dev_p->mtp_turbo_active)
+ return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+ return cy_as_usb_get_nak_stall(handle, ep,
+ CY_RQT_GET_STALL, CY_RESP_ENDPOINT_STALL, stall_p, cb, client) ;
+}
+
+cy_as_return_status_t
+cy_as_usb_signal_remote_wakeup(cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if (cy_as_device_is_in_callback(dev_p))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ if (dev_p->usb_last_event != cy_as_event_usb_suspend)
+ return CY_AS_ERROR_NOT_IN_SUSPEND ;
+
+ req_p = cy_as_ll_create_request(dev_p,
+ CY_RQT_USB_REMOTE_WAKEUP, CY_RQT_USB_RQT_CONTEXT, 0) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_SIGNALREMOTEWAKEUP, 0,
+ dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p,
+ reply_p, cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_set_m_s_report_threshold(cy_as_device_handle handle,
+ uint32_t wr_sectors,
+ uint32_t rd_sectors,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ if ((cb == 0) && (cy_as_device_is_in_callback(dev_p)))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ /* Check if the firmware version supports this feature. */
+ if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] ==
+ (1 << cy_as_media_nand)))
+ return CY_AS_ERROR_NOT_SUPPORTED ;
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_USB_STORAGE_MONITOR,
+ CY_RQT_USB_RQT_CONTEXT, 4) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Set the read and write count parameters into
+ * the request structure. */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((wr_sectors >> 16) & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 1,
+ (uint16_t)(wr_sectors & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 2,
+ (uint16_t)((rd_sectors >> 16) & 0xFFFF)) ;
+ cy_as_ll_request_response__set_word(req_p, 3,
+ (uint16_t)(rd_sectors & 0xFFFF)) ;
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_USB_SET_MSREPORT_THRESHOLD, 0,
+ dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX,
+ req_p, reply_p, cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+cy_as_return_status_t
+cy_as_usb_select_m_s_partitions(
+ cy_as_device_handle handle,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_usb_m_s_type_t type,
+ cy_as_function_callback cb,
+ uint32_t client)
+{
+ cy_as_return_status_t ret ;
+ cy_as_ll_request_response *req_p , *reply_p ;
+ uint16_t val ;
+
+ cy_as_device *dev_p = (cy_as_device *)handle ;
+ if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+ return CY_AS_ERROR_INVALID_HANDLE ;
+
+ ret = is_usb_active(dev_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ return ret ;
+
+ /* This API has to be made before SetEnumConfig is called. */
+ if (dev_p->usb_config[0].enabled)
+ return CY_AS_ERROR_INVALID_CALL_SEQUENCE ;
+
+ if ((cb == 0) && (cy_as_device_is_in_callback(dev_p)))
+ return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+ req_p = cy_as_ll_create_request(dev_p, CY_RQT_MS_PARTITION_SELECT,
+ CY_RQT_USB_RQT_CONTEXT, 2) ;
+ if (req_p == 0)
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+ /* A single status word response type */
+ reply_p = cy_as_ll_create_response(dev_p, 1) ;
+ if (reply_p == 0) {
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ return CY_AS_ERROR_OUT_OF_MEMORY ;
+ }
+
+ /* Set the read and write count parameters into
+ * the request structure. */
+ cy_as_ll_request_response__set_word(req_p, 0,
+ (uint16_t)((bus << 8) | device)) ;
+
+ val = 0 ;
+ if ((type == cy_as_usb_m_s_unit0) || (type == cy_as_usb_m_s_both))
+ val |= 1 ;
+ if ((type == cy_as_usb_m_s_unit1) || (type == cy_as_usb_m_s_both))
+ val |= (1 << 8) ;
+
+ cy_as_ll_request_response__set_word(req_p, 1, val) ;
+
+ if (cb == 0) {
+ ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+
+ if (cy_as_ll_request_response__get_code(reply_p) ==
+ CY_RESP_SUCCESS_FAILURE)
+ ret = cy_as_ll_request_response__get_word(reply_p, 0) ;
+ else
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ } else {
+ ret = cy_as_misc_send_request(dev_p, cb, client,
+ CY_FUNCT_CB_NODATA, 0, dev_p->func_cbs_usb,
+ CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+ cy_as_usb_func_callback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ goto destroy ;
+ return ret ;
+ }
+
+destroy:
+ cy_as_ll_destroy_request(dev_p, req_p) ;
+ cy_as_ll_destroy_response(dev_p, reply_p) ;
+
+ return ret ;
+}
+
+static void
+cy_as_usb_func_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_ll_request_response *rqt,
+ cy_as_ll_request_response *resp,
+ cy_as_return_status_t stat)
+{
+ cy_as_usb_func_c_b_node* node = (cy_as_usb_func_c_b_node *)
+ dev_p->usb_func_cbs->head_p ;
+ cy_as_func_c_b_node* fnode = (cy_as_func_c_b_node *)
+ dev_p->func_cbs_usb->head_p ;
+ cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
+
+ cy_as_device_handle h = (cy_as_device_handle)dev_p ;
+ cy_bool delayed_ack = (rqt->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK)
+ == CY_AS_REQUEST_RESPONSE_DELAY_ACK;
+ cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX)
+ == CY_AS_REQUEST_RESPONSE_EX ;
+ cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS)
+ == CY_AS_REQUEST_RESPONSE_MS ;
+ uint8_t code ;
+ uint8_t ep, state ;
+
+ if (!ex_request && !ms_request) {
+ cy_as_hal_assert(dev_p->usb_func_cbs->count != 0) ;
+ cy_as_hal_assert(dev_p->usb_func_cbs->type ==
+ CYAS_USB_FUNC_CB) ;
+ } else {
+ cy_as_hal_assert(dev_p->func_cbs_usb->count != 0) ;
+ cy_as_hal_assert(dev_p->func_cbs_usb->type == CYAS_FUNC_CB) ;
+ }
+
+ (void)context ;
+
+ /* The Handlers are responsible for Deleting the rqt and resp when
+ * they are finished
+ */
+ code = cy_as_ll_request_response__get_code(rqt) ;
+ switch (code) {
+ case CY_RQT_START_USB:
+ ret = my_handle_response_usb_start(dev_p, rqt, resp, stat) ;
+ break ;
+ case CY_RQT_STOP_USB:
+ ret = my_handle_response_usb_stop(dev_p, rqt, resp, stat) ;
+ break ;
+ case CY_RQT_SET_CONNECT_STATE:
+ if (!cy_as_ll_request_response__get_word(rqt, 0))
+ ret = my_handle_response_disconnect(
+ dev_p, rqt, resp, stat) ;
+ else
+ ret = my_handle_response_connect(
+ dev_p, rqt, resp, stat) ;
+ break ;
+ case CY_RQT_GET_CONNECT_STATE:
+ break ;
+ case CY_RQT_SET_USB_CONFIG:
+ ret = my_handle_response_set_enum_config(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_GET_USB_CONFIG:
+ cy_as_hal_assert(fnode->data != 0) ;
+ ret = my_handle_response_get_enum_config(dev_p,
+ rqt, resp, fnode->data) ;
+ break ;
+ case CY_RQT_STALL_ENDPOINT:
+ ep = (uint8_t)cy_as_ll_request_response__get_word(rqt, 0) ;
+ state = (uint8_t)cy_as_ll_request_response__get_word(rqt, 1) ;
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ if ((ret == CY_AS_ERROR_SUCCESS) && (ep > 1) && (state != 0)
+ && (dev_p->usb_config[ep].dir == cy_as_usb_out))
+ cy_as_usb_flush_logical_e_p(dev_p, ep) ;
+ break ;
+ case CY_RQT_GET_STALL:
+ cy_as_hal_assert(fnode->data != 0) ;
+ ret = my_handle_response_get_stall(dev_p,
+ rqt, resp, (cy_bool *)fnode->data) ;
+ break ;
+ case CY_RQT_SET_DESCRIPTOR:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_GET_DESCRIPTOR:
+ cy_as_hal_assert(fnode->data != 0) ;
+ ret = my_handle_response_get_descriptor(dev_p,
+ rqt, resp, (cy_as_get_descriptor_data *)fnode->data) ;
+ break;
+ case CY_RQT_SET_USB_CONFIG_REGISTERS:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ if (ret == CY_AS_ERROR_SUCCESS)
+ ret = cy_as_usb_setup_dma(dev_p) ;
+ break ;
+ case CY_RQT_ENDPOINT_SET_NAK:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_GET_ENDPOINT_NAK:
+ cy_as_hal_assert(fnode->data != 0) ;
+ ret = my_handle_response_get_nak(dev_p,
+ rqt, resp, (cy_bool *)fnode->data) ;
+ break ;
+ case CY_RQT_ACK_SETUP_PACKET:
+ break ;
+ case CY_RQT_USB_REMOTE_WAKEUP:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_CLEAR_DESCRIPTORS:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_USB_STORAGE_MONITOR:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ case CY_RQT_MS_PARTITION_SELECT:
+ ret = my_handle_response_no_data(dev_p, rqt, resp) ;
+ break ;
+ default:
+ ret = CY_AS_ERROR_INVALID_RESPONSE ;
+ cy_as_hal_assert(cy_false) ;
+ break ;
+ }
+
+ /*
+ * if the low level layer returns a direct error, use
+ * the corresponding error code. if not, use the error
+ * code based on the response from firmware.
+ */
+ if (stat == CY_AS_ERROR_SUCCESS)
+ stat = ret ;
+
+ if (ex_request || ms_request) {
+ fnode->cb_p((cy_as_device_handle)dev_p, stat,
+ fnode->client_data, fnode->data_type, fnode->data) ;
+ cy_as_remove_c_b_node(dev_p->func_cbs_usb) ;
+ } else {
+ node->cb_p((cy_as_device_handle)dev_p, stat,
+ node->client_data) ;
+ cy_as_remove_c_b_node(dev_p->usb_func_cbs) ;
+ }
+
+ if (delayed_ack) {
+ cy_as_hal_assert(cy_as_device_is_ack_delayed(dev_p)) ;
+ cy_as_device_rem_ack_delayed(dev_p) ;
+
+ /*
+ * send the ACK if required.
+ */
+ if (!cy_as_device_is_ack_delayed(dev_p))
+ cy_as_usb_ack_setup_packet(h,
+ usb_ack_callback, 0) ;
+ }
+}
+
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
new file mode 100644
index 000000000000..ac3a4cf4216f
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
@@ -0,0 +1,2450 @@
+/* Cypress WestBridge OMAP3430 Kernel Hal source file (cyashalomap_kernel.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor,
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/scatterlist.h>
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+/* include seems broken moving for patch submission
+ * #include <mach/mux.h>
+ * #include <mach/gpmc.h>
+ * #include <mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h>
+ * #include <mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h>
+ * #include <mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h>
+ * #include <linux/westbridge/cyaserr.h>
+ * #include <linux/westbridge/cyasregs.h>
+ * #include <linux/westbridge/cyasdma.h>
+ * #include <linux/westbridge/cyasintr.h>
+ */
+#include <linux/../../arch/arm/plat-omap/include/plat/mux.h>
+#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
+#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h"
+#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h"
+#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h"
+#include "../../../include/linux/westbridge/cyaserr.h"
+#include "../../../include/linux/westbridge/cyasregs.h"
+#include "../../../include/linux/westbridge/cyasdma.h"
+#include "../../../include/linux/westbridge/cyasintr.h"
+
+#define HAL_REV "1.1.0"
+
+/*
+ * uncomment to enable 16bit pnand interface
+ */
+#define PNAND_16BIT_MODE
+
+/*
+ * selects one of 3 versions of pnand_lbd_read()
+ * PNAND_LBD_READ_NO_PFE - original 8/16 bit code
+ * reads through the gpmc CONTROLLER REGISTERS
+ * ENABLE_GPMC_PF_ENGINE - USES GPMC PFE FIFO reads, in 8 bit mode,
+ * same speed as the above
+ * PFE_LBD_READ_V2 - slightly diffrenet, performance same as above
+ */
+#define PNAND_LBD_READ_NO_PFE
+/* #define ENABLE_GPMC_PF_ENGINE */
+/* #define PFE_LBD_READ_V2 */
+
+/*
+ * westbrige astoria ISR options to limit number of
+ * back to back DMA transfers per ISR interrupt
+ */
+#define MAX_DRQ_LOOPS_IN_ISR 4
+
+/*
+ * debug prints enabling
+ *#define DBGPRN_ENABLED
+ *#define DBGPRN_DMA_SETUP_RD
+ *#define DBGPRN_DMA_SETUP_WR
+ */
+
+
+/*
+ * For performance reasons, we handle storage endpoint transfers upto 4 KB
+ * within the HAL itself.
+ */
+ #define CYASSTORAGE_WRITE_EP_NUM (4)
+ #define CYASSTORAGE_READ_EP_NUM (8)
+
+/*
+ * size of DMA packet HAL can accept from Storage API
+ * HAL will fragment it into smaller chunks that the P port can accept
+ */
+#define CYASSTORAGE_MAX_XFER_SIZE (2*32768)
+
+/*
+ * P port MAX DMA packet size according to interface/ep configurartion
+ */
+#define HAL_DMA_PKT_SZ 512
+
+#define is_storage_e_p(ep) (((ep) == 2) || ((ep) == 4) || \
+ ((ep) == 6) || ((ep) == 8))
+
+/*
+ * persistant, stores current GPMC interface cfg mode
+ */
+static uint8_t pnand_16bit;
+
+/*
+ * keep processing new WB DRQ in ISR untill all handled (performance feature)
+ */
+#define PROCESS_MULTIPLE_DRQ_IN_ISR (1)
+
+
+/*
+ * ASTORIA PNAND IF COMMANDS, CASDO - READ, CASDI - WRITE
+ */
+#define CASDO 0x05
+#define CASDI 0x85
+#define RDPAGE_B1 0x00
+#define RDPAGE_B2 0x30
+#define PGMPAGE_B1 0x80
+#define PGMPAGE_B2 0x10
+
+/*
+ * The type of DMA operation, per endpoint
+ */
+typedef enum cy_as_hal_dma_type {
+ cy_as_hal_read,
+ cy_as_hal_write,
+ cy_as_hal_none
+} cy_as_hal_dma_type ;
+
+
+/*
+ * SG list halpers defined in scaterlist.h
+#define sg_is_chain(sg) ((sg)->page_link & 0x01)
+#define sg_is_last(sg) ((sg)->page_link & 0x02)
+#define sg_chain_ptr(sg) \
+ ((struct scatterlist *) ((sg)->page_link & ~0x03))
+*/
+typedef struct cy_as_hal_endpoint_dma {
+ cy_bool buffer_valid ;
+ uint8_t *data_p ;
+ uint32_t size ;
+ /*
+ * sg_list_enabled - if true use, r/w DMA transfers use sg list,
+ * FALSE use pointer to a buffer
+ * sg_p - pointer to the owner's sg list, of there is such
+ * (like blockdriver)
+ * dma_xfer_sz - size of the next dma xfer on P port
+ * seg_xfer_cnt - counts xfered bytes for in current sg_list
+ * memory segment
+ * req_xfer_cnt - total number of bytes transfered so far in
+ * current request
+ * req_length - total request length
+ */
+ bool sg_list_enabled;
+ struct scatterlist *sg_p ;
+ uint16_t dma_xfer_sz;
+ uint32_t seg_xfer_cnt;
+ uint16_t req_xfer_cnt;
+ uint16_t req_length;
+ cy_as_hal_dma_type type ;
+ cy_bool pending ;
+} cy_as_hal_endpoint_dma ;
+
+/*
+ * The list of OMAP devices (should be one)
+ */
+static cy_as_omap_dev_kernel *m_omap_list_p;
+
+/*
+ * The callback to call after DMA operations are complete
+ */
+static cy_as_hal_dma_complete_callback callback;
+
+/*
+ * Pending data size for the endpoints
+ */
+static cy_as_hal_endpoint_dma end_points[16] ;
+
+/*
+ * Forward declaration
+ */
+static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p);
+
+static uint16_t intr_sequence_num;
+static uint8_t intr__enable;
+spinlock_t int_lock ;
+
+static u32 iomux_vma;
+static u32 csa_phy;
+
+/*
+ * gpmc I/O registers VMA
+ */
+static u32 gpmc_base ;
+
+/*
+ * gpmc data VMA associated with CS4 (ASTORIA CS on GPMC)
+ */
+static u32 gpmc_data_vma;
+static u32 ndata_reg_vma;
+static u32 ncmd_reg_vma;
+static u32 naddr_reg_vma;
+
+/*
+ * fwd declarations
+ */
+static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff);
+static void p_nand_lbd_write(u16 col_addr, u32 row_addr, u16 count, void *buff);
+static inline u16 __attribute__((always_inline))
+ ast_p_nand_casdo_read(u8 reg_addr8);
+static inline void __attribute__((always_inline))
+ ast_p_nand_casdi_write(u8 reg_addr8, u16 data);
+
+/*
+ * prints given number of omap registers
+ */
+static void cy_as_hal_print_omap_regs(char *name_prefix,
+ u8 name_base, u32 virt_base, u16 count)
+{
+ u32 reg_val, reg_addr;
+ u16 i;
+ cy_as_hal_print_message(KERN_INFO "\n");
+ for (i = 0; i < count; i++) {
+
+ reg_addr = virt_base + (i*4);
+ /* use virtual addresses here*/
+ reg_val = __raw_readl(reg_addr);
+ cy_as_hal_print_message(KERN_INFO "%s_%d[%8.8x]=%8.8x\n",
+ name_prefix, name_base+i,
+ reg_addr, reg_val);
+ }
+}
+
+/*
+ * setMUX function for a pad + additional pad flags
+ */
+static u16 omap_cfg_reg_L(u32 pad_func_index)
+{
+ static u8 sanity_check = 1;
+
+ u32 reg_vma;
+ u16 cur_val, wr_val, rdback_val;
+
+ /*
+ * do sanity check on the omap_mux_pin_cfg[] table
+ */
+ cy_as_hal_print_message(KERN_INFO" OMAP pins user_pad cfg ");
+ if (sanity_check) {
+ if ((omap_mux_pin_cfg[END_OF_TABLE].name[0] == 'E') &&
+ (omap_mux_pin_cfg[END_OF_TABLE].name[1] == 'N') &&
+ (omap_mux_pin_cfg[END_OF_TABLE].name[2] == 'D')) {
+
+ cy_as_hal_print_message(KERN_INFO
+ "table is good.\n");
+ } else {
+ cy_as_hal_print_message(KERN_WARNING
+ "table is bad, fix it");
+ }
+ /*
+ * do it only once
+ */
+ sanity_check = 0;
+ }
+
+ /*
+ * get virtual address to the PADCNF_REG
+ */
+ reg_vma = (u32)iomux_vma + omap_mux_pin_cfg[pad_func_index].offset;
+
+ /*
+ * add additional USER PU/PD/EN flags
+ */
+ wr_val = omap_mux_pin_cfg[pad_func_index].mux_val;
+ cur_val = IORD16(reg_vma);
+
+ /*
+ * PADCFG regs 16 bit long, packed into 32 bit regs,
+ * can also be accessed as u16
+ */
+ IOWR16(reg_vma, wr_val);
+ rdback_val = IORD16(reg_vma);
+
+ /*
+ * in case if the caller wants to save the old value
+ */
+ return wr_val;
+}
+
+#define BLKSZ_4K 0x1000
+
+/*
+ * switch GPMC DATA bus mode
+ */
+void cy_as_hal_gpmc_enable_16bit_bus(bool dbus16_enabled)
+{
+ uint32_t tmp32;
+
+ /*
+ * disable gpmc CS4 operation 1st
+ */
+ tmp32 = gpmc_cs_read_reg(AST_GPMC_CS,
+ GPMC_CS_CONFIG7) & ~GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, tmp32);
+
+ /*
+ * GPMC NAND data bus can be 8 or 16 bit wide
+ */
+ if (dbus16_enabled) {
+ DBGPRN("enabling 16 bit bus\n");
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
+ (GPMC_CONFIG1_DEVICETYPE(2) |
+ GPMC_CONFIG1_WAIT_PIN_SEL(2) |
+ GPMC_CONFIG1_DEVICESIZE_16)
+ );
+ } else {
+ DBGPRN(KERN_INFO "enabling 8 bit bus\n");
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
+ (GPMC_CONFIG1_DEVICETYPE(2) |
+ GPMC_CONFIG1_WAIT_PIN_SEL(2))
+ );
+ }
+
+ /*
+ * re-enable astoria CS operation on GPMC
+ */
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7,
+ (tmp32 | GPMC_CONFIG7_CSVALID));
+
+ /*
+ *remember the state
+ */
+ pnand_16bit = dbus16_enabled;
+}
+
+static int cy_as_hal_gpmc_init(void)
+{
+ u32 tmp32;
+ int err;
+ struct gpmc_timings timings;
+ /*
+ * get GPMC i/o registers base(already been i/o mapped
+ * in kernel, no need for separate i/o remap)
+ */
+ gpmc_base = phys_to_virt(OMAP34XX_GPMC_BASE);
+ DBGPRN(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x",
+ gpmc_base, __raw_readl(gpmc_base)
+ );
+
+ /*
+ * these are globals are full VMAs of the gpmc_base above
+ */
+ ncmd_reg_vma = GPMC_VMA(AST_GPMC_NAND_CMD);
+ naddr_reg_vma = GPMC_VMA(AST_GPMC_NAND_ADDR);
+ ndata_reg_vma = GPMC_VMA(AST_GPMC_NAND_DATA);
+
+ /*
+ * request GPMC CS for ASTORIA request
+ */
+ if (gpmc_cs_request(AST_GPMC_CS, SZ_16M, (void *)&csa_phy) < 0) {
+ cy_as_hal_print_message(KERN_ERR "error failed to request"
+ "ncs4 for ASTORIA\n");
+ return -1;
+ } else {
+ DBGPRN(KERN_INFO "got phy_addr:%x for "
+ "GPMC CS%d GPMC_CFGREG7[CS4]\n",
+ csa_phy, AST_GPMC_CS);
+ }
+
+ /*
+ * request VM region for 4K addr space for chip select 4 phy address
+ * technically we don't need it for NAND devices, but do it anyway
+ * so that data read/write bus cycle can be triggered by reading
+ * or writing this mem region
+ */
+ if (!request_mem_region(csa_phy, BLKSZ_4K, "AST_OMAP_HAL")) {
+ err = -EBUSY;
+ cy_as_hal_print_message(KERN_ERR "error MEM region "
+ "request for phy_addr:%x failed\n",
+ csa_phy);
+ goto out_free_cs;
+ }
+
+ /*
+ * REMAP mem region associated with our CS
+ */
+ gpmc_data_vma = (u32)ioremap_nocache(csa_phy, BLKSZ_4K);
+ if (!gpmc_data_vma) {
+ err = -ENOMEM;
+ cy_as_hal_print_message(KERN_ERR "error- ioremap()"
+ "for phy_addr:%x failed", csa_phy);
+
+ goto out_release_mem_region;
+ }
+ cy_as_hal_print_message(KERN_INFO "ioremap(%x) returned vma=%x\n",
+ csa_phy, gpmc_data_vma);
+
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
+ (GPMC_CONFIG1_DEVICETYPE(2) |
+ GPMC_CONFIG1_WAIT_PIN_SEL(2)));
+
+ memset(&timings, 0, sizeof(timings));
+
+ /* cs timing */
+ timings.cs_on = WB_GPMC_CS_t_o_n;
+ timings.cs_wr_off = WB_GPMC_BUSCYC_t;
+ timings.cs_rd_off = WB_GPMC_BUSCYC_t;
+
+ /* adv timing */
+ timings.adv_on = WB_GPMC_ADV_t_o_n;
+ timings.adv_rd_off = WB_GPMC_BUSCYC_t;
+ timings.adv_wr_off = WB_GPMC_BUSCYC_t;
+
+ /* oe timing */
+ timings.oe_on = WB_GPMC_OE_t_o_n;
+ timings.oe_off = WB_GPMC_OE_t_o_f_f;
+ timings.access = WB_GPMC_RD_t_a_c_c;
+ timings.rd_cycle = WB_GPMC_BUSCYC_t;
+
+ /* we timing */
+ timings.we_on = WB_GPMC_WE_t_o_n;
+ timings.we_off = WB_GPMC_WE_t_o_f_f;
+ timings.wr_access = WB_GPMC_WR_t_a_c_c;
+ timings.wr_cycle = WB_GPMC_BUSCYC_t;
+
+ timings.page_burst_access = WB_GPMC_BUSCYC_t;
+ timings.wr_data_mux_bus = WB_GPMC_BUSCYC_t;
+ gpmc_cs_set_timings(AST_GPMC_CS, &timings);
+
+ cy_as_hal_print_omap_regs("GPMC_CONFIG", 1,
+ GPMC_VMA(GPMC_CFG_REG(1, AST_GPMC_CS)), 7);
+
+ /*
+ * DISABLE cs4, NOTE GPMC REG7 is already configured
+ * at this point by gpmc_cs_request
+ */
+ tmp32 = gpmc_cs_read_reg(AST_GPMC_CS, GPMC_CS_CONFIG7) &
+ ~GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, tmp32);
+
+ /*
+ * PROGRAM chip select Region, (see OMAP3430 TRM PAGE 1088)
+ */
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7,
+ (AS_CS_MASK | AS_CS_BADDR));
+
+ /*
+ * by default configure GPMC into 8 bit mode
+ * (to match astoria default mode)
+ */
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
+ (GPMC_CONFIG1_DEVICETYPE(2) |
+ GPMC_CONFIG1_WAIT_PIN_SEL(2)));
+
+ /*
+ * ENABLE astoria cs operation on GPMC
+ */
+ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7,
+ (tmp32 | GPMC_CONFIG7_CSVALID));
+
+ /*
+ * No method currently exists to write this register through GPMC APIs
+ * need to change WAIT2 polarity
+ */
+ tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
+ tmp32 = tmp32 | NAND_FORCE_POSTED_WRITE_B | 0x40;
+ IOWR32(GPMC_VMA(GPMC_CONFIG_REG), tmp32);
+
+ tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
+ cy_as_hal_print_message("GPMC_CONFIG_REG=0x%x\n", tmp32);
+
+ return 0;
+
+out_release_mem_region:
+ release_mem_region(csa_phy, BLKSZ_4K);
+
+out_free_cs:
+ gpmc_cs_free(AST_GPMC_CS);
+
+ return err;
+}
+
+/*
+ * west bridge astoria ISR (Interrupt handler)
+ */
+static irqreturn_t cy_astoria_int_handler(int irq,
+ void *dev_id, struct pt_regs *regs)
+{
+ cy_as_omap_dev_kernel *dev_p;
+ uint16_t read_val = 0 ;
+ uint16_t mask_val = 0 ;
+
+ /*
+ * debug stuff, counts number of loops per one intr trigger
+ */
+ uint16_t drq_loop_cnt = 0;
+ uint8_t irq_pin;
+ /*
+ * flags to watch
+ */
+ const uint16_t sentinel = (CY_AS_MEM_P0_INTR_REG_MCUINT |
+ CY_AS_MEM_P0_INTR_REG_MBINT |
+ CY_AS_MEM_P0_INTR_REG_PMINT |
+ CY_AS_MEM_P0_INTR_REG_PLLLOCKINT);
+
+ /*
+ * sample IRQ pin level (just for statistics)
+ */
+ irq_pin = __gpio_get_value(AST_INT);
+
+ /*
+ * this one just for debugging
+ */
+ intr_sequence_num++ ;
+
+ /*
+ * astoria device handle
+ */
+ dev_p = dev_id;
+
+ /*
+ * read Astoria intr register
+ */
+ read_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INTR_REG) ;
+
+ /*
+ * save current mask value
+ */
+ mask_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INT_MASK_REG) ;
+
+ DBGPRN("<1>HAL__intr__enter:_seq:%d, P0_INTR_REG:%x\n",
+ intr_sequence_num, read_val);
+
+ /*
+ * Disable WB interrupt signal generation while we are in ISR
+ */
+ cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INT_MASK_REG, 0x0000) ;
+
+ /*
+ * this is a DRQ Interrupt
+ */
+ if (read_val & CY_AS_MEM_P0_INTR_REG_DRQINT) {
+
+ do {
+ /*
+ * handle DRQ interrupt
+ */
+ drq_loop_cnt++;
+
+ cy_handle_d_r_q_interrupt(dev_p) ;
+
+ /*
+ * spending to much time in ISR may impact
+ * average system performance
+ */
+ if (drq_loop_cnt >= MAX_DRQ_LOOPS_IN_ISR)
+ break;
+
+ /*
+ * Keep processing if there is another DRQ int flag
+ */
+ } while (cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INTR_REG) &
+ CY_AS_MEM_P0_INTR_REG_DRQINT);
+ }
+
+ if (read_val & sentinel)
+ cy_as_intr_service_interrupt((cy_as_hal_device_tag)dev_p) ;
+
+ DBGPRN("<1>_hal:_intr__exit seq:%d, mask=%4.4x,"
+ "int_pin:%d DRQ_jobs:%d\n",
+ intr_sequence_num,
+ mask_val,
+ irq_pin,
+ drq_loop_cnt);
+
+ /*
+ * re-enable WB hw interrupts
+ */
+ cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INT_MASK_REG, mask_val) ;
+
+ return IRQ_HANDLED ;
+}
+
+static int cy_as_hal_configure_interrupts(void *dev_p)
+{
+ int result;
+ int irq_pin = AST_INT;
+
+ set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW);
+
+ /*
+ * for shared IRQS must provide non NULL device ptr
+ * othervise the int won't register
+ * */
+ result = request_irq(OMAP_GPIO_IRQ(irq_pin),
+ (irq_handler_t)cy_astoria_int_handler,
+ IRQF_SHARED, "AST_INT#", dev_p);
+
+ if (result == 0) {
+ /*
+ * OMAP_GPIO_IRQ(irq_pin) - omap logical IRQ number
+ * assigned to this interrupt
+ * OMAP_GPIO_BIT(AST_INT, GPIO_IRQENABLE1) - print status
+ * of AST_INT GPIO IRQ_ENABLE FLAG
+ */
+ cy_as_hal_print_message(KERN_INFO"AST_INT omap_pin:"
+ "%d assigned IRQ #%d IRQEN1=%d\n",
+ irq_pin,
+ OMAP_GPIO_IRQ(irq_pin),
+ OMAP_GPIO_BIT(AST_INT, GPIO_IRQENABLE1)
+ );
+ } else {
+ cy_as_hal_print_message("cyasomaphal: interrupt "
+ "failed to register\n");
+ gpio_free(irq_pin);
+ cy_as_hal_print_message(KERN_WARNING
+ "ASTORIA: can't get assigned IRQ"
+ "%i for INT#\n", OMAP_GPIO_IRQ(irq_pin));
+ }
+
+ return result;
+}
+
+/*
+ * initialize OMAP pads/pins to user defined functions
+ */
+static void cy_as_hal_init_user_pads(user_pad_cfg_t *pad_cfg_tab)
+{
+ /*
+ * browse through the table an dinitiaze the pins
+ */
+ u32 in_level = 0;
+ u16 tmp16, mux_val;
+
+ while (pad_cfg_tab->name != NULL) {
+
+ if (gpio_request(pad_cfg_tab->pin_num, NULL) == 0) {
+
+ pad_cfg_tab->valid = 1;
+ mux_val = omap_cfg_reg_L(pad_cfg_tab->mux_func);
+
+ /*
+ * always set drv level before changing out direction
+ */
+ __gpio_set_value(pad_cfg_tab->pin_num,
+ pad_cfg_tab->drv);
+
+ /*
+ * "0" - OUT, "1", input omap_set_gpio_direction
+ * (pad_cfg_tab->pin_num, pad_cfg_tab->dir);
+ */
+ if (pad_cfg_tab->dir)
+ gpio_direction_input(pad_cfg_tab->pin_num);
+ else
+ gpio_direction_output(pad_cfg_tab->pin_num,
+ pad_cfg_tab->drv);
+
+ /* sample the pin */
+ in_level = __gpio_get_value(pad_cfg_tab->pin_num);
+
+ cy_as_hal_print_message(KERN_INFO "configured %s to "
+ "OMAP pad_%d, DIR=%d "
+ "DOUT=%d, DIN=%d\n",
+ pad_cfg_tab->name,
+ pad_cfg_tab->pin_num,
+ pad_cfg_tab->dir,
+ pad_cfg_tab->drv,
+ in_level
+ );
+ } else {
+ /*
+ * get the pad_mux value to check on the pin_function
+ */
+ cy_as_hal_print_message(KERN_INFO "couldn't cfg pin %d"
+ "for signal %s, its already taken\n",
+ pad_cfg_tab->pin_num,
+ pad_cfg_tab->name);
+ }
+
+ tmp16 = *(u16 *)PADCFG_VMA
+ (omap_mux_pin_cfg[pad_cfg_tab->mux_func].offset);
+
+ cy_as_hal_print_message(KERN_INFO "GPIO_%d(PAD_CFG=%x,OE=%d"
+ "DOUT=%d, DIN=%d IRQEN=%d)\n\n",
+ pad_cfg_tab->pin_num, tmp16,
+ OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_OE),
+ OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_OUT),
+ OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_IN),
+ OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_IRQENABLE1)
+ );
+
+ /*
+ * next pad_cfg deriptor
+ */
+ pad_cfg_tab++;
+ }
+
+ cy_as_hal_print_message(KERN_INFO"pads configured\n");
+}
+
+
+/*
+ * release gpios taken by the module
+ */
+static void cy_as_hal_release_user_pads(user_pad_cfg_t *pad_cfg_tab)
+{
+ while (pad_cfg_tab->name != NULL) {
+
+ if (pad_cfg_tab->valid) {
+ gpio_free(pad_cfg_tab->pin_num);
+ pad_cfg_tab->valid = 0;
+ cy_as_hal_print_message(KERN_INFO "GPIO_%d "
+ "released from %s\n",
+ pad_cfg_tab->pin_num,
+ pad_cfg_tab->name);
+ } else {
+ cy_as_hal_print_message(KERN_INFO "no release "
+ "for %s, GPIO_%d, wasn't acquired\n",
+ pad_cfg_tab->name,
+ pad_cfg_tab->pin_num);
+ }
+ pad_cfg_tab++;
+ }
+}
+
+void cy_as_hal_config_c_s_mux(void)
+{
+ /*
+ * FORCE the GPMC CS4 pin (it is in use by the zoom system)
+ */
+ omap_cfg_reg_L(T8_OMAP3430_GPMC_n_c_s4);
+}
+EXPORT_SYMBOL(cy_as_hal_config_c_s_mux);
+
+/*
+ * inits all omap h/w
+ */
+uint32_t cy_as_hal_processor_hw_init(void)
+{
+ int i, err;
+
+ cy_as_hal_print_message(KERN_INFO "init OMAP3430 hw...\n");
+
+ iomux_vma = (u32)ioremap_nocache(
+ (u32)CTLPADCONF_BASE_ADDR, CTLPADCONF_SIZE);
+ cy_as_hal_print_message(KERN_INFO "PADCONF_VMA=%x val=%x\n",
+ iomux_vma, IORD32(iomux_vma));
+
+ /*
+ * remap gpio banks
+ */
+ for (i = 0; i < 6; i++) {
+ gpio_vma_tab[i].virt_addr = (u32)ioremap_nocache(
+ gpio_vma_tab[i].phy_addr,
+ gpio_vma_tab[i].size);
+
+ cy_as_hal_print_message(KERN_INFO "%s virt_addr=%x\n",
+ gpio_vma_tab[i].name,
+ (u32)gpio_vma_tab[i].virt_addr);
+ };
+
+ /*
+ * force OMAP_GPIO_126 to rleased state,
+ * will be configured to drive reset
+ */
+ gpio_free(AST_RESET);
+
+ /*
+ *same thing with AStoria CS pin
+ */
+ gpio_free(AST_CS);
+
+ /*
+ * initialize all the OMAP pads connected to astoria
+ */
+ cy_as_hal_init_user_pads(user_pad_cfg);
+
+ err = cy_as_hal_gpmc_init();
+ if (err < 0)
+ cy_as_hal_print_message(KERN_INFO"gpmc init failed:%d", err);
+
+ cy_as_hal_config_c_s_mux();
+
+ return gpmc_data_vma;
+}
+EXPORT_SYMBOL(cy_as_hal_processor_hw_init);
+
+void cy_as_hal_omap_hardware_deinit(cy_as_omap_dev_kernel *dev_p)
+{
+ /*
+ * free omap hw resources
+ */
+ if (gpmc_data_vma != 0)
+ iounmap((void *)gpmc_data_vma);
+
+ if (csa_phy != 0)
+ release_mem_region(csa_phy, BLKSZ_4K);
+
+ gpmc_cs_free(AST_GPMC_CS);
+
+ free_irq(OMAP_GPIO_IRQ(AST_INT), dev_p);
+
+ cy_as_hal_release_user_pads(user_pad_cfg);
+}
+
+/*
+ * These are the functions that are not part of the
+ * HAL layer, but are required to be called for this HAL
+ */
+
+/*
+ * Called On AstDevice LKM exit
+ */
+int stop_o_m_a_p_kernel(const char *pgm, cy_as_hal_device_tag tag)
+{
+ cy_as_omap_dev_kernel *dev_p = (cy_as_omap_dev_kernel *)tag ;
+
+ /*
+ * TODO: Need to disable WB interrupt handlere 1st
+ */
+ if (0 == dev_p)
+ return 1 ;
+
+ cy_as_hal_print_message("<1>_stopping OMAP34xx HAL layer object\n");
+ if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG) {
+ cy_as_hal_print_message("<1>%s: %s: bad HAL tag\n",
+ pgm, __func__) ;
+ return 1 ;
+ }
+
+ /*
+ * disable interrupt
+ */
+ cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INT_MASK_REG, 0x0000) ;
+
+#if 0
+ if (dev_p->thread_flag == 0) {
+ dev_p->thread_flag = 1 ;
+ wait_for_completion(&dev_p->thread_complete) ;
+ cy_as_hal_print_message("cyasomaphal:"
+ "done cleaning thread\n");
+ cy_as_hal_destroy_sleep_channel(&dev_p->thread_sc) ;
+ }
+#endif
+
+ cy_as_hal_omap_hardware_deinit(dev_p);
+
+ /*
+ * Rearrange the list
+ */
+ if (m_omap_list_p == dev_p)
+ m_omap_list_p = dev_p->m_next_p ;
+
+ cy_as_hal_free(dev_p) ;
+
+ cy_as_hal_print_message(KERN_INFO"OMAP_kernel_hal stopped\n");
+ return 0;
+}
+
+int omap_start_intr(cy_as_hal_device_tag tag)
+{
+ cy_as_omap_dev_kernel *dev_p = (cy_as_omap_dev_kernel *)tag ;
+ int ret = 0 ;
+ const uint16_t mask = CY_AS_MEM_P0_INTR_REG_DRQINT |
+ CY_AS_MEM_P0_INTR_REG_MBINT ;
+
+ /*
+ * register for interrupts
+ */
+ ret = cy_as_hal_configure_interrupts(dev_p) ;
+
+ /*
+ * enable only MBox & DRQ interrupts for now
+ */
+ cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_INT_MASK_REG, mask) ;
+
+ return 1 ;
+}
+
+/*
+ * Below are the functions that communicate with the WestBridge device.
+ * These are system dependent and must be defined by the HAL layer
+ * for a given system.
+ */
+
+/*
+ * GPMC NAND command+addr write phase
+ */
+static inline void nand_cmd_n_addr(u8 cmdb1, u16 col_addr, u32 row_addr)
+{
+ /*
+ * byte order on the bus <cmd> <CA0,CA1,RA0,RA1, RA2>
+ */
+ u32 tmpa32 = ((row_addr << 16) | col_addr);
+ u8 RA2 = (u8)(row_addr >> 16);
+
+ if (!pnand_16bit) {
+ /*
+ * GPMC PNAND 8bit BUS
+ */
+ /*
+ * CMD1
+ */
+ IOWR8(ncmd_reg_vma, cmdb1);
+
+ /*
+ *pnand bus: <CA0,CA1,RA0,RA1>
+ */
+ IOWR32(naddr_reg_vma, tmpa32);
+
+ /*
+ * <RA2> , always zero
+ */
+ IOWR8(naddr_reg_vma, RA2);
+
+ } else {
+ /*
+ * GPMC PNAND 16bit BUS , in 16 bit mode CMD
+ * and ADDR sent on [d7..d0]
+ */
+ uint8_t CA0, CA1, RA0, RA1;
+ CA0 = tmpa32 & 0x000000ff;
+ CA1 = (tmpa32 >> 8) & 0x000000ff;
+ RA0 = (tmpa32 >> 16) & 0x000000ff;
+ RA1 = (tmpa32 >> 24) & 0x000000ff;
+
+ /*
+ * can't use 32 bit writes here omap will not serialize
+ * them to lower half in16 bit mode
+ */
+
+ /*
+ *pnand bus: <CMD1, CA0,CA1,RA0,RA1, RA2 (always zero)>
+ */
+ IOWR8(ncmd_reg_vma, cmdb1);
+ IOWR8(naddr_reg_vma, CA0);
+ IOWR8(naddr_reg_vma, CA1);
+ IOWR8(naddr_reg_vma, RA0);
+ IOWR8(naddr_reg_vma, RA1);
+ IOWR8(naddr_reg_vma, RA2);
+ }
+}
+
+/*
+ * spin until r/b goes high
+ */
+inline int wait_rn_b_high(void)
+{
+ u32 w_spins = 0;
+
+ /*
+ * TODO: note R/b may go low here, need to spin until high
+ * while (omap_get_gpio_datain(AST_RnB) == 0) {
+ * w_spins++;
+ * }
+ * if (OMAP_GPIO_BIT(AST_RnB, GPIO_DATA_IN) == 0) {
+ *
+ * while (OMAP_GPIO_BIT(AST_RnB, GPIO_DATA_IN) == 0) {
+ * w_spins++;
+ * }
+ * printk("<1>RnB=0!:%d\n",w_spins);
+ * }
+ */
+ return w_spins;
+}
+
+#ifdef ENABLE_GPMC_PF_ENGINE
+/* #define PFE_READ_DEBUG
+ * PNAND block read with OMAP PFE enabled
+ * status: Not tested, NW, broken , etc
+ */
+static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff)
+{
+ uint16_t w32cnt;
+ uint32_t *ptr32;
+ uint8_t *ptr8;
+ uint8_t bytes_in_fifo;
+
+ /* debug vars*/
+#ifdef PFE_READ_DEBUG
+ uint32_t loop_limit;
+ uint16_t bytes_read = 0;
+#endif
+
+ /*
+ * configure the prefetch engine
+ */
+ uint32_t tmp32;
+ uint32_t pfe_status;
+
+ /*
+ * DISABLE GPMC CS4 operation 1st, this is
+ * in case engine is be already disabled
+ */
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x0);
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG1), GPMC_PREFETCH_CONFIG1_VAL);
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG2), count);
+
+#ifdef PFE_READ_DEBUG
+ tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_CONFIG1));
+ if (tmp32 != GPMC_PREFETCH_CONFIG1_VAL) {
+ printk(KERN_INFO "<1> prefetch is CONFIG1 read val:%8.8x, != VAL written:%8.8x\n",
+ tmp32, GPMC_PREFETCH_CONFIG1_VAL);
+ tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS));
+ printk(KERN_INFO "<1> GPMC_PREFETCH_STATUS : %8.8x\n", tmp32);
+ }
+
+ /*
+ *sanity check 2
+ */
+ tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_CONFIG2));
+ if (tmp32 != (count))
+ printk(KERN_INFO "<1> GPMC_PREFETCH_CONFIG2 read val:%d, "
+ "!= VAL written:%d\n", tmp32, count);
+#endif
+
+ /*
+ * ISSUE PNAND CMD+ADDR, note gpmc puts 32b words
+ * on the bus least sig. byte 1st
+ */
+ nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr);
+
+ IOWR8(ncmd_reg_vma, RDPAGE_B2);
+
+ /*
+ * start the prefetch engine
+ */
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x1);
+
+ ptr32 = buff;
+
+ while (1) {
+ /*
+ * GPMC PFE service loop
+ */
+ do {
+ /*
+ * spin until PFE fetched some
+ * PNAND bus words in the FIFO
+ */
+ pfe_status = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS));
+ bytes_in_fifo = (pfe_status >> 24) & 0x7f;
+ } while (bytes_in_fifo == 0);
+
+ /* whole 32 bit words in fifo */
+ w32cnt = bytes_in_fifo >> 2;
+
+#if 0
+ /*
+ *NOTE: FIFO_PTR indicates number of NAND bus words bytes
+ * already received in the FIFO and available to be read
+ * by DMA or MPU whether COUNTVAL indicates number of BUS
+ * words yet to be read from PNAND bus words
+ */
+ printk(KERN_ERR "<1> got PF_STATUS:%8.8x FIFO_PTR:%d, COUNTVAL:%d, w32cnt:%d\n",
+ pfe_status, bytes_in_fifo,
+ (pfe_status & 0x3fff), w32cnt);
+#endif
+
+ while (w32cnt--)
+ *ptr32++ = IORD32(gpmc_data_vma);
+
+ if ((pfe_status & 0x3fff) == 0) {
+ /*
+ * PFE acc angine done, there still may be data leftover
+ * in the FIFO re-read FIFO BYTE counter (check for
+ * leftovers from 32 bit read accesses above)
+ */
+ bytes_in_fifo = (IORD32(
+ GPMC_VMA(GPMC_PREFETCH_STATUS)) >> 24) & 0x7f;
+
+ /*
+ * NOTE we may still have one word left in the fifo
+ * read it out
+ */
+ ptr8 = ptr32;
+ switch (bytes_in_fifo) {
+
+ case 0:
+ /*
+ * nothing to do we already read the
+ * FIFO out with 32 bit accesses
+ */
+ break;
+ case 1:
+ /*
+ * this only possible
+ * for 8 bit pNAND only
+ */
+ *ptr8 = IORD8(gpmc_data_vma);
+ break;
+
+ case 2:
+ /*
+ * this one can occur in either modes
+ */
+ *(uint16_t *)ptr8 = IORD16(gpmc_data_vma);
+ break;
+
+ case 3:
+ /*
+ * this only possible for 8 bit pNAND only
+ */
+ *(uint16_t *)ptr8 = IORD16(gpmc_data_vma);
+ ptr8 += 2;
+ *ptr8 = IORD8(gpmc_data_vma);
+ break;
+
+ case 4:
+ /*
+ * shouldn't happen, but has been seen
+ * in 8 bit mode
+ */
+ *ptr32 = IORD32(gpmc_data_vma);
+ break;
+
+ default:
+ printk(KERN_ERR"<1>_error: PFE FIFO bytes leftover is not read:%d\n",
+ bytes_in_fifo);
+ break;
+ }
+ /*
+ * read is completed, get out of the while(1) loop
+ */
+ break;
+ }
+ }
+}
+#endif
+
+#ifdef PFE_LBD_READ_V2
+/*
+ * PFE engine assisted reads with the 64 byte blocks
+ */
+static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff)
+{
+ uint8_t rd_cnt;
+ uint32_t *ptr32;
+ uint8_t *ptr8;
+ uint16_t reminder;
+ uint32_t pfe_status;
+
+ /*
+ * ISSUE PNAND CMD+ADDR
+ * note gpmc puts 32b words on the bus least sig. byte 1st
+ */
+ nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr);
+ IOWR8(ncmd_reg_vma, RDPAGE_B2);
+
+ /*
+ * setup PFE block
+ * count - OMAP number of bytes to access on pnand bus
+ */
+
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG1), GPMC_PREFETCH_CONFIG1_VAL);
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG2), count);
+ IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x1);
+
+ ptr32 = buff;
+
+ do {
+ pfe_status = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)) ;
+ rd_cnt = pfe_status >> (24+2);
+
+ while (rd_cnt--)
+ *ptr32++ = IORD32(gpmc_data_vma);
+
+ } while (pfe_status & 0x3fff);
+
+ /*
+ * read out the leftover
+ */
+ ptr8 = ptr32;
+ rd_cnt = (IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)) >> 24) & 0x7f;
+
+ while (rd_cnt--)
+ *ptr8++ = IORD8(gpmc_data_vma);
+}
+#endif
+
+#ifdef PNAND_LBD_READ_NO_PFE
+/*
+ * Endpoint buffer read w/o OMAP GPMC Prefetch Engine
+ * the original working code, works at max speed for 8 bit xfers
+ * for 16 bit the bus diagram has gaps
+ */
+static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff)
+{
+ uint16_t w32cnt;
+ uint32_t *ptr32;
+ uint16_t *ptr16;
+ uint16_t remainder;
+
+ DBGPRN("<1> %s(): NO_PFE\n", __func__);
+
+ ptr32 = buff;
+ /* number of whole 32 bit words in the transfer */
+ w32cnt = count >> 2;
+
+ /* remainder, in bytes(0..3) */
+ remainder = count & 03;
+
+ /*
+ * note gpmc puts 32b words on the bus least sig. byte 1st
+ */
+ nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr);
+ IOWR8(ncmd_reg_vma, RDPAGE_B2);
+
+ /*
+ * read data by 32 bit chunks
+ */
+ while (w32cnt--)
+ *ptr32++ = IORD32(ndata_reg_vma);
+
+ /*
+ * now do the remainder(it can be 0, 1, 2 or 3)
+ * same code for both 8 & 16 bit bus
+ * do 1 or 2 MORE words
+ */
+ ptr16 = (uint16_t *)ptr32;
+
+ switch (remainder) {
+ case 1:
+ /* read one 16 bit word
+ * IN 8 BIT WE NEED TO READ even number of bytes
+ */
+ case 2:
+ *ptr16 = IORD16(ndata_reg_vma);
+ break;
+ case 3:
+ /*
+ * for 3 bytes read 2 16 bit words
+ */
+ *ptr16++ = IORD16(ndata_reg_vma);
+ *ptr16 = IORD16(ndata_reg_vma);
+ break;
+ default:
+ /*
+ * remainder is 0
+ */
+ break;
+ }
+}
+#endif
+
+/*
+ * uses LBD mode to write N bytes into astoria
+ * Status: Working, however there are 150ns idle
+ * timeafter every 2 (16 bit or 4(8 bit) bus cycles
+ */
+static void p_nand_lbd_write(u16 col_addr, u32 row_addr, u16 count, void *buff)
+{
+ uint16_t w32cnt;
+ uint16_t remainder;
+ uint8_t *ptr8;
+ uint16_t *ptr16;
+ uint32_t *ptr32;
+
+ remainder = count & 03;
+ w32cnt = count >> 2;
+ ptr32 = buff;
+ ptr8 = buff;
+
+ /*
+ * send: CMDB1, CA0,CA1,RA0,RA1,RA2
+ */
+ nand_cmd_n_addr(PGMPAGE_B1, col_addr, row_addr);
+
+ /*
+ * blast the data out in 32bit chunks
+ */
+ while (w32cnt--)
+ IOWR32(ndata_reg_vma, *ptr32++);
+
+ /*
+ * do the reminder if there is one
+ * same handling for both 8 & 16 bit pnand: mode
+ */
+ ptr16 = (uint16_t *)ptr32; /* do 1 or 2 words */
+
+ switch (remainder) {
+ case 1:
+ /*
+ * read one 16 bit word
+ */
+ case 2:
+ IOWR16(ndata_reg_vma, *ptr16);
+ break;
+
+ case 3:
+ /*
+ * for 3 bytes read 2 16 bit words
+ */
+ IOWR16(ndata_reg_vma, *ptr16++);
+ IOWR16(ndata_reg_vma, *ptr16);
+ break;
+ default:
+ /*
+ * reminder is 0
+ */
+ break;
+ }
+ /*
+ * finally issue a PGM cmd
+ */
+ IOWR8(ncmd_reg_vma, PGMPAGE_B2);
+}
+
+/*
+ * write Astoria register
+ */
+static inline void ast_p_nand_casdi_write(u8 reg_addr8, u16 data)
+{
+ unsigned long flags;
+ u16 addr16;
+ /*
+ * throw an error if called from multiple threads
+ */
+ static atomic_t rdreg_usage_cnt = { 0 };
+
+ /*
+ * disable interrupts
+ */
+ local_irq_save(flags);
+
+ if (atomic_read(&rdreg_usage_cnt) != 0) {
+ cy_as_hal_print_message(KERN_ERR "cy_as_omap_hal:"
+ "* cy_as_hal_write_register usage:%d\n",
+ atomic_read(&rdreg_usage_cnt));
+ }
+
+ atomic_inc(&rdreg_usage_cnt);
+
+ /*
+ * 2 flavors of GPMC -> PNAND access
+ */
+ if (pnand_16bit) {
+ /*
+ * 16 BIT gpmc NAND mode
+ */
+
+ /*
+ * CMD1, CA1, CA2,
+ */
+ IOWR8(ncmd_reg_vma, 0x85);
+ IOWR8(naddr_reg_vma, reg_addr8);
+ IOWR8(naddr_reg_vma, 0x0c);
+
+ /*
+ * this should be sent on the 16 bit bus
+ */
+ IOWR16(ndata_reg_vma, data);
+ } else {
+ /*
+ * 8 bit nand mode GPMC will automatically
+ * seriallize 16bit or 32 bit writes into
+ * 8 bit onesto the lower 8 bit in LE order
+ */
+ addr16 = 0x0c00 | reg_addr8;
+
+ /*
+ * CMD1, CA1, CA2,
+ */
+ IOWR8(ncmd_reg_vma, 0x85);
+ IOWR16(naddr_reg_vma, addr16);
+ IOWR16(ndata_reg_vma, data);
+ }
+
+ /*
+ * re-enable interrupts
+ */
+ atomic_dec(&rdreg_usage_cnt);
+ local_irq_restore(flags);
+}
+
+
+/*
+ * read astoria register via pNAND interface
+ */
+static inline u16 ast_p_nand_casdo_read(u8 reg_addr8)
+{
+ u16 data;
+ u16 addr16;
+ unsigned long flags;
+ /*
+ * throw an error if called from multiple threads
+ */
+ static atomic_t wrreg_usage_cnt = { 0 };
+
+ /*
+ * disable interrupts
+ */
+ local_irq_save(flags);
+
+ if (atomic_read(&wrreg_usage_cnt) != 0) {
+ /*
+ * if it gets here ( from other threads), this function needs
+ * need spin_lock_irq save() protection
+ */
+ cy_as_hal_print_message(KERN_ERR"cy_as_omap_hal: "
+ "cy_as_hal_write_register usage:%d\n",
+ atomic_read(&wrreg_usage_cnt));
+ }
+ atomic_inc(&wrreg_usage_cnt);
+
+ /*
+ * 2 flavors of GPMC -> PNAND access
+ */
+ if (pnand_16bit) {
+ /*
+ * 16 BIT gpmc NAND mode
+ * CMD1, CA1, CA2,
+ */
+
+ IOWR8(ncmd_reg_vma, 0x05);
+ IOWR8(naddr_reg_vma, reg_addr8);
+ IOWR8(naddr_reg_vma, 0x0c);
+ IOWR8(ncmd_reg_vma, 0x00E0);
+
+ udelay(1);
+
+ /*
+ * much faster through the gPMC Register space
+ */
+ data = IORD16(ndata_reg_vma);
+ } else {
+ /*
+ * 8 BIT gpmc NAND mode
+ * CMD1, CA1, CA2, CMD2
+ */
+ addr16 = 0x0c00 | reg_addr8;
+ IOWR8(ncmd_reg_vma, 0x05);
+ IOWR16(naddr_reg_vma, addr16);
+ IOWR8(ncmd_reg_vma, 0xE0);
+ udelay(1);
+ data = IORD16(ndata_reg_vma);
+ }
+
+ /*
+ * re-enable interrupts
+ */
+ atomic_dec(&wrreg_usage_cnt);
+ local_irq_restore(flags);
+
+ return data;
+}
+
+
+/*
+ * This function must be defined to write a register within the WestBridge
+ * device. The addr value is the address of the register to write with
+ * respect to the base address of the WestBridge device.
+ */
+void cy_as_hal_write_register(
+ cy_as_hal_device_tag tag,
+ uint16_t addr, uint16_t data)
+{
+ ast_p_nand_casdi_write((u8)addr, data);
+}
+
+/*
+ * This function must be defined to read a register from the WestBridge
+ * device. The addr value is the address of the register to read with
+ * respect to the base address of the WestBridge device.
+ */
+uint16_t cy_as_hal_read_register(cy_as_hal_device_tag tag, uint16_t addr)
+{
+ uint16_t data = 0 ;
+
+ /*
+ * READ ASTORIA REGISTER USING CASDO
+ */
+ data = ast_p_nand_casdo_read((u8)addr);
+
+ return data ;
+}
+
+/*
+ * preps Ep pointers & data counters for next packet
+ * (fragment of the request) xfer returns true if
+ * there is a next transfer, and false if all bytes in
+ * current request have been xfered
+ */
+static inline bool prep_for_next_xfer(cy_as_hal_device_tag tag, uint8_t ep)
+{
+
+ if (!end_points[ep].sg_list_enabled) {
+ /*
+ * no further transfers for non storage EPs
+ * (like EP2 during firmware download, done
+ * in 64 byte chunks)
+ */
+ if (end_points[ep].req_xfer_cnt >= end_points[ep].req_length) {
+ DBGPRN("<1> %s():RQ sz:%d non-_sg EP:%d completed\n",
+ __func__, end_points[ep].req_length, ep);
+
+ /*
+ * no more transfers, we are done with the request
+ */
+ return false;
+ }
+
+ /*
+ * calculate size of the next DMA xfer, corner
+ * case for non-storage EPs where transfer size
+ * is not egual N * HAL_DMA_PKT_SZ xfers
+ */
+ if ((end_points[ep].req_length - end_points[ep].req_xfer_cnt)
+ >= HAL_DMA_PKT_SZ) {
+ end_points[ep].dma_xfer_sz = HAL_DMA_PKT_SZ;
+ } else {
+ /*
+ * that would be the last chunk less
+ * than P-port max size
+ */
+ end_points[ep].dma_xfer_sz = end_points[ep].req_length -
+ end_points[ep].req_xfer_cnt;
+ }
+
+ return true;
+ }
+
+ /*
+ * for SG_list assisted dma xfers
+ * are we done with current SG ?
+ */
+ if (end_points[ep].seg_xfer_cnt == end_points[ep].sg_p->length) {
+ /*
+ * was it the Last SG segment on the list ?
+ */
+ if (sg_is_last(end_points[ep].sg_p)) {
+ DBGPRN("<1> %s: EP:%d completed,"
+ "%d bytes xfered\n",
+ __func__,
+ ep,
+ end_points[ep].req_xfer_cnt
+ );
+
+ return false;
+ } else {
+ /*
+ * There are more SG segments in current
+ * request's sg list setup new segment
+ */
+
+ end_points[ep].seg_xfer_cnt = 0;
+ end_points[ep].sg_p = sg_next(end_points[ep].sg_p);
+ /* set data pointer for next DMA sg transfer*/
+ end_points[ep].data_p = sg_virt(end_points[ep].sg_p);
+ DBGPRN("<1> %s new SG:_va:%p\n\n",
+ __func__, end_points[ep].data_p);
+ }
+
+ }
+
+ /*
+ * for sg list xfers it will always be 512 or 1024
+ */
+ end_points[ep].dma_xfer_sz = HAL_DMA_PKT_SZ;
+
+ /*
+ * next transfer is required
+ */
+
+ return true;
+}
+
+/*
+ * Astoria DMA read request, APP_CPU reads from WB ep buffer
+ */
+static void cy_service_e_p_dma_read_request(
+ cy_as_omap_dev_kernel *dev_p, uint8_t ep)
+{
+ cy_as_hal_device_tag tag = (cy_as_hal_device_tag)dev_p ;
+ uint16_t v, size;
+ void *dptr;
+ uint16_t col_addr = 0x0000;
+ uint32_t row_addr = CYAS_DEV_CALC_EP_ADDR(ep);
+ uint16_t ep_dma_reg = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2;
+
+ /*
+ * get the XFER size frtom WB eP DMA REGISTER
+ */
+ v = cy_as_hal_read_register(tag, ep_dma_reg);
+
+ /*
+ * amount of data in EP buff in bytes
+ */
+ size = v & CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK;
+
+ /*
+ * memory pointer for this DMA packet xfer (sub_segment)
+ */
+ dptr = end_points[ep].data_p;
+
+ DBGPRN("<1>HAL:_svc_dma_read on EP_%d sz:%d, intr_seq:%d, dptr:%p\n",
+ ep,
+ size,
+ intr_sequence_num,
+ dptr
+ );
+
+ cy_as_hal_assert(size != 0);
+
+ if (size) {
+ /*
+ * the actual WB-->OMAP memory "soft" DMA xfer
+ */
+ p_nand_lbd_read(col_addr, row_addr, size, dptr);
+ }
+
+ /*
+ * clear DMAVALID bit indicating that the data has been read
+ */
+ cy_as_hal_write_register(tag, ep_dma_reg, 0) ;
+
+ end_points[ep].seg_xfer_cnt += size;
+ end_points[ep].req_xfer_cnt += size;
+
+ /*
+ * pre-advance data pointer (if it's outside sg
+ * list it will be reset anyway
+ */
+ end_points[ep].data_p += size;
+
+ if (prep_for_next_xfer(tag, ep)) {
+ /*
+ * we have more data to read in this request,
+ * setup next dma packet due tell WB how much
+ * data we are going to xfer next
+ */
+ v = end_points[ep].dma_xfer_sz/*HAL_DMA_PKT_SZ*/ |
+ CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
+ cy_as_hal_write_register(tag, ep_dma_reg, v);
+ } else {
+ end_points[ep].pending = cy_false ;
+ end_points[ep].type = cy_as_hal_none ;
+ end_points[ep].buffer_valid = cy_false ;
+
+ /*
+ * notify the API that we are done with rq on this EP
+ */
+ if (callback) {
+ DBGPRN("<1>trigg rd_dma completion cb: xfer_sz:%d\n",
+ end_points[ep].req_xfer_cnt);
+ callback(tag, ep,
+ end_points[ep].req_xfer_cnt,
+ CY_AS_ERROR_SUCCESS);
+ }
+ }
+}
+
+/*
+ * omap_cpu needs to transfer data to ASTORIA EP buffer
+ */
+static void cy_service_e_p_dma_write_request(
+ cy_as_omap_dev_kernel *dev_p, uint8_t ep)
+{
+ uint16_t addr;
+ uint16_t v = 0;
+ uint32_t size;
+ uint16_t col_addr = 0x0000;
+ uint32_t row_addr = CYAS_DEV_CALC_EP_ADDR(ep);
+ void *dptr;
+
+ cy_as_hal_device_tag tag = (cy_as_hal_device_tag)dev_p ;
+ /*
+ * note: size here its the size of the dma transfer could be
+ * anything > 0 && < P_PORT packet size
+ */
+ size = end_points[ep].dma_xfer_sz ;
+ dptr = end_points[ep].data_p ;
+
+ /*
+ * perform the soft DMA transfer, soft in this case
+ */
+ if (size)
+ p_nand_lbd_write(col_addr, row_addr, size, dptr);
+
+ end_points[ep].seg_xfer_cnt += size;
+ end_points[ep].req_xfer_cnt += size;
+ /*
+ * pre-advance data pointer
+ * (if it's outside sg list it will be reset anyway)
+ */
+ end_points[ep].data_p += size;
+
+ /*
+ * now clear DMAVAL bit to indicate we are done
+ * transferring data and that the data can now be
+ * sent via USB to the USB host, sent to storage,
+ * or used internally.
+ */
+
+ addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
+ cy_as_hal_write_register(tag, addr, size) ;
+
+ /*
+ * finally, tell the USB subsystem that the
+ * data is gone and we can accept the
+ * next request if one exists.
+ */
+ if (prep_for_next_xfer(tag, ep)) {
+ /*
+ * There is more data to go. Re-init the WestBridge DMA side
+ */
+ v = end_points[ep].dma_xfer_sz |
+ CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
+ cy_as_hal_write_register(tag, addr, v) ;
+ } else {
+
+ end_points[ep].pending = cy_false ;
+ end_points[ep].type = cy_as_hal_none ;
+ end_points[ep].buffer_valid = cy_false ;
+
+ /*
+ * notify the API that we are done with rq on this EP
+ */
+ if (callback) {
+ /*
+ * this callback will wake up the process that might be
+ * sleeping on the EP which data is being transferred
+ */
+ callback(tag, ep,
+ end_points[ep].req_xfer_cnt,
+ CY_AS_ERROR_SUCCESS);
+ }
+ }
+}
+
+/*
+ * HANDLE DRQINT from Astoria (called in AS_Intr context
+ */
+static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p)
+{
+ uint16_t v ;
+ static uint8_t service_ep = 2 ;
+
+ /*
+ * We've got DRQ INT, read DRQ STATUS Register */
+ v = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
+ CY_AS_MEM_P0_DRQ) ;
+
+ if (v == 0) {
+#ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("stray DRQ interrupt detected\n") ;
+#endif
+ return;
+ }
+
+ /*
+ * Now, pick a given DMA request to handle, for now, we just
+ * go round robin. Each bit position in the service_mask
+ * represents an endpoint from EP2 to EP15. We rotate through
+ * each of the endpoints to find one that needs to be serviced.
+ */
+ while ((v & (1 << service_ep)) == 0) {
+
+ if (service_ep == 15)
+ service_ep = 2 ;
+ else
+ service_ep++ ;
+ }
+
+ if (end_points[service_ep].type == cy_as_hal_write) {
+ /*
+ * handle DMA WRITE REQUEST: app_cpu will
+ * write data into astoria EP buffer
+ */
+ cy_service_e_p_dma_write_request(dev_p, service_ep) ;
+ } else if (end_points[service_ep].type == cy_as_hal_read) {
+ /*
+ * handle DMA READ REQUEST: cpu will
+ * read EP buffer from Astoria
+ */
+ cy_service_e_p_dma_read_request(dev_p, service_ep) ;
+ }
+#ifndef WESTBRIDGE_NDEBUG
+ else
+ cy_as_hal_print_message("cyashalomap:interrupt,"
+ " w/o pending DMA job,"
+ "-check DRQ_MASK logic\n") ;
+#endif
+
+ /*
+ * Now bump the EP ahead, so other endpoints get
+ * a shot before the one we just serviced
+ */
+ if (end_points[service_ep].type == cy_as_hal_none) {
+ if (service_ep == 15)
+ service_ep = 2 ;
+ else
+ service_ep++ ;
+ }
+
+}
+
+void cy_as_hal_dma_cancel_request(cy_as_hal_device_tag tag, uint8_t ep)
+{
+ DBGPRN("cy_as_hal_dma_cancel_request on ep:%d", ep);
+ if (end_points[ep].pending)
+ cy_as_hal_write_register(tag,
+ CY_AS_MEM_P0_EP2_DMA_REG + ep - 2, 0);
+
+ end_points[ep].buffer_valid = cy_false ;
+ end_points[ep].type = cy_as_hal_none;
+}
+
+/*
+ * enables/disables SG list assisted DMA xfers for the given EP
+ * sg_list assisted XFERS can use physical addresses of mem pages in case if the
+ * xfer is performed by a h/w DMA controller rather then the CPU on P port
+ */
+void cy_as_hal_set_ep_dma_mode(uint8_t ep, bool sg_xfer_enabled)
+{
+ end_points[ep].sg_list_enabled = sg_xfer_enabled;
+ DBGPRN("<1> EP:%d sg_list assisted DMA mode set to = %d\n",
+ ep, end_points[ep].sg_list_enabled);
+}
+EXPORT_SYMBOL(cy_as_hal_set_ep_dma_mode);
+
+/*
+ * This function must be defined to transfer a block of data to
+ * the WestBridge device. This function can use the burst write
+ * (DMA) capabilities of WestBridge to do this, or it can just copy
+ * the data using writes.
+ */
+void cy_as_hal_dma_setup_write(cy_as_hal_device_tag tag,
+ uint8_t ep, void *buf,
+ uint32_t size, uint16_t maxsize)
+{
+ uint32_t addr = 0 ;
+ uint16_t v = 0;
+
+ /*
+ * Note: "size" is the actual request size
+ * "maxsize" - is the P port fragment size
+ * No EP0 or EP1 traffic should get here
+ */
+ cy_as_hal_assert(ep != 0 && ep != 1) ;
+
+ /*
+ * If this asserts, we have an ordering problem. Another DMA request
+ * is coming down before the previous one has completed.
+ */
+ cy_as_hal_assert(end_points[ep].buffer_valid == cy_false) ;
+ end_points[ep].buffer_valid = cy_true ;
+ end_points[ep].type = cy_as_hal_write ;
+ end_points[ep].pending = cy_true;
+
+ /*
+ * total length of the request
+ */
+ end_points[ep].req_length = size;
+
+ if (size >= maxsize) {
+ /*
+ * set xfer size for very 1st DMA xfer operation
+ * port max packet size ( typically 512 or 1024)
+ */
+ end_points[ep].dma_xfer_sz = maxsize;
+ } else {
+ /*
+ * smaller xfers for non-storage EPs
+ */
+ end_points[ep].dma_xfer_sz = size;
+ }
+
+ /*
+ * check the EP transfer mode uses sg_list rather then a memory buffer
+ * block devices pass it to the HAL, so the hAL could get to the real
+ * physical address for each segment and set up a DMA controller
+ * hardware ( if there is one)
+ */
+ if (end_points[ep].sg_list_enabled) {
+ /*
+ * buf - pointer to the SG list
+ * data_p - data pointer to the 1st DMA segment
+ * seg_xfer_cnt - keeps track of N of bytes sent in current
+ * sg_list segment
+ * req_xfer_cnt - keeps track of the total N of bytes
+ * transferred for the request
+ */
+ end_points[ep].sg_p = buf;
+ end_points[ep].data_p = sg_virt(end_points[ep].sg_p);
+ end_points[ep].seg_xfer_cnt = 0 ;
+ end_points[ep].req_xfer_cnt = 0;
+
+#ifdef DBGPRN_DMA_SETUP_WR
+ DBGPRN("cyasomaphal:%s: EP:%d, buf:%p, buf_va:%p,"
+ "req_sz:%d, maxsz:%d\n",
+ __func__,
+ ep,
+ buf,
+ end_points[ep].data_p,
+ size,
+ maxsize);
+#endif
+
+ } else {
+ /*
+ * setup XFER for non sg_list assisted EPs
+ */
+
+ #ifdef DBGPRN_DMA_SETUP_WR
+ DBGPRN("<1>%s non storage or sz < 512:"
+ "EP:%d, sz:%d\n", __func__, ep, size);
+ #endif
+
+ end_points[ep].sg_p = NULL;
+
+ /*
+ * must be a VMA of a membuf in kernel space
+ */
+ end_points[ep].data_p = buf;
+
+ /*
+ * will keep track No of bytes xferred for the request
+ */
+ end_points[ep].req_xfer_cnt = 0;
+ }
+
+ /*
+ * Tell WB we are ready to send data on the given endpoint
+ */
+ v = (end_points[ep].dma_xfer_sz & CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK)
+ | CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
+
+ addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
+
+ cy_as_hal_write_register(tag, addr, v) ;
+}
+
+/*
+ * This function must be defined to transfer a block of data from
+ * the WestBridge device. This function can use the burst read
+ * (DMA) capabilities of WestBridge to do this, or it can just
+ * copy the data using reads.
+ */
+void cy_as_hal_dma_setup_read(cy_as_hal_device_tag tag,
+ uint8_t ep, void *buf,
+ uint32_t size, uint16_t maxsize)
+{
+ uint32_t addr ;
+ uint16_t v ;
+
+ /*
+ * Note: "size" is the actual request size
+ * "maxsize" - is the P port fragment size
+ * No EP0 or EP1 traffic should get here
+ */
+ cy_as_hal_assert(ep != 0 && ep != 1) ;
+
+ /*
+ * If this asserts, we have an ordering problem.
+ * Another DMA request is coming down before the
+ * previous one has completed. we should not get
+ * new requests if current is still in process
+ */
+
+ cy_as_hal_assert(end_points[ep].buffer_valid == cy_false);
+
+ end_points[ep].buffer_valid = cy_true ;
+ end_points[ep].type = cy_as_hal_read ;
+ end_points[ep].pending = cy_true;
+ end_points[ep].req_xfer_cnt = 0;
+ end_points[ep].req_length = size;
+
+ if (size >= maxsize) {
+ /*
+ * set xfer size for very 1st DMA xfer operation
+ * port max packet size ( typically 512 or 1024)
+ */
+ end_points[ep].dma_xfer_sz = maxsize;
+ } else {
+ /*
+ * so that we could handle small xfers on in case
+ * of non-storage EPs
+ */
+ end_points[ep].dma_xfer_sz = size;
+ }
+
+ addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
+
+ if (end_points[ep].sg_list_enabled) {
+ /*
+ * Handle sg-list assisted EPs
+ * seg_xfer_cnt - keeps track of N of sent packets
+ * buf - pointer to the SG list
+ * data_p - data pointer for the 1st DMA segment
+ */
+ end_points[ep].seg_xfer_cnt = 0 ;
+ end_points[ep].sg_p = buf;
+ end_points[ep].data_p = sg_virt(end_points[ep].sg_p);
+
+ #ifdef DBGPRN_DMA_SETUP_RD
+ DBGPRN("cyasomaphal:DMA_setup_read sg_list EP:%d, "
+ "buf:%p, buf_va:%p, req_sz:%d, maxsz:%d\n",
+ ep,
+ buf,
+ end_points[ep].data_p,
+ size,
+ maxsize);
+ #endif
+ v = (end_points[ep].dma_xfer_sz &
+ CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK) |
+ CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
+ cy_as_hal_write_register(tag, addr, v);
+ } else {
+ /*
+ * Non sg list EP passed void *buf rather then scatterlist *sg
+ */
+ #ifdef DBGPRN_DMA_SETUP_RD
+ DBGPRN("%s:non-sg_list EP:%d,"
+ "RQ_sz:%d, maxsz:%d\n",
+ __func__, ep, size, maxsize);
+ #endif
+
+ end_points[ep].sg_p = NULL;
+
+ /*
+ * must be a VMA of a membuf in kernel space
+ */
+ end_points[ep].data_p = buf;
+
+ /*
+ * Program the EP DMA register for Storage endpoints only.
+ */
+ if (is_storage_e_p(ep)) {
+ v = (end_points[ep].dma_xfer_sz &
+ CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK) |
+ CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
+ cy_as_hal_write_register(tag, addr, v);
+ }
+ }
+}
+
+/*
+ * This function must be defined to allow the WB API to
+ * register a callback function that is called when a
+ * DMA transfer is complete.
+ */
+void cy_as_hal_dma_register_callback(cy_as_hal_device_tag tag,
+ cy_as_hal_dma_complete_callback cb)
+{
+ DBGPRN("<1>\n%s: WB API has registered a dma_complete callback:%x\n",
+ __func__, (uint32_t)cb);
+ callback = cb ;
+}
+
+/*
+ * This function must be defined to return the maximum size of
+ * DMA request that can be handled on the given endpoint. The
+ * return value should be the maximum size in bytes that the DMA
+ * module can handle.
+ */
+uint32_t cy_as_hal_dma_max_request_size(cy_as_hal_device_tag tag,
+ cy_as_end_point_number_t ep)
+{
+ /*
+ * Storage reads and writes are always done in 512 byte blocks.
+ * So, we do the count handling within the HAL, and save on
+ * some of the data transfer delay.
+ */
+ if ((ep == CYASSTORAGE_READ_EP_NUM) ||
+ (ep == CYASSTORAGE_WRITE_EP_NUM)) {
+ /* max DMA request size HAL can handle by itself */
+ return CYASSTORAGE_MAX_XFER_SIZE;
+ } else {
+ /*
+ * For the USB - Processor endpoints, the maximum transfer
+ * size depends on the speed of USB operation. So, we use
+ * the following constant to indicate to the API that
+ * splitting of the data into chunks less that or equal to
+ * the max transfer size should be handled internally.
+ */
+
+ /* DEFINED AS 0xffffffff in cyasdma.h */
+ return CY_AS_DMA_MAX_SIZE_HW_SIZE;
+ }
+}
+
+/*
+ * This function must be defined to set the state of the WAKEUP pin
+ * on the WestBridge device. Generally this is done via a GPIO of
+ * some type.
+ */
+cy_bool cy_as_hal_set_wakeup_pin(cy_as_hal_device_tag tag, cy_bool state)
+{
+ /*
+ * Not supported as of now.
+ */
+ return cy_false ;
+}
+
+void cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag)
+{
+ cy_as_hal_print_message("error: astoria PLL lock is lost\n") ;
+ cy_as_hal_print_message("please check the input voltage levels");
+ cy_as_hal_print_message("and clock, and restart the system\n") ;
+}
+
+/*
+ * Below are the functions that must be defined to provide the basic
+ * operating system services required by the API.
+ */
+
+/*
+ * This function is required by the API to allocate memory.
+ * This function is expected to work exactly like malloc().
+ */
+void *cy_as_hal_alloc(uint32_t cnt)
+{
+ void *ret_p ;
+
+ ret_p = kmalloc(cnt, GFP_ATOMIC) ;
+ return ret_p ;
+}
+
+/*
+ * This function is required by the API to free memory allocated
+ * with CyAsHalAlloc(). This function is'expected to work exacly
+ * like free().
+ */
+void cy_as_hal_free(void *mem_p)
+{
+ kfree(mem_p) ;
+}
+
+/*
+ * Allocator that can be used in interrupt context.
+ * We have to ensure that the kmalloc call does not
+ * sleep in this case.
+ */
+void *cy_as_hal_c_b_alloc(uint32_t cnt)
+{
+ void *ret_p ;
+
+ ret_p = kmalloc(cnt, GFP_ATOMIC) ;
+ return ret_p ;
+}
+
+/*
+ * This function is required to set a block of memory to a
+ * specific value. This function is expected to work exactly
+ * like memset()
+ */
+void cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt)
+{
+ memset(ptr, value, cnt) ;
+}
+
+/*
+ * This function is expected to create a sleep channel.
+ * The data structure that represents the sleep channel object
+ * sleep channel (which is Linux "wait_queue_head_t wq" for this paticular HAL)
+ * passed as a pointer, and allpocated by the caller
+ * (typically as a local var on the stack) "Create" word should read as
+ * "SleepOn", this func doesn't actually create anything
+ */
+cy_bool cy_as_hal_create_sleep_channel(cy_as_hal_sleep_channel *channel)
+{
+ init_waitqueue_head(&channel->wq) ;
+ return cy_true ;
+}
+
+/*
+ * for this particular HAL it doesn't actually destroy anything
+ * since no actual sleep object is created in CreateSleepChannel()
+ * sleep channel is given by the pointer in the argument.
+ */
+cy_bool cy_as_hal_destroy_sleep_channel(cy_as_hal_sleep_channel *channel)
+{
+ return cy_true ;
+}
+
+/*
+ * platform specific wakeable Sleep implementation
+ */
+cy_bool cy_as_hal_sleep_on(cy_as_hal_sleep_channel *channel, uint32_t ms)
+{
+ wait_event_interruptible_timeout(channel->wq, 0, ((ms * HZ)/1000)) ;
+ return cy_true ;
+}
+
+/*
+ * wakes up the process waiting on the CHANNEL
+ */
+cy_bool cy_as_hal_wake(cy_as_hal_sleep_channel *channel)
+{
+ wake_up_interruptible_all(&channel->wq);
+ return cy_true ;
+}
+
+uint32_t cy_as_hal_disable_interrupts()
+{
+ if (0 == intr__enable)
+ ;
+
+ intr__enable++ ;
+ return 0 ;
+}
+
+void cy_as_hal_enable_interrupts(uint32_t val)
+{
+ intr__enable-- ;
+ if (0 == intr__enable)
+ ;
+}
+
+/*
+ * Sleep atleast 150ns, cpu dependent
+ */
+void cy_as_hal_sleep150(void)
+{
+ uint32_t i, j;
+
+ j = 0;
+ for (i = 0; i < 1000; i++)
+ j += (~i);
+}
+
+void cy_as_hal_sleep(uint32_t ms)
+{
+ cy_as_hal_sleep_channel channel;
+
+ cy_as_hal_create_sleep_channel(&channel) ;
+ cy_as_hal_sleep_on(&channel, ms) ;
+ cy_as_hal_destroy_sleep_channel(&channel) ;
+}
+
+cy_bool cy_as_hal_is_polling()
+{
+ return cy_false;
+}
+
+void cy_as_hal_c_b_free(void *ptr)
+{
+ cy_as_hal_free(ptr);
+}
+
+/*
+ * suppose to reinstate the astoria registers
+ * that may be clobbered in sleep mode
+ */
+void cy_as_hal_init_dev_registers(cy_as_hal_device_tag tag,
+ cy_bool is_standby_wakeup)
+{
+ /* specific to SPI, no implementation required */
+ (void) tag;
+ (void) is_standby_wakeup;
+}
+
+void cy_as_hal_read_regs_before_standby(cy_as_hal_device_tag tag)
+{
+ /* specific to SPI, no implementation required */
+ (void) tag;
+}
+
+cy_bool cy_as_hal_sync_device_clocks(cy_as_hal_device_tag tag)
+{
+ /*
+ * we are in asynchronous mode. so no need to handle this
+ */
+ return true;
+}
+
+/*
+ * init OMAP h/w resources
+ */
+int start_o_m_a_p_kernel(const char *pgm,
+ cy_as_hal_device_tag *tag, cy_bool debug)
+{
+ cy_as_omap_dev_kernel *dev_p ;
+ int i;
+ u16 data16[4];
+ u8 pncfg_reg;
+
+ /*
+ * No debug mode support through argument as of now
+ */
+ (void)debug;
+
+ DBGPRN(KERN_INFO"starting OMAP34xx HAL...\n");
+
+ /*
+ * Initialize the HAL level endpoint DMA data.
+ */
+ for (i = 0 ; i < sizeof(end_points)/sizeof(end_points[0]) ; i++) {
+ end_points[i].data_p = 0 ;
+ end_points[i].pending = cy_false ;
+ end_points[i].size = 0 ;
+ end_points[i].type = cy_as_hal_none ;
+ end_points[i].sg_list_enabled = cy_false;
+
+ /*
+ * by default the DMA transfers to/from the E_ps don't
+ * use sg_list that implies that the upper devices like
+ * blockdevice have to enable it for the E_ps in their
+ * initialization code
+ */
+ }
+
+ /*
+ * allocate memory for OMAP HAL
+ */
+ dev_p = (cy_as_omap_dev_kernel *)cy_as_hal_alloc(
+ sizeof(cy_as_omap_dev_kernel)) ;
+ if (dev_p == 0) {
+ cy_as_hal_print_message("out of memory allocating OMAP"
+ "device structure\n") ;
+ return 0 ;
+ }
+
+ dev_p->m_sig = CY_AS_OMAP_KERNEL_HAL_SIG;
+
+ /*
+ * initialize OMAP hardware and StartOMAPKernelall gpio pins
+ */
+ dev_p->m_addr_base = (void *)cy_as_hal_processor_hw_init();
+
+ /*
+ * Now perform a hard reset of the device to have
+ * the new settings take effect
+ */
+ __gpio_set_value(AST_WAKEUP, 1);
+
+ /*
+ * do Astoria h/w reset
+ */
+ DBGPRN(KERN_INFO"-_-_pulse -> westbridge RST pin\n");
+
+ /*
+ * NEGATIVE PULSE on RST pin
+ */
+ __gpio_set_value(AST_RESET, 0);
+ mdelay(1);
+ __gpio_set_value(AST_RESET, 1);
+ mdelay(50);
+
+ /*
+ * note AFTER reset PNAND interface is 8 bit mode
+ * so if gpmc Is configured in 8 bit mode upper half will be FF
+ */
+ pncfg_reg = ast_p_nand_casdo_read(CY_AS_MEM_PNAND_CFG);
+
+#ifdef PNAND_16BIT_MODE
+
+ /*
+ * switch to 16 bit mode, force NON-LNA LBD mode, 3 RA addr bytes
+ */
+ ast_p_nand_casdi_write(CY_AS_MEM_PNAND_CFG, 0x0001);
+
+ /*
+ * now in order to continue to talk to astoria
+ * sw OMAP GPMC into 16 bit mode as well
+ */
+ cy_as_hal_gpmc_enable_16bit_bus(cy_true);
+#else
+ /* Astoria and GPMC are already in 8 bit mode, jsut initialize PNAND_CFG */
+ ast_p_nand_casdi_write(CY_AS_MEM_PNAND_CFG, 0x0000);
+#endif
+
+ /*
+ * NOTE: if you want to capture bus activity on the LA,
+ * don't use printks in between the activities you want to capture.
+ * prinks may take milliseconds, and the data of interest
+ * will fall outside the LA capture window/buffer
+ */
+ data16[0] = ast_p_nand_casdo_read(CY_AS_MEM_CM_WB_CFG_ID);
+ data16[1] = ast_p_nand_casdo_read(CY_AS_MEM_PNAND_CFG);
+
+ if (data16[0] != 0xA200) {
+ /*
+ * astoria device is not found
+ */
+ printk(KERN_ERR "ERROR: astoria device is not found, CY_AS_MEM_CM_WB_CFG_ID ");
+ printk(KERN_ERR "read returned:%4.4X: CY_AS_MEM_PNAND_CFG:%4.4x !\n",
+ data16[0], data16[0]);
+ goto bus_acc_error;
+ }
+
+ cy_as_hal_print_message(KERN_INFO" register access CASDO test:"
+ "\n CY_AS_MEM_CM_WB_CFG_ID:%4.4x\n"
+ "PNAND_CFG after RST:%4.4x\n "
+ "CY_AS_MEM_PNAND_CFG"
+ "after cfg_wr:%4.4x\n\n",
+ data16[0], pncfg_reg, data16[1]);
+
+ dev_p->thread_flag = 1 ;
+ spin_lock_init(&int_lock) ;
+ dev_p->m_next_p = m_omap_list_p ;
+
+ m_omap_list_p = dev_p ;
+ *tag = dev_p;
+
+ cy_as_hal_configure_interrupts((void *)dev_p);
+
+ cy_as_hal_print_message(KERN_INFO"OMAP3430__hal started tag:%p"
+ ", kernel HZ:%d\n", dev_p, HZ);
+
+ /*
+ *make processor to storage endpoints SG assisted by default
+ */
+ cy_as_hal_set_ep_dma_mode(4, true);
+ cy_as_hal_set_ep_dma_mode(8, true);
+
+ return 1 ;
+
+ /*
+ * there's been a NAND bus access error or
+ * astoria device is not connected
+ */
+bus_acc_error:
+ /*
+ * at this point hal tag hasn't been set yet
+ * so the device will not call omap_stop
+ */
+ cy_as_hal_omap_hardware_deinit(dev_p);
+ cy_as_hal_free(dev_p) ;
+ return 0;
+}
+
+#else
+/*
+ * Some compilers do not like empty C files, so if the OMAP hal is not being
+ * compiled, we compile this single function. We do this so that for a
+ * given target HAL there are not multiple sources for the HAL functions.
+ */
+void my_o_m_a_p_kernel_hal_dummy_function(void)
+{
+}
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h
new file mode 100644
index 000000000000..6ce78ae6c3bb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h
@@ -0,0 +1,55 @@
+/* Cypress West Bridge API header file (cyashaldef.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASHALDEF_H_
+#define _INCLUDED_CYASHALDEF_H_
+
+/* Summary
+ * If set to TRUE, the basic numeric types are defined by the
+ * West Bridge API code
+ *
+ * Description
+ * The West Bridge API relies on some basic integral types to be
+ * defined. These types include uint8_t, int8_t, uint16_t,
+ * int16_t, uint32_t, and int32_t. If this macro is defined the
+ * West Bridge API will define these types based on some basic
+ * assumptions. If this value is set and the West Bridge API is
+ * used to set these types, the definition of these types must be
+ * examined to insure that they are appropriate for the given
+ * target architecture and compiler.
+ *
+ * Notes
+ * It is preferred that if the basic platform development
+ * environment defines these types that the CY_DEFINE_BASIC_TYPES
+ * macro be undefined and the appropriate target system header file
+ * be added to the file cyashaldef.h.
+ */
+
+#include <linux/types.h>
+
+
+#if !defined(__doxygen__)
+typedef int cy_bool ;
+#define cy_true (1)
+#define cy_false (0)
+#endif
+
+#endif /* _INCLUDED_CYASHALDEF_H_ */
diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h
new file mode 100644
index 000000000000..c40279b29109
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h
@@ -0,0 +1,319 @@
+/* Cypress Antioch HAL for OMAP KERNEL header file (cyashalomapkernel.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * This file contains the defintion of the hardware abstraction
+ * layer on OMAP3430 talking to the West Bridge Astoria device
+ */
+
+
+#ifndef _INCLUDED_CYASHALOMAP_KERNEL_H_
+#define _INCLUDED_CYASHALOMAP_KERNEL_H_
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/string.h>
+/* include does not seem to work
+ * moving for patch submission
+#include <mach/gpmc.h>
+*/
+#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
+typedef struct cy_as_hal_sleep_channel_t {
+ wait_queue_head_t wq ;
+} cy_as_hal_sleep_channel ;
+
+/* moved to staging location, eventual location
+ * considered is here
+#include <mach/westbridge/cyashaldef.h>
+#include <linux/westbridge/cyastypes.h>
+#include <linux/westbridge/cyas_cplus_start.h>
+*/
+#include "../cyashaldef.h"
+#include "../../../../../../../include/linux/westbridge/cyastypes.h"
+#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h"
+#include "cyasomapdev_kernel.h"
+
+/*
+ * Below are the data structures that must be defined by the HAL layer
+ */
+
+/*
+ * The HAL layer must define a TAG for identifying a specific Astoria
+ * device in the system. In this case the tag is a void * which is
+ * really an OMAP device pointer
+ */
+typedef void *cy_as_hal_device_tag ;
+
+
+/* This must be included after the CyAsHalDeviceTag type is defined */
+
+/* moved to staging location, eventual location
+ * considered is here
+ * #include <linux/westbridge/cyashalcb.h>
+*/
+#include "../../../../../../../include/linux/westbridge/cyashalcb.h"
+/*
+ * Below are the functions that communicate with the West Bridge
+ * device. These are system dependent and must be defined by
+ * the HAL layer for a given system.
+ */
+
+/*
+ * This function must be defined to write a register within the Antioch
+ * device. The addr value is the address of the register to write with
+ * respect to the base address of the Antioch device.
+ */
+void
+cy_as_hal_write_register(cy_as_hal_device_tag tag,
+ uint16_t addr, uint16_t data) ;
+
+/*
+ * This function must be defined to read a register from
+ * the west bridge device. The addr value is the address of
+ * the register to read with respect to the base address
+ * of the west bridge device.
+ */
+uint16_t
+cy_as_hal_read_register(cy_as_hal_device_tag tag, uint16_t addr) ;
+
+/*
+ * This function must be defined to transfer a block of data
+ * to the west bridge device. This function can use the burst write
+ * (DMA) capabilities of Antioch to do this, or it can just copy
+ * the data using writes.
+ */
+void
+cy_as_hal_dma_setup_write(cy_as_hal_device_tag tag,
+ uint8_t ep, void *buf, uint32_t size, uint16_t maxsize) ;
+
+/*
+ * This function must be defined to transfer a block of data
+ * from the Antioch device. This function can use the burst
+ * read (DMA) capabilities of Antioch to do this, or it can
+ * just copy the data using reads.
+ */
+void
+cy_as_hal_dma_setup_read(cy_as_hal_device_tag tag, uint8_t ep,
+ void *buf, uint32_t size, uint16_t maxsize) ;
+
+/*
+ * This function must be defined to cancel any pending DMA request.
+ */
+void
+cy_as_hal_dma_cancel_request(cy_as_hal_device_tag tag, uint8_t ep) ;
+
+/*
+ * This function must be defined to allow the Antioch API to
+ * register a callback function that is called when a DMA transfer
+ * is complete.
+ */
+void
+cy_as_hal_dma_register_callback(cy_as_hal_device_tag tag,
+ cy_as_hal_dma_complete_callback cb) ;
+
+/*
+ * This function must be defined to return the maximum size of DMA
+ * request that can be handled on the given endpoint. The return
+ * value should be the maximum size in bytes that the DMA module can
+ * handle.
+ */
+uint32_t
+cy_as_hal_dma_max_request_size(cy_as_hal_device_tag tag,
+ cy_as_end_point_number_t ep) ;
+
+/*
+ * This function must be defined to set the state of the WAKEUP pin
+ * on the Antioch device. Generally this is done via a GPIO of some
+ * type.
+ */
+cy_bool
+cy_as_hal_set_wakeup_pin(cy_as_hal_device_tag tag, cy_bool state) ;
+
+/*
+ * This function is called when the Antioch PLL loses lock, because
+ * of a problem in the supply voltage or the input clock.
+ */
+void
+cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag) ;
+
+
+/**********************************************************************
+ *
+ * Below are the functions that must be defined to provide the basic
+ * operating system services required by the API.
+ *
+***********************************************************************/
+
+/*
+ * This function is required by the API to allocate memory. This function
+ * is expected to work exactly like malloc().
+ */
+void *
+cy_as_hal_alloc(uint32_t cnt) ;
+
+/*
+ * This function is required by the API to free memory allocated with
+ * CyAsHalAlloc(). This function is expected to work exacly like free().
+ */
+void
+cy_as_hal_free(void *mem_p) ;
+
+/*
+ * This function is required by the API to allocate memory during a
+ * callback. This function must be able to provide storage at inturupt
+ * time.
+ */
+void *
+cy_as_hal_c_b_alloc(uint32_t cnt) ;
+
+/*
+ * This function is required by the API to free memory allocated with
+ * CyAsCBHalAlloc().
+ */
+void
+cy_as_hal_c_b_free(void *ptr) ;
+
+/*
+ * This function is required to set a block of memory to a specific
+ * value. This function is expected to work exactly like memset()
+ */
+void
+cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt) ;
+
+/*
+ * This function is expected to create a sleep channel. The data
+ * structure that represents the sleep channel is given by the
+ * pointer in the argument.
+ */
+cy_bool
+cy_as_hal_create_sleep_channel(cy_as_hal_sleep_channel *channel) ;
+
+/*
+ * This function is expected to destroy a sleep channel. The data
+ * structure that represents the sleep channel is given by
+ * the pointer in the argument.
+ */
+
+
+cy_bool
+cy_as_hal_destroy_sleep_channel(cy_as_hal_sleep_channel *channel) ;
+
+cy_bool
+cy_as_hal_sleep_on(cy_as_hal_sleep_channel *channel, uint32_t ms) ;
+
+cy_bool
+cy_as_hal_wake(cy_as_hal_sleep_channel *channel) ;
+
+uint32_t
+cy_as_hal_disable_interrupts(void) ;
+
+void
+cy_as_hal_enable_interrupts(uint32_t);
+
+void
+cy_as_hal_sleep150(void);
+
+void
+cy_as_hal_sleep(uint32_t ms);
+
+cy_bool
+cy_as_hal_is_polling(void);
+
+void cy_as_hal_init_dev_registers(cy_as_hal_device_tag tag,
+ cy_bool is_standby_wakeup);
+
+/*
+ * required only in spi mode
+ */
+cy_bool cy_as_hal_sync_device_clocks(cy_as_hal_device_tag tag);
+
+void cy_as_hal_read_regs_before_standby(cy_as_hal_device_tag tag);
+
+
+#ifndef NDEBUG
+#define cy_as_hal_assert(cond) if (!(cond))\
+ printk(KERN_WARNING"assertion failed at %s:%d\n", __FILE__, __LINE__);
+#else
+#define cy_as_hal_assert(cond)
+#endif
+
+#define cy_as_hal_print_message printk
+
+/* removable debug printks */
+#ifndef WESTBRIDGE_NDEBUG
+#define DBG_PRINT_ENABLED
+#endif
+
+/*#define MBOX_ACCESS_DBG_PRINT_ENABLED*/
+
+
+#ifdef DBG_PRINT_ENABLED
+ /* Debug printing enabled */
+
+ #define DBGPRN(...) printk(__VA_ARGS__)
+ #define DBGPRN_FUNC_NAME printk("<1> %x:_func: %s\n", \
+ current->pid, __func__)
+
+#else
+ /** NO DEBUG PRINTING **/
+ #define DBGPRN(...)
+ #define DBGPRN_FUNC_NAME
+
+#endif
+
+/*
+CyAsMiscSetLogLevel(uint8_t level)
+{
+ debug_level = level ;
+}
+
+#ifdef CY_AS_LOG_SUPPORT
+
+void
+cy_as_log_debug_message(int level, const char *str)
+{
+ if (level <= debug_level)
+ cy_as_hal_print_message("log %d: %s\n", level, str) ;
+}
+*/
+
+
+/*
+ * print buffer helper
+ */
+void cyashal_prn_buf(void *buf, uint16_t offset, int len);
+
+/*
+ * These are the functions that are not part of the HAL layer,
+ * but are required to be called for this HAL.
+ */
+int start_o_m_a_p_kernel(const char *pgm,
+ cy_as_hal_device_tag *tag, cy_bool debug) ;
+int stop_o_m_a_p_kernel(const char *pgm, cy_as_hal_device_tag tag) ;
+int omap_start_intr(cy_as_hal_device_tag tag) ;
+void cy_as_hal_set_ep_dma_mode(uint8_t ep, bool sg_xfer_enabled);
+
+/* moved to staging location
+#include <linux/westbridge/cyas_cplus_end.h>
+*/
+#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h"
+#endif
diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h
new file mode 100644
index 000000000000..3eee192ffe89
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h
@@ -0,0 +1,558 @@
+/*
+ OMAP3430 ZOOM MDK astoria interface defs(cyasmemmap.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+/* include does not seem to work
+ * moving for patch submission
+#include <mach/gpmc.h>
+#include <mach/mux.h>
+*/
+#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
+#include <linux/../../arch/arm/plat-omap/include/plat/mux.h>
+
+#ifndef _INCLUDED_CYASMEMMAP_H_
+#define _INCLUDED_CYASMEMMAP_H_
+
+/* defines copied from OMAP kernel branch */
+
+#define OMAP2_PULL_UP (1 << 4)
+#define OMAP2_PULL_ENA (1 << 3)
+#define OMAP34XX_MUX_MODE0 0
+#define OMAP34XX_MUX_MODE4 4
+#define OMAP3_INPUT_EN (1 << 8)
+#define OMAP34XX_PIN_INPUT_PULLUP (OMAP2_PULL_ENA | OMAP3_INPUT_EN \
+ | OMAP2_PULL_UP)
+
+/*
+ * for OMAP3430 <-> astoria : ADmux mode, 8 bit data path
+ * WB Signal- OMAP3430 signal COMMENTS
+ * --------------------------- --------------------
+ * CS_L -GPMC_nCS4_GPIO_53 ZOOM I SOM board
+ * signal: up_nCS_A_EXT
+ * AD[7:0]-upD[7:0] buffered on the
+ * transposer board
+ * GPMC_ADDR
+ * [A8:A1]->upD[7:0]
+ * INT# -GPMC_nWP_GPIO_62
+ * DACK -N/C not conected
+ * WAKEUP-GPIO_167
+ * RESET-GPIO_126
+ * R/B -GPMC_WAIT2_GPIO_64
+ * -------------------------------------------
+ * The address range for nCS1B is 0x06000000 - 0x07FF FFFF.
+*/
+
+/*
+ *OMAP_ZOOM LEDS
+ */
+#define LED_0 156
+#define LED_1 128
+#define LED_2 64
+#define LED_3 60
+
+#define HIGH 1
+#define LOW 1
+
+/*
+ *omap GPIO number
+ */
+#define AST_WAKEUP 167
+#define AST_RESET 126
+#define AST__rn_b 64
+
+/*
+ * NOTE THIS PIN IS USED AS WP for OMAP NAND
+ */
+#define AST_INT 62
+
+/*
+ * as an I/O, it is actually controlled by GPMC
+ */
+#define AST_CS 55
+
+
+/*
+ *GPMC prefetch engine
+ */
+
+/* register and its bit fields */
+#define GPMC_PREFETCH_CONFIG1 0x01E0
+
+ /*32 bytes for 16 bit pnand mode*/
+ #define PFE_THRESHOLD 31
+
+ /*
+ * bit fields
+ * PF_ACCESSMODE - 0 - read mode, 1 - write mode
+ * PF_DMAMODE - 0 - default only intr line signal will be generated
+ * PF_SYNCHROMODE - default 0 - engin will start access as soon as
+ * ctrl re STARTENGINE is set
+ * PF_WAITPINSEL - FOR synchro mode selects WAIT pin whch edge
+ * will be monitored
+ * PF_EN_ENGINE - 1- ENABLES ENGINE, but it needs to be started after
+ * that C ctrl reg bit 0
+ * PF_FIFO_THRESHOLD - FIFO threshhold in number of BUS(8 or 16) words
+ * PF_WEIGHTED_PRIO - NUM of cycles granted to PFE if RND_ROBIN
+ * prioritization is enabled
+ * PF_ROUND_ROBIN - if enabled, gives priority to other CS, but
+ * reserves NUM of cycles for PFE's turn
+ * PF_ENGIN_CS_SEL - GPMC CS assotiated with PFE function
+ */
+ #define PF_ACCESSMODE (0 << 0)
+ #define PF_DMAMODE (0 << 2)
+ #define PF_SYNCHROMODE (0 << 3)
+ #define PF_WAITPINSEL (0x0 << 4)
+ #define PF_EN_ENGINE (1 << 7)
+ #define PF_FIFO_THRESHOLD (PFE_THRESHOLD << 8)
+ #define PF_WEIGHTED_PRIO (0x0 << 16)
+ #define PF_ROUND_ROBIN (0 << 23)
+ #define PF_ENGIN_CS_SEL (AST_GPMC_CS << 24)
+ #define PF_EN_OPTIM_ACC (0 << 27)
+ #define PF_CYCLEOPTIM (0x0 << 28)
+
+#define GPMC_PREFETCH_CONFIG1_VAL (PF_ACCESSMODE | \
+ PF_DMAMODE | PF_SYNCHROMODE | \
+ PF_WAITPINSEL | PF_EN_ENGINE | \
+ PF_FIFO_THRESHOLD | PF_FIFO_THRESHOLD | \
+ PF_WEIGHTED_PRIO | PF_ROUND_ROBIN | \
+ PF_ENGIN_CS_SEL | PF_EN_OPTIM_ACC | \
+ PF_CYCLEOPTIM)
+
+/* register and its bit fields */
+#define GPMC_PREFETCH_CONFIG2 0x01E4
+ /*
+ * bit fields
+ * 14 bit field NOTE this counts is also
+ * is in number of BUS(8 or 16) words
+ */
+ #define PF_TRANSFERCOUNT (0x000)
+
+
+/* register and its bit fields */
+#define GPMC_PREFETCH_CONTROL 0x01EC
+ /*
+ * bit fields , ONLY BIT 0 is implemented
+ * PFWE engin must be programmed with this bit = 0
+ */
+ #define PFPW_STARTENGINE (1 << 0)
+
+/* register and its bit fields */
+#define GPMC_PREFETCH_STATUS 0x01F0
+
+ /* */
+ #define PFE_FIFO_THRESHOLD (1 << 16)
+
+/*
+ * GPMC posted write/prefetch engine end
+ */
+
+
+/*
+ * chip select number on GPMC ( 0..7 )
+ */
+#define AST_GPMC_CS 4
+
+/*
+ * not connected
+ */
+#define AST_DACK 00
+
+
+/*
+ * Physical address above the NAND flash
+ * we use CS For mapping in OMAP3430 RAM space use 0x0600 0000
+ */
+#define CYAS_DEV_BASE_ADDR (0x20000000)
+
+#define CYAS_DEV_MAX_ADDR (0xFF)
+#define CYAS_DEV_ADDR_RANGE (CYAS_DEV_MAX_ADDR << 1)
+
+#ifdef p_s_r_a_m_INTERFACE
+ /* in CRAM or PSRAM mode OMAP A1..An wires-> Astoria, there is no A0 line */
+ #define CYAS_DEV_CALC_ADDR(cyas_addr) (cyas_addr << 1)
+ #define CYAS_DEV_CALC_EP_ADDR(ep) (ep << 1)
+#else
+ /*
+ * For pNAND interface it depends on NAND emulation mode
+ * SBD/LBD etc we use NON-LNA_LBD mode, so it goes like this:
+ * forlbd <CMD><CA0,CA1,RA0,RA1,RA2> <CMD>,
+ * where CA1 address must have bits 2,3 = "11"
+ * ep is mapped into RA1 bits {4:0}
+ */
+ #define CYAS_DEV_CALC_ADDR(cyas_addr) (cyas_addr | 0x0c00)
+ #define CYAS_DEV_CALC_EP_ADDR(ep) ep
+#endif
+
+/*
+ *OMAP3430 i/o access macros
+ */
+#define IORD32(addr) (*(volatile u32 *)(addr))
+#define IOWR32(addr, val) (*(volatile u32 *)(addr) = val)
+
+#define IORD16(addr) (*(volatile u16 *)(addr))
+#define IOWR16(addr, val) (*(volatile u16 *)(addr) = val)
+
+#define IORD8(addr) (*(volatile u8 *)(addr))
+#define IOWR8(addr, val) (*(volatile u8 *)(addr) = val)
+
+/*
+ * local defines for accessing to OMAP GPIO ***
+ */
+#define CTLPADCONF_BASE_ADDR 0x48002000
+#define CTLPADCONF_SIZE 0x1000
+
+#define GPIO1_BASE_ADDR 0x48310000
+#define GPIO2_BASE_ADDR 0x49050000
+#define GPIO3_BASE_ADDR 0x49052000
+#define GPIO4_BASE_ADDR 0x49054000
+#define GPIO5_BASE_ADDR 0x49056000
+#define GPIO6_BASE_ADDR 0x49058000
+#define GPIO_SPACE_SIZE 0x1000
+
+
+/*
+ * OMAP3430 GPMC timing for pNAND interface
+ */
+#define GPMC_BASE 0x6E000000
+#define GPMC_REGION_SIZE 0x1000
+#define GPMC_CONFIG_REG (0x50)
+
+/*
+ * bit 0 in the GPMC_CONFIG_REG
+ */
+#define NAND_FORCE_POSTED_WRITE_B 1
+
+/*
+ * WAIT2STATUS, must be (1 << 10)
+ */
+#define AS_WAIT_PIN_MASK (1 << 10)
+
+
+/*
+ * GPMC_CONFIG(reg number [1..7] [for chip sel CS[0..7])
+ */
+#define GPMC_CFG_REG(N, CS) ((0x60 + (4*(N-1))) + (0x30*CS))
+
+/*
+ *gpmc nand registers for CS4
+ */
+#define AST_GPMC_NAND_CMD (0x7c + (0x30*AST_GPMC_CS))
+#define AST_GPMC_NAND_ADDR (0x80 + (0x30*AST_GPMC_CS))
+#define AST_GPMC_NAND_DATA (0x84 + (0x30*AST_GPMC_CS))
+
+#define GPMC_STAT_REG (0x54)
+#define GPMC_ERR_TYPE (0x48)
+
+/*
+ * we get "gpmc_base" from kernel
+ */
+#define GPMC_VMA(offset) (gpmc_base + offset)
+
+/*
+ * GPMC CS space VMA start address
+ */
+#define GPMC_CS_VMA(offset) (gpmc_data_vma + offset)
+
+/*
+ * PAD_CFG mux space VMA
+ */
+#define PADCFG_VMA(offset) (iomux_vma + offset)
+
+/*
+ * CONFIG1: by default, sngle access, async r/w RD_MULTIPLE[30]
+ * WR_MULTIPLE[28]; GPMC_FCL_DIV[1:0]
+ */
+#define GPMC_FCLK_DIV ((0) << 0)
+
+/*
+ * ADDITIONAL DIVIDER FOR ALL TIMING PARAMS
+ */
+#define TIME_GRAN_SCALE ((0) << 4)
+
+/*
+ * for use by gpmc_set_timings api, measured in ns, not clocks
+ */
+#define WB_GPMC_BUSCYC_t (7 * 6)
+#define WB_GPMC_CS_t_o_n (0)
+#define WB_GPMC_ADV_t_o_n (0)
+#define WB_GPMC_OE_t_o_n (0)
+#define WB_GPMC_OE_t_o_f_f (5 * 6)
+#define WB_GPMC_WE_t_o_n (1 * 6)
+#define WB_GPMC_WE_t_o_f_f (5 * 6)
+#define WB_GPMC_RDS_ADJ (2 * 6)
+#define WB_GPMC_RD_t_a_c_c (WB_GPMC_OE_t_o_f_f + WB_GPMC_RDS_ADJ)
+#define WB_GPMC_WR_t_a_c_c (WB_GPMC_BUSCYC_t)
+
+#define DIR_OUT 0
+#define DIR_INP 1
+#define DRV_HI 1
+#define DRV_LO 0
+
+/*
+ * GPMC_CONFIG7[cs] register bit fields
+ * AS_CS_MASK - 3 bit mask for A26,A25,A24,
+ * AS_CS_BADDR - 6 BIT VALUE A29 ...A24
+ * CSVALID_B - CSVALID bit on GPMC_CONFIG7[cs] register
+ */
+#define AS_CS_MASK (0X7 << 8)
+#define AS_CS_BADDR 0x02
+#define CSVALID_B (1 << 6)
+
+/*
+ * DEFINE OMAP34XX GPIO OFFSETS (should have been defined in kernel /arch
+ * these are offsets from the BASE_ADDRESS of the GPIO BLOCK
+ */
+#define GPIO_REVISION 0x000
+#define GPIO_SYSCONFIG 0x010
+#define GPIO_SYSSTATUS1 0x014
+#define GPIO_IRQSTATUS1 0x018
+#define GPIO_IRQENABLE1 0x01C
+#define GPIO_IRQSTATUS2 0x028
+#define GPIO_CTRL 0x030
+#define GPIO_OE 0x034
+#define GPIO_DATA_IN 0x038
+#define GPIO_DATA_OUT 0x03C
+#define GPIO_LEVELDETECT0 0x040
+#define GPIO_LEVELDETECT1 0x044
+#define GPIO_RISINGDETECT 0x048
+#define GPIO_FALLINGDETECT 0x04c
+#define GPIO_CLEAR_DATAOUT 0x090
+#define GPIO_SET_DATAOUT 0x094
+
+typedef struct {
+ char *name;
+ u32 phy_addr;
+ u32 virt_addr;
+ u32 size;
+} io2vma_tab_t;
+
+/*
+ * GPIO phy to translation VMA table
+ */
+static io2vma_tab_t gpio_vma_tab[6] = {
+ {"GPIO1_BASE_ADDR", GPIO1_BASE_ADDR , 0 , GPIO_SPACE_SIZE},
+ {"GPIO2_BASE_ADDR", GPIO2_BASE_ADDR , 0 , GPIO_SPACE_SIZE},
+ {"GPIO3_BASE_ADDR", GPIO3_BASE_ADDR , 0 , GPIO_SPACE_SIZE},
+ {"GPIO4_BASE_ADDR", GPIO4_BASE_ADDR , 0 , GPIO_SPACE_SIZE},
+ {"GPIO5_BASE_ADDR", GPIO5_BASE_ADDR , 0 , GPIO_SPACE_SIZE},
+ {"GPIO6_BASE_ADDR", GPIO6_BASE_ADDR , 0 , GPIO_SPACE_SIZE}
+};
+/*
+ * name - USER signal name assigned to the pin ( for printks)
+ * mux_func - enum index NAME for the pad_cfg function
+ * pin_num - pin_number if mux_func is GPIO, if not a GPIO it is -1
+ * mux_ptr - pointer to the corresponding pad_cfg_reg
+ * (used for pad release )
+ * mux_save - preserve here original PAD_CNF value for this
+ * pin (used for pad release)
+ * dir - if GPIO: 0 - OUT , 1 - IN
+ * dir_save - save original pin direction
+ * drv - initial drive level "0" or "1"
+ * drv_save - save original pin drive level
+ * valid - 1 if successfuly configured
+*/
+typedef struct {
+ char *name;
+ u32 mux_func;
+ int pin_num;
+ u16 *mux_ptr;
+ u16 mux_save;
+ u8 dir;
+ u8 dir_save;
+ u8 drv;
+ u8 drv_save;
+ u8 valid;
+} user_pad_cfg_t;
+
+/*
+ * need to ensure that enums are in sync with the
+ * omap_mux_pin_cfg table, these enums designate
+ * functions that OMAP pads can be configured to
+ */
+enum {
+ B23_OMAP3430_GPIO_167,
+ D23_OMAP3430_GPIO_126,
+ H1_OMAP3430_GPIO_62,
+ H1_OMAP3430_GPMC_n_w_p,
+ T8_OMAP3430_GPMC_n_c_s4,
+ T8_OMAP3430_GPIO_55,
+ R25_OMAP3430_GPIO_156,
+ R27_OMAP3430_GPIO_128,
+ K8_OMAP3430_GPIO_64,
+ K8_GPMC_WAIT2,
+ G3_OMAP3430_GPIO_60,
+ G3_OMAP3430_n_b_e0_CLE,
+ C6_GPMC_WAIT3,
+ J1_OMAP3430_GPIO_61,
+ C6_OMAP3430_GPIO_65,
+
+ END_OF_TABLE
+};
+
+/*
+ * number of GPIOS we plan to grab
+ */
+#define GPIO_SLOTS 8
+
+/*
+ * user_pads_init() reads(and saves) from/to this table
+ * used in conjunction with omap_3430_mux_t table in .h file
+ * because the way it's done in the kernel code
+ * TODO: implement restore of the the original cfg and i/o regs
+ */
+
+static user_pad_cfg_t user_pad_cfg[] = {
+ /*
+ * name,pad_func,pin_num, mux_ptr, mux_sav, dir,
+ * dir_sav, drv, drv_save, valid
+ */
+ {"AST_WAKEUP", B23_OMAP3430_GPIO_167, 167, NULL, 0,
+ DIR_OUT, 0, DRV_HI, 0, 0},
+ {"AST_RESET", D23_OMAP3430_GPIO_126, 126, NULL, 0,
+ DIR_OUT, 0, DRV_HI, 0, 0},
+ {"AST__rn_b", K8_GPMC_WAIT2, 64, NULL, 0,
+ DIR_INP, 0, 0, 0, 0},
+ {"AST_INTR", H1_OMAP3430_GPIO_62, 62, NULL, 0,
+ DIR_INP, 0, DRV_HI, 0, 0},
+ {"AST_CS", T8_OMAP3430_GPMC_n_c_s4, 55, NULL, 0,
+ DIR_OUT, 0, DRV_HI, 0, 0},
+ {"LED_0", R25_OMAP3430_GPIO_156, 156, NULL, 0,
+ DIR_OUT, 0, DRV_LO, 0, 0},
+ {"LED_1", R27_OMAP3430_GPIO_128, 128, NULL, 0,
+ DIR_OUT, 0, DRV_LO, 0, 0},
+ {"AST_CLE", G3_OMAP3430_n_b_e0_CLE , 60, NULL, 0,
+ DIR_OUT, 0, DRV_LO, 0, 0},
+ /*
+ * Z terminator, must always be present
+ * for sanity check, don't remove
+ */
+ {NULL}
+};
+
+#define GPIO_BANK(pin) (pin >> 5)
+#define REG_WIDTH 32
+#define GPIO_REG_VMA(pin_num, offset) \
+ (gpio_vma_tab[GPIO_BANK(pin_num)].virt_addr + offset)
+
+/*
+ * OMAP GPIO_REG 32 BIT MASK for a bit or
+ * flag in gpio_No[0..191] apply it to a 32 bit
+ * location to set clear or check on a corresponding
+ * gpio bit or flag
+ */
+#define GPIO_REG_MASK(pin_num) (1 << \
+ (pin_num - (GPIO_BANK(pin_num) * REG_WIDTH)))
+
+/*
+ * OMAP GPIO registers bitwise access macros
+ */
+
+#define OMAP_GPIO_BIT(pin_num, reg) \
+ ((*((u32 *)GPIO_REG_VMA(pin_num, reg)) \
+ & GPIO_REG_MASK(pin_num)) ? 1 : 0)
+
+#define RD_OMAP_GPIO_BIT(pin_num, v) OMAP_GPIO_BIT(pin_num, reg)
+
+/*
+ *these are superfast set/clr bitbang macro, 48ns cyc tyme
+ */
+#define OMAP_SET_GPIO(pin_num) \
+ (*(u32 *)GPIO_REG_VMA(pin_num, GPIO_SET_DATAOUT) \
+ = GPIO_REG_MASK(pin_num))
+#define OMAP_CLR_GPIO(pin_num) \
+ (*(u32 *)GPIO_REG_VMA(pin_num, GPIO_CLEAR_DATAOUT) \
+ = GPIO_REG_MASK(pin_num))
+
+#define WR_OMAP_GPIO_BIT(pin_num, v) \
+ (v ? (*(u32 *)GPIO_REG_VMA(pin_num, \
+ GPIO_SET_DATAOUT) = GPIO_REG_MASK(pin_num)) \
+ : (*(u32 *)GPIO_REG_VMA(pin_num, \
+ GPIO_CLEAR_DATAOUT) = GPIO_REG_MASK(pin_num)))
+
+/*
+ * Note this pin cfg mimicks similar implementation
+ * in linux kernel, which unfortunately doesn't allow
+ * us to dynamically insert new custom GPIO mux
+ * configurations all REG definitions used in this
+ * applications. to add a new pad_cfg function, insert
+ * a new ENUM and new pin_cfg entry in omap_mux_pin_cfg[]
+ * table below
+ *
+ * offset - note this is a word offset since the
+ * SCM regs are 16 bit packed in one 32 bit word
+ * mux_val - just enough to describe pins used
+ */
+typedef struct {
+ char *name;
+ u16 offset;
+ u16 mux_val;
+} omap_3430_mux_t;
+
+/*
+ * "OUTIN" is configuration when DATA reg drives the
+ * pin but the level at the pin can be sensed
+ */
+#define PAD_AS_OUTIN (OMAP34XX_MUX_MODE4 | \
+ OMAP34XX_PIN_OUTPUT | OMAP34XX_PIN_INPUT)
+
+omap_3430_mux_t omap_mux_pin_cfg[] = {
+ /*
+ * B23_OMAP3430_GPIO_167 - GPIO func to PAD 167 WB wakeup
+ * D23_OMAP3430_GPIO_126 - drive GPIO_126 ( AST RESET)
+ * H1_OMAP3430_GPIO_62 - need a pullup on this pin
+ * H1_OMAP3430_GPMC_n_w_p - GPMC NAND CTRL n_w_p out
+ * T8_OMAP3430_GPMC_n_c_s4" - T8 is controlled b_y GPMC NAND ctrl
+ * R25_OMAP3430_GPIO_156 - OMAPZOOM drive LED_0
+ * R27_OMAP3430_GPIO_128 - OMAPZOOM drive LED_1
+ * K8_OMAP3430_GPIO_64 - OMAPZOOM drive LED_2
+ * K8_GPMC_WAIT2 - GPMC WAIT2 function on PAD K8
+ * G3_OMAP3430_GPIO_60 - OMAPZOOM drive LED_3
+ * G3_OMAP3430_n_b_e0_CLE -GPMC NAND ctrl CLE signal
+ */
+
+ {"B23_OMAP3430_GPIO_167", 0x0130, (OMAP34XX_MUX_MODE4)},
+ {"D23_OMAP3430_GPIO_126", 0x0132, (OMAP34XX_MUX_MODE4)},
+ {"H1_OMAP3430_GPIO_62", 0x00CA, (OMAP34XX_MUX_MODE4 |
+ OMAP3_INPUT_EN | OMAP34XX_PIN_INPUT_PULLUP) },
+ {"H1_OMAP3430_GPMC_n_w_p", 0x00CA, (OMAP34XX_MUX_MODE0)},
+ {"T8_OMAP3430_GPMC_n_c_s4", 0x00B6, (OMAP34XX_MUX_MODE0) },
+ {"T8_OMAP3430_GPIO_55", 0x00B6, (OMAP34XX_MUX_MODE4) },
+ {"R25_OMAP3430_GPIO_156", 0x018C, (OMAP34XX_MUX_MODE4) },
+ {"R27_OMAP3430_GPIO_128", 0x0154, (OMAP34XX_MUX_MODE4) },
+ {"K8_OMAP3430_GPIO_64", 0x00d0, (OMAP34XX_MUX_MODE4) },
+ {"K8_GPMC_WAIT2", 0x00d0, (OMAP34XX_MUX_MODE0) },
+ {"G3_OMAP3430_GPIO_60", 0x00C6, (OMAP34XX_MUX_MODE4 |
+ OMAP3_INPUT_EN)},
+ {"G3_OMAP3430_n_b_e0_CLE", 0x00C6, (OMAP34XX_MUX_MODE0)},
+ {"C6_GPMC_WAIT3", 0x00d2, (OMAP34XX_MUX_MODE0)},
+ {"C6_OMAP3430_GPIO_65", 0x00d2, (OMAP34XX_MUX_MODE4 |
+ OMAP3_INPUT_EN)},
+ {"J1_OMAP3430_GPIO_61", 0x00C8, (OMAP34XX_MUX_MODE4 |
+ OMAP3_INPUT_EN | OMAP34XX_PIN_INPUT_PULLUP)},
+ /*
+ * don't remove, used for sanity check.
+ */
+ {"END_OF_TABLE"}
+};
+
+
+#endif /* _INCLUDED_CYASMEMMAP_H_ */
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h
new file mode 100644
index 000000000000..896e23281dba
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h
@@ -0,0 +1,72 @@
+/* Cypress Antioch OMAP KERNEL file (cyanomapdev_kernel.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor,
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef __CY_AS_OMAP_DEV_KERNEL_H__
+#define __CY_AS_OMAP_DEV_KERNEL_H__
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/completion.h>
+
+/* include does not seem to work
+ * moving for patch submission
+#include <mach/gpmc.h>
+*/
+#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
+
+/*
+ * Constants
+ */
+#define CY_AS_OMAP_KERNEL_HAL_SIG (0x1441)
+
+
+/*
+ * Data structures
+ */
+typedef struct cy_as_omap_dev_kernel {
+ /* This is the signature for this data structure */
+ unsigned int m_sig ;
+
+ /* Address base of Antioch Device */
+ void *m_addr_base;
+
+ /* This is a pointer to the next Antioch device in the system */
+ struct cy_as_omap_dev_kernel *m_next_p;
+
+ /* This is for thread sync */
+ struct completion thread_complete;
+
+ /* This is for thread to wait for interrupts */
+ cy_as_hal_sleep_channel thread_sc;
+
+ /* This is for thread to exit upon StopOmapKernel */
+ int thread_flag; /* set 1 to exit */
+
+ int dma_ch;
+
+ /* This is for dma sync */
+ struct completion dma_complete;
+} cy_as_omap_dev_kernel;
+
+#endif
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/block/Kconfig b/drivers/staging/westbridge/astoria/block/Kconfig
new file mode 100644
index 000000000000..851bf96a7b87
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/block/Kconfig
@@ -0,0 +1,9 @@
+#
+# West Bridge block driver configuration
+#
+
+config WESTBRIDGE_BLOCK_DRIVER
+ tristate "West Bridge Block Driver"
+ help
+ Include the West Bridge based block driver
+
diff --git a/drivers/staging/westbridge/astoria/block/Makefile b/drivers/staging/westbridge/astoria/block/Makefile
new file mode 100644
index 000000000000..4a45dd0861e7
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/block/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the kernel westbridge block driver
+#
+
+ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
+ EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE_BLOCK_DRIVER) += cyasblkdev.o
+cyasblkdev-y := cyasblkdev_block.o cyasblkdev_queue.o
+
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
new file mode 100644
index 000000000000..58b89b167870
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
@@ -0,0 +1,1628 @@
+/* cyanblkdev_block.c - West Bridge Linux Block Driver source file
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * Linux block driver implementation for Cypress West Bridge.
+ * Based on the mmc block driver implementation by Andrew Christian
+ * for the linux 2.6.26 kernel.
+ * mmc_block.c, 5/28/2002
+ */
+
+/*
+ * Block driver for media (i.e., flash cards)
+ *
+ * Copyright 2002 Hewlett-Packard Company
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * Many thanks to Alessandro Rubini and Jonathan Corbet!
+ *
+ * Author: Andrew Christian
+ * 28 May 2002
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/hdreg.h>
+#include <linux/kdev_t.h>
+#include <linux/blkdev.h>
+
+#include <asm/system.h>
+#include <linux/uaccess.h>
+
+#include <linux/scatterlist.h>
+#include <linux/time.h>
+#include <linux/signal.h>
+#include <linux/delay.h>
+
+#include "cyasblkdev_queue.h"
+
+#define CYASBLKDEV_SHIFT 0 /* Only a single partition. */
+#define CYASBLKDEV_MAX_REQ_LEN (256)
+#define CYASBLKDEV_NUM_MINORS (256 >> CYASBLKDEV_SHIFT)
+#define CY_AS_TEST_NUM_BLOCKS (64)
+#define CYASBLKDEV_MINOR_0 1
+#define CYASBLKDEV_MINOR_1 2
+#define CYASBLKDEV_MINOR_2 3
+
+static int major;
+module_param(major, int, 0444);
+MODULE_PARM_DESC(major,
+ "specify the major device number for cyasblkdev block driver");
+
+/* parameters passed from the user space */
+static int vfat_search;
+module_param(vfat_search, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(vfat_search,
+ "dynamically find the location of the first sector");
+
+static int private_partition_bus = -1;
+module_param(private_partition_bus, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(private_partition_bus,
+ "bus number for private partition");
+
+static int private_partition_size = -1;
+module_param(private_partition_size, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(private_partition_size,
+ "size of the private partition");
+
+/*
+ * There is one cyasblkdev_blk_data per slot.
+ */
+struct cyasblkdev_blk_data {
+ spinlock_t lock;
+ int media_count[2];
+ const struct block_device_operations *blkops;
+ unsigned int usage;
+ unsigned int suspended;
+
+ /* handle to the west bridge device this handle, typdefed as *void */
+ cy_as_device_handle dev_handle;
+
+ /* our custom structure, in addition to request queue,
+ * adds lock & semaphore items*/
+ struct cyasblkdev_queue queue;
+
+ /* 16 entries is enough given max request size
+ * 16 * 4K (64 K per request)*/
+ struct scatterlist sg[16];
+
+ /* non-zero enables printk of executed reqests */
+ unsigned int dbgprn_flags;
+
+ /*gen_disk for private, system disk */
+ struct gendisk *system_disk;
+ cy_as_media_type system_disk_type;
+ cy_bool system_disk_read_only;
+ cy_bool system_disk_bus_num;
+
+ /* sector size for the medium */
+ unsigned int system_disk_blk_size;
+ unsigned int system_disk_first_sector;
+ unsigned int system_disk_unit_no;
+
+ /*gen_disk for bus 0 */
+ struct gendisk *user_disk_0;
+ cy_as_media_type user_disk_0_type;
+ cy_bool user_disk_0_read_only;
+ cy_bool user_disk_0_bus_num;
+
+ /* sector size for the medium */
+ unsigned int user_disk_0_blk_size;
+ unsigned int user_disk_0_first_sector;
+ unsigned int user_disk_0_unit_no;
+
+ /*gen_disk for bus 1 */
+ struct gendisk *user_disk_1;
+ cy_as_media_type user_disk_1_type;
+ cy_bool user_disk_1_read_only;
+ cy_bool user_disk_1_bus_num;
+
+ /* sector size for the medium */
+ unsigned int user_disk_1_blk_size;
+ unsigned int user_disk_1_first_sector;
+ unsigned int user_disk_1_unit_no;
+};
+
+/* pointer to west bridge block data device superstructure */
+static struct cyasblkdev_blk_data *gl_bd ;
+
+static DECLARE_MUTEX(open_lock);
+
+/* local forwardd declarationss */
+static cy_as_device_handle *cyas_dev_handle;
+static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd);
+
+/*change debug print options */
+ #define DBGPRN_RD_RQ (1 < 0)
+ #define DBGPRN_WR_RQ (1 < 1)
+ #define DBGPRN_RQ_END (1 < 2)
+
+int blkdev_ctl_dbgprn(
+ int prn_flags
+ )
+{
+ int cur_options = gl_bd->dbgprn_flags;
+
+ DBGPRN_FUNC_NAME;
+
+ /* set new debug print options */
+ gl_bd->dbgprn_flags = prn_flags;
+
+ /* return previous */
+ return cur_options;
+}
+EXPORT_SYMBOL(blkdev_ctl_dbgprn);
+
+static struct cyasblkdev_blk_data *cyasblkdev_blk_get(
+ struct gendisk *disk
+ )
+{
+ struct cyasblkdev_blk_data *bd;
+
+ DBGPRN_FUNC_NAME;
+
+ down(&open_lock);
+
+ bd = disk->private_data;
+
+ if (bd && (bd->usage == 0))
+ bd = NULL;
+
+ if (bd) {
+ bd->usage++;
+ #ifndef NBDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev_blk_get: usage = %d\n", bd->usage) ;
+ #endif
+ }
+ up(&open_lock);
+
+ return bd;
+}
+
+static void cyasblkdev_blk_put(
+ struct cyasblkdev_blk_data *bd
+ )
+{
+ DBGPRN_FUNC_NAME;
+
+ down(&open_lock);
+
+ if (bd) {
+ bd->usage--;
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ " cyasblkdev_blk_put , bd->usage= %d\n", bd->usage);
+ #endif
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev: blk_put(bd) on bd = NULL!: usage = %d\n",
+ bd->usage);
+ #endif
+ up(&open_lock);
+ return ;
+ }
+
+ if (bd->usage == 0) {
+ put_disk(bd->user_disk_0);
+ put_disk(bd->user_disk_1);
+ put_disk(bd->system_disk);
+ cyasblkdev_cleanup_queue(&bd->queue);
+
+ if (CY_AS_ERROR_SUCCESS !=
+ cy_as_storage_release(bd->dev_handle, 0, 0, 0, 0)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev: cannot release bus 0\n") ;
+ #endif
+ }
+
+ if (CY_AS_ERROR_SUCCESS !=
+ cy_as_storage_release(bd->dev_handle, 1, 0, 0, 0)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev: cannot release bus 1\n") ;
+ #endif
+ }
+
+ if (CY_AS_ERROR_SUCCESS !=
+ cy_as_storage_stop(bd->dev_handle, 0, 0)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev: cannot stop storage stack\n") ;
+ #endif
+ }
+
+ #ifdef __CY_ASTORIA_SCM_KERNEL_HAL__
+ /* If the SCM Kernel HAL is being used, disable the use
+ * of scatter/gather lists at the end of block driver usage.
+ */
+ cy_as_hal_disable_scatter_list(cyasdevice_gethaltag()) ;
+ #endif
+
+ /*ptr to global struct cyasblkdev_blk_data */
+ gl_bd = NULL ;
+ kfree(bd);
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev (blk_put): usage = %d\n",
+ bd->usage) ;
+ #endif
+ up(&open_lock);
+}
+
+static int cyasblkdev_blk_open(
+ struct block_device *bdev,
+ fmode_t mode
+ )
+{
+ struct cyasblkdev_blk_data *bd = cyasblkdev_blk_get(bdev->bd_disk);
+ int ret = -ENXIO;
+
+ DBGPRN_FUNC_NAME;
+
+ if (bd) {
+ if (bd->usage == 2)
+ check_disk_change(bdev);
+
+ ret = 0;
+
+ if (bdev->bd_disk == bd->user_disk_0) {
+ if ((mode & FMODE_WRITE) && bd->user_disk_0_read_only) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "device marked as readonly "
+ "and write requested\n");
+ #endif
+
+ cyasblkdev_blk_put(bd);
+ ret = -EROFS;
+ }
+ } else if (bdev->bd_disk == bd->user_disk_1) {
+ if ((mode & FMODE_WRITE) && bd->user_disk_1_read_only) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "device marked as readonly "
+ "and write requested\n");
+ #endif
+
+ cyasblkdev_blk_put(bd);
+ ret = -EROFS;
+ }
+ } else if (bdev->bd_disk == bd->system_disk) {
+ if ((mode & FMODE_WRITE) && bd->system_disk_read_only) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "device marked as readonly "
+ "and write requested\n");
+ #endif
+
+ cyasblkdev_blk_put(bd);
+ ret = -EROFS;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int cyasblkdev_blk_release(
+ struct gendisk *disk,
+ fmode_t mode
+ )
+{
+ struct cyasblkdev_blk_data *bd = disk->private_data;
+
+ DBGPRN_FUNC_NAME;
+
+ cyasblkdev_blk_put(bd);
+ return 0;
+}
+
+static int cyasblkdev_blk_ioctl(
+ struct block_device *bdev,
+ fmode_t mode,
+ unsigned int cmd,
+ unsigned long arg
+ )
+{
+ DBGPRN_FUNC_NAME;
+
+ if (cmd == HDIO_GETGEO) {
+ /*for now we only process geometry IOCTL*/
+ struct hd_geometry geo;
+
+ memset(&geo, 0, sizeof(struct hd_geometry));
+
+ geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
+ geo.heads = 4;
+ geo.sectors = 16;
+ geo.start = get_start_sect(bdev);
+
+ /* copy to user space */
+ return copy_to_user((void __user *)arg, &geo, sizeof(geo))
+ ? -EFAULT : 0;
+ }
+
+ return -ENOTTY;
+}
+
+/* Media_changed block_device opp
+ * this one is called by kernel to confirm if the media really changed
+ * as we indicated by issuing check_disk_change() call */
+int cyasblkdev_media_changed(struct gendisk *gd)
+{
+ struct cyasblkdev_blk_data *bd;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("cyasblkdev_media_changed() is called\n");
+ #endif
+
+ if (gd)
+ bd = gd->private_data;
+ else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "cyasblkdev_media_changed() is called, "
+ "but gd is null\n");
+ #endif
+ }
+
+ /* return media change state "1" yes, 0 no */
+ return 1;
+}
+
+/* this one called by kernel to give us a chence
+ * to prep the new media before it starts to rescaning
+ * of the newlly inserted SD media */
+int cyasblkdev_revalidate_disk(struct gendisk *gd)
+{
+ /*int (*revalidate_disk) (struct gendisk *); */
+
+ #ifndef WESTBRIDGE_NDEBUG
+ if (gd)
+ cy_as_hal_print_message(
+ "cyasblkdev_revalidate_disk() is called, "
+ "(gl_bd->usage:%d)\n", gl_bd->usage);
+ #endif
+
+ /* 0 means ok, kern can go ahead with partition rescan */
+ return 0;
+}
+
+
+/*standard block device driver interface */
+static struct block_device_operations cyasblkdev_bdops = {
+ .open = cyasblkdev_blk_open,
+ .release = cyasblkdev_blk_release,
+ .ioctl = cyasblkdev_blk_ioctl,
+ /* .getgeo = cyasblkdev_blk_getgeo, */
+ /* added to support media removal( real and simulated) media */
+ .media_changed = cyasblkdev_media_changed,
+ /* added to support media removal( real and simulated) media */
+ .revalidate_disk = cyasblkdev_revalidate_disk,
+ .owner = THIS_MODULE,
+};
+
+/* west bridge block device prep request function */
+static int cyasblkdev_blk_prep_rq(
+ struct cyasblkdev_queue *bq,
+ struct request *req
+ )
+{
+ struct cyasblkdev_blk_data *bd = bq->data;
+ int stat = BLKPREP_OK;
+
+ DBGPRN_FUNC_NAME;
+
+ /* If we have no device, we haven't finished initialising. */
+ if (!bd || !bd->dev_handle) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(KERN_ERR
+ "cyasblkdev %s: killing request - no device/host\n",
+ req->rq_disk->disk_name);
+ #endif
+ stat = BLKPREP_KILL;
+ }
+
+ if (bd->suspended) {
+ blk_plug_device(bd->queue.queue);
+ stat = BLKPREP_DEFER;
+ }
+
+ /* Check for excessive requests.*/
+ if (blk_rq_pos(req) + blk_rq_sectors(req) > get_capacity(req->rq_disk)) {
+ cy_as_hal_print_message("cyasblkdev: bad request address\n");
+ stat = BLKPREP_KILL;
+ }
+
+ return stat;
+}
+
+/*west bridge storage async api on_completed callback */
+static void cyasblkdev_issuecallback(
+ /* Handle to the device completing the storage operation */
+ cy_as_device_handle handle,
+ /* The media type completing the operation */
+ cy_as_media_type type,
+ /* The device completing the operation */
+ uint32_t device,
+ /* The unit completing the operation */
+ uint32_t unit,
+ /* The block number of the completed operation */
+ uint32_t block_number,
+ /* The type of operation */
+ cy_as_oper_type op,
+ /* The error status */
+ cy_as_return_status_t status
+ )
+{
+ int retry_cnt = 0;
+ DBGPRN_FUNC_NAME;
+
+ if (status != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: async r/w: op:%d failed with error %d at address %d\n",
+ __func__, op, status, block_number) ;
+ #endif
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s calling blk_end_request from issue_callback "
+ "req=0x%x, status=0x%x, nr_sectors=0x%x\n",
+ __func__, (unsigned int) gl_bd->queue.req, status,
+ (unsigned int) blk_rq_sectors(gl_bd->queue.req)) ;
+ #endif
+
+ /* note: blk_end_request w/o __ prefix should
+ * not require spinlocks on the queue*/
+ while (blk_end_request(gl_bd->queue.req,
+ status, blk_rq_sectors(gl_bd->queue.req)*512)) {
+ retry_cnt++;
+ };
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s blkdev_callback: ended rq on %d sectors, "
+ "with err:%d, n:%d times\n", __func__,
+ (int)blk_rq_sectors(gl_bd->queue.req), status,
+ retry_cnt
+ );
+ #endif
+
+ spin_lock_irq(&gl_bd->lock);
+
+ /*elevate next request, if there is one*/
+ if (!blk_queue_plugged(gl_bd->queue.queue)) {
+ /* queue is not plugged */
+ gl_bd->queue.req = blk_fetch_request(gl_bd->queue.queue);
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s blkdev_callback: "
+ "blk_fetch_request():%p\n",
+ __func__, gl_bd->queue.req);
+ #endif
+ }
+
+ if (gl_bd->queue.req) {
+ spin_unlock_irq(&gl_bd->lock);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s blkdev_callback: about to "
+ "call issue_fn:%p\n", __func__, gl_bd->queue.req);
+ #endif
+
+ gl_bd->queue.issue_fn(&gl_bd->queue, gl_bd->queue.req);
+ } else {
+ spin_unlock_irq(&gl_bd->lock);
+ }
+}
+
+/* issue astoria blkdev request (issue_fn) */
+static int cyasblkdev_blk_issue_rq(
+ struct cyasblkdev_queue *bq,
+ struct request *req
+ )
+{
+ struct cyasblkdev_blk_data *bd = bq->data;
+ int index = 0 ;
+ int ret = CY_AS_ERROR_SUCCESS;
+ uint32_t req_sector = 0;
+ uint32_t req_nr_sectors = 0;
+ int bus_num = 0;
+ int lcl_unit_no = 0;
+
+ DBGPRN_FUNC_NAME;
+
+ /*
+ * will construct a scatterlist for the given request;
+ * the return value is the number of actually used
+ * entries in the resulting list. Then, this scatterlist
+ * can be used for the actual DMA prep operation.
+ */
+ spin_lock_irq(&bd->lock);
+ index = blk_rq_map_sg(bq->queue, req, bd->sg);
+
+ if (req->rq_disk == bd->user_disk_0) {
+ bus_num = bd->user_disk_0_bus_num;
+ req_sector = blk_rq_pos(req) + gl_bd->user_disk_0_first_sector;
+ req_nr_sectors = blk_rq_sectors(req);
+ lcl_unit_no = gl_bd->user_disk_0_unit_no;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: request made to disk 0 "
+ "for sector=%d, num_sectors=%d, unit_no=%d\n",
+ __func__, req_sector, (int) blk_rq_sectors(req),
+ lcl_unit_no);
+ #endif
+ } else if (req->rq_disk == bd->user_disk_1) {
+ bus_num = bd->user_disk_1_bus_num;
+ req_sector = blk_rq_pos(req) + gl_bd->user_disk_1_first_sector;
+ /*SECT_NUM_TRANSLATE(blk_rq_sectors(req));*/
+ req_nr_sectors = blk_rq_sectors(req);
+ lcl_unit_no = gl_bd->user_disk_1_unit_no;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: request made to disk 1 for "
+ "sector=%d, num_sectors=%d, unit_no=%d\n", __func__,
+ req_sector, (int) blk_rq_sectors(req), lcl_unit_no);
+ #endif
+ } else if (req->rq_disk == bd->system_disk) {
+ bus_num = bd->system_disk_bus_num;
+ req_sector = blk_rq_pos(req) + gl_bd->system_disk_first_sector;
+ req_nr_sectors = blk_rq_sectors(req);
+ lcl_unit_no = gl_bd->system_disk_unit_no;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: request made to system disk "
+ "for sector=%d, num_sectors=%d, unit_no=%d\n", __func__,
+ req_sector, (int) blk_rq_sectors(req), lcl_unit_no);
+ #endif
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message(
+ "%s: invalid disk used for request\n", __func__);
+ }
+ #endif
+
+ spin_unlock_irq(&bd->lock);
+
+ if (rq_data_dir(req) == READ) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: calling readasync() "
+ "req_sector=0x%x, req_nr_sectors=0x%x, bd->sg:%x\n\n",
+ __func__, req_sector, req_nr_sectors, (uint32_t)bd->sg);
+ #endif
+
+ ret = cy_as_storage_read_async(bd->dev_handle, bus_num, 0,
+ lcl_unit_no, req_sector, bd->sg, req_nr_sectors,
+ (cy_as_storage_callback)cyasblkdev_issuecallback);
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s:readasync() error %d at "
+ "address %ld, unit no %d\n", __func__, ret,
+ blk_rq_pos(req), lcl_unit_no);
+ cy_as_hal_print_message("%s:ending i/o request "
+ "on reg:%x\n", __func__, (uint32_t)req);
+ #endif
+
+ while (blk_end_request(req,
+ (ret == CY_AS_ERROR_SUCCESS),
+ req_nr_sectors*512))
+ ;
+
+ bq->req = NULL ;
+ }
+ } else {
+ ret = cy_as_storage_write_async(bd->dev_handle, bus_num, 0,
+ lcl_unit_no, req_sector, bd->sg, req_nr_sectors,
+ (cy_as_storage_callback)cyasblkdev_issuecallback);
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: write failed with "
+ "error %d at address %ld, unit no %d\n",
+ __func__, ret, blk_rq_pos(req), lcl_unit_no);
+ #endif
+
+ /*end IO op on this request(does both
+ * end_that_request_... _first & _last) */
+ while (blk_end_request(req,
+ (ret == CY_AS_ERROR_SUCCESS),
+ req_nr_sectors*512))
+ ;
+
+ bq->req = NULL ;
+ }
+ }
+
+ return ret;
+}
+
+static unsigned long
+dev_use[CYASBLKDEV_NUM_MINORS / (8 * sizeof(unsigned long))];
+
+
+/* storage event callback (note: called in astoria isr context) */
+static void cyasblkdev_storage_callback(
+ cy_as_device_handle dev_h,
+ cy_as_bus_number_t bus,
+ uint32_t device,
+ cy_as_storage_event evtype,
+ void *evdata
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: bus:%d, device:%d, evtype:%d, "
+ "evdata:%p\n ", __func__, bus, device, evtype, evdata);
+ #endif
+
+ switch (evtype) {
+ case cy_as_storage_processor:
+ break;
+
+ case cy_as_storage_removed:
+ break;
+
+ case cy_as_storage_inserted:
+ break;
+
+ default:
+ break;
+ }
+}
+
+#define SECTORS_TO_SCAN 4096
+
+uint32_t cyasblkdev_get_vfat_offset(int bus_num, int unit_no)
+{
+ /*
+ * for sd media, vfat partition boot record is not always
+ * located at sector it greatly depends on the system and
+ * software that was used to format the sd however, linux
+ * fs layer always expects it at sector 0, this function
+ * finds the offset and then uses it in all media r/w
+ * operations
+ */
+ int sect_no, stat;
+ uint8_t *sect_buf;
+ bool br_found = false;
+
+ DBGPRN_FUNC_NAME;
+
+ sect_buf = kmalloc(1024, GFP_KERNEL);
+
+ /* since HAL layer always uses sg lists instead of the
+ * buffer (for hw dmas) we need to initialize the sg list
+ * for local buffer*/
+ sg_init_one(gl_bd->sg, sect_buf, 512);
+
+ /*
+ * Check MPR partition table 1st, then try to scan through
+ * 1st 384 sectors until BR signature(intel JMP istruction
+ * code and ,0x55AA) is found
+ */
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s scanning media for vfat partition...\n", __func__) ;
+ #endif
+
+ for (sect_no = 0; sect_no < SECTORS_TO_SCAN; sect_no++) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s before cyasstorageread "
+ "gl_bd->sg addr=0x%x\n", __func__,
+ (unsigned int) gl_bd->sg);
+ #endif
+
+ stat = cy_as_storage_read(
+ /* Handle to the device of interest */
+ gl_bd->dev_handle,
+ /* The bus to access */
+ bus_num,
+ /* The device to access */
+ 0,
+ /* The unit to access */
+ unit_no,
+ /* absolute sector number */
+ sect_no,
+ /* sg structure */
+ gl_bd->sg,
+ /* The number of blocks to be read */
+ 1
+ );
+
+ /* try only sectors with boot signature */
+ if ((sect_buf[510] == 0x55) && (sect_buf[511] == 0xaa)) {
+ /* vfat boot record may also be located at
+ * sector 0, check it first */
+ if (sect_buf[0] == 0xEB) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s vfat partition found "
+ "at sector:%d\n",
+ __func__, sect_no);
+ #endif
+
+ br_found = true;
+ break;
+ }
+ }
+
+ if (stat != 0) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s sector scan error\n",
+ __func__);
+ #endif
+ break;
+ }
+ }
+
+ kfree(sect_buf);
+
+ if (br_found) {
+ return sect_no;
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s vfat partition is not found, using 0 offset\n",
+ __func__);
+ #endif
+ return 0;
+ }
+}
+
+cy_as_storage_query_device_data dev_data = {0} ;
+
+static int cyasblkdev_add_disks(int bus_num,
+ struct cyasblkdev_blk_data *bd,
+ int total_media_count,
+ int devidx)
+{
+ int ret = 0;
+ uint64_t disk_cap;
+ int lcl_unit_no;
+ cy_as_storage_query_unit_data unit_data = {0} ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s:query device: "
+ "type:%d, removable:%d, writable:%d, "
+ "blksize %d, units:%d, locked:%d, "
+ "erase_sz:%d\n",
+ __func__,
+ dev_data.desc_p.type,
+ dev_data.desc_p.removable,
+ dev_data.desc_p.writeable,
+ dev_data.desc_p.block_size,
+ dev_data.desc_p.number_units,
+ dev_data.desc_p.locked,
+ dev_data.desc_p.erase_unit_size
+ );
+ #endif
+
+ /* make sure that device is not locked */
+ if (dev_data.desc_p.locked) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: device is locked\n", __func__);
+ #endif
+ ret = cy_as_storage_release(
+ bd->dev_handle, bus_num, 0, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s cannot release"
+ " storage\n", __func__) ;
+ #endif
+ goto out;
+ }
+ goto out;
+ }
+
+ unit_data.device = 0 ;
+ unit_data.unit = 0 ;
+ unit_data.bus = bus_num;
+ ret = cy_as_storage_query_unit(bd->dev_handle,
+ &unit_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot query "
+ "%d device unit - reason code %d\n",
+ __func__, bus_num, ret) ;
+ #endif
+ goto out ;
+ }
+
+ if (private_partition_bus == bus_num) {
+ if (private_partition_size > 0) {
+ ret = cy_as_storage_create_p_partition(
+ bd->dev_handle, bus_num, 0,
+ private_partition_size, 0, 0);
+ if ((ret != CY_AS_ERROR_SUCCESS) &&
+ (ret != CY_AS_ERROR_ALREADY_PARTITIONED)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_storage_"
+ "create_p_partition after size > 0 check "
+ "failed with error code %d\n",
+ __func__, ret);
+ #endif
+
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no = 0;
+
+ } else if (ret == CY_AS_ERROR_ALREADY_PARTITIONED) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cy_as_storage_create_p_partition "
+ "indicates memory already partitioned\n",
+ __func__);
+ #endif
+
+ /*check to see that partition
+ * matches size */
+ if (unit_data.desc_p.unit_size !=
+ private_partition_size) {
+ ret = cy_as_storage_remove_p_partition(
+ bd->dev_handle,
+ bus_num, 0, 0, 0);
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ ret = cy_as_storage_create_p_partition(
+ bd->dev_handle, bus_num, 0,
+ private_partition_size, 0, 0);
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ unit_data.bus = bus_num ;
+ unit_data.device = 0 ;
+ unit_data.unit = 1 ;
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cy_as_storage_create_p_partition "
+ "after removal unexpectedly failed "
+ "with error %d\n", __func__, ret) ;
+ #endif
+
+ /* need to requery bus
+ * seeing as delete
+ * successful and create
+ * failed we have changed
+ * the disk properties */
+ unit_data.bus = bus_num ;
+ unit_data.device = 0 ;
+ unit_data.unit = 0 ;
+ }
+
+ ret = cy_as_storage_query_unit(
+ bd->dev_handle,
+ &unit_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cannot query %d "
+ "device unit - reason code %d\n",
+ __func__, bus_num, ret) ;
+ #endif
+ goto out ;
+ } else {
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no =
+ unit_data.unit;
+ }
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cy_as_storage_remove_p_partition "
+ "failed with error %d\n",
+ __func__, ret);
+ #endif
+
+ unit_data.bus = bus_num ;
+ unit_data.device = 0 ;
+ unit_data.unit = 1 ;
+
+ ret = cy_as_storage_query_unit(
+ bd->dev_handle, &unit_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cannot query %d "
+ "device unit - reason "
+ "code %d\n", __func__,
+ bus_num, ret) ;
+ #endif
+ goto out ;
+ }
+
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no =
+ unit_data.unit ;
+ }
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: partition "
+ "exists and sizes equal\n",
+ __func__);
+ #endif
+
+ /*partition already existed,
+ * need to query second unit*/
+ unit_data.bus = bus_num ;
+ unit_data.device = 0 ;
+ unit_data.unit = 1 ;
+
+ ret = cy_as_storage_query_unit(
+ bd->dev_handle, &unit_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cannot query %d "
+ "device unit "
+ "- reason code %d\n",
+ __func__, bus_num, ret) ;
+ #endif
+ goto out ;
+ } else {
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no = unit_data.unit ;
+ }
+ }
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cy_as_storage_create_p_partition "
+ "created successfully\n", __func__);
+ #endif
+
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size -
+ private_partition_size);
+
+ lcl_unit_no = 1;
+ }
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message(
+ "%s: invalid partition_size%d\n", __func__,
+ private_partition_size);
+
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no = 0;
+ }
+ #endif
+ } else {
+ disk_cap = (uint64_t)
+ (unit_data.desc_p.unit_size);
+ lcl_unit_no = 0;
+ }
+
+ if ((bus_num == 0) ||
+ (total_media_count == 1)) {
+ sprintf(bd->user_disk_0->disk_name,
+ "cyasblkdevblk%d", devidx);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: disk unit_sz:%lu blk_sz:%d, "
+ "start_blk:%lu, capacity:%llu\n",
+ __func__, (unsigned long)
+ unit_data.desc_p.unit_size,
+ unit_data.desc_p.block_size,
+ (unsigned long)
+ unit_data.desc_p.start_block,
+ (uint64_t)disk_cap
+ );
+ #endif
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: setting gendisk disk "
+ "capacity to %d\n", __func__, (int) disk_cap);
+ #endif
+
+ /* initializing bd->queue */
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: init bd->queue\n",
+ __func__);
+ #endif
+
+ /* this will create a
+ * queue kernel thread */
+ cyasblkdev_init_queue(
+ &bd->queue, &bd->lock) ;
+
+ bd->queue.prep_fn = cyasblkdev_blk_prep_rq;
+ bd->queue.issue_fn = cyasblkdev_blk_issue_rq;
+ bd->queue.data = bd;
+
+ /*blk_size should always
+ * be a multiple of 512,
+ * set to the max to ensure
+ * that all accesses aligned
+ * to the greatest multiple,
+ * can adjust request to
+ * smaller block sizes
+ * dynamically*/
+
+ bd->user_disk_0_read_only = !dev_data.desc_p.writeable;
+ bd->user_disk_0_blk_size = dev_data.desc_p.block_size;
+ bd->user_disk_0_type = dev_data.desc_p.type;
+ bd->user_disk_0_bus_num = bus_num;
+ bd->user_disk_0->major = major;
+ bd->user_disk_0->first_minor = devidx << CYASBLKDEV_SHIFT;
+ bd->user_disk_0->minors = 8;
+ bd->user_disk_0->fops = &cyasblkdev_bdops;
+ bd->user_disk_0->private_data = bd;
+ bd->user_disk_0->queue = bd->queue.queue;
+ bd->dbgprn_flags = DBGPRN_RD_RQ;
+ bd->user_disk_0_unit_no = lcl_unit_no;
+
+ blk_queue_logical_block_size(bd->queue.queue,
+ bd->user_disk_0_blk_size);
+
+ set_capacity(bd->user_disk_0,
+ disk_cap);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: returned from set_capacity %d\n",
+ __func__, (int) disk_cap);
+ #endif
+
+ /* need to start search from
+ * public partition beginning */
+ if (vfat_search) {
+ bd->user_disk_0_first_sector =
+ cyasblkdev_get_vfat_offset(0,
+ bd->user_disk_0_unit_no);
+ } else {
+ bd->user_disk_0_first_sector = 0;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: set user_disk_0_first "
+ "sector to %d\n", __func__,
+ bd->user_disk_0_first_sector);
+ cy_as_hal_print_message(
+ "%s: add_disk: disk->major=0x%x\n",
+ __func__,
+ bd->user_disk_0->major);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->first_minor=0x%x\n", __func__,
+ bd->user_disk_0->first_minor);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->minors=0x%x\n", __func__,
+ bd->user_disk_0->minors);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->disk_name=%s\n",
+ __func__,
+ bd->user_disk_0->disk_name);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->part_tbl=0x%x\n", __func__,
+ (unsigned int)
+ bd->user_disk_0->part_tbl);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->queue=0x%x\n", __func__,
+ (unsigned int)
+ bd->user_disk_0->queue);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->flags=0x%x\n",
+ __func__, (unsigned int)
+ bd->user_disk_0->flags);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->driverfs_dev=0x%x\n",
+ __func__, (unsigned int)
+ bd->user_disk_0->driverfs_dev);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->slave_dir=0x%x\n",
+ __func__, (unsigned int)
+ bd->user_disk_0->slave_dir);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->random=0x%x\n",
+ __func__, (unsigned int)
+ bd->user_disk_0->random);
+ cy_as_hal_print_message(
+ "%s: add_disk: "
+ "disk->node_id=0x%x\n",
+ __func__, (unsigned int)
+ bd->user_disk_0->node_id);
+
+ #endif
+
+ add_disk(bd->user_disk_0);
+
+ } else if ((bus_num == 1) &&
+ (total_media_count == 2)) {
+ bd->user_disk_1_read_only = !dev_data.desc_p.writeable;
+ bd->user_disk_1_blk_size = dev_data.desc_p.block_size;
+ bd->user_disk_1_type = dev_data.desc_p.type;
+ bd->user_disk_1_bus_num = bus_num;
+ bd->user_disk_1->major = major;
+ bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT;
+ bd->user_disk_1->minors = 8;
+ bd->user_disk_1->fops = &cyasblkdev_bdops;
+ bd->user_disk_1->private_data = bd;
+ bd->user_disk_1->queue = bd->queue.queue;
+ bd->dbgprn_flags = DBGPRN_RD_RQ;
+ bd->user_disk_1_unit_no = lcl_unit_no;
+
+ sprintf(bd->user_disk_1->disk_name,
+ "cyasblkdevblk%d", (devidx + 1));
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: disk unit_sz:%lu "
+ "blk_sz:%d, "
+ "start_blk:%lu, "
+ "capacity:%llu\n",
+ __func__,
+ (unsigned long)
+ unit_data.desc_p.unit_size,
+ unit_data.desc_p.block_size,
+ (unsigned long)
+ unit_data.desc_p.start_block,
+ (uint64_t)disk_cap
+ );
+ #endif
+
+ /*blk_size should always be a
+ * multiple of 512, set to the max
+ * to ensure that all accesses
+ * aligned to the greatest multiple,
+ * can adjust request to smaller
+ * block sizes dynamically*/
+ if (bd->user_disk_0_blk_size >
+ bd->user_disk_1_blk_size) {
+ blk_queue_logical_block_size(bd->queue.queue,
+ bd->user_disk_0_blk_size);
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: set hard sect_sz:%d\n",
+ __func__,
+ bd->user_disk_0_blk_size);
+ #endif
+ } else {
+ blk_queue_logical_block_size(bd->queue.queue,
+ bd->user_disk_1_blk_size);
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: set hard sect_sz:%d\n",
+ __func__,
+ bd->user_disk_1_blk_size);
+ #endif
+ }
+
+ set_capacity(bd->user_disk_1, disk_cap);
+ if (vfat_search) {
+ bd->user_disk_1_first_sector =
+ cyasblkdev_get_vfat_offset(
+ 1, bd->user_disk_1_unit_no);
+ } else {
+ bd->user_disk_1_first_sector
+ = 0;
+ }
+
+ add_disk(bd->user_disk_1);
+ }
+
+ if (lcl_unit_no > 0) {
+ if (bd->system_disk == NULL) {
+ bd->system_disk =
+ alloc_disk(CYASBLKDEV_MINOR_2
+ << CYASBLKDEV_SHIFT);
+ if (bd->system_disk == NULL) {
+ kfree(bd);
+ bd = ERR_PTR(-ENOMEM);
+ return bd ;
+ }
+ disk_cap = (uint64_t)
+ (private_partition_size);
+
+ /* set properties of
+ * system disk */
+ bd->system_disk_read_only = !dev_data.desc_p.writeable;
+ bd->system_disk_blk_size = dev_data.desc_p.block_size;
+ bd->system_disk_bus_num = bus_num;
+ bd->system_disk->major = major;
+ bd->system_disk->first_minor =
+ (devidx + 2) << CYASBLKDEV_SHIFT;
+ bd->system_disk->minors = 8;
+ bd->system_disk->fops = &cyasblkdev_bdops;
+ bd->system_disk->private_data = bd;
+ bd->system_disk->queue = bd->queue.queue;
+ /* don't search for vfat
+ * with system disk */
+ bd->system_disk_first_sector = 0;
+ sprintf(
+ bd->system_disk->disk_name,
+ "cyasblkdevblk%d", (devidx + 2));
+
+ set_capacity(bd->system_disk,
+ disk_cap);
+
+ add_disk(bd->system_disk);
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message(
+ "%s: system disk already allocated %d\n",
+ __func__, bus_num) ;
+ }
+ #endif
+ }
+out:
+ return ret;
+}
+
+static struct cyasblkdev_blk_data *cyasblkdev_blk_alloc(void)
+{
+ struct cyasblkdev_blk_data *bd;
+ int ret = 0 ;
+ cy_as_return_status_t stat = -1 ;
+ int bus_num = 0;
+ int total_media_count = 0;
+ int devidx = 0;
+ DBGPRN_FUNC_NAME;
+
+ total_media_count = 0;
+ devidx = find_first_zero_bit(dev_use, CYASBLKDEV_NUM_MINORS);
+ if (devidx >= CYASBLKDEV_NUM_MINORS)
+ return ERR_PTR(-ENOSPC);
+
+ __set_bit(devidx, dev_use);
+ __set_bit(devidx + 1, dev_use);
+
+ bd = kzalloc(sizeof(struct cyasblkdev_blk_data), GFP_KERNEL);
+ if (bd) {
+ gl_bd = bd ;
+
+ spin_lock_init(&bd->lock);
+ bd->usage = 1;
+
+ /* setup the block_dev_ops pointer*/
+ bd->blkops = &cyasblkdev_bdops;
+
+ /* Get the device handle */
+ bd->dev_handle = cyasdevice_getdevhandle() ;
+ if (0 == bd->dev_handle) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: get device failed\n", __func__) ;
+ #endif
+ ret = ENODEV ;
+ goto out ;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s west bridge device handle:%x\n",
+ __func__, (uint32_t)bd->dev_handle);
+ #endif
+
+ /* start the storage api and get a handle to the
+ * device we are interested in. */
+
+ /* Error code to use if the conditions are not satisfied. */
+ ret = ENOMEDIUM ;
+
+ stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_0);
+ if ((stat != CY_AS_ERROR_SUCCESS) &&
+ (stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot release "
+ "resource bus 0 - reason code %d\n",
+ __func__, stat) ;
+ #endif
+ }
+
+ stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_1);
+ if ((stat != CY_AS_ERROR_SUCCESS) &&
+ (stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot release "
+ "resource bus 0 - reason code %d\n",
+ __func__, stat) ;
+ #endif
+ }
+
+ /* start storage stack*/
+ stat = cy_as_storage_start(bd->dev_handle, 0, 0x101) ;
+ if (stat != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot start storage "
+ "stack - reason code %d\n", __func__, stat) ;
+ #endif
+ goto out;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: storage started:%d ok\n",
+ __func__, stat);
+ #endif
+
+ stat = cy_as_storage_register_callback(bd->dev_handle,
+ cyasblkdev_storage_callback);
+ if (stat != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot register callback "
+ "- reason code %d\n", __func__, stat) ;
+ #endif
+ goto out;
+ }
+
+ for (bus_num = 0; bus_num < 2; bus_num++) {
+ stat = cy_as_storage_query_bus(bd->dev_handle,
+ bus_num, &bd->media_count[bus_num], 0, 0) ;
+ if (stat == CY_AS_ERROR_SUCCESS) {
+ total_media_count = total_media_count +
+ bd->media_count[bus_num];
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cannot query %d, "
+ "reason code: %d\n",
+ __func__, bus_num, stat) ;
+ #endif
+ goto out;
+ }
+ }
+
+ if (total_media_count == 0) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: no storage media was found\n", __func__) ;
+ #endif
+ goto out ;
+ } else if (total_media_count >= 1) {
+ if (bd->user_disk_0 == NULL) {
+
+ bd->user_disk_0 =
+ alloc_disk(CYASBLKDEV_MINOR_0
+ << CYASBLKDEV_SHIFT);
+ if (bd->user_disk_0 == NULL) {
+ kfree(bd);
+ bd = ERR_PTR(-ENOMEM);
+ return bd ;
+ }
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message("%s: no available "
+ "gen_disk for disk 0, "
+ "physically inconsistent\n", __func__);
+ }
+ #endif
+ }
+
+ if (total_media_count == 2) {
+ if (bd->user_disk_1 == NULL) {
+ bd->user_disk_1 =
+ alloc_disk(CYASBLKDEV_MINOR_1
+ << CYASBLKDEV_SHIFT);
+ if (bd->user_disk_1 == NULL) {
+ kfree(bd);
+ bd = ERR_PTR(-ENOMEM);
+ return bd ;
+ }
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message("%s: no available "
+ "gen_disk for media, "
+ "physically inconsistent\n", __func__);
+ }
+ #endif
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else if (total_media_count > 2) {
+ cy_as_hal_print_message("%s: count corrupted = 0x%d\n",
+ __func__, total_media_count);
+ }
+ #endif
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: %d device(s) found\n",
+ __func__, total_media_count) ;
+ #endif
+
+ for (bus_num = 0; bus_num <= 1; bus_num++) {
+ /*claim storage for cpu */
+ stat = cy_as_storage_claim(bd->dev_handle,
+ bus_num, 0, 0, 0) ;
+ if (stat != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("%s: cannot claim "
+ "%d bus - reason code %d\n",
+ __func__, bus_num, stat) ;
+ goto out;
+ }
+
+ dev_data.bus = bus_num ;
+ dev_data.device = 0 ;
+
+ stat = cy_as_storage_query_device(bd->dev_handle,
+ &dev_data, 0, 0) ;
+ if (stat == CY_AS_ERROR_SUCCESS) {
+ cyasblkdev_add_disks(bus_num, bd,
+ total_media_count, devidx);
+ } else if (stat == CY_AS_ERROR_NO_SUCH_DEVICE) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: no device on bus %d\n",
+ __func__, bus_num) ;
+ #endif
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cannot query %d device "
+ "- reason code %d\n",
+ __func__, bus_num, stat) ;
+ #endif
+ goto out ;
+ }
+ } /* end for (bus_num = 0; bus_num <= 1; bus_num++)*/
+
+ return bd ;
+ }
+out:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: bd failed to initialize\n", __func__);
+ #endif
+
+ kfree(bd);
+ bd = ERR_PTR(-ret);
+ return bd;
+}
+
+
+/*init west bridge block device */
+static int cyasblkdev_blk_initialize(void)
+{
+ struct cyasblkdev_blk_data *bd;
+ int res;
+
+ DBGPRN_FUNC_NAME;
+
+ res = register_blkdev(major, "cyasblkdev");
+
+ if (res < 0) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(KERN_WARNING
+ "%s unable to get major %d for cyasblkdev media: %d\n",
+ __func__, major, res);
+ #endif
+ return res;
+ }
+
+ if (major == 0)
+ major = res;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s cyasblkdev registered with major number: %d\n",
+ __func__, major) ;
+ #endif
+
+ bd = cyasblkdev_blk_alloc();
+ if (IS_ERR(bd))
+ return PTR_ERR(bd);
+
+ return 0;
+}
+
+/* start block device */
+static int __init cyasblkdev_blk_init(void)
+{
+ int res = -ENOMEM;
+
+ DBGPRN_FUNC_NAME;
+
+ /* get the cyasdev handle for future use*/
+ cyas_dev_handle = cyasdevice_getdevhandle();
+
+ if (cyasblkdev_blk_initialize() == 0)
+ return 0;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("cyasblkdev init error:%d\n", res);
+ #endif
+ return res;
+}
+
+
+static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd)
+{
+ DBGPRN_FUNC_NAME;
+
+ if (bd) {
+ int devidx;
+
+ if (bd->user_disk_0 != NULL) {
+ del_gendisk(bd->user_disk_0);
+ devidx = bd->user_disk_0->first_minor
+ >> CYASBLKDEV_SHIFT;
+ __clear_bit(devidx, dev_use);
+ }
+
+ if (bd->user_disk_1 != NULL) {
+ del_gendisk(bd->user_disk_1);
+ devidx = bd->user_disk_1->first_minor
+ >> CYASBLKDEV_SHIFT;
+ __clear_bit(devidx, dev_use);
+ }
+
+ if (bd->system_disk != NULL) {
+ del_gendisk(bd->system_disk);
+ devidx = bd->system_disk->first_minor
+ >> CYASBLKDEV_SHIFT;
+ __clear_bit(devidx, dev_use);
+ }
+
+ cyasblkdev_blk_put(bd);
+ }
+}
+
+/* block device exit */
+static void __exit cyasblkdev_blk_exit(void)
+{
+ DBGPRN_FUNC_NAME;
+
+ cyasblkdev_blk_deinit(gl_bd);
+ unregister_blkdev(major, "cyasblkdev");
+
+}
+
+module_init(cyasblkdev_blk_init);
+module_exit(cyasblkdev_blk_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("antioch (cyasblkdev) block device driver");
+MODULE_AUTHOR("cypress semiconductor");
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
new file mode 100644
index 000000000000..5cc469ab89fe
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
@@ -0,0 +1,417 @@
+/* cyanblkdev_queue.h - Antioch Linux Block Driver queue source file
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor,
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * Request queue handling for Antioch block device driver.
+ * Based on the mmc queue handling code by Russell King in the
+ * linux 2.6.10 kernel.
+ */
+
+/*
+ * linux/drivers/mmc/mmc_queue.c
+ *
+ * Copyright (C) 2003 Russell King, 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/blkdev.h>
+
+#include "cyasblkdev_queue.h"
+
+#define CYASBLKDEV_QUEUE_EXIT (1 << 0)
+#define CYASBLKDEV_QUEUE_SUSPENDED (1 << 1)
+#define CY_AS_USE_ASYNC_API
+
+
+
+/* print flags by name */
+const char *rq_flag_bit_names[] = {
+ "REQ_RW", /* not set, read. set, write */
+ "REQ_FAILFAST", /* no low level driver retries */
+ "REQ_SORTED", /* elevator knows about this request */
+ "REQ_SOFTBARRIER", /* may not be passed by ioscheduler */
+ "REQ_HARDBARRIER", /* may not be passed by drive either */
+ "REQ_FUA", /* forced unit access */
+ "REQ_NOMERGE", /* don't touch this for merging */
+ "REQ_STARTED", /* drive already may have started this one */
+ "REQ_DONTPREP", /* don't call prep for this one */
+ "REQ_QUEUED", /* uses queueing */
+ "REQ_ELVPRIV", /* elevator private data attached */
+ "REQ_FAILED", /* set if the request failed */
+ "REQ_QUIET", /* don't worry about errors */
+ "REQ_PREEMPT", /* set for "ide_preempt" requests */
+ "REQ_ORDERED_COLOR",/* is before or after barrier */
+ "REQ_RW_SYNC", /* request is sync (O_DIRECT) */
+ "REQ_ALLOCED", /* request came from our alloc pool */
+ "REQ_RW_META", /* metadata io request */
+ "REQ_COPY_USER", /* contains copies of user pages */
+ "REQ_NR_BITS", /* stops here */
+};
+
+void verbose_rq_flags(int flags)
+{
+ int i;
+ uint32_t j;
+ j = 1;
+ for (i = 0; i < 32; i++) {
+ if (flags & j)
+ DBGPRN("<1>%s", rq_flag_bit_names[i]);
+ j = j << 1;
+ }
+}
+
+
+/*
+ * Prepare a -BLK_DEV request. Essentially, this means passing the
+ * preparation off to the media driver. The media driver will
+ * create request to CyAsDev.
+ */
+static int cyasblkdev_prep_request(
+ struct request_queue *q, struct request *req)
+{
+ DBGPRN_FUNC_NAME;
+
+ /* we only like normal block requests.*/
+ if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s:%x bad request received\n",
+ __func__, current->pid) ;
+ #endif
+
+ blk_dump_rq_flags(req, "cyasblkdev bad request");
+ return BLKPREP_KILL;
+ }
+
+ req->cmd_flags |= REQ_DONTPREP;
+
+ return BLKPREP_OK;
+}
+
+/* queue worker thread */
+static int cyasblkdev_queue_thread(void *d)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ struct cyasblkdev_queue *bq = d;
+ struct request_queue *q = bq->queue;
+ u32 qth_pid;
+
+ DBGPRN_FUNC_NAME;
+
+ /*
+ * set iothread to ensure that we aren't put to sleep by
+ * the process freezing. we handle suspension ourselves.
+ */
+ daemonize("cyasblkdev_queue_thread");
+
+ /* signal to queue_init() so it could contnue */
+ complete(&bq->thread_complete);
+
+ down(&bq->thread_sem);
+ add_wait_queue(&bq->thread_wq, &wait);
+
+ qth_pid = current->pid;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s:%x started, bq:%p, q:%p\n", __func__, qth_pid, bq, q) ;
+ #endif
+
+ do {
+ struct request *req = NULL;
+
+ /* the thread wants to be woken up by signals as well */
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ spin_lock_irq(q->queue_lock);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: for bq->queue is null\n", __func__);
+ #endif
+
+ if (!bq->req) {
+ /* chk if queue is plugged */
+ if (!blk_queue_plugged(q)) {
+ bq->req = req = blk_fetch_request(q);
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: blk_fetch_request:%x\n",
+ __func__, (uint32_t)req);
+ #endif
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: queue plugged, "
+ "skip blk_fetch()\n", __func__);
+ #endif
+ }
+ }
+ spin_unlock_irq(q->queue_lock);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: checking if request queue is null\n", __func__);
+ #endif
+
+ if (!req) {
+ if (bq->flags & CYASBLKDEV_QUEUE_EXIT) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s:got QUEUE_EXIT flag\n", __func__);
+ #endif
+
+ break;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: request queue is null, goto sleep, "
+ "thread_sem->count=%d\n",
+ __func__, bq->thread_sem.count);
+ if (spin_is_locked(q->queue_lock)) {
+ cy_as_hal_print_message("%s: queue_lock "
+ "is locked, need to release\n", __func__);
+ spin_unlock(q->queue_lock);
+
+ if (spin_is_locked(q->queue_lock))
+ cy_as_hal_print_message(
+ "%s: unlock did not work\n",
+ __func__);
+ } else {
+ cy_as_hal_print_message(
+ "%s: checked lock, is not locked\n",
+ __func__);
+ }
+ #endif
+
+ up(&bq->thread_sem);
+
+ /* yields to the next rdytorun proc,
+ * then goes back to sleep*/
+ schedule();
+ down(&bq->thread_sem);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: wake_up,continue\n",
+ __func__);
+ #endif
+ continue;
+ }
+
+ /* new req recieved, issue it to the driver */
+ set_current_state(TASK_RUNNING);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: issued a RQ:%x\n",
+ __func__, (uint32_t)req);
+ #endif
+
+ bq->issue_fn(bq, req);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: bq->issue_fn() returned\n",
+ __func__);
+ #endif
+
+
+ } while (1);
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&bq->thread_wq, &wait);
+ up(&bq->thread_sem);
+
+ complete_and_exit(&bq->thread_complete, 0);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: is finished\n", __func__) ;
+ #endif
+
+ return 0;
+}
+
+/*
+ * Generic request handler. it is called for any queue on a
+ * particular host. When the host is not busy, we look for a request
+ * on any queue on this host, and attempt to issue it. This may
+ * not be the queue we were asked to process.
+ */
+static void cyasblkdev_request(struct request_queue *q)
+{
+ struct cyasblkdev_queue *bq = q->queuedata;
+ DBGPRN_FUNC_NAME;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s new request on cyasblkdev_queue_t bq:=%x\n",
+ __func__, (uint32_t)bq);
+ #endif
+
+ if (!bq->req) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s wake_up(&bq->thread_wq)\n",
+ __func__);
+ #endif
+
+ /* wake up cyasblkdev_queue worker thread*/
+ wake_up(&bq->thread_wq);
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: don't wake Q_thr, bq->req:%x\n",
+ __func__, (uint32_t)bq->req);
+ #endif
+ }
+}
+
+/*
+ * cyasblkdev_init_queue - initialise a queue structure.
+ * @bq: cyasblkdev queue
+ * @dev: CyAsDeviceHandle to attach this queue
+ * @lock: queue lock
+ *
+ * Initialise a cyasblkdev_request queue.
+ */
+
+/* MAX NUMBER OF SECTORS PER REQUEST **/
+#define Q_MAX_SECTORS 128
+
+/* MAX NUMBER OF PHYS SEGMENTS (entries in the SG list)*/
+#define Q_MAX_SGS 16
+
+int cyasblkdev_init_queue(struct cyasblkdev_queue *bq, spinlock_t *lock)
+{
+ int ret;
+
+ DBGPRN_FUNC_NAME;
+
+ /* 1st param is a function that wakes up the queue thread */
+ bq->queue = blk_init_queue(cyasblkdev_request, lock);
+ if (!bq->queue)
+ return -ENOMEM;
+
+ blk_queue_prep_rq(bq->queue, cyasblkdev_prep_request);
+
+ blk_queue_bounce_limit(bq->queue, BLK_BOUNCE_ANY);
+ blk_queue_max_hw_sectors(bq->queue, Q_MAX_SECTORS);
+
+ /* As of now, we have the HAL/driver support to
+ * merge scattered segments and handle them simultaneously.
+ * so, setting the max_phys_segments to 8. */
+ /*blk_queue_max_phys_segments(bq->queue, Q_MAX_SGS);
+ blk_queue_max_hw_segments(bq->queue, Q_MAX_SGS);*/
+ blk_queue_max_segments(bq->queue, Q_MAX_SGS);
+
+ /* should be < then HAL can handle */
+ blk_queue_max_segment_size(bq->queue, 512*Q_MAX_SECTORS);
+
+ bq->queue->queuedata = bq;
+ bq->req = NULL;
+
+ init_completion(&bq->thread_complete);
+ init_waitqueue_head(&bq->thread_wq);
+ init_MUTEX(&bq->thread_sem);
+
+ ret = kernel_thread(cyasblkdev_queue_thread, bq, CLONE_KERNEL);
+ if (ret >= 0) {
+ /* wait until the thread is spawned */
+ wait_for_completion(&bq->thread_complete);
+
+ /* reinitialize the completion */
+ init_completion(&bq->thread_complete);
+ ret = 0;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL(cyasblkdev_init_queue);
+
+/*called from blk_put() */
+void cyasblkdev_cleanup_queue(struct cyasblkdev_queue *bq)
+{
+ DBGPRN_FUNC_NAME;
+
+ bq->flags |= CYASBLKDEV_QUEUE_EXIT;
+ wake_up(&bq->thread_wq);
+ wait_for_completion(&bq->thread_complete);
+
+ blk_cleanup_queue(bq->queue);
+}
+EXPORT_SYMBOL(cyasblkdev_cleanup_queue);
+
+
+/**
+ * cyasblkdev_queue_suspend - suspend a CyAsBlkDev request queue
+ * @bq: CyAsBlkDev queue to suspend
+ *
+ * Stop the block request queue, and wait for our thread to
+ * complete any outstanding requests. This ensures that we
+ * won't suspend while a request is being processed.
+ */
+void cyasblkdev_queue_suspend(struct cyasblkdev_queue *bq)
+{
+ struct request_queue *q = bq->queue;
+ unsigned long flags;
+
+ DBGPRN_FUNC_NAME;
+
+ if (!(bq->flags & CYASBLKDEV_QUEUE_SUSPENDED)) {
+ bq->flags |= CYASBLKDEV_QUEUE_SUSPENDED;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_stop_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ down(&bq->thread_sem);
+ }
+}
+EXPORT_SYMBOL(cyasblkdev_queue_suspend);
+
+/*cyasblkdev_queue_resume - resume a previously suspended
+ * CyAsBlkDev request queue @bq: CyAsBlkDev queue to resume */
+void cyasblkdev_queue_resume(struct cyasblkdev_queue *bq)
+{
+ struct request_queue *q = bq->queue;
+ unsigned long flags;
+
+ DBGPRN_FUNC_NAME;
+
+ if (bq->flags & CYASBLKDEV_QUEUE_SUSPENDED) {
+ bq->flags &= ~CYASBLKDEV_QUEUE_SUSPENDED;
+
+ up(&bq->thread_sem);
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_start_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+}
+EXPORT_SYMBOL(cyasblkdev_queue_resume);
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h
new file mode 100644
index 000000000000..26f9f596506d
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h
@@ -0,0 +1,64 @@
+/* cyanblkdev_queue.h - Antioch Linux Block Driver queue header file
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANBLKDEV_QUEUE_H_
+#define _INCLUDED_CYANBLKDEV_QUEUE_H_
+
+/*
+ * may contain various useful MACRO and debug printks
+ */
+
+/* moved to staging location, eventual implementation
+ * considered is here
+ * #include <linux/westbridge/cyashal.h>
+ * #include <linux/westbridge/cyastoria.h>
+ * */
+
+#include "../include/linux/westbridge/cyashal.h"
+#include "../include/linux/westbridge/cyastoria.h"
+
+struct request;
+struct task_struct;
+
+struct cyasblkdev_queue {
+ struct completion thread_complete;
+ wait_queue_head_t thread_wq;
+ struct semaphore thread_sem;
+ unsigned int flags;
+ struct request *req;
+ int (*prep_fn)(struct cyasblkdev_queue *, struct request *);
+ int (*issue_fn)(struct cyasblkdev_queue *, struct request *);
+ void *data;
+ struct request_queue *queue;
+};
+
+extern int cyasblkdev_init_queue(struct cyasblkdev_queue *, spinlock_t *);
+extern void cyasblkdev_cleanup_queue(struct cyasblkdev_queue *);
+extern void cyasblkdev_queue_suspend(struct cyasblkdev_queue *);
+extern void cyasblkdev_queue_resume(struct cyasblkdev_queue *);
+
+extern cy_as_device_handle cyasdevice_getdevhandle(void) ;
+#define MOD_LOGS 1
+void verbose_rq_flags(int flags);
+
+#endif /* _INCLUDED_CYANBLKDEV_QUEUE_H_ */
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/device/Kconfig b/drivers/staging/westbridge/astoria/device/Kconfig
new file mode 100644
index 000000000000..cc99658cf3a4
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/Kconfig
@@ -0,0 +1,9 @@
+#
+# West Bridge block driver configuration
+#
+
+config WESTBRIDGE_DEVICE_DRIVER
+ tristate "West Bridge Device Driver"
+ help
+ Include the West Bridge based device driver
+
diff --git a/drivers/staging/westbridge/astoria/device/Makefile b/drivers/staging/westbridge/astoria/device/Makefile
new file mode 100644
index 000000000000..7af8b5b0a8f5
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for the kernel westbridge device driver
+#
+
+ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
+ EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasdev.o
+
+
+ifeq ($(CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL),y)
+#moved for staging compatbility
+#cyasdev-y := ../../../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o
+cyasdev-y := ../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o \
+ ../api/src/cyasdma.o ../api/src/cyasintr.o ../api/src/cyaslep2pep.o \
+ ../api/src/cyaslowlevel.o ../api/src/cyasmisc.o ../api/src/cyasmtp.o \
+ ../api/src/cyasstorage.o ../api/src/cyasusb.o
+
+else
+# should not get here, need to be built with some hal
+cyasdev-y := cyasdevice.o
+endif
diff --git a/drivers/staging/westbridge/astoria/device/cyandevice_export.h b/drivers/staging/westbridge/astoria/device/cyandevice_export.h
new file mode 100644
index 000000000000..fc9dee994f01
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/cyandevice_export.h
@@ -0,0 +1,132 @@
+/*
+## cyandevice_export.h - Linux Antioch device driver file
+##
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * Export Misc APIs that can be used from the other driver modules.
+ * The APIs to create a device handle and download firmware are not exported
+ * because they are expected to be used only by this kernel module.
+ */
+EXPORT_SYMBOL(cy_as_misc_get_firmware_version) ;
+EXPORT_SYMBOL(cy_as_misc_read_m_c_u_register) ;
+EXPORT_SYMBOL(cy_as_misc_reset) ;
+EXPORT_SYMBOL(cy_as_misc_acquire_resource) ;
+EXPORT_SYMBOL(cy_as_misc_release_resource) ;
+EXPORT_SYMBOL(cy_as_misc_enter_standby) ;
+EXPORT_SYMBOL(cy_as_misc_leave_standby) ;
+EXPORT_SYMBOL(cy_as_misc_enter_suspend) ;
+EXPORT_SYMBOL(cy_as_misc_leave_suspend) ;
+EXPORT_SYMBOL(cy_as_misc_storage_changed) ;
+EXPORT_SYMBOL(cy_as_misc_heart_beat_control) ;
+EXPORT_SYMBOL(cy_as_misc_get_gpio_value) ;
+EXPORT_SYMBOL(cy_as_misc_set_gpio_value) ;
+EXPORT_SYMBOL(cy_as_misc_set_low_speed_sd_freq) ;
+EXPORT_SYMBOL(cy_as_misc_set_high_speed_sd_freq) ;
+
+/*
+ * Export the USB APIs that can be used by the dependent kernel modules.
+ */
+EXPORT_SYMBOL(cy_as_usb_set_end_point_config) ;
+EXPORT_SYMBOL(cy_as_usb_read_data_async) ;
+EXPORT_SYMBOL(cy_as_usb_write_data_async) ;
+EXPORT_SYMBOL(cy_as_usb_cancel_async) ;
+EXPORT_SYMBOL(cy_as_usb_set_stall) ;
+EXPORT_SYMBOL(cy_as_usb_clear_stall) ;
+EXPORT_SYMBOL(cy_as_usb_connect) ;
+EXPORT_SYMBOL(cy_as_usb_disconnect) ;
+EXPORT_SYMBOL(cy_as_usb_start) ;
+EXPORT_SYMBOL(cy_as_usb_stop) ;
+EXPORT_SYMBOL(cy_as_usb_set_enum_config) ;
+EXPORT_SYMBOL(cy_as_usb_get_enum_config) ;
+EXPORT_SYMBOL(cy_as_usb_set_physical_configuration) ;
+EXPORT_SYMBOL(cy_as_usb_register_callback) ;
+EXPORT_SYMBOL(cy_as_usb_commit_config) ;
+EXPORT_SYMBOL(cy_as_usb_set_descriptor) ;
+EXPORT_SYMBOL(cy_as_usb_clear_descriptors) ;
+EXPORT_SYMBOL(cy_as_usb_get_descriptor) ;
+EXPORT_SYMBOL(cy_as_usb_get_end_point_config) ;
+EXPORT_SYMBOL(cy_as_usb_read_data) ;
+EXPORT_SYMBOL(cy_as_usb_write_data) ;
+EXPORT_SYMBOL(cy_as_usb_get_stall) ;
+EXPORT_SYMBOL(cy_as_usb_set_nak) ;
+EXPORT_SYMBOL(cy_as_usb_clear_nak) ;
+EXPORT_SYMBOL(cy_as_usb_get_nak) ;
+EXPORT_SYMBOL(cy_as_usb_signal_remote_wakeup) ;
+EXPORT_SYMBOL(cy_as_usb_set_m_s_report_threshold) ;
+EXPORT_SYMBOL(cy_as_usb_select_m_s_partitions) ;
+
+/*
+ * Export all Storage APIs that can be used by dependent kernel modules.
+ */
+EXPORT_SYMBOL(cy_as_storage_start) ;
+EXPORT_SYMBOL(cy_as_storage_stop) ;
+EXPORT_SYMBOL(cy_as_storage_register_callback) ;
+EXPORT_SYMBOL(cy_as_storage_query_bus) ;
+EXPORT_SYMBOL(cy_as_storage_query_media) ;
+EXPORT_SYMBOL(cy_as_storage_query_device) ;
+EXPORT_SYMBOL(cy_as_storage_query_unit) ;
+EXPORT_SYMBOL(cy_as_storage_device_control) ;
+EXPORT_SYMBOL(cy_as_storage_claim) ;
+EXPORT_SYMBOL(cy_as_storage_release) ;
+EXPORT_SYMBOL(cy_as_storage_read) ;
+EXPORT_SYMBOL(cy_as_storage_write) ;
+EXPORT_SYMBOL(cy_as_storage_read_async) ;
+EXPORT_SYMBOL(cy_as_storage_write_async) ;
+EXPORT_SYMBOL(cy_as_storage_cancel_async) ;
+EXPORT_SYMBOL(cy_as_storage_sd_register_read) ;
+EXPORT_SYMBOL(cy_as_storage_create_p_partition) ;
+EXPORT_SYMBOL(cy_as_storage_remove_p_partition) ;
+EXPORT_SYMBOL(cy_as_storage_get_transfer_amount) ;
+EXPORT_SYMBOL(cy_as_storage_erase) ;
+
+EXPORT_SYMBOL(cy_as_sdio_query_card);
+EXPORT_SYMBOL(cy_as_sdio_init_function);
+EXPORT_SYMBOL(cy_as_sdio_set_blocksize);
+EXPORT_SYMBOL(cy_as_sdio_direct_read);
+EXPORT_SYMBOL(cy_as_sdio_direct_write);
+EXPORT_SYMBOL(cy_as_sdio_extended_read);
+EXPORT_SYMBOL(cy_as_sdio_extended_write);
+
+EXPORT_SYMBOL(cy_as_hal_alloc) ;
+EXPORT_SYMBOL(cy_as_hal_free) ;
+EXPORT_SYMBOL(cy_as_hal_sleep) ;
+EXPORT_SYMBOL(cy_as_hal_create_sleep_channel) ;
+EXPORT_SYMBOL(cy_as_hal_destroy_sleep_channel) ;
+EXPORT_SYMBOL(cy_as_hal_sleep_on) ;
+EXPORT_SYMBOL(cy_as_hal_wake) ;
+EXPORT_SYMBOL(cy_as_hal_mem_set);
+
+EXPORT_SYMBOL(cy_as_mtp_storage_only_start);
+EXPORT_SYMBOL(cy_as_mtp_storage_only_stop);
+EXPORT_SYMBOL(cy_as_mtp_start);
+EXPORT_SYMBOL(cy_as_mtp_init_send_object);
+EXPORT_SYMBOL(cy_as_mtp_init_get_object);
+EXPORT_SYMBOL(cy_as_mtp_cancel_send_object);
+EXPORT_SYMBOL(cy_as_mtp_cancel_get_object);
+
+#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__
+/* Functions in the SCM kernel HAL implementation only. */
+EXPORT_SYMBOL(cy_as_hal_enable_scatter_list) ;
+EXPORT_SYMBOL(cy_as_hal_disable_scatter_list) ;
+#endif
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c
new file mode 100644
index 000000000000..cd0f7cbc9b18
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/cyasdevice.c
@@ -0,0 +1,394 @@
+/*
+## cyandevice.c - Linux Antioch device driver file
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/scatterlist.h>
+#include <linux/err.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* moved for staging location
+ * update/patch submission
+#include <linux/westbridge/cyastoria.h>
+#include <linux/westbridge/cyashal.h>
+#include <linux/westbridge/cyasregs.h>
+*/
+
+#include "../include/linux/westbridge/cyastoria.h"
+#include "../include/linux/westbridge/cyashal.h"
+#include "../include/linux/westbridge/cyasregs.h"
+
+/* API exports include file */
+#include "cyandevice_export.h"
+
+typedef struct cyasdevice {
+ /* Handle to the Antioch device */
+ cy_as_device_handle dev_handle;
+ /* Handle to the HAL */
+ cy_as_hal_device_tag hal_tag;
+} cyasdevice ;
+
+/* global ptr to astoria device */
+static cyasdevice *cy_as_device_controller ;
+int cy_as_device_init_done;
+const char *dev_handle_name = "cy_astoria_dev_handle" ;
+
+#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+extern void cy_as_hal_config_c_s_mux(void);
+#endif
+
+static void cyasdevice_deinit(cyasdevice *cy_as_dev)
+{
+ cy_as_hal_print_message("<1>_cy_as_device deinitialize called\n") ;
+ if (!cy_as_dev) {
+ cy_as_hal_print_message("<1>_cy_as_device_deinit: "
+ "device handle %x is invalid\n", (uint32_t)cy_as_dev) ;
+ return ;
+ }
+
+ /* stop west_brige */
+ if (cy_as_dev->dev_handle) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_misc_destroy_device called\n") ;
+ if (cy_as_misc_destroy_device(cy_as_dev->dev_handle) !=
+ CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: destroying failed\n");
+ }
+ }
+
+ if (cy_as_dev->hal_tag) {
+
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ if (stop_o_m_a_p_kernel(dev_handle_name,
+ cy_as_dev->hal_tag) != 0)
+ cy_as_hal_print_message("<1>_cy_as_device: stopping "
+ "OMAP kernel HAL failed\n");
+
+ #endif
+ }
+ cy_as_hal_print_message("<1>_cy_as_device:HAL layer stopped\n") ;
+
+ kfree(cy_as_dev) ;
+ cy_as_device_controller = NULL ;
+ cy_as_hal_print_message("<1>_cy_as_device: deinitialized\n") ;
+}
+
+/*called from src/cyasmisc.c:MyMiscCallback() as a func
+ * pointer [dev_p->misc_event_cb] which was previously
+ * registered by CyAsLLRegisterRequestCallback(...,
+ * MyMiscCallback) ; called from CyAsMiscConfigureDevice()
+ * which is in turn called from cyasdevice_initialize() in
+ * this src
+ */
+static void cy_misc_callback(cy_as_device_handle h,
+ cy_as_misc_event_type evtype, void *evdata)
+{
+ (void)h ;
+ (void)evdata ;
+
+ switch (evtype) {
+ case cy_as_event_misc_initialized:
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "initialization done callback triggered\n") ;
+ cy_as_device_init_done = 1 ;
+ break ;
+
+ case cy_as_event_misc_awake:
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_event_misc_awake event callback triggered\n") ;
+ cy_as_device_init_done = 1 ;
+ break ;
+ default:
+ break ;
+ }
+}
+
+/* reset astoria and reinit all regs */
+ #define PNAND_REG_CFG_INIT_VAL 0x0000
+void hal_reset(cy_as_hal_device_tag tag)
+{
+ cy_as_hal_print_message("<1> send soft hard rst: "
+ "MEM_RST_CTRL_REG_HARD...\n");
+ cy_as_hal_write_register(tag, CY_AS_MEM_RST_CTRL_REG,
+ CY_AS_MEM_RST_CTRL_REG_HARD) ;
+ mdelay(60);
+
+ cy_as_hal_print_message("<1> after RST: si_rev_REG:%x, "
+ "PNANDCFG_reg:%x\n",
+ cy_as_hal_read_register(tag, CY_AS_MEM_CM_WB_CFG_ID),
+ cy_as_hal_read_register(tag, CY_AS_MEM_PNAND_CFG)
+ );
+
+ /* set it to LBD */
+ cy_as_hal_write_register(tag, CY_AS_MEM_PNAND_CFG,
+ PNAND_REG_CFG_INIT_VAL) ;
+}
+EXPORT_SYMBOL(hal_reset);
+
+
+/* below structures and functions primarily
+ * implemented for firmware loading */
+static struct platform_device *westbridge_pd;
+
+static int __devinit wb_probe(struct platform_device *devptr)
+{
+ cy_as_hal_print_message("%s called\n", __func__);
+ return 0;
+}
+
+static int __devexit wb_remove(struct platform_device *devptr)
+{
+ cy_as_hal_print_message("%s called\n", __func__);
+ return 0;
+}
+
+static struct platform_driver west_bridge_driver = {
+ .probe = wb_probe,
+ .remove = __devexit_p(wb_remove),
+ .driver = {
+ .name = "west_bridge_dev"},
+};
+
+/* west bridge device driver main init */
+static int cyasdevice_initialize(void)
+{
+ cyasdevice *cy_as_dev = 0 ;
+ int ret = 0 ;
+ int retval = 0 ;
+ cy_as_device_config config ;
+ cy_as_hal_sleep_channel channel ;
+ cy_as_get_firmware_version_data ver_data = {0};
+ const char *str = "" ;
+ int spin_lim;
+ const struct firmware *fw_entry;
+
+ cy_as_device_init_done = 0;
+
+ cy_as_misc_set_log_level(8);
+
+ cy_as_hal_print_message("<1>_cy_as_device initialize called\n") ;
+
+ if (cy_as_device_controller != 0) {
+ cy_as_hal_print_message("<1>_cy_as_device: the device "
+ "has already been initilaized. ignoring\n") ;
+ return -EBUSY ;
+ }
+
+ /* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */
+ cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice));
+ if (cy_as_dev == NULL) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "memmory allocation failed\n") ;
+ return -ENOMEM;
+ }
+ memset(cy_as_dev, 0, sizeof(cyasdevice));
+
+
+ /* Init the HAL & CyAsDeviceHandle */
+
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ /* start OMAP HAL init instsnce */
+
+ if (!start_o_m_a_p_kernel(dev_handle_name,
+ &(cy_as_dev->hal_tag), cy_false)) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: start OMAP34xx HAL failed\n") ;
+ goto done;
+ }
+ #endif
+
+ /* Now create the device */
+ if (cy_as_misc_create_device(&(cy_as_dev->dev_handle),
+ cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: create device failed\n") ;
+ goto done ;
+ }
+
+ memset(&config, 0, sizeof(config));
+ config.dmaintr = cy_true;
+
+ ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: configure device "
+ "failed. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ ret = cy_as_misc_register_callback(cy_as_dev->dev_handle,
+ cy_misc_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_misc_register_callback failed. "
+ "reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ ret = platform_driver_register(&west_bridge_driver);
+ if (unlikely(ret < 0))
+ return ret;
+ westbridge_pd = platform_device_register_simple(
+ "west_bridge_dev", -1, NULL, 0);
+
+ if (IS_ERR(westbridge_pd)) {
+ platform_driver_unregister(&west_bridge_driver);
+ return PTR_ERR(westbridge_pd);
+ }
+ /* Load the firmware */
+ ret = request_firmware(&fw_entry,
+ "west bridge fw", &westbridge_pd->dev);
+ if (ret) {
+ cy_as_hal_print_message("cy_as_device: "
+ "request_firmware failed return val = %d\n", ret);
+ } else {
+ cy_as_hal_print_message("cy_as_device: "
+ "got the firmware %d size=0x%x\n", ret, fw_entry->size);
+
+ ret = cy_as_misc_download_firmware(
+ cy_as_dev->dev_handle,
+ fw_entry->data,
+ fw_entry->size ,
+ 0, 0) ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: cannot download "
+ "firmware. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ /* spin until the device init is completed */
+ /* 50 -MAX wait time for the FW load & init
+ * to complete is 5sec*/
+ spin_lim = 50;
+
+ cy_as_hal_create_sleep_channel(&channel) ;
+ while (!cy_as_device_init_done) {
+
+ cy_as_hal_sleep_on(&channel, 100) ;
+
+ if (spin_lim-- <= 0) {
+ cy_as_hal_print_message(
+ "<1>\n_e_r_r_o_r!: "
+ "wait for FW init has timed out !!!");
+ break;
+ }
+ }
+ cy_as_hal_destroy_sleep_channel(&channel) ;
+
+ if (spin_lim > 0)
+ cy_as_hal_print_message(
+ "cy_as_device: astoria firmware is loaded\n") ;
+
+ ret = cy_as_misc_get_firmware_version(cy_as_dev->dev_handle,
+ &ver_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: cannot get firmware "
+ "version. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06))
+ str = "nand and SD/MMC." ;
+ else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08))
+ str = "nand and CEATA." ;
+ else if (ver_data.media_type & 0x01)
+ str = "nand." ;
+ else if (ver_data.media_type & 0x08)
+ str = "CEATA." ;
+ else
+ str = "SD/MMC." ;
+
+ cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s "
+ "major=%d minor=%d build=%d,\n_media types supported:%s\n",
+ ((ver_data.is_debug_mode) ? "debug" : "release"),
+ ver_data.major, ver_data.minor, ver_data.build, str) ;
+
+ /* done now */
+ cy_as_device_controller = cy_as_dev ;
+
+ return 0 ;
+
+done:
+ if (cy_as_dev)
+ cyasdevice_deinit(cy_as_dev) ;
+
+ return -EINVAL ;
+}
+
+cy_as_device_handle cyasdevice_getdevhandle(void)
+{
+ if (cy_as_device_controller) {
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ cy_as_hal_config_c_s_mux();
+ #endif
+
+ return cy_as_device_controller->dev_handle ;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(cyasdevice_getdevhandle) ;
+
+cy_as_hal_device_tag cyasdevice_gethaltag(void)
+{
+ if (cy_as_device_controller)
+ return (cy_as_hal_device_tag)
+ cy_as_device_controller->hal_tag ;
+
+ return NULL;
+}
+EXPORT_SYMBOL(cyasdevice_gethaltag) ;
+
+
+/*init Westbridge device driver **/
+static int __init cyasdevice_init(void)
+{
+ if (cyasdevice_initialize() != 0)
+ return ENODEV;
+
+ return 0 ;
+}
+
+
+static void __exit cyasdevice_cleanup(void)
+{
+
+ cyasdevice_deinit(cy_as_device_controller) ;
+}
+
+
+MODULE_DESCRIPTION("west bridge device driver");
+MODULE_AUTHOR("cypress semiconductor");
+MODULE_LICENSE("GPL");
+
+module_init(cyasdevice_init);
+module_exit(cyasdevice_cleanup);
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/gadget/Kconfig b/drivers/staging/westbridge/astoria/gadget/Kconfig
new file mode 100644
index 000000000000..6fbdf2277b03
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/gadget/Kconfig
@@ -0,0 +1,9 @@
+#
+# West Bridge gadget driver configuration
+#
+
+config WESTBRIDGE_GADGET_DRIVER
+ tristate "West Bridge Gadget Driver"
+ help
+ Include the West Bridge based gadget peripheral controller driver
+
diff --git a/drivers/staging/westbridge/astoria/gadget/Makefile b/drivers/staging/westbridge/astoria/gadget/Makefile
new file mode 100644
index 000000000000..a5eef7ee60a4
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/gadget/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the kernel westbridge hal
+#
+
+ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
+ EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE_GADGET_DRIVER) += cyasgadgetctrl.o
+cyasgadgetctrl-y := cyasgadget.o
+
diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget.c b/drivers/staging/westbridge/astoria/gadget/cyasgadget.c
new file mode 100644
index 000000000000..756ff278f66d
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/gadget/cyasgadget.c
@@ -0,0 +1,2177 @@
+/* cyangadget.c - Linux USB Gadget driver file for the Cypress West Bridge
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * Cypress West Bridge high/full speed usb device controller code
+ * Based on the Netchip 2280 device controller by David Brownell
+ * in the linux 2.6.10 kernel
+ *
+ * linux/drivers/usb/gadget/net2280.c
+ */
+
+/*
+ * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
+ * Copyright (C) 2003 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.
+ *
+ * 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 "cyasgadget.h"
+
+#define CY_AS_DRIVER_DESC "cypress west bridge usb gadget"
+#define CY_AS_DRIVER_VERSION "REV B"
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+static const char cy_as_driver_name[] = "cy_astoria_gadget";
+static const char cy_as_driver_desc[] = CY_AS_DRIVER_DESC;
+
+static const char cy_as_ep0name[] = "EP0";
+static const char *cy_as_ep_names[] = {
+ cy_as_ep0name, "EP1",
+ "EP2", "EP3", "EP4", "EP5", "EP6", "EP7", "EP8",
+ "EP9", "EP10", "EP11", "EP12", "EP13", "EP14", "EP15"
+};
+
+/* forward declarations */
+static void
+cyas_ep_reset(
+ struct cyasgadget_ep *an_ep) ;
+
+static int
+cyasgadget_fifo_status(
+ struct usb_ep *_ep) ;
+
+static void
+cyasgadget_stallcallback(
+ cy_as_device_handle h,
+ cy_as_return_status_t status,
+ uint32_t tag,
+ cy_as_funct_c_b_type cbtype,
+ void *cbdata);
+
+/* variables */
+static cyasgadget *cy_as_gadget_controller;
+
+static int append_mtp;
+module_param(append_mtp, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(append_mtp,
+ "west bridge to append descriptors for mtp 0=no 1=yes");
+
+static int msc_enum_bus_0;
+module_param(msc_enum_bus_0, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msc_enum_bus_0,
+ "west bridge to enumerate bus 0 as msc 0=no 1=yes");
+
+static int msc_enum_bus_1;
+module_param(msc_enum_bus_1, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msc_enum_bus_1,
+ "west bridge to enumerate bus 1 as msc 0=no 1=yes");
+
+/* all Callbacks are placed in this subsection*/
+static void cy_as_gadget_usb_event_callback(
+ cy_as_device_handle h,
+ cy_as_usb_event ev,
+ void *evdata
+ )
+{
+ cyasgadget *cy_as_dev ;
+ #ifndef WESTBRIDGE_NDEBUG
+ struct usb_ctrlrequest *ctrlreq;
+ #endif
+
+ /* cy_as_dev = container_of(h, cyasgadget, dev_handle); */
+ cy_as_dev = cy_as_gadget_controller ;
+ switch (ev) {
+ case cy_as_event_usb_suspend:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_suspend received\n") ;
+ #endif
+ cy_as_dev->driver->suspend(&cy_as_dev->gadget) ;
+ break;
+
+ case cy_as_event_usb_resume:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_resume received\n") ;
+ #endif
+ cy_as_dev->driver->resume(&cy_as_dev->gadget) ;
+ break;
+
+ case cy_as_event_usb_reset:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_reset received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_speed_change:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_speed_change received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_set_config:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_set_config received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_setup_packet:
+ #ifndef WESTBRIDGE_NDEBUG
+ ctrlreq = (struct usb_ctrlrequest *)evdata;
+
+ cy_as_hal_print_message("<1>_cy_as_event_usb_setup_packet "
+ "received"
+ "bRequestType=0x%x,"
+ "bRequest=0x%x,"
+ "wValue=x%x,"
+ "wIndex=0x%x,"
+ "wLength=0x%x,",
+ ctrlreq->bRequestType,
+ ctrlreq->bRequest,
+ ctrlreq->wValue,
+ ctrlreq->wIndex,
+ ctrlreq->wLength
+ ) ;
+ #endif
+ cy_as_dev->outsetupreq = 0;
+ if ((((uint8_t *)evdata)[0] & USB_DIR_IN) == USB_DIR_OUT)
+ cy_as_dev->outsetupreq = 1;
+ cy_as_dev->driver->setup(&cy_as_dev->gadget,
+ (struct usb_ctrlrequest *)evdata) ;
+ break;
+
+ case cy_as_event_usb_status_packet:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_status_packet received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_inquiry_before:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_inquiry_before received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_inquiry_after:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_inquiry_after received\n") ;
+ #endif
+ break;
+
+ case cy_as_event_usb_start_stop:
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<1>_cy_as_event_usb_start_stop received\n") ;
+ #endif
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void cy_as_gadget_mtp_event_callback(
+ cy_as_device_handle handle,
+ cy_as_mtp_event evtype,
+ void *evdata
+ )
+{
+
+ cyasgadget *dev = cy_as_gadget_controller ;
+ (void) handle;
+
+ switch (evtype) {
+ case cy_as_mtp_send_object_complete:
+ {
+ cy_as_mtp_send_object_complete_data *send_obj_data =
+ (cy_as_mtp_send_object_complete_data *) evdata ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<6>MTP EVENT: send_object_complete\n");
+ cy_as_hal_print_message(
+ "<6>_bytes sent = %d\n_send status = %d",
+ send_obj_data->byte_count,
+ send_obj_data->status);
+ #endif
+
+ dev->tmtp_send_complete_data.byte_count =
+ send_obj_data->byte_count;
+ dev->tmtp_send_complete_data.status =
+ send_obj_data->status;
+ dev->tmtp_send_complete_data.transaction_id =
+ send_obj_data->transaction_id ;
+ dev->tmtp_send_complete = cy_true ;
+ break;
+ }
+ case cy_as_mtp_get_object_complete:
+ {
+ cy_as_mtp_get_object_complete_data *get_obj_data =
+ (cy_as_mtp_get_object_complete_data *) evdata ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<6>MTP EVENT: get_object_complete\n");
+ cy_as_hal_print_message(
+ "<6>_bytes got = %d\n_get status = %d",
+ get_obj_data->byte_count, get_obj_data->status);
+ #endif
+
+ dev->tmtp_get_complete_data.byte_count =
+ get_obj_data->byte_count;
+ dev->tmtp_get_complete_data.status =
+ get_obj_data->status ;
+ dev->tmtp_get_complete = cy_true ;
+ break;
+ }
+ case cy_as_mtp_block_table_needed:
+ {
+ dev->tmtp_need_new_blk_tbl = cy_true ;
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<6>MTP EVENT: cy_as_mtp_block_table_needed\n");
+ #endif
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+cyasgadget_setupreadcallback(
+ cy_as_device_handle h,
+ cy_as_end_point_number_t ep,
+ uint32_t count,
+ void *buf,
+ cy_as_return_status_t status)
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget_req *an_req;
+ cyasgadget *cy_as_dev ;
+ unsigned stopped ;
+ unsigned long flags;
+ (void)buf ;
+
+ cy_as_dev = cy_as_gadget_controller ;
+ if (cy_as_dev->driver == NULL)
+ return;
+
+ an_ep = &cy_as_dev->an_gadget_ep[ep] ;
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+ stopped = an_ep->stopped ;
+
+#ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: ep=%d, count=%d, "
+ "status=%d\n", __func__, ep, count, status) ;
+#endif
+
+ an_req = list_entry(an_ep->queue.next,
+ cyasgadget_req, queue) ;
+ list_del_init(&an_req->queue) ;
+
+ if (status == CY_AS_ERROR_SUCCESS)
+ an_req->req.status = 0;
+ else
+ an_req->req.status = -status;
+ an_req->req.actual = count ;
+ an_ep->stopped = 1;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req);
+
+ an_ep->stopped = stopped;
+
+}
+/*called when the write of a setup packet has been completed*/
+static void cyasgadget_setupwritecallback(
+ cy_as_device_handle h,
+ cy_as_end_point_number_t ep,
+ uint32_t count,
+ void *buf,
+ cy_as_return_status_t status
+ )
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget_req *an_req;
+ cyasgadget *cy_as_dev ;
+ unsigned stopped ;
+ unsigned long flags;
+
+ (void)buf ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called status=0x%x\n",
+ __func__, status);
+ #endif
+
+ cy_as_dev = cy_as_gadget_controller ;
+
+ if (cy_as_dev->driver == NULL)
+ return;
+
+ an_ep = &cy_as_dev->an_gadget_ep[ep] ;
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+
+ stopped = an_ep->stopped ;
+
+#ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("setup_write_callback: ep=%d, "
+ "count=%d, status=%d\n", ep, count, status) ;
+#endif
+
+ an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue) ;
+ list_del_init(&an_req->queue) ;
+
+ an_req->req.actual = count ;
+ an_req->req.status = 0 ;
+ an_ep->stopped = 1;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req);
+
+ an_ep->stopped = stopped;
+
+}
+
+/* called when a read operation has completed.*/
+static void cyasgadget_readcallback(
+ cy_as_device_handle h,
+ cy_as_end_point_number_t ep,
+ uint32_t count,
+ void *buf,
+ cy_as_return_status_t status
+ )
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget_req *an_req;
+ cyasgadget *cy_as_dev ;
+ unsigned stopped ;
+ cy_as_return_status_t ret ;
+ unsigned long flags;
+
+ (void)h ;
+ (void)buf ;
+
+ cy_as_dev = cy_as_gadget_controller ;
+
+ if (cy_as_dev->driver == NULL)
+ return;
+
+ an_ep = &cy_as_dev->an_gadget_ep[ep] ;
+ stopped = an_ep->stopped ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: ep=%d, count=%d, status=%d\n",
+ __func__, ep, count, status) ;
+ #endif
+
+ if (status == CY_AS_ERROR_CANCELED)
+ return ;
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+
+ an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue) ;
+ list_del_init(&an_req->queue) ;
+
+ if (status == CY_AS_ERROR_SUCCESS)
+ an_req->req.status = 0 ;
+ else
+ an_req->req.status = -status ;
+
+ an_req->complete = 1;
+ an_req->req.actual = count ;
+ an_ep->stopped = 1;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+ an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req);
+
+ an_ep->stopped = stopped;
+
+ /* We need to call ReadAsync on this end-point
+ * again, so as to not miss any data packets. */
+ if (!an_ep->stopped) {
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+ an_req = 0 ;
+ if (!list_empty(&an_ep->queue))
+ an_req = list_entry(an_ep->queue.next,
+ cyasgadget_req, queue) ;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ if ((an_req) && (an_req->req.status == -EINPROGRESS)) {
+ ret = cy_as_usb_read_data_async(cy_as_dev->dev_handle,
+ an_ep->num, cy_false, an_req->req.length,
+ an_req->req.buf, cyasgadget_readcallback);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_read_data_async failed "
+ "with error code %d\n", ret) ;
+ else
+ an_req->req.status = -EALREADY ;
+ }
+ }
+}
+
+/* function is called when a usb write operation has completed*/
+static void cyasgadget_writecallback(
+ cy_as_device_handle h,
+ cy_as_end_point_number_t ep,
+ uint32_t count,
+ void *buf,
+ cy_as_return_status_t status
+ )
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget_req *an_req;
+ cyasgadget *cy_as_dev ;
+ unsigned stopped = 0;
+ cy_as_return_status_t ret ;
+ unsigned long flags;
+
+ (void)h ;
+ (void)buf ;
+
+ cy_as_dev = cy_as_gadget_controller ;
+ if (cy_as_dev->driver == NULL)
+ return;
+
+ an_ep = &cy_as_dev->an_gadget_ep[ep] ;
+
+ if (status == CY_AS_ERROR_CANCELED)
+ return ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: ep=%d, count=%d, status=%d\n",
+ __func__, ep, count, status) ;
+ #endif
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+
+ an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue) ;
+ list_del_init(&an_req->queue) ;
+ an_req->req.actual = count ;
+
+ /* Verify the status value before setting req.status to zero */
+ if (status == CY_AS_ERROR_SUCCESS)
+ an_req->req.status = 0 ;
+ else
+ an_req->req.status = -status ;
+
+ an_ep->stopped = 1;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req);
+ an_ep->stopped = stopped;
+
+ /* We need to call WriteAsync on this end-point again, so as to not
+ miss any data packets. */
+ if (!an_ep->stopped) {
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+ an_req = 0 ;
+ if (!list_empty(&an_ep->queue))
+ an_req = list_entry(an_ep->queue.next,
+ cyasgadget_req, queue) ;
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ if ((an_req) && (an_req->req.status == -EINPROGRESS)) {
+ ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle,
+ an_ep->num, an_req->req.length, an_req->req.buf,
+ cy_false, cyasgadget_writecallback);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async "
+ "failed with error code %d\n", ret) ;
+ else
+ an_req->req.status = -EALREADY ;
+ }
+ }
+}
+
+static void cyasgadget_stallcallback(
+ cy_as_device_handle h,
+ cy_as_return_status_t status,
+ uint32_t tag,
+ cy_as_funct_c_b_type cbtype,
+ void *cbdata
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ if (status != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_set/_clear stall "
+ "failed with status %d\n", status) ;
+ #endif
+}
+
+
+/*******************************************************************/
+/* All usb_ep_ops (cyasgadget_ep_ops) are placed in this subsection*/
+/*******************************************************************/
+static int cyasgadget_enable(
+ struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc
+ )
+{
+ cyasgadget *an_dev;
+ cyasgadget_ep *an_ep;
+ u32 max, tmp;
+ unsigned long flags;
+
+ an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+ if (!_ep || !desc || an_ep->desc || _ep->name == cy_as_ep0name
+ || desc->bDescriptorType != USB_DT_ENDPOINT)
+ return -EINVAL;
+
+ an_dev = an_ep->dev;
+ if (!an_dev->driver || an_dev->gadget.speed == USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+ max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff;
+
+ spin_lock_irqsave(&an_dev->lock, flags);
+ _ep->maxpacket = max & 0x7ff;
+ an_ep->desc = desc;
+
+ /* ep_reset() has already been called */
+ an_ep->stopped = 0;
+ an_ep->out_overflow = 0;
+
+ if (an_ep->cyepconfig.enabled != cy_true) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on enabled\n", an_ep->usb_ep_inst.name) ;
+ #endif
+ return -EINVAL;
+ }
+
+ tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+ an_ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
+
+ spin_unlock_irqrestore(&an_dev->lock, flags);
+
+ switch (tmp) {
+ case USB_ENDPOINT_XFER_ISOC:
+ if (an_ep->cyepconfig.type != cy_as_usb_iso) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on type %d %d\n", an_ep->usb_ep_inst.name,
+ an_ep->cyepconfig.type, cy_as_usb_iso) ;
+ #endif
+ return -EINVAL;
+ }
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ if (an_ep->cyepconfig.type != cy_as_usb_int) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on type %d %d\n", an_ep->usb_ep_inst.name,
+ an_ep->cyepconfig.type, cy_as_usb_int) ;
+ #endif
+ return -EINVAL;
+ }
+ break;
+ default:
+ if (an_ep->cyepconfig.type != cy_as_usb_bulk) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on type %d %d\n", an_ep->usb_ep_inst.name,
+ an_ep->cyepconfig.type, cy_as_usb_bulk) ;
+ #endif
+ return -EINVAL;
+ }
+ break;
+ }
+
+ tmp = desc->bEndpointAddress;
+ an_ep->is_in = (tmp & USB_DIR_IN) != 0;
+
+ if ((an_ep->cyepconfig.dir == cy_as_usb_in) &&
+ (!an_ep->is_in)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on dir %d %d\n", an_ep->usb_ep_inst.name,
+ an_ep->cyepconfig.dir, cy_as_usb_in) ;
+ #endif
+ return -EINVAL;
+ } else if ((an_ep->cyepconfig.dir == cy_as_usb_out) &&
+ (an_ep->is_in)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_end_point_config EP %s mismatch "
+ "on dir %d %d\n", an_ep->usb_ep_inst.name,
+ an_ep->cyepconfig.dir, cy_as_usb_out) ;
+ #endif
+ return -EINVAL;
+ }
+
+ cy_as_usb_clear_stall(an_dev->dev_handle, an_ep->num,
+ cyasgadget_stallcallback, 0);
+
+ cy_as_hal_print_message("%s enabled %s (ep%d-%d) max %04x\n",
+ __func__, _ep->name, an_ep->num, tmp, max);
+
+ return 0;
+}
+
+static int cyasgadget_disable(
+ struct usb_ep *_ep
+ )
+{
+ cyasgadget_ep *an_ep;
+ unsigned long flags;
+
+ an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+ if (!_ep || !an_ep->desc || _ep->name == cy_as_ep0name)
+ return -EINVAL;
+
+ spin_lock_irqsave(&an_ep->dev->lock, flags);
+ cyas_ep_reset(an_ep);
+
+ spin_unlock_irqrestore(&an_ep->dev->lock, flags);
+ return 0;
+}
+
+static struct usb_request *cyasgadget_alloc_request(
+ struct usb_ep *_ep, gfp_t gfp_flags
+ )
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget_req *an_req;
+
+ if (!_ep)
+ return NULL;
+
+ an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+
+ an_req = kzalloc(sizeof(cyasgadget_req), gfp_flags);
+ if (!an_req)
+ return NULL;
+
+ an_req->req.dma = DMA_ADDR_INVALID;
+ INIT_LIST_HEAD(&an_req->queue);
+
+ return &an_req->req;
+}
+
+static void cyasgadget_free_request(
+ struct usb_ep *_ep,
+ struct usb_request *_req
+ )
+{
+ cyasgadget_req *an_req ;
+
+ if (!_ep || !_req)
+ return ;
+
+ an_req = container_of(_req, cyasgadget_req, req) ;
+
+ kfree(an_req);
+}
+
+/* Load a packet into the fifo we use for usb IN transfers.
+ * works for all endpoints. */
+static int cyasgadget_queue(
+ struct usb_ep *_ep,
+ struct usb_request *_req,
+ gfp_t gfp_flags
+ )
+{
+ cyasgadget_req *as_req;
+ cyasgadget_ep *as_ep;
+ cyasgadget *cy_as_dev;
+ unsigned long flags;
+ cy_as_return_status_t ret = 0;
+
+ as_req = container_of(_req, cyasgadget_req, req);
+ if (!_req || !_req->complete || !_req->buf
+ || !list_empty(&as_req->queue))
+ return -EINVAL;
+
+ as_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+
+ if (!_ep || (!as_ep->desc && (as_ep->num != 0)))
+ return -EINVAL;
+
+ cy_as_dev = as_ep->dev;
+ if (!cy_as_dev->driver ||
+ cy_as_dev->gadget.speed == USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ /* Call Async functions */
+ if (as_ep->is_in) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async being called "
+ "on ep %d\n", as_ep->num) ;
+ #endif
+
+ ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle,
+ as_ep->num, _req->length, _req->buf,
+ cy_false, cyasgadget_writecallback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async failed with "
+ "error code %d\n", ret) ;
+ else
+ _req->status = -EALREADY ;
+ } else if (as_ep->num == 0) {
+ /*
+ ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle,
+ as_ep->num, _req->length, _req->buf, cy_false,
+ cyasgadget_setupwritecallback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async failed with error "
+ "code %d\n", ret) ;
+ */
+ if ((cy_as_dev->outsetupreq) && (_req->length)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_read_data_async "
+ "being called on ep %d\n",
+ as_ep->num) ;
+ #endif
+
+ ret = cy_as_usb_read_data_async (
+ cy_as_dev->dev_handle, as_ep->num,
+ cy_true, _req->length, _req->buf,
+ cyasgadget_setupreadcallback);
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_read_data_async failed with "
+ "error code %d\n", ret) ;
+
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async "
+ "being called on ep %d\n",
+ as_ep->num) ;
+ #endif
+
+ ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle,
+ as_ep->num, _req->length, _req->buf, cy_false,
+ cyasgadget_setupwritecallback) ;
+
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_write_data_async failed with "
+ "error code %d\n", ret) ;
+ }
+
+ } else if (list_empty(&as_ep->queue)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_read_data_async being called since "
+ "ep queue empty%d\n", ret) ;
+ #endif
+
+ ret = cy_as_usb_read_data_async(cy_as_dev->dev_handle,
+ as_ep->num, cy_false, _req->length, _req->buf,
+ cyasgadget_readcallback) ;
+ if (ret != CY_AS_ERROR_SUCCESS)
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_read_data_async failed with error "
+ "code %d\n", ret) ;
+ else
+ _req->status = -EALREADY ;
+ }
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+
+ if (as_req)
+ list_add_tail(&as_req->queue, &as_ep->queue);
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ return 0;
+}
+
+/* dequeue request */
+static int cyasgadget_dequeue(
+ struct usb_ep *_ep,
+ struct usb_request *_req
+ )
+{
+ cyasgadget_ep *an_ep;
+ cyasgadget *dev;
+ an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+ dev = an_ep->dev ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ cy_as_usb_cancel_async(dev->dev_handle, an_ep->num);
+
+ return 0;
+}
+
+static int cyasgadget_set_halt(
+ struct usb_ep *_ep,
+ int value
+ )
+{
+ cyasgadget_ep *an_ep;
+ int retval = 0;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst);
+ if (!_ep || (!an_ep->desc && an_ep->num != 0))
+ return -EINVAL;
+
+ if (!an_ep->dev->driver || an_ep->dev->gadget.speed ==
+ USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+ if (an_ep->desc /* not ep0 */ &&
+ (an_ep->desc->bmAttributes & 0x03) == USB_ENDPOINT_XFER_ISOC)
+ return -EINVAL;
+
+ if (!list_empty(&an_ep->queue))
+ retval = -EAGAIN;
+ else if (an_ep->is_in && value &&
+ cyasgadget_fifo_status(_ep) != 0)
+ retval = -EAGAIN;
+ else {
+ if (value) {
+ cy_as_usb_set_stall(an_ep->dev->dev_handle,
+ an_ep->num, cyasgadget_stallcallback, 0) ;
+ } else {
+ cy_as_usb_clear_stall(an_ep->dev->dev_handle,
+ an_ep->num, cyasgadget_stallcallback, 0) ;
+ }
+ }
+
+ return retval;
+}
+
+static int cyasgadget_fifo_status(
+ struct usb_ep *_ep
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ return 0 ;
+}
+
+static void cyasgadget_fifo_flush(
+ struct usb_ep *_ep
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+}
+
+static struct usb_ep_ops cyasgadget_ep_ops = {
+ .enable = cyasgadget_enable,
+ .disable = cyasgadget_disable,
+ .alloc_request = cyasgadget_alloc_request,
+ .free_request = cyasgadget_free_request,
+ .queue = cyasgadget_queue,
+ .dequeue = cyasgadget_dequeue,
+ .set_halt = cyasgadget_set_halt,
+ .fifo_status = cyasgadget_fifo_status,
+ .fifo_flush = cyasgadget_fifo_flush,
+};
+
+/*************************************************************/
+/*This subsection contains all usb_gadget_ops cyasgadget_ops */
+/*************************************************************/
+static int cyasgadget_get_frame(
+ struct usb_gadget *_gadget
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+ return 0 ;
+}
+
+static int cyasgadget_wakeup(
+ struct usb_gadget *_gadget
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+ return 0;
+}
+
+static int cyasgadget_set_selfpowered(
+ struct usb_gadget *_gadget,
+ int value
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+ return 0;
+}
+
+static int cyasgadget_pullup(
+ struct usb_gadget *_gadget,
+ int is_on
+ )
+{
+ struct cyasgadget *cy_as_dev ;
+ unsigned long flags;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ if (!_gadget)
+ return -ENODEV;
+
+ cy_as_dev = container_of(_gadget, cyasgadget, gadget);
+
+ spin_lock_irqsave(&cy_as_dev->lock, flags);
+ cy_as_dev->softconnect = (is_on != 0);
+ if (is_on)
+ cy_as_usb_connect(cy_as_dev->dev_handle, 0, 0) ;
+ else
+ cy_as_usb_disconnect(cy_as_dev->dev_handle, 0, 0) ;
+
+ spin_unlock_irqrestore(&cy_as_dev->lock, flags);
+
+ return 0;
+}
+
+static int cyasgadget_ioctl(
+ struct usb_gadget *_gadget,
+ unsigned code,
+ unsigned long param
+ )
+{
+ int err = 0;
+ int retval = 0;
+ int ret_stat = 0;
+ cyasgadget *dev = cy_as_gadget_controller ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called, code=%d, param=%ld\n",
+ __func__, code, param);
+ #endif
+ /*
+ * extract the type and number bitfields, and don't decode
+ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ */
+ if (_IOC_TYPE(code) != CYASGADGET_IOC_MAGIC) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s, bad magic number = 0x%x\n",
+ __func__, _IOC_TYPE(code));
+ #endif
+ return -ENOTTY;
+ }
+
+ if (_IOC_NR(code) > CYASGADGET_IOC_MAXNR) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s, bad ioctl code = 0x%x\n",
+ __func__, _IOC_NR(code));
+ #endif
+ return -ENOTTY;
+ }
+
+ /*
+ * the direction is a bitmask, and VERIFY_WRITE catches R/W
+ * transfers. `Type' is user-oriented, while
+ * access_ok is kernel-oriented, so the concept of "read" and
+ * "write" is reversed
+ */
+ if (_IOC_DIR(code) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE,
+ (void __user *)param, _IOC_SIZE(code));
+ else if (_IOC_DIR(code) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ,
+ (void __user *)param, _IOC_SIZE(code));
+
+ if (err) {
+ cy_as_hal_print_message("%s, bad ioctl dir = 0x%x\n",
+ __func__, _IOC_DIR(code));
+ return -EFAULT;
+ }
+
+ switch (code) {
+ case CYASGADGET_GETMTPSTATUS:
+ {
+ cy_as_gadget_ioctl_tmtp_status *usr_d =
+ (cy_as_gadget_ioctl_tmtp_status *)param ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: got CYASGADGET_GETMTPSTATUS\n",
+ __func__);
+ #endif
+
+ retval = __put_user(dev->tmtp_send_complete,
+ (uint32_t __user *)(&(usr_d->tmtp_send_complete)));
+ retval = __put_user(dev->tmtp_get_complete,
+ (uint32_t __user *)(&(usr_d->tmtp_get_complete)));
+ retval = __put_user(dev->tmtp_need_new_blk_tbl,
+ (uint32_t __user *)(&(usr_d->tmtp_need_new_blk_tbl)));
+
+ if (copy_to_user((&(usr_d->tmtp_send_complete_data)),
+ (&(dev->tmtp_send_complete_data)),
+ sizeof(cy_as_gadget_ioctl_send_object)))
+ return -EFAULT;
+
+ if (copy_to_user((&(usr_d->tmtp_get_complete_data)),
+ (&(dev->tmtp_get_complete_data)),
+ sizeof(cy_as_gadget_ioctl_get_object)))
+ return -EFAULT;
+ break;
+ }
+ case CYASGADGET_CLEARTMTPSTATUS:
+ {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s got CYASGADGET_CLEARTMTPSTATUS\n",
+ __func__);
+ #endif
+
+ dev->tmtp_send_complete = 0 ;
+ dev->tmtp_get_complete = 0 ;
+ dev->tmtp_need_new_blk_tbl = 0 ;
+
+ break;
+ }
+ case CYASGADGET_INITSOJ:
+ {
+ cy_as_gadget_ioctl_i_s_o_j_d k_d ;
+ cy_as_gadget_ioctl_i_s_o_j_d *usr_d =
+ (cy_as_gadget_ioctl_i_s_o_j_d *)param ;
+ cy_as_mtp_block_table blk_table ;
+ struct scatterlist sg ;
+ char *alloc_filename;
+ struct file *file_to_allocate;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s got CYASGADGET_INITSOJ\n",
+ __func__);
+ #endif
+
+ memset(&blk_table, 0, sizeof(blk_table));
+
+ /* Get user argument structure */
+ if (copy_from_user(&k_d, usr_d,
+ sizeof(cy_as_gadget_ioctl_i_s_o_j_d)))
+ return -EFAULT;
+
+ /* better use fixed size buff*/
+ alloc_filename = kmalloc(k_d.name_length + 1, GFP_KERNEL);
+ if (alloc_filename == NULL)
+ return -ENOMEM;
+
+ /* get the filename */
+ if (copy_from_user(alloc_filename, k_d.file_name,
+ k_d.name_length + 1)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: CYASGADGET_INITSOJ, "
+ "copy file name from user space failed\n",
+ __func__);
+ #endif
+ kfree(alloc_filename);
+ return -EFAULT;
+ }
+
+ file_to_allocate = filp_open(alloc_filename, O_RDWR, 0);
+
+ if (!IS_ERR(file_to_allocate)) {
+
+ struct address_space *mapping =
+ file_to_allocate->f_mapping;
+ const struct address_space_operations *a_ops =
+ mapping->a_ops;
+ struct inode *inode = mapping->host;
+ struct inode *alloc_inode =
+ file_to_allocate->f_path.dentry->d_inode;
+ uint32_t num_clusters = 0;
+ struct buffer_head bh;
+ struct kstat stat;
+ int nr_pages = 0;
+ int ret_stat = 0;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: fhandle is OK, "
+ "calling vfs_getattr\n", __func__);
+ #endif
+
+ ret_stat = vfs_getattr(file_to_allocate->f_path.mnt,
+ file_to_allocate->f_path.dentry, &stat);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: returned from "
+ "vfs_getattr() stat->blksize=0x%lx\n",
+ __func__, stat.blksize);
+ #endif
+
+ /* TODO: get this from disk properties
+ * (from blockdevice)*/
+ #define SECTOR_SIZE 512
+ if (stat.blksize != 0) {
+ num_clusters = (k_d.num_bytes) / SECTOR_SIZE;
+
+ if (((k_d.num_bytes) % SECTOR_SIZE) != 0)
+ num_clusters++;
+ } else {
+ goto initsoj_safe_exit;
+ }
+
+ bh.b_state = 0;
+ bh.b_blocknr = 0;
+ /* block size is arbitrary , we'll use sector size*/
+ bh.b_size = SECTOR_SIZE ;
+
+
+
+ /* clear dirty pages in page cache
+ * (if were any allocated) */
+ nr_pages = (k_d.num_bytes) / (PAGE_CACHE_SIZE);
+
+ if (((k_d.num_bytes) % (PAGE_CACHE_SIZE)) != 0)
+ nr_pages++;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ /*check out how many pages where actually allocated */
+ if (mapping->nrpages != nr_pages)
+ cy_as_hal_print_message("%s mpage_cleardirty "
+ "mapping->nrpages %d != num_pages %d\n",
+ __func__, (int) mapping->nrpages,
+ nr_pages);
+
+ cy_as_hal_print_message("%s: calling "
+ "mpage_cleardirty() "
+ "for %d pages\n", __func__, nr_pages);
+ #endif
+
+ ret_stat = mpage_cleardirty(mapping, nr_pages);
+
+ /*fill up the the block table from the addr mapping */
+ if (a_ops->bmap) {
+ int8_t blk_table_idx = -1;
+ uint32_t file_block_idx = 0;
+ uint32_t last_blk_addr_map = 0,
+ curr_blk_addr_map = 0;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ if (alloc_inode->i_bytes == 0)
+ cy_as_hal_print_message(
+ "%s: alloc_inode->ibytes =0\n",
+ __func__);
+ #endif
+
+ /* iterate through the list of
+ * blocks (not clusters)*/
+ for (file_block_idx = 0;
+ file_block_idx < num_clusters
+ /*inode->i_bytes*/; file_block_idx++) {
+
+ /* returns starting sector number */
+ curr_blk_addr_map =
+ a_ops->bmap(mapping,
+ file_block_idx);
+
+ /*no valid mapping*/
+ if (curr_blk_addr_map == 0) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s:hit invalid "
+ "mapping\n", __func__);
+ #endif
+ break;
+ } else if (curr_blk_addr_map !=
+ (last_blk_addr_map + 1) ||
+ (blk_table.num_blocks
+ [blk_table_idx] == 65535)) {
+
+ /* next table entry */
+ blk_table_idx++;
+ /* starting sector of a
+ * scattered cluster*/
+ blk_table.start_blocks
+ [blk_table_idx] =
+ curr_blk_addr_map;
+ /* ++ num of blocks in cur
+ * table entry*/
+ blk_table.
+ num_blocks[blk_table_idx]++;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ if (file_block_idx != 0)
+ cy_as_hal_print_message(
+ "<*> next table "
+ "entry:%d required\n",
+ blk_table_idx);
+ #endif
+ } else {
+ /*add contiguous block*/
+ blk_table.num_blocks
+ [blk_table_idx]++;
+ } /*if (curr_blk_addr_map == 0)*/
+
+ last_blk_addr_map = curr_blk_addr_map;
+ } /* end for (file_block_idx = 0; file_block_idx
+ < inode->i_bytes;) */
+
+ #ifndef WESTBRIDGE_NDEBUG
+ /*print result for verification*/
+ {
+ int i;
+ cy_as_hal_print_message(
+ "%s: print block table "
+ "mapping:\n",
+ __func__);
+ for (i = 0; i <= blk_table_idx; i++) {
+ cy_as_hal_print_message(
+ "<1> %d 0x%x 0x%x\n", i,
+ blk_table.start_blocks[i],
+ blk_table.num_blocks[i]);
+ }
+ }
+ #endif
+
+ /* copy the block table to user
+ * space (for debug purposes) */
+ retval = __put_user(
+ blk_table.start_blocks[blk_table_idx],
+ (uint32_t __user *)
+ (&(usr_d->blk_addr_p)));
+
+ retval = __put_user(
+ blk_table.num_blocks[blk_table_idx],
+ (uint32_t __user *)
+ (&(usr_d->blk_count_p)));
+
+ blk_table_idx++;
+ retval = __put_user(blk_table_idx,
+ (uint32_t __user *)
+ (&(usr_d->item_count)));
+
+ } /*end if (a_ops->bmap)*/
+
+ filp_close(file_to_allocate, NULL);
+
+ dev->tmtp_send_complete = 0 ;
+ dev->tmtp_need_new_blk_tbl = 0 ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: calling cy_as_mtp_init_send_object()\n",
+ __func__);
+ #endif
+ sg_init_one(&sg, &blk_table, sizeof(blk_table));
+ ret_stat = cy_as_mtp_init_send_object(dev->dev_handle,
+ (cy_as_mtp_block_table *)&sg,
+ k_d.num_bytes, 0, 0);
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: returned from "
+ "cy_as_mtp_init_send_object()\n", __func__);
+ #endif
+
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message(
+ "%s: failed to allocate the file %s\n",
+ __func__, alloc_filename);
+ } /* end if (file_to_allocate)*/
+ #endif
+ kfree(alloc_filename);
+initsoj_safe_exit:
+ ret_stat = 0;
+ retval = __put_user(ret_stat,
+ (uint32_t __user *)(&(usr_d->ret_val)));
+
+ break;
+ }
+ case CYASGADGET_INITGOJ:
+ {
+ cy_as_gadget_ioctl_i_g_o_j_d k_d ;
+ cy_as_gadget_ioctl_i_g_o_j_d *usr_d =
+ (cy_as_gadget_ioctl_i_g_o_j_d *)param ;
+ cy_as_mtp_block_table blk_table ;
+ struct scatterlist sg ;
+ char *map_filename;
+ struct file *file_to_map;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: got CYASGADGET_INITGOJ\n",
+ __func__);
+ #endif
+
+ memset(&blk_table, 0, sizeof(blk_table));
+
+ /* Get user argument sturcutre */
+ if (copy_from_user(&k_d, usr_d,
+ sizeof(cy_as_gadget_ioctl_i_g_o_j_d)))
+ return -EFAULT;
+
+ map_filename = kmalloc(k_d.name_length + 1, GFP_KERNEL);
+ if (map_filename == NULL)
+ return -ENOMEM;
+ if (copy_from_user(map_filename, k_d.file_name,
+ k_d.name_length + 1)) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: copy file name from "
+ "user space failed\n", __func__);
+ #endif
+ kfree(map_filename);
+ return -EFAULT;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<*>%s: opening %s for kernel "
+ "mode access map\n", __func__, map_filename);
+ #endif
+ file_to_map = filp_open(map_filename, O_RDWR, 0);
+ if (file_to_map) {
+ struct address_space *mapping = file_to_map->f_mapping;
+ const struct address_space_operations
+ *a_ops = mapping->a_ops;
+ struct inode *inode = mapping->host;
+
+ int8_t blk_table_idx = -1;
+ uint32_t file_block_idx = 0;
+ uint32_t last_blk_addr_map = 0, curr_blk_addr_map = 0;
+
+ /*verify operation exists*/
+ if (a_ops->bmap) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<*>%s: bmap found, i_bytes=0x%x, "
+ "i_size=0x%x, i_blocks=0x%x\n",
+ __func__, inode->i_bytes,
+ (unsigned int) inode->i_size,
+ (unsigned int) inode->i_blocks);
+ #endif
+
+ k_d.num_bytes = inode->i_size;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "<*>%s: k_d.num_bytes=0x%x\n",
+ __func__, k_d.num_bytes);
+ #endif
+
+ for (file_block_idx = 0;
+ file_block_idx < inode->i_size;
+ file_block_idx++) {
+ curr_blk_addr_map =
+ a_ops->bmap(mapping,
+ file_block_idx);
+
+ if (curr_blk_addr_map == 0) {
+ /*no valid mapping*/
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: no valid "
+ "mapping\n", __func__);
+ #endif
+ break;
+ } else if (curr_blk_addr_map !=
+ (last_blk_addr_map + 1)) {
+ /*non-contiguous break*/
+ blk_table_idx++;
+ blk_table.start_blocks
+ [blk_table_idx] =
+ curr_blk_addr_map;
+ blk_table.num_blocks
+ [blk_table_idx]++;
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: found non-"
+ "contiguous break",
+ __func__);
+ #endif
+ } else {
+ /*add contiguous block*/
+ blk_table.num_blocks
+ [blk_table_idx]++;
+ }
+ last_blk_addr_map = curr_blk_addr_map;
+ }
+
+ /*print result for verification*/
+ #ifndef WESTBRIDGE_NDEBUG
+ {
+ int i = 0;
+
+ for (i = 0 ; i <= blk_table_idx; i++) {
+ cy_as_hal_print_message(
+ "%s %d 0x%x 0x%x\n",
+ __func__, i,
+ blk_table.start_blocks[i],
+ blk_table.num_blocks[i]);
+ }
+ }
+ #endif
+ } else {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: could not find "
+ "a_ops->bmap\n", __func__);
+ #endif
+ return -EFAULT;
+ }
+
+ filp_close(file_to_map, NULL);
+
+ dev->tmtp_get_complete = 0 ;
+ dev->tmtp_need_new_blk_tbl = 0 ;
+
+ ret_stat = __put_user(
+ blk_table.start_blocks[blk_table_idx],
+ (uint32_t __user *)(&(usr_d->blk_addr_p)));
+
+ ret_stat = __put_user(
+ blk_table.num_blocks[blk_table_idx],
+ (uint32_t __user *)(&(usr_d->blk_count_p)));
+
+ sg_init_one(&sg, &blk_table, sizeof(blk_table));
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: calling cy_as_mtp_init_get_object() "
+ "start=0x%x, num =0x%x, tid=0x%x, "
+ "num_bytes=0x%x\n",
+ __func__,
+ blk_table.start_blocks[0],
+ blk_table.num_blocks[0],
+ k_d.tid,
+ k_d.num_bytes);
+ #endif
+
+ ret_stat = cy_as_mtp_init_get_object(
+ dev->dev_handle,
+ (cy_as_mtp_block_table *)&sg,
+ k_d.num_bytes, k_d.tid, 0, 0);
+ if (ret_stat != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: cy_as_mtp_init_get_object "
+ "failed ret_stat=0x%x\n",
+ __func__, ret_stat);
+ #endif
+ }
+ }
+ #ifndef WESTBRIDGE_NDEBUG
+ else {
+ cy_as_hal_print_message(
+ "%s: failed to open file %s\n",
+ __func__, map_filename);
+ }
+ #endif
+ kfree(map_filename);
+
+ ret_stat = 0;
+ retval = __put_user(ret_stat, (uint32_t __user *)
+ (&(usr_d->ret_val)));
+ break;
+ }
+ case CYASGADGET_CANCELSOJ:
+ {
+ cy_as_gadget_ioctl_cancel *usr_d =
+ (cy_as_gadget_ioctl_cancel *)param ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message(
+ "%s: got CYASGADGET_CANCELSOJ\n",
+ __func__);
+ #endif
+
+ ret_stat = cy_as_mtp_cancel_send_object(dev->dev_handle, 0, 0);
+
+ retval = __put_user(ret_stat, (uint32_t __user *)
+ (&(usr_d->ret_val)));
+ break;
+ }
+ case CYASGADGET_CANCELGOJ:
+ {
+ cy_as_gadget_ioctl_cancel *usr_d =
+ (cy_as_gadget_ioctl_cancel *)param ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: got CYASGADGET_CANCELGOJ\n",
+ __func__);
+ #endif
+
+ ret_stat = cy_as_mtp_cancel_get_object(dev->dev_handle, 0, 0);
+
+ retval = __put_user(ret_stat,
+ (uint32_t __user *)(&(usr_d->ret_val)));
+ break;
+ }
+ default:
+ {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: unknown ioctl received: %d\n",
+ __func__, code);
+
+ cy_as_hal_print_message("%s: known codes:\n"
+ "CYASGADGET_GETMTPSTATUS=%d\n"
+ "CYASGADGET_CLEARTMTPSTATUS=%d\n"
+ "CYASGADGET_INITSOJ=%d\n"
+ "CYASGADGET_INITGOJ=%d\n"
+ "CYASGADGET_CANCELSOJ=%d\n"
+ "CYASGADGET_CANCELGOJ=%d\n",
+ __func__,
+ CYASGADGET_GETMTPSTATUS,
+ CYASGADGET_CLEARTMTPSTATUS,
+ CYASGADGET_INITSOJ,
+ CYASGADGET_INITGOJ,
+ CYASGADGET_CANCELSOJ,
+ CYASGADGET_CANCELGOJ);
+ #endif
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static const struct usb_gadget_ops cyasgadget_ops = {
+ .get_frame = cyasgadget_get_frame,
+ .wakeup = cyasgadget_wakeup,
+ .set_selfpowered = cyasgadget_set_selfpowered,
+ .pullup = cyasgadget_pullup,
+ .ioctl = cyasgadget_ioctl,
+};
+
+
+/* keeping it simple:
+ * - one bus driver, initted first;
+ * - one function driver, initted second
+ *
+ * most of the work to support multiple controllers would
+ * be to associate this gadget driver with all of them, or
+ * perhaps to bind specific drivers to specific devices.
+ */
+
+static void cyas_ep_reset(
+ cyasgadget_ep *an_ep
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ an_ep->desc = NULL;
+ INIT_LIST_HEAD(&an_ep->queue);
+
+ an_ep->stopped = 0 ;
+ an_ep->is_in = 0 ;
+ an_ep->is_iso = 0 ;
+ an_ep->usb_ep_inst.maxpacket = ~0;
+ an_ep->usb_ep_inst.ops = &cyasgadget_ep_ops;
+}
+
+static void cyas_usb_reset(
+ cyasgadget *cy_as_dev
+ )
+{
+ cy_as_return_status_t ret;
+ cy_as_usb_enum_control config ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_device *dev_p = (cy_as_device *)cy_as_dev->dev_handle ;
+
+ cy_as_hal_print_message("<1>%s called mtp_firmware=0x%x\n",
+ __func__, dev_p->is_mtp_firmware);
+ #endif
+
+ ret = cy_as_misc_release_resource(cy_as_dev->dev_handle,
+ cy_as_bus_u_s_b) ;
+ if (ret != CY_AS_ERROR_SUCCESS && ret !=
+ CY_AS_ERROR_RESOURCE_NOT_OWNED) {
+ cy_as_hal_print_message("<1>_cy_as_gadget: cannot "
+ "release usb resource: failed with error code %d\n",
+ ret) ;
+ return ;
+ }
+
+ cy_as_dev->gadget.speed = USB_SPEED_HIGH ;
+
+ ret = cy_as_usb_start(cy_as_dev->dev_handle, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_start failed with error code %d\n",
+ ret) ;
+ return ;
+ }
+ /* P port will do enumeration, not West Bridge */
+ config.antioch_enumeration = cy_false ;
+ /* 1 2 : 1-BUS_NUM , 2:Storage_device number, SD - is bus 1*/
+
+ /* TODO: add module param to enumerate mass storage */
+ config.mass_storage_interface = 0 ;
+
+ if (append_mtp) {
+ ret = cy_as_mtp_start(cy_as_dev->dev_handle,
+ cy_as_gadget_mtp_event_callback, 0, 0);
+ if (ret == CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("MTP start passed, enumerating "
+ "MTP interface\n");
+ config.mtp_interface = append_mtp ;
+ /*Do not enumerate NAND storage*/
+ config.devices_to_enumerate[0][0] = cy_false;
+
+ /*enumerate SD storage as MTP*/
+ config.devices_to_enumerate[1][0] = cy_true;
+ }
+ } else {
+ cy_as_hal_print_message("MTP start not attempted, not "
+ "enumerating MTP interface\n");
+ config.mtp_interface = 0 ;
+ /* enumerate mass storage based on module parameters */
+ config.devices_to_enumerate[0][0] = msc_enum_bus_0;
+ config.devices_to_enumerate[1][0] = msc_enum_bus_1;
+ }
+
+ ret = cy_as_usb_set_enum_config(cy_as_dev->dev_handle,
+ &config, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_gadget: "
+ "cy_as_usb_set_enum_config failed with error "
+ "code %d\n", ret) ;
+ return ;
+ }
+
+ cy_as_usb_set_physical_configuration(cy_as_dev->dev_handle, 1);
+
+}
+
+static void cyas_usb_reinit(
+ cyasgadget *cy_as_dev
+ )
+{
+ int index = 0;
+ cyasgadget_ep *an_ep_p;
+ cy_as_return_status_t ret;
+ cy_as_device *dev_p = (cy_as_device *)cy_as_dev->dev_handle ;
+
+ INIT_LIST_HEAD(&cy_as_dev->gadget.ep_list);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called, is_mtp_firmware = "
+ "0x%x\n", __func__, dev_p->is_mtp_firmware);
+ #endif
+
+ /* Init the end points */
+ for (index = 1; index <= 15; index++) {
+ an_ep_p = &cy_as_dev->an_gadget_ep[index] ;
+ cyas_ep_reset(an_ep_p) ;
+ an_ep_p->usb_ep_inst.name = cy_as_ep_names[index] ;
+ an_ep_p->dev = cy_as_dev ;
+ an_ep_p->num = index ;
+ memset(&an_ep_p->cyepconfig, 0, sizeof(an_ep_p->cyepconfig));
+
+ /* EP0, EPs 2,4,6,8 need not be added */
+ if ((index <= 8) && (index % 2 == 0) &&
+ (!dev_p->is_mtp_firmware)) {
+ /* EP0 is 64 and EPs 2,4,6,8 not allowed */
+ cy_as_dev->an_gadget_ep[index].fifo_size = 0 ;
+ } else {
+ if (index == 1)
+ an_ep_p->fifo_size = 64;
+ else
+ an_ep_p->fifo_size = 512 ;
+ list_add_tail(&an_ep_p->usb_ep_inst.ep_list,
+ &cy_as_dev->gadget.ep_list);
+ }
+ }
+ /* need to setendpointconfig before usb connect, this is not
+ * quite compatible with gadget methodology (ep_enable called
+ * by gadget after connect), therefore need to set config in
+ * initialization and verify compatibility in ep_enable,
+ * kick up error otherwise*/
+ an_ep_p = &cy_as_dev->an_gadget_ep[3] ;
+ an_ep_p->cyepconfig.enabled = cy_true ;
+ an_ep_p->cyepconfig.dir = cy_as_usb_out ;
+ an_ep_p->cyepconfig.type = cy_as_usb_bulk ;
+ an_ep_p->cyepconfig.size = 0 ;
+ an_ep_p->cyepconfig.physical = 1 ;
+ ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle,
+ 3, &an_ep_p->cyepconfig) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("cy_as_usb_set_end_point_config "
+ "failed with error code %d\n", ret) ;
+ }
+
+ cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 3, 0, 0);
+
+ an_ep_p = &cy_as_dev->an_gadget_ep[5] ;
+ an_ep_p->cyepconfig.enabled = cy_true ;
+ an_ep_p->cyepconfig.dir = cy_as_usb_in ;
+ an_ep_p->cyepconfig.type = cy_as_usb_bulk ;
+ an_ep_p->cyepconfig.size = 0 ;
+ an_ep_p->cyepconfig.physical = 2 ;
+ ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle,
+ 5, &an_ep_p->cyepconfig) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("cy_as_usb_set_end_point_config "
+ "failed with error code %d\n", ret) ;
+ }
+
+ cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 5, 0, 0);
+
+ an_ep_p = &cy_as_dev->an_gadget_ep[9] ;
+ an_ep_p->cyepconfig.enabled = cy_true ;
+ an_ep_p->cyepconfig.dir = cy_as_usb_in ;
+ an_ep_p->cyepconfig.type = cy_as_usb_bulk ;
+ an_ep_p->cyepconfig.size = 0 ;
+ an_ep_p->cyepconfig.physical = 4 ;
+ ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle,
+ 9, &an_ep_p->cyepconfig) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("cy_as_usb_set_end_point_config "
+ "failed with error code %d\n", ret) ;
+ }
+
+ cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 9, 0, 0);
+
+ if (dev_p->mtp_count != 0) {
+ /* these need to be set for compatibility with
+ * the gadget_enable logic */
+ an_ep_p = &cy_as_dev->an_gadget_ep[2] ;
+ an_ep_p->cyepconfig.enabled = cy_true ;
+ an_ep_p->cyepconfig.dir = cy_as_usb_out ;
+ an_ep_p->cyepconfig.type = cy_as_usb_bulk ;
+ an_ep_p->cyepconfig.size = 0 ;
+ an_ep_p->cyepconfig.physical = 0 ;
+ cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 2, 0, 0);
+
+ an_ep_p = &cy_as_dev->an_gadget_ep[6] ;
+ an_ep_p->cyepconfig.enabled = cy_true ;
+ an_ep_p->cyepconfig.dir = cy_as_usb_in ;
+ an_ep_p->cyepconfig.type = cy_as_usb_bulk ;
+ an_ep_p->cyepconfig.size = 0 ;
+ an_ep_p->cyepconfig.physical = 0 ;
+ cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 6, 0, 0);
+ }
+
+ cyas_ep_reset(&cy_as_dev->an_gadget_ep[0]) ;
+ cy_as_dev->an_gadget_ep[0].usb_ep_inst.name = cy_as_ep_names[0] ;
+ cy_as_dev->an_gadget_ep[0].dev = cy_as_dev ;
+ cy_as_dev->an_gadget_ep[0].num = 0 ;
+ cy_as_dev->an_gadget_ep[0].fifo_size = 64 ;
+
+ cy_as_dev->an_gadget_ep[0].usb_ep_inst.maxpacket = 64;
+ cy_as_dev->gadget.ep0 = &cy_as_dev->an_gadget_ep[0].usb_ep_inst;
+ cy_as_dev->an_gadget_ep[0].stopped = 0;
+ INIT_LIST_HEAD(&cy_as_dev->gadget.ep0->ep_list);
+}
+
+static void cyas_ep0_start(
+ cyasgadget *dev
+ )
+{
+ cy_as_return_status_t ret ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ ret = cy_as_usb_register_callback(dev->dev_handle,
+ cy_as_gadget_usb_event_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_usb_register_callback "
+ "failed with error code %d\n", __func__, ret) ;
+ #endif
+ return ;
+ }
+
+ ret = cy_as_usb_commit_config(dev->dev_handle, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_usb_commit_config "
+ "failed with error code %d\n", __func__, ret) ;
+ #endif
+ return ;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_usb_commit_config "
+ "message sent\n", __func__) ;
+ #endif
+
+ ret = cy_as_usb_connect(dev->dev_handle, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_usb_connect failed "
+ "with error code %d\n", __func__, ret) ;
+ #endif
+ return ;
+ }
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s: cy_as_usb_connect message "
+ "sent\n", __func__) ;
+ #endif
+}
+
+/*
+ * When a driver is successfully registered, it will receive
+ * control requests including set_configuration(), which enables
+ * non-control requests. then usb traffic follows until a
+ * disconnect is reported. then a host may connect again, or
+ * the driver might get unbound.
+ */
+int usb_gadget_register_driver(
+ struct usb_gadget_driver *driver
+ )
+{
+ cyasgadget *dev = cy_as_gadget_controller ;
+ int retval;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called driver=0x%x\n",
+ __func__, (unsigned int) driver);
+ #endif
+
+ /* insist on high speed support from the driver, since
+ * "must not be used in normal operation"
+ */
+ if (!driver
+ || !driver->bind
+ || !driver->unbind
+ || !driver->setup)
+ return -EINVAL;
+
+ if (!dev)
+ return -ENODEV;
+
+ if (dev->driver)
+ return -EBUSY;
+
+ /* hook up the driver ... */
+ dev->softconnect = 1;
+ driver->driver.bus = NULL;
+ dev->driver = driver;
+ dev->gadget.dev.driver = &driver->driver;
+
+ /* Do the needful */
+ cyas_usb_reset(dev) ; /* External usb */
+ cyas_usb_reinit(dev) ; /* Internal */
+
+ retval = driver->bind(&dev->gadget);
+ if (retval) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("%s bind to driver %s --> %d\n",
+ __func__, driver->driver.name, retval);
+ #endif
+
+ dev->driver = NULL;
+ dev->gadget.dev.driver = NULL;
+ return retval;
+ }
+
+ /* ... then enable host detection and ep0; and we're ready
+ * for set_configuration as well as eventual disconnect.
+ */
+ cyas_ep0_start(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+static void cyasgadget_nuke(
+ cyasgadget_ep *an_ep
+ )
+{
+ cyasgadget *dev = cy_as_gadget_controller ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ cy_as_usb_cancel_async(dev->dev_handle, an_ep->num);
+ an_ep->stopped = 1 ;
+
+ while (!list_empty(&an_ep->queue)) {
+ cyasgadget_req *an_req = list_entry
+ (an_ep->queue.next, cyasgadget_req, queue) ;
+ list_del_init(&an_req->queue) ;
+ an_req->req.status = -ESHUTDOWN ;
+ an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req) ;
+ }
+}
+
+static void cyasgadget_stop_activity(
+ cyasgadget *dev,
+ struct usb_gadget_driver *driver
+ )
+{
+ int index ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ /* don't disconnect if it's not connected */
+ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
+ driver = NULL;
+
+ if (spin_is_locked(&dev->lock))
+ spin_unlock(&dev->lock);
+
+ /* Stop hardware; prevent new request submissions;
+ * and kill any outstanding requests.
+ */
+ cy_as_usb_disconnect(dev->dev_handle, 0, 0) ;
+
+ for (index = 3; index <= 7; index += 2) {
+ cyasgadget_ep *an_ep_p = &dev->an_gadget_ep[index] ;
+ cyasgadget_nuke(an_ep_p) ;
+ }
+
+ for (index = 9; index <= 15; index++) {
+ cyasgadget_ep *an_ep_p = &dev->an_gadget_ep[index] ;
+ cyasgadget_nuke(an_ep_p) ;
+ }
+
+ /* report disconnect; the driver is already quiesced */
+ if (driver)
+ driver->disconnect(&dev->gadget);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("cy_as_usb_disconnect returned success");
+ #endif
+
+ /* Stop Usb */
+ cy_as_usb_stop(dev->dev_handle, 0, 0) ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("cy_as_usb_stop returned success");
+ #endif
+}
+
+int usb_gadget_unregister_driver(
+ struct usb_gadget_driver *driver
+ )
+{
+ cyasgadget *dev = cy_as_gadget_controller ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ if (!dev)
+ return -ENODEV;
+
+ if (!driver || driver != dev->driver)
+ return -EINVAL;
+
+ cyasgadget_stop_activity(dev, driver);
+
+ driver->unbind(&dev->gadget);
+ dev->gadget.dev.driver = NULL;
+ dev->driver = NULL;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("unregistered driver '%s'\n",
+ driver->driver.name) ;
+ #endif
+
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+static void cyas_gadget_release(
+ struct device *_dev
+ )
+{
+ cyasgadget *dev = dev_get_drvdata(_dev);
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>%s called\n", __func__);
+ #endif
+
+ kfree(dev);
+}
+
+/* DeInitialize gadget driver */
+static void cyasgadget_deinit(
+ cyasgadget *cy_as_dev
+ )
+{
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget deinitialize called\n") ;
+ #endif
+
+ if (!cy_as_dev) {
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget_deinit: "
+ "invalid cyasgadget device\n") ;
+ #endif
+ return ;
+ }
+
+ if (cy_as_dev->driver) {
+ /* should have been done already by driver model core */
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1> cy_as_gadget: '%s' "
+ "is still registered\n",
+ cy_as_dev->driver->driver.name);
+ #endif
+ usb_gadget_unregister_driver(cy_as_dev->driver);
+ }
+
+ kfree(cy_as_dev) ;
+ cy_as_gadget_controller = NULL ;
+}
+
+/* Initialize gadget driver */
+static int cyasgadget_initialize(void)
+{
+ cyasgadget *cy_as_dev = 0 ;
+ int retval = 0 ;
+
+ #ifndef WESTBRIDGE_NDEBUG
+ cy_as_hal_print_message("<1>_cy_as_gadget [V1.1] initialize called\n") ;
+ #endif
+
+ if (cy_as_gadget_controller != 0) {
+ cy_as_hal_print_message("<1> cy_as_gadget: the device has "
+ "already been initilaized. ignoring\n") ;
+ return -EBUSY ;
+ }
+
+ cy_as_dev = kzalloc(sizeof(cyasgadget), GFP_ATOMIC);
+ if (cy_as_dev == NULL) {
+ cy_as_hal_print_message("<1> cy_as_gadget: memory "
+ "allocation failed\n") ;
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&cy_as_dev->lock);
+ cy_as_dev->gadget.ops = &cyasgadget_ops;
+ cy_as_dev->gadget.is_dualspeed = 1;
+
+ /* the "gadget" abstracts/virtualizes the controller */
+ /*strcpy(cy_as_dev->gadget.dev.bus_id, "cyasgadget");*/
+ cy_as_dev->gadget.dev.release = cyas_gadget_release;
+ cy_as_dev->gadget.name = cy_as_driver_name;
+
+ /* Get the device handle */
+ cy_as_dev->dev_handle = cyasdevice_getdevhandle() ;
+ if (0 == cy_as_dev->dev_handle) {
+ #ifndef NDEBUG
+ cy_as_hal_print_message("<1> cy_as_gadget: "
+ "no west bridge device\n") ;
+ #endif
+ retval = -EFAULT ;
+ goto done ;
+ }
+
+ /* We are done now */
+ cy_as_gadget_controller = cy_as_dev ;
+ return 0 ;
+
+/*
+ * in case of an error
+ */
+done:
+ if (cy_as_dev)
+ cyasgadget_deinit(cy_as_dev) ;
+
+ return retval ;
+}
+
+static int __init cyas_init(void)
+{
+ int init_res = 0;
+
+ init_res = cyasgadget_initialize();
+
+ if (init_res != 0) {
+ printk(KERN_WARNING "<1> gadget ctl instance "
+ "init error:%d\n", init_res);
+ if (init_res > 0) {
+ /* force -E/0 linux convention */
+ init_res = init_res * -1;
+ }
+ }
+
+ return init_res;
+}
+module_init(cyas_init);
+
+static void __exit cyas_cleanup(void)
+{
+ if (cy_as_gadget_controller != NULL)
+ cyasgadget_deinit(cy_as_gadget_controller);
+}
+module_exit(cyas_cleanup);
+
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(CY_AS_DRIVER_DESC);
+MODULE_AUTHOR("cypress semiconductor");
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget.h b/drivers/staging/westbridge/astoria/gadget/cyasgadget.h
new file mode 100644
index 000000000000..d7b72d2720be
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/gadget/cyasgadget.h
@@ -0,0 +1,193 @@
+/* cyangadget.h - Linux USB Gadget driver file for the Cypress West Bridge
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * Cypress West Bridge high/full speed USB device controller code
+ * Based on the Netchip 2280 device controller by David Brownell
+ * in the linux 2.6.10 kernel
+ *
+ * linux/drivers/usb/gadget/net2280.h
+ */
+
+/*
+ * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
+ * Copyright (C) 2003 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.
+ *
+ * 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 _INCLUDED_CYANGADGET_H_
+#define _INCLUDED_CYANGADGET_H_
+
+#include <linux/device.h>
+#include <linux/moduleparam.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/sched.h>
+
+#include "../include/linux/westbridge/cyastoria.h"
+#include "../include/linux/westbridge/cyashal.h"
+#include "../include/linux/westbridge/cyasdevice.h"
+#include "cyasgadget_ioctl.h"
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+/*char driver defines, revisit*/
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/types.h> /* size_t */
+#include <linux/proc_fs.h>
+#include <linux/fcntl.h> /* O_ACCMODE */
+#include <linux/seq_file.h>
+#include <linux/cdev.h>
+#include <linux/scatterlist.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h> /* vmalloc(), vfree */
+#include <linux/msdos_fs.h> /*fat_alloc_cluster*/
+#include <linux/buffer_head.h>
+#include <asm/system.h> /* cli(), *_flags */
+#include <linux/uaccess.h> /* copy_*_user */
+
+extern int mpage_cleardirty(struct address_space *mapping, int num_pages);
+extern int fat_get_block(struct inode *, sector_t , struct buffer_head *, int);
+extern cy_as_device_handle *cyasdevice_getdevhandle(void) ;
+
+/* Driver data structures and utilities */
+typedef struct cyasgadget_ep {
+ struct usb_ep usb_ep_inst;
+ struct cyasgadget *dev;
+
+ /* analogous to a host-side qh */
+ struct list_head queue;
+ const struct usb_endpoint_descriptor *desc;
+ unsigned num:8,
+ fifo_size:12,
+ in_fifo_validate:1,
+ out_overflow:1,
+ stopped:1,
+ is_in:1,
+ is_iso:1;
+ cy_as_usb_end_point_config cyepconfig;
+} cyasgadget_ep ;
+
+typedef struct cyasgadget_req {
+ struct usb_request req;
+ struct list_head queue;
+ int ep_num;
+ unsigned mapped:1,
+ valid:1,
+ complete:1,
+ ep_stopped:1;
+} cyasgadget_req ;
+
+typedef struct cyasgadget {
+ /* each device provides one gadget, several endpoints */
+ struct usb_gadget gadget;
+ spinlock_t lock;
+ struct cyasgadget_ep an_gadget_ep[16];
+ struct usb_gadget_driver *driver;
+ /* Handle to the West Bridge device */
+ cy_as_device_handle dev_handle;
+ unsigned enabled:1,
+ protocol_stall:1,
+ softconnect:1,
+ outsetupreq:1;
+ struct completion thread_complete;
+ wait_queue_head_t thread_wq;
+ struct semaphore thread_sem;
+ struct list_head thread_queue;
+
+ cy_bool tmtp_send_complete;
+ cy_bool tmtp_get_complete;
+ cy_bool tmtp_need_new_blk_tbl;
+ /* Data member used to store the SendObjectComplete event data */
+ cy_as_mtp_send_object_complete_data tmtp_send_complete_data;
+ /* Data member used to store the GetObjectComplete event data */
+ cy_as_mtp_get_object_complete_data tmtp_get_complete_data;
+
+} cyasgadget ;
+
+static inline void set_halt(cyasgadget_ep *ep)
+{
+ return ;
+}
+
+static inline void clear_halt(cyasgadget_ep *ep)
+{
+ return ;
+}
+
+#define xprintk(dev, level, fmt, args...) \
+ printk(level "%s %s: " fmt, driver_name, \
+ pci_name(dev->pdev), ## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(dev, fmt, args...) \
+ xprintk(dev, KERN_DEBUG, fmt, ## args)
+#else
+#define DEBUG(dev, fmt, args...) \
+ do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDEBUG DEBUG
+#else
+#define VDEBUG(dev, fmt, args...) \
+ do { } while (0)
+#endif /* VERBOSE */
+
+#define ERROR(dev, fmt, args...) \
+ xprintk(dev, KERN_ERR, fmt, ## args)
+#define GADG_WARN(dev, fmt, args...) \
+ xprintk(dev, KERN_WARNING, fmt, ## args)
+#define INFO(dev, fmt, args...) \
+ xprintk(dev, KERN_INFO, fmt, ## args)
+
+/*-------------------------------------------------------------------------*/
+
+static inline void start_out_naking(struct cyasgadget_ep *ep)
+{
+ return ;
+}
+
+static inline void stop_out_naking(struct cyasgadget_ep *ep)
+{
+ return ;
+}
+
+#endif /* _INCLUDED_CYANGADGET_H_ */
diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h b/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h
new file mode 100644
index 000000000000..e67bfd36f62a
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h
@@ -0,0 +1,99 @@
+/* cyasgadget_ioctl.h - Linux USB Gadget driver ioctl file for
+ * Cypress West Bridge
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef CYASGADGET_IOCTL_H
+#define CYASGADGET_IOCTL_H
+
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+typedef struct cy_as_gadget_ioctl_send_object {
+ uint32_t status;
+ uint32_t byte_count ;
+ uint32_t transaction_id ;
+} cy_as_gadget_ioctl_send_object ;
+
+typedef struct cy_as_gadget_ioctl_get_object {
+ uint32_t status;
+ uint32_t byte_count ;
+} cy_as_gadget_ioctl_get_object ;
+
+
+typedef struct cy_as_gadget_ioctl_tmtp_status {
+ cy_bool tmtp_send_complete;
+ cy_bool tmtp_get_complete;
+ cy_bool tmtp_need_new_blk_tbl;
+ cy_as_gadget_ioctl_send_object tmtp_send_complete_data;
+ cy_as_gadget_ioctl_get_object tmtp_get_complete_data;
+ uint32_t t_usec;
+} cy_as_gadget_ioctl_tmtp_status ;
+
+/*Init send object data*/
+typedef struct cy_as_gadget_ioctl_i_s_o_j_d {
+ uint32_t *blk_addr_p; /* starting sector */
+ uint16_t *blk_count_p; /* num of sectors in the block */
+ /* number of entries in the blk table */
+ uint32_t item_count;
+ uint32_t num_bytes;
+ /* in case if more prcise timestamping is done in kernel mode */
+ uint32_t t_usec;
+ uint32_t ret_val ;
+ char *file_name;
+ uint32_t name_length;
+
+} cy_as_gadget_ioctl_i_s_o_j_d;
+
+
+/*Init get object data*/
+typedef struct cy_as_gadget_ioctl_i_g_o_j_d {
+ uint32_t *blk_addr_p;
+ uint16_t *blk_count_p;
+ uint32_t item_count;
+ uint32_t num_bytes;
+ uint32_t tid ;
+ uint32_t ret_val ;
+ char *file_name;
+ uint32_t name_length;
+
+} cy_as_gadget_ioctl_i_g_o_j_d ;
+
+typedef struct cy_as_gadget_ioctl_cancel {
+ uint32_t ret_val;
+} cy_as_gadget_ioctl_cancel;
+
+#define CYASGADGET_IOC_MAGIC 0xEF
+#define CYASGADGET_GETMTPSTATUS \
+ _IOW(CYASGADGET_IOC_MAGIC, 0, cy_as_gadget_ioctl_tmtp_status)
+#define CYASGADGET_CLEARTMTPSTATUS \
+ _IO(CYASGADGET_IOC_MAGIC, 1)
+#define CYASGADGET_INITSOJ \
+ _IOW(CYASGADGET_IOC_MAGIC, 2, cy_as_gadget_ioctl_i_s_o_j_d)
+#define CYASGADGET_INITGOJ \
+ _IOW(CYASGADGET_IOC_MAGIC, 3, cy_as_gadget_ioctl_i_g_o_j_d)
+#define CYASGADGET_CANCELSOJ \
+ _IOW(CYASGADGET_IOC_MAGIC, 4, cy_as_gadget_ioctl_cancel)
+#define CYASGADGET_CANCELGOJ \
+ _IOW(CYASGADGET_IOC_MAGIC, 5, cy_as_gadget_ioctl_cancel)
+#define CYASGADGET_IOC_MAXNR 6
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h
new file mode 100644
index 000000000000..c7d4ebb020c9
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h
@@ -0,0 +1,418 @@
+/* Cypress West Bridge API header file (cyanerr.h)
+ ## Symbols for backward compatibility with previous releases of Antioch SDK.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANERR_H_
+#define _INCLUDED_CYANERR_H_
+
+#include "cyaserr.h"
+
+#ifndef __doxygen__
+
+/*
+ * Function completed successfully.
+ */
+#define CY_AN_ERROR_SUCCESS (CY_AS_ERROR_SUCCESS)
+
+/*
+ * A function trying to acquire a resource was unable to do so.
+ */
+#define CY_AN_ERROR_NOT_ACQUIRED (CY_AS_ERROR_NOT_ACQUIRED)
+
+/*
+ * A function trying to acquire a resource was unable to do so.
+ */
+#define CY_AN_ERROR_NOT_RELEASED (CY_AS_ERROR_NOT_RELEASED)
+
+/*
+ * The West Bridge firmware is not loaded.
+ */
+#define CY_AN_ERROR_NO_FIRMWARE (CY_AS_ERROR_NO_FIRMWARE)
+
+/*
+ * A timeout occurred waiting on a response from the West Bridge device
+ */
+#define CY_AN_ERROR_TIMEOUT (CY_AS_ERROR_TIMEOUT)
+
+/*
+ * A request to download firmware was made while not in the CONFIG mode
+ */
+#define CY_AN_ERROR_NOT_IN_CONFIG_MODE (CY_AS_ERROR_NOT_IN_CONFIG_MODE)
+
+/*
+ * This error is returned if the firmware size specified is too invalid.
+ */
+#define CY_AN_ERROR_INVALID_SIZE (CY_AS_ERROR_INVALID_SIZE)
+
+/*
+ * This error is returned if a request is made to acquire a resource that has
+ * already been acquired.
+ */
+#define CY_AN_ERROR_RESOURCE_ALREADY_OWNED (CY_AS_ERROR_RESOURCE_ALREADY_OWNED)
+
+/*
+ * This error is returned if a request is made to release a resource that has
+ * not previously been acquired.
+ */
+#define CY_AN_ERROR_RESOURCE_NOT_OWNED (CY_AS_ERROR_RESOURCE_NOT_OWNED)
+
+/*
+ * This error is returned when a request is made for a media that does not
+ * exist
+ */
+#define CY_AN_ERROR_NO_SUCH_MEDIA (CY_AS_ERROR_NO_SUCH_MEDIA)
+
+/*
+ * This error is returned when a request is made for a device that does
+ * not exist
+ */
+#define CY_AN_ERROR_NO_SUCH_DEVICE (CY_AS_ERROR_NO_SUCH_DEVICE)
+
+/*
+ * This error is returned when a request is made for a unit that does
+ * not exist
+ */
+#define CY_AN_ERROR_NO_SUCH_UNIT (CY_AS_ERROR_NO_SUCH_UNIT)
+
+/*
+ * This error is returned when a request is made for a block that does
+ * not exist
+ */
+#define CY_AN_ERROR_INVALID_BLOCK (CY_AS_ERROR_INVALID_BLOCK)
+
+/*
+ * This error is returned when an invalid trace level is set.
+ */
+#define CY_AN_ERROR_INVALID_TRACE_LEVEL (CY_AS_ERROR_INVALID_TRACE_LEVEL)
+
+/*
+ * This error is returned when West Bridge is already in the standby state
+ * and an attempt is made to put West Bridge into this state again.
+ */
+#define CY_AN_ERROR_ALREADY_STANDBY (CY_AS_ERROR_ALREADY_STANDBY)
+
+/*
+ * This error is returned when the API needs to set a pin on the
+ * West Bridge device, but this is not supported by the underlying HAL
+ * layer.
+ */
+#define CY_AN_ERROR_SETTING_WAKEUP_PIN (CY_AS_ERROR_SETTING_WAKEUP_PIN)
+
+/*
+ * This error is returned when a module is being started that has
+ * already been started.
+ */
+#define CY_AN_ERROR_ALREADY_RUNNING (CY_AS_ERROR_ALREADY_RUNNING)
+
+/*
+ * This error is returned when a module is being stopped that has
+ * already been stopped.
+ */
+#define CY_AN_ERROR_NOT_RUNNING (CY_AS_ERROR_NOT_RUNNING)
+
+/*
+ * This error is returned when the caller tries to claim a media that has
+ * already been claimed.
+ */
+#define CY_AN_ERROR_MEDIA_ALREADY_CLAIMED (CY_AS_ERROR_MEDIA_ALREADY_CLAIMED)
+
+/*
+ * This error is returned when the caller tries to release a media that
+ * has already been released.
+ */
+#define CY_AN_ERROR_MEDIA_NOT_CLAIMED (CY_AS_ERROR_MEDIA_NOT_CLAIMED)
+
+/*
+ * This error is returned when canceling trying to cancel an asynchronous
+ * operation when an async operation is not pending.
+ */
+#define CY_AN_ERROR_NO_OPERATION_PENDING (CY_AS_ERROR_NO_OPERATION_PENDING)
+
+/*
+ * This error is returned when an invalid endpoint number is provided
+ * to an API call.
+ */
+#define CY_AN_ERROR_INVALID_ENDPOINT (CY_AS_ERROR_INVALID_ENDPOINT)
+
+/*
+ * This error is returned when an invalid descriptor type
+ * is specified in an API call.
+ */
+#define CY_AN_ERROR_INVALID_DESCRIPTOR (CY_AS_ERROR_INVALID_DESCRIPTOR)
+
+/*
+ * This error is returned when an invalid descriptor index
+ * is specified in an API call.
+ */
+#define CY_AN_ERROR_BAD_INDEX (CY_AS_ERROR_BAD_INDEX)
+
+/*
+ * This error is returned if trying to set a USB descriptor
+ * when in the P port enumeration mode.
+ */
+#define CY_AN_ERROR_BAD_ENUMERATION_MODE (CY_AS_ERROR_BAD_ENUMERATION_MODE)
+
+/*
+ * This error is returned when the endpoint configuration specified
+ * is not valid.
+ */
+#define CY_AN_ERROR_INVALID_CONFIGURATION (CY_AS_ERROR_INVALID_CONFIGURATION)
+
+/*
+ * This error is returned when the API cannot verify it is connected
+ * to an West Bridge device.
+ */
+#define CY_AN_ERROR_NO_ANTIOCH (CY_AS_ERROR_NO_ANTIOCH)
+
+/*
+ * This error is returned when an API function is called and
+ * CyAnMiscConfigureDevice has not been called to configure West
+ * Bridge for the current environment.
+ */
+#define CY_AN_ERROR_NOT_CONFIGURED (CY_AS_ERROR_NOT_CONFIGURED)
+
+/*
+ * This error is returned when West Bridge cannot allocate memory required for
+ * internal API operations.
+ */
+#define CY_AN_ERROR_OUT_OF_MEMORY (CY_AS_ERROR_OUT_OF_MEMORY)
+
+/*
+ * This error is returned when a module is being started that has
+ * already been started.
+ */
+#define CY_AN_ERROR_NESTED_SLEEP (CY_AS_ERROR_NESTED_SLEEP)
+
+/*
+ * This error is returned when an operation is attempted on an endpoint that has
+ * been disabled.
+ */
+#define CY_AN_ERROR_ENDPOINT_DISABLED (CY_AS_ERROR_ENDPOINT_DISABLED)
+
+/*
+ * This error is returned when a call is made to an API function when the device
+ * is in standby.
+ */
+#define CY_AN_ERROR_IN_STANDBY (CY_AS_ERROR_IN_STANDBY)
+
+/*
+ * This error is returned when an API call is made with an invalid handle value.
+ */
+#define CY_AN_ERROR_INVALID_HANDLE (CY_AS_ERROR_INVALID_HANDLE)
+
+/*
+ * This error is returned when an invalid response is returned from the West
+ * Bridge device.
+ */
+#define CY_AN_ERROR_INVALID_RESPONSE (CY_AS_ERROR_INVALID_RESPONSE)
+
+/*
+ * This error is returned from the callback function for any asynchronous
+ * read or write request that is canceled.
+ */
+#define CY_AN_ERROR_CANCELED (CY_AS_ERROR_CANCELED)
+
+/*
+ * This error is returned when the call to create sleep channel fails
+ * in the HAL layer.
+ */
+#define CY_AN_ERROR_CREATE_SLEEP_CHANNEL_FAILED \
+ (CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED)
+
+/*
+ * This error is returned when the call to CyAnMiscLeaveStandby
+ * is made and the device is not in standby.
+ */
+#define CY_AN_ERROR_NOT_IN_STANDBY (CY_AS_ERROR_NOT_IN_STANDBY)
+
+/*
+ * This error is returned when the call to destroy sleep channel fails
+ * in the HAL layer.
+ */
+#define CY_AN_ERROR_DESTROY_SLEEP_CHANNEL_FAILED \
+ (CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED)
+
+/*
+ * This error is returned when an invalid resource is specified to a call
+ * to CyAnMiscAcquireResource() or CyAnMiscReleaseResource()
+ */
+#define CY_AN_ERROR_INVALID_RESOURCE (CY_AS_ERROR_INVALID_RESOURCE)
+
+/*
+ * This error occurs when an operation is requested on an endpoint that has
+ * a currently pending async operation.
+ */
+#define CY_AN_ERROR_ASYNC_PENDING (CY_AS_ERROR_ASYNC_PENDING)
+
+/*
+ * This error is returned when a call to CyAnStorageCancelAsync() or
+ * CyAnUsbCancelAsync() is made when no asynchronous request is pending.
+ */
+#define CY_AN_ERROR_ASYNC_NOT_PENDING (CY_AS_ERROR_ASYNC_NOT_PENDING)
+
+/*
+ * This error is returned when a request is made to put the West Bridge device
+ * into standby mode while the USB stack is still active.
+ */
+#define CY_AN_ERROR_USB_RUNNING (CY_AS_ERROR_USB_RUNNING)
+
+/*
+ * A request for in the wrong direction was issued on an endpoint.
+ */
+#define CY_AN_ERROR_USB_BAD_DIRECTION (CY_AS_ERROR_USB_BAD_DIRECTION)
+
+/*
+ * An invalid request was received
+ */
+#define CY_AN_ERROR_INVALID_REQUEST (CY_AS_ERROR_INVALID_REQUEST)
+
+/*
+ * An ACK request was requested while no setup packet was pending.
+ */
+#define CY_AN_ERROR_NO_SETUP_PACKET_PENDING \
+ (CY_AS_ERROR_NO_SETUP_PACKET_PENDING)
+
+/*
+ * A call was made to a API function that cannot be called from a callback.
+ */
+#define CY_AN_ERROR_INVALID_IN_CALLBACK (CY_AS_ERROR_INVALID_IN_CALLBACK)
+
+/*
+ * A call was made to CyAnUsbSetEndPointConfig() before
+ * CyAnUsbSetPhysicalConfiguration() was called.
+ */
+#define CY_AN_ERROR_ENDPOINT_CONFIG_NOT_SET \
+ (CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET)
+
+/*
+ * The physical endpoint referenced is not valid in the current
+ * physical configuration
+ */
+#define CY_AN_ERROR_INVALID_PHYSICAL_ENDPOINT \
+ (CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT)
+
+/*
+ * The data supplied to the CyAnMiscDownloadFirmware() call is not aligned on a
+ * WORD (16 bit) boundary.
+ */
+#define CY_AN_ERROR_ALIGNMENT_ERROR (CY_AS_ERROR_ALIGNMENT_ERROR)
+
+/*
+ * A call was made to destroy the West Bridge device, but the USB stack or the
+ * storage stack was will running.
+ */
+#define CY_AN_ERROR_STILL_RUNNING (CY_AS_ERROR_STILL_RUNNING)
+
+/*
+ * A call was made to the API for a function that is not yet supported.
+ */
+#define CY_AN_ERROR_NOT_YET_SUPPORTED (CY_AS_ERROR_NOT_YET_SUPPORTED)
+
+/*
+ * A NULL callback was provided where a non-NULL callback was required
+ */
+#define CY_AN_ERROR_NULL_CALLBACK (CY_AS_ERROR_NULL_CALLBACK)
+
+/*
+ * This error is returned when a request is made to put the West Bridge device
+ * into standby mode while the storage stack is still active.
+ */
+#define CY_AN_ERROR_STORAGE_RUNNING (CY_AS_ERROR_STORAGE_RUNNING)
+
+/*
+ * This error is returned when an operation is attempted that cannot be
+ * completed while the USB stack is connected to a USB host.
+ */
+#define CY_AN_ERROR_USB_CONNECTED (CY_AS_ERROR_USB_CONNECTED)
+
+/*
+ * This error is returned when a USB disconnect is attempted and the
+ * West Bridge device is not connected.
+ */
+#define CY_AN_ERROR_USB_NOT_CONNECTED (CY_AS_ERROR_USB_NOT_CONNECTED)
+
+/*
+ * This error is returned when an P2S storage operation attempted and
+ * data could not be read or written to the storage media.
+ */
+#define CY_AN_ERROR_MEDIA_ACCESS_FAILURE (CY_AS_ERROR_MEDIA_ACCESS_FAILURE)
+
+/*
+ * This error is returned when an P2S storage operation attempted and
+ * the media is write protected.
+ */
+#define CY_AN_ERROR_MEDIA_WRITE_PROTECTED (CY_AS_ERROR_MEDIA_WRITE_PROTECTED)
+
+/*
+ * This error is returned when an attempt is made to cancel a request
+ * that has already been sent to the West Bridge.
+ */
+#define CY_AN_ERROR_OPERATION_IN_TRANSIT (CY_AS_ERROR_OPERATION_IN_TRANSIT)
+
+/*
+ * This error is returned when an invalid parameter is passed to one of
+ * the APIs.
+ */
+#define CY_AN_ERROR_INVALID_PARAMETER (CY_AS_ERROR_INVALID_PARAMETER)
+
+/*
+ * This error is returned if an API is not supported by the current
+ * West Bridge device or the active firmware version.
+ */
+#define CY_AN_ERROR_NOT_SUPPORTED (CY_AS_ERROR_NOT_SUPPORTED)
+
+/*
+ * This error is returned when a call is made to one of the Storage or
+ * USB APIs while the device is in suspend mode.
+ */
+#define CY_AN_ERROR_IN_SUSPEND (CY_AS_ERROR_IN_SUSPEND)
+
+/*
+ * This error is returned when the call to CyAnMiscLeaveSuspend
+ * is made and the device is not in suspend mode.
+ */
+#define CY_AN_ERROR_NOT_IN_SUSPEND (CY_AS_ERROR_NOT_IN_SUSPEND)
+
+/*
+ * This error is returned when a command that is disabled by USB is called.
+ */
+#define CY_AN_ERROR_FEATURE_NOT_ENABLED (CY_AS_ERROR_FEATURE_NOT_ENABLED)
+
+/*
+ * This error is returned when an Async storage read or write is called before a
+ * query device call is issued.
+ */
+#define CY_AN_ERROR_QUERY_DEVICE_NEEDED (CY_AS_ERROR_QUERY_DEVICE_NEEDED)
+
+/*
+ * This error is returned when a call is made to USB or STORAGE Start or
+ * Stop before a prior Start or Stop has finished.
+ */
+#define CY_AN_ERROR_STARTSTOP_PENDING (CY_AS_ERROR_STARTSTOP_PENDING)
+
+/*
+ * This error is returned when a request is made for a bus that does not exist
+ */
+#define CY_AN_ERROR_NO_SUCH_BUS (CY_AS_ERROR_NO_SUCH_BUS)
+
+#endif /* __doxygen__ */
+
+#endif /* _INCLUDED_CYANERR_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h
new file mode 100644
index 000000000000..be074887f5a3
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h
@@ -0,0 +1,59 @@
+/* Cypress West Bridge API header file (cyanmedia.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANMEDIA_H_
+#define _INCLUDED_CYANMEDIA_H_
+
+#include "cyas_cplus_start.h"
+
+/* Summary
+ Specifies a specific type of media supported by West Bridge
+
+ Description
+ The West Bridge device supports five specific types
+ of media as storage/IO devices attached to it's S-Port. This
+ type is used to indicate the type of media being referenced in
+ any API call.
+*/
+#include "cyasmedia.h"
+
+/* Flash NAND memory (may be SLC or MLC) */
+#define cy_an_media_nand cy_as_media_nand
+
+/* An SD flash memory device */
+#define cy_an_media_sd_flash cy_as_media_sd_flash
+
+/* An MMC flash memory device */
+#define cy_an_media_mmc_flash cy_as_media_mmc_flash
+
+/* A CE-ATA disk drive */
+#define cy_an_media_ce_ata cy_as_media_ce_ata
+
+ /* SDIO device. */
+#define cy_an_media_sdio cy_as_media_sdio
+#define cy_an_media_max_media_value \
+ cy_as_media_max_media_value
+
+typedef cy_as_media_type cy_an_media_type;
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYANMEDIA_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h
new file mode 100644
index 000000000000..34584b798709
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h
@@ -0,0 +1,614 @@
+/* Cypress West Bridge API header file (cyanmisc.h)
+ ## Version for backward compatibility with previous Antioch SDK releases.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANMISC_H_
+#define _INCLUDED_CYANMISC_H_
+
+#include "cyantypes.h"
+#include <cyasmisc.h>
+#include "cyanmedia.h"
+#include "cyas_cplus_start.h"
+
+#define CY_AN_LEAVE_STANDBY_DELAY_CLOCK \
+ (CY_AS_LEAVE_STANDBY_DELAY_CLOCK)
+#define CY_AN_RESET_DELAY_CLOCK \
+ (CY_AS_RESET_DELAY_CLOCK)
+
+#define CY_AN_LEAVE_STANDBY_DELAY_CRYSTAL \
+ (CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL)
+
+#define CY_AN_RESET_DELAY_CRYSTAL \
+ (CY_AS_RESET_DELAY_CRYSTAL)
+
+/* Defines to convert the old CyAn names to the new
+ * CyAs names
+ */
+typedef cy_as_device_handle cy_an_device_handle;
+
+#define cy_an_device_dack_ack cy_as_device_dack_ack
+#define cy_an_device_dack_eob cy_as_device_dack_eob
+typedef cy_as_device_dack_mode cy_an_device_dack_mode;
+
+typedef cy_as_device_config cy_an_device_config;
+
+#define cy_an_resource_u_s_b cy_as_bus_u_sB
+#define cy_an_resource_sdio_MMC cy_as_bus_1
+#define cy_an_resource_nand cy_as_bus_0
+typedef cy_as_resource_type cy_an_resource_type;
+
+#define cy_an_reset_soft cy_as_reset_soft
+#define cy_an_reset_hard cy_as_reset_hard
+typedef cy_as_reset_type cy_an_reset_type;
+typedef cy_as_funct_c_b_type cy_an_funct_c_b_type;
+typedef cy_as_function_callback cy_an_function_callback;
+
+#define cy_an_event_misc_initialized \
+ cy_as_event_misc_initialized
+#define cy_an_event_misc_awake \
+ cy_as_event_misc_awake
+#define cy_an_event_misc_heart_beat \
+ cy_as_event_misc_heart_beat
+#define cy_an_event_misc_wakeup \
+ cy_as_event_misc_wakeup
+#define cy_an_event_misc_device_mismatch \
+ cy_as_event_misc_device_mismatch
+typedef cy_as_misc_event_type \
+ cy_an_misc_event_type;
+typedef cy_as_misc_event_callback \
+ cy_an_misc_event_callback;
+
+#define cy_an_misc_gpio_0 cy_as_misc_gpio_0
+#define cy_an_misc_gpio_1 cy_as_misc_gpio_1
+#define cy_an_misc_gpio__nand_CE \
+ cy_as_misc_gpio__nand_CE
+#define cy_an_misc_gpio__nand_CE2 \
+ cy_as_misc_gpio__nand_CE2
+#define cy_an_misc_gpio__nand_WP \
+ cy_as_misc_gpio__nand_WP
+#define cy_an_misc_gpio__nand_CLE \
+ cy_as_misc_gpio__nand_CLE
+#define cy_an_misc_gpio__nand_ALE \
+ cy_as_misc_gpio__nand_ALE
+#define cy_an_misc_gpio_U_valid \
+ cy_as_misc_gpio_U_valid
+#define cy_an_misc_gpio_SD_POW \
+ cy_as_misc_gpio_SD_POW
+typedef cy_as_misc_gpio cy_an_misc_gpio;
+
+#define CY_AN_SD_DEFAULT_FREQ CY_AS_SD_DEFAULT_FREQ
+#define CY_AN_SD_RATED_FREQ CY_AS_SD_RATED_FREQ
+typedef cy_as_low_speed_sd_freq cy_an_low_speed_sd_freq;
+
+#define CY_AN_HS_SD_FREQ_48 CY_AS_HS_SD_FREQ_48
+#define CY_AN_HS_SD_FREQ_24 CY_AS_HS_SD_FREQ_24
+typedef cy_as_high_speed_sd_freq \
+ cy_an_high_speed_sd_freq;
+
+#define cy_an_misc_active_high cy_as_misc_active_high
+#define cy_an_misc_active_low cy_as_misc_active_low
+typedef cy_as_misc_signal_polarity cy_an_misc_signal_polarity;
+
+typedef cy_as_get_firmware_version_data \
+ cy_an_get_firmware_version_data;
+
+enum {
+ CYAN_FW_TRACE_LOG_NONE = 0,
+ CYAN_FW_TRACE_LOG_STATE,
+ CYAN_FW_TRACE_LOG_CALLS,
+ CYAN_FW_TRACE_LOG_STACK_TRACE,
+ CYAN_FW_TRACE_MAX_LEVEL
+};
+
+
+/***********************************/
+/***********************************/
+/* FUNCTIONS */
+/***********************************/
+/***********************************/
+
+
+EXTERN cy_an_return_status_t
+cy_an_misc_create_device(
+ cy_an_device_handle *handle_p,
+ cy_an_hal_device_tag tag
+ ) ;
+#define cy_an_misc_create_device(h, tag) \
+ cy_as_misc_create_device((cy_as_device_handle *)(h), \
+ (cy_as_hal_device_tag)(tag))
+
+EXTERN cy_an_return_status_t
+cy_an_misc_destroy_device(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_misc_destroy_device(h) \
+ cy_as_misc_destroy_device((cy_as_device_handle)(h))
+
+EXTERN cy_an_return_status_t
+cy_an_misc_configure_device(
+ cy_an_device_handle handle,
+ cy_an_device_config *config_p
+ ) ;
+#define cy_an_misc_configure_device(h, cfg) \
+ cy_as_misc_configure_device((cy_as_device_handle)(h), \
+ (cy_as_device_config *)(cfg))
+
+EXTERN cy_an_return_status_t
+cy_an_misc_in_standby(
+ cy_an_device_handle handle,
+ cy_bool *standby
+ ) ;
+#define cy_an_misc_in_standby(h, standby) \
+ cy_as_misc_in_standby((cy_as_device_handle)(h), (standby))
+
+/* Sync version of Download Firmware */
+EXTERN cy_an_return_status_t
+cy_an_misc_download_firmware(
+ cy_an_device_handle handle,
+ const void *fw_p,
+ uint16_t size
+ ) ;
+
+#define cy_an_misc_download_firmware(handle, fw_p, size) \
+ cy_as_misc_download_firmware((cy_as_device_handle)\
+ (handle), (fw_p), (size), 0, 0)
+
+/* Async version of Download Firmware */
+EXTERN cy_an_return_status_t
+cy_an_misc_download_firmware_e_x(
+ cy_an_device_handle handle,
+ const void *fw_p,
+ uint16_t size,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+
+#define cy_an_misc_download_firmware_e_x(h, fw_p, size, cb, client) \
+ cy_as_misc_download_firmware((cy_as_device_handle)(h), \
+ (fw_p), (size), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Get Firmware Version */
+EXTERN cy_an_return_status_t
+cy_as_misc_get_firmware_version_dep(
+ cy_as_device_handle handle,
+ uint16_t *major,
+ uint16_t *minor,
+ uint16_t *build,
+ uint8_t *media_type,
+ cy_bool *is_debug_mode);
+
+#define cy_an_misc_get_firmware_version\
+ (h, major, minor, bld, type, mode) \
+ cy_as_misc_get_firmware_version_dep((cy_as_device_handle)(h), \
+ (major), (minor), (bld), (type), (mode))
+
+/* Async version of Get Firmware Version*/
+EXTERN cy_an_return_status_t
+cy_an_misc_get_firmware_version_e_x(
+ cy_an_device_handle handle,
+ cy_an_get_firmware_version_data *data,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_get_firmware_version_e_x\
+ (h, data, cb, client) \
+ cy_as_misc_get_firmware_version((cy_as_device_handle)(h), \
+ (data), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Read MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_read_m_c_u_register(
+ cy_an_device_handle handle,
+ uint16_t address,
+ uint8_t *value
+ ) ;
+
+#define cy_an_misc_read_m_c_u_register(handle, address, value) \
+ cy_as_misc_read_m_c_u_register((cy_as_device_handle)(handle), \
+ (address), (value), 0, 0)
+
+/* Async version of Read MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_read_m_c_u_register_e_x(
+ cy_an_device_handle handle,
+ uint16_t address,
+ uint8_t *value,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+
+#define cy_an_misc_read_m_c_u_register_e_x\
+ (h, addr, val, cb, client) \
+ cy_as_misc_read_m_c_u_register((cy_as_device_handle)(h), \
+ (addr), (val), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Write MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_write_m_c_u_register(
+ cy_an_device_handle handle,
+ uint16_t address,
+ uint8_t mask,
+ uint8_t value
+ ) ;
+#define cy_an_misc_write_m_c_u_register\
+ (handle, address, mask, value) \
+ cy_as_misc_write_m_c_u_register((cy_as_device_handle)(handle), \
+ (address), (mask), (value), 0, 0)
+
+/* Async version of Write MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_write_m_c_u_register_e_x(
+ cy_an_device_handle handle,
+ uint16_t address,
+ uint8_t mask,
+ uint8_t value,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_write_m_c_u_register_e_x\
+ (h, addr, mask, val, cb, client) \
+ cy_as_misc_write_m_c_u_register((cy_as_device_handle)(h), \
+ (addr), (mask), (val), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Write MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_reset(
+ cy_an_device_handle handle,
+ cy_an_reset_type type,
+ cy_bool flush
+ ) ;
+#define cy_an_misc_reset(handle, type, flush) \
+ cy_as_misc_reset((cy_as_device_handle)(handle), \
+ (type), (flush), 0, 0)
+
+/* Async version of Write MCU Register*/
+EXTERN cy_an_return_status_t
+cy_an_misc_reset_e_x(
+ cy_an_device_handle handle,
+ cy_an_reset_type type,
+ cy_bool flush,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_reset_e_x(h, type, flush, cb, client) \
+ cy_as_misc_reset((cy_as_device_handle)(h), \
+ (cy_as_reset_type)(type), (flush), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Synchronous version of CyAnMiscAcquireResource. */
+EXTERN cy_an_return_status_t
+cy_an_misc_acquire_resource(
+ cy_an_device_handle handle,
+ cy_an_resource_type type,
+ cy_bool force
+ ) ;
+#define cy_an_misc_acquire_resource(h, type, force) \
+ cy_as_misc_acquire_resource_dep((cy_as_device_handle)(h), \
+ (cy_as_resource_type)(type), (force))
+
+/* Asynchronous version of CyAnMiscAcquireResource. */
+EXTERN cy_an_return_status_t
+cy_an_misc_acquire_resource_e_x(
+ cy_an_device_handle handle,
+ cy_an_resource_type *type,
+ cy_bool force,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_acquire_resource_e_x\
+ (h, type_p, force, cb, client) \
+ cy_as_misc_acquire_resource((cy_as_device_handle)(h), \
+ (cy_as_resource_type *)(type_p), \
+ (force), (cy_as_function_callback)(cb), (client))
+
+/* The one and only version of Release resource */
+EXTERN cy_an_return_status_t
+cy_an_misc_release_resource(
+ cy_an_device_handle handle,
+ cy_an_resource_type type
+ ) ;
+#define cy_an_misc_release_resource(h, type)\
+ cy_as_misc_release_resource((cy_as_device_handle)(h), \
+ (cy_as_resource_type)(type))
+
+/* Synchronous version of CyAnMiscSetTraceLevel. */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_trace_level(
+ cy_an_device_handle handle,
+ uint8_t level,
+ cy_an_media_type media,
+ uint32_t device,
+ uint32_t unit
+ ) ;
+
+#define cy_an_misc_set_trace_level\
+ (handle, level, media, device, unit) \
+ cy_as_misc_set_trace_level_dep((cy_as_device_handle)(handle), \
+ (level), (cy_as_media_type)(media), (device), (unit), 0, 0)
+
+/* Asynchronous version of CyAnMiscSetTraceLevel. */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_trace_level_e_x(
+ cy_an_device_handle handle,
+ uint8_t level,
+ cy_an_media_type media,
+ uint32_t device,
+ uint32_t unit,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_set_trace_level_e_x\
+ (h, level, media, device, unit, cb, client) \
+ cy_as_misc_set_trace_level_dep((cy_as_device_handle)(h), \
+ (level), (cy_as_media_type)(media), (device), (unit), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Synchronous version of CyAnMiscEnterStandby. */
+EXTERN cy_an_return_status_t
+cy_an_misc_enter_standby(
+ cy_an_device_handle handle,
+ cy_bool pin
+ ) ;
+#define cy_an_misc_enter_standby(handle, pin) \
+ cy_as_misc_enter_standby(\
+ (cy_as_device_handle)(handle), (pin), 0, 0)
+
+/* Synchronous version of CyAnMiscEnterStandby. */
+EXTERN cy_an_return_status_t
+cy_an_misc_enter_standby_e_x(
+ cy_an_device_handle handle,
+ cy_bool pin,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_enter_standby_e_x(h, pin, cb, client) \
+ cy_as_misc_enter_standby((cy_as_device_handle)(h), \
+ (pin), (cy_as_function_callback)(cb), (client))
+
+/* Only one version of CyAnMiscLeaveStandby. */
+EXTERN cy_an_return_status_t
+cy_an_misc_leave_standby(
+ cy_an_device_handle handle,
+ cy_an_resource_type type
+ ) ;
+#define cy_an_misc_leave_standby(h, type) \
+ cy_as_misc_leave_standby((cy_as_device_handle)(h), \
+ (cy_as_resource_type)(type))
+
+/* The one version of Misc Register Callback */
+EXTERN cy_an_return_status_t
+cy_an_misc_register_callback(
+ cy_an_device_handle handle,
+ cy_an_misc_event_callback callback
+ ) ;
+#define cy_an_misc_register_callback(h, cb) \
+ cy_as_misc_register_callback((cy_as_device_handle)(h), \
+ (cy_as_misc_event_callback)(cb))
+
+/* The only version of SetLogLevel */
+EXTERN void
+cy_an_misc_set_log_level(
+ uint8_t level
+ ) ;
+#define cy_an_misc_set_log_level(level) \
+ cy_as_misc_set_log_level(level)
+
+/* Sync version of Misc Storage Changed */
+EXTERN cy_an_return_status_t
+cy_an_misc_storage_changed(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_misc_storage_changed(handle) \
+ cy_as_misc_storage_changed((cy_as_device_handle)(handle), 0, 0)
+
+/* Async version of Misc Storage Changed */
+EXTERN cy_an_return_status_t
+cy_an_misc_storage_changed_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_storage_changed_e_x(h, cb, client) \
+ cy_as_misc_storage_changed((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Heartbeat control */
+EXTERN cy_an_return_status_t
+cy_an_misc_heart_beat_control(
+ cy_an_device_handle handle,
+ cy_bool enable
+ ) ;
+#define cy_an_misc_heart_beat_control(handle, enable) \
+ cy_as_misc_heart_beat_control((cy_as_device_handle)\
+ (handle), (enable), 0, 0)
+
+/* Async version of Heartbeat control */
+EXTERN cy_an_return_status_t
+cy_an_misc_heart_beat_control_e_x(
+ cy_an_device_handle handle,
+ cy_bool enable,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_heart_beat_control_e_x(h, enable, cb, client) \
+ cy_as_misc_heart_beat_control((cy_as_device_handle)(h), \
+ (enable), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Get Gpio */
+EXTERN cy_an_return_status_t
+cy_an_misc_get_gpio_value(
+ cy_an_device_handle handle,
+ cy_an_misc_gpio pin,
+ uint8_t *value
+ ) ;
+#define cy_an_misc_get_gpio_value(handle, pin, value) \
+ cy_as_misc_get_gpio_value((cy_as_device_handle)(handle), \
+ (cy_as_misc_gpio)(pin), (value), 0, 0)
+
+/* Async version of Get Gpio */
+EXTERN cy_an_return_status_t
+cy_an_misc_get_gpio_value_e_x(
+ cy_an_device_handle handle,
+ cy_an_misc_gpio pin,
+ uint8_t *value,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_get_gpio_value_e_x(h, pin, value, cb, client) \
+ cy_as_misc_get_gpio_value((cy_as_device_handle)(h), \
+ (cy_as_misc_gpio)(pin), (value), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Set Gpio */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_gpio_value(
+ cy_an_device_handle handle,
+ cy_an_misc_gpio pin,
+ uint8_t value
+ ) ;
+#define cy_an_misc_set_gpio_value(handle, pin, value) \
+ cy_as_misc_set_gpio_value((cy_as_device_handle)(handle), \
+ (cy_as_misc_gpio)(pin), (value), 0, 0)
+
+/* Async version of Set Gpio */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_gpio_value_e_x(
+ cy_an_device_handle handle,
+ cy_an_misc_gpio pin,
+ uint8_t value,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_set_gpio_value_e_x\
+ (h, pin, value, cb, client) \
+ cy_as_misc_set_gpio_value((cy_as_device_handle)(h), \
+ (cy_as_misc_gpio)(pin), (value), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Enter suspend */
+EXTERN cy_an_return_status_t
+cy_an_misc_enter_suspend(
+ cy_an_device_handle handle,
+ cy_bool usb_wakeup_en,
+ cy_bool gpio_wakeup_en
+ ) ;
+#define cy_an_misc_enter_suspend(handle, usb_wakeup_en, \
+ gpio_wakeup_en) \
+ cy_as_misc_enter_suspend((cy_as_device_handle)(handle), \
+ (usb_wakeup_en), (gpio_wakeup_en), 0, 0)
+
+/* Async version of Enter suspend */
+EXTERN cy_an_return_status_t
+cy_an_misc_enter_suspend_e_x(
+ cy_an_device_handle handle,
+ cy_bool usb_wakeup_en,
+ cy_bool gpio_wakeup_en,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_enter_suspend_e_x(h, usb_en, gpio_en, cb, client)\
+ cy_as_misc_enter_suspend((cy_as_device_handle)(h), (usb_en), \
+ (gpio_en), (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Enter suspend */
+EXTERN cy_an_return_status_t
+cy_an_misc_leave_suspend(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_misc_leave_suspend(handle) \
+ cy_as_misc_leave_suspend((cy_as_device_handle)(handle), 0, 0)
+
+/* Async version of Enter suspend */
+EXTERN cy_an_return_status_t
+cy_an_misc_leave_suspend_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+
+#define cy_an_misc_leave_suspend_e_x(h, cb, client) \
+ cy_as_misc_leave_suspend((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of SetLowSpeedSDFreq */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_low_speed_sd_freq(
+ cy_an_device_handle handle,
+ cy_an_low_speed_sd_freq setting
+ ) ;
+#define cy_an_misc_set_low_speed_sd_freq(h, setting) \
+ cy_as_misc_set_low_speed_sd_freq((cy_as_device_handle)(h), \
+ (cy_as_low_speed_sd_freq)(setting), 0, 0)
+
+/* Async version of SetLowSpeedSDFreq */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_low_speed_sd_freq_e_x(
+ cy_an_device_handle handle,
+ cy_an_low_speed_sd_freq setting,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_set_low_speed_sd_freq_e_x\
+(h, setting, cb, client) \
+ cy_as_misc_set_low_speed_sd_freq((cy_as_device_handle)(h), \
+ (cy_as_low_speed_sd_freq)(setting), \
+ (cy_as_function_callback)(cb), (client))
+
+/* SetHighSpeedSDFreq */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_high_speed_sd_freq(
+ cy_an_device_handle handle,
+ cy_an_high_speed_sd_freq setting,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_misc_set_high_speed_sd_freq(h, setting, cb, client) \
+ cy_as_misc_set_high_speed_sd_freq((cy_as_device_handle)(h), \
+ (cy_as_high_speed_sd_freq)(setting), \
+ (cy_as_function_callback)(cb), (client))
+
+/* ReserveLNABootArea */
+EXTERN cy_an_return_status_t
+cy_an_misc_reserve_l_n_a_boot_area(
+ cy_an_device_handle handle,
+ uint8_t numzones,
+ cy_an_function_callback cb,
+ uint32_t client);
+#define cy_an_misc_reserve_l_n_a_boot_area(h, num, cb, client) \
+ cy_as_misc_reserve_l_n_a_boot_area((cy_as_device_handle)(h), \
+ num, (cy_as_function_callback)(cb), (client))
+
+/* SetSDPowerPolarity */
+EXTERN cy_an_return_status_t
+cy_an_misc_set_sd_power_polarity(
+ cy_an_device_handle handle,
+ cy_an_misc_signal_polarity polarity,
+ cy_an_function_callback cb,
+ uint32_t client);
+#define cy_an_misc_set_sd_power_polarity(h, pol, cb, client) \
+ cy_as_misc_set_sd_power_polarity((cy_as_device_handle)(h), \
+ (cy_as_misc_signal_polarity)(pol), \
+ (cy_as_function_callback)(cb), (client))
+
+#include "cyas_cplus_end.h"
+
+#endif
+
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h
new file mode 100644
index 000000000000..d670291bd24d
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h
@@ -0,0 +1,180 @@
+/* Cypress West Bridge API header file (cyanregs.h)
+ ## Register and field definitions for the Antioch device.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANREG_H_
+#define _INCLUDED_CYANREG_H_
+
+#if !defined(__doxygen__)
+
+#define CY_AN_MEM_CM_WB_CFG_ID (0x80)
+#define CY_AN_MEM_CM_WB_CFG_ID_VER_MASK (0x000F)
+#define CY_AN_MEM_CM_WB_CFG_ID_HDID_MASK (0xFFF0)
+#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE (0xA100)
+#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE (0x6800)
+#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE (0xA200)
+
+
+#define CY_AN_MEM_RST_CTRL_REG (0x81)
+#define CY_AN_MEM_RST_CTRL_REG_HARD (0x0003)
+#define CY_AN_MEM_RST_CTRL_REG_SOFT (0x0001)
+#define CY_AN_MEM_RST_RSTCMPT (0x0004)
+
+#define CY_AN_MEM_P0_ENDIAN (0x82)
+#define CY_AN_LITTLE_ENDIAN (0x0000)
+#define CY_AN_BIG_ENDIAN (0x0101)
+
+#define CY_AN_MEM_P0_VM_SET (0x83)
+#define CY_AN_MEM_P0_VM_SET_VMTYPE_MASK (0x0007)
+#define CY_AN_MEM_P0_VM_SET_VMTYPE_RAM (0x0005)
+#define CY_AN_MEM_P0_VM_SET_VMTYPE_VMWIDTH (0x0008)
+#define CY_AN_MEM_P0_VM_SET_VMTYPE_FLOWCTRL (0x0010)
+#define CY_AN_MEM_P0_VM_SET_IFMODE (0x0020)
+#define CY_AN_MEM_P0_VM_SET_CFGMODE (0x0040)
+#define CY_AN_MEM_P0_VM_SET_DACKEOB (0x0080)
+#define CY_AN_MEM_P0_VM_SET_OVERRIDE (0x0100)
+#define CY_AN_MEM_P0_VM_SET_INTOVERD (0x0200)
+#define CY_AN_MEM_P0_VM_SET_DRQOVERD (0x0400)
+#define CY_AN_MEM_P0_VM_SET_DRQPOL (0x0800)
+#define CY_AN_MEM_P0_VM_SET_DACKPOL (0x1000)
+
+
+#define CY_AN_MEM_P0_NV_SET (0x84)
+#define CY_AN_MEM_P0_NV_SET_WPSWEN (0x0001)
+#define CY_AN_MEM_P0_NV_SET_WPPOLAR (0x0002)
+
+#define CY_AN_MEM_PMU_UPDATE (0x85)
+#define CY_AN_MEM_PMU_UPDATE_UVALID (0x0001)
+#define CY_AN_MEM_PMU_UPDATE_USBUPDATE (0x0002)
+#define CY_AN_MEM_PMU_UPDATE_SDIOUPDATE (0x0004)
+
+#define CY_AN_MEM_P0_INTR_REG (0x90)
+#define CY_AN_MEM_P0_INTR_REG_MCUINT (0x0020)
+#define CY_AN_MEM_P0_INTR_REG_DRQINT (0x0800)
+#define CY_AN_MEM_P0_INTR_REG_MBINT (0x1000)
+#define CY_AN_MEM_P0_INTR_REG_PMINT (0x2000)
+#define CY_AN_MEM_P0_INTR_REG_PLLLOCKINT (0x4000)
+
+#define CY_AN_MEM_P0_INT_MASK_REG (0x91)
+#define CY_AN_MEM_P0_INT_MASK_REG_MMCUINT (0x0020)
+#define CY_AN_MEM_P0_INT_MASK_REG_MDRQINT (0x0800)
+#define CY_AN_MEM_P0_INT_MASK_REG_MMBINT (0x1000)
+#define CY_AN_MEM_P0_INT_MASK_REG_MPMINT (0x2000)
+#define CY_AN_MEM_P0_INT_MASK_REG_MPLLLOCKINT (0x4000)
+
+#define CY_AN_MEM_MCU_MB_STAT (0x92)
+#define CY_AN_MEM_P0_MCU_MBNOTRD (0x0001)
+
+#define CY_AN_MEM_P0_MCU_STAT (0x94)
+#define CY_AN_MEM_P0_MCU_STAT_CARDINS (0x0001)
+#define CY_AN_MEM_P0_MCU_STAT_CARDREM (0x0002)
+
+#define CY_AN_MEM_PWR_MAGT_STAT (0x95)
+#define CY_AN_MEM_PWR_MAGT_STAT_WAKEUP (0x0001)
+
+#define CY_AN_MEM_P0_RSE_ALLOCATE (0x98)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_SDIOAVI (0x0001)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_SDIOALLO (0x0002)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_NANDAVI (0x0004)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_NANDALLO (0x0008)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_USBAVI (0x0010)
+#define CY_AN_MEM_P0_RSE_ALLOCATE_USBALLO (0x0020)
+
+#define CY_AN_MEM_P0_RSE_MASK (0x9A)
+#define CY_AN_MEM_P0_RSE_MASK_MSDIOBUS_RW (0x0003)
+#define CY_AN_MEM_P0_RSE_MASK_MNANDBUS_RW (0x00C0)
+#define CY_AN_MEM_P0_RSE_MASK_MUSBBUS_RW (0x0030)
+
+#define CY_AN_MEM_P0_DRQ (0xA0)
+#define CY_AN_MEM_P0_DRQ_EP2DRQ (0x0004)
+#define CY_AN_MEM_P0_DRQ_EP3DRQ (0x0008)
+#define CY_AN_MEM_P0_DRQ_EP4DRQ (0x0010)
+#define CY_AN_MEM_P0_DRQ_EP5DRQ (0x0020)
+#define CY_AN_MEM_P0_DRQ_EP6DRQ (0x0040)
+#define CY_AN_MEM_P0_DRQ_EP7DRQ (0x0080)
+#define CY_AN_MEM_P0_DRQ_EP8DRQ (0x0100)
+#define CY_AN_MEM_P0_DRQ_EP9DRQ (0x0200)
+#define CY_AN_MEM_P0_DRQ_EP10DRQ (0x0400)
+#define CY_AN_MEM_P0_DRQ_EP11DRQ (0x0800)
+#define CY_AN_MEM_P0_DRQ_EP12DRQ (0x1000)
+#define CY_AN_MEM_P0_DRQ_EP13DRQ (0x2000)
+#define CY_AN_MEM_P0_DRQ_EP14DRQ (0x4000)
+#define CY_AN_MEM_P0_DRQ_EP15DRQ (0x8000)
+
+#define CY_AN_MEM_P0_DRQ_MASK (0xA1)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP2DRQ (0x0004)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP3DRQ (0x0008)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP4DRQ (0x0010)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP5DRQ (0x0020)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP6DRQ (0x0040)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP7DRQ (0x0080)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP8DRQ (0x0100)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP9DRQ (0x0200)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP10DRQ (0x0400)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP11DRQ (0x0800)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP12DRQ (0x1000)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP13DRQ (0x2000)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP14DRQ (0x4000)
+#define CY_AN_MEM_P0_DRQ_MASK_MEP15DRQ (0x8000)
+
+#define CY_AN_MEM_P0_EP2_DMA_REG (0xA2)
+#define CY_AN_MEM_P0_E_pn_DMA_REG_COUNT_MASK (0x7FF)
+#define CY_AN_MEM_P0_E_pn_DMA_REG_DMAVAL (1 << 12)
+#define CY_AN_MEM_P0_EP3_DMA_REG (0xA3)
+#define CY_AN_MEM_P0_EP4_DMA_REG (0xA4)
+#define CY_AN_MEM_P0_EP5_DMA_REG (0xA5)
+#define CY_AN_MEM_P0_EP6_DMA_REG (0xA6)
+#define CY_AN_MEM_P0_EP7_DMA_REG (0xA7)
+#define CY_AN_MEM_P0_EP8_DMA_REG (0xA8)
+#define CY_AN_MEM_P0_EP9_DMA_REG (0xA9)
+#define CY_AN_MEM_P0_EP10_DMA_REG (0xAA)
+#define CY_AN_MEM_P0_EP11_DMA_REG (0xAB)
+#define CY_AN_MEM_P0_EP12_DMA_REG (0xAC)
+#define CY_AN_MEM_P0_EP13_DMA_REG (0xAD)
+#define CY_AN_MEM_P0_EP14_DMA_REG (0xAE)
+#define CY_AN_MEM_P0_EP15_DMA_REG (0xAF)
+
+#define CY_AN_MEM_IROS_IO_CFG (0xC1)
+#define CY_AN_MEM_IROS_IO_CFG_GPIODRVST_MASK (0x0003)
+#define CY_AN_MEM_IROS_IO_CFG_GPIOSLEW_MASK (0x0004)
+#define CY_AN_MEM_IROS_IO_CFG_PPIODRVST_MASK (0x0018)
+#define CY_AN_MEM_IROS_IO_CFG_PPIOSLEW_MASK (0x0020)
+#define CY_AN_MEM_IROS_IO_CFG_SSIODRVST_MASK (0x0300)
+#define CY_AN_MEM_IROS_IO_CFG_SSIOSLEW_MASK (0x0400)
+#define CY_AN_MEM_IROS_IO_CFG_SNIODRVST_MASK (0x1800)
+#define CY_AN_MEM_IROS_IO_CFG_SNIOSLEW_MASK (0x2000)
+
+#define CY_AN_MEM_PLL_LOCK_LOSS_STAT (0xC4)
+#define CY_AN_MEM_PLL_LOCK_LOSS_STAT_PLLSTAT (0x0800)
+
+#define CY_AN_MEM_P0_MAILBOX0 (0xF0)
+#define CY_AN_MEM_P0_MAILBOX1 (0xF1)
+#define CY_AN_MEM_P0_MAILBOX2 (0xF2)
+#define CY_AN_MEM_P0_MAILBOX3 (0xF3)
+
+#define CY_AN_MEM_MCU_MAILBOX0 (0xF8)
+#define CY_AN_MEM_MCU_MAILBOX1 (0xF9)
+#define CY_AN_MEM_MCU_MAILBOX2 (0xFA)
+#define CY_AN_MEM_MCU_MAILBOX3 (0xFB)
+
+#endif /* !defined(__doxygen__) */
+
+#endif /* _INCLUDED_CYANREG_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h
new file mode 100644
index 000000000000..ac26b9556dda
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h
@@ -0,0 +1,30 @@
+/* Cypress Antioch Sdk Version file (cyansdkversion.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANSDK_VERSION_H_
+#define _INCLUDED_CYANSDK_VERSION_H_
+
+/* Antioch SDK version 1.3.2 */
+#define CYAN_MAJOR_VERSION (1)
+#define CYAN_MINOR_VERSION (3)
+#define CYAN_BUILD_NUMBER (473)
+
+#endif /*_INCLUDED_CYANSDK_VERSION_H_*/
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h
new file mode 100644
index 000000000000..766f94a9c92b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h
@@ -0,0 +1,419 @@
+/* Cypress West Bridge API header file (cyanstorage.h)
+ ## Header for backward compatibility with previous releases of Antioch SDK.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANSTORAGE_H_
+#define _INCLUDED_CYANSTORAGE_H_
+#ifndef __doxygen__
+
+#include "cyanmedia.h"
+#include "cyanmisc.h"
+#include "cyasstorage.h"
+#include "cyas_cplus_start.h"
+
+#define CY_AN_LUN_PHYSICAL_DEVICE (CY_AS_LUN_PHYSICAL_DEVICE)
+#define CY_AN_STORAGE_EP_SIZE (CY_AS_STORAGE_EP_SIZE)
+
+#define cy_an_storage_antioch cy_as_storage_antioch
+#define cy_an_storage_processor cy_as_storage_processor
+#define cy_an_storage_removed cy_as_storage_removed
+#define cy_an_storage_inserted cy_as_storage_inserted
+#define cy_an_sdio_interrupt cy_as_sdio_interrupt
+typedef cy_as_storage_event cy_an_storage_event;
+
+#define cy_an_op_read cy_as_op_read
+#define cy_an_op_write cy_as_op_write
+typedef cy_as_oper_type cy_an_oper_type;
+
+typedef cy_as_device_desc cy_an_device_desc;
+
+typedef cy_as_unit_desc cy_an_unit_desc;
+
+typedef cy_as_storage_callback_dep \
+ cy_an_storage_callback;
+
+typedef cy_as_storage_event_callback_dep \
+ cy_an_storage_event_callback;
+
+#define cy_an_sd_reg_OCR cy_as_sd_reg_OCR
+#define cy_an_sd_reg_CID cy_as_sd_reg_CID
+#define cy_an_sd_reg_CSD cy_as_sd_reg_CSD
+typedef cy_as_sd_card_reg_type \
+ cy_an_sd_card_reg_type;
+
+typedef cy_as_storage_query_device_data_dep \
+ cy_an_storage_query_device_data ;
+
+typedef cy_as_storage_query_unit_data_dep \
+ cy_an_storage_query_unit_data ;
+
+typedef cy_as_storage_sd_reg_read_data \
+ cy_an_storage_sd_reg_read_data;
+
+#define CY_AN_SD_REG_OCR_LENGTH (CY_AS_SD_REG_OCR_LENGTH)
+#define CY_AN_SD_REG_CID_LENGTH (CY_AS_SD_REG_CID_LENGTH)
+#define CY_AN_SD_REG_CSD_LENGTH (CY_AS_SD_REG_CSD_LENGTH)
+#define CY_AN_SD_REG_MAX_RESP_LENGTH \
+ (CY_AS_SD_REG_MAX_RESP_LENGTH)
+
+/**** API Functions ******/
+
+/* Sync version of Storage Start */
+EXTERN cy_an_return_status_t
+cy_an_storage_start(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_storage_start(handle) \
+ cy_as_storage_start((cy_as_device_handle)(handle), 0, 0)
+
+/* Async version of Storage Start */
+EXTERN cy_an_return_status_t
+cy_an_storage_start_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_start_e_x(h, cb, client) \
+ cy_as_storage_start((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Storage Stop */
+EXTERN cy_an_return_status_t
+cy_an_storage_stop(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_storage_stop(handle) \
+ cy_as_storage_stop((cy_as_device_handle)(handle), 0, 0)
+
+/* Async version of Storage Stop */
+EXTERN cy_an_return_status_t
+cy_an_storage_stop_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_stop_e_x(h, cb, client) \
+ cy_as_storage_stop((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Register Call back api */
+EXTERN cy_an_return_status_t
+cy_an_storage_register_callback(
+ cy_an_device_handle handle,
+ cy_an_storage_event_callback callback
+ ) ;
+#define cy_an_storage_register_callback(h, cb) \
+ cy_as_storage_register_callback_dep((cy_as_device_handle)(h), \
+ (cy_as_storage_event_callback_dep)(cb))
+
+/* Sync version of Storage Claim */
+EXTERN cy_an_return_status_t
+cy_an_storage_claim(
+ cy_an_device_handle handle,
+ cy_an_media_type type
+ ) ;
+#define cy_an_storage_claim(h, type) \
+ cy_as_storage_claim_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type))
+
+/* Async version of Storage Claim */
+EXTERN cy_an_return_status_t
+cy_an_storage_claim_e_x(
+ cy_an_device_handle handle,
+ cy_an_media_type *type,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_claim_e_x(h, type_p, cb, client) \
+ cy_as_storage_claim_dep_EX((cy_as_device_handle)(h), \
+ (cy_as_media_type *)(type_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync Version of Storage Release */
+EXTERN cy_an_return_status_t
+cy_an_storage_release(
+ cy_an_device_handle handle,
+ cy_an_media_type type
+ ) ;
+#define cy_an_storage_release(h, type) \
+ cy_as_storage_release_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type))
+
+/* Async Version of Storage Release */
+EXTERN cy_an_return_status_t
+cy_an_storage_release_e_x(
+ cy_an_device_handle handle,
+ cy_an_media_type *type,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_release_e_x(h, type_p, cb, client) \
+ cy_as_storage_release_dep_EX((cy_as_device_handle)(h), \
+ (cy_as_media_type *)(type_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Query Media */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_media(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t *count
+ ) ;
+#define cy_an_storage_query_media(handle, type, count) \
+ cy_as_storage_query_media((cy_as_device_handle)(handle), \
+ (cy_as_media_type)(type), (count), 0, 0)
+
+/* Async version of Query Media */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_media_e_x(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t *count,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_query_media_e_x(h, type, count, cb, client) \
+ cy_as_storage_query_media((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (count), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Query device */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_device(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ cy_an_device_desc *desc_p
+ ) ;
+#define cy_an_storage_query_device(h, type, device, desc_p) \
+ cy_as_storage_query_device_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), (cy_as_device_desc *)(desc_p))
+
+/* Async version of Query device */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_device_e_x(
+ cy_an_device_handle handle,
+ cy_an_storage_query_device_data *data,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_query_device_e_x(h, data, cb, client) \
+ cy_as_storage_query_device_dep_EX((cy_as_device_handle)(h), \
+ (cy_as_storage_query_device_data_dep *)(data), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Query Unit */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_unit(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ uint32_t unit,
+ cy_an_unit_desc *desc_p
+ ) ;
+#define cy_an_storage_query_unit(h, type, device, unit, desc_p) \
+ cy_as_storage_query_unit_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), \
+ (unit), (cy_as_unit_desc *)(desc_p))
+
+/* Async version of Query Unit */
+EXTERN cy_an_return_status_t
+cy_an_storage_query_unit_e_x(
+ cy_an_device_handle handle,
+ cy_an_storage_query_unit_data *data_p,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_query_unit_e_x(h, data_p, cb, client) \
+ cy_as_storage_query_unit_dep_EX((cy_as_device_handle)(h), \
+ (cy_as_storage_query_unit_data_dep *)(data_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of device control */
+EXTERN cy_an_return_status_t
+cy_an_storage_device_control(
+ cy_an_device_handle handle,
+ cy_bool card_detect_en,
+ cy_bool write_prot_en
+ ) ;
+#define cy_an_storage_device_control(handle, \
+ card_detect_en, write_prot_en) \
+ cy_as_storage_device_control_dep((cy_as_device_handle)(handle), \
+ (card_detect_en), (write_prot_en), 0, 0)
+
+/* Async version of device control */
+EXTERN cy_an_return_status_t
+cy_an_storage_device_control_e_x(
+ cy_an_device_handle handle,
+ cy_bool card_detect_en,
+ cy_bool write_prot_en,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_device_control_e_x(h, det_en, prot_en, cb, client) \
+ cy_as_storage_device_control_dep((cy_as_device_handle)(h), (det_en), \
+ (prot_en), (cy_as_function_callback)(cb), (client))
+
+/* Sync Read */
+EXTERN cy_an_return_status_t
+cy_an_storage_read(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ uint32_t unit,
+ uint32_t block,
+ void *data_p,
+ uint16_t num_blocks
+ ) ;
+#define cy_an_storage_read(h, type, device, unit, block, data_p, nblks) \
+ cy_as_storage_read_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), (unit), \
+ (block), (data_p), (nblks))
+
+/* Async Read */
+EXTERN cy_an_return_status_t
+cy_an_storage_read_async(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ uint32_t unit,
+ uint32_t block,
+ void *data_p,
+ uint16_t num_blocks,
+ cy_an_storage_callback callback
+ ) ;
+#define cy_an_storage_read_async(h, type, device, unit, \
+ block, data_p, nblks, cb) \
+ cy_as_storage_read_async_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), (unit), (block), \
+ (data_p), (nblks), (cy_as_storage_callback_dep)(cb))
+
+/* Sync Write */
+EXTERN cy_an_return_status_t
+cy_an_storage_write(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ uint32_t unit,
+ uint32_t block,
+ void *data_p,
+ uint16_t num_blocks
+ ) ;
+#define cy_an_storage_write(h, type, device, unit, \
+ block, data_p, nblks) \
+ cy_as_storage_write_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), (unit), \
+ (block), (data_p), (nblks))
+
+/* Async Write */
+EXTERN cy_an_return_status_t
+cy_an_storage_write_async(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint32_t device,
+ uint32_t unit,
+ uint32_t block,
+ void *data_p,
+ uint16_t num_blocks,
+ cy_an_storage_callback callback
+ ) ;
+#define cy_an_storage_write_async(h, type, device, unit, \
+ block, data_p, nblks, cb) \
+ cy_as_storage_write_async_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), (unit), (block), \
+ (data_p), (nblks), (cy_as_storage_callback_dep)(cb))
+
+/* Cancel Async */
+EXTERN cy_an_return_status_t
+cy_an_storage_cancel_async(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_storage_cancel_async(h) \
+ cy_as_storage_cancel_async((cy_as_device_handle)(h))
+
+/* Sync SD Register Read*/
+EXTERN cy_an_return_status_t
+cy_an_storage_sd_register_read(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint8_t device,
+ cy_an_sd_card_reg_type reg_type,
+ uint8_t read_len,
+ uint8_t *data_p
+ ) ;
+#define cy_an_storage_sd_register_read(h, type, device, \
+ reg_type, len, data_p) \
+ cy_as_storage_sd_register_read_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), \
+ (cy_as_sd_card_reg_type)(reg_type), (len), (data_p))
+
+/*Async SD Register Read*/
+EXTERN cy_an_return_status_t
+cy_an_storage_sd_register_read_e_x(
+ cy_an_device_handle handle,
+ cy_an_media_type type,
+ uint8_t device,
+ cy_an_sd_card_reg_type reg_type,
+ cy_an_storage_sd_reg_read_data *data_p,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_storage_sd_register_read_e_x(h, type, device, \
+ reg_type, data_p, cb, client) \
+ cy_as_storage_sd_register_read_dep_EX((cy_as_device_handle)(h), \
+ (cy_as_media_type)(type), (device), \
+ (cy_as_sd_card_reg_type)(reg_type), \
+ (cy_as_storage_sd_reg_read_data *)(data_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Create partition on storage device */
+EXTERN cy_an_return_status_t
+cy_an_storage_create_p_partition(
+ cy_an_device_handle handle,
+ cy_an_media_type media,
+ uint32_t device,
+ uint32_t size,
+ cy_an_function_callback cb,
+ uint32_t client) ;
+#define cy_an_storage_create_p_partition(h, media, dev, \
+ size, cb, client) \
+ cy_as_storage_create_p_partition_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(media), (dev), \
+ (size), (cy_as_function_callback)(cb), (client))
+
+/* Remove partition on storage device */
+EXTERN cy_an_return_status_t
+cy_an_storage_remove_p_partition(
+ cy_an_device_handle handle,
+ cy_an_media_type media,
+ uint32_t device,
+ cy_an_function_callback cb,
+ uint32_t client) ;
+#define cy_an_storage_remove_p_partition\
+(h, media, dev, cb, client) \
+ cy_as_storage_remove_p_partition_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(media), (dev), \
+ (cy_as_function_callback)(cb), (client))
+
+#include "cyas_cplus_end.h"
+#endif /*__doxygen__ */
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h
new file mode 100644
index 000000000000..d65b35a14ae1
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h
@@ -0,0 +1,35 @@
+/* Cypress West Bridge API header file (cyastioch.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANTIOCH_H_
+#define _INCLUDED_CYANTIOCH_H_
+
+#if !defined(__doxygen__)
+
+#include "cyanerr.h"
+#include "cyanmisc.h"
+#include "cyanstorage.h"
+#include "cyanusb.h"
+#include "cyanch9.h"
+
+#endif
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h
new file mode 100644
index 000000000000..d6028d64d247
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h
@@ -0,0 +1,31 @@
+/* Cypress West Bridge API header file (cyantypes.h)
+## Type definitions for backward compatibility with previous
+## Antioch SDK releases.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANTYPES_H_
+#define _INCLUDED_CYANTYPES_H_
+
+#include "cyastypes.h"
+typedef cy_as_end_point_number_t cy_an_end_point_number_t ;
+typedef cy_as_return_status_t cy_an_return_status_t ;
+typedef cy_as_bus_number_t cy_an_bus_number_t ;
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h
new file mode 100644
index 000000000000..0777fd457d49
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h
@@ -0,0 +1,619 @@
+/* Cypress West Bridge API header file (cyanusb.h)
+ ## Header for backward compatibility with previous Antioch SDK releases.
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYANUSB_H_
+#define _INCLUDED_CYANUSB_H_
+
+#if !defined(__doxygen__)
+
+#include "cyanmisc.h"
+#include "cyasusb.h"
+#include "cyas_cplus_start.h"
+
+#define CY_AN_MAX_USB_DESCRIPTOR_SIZE (CY_AS_MAX_USB_DESCRIPTOR_SIZE)
+
+typedef cy_as_usb_inquiry_data_dep cy_an_usb_inquiry_data;
+typedef cy_as_usb_unknown_command_data_dep \
+ cy_an_usb_unknown_command_data ;
+typedef cy_as_usb_start_stop_data_dep cy_an_usb_start_stop_data ;
+typedef cy_as_m_s_c_progress_data cy_an_m_s_c_progress_data ;
+
+#define cy_an_usb_nand_enum cy_as_usb_nand_enum
+#define cy_an_usb_sd_enum cy_as_usb_sd_enum
+#define cy_an_usb_mmc_enum cy_as_usb_mmc_enum
+#define cy_an_usb_ce_ata_enum cy_as_usb_ce_ata_enum
+typedef cy_as_usb_mass_storage_enum cy_an_usb_mass_storage_enum;
+
+#define cy_an_usb_desc_device cy_as_usb_desc_device
+#define cy_an_usb_desc_device_qual cy_as_usb_desc_device_qual
+#define cy_an_usb_desc_f_s_configuration \
+ cy_as_usb_desc_f_s_configuration
+#define cy_an_usb_desc_h_s_configuration \
+ cy_as_usb_desc_h_s_configuration
+#define cy_an_usb_desc_string cy_as_usb_desc_string
+typedef cy_as_usb_desc_type cy_an_usb_desc_type ;
+
+#define cy_an_usb_in cy_as_usb_in
+#define cy_an_usb_out cy_as_usb_out
+#define cy_an_usb_in_out cy_as_usb_in_out
+typedef cy_as_usb_end_point_dir cy_an_usb_end_point_dir ;
+
+
+#define cy_an_usb_control cy_as_usb_control
+#define cy_an_usb_iso cy_as_usb_iso
+#define cy_an_usb_bulk cy_as_usb_bulk
+#define cy_an_usb_int cy_as_usb_int
+typedef cy_as_usb_end_point_type cy_an_usb_end_point_type ;
+
+
+typedef cy_as_usb_enum_control_dep cy_an_usb_enum_control ;
+typedef cy_as_usb_end_point_config cy_an_usb_end_point_config ;
+
+#define cy_an_usb_m_s_unit0 cy_as_usb_m_s_unit0
+#define cy_an_usb_m_s_unit1 cy_as_usb_m_s_unit1
+#define cy_an_usb_m_s_both cy_as_usb_m_s_both
+typedef cy_as_usb_m_s_type_t cy_an_usb_m_s_type_t ;
+
+#define cy_an_event_usb_suspend cy_as_event_usb_suspend
+#define cy_an_event_usb_resume cy_as_event_usb_resume
+#define cy_an_event_usb_reset cy_as_event_usb_reset
+#define cy_an_event_usb_set_config cy_as_event_usb_set_config
+#define cy_an_event_usb_speed_change cy_as_event_usb_speed_change
+#define cy_an_event_usb_setup_packet cy_as_event_usb_setup_packet
+#define cy_an_event_usb_status_packet cy_as_event_usb_status_packet
+#define cy_an_event_usb_inquiry_before cy_as_event_usb_inquiry_before
+#define cy_an_event_usb_inquiry_after cy_as_event_usb_inquiry_after
+#define cy_an_event_usb_start_stop cy_as_event_usb_start_stop
+#define cy_an_event_usb_unknown_storage cy_as_event_usb_unknown_storage
+#define cy_an_event_usb_m_s_c_progress cy_as_event_usb_m_s_c_progress
+typedef cy_as_usb_event cy_an_usb_event;
+
+typedef cy_as_usb_event_callback_dep cy_an_usb_event_callback ;
+
+typedef cy_as_usb_io_callback cy_an_usb_io_callback;
+typedef cy_as_usb_function_callback cy_an_usb_function_callback;
+
+/******* USB Functions ********************/
+
+/* Sync Usb Start */
+extern cy_an_return_status_t
+cy_an_usb_start(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_start(handle) \
+ cy_as_usb_start((cy_as_device_handle)(handle), 0, 0)
+
+/*Async Usb Start */
+extern cy_an_return_status_t
+cy_an_usb_start_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_start_e_x(h, cb, client) \
+ cy_as_usb_start((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync Usb Stop */
+extern cy_an_return_status_t
+cy_an_usb_stop(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_stop(handle) \
+ cy_as_usb_stop((cy_as_device_handle)(handle), 0, 0)
+
+/*Async Usb Stop */
+extern cy_an_return_status_t
+cy_an_usb_stop_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_stop_e_x(h, cb, client) \
+ cy_as_usb_stop((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Register USB event callback */
+EXTERN cy_an_return_status_t
+cy_an_usb_register_callback(
+ cy_an_device_handle handle,
+ cy_an_usb_event_callback callback
+ ) ;
+#define cy_an_usb_register_callback(h, cb) \
+ cy_as_usb_register_callback_dep((cy_as_device_handle)(h), \
+ (cy_as_usb_event_callback_dep)(cb))
+
+/*Sync Usb connect */
+EXTERN cy_an_return_status_t
+cy_an_usb_connect(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_connect(handle) \
+ cy_as_usb_connect((cy_as_device_handle)(handle), 0, 0)
+
+/*Async Usb connect */
+extern cy_an_return_status_t
+cy_an_usb_connect_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_connect_e_x(h, cb, client) \
+ cy_as_usb_connect((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/*Sync Usb disconnect */
+EXTERN cy_an_return_status_t
+cy_an_usb_disconnect(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_disconnect(handle) \
+ cy_as_usb_disconnect((cy_as_device_handle)(handle), 0, 0)
+
+/*Async Usb disconnect */
+extern cy_an_return_status_t
+cy_an_usb_disconnect_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_disconnect_e_x(h, cb, client) \
+ cy_as_usb_disconnect((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of set enum config */
+EXTERN cy_an_return_status_t
+cy_an_usb_set_enum_config(
+ cy_an_device_handle handle,
+ cy_an_usb_enum_control *config_p
+ ) ;
+#define cy_an_usb_set_enum_config(handle, config_p) \
+ cy_as_usb_set_enum_config_dep((cy_as_device_handle)(handle), \
+ (cy_as_usb_enum_control_dep *)(config_p), 0, 0)
+
+/* Async version of set enum config */
+extern cy_an_return_status_t
+cy_an_usb_set_enum_config_e_x(
+ cy_an_device_handle handle,
+ cy_an_usb_enum_control *config_p,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_set_enum_config_e_x(h, config_p, cb, client) \
+ cy_as_usb_set_enum_config_dep((cy_as_device_handle)(h), \
+ (cy_as_usb_enum_control_dep *)(config_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of get enum config */
+EXTERN cy_an_return_status_t
+cy_an_usb_get_enum_config(
+ cy_an_device_handle handle,
+ cy_an_usb_enum_control *config_p
+ ) ;
+#define cy_an_usb_get_enum_config(handle, config_p) \
+ cy_as_usb_get_enum_config_dep((cy_as_device_handle)(handle), \
+ (cy_as_usb_enum_control_dep *)(config_p), 0, 0)
+
+/* Async version of get enum config */
+extern cy_an_return_status_t
+cy_an_usb_get_enum_config_e_x(
+ cy_an_device_handle handle,
+ cy_an_usb_enum_control *config_p,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_get_enum_config_e_x(h, config_p, cb, client) \
+ cy_as_usb_get_enum_config_dep((cy_as_device_handle)(h), \
+ (cy_as_usb_enum_control_dep *)(config_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync Version of Set descriptor */
+EXTERN cy_an_return_status_t
+cy_an_usb_set_descriptor(
+ cy_an_device_handle handle,
+ cy_an_usb_desc_type type,
+ uint8_t index,
+ void *desc_p,
+ uint16_t length
+ ) ;
+#define cy_an_usb_set_descriptor(handle, type, index, desc_p, length) \
+ cy_as_usb_set_descriptor((cy_as_device_handle)(handle), \
+ (cy_as_usb_desc_type)(type), (index), (desc_p), (length), 0, 0)
+
+/* Async Version of Set descriptor */
+extern cy_an_return_status_t
+cy_an_usb_set_descriptor_e_x(
+ cy_an_device_handle handle,
+ cy_an_usb_desc_type type,
+ uint8_t index,
+ void *desc_p,
+ uint16_t length,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_set_descriptor_e_x\
+ (h, type, index, desc_p, length, cb, client) \
+ cy_as_usb_set_descriptor((cy_as_device_handle)(h), \
+ (cy_as_usb_desc_type)(type), (index), (desc_p), (length), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Only version of clear descriptors */
+EXTERN cy_an_return_status_t
+cy_an_usb_clear_descriptors(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_clear_descriptors(h, cb, client) \
+ cy_as_usb_clear_descriptors((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of get descriptor*/
+EXTERN cy_an_return_status_t
+cy_an_usb_get_descriptor(
+ cy_an_device_handle handle,
+ cy_an_usb_desc_type type,
+ uint8_t index,
+ void *desc_p,
+ uint32_t *length_p
+ ) ;
+#define cy_an_usb_get_descriptor(h, type, index, desc_p, length_p) \
+ cy_as_usb_get_descriptor_dep((cy_as_device_handle)(h), \
+ (cy_as_usb_desc_type)(type), (index), (desc_p), (length_p))
+
+typedef cy_as_get_descriptor_data cy_an_get_descriptor_data ;
+
+/* Async version of get descriptor */
+extern cy_an_return_status_t
+cy_an_usb_get_descriptor_e_x(
+ cy_an_device_handle handle,
+ cy_an_usb_desc_type type,
+ uint8_t index,
+ cy_an_get_descriptor_data *data,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_get_descriptor_e_x\
+ (h, type, index, data, cb, client) \
+ cy_as_usb_get_descriptor((cy_as_device_handle)(h), \
+ (cy_as_usb_desc_type)(type), (index), \
+ (cy_as_get_descriptor_data *)(data), \
+ (cy_as_function_callback)(cb), (client))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_set_physical_configuration(
+ cy_an_device_handle handle,
+ uint8_t config
+ ) ;
+#define cy_an_usb_set_physical_configuration(h, config) \
+ cy_as_usb_set_physical_configuration\
+ ((cy_as_device_handle)(h), (config))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_set_end_point_config(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_end_point_config *config_p
+ ) ;
+#define cy_an_usb_set_end_point_config(h, ep, config_p) \
+ cy_as_usb_set_end_point_config((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_end_point_config *)(config_p))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_get_end_point_config(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_end_point_config *config_p
+ ) ;
+#define cy_an_usb_get_end_point_config(h, ep, config_p) \
+ cy_as_usb_get_end_point_config((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_end_point_config *)(config_p))
+
+/* Sync version of commit */
+EXTERN cy_an_return_status_t
+cy_an_usb_commit_config(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_commit_config(handle) \
+ cy_as_usb_commit_config((cy_as_device_handle)(handle), 0, 0)
+
+/* Async version of commit */
+extern cy_an_return_status_t
+cy_an_usb_commit_config_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_commit_config_e_x(h, cb, client) \
+ cy_as_usb_commit_config((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_read_data(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool pktread,
+ uint32_t dsize,
+ uint32_t *dataread,
+ void *data
+ ) ;
+#define cy_an_usb_read_data(h, ep, pkt, dsize, dataread, data_p) \
+ cy_as_usb_read_data((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (pkt), (dsize), \
+ (dataread), (data_p))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_read_data_async(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool pktread,
+ uint32_t dsize,
+ void *data,
+ cy_an_usb_io_callback callback
+ ) ;
+#define cy_an_usb_read_data_async(h, ep, pkt, dsize, data_p, cb) \
+ cy_as_usb_read_data_async((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (pkt), (dsize), (data_p), \
+ (cy_as_usb_io_callback)(cb))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_write_data(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ uint32_t dsize,
+ void *data
+ ) ;
+#define cy_an_usb_write_data(h, ep, dsize, data_p) \
+ cy_as_usb_write_data((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (dsize), (data_p))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_write_data_async(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ uint32_t dsize,
+ void *data,
+ cy_bool spacket,
+ cy_an_usb_io_callback callback
+ ) ;
+#define cy_an_usb_write_data_async(h, ep, dsize, data_p, spacket, cb) \
+ cy_as_usb_write_data_async((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (dsize), (data_p), (spacket), \
+ (cy_as_usb_io_callback)(cb))
+
+EXTERN cy_an_return_status_t
+cy_an_usb_cancel_async(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep
+ ) ;
+#define cy_an_usb_cancel_async(h, ep) \
+ cy_as_usb_cancel_async((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep))
+
+/* Sync version of set stall */
+EXTERN cy_an_return_status_t
+cy_an_usb_set_stall(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_function_callback cb,
+ uint32_t client
+) ;
+#define cy_an_usb_set_stall(h, ep, cb, client) \
+ cy_as_usb_set_stall_dep((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_function_callback)(cb), (client))
+
+/* Async version of set stall */
+extern cy_an_return_status_t
+cy_an_usb_set_stall_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_function_callback cb,
+ uint32_t client
+) ;
+#define cy_an_usb_set_stall_e_x(h, ep, cb, client) \
+ cy_as_usb_set_stall((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_function_callback)(cb), (client))
+
+/*Sync version of clear stall */
+EXTERN cy_an_return_status_t
+cy_an_usb_clear_stall(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_clear_stall(h, ep, cb, client) \
+ cy_as_usb_clear_stall_dep((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_function_callback)(cb), (client))
+
+/*Sync version of clear stall */
+extern cy_an_return_status_t
+cy_an_usb_clear_stall_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_clear_stall_e_x(h, ep, cb, client) \
+ cy_as_usb_clear_stall((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync get stall */
+EXTERN cy_an_return_status_t
+cy_an_usb_get_stall(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool *stall_p
+ ) ;
+#define cy_an_usb_get_stall(handle, ep, stall_p) \
+ cy_as_usb_get_stall((cy_as_device_handle)(handle), \
+ (cy_as_end_point_number_t)(ep), (stall_p), 0, 0)
+
+/* Async get stall */
+extern cy_an_return_status_t
+cy_an_usb_get_stall_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool *stall_p,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_get_stall_e_x(h, ep, stall_p, cb, client) \
+ cy_as_usb_get_stall((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (stall_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of Set Nak */
+EXTERN cy_an_return_status_t
+cy_an_usb_set_nak(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_function_callback cb,
+ uint32_t client
+) ;
+
+#define cy_an_usb_set_nak(h, ep, cb, client) \
+ cy_as_usb_set_nak_dep((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_function_callback)(cb), (client))
+
+/* Async version of Set Nak */
+extern cy_an_return_status_t
+cy_an_usb_set_nak_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_function_callback cb,
+ uint32_t client
+) ;
+#define cy_an_usb_set_nak_e_x(h, ep, cb, client) \
+ cy_as_usb_set_nak((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync version of clear nak */
+EXTERN cy_an_return_status_t
+cy_an_usb_clear_nak(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_usb_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_clear_nak(h, ep, cb, client) \
+ cy_as_usb_clear_nak_dep((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_usb_function_callback)(cb), (client))
+
+/* Sync version of clear nak */
+extern cy_an_return_status_t
+cy_an_usb_clear_nak_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_clear_nak_e_x(h, ep, cb, client) \
+ cy_as_usb_clear_nak((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync Get NAK */
+EXTERN cy_an_return_status_t
+cy_an_usb_get_nak(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool *nak_p
+) ;
+#define cy_an_usb_get_nak(handle, ep, nak_p) \
+ cy_as_usb_get_nak((cy_as_device_handle)(handle), \
+ (cy_as_end_point_number_t)(ep), (nak_p), 0, 0)
+
+/* Async Get NAK */
+EXTERN cy_an_return_status_t
+cy_an_usb_get_nak_e_x(
+ cy_an_device_handle handle,
+ cy_an_end_point_number_t ep,
+ cy_bool *nak_p,
+ cy_an_function_callback cb,
+ uint32_t client
+) ;
+#define cy_an_usb_get_nak_e_x(h, ep, nak_p, cb, client) \
+ cy_as_usb_get_nak((cy_as_device_handle)(h), \
+ (cy_as_end_point_number_t)(ep), (nak_p), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Sync remote wakup */
+EXTERN cy_an_return_status_t
+cy_an_usb_signal_remote_wakeup(
+ cy_an_device_handle handle
+ ) ;
+#define cy_an_usb_signal_remote_wakeup(handle) \
+ cy_as_usb_signal_remote_wakeup((cy_as_device_handle)(handle), 0, 0)
+
+/* Async remote wakup */
+EXTERN cy_an_return_status_t
+cy_an_usb_signal_remote_wakeup_e_x(
+ cy_an_device_handle handle,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_signal_remote_wakeup_e_x(h, cb, client) \
+ cy_as_usb_signal_remote_wakeup((cy_as_device_handle)(h), \
+ (cy_as_function_callback)(cb), (client))
+
+/* Only version of SetMSReportThreshold */
+EXTERN cy_an_return_status_t
+cy_an_usb_set_m_s_report_threshold(
+ cy_an_device_handle handle,
+ uint32_t wr_sectors,
+ uint32_t rd_sectors,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_set_m_s_report_threshold\
+ (h, wr_cnt, rd_cnt, cb, client) \
+ cy_as_usb_set_m_s_report_threshold((cy_as_device_handle)(h), \
+ wr_cnt, rd_cnt, (cy_as_function_callback)(cb), (client))
+
+/* Select storage partitions to be enumerated. */
+EXTERN cy_an_return_status_t
+cy_an_usb_select_m_s_partitions(
+ cy_an_device_handle handle,
+ cy_an_media_type media,
+ uint32_t device,
+ cy_an_usb_m_s_type_t type,
+ cy_an_function_callback cb,
+ uint32_t client
+ ) ;
+#define cy_an_usb_select_m_s_partitions(h, media, dev, type, cb, client) \
+ cy_as_usb_select_m_s_partitions_dep((cy_as_device_handle)(h), \
+ (cy_as_media_type)(media), (dev), \
+ (cy_as_usb_m_s_type_t)(type), (cy_as_function_callback)(cb), (client))
+
+#include "cyas_cplus_end.h"
+#endif /*__doxygen__*/
+#endif /*_INCLUDED_CYANUSB_H_*/
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h
new file mode 100644
index 000000000000..ece44ca34f3b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h
@@ -0,0 +1,11 @@
+/*
+ * This file is included at the end of other include files.
+ * It basically turns off the C++ specific code words that
+ * insure this code is seen as C code even within
+ * a C++ compiler.
+ *
+ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h
new file mode 100644
index 000000000000..b879cefa9d6b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h
@@ -0,0 +1,11 @@
+/*
+ * This file is included after all other headers files, but before any other
+ * definitions in the file. It basically insures that the definitions within
+ * the file are seen as C defintions even when compiled by a C++ compiler.
+ */
+
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h
new file mode 100644
index 000000000000..5f8c852fbb41
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h
@@ -0,0 +1,35 @@
+/* Cypress West Bridge API header file (cyascast.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASCAST_H_
+#define _INCLUDED_CYASCAST_H_
+
+#ifndef __doxygen__
+
+#ifdef _DEBUG
+#define cy_cast_int2U_int16(v) \
+ (cy_as_hal_assert(v < 65536), (uint16_t)(v))
+#else /* _DEBUG */
+#define cy_cast_int2U_int16(v) ((uint16_t)(v))
+#endif /* _DEBUG */
+
+#endif /* __doxygen__ */
+#endif /* _INCLUDED_CYASCAST_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h
new file mode 100644
index 000000000000..b17c985ed0ae
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h
@@ -0,0 +1,1057 @@
+/* Cypress West Bridge API header file (cyasdevice.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+##Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef __INCLUDED_CYASDEVICE_H__
+#define __INCLUDED_CYASDEVICE_H__
+
+#include "cyashal.h"
+#include "cyasprotocol.h"
+#include "cyasusb.h"
+#include "cyasstorage.h"
+#include "cyasmtp.h"
+#include "cyas_cplus_start.h"
+
+/***********************************
+ * West Bridge Constants
+ ***********************************/
+
+/* The endpoints used by West Bridge for the P port to S port path */
+#define CY_AS_P2S_WRITE_ENDPOINT (0x04)
+#define CY_AS_P2S_READ_ENDPOINT (0x08)
+
+/* The endpoint to use for firmware download */
+#define CY_AS_FIRMWARE_ENDPOINT (0x02)
+
+/* The maximum size of the firmware image West Bridge can accept */
+#define CY_AS_MAXIMUM_FIRMWARE_SIZE (24 * 1024)
+
+/* The maximum size of a write for EP0 and EP1 */
+#define CY_AS_EP0_MAX_WRITE_SIZE (128)
+#define CY_AS_EP1_MAX_WRITE_SIZE (64)
+
+/* The bitfields for the device state value */
+
+/* The device is in StandBy mode */
+#define CY_AS_DEVICE_STATE_PIN_STANDBY (0x00000001)
+/* The device has been configured */
+#define CY_AS_DEVICE_STATE_CONFIGURED (0x00000002)
+/* The firmware has been loaded into the device */
+#define CY_AS_DEVICE_STATE_FIRMWARE_LOADED (0x00000004)
+/* The interrupt module has been initialized */
+#define CY_AS_DEVICE_STATE_LOWLEVEL_MODULE (0x00000008)
+/* The DMA module has been initialized */
+#define CY_AS_DEVICE_STATE_DMA_MODULE (0x00000010)
+/* The interrupt module has been initialized */
+#define CY_AS_DEVICE_STATE_INTR_MODULE (0x00000020)
+/* The storage module has been initialized */
+#define CY_AS_DEVICE_STATE_STORAGE_MODULE (0x00000040)
+/* The USB module has been initialized */
+#define CY_AS_DEVICE_STATE_USB_MODULE (0x00000080)
+/* If set, the API wants SCSI messages */
+#define CY_AS_DEVICE_STATE_STORAGE_SCSIMSG (0x00000100)
+/* If set, an ASYNC storage operation is pending */
+#define CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING (0x00000200)
+/* If set, the USB port is connected */
+#define CY_AS_DEVICE_STATE_USB_CONNECTED (0x00000400)
+/* If set and USB is connected, it is high speed */
+#define CY_AS_DEVICE_STATE_USB_HIGHSPEED (0x00000800)
+/* If set, we are in a callback */
+#define CY_AS_DEVICE_STATE_IN_CALLBACK (0x00001000)
+/* If set, we are processing a setup packet */
+#define CY_AS_DEVICE_STATE_IN_SETUP_PACKET (0x00004000)
+/* The device was placed in standby via register */
+#define CY_AS_DEVICE_STATE_REGISTER_STANDBY (0x00008000)
+/* If set, the device is using a crystal */
+#define CY_AS_DEVICE_STATE_CRYSTAL (0x00010000)
+/* If set, wakeup has been called */
+#define CY_AS_DEVICE_STATE_WAKING (0x00020000)
+/* If set, EP0 has been stalled. */
+#define CY_AS_DEVICE_STATE_EP0_STALLED (0x00040000)
+/* If set, device is in suspend mode. */
+#define CY_AS_DEVICE_STATE_SUSPEND (0x00080000)
+/* If set, device is a reset is pending. */
+#define CY_AS_DEVICE_STATE_RESETP (0x00100000)
+/* If set, device is a standby is pending. */
+#define CY_AS_DEVICE_STATE_STANDP (0x00200000)
+/* If set, device has a storage start or stop pending. */
+#define CY_AS_DEVICE_STATE_SSSP (0x00400000)
+/* If set, device has a usb start or stop pending. */
+#define CY_AS_DEVICE_STATE_USSP (0x00800000)
+/* If set, device has a mtp start or stop pending. */
+#define CY_AS_DEVICE_STATE_MSSP (0x01000000)
+/* If set, P2S DMA transfer can be started. */
+#define CY_AS_DEVICE_STATE_P2SDMA_START (0x02000000)
+
+/* The bitfields for the endpoint state value */
+/* DMA requests are accepted into the queue */
+#define CY_AS_DMA_ENDPOINT_STATE_ENABLED (0x0001)
+/* The endpoint has a sleeping client, waiting on a queue drain */
+#define CY_AS_DMA_ENDPOINT_STATE_SLEEPING (0x0002)
+/* The DMA backend to hardware is running */
+#define CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING (0x0004)
+/* There is an outstanding DMA entry deployed to the HAL */
+#define CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT (0x0008)
+/* 0 = OUT (West Bridge -> P Port), 1 = IN (P Port -> West Bridge) */
+#define CY_AS_DMA_ENDPOINT_STATE_DIRECTION (0x0010)
+
+/* The state values for the request list */
+/* Mask for getting the state information */
+#define CY_AS_REQUEST_LIST_STATE_MASK (0x0f)
+/* The request is queued, nothing further */
+#define CY_AS_REQUEST_LIST_STATE_QUEUED (0x00)
+/* The request is sent, waiting for response */
+#define CY_AS_REQUEST_LIST_STATE_WAITING (0x01)
+/* The response has been received, processing reponse */
+#define CY_AS_REQUEST_LIST_STATE_RECEIVED (0x02)
+/* The request/response is being canceled */
+#define CY_AS_REQUEST_LIST_STATE_CANCELING (0x03)
+/* The request is synchronous */
+#define CY_AS_REQUEST_LIST_STATE_SYNC (0x80)
+
+/* The flag values for a LL RequestResponse */
+/* This request requires an ACK to be sent after it is completed */
+#define CY_AS_REQUEST_RESPONSE_DELAY_ACK (0x01)
+/* This request originated from a version V1.1 function call */
+#define CY_AS_REQUEST_RESPONSE_EX (0x02)
+/* This request originated from a version V1.2 function call */
+#define CY_AS_REQUEST_RESPONSE_MS (0x04)
+
+
+#define CY_AS_DEVICE_HANDLE_SIGNATURE (0x01211219)
+
+/*
+ * This macro returns the endpoint pointer given the
+ * device pointer and an endpoint number
+ */
+#define CY_AS_NUM_EP(dev_p, num) ((dev_p)->endp[(num)])
+
+/****************************************
+ * West Bridge Data Structures
+ ****************************************/
+
+typedef struct cy_as_device cy_as_device ;
+
+/* Summary
+ This type defines a callback function that will be called
+ on completion of a DMA operation.
+
+ Description
+ This function definition is for a function that is called when
+ the DMA operation is complete. This function is called with the
+ endpoint number, operation type, buffer pointer and size.
+
+ See Also
+ * CyAsDmaOper
+ * CyAsDmaQueueWrite
+ */
+typedef void (*cy_as_dma_callback)(
+ /* The device that completed DMA */
+ cy_as_device *dev_p,
+ /* The endpoint that completed DMA */
+ cy_as_end_point_number_t ep,
+ /* The pointer to the buffer that completed DMA */
+ void *mem_p,
+ /* The amount of data transferred */
+ uint32_t size,
+ /* The error code for this DMA xfer */
+ cy_as_return_status_t error
+ ) ;
+
+/* Summary
+ This structure defines a DMA request that is queued
+
+ Description
+ This structure contains the information about a DMA
+ request that is queued and is to be sent when possible.
+*/
+typedef struct cy_as_dma_queue_entry {
+ /* Pointer to memory buffer for this request */
+ void *buf_p ;
+ /* Size of the memory buffer for DMA operation */
+ uint32_t size ;
+ /* Offset into memory buffer for next DMA operation */
+ uint32_t offset ;
+ /* If TRUE and IN request */
+ cy_bool packet ;
+ /* If TRUE, this is a read request */
+ cy_bool readreq ;
+ /* Callback function for when DMA is complete */
+ cy_as_dma_callback cb ;
+ /* Pointer to next entry in queue */
+ struct cy_as_dma_queue_entry *next_p ;
+} cy_as_dma_queue_entry ;
+
+/* Summary
+ This structure defines the endpoint data for a given
+
+ Description
+ This structure defines all of the information required
+ to manage DMA for a given endpoint.
+*/
+typedef struct cy_as_dma_end_point {
+ /* The endpoint number */
+ cy_as_end_point_number_t ep ;
+ /* The state of this endpoint */
+ uint8_t state ;
+ /* The maximum amount of data accepted in a packet by the hw */
+ uint16_t maxhwdata ;
+ /* The maximum amount of data accepted by the HAL layer */
+ uint32_t maxhaldata ;
+ /* The queue for DMA operations */
+ cy_as_dma_queue_entry *queue_p ;
+ /* The last entry in the DMA queue */
+ cy_as_dma_queue_entry *last_p ;
+ /* This sleep channel is used to wait while the DMA queue
+ * drains for a given endpoint */
+ cy_as_hal_sleep_channel channel ;
+} cy_as_dma_end_point ;
+
+#define cy_as_end_point_number_is_usb(n) \
+ ((n) != 2 && (n) != 4 && (n) != 6 && (n) != 8)
+#define cy_as_end_point_number_is_storage(n) \
+ ((n) == 2 || (n) == 4 || (n) == 6 || (n) == 8)
+
+#define cy_as_dma_end_point_is_enabled(ep) \
+ ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_ENABLED)
+#define cy_as_dma_end_point_enable(ep) \
+ ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_ENABLED)
+#define cy_as_dma_end_point_disable(ep) \
+ ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_ENABLED)
+
+#define cy_as_dma_end_point_is_sleeping(ep) \
+ ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_SLEEPING)
+#define cy_as_dma_end_point_set_sleep_state(ep) \
+ ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_SLEEPING)
+#define cy_as_dma_end_point_set_wake_state(ep) \
+ ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_SLEEPING)
+
+#define cy_as_dma_end_point_is_running(ep) \
+ ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING)
+#define cy_as_dma_end_point_set_running(ep) \
+ ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING)
+#define cy_as_dma_end_point_set_stopped(ep) \
+ ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING)
+
+#define cy_as_dma_end_point_in_transit(ep) \
+ ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT)
+#define cy_as_dma_end_point_set_in_transit(ep) \
+ ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT)
+#define cy_as_dma_end_point_clear_in_transit(ep) \
+ ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT)
+
+#define cy_as_dma_end_point_is_direction_in(ep) \
+ (((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DIRECTION) == \
+ CY_AS_DMA_ENDPOINT_STATE_DIRECTION)
+#define cy_as_dma_end_point_is_direction_out(ep) \
+ (((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DIRECTION) == 0)
+#define cy_as_dma_end_point_set_direction_in(ep) \
+ ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_DIRECTION)
+#define cy_as_dma_end_point_set_direction_out(ep) \
+ ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_DIRECTION)
+
+#define cy_as_dma_end_point_is_usb(p) \
+ cy_as_end_point_number_is_usb((p)->ep)
+#define cy_as_dma_end_point_is_storage(p) \
+ cy_as_end_point_number_is_storage((p)->ep)
+
+typedef struct cy_as_ll_request_response {
+ /* The mbox[0] contents - see low level comm section of API doc */
+ uint16_t box0 ;
+ /* The amount of data stored in this request/response in bytes */
+ uint16_t stored ;
+ /* Length of this request in words */
+ uint16_t length ;
+ /* Additional status information about the request */
+ uint16_t flags ;
+ /* Note: This is over indexed and contains the request/response data */
+ uint16_t data[1] ;
+} cy_as_ll_request_response ;
+
+/*
+ * The callback function for responses
+ */
+typedef void (*cy_as_response_callback)(
+ /* The device that had the response */
+ cy_as_device *dev_p,
+ /* The context receiving a response */
+ uint8_t context,
+ /* The request data */
+ cy_as_ll_request_response *rqt,
+ /* The response data */
+ cy_as_ll_request_response *resp,
+ /* The status of the request */
+ cy_as_return_status_t status
+ ) ;
+
+typedef struct cy_as_ll_request_list_node {
+ /* The request to send */
+ cy_as_ll_request_response *rqt ;
+ /* The associated response for the request */
+ cy_as_ll_request_response *resp ;
+ /* Length of the response */
+ uint16_t length ;
+ /* The callback to call when done */
+ cy_as_response_callback callback ;
+ /* The state of the request */
+ uint8_t state ;
+ /* The next request in the list */
+ struct cy_as_ll_request_list_node *next ;
+} cy_as_ll_request_list_node ;
+
+#define cy_as_request_get_node_state(node_p) \
+ ((node_p)->state & CY_AS_REQUEST_LIST_STATE_MASK)
+#define cy_as_request_set_node_state(node_p, st) \
+ ((node_p)->state = \
+ ((node_p)->state & ~CY_AS_REQUEST_LIST_STATE_MASK) | (st))
+
+#define cy_as_request_node_is_sync(node_p) \
+ ((node_p)->state & CY_AS_REQUEST_LIST_STATE_SYNC)
+#define cy_as_request_node_set_sync(node_p) \
+ ((node_p)->state |= CY_AS_REQUEST_LIST_STATE_SYNC)
+#define cy_as_request_node_clear_sync(node_p) \
+ ((node_p)->state &= ~CY_AS_REQUEST_LIST_STATE_SYNC)
+
+#ifndef __doxygen__
+typedef enum cy_as_c_b_node_type {
+ CYAS_INVALID,
+ CYAS_USB_FUNC_CB,
+ CYAS_USB_IO_CB,
+ CYAS_STORAGE_IO_CB,
+ CYAS_FUNC_CB
+} cy_as_c_b_node_type ;
+
+typedef struct cy_as_func_c_b_node {
+ cy_as_c_b_node_type node_type ;
+ cy_as_function_callback cb_p ;
+ uint32_t client_data ;
+ cy_as_funct_c_b_type data_type ;
+ void *data ;
+ struct cy_as_func_c_b_node *next_p ;
+} cy_as_func_c_b_node;
+
+extern cy_as_func_c_b_node*
+cy_as_create_func_c_b_node_data(cy_as_function_callback
+ cb, uint32_t client, cy_as_funct_c_b_type type, void *data) ;
+
+extern cy_as_func_c_b_node*
+cy_as_create_func_c_b_node(cy_as_function_callback cb,
+ uint32_t client) ;
+
+extern void
+cy_as_destroy_func_c_b_node(cy_as_func_c_b_node *node) ;
+
+typedef struct cy_as_mtp_func_c_b_node {
+ cy_as_c_b_node_type type ;
+ cy_as_mtp_function_callback cb_p ;
+ uint32_t client_data;
+ struct cy_as_mtp_func_c_b_node *next_p ;
+} cy_as_mtp_func_c_b_node;
+
+extern cy_as_mtp_func_c_b_node*
+cy_as_create_mtp_func_c_b_node(cy_as_mtp_function_callback cb,
+ uint32_t client) ;
+
+extern void
+cy_as_destroy_mtp_func_c_b_node(cy_as_mtp_func_c_b_node *node) ;
+
+typedef struct cy_as_usb_func_c_b_node {
+ cy_as_c_b_node_type type ;
+ cy_as_usb_function_callback cb_p ;
+ uint32_t client_data;
+ struct cy_as_usb_func_c_b_node *next_p ;
+} cy_as_usb_func_c_b_node;
+
+extern cy_as_usb_func_c_b_node*
+cy_as_create_usb_func_c_b_node(cy_as_usb_function_callback cb,
+ uint32_t client) ;
+
+extern void
+cy_as_destroy_usb_func_c_b_node(cy_as_usb_func_c_b_node *node) ;
+
+typedef struct cy_as_usb_io_c_b_node {
+ cy_as_c_b_node_type type ;
+ cy_as_usb_io_callback cb_p ;
+ struct cy_as_usb_io_c_b_node *next_p ;
+} cy_as_usb_io_c_b_node;
+
+extern cy_as_usb_io_c_b_node*
+cy_as_create_usb_io_c_b_node(cy_as_usb_io_callback cb) ;
+
+extern void
+cy_as_destroy_usb_io_c_b_node(cy_as_usb_io_c_b_node *node) ;
+
+typedef struct cy_as_storage_io_c_b_node {
+ cy_as_c_b_node_type type ;
+ cy_as_storage_callback cb_p ;
+ /* The media for the currently outstanding async storage request */
+ cy_as_media_type media ;
+ /* The device index for the currently outstanding async storage
+ * request */
+ uint32_t device_index ;
+ /* The unit index for the currently outstanding async storage
+ * request */
+ uint32_t unit ;
+ /* The block address for the currently outstanding async storage
+ * request */
+ uint32_t block_addr ;
+ /* The operation for the currently outstanding async storage
+ * request */
+ cy_as_oper_type oper ;
+ cy_as_ll_request_response *req_p ;
+ cy_as_ll_request_response *reply_p ;
+ struct cy_as_storage_io_c_b_node *next_p ;
+} cy_as_storage_io_c_b_node;
+
+extern cy_as_storage_io_c_b_node*
+cy_as_create_storage_io_c_b_node(cy_as_storage_callback cb,
+ cy_as_media_type media, uint32_t device_index,
+ uint32_t unit, uint32_t block_addr, cy_as_oper_type oper,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p) ;
+
+extern void
+cy_as_destroy_storage_io_c_b_node(cy_as_storage_io_c_b_node *node) ;
+
+typedef struct cy_as_c_b_queue {
+ void *head_p;
+ void *tail_p;
+ uint32_t count ;
+ cy_as_c_b_node_type type ;
+} cy_as_c_b_queue ;
+
+extern cy_as_c_b_queue *
+cy_as_create_c_b_queue(cy_as_c_b_node_type type) ;
+
+extern void
+cy_as_destroy_c_b_queue(cy_as_c_b_queue *queue) ;
+
+/* Allocates a new CyAsCBNode */
+extern void
+cy_as_insert_c_b_node(cy_as_c_b_queue *queue_p, void *cbnode) ;
+
+/* Removes the first CyAsCBNode from the queue and frees it */
+extern void
+cy_as_remove_c_b_node(cy_as_c_b_queue *queue_p) ;
+
+/* Remove the last CyAsCBNode from the queue and frees it */
+extern void
+cy_as_remove_c_b_tail_node(cy_as_c_b_queue *queue_p) ;
+
+/* Removes and frees all pending callbacks */
+extern void
+cy_as_clear_c_b_queue(cy_as_c_b_queue *queue_p) ;
+
+extern cy_as_return_status_t
+cy_as_misc_send_request(cy_as_device *dev_p,
+ cy_as_function_callback cb,
+ uint32_t client,
+ cy_as_funct_c_b_type type,
+ void *data,
+ cy_as_c_b_queue *queue,
+ uint16_t req_type,
+ cy_as_ll_request_response *req_p,
+ cy_as_ll_request_response *reply_p,
+ cy_as_response_callback rcb) ;
+
+extern void
+cy_as_misc_cancel_ex_requests(cy_as_device *dev_p) ;
+
+/* Summary
+ Free all memory allocated by and zero all
+ structures initialized by CyAsUsbStart.
+ */
+extern void
+cy_as_usb_cleanup(
+ cy_as_device *dev_p) ;
+
+/* Summary
+ Free all memory allocated and zero all structures initialized
+ by CyAsStorageStart.
+ */
+extern void
+cy_as_storage_cleanup(
+ cy_as_device *dev_p) ;
+#endif
+
+/* Summary
+ This structure defines the data structure to support a
+ given command context
+
+ Description
+ All commands send to the West Bridge device via the mailbox
+ registers are sent via a context.Each context is independent
+ and there can be a parallel stream of requests and responses on
+ each context. This structure is used to manage a single context.
+*/
+typedef struct cy_as_context {
+ /* The context number for this context */
+ uint8_t number ;
+ /* This sleep channel is used to sleep while waiting on a
+ * response from the west bridge device for a request. */
+ cy_as_hal_sleep_channel channel ;
+ /* The buffer for received requests */
+ cy_as_ll_request_response *req_p ;
+ /* The length of the request being received */
+ uint16_t request_length ;
+ /* The callback for the next request received */
+ cy_as_response_callback request_callback ;
+ /* A list of low level requests to go to the firmware */
+ cy_as_ll_request_list_node *request_queue_p ;
+ /* The list node in the request queue */
+ cy_as_ll_request_list_node *last_node_p ;
+ /* Index upto which data is stored. */
+ uint16_t queue_index ;
+ /* Index to the next request in the queue. */
+ uint16_t rqt_index ;
+ /* Queue of data stored */
+ uint16_t data_queue[128] ;
+
+} cy_as_context ;
+
+#define cy_as_context_is_waiting(ctxt) \
+ ((ctxt)->state & CY_AS_CTXT_STATE_WAITING_RESPONSE)
+#define cy_as_context_set_waiting(ctxt) \
+ ((ctxt)->state |= CY_AS_CTXT_STATE_WAITING_RESPONSE)
+#define cy_as_context_clear_waiting(ctxt) \
+ ((ctxt)->state &= ~CY_AS_CTXT_STATE_WAITING_RESPONSE)
+
+
+
+/* Summary
+ This data structure stores SDIO function
+ parameters for a SDIO card
+
+ Description
+*/
+typedef struct cy_as_sdio_device {
+ /* Keeps track of IO functions initialized*/
+ uint8_t function_init_map;
+ uint8_t function_suspended_map;
+ /* Function 0 (Card Common) properties*/
+ cy_as_sdio_card card;
+ /* Function 1-7 (Mapped to array element 0-6) properties.*/
+ cy_as_sdio_func function[7];
+
+} cy_as_sdio_device;
+
+/* Summary
+Macros to access the SDIO card properties
+*/
+
+#define cy_as_sdio_get_function_code(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].function_code)
+
+#define cy_as_sdio_get_function_ext_code(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].\
+ function[i-1].extended_func_code)
+
+#define cy_as_sdio_get_function_p_s_n(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].card_psn)
+
+#define cy_as_sdio_get_function_blocksize(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].blocksize)
+
+#define cy_as_sdio_get_function_max_blocksize(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].maxblocksize)
+
+#define cy_as_sdio_get_function_csa_support(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].csa_bits)
+
+#define cy_as_sdio_get_function_wakeup_support(handle, bus, i) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1]. wakeup_support)
+
+#define cy_as_sdio_set_function_block_size(handle, bus, i, blocksize) \
+ (((cy_as_device *)handle)->sdiocard[bus].function[i-1].blocksize = \
+ blocksize)
+
+#define cy_as_sdio_get_card_num_functions(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.num_functions)
+
+#define cy_as_sdio_get_card_mem_present(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.memory_present)
+
+#define cy_as_sdio_get_card_manf_id(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.manufacturer__id)
+
+#define cy_as_sdio_get_card_manf_info(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.manufacturer_info)
+
+#define cy_as_sdio_get_card_blocksize(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.blocksize)
+
+#define cy_as_sdio_get_card_max_blocksize(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.maxblocksize)
+
+#define cy_as_sdio_get_card_sdio_version(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.sdio_version)
+
+#define cy_as_sdio_get_card_capability(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.card_capability)
+
+#define cy_as_sdio_get_function_init_map(handle, bus) \
+ (((cy_as_device *)handle)->sdiocard[bus].function_init_map)
+
+#define cy_as_sdio_check_function_initialized(handle, bus, i) \
+ (((cy_as_sdio_get_function_init_map(handle, bus)) & (0x01<<i)) ? 1 : 0)
+
+#define cy_as_sdio_set_card_block_size(handle, bus, blocksize) \
+ (((cy_as_device *)handle)->sdiocard[bus].card.blocksize = blocksize)
+
+#define cy_as_sdio_check_support_bus_suspend(handle, bus) \
+ ((cy_as_sdio_get_card_capability(handle, bus) & CY_SDIO_SBS) ? 1 : 0)
+
+#define cy_as_sdio_check_function_suspended(handle, bus, i) \
+ ((((cy_as_device *)handle)->sdiocard[bus].function_suspended_map & \
+ (0x01<<i)) ? 1 : 0)
+
+#define cy_as_sdio_set_function_suspended(handle, bus, i) \
+ ((((cy_as_device *)handle)->sdiocard[bus].function_suspended_map) \
+ |= (0x01<<i))
+
+#define cy_as_sdio_clear_function_suspended(handle, bus, i) \
+ ((((cy_as_device *)handle)->sdiocard[bus].function_suspended_map) \
+ &= (~(0x01<<i)))
+
+/* Summary
+ This data structure represents a single device.
+
+ Description
+*/
+struct cy_as_device {
+ /* General stuff */
+ /* A signature to insure we have a valid handle */
+ uint32_t sig ;
+ /* The ID of the silicon */
+ uint16_t silicon_id ;
+ /* Pointer to the next device */
+ struct cy_as_device *next_p ;
+ /* This is the client specific tag for this device */
+ cy_as_hal_device_tag tag ;
+ /* This contains various state information about the device */
+ uint32_t state ;
+ /* Flag indicating whether INT# pin is used for DRQ */
+ cy_bool use_int_drq ;
+
+ /* DMA related */
+ /* The endpoint pointers associated with this device */
+ cy_as_dma_end_point *endp[16] ;
+ /* List of queue entries that can be used for xfers */
+ cy_as_dma_queue_entry *dma_freelist_p ;
+
+ /* Low level comm related */
+ /* The contexts available in this device */
+ cy_as_context *context[CY_RQT_CONTEXT_COUNT] ;
+ /* The low level error returned from sending an async request */
+ cy_as_return_status_t ll_error ;
+ /* A request is currently being sent to West Bridge. */
+ cy_bool ll_sending_rqt ;
+ /* The current mailbox request should be aborted. */
+ cy_bool ll_abort_curr_rqt ;
+ /* Indicates that the LL layer has queued mailbox data. */
+ cy_bool ll_queued_data ;
+
+ /* MISC API related */
+ /* Misc callback */
+ cy_as_misc_event_callback misc_event_cb ;
+
+ /* Storage Related */
+ /* The reference count for the Storage API */
+ uint32_t storage_count ;
+ /* Callback for storage events */
+ cy_as_storage_event_callback_dep storage_event_cb ;
+ /* V1.2+ callback for storage events */
+ cy_as_storage_event_callback storage_event_cb_ms ;
+ /* The error for a sleeping storage operation */
+ cy_as_return_status_t storage_error ;
+ /* Flag indicating that the storage stack is waiting for an operation */
+ cy_bool storage_wait ;
+ /* Request used for storage read/writes. */
+ cy_as_ll_request_response *storage_rw_req_p ;
+ /* Response used for storage read/writes. */
+ cy_as_ll_request_response *storage_rw_resp_p ;
+ /* The storage callback */
+ cy_as_storage_callback_dep storage_cb ;
+ /* The V1.2+ storage callback */
+ cy_as_storage_callback storage_cb_ms ;
+ /* The bus index for the currently outstanding async storage request */
+ cy_as_bus_number_t storage_bus_index ;
+ /* The device index for the currently outstanding async storage
+ * request */
+ uint32_t storage_device_index ;
+ /* The unit index for the currently outstanding async storage request */
+ uint32_t storage_unit ;
+ /* The block address for the currently outstanding async storage
+ * request */
+ uint32_t storage_block_addr ;
+ /* The operation for the currently outstanding async storage request */
+ cy_as_oper_type storage_oper ;
+ /* The endpoint used to read Storage data */
+ cy_as_end_point_number_t storage_read_endpoint ;
+ /* The endpoint used to write endpoint data */
+ cy_as_end_point_number_t storage_write_endpoint ;
+ cy_as_device_desc storage_device_info
+ [CY_AS_MAX_BUSES][CY_AS_MAX_STORAGE_DEVICES] ;
+ /* The information on each device on each bus */
+
+ /* USB Related */
+ /* This conatins the endpoint async state */
+ uint16_t epasync ;
+ /* The reference count for the USB API */
+ uint32_t usb_count ;
+ /* The physical endpoint configuration */
+ uint8_t usb_phy_config ;
+ /* The callbacks for async func calls */
+ cy_as_c_b_queue *usb_func_cbs ;
+ /* Endpoint configuration information */
+ cy_as_usb_end_point_config usb_config[16] ;
+ /* The USB callback */
+ cy_as_usb_event_callback_dep usb_event_cb ;
+ /* The V1.2+ USB callback */
+ cy_as_usb_event_callback usb_event_cb_ms ;
+ /* The error for a sleeping usb operation */
+ cy_as_return_status_t usb_error ;
+ /* The USB callback for a pending storage operation */
+ cy_as_usb_io_callback usb_cb[16] ;
+ /* The buffer pending from a USB operation */
+ void *usb_pending_buffer ;
+ /* The size of the buffer pending from a USB operation */
+ uint32_t usb_pending_size ;
+ /* If true, send a short packet */
+ cy_bool usb_spacket[16] ;
+ /* The amount of data actually xferred */
+ uint32_t usb_actual_cnt ;
+ /* EP1OUT and EP1IN config register contents */
+ uint8_t usb_ep1cfg[2] ;
+ /* LEP config register contents */
+ uint16_t usb_lepcfg[10] ;
+ /* PEP config register contents */
+ uint16_t usb_pepcfg[4] ;
+ /* Buffer for EP0 and EP1 data sent via mailboxes */
+ uint8_t *usb_ep_data ;
+ /* Used to track how many ack requests are pending */
+ uint32_t usb_delay_ack_count ;
+ /* Maximum transfer size for USB endpoints. */
+ uint32_t usb_max_tx_size ;
+
+ /* Request for sending EP0 data to West Bridge */
+ cy_as_ll_request_response *usb_ep0_dma_req ;
+ /* Response for EP0 data sent to West Bridge */
+ cy_as_ll_request_response *usb_ep0_dma_resp ;
+ /* Request for sending EP1 data to West Bridge */
+ cy_as_ll_request_response *usb_ep1_dma_req ;
+ /* Response for EP1 data sent to West Bridge */
+ cy_as_ll_request_response *usb_ep1_dma_resp ;
+
+ cy_as_ll_request_response *usb_ep0_dma_req_save ;
+ cy_as_ll_request_response *usb_ep0_dma_resp_save ;
+
+ /* MTP Related */
+ /* The reference count for the MTP API */
+ uint32_t mtp_count ;
+ /* The MTP event callback supplied by the client */
+ cy_as_mtp_event_callback mtp_event_cb ;
+ /* The current block table to be transfered */
+ cy_as_mtp_block_table *tp_blk_tbl ;
+
+ cy_as_c_b_queue *func_cbs_mtp ;
+ cy_as_c_b_queue *func_cbs_usb ;
+ cy_as_c_b_queue *func_cbs_stor ;
+ cy_as_c_b_queue *func_cbs_misc ;
+ cy_as_c_b_queue *func_cbs_res ;
+
+ /* The last USB event that was received */
+ cy_as_usb_event usb_last_event ;
+ /* Types of storage media supported by the firmware */
+ uint8_t media_supported[CY_AS_MAX_BUSES] ;
+
+ /* SDIO card parameters*/
+ cy_as_sdio_device sdiocard[CY_AS_MAX_BUSES];
+ /* if true, MTP enabled Firmware. */
+ cy_bool is_mtp_firmware ;
+ /* if true, mailbox message has come already */
+ cy_bool is_mtp_data_pending ;
+ /* True between the time an Init was called and
+ * the complete event is generated */
+ cy_bool mtp_turbo_active ;
+ /* mbox reported EP 2 data len */
+ uint16_t mtp_data_len ;
+ /* The error for mtp EP4 write operation */
+ cy_as_return_status_t mtp_error ;
+ /* mtp send/get operation callback */
+ cy_as_function_callback mtp_cb ;
+ /* mtp send/get operation client id */
+ uint32_t mtp_client ;
+ /* mtp operation type. To be used in callback */
+ cy_as_funct_c_b_type mtp_op ;
+
+ /* Firmware is running in P2S only mode. */
+ cy_bool is_storage_only_mode ;
+ /* Interrupt mask value during device standby. */
+ uint32_t stby_int_mask ;
+} ;
+
+#define cy_as_device_is_configured(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_CONFIGURED)
+#define cy_as_device_set_configured(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_CONFIGURED)
+#define cy_as_device_set_unconfigured(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_CONFIGURED)
+
+#define cy_as_device_is_dma_running(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_DMA_MODULE)
+#define cy_as_device_set_dma_running(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_DMA_MODULE)
+#define cy_as_device_set_dma_stopped(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_DMA_MODULE)
+
+#define cy_as_device_is_low_level_running(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_LOWLEVEL_MODULE)
+#define cy_as_device_set_low_level_running(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_LOWLEVEL_MODULE)
+#define cy_as_device_set_low_level_stopped(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_LOWLEVEL_MODULE)
+
+#define cy_as_device_is_intr_running(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_INTR_MODULE)
+#define cy_as_device_set_intr_running(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_INTR_MODULE)
+#define cy_as_device_set_intr_stopped(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_INTR_MODULE)
+
+#define cy_as_device_is_firmware_loaded(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_FIRMWARE_LOADED)
+#define cy_as_device_set_firmware_loaded(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_FIRMWARE_LOADED)
+#define cy_as_device_set_firmware_not_loaded(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_FIRMWARE_LOADED)
+
+#define cy_as_device_is_storage_running(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_STORAGE_MODULE)
+#define cy_as_device_set_storage_running(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_MODULE)
+#define cy_as_device_set_storage_stopped(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_MODULE)
+
+#define cy_as_device_is_usb_running(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_USB_MODULE)
+#define cy_as_device_set_usb_running(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_USB_MODULE)
+#define cy_as_device_set_usb_stopped(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_MODULE)
+
+#define cy_as_device_wants_scsi_messages(dp) \
+ (((dp)->state & CY_AS_DEVICE_STATE_STORAGE_SCSIMSG) \
+ ? cy_true : cy_false)
+#define cy_as_device_set_scsi_messages(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_SCSIMSG)
+#define cy_as_device_clear_scsi_messages(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_SCSIMSG)
+
+#define cy_as_device_is_storage_async_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING)
+#define cy_as_device_set_storage_async_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING)
+#define cy_as_device_clear_storage_async_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING)
+
+#define cy_as_device_is_usb_connected(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_USB_CONNECTED)
+#define cy_as_device_set_usb_connected(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_USB_CONNECTED)
+#define cy_as_device_clear_usb_connected(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_CONNECTED)
+
+#define cy_as_device_is_usb_high_speed(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_USB_HIGHSPEED)
+#define cy_as_device_set_usb_high_speed(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_USB_HIGHSPEED)
+#define cy_as_device_clear_usb_high_speed(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_HIGHSPEED)
+
+#define cy_as_device_is_in_callback(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_IN_CALLBACK)
+#define cy_as_device_set_in_callback(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_IN_CALLBACK)
+#define cy_as_device_clear_in_callback(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_IN_CALLBACK)
+
+#define cy_as_device_is_setup_i_o_performed(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED)
+#define cy_as_device_set_setup_i_o_performed(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED)
+#define cy_as_device_clear_setup_i_o_performed(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED)
+
+#define cy_as_device_is_ack_delayed(dp) \
+ ((dp)->usb_delay_ack_count > 0)
+#define cy_as_device_set_ack_delayed(dp) \
+ ((dp)->usb_delay_ack_count++)
+#define cy_as_device_rem_ack_delayed(dp) \
+ ((dp)->usb_delay_ack_count--)
+#define cy_as_device_clear_ack_delayed(dp) \
+ ((dp)->usb_delay_ack_count = 0)
+
+#define cy_as_device_is_setup_packet(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_IN_SETUP_PACKET)
+#define cy_as_device_set_setup_packet(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_IN_SETUP_PACKET)
+#define cy_as_device_clear_setup_packet(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_IN_SETUP_PACKET)
+
+#define cy_as_device_is_ep0_stalled(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_EP0_STALLED)
+#define cy_as_device_set_ep0_stalled(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_EP0_STALLED)
+#define cy_as_device_clear_ep0_stalled(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_EP0_STALLED)
+
+#define cy_as_device_is_register_standby(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_REGISTER_STANDBY)
+#define cy_as_device_set_register_standby(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_REGISTER_STANDBY)
+#define cy_as_device_clear_register_standby(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_REGISTER_STANDBY)
+
+#define cy_as_device_is_pin_standby(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_PIN_STANDBY)
+#define cy_as_device_set_pin_standby(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_PIN_STANDBY)
+#define cy_as_device_clear_pin_standby(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_PIN_STANDBY)
+
+#define cy_as_device_is_crystal(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_CRYSTAL)
+#define cy_as_device_is_external_clock(dp) \
+ (!((dp)->state & CY_AS_DEVICE_STATE_CRYSTAL))
+#define cy_as_device_set_crystal(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_CRYSTAL)
+#define cy_as_device_set_external_clock(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_CRYSTAL)
+
+#define cy_as_device_is_waking(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_WAKING)
+#define cy_as_device_set_waking(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_WAKING)
+#define cy_as_device_clear_waking(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_WAKING)
+
+#define cy_as_device_is_in_suspend_mode(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_SUSPEND)
+#define cy_as_device_set_suspend_mode(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_SUSPEND)
+#define cy_as_device_clear_suspend_mode(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_SUSPEND)
+
+#define cy_as_device_is_reset_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_RESETP)
+#define cy_as_device_set_reset_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_RESETP)
+#define cy_as_device_clear_reset_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_RESETP)
+
+#define cy_as_device_is_standby_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_STANDP)
+#define cy_as_device_set_standby_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_STANDP)
+#define cy_as_device_clear_standby_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_STANDP)
+
+#define cy_as_device_is_s_s_s_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_SSSP)
+#define cy_as_device_set_s_s_s_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_SSSP)
+#define cy_as_device_clear_s_s_s_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_SSSP)
+
+#define cy_as_device_is_u_s_s_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_USSP)
+#define cy_as_device_set_u_s_s_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_USSP)
+#define cy_as_device_clear_u_s_s_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_USSP)
+
+#define cy_as_device_is_m_s_s_pending(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_MSSP)
+#define cy_as_device_set_m_s_s_pending(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_MSSP)
+#define cy_as_device_clear_m_s_s_pending(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_MSSP)
+
+#define cy_as_device_is_p2s_dma_start_recvd(dp) \
+ ((dp)->state & CY_AS_DEVICE_STATE_P2SDMA_START)
+#define cy_as_device_set_p2s_dma_start_recvd(dp) \
+ ((dp)->state |= CY_AS_DEVICE_STATE_P2SDMA_START)
+#define cy_as_device_clear_p2s_dma_start_recvd(dp) \
+ ((dp)->state &= ~CY_AS_DEVICE_STATE_P2SDMA_START)
+
+#define cy_as_device_is_usb_async_pending(dp, ep) \
+ ((dp)->epasync & (1 << ep))
+#define cy_as_device_set_usb_async_pending(dp, ep) \
+ ((dp)->epasync |= (1 << ep))
+#define cy_as_device_clear_usb_async_pending(dp, ep) \
+ ((dp)->epasync &= ~(1 << ep))
+
+#define cy_as_device_is_nand_storage_supported(dp) \
+ ((dp)->media_supported[0] & 1)
+
+/* Macros to check the type of West Bridge device. */
+#define cy_as_device_is_astoria_dev(dp) \
+ (((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE) || \
+ ((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE))
+#define cy_as_device_is_antioch_dev(dp) \
+ ((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE)
+
+#ifdef CY_AS_LOG_SUPPORT
+extern void cy_as_log_debug_message(int value, const char *msg) ;
+#else
+#define cy_as_log_debug_message(value, msg)
+#endif
+
+/* Summary
+ This function finds the device object given the HAL tag
+
+ Description
+ The user associats a device TAG with each West Bridge device
+ created. This tag is passed from the API functions to and HAL
+ functions that need to ID a specific West Bridge device. This
+ tag is also passed in from the user back into the API via
+ interrupt functions. This function allows the API to find the
+ device structure associated with a given tag.
+
+ Notes
+ This function does a simple linear search for the device based
+ on the TAG. This function is called each time an West Bridge
+ interrupt handler is called. Therefore this works fine for a
+ small number of West Bridge devices (e.g. less than five).
+ Anything more than this and this methodology will need to be
+ updated.
+
+ Returns
+ Pointer to a CyAsDevice associated with the tag
+*/
+extern cy_as_device *
+cy_as_device_find_from_tag(
+ cy_as_hal_device_tag tag
+ ) ;
+
+#include "cyas_cplus_end.h"
+
+#endif /* __INCLUDED_CYASDEVICE_H__ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h
new file mode 100644
index 000000000000..c97f9876fc4c
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h
@@ -0,0 +1,375 @@
+/* Cypress West Bridge API header file (cyasdma.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASDMA_H_
+#define _INCLUDED_CYASDMA_H_
+
+#include "cyashal.h"
+#include "cyasdevice.h"
+
+#include "cyas_cplus_start.h"
+
+
+/*@@DMA Overview
+ This module manages the DMA operations to/from the West Bridge
+ device. The DMA module maintains a DMA queue for each endpoint
+ so multiple DMA requests may be queued and they will complete
+ at some future time.
+
+ The DMA module must be started before it can be used. It is
+ started by calling CyAsDmaStart(). This function intializes
+ all of the endpoint data structures.
+
+ In order to perform DMA on a particular endpoint, the endpoint
+ must be enabled by calling CyAsDmaEnableEndPoint(). In addition
+ to enabling or disabling the endpoint, this function also sets
+ the direction for a given endpoint. Direction is given in USB
+ terms. For P port to West Bridge traffic, the endpoint is a
+ CyAsDirectionIn endpoint. For West Bridge to P port traffic,
+ the endpoint is a CyAsDirectionOut endpoint.
+
+ Once DMA is started and an endpoint is enabled, DMA requests
+ are issued by calling CyAsDmaQueueRequest(). This function
+ queue either a DMA read or DMA write request. The callback
+ associated with the request is called once the request has been
+ fulfilled.
+
+ See Also
+ * CyAsDmaStart
+ * CyAsDmaEnableEndPoint
+ * CyAsDmaDirection
+ * CyAsDmaQueueRequest
+ */
+
+/************************
+ * West Bridge Constants
+ ************************/
+#define CY_AS_DMA_MAX_SIZE_HW_SIZE (0xffffffff)
+
+/************************
+ * West Bridge Data Structures
+ ************************/
+
+/* Summary
+ This type specifies the direction of an endpoint to the
+ CyAsDmaEnableEndPoint function.
+
+ Description
+ When an endpoint is enabled, the direction of the endpoint
+ can also be set. This type is used to specify the endpoint
+ type. Note that the direction is specified in USB terms.
+ Therefore, if the DMA is from the P port to West Bridge,
+ the direction is IN.
+
+ See Also
+ * CyAsDmaEnableEndPoint
+*/
+typedef enum cy_as_dma_direction {
+ /* Set the endpoint to type IN (P -> West Bridge) */
+ cy_as_direction_in = 0,
+ /* Set the endpoint to type OUT (West Bridge -> P) */
+ cy_as_direction_out = 1,
+ /* Only valid for EP 0 */
+ cy_as_direction_in_out = 2,
+ /* Do no change the endpoint type */
+ cy_as_direction_dont_change = 3
+} cy_as_dma_direction ;
+
+/*********************************
+ * West Bridge Functions
+ *********************************/
+
+/* Summary
+ Initialize the DMA module and ready the module for receiving data
+
+ Description
+ This function initializes the DMA module by initializing all of
+ the endpoint data structures associated with the device given.
+ This function also register a DMA complete callback with the HAL
+ DMA code. This callback is called whenever the HAL DMA subsystem
+ completes a requested DMA operation.
+
+ Returns
+ CY_AS_ERROR_SUCCESS - the module initialized sucessfully
+ CY_AS_ERROR_OUT_OF_MEMORY - memory allocation failed during
+ initialization
+ CY_AS_ERROR_ALREADY_RUNNING - the DMA module was already running
+
+ See Also
+ * CyAsDmaStop
+*/
+extern cy_as_return_status_t
+cy_as_dma_start(
+ /* The device to start */
+ cy_as_device *dev_p
+ ) ;
+
+/* Summary
+ Shutdown the DMA module
+
+ Description
+ This function shuts down the DMA module for this device by
+ canceling any DMA requests associated with each endpoint and
+ then freeing the resources associated with each DMA endpoint.
+
+ Returns
+ CY_AS_ERROR_SUCCESS - the module shutdown sucessfully
+ CY_AS_ERROR_NOT_RUNNING - the DMA module was not running
+
+ See Also
+ * CyAsDmaStart
+ * CyAsDmaCancel
+*/
+extern cy_as_return_status_t
+cy_as_dma_stop(
+ /* The device to stop */
+ cy_as_device *dev_p
+ ) ;
+
+/* Summary
+ This function cancels all outstanding DMA requests on a given endpoint
+
+ Description
+ This function cancels any DMA requests outstanding on a given endpoint
+ by disabling the transfer of DMA requests from the queue to the HAL
+ layer and then removing any pending DMA requests from the queue. The
+ callback associated with any DMA requests that are being removed is
+ called with an error code of CY_AS_ERROR_CANCELED.
+
+ Notes
+ If a request has already been sent to the HAL layer it will be
+ completed and not canceled. Only requests that have not been sent to
+ the HAL layer will be cancelled.
+
+ Returns
+ CY_AS_ERROR_SUCCESS - the traffic on the endpoint is canceled
+ sucessfully
+
+ See Also
+*/
+extern cy_as_return_status_t
+cy_as_dma_cancel(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to cancel */
+ cy_as_end_point_number_t ep,
+ cy_as_return_status_t err
+ ) ;
+
+/* Summary
+ This function enables a single endpoint for DMA operations
+
+ Description
+ In order to enable the queuing of DMA requests on a given
+ endpoint, the endpoint must be enabled for DMA. This function
+ enables a given endpoint. In addition, this function sets the
+ direction of the DMA operation.
+
+ Returns
+ * CY_AS_ERROR_INVALID_ENDPOINT - invalid endpoint number
+ * CY_AS_ERROR_SUCCESS - endpoint was enabled or disabled
+ * successfully
+
+ See Also
+ * CyAsDmaQueueRequest
+*/
+extern cy_as_return_status_t
+cy_as_dma_enable_end_point(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to enable or disable */
+ cy_as_end_point_number_t ep,
+ /* CyTrue to enable, CyFalse to disable */
+ cy_bool enable,
+ /* The direction of the endpoint */
+ cy_as_dma_direction dir
+) ;
+
+/* Summary
+ This function queue a DMA request for a given endpoint
+
+ Description
+ When an West Bridge API module wishes to do a DMA operation,
+ this function is called on the associated endpoint to queue
+ a DMA request. When the DMA request has been fulfilled, the
+ callback associated with the DMA operation is called.
+
+ Notes
+ The buffer associated with the DMA request, must remain valid
+ until after the callback function is calld.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the DMA operation was queued successfully
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint number was invalid
+ * CY_AS_ERROR_ENDPOINT_DISABLED - the endpoint was disabled
+ * CY_AS_ERROR_OUT_OF_MEMORY - out of memory processing the request
+
+ See Also
+ * CyAsDmaEnableEndPoint
+ * CyAsDmaCancel
+*/
+extern cy_as_return_status_t
+cy_as_dma_queue_request(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to receive a new request */
+ cy_as_end_point_number_t ep,
+ /* The memory buffer for the DMA request -
+ * must be valid until after the callback has been called */
+ void *mem_p,
+ /* The size of the DMA request in bytes */
+ uint32_t size,
+ /* If true and a DMA read request, return the next packet
+ * regardless of size */
+ cy_bool packet,
+ /* If true, this is a read request,
+ * otherwise it is a write request */
+ cy_bool readreq,
+ /* The callback to call when the DMA request is complete,
+ * either successfully or via an error */
+ cy_as_dma_callback cb
+ ) ;
+
+/* Summary
+ This function waits until all DMA requests on a given endpoint
+ have been processed and then return
+
+ Description
+ There are times when a module in the West Bridge API needs to
+ wait until the DMA operations have been queued. This function
+ sleeps until all DMA requests have been fulfilled and only then
+ returns to the caller.
+
+ Notes
+ I don't think we will need a list of sleeping clients to support
+ multiple parallel client modules sleeping on a single endpoint,
+ but if we do instead of having a single sleep channel in the
+ endpoint, each client will have to supply a sleep channel and we
+ will have to maintain a list of sleep channels to wake.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the queue has drained sucessfully
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given is not valid
+ * CY_AS_ERROR_NESTED_SLEEP - CyAsDmaQueueRequest() was requested
+ * on an endpoint where CyAsDmaQueueRequest was already called
+*/
+extern cy_as_return_status_t
+cy_as_dma_drain_queue(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to drain */
+ cy_as_end_point_number_t ep,
+ /* If CyTrue, call kickstart to start the DMA process,
+ if cy_false, west bridge will start the DMA process */
+ cy_bool kickstart
+ ) ;
+
+/* Summary
+ Sets the maximum amount of data West Bridge can accept in a single
+ DMA Operation for the given endpoint
+
+ Description
+ Depending on the configuration of the West Bridge device endpoint,
+ the amount of data that can be accepted varies. This function
+ sets the maximum amount of data West Bridge can accept in a single
+ DMA operation. The value is stored with the endpoint and passed
+ to the HAL layer in the CyAsHalDmaSetupWrite() and
+ CyAsHalDmaSetupRead() functoins.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the value was set sucessfully
+ * CY_AS_ERROR_INVALID_SIZE - the size value was not valid
+*/
+extern cy_as_return_status_t
+cy_as_dma_set_max_dma_size(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to change */
+ cy_as_end_point_number_t ep,
+ /* The max size of this endpoint in bytes */
+ uint32_t size
+ ) ;
+
+/* Summary
+ This function starts the DMA process on a given channel.
+
+ Description
+ When transferring data from the P port processor to West
+ Bridge, the DMA operation must be initiated P Port software
+ for the first transfer. Subsequent transferrs will be
+ handled at the interrupt level.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+*/
+extern cy_as_return_status_t
+cy_as_dma_kick_start(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint to change */
+ cy_as_end_point_number_t ep
+ ) ;
+
+/* Summary
+ This function receives endpoint data from a request.
+
+ Description
+ For endpoint 0 and 1 the endpoint data is transferred from
+ the West Bridge device to the DMA via a lowlevel
+ requests (via the mailbox registers).
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+*/
+extern cy_as_return_status_t
+cy_as_dma_received_data(
+ /* The device of interest */
+ cy_as_device *dev_p,
+ /* The endpoint that received data */
+ cy_as_end_point_number_t ep,
+ /* The data size */
+ uint32_t dsize,
+ /* The data buffer */
+ void *data
+ );
+
+/* Summary
+ This function is called when the DMA operation on
+ an endpoint has been completed.
+
+ Returns
+ * void
+ */
+extern void
+cy_as_dma_completed_callback(
+ /* Tag to HAL completing the DMA operation. */
+ cy_as_hal_device_tag tag,
+ /* Endpoint on which DMA has been completed. */
+ cy_as_end_point_number_t ep,
+ /* Length of data received. */
+ uint32_t length,
+ /* Status of DMA operation. */
+ cy_as_return_status_t status
+ ) ;
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASDMA_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h
new file mode 100644
index 000000000000..f78d60270d45
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h
@@ -0,0 +1,1094 @@
+/* Cypress West Bridge API header file (cyaserr.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASERR_H_
+#define _INCLUDED_CYASERR_H_
+
+/*@@West Bridge Errors
+ Summary
+ This section lists the error codes for West Bridge.
+
+*/
+
+/* Summary
+ The function completed sucessfully
+*/
+#define CY_AS_ERROR_SUCCESS (0)
+
+/* Summary
+ A function trying to acquire a resource was unable to do so.
+
+ Description
+ This code indicates that a resource that the API was trying to claim
+ could not be claimed.
+
+ See Also
+ * CyAsMiscAcquireResource
+ * CyAsStorageClaim
+*/
+#define CY_AS_ERROR_NOT_ACQUIRED (1)
+
+/* Summary
+ A function trying to acquire a resource was unable to do so.
+
+ Description
+ The West Bridge API provides the capability to assign the storage media to
+ either the West Bridge device or the USB port. This error indicates the
+ P port was trying to release a storage media and was not able to do
+ so. This generally means it was not owned by the P port processor.
+
+ See Also
+ * CyAsStorageRelease
+*/
+#define CY_AS_ERROR_NOT_RELEASED (2)
+
+/* Summary
+ The West Bridge firmware is not loaded.
+
+ Description
+ Most of the API functions that are part of the West Bridge API rely on
+ firmware running on the West Bridge device. This error code is
+ returned when one of these functions is called and the firmware has
+ not yet been loaded.
+
+ See Also
+ * CyAsMiscGetFirmwareVersion
+ * CyAsMiscReset
+ * CyAsMiscAcquireResource
+ * CyAsMiscReleaseResource
+ * CyAsMiscSetTraceLevel
+ * CyAsStorageStart
+ * CyAsStorageStop
+ * CyAsStorageRegisterCallback
+ * CyAsStorageClaim
+ * CyAsStorageRelease
+ * CyAsStorageQueryMedia
+ * CyAsStorageQueryDevice
+ * CyAsStorageQueryUnit
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_NO_FIRMWARE (3)
+
+/* Summary
+ A timeout occurred waiting on a response from the West Bridge device
+
+ Description
+ When requests are made of the West Bridge device, a response is expected
+ within a given timeframe. If a response is not recevied within the
+ given timeframe, a timeout error occurs.
+*/
+#define CY_AS_ERROR_TIMEOUT (4)
+
+/* Summary
+ A request to download firmware was made while not in the CONFIG mode
+
+ Description
+ Firmware is downloaded via the CyAsMiscDownloadFirmware() function. This
+ function can only be called while in the CONFIG mode. This error indicates
+ that the CyAsMiscDownloadFirmware() call was made while not in the CONFIG
+ mode.
+
+ See Also
+ * CyAsMiscDownloadFirmware
+*/
+#define CY_AS_ERROR_NOT_IN_CONFIG_MODE (5)
+
+/* Summary
+ This error is returned if the firmware size specified is too invalid.
+
+ Description
+ If the size of the firmware to be downloaded into West Bridge is
+ invalid, this error is issued. Invalid firmware sizes are those
+ greater than 24K or a size of zero.
+
+ See Also
+ * CyAsMiscDownloadFirmare
+*/
+#define CY_AS_ERROR_INVALID_SIZE (6)
+
+/* Summary
+ This error is returned if a request is made to acquire a resource that has
+ already been acquired.
+
+ Description
+ This error is returned if a request is made to acquire a resource that has
+ already been acquired.
+
+ See Also
+ * CyAsMiscAcquireResource
+ * CyAsMiscReleaseResource
+*/
+#define CY_AS_ERROR_RESOURCE_ALREADY_OWNED (7)
+
+/* Summary
+ This error is returned if a request is made to release a resource that has
+ not previously been acquired.
+
+ Description
+ This error is returned if a request is made to release a resource that has
+ not previously been acquired.
+
+ See Also
+ * CyAsMiscAcquireResource
+ * CyAsMiscReleaseResource
+*/
+#define CY_AS_ERROR_RESOURCE_NOT_OWNED (8)
+
+/* Summary
+ This error is returned when a request is made for a media that
+ does not exist
+
+ Description
+ This error is returned when a request is made that references
+ a storage media that does not exist. This error is returned
+ when the storage media is not present in the current system,
+ or if the media value given is not valid.
+
+ See Also
+ * CyAsMiscSetTraceLevel
+ * CyAsStorageClaim
+ * CyAsStorageRelease
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_NO_SUCH_MEDIA (9)
+
+/* Summary
+ This error is returned when a request is made for a device
+ that does not exist
+
+ Description
+ This error is returned when a request is made that references a
+ storage device that does not exist. This error is returned when
+ the device index is not present in the current system, or if the
+ device index exceeds 15.
+
+ See Also
+ * CyAsMiscSetTraceLevel
+ * CyAsStorageQueryDevice
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_NO_SUCH_DEVICE (10)
+
+/* Summary
+ This error is returned when a request is made for a unit that
+ does not exist
+
+ Description
+ This error is returned when a request is made that references
+ a storage unit that does not exist. This error is returned
+ when the unit index is not present in the current system, or
+ if the unit index exceeds 255.
+
+ See Also
+ * CyAsMiscSetTraceLevel
+ * CyAsStorageQueryDevice
+ * CyAsStorageQueryUnit
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_NO_SUCH_UNIT (11)
+
+/* Summary
+ This error is returned when a request is made for a block that
+ does not exist
+
+ Description
+ This error is returned when a request is made that references
+ a storage block that does not exist. This error is returned
+ when the block address reference an address beyond the end of
+ the unit selected.
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_INVALID_BLOCK (12)
+
+/* Summary
+ This error is returned when an invalid trace level is set.
+
+ Description
+ This error is returned when the trace level request is greater
+ than three.
+
+ See Also
+ * CyAsMiscSetTraceLevel
+*/
+#define CY_AS_ERROR_INVALID_TRACE_LEVEL (13)
+
+/* Summary
+ This error is returned when West Bridge is already in the standby state
+ and an attempt is made to put West Bridge into this state again.
+
+ Description
+ This error is returned when West Bridge is already in the standby state
+ and an attempt is made to put West Bridge into this state again.
+
+ See Also
+ * CyAsMiscEnterStandby
+*/
+#define CY_AS_ERROR_ALREADY_STANDBY (14)
+
+/* Summary
+ This error is returned when the API needs to set a pin on the
+ West Bridge device, but this is not supported by the underlying HAL
+ layer.
+
+ Description
+ This error is returned when the API needs to set a pin on the
+ West Bridge device, but this is not supported by the underlying HAL
+ layer.
+
+ See Also
+ * CyAsMiscEnterStandby
+ * CyAsMiscLeaveStandby
+*/
+#define CY_AS_ERROR_SETTING_WAKEUP_PIN (15)
+
+/* Summary
+ This error is returned when a module is being started that has
+ already been started.
+
+ Description
+ This error is returned when a module is being started and that module
+ has already been started. This error does not occur with the
+ CyAsStorageStart() or CyAsUsbStart() functions as the storage and
+ USB modules are reference counted.
+
+ Note
+ At the current time, this error is returned by module internal to
+ the API but not returned by any of the API functions.
+*/
+#define CY_AS_ERROR_ALREADY_RUNNING (16)
+
+/* Summary
+ This error is returned when a module is being stopped that has
+ already been stopped.
+
+ Description
+ This error is returned when a module is being stopped and that module
+ has already been stopped. This error does not occur with the
+ CyAsStorageStop() or CyAsUsbStop() functions as the storage and USB
+ modules are reference counted.
+
+ Note
+ At the current time, this error is returned by module internal to
+ the API but not returned by any of the API functions.
+*/
+
+#define CY_AS_ERROR_NOT_RUNNING (17)
+
+/* Summary
+ This error is returned when the caller tries to claim a media that
+ has already been claimed.
+
+ Description
+ This error is returned when the caller tries to claim a media that
+ has already been claimed.
+
+ See Also
+ * CyAsStorageClaim
+*/
+#define CY_AS_ERROR_MEDIA_ALREADY_CLAIMED (18)
+
+/* Summary
+ This error is returned when the caller tries to release a media that has
+ already been released.
+
+ Description
+ This error is returned when the caller tries to release a media that has
+ already been released.
+
+ See Also
+ * CyAsStorageRelease
+*/
+#define CY_AS_ERROR_MEDIA_NOT_CLAIMED (19)
+
+/* Summary
+ This error is returned when canceling trying to cancel an asynchronous
+ operation when an async operation is not pending.
+
+ Description
+ This error is returned when a call is made to a function to cancel an
+ asynchronous operation and there is no asynchronous operation pending.
+
+ See Also
+ * CyAsStorageCancelAsync
+ * CyAsUsbCancelAsync
+*/
+#define CY_AS_ERROR_NO_OPERATION_PENDING (20)
+
+/* Summary
+ This error is returned when an invalid endpoint number is provided to
+ an API call.
+
+ Description
+ This error is returned when an invalid endpoint number is specified in
+ an API call. The endpoint number may be invalid because it is greater
+ than 15, or because it was a reference to an endpoint that is invalid
+ for West Bridge (2, 4, 6, or 8).
+
+ See Also
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbGetEndPointConfig
+ * CyAsUsbReadData
+ * CyAsUsbWriteData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+ * CyAsUsbSetStall
+ * CyAsUsbGetStall
+*/
+#define CY_AS_ERROR_INVALID_ENDPOINT (21)
+
+/* Summary
+ This error is returned when an invalid descriptor type
+ is specified in an API call.
+
+ Description
+ This error is returned when an invalid descriptor type
+ is specified in an API call.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+*/
+#define CY_AS_ERROR_INVALID_DESCRIPTOR (22)
+
+/* Summary
+ This error is returned when an invalid descriptor index
+ is specified in an API call.
+
+ Description
+ This error is returned when an invalid descriptor index
+ is specified in an API call.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+*/
+#define CY_AS_ERROR_BAD_INDEX (23)
+
+/* Summary
+ This error is returned if trying to set a USB descriptor
+ when in the P port enumeration mode.
+
+ Description
+ This error is returned if trying to set a USB descriptor
+ when in the P port enumeration mode.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+*/
+#define CY_AS_ERROR_BAD_ENUMERATION_MODE (24)
+
+/* Summary
+ This error is returned when the endpoint configuration specified
+ is not valid.
+
+ Description
+ This error is returned when the endpoint configuration specified
+ is not valid.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+ * CyAsUsbCommitConfig
+*/
+#define CY_AS_ERROR_INVALID_CONFIGURATION (25)
+
+/* Summary
+ This error is returned when the API cannot verify it is connected
+ to an West Bridge device.
+
+ Description
+ When the API is initialized, the API tries to read the ID register from
+ the West Bridge device. The value from this ID register should match the
+ value expected before communications with West Bridge are established. This
+ error means that the contents of the ID register cannot be verified.
+
+ See Also
+ * CyAsMiscConfigureDevice
+*/
+#define CY_AS_ERROR_NO_ANTIOCH (26)
+
+/* Summary
+ This error is returned when an API function is called and
+ CyAsMiscConfigureDevice has not been called to configure West Bridge
+ for the current environment.
+
+ Description
+ This error is returned when an API function is called and
+ CyAsMiscConfigureDevice has not been called to configure West Bridge for
+ the current environment.
+
+ See Also
+ * Almost all API function
+*/
+#define CY_AS_ERROR_NOT_CONFIGURED (27)
+
+/* Summary
+ This error is returned when West Bridge cannot allocate memory required for
+ internal API operations.
+
+ Description
+ This error is returned when West Bridge cannot allocate memory required for
+ internal API operations.
+
+ See Also
+ * Almost all API functoins
+*/
+#define CY_AS_ERROR_OUT_OF_MEMORY (28)
+
+/* Summary
+ This error is returned when a module is being started that has
+ already been started.
+
+ Description
+ This error is returned when a module is being started and that module
+ has already been started. This error does not occur with the
+ CyAsStorageStart() or CyAsUsbStart() functions as the storage and
+ USB modules are reference counted.
+
+ Note
+ At the current time, this error is returned by module internal to the API but
+ not returned by any of the API functions.
+*/
+#define CY_AS_ERROR_NESTED_SLEEP (29)
+
+/* Summary
+ This error is returned when an operation is attempted on an endpoint that has
+ been disabled.
+
+ Description
+ This error is returned when an operation is attempted on an endpoint that has
+ been disabled.
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbWriteData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+*/
+#define CY_AS_ERROR_ENDPOINT_DISABLED (30)
+
+/* Summary
+ This error is returned when a call is made to an API function when
+ the device is in standby.
+
+ Description
+ When the West Bridge device is in standby, the only two API functions that
+ can be called are CyAsMiscInStandby() and CyAsMiscLeaveStandby().
+ Calling any other API function will result in this error.
+
+ See Also
+*/
+#define CY_AS_ERROR_IN_STANDBY (31)
+
+/* Summary
+ This error is returned when an API call is made with an invalid handle value.
+
+ Description
+ This error is returned when an API call is made with an invalid handle value.
+
+ See Also
+*/
+#define CY_AS_ERROR_INVALID_HANDLE (32)
+
+/* Summary
+ This error is returned when an invalid response is returned from
+ the West Bridge device.
+
+ Description
+ Many of the API calls result in requests made to the West Bridge
+ device. This error occurs when the response from West Bridge is
+ invalid and generally indicates that the West Bridge device
+ should be reset.
+
+ See Also
+*/
+#define CY_AS_ERROR_INVALID_RESPONSE (33)
+
+/* Summary
+ This error is returned from the callback function for any asynchronous
+ read or write request that is canceled.
+
+ Description
+ When asynchronous requests are canceled, this error is passed to the
+ callback function associated with the request to indicate that the
+ request has been canceled
+
+ See Also
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+ * CyAsStorageCancelAsync
+ * CyAsUsbCancelAsync
+*/
+#define CY_AS_ERROR_CANCELED (34)
+
+/* Summary
+ This error is returned when the call to create sleep channel fails
+ in the HAL layer.
+
+ Description
+ This error is returned when the call to create sleep channel fails
+ in the HAL layer.
+
+ See Also
+ * CyAsMiscConfigureDevice
+*/
+#define CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED (35)
+
+/* Summary
+ This error is returned when the call to CyAsMiscLeaveStandby
+ is made and the device is not in standby.
+
+ Description
+ This error is returned when the call to CyAsMiscLeaveStandby
+ is made and the device is not in standby.
+
+ See Also
+*/
+#define CY_AS_ERROR_NOT_IN_STANDBY (36)
+
+/* Summary
+ This error is returned when the call to destroy sleep channel fails
+ in the HAL layer.
+
+ Description
+ This error is returned when the call to destroy sleep channel fails
+ in the HAL layer.
+
+ See Also
+ * CyAsMiscDestroyDevice
+*/
+#define CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED (37)
+
+/* Summary
+ This error is returned when an invalid resource is specified to a call
+ to CyAsMiscAcquireResource() or CyAsMiscReleaseResource()
+
+ Description
+ This error is returned when an invalid resource is specified to a call
+ to CyAsMiscAcquireResource() or CyAsMiscReleaseResource()
+
+ See Also
+ * CyAsMiscAcquireResource
+ * CyAsMiscReleaseResource
+*/
+#define CY_AS_ERROR_INVALID_RESOURCE (38)
+
+/* Summary
+ This error occurs when an operation is requested on an endpoint that has
+ a currently pending async operation.
+
+ Description
+ There can only be a single asynchronous pending operation on a given
+ endpoint and while the operation is pending on other operation can occur
+ on the endpoint. In addition, the device cannot enter standby while
+ any asynchronous operations are pending.
+
+ See Also
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsUsbReadData
+ * CyAsUsbWriteData
+ * CyAsMiscEnterStandby
+*/
+#define CY_AS_ERROR_ASYNC_PENDING (39)
+
+/* Summary
+ This error is returned when a call to CyAsStorageCancelAsync() or
+ CyAsUsbCancelAsync() is made when no asynchronous request is pending.
+
+ Description
+ This error is returned when a call to CyAsStorageCancelAsync() or
+ CyAsUsbCancelAsync() is made when no asynchronous request is pending.
+
+ See Also
+ * CyAsStorageCancelAsync
+ * CyAsUsbCancelAsync
+*/
+#define CY_AS_ERROR_ASYNC_NOT_PENDING (40)
+
+/* Summary
+ This error is returned when a request is made to put the West Bridge device
+ into standby mode while the USB stack is still active.
+
+ Description
+ This error is returned when a request is made to put the West Bridge device
+ into standby mode while the USB stack is still active. You must call the
+ function CyAsUsbStop() in order to shut down the USB stack in order to go
+ into the standby mode.
+
+ See Also
+ * CyAsMiscEnterStandby
+*/
+#define CY_AS_ERROR_USB_RUNNING (41)
+
+/* Summary
+ A request for in the wrong direction was issued on an endpoint.
+
+ Description
+ This error is returned when a write is attempted on an OUT endpoint or
+ a read is attempted on an IN endpoint.
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbWriteData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+*/
+#define CY_AS_ERROR_USB_BAD_DIRECTION (42)
+
+/* Summary
+ An invalid request was received
+
+ Description
+ This error is isused if an invalid request is issued.
+*/
+#define CY_AS_ERROR_INVALID_REQUEST (43)
+
+/* Summary
+ An ACK request was requested while no setup packet was pending.
+
+ Description
+ This error is issued if CyAsUsbAckSetupPacket() is called when no
+ setup packet is pending.
+*/
+#define CY_AS_ERROR_NO_SETUP_PACKET_PENDING (44)
+
+/* Summary
+ A call was made to a API function that cannot be called from a callback.
+
+ Description
+ Only asynchronous functions can be called from within West Bridge callbacks.
+ This error results when an invalid function is called from a callback.
+*/
+#define CY_AS_ERROR_INVALID_IN_CALLBACK (45)
+
+/* Summary
+ A call was made to CyAsUsbSetEndPointConfig() before
+ CyAsUsbSetPhysicalConfiguration() was called.
+
+ Description
+ When logical endpoints are configured, you must define the physical
+ endpoint for the logical endpoint being configured. Therefore
+ CyAsUsbSetPhysicalConfiguration() must be called to define the
+ physical endpoints before calling CyAsUsbSetEndPointConfig().
+*/
+#define CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET (46)
+
+/* Summary
+ The physical endpoint referenced is not valid in the current physical
+ configuration
+
+ Description
+ When logical endpoints are configured, you must define the physical
+ endpoint for the logical endpoint being configured. Given the
+ current physical configuration, the physical endpoint referenced
+ is not valid.
+*/
+#define CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT (47)
+
+/* Summary
+ The data supplied to the CyAsMiscDownloadFirmware() call is not
+ aligned on a WORD (16 bit) boundary.
+
+ Description
+ Many systems have problems with the transfer of data a word at a
+ time when the data is not word aligned. For this reason, we
+ require that the firmware image be aligned on a word boundary and
+ be an even number of bytes. This error is returned if these
+ conditions are not met.
+*/
+#define CY_AS_ERROR_ALIGNMENT_ERROR (48)
+
+/* Summary
+ A call was made to destroy the West Bridge device, but the USB
+ stack or the storage stack was will running.
+
+ Description
+ Before calling CyAsMiscDestroyDevice to destroy an West Bridge
+ device created via a call to CyAsMiscCreateDevice, the USB and
+ STORAGE stacks much be stopped via calls to CyAsUsbStop and
+ CyAsStorageStop. This error indicates that one of these two
+ stacks have not been stopped.
+*/
+#define CY_AS_ERROR_STILL_RUNNING (49)
+
+/* Summary
+ A call was made to the API for a function that is not yet supported.
+
+ Description
+ There are calls that are not yet supported that may be called through
+ the API. This is done to maintain compatibility in the future with
+ the API. This error is returned if you are asking for a capability
+ that does not yet exist.
+*/
+#define CY_AS_ERROR_NOT_YET_SUPPORTED (50)
+
+/* Summary
+ A NULL callback was provided where a non-NULL callback was required
+
+ Description
+ When async IO function are called, a callback is required to indicate
+ that the IO has completed. This callback must be non-NULL.
+*/
+#define CY_AS_ERROR_NULL_CALLBACK (51)
+
+/* Summary
+ This error is returned when a request is made to put the West Bridge device
+ into standby mode while the storage stack is still active.
+
+ Description
+ This error is returned when a request is made to put the West Bridge device
+ into standby mode while the storage stack is still active. You must call the
+ function CyAsStorageStop() in order to shut down the storage stack in order
+ to go into the standby mode.
+
+ See Also
+ * CyAsMiscEnterStandby
+*/
+#define CY_AS_ERROR_STORAGE_RUNNING (52)
+
+/* Summary
+ This error is returned when an operation is attempted that cannot be
+ completed while the USB stack is connected to a USB host.
+
+ Description
+ This error is returned when an operation is attempted that cannot be
+ completed while the USB stack is connected to a USB host. In order
+ to sucessfully complete the desired operation, CyAsUsbDisconnect()
+ must be called to disconnect from the host.
+*/
+#define CY_AS_ERROR_USB_CONNECTED (53)
+
+/* Summary
+ This error is returned when a USB disconnect is attempted and the
+ West Bridge device is not connected.
+
+ Description
+ This error is returned when a USB disconnect is attempted and the
+ West Bridge device is not connected.
+*/
+#define CY_AS_ERROR_USB_NOT_CONNECTED (54)
+
+/* Summary
+ This error is returned when an P2S storage operation attempted
+ and data could not be read or written to the storage media.
+
+ Description
+ This error is returned when an P2S storage operation attempted
+ and data could not be read or written to the storage media. If
+ this error is recevied then a retry can be done.
+*/
+#define CY_AS_ERROR_MEDIA_ACCESS_FAILURE (55)
+
+/* Summary
+ This error is returned when an P2S storage operation attempted
+ and the media is write protected.
+
+ Description
+ This error is returned when an P2S storage operation attempted
+ and the media is write protected.
+*/
+#define CY_AS_ERROR_MEDIA_WRITE_PROTECTED (56)
+
+/* Summary
+ This error is returned when an attempt is made to cancel a request
+ that has already been sent to the West Bridge.
+
+ Description
+ It is not possible to cancel an asynchronous storage read/write
+ operation after the actual data transfer with the West Bridge
+ has started. This error is returned if CyAsStorageCancelAsync
+ is called to cancel such a request.
+ */
+#define CY_AS_ERROR_OPERATION_IN_TRANSIT (57)
+
+/* Summary
+ This error is returned when an invalid parameter is passed to
+ one of the APIs.
+
+ Description
+ Some of the West Bridge APIs are applicable to only specific
+ media types, devices etc. This error code is returned when a
+ API is called with an invalid parameter type.
+ */
+#define CY_AS_ERROR_INVALID_PARAMETER (58)
+
+/* Summary
+ This error is returned if an API is not supported in the current setup.
+
+ Description
+ Some of the West Bridge APIs work only with specific device types
+ or firmware images. This error is returned when such APIs are called
+ when the current device or firmware does not support the invoked API
+ function.
+ */
+#define CY_AS_ERROR_NOT_SUPPORTED (59)
+
+/* Summary
+ This error is returned when a call is made to one of the Storage or
+ USB APIs while the device is in suspend mode.
+
+ Description
+ This error is returned when a call is made to one of the storage or
+ USB APIs while the device is in suspend mode.
+ */
+#define CY_AS_ERROR_IN_SUSPEND (60)
+
+/* Summary
+ This error is returned when the call to CyAsMiscLeaveSuspend
+ is made and the device is not in suspend mode.
+
+ Description
+ This error is returned when the call to CyAsMiscLeaveSuspend
+ is made and the device is not in suspend mode.
+ */
+#define CY_AS_ERROR_NOT_IN_SUSPEND (61)
+
+/* Summary
+ This error is returned when a command that is disabled by USB is called.
+
+ Description
+ The remote wakeup capability should be exercised only if enabled by the
+ USB host. This error is returned when the CyAsUsbSignalRemoteWakeup API
+ is called when the feature has not been enabled by the USB host.
+ */
+#define CY_AS_ERROR_FEATURE_NOT_ENABLED (62)
+
+/* Summary
+ This error is returned when an Async storage read or write is called before a
+ query device call is issued.
+
+ Description
+ In order for the SDK to properly set up a DMA the block size of a given media
+ needs to be known. This is done by making a call to CyAsStorageQueryDevice.
+ This call only needs to be made once per device. If this call is not issued
+ before an Async read or write is issued this error code is returned.
+ */
+#define CY_AS_ERROR_QUERY_DEVICE_NEEDED (63)
+
+/* Summary
+ This error is returned when a call is made to USB or STORAGE Start or
+ Stop before a prior Start or Stop has finished.
+
+ Description
+ The USB and STORAGE start and stop functions can only be called if a
+ prior start or stop function call has fully completed. This means when
+ an async EX call is made you must wait until the callback for that call
+ has been completed before calling start or stop again.
+ */
+#define CY_AS_ERROR_STARTSTOP_PENDING (64)
+
+/* Summary
+ This error is returned when a request is made for a bus that does not exist
+
+ Description
+ This error is returned when a request is made that references a bus
+ number that does not exist. This error is returned when the bus number
+ is not present in the current system, or if the bus number given is not
+ valid.
+
+ See Also
+ * CyAsMiscSetTraceLevel
+ * CyAsStorageClaim
+ * CyAsStorageRelease
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_ERROR_NO_SUCH_BUS (65)
+
+/* Summary
+ This error is returned when the bus corresponding to a media type cannot
+ be resolved.
+
+ Description
+ In some S-Port configurations, the same media type may be supported on
+ multiple buses. In this case, it is not possible to resolve the target
+ address based on the media type. This error indicates that only
+ bus-based addressing is supported in a particular run-time
+ configuration.
+
+ See Also
+ * CyAsMediaType
+ * CyAsBusNumber_t
+ */
+#define CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR (66)
+
+/* Summary
+ This error is returned when an invalid command is passed to the
+ CyAsStorageSDIOSync() function.
+
+ Description
+ This error indiactes an unknown Command type was passed to the SDIO
+ command handler function.
+ */
+
+#define CY_AS_ERROR_INVALID_COMMAND (67)
+
+
+/* Summary
+ This error is returned when an invalid function /uninitialized
+ function is passed to an SDIO function.
+
+ Description
+ This error indiactes an unknown/uninitialized function number was
+ passed to a SDIO function.
+ */
+#define CY_AS_ERROR_INVALID_FUNCTION (68)
+
+/* Summary
+ This error is returned when an invalid block size is passed to
+ CyAsSdioSetBlocksize().
+
+ Description
+ This error is returned when an invalid block size (greater than
+ maximum block size supported) is passed to CyAsSdioSetBlocksize().
+ */
+
+#define CY_AS_ERROR_INVALID_BLOCKSIZE (69)
+
+/* Summary
+ This error is returned when an tuple requested is not found.
+
+ Description
+ This error is returned when an tuple requested is not found.
+ */
+#define CY_AS_ERROR_TUPLE_NOT_FOUND (70)
+
+/* Summary
+ This error is returned when an extended IO operation to an SDIO function is
+ Aborted.
+ Description
+ This error is returned when an extended IO operation to an SDIO function is
+ Aborted. */
+#define CY_AS_ERROR_IO_ABORTED (71)
+
+/* Summary
+ This error is returned when an extended IO operation to an SDIO function is
+ Suspended.
+ Description
+ This error is returned when an extended IO operation to an SDIO function is
+ Suspended. */
+#define CY_AS_ERROR_IO_SUSPENDED (72)
+
+/* Summary
+ This error is returned when IO is attempted to a Suspended SDIO function.
+ Description
+ This error is returned when IO is attempted to a Suspended SDIO function. */
+#define CY_AS_ERROR_FUNCTION_SUSPENDED (73)
+
+/* Summary
+ This error is returned if an MTP function is called before MTPStart
+ has completed.
+ Description
+ This error is returned if an MTP function is called before MTPStart
+ has completed.
+*/
+#define CY_AS_ERROR_MTP_NOT_STARTED (74)
+
+/* Summary
+ This error is returned by API functions that are not valid in MTP
+ mode (CyAsStorageClaim for example)
+ Description
+ This error is returned by API functions that are not valid in MTP
+ mode (CyAsStorageClaim for example)
+*/
+#define CY_AS_ERROR_NOT_VALID_IN_MTP (75)
+
+/* Summary
+ This error is returned when an attempt is made to partition a
+ storage device that is already partitioned.
+
+ Description
+ This error is returned when an attempt is made to partition a
+ storage device that is already partitioned.
+*/
+#define CY_AS_ERROR_ALREADY_PARTITIONED (76)
+
+/* Summary
+ This error is returned when a call is made to
+ CyAsUsbSelectMSPartitions after CyAsUsbSetEnumConfig is called.
+
+ Description
+ This error is returned when a call is made to
+ CyAsUsbSelectMSPartitions after CyAsUsbSetEnumConfig is called.
+ */
+#define CY_AS_ERROR_INVALID_CALL_SEQUENCE (77)
+
+/* Summary
+ This error is returned when a StorageWrite opperation is attempted
+ during an ongoing MTP transfer.
+ Description
+ This error is returned when a StorageWrite opperation is attempted
+ during an ongoing MTP transfer. A MTP transfer is initiated by a
+ call to CyAsMTPInitSendObject or CyAsMTPInitGetObject and is not
+ finished until the CyAsMTPSendObjectComplete or
+ CyAsMTPGetObjectComplete event is generated.
+*/
+#define CY_AS_ERROR_NOT_VALID_DURING_MTP (78)
+
+/* Summary
+ This error is returned when a StorageRead or StorageWrite is
+ attempted while a UsbRead or UsbWrite on a Turbo endpoint (2 or 6) is
+ pending, or visa versa.
+ Description
+ When there is a pending usb read or write on a turbo endpoint (2 or 6)
+ a storage read or write call may not be performed. Similarly when there
+ is a pending storage read or write a usb read or write may not be
+ performed on a turbo endpoint (2 or 6).
+*/
+#define CY_AS_ERROR_STORAGE_EP_TURBO_EP_CONFLICT (79)
+
+/* Summary
+ This error is returned when processor requests to reserve greater
+ number of zones than available for proc booting via lna firmware.
+
+ Description
+ Astoria does not allocate any nand zones for the processor in this case.
+*/
+#define CY_AS_ERROR_EXCEEDED_NUM_ZONES_AVAIL (80)
+
+#endif /* _INCLUDED_CYASERR_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h
new file mode 100644
index 000000000000..b695ba1a9110
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h
@@ -0,0 +1,108 @@
+/* Cypress West Bridge API header file (cyashal.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASHAL_H_
+#define _INCLUDED_CYASHAL_H_
+
+#if !defined(__doxygen__)
+
+/* The possible HAL layers defined and implemented by Cypress */
+
+#ifdef __CY_ASTORIA_FPGA_HAL__
+#ifdef CY_HAL_DEFINED
+#error only one HAL layer can be defined
+#endif
+
+#define CY_HAL_DEFINED
+
+#include "cyashalfpga.h"
+#endif
+
+/***** SCM User space HAL ****/
+#ifdef __CY_ASTORIA_SCM_HAL__
+#ifdef CY_HAL_DEFINED
+#error only one HAL layer can be defined
+#endif
+
+#define CY_HAL_DEFINEDŚŚ
+
+#include "cyanhalscm.h"
+#endif
+/***** SCM User space HAL ****/
+
+/***** SCM Kernel HAL ****/
+#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__
+#ifdef CY_HAL_DEFINED
+#error only one HAL layer can be defined
+#endif
+
+#define CY_HAL_DEFINEDÅš
+
+#include "cyanhalscm_kernel.h"
+#endif
+/***** SCM Kernel HAL ****/
+
+/***** OMAP5912 Kernel HAL ****/
+#ifdef __CY_ASTORIA_OMAP_5912_KERNEL_HAL__
+ #ifdef CY_HAL_DEFINED
+ #error only one HAL layer can be defined
+ #endif
+
+ #define CY_HAL_DEFINED
+
+ #include "cyanhalomap_kernel.h"
+#endif
+/***** eof OMAP5912 Kernel HAL ****/
+
+
+
+/***** OMAP3430 Kernel HAL ****/
+#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+
+ #ifdef CY_HAL_DEFINED
+ #error only one HAL layer can be defined
+ #endif
+
+ #define CY_HAL_DEFINED
+/* moved to staging location, eventual implementation
+ * considered is here
+ * #include mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h>
+*/
+ #include "../../../arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h"
+
+#endif
+/*****************************/
+
+
+/******/
+#ifdef __CY_ASTORIA_CUSTOMER_HAL__
+#ifdef CY_HAL_DEFINED
+#error only one HAL layer can be defined
+#endif
+br
+#define CY_HAL_DEFINED
+#include "cyashal_customer.h"
+
+#endif
+
+#endif /* __doxygen__ */
+
+#endif /* _INCLUDED_CYASHAL_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h
new file mode 100644
index 000000000000..d48a7f4b147f
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h
@@ -0,0 +1,44 @@
+/* Cypress West Bridge API header file (cyashalcb.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASHALCB_H_
+#define _INCLUDED_CYASHALCB_H_
+
+/* Summary
+ This type defines a callback function type called when a
+ DMA operation has completed.
+
+ Description
+
+ See Also
+ * CyAsHalDmaRegisterCallback
+ * CyAsHalDmaSetupWrite
+ * CyAsHalDmaSetupRead
+*/
+typedef void (*cy_as_hal_dma_complete_callback)(
+ cy_as_hal_device_tag tag,
+ cy_as_end_point_number_t ep,
+ uint32_t cnt,
+ cy_as_return_status_t ret) ;
+
+typedef cy_as_hal_dma_complete_callback \
+ cy_an_hal_dma_complete_callback;
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h
new file mode 100644
index 000000000000..2cfe4fb4cf68
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h
@@ -0,0 +1,800 @@
+/* Cypress West Bridge API header file (cyashaldoc.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASHALDOC_H_
+#define _INCLUDED_CYASHALDOC_H_
+
+#include "cyashaldef.h"
+
+/*@@Hardware Abstraction Layer (HAL)
+ Summary
+ This software module is supplied by the user of the West Bridge
+ API. This module contains the software that is specific to the
+ hardware implementation or operating system of the client
+ system.
+
+ * Sleep Channels *
+ A sleep channel is a operating system object that provides that
+ capability for one thread or process to sleep while waiting on
+ the completion of some hardware event. The hardware event is
+ usually processed by a hardware interrupt and the interrupt
+ handler then wakes the thread or process that is sleeping.
+
+ A sleep channel provides the mechanism for this operation. A
+ sleep channel is created and initialized during the API
+ initialization. When the API needs to wait for the hardware,
+ the API performs a SleepOn() operation on the sleep channel.
+ When hardware event occurs, an interrupt handler processes the
+ event and then performs a Wake() operation on the sleep channel
+ to wake the sleeping process or thread.
+
+ * DMA Model *
+ When the West Bridge API needs to transfer USB or storage data
+ to/from the West Bridge device, this is done using a "DMA"
+ operation. In this context the term DMA is used loosely as the
+ West Bridge API does not really care if the data is transferred
+ using a burst read or write operation, or if the data is
+ transferred using programmed I/O operations. When a "DMA"
+ operation is needed, the West Bridge API calls either
+ CyAsHalDmaSetupRead() or CyAsHalDmaSetupWrite() depending on the
+ direction of the data flow. The West Bridge API expects the
+ "DMA" operation requested in the call to be completed and the
+ registered "DMA complete" callback to be called.
+
+ The West Bridge API looks at several factors to determine the
+ size of the "DMA" request to pass to the HAL layer. First the
+ West Bridge API calls CyAsHalDmaMaxRequestSize() to determine
+ the maximum amount of data the HAL layer can accept for a "DMA"
+ operation on the requested endpoint. The West Bridge API will
+ never exceed this value in a "DMA" request to the HAL layer.
+ The West Bridge API also sends the maximum amount of data the
+ West Bridge device can accept as part of the "DMA" request. If
+ the amount of data in the "DMA" request to the HAL layer
+ exceeds the amount of data the West Bridge device can accept,
+ it is expected that the HAL layer has the ability to break the
+ request into multiple operations.
+
+ If the HAL implementation requires the API to handle the size
+ of the "DMA" requests for one or more endpoints, the value
+ CY_AS_DMA_MAX_SIZE_HW_SIZE can be returned from the
+ CyAsHalDmaMaxRequestSize() call. In this case, the API assumes
+ that the maximum size of each "DMA" request should be limited
+ to the maximum that can be accepted by the endpoint in question.
+
+ Notes
+ See the <install>/api/hal/scm_kernel/cyashalscm_kernel.c file
+ for an example of how the DMA request size can be managed by
+ the HAL implementation.
+
+ * Interrupt Handling *
+ The HAL implementation is required to handle interrupts arriving
+ from the West Bridge device, and call the appropriate handlers.
+ If the interrupt arriving is one of PLLLOCKINT, PMINT, MBINT or
+ MCUINT, the CyAsIntrServiceInterrupt API should be called to
+ service the interrupt. If the interrupt arriving is DRQINT, the
+ HAL should identify the endpoint corresponding to which the DRQ
+ is being generated and perform the read/write transfer from the
+ West Bridge. See the <install>/api/hal/scm_kernel/
+ cyashalscm_kernel.c or <install>/api/hal/fpga/cyashalfpga.c
+ reference HAL implementations for examples.
+
+ The HAL implementation can choose to poll the West Bridge
+ interrupt status register instead of using interrupts. In this
+ case, the polling has to be performed from a different thread/
+ task than the one running the APIs. This is required because
+ there are API calls that block on the reception of data from the
+ West Bridge, which is delivered only through the interrupt
+ handlers.
+
+ * Required Functions *
+ This section defines the types and functions that must be
+ supplied in order to provide a complete HAL layer for the
+ West Bridge API.
+
+ Types that must be supplied:
+ * CyAsHalSleepChannel
+
+ Hardware functions that must be supplied:
+ * CyAsHalWriteRegister
+ * CyAsHalReadRegister
+ * CyAsHalDmaSetupWrite
+ * CyAsHalDmaSetupRead
+ * CyAsHalDmaCancelRequest
+ * CyAsHalDmaRegisterCallback
+ * CyAsHalDmaMaxRequestSize
+ * CyAsHalSetWakeupPin
+ * CyAsHalSyncDeviceClocks
+ * CyAsHalInitDevRegisters
+ * CyAsHalReadRegsBeforeStandby
+ * CyAsHalRestoreRegsAfterStandby
+
+ Operating system functions that must be supplied:
+ * CyAsHalAlloc
+ * CyAsHalFree
+ * CyAsHalCBAlloc
+ * CyAsHalCBFree
+ * CyAsHalMemSet
+ * CyAsHalCreateSleepChannel
+ * CyAsHalDestroySleepChannel
+ * CyAsHalSleepOn
+ * CyAsHalWake
+ * CyAsHalDisableInterrupts
+ * CyAsHalEnableInterrupts
+ * CyAsHalSleep150
+ * CyAsHalSleep
+ * CyAsHalAssert
+ * CyAsHalPrintMessage
+ * CyAsHalIsPolling
+*/
+
+/* Summary
+ This is the type that represents a sleep channel
+
+ Description
+ A sleep channel is an operating system object that, when a
+ thread of control waits on the sleep channel, the thread
+ sleeps until another thread signals the sleep object. This
+ object is generally used when a high level API is called
+ and must wait for a response that is supplied in an interrupt
+ handler. The thread calling the API is put into a sleep
+ state and when the reply arrives via the interrupt handler,
+ the interrupt handler wakes the sleeping thread to indicate
+ that the expect reply is available.
+*/
+typedef struct cy_as_hal_sleep_channel {
+ /* This structure is filled in with OS specific information
+ to implementat a sleep channel */
+ int m_channel ;
+} cy_as_hal_sleep_channel ;
+
+/* Summary
+ This function is called to write a register value
+
+ Description
+ This function is called to write a specific register to a
+ specific value. The tag identifies the device of interest.
+ The address is relative to the base address of the West
+ Bridge device.
+
+ Returns
+ Nothing
+
+ See Also
+ * CyAsHalDeviceTag
+ * CyAsHalReadRegister
+*/
+EXTERN void
+cy_as_hal_write_register(
+/* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The address we are writing to */
+ uint16_t addr,
+ /* The value to write to the register */
+ uint16_t value
+ ) ;
+
+/* Summary
+ This function is called to read a register value
+
+ Description
+ This function is called to read the contents of a specific
+ register. The tag identifies the device of interest. The
+ address is relative to the base address of the West Bridge
+ device.
+
+ Returns
+ Contents of the register
+
+ See Also
+ * CyAsHalDeviceTag
+ * CyAsHalWriteRegister
+*/
+EXTERN uint16_t
+cy_as_hal_read_register(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The address we are writing to */
+ uint16_t addr
+ ) ;
+
+/* Summary
+ This function initiates a DMA write operation to write
+ to West Bridge
+
+ Description
+ This function initiates a DMA write operation. The request
+ size will not exceed the value the HAL layer returned via
+ CyAsHalDmaMaxRequestSize(). This request size may exceed
+ the size of what the West Bridge device will accept as on
+ packet and the HAL layer may need to divide the request
+ into multiple hardware DMA operations.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalDmaSetupRead
+ * CyAsHalDmaMaxRequestSize
+*/
+EXTERN void
+cy_as_hal_dma_setup_write(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The endpoint we are writing to */
+ cy_as_end_point_number_t ep,
+ /* The data to write via DMA */
+ void *buf_p,
+ /* The size of the data at buf_p */
+ uint32_t size,
+ /* The maximum amount of data that the endpoint
+ * can accept as one packet */
+ uint16_t maxsize
+ ) ;
+
+/* Summary
+ This function initiates a DMA read operation from West Bridge
+
+ Description
+ This function initiates a DMA read operation. The request
+ size will not exceed the value the HAL layer returned via
+ CyAsHalDmaMaxRequestSize(). This request size may exceed
+ the size of what the Anitoch will accept as one packet and
+ the HAL layer may need to divide the request into multiple
+ hardware DMA operations.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalDmaSetupRead
+ * CyAsHalDmaMaxRequestSize
+*/
+EXTERN void
+cy_as_hal_dma_setup_read(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The endpoint we are reading from */
+ cy_as_end_point_number_t ep,
+ /* The buffer to read data into */
+ void *buf_p,
+ /* The amount of data to read */
+ uint32_t size,
+ /* The maximum amount of data that the endpoint
+ * can provide in one DMA operation */
+ uint16_t maxsize
+ ) ;
+
+/* Summary
+ This function cancels a pending DMA request
+
+ Description
+ This function cancels a pending DMA request that has been
+ passed down to the hardware. The HAL layer can elect to
+ physically cancel the request if possible, or just ignore
+ the results of the request if it is not possible.
+
+ Returns
+ None
+*/
+EXTERN void
+cy_as_hal_dma_cancel_request(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The endpoint we are reading from */
+ cy_as_end_point_number_t ep
+ ) ;
+
+/* Summary
+ This function registers a callback function to be called when
+ a DMA request is completed
+
+ Description
+ This function registers a callback that is called when a request
+ issued via CyAsHalDmaSetupWrite() or CyAsHalDmaSetupRead() has
+ completed.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalDmaSetupWrite
+ * CyAsHalDmaSetupRead
+*/
+EXTERN void
+cy_as_hal_dma_register_callback(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The callback to call when a request has completed */
+ cy_as_hal_dma_complete_callback cb
+ ) ;
+
+/* Summary
+ This function returns the maximum size of a DMA request that can
+ be handled by the HAL.
+
+ Description
+ When DMA requests are passed to the HAL layer for processing,
+ the HAL layer may have a limit on the size of the request that
+ can be handled. This function is called by the DMA manager for
+ an endpoint when DMA is enabled to get the maximum size of data
+ the HAL layer can handle. The DMA manager insures that a request
+ is never sent to the HAL layer that exceeds the size returned by
+ this function.
+
+ Returns
+ the maximum size of DMA request the HAL layer can handle
+*/
+EXTERN uint32_t
+cy_as_hal_dma_max_request_size(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep
+ ) ;
+
+/* Summary
+ This function sets the WAKEUP pin to a specific state on the
+ West Bridge device.
+
+ Description
+ In order to enter the standby mode, the WAKEUP pin must be
+ de-asserted. In order to resume from standby mode, the WAKEUP
+ pin must be asserted. This function provides the mechanism to
+ do this.
+
+ Returns
+ 1 if the pin was changed, 0 if the HAL layer does not support
+ changing this pin
+*/
+EXTERN uint32_t
+cy_as_hal_set_wakeup_pin(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* The desired state of the wakeup pin */
+ cy_bool state
+ ) ;
+
+/* Summary
+ Synchronise the West Bridge device clocks to re-establish device
+ connectivity.
+
+ Description
+ When the Astoria bridge device is working in SPI mode, a long
+ period of inactivity can cause a loss of serial synchronisation
+ between the processor and Astoria. This function is called by
+ the API when it detects such a condition, and is expected to take
+ the action required to re-establish clock synchronisation between
+ the devices.
+
+ Returns
+ CyTrue if the attempt to re-synchronise is successful,
+ CyFalse if not.
+ */
+EXTERN cy_bool
+cy_as_hal_sync_device_clocks(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ ) ;
+
+/* Summary
+ Initialize West Bridge device registers that may have been
+ modified while the device was in standby.
+
+ Description
+ The content of some West Bridge registers may be lost when
+ the device is placed in standby mode. This function restores
+ these register contents so that the device can continue to
+ function normally after it wakes up from standby mode.
+
+ This function is required to perform operations only when the
+ API is being used with the Astoria device in one of the PNAND
+ modes or in the PSPI mode. It can be a no-operation in all
+ other cases.
+
+ Returns
+ None
+ */
+EXTERN void
+cy_as_hal_init_dev_registers(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag,
+ /* Indicates whether this is a wake-up from standby. */
+ cy_bool is_standby_wakeup
+ ) ;
+
+/* Summary
+ This function reads a set of P-port accessible device registers and
+ stores their value for later use.
+
+ Description
+ The West Bridge Astoria device silicon has a known problem when
+ operating in SPI mode on the P-port, where some of the device
+ registers lose their value when the device goes in and out of
+ standby mode. The suggested work-around is to reset the Astoria
+ device as part of the wakeup procedure from standby.
+
+ This requires that the values of some of the P-port accessible
+ registers be restored to their pre-standby values after it has
+ been reset. This HAL function can be used to read and store
+ the values of these registers at the point where the device is
+ being placed in standby mode.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalRestoreRegsAfterStandby
+ */
+EXTERN void
+cy_as_hal_read_regs_before_standby(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag
+ ) ;
+
+/* Summary
+ This function restores the old values to a set of P-port
+ accessible device registers.
+
+ Description
+ This function is part of the work-around to a known West
+ Bridge Astoria device error when operating in SPI mode on
+ the P-port. This function is used to restore a set of
+ P-port accessible registers to the values they had before
+ the device was placed in standby mode.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalRestoreRegsAfterStandby
+ */
+EXTERN void
+cy_as_hal_restore_regs_after_standby(
+ /* The tag to ID a specific West Bridge device */
+ cy_as_hal_device_tag tag
+ ) ;
+
+/*
+ * The functions below this comment are part of the HAL layer,
+ * as the HAL layer consists of the abstraction to both the
+ * hardware platform and the operating system. However; the
+ * functions below this comment all relate to the operating
+ * environment and not specifically to the hardware platform
+ * or specific device.
+ */
+
+/* Summary
+ This function allocates a block of memory
+
+ Description
+ This is the HAL layer equivalent of the malloc() function.
+
+ Returns
+ a pointer to a block of memory
+
+ See Also
+ * CyAsHalFree
+*/
+EXTERN void *
+cy_as_hal_alloc(
+ /* The size of the memory block to allocate */
+ uint32_t size
+ ) ;
+
+/* Summary
+ This function frees a previously allocated block of memory
+
+ Description
+ This is the HAL layer equivalent of the free() function.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalAlloc
+*/
+EXTERN void
+cy_as_hal_free(
+ /* Pointer to a memory block to free */
+ void *ptr
+ ) ;
+
+/* Summary
+ This function is a malloc equivalent that can be used from an
+ interrupt context.
+
+ Description
+ This function is a malloc equivalent that will be called from the
+ API in callbacks. This function is required to be able to provide
+ memory in interrupt context.
+
+ Notes
+ For platforms where it is not possible to allocate memory in interrupt
+ context, we provide a reference allocator that takes memory during
+ initialization and implements malloc/free using this memory.
+ See the <install>/api/hal/fpga/cyashalblkalloc.[ch] files for the
+ implementation, and the <install>/api/hal/fpga/cyashalfpga.c file
+ for an example of the use of this allocator.
+
+ Returns
+ A pointer to the allocated block of memory
+
+ See Also
+ * CyAsHalCBFree
+ * CyAsHalAlloc
+*/
+EXTERN void *
+cy_as_hal_c_b_alloc(
+ /* The size of the memory block to allocate */
+ uint32_t size
+ ) ;
+
+/* Summary
+ This function frees the memory allocated through the CyAsHalCBAlloc
+ call.
+
+ Description
+ This function frees memory allocated through the CyAsHalCBAlloc
+ call, and is also required to support calls from interrupt
+ context.
+
+ Returns
+ None
+
+ See Also
+ * CyAsHalCBAlloc
+ * CyAsHalFree
+*/
+EXTERN void
+cy_as_hal_c_b_free(
+ /* Pointer to the memory block to be freed */
+ void *ptr
+ ) ;
+
+/* Summary
+ This function sets a block of memory to a specific value
+
+ Description
+ This function is the HAL layer equivalent of the memset() function.
+
+ Returns
+ None
+*/
+EXTERN void
+cy_as_mem_set(
+ /* A pointer to a block of memory to set */
+ void *ptr,
+ /* The value to set the memory to */
+ uint8_t value,
+ /* The number of bytes to set */
+ uint32_t cnt
+ ) ;
+
+/* Summary
+ This function creates or initializes a sleep channel
+
+ Description
+ This function creates or initializes a sleep channel. The
+ sleep channel defined using the HAL data structure
+ CyAsHalSleepChannel.
+
+ Returns
+ CyTrue is the initialization was sucessful, and CyFalse otherwise
+
+ See Also
+ * CyAsHalSleepChannel
+ * CyAsHalDestroySleepChannel
+ * CyAsHalSleepOn
+ * CyAsHalWake
+*/
+EXTERN cy_bool
+cy_as_hal_create_sleep_channel(
+ /* Pointer to the sleep channel to create/initialize */
+ cy_as_hal_sleep_channel *chan
+ ) ;
+
+/* Summary
+ This function destroys an existing sleep channel
+
+ Description
+ This function destroys an existing sleep channel. The sleep channel
+ is of type CyAsHalSleepChannel.
+
+ Returns
+ CyTrue if the channel was destroyed, and CyFalse otherwise
+
+ See Also
+ * CyAsHalSleepChannel
+ * CyAsHalCreateSleepChannel
+ * CyAsHalSleepOn
+ * CyAsHalWake
+*/
+EXTERN cy_bool
+cy_as_hal_destroy_sleep_channel(
+ /* The sleep channel to destroy */
+ cy_as_hal_sleep_channel chan
+ ) ;
+
+/* Summary
+ This function causes the calling process or thread to sleep until
+ CyAsHalWake() is called
+
+ Description
+ This function causes the calling process or threadvto sleep.
+ When CyAsHalWake() is called on the same sleep channel, this
+ processes or thread is then wakened and allowed to run
+
+ Returns
+ CyTrue if the thread or process is asleep, and CyFalse otherwise
+
+ See Also
+ * CyAsHalSleepChannel
+ * CyAsHalWake
+*/
+EXTERN cy_bool
+cy_as_hal_sleep_on(
+ /* The sleep channel to sleep on */
+ cy_as_hal_sleep_channel chan,
+ /* The maximum time to sleep in milli-seconds */
+ uint32_t ms
+ ) ;
+
+/* Summary
+ This function casues the process or thread sleeping on the given
+ sleep channel to wake
+
+ Description
+ This function causes the process or thread sleeping on the given
+ sleep channel to wake. The channel
+
+ Returns
+ CyTrue if the thread or process is awake, and CyFalse otherwise
+
+ See Also
+ * CyAsHalSleepChannel
+ * CyAsHalSleepOn
+*/
+EXTERN cy_bool
+cy_as_hal_wake(
+ /* The sleep channel to wake */
+ cy_as_hal_sleep_channel chan
+ ) ;
+
+/* Summary
+ This function disables interrupts, insuring that short bursts
+ of code can be run without danger of interrupt handlers running.
+
+ Description
+ There are cases within the API when lists must be manipulated by
+ both the API and the associated interrupt handlers. In these
+ cases, interrupts must be disabled to insure the integrity of the
+ list during the modification. This function is used to disable
+ interrupts during the short intervals where these lists are being
+ changed.
+
+ The HAL must have the ability to nest calls to
+ CyAsHalDisableInterrupts and CyAsHalEnableInterrupts.
+
+ Returns
+ Any interrupt related state value which will be passed back into
+ the subsequent CyAsHalEnableInterrupts call.
+
+ See Also
+ * CyAsHalEnableInterrupts
+*/
+EXTERN uint32_t
+cy_as_hal_disable_interrupts() ;
+
+/* Summary
+ This function re-enables interrupts after a critical section of
+ code in the API has been completed.
+
+ Description
+ There are cases within the API when lists must be manipulated by
+ both the API and the associated interrupt handlers. In these
+ cases, interrupts must be disabled to insure the integrity of the
+ list during the modification. This function is used to enable
+ interrupts after the short intervals where these lists are being
+ changed.
+
+ See Also
+ * CyAsHalDisableInterrupts
+*/
+EXTERN void
+cy_as_hal_enable_interrupts(
+ /* Value returned by the previous CyAsHalDisableInterrupts call. */
+ uint32_t value
+ ) ;
+
+/* Summary
+ This function sleeps for 150 ns.
+
+ Description
+ This function sleeps for 150 ns before allowing the calling function
+ to continue. This function is used for a specific purpose and the
+ sleep required is at least 150 ns.
+*/
+EXTERN void
+cy_as_hal_sleep150(
+ ) ;
+
+/* Summary
+ This function sleeps for the given number of milliseconds
+
+ Description
+ This function sleeps for at least the given number of milliseonds
+*/
+EXTERN void
+cy_as_hal_sleep(
+ uint32_t ms
+ ) ;
+
+/* Summary
+ This function asserts when the condition evaluates to zero
+
+ Description
+ Within the API there are conditions which are checked to insure
+ the integrity of the code. These conditions are checked only
+ within a DEBUG build. This function is used to check the condition
+ and if the result evaluates to zero, it should be considered a
+ fatal error that should be reported to Cypress.
+*/
+EXTERN void
+cy_as_hal_assert(
+ /* The condition to evaluate */
+ cy_bool cond
+ ) ;
+
+/* Summary
+ This function prints a message from the API to a human readable device
+
+ Description
+ There are places within the West Bridge API where printing a message
+ is useful to the debug process. This function provides the mechanism
+ to print a message.
+
+ Returns
+ NONE
+*/
+EXTERN void
+cy_as_hal_print_message(
+ /* The message to print */
+ const char *fmt_p,
+ ... /* Variable arguments */
+ ) ;
+
+/* Summary
+ This function reports whether the HAL implementation uses
+ polling to service data coming from the West Bridge.
+
+ Description
+ This function reports whether the HAL implementation uses
+ polling to service data coming from the West Bridge.
+
+ Returns
+ CyTrue if the HAL polls the West Bridge Interrupt Status registers
+ to complete operations, CyFalse if the HAL is interrupt driven.
+ */
+EXTERN cy_bool
+cy_as_hal_is_polling(
+ void) ;
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h
new file mode 100644
index 000000000000..e77aa6ae82bb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h
@@ -0,0 +1,104 @@
+/* Cypress West Bridge API header file (cyasintr.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASINTR_H_
+#define _INCLUDED_CYASINTR_H_
+
+#include "cyasdevice.h"
+
+#include "cyas_cplus_start.h"
+
+/* Summary
+ Initialize the interrupt manager module
+
+ Description
+ This function is called to initialize the interrupt module.
+ This module enables interrupts as well as servies West Bridge
+ related interrupts by determining the source of the interrupt
+ and calling the appropriate handler function.
+
+ Notes
+ If the dmaintr parameter is TRUE, the initialization code
+ initializes the interrupt mask to have the DMA related interrupt
+ enabled via the general purpose interrupt. However, the interrupt
+ service function assumes that the DMA interrupt is handled by the
+ HAL layer before the interrupt module handler function is called.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the interrupt module was initialized
+ * correctly
+ * CY_AS_ERROR_ALREADY_RUNNING - the interrupt module was already
+ * started
+
+ See Also
+ * CyAsIntrStop
+ * CyAsServiceInterrupt
+*/
+cy_as_return_status_t
+cy_as_intr_start(
+ /* Device being initialized */
+ cy_as_device *dev_p,
+ /* If true, enable the DMA interrupt through the INT signal */
+ cy_bool dmaintr
+ ) ;
+
+/* Summary
+ Stop the interrupt manager module
+
+ Description
+ This function stops the interrupt module and masks all interrupts
+ from the West Bridge device.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the interrupt module was stopped
+ * sucessfully
+ * CY_AS_ERROR_NOT_RUNNING - the interrupt module was not
+ * running
+
+ See Also
+ * CyAsIntrStart
+ * CyAsServiceInterrupt
+*/
+cy_as_return_status_t
+cy_as_intr_stop(
+ /* Device bein stopped */
+ cy_as_device *dev_p
+ ) ;
+
+
+/* Summary
+ The interrupt service routine for West Bridge
+
+ Description
+ When an interrupt is detected, this function is called to
+ service the West Bridge interrupt. It is safe and efficient
+ for this function to be called when no West Bridge interrupt
+ has occurred. This function will determine it is not an West
+ Bridge interrupt quickly and return.
+*/
+void cy_as_intr_service_interrupt(
+ /* The USER supplied tag for this device */
+ cy_as_hal_device_tag tag
+ ) ;
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASINTR_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h
new file mode 100644
index 000000000000..40497655b7fb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h
@@ -0,0 +1,36 @@
+/* Cypress West Bridge API header file (cyaslep2pep.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASLEP2PEP_H_
+#define _INCLUDED_CYASLEP2PEP_H_
+
+#include "cyasdevice.h"
+
+extern cy_as_return_status_t
+cy_as_usb_map_logical2_physical(cy_as_device *dev_p) ;
+
+extern cy_as_return_status_t
+cy_as_usb_setup_dma(cy_as_device *dev_p) ;
+
+extern cy_as_return_status_t
+cy_as_usb_set_dma_sizes(cy_as_device *dev_p) ;
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h
new file mode 100644
index 000000000000..6d40aa6eed6c
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h
@@ -0,0 +1,366 @@
+/* Cypress West Bridge API header file (cyaslowlevel.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASLOWLEVEL_H_
+#define _INCLUDED_CYASLOWLEVEL_H_
+
+/*@@Low Level Communications
+
+ Summary
+ The low level communications module is responsible for
+ communications between the West Bridge device and the P
+ port processor. Communications is organized as a series
+ of requests and subsequent responses. For each request
+ there is a one and only one response. Requests may go
+ from the West Bridge device to the P port processor, or
+ from the P Port processor to the West Bridge device.
+
+ Description
+ Requests are issued across what is called a context. A
+ context is a single channel of communications from one
+ processor to another processor. There can be only a single
+ request outstanding on a context at a given time. Contexts
+ are used to identify subsystems that can only process a
+ single request at a time, but are independent of other
+ contexts in the system. For instance, there is a context
+ for communicating storage commands from the P port processor
+ to the West Bridge device. There is also a context for
+ communicating USB commands from the P port processor to the
+ West Bridge device.
+
+ Requests and responses are identical with the exception of
+ the type bit in the request/response header. If the type
+ bit is one, the packet is a request. If this bit is zero,
+ the packet is a response. Also encoded within the header of
+ the request/response is the code. The code is a command
+ code for a request, or a response code for a response. For
+ a request, the code is a function of the context. The code
+ 0 has one meaning for the storage context and a different
+ meaning for the USB context. The code is treated differently
+ in the response. If the code in the response is less than 16,
+ then the meaning of the response is global across all
+ contexts. If the response is greater than or equal to 16,
+ then the response is specific to the associated context.
+
+ Requests and responses are transferred between processors
+ through the mailbox registers. It may take one or more cycles
+ to transmit a complete request or response. The context is
+ encoded into each cycle of the transfer to insure the
+ receiving processor can route the data to the appropriate
+ context for processing. In this way, the traffic from multiple
+ contexts can be multiplexed into a single data stream through
+ the mailbox registers by the sending processor, and
+ demultiplexed from the mailbox registers by the receiving
+ processor.
+
+ * Firmware Assumptions *
+ The firmware assumes that mailbox contents will be consumed
+ immediately. Therefore for multi-cycle packets, the data is
+ sent in a tight polling loop from the firmware. This implies
+ that the data must be read from the mailbox register on the P
+ port side and processed immediately or performance of the
+ firmware will suffer. In order to insure this is the case,
+ the data from the mailboxes is read and stored immediately
+ in a per context buffer. This occurs until the entire packet
+ is received at which time the request packet is processed.
+ Since the protocol is designed to allow for only one
+ outstanding packet at a time, the firmware can never be in a
+ position of waiting on the mailbox registers while the P port
+ is processing a request. Only after the response to the
+ previous request is sent will another request be sent.
+*/
+
+#include "cyashal.h"
+#include "cyasdevice.h"
+
+#include "cyas_cplus_start.h"
+
+/*
+ * Constants
+ */
+#define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff)
+#define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK (0x0F00)
+#define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8)
+#define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000)
+#define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000)
+#define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000)
+
+/*
+ * These macros extract the data from a 16 bit value
+ */
+#define cy_as_mbox_get_code(c) \
+ ((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK))
+#define cy_as_mbox_get_context(c) \
+ ((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \
+ >> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))
+#define cy_as_mbox_is_last(c) \
+ ((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK)
+#define cy_as_mbox_is_request(c) \
+ (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0)
+#define cy_as_mbox_is_response(c) \
+ (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0)
+
+/*
+ * These macros (not yet written) pack data into or extract data
+ * from the m_box0 field of the request or response
+ */
+#define cy_as_ll_request_response__set_code(req, code) \
+ ((req)->box0 = \
+ ((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \
+ (code & CY_AS_REQUEST_RESPONSE_CODE_MASK))
+
+#define cy_as_ll_request_response__get_code(req) \
+ cy_as_mbox_get_code((req)->box0)
+
+#define cy_as_ll_request_response__set_context(req, context) \
+ ((req)->box0 |= ((context) << \
+ CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))
+
+#define cy_as_ll_request_response__set_clear_storage_flag(req) \
+ ((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG)
+
+#define cy_as_ll_request_response__get_context(req) \
+ cy_as_mbox_get_context((req)->box0)
+
+#define cy_as_ll_request_response__is_last(req) \
+ cy_as_mbox_is_last((req)->box0)
+
+#define CY_an_ll_request_response___set_last(req) \
+ ((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK)
+
+#define cy_as_ll_request_response__is_request(req) \
+ cy_as_mbox_is_request((req)->box0)
+
+#define cy_as_ll_request_response__set_request(req) \
+ ((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK)
+
+#define cy_as_ll_request_response__set_response(req) \
+ ((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK)
+
+#define cy_as_ll_request_response__is_response(req) \
+ cy_as_mbox_is_response((req)->box0)
+
+#define cy_as_ll_request_response__get_word(req, offset) \
+ ((req)->data[(offset)])
+
+#define cy_as_ll_request_response__set_word(req, offset, \
+ value) ((req)->data[(offset)] = value)
+
+typedef enum cy_as_remove_request_result_t {
+ cy_as_remove_request_sucessful,
+ cy_as_remove_request_in_transit,
+ cy_as_remove_request_not_found
+} cy_as_remove_request_result_t ;
+
+/* Summary
+ Start the low level communications module
+
+ Description
+*/
+cy_as_return_status_t
+cy_as_ll_start(
+ cy_as_device *dev_p
+ ) ;
+
+cy_as_return_status_t
+cy_as_ll_stop(
+ cy_as_device *dev_p
+ ) ;
+
+
+cy_as_ll_request_response *
+cy_as_ll_create_request(
+ cy_as_device *dev_p,
+ uint16_t code,
+ uint8_t context,
+ /* Length of the request in 16 bit words */
+ uint16_t length
+ ) ;
+
+void
+cy_as_ll_init_request(
+ cy_as_ll_request_response *req_p,
+ uint16_t code,
+ uint16_t context,
+ uint16_t length) ;
+
+void
+cy_as_ll_init_response(
+ cy_as_ll_request_response *req_p,
+ uint16_t length) ;
+
+void
+cy_as_ll_destroy_request(
+ cy_as_device *dev_p,
+ cy_as_ll_request_response *) ;
+
+cy_as_ll_request_response *
+cy_as_ll_create_response(
+ cy_as_device *dev_p,
+ /* Length of the request in 16 bit words */
+ uint16_t length
+ ) ;
+
+cy_as_remove_request_result_t
+cy_as_ll_remove_request(
+ cy_as_device *dev_p,
+ cy_as_context *ctxt_p,
+ cy_as_ll_request_response *req_p,
+ cy_bool force
+ ) ;
+void
+cy_as_ll_remove_all_requests(cy_as_device *dev_p,
+ cy_as_context *ctxt_p) ;
+
+void
+cy_as_ll_destroy_response(
+ cy_as_device *dev_p,
+ cy_as_ll_request_response *) ;
+
+cy_as_return_status_t
+cy_as_ll_send_request(
+ /* The West Bridge device */
+ cy_as_device *dev_p,
+ /* The request to send */
+ cy_as_ll_request_response *req,
+ /* Storage for a reply, must be sure it is of sufficient size */
+ cy_as_ll_request_response *resp,
+ /* If true, this is a sync request */
+ cy_bool sync,
+ /* Callback to call when reply is received */
+ cy_as_response_callback cb
+) ;
+
+cy_as_return_status_t
+cy_as_ll_send_request_wait_reply(
+ /* The West Bridge device */
+ cy_as_device *dev_p,
+ /* The request to send */
+ cy_as_ll_request_response *req,
+ /* Storage for a reply, must be sure it is of sufficient size */
+ cy_as_ll_request_response *resp
+) ;
+
+/* Summary
+ This function registers a callback function to be called when a
+ request arrives on a given context.
+
+ Description
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+*/
+extern cy_as_return_status_t
+cy_as_ll_register_request_callback(
+ cy_as_device *dev_p,
+ uint8_t context,
+ cy_as_response_callback cb
+ ) ;
+
+/* Summary
+ This function packs a set of bytes given by the data_p pointer
+ into a request, reply structure.
+*/
+extern void
+cy_as_ll_request_response__pack(
+ /* The destintation request or response */
+ cy_as_ll_request_response *req,
+ /* The offset of where to pack the data */
+ uint32_t offset,
+ /* The length of the data to pack in bytes */
+ uint32_t length,
+ /* The data to pack */
+ void *data_p
+ ) ;
+
+/* Summary
+ This function unpacks a set of bytes from a request/reply
+ structure into a segment of memory given by the data_p pointer.
+*/
+extern void
+cy_as_ll_request_response__unpack(
+ /* The source of the data to unpack */
+ cy_as_ll_request_response *req,
+ /* The offset of the data to unpack */
+ uint32_t offset,
+ /* The length of the data to unpack in bytes */
+ uint32_t length,
+ /* The destination of the unpack operation */
+ void *data_p
+ ) ;
+
+/* Summary
+ This function sends a status response back to the West Bridge
+ device in response to a previously send request
+*/
+extern cy_as_return_status_t
+cy_as_ll_send_status_response(
+ /* The West Bridge device */
+ cy_as_device *dev_p,
+ /* The context to send the response on */
+ uint8_t context,
+ /* The success/failure code to send */
+ uint16_t code,
+ /* Flag to clear wait on storage context */
+ uint8_t clear_storage) ;
+
+/* Summary
+ This function sends a response back to the West Bridge device.
+
+ Description
+ This function sends a response back to the West Bridge device.
+ The response is sent on the context given by the 'context'
+ variable. The code for the response is given by the 'code'
+ argument. The data for the response is given by the data and
+ length arguments.
+*/
+extern cy_as_return_status_t
+cy_as_ll_send_data_response(
+ /* The West Bridge device */
+ cy_as_device *dev_p,
+ /* The context to send the response on */
+ uint8_t context,
+ /* The response code to use */
+ uint16_t code,
+ /* The length of the data for the response */
+ uint16_t length,
+ /* The data for the response */
+ void *data
+) ;
+
+/* Summary
+ This function removes any requests of the given type
+ from the given context.
+
+ Description
+ This function removes requests of a given type from the
+ context given via the context number.
+*/
+extern cy_as_return_status_t
+cy_as_ll_remove_ep_data_requests(
+ /* The West Bridge device */
+ cy_as_device *dev_p,
+ cy_as_end_point_number_t ep
+ ) ;
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASLOWLEVEL_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h
new file mode 100644
index 000000000000..e444079cf87c
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h
@@ -0,0 +1,54 @@
+/* Cypress West Bridge API header file (cyasmedia.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASMEDIA_H_
+#define _INCLUDED_CYASMEDIA_H_
+
+#include "cyas_cplus_start.h"
+
+
+/* Summary
+ Specifies a specific type of media supported by West Bridge
+
+ Description
+ The West Bridge device supports five specific types of media
+ as storage/IO devices attached to it's S-Port. This type is
+ used to indicate the type of media being referenced in any
+ API call.
+*/
+typedef enum cy_as_media_type {
+ /* Flash NAND memory (may be SLC or MLC) */
+ cy_as_media_nand = 0x00,
+ /* An SD flash memory device */
+ cy_as_media_sd_flash = 0x01,
+ /* An MMC flash memory device */
+ cy_as_media_mmc_flash = 0x02,
+ /* A CE-ATA disk drive */
+ cy_as_media_ce_ata = 0x03,
+ /* SDIO device. */
+ cy_as_media_sdio = 0x04,
+ cy_as_media_max_media_value = 0x05
+
+} cy_as_media_type ;
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASMEDIA_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h
new file mode 100644
index 000000000000..33655bd125cc
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h
@@ -0,0 +1,1549 @@
+/* Cypress West Bridge API header file (cyasmisc.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASMISC_H_
+#define _INCLUDED_CYASMISC_H_
+
+#include "cyashal.h"
+#include "cyastypes.h"
+#include "cyasmedia.h"
+
+#include "cyas_cplus_start.h"
+
+#define CY_AS_LEAVE_STANDBY_DELAY_CLOCK (1)
+#define CY_AS_RESET_DELAY_CLOCK (1)
+
+#define CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL (5)
+#define CY_AS_RESET_DELAY_CRYSTAL (5)
+
+/* The maximum number of buses supported */
+#define CY_AS_MAX_BUSES (2)
+
+/* The maximum number of storage devices supported per bus */
+#define CY_AS_MAX_STORAGE_DEVICES (1)
+
+#define CY_AS_FUNCTCBTYPE_DATA_MASK (0x60000000U)
+#define CY_AS_FUNCTCBTYPE_TYPE_MASK (0x1FFFFFFFU)
+
+#define cy_as_funct_c_b_type_get_type(t) \
+ ((cy_as_funct_c_b_type)((t) & CY_AS_FUNCTCBTYPE_TYPE_MASK))
+#define cy_as_funct_c_b_type_contains_data(t) \
+ (((cy_as_funct_c_b_type)((t) & \
+ CY_AS_FUNCTCBTYPE_DATA_MASK)) == CY_FUNCT_CB_DATA)
+
+/**************************************
+ * West Bridge Types
+ **************************************/
+
+/* Summary
+ Specifies a handle to an West Bridge device
+
+ Description
+ This type represents an opaque handle to an West Bridge device.
+ This handle is created via the CyAsMiscCreateDevice() function
+ and is used in all subsequent calls that communicate to the West
+ Bridge device.
+
+ See Also
+ * CyAsMiscCreateDevice
+ * CyAsMiscDestroyDevice
+*/
+typedef void *cy_as_device_handle ;
+
+/* Summary
+ This data type gives the mode for the DACK# signal
+*/
+typedef enum cy_as_device_dack_mode {
+ cy_as_device_dack_ack, /* Operate in the ACK mode */
+ cy_as_device_dack_eob /* Operate in the EOB mode */
+} cy_as_device_dack_mode ;
+
+/* Summary
+ This data structure gives the options for all hardware features.
+
+ Description
+ This structure contains the information required to initialize the
+ West Bridge hardware. Any features of the device that can be
+ configured by the caller are specified here.
+
+ See Also
+ * CyAsMiscConfigure
+*/
+typedef struct cy_as_device_config {
+ /* If TRUE, the P port is running in SRAM mode. */
+ cy_bool srammode ;
+ /* If TRUE, the P port is synchronous, otherwise async */
+ cy_bool sync ;
+ /* If TRUE, DMA req will be delivered via the interrupt signal */
+ cy_bool dmaintr ;
+ /* Mode for the DACK# signal */
+ cy_as_device_dack_mode dackmode ;
+ /* If TRUE, the DRQ line is active high, otherwise active low */
+ cy_bool drqpol ;
+ /* If TRUE, the DACK line is active high, otherwise active low */
+ cy_bool dackpol ;
+ /* If TRUE, the clock is connected to a crystal, otherwise it is
+ connected to a clock */
+ cy_bool crystal ;
+} cy_as_device_config ;
+
+
+/* Summary
+ Specifies a resource that can be owned by either the West Bridge
+ device or by the processor.
+
+ Description
+ This enumerated type identifies a resource that can be owned
+ either by the West Bridge device, or by the processor attached to
+ the P port of the West Bridge device.
+
+ See Also
+ * CyAsMiscAcquireResource
+ * CyAsMiscReleaseResource
+*/
+typedef enum cy_as_resource_type {
+ cy_as_bus_u_s_b = 0, /* The USB D+ and D- pins */
+ cy_as_bus_1 = 1, /* The SDIO bus */
+ cy_as_bus_0 = 2 /* The NAND bus (not implemented) */
+} cy_as_resource_type;
+
+/* Summary
+ Specifies the reset type for a software reset operation.
+
+ Description
+ When the West Bridge device is reset, there are two types of
+ reset that arE possible. This type indicates the type of reset
+ requested.
+
+ Notes
+ Both of these reset types are software based resets; and are
+ distinct from a chip level HARD reset that is applied through
+ the reset pin on the West Bridge.
+
+ The CyAsResetSoft type resets only the on-chip micro-controller
+ in the West Bridge. In this case, the previously loaded firmware
+ will continue running. However, the Storage and USB stack
+ operations will need to be restarted, as any state relating to
+ these would have been lost.
+
+ The CyAsResetHard type resets the entire West Bridge chip, and will
+ need a fresh configuration and firmware download.
+
+ See Also
+ * <LINK CyAsMiscReset>
+ */
+
+typedef enum cy_as_reset_type {
+ /* Just resets the West Bridge micro-controller */
+ cy_as_reset_soft,
+ /* Resets entire device, firmware must be reloaded and
+ the west bridge device must be re-initialized */
+ cy_as_reset_hard
+} cy_as_reset_type;
+
+
+
+/* Summary
+ This type specifies the polarity of the SD power pin.
+
+ Description
+ Sets the SD power pin ( port C, bit 6) to active low or
+ active high.
+
+*/
+
+typedef enum cy_as_misc_signal_polarity {
+ cy_as_misc_active_high,
+ cy_as_misc_active_low
+
+} cy_as_misc_signal_polarity ;
+
+
+
+/* Summary
+ This type specifies the type of the data returned by a Function
+ Callback.
+
+ Description
+ CY_FUNCT_CB_NODATA - This callback does not return any additional
+ information in the data field.
+ CY_FUNCT_CB_DATA - The data field is used, and the CyAsFunctCBType
+ will also contain the type of this data.
+
+ See Also
+ CyAsFunctionCallback
+*/
+typedef enum cy_as_funct_c_b_type {
+ CY_FUNCT_CB_INVALID = 0x0U,
+ /* Data from a CyAsMiscGetFirmwareVersion call. */
+ CY_FUNCT_CB_MISC_GETFIRMWAREVERSION,
+ /* Data from a CyAsMiscHeartBeatControl call. */
+ CY_FUNCT_CB_MISC_HEARTBEATCONTROL,
+ /* Data from a CyAsMiscAcquireResource call. */
+ CY_FUNCT_CB_MISC_ACQUIRERESOURCE,
+ /* Data from a CyAsMiscReadMCURegister call. */
+ CY_FUNCT_CB_MISC_READMCUREGISTER,
+ /* Data from a CyAsMiscWriteMCURegister call. */
+ CY_FUNCT_CB_MISC_WRITEMCUREGISTER,
+ /* Data from a CyAsMiscSetTraceLevel call. */
+ CY_FUNCT_CB_MISC_SETTRACELEVEL,
+ /* Data from a CyAsMiscStorageChanged call. */
+ CY_FUNCT_CB_MISC_STORAGECHANGED,
+ /* Data from a CyAsMiscGetGpioValue call. */
+ CY_FUNCT_CB_MISC_GETGPIOVALUE,
+ /* Data from a CyAsMiscSetGpioValue call. */
+ CY_FUNCT_CB_MISC_SETGPIOVALUE,
+ /* Data from a CyAsMiscDownloadFirmware call. */
+ CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE,
+ /* Data from a CyAsMiscEnterStandby call. */
+ CY_FUNCT_CB_MISC_ENTERSTANDBY,
+ /* Data from a CyAsMiscEnterSuspend call. */
+ CY_FUNCT_CB_MISC_ENTERSUSPEND,
+ /* Data from a CyAsMiscLeaveSuspend call. */
+ CY_FUNCT_CB_MISC_LEAVESUSPEND,
+ /* Data from a CyAsMiscReset call. */
+ CY_FUNCT_CB_MISC_RESET,
+ /* Data from a CyAsMiscSetLowSpeedSDFreq or
+ * CyAsMiscSetHighSpeedSDFreq call. */
+ CY_FUNCT_CB_MISC_SETSDFREQ,
+ /* Data from a CyAsMiscSwitchPnandMode call */
+ CY_FUNCT_CB_MISC_RESERVELNABOOTAREA,
+ /* Data from a CyAsMiscSetSDPowerPolarity call */
+ CY_FUNCT_CB_MISC_SETSDPOLARITY,
+
+ /* Data from a CyAsStorageStart call. */
+ CY_FUNCT_CB_STOR_START,
+ /* Data from a CyAsStorageStop call. */
+ CY_FUNCT_CB_STOR_STOP,
+ /* Data from a CyAsStorageClaim call. */
+ CY_FUNCT_CB_STOR_CLAIM,
+ /* Data from a CyAsStorageRelease call. */
+ CY_FUNCT_CB_STOR_RELEASE,
+ /* Data from a CyAsStorageQueryMedia call. */
+ CY_FUNCT_CB_STOR_QUERYMEDIA,
+ /* Data from a CyAsStorageQueryBus call. */
+ CY_FUNCT_CB_STOR_QUERYBUS,
+ /* Data from a CyAsStorageQueryDevice call. */
+ CY_FUNCT_CB_STOR_QUERYDEVICE,
+ /* Data from a CyAsStorageQueryUnit call. */
+ CY_FUNCT_CB_STOR_QUERYUNIT,
+ /* Data from a CyAsStorageDeviceControl call. */
+ CY_FUNCT_CB_STOR_DEVICECONTROL,
+ /* Data from a CyAsStorageSDRegisterRead call. */
+ CY_FUNCT_CB_STOR_SDREGISTERREAD,
+ /* Data from a CyAsStorageCreatePartition call. */
+ CY_FUNCT_CB_STOR_PARTITION,
+ /* Data from a CyAsStorageGetTransferAmount call. */
+ CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT,
+ /* Data from a CyAsStorageErase call. */
+ CY_FUNCT_CB_STOR_ERASE,
+ /* Data from a CyAsStorageCancelAsync call. */
+ CY_FUNCT_CB_ABORT_P2S_XFER,
+ /* Data from a CyAsUsbStart call. */
+ CY_FUNCT_CB_USB_START,
+ /* Data from a CyAsUsbStop call. */
+ CY_FUNCT_CB_USB_STOP,
+ /* Data from a CyAsUsbConnect call. */
+ CY_FUNCT_CB_USB_CONNECT,
+ /* Data from a CyAsUsbDisconnect call. */
+ CY_FUNCT_CB_USB_DISCONNECT,
+ /* Data from a CyAsUsbSetEnumConfig call. */
+ CY_FUNCT_CB_USB_SETENUMCONFIG,
+ /* Data from a CyAsUsbGetEnumConfig call. */
+ CY_FUNCT_CB_USB_GETENUMCONFIG,
+ /* Data from a CyAsUsbSetDescriptor call. */
+ CY_FUNCT_CB_USB_SETDESCRIPTOR,
+ /* Data from a CyAsUsbGetDescriptor call. */
+ CY_FUNCT_CB_USB_GETDESCRIPTOR,
+ /* Data from a CyAsUsbCommitConfig call. */
+ CY_FUNCT_CB_USB_COMMITCONFIG,
+ /* Data from a CyAsUsbGetNak call. */
+ CY_FUNCT_CB_USB_GETNAK,
+ /* Data from a CyAsUsbGetStall call. */
+ CY_FUNCT_CB_USB_GETSTALL,
+ /* Data from a CyAsUsbSignalRemoteWakeup call. */
+ CY_FUNCT_CB_USB_SIGNALREMOTEWAKEUP,
+ /* Data from a CyAnUsbClearDescriptors call. */
+ CY_FUNCT_CB_USB_CLEARDESCRIPTORS,
+ /* Data from a CyAnUsbSetMSReportThreshold call. */
+ CY_FUNCT_CB_USB_SET_MSREPORT_THRESHOLD,
+ /* Data from a CyAsMTPStart call. */
+ CY_FUNCT_CB_MTP_START,
+ /* Data from a CyAsMTPStop call. */
+ CY_FUNCT_CB_MTP_STOP,
+ /* Data from a CyAsMTPInitSendObject call. */
+ CY_FUNCT_CB_MTP_INIT_SEND_OBJECT,
+ /* Data from a CyAsMTPCancelSendObject call. */
+ CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT,
+ /* Data from a CyAsMTPInitGetObject call. */
+ CY_FUNCT_CB_MTP_INIT_GET_OBJECT,
+ /* Data from a CyAsMTPCancelGetObject call. */
+ CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT,
+ /* Data from a CyAsMTPSendBlockTable call. */
+ CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE,
+ /* Data from a CyAsMTPStopStorageOnly call. */
+ CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY,
+ CY_FUNCT_CB_NODATA = 0x40000000U,
+ CY_FUNCT_CB_DATA = 0x20000000U
+} cy_as_funct_c_b_type ;
+
+/* Summary
+ This type specifies the general West Bridge function callback.
+
+ Description
+ This callback is supplied as an argument to all asynchronous
+ functions in the API. It iS called after the asynchronous function
+ has completed.
+
+ See Also
+ CyAsFunctCBType
+*/
+typedef void (*cy_as_function_callback)(
+ cy_as_device_handle handle,
+ cy_as_return_status_t status,
+ uint32_t client,
+ cy_as_funct_c_b_type type,
+ void *data) ;
+
+/* Summary
+ This type specifies the general West Bridge event that has
+ occurred.
+
+ Description
+ This type is used in the West Bridge misc callback function to
+ indicate the type of callback.
+
+ See Also
+*/
+typedef enum cy_as_misc_event_type {
+ /* This event is sent when West Bridge has finished
+ initialization and is ready to respond to API calls. */
+ cy_as_event_misc_initialized = 0,
+
+ /* This event is sent when West Bridge has left the
+ standby state and is ready to respond to commands again. */
+ cy_as_event_misc_awake,
+
+ /* This event is sent periodically from the firmware
+ to the processor. */
+ cy_as_event_misc_heart_beat,
+
+ /* This event is sent when the West Bridge has left the
+ suspend mode and is ready to respond to commands
+ again. */
+ cy_as_event_misc_wakeup,
+
+ /* This event is sent when the firmware image downloaded
+ cannot run on the active west bridge device. */
+ cy_as_event_misc_device_mismatch
+} cy_as_misc_event_type ;
+
+/* Summary
+ This type is the type of a callback function that is called when a
+ West Bridge misc event occurs.
+
+ Description
+ At times West Bridge needs to inform the P port processor of events
+ that have occurred. These events are asynchronous to the thread of
+ control on the P port processor and as such are generally delivered
+ via a callback function that is called as part of an interrupt
+ handler. This type defines the type of function that must be provided
+ as a callback function for West Bridge misc events.
+
+ See Also
+ * CyAsMiscEventType
+*/
+typedef void (*cy_as_misc_event_callback)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The event type being reported */
+ cy_as_misc_event_type ev,
+ /* The data assocaited with the event being reported */
+ void *evdata
+) ;
+
+#ifndef __doxygen__
+/* Summary
+ This enum provides info of various firmware trace levels.
+
+ Description
+
+ See Also
+ * CyAsMiscSetTraceLevel
+*/
+enum {
+ CYAS_FW_TRACE_LOG_NONE = 0, /* Log nothing. */
+ CYAS_FW_TRACE_LOG_STATE, /* Log state information. */
+ CYAS_FW_TRACE_LOG_CALLS, /* Log function calls. */
+ CYAS_FW_TRACE_LOG_STACK_TRACE, /* Log function calls with args. */
+ CYAS_FW_TRACE_MAX_LEVEL /* Max trace level sentinel. */
+};
+#endif
+
+/* Summary
+ This enum lists the controllable GPIOs of the West Bridge device.
+
+ Description
+ The West Bridge device has GPIOs that can be used for user defined functions.
+ This enumeration lists the GPIOs that are available on the device.
+
+ Notes
+ All of the GPIOs except UVALID can only be accessed when using West Bridge
+ firmware images that support only SD/MMC/MMC+ storage devices. This
+ functionality is not supported in firmware images that support NAND
+ storage.
+
+ See Also
+ * CyAsMiscGetGpioValue
+ * CyAsMiscSetGpioValue
+ */
+typedef enum {
+ cy_as_misc_gpio_0 = 0, /* GPIO[0] pin */
+ cy_as_misc_gpio_1, /* GPIO[1] pin */
+ cy_as_misc_gpio__nand_CE, /* NAND_CE pin, output only */
+ cy_as_misc_gpio__nand_CE2, /* NAND_CE2 pin, output only */
+ cy_as_misc_gpio__nand_WP, /* NAND_WP pin, output only */
+ cy_as_misc_gpio__nand_CLE, /* NAND_CLE pin, output only */
+ cy_as_misc_gpio__nand_ALE, /* NAND_ALE pin, output only */
+ /* SD_POW pin, output only, do not drive low while storage is active */
+ cy_as_misc_gpio_SD_POW,
+ cy_as_misc_gpio_U_valid /* UVALID pin */
+} cy_as_misc_gpio;
+
+/* Summary
+ This enum lists the set of clock frequencies that are supported for
+ working with low speed SD media.
+
+ Description
+ West Bridge firmware uses a clock frequency less than the maximum
+ possible rate for low speed SD media. This can be changed to a
+ setting equal to the maximum frequency as desired by the user. This
+ enumeration lists the different frequency settings that are
+ supported.
+
+ See Also
+ * CyAsMiscSetLowSpeedSDFreq
+ */
+typedef enum cy_as_low_speed_sd_freq {
+ /* Approx. 21.82 MHz, default value */
+ CY_AS_SD_DEFAULT_FREQ = 0,
+ /* 24 MHz */
+ CY_AS_SD_RATED_FREQ
+} cy_as_low_speed_sd_freq ;
+
+/* Summary
+ This enum lists the set of clock frequencies that are supported
+ for working with high speed SD media.
+
+ Description
+ West Bridge firmware uses a 48 MHz clock by default to interface
+ with high speed SD/MMC media. This can be changed to 24 MHz if
+ so desired by the user. This enum lists the different frequencies
+ that are supported.
+
+ See Also
+ * CyAsMiscSetHighSpeedSDFreq
+ */
+typedef enum cy_as_high_speed_sd_freq {
+ CY_AS_HS_SD_FREQ_48, /* 48 MHz, default value */
+ CY_AS_HS_SD_FREQ_24 /* 24 MHz */
+} cy_as_high_speed_sd_freq ;
+
+/* Summary
+ Struct encapsulating all information returned by the
+ CyAsMiscGetFirmwareVersion call.
+
+ Description
+ This struct encapsulates all return values from the asynchronous
+ CyAsMiscGetFirmwareVersion call, so that a single data argument
+ can be passed to the user provided callback function.
+
+ See Also
+ * CyAsMiscGetFirmwareVersion
+ */
+typedef struct cy_as_get_firmware_version_data {
+ /* Return value for major version number for the firmware */
+ uint16_t major;
+ /* Return value for minor version number for the firmware */
+ uint16_t minor;
+ /* Return value for build version number for the firmware */
+ uint16_t build;
+ /* Return value for media types supported in the current firmware */
+ uint8_t media_type;
+ /* Return value to indicate the release or debug mode of firmware */
+ cy_bool is_debug_mode;
+} cy_as_get_firmware_version_data ;
+
+
+/*****************************
+ * West Bridge Functions
+ *****************************/
+
+/* Summary
+ This function creates a new West Bridge device and returns a
+ handle to the device.
+
+ Description
+ This function initializes the API object that represents the West
+ Bridge device and returns a handle to this device. This handle is
+ required for all West Bridge related functions to identify the
+ specific West Bridge device.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_OUT_OF_MEMORY
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_create_device(
+ /* Return value for handle to created device */
+ cy_as_device_handle *handle_p,
+ /* The HAL specific tag for this device */
+ cy_as_hal_device_tag tag
+ ) ;
+
+/* Summary
+ This functions destroys a previously created West Bridge device.
+
+ Description
+ When an West Bridge device is created, an opaque handle is returned
+ that represents the device. This function destroys that handle and
+ frees all resources associated with the handle.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_STILL_RUNNING - The USB or STORAGE stacks are still
+ * running, they must be stopped before the device can be destroyed
+ * CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED - the HAL layer failed to
+ * destroy a sleep channel
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_destroy_device(
+ /* Handle to the device to destroy */
+ cy_as_device_handle handle
+ ) ;
+
+/* Summary
+ This function initializes the hardware for basic communication with
+ West Bridge.
+
+ Description
+ This function intializes the hardware to establish basic
+ communication with the West Bridge device. This is always the first
+ function called to initialize communication with the West Bridge
+ device.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the basic initialization was completed
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_IN_STANDBY
+ * CY_AS_ERROR_ALREADY_RUNNING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_NO_ANTIOCH - cannot find the West Bridge device
+ * CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED -
+ * the HAL layer falied to create a sleep channel
+
+ See Also
+ * CyAsDeviceConfig
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_configure_device(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Configuration information */
+ cy_as_device_config *config_p
+ ) ;
+
+/* Summary
+ This function returns non-zero if West Bridge is in standby and
+ zero otherwise.
+
+ Description
+ West Bridge supports a standby mode. This function is used to
+ query West Bridge to determine if West Bridge is in a standby
+ mode.
+
+ * Valid In Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_in_standby(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Return value for standby state */
+ cy_bool *standby
+ ) ;
+
+/* Summary
+ This function downloads the firmware to West Bridge device.
+
+ Description
+ This function downloads firmware from a given location and with a
+ given size to the West Bridge device. After the firmware is
+ downloaded the West Bridge device is moved out of configuration
+ mode causing the firmware to be executed. It is an error to call
+ this function when the device is not in configuration mode. The
+ device is in configuration mode on power up and may be placed in
+ configuration mode after power up with a hard reset.
+
+ Notes
+ The firmware must be on a word align boundary.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the firmware was sucessfully downloaded
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * was not configured
+ * CY_AS_ERROR_NOT_IN_CONFIG_MODE
+ * CY_AS_ERROR_INVALID_SIZE - the size of the firmware
+ * exceeded 32768 bytes
+ * CY_AS_ERROR_ALIGNMENT_ERROR
+ * CY_AS_ERROR_IN_STANDBY - trying to download
+ * while in standby mode
+ * CY_AS_ERROR_TIMEOUT
+
+ See Also
+ * CyAsMiscReset
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_download_firmware(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Pointer to the firmware to be downloaded */
+ const void *fw_p,
+ /* The size of the firmware in bytes */
+ uint16_t size,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+
+/* Summary
+ This function returns the version number of the firmware running in
+ the West Bridge device.
+
+ Description
+ This function queries the West Bridge device and retreives the
+ firmware version number. If the firmware is not loaded an error is
+ returned indicated no firmware has been loaded.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the firmware version number was retreived
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been downloaded
+ * to the device
+ * CY_AS_ERROR_IN_STANDBY
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response
+ * from the West Bridge firmware
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_get_firmware_version(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Return values indicating the firmware version. */
+ cy_as_get_firmware_version_data *data,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+#if !defined(__doxygen__)
+
+/* Summary
+ This function reads and returns the contents of an MCU accessible
+ register on the West Bridge.
+
+ Description
+ This function requests the firmware to read and return the contents
+ of an MCU accessible register through the mailboxes.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the register content was retrieved.
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response
+ * from the West Bridge firmware
+ * CY_AS_ERROR_INVALID_RESPONSE - the firmware build does not
+ * support this command.
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_read_m_c_u_register(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Address of the register to read */
+ uint16_t address,
+ /* Return value for the MCU register content */
+ uint8_t *value,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function writes to an MCU accessible register on the West Bridge.
+
+ Description
+ This function requests the firmware to write a specified value to an
+ MCU accessible register through the mailboxes.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ This function is only for internal use by the West Bridge API layer.
+ Calling this function directly can cause device malfunction.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the register content was updated.
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response
+ * from the West Bridge firmware
+ * CY_AS_ERROR_INVALID_RESPONSE - the firmware build does not support
+ * this command.
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_write_m_c_u_register(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Address of the register to write */
+ uint16_t address,
+ /* Mask to be applied on the register contents. */
+ uint8_t mask,
+ /* Data to be ORed with the register contents. */
+ uint8_t value,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+#endif
+
+/* Summary
+ This function will reset the West Bridge device and software API.
+
+ Description
+ This function will reset the West Bridge device and software API.
+ The reset operation can be a hard reset or a soft reset. A hard
+ reset will reset all aspects of the West Bridge device. The device
+ will enter the configuration state and the firmware will have to be
+ reloaded. The device will also have to be re-initialized. A soft
+ reset just resets the West Bridge micro-controller.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ When a hard reset is issued, the firmware that may have been
+ previously loaded will be lost and any configuration information set
+ via CyAsMiscConfigureDevice() will be lost. This will be reflected
+ in the API maintained state of the device. In order to re-establish
+ communications with the West Bridge device, CyAsMiscConfigureDevice()
+ and CyAsMiscDownloadFirmware() must be called again.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the device has been reset
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_NOT_YET_SUPPORTED - current soft reset is not supported
+ * CY_AS_ERROR_ASYNC_PENDING - Reset is unable to flush pending async
+ * reads/writes in polling mode.
+
+
+ See Also
+ * CyAsMiscReset
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_reset(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The type of reset to perform */
+ cy_as_reset_type type,
+ /* If true, flush all pending writes to mass storage
+ before performing the reset. */
+ cy_bool flush,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function acquires a given resource.
+
+ Description
+ There are resources in the system that are shared between the
+ West Bridge device and the processor attached to the P port of
+ the West Bridge device. This API provides a mechanism for the
+ P port processor to acquire ownership of a resource.
+
+ Notes
+ The ownership of the resources controlled by CyAsMiscAcquireResource()
+ and CyAsMiscReleaseResource() defaults to a known state at hardware
+ reset. After the firmware is loaded and begins execution the state of
+ these resources may change. At any point if the P Port processor needs
+ to acquire a resource it should do so explicitly to be sure of
+ ownership.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the p port sucessfully acquired the
+ * resource of interest
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_INVALID_RESOURCE
+ * CY_AS_ERROR_RESOURCE_ALREADY_OWNED - the p port already
+ * owns this resource
+ * CY_AS_ERROR_NOT_ACQUIRED - the resource cannot be acquired
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a
+ * response from the West Bridge firmware
+
+ See Also
+ * CyAsResourceType
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_acquire_resource(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The resource to acquire */
+ cy_as_resource_type *resource,
+ /* If true, force West Bridge to release the resource */
+ cy_bool force,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function releases a given resource.
+
+ Description
+ There are resources in the system that are shared between the
+ West Bridge device and the processor attached to the P port of
+ the West Bridge device. This API provides a mechanism for the
+ P port processor to release a resource that has previously been
+ acquired via the CyAsMiscAcquireResource() call.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the p port sucessfully released
+ * the resource of interest
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_INVALID_RESOURCE
+ * CY_AS_ERROR_RESOURCE_NOT_OWNED - the p port does not own the
+ * resource of interest
+
+ See Also
+ * CyAsResourceType
+ * CyAsMiscAcquireResource
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_release_resource(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The resource to release */
+ cy_as_resource_type resource
+ ) ;
+
+#ifndef __doxygen__
+/* Summary
+ This function sets the trace level for the West Bridge firmware.
+
+ Description
+ The West Bridge firmware has the ability to store information
+ about the state and execution path of the firmware on a mass storage
+ device attached to the West Bridge device. This function configures
+ the specific mass storage device to be used and the type of information
+ to be stored. This state information is used for debugging purposes
+ and must be interpreted by a Cypress provided tool.
+
+ *Trace Level*
+ The trace level indicates the amount of information to output.
+ * 0 = no trace information is output
+ * 1 = state information is output
+ * 2 = function call information is output
+ * 3 = function call, arguments, and return value information is output
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ The media device and unit specified in this call will be overwritten
+ and any data currently stored on this device and unit will be lost.
+
+ * NOT IMPLEMENTED YET
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the trace configuration has been
+ * sucessfully changed
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified does not exist
+ * CY_AS_ERROR_INVALID_TRACE_LEVEL - the trace level requested
+ * does not exist
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a
+ * response from the West Bridge firmware
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_set_trace_level(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The trace level */
+ uint8_t level,
+ /* The bus for the output */
+ cy_as_bus_number_t bus,
+ /* The device for the output */
+ uint32_t device,
+ /* The unit for the output */
+ uint32_t unit,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+#endif
+
+/* Summary
+ This function places West Bridge into the low power standby mode.
+
+ Description
+ This function places West Bridge into a low power (sleep) mode, and
+ cannot be called while the USB stack is active. This function first
+ instructs the West Bridge firmware that the device is about to be
+ placed into sleep mode. This allows West Bridge to complete any pending
+ storage operations. After the West Bridge device has responded that
+ pending operations are complete, the device is placed in standby mode.
+
+ There are two methods of placing the device in standby mode. If the
+ WAKEUP pin of the West Bridge is connected to a GPIO on the processor,
+ the pin is de-asserted (via the HAL layer) and West Bridge enters into
+ a sleep mode. If the WAKEUP pin is not accessible, the processor can
+ write into the power management control/status register on the West
+ Bridge to put the device into sleep mode.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function completed and West Bridge
+ * is in sleep mode
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_ALREADY_STANDBY - the West Bridge device is already
+ * in sleep mode
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response
+ * from the West Bridge firmware
+ * CY_AS_ERROR_NOT_SUPPORTED - the HAL layer does not support changing
+ * the WAKEUP pin
+ * CY_AS_ERROR_USB_RUNNING - The USB stack is still running when the
+ * EnterStandby call is made
+ * CY_AS_ERROR_ASYNC_PENDING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_SETTING_WAKEUP_PIN
+ * CY_AS_ERROR_ASYNC_PENDING - In polling mode EnterStandby can not
+ * be called until all pending storage read/write requests have
+ * finished.
+
+ See Also
+ * CyAsMiscLeaveStandby
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_enter_standby_e_x_u(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* If true, use the wakeup pin, otherwise use the register */
+ cy_bool pin,
+ /* Set true to enable specific usages of the
+ UVALID signal, please refer to AN xx or ERRATA xx */
+ cy_bool uvalid_special,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function is provided for backwards compatibility.
+
+ Description
+ Calling this function is the same as calling CyAsMiscEnterStandbyEx
+ with True for the lowpower parameter.
+
+ See Also
+ * CyAsMiscEnterStandbyEx
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_enter_standby(cy_as_device_handle handle,
+ cy_bool pin,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function brings West Bridge out of sleep mode.
+
+ Description
+ This function asserts the WAKEUP pin (via the HAL layer). This
+ brings the West Bridge out of the sleep state and allows the
+ West Bridge firmware to process the event causing the wakeup.
+ When all processing associated with the wakeup is complete, a
+ callback function is called to tell the P port software that
+ the firmware processing associated with wakeup is complete.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns:
+ * CY_AS_ERROR_SUCCESS - the function completed and West Bridge
+ * is in sleep mode
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_SETTING_WAKEUP_PIN
+ * CY_AS_ERROR_NOT_IN_STANDBY - the West Bridge device is not in
+ * the sleep state
+ * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a
+ * response from the West Bridge firmware
+ * CY_AS_ERROR_NOT_SUPPORTED - the HAL layer does not support
+ * changing the WAKEUP pin
+
+ See Also
+ * CyAsMiscEnterStandby
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_leave_standby(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The resource causing the wakeup */
+ cy_as_resource_type resource
+ ) ;
+
+/* Summary
+ This function registers a callback function to be called when an
+ asynchronous West Bridge MISC event occurs.
+
+ Description
+ When asynchronous misc events occur, a callback function can be
+ called to alert the calling program. This functions allows the
+ calling program to register a callback.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns:
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_register_callback(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The function to call */
+ cy_as_misc_event_callback callback
+ ) ;
+
+/* Summary
+ This function sets the logging level for log messages.
+
+ Description
+ The API can print messages via the CyAsHalPrintMessage capability.
+ This function sets the level of detail seen when printing messages
+ from the API.
+
+ * Valid In Asynchronous Callback:NO
+*/
+EXTERN void
+cy_as_misc_set_log_level(
+ /* Level to set, 0 is fewer messages, 255 is all */
+ uint8_t level
+ ) ;
+
+
+/* Summary
+ This function tells West Bridge that SD or MMC media has been
+ inserted or removed.
+
+ Description
+ In some hardware configurations, SD or MMC media detection is
+ handled outside of the West Bridge device. This function is called
+ when a change is detected to inform the West Bridge firmware to check
+ for storage media changes.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns:
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_IN_STANDBY
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsMiscStorageChanged
+
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_storage_changed(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function instructs the West Bridge firmware to start/stop
+ sending periodic heartbeat messages to the processor.
+
+ Description
+ The West Bridge firmware can send heartbeat messages through the
+ mailbox register once every 500 ms. This message can be an overhead
+ as it causes regular Mailbox interrupts to happen, and is turned
+ off by default. The message can be used to test and verify that the
+ West Bridge firmware is alive. This API can be used to enable or
+ disable the heartbeat message.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function completed successfully
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured yet
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded to
+ * the West Bridge device
+
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_heart_beat_control(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Message enable/disable selection */
+ cy_bool enable,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function gets the current state of a GPIO pin on the
+ West Bridge device.
+
+ Description
+ The West Bridge device has GPIO pins that can be used for user
+ defined functions. This function gets the current state of the
+ specified GPIO pin. Calling this function will configure the
+ corresponding pin as an input.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ Only GPIO[0], GPIO[1] and UVALID pins can be used as GP inputs.
+ Of these pins, only the UVALID pin is supported by firmware images
+ that include NAND storage support.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function completed successfully
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured yet
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded
+ * to the West Bridge device
+ * CY_AS_ERROR_BAD_INDEX - an invalid GPIO was specified
+ * CY_AS_ERROR_NOT_SUPPORTED - this feature is not supported
+ * by the firmware
+
+ See Also
+ * CyAsMiscGpio
+ * CyAsMiscSetGpioValue
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_get_gpio_value(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Id of the GPIO pin to query */
+ cy_as_misc_gpio pin,
+ /* Current value of the GPIO pin */
+ uint8_t *value,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function updates the state of a GPIO pin on the West
+ Bridge device.
+
+ Description
+ The West Bridge device has GPIO pins that can be used for
+ user defined functions. This function updates the output
+ value driven on a specified GPIO pin. Calling this function
+ will configure the corresponding pin as an output.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ All of the pins listed under CyAsMiscGpio can be used as GP
+ outputs. This feature is note supported by firmware images
+ that include NAND storage device support.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function completed successfully
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured yet
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded
+ * to the West Bridge device
+ * CY_AS_ERROR_BAD_INDEX - an invalid GPIO was specified
+ * CY_AS_ERROR_NOT_SUPPORTED - this feature is not supported
+ * by firmware.
+
+ See Also
+ * CyAsMiscGpio
+ * CyAsMiscGetGpioValue
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_set_gpio_value(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Id of the GPIO pin to set */
+ cy_as_misc_gpio pin,
+ /* Value to be set on the GPIO pin */
+ uint8_t value,
+ /* Callback to call when the operation is complete. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Set the West Bridge device in the low power suspend mode.
+
+ Description
+ The West Bridge device has a low power suspend mode where the USB
+ core and the internal microcontroller are powered down. This
+ function sets the West Bridge device into this low power mode.
+ This mode can only be entered when there is no active USB
+ connection; i.e., when USB has not been connected or is suspended;
+ and there are no pending USB or storage asynchronous calls. The
+ device will exit the suspend mode and resume handling USB and
+ processor requests when any activity is detected on the CE#, D+/D-
+ or GPIO[0] lines.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ The GPIO[0] pin needs to be configured as an input for the gpio
+ wakeup to work. This flag should not be enabled if the pin is
+ being used as a GP output.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the device was placed in suspend mode.
+ * CY_AS_ERROR_INVALID_HANDLE - the West Bridge handle passed
+ * in is invalid.
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * yet been configured.
+ * CY_AS_ERROR_NO_FIRMWARE - no firmware has been downloaded
+ * to the device.
+ * CY_AS_ERROR_IN_STANDBY - the device is already in sleep mode.
+ * CY_AS_ERROR_USB_CONNECTED - the USB connection is active.
+ * CY_AS_ERROR_ASYNC_PENDING - asynchronous storage/USB calls
+ * are pending.
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for
+ * the operation.
+ * CY_AS_ERROR_INVALID_RESPONSE - command not recognised by
+ * firmware.
+
+ See Also
+ * CyAsMiscLeaveSuspend
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_enter_suspend(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Control the USB wakeup source */
+ cy_bool usb_wakeup_en,
+ /* Control the GPIO[0] wakeup source */
+ cy_bool gpio_wakeup_en,
+ /* Callback to call when suspend mode entry is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Wake up the West Bridge device from suspend mode.
+
+ Description
+ This call wakes up the West Bridge device from suspend mode,
+ and makes it ready for accepting other commands from the API.
+ A CyAsEventMiscWakeup event will be delivered to the callback
+ registered with CyAsMiscRegisterCallback to indicate that the
+ wake up is complete.
+
+ The CyAsEventMiscWakeup event will also be delivered if the
+ wakeup happens due to USB or GPIO activity.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the device was woken up from
+ * suspend mode.
+ * CY_AS_ERROR_INVALID_HANDLE - invalid device handle
+ * passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has
+ * not been configured.
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been
+ * downloaded to the device.
+ * CY_AS_ERROR_NOT_IN_SUSPEND - the device is not in
+ * suspend mode.
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory
+ * for the operation.
+ * CY_AS_ERROR_TIMEOUT - failed to wake up the device.
+
+ See Also
+ * CyAsMiscEnterSuspend
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_leave_suspend(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Callback to call when device has resumed operation. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Reserve first numzones zones of nand device for storing
+ processor boot image. LNA firmware works on the first
+ numzones zones of nand to enable the processor to boot.
+
+ Description
+ This function reserves first numzones zones of nand device
+ for storing processor boot image. This fonction MUST be
+ completed before starting the storage stack for the setting
+ to be taken into account.
+
+ * Valid In Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS- zones are reserved.
+
+*/
+EXTERN cy_as_return_status_t
+cy_as_misc_reserve_l_n_a_boot_area(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* number of nand zones to reserve */
+ uint8_t numzones,
+ /* Callback to call when device has resumed operation. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Select the clock frequency to be used when talking to low
+ speed (non-high speed) SD media.
+
+ Description
+ West Bridge firmware uses a clock frequency less than the
+ maximum possible rate for low speed SD media. This function
+ selects the frequency setting from between the default speed
+ and the maximum speed. This fonction MUST be completed before
+ starting the storage stack for the setting to be taken into
+ account.
+
+ * Valid in Asynchronous Callback: Yes (if cb is non-zero)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the operation completed successfully.
+ * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been
+ * configured.
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded
+ * to the device.
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for
+ * the operation.
+ * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power suspend
+ * mode.
+ * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting
+ * desired.
+ * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to
+ * the operation.
+ * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not support
+ * the operation.
+
+ See Also
+ * CyAsLowSpeedSDFreq
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_set_low_speed_sd_freq(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Frequency setting desired for low speed SD cards */
+ cy_as_low_speed_sd_freq setting,
+ /* Callback to call on completion */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Select the clock frequency to be used when talking to high speed
+ SD/MMC media.
+
+ Description
+ West Bridge firmware uses a 48 MHz clock to interface with high
+ speed SD/MMC media. This clock rate can be restricted to 24 MHz
+ if desired. This function selects the frequency setting to be
+ used. This fonction MUST be completed before starting the storage
+ stack for the setting to be taken into account.
+
+ * Valid in Asynchronous Callback: Yes (if cb is non-zero)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the operation completed successfully.
+ * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been
+ * configured.
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded to
+ * the device.
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for the
+ * operation.
+ * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power suspend mode.
+ * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting desired.
+ * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to the
+ * operation.
+ * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not support
+ * the operation.
+
+ See Also
+ * CyAsLowSpeedSDFreq
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_set_high_speed_sd_freq(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Frequency setting desired for high speed SD cards */
+ cy_as_high_speed_sd_freq setting,
+ /* Callback to call on completion */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+/* Summary
+ Select the polarity of the SD_POW output driven by West Bridge.
+
+ Description
+ The SD_POW signal driven by West Bridge can be used to control
+ the supply of Vcc to the SD/MMC media connected to the device.
+ This signal is driven as an active high signal by default. This
+ function can be used to change the polarity of this signal if
+ required. This fonction MUST be completed before starting the
+ storage stack for the setting to be taken into account.
+
+ * Valid in Asynchronous Callback: Yes (if cb is non-zero)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the operation completed successfully.
+ * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been
+ * configured.
+ * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded
+ * to the device.
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for
+ * the operation.
+ * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power
+ * suspend mode.
+ * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting
+ * desired.
+ * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to
+ * the operation.
+ * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not
+ * support the operation.
+
+ See Also
+ * CyAsMiscSignalPolarity
+ */
+EXTERN cy_as_return_status_t
+cy_as_misc_set_sd_power_polarity(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Desired polarity setting to the SD_POW signal. */
+ cy_as_misc_signal_polarity polarity,
+ /* Callback to call on completion. */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback. */
+ uint32_t client
+ ) ;
+
+/* For supporting deprecated functions */
+#include "cyasmisc_dep.h"
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASMISC_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h
new file mode 100644
index 000000000000..8b258efc0182
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h
@@ -0,0 +1,53 @@
+/* Cypress West Bridge API header file (cyasmisc_dep.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/* This header will contain Antioch specific declaration
+ * of the APIs that are deprecated in Astoria SDK. This is
+ * for maintaining backward compatibility with prior releases
+ * of the Antioch SDK.
+ */
+#ifndef __INCLUDED_CYASMISC_DEP_H__
+#define __INCLUDED_CYASMISC_DEP_H__
+
+#ifndef __doxygen__
+
+EXTERN cy_as_return_status_t
+cy_as_misc_acquire_resource_dep(cy_as_device_handle handle,
+ cy_as_resource_type resource,
+ cy_bool force);
+EXTERN cy_as_return_status_t
+cy_as_misc_get_firmware_version_dep(cy_as_device_handle handle,
+ uint16_t *major,
+ uint16_t *minor,
+ uint16_t *build,
+ uint8_t *media_type,
+ cy_bool *is_debug_mode);
+EXTERN cy_as_return_status_t
+cy_as_misc_set_trace_level_dep(cy_as_device_handle handle,
+ uint8_t level,
+ cy_as_media_type media,
+ uint32_t device,
+ uint32_t unit,
+ cy_as_function_callback cb,
+ uint32_t client);
+#endif /*__doxygen*/
+
+#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h
new file mode 100644
index 000000000000..25af22e9a6b7
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h
@@ -0,0 +1,646 @@
+/* Cypress West Bridge API header file (cyasmtp.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASMTP_H_
+#define _INCLUDED_CYASMTP_H_
+
+#include "cyasmisc.h"
+
+#include "cyas_cplus_start.h"
+
+/*@@Media Transfer Protocol (MTP) Overview
+ Summary
+ The MTP API has been designed to allow MTP enabled West Bridge
+ devices to implement the MTP protocol while maintaining high
+ performance. West Bridge has the capability to enter into a
+ Turbo mode during a MTP SendObject or GetObject operation
+ enabling it to directly stream the data into or out of the
+ attached SD card with minimal involvement from the Processor.
+
+ Description
+ The MTP API is designed to act as a pass through implementation
+ of the MTP protocol for all operations. Each MTP transaction
+ received from the Host is passed through West Bridge and along
+ to the Processor. The Processor can then respond to the
+ transaction and pass data and/or responses back to the Host
+ through West Bridge.
+
+ The MTP API also allows for a high speed handling of MTP
+ SendObject and GetObject operations, referred to as Turbo MTP.
+ During a Turbo MTP operation West Bridge is responsible for
+ reading or writing the data for the MTP operation directly from
+ or to the SD card with minimal interaction from the Processor.
+ The is done by having the Processor transfer a Block Table
+ to West Bridge which contains the locations on the SD card that
+ need to be read or written. During the handling of a Turbo
+ Operation the Processor will then only periodically need to
+ send a new Block Table to West Bridge when the first is used up.
+ See the CyAsMTPInitSendObject and CyAsMTPInitGetObject functions
+ for more details.
+
+ In order to enable the MTP API you must first have a MTP enabled
+ West Bridge loaded with MTP firmware. You then must start the USB
+ and Storage APIs before starting the MTP API. See CyAsMTPStart
+ for more details.
+*/
+
+/*@@Endpoints
+ Summary
+ When using MTP firmware endpoints 2 and 6 are dedicated
+ to bulk MTP traffic and endpoint 1 is available for MTP
+ events.
+
+ Description
+ When using a MTP enabled West Brdige device endpoints 2 and
+ 6 are made available for use to implement the MTP protocol.
+ These endpoints have a few special restrictions noted below
+ but otherwise the existing USB APIs can be used normally with
+ these endpoints.
+
+ 1. CyAsUsbSetNak, CyAsUsbClearNak, and CyAsUsbGetNak are
+ disabled for these endpoints
+ 2. During a turbo operation CyAsUsbSetStall, CyAsUsbClearStall,
+ and CyAsUsbGetStall are disabled.
+
+*/
+
+
+/* Summary
+ This constants defines the maximum number of
+ entries in the Block Table used to describe
+ the locations for Send/GetObject operations.
+
+ See Also
+ * CyAsMtpSendObject
+ * CyAsMtpGetObject
+*/
+#define CY_AS_MAX_BLOCK_TABLE_ENTRIES 64
+
+/* Summary
+ Endpoint to be used for MTP reads from the USB host.
+ */
+#define CY_AS_MTP_READ_ENDPOINT (2)
+
+/* Summary
+ Endpoint to be used fro MTP writes to the USB host.
+ */
+#define CY_AS_MTP_WRITE_ENDPOINT (6)
+
+/******************************************
+ * MTP Types
+ ******************************************/
+
+/* Summary
+ The BlockTable used for turbo operations.
+
+ Description
+ This struct is used to specify the blocks
+ to be used for both read/write and send/getObject
+ operations.
+
+ The start block is a starting Logical Block Address
+ and num block is the number of blocks in that contiguous
+ region.
+
+ start_blocks[i]->[-------] <- start_blocks[i] + num_blocks[i]
+
+ If you need fewer than CY_AS_MAX_BLOCK_TABLE_ENTRIES
+ the remainder should be left empty. Empty is defined
+ as num_blocks equal to 0.
+
+ See Also
+ * CyAsMTPInitSendObject
+ * CyAsMTPInitGetObject
+
+*/
+typedef struct cy_as_mtp_block_table {
+ uint32_t start_blocks[CY_AS_MAX_BLOCK_TABLE_ENTRIES] ;
+ uint16_t num_blocks[CY_AS_MAX_BLOCK_TABLE_ENTRIES] ;
+} cy_as_mtp_block_table ;
+
+/* Summary
+ This type specifies the type of MTP event that has occurred.
+
+ Description
+ MTP events are used to communicate that West Bridge has
+ either finished the handling of the given operation, or
+ that it requires additional data to complete the operation.
+
+ In no case does West Bridge send any MTP protocol responses,
+ this always remain the responsibility of the client.
+
+ See Also
+ * CyAsMTPInitSendObject
+ * CyAsMTPInitGetObject
+ * CyAsMTPSendBlockTable
+
+*/
+typedef enum cy_as_mtp_event {
+ /* This event is sent when West Bridge
+ has finished writing the data from a
+ send_object. west bridge will -not- send
+ the MTP response. */
+ cy_as_mtp_send_object_complete,
+
+ /* This event is sent when West Bridge
+ has finished sending the data for a
+ get_object operation. west bridge will
+ -not- send the MTP response. */
+ cy_as_mtp_get_object_complete,
+
+ /* This event is called when West Bridge
+ needs a new block_table. this is only a
+ notification, to transfer a block_table
+ to west bridge the cy_as_mtp_send_block_table
+ use the function. while west bridge is waiting
+ for a block_table during a send_object it
+ may need to NAK the endpoint. it is important
+ that the cy_as_mtp_send_block_table call is made
+ in a timely manner as eventually a delay
+ will result in an USB reset. this event has
+ no data */
+ cy_as_mtp_block_table_needed
+} cy_as_mtp_event ;
+
+/* Summary
+ Data for the CyAsMTPSendObjectComplete event.
+
+ Description
+ Notification that a SendObject operation has been
+ completed. The status of the operation is given
+ (to distinguish between a cancelled and a success
+ for example) as well as the block count. The blocks
+ are used in order based on the current block table.
+ If more than one block table was used for a given
+ SendObject the count will include the total number
+ of blocks written.
+
+ This callback will be made only once per SendObject
+ operation and it will only be called after all of
+ the data has been committed to the SD card.
+
+ See Also
+ * CyAsMTPEvent
+
+ */
+typedef struct cy_as_mtp_send_object_complete_data {
+ cy_as_return_status_t status ;
+ uint32_t byte_count ;
+ uint32_t transaction_id ;
+} cy_as_mtp_send_object_complete_data ;
+
+/* Summary
+ Data for the CyAsMTPGetObjectComplete event.
+
+ Description
+ Notification that a GetObject has finished. This
+ event allows the P side to know when to send the MTP
+ response for the GetObject operation.
+
+ See Also
+ * CyAsMTPEvent
+
+*/
+typedef struct cy_as_mtp_get_object_complete_data {
+ cy_as_return_status_t status ;
+ uint32_t byte_count ;
+} cy_as_mtp_get_object_complete_data ;
+
+/* Summary
+ MTP Event callback.
+
+ Description
+ Callback used to communicate that a SendObject
+ operation has finished.
+
+ See Also
+ * CyAsMTPEvent
+*/
+typedef void (*cy_as_mtp_event_callback)(
+ cy_as_device_handle handle,
+ cy_as_mtp_event evtype,
+ void *evdata
+ ) ;
+
+/* Summary
+ This is the callback function called after asynchronous API
+ functions have completed.
+
+ Description
+ When calling API functions from callback routines (interrupt
+ handlers usually) the async version of these functions must
+ be used. This callback is called when an asynchronous API
+ function has completed.
+*/
+typedef void (*cy_as_mtp_function_callback)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The error status of the operation */
+ cy_as_return_status_t status,
+ /* A client supplied 32 bit tag */
+ uint32_t client
+) ;
+
+/**************************************
+ * MTP Functions
+ **************************************/
+
+/* Summary
+ This function starts the MTP stack.
+
+ Description
+ Initializes West Bridge for MTP activity and registers the MTP
+ event callback.
+
+ Before calling CyAsMTPStart, CyAsUsbStart and CyAsStorageStart must be
+ called (in either order).
+
+ MTPStart must be called before the device is enumerated. Please
+ see the documentation for CyAsUsbSetEnumConfig and CyAsUsbEnumControl
+ for details on enumerating a device for MTP.
+
+ Calling MTPStart will not affect any ongoing P<->S traffic.
+
+ This requires a MTP firmware image to be loaded on West Bridge.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_IN_SUSPEND
+ * CY_AS_ERROR_INVALID_IN_CALLBACK
+ * CY_AS_ERROR_STARTSTOP_PENDING
+ * CY_AS_ERROR_NOT_RUNNING - CyAsUsbStart or CyAsStorageStart
+ * have not been called
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+
+ See Also
+ * CyAsMTPStop
+ * CyAsUsbStart
+ * CyAsStorageStart
+ * CyAsUsbSetEnumConfig
+ * CyAsUsbEnumControl
+*/
+cy_as_return_status_t
+cy_as_mtp_start(
+ cy_as_device_handle handle,
+ cy_as_mtp_event_callback event_c_b,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+
+/* Summary
+ This function stops the MTP stack.
+
+ Description
+ Stops all MTP activity. Any ongoing transfers are
+ canceled.
+
+ This will not cause a UsbDisconnect but all
+ MTP activity (both pass through and turbo) will
+ stop.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_IN_SUSPEND
+ * CY_AS_ERROR_INVALID_IN_CALLBACK
+ * CY_AS_ERROR_STARTSTOP_PENDING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+
+ See Also
+ * CyAsMTPStart
+*/
+cy_as_return_status_t
+cy_as_mtp_stop(
+ cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets up a Turbo SendObject operation.
+
+ Description
+ Calling this function will setup West Bridge to
+ enable Tubo handling of the next SendObject
+ operation received. This will pass down the initial
+ block table to the firmware and setup a direct u->s
+ write for the SendObject operation.
+
+ If this function is not called before a SendObject
+ operation is seen the SendObject operation and data
+ will be passed along to the P port like any other MTP
+ command. It would then be the responsibility of the
+ client to perform a normal StorageWrite call to
+ store the data on the SD card. N.B. This will be
+ very slow compared with the Turbo handling.
+
+ The completion of this function only signals that
+ West Bridge has been set up to receive the next SendObject
+ operation. When the SendObject operation has been fully
+ handled and the data written to the SD card a separate
+ event will be triggered.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_IN_SUSPEND
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_ASYNC_PENDING
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+
+ See Also
+ * CyAsMTPCancelSendObject
+ * CyAsMTPInitGetObject
+ * CyAsMTPEvent
+ * CyAsMTPSendBlockTable
+*/
+cy_as_return_status_t
+cy_as_mtp_init_send_object(
+ cy_as_device_handle handle,
+ cy_as_mtp_block_table *blk_table,
+ uint32_t num_bytes,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function cancels an ongoing MTP operation.
+
+ Description
+ Causes West Bridge to cancel an ongoing SendObject
+ operation. Note this is only a cancel to West Bridge,
+ the MTP operation still needs to be canceled by
+ sending a response.
+
+ West Bridge will automatically set a Stall on the endpoint
+ when the cancel is received.
+
+ This function is only valid after CyAsMTPInitSendObject
+ has been called, but before the CyAsMTPSendObjectComplete
+ event has been sent.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+ * CY_AS_ERROR_NO_OPERATION_PENDING
+
+ See Also
+ * CyAsMTPInitSendObject
+*/
+cy_as_return_status_t
+cy_as_mtp_cancel_send_object(
+ cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets up a turbo GetObject operation.
+
+ Description
+ Called by the P in response to a GetObject
+ operation. This provides West Bridge with the block
+ addresses for the Object data that needs to be
+ transferred.
+
+ It is the responsibility of the Processor to send the MTP
+ operation before calling CyAsMTPInitGetObject. West Bridge
+ will then send the data phase of the transaction,
+ automatically creating the required container for Data.
+ Once all of the Data has been transferred a callback will
+ be issued to inform the Processor that the Data phase has
+ completed allowing it to send the required MTP response.
+
+ If an entire Block Table is used then after the
+ last block is transferred the CyAsMTPBtCallback
+ will be called to allow an additional Block Table(s)
+ to be specified.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_IN_SUSPEND
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_ASYNC_PENDING
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+
+ See Also
+ * CyAsMTPInitSendObject
+ * CyAsMTPCancelGetObject
+ * CyAsMTPEvent
+ * CyAsMTPSendBlockTable
+*/
+cy_as_return_status_t
+cy_as_mtp_init_get_object(
+ cy_as_device_handle handle,
+ cy_as_mtp_block_table *table_p,
+ uint32_t num_bytes,
+ uint32_t transaction_id,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function cancels an ongoing turbo GetObject
+ operation.
+
+ Description
+ Causes West Bridge to cancel an ongoing GetObject
+ operation. Note this is only a cancel to West Bridge,
+ the MTP operation still needs to be canceled by
+ sending a response.
+
+ This function is only valid after CyAsMTPGetSendObject
+ has been called, but before the CyAsMTPGetObjectComplete
+ event has been sent.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+ * CY_AS_ERROR_NO_OPERATION_PENDING
+
+ See Also
+ * CyAsMTPInitGetObject
+*/
+cy_as_return_status_t
+cy_as_mtp_cancel_get_object(
+ cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function is used to transfer a BlockTable as part of
+ an ongoing MTP operation.
+
+ Description
+ This function is called in response to the
+ CyAsMTPBlockTableNeeded event. This allows the client to
+ pass in a BlockTable structure to West Bridge.
+
+ The memory associated with the table will be copied and
+ can be safely disposed of when the function returns if
+ called synchronously, or when the callback is made if
+ called asynchronously.
+
+ This function is used for both SendObject and GetObject
+ as both can generate the CyAsMTPBlockTableNeeded event.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_NOT_CONFIGURED
+ * CY_AS_ERROR_NO_FIRMWARE
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_IN_SUSPEND
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_ASYNC_PENDING
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running
+ * firmware with MTP support
+
+ See Also
+ * CyAsMTPInitSendObject
+ * CyAsMTPInitGetObject
+*/
+cy_as_return_status_t
+cy_as_mtp_send_block_table(
+ cy_as_device_handle handle,
+ cy_as_mtp_block_table *table,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function is used to mark the start of a storage
+ read/write burst from the P port processor.
+
+ Description
+ This function is used to mark the start of a storage
+ read/write burst from the processor. All USB host access
+ into the mass storage / MTP endpoints will be blocked
+ while the read/write burst is ongoing, and will be allowed
+ to resume only after CyAsMTPStorageOnlyStop is called.
+ The burst mode is used to reduce the firmware overhead
+ due to configuring the internal data paths repeatedly,
+ and can help improve performance when a sequence of
+ read/writes is performed in a burst.
+
+ This function will not generate a special mailbox request,
+ it will only set a flag on the next Storage Read/Write
+ operation. Until such a call is made West Bridge will
+ continue to accept incoming packets from the Host.
+
+ * Valid in Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device
+ * handle was passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not
+ * been configured.
+ * CY_AS_ERROR_NO_FIRMWARE - Firmware is not active on West
+ * Bridge device.
+ * CY_AS_ERROR_NOT_RUNNING - Storage stack is not running.
+ * CY_AS_ERROR_SUCCESS - Burst mode has been started.
+
+ See Also
+ * CyAsStorageReadWriteBurstStop
+ */
+cy_as_return_status_t
+cy_as_mtp_storage_only_start(
+ /* Handle to the West Bridge device. */
+ cy_as_device_handle handle
+ );
+
+/* Summary
+ This function is used to mark the end of a storage read/write
+ burst from the P port processor.
+
+ Description
+ This function is used to mark the end of a storage read/write
+ burst from the processor. At this point, USB access to the
+ mass storage / MTP endpoints on the West Bridge device will be
+ re-enabled.
+
+ * Valid in Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device handle
+ * was passed in.
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been
+ * configured.
+ * CY_AS_ERROR_NO_FIRMWARE - Firmware is not active on West Bridge
+ * device.
+ * CY_AS_ERROR_NOT_RUNNING - Storage stack is not running.
+ * CY_AS_ERROR_INVALID_IN_CALLBACK - This API cannot be called
+ * from a callback.
+ * CY_AS_ERROR_OUT_OF_MEMORY - Failed to allocate memory to
+ * process the request.
+ * CY_AS_ERROR_TIMEOUT - Failed to send request to firmware.
+ * CY_AS_ERROR_SUCCESS - Burst mode has been stopped.
+
+ See Also
+ * CyAsStorageReadWriteBurstStart
+ */
+cy_as_return_status_t
+cy_as_mtp_storage_only_stop(
+ /* Handle to the West Bridge device. */
+ cy_as_device_handle handle,
+ cy_as_function_callback cb,
+ uint32_t client
+ );
+
+#include "cyas_cplus_end.h"
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h
new file mode 100644
index 000000000000..317805fc4ff4
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h
@@ -0,0 +1,3838 @@
+/* Cypress West Bridge API header file (cyasprotocol.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASPROTOCOL_H_
+#define _INCLUDED_CYASPROTOCOL_H_
+
+/*
+ * Constants defining the per context buffer sizes
+ */
+#ifndef __doxygen__
+#define CY_CTX_GEN_MAX_DATA_SIZE (8)
+#define CY_CTX_RES_MAX_DATA_SIZE (8)
+#define CY_CTX_STR_MAX_DATA_SIZE (64)
+#define CY_CTX_USB_MAX_DATA_SIZE (130 + 23)
+#define CY_CTX_TUR_MAX_DATA_SIZE (12)
+#endif
+
+/* Summary
+ This response indicates a command has been processed
+ and returned a status.
+
+ Direction
+ West Bridge -> P Port Processor
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = all
+ * Response Code = 0
+
+ D0
+ * 0 = success (CY_AS_ERROR_SUCCESS)
+ * non-zero = error code
+
+ Description
+ This response indicates that a request was processed
+ and no data was generated as a result of the request
+ beyond a single 16 bit status value. This response
+ contains the 16 bit data value.
+ */
+#define CY_RESP_SUCCESS_FAILURE (0)
+
+/* Summary
+ This response indicates an invalid request was sent
+
+ Direction
+ West Bridge -> P Port Processor
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = all
+ * Response Code = 1
+
+ D0
+ * Mailbox contents for invalid request
+
+ Description
+ This response is returned when a request is sent
+ that contains an invalid
+ context or request code.
+*/
+#define CY_RESP_INVALID_REQUEST (1)
+
+/* Summary
+ This response indicates a request of invalid length was sent
+
+ Direction
+ West Bridge -> P Port Processor
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = all
+ * Response Code = 2
+
+ D0
+ * Mailbox contenxt for invalid request
+ * Length for invalid request
+
+ Description
+ The software API and firmware sends requests across the
+ P Port to West Bridge interface on different contexts.
+ Each contexts has a maximum size of the request packet
+ that can be received. The size of a request can be
+ determined during the first cycle of a request transfer.
+ If the request is larger than can be handled by the
+ receiving context this response is returned. Note that
+ the complete request is received before this response is
+ sent, but that the request is dropped after this response
+ is sent.
+*/
+#define CY_RESP_INVALID_LENGTH (2)
+
+
+/* Summary
+ This response indicates a request was made to an
+ invalid storage address.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = all
+ * Response Code = 0
+
+ D0
+ Bits 15 - 12 : Media Type
+ * 0 = NAND
+ * 1 = SD Flash
+ * 2 = MMC Flash
+ * 3 = CE-ATA
+
+ Bits 11 - 8 : Zero based device index
+
+ Bits 7 - 0 : Zero based unit index
+
+ D1
+ Upper 16 bits of block address
+
+ D2
+ Lower 16 bits of block address
+
+ D3
+ Portion of address that is invalid
+ * 0 = Media Type
+ * 1 = Device Index
+ * 2 = Unit Index
+ * 3 = Block Address
+
+ Description
+ This response indicates a request to an invalid storage media
+ address
+ */
+#define CY_RESP_NO_SUCH_ADDRESS (3)
+
+
+/******************************************************/
+
+/*@@General requests
+ Summary
+ The general requests include:
+ * CY_RQT_GET_FIRMWARE_VERSION
+ * CY_RQT_SET_TRACE_LEVEL
+ * CY_RQT_INITIALIZATION_COMPLETE
+ * CY_RQT_READ_MCU_REGISTER
+ * CY_RQT_WRITE_MCU_REGISTER
+ * CY_RQT_STORAGE_MEDIA_CHANGED
+ * CY_RQT_CONTROL_ANTIOCH_HEARTBEAT
+ * CY_RQT_PREPARE_FOR_STANDBY
+ * CY_RQT_ENTER_SUSPEND_MODE
+ * CY_RQT_OUT_OF_SUSPEND
+ * CY_RQT_GET_GPIO_STATE
+ * CY_RQT_SET_GPIO_STATE
+ * CY_RQT_SET_SD_CLOCK_FREQ
+ * CY_RQT_WB_DEVICE_MISMATCH
+ * CY_RQT_BOOTLOAD_NO_FIRMWARE
+ * CY_RQT_RESERVE_LNA_BOOT_AREA
+ * CY_RQT_ABORT_P2S_XFER
+ */
+
+#ifndef __doxygen__
+#define CY_RQT_GENERAL_RQT_CONTEXT (0)
+#endif
+
+/* Summary
+ This command returns the firmware version number,
+ media types supported and debug/release mode information.
+
+ Direction
+ P Port Processor-> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request Code = 0
+
+ Description
+ The response contains the 16-bit major version, the
+ 16-bit minor version, the 16 bit build number, media
+ types supported and release/debug mode information.
+
+ Responses
+ * CY_RESP_FIRMWARE_VERSION
+ */
+#define CY_RQT_GET_FIRMWARE_VERSION (0)
+
+
+/* Summary
+ This command changes the trace level and trace information
+ destination within the West Bridge firmware.
+
+ Direction
+ P Port Processor-> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request Code = 1
+
+ D0
+ Trace Level
+ * 0 = no trace information
+ * 1 = state information
+ * 2 = function call
+ * 3 = function call with args/return value
+
+ D1
+ Bits 12 - 15 : MediaType
+ * 0 = NAND
+ * 1 = SDIO Flash
+ * 2 = MMC Flash
+ * 3 = CE-ATA
+
+ Bits 8 - 11 : Zero based device index
+
+ Bits 0 - 7 : Zero based unit index
+
+ Description
+ The West Bridge firmware contains debugging facilities that can
+ be used to trace the execution of the firmware. This request
+ sets the level of tracing information that is stored and the
+ location where it is stored.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_SET_TRACE_LEVEL (1)
+
+/* Summary
+ This command indicates that the firmware is up and ready
+ for communications with the P port processor.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 0
+ * Request Code = 3
+
+ D0
+ Major Version
+
+ D1
+ Minor Version
+
+ D2
+ Build Number
+
+ D3
+ Bits 15-8: Media types supported on Bus 1.
+ Bits 7-0: Media types supported on Bus 0.
+ Bits 8, 0: NAND support.
+ * 0: NAND is not supported.
+ * 1: NAND is supported.
+ Bits 9, 1: SD memory card support.
+ * 0: SD memory card is not supported.
+ * 1: SD memory card is supported.
+ Bits 10, 2: MMC card support.
+ * 0: MMC card is not supported.
+ * 1: MMC card is supported.
+ Bits 11, 3: CEATA drive support
+ * 0: CEATA drive is not supported.
+ * 1: CEATA drive is supported.
+ Bits 12, 4: SD IO card support.
+ * 0: SD IO card is not supported.
+ * 1: SD IO card is supported.
+
+ D4
+ Bits 15 - 8 : MTP information
+ * 0 : MTP not supported in firmware
+ * 1 : MTP supported in firmware
+ Bits 7 - 0 : Debug/Release mode information.
+ * 0 : Release mode
+ * 1 : Debug mode
+
+ Description
+ When the West Bridge firmware is loaded it being by performing
+ initialization. Initialization must be complete before West
+ Bridge is ready to accept requests from the P port processor.
+ This request is sent from West Bridge to the P port processor
+ to indicate that initialization is complete.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_INITIALIZATION_COMPLETE (3)
+
+/* Summary
+ This command requests the firmware to read and return the contents
+ of a MCU accessible
+ register.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 4
+
+ D0
+ Address of register to read
+
+ Description
+ This debug command allows the processor to read the contents of
+ a MCU accessible register.
+
+ Responses
+ * CY_RESP_MCU_REGISTER_DATA
+ */
+#define CY_RQT_READ_MCU_REGISTER (4)
+
+/* Summary
+ This command requests the firmware to write to an MCU
+ accessible register.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 5
+
+ D0
+ Address of register to be written
+
+ D1
+ Bits 15 - 8 : Mask to be applied to existing data.
+ Bits 7 - 0 : Data to be ORed with masked data.
+
+ Description
+ This debug command allows the processor to write to an MCU
+ accessible register.
+ Note: This has to be used with caution, and is supported by
+ the firmware only in special debug builds.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_WRITE_MCU_REGISTER (5)
+
+/* Summary
+ This command tells the West Bridge firmware that a change in
+ storage media has been detected.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 6
+
+ Description
+ If the insertion or removal of SD or MMC cards is detected by
+ hardware external to West Bridge, this command is used to tell
+ the West Bridge firmware to re-initialize the storage controlled
+ by the device.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+*/
+#define CY_RQT_STORAGE_MEDIA_CHANGED (6)
+
+/* Summary
+ This command enables/disables the periodic heartbeat message
+ from the West Bridge firmware to the processor.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 7
+
+ Description
+ This command enables/disables the periodic heartbeat message
+ from the West Bridge firmware to the processor. The heartbeat
+ message is left enabled by default, and can lead to a loss
+ in performance on the P port interface.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_CONTROL_ANTIOCH_HEARTBEAT (7)
+
+/* Summary
+ This command requests the West Bridge firmware to prepare for
+ the device going into standby
+ mode.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 8
+
+ Description
+ This command is sent by the processor to the West Bridge as
+ preparation for going into standby mode. The request allows the
+ firmware to complete any pending/cached storage operations before
+ going into the low power state.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_PREPARE_FOR_STANDBY (8)
+
+/* Summary
+ Requests the firmware to go into suspend mode.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 9
+
+ D0
+ Bits 7-0: Wakeup control information.
+
+ Description
+ This command is sent by the processor to the West Bridge to
+ request the device to be placed in suspend mode. The firmware
+ will complete any pending/cached storage operations before
+ going into the low power state.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_ENTER_SUSPEND_MODE (9)
+
+/* Summary
+ Indicates that the device has left suspend mode.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 10
+
+ Description
+ This message is sent by the West Bridge to the Processor
+ to indicate that the device has woken up from suspend mode,
+ and is ready to accept new requests.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_OUT_OF_SUSPEND (10)
+
+/* Summary
+ Request to get the current state of an West Bridge GPIO pin.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 11
+
+ D0
+ Bits 15 - 8 : GPIO pin identifier
+
+ Responses
+ * CY_RESP_GPIO_STATE
+
+ Description
+ Request from the processor to get the current state of
+ an West Bridge GPIO pin.
+ */
+#define CY_RQT_GET_GPIO_STATE (11)
+
+/* Summary
+ Request to update the output value on an West Bridge
+ GPIO pin.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 12
+
+ D0
+ Bits 15 - 8 : GPIO pin identifier
+ Bit 0 : Desired output state
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+
+ Description
+ Request from the processor to update the output value on
+ an West Bridge GPIO pin.
+ */
+#define CY_RQT_SET_GPIO_STATE (12)
+
+/* Summary
+ Set the clock frequency on the SD interface of the West
+ Bridge device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 13
+
+ D0
+ Bit 8: Type of SD/MMC media
+ 0 = low speed media
+ 1 = high speed media
+ Bit 0: Clock frequency selection
+ 0 = Default frequency
+ 1 = Alternate frequency (24 MHz in both cases)
+
+ Description
+ This request is sent by the processor to set the operating clock
+ frequency used on the SD interface of the device.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_SET_SD_CLOCK_FREQ (13)
+
+/* Summary
+ Indicates the firmware downloaded to West Bridge cannot
+ run on the active device.
+
+ Direction
+ West Bridge -> P Port processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 14
+
+ Description
+ Some versions of West Bridge firmware can only run on specific
+ types/versions of the West Bridge device. This error is
+ returned when a firmware image is downloaded onto a device that
+ does not support it.
+
+ Responses
+ * None
+ */
+#define CY_RQT_WB_DEVICE_MISMATCH (14)
+
+/* Summary
+ This command is indicates that no firmware was found in the
+ storage media.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 0
+ * Request code = 15
+
+ Description
+ The command is received only in case of silicon with bootloader
+ ROM. The device sends the request if there is no firmware image
+ found in the storage media or the image is corrupted. The
+ device is waiting for P port to download a valid firmware image.
+
+ Responses
+ * None
+ */
+#define CY_RQT_BOOTLOAD_NO_FIRMWARE (15)
+
+/* Summary
+ This command reserves first numzones zones of nand device for
+ storing processor boot image.
+
+ Direction
+ P Port Processor-> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request Code = 16
+
+ D0
+ Bits 7-0: numzones
+
+ Description
+ The first numzones zones in nand device will be used for storing
+ proc boot image. LNA firmware in Astoria will work on this nand
+ area and boots the processor which will then use the remaining
+ nand for usual purposes.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_RESERVE_LNA_BOOT_AREA (16)
+
+/* Summary
+ This command cancels the processing of a P2S operation in
+ firmware.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request Code = 17
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+*/
+#define CY_RQT_ABORT_P2S_XFER (17)
+
+/*
+ * Used for debugging, ignore for normal operations
+ */
+#ifndef __doxygen__
+#define CY_RQT_DEBUG_MESSAGE (127)
+#endif
+
+/******************************************************/
+
+/*@@General responses
+ Summary
+ The general responses include:
+ * CY_RESP_FIRMWARE_VERSION
+ * CY_RESP_MCU_REGISTER_DATA
+ * CY_RESP_GPIO_STATE
+ */
+
+
+/* Summary
+ This response indicates success and contains the firmware
+ version number, media types supported by the firmware and
+ release/debug mode information.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 0
+ * Response Code = 16
+
+ D0
+ Major Version
+
+ D1
+ Minor Version
+
+ D2
+ Build Number
+
+ D3
+ Bits 15-8: Media types supported on Bus 1.
+ Bits 7-0: Media types supported on Bus 0.
+ Bits 8, 0: NAND support.
+ * 0: NAND is not supported.
+ * 1: NAND is supported.
+ Bits 9, 1: SD memory card support.
+ * 0: SD memory card is not supported.
+ * 1: SD memory card is supported.
+ Bits 10, 2: MMC card support.
+ * 0: MMC card is not supported.
+ * 1: MMC card is supported.
+ Bits 11, 3: CEATA drive support
+ * 0: CEATA drive is not supported.
+ * 1: CEATA drive is supported.
+ Bits 12, 4: SD IO card support.
+ * 0: SD IO card is not supported.
+ * 1: SD IO card is supported.
+
+ D4
+ Bits 15 - 8 : MTP information
+ * 0 : MTP not supported in firmware
+ * 1 : MTP supported in firmware
+ Bits 7 - 0 : Debug/Release mode information.
+ * 0 : Release mode
+ * 1 : Debug mode
+
+ Description
+ This reponse is sent to return the firmware version
+ number to the requestor.
+ */
+#define CY_RESP_FIRMWARE_VERSION (16)
+
+/* Summary
+ This response returns the contents of a MCU accessible
+ register to the processor.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Response code = 17
+
+ D0
+ Bits 7 - 0 : MCU register contents
+
+ Description
+ This response is sent by the firmware in response to the
+ CY_RQT_READ_MCU_REGISTER
+ command.
+ */
+#define CY_RESP_MCU_REGISTER_DATA (17)
+
+/* Summary
+ Reports the current state of an West Bridge GPIO pin.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request code = 18
+
+ D0
+ Bit 0: Current state of the GP input pin
+
+ Description
+ This response is sent by the West Bridge to report the
+ current state observed on a general purpose input pin.
+ */
+#define CY_RESP_GPIO_STATE (18)
+
+
+/* Summary
+ This command notifies West Bridge the polarity of the
+ SD power pin
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 0
+ * Request Code = 19
+ D0: CyAnMiscActivehigh / CyAnMiscActivelow
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+
+ */
+
+#define CY_RQT_SDPOLARITY (19)
+
+/******************************/
+
+/*@@Resource requests
+ Summary
+
+ The resource requests include:
+ * CY_RQT_ACQUIRE_RESOURCE
+ * CY_RQT_RELEASE_RESOURCE
+ */
+
+
+
+
+
+#ifndef __doxygen__
+#define CY_RQT_RESOURCE_RQT_CONTEXT (1)
+#endif
+
+
+/* Summary
+ This command is a request from the P port processor
+ for ownership of a resource.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 1
+ * Request Code = 0
+
+ D0
+ Resource
+ * 0 = USB
+ * 1 = SDIO/MMC
+ * 2 = NAND
+
+ D1
+ Force Flag
+ * 0 = Normal
+ * 1 = Force
+
+ Description
+ The resource may be the USB pins, the SDIO/MMC bus,
+ or the NAND bus.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_RELEASED
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_RESOURCE
+ */
+#define CY_RQT_ACQUIRE_RESOURCE (0)
+
+
+/* Summary
+ This command is a request from the P port processor
+ to release ownership of a resource.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 1
+ * Request Code = 1
+
+ D0
+ Resource
+ * 0 = USB
+ * 1 = SDIO/MMC
+ * 2 = NAND
+
+ Description
+ The resource may be the USB pins, the SDIO/MMC bus, or
+ the NAND bus.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_OWNER
+ */
+#define CY_RQT_RELEASE_RESOURCE (1)
+
+
+/****************************/
+
+/*@@Storage requests
+ Summary
+ The storage commands include:
+ * CY_RQT_START_STORAGE
+ * CY_RQT_STOP_STORAGE
+ * CY_RQT_CLAIM_STORAGE
+ * CY_RQT_RELEASE_STORAGE
+ * CY_RQT_QUERY_MEDIA
+ * CY_RQT_QUERY_DEVICE
+ * CY_RQT_QUERY_UNIT
+ * CY_RQT_READ_BLOCK
+ * CY_RQT_WRITE_BLOCK
+ * CY_RQT_MEDIA_CHANGED
+ * CY_RQT_ANTIOCH_CLAIM
+ * CY_RQT_ANTIOCH_RELEASE
+ * CY_RQT_SD_INTERFACE_CONTROL
+ * CY_RQT_SD_REGISTER_READ
+ * CY_RQT_CHECK_CARD_LOCK
+ * CY_RQT_QUERY_BUS
+ * CY_RQT_PARTITION_STORAGE
+ * CY_RQT_PARTITION_ERASE
+ * CY_RQT_GET_TRANSFER_AMOUNT
+ * CY_RQT_ERASE
+ * CY_RQT_SDIO_READ_DIRECT
+ * CY_RQT_SDIO_WRITE_DIRECT
+ * CY_RQT_SDIO_READ_EXTENDED
+ * CY_RQT_SDIO_WRITE_EXTENDED
+ * CY_RQT_SDIO_INIT_FUNCTION
+ * CY_RQT_SDIO_QUERY_CARD
+ * CY_RQT_SDIO_GET_TUPLE
+ * CY_RQT_SDIO_ABORT_IO
+ * CY_RQT_SDIO_INTR
+ * CY_RQT_SDIO_SUSPEND
+ * CY_RQT_SDIO_RESUME
+ * CY_RQT_SDIO_RESET_DEV
+ * CY_RQT_P2S_DMA_START
+ */
+#ifndef __doxygen__
+#define CY_RQT_STORAGE_RQT_CONTEXT (2)
+#endif
+
+/* Summary
+ This command requests initialization of the storage stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 0
+
+ Description
+ This command is required before any other storage related command
+ can be send to the West Bridge firmware.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_ALREADY_RUNNING
+ */
+#define CY_RQT_START_STORAGE (0)
+
+
+/* Summary
+ This command requests shutdown of the storage stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 1
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_RUNNING
+ */
+#define CY_RQT_STOP_STORAGE (1)
+
+
+/* Summary
+ This command requests ownership of the given media
+ type by the P port processor.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 2
+
+ D0
+ Bits 12 - 15 : Bus Index
+ Bits 8 - 11 : Zero based device index
+
+ Responses
+ * CY_RESP_MEDIA_CLAIMED_RELEASED
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_CLAIM_STORAGE (2)
+
+
+/* Summary
+ This command releases ownership of a given media type
+ by the P port processor.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 3
+
+ D0
+ Bits 12 - 15 : Bus Index
+ Bits 8 - 11 : Zero based device index
+
+ Responses
+ * CY_RESP_MEDIA_CLAIMED_RELEASED
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_RELEASE_STORAGE (3)
+
+
+/* Summary
+ This command returns the total number of logical devices
+ of the given type of media.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 4
+
+ D0
+ Bits 12 - 15 : MediaType
+ * 0 = NAND
+ * 1 = SDIO Flash
+ * 2 = MMC Flash
+ * 3 = CE-ATA
+
+ Bits 8 - 11 : Not Used
+
+ Bits 0 - 7 : Not Used
+
+ Responses
+ * CY_RESP_MEDIA_DESCRIPTOR
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_QUERY_MEDIA (4)
+
+
+/* Summary
+ This command queries a given device to determine
+ information about the number of logical units on
+ the given device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 5
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Not Used
+
+ Responses
+ * CY_RESP_DEVICE_DESCRIPTOR
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_PARTITION_TABLE
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_QUERY_DEVICE (5)
+
+
+/* Summary
+ This command queries a given device to determine
+ information about the size and location of a logical unit
+ located on a physical device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 6
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ Responses
+ * CY_RESP_UNIT_DESCRIPTOR
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_PARTITION_TABLE
+ * CY_RESP_NO_SUCH_ADDRESS
+ */
+#define CY_RQT_QUERY_UNIT (6)
+
+
+/* Summary
+ This command initiates the read of a specific block
+ from the given media,
+ device and unit.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 2
+ * Request Code = 7
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ D1
+ Upper 16 bits of block address
+
+ D2
+ Lower 16 bits of block address
+
+ D3
+ BIT 8 - 15 : Upper 8 bits of Number of blocks
+
+ BIT 0 - 7 : Reserved
+
+ * D4 *
+ BITS 8 - 15 : Lower 8 bits of Number of blocks
+ BITS 1 - 7 : Not Used
+ BIT 0 : Indicates whether this command is a
+ part of a P2S only burst.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_ANTIOCH_DEFERRED_ERROR
+ */
+#define CY_RQT_READ_BLOCK (7)
+
+
+/* Summary
+ This command initiates the write of a specific block
+ from the given media, device and unit.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 2
+ * Request Code = 8
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ D1
+ Upper 16 bits of block address
+
+ D2
+ Lower 16 bits of block address
+
+ D3
+ BIT 8 - 15 : Upper 8 bits of Number of blocks
+
+ BIT 0 - 7 : Reserved
+
+ * D4 *
+ BITS 8 - 15 : Lower 8 bits of Number of blocks
+ BITS 1 - 7 : Not Used
+ BIT 0 : Indicates whether this command is a
+ part of a P2S only burst.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_ANTIOCH_DEFERRED_ERROR
+ */
+#define CY_RQT_WRITE_BLOCK (8)
+
+/* Summary
+ This request is sent when the West Bridge device detects
+ a change in the status of the media.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request Code = 9
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 0 - 7 : Media type
+
+ D1
+ Bit 0 : Action
+ * 0 = Inserted
+ * 1 = Removed
+
+ Description
+ When the media manager detects the insertion or removal
+ of a media from the West Bridge port, this request is sent
+ from the West Bridge device to the P Port processor to
+ inform the processor of the change in status of the media.
+ This request is sent for both an insert operation and a
+ removal operation.
+
+ Responses
+ * CY_RESPO_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_MEDIA_CHANGED (9)
+
+/* Summary
+ This request is sent when the USB module wishes to claim
+ storage media.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request Code = 10
+
+ D0
+ Bit 0:
+ * 0 = do not release NAND
+ * 1 = release NAND
+
+ Bit 1:
+ * 0 = do not release SD Flash
+ * 1 = release SD Flash
+
+ Bit 2:
+ * 0 = do not release MMC flash
+ * 1 = release MMC flash
+
+ Bit 3:
+ * 0 = do not release CE-ATA storage
+ * 1 = release CE-ATA storage
+
+ Bit 8:
+ * 0 = do not release storage on bus 0
+ * 1 = release storage on bus 0
+
+ Bit 9:
+ * 0 = do not release storage on bus 1
+ * 1 = release storage on bus 1
+
+ Description
+ When the USB cable is attached to the West Bridge device,
+ West Bridge will enumerate the storage devices per the USB
+ initialization of West Bridge. In order for West Bridge to
+ respond to requests received via USB for the mass storage
+ devices, the USB module must claim the storeage. This
+ request is a request to the P port processor to release the
+ storage medium. The medium will not be visible on the USB
+ host, until it has been released by the processor.
+*/
+#define CY_RQT_ANTIOCH_CLAIM (10)
+
+/* Summary
+ This request is sent when the P port has asked West Bridge to
+ release storage media, and the West Bridge device has
+ completed this.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request Code = 11
+
+ D0
+ Bit 0:
+ * 0 = No change in ownership of NAND storage
+ * 1 = NAND ownership has been given to processor
+
+ Bit 1:
+ * 0 = No change in ownership of SD storage
+ * 1 = SD ownership has been given to processor
+
+ Bit 2:
+ * 0 = No change in ownership of MMC storage
+ * 1 = MMC ownership has been given to processor
+
+ Bit 3:
+ * 0 = No change in ownership of CE-ATA storage
+ * 1 = CE-ATA ownership has been given to processor
+
+ Bit 4:
+ * 0 = No change in ownership of SD IO device
+ * 1 = SD IO device ownership has been given to processor
+
+ Bit 8:
+ * 0 = No change in ownership of storage on bus 0
+ * 1 = Bus 0 ownership has been given to processor
+
+ Bit 9:
+ * 0 = No change in ownership of storage on bus 1
+ * 1 = Bus 1 ownership has been given to processor
+
+ Description
+ When the P port asks for control of a particular media, West
+ Bridge may be able to release the media immediately. West
+ Bridge may also need to complete the flush of buffers before
+ releasing the media. In the later case, West Bridge will
+ indicated a release is not possible immediately and West Bridge
+ will send this request to the P port when the release has been
+ completed.
+*/
+#define CY_RQT_ANTIOCH_RELEASE (11)
+
+/* Summary
+ This request is sent by the Processor to enable/disable the
+ handling of SD card detection and SD card write protection
+ by the firmware.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 12
+
+ D0
+ Bit 8: Enable/disable handling of card detection.
+ Bit 1: SDAT_3 = 0, GIPO_0 = 1
+ Bit 0: Enable/disable handling of write protection.
+
+ Description
+ This request is sent by the Processor to enable/disable
+ the handling of SD card detection and SD card write
+ protection by the firmware.
+ */
+#define CY_RQT_SD_INTERFACE_CONTROL (12)
+
+/* Summary
+ Request from the processor to read a register on the SD
+ card, and return the contents.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 13
+
+ D0
+ Bits 12 - 15 : MediaType
+ * 0 = Reserved
+ * 1 = SDIO Flash
+ * 2 = MMC Flash
+ * 3 = Reserved
+
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Type of register to read
+
+ Description
+ This request is sent by the processor to instruct the
+ West Bridge to read a register on the SD/MMC card, and
+ send the contents back through the CY_RESP_SD_REGISTER_DATA
+ response.
+ */
+#define CY_RQT_SD_REGISTER_READ (13)
+
+/* Summary
+ Check if the SD/MMC card connected to West Bridge is
+ password locked.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 14
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+
+ Description
+ This request is sent by the processor to check if the
+ SD/MMC connected to the West Bridge is locked with a
+ password.
+ */
+#define CY_RQT_CHECK_CARD_LOCK (14)
+
+/* Summary
+ This command returns the total number of logical devices on the
+ given bus
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 15
+
+ D0
+ Bits 12 - 15 : Bus Number
+
+ Bits 0 - 11: Not Used
+
+ Responses
+ * CY_RESP_BUS_DESCRIPTOR
+ * CY_RESP_NO_SUCH_BUS
+ */
+#define CY_RQT_QUERY_BUS (15)
+
+/* Summary
+ Divide a storage device into two partitions.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request code = 16
+
+ D0
+ Bits 12 - 15 : Bus number
+ Bits 8 - 11 : Device number
+ Bits 0 - 7 : Not used
+
+ D1
+ Size of partition 0 (MS word)
+
+ D2
+ Size of partition 0 (LS word)
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_PARTITION_STORAGE (16)
+
+/* Summary
+ Remove the partition table and unify all partitions on
+ a storage device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request code = 17
+
+ D0
+ Bits 12 - 15 : Bus number
+ Bits 8 - 11 : Device number
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_PARTITION_ERASE (17)
+
+/* Summary
+ Requests the current transfer amount.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request code = 18
+
+ D0
+ Bits 12 - 15 : Bus number
+ Bits 8 - 11 : Device number
+
+ Responses
+ * CY_RESP_TRANSFER_COUNT
+ */
+#define CY_RQT_GET_TRANSFER_AMOUNT (18)
+
+/* Summary
+ Erases.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 2
+ * Request code = 19
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ D1
+ Upper 16 bits of erase unit
+
+ D2
+ Lower 16 bits of erase unit
+
+ D3
+ BIT 8 - 15 : Upper 8 bits of Number of erase units
+ BIT 0 - 7 : Reserved
+
+ * D4 *
+ BIT 8 - 15 : Lower 8 bits of Number of erase units
+ BIT 0 - 7 : Not Used
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ */
+#define CY_RQT_ERASE (19)
+
+/* Summary
+ This command reads 1 byte from an SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 23
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ D1
+ Bits 8 - 15 : 0
+ Bit 7 : 0 to indicate a read
+ Bits 4 - 6 : Function number
+ Bit 3 : 0
+ Bit 2 : 1 if SDIO interrupt needs to be re-enabled.
+ Bits 0 - 1 : Two Most significant bits of Read address
+
+ D2
+ Bits 1 - 15 : 15 Least significant bits of Read address
+ Bit 0 : 0
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ * CY_RESP_SDIO_DIRECT
+*/
+#define CY_RQT_SDIO_READ_DIRECT (23)
+
+/* Summary
+ This command writes 1 byte to an SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 24
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ D1
+ Bits 8 - 15 : Data to write
+ Bit 7 : 1 to indicate a write
+ Bits 4 - 6 : Function number
+ Bit 3 : 1 if Read after write is enabled
+ Bit 2 : 1 if SDIO interrupt needs to be re-enabled.
+ Bits 0 - 1 : Two Most significant bits of write address
+
+ D2
+ Bits 1 - 15 : 15 Least significant bits of write address
+ Bit 0 : 0
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SDIO_DIRECT
+*/
+#define CY_RQT_SDIO_WRITE_DIRECT (24)
+
+/* Summary
+ This command reads performs a multi block/byte read from
+ an SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 25
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ D1
+ Bit 15 : 0 to indicate a read
+ Bit 12 - 14 : Function Number
+ Bit 11 : Block Mode
+ Bit 10 : OpCode
+ Bits 0 - 9 : 10 Most significant bits of Read address
+
+ D2
+ Bits 9 - 15 : 7 Least significant bits of address
+ Bits 0 - 8 : Block/Byte Count
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SDIO_EXT
+*/
+#define CY_RQT_SDIO_READ_EXTENDED (25)
+
+/* Summary
+ This command reads performs a multi block/byte write
+ to an SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 26
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ D1
+ Bit 15 : 1 to indicate a write
+ Bit 12 - 14 : Function Number
+ Bit 11 : Block Mode
+ Bit 10 : OpCode
+ Bits 0 - 9 : 10 Most significant bits of Read address
+
+ D2
+ Bits 9 - 15 : 7 Least significant bits of address
+ Bits 0 - 8 : Block/Byte Count
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SDIO_EXT
+*/
+#define CY_RQT_SDIO_WRITE_EXTENDED (26)
+
+/* Summary
+ This command initialises an IO function on the SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 27
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SDIO_INIT_FUNCTION (27)
+
+/* Summary
+ This command gets properties of the SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 28
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_QUERY_CARD
+*/
+#define CY_RQT_SDIO_QUERY_CARD (28)
+
+/* Summary
+ This command reads a tuple from the CIS of an SDIO card.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 29
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ D1
+ Bits 8 - 15 : Tuple ID to read
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SDIO_GET_TUPLE
+*/
+#define CY_RQT_SDIO_GET_TUPLE (29)
+
+/* Summary
+ This command Aborts an IO operation.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 30
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SDIO_ABORT_IO (30)
+
+/* Summary
+ SDIO Interrupt request sent to the processor from the West Bridge device.
+
+ Direction
+ West Bridge ->P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 31
+
+ D0
+ Bits 0 - 7 : Bus Index
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SDIO_INTR (31)
+
+/* Summary
+ This command Suspends an IO operation.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 32
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SDIO_SUSPEND (32)
+
+/* Summary
+ This command resumes a suspended operation.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 33
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based function number
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SDIO_RESUME
+*/
+#define CY_RQT_SDIO_RESUME (33)
+
+/* Summary
+ This command resets an SDIO device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request Code = 34
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : 0
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SDIO_RESET_DEV (34)
+
+/* Summary
+ This command asks the API to start the DMA transfer
+ for a P2S operation.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Request code = 35
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_P2S_DMA_START (35)
+
+/******************************************************/
+
+/*@@Storage responses
+ Summary
+ The storage responses include:
+ * CY_RESP_MEDIA_CLAIMED_RELEASED
+ * CY_RESP_MEDIA_DESCRIPTOR
+ * CY_RESP_DEVICE_DESCRIPTOR
+ * CY_RESP_UNIT_DESCRIPTOR
+ * CY_RESP_ANTIOCH_DEFERRED_ERROR
+ * CY_RESP_SD_REGISTER_DATA
+ * CY_RESP_SD_LOCK_STATUS
+ * CY_RESP_BUS_DESCRIPTOR
+ * CY_RESP_TRANSFER_COUNT
+ * CY_RESP_SDIO_EXT
+ * CY_RESP_SDIO_INIT_FUNCTION
+ * CY_RESP_SDIO_QUERY_CARD
+ * CY_RESP_SDIO_GET_TUPLE
+ * CY_RESP_SDIO_DIRECT
+ * CY_RESP_SDIO_INVALID_FUNCTION
+ * CY_RESP_SDIO_RESUME
+ */
+
+/* Summary
+ Based on the request sent, the state of a given media was
+ changed as indicated by this response.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Response Code = 16
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+
+ D1
+ State of Media
+ * 0 = released
+ * 1 = claimed
+ */
+#define CY_RESP_MEDIA_CLAIMED_RELEASED (16)
+
+
+/* Summary
+ This response gives the number of physical devices
+ associated with a given media type.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Response Code = 17
+
+ D0
+ Media Type
+ Bits 12 - 15
+ * 0 = NAND
+ * 1 = SDIO Flash
+ * 2 = MMC Flash
+ * 3 = CE-ATA
+
+ D1
+ Number of devices
+ */
+#define CY_RESP_MEDIA_DESCRIPTOR (17)
+
+
+/* Summary
+ This response gives description of a physical device.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 2
+ * Response Code = 18
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Type of media present on bus
+
+ D1
+ Block Size in bytes
+
+ D2
+ Bit 15 : Is device removable
+ Bit 9 : Is device password locked
+ Bit 8 : Is device writeable
+ Bits 0 - 7 : Number Of Units
+
+ D3
+ ERASE_UNIT_SIZE high 16 bits
+
+ D4
+ ERASE_UNIT_SIZE low 16 bits
+
+ */
+#define CY_RESP_DEVICE_DESCRIPTOR (18)
+
+
+/* Summary
+ This response gives description of a unit on a
+ physical device.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 6
+
+ MailBox0
+ * Context = 2
+ * Response Code = 19
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ D1
+ Bits 0 - 7 : Media type
+ * 1 = NAND
+ * 2 = SD FLASH
+ * 4 = MMC FLASH
+ * 8 = CEATA
+ * 16 = SD IO
+
+ D2
+ Block Size in bytes
+
+ D3
+ Start Block Low 16 bits
+
+ D4
+ Start Block High 16 bits
+
+ D5
+ Unit Size Low 16 bits
+
+ D6
+ Unit Size High 16 bits
+ */
+#define CY_RESP_UNIT_DESCRIPTOR (19)
+
+
+/* Summary
+ This response is sent as error status for P2S
+ Storage operation.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 2
+ * Request Code = 20
+
+ D0
+ Bit 8 : Type of operation (Read / Write)
+ Bits 7 - 0 : Error code
+
+ D1
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Zero based unit index
+
+ *D2 - D3*
+ Address where the error occurred.
+
+ D4
+ Length of the operation in blocks.
+
+ Description
+ This error is returned by the West Bridge to the
+ processor if a storage operation fails due to a
+ medium error.
+*/
+#define CY_RESP_ANTIOCH_DEFERRED_ERROR (20)
+
+/* Summary
+ Contents of a register on the SD/MMC card connected to
+ West Bridge.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ Variable
+
+ Mailbox0
+ * Context = 2
+ * Request code = 21
+
+ D0
+ Length of data in bytes
+
+ D1 - Dn
+ The register contents
+
+ Description
+ This is the response to a CY_RQT_SD_REGISTER_READ
+ request.
+*/
+#define CY_RESP_SD_REGISTER_DATA (21)
+
+/* Summary
+ Status of whether the SD card is password locked.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 22
+
+ D0
+ Bit 0 : The card's lock status
+
+ Description
+ Status of whether the SD card is password locked.
+*/
+#define CY_RESP_SD_LOCK_STATUS (22)
+
+
+/* Summary
+ This response gives the types of physical devices
+ attached to a given bus.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 2
+ * Response Code = 23
+
+ D0
+ Bus Number
+ Bits 12 - 15
+
+ D1
+ Media present on addressed bus
+ */
+#define CY_RESP_BUS_DESCRIPTOR (23)
+
+/* Summary
+ Amount of data read/written through the USB mass
+ storage/MTP device.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 2
+ * Request code = 24
+
+ D0
+ MS 16 bits of number of sectors written
+
+ D1
+ LS 16 bits of number of sectors written
+
+ D2
+ MS 16 bits of number of sectors read
+
+ D3
+ LS 16 bits of number of sectors read
+
+ Description
+ This is the response to the CY_RQT_GET_TRANSFER_AMOUNT
+ request, and represents the number of sectors of data
+ that has been written to or read from the storage device
+ through the USB Mass storage or MTP interface.
+ */
+#define CY_RESP_TRANSFER_COUNT (24)
+
+/* Summary
+ Status of SDIO Extended read/write operation.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 34
+
+ D0
+ Bit 8 : 1 if Read response, 0 if write response
+ Bits 0-7: Error Status
+
+ Description
+ Status of SDIO Extended read write operation.
+*/
+
+#define CY_RESP_SDIO_EXT (34)
+
+/* Summary
+ Status of SDIO operation to Initialize a function
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 2
+ * Request code = 35
+
+
+ D0
+ Bits 8-15 : Function Interface Code
+ Bits 0-7: Extended Function Interface Code
+
+ D1
+ Bits 0-15 : Function Block Size
+
+ D2
+ Bits 0-15 : Most significant Word of Function PSN
+
+ D3
+ Bits 0-15 : Least significant Word of Function PSN
+
+ D4
+ Bit 15 : CSA Enabled Status
+ Bit 14 : CSA Support Status
+ Bit 9 : CSA No Format Status
+ Bit 8 : CSA Write Protect Status
+ Bit 0 : Function Wake Up Support status
+
+ Description
+ Status of SDIO Function Initialization operation.
+*/
+#define CY_RESP_SDIO_INIT_FUNCTION (35)
+
+/* Summary
+ Status of SDIO operation to query the Card
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 2
+ * Request code = 36
+
+
+ D0
+ Bits 8-15 : Number of IO functions present
+ Bit 0: 1 if memory is present
+
+ D1
+ Bits 0-15 : Card Manufacturer ID
+
+ D2
+ Bits 0-15 : Card Manufacturer Additional Information
+
+ D3
+ Bits 0-15 : Function 0 Block Size
+
+ D4
+ Bits 8-15 :SDIO Card Capability register
+ Bits 0-7: SDIO Version
+
+
+ Description
+ Status of SDIO Card Query operation.
+ */
+#define CY_RESP_SDIO_QUERY_CARD (36)
+/* Summary
+ Status of SDIO CIS read operation
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 37
+
+ D0
+ Bit 8 : 1
+ Bits 0-7: Error Status
+
+ D1
+ Bits 0 - 7 : Size of data read.
+
+ Description
+ Status of SDIO Get Tuple Read operation.
+ */
+#define CY_RESP_SDIO_GET_TUPLE (37)
+
+/* Summary
+ Status of SDIO Direct read/write operation.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 38
+
+ D0
+ Bit 8 : Error Status
+ Bits 0-7: Data Read(If any)
+
+ Description
+ Status of SDIO Direct read write operation.
+
+*/
+#define CY_RESP_SDIO_DIRECT (38)
+
+/* Summary
+ Indicates an un-initialized function has been used for IO
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 39
+
+ Description
+ Indicates an IO request on an uninitialized function.
+*/
+#define CY_RESP_SDIO_INVALID_FUNCTION (39)
+
+/* Summary
+ Response to a Resume request
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 2
+ * Request code = 40
+
+ D0
+ Bits 8-15 : Error Status
+ Bit 0: 1 if data is available. 0 otherwise.
+
+ Description
+ Response to a Resume request. Indicates if data is
+ available after resum or not.
+*/
+#define CY_RESP_SDIO_RESUME (40)
+
+/******************************************************/
+
+/*@@USB requests
+ Summary
+ The USB requests include:
+ * CY_RQT_START_USB
+ * CY_RQT_STOP_USB
+ * CY_RQT_SET_CONNECT_STATE
+ * CY_RQT_GET_CONNECT_STATE
+ * CY_RQT_SET_USB_CONFIG
+ * CY_RQT_GET_USB_CONFIG
+ * CY_RQT_STALL_ENDPOINT
+ * CY_RQT_GET_STALL
+ * CY_RQT_SET_DESCRIPTOR
+ * CY_RQT_GET_DESCRIPTOR
+ * CY_RQT_SET_USB_CONFIG_REGISTERS
+ * CY_RQT_USB_EVENT
+ * CY_RQT_USB_EP_DATA
+ * CY_RQT_ENDPOINT_SET_NAK
+ * CY_RQT_GET_ENDPOINT_NAK
+ * CY_RQT_ACK_SETUP_PACKET
+ * CY_RQT_SCSI_INQUIRY_COMMAND
+ * CY_RQT_SCSI_START_STOP_COMMAND
+ * CY_RQT_SCSI_UNKNOWN_COMMAND
+ * CY_RQT_USB_REMOTE_WAKEUP
+ * CY_RQT_CLEAR_DESCRIPTORS
+ * CY_RQT_USB_STORAGE_MONITOR
+ * CY_RQT_USB_ACTIVITY_UPDATE
+ * CY_RQT_MS_PARTITION_SELECT
+ */
+#ifndef __doxygen__
+#define CY_RQT_USB_RQT_CONTEXT (3)
+#endif
+
+/* Summary
+ This command requests initialization of the USB stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 0
+
+ Description
+ This command is required before any other USB related command can be
+ sent to the West Bridge firmware.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_ALREADY_RUNNING
+ */
+#define CY_RQT_START_USB (0)
+
+
+/* Summary
+ This command requests shutdown of the USB stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 1
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_STOP_USB (1)
+
+
+/* Summary
+ This command requests that the USB pins be connected
+ or disconnected to/from the West Bridge device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 2
+
+ D0
+ Desired Connect State
+ * 0 = DISCONNECTED
+ * 1 = CONNECTED
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_SET_CONNECT_STATE (2)
+
+
+/* Summary
+ This command requests the connection state of the
+ West Bridge USB pins.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 3
+
+ Responses
+ * CY_RESP_CONNECT_STATE
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_GET_CONNECT_STATE (3)
+
+
+/* Summary
+ This request configures the USB subsystem.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 3
+ * Request Code = 4
+
+ D0
+ Bits 8 - 15: Media to enumerate (bit mask)
+ Bits 0 - 7: Enumerate Mass Storage (bit mask)
+ * 1 = Enumerate device on bus 0
+ * 2 = Enumerate device on bus 1
+
+ D1
+ Enumeration Methodology
+ * 1 = West Bridge enumeration
+ * 0 = P Port enumeration
+
+ D2
+ Mass storage interface number - Interface number to
+ be used for the mass storage interface
+
+ D3
+ Mass storage callbacks
+ * 1 = relay to P port
+ * 0 = completely handle in firmware
+
+ Description
+ This indicates how enumeration should be handled.
+ Enumeration can be handled by the West Bridge device
+ or by the P port processor.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_MASK
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_STORAGE_MEDIA
+ */
+#define CY_RQT_SET_USB_CONFIG (4)
+
+
+/* Summary
+ This request retrieves the current USB configuration from
+ the West Bridge device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 5
+
+ Responses
+ * CY_RESP_USB_CONFIG
+ */
+#define CY_RQT_GET_USB_CONFIG (5)
+
+
+/* Summary
+ This request stalls the given endpoint.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 6
+
+ D0
+ Endpoint Number
+
+ D1
+ * 1 = Stall Endpoint
+ * 0 = Clear Stall
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT
+ */
+#define CY_RQT_STALL_ENDPOINT (6)
+
+
+/* Summary
+ This request retrieves the stall status of the
+ requested endpoint.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 7
+
+ D0
+ Endpoint number
+
+ Responses
+ * CY_RESP_ENDPOINT_STALL
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT
+ */
+#define CY_RQT_GET_STALL (7)
+
+
+/* Summary
+ This command sets the contents of a descriptor.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 8
+
+ D0
+ Bit 15 - Bit 8
+ Descriptor Index
+
+ Bit 7 - Bit 0
+ Descriptor Type
+ * Device = 1
+ * Device Qualifier = 2
+ * Full Speed Configuration = 3
+ * High Speed Configuration = 4
+
+ * D1 - DN *
+ Actual data for the descriptor
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_TYPE
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_INDEX
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_LENGTH
+ */
+#define CY_RQT_SET_DESCRIPTOR (8)
+
+/* Summary
+ This command gets the contents of a descriptor.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 9
+
+ D0
+ Bit 15 - Bit 8
+ Descriptor Index
+
+ Bit 7 - Bit 0
+ Descriptor Type
+ * Device = 1
+ * Device Qualifier = 2
+ * Full Speed Configuration = 3
+ * High Speed Configuration = 4
+
+ Responses
+ * CY_RESP_USB_DESCRIPTOR
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_TYPE
+ * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_INDEX
+ */
+#define CY_RQT_GET_DESCRIPTOR (9)
+
+/* Summary
+ This request is sent from the P port processor to the
+ West Bridge device to physically configure the endpoints
+ in the device.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 3
+
+ MailBox0
+ * Context = 3
+ * Request Code = 10
+
+ D0
+ Bit 15 - Bit 8
+ EP1OUTCFG register value
+ Bit 7 - Bit 0
+ EP1INCFG register value
+
+ * D1 - D2 *
+ PEPxCFS register values where x = 3, 5, 7, 9
+
+ * D3 - D7 *
+ LEPxCFG register values where x = 3, 5, 7, 9, 10,
+ 11, 12, 13, 14, 15
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_SET_USB_CONFIG_REGISTERS (10)
+
+/* Summary
+ This request is sent to the P port processor when a
+ USB event occurs and needs to be relayed to the
+ P port.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Request Code = 11
+
+ D0
+ Event Type
+ * 0 = Reserved
+ * 1 = Reserved
+ * 2 = USB Suspend
+ * 3 = USB Resume
+ * 4 = USB Reset
+ * 5 = USB Set Configuration
+ * 6 = USB Speed change
+
+ D1
+ If EventTYpe is USB Speed change
+ * 0 = Full Speed
+ * 1 = High Speed
+
+ If EventType is USB Set Configuration
+ * The number of the configuration to use
+ * (may be zero to unconfigure)
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_USB_EVENT (11)
+
+/* Summary
+ This request is sent in both directions to transfer
+ endpoint data for endpoints 0 and 1.
+
+ Direction
+ West Bridge -> P Port Processor
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ Variable
+
+ Mailbox0
+ * Context = 3
+ * Request Code = 12
+
+ D0
+ Bit 15 - 14 Data Type
+ * 0 = Setup (payload should be the 8 byte setup packet)
+ * 1 = Data
+ * 2 = Status (payload should be empty)
+
+ Bit 13 Endpoint Number (only 0 and 1 supported)
+ Bit 12 First Packet (only supported for Host ->
+ West Bridge traffic)
+ Bit 11 Last Packet (only supported for Host ->
+ West Bridge traffic)
+
+ Bit 9 - 0 Data Length (real max data length is 64 bytes
+ for EP0 and EP1)
+
+ *D1-Dn*
+ Endpoint data
+*/
+#define CY_RQT_USB_EP_DATA (12)
+
+
+/* Summary
+ This request sets the NAK bit on an endpoint.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 13
+
+ D0
+ Endpoint Number
+
+ D1
+ * 1 = NAK Endpoint
+ * 0 = Clear NAK
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT
+ */
+#define CY_RQT_ENDPOINT_SET_NAK (13)
+
+
+/* Summary
+ This request retrieves the NAK config status of the
+ requested endpoint.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Request Code = 14
+
+ D0
+ Endpoint number
+
+ Responses
+ * CY_RESP_ENDPOINT_NAK
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT
+ */
+#define CY_RQT_GET_ENDPOINT_NAK (14)
+
+/* Summary
+ This request acknowledges a setup packet that does not
+ require any data transfer.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox
+ * Context = 3
+ * Request Code = 15
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_ACK_SETUP_PACKET (15)
+
+/* Summary
+ This request is sent when the USB storage driver within
+ West Bridge receives an Inquiry request.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ x - variable
+
+ Mailbox0
+ * Context = 3
+ * Request Code = 16
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Media type being addressed
+
+ D1
+ Bits 8 : EVPD bit from request
+ Bits 0 - 7 : Codepage from the inquiry request
+
+ D2
+ Length of the inquiry response in bytes
+
+ * D3 - Dn *
+ The inquiry response
+
+ Description
+ When the West Bridge firmware receives an SCSI Inquiry
+ request from the USB host, the response to this mass
+ storage command is created by West Bridge and forwarded to
+ the P port processor. The P port processor may change
+ this response before it is returned to the USB host. This
+ request is the method by which this may happen.
+*/
+#define CY_RQT_SCSI_INQUIRY_COMMAND (16)
+
+/* Summary
+ This request is sent when the USB storage driver within
+ West Bridge receives a Start/Stop request.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Request Code = 17
+
+ D0
+ Bits 12 - 15 : Bus index
+ Bits 8 - 11 : Zero based device index
+ Bits 0 - 7 : Media type being addressed
+
+ D1
+ Bit 1
+ * LoEj Bit (See SCSI-3 specification)
+
+ Bit 0
+ * Start Bit (See SCSI-3 specification)
+
+ Description
+ When the West Bridge firmware received a SCSI Start/Stop
+ request from the USB host, this request is relayed to the
+ P port processor. This request is used to relay the command.
+ The USB firmware will not response to the USB command until
+ the response to this request is recevied by the firmware.
+*/
+#define CY_RQT_SCSI_START_STOP_COMMAND (17)
+
+/* Summary
+ This request is sent when the USB storage driver
+ receives an unknown CBW on mass storage.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 4
+
+ Mailbox0
+ * Context = 3
+ * Request Code = 18
+
+ D0
+ Bits 12 - 15 : MediaType
+ * 0 = NAND
+ * 1 = SDIO Flash
+ * 2 = MMC Flash
+ * 3 = CE-ATA
+
+ D1
+ The length of the request in bytes
+
+ D2 - Dn
+ CBW command block from the SCSI host controller.
+
+ Description
+ When the firmware recevies a SCSI request that is not
+ understood, this request is relayed to the
+ P port processor.
+*/
+#define CY_RQT_SCSI_UNKNOWN_COMMAND (18)
+
+/* Summary
+ Request the West Bridge to signal remote wakeup
+ to the USB host.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Request code = 19
+
+ Description
+ Request from the processor to West Bridge, to signal
+ remote wakeup to the USB host.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_USB_REMOTE_WAKEUP (19)
+
+/* Summary
+ Request the West Bridge to clear all descriptors tha
+ were set previously
+ using the Set Descriptor calls.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Request code = 20
+
+ Description
+ Request from the processor to West Bridge, to clear
+ all descriptor information that was previously stored
+ on the West Bridge using CyAnUsbSetDescriptor calls.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_CLEAR_DESCRIPTORS (20)
+
+/* Summary
+ Request the West Bridge to monitor USB to storage activity
+ and send periodic updates.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 3
+ * Request code = 21
+
+ D0
+ Upper 16 bits of write threshold
+
+ D1
+ Lower 16 bits of write threshold
+
+ D2
+ Upper 16 bits of read threshold
+
+ D3
+ Lower 16 bits of read threshold
+
+ Description
+ Request from the processor to West Bridge, to start
+ monitoring the level of read/write activity on the
+ USB mass storage drive and to set the threshold
+ level at which progress reports are sent.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_USB_STORAGE_MONITOR (21)
+
+/* Summary
+ Event from the West Bridge showing that U2S activity
+ since the last event has crossed the threshold.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 3
+ * Request code = 22
+
+ D0
+ Upper 16 bits of sectors written since last event.
+
+ D1
+ Lower 16 bits of sectors written since last event.
+
+ D2
+ Upper 16 bits of sectors read since last event.
+
+ D3
+ Lower 16 bits of sectors read since last event.
+
+ Description
+ Event notification from the West Bridge indicating
+ that the number of read/writes on the USB mass
+ storage device have crossed a pre-defined threshold
+ level.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_USB_ACTIVITY_UPDATE (22)
+
+/* Summary
+ Request to select the partitions to be enumerated on a
+ storage device with partitions.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Request code = 23
+
+ D0
+ Bits 8-15 : Bus index
+ Bits 0- 7 : Device index
+
+ D1
+ Bits 8-15 : Control whether to enumerate partition 1.
+ Bits 0- 7 : Control whether to enumerate partition 0.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE
+ */
+#define CY_RQT_MS_PARTITION_SELECT (23)
+
+/************/
+
+/*@@USB responses
+ Summary
+ The USB responses include:
+ * CY_RESP_USB_CONFIG
+ * CY_RESP_ENDPOINT_CONFIG
+ * CY_RESP_ENDPOINT_STALL
+ * CY_RESP_CONNECT_STATE
+ * CY_RESP_USB_DESCRIPTOR
+ * CY_RESP_USB_INVALID_EVENT
+ * CY_RESP_ENDPOINT_NAK
+ * CY_RESP_INQUIRY_DATA
+ * CY_RESP_UNKNOWN_SCSI_COMMAND
+ */
+
+/* Summary
+ This response contains the enumeration configuration
+ information for the USB module.
+
+ Direction
+ 8051->P
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Response Code = 32
+
+ D0
+ Bits 8 - 15: Media to enumerate (bit mask)
+ Bits 0 - 7: Buses to enumerate (bit mask)
+ * 1 = Bus 0
+ * 2 = Bus 1
+
+ D1
+ Enumeration Methodology
+ * 0 = West Bridge enumeration
+ * 1 = P Port enumeration
+
+ D2
+ Bits 7 - 0 : Interface Count - the number of interfaces
+ Bits 15 - 8 : Mass storage callbacks
+
+ */
+#define CY_RESP_USB_CONFIG (32)
+
+
+/* Summary
+ This response contains the configuration information
+ for the specified endpoint.
+
+ Direction
+ 8051->P
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Response Code = 33
+
+ D0
+ Bits 15 - 12 : Endpoint Number (0 - 15)
+
+ Bits 11 - 10 : Endpoint Type
+ * 0 = Control
+ * 1 = Bulk
+ * 2 = Interrupt
+ * 3 = Isochronous
+
+ Bits 9 : Endpoint Size
+ * 0 = 512
+ * 1 = 1024
+
+ Bits 8 - 7 : Buffering
+ * 0 = Double
+ * 1 = Triple
+ * 2 = Quad
+
+ Bits 6 : Bit Direction
+ * 0 = Input
+ * 1 = Output
+ */
+#define CY_RESP_ENDPOINT_CONFIG (33)
+
+
+/* Summary
+ This response contains the stall status for
+ the specified endpoint.
+
+ Direction
+ 8051->P
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Response Code = 34
+
+ D0
+ Stall status
+ * 0 = Active
+ * 1 = Stalled
+ */
+#define CY_RESP_ENDPOINT_STALL (34)
+
+
+/* Summary
+ This response contains the connected/disconnected
+ state of the West Bridge USB pins.
+
+ Direction
+ 8051->P
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 3
+ * Response Code = 35
+
+ D0
+ Connect state
+ * 0 = Disconnected
+ * 1 = Connected
+ */
+#define CY_RESP_CONNECT_STATE (35)
+
+/* Summary
+ This response contains the information
+ about the USB configuration
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length
+ x bytes
+
+ Mailbox0
+ * Context = 3
+ * Response Code = 36
+
+ D0
+ Length in bytes of the descriptor
+
+ * D1 - DN *
+ Descriptor contents
+*/
+#define CY_RESP_USB_DESCRIPTOR (36)
+
+/* Summary
+ This response is sent in response to a bad USB event code
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length
+ 1 word (2 bytes)
+
+ Mailbox0
+ * Context = 3
+ * Response Code = 37
+
+ D0
+ The invalid event code in the request
+*/
+#define CY_RESP_USB_INVALID_EVENT (37)
+
+/* Summary
+ This response contains the current NAK status of
+ a USB endpoint.
+
+ Direction
+ West Bridge -> P port processor
+
+ Length
+ 1 transfer
+
+ Mailbox0
+ * Context = 3
+ * Response Code = 38
+
+ D0
+ The NAK status of the endpoint
+ 1 : NAK bit set
+ 0 : NAK bit clear
+*/
+#define CY_RESP_ENDPOINT_NAK (38)
+
+/* Summary
+ This response gives the contents of the inquiry
+ data back to West Bridge to returns to the USB host.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length
+ Variable
+
+ MailBox0
+ * Context = 3
+ * Response Code = 39
+
+ D0
+ Length of the inquiry response
+
+ *D1 - Dn*
+ Inquiry data
+*/
+#define CY_RESP_INQUIRY_DATA (39)
+
+/* Summary
+ This response gives the status of an unknown SCSI command.
+ This also gives three bytes of sense information.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 3
+ * Response Code = 40
+
+ D0
+ The length of the reply in bytes
+
+ D1
+ * Status of the command
+ * Sense Key
+
+ D2
+ * Additional Sense Code (ASC)
+ * Additional Sense Code Qualifier (ASCQ)
+*/
+#define CY_RESP_UNKNOWN_SCSI_COMMAND (40)
+/*******************************************************/
+
+/*@@Turbo requests
+ Summary
+ The Turbo requests include:
+ * CY_RQT_START_MTP
+ * CY_RQT_STOP_MTP
+ * CY_RQT_INIT_SEND_OBJECT
+ * CY_RQT_CANCEL_SEND_OBJECT
+ * CY_RQT_INIT_GET_OBJECT
+ * CY_RQT_CANCEL_GET_OBJECT
+ * CY_RQT_SEND_BLOCK_TABLE
+ * CY_RQT_MTP_EVENT
+ * CY_RQT_TURBO_CMD_FROM_HOST
+ * CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST
+ * CY_RQT_TURBO_SWITCH_ENDPOINT
+ * CY_RQT_TURBO_START_WRITE_DMA
+ * CY_RQT_ENABLE_USB_PATH
+ * CY_RQT_CANCEL_ASYNC_TRANSFER
+ */
+#ifndef __doxygen__
+#define CY_RQT_TUR_RQT_CONTEXT (4)
+#endif
+
+/* Summary
+ This command requests initialization of the MTP stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 0
+
+ Description
+ This command is required before any other MTP related
+ command can be sent to the West Bridge firmware.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_ALREADY_RUNNING
+ */
+#define CY_RQT_START_MTP (0)
+
+/* Summary
+ This command requests shutdown of the MTP stack.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 1
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_STOP_MTP (1)
+
+/* Summary
+ This command sets up an MTP SendObject operation.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 2
+
+ D0
+ Total bytes for send object Low 16 bits
+
+ D1
+ Total bytes for send object High 16 bits
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_INIT_SEND_OBJECT (2)
+
+/* Summary
+ This command cancels West Bridges handling of
+ an ongoing MTP SendObject operation. This
+ does NOT send an MTP response.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 3
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_NO_OPERATION_PENDING
+ */
+#define CY_RQT_CANCEL_SEND_OBJECT (3)
+
+/* Summary
+ This command sets up an MTP GetObject operation.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 4
+ * Request Code = 4
+
+ D0
+ Total bytes for get object Low 16 bits
+
+ D1
+ Total bytes for get object High 16 bits
+
+ D2
+ Transaction Id for get object Low 16 bits
+
+ D3
+ Transaction Id for get object High 16 bits
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_INIT_GET_OBJECT (4)
+
+/* Summary
+ This command notifies West Bridge of a new
+ BlockTable transfer.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 5
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_SEND_BLOCK_TABLE (5)
+
+/* Summary
+ This request is sent to the P port processor when a MTP event occurs
+ and needs to be relayed to the P port.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 4
+ * Request Code = 6
+
+ D0
+ Bits 15 - 8 : Return Status for GetObject/SendObject
+ Bits 7 - 0 : Event Type
+ * 0 = MTP SendObject Complete
+ * 1 = MTP GetObject Complete
+ * 2 = BlockTable Needed
+
+ D1
+ Lower 16 bits of the length of the data that got transferred
+ in the Turbo Endpoint.(Applicable to "MTP SendObject Complete"
+ and "MTP GetObject Complete" events)
+
+ D2
+ Upper 16 bits of the length of the data that got transferred
+ in the Turbo Endpoint. (Applicable to "MTP SendObject Complete"
+ and "MTP GetObject Complete" events)
+
+ D3
+ Lower 16 bits of the Transaction Id of the MTP_SEND_OBJECT
+ command. (Applicable to "MTP SendObject Complete" event)
+
+ D4
+ Upper 16 bits of the Transaction Id of the MTP_SEND_OBJECT
+ command. (Applicable to "MTP SendObject Complete" event)
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_MTP_EVENT (6)
+
+/* Summary
+ This request is sent to the P port processor when a command
+ is received from Host in a Turbo Endpoint. Upon receiving
+ this event, P port should read the data from the endpoint as
+ soon as possible.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 4
+ * Request Code = 7
+
+ D0
+ This contains the EP number. (This will be always two now).
+
+ D1
+ Length of the data available in the Turbo Endpoint.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_TURBO_CMD_FROM_HOST (7)
+
+/* Summary
+ This request is sent to the West Bridge when the P port
+ needs to send data to the Host in a Turbo Endpoint.
+ Upon receiving this event, Firmware will make the end point
+ avilable for the P port. If the length is zero, then
+ firmware will send a zero length packet.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ Mailbox0
+ * Context = 4
+ * Request Code = 8
+
+ D0
+ This contains the EP number. (This will be always six now).
+
+ D1
+ Lower 16 bits of the length of the data that needs to be
+ sent in the Turbo Endpoint.
+
+ D2
+ Upper 16 bits of the length of the data that needs to be
+ sent in the Turbo Endpoint.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+*/
+#define CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST (8)
+
+/* Summary
+ This command cancels West Bridges handling of
+ an ongoing MTP GetObject operation. This
+ does NOT send an MTP response.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 9
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_NO_OPERATION_PENDING
+ */
+#define CY_RQT_CANCEL_GET_OBJECT (9)
+
+/* Summary
+ This command switches a Turbo endpoint
+ from the U port to the P port. If no data
+ is in the endpoint the endpoint is
+ primed to switch as soon as data is placed
+ in the endpoint. The endpoint will continue
+ to switch until all data has been transferd.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 2
+
+ MailBox0
+ * Context = 4
+ * Request Code = 10
+
+ D0
+ Whether the read is a packet read.
+
+ D1
+ Lower 16 bits of the length of the data to switch
+ the Turbo Endpoint for.
+
+ D2
+ Upper 16 bits of the length of the data to switch
+ the Turbo Endpoint for.
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING
+ */
+#define CY_RQT_TURBO_SWITCH_ENDPOINT (10)
+
+/* Summary
+ This command requests the API to start the DMA
+ transfer of a packet of MTP data to the Antioch.
+
+ Direction
+ West Bridge -> P Port Processor
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request Code = 11
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ */
+#define CY_RQT_TURBO_START_WRITE_DMA (11)
+
+/* Summary
+ This command requests the firmware to switch the
+ internal data paths to enable USB access to the
+ Mass storage / MTP endpoints.
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ MailBox0
+ * Context = 4
+ * Request code = 12
+
+ Responses
+ * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS
+ */
+#define CY_RQT_ENABLE_USB_PATH (12)
+
+/* Summary
+ Request to cancel an asynchronous MTP write from
+ the processor side.
+
+ Direction
+ P Port processor -> West Bridge
+
+ Length (in transfers)
+ 1
+
+ Mailbox0
+ * Context = 4
+ * Request code = 13
+
+ D0
+ * EP number
+
+ Description
+ This is a request to the firmware to update internal
+ state so that a pending write on the MTP endpoint
+ can be cancelled.
+ */
+#define CY_RQT_CANCEL_ASYNC_TRANSFER (13)
+
+/******************************************************/
+
+/*@@Turbo responses
+ Summary
+ The Turbo responses include:
+ * CY_RESP_MTP_INVALID_EVENT
+ */
+
+/* Summary
+ This response is sent in response to a bad MTP event code
+
+ Direction
+ P Port Processor -> West Bridge
+
+ Length
+ 1 word (2 bytes)
+
+ Mailbox0
+ * Context = 4
+ * Response Code = 16
+
+ D0
+ The invalid event code in the request
+*/
+#define CY_RESP_MTP_INVALID_EVENT (16)
+
+#ifndef __doxygen__
+#define CY_RQT_CONTEXT_COUNT (5)
+#endif
+
+#endif /* _INCLUDED_CYASPROTOCOL_H_ */
+
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h
new file mode 100644
index 000000000000..f049d7e32a4b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h
@@ -0,0 +1,201 @@
+/* Cypress West Bridge API header file (cyasregs.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASREG_H_
+#define _INCLUDED_CYASREG_H_
+
+#if !defined(__doxygen__)
+
+#define CY_AS_MEM_CM_WB_CFG_ID (0x80)
+#define CY_AS_MEM_CM_WB_CFG_ID_VER_MASK (0x000F)
+#define CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK (0xFFF0)
+#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE (0xA100)
+#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE (0x6800)
+#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE (0xA200)
+
+
+#define CY_AS_MEM_RST_CTRL_REG (0x81)
+#define CY_AS_MEM_RST_CTRL_REG_HARD (0x0003)
+#define CY_AS_MEM_RST_CTRL_REG_SOFT (0x0001)
+#define CY_AS_MEM_RST_RSTCMPT (0x0004)
+
+#define CY_AS_MEM_P0_ENDIAN (0x82)
+#define CY_AS_LITTLE_ENDIAN (0x0000)
+#define CY_AS_BIG_ENDIAN (0x0101)
+
+#define CY_AS_MEM_P0_VM_SET (0x83)
+#define CY_AS_MEM_P0_VM_SET_VMTYPE_MASK (0x0007)
+#define CY_AS_MEM_P0_VM_SET_VMTYPE_RAM (0x0005)
+#define CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM (0x0007)
+#define CY_AS_MEM_P0_VM_SET_VMTYPE_VMWIDTH (0x0008)
+#define CY_AS_MEM_P0_VM_SET_VMTYPE_FLOWCTRL (0x0010)
+#define CY_AS_MEM_P0_VM_SET_IFMODE (0x0020)
+#define CY_AS_MEM_P0_VM_SET_CFGMODE (0x0040)
+#define CY_AS_MEM_P0_VM_SET_DACKEOB (0x0080)
+#define CY_AS_MEM_P0_VM_SET_OVERRIDE (0x0100)
+#define CY_AS_MEM_P0_VM_SET_INTOVERD (0x0200)
+#define CY_AS_MEM_P0_VM_SET_DRQOVERD (0x0400)
+#define CY_AS_MEM_P0_VM_SET_DRQPOL (0x0800)
+#define CY_AS_MEM_P0_VM_SET_DACKPOL (0x1000)
+
+
+#define CY_AS_MEM_P0_NV_SET (0x84)
+#define CY_AS_MEM_P0_NV_SET_WPSWEN (0x0001)
+#define CY_AS_MEM_P0_NV_SET_WPPOLAR (0x0002)
+
+#define CY_AS_MEM_PMU_UPDATE (0x85)
+#define CY_AS_MEM_PMU_UPDATE_UVALID (0x0001)
+#define CY_AS_MEM_PMU_UPDATE_USBUPDATE (0x0002)
+#define CY_AS_MEM_PMU_UPDATE_SDIOUPDATE (0x0004)
+
+#define CY_AS_MEM_P0_INTR_REG (0x90)
+#define CY_AS_MEM_P0_INTR_REG_MCUINT (0x0020)
+#define CY_AS_MEM_P0_INTR_REG_DRQINT (0x0800)
+#define CY_AS_MEM_P0_INTR_REG_MBINT (0x1000)
+#define CY_AS_MEM_P0_INTR_REG_PMINT (0x2000)
+#define CY_AS_MEM_P0_INTR_REG_PLLLOCKINT (0x4000)
+
+#define CY_AS_MEM_P0_INT_MASK_REG (0x91)
+#define CY_AS_MEM_P0_INT_MASK_REG_MMCUINT (0x0020)
+#define CY_AS_MEM_P0_INT_MASK_REG_MDRQINT (0x0800)
+#define CY_AS_MEM_P0_INT_MASK_REG_MMBINT (0x1000)
+#define CY_AS_MEM_P0_INT_MASK_REG_MPMINT (0x2000)
+#define CY_AS_MEM_P0_INT_MASK_REG_MPLLLOCKINT (0x4000)
+
+#define CY_AS_MEM_MCU_MB_STAT (0x92)
+#define CY_AS_MEM_P0_MCU_MBNOTRD (0x0001)
+
+#define CY_AS_MEM_P0_MCU_STAT (0x94)
+#define CY_AS_MEM_P0_MCU_STAT_CARDINS (0x0001)
+#define CY_AS_MEM_P0_MCU_STAT_CARDREM (0x0002)
+
+#define CY_AS_MEM_PWR_MAGT_STAT (0x95)
+#define CY_AS_MEM_PWR_MAGT_STAT_WAKEUP (0x0001)
+
+#define CY_AS_MEM_P0_RSE_ALLOCATE (0x98)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_SDIOAVI (0x0001)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_SDIOALLO (0x0002)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_NANDAVI (0x0004)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_NANDALLO (0x0008)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_USBAVI (0x0010)
+#define CY_AS_MEM_P0_RSE_ALLOCATE_USBALLO (0x0020)
+
+#define CY_AS_MEM_P0_RSE_MASK (0x9A)
+#define CY_AS_MEM_P0_RSE_MASK_MSDIOBUS_RW (0x0003)
+#define CY_AS_MEM_P0_RSE_MASK_MNANDBUS_RW (0x00C0)
+#define CY_AS_MEM_P0_RSE_MASK_MUSBBUS_RW (0x0030)
+
+#define CY_AS_MEM_P0_DRQ (0xA0)
+#define CY_AS_MEM_P0_DRQ_EP2DRQ (0x0004)
+#define CY_AS_MEM_P0_DRQ_EP3DRQ (0x0008)
+#define CY_AS_MEM_P0_DRQ_EP4DRQ (0x0010)
+#define CY_AS_MEM_P0_DRQ_EP5DRQ (0x0020)
+#define CY_AS_MEM_P0_DRQ_EP6DRQ (0x0040)
+#define CY_AS_MEM_P0_DRQ_EP7DRQ (0x0080)
+#define CY_AS_MEM_P0_DRQ_EP8DRQ (0x0100)
+#define CY_AS_MEM_P0_DRQ_EP9DRQ (0x0200)
+#define CY_AS_MEM_P0_DRQ_EP10DRQ (0x0400)
+#define CY_AS_MEM_P0_DRQ_EP11DRQ (0x0800)
+#define CY_AS_MEM_P0_DRQ_EP12DRQ (0x1000)
+#define CY_AS_MEM_P0_DRQ_EP13DRQ (0x2000)
+#define CY_AS_MEM_P0_DRQ_EP14DRQ (0x4000)
+#define CY_AS_MEM_P0_DRQ_EP15DRQ (0x8000)
+
+#define CY_AS_MEM_P0_DRQ_MASK (0xA1)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP2DRQ (0x0004)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP3DRQ (0x0008)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP4DRQ (0x0010)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP5DRQ (0x0020)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP6DRQ (0x0040)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP7DRQ (0x0080)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP8DRQ (0x0100)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP9DRQ (0x0200)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP10DRQ (0x0400)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP11DRQ (0x0800)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP12DRQ (0x1000)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP13DRQ (0x2000)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP14DRQ (0x4000)
+#define CY_AS_MEM_P0_DRQ_MASK_MEP15DRQ (0x8000)
+
+#define CY_AS_MEM_P0_EP2_DMA_REG (0xA2)
+#define CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK (0x7FF)
+#define CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL (1 << 12)
+#define CY_AS_MEM_P0_EP3_DMA_REG (0xA3)
+#define CY_AS_MEM_P0_EP4_DMA_REG (0xA4)
+#define CY_AS_MEM_P0_EP5_DMA_REG (0xA5)
+#define CY_AS_MEM_P0_EP6_DMA_REG (0xA6)
+#define CY_AS_MEM_P0_EP7_DMA_REG (0xA7)
+#define CY_AS_MEM_P0_EP8_DMA_REG (0xA8)
+#define CY_AS_MEM_P0_EP9_DMA_REG (0xA9)
+#define CY_AS_MEM_P0_EP10_DMA_REG (0xAA)
+#define CY_AS_MEM_P0_EP11_DMA_REG (0xAB)
+#define CY_AS_MEM_P0_EP12_DMA_REG (0xAC)
+#define CY_AS_MEM_P0_EP13_DMA_REG (0xAD)
+#define CY_AS_MEM_P0_EP14_DMA_REG (0xAE)
+#define CY_AS_MEM_P0_EP15_DMA_REG (0xAF)
+
+#define CY_AS_MEM_IROS_SLB_DATARET (0xC0)
+
+#define CY_AS_MEM_IROS_IO_CFG (0xC1)
+#define CY_AS_MEM_IROS_IO_CFG_GPIODRVST_MASK (0x0003)
+#define CY_AS_MEM_IROS_IO_CFG_GPIOSLEW_MASK (0x0004)
+#define CY_AS_MEM_IROS_IO_CFG_PPIODRVST_MASK (0x0018)
+#define CY_AS_MEM_IROS_IO_CFG_PPIOSLEW_MASK (0x0020)
+#define CY_AS_MEM_IROS_IO_CFG_SSIODRVST_MASK (0x0300)
+#define CY_AS_MEM_IROS_IO_CFG_SSIOSLEW_MASK (0x0400)
+#define CY_AS_MEM_IROS_IO_CFG_SNIODRVST_MASK (0x1800)
+#define CY_AS_MEM_IROS_IO_CFG_SNIOSLEW_MASK (0x2000)
+
+#define CY_AS_MEM_IROS_PLL_CFG (0xC2)
+
+#define CY_AS_MEM_IROS_PXB_DATARET (0xC3)
+
+#define CY_AS_MEM_PLL_LOCK_LOSS_STAT (0xC4)
+#define CY_AS_MEM_PLL_LOCK_LOSS_STAT_PLLSTAT (0x0800)
+
+#define CY_AS_MEM_IROS_SLEEP_CFG (0xC5)
+
+#define CY_AS_MEM_PNAND_CFG (0xDA)
+#define CY_AS_MEM_PNAND_CFG_IOWIDTH_MASK (0x0001)
+#define CY_AS_MEM_PNAND_CFG_IOWIDTH_8BIT (0x0000)
+#define CY_AS_MEM_PNAND_CFG_IOWIDTH_16BIT (0x0001)
+#define CY_AS_MEM_PNAND_CFG_BLKTYPE_MASK (0x0002)
+#define CY_AS_MEM_PNAND_CFG_BLKTYPE_SMALL (0x0002)
+#define CY_AS_MEM_PNAND_CFG_BLKTYPE_LARGE (0x0000)
+#define CY_AS_MEM_PNAND_CFG_EPABYTE_POS (4)
+#define CY_AS_MEM_PNAND_CFG_EPABYTE_MASK (0x0030)
+#define CY_AS_MEM_PNAND_CFG_EPABIT_POS (6)
+#define CY_AS_MEM_PNAND_CFG_EPABIT_MASK (0x00C0)
+#define CY_AS_MEM_PNAND_CFG_LNAEN_MASK (0x0100)
+
+#define CY_AS_MEM_P0_MAILBOX0 (0xF0)
+#define CY_AS_MEM_P0_MAILBOX1 (0xF1)
+#define CY_AS_MEM_P0_MAILBOX2 (0xF2)
+#define CY_AS_MEM_P0_MAILBOX3 (0xF3)
+
+#define CY_AS_MEM_MCU_MAILBOX0 (0xF8)
+#define CY_AS_MEM_MCU_MAILBOX1 (0xF9)
+#define CY_AS_MEM_MCU_MAILBOX2 (0xFA)
+#define CY_AS_MEM_MCU_MAILBOX3 (0xFB)
+
+#endif /* !defined(__doxygen__) */
+
+#endif /* _INCLUDED_CYASREG_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h
new file mode 100644
index 000000000000..52d3d688a47c
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h
@@ -0,0 +1,2759 @@
+/* Cypress West Bridge API header file (cyasstorage.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASSTORAGE_H_
+#define _INCLUDED_CYASSTORAGE_H_
+
+#include "cyasmedia.h"
+#include "cyasmisc.h"
+#include "cyas_cplus_start.h"
+
+
+/*@@Storage APIs
+ Summary
+ This section documents the storage APIs supported by the
+ West Bridge API.
+
+ Description
+ The storage API is based on some specific concepts which
+ are referenced here.
+ * <LINK Storage API Overview>
+ * Addressing
+ * Ownership
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+
+/*@@Storage API Overview
+ Summary
+ Storage devices are identified by media type. Each media
+ type is considered a single logical device.
+
+ Description
+ Each media type has a consistent block size and consists
+ of a set of logical blocks numbered from 0 to N - 1 where
+ N is the size of the
+ media type in blocks. The mass storage APIs defined below
+ provide the
+ capability to query for devices that are present, and
+ read/write data to/from
+ these devices.
+*/
+
+/*@@Addressing
+ Summary
+ Blocks within a storage device are address by a hierarchal
+ block address. This
+ address consists of the bus number, physical device,
+ logical unit, and finally
+ block address.
+
+ Description
+ While currently only a single device of each media type
+ is supported, the address
+ space reserves space in the future for multiple devices
+ of each type. Therefore
+ the second element of the address is the specific device
+ being addressed within
+ a given device type. For this release of the software,
+ this value will always be
+ zero to address the first device.
+
+ The third element of the address is the logical unit.
+ A device being managed
+ by West Bridge can be partitioned into multiple logical
+ units. This partition
+ information is stored on each device itself. Currently,
+ one of the storage devices
+ managed by West Bridge can be partitioned into two
+ logical units.
+
+ Finally a logical block address is given within the
+ logical unit to address an
+ individual block.
+*/
+
+/*@@Ownership
+ Summary
+ While West Bridge supports concurrent block level
+ operations from both the USB port and
+ the processor port, this is not desirable in most
+ situations as the file system
+ contained on the storage media cannot be accessed
+ concurrently. To insure access
+ by only one of USB and the processor, the West Bridge
+ API provides for ownership of storage
+ devices based on media type.
+
+ Description
+ The processor requests ownership of a given media type
+ by calling CyAsStorageClaim().
+ The firmware in West Bridge releases control of the
+ media and signals the processor through
+ the event callback registered with
+ CyAsStorageRegisterCallback(). The specific event is
+ the CyAsStorageProcessor. The processor can later
+ release the media via a call to
+ CyAsStorageRelease(). This call is immediate and
+ no callback is required.
+
+ If the processor has claimed storage and the USB port
+ is connected, West Bridge will need to
+ claim the storage to manage the mass storage device.
+ West Bridge requests the storage through
+ the event callback registered with
+ CyAsStorageRegisterCallback(). The specific event is
+ CyAsStorageAntioch and is named as such to reflect
+ the USB view of storage. This callback
+ is a request for the processor to release storage.
+ The storage is not actually released
+ until the processor calls CyAsStorageRelease().
+
+ Note that the CyAsStorageAntioch is only sent when the
+ USB storage device is enumerated and
+ NOT at every USB operation. The ownership of a given
+ storage media type is assumed to belong
+ to the processor until the USB connection is established.
+ At that point, the storage ownership
+ is transferred to West Bridge. After the USB connection
+ is broken, ownership can be transferred
+ back to the processor.
+*/
+
+/*@@Asynchronous Versus Synchronous Operation
+ Summary
+ When read or write operations are performed to the
+ storage devices, these operations may be
+ synchronous or asynchronous. A synchronous operation
+ is an operation where the read or write
+ operation is requested and the function does not return
+ until the operation is complete. This
+ type of function is the easiest to use but does not
+ provide for optimal usage of the P port processor time.
+
+ Description
+ An asynchronous operation is one where the function returns
+ as soon as the request is started.
+ The specific read and write request will complete at some
+ time in the future and the P port
+ processor will be notified via a callback function. While
+ asynchronous functions provide for
+ much better usage of the CPU, these function have more
+ stringent requirements for use. First,
+ any buffer use for data transfer must be valid from the
+ function call to request the operation
+ through when the callback function is called. This basically
+ implies that stack based buffers
+ are not acceptable for asynchronous calls. Second, error
+ handling must be deferred until the
+ callback function is called indicating any kind of error
+ that may have occurred.
+*/
+
+/*@@Partitioning
+ Summary
+ West Bridge API and firmware support the creation of up to
+ two logical partitions on one
+ of the storage devices that are managed by West Bridge. The
+ partitions are managed through
+ the CyAsStorageCreatePPartition and CyAsStorageRemovePPartition
+ APIs.
+
+ Description
+ The CyAsStorageCreatePPartition API is used to divide the total
+ storage on a storage
+ device into two logical units or partitions. Since the partition
+ information is stored
+ on the storage device in a custom format, partitions should
+ only be created on fixed
+ storage devices (i.e., no removable SD/MMC cards). Any data
+ stored on the device
+ before the creation of the partition, is liable to be lost when
+ a partition is created.
+
+ The CyAsStorageRemovePPartition API is used to remove the
+ stored partition information,
+ so that all of the device's capacity is treated as a single
+ partition again.
+
+ When a storage device with two partitions (units) is being
+ enumerated as a mass storage
+ device through the West Bridge, it is possible to select the
+ partitions to be made
+ visible to the USB host. This is done through the
+ CyAsUsbSelectMSPartitions API.
+*/
+
+/*********************************
+ * West Bridge Constants
+ **********************************/
+
+/* Summary
+ This constants indicates a raw device access to the read/write
+ functions
+
+ Description
+ When performing reading and writing operations on the
+ storage devices attached
+ to West Bridge, there are cases where writes need to
+ happen to raw devices, versus
+ the units contained within a device. This is
+ specifically required to manage
+ the partitions within physical devices. This constant
+ is used in calls to
+ CyAsStorageRead(), CyAsStorageReadAsync(),
+ CyAsStorageWrite() and
+ CyAsStorageWriteAsync(), to indicate that the raw
+ physical device is being
+ accessed and not any specific unit on the device.
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageReadAsync
+ * CyAsStorageWrite
+ * CyAsStorageWriteAsync
+*/
+#define CY_AS_LUN_PHYSICAL_DEVICE (0xffffffff)
+
+/* Summary
+ This constant represents the maximum DMA burst length
+ supported on a storage endpoint
+
+ Description
+ West Bridge reserves separate endpoints for accessing
+ storage media through the
+ CyAsStorageRead() and CyAsStorageWrite() calls. The
+ maximum size of these
+ endpoints is always 512 bytes, regardless of status
+ and speed of the USB
+ connection.
+*/
+#define CY_AS_STORAGE_EP_SIZE (512)
+
+/********************************
+ * West Bridge Types
+ *******************************/
+
+/* Summary
+ This type indicates the type of event in an event
+ callback from West Bridge
+
+ Description
+ At times West Bridge needs to inform the P port
+ processor of events that have
+ occurred. These events are asynchronous to the
+ thread of control on the P
+ port processor and as such are generally delivered
+ via a callback function that
+ is called as part of an interrupt handler. This
+ type indicates the resonse for
+ the call to the callback function.
+
+ See Also
+ * CyAsStorageEventCallback
+ * CyAsStorageRegisterCallback
+*/
+typedef enum cy_as_storage_event {
+ /* This event occurs when the West Bridge device has
+ detected a USB connect and has enumerated the
+ storage controlled by west bridge to the USB port.
+ this event is the signal that the processor
+ needs to release the storage media. west bridge will
+ not have control of the storage media until the
+ processor calls cy_as_release_storage() to release
+ the specific media. */
+ cy_as_storage_antioch,
+
+ /* This event occurs when the processor has requested
+ ownership of a given media type and west bridge has
+ released the media. this event is an indicator
+ that the transfer of ownership is complete and the
+ processor now owns the given media type. */
+ cy_as_storage_processor,
+
+ /* This event occurs when a removable media type has
+ been removed. */
+ cy_as_storage_removed,
+
+ /* This event occurs when a removable media type has
+ been inserted. */
+ cy_as_storage_inserted,
+
+ /* This event occurs when the West Bridge device
+ * percieves an interrrupt from an SDIO card */
+ cy_as_sdio_interrupt
+
+} cy_as_storage_event ;
+
+/* Summary
+ This type gives the type of the operation in a storage
+ operation callback
+
+ Description
+ This type is used in the callback function for asynchronous
+ operation. This type indicates whether it is a
+ CyAsStorageRead() or CyAsStorageWrite() operation that
+ has completed.
+
+ See Also
+ * <LINK Asynchronous Versus Synchronous Operation>
+ * CyAsStorageRead
+ * CyAsStorageWrite
+*/
+typedef enum cy_as_oper_type {
+ /* A data read operation */
+ cy_as_op_read,
+ /* A data write operation */
+ cy_as_op_write
+} cy_as_oper_type ;
+
+/* Summary
+ This data structure describes a specific type of media
+
+ Description
+ This data structure is the return value from the
+ CyAsStorageQueryDevice function. This structure provides
+ information about the specific storage device being queried.
+
+ See Also
+ * CyAsStorageQueryDevice
+*/
+typedef struct cy_as_device_desc {
+ /* Type of device */
+ cy_as_media_type type ;
+ /* Is the device removable */
+ cy_bool removable ;
+ /* Is the device writeable */
+ cy_bool writeable ;
+ /* Basic block size for device */
+ uint16_t block_size ;
+ /* Number of LUNs on the device */
+ uint32_t number_units ;
+ /* Is the device password locked */
+ cy_bool locked ;
+ /* Size in bytes of an Erase Unit. Block erase operation
+ is only supported for SD storage, and the erase_unit_size
+ is invalid for all other kinds of storage. */
+ uint32_t erase_unit_size ;
+} cy_as_device_desc ;
+
+/* Summary
+ This data structure describes a specific unit on a
+ specific type of media
+
+ Description
+ This data structure is the return value from the
+ CyAsStorageQueryUnit function. This structure provides
+ information about the specific unit.
+
+ See Also
+ * CyAsStorageQueryUnit
+*/
+typedef struct cy_as_unit_desc {
+ /* Type of device */
+ cy_as_media_type type ;
+ /* Basic block size for device */
+ uint16_t block_size ;
+ /* Physical start block for LUN */
+ uint32_t start_block ;
+ /* Number of blocks in the LUN */
+ uint32_t unit_size ;
+} cy_as_unit_desc ;
+
+/* Summary
+ This function type defines a callback to be called after an
+ asynchronous operation
+
+ Description
+ This function type defines a callback function that is called
+ at the completion of any asynchronous read or write operation.
+
+ See Also
+ * CyAsStorageReadAsync()
+ * CyAsStorageWriteAsync()
+*/
+typedef void (*cy_as_storage_callback)(
+ /* Handle to the device completing the storage operation */
+ cy_as_device_handle handle,
+ /* The bus completing the operation */
+ cy_as_bus_number_t bus,
+ /* The device completing the operation */
+ uint32_t device,
+ /* The unit completing the operation */
+ uint32_t unit,
+ /* The block number of the completed operation */
+ uint32_t block_number,
+ /* The type of operation */
+ cy_as_oper_type op,
+ /* The error status */
+ cy_as_return_status_t status
+ ) ;
+
+/* Summary
+ This function type defines a callback to be called in the
+ event of a storage related event
+
+ Description
+ At times West Bridge needs to inform the P port processor
+ of events that have
+ occurred. These events are asynchronous to the thread of
+ control on the P
+ port processor and as such are generally delivered via a
+ callback function that
+ is called as part of an interrupt handler. This type
+ defines the type of function
+ that must be provided as a callback function.
+
+ See Also
+ * CyAsStorageEvent
+ * CyAsStorageRegisterCallback
+*/
+typedef void (*cy_as_storage_event_callback)(
+ /* Handle to the device sending the event notification */
+ cy_as_device_handle handle,
+ /* The bus where the event happened */
+ cy_as_bus_number_t bus,
+ /* The device where the event happened */
+ uint32_t device,
+ /* The event type */
+ cy_as_storage_event evtype,
+ /* Event related data */
+ void *evdata
+ ) ;
+
+/* Summary
+ This function type defines a callback to be called after
+ an asynchronous sdio operation
+
+ Description
+ The Callback function is called at the completion of an
+ asynchronous sdio read or write operation.
+
+ See Also
+ * CyAsSdioExtendedRead()
+ * CyAsSdioExtendedWrite()
+*/
+typedef void (*cy_as_sdio_callback)(
+ /* Handle to the device completing the storage operation */
+ cy_as_device_handle handle,
+ /* The bus completing the operation */
+ cy_as_bus_number_t bus,
+ /* The device completing the operation */
+ uint32_t device,
+ /* The function number of the completing the operation.
+ if the status of the operation is either CY_AS_ERROR_IO_ABORTED
+ or CY_AS_IO_SUSPENDED then the most significant word parameter will
+ contain the number of blocks still pending. */
+ uint32_t function,
+ /* The base address of the completed operation */
+ uint32_t address,
+ /* The type of operation */
+ cy_as_oper_type op,
+ /* The status of the operation */
+ cy_as_return_status_t status
+ ) ;
+
+/* Summary
+ Enumeration of SD/MMC card registers that can be read
+ through the API.
+
+ Description
+ Some of the registers on the SD/MMC card(s) attached to the
+ West Bridge can be read through the API layers. This type
+ enumerates the registers that can be read.
+
+ See Also
+ * CyAsStorageSDRegisterRead
+ */
+typedef enum cy_as_sd_card_reg_type {
+ cy_as_sd_reg_OCR = 0,
+ cy_as_sd_reg_CID,
+ cy_as_sd_reg_CSD
+} cy_as_sd_card_reg_type ;
+
+/* Summary
+ Struct encapsulating parameters and return values for a
+ CyAsStorageQueryDevice call.
+
+ Description
+ This struct holds the input parameters and the return values
+ for an asynchronous CyAsStorageQueryDevice call.
+
+ See Also
+ * CyAsStorageQueryDevice
+ */
+typedef struct cy_as_storage_query_device_data {
+ /* The bus with the device to query */
+ cy_as_bus_number_t bus ;
+ /* The logical device number to query */
+ uint32_t device ;
+ /* The return value for the device descriptor */
+ cy_as_device_desc desc_p ;
+} cy_as_storage_query_device_data ;
+
+
+/* Summary
+ Struct encapsulating parameters and return values
+ for a CyAsStorageQueryUnit call.
+
+ Description
+ This struct holds the input parameters and the return
+ values for an asynchronous CyAsStorageQueryUnit call.
+
+ See Also
+ * CyAsStorageQueryUnit
+ */
+typedef struct cy_as_storage_query_unit_data {
+ /* The bus with the device to query */
+ cy_as_bus_number_t bus ;
+ /* The logical device number to query */
+ uint32_t device ;
+ /* The unit to query on the device */
+ uint32_t unit ;
+ /* The return value for the unit descriptor */
+ cy_as_unit_desc desc_p ;
+} cy_as_storage_query_unit_data ;
+
+/* Summary
+ Struct encapsulating the input parameter and return
+ values for a CyAsStorageSDRegisterRead call.
+
+ Description
+ This struct holds the input parameter and return
+ values for an asynchronous CyAsStorageSDRegisterRead
+ call.
+
+ See Also
+ * CyAsStorageSDRegisterRead
+ */
+typedef struct cy_as_storage_sd_reg_read_data {
+ /* Pointer to the result buffer. */
+ uint8_t *buf_p;
+ /* Length of data to be copied in bytes. */
+ uint8_t length;
+} cy_as_storage_sd_reg_read_data ;
+
+/* Summary
+ Controls which pins are used for card detection
+
+ Description
+ When a StorageDeviceControl call is made to enable or
+ disable card detection this enum is passed in to
+ control which pin is used for the detection.
+
+ See Also
+ * CyAsStorageDeviceControl
+*/
+typedef enum cy_as_storage_card_detect {
+ cy_as_storage_detect_GPIO,
+ cy_as_storage_detect_SDAT_3
+} cy_as_storage_card_detect ;
+
+#ifndef __doxygen__
+#define cy_as_storage_detect_GPIO_0 cy_as_storage_detect_GPIO
+
+/* Length of OCR value in bytes. */
+#define CY_AS_SD_REG_OCR_LENGTH (4)
+/* Length of CID value in bytes. */
+#define CY_AS_SD_REG_CID_LENGTH (16)
+/* Length of CSD value in bytes. */
+#define CY_AS_SD_REG_CSD_LENGTH (16)
+/* Max. length of register response in words. */
+#define CY_AS_SD_REG_MAX_RESP_LENGTH (10)
+
+#endif
+
+/* Summary
+ This data structure is the data passed via the evdata
+ paramater on a usb event callback for the mass storage
+ device progress event.
+
+ Description
+ This data structure reports the number of sectors that have
+ been written and read on the USB mass storage device since
+ the last event report. The corresponding event is only sent
+ when either the number of writes, or the number of reads has
+ crossed a pre-set threshold.
+
+ See Also
+ * CyAsUsbEventCallback
+ * CyAsUsbRegisterCallback
+*/
+typedef struct cy_as_m_s_c_progress_data {
+ /* Number of sectors written since the last event. */
+ uint32_t wr_count;
+ /* Number of sectors read since the last event. */
+ uint32_t rd_count;
+} cy_as_m_s_c_progress_data ;
+
+/* Summary
+Flag to set Direct Write operation to read back from the
+address written to.
+
+
+ See Also
+ *CyAsSdioDirectWrite()
+*/
+#define CY_SDIO_RAW (0x01)
+
+
+/* Summary
+Flag to set Extended Read and Write to perform IO
+using a FIFO i.e. read or write from the specified
+address only.
+
+ See Also
+ *CyAsSdioExtendedRead()
+ *CyAsSdioExtendedWrite()
+*/
+#define CY_SDIO_OP_FIFO (0x00)
+
+/* Summary
+Flag to set Extended Read and Write to perform incremental
+IO using the address provided as the base address.
+
+
+ See Also
+ *CyAsSdioExtendedRead()
+ *CyAsSdioExtendedWrite()
+*/
+#define CY_SDIO_OP_INCR (0x02)
+
+/* Summary
+Flag to set Extended Read and Write to Block Mode operation
+
+ See Also
+ *CyAsSdioExtendedRead()
+ *CyAsSdioExtendedWrite()
+*/
+#define CY_SDIO_BLOCKMODE (0x04)
+
+/* Summary
+Flag to set Extended Read and Write to Byte Mode operation
+
+ See Also
+ *CyAsSdioExtendedRead()
+ *CyAsSdioExtendedWrite()
+*/
+#define CY_SDIO_BYTEMODE (0x00)
+
+/* Summary
+Flag to force re/initialization of a function.
+
+Description
+If not set a call to CyAsSdioInitFunction()
+will not initialize a function that has been previously
+initialized.
+ See Also
+ *CyAsSdioInitFunction()
+ */
+#define CY_SDIO_FORCE_INIT (0x40)
+
+/* Summary
+Flag to re-enable the SDIO interrupts.
+
+Description
+Used with a direct read or direct write
+after the Interrupt triggerred by SDIO has been serviced
+and cleared to reset the West Bridge Sdio Interrupt.
+ See Also
+ *CyAsSdioDirectRead()
+ *CyAsSdioDirectWrite()
+*/
+
+#define CY_SDIO_REARM_INT (0x80)
+
+
+/* Summary
+ Flag to check if 4 bit support is enabled on a
+ low speed card
+ See Also
+ <link CyAsSDIOCard::card_capability>*/
+#define CY_SDIO_4BLS (0x80)
+
+/* Summary
+ Flag to check if card is a low speed card
+ See Also
+ <link CyAsSDIOCard::card_capability> */
+#define CY_SDIO_LSC (0x40)
+
+/* Summary
+ Flag to check if interrupt during multiblock data
+ transfer is enabled
+ See Also
+ <link CyAsSDIOCard::card_capability>*/
+#define CY_SDIO_E4MI (0x20)
+
+/* Summary
+ Flag to check if interrupt during multiblock data
+ transfer is supported
+ See Also
+ <link CyAsSDIOCard::card_capability> */
+#define CY_SDIO_S4MI (0x10)
+
+/* Summary
+ Flag to check if card supports function suspending.
+ See Also
+ <link CyAsSDIOCard::card_capability> */
+#define CY_SDIO_SBS (0x08)
+
+/* Summary
+ Flag to check if card supports SDIO Read-Wait
+ See Also
+ <link CyAsSDIOCard::card_capability> */
+#define CY_SDIO_SRW (0x04)
+
+/* Summary
+ Flag to check if card supports multi-block transfers
+ See Also
+ <link CyAsSDIOCard::card_capability> */
+#define CY_SDIO_SMB (0x02)
+
+/* Summary
+ Flag to check if card supports Direct IO commands
+ during execution of an Extended
+ IO function
+ See Also
+ <link CyAsSDIOCard::card_capability>*/
+#define CY_SDIO_SDC (0x01)
+
+/* Summary
+ Flag to check if function has a CSA area.
+ See Also
+ <link CyAsSDIOFunc::csa_bits> */
+#define CY_SDIO_CSA_SUP (0x40)
+
+/* Summary
+ Flag to check if CSA access is enabled.
+ See Also
+ <link CyAsSDIOFunc::csa_bits> */
+#define CY_SDIO_CSA_EN (0x80)
+
+/* Summary
+ Flag to check if CSA is Write protected.
+ See Also
+ <link CyAsSDIOFunc::csa_bits> */
+#define CY_SDIO_CSA_WP (0x01)
+
+/* Summary
+ Flag to check if CSA formatting is prohibited.
+ See Also
+ <link CyAsSDIOFunc::csa_bits>*/
+#define CY_SDIO_CSA_NF (0x02)
+
+/* Summary
+ Flag to check if the function allows wake-up from low
+ power mode using some vendor specific method.
+ See Also
+ <link CyAsSDIOFunc::wakeup_support>*/
+#define CY_SDIO_FN_WUS (0x01)
+
+
+/* Summary
+ This data structure stores SDIO function 0
+ parameters for a SDIO card
+*/
+typedef struct cy_as_sdio_card {
+ /* Number of functions present on the card. */
+ uint8_t num_functions;
+ /* Memory present(Combo card) or not */
+ uint8_t memory_present;
+ /* 16 bit manufacturer ID */
+ uint16_t manufacturer__id;
+ /* Additional vendor specific info */
+ uint16_t manufacturer_info;
+ /* Max Block size for function 0 */
+ uint16_t maxblocksize;
+ /* Block size used for function 0 */
+ uint16_t blocksize;
+ /* SDIO version supported by the card */
+ uint8_t sdio_version;
+ /* Card capability flags */
+ uint8_t card_capability;
+} cy_as_sdio_card;
+
+/* Summary
+ This data structure stores SDIO function 1-7 parameters
+ for a SDIO card
+*/
+typedef struct cy_as_sdio_func {
+ /* SDIO function code. 0 if non standard function */
+ uint8_t function_code;
+ /* Extended function type code for non-standard function */
+ uint8_t extended_func_code;
+ /* Max IO Blocksize supported by the function */
+ uint16_t maxblocksize;
+ /* IO Blocksize used by the function */
+ uint16_t blocksize;
+ /* 32 bit product serial number for the function */
+ uint32_t card_psn;
+ /* Code storage area variables */
+ uint8_t csa_bits;
+ /* Function wake-up support */
+ uint8_t wakeup_support;
+} cy_as_sdio_func;
+
+/***********************************
+ * West Bridge Functions
+ ************************************/
+
+/* Summary
+ This function starts the West Bridge storage module.
+
+ Description
+ This function initializes the West Bridge storage software
+ stack and readies this module to service storage related
+ requests. If the stack is already running, the reference
+ count for the stack is incremented.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_SUCCESS - the module started sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsStorageStop
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_start(
+ /* Handle to the device */
+ cy_as_device_handle handle,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function stops the West Bridge storage module.
+
+ Description
+ This function decrements the reference count for the
+ storage stack and if this count is zero, the storage
+ stack is shut down. The shutdown frees all resources
+ associated with the storage stack.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ While all resources associated with the storage stack
+ will be freed is a shutdown occurs,
+ resources associated with underlying layers of the
+ software will not be freed if they
+ are shared by the USB stack and the USB stack is
+ active. Specifically the DMA manager,
+ the interrupt manager, and the West Bridge
+ communications module are all shared by both the
+ USB stack and the storage stack.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge
+ * device has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not
+ * been loaded into West Bridge
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - this module was shut
+ * down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING
+ * CY_AS_ERROR_ASYNC_PENDING
+ * CY_AS_ERROR_OUT_OF_MEMORY
+
+ See Also
+ * CyAsStorageStart
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_stop(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function is used to register a callback function
+ for the storage API.
+
+ Description
+ At times West Bridge needs to inform the P port processor
+ of events that have occurred. These events are asynchronous
+ to the thread of control on the P
+ port processor and as such are generally delivered via a
+ callback function that
+ is called as part of an interrupt handler. This function
+ registers the callback
+ function that is called when an event occurs. Each call
+ to this function
+ replaces any old callback function with a new callback
+ function supplied on
+ the most recent call. This function can also be called
+ with a callback function
+ of NULL in order to remove any existing callback function
+
+ * Valid In Asynchronous Callback:YES
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has
+ * not been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle
+ * was passed in
+ * CY_AS_ERROR_SUCCESS - the function was registered
+ * sucessfully
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+
+ See Also
+ * CyAsStorageEventCallback
+ * CyAsStorageEvent
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_register_callback(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The callback function to call for async storage events */
+ cy_as_storage_event_callback callback
+ ) ;
+
+/* Summary
+ This function claims a given media type.
+
+ Description
+ This function communicates to West Bridge that the
+ processor wants control of the
+ given storage media type. Each media type can be
+ claimed or released by the
+ processor independently. As the processor is the
+ master for the storage,
+ West Bridge should release control of the requested
+ media as soon as possible and
+ signal the processor via the CyAsStorageProcessor event.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ This function just notifies West Bridge that the storage
+ is desired. The storage
+ has not actually been released by West Bridge until the
+ registered callback function
+ is called with the CyAsStorageProcessor event
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - this request was sucessfully
+ * transmitted to the West Bridge device
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_MEDIA
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_ACQUIRED
+
+ See Also:
+ * CyAsStorageClaim
+ * CyAsStorageRelease
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_claim(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to claim */
+ cy_as_bus_number_t bus,
+ /* The device to claim */
+ uint32_t device,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function releases a given media type.
+
+ Description
+ This function communicates to West Bridge that the
+ processor has released control of
+ the given storage media type. Each media type can
+ be claimed or released by the
+ processor independently. As the processor is the
+ master for the storage, West Bridge
+ can now assume ownership of the media type. No callback
+ or event is generated.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle
+ * was passed in
+ * CY_AS_ERROR_SUCCESS - the media was sucessfully
+ * released
+ * CY_AS_ERROR_MEDIA_NOT_CLAIMED - the media was not
+ * claimed by the P port
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_MEDIA
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsStorageClaim
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_release(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to release */
+ cy_as_bus_number_t bus,
+ /* The device to release */
+ uint32_t device,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function information about the number of devices present
+ on a given bus
+
+ Description
+ This function retrieves information about how many devices on
+ on the given
+ West Bridge bus.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ While the current implementation of West Bridge only
+ supports one of logical device of
+ each media type, future versions WestBridge/Antioch may
+ support multiple devices.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsStorageQueryDevice
+ * CyAsStorageQueryUnit
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_query_bus(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to query */
+ cy_as_bus_number_t bus,
+ /* The return value containing the number of
+ devices present for this media type */
+ uint32_t *count,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function information about the number of devices
+ present for a given media type
+
+ Description
+ This function retrieves information about how many
+ devices of a given media type are attached to West Bridge.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ While the current implementation of West Bridge only
+ supports one of logical device of each media type, future
+ versions West Bridge may support multiple devices.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsStorageQueryMedia
+ * CyAsMediaType
+ * CyAsStorageQueryDevice
+ * CyAsStorageQueryUnit
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_query_media(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to query */
+ cy_as_media_type type,
+ /* The return value containing the number of
+ devices present for this media type */
+ uint32_t *count,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function returns information about a given device
+ of a specific media type
+
+ Description
+ This function retrieves information about a device of a
+ given type of media. The function is called with a given
+ media type and device and a pointer to a media descriptor
+ (CyAsDeviceDesc). This function fills in the data in the
+ media descriptor to provide information about the
+ attributes of the device of the given device.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ Currently this API only supports a single logical device
+ of each media type. Therefore the only acceptable value
+ for the parameter device is zero (0).
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_NO_SUCH_MEDIA
+ * CY_AS_ERROR_NO_SUCH_DEVICE
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsMediaType
+ * CyAsStorageQueryMedia
+ * CyAsStorageQueryUnit
+ * CyAsDeviceDesc
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_query_device(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Parameters and return value for the query call */
+ cy_as_storage_query_device_data *data,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function returns information about a given unit on a
+ specific device
+
+ Description
+ This function retrieves information about a device of a
+ given logical unit. The function is called with a given
+ media type, device address, unit address, and a pointer
+ to a unit descriptor (CyAsUnitDesc). This function fills
+ in the data in the unit descriptor to provide information
+ about the attributes of the device of the given logical
+ unit.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_NO_SUCH_DEVICE
+ * CY_AS_ERROR_NO_SUCH_UNIT
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+
+ See Also
+ * CyAsMediaType
+ * CyAsStorageQueryMedia
+ * CyAsStorageQueryDevice
+ * CyAsUnitDesc
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_query_unit(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Parameters and return value for the query call */
+ cy_as_storage_query_unit_data *data_p,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function enables/disables the handling of SD/MMC card
+ detection and SD/MMC write protection in West Bridge Firmware.
+
+ Description
+ If the detection of SD/MMC card insertion or removal is being
+ done by the Processor directly, the West Bridge firmware needs
+ to be instructed to disable the card detect feature. Also, if
+ the hardware design does not use the SD_WP GPIO of the West
+ Bridge to handle SD card's write protect notch, the handling
+ of write protection if firmware should be disabled. This API
+ is used to enable/disable the card detect and write protect
+ support in West Bridge firmware.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the feature controls were
+ * set successfully
+ * CY_AS_ERROR_NO_SUCH_BUS - the specified bus is invalid
+ * CY_AS_ERROR_NOT_SUPPORTED - function not supported on
+ * the device in the specified bus
+ * CY_AS_ERROR_IN_SUSPEND - the West Brdige device is in
+ * suspended mode
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_device_control(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The bus to control */
+ cy_as_bus_number_t bus,
+ /* The device to control */
+ uint32_t device,
+ /* Enable/disable control for card detection */
+ cy_bool card_detect_en,
+ /* Enable/disable control for write protect handling */
+ cy_bool write_prot_en,
+ /* Control which pin is used for card detection */
+ cy_as_storage_card_detect config_detect,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function reads one or more blocks of data from
+ the storage system.
+
+ Description
+ This function synchronously reads one or more blocks
+ of data from the given media
+ type/device and places the data into the data buffer
+ given. This function does not
+ return until the data is read and placed into the buffer.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ If the Samsung CEATA drive is the target for a
+ read/write operation, the maximum
+ number of sectors that can be accessed through a
+ single API call is limited to 2047.
+ Longer accesses addressed to a Samsung CEATA drive
+ can result in time-out errors.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle
+ * was passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified
+ * does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified
+ * media/device pair does not exist
+ * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified
+ * does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation
+ * is pending
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was
+ * error in reading from the media
+ * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is
+ * write protected
+ * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater
+ * than 4095 logic blocks are not allowed
+
+ See Also
+ * CyAsStorageReadAsync
+ * CyAsStorageWrite
+ * CyAsStorageWriteAsync
+ * CyAsStorageCancelAsync
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_read(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to access */
+ cy_as_bus_number_t bus,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where data will be placed */
+ void *data_p,
+ /* The number of blocks to be read */
+ uint16_t num_blocks
+ ) ;
+
+/* Summary
+ This function asynchronously reads one or more blocks of data
+ from the storage system.
+
+ Description
+ This function asynchronously reads one or more blocks of
+ data from the given media
+ type/device and places the data into the data buffer given.
+ This function returns
+ as soon as the request is transmitted to the West Bridge
+ device but before the data is
+ available. When the read is complete, the callback function
+ is called to indicate the
+ data has been placed into the data buffer. Note that the
+ data buffer must remain
+ valid from when the read is requested until the callback
+ function is called.
+
+ * Valid In Asynchronous Callback: YES
+
+ Notes
+ If the Samsung CEATA drive is the target for a read/write
+ operation, the maximum
+ number of sectors that can be accessed through a single API
+ call is limited to 2047.
+ Longer accesses addressed to a Samsung CEATA drive can
+ result in time-out errors.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle
+ * was passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation
+ * is pending
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error
+ * in reading from the media
+ * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is
+ * write protected
+ * CY_AS_ERROR_QUERY_DEVICE_NEEDED - Before an
+ * asynchronous read can be issue a call to
+ * CyAsStorageQueryDevice must be made
+ * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater
+ * than 4095 logic blocks are not allowed
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageWriteAsync
+ * CyAsStorageCancelAsync
+ * CyAsStorageQueryDevice
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_read_async(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to access */
+ cy_as_bus_number_t bus,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where data will be placed */
+ void *data_p,
+ /* The number of blocks to be read */
+ uint16_t num_blocks,
+ /* The function to call when the read is complete
+ or an error occurs */
+ cy_as_storage_callback callback
+ ) ;
+
+/* Summary
+ This function writes one or more blocks of data
+ to the storage system.
+
+ Description
+ This function synchronously writes one or more blocks of
+ data to the given media/device.
+ This function does not return until the data is written
+ into the media.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ If the Samsung CEATA drive is the target for a read/write
+ operation, the maximum
+ number of sectors that can be accessed through a single
+ API call is limited to 2047.
+ Longer accesses addressed to a Samsung CEATA drive can
+ result in time-out errors.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does
+ * not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified
+ * media/device pair does not exist
+ * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified
+ * does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation
+ * is pending
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error
+ * in reading from the media
+ * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is
+ * write protected
+ * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater
+ * than 4095 logic blocks are not allowed
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageReadAsync
+ * CyAsStorageWriteAsync
+ * CyAsStorageCancelAsync
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_write(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to access */
+ cy_as_bus_number_t bus,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer containing the data to be written */
+ void *data_p,
+ /* The number of blocks to be written */
+ uint16_t num_blocks
+ ) ;
+
+/* Summary
+ This function asynchronously writes one or more blocks
+ of data to the storage system
+
+ Description
+ This function asynchronously writes one or more blocks of
+ data to the given media type/device.
+ This function returns as soon as the request is transmitted
+ to the West Bridge device
+ but before the data is actually written. When the write is
+ complete, the callback
+ function is called to indicate the data has been physically
+ written into the media.
+
+ * Valid In Asynchronous Callback: YES
+
+ Notes
+ If the Samsung CEATA drive is the target for a read/write
+ operation, the maximum
+ number of sectors that can be accessed through a single API
+ call is limited to 2047.
+ Longer accesses addressed to a Samsung CEATA drive can
+ result in time-out errors.
+
+ Notes
+ The data buffer must remain valid from when the write is
+ requested until the callback function is called.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has
+ * not been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation is
+ * pending
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is write
+ * protected
+ * CY_AS_ERROR_QUERY_DEVICE_NEEDED - A query device call is
+ * required before async writes are allowed
+ * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater
+ * than 4095 logic blocks are not allowed
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageWrite
+ * CyAsStorageReadAsync
+ * CyAsStorageCancelAsync
+ * CyAsStorageQueryDevice
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_write_async(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The bus to access */
+ cy_as_bus_number_t bus,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where the data to be written is stored */
+ void *data_p,
+ /* The number of blocks to be written */
+ uint16_t num_blocks,
+ /* The function to call when the write is complete
+ or an error occurs */
+ cy_as_storage_callback callback
+ ) ;
+
+/* Summary
+ This function aborts any outstanding asynchronous operation
+
+ Description
+ This function aborts any asynchronous block read or block
+ write operation. As only a single asynchronous block read
+ or write operation is possible at one time, this aborts
+ the single operation in progress.
+
+ * Valid In Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_OPERATION_PENDING - no asynchronous
+ * operation is pending
+
+ See Also
+ * CyAsStorageRead
+ * CyAsStorageReadAsync
+ * CyAsStorageWrite
+ * CyAsStorageWriteAsync
+ * <LINK Asynchronous Versus Synchronous Operation>
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_cancel_async(
+ /* Handle to the device with outstanding async request */
+ cy_as_device_handle handle
+ ) ;
+
+/* Summary
+ This function is used to read the content of SD registers
+
+ Description
+ This function is used to read the contents of CSD, CID and
+ CSD registers of the SD Card.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the read operation was successful
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair
+ * does not exist
+ * CY_AS_ERROR_INVALID_PARAMETER - The register type is invalid
+ * or the media is not supported on the bus
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to process
+ * request
+ * CY_AS_ERROR_INVALID_RESPONSE - communication failure with
+ * West Bridge firmware
+
+ See Also
+ * CyAsStorageSDRegReadData
+ */
+EXTERN cy_as_return_status_t
+cy_as_storage_sd_register_read(
+ /* Handle to the West Bridge device. */
+ cy_as_device_handle handle,
+ /* The bus to query */
+ cy_as_bus_number_t bus,
+ /* The device to query */
+ uint8_t device,
+ /* The type of register to read. */
+ cy_as_sd_card_reg_type reg_type,
+ /* Output data buffer and length. */
+ cy_as_storage_sd_reg_read_data *data_p,
+ /* Callback function to call when done. */
+ cy_as_function_callback cb,
+ /* Call context to send to the cb function. */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Creates a partition starting at the given block and using the
+ remaining blocks on the card.
+
+ Description
+ Storage devices attached to West Bridge can be partitioned
+ into two units.
+ The visibility of these units through the mass storage
+ interface can be
+ individually controlled. This API is used to partition
+ a device into two.
+
+ * Valid in Asynchronous Callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the partition was successfully created
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_USB_RUNNING - Partition cannot be created while
+ * USB stack is active
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to
+ * process request
+ * CY_AS_ERROR_INVALID_REQUEST - feature not supported by
+ * active device or firmware
+ * CY_AS_ERROR_INVALID_RESPONSE - communication failure with
+ * West Bridge firmware
+ * CY_AS_ERROR_ALREADY_PARTITIONED - the storage device already
+ * has been partitioned
+ * CY_AS_ERROR_INVALID_BLOCK - Size specified for the partition
+ * exceeds the actual device capacity
+
+ See Also
+ * <LINK Partitioning>
+ * CyAsStorageRemovePPartition
+ */
+EXTERN cy_as_return_status_t
+cy_as_storage_create_p_partition(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Bus on which the device to be partitioned is connected */
+ cy_as_bus_number_t bus,
+ /* Device number to be partitioned */
+ uint32_t device,
+ /* Size of partition number 0 in blocks */
+ uint32_t size,
+ /* Callback in case of async call */
+ cy_as_function_callback cb,
+ /* Client context to pass to the callback */
+ uint32_t client
+ );
+
+/* Summary
+ Removes the partition table on a storage device connected
+ to the West Bridge.
+
+ Description
+ Storage devices attached to West Bridge can be partitioned
+ into two units.This partition information is stored on the
+ device and is non-volatile. This API is used to remove the
+ stored partition information and make the entire device
+ visible as a single partition (unit).
+
+ * Valid in Asynchronous Callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the partition was successfully
+ * deleted
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_USB_RUNNING - Partition cannot be created
+ * while USB stack is active
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to
+ * process request
+ * CY_AS_ERROR_INVALID_REQUEST - operation not supported
+ * by active device/firmware
+ * CY_AS_ERROR_NO_SUCH_UNIT - the addressed device is
+ * not partitioned
+
+ See Also
+ * <LINK Partitioning>
+ * CyAsStorageCreatePPartition
+ */
+EXTERN cy_as_return_status_t
+cy_as_storage_remove_p_partition(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Bus on which device of interest is connected */
+ cy_as_bus_number_t bus,
+ /* Device number of interest */
+ uint32_t device,
+ /* Callback in case of async call */
+ cy_as_function_callback cb,
+ /* Client context to pass to the callback */
+ uint32_t client
+ );
+
+/* Summary
+ Returns the amount of data read/written to the given
+ device from the USB host.
+
+ Description
+
+ * Valid in Asynchronous Callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - API call completed successfully
+ * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device
+ * handle
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - No firmware image has been
+ * loaded on West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - Storage stack has not been
+ * started
+ * CY_AS_ERROR_NOT_SUPPORTED - This function is not
+ * supported by active firmware version
+ * CY_AS_ERROR_OUT_OF_MEMORY - Failed to get memory to
+ * process the request
+ * CY_AS_ERROR_TIMEOUT - West Bridge firmware did not
+ * respond to request
+ * CY_AS_ERROR_INVALID_RESPONSE - Unexpected reply from
+ * West Bridge firmware
+
+ See Also
+ * CyAsUsbSetMSReportThreshold
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_get_transfer_amount(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Bus on which device of interest is connected */
+ cy_as_bus_number_t bus,
+ /* Device number of interest */
+ uint32_t device,
+ /* Return value containing read/write sector counts. */
+ cy_as_m_s_c_progress_data *data_p,
+ /* Callback in case of async call */
+ cy_as_function_callback cb,
+ /* Client context to pass to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Performs a Sector Erase on an attached SD Card
+
+ Description
+ This allows you to erase an attached SD card. The area to erase
+ is specified in terms of a starting Erase Unit and a number of
+ Erase Units. The size of each Erase Unit is defined in the
+ DeviceDesc returned from a StorageQueryDevice call and it can
+ differ between SD cards.
+
+ A large erase can take a while to complete depending on the SD
+ card. In such a case it is reccomended that an async call is made.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - API call completed successfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is write protected
+ * CY_AS_ERROR_QUERY_DEVICE_NEEDED - A query device call is
+ * required before erase is allowed
+ * CY_AS_ERROR_NO_SUCH_BUS
+ * CY_AS_ERROR_NO_SUCH_DEVICE
+ * CY_AS_ERROR_NOT_SUPPORTED - Erase is currenly only supported
+ * on SD and using SD only firmware
+ * CY_AS_ERROR_OUT_OF_MEMORY
+
+ See Also
+ * CyAsStorageSDRegisterRead
+*/
+EXTERN cy_as_return_status_t
+cy_as_storage_erase(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Bus on which device of interest is connected */
+ cy_as_bus_number_t bus,
+ /* Device number of interest */
+ uint32_t device,
+ /* Erase Unit to start the erase */
+ uint32_t erase_unit,
+ /* Number of Erase Units to erase */
+ uint16_t num_erase_units,
+ /* Callback in case of async call */
+ cy_as_function_callback cb,
+ /* Client context to pass to the callback */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function is used to read a Tuple from the SDIO CIS area.
+
+ Description
+ This function is used to read a Tuple from the SDIO CIS area.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device
+ * is in suspend mode
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending
+ * CY_AS_ERROR_INVALID_REQUEST - an invalid IO request
+ * type was made
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to
+ * an invalid function
+ * CY_AS_ERROR_INVALID_ENDPOINT - A DMA request was made to
+ * an invalid endpoint
+ * CY_AS_ERROR_ENDPOINT_DISABLED - A DMA request was made to
+ * a disabled endpoint
+
+*/
+cy_as_return_status_t
+cy_as_sdio_get_c_i_s_info(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Id of tuple to be fetched */
+ uint16_t tuple_id,
+ /* Buffer to hold tuple read from card.
+ should be at least 256 bytes in size */
+ uint8_t *data_p
+ );
+
+
+/* Summary
+ This function is used to read properties of the SDIO card.
+
+ Description
+ This function is used to read properties of the SDIO card
+ into a CyAsSDIOCard structure.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_SUCCESS - the card information was returned
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+
+*/
+cy_as_return_status_t
+cy_as_sdio_query_card(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* Buffer to store card properties */
+ cy_as_sdio_card *data_p
+ );
+
+/* Summary
+ This function is used to reset a SDIO card.
+
+ Description
+ This function is used to reset a SDIO card by writing to
+ the reset bit in the CCCR and reinitializing the card. This
+ function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ */
+cy_as_return_status_t
+cy_as_sdio_reset_card(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device
+ );
+
+/* Summary
+ This function performs a Synchronous 1 byte read from the sdio
+ device function.
+
+ Description
+ This function is used to perform a synchronous 1 byte read
+ from an SDIO card function. This function is to be used only
+ for IO to an SDIO card as other media will not respond to the
+ SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed
+ * in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair
+ * does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved
+ * from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in reading
+ * from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to an
+ * invalid function
+ * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which read
+ * was attempted is in suspend
+*/
+cy_as_return_status_t
+cy_as_sdio_direct_read(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Address for IO */
+ uint32_t address,
+ /* Set to CY_SDIO_REARM_INT to reinitialize SDIO interrupt */
+ uint8_t misc_buf,
+ /* Buffer to hold byte read from card */
+ uint8_t *data_p
+ );
+
+/* Summary
+ This function performs a Synchronous 1 byte write to the
+ sdio device function.
+
+ Description
+ This function is used to perform a synchronous 1 byte write
+ to an SDIO card function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved
+ * from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to
+ * an invalid function
+ * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which
+ * write was attempted is in suspend
+*/
+cy_as_return_status_t
+cy_as_sdio_direct_write(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Address for IO */
+ uint32_t address,
+ /* Set to CY_SDIO_REARM_INT to reinitialize SDIO interrupt,
+ set to CY_SDIO_RAW for read after write */
+ uint8_t misc_buf,
+ /* Byte to write */
+ uint16_t argument,
+ /* Buffer to hold byte read from card in Read after write mode */
+ uint8_t *data_p
+ );
+
+/* Summary
+ This function is used to set the blocksize of an SDIO function.
+
+ Description
+ This function is used to set the blocksize of an SDIO function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory
+ * available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+ * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize
+ * was passed to the function.
+ * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which
+ * write was attempted is in suspend
+*/
+cy_as_return_status_t
+cy_as_sdio_set_blocksize(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Block size to set. */
+ uint16_t blocksize
+ );
+
+/* Summary
+ This function is used to read Multibyte/Block data from a
+ IO function.
+
+ Description
+ This function is used to read Multibyte/Block data from a
+ IO function. This function is to be used only for IO to an
+ SDIO card as other media will not respond to the SDIO
+ command set.
+
+ * Valid in Asynchronous Callback: YES
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved
+ * from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to
+ * an invalid function
+ * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize or
+ * block count was passed to the function.
+ * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which
+ * write was attempted is in suspend
+ * CY_AS_ERROR_IO_ABORTED - The IO operation was aborted
+ * CY_AS_ERROR_IO_SUSPENDED - The IO operation was suspended
+ * CY_AS_ERROR_INVALID_REQUEST - An invalid request was
+ * passed to the card.
+
+*/
+cy_as_return_status_t
+cy_as_sdio_extended_read(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Base Address for IO */
+ uint32_t address,
+ /* Set to CY_SDIO_BLOCKMODE for block IO,
+ CY_SDIO_BYTEMODE for multibyte IO,
+ CY_SDIO_OP_FIFO to read multiple bytes from the
+ same address, CY_SDIO_OP_INCR to read bytes from
+ the incrementing addresses */
+ uint8_t misc_buf,
+ /* Block/Byte count to read */
+ uint16_t argument,
+ /* Buffer to hold data read from card */
+ uint8_t *data_p,
+ /* Callback in case of Asyncronous call. 0 if Synchronous */
+ cy_as_sdio_callback callback
+ );
+
+/* Summary
+ This function is used to write Multibyte/Block data
+ to a IO function.
+
+ Description
+ This function is used to write Multibyte/Block data
+ to a IO function. This function is to be used only
+ for IO to an SDIO card as other media will not respond
+ to the SDIO command set.
+
+ * Valid in Asynchronous Callback: YES
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+ * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize or
+ * block count was passed to the function.
+ * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which
+ * write was attempted is in suspend
+ * CY_AS_ERROR_IO_ABORTED - The IO operation was aborted
+ * CY_AS_ERROR_IO_SUSPENDED - The IO operation was suspended
+ * CY_AS_ERROR_INVALID_REQUEST - An invalid request was
+ * passed to the card.
+*/
+cy_as_return_status_t
+cy_as_sdio_extended_write(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Base Address for IO */
+ uint32_t address,
+ /* Set to CY_SDIO_BLOCKMODE for block IO,
+ CY_SDIO_BYTEMODE for multibyte IO,
+ CY_SDIO_OP_FIFO to write multiple bytes to the same address,
+ CY_SDIO_OP_INCR to write multiple bytes to incrementing
+ addresses */
+ uint8_t misc_buf,
+ /* Block/Byte count to write
+ in case of byte mode the count should not exceed the block size
+ or 512, whichever is smaller.
+ in case of block mode, maximum number of blocks is 511. */
+ uint16_t argument,
+ /* Buffer to hold data to be written to card. */
+ uint8_t *data_p,
+ /* Callback in case of Asyncronous call. 0 if Synchronous */
+ cy_as_sdio_callback callback
+ );
+
+/* Summary
+ This function is used to initialize a SDIO card function.
+
+ Description
+ This function is used to initialize a SDIO card function
+ (1 - 7). This function is to be used only for IO to an
+ SDIO card as other media will not respond to the SDIO
+ command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed
+ * in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in
+ * reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+*/
+cy_as_return_status_t
+cy_as_sdio_init_function(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Set to CY_SDIO_FORCE_INIT to reinitialize function */
+ uint8_t misc_buf
+ );
+
+/* Summary
+ This function is used to get properties of a SDIO card function.
+
+ Description
+ This function is used to get properties of a SDIO card functio
+ (1 - 7) into a CyAsSDIOFunc structure. This function is to be
+ used only for IO to an SDIO card as other media will not respond
+ to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been
+ * started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed
+ * in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the media specified does
+ * not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair
+ * does not exist
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO request was made to
+ * an invalid function
+*/
+cy_as_return_status_t
+cy_as_sdio_query_function(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Buffer to store function properties */
+ cy_as_sdio_func *data_p
+ );
+
+/* Summary
+ This function is used to Abort the current IO function.
+
+ Description
+ This function is used to Abort the current IO function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified
+ * media/device pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory
+ * available
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+*/
+cy_as_return_status_t
+cy_as_sdio_abort_function(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no
+ );
+
+/* Summary
+ This function is used to Disable IO to an SDIO function.
+
+ Description
+ This function is used to Disable IO to an SDIO function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is
+ * in suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device
+ * pair does not exist
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+*/
+cy_as_return_status_t
+cy_as_sdio_de_init_function(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no
+ );
+
+/* Summary
+ This function is used to Suspend the current IO function.
+
+ Description
+ This function is used to Suspend the current IO function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has
+ * not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not
+ * exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified
+ * media/device pair does not exist
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory
+ * available
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made
+ * to an invalid function
+*/
+cy_as_return_status_t
+cy_as_sdio_suspend(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no
+ );
+
+/* Summary
+ This function is used to resume a Suspended IO function.
+
+ Description
+ This function is used to resume a Suspended IO function.
+ This function is to be used only for IO to an SDIO card as
+ other media will not respond to the SDIO command set.
+
+ * Valid in Asynchronous Callback: NO
+ * Valid on Antioch device: NO
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device
+ * has not been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been
+ * loaded into West Bridge
+ * CY_AS_ERROR_NOT_RUNNING - the storage stack has not
+ * been started
+ * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was
+ * passed in
+ * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is
+ * in suspend mode
+ * CY_AS_ERROR_SUCCESS - the media information was
+ * returned
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred
+ * communicating with the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the stack is not running
+ * CY_AS_ERROR_NO_SUCH_BUS - the bus specified
+ * does not exist
+ * CY_AS_ERROR_NO_SUCH_DEVICE - the specified
+ * media/device pair does not exist
+ * CY_AS_ERROR_ASYNC_PENDING - an async operation
+ * is pending
+ * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory
+ * available
+ * CY_AS_ERROR_INVALID_RESPONSE - an error message was
+ * recieved from the firmware
+ * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error
+ * in reading from the media
+ * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was
+ * made to an invalid function
+ * CY_AS_ERROR_IO_ABORTED - The IO operation was
+ * aborted
+ * CY_AS_ERROR_IO_SUSPENDED - The IO operation was
+ * suspended
+ * CY_AS_ERROR_INVALID_REQUEST - An invalid request was
+ * passed to the card.
+
+*/
+cy_as_return_status_t
+cy_as_sdio_resume(
+ /* Handle to the Westbridge device */
+ cy_as_device_handle handle,
+ /* Bus to use */
+ cy_as_bus_number_t bus,
+ /* Device number */
+ uint32_t device,
+ /* IO function Number */
+ uint8_t n_function_no,
+ /* Operation to resume (Read or Write) */
+ cy_as_oper_type op,
+ /* Micellaneous buffer same as for Extended read and Write */
+ uint8_t misc_buf,
+ /* Number of pending blocks for IO. Should be less
+ than or equal to the maximum defined for extended
+ read and write */
+ uint16_t pendingblockcount,
+ /* Buffer to continue the Suspended IO operation */
+ uint8_t *data_p
+ );
+
+
+
+/* For supporting deprecated functions */
+#include "cyasstorage_dep.h"
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASSTORAGE_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h
new file mode 100644
index 000000000000..172fa85731bb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h
@@ -0,0 +1,309 @@
+/* Cypress West Bridge API header file (cyanstorage_dep.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/* This header will contain Antioch specific declaration
+ * of the APIs that are deprecated in Astoria SDK. This is
+ * for maintaining backward compatibility
+ */
+#ifndef __INCLUDED_CYANSTORAGE_DEP_H__
+#define __INCLUDED_CYANSTORAGE_DEP_H__
+
+#ifndef __doxygen__
+
+typedef void (*cy_as_storage_callback_dep)(
+/* Handle to the device completing the storage operation */
+ cy_as_device_handle handle,
+ /* The media type completing the operation */
+ cy_as_media_type type,
+ /* The device completing the operation */
+ uint32_t device,
+ /* The unit completing the operation */
+ uint32_t unit,
+ /* The block number of the completed operation */
+ uint32_t block_number,
+ /* The type of operation */
+ cy_as_oper_type op,
+ /* The error status */
+ cy_as_return_status_t status
+ ) ;
+
+typedef void (*cy_as_storage_event_callback_dep)(
+ /* Handle to the device sending the event notification */
+ cy_as_device_handle handle,
+ /* The media type */
+ cy_as_media_type type,
+ /* The event type */
+ cy_as_storage_event evtype,
+ /* Event related data */
+ void *evdata
+ ) ;
+
+typedef struct cy_as_storage_query_device_data_dep {
+ /* The type of media to query */
+ cy_as_media_type type ;
+ /* The logical device number to query */
+ uint32_t device ;
+ /* The return value for the device descriptor */
+ cy_as_device_desc desc_p ;
+} cy_as_storage_query_device_data_dep ;
+
+typedef struct cy_as_storage_query_unit_data_dep {
+ /* The type of media to query */
+ cy_as_media_type type ;
+ /* The logical device number to query */
+ uint32_t device ;
+ /* The unit to query on the device */
+ uint32_t unit ;
+ /* The return value for the unit descriptor */
+ cy_as_unit_desc desc_p ;
+} cy_as_storage_query_unit_data_dep ;
+
+
+/************ FUNCTIONS *********************/
+
+EXTERN cy_as_return_status_t
+cy_as_storage_register_callback_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The callback function to call for async storage events */
+ cy_as_storage_event_callback_dep callback
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_claim_dep(cy_as_device_handle handle,
+ cy_as_media_type type
+ );
+
+EXTERN cy_as_return_status_t
+cy_as_storage_claim_dep_EX(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to claim */
+ cy_as_media_type *type,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_release_dep(cy_as_device_handle handle,
+ cy_as_media_type type
+ );
+
+EXTERN cy_as_return_status_t
+cy_as_storage_release_dep_EX(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Handle to the device of interest */
+ cy_as_media_type *type,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_query_device_dep(
+ cy_as_device_handle handle,
+ cy_as_media_type media,
+ uint32_t device,
+ cy_as_device_desc *desc_p
+ );
+
+EXTERN cy_as_return_status_t
+cy_as_storage_query_device_dep_EX(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Parameters and return value for the query call */
+ cy_as_storage_query_device_data_dep *data,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_query_unit_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to query */
+ cy_as_media_type type,
+ /* The logical device number to query */
+ uint32_t device,
+ /* The unit to query on the device */
+ uint32_t unit,
+ /* The return value for the unit descriptor */
+ cy_as_unit_desc *unit_p
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_query_unit_dep_EX(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* Parameters and return value for the query call */
+ cy_as_storage_query_unit_data_dep *data_p,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_device_control_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Enable/disable control for card detection */
+ cy_bool card_detect_en,
+ /* Enable/disable control for write protect handling */
+ cy_bool write_prot_en,
+ /* Callback to be called when the operation is complete */
+ cy_as_function_callback cb,
+ /* Client data to be passed to the callback */
+ uint32_t client
+ ) ;
+
+
+EXTERN cy_as_return_status_t
+cy_as_storage_read_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to access */
+ cy_as_media_type type,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where data will be placed */
+ void *data_p,
+ /* The number of blocks to be read */
+ uint16_t num_blocks
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_read_async_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to access */
+ cy_as_media_type type,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where data will be placed */
+ void *data_p,
+ /* The number of blocks to be read */
+ uint16_t num_blocks,
+ /* The function to call when the read is complete
+ or an error occurs */
+ cy_as_storage_callback_dep callback
+ ) ;
+EXTERN cy_as_return_status_t
+cy_as_storage_write_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to access */
+ cy_as_media_type type,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer containing the data to be written */
+ void *data_p,
+ /* The number of blocks to be written */
+ uint16_t num_blocks
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_write_async_dep(
+ /* Handle to the device of interest */
+ cy_as_device_handle handle,
+ /* The type of media to access */
+ cy_as_media_type type,
+ /* The device to access */
+ uint32_t device,
+ /* The unit to access */
+ uint32_t unit,
+ /* The first block to access */
+ uint32_t block,
+ /* The buffer where the data to be written is stored */
+ void *data_p,
+ /* The number of blocks to be written */
+ uint16_t num_blocks,
+ /* The function to call when the write is complete
+ or an error occurs */
+ cy_as_storage_callback_dep callback
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_sd_register_read_dep(
+ cy_as_device_handle handle,
+ cy_as_media_type type,
+ uint8_t device,
+ cy_as_sd_card_reg_type reg_type,
+ uint8_t read_len,
+ uint8_t *data_p
+ );
+
+EXTERN cy_as_return_status_t
+cy_as_storage_sd_register_read_dep_EX(
+ /* Handle to the West Bridge device. */
+ cy_as_device_handle handle,
+ /* The type of media to query */
+ cy_as_media_type type,
+ /* The device to query */
+ uint8_t device,
+ /* The type of register to read. */
+ cy_as_sd_card_reg_type reg_type,
+ /* Output data buffer and length. */
+ cy_as_storage_sd_reg_read_data *data_p,
+ /* Callback function to call when done. */
+ cy_as_function_callback cb,
+ /* Call context to send to the cb function. */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_create_p_partition_dep(
+ cy_as_device_handle handle,
+ cy_as_media_type media,
+ uint32_t device,
+ uint32_t size,
+ cy_as_function_callback cb,
+ uint32_t client) ;
+
+EXTERN cy_as_return_status_t
+cy_as_storage_remove_p_partition_dep(
+ cy_as_device_handle handle,
+ cy_as_media_type media,
+ uint32_t device,
+ cy_as_function_callback cb,
+ uint32_t client) ;
+
+#endif /*__doxygen*/
+
+#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h
new file mode 100644
index 000000000000..b1b18d0685e4
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h
@@ -0,0 +1,36 @@
+/* Cypress West Bridge API header file (cyastioch.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASTORIA_H_
+#define _INCLUDED_CYASTORIA_H_
+
+#if !defined(__doxygen__)
+
+#include "cyaserr.h"
+#include "cyasmisc.h"
+#include "cyasstorage.h"
+#include "cyasusb.h"
+#include "cyasmtp.h"
+
+#endif
+
+#endif
+
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h
new file mode 100644
index 000000000000..a3c10aa559e2
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h
@@ -0,0 +1,30 @@
+/* Cypress Astoria Sdk Version file (cyastsdkversion.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASTSDK_VERSION_H_
+#define _INCLUDED_CYASTSDK_VERSION_H_
+
+/* Astoria SDK version 1.2.1 */
+#define CYAS_MAJOR_VERSION (1)
+#define CYAS_MINOR_VERSION (2)
+#define CYAS_BUILD_NUMBER (197)
+
+#endif /*_INCLUDED_CYASTSDK_VERSION_H_*/
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h
new file mode 100644
index 000000000000..2ccccf746a10
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h
@@ -0,0 +1,71 @@
+/* Cypress West Bridge API header file (cyastypes.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASTYPES_H_
+#define _INCLUDED_CYASTYPES_H_
+/* moved to staging location, eventual implementation
+ * considered is here
+#include <mach/westbridge/cyashaldef.h>
+*/
+ #include "../../../arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h"
+
+/* Types that are not available on specific platforms.
+ * These are used only in the reference HAL implementations and
+ * are not required for using the API.
+ */
+#ifdef __unix__
+typedef unsigned long DWORD;
+typedef void *LPVOID;
+#define WINAPI
+#define INFINITE (0xFFFFFFFF)
+#define ptr_to_uint(ptr) ((unsigned int)(ptr))
+#endif
+
+/* Basic types used by the entire API */
+
+/* Summary
+ This type represents an endpoint number
+*/
+typedef uint8_t cy_as_end_point_number_t ;
+
+/* Summary
+ This type is used to return status information from
+ an API call.
+*/
+typedef uint16_t cy_as_return_status_t ;
+
+/* Summary
+ This type represents a bus number
+*/
+typedef uint32_t cy_as_bus_number_t ;
+
+/* Summary
+ All APIs provided with this release are marked extern
+ through this definition. This definition can be changed
+ to meet the scope changes required in the user build
+ environment.
+
+ For example, this can be changed to __declspec(exportdll)
+ to enable exporting the API from a DLL.
+ */
+#define EXTERN extern
+
+#endif
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h
new file mode 100644
index 000000000000..f066848cb7a9
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h
@@ -0,0 +1,1862 @@
+/* Cypress West Bridge API header file (cyasusb.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#ifndef _INCLUDED_CYASUSB_H_
+#define _INCLUDED_CYASUSB_H_
+
+#include "cyasmisc.h"
+
+#include "cyas_cplus_start.h"
+
+/*@@Enumeration Model
+ Summary
+ The USB enumeration process is the process of communicating
+ to the USB host information
+ about the capabilities of the connected device. This
+ process is completed by servicing
+ requests for various types of descriptors. In the software
+ APIs described below, this
+ process is controlled in one of two ways.
+
+ Description
+ There are advantages to either type of enumeration
+ and this is why both models are supported.
+ P Port processor based enumeraton gives the P port
+ processor maximum control and flexibility
+ for providing USB configuration information. However,
+ this does require (near) real time data
+ responses from the P port processor during the enumeration
+ process. West Bridge based enumeration
+ requires no real time information from the P port processor,
+ ensuring the fastest possible
+ enumeration times.
+
+ * P Port Based Enumeration *
+ The first method for handling USB enumeration is for the
+ processor client to handle all
+ endpoint zero requests for descriptors. This mode is
+ configured by indicating to the API
+ that the processor wants to handle all endpoint zero
+ requests. This is done by setting
+ bit 0 in the end_point_mask to a 1. The processor uses
+ CyAsUsbReadDataAsync() to read the request and
+ CyAsUsbWriteDataAsync() to write the response.
+
+ * West Bridge Based Enumeration *
+ The second method for handling USB enumeration is the
+ configuration information method.
+ Before enabling a connection from the West Bridge device
+ to the USB connector, the P Port
+ processor sends information about the USB configuration to
+ West Bridge through the configuration
+ APIs. This information is stored within the West Bridge
+ device. When a USB cable is attached,
+ the West Bridge device then handles all descriptor requests
+ based on the stored information.
+ Note that this method of enumeration only supports a single
+ USB configuration.
+
+ In either model of enumeration, the processor client is
+ responsible for ensuring that
+ the system meets USB Chapter 9 compliance requirements. This
+ can be done by providing spec
+ compliant descriptors, and handling any setup packets that
+ are sent to the client
+ appropriately.
+
+ Mass storage class compliance will be ensured by the West
+ Bridge firmware when the mass
+ storage functionality is enabled.
+*/
+
+/*@@Endpoint Configuration
+ Summary
+ The West Bridge device has one 64-byte control endpoint, one
+ 64-byte low bandwidth endpoint, four bulk
+ endpoints dedicated for mass storage usage, and up to ten
+ bulk/interrupt/isochronous
+ endpoints that can be used for USB-to-Processor communication.
+
+ Description
+ The four storage endpoints (Endpoints 2, 4, 6 and 8) are
+ reserved for accessing storage
+ devices attached to West Bridge and are not available for use
+ by the processor. These are
+ used implicitly when using the storage API to read/write to
+ the storage media.
+
+ Endpoint 0 is the standard USB control pipe used for all
+ enumeration activity. Though
+ the endpoint buffer is not directly accessible from the
+ processor, read/write activity
+ can be performed on this endpoint through the API layers.
+ This endpoint is always
+ configured as a bi-directional control endpoint.
+
+ Endpoint 1 is a 64-byte endpoint that can be used for low
+ bandwidth bulk/interrupt
+ activity. The physical buffer is not accessible from the
+ processor, but can be read/written
+ through the API. As the data coming to this endpoint is
+ being handled through the
+ software layers, there can be loss of data if a read call
+ is not waiting when an OUT
+ packet arrives.
+
+ Endpoints 3, 5, 7, 9, 10, 11, 12, 13, 14 and 15 are ten
+ configurable endpoints
+ mapped to parts of a total 4 KB FIFO buffer space on the
+ West Bridge device. This 4 KB
+ physical buffer space is divided into up to four endpoints
+ called PEP1, PEP2, PEP3 and PEP4
+ in this software document. There are multiple configurations
+ in which this buffer space
+ can be used, and the size and number of buffers available to
+ each physical endpoint
+ vary between these configurations. See the West Bridge PDD
+ for details on the buffer
+ orientation corresponding to each configuration.
+
+ * Note *
+ PEPs 1, 2, 3 and 4 are called Physical EP 3, 5, 7 and 9 in the
+ West Bridge PDD. The
+ sequential number scheme is used in the software to disambiguate
+ these from the logical
+ endpoint numbers, and also for convenience of array indexing.
+*/
+
+#if !defined(__doxygen__)
+
+
+#endif
+
+/* Summary
+ This constants defines the maximum size of a USB descriptor
+ when referenced via the CyAsUsbSetDescriptor or
+ CyAsUsbGetDescriptor functions.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+*/
+#define CY_AS_MAX_USB_DESCRIPTOR_SIZE (128)
+
+/***************************************
+ * West Bridge Types
+ ***************************************/
+
+
+/* Summary
+ This data structure is the data passed via the evdata paramater
+ on a usb event callback for the inquiry request.
+
+ Description
+ When a SCSI inquiry request arrives via the USB connection and
+ the P Port has asked
+ to receive inquiry requests, this request is forwarded to the
+ client via the USB
+ callback. This callback is called twice, once before the
+ inquiry data is forwarded
+ to the host (CyAsEventUsbInquiryBefore) and once after the
+ inquiry has been sent to the
+ USB host (CyAsEventUsbInquiryAfter). The evdata parameter
+ is a pointer to this data
+ structure.
+
+ *CyAsEventUsbInquiryBefore*
+ If the client just wishes to see the inquiry request and
+ associated data, then a simple
+ return from the callback will forward the inquiry response
+ to the USB host. If the
+ client wishes to change the data returned to the USB host,
+ the updated parameter must
+ be set to CyTrue and the memory area address by the data
+ parameter should be updated.
+ The data pointer can be changed to point to a new memory
+ area and the length field
+ changed to change the amount of data returned from the
+ inquiry request. Note that the
+ data area pointed to by the data parameter must remain
+ valid and the contents must
+ remain consistent until after the CyAsEventUsbInquiryAfter
+ event has occurred. THE LENGTH
+ MUST BE LESS THAN 192 BYTES OR THE CUSTOM INQUIRY RESPONSE
+ WILL NOT BE RETURNED. If the
+ length is too long, the default inquiry response will be
+ returned.
+
+ *CyAsEventUsbInquiryAfter*
+ If the client needs to free any data, this event signals that
+ the data associated with the inquiry is no longer needed.
+
+ See Also
+ * CyAsUsbEventCallback
+ * CyAsUsbRegisterCallback
+*/
+typedef struct cy_as_usb_inquiry_data {
+ /* The bus for the event */
+ cy_as_bus_number_t bus ;
+ /* The device the event */
+ uint32_t device ;
+ /* The EVPD bit from the SCSI INQUIRY request */
+ uint8_t evpd ;
+ /* The codepage in the inquiry request */
+ uint8_t codepage ;
+ /* This bool must be set to CyTrue indicate that the inquiry
+ data was changed */
+ cy_bool updated ;
+ /* The length of the data */
+ uint16_t length ;
+ /* The inquiry data */
+ void *data ;
+} cy_as_usb_inquiry_data ;
+
+
+/* Summary
+ This data structure is the data passed via the evdata
+ parameter on a usb event
+ callback for the unknown mass storage request.
+
+ Description
+ When a SCSI request is made that the mass storage
+ firmware in West Bridge does not
+ know how to process, this request is passed to the
+ processor for handling via
+ the usb callback. This data structure is used to
+ pass the request and the
+ associated response. The user may set the status
+ to indicate the status of the
+ request. The status value is the bCSWStatus value
+ from the USB mass storage
+ Command Status Wrapper (0 = command passed, 1 =
+ command failed). If the status
+ is set to command failed (1), the sense information
+ should be set as well. For
+ more information about sense information, see the
+ USB mass storage specification
+ as well as the SCSI specifications for block devices.
+ By default the status is
+ initialized to 1 (failure) with a sense information
+ of 05h/20h/00h which
+ indicates INVALID COMMAND.
+*/
+typedef struct cy_as_usb_unknown_command_data {
+ /* The bus for the event */
+ cy_as_bus_number_t bus ;
+ /* The device for the event */
+ uint32_t device ;
+
+ uint16_t reqlen ;
+ /* The request */
+ void *request ;
+
+ /* The returned status value for the command */
+ uint8_t status ;
+ /* If status is failed, the sense key */
+ uint8_t key ;
+ /* If status is failed, the additional sense code */
+ uint8_t asc ;
+ /* If status if failed, the additional sense code qualifier */
+ uint8_t ascq ;
+} cy_as_usb_unknown_command_data ;
+
+
+/* Summary
+ This data structure is the data passed via the evdata
+ paramater on a usb event callback for the start/stop request.
+
+ Description
+ When a SCSI start stop request arrives via the USB connection
+ and the P Port has asked
+
+ See Also
+ * CyAsUsbEventCallback
+ * CyAsUsbRegisterCallback
+*/
+typedef struct cy_as_usb_start_stop_data {
+ /* The bus for the event */
+ cy_as_bus_number_t bus ;
+ /* The device for the event */
+ uint32_t device ;
+ /* CyTrue means start request, CyFalse means stop request */
+ cy_bool start ;
+ /* CyTrue means LoEj bit set, otherwise false */
+ cy_bool loej ;
+} cy_as_usb_start_stop_data ;
+
+/* Summary
+ This data type is used to indicate which mass storage devices
+ are enumerated.
+
+ Description
+
+ See Also
+ * CyAsUsbEnumControl
+ * CyAsUsbSetEnumConfig
+*/
+typedef enum cy_as_usb_mass_storage_enum {
+ cy_as_usb_nand_enum = 0x01,
+ cy_as_usb_sd_enum = 0x02,
+ cy_as_usb_mmc_enum = 0x04,
+ cy_as_usb_ce_ata_enum = 0x08
+} cy_as_usb_mass_storage_enum ;
+
+/* Summary
+ This data type specifies the type of descriptor to transfer
+ to the West Bridge device
+
+ Description
+ During enumeration, if West Bridge is handling enumeration,
+ the West Bridge device needs to USB descriptors
+ to complete the enumeration. The function CyAsUsbSetDescriptor()
+ is used to transfer the descriptors
+ to the West Bridge device. This type is an argument to that
+ function and specifies which descriptor
+ is being transferred.
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * CyAsUsbGetDescriptor
+*/
+typedef enum cy_as_usb_desc_type {
+ /* A device descriptor - See USB 2.0 specification Chapter 9 */
+ cy_as_usb_desc_device = 1,
+ /* A device descriptor qualifier -
+ * See USB 2.0 specification Chapter 9 */
+ cy_as_usb_desc_device_qual = 2,
+ /* A configuration descriptor for FS operation -
+ * See USB 2.0 specification Chapter 9 */
+ cy_as_usb_desc_f_s_configuration = 3,
+ /* A configuration descriptor for HS operation -
+ * See USB 2.0 specification Chapter 9 */
+ cy_as_usb_desc_h_s_configuration = 4,
+ cy_as_usb_desc_string = 5
+} cy_as_usb_desc_type ;
+
+/* Summary
+ This type specifies the direction of an endpoint
+
+ Description
+ This type is used when configuring the endpoint hardware
+ to specify the direction
+ of the endpoint.
+
+ See Also
+ * CyAsUsbEndPointConfig
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbGetEndPointConfig
+*/
+typedef enum cy_as_usb_end_point_dir {
+ /* The endpoint direction is IN (West Bridge -> USB Host) */
+ cy_as_usb_in = 0,
+ /* The endpoint direction is OUT (USB Host -> West Bridge) */
+ cy_as_usb_out = 1,
+ /* The endpoint direction is IN/OUT (valid only for EP 0 & 1) */
+ cy_as_usb_in_out = 2
+} cy_as_usb_end_point_dir ;
+
+/* Summary
+ This type specifies the type of an endpoint
+
+ Description
+ This type is used when configuring the endpoint hardware
+ to specify the type of endpoint.
+
+ See Also
+ * CyAsUsbEndPointConfig
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbGetEndPointConfig
+*/
+typedef enum cy_as_usb_end_point_type {
+ cy_as_usb_control,
+ cy_as_usb_iso,
+ cy_as_usb_bulk,
+ cy_as_usb_int
+} cy_as_usb_end_point_type ;
+
+/* Summary
+ This type is a structure used to indicate the top level
+ configuration of the USB stack
+
+ Description
+ In order to configure the USB stack, the CyAsUsbSetEnumConfig()
+ function is called to indicate
+ how mass storage is to be handled, the specific number of
+ interfaces to be supported if
+ West Bridge is handling enumeration, and the end points of
+ specifi interest. This structure
+ contains this information.
+
+ See Also
+ * CyAsUsbSetConfig
+ * CyAsUsbGetConfig
+ * <LINK Enumeration Model>
+*/
+typedef struct cy_as_usb_enum_control {
+ /* Designate which devices on which buses to enumerate */
+ cy_bool devices_to_enumerate[CY_AS_MAX_BUSES]
+ [CY_AS_MAX_STORAGE_DEVICES];
+ /* If true, West Bridge will control enumeration. If this
+ * is false the P port controls enumeration. if the P port
+ * is controlling enumeration, traffic will be received via
+ * endpoint zero. */
+ cy_bool antioch_enumeration ;
+ /* This is the interface # to use for the mass storage
+ * interface, if mass storage is enumerated. if mass
+ * storage is not enumerated this value should be zero. */
+ uint8_t mass_storage_interface ;
+ /* This is the interface # to use for the MTP interface,
+ * if MTP is enumerated. if MTP is not enumerated
+ * this value should be zero. */
+ uint8_t mtp_interface ;
+ /* If true, Inquiry, START/STOP, and unknown mass storage
+ * requests cause a callback to occur for handling by the
+ * baseband processor. */
+ cy_bool mass_storage_callbacks ;
+} cy_as_usb_enum_control ;
+
+
+/* Summary
+ This structure is used to configure a single endpoint
+
+ Description
+ This data structure contains all of the information required
+ to configure the West Bridge hardware
+ associated with a given endpoint.
+
+ See Also
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbGetEndPointConfig
+*/
+typedef struct cy_as_usb_end_point_config {
+ /* If true, this endpoint is enabled */
+ cy_bool enabled ;
+ /* The direction of this endpoint */
+ cy_as_usb_end_point_dir dir ;
+ /* The type of endpoint */
+ cy_as_usb_end_point_type type ;
+ /* The physical endpoint #, 1, 2, 3, 4 */
+ cy_as_end_point_number_t physical ;
+ /* The size of the endpoint in bytes */
+ uint16_t size ;
+} cy_as_usb_end_point_config ;
+
+/* Summary
+ List of partition enumeration combinations that can
+ be selected on a partitioned storage device.
+
+ Description
+ West Bridge firmware supports creating upto two
+ partitions on mass storage devices connected to
+ West Bridge. When there are two partitions on a device,
+ the user can choose which of these partitions should be
+ made visible to a USB host through the mass storage
+ interface. This enumeration lists the various enumeration
+ selections that can be made.
+
+ See Also
+ * CyAsStorageCreatePPartition
+ * CyAsStorageRemovePPartition
+ * CyAsUsbSelectMSPartitions
+ */
+typedef enum cy_as_usb_m_s_type_t {
+ /* Enumerate only partition 0 as CD (autorun) device */
+ cy_as_usb_m_s_unit0 = 0,
+ /* Enumerate only partition 1 as MS device (default setting) */
+ cy_as_usb_m_s_unit1,
+ /* Enumerate both units */
+ cy_as_usb_m_s_both
+} cy_as_usb_m_s_type_t ;
+
+/* Summary
+ This type specifies the type of USB event that has occurred
+
+ Description
+ This type is used in the USB event callback function to
+ indicate the type of USB event that has occurred. The callback
+ function includes both this reasons for the callback and a data
+ parameter associated with the reason. The data parameter is used
+ in a reason specific way and is documented below with each reason.
+
+ See Also
+ * CyAsUsbIoCallback
+*/
+typedef enum cy_as_usb_event {
+ /* This event is sent when West Bridge is put into the suspend
+ state by the USB host. the data parameter is not used and
+ will be zero. */
+ cy_as_event_usb_suspend,
+ /* This event is sent when West Bridge is taken out of the
+ suspend state by the USB host. the data parameter is not
+ used and will be zero. */
+ cy_as_event_usb_resume,
+ /* This event is sent when a USB reset request is received
+ by the west bridge device. the data parameter is not used and
+ will be zero. */
+ cy_as_event_usb_reset,
+ /* This event is sent when a USB set configuration request is made.
+ the data parameter is a pointer to a uint16_t that contains the
+ configuration number. the configuration number may be zero to
+ indicate an unconfigure operation. */
+ cy_as_event_usb_set_config,
+ /* This event is sent when the USB connection changes speed. This is
+ generally a transition from full speed to high speed. the parameter
+ to this event is a pointer to uint16_t that gives the speed of the
+ USB connection. zero indicates full speed, one indicates high speed */
+ cy_as_event_usb_speed_change,
+ /* This event is sent when a setup packet is received.
+ * The data parameter is a pointer to the eight bytes of setup data. */
+ cy_as_event_usb_setup_packet,
+ /* This event is sent when a status packet is received. The data
+ parameter is not used. */
+ cy_as_event_usb_status_packet,
+ /* This event is sent when mass storage receives an inquiry
+ request and we have asked to see these requests. */
+ cy_as_event_usb_inquiry_before,
+ /* This event is sent when mass storage has finished processing an
+ inquiry request and any data associated with the request is no longer
+ required. */
+ cy_as_event_usb_inquiry_after,
+ /* This event is sent when mass storage receives a start/stop
+ * request and we have asked to see these requests */
+ cy_as_event_usb_start_stop,
+ /* This event is sent when a Clear Feature request is received.
+ * The data parameter is the endpoint number. */
+ cy_as_event_usb_clear_feature,
+ /* This event is sent when mass storage receives a request
+ * that is not known and we have asked to see these requests */
+ cy_as_event_usb_unknown_storage,
+ /* This event is sent when the read/write activity on the USB mass
+ storage has crossed a pre-set level */
+ cy_as_event_usb_m_s_c_progress
+} cy_as_usb_event;
+
+/* Summary
+ This type is the type of a callback function that is
+ called when a USB event occurs
+
+ Description
+ At times West Bridge needs to inform the P port processor
+ of events that have
+ occurred. These events are asynchronous to the thread of
+ control on the P
+ port processor and as such are generally delivered via a
+ callback function that
+ is called as part of an interrupt handler. This type
+ defines the type of function
+ that must be provided as a callback function for USB events.
+
+ See Also
+ * CyAsUsbEvent
+*/
+typedef void (*cy_as_usb_event_callback)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The event type being reported */
+ cy_as_usb_event ev,
+ /* The data assocaited with the event being reported */
+ void *evdata
+) ;
+
+
+/* Summary
+ This type is the callback function called after an
+ asynchronous USB read/write operation
+
+ Description
+ This function type defines a callback function that is
+ called at the completion of any
+ asynchronous read or write operation.
+
+ See Also
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+ * CY_AS_ERROR_CANCELED
+*/
+typedef void (*cy_as_usb_io_callback)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The endpoint that has completed an operation */
+ cy_as_end_point_number_t ep,
+ /* THe amount of data transferred to/from USB */
+ uint32_t count,
+ /* The data buffer for the operation */
+ void *buffer,
+ /* The error status of the operation */
+ cy_as_return_status_t status
+) ;
+
+/* Summary
+ This type is the callback function called after asynchronous
+ API functions have completed.
+
+ Description
+ When calling API functions from callback routines (interrupt
+ handlers usually) the async version of
+ these functions must be used. This callback is called when an
+ asynchronous API function has completed.
+*/
+typedef void (*cy_as_usb_function_callback)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The error status of the operation */
+ cy_as_return_status_t status,
+ /* A client supplied 32 bit tag */
+ uint32_t client
+) ;
+
+
+/********************************************
+ * West Bridge Functions
+ ********************************************/
+
+/* Summary
+ This function starts the USB stack
+
+ Description
+ This function initializes the West Bridge USB software
+ stack if it has not yet been stared.
+ This initializes any required data structures and powers
+ up any USB specific portions of
+ the West Bridge hardware. If the stack had already been
+ started, the USB stack reference count
+ is incremented.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ This function cannot be called from any type of West Bridge
+ callback.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_SUCCESS - the stack initialized and is ready
+ * for use
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating
+ * with the West Bridge device
+
+ See Also
+ * CyAsUsbStop
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_start(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function stops the USB stack
+
+ Description
+ This function decrements the reference count for
+ the USB stack and if this count
+ is zero, the USB stack is shut down. The shutdown
+ frees all resources associated
+ with the USB stack.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ While all resources associated with the USB stack will
+ be freed is a shutdown occurs,
+ resources associated with underlying layers of the software
+ will not be freed if they
+ are shared by the storage stack and the storage stack is active.
+ Specifically the DMA manager,
+ the interrupt manager, and the West Bridge communications module
+ are all shared by both the
+ USB stack and the storage stack.
+
+ Returns
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+
+ See Also
+ * CyAsUsbStart
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_stop(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function registers a callback function to be called when an
+ asynchronous USB event occurs
+
+ Description
+ When asynchronous USB events occur, a callback function can be
+ called to alert the calling program. This
+ functions allows the calling program to register a callback.
+
+ * Valid In Asynchronous Callback: YES
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_register_callback(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The function to call */
+ cy_as_usb_event_callback callback
+ ) ;
+
+
+/* Summary
+ This function connects the West Bridge device D+ and D- signals
+ physically to the USB host.
+
+ Description
+ The West Bridge device has the ability to programmatically
+ disconnect the USB pins on the device
+ from the USB host. This feature allows for re-enumeration of
+ the West Bridge device as a different
+ device when necessary. This function connects the D+ and D-
+ signal physically to the USB host
+ if they have been previously disconnnected.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+
+ See Also
+ * CyAsUsbDisconnect
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_connect(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function disconnects the West Bridge device D+ and D-
+ signals physically from the USB host.
+
+ Description
+ The West Bridge device has the ability to programmatically
+ disconnect the USB pins on the device
+ from the USB host. This feature allows for re-enumeration
+ of the West Bridge device as a different
+ device when necessary. This function disconnects the D+
+ and D- signal physically from the USB host
+ if they have been previously connected.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+
+ See Also
+ * CyAsUsbConnect
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_disconnect(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function configures the USB stack
+
+ Description
+ This function is used to configure the USB stack. It is
+ used to indicate which endpoints are going to
+ be used, and how to deal with the mass storage USB device
+ within West Bridge.
+
+ * Valid In Asynchronous Callback: Yes (if cb supplied)
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+
+ See Also
+ * CyAsUsbGetEnumConfig
+ * CyAsUsbEnumControl
+ */
+EXTERN cy_as_return_status_t
+cy_as_usb_set_enum_config(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The USB configuration information */
+ cy_as_usb_enum_control *config_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function retreives the current configuration of
+ the USB stack
+
+ Description
+ This function sends a request to West Bridge to retreive
+ the current configuration
+
+ * Valid In Asynchronous Callback: Yes (if cb supplied)
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+
+ See Also
+ * CyAsUsbSetConfig
+ * CyAsUsbConfig
+ */
+EXTERN cy_as_return_status_t
+cy_as_usb_get_enum_config(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The return value for USB congifuration information */
+ cy_as_usb_enum_control *config_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets the USB descriptor
+
+ Description
+ This function is used to set the various descriptors
+ assocaited with the USB enumeration
+ process. This function should only be called when the
+ West Bridge enumeration model is selected.
+ Descriptors set using this function can be cleared by
+ stopping the USB stack, or by calling
+ the CyAsUsbClearDescriptors function.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ These descriptors are described in the USB 2.0 specification,
+ Chapter 9.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_DESCRIPTOR - the descriptor passed is
+ * not valid
+ * CY_AS_ERROR_BAD_INDEX - a bad index was given for the type
+ * of descriptor given
+ * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be
+ * called if the P port processor doing enumeration
+
+ See Also
+ * CyAsUsbGetDescriptor
+ * CyAsUsbClearDescriptors
+ * <LINK Enumeration Model>
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_descriptor(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The type of descriptor */
+ cy_as_usb_desc_type type,
+ /* Only valid for string descriptors */
+ uint8_t index,
+ /* The descriptor to be transferred */
+ void *desc_p,
+ /* The length of the descriptor in bytes */
+ uint16_t length,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function clears all user descriptors stored
+ on the West Bridge.
+
+ Description
+ This function is used to clear all descriptors that
+ were previously
+ stored on the West Bridge through CyAsUsbSetDescriptor
+ calls, and go back
+ to the default descriptor setup in the firmware. This
+ function should
+ only be called when the Antioch enumeration model is
+ selected.
+
+ * Valid In Asynchronous Callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - all descriptors cleared successfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be
+ * called if the P port processor is doing enumeration
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * <LINK Enumeration Model>
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_clear_descriptors(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+/* Summary
+ This structure contains the descriptor buffer to be
+ filled by CyAsUsbGetDescriptor API.
+
+ Description
+ This data structure the buffer to hold the descriptor
+ data, and an in/out parameter ti indicate the
+ lenght of the buffer and descriptor data in bytes.
+
+ See Also
+ * CyAsUsbGetDescriptor
+*/
+typedef struct cy_as_get_descriptor_data {
+ /* The buffer to hold the returned descriptor */
+ void *desc_p;
+ /* This is an input and output parameter.
+ * Before the code this pointer points to a uint32_t
+ * that contains the length of the buffer. after
+ * the call, this value contains the amount of data
+ * actually returned. */
+ uint32_t length;
+
+} cy_as_get_descriptor_data ;
+
+/* Summary
+ This function retreives a given descriptor from the
+ West Bridge device
+
+ Description
+ This function retreives a USB descriptor from the West
+ Bridge device. This function should only be called when the
+ West Bridge enumeration model is selected.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Notes
+ These descriptors are described in the USB 2.0 specification,
+ Chapter 9.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_BAD_INDEX - a bad index was given for the type of
+ * descriptor given
+ * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be
+ * called if the P port processor doing enumeration
+
+ See Also
+ * CyAsUsbSetDescriptor
+ * <LINK Enumeration Model>
+*/
+
+EXTERN cy_as_return_status_t
+cy_as_usb_get_descriptor(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The type of descriptor */
+ cy_as_usb_desc_type type,
+ /* Index for string descriptor */
+ uint8_t index,
+ /* Parameters and return value for the get descriptor call */
+ cy_as_get_descriptor_data *data,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets the configuration of the physical
+ endpoints into one of the twelve supported configuration
+
+ Description
+ USB endpoints are mapped onto one of four physical
+ endpoints in the device. Therefore
+ USB endpoints are known as logical endpoints and these
+ logical endpoints are mapped to
+ one of four physical endpoints. In support of these
+ four physical endpoints there is
+ four kilo-bytes of buffer spaces that can be used as
+ buffers for these physical endpoints.
+ This 4K of buffer space can be configured in one of
+ twelve ways. This function sets the
+ buffer configuration for the physical endpoints.
+
+ * Config 1: PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (2 * 512), PEP4 (2 * 512)
+ * Config 2: PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (4 * 512), PEP4 (N/A)
+ * Config 3: PEP1 (2 * 512), PEP2 (2 * 512),
+ * PEP3 (2 * 1024), PEP4(N/A)
+ * Config 4: PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (2 * 512), PEP4 (2 * 512)
+ * Config 5: PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (4 * 512), PEP4 (N/A)
+ * Config 6: PEP1 (4 * 512), PEP2 (N/A),
+ * PEP3 (2 * 1024), PEP4 (N/A)
+ * Config 7: PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (2 * 512), PEP4 (2 * 512)
+ * Config 8: PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (4 * 512), PEP4 (N/A)
+ * Config 9: PEP1 (2 * 1024), PEP2 (N/A),
+ * PEP3 (2 * 1024), PEP4 (N/A)
+ * Config 10: PEP1 (3 * 512), PEP2 (N/A),
+ * PEP3 (3 * 512), PEP4 (2 * 512)
+ * Config 11: PEP1 (3 * 1024), PEP2 (N/A),
+ * PEP3 (N/A), PEP4 (2 * 512)
+ * Config 12: PEP1 (4 * 1024), PEP2 (N/A),
+ * PEP3 (N/A), PEP4 (N/A)
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_CONFIGURATION - the configuration given
+ * is not between 1 and 12
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_physical_configuration(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The physical endpoint configuration number */
+ uint8_t config
+ ) ;
+
+/* Summary
+ This function sets the hardware configuration for a given endpoint
+
+ Description
+ This function sets the hardware configuration for a given endpoint.
+ This is the method to set the direction of the endpoint, the type
+ of endpoint, the size of the endpoint buffer, and the buffering
+ style for the endpoint.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ Add documentation about endpoint configuration limitations
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is invalid
+ * CY_AS_ERROR_INVALID_CONFIGURATION - the endpoint configuration
+ * given is not valid
+ * CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET - the physical endpoint
+ * configuration is not set
+
+ See Also
+ * CyAsUsbGetEndPointConfig
+ * CyAsUsbEndPointConfig
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_end_point_config(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The configuration information for the endpoint */
+ cy_as_usb_end_point_config *config_p
+ ) ;
+
+/* Summary
+ This function retreives the hardware configuration for
+ a given endpoint
+
+ Description
+ This function gets the hardware configuration for the given
+ endpoint. This include information about the direction of
+ the endpoint, the type of endpoint, the size of the endpoint
+ buffer, and the buffering style for the endpoint.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is
+ * invalid
+
+ See Also
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbEndPointConfig
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_get_end_point_config(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest*/
+ cy_as_end_point_number_t ep,
+ /* The return value containing the endpoint config
+ * information */
+ cy_as_usb_end_point_config *config_p
+ ) ;
+
+/* Summary
+ This function commits the configuration information that
+ has previously been set.
+
+ Description
+ The initialization process involves calling CyAsUsbSetEnumConfig()
+ and CyAsUsbSetEndPointConfig(). These
+ functions do not actually send the configuration information to
+ the West Bridge device. Instead, these
+ functions store away the configuration information and this
+ CyAsUsbCommitConfig() actually finds the
+ best hardware configuration based on the requested endpoint
+ configuration and sends thsi optimal
+ confiuration down to the West Bridge device.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - a configuration was found and sent
+ * to West Bridge
+ * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded
+ * into West Bridge
+ * CY_AS_ERROR_INVALID_CONFIGURATION - the configuration requested
+ * is not possible
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+
+ See Also
+ * CyAsUsbSetEndPointConfig
+ * CyAsUsbSetEnumConfig
+*/
+
+EXTERN cy_as_return_status_t
+cy_as_usb_commit_config(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function reads data from a USB endpoint.
+
+ Description
+ This function reads data from an OUT. This function blocks
+ until the read is complete.
+ If this is a packet read, a single received USB packet will
+ complete the read. If this
+ is not a packet read, this function will block until all of
+ the data requested has been
+ recevied.
+
+ * Valid In Asynchronous Callback: NO
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is
+ * invalid
+
+ See Also
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteData
+ * CyAsUsbWriteDataAsync
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_read_data(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* If CyTrue, this is a packet read */
+ cy_bool pktread,
+ /* The amount of data to read */
+ uint32_t dsize,
+ /* The amount of data read */
+ uint32_t *dataread,
+ /* The buffer to hold the data read */
+ void *data
+ ) ;
+
+/* Summary
+ This function reads data from a USB endpoint
+
+ Description
+ This function reads data from an OUT endpoint. This
+ function will return immediately and the callback
+ provided will be called when the read is complete.
+ If this is a packet read, then the callback will be
+ called on the next received packet. If this is not a
+ packet read, the callback will be called when the
+ requested data is received.
+
+ * Valid In Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is
+ * invalid
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbWriteData
+ * CyAsUsbWriteDataAsync
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_read_data_async(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* If CyTrue, this is a packet read */
+ cy_bool pktread,
+ /* The amount of data to read */
+ uint32_t dsize,
+ /* The buffer for storing the data */
+ void *data,
+ /* The callback function to call when the data is read */
+ cy_as_usb_io_callback callback
+ ) ;
+
+/* Summary
+ This function writes data to a USB endpoint
+
+ Description
+ This function writes data to an IN endpoint data buffer.
+ Multiple USB packets may be sent until all data requeste
+ has been sent. This function blocks until all of the data
+ has been sent.
+
+ * Valid In Asynchronous Callback: NO
+
+ Notes
+ Calling this function with a dsize of zero will result in
+ a zero length packet transmitted to the USB host.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is
+ * invalid
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteDataAsync
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_write_data(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint to write data to */
+ cy_as_end_point_number_t ep,
+ /* The size of the data to write */
+ uint32_t dsize,
+ /* The data buffer */
+ void *data
+ ) ;
+
+/* Summary
+ This function writes data to a USB endpoint
+
+ Description
+ This function writes data to an IN endpoint data buffer.
+ This function returns immediately and when the write
+ completes, or if an error occurs, the callback function
+ is called to indicate completion of the write operation.
+
+ * Valid In Asynchronous Callback: YES
+
+ Notes
+ Calling this function with a dsize of zero will result
+ in a zero length packet transmitted to the USB host.
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is
+ * invalid
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteData
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_write_data_async(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint to write data to */
+ cy_as_end_point_number_t ep,
+ /* The size of the data */
+ uint32_t dsize,
+ /* The buffer containing the data */
+ void *data,
+ /* If true, send a short packet to terminate data */
+ cy_bool spacket,
+ /* The callback to call when the data is written */
+ cy_as_usb_io_callback callback
+ ) ;
+
+/* Summary
+ This function aborts an outstanding asynchronous
+ operation on a given endpoint
+
+ Description
+ This function aborts any outstanding operation that is
+ pending on the given endpoint.
+
+ * Valid In Asynchronous Callback: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - this module was shut down
+ * sucessfully
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not
+ * running
+ * CY_AS_ERROR_ASYNC_NOT_PENDING - no asynchronous USB
+ * operation was pending
+
+ See Also
+ * CyAsUsbReadData
+ * CyAsUsbReadDataAsync
+ * CyAsUsbWriteData
+ * CyAsUsbWriteDataAsync
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_cancel_async(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep
+ ) ;
+
+/* Summary
+ This function sets a stall condition on a given endpoint
+
+ Description
+ This function sets a stall condition on the given endpoint.
+ If the callback function is not zero, the function is
+ executed asynchronously and the callback is called when
+ the function is completed. If the callback function is
+ zero, this function executes synchronously and will not
+ return until the function has completed.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid,
+ * or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied)
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbGetStall
+ * CyAsUsbClearStall
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_stall(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+) ;
+
+/* Summary
+ This function clears a stall condition on a given endpoint
+
+ Description
+ This function clears a stall condition on the given endpoint.
+ If the callback function is not zero, the function is
+ executed asynchronously and the callback is called when the
+ function is completed. If the callback function is zero, this
+ function executes synchronously and will not return until the
+ function has completed.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid,
+ * or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied)
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbGetStall
+ * CyAsUsbSetStall
+*/
+
+EXTERN cy_as_return_status_t
+cy_as_usb_clear_stall(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+
+/* Summary
+ This function returns the stall status for a given endpoint
+
+ Description
+ This function returns the stall status for a given endpoint
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid,
+ * or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbGetStall
+ * CyAsUsbSetStall
+ * CyAsUsbClearStall
+*/
+
+EXTERN cy_as_return_status_t
+cy_as_usb_get_stall(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The return value for the stall state */
+ cy_bool *stall_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets a NAK condition on a given endpoint
+
+ Description
+ This function sets a NAK condition on the given endpoint.
+ If the callback function is not zero, the function is
+ executed asynchronously and the callback is called when
+ the function is completed. If the callback function is
+ zero, this function executes synchronously and will not
+ return until the function has completed.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was
+ * invalid, or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied)
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbGetNak
+ * CyAsUsbClearNak
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_nak(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+) ;
+
+/* Summary
+ This function clears a NAK condition on a given endpoint
+
+ Description
+ This function clears a NAK condition on the given endpoint.
+ If the callback function is not zero, the function is
+ executed asynchronously and the callback is called when the
+ function is completed. If the callback function is zero,
+ this function executes synchronously and will not return
+ until the function has completed.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid,
+ * or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied)
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbGetNak
+ * CyAsUsbSetNak
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_clear_nak(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function returns the NAK status for a given endpoint
+
+ Description
+ This function returns the NAK status for a given endpoint
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid,
+ * or was not configured as an OUT endpoint
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+
+ See Also
+ * CyAsUsbSetNak
+ * CyAsUsbClearNak
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_get_nak(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The return value for the stall state */
+ cy_bool *nak_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+) ;
+
+/* Summary
+ This function triggers a USB remote wakeup from the Processor
+ API
+
+ Description
+ When there is a Suspend condition on the USB bus, this function
+ programmatically takes the USB bus out of thi suspend state.
+
+ * Valid In Asynchronous Callback: YES (if cb supplied)
+ * Nestable: YES
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE
+ * CY_AS_ERROR_INVALID_IN_CALLBACK
+ * CY_AS_ERROR_OUT_OF_MEMORY
+ * CY_AS_ERROR_INVALID_RESPONSE
+ * CY_AS_ERROR_NOT_IN_SUSPEND
+
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_signal_remote_wakeup(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ This function sets the threshold levels for mass storage progress
+ reports from the West Bridge.
+
+ Description
+ The West Bridge firmware can be configured to track the amount of
+ read/write activity on the mass storage device, and send progress
+ reports when the activity level has crossed a threshold level.
+ This function sets the threshold levels for the progress reports.
+ Set wr_sectors and rd_sectors to 0, if the progress reports are to
+ be turned off.
+
+ * Valid In Asynchronous Callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - the function succeeded
+ * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running
+ * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with
+ * the West Bridge device
+ * CY_AS_ERROR_INVALID_HANDLE - Bad handle
+ * CY_AS_ERROR_INVALID_IN_CALLBACK - Synchronous call made
+ * while in callback
+ * CY_AS_ERROR_OUT_OF_MEMORY - Failed allocating memory for
+ * request processing
+ * CY_AS_ERROR_NOT_SUPPORTED - Firmware version does not support
+ * mass storage progress tracking
+ * CY_AS_ERROR_INVALID_RESPONSE - Unexpected response from
+ * Firmware
+
+ See Also
+ * CyAsUsbMSCProgressData
+ * CyAsEventUsbMSCProgress
+*/
+EXTERN cy_as_return_status_t
+cy_as_usb_set_m_s_report_threshold(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Number of sectors written before report is sent */
+ uint32_t wr_sectors,
+ /* Number of sectors read before report is sent */
+ uint32_t rd_sectors,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+/* Summary
+ Specify which of the partitions on a partitioned mass storage
+ device should be made visible to USB.
+
+ Description
+ West Bridge firmware supports the creation of upto two
+ partitions on mass storage devices connected to the West Bridge
+ device. When there are two partitions on a device, the user can
+ choose which of these partitions should be made visible to the
+ USB host through the USB mass storage interface. This function
+ allows the user to configure the partitions that should be
+ enumerated. At least one partition should be selected through
+ this API. If neither partition needs to be enumerated, use
+ CyAsUsbSetEnumConfig to control this.
+
+ * Valid in Asynchronous callback: Yes (if cb supplied)
+ * Nestable: Yes
+
+ Returns
+ * CY_AS_ERROR_SUCCESS - operation completed successfully
+ * CY_AS_ERROR_INVALID_HANDLE - invalid handle to the West
+ * Bridge device
+ * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not
+ * been configured
+ * CY_AS_ERROR_NO_FIRMWARE - no firmware running on West
+ * Bridge device
+ * CY_AS_ERROR_NOT_RUNNING - USB stack has not been started
+ * CY_AS_ERROR_IN_SUSPEND - West Bridge device is in
+ * suspend mode
+ * CY_AS_ERROR_INVALID_CALL_SEQUENCE - this API has to be
+ * called before CyAsUsbSetEnumConfig
+ * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to
+ * process the request
+ * CY_AS_ERROR_NO_SUCH_UNIT - Storage device addressed has
+ * not been partitioned
+ * CY_AS_ERROR_NOT_SUPPORTED - operation is not supported by
+ * active device/firmware.
+
+ See Also
+ * CyAsStorageCreatePPartition
+ * CyAsStorageRemovePPartition
+ * CyAsUsbMsType_t
+ */
+EXTERN cy_as_return_status_t
+cy_as_usb_select_m_s_partitions(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* Bus index of the device being addressed */
+ cy_as_bus_number_t bus,
+ /* Device id of the device being addressed */
+ uint32_t device,
+ /* Selection of partitions to be enumerated */
+ cy_as_usb_m_s_type_t type,
+ /* The callback, if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ );
+
+extern cy_as_media_type
+cy_as_storage_get_media_from_address(uint16_t v) ;
+
+extern cy_as_bus_number_t
+cy_as_storage_get_bus_from_address(uint16_t v) ;
+
+extern uint32_t
+cy_as_storage_get_device_from_address(uint16_t v) ;
+
+/* For supporting deprecated functions */
+#include "cyasusb_dep.h"
+
+#include "cyas_cplus_end.h"
+
+#endif /* _INCLUDED_CYASUSB_H_ */
diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h
new file mode 100644
index 000000000000..0ee18e8ba1bd
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h
@@ -0,0 +1,224 @@
+/* Cypress West Bridge API header file (cyasusb_dep.h)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+/*
+ * This header will contain Antioch specific declaration
+ * of the APIs that are deprecated in Astoria SDK. This is
+ * for maintaining backward compatibility.
+ */
+
+#ifndef __INCLUDED_CYASUSB_DEP_H__
+#define __INCLUDED_CYASUSB_DEP_H__
+
+#ifndef __doxygen__
+
+/*
+ This data structure is the data passed via the evdata
+ paramater on a usb event callback for the inquiry request.
+*/
+
+typedef struct cy_as_usb_inquiry_data_dep {
+ /* The media for the event */
+ cy_as_media_type media ;
+ /* The EVPD bit from the SCSI INQUIRY request */
+ uint8_t evpd ;
+ /* The codepage in the inquiry request */
+ uint8_t codepage ;
+ /* This bool must be set to CyTrue indicate
+ * that the inquiry data was changed */
+ cy_bool updated ;
+ /* The length of the data */
+ uint16_t length ;
+ /* The inquiry data */
+ void *data ;
+} cy_as_usb_inquiry_data_dep ;
+
+
+typedef struct cy_as_usb_unknown_command_data_dep {
+ /* The media for the event */
+ cy_as_media_type media ;
+ /* The length of the requst (should be 16 bytes) */
+ uint16_t reqlen ;
+ /* The request */
+ void *request ;
+ /* The returned status value for the command */
+ uint8_t status ;
+ /* If status is failed, the sense key */
+ uint8_t key ;
+ /* If status is failed, the additional sense code */
+ uint8_t asc ;
+ /* If status if failed, the additional sense code qualifier */
+ uint8_t ascq ;
+} cy_as_usb_unknown_command_data_dep ;
+
+
+typedef struct cy_as_usb_start_stop_data_dep {
+ /* The media type for the event */
+ cy_as_media_type media ;
+ /* CyTrue means start request, CyFalse means stop request */
+ cy_bool start ;
+ /* CyTrue means LoEj bit set, otherwise false */
+ cy_bool loej ;
+} cy_as_usb_start_stop_data_dep ;
+
+
+typedef struct cy_as_usb_enum_control_dep {
+ /* The bits in this member determine which mass storage devices
+ are enumerated. see cy_as_usb_mass_storage_enum for more details. */
+ uint8_t enum_mass_storage ;
+ /* If true, West Bridge will control enumeration. If this is false the
+ pport controls enumeration. if the P port is controlling
+ enumeration, traffic will be received via endpoint zero. */
+ cy_bool antioch_enumeration ;
+ /* This is the interface # to use for the mass storage interface,
+ if mass storage is enumerated. if mass storage is not enumerated
+ this value should be zero. */
+ uint8_t mass_storage_interface ;
+ /* If true, Inquiry, START/STOP, and unknown mass storage
+ requests cause a callback to occur for handling by the
+ baseband processor. */
+ cy_bool mass_storage_callbacks ;
+} cy_as_usb_enum_control_dep ;
+
+
+typedef void (*cy_as_usb_event_callback_dep)(
+ /* Handle to the device to configure */
+ cy_as_device_handle handle,
+ /* The event type being reported */
+ cy_as_usb_event ev,
+ /* The data assocaited with the event being reported */
+ void *evdata
+) ;
+
+
+
+/* Register Callback api */
+EXTERN cy_as_return_status_t
+cy_as_usb_register_callback_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The function to call */
+ cy_as_usb_event_callback_dep callback
+ ) ;
+
+
+extern cy_as_return_status_t
+cy_as_usb_set_enum_config_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The USB configuration information */
+ cy_as_usb_enum_control_dep *config_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+
+extern cy_as_return_status_t
+cy_as_usb_get_enum_config_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The return value for USB congifuration information */
+ cy_as_usb_enum_control_dep *config_p,
+ /* The callback if async call */
+ cy_as_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+extern cy_as_return_status_t
+cy_as_usb_get_descriptor_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The type of descriptor */
+ cy_as_usb_desc_type type,
+ /* Index for string descriptor */
+ uint8_t index,
+ /* The buffer to hold the returned descriptor */
+ void *desc_p,
+ /* This is an input and output parameter. Before the code this pointer
+ points to a uint32_t that contains the length of the buffer. after
+ the call, this value contains the amount of data actually returned. */
+ uint32_t *length_p
+ ) ;
+
+extern cy_as_return_status_t
+cy_as_usb_set_stall_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_usb_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+) ;
+
+EXTERN cy_as_return_status_t
+cy_as_usb_clear_stall_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_usb_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_usb_set_nak_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_usb_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+) ;
+
+EXTERN cy_as_return_status_t
+cy_as_usb_clear_nak_dep(
+ /* Handle to the West Bridge device */
+ cy_as_device_handle handle,
+ /* The endpoint of interest */
+ cy_as_end_point_number_t ep,
+ /* The callback if async call */
+ cy_as_usb_function_callback cb,
+ /* Client supplied data */
+ uint32_t client
+ ) ;
+
+EXTERN cy_as_return_status_t
+cy_as_usb_select_m_s_partitions_dep(
+ cy_as_device_handle handle,
+ cy_as_media_type media,
+ uint32_t device,
+ cy_as_usb_m_s_type_t type,
+ cy_as_function_callback cb,
+ uint32_t client
+ ) ;
+
+#endif /*__doxygen*/
+
+#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/
diff --git a/drivers/staging/wlags49_h2/mdd.h b/drivers/staging/wlags49_h2/mdd.h
index b50b7b0a5cac..5aa9eb846ded 100644
--- a/drivers/staging/wlags49_h2/mdd.h
+++ b/drivers/staging/wlags49_h2/mdd.h
@@ -1002,7 +1002,7 @@ XX1( CFG_SCAN, SCAN_RS_STRCT, scan_result[32] ) /*Scan results *
#define CFG_CONNECTION_MODE 0x0908 //controls the mode of the FW (ESS/AP/IBSS/ADHOC)
#define CFG_IFB 0x0909 //byte wise copy of IFB
#define CFG_MSF_TALLIES 0x090A //MSF tallies (int's, rx and tx)
-#define CFG_CURRENT_LINK_STATUS 0x090B //Latest link status got trough 0xF200 LinkEvent
+#define CFG_CURRENT_LINK_STATUS 0x090B //Latest link status got through 0xF200 LinkEvent
/*============================================================ INFORMATION FRAMES =========================*/
#define CFG_INFO_FRAME_MIN 0xF000 //lowest value representing an Informatio Frame
diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c
index 88d0d472142f..a2bc76a59f4b 100644
--- a/drivers/staging/wlags49_h2/wl_main.c
+++ b/drivers/staging/wlags49_h2/wl_main.c
@@ -450,7 +450,7 @@ int wl_insert( struct net_device *dev )
/* Initialize the adapter parameters. */
spin_lock_init( &( lp->slock ));
- /* Intialize states */
+ /* Initialize states */
//lp->lockcount = 0; //PE1DNN
lp->is_handling_int = WL_NOT_HANDLING_INT;
lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index 368c30a9d5ff..4af83d5318f2 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -219,6 +219,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
return -ENOENT;
params.key_len = len;
params.key = wlandev->wep_keys[key_index];
+ params.seq_len = 0;
callback(cookie, &params);
@@ -735,6 +736,8 @@ struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev)
priv->band.n_channels = ARRAY_SIZE(prism2_channels);
priv->band.bitrates = priv->rates;
priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
+ priv->band.band = IEEE80211_BAND_2GHZ;
+ priv->band.ht_cap.ht_supported = false;
wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
set_wiphy_dev(wiphy, dev);
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index ea81cb547bb1..a6efc033fe10 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -511,7 +511,7 @@ static void hfa384x_usb_defer(struct work_struct *data)
* hfa384x_create
*
* Sets up the hfa384x_t data structure for use. Note this
-* does _not_ intialize the actual hardware, just the data structures
+* does _not_ initialize the actual hardware, just the data structures
* we use to keep track of its state.
*
* Arguments:
diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h
index 28c057994b37..5a0395bef2f2 100644
--- a/drivers/staging/xgifb/XGI_accel.h
+++ b/drivers/staging/xgifb/XGI_accel.h
@@ -179,7 +179,7 @@
/* TW: BR(16)+2 = 0x8242 */
-int xgiCmdQueLen;
+static int xgiCmdQueLen;
#define XGI300Idle \
{ \
@@ -488,6 +488,7 @@ int xgiCmdQueLen;
int XGIfb_initaccel(void);
void XGIfb_syncaccel(void);
+int fbcon_XGI_sync(struct fb_info *info);
extern struct video_info xgi_video_info;
diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h
index fd1152eb2c92..72448e88fd8b 100644
--- a/drivers/staging/xgifb/XGI_main.h
+++ b/drivers/staging/xgifb/XGI_main.h
@@ -46,8 +46,7 @@
#define XGI_IOTYPE2 __iomem
#define XGIINITSTATIC static
-static struct pci_device_id __devinitdata xgifb_pci_table[] = {
-
+static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = {
{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
@@ -351,20 +350,17 @@ static int enable_dstn = 0;
static int XGIfb_ypan = -1;
-int XGIfb_accel = 0;
-
-
static int XGIfb_hwcursor_size = 0;
static int XGIfb_CRT2_write_enable = 0;
-int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */
-int XGIfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */
+static int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */
+static int XGIfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */
-int XGIfb_queuemode = -1; /* TW: Use MMIO queue mode by default (310/325 series only) */
+static int XGIfb_queuemode = -1; /* TW: Use MMIO queue mode by default (310/325 series only) */
-unsigned char XGIfb_detectedpdc = 0;
+static unsigned char XGIfb_detectedpdc = 0;
-unsigned char XGIfb_detectedlcda = 0xff;
+static unsigned char XGIfb_detectedlcda = 0xff;
@@ -373,10 +369,10 @@ unsigned char XGIfb_detectedlcda = 0xff;
/* XGIfb_info XGIfbinfo; */
/* TW: Hardware extension; contains data on hardware */
-struct xgi_hw_device_info XGIhw_ext;
+static struct xgi_hw_device_info XGIhw_ext;
/* TW: XGI private structure */
-struct vb_device_info XGI_Pr;
+static struct vb_device_info XGI_Pr;
/* card parameters */
static unsigned long XGIfb_mmio_size = 0;
@@ -393,7 +389,7 @@ typedef enum _XGI_CMDTYPE {
/* mode table */
/* NOT const - will be patched for 1280x960 mode number chaos reasons */
-struct _XGIbios_mode {
+static struct _XGIbios_mode {
char name[15];
u8 mode_no;
u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */
@@ -492,17 +488,17 @@ static int xgifb_mode_idx = 1;
#else
static int xgifb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
#endif
-u8 XGIfb_mode_no = 0;
-u8 XGIfb_rate_idx = 0;
+static u8 XGIfb_mode_no = 0;
+static u8 XGIfb_rate_idx = 0;
/* TW: CR36 evaluation */
-const unsigned short XGI300paneltype[] =
+static const unsigned short XGI300paneltype[] =
{ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
LCD_1024x768, LCD_1024x768, LCD_1024x768,
LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768 };
-const unsigned short XGI310paneltype[] =
+static const unsigned short XGI310paneltype[] =
{ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
LCD_1152x768, LCD_1400x1050,LCD_1280x768, LCD_1600x1200,
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 976c39bb2866..4f73d095c3ac 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -4,7 +4,7 @@
* Base on TW's sis fbdev code.
*/
-//#include <linux/config.h>
+/* #include <linux/config.h> */
#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -29,7 +29,6 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
-
#ifndef XGIFB_PAN
#define XGIFB_PAN
#endif
@@ -44,6 +43,7 @@
#include "XGI_main.h"
#include "vb_util.h"
+int XGIfb_accel = 0;
#define Index_CR_GPIO_Reg1 0x48
#define Index_CR_GPIO_Reg2 0x49
@@ -67,90 +67,84 @@ int XGIfb_GetXG21DefaultLVDSModeIdx(void);
#ifdef XGIFBDEBUG
static void dumpVGAReg(void)
{
- u8 i,reg;
-
-outXGIIDXREG(XGISR, 0x05, 0x86);
-/*
-outXGIIDXREG(XGISR, 0x08, 0x4f);
-outXGIIDXREG(XGISR, 0x0f, 0x20);
-outXGIIDXREG(XGISR, 0x11, 0x4f);
-outXGIIDXREG(XGISR, 0x13, 0x45);
-outXGIIDXREG(XGISR, 0x14, 0x51);
-outXGIIDXREG(XGISR, 0x1e, 0x41);
-outXGIIDXREG(XGISR, 0x1f, 0x0);
-outXGIIDXREG(XGISR, 0x20, 0xa1);
-outXGIIDXREG(XGISR, 0x22, 0xfb);
-outXGIIDXREG(XGISR, 0x26, 0x22);
-outXGIIDXREG(XGISR, 0x3e, 0x07);
-*/
-
-//outXGIIDXREG(XGICR, 0x19, 0x00);
-//outXGIIDXREG(XGICR, 0x1a, 0x3C);
-//outXGIIDXREG(XGICR, 0x22, 0xff);
-//outXGIIDXREG(XGICR, 0x3D, 0x10);
-
-//outXGIIDXREG(XGICR, 0x4a, 0xf3);
-
-//outXGIIDXREG(XGICR, 0x57, 0x0);
-//outXGIIDXREG(XGICR, 0x7a, 0x2c);
-
-//outXGIIDXREG(XGICR, 0x82, 0xcc);
-//outXGIIDXREG(XGICR, 0x8c, 0x0);
-/*
-outXGIIDXREG(XGICR, 0x99, 0x1);
-outXGIIDXREG(XGICR, 0x41, 0x40);
-*/
-
- for(i=0; i < 0x4f; i++)
- {
- inXGIIDXREG(XGISR, i, reg);
- printk("\no 3c4 %x",i);
- printk("\ni 3c5 => %x",reg);
- }
-
- for(i=0; i < 0xF0; i++)
- {
- inXGIIDXREG(XGICR, i, reg);
- printk("\no 3d4 %x",i);
- printk("\ni 3d5 => %x",reg);
- }
-/*
-
- outXGIIDXREG(XGIPART1,0x2F,1);
- for(i=1; i < 0x50; i++)
- {
- inXGIIDXREG(XGIPART1, i, reg);
- printk("\no d004 %x",i);
- printk("\ni d005 => %x",reg);
- }
-
- for(i=0; i < 0x50; i++)
- {
- inXGIIDXREG(XGIPART2, i, reg);
- printk("\no d010 %x",i);
- printk("\ni d011 => %x",reg);
- }
- for(i=0; i < 0x50; i++)
- {
- inXGIIDXREG(XGIPART3, i, reg);
- printk("\no d012 %x",i);
- printk("\ni d013 => %x",reg);
- }
- for(i=0; i < 0x50; i++)
- {
- inXGIIDXREG(XGIPART4, i, reg);
- printk("\no d014 %x",i);
- printk("\ni d015 => %x",reg);
- }
-*/
+ u8 i, reg;
+
+ outXGIIDXREG(XGISR, 0x05, 0x86);
+ /*
+ outXGIIDXREG(XGISR, 0x08, 0x4f);
+ outXGIIDXREG(XGISR, 0x0f, 0x20);
+ outXGIIDXREG(XGISR, 0x11, 0x4f);
+ outXGIIDXREG(XGISR, 0x13, 0x45);
+ outXGIIDXREG(XGISR, 0x14, 0x51);
+ outXGIIDXREG(XGISR, 0x1e, 0x41);
+ outXGIIDXREG(XGISR, 0x1f, 0x0);
+ outXGIIDXREG(XGISR, 0x20, 0xa1);
+ outXGIIDXREG(XGISR, 0x22, 0xfb);
+ outXGIIDXREG(XGISR, 0x26, 0x22);
+ outXGIIDXREG(XGISR, 0x3e, 0x07);
+ */
+
+ /* outXGIIDXREG(XGICR, 0x19, 0x00); */
+ /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
+ /* outXGIIDXREG(XGICR, 0x22, 0xff); */
+ /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
+
+ /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
+
+ /* outXGIIDXREG(XGICR, 0x57, 0x0); */
+ /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
+
+ /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
+ /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
+ /*
+ outXGIIDXREG(XGICR, 0x99, 0x1);
+ outXGIIDXREG(XGICR, 0x41, 0x40);
+ */
+
+ for (i = 0; i < 0x4f; i++) {
+ inXGIIDXREG(XGISR, i, reg);
+ printk("\no 3c4 %x", i);
+ printk("\ni 3c5 => %x", reg);
+ }
+
+ for (i = 0; i < 0xF0; i++) {
+ inXGIIDXREG(XGICR, i, reg);
+ printk("\no 3d4 %x", i);
+ printk("\ni 3d5 => %x", reg);
+ }
+ /*
+ outXGIIDXREG(XGIPART1,0x2F,1);
+ for (i=1; i < 0x50; i++) {
+ inXGIIDXREG(XGIPART1, i, reg);
+ printk("\no d004 %x", i);
+ printk("\ni d005 => %x", reg);
+ }
+
+ for (i=0; i < 0x50; i++) {
+ inXGIIDXREG(XGIPART2, i, reg);
+ printk("\no d010 %x", i);
+ printk("\ni d011 => %x", reg);
+ }
+ for (i=0; i < 0x50; i++) {
+ inXGIIDXREG(XGIPART3, i, reg);
+ printk("\no d012 %x",i);
+ printk("\ni d013 => %x",reg);
+ }
+ for (i=0; i < 0x50; i++) {
+ inXGIIDXREG(XGIPART4, i, reg);
+ printk("\no d014 %x",i);
+ printk("\ni d015 => %x",reg);
+ }
+ */
}
#else
-static inline void dumpVGAReg(void) {}
+static inline void dumpVGAReg(void)
+{
+}
#endif
/* data for XGI components */
-struct video_info xgi_video_info;
-
+struct video_info xgi_video_info;
#if 1
#define DEBUGPRN(x)
@@ -158,251 +152,244 @@ struct video_info xgi_video_info;
#define DEBUGPRN(x) printk(KERN_INFO x "\n");
#endif
-
/* --------------- Hardware Access Routines -------------------------- */
-int
-XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex)
+static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex)
{
- unsigned short ModeNo = modeno;
- unsigned short ModeIdIndex = 0, ClockIndex = 0;
- unsigned short RefreshRateTableIndex = 0;
+ unsigned short ModeNo = modeno;
+ unsigned short ModeIdIndex = 0, ClockIndex = 0;
+ unsigned short RefreshRateTableIndex = 0;
- /*unsigned long temp = 0;*/
- int Clock;
- XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
- InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
+ /* unsigned long temp = 0; */
+ int Clock;
+ XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
- RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, XGI_Pr);
-/*
- temp = XGI_SearchModeID( ModeNo , &ModeIdIndex, XGI_Pr ) ;
- if(!temp) {
- printk(KERN_ERR "Could not find mode %x\n", ModeNo);
- return 65000;
- }
+ /*
+ temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
+ if (!temp) {
+ printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+ return 65000;
+ }
- RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
- RefreshRateTableIndex += (rateindex - 1);
+ RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
+ RefreshRateTableIndex += (rateindex - 1);
-*/
- ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwDeviceExtension->jChipType < XGI_315H) {
- ClockIndex &= 0x3F;
- }
- Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000 ;
+ */
+ ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if (HwDeviceExtension->jChipType < XGI_315H)
+ ClockIndex &= 0x3F;
+
+ Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
- return(Clock);
+ return Clock;
}
-int
-XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex,
- u32 *left_margin, u32 *right_margin,
- u32 *upper_margin, u32 *lower_margin,
- u32 *hsync_len, u32 *vsync_len,
- u32 *sync, u32 *vmode)
+static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex,
+ u32 *left_margin, u32 *right_margin, u32 *upper_margin,
+ u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
+ u32 *vmode)
{
- unsigned short ModeNo = modeno;
- unsigned short ModeIdIndex = 0, index = 0;
- unsigned short RefreshRateTableIndex = 0;
-
- unsigned short VRE, VBE, VRS, VBS, VDE, VT;
- unsigned short HRE, HBE, HRS, HBS, HDE, HT;
- unsigned char sr_data, cr_data, cr_data2;
- unsigned long cr_data3;
- int A, B, C, D, E, F, temp, j;
- XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
- InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
- RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
-/*
- temp = XGI_SearchModeID( ModeNo, &ModeIdIndex, XGI_Pr);
- if(!temp) return 0;
-
- RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
- RefreshRateTableIndex += (rateindex - 1);
-*/
- index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
+ unsigned short ModeNo = modeno;
+ unsigned short ModeIdIndex = 0, index = 0;
+ unsigned short RefreshRateTableIndex = 0;
+
+ unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+ unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+ unsigned char sr_data, cr_data, cr_data2;
+ unsigned long cr_data3;
+ int A, B, C, D, E, F, temp, j;
+ XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, XGI_Pr);
+ /*
+ temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
+ if (!temp)
+ return 0;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
+ RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
+ RefreshRateTableIndex += (rateindex - 1);
+ */
+ index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- /* Horizontal total */
- HT = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x03) << 8);
- A = HT + 5;
+ sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
- /*cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
- Horizontal display enable end
- HDE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x0C) << 6);*/
- HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) -1;
- E = HDE + 1;
+ /* Horizontal total */
+ HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
+ A = HT + 5;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
+ /*
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
- /* Horizontal retrace (=sync) start */
- HRS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0xC0) << 2);
- F = HRS - E - 3;
+ Horizontal display enable end
+ HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
+ */
+ HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
+ E = HDE + 1;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
- /* Horizontal blank start */
- HBS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x30) << 4);
+ /* Horizontal retrace (=sync) start */
+ HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
+ F = HRS - E - 3;
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
+ /* Horizontal blank start */
+ HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
- cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
+ sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
- /* Horizontal blank end */
- HBE = (cr_data & 0x1f) |
- ((unsigned short) (cr_data2 & 0x80) >> 2) |
- ((unsigned short) (sr_data & 0x03) << 6);
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
- /* Horizontal retrace (=sync) end */
- HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
+ cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
- temp = HBE - ((E - 1) & 255);
- B = (temp > 0) ? temp : (temp + 256);
+ /* Horizontal blank end */
+ HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
+ | ((unsigned short) (sr_data & 0x03) << 6);
- temp = HRE - ((E + F + 3) & 63);
- C = (temp > 0) ? temp : (temp + 64);
+ /* Horizontal retrace (=sync) end */
+ HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
- D = B - F - C;
+ temp = HBE - ((E - 1) & 255);
+ B = (temp > 0) ? temp : (temp + 256);
- *left_margin = D * 8;
- *right_margin = F * 8;
- *hsync_len = C * 8;
+ temp = HRE - ((E + F + 3) & 63);
+ C = (temp > 0) ? temp : (temp + 64);
- sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
+ D = B - F - C;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
+ *left_margin = D * 8;
+ *right_margin = F * 8;
+ *hsync_len = C * 8;
- cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
+ sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
- /* Vertical total */
- VT = (cr_data & 0xFF) |
- ((unsigned short) (cr_data2 & 0x01) << 8) |
- ((unsigned short)(cr_data2 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x01) << 10);
- A = VT + 2;
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
- //cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
+ cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
- /* Vertical display enable end */
-/* VDE = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x02) << 7) |
- ((unsigned short) (cr_data2 & 0x40) << 3) |
- ((unsigned short) (sr_data & 0x02) << 9); */
- VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes -1;
- E = VDE + 1;
+ /* Vertical total */
+ VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
+ | ((unsigned short) (cr_data2 & 0x20) << 4)
+ | ((unsigned short) (sr_data & 0x01) << 10);
+ A = VT + 2;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
+ /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
- /* Vertical retrace (=sync) start */
- VRS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x04) << 6) |
- ((unsigned short) (cr_data2 & 0x80) << 2) |
- ((unsigned short) (sr_data & 0x08) << 7);
- F = VRS + 1 - E;
+ /* Vertical display enable end */
+ /*
+ VDE = (cr_data & 0xff) |
+ ((unsigned short) (cr_data2 & 0x02) << 7) |
+ ((unsigned short) (cr_data2 & 0x40) << 3) |
+ ((unsigned short) (sr_data & 0x02) << 9);
+ */
+ VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
+ E = VDE + 1;
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
- cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
+ /* Vertical retrace (=sync) start */
+ VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
+ | ((unsigned short) (cr_data2 & 0x80) << 2)
+ | ((unsigned short) (sr_data & 0x08) << 7);
+ F = VRS + 1 - E;
- /* Vertical blank start */
- VBS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x08) << 5) |
- ((unsigned short) (cr_data3 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x04) << 8);
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
+ cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
- /* Vertical blank end */
- VBE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x10) << 4);
- temp = VBE - ((E - 1) & 511);
- B = (temp > 0) ? temp : (temp + 512);
+ /* Vertical blank start */
+ VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
+ | ((unsigned short) (cr_data3 & 0x20) << 4)
+ | ((unsigned short) (sr_data & 0x04) << 8);
- cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
- /* Vertical retrace (=sync) end */
- VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
- temp = VRE - ((E + F - 1) & 31);
- C = (temp > 0) ? temp : (temp + 32);
+ /* Vertical blank end */
+ VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
+ temp = VBE - ((E - 1) & 511);
+ B = (temp > 0) ? temp : (temp + 512);
- D = B - F - C;
+ cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
- *upper_margin = D;
- *lower_margin = F;
- *vsync_len = C;
+ /* Vertical retrace (=sync) end */
+ VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
+ temp = VRE - ((E + F - 1) & 31);
+ C = (temp > 0) ? temp : (temp + 32);
- if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
- *sync &= ~FB_SYNC_VERT_HIGH_ACT;
- else
- *sync |= FB_SYNC_VERT_HIGH_ACT;
+ D = B - F - C;
- if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
- *sync &= ~FB_SYNC_HOR_HIGH_ACT;
- else
- *sync |= FB_SYNC_HOR_HIGH_ACT;
+ *upper_margin = D;
+ *lower_margin = F;
+ *vsync_len = C;
- *vmode = FB_VMODE_NONINTERLACED;
- if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
- *vmode = FB_VMODE_INTERLACED;
- else {
- j = 0;
- while(XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
- if(XGI_Pr->EModeIDTable[j].Ext_ModeID ==
- XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
- if(XGI_Pr->EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
- *vmode = FB_VMODE_DOUBLE;
- }
- break;
- }
- j++;
- }
- }
-
- return 1;
-}
+ if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
+ *sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ else
+ *sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
+ *sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ else
+ *sync |= FB_SYNC_HOR_HIGH_ACT;
+ *vmode = FB_VMODE_NONINTERLACED;
+ if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
+ *vmode = FB_VMODE_INTERLACED;
+ else {
+ j = 0;
+ while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
+ if (XGI_Pr->EModeIDTable[j].Ext_ModeID
+ == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
+ if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
+ & DoubleScanMode) {
+ *vmode = FB_VMODE_DOUBLE;
+ }
+ break;
+ }
+ j++;
+ }
+ }
+ return 1;
+}
-void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
+static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
{
- XGI_Pr->RelIO = BaseAddr;
- XGI_Pr->P3c4 = BaseAddr + 0x14;
- XGI_Pr->P3d4 = BaseAddr + 0x24;
- XGI_Pr->P3c0 = BaseAddr + 0x10;
- XGI_Pr->P3ce = BaseAddr + 0x1e;
- XGI_Pr->P3c2 = BaseAddr + 0x12;
- XGI_Pr->P3ca = BaseAddr + 0x1a;
- XGI_Pr->P3c6 = BaseAddr + 0x16;
- XGI_Pr->P3c7 = BaseAddr + 0x17;
- XGI_Pr->P3c8 = BaseAddr + 0x18;
- XGI_Pr->P3c9 = BaseAddr + 0x19;
- XGI_Pr->P3da = BaseAddr + 0x2A;
- XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
- XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
- XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
- XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
- XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14+2; /* 301 palette address port registers */
+ XGI_Pr->RelIO = BaseAddr;
+ XGI_Pr->P3c4 = BaseAddr + 0x14;
+ XGI_Pr->P3d4 = BaseAddr + 0x24;
+ XGI_Pr->P3c0 = BaseAddr + 0x10;
+ XGI_Pr->P3ce = BaseAddr + 0x1e;
+ XGI_Pr->P3c2 = BaseAddr + 0x12;
+ XGI_Pr->P3ca = BaseAddr + 0x1a;
+ XGI_Pr->P3c6 = BaseAddr + 0x16;
+ XGI_Pr->P3c7 = BaseAddr + 0x17;
+ XGI_Pr->P3c8 = BaseAddr + 0x18;
+ XGI_Pr->P3c9 = BaseAddr + 0x19;
+ XGI_Pr->P3da = BaseAddr + 0x2A;
+ XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
+ XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
+ XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
+ XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
+ XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
}
-
void XGIfb_set_reg4(u16 port, unsigned long data)
{
- outl((u32) (data & 0xffffffff), port);
+ outl((u32)(data & 0xffffffff), port);
}
u32 XGIfb_get_reg3(u16 port)
@@ -410,14 +397,14 @@ u32 XGIfb_get_reg3(u16 port)
u32 data;
data = inl(port);
- return (data);
+ return data;
}
/* ------------ Interface for init & mode switching code ------------- */
-unsigned char
-XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
- unsigned long offset, unsigned long set, unsigned long *value)
+unsigned char XGIfb_query_VGA_config_space(
+ struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
+ unsigned long set, unsigned long *value)
{
static struct pci_dev *pdev = NULL;
static unsigned char init = 0, valid_pdev = 0;
@@ -429,7 +416,8 @@ XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
if (!init) {
init = 1;
- pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id, pdev);
+ pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
+ pdev);
if (pdev) {
valid_pdev = 1;
pci_dev_put(pdev);
@@ -443,14 +431,15 @@ XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
}
if (set == 0)
- pci_read_config_dword(pdev, offset, (u32 *)value);
+ pci_read_config_dword(pdev, offset, (u32 *) value);
else
pci_write_config_dword(pdev, offset, (u32)(*value));
return 1;
}
-/*unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
+/*
+unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
unsigned long offset, unsigned long set, unsigned long *value)
{
static struct pci_dev *pdev = NULL;
@@ -490,7 +479,7 @@ XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
if (!valid_pdev) {
printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
- nbridge_id);
+ nbridge_id);
return 0;
}
@@ -508,28 +497,29 @@ static void XGIfb_search_mode(const char *name)
{
int i = 0, j = 0, l;
- if(name == NULL) {
- printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
- xgifb_mode_idx = DEFAULT_MODE;
- if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
- {
- xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
- }
- return;
+ if (name == NULL) {
+ printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
+ xgifb_mode_idx = DEFAULT_MODE;
+ if ((xgi_video_info.chip == XG21)
+ && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
+ == DISPTYPE_LCD)) {
+ xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
+ }
+ return;
}
-
- if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
- printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
- xgifb_mode_idx = DEFAULT_MODE;
- if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
- {
- xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
- }
- return;
+ if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
+ printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
+ xgifb_mode_idx = DEFAULT_MODE;
+ if ((xgi_video_info.chip == XG21)
+ && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
+ == DISPTYPE_LCD)) {
+ xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
+ }
+ return;
}
- while(XGIbios_mode[i].mode_no != 0) {
+ while (XGIbios_mode[i].mode_no != 0) {
l = min(strlen(name), strlen(XGIbios_mode[i].name));
if (!strncmp(name, XGIbios_mode[i].name, l)) {
xgifb_mode_idx = i;
@@ -538,83 +528,92 @@ static void XGIfb_search_mode(const char *name)
}
i++;
}
- if(!j) printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
+ if (!j)
+ printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
}
static void XGIfb_search_vesamode(unsigned int vesamode)
{
int i = 0, j = 0;
- if(vesamode == 0) {
+ if (vesamode == 0) {
printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
xgifb_mode_idx = DEFAULT_MODE;
- if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
- {
- xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
+ if ((xgi_video_info.chip == XG21)
+ && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
+ == DISPTYPE_LCD)) {
+ xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
}
return;
}
- vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
+ vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
- while(XGIbios_mode[i].mode_no != 0) {
- if( (XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
- (XGIbios_mode[i].vesa_mode_no_2 == vesamode) ) {
+ while (XGIbios_mode[i].mode_no != 0) {
+ if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
+ || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
xgifb_mode_idx = i;
j = 1;
break;
}
i++;
}
- if(!j) printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
+ if (!j)
+ printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
}
-int XGIfb_GetXG21LVDSData(void)
+static int XGIfb_GetXG21LVDSData(void)
{
- u8 tmp;
- unsigned char *pData;
- int i,j,k;
-
- inXGIIDXREG(XGISR,0x1e,tmp);
- outXGIIDXREG(XGISR, 0x1e, tmp|4);
-
- pData = xgi_video_info.mmio_vbase+0x20000;
- if ((pData[0x0]==0x55) && (pData[0x1]==0xAA) && (pData[0x65] & 0x1))
- {
- i = pData[ 0x316 ] | ( pData[ 0x317 ] << 8 );
- j = pData[ i-1 ] ;
- if ( j == 0xff )
- {
- j = 1;
- }
- k = 0;
- do
- {
- XGI21_LCDCapList[k].LVDS_Capability = pData[ i ] | ( pData[ i + 1 ] << 8 );
- XGI21_LCDCapList[k].LVDSHT = pData[ i + 2 ] | ( pData[ i + 3 ] << 8 ) ;
- XGI21_LCDCapList[k].LVDSVT = pData[ i + 4 ] | ( pData[ i + 5 ] << 8 );
- XGI21_LCDCapList[k].LVDSHDE = pData[ i + 6 ] | ( pData[ i + 7 ] << 8 );
- XGI21_LCDCapList[k].LVDSVDE = pData[ i + 8 ] | ( pData[ i + 9 ] << 8 );
- XGI21_LCDCapList[k].LVDSHFP = pData[ i + 10 ] | ( pData[ i + 11 ] << 8 );
- XGI21_LCDCapList[k].LVDSVFP = pData[ i + 12 ] | ( pData[ i + 13 ] << 8 );
- XGI21_LCDCapList[k].LVDSHSYNC = pData[ i + 14 ] | ( pData[ i + 15 ] << 8 );
- XGI21_LCDCapList[k].LVDSVSYNC = pData[ i + 16 ] | ( pData[ i + 17 ] << 8 );
- XGI21_LCDCapList[k].VCLKData1 = pData[ i + 18 ] ;
- XGI21_LCDCapList[k].VCLKData2 = pData[ i + 19 ] ;
- XGI21_LCDCapList[k].PSC_S1 = pData[ i + 20 ] ;
- XGI21_LCDCapList[k].PSC_S2 = pData[ i + 21 ] ;
- XGI21_LCDCapList[k].PSC_S3 = pData[ i + 22 ] ;
- XGI21_LCDCapList[k].PSC_S4 = pData[ i + 23 ] ;
- XGI21_LCDCapList[k].PSC_S5 = pData[ i + 24 ] ;
- i += 25;
- j--;
- k++;
- } while ((j > 0) &&
- (k < (sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))));
- return 1;
- }
- return 0;
+ u8 tmp;
+ unsigned char *pData;
+ int i, j, k;
+
+ inXGIIDXREG(XGISR, 0x1e, tmp);
+ outXGIIDXREG(XGISR, 0x1e, tmp | 4);
+
+ pData = xgi_video_info.mmio_vbase + 0x20000;
+ if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
+ i = pData[0x316] | (pData[0x317] << 8);
+ j = pData[i - 1];
+ if (j == 0xff)
+ j = 1;
+
+ k = 0;
+ do {
+ XGI21_LCDCapList[k].LVDS_Capability = pData[i]
+ | (pData[i + 1] << 8);
+ XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
+ + 3] << 8);
+ XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
+ + 5] << 8);
+ XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
+ + 7] << 8);
+ XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
+ + 9] << 8);
+ XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
+ + 11] << 8);
+ XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
+ + 13] << 8);
+ XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
+ | (pData[i + 15] << 8);
+ XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
+ | (pData[i + 17] << 8);
+ XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
+ XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
+ XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
+ XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
+ XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
+ XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
+ XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
+ i += 25;
+ j--;
+ k++;
+ } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
+ / sizeof(struct XGI21_LVDSCapStruct))));
+ return 1;
+ }
+ return 0;
}
int XGIfb_GetXG21DefaultLVDSModeIdx(void)
@@ -624,218 +623,257 @@ int XGIfb_GetXG21DefaultLVDSModeIdx(void)
int XGIfb_mode_idx = 0;
found_mode = 0;
- while( (XGIbios_mode[XGIfb_mode_idx].mode_no != 0) &&
- (XGIbios_mode[XGIfb_mode_idx].xres <= XGI21_LCDCapList[0].LVDSHDE) )
- {
- if( (XGIbios_mode[XGIfb_mode_idx].xres == XGI21_LCDCapList[0].LVDSHDE) &&
- (XGIbios_mode[XGIfb_mode_idx].yres == XGI21_LCDCapList[0].LVDSVDE) &&
- (XGIbios_mode[XGIfb_mode_idx].bpp == 8))
- {
+ while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
+ && (XGIbios_mode[XGIfb_mode_idx].xres
+ <= XGI21_LCDCapList[0].LVDSHDE)) {
+ if ((XGIbios_mode[XGIfb_mode_idx].xres
+ == XGI21_LCDCapList[0].LVDSHDE)
+ && (XGIbios_mode[XGIfb_mode_idx].yres
+ == XGI21_LCDCapList[0].LVDSVDE)
+ && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
found_mode = 1;
break;
}
XGIfb_mode_idx++;
}
- if (!found_mode)
- XGIfb_mode_idx = 0;
+ if (!found_mode)
+ XGIfb_mode_idx = 0;
- return (XGIfb_mode_idx);
+ return XGIfb_mode_idx;
}
-
static int XGIfb_validate_mode(int myindex)
{
- u16 xres, yres;
-
- if (xgi_video_info.chip == XG21)
- {
- if ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD)
- {
- xres = XGI21_LCDCapList[0].LVDSHDE;
- yres = XGI21_LCDCapList[0].LVDSVDE;
- if(XGIbios_mode[myindex].xres > xres)
- return(-1);
- if(XGIbios_mode[myindex].yres > yres)
- return(-1);
- if ((XGIbios_mode[myindex].xres < xres) && (XGIbios_mode[myindex].yres < yres) )
- {
- if (XGIbios_mode[myindex].bpp > 8)
- return(-1);
- }
-
- }
- return(myindex);
-
- }
-
- /* FIXME: for now, all is valid on XG27 */
- if (xgi_video_info.chip == XG27)
- return(myindex);
-
- if(!(XGIbios_mode[myindex].chipset & MD_XGI315))
- return(-1);
-
- switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
- case DISPTYPE_LCD:
- switch (XGIhw_ext.ulCRT2LCDType) {
- case LCD_640x480:
- xres = 640; yres = 480; break;
- case LCD_800x600:
- xres = 800; yres = 600; break;
- case LCD_1024x600:
- xres = 1024; yres = 600; break;
- case LCD_1024x768:
- xres = 1024; yres = 768; break;
- case LCD_1152x768:
- xres = 1152; yres = 768; break;
- case LCD_1280x960:
- xres = 1280; yres = 960; break;
- case LCD_1280x768:
- xres = 1280; yres = 768; break;
- case LCD_1280x1024:
- xres = 1280; yres = 1024; break;
- case LCD_1400x1050:
- xres = 1400; yres = 1050; break;
- case LCD_1600x1200:
- xres = 1600; yres = 1200; break;
-// case LCD_320x480: // TW: FSTN
-// xres = 320; yres = 480; break;
- default:
- xres = 0; yres = 0; break;
- }
- if(XGIbios_mode[myindex].xres > xres) {
- return(-1);
- }
- if(XGIbios_mode[myindex].yres > yres) {
- return(-1);
+ u16 xres, yres;
+
+ if (xgi_video_info.chip == XG21) {
+ if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
+ == DISPTYPE_LCD) {
+ xres = XGI21_LCDCapList[0].LVDSHDE;
+ yres = XGI21_LCDCapList[0].LVDSVDE;
+ if (XGIbios_mode[myindex].xres > xres)
+ return -1;
+ if (XGIbios_mode[myindex].yres > yres)
+ return -1;
+ if ((XGIbios_mode[myindex].xres < xres)
+ && (XGIbios_mode[myindex].yres < yres)) {
+ if (XGIbios_mode[myindex].bpp > 8)
+ return -1;
+ }
+
+ }
+ return myindex;
+
}
- if((XGIhw_ext.ulExternalChip == 0x01) || // LVDS
- (XGIhw_ext.ulExternalChip == 0x05)) // LVDS+Chrontel
- {
- switch (XGIbios_mode[myindex].xres) {
- case 512:
- if(XGIbios_mode[myindex].yres != 512) return -1;
- if(XGIhw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
- break;
- case 640:
- if((XGIbios_mode[myindex].yres != 400) &&
- (XGIbios_mode[myindex].yres != 480))
- return -1;
- break;
- case 800:
- if(XGIbios_mode[myindex].yres != 600) return -1;
- break;
- case 1024:
- if((XGIbios_mode[myindex].yres != 600) &&
- (XGIbios_mode[myindex].yres != 768))
- return -1;
- if((XGIbios_mode[myindex].yres == 600) &&
- (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
- return -1;
+
+ /* FIXME: for now, all is valid on XG27 */
+ if (xgi_video_info.chip == XG27)
+ return myindex;
+
+ if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
+ return -1;
+
+ switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
+ case DISPTYPE_LCD:
+ switch (XGIhw_ext.ulCRT2LCDType) {
+ case LCD_640x480:
+ xres = 640;
+ yres = 480;
break;
- case 1152:
- if((XGIbios_mode[myindex].yres) != 768) return -1;
- if(XGIhw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
+ case LCD_800x600:
+ xres = 800;
+ yres = 600;
break;
- case 1280:
- if((XGIbios_mode[myindex].yres != 768) &&
- (XGIbios_mode[myindex].yres != 1024))
- return -1;
- if((XGIbios_mode[myindex].yres == 768) &&
- (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
- return -1;
+ case LCD_1024x600:
+ xres = 1024;
+ yres = 600;
break;
- case 1400:
- if(XGIbios_mode[myindex].yres != 1050) return -1;
+ case LCD_1024x768:
+ xres = 1024;
+ yres = 768;
break;
- case 1600:
- if(XGIbios_mode[myindex].yres != 1200) return -1;
+ case LCD_1152x768:
+ xres = 1152;
+ yres = 768;
break;
- default:
- return -1;
- }
- } else {
- switch (XGIbios_mode[myindex].xres) {
- case 512:
- if(XGIbios_mode[myindex].yres != 512) return -1;
- break;
- case 640:
- if((XGIbios_mode[myindex].yres != 400) &&
- (XGIbios_mode[myindex].yres != 480))
- return -1;
- break;
- case 800:
- if(XGIbios_mode[myindex].yres != 600) return -1;
- break;
- case 1024:
- if(XGIbios_mode[myindex].yres != 768) return -1;
+ case LCD_1280x960:
+ xres = 1280;
+ yres = 960;
break;
- case 1280:
- if((XGIbios_mode[myindex].yres != 960) &&
- (XGIbios_mode[myindex].yres != 1024))
- return -1;
- if(XGIbios_mode[myindex].yres == 960) {
- if(XGIhw_ext.ulCRT2LCDType == LCD_1400x1050)
- return -1;
- }
+ case LCD_1280x768:
+ xres = 1280;
+ yres = 768;
break;
- case 1400:
- if(XGIbios_mode[myindex].yres != 1050) return -1;
+ case LCD_1280x1024:
+ xres = 1280;
+ yres = 1024;
break;
- case 1600:
- if(XGIbios_mode[myindex].yres != 1200) return -1;
+ case LCD_1400x1050:
+ xres = 1400;
+ yres = 1050;
break;
- default:
- return -1;
- }
- }
- break;
- case DISPTYPE_TV:
- switch (XGIbios_mode[myindex].xres) {
- case 512:
- case 640:
- case 800:
- break;
- case 720:
- if (xgi_video_info.TV_type == TVMODE_NTSC) {
- if (XGIbios_mode[myindex].yres != 480) {
- return(-1);
+ case LCD_1600x1200:
+ xres = 1600;
+ yres = 1200;
+ break;
+ /* case LCD_320x480: */ /* TW: FSTN */
+ /*
+ xres = 320;
+ yres = 480;
+ break;
+ */
+ default:
+ xres = 0;
+ yres = 0;
+ break;
+ }
+ if (XGIbios_mode[myindex].xres > xres)
+ return -1;
+ if (XGIbios_mode[myindex].yres > yres)
+ return -1;
+ if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
+ (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ if (XGIbios_mode[myindex].yres != 512)
+ return -1;
+ if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
+ return -1;
+ break;
+ case 640:
+ if ((XGIbios_mode[myindex].yres != 400)
+ && (XGIbios_mode[myindex].yres
+ != 480))
+ return -1;
+ break;
+ case 800:
+ if (XGIbios_mode[myindex].yres != 600)
+ return -1;
+ break;
+ case 1024:
+ if ((XGIbios_mode[myindex].yres != 600)
+ && (XGIbios_mode[myindex].yres
+ != 768))
+ return -1;
+ if ((XGIbios_mode[myindex].yres == 600)
+ && (XGIhw_ext.ulCRT2LCDType
+ != LCD_1024x600))
+ return -1;
+ break;
+ case 1152:
+ if ((XGIbios_mode[myindex].yres) != 768)
+ return -1;
+ if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
+ return -1;
+ break;
+ case 1280:
+ if ((XGIbios_mode[myindex].yres != 768)
+ && (XGIbios_mode[myindex].yres
+ != 1024))
+ return -1;
+ if ((XGIbios_mode[myindex].yres == 768)
+ && (XGIhw_ext.ulCRT2LCDType
+ != LCD_1280x768))
+ return -1;
+ break;
+ case 1400:
+ if (XGIbios_mode[myindex].yres != 1050)
+ return -1;
+ break;
+ case 1600:
+ if (XGIbios_mode[myindex].yres != 1200)
+ return -1;
+ break;
+ default:
+ return -1;
}
- } else if (xgi_video_info.TV_type == TVMODE_PAL) {
- if (XGIbios_mode[myindex].yres != 576) {
- return(-1);
+ } else {
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ if (XGIbios_mode[myindex].yres != 512)
+ return -1;
+ break;
+ case 640:
+ if ((XGIbios_mode[myindex].yres != 400)
+ && (XGIbios_mode[myindex].yres
+ != 480))
+ return -1;
+ break;
+ case 800:
+ if (XGIbios_mode[myindex].yres != 600)
+ return -1;
+ break;
+ case 1024:
+ if (XGIbios_mode[myindex].yres != 768)
+ return -1;
+ break;
+ case 1280:
+ if ((XGIbios_mode[myindex].yres != 960)
+ && (XGIbios_mode[myindex].yres
+ != 1024))
+ return -1;
+ if (XGIbios_mode[myindex].yres == 960) {
+ if (XGIhw_ext.ulCRT2LCDType
+ == LCD_1400x1050)
+ return -1;
+ }
+ break;
+ case 1400:
+ if (XGIbios_mode[myindex].yres != 1050)
+ return -1;
+ break;
+ case 1600:
+ if (XGIbios_mode[myindex].yres != 1200)
+ return -1;
+ break;
+ default:
+ return -1;
}
}
- // TW: LVDS/CHRONTEL does not support 720
- if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
- xgi_video_info.hasVB == HASVB_CHRONTEL) {
- return(-1);
- }
break;
- case 1024:
- if (xgi_video_info.TV_type == TVMODE_NTSC) {
- if(XGIbios_mode[myindex].bpp == 32) {
- return(-1);
+ case DISPTYPE_TV:
+ switch (XGIbios_mode[myindex].xres) {
+ case 512:
+ case 640:
+ case 800:
+ break;
+ case 720:
+ if (xgi_video_info.TV_type == TVMODE_NTSC) {
+ if (XGIbios_mode[myindex].yres != 480)
+ return -1;
+ } else if (xgi_video_info.TV_type == TVMODE_PAL) {
+ if (XGIbios_mode[myindex].yres != 576)
+ return -1;
}
- }
- // TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)
- if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
- xgi_video_info.hasVB == HASVB_CHRONTEL) {
- if(xgi_video_info.chip < XGI_315H) {
- return(-1);
- }
+ /* TW: LVDS/CHRONTEL does not support 720 */
+ if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
+ || xgi_video_info.hasVB == HASVB_CHRONTEL) {
+ return -1;
+ }
+ break;
+ case 1024:
+ if (xgi_video_info.TV_type == TVMODE_NTSC) {
+ if (XGIbios_mode[myindex].bpp == 32)
+ return -1;
+ }
+ /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
+ if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
+ || xgi_video_info.hasVB == HASVB_CHRONTEL) {
+ if (xgi_video_info.chip < XGI_315H)
+ return -1;
+ }
+ break;
+ default:
+ return -1;
}
break;
- default:
- return(-1);
+ case DISPTYPE_CRT2:
+ if (XGIbios_mode[myindex].xres > 1280)
+ return -1;
+ break;
}
- break;
- case DISPTYPE_CRT2:
- if(XGIbios_mode[myindex].xres > 1280) return -1;
- break;
- }
- return(myindex);
+ return myindex;
}
@@ -843,10 +881,10 @@ static void XGIfb_search_crt2type(const char *name)
{
int i = 0;
- if(name == NULL)
+ if (name == NULL)
return;
- while(XGI_crt2type[i].type_no != -1) {
+ while (XGI_crt2type[i].type_no != -1) {
if (!strcmp(name, XGI_crt2type[i].name)) {
XGIfb_crt2type = XGI_crt2type[i].type_no;
XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
@@ -854,7 +892,7 @@ static void XGIfb_search_crt2type(const char *name)
}
i++;
}
- if(XGIfb_crt2type < 0)
+ if (XGIfb_crt2type < 0)
printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
}
@@ -862,7 +900,7 @@ static void XGIfb_search_queuemode(const char *name)
{
int i = 0;
- if(name == NULL)
+ if (name == NULL)
return;
while (XGI_queuemode[i].type_no != -1) {
@@ -886,30 +924,34 @@ static u8 XGIfb_search_refresh_rate(unsigned int rate)
XGIfb_rate_idx = 0;
while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
- if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres == yres)) {
+ if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
+ == yres)) {
if (XGIfb_vrate[i].refresh == rate) {
XGIfb_rate_idx = XGIfb_vrate[i].idx;
break;
} else if (XGIfb_vrate[i].refresh > rate) {
if ((XGIfb_vrate[i].refresh - rate) <= 3) {
DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
- rate, XGIfb_vrate[i].refresh);
+ rate, XGIfb_vrate[i].refresh);
XGIfb_rate_idx = XGIfb_vrate[i].idx;
- xgi_video_info.refresh_rate = XGIfb_vrate[i].refresh;
- } else if (((rate - XGIfb_vrate[i-1].refresh) <= 2)
- && (XGIfb_vrate[i].idx != 1)) {
+ xgi_video_info.refresh_rate
+ = XGIfb_vrate[i].refresh;
+ } else if (((rate - XGIfb_vrate[i - 1].refresh)
+ <= 2) && (XGIfb_vrate[i].idx
+ != 1)) {
DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
- rate, XGIfb_vrate[i-1].refresh);
- XGIfb_rate_idx = XGIfb_vrate[i-1].idx;
- xgi_video_info.refresh_rate = XGIfb_vrate[i-1].refresh;
+ rate, XGIfb_vrate[i-1].refresh);
+ XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
+ xgi_video_info.refresh_rate
+ = XGIfb_vrate[i - 1].refresh;
}
break;
- } else if((rate - XGIfb_vrate[i].refresh) <= 2) {
+ } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
rate, XGIfb_vrate[i].refresh);
- XGIfb_rate_idx = XGIfb_vrate[i].idx;
- break;
- }
+ XGIfb_rate_idx = XGIfb_vrate[i].idx;
+ break;
+ }
}
i++;
}
@@ -917,7 +959,7 @@ static u8 XGIfb_search_refresh_rate(unsigned int rate)
return XGIfb_rate_idx;
} else {
printk(KERN_INFO
- "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
+ "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
return 0;
}
}
@@ -926,7 +968,7 @@ static void XGIfb_search_tvstd(const char *name)
{
int i = 0;
- if(name == NULL)
+ if (name == NULL)
return;
while (XGI_tvtype[i].type_no != -1) {
@@ -940,73 +982,70 @@ static void XGIfb_search_tvstd(const char *name)
static unsigned char XGIfb_bridgeisslave(void)
{
- unsigned char usScratchP1_00;
+ unsigned char usScratchP1_00;
- if (xgi_video_info.hasVB == HASVB_NONE)
- return 0;
+ if (xgi_video_info.hasVB == HASVB_NONE)
+ return 0;
- inXGIIDXREG(XGIPART1,0x00,usScratchP1_00);
- if ((usScratchP1_00 & 0x50) == 0x10)
- return 1;
- else
- return 0;
+ inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
+ if ((usScratchP1_00 & 0x50) == 0x10)
+ return 1;
+ else
+ return 0;
}
static unsigned char XGIfbcheckvretracecrt1(void)
{
- unsigned char temp;
-
- inXGIIDXREG(XGICR,0x17,temp);
- if (!(temp & 0x80))
- return 0;
+ unsigned char temp;
+ inXGIIDXREG(XGICR, 0x17, temp);
+ if (!(temp & 0x80))
+ return 0;
- inXGIIDXREG(XGISR,0x1f,temp);
- if (temp & 0xc0)
- return 0;
+ inXGIIDXREG(XGISR, 0x1f, temp);
+ if (temp & 0xc0)
+ return 0;
- if (inXGIREG(XGIINPSTAT) & 0x08)
- return 1;
- else
- return 0;
+ if (inXGIREG(XGIINPSTAT) & 0x08)
+ return 1;
+ else
+ return 0;
}
static unsigned char XGIfbcheckvretracecrt2(void)
{
- unsigned char temp;
- if (xgi_video_info.hasVB == HASVB_NONE)
- return 0;
- inXGIIDXREG(XGIPART1, 0x30, temp);
- if (temp & 0x02)
- return 0;
- else
- return 1;
+ unsigned char temp;
+ if (xgi_video_info.hasVB == HASVB_NONE)
+ return 0;
+ inXGIIDXREG(XGIPART1, 0x30, temp);
+ if (temp & 0x02)
+ return 0;
+ else
+ return 1;
}
static unsigned char XGIfb_CheckVBRetrace(void)
{
- if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
- if(XGIfb_bridgeisslave()) {
- return(XGIfbcheckvretracecrt1());
- } else {
- return(XGIfbcheckvretracecrt2());
- }
- }
- return(XGIfbcheckvretracecrt1());
+ if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
+ if (XGIfb_bridgeisslave())
+ return XGIfbcheckvretracecrt1();
+ else
+ return XGIfbcheckvretracecrt2();
+ }
+ return XGIfbcheckvretracecrt1();
}
/* ----------- FBDev related routines for all series ----------- */
-
static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
{
- switch(var->bits_per_pixel) {
- case 8:
- var->red.offset = var->green.offset = var->blue.offset = 0;
+ switch (var->bits_per_pixel) {
+ case 8:
+ var->red.offset = var->green.offset = var->blue.offset = 0;
var->red.length = var->green.length = var->blue.length = 6;
xgi_video_info.video_cmap_len = 256;
break;
- case 16:
+ case 16:
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
@@ -1017,7 +1056,7 @@ static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
var->transp.length = 0;
xgi_video_info.video_cmap_len = 16;
break;
- case 32:
+ case 32:
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
@@ -1031,69 +1070,66 @@ static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
}
}
-
-
static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
- struct fb_info *info)
+ struct fb_info *info)
{
- unsigned int htotal = var->left_margin + var->xres +
- var->right_margin + var->hsync_len;
- unsigned int vtotal = var->upper_margin + var->yres +
- var->lower_margin + var->vsync_len;
+ unsigned int htotal = var->left_margin + var->xres + var->right_margin
+ + var->hsync_len;
+ unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
+ + var->vsync_len;
#if defined(__powerpc__)
u8 sr_data, cr_data;
#endif
unsigned int drate = 0, hrate = 0;
int found_mode = 0;
int old_mode;
-// unsigned char reg,reg1;
+ /* unsigned char reg, reg1; */
DEBUGPRN("Inside do_set_var");
-// printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres,var->upper_margin,var->lower_margin,var->vsync_len);
+ /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
- info->var.xres_virtual = var->xres_virtual;
- info->var.yres_virtual = var->yres_virtual;
- info->var.bits_per_pixel = var->bits_per_pixel;
+ info->var.xres_virtual = var->xres_virtual;
+ info->var.yres_virtual = var->yres_virtual;
+ info->var.bits_per_pixel = var->bits_per_pixel;
if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
vtotal <<= 1;
else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
vtotal <<= 2;
- else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
- {
-// vtotal <<= 1;
-// var->yres <<= 1;
+ else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ /* vtotal <<= 1; */
+ /* var->yres <<= 1; */
}
- if(!htotal || !vtotal) {
+ if (!htotal || !vtotal) {
DPRINTK("XGIfb: Invalid 'var' information\n");
return -EINVAL;
- }
- printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
- var->pixclock,htotal,vtotal);
-
+ } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
+ var->pixclock, htotal, vtotal);
-
- if(var->pixclock && htotal && vtotal) {
+ if (var->pixclock && htotal && vtotal) {
drate = 1000000000 / var->pixclock;
hrate = (drate * 1000) / htotal;
- xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
+ / vtotal);
} else {
xgi_video_info.refresh_rate = 60;
}
printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
- var->xres,var->yres,var->bits_per_pixel,xgi_video_info.refresh_rate);
+ var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
old_mode = xgifb_mode_idx;
xgifb_mode_idx = 0;
- while( (XGIbios_mode[xgifb_mode_idx].mode_no != 0) &&
- (XGIbios_mode[xgifb_mode_idx].xres <= var->xres) ) {
- if( (XGIbios_mode[xgifb_mode_idx].xres == var->xres) &&
- (XGIbios_mode[xgifb_mode_idx].yres == var->yres) &&
- (XGIbios_mode[xgifb_mode_idx].bpp == var->bits_per_pixel)) {
+ while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
+ && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
+ if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
+ && (XGIbios_mode[xgifb_mode_idx].yres
+ == var->yres)
+ && (XGIbios_mode[xgifb_mode_idx].bpp
+ == var->bits_per_pixel)) {
XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
found_mode = 1;
break;
@@ -1101,45 +1137,45 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
xgifb_mode_idx++;
}
- if(found_mode)
+ if (found_mode)
xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
else
xgifb_mode_idx = -1;
- if(xgifb_mode_idx < 0) {
+ if (xgifb_mode_idx < 0) {
printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
- var->yres, var->bits_per_pixel);
+ var->yres, var->bits_per_pixel);
xgifb_mode_idx = old_mode;
return -EINVAL;
}
- if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
+ if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
xgi_video_info.refresh_rate = 60;
}
- if(isactive) {
-
+ if (isactive) {
XGIfb_pre_setmode();
- if(XGISetModeNew( &XGIhw_ext, XGIfb_mode_no) == 0) {
+ if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
return -EINVAL;
}
- info->fix.line_length = ((info->var.xres_virtual * info->var.bits_per_pixel)>>6);
+ info->fix.line_length = ((info->var.xres_virtual
+ * info->var.bits_per_pixel) >> 6);
- outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
+ outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
- outXGIIDXREG(XGICR,0x13,(info->fix.line_length & 0x00ff));
- outXGIIDXREG(XGISR,0x0E,(info->fix.line_length & 0xff00)>>8);
+ outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
+ outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
XGIfb_post_setmode();
- DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d \n",
- XGIbios_mode[xgifb_mode_idx].xres,
- XGIbios_mode[xgifb_mode_idx].yres,
- XGIbios_mode[xgifb_mode_idx].bpp,
- xgi_video_info.refresh_rate);
+ DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
+ XGIbios_mode[xgifb_mode_idx].xres,
+ XGIbios_mode[xgifb_mode_idx].yres,
+ XGIbios_mode[xgifb_mode_idx].bpp,
+ xgi_video_info.refresh_rate);
xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
xgi_video_info.video_vwidth = info->var.xres_virtual;
@@ -1147,46 +1183,47 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
xgi_video_info.video_vheight = info->var.yres_virtual;
xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
xgi_video_info.org_x = xgi_video_info.org_y = 0;
- xgi_video_info.video_linelength = info->var.xres_virtual * (xgi_video_info.video_bpp >> 3);
+ xgi_video_info.video_linelength = info->var.xres_virtual
+ * (xgi_video_info.video_bpp >> 3);
xgi_video_info.accel = 0;
- if(XGIfb_accel) {
- xgi_video_info.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
+ if (XGIfb_accel) {
+ xgi_video_info.accel = (var->accel_flags
+ & FB_ACCELF_TEXT) ? -1 : 0;
}
- switch(xgi_video_info.video_bpp)
- {
- case 8:
- xgi_video_info.DstColor = 0x0000;
- xgi_video_info.XGI310_AccelDepth = 0x00000000;
- xgi_video_info.video_cmap_len = 256;
+ switch (xgi_video_info.video_bpp) {
+ case 8:
+ xgi_video_info.DstColor = 0x0000;
+ xgi_video_info.XGI310_AccelDepth = 0x00000000;
+ xgi_video_info.video_cmap_len = 256;
#if defined(__powerpc__)
- inXGIIDXREG (XGICR, 0x4D, cr_data);
- outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
+ inXGIIDXREG(XGICR, 0x4D, cr_data);
+ outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
#endif
- break;
- case 16:
- xgi_video_info.DstColor = 0x8000;
- xgi_video_info.XGI310_AccelDepth = 0x00010000;
+ break;
+ case 16:
+ xgi_video_info.DstColor = 0x8000;
+ xgi_video_info.XGI310_AccelDepth = 0x00010000;
#if defined(__powerpc__)
- inXGIIDXREG (XGICR, 0x4D, cr_data);
- outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
+ inXGIIDXREG(XGICR, 0x4D, cr_data);
+ outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
#endif
- xgi_video_info.video_cmap_len = 16;
- break;
- case 32:
- xgi_video_info.DstColor = 0xC000;
- xgi_video_info.XGI310_AccelDepth = 0x00020000;
- xgi_video_info.video_cmap_len = 16;
+ xgi_video_info.video_cmap_len = 16;
+ break;
+ case 32:
+ xgi_video_info.DstColor = 0xC000;
+ xgi_video_info.XGI310_AccelDepth = 0x00020000;
+ xgi_video_info.video_cmap_len = 16;
#if defined(__powerpc__)
- inXGIIDXREG (XGICR, 0x4D, cr_data);
- outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
+ inXGIIDXREG(XGICR, 0x4D, cr_data);
+ outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
#endif
- break;
- default:
- xgi_video_info.video_cmap_len = 16;
- printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
- xgi_video_info.accel = 0;
- break;
- }
+ break;
+ default:
+ xgi_video_info.video_cmap_len = 16;
+ printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
+ xgi_video_info.accel = 0;
+ break;
+ }
}
XGIfb_bpp_to_var(var); /*update ARGB info*/
DEBUGPRN("End of do_set_var");
@@ -1200,92 +1237,88 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var)
{
unsigned int base;
-// printk("Inside pan_var");
+ /* printk("Inside pan_var"); */
if (var->xoffset > (var->xres_virtual - var->xres)) {
-// printk( "Pan: xo: %d xv %d xr %d\n",
-// var->xoffset, var->xres_virtual, var->xres);
+ /* printk("Pan: xo: %d xv %d xr %d\n",
+ var->xoffset, var->xres_virtual, var->xres); */
return -EINVAL;
}
- if(var->yoffset > (var->yres_virtual - var->yres)) {
-// printk( "Pan: yo: %d yv %d yr %d\n",
-// var->yoffset, var->yres_virtual, var->yres);
+ if (var->yoffset > (var->yres_virtual - var->yres)) {
+ /* printk("Pan: yo: %d yv %d yr %d\n",
+ var->yoffset, var->yres_virtual, var->yres); */
return -EINVAL;
}
- base = var->yoffset * var->xres_virtual + var->xoffset;
+ base = var->yoffset * var->xres_virtual + var->xoffset;
- /* calculate base bpp dep. */
- switch(var->bits_per_pixel) {
- case 16:
- base >>= 1;
- break;
+ /* calculate base bpp dep. */
+ switch (var->bits_per_pixel) {
+ case 16:
+ base >>= 1;
+ break;
case 32:
- break;
+ break;
case 8:
- default:
- base >>= 2;
- break;
- }
+ default:
+ base >>= 2;
+ break;
+ }
outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
- outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
+ outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
- outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
+ outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
- if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
+ if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
- outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
- outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
- outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
+ outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
+ outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
+ outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
- }
-// printk("End of pan_var");
+ }
+ /* printk("End of pan_var"); */
return 0;
}
#endif
-
void XGI_dispinfo(struct ap_data *rec)
{
- rec->minfo.bpp = xgi_video_info.video_bpp;
- rec->minfo.xres = xgi_video_info.video_width;
- rec->minfo.yres = xgi_video_info.video_height;
+ rec->minfo.bpp = xgi_video_info.video_bpp;
+ rec->minfo.xres = xgi_video_info.video_width;
+ rec->minfo.yres = xgi_video_info.video_height;
rec->minfo.v_xres = xgi_video_info.video_vwidth;
rec->minfo.v_yres = xgi_video_info.video_vheight;
- rec->minfo.org_x = xgi_video_info.org_x;
- rec->minfo.org_y = xgi_video_info.org_y;
- rec->minfo.vrate = xgi_video_info.refresh_rate;
- rec->iobase = xgi_video_info.vga_base - 0x30;
- rec->mem_size = xgi_video_info.video_size;
- rec->disp_state = xgi_video_info.disp_state;
- rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
- rec->hasVB = xgi_video_info.hasVB;
- rec->TV_type = xgi_video_info.TV_type;
- rec->TV_plug = xgi_video_info.TV_plug;
- rec->chip = xgi_video_info.chip;
+ rec->minfo.org_x = xgi_video_info.org_x;
+ rec->minfo.org_y = xgi_video_info.org_y;
+ rec->minfo.vrate = xgi_video_info.refresh_rate;
+ rec->iobase = xgi_video_info.vga_base - 0x30;
+ rec->mem_size = xgi_video_info.video_size;
+ rec->disp_state = xgi_video_info.disp_state;
+ rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
+ rec->hasVB = xgi_video_info.hasVB;
+ rec->TV_type = xgi_video_info.TV_type;
+ rec->TV_plug = xgi_video_info.TV_plug;
+ rec->chip = xgi_video_info.chip;
}
-
-
-
static int XGIfb_open(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
static int XGIfb_release(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
{
int rc = 16;
- switch(var->bits_per_pixel) {
+ switch (var->bits_per_pixel) {
case 8:
rc = 256;
break;
@@ -1299,35 +1332,36 @@ static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
return rc;
}
-static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info *info)
+static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info)
{
if (regno >= XGIfb_get_cmap_len(&info->var))
return 1;
switch (info->var.bits_per_pixel) {
case 8:
- outXGIREG(XGIDACA, regno);
+ outXGIREG(XGIDACA, regno);
outXGIREG(XGIDACD, (red >> 10));
outXGIREG(XGIDACD, (green >> 10));
outXGIREG(XGIDACD, (blue >> 10));
if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
- outXGIREG(XGIDAC2A, regno);
+ outXGIREG(XGIDAC2A, regno);
outXGIREG(XGIDAC2D, (red >> 8));
outXGIREG(XGIDAC2D, (green >> 8));
outXGIREG(XGIDAC2D, (blue >> 8));
}
break;
case 16:
- ((u32 *)(info->pseudo_palette))[regno] =
- ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+ ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
+ | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
+ >> 11);
break;
case 32:
red >>= 8;
green >>= 8;
blue >>= 8;
- ((u32 *) (info->pseudo_palette))[regno] =
- (red << 16) | (green << 8) | (blue);
+ ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
+ << 8) | (blue);
break;
}
return 0;
@@ -1337,20 +1371,19 @@ static int XGIfb_set_par(struct fb_info *info)
{
int err;
-// printk("XGIfb: inside set_par\n");
- if((err = XGIfb_do_set_var(&info->var, 1, info)))
+ /* printk("XGIfb: inside set_par\n"); */
+ err = XGIfb_do_set_var(&info->var, 1, info);
+ if (err)
return err;
XGIfb_get_fix(&info->fix, -1, info);
-// printk("XGIfb:end of set_par\n");
+ /* printk("XGIfb: end of set_par\n"); */
return 0;
}
-static int XGIfb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- unsigned int htotal =
- var->left_margin + var->xres + var->right_margin +
- var->hsync_len;
+ unsigned int htotal = var->left_margin + var->xres + var->right_margin
+ + var->hsync_len;
unsigned int vtotal = 0;
unsigned int drate = 0, hrate = 0;
int found_mode = 0;
@@ -1358,90 +1391,91 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var,
DEBUGPRN("Inside check_var");
- if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
- vtotal = var->upper_margin + var->yres + var->lower_margin +
- var->vsync_len;
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+ vtotal = var->upper_margin + var->yres + var->lower_margin
+ + var->vsync_len;
vtotal <<= 1;
- } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- vtotal = var->upper_margin + var->yres + var->lower_margin +
- var->vsync_len;
+ } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ vtotal = var->upper_margin + var->yres + var->lower_margin
+ + var->vsync_len;
vtotal <<= 2;
- } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
- var->vsync_len;
- } else vtotal = var->upper_margin + var->yres + var->lower_margin +
- var->vsync_len;
+ } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ vtotal = var->upper_margin + (var->yres / 2)
+ + var->lower_margin + var->vsync_len;
+ } else
+ vtotal = var->upper_margin + var->yres + var->lower_margin
+ + var->vsync_len;
- if(!(htotal) || !(vtotal)) {
+ if (!(htotal) || !(vtotal))
XGIFAIL("XGIfb: no valid timing data");
- }
-
- if(var->pixclock && htotal && vtotal) {
- drate = 1000000000 / var->pixclock;
- hrate = (drate * 1000) / htotal;
- xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
- printk(KERN_DEBUG \
- "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" \
- "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
- __func__,var->pixclock, htotal, vtotal,
- __func__, drate, hrate, xgi_video_info.refresh_rate);
- } else {
- xgi_video_info.refresh_rate = 60;
- }
+ if (var->pixclock && htotal && vtotal) {
+ drate = 1000000000 / var->pixclock;
+ hrate = (drate * 1000) / htotal;
+ xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ printk(KERN_DEBUG
+ "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
+ "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
+ __func__, var->pixclock, htotal, vtotal,
+ __func__, drate, hrate, xgi_video_info.refresh_rate);
+ } else {
+ xgi_video_info.refresh_rate = 60;
+ }
-/*
- if((var->pixclock) && (htotal)) {
- drate = 1E12 / var->pixclock;
- hrate = drate / htotal;
- refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
- } else refresh_rate = 60;
-*/
+ /*
+ if ((var->pixclock) && (htotal)) {
+ drate = 1E12 / var->pixclock;
+ hrate = drate / htotal;
+ refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+ } else {
+ refresh_rate = 60;
+ }
+ */
/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
- if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
+ if ((var->xres == 1024) && (var->yres == 600))
+ refresh_rate = 60;
search_idx = 0;
- while((XGIbios_mode[search_idx].mode_no != 0) &&
- (XGIbios_mode[search_idx].xres <= var->xres) ) {
- if((XGIbios_mode[search_idx].xres == var->xres) &&
- (XGIbios_mode[search_idx].yres == var->yres) &&
- (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
- if(XGIfb_validate_mode(search_idx) > 0) {
- found_mode = 1;
- break;
- }
- }
+ while ((XGIbios_mode[search_idx].mode_no != 0) &&
+ (XGIbios_mode[search_idx].xres <= var->xres)) {
+ if ((XGIbios_mode[search_idx].xres == var->xres) &&
+ (XGIbios_mode[search_idx].yres == var->yres) &&
+ (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
+ if (XGIfb_validate_mode(search_idx) > 0) {
+ found_mode = 1;
+ break;
+ }
+ }
search_idx++;
}
- if(!found_mode) {
+ if (!found_mode) {
printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
var->xres, var->yres, var->bits_per_pixel);
-
- search_idx = 0;
- while(XGIbios_mode[search_idx].mode_no != 0) {
-
- if( (var->xres <= XGIbios_mode[search_idx].xres) &&
- (var->yres <= XGIbios_mode[search_idx].yres) &&
- (var->bits_per_pixel == XGIbios_mode[search_idx].bpp) ) {
- if(XGIfb_validate_mode(search_idx) > 0) {
- found_mode = 1;
- break;
- }
- }
- search_idx++;
- }
- if(found_mode) {
+ search_idx = 0;
+ while (XGIbios_mode[search_idx].mode_no != 0) {
+
+ if ((var->xres <= XGIbios_mode[search_idx].xres) &&
+ (var->yres <= XGIbios_mode[search_idx].yres) &&
+ (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
+ if (XGIfb_validate_mode(search_idx) > 0) {
+ found_mode = 1;
+ break;
+ }
+ }
+ search_idx++;
+ }
+ if (found_mode) {
var->xres = XGIbios_mode[search_idx].xres;
- var->yres = XGIbios_mode[search_idx].yres;
- printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
- var->xres, var->yres, var->bits_per_pixel);
+ var->yres = XGIbios_mode[search_idx].yres;
+ printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
+ var->xres, var->yres, var->bits_per_pixel);
} else {
- printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
+ printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel);
- return -EINVAL;
+ return -EINVAL;
}
}
@@ -1456,21 +1490,20 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var,
if (var->yoffset < 0)
var->yoffset = 0;
-
- if(!XGIfb_ypan) {
- if(var->xres != var->xres_virtual)
- var->xres_virtual = var->xres;
- if(var->yres != var->yres_virtual)
+ if (!XGIfb_ypan) {
+ if (var->xres != var->xres_virtual)
+ var->xres_virtual = var->xres;
+ if (var->yres != var->yres_virtual)
var->yres_virtual = var->yres;
- }/* else {
- // TW: Now patch yres_virtual if we use panning
- // May I do this?
- var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3));
- if(var->yres_virtual <= var->yres) {
- // TW: Paranoia check
- var->yres_virtual = var->yres;
- }
- }*/
+ } /* else { */
+ /* TW: Now patch yres_virtual if we use panning */
+ /* May I do this? */
+ /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
+ /* if (var->yres_virtual <= var->yres) { */
+ /* TW: Paranoia check */
+ /* var->yres_virtual = var->yres; */
+ /* } */
+ /* } */
/* Truncate offsets to maximum if too high */
if (var->xoffset > var->xres_virtual - var->xres)
@@ -1481,21 +1514,21 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var,
/* Set everything else to 0 */
var->red.msb_right =
- var->green.msb_right =
- var->blue.msb_right =
- var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+ var->green.msb_right =
+ var->blue.msb_right =
+ var->transp.offset = var->transp.length = var->transp.msb_right = 0;
DEBUGPRN("end of check_var");
return 0;
}
#ifdef XGIFB_PAN
-static int XGIfb_pan_display( struct fb_var_screeninfo *var,
- struct fb_info* info)
+static int XGIfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
int err;
-// printk("\nInside pan_display:");
+ /* printk("\nInside pan_display:\n"); */
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
@@ -1503,16 +1536,18 @@ static int XGIfb_pan_display( struct fb_var_screeninfo *var,
return -EINVAL;
if (var->vmode & FB_VMODE_YWRAP) {
- if (var->yoffset < 0
- || var->yoffset >= info->var.yres_virtual
- || var->xoffset) return -EINVAL;
+ if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
+ || var->xoffset)
+ return -EINVAL;
} else {
- if (var->xoffset + info->var.xres > info->var.xres_virtual ||
- var->yoffset + info->var.yres > info->var.yres_virtual)
+ if (var->xoffset + info->var.xres > info->var.xres_virtual
+ || var->yoffset + info->var.yres
+ > info->var.yres_virtual)
return -EINVAL;
}
-
- if((err = XGIfb_pan_var(var)) < 0) return err;
+ err = XGIfb_pan_var(var);
+ if (err < 0)
+ return err;
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
@@ -1521,139 +1556,135 @@ static int XGIfb_pan_display( struct fb_var_screeninfo *var,
else
info->var.vmode &= ~FB_VMODE_YWRAP;
-// printk(" End of pan_display");
+ /* printk("End of pan_display\n"); */
return 0;
}
#endif
-
static int XGIfb_blank(int blank, struct fb_info *info)
{
u8 reg;
inXGIIDXREG(XGICR, 0x17, reg);
- if(blank > 0)
+ if (blank > 0)
reg &= 0x7f;
else
reg |= 0x80;
- outXGIIDXREG(XGICR, 0x17, reg);
- outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
- outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
- return(0);
+ outXGIIDXREG(XGICR, 0x17, reg);
+ outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
+ outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
+ return 0;
}
-
static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
DEBUGPRN("inside ioctl");
switch (cmd) {
- case FBIO_ALLOC:
+ case FBIO_ALLOC:
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
XGI_malloc((struct XGI_memreq *) arg);
break;
- case FBIO_FREE:
+ case FBIO_FREE:
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
XGI_free(*(unsigned long *) arg);
break;
- case FBIOGET_HWCINFO:
- {
- unsigned long *hwc_offset = (unsigned long *) arg;
+ case FBIOGET_HWCINFO: {
+ unsigned long *hwc_offset = (unsigned long *) arg;
- if (XGIfb_caps & HW_CURSOR_CAP)
- *hwc_offset = XGIfb_hwcursor_vbase -
- (unsigned long) xgi_video_info.video_vbase;
- else
- *hwc_offset = 0;
+ if (XGIfb_caps & HW_CURSOR_CAP)
+ *hwc_offset
+ = XGIfb_hwcursor_vbase
+ - (unsigned long) xgi_video_info.video_vbase;
+ else
+ *hwc_offset = 0;
+ break;
+ }
+ case FBIOPUT_MODEINFO: {
+ struct mode_info *x = (struct mode_info *) arg;
+
+ xgi_video_info.video_bpp = x->bpp;
+ xgi_video_info.video_width = x->xres;
+ xgi_video_info.video_height = x->yres;
+ xgi_video_info.video_vwidth = x->v_xres;
+ xgi_video_info.video_vheight = x->v_yres;
+ xgi_video_info.org_x = x->org_x;
+ xgi_video_info.org_y = x->org_y;
+ xgi_video_info.refresh_rate = x->vrate;
+ xgi_video_info.video_linelength = xgi_video_info.video_vwidth
+ * (xgi_video_info.video_bpp >> 3);
+ switch (xgi_video_info.video_bpp) {
+ case 8:
+ xgi_video_info.DstColor = 0x0000;
+ xgi_video_info.XGI310_AccelDepth = 0x00000000;
+ xgi_video_info.video_cmap_len = 256;
break;
- }
- case FBIOPUT_MODEINFO:
- {
- struct mode_info *x = (struct mode_info *)arg;
-
- xgi_video_info.video_bpp = x->bpp;
- xgi_video_info.video_width = x->xres;
- xgi_video_info.video_height = x->yres;
- xgi_video_info.video_vwidth = x->v_xres;
- xgi_video_info.video_vheight = x->v_yres;
- xgi_video_info.org_x = x->org_x;
- xgi_video_info.org_y = x->org_y;
- xgi_video_info.refresh_rate = x->vrate;
- xgi_video_info.video_linelength = xgi_video_info.video_vwidth * (xgi_video_info.video_bpp >> 3);
- switch(xgi_video_info.video_bpp) {
- case 8:
- xgi_video_info.DstColor = 0x0000;
- xgi_video_info.XGI310_AccelDepth = 0x00000000;
- xgi_video_info.video_cmap_len = 256;
- break;
- case 16:
- xgi_video_info.DstColor = 0x8000;
- xgi_video_info.XGI310_AccelDepth = 0x00010000;
- xgi_video_info.video_cmap_len = 16;
- break;
- case 32:
- xgi_video_info.DstColor = 0xC000;
- xgi_video_info.XGI310_AccelDepth = 0x00020000;
- xgi_video_info.video_cmap_len = 16;
- break;
- default:
- xgi_video_info.video_cmap_len = 16;
- printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
- xgi_video_info.accel = 0;
- break;
- }
-
+ case 16:
+ xgi_video_info.DstColor = 0x8000;
+ xgi_video_info.XGI310_AccelDepth = 0x00010000;
+ xgi_video_info.video_cmap_len = 16;
+ break;
+ case 32:
+ xgi_video_info.DstColor = 0xC000;
+ xgi_video_info.XGI310_AccelDepth = 0x00020000;
+ xgi_video_info.video_cmap_len = 16;
+ break;
+ default:
+ xgi_video_info.video_cmap_len = 16;
+ printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
+ xgi_video_info.accel = 0;
break;
}
- case FBIOGET_DISPINFO:
- XGI_dispinfo((struct ap_data *)arg);
+
+ break;
+ }
+ case FBIOGET_DISPINFO:
+ XGI_dispinfo((struct ap_data *) arg);
+ break;
+ case XGIFB_GET_INFO: /* TW: New for communication with X driver */
+ {
+ struct XGIfb_info *x = (struct XGIfb_info *) arg;
+
+ /* x->XGIfb_id = XGIFB_ID; */
+ x->XGIfb_version = VER_MAJOR;
+ x->XGIfb_revision = VER_MINOR;
+ x->XGIfb_patchlevel = VER_LEVEL;
+ x->chip_id = xgi_video_info.chip_id;
+ x->memory = xgi_video_info.video_size / 1024;
+ x->heapstart = xgi_video_info.heapstart / 1024;
+ x->fbvidmode = XGIfb_mode_no;
+ x->XGIfb_caps = XGIfb_caps;
+ x->XGIfb_tqlen = 512; /* yet unused */
+ x->XGIfb_pcibus = xgi_video_info.pcibus;
+ x->XGIfb_pcislot = xgi_video_info.pcislot;
+ x->XGIfb_pcifunc = xgi_video_info.pcifunc;
+ x->XGIfb_lcdpdc = XGIfb_detectedpdc;
+ x->XGIfb_lcda = XGIfb_detectedlcda;
break;
- case XGIFB_GET_INFO: /* TW: New for communication with X driver */
- {
- struct XGIfb_info *x = (struct XGIfb_info *)arg;
-
- //x->XGIfb_id = XGIFB_ID;
- x->XGIfb_version = VER_MAJOR;
- x->XGIfb_revision = VER_MINOR;
- x->XGIfb_patchlevel = VER_LEVEL;
- x->chip_id = xgi_video_info.chip_id;
- x->memory = xgi_video_info.video_size / 1024;
- x->heapstart = xgi_video_info.heapstart / 1024;
- x->fbvidmode = XGIfb_mode_no;
- x->XGIfb_caps = XGIfb_caps;
- x->XGIfb_tqlen = 512; /* yet unused */
- x->XGIfb_pcibus = xgi_video_info.pcibus;
- x->XGIfb_pcislot = xgi_video_info.pcislot;
- x->XGIfb_pcifunc = xgi_video_info.pcifunc;
- x->XGIfb_lcdpdc = XGIfb_detectedpdc;
- x->XGIfb_lcda = XGIfb_detectedlcda;
- break;
- }
- case XGIFB_GET_VBRSTATUS:
- {
- unsigned long *vbrstatus = (unsigned long *) arg;
- if(XGIfb_CheckVBRetrace()) *vbrstatus = 1;
- else *vbrstatus = 0;
- }
- default:
- return -EINVAL;
}
- DEBUGPRN("end of ioctl");
+ case XGIFB_GET_VBRSTATUS: {
+ unsigned long *vbrstatus = (unsigned long *) arg;
+ if (XGIfb_CheckVBRetrace())
+ *vbrstatus = 1;
+ else
+ *vbrstatus = 0;
+ }
+ default:
+ return -EINVAL;
+ } DEBUGPRN("end of ioctl");
return 0;
}
-
-
/* ----------- FBDev related routines for all series ---------- */
static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+ struct fb_info *info)
{
DEBUGPRN("inside get_fix");
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
@@ -1664,175 +1695,168 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
fix->smem_len = xgi_video_info.video_size;
-
-/* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
- if (xgi_video_info.video_size > 0x1000000) {
- fix->smem_len = 0xD00000;
- } else if (xgi_video_info.video_size > 0x800000)
- fix->smem_len = 0x800000;
- else
- fix->smem_len = 0x400000;
- } else
- fix->smem_len = XGIfb_mem * 1024;
-*/
- fix->type = video_type;
- fix->type_aux = 0;
- if(xgi_video_info.video_bpp == 8)
+ /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
+ if (xgi_video_info.video_size > 0x1000000) {
+ fix->smem_len = 0xD00000;
+ } else if (xgi_video_info.video_size > 0x800000)
+ fix->smem_len = 0x800000;
+ else
+ fix->smem_len = 0x400000;
+ } else
+ fix->smem_len = XGIfb_mem * 1024;
+ */
+ fix->type = video_type;
+ fix->type_aux = 0;
+ if (xgi_video_info.video_bpp == 8)
fix->visual = FB_VISUAL_PSEUDOCOLOR;
else
fix->visual = FB_VISUAL_DIRECTCOLOR;
- fix->xpanstep = 0;
+ fix->xpanstep = 0;
#ifdef XGIFB_PAN
- if(XGIfb_ypan) fix->ypanstep = 1;
+ if (XGIfb_ypan)
+ fix->ypanstep = 1;
#endif
- fix->ywrapstep = 0;
+ fix->ywrapstep = 0;
fix->line_length = xgi_video_info.video_linelength;
- fix->mmio_start = xgi_video_info.mmio_base;
- fix->mmio_len = XGIfb_mmio_size;
- if(xgi_video_info.chip >= XG40)
- fix->accel = FB_ACCEL_XGI_XABRE;
+ fix->mmio_start = xgi_video_info.mmio_base;
+ fix->mmio_len = XGIfb_mmio_size;
+ if (xgi_video_info.chip >= XG40)
+ fix->accel = FB_ACCEL_XGI_XABRE;
else
- fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
-
+ fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
DEBUGPRN("end of get_fix");
return 0;
}
-
static struct fb_ops XGIfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = XGIfb_open,
- .fb_release = XGIfb_release,
+ .owner = THIS_MODULE,
+ .fb_open = XGIfb_open,
+ .fb_release = XGIfb_release,
.fb_check_var = XGIfb_check_var,
- .fb_set_par = XGIfb_set_par,
+ .fb_set_par = XGIfb_set_par,
.fb_setcolreg = XGIfb_setcolreg,
#ifdef XGIFB_PAN
- .fb_pan_display = XGIfb_pan_display,
+ .fb_pan_display = XGIfb_pan_display,
#endif
- .fb_blank = XGIfb_blank,
- .fb_fillrect = fbcon_XGI_fillrect,
- .fb_copyarea = fbcon_XGI_copyarea,
+ .fb_blank = XGIfb_blank,
+ .fb_fillrect = fbcon_XGI_fillrect,
+ .fb_copyarea = fbcon_XGI_copyarea,
.fb_imageblit = cfb_imageblit,
- .fb_sync = fbcon_XGI_sync,
- .fb_ioctl = XGIfb_ioctl,
-// .fb_mmap = XGIfb_mmap,
+ .fb_sync = fbcon_XGI_sync,
+ .fb_ioctl = XGIfb_ioctl,
+ /* .fb_mmap = XGIfb_mmap, */
};
/* ---------------- Chip generation dependent routines ---------------- */
-
/* for XGI 315/550/650/740/330 */
static int XGIfb_get_dram_size(void)
{
- u8 ChannelNum,tmp;
- u8 reg = 0;
+ u8 ChannelNum, tmp;
+ u8 reg = 0;
/* xorg driver sets 32MB * 1 channel */
if (xgi_video_info.chip == XG27)
outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
- inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
- switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
- case XGI_DRAM_SIZE_1MB:
- xgi_video_info.video_size = 0x100000;
- break;
- case XGI_DRAM_SIZE_2MB:
- xgi_video_info.video_size = 0x200000;
- break;
- case XGI_DRAM_SIZE_4MB:
- xgi_video_info.video_size = 0x400000;
- break;
- case XGI_DRAM_SIZE_8MB:
- xgi_video_info.video_size = 0x800000;
- break;
- case XGI_DRAM_SIZE_16MB:
- xgi_video_info.video_size = 0x1000000;
- break;
- case XGI_DRAM_SIZE_32MB:
- xgi_video_info.video_size = 0x2000000;
- break;
- case XGI_DRAM_SIZE_64MB:
- xgi_video_info.video_size = 0x4000000;
- break;
- case XGI_DRAM_SIZE_128MB:
- xgi_video_info.video_size = 0x8000000;
- break;
- case XGI_DRAM_SIZE_256MB:
- xgi_video_info.video_size = 0x10000000;
- break;
- default:
- return -1;
- }
+ inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
+ switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
+ case XGI_DRAM_SIZE_1MB:
+ xgi_video_info.video_size = 0x100000;
+ break;
+ case XGI_DRAM_SIZE_2MB:
+ xgi_video_info.video_size = 0x200000;
+ break;
+ case XGI_DRAM_SIZE_4MB:
+ xgi_video_info.video_size = 0x400000;
+ break;
+ case XGI_DRAM_SIZE_8MB:
+ xgi_video_info.video_size = 0x800000;
+ break;
+ case XGI_DRAM_SIZE_16MB:
+ xgi_video_info.video_size = 0x1000000;
+ break;
+ case XGI_DRAM_SIZE_32MB:
+ xgi_video_info.video_size = 0x2000000;
+ break;
+ case XGI_DRAM_SIZE_64MB:
+ xgi_video_info.video_size = 0x4000000;
+ break;
+ case XGI_DRAM_SIZE_128MB:
+ xgi_video_info.video_size = 0x8000000;
+ break;
+ case XGI_DRAM_SIZE_256MB:
+ xgi_video_info.video_size = 0x10000000;
+ break;
+ default:
+ return -1;
+ }
- tmp = (reg & 0x0c) >> 2;
- switch(xgi_video_info.chip)
- {
- case XG20:
- case XG21:
- case XG27:
- ChannelNum = 1;
- break;
-
- case XG42:
- if(reg & 0x04)
- ChannelNum = 2;
- else
- ChannelNum = 1;
- break;
-
- case XG45:
- if(tmp == 1)
- ChannelNum = 2;
- else
- if(tmp == 2)
- ChannelNum = 3;
- else
- if(tmp == 3)
- ChannelNum = 4;
- else
- ChannelNum = 1;
- break;
-
- case XG40:
- default:
- if(tmp == 2)
- ChannelNum = 2;
- else
- if(tmp == 3)
- ChannelNum = 3;
- else
- ChannelNum = 1;
- break;
- }
+ tmp = (reg & 0x0c) >> 2;
+ switch (xgi_video_info.chip) {
+ case XG20:
+ case XG21:
+ case XG27:
+ ChannelNum = 1;
+ break;
+ case XG42:
+ if (reg & 0x04)
+ ChannelNum = 2;
+ else
+ ChannelNum = 1;
+ break;
- xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
- //PLiad fixed for benchmarking and fb set
- //xgi_video_info.video_size = 0x200000;//1024x768x16
- //xgi_video_info.video_size = 0x1000000;//benchmark
+ case XG45:
+ if (tmp == 1)
+ ChannelNum = 2;
+ else if (tmp == 2)
+ ChannelNum = 3;
+ else if (tmp == 3)
+ ChannelNum = 4;
+ else
+ ChannelNum = 1;
+ break;
- printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",reg,xgi_video_info.video_size ,ChannelNum );
- return 0;
+ case XG40:
+ default:
+ if (tmp == 2)
+ ChannelNum = 2;
+ else if (tmp == 3)
+ ChannelNum = 3;
+ else
+ ChannelNum = 1;
+ break;
+ }
+
+ xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
+ /* PLiad fixed for benchmarking and fb set */
+ /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
+ /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
+
+ printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
+ xgi_video_info.video_size, ChannelNum);
+ return 0;
}
static void XGIfb_detect_VB(void)
{
- u8 cr32, temp=0;
+ u8 cr32, temp = 0;
xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
- switch(xgi_video_info.hasVB) {
- case HASVB_LVDS_CHRONTEL:
- case HASVB_CHRONTEL:
- break;
- case HASVB_301:
- case HASVB_302:
-// XGI_Sense30x(); //Yi-Lin TV Sense?
- break;
+ switch (xgi_video_info.hasVB) {
+ case HASVB_LVDS_CHRONTEL:
+ case HASVB_CHRONTEL:
+ break;
+ case HASVB_301:
+ case HASVB_302:
+ /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
+ break;
}
inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
@@ -1858,45 +1882,47 @@ static void XGIfb_detect_VB(void)
else
xgi_video_info.disp_state = 0;
- if(XGIfb_tvplug != -1)
+ if (XGIfb_tvplug != -1)
/* PR/TW: Override with option */
- xgi_video_info.TV_plug = XGIfb_tvplug;
+ xgi_video_info.TV_plug = XGIfb_tvplug;
else if (cr32 & XGI_VB_HIVISION) {
xgi_video_info.TV_type = TVMODE_HIVISION;
xgi_video_info.TV_plug = TVPLUG_SVIDEO;
- }
- else if (cr32 & XGI_VB_SVIDEO)
+ } else if (cr32 & XGI_VB_SVIDEO)
xgi_video_info.TV_plug = TVPLUG_SVIDEO;
else if (cr32 & XGI_VB_COMPOSITE)
xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
else if (cr32 & XGI_VB_SCART)
xgi_video_info.TV_plug = TVPLUG_SCART;
- if(xgi_video_info.TV_type == 0) {
- /* TW: PAL/NTSC changed for 650 */
- if((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip >= XGI_330)) {
+ if (xgi_video_info.TV_type == 0) {
+ /* TW: PAL/NTSC changed for 650 */
+ if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
+ >= XGI_330)) {
- inXGIIDXREG(XGICR, 0x38, temp);
- if(temp & 0x10)
- xgi_video_info.TV_type = TVMODE_PAL;
- else
- xgi_video_info.TV_type = TVMODE_NTSC;
+ inXGIIDXREG(XGICR, 0x38, temp);
+ if (temp & 0x10)
+ xgi_video_info.TV_type = TVMODE_PAL;
+ else
+ xgi_video_info.TV_type = TVMODE_NTSC;
- } else {
+ } else {
- inXGIIDXREG(XGICR, 0x79, temp);
- if(temp & 0x20)
- xgi_video_info.TV_type = TVMODE_PAL;
- else
- xgi_video_info.TV_type = TVMODE_NTSC;
- }
+ inXGIIDXREG(XGICR, 0x79, temp);
+ if (temp & 0x20)
+ xgi_video_info.TV_type = TVMODE_PAL;
+ else
+ xgi_video_info.TV_type = TVMODE_NTSC;
+ }
}
/* TW: Copy forceCRT1 option to CRT1off if option is given */
- if (XGIfb_forcecrt1 != -1) {
- if (XGIfb_forcecrt1) XGIfb_crt1off = 0;
- else XGIfb_crt1off = 1;
- }
+ if (XGIfb_forcecrt1 != -1) {
+ if (XGIfb_forcecrt1)
+ XGIfb_crt1off = 0;
+ else
+ XGIfb_crt1off = 1;
+ }
}
static void XGIfb_get_VB_type(void)
@@ -1904,202 +1930,211 @@ static void XGIfb_get_VB_type(void)
u8 reg;
if (!XGIfb_has_VB()) {
- inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
+ inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
- case XGI310_EXTERNAL_CHIP_LVDS:
+ case XGI310_EXTERNAL_CHIP_LVDS:
xgi_video_info.hasVB = HASVB_LVDS;
break;
- case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+ case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
break;
- default:
+ default:
break;
}
}
}
-
static int XGIfb_has_VB(void)
{
u8 vb_chipid;
inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
switch (vb_chipid) {
- case 0x01:
+ case 0x01:
xgi_video_info.hasVB = HASVB_301;
break;
- case 0x02:
+ case 0x02:
xgi_video_info.hasVB = HASVB_302;
break;
- default:
+ default:
xgi_video_info.hasVB = HASVB_NONE;
return 0;
}
return 1;
}
-
-
/* ------------------ Sensing routines ------------------ */
/* TW: Determine and detect attached devices on XGI30x */
-int
-XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
+int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
{
- int temp,i;
-
- outXGIIDXREG(XGIPART4,0x11,tempbl);
- temp = tempbh | tempcl;
- setXGIIDXREG(XGIPART4,0x10,0xe0,temp);
- for(i=0; i<10; i++) XGI_LongWait(&XGI_Pr);
- tempch &= 0x7f;
- inXGIIDXREG(XGIPART4,0x03,temp);
- temp ^= 0x0e;
- temp &= tempch;
- return(temp);
+ int temp, i;
+
+ outXGIIDXREG(XGIPART4, 0x11, tempbl);
+ temp = tempbh | tempcl;
+ setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
+ for (i = 0; i < 10; i++)
+ XGI_LongWait(&XGI_Pr);
+ tempch &= 0x7f;
+ inXGIIDXREG(XGIPART4, 0x03, temp);
+ temp ^= 0x0e;
+ temp &= tempch;
+ return temp;
}
-void
-XGI_Sense30x(void)
+void XGI_Sense30x(void)
{
- u8 backupP4_0d;
- u8 testsvhs_tempbl, testsvhs_tempbh;
- u8 testsvhs_tempcl, testsvhs_tempch;
- u8 testcvbs_tempbl, testcvbs_tempbh;
- u8 testcvbs_tempcl, testcvbs_tempch;
- u8 testvga2_tempbl, testvga2_tempbh;
- u8 testvga2_tempcl, testvga2_tempch;
- int myflag, result;
-
- inXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
- outXGIIDXREG(XGIPART4,0x0d,(backupP4_0d | 0x04));
-
-
-
- testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
- testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
- testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
- if((XGIhw_ext.ujVBChipID != VB_CHIP_301) &&
- (XGIhw_ext.ujVBChipID != VB_CHIP_302)) {
- testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
- testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
- testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
- if(XGIhw_ext.ujVBChipID == VB_CHIP_301LV ||
- XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
- testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
- testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
- testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
- }
- }
- if(XGIhw_ext.ujVBChipID != VB_CHIP_301LV &&
- XGIhw_ext.ujVBChipID != VB_CHIP_302LV) {
- inXGIIDXREG(XGIPART4,0x01,myflag);
- if(myflag & 0x04) {
- testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
- testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
- testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
- }
- }
- if((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
- (XGIhw_ext.ujVBChipID == VB_CHIP_302LV) ) {
- testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
- testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
- testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
- testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+ u8 backupP4_0d;
+ u8 testsvhs_tempbl, testsvhs_tempbh;
+ u8 testsvhs_tempcl, testsvhs_tempch;
+ u8 testcvbs_tempbl, testcvbs_tempbh;
+ u8 testcvbs_tempcl, testcvbs_tempch;
+ u8 testvga2_tempbl, testvga2_tempbh;
+ u8 testvga2_tempcl, testvga2_tempch;
+ int myflag, result;
+
+ inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
+ outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
+
+ testvga2_tempbh = 0x00;
+ testvga2_tempbl = 0xd1;
+ testsvhs_tempbh = 0x00;
+ testsvhs_tempbl = 0xb9;
+ testcvbs_tempbh = 0x00;
+ testcvbs_tempbl = 0xb3;
+ if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
+ != VB_CHIP_302)) {
+ testvga2_tempbh = 0x01;
+ testvga2_tempbl = 0x90;
+ testsvhs_tempbh = 0x01;
+ testsvhs_tempbl = 0x6b;
+ testcvbs_tempbh = 0x01;
+ testcvbs_tempbl = 0x74;
+ if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
+ || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
+ testvga2_tempbh = 0x00;
+ testvga2_tempbl = 0x00;
+ testsvhs_tempbh = 0x02;
+ testsvhs_tempbl = 0x00;
+ testcvbs_tempbh = 0x01;
+ testcvbs_tempbl = 0x00;
+ }
+ }
+ if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
+ != VB_CHIP_302LV) {
+ inXGIIDXREG(XGIPART4, 0x01, myflag);
+ if (myflag & 0x04) {
+ testvga2_tempbh = 0x00;
+ testvga2_tempbl = 0xfd;
+ testsvhs_tempbh = 0x00;
+ testsvhs_tempbl = 0xdd;
+ testcvbs_tempbh = 0x00;
+ testcvbs_tempbl = 0xee;
+ }
+ }
+ if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
+ == VB_CHIP_302LV)) {
+ testvga2_tempbh = 0x00;
+ testvga2_tempbl = 0x00;
+ testvga2_tempch = 0x00;
+ testvga2_tempcl = 0x00;
+ testsvhs_tempch = 0x04;
+ testsvhs_tempcl = 0x08;
+ testcvbs_tempch = 0x08;
+ testcvbs_tempcl = 0x08;
} else {
- testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
- testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
- testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
- }
-
-
- if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
- result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
- testvga2_tempcl, testvga2_tempch);
- if(result) {
- printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
- orXGIIDXREG(XGICR, 0x32, 0x10);
- }
- }
-
- result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh,
- testsvhs_tempcl, testsvhs_tempch);
- if(result) {
- printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
- /* TW: So we can be sure that there IS a SVHS output */
- xgi_video_info.TV_plug = TVPLUG_SVIDEO;
- orXGIIDXREG(XGICR, 0x32, 0x02);
- }
-
- if(!result) {
- result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
- testcvbs_tempcl, testcvbs_tempch);
- if(result) {
- printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
- /* TW: So we can be sure that there IS a CVBS output */
- xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
- orXGIIDXREG(XGICR, 0x32, 0x01);
- }
- }
- XGIDoSense(0, 0, 0, 0);
-
- outXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
-}
+ testvga2_tempch = 0x0e;
+ testvga2_tempcl = 0x08;
+ testsvhs_tempch = 0x06;
+ testsvhs_tempcl = 0x04;
+ testcvbs_tempch = 0x08;
+ testcvbs_tempcl = 0x04;
+ }
+
+ if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
+ || testvga2_tempbl) {
+ result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
+ testvga2_tempcl, testvga2_tempch);
+ if (result) {
+ printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
+ orXGIIDXREG(XGICR, 0x32, 0x10);
+ }
+ }
+ result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
+ testsvhs_tempch);
+ if (result) {
+ printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
+ /* TW: So we can be sure that there IS a SVHS output */
+ xgi_video_info.TV_plug = TVPLUG_SVIDEO;
+ orXGIIDXREG(XGICR, 0x32, 0x02);
+ }
+ if (!result) {
+ result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
+ testcvbs_tempcl, testcvbs_tempch);
+ if (result) {
+ printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
+ /* TW: So we can be sure that there IS a CVBS output */
+ xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
+ orXGIIDXREG(XGICR, 0x32, 0x01);
+ }
+ }
+ XGIDoSense(0, 0, 0, 0);
+
+ outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
+}
/* ------------------------ Heap routines -------------------------- */
static int XGIfb_heap_init(void)
{
XGI_OH *poh;
- u8 temp=0;
-
- int agp_enabled = 1;
- u32 agp_size;
- unsigned long *cmdq_baseport = 0;
- unsigned long *read_port = 0;
- unsigned long *write_port = 0;
- XGI_CMDTYPE cmd_type;
+ u8 temp = 0;
+
+ int agp_enabled = 1;
+ u32 agp_size;
+ unsigned long *cmdq_baseport = NULL;
+ unsigned long *read_port = NULL;
+ unsigned long *write_port = NULL;
+ XGI_CMDTYPE cmd_type;
#ifndef AGPOFF
- struct agp_kern_info *agp_info;
- struct agp_memory *agp;
- u32 agp_phys;
+ struct agp_kern_info *agp_info;
+ struct agp_memory *agp;
+ u32 agp_phys;
#endif
-/* TW: The heap start is either set manually using the "mem" parameter, or
- * defaults as follows:
- * -) If more than 16MB videoRAM available, let our heap start at 12MB.
- * -) If more than 8MB videoRAM available, let our heap start at 8MB.
- * -) If 4MB or less is available, let it start at 4MB.
- * This is for avoiding a clash with X driver which uses the beginning
- * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
- * in XF86Config-4.
- * The heap start can also be specified by parameter "mem" when starting the XGIfb
- * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
- */
- if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
- if (xgi_video_info.video_size > 0x1000000) {
- xgi_video_info.heapstart = 0xD00000;
- } else if (xgi_video_info.video_size > 0x800000) {
- xgi_video_info.heapstart = 0x800000;
+ /* TW: The heap start is either set manually using the "mem" parameter, or
+ * defaults as follows:
+ * -) If more than 16MB videoRAM available, let our heap start at 12MB.
+ * -) If more than 8MB videoRAM available, let our heap start at 8MB.
+ * -) If 4MB or less is available, let it start at 4MB.
+ * This is for avoiding a clash with X driver which uses the beginning
+ * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
+ * in XF86Config-4.
+ * The heap start can also be specified by parameter "mem" when starting the XGIfb
+ * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
+ */
+ if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
+ if (xgi_video_info.video_size > 0x1000000)
+ xgi_video_info.heapstart = 0xD00000;
+ else if (xgi_video_info.video_size > 0x800000)
+ xgi_video_info.heapstart = 0x800000;
+ else
+ xgi_video_info.heapstart = 0x400000;
} else {
- xgi_video_info.heapstart = 0x400000;
+ xgi_video_info.heapstart = XGIfb_mem * 1024;
}
- } else {
- xgi_video_info.heapstart = XGIfb_mem * 1024;
- }
- XGIfb_heap_start =
- (unsigned long) (xgi_video_info.video_vbase + xgi_video_info.heapstart);
- printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
- (int)(xgi_video_info.heapstart / 1024));
+ XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
+ + xgi_video_info.heapstart);
+ printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
+ (int)(xgi_video_info.heapstart / 1024));
- XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase + xgi_video_info.video_size;
- XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
+ XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
+ + xgi_video_info.video_size;
+ XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
-
-
- /* TW: Now initialize the 310 series' command queue mode.
+ /* TW: Now initialize the 310 series' command queue mode.
* On 310/325, there are three queue modes available which
* are chosen by setting bits 7:5 in SR26:
* 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
@@ -2129,25 +2164,28 @@ static int XGIfb_heap_init(void)
* 11 (0x0C) 4M
* The queue location is to be written to 0x85C0.
*
- */
- cmdq_baseport = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_PHYBASE);
- write_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_WRITEPORT);
- read_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_READPORT);
+ */
+ cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
+ + MMIO_QUEUE_PHYBASE);
+ write_port = (unsigned long *) (xgi_video_info.mmio_vbase
+ + MMIO_QUEUE_WRITEPORT);
+ read_port = (unsigned long *) (xgi_video_info.mmio_vbase
+ + MMIO_QUEUE_READPORT);
DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
- agp_size = COMMAND_QUEUE_AREA_SIZE;
+ agp_size = COMMAND_QUEUE_AREA_SIZE;
#ifndef AGPOFF
if (XGIfb_queuemode == AGP_CMD_QUEUE) {
agp_info = vmalloc(sizeof(*agp_info));
- memset((void*)agp_info, 0x00, sizeof(*agp_info));
+ memset((void *)agp_info, 0x00, sizeof(*agp_info));
agp_copy_info(agp_info);
agp_backend_acquire();
- agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
- AGP_NORMAL_MEMORY);
+ agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
+ AGP_NORMAL_MEMORY);
if (agp == NULL) {
DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
agp_enabled = 0;
@@ -2170,8 +2208,8 @@ static int XGIfb_heap_init(void)
if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
cmd_type = AGP_CMD_QUEUE;
printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
-/* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
- } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
+ /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
+ } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
cmd_type = VM_CMD_QUEUE;
printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
} else {
@@ -2180,32 +2218,32 @@ static int XGIfb_heap_init(void)
}
switch (agp_size) {
- case 0x80000:
+ case 0x80000:
temp = XGI_CMD_QUEUE_SIZE_512k;
break;
- case 0x100000:
+ case 0x100000:
temp = XGI_CMD_QUEUE_SIZE_1M;
break;
- case 0x200000:
+ case 0x200000:
temp = XGI_CMD_QUEUE_SIZE_2M;
break;
- case 0x400000:
+ case 0x400000:
temp = XGI_CMD_QUEUE_SIZE_4M;
break;
}
switch (cmd_type) {
- case AGP_CMD_QUEUE:
+ case AGP_CMD_QUEUE:
#ifndef AGPOFF
DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
agp_info->aper_base, agp->physical, agp_size/1024);
agp_phys = agp_info->aper_base + agp->physical;
- outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
- outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
+ outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
+ outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
- outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+ outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
@@ -2220,7 +2258,7 @@ static int XGIfb_heap_init(void)
#endif
break;
- case VM_CMD_QUEUE:
+ case VM_CMD_QUEUE:
XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
@@ -2241,40 +2279,37 @@ static int XGIfb_heap_init(void)
*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
break;
- default: /* MMIO */
+ default: /* MMIO */
-// printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__);
- /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
+ /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
+ /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
* to IND_XGI_CMDQUEUE_SET. I doubt that this is
* enough. Reserve memory in any way.
*/
-// FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
-// FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
-// FIXME
-// FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
-// FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
-// FIXME
-// FIXME *write_port = *read_port;
-// FIXME
-// FIXME /* TW: Set Auto_Correction bit */
-// FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR);
-// FIXME // FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
-// FIXME
-// FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
-// FIXME
-// FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP;
-// FIXME
-// FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
-// FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
- break;
- }
-
-
-
+ /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
+ /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
+ /* FIXME */
+ /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
+ /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
+ /* FIXME */
+ /* FIXME *write_port = *read_port; */
+ /* FIXME */
+ /* FIXME *//* TW: Set Auto_Correction bit */
+ /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
+ /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
+ /* FIXME */
+ /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
+ /* FIXME */
+ /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
+ /* FIXME */
+ /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
+ /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
+ break;
+}
- /* TW: Now reserve memory for the HWCursor. It is always located at the very
- top of the videoRAM, right below the TB memory area (if used). */
- if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
+ /* TW: Now reserve memory for the HWCursor. It is always located at the very
+ top of the videoRAM, right below the TB memory area (if used). */
+ if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
XGIfb_heap_end -= XGIfb_hwcursor_size;
XGIfb_heap_size -= XGIfb_hwcursor_size;
XGIfb_hwcursor_vbase = XGIfb_heap_end;
@@ -2282,55 +2317,58 @@ static int XGIfb_heap_init(void)
XGIfb_caps |= HW_CURSOR_CAP;
DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
- XGIfb_heap_end, XGIfb_hwcursor_size/1024);
- }
+ XGIfb_heap_end, XGIfb_hwcursor_size/1024);
+ }
- XGIfb_heap.poha_chain = NULL;
- XGIfb_heap.poh_freelist = NULL;
+ XGIfb_heap.poha_chain = NULL;
+ XGIfb_heap.poh_freelist = NULL;
- poh = XGIfb_poh_new_node();
+ poh = XGIfb_poh_new_node();
- if(poh == NULL) return 1;
+ if (poh == NULL)
+ return 1;
- poh->poh_next = &XGIfb_heap.oh_free;
- poh->poh_prev = &XGIfb_heap.oh_free;
- poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
- poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
+ poh->poh_next = &XGIfb_heap.oh_free;
+ poh->poh_prev = &XGIfb_heap.oh_free;
+ poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
+ poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
- DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
+ DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
(char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
(unsigned int) poh->size / 1024);
- DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
+ DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
(unsigned int) poh->offset, (unsigned int) poh->size / 1024);
- XGIfb_heap.oh_free.poh_next = poh;
- XGIfb_heap.oh_free.poh_prev = poh;
- XGIfb_heap.oh_free.size = 0;
- XGIfb_heap.max_freesize = poh->size;
+ XGIfb_heap.oh_free.poh_next = poh;
+ XGIfb_heap.oh_free.poh_prev = poh;
+ XGIfb_heap.oh_free.size = 0;
+ XGIfb_heap.max_freesize = poh->size;
- XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
- XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
- XGIfb_heap.oh_used.size = SENTINEL;
+ XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
+ XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
+ XGIfb_heap.oh_used.size = SENTINEL;
- return 0;
+ return 0;
}
static XGI_OH *XGIfb_poh_new_node(void)
{
- int i;
+ int i;
unsigned long cOhs;
- XGI_OHALLOC *poha;
- XGI_OH *poh;
+ XGI_OHALLOC *poha;
+ XGI_OH *poh;
if (XGIfb_heap.poh_freelist == NULL) {
poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
- if(!poha) return NULL;
+ if (!poha)
+ return NULL;
poha->poha_next = XGIfb_heap.poha_chain;
XGIfb_heap.poha_chain = poha;
- cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH) + 1;
+ cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
+ + 1;
poh = &poha->aoh[0];
for (i = cOhs - 1; i != 0; i--) {
@@ -2345,19 +2383,19 @@ static XGI_OH *XGIfb_poh_new_node(void)
poh = XGIfb_heap.poh_freelist;
XGIfb_heap.poh_freelist = poh->poh_next;
- return (poh);
+ return poh;
}
static XGI_OH *XGIfb_poh_allocate(unsigned long size)
{
XGI_OH *pohThis;
XGI_OH *pohRoot;
- int bAllocated = 0;
+ int bAllocated = 0;
if (size > XGIfb_heap.max_freesize) {
DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
- (unsigned int) size / 1024);
- return (NULL);
+ (unsigned int) size / 1024);
+ return NULL;
}
pohThis = XGIfb_heap.oh_free.poh_next;
@@ -2372,8 +2410,8 @@ static XGI_OH *XGIfb_poh_allocate(unsigned long size)
if (!bAllocated) {
DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
- (unsigned int) size / 1024);
- return (NULL);
+ (unsigned int) size / 1024);
+ return NULL;
}
if (size == pohThis->size) {
@@ -2382,9 +2420,8 @@ static XGI_OH *XGIfb_poh_allocate(unsigned long size)
} else {
pohRoot = XGIfb_poh_new_node();
- if (pohRoot == NULL) {
- return (NULL);
- }
+ if (pohRoot == NULL)
+ return NULL;
pohRoot->offset = pohThis->offset;
pohRoot->size = size;
@@ -2398,7 +2435,7 @@ static XGI_OH *XGIfb_poh_allocate(unsigned long size)
pohThis = &XGIfb_heap.oh_used;
XGIfb_insert_node(pohThis, pohRoot);
- return (pohRoot);
+ return pohRoot;
}
static void XGIfb_delete_node(XGI_OH *poh)
@@ -2439,8 +2476,8 @@ static XGI_OH *XGIfb_poh_free(unsigned long base)
poh_freed = XGIfb_heap.oh_used.poh_next;
- while(poh_freed != &XGIfb_heap.oh_used) {
- if(poh_freed->offset == base) {
+ while (poh_freed != &XGIfb_heap.oh_used) {
+ if (poh_freed->offset == base) {
foundNode = 1;
break;
}
@@ -2448,7 +2485,8 @@ static XGI_OH *XGIfb_poh_free(unsigned long base)
poh_freed = poh_freed->poh_next;
}
- if (!foundNode) return (NULL);
+ if (!foundNode)
+ return NULL;
XGIfb_heap.max_freesize += poh_freed->size;
@@ -2459,13 +2497,11 @@ static XGI_OH *XGIfb_poh_free(unsigned long base)
pohThis = XGIfb_heap.oh_free.poh_next;
while (pohThis != &XGIfb_heap.oh_free) {
- if (pohThis->offset == ulUpper) {
+ if (pohThis->offset == ulUpper)
poh_next = pohThis;
- }
- else if ((pohThis->offset + pohThis->size) ==
- ulLower) {
+ else if ((pohThis->offset + pohThis->size) == ulLower)
poh_prev = pohThis;
- }
+
pohThis = pohThis->poh_next;
}
@@ -2476,30 +2512,31 @@ static XGI_OH *XGIfb_poh_free(unsigned long base)
XGIfb_delete_node(poh_next);
XGIfb_free_node(poh_freed);
XGIfb_free_node(poh_next);
- return (poh_prev);
+ return poh_prev;
}
if (poh_prev) {
poh_prev->size += poh_freed->size;
XGIfb_free_node(poh_freed);
- return (poh_prev);
+ return poh_prev;
}
if (poh_next) {
poh_next->size += poh_freed->size;
poh_next->offset = poh_freed->offset;
XGIfb_free_node(poh_freed);
- return (poh_next);
+ return poh_next;
}
XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
- return (poh_freed);
+ return poh_freed;
}
static void XGIfb_free_node(XGI_OH *poh)
{
- if(poh == NULL) return;
+ if (poh == NULL)
+ return;
poh->poh_next = XGIfb_heap.poh_freelist;
XGIfb_heap.poh_freelist = poh;
@@ -2512,13 +2549,13 @@ void XGI_malloc(struct XGI_memreq *req)
poh = XGIfb_poh_allocate(req->size);
- if(poh == NULL) {
+ if (poh == NULL) {
req->offset = 0;
req->size = 0;
DPRINTK("XGIfb: Video RAM allocation failed\n");
} else {
DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
- (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
+ (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
req->offset = poh->offset;
req->size = poh->size;
@@ -2532,9 +2569,9 @@ void XGI_free(unsigned long base)
poh = XGIfb_poh_free(base);
- if(poh == NULL) {
+ if (poh == NULL) {
DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
- (unsigned int) base);
+ (unsigned int) base);
}
}
@@ -2548,41 +2585,45 @@ static void XGIfb_pre_setmode(void)
cr31 &= ~0x60;
switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
- case DISPTYPE_CRT2:
+ case DISPTYPE_CRT2:
cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
cr31 |= XGI_DRIVER_MODE;
break;
- case DISPTYPE_LCD:
- cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
+ case DISPTYPE_LCD:
+ cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
cr31 |= XGI_DRIVER_MODE;
break;
- case DISPTYPE_TV:
+ case DISPTYPE_TV:
if (xgi_video_info.TV_type == TVMODE_HIVISION)
- cr30 = (XGI_VB_OUTPUT_HIVISION | XGI_SIMULTANEOUS_VIEW_ENABLE);
+ cr30 = (XGI_VB_OUTPUT_HIVISION
+ | XGI_SIMULTANEOUS_VIEW_ENABLE);
else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
- cr30 = (XGI_VB_OUTPUT_SVIDEO | XGI_SIMULTANEOUS_VIEW_ENABLE);
+ cr30 = (XGI_VB_OUTPUT_SVIDEO
+ | XGI_SIMULTANEOUS_VIEW_ENABLE);
else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
- cr30 = (XGI_VB_OUTPUT_COMPOSITE | XGI_SIMULTANEOUS_VIEW_ENABLE);
+ cr30 = (XGI_VB_OUTPUT_COMPOSITE
+ | XGI_SIMULTANEOUS_VIEW_ENABLE);
else if (xgi_video_info.TV_plug == TVPLUG_SCART)
- cr30 = (XGI_VB_OUTPUT_SCART | XGI_SIMULTANEOUS_VIEW_ENABLE);
+ cr30 = (XGI_VB_OUTPUT_SCART
+ | XGI_SIMULTANEOUS_VIEW_ENABLE);
cr31 |= XGI_DRIVER_MODE;
- if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
+ if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
cr31 |= 0x01;
- else
- cr31 &= ~0x01;
+ else
+ cr31 &= ~0x01;
break;
- default: /* disable CRT2 */
+ default: /* disable CRT2 */
cr30 = 0x00;
cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
}
outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
- outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
-
- if(xgi_video_info.accel) XGIfb_syncaccel();
+ outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
+ if (xgi_video_info.accel)
+ XGIfb_syncaccel();
}
@@ -2590,32 +2631,33 @@ static void XGIfb_post_setmode(void)
{
u8 reg;
unsigned char doit = 1;
-/* outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
- outXGIIDXREG(XGICR,0x13,0x00);
- setXGIIDXREG(XGISR,0x0E,0xF0,0x01);
-*test**/
+ /*
+ outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
+ outXGIIDXREG(XGICR, 0x13, 0x00);
+ setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
+ *test*
+ */
if (xgi_video_info.video_bpp == 8) {
/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
- if ((xgi_video_info.hasVB == HASVB_LVDS) || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
+ if ((xgi_video_info.hasVB == HASVB_LVDS)
+ || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
doit = 0;
}
/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
- if (xgi_video_info.disp_state & DISPTYPE_LCD) {
+ if (xgi_video_info.disp_state & DISPTYPE_LCD)
doit = 0;
- }
}
/* TW: We can't switch off CRT1 if bridge is in slave mode */
- if(xgi_video_info.hasVB != HASVB_NONE) {
+ if (xgi_video_info.hasVB != HASVB_NONE) {
inXGIIDXREG(XGIPART1, 0x00, reg);
-
if ((reg & 0x50) == 0x10)
doit = 0;
-
- } else
+ } else {
XGIfb_crt1off = 0;
+ }
inXGIIDXREG(XGICR, 0x17, reg);
if ((XGIfb_crt1off) && (doit))
@@ -2624,139 +2666,152 @@ static void XGIfb_post_setmode(void)
reg |= 0x80;
outXGIIDXREG(XGICR, 0x17, reg);
- andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
-
- if((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB == HASVB_301)) {
-
- inXGIIDXREG(XGIPART4, 0x01, reg);
-
- if(reg < 0xB0) { /* Set filter for XGI301 */
-
- switch (xgi_video_info.video_width) {
- case 320:
- filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
- break;
- case 640:
- filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
- break;
- case 720:
- filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
- break;
- case 800:
- filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
- break;
- default:
- filter = -1;
- break;
- }
-
- orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
-
- if(xgi_video_info.TV_type == TVMODE_NTSC) {
+ andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
- andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
+ if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
+ == HASVB_301)) {
- if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
+ inXGIIDXREG(XGIPART4, 0x01, reg);
- andXGIIDXREG(XGIPART2, 0x30, 0xdf);
+ if (reg < 0xB0) { /* Set filter for XGI301 */
- } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
+ switch (xgi_video_info.video_width) {
+ case 320:
+ filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
+ break;
+ case 640:
+ filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
+ break;
+ case 720:
+ filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
+ break;
+ case 800:
+ filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
+ break;
+ default:
+ filter = -1;
+ break;
+ }
- orXGIIDXREG(XGIPART2, 0x30, 0x20);
+ orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
+
+ if (xgi_video_info.TV_type == TVMODE_NTSC) {
+
+ andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
+
+ if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
+
+ andXGIIDXREG(XGIPART2, 0x30, 0xdf);
+
+ } else if (xgi_video_info.TV_plug
+ == TVPLUG_COMPOSITE) {
+
+ orXGIIDXREG(XGIPART2, 0x30, 0x20);
+
+ switch (xgi_video_info.video_width) {
+ case 640:
+ outXGIIDXREG(XGIPART2, 0x35, 0xEB);
+ outXGIIDXREG(XGIPART2, 0x36, 0x04);
+ outXGIIDXREG(XGIPART2, 0x37, 0x25);
+ outXGIIDXREG(XGIPART2, 0x38, 0x18);
+ break;
+ case 720:
+ outXGIIDXREG(XGIPART2, 0x35, 0xEE);
+ outXGIIDXREG(XGIPART2, 0x36, 0x0C);
+ outXGIIDXREG(XGIPART2, 0x37, 0x22);
+ outXGIIDXREG(XGIPART2, 0x38, 0x08);
+ break;
+ case 800:
+ outXGIIDXREG(XGIPART2, 0x35, 0xEB);
+ outXGIIDXREG(XGIPART2, 0x36, 0x15);
+ outXGIIDXREG(XGIPART2, 0x37, 0x25);
+ outXGIIDXREG(XGIPART2, 0x38, 0xF6);
+ break;
+ }
+ }
- switch (xgi_video_info.video_width) {
- case 640:
- outXGIIDXREG(XGIPART2, 0x35, 0xEB);
- outXGIIDXREG(XGIPART2, 0x36, 0x04);
- outXGIIDXREG(XGIPART2, 0x37, 0x25);
- outXGIIDXREG(XGIPART2, 0x38, 0x18);
- break;
- case 720:
- outXGIIDXREG(XGIPART2, 0x35, 0xEE);
- outXGIIDXREG(XGIPART2, 0x36, 0x0C);
- outXGIIDXREG(XGIPART2, 0x37, 0x22);
- outXGIIDXREG(XGIPART2, 0x38, 0x08);
- break;
- case 800:
- outXGIIDXREG(XGIPART2, 0x35, 0xEB);
- outXGIIDXREG(XGIPART2, 0x36, 0x15);
- outXGIIDXREG(XGIPART2, 0x37, 0x25);
- outXGIIDXREG(XGIPART2, 0x38, 0xF6);
- break;
+ } else if (xgi_video_info.TV_type == TVMODE_PAL) {
+
+ andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
+
+ if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
+
+ andXGIIDXREG(XGIPART2, 0x30, 0xDF);
+
+ } else if (xgi_video_info.TV_plug
+ == TVPLUG_COMPOSITE) {
+
+ orXGIIDXREG(XGIPART2, 0x30, 0x20);
+
+ switch (xgi_video_info.video_width) {
+ case 640:
+ outXGIIDXREG(XGIPART2, 0x35, 0xF1);
+ outXGIIDXREG(XGIPART2, 0x36, 0xF7);
+ outXGIIDXREG(XGIPART2, 0x37, 0x1F);
+ outXGIIDXREG(XGIPART2, 0x38, 0x32);
+ break;
+ case 720:
+ outXGIIDXREG(XGIPART2, 0x35, 0xF3);
+ outXGIIDXREG(XGIPART2, 0x36, 0x00);
+ outXGIIDXREG(XGIPART2, 0x37, 0x1D);
+ outXGIIDXREG(XGIPART2, 0x38, 0x20);
+ break;
+ case 800:
+ outXGIIDXREG(XGIPART2, 0x35, 0xFC);
+ outXGIIDXREG(XGIPART2, 0x36, 0xFB);
+ outXGIIDXREG(XGIPART2, 0x37, 0x14);
+ outXGIIDXREG(XGIPART2, 0x38, 0x2A);
+ break;
+ }
}
}
- } else if(xgi_video_info.TV_type == TVMODE_PAL) {
-
- andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
-
- if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
-
- andXGIIDXREG(XGIPART2, 0x30, 0xDF);
-
- } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
-
- orXGIIDXREG(XGIPART2, 0x30, 0x20);
-
- switch (xgi_video_info.video_width) {
- case 640:
- outXGIIDXREG(XGIPART2, 0x35, 0xF1);
- outXGIIDXREG(XGIPART2, 0x36, 0xF7);
- outXGIIDXREG(XGIPART2, 0x37, 0x1F);
- outXGIIDXREG(XGIPART2, 0x38, 0x32);
- break;
- case 720:
- outXGIIDXREG(XGIPART2, 0x35, 0xF3);
- outXGIIDXREG(XGIPART2, 0x36, 0x00);
- outXGIIDXREG(XGIPART2, 0x37, 0x1D);
- outXGIIDXREG(XGIPART2, 0x38, 0x20);
- break;
- case 800:
- outXGIIDXREG(XGIPART2, 0x35, 0xFC);
- outXGIIDXREG(XGIPART2, 0x36, 0xFB);
- outXGIIDXREG(XGIPART2, 0x37, 0x14);
- outXGIIDXREG(XGIPART2, 0x38, 0x2A);
- break;
- }
+ if ((filter >= 0) && (filter <= 7)) {
+ DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
+ XGI_TV_filter[filter_tb].filter[filter][0],
+ XGI_TV_filter[filter_tb].filter[filter][1],
+ XGI_TV_filter[filter_tb].filter[filter][2],
+ XGI_TV_filter[filter_tb].filter[filter][3]
+ );
+ outXGIIDXREG(
+ XGIPART2,
+ 0x35,
+ (XGI_TV_filter[filter_tb].filter[filter][0]));
+ outXGIIDXREG(
+ XGIPART2,
+ 0x36,
+ (XGI_TV_filter[filter_tb].filter[filter][1]));
+ outXGIIDXREG(
+ XGIPART2,
+ 0x37,
+ (XGI_TV_filter[filter_tb].filter[filter][2]));
+ outXGIIDXREG(
+ XGIPART2,
+ 0x38,
+ (XGI_TV_filter[filter_tb].filter[filter][3]));
}
- }
- if ((filter >= 0) && (filter <=7)) {
- DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
- XGI_TV_filter[filter_tb].filter[filter][0],
- XGI_TV_filter[filter_tb].filter[filter][1],
- XGI_TV_filter[filter_tb].filter[filter][2],
- XGI_TV_filter[filter_tb].filter[filter][3]
- );
- outXGIIDXREG(XGIPART2, 0x35, (XGI_TV_filter[filter_tb].filter[filter][0]));
- outXGIIDXREG(XGIPART2, 0x36, (XGI_TV_filter[filter_tb].filter[filter][1]));
- outXGIIDXREG(XGIPART2, 0x37, (XGI_TV_filter[filter_tb].filter[filter][2]));
- outXGIIDXREG(XGIPART2, 0x38, (XGI_TV_filter[filter_tb].filter[filter][3]));
}
- }
-
}
}
-#ifndef MODULE
XGIINITSTATIC int __init XGIfb_setup(char *options)
{
char *this_opt;
-
-
xgi_video_info.refresh_rate = 0;
- printk(KERN_INFO "XGIfb: Options %s\n", options);
+ printk(KERN_INFO "XGIfb: Options %s\n", options);
if (!options || !*options)
return 0;
- while((this_opt = strsep(&options, ",")) != NULL) {
+ while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ if (!*this_opt)
+ continue;
if (!strncmp(this_opt, "mode:", 5)) {
XGIfb_search_mode(this_opt + 5);
@@ -2780,414 +2835,384 @@ XGIINITSTATIC int __init XGIfb_setup(char *options)
XGIfb_search_crt2type(this_opt + 14);
} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
- } else if (!strncmp(this_opt, "tvmode:",7)) {
- XGIfb_search_tvstd(this_opt + 7);
- } else if (!strncmp(this_opt, "tvstandard:",11)) {
+ } else if (!strncmp(this_opt, "tvmode:", 7)) {
+ XGIfb_search_tvstd(this_opt + 7);
+ } else if (!strncmp(this_opt, "tvstandard:", 11)) {
XGIfb_search_tvstd(this_opt + 7);
- } else if (!strncmp(this_opt, "mem:",4)) {
- XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
- } else if (!strncmp(this_opt, "dstn", 4)) {
+ } else if (!strncmp(this_opt, "mem:", 4)) {
+ XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
+ } else if (!strncmp(this_opt, "dstn", 4)) {
enable_dstn = 1;
/* TW: DSTN overrules forcecrt2type */
XGIfb_crt2type = DISPTYPE_LCD;
} else if (!strncmp(this_opt, "queuemode:", 10)) {
XGIfb_search_queuemode(this_opt + 10);
} else if (!strncmp(this_opt, "pdc:", 4)) {
- XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
- if(XGIfb_pdc & ~0x3c) {
- printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
- XGIfb_pdc = 0;
- }
+ XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
+ if (XGIfb_pdc & ~0x3c) {
+ printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
+ XGIfb_pdc = 0;
+ }
} else if (!strncmp(this_opt, "noaccel", 7)) {
XGIfb_accel = 0;
} else if (!strncmp(this_opt, "noypan", 6)) {
- XGIfb_ypan = 0;
+ XGIfb_ypan = 0;
} else if (!strncmp(this_opt, "userom:", 7)) {
XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
-// } else if (!strncmp(this_opt, "useoem:", 7)) {
-// XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
+ /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
+ /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
} else {
XGIfb_search_mode(this_opt);
-// printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt);
+ /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
}
/* TW: Acceleration only with MMIO mode */
- if((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
+ if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
XGIfb_ypan = 0;
XGIfb_accel = 0;
}
/* TW: Panning only with acceleration */
- if(XGIfb_accel == 0) XGIfb_ypan = 0;
+ if (XGIfb_accel == 0)
+ XGIfb_ypan = 0;
}
printk("\nxgifb: outa xgifb_setup 3450");
return 0;
}
-#endif
static unsigned char VBIOS_BUF[65535];
-unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
+static unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
{
- u32 rom_size = 0;
- u32 rom_address = 0;
- int j;
-
- /* Get the size of the expansion rom */
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
- pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
- if ((rom_size & 0x01) == 0)
- {
+ u32 rom_size = 0;
+ u32 rom_address = 0;
+ int j;
+
+ /* Get the size of the expansion rom */
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
+ pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
+ if ((rom_size & 0x01) == 0) {
printk("No ROM\n");
return NULL;
- }
+ }
- rom_size &= 0xFFFFF800;
- rom_size = (~rom_size)+1;
+ rom_size &= 0xFFFFF800;
+ rom_size = (~rom_size) + 1;
- rom_address = pci_resource_start(dev, 0);
- if (rom_address == 0 || rom_address == 0xFFFFFFF0)
- {
- printk("No suitable rom address found\n"); return NULL;
- }
+ rom_address = pci_resource_start(dev, 0);
+ if (rom_address == 0 || rom_address == 0xFFFFFFF0) {
+ printk("No suitable rom address found\n");
+ return NULL;
+ }
- printk("ROM Size is %dK, Address is %x\n", rom_size/1024, rom_address);
+ printk("ROM Size is %dK, Address is %x\n", rom_size / 1024, rom_address);
- /* Map ROM */
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
+ /* Map ROM */
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address
+ | PCI_ROM_ADDRESS_ENABLE);
- /* memcpy(copy_address, rom_address, rom_size); */
- {
+ /* memcpy(copy_address, rom_address, rom_size); */
+ {
unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
- unsigned char *from = (unsigned char *)virt_addr;
- unsigned char *to = (unsigned char *)copy_address;
- for (j=0; j<65536 /*rom_size*/; j++) *to++ = *from++;
+ unsigned char *from = (unsigned char *) virt_addr;
+ unsigned char *to = (unsigned char *) copy_address;
+ for (j = 0; j < 65536 /*rom_size*/; j++)
+ *to++ = *from++;
}
pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
- printk("Copy is done\n");
+ printk("Copy is done\n");
return copy_address;
}
-int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit xgifb_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
u16 reg16;
- u8 reg, reg1;
- u8 CR48,CR38;
+ u8 reg, reg1;
+ u8 CR48, CR38;
if (XGIfb_off)
return -ENXIO;
XGIfb_registered = 0;
memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
- fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
- if(!fb_info) return -ENOMEM;
-
- xgi_video_info.chip_id = pdev->device;
- pci_read_config_byte(pdev, PCI_REVISION_ID,&xgi_video_info.revision_id);
- pci_read_config_word(pdev, PCI_COMMAND, &reg16);
- XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
- XGIvga_enabled = reg16 & 0x01;
-
- xgi_video_info.pcibus = pdev->bus->number;
- xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
- xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
- xgi_video_info.subsysvendor = pdev->subsystem_vendor;
- xgi_video_info.subsysdevice = pdev->subsystem_device;
-
- xgi_video_info.video_base = pci_resource_start(pdev, 0);
- xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
- XGIfb_mmio_size = pci_resource_len(pdev, 1);
- xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
- XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
- //XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30;
- printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
- (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
-
- if (pci_enable_device(pdev))
- return -EIO;
-
- XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
-
- outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
- inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
-
- if(reg1 != 0xa1) /*I/O error */
- {
- printk("\nXGIfb: I/O error!!!");
- return -EIO;
- }
+ fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
+ if (!fb_info)
+ return -ENOMEM;
+
+ xgi_video_info.chip_id = pdev->device;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
+ pci_read_config_word(pdev, PCI_COMMAND, &reg16);
+ XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
+ XGIvga_enabled = reg16 & 0x01;
+
+ xgi_video_info.pcibus = pdev->bus->number;
+ xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
+ xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
+ xgi_video_info.subsysvendor = pdev->subsystem_vendor;
+ xgi_video_info.subsysdevice = pdev->subsystem_device;
+
+ xgi_video_info.video_base = pci_resource_start(pdev, 0);
+ xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
+ XGIfb_mmio_size = pci_resource_len(pdev, 1);
+ xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
+ XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
+ /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
+ printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
+ (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
+
+ if (pci_enable_device(pdev))
+ return -EIO;
+
+ XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
+
+ outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+ inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
+
+ if (reg1 != 0xa1) { /*I/O error */
+ printk("\nXGIfb: I/O error!!!");
+ return -EIO;
+ }
switch (xgi_video_info.chip_id) {
- case PCI_DEVICE_ID_XG_20:
+ case PCI_DEVICE_ID_XG_20:
orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
if (CR48&GPIOG_READ)
xgi_video_info.chip = XG21;
else
- xgi_video_info.chip = XG20;
+ xgi_video_info.chip = XG20;
XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
break;
- case PCI_DEVICE_ID_XG_40:
+ case PCI_DEVICE_ID_XG_40:
xgi_video_info.chip = XG40;
XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
break;
- case PCI_DEVICE_ID_XG_41:
+ case PCI_DEVICE_ID_XG_41:
xgi_video_info.chip = XG41;
XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
break;
- case PCI_DEVICE_ID_XG_42:
+ case PCI_DEVICE_ID_XG_42:
xgi_video_info.chip = XG42;
XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
break;
- case PCI_DEVICE_ID_XG_27:
+ case PCI_DEVICE_ID_XG_27:
xgi_video_info.chip = XG27;
XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
break;
- default:
- return -ENODEV;
+ default:
+ return -ENODEV;
}
- printk("XGIfb:chipid = %x\n",xgi_video_info.chip);
- XGIhw_ext.jChipType = xgi_video_info.chip;
-
- switch (xgi_video_info.chip) {
- case XG40:
- case XG41:
- case XG42:
- case XG45:
- case XG20:
- case XG21:
- case XG27:
- XGIhw_ext.bIntegratedMMEnabled = 1;
- break;
-
- default:
- break;
- }
+ printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
+ XGIhw_ext.jChipType = xgi_video_info.chip;
+ switch (xgi_video_info.chip) {
+ case XG40:
+ case XG41:
+ case XG42:
+ case XG45:
+ case XG20:
+ case XG21:
+ case XG27:
+ XGIhw_ext.bIntegratedMMEnabled = 1;
+ break;
+ default:
+ break;
+ }
- XGIhw_ext.pDevice = NULL;
- if ((xgi_video_info.chip == XG21) || (XGIfb_userom))
- {
- XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
+ XGIhw_ext.pDevice = NULL;
+ if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
+ XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
- if(XGIhw_ext.pjVirtualRomBase)
- printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",XGIhw_ext.pjVirtualRomBase);
+ if (XGIhw_ext.pjVirtualRomBase)
+ printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
else
printk(KERN_INFO "XGIfb: Video ROM not found\n");
- } else {
- XGIhw_ext.pjVirtualRomBase = NULL;
+ } else {
+ XGIhw_ext.pjVirtualRomBase = NULL;
printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
- }
- XGIhw_ext.pjCustomizedROMImage = NULL;
- XGIhw_ext.bSkipDramSizing = 0;
- XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
-// XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space;
- strcpy(XGIhw_ext.szVBIOSVer, "0.84");
+ }
+ XGIhw_ext.pjCustomizedROMImage = NULL;
+ XGIhw_ext.bSkipDramSizing = 0;
+ XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
+ /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
+ strcpy(XGIhw_ext.szVBIOSVer, "0.84");
+ XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
+ if (XGIhw_ext.pSR == NULL) {
+ printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
+ return -ENODEV;
+ }
+ XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
- XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
- if (XGIhw_ext.pSR == NULL)
- {
- printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
- return -ENODEV;
- }
- XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
+ XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
+ if (XGIhw_ext.pCR == NULL) {
+ vfree(XGIhw_ext.pSR);
+ printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
+ return -ENODEV;
+ }
+ XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
+
+ if (!XGIvga_enabled) {
+ /* Mapping Max FB Size for 315 Init */
+ XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
+ if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
+#ifdef LINUXBIOS
+ printk("XGIfb: XGIInit() ...");
+ /* XGIInitNewt for LINUXBIOS only */
+ if (XGIInitNew(&XGIhw_ext))
+ printk("OK\n");
+ else
+ printk("Fail\n");
+#endif
- XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
- if (XGIhw_ext.pCR == NULL)
- {
- vfree(XGIhw_ext.pSR);
- printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
- return -ENODEV;
- }
- XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
+ outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+ }
+ }
+#ifdef LINUXBIOS
+ else {
+ XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
+ if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
+ outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+ /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
+ /* Set SR13 ,14 temporarily for UDtech */
+ outXGIIDXREG(XGISR, 0x13, 0x45);
+ outXGIIDXREG(XGISR, 0x14, 0x51);
- if (!XGIvga_enabled)
- {
- /* Mapping Max FB Size for 315 Init */
- XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
- if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
- {
-#ifdef LINUXBIOS
- printk("XGIfb: XGIInit() ...");
- /* XGIInitNewt for LINUXBIOS only */
- if(XGIInitNew(&XGIhw_ext))
- {
- printk("OK\n");
- }
- else
- {
- printk("Fail\n");
}
+ }
#endif
+ if (XGIfb_get_dram_size()) {
+ vfree(XGIhw_ext.pSR);
+ vfree(XGIhw_ext.pCR);
+ printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
+ return -ENODEV;
+ }
- outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+ if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
+ /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
+ orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
+ /* Enable 2D accelerator engine */
+ orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
+ }
+ XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
- }
+ if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
+ printk("unable request memory size %x", xgi_video_info.video_size);
+ printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
+ printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
+ vfree(XGIhw_ext.pSR);
+ vfree(XGIhw_ext.pCR);
+ return -ENODEV;
}
-#ifdef LINUXBIOS
- else
- {
- XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
- if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
- {
- outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+ if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) {
+ printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
+ release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
+ vfree(XGIhw_ext.pSR);
+ vfree(XGIhw_ext.pCR);
+ return -ENODEV;
+ }
- // yilin Because no VBIOS DRAM Sizing, Dram size will error.
- // Set SR13 ,14 temporarily for UDtech
- outXGIIDXREG(XGISR, 0x13, 0x45);
- outXGIIDXREG(XGISR, 0x14, 0x51);
+ xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
+ ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
+ xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
+ printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+ xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
- }
- }
-#endif
- if (XGIfb_get_dram_size())
- {
- vfree(XGIhw_ext.pSR);
- vfree(XGIhw_ext.pCR);
- printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
- return -ENODEV;
- }
-
-
-
- if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
- {
- /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
- orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
- /* Enable 2D accelerator engine */
- orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
- }
-
- XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
-
- if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB"))
- { printk("unable request memory size %x",xgi_video_info.video_size);
- printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
- printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
- vfree(XGIhw_ext.pSR);
- vfree(XGIhw_ext.pCR);
- return -ENODEV;
- }
-
- if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO"))
- {
- printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
- release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
- vfree(XGIhw_ext.pSR);
- vfree(XGIhw_ext.pCR);
- return -ENODEV;
- }
-
- xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
- ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
- xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
-
- printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
- xgi_video_info.video_base, xgi_video_info.video_vbase,xgi_video_info.video_size / 1024);
-
- printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
- xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,XGIfb_mmio_size / 1024);
- printk("XGIfb: XGIInitNew() ...");
- if(XGIInitNew(&XGIhw_ext))
- {
- printk("OK\n");
- }
- else
- {
+ printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
+ xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024);
+ printk("XGIfb: XGIInitNew() ...");
+ if (XGIInitNew(&XGIhw_ext))
+ printk("OK\n");
+ else
printk("Fail\n");
- }
-
- if(XGIfb_heap_init())
- {
- printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
- }
-
-
- xgi_video_info.mtrr = (unsigned int) 0;
-
- if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
- {
- xgi_video_info.hasVB = HASVB_NONE;
- if((xgi_video_info.chip == XG20)||(xgi_video_info.chip == XG27))
- xgi_video_info.hasVB = HASVB_NONE;
- else if(xgi_video_info.chip == XG21) {
- inXGIIDXREG(XGICR,0x38,CR38);
- if ((CR38&0xE0) == 0xC0) {
- xgi_video_info.disp_state = DISPTYPE_LCD;
- if (!XGIfb_GetXG21LVDSData()) {
- int m;
- for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
- if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
- (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
- XGINew_SetReg1( XGI_Pr.P3d4 , 0x36, m) ;
- }
- }
- }
- }
- else if ((CR38&0xE0) == 0x60)
- xgi_video_info.hasVB = HASVB_CHRONTEL ;
- else
+
+ if (XGIfb_heap_init())
+ printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
+
+ xgi_video_info.mtrr = (unsigned int) 0;
+
+ if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
xgi_video_info.hasVB = HASVB_NONE;
- }
- else
- XGIfb_get_VB_type();
+ if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
+ xgi_video_info.hasVB = HASVB_NONE;
+ } else if (xgi_video_info.chip == XG21) {
+ inXGIIDXREG(XGICR, 0x38, CR38);
+ if ((CR38&0xE0) == 0xC0) {
+ xgi_video_info.disp_state = DISPTYPE_LCD;
+ if (!XGIfb_GetXG21LVDSData()) {
+ int m;
+ for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
+ if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
+ (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
+ XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
+ }
+ }
+ }
+ } else if ((CR38&0xE0) == 0x60) {
+ xgi_video_info.hasVB = HASVB_CHRONTEL;
+ } else {
+ xgi_video_info.hasVB = HASVB_NONE;
+ }
+ } else {
+ XGIfb_get_VB_type();
+ }
- XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+ XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
- XGIhw_ext.ulExternalChip = 0;
+ XGIhw_ext.ulExternalChip = 0;
switch (xgi_video_info.hasVB) {
case HASVB_301:
- inXGIIDXREG(XGIPART4, 0x01, reg);
+ inXGIIDXREG(XGIPART4, 0x01, reg);
if (reg >= 0xE0) {
XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
- printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
- } else if (reg >= 0xD0) {
+ printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+ } else if (reg >= 0xD0) {
XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
- printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n",reg);
- }
+ printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
+ }
/* else if (reg >= 0xB0) {
XGIhw_ext.ujVBChipID = VB_CHIP_301B;
- inXGIIDXREG(XGIPART4,0x23,reg1);
- printk("XGIfb: XGI301B bridge detected\n");
- }*/
+ inXGIIDXREG(XGIPART4, 0x23, reg1);
+ printk("XGIfb: XGI301B bridge detected\n");
+ } */
else {
XGIhw_ext.ujVBChipID = VB_CHIP_301;
printk("XGIfb: XGI301 bridge detected\n");
}
break;
case HASVB_302:
- inXGIIDXREG(XGIPART4, 0x01, reg);
+ inXGIIDXREG(XGIPART4, 0x01, reg);
if (reg >= 0xE0) {
XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
- printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
- } else if (reg >= 0xD0) {
+ printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+ } else if (reg >= 0xD0) {
XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
- printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
- } else if (reg >= 0xB0) {
- inXGIIDXREG(XGIPART4,0x23,reg1);
+ printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+ } else if (reg >= 0xB0) {
+ inXGIIDXREG(XGIPART4, 0x23, reg1);
- XGIhw_ext.ujVBChipID = VB_CHIP_302B;
+ XGIhw_ext.ujVBChipID = VB_CHIP_302B;
} else {
- XGIhw_ext.ujVBChipID = VB_CHIP_302;
+ XGIhw_ext.ujVBChipID = VB_CHIP_302;
printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
}
break;
@@ -3207,14 +3232,13 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
XGIhw_ext.ulExternalChip = 0x5;
printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
break;
- default:
+ default:
printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
break;
}
- if (xgi_video_info.hasVB != HASVB_NONE) {
- XGIfb_detect_VB();
- }
+ if (xgi_video_info.hasVB != HASVB_NONE)
+ XGIfb_detect_VB();
if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
if (XGIfb_crt1off)
@@ -3226,61 +3250,52 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
if (xgi_video_info.disp_state & DISPTYPE_LCD) {
- if (!enable_dstn) {
- inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
- reg &= 0x0f;
- XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
-
- } else {
- // TW: FSTN/DSTN
- XGIhw_ext.ulCRT2LCDType = LCD_320x480;
- }
+ if (!enable_dstn) {
+ inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
+ reg &= 0x0f;
+ XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
+
+ } else {
+ /* TW: FSTN/DSTN */
+ XGIhw_ext.ulCRT2LCDType = LCD_320x480;
+ }
}
XGIfb_detectedpdc = 0;
- XGIfb_detectedlcda = 0xff;
+ XGIfb_detectedlcda = 0xff;
#ifndef LINUXBIOS
- /* TW: Try to find about LCDA */
-
- if((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
- (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
- (XGIhw_ext.ujVBChipID == VB_CHIP_302LV))
- {
- int tmp;
- inXGIIDXREG(XGICR,0x34,tmp);
- if(tmp <= 0x13)
- {
- // Currently on LCDA? (Some BIOSes leave CR38)
- inXGIIDXREG(XGICR,0x38,tmp);
- if((tmp & 0x03) == 0x03)
- {
-/* XGI_Pr.XGI_UseLCDA = 1; */
- }else
- {
- // Currently on LCDA? (Some newer BIOSes set D0 in CR35)
- inXGIIDXREG(XGICR,0x35,tmp);
- if(tmp & 0x01)
- {
-/* XGI_Pr.XGI_UseLCDA = 1; */
- }else
- {
- inXGIIDXREG(XGICR,0x30,tmp);
- if(tmp & 0x20)
- {
- inXGIIDXREG(XGIPART1,0x13,tmp);
- if(tmp & 0x04)
- {
-/* XGI_Pr.XGI_UseLCDA = 1; */
- }
- }
- }
- }
- }
-
- }
+ /* TW: Try to find about LCDA */
+
+ if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
+ (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
+ (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
+ int tmp;
+ inXGIIDXREG(XGICR, 0x34, tmp);
+ if (tmp <= 0x13) {
+ /* Currently on LCDA? (Some BIOSes leave CR38) */
+ inXGIIDXREG(XGICR, 0x38, tmp);
+ if ((tmp & 0x03) == 0x03) {
+ /* XGI_Pr.XGI_UseLCDA = 1; */
+ } else {
+ /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
+ inXGIIDXREG(XGICR, 0x35, tmp);
+ if (tmp & 0x01) {
+ /* XGI_Pr.XGI_UseLCDA = 1; */
+ } else {
+ inXGIIDXREG(XGICR, 0x30, tmp);
+ if (tmp & 0x20) {
+ inXGIIDXREG(XGIPART1, 0x13, tmp);
+ if (tmp & 0x04) {
+ /* XGI_Pr.XGI_UseLCDA = 1; */
+ }
+ }
+ }
+ }
+ }
+ }
#endif
@@ -3289,17 +3304,15 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (xgifb_mode_idx < 0) {
switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
- case DISPTYPE_LCD:
+ case DISPTYPE_LCD:
xgifb_mode_idx = DEFAULT_LCDMODE;
if (xgi_video_info.chip == XG21)
- {
- xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
- }
+ xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
break;
- case DISPTYPE_TV:
+ case DISPTYPE_TV:
xgifb_mode_idx = DEFAULT_TVMODE;
break;
- default:
+ default:
xgifb_mode_idx = DEFAULT_MODE;
break;
}
@@ -3307,47 +3320,43 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
-
- if( xgi_video_info.refresh_rate == 0)
- xgi_video_info.refresh_rate = 60; /*yilin set default refresh rate */
- if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0)
- {
- XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
- xgi_video_info.refresh_rate = 60;
- }
+ if (xgi_video_info.refresh_rate == 0)
+ xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
+ if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
+ XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
+ xgi_video_info.refresh_rate = 60;
+ }
xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
xgi_video_info.org_x = xgi_video_info.org_y = 0;
xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
- switch(xgi_video_info.video_bpp) {
- case 8:
- xgi_video_info.DstColor = 0x0000;
- xgi_video_info.XGI310_AccelDepth = 0x00000000;
+ switch (xgi_video_info.video_bpp) {
+ case 8:
+ xgi_video_info.DstColor = 0x0000;
+ xgi_video_info.XGI310_AccelDepth = 0x00000000;
xgi_video_info.video_cmap_len = 256;
- break;
- case 16:
- xgi_video_info.DstColor = 0x8000;
- xgi_video_info.XGI310_AccelDepth = 0x00010000;
+ break;
+ case 16:
+ xgi_video_info.DstColor = 0x8000;
+ xgi_video_info.XGI310_AccelDepth = 0x00010000;
xgi_video_info.video_cmap_len = 16;
- break;
- case 32:
- xgi_video_info.DstColor = 0xC000;
- xgi_video_info.XGI310_AccelDepth = 0x00020000;
+ break;
+ case 32:
+ xgi_video_info.DstColor = 0xC000;
+ xgi_video_info.XGI310_AccelDepth = 0x00020000;
xgi_video_info.video_cmap_len = 16;
- break;
+ break;
default:
xgi_video_info.video_cmap_len = 16;
- printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
+ printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
break;
- }
-
-
+ }
printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
- xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
- xgi_video_info.refresh_rate);
+ xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
+ xgi_video_info.refresh_rate);
default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
@@ -3359,29 +3368,29 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
XGIfb_mode_no, XGIfb_rate_idx));
- if(XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
- XGIfb_mode_no, XGIfb_rate_idx,
- &default_var.left_margin, &default_var.right_margin,
- &default_var.upper_margin, &default_var.lower_margin,
- &default_var.hsync_len, &default_var.vsync_len,
- &default_var.sync, &default_var.vmode)) {
-
- if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- default_var.yres <<= 1;
- default_var.yres_virtual <<= 1;
- } else if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- default_var.pixclock >>= 1;
- default_var.yres >>= 1;
- default_var.yres_virtual >>= 1;
- }
+ if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
+ XGIfb_mode_no, XGIfb_rate_idx,
+ &default_var.left_margin, &default_var.right_margin,
+ &default_var.upper_margin, &default_var.lower_margin,
+ &default_var.hsync_len, &default_var.vsync_len,
+ &default_var.sync, &default_var.vmode)) {
+
+ if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ default_var.yres <<= 1;
+ default_var.yres_virtual <<= 1;
+ } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ default_var.pixclock >>= 1;
+ default_var.yres >>= 1;
+ default_var.yres_virtual >>= 1;
+ }
- }
+ }
xgi_video_info.accel = 0;
- if(XGIfb_accel) {
- xgi_video_info.accel = -1;
- default_var.accel_flags |= FB_ACCELF_TEXT;
- XGIfb_initaccel();
+ if (XGIfb_accel) {
+ xgi_video_info.accel = -1;
+ default_var.accel_flags |= FB_ACCELF_TEXT;
+ XGIfb_initaccel();
}
fb_info->flags = FBINFO_FLAG_DEFAULT;
@@ -3395,33 +3404,21 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
fb_alloc_cmap(&fb_info->cmap, 256 , 0);
-
#ifdef CONFIG_MTRR
xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
(unsigned int) xgi_video_info.video_size,
MTRR_TYPE_WRCOMB, 1);
- if(xgi_video_info.mtrr) {
+ if (xgi_video_info.mtrr)
printk(KERN_INFO "XGIfb: Added MTRRs\n");
- }
#endif
- if(register_framebuffer(fb_info) < 0)
- {
+ if (register_framebuffer(fb_info) < 0)
return -EINVAL;
- }
XGIfb_registered = 1;
- printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%lx)\n",
- XGIFB_GET_INFO);
-
-/* printk(KERN_INFO "XGIfb: 2D acceleration is %s, scrolling mode %s\n",
- XGIfb_accel ? "enabled" : "disabled",
- XGIfb_ypan ? "ypan" : "redraw");
-*/
printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
- fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
-
+ fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
}
@@ -3430,7 +3427,6 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
}
-
/*****************************************************/
/* PCI DEVICE HANDLING */
/*****************************************************/
@@ -3438,34 +3434,32 @@ int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
static void __devexit xgifb_remove(struct pci_dev *pdev)
{
/* Unregister the framebuffer */
-// if(xgi_video_info.registered) {
- unregister_framebuffer(fb_info);
- framebuffer_release(fb_info);
-// }
+ /* if (xgi_video_info.registered) { */
+ unregister_framebuffer(fb_info);
+ framebuffer_release(fb_info);
+ /* } */
pci_set_drvdata(pdev, NULL);
};
static struct pci_driver xgifb_driver = {
- .name = "xgifb",
- .id_table = xgifb_pci_table,
- .probe = xgifb_probe,
- .remove = __devexit_p(xgifb_remove)
+ .name = "xgifb",
+ .id_table = xgifb_pci_table,
+ .probe = xgifb_probe,
+ .remove = __devexit_p(xgifb_remove)
};
XGIINITSTATIC int __init xgifb_init(void)
{
-#ifndef MODULE
char *option = NULL;
if (fb_get_options("xgifb", &option))
return -ENODEV;
XGIfb_setup(option);
-#endif
- return(pci_register_driver(&xgifb_driver));
-}
+ return pci_register_driver(&xgifb_driver);
+}
#ifndef MODULE
module_init(xgifb_init);
@@ -3477,37 +3471,34 @@ module_init(xgifb_init);
#ifdef MODULE
-static char *mode = NULL;
-static int vesa = 0;
+static char *mode = NULL;
+static int vesa = 0;
static unsigned int rate = 0;
-static unsigned int crt1off = 1;
static unsigned int mem = 0;
-static char *forcecrt2type = NULL;
-static int forcecrt1 = -1;
-static int pdc = -1;
-static int pdc1 = -1;
-static int noaccel = -1;
-static int noypan = -1;
-static int nomax = -1;
-static int userom = -1;
-static int useoem = -1;
-static char *tvstandard = NULL;
-static int nocrt2rate = 0;
-static int scalelcd = -1;
-static char *specialtiming = NULL;
-static int lvdshl = -1;
-static int tvxposoffset = 0, tvyposoffset = 0;
+static char *forcecrt2type = NULL;
+static int forcecrt1 = -1;
+static int pdc = -1;
+static int pdc1 = -1;
+static int noaccel = -1;
+static int noypan = -1;
+static int nomax = -1;
+static int userom = -1;
+static int useoem = -1;
+static char *tvstandard = NULL;
+static int nocrt2rate = 0;
+static int scalelcd = -1;
+static char *specialtiming = NULL;
+static int lvdshl = -1;
+static int tvxposoffset = 0, tvyposoffset = 0;
#if !defined(__i386__) && !defined(__x86_64__)
-static int resetcard = 0;
-static int videoram = 0;
+static int resetcard = 0;
+static int videoram = 0;
#endif
MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XGITECH , Others");
-
-
module_param(mem, int, 0);
module_param(noaccel, int, 0);
module_param(noypan, int, 0);
@@ -3534,122 +3525,115 @@ module_param(resetcard, int, 0);
module_param(videoram, int, 0);
#endif
-
MODULE_PARM_DESC(mem,
- "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
- "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
- "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
- "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
- "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
- "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
- "for XFree86 4.x/X.org 6.7 and later.\n");
+ "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+ "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
+ "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
+ "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
+ "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
+ "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
+ "for XFree86 4.x/X.org 6.7 and later.\n");
MODULE_PARM_DESC(noaccel,
- "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
- "(default: 0)\n");
+ "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+ "(default: 0)\n");
MODULE_PARM_DESC(noypan,
- "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
- "will be performed by redrawing the screen. (default: 0)\n");
+ "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+ "will be performed by redrawing the screen. (default: 0)\n");
MODULE_PARM_DESC(nomax,
- "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
- "memory for the virtual screen in order to optimize scrolling performance. If\n"
- "this is set to anything other than 0, xgifb will not do this and thereby \n"
- "enable the user to positively specify a virtual Y size of the screen using\n"
- "fbset. (default: 0)\n");
-
-
+ "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
+ "memory for the virtual screen in order to optimize scrolling performance. If\n"
+ "this is set to anything other than 0, xgifb will not do this and thereby\n"
+ "enable the user to positively specify a virtual Y size of the screen using\n"
+ "fbset. (default: 0)\n");
MODULE_PARM_DESC(mode,
- "\nSelects the desired default display mode in the format XxYxDepth,\n"
- "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
- "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
- "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
+ "\nSelects the desired default display mode in the format XxYxDepth,\n"
+ "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+ "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
MODULE_PARM_DESC(vesa,
- "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
- "0x117 (default: 0x0103)\n");
-
+ "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+ "0x117 (default: 0x0103)\n");
MODULE_PARM_DESC(rate,
- "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
- "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
- "will be ignored (default: 60)\n");
+ "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
+ "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
+ "will be ignored (default: 60)\n");
MODULE_PARM_DESC(forcecrt1,
- "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
- "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
- "0=CRT1 OFF) (default: [autodetected])\n");
+ "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
+ "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
+ "0=CRT1 OFF) (default: [autodetected])\n");
MODULE_PARM_DESC(forcecrt2type,
- "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
- "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
- "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
- "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
- "be used instead of TV to override the TV detection. Furthermore, on systems\n"
- "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
- "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
- "depends on the very hardware in use. (default: [autodetected])\n");
+ "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
+ "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
+ "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
+ "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
+ "be used instead of TV to override the TV detection. Furthermore, on systems\n"
+ "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
+ "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
+ "depends on the very hardware in use. (default: [autodetected])\n");
MODULE_PARM_DESC(scalelcd,
- "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
- "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
- "show black bars around the image, TMDS panels will probably do the scaling\n"
- "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
+ "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
+ "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
+ "show black bars around the image, TMDS panels will probably do the scaling\n"
+ "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
MODULE_PARM_DESC(pdc,
- "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
- "should detect this correctly in most cases; however, sometimes this is not\n"
- "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
- "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
- "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
- "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
+ "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
+ "should detect this correctly in most cases; however, sometimes this is not\n"
+ "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
+ "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
+ "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
+ "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
MODULE_PARM_DESC(pdc1,
- "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
- "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
- "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
- "implemented yet.\n");
+ "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
+ "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
+ "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
+ "implemented yet.\n");
MODULE_PARM_DESC(specialtiming,
- "\nPlease refer to documentation for more information on this option.\n");
+ "\nPlease refer to documentation for more information on this option.\n");
MODULE_PARM_DESC(lvdshl,
- "\nPlease refer to documentation for more information on this option.\n");
+ "\nPlease refer to documentation for more information on this option.\n");
MODULE_PARM_DESC(tvstandard,
- "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
- "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
+ "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+ "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
MODULE_PARM_DESC(tvxposoffset,
- "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
- "Default: 0\n");
+ "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
+ "Default: 0\n");
MODULE_PARM_DESC(tvyposoffset,
- "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
- "Default: 0\n");
+ "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
+ "Default: 0\n");
MODULE_PARM_DESC(filter,
- "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
- "(Possible values 0-7, default: [no filter])\n");
+ "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+ "(Possible values 0-7, default: [no filter])\n");
MODULE_PARM_DESC(nocrt2rate,
- "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
- "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
-
-
-
+ "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
+ "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
-int __init xgifb_init_module(void)
+static int __init xgifb_init_module(void)
{
- printk("\nXGIfb_init_module");
- if(mode)
+ printk("\nXGIfb_init_module");
+ if (mode)
XGIfb_search_mode(mode);
else if (vesa != -1)
XGIfb_search_vesamode(vesa);
- return(xgifb_init());
+ return xgifb_init();
}
static void __exit xgifb_remove_module(void)
@@ -3661,7 +3645,7 @@ static void __exit xgifb_remove_module(void)
module_init(xgifb_init_module);
module_exit(xgifb_remove_module);
-#endif /* /MODULE */
+#endif /* /MODULE */
EXPORT_SYMBOL(XGI_malloc);
EXPORT_SYMBOL(XGI_free);
diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c
index 1ecf9e3e85fb..80c78185a2e2 100644
--- a/drivers/staging/xgifb/vb_ext.c
+++ b/drivers/staging/xgifb/vb_ext.c
@@ -9,1046 +9,849 @@
#include "vb_util.h"
#include "vb_setmode.h"
#include "vb_ext.h"
-extern unsigned char XGI330_SoftSetting;
-extern unsigned char XGI330_OutputSelect;
-extern unsigned short XGI330_RGBSenseData2;
-extern unsigned short XGI330_YCSenseData2;
-extern unsigned short XGI330_VideoSenseData2;
-void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
-unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo);
+extern unsigned char XGI330_SoftSetting;
+extern unsigned char XGI330_OutputSelect;
+extern unsigned short XGI330_RGBSenseData2;
+extern unsigned short XGI330_YCSenseData2;
+extern unsigned short XGI330_VideoSenseData2;
+void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
+unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo);
unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
- struct vb_device_info *pVBInfo);
-unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ struct vb_device_info *pVBInfo);
+unsigned char XGINew_GetLCDDDCInfo(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
unsigned long VESA_POWER_STATE);
-unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
+unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *,
+ struct vb_device_info *pVBInfo);
unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx,
- struct vb_device_info *pVBInfo);
+ struct vb_device_info *pVBInfo);
unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ struct vb_device_info *pVBInfo);
/**************************************************************
- Dynamic Sense
-*************************************************************/
+ *********************** Dynamic Sense ************************
+ *************************************************************/
void XGI_WaitDisplay(void);
unsigned char XGI_Is301C(struct vb_device_info *);
unsigned char XGI_Is301LV(struct vb_device_info *);
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Is301B */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
+static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
{
- unsigned short flag ;
+ unsigned short flag;
- flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) ;
+ flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
- if ( flag > 0x0B0 )
- return( 0 ) ; /* 301b */
- else
- return( 1 ) ;
+ if (flag > 0x0B0)
+ return 0; /* 301b */
+ else
+ return 1;
}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_Is301C */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGI_Is301C(struct vb_device_info *pVBInfo)
{
- if ( ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) & 0xF0 ) == 0xC0 )
- return( 1 ) ;
+ if ((XGINew_GetReg1(pVBInfo->Part4Port, 0x01) & 0xF0) == 0xC0)
+ return 1;
- if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
- {
- if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) == 0xE0 )
- return( 1 ) ;
- }
+ if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) {
+ if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xE0)
+ return 1;
+ }
- return( 0 ) ;
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_Is301LV */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGI_Is301LV(struct vb_device_info *pVBInfo)
{
- if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
- {
- if ( XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) == 0xFF )
- {
- return( 1 ) ;
- }
- }
- return( 0 ) ;
+ if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) {
+ if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xFF)
+ return 1;
+ }
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Sense */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGINew_Sense(unsigned short tempbx,
- unsigned short tempcx,
- struct vb_device_info *pVBInfo)
+unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo)
{
- unsigned short temp, i, tempch;
-
- temp = tempbx & 0xFF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp |= ( tempcx & 0x00FF ) ;
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
-
- for( i = 0 ; i < 10 ; i++ )
- XGI_LongWait( pVBInfo) ;
-
- tempch = ( tempcx & 0x7F00 ) >> 8 ;
- temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
- temp = temp ^ ( 0x0E ) ;
- temp &= tempch ;
-
- if ( temp > 0 )
- return( 1 ) ;
- else
- return( 0 ) ;
+ unsigned short temp, i, tempch;
+
+ temp = tempbx & 0xFF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp |= (tempcx & 0x00FF);
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
+
+ for (i = 0; i < 10; i++)
+ XGI_LongWait(pVBInfo);
+
+ tempch = (tempcx & 0x7F00) >> 8;
+ temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
+ temp = temp ^ (0x0E);
+ temp &= tempch;
+
+ if (temp > 0)
+ return 1;
+ else
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGISetDPMS */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
- unsigned long VESA_POWER_STATE)
+void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE, unsigned long VESA_POWER_STATE)
{
- unsigned short ModeNo, ModeIdIndex;
- unsigned char temp;
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->BaseAddr = (unsigned long)pXGIHWDE->pjIOAddress ;
- pVBInfo->ROMAddr = pXGIHWDE->pjVirtualRomBase ;
-
-
- pVBInfo->IF_DEF_LVDS = 0 ;
- pVBInfo->IF_DEF_CH7005 = 0 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_LCDA = 1 ;
- pVBInfo->IF_DEF_CH7017 = 0 ;
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- pVBInfo->IF_DEF_VideoCapture = 0 ;
- pVBInfo->IF_DEF_ScaleLCD = 0 ;
- pVBInfo->IF_DEF_OEMUtil = 0 ;
- pVBInfo->IF_DEF_PWD = 0 ;
-
- InitTo330Pointer( pXGIHWDE->jChipType, pVBInfo ) ;
- ReadVBIOSTablData( pXGIHWDE->jChipType , pVBInfo) ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- if ( pXGIHWDE->jChipType == XG27 )
- {
- if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
- {
- if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) & 0x20 )
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- }
- }
- }
-
- if ( pVBInfo->IF_DEF_CH7007 == 0 )
- {
- XGINew_SetModeScratch ( pXGIHWDE , pVBInfo ) ;
- }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ; /* 1.Openkey */
- XGI_UnLockCRT2( pXGIHWDE , pVBInfo) ;
- ModeNo = XGINew_GetReg1( pVBInfo->P3d4 , 0x34 ) ;
- XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
- XGI_GetVGAType( pXGIHWDE , pVBInfo ) ;
-
- if ( ( pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) || ( pVBInfo->IF_DEF_CH7007 == 1 ))
- {
- XGI_GetVBType( pVBInfo ) ;
- XGI_GetVBInfo( ModeNo , ModeIdIndex , pXGIHWDE, pVBInfo ) ;
- XGI_GetTVInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetLCDInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- }
-
- if ( VESA_POWER_STATE == 0x00000400 )
- XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char)(XGINew_GetReg1(pVBInfo->Part4Port, 0x31) & 0xFE));
- else
- XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char)(XGINew_GetReg1(pVBInfo->Part4Port, 0x31) | 0x01));
-
- temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x1f);
- temp &= 0x3f ;
- switch ( VESA_POWER_STATE )
- {
- case 0x00000000: /* on */
- if ( ( pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
- {
- XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x00));
- XGI_EnableBridge( pXGIHWDE, pVBInfo ) ;
- }
- else
- {
- if ( pXGIHWDE->jChipType == XG21 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
- XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
- }
- }
- if ( pXGIHWDE->jChipType == XG27 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
- XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
- }
- }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , ~0xC0 , 0x00 ) ;
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x01 , ~0x20 ) ; /* CRT on */
-
- if ( pXGIHWDE->jChipType == XG21 )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- if ( temp & 0xE0 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ; /* DVO ON */
- XGI_SetXG21FPBits( pVBInfo );
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
- /*XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~0x20 , 0x20 ) ;*/ /* LCD Display ON */
- }
- XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
- XGI_DisplayOn( pXGIHWDE, pVBInfo );
- }
- if ( pXGIHWDE->jChipType == XG27 )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- if ( temp & 0xE0 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ; /* DVO ON */
- XGI_SetXG27FPBits( pVBInfo );
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
- /*XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~0x20 , 0x20 ) ;*/ /* LCD Display ON */
- }
- XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
- XGI_DisplayOn( pXGIHWDE, pVBInfo );
- }
- }
- break ;
- case 0x00000100: /* standby */
- if ( pXGIHWDE->jChipType >= XG21 )
- {
- XGI_DisplayOff( pXGIHWDE, pVBInfo );
- }
-
- XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x40));
- break ;
- case 0x00000200: /* suspend */
- if ( pXGIHWDE->jChipType == XG21 )
- {
- XGI_DisplayOff( pXGIHWDE, pVBInfo );
- XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
- }
- if ( pXGIHWDE->jChipType == XG27 )
- {
- XGI_DisplayOff( pXGIHWDE, pVBInfo );
- XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
- }
- XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0x80));
- break ;
- case 0x00000400: /* off */
- if ( (pXGIHWDE->ujVBChipID == VB_CHIP_301 ) || ( pXGIHWDE->ujVBChipID == VB_CHIP_302 ) )
- {
- XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char)(temp | 0xc0));
- XGI_DisableBridge( pXGIHWDE, pVBInfo ) ;
- }
- else
- {
- if ( pXGIHWDE->jChipType == XG21 )
- {
- XGI_DisplayOff( pXGIHWDE, pVBInfo );
-
- XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- if ( temp & 0xE0 )
- {
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x09 , ~0x80 ) ; /* DVO Off */
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Enable write GPIOF */
- /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* LCD Display OFF */
- }
- }
- if ( pXGIHWDE->jChipType == XG27 )
- {
- XGI_DisplayOff( pXGIHWDE, pVBInfo );
-
- XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* LVDS signal off */
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- if ( temp & 0xE0 )
- {
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x09 , ~0x80 ) ; /* DVO Off */
- }
- }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , ~0xC0 , 0xC0 ) ;
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x01 , 0x20 ) ; /* CRT Off */
-
- if ( ( pXGIHWDE->jChipType == XG21 ) && ( pVBInfo->IF_DEF_LVDS == 1 ) )
- {
- XGI_XG21SetPanelDelay( 4,pVBInfo ) ;
- XGI_XG21BLSignalVDD( 0x01 , 0x00, pVBInfo ) ; /* LVDS VDD off */
- XGI_XG21SetPanelDelay( 5,pVBInfo ) ;
- }
- if ( ( pXGIHWDE->jChipType == XG27 ) && ( pVBInfo->IF_DEF_LVDS == 1 ) )
- {
- XGI_XG21SetPanelDelay( 4,pVBInfo ) ;
- XGI_XG27BLSignalVDD( 0x01 , 0x00, pVBInfo ) ; /* LVDS VDD off */
- XGI_XG21SetPanelDelay( 5,pVBInfo ) ;
- }
- }
- break ;
-
- default:
- break ;
- }
- XGI_LockCRT2( pXGIHWDE , pVBInfo ) ;
+ unsigned short ModeNo, ModeIdIndex;
+ unsigned char temp;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->BaseAddr = (unsigned long) pXGIHWDE->pjIOAddress;
+ pVBInfo->ROMAddr = pXGIHWDE->pjVirtualRomBase;
+
+ pVBInfo->IF_DEF_LVDS = 0;
+ pVBInfo->IF_DEF_CH7005 = 0;
+ pVBInfo->IF_DEF_HiVision = 1;
+ pVBInfo->IF_DEF_LCDA = 1;
+ pVBInfo->IF_DEF_CH7017 = 0;
+ pVBInfo->IF_DEF_YPbPr = 1;
+ pVBInfo->IF_DEF_CRT2Monitor = 0;
+ pVBInfo->IF_DEF_VideoCapture = 0;
+ pVBInfo->IF_DEF_ScaleLCD = 0;
+ pVBInfo->IF_DEF_OEMUtil = 0;
+ pVBInfo->IF_DEF_PWD = 0;
+
+ InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo);
+ ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo);
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ if (pXGIHWDE->jChipType == XG27) {
+ if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
+ if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
+ pVBInfo->IF_DEF_LVDS = 1;
+ }
+ }
+
+ if (pVBInfo->IF_DEF_CH7007 == 0)
+ XGINew_SetModeScratch(pXGIHWDE, pVBInfo);
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); /* 1.Openkey */
+ XGI_UnLockCRT2(pXGIHWDE, pVBInfo);
+ ModeNo = XGINew_GetReg1(pVBInfo->P3d4, 0x34);
+ XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+ XGI_GetVGAType(pXGIHWDE, pVBInfo);
+
+ if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302) || (pVBInfo->IF_DEF_CH7007 == 1)) {
+ XGI_GetVBType(pVBInfo);
+ XGI_GetVBInfo(ModeNo, ModeIdIndex, pXGIHWDE, pVBInfo);
+ XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
+ }
+
+ if (VESA_POWER_STATE == 0x00000400)
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) & 0xFE));
+ else
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) | 0x01));
+
+ temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1f);
+ temp &= 0x3f;
+ switch (VESA_POWER_STATE) {
+ case 0x00000000: /* on */
+ if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x00));
+ XGI_EnableBridge(pXGIHWDE, pVBInfo);
+ } else {
+ if (pXGIHWDE->jChipType == XG21) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+ XGI_XG21SetPanelDelay(2, pVBInfo);
+ }
+ }
+ if (pXGIHWDE->jChipType == XG27) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+ XGI_XG21SetPanelDelay(2, pVBInfo);
+ }
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0x00);
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x01, ~0x20); /* CRT on */
+
+ if (pXGIHWDE->jChipType == XG21) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ if (temp & 0xE0) {
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */
+ XGI_SetXG21FPBits(pVBInfo);
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
+ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */
+ }
+ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+ XGI_DisplayOn(pXGIHWDE, pVBInfo);
+ }
+ if (pXGIHWDE->jChipType == XG27) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ if (temp & 0xE0) {
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */
+ XGI_SetXG27FPBits(pVBInfo);
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
+ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */
+ }
+ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+ XGI_DisplayOn(pXGIHWDE, pVBInfo);
+ }
+ }
+ break;
+
+ case 0x00000100: /* standby */
+ if (pXGIHWDE->jChipType >= XG21)
+ XGI_DisplayOff(pXGIHWDE, pVBInfo);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x40));
+ break;
+
+ case 0x00000200: /* suspend */
+ if (pXGIHWDE->jChipType == XG21) {
+ XGI_DisplayOff(pXGIHWDE, pVBInfo);
+ XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
+ }
+ if (pXGIHWDE->jChipType == XG27) {
+ XGI_DisplayOff(pXGIHWDE, pVBInfo);
+ XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x80));
+ break;
+
+ case 0x00000400: /* off */
+ if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0xc0));
+ XGI_DisableBridge(pXGIHWDE, pVBInfo);
+ } else {
+ if (pXGIHWDE->jChipType == XG21) {
+ XGI_DisplayOff(pXGIHWDE, pVBInfo);
+
+ XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ if (temp & 0xE0) {
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
+ /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* LCD Display OFF */
+ }
+ }
+ if (pXGIHWDE->jChipType == XG27) {
+ XGI_DisplayOff(pXGIHWDE, pVBInfo);
+
+ XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ if (temp & 0xE0)
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0xC0);
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x01, 0x20); /* CRT Off */
+
+ if ((pXGIHWDE->jChipType == XG21) && (pVBInfo->IF_DEF_LVDS == 1)) {
+ XGI_XG21SetPanelDelay(4, pVBInfo);
+ XGI_XG21BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */
+ XGI_XG21SetPanelDelay(5, pVBInfo);
+ }
+ if ((pXGIHWDE->jChipType == XG27) && (pVBInfo->IF_DEF_LVDS == 1)) {
+ XGI_XG21SetPanelDelay(4, pVBInfo);
+ XGI_XG27BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */
+ XGI_XG21SetPanelDelay(5, pVBInfo);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ XGI_LockCRT2(pXGIHWDE, pVBInfo);
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetSenseStatus */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
{
- unsigned short tempax = 0 , tempbx , tempcx , temp ,
- P2reg0 = 0 , SenseModeNo = 0 , OutputSelect = *pVBInfo->pOutputSelect ,
- ModeIdIndex , i ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
-
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ; /* ynlai 02/27/2002 */
- tempbx = XGINew_GetReg1( pVBInfo->P3c4 , 0x1B ) ;
- tempax = ( ( tempax & 0xFE ) >> 1 ) | ( tempbx << 8 ) ;
- if ( tempax == 0x00 )
- { /* Get Panel id from DDC */
- temp = XGINew_GetLCDDDCInfo( HwDeviceExtension, pVBInfo ) ;
- if ( temp == 1 )
- { /* LCD connect */
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x39 , 0xFF , 0x01 ) ; /* set CR39 bit0="1" */
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , 0xEF , 0x00 ) ; /* clean CR37 bit4="0" */
- temp = LCDSense ;
- }
- else
- { /* LCD don't connect */
- temp = 0 ;
- }
- }
- else
- {
- XGINew_GetPanelID(pVBInfo) ;
- temp = LCDSense ;
- }
-
- tempbx = ~( LCDSense | AVIDEOSense | SVIDEOSense ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , tempbx , temp ) ;
- }
- else
- { /* for 301 */
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- { /* for HiVision */
- tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x38 ) ;
- temp = tempax & 0x01 ;
- tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) ;
- temp = temp | ( tempax & 0x02 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xA0 , temp ) ;
- }
- else
- {
- if ( XGI_BridgeIsOn( pVBInfo ) )
- {
- P2reg0 = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
- if ( !XGINew_BridgeIsEnable( HwDeviceExtension, pVBInfo ) )
- {
- SenseModeNo = 0x2e ;
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x41 ) ; */
- /* XGISetModeNew( HwDeviceExtension , 0x2e ) ; // ynlai InitMode */
-
- temp = XGI_SearchModeID( SenseModeNo , &ModeIdIndex, pVBInfo ) ;
- XGI_GetVGAType( HwDeviceExtension , pVBInfo) ;
- XGI_GetVBType( pVBInfo ) ;
- pVBInfo->SetFlag = 0x00 ;
- pVBInfo->ModeType = ModeVGA ;
- pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode ;
- XGI_GetLCDInfo( 0x2e , ModeIdIndex, pVBInfo ) ;
- XGI_GetTVInfo( 0x2e , ModeIdIndex, pVBInfo ) ;
- XGI_EnableBridge( HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT2Group301( SenseModeNo , HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT2ModeRegs( 0x2e , HwDeviceExtension, pVBInfo ) ;
- /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xDF , 0x20 ) ; /* Display Off 0212 */
- for( i = 0 ; i < 20 ; i++ )
- {
- XGI_LongWait(pVBInfo) ;
- }
- }
- XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , 0x1c ) ;
- tempax = 0 ;
- tempbx = *pVBInfo->pRGBSenseData ;
-
- if ( !( XGINew_Is301B( pVBInfo ) ) )
- {
- tempbx = *pVBInfo->pRGBSenseData2 ;
- }
-
- tempcx = 0x0E08 ;
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- tempax |= Monitor2Sense ;
- }
- }
-
- if ( pVBInfo->VBType & VB_XGI301C)
- {
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x0d , 0x04 ) ;
- }
-
- if ( XGINew_SenseHiTV( HwDeviceExtension , pVBInfo) ) /* add by kuku for Multi-adapter sense HiTV */
- {
- tempax |= HiTVSense ;
- if ( ( pVBInfo->VBType & VB_XGI301C ) )
- {
- tempax ^= ( HiTVSense | YPbPrSense ) ;
- }
- }
-
- if ( !( tempax & ( HiTVSense | YPbPrSense ) ) ) /* start */
- {
-
- tempbx = *pVBInfo->pYCSenseData ;
-
- if ( !( XGINew_Is301B( pVBInfo ) ) )
- {
- tempbx=*pVBInfo->pYCSenseData2;
- }
-
- tempcx = 0x0604 ;
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- tempax |= SVIDEOSense ;
- }
- }
-
- if ( OutputSelect & BoardTVType )
- {
- tempbx = *pVBInfo->pVideoSenseData ;
-
- if ( !( XGINew_Is301B( pVBInfo ) ) )
- {
- tempbx = *pVBInfo->pVideoSenseData2 ;
- }
-
- tempcx = 0x0804 ;
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- tempax |= AVIDEOSense ;
- }
- }
- }
- else
- {
- if ( !( tempax & SVIDEOSense ) )
- {
- tempbx = *pVBInfo->pVideoSenseData ;
-
- if ( !( XGINew_Is301B( pVBInfo ) ) )
- {
- tempbx=*pVBInfo->pVideoSenseData2;
- }
-
- tempcx = 0x0804 ;
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- if ( XGINew_Sense(tempbx , tempcx, pVBInfo ) )
- {
- tempax |= AVIDEOSense ;
- }
- }
- }
- }
- }
- } /* end */
- if ( !( tempax & Monitor2Sense ) )
- {
- if ( XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) )
- {
- tempax |= LCDSense ;
- }
- }
- tempbx = 0 ;
- tempcx = 0 ;
- XGINew_Sense(tempbx , tempcx, pVBInfo ) ;
-
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~0xDF , tempax ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , P2reg0 ) ;
-
- if ( !( P2reg0 & 0x20 ) )
- {
- pVBInfo->VBInfo = DisableCRT2Display ;
- /* XGI_SetCRT2Group301( SenseModeNo , HwDeviceExtension, pVBInfo ) ; */
- }
- }
- }
- XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; /* shampoo 0226 */
+ unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0,
+ OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */
+ tempbx = XGINew_GetReg1(pVBInfo->P3c4, 0x1B);
+ tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8);
+ if (tempax == 0x00) { /* Get Panel id from DDC */
+ temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
+ if (temp == 1) { /* LCD connect */
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */
+ temp = LCDSense;
+ } else { /* LCD don't connect */
+ temp = 0;
+ }
+ } else {
+ XGINew_GetPanelID(pVBInfo);
+ temp = LCDSense;
+ }
+
+ tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp);
+ } else { /* for 301 */
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */
+ tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x38);
+ temp = tempax & 0x01;
+ tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
+ temp = temp | (tempax & 0x02);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp);
+ } else {
+ if (XGI_BridgeIsOn(pVBInfo)) {
+ P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
+ if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) {
+ SenseModeNo = 0x2e;
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x41); */
+ /* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */
+
+ temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo);
+ XGI_GetVGAType(HwDeviceExtension, pVBInfo);
+ XGI_GetVBType(pVBInfo);
+ pVBInfo->SetFlag = 0x00;
+ pVBInfo->ModeType = ModeVGA;
+ pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode;
+ XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo);
+ XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo);
+ XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo);
+ /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */
+ for (i = 0; i < 20; i++)
+ XGI_LongWait(pVBInfo);
+ }
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1c);
+ tempax = 0;
+ tempbx = *pVBInfo->pRGBSenseData;
+
+ if (!(XGINew_Is301B(pVBInfo)))
+ tempbx = *pVBInfo->pRGBSenseData2;
+
+ tempcx = 0x0E08;
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+ tempax |= Monitor2Sense;
+ }
+
+ if (pVBInfo->VBType & VB_XGI301C)
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x0d, 0x04);
+
+ if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */
+ tempax |= HiTVSense;
+ if ((pVBInfo->VBType & VB_XGI301C))
+ tempax ^= (HiTVSense | YPbPrSense);
+ }
+
+ if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */
+
+ tempbx = *pVBInfo->pYCSenseData;
+
+ if (!(XGINew_Is301B(pVBInfo)))
+ tempbx = *pVBInfo->pYCSenseData2;
+
+ tempcx = 0x0604;
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+ tempax |= SVIDEOSense;
+ }
+
+ if (OutputSelect & BoardTVType) {
+ tempbx = *pVBInfo->pVideoSenseData;
+
+ if (!(XGINew_Is301B(pVBInfo)))
+ tempbx = *pVBInfo->pVideoSenseData2;
+
+ tempcx = 0x0804;
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+ tempax |= AVIDEOSense;
+ }
+ } else {
+ if (!(tempax & SVIDEOSense)) {
+ tempbx = *pVBInfo->pVideoSenseData;
+
+ if (!(XGINew_Is301B(pVBInfo)))
+ tempbx = *pVBInfo->pVideoSenseData2;
+
+ tempcx = 0x0804;
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
+ if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+ tempax |= AVIDEOSense;
+ }
+ }
+ }
+ }
+ } /* end */
+ if (!(tempax & Monitor2Sense)) {
+ if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo))
+ tempax |= LCDSense;
+ }
+ tempbx = 0;
+ tempcx = 0;
+ XGINew_Sense(tempbx, tempcx, pVBInfo);
+
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x00, P2reg0);
+
+ if (!(P2reg0 & 0x20)) {
+ pVBInfo->VBInfo = DisableCRT2Display;
+ /* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */
+ }
+ }
+ }
+ XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SenseLCD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
+unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
{
- /* unsigned short SoftSetting ; */
- unsigned short temp ;
+ /* unsigned short SoftSetting ; */
+ unsigned short temp;
- if ( ( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40 ) )
- temp = 0 ;
- else
- temp=XGINew_GetPanelID(pVBInfo) ;
+ if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40))
+ temp = 0;
+ else
+ temp = XGINew_GetPanelID(pVBInfo);
- if( !temp )
- temp = XGINew_GetLCDDDCInfo( HwDeviceExtension, pVBInfo ) ;
+ if (!temp)
+ temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
- return( temp ) ;
+ return temp;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_GetLCDDDCInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
{
- unsigned short temp ;
-
- /* add lcd sense */
- if ( HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN )
- {
- return( 0 ) ;
- }
- else
- {
- temp = (unsigned short)HwDeviceExtension->ulCRT2LCDType ;
- switch( HwDeviceExtension->ulCRT2LCDType )
- {
- case LCD_INVALID:
- case LCD_800x600:
- case LCD_1024x768:
- case LCD_1280x1024:
- break ;
-
- case LCD_640x480:
- case LCD_1024x600:
- case LCD_1152x864:
- case LCD_1280x960:
- case LCD_1152x768:
- temp = 0 ;
- break ;
-
- case LCD_1400x1050:
- case LCD_1280x768:
- case LCD_1600x1200:
- break ;
-
- case LCD_1920x1440:
- case LCD_2048x1536:
- temp = 0 ;
- break ;
-
- default:
- break ;
- }
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x36 , 0xF0 , temp ) ;
- return( 1 ) ;
- }
+ unsigned short temp;
+
+ /* add lcd sense */
+ if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
+ return 0;
+ } else {
+ temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
+ switch (HwDeviceExtension->ulCRT2LCDType) {
+ case LCD_INVALID:
+ case LCD_800x600:
+ case LCD_1024x768:
+ case LCD_1280x1024:
+ break;
+
+ case LCD_640x480:
+ case LCD_1024x600:
+ case LCD_1152x864:
+ case LCD_1280x960:
+ case LCD_1152x768:
+ temp = 0;
+ break;
+
+ case LCD_1400x1050:
+ case LCD_1280x768:
+ case LCD_1600x1200:
+ break;
+
+ case LCD_1920x1440:
+ case LCD_2048x1536:
+ temp = 0;
+ break;
+
+ default:
+ break;
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x36, 0xF0, temp);
+ return 1;
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo)
{
- unsigned short PanelTypeTable[16] = {
- SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType00,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
- SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType02,
- SyncNN | PanelRGB18Bit | Panel640x480 | _PanelType03,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
- SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
- SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType08,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
- SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType0A,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
- SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
- SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F };
- unsigned short tempax , tempbx, temp;
- /* unsigned short return_flag ; */
-
- tempax = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ;
- tempbx = tempax & 0x1E ;
-
- if ( tempax == 0 )
- return( 0 ) ;
- else
- {
-/*
- if ( !( tempax & 0x10 ) )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- tempbx = 0 ;
- temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x38 ) ;
- if ( temp & 0x40 )
- tempbx |= 0x08 ;
- if ( temp & 0x20 )
- tempbx |= 0x02 ;
- if ( temp & 0x01 )
- tempbx |= 0x01 ;
-
- temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) ;
- if ( temp & 0x80 )
- tempbx |= 0x04 ;
- }
- else
- {
- return( 0 ) ;
- }
- }
-*/
-
- tempbx = tempbx >> 1 ;
- temp = tempbx & 0x00F ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x36 , temp ) ;
- tempbx-- ;
- tempbx = PanelTypeTable[ tempbx ] ;
-
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~( LCDSyncBit | LCDRGB18Bit ) , temp ) ;
- return( 1 ) ;
- }
+ unsigned short PanelTypeTable[16] = { SyncNN | PanelRGB18Bit
+ | Panel800x600 | _PanelType00, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType01, SyncNN | PanelRGB18Bit
+ | Panel800x600 | _PanelType02, SyncNN | PanelRGB18Bit
+ | Panel640x480 | _PanelType03, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType04, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType05, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType06, SyncNN | PanelRGB24Bit
+ | Panel1024x768 | _PanelType07, SyncNN | PanelRGB18Bit
+ | Panel800x600 | _PanelType08, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType09, SyncNN | PanelRGB18Bit
+ | Panel800x600 | _PanelType0A, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType0B, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType0C, SyncNN | PanelRGB24Bit
+ | Panel1024x768 | _PanelType0D, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType0E, SyncNN | PanelRGB18Bit
+ | Panel1024x768 | _PanelType0F };
+ unsigned short tempax, tempbx, temp;
+ /* unsigned short return_flag; */
+
+ tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A);
+ tempbx = tempax & 0x1E;
+
+ if (tempax == 0)
+ return 0;
+ else {
+ /*
+ if (!(tempax & 0x10)) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ tempbx = 0;
+ temp = XGINew_GetReg1(pVBInfo->P3c4, 0x38);
+ if (temp & 0x40)
+ tempbx |= 0x08;
+ if (temp & 0x20)
+ tempbx |= 0x02;
+ if (temp & 0x01)
+ tempbx |= 0x01;
+
+ temp = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
+ if (temp & 0x80)
+ tempbx |= 0x04;
+ } else {
+ return(0);
+ }
+ }
+ */
+
+ tempbx = tempbx >> 1;
+ temp = tempbx & 0x00F;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x36, temp);
+ tempbx--;
+ tempbx = PanelTypeTable[tempbx];
+
+ temp = (tempbx & 0xFF00) >> 8;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~(LCDSyncBit
+ | LCDRGB18Bit), temp);
+ return 1;
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_BridgeIsEnable */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
{
- unsigned short flag ;
-
- if ( XGI_BridgeIsOn( pVBInfo ) == 0 )
- {
- flag = XGINew_GetReg1( pVBInfo->Part1Port , 0x0 ) ;
-
- if ( flag & 0x050 )
- {
- return( 1 ) ;
- }
- else
- {
- return( 0 ) ;
- }
-
- }
- return( 0 ) ;
+ unsigned short flag;
+
+ if (XGI_BridgeIsOn(pVBInfo) == 0) {
+ flag = XGINew_GetReg1(pVBInfo->Part1Port, 0x0);
+
+ if (flag & 0x050)
+ return 1;
+ else
+ return 0;
+
+ }
+ return 0;
}
-/* ------------------------------------------------------ */
-/* Function : XGINew_SenseHiTV */
-/* Input : */
-/* Output : */
-/* Description : */
-/* ------------------------------------------------------ */
unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
{
- unsigned short tempbx , tempcx , temp , i , tempch;
-
- tempbx = *pVBInfo->pYCSenseData2 ;
-
- tempcx = 0x0604 ;
-
- temp = tempbx & 0xFF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp |= ( tempcx & 0x00FF ) ;
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
-
- for( i = 0 ; i < 10 ; i++ )
- XGI_LongWait(pVBInfo) ;
-
- tempch = ( tempcx & 0xFF00 ) >> 8;
- temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
- temp = temp ^ ( 0x0E ) ;
- temp &= tempch ;
-
- if ( temp != tempch )
- return( 0 ) ;
-
- tempbx = *pVBInfo->pVideoSenseData2 ;
-
- tempcx = 0x0804 ;
- temp = tempbx & 0xFF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp |= ( tempcx & 0x00FF ) ;
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
-
- for( i = 0 ; i < 10 ; i++ )
- XGI_LongWait(pVBInfo) ;
-
- tempch = ( tempcx & 0xFF00 ) >> 8;
- temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
- temp = temp ^ ( 0x0E ) ;
- temp &= tempch ;
-
- if ( temp != tempch )
- return( 0 ) ;
- else
- {
- tempbx = 0x3FF ;
- tempcx = 0x0804 ;
- temp = tempbx & 0xFF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x11 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp |= ( tempcx & 0x00FF ) ;
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x10 , ~0x1F , temp ) ;
-
- for( i = 0 ; i < 10 ; i++ )
- XGI_LongWait(pVBInfo) ;
-
- tempch = ( tempcx & 0xFF00 ) >> 8;
- temp = XGINew_GetReg1( pVBInfo->Part4Port , 0x03 ) ;
- temp = temp ^ ( 0x0E ) ;
- temp &= tempch ;
-
- if ( temp != tempch )
- return( 1 ) ;
- else
- return( 0 ) ;
- }
+ unsigned short tempbx, tempcx, temp, i, tempch;
+
+ tempbx = *pVBInfo->pYCSenseData2;
+
+ tempcx = 0x0604;
+
+ temp = tempbx & 0xFF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp |= (tempcx & 0x00FF);
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
+
+ for (i = 0; i < 10; i++)
+ XGI_LongWait(pVBInfo);
+
+ tempch = (tempcx & 0xFF00) >> 8;
+ temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
+ temp = temp ^ (0x0E);
+ temp &= tempch;
+
+ if (temp != tempch)
+ return 0;
+
+ tempbx = *pVBInfo->pVideoSenseData2;
+
+ tempcx = 0x0804;
+ temp = tempbx & 0xFF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp |= (tempcx & 0x00FF);
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
+
+ for (i = 0; i < 10; i++)
+ XGI_LongWait(pVBInfo);
+
+ tempch = (tempcx & 0xFF00) >> 8;
+ temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
+ temp = temp ^ (0x0E);
+ temp &= tempch;
+
+ if (temp != tempch) {
+ return 0;
+ } else {
+ tempbx = 0x3FF;
+ tempcx = 0x0804;
+ temp = tempbx & 0xFF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp |= (tempcx & 0x00FF);
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
+
+ for (i = 0; i < 10; i++)
+ XGI_LongWait(pVBInfo);
+
+ tempch = (tempcx & 0xFF00) >> 8;
+ temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
+ temp = temp ^ (0x0E);
+ temp &= tempch;
+
+ if (temp != tempch)
+ return 1;
+ else
+ return 0;
+ }
}
-
-
-/*
-;-----------------------------------------------------------------------------
-; Description: Get Panel support
-; O/P :
-; BL: Panel ID=81h for no scaler LVDS
-; BH: Panel enhanced Mode Count
-; CX: Panel H. resolution
-; DX: PAnel V. resolution
-;-----------------------------------------------------------------------------
-*/
-void XGI_XG21Fun14Sub70(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
+/* ----------------------------------------------------------------------------
+ * Description: Get Panel support
+ * O/P :
+ * BL: Panel ID=81h for no scaler LVDS
+ * BH: Panel enhanced Mode Count
+ * CX: Panel H. resolution
+ * DX: PAnel V. resolution
+ * ----------------------------------------------------------------------------
+ */
+static void XGI_XG21Fun14Sub70(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
{
-
- unsigned short ModeIdIndex;
- unsigned short ModeNo;
-
- unsigned short EModeCount;
- unsigned short lvdstableindex;
-
- lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
- pBiosArguments->h.bl = 0x81;
- pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
- pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
- EModeCount = 0;
-
- pBiosArguments->x.ax = 0x0014;
- for( ModeIdIndex = 0 ; ; ModeIdIndex ++ )
- {
- ModeNo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID;
- if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID == 0xFF )
- {
- pBiosArguments->h.bh = (unsigned char) EModeCount;
- return;
- }
- if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
- {
- continue;
- }
- EModeCount++ ;
- }
+ unsigned short ModeIdIndex;
+ unsigned short ModeNo;
+
+ unsigned short EModeCount;
+ unsigned short lvdstableindex;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
+ pBiosArguments->h.bl = 0x81;
+ pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
+ pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
+ EModeCount = 0;
+
+ pBiosArguments->x.ax = 0x0014;
+ for (ModeIdIndex = 0;; ModeIdIndex++) {
+ ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID;
+ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) {
+ pBiosArguments->h.bh = (unsigned char) EModeCount;
+ return;
+ }
+ if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
+ continue;
+
+ EModeCount++;
+ }
}
-/*(
-;-----------------------------------------------------------------------------
-;
-; Description: Get Panel mode ID for enhanced mode
-; I/P : BH: EModeIndex ( which < Panel enhanced Mode Count )
-; O/P :
-; BL: Mode ID
-; CX: H. resolution of the assigned by the index
-; DX: V. resolution of the assigned by the index
-;
-;-----------------------------------------------------------------------------
-*/
-void XGI_XG21Fun14Sub71(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
+
+/* ----------------------------------------------------------------------------
+ *
+ * Description: Get Panel mode ID for enhanced mode
+ * I/P : BH: EModeIndex ( which < Panel enhanced Mode Count )
+ * O/P :
+ * BL: Mode ID
+ * CX: H. resolution of the assigned by the index
+ * DX: V. resolution of the assigned by the index
+ *
+ * ----------------------------------------------------------------------------
+ */
+
+static void XGI_XG21Fun14Sub71(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
{
- unsigned short EModeCount;
- unsigned short ModeIdIndex, resindex;
- unsigned short ModeNo;
- unsigned short EModeIndex = pBiosArguments->h.bh;
-
- EModeCount = 0;
- for( ModeIdIndex = 0 ; ; ModeIdIndex ++ )
- {
- ModeNo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID;
- if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeID == 0xFF )
- {
- pBiosArguments->x.ax = 0x0114;
- return;
- }
- if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
- {
- continue;
- }
- if (EModeCount == EModeIndex)
- {
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- pBiosArguments->h.bl = (unsigned char) ModeNo;
- pBiosArguments->x.cx = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- pBiosArguments->x.dx = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- pBiosArguments->x.ax = 0x0014;
- }
- EModeCount++ ;
-
- }
+ unsigned short EModeCount;
+ unsigned short ModeIdIndex, resindex;
+ unsigned short ModeNo;
+ unsigned short EModeIndex = pBiosArguments->h.bh;
+
+ EModeCount = 0;
+ for (ModeIdIndex = 0;; ModeIdIndex++) {
+ ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID;
+ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) {
+ pBiosArguments->x.ax = 0x0114;
+ return;
+ }
+ if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
+ continue;
+
+ if (EModeCount == EModeIndex) {
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ pBiosArguments->h.bl = (unsigned char) ModeNo;
+ pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ pBiosArguments->x.ax = 0x0014;
+ }
+ EModeCount++;
+
+ }
}
-/*
-;-----------------------------------------------------------------------------
-;
-; Description: Validate Panel modes ID support
-; I/P :
-; BL: ModeID
-; O/P :
-; CX: H. resolution of the assigned by the index
-; DX: V. resolution of the assigned by the index
-;
-;-----------------------------------------------------------------------------
-*/
-void XGI_XG21Fun14Sub72(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
+
+/* ----------------------------------------------------------------------------
+ *
+ * Description: Validate Panel modes ID support
+ * I/P :
+ * BL: ModeID
+ * O/P :
+ * CX: H. resolution of the assigned by the index
+ * DX: V. resolution of the assigned by the index
+ *
+ * ----------------------------------------------------------------------------
+ */
+static void XGI_XG21Fun14Sub72(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
{
- unsigned short ModeIdIndex, resindex;
- unsigned short ModeNo;
-
-
- ModeNo = pBiosArguments->h.bl ;
- XGI_SearchModeID( ModeNo, &ModeIdIndex, pVBInfo);
- if ( !XGI_XG21CheckLVDSMode( ModeNo , ModeIdIndex, pVBInfo) )
- {
- pBiosArguments->x.cx = 0;
- pBiosArguments->x.dx = 0;
- pBiosArguments->x.ax = 0x0114;
- return;
- }
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( ModeNo <= 0x13 )
- {
- pBiosArguments->x.cx = pVBInfo->StResInfo[ resindex ].HTotal ;
- pBiosArguments->x.dx = pVBInfo->StResInfo[ resindex ].VTotal ;
- }
- else
- {
- pBiosArguments->x.cx = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- pBiosArguments->x.dx = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- }
-
- pBiosArguments->x.ax = 0x0014;
+ unsigned short ModeIdIndex, resindex;
+ unsigned short ModeNo;
+
+ ModeNo = pBiosArguments->h.bl;
+ XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+ if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) {
+ pBiosArguments->x.cx = 0;
+ pBiosArguments->x.dx = 0;
+ pBiosArguments->x.ax = 0x0114;
+ return;
+ }
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13) {
+ pBiosArguments->x.cx = pVBInfo->StResInfo[resindex].HTotal;
+ pBiosArguments->x.dx = pVBInfo->StResInfo[resindex].VTotal;
+ } else {
+ pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ }
+
+ pBiosArguments->x.ax = 0x0014;
}
-/*
-;-----------------------------------------------------------------------------
-; Description: Get Customized Panel misc. information support
-; I/P : Select
-; to get panel horizontal timing
-; to get panel vertical timing
-; to get channel clock parameter
-; to get panel misc information
-;
-; O/P :
-; BL: for input Select = 0 ;
-; BX: *Value1 = Horizontal total
-; CX: *Value2 = Horizontal front porch
-; DX: *Value2 = Horizontal sync width
-; BL: for input Select = 1 ;
-; BX: *Value1 = Vertical total
-; CX: *Value2 = Vertical front porch
-; DX: *Value2 = Vertical sync width
-; BL: for input Select = 2 ;
-; BX: Value1 = The first CLK parameter
-; CX: Value2 = The second CLK parameter
-; BL: for input Select = 4 ;
-; BX[15]: *Value1 D[15] VESA V. Polarity
-; BX[14]: *Value1 D[14] VESA H. Polarity
-; BX[7]: *Value1 D[7] Panel V. Polarity
-; BX[6]: *Value1 D[6] Panel H. Polarity
-;-----------------------------------------------------------------------------
-*/
-void XGI_XG21Fun14Sub73(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
+/* ----------------------------------------------------------------------------
+ *
+ * Description: Get Customized Panel misc. information support
+ * I/P : Select
+ * to get panel horizontal timing
+ * to get panel vertical timing
+ * to get channel clock parameter
+ * to get panel misc information
+ *
+ * O/P :
+ * BL: for input Select = 0 ;
+ * BX: *Value1 = Horizontal total
+ * CX: *Value2 = Horizontal front porch
+ * DX: *Value2 = Horizontal sync width
+ * BL: for input Select = 1 ;
+ * BX: *Value1 = Vertical total
+ * CX: *Value2 = Vertical front porch
+ * DX: *Value2 = Vertical sync width
+ * BL: for input Select = 2 ;
+ * BX: Value1 = The first CLK parameter
+ * CX: Value2 = The second CLK parameter
+ * BL: for input Select = 4 ;
+ * BX[15]: *Value1 D[15] VESA V. Polarity
+ * BX[14]: *Value1 D[14] VESA H. Polarity
+ * BX[7]: *Value1 D[7] Panel V. Polarity
+ * BX[6]: *Value1 D[6] Panel H. Polarity
+ * ----------------------------------------------------------------------------
+ */
+static void XGI_XG21Fun14Sub73(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
{
- unsigned char Select;
-
- unsigned short lvdstableindex;
-
- lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
- Select = pBiosArguments->h.bl;
-
- switch (Select)
- {
- case 0:
- pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
- pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
- pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
- break;
- case 1:
- pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
- pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
- pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
- break;
- case 2:
- pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1;
- pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2;
- break;
- case 4:
- pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability;
- break;
- }
-
- pBiosArguments->x.ax = 0x0014;
+ unsigned char Select;
+
+ unsigned short lvdstableindex;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
+ Select = pBiosArguments->h.bl;
+
+ switch (Select) {
+ case 0:
+ pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
+ pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
+ pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
+ break;
+ case 1:
+ pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
+ pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
+ pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
+ break;
+ case 2:
+ pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1;
+ pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2;
+ break;
+ case 4:
+ pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability;
+ break;
+ }
+
+ pBiosArguments->x.ax = 0x0014;
}
-
void XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments)
{
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
-
- pVBInfo->IF_DEF_LVDS = 0 ;
- pVBInfo->IF_DEF_CH7005 = 0 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_LCDA = 1 ;
- pVBInfo->IF_DEF_CH7017 = 0 ;
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- pVBInfo->IF_DEF_VideoCapture = 0 ;
- pVBInfo->IF_DEF_ScaleLCD = 0 ;
- pVBInfo->IF_DEF_OEMUtil = 0 ;
- pVBInfo->IF_DEF_PWD = 0 ;
-
- InitTo330Pointer( pXGIHWDE->jChipType, pVBInfo ) ;
- ReadVBIOSTablData( pXGIHWDE->jChipType , pVBInfo) ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- switch(pBiosArguments->x.ax)
- {
- case 0x1470:
- XGI_XG21Fun14Sub70( pVBInfo , pBiosArguments ) ;
- break;
- case 0x1471:
- XGI_XG21Fun14Sub71( pVBInfo , pBiosArguments ) ;
- break;
- case 0x1472:
- XGI_XG21Fun14Sub72( pVBInfo , pBiosArguments ) ;
- break;
- case 0x1473:
- XGI_XG21Fun14Sub73( pVBInfo , pBiosArguments ) ;
- break;
- }
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+
+ pVBInfo->IF_DEF_LVDS = 0;
+ pVBInfo->IF_DEF_CH7005 = 0;
+ pVBInfo->IF_DEF_HiVision = 1;
+ pVBInfo->IF_DEF_LCDA = 1;
+ pVBInfo->IF_DEF_CH7017 = 0;
+ pVBInfo->IF_DEF_YPbPr = 1;
+ pVBInfo->IF_DEF_CRT2Monitor = 0;
+ pVBInfo->IF_DEF_VideoCapture = 0;
+ pVBInfo->IF_DEF_ScaleLCD = 0;
+ pVBInfo->IF_DEF_OEMUtil = 0;
+ pVBInfo->IF_DEF_PWD = 0;
+
+ InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo);
+ ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo);
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ switch (pBiosArguments->x.ax) {
+ case 0x1470:
+ XGI_XG21Fun14Sub70(pVBInfo, pBiosArguments);
+ break;
+ case 0x1471:
+ XGI_XG21Fun14Sub71(pVBInfo, pBiosArguments);
+ break;
+ case 0x1472:
+ XGI_XG21Fun14Sub72(pVBInfo, pBiosArguments);
+ break;
+ case 0x1473:
+ XGI_XG21Fun14Sub73(pVBInfo, pBiosArguments);
+ break;
+ }
}
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index e02722d05f68..8d591828cee5 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -15,10 +15,7 @@
#include <asm/io.h>
-
-
-
-unsigned char XGINew_ChannelAB, XGINew_DataBusWidth;
+static unsigned char XGINew_ChannelAB, XGINew_DataBusWidth;
unsigned short XGINew_DRAMType[17][5] = {
{0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48},
@@ -31,7 +28,7 @@ unsigned short XGINew_DRAMType[17][5] = {
{0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10},
{0x09, 0x08, 0x01, 0x01, 0x00} };
-unsigned short XGINew_SDRDRAM_TYPE[13][5] = {
+static unsigned short XGINew_SDRDRAM_TYPE[13][5] = {
{ 2, 12, 9, 64, 0x35},
{ 1, 13, 9, 64, 0x44},
{ 2, 12, 8, 32, 0x31},
@@ -46,19 +43,19 @@ unsigned short XGINew_SDRDRAM_TYPE[13][5] = {
{ 1, 10, 8, 4, 0x10},
{ 1, 9, 8, 2, 0x00} };
-unsigned short XGINew_DDRDRAM_TYPE[4][5] = {
+static unsigned short XGINew_DDRDRAM_TYPE[4][5] = {
{ 2, 12, 9, 64, 0x35},
{ 2, 12, 8, 32, 0x31},
{ 2, 11, 8, 16, 0x21},
{ 2, 9, 8, 4, 0x01} };
-unsigned short XGINew_DDRDRAM_TYPE340[4][5] = {
+static unsigned short XGINew_DDRDRAM_TYPE340[4][5] = {
{ 2, 13, 9, 64, 0x45},
{ 2, 12, 9, 32, 0x35},
{ 2, 12, 8, 16, 0x31},
{ 2, 11, 8, 8, 0x21} };
-unsigned short XGINew_DDRDRAM_TYPE20[12][5] = {
+static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = {
{ 2, 14, 11, 128, 0x5D},
{ 2, 14, 10, 64, 0x59},
{ 2, 13, 11, 64, 0x4D},
@@ -89,8 +86,10 @@ void XGINew_CheckBusWidth_310(struct vb_device_info *) ;
int XGINew_SDRSizing(struct vb_device_info *);
int XGINew_DDRSizing(struct vb_device_info *);
void XGINew_EnableRefresh(struct xgi_hw_device_info *, struct vb_device_info *);
-int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
-unsigned long UNIROM; /* UNIROM */
+static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
+#if 0
+static unsigned long UNIROM;
+#endif
unsigned char ChkLFB(struct vb_device_info *);
void XGINew_Delay15us(unsigned long);
void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
@@ -106,2536 +105,2073 @@ unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo);
void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo);
-void DelayUS(unsigned long MicroSeconds)
+static void DelayUS(unsigned long MicroSeconds)
{
udelay(MicroSeconds);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGIInitNew */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension)
{
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ unsigned char i, temp = 0, temp1;
+ /* VBIOSVersion[5]; */
+ volatile unsigned char *pVideoMemory;
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- unsigned char i, temp = 0, temp1 ;
- // VBIOSVersion[ 5 ] ;
- volatile unsigned char *pVideoMemory;
+ /* unsigned long j, k; */
- /* unsigned long j, k ; */
+ struct XGI_DSReg *pSR;
- struct XGI_DSReg *pSR ;
+ unsigned long Temp;
- unsigned long Temp ;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
+ pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
- pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
+ /* Newdebugcode(0x99); */
-// Newdebugcode( 0x99 ) ;
+ /* if (pVBInfo->ROMAddr == 0) */
+ /* return(0); */
+ if (pVBInfo->FBAddr == NULL) {
+ printk("\n pVBInfo->FBAddr == 0 ");
+ return 0;
+ }
+ printk("1");
+ if (pVBInfo->BaseAddr == 0) {
+ printk("\npVBInfo->BaseAddr == 0 ");
+ return 0;
+ }
+ printk("2");
- /* if ( pVBInfo->ROMAddr == 0 ) */
- /* return( 0 ) ; */
+ XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */
- if (pVBInfo->FBAddr == 0) {
- printk("\n pVBInfo->FBAddr == 0 ");
- return 0;
- }
-printk("1");
-if (pVBInfo->BaseAddr == 0) {
- printk("\npVBInfo->BaseAddr == 0 ");
- return 0;
-}
-printk("2");
+ pVBInfo->ISXPDOS = 0;
+ printk("3");
- XGINew_SetReg3( ( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
+ if (!HwDeviceExtension->bIntegratedMMEnabled)
+ return 0; /* alan */
- pVBInfo->ISXPDOS = 0 ;
-printk("3");
+ printk("4");
-if ( !HwDeviceExtension->bIntegratedMMEnabled )
- return 0; /* alan */
+ /* VBIOSVersion[4] = 0x0; */
-printk("4");
+ /* 09/07/99 modify by domao */
- // VBIOSVersion[ 4 ] = 0x0 ;
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+ printk("5");
- /* 09/07/99 modify by domao */
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-printk("5");
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
-
- InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
-
- /* ReadVBIOSData */
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- /* 1.Openkey */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
-printk("6");
-
- /* GetXG21Sense (GPIO) */
- if ( HwDeviceExtension->jChipType == XG21 )
- {
- XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo) ;
- }
- if ( HwDeviceExtension->jChipType == XG27 )
- {
- XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo) ;
- }
-printk("7");
-
- /* 2.Reset Extended register */
-
- for( i = 0x06 ; i < 0x20 ; i++ )
- XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
-
- for( i = 0x21 ; i <= 0x27 ; i++ )
- XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
-
- /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
- /* XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ; */
-
-printk("8");
-
- if(( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
- {
- for( i = 0x31 ; i <= 0x3B ; i++ )
- XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
- }
- else
- {
- for( i = 0x31 ; i <= 0x3D ; i++ )
- XGINew_SetReg1( pVBInfo->P3c4 , i , 0 ) ;
- }
-printk("9");
-
- if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
-
- /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
- /* XGINew_SetReg1( pVBInfo->P3d4 , i , 0 ) ; */
-
- for( i = 0x79 ; i <= 0x7C ; i++ )
- XGINew_SetReg1( pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
-
-printk("10");
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x97 , *pVBInfo->pXGINew_CR97 ) ;
-
- /* 3.SetMemoryClock
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo) ;
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ; */
-
-printk("11");
-
- /* 4.SetDefExt1Regs begin */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x07 , *pVBInfo->pSR07 ) ;
- if ( HwDeviceExtension->jChipType == XG27 )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x40 , *pVBInfo->pSR40 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x41 , *pVBInfo->pSR41 ) ;
- }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x11 , 0x0F ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , *pVBInfo->pSR1F ) ;
- /* XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0x20 ) ; */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x20 , 0xA0 ) ; /* alan, 2001/6/26 Frame buffer can read/write SR20 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x36 , 0x70 ) ; /* Hsuan, 2006/01/01 H/W request for slow corner chip */
- if ( HwDeviceExtension->jChipType == XG27 ) /* Alan 12/07/2006 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x36 , *pVBInfo->pSR36 ) ;
-
- /* SR11 = 0x0F ; */
- /* XGINew_SetReg1( pVBInfo->P3c4 , 0x11 , SR11 ) ; */
-
-printk("12");
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- {
-// /* Set AGP Rate */
-// temp1 = XGINew_GetReg1( pVBInfo->P3c4 , 0x3B ) ;
-// temp1 &= 0x02 ;
-// if ( temp1 == 0x02 )
-// {
-// XGINew_SetReg4( 0xcf8 , 0x80000000 ) ;
-// ChipsetID = XGINew_GetReg3( 0x0cfc ) ;
-// XGINew_SetReg4( 0xcf8 , 0x8000002C ) ;
-// VendorID = XGINew_GetReg3( 0x0cfc ) ;
-// VendorID &= 0x0000FFFF ;
-// XGINew_SetReg4( 0xcf8 , 0x8001002C ) ;
-// GraphicVendorID = XGINew_GetReg3( 0x0cfc ) ;
-// GraphicVendorID &= 0x0000FFFF;
-//
-// if ( ChipsetID == 0x7301039 )
-/// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x09 ) ;
-//
-// ChipsetID &= 0x0000FFFF ;
-///
-// if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
-// {
-// if ( ChipsetID == 0x1106 )
-// {
-// if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
-// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0D ) ;
-// else
-// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0B ) ;
-// }
-// else
-// XGINew_SetReg1( pVBInfo->P3d4 , 0x5F , 0x0B ) ;
-// }
-// }
-
-printk("13");
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- {
- /* Set AGP customize registers (in SetDefAGPRegs) Start */
- for( i = 0x47 ; i <= 0x4C ; i++ )
- XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
-
- for( i = 0x70 ; i <= 0x71 ; i++ )
- XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
-
- for( i = 0x74 ; i <= 0x77 ; i++ )
- XGINew_SetReg1( pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
- /* Set AGP customize registers (in SetDefAGPRegs) End */
- /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
-// XGINew_SetReg4( 0xcf8 , 0x80000000 ) ;
-// ChipsetID = XGINew_GetReg3( 0x0cfc ) ;
-// if ( ChipsetID == 0x25308086 )
-// XGINew_SetReg1( pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
-
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
- Temp >>= 20 ;
- Temp &= 0xF ;
-
- if ( Temp == 1 )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
- }
-printk("14");
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
- } /* != XG20 */
-
- /* Set PCI */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x23 , *pVBInfo->pSR23 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x24 , *pVBInfo->pSR24 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x25 , pVBInfo->SR25[ 0 ] ) ;
-printk("15");
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- {
- /* Set VB */
- XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
- XGINew_SetRegANDOR( pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , 0x00 ) ;
- temp1 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
- temp = (unsigned char)((temp1 >> 4) & 0x0F);
-
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x02 , ( *pVBInfo->pCRT2Data_1_2 ) ) ;
-
-printk("16");
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
- } /* != XG20 */
-
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x27 , 0x1F ) ;
-
- if ( ( HwDeviceExtension->jChipType == XG42 ) && XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo) != 0 ) /* Not DDR */
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , ( *pVBInfo->pSR31 & 0x3F ) | 0x40 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , ( *pVBInfo->pSR32 & 0xFC ) | 0x01 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , *pVBInfo->pSR31 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , *pVBInfo->pSR32 ) ;
- }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x33 , *pVBInfo->pSR33 ) ;
-printk("17");
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+ XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
-/*
- if ( HwDeviceExtension->jChipType >= XG40 )
- SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4); */
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- {
- if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , 0x00 , 0x1C ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0D , *pVBInfo->pCRT2Data_4_D ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0E , *pVBInfo->pCRT2Data_4_E ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x10 , *pVBInfo->pCRT2Data_4_10 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0F , 0x3F ) ;
- }
-
- XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
- }
- } /* != XG20 */
-printk("18");
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x83 , 0x00 ) ;
-printk("181");
-
-if (HwDeviceExtension->bSkipSense == 0) {
- printk("182");
-
- XGI_SenseCRT1(pVBInfo) ;
-
- printk("183");
- /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
- pVBInfo->IF_DEF_CH7007 = 0;
- if ( ( HwDeviceExtension->jChipType == XG21 ) && (pVBInfo->IF_DEF_CH7007) )
- {
-printk("184");
- XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
-printk("185");
-
- }
- if ( HwDeviceExtension->jChipType == XG21 )
- {
-printk("186");
-
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
- temp = GetXG21FPBits( pVBInfo ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~0x01, temp ) ;
-printk("187");
-
- }
- if ( HwDeviceExtension->jChipType == XG27 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
- temp = GetXG27FPBits( pVBInfo ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x37 , ~0x03, temp ) ;
- }
- }
-printk("19");
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- {
- if ( HwDeviceExtension->jChipType >= XG40 )
- {
- XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
- }
-
- XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
-
- if (HwDeviceExtension->bSkipDramSizing == 1) {
- pSR = HwDeviceExtension->pSR ;
- if ( pSR!=NULL )
- {
- while( pSR->jIdx != 0xFF )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
- pSR++ ;
- }
- }
- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
- } /* SkipDramSizing */
- else
- {
-{
-printk("20");
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
- XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
-}
-printk("21");
+ /* ReadVBIOSData */
+ ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
- }
- } /* XG40 */
+ /* 1.Openkey */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
+ printk("6");
-printk("22");
+ /* GetXG21Sense (GPIO) */
+ if (HwDeviceExtension->jChipType == XG21)
+ XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
- /* SetDefExt2Regs begin */
-/*
- AGP = 1 ;
- temp =(unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x3A) ;
- temp &= 0x30 ;
- if ( temp == 0x30 )
- AGP = 0 ;
-
- if ( AGP == 0 )
- *pVBInfo->pSR21 &= 0xEF ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , *pVBInfo->pSR21 ) ;
- if ( AGP == 1 )
- *pVBInfo->pSR22 &= 0x20 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , *pVBInfo->pSR22 ) ;
-*/
+ printk("7");
-// base = 0x80000000 ;
-// OutPortLong( 0xcf8 , base ) ;
-// Temp = ( InPortLong( 0xcfc ) & 0xFFFF ) ;
-// if ( Temp == 0x1039 )
-// {
- XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char)((*pVBInfo->pSR22) & 0xFE));
-// }
-// else
-// {
-// XGINew_SetReg1( pVBInfo->P3c4 , 0x22 , *pVBInfo->pSR22 ) ;
-// }
+ /* 2.Reset Extended register */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , *pVBInfo->pSR21 ) ;
+ for (i = 0x06; i < 0x20; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, i, 0);
-printk("23");
+ for (i = 0x21; i <= 0x27; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+ /* for(i = 0x06; i <= 0x27; i++) */
+ /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */
- XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
+ printk("8");
-printk("24");
+ if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) {
+ for (i = 0x31; i <= 0x3B; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+ } else {
+ for (i = 0x31; i <= 0x3D; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, i, 0);
+ }
+ printk("9");
+ if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0);
-XGINew_SetReg1( pVBInfo->P3d4 , 0x8c , 0x87);
-XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x31);
-printk("25");
+ /* for (i = 0x30; i <= 0x3F; i++) */
+ /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */
-return 1;
-} /* end of init */
+ for (i = 0x79; i <= 0x7C; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */
+
+ printk("10");
+ if (HwDeviceExtension->jChipType >= XG20)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97);
+ /* 3.SetMemoryClock
+ if (HwDeviceExtension->jChipType >= XG40)
+ XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ if (HwDeviceExtension->jChipType < XG40)
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); */
+
+ printk("11");
+
+ /* 4.SetDefExt1Regs begin */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07);
+ if (HwDeviceExtension->jChipType == XG27) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41);
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F);
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */
+ if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36);
+
+ /* SR11 = 0x0F; */
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */
+
+ printk("12");
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ /* Set AGP Rate */
+ /*
+ temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
+ temp1 &= 0x02;
+ if (temp1 == 0x02) {
+ XGINew_SetReg4(0xcf8, 0x80000000);
+ ChipsetID = XGINew_GetReg3(0x0cfc);
+ XGINew_SetReg4(0xcf8, 0x8000002C);
+ VendorID = XGINew_GetReg3(0x0cfc);
+ VendorID &= 0x0000FFFF;
+ XGINew_SetReg4(0xcf8, 0x8001002C);
+ GraphicVendorID = XGINew_GetReg3(0x0cfc);
+ GraphicVendorID &= 0x0000FFFF;
+
+ if (ChipsetID == 0x7301039)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09);
+
+ ChipsetID &= 0x0000FFFF;
+
+ if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) {
+ if (ChipsetID == 0x1106) {
+ if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019))
+ XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D);
+ else
+ XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
+ } else {
+ XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
+ }
+ }
+ }
+ */
+
+ printk("13");
+
+ if (HwDeviceExtension->jChipType >= XG40) {
+ /* Set AGP customize registers (in SetDefAGPRegs) Start */
+ for (i = 0x47; i <= 0x4C; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]);
+
+ for (i = 0x70; i <= 0x71; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]);
+
+ for (i = 0x74; i <= 0x77; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]);
+ /* Set AGP customize registers (in SetDefAGPRegs) End */
+ /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
+ /* XGINew_SetReg4(0xcf8 , 0x80000000); */
+ /* ChipsetID = XGINew_GetReg3(0x0cfc); */
+ /* if (ChipsetID == 0x25308086) */
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */
+
+ HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */
+ Temp >>= 20;
+ Temp &= 0xF;
+
+ if (Temp == 1)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
+ }
+ printk("14");
+
+ if (HwDeviceExtension->jChipType < XG40)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]);
+ } /* != XG20 */
+
+ /* Set PCI */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
+ printk("15");
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ /* Set VB */
+ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+ XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00);
+ temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
+ temp = (unsigned char) ((temp1 >> 4) & 0x0F);
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2));
+
+ printk("16");
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
+ } /* != XG20 */
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F);
+
+ if ((HwDeviceExtension->jChipType == XG42)
+ && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01);
+ } else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32);
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33);
+ printk("17");
+
+ /*
+ if (HwDeviceExtension->jChipType >= XG40)
+ SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4); */
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ if (XGI_BridgeIsOn(pVBInfo) == 1) {
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F);
+ }
+
+ XGI_LockCRT2(HwDeviceExtension, pVBInfo);
+ }
+ } /* != XG20 */
+ printk("18");
+
+ if (HwDeviceExtension->jChipType < XG40)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00);
+ printk("181");
+
+ if (HwDeviceExtension->bSkipSense == 0) {
+ printk("182");
+
+ XGI_SenseCRT1(pVBInfo);
+
+ printk("183");
+ /* XGINew_DetectMonitor(HwDeviceExtension); */
+ pVBInfo->IF_DEF_CH7007 = 0;
+ if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) {
+ printk("184");
+ XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */
+ printk("185");
+
+ }
+ if (HwDeviceExtension->jChipType == XG21) {
+ printk("186");
+
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+ temp = GetXG21FPBits(pVBInfo);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp);
+ printk("187");
+
+ }
+ if (HwDeviceExtension->jChipType == XG27) {
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+ temp = GetXG27FPBits(pVBInfo);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp);
+ }
+ }
+ printk("19");
+
+ if (HwDeviceExtension->jChipType >= XG40) {
+ if (HwDeviceExtension->jChipType >= XG40)
+ XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+
+ XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo);
+
+ if (HwDeviceExtension->bSkipDramSizing == 1) {
+ pSR = HwDeviceExtension->pSR;
+ if (pSR != NULL) {
+ while (pSR->jIdx != 0xFF) {
+ XGINew_SetReg1(pVBInfo->P3c4, pSR->jIdx, pSR->jVal);
+ pSR++;
+ }
+ }
+ /* XGINew_SetDRAMModeRegister340(pVBInfo); */
+ } /* SkipDramSizing */
+ else {
+ {
+ printk("20");
+ XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
+ }
+ printk("21");
+
+ }
+ } /* XG40 */
+
+ printk("22");
+
+ /* SetDefExt2Regs begin */
+ /*
+ AGP = 1;
+ temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
+ temp &= 0x30;
+ if (temp == 0x30)
+ AGP = 0;
+
+ if (AGP == 0)
+ *pVBInfo->pSR21 &= 0xEF;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
+ if (AGP == 1)
+ *pVBInfo->pSR22 &= 0x20;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22);
+ */
+ /* base = 0x80000000; */
+ /* OutPortLong(0xcf8, base); */
+ /* Temp = (InPortLong(0xcfc) & 0xFFFF); */
+ /* if (Temp == 0x1039) { */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
+ /* } else { */
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */
+ /* } */
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
+
+ printk("23");
+
+ XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
+ XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
+
+ printk("24");
+
+ XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31);
+ printk("25");
+
+ return 1;
+} /* end of init */
/* ============== alan ====================== */
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_GetXG20DRAMType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
+ struct vb_device_info *pVBInfo)
{
- unsigned char data, temp;
-
- if ( HwDeviceExtension->jChipType < XG20 )
- {
- if ( *pVBInfo->pSoftSetting & SoftDRAMType )
- {
- data = *pVBInfo->pSoftSetting & 0x07 ;
- return( data ) ;
- }
- else
- {
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) & 0x02 ;
-
- if ( data == 0 )
- data = ( XGINew_GetReg1( pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
-
- return( data ) ;
- }
- }
- else if ( HwDeviceExtension->jChipType == XG27 )
- {
- if ( *pVBInfo->pSoftSetting & SoftDRAMType )
- {
- data = *pVBInfo->pSoftSetting & 0x07 ;
- return( data ) ;
- }
- temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3B ) ;
-
- if (( temp & 0x88 )==0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
- data = 0 ; /*DDR*/
- else
- data = 1 ; /*DDRII*/
- return( data ) ;
- }
- else if ( HwDeviceExtension->jChipType == XG21 )
- {
- XGINew_SetRegAND( pVBInfo->P3d4 , 0xB4 , ~0x02 ) ; /* Independent GPIO control */
- DelayUS(800);
- XGINew_SetRegOR( pVBInfo->P3d4 , 0x4A , 0x80 ) ; /* Enable GPIOH read */
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ; /* GPIOF 0:DVI 1:DVO */
-// HOTPLUG_SUPPORT
-// for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily
- if ( temp & 0x01 ) /* DVI read GPIOH */
- data = 1 ; /*DDRII*/
- else
- data = 0 ; /*DDR*/
-//~HOTPLUG_SUPPORT
- XGINew_SetRegOR( pVBInfo->P3d4 , 0xB4 , 0x02 ) ;
- return( data ) ;
- }
- else
- {
- data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) & 0x01 ;
-
- if ( data == 1 )
- data ++ ;
-
- return( data );
- }
+ unsigned char data, temp;
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ if (*pVBInfo->pSoftSetting & SoftDRAMType) {
+ data = *pVBInfo->pSoftSetting & 0x07;
+ return data;
+ } else {
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02;
+
+ if (data == 0)
+ data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1;
+
+ return data;
+ }
+ } else if (HwDeviceExtension->jChipType == XG27) {
+ if (*pVBInfo->pSoftSetting & SoftDRAMType) {
+ data = *pVBInfo->pSoftSetting & 0x07;
+ return data;
+ }
+ temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
+
+ if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+ data = 0; /* DDR */
+ else
+ data = 1; /* DDRII */
+ return data;
+ } else if (HwDeviceExtension->jChipType == XG21) {
+ XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */
+ DelayUS(800);
+ XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */
+ /* HOTPLUG_SUPPORT */
+ /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
+ if (temp & 0x01) /* DVI read GPIOH */
+ data = 1; /* DDRII */
+ else
+ data = 0; /* DDR */
+ /* ~HOTPLUG_SUPPORT */
+ XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02);
+ return data;
+ } else {
+ data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01;
+
+ if (data == 1)
+ data++;
+
+ return data;
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Get310DRAMType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGINew_Get310DRAMType(struct vb_device_info *pVBInfo)
+static unsigned char XGINew_Get310DRAMType(struct vb_device_info *pVBInfo)
{
- unsigned char data ;
+ unsigned char data;
- /* index = XGINew_GetReg1( pVBInfo->P3c4 , 0x1A ) ; */
- /* index &= 07 ; */
+ /* index = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); */
+ /* index &= 07; */
- if ( *pVBInfo->pSoftSetting & SoftDRAMType )
- data = *pVBInfo->pSoftSetting & 0x03 ;
- else
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3a ) & 0x03 ;
+ if (*pVBInfo->pSoftSetting & SoftDRAMType)
+ data = *pVBInfo->pSoftSetting & 0x03;
+ else
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x3a) & 0x03;
- return( data ) ;
+ return data;
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Delay15us */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
/*
void XGINew_Delay15us(unsigned long ulMicrsoSec)
{
}
*/
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SDR_MRS */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SDR_MRS(struct vb_device_info *pVBInfo)
+static void XGINew_SDR_MRS(struct vb_device_info *pVBInfo)
{
- unsigned short data ;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
- data &= 0x3F ; /* SR16 D7=0,D6=0 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
- /* XGINew_Delay15us( 0x100 ) ; */
- data |= 0x80 ; /* SR16 D7=1,D6=0 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
- /* XGINew_Delay15us( 0x100 ) ; */
+ unsigned short data;
+
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x16);
+ data &= 0x3F; /* SR16 D7=0,D6=0 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) low */
+ /* XGINew_Delay15us(0x100); */
+ data |= 0x80; /* SR16 D7=1,D6=0 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) high */
+ /* XGINew_Delay15us(0x100); */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_MRS_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
+static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
- XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
-
- if ( *pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C ) /* Samsung F Die */
- {
- DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
- }
-
- DelayUS( 60 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
- XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
- DelayUS( 1000 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
- XGINew_SetReg1( P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
-}
+ XGINew_SetReg1(P3c4, 0x18, 0x01);
+ XGINew_SetReg1(P3c4, 0x19, 0x20);
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+
+ if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */
+ DelayUS(3000); /* Delay 67 x 3 Delay15us */
+ XGINew_SetReg1(P3c4, 0x18, 0x00);
+ XGINew_SetReg1(P3c4, 0x19, 0x20);
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+ }
+ DelayUS(60);
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ XGINew_SetReg1(P3c4, 0x19, 0x01);
+ XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]);
+ XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]);
+ DelayUS(1000);
+ XGINew_SetReg1(P3c4, 0x1B, 0x03);
+ DelayUS(500);
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ XGINew_SetReg1(P3c4, 0x19, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]);
+ XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00);
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2x_MRS_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
+static void XGINew_DDR2x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x19 , 0x20 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 60 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
- XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
- DelayUS( 1000 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
+ XGINew_SetReg1(P3c4, 0x18, 0x00);
+ XGINew_SetReg1(P3c4, 0x19, 0x20);
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+ DelayUS(60);
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ /* XGINew_SetReg1(P3c4 ,0x18 ,0x31); */
+ XGINew_SetReg1(P3c4, 0x19, 0x01);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+ DelayUS(1000);
+ XGINew_SetReg1(P3c4, 0x1B, 0x03);
+ DelayUS(500);
+ /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ XGINew_SetReg1(P3c4, 0x19, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDRII_Bootup_XG27 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDRII_Bootup_XG27(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long P3c4, struct vb_device_info *pVBInfo)
+static void XGINew_DDRII_Bootup_XG27(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- unsigned long P3d4 = P3c4 + 0x10 ;
- XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- /* Set Double Frequency */
- /* XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; */ /* CR97 */
- XGINew_SetReg1( P3d4 , 0x97 , *pVBInfo->pXGINew_CR97 ) ; /* CR97 */
-
- DelayUS( 200 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS2
- XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS3
- XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
- DelayUS( 15) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS1
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ //MRS, DLL Enable
- XGINew_SetReg1( P3c4 , 0x19 , 0x0A ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ; /* Set SR16 */
- /* DelayUS( 15 ) ; */
-
- XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* Set SR1B */
- DelayUS( 60 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* Set SR1B */
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ //MRS, DLL Reset
- XGINew_SetReg1( P3c4 , 0x19 , 0x08 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
-
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x80 ) ; /* Set SR18 */ //MRS, ODT
- XGINew_SetReg1( P3c4 , 0x19 , 0x46 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ //EMRS
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
- XGINew_SetReg1( P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
- DelayUS( 15 ) ;
-
- XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* Set SR1B refresh control 000:close; 010:open */
- DelayUS( 200 ) ;
-
+ unsigned long P3d4 = P3c4 + 0x10;
+ XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+
+ /* Set Double Frequency */
+ /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */
+ XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */
+
+ DelayUS(200);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
+ XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+ DelayUS(15);
+ XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
+ XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+ DelayUS(15);
+ XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
+ XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+ XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */
+ /* DelayUS(15); */
+
+ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */
+ DelayUS(60);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */
+
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
+ XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
+
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
+ XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
+ XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
+ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
+ DelayUS(15);
+
+ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */
+ DelayUS(200);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2_MRS_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long P3c4, struct vb_device_info *pVBInfo)
+
+static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- unsigned long P3d4 = P3c4 + 0x10 ;
-
- XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; /* CR97 */
-
- DelayUS( 200 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
- XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
-
- // XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ; /* MRS1 */
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x02 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
-
- DelayUS( 15 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* SR1B */
- DelayUS( 100 ) ;
-
- //XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ; /* MRS2 */
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x05 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x85 ) ;
-
- DelayUS( 200 ) ;
+ unsigned long P3d4 = P3c4 + 0x10;
+
+ XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+
+ XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
+
+ DelayUS(200);
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
+ XGINew_SetReg1(P3c4, 0x19, 0x80);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
+ XGINew_SetReg1(P3c4, 0x19, 0xC0);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x40);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+
+ /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x02);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+
+ DelayUS(15);
+ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
+ DelayUS(100);
+
+ /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x05);
+ XGINew_SetReg1(P3c4, 0x16, 0x85);
+
+ DelayUS(200);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2_MRS_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2_MRS_XG27(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long P3c4, struct vb_device_info *pVBInfo)
+#if 0
+static void XGINew_DDR2_MRS_XG27(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- unsigned long P3d4 = P3c4 + 0x10 ;
-
- XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; /* CR97 */
- DelayUS( 200 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x80 ) ;
+ unsigned long P3d4 = P3c4 + 0x10;
- XGINew_SetReg1( P3c4 , 0x16 , 0x10 ) ;
- DelayUS( 15 ) ; ////06/11/23 XG27 A0 for CKE enable
- XGINew_SetReg1( P3c4 , 0x16 , 0x90 ) ;
+ XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ XGINew_SetMemoryClock(HwDeviceExtension , pVBInfo);
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
- XGINew_SetReg1( P3c4 , 0x19 , 0xC0 ) ;
+ XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
+ DelayUS(200);
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
+ XGINew_SetReg1(P3c4, 0x19, 0x80);
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 15 ) ; ////06/11/22 XG27 A0
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x16, 0x10);
+ DelayUS(15); /* 06/11/23 XG27 A0 for CKE enable */
+ XGINew_SetReg1(P3c4, 0x16, 0x90);
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
+ XGINew_SetReg1(P3c4, 0x19, 0xC0);
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(15); /* 06/11/22 XG27 A0 */
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 15 ) ; ////06/11/22 XG27 A0
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x40);
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x06 ) ; ////[Billy]06/11/22 DLL Reset for XG27 Hynix DRAM
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(15); /* 06/11/22 XG27 A0 */
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 15 ) ; ////06/11/23 XG27 A0
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x06); /* [Billy]06/11/22 DLL Reset for XG27 Hynix DRAM */
- DelayUS( 30 ) ; ////06/11/23 XG27 A0 Start Auto-PreCharge
- XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
- DelayUS( 60 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ; /* SR1B */
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(15); /* 06/11/23 XG27 A0 */
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+ DelayUS(30); /* 06/11/23 XG27 A0 Start Auto-PreCharge */
+ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
+ DelayUS(60);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
- XGINew_SetReg1( P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x04 ) ; //// DLL without Reset for XG27 Hynix DRAM
+ XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
+ XGINew_SetReg1(P3c4, 0x19, 0x04); /* DLL without Reset for XG27 Hynix DRAM */
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
- XGINew_SetReg1( P3c4 , 0x18 , 0x80 ); ////XG27 OCD ON
- XGINew_SetReg1( P3c4 , 0x19 , 0x46 );
+ XGINew_SetReg1(P3c4, 0x18, 0x80); /* XG27 OCD ON */
+ XGINew_SetReg1(P3c4, 0x19, 0x46);
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 );
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 );
+ XGINew_SetReg1(P3c4, 0x18, 0x00);
+ XGINew_SetReg1(P3c4, 0x19, 0x40);
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- DelayUS( 30 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ DelayUS(30);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
- DelayUS( 15 ) ; ////Start Auto-PreCharge
- XGINew_SetReg1( P3c4 , 0x1B , 0x04 ) ; /* SR1B */
- DelayUS( 200 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ; /* SR1B */
+ DelayUS(15); /* Start Auto-PreCharge */
+ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
+ DelayUS(200);
+ XGINew_SetReg1(P3c4, 0x1B, 0x03); /* SR1B */
}
+#endif
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR1x_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long Port, struct vb_device_info *pVBInfo)
+static void XGINew_DDR1x_DefaultRegister(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
{
- unsigned long P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- {
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
-
- XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
- XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
-
- XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
- }
- else
- {
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- switch( HwDeviceExtension->jChipType )
- {
- case XG41:
- case XG42:
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- break ;
- default:
- XGINew_SetReg1( P3d4 , 0x82 , 0x88 ) ;
- XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
- XGINew_GetReg1( P3d4 , 0x86 ) ;
- XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
- XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
- XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- break ;
- }
-
- XGINew_SetReg1( P3d4 , 0x97 , 0x00 ) ;
- XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
- XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
- XGINew_DDR1x_MRS_340( P3c4 , pVBInfo ) ;
- }
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+
+ XGINew_SetReg1(P3d4, 0x98, 0x01);
+ XGINew_SetReg1(P3d4, 0x9A, 0x02);
+
+ XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
+ } else {
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
+
+ switch (HwDeviceExtension->jChipType) {
+ case XG41:
+ case XG42:
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+ break;
+ default:
+ XGINew_SetReg1(P3d4, 0x82, 0x88);
+ XGINew_SetReg1(P3d4, 0x86, 0x00);
+ XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x86, 0x88);
+ XGINew_GetReg1(P3d4, 0x86);
+ XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
+ XGINew_SetReg1(P3d4, 0x82, 0x77);
+ XGINew_SetReg1(P3d4, 0x85, 0x00);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, 0x88);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ break;
+ }
+
+ XGINew_SetReg1(P3d4, 0x97, 0x00);
+ XGINew_SetReg1(P3d4, 0x98, 0x01);
+ XGINew_SetReg1(P3d4, 0x9A, 0x02);
+ XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
+ }
}
+#if 0
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2x_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2x_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long Port, struct vb_device_info *pVBInfo)
+static void XGINew_DDR2x_DefaultRegister(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
{
- unsigned long P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
- switch( HwDeviceExtension->jChipType )
- {
- case XG41:
- case XG42:
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- break ;
- default:
- /* keep following setting sequence, each setting in the same reg insert idle */
- XGINew_SetReg1( P3d4 , 0x82 , 0x88 ) ;
- XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
- XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
- XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- }
- XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ;
- if ( HwDeviceExtension->jChipType == XG42 )
- {
- XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
- }
- else
- {
- XGINew_SetReg1( P3d4 , 0x98 , 0x03 ) ;
- }
- XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
-
- XGINew_DDR2x_MRS_340( P3c4 , pVBInfo ) ;
-}
+ unsigned long P3d4 = Port ,
+ P3c4 = Port - 0x10;
+ XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2_DefaultRegister(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long Port, struct vb_device_info *pVBInfo)
-{
- unsigned long P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- /* keep following setting sequence, each setting in the same reg insert idle */
- XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
- XGINew_SetReg1( P3d4 , 0x86 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x86 , 0x88 ) ;
- XGINew_GetReg1( P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- XGINew_SetReg1( P3d4 , 0x82 , 0x77 ) ;
- XGINew_SetReg1( P3d4 , 0x85 , 0x00 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , 0x88 ) ;
- XGINew_GetReg1( P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGINew_SetReg1( P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- if ( HwDeviceExtension->jChipType == XG27 )
- XGINew_SetReg1( P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- else
- XGINew_SetReg1( P3d4 , 0x82 , 0xA8 ) ; /* CR82 */
-
- XGINew_SetReg1( P3d4 , 0x98 , 0x01 ) ;
- XGINew_SetReg1( P3d4 , 0x9A , 0x02 ) ;
- if ( HwDeviceExtension->jChipType == XG27 )
- XGINew_DDRII_Bootup_XG27( HwDeviceExtension , P3c4 , pVBInfo) ;
- else
- XGINew_DDR2_MRS_XG20( HwDeviceExtension , P3c4, pVBInfo ) ;
-}
+ /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
+ switch (HwDeviceExtension->jChipType) {
+ case XG41:
+ case XG42:
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+ break;
+ default:
+ /* keep following setting sequence, each setting in the same reg insert idle */
+ XGINew_SetReg1(P3d4, 0x82, 0x88);
+ XGINew_SetReg1(P3d4, 0x86, 0x00);
+ XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x86, 0x88);
+ XGINew_SetReg1(P3d4, 0x82, 0x77);
+ XGINew_SetReg1(P3d4, 0x85, 0x00);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, 0x88);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ }
+ XGINew_SetReg1(P3d4, 0x97, 0x11);
+ if (HwDeviceExtension->jChipType == XG42)
+ XGINew_SetReg1(P3d4, 0x98, 0x01);
+ else
+ XGINew_SetReg1(P3d4, 0x98, 0x03);
+ XGINew_SetReg1(P3d4, 0x9A, 0x02);
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMDefaultRegister340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long Port, struct vb_device_info *pVBInfo)
-{
- unsigned char temp, temp1, temp2, temp3 ,
- i , j , k ;
-
- unsigned long P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- XGINew_SetReg1( P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
- XGINew_SetReg1( P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
- XGINew_SetReg1( P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
- XGINew_SetReg1( P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
-
- temp2 = 0 ;
- for( i = 0 ; i < 4 ; i++ )
- {
- temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
- temp2 |= temp1 ;
- XGINew_SetReg1( P3d4 , 0x6B , temp2 ) ;
- XGINew_GetReg1( P3d4 , 0x6B ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
- }
-
- temp2 = 0 ;
- for( i = 0 ; i < 4 ; i++ )
- {
- temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
- temp2 |= temp1 ;
- XGINew_SetReg1( P3d4 , 0x6E , temp2 ) ;
- XGINew_GetReg1( P3d4 , 0x6E ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
- }
-
- temp3 = 0 ;
- for( k = 0 ; k < 4 ; k++ )
- {
- XGINew_SetRegANDOR( P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
- temp2 = 0 ;
- for( i = 0 ; i < 8 ; i++ )
- {
- temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
- temp2 |= temp1 ;
- XGINew_SetReg1( P3d4 , 0x6F , temp2 ) ;
- XGINew_GetReg1( P3d4 , 0x6F ) ; /* Insert read command for delay */
- temp2 &= 0xF8 ;
- temp2 += 0x08 ;
- }
- }
- temp3 += 0x01 ;
- }
-
- XGINew_SetReg1( P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
- XGINew_SetReg1( P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
-
- temp2 = 0x80 ;
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
- temp2 |= temp1 ;
- XGINew_SetReg1( P3d4 , 0x89 , temp2 ) ;
- XGINew_GetReg1( P3d4 , 0x89 ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
-
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
- temp1 = temp & 0x03 ;
- temp2 |= temp1 ;
- XGINew_SetReg1( P3d4 , 0x89 , temp2 ) ;
-
- temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
- temp1 = temp & 0x0F ;
- temp2 = ( temp >> 4 ) & 0x07 ;
- temp3 = temp & 0x80 ;
- XGINew_SetReg1( P3d4 , 0x45 , temp1 ) ; /* CR45 */
- XGINew_SetReg1( P3d4 , 0x99 , temp2 ) ; /* CR99 */
- XGINew_SetRegOR( P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
- XGINew_SetReg1( P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
-
- if ( HwDeviceExtension->jChipType == XG27 )
- XGINew_SetReg1( P3d4 , 0x8F , *pVBInfo->pCR8F ) ; /* CR8F */
-
- for( j = 0 ; j <= 6 ; j++ )
- XGINew_SetReg1( P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
-
- for( j = 0 ; j <= 2 ; j++ )
- XGINew_SetReg1( P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
-
- for( j = 0 ; j < 2 ; j++ )
- XGINew_SetReg1( P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
-
- if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
- XGINew_SetReg1( P3d4 , 0x8C , 0x87 ) ;
-
- XGINew_SetReg1( P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
-
- XGINew_SetReg1( P3d4 , 0x83 , 0x09 ) ; /* CR83 */
- XGINew_SetReg1( P3d4 , 0x87 , 0x00 ) ; /* CR87 */
- XGINew_SetReg1( P3d4 , 0xCF , *pVBInfo->pCRCF ) ; /* CRCF */
- if ( XGINew_RAMType )
- {
- //XGINew_SetReg1( P3c4 , 0x17 , 0xC0 ) ; /* SR17 DDRII */
- XGINew_SetReg1( P3c4 , 0x17 , 0x80 ) ; /* SR17 DDRII */
- if ( HwDeviceExtension->jChipType == XG27 )
- XGINew_SetReg1( P3c4 , 0x17 , 0x02 ) ; /* SR17 DDRII */
-
- }
- else
- XGINew_SetReg1( P3c4 , 0x17 , 0x00 ) ; /* SR17 DDR */
- XGINew_SetReg1( P3c4 , 0x1A , 0x87 ) ; /* SR1A */
-
- temp = XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) ;
- if( temp == 0 )
- XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
- else
- {
- XGINew_SetReg1( P3d4 , 0xB0 , 0x80 ) ; /* DDRII Dual frequency mode */
- XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
- }
- XGINew_SetReg1( P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+ XGINew_DDR2x_MRS_340(P3c4, pVBInfo);
}
+#endif
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR_MRS */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR_MRS(struct vb_device_info *pVBInfo)
+static void XGINew_DDR2_DefaultRegister(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
{
- unsigned short data ;
-
- volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
-
- /* SR16 <- 1F,DF,2F,AF */
- /* yriver modified SR16 <- 0F,DF,0F,AF */
- /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
- data = pVideoMemory[ 0xFB ] ;
- /* data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ; */
-
- data &= 0x0F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xC0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0x80 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xD0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xA0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x16 , data ) ;
-/*
- else {
- data &= 0x0F;
- data |= 0x10;
- XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
-
- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
- {
- data &= 0x0F;
- }
-
- data |= 0xC0;
- XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
-
-
- data &= 0x0F;
- data |= 0x20;
- XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
- {
- data &= 0x0F;
- }
-
- data |= 0x80;
- XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
- }
-*/
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ /* keep following setting sequence, each setting in the same reg insert idle */
+ XGINew_SetReg1(P3d4, 0x82, 0x77);
+ XGINew_SetReg1(P3d4, 0x86, 0x00);
+ XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x86, 0x88);
+ XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+ XGINew_SetReg1(P3d4, 0x82, 0x77);
+ XGINew_SetReg1(P3d4, 0x85, 0x00);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, 0x88);
+ XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
+ XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+ else
+ XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */
+
+ XGINew_SetReg1(P3d4, 0x98, 0x01);
+ XGINew_SetReg1(P3d4, 0x9A, 0x02);
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
+ else
+ XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
}
+void XGINew_SetDRAMDefaultRegister340(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned long Port, struct vb_device_info *pVBInfo)
+{
+ unsigned char temp, temp1, temp2, temp3, i, j, k;
+
+ unsigned long P3d4 = Port, P3c4 = Port - 0x10;
+
+ XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]);
+ XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]);
+ XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]);
+ XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]);
+
+ temp2 = 0;
+ for (i = 0; i < 4; i++) {
+ temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */
+ for (j = 0; j < 4; j++) {
+ temp1 = ((temp >> (2 * j)) & 0x03) << 2;
+ temp2 |= temp1;
+ XGINew_SetReg1(P3d4, 0x6B, temp2);
+ XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */
+ temp2 &= 0xF0;
+ temp2 += 0x10;
+ }
+ }
-/* check if read cache pointer is correct */
+ temp2 = 0;
+ for (i = 0; i < 4; i++) {
+ temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */
+ for (j = 0; j < 4; j++) {
+ temp1 = ((temp >> (2 * j)) & 0x03) << 2;
+ temp2 |= temp1;
+ XGINew_SetReg1(P3d4, 0x6E, temp2);
+ XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */
+ temp2 &= 0xF0;
+ temp2 += 0x10;
+ }
+ }
+ temp3 = 0;
+ for (k = 0; k < 4; k++) {
+ XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */
+ temp2 = 0;
+ for (i = 0; i < 8; i++) {
+ temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */
+ for (j = 0; j < 4; j++) {
+ temp1 = (temp >> (2 * j)) & 0x03;
+ temp2 |= temp1;
+ XGINew_SetReg1(P3d4, 0x6F, temp2);
+ XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */
+ temp2 &= 0xF8;
+ temp2 += 0x08;
+ }
+ }
+ temp3 += 0x01;
+ }
+ XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */
+ XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */
+
+ temp2 = 0x80;
+ temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */
+ for (j = 0; j < 4; j++) {
+ temp1 = (temp >> (2 * j)) & 0x03;
+ temp2 |= temp1;
+ XGINew_SetReg1(P3d4, 0x89, temp2);
+ XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */
+ temp2 &= 0xF0;
+ temp2 += 0x10;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_VerifyMclk */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_VerifyMclk(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+ temp = pVBInfo->CR89[XGINew_RAMType][1];
+ temp1 = temp & 0x03;
+ temp2 |= temp1;
+ XGINew_SetReg1(P3d4, 0x89, temp2);
+
+ temp = pVBInfo->CR40[3][XGINew_RAMType];
+ temp1 = temp & 0x0F;
+ temp2 = (temp >> 4) & 0x07;
+ temp3 = temp & 0x80;
+ XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */
+ XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */
+ XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */
+ XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */
+
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */
+
+ for (j = 0; j <= 6; j++)
+ XGINew_SetReg1(P3d4, (0x90 + j),
+ pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */
+
+ for (j = 0; j <= 2; j++)
+ XGINew_SetReg1(P3d4, (0xC3 + j),
+ pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */
+
+ for (j = 0; j < 2; j++)
+ XGINew_SetReg1(P3d4, (0x8A + j),
+ pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */
+
+ if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42))
+ XGINew_SetReg1(P3d4, 0x8C, 0x87);
+
+ XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */
+
+ XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */
+ XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */
+ XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */
+ if (XGINew_RAMType) {
+ /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */
+ XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */
+ if (HwDeviceExtension->jChipType == XG27)
+ XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */
+
+ } else {
+ XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */
+ }
+ XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */
+
+ temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+ if (temp == 0) {
+ XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+ } else {
+ XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
+ XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
+ }
+ XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
+}
+
+static void XGINew_DDR_MRS(struct vb_device_info *pVBInfo)
{
- unsigned char *pVideoMemory = pVBInfo->FBAddr ;
- unsigned char i, j ;
- unsigned short Temp , SR21 ;
-
- pVideoMemory[ 0 ] = 0xaa ; /* alan */
- pVideoMemory[ 16 ] = 0x55 ; /* note: PCI read cache is off */
-
- if ( ( pVideoMemory[ 0 ] != 0xaa ) || ( pVideoMemory[ 16 ] != 0x55 ) )
- {
- for( i = 0 , j = 16 ; i < 2 ; i++ , j += 16 )
- {
- SR21 = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
- Temp = SR21 & 0xFB ; /* disable PCI post write buffer empty gating */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , Temp ) ;
-
- Temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3C ) ;
- Temp |= 0x01 ; /* MCLK reset */
-
-
- Temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x3C ) ;
- Temp &= 0xFE ; /* MCLK normal operation */
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x21 , SR21 ) ;
-
- pVideoMemory[ 16 + j ] = j ;
- if ( pVideoMemory[ 16 + j ] == j )
- {
- pVideoMemory[ j ] = j ;
- break ;
- }
- }
- }
+ unsigned short data;
+
+ volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
+
+ /* SR16 <- 1F,DF,2F,AF */
+ /* yriver modified SR16 <- 0F,DF,0F,AF */
+ /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+ data = pVideoMemory[0xFB];
+ /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x16); */
+
+ data &= 0x0F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data |= 0xC0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data &= 0x0F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data |= 0x80;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data &= 0x0F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data |= 0xD0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data &= 0x0F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ data |= 0xA0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
+ /*
+ else {
+ data &= 0x0F;
+ data |= 0x10;
+ XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
+
+ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) {
+ data &= 0x0F;
+ }
+
+ data |= 0xC0;
+ XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
+
+ data &= 0x0F;
+ data |= 0x20;
+ XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
+ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) {
+ data &= 0x0F;
+ }
+
+ data |= 0x80;
+ XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
+ }
+ */
}
+/* check if read cache pointer is correct */
+static void XGINew_VerifyMclk(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char *pVideoMemory = pVBInfo->FBAddr;
+ unsigned char i, j;
+ unsigned short Temp, SR21;
+ pVideoMemory[0] = 0xaa; /* alan */
+ pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
+ if ((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
+ for (i = 0, j = 16; i < 2; i++, j += 16) {
+ SR21 = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+ Temp = SR21 & 0xFB; /* disable PCI post write buffer empty gating */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, Temp);
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSize_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short data ;
+ Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C);
+ Temp |= 0x01; /* MCLK reset */
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C);
+ Temp &= 0xFE; /* MCLK normal operation */
- XGISetModeNew( HwDeviceExtension , 0x2e ) ;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, SR21);
+ pVideoMemory[16 + j] = j;
+ if (pVideoMemory[16 + j] == j) {
+ pVideoMemory[j] = j;
+ break;
+ }
+ }
+ }
+}
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF)); /* disable read cache */
- XGI_DisplayOff( HwDeviceExtension, pVBInfo );
+void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data;
- /*data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;*/
- /*data |= 0x20 ;*/
- /*XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ;*/ /* Turn OFF Display */
- XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
- data=XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20)); /* enable read cache */
-}
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ XGISetModeNew(HwDeviceExtension, 0x2e);
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+
+ /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */
+ /* data |= 0x20 ; */
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */
+ XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
+}
+
+void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short data ;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ,
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ unsigned short data;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase, pVBInfo->FBAddr
+ = HwDeviceExtension->pjVideoMemoryAddress;
#ifdef XGI301
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x40 ) ; */
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x40); */
#endif
#ifdef XGI302 /* alan,should change value */
- XGINew_SetReg1( pVBInfo->P3d4 , 0x30 , 0x4D ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x31 , 0xc0 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x34 , 0x3F ) ;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x4D);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x31, 0xc0);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x34, 0x3F);
#endif
- XGISetModeNew( HwDeviceExtension , 0x2e ) ;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x21 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF)); /* disable read cache */
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1 ) ;
- data |= 0x20 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ; /* Turn OFF Display */
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x16 ) ;
-
-
- XGINew_SetReg1(pVBInfo->P3c4, 0x16, (unsigned short)(data | 0x0F)); /* assume lowest speed DRAM */
-
- XGINew_SetDRAMModeRegister( pVBInfo ) ;
- XGINew_DisableRefresh( HwDeviceExtension, pVBInfo ) ;
- XGINew_CheckBusWidth_310( pVBInfo) ;
- XGINew_VerifyMclk( HwDeviceExtension, pVBInfo ) ; /* alan 2000/7/3 */
+ XGISetModeNew(HwDeviceExtension, 0x2e);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x1);
+ data |= 0x20;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); /* Turn OFF Display */
- if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
- {
- XGINew_SDRSizing( pVBInfo ) ;
- }
- else
- {
- XGINew_DDRSizing( pVBInfo) ;
- }
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x16);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, (unsigned short) (data | 0x0F)); /* assume lowest speed DRAM */
+ XGINew_SetDRAMModeRegister(pVBInfo);
+ XGINew_DisableRefresh(HwDeviceExtension, pVBInfo);
+ XGINew_CheckBusWidth_310(pVBInfo);
+ XGINew_VerifyMclk(HwDeviceExtension, pVBInfo); /* alan 2000/7/3 */
+ if (XGINew_Get310DRAMType(pVBInfo) < 2)
+ XGINew_SDRSizing(pVBInfo);
+ else
+ XGINew_DDRSizing(pVBInfo);
- XGINew_SetReg1(pVBInfo->P3c4, 0x16, pVBInfo->SR15[1][XGINew_RAMType]); /* restore SR16 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x16, pVBInfo->SR15[1][XGINew_RAMType]); /* restore SR16 */
- XGINew_EnableRefresh( HwDeviceExtension, pVBInfo ) ;
- data=XGINew_GetReg1( pVBInfo->P3c4 ,0x21 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20)); /* enable read cache */
+ XGINew_EnableRefresh(HwDeviceExtension, pVBInfo);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMModeRegister340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-
void XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension)
{
- unsigned char data ;
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
-
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- {
- data = ( XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
- if ( data == 0x01 )
- XGINew_DDR2x_MRS_340( pVBInfo->P3c4, pVBInfo ) ;
- else
- XGINew_DDR1x_MRS_340( pVBInfo->P3c4, pVBInfo ) ;
- }
- else
- XGINew_DDR2_MRS_XG20( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+ unsigned char data;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+ pVBInfo->ISXPDOS = 0;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+ XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
+
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+
+ ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+
+ if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) {
+ data = (XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02) >> 1;
+ if (data == 0x01)
+ XGINew_DDR2x_MRS_340(pVBInfo->P3c4, pVBInfo);
+ else
+ XGINew_DDR1x_MRS_340(pVBInfo->P3c4, pVBInfo);
+ } else {
+ XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMModeRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGINew_SetDRAMModeRegister(struct vb_device_info *pVBInfo)
{
- if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
- {
- XGINew_SDR_MRS(pVBInfo ) ;
- }
- else
- {
- /* SR16 <- 0F,CF,0F,8F */
- XGINew_DDR_MRS( pVBInfo ) ;
- }
+ if (XGINew_Get310DRAMType(pVBInfo) < 2) {
+ XGINew_SDR_MRS(pVBInfo);
+ } else {
+ /* SR16 <- 0F,CF,0F,8F */
+ XGINew_DDR_MRS(pVBInfo);
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DisableRefresh */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DisableRefresh(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGINew_DisableRefresh(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short data ;
+ unsigned short data;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1B ) ;
- data &= 0xF8 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , data ) ;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x1B);
+ data &= 0xF8;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, data);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_EnableRefresh */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_EnableRefresh(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGINew_EnableRefresh(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
-
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DisableChannelInterleaving */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DisableChannelInterleaving(int index,
- unsigned short XGINew_DDRDRAM_TYPE[][5],
- struct vb_device_info *pVBInfo)
+static void XGINew_DisableChannelInterleaving(int index,
+ unsigned short XGINew_DDRDRAM_TYPE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned short data ;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x15 ) ;
- data &= 0x1F ;
-
- switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
- {
- case 64:
- data |= 0 ;
- break ;
- case 32:
- data |= 0x20 ;
- break ;
- case 16:
- data |= 0x40 ;
- break ;
- case 4:
- data |= 0x60 ;
- break ;
- default:
- break ;
- }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , data ) ;
+ unsigned short data;
+
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x15);
+ data &= 0x1F;
+
+ switch (XGINew_DDRDRAM_TYPE[index][3]) {
+ case 64:
+ data |= 0;
+ break;
+ case 32:
+ data |= 0x20;
+ break;
+ case 16:
+ data |= 0x40;
+ break;
+ case 4:
+ data |= 0x60;
+ break;
+ default:
+ break;
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x15, data);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSizingType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSizingType(int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static void XGINew_SetDRAMSizingType(int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned short data;
+ unsigned short data;
- data = DRAMTYPE_TABLE[ index ][ 4 ] ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
- DelayUS( 15 ) ;
- /* should delay 50 ns */
+ data = DRAMTYPE_TABLE[index][4];
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data);
+ DelayUS(15);
+ /* should delay 50 ns */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckBusWidth_310 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGINew_CheckBusWidth_310(struct vb_device_info *pVBInfo)
{
- unsigned short data ;
- volatile unsigned long *pVideoMemory ;
-
- pVideoMemory = (unsigned long *) pVBInfo->FBAddr;
-
- if ( XGINew_Get310DRAMType( pVBInfo ) < 2 )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x12 ) ;
- /* should delay */
- XGINew_SDR_MRS( pVBInfo ) ;
-
- XGINew_ChannelAB = 0 ;
- XGINew_DataBusWidth = 128 ;
- pVideoMemory[ 0 ] = 0x01234567L ;
- pVideoMemory[ 1 ] = 0x456789ABL ;
- pVideoMemory[ 2 ] = 0x89ABCDEFL ;
- pVideoMemory[ 3 ] = 0xCDEF0123L ;
- pVideoMemory[ 4 ] = 0x55555555L ;
- pVideoMemory[ 5 ] = 0x55555555L ;
- pVideoMemory[ 6 ] = 0xFFFFFFFFL ;
- pVideoMemory[ 7 ] = 0xFFFFFFFFL ;
-
- if ( ( pVideoMemory[ 3 ] != 0xCDEF0123L ) || ( pVideoMemory[ 2 ] != 0x89ABCDEFL ) )
- {
- /* ChannelA64Bit */
- XGINew_DataBusWidth = 64 ;
- XGINew_ChannelAB = 0 ;
- data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x14, (unsigned short)(data & 0xFD));
- }
-
- if ( ( pVideoMemory[ 1 ] != 0x456789ABL ) || ( pVideoMemory[ 0 ] != 0x01234567L ) )
- {
- /* ChannelB64Bit */
- XGINew_DataBusWidth = 64 ;
- XGINew_ChannelAB = 1 ;
- data=XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
- XGINew_SetReg1(pVBInfo->P3c4, 0x14,
- (unsigned short)((data & 0xFD) | 0x01));
- }
-
- return ;
- }
- else
- {
- /* DDR Dual channel */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x02 ) ; /* Channel A, 64bit */
- /* should delay */
- XGINew_DDR_MRS( pVBInfo ) ;
-
- XGINew_ChannelAB = 0 ;
- XGINew_DataBusWidth = 64 ;
- pVideoMemory[ 0 ] = 0x01234567L ;
- pVideoMemory[ 1 ] = 0x456789ABL ;
- pVideoMemory[ 2 ] = 0x89ABCDEFL ;
- pVideoMemory[ 3 ] = 0xCDEF0123L ;
- pVideoMemory[ 4 ] = 0x55555555L ;
- pVideoMemory[ 5 ] = 0x55555555L ;
- pVideoMemory[ 6 ] = 0xAAAAAAAAL ;
- pVideoMemory[ 7 ] = 0xAAAAAAAAL ;
-
- if ( pVideoMemory[ 1 ] == 0x456789ABL )
- {
- if ( pVideoMemory[ 0 ] == 0x01234567L )
- {
- /* Channel A 64bit */
- return ;
- }
- }
- else
- {
- if ( pVideoMemory[ 0 ] == 0x01234567L )
- {
- /* Channel A 32bit */
- XGINew_DataBusWidth = 32 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x00 ) ;
- return ;
- }
- }
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x03 ) ; /* Channel B, 64bit */
- XGINew_DDR_MRS( pVBInfo);
-
- XGINew_ChannelAB = 1 ;
- XGINew_DataBusWidth = 64 ;
- pVideoMemory[ 0 ] = 0x01234567L ;
- pVideoMemory[ 1 ] = 0x456789ABL ;
- pVideoMemory[ 2 ] = 0x89ABCDEFL ;
- pVideoMemory[ 3 ] = 0xCDEF0123L ;
- pVideoMemory[ 4 ] = 0x55555555L ;
- pVideoMemory[ 5 ] = 0x55555555L ;
- pVideoMemory[ 6 ] = 0xAAAAAAAAL ;
- pVideoMemory[ 7 ] = 0xAAAAAAAAL ;
-
- if ( pVideoMemory[ 1 ] == 0x456789ABL )
- {
- /* Channel B 64 */
- if ( pVideoMemory[ 0 ] == 0x01234567L )
- {
- /* Channel B 64bit */
- return ;
- }
- else
- {
- /* error */
- }
- }
- else
- {
- if ( pVideoMemory[ 0 ] == 0x01234567L )
- {
- /* Channel B 32 */
- XGINew_DataBusWidth = 32 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x01 ) ;
- }
- else
- {
- /* error */
- }
- }
- }
+ unsigned short data;
+ volatile unsigned long *pVideoMemory;
+
+ pVideoMemory = (unsigned long *) pVBInfo->FBAddr;
+
+ if (XGINew_Get310DRAMType(pVBInfo) < 2) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x12);
+ /* should delay */
+ XGINew_SDR_MRS(pVBInfo);
+
+ XGINew_ChannelAB = 0;
+ XGINew_DataBusWidth = 128;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xFFFFFFFFL;
+ pVideoMemory[7] = 0xFFFFFFFFL;
+
+ if ((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2]
+ != 0x89ABCDEFL)) {
+ /* ChannelA64Bit */
+ XGINew_DataBusWidth = 64;
+ XGINew_ChannelAB = 0;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14,
+ (unsigned short) (data & 0xFD));
+ }
+
+ if ((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0]
+ != 0x01234567L)) {
+ /* ChannelB64Bit */
+ XGINew_DataBusWidth = 64;
+ XGINew_ChannelAB = 1;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14,
+ (unsigned short) ((data & 0xFD) | 0x01));
+ }
+
+ return;
+ } else {
+ /* DDR Dual channel */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x02); /* Channel A, 64bit */
+ /* should delay */
+ XGINew_DDR_MRS(pVBInfo);
+
+ XGINew_ChannelAB = 0;
+ XGINew_DataBusWidth = 64;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xAAAAAAAAL;
+ pVideoMemory[7] = 0xAAAAAAAAL;
+
+ if (pVideoMemory[1] == 0x456789ABL) {
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel A 64bit */
+ return;
+ }
+ } else {
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel A 32bit */
+ XGINew_DataBusWidth = 32;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x00);
+ return;
+ }
+ }
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x03); /* Channel B, 64bit */
+ XGINew_DDR_MRS(pVBInfo);
+
+ XGINew_ChannelAB = 1;
+ XGINew_DataBusWidth = 64;
+ pVideoMemory[0] = 0x01234567L;
+ pVideoMemory[1] = 0x456789ABL;
+ pVideoMemory[2] = 0x89ABCDEFL;
+ pVideoMemory[3] = 0xCDEF0123L;
+ pVideoMemory[4] = 0x55555555L;
+ pVideoMemory[5] = 0x55555555L;
+ pVideoMemory[6] = 0xAAAAAAAAL;
+ pVideoMemory[7] = 0xAAAAAAAAL;
+
+ if (pVideoMemory[1] == 0x456789ABL) {
+ /* Channel B 64 */
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel B 64bit */
+ return;
+ } else {
+ /* error */
+ }
+ } else {
+ if (pVideoMemory[0] == 0x01234567L) {
+ /* Channel B 32 */
+ XGINew_DataBusWidth = 32;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x01);
+ } else {
+ /* error */
+ }
+ }
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_SetRank(int index,
- unsigned char RankNo,
- unsigned char XGINew_ChannelAB,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static int XGINew_SetRank(int index, unsigned char RankNo,
+ unsigned char XGINew_ChannelAB,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned short data;
- int RankSize ;
-
- if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
- return 0 ;
-
- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
-
- if ( ( RankNo * RankSize ) <= 128 )
- {
- data = 0 ;
-
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
- data |= ( RankNo - 1 ) << 2 ;
- data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
- data |= XGINew_ChannelAB ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
- /* should delay */
- XGINew_SDR_MRS( pVBInfo ) ;
- return( 1 ) ;
- }
- else
- return( 0 ) ;
-}
+ unsigned short data;
+ int RankSize;
+ if ((RankNo == 2) && (DRAMTYPE_TABLE[index][0] == 2))
+ return 0;
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDDRChannel */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_SetDDRChannel(int index,
- unsigned char ChannelNo,
- unsigned char XGINew_ChannelAB,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
-{
- unsigned short data;
- int RankSize ;
-
- RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
- /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
- if ( ChannelNo * RankSize <= 128 )
- {
- data = 0 ;
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
-
- if ( ChannelNo == 2 )
- data |= 0x0C ;
-
- data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
- data |= XGINew_ChannelAB ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
- /* should delay */
- XGINew_DDR_MRS( pVBInfo ) ;
- return( 1 ) ;
- }
- else
- return( 0 ) ;
-}
+ RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32;
+ if ((RankNo * RankSize) <= 128) {
+ data = 0;
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckColumn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckColumn(int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
-{
- int i ;
- unsigned long Increment , Position ;
-
- /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
- Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
- Position += Increment ;
- }
-
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
- if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
- return 0;
- Position += Increment;
- }
- return( 1 ) ;
-}
+ while ((RankSize >>= 1) > 0)
+ data += 0x10;
+ data |= (RankNo - 1) << 2;
+ data |= (XGINew_DataBusWidth / 64) & 2;
+ data |= XGINew_ChannelAB;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
+ /* should delay */
+ XGINew_SDR_MRS(pVBInfo);
+ return 1;
+ } else {
+ return 0;
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckBanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckBanks(int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static int XGINew_SetDDRChannel(int index, unsigned char ChannelNo,
+ unsigned char XGINew_ChannelAB,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- int i ;
- unsigned long Increment , Position ;
-
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
-
- for( i = 0 , Position = 0 ; i < 4 ; i++ )
- {
- /* pVBInfo->FBAddr[ Position ] = Position ; */
- *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
- Position += Increment ;
- }
-
- for( i = 0 , Position = 0 ; i < 4 ; i++ )
- {
- /* if (pVBInfo->FBAddr[ Position ] != Position ) */
- if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
- return 0;
- Position += Increment;
- }
- return( 1 ) ;
+ unsigned short data;
+ int RankSize;
+
+ RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32;
+ /* RankSize = DRAMTYPE_TABLE[index][3]; */
+ if (ChannelNo * RankSize <= 128) {
+ data = 0;
+ while ((RankSize >>= 1) > 0)
+ data += 0x10;
+
+ if (ChannelNo == 2)
+ data |= 0x0C;
+
+ data |= (XGINew_DataBusWidth / 32) & 2;
+ data |= XGINew_ChannelAB;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
+ /* should delay */
+ XGINew_DDR_MRS(pVBInfo);
+ return 1;
+ } else {
+ return 0;
+ }
}
+static int XGINew_CheckColumn(int index, unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
+{
+ int i;
+ unsigned long Increment, Position;
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckRank(int RankNo, int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+ /* Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 1); */
+ Increment = 1 << (10 + XGINew_DataBusWidth / 64);
+
+ for (i = 0, Position = 0; i < 2; i++) {
+ *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
+ Position += Increment;
+ }
+
+ for (i = 0, Position = 0; i < 2; i++) {
+ /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
+ if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+ return 0;
+ Position += Increment;
+ }
+ return 1;
+}
+
+static int XGINew_CheckBanks(int index, unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- int i ;
- unsigned long Increment , Position ;
-
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* pVBInfo->FBAddr[ Position ] = Position ; */
- /* *( (unsigned long *)( pVBInfo->FBAddr ) ) = Position ; */
- *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
- Position += Increment;
- }
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
- /* if ( ( *(unsigned long *)( pVBInfo->FBAddr ) ) != Position ) */
- if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
- return 0;
- Position += Increment;
- }
- return( 1 );
+ int i;
+ unsigned long Increment, Position;
+
+ Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 2);
+
+ for (i = 0, Position = 0; i < 4; i++) {
+ /* pVBInfo->FBAddr[Position] = Position; */
+ *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
+ Position += Increment;
+ }
+
+ for (i = 0, Position = 0; i < 4; i++) {
+ /* if (pVBInfo->FBAddr[Position] != Position) */
+ if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+ return 0;
+ Position += Increment;
+ }
+ return 1;
}
+static int XGINew_CheckRank(int RankNo, int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
+{
+ int i;
+ unsigned long Increment, Position;
+
+ Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1]
+ + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64
+ + RankNo);
+
+ for (i = 0, Position = 0; i < 2; i++) {
+ /* pVBInfo->FBAddr[Position] = Position; */
+ /* *((unsigned long *)(pVBInfo->FBAddr)) = Position; */
+ *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
+ Position += Increment;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckDDRRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRank(int RankNo, int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+ for (i = 0, Position = 0; i < 2; i++) {
+ /* if (pVBInfo->FBAddr[Position] != Position) */
+ /* if ((*(unsigned long *)(pVBInfo->FBAddr)) != Position) */
+ if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+ return 0;
+ Position += Increment;
+ }
+ return 1;
+}
+
+static int XGINew_CheckDDRRank(int RankNo, int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned long Increment , Position ;
- unsigned short data ;
+ unsigned long Increment, Position;
+ unsigned short data;
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
+ Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1]
+ + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64
+ + RankNo);
- Increment += Increment / 2 ;
+ Increment += Increment / 2;
- Position = 0;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 0)) = 0x01234567;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 1)) = 0x456789AB;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 2)) = 0x55555555;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 3)) = 0x55555555;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 4)) = 0xAAAAAAAA;
- *((unsigned long *)(pVBInfo->FBAddr + Position + 5)) = 0xAAAAAAAA;
+ Position = 0;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 0)) = 0x01234567;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 1)) = 0x456789AB;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 2)) = 0x55555555;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 3)) = 0x55555555;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 4)) = 0xAAAAAAAA;
+ *((unsigned long *) (pVBInfo->FBAddr + Position + 5)) = 0xAAAAAAAA;
- if ((*(unsigned long *)(pVBInfo->FBAddr + 1)) == 0x456789AB)
- return 1;
+ if ((*(unsigned long *) (pVBInfo->FBAddr + 1)) == 0x456789AB)
+ return 1;
- if ((*(unsigned long *)(pVBInfo->FBAddr + 0)) == 0x01234567)
- return 0;
+ if ((*(unsigned long *) (pVBInfo->FBAddr + 0)) == 0x01234567)
+ return 0;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ;
- data &= 0xF3 ;
- data |= 0x0E ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x15 ) ;
- data += 0x20 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , data ) ;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
+ data &= 0xF3;
+ data |= 0x0E;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x15);
+ data += 0x20;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x15, data);
- return( 1 ) ;
+ return 1;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckRanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckRanks(int RankNo, int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static int XGINew_CheckRanks(int RankNo, int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- int r ;
+ int r;
- for( r = RankNo ; r >= 1 ; r-- )
- {
- if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
- }
+ for (r = RankNo; r >= 1; r--) {
+ if (!XGINew_CheckRank(r, index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
+ }
- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
+ if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
+ if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
- return( 1 ) ;
+ return 1;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckDDRRanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRanks(int RankNo, int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static int XGINew_CheckDDRRanks(int RankNo, int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- int r ;
+ int r;
- for( r = RankNo ; r >= 1 ; r-- )
- {
- if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
- }
+ for (r = RankNo; r >= 1; r--) {
+ if (!XGINew_CheckDDRRank(r, index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
+ }
- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
+ if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
+ if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo))
+ return 0;
- return( 1 ) ;
+ return 1;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
int XGINew_SDRSizing(struct vb_device_info *pVBInfo)
{
- int i ;
- unsigned char j ;
-
- for( i = 0 ; i < 13 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
-
- for( j = 2 ; j > 0 ; j-- )
- {
- if (!XGINew_SetRank(i, (unsigned char)j, XGINew_ChannelAB,
- XGINew_SDRDRAM_TYPE, pVBInfo))
- continue ;
- else
- {
- if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
- return( 1 ) ;
- }
- }
- }
- return( 0 ) ;
+ int i;
+ unsigned char j;
+
+ for (i = 0; i < 13; i++) {
+ XGINew_SetDRAMSizingType(i, XGINew_SDRDRAM_TYPE, pVBInfo);
+
+ for (j = 2; j > 0; j--) {
+ if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_SDRDRAM_TYPE, pVBInfo)) {
+ continue;
+ } else {
+ if (XGINew_CheckRanks(j, i, XGINew_SDRDRAM_TYPE, pVBInfo))
+ return 1;
+ }
+ }
+ }
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSizeReg */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned short XGINew_SetDRAMSizeReg(int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static unsigned short XGINew_SetDRAMSizeReg(int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned short data = 0 , memsize = 0;
- int RankSize ;
- unsigned char ChannelNo ;
+ unsigned short data = 0, memsize = 0;
+ int RankSize;
+ unsigned char ChannelNo;
- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
- data &= 0x80 ;
+ RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
+ data &= 0x80;
- if ( data == 0x80 )
- RankSize *= 2 ;
+ if (data == 0x80)
+ RankSize *= 2;
- data = 0 ;
+ data = 0;
- if( XGINew_ChannelAB == 3 )
- ChannelNo = 4 ;
- else
- ChannelNo = XGINew_ChannelAB ;
+ if (XGINew_ChannelAB == 3)
+ ChannelNo = 4;
+ else
+ ChannelNo = XGINew_ChannelAB;
- if ( ChannelNo * RankSize <= 256 )
- {
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
+ if (ChannelNo * RankSize <= 256) {
+ while ((RankSize >>= 1) > 0)
+ data += 0x10;
- memsize = data >> 4 ;
+ memsize = data >> 4;
- /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
+ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
- /* data |= XGINew_ChannelAB << 2 ; */
- /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
- /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
+ /* data |= XGINew_ChannelAB << 2; */
+ /* data |= (XGINew_DataBusWidth / 64) << 1; */
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
- /* should delay */
- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
- }
- return( memsize ) ;
+ /* should delay */
+ /* XGINew_SetDRAMModeRegister340(pVBInfo); */
+ }
+ return memsize;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSize20Reg */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned short XGINew_SetDRAMSize20Reg(int index,
- unsigned short DRAMTYPE_TABLE[][5],
- struct vb_device_info *pVBInfo)
+static unsigned short XGINew_SetDRAMSize20Reg(int index,
+ unsigned short DRAMTYPE_TABLE[][5],
+ struct vb_device_info *pVBInfo)
{
- unsigned short data = 0 , memsize = 0;
- int RankSize ;
- unsigned char ChannelNo ;
+ unsigned short data = 0, memsize = 0;
+ int RankSize;
+ unsigned char ChannelNo;
- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 8 ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x13 ) ;
- data &= 0x80 ;
+ RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
+ data &= 0x80;
- if ( data == 0x80 )
- RankSize *= 2 ;
+ if (data == 0x80)
+ RankSize *= 2;
- data = 0 ;
+ data = 0;
- if( XGINew_ChannelAB == 3 )
- ChannelNo = 4 ;
- else
- ChannelNo = XGINew_ChannelAB ;
+ if (XGINew_ChannelAB == 3)
+ ChannelNo = 4;
+ else
+ ChannelNo = XGINew_ChannelAB;
- if ( ChannelNo * RankSize <= 256 )
- {
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
+ if (ChannelNo * RankSize <= 256) {
+ while ((RankSize >>= 1) > 0)
+ data += 0x10;
- memsize = data >> 4 ;
+ memsize = data >> 4;
- /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , ( XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
- DelayUS( 15 ) ;
+ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
+ DelayUS(15);
- /* data |= XGINew_ChannelAB << 2 ; */
- /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
- /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
+ /* data |= XGINew_ChannelAB << 2; */
+ /* data |= (XGINew_DataBusWidth / 64) << 1; */
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
- /* should delay */
- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
- }
- return( memsize ) ;
+ /* should delay */
+ /* XGINew_SetDRAMModeRegister340(pVBInfo); */
+ }
+ return memsize;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_ReadWriteRest */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_ReadWriteRest(unsigned short StopAddr, unsigned short StartAddr,
- struct vb_device_info *pVBInfo)
+static int XGINew_ReadWriteRest(unsigned short StopAddr,
+ unsigned short StartAddr, struct vb_device_info *pVBInfo)
{
- int i ;
- unsigned long Position = 0 ;
-
- *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
+ int i;
+ unsigned long Position = 0;
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- *((unsigned long *)(pVBInfo->FBAddr + Position)) = Position;
- }
+ *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
- DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+ for (i = StartAddr; i <= StopAddr; i++) {
+ Position = 1 << i;
+ *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
+ }
- Position = 0 ;
+ DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
- if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
- return 0;
+ Position = 0;
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- if ((*(unsigned long *)(pVBInfo->FBAddr + Position)) != Position)
+ if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
return 0;
- }
- return( 1 ) ;
-}
+ for (i = StartAddr; i <= StopAddr; i++) {
+ Position = 1 << i;
+ if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+ return 0;
+ }
+ return 1;
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckFrequence */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
+static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
{
- unsigned char data ;
-
- data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) ;
-
- if ( ( data & 0x10 ) == 0 )
- {
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x39 ) ;
- data = ( data & 0x02 ) >> 1 ;
- return( data ) ;
- }
- else
- return( data & 0x01 ) ;
-}
+ unsigned char data;
+ data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckChannel */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+ if ((data & 0x10) == 0) {
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
+ data = (data & 0x02) >> 1;
+ return data;
+ } else {
+ return data & 0x01;
+ }
+}
+
+static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned char data;
-
- switch( HwDeviceExtension->jChipType )
- {
- case XG20:
- case XG21:
- data = XGINew_GetReg1( pVBInfo->P3d4 , 0x97 ) ;
- data = data & 0x01;
- XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
-
- if ( data == 0 ) /* Single_32_16 */
- {
-
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x1000000)
- {
-
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
- return ;
- }
- }
-
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
- {
- XGINew_DataBusWidth = 16 ; /* 16 bits */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x41 ) ;
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
- else
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ;
- DelayUS( 15 ) ;
- }
-
- }
- else /* Dual_16_8 */
- {
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
- {
-
- XGINew_DataBusWidth = 16 ; /* 16 bits */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* (0x31:12x8x2) 22bit + 2 rank */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x41 ) ; /* 0x41:16Mx16 bit*/
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
-
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* (0x31:12x8x2) 22bit + 1 rank */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x31 ) ; /* 0x31:8Mx16 bit*/
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
- return ;
- }
- }
-
-
- if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
- {
- XGINew_DataBusWidth = 8 ; /* 8 bits */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* (0x31:12x8x2) 22bit + 2 rank */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x30 ) ; /* 0x30:8Mx8 bit*/
- DelayUS( 15 ) ;
-
- if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
- return ;
- else
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* (0x31:12x8x2) 22bit + 1 rank */
- DelayUS( 15 ) ;
- }
- }
- break ;
-
- case XG27:
- XGINew_DataBusWidth = 16 ; /* 16 bits */
- XGINew_ChannelAB = 1 ; /* Single channel */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x51 ) ; /* 32Mx16 bit*/
- break ;
- case XG41:
- if ( XGINew_CheckFrequence(pVBInfo) == 1 )
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 3 ; /* Quad Channel */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4C ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x48 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x49 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 3 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x3C ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x38 ) ;
-
- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
- return ;
- else
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x39 ) ;
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x5A ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x53 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4A ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
-
- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
- return ;
- else
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x43 ) ;
- }
-
- break ;
-
- case XG42:
-/*
- XG42 SR14 D[3] Reserve
- D[2] = 1, Dual Channel
- = 0, Single Channel
+ unsigned char data;
- It's Different from Other XG40 Series.
-*/
- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 2 ; /* 2 Channel */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x44 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x34 ) ;
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single Channel */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x40 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x30 ) ;
- }
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 1 ; /* 1 channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x52 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x42 ) ;
- }
- }
-
- break ;
-
- default: /* XG40 */
-
- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 3 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4C ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x48 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x3C ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- XGINew_ChannelAB = 3 ; /* 4 channels */
- else
- {
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x38 ) ;
- }
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x5A ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , 0x4A ) ;
- }
- }
- break ;
- }
-}
+ switch (HwDeviceExtension->jChipType) {
+ case XG20:
+ case XG21:
+ data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
+ data = data & 0x01;
+ XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */
+
+ if (data == 0) { /* Single_32_16 */
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1)
+ > 0x1000000) {
+
+ XGINew_DataBusWidth = 32; /* 32 bits */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1)
+ return;
+ }
+ }
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
+ XGINew_DataBusWidth = 16; /* 16 bits */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41);
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+ else
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31);
+ DelayUS(15);
+ }
+
+ } else { /* Dual_16_8 */
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
+
+ XGINew_DataBusWidth = 16; /* 16 bits */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1)
+ return;
+ }
+ }
+
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
+ XGINew_DataBusWidth = 8; /* 8 bits */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/
+ DelayUS(15);
+
+ if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
+ return;
+ else
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
+ DelayUS(15);
+ }
+ }
+ break;
+
+ case XG27:
+ XGINew_DataBusWidth = 16; /* 16 bits */
+ XGINew_ChannelAB = 1; /* Single channel */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
+ break;
+ case XG41:
+ if (XGINew_CheckFrequence(pVBInfo) == 1) {
+ XGINew_DataBusWidth = 32; /* 32 bits */
+ XGINew_ChannelAB = 3; /* Quad Channel */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
+ if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
+ return;
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDRSizing340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- int i ;
- unsigned short memsize , addr ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
- XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
-
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- {
- for( i = 0 ; i < 12 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
- memsize = XGINew_SetDRAMSize20Reg( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
- if ( memsize == 0 )
- continue ;
-
- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
- if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long)(1 << addr))
- continue ;
-
- if ( XGINew_ReadWriteRest( addr , 5, pVBInfo ) == 1 )
- return( 1 ) ;
- }
- }
- else
- {
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
- memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
-
- if ( memsize == 0 )
- continue ;
-
- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
- if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long)(1 << addr))
- continue ;
-
- if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
- return( 1 ) ;
- }
- }
- return( 0 ) ;
-}
+ XGINew_ChannelAB = 2; /* Dual channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDRSizing */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_DDRSizing(struct vb_device_info *pVBInfo)
-{
- int i ;
- unsigned char j ;
-
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
- XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
- for( j = 2 ; j > 0 ; j-- )
- {
- XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
- if (!XGINew_SetRank(i, (unsigned char)j, XGINew_ChannelAB,
- XGINew_DDRDRAM_TYPE, pVBInfo))
- continue ;
- else
- {
- if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
- return( 1 ) ;
- }
- }
- }
- return( 0 ) ;
-}
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49);
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetMemoryClock */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_ChannelAB = 3;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
+
+ if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
+ return;
+ else
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39);
+ } else { /* DDR */
+ XGINew_DataBusWidth = 64; /* 64 bits */
+ XGINew_ChannelAB = 2; /* Dual channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
+
+ if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
+ return;
+ XGINew_ChannelAB = 1; /* Single channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
- XGINew_SetReg1( pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53);
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
+ XGINew_ChannelAB = 2; /* Dual channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
- /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
- /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
- if ( HwDeviceExtension->jChipType == XG42 )
- {
- if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
- && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
- || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
- XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
- }
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_ChannelAB = 1; /* Single channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+
+ if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
+ return;
+ else
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43);
+ }
+
+ break;
+
+ case XG42:
+ /*
+ XG42 SR14 D[3] Reserve
+ D[2] = 1, Dual Channel
+ = 0, Single Channel
+
+ It's Different from Other XG40 Series.
+ */
+ if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
+ XGINew_DataBusWidth = 32; /* 32 bits */
+ XGINew_ChannelAB = 2; /* 2 Channel */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34);
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+
+ XGINew_ChannelAB = 1; /* Single Channel */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40);
+
+ if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
+ return;
+ else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30);
+ }
+ } else { /* DDR */
+ XGINew_DataBusWidth = 64; /* 64 bits */
+ XGINew_ChannelAB = 1; /* 1 channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+ else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
+ }
+ }
+
+ break;
+
+ default: /* XG40 */
+
+ if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
+ XGINew_DataBusWidth = 32; /* 32 bits */
+ XGINew_ChannelAB = 3;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
+
+ if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_ChannelAB = 2; /* 2 channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
+ return;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
+
+ if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
+ XGINew_ChannelAB = 3; /* 4 channels */
+ } else {
+ XGINew_ChannelAB = 2; /* 2 channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
+ }
+ } else { /* DDR */
+ XGINew_DataBusWidth = 64; /* 64 bits */
+ XGINew_ChannelAB = 2; /* 2 channels */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
+
+ if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) {
+ return;
+ } else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
+ }
+ }
+ break;
+ }
+}
+
+int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ int i;
+ unsigned short memsize, addr;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
+ XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ for (i = 0; i < 12; i++) {
+ XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
+ memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
+ if (memsize == 0)
+ continue;
+
+ addr = memsize + (XGINew_ChannelAB - 2) + 20;
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+ continue;
+
+ if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1)
+ return 1;
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
+ memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
+
+ if (memsize == 0)
+ continue;
+
+ addr = memsize + (XGINew_ChannelAB - 2) + 20;
+ if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+ continue;
+
+ if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int XGINew_DDRSizing(struct vb_device_info *pVBInfo)
+{
+ int i;
+ unsigned char j;
+
+ for (i = 0; i < 4; i++) {
+ XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE, pVBInfo);
+ XGINew_DisableChannelInterleaving(i, XGINew_DDRDRAM_TYPE, pVBInfo);
+ for (j = 2; j > 0; j--) {
+ XGINew_SetDDRChannel(i, j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo);
+ if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo)) {
+ continue;
+ } else {
+ if (XGINew_CheckDDRRanks(j, i, XGINew_DDRDRAM_TYPE, pVBInfo))
+ return 1;
+ }
+ }
+ }
+ return 0;
}
+void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A);
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30);
+
+ /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
+ /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
+ if (HwDeviceExtension->jChipType == XG42) {
+ if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C)
+ && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01)
+ && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C)
+ && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))
+ || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22)
+ && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
+ XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : ChkLFB */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char ChkLFB(struct vb_device_info *pVBInfo)
{
- if (LFBDRAMTrap & XGINew_GetReg1(pVBInfo->P3d4 , 0x78))
+ if (LFBDRAMTrap & XGINew_GetReg1(pVBInfo->P3d4, 0x78))
return 1;
else
return 0;
}
-
/* --------------------------------------------------------------------- */
/* input : dx ,valid value : CR or second chip's CR */
/* */
@@ -2645,539 +2181,499 @@ unsigned char ChkLFB(struct vb_device_info *pVBInfo)
/* output : none */
/* --------------------------------------------------------------------- */
void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned long XGI_P3d4Port)
+ unsigned long XGI_P3d4Port)
{
- unsigned long lTemp ;
- unsigned char bTemp;
-
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
- if ((lTemp&0xFF)==0)
- {
- /* set CR58 D[5]=0 D[3]=0 */
- XGINew_SetRegAND( XGI_P3d4Port , 0x58 , 0xD7 ) ;
- bTemp = (unsigned char) XGINew_GetReg1(XGI_P3d4Port, 0xCB);
- if (bTemp&0x20)
- {
- if (!(bTemp&0x10))
- {
- XGINew_SetRegANDOR( XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
- }
- else
- {
- XGINew_SetRegANDOR( XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
- }
-
- }
-
- }
-}
+ unsigned long lTemp;
+ unsigned char bTemp;
+
+ HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x08, 0, &lTemp); /* Get */
+ if ((lTemp & 0xFF) == 0) {
+ /* set CR58 D[5]=0 D[3]=0 */
+ XGINew_SetRegAND(XGI_P3d4Port, 0x58, 0xD7);
+ bTemp = (unsigned char) XGINew_GetReg1(XGI_P3d4Port, 0xCB);
+ if (bTemp & 0x20) {
+ if (!(bTemp & 0x10))
+ XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x20); /* CR58 D[5]=1 D[3]=0 */
+ else
+ XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x08); /* CR58 D[5]=0 D[3]=1 */
+
+ }
+ }
+}
-void XGINew_InitVBIOSData(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+#if 0
+static void XGINew_InitVBIOSData(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- /* unsigned long ROMAddr = (unsigned long)HwDeviceExtension->pjVirtualRomBase; */
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
-
- switch(HwDeviceExtension->jChipType)
- {
+ /* unsigned long ROMAddr = (unsigned long) HwDeviceExtension->pjVirtualRomBase; */
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+ pVBInfo->ISXPDOS = 0;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+ XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
+
+ switch (HwDeviceExtension->jChipType) {
case XG40:
case XG41:
case XG42:
case XG20:
case XG21:
default:
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
- return ;
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+ return;
}
}
+#endif
-/* --------------------------------------------------------------------- */
-/* Function : ReadVBIOSTablData */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
{
- volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
- unsigned long i ;
- unsigned char j, k ;
- /* Volari customize data area end */
-
- if ( ChipType == XG21 )
- {
- pVBInfo->IF_DEF_LVDS = 0 ;
- if (pVideoMemory[ 0x65 ] & 0x1)
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
- j = pVideoMemory[ i-1 ] ;
- if ( j != 0xff )
- {
- k = 0;
- do
- {
- pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
- pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
- pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
- pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
- pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
- pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
- pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
- pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
- pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
- i += 25;
- j--;
- k++;
- } while ((j > 0) &&
- (k < (sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))));
- }
- else
- {
- pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
- pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
- pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
- pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
- pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
- pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
- pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
- pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
- pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
- }
- }
- }
+ volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
+ unsigned long i;
+ unsigned char j, k;
+ /* Volari customize data area end */
+
+ if (ChipType == XG21) {
+ pVBInfo->IF_DEF_LVDS = 0;
+ if (pVideoMemory[0x65] & 0x1) {
+ pVBInfo->IF_DEF_LVDS = 1;
+ i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8);
+ j = pVideoMemory[i - 1];
+ if (j != 0xff) {
+ k = 0;
+ do {
+ pVBInfo->XG21_LVDSCapList[k].LVDS_Capability
+ = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSHT
+ = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSVT
+ = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSHDE
+ = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSVDE
+ = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSHFP
+ = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSVFP
+ = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
+ = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+ pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
+ = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+ pVBInfo->XG21_LVDSCapList[k].VCLKData1
+ = pVideoMemory[i + 18];
+ pVBInfo->XG21_LVDSCapList[k].VCLKData2
+ = pVideoMemory[i + 19];
+ pVBInfo->XG21_LVDSCapList[k].PSC_S1
+ = pVideoMemory[i + 20];
+ pVBInfo->XG21_LVDSCapList[k].PSC_S2
+ = pVideoMemory[i + 21];
+ pVBInfo->XG21_LVDSCapList[k].PSC_S3
+ = pVideoMemory[i + 22];
+ pVBInfo->XG21_LVDSCapList[k].PSC_S4
+ = pVideoMemory[i + 23];
+ pVBInfo->XG21_LVDSCapList[k].PSC_S5
+ = pVideoMemory[i + 24];
+ i += 25;
+ j--;
+ k++;
+ } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct))));
+ } else {
+ pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
+ = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSHT
+ = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSVT
+ = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSHDE
+ = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSVDE
+ = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSHFP
+ = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSVFP
+ = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
+ = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+ pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
+ = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+ pVBInfo->XG21_LVDSCapList[0].VCLKData1
+ = pVideoMemory[i + 18];
+ pVBInfo->XG21_LVDSCapList[0].VCLKData2
+ = pVideoMemory[i + 19];
+ pVBInfo->XG21_LVDSCapList[0].PSC_S1
+ = pVideoMemory[i + 20];
+ pVBInfo->XG21_LVDSCapList[0].PSC_S2
+ = pVideoMemory[i + 21];
+ pVBInfo->XG21_LVDSCapList[0].PSC_S3
+ = pVideoMemory[i + 22];
+ pVBInfo->XG21_LVDSCapList[0].PSC_S4
+ = pVideoMemory[i + 23];
+ pVBInfo->XG21_LVDSCapList[0].PSC_S5
+ = pVideoMemory[i + 24];
+ }
+ }
+ }
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_MRS_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
{
- XGINew_SetReg1( P3c4 , 0x18 , 0x01 ) ;
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 60 ) ;
-
- XGINew_SetReg1( P3c4 , 0x18 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x19 , 0x40 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 60 ) ;
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
- XGINew_SetReg1( P3c4 , 0x19 , 0x01 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x03 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ;
- DelayUS( 1000 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- /* XGINew_SetReg1( P3c4 , 0x18 , 0x31 ) ; */
- XGINew_SetReg1( P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGINew_SetReg1( P3c4 , 0x19 , 0x00 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x03 ) ;
- XGINew_SetReg1( P3c4 , 0x16 , 0x83 ) ;
- XGINew_SetReg1( P3c4 , 0x1B , 0x00 ) ;
+ XGINew_SetReg1(P3c4, 0x18, 0x01);
+ XGINew_SetReg1(P3c4, 0x19, 0x40);
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+ DelayUS(60);
+
+ XGINew_SetReg1(P3c4, 0x18, 0x00);
+ XGINew_SetReg1(P3c4, 0x19, 0x40);
+ XGINew_SetReg1(P3c4, 0x16, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x80);
+ DelayUS(60);
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
+ XGINew_SetReg1(P3c4, 0x19, 0x01);
+ XGINew_SetReg1(P3c4, 0x16, 0x03);
+ XGINew_SetReg1(P3c4, 0x16, 0x83);
+ DelayUS(1000);
+ XGINew_SetReg1(P3c4, 0x1B, 0x03);
+ DelayUS(500);
+ /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
+ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
+ XGINew_SetReg1(P3c4, 0x19, 0x00);
+ XGINew_SetReg1(P3c4, 0x16, 0x03);
+ XGINew_SetReg1(P3c4, 0x16, 0x83);
+ XGINew_SetReg1(P3c4, 0x1B, 0x00);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMModeRegister_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension)
{
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
- else
- XGINew_DDR2_MRS_XG20( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+ pVBInfo->ISXPDOS = 0;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+
+ ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+
+ if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
+ XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
+ else
+ XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
}
-void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension)
+void XGINew_SetDRAMModeRegister_XG27(
+ struct xgi_hw_device_info *HwDeviceExtension)
{
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
- else
- //XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
- XGINew_DDRII_Bootup_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo) ;
-
- //XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+ pVBInfo->ISXPDOS = 0;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+
+ ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+
+ if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
+ XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
+ else
+ /* XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); */
+ XGINew_DDRII_Bootup_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
+
+ /* XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
}
+
/*
void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension)
{
+ unsigned char data;
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
+ pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress;
+ pVBInfo->ISXPDOS = 0;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
+
+ ReadVBIOSTablData(HwDeviceExtension->jChipType , pVBInfo);
+
+ if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
+ XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
+ else
+ XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
- unsigned char data ;
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress ;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
- else
- XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
}
*/
-/* -------------------------------------------------------- */
-/* Function : XGINew_ChkSenseStatus */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+
+void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short tempbx = 0, temp, tempcx, CR3CData;
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x32 ) ;
-
- if ( temp & Monitor1Sense )
- tempbx |= ActiveCRT1 ;
- if ( temp & LCDSense )
- tempbx |= ActiveLCD ;
- if ( temp & Monitor2Sense )
- tempbx |= ActiveCRT2 ;
- if ( temp & TVSense )
- {
- tempbx |= ActiveTV ;
- if ( temp & AVIDEOSense )
- tempbx |= ( ActiveAVideo << 8 );
- if ( temp & SVIDEOSense )
- tempbx |= ( ActiveSVideo << 8 );
- if ( temp & SCARTSense )
- tempbx |= ( ActiveSCART << 8 );
- if ( temp & HiTVSense )
- tempbx |= ( ActiveHiTV << 8 );
- if ( temp & YPbPrSense )
- tempbx |= ( ActiveYPbPr << 8 );
- }
-
- tempcx = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
- tempcx |= ( XGINew_GetReg1( pVBInfo->P3d4 , 0x3e ) << 8 ) ;
-
- if ( tempbx & tempcx )
- {
- CR3CData = XGINew_GetReg1( pVBInfo->P3d4 , 0x3c ) ;
- if ( !( CR3CData & DisplayDeviceFromCMOS ) )
- {
- tempcx = 0x1FF0 ;
- if ( *pVBInfo->pSoftSetting & ModeSoftSetting )
- {
- tempbx = 0x1FF0 ;
- }
- }
- }
- else
- {
- tempcx = 0x1FF0 ;
- if ( *pVBInfo->pSoftSetting & ModeSoftSetting )
- {
- tempbx = 0x1FF0 ;
- }
- }
-
- tempbx &= tempcx ;
- XGINew_SetReg1( pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
- XGINew_SetReg1( pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
+ unsigned short tempbx = 0, temp, tempcx, CR3CData;
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32);
+
+ if (temp & Monitor1Sense)
+ tempbx |= ActiveCRT1;
+ if (temp & LCDSense)
+ tempbx |= ActiveLCD;
+ if (temp & Monitor2Sense)
+ tempbx |= ActiveCRT2;
+ if (temp & TVSense) {
+ tempbx |= ActiveTV;
+ if (temp & AVIDEOSense)
+ tempbx |= (ActiveAVideo << 8);
+ if (temp & SVIDEOSense)
+ tempbx |= (ActiveSVideo << 8);
+ if (temp & SCARTSense)
+ tempbx |= (ActiveSCART << 8);
+ if (temp & HiTVSense)
+ tempbx |= (ActiveHiTV << 8);
+ if (temp & YPbPrSense)
+ tempbx |= (ActiveYPbPr << 8);
+ }
+
+ tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+ tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8);
+
+ if (tempbx & tempcx) {
+ CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c);
+ if (!(CR3CData & DisplayDeviceFromCMOS)) {
+ tempcx = 0x1FF0;
+ if (*pVBInfo->pSoftSetting & ModeSoftSetting)
+ tempbx = 0x1FF0;
+ }
+ } else {
+ tempcx = 0x1FF0;
+ if (*pVBInfo->pSoftSetting & ModeSoftSetting)
+ tempbx = 0x1FF0;
+ }
+
+ tempbx &= tempcx;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
+ XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
}
-/* -------------------------------------------------------- */
-/* Function : XGINew_SetModeScratch */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+
+void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
- temp |= XGINew_GetReg1( pVBInfo->P3d4 , 0x3e ) << 8 ;
- temp |= ( XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
-
- if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
- {
- if ( temp & ActiveCRT2 )
- tempcl = SetCRT2ToRAMDAC ;
- }
-
- if ( temp & ActiveLCD )
- {
- tempcl |= SetCRT2ToLCD ;
- if ( temp & DriverMode )
- {
- if ( temp & ActiveTV )
- {
- tempch = SetToLCDA | EnableDualEdge ;
- temp ^= SetCRT2ToLCD ;
-
- if ( ( temp >> 8 ) & ActiveAVideo )
- tempcl |= SetCRT2ToAVIDEO ;
- if ( ( temp >> 8 ) & ActiveSVideo )
- tempcl |= SetCRT2ToSVIDEO ;
- if ( ( temp >> 8 ) & ActiveSCART )
- tempcl |= SetCRT2ToSCART ;
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( ( temp >> 8 ) & ActiveHiTV )
- tempcl |= SetCRT2ToHiVisionTV ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( ( temp >> 8 ) & ActiveYPbPr )
- tempch |= SetYPbPr ;
- }
- }
- }
- }
- else
- {
- if ( ( temp >> 8 ) & ActiveAVideo )
- tempcl |= SetCRT2ToAVIDEO ;
- if ( ( temp >> 8 ) & ActiveSVideo )
- tempcl |= SetCRT2ToSVIDEO ;
- if ( ( temp >> 8 ) & ActiveSCART )
- tempcl |= SetCRT2ToSCART ;
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( ( temp >> 8 ) & ActiveHiTV )
- tempcl |= SetCRT2ToHiVisionTV ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( ( temp >> 8 ) & ActiveYPbPr )
- tempch |= SetYPbPr ;
- }
- }
-
-
- tempcl |= SetSimuScanMode ;
- if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
- if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
- XGINew_SetReg1( pVBInfo->P3d4, 0x30 , tempcl ) ;
-
- CR31Data = XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
- CR31Data &= ~( SetNotSimuMode >> 8 ) ;
- if ( !( temp & ActiveCRT1 ) )
- CR31Data |= ( SetNotSimuMode >> 8 ) ;
- CR31Data &= ~( DisableCRT2Display >> 8 ) ;
- if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
- CR31Data |= ( DisableCRT2Display >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3d4, 0x31 , CR31Data ) ;
-
- CR38Data = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- CR38Data &= ~SetYPbPr ;
- CR38Data |= tempch ;
- XGINew_SetReg1( pVBInfo->P3d4, 0x38 , CR38Data ) ;
+ unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+ temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8;
+ temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
+
+ if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+ if (temp & ActiveCRT2)
+ tempcl = SetCRT2ToRAMDAC;
+ }
+
+ if (temp & ActiveLCD) {
+ tempcl |= SetCRT2ToLCD;
+ if (temp & DriverMode) {
+ if (temp & ActiveTV) {
+ tempch = SetToLCDA | EnableDualEdge;
+ temp ^= SetCRT2ToLCD;
+
+ if ((temp >> 8) & ActiveAVideo)
+ tempcl |= SetCRT2ToAVIDEO;
+ if ((temp >> 8) & ActiveSVideo)
+ tempcl |= SetCRT2ToSVIDEO;
+ if ((temp >> 8) & ActiveSCART)
+ tempcl |= SetCRT2ToSCART;
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if ((temp >> 8) & ActiveHiTV)
+ tempcl |= SetCRT2ToHiVisionTV;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if ((temp >> 8) & ActiveYPbPr)
+ tempch |= SetYPbPr;
+ }
+ }
+ }
+ } else {
+ if ((temp >> 8) & ActiveAVideo)
+ tempcl |= SetCRT2ToAVIDEO;
+ if ((temp >> 8) & ActiveSVideo)
+ tempcl |= SetCRT2ToSVIDEO;
+ if ((temp >> 8) & ActiveSCART)
+ tempcl |= SetCRT2ToSCART;
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if ((temp >> 8) & ActiveHiTV)
+ tempcl |= SetCRT2ToHiVisionTV;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if ((temp >> 8) & ActiveYPbPr)
+ tempch |= SetYPbPr;
+ }
+ }
+
+ tempcl |= SetSimuScanMode;
+ if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
+ || (temp & ActiveCRT2)))
+ tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+ if ((temp & ActiveLCD) && (temp & ActiveTV))
+ tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl);
+
+ CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
+ CR31Data &= ~(SetNotSimuMode >> 8);
+ if (!(temp & ActiveCRT1))
+ CR31Data |= (SetNotSimuMode >> 8);
+ CR31Data &= ~(DisableCRT2Display >> 8);
+ if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2)))
+ CR31Data |= (DisableCRT2Display >> 8);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data);
+
+ CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ CR38Data &= ~SetYPbPr;
+ CR38Data |= tempch;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data);
}
-/* -------------------------------------------------------- */
-/* Function : XGINew_GetXG21Sense */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned char Temp;
- volatile unsigned char *pVideoMemory = (unsigned char *)pVBInfo->ROMAddr;
+ unsigned char Temp;
+ volatile unsigned char *pVideoMemory =
+ (unsigned char *) pVBInfo->ROMAddr;
- pVBInfo->IF_DEF_LVDS = 0 ;
+ pVBInfo->IF_DEF_LVDS = 0;
#if 1
- if (( pVideoMemory[ 0x65 ] & 0x01 ) ) /* For XG21 LVDS */
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS on chip */
- }
- else
- {
+ if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
+ pVBInfo->IF_DEF_LVDS = 1;
+ XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */
+ } else {
#endif
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* Enable GPIOA/B read */
- Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0xC0;
- if ( Temp == 0xC0 )
- { /* DVI & DVO GPIOA/B pull high */
- XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) ;
- XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x20 , 0x20 ) ; /* Enable read GPIOF */
- Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0x04 ;
- if ( !Temp )
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x80 ) ; /* TMDS on chip */
- else
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* Only DVO on chip */
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Disable read GPIOF */
- }
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */
+ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0;
+ if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
+ XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
+ XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */
+ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04;
+ if (!Temp)
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */
+ else
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */
+ }
#if 1
- }
+ }
#endif
}
-/* -------------------------------------------------------- */
-/* Function : XGINew_GetXG27Sense */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
unsigned char Temp, bCR4A;
- pVBInfo->IF_DEF_LVDS = 0 ;
- bCR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x07 , 0x07 ) ; /* Enable GPIOA/B/C read */
- Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) & 0x07;
- XGINew_SetReg1( pVBInfo->P3d4, 0x4A , bCR4A ) ;
-
- if ( Temp <= 0x02 )
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS setting */
- XGINew_SetReg1( pVBInfo->P3d4, 0x30 , 0x21 ) ;
- }
- else
- {
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* TMDS/DVO setting */
- }
- XGINew_SetRegOR( pVBInfo->P3d4 , 0x32 , LCDSense ) ;
+ pVBInfo->IF_DEF_LVDS = 0;
+ bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */
+ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A);
+
+ if (Temp <= 0x02) {
+ pVBInfo->IF_DEF_LVDS = 1;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21);
+ } else {
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */
+ }
+ XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
}
@@ -3185,39 +2681,35 @@ unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
{
unsigned char CR38, CR4A, temp;
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x10 , 0x10 ) ; /* enable GPIOE read */
- CR38 = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- temp =0;
- if ( ( CR38 & 0xE0 ) > 0x80 )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
- temp &= 0x08;
- temp >>= 3;
- }
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */
+ CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ temp = 0;
+ if ((CR38 & 0xE0) > 0x80) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
+ temp &= 0x08;
+ temp >>= 3;
+ }
- XGINew_SetReg1( pVBInfo->P3d4, 0x4A , CR4A ) ;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
- return temp;
+ return temp;
}
unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
{
unsigned char CR4A, temp;
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* enable GPIOA/B/C read */
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
- if ( temp <= 2 )
- {
- temp &= 0x03;
- }
- else
- {
- temp = ((temp&0x04)>>1) || ((~temp)&0x01);
- }
- XGINew_SetReg1( pVBInfo->P3d4, 0x4A , CR4A ) ;
-
- return temp;
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
+ if (temp <= 2)
+ temp &= 0x03;
+ else
+ temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01);
+
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+
+ return temp;
}
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index d90bf06bf62f..7016fdd2509f 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -22,50 +22,50 @@
unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo);
unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo);
unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo);
unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo);
unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo);
unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- unsigned short *i, struct vb_device_info *pVBInfo);
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ unsigned short *i, struct vb_device_info *pVBInfo);
unsigned char XGI_SearchModeID(unsigned short ModeNo,
- unsigned short *ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ unsigned short *ModeIdIndex,
+ struct vb_device_info *pVBInfo);
unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo);
unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo);
+ unsigned short ModeNo);
unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo);
-unsigned char XGI_GetModePtr(unsigned short ModeNo,
+unsigned char XGI_GetModePtr(unsigned short ModeNo,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo);
unsigned short XGI_GetOffset(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo);
unsigned short XGI_GetResInfo(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo);
unsigned short XGI_GetColorDepth(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo);
unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo);
unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
void XGI_VBLongWait(struct vb_device_info *pVBInfo);
void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo);
void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
@@ -122,12 +122,13 @@ void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, u
/*void XGI_ClearBuffer(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, struct vb_device_info *pVBInfo);*/
void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ struct vb_device_info *pVBInfo);
void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
+unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo);
void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo);
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo);
void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo);
void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
@@ -151,7 +152,7 @@ void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, s
void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo);
void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl,
- unsigned char *tempch, struct vb_device_info *pVBInfo);
+ unsigned char *tempch, struct vb_device_info *pVBInfo);
unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo);
void XGI_SetCRT2ModeRegs(unsigned short ModeNo, struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo);
@@ -164,11 +165,11 @@ void XGINew_LCD_Wait_Time(unsigned char DelayTime, struct vb_device_info *pV
void XGI_LongWait(struct vb_device_info *pVBInfo);
void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
- struct vb_device_info *pVBInfo);
+ struct vb_device_info *pVBInfo);
unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo);
+ unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo);
void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
unsigned char *di_1, struct vb_device_info *pVBInfo);
unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo);
@@ -191,7 +192,7 @@ extern void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVB
/* unsigned short XGINew_flag_clearbuffer; 0: no clear frame buffer 1:clear frame buffer */
-unsigned short XGINew_MDA_DAC[] = {
+static unsigned short XGINew_MDA_DAC[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
@@ -201,7 +202,7 @@ unsigned short XGINew_MDA_DAC[] = {
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F};
-unsigned short XGINew_CGA_DAC[] = {
+static unsigned short XGINew_CGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
@@ -211,7 +212,7 @@ unsigned short XGINew_CGA_DAC[] = {
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
-unsigned short XGINew_EGA_DAC[] = {
+static unsigned short XGINew_EGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
@@ -221,7 +222,7 @@ unsigned short XGINew_EGA_DAC[] = {
0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
-unsigned short XGINew_VGA_DAC[] = {
+static unsigned short XGINew_VGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
@@ -233,1282 +234,1053 @@ unsigned short XGINew_VGA_DAC[] = {
0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
0x0B, 0x0C, 0x0D, 0x0F, 0x10};
-
-/* --------------------------------------------------------------------- */
-/* Function : InitTo330Pointer */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
{
- pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable ;
- pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable ;
- pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable ;
- pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex ;
- pVBInfo->XGINEWUB_CRT1Table = (struct XGI_CRT1TableStruct *) XGI_CRT1Table ;
-
- /* add for new UNIVGABIOS */
- /* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
- /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
-
-
- if ( ChipType >= XG40 )
- {
- pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
- pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
- }
- else
- {
- pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI330New_MCLKData;
- pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI330_ECLKData;
- }
-
- pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData ;
- pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData ;
- pVBInfo->ScreenOffset = XGI330_ScreenOffset ;
- pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo ;
- pVBInfo->ModeResInfo = (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo ;
-
- pVBInfo->pOutputSelect = &XGI330_OutputSelect ;
- pVBInfo->pSoftSetting = &XGI330_SoftSetting ;
- pVBInfo->pSR07 = &XGI330_SR07 ;
- pVBInfo->LCDResInfo = 0 ;
- pVBInfo->LCDTypeInfo = 0 ;
- pVBInfo->LCDInfo = 0 ;
- pVBInfo->VBInfo = 0 ;
- pVBInfo->TVInfo = 0;
-
-
- pVBInfo->SR15 = XGI340_SR13 ;
- pVBInfo->CR40 = XGI340_cr41 ;
- pVBInfo->SR25 = XGI330_sr25 ;
- pVBInfo->pSR31 = &XGI330_sr31 ;
- pVBInfo->pSR32 = &XGI330_sr32 ;
- pVBInfo->CR6B = XGI340_CR6B ;
- pVBInfo->CR6E = XGI340_CR6E ;
- pVBInfo->CR6F = XGI340_CR6F ;
- pVBInfo->CR89 = XGI340_CR89 ;
- pVBInfo->AGPReg = XGI340_AGPReg ;
- pVBInfo->SR16 = XGI340_SR16 ;
- pVBInfo->pCRCF = &XG40_CRCF ;
- pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition ;
-
-
- pVBInfo->CR49 = XGI330_CR49 ;
- pVBInfo->pSR1F = &XGI330_SR1F ;
- pVBInfo->pSR21 = &XGI330_SR21 ;
- pVBInfo->pSR22 = &XGI330_SR22 ;
- pVBInfo->pSR23 = &XGI330_SR23 ;
- pVBInfo->pSR24 = &XGI330_SR24 ;
- pVBInfo->pSR33 = &XGI330_SR33 ;
-
-
-
- pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2 ;
- pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D ;
- pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E ;
- pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10 ;
- pVBInfo->pRGBSenseData = &XGI330_RGBSenseData ;
- pVBInfo->pVideoSenseData = &XGI330_VideoSenseData ;
- pVBInfo->pYCSenseData = &XGI330_YCSenseData ;
- pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2 ;
- pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2 ;
- pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2 ;
-
- pVBInfo->NTSCTiming = XGI330_NTSCTiming ;
- pVBInfo->PALTiming = XGI330_PALTiming ;
- pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming ;
- pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing ;
- pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing ;
- pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming ;
- pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming ;
- pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming ;
- pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming ;
- pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data ;
- pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu ;
- pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text ;
- pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3 ;
- pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3 ;
-
-
- pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH ;
- pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV ;
- pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
-
- pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC ;
- pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC ;
- pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL ;
- pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL ;
-
- /* 310 customization related */
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- pVBInfo->LCDCapList = XGI_LCDDLCapList ;
- else
- pVBInfo->LCDCapList = XGI_LCDCapList ;
-
- if ( ( ChipType == XG21 ) || ( ChipType == XG27 ) )
- pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList ;
-
- pVBInfo->XGI_TVDelayList = XGI301TVDelayList ;
- pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2 ;
-
-
- pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition ;
-
- if ( ChipType >= XG20 )
- pVBInfo->pXGINew_CR97 = &XG20_CR97 ;
-
- if ( ChipType == XG27 )
- {
- pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
- pVBInfo->CR40 = XGI27_cr41 ;
- pVBInfo->pXGINew_CR97 = &XG27_CR97 ;
- pVBInfo->pSR36 = &XG27_SR36 ;
- pVBInfo->pCR8F = &XG27_CR8F ;
- pVBInfo->pCRD0 = XG27_CRD0 ;
- pVBInfo->pCRDE = XG27_CRDE ;
- pVBInfo->pSR40 = &XG27_SR40 ;
- pVBInfo->pSR41 = &XG27_SR41 ;
-
- }
-
- if ( ChipType >= XG20 )
- {
- pVBInfo->pDVOSetting = &XG21_DVOSetting ;
- pVBInfo->pCR2E = &XG21_CR2E ;
- pVBInfo->pCR2F = &XG21_CR2F ;
- pVBInfo->pCR46 = &XG21_CR46 ;
- pVBInfo->pCR47 = &XG21_CR47 ;
- }
+ pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable;
+ pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable;
+ pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable;
+ pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex;
+ pVBInfo->XGINEWUB_CRT1Table
+ = (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
+
+ /* add for new UNIVGABIOS */
+ /* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
+ /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */
+
+ if (ChipType >= XG40) {
+ pVBInfo->MCLKData
+ = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
+ pVBInfo->ECLKData
+ = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
+ } else {
+ pVBInfo->MCLKData
+ = (struct XGI_MCLKDataStruct *) XGI330New_MCLKData;
+ pVBInfo->ECLKData
+ = (struct XGI_ECLKDataStruct *) XGI330_ECLKData;
+ }
-}
+ pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData;
+ pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData;
+ pVBInfo->ScreenOffset = XGI330_ScreenOffset;
+ pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo;
+ pVBInfo->ModeResInfo
+ = (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo;
+
+ pVBInfo->pOutputSelect = &XGI330_OutputSelect;
+ pVBInfo->pSoftSetting = &XGI330_SoftSetting;
+ pVBInfo->pSR07 = &XGI330_SR07;
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+ pVBInfo->VBInfo = 0;
+ pVBInfo->TVInfo = 0;
+
+ pVBInfo->SR15 = XGI340_SR13;
+ pVBInfo->CR40 = XGI340_cr41;
+ pVBInfo->SR25 = XGI330_sr25;
+ pVBInfo->pSR31 = &XGI330_sr31;
+ pVBInfo->pSR32 = &XGI330_sr32;
+ pVBInfo->CR6B = XGI340_CR6B;
+ pVBInfo->CR6E = XGI340_CR6E;
+ pVBInfo->CR6F = XGI340_CR6F;
+ pVBInfo->CR89 = XGI340_CR89;
+ pVBInfo->AGPReg = XGI340_AGPReg;
+ pVBInfo->SR16 = XGI340_SR16;
+ pVBInfo->pCRCF = &XG40_CRCF;
+ pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition;
+
+ pVBInfo->CR49 = XGI330_CR49;
+ pVBInfo->pSR1F = &XGI330_SR1F;
+ pVBInfo->pSR21 = &XGI330_SR21;
+ pVBInfo->pSR22 = &XGI330_SR22;
+ pVBInfo->pSR23 = &XGI330_SR23;
+ pVBInfo->pSR24 = &XGI330_SR24;
+ pVBInfo->pSR33 = &XGI330_SR33;
+
+ pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2;
+ pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D;
+ pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E;
+ pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10;
+ pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
+ pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
+ pVBInfo->pYCSenseData = &XGI330_YCSenseData;
+ pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
+ pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
+ pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
+
+ pVBInfo->NTSCTiming = XGI330_NTSCTiming;
+ pVBInfo->PALTiming = XGI330_PALTiming;
+ pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
+ pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
+ pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
+ pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
+ pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
+ pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
+ pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
+ pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
+ pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
+ pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
+ pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
+ pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
+
+ pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH;
+ pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV;
+ pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table;
+
+ pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
+ pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
+ pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
+ pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
+
+ /* 310 customization related */
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
+ pVBInfo->LCDCapList = XGI_LCDDLCapList;
+ else
+ pVBInfo->LCDCapList = XGI_LCDCapList;
+ if ((ChipType == XG21) || (ChipType == XG27))
+ pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList;
+ pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
+ pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
+ pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition;
+ if (ChipType >= XG20)
+ pVBInfo->pXGINew_CR97 = &XG20_CR97;
+ if (ChipType == XG27) {
+ pVBInfo->MCLKData
+ = (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
+ pVBInfo->CR40 = XGI27_cr41;
+ pVBInfo->pXGINew_CR97 = &XG27_CR97;
+ pVBInfo->pSR36 = &XG27_SR36;
+ pVBInfo->pCR8F = &XG27_CR8F;
+ pVBInfo->pCRD0 = XG27_CRD0;
+ pVBInfo->pCRDE = XG27_CRDE;
+ pVBInfo->pSR40 = &XG27_SR40;
+ pVBInfo->pSR41 = &XG27_SR41;
+
+ }
+
+ if (ChipType >= XG20) {
+ pVBInfo->pDVOSetting = &XG21_DVOSetting;
+ pVBInfo->pCR2E = &XG21_CR2E;
+ pVBInfo->pCR2F = &XG21_CR2F;
+ pVBInfo->pCR46 = &XG21_CR46;
+ pVBInfo->pCR47 = &XG21_CR47;
+ }
+
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGISetModeNew */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo)
-{
- unsigned short ModeIdIndex ;
- /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
- struct vb_device_info VBINF;
- struct vb_device_info *pVBInfo = &VBINF;
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->BaseAddr = (unsigned long)HwDeviceExtension->pjIOAddress ;
- pVBInfo->IF_DEF_LVDS = 0 ;
- pVBInfo->IF_DEF_CH7005 = 0 ;
- pVBInfo->IF_DEF_LCDA = 1 ;
- pVBInfo->IF_DEF_CH7017 = 0 ;
- pVBInfo->IF_DEF_CH7007 = 0 ; /* [Billy] 2007/05/14 */
- pVBInfo->IF_DEF_VideoCapture = 0 ;
- pVBInfo->IF_DEF_ScaleLCD = 0 ;
- pVBInfo->IF_DEF_OEMUtil = 0 ;
- pVBInfo->IF_DEF_PWD = 0 ;
-
-
- if ( HwDeviceExtension->jChipType >= XG20 ) /* kuku 2004/06/25 */
- {
- pVBInfo->IF_DEF_YPbPr = 0 ;
- pVBInfo->IF_DEF_HiVision = 0 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- pVBInfo->VBType = 0 ; /*set VBType default 0*/
- }
- else if ( HwDeviceExtension->jChipType >= XG40 )
- {
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 1 ;
- }
- else
- {
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- }
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- if ( HwDeviceExtension->jChipType == XG21 ) /* for x86 Linux, XG21 LVDS */
- {
- if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- }
- }
- if ( HwDeviceExtension->jChipType == XG27 )
- {
- if ( ( XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
- {
- if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) & 0x20 )
- {
- pVBInfo->IF_DEF_LVDS = 1 ;
- }
- }
- }
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- XGI_GetVBType( pVBInfo ) ;
-
- InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
- if ( ModeNo & 0x80 )
- {
- ModeNo = ModeNo & 0x7F ;
-/* XGINew_flag_clearbuffer = 0 ; */
- }
-/* else
- {
- XGINew_flag_clearbuffer = 1 ;
- }
-*/
- XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 1.Openkey */
- XGI_UnLockCRT2( HwDeviceExtension , pVBInfo ) ;
-
- XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
-
- XGI_GetVGAType(HwDeviceExtension, pVBInfo) ;
-
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
- {
- XGI_GetVBInfo(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_GetTVInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetLCDInfo(ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_DisableBridge( HwDeviceExtension,pVBInfo ) ;
-/* XGI_OpenCRTC( HwDeviceExtension, pVBInfo ) ; */
-
- if ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToLCDA ) )
- {
- XGI_SetCRT1Group(HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- XGI_SetLCDAGroup(ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
- }
- }
- else
- {
- if ( !( pVBInfo->VBInfo & SwitchToCRT2) )
- {
- XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- XGI_SetLCDAGroup( ModeNo , ModeIdIndex , HwDeviceExtension, pVBInfo ) ;
- }
- }
- }
-
- if ( pVBInfo->VBInfo & ( SetSimuScanMode | SwitchToCRT2 ) )
- {
- switch( HwDeviceExtension->ujVBChipID )
- {
- case VB_CHIP_301:
- XGI_SetCRT2Group301( ModeNo , HwDeviceExtension, pVBInfo ) ; /*add for CRT2 */
- break ;
-
- case VB_CHIP_302:
- XGI_SetCRT2Group301(ModeNo , HwDeviceExtension, pVBInfo ) ; /*add for CRT2 */
- break ;
-
- default:
- break ;
- }
- }
-
- XGI_SetCRT2ModeRegs( ModeNo, HwDeviceExtension,pVBInfo ) ;
- XGI_OEM310Setting( ModeNo, ModeIdIndex,pVBInfo ) ; /*0212*/
- XGI_CloseCRTC( HwDeviceExtension, pVBInfo ) ;
- XGI_EnableBridge( HwDeviceExtension ,pVBInfo) ;
- } /* !XG20 */
- else
- {
- if (pVBInfo->IF_DEF_LVDS == 1)
- if (!XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo))
- return 0;
-
- if ( ModeNo <= 0x13 )
- {
- pVBInfo->ModeType = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag & ModeInfoFlag;
- }
- else
- {
- pVBInfo->ModeType = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag & ModeInfoFlag;
- }
-
- pVBInfo->SetFlag = 0 ;
- if ( pVBInfo->IF_DEF_CH7007 != 1 )
- {
- pVBInfo->VBInfo = DisableCRT2Display ;
- }
-
-
- XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
-
- XGI_SetCRT1Group(HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
-
- XGI_DisplayOn( HwDeviceExtension, pVBInfo ) ;
- /*
- if( HwDeviceExtension->jChipType == XG21 )
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0x80 , 0x80 ) ;
- */
- }
+ unsigned short ModeNo)
+{
+ unsigned short ModeIdIndex;
+ /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */
+ struct vb_device_info VBINF;
+ struct vb_device_info *pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
+ pVBInfo->IF_DEF_LVDS = 0;
+ pVBInfo->IF_DEF_CH7005 = 0;
+ pVBInfo->IF_DEF_LCDA = 1;
+ pVBInfo->IF_DEF_CH7017 = 0;
+ pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */
+ pVBInfo->IF_DEF_VideoCapture = 0;
+ pVBInfo->IF_DEF_ScaleLCD = 0;
+ pVBInfo->IF_DEF_OEMUtil = 0;
+ pVBInfo->IF_DEF_PWD = 0;
+
+ if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */
+ pVBInfo->IF_DEF_YPbPr = 0;
+ pVBInfo->IF_DEF_HiVision = 0;
+ pVBInfo->IF_DEF_CRT2Monitor = 0;
+ pVBInfo->VBType = 0; /*set VBType default 0*/
+ } else if (HwDeviceExtension->jChipType >= XG40) {
+ pVBInfo->IF_DEF_YPbPr = 1;
+ pVBInfo->IF_DEF_HiVision = 1;
+ pVBInfo->IF_DEF_CRT2Monitor = 1;
+ } else {
+ pVBInfo->IF_DEF_YPbPr = 1;
+ pVBInfo->IF_DEF_HiVision = 1;
+ pVBInfo->IF_DEF_CRT2Monitor = 0;
+ }
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
+ pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+
+ if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */
+ if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
+ pVBInfo->IF_DEF_LVDS = 1;
+ }
+ if (HwDeviceExtension->jChipType == XG27) {
+ if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
+ if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
+ pVBInfo->IF_DEF_LVDS = 1;
+ }
+ }
-/*
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
- pVBInfo->ModeType = modeflag&ModeInfoFlag ;
- pVBInfo->SetFlag = 0x00 ;
- pVBInfo->VBInfo = DisableCRT2Display ;
- temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
-
- if ( temp == 0 )
- return( 0 ) ;
-
- XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
- XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
-*/
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+ XGI_GetVBType(pVBInfo);
- XGI_UpdateModeInfo( HwDeviceExtension, pVBInfo ) ;
+ InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
+ if (ModeNo & 0x80) {
+ ModeNo = ModeNo & 0x7F;
+ /* XGINew_flag_clearbuffer = 0; */
+ }
+ /* else {
+ XGINew_flag_clearbuffer = 1;
+ }
+ */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
+
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
+ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+
+ XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+
+ XGI_GetVGAType(HwDeviceExtension, pVBInfo);
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
+ XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_DisableBridge(HwDeviceExtension, pVBInfo);
+ /* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */
+
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
+ HwDeviceExtension, pVBInfo);
+ }
+ } else {
+ if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
+ HwDeviceExtension,
+ pVBInfo);
+ }
+ }
+ }
+
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301:
+ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
+ pVBInfo); /*add for CRT2 */
+ break;
+
+ case VB_CHIP_302:
+ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
+ pVBInfo); /*add for CRT2 */
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
+ XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
+ XGI_CloseCRTC(HwDeviceExtension, pVBInfo);
+ XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+ } /* !XG20 */
+ else {
+ if (pVBInfo->IF_DEF_LVDS == 1)
+ if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
+ return 0;
+
+ if (ModeNo <= 0x13) {
+ pVBInfo->ModeType
+ = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+ & ModeInfoFlag;
+ } else {
+ pVBInfo->ModeType
+ = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag
+ & ModeInfoFlag;
+ }
+
+ pVBInfo->SetFlag = 0;
+ if (pVBInfo->IF_DEF_CH7007 != 1)
+ pVBInfo->VBInfo = DisableCRT2Display;
+
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
+ pVBInfo);
+
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ /*
+ if (HwDeviceExtension->jChipType == XG21)
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80);
+ */
+ }
- if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
-{
- XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
-}
+ /*
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+ pVBInfo->ModeType = modeflag&ModeInfoFlag;
+ pVBInfo->SetFlag = 0x00;
+ pVBInfo->VBInfo = DisableCRT2Display;
+ temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
- return 1;
-}
+ if (temp == 0)
+ return (0);
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ */
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Group */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo,
- unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short StandTableIndex ,
- RefreshRateTableIndex ,
- b3CC ,
- temp ;
-
- unsigned short XGINew_P3cc = pVBInfo->P3cc;
-
- /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
- StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
- /* XGI_SetBIOSData(ModeNo , ModeIdIndex ) ; */
- /* XGI_ClearBankRegs( ModeNo , ModeIdIndex ) ; */
- XGI_SetSeqRegs( ModeNo , StandTableIndex , ModeIdIndex, pVBInfo ) ;
- XGI_SetMiscRegs( StandTableIndex, pVBInfo ) ;
- XGI_SetCRTCRegs( HwDeviceExtension , StandTableIndex, pVBInfo) ;
- XGI_SetATTRegs( ModeNo , StandTableIndex , ModeIdIndex, pVBInfo ) ;
- XGI_SetGRCRegs( StandTableIndex, pVBInfo ) ;
- XGI_ClearExt1Regs(pVBInfo) ;
-
-/* if ( pVBInfo->IF_DEF_ExpLink ) */
- if ( HwDeviceExtension->jChipType == XG27 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- XGI_SetDefaultVCLK( pVBInfo ) ;
- }
- }
-
- temp = ~ProgrammingCRT2 ;
- pVBInfo->SetFlag &= temp ;
- pVBInfo->SelectCRT2Rate = 0 ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode ) )
- {
- pVBInfo->SetFlag |= ProgrammingCRT2 ;
- }
- }
-
- RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( RefreshRateTableIndex != 0xFFFF )
- {
- XGI_SetSync( RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetCRT1CRTC( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo, HwDeviceExtension ) ;
- XGI_SetCRT1DE( HwDeviceExtension , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetCRT1Offset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT1VCLK( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
- }
-
- if ( ( HwDeviceExtension->jChipType >= XG20 )&&
- ( HwDeviceExtension->jChipType < XG27 ) ) /* fix H/W DCLK/2 bug */
- {
- if ( ( ModeNo == 0x00 ) | (ModeNo == 0x01) )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x4E) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE9) ;
- b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc) ;
- XGINew_SetReg3(XGINew_P3cc , (b3CC |= 0x0C) ) ;
- }
- else if ( ( ModeNo == 0x04) | ( ModeNo == 0x05) | ( ModeNo == 0x0D) )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE3) ;
- b3CC = (unsigned char)XGINew_GetReg2(XGINew_P3cc) ;
- XGINew_SetReg3(XGINew_P3cc , (b3CC |= 0x0C) ) ;
- }
- }
-
- if ( HwDeviceExtension->jChipType >= XG21 )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
- if ( temp & 0xA0 )
- {
-
- /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ;*/ /* Enable write GPIOF */
- /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* P. DWN */
- /* XG21 CRT1 Timing */
- if ( HwDeviceExtension->jChipType == XG27 )
- XGI_SetXG27CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
- else
- XGI_SetXG21CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
-
- XGI_UpdateXG21CRTC( ModeNo , pVBInfo , RefreshRateTableIndex) ;
-
- if ( HwDeviceExtension->jChipType == XG27 )
- XGI_SetXG27LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
- else
- XGI_SetXG21LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
-
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- if ( HwDeviceExtension->jChipType == XG27 )
- XGI_SetXG27LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
- else
- XGI_SetXG21LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
- }
- /*XGINew_SetRegOR( pVBInfo->P3d4 , 0x48 , 0x20 ) ;*/ /* P. ON */
- }
- }
-
- pVBInfo->SetFlag &= ( ~ProgrammingCRT2 ) ;
- XGI_SetCRT1FIFO( ModeNo , HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT1ModeRegs( HwDeviceExtension , ModeNo , ModeIdIndex , RefreshRateTableIndex , pVBInfo) ;
-
-
- /* XGI_LoadCharacter(); //dif ifdef TVFont */
-
- XGI_LoadDAC( ModeNo , ModeIdIndex, pVBInfo ) ;
- /* XGI_ClearBuffer( HwDeviceExtension , ModeNo, pVBInfo ) ; */
+ XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ XGI_LockCRT2(HwDeviceExtension, pVBInfo);
+ }
+
+ return 1;
}
+void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp;
+
+ unsigned short XGINew_P3cc = pVBInfo->P3cc;
+
+ /* XGINew_CRT1Mode = ModeNo; // SaveModeID */
+ StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+ /* XGI_SetBIOSData(ModeNo, ModeIdIndex); */
+ /* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */
+ XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+ XGI_SetMiscRegs(StandTableIndex, pVBInfo);
+ XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo);
+ XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+ XGI_SetGRCRegs(StandTableIndex, pVBInfo);
+ XGI_ClearExt1Regs(pVBInfo);
+
+ /* if (pVBInfo->IF_DEF_ExpLink) */
+ if (HwDeviceExtension->jChipType == XG27) {
+ if (pVBInfo->IF_DEF_LVDS == 0)
+ XGI_SetDefaultVCLK(pVBInfo);
+ }
+
+ temp = ~ProgrammingCRT2;
+ pVBInfo->SetFlag &= temp;
+ pVBInfo->SelectCRT2Rate = 0;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA
+ | SetInSlaveMode)) {
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ }
+ }
+
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ if (RefreshRateTableIndex != 0xFFFF) {
+ XGI_SetSync(RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo, HwDeviceExtension);
+ XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ }
+
+ if ((HwDeviceExtension->jChipType >= XG20)
+ && (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
+ if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9);
+ b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
+ XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
+ } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo
+ == 0x0D)) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3);
+ b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc);
+ XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C));
+ }
+ }
+
+ if (HwDeviceExtension->jChipType >= XG21) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+ if (temp & 0xA0) {
+
+ /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */
+ /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */
+ /* XG21 CRT1 Timing */
+ if (HwDeviceExtension->jChipType == XG27)
+ XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ else
+ XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+
+ XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
+ RefreshRateTableIndex);
+
+ if (HwDeviceExtension->jChipType == XG27)
+ XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex,
+ ModeNo);
+ else
+ XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex,
+ ModeNo);
+
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ if (HwDeviceExtension->jChipType == XG27)
+ XGI_SetXG27LVDSPara(ModeNo,
+ ModeIdIndex, pVBInfo);
+ else
+ XGI_SetXG21LVDSPara(ModeNo,
+ ModeIdIndex, pVBInfo);
+ }
+ /* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */
+ }
+ }
+
+ pVBInfo->SetFlag &= (~ProgrammingCRT2);
+ XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+
+ /* XGI_LoadCharacter(); //dif ifdef TVFont */
+
+ XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
+ /* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetModePtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
+ struct vb_device_info *pVBInfo)
{
- unsigned char index ;
+ unsigned char index;
- if ( ModeNo <= 0x13 )
- index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_StTableIndex ;
- else
- {
- if ( pVBInfo->ModeType <= 0x02 )
- index = 0x1B ; /* 02 -> ModeEGA */
- else
- index = 0x0F ;
- }
- return( index ) ; /* Get pVBInfo->StandTable index */
+ if (ModeNo <= 0x13)
+ index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex;
+ else {
+ if (pVBInfo->ModeType <= 0x02)
+ index = 0x1B; /* 02 -> ModeEGA */
+ else
+ index = 0x0F;
+ }
+ return index; /* Get pVBInfo->StandTable index */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetBIOSData */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-/*unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex)
-{
- return( 0 ) ;
+/*
+unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) {
+ return (0);
}
*/
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ClearBankRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-/*unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex)
-{
- return( 0 ) ;
+/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) {
+ return( 0 ) ;
}
*/
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetSeqRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
- unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
{
- unsigned char tempah ,
- SRdata ;
-
- unsigned short i ,
- modeflag ;
-
- if ( ModeNo <= 0x13 )
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- else
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
+ unsigned char tempah, SRdata;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x00 , 0x03 ) ; /* Set SR0 */
- tempah=pVBInfo->StandTable[ StandTableIndex ].SR[ 0 ] ;
+ unsigned short i, modeflag;
- i = SetCRT2ToLCDA ;
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- tempah |= 0x01 ;
- }
- else
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- tempah |= 0x01 ;
- }
- }
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
+ tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
+
+ i = SetCRT2ToLCDA;
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ tempah |= 0x01;
+ } else {
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempah |= 0x01;
+ }
+ }
- tempah |= 0x20 ; /* screen off */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , tempah ) ; /* Set SR1 */
+ tempah |= 0x20; /* screen off */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
- for( i = 02 ; i <= 04 ; i++ )
- {
- SRdata = pVBInfo->StandTable[ StandTableIndex ].SR[ i - 1 ] ; /* Get SR2,3,4 from file */
- XGINew_SetReg1( pVBInfo->P3c4 , i , SRdata ) ; /* Set SR2 3 4 */
- }
+ for (i = 02; i <= 04; i++) {
+ SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */
+ XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetMiscRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+void XGI_SetMiscRegs(unsigned short StandTableIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned char Miscdata ;
+ unsigned char Miscdata;
- Miscdata = pVBInfo->StandTable[ StandTableIndex ].MISC ; /* Get Misc from file */
-/*
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- Miscdata |= 0x0C ;
- }
- }
-*/
+ Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
+ /*
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ Miscdata |= 0x0C;
+ }
+ }
+ */
- XGINew_SetReg3( pVBInfo->P3c2 , Miscdata ) ; /* Set Misc(3c2) */
+ XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRTCRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+ unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
{
- unsigned char CRTCdata ;
- unsigned short i ;
+ unsigned char CRTCdata;
+ unsigned short i;
- CRTCdata = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
- CRTCdata &= 0x7f ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , CRTCdata ) ; /* Unlock CRTC */
+ CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ CRTCdata &= 0x7f;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
- for( i = 0 ; i <= 0x18 ; i++ )
- {
- CRTCdata = pVBInfo->StandTable[ StandTableIndex ].CRTC[ i ] ; /* Get CRTC from file */
- XGINew_SetReg1( pVBInfo->P3d4 , i , CRTCdata ) ; /* Set CRTC( 3d4 ) */
- }
-/*
- if ( ( HwDeviceExtension->jChipType == XGI_630 )&& ( HwDeviceExtension->jChipRevision == 0x30 ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) )
- {
- XGINew_SetReg1( pVBInfo->P3d4 , 0x18 , 0xFE ) ;
- }
- }
- }
-*/
+ for (i = 0; i <= 0x18; i++) {
+ CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */
+ XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
+ }
+ /*
+ if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE);
+ }
+ }
+ }
+ */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
- unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned char ARdata ;
- unsigned short i, modeflag;
-
- if ( ModeNo <= 0x13 )
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- else
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
-
- for( i = 0 ; i <= 0x13 ; i++ )
- {
- ARdata = pVBInfo->StandTable[ StandTableIndex ].ATTR[ i ] ;
- if ( modeflag & Charx8Dot ) /* ifndef Dot9 */
- {
- if ( i == 0x13 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- ARdata = 0 ;
- else
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- ARdata = 0 ;
- }
- }
- }
- }
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- XGINew_SetReg3( pVBInfo->P3c0 , i ) ; /* set index */
- XGINew_SetReg3( pVBInfo->P3c0 , ARdata ) ; /* set data */
- }
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x14 ) ; /* set index */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data */
- XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
-}
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ unsigned char ARdata;
+ unsigned short i, modeflag;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ for (i = 0; i <= 0x13; i++) {
+ ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
+ if (modeflag & Charx8Dot) { /* ifndef Dot9 */
+ if (i == 0x13) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ ARdata = 0;
+ } else {
+ if (pVBInfo->VBInfo & (SetCRT2ToTV
+ | SetCRT2ToLCD)) {
+ if (pVBInfo->VBInfo
+ & SetInSlaveMode)
+ ARdata = 0;
+ }
+ }
+ }
+ }
+
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */
+ XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGRCRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */
+ XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x20);
+}
+
+void XGI_SetGRCRegs(unsigned short StandTableIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned char GRdata ;
- unsigned short i ;
+ unsigned char GRdata;
+ unsigned short i;
- for( i = 0 ; i <= 0x08 ; i++ )
- {
- GRdata = pVBInfo->StandTable[ StandTableIndex ].GRC[ i ] ; /* Get GR from file */
- XGINew_SetReg1( pVBInfo->P3ce , i , GRdata ) ; /* Set GR(3ce) */
- }
+ for (i = 0; i <= 0x08; i++) {
+ GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */
+ XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
+ }
- if ( pVBInfo->ModeType > ModeVGA )
- {
- GRdata = (unsigned char)XGINew_GetReg1(pVBInfo->P3ce, 0x05);
- GRdata &= 0xBF ; /* 256 color disable */
- XGINew_SetReg1( pVBInfo->P3ce , 0x05 , GRdata ) ;
- }
+ if (pVBInfo->ModeType > ModeVGA) {
+ GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05);
+ GRdata &= 0xBF; /* 256 color disable */
+ XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata);
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ClearExt1Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
{
- unsigned short i ;
+ unsigned short i;
- for( i = 0x0A ; i <= 0x0E ; i++ )
- XGINew_SetReg1( pVBInfo->P3c4 , i , 0x00 ) ; /* Clear SR0A-SR0E */
+ for (i = 0x0A; i <= 0x0E; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetDefaultVCLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 0 ].SR2B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 0 ].SR2C ) ;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 1 ].SR2B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 1 ].SR2C ) ;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x31 , ~0x30 ) ;
- return( 0 ) ;
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30);
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetRatePtrCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- short LCDRefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 } ,
- LCDARefreshIndex[] = { 0x00 , 0x00 , 0x03 , 0x01 , 0x01 , 0x01 , 0x01 } ;
-
- unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
-
- if ( pVBInfo->IF_DEF_CH7005 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( modeflag & HalfDCLK )
- return( 0 ) ;
- }
- }
-
- if ( ModeNo < 0x14 )
- return( 0xFFFF ) ;
-
- index = XGINew_GetReg1( pVBInfo->P3d4 , 0x33 ) ;
- index = index >> pVBInfo->SelectCRT2Rate ;
- index &= 0x0F ;
-
- if ( pVBInfo->LCDInfo & LCDNonExpanding )
- index = 0 ;
-
- if ( index > 0 )
- index-- ;
-
- if ( pVBInfo->SetFlag & ProgrammingCRT2 )
- {
- if ( pVBInfo->IF_DEF_CH7005 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- index = 0 ;
- }
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- if( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- temp = LCDARefreshIndex[ pVBInfo->LCDResInfo & 0x0F ] ; /* 301b */
- else
- temp = LCDRefreshIndex[ pVBInfo->LCDResInfo & 0x0F ] ;
-
- if ( index > temp )
- {
- index = temp ;
- }
- }
- else
- {
- index = 0 ;
- }
- }
- }
-
- RefreshRateTableIndex = pVBInfo->EModeIDTable[ ModeIdIndex ].REFindex ;
- ModeNo = pVBInfo->RefIndex[ RefreshRateTableIndex ].ModeID ;
- if ( pXGIHWDE->jChipType >= XG20 ) /* for XG20, XG21, XG27 */
- {
- /*
- if ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag & XG2xNotSupport )
- {
- index++;
- }
- */
- if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 800 ) &&
- ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 600 ) )
- {
- index++;
- }
-/* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
- if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1024 ) &&
- ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 768 ) )
- {
- index++;
- }
- if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1280 ) &&
- ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1024 ) )
- {
- index++;
- }
- }
-
- i = 0 ;
- do
- {
- if ( pVBInfo->RefIndex[ RefreshRateTableIndex + i ].ModeID != ModeNo )
- break ;
- temp = pVBInfo->RefIndex[ RefreshRateTableIndex + i ].Ext_InfoFlag ;
- temp &= ModeInfoFlag ;
- if ( temp < pVBInfo->ModeType )
- break ;
- i++ ;
- index-- ;
-
- } while( index != 0xFFFF ) ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- temp = pVBInfo->RefIndex[ RefreshRateTableIndex + i - 1 ].Ext_InfoFlag ;
- if ( temp & InterlaceMode )
- {
- i++ ;
- }
- }
- }
- i-- ;
- if ( ( pVBInfo->SetFlag & ProgrammingCRT2 ) )
- {
- temp = XGI_AjustCRT2Rate( ModeNo , ModeIdIndex , RefreshRateTableIndex , &i, pVBInfo) ;
- }
- return( RefreshRateTableIndex + i ) ; /*return(0x01|(temp1<<1)); */
-}
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 },
+ LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01,
+ 0x01, 0x01 };
+ unsigned short RefreshRateTableIndex, i, modeflag, index, temp;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_AjustCRT2Rate */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- unsigned short *i, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
-
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- tempbx = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID ;
- tempax = 0 ;
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- {
- tempax |= SupportRAMDAC2 ;
-
- if ( pVBInfo->VBType & VB_XGI301C )
- tempax |= SupportCRT2in301C ;
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) /* 301b */
- {
- tempax |= SupportLCD ;
-
- if ( pVBInfo->LCDResInfo != Panel1280x1024 )
- {
- if ( pVBInfo->LCDResInfo != Panel1280x960 )
- {
- if ( pVBInfo->LCDInfo & LCDNonExpanding )
- {
- if ( resinfo >= 9 )
- {
- tempax = 0 ;
- return( 0 ) ;
- }
- }
- }
- }
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) /* for HiTV */
- {
- if ( ( pVBInfo->VBType & VB_XGI301LV ) && ( pVBInfo->VBExtInfo == VB_YPbPr1080i ) )
- {
- tempax |= SupportYPbPr ;
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( resinfo == 4 )
- return( 0 ) ;
-
- if ( resinfo == 3 )
- return( 0 ) ;
-
- if ( resinfo > 7 )
- return( 0 ) ;
- }
- }
- else
- {
- tempax |= SupportHiVisionTV ;
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( resinfo == 4 )
- return( 0 ) ;
-
- if ( resinfo == 3 )
- {
- if ( pVBInfo->SetFlag & TVSimuMode )
- return( 0 ) ;
- }
-
- if ( resinfo > 7 )
- return( 0 ) ;
- }
- }
- }
- else
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV ) )
- {
- tempax |= SupportTV ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempax |= SupportTV1024 ;
- }
-
- if ( !( pVBInfo->VBInfo & SetPALTV ) )
- {
- if ( modeflag & NoSupportSimuTV )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( !( pVBInfo->VBInfo & SetNotSimuMode ) )
- {
- return( 0 ) ;
- }
- }
- }
- }
- }
- }
- }
- else /* for LVDS */
- {
- if ( pVBInfo->IF_DEF_CH7005 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- tempax |= SupportCHTV ;
- }
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- {
- tempax |= SupportLCD ;
-
- if ( resinfo > 0x08 )
- return( 0 ) ; /* 1024x768 */
-
- if ( pVBInfo->LCDResInfo < Panel1024x768 )
- {
- if ( resinfo > 0x07 )
- return( 0 ) ; /* 800x600 */
-
- if ( resinfo == 0x04 )
- return( 0 ) ; /* 512x384 */
- }
- }
- }
-
- for( ; pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID == tempbx ; ( *i )-- )
- {
- infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].Ext_InfoFlag ;
- if ( infoflag & tempax )
- {
- return( 1 ) ;
- }
- if ( ( *i ) == 0 )
- break ;
- }
-
- for( ( *i ) = 0 ; ; ( *i )++ )
- {
- infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].Ext_InfoFlag ;
- if ( pVBInfo->RefIndex[ RefreshRateTableIndex + ( *i ) ].ModeID != tempbx )
- {
- return( 0 ) ;
- }
-
- if ( infoflag & tempax )
- {
- return( 1 ) ;
- }
- }
- return( 1 ) ;
-}
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ if (pVBInfo->IF_DEF_CH7005 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (modeflag & HalfDCLK)
+ return 0;
+ }
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetSync */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
+ if (ModeNo < 0x14)
+ return 0xFFFF;
+
+ index = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
+ index = index >> pVBInfo->SelectCRT2Rate;
+ index &= 0x0F;
+
+ if (pVBInfo->LCDInfo & LCDNonExpanding)
+ index = 0;
+
+ if (index > 0)
+ index--;
+
+ if (pVBInfo->SetFlag & ProgrammingCRT2) {
+ if (pVBInfo->IF_DEF_CH7005 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ index = 0;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C))
+ temp
+ = LCDARefreshIndex[pVBInfo->LCDResInfo
+ & 0x0F]; /* 301b */
+ else
+ temp
+ = LCDRefreshIndex[pVBInfo->LCDResInfo
+ & 0x0F];
+
+ if (index > temp)
+ index = temp;
+ } else {
+ index = 0;
+ }
+ }
+ }
+
+ RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
+ if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
+ /*
+ if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) {
+ index++;
+ }
+ */
+ if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800)
+ && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+ == 600)) {
+ index++;
+ }
+ /* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */
+ if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024)
+ && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+ == 768)) {
+ index++;
+ }
+ if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280)
+ && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
+ == 1024)) {
+ index++;
+ }
+ }
+
+ i = 0;
+ do {
+ if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID
+ != ModeNo)
+ break;
+ temp
+ = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+ temp &= ModeInfoFlag;
+ if (temp < pVBInfo->ModeType)
+ break;
+ i++;
+ index--;
+
+ } while (index != 0xFFFF);
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ temp
+ = pVBInfo->RefIndex[RefreshRateTableIndex
+ + i - 1].Ext_InfoFlag;
+ if (temp & InterlaceMode)
+ i++;
+ }
+ }
+ i--;
+ if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
+ temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, &i, pVBInfo);
+ }
+ return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */
+}
+
+unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex, unsigned short *i,
+ struct vb_device_info *pVBInfo)
{
- unsigned short sync ,
- temp ;
+ unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
- sync = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag >> 8 ; /* di+0x00 */
- sync &= 0xC0 ;
- temp = 0x2F ;
- temp |= sync ;
- XGINew_SetReg3( pVBInfo->P3c2 , temp ) ; /* Set Misc(3c2) */
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ tempax = 0;
+
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempax |= SupportRAMDAC2;
+
+ if (pVBInfo->VBType & VB_XGI301C)
+ tempax |= SupportCRT2in301C;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
+ tempax |= SupportLCD;
+
+ if (pVBInfo->LCDResInfo != Panel1280x1024) {
+ if (pVBInfo->LCDResInfo != Panel1280x960) {
+ if (pVBInfo->LCDInfo & LCDNonExpanding) {
+ if (resinfo >= 9) {
+ tempax = 0;
+ return 0;
+ }
+ }
+ }
+ }
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+ tempax |= SupportYPbPr;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (resinfo == 4)
+ return 0;
+
+ if (resinfo == 3)
+ return 0;
+
+ if (resinfo > 7)
+ return 0;
+ }
+ } else {
+ tempax |= SupportHiVisionTV;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (resinfo == 4)
+ return 0;
+
+ if (resinfo == 3) {
+ if (pVBInfo->SetFlag
+ & TVSimuMode)
+ return 0;
+ }
+
+ if (resinfo > 7)
+ return 0;
+ }
+ }
+ } else {
+ if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+ | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
+ tempax |= SupportTV;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ tempax |= SupportTV1024;
+ }
+
+ if (!(pVBInfo->VBInfo & SetPALTV)) {
+ if (modeflag & NoSupportSimuTV) {
+ if (pVBInfo->VBInfo
+ & SetInSlaveMode) {
+ if (!(pVBInfo->VBInfo
+ & SetNotSimuMode)) {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else { /* for LVDS */
+ if (pVBInfo->IF_DEF_CH7005 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ tempax |= SupportCHTV;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ tempax |= SupportLCD;
+
+ if (resinfo > 0x08)
+ return 0; /* 1024x768 */
+
+ if (pVBInfo->LCDResInfo < Panel1024x768) {
+ if (resinfo > 0x07)
+ return 0; /* 800x600 */
+
+ if (resinfo == 0x04)
+ return 0; /* 512x384 */
+ }
+ }
+ }
+
+ for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) {
+ infoflag
+ = pVBInfo->RefIndex[RefreshRateTableIndex
+ + (*i)].Ext_InfoFlag;
+ if (infoflag & tempax)
+ return 1;
+
+ if ((*i) == 0)
+ break;
+ }
+
+ for ((*i) = 0;; (*i)++) {
+ infoflag
+ = pVBInfo->RefIndex[RefreshRateTableIndex
+ + (*i)].Ext_InfoFlag;
+ if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
+ != tempbx) {
+ return 0;
+ }
+
+ if (infoflag & tempax)
+ return 1;
+ }
+ return 1;
}
+void XGI_SetSync(unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short sync, temp;
+
+ sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */
+ sync &= 0xC0;
+ temp = 0x2F;
+ temp |= sync;
+ XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1CRTC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo,
- struct xgi_hw_device_info *HwDeviceExtension)
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo,
+ struct xgi_hw_device_info *HwDeviceExtension)
{
- unsigned char index, data;
- unsigned short i;
+ unsigned char index, data;
+ unsigned short i;
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ; /* Get index */
- index = index&IndexMask ;
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+ index = index & IndexMask;
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
- data &= 0x7F ;
- XGINew_SetReg1(pVBInfo->P3d4,0x11,data); /* Unlock CRTC */
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
- for( i = 0 ; i < 8 ; i++ )
- pVBInfo->TimingH[ 0 ].data[ i ] = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ i ] ;
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH[0].data[i]
+ = pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
- for( i = 0 ; i < 7 ; i++ )
- pVBInfo->TimingV[ 0 ].data[ i ] = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ i + 8 ] ;
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV[0].data[i]
+ = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
- XGI_SetCRT1Timing_H( pVBInfo, HwDeviceExtension ) ;
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+ if (pVBInfo->ModeType > 0x03)
+ XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F);
+}
- XGI_SetCRT1Timing_V( ModeIdIndex , ModeNo, pVBInfo ) ;
+void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
+ struct xgi_hw_device_info *HwDeviceExtension)
+{
+ unsigned char data, data1, pushax;
+ unsigned short i, j;
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
+ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
- if( pVBInfo->ModeType > 0x03 )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x14 , 0x4F ) ;
-}
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
+ data &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, data);
+ data = pVBInfo->TimingH[0].data[0];
+ XGINew_SetReg1(pVBInfo->P3d4, 0, data);
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Timing_H */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension)
-{
- unsigned char data, data1, pushax;
- unsigned short i, j;
-
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
- /* XGINew_SetRegANDOR( pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
-
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
- data &= 0x7F ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ;
-
- data = pVBInfo->TimingH[ 0 ].data[ 0 ] ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0 , data ) ;
-
- for( i = 0x01 ; i <= 0x04 ; i++ )
- {
- data = pVBInfo->TimingH[ 0 ].data[ i ] ;
- XGINew_SetReg1( pVBInfo->P3d4, (unsigned short)(i + 1), data);
- }
-
- for( i = 0x05 ; i <= 0x06 ; i++ )
- {
- data = pVBInfo->TimingH[ 0 ].data[ i ];
- XGINew_SetReg1(pVBInfo->P3c4, (unsigned short)(i + 6), data);
- }
-
- j = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
- j &= 0x1F ;
- data = pVBInfo->TimingH[ 0 ].data[ 7 ] ;
- data &= 0xE0 ;
- data |= j ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0e , data ) ;
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- {
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x04);
- data = data - 1 ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x04 , data ) ;
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x05);
- data1 = data ;
- data1 &= 0xE0 ;
- data &= 0x1F ;
- if ( data == 0 )
- {
- pushax = data ;
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0c);
- data &= 0xFB ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0c , data ) ;
- data = pushax ;
- }
- data = data - 1 ;
- data |= data1 ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x05 , data ) ;
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
- data = data >> 5 ;
- data = data + 3 ;
- if ( data > 7 )
- data = data - 7 ;
- data = data << 5 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0e , ~0xE0 , data ) ;
- }
-}
+ for (i = 0x01; i <= 0x04; i++) {
+ data = pVBInfo->TimingH[0].data[i];
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data);
+ }
+ for (i = 0x05; i <= 0x06; i++) {
+ data = pVBInfo->TimingH[0].data[i];
+ XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data);
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Timing_V */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
- unsigned short ModeNo,
- struct vb_device_info *pVBInfo)
-{
- unsigned char data;
- unsigned short i, j;
-
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0 ) ; */
- /* XGINew_SetReg1( pVBInfo->P3d4 , 0x56 , 0 ) ; */
- /* XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
-
- for( i = 0x00 ; i <= 0x01 ; i++ )
- {
- data = pVBInfo->TimingV[ 0 ].data[ i ] ;
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 6), data);
- }
-
- for( i = 0x02 ; i <= 0x03 ; i++ )
- {
- data = pVBInfo->TimingV[ 0 ].data[ i ] ;
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 0x0e), data);
- }
-
- for( i = 0x04 ; i <= 0x05 ; i++ )
- {
- data = pVBInfo->TimingV[ 0 ].data[ i ] ;
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 0x11), data);
- }
-
- j = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
- j &= 0xC0 ;
- data = pVBInfo->TimingV[ 0 ].data[ 6 ] ;
- data &= 0x3F ;
- data |= j ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0a , data ) ;
-
- data = pVBInfo->TimingV[ 0 ].data[ 6 ] ;
- data &= 0x80 ;
- data = data >> 2 ;
-
- if ( ModeNo <= 0x13 )
- i = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- else
- i = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
-
- i &= DoubleScanMode ;
- if ( i )
- data |= 0x80 ;
-
- j = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x09);
- j &= 0x5F ;
- data |= j ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x09 , data ) ;
+ j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
+ j &= 0x1F;
+ data = pVBInfo->TimingH[0].data[7];
+ data &= 0xE0;
+ data |= j;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data);
+
+ if (HwDeviceExtension->jChipType >= XG20) {
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04);
+ data = data - 1;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x04, data);
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05);
+ data1 = data;
+ data1 &= 0xE0;
+ data &= 0x1F;
+ if (data == 0) {
+ pushax = data;
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4,
+ 0x0c);
+ data &= 0xFB;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data);
+ data = pushax;
+ }
+ data = data - 1;
+ data |= data1;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x05, data);
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e);
+ data = data >> 5;
+ data = data + 3;
+ if (data > 7)
+ data = data - 7;
+ data = data << 5;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data);
+ }
}
+void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char data;
+ unsigned short i, j;
+
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */
+ /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */
+ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
+
+ for (i = 0x00; i <= 0x01; i++) {
+ data = pVBInfo->TimingV[0].data[i];
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data);
+ }
+
+ for (i = 0x02; i <= 0x03; i++) {
+ data = pVBInfo->TimingV[0].data[i];
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
+ }
+
+ for (i = 0x04; i <= 0x05; i++) {
+ data = pVBInfo->TimingV[0].data[i];
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
+ }
+
+ j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a);
+ j &= 0xC0;
+ data = pVBInfo->TimingV[0].data[6];
+ data &= 0x3F;
+ data |= j;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data);
+
+ data = pVBInfo->TimingV[0].data[6];
+ data &= 0x80;
+ data = data >> 2;
+
+ if (ModeNo <= 0x13)
+ i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ i &= DoubleScanMode;
+ if (i)
+ data |= 0x80;
+
+ j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09);
+ j &= 0x5F;
+ data |= j;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x09, data);
+}
/* --------------------------------------------------------------------- */
/* Function : XGI_SetXG21CRTC */
@@ -1517,265 +1289,256 @@ void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
/* Description : Set LCD timing */
/* --------------------------------------------------------------------- */
void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
- unsigned short Temp1, Temp2, Temp3;
-
- if ( ModeNo <= 0x13 )
- {
- StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
- Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
- Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
- Tempcx = Tempax ;
- Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
- Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
- if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
- Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
- Tempdx <<= 2 ; /* Tempdx << 2 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
-
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR16 VRS */
- Tempbx = Tempax ; /* Tempbx=Tempax */
- Tempax &= 0x01 ; /* Tempax: VRS[0] */
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS */
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax: CR7 VRS */
- Tempdx = Tempbx >> 1 ; /* Tempdx: VRS[7:1] */
- Tempcx = Tempax & 0x04 ; /* Tempcx: CR7[2] */
- Tempcx <<= 5 ; /* Tempcx[7]: VRS[8] */
- Tempdx |= Tempcx ; /* Tempdx: VRS[8:1] */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempdx ) ; /* SR34[7:0]: VRS[8:1] */
-
- Temp1 = Tempcx << 1 ; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
- Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
- Tempax &= 0x80 ; /* Tempax[7]: CR7[7] */
- Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
- Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
-
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR16 VRE */
- Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
- Temp2 = Temp1 & 0x3F0 ; /* Temp2[9:4]: VRS[9:4] */
- Temp2 |= Tempax ; /* Temp2[9:0]: VRE[9:0] */
- Temp3 = Temp1 & 0x0F ; /* Temp3[3:0]: VRS[3:0] */
- if ( Tempax < Temp3 ) /* VRE[3:0]<VRS[3:0] */
- Temp2 |= 0x10 ; /* Temp2: VRE + 0x10 */
- Temp2 &= 0xFF ; /* Temp2[7:0]: VRE[7:0] */
- Tempax = (unsigned char)Temp2; /* Tempax[7:0]: VRE[7:0] */
- Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
- Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
- Temp1 >>= 9 ; /* [10:9]->[1:0] */
- Tempbx = (unsigned char)Temp1; /* Tempbx[1:0]: VRS[10:9] */
- Tempax |= Tempbx ; /* VRE[5:0]VRS[10:9] */
- Tempax &= 0x7F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
- }
- else
- {
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
- Tempcx = Tempax ; /* Tempcx: HRS */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
-
- Tempdx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SRB */
- Tempdx &= 0xC0 ; /* Tempdx[7:6]: SRB[7:6] */
- Temp1 = Tempdx ; /* Temp1[7:6]: HRS[9:8] */
- Temp1 <<= 2 ; /* Temp1[9:8]: HRS[9:8] */
- Temp1 |= Tempax ; /* Temp1[9:0]: HRS[9:0] */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
- Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
-
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
- Tempbx &= 0x04 ; /* Tempbx[2]: HRE[5] */
- Tempbx <<= 3 ; /* Tempbx[5]: HRE[5] */
- Tempax |= Tempbx ; /* Tempax[5:0]: HRE[5:0] */
-
- Temp2 = Temp1 & 0x3C0 ; /* Temp2[9:6]: HRS[9:6] */
- Temp2 |= Tempax ; /* Temp2[9:0]: HRE[9:0] */
-
- Tempcx &= 0x3F ; /* Tempcx[5:0]: HRS[5:0] */
- if( Tempax < Tempcx ) /* HRE < HRS */
- Temp2 |= 0x40 ; /* Temp2 + 0x40 */
-
- Temp2 &= 0xFF ;
- Tempax = (unsigned char)Temp2; /* Tempax: HRE[7:0] */
- Tempax <<= 2 ; /* Tempax[7:2]: HRE[5:0] */
- Tempdx >>= 6 ; /* Tempdx[7:6]->[1:0] HRS[9:8] */
- Tempax |= Tempdx ; /* HRE[5:0]HRS[9:8] */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F D[7:2]->HRE, D[1:0]->HRS */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
- Tempbx = Tempax ; /* Tempbx: VRS */
- Tempax &= 0x01 ; /* Tempax[0]: VRS[0] */
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS[0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[2][7] VRE */
- Tempcx = Tempbx >> 1 ; /* Tempcx[6:0]: VRS[7:1] */
- Tempdx = Tempax & 0x04 ; /* Tempdx[2]: CR7[2] */
- Tempdx <<= 5 ; /* Tempdx[7]: VRS[8] */
- Tempcx |= Tempdx ; /* Tempcx[7:0]: VRS[8:1] */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempcx ) ; /* SR34[8:1]->VRS */
-
- Temp1 = Tempdx ; /* Temp1[7]: Tempdx[7] */
- Temp1 <<= 1 ; /* Temp1[8]: VRS[8] */
- Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
- Tempax &= 0x80 ;
- Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
- Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SRA */
- Tempax &= 0x08 ; /* Tempax[3]: VRS[3] */
- Temp2 = Tempax ;
- Temp2 <<= 7 ; /* Temp2[10]: VRS[10] */
- Temp1 |= Temp2 ; /* Temp1[10:0]: VRS[10:0] */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
- Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SRA */
- Tempbx &= 0x20 ; /* Tempbx[5]: VRE[5] */
- Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
- Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
- Temp2 = Temp1 & 0x7E0 ; /* Temp2[10:5]: VRS[10:5] */
- Temp2 |= Tempax ; /* Temp2[10:5]: VRE[10:5] */
-
- Temp3 = Temp1 & 0x1F ; /* Temp3[4:0]: VRS[4:0] */
- if ( Tempax < Temp3 ) /* VRE < VRS */
- Temp2 |= 0x20 ; /* VRE + 0x20 */
-
- Temp2 &= 0xFF ;
- Tempax = (unsigned char)Temp2; /* Tempax: VRE[7:0] */
- Tempax <<= 2 ; /* Tempax[7:0]; VRE[5:0]00 */
- Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
- Temp1 >>= 9 ; /* Temp1[1:0]: VRS[10:9] */
- Tempbx = (unsigned char)Temp1;
- Tempax |= Tempbx ; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
- Tempax &= 0x7F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
- }
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
+ unsigned short Temp1, Temp2, Temp3;
+
+ if (ModeNo <= 0x13) {
+ StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
+ Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+ Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
+ Tempcx = Tempax;
+ Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
+ Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+ if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
+ Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
+ Tempdx <<= 2; /* Tempdx << 2 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */
+ Tempbx = Tempax; /* Tempbx=Tempax */
+ Tempax &= 0x01; /* Tempax: VRS[0] */
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */
+ Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
+ Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
+ Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
+ Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */
+
+ Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
+ Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
+ Tempax &= 0x80; /* Tempax[7]: CR7[7] */
+ Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
+ Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
+
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */
+ Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+ Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
+ Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
+ Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */
+ if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */
+ Temp2 |= 0x10; /* Temp2: VRE + 0x10 */
+ Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */
+ Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */
+ Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
+ Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
+ Temp1 >>= 9; /* [10:9]->[1:0] */
+ Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
+ Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
+ Tempax &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
+ } else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+ Tempcx = Tempax; /* Tempcx: HRS */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+
+ Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
+ Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
+ Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
+ Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
+ Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+ Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
+ Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
+ Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
+
+ Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
+ Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
+
+ Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
+ if (Tempax < Tempcx) /* HRE < HRS */
+ Temp2 |= 0x40; /* Temp2 + 0x40 */
+
+ Temp2 &= 0xFF;
+ Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
+ Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
+ Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
+ Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
+ Tempbx = Tempax; /* Tempbx: VRS */
+ Tempax &= 0x01; /* Tempax[0]: VRS[0] */
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */
+ Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
+ Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
+ Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
+ Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
+
+ Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
+ Temp1 <<= 1; /* Temp1[8]: VRS[8] */
+ Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
+ Tempax &= 0x80;
+ Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
+ Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */
+ Tempax &= 0x08; /* Tempax[3]: VRS[3] */
+ Temp2 = Tempax;
+ Temp2 <<= 7; /* Temp2[10]: VRS[10] */
+ Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+ Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */
+ Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
+ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+ Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
+ Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
+
+ Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
+ if (Tempax < Temp3) /* VRE < VRS */
+ Temp2 |= 0x20; /* VRE + 0x20 */
+
+ Temp2 &= 0xFF;
+ Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
+ Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
+ Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
+ Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
+ Tempbx = (unsigned char) Temp1;
+ Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
+ Tempax &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
+ }
}
void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
- if ( ModeNo <= 0x13 )
- {
- StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
- Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
- Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
- Tempcx = Tempax ;
- Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
- Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
- if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
- Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
- Tempdx <<= 2 ; /* Tempdx << 2 */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
-
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR10 VRS */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS */
- Tempcx = Tempax ; /* Tempcx=Tempax=VRS[7:0] */
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
- Tempbx = Tempax ; /* Tempbx=CR07 */
- Tempax &= 0x04 ; /* Tempax[2]: CR07[2] VRS[8] */
- Tempax >>= 2;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x01, Tempax ) ; /* SR35 D[0]->VRS D[8] */
- Tempcx |= (Tempax << 8) ; /* Tempcx[8] |= VRS[8] */
- Tempcx |= (Tempbx & 0x80)<<2; /* Tempcx[9] |= VRS[9] */
-
-
- Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR11 VRE */
- Tempax &= 0x0F ; /* Tempax: VRE[3:0] */
- Tempbx = Tempcx ; /* Tempbx=Tempcx=VRS[9:0] */
- Tempbx &= 0x3F0 ; /* Tempbx[9:4]: VRS[9:4] */
- Tempbx |= Tempax ; /* Tempbx[9:0]: VRE[9:0] */
- if ( Tempax <= (Tempcx & 0x0F) ) /* VRE[3:0]<=VRS[3:0] */
- Tempbx |= 0x10 ; /* Tempbx: VRE + 0x10 */
- Tempax = (unsigned char)Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
- Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
- Tempcx = (Tempcx&0x600)>>8; /* Tempcx VRS[10:9] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC, Tempax ) ; /* SR3F D[7:2]->VRE D[5:0] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x06, Tempcx ) ; /* SR35 D[2:1]->VRS[10:9] */
- }
- else
- {
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
- Tempbx = Tempax ; /* Tempbx: HRS[7:0] */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
- Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
- Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
- Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
- Tempcx = Tempax ; /* Tempcx: HRE[4:0] */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
- Tempax &= 0x04 ; /* Tempax[2]: HRE[5] */
- Tempax <<= 3 ; /* Tempax[5]: HRE[5] */
- Tempcx |= Tempax ; /* Tempcx[5:0]: HRE[5:0] */
-
- Tempbx = Tempbx & 0x3C0 ; /* Tempbx[9:6]: HRS[9:6] */
- Tempbx |= Tempcx ; /* Tempbx: HRS[9:6]HRE[5:0] */
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
- Tempax &= 0x3F ; /* Tempax: HRS[5:0] */
- if( Tempcx <= Tempax ) /* HRE[5:0] < HRS[5:0] */
- Tempbx += 0x40 ; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
- Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
- Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
- Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS[7:0] */
-
- Tempcx = Tempax ; /* Tempcx <= VRS[7:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[7][2] VRS[9][8] */
- Tempbx = Tempax ; /* Tempbx <= CR07[7:0] */
- Tempax = Tempax & 0x04 ; /* Tempax[2]: CR7[2]: VRS[8] */
- Tempax >>= 2 ; /* Tempax[0]: VRS[8] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x01 , Tempax ) ; /* SR35[0]: VRS[8] */
- Tempcx |= (Tempax<<8) ; /* Tempcx <= VRS[8:0] */
- Tempcx |= ((Tempbx&0x80)<<2) ; /* Tempcx <= VRS[9:0] */
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SR0A */
- Tempax &= 0x08; /* SR0A[3] VRS[10] */
- Tempcx |= (Tempax<<7) ; /* Tempcx <= VRS[10:0] */
-
-
- Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
- Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
- Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SR0A */
- Tempbx &= 0x20 ; /* Tempbx[5]: SR0A[5]: VRE[4] */
- Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
- Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
- Tempbx = Tempcx ; /* Tempbx: VRS[10:0] */
- Tempbx &= 0x7E0 ; /* Tempbx[10:5]: VRS[10:5] */
- Tempbx |= Tempax ; /* Tempbx: VRS[10:5]VRE[4:0] */
-
- if ( Tempbx <= Tempcx ) /* VRE <= VRS */
- Tempbx |= 0x20 ; /* VRE + 0x20 */
-
- Tempax = (Tempbx<<2) & 0xFF ; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , Tempax ) ; /* SR3F[7:2]:VRE[5:0] */
- Tempax = Tempcx >> 8;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x07 , Tempax ) ; /* SR35[2:0]:VRS[10:8] */
- }
+ if (ModeNo <= 0x13) {
+ StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
+ Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+ Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
+ Tempcx = Tempax;
+ Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
+ Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+ if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
+ Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
+ Tempdx <<= 2; /* Tempdx << 2 */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
+ Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
+ Tempbx = Tempax; /* Tempbx=CR07 */
+ Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
+ Tempax >>= 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */
+ Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
+ Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
+
+ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */
+ Tempax &= 0x0F; /* Tempax: VRE[3:0] */
+ Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
+ Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
+ Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
+ if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
+ Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
+ Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
+ Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
+ Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */
+ } else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+ Tempbx = Tempax; /* Tempbx: HRS[7:0] */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
+ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
+ Tempcx = Tempax; /* Tempcx: HRE[4:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
+ Tempax &= 0x04; /* Tempax[2]: HRE[5] */
+ Tempax <<= 3; /* Tempax[5]: HRE[5] */
+ Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
+
+ Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
+ Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+ Tempax &= 0x3F; /* Tempax: HRS[5:0] */
+ if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
+ Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
+ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00);
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */
+
+ Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */
+ Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
+ Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
+ Tempax >>= 2; /* Tempax[0]: VRS[8] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */
+ Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
+ Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */
+ Tempax &= 0x08; /* SR0A[3] VRS[10] */
+ Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+ Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */
+ Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
+ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
+ Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
+ Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
+ Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
+
+ if (Tempbx <= Tempcx) /* VRE <= VRS */
+ Tempbx |= 0x20; /* VRE + 0x20 */
+
+ Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */
+ Tempax = Tempcx >> 8;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */
+ }
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetXG21LCD */
/* Input : */
@@ -1783,109 +1546,97 @@ void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
/* Description : All values set zero */
/* --------------------------------------------------------------------- */
void XGI_SetXG21LCD(struct vb_device_info *pVBInfo,
- unsigned short RefreshRateTableIndex,
- unsigned short ModeNo)
+ unsigned short RefreshRateTableIndex, unsigned short ModeNo)
{
unsigned short Data, Temp, b3CC;
unsigned short XGI_P3cc;
- XGI_P3cc = pVBInfo->P3cc ;
-
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
- if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
- {
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
- }
-
- Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
-
- if ( Temp & 0x01 )
- {
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x06 , 0x40 ) ; /* 18 bits FP */
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x09 , 0x40 ) ;
- }
-
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
-
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x30 , ~0x20 ) ;
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x35 , ~0x80 ) ;
-
- if ( ModeNo <= 0x13 )
- {
- b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
- if ( b3CC & 0x40 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
- if ( b3CC & 0x80 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
- }
- else
- {
- Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
- if ( Data & 0x4000 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
- if ( Data & 0x8000 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
- }
+ XGI_P3cc = pVBInfo->P3cc;
+
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
+ if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
+ }
+
+ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+
+ if (Temp & 0x01) {
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40);
+ }
+
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20);
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80);
+
+ if (ModeNo <= 0x13) {
+ b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
+ if (b3CC & 0x40)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+ if (b3CC & 0x80)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+ } else {
+ Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ if (Data & 0x4000)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+ if (Data & 0x8000)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+ }
}
void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
- unsigned short RefreshRateTableIndex,
- unsigned short ModeNo)
-{
- unsigned short Data , Temp , b3CC ;
- unsigned short XGI_P3cc ;
-
- XGI_P3cc = pVBInfo->P3cc ;
-
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
-
- Temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
- if ( ( Temp & 0x03 ) == 0 ) /* dual 12 */
- {
- XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , 0x13 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , 0x13 ) ;
- }
-
- if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
- {
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
- }
-
- XGI_SetXG27FPBits(pVBInfo);
-
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
-
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x30 , ~0x20 ) ; /* Hsync polarity */
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x35 , ~0x80 ) ; /* Vsync polarity */
-
- if ( ModeNo <= 0x13 )
- {
- b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
- if ( b3CC & 0x40 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
- if ( b3CC & 0x80 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
- }
- else
- {
- Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
- if ( Data & 0x4000 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
- if ( Data & 0x8000 )
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
- }
+ unsigned short RefreshRateTableIndex, unsigned short ModeNo)
+{
+ unsigned short Data, Temp, b3CC;
+ unsigned short XGI_P3cc;
+
+ XGI_P3cc = pVBInfo->P3cc;
+
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00);
+
+ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+ if ((Temp & 0x03) == 0) { /* dual 12 */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13);
+ }
+
+ if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
+ }
+
+ XGI_SetXG27FPBits(pVBInfo);
+
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
+
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
+
+ if (ModeNo <= 0x13) {
+ b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc);
+ if (b3CC & 0x40)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+ if (b3CC & 0x80)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+ } else {
+ Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ if (Data & 0x4000)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+ if (Data & 0x8000)
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+ }
}
/* --------------------------------------------------------------------- */
@@ -1894,4772 +1645,4030 @@ void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
/* Output : CRT1 CRTC */
/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
/* --------------------------------------------------------------------- */
-void XGI_UpdateXG21CRTC(unsigned short ModeNo,
- struct vb_device_info *pVBInfo,
- unsigned short RefreshRateTableIndex)
-{
- int i , index = -1;
-
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x11 , 0x7F ) ; /* Unlock CR0~7 */
- if ( ModeNo <= 0x13 )
- {
- for( i = 0 ; i < 12 ; i++ )
- {
- if ( ModeNo == pVBInfo->UpdateCRT1[ i ].ModeID )
- index = i ;
- }
- }
- else
- {
- if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x60 ) )
- index = 12 ;
- else if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x72 ) )
- index = 13 ;
- else if ( ModeNo == 0x2F )
- index = 14 ;
- else if ( ModeNo == 0x50 )
- index = 15 ;
- else if ( ModeNo == 0x59 )
- index = 16 ;
- }
-
- if( index != -1 )
- {
- XGINew_SetReg1( pVBInfo->P3d4 , 0x02 , pVBInfo->UpdateCRT1[ index ].CR02 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x03 , pVBInfo->UpdateCRT1[ index ].CR03 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , pVBInfo->UpdateCRT1[ index ].CR15 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , pVBInfo->UpdateCRT1[ index ].CR16 ) ;
- }
-}
+void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo,
+ unsigned short RefreshRateTableIndex)
+{
+ int i, index = -1;
+
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
+ if (ModeNo <= 0x13) {
+ for (i = 0; i < 12; i++) {
+ if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID)
+ index = i;
+ }
+ } else {
+ if (ModeNo == 0x2E
+ && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
+ == RES640x480x60))
+ index = 12;
+ else if (ModeNo == 0x2E
+ && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
+ == RES640x480x72))
+ index = 13;
+ else if (ModeNo == 0x2F)
+ index = 14;
+ else if (ModeNo == 0x50)
+ index = 15;
+ else if (ModeNo == 0x59)
+ index = 16;
+ }
+ if (index != -1) {
+ XGINew_SetReg1(pVBInfo->P3d4, 0x02,
+ pVBInfo->UpdateCRT1[index].CR02);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x03,
+ pVBInfo->UpdateCRT1[index].CR03);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x15,
+ pVBInfo->UpdateCRT1[index].CR15);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x16,
+ pVBInfo->UpdateCRT1[index].CR16);
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1DE */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
- unsigned char data;
+ unsigned char data;
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- tempax = pVBInfo->StResInfo[ resindex ].HTotal ;
- tempbx = pVBInfo->StResInfo[ resindex ].VTotal ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- tempax = pVBInfo->ModeResInfo[ resindex ].HTotal ;
- tempbx = pVBInfo->ModeResInfo[ resindex ].VTotal ;
- }
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempax = pVBInfo->StResInfo[resindex].HTotal;
+ tempbx = pVBInfo->StResInfo[resindex].VTotal;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempax = pVBInfo->ModeResInfo[resindex].HTotal;
+ tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
+ }
- if ( modeflag & HalfDCLK )
- tempax = tempax >> 1 ;
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
- if ( ModeNo > 0x13 )
- {
- if ( modeflag & HalfDCLK )
- tempax = tempax << 1 ;
+ if (ModeNo > 0x13) {
+ if (modeflag & HalfDCLK)
+ tempax = tempax << 1;
- temp = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
+ temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- if ( temp & InterlaceMode )
- tempbx = tempbx >> 1 ;
+ if (temp & InterlaceMode)
+ tempbx = tempbx >> 1;
- if ( modeflag & DoubleScanMode )
- tempbx = tempbx << 1 ;
- }
+ if (modeflag & DoubleScanMode)
+ tempbx = tempbx << 1;
+ }
- tempcx = 8 ;
+ tempcx = 8;
- /* if ( !( modeflag & Charx8Dot ) ) */
- /* tempcx = 9 ; */
+ /* if (!(modeflag & Charx8Dot)) */
+ /* tempcx = 9; */
- tempax /= tempcx ;
- tempax -= 1 ;
- tempbx -= 1 ;
- tempcx = tempax ;
- temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11);
- data &= 0x7F ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , data ) ; /* Unlock CRTC */
- XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short)(tempcx & 0xff));
- XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, (unsigned short)((tempcx & 0x0ff00) >> 10));
- XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short)(tempbx & 0xff));
- tempax = 0 ;
- tempbx = tempbx >> 8 ;
+ tempax /= tempcx;
+ tempax -= 1;
+ tempbx -= 1;
+ tempcx = tempax;
+ temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c,
+ (unsigned short) ((tempcx & 0x0ff00) >> 10));
+ XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
+ tempax = 0;
+ tempbx = tempbx >> 8;
- if ( tempbx & 0x01 )
- tempax |= 0x02 ;
+ if (tempbx & 0x01)
+ tempax |= 0x02;
- if ( tempbx & 0x02 )
- tempax |= 0x40 ;
+ if (tempbx & 0x02)
+ tempax |= 0x40;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x42 , tempax ) ;
- data = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x07);
- data &= 0xFF ;
- tempax = 0 ;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax);
+ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07);
+ data &= 0xFF;
+ tempax = 0;
- if ( tempbx & 0x04 )
- tempax |= 0x02 ;
+ if (tempbx & 0x04)
+ tempax |= 0x02;
- XGINew_SetRegANDOR( pVBInfo->P3d4 ,0x0a , ~0x02 , tempax ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp ) ;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetResInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetResInfo(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
{
unsigned short resindex;
- if ( ModeNo <= 0x13 )
- {
- resindex = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
- }
- else
- {
- resindex = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
- }
- return( resindex ) ;
-}
+ if (ModeNo <= 0x13)
+ resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+ else
+ resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+ return resindex;
+}
+
+void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, ah, al, temp2, i, DisplayUnit;
+
+ /* GetOffset */
+ temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ temp = temp >> 8;
+ temp = pVBInfo->ScreenOffset[temp];
+
+ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+
+ if (temp2)
+ temp = temp << 1;
+
+ temp2 = pVBInfo->ModeType - ModeEGA;
+
+ switch (temp2) {
+ case 0:
+ temp2 = 1;
+ break;
+ case 1:
+ temp2 = 2;
+ break;
+ case 2:
+ temp2 = 4;
+ break;
+ case 3:
+ temp2 = 4;
+ break;
+ case 4:
+ temp2 = 6;
+ break;
+ case 5:
+ temp2 = 8;
+ break;
+ default:
+ break;
+ }
+ if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
+ temp = temp * temp2 + temp2 / 2;
+ else
+ temp *= temp2;
+
+ /* SetOffset */
+ DisplayUnit = temp;
+ temp2 = temp;
+ temp = temp >> 8; /* ah */
+ temp &= 0x0F;
+ i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E);
+ i &= 0xF0;
+ i |= temp;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i);
+
+ temp = (unsigned char) temp2;
+ temp &= 0xFF; /* al */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp);
+
+ /* SetDisplayUnit */
+ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+ if (temp2)
+ DisplayUnit >>= 1;
+
+ DisplayUnit = DisplayUnit << 5;
+ ah = (DisplayUnit & 0xff00) >> 8;
+ al = DisplayUnit & 0x00ff;
+ if (al == 0)
+ ah += 1;
+ else
+ ah += 2;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Offset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT1Offset(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short temp ,
- ah ,
- al ,
- temp2 ,
- i ,
- DisplayUnit ;
-
- /* GetOffset */
- temp = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeInfo ;
- temp = temp >> 8 ;
- temp = pVBInfo->ScreenOffset[ temp ] ;
-
- temp2 = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
- temp2 &= InterlaceMode ;
-
- if ( temp2 )
- temp = temp << 1;
-
- temp2 = pVBInfo->ModeType - ModeEGA ;
-
- switch( temp2 )
- {
- case 0:
- temp2 = 1 ;
- break ;
- case 1:
- temp2 = 2 ;
- break ;
- case 2:
- temp2 = 4 ;
- break ;
- case 3:
- temp2 = 4 ;
- break ;
- case 4:
- temp2 = 6 ;
- break;
- case 5:
- temp2 = 8 ;
- break ;
- default:
- break ;
- }
-
- if ( ( ModeNo >= 0x26 ) && ( ModeNo <= 0x28 ) )
- temp = temp * temp2 + temp2 / 2 ;
- else
- temp *= temp2 ;
-
- /* SetOffset */
- DisplayUnit = temp ;
- temp2 = temp ;
- temp = temp >> 8 ; /* ah */
- temp &= 0x0F ;
- i = XGINew_GetReg1( pVBInfo->P3c4 , 0x0E ) ;
- i &= 0xF0 ;
- i |= temp ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0E , i ) ;
-
- temp = (unsigned char)temp2;
- temp &= 0xFF ; /* al */
- XGINew_SetReg1( pVBInfo->P3d4 , 0x13 , temp ) ;
-
- /* SetDisplayUnit */
- temp2 = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
- temp2 &= InterlaceMode ;
- if ( temp2 )
- DisplayUnit >>= 1 ;
-
- DisplayUnit = DisplayUnit << 5 ;
- ah = ( DisplayUnit & 0xff00 ) >> 8 ;
- al = DisplayUnit & 0x00ff ;
- if ( al == 0 )
- ah += 1 ;
- else
- ah += 2 ;
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- if ( ( ModeNo == 0x4A ) | (ModeNo == 0x49 ) )
- ah -= 1 ;
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x10 , ah ) ;
-}
+ if (HwDeviceExtension->jChipType >= XG20)
+ if ((ModeNo == 0x4A) | (ModeNo == 0x49))
+ ah -= 1;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah);
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1VCLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
unsigned char index, data;
- unsigned short vclkindex ;
-
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ index ].SR2B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ index ].SR2C ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
- }
- else if ( ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) && ( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
- {
- vclkindex = XGI_GetVCLK2Ptr( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
- data = pVBInfo->VBVCLKData[ vclkindex ].Part4_A ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , data ) ;
- data = pVBInfo->VBVCLKData[ vclkindex ].Part4_B ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , data ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
- }
- else
- {
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x31 ) & 0xCF ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , data ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ index ].SR2B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ index ].SR2C ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2D , 0x01 ) ;
- }
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- {
- if ( pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag & HalfDCLK )
- {
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x2B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , data ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x2C ) ;
- index = data ;
- index &= 0xE0 ;
- data &= 0x1F ;
- data = data << 1 ;
- data += 1 ;
- data |= index ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , data ) ;
- }
- }
-}
+ unsigned short vclkindex;
+
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B,
+ pVBInfo->VCLKData[index].SR2B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C,
+ pVBInfo->VCLKData[index].SR2C);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
+ } else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo
+ & SetCRT2ToLCDA)) {
+ vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, HwDeviceExtension,
+ pVBInfo);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
+ data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data);
+ data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
+ } else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, data);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B,
+ pVBInfo->VCLKData[index].SR2B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C,
+ pVBInfo->VCLKData[index].SR2C);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01);
+ }
+ if (HwDeviceExtension->jChipType >= XG20) {
+ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) {
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x2B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x2C);
+ index = data;
+ index &= 0xE0;
+ data &= 0x1F;
+ data = data << 1;
+ data += 1;
+ data |= index;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data);
+ }
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1FIFO */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRT1FIFO(unsigned short ModeNo,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short data ;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3D ) ;
- data &= 0xfe ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3D , data ) ; /* diable auto-threshold */
-
- if ( ModeNo > 0x13 )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0x34 ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
- data &= 0xC0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data | 0x30) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x3D ) ;
- data |= 0x01 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3D , data ) ;
- }
- else
- {
- if (HwDeviceExtension->jChipType == XG27)
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0x0E ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
- data &= 0xC0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data | 0x20 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x08 , 0xAE ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x09 ) ;
- data &= 0xF0 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x09 , data ) ;
- }
- }
-
- if (HwDeviceExtension->jChipType == XG21)
- {
- XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
- }
-}
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data;
+
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D);
+ data &= 0xfe;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
+
+ if (ModeNo > 0x13) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x34);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
+ data &= 0xC0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x30);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D);
+ data |= 0x01;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data);
+ } else {
+ if (HwDeviceExtension->jChipType == XG27) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x0E);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
+ data &= 0xC0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x20);
+ } else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0xAE);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x09);
+ data &= 0xF0;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x09, data);
+ }
+ }
+ if (HwDeviceExtension->jChipType == XG21)
+ XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1ModeRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short data ,
- data2 ,
- data3 ,
- infoflag = 0 ,
- modeflag ,
- resindex ,
- xres ;
-
- if ( ModeNo > 0x13 )
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
- }
- else
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
-
- if ( XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) & 0x01 )
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1F , 0x3F , 0x00 ) ;
-
- if ( ModeNo > 0x13 )
- data = infoflag ;
- else
- data = 0 ;
-
- data2 = 0 ;
-
- if ( ModeNo > 0x13 )
- {
- if ( pVBInfo->ModeType > 0x02 )
- {
- data2 |= 0x02 ;
- data3 = pVBInfo->ModeType - ModeVGA ;
- data3 = data3 << 2 ;
- data2 |= data3 ;
- }
- }
-
- data &= InterlaceMode ;
-
- if ( data )
- data2 |= 0x20 ;
-
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0x3F , data2 ) ;
- /* XGINew_SetReg1(pVBInfo->P3c4,0x06,data2); */
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( ModeNo <= 0x13 )
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- else
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
-
- data = 0x0000 ;
- if ( infoflag & InterlaceMode )
- {
- if ( xres == 1024 )
- data = 0x0035 ;
- else if ( xres == 1280 )
- data = 0x0048 ;
- }
-
- data2 = data & 0x00FF ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x19 , 0xFF , data2 ) ;
- data2 = ( data & 0xFF00 ) >> 8 ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x19 , 0xFC , data2 ) ;
-
- if( modeflag & HalfDCLK )
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xF7 , 0x08 ) ;
-
- data2 = 0 ;
-
- if ( modeflag & LineCompareOff )
- data2 |= 0x08 ;
-
- if ( ModeNo > 0x13 )
- {
- if ( pVBInfo->ModeType == ModeEGA )
- data2 |= 0x40 ;
- }
-
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0F , ~0x48 , data2 ) ;
- data = 0x60 ;
- if ( pVBInfo->ModeType != ModeText )
- {
- data = data ^ 0x60 ;
- if ( pVBInfo->ModeType != ModeEGA )
- {
- data = data ^ 0xA0 ;
- }
- }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x21 , 0x1F , data ) ;
-
- XGI_SetVCLKState( HwDeviceExtension , ModeNo , RefreshRateTableIndex, pVBInfo) ;
-
- /* if(modeflag&HalfDCLK)//030305 fix lowresolution bug */
- /* if(XGINew_IF_DEF_NEW_LOWRES) */
- /* XGI_VesaLowResolution(ModeNo,ModeIdIndex);//030305 fix lowresolution bug */
-
- data=XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
-
- if (HwDeviceExtension->jChipType == XG27 )
- {
- if ( data & 0x40 )
- data = 0x2c ;
- else
- data = 0x6c ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
- XGINew_SetRegOR( pVBInfo->P3d4 , 0x51 , 0x10 ) ;
- }
- else
- if (HwDeviceExtension->jChipType >= XG20 )
- {
- if ( data & 0x40 )
- data = 0x33 ;
- else
- data = 0x73 ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x51 , 0x02 ) ;
- }
- else
- {
- if ( data & 0x40 )
- data = 0x2c ;
- else
- data = 0x6c ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x52 , data ) ;
- }
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
+ xres;
-}
+ if (ModeNo > 0x13) {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ } else
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+ if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01)
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+
+ if (ModeNo > 0x13)
+ data = infoflag;
+ else
+ data = 0;
+
+ data2 = 0;
+
+ if (ModeNo > 0x13) {
+ if (pVBInfo->ModeType > 0x02) {
+ data2 |= 0x02;
+ data3 = pVBInfo->ModeType - ModeVGA;
+ data3 = data3 << 2;
+ data2 |= data3;
+ }
+ }
+
+ data &= InterlaceMode;
+
+ if (data)
+ data2 |= 0x20;
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x3F, data2);
+ /* XGINew_SetReg1(pVBInfo->P3c4,0x06,data2); */
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13)
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ else
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+
+ data = 0x0000;
+ if (infoflag & InterlaceMode) {
+ if (xres == 1024)
+ data = 0x0035;
+ else if (xres == 1280)
+ data = 0x0048;
+ }
+
+ data2 = data & 0x00FF;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFF, data2);
+ data2 = (data & 0xFF00) >> 8;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFC, data2);
+
+ if (modeflag & HalfDCLK)
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
+
+ data2 = 0;
+
+ if (modeflag & LineCompareOff)
+ data2 |= 0x08;
+
+ if (ModeNo > 0x13) {
+ if (pVBInfo->ModeType == ModeEGA)
+ data2 |= 0x40;
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0F, ~0x48, data2);
+ data = 0x60;
+ if (pVBInfo->ModeType != ModeText) {
+ data = data ^ 0x60;
+ if (pVBInfo->ModeType != ModeEGA)
+ data = data ^ 0xA0;
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x21, 0x1F, data);
+
+ XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
+ pVBInfo);
+
+ /* if (modeflag&HalfDCLK) //030305 fix lowresolution bug */
+ /* if (XGINew_IF_DEF_NEW_LOWRES) */
+ /* XGI_VesaLowResolution(ModeNo, ModeIdIndex); //030305 fix lowresolution bug */
+
+ data = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
+
+ if (HwDeviceExtension->jChipType == XG27) {
+ if (data & 0x40)
+ data = 0x2c;
+ else
+ data = 0x6c;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
+ XGINew_SetRegOR(pVBInfo->P3d4, 0x51, 0x10);
+ } else if (HwDeviceExtension->jChipType >= XG20) {
+ if (data & 0x40)
+ data = 0x33;
+ else
+ data = 0x73;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0x02);
+ } else {
+ if (data & 0x40)
+ data = 0x2c;
+ else
+ data = 0x6c;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x52, data);
+ }
+
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetVCLKState */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short data ,
- data2 = 0 ;
- short VCLK ;
-
- unsigned char index;
-
- if ( ModeNo <= 0x13 )
- VCLK = 0 ;
- else
- {
- index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
- index &= IndexMask ;
- VCLK = pVBInfo->VCLKData[ index ].CLOCK ;
- }
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x32 ) ;
- data &= 0xf3 ;
- if ( VCLK >= 200 )
- data |= 0x0c ; /* VCLK > 200 */
-
- if ( HwDeviceExtension->jChipType >= XG20 )
- data &= ~0x04 ; /* 2 pixel mode */
-
- XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , data ) ;
-
- if ( HwDeviceExtension->jChipType < XG20 )
- {
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
- data &= 0xE7 ;
- if ( VCLK < 200 )
- data |= 0x10 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x1F , data ) ;
- }
-
-/* Jong for Adavantech LCD ripple issue
- if ( ( VCLK >= 0 ) && ( VCLK < 135 ) )
- data2 = 0x03 ;
- else if ( ( VCLK >= 135 ) && ( VCLK < 160 ) )
- data2 = 0x02 ;
- else if ( ( VCLK >= 160 ) && ( VCLK < 260 ) )
- data2 = 0x01 ;
- else if ( VCLK > 260 )
- data2 = 0x00 ;
-*/
- data2 = 0x00 ;
+ unsigned short ModeNo, unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2 = 0;
+ short VCLK;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x07 , 0xFC , data2 ) ;
- if (HwDeviceExtension->jChipType >= XG27 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x40 , 0xFC , data2&0x03 ) ;
- }
+ unsigned char index;
+ if (ModeNo <= 0x13)
+ VCLK = 0;
+ else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index &= IndexMask;
+ VCLK = pVBInfo->VCLKData[index].CLOCK;
+ }
+
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x32);
+ data &= 0xf3;
+ if (VCLK >= 200)
+ data |= 0x0c; /* VCLK > 200 */
+
+ if (HwDeviceExtension->jChipType >= XG20)
+ data &= ~0x04; /* 2 pixel mode */
+
+ XGINew_SetReg1(pVBInfo->P3c4, 0x32, data);
+
+ if (HwDeviceExtension->jChipType < XG20) {
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+ data &= 0xE7;
+ if (VCLK < 200)
+ data |= 0x10;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data);
+ }
+
+ /* Jong for Adavantech LCD ripple issue
+ if ((VCLK >= 0) && (VCLK < 135))
+ data2 = 0x03;
+ else if ((VCLK >= 135) && (VCLK < 160))
+ data2 = 0x02;
+ else if ((VCLK >= 160) && (VCLK < 260))
+ data2 = 0x01;
+ else if (VCLK > 260)
+ data2 = 0x00;
+ */
+ data2 = 0x00;
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2);
+ if (HwDeviceExtension->jChipType >= XG27)
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_VesaLowResolution */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-/*void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short modeflag;
-
- if ( ModeNo > 0x13 )
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- else
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
-
- if ( ModeNo > 0x13 )
- {
- if ( modeflag & DoubleScanMode )
- {
- if ( modeflag & HalfDCLK )
- {
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xf7 , 0x00 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0x7f , 0x00 ) ;
- return ;
- }
- }
- }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0xff , 0x80 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xf7 , 0x00 ) ;
- return ;
- }
- }
- }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0f , 0x7f , 0x00 ) ;
+/*
+void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ unsigned short modeflag;
+
+ if (ModeNo > 0x13)
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ else
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+
+ if (ModeNo > 0x13) {
+ if (modeflag & DoubleScanMode) {
+ if (modeflag & HalfDCLK) {
+ if (pVBInfo->VBType & VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00);
+ return;
+ }
+ }
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0xff, 0x80);
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
+ return;
+ }
+ }
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00);
}
*/
-/* --------------------------------------------------------------------- */
-/* Function : XGI_LoadDAC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_LoadDAC(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short data , data2 , time ,
- i , j , k , m , n , o ,
- si , di , bx , dl , al , ah , dh ,
- *table = NULL ;
-
- if ( ModeNo <= 0x13 )
- data = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- else
- data = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
-
- data &= DACInfoFlag ;
- time = 64 ;
-
- if ( data == 0x00 )
- table = XGINew_MDA_DAC ;
- else if ( data == 0x08 )
- table = XGINew_CGA_DAC ;
- else if ( data == 0x10 )
- table = XGINew_EGA_DAC ;
- else if ( data == 0x18 )
- {
- time = 256 ;
- table = XGINew_VGA_DAC ;
- }
-
- if ( time == 256 )
- j = 16 ;
- else
- j = time ;
-
- XGINew_SetReg3( pVBInfo->P3c6 , 0xFF ) ;
- XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
-
- for( i = 0 ; i < j ; i++ )
- {
- data = table[ i ] ;
-
- for( k = 0 ; k < 3 ; k++ )
- {
- data2 = 0 ;
-
- if ( data & 0x01 )
- data2 = 0x2A ;
-
- if ( data & 0x02 )
- data2 += 0x15 ;
-
- XGINew_SetReg3( pVBInfo->P3c9 , data2 ) ;
- data = data >> 2 ;
- }
- }
-
- if ( time == 256 )
- {
- for( i = 16 ; i < 32 ; i++ )
- {
- data = table[ i ] ;
-
- for( k = 0 ; k < 3 ; k++ )
- XGINew_SetReg3( pVBInfo->P3c9 , data ) ;
- }
-
- si = 32 ;
-
- for( m = 0 ; m < 9 ; m++ )
- {
- di = si ;
- bx = si + 0x04 ;
- dl = 0 ;
-
- for( n = 0 ; n < 3 ; n++ )
- {
- for( o = 0 ; o < 5 ; o++ )
- {
- dh = table[ si ] ;
- ah = table[ di ] ;
- al = table[ bx ] ;
- si++ ;
- XGI_WriteDAC( dl , ah , al , dh, pVBInfo ) ;
- }
-
- si -= 2 ;
-
- for( o = 0 ; o < 3 ; o++ )
- {
- dh = table[ bx ] ;
- ah = table[ di ] ;
- al = table[ si ] ;
- si-- ;
- XGI_WriteDAC( dl , ah , al , dh, pVBInfo ) ;
- }
-
- dl++ ;
- }
-
- si += 5 ;
- }
- }
-}
+void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al,
+ ah, dh, *table = NULL;
+ if (ModeNo <= 0x13)
+ data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ data &= DACInfoFlag;
+ time = 64;
+
+ if (data == 0x00)
+ table = XGINew_MDA_DAC;
+ else if (data == 0x08)
+ table = XGINew_CGA_DAC;
+ else if (data == 0x10)
+ table = XGINew_EGA_DAC;
+ else if (data == 0x18) {
+ time = 256;
+ table = XGINew_VGA_DAC;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_WriteDAC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_WriteDAC(unsigned short dl, unsigned short ah,
- unsigned short al, unsigned short dh,
- struct vb_device_info *pVBInfo)
-{
- unsigned short temp , bh , bl ;
-
- bh = ah ;
- bl = al ;
-
- if ( dl != 0 )
- {
- temp = bh ;
- bh = dh ;
- dh = temp ;
- if ( dl == 1 )
- {
- temp = bl ;
- bl = dh ;
- dh = temp ;
- }
- else
- {
- temp = bl ;
- bl = bh ;
- bh = temp ;
- }
- }
- XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)dh);
- XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)bh);
- XGINew_SetReg3(pVBInfo->P3c9, (unsigned short)bl);
+ if (time == 256)
+ j = 16;
+ else
+ j = time;
+
+ XGINew_SetReg3(pVBInfo->P3c6, 0xFF);
+ XGINew_SetReg3(pVBInfo->P3c8, 0x00);
+
+ for (i = 0; i < j; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++) {
+ data2 = 0;
+
+ if (data & 0x01)
+ data2 = 0x2A;
+
+ if (data & 0x02)
+ data2 += 0x15;
+
+ XGINew_SetReg3(pVBInfo->P3c9, data2);
+ data = data >> 2;
+ }
+ }
+
+ if (time == 256) {
+ for (i = 16; i < 32; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++)
+ XGINew_SetReg3(pVBInfo->P3c9, data);
+ }
+
+ si = 32;
+
+ for (m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 0x04;
+ dl = 0;
+
+ for (n = 0; n < 3; n++) {
+ for (o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
+ }
+
+ si -= 2;
+
+ for (o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
+ }
+
+ dl++;
+ }
+
+ si += 5;
+ }
+ }
}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDAGroup */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetLCDAGroup(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
+void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al,
+ unsigned short dh, struct vb_device_info *pVBInfo)
{
- unsigned short RefreshRateTableIndex ;
- /* unsigned short temp ; */
+ unsigned short temp, bh, bl;
- /* pVBInfo->SelectCRT2Rate = 0 ; */
+ bh = ah;
+ bl = al;
- pVBInfo->SetFlag |= ProgrammingCRT2 ;
- RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetLVDSResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetLVDSData( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo);
- XGI_ModCRT1Regs( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_SetLVDSRegs( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetCRT2ECLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
+ if (dl != 0) {
+ temp = bh;
+ bh = dh;
+ dh = temp;
+ if (dl == 1) {
+ temp = bl;
+ bl = dh;
+ dh = temp;
+ } else {
+ temp = bl;
+ bl = bh;
+ bh = temp;
+ }
+ }
+ XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh);
+ XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh);
+ XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl);
}
+void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short RefreshRateTableIndex;
+ /* unsigned short temp ; */
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLVDSResInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetLVDSResInfo(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short resindex , xres , yres , modeflag ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
- }
-
-
- /* if ( ModeNo > 0x13 ) */
- /* modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; */
- /* else */
- /* modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; */
-
- if ( ModeNo <= 0x13 )
- {
- resindex = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
- }
- else
- {
- resindex = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
- }
-
- /* resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ; */
-
- if ( ModeNo <= 0x13 )
- {
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- yres = pVBInfo->StResInfo[ resindex ].VTotal ;
- }
- else
- {
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ;
- yres = pVBInfo->ModeResInfo[ resindex ].VTotal ;
- }
- if ( ModeNo > 0x13 )
- {
- if ( modeflag & HalfDCLK )
- xres = xres << 1 ;
-
- if ( modeflag & DoubleScanMode )
- yres = yres << 1 ;
- }
- /* if ( modeflag & Charx8Dot ) */
- /* { */
-
- if ( xres == 720 )
- xres = 640 ;
-
- /* } */
- pVBInfo->VGAHDE = xres ;
- pVBInfo->HDE = xres ;
- pVBInfo->VGAVDE = yres ;
- pVBInfo->VDE = yres ;
+ /* pVBInfo->SelectCRT2Rate = 0; */
+
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
}
+void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short resindex, xres, yres, modeflag;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLVDSData */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetLVDSData(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx ;
- struct XGI330_LVDSDataStruct *LCDPtr = NULL ;
- struct XGI330_CHTVDataStruct *TVPtr = NULL ;
-
- tempbx = 2 ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- LCDPtr = (struct XGI330_LVDSDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- pVBInfo->VGAHT = LCDPtr->VGAHT ;
- pVBInfo->VGAVT = LCDPtr->VGAVT ;
- pVBInfo->HT = LCDPtr->LCDHT ;
- pVBInfo->VT = LCDPtr->LCDVT ;
- }
- if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- pVBInfo->VGAHT = TVPtr->VGAHT ;
- pVBInfo->VGAVT = TVPtr->VGAVT ;
- pVBInfo->HT = TVPtr->LCDHT ;
- pVBInfo->VT = TVPtr->LCDVT ;
- }
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- if ( !( pVBInfo->LCDInfo & ( SetLCDtoNonExpanding | EnableScalingLCD ) ) )
- {
- if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
- {
- pVBInfo->HDE = 1024 ;
- pVBInfo->VDE = 768 ;
- }
- else if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
- {
- pVBInfo->HDE = 1280 ;
- pVBInfo->VDE = 1024 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
- {
- pVBInfo->HDE = 1400 ;
- pVBInfo->VDE = 1050 ;
- }
- else
- {
- pVBInfo->HDE = 1600 ;
- pVBInfo->VDE = 1200 ;
- }
- }
- }
-}
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+ /* if (ModeNo > 0x13) */
+ /* modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; */
+ /* else */
+ /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; */
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ModCRT1Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned char index;
- unsigned short tempbx , i ;
- struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
- struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
- /* struct XGI330_CHTVDataStruct *TVPtr = NULL ; */
- struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
- struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
-
- if( ModeNo <= 0x13 )
- index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- else
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- index= index & IndexMask ;
-
- if ( ( pVBInfo->IF_DEF_ScaleLCD == 0 ) || ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( !( pVBInfo->LCDInfo & EnableScalingLCD ) ) ) )
- {
- tempbx = 0 ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-
- for( i = 0 ; i < 8 ; i++ )
- pVBInfo->TimingH[ 0 ].data[ i ] = LCDPtr[ 0 ].Reg[ i ] ;
- }
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- CH7007TV_TimingHPtr = (struct XGI_CH7007TV_TimingHStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-
- for( i = 0 ; i < 8 ; i++ )
- pVBInfo->TimingH[ 0 ].data[ i ] = CH7007TV_TimingHPtr[ 0 ].data[ i ] ;
- }
- }
-
- /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- TVPtr = ( struct XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- } */
-
- XGI_SetCRT1Timing_H(pVBInfo,HwDeviceExtension) ;
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , CH7007TV_TimingHPtr[ 0 ].data[ 8 ] ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2F , CH7007TV_TimingHPtr[ 0 ].data[ 9 ] ) ;
- }
-
- tempbx = 1 ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- for( i = 0 ; i < 7 ; i++ )
- pVBInfo->TimingV[ 0 ].data[ i ] = LCDPtr1[ 0 ].Reg[ i ] ;
- }
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- CH7007TV_TimingVPtr = (struct XGI_CH7007TV_TimingVStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-
- for( i = 0 ; i < 7 ; i++ )
- pVBInfo->TimingV[ 0 ].data[ i ] = CH7007TV_TimingVPtr[ 0 ].data[ i ] ;
- }
- }
- /* if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- TVPtr = ( struct XGI330_CHTVDataStruct *)XGI_GetTVPtr( tempbx , ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- } */
-
- XGI_SetCRT1Timing_V( ModeIdIndex , ModeNo , pVBInfo) ;
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x33 , ~0x01 , CH7007TV_TimingVPtr[ 0 ].data[ 7 ]&0x01 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , CH7007TV_TimingVPtr[ 0 ].data[8 ] ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x3F , CH7007TV_TimingVPtr[ 0 ].data[9 ] ) ;
-
- }
- }
-}
+ if (ModeNo <= 0x13)
+ resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+ else
+ resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+ /* resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); */
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ } else {
+ xres = pVBInfo->ModeResInfo[resindex].HTotal;
+ yres = pVBInfo->ModeResInfo[resindex].VTotal;
+ }
+ if (ModeNo > 0x13) {
+ if (modeflag & HalfDCLK)
+ xres = xres << 1;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLVDSRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx , tempax , tempcx , tempdx , push1 , push2 , modeflag ;
- unsigned long temp , temp1 , temp2 , temp3 , push3 ;
- struct XGI330_LCDDataDesStruct *LCDPtr = NULL ;
- struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL ;
-
- if ( ModeNo > 0x13 )
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- else
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
-
- if ( !( pVBInfo->SetFlag & Win9xDOSMode ) )
- {
- if ( ( pVBInfo->IF_DEF_CH7017 == 0 ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
- {
- if ( pVBInfo->IF_DEF_OEMUtil == 1 )
- {
- tempbx = 8 ;
- LCDPtr = (struct XGI330_LCDDataDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- }
-
- if ( ( pVBInfo->IF_DEF_OEMUtil == 0 ) || ( LCDPtr == 0 ) )
- {
- tempbx = 3 ;
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- LCDPtr1 = (struct XGI330_LCDDataDesStruct2 *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- else
- LCDPtr = (struct XGI330_LCDDataDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- }
-
- XGI_GetLCDSync( &tempax , &tempbx ,pVBInfo) ;
- push1 = tempbx ;
- push2 = tempax ;
-
- /* GetLCDResInfo */
- if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
- {
- tempax = 1024 ;
- tempbx = 768 ;
- }
- else if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
- {
- tempax = 1280 ;
- tempbx = 1024 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
- {
- tempax = 1400 ;
- tempbx = 1050 ;
- }
- else
- {
- tempax = 1600 ;
- tempbx = 1200 ;
- }
-
- if ( pVBInfo->LCDInfo & SetLCDtoNonExpanding )
- {
- pVBInfo->HDE=tempax;
- pVBInfo->VDE=tempbx;
- pVBInfo->VGAHDE=tempax;
- pVBInfo->VGAVDE=tempbx;
- }
-
- if ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( pVBInfo->LCDInfo & EnableScalingLCD ) )
- {
- tempax=pVBInfo->HDE;
- tempbx=pVBInfo->VDE;
- }
-
- tempax = pVBInfo->HT ;
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempbx = LCDPtr1->LCDHDES ;
- else
- tempbx = LCDPtr->LCDHDES ;
-
- tempcx = pVBInfo->HDE ;
- tempbx = tempbx & 0x0fff ;
- tempcx += tempbx ;
-
- if ( tempcx >= tempax )
- tempcx -= tempax ;
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x1A , tempbx & 0x07 ) ;
-
- tempcx = tempcx >> 3 ;
- tempbx = tempbx >> 3 ;
-
- XGINew_SetReg1(pVBInfo->Part1Port, 0x16, (unsigned short)(tempbx & 0xff));
- XGINew_SetReg1(pVBInfo->Part1Port, 0x17, (unsigned short)(tempcx & 0xff));
-
- tempax = pVBInfo->HT ;
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempbx = LCDPtr1->LCDHRS ;
- else
- tempbx = LCDPtr->LCDHRS ;
-
- tempcx = push2 ;
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempcx = LCDPtr1->LCDHSync ;
-
- tempcx += tempbx ;
-
- if ( tempcx >= tempax )
- tempcx -= tempax ;
-
- tempax = tempbx & 0x07 ;
- tempax = tempax >> 5 ;
- tempcx = tempcx >> 3 ;
- tempbx = tempbx >> 3 ;
-
- tempcx &= 0x1f ;
- tempax |= tempcx ;
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x15 , tempax ) ;
- XGINew_SetReg1(pVBInfo->Part1Port, 0x14, (unsigned short)(tempbx & 0xff));
+ if (modeflag & DoubleScanMode)
+ yres = yres << 1;
+ }
+ /* if (modeflag & Charx8Dot) */
+ /* { */
- tempax = pVBInfo->VT ;
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempbx = LCDPtr1->LCDVDES ;
- else
- tempbx = LCDPtr->LCDVDES ;
- tempcx = pVBInfo->VDE ;
+ if (xres == 720)
+ xres = 640;
- tempbx = tempbx & 0x0fff ;
- tempcx += tempbx ;
- if ( tempcx >= tempax )
- tempcx -= tempax ;
+ /* } */
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
- XGINew_SetReg1(pVBInfo->Part1Port, 0x1b, (unsigned short)(tempbx & 0xff));
- XGINew_SetReg1(pVBInfo->Part1Port, 0x1c, (unsigned short)(tempcx & 0xff));
+void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+ struct XGI330_LVDSDataStruct *LCDPtr = NULL;
+ struct XGI330_CHTVDataStruct *TVPtr = NULL;
- tempbx = ( tempbx >> 8 ) & 0x07 ;
- tempcx = ( tempcx >> 8 ) & 0x07 ;
+ tempbx = 2;
- XGINew_SetReg1(pVBInfo->Part1Port, 0x1d, (unsigned short)((tempcx << 3) | tempbx));
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
+ ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+ }
+ if (pVBInfo->IF_DEF_CH7017 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr(
+ tempbx, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ pVBInfo->VGAHT = TVPtr->VGAHT;
+ pVBInfo->VGAVT = TVPtr->VGAVT;
+ pVBInfo->HT = TVPtr->LCDHT;
+ pVBInfo->VT = TVPtr->LCDVT;
+ }
+ }
- tempax = pVBInfo->VT ;
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempbx = LCDPtr1->LCDVRS ;
- else
- tempbx = LCDPtr->LCDVRS ;
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
+ | EnableScalingLCD))) {
+ if ((pVBInfo->LCDResInfo == Panel1024x768)
+ || (pVBInfo->LCDResInfo
+ == Panel1024x768x75)) {
+ pVBInfo->HDE = 1024;
+ pVBInfo->VDE = 768;
+ } else if ((pVBInfo->LCDResInfo == Panel1280x1024)
+ || (pVBInfo->LCDResInfo
+ == Panel1280x1024x75)) {
+ pVBInfo->HDE = 1280;
+ pVBInfo->VDE = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+ pVBInfo->HDE = 1400;
+ pVBInfo->VDE = 1050;
+ } else {
+ pVBInfo->HDE = 1600;
+ pVBInfo->VDE = 1200;
+ }
+ }
+ }
+}
- /* tempbx = tempbx >> 4 ; */
- tempcx = push1 ;
+void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char index;
+ unsigned short tempbx, i;
+ struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
+ struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
+ /* struct XGI330_CHTVDataStruct *TVPtr = NULL; */
+ struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL;
+ struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL;
+
+ if (ModeNo <= 0x13)
+ index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ index = index & IndexMask;
+
+ if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1)
+ && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
+ tempbx = 0;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr
+ = (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(
+ tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
+ }
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ CH7007TV_TimingHPtr
+ = (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr(
+ tempbx,
+ ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH[0].data[i]
+ = CH7007TV_TimingHPtr[0].data[i];
+ }
+ }
+
+ /* if (pVBInfo->IF_DEF_CH7017 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ }
+ */
+
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E,
+ CH7007TV_TimingHPtr[0].data[8]);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2F,
+ CH7007TV_TimingHPtr[0].data[9]);
+ }
+
+ tempbx = 1;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr1
+ = (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(
+ tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
+ }
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ CH7007TV_TimingVPtr
+ = (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr(
+ tempbx,
+ ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV[0].data[i]
+ = CH7007TV_TimingVPtr[0].data[i];
+ }
+ }
+ /* if (pVBInfo->IF_DEF_CH7017 == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ }
+ */
+
+ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01,
+ CH7007TV_TimingVPtr[0].data[7] & 0x01);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34,
+ CH7007TV_TimingVPtr[0].data[8]);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x3F,
+ CH7007TV_TimingVPtr[0].data[9]);
+
+ }
+ }
+}
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempcx = LCDPtr1->LCDVSync ;
+void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
+ unsigned long temp, temp1, temp2, temp3, push3;
+ struct XGI330_LCDDataDesStruct *LCDPtr = NULL;
+ struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
- tempcx += tempbx ;
- if ( tempcx >= tempax )
- tempcx -= tempax ;
+ if (ModeNo > 0x13)
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ else
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+
+ if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
+ if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo
+ & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+ if (pVBInfo->IF_DEF_OEMUtil == 1) {
+ tempbx = 8;
+ LCDPtr
+ = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
+ tempbx,
+ ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ }
+
+ if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) {
+ tempbx = 3;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ LCDPtr1
+ = (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(
+ tempbx,
+ ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ else
+ LCDPtr
+ = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
+ tempbx,
+ ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ }
+
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ push1 = tempbx;
+ push2 = tempax;
+
+ /* GetLCDResInfo */
+ if ((pVBInfo->LCDResInfo == Panel1024x768)
+ || (pVBInfo->LCDResInfo
+ == Panel1024x768x75)) {
+ tempax = 1024;
+ tempbx = 768;
+ } else if ((pVBInfo->LCDResInfo == Panel1280x1024)
+ || (pVBInfo->LCDResInfo
+ == Panel1280x1024x75)) {
+ tempax = 1280;
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+ tempax = 1400;
+ tempbx = 1050;
+ } else {
+ tempax = 1600;
+ tempbx = 1200;
+ }
+
+ if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
+ pVBInfo->HDE = tempax;
+ pVBInfo->VDE = tempbx;
+ pVBInfo->VGAHDE = tempax;
+ pVBInfo->VGAVDE = tempbx;
+ }
+
+ if ((pVBInfo->IF_DEF_ScaleLCD == 1)
+ && (pVBInfo->LCDInfo & EnableScalingLCD)) {
+ tempax = pVBInfo->HDE;
+ tempbx = pVBInfo->VDE;
+ }
+
+ tempax = pVBInfo->HT;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDHDES;
+ else
+ tempbx = LCDPtr->LCDHDES;
+
+ tempcx = pVBInfo->HDE;
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
+
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x16,
+ (unsigned short) (tempbx & 0xff));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x17,
+ (unsigned short) (tempcx & 0xff));
+
+ tempax = pVBInfo->HT;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDHRS;
+ else
+ tempbx = LCDPtr->LCDHRS;
+
+ tempcx = push2;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDHSync;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ tempax = tempbx & 0x07;
+ tempax = tempax >> 5;
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ tempcx &= 0x1f;
+ tempax |= tempcx;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x14,
+ (unsigned short) (tempbx & 0xff));
+
+ tempax = pVBInfo->VT;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDVDES;
+ else
+ tempbx = LCDPtr->LCDVDES;
+ tempcx = pVBInfo->VDE;
+
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1b,
+ (unsigned short) (tempbx & 0xff));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1c,
+ (unsigned short) (tempcx & 0xff));
+
+ tempbx = (tempbx >> 8) & 0x07;
+ tempcx = (tempcx >> 8) & 0x07;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1d,
+ (unsigned short) ((tempcx << 3)
+ | tempbx));
+
+ tempax = pVBInfo->VT;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDVRS;
+ else
+ tempbx = LCDPtr->LCDVRS;
- XGINew_SetReg1(pVBInfo->Part1Port, 0x18, (unsigned short)(tempbx & 0xff));
- XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, (unsigned short)(tempcx & 0x0f));
+ /* tempbx = tempbx >> 4; */
+ tempcx = push1;
- tempax = ( ( tempbx >> 8 ) & 0x07 ) << 3 ;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDVSync;
- tempbx = pVBInfo->VGAVDE ;
- if ( tempbx != pVBInfo->VDE )
- tempax |= 0x40 ;
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
- if ( pVBInfo->LCDInfo & EnableLVDSDDA )
- tempax |= 0x40 ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x18,
+ (unsigned short) (tempbx & 0xff));
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f,
+ (unsigned short) (tempcx & 0x0f));
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1a , 0x07 , tempax ) ;
+ tempax = ((tempbx >> 8) & 0x07) << 3;
- tempcx = pVBInfo->VGAVT ;
- tempbx = pVBInfo->VDE ;
- tempax = pVBInfo->VGAVDE ;
- tempcx -= tempax ;
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx != pVBInfo->VDE)
+ tempax |= 0x40;
- temp = tempax ; /* 0430 ylshieh */
- temp1 = ( temp << 18 ) / tempbx ;
+ if (pVBInfo->LCDInfo & EnableLVDSDDA)
+ tempax |= 0x40;
- tempdx = (unsigned short)((temp << 18) % tempbx);
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07,
+ tempax);
- if ( tempdx != 0 )
- temp1 += 1 ;
+ tempcx = pVBInfo->VGAVT;
+ tempbx = pVBInfo->VDE;
+ tempax = pVBInfo->VGAVDE;
+ tempcx -= tempax;
- temp2 = temp1 ;
- push3 = temp2 ;
+ temp = tempax; /* 0430 ylshieh */
+ temp1 = (temp << 18) / tempbx;
- XGINew_SetReg1(pVBInfo->Part1Port, 0x37, (unsigned short)(temp2 & 0xff));
- XGINew_SetReg1(pVBInfo->Part1Port, 0x36, (unsigned short)((temp2 >> 8) & 0xff));
+ tempdx = (unsigned short) ((temp << 18) % tempbx);
- tempbx = (unsigned short)(temp2 >> 16);
- tempax = tempbx & 0x03 ;
+ if (tempdx != 0)
+ temp1 += 1;
- tempbx = pVBInfo->VGAVDE ;
- if ( tempbx == pVBInfo->VDE )
- tempax |= 0x04 ;
+ temp2 = temp1;
+ push3 = temp2;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x35 , tempax ) ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x37,
+ (unsigned short) (temp2 & 0xff));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x36,
+ (unsigned short) ((temp2 >> 8) & 0xff));
- if ( pVBInfo->VBType & VB_XGI301C )
- {
- temp2 = push3 ;
- XGINew_SetReg1(pVBInfo->Part4Port, 0x3c, (unsigned short)(temp2 & 0xff));
- XGINew_SetReg1(pVBInfo->Part4Port, 0x3b, (unsigned short)((temp2 >> 8) & 0xff));
- tempbx = (unsigned short)(temp2 >> 16);
- XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a, ~0xc0, (unsigned short)((tempbx & 0xff) << 6));
+ tempbx = (unsigned short) (temp2 >> 16);
+ tempax = tempbx & 0x03;
- tempcx = pVBInfo->VGAVDE ;
- if ( tempcx == pVBInfo->VDE )
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x30 , ~0x0c , 0x00 ) ;
- else
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x30 , ~0x0c , 0x08 ) ;
- }
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx == pVBInfo->VDE)
+ tempax |= 0x04;
- tempcx = pVBInfo->VGAHDE ;
- tempbx = pVBInfo->HDE ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax);
- temp1 = tempcx << 16 ;
+ if (pVBInfo->VBType & VB_XGI301C) {
+ temp2 = push3;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x3c,
+ (unsigned short) (temp2 & 0xff));
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x3b,
+ (unsigned short) ((temp2 >> 8)
+ & 0xff));
+ tempbx = (unsigned short) (temp2 >> 16);
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a,
+ ~0xc0,
+ (unsigned short) ((tempbx
+ & 0xff) << 6));
- tempax = (unsigned short)(temp1 / tempbx);
+ tempcx = pVBInfo->VGAVDE;
+ if (tempcx == pVBInfo->VDE)
+ XGINew_SetRegANDOR(pVBInfo->Part4Port,
+ 0x30, ~0x0c, 0x00);
+ else
+ XGINew_SetRegANDOR(pVBInfo->Part4Port,
+ 0x30, ~0x0c, 0x08);
+ }
- if ( ( tempbx & 0xffff ) == ( tempcx & 0xffff ) )
- tempax = 65535 ;
+ tempcx = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
- temp3 = tempax ;
- temp1 = pVBInfo->VGAHDE << 16 ;
+ temp1 = tempcx << 16;
- temp1 /= temp3 ;
- temp3 = temp3 << 16 ;
- temp1 -= 1 ;
+ tempax = (unsigned short) (temp1 / tempbx);
- temp3 = ( temp3 & 0xffff0000 ) + ( temp1 & 0xffff ) ;
+ if ((tempbx & 0xffff) == (tempcx & 0xffff))
+ tempax = 65535;
- tempax = (unsigned short)(temp3 & 0xff);
- XGINew_SetReg1( pVBInfo->Part1Port , 0x1f , tempax ) ;
+ temp3 = tempax;
+ temp1 = pVBInfo->VGAHDE << 16;
- temp1 = pVBInfo->VGAVDE << 18 ;
- temp1 = temp1 / push3 ;
- tempbx = (unsigned short)(temp1 & 0xffff);
+ temp1 /= temp3;
+ temp3 = temp3 << 16;
+ temp1 -= 1;
- if ( pVBInfo->LCDResInfo == Panel1024x768 )
- tempbx -= 1 ;
+ temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
- tempax = ( ( tempbx >> 8 ) & 0xff ) << 3 ;
- tempax |= (unsigned short)((temp3 >> 8) & 0x07);
- XGINew_SetReg1(pVBInfo->Part1Port, 0x20, (unsigned short)(tempax & 0xff));
- XGINew_SetReg1(pVBInfo->Part1Port, 0x21, (unsigned short)(tempbx & 0xff));
+ tempax = (unsigned short) (temp3 & 0xff);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax);
- temp3 = temp3 >> 16 ;
+ temp1 = pVBInfo->VGAVDE << 18;
+ temp1 = temp1 / push3;
+ tempbx = (unsigned short) (temp1 & 0xffff);
- if ( modeflag & HalfDCLK )
- temp3 = temp3 >> 1 ;
+ if (pVBInfo->LCDResInfo == Panel1024x768)
+ tempbx -= 1;
- XGINew_SetReg1(pVBInfo->Part1Port , 0x22, (unsigned short)((temp3 >> 8) & 0xff));
- XGINew_SetReg1(pVBInfo->Part1Port , 0x23, (unsigned short)(temp3 & 0xff));
- }
- }
-}
+ tempax = ((tempbx >> 8) & 0xff) << 3;
+ tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x20,
+ (unsigned short) (tempax & 0xff));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x21,
+ (unsigned short) (tempbx & 0xff));
+ temp3 = temp3 >> 16;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2ECLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
-{
- unsigned char di_0, di_1, tempal;
- int i ;
-
- tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetVCLKLen( tempal , &di_0 , &di_1, pVBInfo ) ;
- XGI_GetLCDVCLKPtr( &di_0 , &di_1, pVBInfo ) ;
-
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, (unsigned short)(0x10 * i));
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2b , di_0 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2c , di_1 ) ;
- }
- else if ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) )
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2e , di_0 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2f , di_1 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2b , di_0 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2c , di_1 ) ;
- }
- }
-}
+ if (modeflag & HalfDCLK)
+ temp3 = temp3 >> 1;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x22,
+ (unsigned short) ((temp3 >> 8) & 0xff));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x23,
+ (unsigned short) (temp3 & 0xff));
+ }
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_UpdateModeInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempcl ,
- tempch ,
- temp ,
- tempbl ,
- tempax ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempcl = 0 ;
- tempch = 0 ;
- temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
-
- if ( !( temp & 0x20 ) )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x17 ) ;
- if ( temp & 0x80 )
- {
- if ( ( HwDeviceExtension->jChipType >= XG20 ) || ( HwDeviceExtension->jChipType >= XG40 ) )
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x53 ) ;
- else
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x63 ) ;
-
- if ( !( temp & 0x40 ) )
- tempcl |= ActiveCRT1 ;
- }
- }
-
- temp = XGINew_GetReg1( pVBInfo->Part1Port , 0x2e ) ;
- temp &= 0x0f ;
-
- if ( !( temp == 0x08 ) )
- {
- tempax = XGINew_GetReg1( pVBInfo->Part1Port , 0x13 ) ; /* Check ChannelA by Part1_13 [2003/10/03] */
- if ( tempax & 0x04 )
- tempcl = tempcl | ActiveLCD ;
-
- temp &= 0x05 ;
-
- if ( !( tempcl & ActiveLCD ) )
- if ( temp == 0x01 )
- tempcl |= ActiveCRT2 ;
-
- if ( temp == 0x04 )
- tempcl |= ActiveLCD ;
-
- if ( temp == 0x05 )
- {
- temp = XGINew_GetReg1( pVBInfo->Part2Port , 0x00 ) ;
-
- if( !( temp & 0x08 ) )
- tempch |= ActiveAVideo ;
-
- if ( !( temp & 0x04 ) )
- tempch |= ActiveSVideo ;
-
- if ( temp & 0x02 )
- tempch |= ActiveSCART ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( temp & 0x01 )
- tempch |= ActiveHiTV ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- temp = XGINew_GetReg1( pVBInfo->Part2Port , 0x4d ) ;
-
- if ( temp & 0x10 )
- tempch |= ActiveYPbPr ;
- }
-
- if ( tempch != 0 )
- tempcl |= ActiveTV ;
- }
- }
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x3d ) ;
- if ( tempcl & ActiveLCD )
- {
- if ( ( pVBInfo->SetFlag & ReserveTVOption ) )
- {
- if ( temp & ActiveTV )
- tempcl |= ActiveTV ;
- }
- }
- temp = tempcl ;
- tempbl = ~ModeSwitchStatus ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x3d , tempbl , temp ) ;
-
- if ( !( pVBInfo->SetFlag & ReserveTVOption ) )
- XGINew_SetReg1( pVBInfo->P3d4 , 0x3e , tempch ) ;
- }
- else
- {
- return ;
- }
+void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char di_0, di_1, tempal;
+ int i;
+
+ tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
+ pVBInfo);
+ XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+ XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+
+ for (i = 0; i < 4; i++) {
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30,
+ (unsigned short) (0x10 * i));
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
+ } else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1);
+ } else {
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1);
+ }
+ }
}
+void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempcl, tempch, temp, tempbl, tempax;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ tempcl = 0;
+ tempch = 0;
+ temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
+
+ if (!(temp & 0x20)) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17);
+ if (temp & 0x80) {
+ if ((HwDeviceExtension->jChipType >= XG20)
+ || (HwDeviceExtension->jChipType
+ >= XG40))
+ temp = XGINew_GetReg1(pVBInfo->P3d4,
+ 0x53);
+ else
+ temp = XGINew_GetReg1(pVBInfo->P3d4,
+ 0x63);
+
+ if (!(temp & 0x40))
+ tempcl |= ActiveCRT1;
+ }
+ }
+
+ temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e);
+ temp &= 0x0f;
+
+ if (!(temp == 0x08)) {
+ tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
+ if (tempax & 0x04)
+ tempcl = tempcl | ActiveLCD;
+
+ temp &= 0x05;
+
+ if (!(tempcl & ActiveLCD))
+ if (temp == 0x01)
+ tempcl |= ActiveCRT2;
+
+ if (temp == 0x04)
+ tempcl |= ActiveLCD;
+
+ if (temp == 0x05) {
+ temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
+
+ if (!(temp & 0x08))
+ tempch |= ActiveAVideo;
+
+ if (!(temp & 0x04))
+ tempch |= ActiveSVideo;
+
+ if (temp & 0x02)
+ tempch |= ActiveSCART;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (temp & 0x01)
+ tempch |= ActiveHiTV;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ temp = XGINew_GetReg1(
+ pVBInfo->Part2Port,
+ 0x4d);
+
+ if (temp & 0x10)
+ tempch |= ActiveYPbPr;
+ }
+
+ if (tempch != 0)
+ tempcl |= ActiveTV;
+ }
+ }
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
+ if (tempcl & ActiveLCD) {
+ if ((pVBInfo->SetFlag & ReserveTVOption)) {
+ if (temp & ActiveTV)
+ tempcl |= ActiveTV;
+ }
+ }
+ temp = tempcl;
+ tempbl = ~ModeSwitchStatus;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp);
+
+ if (!(pVBInfo->SetFlag & ReserveTVOption))
+ XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch);
+ } else {
+ return;
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVGAType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- /*
- if ( HwDeviceExtension->jChipType >= XG20 )
- {
- pVBInfo->Set_VGAType = XG20;
- }
- else if ( HwDeviceExtension->jChipType >= XG40 )
- {
- pVBInfo->Set_VGAType = VGA_XGI340 ;
- }
- */
- pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
+ /*
+ if ( HwDeviceExtension->jChipType >= XG20 ) {
+ pVBInfo->Set_VGAType = XG20;
+ } else if (HwDeviceExtension->jChipType >= XG40) {
+ pVBInfo->Set_VGAType = VGA_XGI340;
+ }
+ */
+ pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVBType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_GetVBType(struct vb_device_info *pVBInfo)
{
- unsigned short flag , tempbx , tempah ;
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- pVBInfo->VBType = VB_CH7007 ;
- return;
- }
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- tempbx = VB_XGI302B ;
- flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x00 ) ;
- if ( flag != 0x02 )
- {
- tempbx = VB_XGI301 ;
- flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x01 ) ;
- if ( flag >= 0xB0 )
- {
- tempbx = VB_XGI301B ;
- if ( flag >= 0xC0 )
- {
- tempbx = VB_XGI301C ;
- if ( flag >= 0xD0 )
- {
- tempbx = VB_XGI301LV ;
- if ( flag >= 0xE0 )
- {
- tempbx = VB_XGI302LV ;
- tempah = XGINew_GetReg1( pVBInfo->Part4Port , 0x39 ) ;
- if ( tempah != 0xFF )
- tempbx = VB_XGI301C ;
- }
- }
- }
-
- if ( tempbx & ( VB_XGI301B | VB_XGI302B ) )
- {
- flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x23 ) ;
-
- if ( !( flag & 0x02 ) )
- tempbx = tempbx | VB_NoLCD ;
- }
- }
- }
- pVBInfo->VBType = tempbx ;
- }
-/*
- else if ( pVBInfo->IF_DEF_CH7017 == 1 )
- pVBInfo->VBType = VB_CH7017 ;
- else //LVDS
- pVBInfo->VBType = VB_LVDS_NS ;
-*/
+ unsigned short flag, tempbx, tempah;
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ pVBInfo->VBType = VB_CH7007;
+ return;
+ }
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ tempbx = VB_XGI302B;
+ flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
+ if (flag != 0x02) {
+ tempbx = VB_XGI301;
+ flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
+ if (flag >= 0xB0) {
+ tempbx = VB_XGI301B;
+ if (flag >= 0xC0) {
+ tempbx = VB_XGI301C;
+ if (flag >= 0xD0) {
+ tempbx = VB_XGI301LV;
+ if (flag >= 0xE0) {
+ tempbx = VB_XGI302LV;
+ tempah
+ = XGINew_GetReg1(
+ pVBInfo->Part4Port,
+ 0x39);
+ if (tempah != 0xFF)
+ tempbx
+ = VB_XGI301C;
+ }
+ }
+ }
+
+ if (tempbx & (VB_XGI301B | VB_XGI302B)) {
+ flag = XGINew_GetReg1(
+ pVBInfo->Part4Port,
+ 0x23);
+
+ if (!(flag & 0x02))
+ tempbx = tempbx | VB_NoLCD;
+ }
+ }
+ }
+ pVBInfo->VBType = tempbx;
+ }
+ /*
+ else if (pVBInfo->IF_DEF_CH7017 == 1)
+ pVBInfo->VBType = VB_CH7017;
+ else //LVDS
+ pVBInfo->VBType = VB_LVDS_NS;
+ */
}
+void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, push, tempbx, temp, modeflag;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVBInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax ,
- push ,
- tempbx ,
- temp ,
- modeflag ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
-
- pVBInfo->SetFlag = 0 ;
- pVBInfo->ModeType = modeflag & ModeInfoFlag ;
- tempbx = 0 ;
-
- if ( pVBInfo->VBType & 0xFFFF )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x30 ) ; /* Check Display Device */
- tempbx = tempbx | temp ;
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x31 ) ;
- push = temp ;
- push = push << 8 ;
- tempax = temp << 8 ;
- tempbx = tempbx | tempax ;
- temp = ( SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA | SetInSlaveMode | DisableCRT2Display ) ;
- temp = 0xFFFF ^ temp ;
- tempbx &= temp ;
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ;
-
- if ( pVBInfo->IF_DEF_LCDA == 1 )
- {
-
- if ( ( pVBInfo->Set_VGAType >= XG20 ) || ( pVBInfo->Set_VGAType >= XG40 ))
- {
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
- if ( pVBInfo->VBType & ( VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( temp & EnableDualEdge )
- {
- tempbx |= SetCRT2ToDualEdge ;
-
- if ( temp & SetToLCDA )
- tempbx |= SetCRT2ToLCDA ;
- }
- }
- }
- else if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- if ( pVBInfo->VBType & VB_CH7017 )
- {
- if ( temp & EnableDualEdge )
- {
- tempbx |= SetCRT2ToDualEdge ;
-
- if ( temp & SetToLCDA )
- tempbx |= SetCRT2ToLCDA ;
- }
- }
- }
- }
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( ( ( pVBInfo->IF_DEF_LVDS == 0 ) && ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) )
- || ( ( pVBInfo->IF_DEF_CH7017 == 1 ) && ( pVBInfo->VBType&VB_CH7017 ) ) || ( (pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType&VB_CH7007) ) ) /* [Billy] 07/05/04 */
- {
- if ( temp & SetYPbPr ) /* temp = CR38 */
- {
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ; /* shampoo add for new scratch */
- temp &= YPbPrMode ;
- tempbx |= SetCRT2ToHiVisionTV ;
-
- if ( temp != YPbPrMode1080i ) {
- tempbx &= ( ~SetCRT2ToHiVisionTV ) ;
- tempbx |= SetCRT2ToYPbPr ; }
- }
-
- /* tempbx |= SetCRT2ToYPbPr ; */
- }
- }
- }
-
- tempax = push ; /* restore CR31 */
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- temp = 0x09FC ;
- else
- temp = 0x097C ;
- }
- else
- {
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- temp = 0x01FC ;
- else
- temp = 0x017C ;
- }
- }
- else /* 3nd party chip */
- {
- if ( pVBInfo->IF_DEF_CH7017 == 1 )
- temp = ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) ;
- else if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/03 */
- {
- temp = SetCRT2ToTV ;
- }
- else
- temp = SetCRT2ToLCD ;
- }
-
- if ( !( tempbx & temp ) )
- {
- tempax |= DisableCRT2Display ;
- tempbx = 0 ;
- }
-
- if ( pVBInfo->IF_DEF_LCDA == 1 ) /* Select Display Device */
- {
- if ( !( pVBInfo->VBType & VB_NoLCD ) )
- {
- if ( tempbx & SetCRT2ToLCDA )
- {
- if ( tempbx & SetSimuScanMode )
- tempbx &= ( ~( SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2 ) ) ;
- else
- tempbx &= ( ~( SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV | SwitchToCRT2 ) ) ;
- }
- }
- }
-
- /* shampoo add */
- if ( !( tempbx & ( SwitchToCRT2 | SetSimuScanMode ) ) ) /* for driver abnormal */
- {
- if ( pVBInfo->IF_DEF_CRT2Monitor == 1 )
- {
- if ( tempbx & SetCRT2ToRAMDAC )
- {
- tempbx &= ( 0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 | SetSimuScanMode ) ;
- tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
- }
- }
- else
- tempbx &= ( ~( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) ;
- }
-
- if ( !( pVBInfo->VBType & VB_NoLCD ) )
- {
- if ( tempbx & SetCRT2ToLCD )
- {
- tempbx &= ( 0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode ) ;
- tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
- }
- }
-
- if ( tempbx & SetCRT2ToSCART )
- {
- tempbx &= ( 0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode ) ;
- tempbx &= ( 0x00FF | ( ~SetCRT2ToYPbPr ) ) ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( tempbx & SetCRT2ToYPbPr )
- tempbx &= ( 0xFF00 | SwitchToCRT2 | SetSimuScanMode ) ;
- }
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( tempbx & SetCRT2ToHiVisionTV )
- tempbx &= ( 0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode ) ;
- }
-
- if ( tempax & DisableCRT2Display ) /* Set Display Device Info */
- {
- if ( !( tempbx & ( SwitchToCRT2 | SetSimuScanMode ) ) )
- tempbx = DisableCRT2Display ;
- }
-
- if ( !( tempbx & DisableCRT2Display ) )
- {
- if ( ( !( tempbx & DriverMode ) ) || ( !( modeflag & CRT2Mode ) ) )
- {
- if ( pVBInfo->IF_DEF_LCDA == 1 )
- {
- if ( !( tempbx & SetCRT2ToLCDA ) )
- tempbx |= ( SetInSlaveMode | SetSimuScanMode ) ;
- }
-
- if ( pVBInfo->IF_DEF_VideoCapture == 1 )
- {
- if ( ( ( HwDeviceExtension->jChipType == XG40 ) && ( pVBInfo->Set_VGAType == XG40 ) )
- || ( ( HwDeviceExtension->jChipType == XG41 ) && ( pVBInfo->Set_VGAType == XG41 ) )
- || ( ( HwDeviceExtension->jChipType == XG42 ) && ( pVBInfo->Set_VGAType == XG42 ) )
- || ( ( HwDeviceExtension->jChipType == XG45 ) && ( pVBInfo->Set_VGAType == XG45 ) ) )
- {
- if ( ModeNo <= 13 )
- {
- if ( !( tempbx & SetCRT2ToRAMDAC ) ) /*CRT2 not need to support*/
- {
- tempbx &= ( 0x00FF | ( ~SetInSlaveMode ) ) ;
- pVBInfo->SetFlag |= EnableVCMode ;
- }
- }
- }
- }
- }
-
- /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB)*/
- if ( ( tempbx & SetInSlaveMode ) && ( tempbx & SetCRT2ToLCDA ) )
- {
- tempbx ^= ( SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge ) ;
- pVBInfo->SetFlag |= ReserveTVOption ;
- }
- }
- }
-
- pVBInfo->VBInfo = tempbx ;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ pVBInfo->SetFlag = 0;
+ pVBInfo->ModeType = modeflag & ModeInfoFlag;
+ tempbx = 0;
+
+ if (pVBInfo->VBType & 0xFFFF) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */
+ tempbx = tempbx | temp;
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
+ push = temp;
+ push = push << 8;
+ tempax = temp << 8;
+ tempbx = tempbx | tempax;
+ temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA
+ | SetInSlaveMode | DisableCRT2Display);
+ temp = 0xFFFF ^ temp;
+ tempbx &= temp;
+
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
+
+ if (pVBInfo->IF_DEF_LCDA == 1) {
+
+ if ((pVBInfo->Set_VGAType >= XG20)
+ || (pVBInfo->Set_VGAType >= XG40)) {
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ /* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */
+ if (pVBInfo->VBType & (VB_XGI302B
+ | VB_XGI301LV
+ | VB_XGI302LV
+ | VB_XGI301C)) {
+ if (temp & EnableDualEdge) {
+ tempbx
+ |= SetCRT2ToDualEdge;
+
+ if (temp & SetToLCDA)
+ tempbx
+ |= SetCRT2ToLCDA;
+ }
+ }
+ } else if (pVBInfo->IF_DEF_CH7017 == 1) {
+ if (pVBInfo->VBType & VB_CH7017) {
+ if (temp & EnableDualEdge) {
+ tempbx
+ |= SetCRT2ToDualEdge;
+
+ if (temp & SetToLCDA)
+ tempbx
+ |= SetCRT2ToLCDA;
+ }
+ }
+ }
+ }
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType
+ & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV) || (pVBInfo->VBType
+ & VB_XGI301C)))
+ || ((pVBInfo->IF_DEF_CH7017 == 1)
+ && (pVBInfo->VBType
+ & VB_CH7017))
+ || ((pVBInfo->IF_DEF_CH7007 == 1)
+ && (pVBInfo->VBType
+ & VB_CH7007))) { /* [Billy] 07/05/04 */
+ if (temp & SetYPbPr) { /* temp = CR38 */
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ temp = XGINew_GetReg1(
+ pVBInfo->P3d4,
+ 0x35); /* shampoo add for new scratch */
+ temp &= YPbPrMode;
+ tempbx |= SetCRT2ToHiVisionTV;
+
+ if (temp != YPbPrMode1080i) {
+ tempbx
+ &= (~SetCRT2ToHiVisionTV);
+ tempbx
+ |= SetCRT2ToYPbPr;
+ }
+ }
+
+ /* tempbx |= SetCRT2ToYPbPr; */
+ }
+ }
+ }
+
+ tempax = push; /* restore CR31 */
+
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (pVBInfo->IF_DEF_HiVision == 1)
+ temp = 0x09FC;
+ else
+ temp = 0x097C;
+ } else {
+ if (pVBInfo->IF_DEF_HiVision == 1)
+ temp = 0x01FC;
+ else
+ temp = 0x017C;
+ }
+ } else { /* 3nd party chip */
+ if (pVBInfo->IF_DEF_CH7017 == 1)
+ temp = (SetCRT2ToTV | SetCRT2ToLCD
+ | SetCRT2ToLCDA);
+ else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */
+ temp = SetCRT2ToTV;
+ } else
+ temp = SetCRT2ToLCD;
+ }
+
+ if (!(tempbx & temp)) {
+ tempax |= DisableCRT2Display;
+ tempbx = 0;
+ }
+
+ if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & SetCRT2ToLCDA) {
+ if (tempbx & SetSimuScanMode)
+ tempbx
+ &= (~(SetCRT2ToLCD
+ | SetCRT2ToRAMDAC
+ | SwitchToCRT2));
+ else
+ tempbx
+ &= (~(SetCRT2ToLCD
+ | SetCRT2ToRAMDAC
+ | SetCRT2ToTV
+ | SwitchToCRT2));
+ }
+ }
+ }
+
+ /* shampoo add */
+ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
+ if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+ if (tempbx & SetCRT2ToRAMDAC) {
+ tempbx &= (0xFF00 | SetCRT2ToRAMDAC
+ | SwitchToCRT2
+ | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+ } else {
+ tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD
+ | SetCRT2ToTV));
+ }
+ }
+
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & SetCRT2ToLCD) {
+ tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2
+ | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+ }
+
+ if (tempbx & SetCRT2ToSCART) {
+ tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2
+ | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (tempbx & SetCRT2ToYPbPr)
+ tempbx &= (0xFF00 | SwitchToCRT2
+ | SetSimuScanMode);
+ }
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if (tempbx & SetCRT2ToHiVisionTV)
+ tempbx &= (0xFF00 | SetCRT2ToHiVisionTV
+ | SwitchToCRT2
+ | SetSimuScanMode);
+ }
+
+ if (tempax & DisableCRT2Display) { /* Set Display Device Info */
+ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
+ tempbx = DisableCRT2Display;
+ }
+
+ if (!(tempbx & DisableCRT2Display)) {
+ if ((!(tempbx & DriverMode))
+ || (!(modeflag & CRT2Mode))) {
+ if (pVBInfo->IF_DEF_LCDA == 1) {
+ if (!(tempbx & SetCRT2ToLCDA))
+ tempbx
+ |= (SetInSlaveMode
+ | SetSimuScanMode);
+ }
+
+ if (pVBInfo->IF_DEF_VideoCapture == 1) {
+ if (((HwDeviceExtension->jChipType
+ == XG40)
+ && (pVBInfo->Set_VGAType
+ == XG40))
+ || ((HwDeviceExtension->jChipType
+ == XG41)
+ && (pVBInfo->Set_VGAType
+ == XG41))
+ || ((HwDeviceExtension->jChipType
+ == XG42)
+ && (pVBInfo->Set_VGAType
+ == XG42))
+ || ((HwDeviceExtension->jChipType
+ == XG45)
+ && (pVBInfo->Set_VGAType
+ == XG45))) {
+ if (ModeNo <= 13) {
+ if (!(tempbx
+ & SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/
+ tempbx
+ &= (0x00FF
+ | (~SetInSlaveMode));
+ pVBInfo->SetFlag
+ |= EnableVCMode;
+ }
+ }
+ }
+ }
+ }
+
+ /* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
+ if ((tempbx & SetInSlaveMode) && (tempbx
+ & SetCRT2ToLCDA)) {
+ tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA
+ | SetCRT2ToDualEdge);
+ pVBInfo->SetFlag |= ReserveTVOption;
+ }
+ }
+ }
+
+ pVBInfo->VBInfo = tempbx;
+}
+
+void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
+
+ tempbx = 0;
+ resinfo = 0;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (ModeNo <= 0x13) {
+ modeflag
+ = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+ } else {
+ modeflag
+ = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo
+ = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+ tempbx = temp;
+ if (tempbx & SetPALTV) {
+ tempbx &= (SetCHTVOverScan | SetPALMTV
+ | SetPALNTV | SetPALTV);
+ if (tempbx & SetPALMTV)
+ tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
+ } else
+ tempbx &= (SetCHTVOverScan | SetNTSCJ
+ | SetPALTV);
+ /*
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info
+ temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N
+ tempbx |= temp2;
+ if (temp2 & 0x02) //PAL-M
+ tempbx &= (~SetPALTV);
+ }
+ */
+ }
+
+ if (pVBInfo->IF_DEF_CH7017 == 1) {
+ tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+
+ if (tempbx & TVOverScan)
+ tempbx |= SetCHTVOverScan;
+ }
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */
+ tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+
+ if (tempbx & TVOverScan)
+ tempbx |= SetCHTVOverScan;
+ }
+
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempbx |= SetPALTV;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35);
+ index1 &= YPbPrMode;
+
+ if (index1 == YPbPrMode525i)
+ tempbx |= SetYPbPrMode525i;
+
+ if (index1 == YPbPrMode525p)
+ tempbx = tempbx | SetYPbPrMode525p;
+ if (index1 == YPbPrMode750p)
+ tempbx = tempbx | SetYPbPrMode750p;
+ }
+ }
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
+ }
+
+ if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
+ if ((pVBInfo->VBInfo & SetInSlaveMode)
+ && (!(pVBInfo->VBInfo & SetNotSimuMode)))
+ tempbx |= TVSimuMode;
+
+ if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo
+ == 8)) /* NTSC 1024x768, */
+ tempbx |= NTSC1024x768;
+
+ tempbx |= RPLLDIV2XO;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempbx &= (~RPLLDIV2XO);
+ } else {
+ if (tempbx & (SetYPbPrMode525p
+ | SetYPbPrMode750p))
+ tempbx &= (~RPLLDIV2XO);
+ else if (!(pVBInfo->VBType & (VB_XGI301B
+ | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C))) {
+ if (tempbx & TVSimuMode)
+ tempbx &= (~RPLLDIV2XO);
+ }
+ }
+ }
+ }
+ pVBInfo->TVInfo = tempbx;
}
+unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short temp ,
- tempbx = 0 ,
- resinfo = 0 ,
- modeflag ,
- index1 ;
-
- tempbx = 0 ;
- resinfo = 0 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ; /* si+St_ResInfo */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo */
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
- tempbx = temp;
- if ( tempbx & SetPALTV )
- {
- tempbx &= ( SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV ) ;
- if ( tempbx & SetPALMTV )
- tempbx &= ~SetPALTV ; /* set to NTSC if PAL-M */
- }
- else
- tempbx &= ( SetCHTVOverScan | SetNTSCJ | SetPALTV ) ;
-/*
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- index1 = XGINew_GetReg1( pVBInfo->P3d4 , 0x38 ) ; //PAL-M/PAL-N Info
- temp2 = ( index1 & 0xC0 ) >> 5 ; //00:PAL, 01:PAL-M, 10:PAL-N
- tempbx |= temp2 ;
- if ( temp2 & 0x02 ) //PAL-M
- tempbx &= ( ~SetPALTV ) ;
- }
-*/
- }
-
- if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- tempbx = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
-
- if ( tempbx & TVOverScan )
- tempbx |= SetCHTVOverScan ;
- }
-
- if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/04 */
- {
- tempbx = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
-
- if ( tempbx & TVOverScan )
- {
- tempbx |= SetCHTVOverScan ;
- }
- }
-
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToSCART )
- tempbx |= SetPALTV ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- index1 = XGINew_GetReg1( pVBInfo->P3d4 , 0x35 ) ;
- index1 &= YPbPrMode ;
-
- if ( index1 == YPbPrMode525i )
- tempbx |= SetYPbPrMode525i ;
-
- if ( index1 == YPbPrMode525p )
- tempbx = tempbx | SetYPbPrMode525p;
- if ( index1 == YPbPrMode750p)
- tempbx = tempbx | SetYPbPrMode750p;
- }
- }
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- tempbx = tempbx | SetYPbPrMode1080i | SetPALTV ;
- }
- }
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- { /* shampoo */
- if ( ( pVBInfo->VBInfo & SetInSlaveMode ) && ( !( pVBInfo->VBInfo & SetNotSimuMode ) ) )
- tempbx |= TVSimuMode ;
-
- if ( !( tempbx & SetPALTV ) && ( modeflag > 13 ) && ( resinfo == 8 ) ) /* NTSC 1024x768, */
- tempbx |= NTSC1024x768 ;
-
- tempbx |= RPLLDIV2XO ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- tempbx &=( ~RPLLDIV2XO ) ;
- }
- else
- {
- if ( tempbx & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
- tempbx &= ( ~RPLLDIV2XO ) ;
- else if ( !( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) )
- {
- if ( tempbx & TVSimuMode )
- tempbx &= ( ~RPLLDIV2XO ) ;
- }
- }
- }
- }
- pVBInfo->TVInfo = tempbx ;
-}
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short temp ,
- tempax ,
- tempbx ,
- modeflag ,
- resinfo = 0 ,
- LCDIdIndex ;
-
- pVBInfo->LCDResInfo = 0 ;
- pVBInfo->LCDTypeInfo = 0 ;
- pVBInfo->LCDInfo = 0 ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ModeFlag // */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ; /* si+Ext_ResInfo// */
- }
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ; /* Get LCD Res.Info */
- tempbx = temp & 0x0F ;
-
- if ( tempbx == 0 )
- tempbx = Panel1024x768 ; /* default */
-
- /* LCD75 [2003/8/22] Vicent */
- if ( ( tempbx == Panel1024x768 ) || ( tempbx == Panel1280x1024 ) )
- {
- if ( pVBInfo->VBInfo & DriverMode )
- {
- tempax = XGINew_GetReg1( pVBInfo->P3d4 , 0x33 ) ;
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- tempax &= 0x0F ;
- else
- tempax = tempax >> 4 ;
-
- if ( ( resinfo == 6 ) || ( resinfo == 9 ) )
- {
- if ( tempax >= 3 )
- tempbx |= PanelRef75Hz ;
- }
- else if ( ( resinfo == 7 ) || ( resinfo == 8 ) )
- {
- if ( tempax >= 4 )
- tempbx |= PanelRef75Hz ;
- }
- }
- }
-
- pVBInfo->LCDResInfo = tempbx ;
-
- /* End of LCD75 */
-
- if( pVBInfo->IF_DEF_OEMUtil == 1 )
- {
- pVBInfo->LCDTypeInfo = ( temp & 0xf0 ) >> 4 ;
- }
-
- if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
- {
- return 0;
- }
-
- tempbx = 0 ;
-
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
-
- temp &= ( ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable ) ;
-
- if ( ( pVBInfo->IF_DEF_ScaleLCD == 1 ) && ( temp & LCDNonExpanding ) )
- temp &= ~EnableScalingLCD ;
-
- tempbx |= temp ;
-
- LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo) ;
-
- tempax = pVBInfo->LCDCapList[ LCDIdIndex ].LCD_Capability ;
-
- if ( pVBInfo->IF_DEF_LVDS == 0 ) /* shampoo */
- {
- if ( ( ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) && ( tempax & LCDDualLink ) )
- {
- tempbx |= SetLCDDualLink ;
- }
- }
-
- if ( pVBInfo->IF_DEF_CH7017 == 1 )
- {
- if ( tempax & LCDDualLink )
- {
- tempbx |= SetLCDDualLink ;
- }
- }
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( ( pVBInfo->LCDResInfo == Panel1400x1050 ) && ( pVBInfo->VBInfo & SetCRT2ToLCD ) && ( ModeNo > 0x13 ) && ( resinfo == 9 ) && ( !( tempbx & EnableScalingLCD ) ) )
- tempbx |= SetLCDtoNonExpanding ; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
- }
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
+ tempbx = temp & 0x0F;
+
+ if (tempbx == 0)
+ tempbx = Panel1024x768; /* default */
+
+ /* LCD75 [2003/8/22] Vicent */
+ if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
+ if (pVBInfo->VBInfo & DriverMode) {
+ tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33);
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempax &= 0x0F;
+ else
+ tempax = tempax >> 4;
+
+ if ((resinfo == 6) || (resinfo == 9)) {
+ if (tempax >= 3)
+ tempbx |= PanelRef75Hz;
+ } else if ((resinfo == 7) || (resinfo == 8)) {
+ if (tempax >= 4)
+ tempbx |= PanelRef75Hz;
+ }
+ }
+ }
-/*
- if ( tempax & LCDBToA )
- {
- tempbx |= SetLCDBToA ;
- }
-*/
+ pVBInfo->LCDResInfo = tempbx;
- if ( pVBInfo->IF_DEF_ExpLink == 1 )
- {
- if ( modeflag & HalfDCLK )
- {
- /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
- if ( !( tempbx & SetLCDtoNonExpanding ) )
- {
- tempbx |= EnableLVDSDDA ;
- }
- else
- {
- if ( ModeNo > 0x13 )
- {
- if ( pVBInfo->LCDResInfo == Panel1024x768 )
- {
- if ( resinfo == 4 )
- { /* 512x384 */
- tempbx |= EnableLVDSDDA ;
- }
- }
- }
- }
- }
- }
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( pVBInfo->VBInfo & SetNotSimuMode )
- {
- tempbx |= LCDVESATiming ;
- }
- }
- else
- {
- tempbx |= LCDVESATiming ;
- }
-
- pVBInfo->LCDInfo = tempbx ;
-
- if ( pVBInfo->IF_DEF_PWD == 1 )
- {
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- {
- if ( ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) )
- {
- if ( !( tempax & PWDEnable ) )
- {
- pVBInfo->LCDInfo &= ~SetPWDEnable ;
- }
- }
- }
- }
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( tempax & ( LockLCDBToA | StLCDBToA ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( !( tempax & LockLCDBToA ) )
- {
- if ( ModeNo <= 0x13 )
- {
- pVBInfo->VBInfo &= ~( SetSimuScanMode | SetInSlaveMode | SetCRT2ToLCD ) ;
- pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge ;
- }
- }
- }
- }
- }
+ /* End of LCD75 */
-/*
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( tempax & ( LockLCDBToA | StLCDBToA ) )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( !( ( !( tempax & LockLCDBToA ) ) && ( ModeNo > 0x13 ) ) )
- {
- pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
- pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
- }
- }
- }
- }
-*/
+ if (pVBInfo->IF_DEF_OEMUtil == 1)
+ pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
- return( 1 ) ;
-}
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ return 0;
+ tempbx = 0;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SearchModeID */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_SearchModeID(unsigned short ModeNo,
- unsigned short *ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
+ temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
+ if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
+ temp &= ~EnableScalingLCD;
-#ifdef LINUX /* chiawen for linux solution */
+ tempbx |= temp;
- if ( ModeNo <= 5 )
- ModeNo |= 1 ;
- if ( ModeNo <= 0x13 )
- {
- /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->SModeIDTable)/sizeof(struct XGI_StStruct);(*ModeIdIndex)++) */
- for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
- {
- if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
- break;
- if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
- return 0;
- }
-
- if ( ModeNo == 0x07 )
- ( *ModeIdIndex )++ ; /* 400 lines */
-
- if ( ModeNo <= 3 )
- ( *ModeIdIndex ) += 2 ; /* 400 lines */
- /* else 350 lines */
- }
- else
- {
- /* for (*ModeIdIndex=0;*ModeIdIndex<sizeof(pVBInfo->EModeIDTable)/sizeof(struct XGI_ExtStruct);(*ModeIdIndex)++) */
- for( *ModeIdIndex = 0 ; ; ( *ModeIdIndex )++ )
- {
- if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
- break;
- if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
- return 0;
- }
- }
+ LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
-#endif
+ tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
- return 1;
-}
+ if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
+ if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
+ & VB_XGI301C)) && (tempax & LCDDualLink)) {
+ tempbx |= SetLCDDualLink;
+ }
+ }
+ if (pVBInfo->IF_DEF_CH7017 == 1) {
+ if (tempax & LCDDualLink)
+ tempbx |= SetLCDDualLink;
+ }
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
+ & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
+ == 9) && (!(tempbx & EnableScalingLCD)))
+ tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
+ }
+ /*
+ if (tempax & LCDBToA) {
+ tempbx |= SetLCDBToA;
+ }
+ */
+
+ if (pVBInfo->IF_DEF_ExpLink == 1) {
+ if (modeflag & HalfDCLK) {
+ /* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */
+ if (!(tempbx & SetLCDtoNonExpanding)) {
+ tempbx |= EnableLVDSDDA;
+ } else {
+ if (ModeNo > 0x13) {
+ if (pVBInfo->LCDResInfo
+ == Panel1024x768) {
+ if (resinfo == 4) { /* 512x384 */
+ tempbx |= EnableLVDSDDA;
+ }
+ }
+ }
+ }
+ }
+ }
-/* win2000 MM adapter not support standard mode! */
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->VBInfo & SetNotSimuMode)
+ tempbx |= LCDVESATiming;
+ } else {
+ tempbx |= LCDVESATiming;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short memorysize ,
- modeflag ,
- temp ,
- temp1 ,
- tmp ;
-
-/* if ( ( HwDeviceExtension->jChipType == XGI_650 ) ||
- ( HwDeviceExtension->jChipType == XGI_650M ) )
- {
- return 1;
- } */
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
-
- /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
-
- memorysize = modeflag & MemoryInfoFlag ;
- memorysize = memorysize > MemorySizeShift ;
- memorysize++ ; /* Get memory size */
-
- temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x14 ) ; /* Get DRAM Size */
- tmp = temp ;
-
- if ( HwDeviceExtension->jChipType == XG40 )
- {
- temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
- if ( ( tmp & 0x0c ) == 0x0C ) /* Qual channels */
- {
- temp <<= 2 ;
- }
- else if ( ( tmp & 0x0c ) == 0x08 ) /* Dual channels */
- {
- temp <<= 1 ;
- }
- }
- else if ( HwDeviceExtension->jChipType == XG42 )
- {
- temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
- if ( ( tmp & 0x04 ) == 0x04 ) /* Dual channels */
- {
- temp <<= 1 ;
- }
- }
- else if ( HwDeviceExtension->jChipType == XG45 )
- {
- temp = 1 << ( ( temp & 0x0F0 ) >> 4 ) ; /* memory size per channel SR14[7:4] */
- if ( ( tmp & 0x0c ) == 0x0C ) /* Qual channels */
- {
- temp <<= 2 ;
- }
- else if ( ( tmp & 0x0c ) == 0x08 ) /* triple channels */
- {
- temp1 = temp ;
- temp <<= 1 ;
- temp += temp1 ;
- }
- else if ( ( tmp & 0x0c ) == 0x04 ) /* Dual channels */
- {
- temp <<= 1 ;
- }
- }
- if (temp < memorysize)
- return 0;
- else
- return 1;
-}
+ pVBInfo->LCDInfo = tempbx;
+ if (pVBInfo->IF_DEF_PWD == 1) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
+ & VB_XGI301C)) {
+ if (!(tempax & PWDEnable))
+ pVBInfo->LCDInfo &= ~SetPWDEnable;
+ }
+ }
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_IsLowResolution */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-/*void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short data ;
- unsigned short ModeFlag ;
-
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x0F ) ;
- data &= 0x7F ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0F , data ) ;
-
- if ( ModeNo > 0x13 )
- {
- ModeFlag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- if ( ( ModeFlag & HalfDCLK ) && ( ModeFlag & DoubleScanMode ) )
- {
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x0F ) ;
- data |= 0x80 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x0F , data ) ;
- data = XGINew_GetReg1( pVBInfo->P3c4 , 0x01 ) ;
- data &= 0xF7 ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , data ) ;
- }
- }
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (tempax & (LockLCDBToA | StLCDBToA)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(tempax & LockLCDBToA)) {
+ if (ModeNo <= 0x13) {
+ pVBInfo->VBInfo
+ &= ~(SetSimuScanMode
+ | SetInSlaveMode
+ | SetCRT2ToLCD);
+ pVBInfo->VBInfo
+ |= SetCRT2ToLCDA
+ | SetCRT2ToDualEdge;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (tempax & (LockLCDBToA | StLCDBToA)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) {
+ pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
+ pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
+ }
+ }
+ }
+ }
+ */
+
+ return 1;
}
-*/
+unsigned char XGI_SearchModeID(unsigned short ModeNo,
+ unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ if (ModeNo <= 5)
+ ModeNo |= 1;
+ if (ModeNo <= 0x13) {
+ /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */
+ for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
+ if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
+ break;
+ if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+ return 0;
+ }
+
+ if (ModeNo == 0x07)
+ (*ModeIdIndex)++; /* 400 lines */
+ if (ModeNo <= 3)
+ (*ModeIdIndex) += 2; /* 400 lines */
+ /* else 350 lines */
+ } else {
+ /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */
+ for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
+ if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+ break;
+ if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+ return 0;
+ }
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisplayOn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo)
-{
-
- XGINew_SetRegANDOR(pVBInfo->P3c4,0x01,0xDF,0x00);
- if ( pXGIHWDE->jChipType == XG21 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- if (!(XGI_XG21GetPSCValue( pVBInfo )&0x1))
- {
- XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
- XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
- }
- if (!(XGI_XG21GetPSCValue( pVBInfo )&0x20))
- {
- XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
- }
- XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
- XGI_XG21BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
- }
- else
- {
- XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
- }
-
- }
-
- if (pVBInfo->IF_DEF_CH7007 == 1) /* [Billy] 07/05/23 For CH7007 */
- {
-
- }
-
-
- if ( pXGIHWDE->jChipType == XG27 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- if (!(XGI_XG27GetPSCValue( pVBInfo )&0x1))
- {
- XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
- XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
- }
- if (!(XGI_XG27GetPSCValue( pVBInfo )&0x20))
- {
- XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
- }
- XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
- XGI_XG27BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
- }
- else
- {
- XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
- }
-
- }
+ return 1;
}
+/* win2000 MM adapter not support standard mode! */
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisplayOff */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo)
+#if 0
+static unsigned char XGINew_CheckMemorySize(
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
{
+ unsigned short memorysize, modeflag, temp, temp1, tmp;
+
+ /*
+ if ((HwDeviceExtension->jChipType == XGI_650) ||
+ (HwDeviceExtension->jChipType == XGI_650M)) {
+ return 1;
+ }
+ */
+
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ /* ModeType = modeflag&ModeInfoFlag; // Get mode type */
+
+ memorysize = modeflag & MemoryInfoFlag;
+ memorysize = memorysize > MemorySizeShift;
+ memorysize++; /* Get memory size */
+
+ temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */
+ tmp = temp;
+
+ if (HwDeviceExtension->jChipType == XG40) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+ temp <<= 2;
+ } else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
+ temp <<= 1;
+ }
+ } else if (HwDeviceExtension->jChipType == XG42) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x04) == 0x04) { /* Dual channels */
+ temp <<= 1;
+ }
+ } else if (HwDeviceExtension->jChipType == XG45) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+ temp <<= 2;
+ } else if ((tmp & 0x0c) == 0x08) { /* triple channels */
+ temp1 = temp;
+ temp <<= 1;
+ temp += temp1;
+ } else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
+ temp <<= 1;
+ }
+ }
+ if (temp < memorysize)
+ return 0;
+ else
+ return 1;
+}
+#endif
+
+/*
+void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ unsigned short data ;
+ unsigned short ModeFlag ;
+
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
+ data &= 0x7F;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
+
+ if (ModeNo > 0x13) {
+ ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F);
+ data |= 0x80;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data);
+ data = XGINew_GetReg1(pVBInfo->P3c4, 0x01);
+ data &= 0xF7;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x01, data);
+ }
+ }
+}
+*/
- if ( pXGIHWDE->jChipType == XG21 )
- {
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- XGI_XG21BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
- XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
- }
- else
- {
- XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
- }
- }
+void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE,
+ struct vb_device_info *pVBInfo)
+{
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
+ if (pXGIHWDE->jChipType == XG21) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
+ XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+ XGI_XG21SetPanelDelay(2, pVBInfo);
+ }
+ if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
+ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+ XGI_XG21SetPanelDelay(3, pVBInfo);
+ XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+ } else {
+ XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+ }
- if (pVBInfo->IF_DEF_CH7007 == 1) /*[Billy] 07/05/23 For CH7007 */
- {
- /* if( IsCH7007TVMode( pVBInfo ) == 0 ) */
- {
- }
- }
+ }
+ if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
- if ( pXGIHWDE->jChipType == XG27 )
- {
- if ((XGI_XG27GetPSCValue( pVBInfo )&0x2))
- {
- XGI_XG27BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
- XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
- }
+ }
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
- }
- }
+ if (pXGIHWDE->jChipType == XG27) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
+ XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+ XGI_XG21SetPanelDelay(2, pVBInfo);
+ }
+ if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
+ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+ XGI_XG21SetPanelDelay(3, pVBInfo);
+ XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+ } else {
+ XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+ }
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x01 , 0xDF , 0x20 ) ;
+ }
}
+void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE,
+ struct vb_device_info *pVBInfo)
+{
+
+ if (pXGIHWDE->jChipType == XG21) {
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+ XGI_XG21SetPanelDelay(3, pVBInfo);
+ } else {
+ XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+ }
+ }
+
+ if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
+ /* if (IsCH7007TVMode(pVBInfo) == 0) */
+ {
+ }
+ }
+
+ if (pXGIHWDE->jChipType == XG27) {
+ if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
+ XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+ XGI_XG21SetPanelDelay(3, pVBInfo);
+ }
+
+ if (pVBInfo->IF_DEF_LVDS == 0)
+ XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_WaitDisply */
-/* Input : */
-/* Output : */
-/* Description : chiawen for sensecrt1 */
-/* --------------------------------------------------------------------- */
void XGI_WaitDisply(struct vb_device_info *pVBInfo)
{
- while( ( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) )
- break ;
+ while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01))
+ break;
- while( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) )
- break ;
+ while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01))
+ break;
}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SenseCRT1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-
void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
{
- unsigned char CRTCData[17] = {
- 0x5F , 0x4F , 0x50 , 0x82 , 0x55 , 0x81 ,
- 0x0B , 0x3E , 0xE9 , 0x0B , 0xDF , 0xE7 ,
- 0x04 , 0x00 , 0x00 , 0x05 , 0x00 };
+ unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
+ 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
+ 0x05, 0x00 };
unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
unsigned char CR17, CR63, SR31;
- unsigned short temp ;
- unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F } ;
+ unsigned short temp;
+ unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
- int i ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x05 , 0x86 ) ;
+ int i;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
- /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
- XGINew_SetReg1( pVBInfo->P3d4 , 0x57 , 0x4A ) ;
- XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char)(XGINew_GetReg1(pVBInfo->P3d4, 0x53) | 0x02));
+ /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
+ pVBInfo->P3d4, 0x53) | 0x02));
- SR31 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x31);
- CR63 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x63);
- SR01 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x01);
+ SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31);
+ CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63);
+ SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01);
- XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char)(SR01 & 0xDF));
- XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char)(CR63 & 0xBF));
+ XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
+ XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
- CR17 = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x17);
- XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char)(CR17 | 0x80)) ;
+ CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
- SR1F = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
- XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char)(SR1F | 0x04));
+ SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
- SR07 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x07);
- XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char)(SR07 & 0xFB));
- SR06 = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x06);
- XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char)(SR06 & 0xC3));
+ SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
+ SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , 0x00 ) ;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00);
- for( i = 0 ; i < 8 ; i++ )
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)i, CRTCData[i]);
+ for (i = 0; i < 8; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
- for( i = 8 ; i < 11 ; i++ )
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 8), CRTCData[i]);
+ for (i = 8; i < 11; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8),
+ CRTCData[i]);
- for( i = 11 ; i < 13 ; i++ )
- XGINew_SetReg1(pVBInfo->P3d4, (unsigned short)(i + 4), CRTCData[i]);
+ for (i = 11; i < 13; i++)
+ XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4),
+ CRTCData[i]);
- for( i = 13 ; i < 16 ; i++ )
- XGINew_SetReg1(pVBInfo->P3c4, (unsigned short)(i - 3), CRTCData[i]);
+ for (i = 13; i < 16; i++)
+ XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3),
+ CRTCData[i]);
- XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char)(CRTCData[16] & 0xE0));
+ XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
+ & 0xE0));
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , 0x1B ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , 0xE1 ) ;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1);
- XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
+ XGINew_SetReg3(pVBInfo->P3c8, 0x00);
- for( i = 0 ; i < 256 ; i++ )
- {
- XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[0]);
- XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[1]);
- XGINew_SetReg3((pVBInfo->P3c8 + 1), (unsigned char)DAC_TEST_PARMS[2]);
- }
+ for (i = 0; i < 256; i++) {
+ XGINew_SetReg3((pVBInfo->P3c8 + 1),
+ (unsigned char) DAC_TEST_PARMS[0]);
+ XGINew_SetReg3((pVBInfo->P3c8 + 1),
+ (unsigned char) DAC_TEST_PARMS[1]);
+ XGINew_SetReg3((pVBInfo->P3c8 + 1),
+ (unsigned char) DAC_TEST_PARMS[2]);
+ }
- XGI_VBLongWait( pVBInfo ) ;
- XGI_VBLongWait( pVBInfo ) ;
- XGI_VBLongWait( pVBInfo ) ;
+ XGI_VBLongWait(pVBInfo);
+ XGI_VBLongWait(pVBInfo);
+ XGI_VBLongWait(pVBInfo);
- XGINew_LCD_Wait_Time( 0x01 , pVBInfo ) ;
+ XGINew_LCD_Wait_Time(0x01, pVBInfo);
- XGI_WaitDisply( pVBInfo ) ;
- temp = XGINew_GetReg2( pVBInfo->P3c2 ) ;
+ XGI_WaitDisply(pVBInfo);
+ temp = XGINew_GetReg2(pVBInfo->P3c2);
- if( temp & 0x10 )
- {
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xDF , 0x20 ) ;
- }
- else
- {
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x32 , 0xDF , 0x00 ) ;
- }
+ if (temp & 0x10)
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
+ else
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
- /* alan, avoid display something, set BLACK DAC if not restore DAC */
- XGINew_SetReg3( pVBInfo->P3c8 , 0x00 ) ;
+ /* alan, avoid display something, set BLACK DAC if not restore DAC */
+ XGINew_SetReg3(pVBInfo->P3c8, 0x00);
- for( i = 0 ; i < 256 ; i++ )
- {
- XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
- XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
- XGINew_SetReg3( ( pVBInfo->P3c8 + 1 ) , 0 ) ;
- }
+ for (i = 0; i < 256; i++) {
+ XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
+ XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
+ XGINew_SetReg3((pVBInfo->P3c8 + 1), 0);
+ }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x01 , SR01 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x63 , CR63 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x31 , SR31 ) ;
+ XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31);
- /* [2004/05/11] Vicent */
- XGINew_SetReg1(pVBInfo->P3d4, 0x53,
- (unsigned char)(XGINew_GetReg1(pVBInfo->P3d4, 0x53) & 0xFD));
- XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char)SR1F);
+ /* [2004/05/11] Vicent */
+ XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1(
+ pVBInfo->P3d4, 0x53) & 0xFD));
+ XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
}
+#if 0
+static void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
+{
+ while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01));
+ while (XGINew_GetReg2(pVBInfo->P3da) & 0x01);
+}
+#endif
+unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex;
+
+ tempbx = pVBInfo->VBInfo;
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
+ pVBInfo->SelectCRT2Rate = 4;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
+ ModeIdIndex, pVBInfo);
+ XGI_SaveCRT2Info(ModeNo, pVBInfo);
+ XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetTap4Regs(pVBInfo);
+ XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_AutoThreshold(pVBInfo);
+ return 1;
+}
+void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
+{
+ if (!(pVBInfo->SetFlag & Win9xDOSMode))
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40);
+}
+void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
+{
+ unsigned short temp1, temp2;
+
+ XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
+ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1);
+}
+
+void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short xres, yres, modeflag, resindex;
+
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
+ } else {
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+
+ /*
+ if (pVBInfo->IF_DEF_FSTN) {
+ xres *= 2;
+ yres *= 2;
+ } else {
+ */
+ if (modeflag & HalfDCLK)
+ xres *= 2;
+
+ if (modeflag & DoubleScanMode)
+ yres *= 2;
+ /* } */
+ }
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ if (pVBInfo->LCDResInfo == Panel1600x1200) {
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (yres == 1024)
+ yres = 1056;
+ }
+ }
+
+ if (pVBInfo->LCDResInfo == Panel1280x1024) {
+ if (yres == 400)
+ yres = 405;
+ else if (yres == 350)
+ yres = 360;
+
+ if (pVBInfo->LCDInfo & LCDVESATiming) {
+ if (yres == 360)
+ yres = 375;
+ }
+ }
+
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (!(pVBInfo->LCDInfo
+ & LCDNonExpanding)) {
+ if (yres == 350)
+ yres = 357;
+ else if (yres == 400)
+ yres = 420;
+ else if (yres == 480)
+ yres = 525;
+ }
+ }
+ }
+ }
+
+ if (xres == 720)
+ xres = 640;
+ }
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
+unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
+{
+ if ((((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA))
+ && (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
+ return 1;
+ return 0;
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_WaitDisplay */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
+void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
- while( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) ) ;
+ unsigned short tempax = 0, tempbx, modeflag, resinfo;
- while( XGINew_GetReg2( pVBInfo->P3da ) & 0x01 ) ;
-}
+ struct XGI_LCDDataStruct *LCDPtr = NULL;
+ struct XGI_TVDataStruct *TVPtr = NULL;
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+ pVBInfo->NewFlickerMode = 0;
+ pVBInfo->RVBHRS = 50;
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+ return;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2Group301 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx ,
- ModeIdIndex ,
- RefreshRateTableIndex ;
-
- tempbx=pVBInfo->VBInfo ;
- pVBInfo->SetFlag |= ProgrammingCRT2 ;
- XGI_SearchModeID( ModeNo , &ModeIdIndex, pVBInfo ) ;
- pVBInfo->SelectCRT2Rate = 4 ;
- RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_SaveCRT2Info( ModeNo, pVBInfo ) ;
- XGI_GetCRT2ResInfo( ModeNo , ModeIdIndex, pVBInfo) ;
- XGI_GetCRT2Data( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- XGI_PreSetGroup1( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetGroup1( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetLockRegs( ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetGroup2( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_SetLCDRegs(ModeNo , ModeIdIndex , HwDeviceExtension , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetTap4Regs(pVBInfo) ;
- XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
- XGI_SetGroup4( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT2VCLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
- XGI_SetGroup5( ModeNo , ModeIdIndex, pVBInfo) ;
- XGI_AutoThreshold( pVBInfo) ;
- return 1 ;
-}
+ tempbx = 4;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx,
+ ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+
+ pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ tempax = 1024;
+ tempbx = 768;
+
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 357)
+ tempbx = 527;
+ else if (pVBInfo->VGAVDE == 420)
+ tempbx = 620;
+ else if (pVBInfo->VGAVDE == 525)
+ tempbx = 775;
+ else if (pVBInfo->VGAVDE == 600)
+ tempbx = 775;
+ /* else if (pVBInfo->VGAVDE==350) tempbx=560; */
+ /* else if (pVBInfo->VGAVDE==400) tempbx=640; */
+ else
+ tempbx = 768;
+ } else
+ tempbx = 768;
+ } else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
+ tempax = 1024;
+ tempbx = 768;
+ } else if (pVBInfo->LCDResInfo == Panel1280x1024) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 768;
+ else if (pVBInfo->VGAVDE == 375)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 405)
+ tempbx = 864;
+ else
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
+ tempax = 1280;
+ tempbx = 1024;
+ } else if (pVBInfo->LCDResInfo == Panel1280x960) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 700;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 1024)
+ tempbx = 960;
+ else
+ tempbx = 960;
+ } else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+ tempax = 1400;
+ tempbx = 1050;
+
+ if (pVBInfo->VGAVDE == 1024) {
+ tempax = 1280;
+ tempbx = 1024;
+ }
+ } else if (pVBInfo->LCDResInfo == Panel1600x1200) {
+ tempax = 1600;
+ tempbx = 1200; /* alan 10/14/2003 */
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 875;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 1000;
+ }
+ }
+
+ if (pVBInfo->LCDInfo & LCDNonExpanding) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->VGAVDE;
+ }
+
+ pVBInfo->HDE = tempax;
+ pVBInfo->VDE = tempbx;
+ return;
+ }
+ if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
+ tempbx = 4;
+ TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx,
+ ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+
+ pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
+ pVBInfo->VGAHT = TVPtr->VGAHT;
+ pVBInfo->VGAVT = TVPtr->VGAVT;
+ pVBInfo->HDE = TVPtr->TVHDE;
+ pVBInfo->VDE = TVPtr->TVVDE;
+ pVBInfo->RVBHRS = TVPtr->RVBHRS;
+ pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (resinfo == 0x08)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x09)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x12)
+ pVBInfo->NewFlickerMode = 0x40;
+
+ if (pVBInfo->VGAVDE == 350)
+ pVBInfo->TVInfo |= TVSimuMode;
+
+ tempax = ExtHiTVHT;
+ tempbx = ExtHiTVVT;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ tempax = StHiTVHT;
+ tempbx = StHiTVVT;
+
+ if (!(modeflag & Charx8Dot)) {
+ tempax = StHiTextTVHT;
+ tempbx = StHiTextTVVT;
+ }
+ }
+ }
+ } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+ tempax = YPbPrTV750pHT; /* Ext750pTVHT */
+ tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
+ }
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ tempax = YPbPrTV525pHT; /* Ext525pTVHT */
+ tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
+ } else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+ tempax = YPbPrTV525iHT; /* Ext525iTVHT */
+ tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ } else {
+ tempax = PALHT;
+ tempbx = PALVT;
+ if (!(pVBInfo->TVInfo & SetPALTV)) {
+ tempax = NTSCHT;
+ tempbx = NTSCVT;
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ }
+
+ pVBInfo->HT = tempax;
+ pVBInfo->VT = tempbx;
+ return;
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_AutoThreshold */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
+void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
- if ( !( pVBInfo->SetFlag & Win9xDOSMode ) )
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x01 , 0x40 ) ;
-}
+ unsigned char di_0, di_1, tempal;
+
+ tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
+ pVBInfo);
+ XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
+ XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
+
+ if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */
+ /* 301 */
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
+ } else { /* 301b/302b/301lv/302lv */
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1);
+ }
+
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12);
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28);
+ else
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08);
+}
/* --------------------------------------------------------------------- */
-/* Function : XGI_SaveCRT2Info */
+/* Function : XGI_GETLCDVCLKPtr */
/* Input : */
-/* Output : */
+/* Output : al -> VCLK Index */
/* Description : */
/* --------------------------------------------------------------------- */
-void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
+void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short index;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (pVBInfo->IF_DEF_ScaleLCD == 1) {
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ return;
+ }
+
+ /* index = XGI_GetLCDCapPtr(pVBInfo); */
+ index = XGI_GetLCDCapPtr1(pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
+ *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
+ *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
+ } else { /* LCDA */
+ *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
+ *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
+ }
+ }
+ return;
+}
+
+unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
+ unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned short temp1 ,
- temp2 ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x34 , ModeNo ) ; /* reserve CR34 for CRT1 Mode No */
- temp1 = ( pVBInfo->VBInfo&SetInSlaveMode ) >> 8 ;
- temp2 = ~( SetInSlaveMode >> 8 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x31 , temp2 , temp1 ) ;
-}
+ unsigned short index, modeflag;
+ unsigned short tempbx;
+ unsigned char tempal;
+ unsigned char *CHTVVCLKPtr = NULL;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+
+ if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo
+ & EnableScalingLCD))) { /* {LCDA/LCDB} */
+ index = XGI_GetLCDCapPtr(pVBInfo);
+ tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ return tempal;
+
+ /* {TV} */
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempal = HiTVVCLKDIV2;
+ if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+ tempal = HiTVVCLK;
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ tempal = HiTVSimuVCLK;
+ if (!(modeflag & Charx8Dot))
+ tempal = HiTVTextVCLK;
+
+ }
+ return tempal;
+ }
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+ tempal = YPbPr750pVCLK;
+ return tempal;
+ }
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ tempal = YPbPr525pVCLK;
+ return tempal;
+ }
+
+ tempal = NTSC1024VCLK;
+
+ if (!(pVBInfo->TVInfo & NTSC1024x768)) {
+ tempal = TVVCLKDIV2;
+ if (!(pVBInfo->TVInfo & RPLLDIV2XO))
+ tempal = TVVCLK;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ return tempal;
+ }
+ /* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) {
+ if (ModeNo<=0x13)
+ *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ *tempal = *tempal & 0x1F;
+ tempbx = 0;
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempbx = tempbx + 2;
+ if (pVBInfo->TVInfo & SetCHTVOverScan)
+ tempbx++;
+ tempbx = tempbx << 1;
+ } */
+ } /* {End of VB} */
+
+ if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
+ /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
+ if ((pVBInfo->VBInfo & SetCRT2ToTV)) {
+ if (ModeNo <= 0x13) {
+ tempal
+ = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ tempal
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempal = tempal & 0x0F;
+ tempbx = 0;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempbx = tempbx + 2;
+
+ if (pVBInfo->TVInfo & SetCHTVOverScan)
+ tempbx++;
+
+ /** tempbx = tempbx << 1; CH7007 ? **/
+
+ /* [Billy]07/05/29 CH7007 */
+ if (pVBInfo->IF_DEF_CH7007 == 1) {
+ switch (tempbx) {
+ case 0:
+ CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC;
+ break;
+ case 1:
+ CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC;
+ break;
+ case 2:
+ CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL;
+ break;
+ case 3:
+ CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL;
+ break;
+ default:
+ break;
+
+ }
+ }
+ /* else {
+ switch(tempbx) {
+ case 0:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
+ break;
+ case 1:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
+ break;
+ case 2:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
+ break;
+ case 3:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
+ break;
+ default:
+ break;
+ }
+ }
+ */
+
+ tempal = CHTVVCLKPtr[tempal];
+ return tempal;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetCRT2ResInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetCRT2ResInfo(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short xres ,
- yres ,
- modeflag ,
- resindex ;
-
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo) ;
- if ( ModeNo <= 0x13 )
- {
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- yres = pVBInfo->StResInfo[ resindex ].VTotal ;
- /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
- }
- else
- {
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
-
-/* if ( pVBInfo->IF_DEF_FSTN )
- {
- xres *= 2 ;
- yres *= 2 ;
- }
- else
- {
-*/
- if ( modeflag & HalfDCLK )
- xres *= 2;
-
- if ( modeflag & DoubleScanMode )
- yres *= 2 ;
-/* } */
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- {
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- if ( pVBInfo->LCDResInfo == Panel1600x1200 )
- {
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( yres == 1024 )
- yres = 1056 ;
- }
- }
-
- if ( pVBInfo->LCDResInfo == Panel1280x1024 )
- {
- if ( yres == 400 )
- yres = 405 ;
- else if ( yres == 350 )
- yres = 360 ;
-
- if ( pVBInfo->LCDInfo & LCDVESATiming )
- {
- if ( yres == 360 )
- yres = 375 ;
- }
- }
-
- if ( pVBInfo->LCDResInfo == Panel1024x768 )
- {
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( !( pVBInfo->LCDInfo & LCDNonExpanding ) )
- {
- if ( yres == 350 )
- yres = 357 ;
- else if ( yres == 400 )
- yres = 420 ;
- else if ( yres == 480 )
- yres = 525 ;
- }
- }
- }
- }
-
- if ( xres == 720 )
- xres = 640 ;
- }
-
- pVBInfo->VGAHDE = xres ;
- pVBInfo->HDE = xres ;
- pVBInfo->VGAVDE = yres ;
- pVBInfo->VDE = yres ;
+ }
+
+ tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02));
+ tempal = tempal >> 2;
+ tempal &= 0x03;
+
+ if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */
+ tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
+
+ if (ModeNo <= 0x13)
+ return tempal;
+
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ return tempal;
}
+void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
+ unsigned char *di_1, struct vb_device_info *pVBInfo)
+{
+ if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */
+ /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
+ *di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B;
+ *di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C;
+ } else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag
+ & ProgrammingCRT2)) {
+ *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
+ *di_1 = XGI_VBVCLKData[tempal].SR2C;
+ }
+ } else {
+ *di_0 = XGI_VCLKData[tempal].SR2B;
+ *di_1 = XGI_VCLKData[tempal].SR2C;
+ }
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_IsLCDDualLink */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
+static void XGI_SetCRT2Offset(unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
+ unsigned short offset;
+ unsigned char temp;
- if ( ( ( ( pVBInfo->VBInfo & SetCRT2ToLCD ) | SetCRT2ToLCDA ) ) && ( pVBInfo->LCDInfo & SetLCDDualLink ) ) /* shampoo0129 */
- return ( 1 ) ;
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ return;
- return( 0 ) ;
+ offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ temp = (unsigned char) (offset & 0xFF);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp);
+ temp = (unsigned char) ((offset & 0xFF00) >> 8);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp);
+ temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
}
+unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short temp, colordepth, modeinfo, index, infoflag,
+ ColorDepth[] = { 0x01, 0x02, 0x04 };
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetCRT2Data */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax = 0,
- tempbx ,
- modeflag ,
- resinfo ;
-
- struct XGI_LCDDataStruct *LCDPtr = NULL ;
- struct XGI_TVDataStruct *TVPtr = NULL ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- }
-
- pVBInfo->NewFlickerMode = 0 ;
- pVBInfo->RVBHRS = 50 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- {
- XGI_GetRAMDAC2DATA( ModeNo , ModeIdIndex , RefreshRateTableIndex,pVBInfo ) ;
- return ;
- }
-
- tempbx = 4 ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- LCDPtr = (struct XGI_LCDDataStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-
- pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX ;
- pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT ;
- pVBInfo->VGAHT = LCDPtr->VGAHT ;
- pVBInfo->VGAVT = LCDPtr->VGAVT ;
- pVBInfo->HT = LCDPtr->LCDHT ;
- pVBInfo->VT = LCDPtr->LCDVT ;
-
- if ( pVBInfo->LCDResInfo == Panel1024x768 )
- {
- tempax = 1024 ;
- tempbx = 768 ;
-
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( pVBInfo->VGAVDE == 357 )
- tempbx = 527 ;
- else if ( pVBInfo->VGAVDE == 420 )
- tempbx = 620 ;
- else if ( pVBInfo->VGAVDE == 525 )
- tempbx = 775 ;
- else if ( pVBInfo->VGAVDE == 600 )
- tempbx = 775 ;
- /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
- /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
- else
- tempbx = 768 ;
- }
- else
- tempbx = 768 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1024x768x75 )
- {
- tempax = 1024 ;
- tempbx = 768 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1280x1024 )
- {
- tempax = 1280 ;
- if ( pVBInfo->VGAVDE == 360 )
- tempbx = 768 ;
- else if ( pVBInfo->VGAVDE == 375 )
- tempbx = 800 ;
- else if ( pVBInfo->VGAVDE == 405 )
- tempbx = 864 ;
- else
- tempbx = 1024 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1280x1024x75 )
- {
- tempax = 1280 ;
- tempbx = 1024 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1280x960 )
- {
- tempax = 1280 ;
- if ( pVBInfo->VGAVDE == 350 )
- tempbx = 700 ;
- else if ( pVBInfo->VGAVDE == 400 )
- tempbx = 800 ;
- else if ( pVBInfo->VGAVDE == 1024 )
- tempbx = 960 ;
- else
- tempbx = 960 ;
- }
- else if ( pVBInfo->LCDResInfo == Panel1400x1050 )
- {
- tempax = 1400 ;
- tempbx = 1050 ;
-
- if ( pVBInfo->VGAVDE == 1024 )
- {
- tempax = 1280 ;
- tempbx = 1024 ;
- }
- }
- else if ( pVBInfo->LCDResInfo == Panel1600x1200 )
- {
- tempax = 1600 ;
- tempbx = 1200 ; /* alan 10/14/2003 */
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( pVBInfo->VGAVDE == 350 )
- tempbx = 875 ;
- else if ( pVBInfo->VGAVDE == 400 )
- tempbx = 1000 ;
- }
- }
-
- if ( pVBInfo->LCDInfo & LCDNonExpanding )
- {
- tempax = pVBInfo->VGAHDE ;
- tempbx = pVBInfo->VGAVDE ;
- }
-
- pVBInfo->HDE = tempax ;
- pVBInfo->VDE = tempbx ;
- return ;
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV ) )
- {
- tempbx = 4 ;
- TVPtr = (struct XGI_TVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-
- pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX ;
- pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT ;
- pVBInfo->VGAHT = TVPtr->VGAHT ;
- pVBInfo->VGAVT = TVPtr->VGAVT ;
- pVBInfo->HDE = TVPtr->TVHDE ;
- pVBInfo->VDE = TVPtr->TVVDE ;
- pVBInfo->RVBHRS = TVPtr->RVBHRS ;
- pVBInfo->NewFlickerMode = TVPtr->FlickerMode ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( resinfo == 0x08 )
- pVBInfo->NewFlickerMode = 0x40 ;
- else if ( resinfo == 0x09 )
- pVBInfo->NewFlickerMode = 0x40 ;
- else if ( resinfo == 0x12 )
- pVBInfo->NewFlickerMode = 0x40 ;
-
- if ( pVBInfo->VGAVDE == 350 )
- pVBInfo->TVInfo |= TVSimuMode ;
-
- tempax = ExtHiTVHT ;
- tempbx = ExtHiTVVT ;
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( pVBInfo->TVInfo & TVSimuMode )
- {
- tempax = StHiTVHT ;
- tempbx = StHiTVVT ;
-
- if ( !( modeflag & Charx8Dot ) )
- {
- tempax = StHiTextTVHT ;
- tempbx = StHiTextTVVT ;
- }
- }
- }
- }
- else if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- {
- tempax = YPbPrTV750pHT ; /* Ext750pTVHT */
- tempbx = YPbPrTV750pVT ; /* Ext750pTVVT */
- }
-
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- {
- tempax = YPbPrTV525pHT ; /* Ext525pTVHT */
- tempbx = YPbPrTV525pVT ; /* Ext525pTVVT */
- }
- else if ( pVBInfo->TVInfo & SetYPbPrMode525i )
- {
- tempax = YPbPrTV525iHT ; /* Ext525iTVHT */
- tempbx = YPbPrTV525iVT ; /* Ext525iTVVT */
- if ( pVBInfo->TVInfo & NTSC1024x768 )
- tempax = NTSC1024x768HT ;
- }
- }
- else
- {
- tempax = PALHT ;
- tempbx = PALVT ;
- if ( !( pVBInfo->TVInfo & SetPALTV ) )
- {
- tempax = NTSCHT ;
- tempbx = NTSCVT ;
- if ( pVBInfo->TVInfo & NTSC1024x768 )
- tempax = NTSC1024x768HT ;
- }
- }
-
- pVBInfo->HT = tempax ;
- pVBInfo->VT = tempbx ;
- return ;
- }
+ modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ if (ModeNo <= 0x14)
+ infoflag = 0;
+ else
+ infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ index = (modeinfo >> 8) & 0xFF;
+
+ temp = pVBInfo->ScreenOffset[index];
+
+ if (infoflag & InterlaceMode)
+ temp = temp << 1;
+
+ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
+
+ if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
+ temp = ModeNo - 0x7C;
+ colordepth = ColorDepth[temp];
+ temp = 0x6B;
+ if (infoflag & InterlaceMode)
+ temp = temp << 1;
+ return temp * colordepth;
+ } else {
+ return temp * colordepth;
+ }
}
+static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
+{
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2VCLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
+void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned char di_0, di_1, tempal;
+ unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
- tempal = XGI_GetVCLKPtr( RefreshRateTableIndex , ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_GetVCLKLen( tempal, &di_0 , &di_1, pVBInfo ) ;
- XGI_GetLCDVCLKPtr( &di_0 , &di_1, pVBInfo ) ;
+ if (ModeNo > 0x13) {
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
- if ( pVBInfo->VBType & VB_XGI301 ) /* shampoo 0129 */
- { /* 301 */
- XGINew_SetReg1(pVBInfo->Part4Port , 0x0A , 0x10 ) ;
- XGINew_SetReg1(pVBInfo->Part4Port , 0x0B , di_1 ) ;
- XGINew_SetReg1(pVBInfo->Part4Port , 0x0A , di_0 ) ;
- }
- else
- { /* 301b/302b/301lv/302lv */
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0A , di_0 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0B , di_1 ) ;
- }
+ XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2FIFO(pVBInfo);
+ /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
- XGINew_SetReg1( pVBInfo->Part4Port , 0x00 , 0x12 ) ;
+ for (tempcx = 4; tempcx < 7; tempcx++)
+ XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0);
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x12 , 0x28 ) ;
- else
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x12 , 0x08 ) ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GETLCDVCLKPtr */
-/* Input : */
-/* Output : al -> VCLK Index */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
- struct vb_device_info *pVBInfo)
+void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned short index ;
+ unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
+ pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- if ( pVBInfo->IF_DEF_ScaleLCD == 1 )
- {
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- return ;
- }
+ if (ModeNo > 0x13) {
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
- /* index = XGI_GetLCDCapPtr(pVBInfo) ; */
- index = XGI_GetLCDCapPtr1( pVBInfo) ;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ /* bainy change table name */
+ if (modeflag & HalfDCLK) {
+ temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+ temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
+ pushbx = pVBInfo->VGAHDE / 2 + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+ tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
+ & 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ tempcx &= 0x1F;
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ }
+
+ tempbx += 4;
+ tempcx += 4;
+
+ if (tempcx > (pVBInfo->VGAHT / 2))
+ tempcx = pVBInfo->VGAHT / 2;
+
+ temp = tempbx & 0x00FF;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+ } else {
+ temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
+ temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
+ pushbx = pVBInfo->VGAHDE + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
+ tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]
+ & 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+ tempcx &= 0x1F;
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempbx += 16;
+ tempcx += 16;
+ }
+
+ if (tempcx > pVBInfo->VGAHT)
+ tempcx = pVBInfo->VGAHT;
+
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
+ }
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- { /* LCDB */
- *di_0 = pVBInfo->LCDCapList[ index ].LCUCHAR_VCLKData1 ;
- *di_1 = pVBInfo->LCDCapList[ index ].LCUCHAR_VCLKData2 ;
- }
- else
- { /* LCDA */
- *di_0 = pVBInfo->LCDCapList[ index ].LCDA_VCLKData1 ;
- *di_1 = pVBInfo->LCDCapList[ index ].LCDA_VCLKData2 ;
- }
- }
- return ;
-}
+ tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
+ tempbx = pushbx;
+ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+ tempax |= (tempbx & 0xFF00);
+ temp = (tempax & 0xFF00) >> 8;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp);
+ tempcx = (pVBInfo->VGAVT - 1);
+ temp = tempcx & 0x00FF;
+
+ if (pVBInfo->IF_DEF_CH7005 == 1) {
+ if (pVBInfo->VBInfo & 0x0C)
+ temp--;
+ }
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
+ tempbx = pVBInfo->VGAVDE - 1;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp);
+ temp = ((tempbx & 0xFF00) << 3) >> 8;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp);
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVCLKPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
- unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
-
- unsigned short index ,
- modeflag ;
- unsigned short tempbx ;
- unsigned char tempal;
- unsigned char *CHTVVCLKPtr = NULL;
-
- if ( ModeNo <= 0x13 )
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- else
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
-
-
- if ( ( pVBInfo->SetFlag & ProgrammingCRT2 ) && ( !( pVBInfo->LCDInfo & EnableScalingLCD ) ) )
- { /* {LCDA/LCDB} */
- index = XGI_GetLCDCapPtr(pVBInfo) ;
- tempal = pVBInfo->LCDCapList[ index ].LCD_VCLK ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- return tempal ;
-
- /* {TV} */
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV| VB_XGI302LV| VB_XGI301C ) )
- {
- if(pVBInfo->VBInfo&SetCRT2ToHiVisionTV)
- {
- tempal = HiTVVCLKDIV2;
- if(!(pVBInfo->TVInfo & RPLLDIV2XO))
- tempal = HiTVVCLK;
- if(pVBInfo->TVInfo & TVSimuMode)
- {
- tempal = HiTVSimuVCLK;
- if(!(modeflag & Charx8Dot))
- tempal = HiTVTextVCLK;
-
- }
- return tempal;
- }
-
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- {
- tempal = YPbPr750pVCLK ;
- return tempal ;
- }
-
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- {
- tempal = YPbPr525pVCLK ;
- return tempal ;
- }
-
- tempal = NTSC1024VCLK ;
-
- if ( !( pVBInfo->TVInfo & NTSC1024x768 ) )
- {
- tempal = TVVCLKDIV2 ;
- if ( !( pVBInfo->TVInfo & RPLLDIV2XO ) )
- tempal = TVVCLK ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- return tempal ;
- }
- /*else
- if((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017))
- {
- if(ModeNo<=0x13)
- *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- else
- *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- *tempal = *tempal & 0x1F;
-
- tempbx = 0;
- if(pVBInfo->TVInfo & SetPALTV)
- tempbx = tempbx + 2;
- if(pVBInfo->TVInfo & SetCHTVOverScan)
- tempbx++;
- tempbx = tempbx << 1;
- } */
- } /* {End of VB} */
-
- if((pVBInfo->IF_DEF_CH7007==1)&&(pVBInfo->VBType&VB_CH7007)) /* [Billy] 07/05/08 CH7007 */
- {
- /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
- if ( (pVBInfo->VBInfo & SetCRT2ToTV) )
- {
- if( ModeNo <= 0x13 )
- {
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- }
- else
- {
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- tempal = tempal & 0x0F;
- tempbx = 0;
-
- if(pVBInfo->TVInfo & SetPALTV)
- {
- tempbx = tempbx + 2;
- }
- if(pVBInfo->TVInfo & SetCHTVOverScan)
- {
- tempbx++;
- }
- /** tempbx = tempbx << 1; CH7007 ? **/
-
-/*[Billy]07/05/29 CH7007*/
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- switch( tempbx )
- {
- case 0:
- CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC ;
- break ;
- case 1:
- CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC ;
- break ;
- case 2:
- CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL ;
- break ;
- case 3:
- CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL ;
- break ;
- default:
- break ;
-
- }
- }
- /*else
- {
- switch( tempbx )
- {
- case 0:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
- break ;
- case 1:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
- break ;
- case 2:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
- break ;
- case 3:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
- break ;
- default:
- break ;
- }
- }*/
-
- tempal = CHTVVCLKPtr[ tempal ] ;
- return tempal ;
- }
-
- }
-
- tempal = (unsigned char)XGINew_GetReg2((pVBInfo->P3ca + 0x02));
- tempal = tempal >> 2 ;
- tempal &= 0x03 ;
-
- if ( ( pVBInfo->LCDInfo & EnableScalingLCD ) && ( modeflag & Charx8Dot ) ) /* for Dot8 Scaling LCD */
- tempal = tempal ^ tempal ; /* ; set to VCLK25MHz always */
-
- if ( ModeNo <= 0x13 )
- return tempal ;
-
- tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
- return tempal ;
-}
+ tempax = pVBInfo->VGAVDE;
+ tempbx = pVBInfo->VGAVDE;
+ tempcx = pVBInfo->VGAVT;
+ tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVCLKLen */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
- unsigned char *di_1, struct vb_device_info *pVBInfo)
-{
- if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 2007/05/16 */
- {
- /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
- *di_0 = (unsigned char)XGI_CH7007VCLKData[tempal].SR2B;
- *di_1 = (unsigned char)XGI_CH7007VCLKData[tempal].SR2C;
- }
- else if ( pVBInfo->VBType & ( VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( pVBInfo->SetFlag & ProgrammingCRT2 ) )
- {
- *di_0 = (unsigned char)XGI_VBVCLKData[tempal].SR2B;
- *di_1 = XGI_VBVCLKData[ tempal ].SR2C ;
- }
- }
- else
- {
- *di_0 = XGI_VCLKData[ tempal ].SR2B ;
- *di_1 = XGI_VCLKData[ tempal ].SR2C ;
- }
-}
+ if (temp & 0x04)
+ tempbx |= 0x0100;
+ if (temp & 0x080)
+ tempbx |= 0x0200;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2Offset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT2Offset(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short offset ;
- unsigned char temp;
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- return ;
- }
+ if (temp & 0x08)
+ tempbx |= 0x0400;
- offset = XGI_GetOffset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- temp = (unsigned char)(offset & 0xFF);
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , temp ) ;
- temp = (unsigned char)((offset & 0xFF00) >> 8);
- XGINew_SetReg1(pVBInfo->Part1Port , 0x09 , temp);
- temp = (unsigned char)(((offset >> 3) & 0xFF) + 1) ;
- XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
-}
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
+ tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+ }
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp = ((tempcx & 0x000F) | (temp));
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp);
+ tempax = 0;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetOffset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+ if (modeflag & DoubleScanMode)
+ tempax |= 0x80;
+
+ if (modeflag & HalfDCLK)
+ tempax |= 0x40;
+
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+}
+
+void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned short temp ,
- colordepth ,
- modeinfo ,
- index ,
- infoflag ,
- ColorDepth[] = { 0x01 , 0x02 , 0x04 } ;
+ unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
+ modeflag, CRT1Index;
- modeinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeInfo ;
- if ( ModeNo <= 0x14 )
- infoflag = 0 ;
- else
- infoflag = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ }
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ return;
+
+ temp = 0xFF; /* set MAX HT */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp);
+ /* if (modeflag & Charx8Dot) */
+ /* tempcx = 0x08; */
+ /* else */
+ tempcx = 0x08;
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ modeflag |= Charx8Dot;
+
+ tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ tempax = (tempax / tempcx) - 1;
+ tempbx |= ((tempax & 0x00FF) << 8);
+ temp = tempax & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)))
+ temp += 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
+ if (resinfo == 7)
+ temp -= 2;
+ }
+ } else if (resinfo == 7) {
+ temp -= 2;
+ }
+ }
+ }
- index = ( modeinfo >> 8 ) & 0xFF ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
- temp = pVBInfo->ScreenOffset[ index ] ;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ tempax = pVBInfo->VGAHT;
+ else
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ }
- if ( infoflag & InterlaceMode )
- {
- temp = temp << 1 ;
- }
+ if (tempax >= pVBInfo->VGAHT)
+ tempax = pVBInfo->VGAHT;
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ tempax = (tempax / tempcx) - 5;
+ tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ temp = (tempbx & 0x00FF) - 1;
+ if (!(modeflag & HalfDCLK)) {
+ temp -= 6;
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ temp -= 4;
+ if (ModeNo > 0x13)
+ temp -= 10;
+ }
+ }
+ } else {
+ /* tempcx = tempbx & 0x00FF ; */
+ tempbx = (tempbx & 0xFF00) >> 8;
+ tempcx = (tempcx + tempbx) >> 1;
+ temp = (tempcx & 0x00FF) + 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ temp -= 1;
+ if (!(modeflag & HalfDCLK)) {
+ if ((modeflag & Charx8Dot)) {
+ temp += 4;
+ if (pVBInfo->VGAHDE >= 800)
+ temp -= 6;
+ }
+ }
+ } else {
+ if (!(modeflag & HalfDCLK)) {
+ temp -= 4;
+ if (pVBInfo->LCDResInfo != Panel1280x960) {
+ if (pVBInfo->VGAHDE >= 800) {
+ temp -= 7;
+ if (pVBInfo->ModeType
+ == ModeEGA) {
+ if (pVBInfo->VGAVDE
+ == 1024) {
+ temp += 15;
+ if (pVBInfo->LCDResInfo
+ != Panel1280x1024) {
+ temp
+ += 7;
+ }
+ }
+ }
+
+ if (pVBInfo->VGAHDE >= 1280) {
+ if (pVBInfo->LCDResInfo
+ != Panel1280x960) {
+ if (pVBInfo->LCDInfo
+ & LCDNonExpanding) {
+ temp
+ += 28;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
- colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo
+ == 0x11) || (ModeNo == 0x13) || (ModeNo
+ == 0x0F)) {
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03);
+ }
+
+ if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x2A);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x61);
+ } else {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x2A);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x41);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x0C, 0xF0);
+ }
+ }
+
+ if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo
+ == 0x07)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x54);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x00);
+ } else {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x55);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x00);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x0C, 0xF0);
+ }
+ }
+
+ if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo
+ == 0x0D) || (ModeNo == 0x50)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x30);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x03);
+ } else {
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x07, 0x2f);
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x08, 0x02);
+ }
+ }
+ }
+ }
- if ( ( ModeNo >= 0x7C ) && ( ModeNo <= 0x7E ) )
- {
- temp = ModeNo - 0x7C ;
- colordepth = ColorDepth[ temp ] ;
- temp = 0x6B ;
- if ( infoflag & InterlaceMode )
- {
- temp = temp << 1 ;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
+
+ tempbx = pVBInfo->VGAVT;
+ push1 = tempbx;
+ tempcx = 0x121;
+ tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
+
+ if (tempbx == 357)
+ tempbx = 350;
+ if (tempbx == 360)
+ tempbx = 350;
+ if (tempbx == 375)
+ tempbx = 350;
+ if (tempbx == 405)
+ tempbx = 400;
+ if (tempbx == 525)
+ tempbx = 480;
+
+ push2 = tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (tempbx == 350)
+ tempbx += 5;
+ if (tempbx == 480)
+ tempbx += 5;
+ }
+ }
}
- return( temp * colordepth ) ;
- }
- else
- return( temp * colordepth ) ;
-}
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
+ tempbx = push2;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp);
+ if (tempbx & 0x0100)
+ tempcx |= 0x0002;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2FIFO */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
-{
- XGINew_SetReg1( pVBInfo->Part1Port , 0x01 , 0x3B ) ; /* threshold high ,disable auto threshold */
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x02 , ~( 0x3F ) , 0x04 ) ; /* threshold low default 04h */
-}
+ tempax = 0x000B;
+ if (modeflag & DoubleScanMode)
+ tempax |= 0x08000;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_PreSetGroup1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempcx = 0 ,
- CRT1Index = 0 ,
- resinfo = 0 ;
+ if (tempbx & 0x0200)
+ tempcx |= 0x0040;
- if ( ModeNo > 0x13 )
- {
- CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- CRT1Index &= IndexMask ;
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- }
+ temp = (tempax & 0xFF00) >> 8;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp);
- XGI_SetCRT2Offset( ModeNo , ModeIdIndex , RefreshRateTableIndex , HwDeviceExtension, pVBInfo ) ;
- XGI_SetCRT2FIFO(pVBInfo) ;
- /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
+ if (tempbx & 0x0400)
+ tempcx |= 0x0600;
- for( tempcx = 4 ; tempcx < 7 ; tempcx++ )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , tempcx , 0x0 ) ;
- }
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x50 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x02 , 0x44 ) ; /* temp 0206 */
-}
+ tempax = push1;
+ tempax -= tempbx; /* 0x0C Vertical Retrace Start */
+ tempax = tempax >> 2;
+ push1 = tempax; /* push ax */
+ if (resinfo != 0x09) {
+ tempax = tempax << 1;
+ tempbx += tempax;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short temp = 0 ,
- tempax = 0 ,
- tempbx = 0 ,
- tempcx = 0 ,
- pushbx = 0 ,
- CRT1Index = 0 ,
- modeflag ,
- resinfo = 0 ;
-
- if ( ModeNo > 0x13 )
- {
- CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- CRT1Index &= IndexMask ;
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- }
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
-
- /* bainy change table name */
- if ( modeflag & HalfDCLK )
- {
- temp = ( pVBInfo->VGAHT / 2 - 1 ) & 0x0FF ; /* BTVGA2HT 0x08,0x09 */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , temp ) ;
- temp = ( ( ( pVBInfo->VGAHT / 2 - 1 ) & 0xFF00 ) >> 8 ) << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x09 , ~0x0F0 , temp ) ;
- temp = ( pVBInfo->VGAHDE / 2 + 16 ) & 0x0FF ; /* BTVGA2HDEE 0x0A,0x0C */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ;
- tempcx = ( ( pVBInfo->VGAHT - pVBInfo->VGAHDE ) / 2 ) >> 2 ;
- pushbx = pVBInfo->VGAHDE / 2 + 16 ;
- tempcx = tempcx >> 1 ;
- tempbx = pushbx + tempcx ; /* bx BTVGA@HRS 0x0B,0x0C */
- tempcx += tempbx ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 4 ] ;
- tempbx |= ( ( pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] & 0xC0 ) << 2 ) ;
- tempbx = ( tempbx - 3 ) << 3 ; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[ 5 ] ;
- tempcx &= 0x1F ;
- temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 15 ] ;
- temp = ( temp & 0x04 ) << ( 5 - 2 ) ; /* VGAHRE D[5] */
- tempcx = ( ( tempcx | temp ) - 3 ) << 3 ; /* (VGAHRE-3)*8 */
- }
-
- tempbx += 4 ;
- tempcx += 4 ;
-
- if ( tempcx > ( pVBInfo->VGAHT / 2 ) )
- tempcx = pVBInfo->VGAHT / 2 ;
-
- temp = tempbx & 0x00FF ;
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
- }
- else
- {
- temp = ( pVBInfo->VGAHT - 1 ) & 0x0FF ; /* BTVGA2HT 0x08,0x09 */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , temp ) ;
- temp = ( ( ( pVBInfo->VGAHT - 1 ) & 0xFF00 ) >> 8 ) << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x09 , ~0x0F0 , temp ) ;
- temp = ( pVBInfo->VGAHDE + 16 ) & 0x0FF ; /* BTVGA2HDEE 0x0A,0x0C */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ;
- tempcx = ( pVBInfo->VGAHT - pVBInfo->VGAHDE ) >> 2 ; /* cx */
- pushbx = pVBInfo->VGAHDE + 16 ;
- tempcx = tempcx >> 1 ;
- tempbx = pushbx + tempcx ; /* bx BTVGA@HRS 0x0B,0x0C */
- tempcx += tempbx ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 3 ] ;
- tempbx |= ( ( pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 5 ] & 0xC0 ) << 2 ) ;
- tempbx = ( tempbx - 3 ) << 3 ; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 4 ] ;
- tempcx &= 0x1F ;
- temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 6 ] ;
- temp = ( temp & 0x04 ) << ( 5 - 2 ) ; /* VGAHRE D[5] */
- tempcx = ( ( tempcx | temp ) - 3 ) << 3 ; /* (VGAHRE-3)*8 */
- tempbx += 16 ;
- tempcx += 16 ;
- }
-
- if ( tempcx > pVBInfo->VGAHT )
- tempcx = pVBInfo->VGAHT ;
-
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
- }
-
- tempax = ( tempax & 0x00FF ) | ( tempbx & 0xFF00 ) ;
- tempbx = pushbx ;
- tempbx = ( tempbx & 0x00FF ) | ( ( tempbx & 0xFF00 ) << 4 ) ;
- tempax |= ( tempbx & 0xFF00 ) ;
- temp = ( tempax & 0xFF00 ) >> 8 ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , temp ) ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0D , temp ) ;
- tempcx = ( pVBInfo->VGAVT - 1 ) ;
- temp = tempcx & 0x00FF ;
-
- if ( pVBInfo->IF_DEF_CH7005 == 1 )
- {
- if ( pVBInfo->VBInfo & 0x0C )
- {
- temp-- ;
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0E , temp ) ;
- tempbx = pVBInfo->VGAVDE - 1 ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0F , temp ) ;
- temp = ( ( tempbx & 0xFF00 ) << 3 ) >> 8 ;
- temp |= ( ( tempcx & 0xFF00 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x12 , temp ) ;
-
- tempax = pVBInfo->VGAVDE ;
- tempbx = pVBInfo->VGAVDE ;
- tempcx = pVBInfo->VGAVT ;
- tempbx = ( pVBInfo->VGAVT + pVBInfo->VGAVDE ) >> 1 ; /* BTVGA2VRS 0x10,0x11 */
- tempcx = ( ( pVBInfo->VGAVT - pVBInfo->VGAVDE ) >> 4 ) + tempbx + 1 ; /* BTVGA2VRE 0x11 */
-
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 10 ] ;
- temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 9 ] ;
-
- if ( temp & 0x04 )
- tempbx |= 0x0100 ;
-
- if ( temp & 0x080 )
- tempbx |= 0x0200 ;
-
- temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 14 ] ;
-
- if ( temp & 0x08 )
- tempbx |= 0x0400 ;
-
- temp = pVBInfo->XGINEWUB_CRT1Table[ CRT1Index ].CR[ 11 ] ;
- tempcx = ( tempcx & 0xFF00 ) | ( temp & 0x00FF ) ;
- }
-
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x10 , temp ) ;
- temp = ( ( tempbx & 0xFF00 ) >> 8 ) << 4 ;
- temp = ( ( tempcx & 0x000F ) | ( temp ) ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x11 , temp ) ;
- tempax = 0 ;
-
- if ( modeflag & DoubleScanMode )
- tempax |= 0x80 ;
-
- if ( modeflag & HalfDCLK )
- tempax |= 0x40 ;
-
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2C , ~0x0C0 , tempax ) ;
-}
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+ tempbx -= 10;
+ } else {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if (pVBInfo->TVInfo & SetPALTV) {
+ if (pVBInfo->VBType
+ & VB_XGI301LV) {
+ if (!(pVBInfo->TVInfo
+ & (SetYPbPrMode525p
+ | SetYPbPrMode750p
+ | SetYPbPrMode1080i)))
+ tempbx += 40;
+ } else {
+ tempbx += 40;
+ }
+ }
+ }
+ }
+ } else {
+ tempbx -= 10;
+ }
+ } else {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if (pVBInfo->TVInfo & SetPALTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (!(pVBInfo->TVInfo
+ & (SetYPbPrMode525p
+ | SetYPbPrMode750p
+ | SetYPbPrMode1080i)))
+ tempbx += 40;
+ } else {
+ tempbx += 40;
+ }
+ }
+ }
+ }
+ tempax = push1;
+ tempax = tempax >> 2;
+ tempax++;
+ tempax += tempbx;
+ push1 = tempax; /* push ax */
+
+ if ((pVBInfo->TVInfo & SetPALTV)) {
+ if (tempbx <= 513) {
+ if (tempax >= 513)
+ tempbx = 513;
+ }
+ }
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp);
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp);
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLockRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short push1 ,
- push2 ,
- tempax ,
- tempbx = 0 ,
- tempcx ,
- temp ,
- resinfo ,
- modeflag ,
- CRT1Index ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- CRT1Index &= IndexMask;
- }
-
- if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
- {
- return ;
- }
-
- temp = 0xFF ; /* set MAX HT */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , temp ) ;
- /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
- /* else */
- tempcx=0x08;
-
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- modeflag |= Charx8Dot ;
-
- tempax = pVBInfo->VGAHDE ; /* 0x04 Horizontal Display End */
-
- if ( modeflag & HalfDCLK )
- tempax = tempax >> 1 ;
-
- tempax = ( tempax / tempcx ) - 1 ;
- tempbx |= ( ( tempax & 0x00FF ) << 8 ) ;
- temp = tempax & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x04 , temp ) ;
-
- temp = ( tempbx & 0xFF00 ) >> 8 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( !( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) )
- temp += 2 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( pVBInfo->VBExtInfo == VB_YPbPr1080i )
- {
- if ( resinfo == 7 )
- temp -= 2 ;
- }
- }
- else
- if ( resinfo == 7 )
- temp -= 2 ;
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x05 , temp ) ; /* 0x05 Horizontal Display Start */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x06 , 0x03 ) ; /* 0x06 Horizontal Blank end */
-
- if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
- { /* 030226 bainy */
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- tempax = pVBInfo->VGAHT ;
- else
- tempax = XGI_GetVGAHT2( pVBInfo) ;
- }
-
- if ( tempax >= pVBInfo->VGAHT )
- {
- tempax = pVBInfo->VGAHT ;
- }
-
- if ( modeflag & HalfDCLK )
- {
- tempax = tempax >> 1 ;
- }
-
- tempax = ( tempax / tempcx ) - 5 ;
- tempcx = tempax ; /* 20030401 0x07 horizontal Retrace Start */
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- temp = ( tempbx & 0x00FF ) - 1 ;
- if ( !( modeflag & HalfDCLK ) )
- {
- temp -= 6 ;
- if ( pVBInfo->TVInfo & TVSimuMode )
- {
- temp -= 4 ;
- if ( ModeNo > 0x13 )
- temp -= 10 ;
- }
- }
- }
- else
- {
- /* tempcx = tempbx & 0x00FF ; */
- tempbx = ( tempbx & 0xFF00 ) >> 8 ;
- tempcx = ( tempcx + tempbx ) >> 1 ;
- temp = ( tempcx & 0x00FF ) + 2 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- temp -= 1 ;
- if ( !( modeflag & HalfDCLK ) )
- {
- if ( ( modeflag & Charx8Dot ) )
- {
- temp += 4 ;
- if ( pVBInfo->VGAHDE >= 800 )
- {
- temp -= 6 ;
- }
- }
- }
- }
- else
- {
- if ( !( modeflag & HalfDCLK ) )
- {
- temp -= 4 ;
- if ( pVBInfo->LCDResInfo != Panel1280x960 )
- {
- if( pVBInfo->VGAHDE >= 800 )
- {
- temp -= 7 ;
- if ( pVBInfo->ModeType == ModeEGA )
- {
- if ( pVBInfo->VGAVDE == 1024 )
- {
- temp += 15 ;
- if ( pVBInfo->LCDResInfo != Panel1280x1024 )
- {
- temp += 7 ;
- }
- }
- }
-
- if ( pVBInfo->VGAHDE >= 1280 )
- {
- if ( pVBInfo->LCDResInfo != Panel1280x960 )
- {
- if ( pVBInfo->LCDInfo & LCDNonExpanding )
- {
- temp += 28 ;
- }
- }
- }
- }
- }
- }
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , temp ) ; /* 0x07 Horizontal Retrace Start */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0 ) ; /* 0x08 Horizontal Retrace End */
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( pVBInfo->TVInfo & TVSimuMode )
- {
- if ( ( ModeNo == 0x06 ) || ( ModeNo == 0x10 ) || ( ModeNo == 0x11 ) || ( ModeNo == 0x13 ) || ( ModeNo == 0x0F ) )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x5b ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x03 ) ;
- }
-
- if ( ( ModeNo == 0x00 ) || ( ModeNo == 0x01 ) )
- {
- if ( pVBInfo->TVInfo & SetNTSCTV )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2A ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x61 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2A ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x41 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , 0xF0 ) ;
- }
- }
-
- if ( ( ModeNo == 0x02 ) || ( ModeNo == 0x03 ) || ( ModeNo == 0x07 ) )
- {
- if ( pVBInfo->TVInfo & SetNTSCTV )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x54 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x00 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x55 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , 0xF0 ) ;
- }
- }
-
- if ( ( ModeNo == 0x04 ) || ( ModeNo == 0x05 ) || ( ModeNo == 0x0D ) || ( ModeNo == 0x50 ) )
- {
- if ( pVBInfo->TVInfo & SetNTSCTV )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x30 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x03 ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x07 , 0x2f ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x08 , 0x02 ) ;
- }
- }
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x18 , 0x03 ) ; /* 0x18 SR0B */
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x19 , 0xF0 , 0x00 ) ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x09 , 0xFF ) ; /* 0x09 Set Max VT */
-
- tempbx = pVBInfo->VGAVT ;
- push1 = tempbx ;
- tempcx = 0x121 ;
- tempbx = pVBInfo->VGAVDE ; /* 0x0E Virtical Display End */
-
- if ( tempbx == 357 )
- tempbx = 350 ;
- if ( tempbx == 360 )
- tempbx =350 ;
- if ( tempbx == 375 )
- tempbx = 350 ;
- if ( tempbx == 405 )
- tempbx = 400 ;
- if ( tempbx == 525 )
- tempbx = 480 ;
-
- push2 = tempbx ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- {
- if ( pVBInfo->LCDResInfo == Panel1024x768 )
- {
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( tempbx == 350 )
- tempbx += 5 ;
- if ( tempbx == 480 )
- tempbx += 5 ;
- }
- }
- }
- tempbx-- ;
- temp = tempbx & 0x00FF ;
- tempbx-- ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x10 ,temp ) ; /* 0x10 vertical Blank Start */
- tempbx = push2 ;
- tempbx-- ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0E , temp ) ;
-
- if ( tempbx & 0x0100 )
- {
- tempcx |= 0x0002 ;
- }
-
- tempax = 0x000B ;
-
- if ( modeflag & DoubleScanMode )
- {
- tempax |= 0x08000 ;
- }
-
- if ( tempbx & 0x0200 )
- {
- tempcx |= 0x0040 ;
- }
-
- temp = ( tempax & 0xFF00 ) >> 8 ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0B , temp ) ;
-
- if ( tempbx & 0x0400 )
- {
- tempcx |= 0x0600 ;
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x11 , 0x00 ) ; /* 0x11 Vertival Blank End */
-
- tempax = push1 ;
- tempax -= tempbx ; /* 0x0C Vertical Retrace Start */
- tempax = tempax >> 2 ;
- push1 = tempax ; /* push ax */
-
- if ( resinfo != 0x09 )
- {
- tempax = tempax << 1 ;
- tempbx += tempax ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
- tempbx -= 10 ;
- else
- {
- if ( pVBInfo->TVInfo & TVSimuMode )
- {
- if ( pVBInfo->TVInfo & SetPALTV )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
- tempbx += 40 ;
- }
- else
- tempbx += 40 ;
- }
- }
- }
- }
- else
- tempbx -= 10 ;
- }
- else
- {
- if ( pVBInfo->TVInfo & TVSimuMode )
- {
- if ( pVBInfo->TVInfo & SetPALTV )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
- tempbx += 40 ;
- }
- else
- tempbx += 40 ;
- }
- }
- }
- tempax = push1 ;
- tempax = tempax >> 2 ;
- tempax++ ;
- tempax += tempbx ;
- push1 = tempax ; /* push ax */
-
- if ( ( pVBInfo->TVInfo & SetPALTV ) )
- {
- if ( tempbx <= 513 )
- {
- if ( tempax >= 513 )
- {
- tempbx = 513 ;
- }
- }
- }
-
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0C , temp ) ;
- tempbx-- ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x10 , temp ) ;
-
- if ( tempbx & 0x0100 )
- {
- tempcx |= 0x0008 ;
- }
-
- if ( tempbx & 0x0200 )
- {
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x0B , 0x0FF , 0x20 ) ;
- }
-
- tempbx++ ;
-
- if ( tempbx & 0x0100 )
- {
- tempcx |= 0x0004 ;
- }
-
- if ( tempbx & 0x0200 )
- {
- tempcx |= 0x0080 ;
- }
-
- if ( tempbx & 0x0400 )
- {
- tempcx |= 0x0C00 ;
- }
-
- tempbx = push1 ; /* pop ax */
- temp = tempbx & 0x00FF ;
- temp &= 0x0F ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0D , temp ) ; /* 0x0D vertical Retrace End */
-
- if ( tempbx & 0x0010 )
- {
- tempcx |= 0x2000 ;
- }
-
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0A , temp ) ; /* 0x0A CR07 */
- temp = ( tempcx & 0x0FF00 ) >> 8 ;
- XGINew_SetReg1( pVBInfo->Part1Port , 0x17 , temp ) ; /* 0x17 SR0A */
- tempax = modeflag ;
- temp = ( tempax & 0xFF00 ) >> 8 ;
-
- temp = ( temp >> 1 ) & 0x09 ;
-
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- temp |= 0x01 ;
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x16 , temp ) ; /* 0x16 SR01 */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x0F , 0 ) ; /* 0x0F CR14 */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x12 , 0 ) ; /* 0x12 CR17 */
-
- if ( pVBInfo->LCDInfo & LCDRGB18Bit )
- temp = 0x80 ;
- else
- temp = 0x00 ;
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x1A , temp ) ; /* 0x1A SR0E */
-
- return ;
+ if (tempbx & 0x0100)
+ tempcx |= 0x0008;
+
+ if (tempbx & 0x0200)
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
+
+ tempbx++;
+
+ if (tempbx & 0x0100)
+ tempcx |= 0x0004;
+
+ if (tempbx & 0x0200)
+ tempcx |= 0x0080;
+
+ if (tempbx & 0x0400)
+ tempcx |= 0x0C00;
+
+ tempbx = push1; /* pop ax */
+ temp = tempbx & 0x00FF;
+ temp &= 0x0F;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
+
+ if (tempbx & 0x0010)
+ tempcx |= 0x2000;
+
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
+ temp = (tempcx & 0x0FF00) >> 8;
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
+ tempax = modeflag;
+ temp = (tempax & 0xFF00) >> 8;
+
+ temp = (temp >> 1) & 0x09;
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ temp |= 0x01;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
+
+ if (pVBInfo->LCDInfo & LCDRGB18Bit)
+ temp = 0x80;
+ else
+ temp = 0x00;
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
+
+ return;
}
+void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
+ modeflag, resinfo, crt2crtc;
+ unsigned char *TimingPoint;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short i ,
- j ,
- tempax ,
- tempbx ,
- tempcx ,
- temp ,
- push1 ,
- push2 ,
- modeflag ,
- resinfo ,
- crt2crtc ;
- unsigned char *TimingPoint ;
-
- unsigned long longtemp ,
- tempeax ,
- tempebx ,
- temp2 ,
- tempecx ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
- crt2crtc = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- crt2crtc = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
- }
-
- tempax = 0 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToAVIDEO ) )
- tempax |= 0x0800 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
- tempax |= 0x0400 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToSCART )
- tempax |= 0x0200 ;
-
- if ( !( pVBInfo->TVInfo & SetPALTV ) )
- tempax |= 0x1000 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- tempax |= 0x0100 ;
-
- if ( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
- tempax &= 0xfe00 ;
-
- tempax = ( tempax & 0xff00 ) >> 8 ;
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x0 , tempax ) ;
- TimingPoint = pVBInfo->NTSCTiming ;
-
- if ( pVBInfo->TVInfo & SetPALTV )
- {
- TimingPoint = pVBInfo->PALTiming ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- TimingPoint = pVBInfo->HiTVExtTiming ;
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- TimingPoint = pVBInfo->HiTVSt2Timing ;
-
- if ( pVBInfo->SetFlag & TVSimuMode )
- TimingPoint = pVBInfo->HiTVSt1Timing ;
-
- if ( !(modeflag & Charx8Dot) )
- TimingPoint = pVBInfo->HiTVTextTiming ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode525i )
- TimingPoint = pVBInfo->YPbPr525iTiming ;
-
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- TimingPoint = pVBInfo->YPbPr525pTiming ;
-
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- TimingPoint = pVBInfo->YPbPr750pTiming ;
- }
-
- for( i = 0x01 , j = 0 ; i <= 0x2D ; i++ , j++ )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ;
- }
-
- for( i = 0x39 ; i <= 0x45 ; i++ , j++ )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ; /* di->temp2[j] */
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x3A , 0x1F , 0x00 ) ;
- }
-
- temp = pVBInfo->NewFlickerMode ;
- temp &= 0x80 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0xFF , temp ) ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- tempax = 950 ;
-
- if ( pVBInfo->TVInfo & SetPALTV )
- tempax = 520 ;
- else
- tempax = 440 ;
-
- if ( pVBInfo->VDE <= tempax )
- {
- tempax -= pVBInfo->VDE ;
- tempax = tempax >> 2 ;
- tempax = ( tempax & 0x00FF ) | ( ( tempax & 0x00FF ) << 8 ) ;
- push1 = tempax ;
- temp = ( tempax & 0xFF00 ) >> 8 ;
- temp += (unsigned short)TimingPoint[0];
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr ) )
- {
- tempcx=pVBInfo->VGAHDE;
- if ( tempcx >= 1024 )
- {
- temp = 0x17 ; /* NTSC */
- if ( pVBInfo->TVInfo & SetPALTV )
- temp = 0x19 ; /* PAL */
- }
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x01 , temp ) ;
- tempax = push1 ;
- temp = ( tempax & 0xFF00 ) >> 8 ;
- temp += TimingPoint[ 1 ] ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( ( pVBInfo->VBInfo & ( SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr ) ) )
- {
- tempcx = pVBInfo->VGAHDE ;
- if ( tempcx >= 1024 )
- {
- temp = 0x1D ; /* NTSC */
- if ( pVBInfo->TVInfo & SetPALTV )
- temp = 0x52 ; /* PAL */
- }
- }
- }
- XGINew_SetReg1( pVBInfo->Part2Port , 0x02 , temp ) ;
- }
-
- /* 301b */
- tempcx = pVBInfo->HT ;
-
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- tempcx = tempcx >> 1 ;
-
- tempcx -= 2 ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x1B , temp ) ;
-
- temp = ( tempcx & 0xFF00 ) >> 8 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1D , ~0x0F , temp ) ;
-
- tempcx = pVBInfo->HT >> 1 ;
- push1 = tempcx ; /* push cx */
- tempcx += 7 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- tempcx -= 4 ;
- }
-
- temp = tempcx & 0x00FF ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x22 , 0x0F , temp ) ;
-
- tempbx = TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ;
- tempbx += tempcx ;
- push2 = tempbx ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x24 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR(pVBInfo->Part2Port,0x25,0x0F,temp);
-
- tempbx=push2;
- tempbx=tempbx+8;
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- tempbx=tempbx-4;
- tempcx=tempbx;
- }
-
- temp = ( tempbx & 0x00FF ) << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x29 , 0x0F , temp ) ;
-
- j += 2 ;
- tempcx += ( TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ) ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x27 , temp ) ;
- temp = ( ( tempcx & 0xFF00 ) >> 8 ) << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x28 , 0x0F , temp ) ;
-
- tempcx += 8 ;
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- tempcx -= 4 ;
- }
-
- temp = tempcx & 0xFF ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2A , 0x0F , temp ) ;
-
- tempcx = push1 ; /* pop cx */
- j += 2 ;
- temp = TimingPoint[ j ] | ( ( TimingPoint[ j + 1 ] ) << 8 ) ;
- tempcx -= temp ;
- temp = tempcx & 0x00FF ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2D , 0x0F ,temp ) ;
-
- tempcx -= 11 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
- {
- tempax = XGI_GetVGAHT2( pVBInfo) ;
- tempcx = tempax - 1 ;
- }
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x2E , temp ) ;
-
- tempbx = pVBInfo->VDE ;
-
- if ( pVBInfo->VGAVDE == 360 )
- tempbx = 746 ;
- if ( pVBInfo->VGAVDE == 375 )
- tempbx = 746 ;
- if ( pVBInfo->VGAVDE == 405 )
- tempbx = 853 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
- tempbx = tempbx >> 1 ;
- }
- else
- tempbx = tempbx >> 1 ;
- }
-
- tempbx -= 2 ;
- temp = tempbx & 0x00FF ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( ModeNo == 0x2f )
- temp += 1 ;
- }
- }
- }
- else
- {
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( ModeNo == 0x2f )
- temp += 1 ;
- }
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x2F , temp ) ;
-
- temp = ( tempcx & 0xFF00 ) >> 8 ;
- temp |= ( ( tempbx & 0xFF00 ) >> 8 ) << 6 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
- {
- temp |= 0x10 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
- temp |= 0x20 ;
- }
- }
- else
- {
- temp |= 0x10 ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToSVIDEO ) )
- temp |= 0x20 ;
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x30 , temp ) ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) ) /* TV gatingno */
- {
- tempbx = pVBInfo->VDE ;
- tempcx = tempbx - 2 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
- tempbx = tempbx >> 1 ;
- }
-
- if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
- {
- temp=0;
- if( tempcx & 0x0400 )
- temp |= 0x20 ;
-
- if ( tempbx & 0x0400 )
- temp |= 0x40 ;
-
- XGINew_SetReg1( pVBInfo->Part4Port , 0x10 , temp ) ;
- }
-
- temp = ( ( ( tempbx - 3 ) & 0x0300 ) >> 8 ) << 5 ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x46 , temp ) ;
- temp = ( tempbx - 3 ) & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x47 , temp ) ;
- }
-
- tempbx = tempbx & 0x00FF ;
-
- if ( !( modeflag & HalfDCLK ) )
- {
- tempcx = pVBInfo->VGAHDE ;
- if ( tempcx >= pVBInfo->HDE )
- {
- tempbx |= 0x2000 ;
- tempax &= 0x00FF ;
- }
- }
-
- tempcx = 0x0101 ;
-
- if( pVBInfo->VBInfo & SetCRT2ToTV ) { /*301b*/
- if(pVBInfo->VGAHDE>=1024)
- {
- tempcx=0x1920;
- if(pVBInfo->VGAHDE>=1280)
- {
- tempcx=0x1420;
- tempbx=tempbx&0xDFFF;
- }
- }
- }
-
- if ( !( tempbx & 0x2000 ) )
- {
- if ( modeflag & HalfDCLK )
- {
- tempcx = ( tempcx & 0xFF00 ) | ( ( tempcx & 0x00FF ) << 1 ) ;
- }
-
- push1 = tempbx ;
- tempeax = pVBInfo->VGAHDE ;
- tempebx = ( tempcx & 0xFF00 ) >> 8 ;
- longtemp = tempeax * tempebx ;
- tempecx = tempcx & 0x00FF ;
- longtemp = longtemp / tempecx ;
+ unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
- /* 301b */
- tempecx = 8 * 1024 ;
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ crt2crtc
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempax = 0;
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempecx = tempecx * 8 ;
- }
+ if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
+ tempax |= 0x0800;
- longtemp = longtemp * tempecx ;
- tempecx = pVBInfo->HDE ;
- temp2 = longtemp % tempecx ;
- tempeax = longtemp / tempecx ;
- if ( temp2 != 0 )
- {
- tempeax += 1 ;
- }
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ tempax |= 0x0400;
- tempax = (unsigned short)tempeax;
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempax |= 0x0200;
+
+ if (!(pVBInfo->TVInfo & SetPALTV))
+ tempax |= 0x1000;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempax |= 0x0100;
+
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+ tempax &= 0xfe00;
+
+ tempax = (tempax & 0xff00) >> 8;
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax);
+ TimingPoint = pVBInfo->NTSCTiming;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ TimingPoint = pVBInfo->PALTiming;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ TimingPoint = pVBInfo->HiTVExtTiming;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ TimingPoint = pVBInfo->HiTVSt2Timing;
+
+ if (pVBInfo->SetFlag & TVSimuMode)
+ TimingPoint = pVBInfo->HiTVSt1Timing;
+
+ if (!(modeflag & Charx8Dot))
+ TimingPoint = pVBInfo->HiTVTextTiming;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ TimingPoint = pVBInfo->YPbPr525iTiming;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ TimingPoint = pVBInfo->YPbPr525pTiming;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ TimingPoint = pVBInfo->YPbPr750pTiming;
+ }
+
+ for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
+ XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]);
+
+ for (i = 0x39; i <= 0x45; i++, j++)
+ XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+
+ temp = pVBInfo->NewFlickerMode;
+ temp &= 0x80;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempax = 950;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempax = 520;
+ else
+ tempax = 440;
+
+ if (pVBInfo->VDE <= tempax) {
+ tempax -= pVBInfo->VDE;
+ tempax = tempax >> 2;
+ tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+ push1 = tempax;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += (unsigned short) TimingPoint[0];
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+ | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x17; /* NTSC */
+ if (pVBInfo->TVInfo & SetPALTV)
+ temp = 0x19; /* PAL */
+ }
+ }
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
+ tempax = push1;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += TimingPoint[1];
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
+ | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr))) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x1D; /* NTSC */
+ if (pVBInfo->TVInfo & SetPALTV)
+ temp = 0x52; /* PAL */
+ }
+ }
+ }
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp);
+ }
/* 301b */
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempcx = ( ( tempax & 0xFF00 ) >> 5 ) >> 8 ;
- }
- /* end 301b */
-
- tempbx = push1 ;
- tempbx = (unsigned short)(((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
- tempax = (unsigned short)(((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
- temp = ( tempax & 0xFF00 ) >> 8 ;
- }
- else
- {
- temp = ( tempax & 0x00FF ) >> 8 ;
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x44 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x45 , ~0x03F , temp ) ;
- temp = tempcx & 0x00FF ;
-
- if ( tempbx & 0x2000 )
- temp = 0 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
- temp |= 0x18 ;
-
- XGINew_SetRegANDOR(pVBInfo->Part2Port,0x46,~0x1F,temp);
- if ( pVBInfo->TVInfo & SetPALTV )
- {
- tempbx = 0x0382 ;
- tempcx = 0x007e ;
- }
- else
- {
- tempbx = 0x0369 ;
- tempcx = 0x0061 ;
- }
-
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x4b , temp ) ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x4c , temp ) ;
-
- temp = ( ( tempcx & 0xFF00 ) >> 8 ) & 0x03 ;
- temp = temp << 2 ;
- temp |= ( ( tempbx & 0xFF00 ) >> 8 ) & 0x03 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- temp |= 0x10 ;
-
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- temp |= 0x20 ;
-
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- temp |= 0x60 ;
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x4d , temp ) ;
- temp=XGINew_GetReg1( pVBInfo->Part2Port , 0x43 ) ; /* 301b change */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x43, (unsigned short)( temp - 3 ) ) ;
-
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) )
- {
- if ( pVBInfo->TVInfo & NTSC1024x768 )
- {
- TimingPoint = XGI_NTSC1024AdjTime ;
- for( i = 0x1c , j = 0 ; i <= 0x30 ; i++ , j++ )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , i , TimingPoint[ j ] ) ;
- }
- XGINew_SetReg1( pVBInfo->Part2Port , 0x43 , 0x72 ) ;
- }
- }
-
- /* [ycchen] 01/14/03 Modify for 301C PALM Support */
- if ( pVBInfo->VBType & VB_XGI301C )
- {
- if ( pVBInfo->TVInfo & SetPALMTV )
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x08 , 0x08 ) ; /* PALM Mode */
- }
-
- if ( pVBInfo->TVInfo & SetPALMTV )
- {
- tempax = (unsigned char)XGINew_GetReg1(pVBInfo->Part2Port, 0x01);
- tempax-- ;
- XGINew_SetRegAND( pVBInfo->Part2Port , 0x01 , tempax ) ;
-
- /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
- XGINew_SetRegAND( pVBInfo->Part2Port , 0x00 , 0xEF ) ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , 0x0B , 0x00 ) ;
- }
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- return ;
- }
-}
+ tempcx = pVBInfo->HT;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempcx = tempcx >> 1;
+
+ tempcx -= 2;
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
+
+ tempcx = pVBInfo->HT >> 1;
+ push1 = tempcx; /* push cx */
+ tempcx += 7;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempcx -= 4;
+
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp);
+
+ tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempbx += tempcx;
+ push2 = tempbx;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp);
+
+ tempbx = push2;
+ tempbx = tempbx + 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempbx = tempbx - 4;
+ tempcx = tempbx;
+ }
+ temp = (tempbx & 0x00FF) << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp);
+
+ j += 2;
+ tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp);
+ temp = ((tempcx & 0xFF00) >> 8) << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp);
+
+ tempcx += 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempcx -= 4;
+
+ temp = tempcx & 0xFF;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
+
+ tempcx = push1; /* pop cx */
+ j += 2;
+ temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempcx -= temp;
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
+
+ tempcx -= 11;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ tempcx = tempax - 1;
+ }
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp);
+
+ tempbx = pVBInfo->VDE;
+
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 375)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 405)
+ tempbx = 853;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
+ | SetYPbPrMode750p)))
+ tempbx = tempbx >> 1;
+ } else
+ tempbx = tempbx >> 1;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short push1 ,
- push2 ,
- pushbx ,
- tempax ,
- tempbx ,
- tempcx ,
- temp ,
- tempah ,
- tempbh ,
- tempch ,
- resinfo ,
- modeflag ,
- CRT1Index ;
-
- struct XGI_LCDDesStruct *LCDBDesPtr = NULL ;
-
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- CRT1Index &= IndexMask ;
- }
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
- {
- return ;
- }
-
- tempbx = pVBInfo->HDE ; /* RHACTE=HDE-1 */
-
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- tempbx = tempbx >> 1 ;
-
- tempbx -= 1 ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x2C , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x2B , 0x0F , temp ) ;
- temp = 0x01 ;
-
- if ( pVBInfo->LCDResInfo == Panel1280x1024 )
- {
- if ( pVBInfo->ModeType == ModeEGA )
- {
- if ( pVBInfo->VGAHDE >= 1024 )
- {
- temp = 0x02 ;
- if ( pVBInfo->LCDInfo & LCDVESATiming )
- temp = 0x01 ;
- }
- }
- }
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x0B , temp ) ;
- tempbx = pVBInfo->VDE ; /* RTVACTEO=(VDE-1)&0xFF */
- push1 = tempbx ;
- tempbx-- ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x03 , temp ) ;
- temp = ( ( tempbx & 0xFF00 ) >> 8 ) & 0x07 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0C , ~0x07 , temp ) ;
-
- tempcx = pVBInfo->VT - 1 ;
- push2 = tempcx + 1 ;
- temp = tempcx & 0x00FF ; /* RVTVT=VT-1 */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x19 , temp ) ;
- temp = ( tempcx & 0xFF00 ) >> 8 ;
- temp = temp << 5 ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x1A , temp ) ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x09 , 0xF0 , 0x00 ) ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0xF0 , 0x00 ) ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x17 , 0xFB , 0x00 ) ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x18 , 0xDF , 0x00 ) ;
-
- /* Customized LCDB Des no add */
- tempbx = 5 ;
- LCDBDesPtr = (struct XGI_LCDDesStruct *)XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- tempah = pVBInfo->LCDResInfo ;
- tempah &= PanelResInfo ;
-
- if ( ( tempah == Panel1024x768 ) || ( tempah == Panel1024x768x75 ) )
- {
- tempbx = 1024 ;
- tempcx = 768 ;
- }
- else if ( ( tempah == Panel1280x1024 ) || ( tempah == Panel1280x1024x75 ) )
- {
- tempbx = 1280 ;
- tempcx = 1024 ;
- }
- else if ( tempah == Panel1400x1050 )
- {
- tempbx = 1400 ;
- tempcx = 1050 ;
- }
- else
- {
- tempbx = 1600 ;
- tempcx = 1200 ;
- }
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- {
- tempbx = pVBInfo->HDE ;
- tempcx = pVBInfo->VDE ;
- }
-
- pushbx = tempbx ;
- tempax = pVBInfo->VT ;
- pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES ;
- pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS ;
- pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES ;
- pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS ;
- tempbx = pVBInfo->LCDVDES ;
- tempcx += tempbx ;
-
- if ( tempcx >= tempax )
- tempcx -= tempax ; /* lcdvdes */
-
- temp = tempbx & 0x00FF ; /* RVEQ1EQ=lcdvdes */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x05 , temp ) ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x06 , temp ) ;
- tempch = ( ( tempcx & 0xFF00 ) >> 8 ) & 0x07 ;
- tempbh = ( ( tempbx & 0xFF00 ) >> 8 ) & 0x07 ;
- tempah = tempch ;
- tempah = tempah << 3 ;
- tempah |= tempbh ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x02 , tempah ) ;
-
- /* getlcdsync() */
- XGI_GetLCDSync( &tempax , &tempbx,pVBInfo ) ;
- tempcx = tempbx ;
- tempax = pVBInfo->VT ;
- tempbx = pVBInfo->LCDVRS ;
-
- /* if ( SetLCD_Info & EnableScalingLCD ) */
- tempcx += tempbx ;
- if ( tempcx >= tempax )
- tempcx -= tempax ;
-
- temp = tempbx & 0x00FF ; /* RTVACTEE=lcdvrs */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x04 , temp ) ;
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp = temp << 4 ;
- temp |= ( tempcx & 0x000F ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x01 , temp ) ;
- tempcx = pushbx ;
- tempax = pVBInfo->HT ;
- tempbx = pVBInfo->LCDHDES ;
- tempbx &= 0x0FFF ;
-
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- {
- tempax = tempax >> 1 ;
- tempbx = tempbx >> 1 ;
- tempcx = tempcx >> 1 ;
- }
-
- if ( pVBInfo->VBType & VB_XGI302LV )
- tempbx += 1 ;
-
- if ( pVBInfo->VBType & VB_XGI301C ) /* tap4 */
- tempbx += 1 ;
-
- tempcx += tempbx ;
-
- if ( tempcx >= tempax )
- tempcx -= tempax ;
-
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x1F , temp ) ; /* RHBLKE=lcdhdes */
- temp = ( ( tempbx & 0xFF00 ) >> 8 ) << 4 ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x20 , temp ) ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x23 , temp ) ; /* RHEQPLE=lcdhdee */
- temp = ( tempcx & 0xFF00 ) >> 8 ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x25 , temp ) ;
-
- /* getlcdsync() */
- XGI_GetLCDSync( &tempax , &tempbx ,pVBInfo) ;
- tempcx = tempax ;
- tempax = pVBInfo->HT ;
- tempbx = pVBInfo->LCDHRS ;
- /* if ( SetLCD_Info & EnableScalingLCD) */
- if ( XGI_IsLCDDualLink( pVBInfo) )
- {
- tempax = tempax >> 1 ;
- tempbx = tempbx >> 1 ;
- tempcx = tempcx >> 1 ;
- }
-
- if ( pVBInfo->VBType & VB_XGI302LV )
- tempbx += 1 ;
-
- tempcx += tempbx ;
-
- if ( tempcx >= tempax )
- tempcx -= tempax ;
-
- temp = tempbx & 0x00FF ; /* RHBURSTS=lcdhrs */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x1C , temp ) ;
-
- temp = ( tempbx & 0xFF00 ) >> 8 ;
- temp = temp << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x1D , ~0x0F0 , temp ) ;
- temp = tempcx & 0x00FF ; /* RHSYEXP2S=lcdhre */
- XGINew_SetReg1( pVBInfo->Part2Port , 0x21 , temp ) ;
-
- if ( !( pVBInfo->LCDInfo & LCDVESATiming ) )
- {
- if ( pVBInfo->VGAVDE == 525 )
- {
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- temp = 0xC6 ;
- }
- else
- temp = 0xC4 ;
-
- XGINew_SetReg1( pVBInfo->Part2Port , 0x2f , temp ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x30 , 0xB3 ) ;
- }
-
- if ( pVBInfo->VGAVDE == 420 )
- {
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- temp = 0x4F ;
- }
- else
- temp = 0x4E ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x2f , temp ) ;
- }
- }
+ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+ } else {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ temp |= ((tempbx & 0xFF00) >> 8) << 6;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+ temp |= 0x10;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ } else {
+ temp |= 0x10;
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp);
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
+ tempbx = pVBInfo->VDE;
+ tempcx = tempbx - 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
+ | SetYPbPrMode750p)))
+ tempbx = tempbx >> 1;
+ }
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ temp = 0;
+ if (tempcx & 0x0400)
+ temp |= 0x20;
+
+ if (tempbx & 0x0400)
+ temp |= 0x40;
+
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp);
+ }
+
+ temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp);
+ temp = (tempbx - 3) & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp);
+ }
+
+ tempbx = tempbx & 0x00FF;
+
+ if (!(modeflag & HalfDCLK)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= pVBInfo->HDE) {
+ tempbx |= 0x2000;
+ tempax &= 0x00FF;
+ }
+ }
+
+ tempcx = 0x0101;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
+ if (pVBInfo->VGAHDE >= 1024) {
+ tempcx = 0x1920;
+ if (pVBInfo->VGAHDE >= 1280) {
+ tempcx = 0x1420;
+ tempbx = tempbx & 0xDFFF;
+ }
+ }
+ }
+
+ if (!(tempbx & 0x2000)) {
+ if (modeflag & HalfDCLK)
+ tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
+
+ push1 = tempbx;
+ tempeax = pVBInfo->VGAHDE;
+ tempebx = (tempcx & 0xFF00) >> 8;
+ longtemp = tempeax * tempebx;
+ tempecx = tempcx & 0x00FF;
+ longtemp = longtemp / tempecx;
+
+ /* 301b */
+ tempecx = 8 * 1024;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ tempecx = tempecx * 8;
+ }
+
+ longtemp = longtemp * tempecx;
+ tempecx = pVBInfo->HDE;
+ temp2 = longtemp % tempecx;
+ tempeax = longtemp / tempecx;
+ if (temp2 != 0)
+ tempeax += 1;
+
+ tempax = (unsigned short) tempeax;
+
+ /* 301b */
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+ }
+ /* end 301b */
+
+ tempbx = push1;
+ tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
+ | (tempbx & 0x00FF));
+ tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
+ | (tempax & 0x00FF));
+ temp = (tempax & 0xFF00) >> 8;
+ } else {
+ temp = (tempax & 0x00FF) >> 8;
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
+ temp = tempcx & 0x00FF;
+
+ if (tempbx & 0x2000)
+ temp = 0;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ temp |= 0x18;
+
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
+ if (pVBInfo->TVInfo & SetPALTV) {
+ tempbx = 0x0382;
+ tempcx = 0x007e;
+ } else {
+ tempbx = 0x0369;
+ tempcx = 0x0061;
+ }
+
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp);
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) & 0x03;
+ temp = temp << 2;
+ temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ temp |= 0x10;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ temp |= 0x20;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ temp |= 0x60;
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp);
+ temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
+
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ TimingPoint = XGI_NTSC1024AdjTime;
+ for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+ XGINew_SetReg1(pVBInfo->Part2Port, i,
+ TimingPoint[j]);
+ }
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72);
+ }
+ }
+
+ /* [ycchen] 01/14/03 Modify for 301C PALM Support */
+ if (pVBInfo->VBType & VB_XGI301C) {
+ if (pVBInfo->TVInfo & SetPALMTV)
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08,
+ 0x08); /* PALM Mode */
+ }
+
+ if (pVBInfo->TVInfo & SetPALMTV) {
+ tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port,
+ 0x01);
+ tempax--;
+ XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax);
+
+ /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
+ XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ return;
}
+void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp,
+ tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
+
+ struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ return;
+
+ tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ tempbx -= 1;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
+ temp = 0x01;
+
+ if (pVBInfo->LCDResInfo == Panel1280x1024) {
+ if (pVBInfo->ModeType == ModeEGA) {
+ if (pVBInfo->VGAHDE >= 1024) {
+ temp = 0x02;
+ if (pVBInfo->LCDInfo & LCDVESATiming)
+ temp = 0x01;
+ }
+ }
+ }
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp);
+ tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
+ push1 = tempbx;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp);
+ temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
+
+ tempcx = pVBInfo->VT - 1;
+ push2 = tempcx + 1;
+ temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp);
+ temp = (tempcx & 0xFF00) >> 8;
+ temp = temp << 5;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp);
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
+
+ /* Customized LCDB Des no add */
+ tempbx = 5;
+ LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ tempah = pVBInfo->LCDResInfo;
+ tempah &= PanelResInfo;
+
+ if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
+ tempbx = 1024;
+ tempcx = 768;
+ } else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) {
+ tempbx = 1280;
+ tempcx = 1024;
+ } else if (tempah == Panel1400x1050) {
+ tempbx = 1400;
+ tempcx = 1050;
+ } else {
+ tempbx = 1600;
+ tempcx = 1200;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ tempbx = pVBInfo->HDE;
+ tempcx = pVBInfo->VDE;
+ }
+
+ pushbx = tempbx;
+ tempax = pVBInfo->VT;
+ pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
+ pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
+ pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
+ pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
+ tempbx = pVBInfo->LCDVDES;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax; /* lcdvdes */
+
+ temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp);
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp);
+ tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
+ tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
+ tempah = tempch;
+ tempah = tempah << 3;
+ tempah |= tempbh;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah);
+
+ /* getlcdsync() */
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ tempcx = tempbx;
+ tempax = pVBInfo->VT;
+ tempbx = pVBInfo->LCDVRS;
+
+ /* if (SetLCD_Info & EnableScalingLCD) */
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ temp |= (tempcx & 0x000F);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp);
+ tempcx = pushbx;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHDES;
+ tempbx &= 0x0FFF;
+
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_XGI302LV)
+ tempbx += 1;
+
+ if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp);
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
+ temp = (tempcx & 0xFF00) >> 8;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp);
+
+ /* getlcdsync() */
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ tempcx = tempax;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHRS;
+ /* if ( SetLCD_Info & EnableScalingLCD) */
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_XGI302LV)
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
+ temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp);
+
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 525) {
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ temp = 0xC6;
+ } else
+ temp = 0xC4;
+
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3);
+ }
+
+ if (pVBInfo->VGAVDE == 420) {
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ temp = 0x4F;
+ } else
+ temp = 0x4E;
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp);
+ }
+ }
+}
/* --------------------------------------------------------------------- */
/* Function : XGI_GetTap4Ptr */
@@ -6668,1134 +5677,973 @@ void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct x
/* Description : */
/* --------------------------------------------------------------------- */
struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempax ,
- tempbx ,
- i ;
-
- struct XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
-
- if ( tempcx == 0 )
- {
- tempax = pVBInfo->VGAHDE ;
- tempbx = pVBInfo->HDE ;
- }
- else
- {
- tempax = pVBInfo->VGAVDE ;
- tempbx = pVBInfo->VDE ;
- }
-
- if ( tempax < tempbx )
- return &EnlargeTap4Timing[ 0 ] ;
- else if( tempax == tempbx )
- return &NoScaleTap4Timing[ 0 ] ; /* 1:1 */
- else
- Tap4TimingPtr = NTSCTap4Timing ; /* NTSC */
-
- if ( pVBInfo->TVInfo & SetPALTV )
- Tap4TimingPtr = PALTap4Timing ;
-
-
- if ( pVBInfo->VBInfo & SetCRT2ToYPbPr )
- {
- if ( pVBInfo->TVInfo & SetYPbPrMode525i )
- Tap4TimingPtr = YPbPr525iTap4Timing ;
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- Tap4TimingPtr = YPbPr525pTap4Timing ;
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- Tap4TimingPtr = YPbPr750pTap4Timing ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- Tap4TimingPtr = HiTVTap4Timing ;
-
- i = 0 ;
- while( Tap4TimingPtr[ i ].DE != 0xFFFF )
- {
- if ( Tap4TimingPtr[ i ].DE == tempax )
- break ;
- i++ ;
- }
- return &Tap4TimingPtr[ i ] ;
-}
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, i;
+ struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+
+ if (tempcx == 0) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
+ } else {
+ tempax = pVBInfo->VGAVDE;
+ tempbx = pVBInfo->VDE;
+ }
+
+ if (tempax < tempbx)
+ return &EnlargeTap4Timing[0];
+ else if (tempax == tempbx)
+ return &NoScaleTap4Timing[0]; /* 1:1 */
+ else
+ Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ Tap4TimingPtr = PALTap4Timing;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ Tap4TimingPtr = YPbPr525iTap4Timing;
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ Tap4TimingPtr = YPbPr525pTap4Timing;
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ Tap4TimingPtr = YPbPr750pTap4Timing;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ Tap4TimingPtr = HiTVTap4Timing;
+
+ i = 0;
+ while (Tap4TimingPtr[i].DE != 0xFFFF) {
+ if (Tap4TimingPtr[i].DE == tempax)
+ break;
+ i++;
+ }
+ return &Tap4TimingPtr[i];
+}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetTap4Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
{
- unsigned short i ,
- j ;
+ unsigned short i, j;
- struct XGI301C_Tap4TimingStruct *Tap4TimingPtr ;
+ struct XGI301C_Tap4TimingStruct *Tap4TimingPtr;
- if ( !( pVBInfo->VBType & VB_XGI301C ) )
- return ;
+ if (!(pVBInfo->VBType & VB_XGI301C))
+ return;
#ifndef Tap4
- XGINew_SetRegAND( pVBInfo->Part2Port , 0x4E , 0xEB ) ; /* Disable Tap4 */
+ XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
#else /* Tap4 Setting */
- Tap4TimingPtr = XGI_GetTap4Ptr( 0 , pVBInfo) ; /* Set Horizontal Scaling */
- for( i = 0x80 , j = 0 ; i <= 0xBF ; i++ , j++ )
- XGINew_SetReg1( pVBInfo->Part2Port , i , Tap4TimingPtr->Reg[ j ] ) ;
-
- if ( ( pVBInfo->VBInfo & SetCRT2ToTV ) && ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) )
- {
- Tap4TimingPtr = XGI_GetTap4Ptr( 1 , pVBInfo); /* Set Vertical Scaling */
- for( i = 0xC0 , j = 0 ; i < 0xFF ; i++ , j++ )
- XGINew_SetReg1( pVBInfo->Part2Port , i , Tap4TimingPtr->Reg[ j ] ) ;
- }
-
- if ( ( pVBInfo->VBInfo & SetCRT2ToTV ) && ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) )
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x14 , 0x04 ) ; /* Enable V.Scaling */
- else
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x4E , ~0x14 , 0x10 ) ; /* Enable H.Scaling */
+ Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
+ for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
+ XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+ Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
+ for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
+ XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+ }
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
+ else
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
#endif
}
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup3 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short i;
- unsigned char *tempdi;
- unsigned short modeflag;
-
- if(ModeNo<=0x13)
- {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- }
-
-
- XGINew_SetReg1(pVBInfo->Part3Port,0x00,0x00);
- if(pVBInfo->TVInfo&SetPALTV)
- {
- XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xFA);
- XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xC8);
- }
- else
- {
- XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xF5);
- XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xB7);
- }
-
- if(!(pVBInfo->VBInfo&SetCRT2ToTV))
- {
- return;
- }
-
- if(pVBInfo->TVInfo&SetPALMTV)
- {
- XGINew_SetReg1(pVBInfo->Part3Port,0x13,0xFA);
- XGINew_SetReg1(pVBInfo->Part3Port,0x14,0xC8);
- XGINew_SetReg1(pVBInfo->Part3Port,0x3D,0xA8);
- }
-
- if((pVBInfo->VBInfo&SetCRT2ToHiVisionTV)|| (pVBInfo->VBInfo&SetCRT2ToYPbPr))
- {
- if(pVBInfo->TVInfo & SetYPbPrMode525i)
- {
- return;
- }
- tempdi=pVBInfo->HiTVGroup3Data;
- if(pVBInfo->SetFlag&TVSimuMode)
- {
- tempdi=pVBInfo->HiTVGroup3Simu;
- if(!(modeflag&Charx8Dot))
- {
- tempdi=pVBInfo->HiTVGroup3Text;
- }
- }
-
- if(pVBInfo->TVInfo & SetYPbPrMode525p)
- {
- tempdi=pVBInfo->Ren525pGroup3;
- }
- if(pVBInfo->TVInfo & SetYPbPrMode750p)
- {
- tempdi=pVBInfo->Ren750pGroup3;
- }
-
- for(i=0;i<=0x3E;i++)
- {
- XGINew_SetReg1(pVBInfo->Part3Port,i,tempdi[i]);
- }
- if(pVBInfo->VBType&VB_XGI301C) /* Marcovision */
- {
- if(pVBInfo->TVInfo & SetYPbPrMode525p)
- {
- XGINew_SetReg1(pVBInfo->Part3Port,0x28,0x3f);
- }
- }
- }
- return;
-} /* {end of XGI_SetGroup3} */
+void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i;
+ unsigned char *tempdi;
+ unsigned short modeflag;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00);
+ if (pVBInfo->TVInfo & SetPALTV) {
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
+ } else {
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5);
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7);
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup4 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax ,
- tempcx ,
- tempbx ,
- modeflag ,
- temp ,
- temp2 ;
-
- unsigned long tempebx ,
- tempeax ,
- templong ;
-
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- }
-
- temp = pVBInfo->RVBHCFACT ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x13 , temp ) ;
-
- tempbx = pVBInfo->RVBHCMAX ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x14 , temp ) ;
- temp2 = ( ( tempbx & 0xFF00 ) >> 8 ) << 7 ;
- tempcx = pVBInfo->VGAHT - 1 ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x16 , temp ) ;
-
- temp =( ( tempcx & 0xFF00 ) >> 8 ) << 3 ;
- temp2 |= temp ;
-
- tempcx = pVBInfo->VGAVT - 1 ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
- {
- tempcx -= 5 ;
- }
-
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x17 , temp ) ;
- temp = temp2 | ( ( tempcx & 0xFF00 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x15 , temp ) ;
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x0D , 0x08 ) ;
- tempcx = pVBInfo->VBInfo ;
- tempbx = pVBInfo->VGAHDE ;
-
- if ( modeflag & HalfDCLK )
- {
- tempbx = tempbx >> 1 ;
- }
-
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- tempbx = tempbx >> 1 ;
-
- if(tempcx&SetCRT2ToHiVisionTV)
- {
- temp=0;
- if(tempbx<=1024)
- temp=0xA0;
- if(tempbx == 1280)
- temp = 0xC0;
- }
- else if(tempcx&SetCRT2ToTV)
- {
- temp=0xA0;
- if(tempbx <= 800)
- temp=0x80;
- }
- else
- {
- temp=0x80;
- if(pVBInfo->VBInfo&SetCRT2ToLCD)
- {
- temp=0;
- if(tempbx>800)
- temp=0x60;
- }
- }
-
- if ( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
- {
- temp = 0x00 ;
- if ( pVBInfo->VGAHDE == 1280 )
- temp = 0x40 ;
- if ( pVBInfo->VGAHDE == 1024 )
- temp = 0x20 ;
- }
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0E , ~0xEF , temp ) ;
-
- tempebx = pVBInfo->VDE ;
-
- if ( tempcx & SetCRT2ToHiVisionTV )
- {
- if ( !( temp & 0xE000 ) )
- tempbx = tempbx >> 1 ;
- }
-
- tempcx = pVBInfo->RVBHRS ;
- temp = tempcx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x18 , temp );
-
- tempeax = pVBInfo->VGAVDE ;
- tempcx |= 0x04000 ;
-
-
- if ( tempeax <= tempebx )
- {
- tempcx=(tempcx&(~0x4000));
- tempeax = pVBInfo->VGAVDE ;
- }
- else
- {
- tempeax -= tempebx ;
- }
-
-
- templong = ( tempeax * 256 * 1024 ) % tempebx ;
- tempeax = ( tempeax * 256 * 1024 ) / tempebx ;
- tempebx = tempeax ;
-
- if ( templong != 0 )
- {
- tempebx++ ;
- }
-
-
- temp = (unsigned short)(tempebx & 0x000000FF);
- XGINew_SetReg1( pVBInfo->Part4Port , 0x1B , temp ) ;
-
- temp = (unsigned short)((tempebx & 0x0000FF00) >> 8);
- XGINew_SetReg1( pVBInfo->Part4Port , 0x1A , temp ) ;
- tempbx = (unsigned short)(tempebx >> 16);
- temp = tempbx & 0x00FF ;
- temp = temp << 4 ;
- temp |= ( ( tempcx & 0xFF00 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x19 , temp ) ;
-
- /* 301b */
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- temp = 0x0028 ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x1C , temp ) ;
- tempax = pVBInfo->VGAHDE ;
- if ( modeflag & HalfDCLK )
- {
- tempax = tempax >> 1 ;
- }
-
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- tempax = tempax >> 1 ;
-
- /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- {
- if ( tempax > 800 )
- tempax -= 800 ;
- }
- else
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- if ( pVBInfo->VGAHDE == 1024 )
- tempax = ( tempax * 25 / 32 ) - 1 ;
- else
- tempax = ( tempax * 20 / 32 ) - 1 ;
- }
- }
- tempax -= 1 ;
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+ return;
-/*
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- if ( pVBInfo->VGAHDE == 1024 )
- tempax = ( tempax * 25 / 32 ) - 1 ;
- else
- tempax = ( tempax * 20 / 32 ) - 1 ;
- }
- }
- }
- else
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- if ( pVBInfo->VGAHDE == 1024 )
- tempax = ( tempax * 25 / 32 ) - 1 ;
- else
- tempax = ( tempax * 20 / 32 ) - 1 ;
- }
- }
- }
-*/
+ if (pVBInfo->TVInfo & SetPALMTV) {
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA);
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8);
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8);
+ }
- temp = ( tempax & 0xFF00 ) >> 8 ;
- temp = ( ( temp & 0x0003 ) << 4 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x1E , temp ) ;
- temp = ( tempax & 0x00FF ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x1D , temp ) ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x1E , 0x08 ) ;
- }
- }
- temp = 0x0036 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( !( pVBInfo->TVInfo & ( NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
- {
- temp |= 0x0001 ;
- if ( ( pVBInfo->VBInfo & SetInSlaveMode ) && ( !( pVBInfo->TVInfo & TVSimuMode ) ) )
- temp &= ( ~0x0001 ) ;
- }
- }
-
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x1F , 0x00C0 , temp ) ;
- tempbx = pVBInfo->HT ;
- if ( XGI_IsLCDDualLink( pVBInfo ) )
- tempbx = tempbx >> 1 ;
- tempbx = ( tempbx >> 1 ) - 2 ;
- temp = ( ( tempbx & 0x0700 ) >> 8 ) << 3 ;
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x21 , 0x00C0 , temp ) ;
- temp = tempbx & 0x00FF ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x22 , temp ) ;
- }
- /* end 301b */
-
- if ( pVBInfo->ISXPDOS == 0 )
- XGI_SetCRT2VCLK( ModeNo , ModeIdIndex , RefreshRateTableIndex, pVBInfo ) ;
-}
+ if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo
+ & SetCRT2ToYPbPr)) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ return;
+ tempdi = pVBInfo->HiTVGroup3Data;
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ tempdi = pVBInfo->HiTVGroup3Simu;
+ if (!(modeflag & Charx8Dot))
+ tempdi = pVBInfo->HiTVGroup3Text;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup5 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ tempdi = pVBInfo->Ren525pGroup3;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ tempdi = pVBInfo->Ren750pGroup3;
+
+ for (i = 0; i <= 0x3E; i++)
+ XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]);
+
+ if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f);
+ }
+ }
+ return;
+} /* {end of XGI_SetGroup3} */
+
+void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short Pindex ,
- Pdata ;
+ unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
+
+ unsigned long tempebx, tempeax, templong;
+
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+
+ temp = pVBInfo->RVBHCFACT;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp);
+
+ tempbx = pVBInfo->RVBHCMAX;
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp);
+ temp2 = ((tempbx & 0xFF00) >> 8) << 7;
+ tempcx = pVBInfo->VGAHT - 1;
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) << 3;
+ temp2 |= temp;
+
+ tempcx = pVBInfo->VGAVT - 1;
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV))
+ tempcx -= 5;
+
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp);
+ temp = temp2 | ((tempcx & 0xFF00) >> 8);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp);
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08);
+ tempcx = pVBInfo->VBInfo;
+ tempbx = pVBInfo->VGAHDE;
+
+ if (modeflag & HalfDCLK)
+ tempbx = tempbx >> 1;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ if (tempcx & SetCRT2ToHiVisionTV) {
+ temp = 0;
+ if (tempbx <= 1024)
+ temp = 0xA0;
+ if (tempbx == 1280)
+ temp = 0xC0;
+ } else if (tempcx & SetCRT2ToTV) {
+ temp = 0xA0;
+ if (tempbx <= 800)
+ temp = 0x80;
+ } else {
+ temp = 0x80;
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ temp = 0;
+ if (tempbx > 800)
+ temp = 0x60;
+ }
+ }
+
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
+ temp = 0x00;
+ if (pVBInfo->VGAHDE == 1280)
+ temp = 0x40;
+ if (pVBInfo->VGAHDE == 1024)
+ temp = 0x20;
+ }
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+
+ tempebx = pVBInfo->VDE;
- Pindex = pVBInfo->Part5Port ;
- Pdata = pVBInfo->Part5Port + 1 ;
- if ( pVBInfo->ModeType == ModeVGA )
- {
- if ( !( pVBInfo->VBInfo & ( SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag ) ) )
- {
- XGINew_EnableCRT2(pVBInfo) ;
- /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
- }
- }
- return ;
+ if (tempcx & SetCRT2ToHiVisionTV) {
+ if (!(temp & 0xE000))
+ tempbx = tempbx >> 1;
+ }
+
+ tempcx = pVBInfo->RVBHRS;
+ temp = tempcx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp);
+
+ tempeax = pVBInfo->VGAVDE;
+ tempcx |= 0x04000;
+
+ if (tempeax <= tempebx) {
+ tempcx = (tempcx & (~0x4000));
+ tempeax = pVBInfo->VGAVDE;
+ } else {
+ tempeax -= tempebx;
+ }
+
+ templong = (tempeax * 256 * 1024) % tempebx;
+ tempeax = (tempeax * 256 * 1024) / tempebx;
+ tempebx = tempeax;
+
+ if (templong != 0)
+ tempebx++;
+
+ temp = (unsigned short) (tempebx & 0x000000FF);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp);
+
+ temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp);
+ tempbx = (unsigned short) (tempebx >> 16);
+ temp = tempbx & 0x00FF;
+ temp = temp << 4;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp);
+
+ /* 301b */
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ temp = 0x0028;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp);
+ tempax = pVBInfo->VGAHDE;
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempax = tempax >> 1;
+
+ /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (tempax > 800)
+ tempax -= 800;
+ } else {
+ if (pVBInfo->VGAHDE > 800) {
+ if (pVBInfo->VGAHDE == 1024)
+ tempax = (tempax * 25 / 32) - 1;
+ else
+ tempax = (tempax * 20 / 32) - 1;
+ }
+ }
+ tempax -= 1;
+
+ /*
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) {
+ if (pVBInfo->VGAHDE > 800) {
+ if (pVBInfo->VGAHDE == 1024)
+ tempax = (tempax * 25 / 32) - 1;
+ else
+ tempax = (tempax * 20 / 32) - 1;
+ }
+ }
+ } else {
+ if (pVBInfo->VGAHDE > 800) {
+ if (pVBInfo->VGAHDE == 1024)
+ tempax = (tempax * 25 / 32) - 1;
+ else
+ tempax = (tempax * 20 / 32) - 1;
+ }
+ }
+ }
+ */
+
+ temp = (tempax & 0xFF00) >> 8;
+ temp = ((temp & 0x0003) << 4);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp);
+ temp = (tempax & 0x00FF);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+ if (pVBInfo->VGAHDE > 800)
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08);
+
+ }
+ temp = 0x0036;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->TVInfo & (NTSC1024x768
+ | SetYPbPrMode525p | SetYPbPrMode750p
+ | SetYPbPrMode1080i))) {
+ temp |= 0x0001;
+ if ((pVBInfo->VBInfo & SetInSlaveMode)
+ && (!(pVBInfo->TVInfo
+ & TVSimuMode)))
+ temp &= (~0x0001);
+ }
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
+ tempbx = pVBInfo->HT;
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+ tempbx = (tempbx >> 1) - 2;
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
+ temp = tempbx & 0x00FF;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp);
+ }
+ /* end 301b */
+
+ if (pVBInfo->ISXPDOS == 0)
+ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
}
+void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short Pindex, Pdata;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLcdPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void *XGI_GetLcdPtr(unsigned short BX,
- unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short i ,
- tempdx ,
- tempcx ,
- tempbx ,
- tempal ,
- modeflag ,
- table ;
-
- struct XGI330_LCDDataTablStruct *tempdi = 0 ;
-
-
- tempbx = BX;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
- }
-
- tempal = tempal & 0x0f ;
-
- if ( tempbx <= 1 ) /* ExpLink */
- {
- if ( ModeNo <= 0x13 )
- {
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ; /* find no Ext_CRT2CRTC2 */
- }
- else
- {
- tempal= pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- if ( ModeNo <= 0x13 )
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC2 ;
- else
- tempal= pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC2 ;
- }
-
- if ( tempbx & 0x01 )
- tempal = ( tempal >> 4 ) ;
-
- tempal = ( tempal & 0x0f ) ;
- }
-
- tempcx = LCDLenList[ tempbx ] ; /* mov cl,byte ptr cs:LCDLenList[bx] */
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD ) /* ScaleLCD */
- {
- if ( ( tempbx == 5 ) || ( tempbx ) == 7 )
- tempcx = LCDDesDataLen2 ;
- else if ( ( tempbx == 3 ) || ( tempbx == 8 ) )
- tempcx = LVDSDesDataLen2 ;
- }
- /* mov di, word ptr cs:LCDDataList[bx] */
- /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
-
- switch( tempbx )
- {
- case 0:
- tempdi = XGI_EPLLCDCRT1Ptr_H ;
- break ;
- case 1:
- tempdi = XGI_EPLLCDCRT1Ptr_V ;
- break ;
- case 2:
- tempdi = XGI_EPLLCDDataPtr ;
- break ;
- case 3:
- tempdi = XGI_EPLLCDDesDataPtr ;
- break ;
- case 4:
- tempdi = XGI_LCDDataTable ;
- break ;
- case 5:
- tempdi = XGI_LCDDesDataTable ;
- break ;
- case 6:
- tempdi = XGI_EPLCHLCDRegPtr ;
- break ;
- case 7:
- case 8:
- case 9:
- tempdi = 0 ;
- break ;
- default:
- break ;
- }
-
- if ( tempdi == 0x00 ) /* OEMUtil */
- return 0 ;
-
- table = tempbx ;
- i = 0 ;
-
- while( tempdi[ i ].PANELID != 0xff )
- {
- tempdx = pVBInfo->LCDResInfo ;
- if ( tempbx & 0x0080 ) /* OEMUtil */
- {
- tempbx &= ( ~0x0080 ) ;
- tempdx = pVBInfo->LCDTypeInfo ;
- }
-
- if ( pVBInfo->LCDInfo & EnableScalingLCD )
- tempdx &= ( ~PanelResInfo ) ;
-
- if ( tempdi[ i ].PANELID == tempdx )
- {
- tempbx = tempdi[ i ].MASK ;
- tempdx = pVBInfo->LCDInfo ;
-
- if ( ModeNo <= 0x13 ) /* alan 09/10/2003 */
- tempdx |= SetLCDStdMode ;
-
- if ( modeflag & HalfDCLK )
- tempdx |= SetLCDLowResolution ;
-
- tempbx &= tempdx;
- if ( tempbx == tempdi[ i ].CAP )
- break ;
- }
- i++ ;
- }
-
- if ( table == 0 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_LVDSCRT11024x768_1_H[ tempal ] ;
- break ;
- case 1:
- return &XGI_LVDSCRT11024x768_2_H[ tempal ] ;
- break ;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_H[ tempal ] ;
- break ;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_H[ tempal ] ;
- break ;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_H[ tempal ] ;
- break ;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_H[ tempal ] ;
- break ;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_H[ tempal ] ;
- break ;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Hx75[ tempal ] ;
- break ;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Hx75[ tempal ] ;
- break ;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Hx75[ tempal ] ;
- break ;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Hx75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 1 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_LVDSCRT11024x768_1_V[ tempal ] ;
- break ;
- case 1:
- return &XGI_LVDSCRT11024x768_2_V[ tempal ] ;
- break ;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_V[ tempal ] ;
- break ;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_V[ tempal ] ;
- break ;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_V[ tempal ] ;
- break ;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_V[ tempal ] ;
- break ;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_V[ tempal ] ;
- break ;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Vx75[ tempal ] ;
- break ;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Vx75[ tempal ] ;
- break ;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Vx75[ tempal ] ;
- break ;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Vx75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 2 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_LVDS1024x768Data_1[ tempal ] ;
- break ;
- case 1:
- return &XGI_LVDS1024x768Data_2[ tempal ] ;
- break ;
- case 2:
- return &XGI_LVDS1280x1024Data_1[ tempal ] ;
- break ;
- case 3:
- return &XGI_LVDS1280x1024Data_2[ tempal ] ;
- break ;
- case 4:
- return &XGI_LVDS1400x1050Data_1[ tempal ] ;
- break ;
- case 5:
- return &XGI_LVDS1400x1050Data_2[ tempal ] ;
- break ;
- case 6:
- return &XGI_LVDS1600x1200Data_1[ tempal ] ;
- break ;
- case 7:
- return &XGI_LVDSNoScalingData[ tempal ] ;
- break ;
- case 8:
- return &XGI_LVDS1024x768Data_1x75[ tempal ] ;
- break ;
- case 9:
- return &XGI_LVDS1024x768Data_2x75[ tempal ] ;
- break ;
- case 10:
- return &XGI_LVDS1280x1024Data_1x75[ tempal ] ;
- break ;
- case 11:
- return &XGI_LVDS1280x1024Data_2x75[ tempal ] ;
- break ;
- case 12:
- return &XGI_LVDSNoScalingDatax75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 3 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_LVDS1024x768Des_1[ tempal ] ;
- break ;
- case 1:
- return &XGI_LVDS1024x768Des_3[ tempal ] ;
- break ;
- case 2:
- return &XGI_LVDS1024x768Des_2[ tempal ] ;
- break ;
- case 3:
- return &XGI_LVDS1280x1024Des_1[ tempal ] ;
- break ;
- case 4:
- return &XGI_LVDS1280x1024Des_2[ tempal ] ;
- break ;
- case 5:
- return &XGI_LVDS1400x1050Des_1[ tempal ] ;
- break ;
- case 6:
- return &XGI_LVDS1400x1050Des_2[ tempal ] ;
- break ;
- case 7:
- return &XGI_LVDS1600x1200Des_1[ tempal ] ;
- break ;
- case 8:
- return &XGI_LVDSNoScalingDesData[ tempal ] ;
- break ;
- case 9:
- return &XGI_LVDS1024x768Des_1x75[ tempal ] ;
- break ;
- case 10:
- return &XGI_LVDS1024x768Des_3x75[ tempal ] ;
- break ;
- case 11:
- return &XGI_LVDS1024x768Des_2x75[ tempal ] ;
- break;
- case 12:
- return &XGI_LVDS1280x1024Des_1x75[ tempal ] ;
- break ;
- case 13:
- return &XGI_LVDS1280x1024Des_2x75[ tempal ] ;
- break ;
- case 14:
- return &XGI_LVDSNoScalingDesDatax75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 4 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_ExtLCD1024x768Data[ tempal ] ;
- break ;
- case 1:
- return &XGI_StLCD1024x768Data[ tempal ] ;
- break ;
- case 2:
- return &XGI_CetLCD1024x768Data[ tempal ] ;
- break ;
- case 3:
- return &XGI_ExtLCD1280x1024Data[ tempal ] ;
- break ;
- case 4:
- return &XGI_StLCD1280x1024Data[ tempal ] ;
- break ;
- case 5:
- return &XGI_CetLCD1280x1024Data[ tempal ] ;
- break ;
- case 6:
- return &XGI_ExtLCD1400x1050Data[ tempal ] ;
- break ;
- case 7:
- return &XGI_StLCD1400x1050Data[ tempal ] ;
- break ;
- case 8:
- return &XGI_CetLCD1400x1050Data[ tempal ] ;
- break ;
- case 9:
- return &XGI_ExtLCD1600x1200Data[ tempal ] ;
- break ;
- case 10:
- return &XGI_StLCD1600x1200Data[ tempal ] ;
- break ;
- case 11:
- return &XGI_NoScalingData[ tempal ] ;
- break ;
- case 12:
- return &XGI_ExtLCD1024x768x75Data[ tempal ] ;
- break ;
- case 13:
- return &XGI_ExtLCD1024x768x75Data[ tempal ] ;
- break ;
- case 14:
- return &XGI_CetLCD1024x768x75Data[ tempal ] ;
- break ;
- case 15:
- return &XGI_ExtLCD1280x1024x75Data[ tempal ] ;
- break ;
- case 16:
- return &XGI_StLCD1280x1024x75Data[ tempal ] ;
- break;
- case 17:
- return &XGI_CetLCD1280x1024x75Data[ tempal ] ;
- break;
- case 18:
- return &XGI_NoScalingDatax75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 5 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_ExtLCDDes1024x768Data[ tempal ] ;
- break ;
- case 1:
- return &XGI_StLCDDes1024x768Data[ tempal ] ;
- break ;
- case 2:
- return &XGI_CetLCDDes1024x768Data[ tempal ] ;
- break ;
- case 3:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_ExtLCDDLDes1280x1024Data[ tempal ] ;
- else
- return &XGI_ExtLCDDes1280x1024Data[ tempal ] ;
- break ;
- case 4:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_StLCDDLDes1280x1024Data[ tempal ] ;
- else
- return &XGI_StLCDDes1280x1024Data[ tempal ] ;
- break ;
- case 5:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_CetLCDDLDes1280x1024Data[ tempal ] ;
- else
- return &XGI_CetLCDDes1280x1024Data[ tempal ] ;
- break ;
- case 6:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_ExtLCDDLDes1400x1050Data[ tempal ] ;
- else
- return &XGI_ExtLCDDes1400x1050Data[ tempal ] ;
- break ;
- case 7:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_StLCDDLDes1400x1050Data[ tempal ] ;
- else
- return &XGI_StLCDDes1400x1050Data[ tempal ] ;
- break ;
- case 8:
- return &XGI_CetLCDDes1400x1050Data[ tempal ] ;
- break ;
- case 9:
- return &XGI_CetLCDDes1400x1050Data2[ tempal ] ;
- break ;
- case 10:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_ExtLCDDLDes1600x1200Data[ tempal ] ;
- else
- return &XGI_ExtLCDDes1600x1200Data[ tempal ] ;
- break ;
- case 11:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_StLCDDLDes1600x1200Data[ tempal ] ;
- else
- return &XGI_StLCDDes1600x1200Data[ tempal ] ;
- break ;
- case 12:
- return &XGI_NoScalingDesData[ tempal ] ;
- break;
- case 13:
- return &XGI_ExtLCDDes1024x768x75Data[ tempal ] ;
- break ;
- case 14:
- return &XGI_StLCDDes1024x768x75Data[ tempal ] ;
- break ;
- case 15:
- return &XGI_CetLCDDes1024x768x75Data[ tempal ] ;
- break ;
- case 16:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_ExtLCDDLDes1280x1024x75Data[ tempal ] ;
- else
- return &XGI_ExtLCDDes1280x1024x75Data[ tempal ] ;
- break ;
- case 17:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_StLCDDLDes1280x1024x75Data[ tempal ] ;
- else
- return &XGI_StLCDDes1280x1024x75Data[ tempal ] ;
- break ;
- case 18:
- if ( ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) )
- return &XGI_CetLCDDLDes1280x1024x75Data[ tempal ] ;
- else
- return &XGI_CetLCDDes1280x1024x75Data[ tempal ] ;
- break ;
- case 19:
- return &XGI_NoScalingDesDatax75[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if ( table == 6 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_CH7017LV1024x768[ tempal ] ;
- break ;
- case 1:
- return &XGI_CH7017LV1400x1050[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- return 0 ;
+ Pindex = pVBInfo->Part5Port;
+ Pdata = pVBInfo->Part5Port + 1;
+ if (pVBInfo->ModeType == ModeVGA) {
+ if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
+ | CRT2DisplayFlag))) {
+ XGINew_EnableCRT2(pVBInfo);
+ /* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */
+ }
+ }
+ return;
}
+void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short i , tempdx , tempbx , tempal , modeflag , table ;
- struct XGI330_TVDataTablStruct *tempdi = 0 ;
-
- tempbx = BX ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- tempal = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
- }
-
- tempal = tempal & 0x3f ;
- table = tempbx ;
-
- switch( tempbx )
- {
- case 0:
- tempdi = 0 ; /*EPLCHTVCRT1Ptr_H;*/
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- tempdi = XGI_EPLCHTVCRT1Ptr;
- }
- break ;
- case 1:
- tempdi = 0 ; /*EPLCHTVCRT1Ptr_V;*/
- if ( pVBInfo->IF_DEF_CH7007 == 1 )
- {
- tempdi = XGI_EPLCHTVCRT1Ptr;
- }
- break ;
- case 2:
- tempdi = XGI_EPLCHTVDataPtr ;
- break ;
- case 3:
- tempdi = 0 ;
- break ;
- case 4:
- tempdi = XGI_TVDataTable ;
- break ;
- case 5:
- tempdi = 0 ;
- break ;
- case 6:
- tempdi = XGI_EPLCHTVRegPtr ;
- break ;
- default:
- break ;
- }
-
- if ( tempdi == 0x00 ) /* OEMUtil */
- return( 0 ) ;
-
- tempdx = pVBInfo->TVInfo ;
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- tempdx = tempdx | SetTVLockMode ;
-
- if ( modeflag & HalfDCLK )
- tempdx = tempdx | SetTVLowResolution ;
-
- i = 0 ;
-
- while( tempdi[ i ].MASK != 0xffff )
- {
- if ( ( tempdx & tempdi[ i ].MASK ) == tempdi[ i ].CAP )
- break ;
- i++ ;
- }
-
- if ( table == 0x00 ) /* 07/05/22 */
- {
- }
- else if ( table == 0x01 )
- {
- }
- else if ( table == 0x04 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_ExtPALData[ tempal ] ;
- break ;
- case 1:
- return &XGI_ExtNTSCData[ tempal ] ;
- break ;
- case 2:
- return &XGI_StPALData[ tempal ] ;
- break ;
- case 3:
- return &XGI_StNTSCData[ tempal ] ;
- break ;
- case 4:
- return &XGI_ExtHiTVData[ tempal ] ;
- break ;
- case 5:
- return &XGI_St2HiTVData[ tempal ] ;
- break ;
- case 6:
- return &XGI_ExtYPbPr525iData[ tempal ] ;
- break ;
- case 7:
- return &XGI_ExtYPbPr525pData[ tempal ] ;
- break ;
- case 8:
- return &XGI_ExtYPbPr750pData[ tempal ] ;
- break ;
- case 9:
- return &XGI_StYPbPr525iData[ tempal ] ;
- break ;
- case 10:
- return &XGI_StYPbPr525pData[ tempal ] ;
- break ;
- case 11:
- return &XGI_StYPbPr750pData[ tempal ] ;
- break;
- case 12: /* avoid system hang */
- return &XGI_ExtNTSCData[ tempal ] ;
- break ;
- case 13:
- return &XGI_St1HiTVData[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if( table == 0x02 )
- {
- switch( tempdi[ i ].DATAPTR )
- {
- case 0:
- return &XGI_CHTVUNTSCData[ tempal ] ;
- break ;
- case 1:
- return &XGI_CHTVONTSCData[ tempal ] ;
- break ;
- case 2:
- return &XGI_CHTVUPALData[ tempal ] ;
- break ;
- case 3:
- return &XGI_CHTVOPALData[ tempal ] ;
- break ;
- default:
- break ;
- }
- }
- else if( table == 0x06 )
- {
- }
- return( 0 ) ;
+ struct XGI330_LCDDataTablStruct *tempdi = NULL;
+
+ tempbx = BX;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempal = tempal & 0x0f;
+
+ if (tempbx <= 1) { /* ExpLink */
+ if (ModeNo <= 0x13) {
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
+ } else {
+ tempal
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (ModeNo <= 0x13)
+ tempal
+ = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
+ else
+ tempal
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
+ }
+
+ if (tempbx & 0x01)
+ tempal = (tempal >> 4);
+
+ tempal = (tempal & 0x0f);
+ }
+
+ tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+ if ((tempbx == 5) || (tempbx) == 7)
+ tempcx = LCDDesDataLen2;
+ else if ((tempbx == 3) || (tempbx == 8))
+ tempcx = LVDSDesDataLen2;
+ }
+ /* mov di, word ptr cs:LCDDataList[bx] */
+ /* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
+
+ switch (tempbx) {
+ case 0:
+ tempdi = XGI_EPLLCDCRT1Ptr_H;
+ break;
+ case 1:
+ tempdi = XGI_EPLLCDCRT1Ptr_V;
+ break;
+ case 2:
+ tempdi = XGI_EPLLCDDataPtr;
+ break;
+ case 3:
+ tempdi = XGI_EPLLCDDesDataPtr;
+ break;
+ case 4:
+ tempdi = XGI_LCDDataTable;
+ break;
+ case 5:
+ tempdi = XGI_LCDDesDataTable;
+ break;
+ case 6:
+ tempdi = XGI_EPLCHLCDRegPtr;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ tempdi = NULL;
+ break;
+ default:
+ break;
+ }
+
+ if (tempdi == NULL) /* OEMUtil */
+ return NULL;
+
+ table = tempbx;
+ i = 0;
+
+ while (tempdi[i].PANELID != 0xff) {
+ tempdx = pVBInfo->LCDResInfo;
+ if (tempbx & 0x0080) { /* OEMUtil */
+ tempbx &= (~0x0080);
+ tempdx = pVBInfo->LCDTypeInfo;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempdx &= (~PanelResInfo);
+
+ if (tempdi[i].PANELID == tempdx) {
+ tempbx = tempdi[i].MASK;
+ tempdx = pVBInfo->LCDInfo;
+
+ if (ModeNo <= 0x13) /* alan 09/10/2003 */
+ tempdx |= SetLCDStdMode;
+
+ if (modeflag & HalfDCLK)
+ tempdx |= SetLCDLowResolution;
+
+ tempbx &= tempdx;
+ if (tempbx == tempdi[i].CAP)
+ break;
+ }
+ i++;
+ }
+
+ if (table == 0) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDSCRT11024x768_1_H[tempal];
+ break;
+ case 1:
+ return &XGI_LVDSCRT11024x768_2_H[tempal];
+ break;
+ case 2:
+ return &XGI_LVDSCRT11280x1024_1_H[tempal];
+ break;
+ case 3:
+ return &XGI_LVDSCRT11280x1024_2_H[tempal];
+ break;
+ case 4:
+ return &XGI_LVDSCRT11400x1050_1_H[tempal];
+ break;
+ case 5:
+ return &XGI_LVDSCRT11400x1050_2_H[tempal];
+ break;
+ case 6:
+ return &XGI_LVDSCRT11600x1200_1_H[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 1) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDSCRT11024x768_1_V[tempal];
+ break;
+ case 1:
+ return &XGI_LVDSCRT11024x768_2_V[tempal];
+ break;
+ case 2:
+ return &XGI_LVDSCRT11280x1024_1_V[tempal];
+ break;
+ case 3:
+ return &XGI_LVDSCRT11280x1024_2_V[tempal];
+ break;
+ case 4:
+ return &XGI_LVDSCRT11400x1050_1_V[tempal];
+ break;
+ case 5:
+ return &XGI_LVDSCRT11400x1050_2_V[tempal];
+ break;
+ case 6:
+ return &XGI_LVDSCRT11600x1200_1_V[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 2) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDS1024x768Data_1[tempal];
+ break;
+ case 1:
+ return &XGI_LVDS1024x768Data_2[tempal];
+ break;
+ case 2:
+ return &XGI_LVDS1280x1024Data_1[tempal];
+ break;
+ case 3:
+ return &XGI_LVDS1280x1024Data_2[tempal];
+ break;
+ case 4:
+ return &XGI_LVDS1400x1050Data_1[tempal];
+ break;
+ case 5:
+ return &XGI_LVDS1400x1050Data_2[tempal];
+ break;
+ case 6:
+ return &XGI_LVDS1600x1200Data_1[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSNoScalingData[tempal];
+ break;
+ case 8:
+ return &XGI_LVDS1024x768Data_1x75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDS1024x768Data_2x75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDS1280x1024Data_1x75[tempal];
+ break;
+ case 11:
+ return &XGI_LVDS1280x1024Data_2x75[tempal];
+ break;
+ case 12:
+ return &XGI_LVDSNoScalingDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 3) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDS1024x768Des_1[tempal];
+ break;
+ case 1:
+ return &XGI_LVDS1024x768Des_3[tempal];
+ break;
+ case 2:
+ return &XGI_LVDS1024x768Des_2[tempal];
+ break;
+ case 3:
+ return &XGI_LVDS1280x1024Des_1[tempal];
+ break;
+ case 4:
+ return &XGI_LVDS1280x1024Des_2[tempal];
+ break;
+ case 5:
+ return &XGI_LVDS1400x1050Des_1[tempal];
+ break;
+ case 6:
+ return &XGI_LVDS1400x1050Des_2[tempal];
+ break;
+ case 7:
+ return &XGI_LVDS1600x1200Des_1[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSNoScalingDesData[tempal];
+ break;
+ case 9:
+ return &XGI_LVDS1024x768Des_1x75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDS1024x768Des_3x75[tempal];
+ break;
+ case 11:
+ return &XGI_LVDS1024x768Des_2x75[tempal];
+ break;
+ case 12:
+ return &XGI_LVDS1280x1024Des_1x75[tempal];
+ break;
+ case 13:
+ return &XGI_LVDS1280x1024Des_2x75[tempal];
+ break;
+ case 14:
+ return &XGI_LVDSNoScalingDesDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 4) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtLCD1024x768Data[tempal];
+ break;
+ case 1:
+ return &XGI_StLCD1024x768Data[tempal];
+ break;
+ case 2:
+ return &XGI_CetLCD1024x768Data[tempal];
+ break;
+ case 3:
+ return &XGI_ExtLCD1280x1024Data[tempal];
+ break;
+ case 4:
+ return &XGI_StLCD1280x1024Data[tempal];
+ break;
+ case 5:
+ return &XGI_CetLCD1280x1024Data[tempal];
+ break;
+ case 6:
+ return &XGI_ExtLCD1400x1050Data[tempal];
+ break;
+ case 7:
+ return &XGI_StLCD1400x1050Data[tempal];
+ break;
+ case 8:
+ return &XGI_CetLCD1400x1050Data[tempal];
+ break;
+ case 9:
+ return &XGI_ExtLCD1600x1200Data[tempal];
+ break;
+ case 10:
+ return &XGI_StLCD1600x1200Data[tempal];
+ break;
+ case 11:
+ return &XGI_NoScalingData[tempal];
+ break;
+ case 12:
+ return &XGI_ExtLCD1024x768x75Data[tempal];
+ break;
+ case 13:
+ return &XGI_ExtLCD1024x768x75Data[tempal];
+ break;
+ case 14:
+ return &XGI_CetLCD1024x768x75Data[tempal];
+ break;
+ case 15:
+ return &XGI_ExtLCD1280x1024x75Data[tempal];
+ break;
+ case 16:
+ return &XGI_StLCD1280x1024x75Data[tempal];
+ break;
+ case 17:
+ return &XGI_CetLCD1280x1024x75Data[tempal];
+ break;
+ case 18:
+ return &XGI_NoScalingDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 5) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtLCDDes1024x768Data[tempal];
+ break;
+ case 1:
+ return &XGI_StLCDDes1024x768Data[tempal];
+ break;
+ case 2:
+ return &XGI_CetLCDDes1024x768Data[tempal];
+ break;
+ case 3:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_ExtLCDDes1280x1024Data[tempal];
+ break;
+ case 4:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_StLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_StLCDDes1280x1024Data[tempal];
+ break;
+ case 5:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_CetLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_CetLCDDes1280x1024Data[tempal];
+ break;
+ case 6:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1400x1050Data[tempal];
+ else
+ return &XGI_ExtLCDDes1400x1050Data[tempal];
+ break;
+ case 7:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_StLCDDLDes1400x1050Data[tempal];
+ else
+ return &XGI_StLCDDes1400x1050Data[tempal];
+ break;
+ case 8:
+ return &XGI_CetLCDDes1400x1050Data[tempal];
+ break;
+ case 9:
+ return &XGI_CetLCDDes1400x1050Data2[tempal];
+ break;
+ case 10:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1600x1200Data[tempal];
+ else
+ return &XGI_ExtLCDDes1600x1200Data[tempal];
+ break;
+ case 11:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_StLCDDLDes1600x1200Data[tempal];
+ else
+ return &XGI_StLCDDes1600x1200Data[tempal];
+ break;
+ case 12:
+ return &XGI_NoScalingDesData[tempal];
+ break;
+ case 13:
+ return &XGI_ExtLCDDes1024x768x75Data[tempal];
+ break;
+ case 14:
+ return &XGI_StLCDDes1024x768x75Data[tempal];
+ break;
+ case 15:
+ return &XGI_CetLCDDes1024x768x75Data[tempal];
+ break;
+ case 16:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_ExtLCDDes1280x1024x75Data[tempal];
+ break;
+ case 17:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_StLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_StLCDDes1280x1024x75Data[tempal];
+ break;
+ case 18:
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
+ & VB_XGI302LV))
+ return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_CetLCDDes1280x1024x75Data[tempal];
+ break;
+ case 19:
+ return &XGI_NoScalingDesDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 6) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_CH7017LV1024x768[tempal];
+ break;
+ case 1:
+ return &XGI_CH7017LV1400x1050[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
}
+void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, tempdx, tempbx, tempal, modeflag, table;
+ struct XGI330_TVDataTablStruct *tempdi = NULL;
+
+ tempbx = BX;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempal = tempal & 0x3f;
+ table = tempbx;
+
+ switch (tempbx) {
+ case 0:
+ tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
+ if (pVBInfo->IF_DEF_CH7007 == 1)
+ tempdi = XGI_EPLCHTVCRT1Ptr;
+
+ break;
+ case 1:
+ tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
+ if (pVBInfo->IF_DEF_CH7007 == 1)
+ tempdi = XGI_EPLCHTVCRT1Ptr;
+
+ break;
+ case 2:
+ tempdi = XGI_EPLCHTVDataPtr;
+ break;
+ case 3:
+ tempdi = NULL;
+ break;
+ case 4:
+ tempdi = XGI_TVDataTable;
+ break;
+ case 5:
+ tempdi = NULL;
+ break;
+ case 6:
+ tempdi = XGI_EPLCHTVRegPtr;
+ break;
+ default:
+ break;
+ }
+
+ if (tempdi == NULL) /* OEMUtil */
+ return NULL;
+
+ tempdx = pVBInfo->TVInfo;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempdx = tempdx | SetTVLockMode;
+
+ if (modeflag & HalfDCLK)
+ tempdx = tempdx | SetTVLowResolution;
+
+ i = 0;
+
+ while (tempdi[i].MASK != 0xffff) {
+ if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
+ break;
+ i++;
+ }
+
+ if (table == 0x00) { /* 07/05/22 */
+ } else if (table == 0x01) {
+ } else if (table == 0x04) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtPALData[tempal];
+ break;
+ case 1:
+ return &XGI_ExtNTSCData[tempal];
+ break;
+ case 2:
+ return &XGI_StPALData[tempal];
+ break;
+ case 3:
+ return &XGI_StNTSCData[tempal];
+ break;
+ case 4:
+ return &XGI_ExtHiTVData[tempal];
+ break;
+ case 5:
+ return &XGI_St2HiTVData[tempal];
+ break;
+ case 6:
+ return &XGI_ExtYPbPr525iData[tempal];
+ break;
+ case 7:
+ return &XGI_ExtYPbPr525pData[tempal];
+ break;
+ case 8:
+ return &XGI_ExtYPbPr750pData[tempal];
+ break;
+ case 9:
+ return &XGI_StYPbPr525iData[tempal];
+ break;
+ case 10:
+ return &XGI_StYPbPr525pData[tempal];
+ break;
+ case 11:
+ return &XGI_StYPbPr750pData[tempal];
+ break;
+ case 12: /* avoid system hang */
+ return &XGI_ExtNTSCData[tempal];
+ break;
+ case 13:
+ return &XGI_St1HiTVData[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 0x02) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_CHTVUNTSCData[tempal];
+ break;
+ case 1:
+ return &XGI_CHTVONTSCData[tempal];
+ break;
+ case 2:
+ return &XGI_CHTVUPALData[tempal];
+ break;
+ case 3:
+ return &XGI_CHTVOPALData[tempal];
+ break;
+ default:
+ break;
+ }
+ } else if (table == 0x06) {
+ }
+ return NULL;
+}
/* --------------------------------------------------------------------- */
/* Function : XGI_BacklightByDrv */
@@ -7805,16 +6653,15 @@ void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
/* --------------------------------------------------------------------- */
unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo)
{
- unsigned char tempah ;
+ unsigned char tempah;
- tempah = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x3A) ;
- if (tempah & BacklightControlBit)
- return 1;
- else
- return 0;
+ tempah = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x3A);
+ if (tempah & BacklightControlBit)
+ return 1;
+ else
+ return 0;
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_FirePWDDisable */
/* Input : */
@@ -7824,7 +6671,7 @@ unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo)
/*
void XGI_FirePWDDisable(struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x00, 0xFC);
}
*/
@@ -7836,35 +6683,22 @@ void XGI_FirePWDDisable(struct vb_device_info *pVBInfo)
/* --------------------------------------------------------------------- */
void XGI_FirePWDEnable(struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x26 , 0x03 , 0xFC ) ;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnableGatingCRT */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x40 ) ;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisableGatingCRT */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x63 , 0xBF , 0x00 ) ;
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetPanelDelay */
/* Input : */
@@ -7877,24 +6711,23 @@ void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct v
/* --------------------------------------------------------------------- */
void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
{
- unsigned short index ;
+ unsigned short index;
- index = XGI_GetLCDCapPtr(pVBInfo) ;
+ index = XGI_GetLCDCapPtr(pVBInfo);
- if ( tempbl == 1 )
- XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S1, pVBInfo ) ;
+ if (tempbl == 1)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo);
- if ( tempbl == 2 )
- XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S2, pVBInfo ) ;
+ if (tempbl == 2)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo);
- if ( tempbl == 3 )
- XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S3, pVBInfo ) ;
+ if (tempbl == 3)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo);
- if ( tempbl == 4 )
- XGINew_LCD_Wait_Time( pVBInfo->LCDCapList[ index ].PSC_S4, pVBInfo ) ;
+ if (tempbl == 4)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo);
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetPanelPower */
/* Input : */
@@ -7905,25 +6738,25 @@ void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
/* = 1011b = 0Bh ; Backlight off, Power on */
/* = 1111b = 0Fh ; Backlight off, Power off */
/* --------------------------------------------------------------------- */
-void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo)
+void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
{
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x26 , tempbl , tempah ) ;
- else
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x11 , tempbl , tempah ) ;
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah);
+ else
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah);
}
-unsigned char XG21GPIODataTransfer(unsigned char ujDate)
+static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
{
- unsigned char ujRet = 0;
- unsigned char i = 0;
+ unsigned char ujRet = 0;
+ unsigned char i = 0;
- for (i=0; i<8; i++)
- {
- ujRet = ujRet << 1;
- /* ujRet |= GETBITS(ujDate >> i, 0:0); */
- ujRet |= (ujDate >> i) & 1;
- }
+ for (i = 0; i < 8; i++) {
+ ujRet = ujRet << 1;
+ /* ujRet |= GETBITS(ujDate >> i, 0:0); */
+ ujRet |= (ujDate >> i) & 1;
+ }
return ujRet;
}
@@ -7936,17 +6769,17 @@ unsigned char XG21GPIODataTransfer(unsigned char ujDate)
/*----------------------------------------------------------------------------*/
unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
{
- unsigned char CR4A, temp;
+ unsigned char CR4A, temp;
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x23 ) ; /* enable GPIO write */
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
- temp = XG21GPIODataTransfer(temp);
- temp &= 0x23;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x4A , CR4A ) ;
- return temp;
+ temp = XG21GPIODataTransfer(temp);
+ temp &= 0x23;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+ return temp;
}
/*----------------------------------------------------------------------------*/
@@ -7957,19 +6790,19 @@ unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
/*----------------------------------------------------------------------------*/
unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
{
- unsigned char CR4A, CRB4, temp;
+ unsigned char CR4A, CRB4, temp;
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x0C ) ; /* enable GPIO write */
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
- temp &= 0x0C;
- temp >>= 2;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x4A , CR4A ) ;
- CRB4 = XGINew_GetReg1( pVBInfo->P3d4 , 0xB4 ) ;
- temp |= ((CRB4&0x04)<<3);
- return temp;
+ temp &= 0x0C;
+ temp >>= 2;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
+ CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4);
+ temp |= ((CRB4 & 0x04) << 3);
+ return temp;
}
/*----------------------------------------------------------------------------*/
/* input */
@@ -7980,70 +6813,71 @@ unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
/* 000010b : clear bit 1, to set bit1 */
/* 000001b : clear bit 0, to set bit0 */
/*----------------------------------------------------------------------------*/
-void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo)
+void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
{
- unsigned char CR4A, temp;
+ unsigned char CR4A, temp;
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- tempbh &= 0x23;
- tempbl &= 0x23;
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ tempbh &= 0x23;
+ tempbl &= 0x23;
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
- if (tempbh&0x20)
- {
- temp = (tempbl>>4)&0x02;
+ if (tempbh & 0x20) {
+ temp = (tempbl >> 4) & 0x02;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
- }
+ }
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x48 ) ;
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
- temp = XG21GPIODataTransfer(temp);
- temp &= ~tempbh;
- temp |= tempbl;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x48 , temp ) ;
+ temp = XG21GPIODataTransfer(temp);
+ temp &= ~tempbh;
+ temp |= tempbl;
+ XGINew_SetReg1(pVBInfo->P3d4, 0x48, temp);
}
-void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo)
+void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
{
- unsigned char CR4A, temp;
- unsigned short tempbh0, tempbl0;
+ unsigned char CR4A, temp;
+ unsigned short tempbh0, tempbl0;
- tempbh0 = tempbh;
- tempbl0 = tempbl;
- tempbh0 &= 0x20;
- tempbl0 &= 0x20;
- tempbh0 >>= 3;
- tempbl0 >>= 3;
+ tempbh0 = tempbh;
+ tempbl0 = tempbl;
+ tempbh0 &= 0x20;
+ tempbl0 &= 0x20;
+ tempbh0 >>= 3;
+ tempbl0 >>= 3;
- if (tempbh&0x20)
- {
- temp = (tempbl>>4)&0x02;
+ if (tempbh & 0x20) {
+ temp = (tempbl >> 4) & 0x02;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
- }
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0xB4 , ~tempbh0 , tempbl0 ) ;
+ }
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
- CR4A = XGINew_GetReg1( pVBInfo->P3d4 , 0x4A ) ;
- tempbh &= 0x03;
- tempbl &= 0x03;
- tempbh <<= 2;
- tempbl <<= 2; /* GPIOC,GPIOD */
- XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x48 , ~tempbh , tempbl ) ;
+ CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
+ tempbh &= 0x03;
+ tempbl &= 0x03;
+ tempbh <<= 2;
+ tempbl <<= 2; /* GPIOC,GPIOD */
+ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
}
/* --------------------------------------------------------------------- */
unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo)
{
- unsigned short index ;
+ unsigned short index;
- index = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
- if (index < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))
- return index;
- return 0;
+ index = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
+ if (index < sizeof(XGI21_LCDCapList)
+ / sizeof(struct XGI21_LVDSCapStruct))
+ return index;
+ return 0;
}
/* --------------------------------------------------------------------- */
@@ -8056,472 +6890,470 @@ unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo)
/* : bl : 3 ; T3 : the duration between CPL off and signal off */
/* : bl : 4 ; T4 : the duration signal off and Vdd off */
/* --------------------------------------------------------------------- */
-void XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo)
+void XGI_XG21SetPanelDelay(unsigned short tempbl,
+ struct vb_device_info *pVBInfo)
{
- unsigned short index ;
+ unsigned short index;
- index = XGI_GetLVDSOEMTableIndex( pVBInfo );
- if ( tempbl == 1 )
- XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S1, pVBInfo ) ;
+ index = XGI_GetLVDSOEMTableIndex(pVBInfo);
+ if (tempbl == 1)
+ XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S1,
+ pVBInfo);
- if ( tempbl == 2 )
- XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S2, pVBInfo ) ;
+ if (tempbl == 2)
+ XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S2,
+ pVBInfo);
- if ( tempbl == 3 )
- XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S3, pVBInfo ) ;
+ if (tempbl == 3)
+ XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S3,
+ pVBInfo);
- if ( tempbl == 4 )
- XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S4, pVBInfo ) ;
+ if (tempbl == 4)
+ XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S4,
+ pVBInfo);
}
unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short xres ,
- yres ,
- colordepth ,
- modeflag ,
- resindex ,
- lvdstableindex;
-
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( ModeNo <= 0x13 )
- {
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- yres = pVBInfo->StResInfo[ resindex ].VTotal ;
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else
- {
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
- }
-
- if ( !( modeflag & Charx8Dot ) )
- {
- xres /= 9;
- xres *= 8;
- }
-
- if ( ModeNo > 0x13 )
- {
- if ( ( ModeNo>0x13 ) && ( modeflag & HalfDCLK ) )
- {
- xres *= 2 ;
- }
- if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
- {
- yres *= 2 ;
- }
- }
-
- lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
- if ( xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) )
- return 0;
-
- if ( yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE) )
- return 0;
-
- if ( ModeNo > 0x13 )
- {
- if ( ( xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) ) ||
- ( yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE)) )
- {
- colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
- if (colordepth > 2)
- return 0;
-
- }
- }
- return 1;
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ unsigned short xres, yres, colordepth, modeflag, resindex,
+ lvdstableindex;
+
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ } else {
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+ }
+
+ if (!(modeflag & Charx8Dot)) {
+ xres /= 9;
+ xres *= 8;
+ }
+
+ if (ModeNo > 0x13) {
+ if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
+ xres *= 2;
+
+ if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
+ yres *= 2;
+
+ }
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
+ if (xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
+ return 0;
+
+ if (yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))
+ return 0;
+
+ if (ModeNo > 0x13) {
+ if ((xres
+ != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
+ || (yres
+ != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))) {
+ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex,
+ pVBInfo);
+ if (colordepth > 2)
+ return 0;
+
+ }
+ }
+ return 1;
}
void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
{
- unsigned char temp;
+ unsigned char temp;
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ; /* D[0] 1: 18bit */
- temp = ( temp & 1 ) << 6;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0x40 , temp ) ; /* SR06[6] 18bit Dither */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
+ temp = (temp & 1) << 6;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
}
void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
{
- unsigned char temp;
+ unsigned char temp;
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ; /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
- temp = ( temp & 3 ) << 6;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x06 , ~0xc0 , temp & 0x80 ) ; /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+ temp = (temp & 3) << 6;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
}
void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned char temp, Miscdata;
- unsigned short xres ,
- yres ,
- modeflag ,
- resindex ,
- lvdstableindex ;
- unsigned short LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
- unsigned short LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
- unsigned short value;
-
- lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
-
- temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8);
- temp &= LCDPolarity;
- Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc) ;
-
- XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
-
- temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity) ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
-
- XGI_SetXG21FPBits(pVBInfo);
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( ModeNo <= 0x13 )
- {
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- yres = pVBInfo->StResInfo[ resindex ].VTotal ;
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else
- {
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
- }
-
- if (!( modeflag & Charx8Dot ))
- xres = xres * 8 / 9;
-
- LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
-
- LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
- if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
- {
- LVDSHBS -= xres/4 ;
- }
- if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
-
- LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
- if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
-
- LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
- if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
-
- LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
-
- LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
-
- LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
- if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
- {
- LVDSVBS += yres/2 ;
- }
- if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
-
- LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
- if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
-
- LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
- if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
-
- LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
-
- temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
-
- if (!( modeflag & Charx8Dot ))
- {
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x1 , 0x1 ) ;
- }
-
- /* HT SR0B[1:0] CR00 */
- value = ( LVDSHT >> 3 ) - 5;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
-
- /* HBS SR0B[5:4] CR02 */
- value = ( LVDSHBS >> 3 ) - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
-
- /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
- value = ( LVDSHBE >> 3 ) - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
-
- /* HRS SR0B[7:6] CR04 */
- value = ( LVDSHRS >> 3 ) + 2;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
-
- /* Panel HRS SR2F[1:0] SR2E[7:0] */
- value--;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
-
- /* HRE SR0C[2] CR05[4:0] */
- value = ( LVDSHRE >> 3 ) + 2;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
-
- /* Panel HRE SR2F[7:2] */
- value--;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
-
- /* VT SR0A[0] CR07[5][0] CR06 */
- value = LVDSVT - 2 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
-
- /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
- value = LVDSVBS - 1 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
-
- /* VBE SR0A[4] CR16 */
- value = LVDSVBE - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char temp, Miscdata;
+ unsigned short xres, yres, modeflag, resindex, lvdstableindex;
+ unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
+ unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
+ unsigned short value;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
+
+ temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
+ & (LCDPolarity << 8)) >> 8);
+ temp &= LCDPolarity;
+ Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
+
+ XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp);
+
+ temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
+ & LCDPolarity);
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
+
+ XGI_SetXG21FPBits(pVBInfo);
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ } else {
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+ }
+
+ if (!(modeflag & Charx8Dot))
+ xres = xres * 8 / 9;
+
+ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
- /* VRS SR0A[3] CR7[7][2] CR10 */
- value = LVDSVRS - 1 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
-
- /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0x03 , ( value & 0x600 ) >> 9 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , (value >> 1) & 0xFF ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x33 , ~0x01 , value & 0x01 ) ;
+ LVDSHBS = xres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE
+ - xres) / 2;
+ if ((ModeNo <= 0x13) && (modeflag & HalfDCLK))
+ LVDSHBS -= xres / 4;
+
+ if (LVDSHBS > LVDSHT)
+ LVDSHBS -= LVDSHT;
+
+ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
+ if (LVDSHRS > LVDSHT)
+ LVDSHRS -= LVDSHT;
+
+ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
+ if (LVDSHRE > LVDSHT)
+ LVDSHRE -= LVDSHT;
+
+ LVDSHBE = LVDSHBS + LVDSHT
+ - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
+
+ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
+
+ LVDSVBS = yres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE
+ - yres) / 2;
+ if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
+ LVDSVBS += yres / 2;
+
+ if (LVDSVBS > LVDSVT)
+ LVDSVBS -= LVDSVT;
+
+ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
+ if (LVDSVRS > LVDSVT)
+ LVDSVRS -= LVDSVT;
+
+ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
+ if (LVDSVRE > LVDSVT)
+ LVDSVRE -= LVDSVT;
+
+ LVDSVBE = LVDSVBS + LVDSVT
+ - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
+
+ temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
+
+ if (!(modeflag & Charx8Dot))
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1);
+
+ /* HT SR0B[1:0] CR00 */
+ value = (LVDSHT >> 3) - 5;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF));
+
+ /* HBS SR0B[5:4] CR02 */
+ value = (LVDSHBS >> 3) - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF));
+
+ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
+ value = (LVDSHBE >> 3) - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
+
+ /* HRS SR0B[7:6] CR04 */
+ value = (LVDSHRS >> 3) + 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF));
+
+ /* Panel HRS SR2F[1:0] SR2E[7:0] */
+ value--;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF));
+
+ /* HRE SR0C[2] CR05[4:0] */
+ value = (LVDSHRE >> 3) + 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
+
+ /* Panel HRE SR2F[7:2] */
+ value--;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
+
+ /* VT SR0A[0] CR07[5][0] CR06 */
+ value = LVDSVT - 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF));
+
+ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
+ value = LVDSVBS - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF));
+
+ /* VBE SR0A[4] CR16 */
+ value = LVDSVBE - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF));
+
+ /* VRS SR0A[3] CR7[7][2] CR10 */
+ value = LVDSVRS - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF));
+
+ /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0x03, (value & 0x600) >> 9);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
+
+ /* VRE SR0A[5] CR11[3:0] */
+ value = LVDSVRE - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
+
+ /* Panel VRE SR3F[7:2] *//* SR3F[7] has to be 0, h/w bug */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0x7C);
+
+ for (temp = 0, value = 0; temp < 3; temp++) {
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value);
+ XGINew_SetReg1(pVBInfo->P3c4,
+ 0x2B,
+ pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
+ XGINew_SetReg1(pVBInfo->P3c4,
+ 0x2C,
+ pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
+ value += 0x10;
+ }
- /* VRE SR0A[5] CR11[3:0] */
- value = LVDSVRE - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
-
- /* Panel VRE SR3F[7:2] */ /* SR3F[7] has to be 0, h/w bug */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0x7C ) ;
-
- for ( temp=0, value = 0; temp < 3; temp++)
- {
-
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
- value += 0x10;
- }
-
- if (!( modeflag & Charx8Dot ))
- {
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x13 ) ; /* set index */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- }
+ if (!(modeflag & Charx8Dot)) {
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/
+ XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x20);
+
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ }
}
/* no shadow case */
void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned char temp, Miscdata;
- unsigned short xres ,
- yres ,
- modeflag ,
- resindex ,
- lvdstableindex ;
- unsigned short LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
- unsigned short LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
- unsigned short value;
-
- lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
- temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8);
- temp &= LCDPolarity;
- Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
-
- XGINew_SetReg3( pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
-
- temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity) ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
-
- XGI_SetXG27FPBits(pVBInfo);
- resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
- if ( ModeNo <= 0x13 )
- {
- xres = pVBInfo->StResInfo[ resindex ].HTotal ;
- yres = pVBInfo->StResInfo[ resindex ].VTotal ;
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else
- {
- xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
- yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
- }
-
- if (!( modeflag & Charx8Dot ))
- xres = xres * 8 / 9;
-
- LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
-
- LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
- if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
- {
- LVDSHBS -= xres/4 ;
- }
- if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
-
- LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
- if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
-
- LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
- if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
-
- LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
-
- LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
-
- LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
- if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
- {
- LVDSVBS += yres/2 ;
- }
- if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
-
- LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
- if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
-
- LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
- if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
-
- LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
-
- temp = (unsigned char)XGINew_GetReg1(pVBInfo->P3d4, 0x11) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
-
- if (!( modeflag & Charx8Dot ))
- {
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x1 , 0x1 ) ;
- }
-
- /* HT SR0B[1:0] CR00 */
- value = ( LVDSHT >> 3 ) - 5;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
-
- /* HBS SR0B[5:4] CR02 */
- value = ( LVDSHBS >> 3 ) - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
-
- /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
- value = ( LVDSHBE >> 3 ) - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
-
- /* HRS SR0B[7:6] CR04 */
- value = ( LVDSHRS >> 3 ) + 2;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
-
- /* Panel HRS SR2F[1:0] SR2E[7:0] */
- value--;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
-
- /* HRE SR0C[2] CR05[4:0] */
- value = ( LVDSHRE >> 3 ) + 2;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
-
- /* Panel HRE SR2F[7:2] */
- value--;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
-
- /* VT SR0A[0] CR07[5][0] CR06 */
- value = LVDSVT - 2 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
-
- /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
- value = LVDSVBS - 1 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
-
- /* VBE SR0A[4] CR16 */
- value = LVDSVBE - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
+ struct vb_device_info *pVBInfo)
+{
+ unsigned char temp, Miscdata;
+ unsigned short xres, yres, modeflag, resindex, lvdstableindex;
+ unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
+ unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
+ unsigned short value;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
+ temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
+ & (LCDPolarity << 8)) >> 8);
+ temp &= LCDPolarity;
+ Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc);
+
+ XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp);
+
+ temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
+ & LCDPolarity);
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
+
+ XGI_SetXG27FPBits(pVBInfo);
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ } else {
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+ }
- /* VRS SR0A[3] CR7[7][2] CR10 */
- value = LVDSVRS - 1 ;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
- XGINew_SetReg1( pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
-
- /* Panel VRS SR35[2:0] SR34[7:0] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x35 , ~0x07 , ( value & 0x700 ) >> 8 ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x34 , value & 0xFF ) ;
+ if (!(modeflag & Charx8Dot))
+ xres = xres * 8 / 9;
+
+ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
- /* VRE SR0A[5] CR11[3:0] */
- value = LVDSVRE - 1;
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
- XGINew_SetRegANDOR( pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
+ LVDSHBS = xres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE
+ - xres) / 2;
+ if ((ModeNo <= 0x13) && (modeflag & HalfDCLK))
+ LVDSHBS -= xres / 4;
+
+ if (LVDSHBS > LVDSHT)
+ LVDSHBS -= LVDSHT;
+
+ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
+ if (LVDSHRS > LVDSHT)
+ LVDSHRS -= LVDSHT;
+
+ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
+ if (LVDSHRE > LVDSHT)
+ LVDSHRE -= LVDSHT;
+
+ LVDSHBE = LVDSHBS + LVDSHT
+ - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
+
+ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
- /* Panel VRE SR3F[7:2] */
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0xFC ) ;
+ LVDSVBS = yres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE
+ - yres) / 2;
+ if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
+ LVDSVBS += yres / 2;
+
+ if (LVDSVBS > LVDSVT)
+ LVDSVBS -= LVDSVT;
+
+ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
+ if (LVDSVRS > LVDSVT)
+ LVDSVRS -= LVDSVT;
+
+ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
+ if (LVDSVRE > LVDSVT)
+ LVDSVRE -= LVDSVT;
+
+ LVDSVBE = LVDSVBS + LVDSVT
+ - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
+
+ temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
+
+ if (!(modeflag & Charx8Dot))
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1);
+
+ /* HT SR0B[1:0] CR00 */
+ value = (LVDSHT >> 3) - 5;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF));
+
+ /* HBS SR0B[5:4] CR02 */
+ value = (LVDSHBS >> 3) - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF));
+
+ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
+ value = (LVDSHBE >> 3) - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
+
+ /* HRS SR0B[7:6] CR04 */
+ value = (LVDSHRS >> 3) + 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF));
+
+ /* Panel HRS SR2F[1:0] SR2E[7:0] */
+ value--;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF));
+
+ /* HRE SR0C[2] CR05[4:0] */
+ value = (LVDSHRE >> 3) + 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
+
+ /* Panel HRE SR2F[7:2] */
+ value--;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
+
+ /* VT SR0A[0] CR07[5][0] CR06 */
+ value = LVDSVT - 2;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF));
+
+ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
+ value = LVDSVBS - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF));
+
+ /* VBE SR0A[4] CR16 */
+ value = LVDSVBE - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF));
+
+ /* VRS SR0A[3] CR7[7][2] CR10 */
+ value = LVDSVRS - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
+ XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF));
+
+ /* Panel VRS SR35[2:0] SR34[7:0] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, (value & 0x700) >> 8);
+ XGINew_SetReg1(pVBInfo->P3c4, 0x34, value & 0xFF);
+
+ /* VRE SR0A[5] CR11[3:0] */
+ value = LVDSVRE - 1;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
+ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
+
+ /* Panel VRE SR3F[7:2] */
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0xFC);
+
+ for (temp = 0, value = 0; temp < 3; temp++) {
+
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value);
+ XGINew_SetReg1(pVBInfo->P3c4,
+ 0x2B,
+ pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
+ XGINew_SetReg1(pVBInfo->P3c4,
+ 0x2C,
+ pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
+ value += 0x10;
+ }
- for ( temp=0, value = 0; temp < 3; temp++)
- {
-
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
- XGINew_SetReg1( pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
- value += 0x10;
- }
-
- if (!( modeflag & Charx8Dot ))
- {
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x13 ) ; /* set index */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* Enable Attribute */
- XGINew_SetReg3( pVBInfo->P3c0 , 0x20 ) ;
-
- XGINew_GetReg2( pVBInfo->P3da ) ; /* reset 3da */
- }
+ if (!(modeflag & Charx8Dot)) {
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/
+ XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */
+ XGINew_SetReg3(pVBInfo->P3c0, 0x20);
+
+ XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */
+ }
}
@@ -8534,52 +7366,40 @@ void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
/* --------------------------------------------------------------------- */
unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
{
- unsigned short tempax ;
+ unsigned short tempax;
- tempax = pVBInfo->VBInfo ;
- if ( tempax & SetCRT2ToDualEdge )
- return 0;
- else if ( tempax & ( DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode ) )
- return 1;
+ tempax = pVBInfo->VBInfo;
+ if (tempax & SetCRT2ToDualEdge)
+ return 0;
+ else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
+ return 1;
- return 0;
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnablePWD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_EnablePWD(struct vb_device_info *pVBInfo)
{
- unsigned short index ,
- temp ;
+ unsigned short index, temp;
- index = XGI_GetLCDCapPtr(pVBInfo) ;
- temp = pVBInfo->LCDCapList[ index ].PWD_2B ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x2B , temp ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x2C , pVBInfo->LCDCapList[ index ].PWD_2C ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x2D , pVBInfo->LCDCapList[ index ].PWD_2D ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x2E , pVBInfo->LCDCapList[ index ].PWD_2E ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x2F , pVBInfo->LCDCapList[ index ].PWD_2F ) ;
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x27 , 0x80 ) ; /* enable PWD */
+ index = XGI_GetLCDCapPtr(pVBInfo);
+ temp = pVBInfo->LCDCapList[index].PWD_2B;
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x2B, temp);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x2C,
+ pVBInfo->LCDCapList[index].PWD_2C);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x2D,
+ pVBInfo->LCDCapList[index].PWD_2D);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x2E,
+ pVBInfo->LCDCapList[index].PWD_2E);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x2F,
+ pVBInfo->LCDCapList[index].PWD_2F);
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisablePWD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_DisablePWD(struct vb_device_info *pVBInfo)
{
- XGINew_SetRegAND( pVBInfo->Part4Port , 0x27 , 0x7F ) ; /* disable PWD */
+ XGINew_SetRegAND(pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_DisableChISLCD */
/* Input : */
@@ -8588,28 +7408,25 @@ void XGI_DisablePWD(struct vb_device_info *pVBInfo)
/* --------------------------------------------------------------------- */
unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ,
- tempah ;
+ unsigned short tempbx, tempah;
- tempbx = pVBInfo->SetFlag & ( DisableChA | DisableChB ) ;
- tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
+ tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
+ tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
- if ( tempbx & ( EnableChA | DisableChA ) )
- {
- if ( !( tempah & 0x08 ) ) /* Chk LCDA Mode */
- return 0 ;
- }
+ if (tempbx & (EnableChA | DisableChA)) {
+ if (!(tempah & 0x08)) /* Chk LCDA Mode */
+ return 0;
+ }
- if ( !( tempbx & ( EnableChB | DisableChB ) ) )
- return 0;
+ if (!(tempbx & (EnableChB | DisableChB)))
+ return 0;
- if ( tempah & 0x01 ) /* Chk LCDB Mode */
- return 1;
+ if (tempah & 0x01) /* Chk LCDB Mode */
+ return 1;
- return 0;
+ return 0;
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_EnableChISLCD */
/* Input : */
@@ -8618,515 +7435,433 @@ unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo)
/* --------------------------------------------------------------------- */
unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ,
- tempah ;
+ unsigned short tempbx, tempah;
+ tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
+ tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E));
- tempbx = pVBInfo->SetFlag & ( EnableChA | EnableChB ) ;
- tempah = ~( (unsigned short)XGINew_GetReg1( pVBInfo->Part1Port , 0x2E ) ) ;
+ if (tempbx & (EnableChA | DisableChA)) {
+ if (!(tempah & 0x08)) /* Chk LCDA Mode */
+ return 0;
+ }
- if ( tempbx & ( EnableChA | DisableChA ) )
- {
- if ( !( tempah & 0x08 ) ) /* Chk LCDA Mode */
+ if (!(tempbx & (EnableChB | DisableChB)))
return 0;
- }
- if ( !( tempbx & ( EnableChB | DisableChB ) ) )
- return 0;
+ if (tempah & 0x01) /* Chk LCDB Mode */
+ return 1;
- if ( tempah & 0x01 ) /* Chk LCDB Mode */
- return 1;
-
- return 0;
+ return 0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDCapPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
{
- unsigned char tempal ,
- tempah ,
- tempbl ,
- i ;
+ unsigned char tempal, tempah, tempbl, i;
- tempah = XGINew_GetReg1( pVBInfo->P3d4 , 0x36 ) ;
- tempal = tempah & 0x0F ;
- tempah = tempah & 0xF0 ;
- i = 0 ;
- tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
+ tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36);
+ tempal = tempah & 0x0F;
+ tempah = tempah & 0xF0;
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
- while( tempbl != 0xFF )
- {
- if ( tempbl & 0x80 ) /* OEMUtil */
- {
- tempal = tempah ;
- tempbl = tempbl & ~( 0x80 ) ;
- }
+ while (tempbl != 0xFF) {
+ if (tempbl & 0x80) { /* OEMUtil */
+ tempal = tempah;
+ tempbl = tempbl & ~(0x80);
+ }
- if ( tempal == tempbl )
- break ;
+ if (tempal == tempbl)
+ break;
- i++ ;
+ i++;
- tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
- }
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
- return i ;
+ return i;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDCapPtr1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
{
- unsigned short tempah ,
- tempal ,
- tempbl ,
- i ;
+ unsigned short tempah, tempal, tempbl, i;
- tempal = pVBInfo->LCDResInfo ;
- tempah = pVBInfo->LCDTypeInfo ;
+ tempal = pVBInfo->LCDResInfo;
+ tempah = pVBInfo->LCDTypeInfo;
- i = 0 ;
- tempbl = pVBInfo->LCDCapList[ i ].LCD_ID;
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
- while( tempbl != 0xFF )
- {
- if ( ( tempbl & 0x80 ) && ( tempbl != 0x80 ) )
- {
- tempal = tempah ;
- tempbl &= ~0x80 ;
- }
+ while (tempbl != 0xFF) {
+ if ((tempbl & 0x80) && (tempbl != 0x80)) {
+ tempal = tempah;
+ tempbl &= ~0x80;
+ }
- if ( tempal == tempbl )
- break ;
+ if (tempal == tempbl)
+ break;
- i++ ;
- tempbl = pVBInfo->LCDCapList[ i ].LCD_ID ;
- }
+ i++;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
- if ( tempbl == 0xFF )
- {
- pVBInfo->LCDResInfo = Panel1024x768 ;
- pVBInfo->LCDTypeInfo = 0 ;
- i = 0 ;
- }
+ if (tempbl == 0xFF) {
+ pVBInfo->LCDResInfo = Panel1024x768;
+ pVBInfo->LCDTypeInfo = 0;
+ i = 0;
+ }
- return i ;
+ return i;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDSync */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetLCDSync(unsigned short *HSyncWidth , unsigned short *VSyncWidth,
- struct vb_device_info *pVBInfo)
+void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth,
+ struct vb_device_info *pVBInfo)
{
- unsigned short Index ;
+ unsigned short Index;
- Index = XGI_GetLCDCapPtr(pVBInfo) ;
- *HSyncWidth = pVBInfo->LCDCapList[ Index ].LCD_HSyncWidth ;
- *VSyncWidth = pVBInfo->LCDCapList[ Index ].LCD_VSyncWidth ;
+ Index = XGI_GetLCDCapPtr(pVBInfo);
+ *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
+ *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
- return ;
+ return;
}
+void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbl, tempah;
+ if (pVBInfo->SetFlag == Win9xDOSMode) {
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ return;
+ } else
+ /* LVDS or CH7017 */
+ return;
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnableBridge */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempbl ,
- tempah ;
-
- if ( pVBInfo->SetFlag == Win9xDOSMode )
- {
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
- return ;
- }
- else /* LVDS or CH7017 */
- return ;
- }
-
-
- if ( HwDeviceExtension->jChipType < XG40 )
- {
- if ( !XGI_DisableChISLCD(pVBInfo) )
- {
- if ( ( XGI_EnableChISLCD(pVBInfo) ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
- {
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- {
- XGI_EnablePWD( pVBInfo);
- }
- else
- {
- pVBInfo->LCDInfo &= ( ~SetPWDEnable ) ;
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempbl = 0xFD ;
- tempah = 0x02 ;
- }
- else
- {
- tempbl = 0xFB ;
- tempah = 0x00 ;
- }
-
- XGI_SetPanelPower( tempah , tempbl, pVBInfo ) ;
- XGI_SetPanelDelay( 1,pVBInfo ) ;
- }
- }
- }
- } /* Not 340 */
-
-
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( !( pVBInfo->SetFlag & DisableChA ) )
- {
- if ( pVBInfo->SetFlag & EnableChA )
- {
- XGINew_SetReg1( pVBInfo->Part1Port , 0x1E , 0x20 ) ; /* Power on */
- }
- else
- {
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge ) /* SetCRT2ToLCDA ) */
- {
- XGINew_SetReg1(pVBInfo->Part1Port,0x1E,0x20); /* Power on */
- }
- }
- }
-
- if ( !( pVBInfo->SetFlag & DisableChB ) )
- {
- if ( ( pVBInfo->SetFlag & EnableChB ) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC ) ) )
- {
- tempah = (unsigned char)XGINew_GetReg1(pVBInfo->P3c4, 0x32);
- tempah &= 0xDF;
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
- tempah |= 0x20 ;
- }
- XGINew_SetReg1( pVBInfo->P3c4 , 0x32 , tempah ) ;
- XGINew_SetRegOR( pVBInfo->P3c4 , 0x1E , 0x20 ) ;
-
- tempah = (unsigned char)XGINew_GetReg1(pVBInfo->Part1Port, 0x2E);
-
- if ( !( tempah & 0x80 ) )
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ; /* BVBDOENABLE = 1 */
-
- XGINew_SetRegAND( pVBInfo->Part1Port , 0x00 , 0x7F ) ; /* BScreenOFF = 0 */
- }
- }
-
- if ( ( pVBInfo->SetFlag & ( EnableChA | EnableChB ) ) || ( !( pVBInfo->VBInfo & DisableCRT2Display ) ) )
- {
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x00 , ~0xE0 , 0x20 ) ; /* shampoo 0129 */
- if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
- {
- if ( !XGI_DisableChISLCD(pVBInfo) )
- {
- if ( XGI_EnableChISLCD( pVBInfo) || ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) )
- XGINew_SetRegAND( pVBInfo->Part4Port ,0x2A , 0x7F ) ; /* LVDS PLL power on */
- }
- XGINew_SetRegAND( pVBInfo->Part4Port , 0x30 , 0x7F ) ; /* LVDS Driver power on */
- }
- }
-
- tempah = 0x00 ;
-
- if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
- {
- tempah = 0xc0 ;
-
- if ( !( pVBInfo->VBInfo & SetSimuScanMode ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- {
- tempah = tempah & 0x40;
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- tempah = tempah ^ 0xC0 ;
-
- if ( pVBInfo->SetFlag & DisableChB )
- tempah &= 0xBF ;
-
- if ( pVBInfo->SetFlag & DisableChA )
- tempah &= 0x7F ;
-
- if ( pVBInfo->SetFlag & EnableChB )
- tempah |= 0x40 ;
-
- if ( pVBInfo->SetFlag & EnableChA )
- tempah |= 0x80 ;
- }
- }
- }
- }
-
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x1F , tempah ) ; /* EnablePart4_1F */
-
- if ( pVBInfo->SetFlag & Win9xDOSMode )
- {
- XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
- return ;
- }
-
- if ( !( pVBInfo->SetFlag & DisableChA ) )
- {
- XGI_VBLongWait( pVBInfo) ;
- if ( !( pVBInfo->SetFlag & GatingCRT ) )
- {
- XGI_DisableGatingCRT( HwDeviceExtension, pVBInfo ) ;
- XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
- XGI_VBLongWait( pVBInfo) ;
- }
- }
- } /* 301 */
- else /* LVDS */
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x1E , 0x20 ) ; /* enable CRT2 */
-
-
-
- tempah = (unsigned char)XGINew_GetReg1(pVBInfo->Part1Port, 0x2E);
- if ( !( tempah & 0x80 ) )
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x2E , 0x80 ) ; /* BVBDOENABLE = 1 */
-
- XGINew_SetRegAND(pVBInfo->Part1Port,0x00,0x7F);
- XGI_DisplayOn( HwDeviceExtension, pVBInfo);
- } /* End of VB */
-
-
- if ( HwDeviceExtension->jChipType < XG40 )
- {
- if ( !XGI_EnableChISLCD(pVBInfo) )
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- if ( XGI_BacklightByDrv(pVBInfo) )
- return ;
- }
- else
- return ;
- }
-
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- {
- XGI_FirePWDEnable(pVBInfo) ;
- return ;
- }
-
- XGI_SetPanelDelay( 2,pVBInfo ) ;
-
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempah = 0x01 ;
- tempbl = 0xFE ; /* turn on backlght */
- }
- else
- {
- tempbl = 0xF7 ;
- tempah = 0x00 ;
- }
- XGI_SetPanelPower( tempah , tempbl , pVBInfo) ;
- }
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!XGI_DisableChISLCD(pVBInfo)) {
+ if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo
+ & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ XGI_EnablePWD(pVBInfo);
+ } else {
+ pVBInfo->LCDInfo &= (~SetPWDEnable);
+ if (pVBInfo->VBType & (VB_XGI301LV
+ | VB_XGI302LV
+ | VB_XGI301C)) {
+ tempbl = 0xFD;
+ tempah = 0x02;
+ } else {
+ tempbl = 0xFB;
+ tempah = 0x00;
+ }
+
+ XGI_SetPanelPower(tempah, tempbl,
+ pVBInfo);
+ XGI_SetPanelDelay(1, pVBInfo);
+ }
+ }
+ }
+ } /* Not 340 */
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (!(pVBInfo->SetFlag & DisableChA)) {
+ if (pVBInfo->SetFlag & EnableChA) {
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+ } else {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
+ XGINew_SetReg1(pVBInfo->Part1Port,
+ 0x1E, 0x20); /* Power on */
+ }
+ }
+ }
+
+ if (!(pVBInfo->SetFlag & DisableChB)) {
+ if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
+ & (SetCRT2ToLCD | SetCRT2ToTV
+ | SetCRT2ToRAMDAC))) {
+ tempah = (unsigned char) XGINew_GetReg1(
+ pVBInfo->P3c4, 0x32);
+ tempah &= 0xDF;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+ tempah |= 0x20;
+ }
+ XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah);
+ XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20);
+
+ tempah = (unsigned char) XGINew_GetReg1(
+ pVBInfo->Part1Port, 0x2E);
+
+ if (!(tempah & 0x80))
+ XGINew_SetRegOR(pVBInfo->Part1Port,
+ 0x2E, 0x80); /* BVBDOENABLE = 1 */
+
+ XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
+ }
+ }
+
+ if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
+ || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0,
+ 0x20); /* shampoo 0129 */
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (!XGI_DisableChISLCD(pVBInfo)) {
+ if (XGI_EnableChISLCD(pVBInfo)
+ || (pVBInfo->VBInfo
+ & (SetCRT2ToLCD
+ | SetCRT2ToLCDA)))
+ XGINew_SetRegAND(
+ pVBInfo->Part4Port,
+ 0x2A, 0x7F); /* LVDS PLL power on */
+ }
+ XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
+ }
+ }
+
+ tempah = 0x00;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = 0xc0;
+
+ if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempah = tempah & 0x40;
+ if (pVBInfo->VBInfo
+ & SetCRT2ToLCDA)
+ tempah = tempah ^ 0xC0;
+
+ if (pVBInfo->SetFlag
+ & DisableChB)
+ tempah &= 0xBF;
+
+ if (pVBInfo->SetFlag
+ & DisableChA)
+ tempah &= 0x7F;
+
+ if (pVBInfo->SetFlag
+ & EnableChB)
+ tempah |= 0x40;
+
+ if (pVBInfo->SetFlag
+ & EnableChA)
+ tempah |= 0x80;
+ }
+ }
+ }
+ }
+
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
+
+ if (pVBInfo->SetFlag & Win9xDOSMode) {
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ return;
+ }
+
+ if (!(pVBInfo->SetFlag & DisableChA)) {
+ XGI_VBLongWait(pVBInfo);
+ if (!(pVBInfo->SetFlag & GatingCRT)) {
+ XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ XGI_VBLongWait(pVBInfo);
+ }
+ }
+ } /* 301 */
+ else { /* LVDS */
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
+ | SetCRT2ToLCDA))
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
+
+ tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port,
+ 0x2E);
+ if (!(tempah & 0x80))
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+
+ XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ } /* End of VB */
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!XGI_EnableChISLCD(pVBInfo)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (XGI_BacklightByDrv(pVBInfo))
+ return;
+ } else
+ return;
+ }
+
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ XGI_FirePWDEnable(pVBInfo);
+ return;
+ }
+
+ XGI_SetPanelDelay(2, pVBInfo);
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ tempah = 0x01;
+ tempbl = 0xFE; /* turn on backlght */
+ } else {
+ tempbl = 0xF7;
+ tempah = 0x00;
+ }
+ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+ }
}
+void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, tempah = 0, tempbl = 0;
+
+ if (pVBInfo->SetFlag == Win9xDOSMode)
+ return;
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ || (XGI_DisableChISLCD(pVBInfo))) {
+ if (!XGI_IsLCDON(pVBInfo)) {
+ if (pVBInfo->LCDInfo & SetPWDEnable)
+ XGI_EnablePWD(pVBInfo);
+ else {
+ pVBInfo->LCDInfo &= ~SetPWDEnable;
+ XGI_DisablePWD(pVBInfo);
+ if (pVBInfo->VBType & (VB_XGI301LV
+ | VB_XGI302LV
+ | VB_XGI301C)) {
+ tempbx = 0xFE; /* not 01h */
+ tempax = 0;
+ } else {
+ tempbx = 0xF7; /* not 08h */
+ tempax = 0x08;
+ }
+ XGI_SetPanelPower(tempax, tempbx,
+ pVBInfo);
+ XGI_SetPanelDelay(3, pVBInfo);
+ }
+ } /* end if (!XGI_IsLCDON(pVBInfo)) */
+ }
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisableBridge */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax ,
- tempbx ,
- tempah = 0 ,
- tempbl = 0 ;
-
- if ( pVBInfo->SetFlag == Win9xDOSMode )
- return ;
-
-
- if ( HwDeviceExtension->jChipType < XG40 )
- {
- if ( ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) ) || ( XGI_DisableChISLCD(pVBInfo) ) )
- {
- if ( !XGI_IsLCDON(pVBInfo) )
- {
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- XGI_EnablePWD( pVBInfo) ;
- else
- {
- pVBInfo->LCDInfo &= ~SetPWDEnable ;
- XGI_DisablePWD(pVBInfo) ;
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempbx = 0xFE ; /* not 01h */
- tempax = 0 ;
- }
- else
- {
- tempbx = 0xF7 ; /* not 08h */
- tempax = 0x08 ;
- }
- XGI_SetPanelPower( tempax , tempbx , pVBInfo) ;
- XGI_SetPanelDelay( 3,pVBInfo ) ;
- }
- } /* end if(!XGI_IsLCDON(pVBInfo)) */
- }
- }
-
-/* if ( CH7017 )
- {
- if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2toLCDA ) ) || ( XGI_DisableChISLCD(pVBInfo) ) )
- {
- if ( !XGI_IsLCDON(pVBInfo) )
- {
- if ( DISCHARGE )
- {
- tempbx = XGINew_GetCH7005( 0x61 ) ;
- if ( tempbx < 0x01 ) //first time we power up
- XGINew_SetCH7005( 0x0066 ) ; //and disable power sequence
- else
- XGINew_SetCH7005( 0x5f66 ) ; //leave VDD on - disable power
- }
- }
- }
- } */
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B| VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempah = 0x3F ;
- if ( !( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- {
- tempah = 0x7F; /* Disable Channel A */
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
- tempah = 0xBF ; /* Disable Channel B */
-
- if ( pVBInfo->SetFlag & DisableChB )
- tempah &= 0xBF ; /* force to disable Cahnnel */
-
- if ( pVBInfo->SetFlag & DisableChA )
- tempah &= 0x7F ; /* Force to disable Channel B */
- }
- }
- }
-
- XGINew_SetRegAND( pVBInfo->Part4Port , 0x1F , tempah ) ; /* disable part4_1f */
-
- if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
- {
- if ( ( ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) ) || ( XGI_DisableChISLCD(pVBInfo) ) || ( XGI_IsLCDON(pVBInfo) ) )
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x80 ) ; /* LVDS Driver power down */
- }
-
- if ( ( pVBInfo->SetFlag & DisableChA ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode ) ) )
- {
- if ( pVBInfo->SetFlag & GatingCRT )
- XGI_EnableGatingCRT( HwDeviceExtension, pVBInfo ) ;
- XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- if ( ( pVBInfo->SetFlag & DisableChA ) || ( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
- XGINew_SetRegAND( pVBInfo->Part1Port , 0x1e , 0xdf ) ; /* Power down */
- }
-
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x32 , 0xdf ) ; /* disable TV as primary VGA swap */
-
- if ( ( pVBInfo->VBInfo & ( SetSimuScanMode | SetCRT2ToDualEdge ) ) )
- XGINew_SetRegAND(pVBInfo->Part2Port,0x00,0xdf);
-
- if ( ( pVBInfo->SetFlag & DisableChB ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) )
- || ( ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) && ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) ) )
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x80 ) ; /* BScreenOff=1 */
-
- if ( ( pVBInfo->SetFlag & DisableChB ) || ( pVBInfo->VBInfo & ( DisableCRT2Display | SetSimuScanMode ) )
- || ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) ) || ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) )
- {
- tempah= XGINew_GetReg1( pVBInfo->Part1Port , 0x00 ) ; /* save Part1 index 0 */
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x10 ) ; /* BTDAC = 1, avoid VB reset */
- XGINew_SetRegAND( pVBInfo->Part1Port , 0x1E , 0xDF ) ; /* disable CRT2 */
- XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ; /* restore Part1 index 0 */
- }
- }
- else /* {301} */
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) )
- {
- XGINew_SetRegOR( pVBInfo->Part1Port , 0x00 , 0x80 ) ; /* BScreenOff=1 */
- XGINew_SetRegAND( pVBInfo->Part1Port , 0x1E , 0xDF ) ; /* Disable CRT2 */
- XGINew_SetRegAND( pVBInfo->P3c4 , 0x32 , 0xDF ) ; /* Disable TV asPrimary VGA swap */
- }
-
- if ( pVBInfo->VBInfo & ( DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode ) )
- XGI_DisplayOff( HwDeviceExtension, pVBInfo) ;
- }
-
-
-
-
- if ( HwDeviceExtension->jChipType < XG40 )
- {
- if ( !( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) ) || ( XGI_DisableChISLCD(pVBInfo) ) || ( XGI_IsLCDON(pVBInfo) ) )
- {
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- {
- if ( pVBInfo->LCDInfo & SetPWDEnable )
- XGI_BacklightByDrv(pVBInfo) ;
- else
- {
- XGI_SetPanelDelay( 4 ,pVBInfo) ;
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- tempbl = 0xFD ;
- tempah = 0x00 ;
- }
- else
- {
- tempbl = 0xFB ;
- tempah = 0x04 ;
- }
- }
- }
- XGI_SetPanelPower( tempah , tempbl , pVBInfo) ;
- }
- }
-}
+ /*
+ if (CH7017) {
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) {
+ if (!XGI_IsLCDON(pVBInfo)) {
+ if (DISCHARGE) {
+ tempbx = XGINew_GetCH7005(0x61);
+ if (tempbx < 0x01) // first time we power up
+ XGINew_SetCH7005(0x0066); // and disable power sequence
+ else
+ XGINew_SetCH7005(0x5f66); // leave VDD on - disable power
+ }
+ }
+ }
+ }
+ */
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ tempah = 0x3F;
+ if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempah = 0x7F; /* Disable Channel A */
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ tempah = 0xBF; /* Disable Channel B */
+
+ if (pVBInfo->SetFlag & DisableChB)
+ tempah &= 0xBF; /* force to disable Cahnnel */
+
+ if (pVBInfo->SetFlag & DisableChA)
+ tempah &= 0x7F; /* Force to disable Channel B */
+ }
+ }
+ }
+
+ XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ || (XGI_DisableChISLCD(pVBInfo))
+ || (XGI_IsLCDON(pVBInfo)))
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
+ }
+
+ if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
+ & (DisableCRT2Display | SetCRT2ToLCDA
+ | SetSimuScanMode))) {
+ if (pVBInfo->SetFlag & GatingCRT)
+ XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
+ & SetCRT2ToLCDA))
+ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
+ }
+
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+
+ if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
+ XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf);
+
+ if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
+ & (DisableCRT2Display | SetSimuScanMode))
+ || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ && (pVBInfo->VBInfo
+ & (SetCRT2ToRAMDAC
+ | SetCRT2ToLCD
+ | SetCRT2ToTV))))
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+
+ if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
+ & (DisableCRT2Display | SetSimuScanMode))
+ || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
+ | SetCRT2ToLCD | SetCRT2ToTV))) {
+ tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
+ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
+ }
+ } else { /* {301} */
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
+ XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
+ }
+
+ if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
+ | SetSimuScanMode))
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+ }
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ || (XGI_DisableChISLCD(pVBInfo))
+ || (XGI_IsLCDON(pVBInfo))) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ if (pVBInfo->LCDInfo & SetPWDEnable)
+ XGI_BacklightByDrv(pVBInfo);
+ else {
+ XGI_SetPanelDelay(4, pVBInfo);
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ tempbl = 0xFD;
+ tempah = 0x00;
+ } else {
+ tempbl = 0xFB;
+ tempah = 0x04;
+ }
+ }
+ }
+ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+ }
+ }
+}
/* --------------------------------------------------------------------- */
/* Function : XGI_GetTVPtrIndex */
@@ -9147,216 +7882,185 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_d
/* --------------------------------------------------------------------- */
unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
{
- unsigned short tempbx = 0 ;
+ unsigned short tempbx = 0;
- if ( pVBInfo->TVInfo & SetPALTV )
- tempbx = 2 ;
- if ( pVBInfo->TVInfo & SetYPbPrMode1080i )
- tempbx = 4 ;
- if ( pVBInfo->TVInfo & SetYPbPrMode525i )
- tempbx = 6 ;
- if ( pVBInfo->TVInfo & SetYPbPrMode525p )
- tempbx = 8 ;
- if ( pVBInfo->TVInfo & SetYPbPrMode750p )
- tempbx = 10 ;
- if ( pVBInfo->TVInfo & TVSimuMode )
- tempbx++ ;
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempbx = 2;
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+ tempbx = 4;
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ tempbx = 6;
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ tempbx = 8;
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ tempbx = 10;
+ if (pVBInfo->TVInfo & TVSimuMode)
+ tempbx++;
- return tempbx ;
+ return tempbx;
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_OEM310Setting */
/* Input : */
/* Output : */
/* Description : Customized Param. for 301 */
/* --------------------------------------------------------------------- */
-void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
{
- if ( pVBInfo->SetFlag & Win9xDOSMode )
- return ;
+ if (pVBInfo->SetFlag & Win9xDOSMode)
+ return;
- /* GetPart1IO(); */
- XGI_SetDelayComp(pVBInfo) ;
+ /* GetPart1IO(); */
+ XGI_SetDelayComp(pVBInfo);
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- XGI_SetLCDCap(pVBInfo) ;
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ XGI_SetLCDCap(pVBInfo);
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- /* GetPart2IO() */
- XGI_SetPhaseIncr(pVBInfo) ;
- XGI_SetYFilter( ModeNo , ModeIdIndex,pVBInfo ) ;
- XGI_SetAntiFlicker( ModeNo , ModeIdIndex,pVBInfo ) ;
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* GetPart2IO() */
+ XGI_SetPhaseIncr(pVBInfo);
+ XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
- if ( pVBInfo->VBType&VB_XGI301)
- XGI_SetEdgeEnhance( ModeNo , ModeIdIndex ,pVBInfo) ;
- }
+ if (pVBInfo->VBType & VB_XGI301)
+ XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetDelayComp */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
{
- unsigned short index ;
-
- unsigned char tempah ,
- tempbl ,
- tempbh ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV | SetCRT2ToRAMDAC ) )
- {
- tempbl = 0;
- tempbh = 0;
-
- index = XGI_GetTVPtrIndex(pVBInfo ) ; /* Get TV Delay */
- tempbl = pVBInfo->XGI_TVDelayList[ index ] ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- tempbl = pVBInfo->XGI_TVDelayList2[ index ] ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- tempbl = tempbl >> 4 ;
-/*
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- tempbl = CRT2Delay1 ; // Get CRT2 Delay
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- tempbl = CRT2Delay2 ;
-*/
- if ( pVBInfo->VBInfo & ( SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- index = XGI_GetLCDCapPtr(pVBInfo) ; /* Get LCD Delay */
- tempbh=pVBInfo->LCDCapList[ index ].LCD_DelayCompensation ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
- tempbl = tempbh ;
- }
-
- tempbl &= 0x0F ;
- tempbh &= 0xF0 ;
- tempah = XGINew_GetReg1( pVBInfo->Part1Port , 0x2D ) ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV ) ) /* Channel B */
- {
- tempah &= 0xF0 ;
- tempah |= tempbl ;
- }
-
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA ) /* Channel A */
- {
- tempah &= 0x0F ;
- tempah |= tempbh ;
- }
- XGINew_SetReg1(pVBInfo->Part1Port,0x2D,tempah);
- }
- }
- else if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- tempbl = 0;
- tempbh = 0;
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- {
- tempah = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_DelayCompensation ; /* / Get LCD Delay */
- tempah &= 0x0f ;
- tempah = tempah << 4 ;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2D , 0x0f , tempah ) ;
- }
- }
+ unsigned short index;
+
+ unsigned char tempah, tempbl, tempbh;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA
+ | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
+ tempbl = 0;
+ tempbh = 0;
+
+ index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
+ tempbl = pVBInfo->XGI_TVDelayList[index];
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
+ | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C))
+ tempbl = pVBInfo->XGI_TVDelayList2[index];
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempbl = tempbl >> 4;
+ /*
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+ tempbl = CRT2Delay1; // Get CRT2 Delay
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ tempbl = CRT2Delay2;
+ */
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
+ tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ tempbl = tempbh;
+ }
+
+ tempbl &= 0x0F;
+ tempbh &= 0xF0;
+ tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
+ | SetCRT2ToTV)) { /* Channel B */
+ tempah &= 0xF0;
+ tempah |= tempbl;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
+ tempah &= 0x0F;
+ tempah |= tempbh;
+ }
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah);
+ }
+ } else if (pVBInfo->IF_DEF_LVDS == 1) {
+ tempbl = 0;
+ tempbh = 0;
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ tempah
+ = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(
+ pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */
+ tempah &= 0x0f;
+ tempah = tempah << 4;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f,
+ tempah);
+ }
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
{
- unsigned short tempcx ;
-
- tempcx = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_Capability ;
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBType & ( VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- { /* 301LV/302LV only */
- /* Set 301LV Capability */
- XGINew_SetReg1(pVBInfo->Part4Port, 0x24, (unsigned char)(tempcx & 0x1F));
+ unsigned short tempcx;
+
+ tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
+ /* Set 301LV Capability */
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x24,
+ (unsigned char) (tempcx & 0x1F));
+ }
+ /* VB Driving */
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
+ ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+ (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
+ | EnablePLLSPLOW)) >> 8));
}
- /* VB Driving */
- XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D,
- ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
- (unsigned short)((tempcx & (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >> 8));
- }
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCD )
- XGI_SetLCDCap_B( tempcx,pVBInfo ) ;
- else if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- XGI_SetLCDCap_A( tempcx,pVBInfo ) ;
- if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
- {
- if ( tempcx & EnableSpectrum )
- SetSpectrum( pVBInfo) ;
- }
- }
- else /* LVDS,CH7017 */
- XGI_SetLCDCap_A( tempcx, pVBInfo ) ;
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCD)
+ XGI_SetLCDCap_B(tempcx, pVBInfo);
+ else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (tempcx & EnableSpectrum)
+ SetSpectrum(pVBInfo);
+ }
+ } else {
+ /* LVDS,CH7017 */
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap_A */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
{
- unsigned short temp ;
+ unsigned short temp;
- temp = XGINew_GetReg1( pVBInfo->P3d4 , 0x37 ) ;
+ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37);
- if ( temp & LCDRGB18Bit )
- {
- XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
- (unsigned short)(0x20 | (tempcx & 0x00C0))); /* Enable Dither */
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x80 ) ;
- }
- else
- {
- XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
- (unsigned short)(0x30 | (tempcx & 0x00C0)));
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x1A , 0x7F , 0x00 ) ;
- }
+ if (temp & LCDRGB18Bit) {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+ (unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+ } else {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F,
+ (unsigned short) (0x30 | (tempcx & 0x00C0)));
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+ }
-/*
- if ( tempcx & EnableLCD24bpp ) // 24bits
- {
- XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(unsigned short)(0x30|(tempcx&0x00C0)) );
- XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x00);
- }
- else
- {
- XGINew_SetRegANDOR(pVBInfo->Part1Port,0x19, 0x0F,(unsigned short)(0x20|(tempcx&0x00C0)) ); // Enable Dither
- XGINew_SetRegANDOR(pVBInfo->Part1Port,0x1A,0x7F,0x80);
- }
-*/
+ /*
+ if (tempcx & EnableLCD24bpp) { // 24bits
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0)));
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+ } else {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+ }
+ */
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetLCDCap_B */
/* Input : cx -> LCD Capability */
@@ -9365,41 +8069,39 @@ void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
/* --------------------------------------------------------------------- */
void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
{
- if ( tempcx & EnableLCD24bpp ) /* 24bits */
- XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
- (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c));
- else
- XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
- (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
+ if (tempcx & EnableLCD24bpp) /* 24bits */
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+ (unsigned short) (((tempcx & 0x00ff) >> 6)
+ | 0x0c));
+ else
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0,
+ (unsigned short) (((tempcx & 0x00ff) >> 6)
+ | 0x18)); /* Enable Dither */
}
-
-/* --------------------------------------------------------------------- */
-/* Function : SetSpectrum */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void SetSpectrum(struct vb_device_info *pVBInfo)
{
- unsigned short index ;
+ unsigned short index;
- index = XGI_GetLCDCapPtr(pVBInfo) ;
+ index = XGI_GetLCDCapPtr(pVBInfo);
- XGINew_SetRegAND( pVBInfo->Part4Port , 0x30 , 0x8F ) ; /* disable down spectrum D[4] */
- XGI_LongWait(pVBInfo) ;
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x20 ) ; /* reset spectrum */
- XGI_LongWait(pVBInfo) ;
+ XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
+ XGI_LongWait(pVBInfo);
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
+ XGI_LongWait(pVBInfo);
- XGINew_SetReg1( pVBInfo->Part4Port , 0x31 , pVBInfo->LCDCapList[ index ].Spectrum_31 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x32 , pVBInfo->LCDCapList[ index ].Spectrum_32 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x33 , pVBInfo->LCDCapList[ index ].Spectrum_33 ) ;
- XGINew_SetReg1( pVBInfo->Part4Port , 0x34 , pVBInfo->LCDCapList[ index ].Spectrum_34 ) ;
- XGI_LongWait(pVBInfo) ;
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x30 , 0x40 ) ; /* enable spectrum */
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x31,
+ pVBInfo->LCDCapList[index].Spectrum_31);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x32,
+ pVBInfo->LCDCapList[index].Spectrum_32);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x33,
+ pVBInfo->LCDCapList[index].Spectrum_33);
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x34,
+ pVBInfo->LCDCapList[index].Spectrum_34);
+ XGI_LongWait(pVBInfo);
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetAntiFlicker */
/* Input : */
@@ -9407,193 +8109,153 @@ void SetSpectrum(struct vb_device_info *pVBInfo)
/* Description : Set TV Customized Param. */
/* --------------------------------------------------------------------- */
void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
+ struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ,
- index ;
+ unsigned short tempbx, index;
- unsigned char tempah ;
+ unsigned char tempah;
- if (pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) )
- return ;
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+ return;
- tempbx = XGI_GetTVPtrIndex(pVBInfo ) ;
- tempbx &= 0xFE ;
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
- if ( ModeNo <= 0x13 )
- {
- index = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVFlickerIndex ;
- }
- else
- {
- index = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVFlickerIndex ;
- }
+ if (ModeNo <= 0x13)
+ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+ else
+ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
- tempbx += index ;
- tempah = TVAntiFlickList[ tempbx ] ;
- tempah = tempah << 4 ;
+ tempbx += index;
+ tempah = TVAntiFlickList[tempbx];
+ tempah = tempah << 4;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x0A , 0x8F , tempah ) ;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetEdgeEnhance */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex,
+ struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ,
- index ;
-
- unsigned char tempah ;
+ unsigned short tempbx, index;
+ unsigned char tempah;
- tempbx = XGI_GetTVPtrIndex(pVBInfo ) ;
- tempbx &= 0xFE ;
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
- if ( ModeNo <= 0x13 )
- {
- index = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVEdgeIndex ;
- }
- else
- {
- index = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVEdgeIndex ;
- }
+ if (ModeNo <= 0x13)
+ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+ else
+ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
- tempbx += index ;
- tempah = TVEdgeList[ tempbx ] ;
- tempah = tempah << 5 ;
+ tempbx += index;
+ tempah = TVEdgeList[tempbx];
+ tempah = tempah << 5;
- XGINew_SetRegANDOR( pVBInfo->Part2Port , 0x3A , 0x1F , tempah ) ;
+ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetPhaseIncr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ;
+ unsigned short tempbx;
- unsigned char tempcl ,
- tempch ;
+ unsigned char tempcl, tempch;
- unsigned long tempData ;
+ unsigned long tempData;
- XGI_GetTVPtrIndex2( &tempbx , &tempcl , &tempch, pVBInfo ) ; /* bx, cl, ch */
- tempData = TVPhaseList[ tempbx ] ;
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+ tempData = TVPhaseList[tempbx];
- XGINew_SetReg1(pVBInfo->Part2Port, 0x31,
- (unsigned short)(tempData & 0x000000FF));
- XGINew_SetReg1(pVBInfo->Part2Port, 0x32,
- (unsigned short)((tempData & 0x0000FF00) >> 8));
- XGINew_SetReg1(pVBInfo->Part2Port, 0x33,
- (unsigned short)((tempData & 0x00FF0000) >> 16));
- XGINew_SetReg1(pVBInfo->Part2Port, 0x34,
- (unsigned short)((tempData & 0xFF000000) >> 24));
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
+ & 0x000000FF));
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
+ & 0x0000FF00) >> 8));
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
+ & 0x00FF0000) >> 16));
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
+ & 0xFF000000) >> 24));
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetYFilter */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx ,
- index ;
-
- unsigned char tempcl ,
- tempch ,
- tempal ,
- *filterPtr ;
-
- XGI_GetTVPtrIndex2( &tempbx , &tempcl , &tempch, pVBInfo ) ; /* bx, cl, ch */
-
- switch( tempbx )
- {
- case 0x00:
- case 0x04:
- filterPtr = NTSCYFilter1 ;
- break ;
-
- case 0x01:
- filterPtr = PALYFilter1 ;
- break ;
-
- case 0x02:
- case 0x05:
- case 0x0D:
- filterPtr = PALMYFilter1 ;
- break ;
-
- case 0x03:
- filterPtr = PALNYFilter1 ;
- break ;
-
- case 0x08:
- case 0x0C:
- filterPtr = NTSCYFilter2 ;
- break ;
-
- case 0x0A:
- filterPtr = PALMYFilter2 ;
- break ;
-
- case 0x0B:
- filterPtr = PALNYFilter2 ;
- break ;
-
- case 0x09:
- filterPtr = PALYFilter2 ;
- break ;
-
- default:
- return ;
- }
-
- if ( ModeNo <= 0x13 )
- tempal = pVBInfo->SModeIDTable[ ModeIdIndex ].VB_StTVYFilterIndex ;
- else
- tempal = pVBInfo->EModeIDTable[ ModeIdIndex ].VB_ExtTVYFilterIndex ;
-
- if ( tempcl == 0 )
- index = tempal * 4;
- else
- index = tempal * 7;
-
- if ( ( tempcl == 0 ) && ( tempch == 1 ) )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , 0x35 , 0 ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x36 , 0 ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x37 , 0 ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x38 , filterPtr[ index++ ] ) ;
- }
- else
- {
- XGINew_SetReg1( pVBInfo->Part2Port , 0x35 , filterPtr[ index++ ] ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x36 , filterPtr[ index++ ] ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x37 , filterPtr[ index++ ] ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x38 , filterPtr[ index++ ] ) ;
- }
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- XGINew_SetReg1( pVBInfo->Part2Port , 0x48 , filterPtr[ index++ ] ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x49 , filterPtr[ index++ ] ) ;
- XGINew_SetReg1( pVBInfo->Part2Port , 0x4A , filterPtr[ index++ ] ) ;
- }
-}
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx, index;
+
+ unsigned char tempcl, tempch, tempal, *filterPtr;
+
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+
+ switch (tempbx) {
+ case 0x00:
+ case 0x04:
+ filterPtr = NTSCYFilter1;
+ break;
+ case 0x01:
+ filterPtr = PALYFilter1;
+ break;
+
+ case 0x02:
+ case 0x05:
+ case 0x0D:
+ filterPtr = PALMYFilter1;
+ break;
+
+ case 0x03:
+ filterPtr = PALNYFilter1;
+ break;
+
+ case 0x08:
+ case 0x0C:
+ filterPtr = NTSCYFilter2;
+ break;
+
+ case 0x0A:
+ filterPtr = PALMYFilter2;
+ break;
+
+ case 0x0B:
+ filterPtr = PALNYFilter2;
+ break;
+
+ case 0x09:
+ filterPtr = PALYFilter2;
+ break;
+
+ default:
+ return;
+ }
+
+ if (ModeNo <= 0x13)
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+ else
+ tempal
+ = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+
+ if (tempcl == 0)
+ index = tempal * 4;
+ else
+ index = tempal * 7;
+
+ if ((tempcl == 0) && (tempch == 1)) {
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+ } else {
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
+ }
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
+ XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
+ }
+}
/* --------------------------------------------------------------------- */
/* Function : XGI_GetTVPtrIndex2 */
@@ -9612,42 +8274,41 @@ void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
/* Description : */
/* --------------------------------------------------------------------- */
void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
- unsigned char *tempch, struct vb_device_info *pVBInfo)
+ unsigned char *tempch, struct vb_device_info *pVBInfo)
{
- *tempbx = 0 ;
- *tempcl = 0 ;
- *tempch = 0 ;
+ *tempbx = 0;
+ *tempcl = 0;
+ *tempch = 0;
- if ( pVBInfo->TVInfo & SetPALTV )
- *tempbx = 1 ;
+ if (pVBInfo->TVInfo & SetPALTV)
+ *tempbx = 1;
- if ( pVBInfo->TVInfo & SetPALMTV )
- *tempbx = 2 ;
+ if (pVBInfo->TVInfo & SetPALMTV)
+ *tempbx = 2;
- if ( pVBInfo->TVInfo & SetPALNTV )
- *tempbx = 3 ;
+ if (pVBInfo->TVInfo & SetPALNTV)
+ *tempbx = 3;
- if ( pVBInfo->TVInfo & NTSC1024x768 )
- {
- *tempbx = 4 ;
- if ( pVBInfo->TVInfo & SetPALMTV )
- *tempbx = 5 ;
- }
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ *tempbx = 4;
+ if (pVBInfo->TVInfo & SetPALMTV)
+ *tempbx = 5;
+ }
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) || ( pVBInfo->TVInfo & TVSimuMode ) )
- {
- *tempbx += 8 ;
- *tempcl += 1 ;
- }
- }
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
+ & TVSimuMode)) {
+ *tempbx += 8;
+ *tempcl += 1;
+ }
+ }
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- (*tempch)++ ;
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C))
+ (*tempch)++;
}
-
/* --------------------------------------------------------------------- */
/* Function : XGI_SetCRT2ModeRegs */
/* Input : */
@@ -9655,776 +8316,598 @@ void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
/* Description : Origin code for crt2group */
/* --------------------------------------------------------------------- */
void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbl ;
- short tempcl ;
-
- unsigned char tempah ;
-
- /* XGINew_SetReg1( pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
- tempah=0;
- if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
- {
- tempah=XGINew_GetReg1( pVBInfo->Part1Port , 0x00 ) ;
- tempah &= ~0x10 ; /* BTRAMDAC */
- tempah |= 0x40 ; /* BTRAM */
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- tempah=0x40; /* BTDRAM */
- if ( ModeNo > 0x13 )
- {
- tempcl = pVBInfo->ModeType ;
- tempcl -= ModeVGA ;
- if ( tempcl >= 0 )
- {
- tempah = ( 0x008 >> tempcl ) ; /* BT Color */
- if ( tempah == 0 )
- tempah = 1 ;
- tempah |= 0x040 ;
- }
- }
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- tempah ^= 0x50 ; /* BTDAC */
- }
- }
-
-/* 0210 shampoo
- if ( pVBInfo->VBInfo & DisableCRT2Display )
- {
- tempah = 0 ;
- }
-
- XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ;
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- tempcl = pVBInfo->ModeType ;
- if ( ModeNo > 0x13 )
- {
- tempcl -= ModeVGA ;
- if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
- {
- tempah=(0x008>>tempcl) ;
- if ( tempah == 0 )
- tempah = 1 ;
- tempah |= 0x040;
- }
- }
- else
- {
- tempah = 0x040 ;
- }
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- tempah = ( tempah ^ 0x050 ) ;
- }
- }
-*/
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbl;
+ short tempcl;
+
+ unsigned char tempah;
+
+ /* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */
+ tempah = 0;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00);
+ tempah &= ~0x10; /* BTRAMDAC */
+ tempah |= 0x40; /* BTRAM */
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
+ | SetCRT2ToLCD)) {
+ tempah = 0x40; /* BTDRAM */
+ if (ModeNo > 0x13) {
+ tempcl = pVBInfo->ModeType;
+ tempcl -= ModeVGA;
+ if (tempcl >= 0) {
+ tempah = (0x008 >> tempcl); /* BT Color */
+ if (tempah == 0)
+ tempah = 1;
+ tempah |= 0x040;
+ }
+ }
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempah ^= 0x50; /* BTDAC */
+ }
+ }
- XGINew_SetReg1( pVBInfo->Part1Port , 0x00 , tempah ) ;
- tempah = 0x08 ;
- tempbl = 0xf0 ;
-
- if ( pVBInfo->VBInfo & DisableCRT2Display )
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
- else
- {
- tempah = 0x00 ;
- tempbl = 0xff ;
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- if ( ( pVBInfo->VBInfo & SetCRT2ToLCDA ) && ( !( pVBInfo->VBInfo & SetSimuScanMode ) ) )
- {
- tempbl &= 0xf7 ;
- tempah |= 0x01 ;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
- }
- else
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- tempbl &= 0xf7 ;
- tempah |= 0x01 ;
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- tempbl &= 0xf8 ;
- tempah = 0x01 ;
-
- if ( !( pVBInfo->VBInfo & SetInSlaveMode ) )
- tempah |= 0x02 ;
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToRAMDAC ) )
- {
- tempah = tempah ^ 0x05 ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
- tempah = tempah ^ 0x01 ;
- }
-
- if ( !( pVBInfo->VBInfo & SetCRT2ToDualEdge ) )
- tempah |= 0x08 ;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
- }
- else
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
- }
- }
- else
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2e , tempbl , tempah ) ;
- }
-
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) )
- {
- tempah &= ( ~0x08 ) ;
- if ( ( pVBInfo->ModeType == ModeVGA ) && ( !( pVBInfo->VBInfo & SetInSlaveMode ) ) )
- {
- tempah |= 0x010 ;
- }
- tempah |= 0x080 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
- /* { */
- tempah |= 0x020 ;
- if ( ModeNo > 0x13 )
- {
- if ( pVBInfo->VBInfo & DriverMode )
- tempah = tempah ^ 0x20 ;
- }
- /* } */
- }
-
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x0D , ~0x0BF , tempah ) ;
- tempah = 0 ;
-
- if ( pVBInfo->LCDInfo & SetLCDDualLink )
- tempah |= 0x40 ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
- /* { */
- if ( pVBInfo->TVInfo & RPLLDIV2XO )
- tempah |= 0x40 ;
- /* } */
- }
-
- if ( ( pVBInfo->LCDResInfo == Panel1280x1024 ) || ( pVBInfo->LCDResInfo == Panel1280x1024x75 ) )
- tempah |= 0x80 ;
-
- if ( pVBInfo->LCDResInfo == Panel1280x960 )
- tempah |= 0x80 ;
-
- XGINew_SetReg1( pVBInfo->Part4Port , 0x0C , tempah ) ;
- }
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- tempah = 0 ;
- tempbl = 0xfb ;
-
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- {
- tempbl=0xff;
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- tempah |= 0x04 ; /* shampoo 0129 */
- }
-
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x13 , tempbl , tempah ) ;
- tempah = 0x00 ;
- tempbl = 0xcf ;
- if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- tempah |= 0x30 ;
- }
-
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2c , tempbl , tempah ) ;
- tempah = 0 ;
- tempbl = 0x3f ;
-
- if ( !( pVBInfo->VBInfo & DisableCRT2Display ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToDualEdge )
- tempah |= 0xc0 ;
- }
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x21 , tempbl , tempah ) ;
- }
-
- tempah = 0 ;
- tempbl = 0x7f ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCDA ) )
- {
- tempbl = 0xff ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToDualEdge ) )
- tempah |= 0x80 ;
- }
-
- XGINew_SetRegANDOR( pVBInfo->Part4Port , 0x23 , tempbl , tempah ) ;
-
- if ( pVBInfo->VBType & ( VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->LCDInfo & SetLCDDualLink )
- {
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x27 , 0x20 ) ;
- XGINew_SetRegOR( pVBInfo->Part4Port , 0x34 , 0x10 ) ;
- }
- }
-}
+ /* 0210 shampoo
+ if (pVBInfo->VBInfo & DisableCRT2Display) {
+ tempah = 0;
+ }
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+ tempcl = pVBInfo->ModeType;
+ if (ModeNo > 0x13) {
+ tempcl -= ModeVGA;
+ if ((tempcl > 0) || (tempcl == 0)) {
+ tempah=(0x008>>tempcl) ;
+ if (tempah == 0)
+ tempah = 1;
+ tempah |= 0x040;
+ }
+ } else {
+ tempah = 0x040;
+ }
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ tempah = (tempah ^ 0x050);
+ }
+ }
+ */
+
+ XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah);
+ tempah = 0x08;
+ tempbl = 0xf0;
+
+ if (pVBInfo->VBInfo & DisableCRT2Display) {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
+ } else {
+ tempah = 0x00;
+ tempbl = 0xff;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
+ | SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
+ && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e,
+ tempbl, tempah);
+ } else {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
+ | SetCRT2ToTV | SetCRT2ToLCD)) {
+ tempbl &= 0xf8;
+ tempah = 0x01;
+
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ tempah |= 0x02;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ tempah = tempah ^ 0x05;
+ if (!(pVBInfo->VBInfo
+ & SetCRT2ToLCD))
+ tempah = tempah ^ 0x01;
+ }
+
+ if (!(pVBInfo->VBInfo
+ & SetCRT2ToDualEdge))
+ tempah |= 0x08;
+ XGINew_SetRegANDOR(pVBInfo->Part1Port,
+ 0x2e, tempbl, tempah);
+ } else {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port,
+ 0x2e, tempbl, tempah);
+ }
+ }
+ } else {
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl,
+ tempah);
+ }
+ }
-/* --------------------------------------------------------------------- */
-/* Function : XGI_CloseCRTC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx ;
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
+ | SetCRT2ToLCDA)) {
+ tempah &= (~0x08);
+ if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
+ & SetInSlaveMode))) {
+ tempah |= 0x010;
+ }
+ tempah |= 0x080;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */
+ tempah |= 0x020;
+ if (ModeNo > 0x13) {
+ if (pVBInfo->VBInfo & DriverMode)
+ tempah = tempah ^ 0x20;
+ }
+ /* } */
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
+ tempah = 0;
+
+ if (pVBInfo->LCDInfo & SetLCDDualLink)
+ tempah |= 0x40;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
+ if (pVBInfo->TVInfo & RPLLDIV2XO)
+ tempah |= 0x40;
+ /* } */
+ }
+
+ if ((pVBInfo->LCDResInfo == Panel1280x1024)
+ || (pVBInfo->LCDResInfo == Panel1280x1024x75))
+ tempah |= 0x80;
+
+ if (pVBInfo->LCDResInfo == Panel1280x960)
+ tempah |= 0x80;
+
+ XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah);
+ }
- tempbx = 0 ;
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
+ | VB_XGI302LV | VB_XGI301C)) {
+ tempah = 0;
+ tempbl = 0xfb;
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempbl = 0xff;
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempah |= 0x04; /* shampoo 0129 */
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah);
+ tempah = 0x00;
+ tempbl = 0xcf;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0x30;
+ }
+
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
+ tempah = 0;
+ tempbl = 0x3f;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0xc0;
+ }
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah);
+ }
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- tempbx = 0x08A0 ;
+ tempah = 0;
+ tempbl = 0x7f;
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+ tempah |= 0x80;
+ }
+ XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah);
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->LCDInfo & SetLCDDualLink) {
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20);
+ XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10);
+ }
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_OpenCRTC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- unsigned short tempbx ;
+ unsigned short tempbx;
- tempbx = 0 ;
+ tempbx = 0;
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempbx = 0x08A0;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetRAMDAC2DATA */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short tempax ,
- tempbx ,
- temp1 ,
- temp2 ,
- modeflag = 0 ,
- tempcx ,
- StandTableIndex ,
- CRT1Index ;
-
- pVBInfo->RVBHCMAX = 1 ;
- pVBInfo->RVBHCFACT = 1 ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ;
- tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 0 ] ;
- tempbx = pVBInfo->StandTable[StandTableIndex ].CRTC[ 6 ] ;
- temp1 = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- CRT1Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
- CRT1Index &= IndexMask ;
- temp1 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
- temp2 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
- tempax = ( temp1 & 0xFF ) | ( ( temp2 & 0x03 ) << 8 ) ;
- tempbx = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
- tempcx = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
- tempcx &= 0x0100 ;
- tempcx = tempcx << 2 ;
- tempbx |= tempcx;
- temp1 = (unsigned short)pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
- }
-
- if ( temp1 & 0x01 )
- tempbx |= 0x0100 ;
-
- if ( temp1 & 0x20 )
- tempbx |= 0x0200 ;
- tempax += 5 ;
-
- if ( modeflag & Charx8Dot )
- tempax *= 8 ;
- else
- tempax *= 9 ;
-
- pVBInfo->VGAHT = tempax ;
- pVBInfo->HT = tempax ;
- tempbx++ ;
- pVBInfo->VGAVT = tempbx ;
- pVBInfo->VT = tempbx ;
+void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+ tempbx = 0;
}
+void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
+ StandTableIndex, CRT1Index;
+ pVBInfo->RVBHCMAX = 1;
+ pVBInfo->RVBHCFACT = 1;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetColorDepth */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned short XGI_GetColorDepth(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
- unsigned short ColorDepth[ 6 ] = { 1 , 2 , 4 , 4 , 6 , 8 } ;
- short index ;
- unsigned short modeflag ;
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
+ tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
+ tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
+ temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT1Index
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ temp1
+ = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
+ temp2
+ = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
+ tempbx
+ = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+ tempcx
+ = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
+ << 8;
+ tempcx &= 0x0100;
+ tempcx = tempcx << 2;
+ tempbx |= tempcx;
+ temp1
+ = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+ }
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
+ if (temp1 & 0x01)
+ tempbx |= 0x0100;
- index=(modeflag&ModeInfoFlag)-ModeEGA;
+ if (temp1 & 0x20)
+ tempbx |= 0x0200;
+ tempax += 5;
- if ( index < 0 )
- index = 0 ;
+ if (modeflag & Charx8Dot)
+ tempax *= 8;
+ else
+ tempax *= 9;
- return( ColorDepth[ index ] ) ;
+ pVBInfo->VGAHT = tempax;
+ pVBInfo->HT = tempax;
+ tempbx++;
+ pVBInfo->VGAVT = tempbx;
+ pVBInfo->VT = tempbx;
}
+unsigned short XGI_GetColorDepth(unsigned short ModeNo,
+ unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+ unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+ short index;
+ unsigned short modeflag;
+ if (ModeNo <= 0x13)
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-/* --------------------------------------------------------------------- */
-/* Function : XGI_UnLockCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
-{
+ index = (modeflag & ModeInfoFlag) - ModeEGA;
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2f , 0xFF , 0x01 ) ;
+ if (index < 0)
+ index = 0;
+ return ColorDepth[index];
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_LockCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->Part1Port , 0x2F , 0xFE , 0x00 ) ;
-
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_EnableCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
+void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
{
- XGINew_SetRegANDOR( pVBInfo->P3c4 , 0x1E , 0xFF , 0x20 ) ;
-}
+ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
+}
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_LCD_Wait_Time(unsigned char DelayTime, struct vb_device_info *pVBInfo)
+void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
{
- unsigned short i ,
- j ;
-
- unsigned long temp ,
- flag ;
+ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
+}
- flag = 0 ;
-//printk("XGINew_LCD_Wait_Time");
-//return;
- for( i = 0 ; i < DelayTime ; i++ )
- {
- for( j = 0 ; j < 66 ; j++ )
- {
+void XGINew_LCD_Wait_Time(unsigned char DelayTime,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short i, j;
- temp = XGINew_GetReg3( 0x61 ) ;
+ unsigned long temp, flag;
- //temp &= 0x10000000;
- temp &= 0x10;
- if ( temp == flag )
- continue ;
+ flag = 0;
+ /* printk("XGINew_LCD_Wait_Time"); */
+ /* return; */
+ for (i = 0; i < DelayTime; i++) {
+ for (j = 0; j < 66; j++) {
+ temp = XGINew_GetReg3(0x61);
+ /* temp &= 0x10000000; */
+ temp &= 0x10;
+ if (temp == flag)
+ continue;
- flag = temp ;
- }
- }
+ flag = temp;
+ }
+ }
}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_BridgeIsOn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
{
- unsigned short flag ;
+ unsigned short flag;
- if ( pVBInfo->IF_DEF_LVDS == 1 )
- {
- return( 1 ) ;
- }
- else
- {
- flag = XGINew_GetReg1( pVBInfo->Part4Port , 0x00 ) ;
- if ( ( flag == 1 ) || ( flag == 2 ) )
- return( 1 ) ; /* 301b */
- else
- return( 0 ) ;
- }
+ if (pVBInfo->IF_DEF_LVDS == 1) {
+ return 1;
+ } else {
+ flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00);
+ if ((flag == 1) || (flag == 2))
+ return 1; /* 301b */
+ else
+ return 0;
+ }
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_LongWait */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_LongWait(struct vb_device_info *pVBInfo)
{
- unsigned short i ;
+ unsigned short i;
- i = XGINew_GetReg1( pVBInfo->P3c4 , 0x1F ) ;
+ i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F);
- if ( !( i & 0xC0 ) )
- {
- for( i = 0 ; i < 0xFFFF ; i++ )
- {
- if ( !( XGINew_GetReg2( pVBInfo->P3da ) & 0x08 ) )
- break ;
- }
+ if (!(i & 0xC0)) {
+ for (i = 0; i < 0xFFFF; i++) {
+ if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08))
+ break;
+ }
- for( i = 0 ; i < 0xFFFF ; i++ )
- {
- if ( ( XGINew_GetReg2( pVBInfo->P3da ) & 0x08 ) )
- break ;
+ for (i = 0; i < 0xFFFF; i++) {
+ if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08))
+ break;
+ }
}
- }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_VBLongWait */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void XGI_VBLongWait(struct vb_device_info *pVBInfo)
{
- unsigned short tempal ,
- temp ,
- i ,
- j ;
-return ;
- if ( !( pVBInfo->VBInfo & SetCRT2ToTV ) )
- {
- temp = 0 ;
- for( i = 0 ; i < 3 ; i++ )
- {
- for( j = 0 ; j < 100 ; j++ )
- {
- tempal = XGINew_GetReg2( pVBInfo->P3da ) ;
- if ( temp & 0x01 )
- { /* VBWaitMode2 */
- if ( ( tempal & 0x08 ) )
- {
- continue ;
- }
-
- if ( !( tempal & 0x08 ) )
- {
- break ;
- }
- }
- else
- { /* VBWaitMode1 */
- if ( !( tempal & 0x08 ) )
- {
- continue ;
- }
-
- if ( ( tempal & 0x08 ) )
- {
- break ;
- }
- }
- }
- temp = temp ^ 0x01 ;
- }
- }
- else
- {
- XGI_LongWait(pVBInfo) ;
- }
- return ;
+ unsigned short tempal, temp, i, j;
+ return;
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ temp = 0;
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 100; j++) {
+ tempal = XGINew_GetReg2(pVBInfo->P3da);
+ if (temp & 0x01) { /* VBWaitMode2 */
+ if ((tempal & 0x08))
+ continue;
+
+ if (!(tempal & 0x08))
+ break;
+
+ } else { /* VBWaitMode1 */
+ if (!(tempal & 0x08))
+ continue;
+
+ if ((tempal & 0x08))
+ break;
+ }
+ }
+ temp = temp ^ 0x01;
+ }
+ } else {
+ XGI_LongWait(pVBInfo);
+ }
+ return;
}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVGAHT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
{
- unsigned long tempax ,
- tempbx ;
+ unsigned long tempax, tempbx;
- tempbx = ( ( pVBInfo->VGAVT - pVBInfo->VGAVDE ) * pVBInfo->RVBHCMAX ) & 0xFFFF ;
- tempax = ( pVBInfo->VT - pVBInfo->VDE ) * pVBInfo->RVBHCFACT ;
- tempax = ( tempax * pVBInfo->HT ) /tempbx ;
+ tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
+ & 0xFFFF;
+ tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
+ tempax = (tempax * pVBInfo->HT) / tempbx;
- return( (unsigned short)tempax ) ;
+ return (unsigned short) tempax;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVCLK2Ptr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
- unsigned short ModeIdIndex,
- unsigned short RefreshRateTableIndex,
- struct xgi_hw_device_info *HwDeviceExtension,
- struct vb_device_info *pVBInfo)
-{
- unsigned short tempbx ;
-
- unsigned short LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
- unsigned short LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
- unsigned short LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
- unsigned short LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
- unsigned short LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
-
- unsigned short CRT2Index , VCLKIndex ;
- unsigned short modeflag , resinfo ;
- unsigned char *CHTVVCLKPtr = NULL ;
-
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ResInfo ;
- CRT2Index = pVBInfo->SModeIDTable[ ModeIdIndex ].St_CRT2CRTC ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_RESINFO ;
- CRT2Index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT2CRTC ;
- }
-
- if ( pVBInfo->IF_DEF_LVDS == 0 )
- {
- CRT2Index = CRT2Index >> 6 ; /* for LCD */
- if ( ( ( pVBInfo->VBInfo & SetCRT2ToLCD ) | SetCRT2ToLCDA ) ) /*301b*/
- {
- if ( pVBInfo->LCDResInfo != Panel1024x768 )
- {
- VCLKIndex = LCDXlat2VCLK[ CRT2Index ] ;
- }
- else
- {
- VCLKIndex = LCDXlat1VCLK[ CRT2Index ] ;
- }
- }
- else /* for TV */
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToHiVisionTV )
- {
- if ( pVBInfo->SetFlag & RPLLDIV2XO )
- {
- VCLKIndex = HiTVVCLKDIV2 ;
-
-
- VCLKIndex += 25 ;
-
- }
- else
- {
- VCLKIndex = HiTVVCLK ;
-
-
- VCLKIndex += 25 ;
-
- }
-
- if ( pVBInfo->SetFlag & TVSimuMode )
- {
- if( modeflag & Charx8Dot )
- {
- VCLKIndex = HiTVSimuVCLK ;
-
-
- VCLKIndex += 25 ;
-
- }
- else
- {
- VCLKIndex = HiTVTextVCLK ;
-
-
- VCLKIndex += 25 ;
-
- }
- }
-
- if ( pVBInfo->VBType & VB_XGI301LV ) /* 301lv */
- {
- if ( !( pVBInfo->VBExtInfo == VB_YPbPr1080i ) )
- {
- VCLKIndex = YPbPr750pVCLK ;
- if ( !( pVBInfo->VBExtInfo == VB_YPbPr750p ) )
- {
- VCLKIndex = YPbPr525pVCLK ;
- if ( !( pVBInfo->VBExtInfo == VB_YPbPr525p ) )
- {
- VCLKIndex = YPbPr525iVCLK_2 ;
- if ( !( pVBInfo->SetFlag & RPLLDIV2XO ) )
- VCLKIndex = YPbPr525iVCLK ;
- }
- }
- }
- }
- }
- else
- {
- if ( pVBInfo->VBInfo & SetCRT2ToTV )
- {
- if ( pVBInfo->SetFlag & RPLLDIV2XO )
- {
- VCLKIndex = TVVCLKDIV2 ;
-
-
- VCLKIndex += 25 ;
-
- }
- else
- {
- VCLKIndex = TVVCLK ;
-
-
- VCLKIndex += 25 ;
-
- }
- }
- }
- }
- else
- { /* for CRT2 */
- VCLKIndex = (unsigned char)XGINew_GetReg2((pVBInfo->P3ca + 0x02)); /* Port 3cch */
- VCLKIndex = ( ( VCLKIndex >> 2 ) & 0x03 ) ;
- if ( ModeNo > 0x13 )
- {
- VCLKIndex = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ; /* di+Ext_CRTVCLK */
- VCLKIndex &= IndexMask ;
- }
- }
- }
- }
- else
- { /* LVDS */
- if ( ModeNo <= 0x13 )
- VCLKIndex = CRT2Index ;
- else
- VCLKIndex = CRT2Index ;
-
- if ( pVBInfo->IF_DEF_CH7005 == 1 )
- {
- if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
- {
- VCLKIndex &= 0x1f ;
- tempbx = 0 ;
-
- if ( pVBInfo->VBInfo & SetPALTV )
- tempbx += 2 ;
-
- if ( pVBInfo->VBInfo & SetCHTVOverScan )
- tempbx += 1 ;
-
- switch( tempbx )
- {
- case 0:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
- break ;
- case 1:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
- break;
- case 2:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
- break ;
- case 3:
- CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
- break ;
- default:
- break ;
- }
-
- VCLKIndex = CHTVVCLKPtr[ VCLKIndex ] ;
- }
- }
- else
- {
- VCLKIndex = VCLKIndex >> 6 ;
- if ( ( pVBInfo->LCDResInfo == Panel800x600 ) || ( pVBInfo->LCDResInfo == Panel320x480 ) )
- VCLKIndex = LVDSXlat1VCLK[ VCLKIndex ] ;
- else if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
- VCLKIndex = LVDSXlat2VCLK[ VCLKIndex ] ;
- else
- VCLKIndex = LVDSXlat3VCLK[ VCLKIndex ] ;
- }
- }
- /* VCLKIndex = VCLKIndex&IndexMask ; */
-
-
-
- return( VCLKIndex ) ;
+ unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,
+ struct xgi_hw_device_info *HwDeviceExtension,
+ struct vb_device_info *pVBInfo)
+{
+ unsigned short tempbx;
+
+ unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+ VCLK65 + 2 };
+ unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5,
+ VCLK108_2 + 5, VCLK108_2 + 5 };
+ unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
+ unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+ VCLK65 + 2 };
+ unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
+ VCLK65 + 2 };
+
+ unsigned short CRT2Index, VCLKIndex;
+ unsigned short modeflag, resinfo;
+ unsigned char *CHTVVCLKPtr = NULL;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT2Index
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ if (pVBInfo->IF_DEF_LVDS == 0) {
+ CRT2Index = CRT2Index >> 6; /* for LCD */
+ if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b*/
+ if (pVBInfo->LCDResInfo != Panel1024x768)
+ VCLKIndex = LCDXlat2VCLK[CRT2Index];
+ else
+ VCLKIndex = LCDXlat1VCLK[CRT2Index];
+ } else { /* for TV */
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->SetFlag & RPLLDIV2XO) {
+ VCLKIndex = HiTVVCLKDIV2;
+
+ VCLKIndex += 25;
+
+ } else {
+ VCLKIndex = HiTVVCLK;
+
+ VCLKIndex += 25;
+
+ }
+
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ if (modeflag & Charx8Dot) {
+ VCLKIndex
+ = HiTVSimuVCLK;
+
+ VCLKIndex += 25;
+
+ } else {
+ VCLKIndex
+ = HiTVTextVCLK;
+
+ VCLKIndex += 25;
+
+ }
+ }
+
+ if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */
+ if (!(pVBInfo->VBExtInfo
+ == VB_YPbPr1080i)) {
+ VCLKIndex
+ = YPbPr750pVCLK;
+ if (!(pVBInfo->VBExtInfo
+ == VB_YPbPr750p)) {
+ VCLKIndex
+ = YPbPr525pVCLK;
+ if (!(pVBInfo->VBExtInfo
+ == VB_YPbPr525p)) {
+ VCLKIndex
+ = YPbPr525iVCLK_2;
+ if (!(pVBInfo->SetFlag
+ & RPLLDIV2XO))
+ VCLKIndex
+ = YPbPr525iVCLK;
+ }
+ }
+ }
+ }
+ } else {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->SetFlag
+ & RPLLDIV2XO) {
+ VCLKIndex = TVVCLKDIV2;
+
+ VCLKIndex += 25;
+
+ } else {
+ VCLKIndex = TVVCLK;
+
+ VCLKIndex += 25;
+
+ }
+ }
+ }
+ } else { /* for CRT2 */
+ VCLKIndex = (unsigned char) XGINew_GetReg2(
+ (pVBInfo->P3ca + 0x02)); /* Port 3cch */
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if (ModeNo > 0x13) {
+ VCLKIndex
+ = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */
+ VCLKIndex &= IndexMask;
+ }
+ }
+ }
+ } else { /* LVDS */
+ if (ModeNo <= 0x13)
+ VCLKIndex = CRT2Index;
+ else
+ VCLKIndex = CRT2Index;
+
+ if (pVBInfo->IF_DEF_CH7005 == 1) {
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
+ VCLKIndex &= 0x1f;
+ tempbx = 0;
+
+ if (pVBInfo->VBInfo & SetPALTV)
+ tempbx += 2;
+
+ if (pVBInfo->VBInfo & SetCHTVOverScan)
+ tempbx += 1;
+
+ switch (tempbx) {
+ case 0:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC;
+ break;
+ case 1:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC;
+ break;
+ case 2:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL;
+ break;
+ case 3:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL;
+ break;
+ default:
+ break;
+ }
+
+ VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+ }
+ } else {
+ VCLKIndex = VCLKIndex >> 6;
+ if ((pVBInfo->LCDResInfo == Panel800x600)
+ || (pVBInfo->LCDResInfo == Panel320x480))
+ VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+ else if ((pVBInfo->LCDResInfo == Panel1024x768)
+ || (pVBInfo->LCDResInfo
+ == Panel1024x768x75))
+ VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
+ else
+ VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
+ }
+ }
+ /* VCLKIndex = VCLKIndex&IndexMask; */
+
+ return VCLKIndex;
}
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
index 510ef7678685..78b1c796f01e 100644
--- a/drivers/staging/xgifb/vb_table.h
+++ b/drivers/staging/xgifb/vb_table.h
@@ -1,7 +1,7 @@
#define Tap4
-struct XGI_MCLKDataStruct XGI330New_MCLKData[] =
+static struct XGI_MCLKDataStruct XGI330New_MCLKData[] =
{
{ 0x5c,0x23,0x01,166},
{ 0x5c,0x23,0x01,166},
@@ -13,7 +13,7 @@ struct XGI_MCLKDataStruct XGI330New_MCLKData[] =
{ 0x29,0x01,0x81,300}
};
//yilin modify for xgi20
-struct XGI_MCLKDataStruct XGI340New_MCLKData[] =
+static struct XGI_MCLKDataStruct XGI340New_MCLKData[] =
{
{ 0x16,0x01,0x01,166},
{ 0x19,0x02,0x01,124},
@@ -25,7 +25,7 @@ struct XGI_MCLKDataStruct XGI340New_MCLKData[] =
{ 0x5c,0x23,0x01,166}
};
-struct XGI_MCLKDataStruct XGI27New_MCLKData[] =
+static struct XGI_MCLKDataStruct XGI27New_MCLKData[] =
{
{ 0x5c,0x23,0x01,166},
{ 0x19,0x02,0x01,124},
@@ -37,7 +37,7 @@ struct XGI_MCLKDataStruct XGI27New_MCLKData[] =
{ 0x5c,0x23,0x01,166}
};
-struct XGI_ECLKDataStruct XGI330_ECLKData[] =
+static struct XGI_ECLKDataStruct XGI330_ECLKData[] =
{
{ 0x7c,0x08,0x01,200},
{ 0x7c,0x08,0x01,200},
@@ -49,7 +49,7 @@ struct XGI_ECLKDataStruct XGI330_ECLKData[] =
{ 0x29,0x01,0x81,300}
};
//yilin modify for xgi20
-struct XGI_ECLKDataStruct XGI340_ECLKData[] =
+static struct XGI_ECLKDataStruct XGI340_ECLKData[] =
{
{ 0x5c,0x23,0x01,166},
{ 0x55,0x84,0x01,123},
@@ -63,14 +63,14 @@ struct XGI_ECLKDataStruct XGI340_ECLKData[] =
-unsigned char XGI340_SR13[4][8] = {
+static unsigned char XGI340_SR13[4][8] = {
{0x35,0x45,0xb1,0x00,0x00,0x00,0x00,0x00},/* SR13 */
{0x41,0x51,0x5c,0x00,0x00,0x00,0x00,0x00},/* SR14 */
{0x31,0x42,0x42,0x00,0x00,0x00,0x00,0x00},/* SR18 */
{0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00}/* SR1B */
};
-unsigned char XGI340_cr41[24][8] =
+static unsigned char XGI340_cr41[24][8] =
{{0x20,0x50,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
@@ -98,7 +98,7 @@ unsigned char XGI340_cr41[24][8] =
};
-unsigned char XGI27_cr41[24][8] =
+static unsigned char XGI27_cr41[24][8] =
{
{0x20,0x40,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
{0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
@@ -126,7 +126,7 @@ unsigned char XGI27_cr41[24][8] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
};
-unsigned char XGI340_CR6B[8][4] = {
+static unsigned char XGI340_CR6B[8][4] = {
{0xaa,0xaa,0xaa,0xaa},
{0xaa,0xaa,0xaa,0xaa},
{0xaa,0xaa,0xaa,0xaa},
@@ -137,7 +137,7 @@ unsigned char XGI340_CR6B[8][4] = {
{0x00,0x00,0x00,0x00}
};
-unsigned char XGI340_CR6E[8][4] = {
+static unsigned char XGI340_CR6E[8][4] = {
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
@@ -148,7 +148,7 @@ unsigned char XGI340_CR6E[8][4] = {
{0x00,0x00,0x00,0x00}
};
-unsigned char XGI340_CR6F[8][32] = {
+static unsigned char XGI340_CR6F[8][32] = {
{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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -159,7 +159,7 @@ unsigned char XGI340_CR6F[8][32] = {
{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}
};
-unsigned char XGI340_CR89[8][2] = {
+static unsigned char XGI340_CR89[8][2] = {
{0x00,0x00},
{0x00,0x00},
{0x00,0x00},
@@ -170,12 +170,14 @@ unsigned char XGI340_CR89[8][2] = {
{0x00,0x00}
};
/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
-unsigned char XGI340_AGPReg[12] = {0x28, 0x23, 0x00, 0x20, 0x00, 0x20, 0x00,
+static unsigned char XGI340_AGPReg[12] = {
+ 0x28, 0x23, 0x00, 0x20, 0x00, 0x20, 0x00,
0x05, 0xd0, 0x10, 0x10, 0x00};
-unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83};
+static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83};
-unsigned char XGI330_SR15_1[8][8] = {
+#if 0
+static unsigned char XGI330_SR15_1[8][8] = {
{0x0,0x0,0x00,0x00,0x20,0x20,0x00,0x00},
{0x5,0x15,0x15,0x15,0x15,0x15,0x00,0x00},
{0xba,0xba,0xba,0xba,0xBA,0xBA,0x00,0x00},
@@ -186,7 +188,7 @@ unsigned char XGI330_SR15_1[8][8] = {
{0x0,0xa5,0xfb,0xf6,0xF6,0xF6,0x00,0x00}
};
-unsigned char XGI330_cr40_1[15][8] = {
+static unsigned char XGI330_cr40_1[15][8] = {
{0x66,0x40,0x40,0x28,0x24,0x24,0x00,0x00},
{0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -203,15 +205,16 @@ unsigned char XGI330_cr40_1[15][8] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0xA2,0x00,0x00,0xA2,0xA2,0x00,0x00},
};
+#endif
-unsigned char XGI330_sr25[] = {0x00, 0x0};
-unsigned char XGI330_sr31 = 0xc0;
-unsigned char XGI330_sr32 = 0x11;
-unsigned char XGI330_SR33 = 0x00;
-unsigned char XG40_CRCF = 0x13;
-unsigned char XG40_DRAMTypeDefinition = 0xFF ;
+static unsigned char XGI330_sr25[] = {0x00, 0x0};
+static unsigned char XGI330_sr31 = 0xc0;
+static unsigned char XGI330_sr32 = 0x11;
+static unsigned char XGI330_SR33 = 0x00;
+static unsigned char XG40_CRCF = 0x13;
+static unsigned char XG40_DRAMTypeDefinition = 0xFF ;
-struct XGI_StStruct XGI330_SModeIDTable[] =
+static struct XGI_StStruct XGI330_SModeIDTable[] =
{
{0x01,0x9208,0x01,0x00,0x10,0x00,0x00,0x01,0x00},
{0x01,0x1210,0x14,0x01,0x00,0x01,0x00,0x01,0x00},
@@ -236,7 +239,7 @@ struct XGI_StStruct XGI330_SModeIDTable[] =
};
-struct XGI_ExtStruct XGI330_EModeIDTable[] =
+static struct XGI_ExtStruct XGI330_EModeIDTable[] =
{
{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x0e},
{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x06},
@@ -308,7 +311,7 @@ struct XGI_ExtStruct XGI330_EModeIDTable[] =
{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
};
-struct XGI_StandTableStruct XGI330_StandTable[] =
+static struct XGI_StandTableStruct XGI330_StandTable[] =
{
/* MD_0_200 */
{
@@ -746,13 +749,13 @@ struct XGI_StandTableStruct XGI330_StandTable[] =
}
};
-struct XGI_TimingHStruct XGI_TimingH[] =
+static struct XGI_TimingHStruct XGI_TimingH[] =
{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
-struct XGI_TimingVStruct XGI_TimingV[] =
+static struct XGI_TimingVStruct XGI_TimingV[] =
{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
-struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] =
+static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] =
{
{0x01,0x27,0x91,0x8f,0xc0}, /* 00 */
{0x03,0x4f,0x83,0x8f,0xc0}, /* 01 */
@@ -773,7 +776,7 @@ struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] =
{0x59,0x27,0x91,0x8f,0xc0} /* 16 */
};
-struct XGI_CRT1TableStruct XGI_CRT1Table[] =
+static struct XGI_CRT1TableStruct XGI_CRT1Table[] =
{
{{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
0xbf,0x1f,0x9c,0x8e,0x96,0xb9,0x30}}, /* 0x0 */
@@ -921,7 +924,8 @@ struct XGI_CRT1TableStruct XGI_CRT1Table[] =
0x03,0xDE,0xC0,0x84,0xBF,0x04,0x90}} /* 0x47 */
};
-struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
+#if 0
+static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
/* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
{{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
{{ 0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
@@ -932,7 +936,7 @@ struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
{{ 0xEE,0x77,0xBB,0x66,0x87,0x32,0x01,0x5A,0x04,0x00,0x80,0x1B,0xD4,0x2F,0x6F,0x00 }}/* 06 (1024x768) ;;5/6/02 */
};
-struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = {
+static struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = {
/* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
{{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
{{ 0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
@@ -943,7 +947,7 @@ struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = {
{{ 0xED,0x77,0xBB,0x66,0x8C,0x21,0x02,0x5A,0x04,0x00,0x80,0x1F,0xA0,0x7E,0x73,0x00 }}/* 06 (1024x768) ;;5/6/02 */
};
-struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = {
+static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = {
/* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
{{ 0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 00 (640x200,640x400) */
{{ 0x41,0x7F,0xB7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* ; 01 (640x350) */
@@ -954,7 +958,7 @@ struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = {
{{ 0xE5,0x7F,0xB7,0x1D,0xA7,0x3E,0x04,0x5A,0x05,0x00,0x80,0x20,0x3E,0xE4,0x22,0x00 }}/* ; 06 (1024x768) ;;1/12/02 */
};
-struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = {
+static struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = {
/* Index:000,0x01,0x02,0x04,0x03,0x05,0x06,0x07,0x08,0x15,0x1F,0x0C,0x0D,0x0E,0x0F,0x10h */
{{ 0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
{{ 0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
@@ -964,15 +968,18 @@ struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = {
{{ 0xC1,0x7F,0xB7,0x4D,0x8C,0x1E,0x31,0x5A,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00 }},/* 05 (800x600) ;;1/12/02 */
{{ 0xE4,0x7F,0xB7,0x1E,0xAF,0x29,0x37,0x5A,0x05,0x00,0x80,0x25,0x8C,0xB2,0x2A,0x00 }}/* 06 (1024x768) ;;1/12/02 */
};
+#endif
-unsigned char XGI_CH7017LV1024x768[] = {0x60, 0x02, 0x00, 0x07, 0x40, 0xED, 0xA3,
+static unsigned char XGI_CH7017LV1024x768[] = {
+ 0x60, 0x02, 0x00, 0x07, 0x40, 0xED, 0xA3,
0xC8, 0xC7, 0xAC, 0xE0, 0x02};
-unsigned char XGI_CH7017LV1400x1050[] = {0x60, 0x03, 0x11, 0x00, 0x40, 0xE3, 0xAD,
+static unsigned char XGI_CH7017LV1400x1050[] = {
+ 0x60, 0x03, 0x11, 0x00, 0x40, 0xE3, 0xAD,
0xDB, 0xF6, 0xAC, 0xE0, 0x02};
/*add for new UNIVGABIOS*/
-struct XGI330_LCDDataStruct XGI_StLCD1024x768Data[] =
+static struct XGI330_LCDDataStruct XGI_StLCD1024x768Data[] =
{
{ 62, 25, 800, 546,1344, 806},
{ 32, 15, 930, 546,1344, 806},
@@ -983,7 +990,7 @@ struct XGI330_LCDDataStruct XGI_StLCD1024x768Data[] =
{ 1, 1,1344, 806,1344, 806}
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] =
{
{ 42, 25,1536, 419,1344, 806}, /* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */
{ 48, 25,1536, 369,1344, 806}, /* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */
@@ -1011,7 +1018,7 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] =
{ 1, 1,1344, 806,1344, 806}
};*/
-struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] =
+static struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] =
{
{ 1,1,1344,806,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 1,1,1344,806,1344,806 }, /* 01 (320x350,640x350) */
@@ -1022,7 +1029,7 @@ struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] =
{ 1,1,1344,806,1344,806 } /* 06 (1024x768x60Hz) */
};
-struct XGI330_LCDDataStruct XGI_StLCD1280x1024Data[] =
+static struct XGI330_LCDDataStruct XGI_StLCD1280x1024Data[] =
{
{ 22, 5, 800, 510,1650,1088},
{ 22, 5, 800, 510,1650,1088},
@@ -1034,7 +1041,7 @@ struct XGI330_LCDDataStruct XGI_StLCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
@@ -1046,7 +1053,8 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-struct XGI330_LCDDataStruct XGI_St2LCD1280x1024Data[] =
+#if 0
+static struct XGI330_LCDDataStruct XGI_St2LCD1280x1024Data[] =
{
{ 22, 5, 800, 510,1650,1088},
{ 22, 5, 800, 510,1650,1088},
@@ -1057,8 +1065,9 @@ struct XGI330_LCDDataStruct XGI_St2LCD1280x1024Data[] =
{ 16, 9,1266, 804,1688,1072},
{ 1, 1,1688,1066,1688,1066}
};
+#endif
-struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] =
+static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] =
{
{ 1,1,1688,1066,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1,1,1688,1066,1688,1066 }, /* 01 (320x350,640x350) */
@@ -1071,7 +1080,7 @@ struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] =
{ 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataStruct XGI_StLCD1400x1050Data[] =
+static struct XGI330_LCDDataStruct XGI_StLCD1400x1050Data[] =
{
{ 211,100,2100,408,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 211,64,1536,358,1688,1066 }, /* 01 (320x350,640x350) */
@@ -1084,7 +1093,7 @@ struct XGI330_LCDDataStruct XGI_StLCD1400x1050Data[] =
{ 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1400x1050Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1400x1050Data[] =
{
{ 211,100,2100,408,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 211,64,1536,358,1688,1066 }, /* 01 (320x350,640x350) */
@@ -1097,7 +1106,7 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1400x1050Data[] =
{ 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[] =
{
{ 4,1,1620,420,2160,1250 }, /* { 3,1,2160,425,2160,1250 }, // 00 (320x200,320x400,640x200,640x400) // alan 10/14/2003 */
{ 27,7,1920,375,2160,1250 }, /* 01 (320x350,640x350) */
@@ -1111,7 +1120,7 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1600x1200Data[] =
{ 1,1,2160,1250,2160,1250 } /* 09 (1600x1200x60Hz) ;302lv */
};
-struct XGI330_LCDDataStruct XGI_StLCD1600x1200Data[] =
+static struct XGI330_LCDDataStruct XGI_StLCD1600x1200Data[] =
{
{ 27,4,800,500,2160,1250 },/* 00 (320x200,320x400,640x200,640x400) */
{ 27,4,800,500,2160,1250 },/* 01 (320x350,640x350) */
@@ -1125,7 +1134,7 @@ struct XGI330_LCDDataStruct XGI_StLCD1600x1200Data[] =
{ 1,1,2160,1250,2160,1250 } /* 09 (1600x1200) */
};
-struct XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[] =
+static struct XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[] =
{
{ 1,1,1688,1066,1688,1066 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1,1,1688,1066,1688,1066 }, /* 01 (320x350,640x350) */
@@ -1138,7 +1147,7 @@ struct XGI330_LCDDataStruct XGI_CetLCD1400x1050Data[] =
{ 1,1,1688,1066,1688,1066 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataStruct XGI_NoScalingData[] =
+static struct XGI330_LCDDataStruct XGI_NoScalingData[] =
{
{ 1, 1, 800, 449, 800, 449},
{ 1, 1, 800, 449, 800, 449},
@@ -1150,7 +1159,7 @@ struct XGI330_LCDDataStruct XGI_NoScalingData[] =
{ 1, 1,1688,1066,1688,1066}
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] =
{
{42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
@@ -1161,7 +1170,8 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] =
{1,1,1312,800,1312,800 } /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LCDDataStruct XGI_StLCD1024x768x75Data[] =
+#if 0
+static struct XGI330_LCDDataStruct XGI_StLCD1024x768x75Data[] =
{
{42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
@@ -1171,8 +1181,9 @@ struct XGI330_LCDDataStruct XGI_StLCD1024x768x75Data[] =
{41,25,1024,625,1312,800 }, /* ; 05 (800x600x75Hz) */
{1,1,1312,800,1312,800 } /* ; 06 (1024x768x75Hz) */
};
+#endif
-struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] =
+static struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] =
{
{1,1,1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1,1,1312,800,1312,800}, /* ; 01 (320x350,640x350) */
@@ -1183,7 +1194,7 @@ struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] =
{1,1,1312,800,1312,800} /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024x75Data[] =
+static struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024x75Data[] =
{
{211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -1195,7 +1206,7 @@ struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024x75Data[] =
{1,1,1688,1066,1688,1066 } /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataStruct XGI_StLCD1280x1024x75Data[] =
+static struct XGI330_LCDDataStruct XGI_StLCD1280x1024x75Data[] =
{
{211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -1207,7 +1218,7 @@ struct XGI330_LCDDataStruct XGI_StLCD1280x1024x75Data[] =
{1,1,1688,1066,1688,1066 } /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[] =
+static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[] =
{
{1,1,1688,1066,1688,1066}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1,1,1688,1066,1688,1066}, /* ; 01 (320x350,640x350) */
@@ -1219,7 +1230,7 @@ struct XGI330_LCDDataStruct XGI_CetLCD1280x1024x75Data[] =
{1,1,1688,1066,1688,1066} /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] =
+static struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] =
{
{1,1,800,449,800,449 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1,1,800,449,800,449 }, /* ; 01 (320x350,640x350) */
@@ -1234,7 +1245,7 @@ struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] =
{1,1,1688,806,1688,806 } /* ; 0A (1280x768x75Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] =
{
{ 9,1057,0, 771 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 9,1057,0, 771 }, /* ; 01 (320x350,640x350) */
@@ -1245,7 +1256,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] =
{ 9,1057,805, 770 } /* ; 06 (1024x768x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] =
{
{ 9,1057,737,703 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 9,1057,686,651 }, /* ; 01 (320x350,640x350) */
@@ -1256,7 +1267,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] =
{ 9,1057,805,770 } /* ; 06 (1024x768x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] =
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] =
{
{ 1152,856,622,587 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 1152,856,597,562 }, /* ; 01 (320x350,640x350) */
@@ -1267,7 +1278,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] =
{ 0,1048,805,770 } /* ; 06 (1024x768x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] =
{
{ 18,1346,981,940 },/* 00 (320x200,320x400,640x200,640x400) */
{ 18,1346,926,865 },/* 01 (320x350,640x350) */
@@ -1279,7 +1290,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] =
{ 18,1346,1065,1024 }/* 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] =
{
{ 18,1346,970,907 },/* 00 (320x200,320x400,640x200,640x400) */
{ 18,1346,917,854 },/* 01 (320x350,640x350) */
@@ -1291,7 +1302,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] =
{ 18,1346,1065,1024 }/* 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] =
{
{ 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1368,1008,729,688 }, /* 01 (320x350,640x350) */
@@ -1303,7 +1314,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] =
{ 18,1346,1065,1024 } /* 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] =
{
{ 9,1337,981,940 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 9,1337,926,884 }, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
@@ -1315,7 +1326,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] =
{ 9,1337,1065,1024 } /* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] =
{
{ 9,1337,970,907 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 9,1337,917,854 }, /* ; 01 (320x350,640x350) */
@@ -1327,7 +1338,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] =
{ 9,1337,1065,1024 } /* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] =
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] =
{
{ 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1368,1008,729,688 }, /* 01 (320x350,640x350) */
@@ -1339,7 +1350,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] =
{ 9,1337,1065,1024 } /* 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1400x1050Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1400x1050Data[] =
{
{ 18,1464,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 18,1464,0,1051 }, /* 01 (320x350,640x350) */
@@ -1352,7 +1363,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1400x1050Data[] =
{ 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1400x1050Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1400x1050Data[] =
{
{ 18,1464,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 18,1464,0,1051 }, /* 01 (320x350,640x350) */
@@ -1365,7 +1376,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1400x1050Data[] =
{ 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1400x1050Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1400x1050Data[] =
{
{ 9,1455,0,1051 },/* 00 (320x200,320x400,640x200,640x400) */
{ 9,1455,0,1051 },/* 01 (320x350,640x350) */
@@ -1378,7 +1389,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1400x1050Data[] =
{ 9,1455,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1400x1050Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1400x1050Data[] =
{
{ 9,1455,0,1051 },/* 00 (320x200,320x400,640x200,640x400) */
{ 9,1455,0,1051 },/* 01 (320x350,640x350) */
@@ -1391,7 +1402,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1400x1050Data[] =
{ 9,1455,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] =
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] =
{
{ 1308,1068,781,766 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1308,1068,781,766 }, /* 01 (320x350,640x350) */
@@ -1404,7 +1415,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] =
{ 18,1464,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] =
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] =
{
{ 0,1448,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0,1448,0,1051 }, /* 01 (320x350,640x350) */
@@ -1415,7 +1426,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] =
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] =
{
{ 18,1682,0,1201 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 18,1682,0,1201 }, /* 01 (320x350,640x350) */
@@ -1429,7 +1440,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] =
{ 18,1682,0,1201 } /* 09 (1600x1200x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] =
{
{ 18,1682,1150,1101 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 18,1682,1083,1034 }, /* 01 (320x350,640x350) */
@@ -1443,7 +1454,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] =
{ 18,1682,0,1201 } /* 09 (1600x1200x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] =
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] =
{
{ 9,1673,0,1201 },/* 00 (320x200,320x400,640x200,640x400) */
{ 9,1673,0,1201 },/* 01 (320x350,640x350) */
@@ -1457,7 +1468,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] =
{ 9,1673,0,1201 } /* 09 (1600x1200x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[] =
{
{ 9,1673,1150,1101 },/* 00 (320x200,320x400,640x200,640x400) */
{ 9,1673,1083,1034 },/* 01 (320x350,640x350) */
@@ -1471,7 +1482,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[] =
{ 9,1673,0,1201 } /* 09 (1600x1200x60Hz) */
};
-struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] =
+static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] =
{
{ 9,657,448,405,96,2 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 9,657,448,355,96,2 }, /* 01 (320x350,640x350) */
@@ -1486,7 +1497,7 @@ struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] =
{ 9,1337,0,771,112,6 } /* 0A (1280x768x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768x75Data[] = /* ;;1024x768x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768x75Data[] = /* ;;1024x768x75Hz */
{
{9,1049,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9,1049,0,769}, /* ; 01 (320x350,640x350) */
@@ -1497,7 +1508,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768x75Data[] = /* ;;1024x768x
{9,1049,0,769} /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768x75Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768x75Data[] =
{
{9,1049,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9,1049,0,769}, /* ; 01 (320x350,640x350) */
@@ -1508,7 +1519,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768x75Data[] =
{9,1049,0,769} /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = /* ;;1024x768x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = /* ;;1024x768x75Hz */
{
{1152,856,622,587}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1152,856,597,562}, /* ; 01 (320x350,640x350) */
@@ -1519,7 +1530,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = /* ;;1024x768x7
{9,1049,0,769} /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024x75Data[] = /* ;;1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024x75Data[] = /* ;;1280x1024x75Hz */
{
{18,1314,0,1025 },/* ; 00 (320x200,320x400,640x200,640x400) */
{18,1314,0,1025 },/* ; 01 (320x350,640x350) */
@@ -1531,7 +1542,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024x75Data[] = /* ;
{18,1314,0,1025 }/* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024x75Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024x75Data[] =
{
{18,1314,0,1025 },/* ; 00 (320x200,320x400,640x200,640x400) */
{18,1314,0,1025 },/* ; 01 (320x350,640x350) */
@@ -1543,7 +1554,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024x75Data[] =
{18,1314,0,1025 }/* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = /* 1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = /* 1280x1024x75Hz */
{
{1368,1008,752,711}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368,1008,729,688}, /* ; 01 (320x350,640x350) */
@@ -1555,7 +1566,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = /* 1280x1024
{18,1314,0,1025} /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024x75Data[] = /* ;;1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024x75Data[] = /* ;;1280x1024x75Hz */
{
{9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
{9,1305,0,1025},/* ; 01 (320x350,640x350) */
@@ -1567,7 +1578,7 @@ struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024x75Data[] = /* ;;1
{9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024x75Data[] =
+static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024x75Data[] =
{
{9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
{9,1305,0,1025},/* ; 01 (320x350,640x350) */
@@ -1579,7 +1590,7 @@ struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024x75Data[] =
{9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
};
-struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[] = /* 1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[] = /* 1280x1024x75Hz */
{
{1368,1008,752,711}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368,1008,729,688}, /* ; 01 (320x350,640x350) */
@@ -1591,7 +1602,7 @@ struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[] = /* 1280x1024x7
{9,1305,0,1025} /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = /* Scaling LCD 75Hz */
+static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = /* Scaling LCD 75Hz */
{
{9,657,448,405,96,2}, /* ; 00 (320x200,320x400,640x200,640x400) */
{9,657,448,355,96,2}, /* ; 01 (320x350,640x350) */
@@ -1606,7 +1617,7 @@ struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = /* Scaling LCD 75Hz
{9,1337,0,771,112,6} /* ; 0A (1280x768x60Hz) */
};
-struct XGI330_TVDataStruct XGI_StPALData[] =
+static struct XGI330_TVDataStruct XGI_StPALData[] =
{
{ 1, 1, 864, 525,1270, 400, 100, 0, 760},
{ 1, 1, 864, 525,1270, 350, 100, 0, 760},
@@ -1616,7 +1627,7 @@ struct XGI330_TVDataStruct XGI_StPALData[] =
{ 1, 1, 864, 525,1270, 600, 50, 0, 0}
};
-struct XGI330_TVDataStruct XGI_ExtPALData[] =
+static struct XGI330_TVDataStruct XGI_ExtPALData[] =
{
{ 2, 1,1080, 463,1270, 500, 50, 0, 50},
{ 15, 7,1152, 413,1270, 500, 50, 0, 50},
@@ -1628,7 +1639,7 @@ struct XGI330_TVDataStruct XGI_ExtPALData[] =
{ 3, 2,1080, 619,1270, 540, 438, 0, 438}
};
-struct XGI330_TVDataStruct XGI_StNTSCData[] =
+static struct XGI330_TVDataStruct XGI_StNTSCData[] =
{
{ 1, 1, 858, 525,1270, 400, 50, 0, 760},
{ 1, 1, 858, 525,1270, 350, 50, 0, 640},
@@ -1637,7 +1648,7 @@ struct XGI330_TVDataStruct XGI_StNTSCData[] =
{ 1, 1, 858, 525,1270, 480, 0, 0, 760}
};
-struct XGI330_TVDataStruct XGI_ExtNTSCData[] =
+static struct XGI330_TVDataStruct XGI_ExtNTSCData[] =
{
{ 9, 5, 1001, 453,1270, 420, 171, 0, 171},
{ 12, 5, 858, 403,1270, 420, 171, 0, 171},
@@ -1650,7 +1661,7 @@ struct XGI330_TVDataStruct XGI_ExtNTSCData[] =
{ 3, 2,1001, 533,1270, 420, 0, 0, 0}
};
-struct XGI330_TVDataStruct XGI_St1HiTVData[] =
+static struct XGI330_TVDataStruct XGI_St1HiTVData[] =
{
{ 1,1,892,563,690,800,0,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1,1,892,563,690,700,0,0,0 }, /* 01 (320x350,640x350) */
@@ -1660,7 +1671,7 @@ struct XGI330_TVDataStruct XGI_St1HiTVData[] =
{ 8,5,1050,683,1648,960,0x150,1,0 } /* 05 (400x300,800x600) */
};
-struct XGI330_TVDataStruct XGI_St2HiTVData[] =
+static struct XGI330_TVDataStruct XGI_St2HiTVData[] =
{
{ 3,1,840,483,1648,960,0x032,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1,1,892,563,690,700,0,0,0 }, /* 01 (320x350,640x350) */
@@ -1671,7 +1682,7 @@ struct XGI330_TVDataStruct XGI_St2HiTVData[] =
};
-struct XGI330_TVDataStruct XGI_ExtHiTVData[] =
+static struct XGI330_TVDataStruct XGI_ExtHiTVData[] =
{
{ 6,1,840,563,1632,960,0,0,0 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 3,1,960,563,1632,960,0,0,0 }, /* 01 (320x350,640x350) */
@@ -1687,7 +1698,7 @@ struct XGI330_TVDataStruct XGI_ExtHiTVData[] =
};
-struct XGI330_TVDataStruct XGI_ExtYPbPr525iData[] =
+static struct XGI330_TVDataStruct XGI_ExtYPbPr525iData[] =
{
{ 9, 5, 1001, 453,1270, 420, 171, 0, 171},
{ 12, 5, 858, 403,1270, 420, 171, 0, 171},
@@ -1700,7 +1711,7 @@ struct XGI330_TVDataStruct XGI_ExtYPbPr525iData[] =
{ 3, 2,1001, 533,1250, 420, 0, 0, 0}
};
-struct XGI330_TVDataStruct XGI_StYPbPr525iData[] =
+static struct XGI330_TVDataStruct XGI_StYPbPr525iData[] =
{
{ 1, 1, 858, 525,1270, 400, 50, 0, 760},
{ 1, 1, 858, 525,1270, 350, 50, 0, 640},
@@ -1709,7 +1720,7 @@ struct XGI330_TVDataStruct XGI_StYPbPr525iData[] =
{ 1, 1, 858, 525,1270, 480, 0, 0, 760},
};
-struct XGI330_TVDataStruct XGI_ExtYPbPr525pData[] =
+static struct XGI330_TVDataStruct XGI_ExtYPbPr525pData[] =
{
{ 9, 5, 1001, 453,1270, 420, 171, 0, 171},
{ 12, 5, 858, 403,1270, 420, 171, 0, 171},
@@ -1722,7 +1733,7 @@ struct XGI330_TVDataStruct XGI_ExtYPbPr525pData[] =
{ 3, 2,1001, 533,1270, 420, 0, 0, 0}
};
-struct XGI330_TVDataStruct XGI_StYPbPr525pData[] =
+static struct XGI330_TVDataStruct XGI_StYPbPr525pData[] =
{
{ 1, 1,1716, 525,1270, 400, 50, 0, 760},
{ 1, 1,1716, 525,1270, 350, 50, 0, 640},
@@ -1731,7 +1742,7 @@ struct XGI330_TVDataStruct XGI_StYPbPr525pData[] =
{ 1, 1,1716, 525,1270, 480, 0, 0, 760},
};
-struct XGI330_TVDataStruct XGI_ExtYPbPr750pData[] =
+static struct XGI330_TVDataStruct XGI_ExtYPbPr750pData[] =
{
{ 3, 1, 935, 470,1130, 680, 50, 0, 0}, /* 00 (320x200,320x400,640x200,640x400) */
{ 24, 7, 935, 420,1130, 680, 50, 0, 0}, /* 01 (320x350,640x350) */
@@ -1746,7 +1757,7 @@ struct XGI330_TVDataStruct XGI_ExtYPbPr750pData[] =
{ 10, 9,1320, 830,1130, 640, 50, 0, 0}
};
-struct XGI330_TVDataStruct XGI_StYPbPr750pData[] =
+static struct XGI330_TVDataStruct XGI_StYPbPr750pData[] =
{
{ 1, 1,1650, 750,1280, 400, 50, 0, 760},
{ 1, 1,1650, 750,1280, 350, 50, 0, 640},
@@ -1755,7 +1766,7 @@ struct XGI330_TVDataStruct XGI_StYPbPr750pData[] =
{ 1, 1,1650, 750,1280, 480, 0, 0, 760},
};
-unsigned char XGI330_NTSCTiming[] = {
+static unsigned char XGI330_NTSCTiming[] = {
0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -1765,7 +1776,7 @@ unsigned char XGI330_NTSCTiming[] = {
0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
-unsigned char XGI330_PALTiming[] = {
+static unsigned char XGI330_PALTiming[] = {
0x21,0x5A,0x35,0x6e,0x04,0x38,0x3d,0x70,
0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -1775,7 +1786,7 @@ unsigned char XGI330_PALTiming[] = {
0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
-unsigned char XGI330_HiTVExtTiming[] =
+static unsigned char XGI330_HiTVExtTiming[] =
{
0x2D,0x60,0x2C,0x5F,0x08,0x31,0x3A,0x64,
0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1789,7 +1800,7 @@ unsigned char XGI330_HiTVExtTiming[] =
};
-unsigned char XGI330_HiTVSt1Timing[] =
+static unsigned char XGI330_HiTVSt1Timing[] =
{
0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1802,7 +1813,7 @@ unsigned char XGI330_HiTVSt1Timing[] =
0x0E,0x00,0xfc,0xff,0x2d,0x00
};
-unsigned char XGI330_HiTVSt2Timing[] =
+static unsigned char XGI330_HiTVSt2Timing[] =
{
0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x64,
0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1815,7 +1826,7 @@ unsigned char XGI330_HiTVSt2Timing[] =
0x27,0x00,0xFC,0xff,0x6a,0x00
};
-unsigned char XGI330_HiTVTextTiming[] =
+static unsigned char XGI330_HiTVTextTiming[] =
{
0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
@@ -1828,7 +1839,7 @@ unsigned char XGI330_HiTVTextTiming[] =
0x11,0x00,0xFC,0xFF,0x32,0x00
};
-unsigned char XGI330_YPbPr750pTiming[] =
+static unsigned char XGI330_YPbPr750pTiming[] =
{
0x30,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
@@ -1841,7 +1852,7 @@ unsigned char XGI330_YPbPr750pTiming[] =
0x11,0x00,0xfc,0xff,0x32,0x00
};
-unsigned char XGI330_YPbPr525pTiming[] =
+static unsigned char XGI330_YPbPr525pTiming[] =
{
0x3E,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
@@ -1854,7 +1865,7 @@ unsigned char XGI330_YPbPr525pTiming[] =
0x11,0x00,0xFC,0xFF,0x32,0x00
};
-unsigned char XGI330_YPbPr525iTiming[] =
+static unsigned char XGI330_YPbPr525iTiming[] =
{
0x1B,0x21,0x03,0x09,0x05,0x06,0x0C,0x0C,
0x94,0x49,0x01,0x0A,0x06,0x0D,0x04,0x0A,
@@ -1868,7 +1879,7 @@ unsigned char XGI330_YPbPr525iTiming[] =
};
-unsigned char XGI330_HiTVGroup3Data[] =
+static unsigned char XGI330_HiTVGroup3Data[] =
{
0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x5F,
0x05,0x21,0xB2,0xB2,0x55,0x77,0x2A,0xA6,
@@ -1880,7 +1891,7 @@ unsigned char XGI330_HiTVGroup3Data[] =
0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
};
-unsigned char XGI330_HiTVGroup3Simu[] =
+static unsigned char XGI330_HiTVGroup3Simu[] =
{
0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x95,
0xDB,0x20,0xB8,0xB8,0x55,0x47,0x2A,0xA6,
@@ -1892,7 +1903,7 @@ unsigned char XGI330_HiTVGroup3Simu[] =
0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
};
-unsigned char XGI330_HiTVGroup3Text[] =
+static unsigned char XGI330_HiTVGroup3Text[] =
{
0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0xA7,
0xF5,0x20,0xCE,0xCE,0x55,0x47,0x2A,0xA6,
@@ -1904,7 +1915,7 @@ unsigned char XGI330_HiTVGroup3Text[] =
0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
};
-unsigned char XGI330_Ren525pGroup3[] =
+static unsigned char XGI330_Ren525pGroup3[] =
{
0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x13,
0xB1,0x41,0x62,0x62,0xFF,0xF4,0x45,0xa6,
@@ -1916,7 +1927,7 @@ unsigned char XGI330_Ren525pGroup3[] =
0x1a,0x1F,0x25,0x2a,0x4C,0xAA,0x01
};
-unsigned char XGI330_Ren750pGroup3[] =
+static unsigned char XGI330_Ren750pGroup3[] =
{
0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x7a,
0x54,0x41,0xE7,0xE7,0xFF,0xF4,0x45,0xa6,
@@ -1928,7 +1939,8 @@ unsigned char XGI330_Ren750pGroup3[] =
0x18,0x1D,0x23,0x28,0x4C,0xAA,0x01
};
-struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] =
+#if 0
+static struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] =
{
{{0x00,0x00}},
{{0x00,0x00}},
@@ -1948,7 +1960,7 @@ struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] =
{{0x00,0x00}}
};
-struct XGI330_LVDSDataStruct XGI330_LVDS320x480Data_1[] =
+static struct XGI330_LVDSDataStruct XGI330_LVDS320x480Data_1[] =
{
{848, 433,400,525},
{848, 389,400,525},
@@ -1961,7 +1973,7 @@ struct XGI330_LVDSDataStruct XGI330_LVDS320x480Data_1[] =
{800, 525,1000, 635}
};
-struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_1[] =
+static struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_1[] =
{
{848, 433,1060, 629},
{848, 389,1060, 629},
@@ -1974,7 +1986,7 @@ struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_1[] =
{800, 525,1000, 635}
};
-struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_2[] =
+static struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_2[] =
{
{1056, 628,1056, 628},
{1056, 628,1056, 628},
@@ -1986,8 +1998,9 @@ struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_2[] =
{800, 449,1000, 644},
{800, 525,1000, 635}
};
+#endif
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] =
{
{ 960 , 438 , 1344 , 806 } , /* 00 (320x200,320x400,640x200,640x400) */
{ 960 , 388 , 1344 , 806 } , /* 01 (320x350,640x350) */
@@ -1999,7 +2012,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] =
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[] =
{
{1344, 806,1344, 806},
{1344, 806,1344, 806},
@@ -2012,7 +2025,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2[] =
{800, 525,1280, 813}
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[] =
{
{1048, 442,1688, 1066},
{1048, 392,1688, 1066},
@@ -2024,7 +2037,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1[] =
{1688, 1066,1688, 1066}
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[] =
{
{1344, 806,1344, 806},
{1344, 806,1344, 806},
@@ -2115,7 +2128,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x768SData_2[] =
{1688,806,1688,806}
};
*/
-struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] =
{
{928,416,1688,1066},
{928,366,1688,1066},
@@ -2128,7 +2141,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] =
{1688,1066,1688,1066}
};
-struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[] =
{
{1688,1066,1688,1066},
{1688,1066,1688,1066},
@@ -2141,7 +2154,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_2[] =
{1688,1066,1688,1066}
};
-struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] =
{ /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
{ 1088,520,2048,1320 },/* 00 (320x200,320x400,640x200,640x400) */
{ 1088,470,2048,1320 },/* 01 (320x350,640x350) */
@@ -2155,7 +2168,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] =
{ 2048,1320,2048,1320 } /* 09 (1600x1200) */
};
-struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] =
+static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] =
{
{ 800,449,800,449 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 800,449,800,449 }, /* 01 (320x350,640x350) */
@@ -2170,7 +2183,7 @@ struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] =
{ 1688,806,1688,806 } /* 0A (1280x768x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] =
{
{960,438,1312,800 }, /* 00 (320x200,320x400,640x200,640x400) */
{960,388,1312,800 }, /* 01 (320x350,640x350) */
@@ -2182,7 +2195,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] =
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] =
{
{1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
{1312,800,1312,800}, /* ; 01 (320x350,640x350) */
@@ -2193,7 +2206,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] =
{1312,800,1312,800}, /* ; 06 (512x384,1024x768) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] =
{
{1048,442,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1048,392,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -2205,7 +2218,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] =
{1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] =
{
{1688,1066,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1688,1066,1688,1066 }, /* ; 01 (320x350,640x350) */
@@ -2217,7 +2230,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] =
{1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
};
-struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] =
{
{800,449,800,449 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{800,449,800,449 }, /* ; 01 (320x350,640x350) */
@@ -2232,7 +2245,7 @@ struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] =
{1688,806,1688,806 }, /* ; 0A (1280x768x75Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] =
{
{ 0,1048, 0, 771 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0,1048, 0, 771 }, /* 01 (320x350,640x350) */
@@ -2243,7 +2256,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] =
{ 0,1048, 805, 770 } /* 06 (1024x768x60Hz) */
} ;
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] =
{
{ 1142, 856, 622, 587 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1142, 856, 597, 562 }, /* 01 (320x350,640x350) */
@@ -2254,7 +2267,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] =
{ 0,1048, 805, 771 } /* 06 (1024x768x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] =
{
{ 320, 24, 622, 587 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 320, 24, 597, 562 }, /* 01 (320x350,640x350) */
@@ -2263,7 +2276,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] =
{ 320, 24, 722, 687 } /* 04 (640x480x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] =
{
{ 0,1328, 0, 1025 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0,1328, 0, 1025 }, /* 01 (320x350,640x350) */
@@ -2276,7 +2289,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] =
};
/* The Display setting for DE Mode Panel */
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] =
{
{ 1368,1008,752,711 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1368,1008,729,688 }, /* 01 (320x350,640x350) */
@@ -2288,7 +2301,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] =
{ 0000,1328,0,1025 } /* 07 (1280x1024x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] =
{
{ 0,1448,0,1051 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0,1448,0,1051 }, /* 01 (320x350,640x350) */
@@ -2301,7 +2314,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] =
{ 0,1448,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] =
{
{ 1308,1068, 781, 766 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 1308,1068, 781, 766 }, /* 01 (320x350,640x350) */
@@ -2314,7 +2327,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] =
{ 0,1448,0,1051 } /* 08 (1400x1050x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] =
{
{ 0,1664,0,1201 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0,1664,0,1201 }, /* 01 (320x350,640x350) */
@@ -2330,7 +2343,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] =
-struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] =
+static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] =
{
{ 0, 648, 448, 405, 96, 2 }, /* 00 (320x200,320x400,640x200,640x400) */
{ 0, 648, 448, 355, 96, 2 }, /* 01 (320x350,640x350) */
@@ -2345,7 +2358,7 @@ struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] =
{ 0,1328,0,0771, 112, 6 } /* 0A (1280x768x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = /* ; 1024x768 Full-screen */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = /* ; 1024x768 Full-screen */
{
{0,1040,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
{0,1040,0,769}, /* ; 01 (320x350,640x350) */
@@ -2356,7 +2369,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = /* ; 1024x768 Full-s
{0,1040,0,769} /* ; 06 (1024x768x75Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = /* ; 1024x768 center-screen (Enh. Mode) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = /* ; 1024x768 center-screen (Enh. Mode) */
{
{1142, 856,622,587 }, /* 00 (320x200,320x400,640x200,640x400) */
{1142, 856,597,562 }, /* 01 (320x350,640x350) */
@@ -2367,7 +2380,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = /* ; 1024x768 center-s
{ 0,1048,805,771 } /* 06 (1024x768x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = /* ; 1024x768 center-screen (St.Mode) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = /* ; 1024x768 center-screen (St.Mode) */
{
{320,24,622,587 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{320,24,597,562 }, /* ; 01 (320x350,640x350) */
@@ -2376,7 +2389,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = /* ; 1024x768 center-s
{320,24,722,687 } /* ; 04 (640x480x60Hz) */
};
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] =
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] =
{
{0,1296,0,1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
{0,1296,0,1025}, /* ; 01 (320x350,640x350) */
@@ -2389,7 +2402,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] =
};
/* The Display setting for DE Mode Panel */
-struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] = /* [ycchen] 02/18/03 Set DE as default */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] = /* [ycchen] 02/18/03 Set DE as default */
{
{1368,976,752,711 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{1368,976,729,688 }, /* ; 01 (320x350,640x350) */
@@ -2401,7 +2414,7 @@ struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] = /* [ycchen] 02/18/0
{0,1296,0,1025 } /* ; 07 (1280x1024x75Hz) */
};
-struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = /* Scaling LCD 75Hz */
+static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = /* Scaling LCD 75Hz */
{
{ 0,648,448,405,96,2 }, /* ; 00 (320x200,320x400,640x200,640x400) */
{ 0,648,448,355,96,2 }, /* ; 01 (320x350,640x350) */
@@ -2416,7 +2429,8 @@ struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = /* Scaling LCD
{ 0,1328,0,771,112,6 } /* ; 0A (1280x768x75Hz) */
};
-struct XGI330_LVDSDataStruct XGI330_LVDS640x480Data_1[] =
+#if 0
+static struct XGI330_LVDSDataStruct XGI330_LVDS640x480Data_1[] =
{
{800, 449, 800, 449},
{800, 449, 800, 449},
@@ -2428,8 +2442,9 @@ struct XGI330_LVDSDataStruct XGI330_LVDS640x480Data_1[] =
{1056, 628,1056, 628},
{1056, 628,1056, 628}
};
+#endif
-struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] =
+static struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] =
{
{840, 600, 840, 600},
{840, 600, 840, 600},
@@ -2439,7 +2454,7 @@ struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] =
{1064, 750,1064, 750}
};
-struct XGI330_CHTVDataStruct XGI_CHTVONTSCData[] =
+static struct XGI330_CHTVDataStruct XGI_CHTVONTSCData[] =
{
{840, 525, 840, 525},
{840, 525, 840, 525},
@@ -2449,7 +2464,7 @@ struct XGI330_CHTVDataStruct XGI_CHTVONTSCData[] =
{1040, 700,1040, 700}
};
-struct XGI330_CHTVDataStruct XGI_CHTVUPALData[] =
+static struct XGI330_CHTVDataStruct XGI_CHTVUPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -2459,7 +2474,7 @@ struct XGI330_CHTVDataStruct XGI_CHTVUPALData[] =
{936, 836, 936, 836}
};
-struct XGI330_CHTVDataStruct XGI_CHTVOPALData[] =
+static struct XGI330_CHTVDataStruct XGI_CHTVOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -2469,7 +2484,7 @@ struct XGI330_CHTVDataStruct XGI_CHTVOPALData[] =
{960, 750, 960, 750}
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] =
{
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }}, /* 00 (320x) */
@@ -2482,7 +2497,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] =
{{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] =
{
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 00 (320x) */
@@ -2496,7 +2511,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] =
{{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] =
{
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 00 (320x) */
@@ -2509,7 +2524,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] =
{{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] =
{
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 00 (320x) */
@@ -2523,7 +2538,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] =
{{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] =
{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x47,0x27,0x8B,0x2C,0x1A,0x00,0x05,0x00 }}, /* 00 (320x) */
{{ 0x47,0x27,0x8B,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
@@ -2537,7 +2552,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] =
{{ 0xCE,0xAE,0x92,0xB3,0x01,0x00,0x03,0x00 }} /* 09 (1400x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] =
{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 00 (320x) */
{{ 0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 01 (360x) */
@@ -2551,7 +2566,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] =
{{ 0xCE,0xAE,0x92,0xBC,0x0A,0x00,0x03,0x00 }} /* 09 (1400x) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] =
/* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
{ /* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 00 (320x) */
@@ -2567,7 +2582,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] =
{{ 0xFB,0xC7,0x9F,0xC9,0x81,0x00,0x07,0x00 }} /* 0A (1600x) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
{{ 0x97,0x1F,0x60,0x87,0x5D,0x83,0x10 }}, /* 00 (x350) */
{{ 0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30 }}, /* 01 (x400) */
@@ -2576,7 +2591,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] =
{{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* 04 (x768) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x24,0xBB,0x31,0x87,0x5D,0x25,0x30 }}, /* 00 (x350) */
{{ 0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30 }}, /* 01 (x400) */
@@ -2585,7 +2600,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] =
{{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* 04 (x768) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x86,0x1F,0x5E,0x82,0x5D,0x87,0x00 }}, /* 00 (x350) */
{{ 0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30 }}, /* 01 (x400) */
@@ -2595,7 +2610,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] =
{{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* 05 (x1024) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1 }}, /* 00 (x350) */
{{ 0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81 }}, /* 01 (x400) */
@@ -2605,7 +2620,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] =
{{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* 05 (x1024) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x6C,0x1F,0x60,0x84,0x5D,0x6D,0x10 }}, /* 00 (x350) */
{{ 0x9E,0x1F,0x93,0x86,0x8F,0x9F,0x30 }}, /* 01 (x400) */
@@ -2616,7 +2631,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] =
{{ 0x28,0x10,0x1A,0x80,0x19,0x29,0x0F }} /* 06 (x1050) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x28,0x92,0xB6,0x83,0xB5,0xCF,0x81 }}, /* 00 (x350) */
{{ 0x28,0x92,0xD5,0x82,0xD4,0xEE,0x81 }}, /* 01 (x400) */
@@ -2627,7 +2642,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] =
{{ 0x28,0x10,0x1A,0x87,0x19,0x29,0x8F }} /* 06 (x1050) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] =
{
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
{{ 0xd4,0x1F,0x81,0x84,0x5D,0xd5,0x10 }}, /* 00 (x350) */
@@ -2640,7 +2655,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] =
{{ 0x26,0x11,0xd3,0x86,0xaF,0x27,0x3f }} /* 07 (x1200) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] =
{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }},/* ; 00 (320x) */
{{ 0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }},/* ; 01 (360x) */
@@ -2652,7 +2667,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] =
{{ 0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00 }} /* ; 07 (1024x) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
{{ 0x97,0x1F,0x60,0x87,0x5D,0x83,0x10 }},/* ; 00 (x350) */
{{ 0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30 }},/* ; 01 (x400) */
@@ -2661,7 +2676,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] =
{{ 0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90 }} /* ; 04 (x768) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] =
{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 00 (320x) */
{{ 0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 01 (360x) */
@@ -2673,7 +2688,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] =
{{ 0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* ; 07 (1024x) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x24,0xBB,0x31,0x87,0x5D,0x25,0x30 }},/* ; 00 (x350) */
{{ 0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30 }},/* ; 01 (x400) */
@@ -2682,7 +2697,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] =
{{ 0x24,0xF5,0x02,0x88,0xFF,0x25,0x90 }} /* ; 04 (x768) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] =
{ /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 00 (320x) */
{{ 0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 01 (360x) */
@@ -2695,7 +2710,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] =
{{ 0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00 }} /* ; 08 (1280x) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] =
{ /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x86,0xD1,0xBC,0x80,0xBB,0xE5,0x00 }},/* ; 00 (x350) */
{{ 0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30 }},/* ; 01 (x400) */
@@ -2705,7 +2720,7 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] =
{{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
};
-struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] =
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] =
{
/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
{{ 0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 00 (320x) */
@@ -2719,7 +2734,7 @@ struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] =
{{ 0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* ; 08 (1280x) */
};
-struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] =
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] =
{
/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
{{ 0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1 }},/* ; 00 (x350) */
@@ -2730,7 +2745,8 @@ struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] =
{{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
};
-struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[] =
+#if 0
+static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[] =
{
{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
@@ -2746,7 +2762,7 @@ struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[] =
0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
};
-struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[] =
+static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[] =
{
{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
@@ -2762,7 +2778,7 @@ struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[] =
0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
};
-struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[] =
+static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
@@ -2778,7 +2794,7 @@ struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[] =
0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
};
-struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[] =
+static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
@@ -2793,9 +2809,10 @@ struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[] =
{{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
0x90,0x8c,0x57,0xed,0x20,0x00,0x05,0x01 }}
};
+#endif
/*add for new UNIVGABIOS*/
-struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] =
+static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] =
{
{Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCD1024x768Data */
{Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCD1024x768Data */
@@ -2819,7 +2836,7 @@ struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] =
{0xFF,0x0000,0x0000,0} /* End of table */
};
-struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] =
+static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] =
{
{Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCDDes1024x768Data */
{Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCDDes1024x768Data */
@@ -2844,7 +2861,7 @@ struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] =
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] =
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] =
{
{Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_H */
{Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_H */
@@ -2860,7 +2877,7 @@ struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] =
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] =
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] =
{
{Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_V */
{Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_V */
@@ -2876,7 +2893,7 @@ struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] =
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] =
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] =
{
{Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Data_1 */
{Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDS1024x768Data_2 */
@@ -2894,7 +2911,7 @@ struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] =
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] =
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] =
{
{Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Des_1 */
{Panel1024x768,0x0618,0x0410,1}, /* XGI_LVDS1024x768Des_3 */
@@ -2914,14 +2931,14 @@ struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] =
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] =
+static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] =
{
{Panel1024x768,0x0000,0x0000,0}, /* XGI_CH7017LV1024x768 */
{Panel1400x1050,0x0000,0x0000,1}, /* XGI_CH7017LV1400x1050 */
{0xFF,0x0000,0x0000,0}
};
-struct XGI330_TVDataTablStruct XGI_TVDataTable[] =
+static struct XGI330_TVDataTablStruct XGI_TVDataTable[] =
{
{0x09E1,0x0001,0}, /* XGI_ExtPALData */
{0x09E1,0x0000,1}, /* XGI_ExtNTSCData */
@@ -2939,7 +2956,8 @@ struct XGI330_TVDataTablStruct XGI_TVDataTable[] =
{0xffff,0x0000,12} /* END */
};
-unsigned short TVLenList[] =
+#if 0
+static unsigned short TVLenList[] =
{
LVDSCRT1Len_H,
LVDSCRT1Len_V,
@@ -2950,9 +2968,10 @@ unsigned short TVLenList[] =
0,
CHTVRegLen
} ;
+#endif
/* Chrontel 7017 TV CRT1 Timing List */
-struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] =
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] =
{
{0x0011,0x0000,0}, /* XGI_CHTVCRT1UNTSC */
{0x0011,0x0010,1}, /* XGI_CHTVCRT1ONTSC */
@@ -2962,7 +2981,7 @@ struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] =
};
/* ;;Chrontel 7017 TV Timing List */
-struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] =
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] =
{
{0x0011,0x0000,0}, /* XGI_CHTVUNTSCData */
{0x0011,0x0010,1}, /* XGI_CHTVONTSCData */
@@ -2972,7 +2991,7 @@ struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] =
};
/* ;;Chrontel 7017 TV Reg. List */
-struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] =
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] =
{
{0x0011,0x0000,0}, /* XGI_CHTVRegUNTSC */
{0x0011,0x0010,1}, /* XGI_CHTVRegONTSC */
@@ -2981,7 +3000,7 @@ struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] =
{0xFFFF,0x0000,4}
};
-unsigned short LCDLenList[] =
+static unsigned short LCDLenList[] =
{
LVDSCRT1Len_H,
LVDSCRT1Len_V,
@@ -2995,7 +3014,8 @@ unsigned short LCDLenList[] =
0
} ;
-struct XGI330_LCDCapStruct XGI660_LCDDLCapList[] = /* 660, Dual link */
+#if 0
+static struct XGI330_LCDCapStruct XGI660_LCDDLCapList[] = /* 660, Dual link */
{
/* LCDCap1024x768 */
{Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
@@ -3026,8 +3046,9 @@ struct XGI330_LCDCapStruct XGI660_LCDDLCapList[] = /* 660, Dual link */
0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
+#endif
-struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = /* Dual link only */
+static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = /* Dual link only */
{
/* LCDCap1024x768 */
{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
@@ -3059,7 +3080,8 @@ struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = /* Dual link only */
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
-struct XGI330_LCDCapStruct XGI660_LCDCapList[] =
+#if 0
+static struct XGI330_LCDCapStruct XGI660_LCDCapList[] =
{
/* LCDCap1024x768 */
{Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
@@ -3090,8 +3112,9 @@ struct XGI330_LCDCapStruct XGI660_LCDCapList[] =
0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
+#endif
-struct XGI330_LCDCapStruct XGI_LCDCapList[] =
+static struct XGI330_LCDCapStruct XGI_LCDCapList[] =
{
/* LCDCap1024x768 */
{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
@@ -3152,7 +3175,7 @@ struct XGI21_LVDSCapStruct XGI21_LCDCapList[] =
};
-struct XGI_Ext2Struct XGI330_RefIndex[] =
+static struct XGI_Ext2Struct XGI330_RefIndex[] =
{
{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
@@ -3230,8 +3253,8 @@ struct XGI_Ext2Struct XGI330_RefIndex[] =
};
-
-struct XGI330_VCLKDataStruct XGI330_VCLKData[] =
+#if 0
+static struct XGI330_VCLKDataStruct XGI330_VCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x0 */
{ 0x4e,0xe4, 28}, /* 0x1 */
@@ -3315,7 +3338,7 @@ struct XGI330_VCLKDataStruct XGI330_VCLKData[] =
{ 0x3b,0x61,108} /* 0x4f */
};
-struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] =
+static struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x0 */
{ 0x4e,0xe4, 28}, /* 0x1 */
@@ -3392,12 +3415,14 @@ struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] =
{ 0x5e,0x64,68}, /* 0x48 chiawen for fuj1280x768*/
{ 0x70,0x44,108}, /* 0x49 chiawen for 1400x1050*/
};
+#endif
-unsigned char XGI330_ScreenOffset[] = { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
+static unsigned char XGI330_ScreenOffset[] = {
+ 0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
0x57, 0x48};
-struct XGI_StResInfoStruct XGI330_StResInfo[] =
+static struct XGI_StResInfoStruct XGI330_StResInfo[] =
{
{ 640,400},
{ 640,350},
@@ -3406,7 +3431,7 @@ struct XGI_StResInfoStruct XGI330_StResInfo[] =
{ 640,480}
};
-struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] =
+static struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] =
{
{ 320, 200, 8, 8},
{ 320, 240, 8, 8},
@@ -3433,10 +3458,12 @@ struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] =
{ 1152, 864, 8,16}
};
-unsigned char XGI330_OutputSelect = 0x40;
-unsigned char XGI330_SoftSetting = 0x30;
-unsigned char XGI330_SR07 = 0x18;
-unsigned char XGI330New_SR15[8][8] = {
+static unsigned char XGI330_OutputSelect = 0x40;
+static unsigned char XGI330_SoftSetting = 0x30;
+static unsigned char XGI330_SR07 = 0x18;
+
+#if 0
+static unsigned char XGI330New_SR15[8][8] = {
{0x0,0x4,0x60,0x60},
{0xf,0xf,0xf,0xf},
{0xba,0xba,0xba,0xba},
@@ -3447,71 +3474,78 @@ unsigned char XGI330New_SR15[8][8] = {
{0x0,0xa5,0xfb,0xf6}
};
-unsigned char XGI330New_CR40[5][8] = {
+static unsigned char XGI330New_CR40[5][8] = {
{0x77,0x77,0x44,0x44},
{0x77,0x77,0x44,0x44},
{0x0,0x0,0x0,0x0},
{0x5b,0x5b,0xab,0xab},
{0x0,0x0,0xf0,0xf8}
};
-
-unsigned char XGI330_CR49[] = {0xaa, 0x88};
-unsigned char XGI330_SR1F = 0x0;
-unsigned char XGI330_SR21 = 0xa3;
-unsigned char XGI330_650_SR21 = 0xa7;
-unsigned char XGI330_SR22 = 0xfb;
-unsigned char XGI330_SR23 = 0xf6;
-unsigned char XGI330_SR24 = 0xd;
-
-unsigned char XGI660_SR21 = 0xa3;/* 2003.0312 */
-unsigned char XGI660_SR22 = 0xf3;/* 2003.0312 */
-
-unsigned char XGI330_LVDS_SR32 = 0x00; /* ynlai for 650 LVDS */
-unsigned char XGI330_LVDS_SR33 = 0x00; /* chiawen for 650 LVDS */
-unsigned char XGI330_650_SR31 = 0x40;
-unsigned char XGI330_650_SR33 = 0x04;
-unsigned char XGI330_CRT2Data_1_2 = 0x0;
-unsigned char XGI330_CRT2Data_4_D = 0x0;
-unsigned char XGI330_CRT2Data_4_E = 0x0;
-unsigned char XGI330_CRT2Data_4_10 = 0x80;
-unsigned short XGI330_RGBSenseData = 0xd1;
-unsigned short XGI330_VideoSenseData = 0xb9;
-unsigned short XGI330_YCSenseData = 0xb3;
-unsigned short XGI330_RGBSenseData2 = 0x0190; /*301b*/
-unsigned short XGI330_VideoSenseData2 = 0x0110;
-unsigned short XGI330_YCSenseData2 = 0x016B;
-unsigned char XGI330_NTSCPhase[] = {0x21, 0xed, 0x8a, 0x8};
-unsigned char XGI330_PALPhase[] = {0x2a, 0x5, 0xd3, 0x0};
-unsigned char XGI330_NTSCPhase2[] = {0x21, 0xF0, 0x7B, 0xD6};/*301b*/
-unsigned char XGI330_PALPhase2[] = {0x2a, 0x09, 0x86, 0xe9};
-unsigned char XGI330_PALMPhase[] = {0x21, 0xE4, 0x2E, 0x9B}; /*palmn*/
-unsigned char XGI330_PALNPhase[] = {0x21, 0xF4, 0x3E, 0xBA};
-unsigned char XG40_I2CDefinition = 0x00 ;
-unsigned char XG20_CR97 = 0x10 ;
-
-unsigned char XG21_DVOSetting = 0x00 ;
-unsigned char XG21_CR2E = 0x00 ;
-unsigned char XG21_CR2F = 0x00 ;
-unsigned char XG21_CR46 = 0x00 ;
-unsigned char XG21_CR47 = 0x00 ;
-
-unsigned char XG27_CR97 = 0xC1 ;
-unsigned char XG27_SR36 = 0x30 ;
-unsigned char XG27_CR8F = 0x0C ;
-unsigned char XG27_CRD0[] = {0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00};
-unsigned char XG27_CRDE[] = {0, 0};
-unsigned char XG27_SR40 = 0x04 ;
-unsigned char XG27_SR41 = 0x00 ;
-
-unsigned char XGI330_CHTVVCLKUNTSC[] = {0x00};
-
-unsigned char XGI330_CHTVVCLKONTSC[] = {0x00};
-
-unsigned char XGI330_CHTVVCLKUPAL[] = {0x00};
-
-unsigned char XGI330_CHTVVCLKOPAL[] = {0x00};
-
-unsigned char XGI7007_CHTVVCLKUNTSC[] = {CH7007TVVCLK30_2,
+#endif
+
+static unsigned char XGI330_CR49[] = {0xaa, 0x88};
+static unsigned char XGI330_SR1F = 0x0;
+static unsigned char XGI330_SR21 = 0xa3;
+#if 0
+static unsigned char XGI330_650_SR21 = 0xa7;
+#endif
+static unsigned char XGI330_SR22 = 0xfb;
+static unsigned char XGI330_SR23 = 0xf6;
+static unsigned char XGI330_SR24 = 0xd;
+
+#if 0
+static unsigned char XGI660_SR21 = 0xa3;/* 2003.0312 */
+static unsigned char XGI660_SR22 = 0xf3;/* 2003.0312 */
+
+static unsigned char XGI330_LVDS_SR32 = 0x00; /* ynlai for 650 LVDS */
+static unsigned char XGI330_LVDS_SR33 = 0x00; /* chiawen for 650 LVDS */
+static unsigned char XGI330_650_SR31 = 0x40;
+static unsigned char XGI330_650_SR33 = 0x04;
+#endif
+static unsigned char XGI330_CRT2Data_1_2 = 0x0;
+static unsigned char XGI330_CRT2Data_4_D = 0x0;
+static unsigned char XGI330_CRT2Data_4_E = 0x0;
+static unsigned char XGI330_CRT2Data_4_10 = 0x80;
+static unsigned short XGI330_RGBSenseData = 0xd1;
+static unsigned short XGI330_VideoSenseData = 0xb9;
+static unsigned short XGI330_YCSenseData = 0xb3;
+static unsigned short XGI330_RGBSenseData2 = 0x0190; /*301b*/
+static unsigned short XGI330_VideoSenseData2 = 0x0110;
+static unsigned short XGI330_YCSenseData2 = 0x016B;
+#if 0
+static unsigned char XGI330_NTSCPhase[] = {0x21, 0xed, 0x8a, 0x8};
+static unsigned char XGI330_PALPhase[] = {0x2a, 0x5, 0xd3, 0x0};
+static unsigned char XGI330_NTSCPhase2[] = {0x21, 0xF0, 0x7B, 0xD6};/*301b*/
+static unsigned char XGI330_PALPhase2[] = {0x2a, 0x09, 0x86, 0xe9};
+static unsigned char XGI330_PALMPhase[] = {0x21, 0xE4, 0x2E, 0x9B}; /*palmn*/
+static unsigned char XGI330_PALNPhase[] = {0x21, 0xF4, 0x3E, 0xBA};
+#endif
+static unsigned char XG40_I2CDefinition = 0x00 ;
+static unsigned char XG20_CR97 = 0x10 ;
+
+static unsigned char XG21_DVOSetting = 0x00 ;
+static unsigned char XG21_CR2E = 0x00 ;
+static unsigned char XG21_CR2F = 0x00 ;
+static unsigned char XG21_CR46 = 0x00 ;
+static unsigned char XG21_CR47 = 0x00 ;
+
+static unsigned char XG27_CR97 = 0xC1 ;
+static unsigned char XG27_SR36 = 0x30 ;
+static unsigned char XG27_CR8F = 0x0C ;
+static unsigned char XG27_CRD0[] = {0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00};
+static unsigned char XG27_CRDE[] = {0, 0};
+static unsigned char XG27_SR40 = 0x04 ;
+static unsigned char XG27_SR41 = 0x00 ;
+
+static unsigned char XGI330_CHTVVCLKUNTSC[] = {0x00};
+
+static unsigned char XGI330_CHTVVCLKONTSC[] = {0x00};
+
+static unsigned char XGI330_CHTVVCLKUPAL[] = {0x00};
+
+static unsigned char XGI330_CHTVVCLKOPAL[] = {0x00};
+
+static unsigned char XGI7007_CHTVVCLKUNTSC[] = {CH7007TVVCLK30_2,
CH7007TVVCLK30_2,
CH7007TVVCLK30_2,
CH7007TVVCLK30_2,
@@ -3519,7 +3553,7 @@ unsigned char XGI7007_CHTVVCLKUNTSC[] = {CH7007TVVCLK30_2,
CH7007TVVCLK47_8
};
-unsigned char XGI7007_CHTVVCLKONTSC[] = {CH7007TVVCLK26_4,
+static unsigned char XGI7007_CHTVVCLKONTSC[] = {CH7007TVVCLK26_4,
CH7007TVVCLK26_4,
CH7007TVVCLK26_4,
CH7007TVVCLK26_4,
@@ -3527,7 +3561,7 @@ unsigned char XGI7007_CHTVVCLKONTSC[] = {CH7007TVVCLK26_4,
CH7007TVVCLK43_6
};
-unsigned char XGI7007_CHTVVCLKUPAL[] = {CH7007TVVCLK31_5,
+static unsigned char XGI7007_CHTVVCLKUPAL[] = {CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
@@ -3535,7 +3569,7 @@ unsigned char XGI7007_CHTVVCLKUPAL[] = {CH7007TVVCLK31_5,
CH7007TVVCLK39
};
-unsigned char XGI7007_CHTVVCLKOPAL[] = {CH7007TVVCLK31_5,
+static unsigned char XGI7007_CHTVVCLKOPAL[] = {CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
CH7007TVVCLK31_5,
@@ -3543,7 +3577,7 @@ unsigned char XGI7007_CHTVVCLKOPAL[] = {CH7007TVVCLK31_5,
CH7007TVVCLK36
};
-struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] =
+static struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] =
{
{ 0x60,0x36,30}, /* 0 30.2 MHZ */
{ 0x40,0x4A,28}, /* 1 28.19 MHZ */
@@ -3558,7 +3592,7 @@ struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] =
{ 0xFF,0x00,0 } /* End mark */
};
-struct XGI330_VCLKDataStruct XGI_VCLKData[] =
+static struct XGI330_VCLKDataStruct XGI_VCLKData[] =
{
/* SR2B,SR2C,SR2D */
{ 0x1B,0xE1,25 },/* 00 (25.175MHz) */
@@ -3759,7 +3793,7 @@ struct XGI330_VCLKDataStruct XGI_VCLKData[] =
{ 0xFF,0x00,0 }/* End mark */
} ;
-struct XGI330_VCLKDataStruct XGI_VBVCLKData[] =
+static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] =
{
{ 0x1B,0xE1,25 },/* 00 (25.175MHz) */
@@ -3960,7 +3994,8 @@ struct XGI330_VCLKDataStruct XGI_VBVCLKData[] =
{ 0xFF,0x00,0 } /* End mark */
};
-unsigned char XGI660_TVDelayList[] =
+#if 0
+static unsigned char XGI660_TVDelayList[] =
{
0x44, /* ; 0 ExtNTSCDelay */
0x44, /* ; 1 StNTSCDelay */
@@ -3976,7 +4011,7 @@ unsigned char XGI660_TVDelayList[] =
0x44 /* ; B StYPbPrDealy(750p) */
};
-unsigned char XGI660_TVDelayList2[] =
+static unsigned char XGI660_TVDelayList2[] =
{
0x44, /* ; 0 ExtNTSCDelay */
0x44, /* ; 1 StNTSCDelay */
@@ -3991,8 +4026,9 @@ unsigned char XGI660_TVDelayList2[] =
0x44, /* ; A ExtYPbPrDelay(750p) */
0x44 /* ; B StYPbPrDealy(750p) */
};
+#endif
-unsigned char XGI301TVDelayList[] =
+static unsigned char XGI301TVDelayList[] =
{
0x22, /* ; 0 ExtNTSCDelay */
0x22, /* ; 1 StNTSCDelay */
@@ -4008,7 +4044,7 @@ unsigned char XGI301TVDelayList[] =
0x22 /* B StYPbPrDealy(750p) */
};
-unsigned char XGI301TVDelayList2[] =
+static unsigned char XGI301TVDelayList2[] =
{
0x22, /* ; 0 ExtNTSCDelay */
0x22, /* ; 1 StNTSCDelay */
@@ -4025,7 +4061,7 @@ unsigned char XGI301TVDelayList2[] =
};
-unsigned char TVAntiFlickList[] =
+static unsigned char TVAntiFlickList[] =
{/* NTSCAntiFlicker */
0x04, /* ; 0 Adaptive */
0x00, /* ; 1 new anti-flicker ? */
@@ -4038,7 +4074,7 @@ unsigned char TVAntiFlickList[] =
};
-unsigned char TVEdgeList[] =
+static unsigned char TVEdgeList[] =
{
0x00, /* ; 0 NTSC No Edge enhance */
0x04, /* ; 1 NTSC Adaptive Edge enhance */
@@ -4048,7 +4084,7 @@ unsigned char TVEdgeList[] =
0x00 /* ; 1 HiTV */
};
-unsigned long TVPhaseList[] =
+static unsigned long TVPhaseList[] =
{ 0x08BAED21, /* ; 0 NTSC phase */
0x00E3052A, /* ; 1 PAL phase */
0x9B2EE421, /* ; 2 PAL-M phase */
@@ -4065,7 +4101,7 @@ unsigned long TVPhaseList[] =
0xE00A831E /* ; D PAL-M 1024x768 */
};
-unsigned char NTSCYFilter1[] =
+static unsigned char NTSCYFilter1[] =
{
0x00,0xF4,0x10,0x38 ,/* 0 : 320x text mode */
0x00,0xF4,0x10,0x38 ,/* 1 : 360x text mode */
@@ -4076,7 +4112,7 @@ unsigned char NTSCYFilter1[] =
0xEB,0x15,0x25,0xF6 /* 6 : 800x gra. mode */
};
-unsigned char PALYFilter1[] =
+static unsigned char PALYFilter1[] =
{
0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
0x00,0xF4,0x10,0x38 ,/* 1 : 360x text mode */
@@ -4087,7 +4123,7 @@ unsigned char PALYFilter1[] =
0xFC,0xFB,0x14,0x2A /* 6 : 800x gra. mode */
};
-unsigned char PALMYFilter1[] =
+static unsigned char PALMYFilter1[] =
{
0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
@@ -4099,7 +4135,7 @@ unsigned char PALMYFilter1[] =
0xFF,0xFF,0xFF,0xFF /* End of Table */
};
-unsigned char PALNYFilter1[] =
+static unsigned char PALNYFilter1[] =
{
0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
@@ -4111,7 +4147,7 @@ unsigned char PALNYFilter1[] =
0xFF,0xFF,0xFF,0xFF /* End of Table */
};
-unsigned char NTSCYFilter2[] =
+static unsigned char NTSCYFilter2[] =
{
0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4123,7 +4159,7 @@ unsigned char NTSCYFilter2[] =
0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
};
-unsigned char PALYFilter2[] =
+static unsigned char PALYFilter2[] =
{
0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4135,7 +4171,7 @@ unsigned char PALYFilter2[] =
0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
};
-unsigned char PALMYFilter2[] =
+static unsigned char PALMYFilter2[] =
{
0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4147,7 +4183,7 @@ unsigned char PALMYFilter2[] =
0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
};
-unsigned char PALNYFilter2[] =
+static unsigned char PALNYFilter2[] =
{
0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
@@ -4159,14 +4195,14 @@ unsigned char PALNYFilter2[] =
0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28 /* 7 : 1024xgra. mode */
};
-unsigned char XGI_NTSC1024AdjTime[] =
+static unsigned char XGI_NTSC1024AdjTime[] =
{
0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
0x13,0x40,0x34,0xF4,0x63,0xBB,0xCC,0x7A,
0x58,0xe4,0x73,0xd0,0x13
};
-struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] =
{
{0,{
0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4181,7 +4217,7 @@ struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] =
{
{0,{
0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4196,7 +4232,7 @@ struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] =
{
{0,{
0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
@@ -4211,7 +4247,7 @@ struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct PALTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct PALTap4Timing[] =
{
{600, {
0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
@@ -4249,7 +4285,7 @@ struct XGI301C_Tap4TimingStruct PALTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] =
{
{480, {
0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4287,7 +4323,7 @@ struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] =
{
{480, {
0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4325,7 +4361,7 @@ struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] =
{
{480, {
0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
@@ -4363,7 +4399,7 @@ struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] =
}
};
-struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] =
+static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] =
{ {0xFFFF,
{
0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c
index 2c40368ceee2..65b3954d8ff2 100644
--- a/drivers/staging/xgifb/vb_util.c
+++ b/drivers/staging/xgifb/vb_util.c
@@ -6,21 +6,20 @@
#include <asm/io.h>
#include <linux/types.h>
-void XGINew_SetReg1(unsigned long,unsigned short,unsigned short);
-void XGINew_SetReg2(unsigned long,unsigned short,unsigned short);
-void XGINew_SetReg3(unsigned long,unsigned short);
-void XGINew_SetReg4(unsigned long,unsigned long);
+void XGINew_SetReg1(unsigned long, unsigned short, unsigned short);
+void XGINew_SetReg2(unsigned long, unsigned short, unsigned short);
+void XGINew_SetReg3(unsigned long, unsigned short);
+void XGINew_SetReg4(unsigned long, unsigned long);
unsigned char XGINew_GetReg1(unsigned long, unsigned short);
unsigned char XGINew_GetReg2(unsigned long);
unsigned long XGINew_GetReg3(unsigned long);
void XGINew_ClearDAC(unsigned char *);
-void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,
- unsigned short DataAND,unsigned short DataOR);
-void XGINew_SetRegOR(unsigned long Port,unsigned short Index,
- unsigned short DataOR);
-void XGINew_SetRegAND(unsigned long Port,unsigned short Index,
- unsigned short DataAND);
-
+void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index,
+ unsigned short DataAND, unsigned short DataOR);
+void XGINew_SetRegOR(unsigned long Port, unsigned short Index,
+ unsigned short DataOR);
+void XGINew_SetRegAND(unsigned long Port, unsigned short Index,
+ unsigned short DataAND);
/* --------------------------------------------------------------------- */
/* Function : XGINew_SetReg1 */
@@ -28,181 +27,110 @@ void XGINew_SetRegAND(unsigned long Port,unsigned short Index,
/* Output : */
/* Description : SR CRTC GR */
/* --------------------------------------------------------------------- */
-void XGINew_SetReg1( unsigned long port , unsigned short index , unsigned short data )
+void XGINew_SetReg1(unsigned long port, unsigned short index,
+ unsigned short data)
{
outb(index, port);
outb(data, port + 1);
}
-
/* --------------------------------------------------------------------- */
/* Function : XGINew_SetReg2 */
/* Input : */
/* Output : */
/* Description : AR( 3C0 ) */
/* --------------------------------------------------------------------- */
-/*void XGINew_SetReg2( unsigned long port , unsigned short index , unsigned short data )
+/*
+void XGINew_SetReg2(unsigned long port, unsigned short index, unsigned short data)
{
- InPortByte((P unsigned char )port + 0x3da - 0x3c0) ;
- OutPortByte( XGINew_P3c0 , index ) ;
- OutPortByte( XGINew_P3c0 , data ) ;
- OutPortByte( XGINew_P3c0 , 0x20 ) ;
-}*/
-
+ InPortByte((P unsigned char)port + 0x3da - 0x3c0) ;
+ OutPortByte(XGINew_P3c0, index);
+ OutPortByte(XGINew_P3c0, data);
+ OutPortByte(XGINew_P3c0, 0x20);
+}
+*/
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetReg3( unsigned long port , unsigned short data )
+void XGINew_SetReg3(unsigned long port, unsigned short data)
{
outb(data, port);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetReg4 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetReg4( unsigned long port , unsigned long data )
+void XGINew_SetReg4(unsigned long port, unsigned long data)
{
outl(data, port);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_GetReg1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_GetReg1(unsigned long port, unsigned short index)
{
- unsigned char data ;
+ unsigned char data;
- outb(index, port);
- data = inb(port + 1) ;
- return( data ) ;
+ outb(index, port);
+ data = inb(port + 1);
+ return data;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_GetReg2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
unsigned char XGINew_GetReg2(unsigned long port)
{
- unsigned char data ;
+ unsigned char data;
- data = inb(port) ;
+ data = inb(port);
- return( data ) ;
+ return data;
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_GetReg3 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned long XGINew_GetReg3( unsigned long port )
+unsigned long XGINew_GetReg3(unsigned long port)
{
- unsigned long data ;
+ unsigned long data;
- data = inl(port) ;
+ data = inl(port);
- return( data ) ;
+ return data;
}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetRegANDOR */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetRegANDOR( unsigned long Port , unsigned short Index , unsigned short DataAND , unsigned short DataOR )
+void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index,
+ unsigned short DataAND, unsigned short DataOR)
{
- unsigned short temp ;
+ unsigned short temp;
- temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
- temp = ( temp & ( DataAND ) ) | DataOR ;
- XGINew_SetReg1( Port , Index , temp ) ;
+ temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */
+ temp = (temp & (DataAND)) | DataOR;
+ XGINew_SetReg1(Port, Index, temp);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetRegAND */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND)
+void XGINew_SetRegAND(unsigned long Port, unsigned short Index,
+ unsigned short DataAND)
{
- unsigned short temp ;
+ unsigned short temp;
- temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
- temp &= DataAND ;
- XGINew_SetReg1( Port , Index , temp ) ;
+ temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */
+ temp &= DataAND;
+ XGINew_SetReg1(Port, Index, temp);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetRegOR */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetRegOR( unsigned long Port , unsigned short Index , unsigned short DataOR )
+void XGINew_SetRegOR(unsigned long Port, unsigned short Index,
+ unsigned short DataOR)
{
- unsigned short temp ;
+ unsigned short temp;
- temp = XGINew_GetReg1( Port , Index ) ; /* XGINew_Part1Port index 02 */
- temp |= DataOR ;
- XGINew_SetReg1( Port , Index , temp ) ;
+ temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */
+ temp |= DataOR;
+ XGINew_SetReg1(Port, Index, temp);
}
-
-/* --------------------------------------------------------------------- */
-/* Function : NewDelaySecond */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void NewDelaySeconds( int seconds )
+#if 0
+void NewDelaySeconds(int seconds)
{
- int i ;
+ int i;
+ for (i = 0; i < seconds; i++) {
- for( i = 0 ; i < seconds ; i++ )
- {
-
-
-
- }
+ }
}
-
-/* --------------------------------------------------------------------- */
-/* Function : Newdebugcode */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
void Newdebugcode(unsigned char code)
{
-// OutPortByte ( 0x80 , code ) ;
- /* OutPortByte ( 0x300 , code ) ; */
- /* NewDelaySeconds( 0x3 ) ; */
+ /* OutPortByte(0x80, code); */
+ /* OutPortByte(0x300, code); */
+ /* NewDelaySeconds(0x3); */
}
-
-
-
+#endif
diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig
index 4654ae2eb42e..da079f8d6e3d 100644
--- a/drivers/staging/zram/Kconfig
+++ b/drivers/staging/zram/Kconfig
@@ -15,15 +15,3 @@ config ZRAM
See zram.txt for more information.
Project home: http://compcache.googlecode.com/
-
-config ZRAM_STATS
- bool "Enable statistics for compressed RAM disks"
- depends on ZRAM
- default y
- help
- Enable statistics collection for compressed RAM devices. Statistics
- are exported through ioctl interface, so you have to use zramconfig
- program to get them. This adds only a minimal overhead.
-
- If unsure, say Y.
-
diff --git a/drivers/staging/zram/Makefile b/drivers/staging/zram/Makefile
index b2c087aa105e..c01160a98d10 100644
--- a/drivers/staging/zram/Makefile
+++ b/drivers/staging/zram/Makefile
@@ -1,3 +1,3 @@
-zram-objs := zram_drv.o xvmalloc.o
+zram-objs := zram_drv.o zram_sysfs.o xvmalloc.o
obj-$(CONFIG_ZRAM) += zram.o
diff --git a/drivers/staging/zram/zram.txt b/drivers/staging/zram/zram.txt
index 520edc1bea73..5f75d2987564 100644
--- a/drivers/staging/zram/zram.txt
+++ b/drivers/staging/zram/zram.txt
@@ -5,33 +5,35 @@ Project home: http://compcache.googlecode.com/
* Introduction
-The zram module creates RAM based block devices: /dev/ramX (X = 0, 1, ...).
-Pages written to these disks are compressed and stored in memory itself.
-These disks allow very fast I/O and compression provides good amounts of
-memory savings.
+The zram module creates RAM based block devices named /dev/zram<id>
+(<id> = 0, 1, ...). Pages written to these disks are compressed and stored
+in memory itself. These disks allow very fast I/O and compression provides
+good amounts of memory savings. Some of the usecases include /tmp storage,
+use as swap disks, various caches under /var and maybe many more :)
-See project home for use cases, performance numbers and a lot more.
-
-Individual zram devices are configured and initialized using zramconfig
-userspace utility as shown in examples below. See zramconfig man page for
-more details.
+Statistics for individual zram devices are exported through sysfs nodes at
+/sys/block/zram<id>/
* Usage
Following shows a typical sequence of steps for using zram.
-1) Load Modules:
+1) Load Module:
modprobe zram num_devices=4
- This creates 4 (uninitialized) devices: /dev/zram{0,1,2,3}
+ This creates 4 devices: /dev/zram{0,1,2,3}
(num_devices parameter is optional. Default: 1)
-2) Initialize:
- Use zramconfig utility to configure and initialize individual
- zram devices. For example:
- zramconfig /dev/zram0 --init # uses default value of disksize_kb
- zramconfig /dev/zram1 --disksize_kb=102400 # 100MB /dev/zram1
+2) Set Disksize (Optional):
+ Set disk size by writing the value to sysfs node 'disksize'
+ (in bytes). If disksize is not given, default value of 25%
+ of RAM is used.
+
+ # Initialize /dev/zram0 with 50MB disksize
+ echo $((50*1024*1024)) > /sys/block/zram0/disksize
- *See zramconfig man page for more details and examples*
+ NOTE: disksize cannot be changed if the disk contains any
+ data. So, for such a disk, you need to issue 'reset' (see below)
+ before you can change its disksize.
3) Activate:
mkswap /dev/zram0
@@ -41,17 +43,29 @@ Following shows a typical sequence of steps for using zram.
mount /dev/zram1 /tmp
4) Stats:
- zramconfig /dev/zram0 --stats
- zramconfig /dev/zram1 --stats
+ Per-device statistics are exported as various nodes under
+ /sys/block/zram<id>/
+ disksize
+ num_reads
+ num_writes
+ invalid_io
+ notify_free
+ discard
+ zero_pages
+ orig_data_size
+ compr_data_size
+ mem_used_total
5) Deactivate:
swapoff /dev/zram0
umount /dev/zram1
6) Reset:
- zramconfig /dev/zram0 --reset
- zramconfig /dev/zram1 --reset
- (This frees memory allocated for the given device).
+ Write any positive value to 'reset' sysfs node
+ echo 1 > /sys/block/zram0/reset
+ echo 1 > /sys/block/zram1/reset
+
+ (This frees all the memory allocated for the given device).
Please report any problems at:
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 77d4d715a789..d0e9e0207539 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -33,10 +33,39 @@
/* Globals */
static int zram_major;
-static struct zram *devices;
+struct zram *devices;
/* Module params (documentation at end) */
-static unsigned int num_devices;
+unsigned int num_devices;
+
+static void zram_stat_inc(u32 *v)
+{
+ *v = *v + 1;
+}
+
+static void zram_stat_dec(u32 *v)
+{
+ *v = *v - 1;
+}
+
+static void zram_stat64_add(struct zram *zram, u64 *v, u64 inc)
+{
+ spin_lock(&zram->stat64_lock);
+ *v = *v + inc;
+ spin_unlock(&zram->stat64_lock);
+}
+
+static void zram_stat64_sub(struct zram *zram, u64 *v, u64 dec)
+{
+ spin_lock(&zram->stat64_lock);
+ *v = *v - dec;
+ spin_unlock(&zram->stat64_lock);
+}
+
+static void zram_stat64_inc(struct zram *zram, u64 *v)
+{
+ zram_stat64_add(zram, v, 1);
+}
static int zram_test_flag(struct zram *zram, u32 index,
enum zram_pageflags flag)
@@ -91,7 +120,7 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes)
"the disk when not in use so a huge zram is "
"wasteful.\n"
"\tMemory Size: %zu kB\n"
- "\tSize you selected: %zu kB\n"
+ "\tSize you selected: %llu kB\n"
"Continuing anyway ...\n",
totalram_bytes >> 10, zram->disksize
);
@@ -100,49 +129,6 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes)
zram->disksize &= PAGE_MASK;
}
-static void zram_ioctl_get_stats(struct zram *zram,
- struct zram_ioctl_stats *s)
-{
- s->disksize = zram->disksize;
-
-#if defined(CONFIG_ZRAM_STATS)
- {
- struct zram_stats *rs = &zram->stats;
- size_t succ_writes, mem_used;
- unsigned int good_compress_perc = 0, no_compress_perc = 0;
-
- mem_used = xv_get_total_size_bytes(zram->mem_pool)
- + (rs->pages_expand << PAGE_SHIFT);
- succ_writes = zram_stat64_read(zram, &rs->num_writes) -
- zram_stat64_read(zram, &rs->failed_writes);
-
- if (succ_writes && rs->pages_stored) {
- good_compress_perc = rs->good_compress * 100
- / rs->pages_stored;
- no_compress_perc = rs->pages_expand * 100
- / rs->pages_stored;
- }
-
- s->num_reads = zram_stat64_read(zram, &rs->num_reads);
- s->num_writes = zram_stat64_read(zram, &rs->num_writes);
- s->failed_reads = zram_stat64_read(zram, &rs->failed_reads);
- s->failed_writes = zram_stat64_read(zram, &rs->failed_writes);
- s->invalid_io = zram_stat64_read(zram, &rs->invalid_io);
- s->notify_free = zram_stat64_read(zram, &rs->notify_free);
- s->pages_zero = rs->pages_zero;
-
- s->good_compress_pct = good_compress_perc;
- s->pages_expand_pct = no_compress_perc;
-
- s->pages_stored = rs->pages_stored;
- s->pages_used = mem_used >> PAGE_SHIFT;
- s->orig_data_size = rs->pages_stored << PAGE_SHIFT;
- s->compr_data_size = rs->compr_size;
- s->mem_used_total = mem_used;
- }
-#endif /* CONFIG_ZRAM_STATS */
-}
-
static void zram_free_page(struct zram *zram, size_t index)
{
u32 clen;
@@ -180,7 +166,7 @@ static void zram_free_page(struct zram *zram, size_t index)
zram_stat_dec(&zram->stats.good_compress);
out:
- zram->stats.compr_size -= clen;
+ zram_stat64_sub(zram, &zram->stats.compr_size, clen);
zram_stat_dec(&zram->stats.pages_stored);
zram->table[index].page = NULL;
@@ -221,9 +207,15 @@ static int zram_read(struct zram *zram, struct bio *bio)
u32 index;
struct bio_vec *bvec;
- zram_stat64_inc(zram, &zram->stats.num_reads);
+ if (unlikely(!zram->init_done)) {
+ set_bit(BIO_UPTODATE, &bio->bi_flags);
+ bio_endio(bio, 0);
+ return 0;
+ }
+ zram_stat64_inc(zram, &zram->stats.num_reads);
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
+
bio_for_each_segment(bvec, bio, i) {
int ret;
size_t clen;
@@ -289,16 +281,20 @@ out:
static int zram_write(struct zram *zram, struct bio *bio)
{
- int i;
+ int i, ret;
u32 index;
struct bio_vec *bvec;
- zram_stat64_inc(zram, &zram->stats.num_writes);
+ if (unlikely(!zram->init_done)) {
+ ret = zram_init_device(zram);
+ if (ret)
+ goto out;
+ }
+ zram_stat64_inc(zram, &zram->stats.num_writes);
index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
bio_for_each_segment(bvec, bio, i) {
- int ret;
u32 offset;
size_t clen;
struct zobj_header *zheader;
@@ -396,7 +392,7 @@ memstore:
kunmap_atomic(src, KM_USER0);
/* Update stats */
- zram->stats.compr_size += clen;
+ zram_stat64_add(zram, &zram->stats.compr_size, clen);
zram_stat_inc(&zram->stats.pages_stored);
if (clen <= PAGE_SIZE / 2)
zram_stat_inc(&zram->stats.good_compress);
@@ -439,11 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
int ret = 0;
struct zram *zram = queue->queuedata;
- if (unlikely(!zram->init_done)) {
- bio_io_error(bio);
- return 0;
- }
-
if (!valid_io_request(zram, bio)) {
zram_stat64_inc(zram, &zram->stats.invalid_io);
bio_io_error(bio);
@@ -463,11 +454,11 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
return ret;
}
-static void reset_device(struct zram *zram)
+void zram_reset_device(struct zram *zram)
{
size_t index;
- /* Do not accept any new I/O request */
+ mutex_lock(&zram->init_lock);
zram->init_done = 0;
/* Free various per-device buffers */
@@ -504,16 +495,19 @@ static void reset_device(struct zram *zram)
memset(&zram->stats, 0, sizeof(zram->stats));
zram->disksize = 0;
+ mutex_unlock(&zram->init_lock);
}
-static int zram_ioctl_init_device(struct zram *zram)
+int zram_init_device(struct zram *zram)
{
int ret;
size_t num_pages;
+ mutex_lock(&zram->init_lock);
+
if (zram->init_done) {
- pr_info("Device already initialized!\n");
- return -EBUSY;
+ mutex_unlock(&zram->init_lock);
+ return 0;
}
zram_set_disksize(zram, totalram_pages << PAGE_SHIFT);
@@ -556,96 +550,19 @@ static int zram_ioctl_init_device(struct zram *zram)
}
zram->init_done = 1;
+ mutex_unlock(&zram->init_lock);
pr_debug("Initialization done!\n");
return 0;
fail:
- reset_device(zram);
+ mutex_unlock(&zram->init_lock);
+ zram_reset_device(zram);
pr_err("Initialization failed: err=%d\n", ret);
return ret;
}
-static int zram_ioctl_reset_device(struct zram *zram)
-{
- if (zram->init_done)
- reset_device(zram);
-
- return 0;
-}
-
-static int zram_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
- size_t disksize_kb;
-
- struct zram *zram = bdev->bd_disk->private_data;
-
- switch (cmd) {
- case ZRAMIO_SET_DISKSIZE_KB:
- if (zram->init_done) {
- ret = -EBUSY;
- goto out;
- }
- if (copy_from_user(&disksize_kb, (void *)arg,
- _IOC_SIZE(cmd))) {
- ret = -EFAULT;
- goto out;
- }
- zram->disksize = disksize_kb << 10;
- pr_info("Disk size set to %zu kB\n", disksize_kb);
- break;
-
- case ZRAMIO_GET_STATS:
- {
- struct zram_ioctl_stats *stats;
- if (!zram->init_done) {
- ret = -ENOTTY;
- goto out;
- }
- stats = kzalloc(sizeof(*stats), GFP_KERNEL);
- if (!stats) {
- ret = -ENOMEM;
- goto out;
- }
- zram_ioctl_get_stats(zram, stats);
- if (copy_to_user((void *)arg, stats, sizeof(*stats))) {
- kfree(stats);
- ret = -EFAULT;
- goto out;
- }
- kfree(stats);
- break;
- }
- case ZRAMIO_INIT:
- ret = zram_ioctl_init_device(zram);
- break;
-
- case ZRAMIO_RESET:
- /* Do not reset an active device! */
- if (bdev->bd_holders) {
- ret = -EBUSY;
- goto out;
- }
-
- /* Make sure all pending I/O is finished */
- if (bdev)
- fsync_bdev(bdev);
-
- ret = zram_ioctl_reset_device(zram);
- break;
-
- default:
- pr_info("Invalid ioctl %u\n", cmd);
- ret = -ENOTTY;
- }
-
-out:
- return ret;
-}
-
void zram_slot_free_notify(struct block_device *bdev, unsigned long index)
{
struct zram *zram;
@@ -656,7 +573,6 @@ void zram_slot_free_notify(struct block_device *bdev, unsigned long index)
}
static const struct block_device_operations zram_devops = {
- .ioctl = zram_ioctl,
.swap_slot_free_notify = zram_slot_free_notify,
.owner = THIS_MODULE
};
@@ -666,6 +582,7 @@ static int create_device(struct zram *zram, int device_id)
int ret = 0;
mutex_init(&zram->lock);
+ mutex_init(&zram->init_lock);
spin_lock_init(&zram->stat64_lock);
zram->queue = blk_alloc_queue(GFP_KERNEL);
@@ -696,7 +613,7 @@ static int create_device(struct zram *zram, int device_id)
zram->disk->private_data = zram;
snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
- /* Actual capacity set using ZRAMIO_SET_DISKSIZE_KB ioctl */
+ /* Actual capacity set using syfs (/sys/block/zram<id>/disksize */
set_capacity(zram->disk, 0);
/*
@@ -710,6 +627,15 @@ static int create_device(struct zram *zram, int device_id)
add_disk(zram->disk);
+#ifdef CONFIG_SYSFS
+ ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj,
+ &zram_disk_attr_group);
+ if (ret < 0) {
+ pr_warning("Error creating sysfs group");
+ goto out;
+ }
+#endif
+
zram->init_done = 0;
out:
@@ -718,6 +644,11 @@ out:
static void destroy_device(struct zram *zram)
{
+#ifdef CONFIG_SYSFS
+ sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
+ &zram_disk_attr_group);
+#endif
+
if (zram->disk) {
del_gendisk(zram->disk);
put_disk(zram->disk);
@@ -769,6 +700,7 @@ static int __init zram_init(void)
free_devices:
while (dev_id)
destroy_device(&devices[--dev_id]);
+ kfree(devices);
unregister:
unregister_blkdev(zram_major, "zram");
out:
@@ -785,7 +717,7 @@ static void __exit zram_exit(void)
destroy_device(zram);
if (zram->init_done)
- reset_device(zram);
+ zram_reset_device(zram);
}
unregister_blkdev(zram_major, "zram");
diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h
index 945f9740442f..a48155112b1e 100644
--- a/drivers/staging/zram/zram_drv.h
+++ b/drivers/staging/zram/zram_drv.h
@@ -18,7 +18,6 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
-#include "zram_ioctl.h"
#include "xvmalloc.h"
/*
@@ -85,11 +84,7 @@ struct table {
} __attribute__((aligned(4)));
struct zram_stats {
- /* basic stats */
- size_t compr_size; /* compressed size of pages stored -
- * needed to enforce memlimit */
- /* more stats */
-#if defined(CONFIG_ZRAM_STATS)
+ u64 compr_size; /* compressed size of pages stored */
u64 num_reads; /* failed + successful */
u64 num_writes; /* --do-- */
u64 failed_reads; /* should NEVER! happen */
@@ -100,7 +95,6 @@ struct zram_stats {
u32 pages_stored; /* no. of pages currently stored */
u32 good_compress; /* % of pages with compression ratio<=50% */
u32 pages_expand; /* % of incompressible pages */
-#endif
};
struct zram {
@@ -114,51 +108,24 @@ struct zram {
struct request_queue *queue;
struct gendisk *disk;
int init_done;
+ /* Prevent concurrent execution of device init and reset */
+ struct mutex init_lock;
/*
* This is the limit on amount of *uncompressed* worth of data
* we can store in a disk.
*/
- size_t disksize; /* bytes */
+ u64 disksize; /* bytes */
struct zram_stats stats;
};
-/*-- */
-
-/* Debugging and Stats */
-#if defined(CONFIG_ZRAM_STATS)
-static void zram_stat_inc(u32 *v)
-{
- *v = *v + 1;
-}
-
-static void zram_stat_dec(u32 *v)
-{
- *v = *v - 1;
-}
-
-static void zram_stat64_inc(struct zram *zram, u64 *v)
-{
- spin_lock(&zram->stat64_lock);
- *v = *v + 1;
- spin_unlock(&zram->stat64_lock);
-}
-
-static u64 zram_stat64_read(struct zram *zram, u64 *v)
-{
- u64 val;
-
- spin_lock(&zram->stat64_lock);
- val = *v;
- spin_unlock(&zram->stat64_lock);
-
- return val;
-}
-#else
-#define zram_stat_inc(v)
-#define zram_stat_dec(v)
-#define zram_stat64_inc(r, v)
-#define zram_stat64_read(r, v)
-#endif /* CONFIG_ZRAM_STATS */
+extern struct zram *devices;
+extern unsigned int num_devices;
+#ifdef CONFIG_SYSFS
+extern struct attribute_group zram_disk_attr_group;
+#endif
+
+extern int zram_init_device(struct zram *zram);
+extern void zram_reset_device(struct zram *zram);
#endif
diff --git a/drivers/staging/zram/zram_ioctl.h b/drivers/staging/zram/zram_ioctl.h
deleted file mode 100644
index 5c415fa4f17b..000000000000
--- a/drivers/staging/zram/zram_ioctl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Compressed RAM block device
- *
- * Copyright (C) 2008, 2009, 2010 Nitin Gupta
- *
- * This code is released using a dual license strategy: BSD/GPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of 3-clause BSD License
- * Released under the terms of GNU General Public License Version 2.0
- *
- * Project home: http://compcache.googlecode.com
- */
-
-#ifndef _ZRAM_IOCTL_H_
-#define _ZRAM_IOCTL_H_
-
-struct zram_ioctl_stats {
- u64 disksize; /* disksize in bytes (user specifies in KB) */
- u64 num_reads; /* failed + successful */
- u64 num_writes; /* --do-- */
- u64 failed_reads; /* should NEVER! happen */
- u64 failed_writes; /* can happen when memory is too low */
- u64 invalid_io; /* non-page-aligned I/O requests */
- u64 notify_free; /* no. of swap slot free notifications */
- u32 pages_zero; /* no. of zero filled pages */
- u32 good_compress_pct; /* no. of pages with compression ratio<=50% */
- u32 pages_expand_pct; /* no. of incompressible pages */
- u32 pages_stored;
- u32 pages_used;
- u64 orig_data_size;
- u64 compr_data_size;
- u64 mem_used_total;
-} __attribute__ ((packed, aligned(4)));
-
-#define ZRAMIO_SET_DISKSIZE_KB _IOW('z', 0, size_t)
-#define ZRAMIO_GET_STATS _IOR('z', 1, struct zram_ioctl_stats)
-#define ZRAMIO_INIT _IO('z', 2)
-#define ZRAMIO_RESET _IO('z', 3)
-
-#endif
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
new file mode 100644
index 000000000000..6c574a994d11
--- /dev/null
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -0,0 +1,224 @@
+/*
+ * Compressed RAM block device
+ *
+ * Copyright (C) 2008, 2009, 2010 Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ * Project home: http://compcache.googlecode.com/
+ */
+
+#include <linux/device.h>
+#include <linux/genhd.h>
+
+#include "zram_drv.h"
+
+#ifdef CONFIG_SYSFS
+
+static u64 zram_stat64_read(struct zram *zram, u64 *v)
+{
+ u64 val;
+
+ spin_lock(&zram->stat64_lock);
+ val = *v;
+ spin_unlock(&zram->stat64_lock);
+
+ return val;
+}
+
+static struct zram *dev_to_zram(struct device *dev)
+{
+ int i;
+ struct zram *zram = NULL;
+
+ for (i = 0; i < num_devices; i++) {
+ zram = &devices[i];
+ if (disk_to_dev(zram->disk) == dev)
+ break;
+ }
+
+ return zram;
+}
+
+static ssize_t disksize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n", zram->disksize);
+}
+
+static ssize_t disksize_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ int ret;
+ struct zram *zram = dev_to_zram(dev);
+
+ if (zram->init_done) {
+ pr_info("Cannot change disksize for initialized device\n");
+ return -EBUSY;
+ }
+
+ ret = strict_strtoull(buf, 10, &zram->disksize);
+ if (ret)
+ return ret;
+
+ zram->disksize &= PAGE_MASK;
+ set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
+
+ return len;
+}
+
+static ssize_t initstate_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%u\n", zram->init_done);
+}
+
+static ssize_t reset_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ int ret;
+ unsigned long do_reset;
+ struct zram *zram;
+ struct block_device *bdev;
+
+ zram = dev_to_zram(dev);
+ bdev = bdget_disk(zram->disk, 0);
+
+ /* Do not reset an active device! */
+ if (bdev->bd_holders)
+ return -EBUSY;
+
+ ret = strict_strtoul(buf, 10, &do_reset);
+ if (ret)
+ return ret;
+
+ if (!do_reset)
+ return -EINVAL;
+
+ /* Make sure all pending I/O is finished */
+ if (bdev)
+ fsync_bdev(bdev);
+
+ if (zram->init_done)
+ zram_reset_device(zram);
+
+ return len;
+}
+
+static ssize_t num_reads_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ zram_stat64_read(zram, &zram->stats.num_reads));
+}
+
+static ssize_t num_writes_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ zram_stat64_read(zram, &zram->stats.num_writes));
+}
+
+static ssize_t invalid_io_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ zram_stat64_read(zram, &zram->stats.invalid_io));
+}
+
+static ssize_t notify_free_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ zram_stat64_read(zram, &zram->stats.notify_free));
+}
+
+static ssize_t zero_pages_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%u\n", zram->stats.pages_zero);
+}
+
+static ssize_t orig_data_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ (u64)(zram->stats.pages_stored) << PAGE_SHIFT);
+}
+
+static ssize_t compr_data_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct zram *zram = dev_to_zram(dev);
+
+ return sprintf(buf, "%llu\n",
+ zram_stat64_read(zram, &zram->stats.compr_size));
+}
+
+static ssize_t mem_used_total_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u64 val = 0;
+ struct zram *zram = dev_to_zram(dev);
+
+ if (zram->init_done) {
+ val = xv_get_total_size_bytes(zram->mem_pool) +
+ ((u64)(zram->stats.pages_expand) << PAGE_SHIFT);
+ }
+
+ return sprintf(buf, "%llu\n", val);
+}
+
+static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO,
+ disksize_show, disksize_store);
+static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
+static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store);
+static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
+static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
+static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
+static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL);
+static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL);
+static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
+static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL);
+static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
+
+static struct attribute *zram_disk_attrs[] = {
+ &dev_attr_disksize.attr,
+ &dev_attr_initstate.attr,
+ &dev_attr_reset.attr,
+ &dev_attr_num_reads.attr,
+ &dev_attr_num_writes.attr,
+ &dev_attr_invalid_io.attr,
+ &dev_attr_notify_free.attr,
+ &dev_attr_zero_pages.attr,
+ &dev_attr_orig_data_size.attr,
+ &dev_attr_compr_data_size.attr,
+ &dev_attr_mem_used_total.attr,
+ NULL,
+};
+
+struct attribute_group zram_disk_attr_group = {
+ .attrs = zram_disk_attrs,
+};
+
+#endif /* CONFIG_SYSFS */
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index b53deee25d74..b6fc11bf3981 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -257,7 +257,7 @@
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
@@ -277,6 +277,7 @@
#define TYPE(inode) (iminor(inode) >> 4)
#define NUM(inode) (iminor(inode) & 0xf)
+static DEFINE_MUTEX(ixj_mutex);
static int ixjdebug;
static int hertz = HZ;
static int samplerate = 100;
@@ -6655,9 +6656,9 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar
static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&ixj_mutex);
ret = do_ixj_ioctl(file_p, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&ixj_mutex);
return ret;
}
@@ -6676,7 +6677,8 @@ static const struct file_operations ixj_fops =
.poll = ixj_poll,
.unlocked_ioctl = ixj_ioctl,
.release = ixj_release,
- .fasync = ixj_fasync
+ .fasync = ixj_fasync,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int ixj_linetest(IXJ *j)
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index f3873f650bb4..a62c1baf32fc 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -130,6 +130,7 @@ static const struct file_operations phone_fops =
{
.owner = THIS_MODULE,
.open = phone_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
/*
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index bff1afbde5a4..3854b3e07486 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -740,6 +740,7 @@ static const struct file_operations uio_fops = {
.mmap = uio_mmap,
.poll = uio_poll,
.fasync = uio_fasync,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int uio_major_init(void)
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
index 85c9884a67fd..fc22e1e6f215 100644
--- a/drivers/uio/uio_pci_generic.c
+++ b/drivers/uio/uio_pci_generic.c
@@ -128,12 +128,6 @@ static int __devinit probe(struct pci_dev *pdev,
struct uio_pci_generic_dev *gdev;
int err;
- if (!pdev->irq) {
- dev_warn(&pdev->dev, "No IRQ assigned to device: "
- "no support for interrupts?\n");
- return -ENODEV;
- }
-
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
@@ -141,6 +135,13 @@ static int __devinit probe(struct pci_dev *pdev,
return err;
}
+ if (!pdev->irq) {
+ dev_warn(&pdev->dev, "No IRQ assigned to device: "
+ "no support for interrupts?\n");
+ pci_disable_device(pdev);
+ return -ENODEV;
+ }
+
err = verify_pci_2_3(pdev);
if (err)
goto err_verify;
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 593fc5e2d2e6..f383cb42b1d7 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -1127,6 +1127,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
{
struct cxacru_data *instance;
struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD];
int ret;
/* instance init */
@@ -1171,15 +1172,34 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
goto fail;
}
- usb_fill_int_urb(instance->rcv_urb,
+ if (!cmd_ep) {
+ dbg("cxacru_bind: no command endpoint");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT) {
+ usb_fill_int_urb(instance->rcv_urb,
usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
instance->rcv_buf, PAGE_SIZE,
cxacru_blocking_completion, &instance->rcv_done, 1);
- usb_fill_int_urb(instance->snd_urb,
+ usb_fill_int_urb(instance->snd_urb,
usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
instance->snd_buf, PAGE_SIZE,
cxacru_blocking_completion, &instance->snd_done, 4);
+ } else {
+ usb_fill_bulk_urb(instance->rcv_urb,
+ usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD),
+ instance->rcv_buf, PAGE_SIZE,
+ cxacru_blocking_completion, &instance->rcv_done);
+
+ usb_fill_bulk_urb(instance->snd_urb,
+ usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
+ instance->snd_buf, PAGE_SIZE,
+ cxacru_blocking_completion, &instance->snd_done);
+ }
mutex_init(&instance->cm_serialize);
@@ -1324,8 +1344,24 @@ static struct usbatm_driver cxacru_driver = {
.tx_padding = 11,
};
-static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int cxacru_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ char buf[15];
+
+ /* Avoid ADSL routers (cx82310_eth).
+ * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD".
+ */
+ if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC
+ && usb_string(usb_dev, usb_dev->descriptor.iProduct,
+ buf, sizeof(buf)) > 0) {
+ if (!strcmp(buf, "USB NET CARD")) {
+ dev_info(&intf->dev, "ignoring cx82310_eth device\n");
+ return -ENODEV;
+ }
+ }
+
return usbatm_usb_probe(intf, id, &cxacru_driver);
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 1833b3a71515..bc62fae0680f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -965,7 +965,8 @@ static int acm_probe(struct usb_interface *intf,
}
if (!buflen) {
- if (intf->cur_altsetting->endpoint->extralen &&
+ if (intf->cur_altsetting->endpoint &&
+ intf->cur_altsetting->endpoint->extralen &&
intf->cur_altsetting->endpoint->extra) {
dev_dbg(&intf->dev,
"Seeking extra descriptors on endpoint\n");
@@ -1481,6 +1482,11 @@ static int acm_reset_resume(struct usb_interface *intf)
USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
USB_CDC_ACM_PROTO_VENDOR)
+#define SAMSUNG_PCSUITE_ACM_INFO(x) \
+ USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \
+ USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \
+ USB_CDC_ACM_PROTO_VENDOR)
+
/*
* USB driver structure.
*/
@@ -1591,6 +1597,17 @@ static const struct usb_device_id acm_ids[] = {
{ NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */
{ NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */
{ NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */
+ { NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */
+ { NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */
+ { NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */
+ { NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */
+ { NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */
+ { NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */
+ { NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */
+ { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */
+ { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */
+ { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */
+ { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */
/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
@@ -1599,6 +1616,10 @@ static const struct usb_device_id acm_ids[] = {
.driver_info = NOT_A_MODEM,
},
+ /* control interfaces without any protocol set */
+ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+ USB_CDC_PROTO_NONE) },
+
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 094c76b5de17..8c63f4994f57 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -584,7 +584,8 @@ static const struct file_operations wdm_fops = {
.open = wdm_open,
.flush = wdm_flush,
.release = wdm_release,
- .poll = wdm_poll
+ .poll = wdm_poll,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct usb_class_driver wdm_class = {
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index e325162859b0..173eacfa6854 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1043,6 +1043,7 @@ static const struct file_operations usblp_fops = {
.compat_ioctl = usblp_ioctl,
.open = usblp_open,
.release = usblp_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static char *usblp_devnode(struct device *dev, mode_t *mode)
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 3e7c1b800ebb..1f4a091cdddf 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -987,6 +987,7 @@ static const struct file_operations fops = {
.open = usbtmc_open,
.release = usbtmc_release,
.unlocked_ioctl = usbtmc_ioctl,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct usb_class_driver usbtmc_class = {
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index f06f5dbc8cdc..0724c5e0af76 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -59,6 +59,7 @@ static int usb_open(struct inode * inode, struct file * file)
static const struct file_operations usb_fops = {
.owner = THIS_MODULE,
.open = usb_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct usb_class {
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5cca00a6d09d..2d6e53a180fd 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2278,6 +2278,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
"request interrupt %d failed\n", irqnum);
goto err_request_irq;
}
+ watch_irq(irqnum, hcd);
hcd->irq = irqnum;
dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,
(hcd->driver->flags & HCD_MEMORY) ?
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 84c1897188d2..5da546c4fd79 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3629,7 +3629,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
}
if (!parent_hdev) {
- /* this requires hcd-specific logic; see OHCI hc_restart() */
+ /* this requires hcd-specific logic; see ohci_restart() */
dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
return -EISDIR;
}
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 095fa5366690..9e2ec9f685c0 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -39,7 +39,6 @@
#include <linux/parser.h>
#include <linux/notifier.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/usb/hcd.h>
#include <asm/byteorder.h>
#include "usb.h"
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index fd4c36ea5e46..844683e50383 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1724,6 +1724,15 @@ free_interfaces:
if (ret)
goto free_interfaces;
+ /* if it's already configured, clear out old state first.
+ * getting rid of old interfaces means unbinding their drivers.
+ */
+ if (dev->state != USB_STATE_ADDRESS)
+ usb_disable_device(dev, 1); /* Skip ep0 */
+
+ /* Get rid of pending async Set-Config requests for this device */
+ cancel_async_set_config(dev);
+
/* Make sure we have bandwidth (and available HCD resources) for this
* configuration. Remove endpoints from the schedule if we're dropping
* this configuration to set configuration 0. After this point, the
@@ -1733,20 +1742,11 @@ free_interfaces:
mutex_lock(&hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
- usb_autosuspend_device(dev);
mutex_unlock(&hcd->bandwidth_mutex);
+ usb_autosuspend_device(dev);
goto free_interfaces;
}
- /* if it's already configured, clear out old state first.
- * getting rid of old interfaces means unbinding their drivers.
- */
- if (dev->state != USB_STATE_ADDRESS)
- usb_disable_device(dev, 1); /* Skip ep0 */
-
- /* Get rid of pending async Set-Config requests for this device */
- cancel_async_set_config(dev);
-
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
NULL, 0, USB_CTRL_SET_TIMEOUT);
@@ -1761,8 +1761,8 @@ free_interfaces:
if (!cp) {
usb_set_device_state(dev, USB_STATE_ADDRESS);
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
- usb_autosuspend_device(dev);
mutex_unlock(&hcd->bandwidth_mutex);
+ usb_autosuspend_device(dev);
goto free_interfaces;
}
mutex_unlock(&hcd->bandwidth_mutex);
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 419e6b34e2fe..c14fc082864f 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -401,8 +401,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
};
/* Check that the pipe's type matches the endpoint's type */
- if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+ if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) {
+ dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
+ usb_pipetype(urb->pipe), pipetypes[xfertype]);
return -EPIPE; /* The most suitable error code :-) */
+ }
/* enforce simple/standard policy */
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 4de1fc6e92cb..8eb7eb8e48ed 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -716,8 +716,8 @@ config USB_FUNCTIONFS
depends on EXPERIMENTAL
select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
help
- The Function Filesystem (FunctioFS) lets one create USB
- composite functions in user space in the same way as GadgetFS
+ The Function Filesystem (FunctionFS) lets one create USB
+ composite functions in user space in the same way GadgetFS
lets one create USB gadgets in user space. This allows creation
of composite gadgets such that some of the functions are
implemented in kernel space (for instance Ethernet, serial or
@@ -733,14 +733,14 @@ config USB_FUNCTIONFS_ETH
bool "Include configuration with CDC ECM (Ethernet)"
depends on USB_FUNCTIONFS && NET
help
- Include a configuration with CDC ECM funcion (Ethernet) and the
- Funcion Filesystem.
+ Include a configuration with CDC ECM function (Ethernet) and the
+ Function Filesystem.
config USB_FUNCTIONFS_RNDIS
bool "Include configuration with RNDIS (Ethernet)"
depends on USB_FUNCTIONFS && NET
help
- Include a configuration with RNDIS funcion (Ethernet) and the Filesystem.
+ Include a configuration with RNDIS function (Ethernet) and the Filesystem.
config USB_FUNCTIONFS_GENERIC
bool "Include 'pure' configuration"
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index 731150d4b1d9..2b361500af1e 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -203,7 +203,7 @@ static void print_regs(struct udc *dev)
DBG(dev, "DMA mode = PPBNDU (packet per buffer "
"WITHOUT desc. update)\n");
dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU");
- } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) {
+ } else if (use_dma && use_dma_ppb && use_dma_ppb_du) {
DBG(dev, "DMA mode = PPBDU (packet per buffer "
"WITH desc. update)\n");
dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU");
@@ -1954,13 +1954,14 @@ static int setup_ep0(struct udc *dev)
}
/* Called by gadget driver to register itself */
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct udc *dev = udc;
int retval;
u32 tmp;
- if (!driver || !driver->bind || !driver->setup
+ if (!driver || !bind || !driver->setup
|| driver->speed != USB_SPEED_HIGH)
return -EINVAL;
if (!dev)
@@ -1972,7 +1973,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev->driver = driver;
dev->gadget.dev.driver = &driver->driver;
- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
/* Some gadget drivers use both ep0 directions.
* NOTE: to gadget driver, ep0 is just one endpoint...
@@ -2000,7 +2001,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
return 0;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/* shutdown requests and disconnect from gadget */
static void
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 93ead19507b6..bdec36acd0fa 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1266,7 +1266,6 @@ write_in:
csr |= AT91_UDP_TXPKTRDY;
__raw_writel(csr, creg);
udc->req_pending = 0;
- return;
}
static void handle_ep0(struct at91_udc *udc)
@@ -1628,7 +1627,8 @@ static void at91_vbus_timer(unsigned long data)
schedule_work(&udc->vbus_timer_work);
}
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct at91_udc *udc = &controller;
int retval;
@@ -1636,7 +1636,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (!driver
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->setup) {
DBG("bad parameter.\n");
return -EINVAL;
@@ -1653,9 +1653,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
udc->enabled = 1;
udc->selfpowered = 1;
- retval = driver->bind(&udc->gadget);
+ retval = bind(&udc->gadget);
if (retval) {
- DBG("driver->bind() returned %d\n", retval);
+ DBG("bind() returned %d\n", retval);
udc->driver = NULL;
udc->gadget.dev.driver = NULL;
dev_set_drvdata(&udc->gadget.dev, NULL);
@@ -1671,7 +1671,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
DBG("bound to %s\n", driver->driver.name);
return 0;
}
-EXPORT_SYMBOL (usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index d623c7bda1f6..e4810c6a0b1f 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1789,7 +1789,8 @@ out:
return IRQ_HANDLED;
}
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct usba_udc *udc = &the_udc;
unsigned long flags;
@@ -1812,7 +1813,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
clk_enable(udc->pclk);
clk_enable(udc->hclk);
- ret = driver->bind(&udc->gadget);
+ ret = bind(&udc->gadget);
if (ret) {
DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
driver->driver.name, ret);
@@ -1841,7 +1842,7 @@ err_driver_bind:
udc->gadget.dev.driver = NULL;
return ret;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index b744ccd0f34d..93b999e49ef3 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -89,7 +89,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
/*-------------------------------------------------------------------------*/
-static int __ref audio_do_config(struct usb_configuration *c)
+static int __init audio_do_config(struct usb_configuration *c)
{
/* FIXME alloc iConfiguration string, set it in c->strings */
@@ -105,7 +105,6 @@ static int __ref audio_do_config(struct usb_configuration *c)
static struct usb_configuration audio_config_driver = {
.label = DRIVER_DESC,
- .bind = audio_do_config,
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -113,7 +112,7 @@ static struct usb_configuration audio_config_driver = {
/*-------------------------------------------------------------------------*/
-static int __ref audio_bind(struct usb_composite_dev *cdev)
+static int __init audio_bind(struct usb_composite_dev *cdev)
{
int gcnum;
int status;
@@ -145,7 +144,7 @@ static int __ref audio_bind(struct usb_composite_dev *cdev)
strings_dev[STRING_PRODUCT_IDX].id = status;
device_desc.iProduct = status;
- status = usb_add_config(cdev, &audio_config_driver);
+ status = usb_add_config(cdev, &audio_config_driver, audio_do_config);
if (status < 0)
goto fail;
@@ -166,13 +165,12 @@ static struct usb_composite_driver audio_driver = {
.name = "g_audio",
.dev = &device_desc,
.strings = audio_strings,
- .bind = audio_bind,
.unbind = __exit_p(audio_unbind),
};
static int __init init(void)
{
- return usb_composite_register(&audio_driver);
+ return usb_composite_probe(&audio_driver, audio_bind);
}
module_init(init);
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 1f5ba2fd4c1f..2720ab07ef1a 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -129,7 +129,7 @@ static u8 hostaddr[ETH_ALEN];
/*
* We _always_ have both CDC ECM and CDC ACM functions.
*/
-static int __ref cdc_do_config(struct usb_configuration *c)
+static int __init cdc_do_config(struct usb_configuration *c)
{
int status;
@@ -151,7 +151,6 @@ static int __ref cdc_do_config(struct usb_configuration *c)
static struct usb_configuration cdc_config_driver = {
.label = "CDC Composite (ECM + ACM)",
- .bind = cdc_do_config,
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -159,7 +158,7 @@ static struct usb_configuration cdc_config_driver = {
/*-------------------------------------------------------------------------*/
-static int __ref cdc_bind(struct usb_composite_dev *cdev)
+static int __init cdc_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
@@ -218,7 +217,7 @@ static int __ref cdc_bind(struct usb_composite_dev *cdev)
device_desc.iProduct = status;
/* register our configuration */
- status = usb_add_config(cdev, &cdc_config_driver);
+ status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config);
if (status < 0)
goto fail1;
@@ -245,7 +244,6 @@ static struct usb_composite_driver cdc_driver = {
.name = "g_cdc",
.dev = &device_desc,
.strings = dev_strings,
- .bind = cdc_bind,
.unbind = __exit_p(cdc_unbind),
};
@@ -255,7 +253,7 @@ MODULE_LICENSE("GPL");
static int __init init(void)
{
- return usb_composite_register(&cdc_driver);
+ return usb_composite_probe(&cdc_driver, cdc_bind);
}
module_init(init);
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 699695128e33..98b36fc88c77 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2340,12 +2340,15 @@ static const struct usb_ep_ops usb_ep_ops = {
static const struct usb_gadget_ops usb_gadget_ops;
/**
- * usb_gadget_register_driver: register a gadget driver
+ * usb_gadget_probe_driver: register a gadget driver
+ * @driver: the driver being registered
+ * @bind: the driver's bind callback
*
- * Check usb_gadget_register_driver() at "usb_gadget.h" for details
- * Interrupts are enabled here
+ * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
+ * Interrupts are enabled here.
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct ci13xxx *udc = _udc;
unsigned long i, k, flags;
@@ -2354,7 +2357,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
trace("%p", driver);
if (driver == NULL ||
- driver->bind == NULL ||
+ bind == NULL ||
driver->unbind == NULL ||
driver->setup == NULL ||
driver->disconnect == NULL ||
@@ -2430,7 +2433,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
udc->gadget.dev.driver = &driver->driver;
spin_unlock_irqrestore(udc->lock, flags);
- retval = driver->bind(&udc->gadget); /* MAY SLEEP */
+ retval = bind(&udc->gadget); /* MAY SLEEP */
spin_lock_irqsave(udc->lock, flags);
if (retval) {
@@ -2447,7 +2450,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
usb_gadget_unregister_driver(driver);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/**
* usb_gadget_unregister_driver: unregister a gadget driver
@@ -2462,7 +2465,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
trace("%p", driver);
if (driver == NULL ||
- driver->bind == NULL ||
driver->unbind == NULL ||
driver->setup == NULL ||
driver->disconnect == NULL ||
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 1160c55de7f2..5e2bd7428424 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>
+#include <linux/utsname.h>
#include <linux/usb/composite.h>
@@ -39,6 +40,7 @@
#define USB_BUFSIZ 1024
static struct usb_composite_driver *composite;
+static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
/* Some systems will need runtime overrides for the product identifers
* published in the device descriptor, either numbers or strings or both.
@@ -69,6 +71,8 @@ static char *iSerialNumber;
module_param(iSerialNumber, charp, 0);
MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
+static char composite_manufacturer[50];
+
/*-------------------------------------------------------------------------*/
/**
@@ -470,18 +474,20 @@ done:
* usb_add_config() - add a configuration to a device.
* @cdev: wraps the USB gadget
* @config: the configuration, with bConfigurationValue assigned
+ * @bind: the configuration's bind function
* Context: single threaded during gadget setup
*
- * One of the main tasks of a composite driver's bind() routine is to
+ * One of the main tasks of a composite @bind() routine is to
* add each of the configurations it supports, using this routine.
*
- * This function returns the value of the configuration's bind(), which
+ * This function returns the value of the configuration's @bind(), which
* is zero for success else a negative errno value. Binding configurations
* assigns global resources including string IDs, and per-configuration
* resources such as interface IDs and endpoints.
*/
int usb_add_config(struct usb_composite_dev *cdev,
- struct usb_configuration *config)
+ struct usb_configuration *config,
+ int (*bind)(struct usb_configuration *))
{
int status = -EINVAL;
struct usb_configuration *c;
@@ -490,7 +496,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
config->bConfigurationValue,
config->label, config);
- if (!config->bConfigurationValue || !config->bind)
+ if (!config->bConfigurationValue || !bind)
goto done;
/* Prevent duplicate configuration identifiers */
@@ -507,7 +513,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
INIT_LIST_HEAD(&config->functions);
config->next_interface_id = 0;
- status = config->bind(config);
+ status = bind(config);
if (status < 0) {
list_del(&config->list);
config->cdev = NULL;
@@ -533,7 +539,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
}
}
- /* set_alt(), or next config->bind(), sets up
+ /* set_alt(), or next bind(), sets up
* ep->driver_data as needed.
*/
usb_ep_autoconfig_reset(cdev->gadget);
@@ -599,6 +605,7 @@ static int get_string(struct usb_composite_dev *cdev,
struct usb_configuration *c;
struct usb_function *f;
int len;
+ const char *str;
/* Yes, not only is USB's I18N support probably more than most
* folk will ever care about ... also, it's all supported here.
@@ -638,9 +645,29 @@ static int get_string(struct usb_composite_dev *cdev,
return s->bLength;
}
- /* Otherwise, look up and return a specified string. String IDs
- * are device-scoped, so we look up each string table we're told
- * about. These lookups are infrequent; simpler-is-better here.
+ /* Otherwise, look up and return a specified string. First
+ * check if the string has not been overridden.
+ */
+ if (cdev->manufacturer_override == id)
+ str = iManufacturer ?: composite->iManufacturer ?:
+ composite_manufacturer;
+ else if (cdev->product_override == id)
+ str = iProduct ?: composite->iProduct;
+ else if (cdev->serial_override == id)
+ str = iSerialNumber;
+ else
+ str = NULL;
+ if (str) {
+ struct usb_gadget_strings strings = {
+ .language = language,
+ .strings = &(struct usb_string) { 0xff, str }
+ };
+ return usb_gadget_get_string(&strings, 0xff, buf);
+ }
+
+ /* String IDs are device-scoped, so we look up each string
+ * table we're told about. These lookups are infrequent;
+ * simpler-is-better here.
*/
if (composite->strings) {
len = lookup_string(composite->strings, buf, language, id);
@@ -1025,26 +1052,17 @@ composite_unbind(struct usb_gadget *gadget)
composite = NULL;
}
-static void
-string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
+static u8 override_id(struct usb_composite_dev *cdev, u8 *desc)
{
- struct usb_string *str = tab->strings;
-
- for (str = tab->strings; str->s; str++) {
- if (str->id == id) {
- str->s = s;
- return;
- }
+ if (!*desc) {
+ int ret = usb_string_id(cdev);
+ if (unlikely(ret < 0))
+ WARNING(cdev, "failed to override string ID\n");
+ else
+ *desc = ret;
}
-}
-static void
-string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
-{
- while (*tab) {
- string_override_one(*tab, id, s);
- tab++;
- }
+ return *desc;
}
static int composite_bind(struct usb_gadget *gadget)
@@ -1074,7 +1092,13 @@ static int composite_bind(struct usb_gadget *gadget)
cdev->bufsiz = USB_BUFSIZ;
cdev->driver = composite;
- usb_gadget_set_selfpowered(gadget);
+ /*
+ * As per USB compliance update, a device that is actively drawing
+ * more than 100mA from USB must report itself as bus-powered in
+ * the GetStatus(DEVICE) call.
+ */
+ if (CONFIG_USB_GADGET_VBUS_DRAW <= USB_SELF_POWER_VBUS_MAX_DRAW)
+ usb_gadget_set_selfpowered(gadget);
/* interface and string IDs start at zero via kzalloc.
* we force endpoints to start unassigned; few controller
@@ -1094,26 +1118,41 @@ static int composite_bind(struct usb_gadget *gadget)
* serial number), register function drivers, potentially update
* power state and consumption, etc
*/
- status = composite->bind(cdev);
+ status = composite_gadget_bind(cdev);
if (status < 0)
goto fail;
cdev->desc = *composite->dev;
cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
- /* strings can't be assigned before bind() allocates the
- * releavnt identifiers
- */
- if (cdev->desc.iManufacturer && iManufacturer)
- string_override(composite->strings,
- cdev->desc.iManufacturer, iManufacturer);
- if (cdev->desc.iProduct && iProduct)
- string_override(composite->strings,
- cdev->desc.iProduct, iProduct);
- if (cdev->desc.iSerialNumber && iSerialNumber)
- string_override(composite->strings,
- cdev->desc.iSerialNumber, iSerialNumber);
+ /* stirng overrides */
+ if (iManufacturer || !cdev->desc.iManufacturer) {
+ if (!iManufacturer && !composite->iManufacturer &&
+ !*composite_manufacturer)
+ snprintf(composite_manufacturer,
+ sizeof composite_manufacturer,
+ "%s %s with %s",
+ init_utsname()->sysname,
+ init_utsname()->release,
+ gadget->name);
+
+ cdev->manufacturer_override =
+ override_id(cdev, &cdev->desc.iManufacturer);
+ }
+
+ if (iProduct || (!cdev->desc.iProduct && composite->iProduct))
+ cdev->product_override =
+ override_id(cdev, &cdev->desc.iProduct);
+
+ if (iSerialNumber)
+ cdev->serial_override =
+ override_id(cdev, &cdev->desc.iSerialNumber);
+
+ /* has userspace failed to provide a serial number? */
+ if (composite->needs_serial && !cdev->desc.iSerialNumber)
+ WARNING(cdev, "userspace failed to provide iSerialNumber\n");
+ /* finish up */
status = device_create_file(&gadget->dev, &dev_attr_suspended);
if (status)
goto fail;
@@ -1177,7 +1216,6 @@ composite_resume(struct usb_gadget *gadget)
static struct usb_gadget_driver composite_driver = {
.speed = USB_SPEED_HIGH,
- .bind = composite_bind,
.unbind = composite_unbind,
.setup = composite_setup,
@@ -1192,8 +1230,12 @@ static struct usb_gadget_driver composite_driver = {
};
/**
- * usb_composite_register() - register a composite driver
+ * usb_composite_probe() - register a composite driver
* @driver: the driver to register
+ * @bind: the callback used to allocate resources that are shared across the
+ * whole device, such as string IDs, and add its configurations using
+ * @usb_add_config(). This may fail by returning a negative errno
+ * value; it should return zero on successful initialization.
* Context: single threaded during gadget setup
*
* This function is used to register drivers using the composite driver
@@ -1206,18 +1248,22 @@ static struct usb_gadget_driver composite_driver = {
* while it was binding. That would usually be done in order to wait for
* some userspace participation.
*/
-int usb_composite_register(struct usb_composite_driver *driver)
+extern int usb_composite_probe(struct usb_composite_driver *driver,
+ int (*bind)(struct usb_composite_dev *cdev))
{
- if (!driver || !driver->dev || !driver->bind || composite)
+ if (!driver || !driver->dev || !bind || composite)
return -EINVAL;
+ if (!driver->iProduct)
+ driver->iProduct = driver->name;
if (!driver->name)
driver->name = "composite";
composite_driver.function = (char *) driver->name;
composite_driver.driver.name = driver->name;
composite = driver;
+ composite_gadget_bind = bind;
- return usb_gadget_register_driver(&composite_driver);
+ return usb_gadget_probe_driver(&composite_driver, composite_bind);
}
/**
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c
index 0ed50a2c0a36..e5ac8a316fec 100644
--- a/drivers/usb/gadget/dbgp.c
+++ b/drivers/usb/gadget/dbgp.c
@@ -386,15 +386,13 @@ static int dbgp_setup(struct usb_gadget *gadget,
} else
goto fail;
- if (len >= 0) {
- req->length = min(length, len);
- req->zero = len < req->length;
- if (data && req->length)
- memcpy(req->buf, data, req->length);
-
- req->complete = dbgp_setup_complete;
- return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
- }
+ req->length = min(length, len);
+ req->zero = len < req->length;
+ if (data && req->length)
+ memcpy(req->buf, data, req->length);
+
+ req->complete = dbgp_setup_complete;
+ return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
fail:
dev_dbg(&dbgp.gadget->dev,
@@ -405,7 +403,6 @@ fail:
static struct usb_gadget_driver dbgp_driver = {
.function = "dbgp",
.speed = USB_SPEED_HIGH,
- .bind = dbgp_bind,
.unbind = dbgp_unbind,
.setup = dbgp_setup,
.disconnect = dbgp_disconnect,
@@ -417,7 +414,7 @@ static struct usb_gadget_driver dbgp_driver = {
static int __init dbgp_init(void)
{
- return usb_gadget_register_driver(&dbgp_driver);
+ return usb_gadget_probe_driver(&dbgp_driver, dbgp_bind);
}
static void __exit dbgp_exit(void)
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index dc6546248ed9..7bb9d78aac27 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -748,7 +748,8 @@ static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
*/
int
-usb_gadget_register_driver (struct usb_gadget_driver *driver)
+usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct dummy *dum = the_controller;
int retval, i;
@@ -757,8 +758,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
return -EINVAL;
if (dum->driver)
return -EBUSY;
- if (!driver->bind || !driver->setup
- || driver->speed == USB_SPEED_UNKNOWN)
+ if (!bind || !driver->setup || driver->speed == USB_SPEED_UNKNOWN)
return -EINVAL;
/*
@@ -796,7 +796,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
dum->gadget.dev.driver = &driver->driver;
dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
driver->driver.name);
- retval = driver->bind(&dum->gadget);
+ retval = bind(&dum->gadget);
if (retval) {
dum->driver = NULL;
dum->gadget.dev.driver = NULL;
@@ -812,7 +812,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
return 0;
}
-EXPORT_SYMBOL (usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int
usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 114fa024c22c..1690c9d68256 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -237,7 +237,7 @@ static u8 hostaddr[ETH_ALEN];
* the first one present. That's to make Microsoft's drivers happy,
* and to follow DOCSIS 1.0 (cable modem standard).
*/
-static int __ref rndis_do_config(struct usb_configuration *c)
+static int __init rndis_do_config(struct usb_configuration *c)
{
/* FIXME alloc iConfiguration string, set it in c->strings */
@@ -251,7 +251,6 @@ static int __ref rndis_do_config(struct usb_configuration *c)
static struct usb_configuration rndis_config_driver = {
.label = "RNDIS",
- .bind = rndis_do_config,
.bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -270,7 +269,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode");
/*
* We _always_ have an ECM, CDC Subset, or EEM configuration.
*/
-static int __ref eth_do_config(struct usb_configuration *c)
+static int __init eth_do_config(struct usb_configuration *c)
{
/* FIXME alloc iConfiguration string, set it in c->strings */
@@ -289,7 +288,6 @@ static int __ref eth_do_config(struct usb_configuration *c)
static struct usb_configuration eth_config_driver = {
/* .label = f(hardware) */
- .bind = eth_do_config,
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -297,7 +295,7 @@ static struct usb_configuration eth_config_driver = {
/*-------------------------------------------------------------------------*/
-static int __ref eth_bind(struct usb_composite_dev *cdev)
+static int __init eth_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
@@ -373,12 +371,13 @@ static int __ref eth_bind(struct usb_composite_dev *cdev)
/* register our configuration(s); RNDIS first, if it's used */
if (has_rndis()) {
- status = usb_add_config(cdev, &rndis_config_driver);
+ status = usb_add_config(cdev, &rndis_config_driver,
+ rndis_do_config);
if (status < 0)
goto fail;
}
- status = usb_add_config(cdev, &eth_config_driver);
+ status = usb_add_config(cdev, &eth_config_driver, eth_do_config);
if (status < 0)
goto fail;
@@ -402,7 +401,6 @@ static struct usb_composite_driver eth_driver = {
.name = "g_ether",
.dev = &device_desc,
.strings = dev_strings,
- .bind = eth_bind,
.unbind = __exit_p(eth_unbind),
};
@@ -412,7 +410,7 @@ MODULE_LICENSE("GPL");
static int __init init(void)
{
- return usb_composite_register(&eth_driver);
+ return usb_composite_probe(&eth_driver, eth_bind);
}
module_init(init);
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 1f48ceb55a77..00975ed903d1 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -317,8 +317,6 @@ static void f_audio_playback_work(struct work_struct *data)
u_audio_playback(&audio->card, play_buf->buf, play_buf->actual);
f_audio_buffer_free(play_buf);
-
- return;
}
static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 53e120208e99..e4ff2352d560 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -318,8 +318,6 @@ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
spin_unlock(&hidg->spinlock);
wake_up(&hidg->read_queue);
-
- return;
}
static int hidg_setup(struct usb_function *f,
@@ -413,8 +411,6 @@ static void hidg_disable(struct usb_function *f)
usb_ep_disable(hidg->in_ep);
hidg->in_ep->driver_data = NULL;
-
- return;
}
static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
@@ -451,6 +447,7 @@ const struct file_operations f_hidg_fops = {
.write = f_hidg_write,
.read = f_hidg_read,
.poll = f_hidg_poll,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f)
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 43225879c3cd..b37960f9e753 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -324,7 +324,7 @@ static void loopback_disable(struct usb_function *f)
/*-------------------------------------------------------------------------*/
-static int __ref loopback_bind_config(struct usb_configuration *c)
+static int __init loopback_bind_config(struct usb_configuration *c)
{
struct f_loopback *loop;
int status;
@@ -346,10 +346,9 @@ static int __ref loopback_bind_config(struct usb_configuration *c)
return status;
}
-static struct usb_configuration loopback_driver = {
+static struct usb_configuration loopback_driver = {
.label = "loopback",
.strings = loopback_strings,
- .bind = loopback_bind_config,
.bConfigurationValue = 2,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
/* .iConfiguration = DYNAMIC */
@@ -382,5 +381,5 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}
- return usb_add_config(cdev, &loopback_driver);
+ return usb_add_config(cdev, &loopback_driver, loopback_bind_config);
}
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 32cce029f65c..44e5ffed5c08 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -73,6 +73,8 @@
* being removable.
* ->cdrom Flag specifying that LUN shall be reported as
* being a CD-ROM.
+ * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12)
+ * commands for this LUN shall be ignored.
*
* lun_name_format A printf-like format for names of the LUN
* devices. This determines how the
@@ -127,6 +129,8 @@
* Default true, boolean for removable media.
* cdrom=b[,b...] Default false, boolean for whether to emulate
* a CD-ROM drive.
+ * nofua=b[,b...] Default false, booleans for ignore FUA flag
+ * in SCSI WRITE(10,12) commands
* luns=N Default N = number of filenames, number of
* LUNs to support.
* stall Default determined according to the type of
@@ -409,6 +413,7 @@ struct fsg_config {
char ro;
char removable;
char cdrom;
+ char nofua;
} luns[FSG_MAX_LUNS];
const char *lun_name_format;
@@ -887,7 +892,7 @@ static int do_write(struct fsg_common *common)
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
- if (common->cmnd[1] & 0x08) { /* FUA */
+ if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_SYNC;
spin_unlock(&curlun->filp->f_lock);
@@ -2662,6 +2667,7 @@ static int fsg_main_thread(void *common_)
/* Write permission is checked per LUN in store_*() functions. */
static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
@@ -2768,6 +2774,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
rc = device_create_file(&curlun->dev, &dev_attr_file);
if (rc)
goto error_luns;
+ rc = device_create_file(&curlun->dev, &dev_attr_nofua);
+ if (rc)
+ goto error_luns;
if (lcfg->filename) {
rc = fsg_lun_open(curlun, lcfg->filename);
@@ -2911,6 +2920,7 @@ static void fsg_common_release(struct kref *ref)
/* In error recovery common->nluns may be zero. */
for (; i; --i, ++lun) {
+ device_remove_file(&lun->dev, &dev_attr_nofua);
device_remove_file(&lun->dev, &dev_attr_ro);
device_remove_file(&lun->dev, &dev_attr_file);
fsg_lun_close(lun);
@@ -3069,8 +3079,10 @@ struct fsg_module_parameters {
int ro[FSG_MAX_LUNS];
int removable[FSG_MAX_LUNS];
int cdrom[FSG_MAX_LUNS];
+ int nofua[FSG_MAX_LUNS];
unsigned int file_count, ro_count, removable_count, cdrom_count;
+ unsigned int nofua_count;
unsigned int luns; /* nluns */
int stall; /* can_stall */
};
@@ -3096,6 +3108,8 @@ struct fsg_module_parameters {
"true to simulate removable media"); \
_FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \
"true to simulate CD-ROM instead of disk"); \
+ _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \
+ "true to ignore SCSI WRITE(10,12) FUA bit"); \
_FSG_MODULE_PARAM(prefix, params, luns, uint, \
"number of LUNs"); \
_FSG_MODULE_PARAM(prefix, params, stall, bool, \
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 685d768f336e..e403a534dd55 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -404,7 +404,7 @@ static void sourcesink_disable(struct usb_function *f)
/*-------------------------------------------------------------------------*/
-static int __ref sourcesink_bind_config(struct usb_configuration *c)
+static int __init sourcesink_bind_config(struct usb_configuration *c)
{
struct f_sourcesink *ss;
int status;
@@ -498,7 +498,6 @@ unknown:
static struct usb_configuration sourcesink_driver = {
.label = "source/sink",
.strings = sourcesink_strings,
- .bind = sourcesink_bind_config,
.setup = sourcesink_setup,
.bConfigurationValue = 3,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -532,5 +531,5 @@ int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}
- return usb_add_config(cdev, &sourcesink_driver);
+ return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);
}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a857b7ac238c..ce437f5dd674 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -89,6 +89,7 @@
* Required if "removable" is not set, names of
* the files or block devices used for
* backing storage
+ * serial=HHHH... Required serial number (string of hex chars)
* ro=b[,b...] Default false, booleans for read-only access
* removable Default false, boolean for removable media
* luns=N Default N = number of filenames, number of
@@ -108,12 +109,11 @@
* vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID
* product=0xPPPP Default 0xa4a5 (FSG), USB Product ID
* release=0xRRRR Override the USB release number (bcdDevice)
- * serial=HHHH... Override serial number (string of hex chars)
* buflen=N Default N=16384, buffer size used (will be
* rounded down to a multiple of
* PAGE_CACHE_SIZE)
*
- * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro",
* "removable", "luns", "nofua", "stall", and "cdrom" options are available;
* default values are used for everything else.
*
@@ -273,13 +273,10 @@
#define DRIVER_DESC "File-backed Storage Gadget"
#define DRIVER_NAME "g_file_storage"
-/* DRIVER_VERSION must be at least 6 characters long, as it is used
- * to generate a fallback serial number. */
-#define DRIVER_VERSION "20 November 2008"
+#define DRIVER_VERSION "1 September 2010"
static char fsg_string_manufacturer[64];
static const char fsg_string_product[] = DRIVER_DESC;
-static char fsg_string_serial[13];
static const char fsg_string_config[] = "Self-powered";
static const char fsg_string_interface[] = "Mass Storage";
@@ -305,6 +302,7 @@ MODULE_LICENSE("Dual BSD/GPL");
static struct {
char *file[FSG_MAX_LUNS];
+ char *serial;
int ro[FSG_MAX_LUNS];
int nofua[FSG_MAX_LUNS];
unsigned int num_filenames;
@@ -321,7 +319,6 @@ static struct {
unsigned short vendor;
unsigned short product;
unsigned short release;
- char *serial;
unsigned int buflen;
int transport_type;
@@ -346,6 +343,9 @@ module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
S_IRUGO);
MODULE_PARM_DESC(file, "names of backing files or devices");
+module_param_named(serial, mod_data.serial, charp, S_IRUGO);
+MODULE_PARM_DESC(serial, "USB serial number");
+
module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
MODULE_PARM_DESC(ro, "true to force read-only");
@@ -365,9 +365,6 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO);
MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
-module_param_named(serial, mod_data.serial, charp, S_IRUGO);
-MODULE_PARM_DESC(serial, "USB serial number");
-
/* In the non-TEST version, only the module parameters listed above
* are available. */
#ifdef CONFIG_USB_FILE_STORAGE_TEST
@@ -3178,6 +3175,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
for (i = 0; i < fsg->nluns; ++i) {
curlun = &fsg->luns[i];
if (curlun->registered) {
+ device_remove_file(&curlun->dev, &dev_attr_nofua);
device_remove_file(&curlun->dev, &dev_attr_ro);
device_remove_file(&curlun->dev, &dev_attr_file);
fsg_lun_close(curlun);
@@ -3213,7 +3211,6 @@ static int __init check_parameters(struct fsg_dev *fsg)
{
int prot;
int gcnum;
- int i;
/* Store the default values */
mod_data.transport_type = USB_PR_BULK;
@@ -3309,45 +3306,29 @@ static int __init check_parameters(struct fsg_dev *fsg)
if ((*ch < '0' || *ch > '9') &&
(*ch < 'A' || *ch > 'F')) { /* not uppercase hex */
WARNING(fsg,
- "Invalid serial string character: %c; "
- "Failing back to default\n",
+ "Invalid serial string character: %c\n",
*ch);
- goto fill_serial;
+ goto no_serial;
}
}
if (len > 126 ||
(mod_data.transport_type == USB_PR_BULK && len < 12) ||
(mod_data.transport_type != USB_PR_BULK && len > 12)) {
- WARNING(fsg,
- "Invalid serial string length; "
- "Failing back to default\n");
- goto fill_serial;
+ WARNING(fsg, "Invalid serial string length!\n");
+ goto no_serial;
}
fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial;
} else {
- WARNING(fsg,
- "Userspace failed to provide serial number; "
- "Failing back to default\n");
-fill_serial:
- /* Serial number not specified or invalid, make our own.
- * We just encode it from the driver version string,
- * 12 characters to comply with both CB[I] and BBB spec.
- * Warning : Two devices running the same kernel will have
- * the same fallback serial number. */
- for (i = 0; i < 12; i += 2) {
- unsigned char c = DRIVER_VERSION[i / 2];
-
- if (!c)
- break;
- sprintf(&fsg_string_serial[i], "%02X", c);
- }
+ WARNING(fsg, "No serial-number string provided!\n");
+ no_serial:
+ device_desc.iSerialNumber = 0;
}
return 0;
}
-static int __ref fsg_bind(struct usb_gadget *gadget)
+static int __init fsg_bind(struct usb_gadget *gadget)
{
struct fsg_dev *fsg = the_fsg;
int rc;
@@ -3607,7 +3588,6 @@ static struct usb_gadget_driver fsg_driver = {
.speed = USB_SPEED_FULL,
#endif
.function = (char *) fsg_string_product,
- .bind = fsg_bind,
.unbind = fsg_unbind,
.disconnect = fsg_disconnect,
.setup = fsg_setup,
@@ -3649,7 +3629,7 @@ static int __init fsg_init(void)
if ((rc = fsg_alloc()) != 0)
return rc;
fsg = the_fsg;
- if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
+ if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0)
kref_put(&fsg->ref, fsg_release);
return rc;
}
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index a5ea2c1d8c93..792d5ef40137 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -2302,9 +2302,10 @@ static irqreturn_t qe_udc_irq(int irq, void *_udc)
}
/*-------------------------------------------------------------------------
- Gadget driver register and unregister.
+ Gadget driver probe and unregister.
--------------------------------------------------------------------------*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
int retval;
unsigned long flags = 0;
@@ -2315,8 +2316,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver || (driver->speed != USB_SPEED_FULL
&& driver->speed != USB_SPEED_HIGH)
- || !driver->bind || !driver->disconnect
- || !driver->setup)
+ || !bind || !driver->disconnect || !driver->setup)
return -EINVAL;
if (udc_controller->driver)
@@ -2332,7 +2332,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
spin_unlock_irqrestore(&udc_controller->lock, flags);
- retval = driver->bind(&udc_controller->gadget);
+ retval = bind(&udc_controller->gadget);
if (retval) {
dev_err(udc_controller->dev, "bind to %s --> %d",
driver->driver.name, retval);
@@ -2353,7 +2353,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
udc_controller->gadget.name, driver->driver.name);
return 0;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 08a9a62a39e3..4c55eda4bd20 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -287,8 +287,6 @@ static void dr_controller_run(struct fsl_udc *udc)
temp = fsl_readl(&dr_regs->usbcmd);
temp |= USB_CMD_RUN_STOP;
fsl_writel(temp, &dr_regs->usbcmd);
-
- return;
}
static void dr_controller_stop(struct fsl_udc *udc)
@@ -308,8 +306,6 @@ static void dr_controller_stop(struct fsl_udc *udc)
tmp = fsl_readl(&dr_regs->usbcmd);
tmp &= ~USB_CMD_RUN_STOP;
fsl_writel(tmp, &dr_regs->usbcmd);
-
- return;
}
static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
@@ -416,8 +412,6 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
p_QH->max_pkt_length = cpu_to_le32(tmp);
p_QH->next_dtd_ptr = 1;
p_QH->size_ioc_int_sts = 0;
-
- return;
}
/* Setup qh structure and ep register for ep0. */
@@ -1765,7 +1759,8 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
* Hook to gadget drivers
* Called by initialization code of gadget drivers
*----------------------------------------------------------------*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
int retval = -ENODEV;
unsigned long flags = 0;
@@ -1775,8 +1770,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver || (driver->speed != USB_SPEED_FULL
&& driver->speed != USB_SPEED_HIGH)
- || !driver->bind || !driver->disconnect
- || !driver->setup)
+ || !bind || !driver->disconnect || !driver->setup)
return -EINVAL;
if (udc_controller->driver)
@@ -1792,7 +1786,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&udc_controller->lock, flags);
/* bind udc driver to gadget driver */
- retval = driver->bind(&udc_controller->gadget);
+ retval = bind(&udc_controller->gadget);
if (retval) {
VDBG("bind to %s --> %d", driver->driver.name, retval);
udc_controller->gadget.dev.driver = NULL;
@@ -1814,7 +1808,7 @@ out:
retval);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/* Disconnect from gadget driver */
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index a9474f8d5325..af75e3620849 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -52,9 +52,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Michal Nazarewicz");
MODULE_LICENSE("GPL");
-
-static unsigned short gfs_vendor_id = 0x0525; /* XXX NetChip */
-static unsigned short gfs_product_id = 0xa4ac; /* XXX */
+#define GFS_VENDOR_ID 0x1d6b /* Linux Foundation */
+#define GFS_PRODUCT_ID 0x0105 /* FunctionFS Gadget */
static struct usb_device_descriptor gfs_dev_desc = {
.bLength = sizeof gfs_dev_desc,
@@ -63,29 +62,16 @@ static struct usb_device_descriptor gfs_dev_desc = {
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
- /* Vendor and product id can be overridden by module parameters. */
- /* .idVendor = cpu_to_le16(gfs_vendor_id), */
- /* .idProduct = cpu_to_le16(gfs_product_id), */
- /* .bcdDevice = f(hardware) */
- /* .iManufacturer = DYNAMIC */
- /* .iProduct = DYNAMIC */
- /* NO SERIAL NUMBER */
- .bNumConfigurations = 1,
+ .idVendor = cpu_to_le16(GFS_VENDOR_ID),
+ .idProduct = cpu_to_le16(GFS_PRODUCT_ID),
};
-#define GFS_MODULE_PARAM_DESC(name, field) \
- MODULE_PARM_DESC(name, "Value of the " #field " field of the device descriptor sent to the host. Takes effect only prior to the user-space driver registering to the FunctionFS.")
-
-module_param_named(usb_class, gfs_dev_desc.bDeviceClass, byte, 0644);
-GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass);
-module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte, 0644);
-GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass);
-module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte, 0644);
-GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol);
-module_param_named(usb_vendor, gfs_vendor_id, ushort, 0644);
-GFS_MODULE_PARAM_DESC(usb_vendor, idVendor);
-module_param_named(usb_product, gfs_product_id, ushort, 0644);
-GFS_MODULE_PARAM_DESC(usb_product, idProduct);
+module_param_named(bDeviceClass, gfs_dev_desc.bDeviceClass, byte, 0644);
+MODULE_PARM_DESC(bDeviceClass, "USB Device class");
+module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte, 0644);
+MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
+module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644);
+MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
@@ -95,8 +81,10 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
.bLength = sizeof(struct usb_otg_descriptor),
.bDescriptorType = USB_DT_OTG,
- /* REVISIT SRP-only hardware is possible, although
- * it would not be called "OTG" ... */
+ /*
+ * REVISIT SRP-only hardware is possible, although
+ * it would not be called "OTG" ...
+ */
.bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
},
@@ -105,19 +93,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
/* string IDs are assigned dynamically */
-enum {
- GFS_STRING_MANUFACTURER_IDX,
- GFS_STRING_PRODUCT_IDX,
- GFS_STRING_FIRST_CONFIG_IDX,
-};
-
-static char gfs_manufacturer[50];
-static const char gfs_driver_desc[] = DRIVER_DESC;
-static const char gfs_short_name[] = DRIVER_NAME;
-
static struct usb_string gfs_strings[] = {
- [GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer,
- [GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc,
#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
{ .s = "FunctionFS + RNDIS" },
#endif
@@ -168,11 +144,11 @@ static int gfs_unbind(struct usb_composite_dev *cdev);
static int gfs_do_config(struct usb_configuration *c);
static struct usb_composite_driver gfs_driver = {
- .name = gfs_short_name,
+ .name = DRIVER_NAME,
.dev = &gfs_dev_desc,
.strings = gfs_dev_strings,
- .bind = gfs_bind,
.unbind = gfs_unbind,
+ .iProduct = DRIVER_DESC,
};
@@ -210,7 +186,7 @@ static int functionfs_ready_callback(struct ffs_data *ffs)
return -EBUSY;
gfs_ffs_data = ffs;
- ret = usb_composite_register(&gfs_driver);
+ ret = usb_composite_probe(&gfs_driver, gfs_bind);
if (unlikely(ret < 0))
clear_bit(0, &gfs_registered);
return ret;
@@ -245,20 +221,10 @@ static int gfs_bind(struct usb_composite_dev *cdev)
if (unlikely(ret < 0))
goto error_quick;
- gfs_dev_desc.idVendor = cpu_to_le16(gfs_vendor_id);
- gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id);
-
- snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
- init_utsname()->sysname, init_utsname()->release,
- cdev->gadget->name);
-
ret = usb_string_ids_tab(cdev, gfs_strings);
if (unlikely(ret < 0))
goto error;
- gfs_dev_desc.iManufacturer = gfs_strings[GFS_STRING_MANUFACTURER_IDX].id;
- gfs_dev_desc.iProduct = gfs_strings[GFS_STRING_PRODUCT_IDX].id;
-
ret = functionfs_bind(gfs_ffs_data, cdev);
if (unlikely(ret < 0))
goto error;
@@ -266,14 +232,12 @@ static int gfs_bind(struct usb_composite_dev *cdev)
for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
struct gfs_configuration *c = gfs_configurations + i;
- ret = GFS_STRING_FIRST_CONFIG_IDX + i;
- c->c.label = gfs_strings[ret].s;
- c->c.iConfiguration = gfs_strings[ret].id;
- c->c.bind = gfs_do_config;
+ c->c.label = gfs_strings[i].s;
+ c->c.iConfiguration = gfs_strings[i].id;
c->c.bConfigurationValue = 1 + i;
c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;
- ret = usb_add_config(cdev, &c->c);
+ ret = usb_add_config(cdev, &c->c, gfs_do_config);
if (unlikely(ret < 0))
goto error_unbind;
}
@@ -293,13 +257,14 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
{
ENTER();
- /* We may have been called in an error recovery frem
+ /*
+ * We may have been called in an error recovery from
* composite_bind() after gfs_unbind() failure so we need to
* check if gfs_ffs_data is not NULL since gfs_bind() handles
* all error recovery itself. I'd rather we werent called
* from composite on orror recovery, but what you're gonna
- * do...? */
-
+ * do...?
+ */
if (gfs_ffs_data) {
gether_cleanup();
functionfs_unbind(gfs_ffs_data);
@@ -334,14 +299,16 @@ static int gfs_do_config(struct usb_configuration *c)
if (unlikely(ret < 0))
return ret;
- /* After previous do_configs there may be some invalid
+ /*
+ * After previous do_configs there may be some invalid
* pointers in c->interface array. This happens every time
* a user space function with fewer interfaces than a user
* space function that was run before the new one is run. The
* compasit's set_config() assumes that if there is no more
* then MAX_CONFIG_INTERFACES interfaces in a configuration
* then there is a NULL pointer after the last interface in
- * c->interface array. We need to make sure this is true. */
+ * c->interface array. We need to make sure this is true.
+ */
if (c->next_interface_id < ARRAY_SIZE(c->interface))
c->interface[c->next_interface_id] = NULL;
@@ -350,10 +317,12 @@ static int gfs_do_config(struct usb_configuration *c)
#ifdef CONFIG_USB_FUNCTIONFS_ETH
+
static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
{
return can_support_ecm(c->cdev->gadget)
? ecm_bind_config(c, ethaddr)
: geth_bind_config(c, ethaddr);
}
+
#endif
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 1b413a5cc3f6..0ab7e141d494 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -1157,7 +1157,7 @@ fail:
/*
* Creates an output endpoint, and initializes output ports.
*/
-static int __ref gmidi_bind(struct usb_gadget *gadget)
+static int __init gmidi_bind(struct usb_gadget *gadget)
{
struct gmidi_device *dev;
struct usb_ep *in_ep, *out_ep;
@@ -1292,7 +1292,6 @@ static void gmidi_resume(struct usb_gadget *gadget)
static struct usb_gadget_driver gmidi_driver = {
.speed = USB_SPEED_FULL,
.function = (char *)longname,
- .bind = gmidi_bind,
.unbind = gmidi_unbind,
.setup = gmidi_setup,
@@ -1309,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = {
static int __init gmidi_init(void)
{
- return usb_gadget_register_driver(&gmidi_driver);
+ return usb_gadget_probe_driver(&gmidi_driver, gmidi_bind);
}
module_init(gmidi_init);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 1088d08c7ed8..49fbd4dbeb94 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1343,14 +1343,15 @@ static struct goku_udc *the_controller;
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct goku_udc *dev = the_controller;
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -1363,7 +1364,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
driver->driver.bus = NULL;
dev->driver = driver;
dev->gadget.dev.driver = &driver->driver;
- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
DBG(dev, "bind to driver %s --> error %d\n",
driver->driver.name, retval);
@@ -1380,7 +1381,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
return 0;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 735495bf8411..2523e54097bd 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -127,7 +127,7 @@ static struct usb_gadget_strings *dev_strings[] = {
/****************************** Configurations ******************************/
-static int __ref do_config(struct usb_configuration *c)
+static int __init do_config(struct usb_configuration *c)
{
struct hidg_func_node *e;
int func = 0, status = 0;
@@ -148,7 +148,6 @@ static int __ref do_config(struct usb_configuration *c)
static struct usb_configuration config_driver = {
.label = "HID Gadget",
- .bind = do_config,
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -156,7 +155,7 @@ static struct usb_configuration config_driver = {
/****************************** Gadget Bind ******************************/
-static int __ref hid_bind(struct usb_composite_dev *cdev)
+static int __init hid_bind(struct usb_composite_dev *cdev)
{
struct usb_gadget *gadget = cdev->gadget;
struct list_head *tmp;
@@ -201,7 +200,7 @@ static int __ref hid_bind(struct usb_composite_dev *cdev)
device_desc.iProduct = status;
/* register our configuration */
- status = usb_add_config(cdev, &config_driver);
+ status = usb_add_config(cdev, &config_driver, do_config);
if (status < 0)
return status;
@@ -256,7 +255,6 @@ static struct usb_composite_driver hidg_driver = {
.name = "g_hid",
.dev = &device_desc,
.strings = dev_strings,
- .bind = hid_bind,
.unbind = __exit_p(hid_unbind),
};
@@ -282,7 +280,7 @@ static int __init hidg_init(void)
if (status < 0)
return status;
- status = usb_composite_register(&hidg_driver);
+ status = usb_composite_probe(&hidg_driver, hid_bind);
if (status < 0)
platform_driver_unregister(&hidg_plat_driver);
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index e743122fcd93..ed0266462c57 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1319,14 +1319,15 @@ static struct imx_udc_struct controller = {
* USB gadged driver functions
*******************************************************************************
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct imx_udc_struct *imx_usb = &controller;
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -1342,7 +1343,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
retval = device_add(&imx_usb->gadget.dev);
if (retval)
goto fail;
- retval = driver->bind(&imx_usb->gadget);
+ retval = bind(&imx_usb->gadget);
if (retval) {
D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n",
__func__, driver->driver.name, retval);
@@ -1362,7 +1363,7 @@ fail:
imx_usb->gadget.dev.driver = NULL;
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index fc35406fc80c..cea33cc73454 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1775,7 +1775,6 @@ static struct usb_gadget_driver gadgetfs_driver = {
.speed = USB_SPEED_FULL,
#endif
.function = (char *) driver_desc,
- .bind = gadgetfs_bind,
.unbind = gadgetfs_unbind,
.setup = gadgetfs_setup,
.disconnect = gadgetfs_disconnect,
@@ -1798,7 +1797,6 @@ static int gadgetfs_probe (struct usb_gadget *gadget)
static struct usb_gadget_driver probe_driver = {
.speed = USB_SPEED_HIGH,
- .bind = gadgetfs_probe,
.unbind = gadgetfs_nop,
.setup = (void *)gadgetfs_nop,
.disconnect = gadgetfs_nop,
@@ -1908,7 +1906,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* triggers gadgetfs_bind(); then we can enumerate. */
spin_unlock_irq (&dev->lock);
- value = usb_gadget_register_driver (&gadgetfs_driver);
+ value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind);
if (value != 0) {
kfree (dev->buf);
dev->buf = NULL;
@@ -2043,13 +2041,19 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
struct dentry *d;
struct dev_data *dev;
- if (the_device)
+ lock_kernel();
+
+ if (the_device) {
+ unlock_kernel();
return -ESRCH;
+ }
/* fake probe to determine $CHIP */
- (void) usb_gadget_register_driver (&probe_driver);
- if (!CHIP)
+ (void) usb_gadget_probe_driver(&probe_driver, gadgetfs_probe);
+ if (!CHIP) {
+ unlock_kernel();
return -ENODEV;
+ }
/* superblock */
sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -2086,6 +2090,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
* from binding to a controller.
*/
the_device = dev;
+ unlock_kernel();
return 0;
enomem3:
@@ -2095,6 +2100,7 @@ enomem2:
enomem1:
iput (inode);
enomem0:
+ unlock_kernel();
return -ENOMEM;
}
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index c2d2a201f84b..d297f9eb92e4 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -19,7 +19,7 @@
/* #undef DEBUG */
-/* #undef VERBOSE */
+/* #undef VERBOSE_DEBUG */
#if defined(CONFIG_USB_LANGWELL_OTG)
#define OTG_TRANSCEIVER
@@ -77,141 +77,110 @@ langwell_ep0_desc = {
/*-------------------------------------------------------------------------*/
/* debugging */
-#ifdef DEBUG
-#define DBG(dev, fmt, args...) \
- pr_debug("%s %s: " fmt , driver_name, \
- pci_name(dev->pdev), ## args)
-#else
-#define DBG(dev, fmt, args...) \
- do { } while (0)
-#endif /* DEBUG */
-
-
-#ifdef VERBOSE
-#define VDBG DBG
-#else
-#define VDBG(dev, fmt, args...) \
- do { } while (0)
-#endif /* VERBOSE */
-
-
-#define ERROR(dev, fmt, args...) \
- pr_err("%s %s: " fmt , driver_name, \
- pci_name(dev->pdev), ## args)
-
-#define WARNING(dev, fmt, args...) \
- pr_warning("%s %s: " fmt , driver_name, \
- pci_name(dev->pdev), ## args)
-
-#define INFO(dev, fmt, args...) \
- pr_info("%s %s: " fmt , driver_name, \
- pci_name(dev->pdev), ## args)
-
-
-#ifdef VERBOSE
+#ifdef VERBOSE_DEBUG
static inline void print_all_registers(struct langwell_udc *dev)
{
int i;
/* Capability Registers */
- printk(KERN_DEBUG "Capability Registers (offset: "
- "0x%04x, length: 0x%08x)\n",
- CAP_REG_OFFSET,
- (u32)sizeof(struct langwell_cap_regs));
- printk(KERN_DEBUG "caplength=0x%02x\n",
+ dev_dbg(&dev->pdev->dev,
+ "Capability Registers (offset: 0x%04x, length: 0x%08x)\n",
+ CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs));
+ dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n",
readb(&dev->cap_regs->caplength));
- printk(KERN_DEBUG "hciversion=0x%04x\n",
+ dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n",
readw(&dev->cap_regs->hciversion));
- printk(KERN_DEBUG "hcsparams=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n",
readl(&dev->cap_regs->hcsparams));
- printk(KERN_DEBUG "hccparams=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n",
readl(&dev->cap_regs->hccparams));
- printk(KERN_DEBUG "dciversion=0x%04x\n",
+ dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n",
readw(&dev->cap_regs->dciversion));
- printk(KERN_DEBUG "dccparams=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n",
readl(&dev->cap_regs->dccparams));
/* Operational Registers */
- printk(KERN_DEBUG "Operational Registers (offset: "
- "0x%04x, length: 0x%08x)\n",
- OP_REG_OFFSET,
- (u32)sizeof(struct langwell_op_regs));
- printk(KERN_DEBUG "extsts=0x%08x\n",
+ dev_dbg(&dev->pdev->dev,
+ "Operational Registers (offset: 0x%04x, length: 0x%08x)\n",
+ OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs));
+ dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n",
readl(&dev->op_regs->extsts));
- printk(KERN_DEBUG "extintr=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n",
readl(&dev->op_regs->extintr));
- printk(KERN_DEBUG "usbcmd=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n",
readl(&dev->op_regs->usbcmd));
- printk(KERN_DEBUG "usbsts=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n",
readl(&dev->op_regs->usbsts));
- printk(KERN_DEBUG "usbintr=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n",
readl(&dev->op_regs->usbintr));
- printk(KERN_DEBUG "frindex=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n",
readl(&dev->op_regs->frindex));
- printk(KERN_DEBUG "ctrldssegment=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n",
readl(&dev->op_regs->ctrldssegment));
- printk(KERN_DEBUG "deviceaddr=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n",
readl(&dev->op_regs->deviceaddr));
- printk(KERN_DEBUG "endpointlistaddr=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n",
readl(&dev->op_regs->endpointlistaddr));
- printk(KERN_DEBUG "ttctrl=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n",
readl(&dev->op_regs->ttctrl));
- printk(KERN_DEBUG "burstsize=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n",
readl(&dev->op_regs->burstsize));
- printk(KERN_DEBUG "txfilltuning=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n",
readl(&dev->op_regs->txfilltuning));
- printk(KERN_DEBUG "txttfilltuning=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n",
readl(&dev->op_regs->txttfilltuning));
- printk(KERN_DEBUG "ic_usb=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n",
readl(&dev->op_regs->ic_usb));
- printk(KERN_DEBUG "ulpi_viewport=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n",
readl(&dev->op_regs->ulpi_viewport));
- printk(KERN_DEBUG "configflag=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n",
readl(&dev->op_regs->configflag));
- printk(KERN_DEBUG "portsc1=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n",
readl(&dev->op_regs->portsc1));
- printk(KERN_DEBUG "devlc=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n",
readl(&dev->op_regs->devlc));
- printk(KERN_DEBUG "otgsc=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n",
readl(&dev->op_regs->otgsc));
- printk(KERN_DEBUG "usbmode=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n",
readl(&dev->op_regs->usbmode));
- printk(KERN_DEBUG "endptnak=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n",
readl(&dev->op_regs->endptnak));
- printk(KERN_DEBUG "endptnaken=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n",
readl(&dev->op_regs->endptnaken));
- printk(KERN_DEBUG "endptsetupstat=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n",
readl(&dev->op_regs->endptsetupstat));
- printk(KERN_DEBUG "endptprime=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n",
readl(&dev->op_regs->endptprime));
- printk(KERN_DEBUG "endptflush=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n",
readl(&dev->op_regs->endptflush));
- printk(KERN_DEBUG "endptstat=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n",
readl(&dev->op_regs->endptstat));
- printk(KERN_DEBUG "endptcomplete=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n",
readl(&dev->op_regs->endptcomplete));
for (i = 0; i < dev->ep_max / 2; i++) {
- printk(KERN_DEBUG "endptctrl[%d]=0x%08x\n",
+ dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n",
i, readl(&dev->op_regs->endptctrl[i]));
}
}
-#endif /* VERBOSE */
+#else
+
+#define print_all_registers(dev) do { } while (0)
+
+#endif /* VERBOSE_DEBUG */
/*-------------------------------------------------------------------------*/
-#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
+#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
+ USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
-#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
- USB_DIR_IN) : ((ep)->desc->bEndpointAddress \
- & USB_DIR_IN) == USB_DIR_IN)
+#define DIR_STRING(ep) (is_in(ep) ? "in" : "out")
-#ifdef DEBUG
-static char *type_string(u8 bmAttributes)
+static char *type_string(const struct usb_endpoint_descriptor *desc)
{
- switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(desc)) {
case USB_ENDPOINT_XFER_BULK:
return "bulk";
case USB_ENDPOINT_XFER_ISOC:
@@ -222,7 +191,6 @@ static char *type_string(u8 bmAttributes)
return "control";
}
-#endif
/* configure endpoint control registers */
@@ -233,7 +201,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num,
u32 endptctrl;
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
if (is_in) { /* TX */
@@ -250,7 +218,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num,
writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -260,7 +228,7 @@ static void ep0_reset(struct langwell_udc *dev)
struct langwell_ep *ep;
int i;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* ep0 in and out */
for (i = 0; i < 2; i++) {
@@ -274,17 +242,18 @@ static void ep0_reset(struct langwell_udc *dev)
ep->dqh->dqh_ios = 1;
ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE;
- /* FIXME: enable ep0-in HW zero length termination select */
+ /* enable ep0-in HW zero length termination select */
if (is_in(ep))
ep->dqh->dqh_zlt = 0;
ep->dqh->dqh_mult = 0;
+ ep->dqh->dtd_next = DTD_TERM;
+
/* configure ep0 control registers */
ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
}
- VDBG(dev, "<--- %s()\n", __func__);
- return;
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -300,12 +269,12 @@ static int langwell_ep_enable(struct usb_ep *_ep,
struct langwell_ep *ep;
u16 max = 0;
unsigned long flags;
- int retval = 0;
+ int i, retval = 0;
unsigned char zlt, ios = 0, mult = 0;
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !desc || ep->desc
|| desc->bDescriptorType != USB_DT_ENDPOINT)
@@ -326,7 +295,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
* sanity check type, direction, address, and then
* initialize the endpoint capabilities fields in dQH
*/
- switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(desc)) {
case USB_ENDPOINT_XFER_CONTROL:
ios = 1;
break;
@@ -386,33 +355,36 @@ static int langwell_ep_enable(struct usb_ep *_ep,
spin_lock_irqsave(&dev->lock, flags);
- /* configure endpoint capabilities in dQH */
- ep->dqh->dqh_ios = ios;
- ep->dqh->dqh_mpl = cpu_to_le16(max);
- ep->dqh->dqh_zlt = zlt;
- ep->dqh->dqh_mult = mult;
-
ep->ep.maxpacket = max;
ep->desc = desc;
ep->stopped = 0;
- ep->ep_num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ ep->ep_num = usb_endpoint_num(desc);
/* ep_type */
- ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ ep->ep_type = usb_endpoint_type(desc);
/* configure endpoint control registers */
ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
- DBG(dev, "enabled %s (ep%d%s-%s), max %04x\n",
+ /* configure endpoint capabilities in dQH */
+ i = ep->ep_num * 2 + is_in(ep);
+ ep->dqh = &dev->ep_dqh[i];
+ ep->dqh->dqh_ios = ios;
+ ep->dqh->dqh_mpl = cpu_to_le16(max);
+ ep->dqh->dqh_zlt = zlt;
+ ep->dqh->dqh_mult = mult;
+ ep->dqh->dtd_next = DTD_TERM;
+
+ dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n",
_ep->name,
ep->ep_num,
- DIR_STRING(desc->bEndpointAddress),
- type_string(desc->bmAttributes),
+ DIR_STRING(ep),
+ type_string(desc),
max);
spin_unlock_irqrestore(&dev->lock, flags);
done:
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
@@ -428,7 +400,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
struct langwell_dtd *curr_dtd, *next_dtd;
int i;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* remove the req from ep->queue */
list_del_init(&req->queue);
@@ -448,7 +420,8 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
}
if (req->mapped) {
- dma_unmap_single(&dev->pdev->dev, req->req.dma, req->req.length,
+ dma_unmap_single(&dev->pdev->dev,
+ req->req.dma, req->req.length,
is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
req->req.dma = DMA_ADDR_INVALID;
req->mapped = 0;
@@ -458,9 +431,10 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (status != -ESHUTDOWN)
- DBG(dev, "complete %s, req %p, stat %d, len %u/%u\n",
- ep->ep.name, &req->req, status,
- req->req.actual, req->req.length);
+ dev_dbg(&dev->pdev->dev,
+ "complete %s, req %p, stat %d, len %u/%u\n",
+ ep->ep.name, &req->req, status,
+ req->req.actual, req->req.length);
/* don't modify queue heads during completion callback */
ep->stopped = 1;
@@ -473,7 +447,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
spin_lock(&dev->lock);
ep->stopped = stopped;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -511,7 +485,7 @@ static int langwell_ep_disable(struct usb_ep *_ep)
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !ep->desc)
return -EINVAL;
@@ -535,8 +509,8 @@ static int langwell_ep_disable(struct usb_ep *_ep)
spin_unlock_irqrestore(&dev->lock, flags);
- DBG(dev, "disabled %s\n", _ep->name);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -555,7 +529,7 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep,
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
req = kzalloc(sizeof(*req), gfp_flags);
if (!req)
@@ -564,8 +538,8 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep,
req->req.dma = DMA_ADDR_INVALID;
INIT_LIST_HEAD(&req->queue);
- VDBG(dev, "alloc request for %s\n", _ep->name);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return &req->req;
}
@@ -580,7 +554,7 @@ static void langwell_free_request(struct usb_ep *_ep,
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !_req)
return;
@@ -591,8 +565,8 @@ static void langwell_free_request(struct usb_ep *_ep,
if (_req)
kfree(req);
- VDBG(dev, "free request for %s\n", _ep->name);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -608,23 +582,24 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
struct langwell_udc *dev;
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
i = ep->ep_num * 2 + is_in(ep);
dqh = &dev->ep_dqh[i];
if (ep->ep_num)
- VDBG(dev, "%s\n", ep->name);
+ dev_vdbg(&dev->pdev->dev, "%s\n", ep->name);
else
/* ep0 */
- VDBG(dev, "%s-%s\n", ep->name, is_in(ep) ? "in" : "out");
+ dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep));
- VDBG(dev, "ep_dqh[%d] addr: 0x%08x\n", i, (u32)&(dev->ep_dqh[i]));
+ dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%08x\n",
+ i, (u32)&(dev->ep_dqh[i]));
bit_mask = is_in(ep) ?
(1 << (ep->ep_num + 16)) : (1 << (ep->ep_num));
- VDBG(dev, "bit_mask = 0x%08x\n", bit_mask);
+ dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask);
/* check if the pipe is empty */
if (!(list_empty(&ep->queue))) {
@@ -665,14 +640,17 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
/* clear active and halt bit */
dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED);
dqh->dtd_status &= dtd_status;
- VDBG(dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
+ dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
+
+ /* ensure that updates to the dQH will occure before priming */
+ wmb();
/* write 1 to endptprime register to PRIME endpoint */
bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num);
- VDBG(dev, "endprime bit_mask = 0x%08x\n", bit_mask);
+ dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask);
writel(bit_mask, &dev->op_regs->endptprime);
out:
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -687,7 +665,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
int i;
dev = req->ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* the maximum transfer length, up to 16k bytes */
*length = min(req->req.length - req->req.actual,
@@ -708,7 +686,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
/* fill in total bytes with transfer size */
dtd->dtd_total = cpu_to_le16(*length);
- VDBG(dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
+ dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
/* set is_last flag if req->req.zero is set or not */
if (req->req.zero) {
@@ -722,7 +700,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
*is_last = 0;
if (*is_last == 0)
- VDBG(dev, "multi-dtd request!\n");
+ dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n");
/* set interrupt on complete bit for the last dTD */
if (*is_last && !req->req.no_interrupt)
@@ -733,10 +711,12 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
/* set the active bit of status field to 1 */
dtd->dtd_status = DTD_STS_ACTIVE;
- VDBG(dev, "dtd->dtd_status = 0x%02x\n", dtd->dtd_status);
+ dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n",
+ dtd->dtd_status);
- VDBG(dev, "length = %d, dma addr= 0x%08x\n", *length, (int)*dma);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n",
+ *length, (int)*dma);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return dtd;
}
@@ -751,7 +731,7 @@ static int req_to_dtd(struct langwell_request *req)
dma_addr_t dma;
dev = req->ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
do {
dtd = build_dtd(req, &count, &dma, &is_last);
if (dtd == NULL)
@@ -773,7 +753,7 @@ static int req_to_dtd(struct langwell_request *req)
req->tail = dtd;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -803,9 +783,9 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
dev = ep->dev;
req->ep = ep;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
- if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+ if (usb_endpoint_xfer_isoc(ep->desc)) {
if (req->req.length > ep->ep.maxpacket)
return -EMSGSIZE;
is_iso = 1;
@@ -818,7 +798,7 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
if (_req->dma == DMA_ADDR_INVALID) {
/* WORKAROUND: WARN_ON(size == 0) */
if (_req->length == 0) {
- VDBG(dev, "req->length: 0->1\n");
+ dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n");
zlflag = 1;
_req->length++;
}
@@ -827,24 +807,25 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
_req->buf, _req->length,
is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (zlflag && (_req->length == 1)) {
- VDBG(dev, "req->length: 1->0\n");
+ dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n");
zlflag = 0;
_req->length = 0;
}
req->mapped = 1;
- VDBG(dev, "req->mapped = 1\n");
+ dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n");
} else {
dma_sync_single_for_device(&dev->pdev->dev,
_req->dma, _req->length,
is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = 0;
- VDBG(dev, "req->mapped = 0\n");
+ dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n");
}
- DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08llx\n",
- _ep->name,
- _req, _req->length, _req->buf, (unsigned long long)_req->dma);
+ dev_dbg(&dev->pdev->dev,
+ "%s queue req %p, len %u, buf %p, dma 0x%08x\n",
+ _ep->name,
+ _req, _req->length, _req->buf, (int)_req->dma);
_req->status = -EINPROGRESS;
_req->actual = 0;
@@ -866,12 +847,12 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
if (likely(req != NULL)) {
list_add_tail(&req->queue, &ep->queue);
- VDBG(dev, "list_add_tail() \n");
+ dev_vdbg(&dev->pdev->dev, "list_add_tail()\n");
}
spin_unlock_irqrestore(&dev->lock, flags);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -888,7 +869,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !ep->desc || !_req)
return -EINVAL;
@@ -924,7 +905,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
/* queue head may be partially complete. */
if (ep->queue.next == &req->queue) {
- DBG(dev, "unlink (%s) dma\n", _ep->name);
+ dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name);
_req->status = -ECONNRESET;
langwell_ep_fifo_flush(&ep->ep);
@@ -963,7 +944,7 @@ done:
ep->stopped = stopped;
spin_unlock_irqrestore(&dev->lock, flags);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
@@ -976,7 +957,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value)
u32 endptctrl = 0;
int ep_num;
struct langwell_udc *dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
ep_num = ep->ep_num;
endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
@@ -1001,7 +982,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value)
writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1016,7 +997,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !ep->desc)
return -EINVAL;
@@ -1024,8 +1005,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
return -ESHUTDOWN;
- if (ep->desc && (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_ISOC)
+ if (usb_endpoint_xfer_isoc(ep->desc))
return -EOPNOTSUPP;
spin_lock_irqsave(&dev->lock, flags);
@@ -1036,7 +1016,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
*/
if (!list_empty(&ep->queue) && is_in(ep) && value) {
/* IN endpoint FIFO holds bytes */
- DBG(dev, "%s FIFO holds bytes\n", _ep->name);
+ dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name);
retval = -EAGAIN;
goto done;
}
@@ -1050,8 +1030,9 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
}
done:
spin_unlock_irqrestore(&dev->lock, flags);
- DBG(dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "%s %s halt\n",
+ _ep->name, value ? "set" : "clear");
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
@@ -1065,12 +1046,12 @@ static int langwell_ep_set_wedge(struct usb_ep *_ep)
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !ep->desc)
return -EINVAL;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return usb_ep_set_halt(_ep);
}
@@ -1086,15 +1067,16 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
ep = container_of(_ep, struct langwell_ep, ep);
dev = ep->dev;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (!_ep || !ep->desc) {
- VDBG(dev, "ep or ep->desc is NULL\n");
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n");
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return;
}
- VDBG(dev, "%s-%s fifo flush\n", _ep->name, is_in(ep) ? "in" : "out");
+ dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n",
+ _ep->name, DIR_STRING(ep));
/* flush endpoint buffer */
if (ep->ep_num == 0)
@@ -1110,14 +1092,14 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
writel(flush_bit, &dev->op_regs->endptflush);
while (readl(&dev->op_regs->endptflush)) {
if (time_after(jiffies, timeout)) {
- ERROR(dev, "ep flush timeout\n");
+ dev_err(&dev->pdev->dev, "ep flush timeout\n");
goto done;
}
cpu_relax();
}
} while (readl(&dev->op_regs->endptstat) & flush_bit);
done:
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1167,31 +1149,59 @@ static int langwell_get_frame(struct usb_gadget *_gadget)
return -ENODEV;
dev = container_of(_gadget, struct langwell_udc, gadget);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
+/* enter or exit PHY low power state */
+static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
+{
+ u32 devlc;
+ u8 devlc_byte2;
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ devlc = readl(&dev->op_regs->devlc);
+ dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
+
+ if (flag)
+ devlc |= LPM_PHCD;
+ else
+ devlc &= ~LPM_PHCD;
+
+ /* FIXME: workaround for Langwell A1/A2/A3 sighting */
+ devlc_byte2 = (devlc >> 16) & 0xff;
+ writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
+
+ devlc = readl(&dev->op_regs->devlc);
+ dev_vdbg(&dev->pdev->dev,
+ "%s PHY low power suspend, devlc = 0x%08x\n",
+ flag ? "enter" : "exit", devlc);
+}
+
+
/* tries to wake up the host connected to this gadget */
static int langwell_wakeup(struct usb_gadget *_gadget)
{
struct langwell_udc *dev;
- u32 portsc1, devlc;
- unsigned long flags;
+ u32 portsc1;
+ unsigned long flags;
if (!_gadget)
return 0;
dev = container_of(_gadget, struct langwell_udc, gadget);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
- /* Remote Wakeup feature not enabled by host */
- if (!dev->remote_wakeup)
+ /* remote wakeup feature not enabled by host */
+ if (!dev->remote_wakeup) {
+ dev_info(&dev->pdev->dev, "remote wakeup is disabled\n");
return -ENOTSUPP;
+ }
spin_lock_irqsave(&dev->lock, flags);
@@ -1201,27 +1211,23 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
return 0;
}
- /* LPM L1 to L0, remote wakeup */
- if (dev->lpm && dev->lpm_state == LPM_L1) {
- portsc1 |= PORTS_SLP;
- writel(portsc1, &dev->op_regs->portsc1);
- }
-
- /* force port resume */
- if (dev->usb_state == USB_STATE_SUSPENDED) {
- portsc1 |= PORTS_FPR;
- writel(portsc1, &dev->op_regs->portsc1);
- }
+ /* LPM L1 to L0 or legacy remote wakeup */
+ if (dev->lpm && dev->lpm_state == LPM_L1)
+ dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
+ else
+ dev_info(&dev->pdev->dev, "device remote wakeup\n");
/* exit PHY low power suspend */
- devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "devlc = 0x%08x\n", devlc);
- devlc &= ~LPM_PHCD;
- writel(devlc, &dev->op_regs->devlc);
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 0);
+
+ /* force port resume */
+ portsc1 |= PORTS_FPR;
+ writel(portsc1, &dev->op_regs->portsc1);
spin_unlock_irqrestore(&dev->lock, flags);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -1231,16 +1237,17 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active)
{
struct langwell_udc *dev;
unsigned long flags;
- u32 usbcmd;
+ u32 usbcmd;
if (!_gadget)
return -ENODEV;
dev = container_of(_gadget, struct langwell_udc, gadget);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
spin_lock_irqsave(&dev->lock, flags);
- VDBG(dev, "VBUS status: %s\n", is_active ? "on" : "off");
+ dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n",
+ is_active ? "on" : "off");
dev->vbus_active = (is_active != 0);
if (dev->driver && dev->softconnected && dev->vbus_active) {
@@ -1255,7 +1262,7 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active)
spin_unlock_irqrestore(&dev->lock, flags);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -1269,15 +1276,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
return -ENODEV;
dev = container_of(_gadget, struct langwell_udc, gadget);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dev->transceiver) {
- VDBG(dev, "otg_set_power\n");
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "otg_set_power\n");
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return otg_set_power(dev->transceiver, mA);
}
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return -ENOTSUPP;
}
@@ -1286,15 +1293,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
{
struct langwell_udc *dev;
- u32 usbcmd;
- unsigned long flags;
+ u32 usbcmd;
+ unsigned long flags;
if (!_gadget)
return -ENODEV;
dev = container_of(_gadget, struct langwell_udc, gadget);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
spin_lock_irqsave(&dev->lock, flags);
dev->softconnected = (is_on != 0);
@@ -1310,7 +1317,7 @@ static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
}
spin_unlock_irqrestore(&dev->lock, flags);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -1346,12 +1353,13 @@ static const struct usb_gadget_ops langwell_ops = {
static int langwell_udc_reset(struct langwell_udc *dev)
{
u32 usbcmd, usbmode, devlc, endpointlistaddr;
+ u8 devlc_byte0, devlc_byte2;
unsigned long timeout;
if (!dev)
return -EINVAL;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* set controller to stop state */
usbcmd = readl(&dev->op_regs->usbcmd);
@@ -1367,7 +1375,7 @@ static int langwell_udc_reset(struct langwell_udc *dev)
timeout = jiffies + RESET_TIMEOUT;
while (readl(&dev->op_regs->usbcmd) & CMD_RST) {
if (time_after(jiffies, timeout)) {
- ERROR(dev, "device reset timeout\n");
+ dev_err(&dev->pdev->dev, "device reset timeout\n");
return -ETIMEDOUT;
}
cpu_relax();
@@ -1382,7 +1390,7 @@ static int langwell_udc_reset(struct langwell_udc *dev)
writel(usbmode, &dev->op_regs->usbmode);
usbmode = readl(&dev->op_regs->usbmode);
- VDBG(dev, "usbmode=0x%08x\n", usbmode);
+ dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode);
/* Write-Clear setup status */
writel(0, &dev->op_regs->usbsts);
@@ -1390,9 +1398,17 @@ static int langwell_udc_reset(struct langwell_udc *dev)
/* if support USB LPM, ACK all LPM token */
if (dev->lpm) {
devlc = readl(&dev->op_regs->devlc);
+ dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
+ /* FIXME: workaround for Langwell A1/A2/A3 sighting */
devlc &= ~LPM_STL; /* don't STALL LPM token */
devlc &= ~LPM_NYT_ACK; /* ACK LPM token */
- writel(devlc, &dev->op_regs->devlc);
+ devlc_byte0 = devlc & 0xff;
+ devlc_byte2 = (devlc >> 16) & 0xff;
+ writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
+ writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
+ devlc = readl(&dev->op_regs->devlc);
+ dev_vdbg(&dev->pdev->dev,
+ "ACK LPM token, devlc = 0x%08x\n", devlc);
}
/* fill endpointlistaddr register */
@@ -1400,10 +1416,11 @@ static int langwell_udc_reset(struct langwell_udc *dev)
endpointlistaddr &= ENDPOINTLISTADDR_MASK;
writel(endpointlistaddr, &dev->op_regs->endpointlistaddr);
- VDBG(dev, "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
- dev->ep_dqh, endpointlistaddr,
- readl(&dev->op_regs->endpointlistaddr));
- DBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev,
+ "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
+ dev->ep_dqh, endpointlistaddr,
+ readl(&dev->op_regs->endpointlistaddr));
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -1415,7 +1432,7 @@ static int eps_reinit(struct langwell_udc *dev)
char name[14];
int i;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* initialize ep0 */
ep = &dev->ep[0];
@@ -1449,11 +1466,9 @@ static int eps_reinit(struct langwell_udc *dev)
INIT_LIST_HEAD(&ep->queue);
list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
-
- ep->dqh = &dev->ep_dqh[i];
}
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -1462,7 +1477,7 @@ static int eps_reinit(struct langwell_udc *dev)
static void langwell_udc_start(struct langwell_udc *dev)
{
u32 usbintr, usbcmd;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* enable interrupts */
usbintr = INTR_ULPIE /* ULPI */
@@ -1485,8 +1500,7 @@ static void langwell_udc_start(struct langwell_udc *dev)
usbcmd |= CMD_RUNSTOP;
writel(usbcmd, &dev->op_regs->usbcmd);
- DBG(dev, "<--- %s()\n", __func__);
- return;
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1495,7 +1509,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
{
u32 usbcmd;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* disable all interrupts */
writel(0, &dev->op_regs->usbintr);
@@ -1508,8 +1522,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
usbcmd &= ~CMD_RUNSTOP;
writel(usbcmd, &dev->op_regs->usbcmd);
- DBG(dev, "<--- %s()\n", __func__);
- return;
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1518,7 +1531,7 @@ static void stop_activity(struct langwell_udc *dev,
struct usb_gadget_driver *driver)
{
struct langwell_ep *ep;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
nuke(&dev->ep[0], -ESHUTDOWN);
@@ -1533,7 +1546,7 @@ static void stop_activity(struct langwell_udc *dev,
spin_lock(&dev->lock);
}
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1659,13 +1672,15 @@ static ssize_t show_langwell_udc(struct device *_dev,
"Over-current Change: %s\n"
"Port Enable/Disable Change: %s\n"
"Port Enabled/Disabled: %s\n"
- "Current Connect Status: %s\n\n",
+ "Current Connect Status: %s\n"
+ "LPM Suspend Status: %s\n\n",
(tmp_reg & PORTS_PR) ? "Reset" : "Not Reset",
(tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend",
(tmp_reg & PORTS_OCC) ? "Detected" : "No",
(tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed",
(tmp_reg & PORTS_PE) ? "Enable" : "Not Correct",
- (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached");
+ (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached",
+ (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0");
size -= t;
next += t;
@@ -1676,7 +1691,7 @@ static ssize_t show_langwell_udc(struct device *_dev,
"Serial Transceiver : %d\n"
"Port Speed: %s\n"
"Port Force Full Speed Connenct: %s\n"
- "PHY Low Power Suspend Clock Disable: %s\n"
+ "PHY Low Power Suspend Clock: %s\n"
"BmAttributes: %d\n\n",
LPM_PTS(tmp_reg),
(tmp_reg & LPM_STS) ? 1 : 0,
@@ -1797,6 +1812,36 @@ static ssize_t show_langwell_udc(struct device *_dev,
static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
+/* device "remote_wakeup" sysfs attribute file */
+static ssize_t store_remote_wakeup(struct device *_dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct langwell_udc *dev = the_controller;
+ unsigned long flags;
+ ssize_t rc = count;
+
+ if (count > 2)
+ return -EINVAL;
+
+ if (count > 0 && buf[count-1] == '\n')
+ ((char *) buf)[count-1] = 0;
+
+ if (buf[0] != '1')
+ return -EINVAL;
+
+ /* force remote wakeup enabled in case gadget driver doesn't support */
+ spin_lock_irqsave(&dev->lock, flags);
+ dev->remote_wakeup = 1;
+ dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ langwell_wakeup(&dev->gadget);
+
+ return rc;
+}
+static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup);
+
+
/*-------------------------------------------------------------------------*/
/*
@@ -1807,7 +1852,8 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
* the driver might get unbound.
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct langwell_udc *dev = the_controller;
unsigned long flags;
@@ -1816,7 +1862,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dev->driver)
return -EBUSY;
@@ -1830,9 +1876,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&dev->lock, flags);
- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
- DBG(dev, "bind to driver %s --> %d\n",
+ dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n",
driver->driver.name, retval);
dev->driver = NULL;
dev->gadget.dev.driver = NULL;
@@ -1851,13 +1897,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (dev->got_irq)
langwell_udc_start(dev);
- VDBG(dev, "After langwell_udc_start(), print all registers:\n");
-#ifdef VERBOSE
+ dev_vdbg(&dev->pdev->dev,
+ "After langwell_udc_start(), print all registers:\n");
print_all_registers(dev);
-#endif
- INFO(dev, "register driver: %s\n", driver->driver.name);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_info(&dev->pdev->dev, "register driver: %s\n",
+ driver->driver.name);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
err_unbind:
@@ -1865,10 +1911,10 @@ err_unbind:
dev->gadget.dev.driver = NULL;
dev->driver = NULL;
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/* unregister gadget driver */
@@ -1880,11 +1926,15 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!dev)
return -ENODEV;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
- if (unlikely(!driver || !driver->bind || !driver->unbind))
+ if (unlikely(!driver || !driver->unbind))
return -EINVAL;
+ /* exit PHY low power suspend */
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 0);
+
/* unbind OTG transceiver */
if (dev->transceiver)
(void)otg_set_peripheral(dev->transceiver, 0);
@@ -1910,8 +1960,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
device_remove_file(&dev->pdev->dev, &dev_attr_function);
- INFO(dev, "unregistered driver '%s'\n", driver->driver.name);
- DBG(dev, "<--- %s()\n", __func__);
+ dev_info(&dev->pdev->dev, "unregistered driver '%s'\n",
+ driver->driver.name);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1930,7 +1981,7 @@ static void setup_tripwire(struct langwell_udc *dev)
unsigned long timeout;
struct langwell_dqh *dqh;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* ep0 OUT dQH */
dqh = &dev->ep_dqh[EP_DIR_OUT];
@@ -1943,7 +1994,7 @@ static void setup_tripwire(struct langwell_udc *dev)
timeout = jiffies + SETUPSTAT_TIMEOUT;
while (readl(&dev->op_regs->endptsetupstat)) {
if (time_after(jiffies, timeout)) {
- ERROR(dev, "setup_tripwire timeout\n");
+ dev_err(&dev->pdev->dev, "setup_tripwire timeout\n");
break;
}
cpu_relax();
@@ -1963,7 +2014,7 @@ static void setup_tripwire(struct langwell_udc *dev)
usbcmd = readl(&dev->op_regs->usbcmd);
writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1972,7 +2023,7 @@ static void ep0_stall(struct langwell_udc *dev)
{
u32 endptctrl;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* set TX and RX to stall */
endptctrl = readl(&dev->op_regs->endptctrl[0]);
@@ -1983,7 +2034,7 @@ static void ep0_stall(struct langwell_udc *dev)
dev->ep0_state = WAIT_FOR_SETUP;
dev->ep0_dir = USB_DIR_OUT;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -1994,7 +2045,7 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
struct langwell_ep *ep;
int status = 0;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dir == EP_DIR_IN)
dev->ep0_dir = USB_DIR_IN;
@@ -2019,11 +2070,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
return -ENOMEM;
if (status)
- ERROR(dev, "can't queue ep0 status request\n");
+ dev_err(&dev->pdev->dev, "can't queue ep0 status request\n");
list_add_tail(&req->queue, &ep->queue);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return status;
}
@@ -2032,11 +2083,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
static void set_address(struct langwell_udc *dev, u16 value,
u16 index, u16 length)
{
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* save the new address to device struct */
dev->dev_addr = (u8) value;
- VDBG(dev, "dev->dev_addr = %d\n", dev->dev_addr);
+ dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr);
/* update usb state */
dev->usb_state = USB_STATE_ADDRESS;
@@ -2045,7 +2096,7 @@ static void set_address(struct langwell_udc *dev, u16 value,
if (prime_status_phase(dev, EP_DIR_IN))
ep0_stall(dev);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2054,7 +2105,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
u16 wIndex)
{
struct langwell_ep *ep;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
return &dev->ep[0];
@@ -2073,7 +2124,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
return ep;
}
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return NULL;
}
@@ -2085,7 +2136,7 @@ static int ep_is_stall(struct langwell_ep *ep)
u32 endptctrl;
int retval;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]);
if (is_in(ep))
@@ -2093,7 +2144,7 @@ static int ep_is_stall(struct langwell_ep *ep)
else
retval = endptctrl & EPCTRL_RXS ? 1 : 0;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
@@ -2107,14 +2158,13 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
u16 status_data = 0; /* 16 bits cpu view status data */
int status = 0;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
ep = &dev->ep[0];
if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
/* get device status */
- status_data = 1 << USB_DEVICE_SELF_POWERED;
- status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+ status_data = dev->dev_status;
} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
/* get interface status */
status_data = 0;
@@ -2129,6 +2179,8 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT;
}
+ dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data);
+
dev->ep0_dir = USB_DIR_IN;
/* borrow the per device status_req */
@@ -2150,18 +2202,19 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
goto stall;
if (status) {
- ERROR(dev, "response error on GET_STATUS request\n");
+ dev_err(&dev->pdev->dev,
+ "response error on GET_STATUS request\n");
goto stall;
}
list_add_tail(&req->queue, &ep->queue);
dev->ep0_state = DATA_STATE_XMIT;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return;
stall:
ep0_stall(dev);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2173,12 +2226,12 @@ static void handle_setup_packet(struct langwell_udc *dev,
u16 wIndex = le16_to_cpu(setup->wIndex);
u16 wLength = le16_to_cpu(setup->wLength);
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* ep0 fifo flush */
nuke(&dev->ep[0], -ESHUTDOWN);
- DBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+ dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
setup->bRequestType, setup->bRequest,
wValue, wIndex, wLength);
@@ -2197,7 +2250,7 @@ static void handle_setup_packet(struct langwell_udc *dev,
/* We process some stardard setup requests here */
switch (setup->bRequest) {
case USB_REQ_GET_STATUS:
- DBG(dev, "SETUP: USB_REQ_GET_STATUS\n");
+ dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n");
/* get status, DATA and STATUS phase */
if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
!= (USB_DIR_IN | USB_TYPE_STANDARD))
@@ -2206,7 +2259,7 @@ static void handle_setup_packet(struct langwell_udc *dev,
goto end;
case USB_REQ_SET_ADDRESS:
- DBG(dev, "SETUP: USB_REQ_SET_ADDRESS\n");
+ dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n");
/* STATUS phase */
if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
| USB_RECIP_DEVICE))
@@ -2220,9 +2273,11 @@ static void handle_setup_packet(struct langwell_udc *dev,
{
int rc = -EOPNOTSUPP;
if (setup->bRequest == USB_REQ_SET_FEATURE)
- DBG(dev, "SETUP: USB_REQ_SET_FEATURE\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_SET_FEATURE\n");
else if (setup->bRequest == USB_REQ_CLEAR_FEATURE)
- DBG(dev, "SETUP: USB_REQ_CLEAR_FEATURE\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_CLEAR_FEATURE\n");
if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
== (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
@@ -2240,13 +2295,29 @@ static void handle_setup_packet(struct langwell_udc *dev,
spin_unlock(&dev->lock);
rc = langwell_ep_set_halt(&epn->ep,
- (setup->bRequest == USB_REQ_SET_FEATURE)
- ? 1 : 0);
+ (setup->bRequest == USB_REQ_SET_FEATURE)
+ ? 1 : 0);
spin_lock(&dev->lock);
} else if ((setup->bRequestType & (USB_RECIP_MASK
| USB_TYPE_MASK)) == (USB_RECIP_DEVICE
| USB_TYPE_STANDARD)) {
+ rc = 0;
+ switch (wValue) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+ if (setup->bRequest == USB_REQ_SET_FEATURE) {
+ dev->remote_wakeup = 1;
+ dev->dev_status |= (1 << wValue);
+ } else {
+ dev->remote_wakeup = 0;
+ dev->dev_status &= ~(1 << wValue);
+ }
+ break;
+ default:
+ rc = -EOPNOTSUPP;
+ break;
+ }
+
if (!gadget_is_otg(&dev->gadget))
break;
else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
@@ -2262,7 +2333,6 @@ static void handle_setup_packet(struct langwell_udc *dev,
dev->gadget.a_alt_hnp_support = 1;
else
break;
- rc = 0;
} else
break;
@@ -2274,31 +2344,38 @@ static void handle_setup_packet(struct langwell_udc *dev,
}
case USB_REQ_GET_DESCRIPTOR:
- DBG(dev, "SETUP: USB_REQ_GET_DESCRIPTOR\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_GET_DESCRIPTOR\n");
goto delegate;
case USB_REQ_SET_DESCRIPTOR:
- DBG(dev, "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
goto delegate;
case USB_REQ_GET_CONFIGURATION:
- DBG(dev, "SETUP: USB_REQ_GET_CONFIGURATION\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_GET_CONFIGURATION\n");
goto delegate;
case USB_REQ_SET_CONFIGURATION:
- DBG(dev, "SETUP: USB_REQ_SET_CONFIGURATION\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_SET_CONFIGURATION\n");
goto delegate;
case USB_REQ_GET_INTERFACE:
- DBG(dev, "SETUP: USB_REQ_GET_INTERFACE\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_GET_INTERFACE\n");
goto delegate;
case USB_REQ_SET_INTERFACE:
- DBG(dev, "SETUP: USB_REQ_SET_INTERFACE\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_SET_INTERFACE\n");
goto delegate;
case USB_REQ_SYNCH_FRAME:
- DBG(dev, "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
+ dev_dbg(&dev->pdev->dev,
+ "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
goto delegate;
default:
@@ -2310,7 +2387,8 @@ delegate:
/* DATA phase from gadget, STATUS phase from udc */
dev->ep0_dir = (setup->bRequestType & USB_DIR_IN)
? USB_DIR_IN : USB_DIR_OUT;
- VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
+ dev_vdbg(&dev->pdev->dev,
+ "dev->ep0_dir = 0x%x, wLength = %d\n",
dev->ep0_dir, wLength);
spin_unlock(&dev->lock);
if (dev->driver->setup(&dev->gadget,
@@ -2322,7 +2400,8 @@ delegate:
} else {
/* no DATA phase, IN STATUS phase from gadget */
dev->ep0_dir = USB_DIR_IN;
- VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
+ dev_vdbg(&dev->pdev->dev,
+ "dev->ep0_dir = 0x%x, wLength = %d\n",
dev->ep0_dir, wLength);
spin_unlock(&dev->lock);
if (dev->driver->setup(&dev->gadget,
@@ -2334,8 +2413,7 @@ delegate:
break;
}
end:
- VDBG(dev, "<--- %s()\n", __func__);
- return;
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2359,7 +2437,7 @@ static int process_ep_req(struct langwell_udc *dev, int index,
td_complete = 0;
actual = curr_req->req.length;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
for (i = 0; i < curr_req->dtd_count; i++) {
remaining_length = le16_to_cpu(curr_dtd->dtd_total);
@@ -2372,10 +2450,12 @@ static int process_ep_req(struct langwell_udc *dev, int index,
/* transfers completed successfully */
if (!remaining_length) {
td_complete++;
- VDBG(dev, "dTD transmitted successfully\n");
+ dev_vdbg(&dev->pdev->dev,
+ "dTD transmitted successfully\n");
} else {
if (dir) {
- VDBG(dev, "TX dTD remains data\n");
+ dev_vdbg(&dev->pdev->dev,
+ "TX dTD remains data\n");
retval = -EPROTO;
break;
@@ -2387,27 +2467,32 @@ static int process_ep_req(struct langwell_udc *dev, int index,
} else {
/* transfers completed with errors */
if (dtd_status & DTD_STS_ACTIVE) {
- DBG(dev, "request not completed\n");
+ dev_dbg(&dev->pdev->dev,
+ "dTD status ACTIVE dQH[%d]\n", index);
retval = 1;
return retval;
} else if (dtd_status & DTD_STS_HALTED) {
- ERROR(dev, "dTD error %08x dQH[%d]\n",
- dtd_status, index);
+ dev_err(&dev->pdev->dev,
+ "dTD error %08x dQH[%d]\n",
+ dtd_status, index);
/* clear the errors and halt condition */
curr_dqh->dtd_status = 0;
retval = -EPIPE;
break;
} else if (dtd_status & DTD_STS_DBE) {
- DBG(dev, "data buffer (overflow) error\n");
+ dev_dbg(&dev->pdev->dev,
+ "data buffer (overflow) error\n");
retval = -EPROTO;
break;
} else if (dtd_status & DTD_STS_TRE) {
- DBG(dev, "transaction(ISO) error\n");
+ dev_dbg(&dev->pdev->dev,
+ "transaction(ISO) error\n");
retval = -EILSEQ;
break;
} else
- ERROR(dev, "unknown error (0x%x)!\n",
- dtd_status);
+ dev_err(&dev->pdev->dev,
+ "unknown error (0x%x)!\n",
+ dtd_status);
}
if (i != curr_req->dtd_count - 1)
@@ -2420,7 +2505,7 @@ static int process_ep_req(struct langwell_udc *dev, int index,
curr_req->req.actual = actual;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -2430,7 +2515,7 @@ static void ep0_req_complete(struct langwell_udc *dev,
struct langwell_ep *ep0, struct langwell_request *req)
{
u32 new_addr;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dev->usb_state == USB_STATE_ADDRESS) {
/* set the new address */
@@ -2438,7 +2523,7 @@ static void ep0_req_complete(struct langwell_udc *dev,
writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr);
new_addr = USBADR(readl(&dev->op_regs->deviceaddr));
- VDBG(dev, "new_addr = %d\n", new_addr);
+ dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr);
}
done(ep0, req, 0);
@@ -2458,14 +2543,14 @@ static void ep0_req_complete(struct langwell_udc *dev,
dev->ep0_state = WAIT_FOR_SETUP;
break;
case WAIT_FOR_SETUP:
- ERROR(dev, "unexpect ep0 packets\n");
+ dev_err(&dev->pdev->dev, "unexpect ep0 packets\n");
break;
default:
ep0_stall(dev);
break;
}
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2477,16 +2562,17 @@ static void handle_trans_complete(struct langwell_udc *dev)
struct langwell_ep *epn;
struct langwell_request *curr_req, *temp_req;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
complete_bits = readl(&dev->op_regs->endptcomplete);
- VDBG(dev, "endptcomplete register: 0x%08x\n", complete_bits);
+ dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n",
+ complete_bits);
/* Write-Clear the bits in endptcomplete register */
writel(complete_bits, &dev->op_regs->endptcomplete);
if (!complete_bits) {
- DBG(dev, "complete_bits = 0\n");
+ dev_dbg(&dev->pdev->dev, "complete_bits = 0\n");
goto done;
}
@@ -2506,23 +2592,25 @@ static void handle_trans_complete(struct langwell_udc *dev)
epn = &dev->ep[i];
if (epn->name == NULL) {
- WARNING(dev, "invalid endpoint\n");
+ dev_warn(&dev->pdev->dev, "invalid endpoint\n");
continue;
}
if (i < 2)
/* ep0 in and out */
- DBG(dev, "%s-%s transfer completed\n",
+ dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n",
epn->name,
is_in(epn) ? "in" : "out");
else
- DBG(dev, "%s transfer completed\n", epn->name);
+ dev_dbg(&dev->pdev->dev, "%s transfer completed\n",
+ epn->name);
/* process the req queue until an uncomplete request */
list_for_each_entry_safe(curr_req, temp_req,
&epn->queue, queue) {
status = process_ep_req(dev, i, curr_req);
- VDBG(dev, "%s req status: %d\n", epn->name, status);
+ dev_vdbg(&dev->pdev->dev, "%s req status: %d\n",
+ epn->name, status);
if (status)
break;
@@ -2540,8 +2628,7 @@ static void handle_trans_complete(struct langwell_udc *dev)
}
}
done:
- VDBG(dev, "<--- %s()\n", __func__);
- return;
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2551,14 +2638,14 @@ static void handle_port_change(struct langwell_udc *dev)
u32 portsc1, devlc;
u32 speed;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dev->bus_reset)
dev->bus_reset = 0;
portsc1 = readl(&dev->op_regs->portsc1);
devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
+ dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
portsc1, devlc);
/* bus reset is finished */
@@ -2579,25 +2666,22 @@ static void handle_port_change(struct langwell_udc *dev)
dev->gadget.speed = USB_SPEED_UNKNOWN;
break;
}
- VDBG(dev, "speed = %d, dev->gadget.speed = %d\n",
+ dev_vdbg(&dev->pdev->dev,
+ "speed = %d, dev->gadget.speed = %d\n",
speed, dev->gadget.speed);
}
/* LPM L0 to L1 */
if (dev->lpm && dev->lpm_state == LPM_L0)
if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) {
- INFO(dev, "LPM L0 to L1\n");
- dev->lpm_state = LPM_L1;
+ dev_info(&dev->pdev->dev, "LPM L0 to L1\n");
+ dev->lpm_state = LPM_L1;
}
/* LPM L1 to L0, force resume or remote wakeup finished */
if (dev->lpm && dev->lpm_state == LPM_L1)
if (!(portsc1 & PORTS_SUSP)) {
- if (portsc1 & PORTS_SLP)
- INFO(dev, "LPM L1 to L0, force resume\n");
- else
- INFO(dev, "LPM L1 to L0, remote wakeup\n");
-
+ dev_info(&dev->pdev->dev, "LPM L1 to L0\n");
dev->lpm_state = LPM_L0;
}
@@ -2605,7 +2689,7 @@ static void handle_port_change(struct langwell_udc *dev)
if (!dev->resume_state)
dev->usb_state = USB_STATE_DEFAULT;
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2617,7 +2701,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
endptcomplete;
unsigned long timeout;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* Write-Clear the device address */
deviceaddr = readl(&dev->op_regs->deviceaddr);
@@ -2634,7 +2718,10 @@ static void handle_usb_reset(struct langwell_udc *dev)
dev->ep0_dir = USB_DIR_OUT;
dev->ep0_state = WAIT_FOR_SETUP;
- dev->remote_wakeup = 0; /* default to 0 on reset */
+
+ /* remote wakeup reset to 0 when the device is reset */
+ dev->remote_wakeup = 0;
+ dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
dev->gadget.b_hnp_enable = 0;
dev->gadget.a_hnp_support = 0;
dev->gadget.a_alt_hnp_support = 0;
@@ -2651,7 +2738,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
timeout = jiffies + PRIME_TIMEOUT;
while (readl(&dev->op_regs->endptprime)) {
if (time_after(jiffies, timeout)) {
- ERROR(dev, "USB reset timeout\n");
+ dev_err(&dev->pdev->dev, "USB reset timeout\n");
break;
}
cpu_relax();
@@ -2661,7 +2748,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
writel((u32) ~0, &dev->op_regs->endptflush);
if (readl(&dev->op_regs->portsc1) & PORTS_PR) {
- VDBG(dev, "USB bus reset\n");
+ dev_vdbg(&dev->pdev->dev, "USB bus reset\n");
/* bus is reseting */
dev->bus_reset = 1;
@@ -2669,7 +2756,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
stop_activity(dev, dev->driver);
dev->usb_state = USB_STATE_DEFAULT;
} else {
- VDBG(dev, "device controller reset\n");
+ dev_vdbg(&dev->pdev->dev, "device controller reset\n");
/* controller reset */
langwell_udc_reset(dev);
@@ -2691,15 +2778,14 @@ static void handle_usb_reset(struct langwell_udc *dev)
dev->lotg->hsm.b_hnp_enable = 0;
#endif
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
/* USB bus suspend/resume interrupt */
static void handle_bus_suspend(struct langwell_udc *dev)
{
- u32 devlc;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
dev->resume_state = dev->usb_state;
dev->usb_state = USB_STATE_SUSPENDED;
@@ -2733,33 +2819,29 @@ static void handle_bus_suspend(struct langwell_udc *dev)
spin_unlock(&dev->lock);
dev->driver->suspend(&dev->gadget);
spin_lock(&dev->lock);
- DBG(dev, "suspend %s\n", dev->driver->driver.name);
+ dev_dbg(&dev->pdev->dev, "suspend %s\n",
+ dev->driver->driver.name);
}
}
/* enter PHY low power suspend */
- devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "devlc = 0x%08x\n", devlc);
- devlc |= LPM_PHCD;
- writel(devlc, &dev->op_regs->devlc);
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 0);
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
static void handle_bus_resume(struct langwell_udc *dev)
{
- u32 devlc;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
dev->usb_state = dev->resume_state;
dev->resume_state = 0;
/* exit PHY low power suspend */
- devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "devlc = 0x%08x\n", devlc);
- devlc &= ~LPM_PHCD;
- writel(devlc, &dev->op_regs->devlc);
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 0);
#ifdef OTG_TRANSCEIVER
if (dev->lotg->otg.default_a == 0)
@@ -2772,11 +2854,12 @@ static void handle_bus_resume(struct langwell_udc *dev)
spin_unlock(&dev->lock);
dev->driver->resume(&dev->gadget);
spin_lock(&dev->lock);
- DBG(dev, "resume %s\n", dev->driver->driver.name);
+ dev_dbg(&dev->pdev->dev, "resume %s\n",
+ dev->driver->driver.name);
}
}
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -2789,11 +2872,11 @@ static irqreturn_t langwell_irq(int irq, void *_dev)
irq_sts,
portsc1;
- VDBG(dev, "---> %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
if (dev->stopped) {
- VDBG(dev, "handle IRQ_NONE\n");
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return IRQ_NONE;
}
@@ -2806,12 +2889,13 @@ static irqreturn_t langwell_irq(int irq, void *_dev)
usbintr = readl(&dev->op_regs->usbintr);
irq_sts = usbsts & usbintr;
- VDBG(dev, "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n",
+ dev_vdbg(&dev->pdev->dev,
+ "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n",
usbsts, usbintr, irq_sts);
if (!irq_sts) {
- VDBG(dev, "handle IRQ_NONE\n");
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
spin_unlock(&dev->lock);
return IRQ_NONE;
}
@@ -2827,12 +2911,13 @@ static irqreturn_t langwell_irq(int irq, void *_dev)
/* USB interrupt */
if (irq_sts & STS_UI) {
- VDBG(dev, "USB interrupt\n");
+ dev_vdbg(&dev->pdev->dev, "USB interrupt\n");
/* setup packet received from ep0 */
if (readl(&dev->op_regs->endptsetupstat)
& EP0SETUPSTAT_MASK) {
- VDBG(dev, "USB SETUP packet received interrupt\n");
+ dev_vdbg(&dev->pdev->dev,
+ "USB SETUP packet received interrupt\n");
/* setup tripwire semaphone */
setup_tripwire(dev);
handle_setup_packet(dev, &dev->local_setup_buff);
@@ -2840,7 +2925,8 @@ static irqreturn_t langwell_irq(int irq, void *_dev)
/* USB transfer completion */
if (readl(&dev->op_regs->endptcomplete)) {
- VDBG(dev, "USB transfer completion interrupt\n");
+ dev_vdbg(&dev->pdev->dev,
+ "USB transfer completion interrupt\n");
handle_trans_complete(dev);
}
}
@@ -2848,36 +2934,36 @@ static irqreturn_t langwell_irq(int irq, void *_dev)
/* SOF received interrupt (for ISO transfer) */
if (irq_sts & STS_SRI) {
/* FIXME */
- /* VDBG(dev, "SOF received interrupt\n"); */
+ /* dev_vdbg(&dev->pdev->dev, "SOF received interrupt\n"); */
}
/* port change detect interrupt */
if (irq_sts & STS_PCI) {
- VDBG(dev, "port change detect interrupt\n");
+ dev_vdbg(&dev->pdev->dev, "port change detect interrupt\n");
handle_port_change(dev);
}
/* suspend interrrupt */
if (irq_sts & STS_SLI) {
- VDBG(dev, "suspend interrupt\n");
+ dev_vdbg(&dev->pdev->dev, "suspend interrupt\n");
handle_bus_suspend(dev);
}
/* USB reset interrupt */
if (irq_sts & STS_URI) {
- VDBG(dev, "USB reset interrupt\n");
+ dev_vdbg(&dev->pdev->dev, "USB reset interrupt\n");
handle_usb_reset(dev);
}
/* USB error or system error interrupt */
if (irq_sts & (STS_UEI | STS_SEI)) {
/* FIXME */
- WARNING(dev, "error IRQ, irq_sts: %x\n", irq_sts);
+ dev_warn(&dev->pdev->dev, "error IRQ, irq_sts: %x\n", irq_sts);
}
spin_unlock(&dev->lock);
- VDBG(dev, "<--- %s()\n", __func__);
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return IRQ_HANDLED;
}
@@ -2889,15 +2975,59 @@ static void gadget_release(struct device *_dev)
{
struct langwell_udc *dev = the_controller;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
complete(dev->done);
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
kfree(dev);
}
+/* enable SRAM caching if SRAM detected */
+static void sram_init(struct langwell_udc *dev)
+{
+ struct pci_dev *pdev = dev->pdev;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->sram_addr = pci_resource_start(pdev, 1);
+ dev->sram_size = pci_resource_len(pdev, 1);
+ dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n",
+ dev->sram_addr, dev->sram_size);
+ dev->got_sram = 1;
+
+ if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) {
+ dev_warn(&dev->pdev->dev, "SRAM request failed\n");
+ dev->got_sram = 0;
+ } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr,
+ dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) {
+ dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n");
+ pci_release_region(pdev, 1);
+ dev->got_sram = 0;
+ }
+
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+}
+
+
+/* release SRAM caching */
+static void sram_deinit(struct langwell_udc *dev)
+{
+ struct pci_dev *pdev = dev->pdev;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dma_release_declared_memory(&pdev->dev);
+ pci_release_region(pdev, 1);
+
+ dev->got_sram = 0;
+
+ dev_info(&dev->pdev->dev, "release SRAM caching\n");
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+}
+
+
/* tear down the binding between this driver and the pci device */
static void langwell_udc_remove(struct pci_dev *pdev)
{
@@ -2906,23 +3036,29 @@ static void langwell_udc_remove(struct pci_dev *pdev)
DECLARE_COMPLETION(done);
BUG_ON(dev->driver);
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
dev->done = &done;
- /* free memory allocated in probe */
+#ifndef OTG_TRANSCEIVER
+ /* free dTD dma_pool and dQH */
if (dev->dtd_pool)
dma_pool_destroy(dev->dtd_pool);
+ if (dev->ep_dqh)
+ dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
+ dev->ep_dqh, dev->ep_dqh_dma);
+
+ /* release SRAM caching */
+ if (dev->has_sram && dev->got_sram)
+ sram_deinit(dev);
+#endif
+
if (dev->status_req) {
kfree(dev->status_req->req.buf);
kfree(dev->status_req);
}
- if (dev->ep_dqh)
- dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
- dev->ep_dqh, dev->ep_dqh_dma);
-
kfree(dev->ep);
/* diable IRQ handler */
@@ -2949,11 +3085,12 @@ static void langwell_udc_remove(struct pci_dev *pdev)
dev->cap_regs = NULL;
- INFO(dev, "unbind\n");
- DBG(dev, "<--- %s()\n", __func__);
+ dev_info(&dev->pdev->dev, "unbind\n");
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
device_unregister(&dev->gadget.dev);
device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
+ device_remove_file(&pdev->dev, &dev_attr_remote_wakeup);
#ifndef OTG_TRANSCEIVER
pci_set_drvdata(pdev, NULL);
@@ -2997,7 +3134,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
spin_lock_init(&dev->lock);
dev->pdev = pdev;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
#ifdef OTG_TRANSCEIVER
/* PCI device is already enabled by otg_transceiver driver */
@@ -3022,7 +3159,7 @@ static int langwell_udc_probe(struct pci_dev *pdev,
resource = pci_resource_start(pdev, 0);
len = pci_resource_len(pdev, 0);
if (!request_mem_region(resource, len, driver_name)) {
- ERROR(dev, "controller already in use\n");
+ dev_err(&dev->pdev->dev, "controller already in use\n");
retval = -EBUSY;
goto error;
}
@@ -3031,33 +3168,43 @@ static int langwell_udc_probe(struct pci_dev *pdev,
base = ioremap_nocache(resource, len);
#endif
if (base == NULL) {
- ERROR(dev, "can't map memory\n");
+ dev_err(&dev->pdev->dev, "can't map memory\n");
retval = -EFAULT;
goto error;
}
dev->cap_regs = (struct langwell_cap_regs __iomem *) base;
- VDBG(dev, "dev->cap_regs: %p\n", dev->cap_regs);
+ dev_vdbg(&dev->pdev->dev, "dev->cap_regs: %p\n", dev->cap_regs);
dev->op_regs = (struct langwell_op_regs __iomem *)
(base + OP_REG_OFFSET);
- VDBG(dev, "dev->op_regs: %p\n", dev->op_regs);
+ dev_vdbg(&dev->pdev->dev, "dev->op_regs: %p\n", dev->op_regs);
/* irq setup after old hardware is cleaned up */
if (!pdev->irq) {
- ERROR(dev, "No IRQ. Check PCI setup!\n");
+ dev_err(&dev->pdev->dev, "No IRQ. Check PCI setup!\n");
retval = -ENODEV;
goto error;
}
+ dev->has_sram = 1;
+ dev->got_sram = 0;
+ dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram);
+
#ifndef OTG_TRANSCEIVER
- INFO(dev, "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
+ /* enable SRAM caching if detected */
+ if (dev->has_sram && !dev->got_sram)
+ sram_init(dev);
+
+ dev_info(&dev->pdev->dev,
+ "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
pdev->irq, resource, len, base);
/* enables bus-mastering for device dev */
pci_set_master(pdev);
if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
driver_name, dev) != 0) {
- ERROR(dev, "request interrupt %d failed\n", pdev->irq);
+ dev_err(&dev->pdev->dev,
+ "request interrupt %d failed\n", pdev->irq);
retval = -EBUSY;
goto error;
}
@@ -3071,32 +3218,34 @@ static int langwell_udc_probe(struct pci_dev *pdev,
dev->lpm = (readl(&dev->cap_regs->hccparams) & HCC_LEN) ? 1 : 0;
dev->dciversion = readw(&dev->cap_regs->dciversion);
dev->devcap = (readl(&dev->cap_regs->dccparams) & DEVCAP) ? 1 : 0;
- VDBG(dev, "dev->lpm: %d\n", dev->lpm);
- VDBG(dev, "dev->dciversion: 0x%04x\n", dev->dciversion);
- VDBG(dev, "dccparams: 0x%08x\n", readl(&dev->cap_regs->dccparams));
- VDBG(dev, "dev->devcap: %d\n", dev->devcap);
+ dev_vdbg(&dev->pdev->dev, "dev->lpm: %d\n", dev->lpm);
+ dev_vdbg(&dev->pdev->dev, "dev->dciversion: 0x%04x\n",
+ dev->dciversion);
+ dev_vdbg(&dev->pdev->dev, "dccparams: 0x%08x\n",
+ readl(&dev->cap_regs->dccparams));
+ dev_vdbg(&dev->pdev->dev, "dev->devcap: %d\n", dev->devcap);
if (!dev->devcap) {
- ERROR(dev, "can't support device mode\n");
+ dev_err(&dev->pdev->dev, "can't support device mode\n");
retval = -ENODEV;
goto error;
}
/* a pair of endpoints (out/in) for each address */
dev->ep_max = DEN(readl(&dev->cap_regs->dccparams)) * 2;
- VDBG(dev, "dev->ep_max: %d\n", dev->ep_max);
+ dev_vdbg(&dev->pdev->dev, "dev->ep_max: %d\n", dev->ep_max);
/* allocate endpoints memory */
dev->ep = kzalloc(sizeof(struct langwell_ep) * dev->ep_max,
GFP_KERNEL);
if (!dev->ep) {
- ERROR(dev, "allocate endpoints memory failed\n");
+ dev_err(&dev->pdev->dev, "allocate endpoints memory failed\n");
retval = -ENOMEM;
goto error;
}
/* allocate device dQH memory */
size = dev->ep_max * sizeof(struct langwell_dqh);
- VDBG(dev, "orig size = %d\n", size);
+ dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size);
if (size < DQH_ALIGNMENT)
size = DQH_ALIGNMENT;
else if ((size % DQH_ALIGNMENT) != 0) {
@@ -3106,17 +3255,18 @@ static int langwell_udc_probe(struct pci_dev *pdev,
dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
&dev->ep_dqh_dma, GFP_KERNEL);
if (!dev->ep_dqh) {
- ERROR(dev, "allocate dQH memory failed\n");
+ dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
retval = -ENOMEM;
goto error;
}
dev->ep_dqh_size = size;
- VDBG(dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
+ dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
/* initialize ep0 status request structure */
dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL);
if (!dev->status_req) {
- ERROR(dev, "allocate status_req memory failed\n");
+ dev_err(&dev->pdev->dev,
+ "allocate status_req memory failed\n");
retval = -ENOMEM;
goto error;
}
@@ -3129,7 +3279,10 @@ static int langwell_udc_probe(struct pci_dev *pdev,
dev->resume_state = USB_STATE_NOTATTACHED;
dev->usb_state = USB_STATE_POWERED;
dev->ep0_dir = USB_DIR_OUT;
- dev->remote_wakeup = 0; /* default to 0 on reset */
+
+ /* remote wakeup reset to 0 when the device is reset */
+ dev->remote_wakeup = 0;
+ dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
#ifndef OTG_TRANSCEIVER
/* reset device controller */
@@ -3174,18 +3327,20 @@ static int langwell_udc_probe(struct pci_dev *pdev,
}
/* done */
- INFO(dev, "%s\n", driver_desc);
- INFO(dev, "irq %d, pci mem %p\n", pdev->irq, base);
- INFO(dev, "Driver version: " DRIVER_VERSION "\n");
- INFO(dev, "Support (max) %d endpoints\n", dev->ep_max);
- INFO(dev, "Device interface version: 0x%04x\n", dev->dciversion);
- INFO(dev, "Controller mode: %s\n", dev->devcap ? "Device" : "Host");
- INFO(dev, "Support USB LPM: %s\n", dev->lpm ? "Yes" : "No");
-
- VDBG(dev, "After langwell_udc_probe(), print all registers:\n");
-#ifdef VERBOSE
+ dev_info(&dev->pdev->dev, "%s\n", driver_desc);
+ dev_info(&dev->pdev->dev, "irq %d, pci mem %p\n", pdev->irq, base);
+ dev_info(&dev->pdev->dev, "Driver version: " DRIVER_VERSION "\n");
+ dev_info(&dev->pdev->dev, "Support (max) %d endpoints\n", dev->ep_max);
+ dev_info(&dev->pdev->dev, "Device interface version: 0x%04x\n",
+ dev->dciversion);
+ dev_info(&dev->pdev->dev, "Controller mode: %s\n",
+ dev->devcap ? "Device" : "Host");
+ dev_info(&dev->pdev->dev, "Support USB LPM: %s\n",
+ dev->lpm ? "Yes" : "No");
+
+ dev_vdbg(&dev->pdev->dev,
+ "After langwell_udc_probe(), print all registers:\n");
print_all_registers(dev);
-#endif
the_controller = dev;
@@ -3197,12 +3352,18 @@ static int langwell_udc_probe(struct pci_dev *pdev,
if (retval)
goto error;
- VDBG(dev, "<--- %s()\n", __func__);
+ retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup);
+ if (retval)
+ goto error_attr1;
+
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
+error_attr1:
+ device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
error:
if (dev) {
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
langwell_udc_remove(pdev);
}
@@ -3214,9 +3375,8 @@ error:
static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct langwell_udc *dev = the_controller;
- u32 devlc;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* disable interrupt and set controller to stop state */
langwell_udc_stop(dev);
@@ -3226,20 +3386,29 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
free_irq(pdev->irq, dev);
dev->got_irq = 0;
-
/* save PCI state */
pci_save_state(pdev);
+ /* free dTD dma_pool and dQH */
+ if (dev->dtd_pool)
+ dma_pool_destroy(dev->dtd_pool);
+
+ if (dev->ep_dqh)
+ dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
+ dev->ep_dqh, dev->ep_dqh_dma);
+
+ /* release SRAM caching */
+ if (dev->has_sram && dev->got_sram)
+ sram_deinit(dev);
+
/* set device power state */
pci_set_power_state(pdev, PCI_D3hot);
/* enter PHY low power suspend */
- devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "devlc = 0x%08x\n", devlc);
- devlc |= LPM_PHCD;
- writel(devlc, &dev->op_regs->devlc);
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 1);
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -3248,27 +3417,58 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
static int langwell_udc_resume(struct pci_dev *pdev)
{
struct langwell_udc *dev = the_controller;
- u32 devlc;
+ size_t size;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* exit PHY low power suspend */
- devlc = readl(&dev->op_regs->devlc);
- VDBG(dev, "devlc = 0x%08x\n", devlc);
- devlc &= ~LPM_PHCD;
- writel(devlc, &dev->op_regs->devlc);
+ if (dev->pdev->device != 0x0829)
+ langwell_phy_low_power(dev, 0);
/* set device D0 power state */
pci_set_power_state(pdev, PCI_D0);
+ /* enable SRAM caching if detected */
+ if (dev->has_sram && !dev->got_sram)
+ sram_init(dev);
+
+ /* allocate device dQH memory */
+ size = dev->ep_max * sizeof(struct langwell_dqh);
+ dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size);
+ if (size < DQH_ALIGNMENT)
+ size = DQH_ALIGNMENT;
+ else if ((size % DQH_ALIGNMENT) != 0) {
+ size += DQH_ALIGNMENT + 1;
+ size &= ~(DQH_ALIGNMENT - 1);
+ }
+ dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
+ &dev->ep_dqh_dma, GFP_KERNEL);
+ if (!dev->ep_dqh) {
+ dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
+ return -ENOMEM;
+ }
+ dev->ep_dqh_size = size;
+ dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
+
+ /* create dTD dma_pool resource */
+ dev->dtd_pool = dma_pool_create("langwell_dtd",
+ &dev->pdev->dev,
+ sizeof(struct langwell_dtd),
+ DTD_ALIGNMENT,
+ DMA_BOUNDARY);
+
+ if (!dev->dtd_pool)
+ return -ENOMEM;
+
/* restore PCI state */
pci_restore_state(pdev);
/* enable IRQ handler */
- if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, driver_name, dev)
- != 0) {
- ERROR(dev, "request interrupt %d failed\n", pdev->irq);
- return -1;
+ if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
+ driver_name, dev) != 0) {
+ dev_err(&dev->pdev->dev, "request interrupt %d failed\n",
+ pdev->irq);
+ return -EBUSY;
}
dev->got_irq = 1;
@@ -3290,7 +3490,7 @@ static int langwell_udc_resume(struct pci_dev *pdev)
dev->ep0_state = WAIT_FOR_SETUP;
dev->ep0_dir = USB_DIR_OUT;
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
@@ -3301,15 +3501,15 @@ static void langwell_udc_shutdown(struct pci_dev *pdev)
struct langwell_udc *dev = the_controller;
u32 usbmode;
- DBG(dev, "---> %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
/* reset controller mode to IDLE */
usbmode = readl(&dev->op_regs->usbmode);
- DBG(dev, "usbmode = 0x%08x\n", usbmode);
+ dev_dbg(&dev->pdev->dev, "usbmode = 0x%08x\n", usbmode);
usbmode &= (~3 | MODE_IDLE);
writel(usbmode, &dev->op_regs->usbmode);
- DBG(dev, "<--- %s()\n", __func__);
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
/*-------------------------------------------------------------------------*/
@@ -3324,7 +3524,6 @@ static const struct pci_device_id pci_ids[] = { {
}, { /* end: all zeroes */ }
};
-
MODULE_DEVICE_TABLE(pci, pci_ids);
@@ -3343,12 +3542,6 @@ static struct pci_driver langwell_pci_driver = {
};
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-
static int __init init(void)
{
#ifdef OTG_TRANSCEIVER
@@ -3370,3 +3563,9 @@ static void __exit cleanup(void)
}
module_exit(cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h
index 9719934e1c08..f1d9c1bb04f3 100644
--- a/drivers/usb/gadget/langwell_udc.h
+++ b/drivers/usb/gadget/langwell_udc.h
@@ -18,11 +18,7 @@
*/
#include <linux/usb/langwell_udc.h>
-
-#if defined(CONFIG_USB_LANGWELL_OTG)
#include <linux/usb/langwell_otg.h>
-#endif
-
/*-------------------------------------------------------------------------*/
@@ -199,7 +195,9 @@ struct langwell_udc {
vbus_active:1,
suspended:1,
stopped:1,
- lpm:1; /* LPM capability */
+ lpm:1, /* LPM capability */
+ has_sram:1, /* SRAM caching */
+ got_sram:1;
/* pci state used to access those endpoints */
struct pci_dev *pdev;
@@ -224,5 +222,12 @@ struct langwell_udc {
/* make sure release() is done */
struct completion *done;
+
+ /* for private SRAM caching */
+ unsigned int sram_addr;
+ unsigned int sram_size;
+
+ /* device status data for get_status request */
+ u16 dev_status;
};
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index fded3fca793b..6b58bd8ce623 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -408,7 +408,8 @@ static void udc_enable(struct lh7a40x_udc *dev)
/*
Register entry point for the peripheral controller driver.
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct lh7a40x_udc *dev = the_controller;
int retval;
@@ -417,7 +418,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver
|| driver->speed != USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -431,7 +432,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev->gadget.dev.driver = &driver->driver;
device_add(&dev->gadget.dev);
- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
dev->gadget.name, driver->driver.name, retval);
@@ -453,8 +454,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
return 0;
}
-
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/*
Unregister entry point for the peripheral controller driver.
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index e03058fe23cb..51b19f3027e7 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -1454,14 +1454,15 @@ static struct usb_ep_ops m66592_ep_ops = {
/*-------------------------------------------------------------------------*/
static struct m66592 *the_controller;
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct m66592 *m66592 = the_controller;
int retval;
if (!driver
|| driver->speed != USB_SPEED_HIGH
- || !driver->bind
+ || !bind
|| !driver->setup)
return -EINVAL;
if (!m66592)
@@ -1480,7 +1481,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
goto error;
}
- retval = driver->bind (&m66592->gadget);
+ retval = bind(&m66592->gadget);
if (retval) {
pr_err("bind to driver error (%d)\n", retval);
device_del(&m66592->gadget.dev);
@@ -1505,7 +1506,7 @@ error:
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 585f2559484d..0769179dbdb0 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -75,10 +75,6 @@ static struct usb_device_descriptor msg_device_desc = {
/* Vendor and product id can be overridden by module parameters. */
.idVendor = cpu_to_le16(FSG_VENDOR_ID),
.idProduct = cpu_to_le16(FSG_PRODUCT_ID),
- /* .bcdDevice = f(hardware) */
- /* .iManufacturer = DYNAMIC */
- /* .iProduct = DYNAMIC */
- /* NO SERIAL NUMBER */
.bNumConfigurations = 1,
};
@@ -86,7 +82,8 @@ static struct usb_otg_descriptor otg_descriptor = {
.bLength = sizeof otg_descriptor,
.bDescriptorType = USB_DT_OTG,
- /* REVISIT SRP-only hardware is possible, although
+ /*
+ * REVISIT SRP-only hardware is possible, although
* it would not be called "OTG" ...
*/
.bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
@@ -98,33 +95,6 @@ static const struct usb_descriptor_header *otg_desc[] = {
};
-/* string IDs are assigned dynamically */
-
-#define STRING_MANUFACTURER_IDX 0
-#define STRING_PRODUCT_IDX 1
-#define STRING_CONFIGURATION_IDX 2
-
-static char manufacturer[50];
-
-static struct usb_string strings_dev[] = {
- [STRING_MANUFACTURER_IDX].s = manufacturer,
- [STRING_PRODUCT_IDX].s = DRIVER_DESC,
- [STRING_CONFIGURATION_IDX].s = "Self Powered",
- { } /* end of list */
-};
-
-static struct usb_gadget_strings stringtab_dev = {
- .language = 0x0409, /* en-us */
- .strings = strings_dev,
-};
-
-static struct usb_gadget_strings *dev_strings[] = {
- &stringtab_dev,
- NULL,
-};
-
-
-
/****************************** Configurations ******************************/
static struct fsg_module_parameters mod_data = {
@@ -141,7 +111,7 @@ static int msg_thread_exits(struct fsg_common *common)
return 0;
}
-static int __ref msg_do_config(struct usb_configuration *c)
+static int __init msg_do_config(struct usb_configuration *c)
{
static const struct fsg_operations ops = {
.thread_exits = msg_thread_exits,
@@ -171,54 +141,23 @@ static int __ref msg_do_config(struct usb_configuration *c)
static struct usb_configuration msg_config_driver = {
.label = "Linux File-Backed Storage",
- .bind = msg_do_config,
.bConfigurationValue = 1,
- /* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
-
/****************************** Gadget Bind ******************************/
-
-static int __ref msg_bind(struct usb_composite_dev *cdev)
+static int __init msg_bind(struct usb_composite_dev *cdev)
{
- struct usb_gadget *gadget = cdev->gadget;
int status;
- /* Allocate string descriptor numbers ... note that string
- * contents can be overridden by the composite_dev glue.
- */
-
- /* device descriptor strings: manufacturer, product */
- snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
- init_utsname()->sysname, init_utsname()->release,
- gadget->name);
- status = usb_string_id(cdev);
+ status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
if (status < 0)
return status;
- strings_dev[STRING_MANUFACTURER_IDX].id = status;
- msg_device_desc.iManufacturer = status;
- status = usb_string_id(cdev);
- if (status < 0)
- return status;
- strings_dev[STRING_PRODUCT_IDX].id = status;
- msg_device_desc.iProduct = status;
-
- status = usb_string_id(cdev);
- if (status < 0)
- return status;
- strings_dev[STRING_CONFIGURATION_IDX].id = status;
- msg_config_driver.iConfiguration = status;
-
- /* register our second configuration */
- status = usb_add_config(cdev, &msg_config_driver);
- if (status < 0)
- return status;
-
- dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+ dev_info(&cdev->gadget->dev,
+ DRIVER_DESC ", version: " DRIVER_VERSION "\n");
set_bit(0, &msg_registered);
return 0;
}
@@ -226,12 +165,11 @@ static int __ref msg_bind(struct usb_composite_dev *cdev)
/****************************** Some noise ******************************/
-
static struct usb_composite_driver msg_driver = {
.name = "g_mass_storage",
.dev = &msg_device_desc,
- .strings = dev_strings,
- .bind = msg_bind,
+ .iProduct = DRIVER_DESC,
+ .needs_serial = 1,
};
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -240,7 +178,7 @@ MODULE_LICENSE("GPL");
static int __init msg_init(void)
{
- return usb_composite_register(&msg_driver);
+ return usb_composite_probe(&msg_driver, msg_bind);
}
module_init(msg_init);
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 795d76232167..d9feced348e3 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -74,8 +74,8 @@ MODULE_LICENSE("GPL");
/***************************** Device Descriptor ****************************/
-#define MULTI_VENDOR_NUM 0x0525 /* XXX NetChip */
-#define MULTI_PRODUCT_NUM 0xa4ab /* XXX */
+#define MULTI_VENDOR_NUM 0x1d6b /* Linux Foundation */
+#define MULTI_PRODUCT_NUM 0x0104 /* Multifunction Composite Gadget */
enum {
@@ -121,8 +121,6 @@ static const struct usb_descriptor_header *otg_desc[] = {
enum {
- MULTI_STRING_MANUFACTURER_IDX,
- MULTI_STRING_PRODUCT_IDX,
#ifdef CONFIG_USB_G_MULTI_RNDIS
MULTI_STRING_RNDIS_CONFIG_IDX,
#endif
@@ -131,11 +129,7 @@ enum {
#endif
};
-static char manufacturer[50];
-
static struct usb_string strings_dev[] = {
- [MULTI_STRING_MANUFACTURER_IDX].s = manufacturer,
- [MULTI_STRING_PRODUCT_IDX].s = DRIVER_DESC,
#ifdef CONFIG_USB_G_MULTI_RNDIS
[MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS",
#endif
@@ -170,7 +164,7 @@ static u8 hostaddr[ETH_ALEN];
#ifdef USB_ETH_RNDIS
-static __ref int rndis_do_config(struct usb_configuration *c)
+static __init int rndis_do_config(struct usb_configuration *c)
{
int ret;
@@ -197,7 +191,6 @@ static __ref int rndis_do_config(struct usb_configuration *c)
static int rndis_config_register(struct usb_composite_dev *cdev)
{
static struct usb_configuration config = {
- .bind = rndis_do_config,
.bConfigurationValue = MULTI_RNDIS_CONFIG_NUM,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
@@ -205,7 +198,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
config.label = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].s;
config.iConfiguration = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].id;
- return usb_add_config(cdev, &config);
+ return usb_add_config(cdev, &config, rndis_do_config);
}
#else
@@ -222,7 +215,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
#ifdef CONFIG_USB_G_MULTI_CDC
-static __ref int cdc_do_config(struct usb_configuration *c)
+static __init int cdc_do_config(struct usb_configuration *c)
{
int ret;
@@ -249,7 +242,6 @@ static __ref int cdc_do_config(struct usb_configuration *c)
static int cdc_config_register(struct usb_composite_dev *cdev)
{
static struct usb_configuration config = {
- .bind = cdc_do_config,
.bConfigurationValue = MULTI_CDC_CONFIG_NUM,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
@@ -257,7 +249,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
config.label = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].s;
config.iConfiguration = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].id;
- return usb_add_config(cdev, &config);
+ return usb_add_config(cdev, &config, cdc_do_config);
}
#else
@@ -314,20 +306,11 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
}
- /* allocate string descriptor numbers */
- snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
- init_utsname()->sysname, init_utsname()->release,
- gadget->name);
-
+ /* allocate string IDs */
status = usb_string_ids_tab(cdev, strings_dev);
if (unlikely(status < 0))
goto fail2;
- device_desc.iManufacturer =
- strings_dev[MULTI_STRING_MANUFACTURER_IDX].id;
- device_desc.iProduct =
- strings_dev[MULTI_STRING_PRODUCT_IDX].id;
-
/* register configurations */
status = rndis_config_register(cdev);
if (unlikely(status < 0))
@@ -368,14 +351,15 @@ static struct usb_composite_driver multi_driver = {
.name = "g_multi",
.dev = &device_desc,
.strings = dev_strings,
- .bind = multi_bind,
.unbind = __exit_p(multi_unbind),
+ .iProduct = DRIVER_DESC,
+ .needs_serial = 1,
};
static int __init multi_init(void)
{
- return usb_composite_register(&multi_driver);
+ return usb_composite_probe(&multi_driver, multi_bind);
}
module_init(multi_init);
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 9498be87a724..d09155b25d73 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1929,7 +1929,8 @@ static void ep0_start (struct net2280 *dev)
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct net2280 *dev = the_controller;
int retval;
@@ -1941,8 +1942,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
*/
if (!driver
|| driver->speed != USB_SPEED_HIGH
- || !driver->bind
- || !driver->setup)
+ || !bind || !driver->setup)
return -EINVAL;
if (!dev)
return -ENODEV;
@@ -1957,7 +1957,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
driver->driver.bus = NULL;
dev->driver = driver;
dev->gadget.dev.driver = &driver->driver;
- retval = driver->bind (&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
DEBUG (dev, "bind to driver %s --> %d\n",
driver->driver.name, retval);
@@ -1993,7 +1993,7 @@ err_unbind:
dev->driver = NULL;
return retval;
}
-EXPORT_SYMBOL (usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index 7d6b66a85724..b5364f9d7cd2 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -135,7 +135,6 @@ static int __init nokia_bind_config(struct usb_configuration *c)
static struct usb_configuration nokia_config_500ma_driver = {
.label = "Bus Powered",
- .bind = nokia_bind_config,
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE,
@@ -144,7 +143,6 @@ static struct usb_configuration nokia_config_500ma_driver = {
static struct usb_configuration nokia_config_100ma_driver = {
.label = "Self Powered",
- .bind = nokia_bind_config,
.bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
@@ -206,11 +204,13 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
}
/* finaly register the configuration */
- status = usb_add_config(cdev, &nokia_config_500ma_driver);
+ status = usb_add_config(cdev, &nokia_config_500ma_driver,
+ nokia_bind_config);
if (status < 0)
goto err_usb;
- status = usb_add_config(cdev, &nokia_config_100ma_driver);
+ status = usb_add_config(cdev, &nokia_config_100ma_driver,
+ nokia_bind_config);
if (status < 0)
goto err_usb;
@@ -241,13 +241,12 @@ static struct usb_composite_driver nokia_driver = {
.name = "g_nokia",
.dev = &device_desc,
.strings = dev_strings,
- .bind = nokia_bind,
.unbind = __exit_p(nokia_unbind),
};
static int __init nokia_init(void)
{
- return usb_composite_register(&nokia_driver);
+ return usb_composite_probe(&nokia_driver, nokia_bind);
}
module_init(nokia_init);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index f81e4f025f23..61d3ca6619bb 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2102,7 +2102,8 @@ static inline int machine_without_vbus_sense(void)
);
}
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
int status = -ENODEV;
struct omap_ep *ep;
@@ -2114,8 +2115,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (!driver
// FIXME if otg, check: driver->is_otg
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
- || !driver->setup)
+ || !bind || !driver->setup)
return -EINVAL;
spin_lock_irqsave(&udc->lock, flags);
@@ -2145,7 +2145,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
if (udc->dc_clk != NULL)
omap_udc_enable_clock(1);
- status = driver->bind (&udc->gadget);
+ status = bind(&udc->gadget);
if (status) {
DBG("bind to %s --> %d\n", driver->driver.name, status);
udc->gadget.dev.driver = NULL;
@@ -2186,7 +2186,7 @@ done:
omap_udc_enable_clock(0);
return status;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index cf241c371a71..159762f86584 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -884,7 +884,8 @@ static const struct file_operations printer_io_operations = {
.fsync = printer_fsync,
.poll = printer_poll,
.unlocked_ioctl = printer_ioctl,
- .release = printer_close
+ .release = printer_close,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/*-------------------------------------------------------------------------*/
@@ -1347,7 +1348,7 @@ printer_unbind(struct usb_gadget *gadget)
set_gadget_data(gadget, NULL);
}
-static int __ref
+static int __init
printer_bind(struct usb_gadget *gadget)
{
struct printer_dev *dev;
@@ -1543,7 +1544,6 @@ static struct usb_gadget_driver printer_driver = {
.speed = DEVSPEED,
.function = (char *) driver_desc,
- .bind = printer_bind,
.unbind = printer_unbind,
.setup = printer_setup,
@@ -1579,11 +1579,11 @@ init(void)
return status;
}
- status = usb_gadget_register_driver(&printer_driver);
+ status = usb_gadget_probe_driver(&printer_driver, printer_bind);
if (status) {
class_destroy(usb_gadget_class);
unregister_chrdev_region(g_printer_devno, 1);
- DBG(dev, "usb_gadget_register_driver %x\n", status);
+ DBG(dev, "usb_gadget_probe_driver %x\n", status);
}
return status;
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index be5fb34d9602..b37f92cb71bc 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1280,14 +1280,15 @@ static void udc_enable (struct pxa25x_udc *dev)
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct pxa25x_udc *dev = the_controller;
int retval;
if (!driver
|| driver->speed < USB_SPEED_FULL
- || !driver->bind
+ || !bind
|| !driver->disconnect
|| !driver->setup)
return -EINVAL;
@@ -1308,7 +1309,7 @@ fail:
dev->gadget.dev.driver = NULL;
return retval;
}
- retval = driver->bind(&dev->gadget);
+ retval = bind(&dev->gadget);
if (retval) {
DMSG("bind to driver %s --> error %d\n",
driver->driver.name, retval);
@@ -1338,7 +1339,7 @@ fail:
bind_fail:
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 980762453a9c..2efd6732d130 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1394,8 +1394,6 @@ static void pxa_ep_fifo_flush(struct usb_ep *_ep)
}
spin_unlock_irqrestore(&ep->lock, flags);
-
- return;
}
/**
@@ -1792,8 +1790,9 @@ static void udc_enable(struct pxa_udc *udc)
}
/**
- * usb_gadget_register_driver - Register gadget driver
+ * usb_gadget_probe_driver - Register gadget driver
* @driver: gadget driver
+ * @bind: bind function
*
* When a driver is successfully registered, it will receive control requests
* including set_configuration(), which enables non-control requests. Then
@@ -1805,12 +1804,13 @@ static void udc_enable(struct pxa_udc *udc)
*
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct pxa_udc *udc = the_controller;
int retval;
- if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind
+ if (!driver || driver->speed < USB_SPEED_FULL || !bind
|| !driver->disconnect || !driver->setup)
return -EINVAL;
if (!udc)
@@ -1828,7 +1828,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_err(udc->dev, "device_add error %d\n", retval);
goto add_fail;
}
- retval = driver->bind(&udc->gadget);
+ retval = bind(&udc->gadget);
if (retval) {
dev_err(udc->dev, "bind to driver %s --> error %d\n",
driver->driver.name, retval);
@@ -1859,7 +1859,7 @@ add_fail:
udc->gadget.dev.driver = NULL;
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/**
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 2456ccd9965e..95092151f901 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1405,14 +1405,15 @@ static struct usb_ep_ops r8a66597_ep_ops = {
/*-------------------------------------------------------------------------*/
static struct r8a66597 *the_controller;
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct r8a66597 *r8a66597 = the_controller;
int retval;
if (!driver
|| driver->speed != USB_SPEED_HIGH
- || !driver->bind
+ || !bind
|| !driver->setup)
return -EINVAL;
if (!r8a66597)
@@ -1431,7 +1432,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
goto error;
}
- retval = driver->bind(&r8a66597->gadget);
+ retval = bind(&r8a66597->gadget);
if (retval) {
printk(KERN_ERR "bind to driver error (%d)\n", retval);
device_del(&r8a66597->gadget.dev);
@@ -1456,7 +1457,7 @@ error:
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 020fa5a25fda..d3cdffea9c8a 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -61,17 +61,17 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
#define RNDIS_MAX_CONFIGS 1
-static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
+static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS];
/* Driver Version */
-static const __le32 rndis_driver_version = 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);
+static rndis_resp_t *rndis_add_response(int configNr, u32 length);
/* supported OIDs */
-static const u32 oid_supported_list [] =
+static const u32 oid_supported_list[] =
{
/* the general stuff */
OID_GEN_SUPPORTED_LIST,
@@ -161,21 +161,20 @@ static const u32 oid_supported_list [] =
/* NDIS Functions */
-static int
-gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
- rndis_resp_t *r)
+static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
+ unsigned buf_len, rndis_resp_t *r)
{
- int retval = -ENOTSUPP;
- u32 length = 4; /* usually */
- __le32 *outbuf;
- int i, count;
- rndis_query_cmplt_type *resp;
- struct net_device *net;
+ int retval = -ENOTSUPP;
+ u32 length = 4; /* usually */
+ __le32 *outbuf;
+ int i, count;
+ rndis_query_cmplt_type *resp;
+ struct net_device *net;
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *stats;
if (!r) return -ENOMEM;
- resp = (rndis_query_cmplt_type *) r->buf;
+ resp = (rndis_query_cmplt_type *)r->buf;
if (!resp) return -ENOMEM;
@@ -191,8 +190,8 @@ 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 = cpu_to_le32 (16);
+ outbuf = (__le32 *)&resp[1];
+ resp->InformationBufferOffset = cpu_to_le32(16);
net = rndis_per_dev_params[configNr].dev;
stats = dev_get_stats(net, &temp);
@@ -204,10 +203,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_SUPPORTED_LIST:
pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
- length = sizeof (oid_supported_list);
- count = length / sizeof (u32);
+ length = sizeof(oid_supported_list);
+ count = length / sizeof(u32);
for (i = 0; i < count; i++)
- outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
+ outbuf[i] = cpu_to_le32(oid_supported_list[i]);
retval = 0;
break;
@@ -220,14 +219,14 @@ 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 = cpu_to_le32 (0);
+ *outbuf = cpu_to_le32(0);
retval = 0;
break;
/* mandatory */
case OID_GEN_MEDIA_SUPPORTED:
pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
- *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
+ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium);
retval = 0;
break;
@@ -235,16 +234,16 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_GEN_MEDIA_IN_USE:
pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
/* one medium, one transport... (maybe you do it better) */
- *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
+ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium);
retval = 0;
break;
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
- if (rndis_per_dev_params [configNr].dev) {
- *outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].dev->mtu);
+ if (rndis_per_dev_params[configNr].dev) {
+ *outbuf = cpu_to_le32(
+ rndis_per_dev_params[configNr].dev->mtu);
retval = 0;
}
break;
@@ -253,21 +252,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_GEN_LINK_SPEED:
if (rndis_debug > 1)
pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
- if (rndis_per_dev_params [configNr].media_state
+ if (rndis_per_dev_params[configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
- *outbuf = cpu_to_le32 (0);
+ *outbuf = cpu_to_le32(0);
else
- *outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].speed);
+ *outbuf = cpu_to_le32(
+ rndis_per_dev_params[configNr].speed);
retval = 0;
break;
/* mandatory */
case OID_GEN_TRANSMIT_BLOCK_SIZE:
pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
- if (rndis_per_dev_params [configNr].dev) {
- *outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].dev->mtu);
+ if (rndis_per_dev_params[configNr].dev) {
+ *outbuf = cpu_to_le32(
+ rndis_per_dev_params[configNr].dev->mtu);
retval = 0;
}
break;
@@ -275,9 +274,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RECEIVE_BLOCK_SIZE:
pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
- if (rndis_per_dev_params [configNr].dev) {
- *outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].dev->mtu);
+ if (rndis_per_dev_params[configNr].dev) {
+ *outbuf = cpu_to_le32(
+ rndis_per_dev_params[configNr].dev->mtu);
retval = 0;
}
break;
@@ -285,17 +284,23 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_ID:
pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__);
- *outbuf = cpu_to_le32 (
- rndis_per_dev_params [configNr].vendorID);
+ *outbuf = cpu_to_le32(
+ rndis_per_dev_params[configNr].vendorID);
retval = 0;
break;
/* mandatory */
case OID_GEN_VENDOR_DESCRIPTION:
pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
- length = strlen (rndis_per_dev_params [configNr].vendorDescr);
- memcpy (outbuf,
- rndis_per_dev_params [configNr].vendorDescr, length);
+ if (rndis_per_dev_params[configNr].vendorDescr) {
+ length = strlen(rndis_per_dev_params[configNr].
+ vendorDescr);
+ memcpy(outbuf,
+ rndis_per_dev_params[configNr].vendorDescr,
+ length);
+ } else {
+ outbuf[0] = 0;
+ }
retval = 0;
break;
@@ -309,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_CURRENT_PACKET_FILTER:
pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
- *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
+ *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter);
retval = 0;
break;
@@ -324,14 +329,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
case OID_GEN_MEDIA_CONNECT_STATUS:
if (rndis_debug > 1)
pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
- *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
+ *outbuf = cpu_to_le32(rndis_per_dev_params[configNr]
.media_state);
retval = 0;
break;
case OID_GEN_PHYSICAL_MEDIUM:
pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
- *outbuf = cpu_to_le32 (0);
+ *outbuf = cpu_to_le32(0);
retval = 0;
break;
@@ -405,10 +410,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_PERMANENT_ADDRESS:
pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
- if (rndis_per_dev_params [configNr].dev) {
+ if (rndis_per_dev_params[configNr].dev) {
length = ETH_ALEN;
- memcpy (outbuf,
- rndis_per_dev_params [configNr].host_mac,
+ memcpy(outbuf,
+ rndis_per_dev_params[configNr].host_mac,
length);
retval = 0;
}
@@ -417,9 +422,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_CURRENT_ADDRESS:
pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
- if (rndis_per_dev_params [configNr].dev) {
+ if (rndis_per_dev_params[configNr].dev) {
length = ETH_ALEN;
- memcpy (outbuf,
+ memcpy(outbuf,
rndis_per_dev_params [configNr].host_mac,
length);
retval = 0;
@@ -430,7 +435,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 = cpu_to_le32 (0xE0000000);
+ *outbuf = cpu_to_le32(0xE0000000);
retval = 0;
break;
@@ -438,7 +443,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 = cpu_to_le32 (1);
+ *outbuf = cpu_to_le32(1);
retval = 0;
break;
@@ -462,14 +467,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 = 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 = cpu_to_le32 (0);
+ *outbuf = cpu_to_le32(0);
retval = 0;
break;
@@ -480,22 +485,22 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
if (retval < 0)
length = 0;
- resp->InformationBufferLength = cpu_to_le32 (length);
- r->length = length + sizeof *resp;
- resp->MessageLength = cpu_to_le32 (r->length);
+ resp->InformationBufferLength = cpu_to_le32(length);
+ r->length = length + sizeof(*resp);
+ resp->MessageLength = cpu_to_le32(r->length);
return retval;
}
-static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
- rndis_resp_t *r)
+static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len,
+ rndis_resp_t *r)
{
- rndis_set_cmplt_type *resp;
- int i, retval = -ENOTSUPP;
- struct rndis_params *params;
+ rndis_set_cmplt_type *resp;
+ int i, retval = -ENOTSUPP;
+ struct rndis_params *params;
if (!r)
return -ENOMEM;
- resp = (rndis_set_cmplt_type *) r->buf;
+ resp = (rndis_set_cmplt_type *)r->buf;
if (!resp)
return -ENOMEM;
@@ -510,7 +515,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
}
}
- params = &rndis_per_dev_params [configNr];
+ params = &rndis_per_dev_params[configNr];
switch (OID) {
case OID_GEN_CURRENT_PACKET_FILTER:
@@ -533,11 +538,11 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
params->state = RNDIS_DATA_INITIALIZED;
netif_carrier_on(params->dev);
if (netif_running(params->dev))
- netif_wake_queue (params->dev);
+ netif_wake_queue(params->dev);
} else {
params->state = RNDIS_INITIALIZED;
- netif_carrier_off (params->dev);
- netif_stop_queue (params->dev);
+ netif_carrier_off(params->dev);
+ netif_stop_queue(params->dev);
}
break;
@@ -559,48 +564,47 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
* Response Functions
*/
-static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
+static int rndis_init_response(int configNr, rndis_init_msg_type *buf)
{
- rndis_init_cmplt_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ rndis_init_cmplt_type *resp;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
if (!params->dev)
return -ENOTSUPP;
- r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
+ r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type));
if (!r)
return -ENOMEM;
- resp = (rndis_init_cmplt_type *) r->buf;
+ resp = (rndis_init_cmplt_type *)r->buf;
- resp->MessageType = cpu_to_le32 (
- REMOTE_NDIS_INITIALIZE_CMPLT);
- resp->MessageLength = cpu_to_le32 (52);
+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT);
+ resp->MessageLength = cpu_to_le32(52);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- 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 (
+ 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)
+ + sizeof(struct ethhdr)
+ + sizeof(struct rndis_packet_msg_type)
+ 22);
- resp->PacketAlignmentFactor = cpu_to_le32 (0);
- resp->AFListOffset = cpu_to_le32 (0);
- resp->AFListSize = 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;
}
-static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
+static int rndis_query_response(int configNr, rndis_query_msg_type *buf)
{
rndis_query_cmplt_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
/* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
if (!params->dev)
@@ -612,47 +616,46 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
* rndis_query_cmplt_type followed by data.
* oid_supported_list is the largest data reply
*/
- r = rndis_add_response (configNr,
- sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));
+ r = rndis_add_response(configNr,
+ sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type));
if (!r)
return -ENOMEM;
- resp = (rndis_query_cmplt_type *) r->buf;
+ resp = (rndis_query_cmplt_type *)r->buf;
- resp->MessageType = 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),
+ if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID),
le32_to_cpu(buf->InformationBufferOffset)
- + 8 + (u8 *) buf,
+ + 8 + (u8 *)buf,
le32_to_cpu(buf->InformationBufferLength),
r)) {
/* OID not supported */
- resp->Status = cpu_to_le32 (
- RNDIS_STATUS_NOT_SUPPORTED);
- resp->MessageLength = cpu_to_le32 (sizeof *resp);
- resp->InformationBufferLength = cpu_to_le32 (0);
- resp->InformationBufferOffset = cpu_to_le32 (0);
+ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
+ resp->MessageLength = cpu_to_le32(sizeof *resp);
+ resp->InformationBufferLength = cpu_to_le32(0);
+ resp->InformationBufferOffset = cpu_to_le32(0);
} else
- resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
}
-static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
+static int rndis_set_response(int configNr, rndis_set_msg_type *buf)
{
- u32 BufLength, BufOffset;
- rndis_set_cmplt_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ u32 BufLength, BufOffset;
+ rndis_set_cmplt_type *resp;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
- r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
+ r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type));
if (!r)
return -ENOMEM;
- resp = (rndis_set_cmplt_type *) r->buf;
+ resp = (rndis_set_cmplt_type *)r->buf;
- BufLength = le32_to_cpu (buf->InformationBufferLength);
- BufOffset = le32_to_cpu (buf->InformationBufferOffset);
+ BufLength = le32_to_cpu(buf->InformationBufferLength);
+ BufOffset = le32_to_cpu(buf->InformationBufferOffset);
#ifdef VERBOSE_DEBUG
pr_debug("%s: Length: %d\n", __func__, BufLength);
@@ -666,59 +669,59 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
pr_debug("\n");
#endif
- resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
- resp->MessageLength = 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 = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
+ if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID),
+ ((u8 *)buf) + 8 + BufOffset, BufLength, r))
+ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
else
- resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
}
-static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
+static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf)
{
- rndis_reset_cmplt_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ rndis_reset_cmplt_type *resp;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
- r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
+ r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type));
if (!r)
return -ENOMEM;
- resp = (rndis_reset_cmplt_type *) r->buf;
+ resp = (rndis_reset_cmplt_type *)r->buf;
- resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
- resp->MessageLength = cpu_to_le32 (16);
- resp->Status = 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 = cpu_to_le32 (1);
+ resp->AddressingReset = cpu_to_le32(1);
params->resp_avail(params->v);
return 0;
}
-static int rndis_keepalive_response (int configNr,
- rndis_keepalive_msg_type *buf)
+static int rndis_keepalive_response(int configNr,
+ rndis_keepalive_msg_type *buf)
{
- rndis_keepalive_cmplt_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ rndis_keepalive_cmplt_type *resp;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
/* host "should" check only in RNDIS_DATA_INITIALIZED state */
- r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
+ r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type));
if (!r)
return -ENOMEM;
- resp = (rndis_keepalive_cmplt_type *) r->buf;
+ resp = (rndis_keepalive_cmplt_type *)r->buf;
- resp->MessageType = cpu_to_le32 (
+ resp->MessageType = cpu_to_le32(
REMOTE_NDIS_KEEPALIVE_CMPLT);
- resp->MessageLength = cpu_to_le32 (16);
+ resp->MessageLength = cpu_to_le32(16);
resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
params->resp_avail(params->v);
return 0;
@@ -728,86 +731,85 @@ static int rndis_keepalive_response (int configNr,
/*
* Device to Host Comunication
*/
-static int rndis_indicate_status_msg (int configNr, u32 status)
+static int rndis_indicate_status_msg(int configNr, u32 status)
{
- rndis_indicate_status_msg_type *resp;
- rndis_resp_t *r;
- struct rndis_params *params = rndis_per_dev_params + configNr;
+ rndis_indicate_status_msg_type *resp;
+ rndis_resp_t *r;
+ struct rndis_params *params = rndis_per_dev_params + configNr;
if (params->state == RNDIS_UNINITIALIZED)
return -ENOTSUPP;
- r = rndis_add_response (configNr,
- sizeof (rndis_indicate_status_msg_type));
+ r = rndis_add_response(configNr,
+ sizeof(rndis_indicate_status_msg_type));
if (!r)
return -ENOMEM;
- resp = (rndis_indicate_status_msg_type *) r->buf;
+ resp = (rndis_indicate_status_msg_type *)r->buf;
- resp->MessageType = cpu_to_le32 (
- REMOTE_NDIS_INDICATE_STATUS_MSG);
- resp->MessageLength = cpu_to_le32 (20);
- resp->Status = cpu_to_le32 (status);
- resp->StatusBufferLength = cpu_to_le32 (0);
- resp->StatusBufferOffset = cpu_to_le32 (0);
+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_INDICATE_STATUS_MSG);
+ resp->MessageLength = cpu_to_le32(20);
+ resp->Status = cpu_to_le32(status);
+ resp->StatusBufferLength = cpu_to_le32(0);
+ resp->StatusBufferOffset = cpu_to_le32(0);
params->resp_avail(params->v);
return 0;
}
-int rndis_signal_connect (int configNr)
+int rndis_signal_connect(int configNr)
{
- rndis_per_dev_params [configNr].media_state
+ rndis_per_dev_params[configNr].media_state
= NDIS_MEDIA_STATE_CONNECTED;
- return rndis_indicate_status_msg (configNr,
+ return rndis_indicate_status_msg(configNr,
RNDIS_STATUS_MEDIA_CONNECT);
}
-int rndis_signal_disconnect (int configNr)
+int rndis_signal_disconnect(int configNr)
{
- rndis_per_dev_params [configNr].media_state
+ rndis_per_dev_params[configNr].media_state
= NDIS_MEDIA_STATE_DISCONNECTED;
- return rndis_indicate_status_msg (configNr,
+ return rndis_indicate_status_msg(configNr,
RNDIS_STATUS_MEDIA_DISCONNECT);
}
-void rndis_uninit (int configNr)
+void rndis_uninit(int configNr)
{
u8 *buf;
u32 length;
if (configNr >= RNDIS_MAX_CONFIGS)
return;
- rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
+ rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED;
/* drain the response queue */
while ((buf = rndis_get_next_response(configNr, &length)))
rndis_free_response(configNr, buf);
}
-void rndis_set_host_mac (int configNr, const u8 *addr)
+void rndis_set_host_mac(int configNr, const u8 *addr)
{
- rndis_per_dev_params [configNr].host_mac = addr;
+ rndis_per_dev_params[configNr].host_mac = addr;
}
/*
* Message Parser
*/
-int rndis_msg_parser (u8 configNr, u8 *buf)
+int rndis_msg_parser(u8 configNr, u8 *buf)
{
u32 MsgType, MsgLength;
__le32 *tmp;
- struct rndis_params *params;
+ struct rndis_params *params;
if (!buf)
return -ENOMEM;
- tmp = (__le32 *) buf;
+ tmp = (__le32 *)buf;
MsgType = get_unaligned_le32(tmp++);
MsgLength = get_unaligned_le32(tmp++);
if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
- params = &rndis_per_dev_params [configNr];
+ params = &rndis_per_dev_params[configNr];
/* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
* rx/tx statistics and link status, in addition to KEEPALIVE traffic
@@ -818,41 +820,41 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
switch (MsgType) {
case REMOTE_NDIS_INITIALIZE_MSG:
pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
- __func__ );
+ __func__);
params->state = RNDIS_INITIALIZED;
- return rndis_init_response (configNr,
- (rndis_init_msg_type *) buf);
+ return rndis_init_response(configNr,
+ (rndis_init_msg_type *)buf);
case REMOTE_NDIS_HALT_MSG:
pr_debug("%s: REMOTE_NDIS_HALT_MSG\n",
- __func__ );
+ __func__);
params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
- netif_carrier_off (params->dev);
- netif_stop_queue (params->dev);
+ netif_carrier_off(params->dev);
+ netif_stop_queue(params->dev);
}
return 0;
case REMOTE_NDIS_QUERY_MSG:
- return rndis_query_response (configNr,
- (rndis_query_msg_type *) buf);
+ return rndis_query_response(configNr,
+ (rndis_query_msg_type *)buf);
case REMOTE_NDIS_SET_MSG:
- return rndis_set_response (configNr,
- (rndis_set_msg_type *) buf);
+ return rndis_set_response(configNr,
+ (rndis_set_msg_type *)buf);
case REMOTE_NDIS_RESET_MSG:
pr_debug("%s: REMOTE_NDIS_RESET_MSG\n",
- __func__ );
- return rndis_reset_response (configNr,
- (rndis_reset_msg_type *) buf);
+ __func__);
+ return rndis_reset_response(configNr,
+ (rndis_reset_msg_type *)buf);
case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
if (rndis_debug > 1)
pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
- __func__ );
- return rndis_keepalive_response (configNr,
+ __func__);
+ return rndis_keepalive_response(configNr,
(rndis_keepalive_msg_type *)
buf);
@@ -862,7 +864,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
* suspending itself.
*/
pr_warning("%s: unknown RNDIS message 0x%08X len %d\n",
- __func__ , MsgType, MsgLength);
+ __func__, MsgType, MsgLength);
{
unsigned i;
for (i = 0; i < MsgLength; i += 16) {
@@ -897,10 +899,10 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
return -EINVAL;
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
- if (!rndis_per_dev_params [i].used) {
- rndis_per_dev_params [i].used = 1;
- rndis_per_dev_params [i].resp_avail = resp_avail;
- rndis_per_dev_params [i].v = v;
+ if (!rndis_per_dev_params[i].used) {
+ rndis_per_dev_params[i].used = 1;
+ rndis_per_dev_params[i].resp_avail = resp_avail;
+ rndis_per_dev_params[i].v = v;
pr_debug("%s: configNr = %d\n", __func__, i);
return i;
}
@@ -910,14 +912,12 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
return -ENODEV;
}
-void rndis_deregister (int configNr)
+void rndis_deregister(int configNr)
{
- pr_debug("%s: \n", __func__);
+ pr_debug("%s:\n", __func__);
if (configNr >= RNDIS_MAX_CONFIGS) return;
- rndis_per_dev_params [configNr].used = 0;
-
- return;
+ rndis_per_dev_params[configNr].used = 0;
}
int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
@@ -927,76 +927,76 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
return -EINVAL;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
- rndis_per_dev_params [configNr].dev = dev;
- rndis_per_dev_params [configNr].filter = cdc_filter;
+ rndis_per_dev_params[configNr].dev = dev;
+ rndis_per_dev_params[configNr].filter = cdc_filter;
return 0;
}
-int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
+int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr)
{
pr_debug("%s:\n", __func__);
if (!vendorDescr) return -1;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
- rndis_per_dev_params [configNr].vendorID = vendorID;
- rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
+ rndis_per_dev_params[configNr].vendorID = vendorID;
+ rndis_per_dev_params[configNr].vendorDescr = vendorDescr;
return 0;
}
-int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
+int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)
{
pr_debug("%s: %u %u\n", __func__, medium, speed);
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
- rndis_per_dev_params [configNr].medium = medium;
- rndis_per_dev_params [configNr].speed = speed;
+ rndis_per_dev_params[configNr].medium = medium;
+ rndis_per_dev_params[configNr].speed = speed;
return 0;
}
-void rndis_add_hdr (struct sk_buff *skb)
+void rndis_add_hdr(struct sk_buff *skb)
{
- struct rndis_packet_msg_type *header;
+ struct rndis_packet_msg_type *header;
if (!skb)
return;
- header = (void *) skb_push (skb, sizeof *header);
- memset (header, 0, sizeof *header);
+ header = (void *)skb_push(skb, sizeof(*header));
+ memset(header, 0, sizeof *header);
header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
header->MessageLength = cpu_to_le32(skb->len);
- header->DataOffset = cpu_to_le32 (36);
- header->DataLength = cpu_to_le32(skb->len - sizeof *header);
+ header->DataOffset = cpu_to_le32(36);
+ header->DataLength = cpu_to_le32(skb->len - sizeof(*header));
}
-void rndis_free_response (int configNr, u8 *buf)
+void rndis_free_response(int configNr, u8 *buf)
{
- rndis_resp_t *r;
- struct list_head *act, *tmp;
+ rndis_resp_t *r;
+ struct list_head *act, *tmp;
- list_for_each_safe (act, tmp,
- &(rndis_per_dev_params [configNr].resp_queue))
+ list_for_each_safe(act, tmp,
+ &(rndis_per_dev_params[configNr].resp_queue))
{
- r = list_entry (act, rndis_resp_t, list);
+ r = list_entry(act, rndis_resp_t, list);
if (r && r->buf == buf) {
- list_del (&r->list);
- kfree (r);
+ list_del(&r->list);
+ kfree(r);
}
}
}
-u8 *rndis_get_next_response (int configNr, u32 *length)
+u8 *rndis_get_next_response(int configNr, u32 *length)
{
- rndis_resp_t *r;
- struct list_head *act, *tmp;
+ rndis_resp_t *r;
+ struct list_head *act, *tmp;
if (!length) return NULL;
- list_for_each_safe (act, tmp,
- &(rndis_per_dev_params [configNr].resp_queue))
+ list_for_each_safe(act, tmp,
+ &(rndis_per_dev_params[configNr].resp_queue))
{
- r = list_entry (act, rndis_resp_t, list);
+ r = list_entry(act, rndis_resp_t, list);
if (!r->send) {
r->send = 1;
*length = r->length;
@@ -1007,20 +1007,20 @@ u8 *rndis_get_next_response (int configNr, u32 *length)
return NULL;
}
-static rndis_resp_t *rndis_add_response (int configNr, u32 length)
+static rndis_resp_t *rndis_add_response(int configNr, u32 length)
{
- rndis_resp_t *r;
+ rndis_resp_t *r;
- /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
- r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
+ /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
+ r = kmalloc(sizeof(rndis_resp_t) + length, GFP_ATOMIC);
if (!r) return NULL;
- r->buf = (u8 *) (r + 1);
+ r->buf = (u8 *)(r + 1);
r->length = length;
r->send = 0;
- list_add_tail (&r->list,
- &(rndis_per_dev_params [configNr].resp_queue));
+ list_add_tail(&r->list,
+ &(rndis_per_dev_params[configNr].resp_queue));
return r;
}
@@ -1029,7 +1029,7 @@ int rndis_rm_hdr(struct gether *port,
struct sk_buff_head *list)
{
/* tmp points to a struct rndis_packet_msg_type */
- __le32 *tmp = (void *) skb->data;
+ __le32 *tmp = (void *)skb->data;
/* MessageType, MessageLength */
if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
@@ -1050,7 +1050,7 @@ int rndis_rm_hdr(struct gether *port,
return 0;
}
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
static int rndis_proc_show(struct seq_file *m, void *v)
{
@@ -1083,7 +1083,7 @@ static int rndis_proc_show(struct seq_file *m, void *v)
}
static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{
rndis_params *p = PDE(file->f_path.dentry->d_inode)->data;
u32 speed = 0;
@@ -1105,11 +1105,11 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
case '8':
case '9':
fl_speed = 1;
- speed = speed*10 + c - '0';
+ speed = speed * 10 + c - '0';
break;
case 'C':
case 'c':
- rndis_signal_connect (p->confignr);
+ rndis_signal_connect(p->confignr);
break;
case 'D':
case 'd':
@@ -1141,14 +1141,14 @@ static const struct file_operations rndis_proc_fops = {
.write = rndis_proc_write,
};
-#define NAME_TEMPLATE "driver/rndis-%03d"
+#define NAME_TEMPLATE "driver/rndis-%03d"
static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
-#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
-int __init rndis_init (void)
+int rndis_init(void)
{
u8 i;
@@ -1156,42 +1156,40 @@ int __init rndis_init (void)
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
char name [20];
- sprintf (name, NAME_TEMPLATE, i);
- if (!(rndis_connect_state [i]
- = proc_create_data(name, 0660, NULL,
+ sprintf(name, NAME_TEMPLATE, i);
+ rndis_connect_state[i] = proc_create_data(name, 0660, NULL,
&rndis_proc_fops,
- (void *)(rndis_per_dev_params + i))))
- {
- pr_debug("%s :remove entries", __func__);
+ (void *)(rndis_per_dev_params + i));
+ if (!rndis_connect_state[i]) {
+ pr_debug("%s: remove entries", __func__);
while (i) {
- sprintf (name, NAME_TEMPLATE, --i);
- remove_proc_entry (name, NULL);
+ sprintf(name, NAME_TEMPLATE, --i);
+ remove_proc_entry(name, NULL);
}
pr_debug("\n");
return -EIO;
}
#endif
- rndis_per_dev_params [i].confignr = i;
- rndis_per_dev_params [i].used = 0;
- rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
- rndis_per_dev_params [i].media_state
+ rndis_per_dev_params[i].confignr = i;
+ rndis_per_dev_params[i].used = 0;
+ rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED;
+ rndis_per_dev_params[i].media_state
= NDIS_MEDIA_STATE_DISCONNECTED;
- INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
+ INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue));
}
return 0;
}
-void rndis_exit (void)
+void rndis_exit(void)
{
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
u8 i;
- char name [20];
+ char name[20];
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
- sprintf (name, NAME_TEMPLATE, i);
- remove_proc_entry (name, NULL);
+ sprintf(name, NAME_TEMPLATE, i);
+ remove_proc_entry(name, NULL);
}
#endif
}
-
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index c236aaa9dcd1..907c33008118 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -262,7 +262,7 @@ int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);
-int __devinit rndis_init (void);
+int rndis_init(void);
void rndis_exit (void);
#endif /* _LINUX_RNDIS_H */
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 521ebed0118d..ef825c3baed9 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -12,8 +12,6 @@
* published by the Free Software Foundation.
*/
-#define DEBUG
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
@@ -2525,7 +2523,8 @@ static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
return 0;
}
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct s3c_hsotg *hsotg = our_hsotg;
int ret;
@@ -2545,7 +2544,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_err(hsotg->dev, "%s: bad speed\n", __func__);
}
- if (!driver->bind || !driver->setup) {
+ if (!bind || !driver->setup) {
dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
return -EINVAL;
}
@@ -2564,7 +2563,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
goto err;
}
- ret = driver->bind(&hsotg->gadget);
+ ret = bind(&hsotg->gadget);
if (ret) {
dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name);
@@ -2689,7 +2688,7 @@ err:
hsotg->gadget.dev.driver = NULL;
return ret;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index ea2b3c7ebee5..c2448950a8d8 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1632,15 +1632,15 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev)
}
/*
- * usb_gadget_register_driver
+ * usb_gadget_probe_driver
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
struct s3c2410_udc *udc = the_controller;
int retval;
- dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n",
- driver->driver.name);
+ dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name);
/* Sanity checks */
if (!udc)
@@ -1649,10 +1649,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (udc->driver)
return -EBUSY;
- if (!driver->bind || !driver->setup
- || driver->speed < USB_SPEED_FULL) {
+ if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) {
printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
- driver->bind, driver->setup, driver->speed);
+ bind, driver->setup, driver->speed);
return -EINVAL;
}
#if defined(MODULE)
@@ -1675,7 +1674,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n",
driver->driver.name);
- if ((retval = driver->bind (&udc->gadget)) != 0) {
+ if ((retval = bind(&udc->gadget)) != 0) {
device_del(&udc->gadget.dev);
goto register_error;
}
@@ -1690,6 +1689,7 @@ register_error:
udc->gadget.dev.driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/*
* usb_gadget_unregister_driver
@@ -2049,7 +2049,6 @@ static void __exit udc_exit(void)
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
-EXPORT_SYMBOL(usb_gadget_register_driver);
module_init(udc_init);
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b22eedbc7dc5..1ac57a973aa9 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -137,7 +137,7 @@ MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
/*-------------------------------------------------------------------------*/
-static int __ref serial_bind_config(struct usb_configuration *c)
+static int __init serial_bind_config(struct usb_configuration *c)
{
unsigned i;
int status = 0;
@@ -155,13 +155,12 @@ static int __ref serial_bind_config(struct usb_configuration *c)
static struct usb_configuration serial_config_driver = {
/* .label = f(use_acm) */
- .bind = serial_bind_config,
/* .bConfigurationValue = f(use_acm) */
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
-static int __ref gs_bind(struct usb_composite_dev *cdev)
+static int __init gs_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
@@ -225,7 +224,8 @@ static int __ref gs_bind(struct usb_composite_dev *cdev)
}
/* register our configuration */
- status = usb_add_config(cdev, &serial_config_driver);
+ status = usb_add_config(cdev, &serial_config_driver,
+ serial_bind_config);
if (status < 0)
goto fail;
@@ -242,7 +242,6 @@ static struct usb_composite_driver gserial_driver = {
.name = "g_serial",
.dev = &device_desc,
.strings = dev_strings,
- .bind = gs_bind,
};
static int __init init(void)
@@ -271,7 +270,7 @@ static int __init init(void)
}
strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
- return usb_composite_register(&gserial_driver);
+ return usb_composite_probe(&gserial_driver, gs_bind);
}
module_init(init);
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 484acfb1a7c5..d7856c599d5a 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -26,7 +26,6 @@
* be defined (each of type pointer to char):
* - fsg_string_manufacturer -- name of the manufacturer
* - fsg_string_product -- name of the product
- * - fsg_string_serial -- product's serial
* - fsg_string_config -- name of the configuration
* - fsg_string_interface -- name of the interface
* The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
@@ -552,7 +551,7 @@ static struct usb_string fsg_strings[] = {
#ifndef FSG_NO_DEVICE_STRINGS
{FSG_STRING_MANUFACTURER, fsg_string_manufacturer},
{FSG_STRING_PRODUCT, fsg_string_product},
- {FSG_STRING_SERIAL, fsg_string_serial},
+ {FSG_STRING_SERIAL, ""},
{FSG_STRING_CONFIG, fsg_string_config},
#endif
{FSG_STRING_INTERFACE, fsg_string_interface},
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index de1deb7a3c63..a5a0fdb808c7 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -308,7 +308,7 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
* USB configuration
*/
-static int __ref
+static int __init
webcam_config_bind(struct usb_configuration *c)
{
return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls,
@@ -317,7 +317,6 @@ webcam_config_bind(struct usb_configuration *c)
static struct usb_configuration webcam_config_driver = {
.label = webcam_config_label,
- .bind = webcam_config_bind,
.bConfigurationValue = 1,
.iConfiguration = 0, /* dynamic */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
@@ -330,7 +329,7 @@ webcam_unbind(struct usb_composite_dev *cdev)
return 0;
}
-static int __ref
+static int __init
webcam_bind(struct usb_composite_dev *cdev)
{
int ret;
@@ -354,7 +353,8 @@ webcam_bind(struct usb_composite_dev *cdev)
webcam_config_driver.iConfiguration = ret;
/* Register our configuration. */
- if ((ret = usb_add_config(cdev, &webcam_config_driver)) < 0)
+ if ((ret = usb_add_config(cdev, &webcam_config_driver,
+ webcam_config_bind)) < 0)
goto error;
INFO(cdev, "Webcam Video Gadget\n");
@@ -373,14 +373,13 @@ static struct usb_composite_driver webcam_driver = {
.name = "g_webcam",
.dev = &webcam_device_descriptor,
.strings = webcam_device_strings,
- .bind = webcam_bind,
.unbind = webcam_unbind,
};
static int __init
webcam_init(void)
{
- return usb_composite_register(&webcam_driver);
+ return usb_composite_probe(&webcam_driver, webcam_bind);
}
static void __exit
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index cf353920bb1c..6d16db9d9d2d 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -264,7 +264,7 @@ static void zero_resume(struct usb_composite_dev *cdev)
/*-------------------------------------------------------------------------*/
-static int __ref zero_bind(struct usb_composite_dev *cdev)
+static int __init zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
@@ -340,7 +340,6 @@ 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,
@@ -351,7 +350,7 @@ MODULE_LICENSE("GPL");
static int __init init(void)
{
- return usb_composite_register(&zero_driver);
+ return usb_composite_probe(&zero_driver, zero_bind);
}
module_init(init);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 76b7fd2d838a..e00547c1ebc6 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -369,18 +369,21 @@ static const struct file_operations debug_async_fops = {
.open = debug_async_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations debug_periodic_fops = {
.owner = THIS_MODULE,
.open = debug_periodic_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations debug_registers_fops = {
.owner = THIS_MODULE,
.open = debug_registers_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations debug_lpm_fops = {
.owner = THIS_MODULE,
@@ -388,6 +391,7 @@ static const struct file_operations debug_lpm_fops = {
.read = debug_lpm_read,
.write = debug_lpm_write,
.release = debug_lpm_close,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct dentry *ehci_debug_root;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a416421abfa2..8600317bd60b 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -233,8 +233,6 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
}
- /* put controller in host mode. */
- ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
#ifdef CONFIG_PPC_85xx
out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
@@ -270,6 +268,8 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
/* cache this readonly data; minimize chip reads */
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ hcd->has_tt = 1;
+
retval = ehci_halt(ehci);
if (retval)
return retval;
@@ -279,8 +279,6 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
if (retval)
return retval;
- hcd->has_tt = 1;
-
ehci->sbrn = 0x20;
ehci_reset(ehci);
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index b5e59db53347..eb537aa54610 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -27,7 +27,6 @@
#define PORT_PTS_SERIAL (3<<30)
#define PORT_PTS_PTW (1<<28)
#define FSL_SOC_USB_PORTSC2 0x188
-#define FSL_SOC_USB_USBMODE 0x1a8
#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 34a928d3b7d2..2adae8e39bba 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -194,6 +194,17 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
return -ETIMEDOUT;
}
+/* check TDI/ARC silicon is in host mode */
+static int tdi_in_host_mode (struct ehci_hcd *ehci)
+{
+ u32 __iomem *reg_ptr;
+ u32 tmp;
+
+ reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
+ tmp = ehci_readl(ehci, reg_ptr);
+ return (tmp & 3) == USBMODE_CM_HC;
+}
+
/* force HC to halt state from unknown (EHCI spec section 2.3) */
static int ehci_halt (struct ehci_hcd *ehci)
{
@@ -202,6 +213,10 @@ static int ehci_halt (struct ehci_hcd *ehci)
/* disable any irqs left enabled by previous code */
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+ if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) {
+ return 0;
+ }
+
if ((temp & STS_HALT) != 0)
return 0;
@@ -1080,7 +1095,6 @@ nogood:
ep->hcpriv = NULL;
done:
spin_unlock_irqrestore (&ehci->lock, flags);
- return;
}
static void
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index a8ad8ac120a2..ac9c4d7c44af 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -26,9 +26,6 @@
#include <mach/mxc_ehci.h>
#define ULPI_VIEWPORT_OFFSET 0x170
-#define PORTSC_OFFSET 0x184
-#define USBMODE_OFFSET 0x1a8
-#define USBMODE_CM_HOST 3
struct ehci_mxc_priv {
struct clk *usbclk, *ahbclk;
@@ -51,6 +48,8 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
/* cache this readonly data; minimize chip reads */
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ hcd->has_tt = 1;
+
retval = ehci_halt(ehci);
if (retval)
return retval;
@@ -60,8 +59,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
if (retval)
return retval;
- hcd->has_tt = 1;
-
ehci->sbrn = 0x20;
ehci_reset(ehci);
@@ -191,12 +188,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
clk_enable(priv->ahbclk);
}
- /* set USBMODE to host mode */
- temp = readl(hcd->regs + USBMODE_OFFSET);
- writel(temp | USBMODE_CM_HOST, hcd->regs + USBMODE_OFFSET);
-
/* set up the PORTSCx register */
- writel(pdata->portsc, hcd->regs + PORTSC_OFFSET);
+ ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
mdelay(10);
/* setup specific usb hw */
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 58b72d741d93..a1e8d273103f 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -119,6 +119,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
ehci->broken_periodic = 1;
ehci_info(ehci, "using broken periodic workaround\n");
}
+ if (pdev->device == 0x0806 || pdev->device == 0x0811
+ || pdev->device == 0x0829) {
+ ehci_info(ehci, "disable lpm for langwell/penwell\n");
+ ehci->has_lpm = 0;
+ }
break;
case PCI_VENDOR_ID_TDI:
if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index 335ee699fd85..ba52be473027 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -192,17 +192,19 @@ ehci_hcd_ppc_of_probe(struct platform_device *op, const struct of_device_id *mat
}
rv = usb_add_hcd(hcd, irq, 0);
- if (rv == 0)
- return 0;
+ if (rv)
+ goto err_ehci;
+
+ return 0;
+err_ehci:
+ if (ehci->has_amcc_usb23)
+ iounmap(ehci->ohci_hcctrl_reg);
iounmap(hcd->regs);
err_ioremap:
irq_dispose_mapping(irq);
err_irq:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-
- if (ehci->has_amcc_usb23)
- iounmap(ehci->ohci_hcctrl_reg);
err_rmr:
usb_put_hcd(hcd);
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index 3e5630369c31..d0abb9b0e673 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -27,8 +27,8 @@
* * 32 transfer descriptors (called ETDs)
* * 4Kb of Data memory
*
- * The data memory is shared between the host and fuction controlers
- * (but this driver only supports the host controler)
+ * The data memory is shared between the host and function controllers
+ * (but this driver only supports the host controller)
*
* So setting up a transfer involves:
* * Allocating a ETD
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 36abd2baa3ea..04813fac2b5c 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -413,18 +413,21 @@ static const struct file_operations debug_async_fops = {
.open = debug_async_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations debug_periodic_fops = {
.owner = THIS_MODULE,
.open = debug_periodic_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations debug_registers_fops = {
.owner = THIS_MODULE,
.open = debug_registers_open,
.read = debug_output,
.release = debug_close,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static struct dentry *ohci_debug_root;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c3b4ccc7337b..15ae39d6cc24 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -370,7 +370,6 @@ sanitize:
}
ep->hcpriv = NULL;
spin_unlock_irqrestore (&ohci->lock, flags);
- return;
}
static int ohci_get_frame (struct usb_hcd *hcd)
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index d9c85a292737..8026dc85996c 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -544,8 +544,6 @@ static void oxu_buf_free(struct oxu_hcd *oxu, struct ehci_qtd *qtd)
qtd->buffer = NULL;
spin_unlock(&oxu->mem_lock);
-
- return;
}
static inline void ehci_qtd_init(struct ehci_qtd *qtd, dma_addr_t dma)
@@ -571,8 +569,6 @@ static inline void oxu_qtd_free(struct oxu_hcd *oxu, struct ehci_qtd *qtd)
oxu->qtd_used[index] = 0;
spin_unlock(&oxu->mem_lock);
-
- return;
}
static struct ehci_qtd *ehci_qtd_alloc(struct oxu_hcd *oxu)
@@ -615,8 +611,6 @@ static void oxu_qh_free(struct oxu_hcd *oxu, struct ehci_qh *qh)
oxu->qh_used[index] = 0;
spin_unlock(&oxu->mem_lock);
-
- return;
}
static void qh_destroy(struct kref *kref)
@@ -693,8 +687,6 @@ static void oxu_murb_free(struct oxu_hcd *oxu, struct oxu_murb *murb)
oxu->murb_used[index] = 0;
spin_unlock(&oxu->mem_lock);
-
- return;
}
static struct oxu_murb *oxu_murb_alloc(struct oxu_hcd *oxu)
@@ -3070,7 +3062,6 @@ nogood:
ep->hcpriv = NULL;
done:
spin_unlock_irqrestore(&oxu->lock, flags);
- return;
}
static int oxu_get_frame(struct usb_hcd *hcd)
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 83b5f9cea85a..5b37b08e0d80 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -338,8 +338,6 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
writel(0x3f, op_reg_base + EHCI_USBSTS);
iounmap(base);
-
- return;
}
/*
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 5b31bae92dbc..fab764946c74 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -316,7 +316,6 @@ static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring,
} else if (queue_delayed_work(workqueue, &ring->scheduler, 0))
return;
kref_put(&u132->kref, u132_hcd_delete);
- return;
}
static void u132_ring_queue_work(struct u132 *u132, struct u132_ring *ring,
@@ -324,7 +323,6 @@ static void u132_ring_queue_work(struct u132 *u132, struct u132_ring *ring,
{
kref_get(&u132->kref);
u132_ring_requeue_work(u132, ring, delta);
- return;
}
static void u132_ring_cancel_work(struct u132 *u132, struct u132_ring *ring)
@@ -543,7 +541,6 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp,
mutex_unlock(&u132->scheduler_lock);
u132_endp_put_kref(u132, endp);
usb_hcd_giveback_urb(hcd, urb, status);
- return;
}
static void u132_hcd_forget_urb(struct u132 *u132, struct u132_endp *endp,
@@ -574,8 +571,8 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp,
endp->active = 0;
spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
kfree(urbq);
- } usb_hcd_giveback_urb(hcd, urb, status);
- return;
+ }
+ usb_hcd_giveback_urb(hcd, urb, status);
}
static inline int edset_input(struct u132 *u132, struct u132_ring *ring,
@@ -3085,7 +3082,6 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
u132->endp[endps] = NULL;
mutex_unlock(&u132->sw_lock);
- return;
}
static int __devinit u132_probe(struct platform_device *pdev)
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index e192e8f7c560..a80342ba14ea 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -963,6 +963,7 @@ static const struct file_operations mdc800_device_ops =
.write = mdc800_device_write,
.open = mdc800_device_open,
.release = mdc800_device_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 3a6bcd5fee09..5a47805d9580 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -398,7 +398,6 @@ void mts_int_submit_urb (struct urb* transfer,
context->srb->result = DID_ERROR << 16;
mts_transfer_cleanup(transfer);
}
- return;
}
@@ -409,7 +408,6 @@ static void mts_transfer_cleanup( struct urb *transfer )
if ( likely(context->final_callback != NULL) )
context->final_callback(context->srb);
-
}
static void mts_transfer_done( struct urb *transfer )
@@ -420,8 +418,6 @@ static void mts_transfer_done( struct urb *transfer )
context->srb->result |= (unsigned)(*context->scsi_status)<<1;
mts_transfer_cleanup(transfer);
-
- return;
}
@@ -452,8 +448,6 @@ static void mts_data_done( struct urb* transfer )
}
mts_get_status(transfer);
-
- return;
}
@@ -496,8 +490,6 @@ static void mts_command_done( struct urb *transfer )
mts_get_status(transfer);
}
}
-
- return;
}
static void mts_do_sg (struct urb* transfer)
@@ -522,7 +514,6 @@ static void mts_do_sg (struct urb* transfer)
sg[context->fragment].length,
context->fragment + 1 == scsi_sg_count(context->srb) ?
mts_data_done : mts_do_sg);
- return;
}
static const u8 mts_read_image_sig[] = { 0x28, 00, 00, 00 };
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 801324af9470..9297e6854669 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -679,6 +679,7 @@ static const struct file_operations adu_fops = {
.write = adu_write,
.open = adu_open,
.release = adu_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/*
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index aecf380f6ecc..7839c98fa742 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -456,7 +456,6 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
{
ftdi_command_queue_work(ftdi, 0);
- return;
}
static void ftdi_elan_command_work(struct work_struct *work)
@@ -483,7 +482,6 @@ static void ftdi_elan_command_work(struct work_struct *work)
static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi)
{
ftdi_respond_queue_work(ftdi, 0);
- return;
}
static void ftdi_elan_respond_work(struct work_struct *work)
@@ -2769,7 +2767,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
ftdi->sequence_num = ++ftdi_instances;
mutex_unlock(&ftdi_module_lock);
ftdi_elan_init_kref(ftdi);
- init_MUTEX(&ftdi->sw_lock);
+ sema_init(&ftdi->sw_lock, 1);
ftdi->udev = usb_get_dev(interface_to_usbdev(interface));
ftdi->interface = interface;
mutex_init(&ftdi->u132_lock);
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index a54c3cb804ce..8e34d0195555 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -105,6 +105,7 @@ static const struct file_operations idmouse_fops = {
.read = idmouse_read,
.open = idmouse_open,
.release = idmouse_release,
+ .llseek = default_llseek,/* read accesses f_pos */
};
/* class driver information */
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index bc88c79875a1..8390786bb192 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -730,6 +730,7 @@ static const struct file_operations iowarrior_fops = {
.open = iowarrior_open,
.release = iowarrior_release,
.poll = iowarrior_poll,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static char *iowarrior_devnode(struct device *dev, mode_t *mode)
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index dd41d8710043..2053eb9d6758 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -613,6 +613,7 @@ static const struct file_operations ld_usb_fops = {
.open = ld_usb_open,
.release = ld_usb_release,
.poll = ld_usb_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};
/*
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index cc13ae61712a..d8816f640075 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -439,6 +439,7 @@ static const struct file_operations usb_rio_fops = {
.unlocked_ioctl = ioctl_rio,
.open = open_rio,
.release = close_rio,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct usb_class_driver usb_rio_class = {
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index d00dde19194c..0d45edeb27b8 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -282,6 +282,7 @@ static const struct file_operations lcd_fops = {
.open = lcd_open,
.unlocked_ioctl = lcd_ioctl,
.release = lcd_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/*
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 812dc288bb8c..10405119985c 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -90,7 +90,6 @@ static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb)
r->rnf_submit(r->r_data, urb);
}
spin_unlock_irqrestore(&mbus->lock, flags);
- return;
}
static void mon_submit(struct usb_bus *ubus, struct urb *urb)
@@ -117,7 +116,6 @@ static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int erro
r->rnf_error(r->r_data, urb, error);
}
spin_unlock_irqrestore(&mbus->lock, flags);
- return;
}
static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c
index c79a5e30d437..9e8639d4e862 100644
--- a/drivers/usb/musb/musb_debugfs.c
+++ b/drivers/usb/musb/musb_debugfs.c
@@ -195,15 +195,14 @@ static const struct file_operations musb_regdump_fops = {
static int musb_test_mode_open(struct inode *inode, struct file *file)
{
- file->private_data = inode->i_private;
-
return single_open(file, musb_test_mode_show, inode->i_private);
}
static ssize_t musb_test_mode_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
- struct musb *musb = file->private_data;
+ struct seq_file *s = file->private_data;
+ struct musb *musb = s->private;
u8 test = 0;
char buf[18];
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6fca870e957e..7cc713f187bc 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -829,7 +829,6 @@ void musb_g_rx(struct musb *musb, u8 epnum)
DBG(3, "packet waiting for %s%s request\n",
musb_ep->desc ? "" : "inactive ",
musb_ep->end_point.name);
- return;
}
/* ------------------------------------------------------------ */
@@ -1696,9 +1695,11 @@ void musb_gadget_cleanup(struct musb *musb)
* -ENOMEM no memeory to perform the operation
*
* @param driver the gadget driver
+ * @param bind the driver's bind function
* @return <0 if error, 0 if everything is fine
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ int (*bind)(struct usb_gadget *))
{
int retval;
unsigned long flags;
@@ -1706,8 +1707,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (!driver
|| driver->speed != USB_SPEED_HIGH
- || !driver->bind
- || !driver->setup)
+ || !bind || !driver->setup)
return -EINVAL;
/* driver must be initialized to support peripheral mode */
@@ -1735,7 +1735,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&musb->lock, flags);
if (retval == 0) {
- retval = driver->bind(&musb->g);
+ retval = bind(&musb->g);
if (retval != 0) {
DBG(3, "bind to driver %s failed --> %d\n",
driver->driver.name, retval);
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 3b1289572d72..299dfd2510cb 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -67,4 +67,18 @@ config NOP_USB_XCEIV
built-in with usb ip or which are autonomous and doesn't require any
phy programming such as ISP1x04 etc.
+config USB_LANGWELL_OTG
+ tristate "Intel Langwell USB OTG dual-role support"
+ depends on USB && X86_MRST
+ select USB_OTG
+ select USB_OTG_UTILS
+ help
+ Say Y here if you want to build Intel Langwell USB OTG
+ transciever driver in kernel. This driver implements role
+ switch between EHCI host driver and Langwell USB OTG
+ client driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called langwell_otg.
+
endif # USB || OTG
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index aeb49a8ec412..b6609db3a849 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_USB_LANGWELL_OTG) += langwell_otg.o
obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
obj-$(CONFIG_USB_ULPI) += ulpi.o
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
new file mode 100644
index 000000000000..879188086daf
--- /dev/null
+++ b/drivers/usb/otg/langwell_otg.c
@@ -0,0 +1,2408 @@
+/*
+ * Intel Langwell USB OTG transceiver driver
+ * Copyright (C) 2008 - 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.
+ *
+ */
+/* This driver helps to switch Langwell OTG controller function between host
+ * and peripheral. It works with EHCI driver and Langwell client controller
+ * driver together.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/moduleparam.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/hcd.h>
+#include <linux/notifier.h>
+#include <linux/delay.h>
+#include <asm/intel_scu_ipc.h>
+
+#include <linux/usb/langwell_otg.h>
+
+#define DRIVER_DESC "Intel Langwell USB OTG transceiver driver"
+#define DRIVER_VERSION "3.0.0.32L.0003"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+static const char driver_name[] = "langwell_otg";
+
+static int langwell_otg_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id);
+static void langwell_otg_remove(struct pci_dev *pdev);
+static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
+static int langwell_otg_resume(struct pci_dev *pdev);
+
+static int langwell_otg_set_host(struct otg_transceiver *otg,
+ struct usb_bus *host);
+static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
+ struct usb_gadget *gadget);
+static int langwell_otg_start_srp(struct otg_transceiver *otg);
+
+static const struct pci_device_id pci_ids[] = {{
+ .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
+ .class_mask = ~0,
+ .vendor = 0x8086,
+ .device = 0x0811,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+}, { /* end: all zeroes */ }
+};
+
+static struct pci_driver otg_pci_driver = {
+ .name = (char *) driver_name,
+ .id_table = pci_ids,
+
+ .probe = langwell_otg_probe,
+ .remove = langwell_otg_remove,
+
+ .suspend = langwell_otg_suspend,
+ .resume = langwell_otg_resume,
+};
+
+static const char *state_string(enum usb_otg_state state)
+{
+ switch (state) {
+ case OTG_STATE_A_IDLE:
+ return "a_idle";
+ case OTG_STATE_A_WAIT_VRISE:
+ return "a_wait_vrise";
+ case OTG_STATE_A_WAIT_BCON:
+ return "a_wait_bcon";
+ case OTG_STATE_A_HOST:
+ return "a_host";
+ case OTG_STATE_A_SUSPEND:
+ return "a_suspend";
+ case OTG_STATE_A_PERIPHERAL:
+ return "a_peripheral";
+ case OTG_STATE_A_WAIT_VFALL:
+ return "a_wait_vfall";
+ case OTG_STATE_A_VBUS_ERR:
+ return "a_vbus_err";
+ case OTG_STATE_B_IDLE:
+ return "b_idle";
+ case OTG_STATE_B_SRP_INIT:
+ return "b_srp_init";
+ case OTG_STATE_B_PERIPHERAL:
+ return "b_peripheral";
+ case OTG_STATE_B_WAIT_ACON:
+ return "b_wait_acon";
+ case OTG_STATE_B_HOST:
+ return "b_host";
+ default:
+ return "UNDEFINED";
+ }
+}
+
+/* HSM timers */
+static inline struct langwell_otg_timer *otg_timer_initializer
+(void (*function)(unsigned long), unsigned long expires, unsigned long data)
+{
+ struct langwell_otg_timer *timer;
+ timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
+ if (timer == NULL)
+ return timer;
+
+ timer->function = function;
+ timer->expires = expires;
+ timer->data = data;
+ return timer;
+}
+
+static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr,
+ *b_se0_srp_tmr, *b_srp_init_tmr;
+
+static struct list_head active_timers;
+
+static struct langwell_otg *the_transceiver;
+
+/* host/client notify transceiver when event affects HNP state */
+void langwell_update_transceiver(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+
+ dev_dbg(lnw->dev, "transceiver is updated\n");
+
+ if (!lnw->qwork)
+ return ;
+
+ queue_work(lnw->qwork, &lnw->work);
+}
+EXPORT_SYMBOL(langwell_update_transceiver);
+
+static int langwell_otg_set_host(struct otg_transceiver *otg,
+ struct usb_bus *host)
+{
+ otg->host = host;
+
+ return 0;
+}
+
+static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
+ struct usb_gadget *gadget)
+{
+ otg->gadget = gadget;
+
+ return 0;
+}
+
+static int langwell_otg_set_power(struct otg_transceiver *otg,
+ unsigned mA)
+{
+ return 0;
+}
+
+/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
+static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ u8 r;
+
+ dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off");
+
+ /* FIXME: surely we should cache this on the first read. If not use
+ readv to avoid two transactions */
+ if (intel_scu_ipc_ioread8(0x00, &r) < 0) {
+ dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
+ return -EBUSY;
+ }
+ if ((r & 0x03) != 0x02) {
+ dev_dbg(lnw->dev, "not NEC PMIC attached\n");
+ return -EBUSY;
+ }
+
+ if (intel_scu_ipc_ioread8(0x20, &r) < 0) {
+ dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
+ return -EBUSY;
+ }
+
+ if ((r & 0x20) == 0) {
+ dev_dbg(lnw->dev, "no battery attached\n");
+ return -EBUSY;
+ }
+
+ /* Workaround for battery attachment issue */
+ if (r == 0x34) {
+ dev_dbg(lnw->dev, "no battery attached on SH\n");
+ return -EBUSY;
+ }
+
+ dev_dbg(lnw->dev, "battery attached. 2 reg = %x\n", r);
+
+ /* workaround: FW detect writing 0x20/0xc0 to d4 event.
+ * this is only for NEC PMIC.
+ */
+
+ if (intel_scu_ipc_iowrite8(0xD4, enabled ? 0x20 : 0xC0))
+ dev_dbg(lnw->dev, "Failed to write PMIC.\n");
+
+ dev_dbg(lnw->dev, "%s --->\n", __func__);
+
+ return 0;
+}
+
+/* charge vbus or discharge vbus through a resistor to ground */
+static void langwell_otg_chrg_vbus(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ u32 val;
+
+ val = readl(lnw->iotg.base + CI_OTGSC);
+
+ if (on)
+ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
+ lnw->iotg.base + CI_OTGSC);
+ else
+ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
+ lnw->iotg.base + CI_OTGSC);
+}
+
+/* Start SRP */
+static int langwell_otg_start_srp(struct otg_transceiver *otg)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val;
+
+ dev_dbg(lnw->dev, "%s --->\n", __func__);
+
+ val = readl(iotg->base + CI_OTGSC);
+
+ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
+ iotg->base + CI_OTGSC);
+
+ /* Check if the data plus is finished or not */
+ msleep(8);
+ val = readl(iotg->base + CI_OTGSC);
+ if (val & (OTGSC_HADP | OTGSC_DP))
+ dev_dbg(lnw->dev, "DataLine SRP Error\n");
+
+ /* Disable interrupt - b_sess_vld */
+ val = readl(iotg->base + CI_OTGSC);
+ val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
+ writel(val, iotg->base + CI_OTGSC);
+
+ /* Start VBus SRP, drive vbus to generate VBus pulse */
+ iotg->otg.set_vbus(&iotg->otg, true);
+ msleep(15);
+ iotg->otg.set_vbus(&iotg->otg, false);
+
+ /* Enable interrupt - b_sess_vld*/
+ val = readl(iotg->base + CI_OTGSC);
+ dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val);
+
+ val |= (OTGSC_BSVIE | OTGSC_BSEIE);
+ writel(val, iotg->base + CI_OTGSC);
+
+ /* If Vbus is valid, then update the hsm */
+ if (val & OTGSC_BSV) {
+ dev_dbg(lnw->dev, "no b_sess_vld interrupt\n");
+
+ lnw->iotg.hsm.b_sess_vld = 1;
+ langwell_update_transceiver();
+ }
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+ return 0;
+}
+
+/* stop SOF via bus_suspend */
+static void langwell_otg_loc_sof(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct usb_hcd *hcd;
+ int err;
+
+ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume");
+
+ hcd = bus_to_hcd(lnw->iotg.otg.host);
+ if (on)
+ err = hcd->driver->bus_resume(hcd);
+ else
+ err = hcd->driver->bus_suspend(hcd);
+
+ if (err)
+ dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err);
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+}
+
+static int langwell_otg_check_otgsc(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ u32 otgsc, usbcfg;
+
+ dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n");
+
+ otgsc = readl(lnw->iotg.base + CI_OTGSC);
+ usbcfg = readl(lnw->usbcfg);
+
+ dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n",
+ otgsc, usbcfg);
+ dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV));
+ dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n",
+ !!(usbcfg & USBCFG_VBUSVAL));
+ dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV));
+ dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n",
+ !!(usbcfg & USBCFG_AVALID));
+ dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV));
+ dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n",
+ !!(usbcfg & USBCFG_BVALID));
+ dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE));
+ dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n",
+ !!(usbcfg & USBCFG_SESEND));
+
+ /* Check USBCFG VBusValid/AValid/BValid/SessEnd */
+ if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) {
+ dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n");
+ goto err;
+ }
+ if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) {
+ dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n");
+ goto err;
+ }
+ if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) {
+ dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n");
+ goto err;
+ }
+ if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) {
+ dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n");
+ goto err;
+ }
+
+ dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n");
+
+ return 0;
+
+err:
+ dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n");
+ return -EPIPE;
+}
+
+
+static void langwell_otg_phy_low_power(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u8 val, phcd;
+ int retval;
+
+ dev_dbg(lnw->dev, "%s ---> %s mode\n",
+ __func__, on ? "Low power" : "Normal");
+
+ phcd = 0x40;
+
+ val = readb(iotg->base + CI_HOSTPC1 + 2);
+
+ if (on) {
+ /* Due to hardware issue, after set PHCD, sync will failed
+ * between USBCFG and OTGSC, so before set PHCD, check if
+ * sync is in process now. If the answer is "yes", then do
+ * not touch PHCD bit */
+ retval = langwell_otg_check_otgsc();
+ if (retval) {
+ dev_dbg(lnw->dev, "Skip PHCD programming..\n");
+ return ;
+ }
+
+ writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2);
+ } else
+ writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2);
+
+ dev_dbg(lnw->dev, "%s <--- done\n", __func__);
+}
+
+/* After drv vbus, add 2 ms delay to set PHCD */
+static void langwell_otg_phy_low_power_wait(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+
+ dev_dbg(lnw->dev, "add 2ms delay before programing PHCD\n");
+
+ mdelay(2);
+ langwell_otg_phy_low_power(on);
+}
+
+/* Enable/Disable OTG interrupt */
+static void langwell_otg_intr(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val;
+
+ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+
+ val = readl(iotg->base + CI_OTGSC);
+
+ /* OTGSC_INT_MASK doesn't contains 1msInt */
+ if (on) {
+ val = val | (OTGSC_INT_MASK);
+ writel(val, iotg->base + CI_OTGSC);
+ } else {
+ val = val & ~(OTGSC_INT_MASK);
+ writel(val, iotg->base + CI_OTGSC);
+ }
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+}
+
+/* set HAAR: Hardware Assist Auto-Reset */
+static void langwell_otg_HAAR(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val;
+
+ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+
+ val = readl(iotg->base + CI_OTGSC);
+ if (on)
+ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
+ iotg->base + CI_OTGSC);
+ else
+ writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
+ iotg->base + CI_OTGSC);
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+}
+
+/* set HABA: Hardware Assist B-Disconnect to A-Connect */
+static void langwell_otg_HABA(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val;
+
+ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+
+ val = readl(iotg->base + CI_OTGSC);
+ if (on)
+ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
+ iotg->base + CI_OTGSC);
+ else
+ writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
+ iotg->base + CI_OTGSC);
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+}
+
+static int langwell_otg_check_se0_srp(int on)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ int delay_time = TB_SE0_SRP * 10;
+ u32 val;
+
+ dev_dbg(lnw->dev, "%s --->\n", __func__);
+
+ do {
+ udelay(100);
+ if (!delay_time--)
+ break;
+ val = readl(lnw->iotg.base + CI_PORTSC1);
+ val &= PORTSC_LS;
+ } while (!val);
+
+ dev_dbg(lnw->dev, "%s <---\n", __func__);
+ return val;
+}
+
+/* The timeout callback function to set time out bit */
+static void set_tmout(unsigned long indicator)
+{
+ *(int *)indicator = 1;
+}
+
+void langwell_otg_nsf_msg(unsigned long indicator)
+{
+ struct langwell_otg *lnw = the_transceiver;
+
+ switch (indicator) {
+ case 2:
+ case 4:
+ case 6:
+ case 7:
+ dev_warn(lnw->dev,
+ "OTG:NSF-%lu - deivce not responding\n", indicator);
+ break;
+ case 3:
+ dev_warn(lnw->dev,
+ "OTG:NSF-%lu - deivce not supported\n", indicator);
+ break;
+ default:
+ dev_warn(lnw->dev, "Do not have this kind of NSF\n");
+ break;
+ }
+}
+
+/* Initialize timers */
+static int langwell_otg_init_timers(struct otg_hsm *hsm)
+{
+ /* HSM used timers */
+ a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
+ (unsigned long)&hsm->a_wait_vrise_tmout);
+ if (a_wait_vrise_tmr == NULL)
+ return -ENOMEM;
+ a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
+ (unsigned long)&hsm->a_aidl_bdis_tmout);
+ if (a_aidl_bdis_tmr == NULL)
+ return -ENOMEM;
+ b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
+ (unsigned long)&hsm->b_se0_srp);
+ if (b_se0_srp_tmr == NULL)
+ return -ENOMEM;
+ b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT,
+ (unsigned long)&hsm->b_srp_init_tmout);
+ if (b_srp_init_tmr == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/* Free timers */
+static void langwell_otg_free_timers(void)
+{
+ kfree(a_wait_vrise_tmr);
+ kfree(a_aidl_bdis_tmr);
+ kfree(b_se0_srp_tmr);
+ kfree(b_srp_init_tmr);
+}
+
+/* The timeout callback function to set time out bit */
+static void langwell_otg_timer_fn(unsigned long indicator)
+{
+ struct langwell_otg *lnw = the_transceiver;
+
+ *(int *)indicator = 1;
+
+ dev_dbg(lnw->dev, "kernel timer - timeout\n");
+
+ langwell_update_transceiver();
+}
+
+/* kernel timer used instead of HW based interrupt */
+static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ unsigned long j = jiffies;
+ unsigned long data, time;
+
+ switch (timers) {
+ case TA_WAIT_VRISE_TMR:
+ iotg->hsm.a_wait_vrise_tmout = 0;
+ data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout;
+ time = TA_WAIT_VRISE;
+ break;
+ case TA_WAIT_BCON_TMR:
+ iotg->hsm.a_wait_bcon_tmout = 0;
+ data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout;
+ time = TA_WAIT_BCON;
+ break;
+ case TA_AIDL_BDIS_TMR:
+ iotg->hsm.a_aidl_bdis_tmout = 0;
+ data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout;
+ time = TA_AIDL_BDIS;
+ break;
+ case TB_ASE0_BRST_TMR:
+ iotg->hsm.b_ase0_brst_tmout = 0;
+ data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout;
+ time = TB_ASE0_BRST;
+ break;
+ case TB_SRP_INIT_TMR:
+ iotg->hsm.b_srp_init_tmout = 0;
+ data = (unsigned long)&iotg->hsm.b_srp_init_tmout;
+ time = TB_SRP_INIT;
+ break;
+ case TB_SRP_FAIL_TMR:
+ iotg->hsm.b_srp_fail_tmout = 0;
+ data = (unsigned long)&iotg->hsm.b_srp_fail_tmout;
+ time = TB_SRP_FAIL;
+ break;
+ case TB_BUS_SUSPEND_TMR:
+ iotg->hsm.b_bus_suspend_tmout = 0;
+ data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout;
+ time = TB_BUS_SUSPEND;
+ break;
+ default:
+ dev_dbg(lnw->dev, "unkown timer, cannot enable it\n");
+ return;
+ }
+
+ lnw->hsm_timer.data = data;
+ lnw->hsm_timer.function = langwell_otg_timer_fn;
+ lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */
+
+ add_timer(&lnw->hsm_timer);
+
+ dev_dbg(lnw->dev, "add timer successfully\n");
+}
+
+/* Add timer to timer list */
+static void langwell_otg_add_timer(void *gtimer)
+{
+ struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
+ struct langwell_otg_timer *tmp_timer;
+ struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg;
+ u32 val32;
+
+ /* Check if the timer is already in the active list,
+ * if so update timer count
+ */
+ list_for_each_entry(tmp_timer, &active_timers, list)
+ if (tmp_timer == timer) {
+ timer->count = timer->expires;
+ return;
+ }
+ timer->count = timer->expires;
+
+ if (list_empty(&active_timers)) {
+ val32 = readl(iotg->base + CI_OTGSC);
+ writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC);
+ }
+
+ list_add_tail(&timer->list, &active_timers);
+}
+
+/* Remove timer from the timer list; clear timeout status */
+static void langwell_otg_del_timer(void *gtimer)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
+ struct langwell_otg_timer *tmp_timer, *del_tmp;
+ u32 val32;
+
+ list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
+ if (tmp_timer == timer)
+ list_del(&timer->list);
+
+ if (list_empty(&active_timers)) {
+ val32 = readl(lnw->iotg.base + CI_OTGSC);
+ writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC);
+ }
+}
+
+/* Reduce timer count by 1, and find timeout conditions.*/
+static int langwell_otg_tick_timer(u32 *int_sts)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct langwell_otg_timer *tmp_timer, *del_tmp;
+ int expired = 0;
+
+ list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
+ tmp_timer->count--;
+ /* check if timer expires */
+ if (!tmp_timer->count) {
+ list_del(&tmp_timer->list);
+ tmp_timer->function(tmp_timer->data);
+ expired = 1;
+ }
+ }
+
+ if (list_empty(&active_timers)) {
+ dev_dbg(lnw->dev, "tick timer: disable 1ms int\n");
+ *int_sts = *int_sts & ~OTGSC_1MSE;
+ }
+ return expired;
+}
+
+static void reset_otg(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ int delay_time = 1000;
+ u32 val;
+
+ dev_dbg(lnw->dev, "reseting OTG controller ...\n");
+ val = readl(lnw->iotg.base + CI_USBCMD);
+ writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD);
+ do {
+ udelay(100);
+ if (!delay_time--)
+ dev_dbg(lnw->dev, "reset timeout\n");
+ val = readl(lnw->iotg.base + CI_USBCMD);
+ val &= USBCMD_RST;
+ } while (val != 0);
+ dev_dbg(lnw->dev, "reset done.\n");
+}
+
+static void set_host_mode(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ u32 val;
+
+ reset_otg();
+ val = readl(lnw->iotg.base + CI_USBMODE);
+ val = (val & (~USBMODE_CM)) | USBMODE_HOST;
+ writel(val, lnw->iotg.base + CI_USBMODE);
+}
+
+static void set_client_mode(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ u32 val;
+
+ reset_otg();
+ val = readl(lnw->iotg.base + CI_USBMODE);
+ val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
+ writel(val, lnw->iotg.base + CI_USBMODE);
+}
+
+static void init_hsm(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val32;
+
+ /* read OTGSC after reset */
+ val32 = readl(lnw->iotg.base + CI_OTGSC);
+ dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32);
+
+ /* set init state */
+ if (val32 & OTGSC_ID) {
+ iotg->hsm.id = 1;
+ iotg->otg.default_a = 0;
+ set_client_mode();
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ } else {
+ iotg->hsm.id = 0;
+ iotg->otg.default_a = 1;
+ set_host_mode();
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ }
+
+ /* set session indicator */
+ if (val32 & OTGSC_BSE)
+ iotg->hsm.b_sess_end = 1;
+ if (val32 & OTGSC_BSV)
+ iotg->hsm.b_sess_vld = 1;
+ if (val32 & OTGSC_ASV)
+ iotg->hsm.a_sess_vld = 1;
+ if (val32 & OTGSC_AVV)
+ iotg->hsm.a_vbus_vld = 1;
+
+ /* defautly power the bus */
+ iotg->hsm.a_bus_req = 1;
+ iotg->hsm.a_bus_drop = 0;
+ /* defautly don't request bus as B device */
+ iotg->hsm.b_bus_req = 0;
+ /* no system error */
+ iotg->hsm.a_clr_err = 0;
+
+ langwell_otg_phy_low_power_wait(1);
+}
+
+static void update_hsm(void)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 val32;
+
+ /* read OTGSC */
+ val32 = readl(lnw->iotg.base + CI_OTGSC);
+ dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
+
+ iotg->hsm.id = !!(val32 & OTGSC_ID);
+ iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
+ iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
+ iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
+ iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
+}
+
+static irqreturn_t otg_dummy_irq(int irq, void *_dev)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ void __iomem *reg_base = _dev;
+ u32 val;
+ u32 int_mask = 0;
+
+ val = readl(reg_base + CI_USBMODE);
+ if ((val & USBMODE_CM) != USBMODE_DEVICE)
+ return IRQ_NONE;
+
+ val = readl(reg_base + CI_USBSTS);
+ int_mask = val & INTR_DUMMY_MASK;
+
+ if (int_mask == 0)
+ return IRQ_NONE;
+
+ /* clear hsm.b_conn here since host driver can't detect it
+ * otg_dummy_irq called means B-disconnect happened.
+ */
+ if (lnw->iotg.hsm.b_conn) {
+ lnw->iotg.hsm.b_conn = 0;
+ if (spin_trylock(&lnw->wq_lock)) {
+ langwell_update_transceiver();
+ spin_unlock(&lnw->wq_lock);
+ }
+ }
+
+ /* Clear interrupts */
+ writel(int_mask, reg_base + CI_USBSTS);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t otg_irq(int irq, void *_dev)
+{
+ struct langwell_otg *lnw = _dev;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ u32 int_sts, int_en;
+ u32 int_mask = 0;
+ int flag = 0;
+
+ int_sts = readl(lnw->iotg.base + CI_OTGSC);
+ int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
+ int_mask = int_sts & int_en;
+ if (int_mask == 0)
+ return IRQ_NONE;
+
+ if (int_mask & OTGSC_IDIS) {
+ dev_dbg(lnw->dev, "%s: id change int\n", __func__);
+ iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
+ dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id);
+ flag = 1;
+ }
+ if (int_mask & OTGSC_DPIS) {
+ dev_dbg(lnw->dev, "%s: data pulse int\n", __func__);
+ iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
+ dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det);
+ flag = 1;
+ }
+ if (int_mask & OTGSC_BSEIS) {
+ dev_dbg(lnw->dev, "%s: b session end int\n", __func__);
+ iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
+ dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end);
+ flag = 1;
+ }
+ if (int_mask & OTGSC_BSVIS) {
+ dev_dbg(lnw->dev, "%s: b session valid int\n", __func__);
+ iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
+ dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end);
+ flag = 1;
+ }
+ if (int_mask & OTGSC_ASVIS) {
+ dev_dbg(lnw->dev, "%s: a session valid int\n", __func__);
+ iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
+ dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld);
+ flag = 1;
+ }
+ if (int_mask & OTGSC_AVVIS) {
+ dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__);
+ iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
+ dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld);
+ flag = 1;
+ }
+
+ if (int_mask & OTGSC_1MSS) {
+ /* need to schedule otg_work if any timer is expired */
+ if (langwell_otg_tick_timer(&int_sts))
+ flag = 1;
+ }
+
+ writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
+ lnw->iotg.base + CI_OTGSC);
+ if (flag)
+ langwell_update_transceiver();
+
+ return IRQ_HANDLED;
+}
+
+static int langwell_otg_iotg_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = data;
+ int flag = 0;
+
+ if (iotg == NULL)
+ return NOTIFY_BAD;
+
+ if (lnw == NULL)
+ return NOTIFY_BAD;
+
+ switch (action) {
+ case MID_OTG_NOTIFY_CONNECT:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n");
+ if (iotg->otg.default_a == 1)
+ iotg->hsm.b_conn = 1;
+ else
+ iotg->hsm.a_conn = 1;
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_DISCONN:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n");
+ if (iotg->otg.default_a == 1)
+ iotg->hsm.b_conn = 0;
+ else
+ iotg->hsm.a_conn = 0;
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_HSUSPEND:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n");
+ if (iotg->otg.default_a == 1)
+ iotg->hsm.a_suspend_req = 1;
+ else
+ iotg->hsm.b_bus_req = 0;
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_HRESUME:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n");
+ if (iotg->otg.default_a == 1)
+ iotg->hsm.b_bus_resume = 1;
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_CSUSPEND:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n");
+ if (iotg->otg.default_a == 1) {
+ if (iotg->hsm.b_bus_suspend_vld == 2) {
+ iotg->hsm.b_bus_suspend = 1;
+ iotg->hsm.b_bus_suspend_vld = 0;
+ flag = 1;
+ } else {
+ iotg->hsm.b_bus_suspend_vld++;
+ flag = 0;
+ }
+ } else {
+ if (iotg->hsm.a_bus_suspend == 0) {
+ iotg->hsm.a_bus_suspend = 1;
+ flag = 1;
+ }
+ }
+ break;
+ case MID_OTG_NOTIFY_CRESUME:
+ dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n");
+ if (iotg->otg.default_a == 0)
+ iotg->hsm.a_bus_suspend = 0;
+ flag = 0;
+ break;
+ case MID_OTG_NOTIFY_HOSTADD:
+ dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n");
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_HOSTREMOVE:
+ dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n");
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_CLIENTADD:
+ dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n");
+ flag = 1;
+ break;
+ case MID_OTG_NOTIFY_CLIENTREMOVE:
+ dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n");
+ flag = 1;
+ break;
+ default:
+ dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n");
+ return NOTIFY_DONE;
+ }
+
+ if (flag)
+ langwell_update_transceiver();
+
+ return NOTIFY_OK;
+}
+
+static void langwell_otg_work(struct work_struct *work)
+{
+ struct langwell_otg *lnw;
+ struct intel_mid_otg_xceiv *iotg;
+ int retval;
+ struct pci_dev *pdev;
+
+ lnw = container_of(work, struct langwell_otg, work);
+ iotg = &lnw->iotg;
+ pdev = to_pci_dev(lnw->dev);
+
+ dev_dbg(lnw->dev, "%s: old state = %s\n", __func__,
+ state_string(iotg->otg.state));
+
+ switch (iotg->otg.state) {
+ case OTG_STATE_UNDEFINED:
+ case OTG_STATE_B_IDLE:
+ if (!iotg->hsm.id) {
+ langwell_otg_del_timer(b_srp_init_tmr);
+ del_timer_sync(&lnw->hsm_timer);
+
+ iotg->otg.default_a = 1;
+ iotg->hsm.a_srp_det = 0;
+
+ langwell_otg_chrg_vbus(0);
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.b_sess_vld) {
+ langwell_otg_del_timer(b_srp_init_tmr);
+ del_timer_sync(&lnw->hsm_timer);
+ iotg->hsm.b_sess_end = 0;
+ iotg->hsm.a_bus_suspend = 0;
+ langwell_otg_chrg_vbus(0);
+
+ if (lnw->iotg.start_peripheral) {
+ lnw->iotg.start_peripheral(&lnw->iotg);
+ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
+ } else
+ dev_dbg(lnw->dev, "client driver not loaded\n");
+
+ } else if (iotg->hsm.b_srp_init_tmout) {
+ iotg->hsm.b_srp_init_tmout = 0;
+ dev_warn(lnw->dev, "SRP init timeout\n");
+ } else if (iotg->hsm.b_srp_fail_tmout) {
+ iotg->hsm.b_srp_fail_tmout = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ /* No silence failure */
+ langwell_otg_nsf_msg(6);
+ } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) {
+ del_timer_sync(&lnw->hsm_timer);
+ /* workaround for b_se0_srp detection */
+ retval = langwell_otg_check_se0_srp(0);
+ if (retval) {
+ iotg->hsm.b_bus_req = 0;
+ dev_dbg(lnw->dev, "LS isn't SE0, try later\n");
+ } else {
+ /* clear the PHCD before start srp */
+ langwell_otg_phy_low_power(0);
+
+ /* Start SRP */
+ langwell_otg_add_timer(b_srp_init_tmr);
+ iotg->otg.start_srp(&iotg->otg);
+ langwell_otg_del_timer(b_srp_init_tmr);
+ langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
+
+ /* reset PHY low power mode here */
+ langwell_otg_phy_low_power_wait(1);
+ }
+ }
+ break;
+ case OTG_STATE_B_SRP_INIT:
+ if (!iotg->hsm.id) {
+ iotg->otg.default_a = 1;
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_chrg_vbus(0);
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.b_sess_vld) {
+ langwell_otg_chrg_vbus(0);
+ if (lnw->iotg.start_peripheral) {
+ lnw->iotg.start_peripheral(&lnw->iotg);
+ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
+ } else
+ dev_dbg(lnw->dev, "client driver not loaded\n");
+ }
+ break;
+ case OTG_STATE_B_PERIPHERAL:
+ if (!iotg->hsm.id) {
+ iotg->otg.default_a = 1;
+ iotg->hsm.a_srp_det = 0;
+
+ langwell_otg_chrg_vbus(0);
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.b_sess_vld) {
+ iotg->hsm.b_hnp_enable = 0;
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ } else if (iotg->hsm.b_bus_req && iotg->otg.gadget &&
+ iotg->otg.gadget->b_hnp_enable &&
+ iotg->hsm.a_bus_suspend) {
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ langwell_otg_HAAR(1);
+ iotg->hsm.a_conn = 0;
+
+ if (lnw->iotg.start_host) {
+ lnw->iotg.start_host(&lnw->iotg);
+ iotg->otg.state = OTG_STATE_B_WAIT_ACON;
+ } else
+ dev_dbg(lnw->dev,
+ "host driver not loaded.\n");
+
+ iotg->hsm.a_bus_resume = 0;
+ langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
+ }
+ break;
+
+ case OTG_STATE_B_WAIT_ACON:
+ if (!iotg->hsm.id) {
+ /* delete hsm timer for b_ase0_brst_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ iotg->otg.default_a = 1;
+ iotg->hsm.a_srp_det = 0;
+
+ langwell_otg_chrg_vbus(0);
+
+ langwell_otg_HAAR(0);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.b_sess_vld) {
+ /* delete hsm timer for b_ase0_brst_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ iotg->hsm.b_hnp_enable = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ langwell_otg_chrg_vbus(0);
+ langwell_otg_HAAR(0);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ } else if (iotg->hsm.a_conn) {
+ /* delete hsm timer for b_ase0_brst_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ langwell_otg_HAAR(0);
+ iotg->otg.state = OTG_STATE_B_HOST;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.a_bus_resume ||
+ iotg->hsm.b_ase0_brst_tmout) {
+ /* delete hsm timer for b_ase0_brst_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ langwell_otg_HAAR(0);
+ langwell_otg_nsf_msg(7);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ iotg->hsm.a_bus_suspend = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ if (lnw->iotg.start_peripheral)
+ lnw->iotg.start_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver not loaded.\n");
+
+ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
+ }
+ break;
+
+ case OTG_STATE_B_HOST:
+ if (!iotg->hsm.id) {
+ iotg->otg.default_a = 1;
+ iotg->hsm.a_srp_det = 0;
+
+ langwell_otg_chrg_vbus(0);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.b_sess_vld) {
+ iotg->hsm.b_hnp_enable = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ langwell_otg_chrg_vbus(0);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ } else if ((!iotg->hsm.b_bus_req) ||
+ (!iotg->hsm.a_conn)) {
+ iotg->hsm.b_bus_req = 0;
+ langwell_otg_loc_sof(0);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ iotg->hsm.a_bus_suspend = 0;
+
+ if (lnw->iotg.start_peripheral)
+ lnw->iotg.start_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver not loaded.\n");
+
+ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
+ }
+ break;
+
+ case OTG_STATE_A_IDLE:
+ iotg->otg.default_a = 1;
+ if (iotg->hsm.id) {
+ iotg->otg.default_a = 0;
+ iotg->hsm.b_bus_req = 0;
+ iotg->hsm.vbus_srp_up = 0;
+
+ langwell_otg_chrg_vbus(0);
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.a_bus_drop &&
+ (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) {
+ langwell_otg_phy_low_power(0);
+
+ /* Turn on VBus */
+ iotg->otg.set_vbus(&iotg->otg, true);
+
+ iotg->hsm.vbus_srp_up = 0;
+ iotg->hsm.a_wait_vrise_tmout = 0;
+ langwell_otg_add_timer(a_wait_vrise_tmr);
+ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) {
+ iotg->hsm.vbus_srp_up = 1;
+ } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) {
+ msleep(10);
+ langwell_otg_phy_low_power(0);
+
+ /* Turn on VBus */
+ iotg->otg.set_vbus(&iotg->otg, true);
+ iotg->hsm.a_srp_det = 1;
+ iotg->hsm.vbus_srp_up = 0;
+ iotg->hsm.a_wait_vrise_tmout = 0;
+ langwell_otg_add_timer(a_wait_vrise_tmr);
+ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.a_sess_vld &&
+ !iotg->hsm.vbus_srp_up) {
+ langwell_otg_phy_low_power(1);
+ }
+ break;
+ case OTG_STATE_A_WAIT_VRISE:
+ if (iotg->hsm.id) {
+ langwell_otg_del_timer(a_wait_vrise_tmr);
+ iotg->hsm.b_bus_req = 0;
+ iotg->otg.default_a = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ set_client_mode();
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ } else if (iotg->hsm.a_vbus_vld) {
+ langwell_otg_del_timer(a_wait_vrise_tmr);
+ iotg->hsm.b_conn = 0;
+ if (lnw->iotg.start_host)
+ lnw->iotg.start_host(&lnw->iotg);
+ else {
+ dev_dbg(lnw->dev, "host driver not loaded.\n");
+ break;
+ }
+
+ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
+ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+ } else if (iotg->hsm.a_wait_vrise_tmout) {
+ iotg->hsm.b_conn = 0;
+ if (iotg->hsm.a_vbus_vld) {
+ if (lnw->iotg.start_host)
+ lnw->iotg.start_host(&lnw->iotg);
+ else {
+ dev_dbg(lnw->dev,
+ "host driver not loaded.\n");
+ break;
+ }
+ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
+ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+ } else {
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+ }
+ }
+ break;
+ case OTG_STATE_A_WAIT_BCON:
+ if (iotg->hsm.id) {
+ /* delete hsm timer for a_wait_bcon_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ iotg->otg.default_a = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ set_client_mode();
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.a_vbus_vld) {
+ /* delete hsm timer for a_wait_bcon_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+ } else if (iotg->hsm.a_bus_drop ||
+ (iotg->hsm.a_wait_bcon_tmout &&
+ !iotg->hsm.a_bus_req)) {
+ /* delete hsm timer for a_wait_bcon_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+ } else if (iotg->hsm.b_conn) {
+ /* delete hsm timer for a_wait_bcon_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ iotg->hsm.a_suspend_req = 0;
+ iotg->otg.state = OTG_STATE_A_HOST;
+ if (iotg->hsm.a_srp_det && iotg->otg.host &&
+ !iotg->otg.host->b_hnp_enable) {
+ /* SRP capable peripheral-only device */
+ iotg->hsm.a_bus_req = 1;
+ iotg->hsm.a_srp_det = 0;
+ } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
+ iotg->otg.host->b_hnp_enable) {
+ /* It is not safe enough to do a fast
+ * transistion from A_WAIT_BCON to
+ * A_SUSPEND */
+ msleep(10000);
+ if (iotg->hsm.a_bus_req)
+ break;
+
+ if (request_irq(pdev->irq,
+ otg_dummy_irq, IRQF_SHARED,
+ driver_name, iotg->base) != 0) {
+ dev_dbg(lnw->dev,
+ "request interrupt %d fail\n",
+ pdev->irq);
+ }
+
+ langwell_otg_HABA(1);
+ iotg->hsm.b_bus_resume = 0;
+ iotg->hsm.a_aidl_bdis_tmout = 0;
+
+ langwell_otg_loc_sof(0);
+ /* clear PHCD to enable HW timer */
+ langwell_otg_phy_low_power(0);
+ langwell_otg_add_timer(a_aidl_bdis_tmr);
+ iotg->otg.state = OTG_STATE_A_SUSPEND;
+ } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
+ !iotg->otg.host->b_hnp_enable) {
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+ }
+ }
+ break;
+ case OTG_STATE_A_HOST:
+ if (iotg->hsm.id) {
+ iotg->otg.default_a = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ set_client_mode();
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.a_bus_drop ||
+ (iotg->otg.host &&
+ !iotg->otg.host->b_hnp_enable &&
+ !iotg->hsm.a_bus_req)) {
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+ } else if (!iotg->hsm.a_vbus_vld) {
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+ } else if (iotg->otg.host &&
+ iotg->otg.host->b_hnp_enable &&
+ !iotg->hsm.a_bus_req) {
+ /* Set HABA to enable hardware assistance to signal
+ * A-connect after receiver B-disconnect. Hardware
+ * will then set client mode and enable URE, SLE and
+ * PCE after the assistance. otg_dummy_irq is used to
+ * clean these ints when client driver is not resumed.
+ */
+ if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED,
+ driver_name, iotg->base) != 0) {
+ dev_dbg(lnw->dev,
+ "request interrupt %d failed\n",
+ pdev->irq);
+ }
+
+ /* set HABA */
+ langwell_otg_HABA(1);
+ iotg->hsm.b_bus_resume = 0;
+ iotg->hsm.a_aidl_bdis_tmout = 0;
+ langwell_otg_loc_sof(0);
+ /* clear PHCD to enable HW timer */
+ langwell_otg_phy_low_power(0);
+ langwell_otg_add_timer(a_aidl_bdis_tmr);
+ iotg->otg.state = OTG_STATE_A_SUSPEND;
+ } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) {
+ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
+ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+ }
+ break;
+ case OTG_STATE_A_SUSPEND:
+ if (iotg->hsm.id) {
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ free_irq(pdev->irq, iotg->base);
+ iotg->otg.default_a = 0;
+ iotg->hsm.b_bus_req = 0;
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.a_bus_req ||
+ iotg->hsm.b_bus_resume) {
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ free_irq(pdev->irq, iotg->base);
+ iotg->hsm.a_suspend_req = 0;
+ langwell_otg_loc_sof(1);
+ iotg->otg.state = OTG_STATE_A_HOST;
+ } else if (iotg->hsm.a_aidl_bdis_tmout ||
+ iotg->hsm.a_bus_drop) {
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ free_irq(pdev->irq, iotg->base);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+ } else if (!iotg->hsm.b_conn && iotg->otg.host &&
+ iotg->otg.host->b_hnp_enable) {
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ free_irq(pdev->irq, iotg->base);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ iotg->hsm.b_bus_suspend = 0;
+ iotg->hsm.b_bus_suspend_vld = 0;
+
+ /* msleep(200); */
+ if (lnw->iotg.start_peripheral)
+ lnw->iotg.start_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver not loaded.\n");
+
+ langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
+ iotg->otg.state = OTG_STATE_A_PERIPHERAL;
+ break;
+ } else if (!iotg->hsm.a_vbus_vld) {
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ free_irq(pdev->irq, iotg->base);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+ }
+ break;
+ case OTG_STATE_A_PERIPHERAL:
+ if (iotg->hsm.id) {
+ /* delete hsm timer for b_bus_suspend_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+ iotg->otg.default_a = 0;
+ iotg->hsm.b_bus_req = 0;
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ set_client_mode();
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (!iotg->hsm.a_vbus_vld) {
+ /* delete hsm timer for b_bus_suspend_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ langwell_otg_phy_low_power_wait(1);
+ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+ } else if (iotg->hsm.a_bus_drop) {
+ /* delete hsm timer for b_bus_suspend_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+ } else if (iotg->hsm.b_bus_suspend) {
+ /* delete hsm timer for b_bus_suspend_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ if (lnw->iotg.start_host)
+ lnw->iotg.start_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver not loaded.\n");
+ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
+ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+ } else if (iotg->hsm.b_bus_suspend_tmout) {
+ u32 val;
+ val = readl(lnw->iotg.base + CI_PORTSC1);
+ if (!(val & PORTSC_SUSP))
+ break;
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "client driver has been removed.\n");
+
+ if (lnw->iotg.start_host)
+ lnw->iotg.start_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev,
+ "host driver not loaded.\n");
+ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
+ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+ }
+ break;
+ case OTG_STATE_A_VBUS_ERR:
+ if (iotg->hsm.id) {
+ iotg->otg.default_a = 0;
+ iotg->hsm.a_clr_err = 0;
+ iotg->hsm.a_srp_det = 0;
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.a_clr_err) {
+ iotg->hsm.a_clr_err = 0;
+ iotg->hsm.a_srp_det = 0;
+ reset_otg();
+ init_hsm();
+ if (iotg->otg.state == OTG_STATE_A_IDLE)
+ langwell_update_transceiver();
+ } else {
+ /* FW will clear PHCD bit when any VBus
+ * event detected. Reset PHCD to 1 again */
+ langwell_otg_phy_low_power(1);
+ }
+ break;
+ case OTG_STATE_A_WAIT_VFALL:
+ if (iotg->hsm.id) {
+ iotg->otg.default_a = 0;
+ set_client_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ langwell_update_transceiver();
+ } else if (iotg->hsm.a_bus_req) {
+
+ /* Turn on VBus */
+ iotg->otg.set_vbus(&iotg->otg, true);
+ iotg->hsm.a_wait_vrise_tmout = 0;
+ langwell_otg_add_timer(a_wait_vrise_tmr);
+ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+ } else if (!iotg->hsm.a_sess_vld) {
+ iotg->hsm.a_srp_det = 0;
+ set_host_mode();
+ langwell_otg_phy_low_power(1);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ }
+ break;
+ default:
+ ;
+ }
+
+ dev_dbg(lnw->dev, "%s: new state = %s\n", __func__,
+ state_string(iotg->otg.state));
+}
+
+static ssize_t
+show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ char *next;
+ unsigned size, t;
+
+ next = buf;
+ size = PAGE_SIZE;
+
+ t = scnprintf(next, size,
+ "\n"
+ "USBCMD = 0x%08x\n"
+ "USBSTS = 0x%08x\n"
+ "USBINTR = 0x%08x\n"
+ "ASYNCLISTADDR = 0x%08x\n"
+ "PORTSC1 = 0x%08x\n"
+ "HOSTPC1 = 0x%08x\n"
+ "OTGSC = 0x%08x\n"
+ "USBMODE = 0x%08x\n",
+ readl(lnw->iotg.base + 0x30),
+ readl(lnw->iotg.base + 0x34),
+ readl(lnw->iotg.base + 0x38),
+ readl(lnw->iotg.base + 0x48),
+ readl(lnw->iotg.base + 0x74),
+ readl(lnw->iotg.base + 0xb4),
+ readl(lnw->iotg.base + 0xf4),
+ readl(lnw->iotg.base + 0xf8)
+ );
+ size -= t;
+ next += t;
+
+ return PAGE_SIZE - size;
+}
+static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
+
+static ssize_t
+show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ char *next;
+ unsigned size, t;
+
+ next = buf;
+ size = PAGE_SIZE;
+
+ if (iotg->otg.host)
+ iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable;
+
+ if (iotg->otg.gadget)
+ iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable;
+
+ t = scnprintf(next, size,
+ "\n"
+ "current state = %s\n"
+ "a_bus_resume = \t%d\n"
+ "a_bus_suspend = \t%d\n"
+ "a_conn = \t%d\n"
+ "a_sess_vld = \t%d\n"
+ "a_srp_det = \t%d\n"
+ "a_vbus_vld = \t%d\n"
+ "b_bus_resume = \t%d\n"
+ "b_bus_suspend = \t%d\n"
+ "b_conn = \t%d\n"
+ "b_se0_srp = \t%d\n"
+ "b_sess_end = \t%d\n"
+ "b_sess_vld = \t%d\n"
+ "id = \t%d\n"
+ "a_set_b_hnp_en = \t%d\n"
+ "b_srp_done = \t%d\n"
+ "b_hnp_enable = \t%d\n"
+ "a_wait_vrise_tmout = \t%d\n"
+ "a_wait_bcon_tmout = \t%d\n"
+ "a_aidl_bdis_tmout = \t%d\n"
+ "b_ase0_brst_tmout = \t%d\n"
+ "a_bus_drop = \t%d\n"
+ "a_bus_req = \t%d\n"
+ "a_clr_err = \t%d\n"
+ "a_suspend_req = \t%d\n"
+ "b_bus_req = \t%d\n"
+ "b_bus_suspend_tmout = \t%d\n"
+ "b_bus_suspend_vld = \t%d\n",
+ state_string(iotg->otg.state),
+ iotg->hsm.a_bus_resume,
+ iotg->hsm.a_bus_suspend,
+ iotg->hsm.a_conn,
+ iotg->hsm.a_sess_vld,
+ iotg->hsm.a_srp_det,
+ iotg->hsm.a_vbus_vld,
+ iotg->hsm.b_bus_resume,
+ iotg->hsm.b_bus_suspend,
+ iotg->hsm.b_conn,
+ iotg->hsm.b_se0_srp,
+ iotg->hsm.b_sess_end,
+ iotg->hsm.b_sess_vld,
+ iotg->hsm.id,
+ iotg->hsm.a_set_b_hnp_en,
+ iotg->hsm.b_srp_done,
+ iotg->hsm.b_hnp_enable,
+ iotg->hsm.a_wait_vrise_tmout,
+ iotg->hsm.a_wait_bcon_tmout,
+ iotg->hsm.a_aidl_bdis_tmout,
+ iotg->hsm.b_ase0_brst_tmout,
+ iotg->hsm.a_bus_drop,
+ iotg->hsm.a_bus_req,
+ iotg->hsm.a_clr_err,
+ iotg->hsm.a_suspend_req,
+ iotg->hsm.b_bus_req,
+ iotg->hsm.b_bus_suspend_tmout,
+ iotg->hsm.b_bus_suspend_vld
+ );
+ size -= t;
+ next += t;
+
+ return PAGE_SIZE - size;
+}
+static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
+
+static ssize_t
+get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ char *next;
+ unsigned size, t;
+
+ next = buf;
+ size = PAGE_SIZE;
+
+ t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req);
+ size -= t;
+ next += t;
+
+ return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_a_bus_req(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+
+ if (!iotg->otg.default_a)
+ return -1;
+ if (count > 2)
+ return -1;
+
+ if (buf[0] == '0') {
+ iotg->hsm.a_bus_req = 0;
+ dev_dbg(lnw->dev, "User request: a_bus_req = 0\n");
+ } else if (buf[0] == '1') {
+ /* If a_bus_drop is TRUE, a_bus_req can't be set */
+ if (iotg->hsm.a_bus_drop)
+ return -1;
+ iotg->hsm.a_bus_req = 1;
+ dev_dbg(lnw->dev, "User request: a_bus_req = 1\n");
+ }
+ if (spin_trylock(&lnw->wq_lock)) {
+ langwell_update_transceiver();
+ spin_unlock(&lnw->wq_lock);
+ }
+ return count;
+}
+static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
+
+static ssize_t
+get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ char *next;
+ unsigned size, t;
+
+ next = buf;
+ size = PAGE_SIZE;
+
+ t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop);
+ size -= t;
+ next += t;
+
+ return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_a_bus_drop(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+
+ if (!iotg->otg.default_a)
+ return -1;
+ if (count > 2)
+ return -1;
+
+ if (buf[0] == '0') {
+ iotg->hsm.a_bus_drop = 0;
+ dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n");
+ } else if (buf[0] == '1') {
+ iotg->hsm.a_bus_drop = 1;
+ iotg->hsm.a_bus_req = 0;
+ dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n");
+ dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n");
+ }
+ if (spin_trylock(&lnw->wq_lock)) {
+ langwell_update_transceiver();
+ spin_unlock(&lnw->wq_lock);
+ }
+ return count;
+}
+static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
+ get_a_bus_drop, set_a_bus_drop);
+
+static ssize_t
+get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ char *next;
+ unsigned size, t;
+
+ next = buf;
+ size = PAGE_SIZE;
+
+ t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req);
+ size -= t;
+ next += t;
+
+ return PAGE_SIZE - size;
+}
+
+static ssize_t
+set_b_bus_req(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+
+ if (iotg->otg.default_a)
+ return -1;
+
+ if (count > 2)
+ return -1;
+
+ if (buf[0] == '0') {
+ iotg->hsm.b_bus_req = 0;
+ dev_dbg(lnw->dev, "User request: b_bus_req = 0\n");
+ } else if (buf[0] == '1') {
+ iotg->hsm.b_bus_req = 1;
+ dev_dbg(lnw->dev, "User request: b_bus_req = 1\n");
+ }
+ if (spin_trylock(&lnw->wq_lock)) {
+ langwell_update_transceiver();
+ spin_unlock(&lnw->wq_lock);
+ }
+ return count;
+}
+static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
+
+static ssize_t
+set_a_clr_err(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+
+ if (!iotg->otg.default_a)
+ return -1;
+ if (count > 2)
+ return -1;
+
+ if (buf[0] == '1') {
+ iotg->hsm.a_clr_err = 1;
+ dev_dbg(lnw->dev, "User request: a_clr_err = 1\n");
+ }
+ if (spin_trylock(&lnw->wq_lock)) {
+ langwell_update_transceiver();
+ spin_unlock(&lnw->wq_lock);
+ }
+ return count;
+}
+static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
+
+static struct attribute *inputs_attrs[] = {
+ &dev_attr_a_bus_req.attr,
+ &dev_attr_a_bus_drop.attr,
+ &dev_attr_b_bus_req.attr,
+ &dev_attr_a_clr_err.attr,
+ NULL,
+};
+
+static struct attribute_group debug_dev_attr_group = {
+ .name = "inputs",
+ .attrs = inputs_attrs,
+};
+
+static int langwell_otg_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ unsigned long resource, len;
+ void __iomem *base = NULL;
+ int retval;
+ u32 val32;
+ struct langwell_otg *lnw;
+ char qname[] = "langwell_otg_queue";
+
+ retval = 0;
+ dev_dbg(&pdev->dev, "\notg controller is detected.\n");
+ if (pci_enable_device(pdev) < 0) {
+ retval = -ENODEV;
+ goto done;
+ }
+
+ lnw = kzalloc(sizeof *lnw, GFP_KERNEL);
+ if (lnw == NULL) {
+ retval = -ENOMEM;
+ goto done;
+ }
+ the_transceiver = lnw;
+
+ /* control register: BAR 0 */
+ resource = pci_resource_start(pdev, 0);
+ len = pci_resource_len(pdev, 0);
+ if (!request_mem_region(resource, len, driver_name)) {
+ retval = -EBUSY;
+ goto err;
+ }
+ lnw->region = 1;
+
+ base = ioremap_nocache(resource, len);
+ if (base == NULL) {
+ retval = -EFAULT;
+ goto err;
+ }
+ lnw->iotg.base = base;
+
+ if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) {
+ retval = -EBUSY;
+ goto err;
+ }
+ lnw->cfg_region = 1;
+
+ /* For the SCCB.USBCFG register */
+ base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN);
+ if (base == NULL) {
+ retval = -EFAULT;
+ goto err;
+ }
+ lnw->usbcfg = base;
+
+ if (!pdev->irq) {
+ dev_dbg(&pdev->dev, "No IRQ.\n");
+ retval = -ENODEV;
+ goto err;
+ }
+
+ lnw->qwork = create_singlethread_workqueue(qname);
+ if (!lnw->qwork) {
+ dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname);
+ retval = -ENOMEM;
+ goto err;
+ }
+ INIT_WORK(&lnw->work, langwell_otg_work);
+
+ /* OTG common part */
+ lnw->dev = &pdev->dev;
+ lnw->iotg.otg.dev = lnw->dev;
+ lnw->iotg.otg.label = driver_name;
+ lnw->iotg.otg.set_host = langwell_otg_set_host;
+ lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral;
+ lnw->iotg.otg.set_power = langwell_otg_set_power;
+ lnw->iotg.otg.set_vbus = langwell_otg_set_vbus;
+ lnw->iotg.otg.start_srp = langwell_otg_start_srp;
+ lnw->iotg.otg.state = OTG_STATE_UNDEFINED;
+
+ if (otg_set_transceiver(&lnw->iotg.otg)) {
+ dev_dbg(lnw->dev, "can't set transceiver\n");
+ retval = -EBUSY;
+ goto err;
+ }
+
+ reset_otg();
+ init_hsm();
+
+ spin_lock_init(&lnw->lock);
+ spin_lock_init(&lnw->wq_lock);
+ INIT_LIST_HEAD(&active_timers);
+ retval = langwell_otg_init_timers(&lnw->iotg.hsm);
+ if (retval) {
+ dev_dbg(&pdev->dev, "Failed to init timers\n");
+ goto err;
+ }
+
+ init_timer(&lnw->hsm_timer);
+ ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier);
+
+ lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify;
+
+ retval = intel_mid_otg_register_notifier(&lnw->iotg,
+ &lnw->iotg_notifier);
+ if (retval) {
+ dev_dbg(lnw->dev, "Failed to register notifier\n");
+ goto err;
+ }
+
+ if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
+ driver_name, lnw) != 0) {
+ dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq);
+ retval = -EBUSY;
+ goto err;
+ }
+
+ /* enable OTGSC int */
+ val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
+ OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
+ writel(val32, lnw->iotg.base + CI_OTGSC);
+
+ retval = device_create_file(&pdev->dev, &dev_attr_registers);
+ if (retval < 0) {
+ dev_dbg(lnw->dev,
+ "Can't register sysfs attribute: %d\n", retval);
+ goto err;
+ }
+
+ retval = device_create_file(&pdev->dev, &dev_attr_hsm);
+ if (retval < 0) {
+ dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval);
+ goto err;
+ }
+
+ retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
+ if (retval < 0) {
+ dev_dbg(lnw->dev,
+ "Can't register sysfs attr group: %d\n", retval);
+ goto err;
+ }
+
+ if (lnw->iotg.otg.state == OTG_STATE_A_IDLE)
+ langwell_update_transceiver();
+
+ return 0;
+
+err:
+ if (the_transceiver)
+ langwell_otg_remove(pdev);
+done:
+ return retval;
+}
+
+static void langwell_otg_remove(struct pci_dev *pdev)
+{
+ struct langwell_otg *lnw = the_transceiver;
+
+ if (lnw->qwork) {
+ flush_workqueue(lnw->qwork);
+ destroy_workqueue(lnw->qwork);
+ }
+ intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier);
+ langwell_otg_free_timers();
+
+ /* disable OTGSC interrupt as OTGSC doesn't change in reset */
+ writel(0, lnw->iotg.base + CI_OTGSC);
+
+ if (pdev->irq)
+ free_irq(pdev->irq, lnw);
+ if (lnw->usbcfg)
+ iounmap(lnw->usbcfg);
+ if (lnw->cfg_region)
+ release_mem_region(USBCFG_ADDR, USBCFG_LEN);
+ if (lnw->iotg.base)
+ iounmap(lnw->iotg.base);
+ if (lnw->region)
+ release_mem_region(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+
+ otg_set_transceiver(NULL);
+ pci_disable_device(pdev);
+ sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
+ device_remove_file(&pdev->dev, &dev_attr_hsm);
+ device_remove_file(&pdev->dev, &dev_attr_registers);
+ kfree(lnw);
+ lnw = NULL;
+}
+
+static void transceiver_suspend(struct pci_dev *pdev)
+{
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+ langwell_otg_phy_low_power(1);
+}
+
+static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
+ int ret = 0;
+
+ /* Disbale OTG interrupts */
+ langwell_otg_intr(0);
+
+ if (pdev->irq)
+ free_irq(pdev->irq, lnw);
+
+ /* Prevent more otg_work */
+ flush_workqueue(lnw->qwork);
+ destroy_workqueue(lnw->qwork);
+ lnw->qwork = NULL;
+
+ /* start actions */
+ switch (iotg->otg.state) {
+ case OTG_STATE_A_WAIT_VFALL:
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ case OTG_STATE_A_IDLE:
+ case OTG_STATE_B_IDLE:
+ case OTG_STATE_A_VBUS_ERR:
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_A_WAIT_VRISE:
+ langwell_otg_del_timer(a_wait_vrise_tmr);
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_A_WAIT_BCON:
+ del_timer_sync(&lnw->hsm_timer);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev, "host driver has been removed.\n");
+
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_A_HOST:
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev, "host driver has been removed.\n");
+
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_A_SUSPEND:
+ langwell_otg_del_timer(a_aidl_bdis_tmr);
+ langwell_otg_HABA(0);
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(lnw->dev, "host driver has been removed.\n");
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_A_PERIPHERAL:
+ del_timer_sync(&lnw->hsm_timer);
+
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev,
+ "client driver has been removed.\n");
+ iotg->hsm.a_srp_det = 0;
+
+ /* Turn off VBus */
+ iotg->otg.set_vbus(&iotg->otg, false);
+ iotg->otg.state = OTG_STATE_A_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_B_HOST:
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev, "host driver has been removed.\n");
+ iotg->hsm.b_bus_req = 0;
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_B_PERIPHERAL:
+ if (lnw->iotg.stop_peripheral)
+ lnw->iotg.stop_peripheral(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev,
+ "client driver has been removed.\n");
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ case OTG_STATE_B_WAIT_ACON:
+ /* delete hsm timer for b_ase0_brst_tmr */
+ del_timer_sync(&lnw->hsm_timer);
+
+ langwell_otg_HAAR(0);
+
+ if (lnw->iotg.stop_host)
+ lnw->iotg.stop_host(&lnw->iotg);
+ else
+ dev_dbg(&pdev->dev, "host driver has been removed.\n");
+ iotg->hsm.b_bus_req = 0;
+ iotg->otg.state = OTG_STATE_B_IDLE;
+ transceiver_suspend(pdev);
+ break;
+ default:
+ dev_dbg(lnw->dev, "error state before suspend\n");
+ break;
+ }
+
+ return ret;
+}
+
+static void transceiver_resume(struct pci_dev *pdev)
+{
+ pci_restore_state(pdev);
+ pci_set_power_state(pdev, PCI_D0);
+}
+
+static int langwell_otg_resume(struct pci_dev *pdev)
+{
+ struct langwell_otg *lnw = the_transceiver;
+ int ret = 0;
+
+ transceiver_resume(pdev);
+
+ lnw->qwork = create_singlethread_workqueue("langwell_otg_queue");
+ if (!lnw->qwork) {
+ dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
+ driver_name, lnw) != 0) {
+ dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq);
+ ret = -EBUSY;
+ goto error;
+ }
+
+ /* enable OTG interrupts */
+ langwell_otg_intr(1);
+
+ update_hsm();
+
+ langwell_update_transceiver();
+
+ return ret;
+error:
+ langwell_otg_intr(0);
+ transceiver_suspend(pdev);
+ return ret;
+}
+
+static int __init langwell_otg_init(void)
+{
+ return pci_register_driver(&otg_pci_driver);
+}
+module_init(langwell_otg_init);
+
+static void __exit langwell_otg_cleanup(void)
+{
+ pci_unregister_driver(&otg_pci_driver);
+}
+module_exit(langwell_otg_cleanup);
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 05aaac1c3861..d335f484fcd8 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -124,7 +124,6 @@
#define PHY_DPLL_CLK (1 << 0)
/* In module TWL4030_MODULE_PM_MASTER */
-#define PROTECT_KEY 0x0E
#define STS_HW_CONDITIONS 0x0F
/* In module TWL4030_MODULE_PM_RECEIVER */
@@ -347,11 +346,20 @@ static void twl4030_i2c_access(struct twl4030_usb *twl, int on)
}
}
-static void twl4030_phy_power(struct twl4030_usb *twl, int on)
+static void __twl4030_phy_power(struct twl4030_usb *twl, int on)
{
- u8 pwr;
+ u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+
+ if (on)
+ pwr &= ~PHY_PWR_PHYPWD;
+ else
+ pwr |= PHY_PWR_PHYPWD;
- pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+ WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+}
+
+static void twl4030_phy_power(struct twl4030_usb *twl, int on)
+{
if (on) {
regulator_enable(twl->usb3v1);
regulator_enable(twl->usb1v8);
@@ -365,15 +373,13 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
twl_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_phy_power(twl, 1);
twl4030_usb_write(twl, PHY_CLK_CTRL,
twl4030_usb_read(twl, PHY_CLK_CTRL) |
(PHY_CLK_CTRL_CLOCKGATING_EN |
PHY_CLK_CTRL_CLK32K_EN));
- } else {
- pwr |= PHY_PWR_PHYPWD;
- WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+ } else {
+ __twl4030_phy_power(twl, 0);
regulator_disable(twl->usb1v5);
regulator_disable(twl->usb1v8);
regulator_disable(twl->usb3v1);
@@ -387,29 +393,40 @@ static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
twl4030_phy_power(twl, 0);
twl->asleep = 1;
+ dev_dbg(twl->dev, "%s\n", __func__);
}
-static void twl4030_phy_resume(struct twl4030_usb *twl)
+static void __twl4030_phy_resume(struct twl4030_usb *twl)
{
- if (!twl->asleep)
- return;
-
twl4030_phy_power(twl, 1);
twl4030_i2c_access(twl, 1);
twl4030_usb_set_mode(twl, twl->usb_mode);
if (twl->usb_mode == T2_USB_MODE_ULPI)
twl4030_i2c_access(twl, 0);
+}
+
+static void twl4030_phy_resume(struct twl4030_usb *twl)
+{
+ if (!twl->asleep)
+ return;
+ __twl4030_phy_resume(twl);
twl->asleep = 0;
+ dev_dbg(twl->dev, "%s\n", __func__);
}
static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
{
/* Enable writing to power configuration registers */
- twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY);
- twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY);
+ twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG1,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+
+ twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ TWL4030_PM_MASTER_KEY_CFG2,
+ TWL4030_PM_MASTER_PROTECT_KEY);
- /* put VUSB3V1 LDO in active state */
- twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);
+ /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/
+ /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/
/* input to VUSB3V1 LDO is from VBAT, not VBUS */
twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
@@ -442,7 +459,8 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
/* disable access to power configuration registers */
- twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY);
+ twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
return 0;
@@ -502,6 +520,26 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
return IRQ_HANDLED;
}
+static void twl4030_usb_phy_init(struct twl4030_usb *twl)
+{
+ int status;
+
+ status = twl4030_usb_linkstat(twl);
+ if (status >= 0) {
+ if (status == USB_EVENT_NONE) {
+ __twl4030_phy_power(twl, 0);
+ twl->asleep = 1;
+ } else {
+ __twl4030_phy_resume(twl);
+ twl->asleep = 0;
+ }
+
+ blocking_notifier_call_chain(&twl->otg.notifier, status,
+ twl->otg.gadget);
+ }
+ sysfs_notify(&twl->dev->kobj, NULL, "vbus");
+}
+
static int twl4030_set_suspend(struct otg_transceiver *x, int suspend)
{
struct twl4030_usb *twl = xceiv_to_twl(x);
@@ -550,7 +588,6 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
int status, err;
- u8 pwr;
if (!pdata) {
dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -569,10 +606,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
twl->otg.set_peripheral = twl4030_set_peripheral;
twl->otg.set_suspend = twl4030_set_suspend;
twl->usb_mode = pdata->usb_mode;
-
- pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
-
- twl->asleep = (pwr & PHY_PWR_PHYPWD);
+ twl->asleep = 1;
/* init spinlock for workqueue */
spin_lock_init(&twl->lock);
@@ -610,15 +644,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
return status;
}
- /* The IRQ handler just handles changes from the previous states
- * of the ID and VBUS pins ... in probe() we must initialize that
- * previous state. The easy way: fake an IRQ.
- *
- * REVISIT: a real IRQ might have happened already, if PREEMPT is
- * enabled. Else the IRQ may not yet be configured or enabled,
- * because of scheduling delays.
+ /* Power down phy or make it work according to
+ * current link state.
*/
- twl4030_usb_irq(twl->irq, twl);
+ twl4030_usb_phy_init(twl);
dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
return 0;
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 916b2b6d765f..95058109f9fa 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -527,6 +527,15 @@ config USB_SERIAL_SAFE_PADDED
bool "USB Secure Encapsulated Driver - Padded"
depends on USB_SERIAL_SAFE
+config USB_SERIAL_SAMBA
+ tristate "USB Atmel SAM Boot Assistant (SAM-BA) driver"
+ help
+ Say Y here if you want to access the SAM-BA boot application of an
+ Atmel AT91SAM device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sam-ba.
+
config USB_SERIAL_SIEMENS_MPI
tristate "USB Siemens MPI driver"
help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 40ebe17b6ea8..cf41b6209c74 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o
obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
+obj-$(CONFIG_USB_SERIAL_SAMBA) += sam-ba.o
obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o
obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 80bf8333bb03..4f1744c5871f 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -56,6 +56,7 @@ static int debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
{ USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
{ USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
{ USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
{ USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
@@ -88,6 +89,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
@@ -109,6 +111,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
+ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
@@ -122,14 +125,14 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
- { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
- { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
- { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
- { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
{ USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */
{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index f5d06746cc3b..2edf238b00b9 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1320,8 +1320,6 @@ continue_read:
cypress_set_dead(port);
}
}
-
- return;
} /* cypress_read_int_callback */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c792c96f590e..1f30a01d5c90 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -753,6 +753,14 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
{ USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -2072,7 +2080,6 @@ static void ftdi_set_termios(struct tty_struct *tty,
/* lower DTR/RTS */
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
}
- return;
}
static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 2e95857c9633..15a4583775ad 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -135,6 +135,18 @@
#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */
/*
+ * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs
+ */
+#define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8
+#define FTDI_CHAMSYS_PC_WING_PID 0xDAF9
+#define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA
+#define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB
+#define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC
+#define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD
+#define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE
+#define FTDI_CHAMSYS_WING_PID 0xDAFF
+
+/*
* Westrex International devices submitted by Cory Lee
*/
#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index a42b29a695b2..26710b189918 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1264,7 +1264,6 @@ static void garmin_read_bulk_callback(struct urb *urb)
garmin_data_p->flags &= ~FLAGS_BULK_IN_ACTIVE;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
}
- return;
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 76e6fb3aab7a..892e916ef67e 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -1465,8 +1465,6 @@ static void edge_throttle(struct tty_struct *tty)
if (status != 0)
return;
}
-
- return;
}
@@ -1770,8 +1768,6 @@ static void edge_break(struct tty_struct *tty, int break_state)
dbg("%s - error sending break set/clear command.",
__func__);
}
-
- return;
}
@@ -2042,7 +2038,6 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
dbg("%s - Unrecognized IOSP status code %u", __func__, code);
break;
}
- return;
}
@@ -2095,8 +2090,6 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
/* Save the new modem status */
edge_port->shadowMSR = newMsr & 0xf0;
-
- return;
}
@@ -2143,8 +2136,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
icount->parity++;
if (newLsr & LSR_FRM_ERR)
icount->frame++;
-
- return;
}
@@ -2720,7 +2711,6 @@ static void change_port_settings(struct tty_struct *tty,
baud = tty_termios_baud_rate(old_termios);
tty_encode_baud_rate(tty, baud, baud);
}
- return;
}
@@ -2922,7 +2912,6 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
0x40, 0x4000, 0x0001, NULL, 0, 3000);
release_firmware(fw);
- return;
}
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index a7cfc5952937..baf703789df4 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1571,8 +1571,6 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
}
}
tty_kref_put(tty);
-
- return;
}
static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
@@ -2424,7 +2422,6 @@ static void change_port_settings(struct tty_struct *tty,
dbg("%s - error %d when trying to write config to device",
__func__, status);
kfree(config);
- return;
}
static void edge_set_termios(struct tty_struct *tty,
@@ -2445,7 +2442,6 @@ static void edge_set_termios(struct tty_struct *tty,
return;
/* change the port settings to the new ones specified */
change_port_settings(tty, edge_port, old_termios);
- return;
}
static int edge_tiocmset(struct tty_struct *tty, struct file *file,
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index efc72113216b..12ed594f5f80 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -807,7 +807,6 @@ static void read_rxcmd_callback(struct urb *urb)
iuu_uart_read_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
dbg("%s - submit result = %d", __func__, result);
- return;
}
static int iuu_uart_on(struct usb_serial_port *port)
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 185fe9a7d4e0..a10dd5676ccc 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -292,7 +292,6 @@ static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
port->interrupt_in_urb->dev = port->serial->dev;
if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
dbg(" usb_submit_urb(read urb) failed");
- return;
}
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 30922a7e3347..f442333dfa99 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -827,7 +827,6 @@ exit:
dev_err(&urb->dev->dev,
"%s - Error %d submitting control urb\n",
__func__, result);
- return;
}
/*
@@ -907,7 +906,6 @@ exit:
dev_err(&urb->dev->dev,
"%s - Error %d submitting control urb\n",
__func__, result);
- return;
}
/*
@@ -1227,8 +1225,6 @@ static void mos7720_break(struct tty_struct *tty, int break_state)
mos7720_port->shadowLCR = data;
write_mos_reg(serial, port->number - port->serial->minor,
LCR, mos7720_port->shadowLCR);
-
- return;
}
/*
@@ -1746,7 +1742,6 @@ static void change_port_settings(struct tty_struct *tty,
dbg("usb_submit_urb(read bulk) failed, status = %d",
status);
}
- return;
}
/*
@@ -1803,7 +1798,6 @@ static void mos7720_set_termios(struct tty_struct *tty,
dbg("usb_submit_urb(read bulk) failed, status = %d",
status);
}
- return;
}
/*
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 585b7e663740..01b3614be99b 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -119,16 +119,20 @@
* by making a change here, in moschip_port_id_table, and in
* moschip_id_table_combined
*/
-#define USB_VENDOR_ID_BANDB 0x0856
-#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
-#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24
-#define BANDB_DEVICE_ID_US9ML2_2 0xAC29
-#define BANDB_DEVICE_ID_US9ML2_4 0xAC30
-#define BANDB_DEVICE_ID_USPTL4_2 0xAC31
-#define BANDB_DEVICE_ID_USPTL4_4 0xAC32
-#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
-#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
-#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24
+#define USB_VENDOR_ID_BANDB 0x0856
+#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22
+#define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00
+#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24
+#define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01
+#define BANDB_DEVICE_ID_US9ML2_2 0xAC29
+#define BANDB_DEVICE_ID_US9ML2_4 0xAC30
+#define BANDB_DEVICE_ID_USPTL4_2 0xAC31
+#define BANDB_DEVICE_ID_USPTL4_4 0xAC32
+#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42
+#define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02
+#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44
+#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03
+#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24
/* This driver also supports
* ATEN UC2324 device using Moschip MCS7840
@@ -184,13 +188,17 @@ static const struct usb_device_id moschip_port_id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
@@ -201,13 +209,17 @@ static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
+ {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
@@ -1355,8 +1367,6 @@ static void mos7840_break(struct tty_struct *tty, int break_state)
mos7840_port->shadowLCR);
mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
mos7840_port->shadowLCR);
-
- return;
}
/*****************************************************************************
@@ -1587,8 +1597,6 @@ static void mos7840_throttle(struct tty_struct *tty)
if (status < 0)
return;
}
-
- return;
}
/*****************************************************************************
@@ -2063,8 +2071,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
mos7840_port->delta_msr_cond = 1;
dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x",
mos7840_port->shadowLCR);
-
- return;
}
/*****************************************************************************
@@ -2133,7 +2139,6 @@ static void mos7840_set_termios(struct tty_struct *tty,
mos7840_port->read_urb_busy = false;
}
}
- return;
}
/*****************************************************************************
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 89c724c0ac0a..60f38d5e64fc 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -246,8 +246,6 @@ static void omninet_read_bulk_callback(struct urb *urb)
dev_err(&port->dev,
"%s - failed resubmitting read urb, error %d\n",
__func__, result);
-
- return;
}
static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index adcbdb994de3..c46911af282f 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -164,6 +164,14 @@ static void option_instat_callback(struct urb *urb);
#define YISO_VENDOR_ID 0x0EAB
#define YISO_PRODUCT_U893 0xC893
+/*
+ * NOVATEL WIRELESS PRODUCTS
+ *
+ * Note from Novatel Wireless:
+ * If your Novatel modem does not work on linux, don't
+ * change the option module, but check our website. If
+ * that does not help, contact ddeschepper@nvtl.com
+*/
/* MERLIN EVDO PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_V640 0x1100
#define NOVATELWIRELESS_PRODUCT_V620 0x1110
@@ -185,24 +193,39 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_EU730 0x2400
#define NOVATELWIRELESS_PRODUCT_EU740 0x2410
#define NOVATELWIRELESS_PRODUCT_EU870D 0x2420
-
/* OVATION PRODUCTS */
#define NOVATELWIRELESS_PRODUCT_MC727 0x4100
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
-#define NOVATELWIRELESS_PRODUCT_U727 0x5010
-#define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100
-#define NOVATELWIRELESS_PRODUCT_MC760 0x6000
+/*
+ * Note from Novatel Wireless:
+ * All PID in the 5xxx range are currently reserved for
+ * auto-install CDROMs, and should not be added to this
+ * module.
+ *
+ * #define NOVATELWIRELESS_PRODUCT_U727 0x5010
+ * #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100
+*/
#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002
-
-/* FUTURE NOVATEL PRODUCTS */
-#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
+#define NOVATELWIRELESS_PRODUCT_MC780 0x6010
+#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_HSPA_HIGHSPEED3 0x7003
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4 0x7004
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5 0x7005
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6 0x7006
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7 0x7007
+#define NOVATELWIRELESS_PRODUCT_MC996D 0x7030
+#define NOVATELWIRELESS_PRODUCT_MF3470 0x7041
+#define NOVATELWIRELESS_PRODUCT_MC547 0x7042
+#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_G1 0xA001
+#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002
+#define NOVATELWIRELESS_PRODUCT_G2 0xA010
/* AMOI PRODUCTS */
#define AMOI_VENDOR_ID 0x1614
@@ -490,36 +513,44 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) },
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, /* Novatel Merlin ES620 SM Bus */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */
- { 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_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */
- { 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(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC780) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC996D) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MF3470) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
diff --git a/drivers/usb/serial/sam-ba.c b/drivers/usb/serial/sam-ba.c
new file mode 100644
index 000000000000..e3bba64afc57
--- /dev/null
+++ b/drivers/usb/serial/sam-ba.c
@@ -0,0 +1,206 @@
+/*
+ * Atmel SAM Boot Assistant (SAM-BA) driver
+ *
+ * Copyright (C) 2010 Johan Hovold <jhovold@gmail.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/kernel.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "Johan Hovold <jhovold@gmail.com>"
+#define DRIVER_DESC "Atmel SAM Boot Assistant (SAM-BA) driver"
+
+#define SAMBA_VENDOR_ID 0x3eb
+#define SAMBA_PRODUCT_ID 0x6124
+
+
+static int debug;
+
+static const struct usb_device_id id_table[] = {
+ /*
+ * NOTE: Only match the CDC Data interface.
+ */
+ { USB_DEVICE_AND_INTERFACE_INFO(SAMBA_VENDOR_ID, SAMBA_PRODUCT_ID,
+ USB_CLASS_CDC_DATA, 0, 0) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver samba_driver = {
+ .name = "sam-ba",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .no_dynamic_id = 1,
+};
+
+
+/*
+ * NOTE: The SAM-BA firmware cannot handle merged write requests so we cannot
+ * use the generic write implementation (which uses the port write fifo).
+ */
+static int samba_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ struct urb *urb;
+ unsigned long flags;
+ int result;
+ int i;
+
+ if (!count)
+ return 0;
+
+ count = min_t(int, count, port->bulk_out_size);
+
+ spin_lock_irqsave(&port->lock, flags);
+ if (!port->write_urbs_free) {
+ spin_unlock_irqrestore(&port->lock, flags);
+ return 0;
+ }
+ i = find_first_bit(&port->write_urbs_free,
+ ARRAY_SIZE(port->write_urbs));
+ __clear_bit(i, &port->write_urbs_free);
+ port->tx_bytes += count;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ urb = port->write_urbs[i];
+ memcpy(urb->transfer_buffer, buf, count);
+ urb->transfer_buffer_length = count;
+ usb_serial_debug_data(debug, &port->dev, __func__, count,
+ urb->transfer_buffer);
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&port->dev, "%s - error submitting urb: %d\n",
+ __func__, result);
+ spin_lock_irqsave(&port->lock, flags);
+ __set_bit(i, &port->write_urbs_free);
+ port->tx_bytes -= count;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return result;
+ }
+
+ return count;
+}
+
+static int samba_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ unsigned long flags;
+ unsigned long free;
+ int count;
+ int room;
+
+ spin_lock_irqsave(&port->lock, flags);
+ free = port->write_urbs_free;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ count = hweight_long(free);
+ room = count * port->bulk_out_size;
+
+ dbg("%s - returns %d", __func__, room);
+
+ return room;
+}
+
+static int samba_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ unsigned long flags;
+ int chars;
+
+ spin_lock_irqsave(&port->lock, flags);
+ chars = port->tx_bytes;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ dbg("%s - returns %d", __func__, chars);
+
+ return chars;
+}
+
+static void samba_write_bulk_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = urb->context;
+ unsigned long flags;
+ int i;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
+ if (port->write_urbs[i] == urb)
+ break;
+ }
+ spin_lock_irqsave(&port->lock, flags);
+ __set_bit(i, &port->write_urbs_free);
+ port->tx_bytes -= urb->transfer_buffer_length;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (urb->status)
+ dbg("%s - non-zero urb status: %d", __func__, urb->status);
+
+ usb_serial_port_softint(port);
+}
+
+static struct usb_serial_driver samba_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "sam-ba",
+ },
+ .usb_driver = &samba_driver,
+ .id_table = id_table,
+ .num_ports = 1,
+ .bulk_in_size = 512,
+ .bulk_out_size = 2048,
+ .write = samba_write,
+ .write_room = samba_write_room,
+ .chars_in_buffer = samba_chars_in_buffer,
+ .write_bulk_callback = samba_write_bulk_callback,
+ .throttle = usb_serial_generic_throttle,
+ .unthrottle = usb_serial_generic_unthrottle,
+};
+
+static int __init samba_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&samba_device);
+ if (retval)
+ return retval;
+
+ retval = usb_register(&samba_driver);
+ if (retval) {
+ usb_serial_deregister(&samba_device);
+ return retval;
+ }
+
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": "
+ DRIVER_DESC "\n");
+ return 0;
+}
+
+static void __exit samba_exit(void)
+{
+ usb_deregister(&samba_driver);
+ usb_serial_deregister(&samba_device);
+}
+
+module_init(samba_init);
+module_exit(samba_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable verbose debugging messages");
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index d47b56e9e8ce..7481ff8a49e4 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -620,8 +620,6 @@ static void sierra_indat_callback(struct urb *urb)
dev_err(&port->dev, "resubmit read urb failed."
"(%d)\n", err);
}
-
- return;
}
static void sierra_instat_callback(struct urb *urb)
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 329d311a35d9..765aa983bf58 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -441,7 +441,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
spcp8x5_set_workMode(serial->dev, 0x000a,
SET_WORKING_MODE_U2C, priv->type);
}
- return;
}
/* open the serial port. do some usb system call. set termios and get the line
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 68c18fdfc6da..e986002b3844 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -46,7 +46,7 @@
#define FULLPWRBIT 0x00000080
#define NEXT_BOARD_POWER_BIT 0x00000004
-static int debug = 1;
+static int debug;
/* Version Information */
#define DRIVER_VERSION "v0.1"
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 0c70b4a621bb..fbc946797801 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -234,7 +234,6 @@ static void usb_wwan_indat_callback(struct urb *urb)
}
}
- return;
}
static void usb_wwan_outdat_callback(struct urb *urb)
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 12ed8209ca72..3f9ac88d588c 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -655,8 +655,6 @@ static void whiteheat_release(struct usb_serial *serial)
}
kfree(info);
}
-
- return;
}
static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -955,8 +953,6 @@ static void whiteheat_throttle(struct tty_struct *tty)
spin_lock_irq(&info->lock);
info->flags |= THROTTLED;
spin_unlock_irq(&info->lock);
-
- return;
}
@@ -975,8 +971,6 @@ static void whiteheat_unthrottle(struct tty_struct *tty)
if (actually_throttled)
rx_data_softint(&info->rx_work);
-
- return;
}
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 552679b8dbd1..e793c0294d3c 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -507,6 +507,7 @@ static const struct file_operations skel_fops = {
.open = skel_open,
.release = skel_release,
.flush = skel_flush,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
/*
diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c
index 973321327c44..8739c4f4d015 100644
--- a/drivers/uwb/address.c
+++ b/drivers/uwb/address.c
@@ -363,10 +363,7 @@ size_t __uwb_addr_print(char *buf, size_t buf_size, const unsigned char *addr,
{
size_t result;
if (type)
- result = scnprintf(buf, buf_size,
- "%02x:%02x:%02x:%02x:%02x:%02x",
- addr[0], addr[1], addr[2],
- addr[3], addr[4], addr[5]);
+ result = scnprintf(buf, buf_size, "%pM", addr);
else
result = scnprintf(buf, buf_size, "%02x:%02x",
addr[1], addr[0]);
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c
index def778cf2216..daf793559bcf 100644
--- a/drivers/uwb/i1480/i1480u-wlp/lc.c
+++ b/drivers/uwb/i1480/i1480u-wlp/lc.c
@@ -93,28 +93,28 @@ void i1480u_init(struct i1480u *i1480u)
* information elements have intuitive mappings, other not.
*/
static
-void i1480u_fill_device_info(struct wlp *wlp, struct wlp_device_info *dev_info)
+void i1480u_fill_device_info(struct wlp *wlp, struct wlp_device_info *wdi)
{
struct i1480u *i1480u = container_of(wlp, struct i1480u, wlp);
struct usb_device *usb_dev = i1480u->usb_dev;
/* Treat device name and model name the same */
if (usb_dev->descriptor.iProduct) {
usb_string(usb_dev, usb_dev->descriptor.iProduct,
- dev_info->name, sizeof(dev_info->name));
+ wdi->name, sizeof(wdi->name));
usb_string(usb_dev, usb_dev->descriptor.iProduct,
- dev_info->model_name, sizeof(dev_info->model_name));
+ wdi->model_name, sizeof(wdi->model_name));
}
if (usb_dev->descriptor.iManufacturer)
usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
- dev_info->manufacturer,
- sizeof(dev_info->manufacturer));
- scnprintf(dev_info->model_nr, sizeof(dev_info->model_nr), "%04x",
+ wdi->manufacturer,
+ sizeof(wdi->manufacturer));
+ scnprintf(wdi->model_nr, sizeof(wdi->model_nr), "%04x",
__le16_to_cpu(usb_dev->descriptor.bcdDevice));
if (usb_dev->descriptor.iSerialNumber)
usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
- dev_info->serial, sizeof(dev_info->serial));
+ wdi->serial, sizeof(wdi->serial));
/* FIXME: where should we obtain category? */
- dev_info->prim_dev_type.category = cpu_to_le16(WLP_DEV_CAT_OTHER);
+ wdi->prim_dev_type.category = cpu_to_le16(WLP_DEV_CAT_OTHER);
/* FIXME: Complete OUI and OUIsubdiv attributes */
}
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c
index 3a8e033dce21..6daa464bed24 100644
--- a/drivers/uwb/wlp/messages.c
+++ b/drivers/uwb/wlp/messages.c
@@ -713,7 +713,7 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
struct sk_buff *_skb;
void *d1_itr;
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0) {
dev_err(dev, "WLP: Unable to setup device "
@@ -721,7 +721,7 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss,
goto error;
}
}
- info = wlp->dev_info;
+ info = wlp->wdi;
_skb = dev_alloc_skb(sizeof(*_d1)
+ sizeof(struct wlp_attr_uuid_e)
+ sizeof(struct wlp_attr_wss_sel_mthd)
@@ -795,7 +795,7 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
void *d2_itr;
size_t mem_needed;
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0) {
dev_err(dev, "WLP: Unable to setup device "
@@ -803,7 +803,7 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss,
goto error;
}
}
- info = wlp->dev_info;
+ info = wlp->wdi;
mem_needed = sizeof(*_d2)
+ sizeof(struct wlp_attr_uuid_e)
+ sizeof(struct wlp_attr_uuid_r)
@@ -971,7 +971,7 @@ error_parse:
*/
static
int wlp_get_variable_info(struct wlp *wlp, void *data,
- struct wlp_device_info *dev_info, ssize_t len)
+ struct wlp_device_info *wdi, ssize_t len)
{
struct device *dev = &wlp->rc->uwb_dev.dev;
size_t used = 0;
@@ -994,7 +994,7 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
goto error_parse;
}
result = wlp_get_manufacturer(wlp, data + used,
- dev_info->manufacturer,
+ wdi->manufacturer,
len - used);
if (result < 0) {
dev_err(dev, "WLP: Unable to obtain "
@@ -1012,7 +1012,7 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
goto error_parse;
}
result = wlp_get_model_name(wlp, data + used,
- dev_info->model_name,
+ wdi->model_name,
len - used);
if (result < 0) {
dev_err(dev, "WLP: Unable to obtain Model "
@@ -1029,7 +1029,7 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
goto error_parse;
}
result = wlp_get_model_nr(wlp, data + used,
- dev_info->model_nr,
+ wdi->model_nr,
len - used);
if (result < 0) {
dev_err(dev, "WLP: Unable to obtain Model "
@@ -1046,7 +1046,7 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
goto error_parse;
}
result = wlp_get_serial(wlp, data + used,
- dev_info->serial, len - used);
+ wdi->serial, len - used);
if (result < 0) {
dev_err(dev, "WLP: Unable to obtain Serial "
"number attribute from D1 message.\n");
@@ -1062,7 +1062,7 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
goto error_parse;
}
result = wlp_get_prim_dev_type(wlp, data + used,
- &dev_info->prim_dev_type,
+ &wdi->prim_dev_type,
len - used);
if (result < 0) {
dev_err(dev, "WLP: Unable to obtain Primary "
@@ -1070,10 +1070,10 @@ int wlp_get_variable_info(struct wlp *wlp, void *data,
"message.\n");
goto error_parse;
}
- dev_info->prim_dev_type.category =
- le16_to_cpu(dev_info->prim_dev_type.category);
- dev_info->prim_dev_type.subID =
- le16_to_cpu(dev_info->prim_dev_type.subID);
+ wdi->prim_dev_type.category =
+ le16_to_cpu(wdi->prim_dev_type.category);
+ wdi->prim_dev_type.subID =
+ le16_to_cpu(wdi->prim_dev_type.subID);
last = WLP_ATTR_PRI_DEV_TYPE;
used += result;
break;
@@ -1099,7 +1099,7 @@ static
int wlp_parse_d1_frame(struct wlp *wlp, struct sk_buff *skb,
struct wlp_uuid *uuid_e,
enum wlp_wss_sel_mthd *sel_mthd,
- struct wlp_device_info *dev_info,
+ struct wlp_device_info *wdi,
enum wlp_assc_error *assc_err)
{
struct device *dev = &wlp->rc->uwb_dev.dev;
@@ -1124,7 +1124,7 @@ int wlp_parse_d1_frame(struct wlp *wlp, struct sk_buff *skb,
goto error_parse;
}
used += result;
- result = wlp_get_dev_name(wlp, ptr + used, dev_info->name,
+ result = wlp_get_dev_name(wlp, ptr + used, wdi->name,
len - used);
if (result < 0) {
dev_err(dev, "WLP: unable to obtain Device Name from D1 "
@@ -1132,7 +1132,7 @@ int wlp_parse_d1_frame(struct wlp *wlp, struct sk_buff *skb,
goto error_parse;
}
used += result;
- result = wlp_get_variable_info(wlp, ptr + used, dev_info, len - used);
+ result = wlp_get_variable_info(wlp, ptr + used, wdi, len - used);
if (result < 0) {
dev_err(dev, "WLP: unable to obtain Device Information from "
"D1 message.\n");
@@ -1172,15 +1172,15 @@ void wlp_handle_d1_frame(struct work_struct *ws)
struct device *dev = &wlp->rc->uwb_dev.dev;
struct wlp_uuid uuid_e;
enum wlp_wss_sel_mthd sel_mthd = 0;
- struct wlp_device_info dev_info;
+ struct wlp_device_info wdi;
enum wlp_assc_error assc_err;
struct sk_buff *resp = NULL;
/* Parse D1 frame */
mutex_lock(&wss->mutex);
mutex_lock(&wlp->mutex); /* to access wlp->uuid */
- memset(&dev_info, 0, sizeof(dev_info));
- result = wlp_parse_d1_frame(wlp, skb, &uuid_e, &sel_mthd, &dev_info,
+ memset(&wdi, 0, sizeof(wdi));
+ result = wlp_parse_d1_frame(wlp, skb, &uuid_e, &sel_mthd, &wdi,
&assc_err);
if (result < 0) {
dev_err(dev, "WLP: Unable to parse incoming D1 frame.\n");
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c
index 6627c94cc854..b24751c3430b 100644
--- a/drivers/uwb/wlp/sysfs.c
+++ b/drivers/uwb/wlp/sysfs.c
@@ -333,12 +333,12 @@ ssize_t wlp_dev_##type##_show(struct wlp *wlp, char *buf) \
{ \
ssize_t result = 0; \
mutex_lock(&wlp->mutex); \
- if (wlp->dev_info == NULL) { \
+ if (wlp->wdi == NULL) { \
result = __wlp_setup_device_info(wlp); \
if (result < 0) \
goto out; \
} \
- result = scnprintf(buf, PAGE_SIZE, "%s\n", wlp->dev_info->type);\
+ result = scnprintf(buf, PAGE_SIZE, "%s\n", wlp->wdi->type); \
out: \
mutex_unlock(&wlp->mutex); \
return result; \
@@ -360,14 +360,14 @@ ssize_t wlp_dev_##type##_store(struct wlp *wlp, const char *buf, size_t size)\
ssize_t result; \
char format[10]; \
mutex_lock(&wlp->mutex); \
- if (wlp->dev_info == NULL) { \
+ if (wlp->wdi == NULL) { \
result = __wlp_alloc_device_info(wlp); \
if (result < 0) \
goto out; \
} \
- memset(wlp->dev_info->type, 0, sizeof(wlp->dev_info->type)); \
+ memset(wlp->wdi->type, 0, sizeof(wlp->wdi->type)); \
sprintf(format, "%%%uc", len); \
- result = sscanf(buf, format, wlp->dev_info->type); \
+ result = sscanf(buf, format, wlp->wdi->type); \
out: \
mutex_unlock(&wlp->mutex); \
return result < 0 ? result : size; \
@@ -409,13 +409,13 @@ ssize_t wlp_dev_prim_category_show(struct wlp *wlp, char *buf)
{
ssize_t result = 0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0)
goto out;
}
result = scnprintf(buf, PAGE_SIZE, "%s\n",
- wlp_dev_category_str(wlp->dev_info->prim_dev_type.category));
+ wlp_dev_category_str(wlp->wdi->prim_dev_type.category));
out:
mutex_unlock(&wlp->mutex);
return result;
@@ -428,7 +428,7 @@ ssize_t wlp_dev_prim_category_store(struct wlp *wlp, const char *buf,
ssize_t result;
u16 cat;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_alloc_device_info(wlp);
if (result < 0)
goto out;
@@ -436,7 +436,7 @@ ssize_t wlp_dev_prim_category_store(struct wlp *wlp, const char *buf,
result = sscanf(buf, "%hu", &cat);
if ((cat >= WLP_DEV_CAT_COMPUTER && cat <= WLP_DEV_CAT_TELEPHONE)
|| cat == WLP_DEV_CAT_OTHER)
- wlp->dev_info->prim_dev_type.category = cat;
+ wlp->wdi->prim_dev_type.category = cat;
else
result = -EINVAL;
out:
@@ -449,15 +449,15 @@ ssize_t wlp_dev_prim_OUI_show(struct wlp *wlp, char *buf)
{
ssize_t result = 0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0)
goto out;
}
result = scnprintf(buf, PAGE_SIZE, "%02x:%02x:%02x\n",
- wlp->dev_info->prim_dev_type.OUI[0],
- wlp->dev_info->prim_dev_type.OUI[1],
- wlp->dev_info->prim_dev_type.OUI[2]);
+ wlp->wdi->prim_dev_type.OUI[0],
+ wlp->wdi->prim_dev_type.OUI[1],
+ wlp->wdi->prim_dev_type.OUI[2]);
out:
mutex_unlock(&wlp->mutex);
return result;
@@ -469,7 +469,7 @@ ssize_t wlp_dev_prim_OUI_store(struct wlp *wlp, const char *buf, size_t size)
ssize_t result;
u8 OUI[3];
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_alloc_device_info(wlp);
if (result < 0)
goto out;
@@ -480,7 +480,7 @@ ssize_t wlp_dev_prim_OUI_store(struct wlp *wlp, const char *buf, size_t size)
result = -EINVAL;
goto out;
} else
- memcpy(wlp->dev_info->prim_dev_type.OUI, OUI, sizeof(OUI));
+ memcpy(wlp->wdi->prim_dev_type.OUI, OUI, sizeof(OUI));
out:
mutex_unlock(&wlp->mutex);
return result < 0 ? result : size;
@@ -492,13 +492,13 @@ ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *wlp, char *buf)
{
ssize_t result = 0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0)
goto out;
}
result = scnprintf(buf, PAGE_SIZE, "%u\n",
- wlp->dev_info->prim_dev_type.OUIsubdiv);
+ wlp->wdi->prim_dev_type.OUIsubdiv);
out:
mutex_unlock(&wlp->mutex);
return result;
@@ -512,14 +512,14 @@ ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *wlp, const char *buf,
unsigned sub;
u8 max_sub = ~0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_alloc_device_info(wlp);
if (result < 0)
goto out;
}
result = sscanf(buf, "%u", &sub);
if (sub <= max_sub)
- wlp->dev_info->prim_dev_type.OUIsubdiv = sub;
+ wlp->wdi->prim_dev_type.OUIsubdiv = sub;
else
result = -EINVAL;
out:
@@ -532,13 +532,13 @@ ssize_t wlp_dev_prim_subcat_show(struct wlp *wlp, char *buf)
{
ssize_t result = 0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_setup_device_info(wlp);
if (result < 0)
goto out;
}
result = scnprintf(buf, PAGE_SIZE, "%u\n",
- wlp->dev_info->prim_dev_type.subID);
+ wlp->wdi->prim_dev_type.subID);
out:
mutex_unlock(&wlp->mutex);
return result;
@@ -552,14 +552,14 @@ ssize_t wlp_dev_prim_subcat_store(struct wlp *wlp, const char *buf,
unsigned sub;
__le16 max_sub = ~0;
mutex_lock(&wlp->mutex);
- if (wlp->dev_info == NULL) {
+ if (wlp->wdi == NULL) {
result = __wlp_alloc_device_info(wlp);
if (result < 0)
goto out;
}
result = sscanf(buf, "%u", &sub);
if (sub <= max_sub)
- wlp->dev_info->prim_dev_type.subID = sub;
+ wlp->wdi->prim_dev_type.subID = sub;
else
result = -EINVAL;
out:
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c
index 7f6a630bf26c..202655d4fc20 100644
--- a/drivers/uwb/wlp/wlp-lc.c
+++ b/drivers/uwb/wlp/wlp-lc.c
@@ -40,9 +40,9 @@ void wlp_neighbor_init(struct wlp_neighbor_e *neighbor)
int __wlp_alloc_device_info(struct wlp *wlp)
{
struct device *dev = &wlp->rc->uwb_dev.dev;
- BUG_ON(wlp->dev_info != NULL);
- wlp->dev_info = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
- if (wlp->dev_info == NULL) {
+ BUG_ON(wlp->wdi != NULL);
+ wlp->wdi = kzalloc(sizeof(struct wlp_device_info), GFP_KERNEL);
+ if (wlp->wdi == NULL) {
dev_err(dev, "WLP: Unable to allocate memory for "
"device information.\n");
return -ENOMEM;
@@ -59,7 +59,7 @@ int __wlp_alloc_device_info(struct wlp *wlp)
static
void __wlp_fill_device_info(struct wlp *wlp)
{
- wlp->fill_device_info(wlp, wlp->dev_info);
+ wlp->fill_device_info(wlp, wlp->wdi);
}
/**
@@ -539,8 +539,8 @@ void wlp_remove(struct wlp *wlp)
uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler);
wlp_eda_release(&wlp->eda);
mutex_lock(&wlp->mutex);
- if (wlp->dev_info != NULL)
- kfree(wlp->dev_info);
+ if (wlp->wdi != NULL)
+ kfree(wlp->wdi);
mutex_unlock(&wlp->mutex);
wlp->rc = NULL;
}
diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c
index a005d2a03b5d..67872c83b679 100644
--- a/drivers/uwb/wlp/wss-lc.c
+++ b/drivers/uwb/wlp/wss-lc.c
@@ -791,11 +791,8 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
} else {
if (printk_ratelimit())
dev_err(dev, "WLP: Destination neighbor (Ethernet: "
- "%02x:%02x:%02x:%02x:%02x:%02x, Dev: "
- "%02x:%02x) is not connected. \n", eth_addr[0],
- eth_addr[1], eth_addr[2], eth_addr[3],
- eth_addr[4], eth_addr[5], dev_addr->data[1],
- dev_addr->data[0]);
+ "%pM, Dev: %02x:%02x) is not connected.\n",
+ eth_addr, dev_addr->data[1], dev_addr->data[0]);
result = -EINVAL;
}
return result;
diff --git a/drivers/vbus/Kconfig b/drivers/vbus/Kconfig
new file mode 100644
index 000000000000..f51cba10913e
--- /dev/null
+++ b/drivers/vbus/Kconfig
@@ -0,0 +1,25 @@
+#
+# Virtual-Bus (VBus) driver configuration
+#
+
+config VBUS_PROXY
+ bool "Virtual-Bus support"
+ select SHM_SIGNAL
+ select IOQ
+ default n
+ help
+ Adds support for a virtual-bus model drivers in a guest to connect
+ to host side virtual-bus resources. If you are using this kernel
+ in a virtualization solution which implements virtual-bus devices
+ on the backend, say Y. If unsure, say N.
+
+config VBUS_PCIBRIDGE
+ bool "PCI to Virtual-Bus bridge"
+ depends on PCI
+ depends on VBUS_PROXY
+ select IOQ
+ default n
+ help
+ Provides a way to bridge host side vbus devices via a PCI-BRIDGE
+ object. If you are running virtualization with vbus devices on the
+ host, and the vbus is exposed via PCI, say Y. Otherwise, say N.
diff --git a/drivers/vbus/Makefile b/drivers/vbus/Makefile
new file mode 100644
index 000000000000..944b7f1fec90
--- /dev/null
+++ b/drivers/vbus/Makefile
@@ -0,0 +1,6 @@
+
+vbus-proxy-objs += bus-proxy.o
+obj-$(CONFIG_VBUS_PROXY) += vbus-proxy.o
+
+vbus-pcibridge-objs += pci-bridge.o
+obj-$(CONFIG_VBUS_PCIBRIDGE) += vbus-pcibridge.o
diff --git a/drivers/vbus/bus-proxy.c b/drivers/vbus/bus-proxy.c
new file mode 100644
index 000000000000..ae11f679d34e
--- /dev/null
+++ b/drivers/vbus/bus-proxy.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2009 Novell. All Rights Reserved.
+ *
+ * Author:
+ * Gregory Haskins <ghaskins@novell.com>
+ *
+ * This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/vbus_driver.h>
+
+MODULE_AUTHOR("Gregory Haskins");
+MODULE_LICENSE("GPL");
+
+#define VBUS_PROXY_NAME "vbus-proxy"
+
+static struct vbus_device_proxy *to_dev(struct device *_dev)
+{
+ return _dev ? container_of(_dev, struct vbus_device_proxy, dev) : NULL;
+}
+
+static struct vbus_driver *to_drv(struct device_driver *_drv)
+{
+ return container_of(_drv, struct vbus_driver, drv);
+}
+
+/*
+ * This function is invoked whenever a new driver and/or device is added
+ * to check if there is a match
+ */
+static int vbus_dev_proxy_match(struct device *_dev, struct device_driver *_drv)
+{
+ struct vbus_device_proxy *dev = to_dev(_dev);
+ struct vbus_driver *drv = to_drv(_drv);
+
+ return !strcmp(dev->type, drv->type);
+}
+
+static int vbus_dev_proxy_uevent(struct device *_dev, struct kobj_uevent_env *env)
+{
+ struct vbus_device_proxy *dev = to_dev(_dev);
+
+ if (add_uevent_var(env, "MODALIAS=vbus-proxy:%s", dev->type))
+ return -ENOMEM;
+
+ return 0;
+}
+
+/*
+ * This function is invoked after the bus infrastructure has already made a
+ * match. The device will contain a reference to the paired driver which
+ * we will extract.
+ */
+static int vbus_dev_proxy_probe(struct device *_dev)
+{
+ int ret = 0;
+ struct vbus_device_proxy *dev = to_dev(_dev);
+ struct vbus_driver *drv = to_drv(_dev->driver);
+
+ if (drv->ops->probe)
+ ret = drv->ops->probe(dev);
+
+ return ret;
+}
+
+static struct bus_type vbus_proxy = {
+ .name = VBUS_PROXY_NAME,
+ .match = vbus_dev_proxy_match,
+ .uevent = vbus_dev_proxy_uevent,
+};
+
+static struct device vbus_proxy_rootdev = {
+ .parent = NULL,
+ .init_name = VBUS_PROXY_NAME,
+};
+
+static int __init vbus_init(void)
+{
+ int ret;
+
+ ret = bus_register(&vbus_proxy);
+ BUG_ON(ret < 0);
+
+ ret = device_register(&vbus_proxy_rootdev);
+ BUG_ON(ret < 0);
+
+ return 0;
+}
+
+postcore_initcall(vbus_init);
+
+static void device_release(struct device *dev)
+{
+ struct vbus_device_proxy *_dev;
+
+ _dev = container_of(dev, struct vbus_device_proxy, dev);
+
+ _dev->ops->release(_dev);
+}
+
+static ssize_t _show_modalias(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "vbus-proxy:%s\n", to_dev(dev)->type);
+}
+static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, _show_modalias, NULL);
+
+int vbus_device_proxy_register(struct vbus_device_proxy *new)
+{
+ int ret;
+
+ new->dev.parent = &vbus_proxy_rootdev;
+ new->dev.bus = &vbus_proxy;
+ new->dev.release = &device_release;
+
+ ret = device_register(&new->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = device_create_file(&new->dev, &dev_attr_modalias);
+ if (ret < 0) {
+ device_unregister(&new->dev);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vbus_device_proxy_register);
+
+void vbus_device_proxy_unregister(struct vbus_device_proxy *dev)
+{
+ device_remove_file(&dev->dev, &dev_attr_modalias);
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(vbus_device_proxy_unregister);
+
+static int match_device_id(struct device *_dev, void *data)
+{
+ struct vbus_device_proxy *dev = to_dev(_dev);
+ u64 id = *(u64 *)data;
+
+ return dev->id == id;
+}
+
+struct vbus_device_proxy *vbus_device_proxy_find(u64 id)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&vbus_proxy, NULL, &id, &match_device_id);
+
+ return to_dev(dev);
+}
+EXPORT_SYMBOL_GPL(vbus_device_proxy_find);
+
+int vbus_driver_register(struct vbus_driver *new)
+{
+ new->drv.bus = &vbus_proxy;
+ new->drv.name = new->type;
+ new->drv.owner = new->owner;
+ new->drv.probe = vbus_dev_proxy_probe;
+
+ return driver_register(&new->drv);
+}
+EXPORT_SYMBOL_GPL(vbus_driver_register);
+
+void vbus_driver_unregister(struct vbus_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(vbus_driver_unregister);
+
+/*
+ *---------------------------------
+ * driver-side IOQ helper
+ *---------------------------------
+ */
+static void
+vbus_driver_ioq_release(struct ioq *ioq)
+{
+ kfree(ioq->head_desc);
+ kfree(ioq);
+}
+
+static struct ioq_ops vbus_driver_ioq_ops = {
+ .release = vbus_driver_ioq_release,
+};
+
+
+int vbus_driver_ioq_alloc(struct vbus_device_proxy *dev, const char *name,
+ int id, int prio, size_t count, struct ioq **ioq)
+{
+ struct ioq *_ioq;
+ struct ioq_ring_head *head = NULL;
+ struct shm_signal *signal = NULL;
+ size_t len = IOQ_HEAD_DESC_SIZE(count);
+ int ret = -ENOMEM;
+
+ _ioq = kzalloc(sizeof(*_ioq), GFP_KERNEL);
+ if (!_ioq)
+ goto error;
+
+ head = kzalloc(len, GFP_KERNEL | GFP_DMA);
+ if (!head)
+ goto error;
+
+ head->magic = IOQ_RING_MAGIC;
+ head->ver = IOQ_RING_VER;
+ head->count = cpu_to_le32(count);
+
+ ret = dev->ops->shm(dev, name, id, prio, head, len,
+ &head->signal, &signal, 0);
+ if (ret < 0)
+ goto error;
+
+ ioq_init(_ioq,
+ &vbus_driver_ioq_ops,
+ ioq_locality_north,
+ head,
+ signal,
+ count);
+
+ *ioq = _ioq;
+
+ return 0;
+
+ error:
+ kfree(_ioq);
+ kfree(head);
+
+ if (signal)
+ shm_signal_put(signal);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(vbus_driver_ioq_alloc);
diff --git a/drivers/vbus/pci-bridge.c b/drivers/vbus/pci-bridge.c
new file mode 100644
index 000000000000..36de7c48891c
--- /dev/null
+++ b/drivers/vbus/pci-bridge.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright (C) 2009 Novell. All Rights Reserved.
+ *
+ * Author:
+ * Gregory Haskins <ghaskins@novell.com>
+ *
+ * This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/ioq.h>
+#include <linux/interrupt.h>
+#include <linux/vbus_driver.h>
+#include <linux/vbus_pci.h>
+
+MODULE_AUTHOR("Gregory Haskins");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1");
+
+#define VBUS_PCI_NAME "pci-to-vbus-bridge"
+
+struct vbus_pci {
+ spinlock_t lock;
+ struct pci_dev *dev;
+ struct ioq eventq;
+ struct vbus_pci_event *ring;
+ struct vbus_pci_regs *regs;
+ struct vbus_pci_signals *signals;
+ int irq;
+ bool enabled;
+ struct {
+ struct dentry *fs;
+ int events;
+ int qnotify;
+ int qinject;
+ int notify;
+ int inject;
+ int bridgecalls;
+ int buscalls;
+ } stats;
+};
+
+static struct vbus_pci vbus_pci;
+
+struct vbus_pci_device {
+ char type[VBUS_MAX_DEVTYPE_LEN];
+ u64 handle;
+ struct list_head shms;
+ struct vbus_device_proxy vdev;
+ struct work_struct drop;
+};
+
+static DEFINE_PER_CPU(struct vbus_pci_fastcall_desc, vbus_pci_percpu_fastcall)
+____cacheline_aligned;
+
+/*
+ * -------------------
+ * common routines
+ * -------------------
+ */
+
+static int
+vbus_pci_bridgecall(unsigned long nr, void *data, unsigned long len)
+{
+ struct vbus_pci_call_desc params = {
+ .vector = nr,
+ .len = len,
+ .datap = __pa(data),
+ };
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vbus_pci.lock, flags);
+
+ memcpy_toio(&vbus_pci.regs->bridgecall, &params, sizeof(params));
+ ret = ioread32(&vbus_pci.regs->bridgecall);
+
+ spin_unlock_irqrestore(&vbus_pci.lock, flags);
+
+ vbus_pci.stats.bridgecalls++;
+
+ return ret;
+}
+
+static int
+vbus_pci_buscall(unsigned long nr, void *data, unsigned long len)
+{
+ struct vbus_pci_fastcall_desc *params;
+ int ret;
+
+ preempt_disable();
+
+ params = &get_cpu_var(vbus_pci_percpu_fastcall);
+
+ params->call.vector = nr;
+ params->call.len = len;
+ params->call.datap = __pa(data);
+
+ iowrite32(smp_processor_id(), &vbus_pci.signals->fastcall);
+
+ ret = params->result;
+
+ preempt_enable();
+
+ vbus_pci.stats.buscalls++;
+
+ return ret;
+}
+
+static struct vbus_pci_device *
+to_dev(struct vbus_device_proxy *vdev)
+{
+ return container_of(vdev, struct vbus_pci_device, vdev);
+}
+
+static void
+_signal_init(struct shm_signal *signal, struct shm_signal_desc *desc,
+ struct shm_signal_ops *ops)
+{
+ desc->magic = SHM_SIGNAL_MAGIC;
+ desc->ver = SHM_SIGNAL_VER;
+
+ shm_signal_init(signal, shm_locality_north, ops, desc);
+}
+
+/*
+ * -------------------
+ * _signal
+ * -------------------
+ */
+
+struct _signal {
+ char name[64];
+ struct vbus_pci *pcivbus;
+ struct shm_signal signal;
+ u32 handle;
+ struct rb_node node;
+ struct list_head list;
+ int irq;
+ struct irq_desc *desc;
+};
+
+static struct _signal *
+to_signal(struct shm_signal *signal)
+{
+ return container_of(signal, struct _signal, signal);
+}
+
+static int
+_signal_inject(struct shm_signal *signal)
+{
+ struct _signal *_signal = to_signal(signal);
+
+ vbus_pci.stats.inject++;
+ iowrite32(_signal->handle, &vbus_pci.signals->shmsignal);
+
+ return 0;
+}
+
+static void
+_signal_release(struct shm_signal *signal)
+{
+ struct _signal *_signal = to_signal(signal);
+
+ kfree(_signal);
+}
+
+static struct shm_signal_ops _signal_ops = {
+ .inject = _signal_inject,
+ .release = _signal_release,
+};
+
+static void shmsignal_disconnect(struct _signal *_signal);
+
+/*
+ * -------------------
+ * vbus_device_proxy routines
+ * -------------------
+ */
+
+static int
+vbus_pci_device_open(struct vbus_device_proxy *vdev, int version, int flags)
+{
+ struct vbus_pci_device *dev = to_dev(vdev);
+ struct vbus_pci_deviceopen params;
+ int ret;
+
+ if (dev->handle)
+ return -EINVAL;
+
+ params.devid = vdev->id;
+ params.version = version;
+
+ ret = vbus_pci_buscall(VBUS_PCI_HC_DEVOPEN,
+ &params, sizeof(params));
+ if (ret < 0)
+ return ret;
+
+ dev->handle = params.handle;
+
+ return 0;
+}
+
+static int
+vbus_pci_device_close(struct vbus_device_proxy *vdev, int flags)
+{
+ struct vbus_pci_device *dev = to_dev(vdev);
+ unsigned long iflags;
+ int ret;
+
+ if (!dev->handle)
+ return -EINVAL;
+
+ spin_lock_irqsave(&vbus_pci.lock, iflags);
+
+ while (!list_empty(&dev->shms)) {
+ struct _signal *_signal;
+
+ _signal = list_first_entry(&dev->shms, struct _signal, list);
+
+ list_del(&_signal->list);
+ shmsignal_disconnect(_signal);
+
+ spin_unlock_irqrestore(&vbus_pci.lock, iflags);
+ shm_signal_put(&_signal->signal);
+ spin_lock_irqsave(&vbus_pci.lock, iflags);
+ }
+
+ spin_unlock_irqrestore(&vbus_pci.lock, iflags);
+
+ /*
+ * The DEVICECLOSE will implicitly close all of the shm on the
+ * host-side, so there is no need to do an explicit per-shm
+ * hypercall
+ */
+ ret = vbus_pci_buscall(VBUS_PCI_HC_DEVCLOSE,
+ &dev->handle, sizeof(dev->handle));
+
+ if (ret < 0)
+ printk(KERN_ERR "VBUS-PCI: Error closing device %s/%lld: %d\n",
+ vdev->type, vdev->id, ret);
+
+ dev->handle = 0;
+
+ return 0;
+}
+
+/*
+ * -------------------
+ * shmsignal interrupt routines
+ * -------------------
+ */
+
+/* We abstract these routines so that we can drop in irqchip later */
+
+static void
+shmsignal_wakeup(struct _signal *_signal)
+{
+ _shm_signal_wakeup(&_signal->signal);
+}
+
+static int
+shmsignal_connect(struct _signal *_signal)
+{
+ return 0;
+}
+
+static void
+shmsignal_disconnect(struct _signal *_signal)
+{
+
+}
+
+static int
+vbus_pci_device_shm(struct vbus_device_proxy *vdev, const char *name,
+ int id, int prio,
+ void *ptr, size_t len,
+ struct shm_signal_desc *sdesc, struct shm_signal **signal,
+ int flags)
+{
+ struct vbus_pci_device *dev = to_dev(vdev);
+ struct _signal *_signal = NULL;
+ struct vbus_pci_deviceshm params;
+ unsigned long iflags;
+ int ret;
+
+ if (!dev->handle)
+ return -EINVAL;
+
+ params.devh = dev->handle;
+ params.id = id;
+ params.flags = flags;
+ params.datap = (u64)__pa(ptr);
+ params.len = len;
+
+ if (signal) {
+ /*
+ * The signal descriptor must be embedded within the
+ * provided ptr
+ */
+ if (!sdesc
+ || (len < sizeof(*sdesc))
+ || ((void *)sdesc < ptr)
+ || ((void *)sdesc > (ptr + len - sizeof(*sdesc))))
+ return -EINVAL;
+
+ _signal = kzalloc(sizeof(*_signal), GFP_KERNEL);
+ if (!_signal)
+ return -ENOMEM;
+
+ _signal_init(&_signal->signal, sdesc, &_signal_ops);
+
+ /*
+ * take another reference for the host. This is dropped
+ * by a SHMCLOSE event
+ */
+ shm_signal_get(&_signal->signal);
+
+ params.signal.offset = (u64)(unsigned long)sdesc -
+ (u64)(unsigned long)ptr;
+ params.signal.prio = prio;
+ params.signal.cookie = (u64)(unsigned long)_signal;
+
+ } else
+ params.signal.offset = -1; /* yes, this is a u32, but its ok */
+
+ ret = vbus_pci_buscall(VBUS_PCI_HC_DEVSHM,
+ &params, sizeof(params));
+ if (ret < 0)
+ goto fail;
+
+ if (signal) {
+
+ BUG_ON(ret < 0);
+
+ _signal->handle = ret;
+
+ if (!name)
+ snprintf(_signal->name, sizeof(_signal->name),
+ "dev%lld-id%d", vdev->id, id);
+ else
+ snprintf(_signal->name, sizeof(_signal->name),
+ "%s", name);
+
+ shmsignal_connect(_signal);
+
+ spin_lock_irqsave(&vbus_pci.lock, iflags);
+ list_add_tail(&_signal->list, &dev->shms);
+ spin_unlock_irqrestore(&vbus_pci.lock, iflags);
+
+ shm_signal_get(&_signal->signal);
+ *signal = &_signal->signal;
+ }
+
+ return 0;
+
+fail:
+ if (_signal) {
+ /*
+ * We held two references above, so we need to drop
+ * both of them
+ */
+ shm_signal_put(&_signal->signal);
+ shm_signal_put(&_signal->signal);
+ }
+
+ return ret;
+}
+
+static int
+vbus_pci_device_call(struct vbus_device_proxy *vdev, u32 func, void *data,
+ size_t len, int flags)
+{
+ struct vbus_pci_device *dev = to_dev(vdev);
+ struct vbus_pci_devicecall params = {
+ .devh = dev->handle,
+ .func = func,
+ .datap = (u64)__pa(data),
+ .len = len,
+ .flags = flags,
+ };
+
+ if (!dev->handle)
+ return -EINVAL;
+
+ return vbus_pci_buscall(VBUS_PCI_HC_DEVCALL, &params, sizeof(params));
+}
+
+static void
+vbus_pci_device_release(struct vbus_device_proxy *vdev)
+{
+ struct vbus_pci_device *_dev = to_dev(vdev);
+
+ vbus_pci_device_close(vdev, 0);
+
+ kfree(_dev);
+}
+
+static struct vbus_device_proxy_ops vbus_pci_device_ops = {
+ .open = vbus_pci_device_open,
+ .close = vbus_pci_device_close,
+ .shm = vbus_pci_device_shm,
+ .call = vbus_pci_device_call,
+ .release = vbus_pci_device_release,
+};
+
+/*
+ * -------------------
+ * vbus events
+ * -------------------
+ */
+
+struct deferred_devadd_event {
+ struct work_struct work;
+ struct vbus_pci_add_event event;
+};
+
+static void deferred_devdrop(struct work_struct *work);
+
+static void
+deferred_devadd(struct work_struct *work)
+{
+ struct deferred_devadd_event *_event;
+ struct vbus_pci_device *new;
+ int ret;
+
+ _event = container_of(work, struct deferred_devadd_event, work);
+
+ new = kzalloc(sizeof(*new), GFP_KERNEL);
+ if (!new) {
+ printk(KERN_ERR "VBUS_PCI: Out of memory on add_event\n");
+ return;
+ }
+
+ INIT_LIST_HEAD(&new->shms);
+
+ memcpy(new->type, _event->event.type, VBUS_MAX_DEVTYPE_LEN);
+ new->vdev.type = new->type;
+ new->vdev.id = _event->event.id;
+ new->vdev.ops = &vbus_pci_device_ops;
+
+ dev_set_name(&new->vdev.dev, "%lld", _event->event.id);
+
+ INIT_WORK(&new->drop, deferred_devdrop);
+
+ ret = vbus_device_proxy_register(&new->vdev);
+ if (ret < 0)
+ panic("failed to register device %lld(%s): %d\n",
+ new->vdev.id, new->type, ret);
+
+ kfree(_event);
+}
+
+static void
+deferred_devdrop(struct work_struct *work)
+{
+ struct vbus_pci_device *dev;
+
+ dev = container_of(work, struct vbus_pci_device, drop);
+ vbus_device_proxy_unregister(&dev->vdev);
+}
+
+static void
+event_devadd(struct vbus_pci_add_event *event)
+{
+ struct deferred_devadd_event *_event;
+
+ _event = kzalloc(sizeof(*_event), GFP_ATOMIC);
+ if (!_event) {
+ printk(KERN_ERR \
+ "VBUS_PCI: Out of ATOMIC memory on add_event\n");
+ return;
+ }
+
+ INIT_WORK(&_event->work, deferred_devadd);
+ memcpy(&_event->event, event, sizeof(*event));
+
+ schedule_work(&_event->work);
+}
+
+static void
+event_devdrop(struct vbus_pci_handle_event *event)
+{
+ struct vbus_device_proxy *dev = vbus_device_proxy_find(event->handle);
+
+ if (!dev) {
+ printk(KERN_WARNING "VBUS-PCI: devdrop failed: %lld\n",
+ event->handle);
+ return;
+ }
+
+ schedule_work(&to_dev(dev)->drop);
+}
+
+static void
+event_shmsignal(struct vbus_pci_handle_event *event)
+{
+ struct _signal *_signal = (struct _signal *)(unsigned long)event->handle;
+
+ vbus_pci.stats.notify++;
+
+ shmsignal_wakeup(_signal);
+}
+
+static void
+event_shmclose(struct vbus_pci_handle_event *event)
+{
+ struct _signal *_signal = (struct _signal *)(unsigned long)event->handle;
+
+ /*
+ * This reference was taken during the DEVICESHM call
+ */
+ shm_signal_put(&_signal->signal);
+}
+
+/*
+ * -------------------
+ * eventq routines
+ * -------------------
+ */
+
+static struct ioq_notifier eventq_notifier;
+
+static int __devinit
+eventq_init(int qlen)
+{
+ struct ioq_iterator iter;
+ int ret;
+ int i;
+
+ vbus_pci.ring = kzalloc(sizeof(struct vbus_pci_event) * qlen,
+ GFP_KERNEL);
+ if (!vbus_pci.ring)
+ return -ENOMEM;
+
+ /*
+ * We want to iterate on the "valid" index. By default the iterator
+ * will not "autoupdate" which means it will not hypercall the host
+ * with our changes. This is good, because we are really just
+ * initializing stuff here anyway. Note that you can always manually
+ * signal the host with ioq_signal() if the autoupdate feature is not
+ * used.
+ */
+ ret = ioq_iter_init(&vbus_pci.eventq, &iter, ioq_idxtype_valid, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * Seek to the tail of the valid index (which should be our first
+ * item since the queue is brand-new)
+ */
+ ret = ioq_iter_seek(&iter, ioq_seek_tail, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * Now populate each descriptor with an empty vbus_event and mark it
+ * valid
+ */
+ for (i = 0; i < qlen; i++) {
+ struct vbus_pci_event *event = &vbus_pci.ring[i];
+ size_t len = sizeof(*event);
+ struct ioq_ring_desc *desc = iter.desc;
+
+ BUG_ON(iter.desc->valid);
+
+ desc->cookie = (u64)(unsigned long)event;
+ desc->ptr = cpu_to_le64(__pa(event));
+ desc->len = cpu_to_le64(len); /* total length */
+ desc->valid = 1;
+
+ /*
+ * This push operation will simultaneously advance the
+ * valid-tail index and increment our position in the queue
+ * by one.
+ */
+ ret = ioq_iter_push(&iter, 0);
+ BUG_ON(ret < 0);
+ }
+
+ vbus_pci.eventq.notifier = &eventq_notifier;
+
+ /*
+ * And finally, ensure that we can receive notification
+ */
+ ioq_notify_enable(&vbus_pci.eventq, 0);
+
+ return 0;
+}
+
+/* Invoked whenever the hypervisor ioq_signal()s our eventq */
+static void
+eventq_wakeup(struct ioq_notifier *notifier)
+{
+ struct ioq_iterator iter;
+ int ret;
+
+ /* We want to iterate on the head of the in-use index */
+ ret = ioq_iter_init(&vbus_pci.eventq, &iter, ioq_idxtype_inuse, 0);
+ BUG_ON(ret < 0);
+
+ ret = ioq_iter_seek(&iter, ioq_seek_head, 0, 0);
+ BUG_ON(ret < 0);
+
+ /*
+ * The EOM is indicated by finding a packet that is still owned by
+ * the south side.
+ *
+ * FIXME: This in theory could run indefinitely if the host keeps
+ * feeding us events since there is nothing like a NAPI budget. We
+ * might need to address that
+ */
+ while (!iter.desc->sown) {
+ struct ioq_ring_desc *desc = iter.desc;
+ struct vbus_pci_event *event;
+
+ event = (struct vbus_pci_event *)(unsigned long)desc->cookie;
+
+ switch (event->eventid) {
+ case VBUS_PCI_EVENT_DEVADD:
+ event_devadd(&event->data.add);
+ break;
+ case VBUS_PCI_EVENT_DEVDROP:
+ event_devdrop(&event->data.handle);
+ break;
+ case VBUS_PCI_EVENT_SHMSIGNAL:
+ event_shmsignal(&event->data.handle);
+ break;
+ case VBUS_PCI_EVENT_SHMCLOSE:
+ event_shmclose(&event->data.handle);
+ break;
+ default:
+ printk(KERN_WARNING "VBUS_PCI: Unexpected event %d\n",
+ event->eventid);
+ break;
+ };
+
+ memset(event, 0, sizeof(*event));
+
+ /* Advance the in-use head */
+ ret = ioq_iter_pop(&iter, 0);
+ BUG_ON(ret < 0);
+
+ vbus_pci.stats.events++;
+ }
+
+ /* And let the south side know that we changed the queue */
+ ioq_signal(&vbus_pci.eventq, 0);
+}
+
+static struct ioq_notifier eventq_notifier = {
+ .signal = &eventq_wakeup,
+};
+
+/* Injected whenever the host issues an ioq_signal() on the eventq */
+static irqreturn_t
+eventq_intr(int irq, void *dev)
+{
+ vbus_pci.stats.qnotify++;
+ _shm_signal_wakeup(vbus_pci.eventq.signal);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * -------------------
+ */
+
+static int
+eventq_signal_inject(struct shm_signal *signal)
+{
+ vbus_pci.stats.qinject++;
+
+ /* The eventq uses the special-case handle=0 */
+ iowrite32(0, &vbus_pci.signals->eventq);
+
+ return 0;
+}
+
+static void
+eventq_signal_release(struct shm_signal *signal)
+{
+ kfree(signal);
+}
+
+static struct shm_signal_ops eventq_signal_ops = {
+ .inject = eventq_signal_inject,
+ .release = eventq_signal_release,
+};
+
+/*
+ * -------------------
+ */
+
+static void
+eventq_ioq_release(struct ioq *ioq)
+{
+ /* released as part of the vbus_pci object */
+}
+
+static struct ioq_ops eventq_ioq_ops = {
+ .release = eventq_ioq_release,
+};
+
+/*
+ * -------------------
+ */
+
+static void
+vbus_pci_release(void)
+{
+#ifdef CONFIG_DEBUG_FS
+ if (vbus_pci.stats.fs)
+ debugfs_remove(vbus_pci.stats.fs);
+#endif
+
+ if (vbus_pci.irq > 0)
+ free_irq(vbus_pci.irq, NULL);
+
+ if (vbus_pci.signals)
+ pci_iounmap(vbus_pci.dev, (void *)vbus_pci.signals);
+
+ if (vbus_pci.regs)
+ pci_iounmap(vbus_pci.dev, (void *)vbus_pci.regs);
+
+ pci_release_regions(vbus_pci.dev);
+ pci_disable_device(vbus_pci.dev);
+
+ kfree(vbus_pci.eventq.head_desc);
+ kfree(vbus_pci.ring);
+
+ vbus_pci.enabled = false;
+}
+
+static int __devinit
+vbus_pci_open(void)
+{
+ struct vbus_pci_bridge_negotiate params = {
+ .magic = VBUS_PCI_ABI_MAGIC,
+ .version = VBUS_PCI_HC_VERSION,
+ .capabilities = 0,
+ };
+
+ return vbus_pci_bridgecall(VBUS_PCI_BRIDGE_NEGOTIATE,
+ &params, sizeof(params));
+}
+
+#define QLEN 1024
+
+static int __devinit
+vbus_pci_eventq_register(void)
+{
+ struct vbus_pci_busreg params = {
+ .count = 1,
+ .eventq = {
+ {
+ .count = QLEN,
+ .ring = (u64)__pa(vbus_pci.eventq.head_desc),
+ .data = (u64)__pa(vbus_pci.ring),
+ },
+ },
+ };
+
+ return vbus_pci_bridgecall(VBUS_PCI_BRIDGE_QREG,
+ &params, sizeof(params));
+}
+
+static int __devinit
+_ioq_init(size_t ringsize, struct ioq *ioq, struct ioq_ops *ops)
+{
+ struct shm_signal *signal = NULL;
+ struct ioq_ring_head *head = NULL;
+ size_t len = IOQ_HEAD_DESC_SIZE(ringsize);
+
+ head = kzalloc(len, GFP_KERNEL | GFP_DMA);
+ if (!head)
+ return -ENOMEM;
+
+ signal = kzalloc(sizeof(*signal), GFP_KERNEL);
+ if (!signal) {
+ kfree(head);
+ return -ENOMEM;
+ }
+
+ head->magic = IOQ_RING_MAGIC;
+ head->ver = IOQ_RING_VER;
+ head->count = cpu_to_le32(ringsize);
+
+ _signal_init(signal, &head->signal, &eventq_signal_ops);
+
+ ioq_init(ioq, ops, ioq_locality_north, head, signal, ringsize);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int _debugfs_seq_show(struct seq_file *m, void *p)
+{
+#define P(F) \
+ seq_printf(m, " .%-30s: %d\n", #F, (int)vbus_pci.stats.F)
+
+ P(events);
+ P(qnotify);
+ P(qinject);
+ P(notify);
+ P(inject);
+ P(bridgecalls);
+ P(buscalls);
+
+#undef P
+
+ return 0;
+}
+
+static int _debugfs_fops_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, _debugfs_seq_show, inode->i_private);
+}
+
+static const struct file_operations stat_fops = {
+ .open = _debugfs_fops_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+#endif
+
+static int __devinit
+vbus_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int ret;
+ int cpu;
+
+ if (vbus_pci.enabled)
+ return -EEXIST; /* we only support one bridge per kernel */
+
+ if (pdev->revision != VBUS_PCI_ABI_VERSION) {
+ printk(KERN_DEBUG "VBUS_PCI: expected ABI version %d, got %d\n",
+ VBUS_PCI_ABI_VERSION,
+ pdev->revision);
+ return -ENODEV;
+ }
+
+ vbus_pci.dev = pdev;
+
+ ret = pci_enable_device(pdev);
+ if (ret < 0)
+ return ret;
+
+ pci_set_master(pdev);
+
+ ret = pci_request_regions(pdev, VBUS_PCI_NAME);
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Could not init BARs: %d\n", ret);
+ goto out_fail;
+ }
+
+ vbus_pci.regs = pci_iomap(pdev, 0, sizeof(struct vbus_pci_regs));
+ if (!vbus_pci.regs) {
+ printk(KERN_ERR "VBUS_PCI: Could not map BARs\n");
+ goto out_fail;
+ }
+
+ vbus_pci.signals = pci_iomap(pdev, 1, sizeof(struct vbus_pci_signals));
+ if (!vbus_pci.signals) {
+ printk(KERN_ERR "VBUS_PCI: Could not map BARs\n");
+ goto out_fail;
+ }
+
+ ret = vbus_pci_open();
+ if (ret < 0) {
+ printk(KERN_DEBUG "VBUS_PCI: Could not register with host: %d\n",
+ ret);
+ goto out_fail;
+ }
+
+ /*
+ * Allocate an IOQ to use for host-2-guest event notification
+ */
+ ret = _ioq_init(QLEN, &vbus_pci.eventq, &eventq_ioq_ops);
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Cound not init eventq: %d\n", ret);
+ goto out_fail;
+ }
+
+ ret = eventq_init(QLEN);
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Cound not setup ring: %d\n", ret);
+ goto out_fail;
+ }
+
+ ret = pci_enable_msi(pdev);
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Cound not enable MSI: %d\n", ret);
+ goto out_fail;
+ }
+
+ vbus_pci.irq = pdev->irq;
+
+ ret = request_irq(pdev->irq, eventq_intr, 0, "vbus", NULL);
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Failed to register IRQ %d\n: %d",
+ pdev->irq, ret);
+ goto out_fail;
+ }
+
+ /*
+ * Add one fastcall vector per cpu so that we can do lockless
+ * hypercalls
+ */
+ for_each_possible_cpu(cpu) {
+ struct vbus_pci_fastcall_desc *desc =
+ &per_cpu(vbus_pci_percpu_fastcall, cpu);
+ struct vbus_pci_call_desc params = {
+ .vector = cpu,
+ .len = sizeof(*desc),
+ .datap = __pa(desc),
+ };
+
+ ret = vbus_pci_bridgecall(VBUS_PCI_BRIDGE_FASTCALL_ADD,
+ &params, sizeof(params));
+ if (ret < 0) {
+ printk(KERN_ERR \
+ "VBUS_PCI: Failed to register cpu:%d\n: %d",
+ cpu, ret);
+ goto out_fail;
+ }
+ }
+
+ /*
+ * Finally register our queue on the host to start receiving events
+ */
+ ret = vbus_pci_eventq_register();
+ if (ret < 0) {
+ printk(KERN_ERR "VBUS_PCI: Could not register with host: %d\n",
+ ret);
+ goto out_fail;
+ }
+
+#ifdef CONFIG_DEBUG_FS
+ vbus_pci.stats.fs = debugfs_create_file(VBUS_PCI_NAME, S_IRUGO,
+ NULL, NULL, &stat_fops);
+ if (IS_ERR(vbus_pci.stats.fs)) {
+ ret = PTR_ERR(vbus_pci.stats.fs);
+ printk(KERN_ERR "VBUS_PCI: error creating stats-fs: %d\n", ret);
+ goto out_fail;
+ }
+#endif
+
+ vbus_pci.enabled = true;
+
+ printk(KERN_INFO "Virtual-Bus: Copyright (c) 2009, " \
+ "Gregory Haskins <ghaskins@novell.com>\n");
+
+ return 0;
+
+ out_fail:
+ vbus_pci_release();
+
+ return ret;
+}
+
+static void __devexit
+vbus_pci_remove(struct pci_dev *pdev)
+{
+ vbus_pci_release();
+}
+
+static DEFINE_PCI_DEVICE_TABLE(vbus_pci_tbl) = {
+ { PCI_DEVICE(0x11da, 0x2000) },
+ { 0 },
+};
+
+MODULE_DEVICE_TABLE(pci, vbus_pci_tbl);
+
+static struct pci_driver vbus_pci_driver = {
+ .name = VBUS_PCI_NAME,
+ .id_table = vbus_pci_tbl,
+ .probe = vbus_pci_probe,
+ .remove = vbus_pci_remove,
+};
+
+static int __init
+vbus_pci_init(void)
+{
+ memset(&vbus_pci, 0, sizeof(vbus_pci));
+ spin_lock_init(&vbus_pci.lock);
+
+ return pci_register_driver(&vbus_pci_driver);
+}
+
+static void __exit
+vbus_pci_exit(void)
+{
+ pci_unregister_driver(&vbus_pci_driver);
+}
+
+module_init(vbus_pci_init);
+module_exit(vbus_pci_exit);
+
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 29e850a7a2f9..a3fd140c1422 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -127,7 +127,10 @@ static void handle_tx(struct vhost_net *net)
size_t len, total_len = 0;
int err, wmem;
size_t hdr_size;
- struct socket *sock = rcu_dereference(vq->private_data);
+ struct socket *sock;
+
+ sock = rcu_dereference_check(vq->private_data,
+ lockdep_is_held(&vq->mutex));
if (!sock)
return;
@@ -582,7 +585,10 @@ static void vhost_net_disable_vq(struct vhost_net *n,
static void vhost_net_enable_vq(struct vhost_net *n,
struct vhost_virtqueue *vq)
{
- struct socket *sock = vq->private_data;
+ struct socket *sock;
+
+ sock = rcu_dereference_protected(vq->private_data,
+ lockdep_is_held(&vq->mutex));
if (!sock)
return;
if (vq == n->vqs + VHOST_NET_VQ_TX) {
@@ -598,7 +604,8 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n,
struct socket *sock;
mutex_lock(&vq->mutex);
- sock = vq->private_data;
+ sock = rcu_dereference_protected(vq->private_data,
+ lockdep_is_held(&vq->mutex));
vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, NULL);
mutex_unlock(&vq->mutex);
@@ -736,7 +743,8 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
}
/* start polling new socket */
- oldsock = vq->private_data;
+ oldsock = rcu_dereference_protected(vq->private_data,
+ lockdep_is_held(&vq->mutex));
if (sock != oldsock) {
vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, sock);
@@ -869,6 +877,7 @@ static const struct file_operations vhost_net_fops = {
.compat_ioctl = vhost_net_compat_ioctl,
#endif
.open = vhost_net_open,
+ .llseek = noop_llseek,/* no read or write fn */
};
static struct miscdevice vhost_net_misc = {
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e05557d52999..32c3747902e5 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -60,22 +60,25 @@ static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync,
return 0;
}
+static void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn)
+{
+ INIT_LIST_HEAD(&work->node);
+ work->fn = fn;
+ init_waitqueue_head(&work->done);
+ work->flushing = 0;
+ work->queue_seq = work->done_seq = 0;
+}
+
/* Init poll structure */
void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
unsigned long mask, struct vhost_dev *dev)
{
- struct vhost_work *work = &poll->work;
-
init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup);
init_poll_funcptr(&poll->table, vhost_poll_func);
poll->mask = mask;
poll->dev = dev;
- INIT_LIST_HEAD(&work->node);
- work->fn = fn;
- init_waitqueue_head(&work->done);
- work->flushing = 0;
- work->queue_seq = work->done_seq = 0;
+ vhost_work_init(&poll->work, fn);
}
/* Start polling a file. We add ourselves to file's wait queue. The caller must
@@ -95,35 +98,38 @@ void vhost_poll_stop(struct vhost_poll *poll)
remove_wait_queue(poll->wqh, &poll->wait);
}
-/* Flush any work that has been scheduled. When calling this, don't hold any
- * locks that are also used by the callback. */
-void vhost_poll_flush(struct vhost_poll *poll)
+static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
{
- struct vhost_work *work = &poll->work;
unsigned seq;
int left;
int flushing;
- spin_lock_irq(&poll->dev->work_lock);
+ spin_lock_irq(&dev->work_lock);
seq = work->queue_seq;
work->flushing++;
- spin_unlock_irq(&poll->dev->work_lock);
+ spin_unlock_irq(&dev->work_lock);
wait_event(work->done, ({
- spin_lock_irq(&poll->dev->work_lock);
+ spin_lock_irq(&dev->work_lock);
left = seq - work->done_seq <= 0;
- spin_unlock_irq(&poll->dev->work_lock);
+ spin_unlock_irq(&dev->work_lock);
left;
}));
- spin_lock_irq(&poll->dev->work_lock);
+ spin_lock_irq(&dev->work_lock);
flushing = --work->flushing;
- spin_unlock_irq(&poll->dev->work_lock);
+ spin_unlock_irq(&dev->work_lock);
BUG_ON(flushing < 0);
}
-void vhost_poll_queue(struct vhost_poll *poll)
+/* Flush any work that has been scheduled. When calling this, don't hold any
+ * locks that are also used by the callback. */
+void vhost_poll_flush(struct vhost_poll *poll)
+{
+ vhost_work_flush(poll->dev, &poll->work);
+}
+
+static inline void vhost_work_queue(struct vhost_dev *dev,
+ struct vhost_work *work)
{
- struct vhost_dev *dev = poll->dev;
- struct vhost_work *work = &poll->work;
unsigned long flags;
spin_lock_irqsave(&dev->work_lock, flags);
@@ -135,6 +141,11 @@ void vhost_poll_queue(struct vhost_poll *poll)
spin_unlock_irqrestore(&dev->work_lock, flags);
}
+void vhost_poll_queue(struct vhost_poll *poll)
+{
+ vhost_work_queue(poll->dev, &poll->work);
+}
+
static void vhost_vq_reset(struct vhost_dev *dev,
struct vhost_virtqueue *vq)
{
@@ -236,6 +247,29 @@ long vhost_dev_check_owner(struct vhost_dev *dev)
return dev->mm == current->mm ? 0 : -EPERM;
}
+struct vhost_attach_cgroups_struct {
+ struct vhost_work work;
+ struct task_struct *owner;
+ int ret;
+};
+
+static void vhost_attach_cgroups_work(struct vhost_work *work)
+{
+ struct vhost_attach_cgroups_struct *s;
+ s = container_of(work, struct vhost_attach_cgroups_struct, work);
+ s->ret = cgroup_attach_task_all(s->owner, current);
+}
+
+static int vhost_attach_cgroups(struct vhost_dev *dev)
+{
+ struct vhost_attach_cgroups_struct attach;
+ attach.owner = current;
+ vhost_work_init(&attach.work, vhost_attach_cgroups_work);
+ vhost_work_queue(dev, &attach.work);
+ vhost_work_flush(dev, &attach.work);
+ return attach.ret;
+}
+
/* Caller should have device mutex */
static long vhost_dev_set_owner(struct vhost_dev *dev)
{
@@ -255,14 +289,16 @@ static long vhost_dev_set_owner(struct vhost_dev *dev)
}
dev->worker = worker;
- err = cgroup_attach_task_current_cg(worker);
+ wake_up_process(worker); /* avoid contributing to loadavg */
+
+ err = vhost_attach_cgroups(dev);
if (err)
goto err_cgroup;
- wake_up_process(worker); /* avoid contributing to loadavg */
return 0;
err_cgroup:
kthread_stop(worker);
+ dev->worker = NULL;
err_worker:
if (dev->mm)
mmput(dev->mm);
@@ -284,7 +320,7 @@ long vhost_dev_reset_owner(struct vhost_dev *dev)
vhost_dev_cleanup(dev);
memory->nregions = 0;
- dev->memory = memory;
+ RCU_INIT_POINTER(dev->memory, memory);
return 0;
}
@@ -316,14 +352,18 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
fput(dev->log_file);
dev->log_file = NULL;
/* No one will access memory at this point */
- kfree(dev->memory);
- dev->memory = NULL;
+ kfree(rcu_dereference_protected(dev->memory,
+ lockdep_is_held(&dev->mutex)));
+ RCU_INIT_POINTER(dev->memory, NULL);
if (dev->mm)
mmput(dev->mm);
dev->mm = NULL;
WARN_ON(!list_empty(&dev->work_list));
- kthread_stop(dev->worker);
+ if (dev->worker) {
+ kthread_stop(dev->worker);
+ dev->worker = NULL;
+ }
}
static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz)
@@ -401,14 +441,22 @@ static int vq_access_ok(unsigned int num,
/* Caller should have device mutex but not vq mutex */
int vhost_log_access_ok(struct vhost_dev *dev)
{
- return memory_access_ok(dev, dev->memory, 1);
+ struct vhost_memory *mp;
+
+ mp = rcu_dereference_protected(dev->memory,
+ lockdep_is_held(&dev->mutex));
+ return memory_access_ok(dev, mp, 1);
}
/* Verify access for write logging. */
/* Caller should have vq mutex and device mutex */
static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
{
- return vq_memory_access_ok(log_base, vq->dev->memory,
+ struct vhost_memory *mp;
+
+ mp = rcu_dereference_protected(vq->dev->memory,
+ lockdep_is_held(&vq->mutex));
+ return vq_memory_access_ok(log_base, mp,
vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) &&
(!vq->log_used || log_access_ok(log_base, vq->log_addr,
sizeof *vq->used +
@@ -448,7 +496,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
kfree(newmem);
return -EFAULT;
}
- oldmem = d->memory;
+ oldmem = rcu_dereference_protected(d->memory,
+ lockdep_is_held(&d->mutex));
rcu_assign_pointer(d->memory, newmem);
synchronize_rcu();
kfree(oldmem);
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index afd77295971c..af3c11ded5fd 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -106,7 +106,7 @@ struct vhost_virtqueue {
* vhost_work execution acts instead of rcu_read_lock() and the end of
* vhost_work execution acts instead of rcu_read_lock().
* Writers use virtqueue mutex. */
- void *private_data;
+ void __rcu *private_data;
/* Log write descriptors */
void __user *log_base;
struct vhost_log log[VHOST_NET_MAX_SG];
@@ -116,7 +116,7 @@ struct vhost_dev {
/* Readers use RCU to access memory table pointer
* log base pointer and features.
* Writers use mutex below.*/
- struct vhost_memory *memory;
+ struct vhost_memory __rcu *memory;
struct mm_struct *mm;
struct mutex mutex;
unsigned acked_features;
@@ -173,7 +173,11 @@ enum {
static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
{
- unsigned acked_features = rcu_dereference(dev->acked_features);
+ unsigned acked_features;
+
+ acked_features =
+ rcu_dereference_index_check(dev->acked_features,
+ lockdep_is_held(&dev->mutex));
return acked_features & (1 << bit);
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 8b31fdfefc98..43e90b899fe1 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1919,6 +1919,7 @@ config FB_SH_MOBILE_HDMI
tristate "SuperH Mobile HDMI controller support"
depends on FB_SH_MOBILE_LCDC
select FB_MODE_HELPERS
+ select SND_SOC
---help---
Driver for the on-chip SH-Mobile HDMI controller.
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index b020ba7f1cf2..e7d0f525041e 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -241,12 +241,12 @@ static int request_ports(struct bfin_bf54xfb_info *fbi)
u16 disp = fbi->mach_info->disp;
if (gpio_request(disp, DRIVER_NAME)) {
- printk(KERN_ERR "Requesting GPIO %d faild\n", disp);
+ printk(KERN_ERR "Requesting GPIO %d failed\n", disp);
return -EFAULT;
}
if (peripheral_request_list(eppi_req_18, DRIVER_NAME)) {
- printk(KERN_ERR "Requesting Peripherals faild\n");
+ printk(KERN_ERR "Requesting Peripherals failed\n");
gpio_free(disp);
return -EFAULT;
}
@@ -256,7 +256,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi)
u16 eppi_req_24[] = EPPI0_24;
if (peripheral_request_list(eppi_req_24, DRIVER_NAME)) {
- printk(KERN_ERR "Requesting Peripherals faild\n");
+ printk(KERN_ERR "Requesting Peripherals failed\n");
peripheral_free_list(eppi_req_18);
gpio_free(disp);
return -EFAULT;
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 7a50272eaab9..3cf77676947c 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -192,7 +192,7 @@ static int bfin_t350mcqb_request_ports(int action)
{
if (action) {
if (peripheral_request_list(ppi0_req_8, DRIVER_NAME)) {
- printk(KERN_ERR "Requesting Peripherals faild\n");
+ printk(KERN_ERR "Requesting Peripherals failed\n");
return -EFAULT;
}
} else
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index b06647517c0e..80ba80d5cf7c 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1439,6 +1439,7 @@ static const struct file_operations fb_fops = {
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
#endif
+ .llseek = default_llseek,/* read accesses f_pos */
};
struct class *fb_class;
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index ecad96524570..cfa6d8b36011 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -175,36 +175,42 @@ static const struct file_operations sysconf_fops = {
.read = sysconf_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations clock_fops = {
.read = clock_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations display_fops = {
.read = display_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations gsctl_fops = {
.read = gsctl_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations sdram_fops = {
.read = sdram_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static const struct file_operations misc_fops = {
.read = misc_read_file,
.write = write_file_dummy,
.open = open_file_generic,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 881c9f77c75a..12327bbfdbbb 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -40,7 +40,7 @@ config PANEL_TPO_TD043MTEA1
config PANEL_ACX565AKM
tristate "ACX565AKM Panel"
- depends on OMAP2_DSS_SDI
+ depends on OMAP2_DSS_SDI && SPI
select BACKLIGHT_CLASS_DEVICE
help
This is the LCD panel used on Nokia N900
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5ecdc0004094..90eb11083cc7 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -139,6 +139,22 @@ struct omap_dispc_isr_data {
u32 mask;
};
+struct dispc_h_coef {
+ s8 hc4;
+ s8 hc3;
+ u8 hc2;
+ s8 hc1;
+ s8 hc0;
+};
+
+struct dispc_v_coef {
+ s8 vc22;
+ s8 vc2;
+ u8 vc1;
+ s8 vc0;
+ s8 vc00;
+};
+
#define REG_GET(idx, start, end) \
FLD_GET(dispc_read_reg(idx), start, end)
@@ -564,106 +580,77 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
int vscaleup, int five_taps)
{
/* Coefficients for horizontal up-sampling */
- static const u32 coef_hup[8] = {
- 0x00800000,
- 0x0D7CF800,
- 0x1E70F5FF,
- 0x335FF5FE,
- 0xF74949F7,
- 0xF55F33FB,
- 0xF5701EFE,
- 0xF87C0DFF,
+ static const struct dispc_h_coef coef_hup[8] = {
+ { 0, 0, 128, 0, 0 },
+ { -1, 13, 124, -8, 0 },
+ { -2, 30, 112, -11, -1 },
+ { -5, 51, 95, -11, -2 },
+ { 0, -9, 73, 73, -9 },
+ { -2, -11, 95, 51, -5 },
+ { -1, -11, 112, 30, -2 },
+ { 0, -8, 124, 13, -1 },
};
- /* Coefficients for horizontal down-sampling */
- static const u32 coef_hdown[8] = {
- 0x24382400,
- 0x28371FFE,
- 0x2C361BFB,
- 0x303516F9,
- 0x11343311,
- 0x1635300C,
- 0x1B362C08,
- 0x1F372804,
+ /* Coefficients for vertical up-sampling */
+ static const struct dispc_v_coef coef_vup_3tap[8] = {
+ { 0, 0, 128, 0, 0 },
+ { 0, 3, 123, 2, 0 },
+ { 0, 12, 111, 5, 0 },
+ { 0, 32, 89, 7, 0 },
+ { 0, 0, 64, 64, 0 },
+ { 0, 7, 89, 32, 0 },
+ { 0, 5, 111, 12, 0 },
+ { 0, 2, 123, 3, 0 },
};
- /* Coefficients for horizontal and vertical up-sampling */
- static const u32 coef_hvup[2][8] = {
- {
- 0x00800000,
- 0x037B02FF,
- 0x0C6F05FE,
- 0x205907FB,
- 0x00404000,
- 0x075920FE,
- 0x056F0CFF,
- 0x027B0300,
- },
- {
- 0x00800000,
- 0x0D7CF8FF,
- 0x1E70F5FE,
- 0x335FF5FB,
- 0xF7404000,
- 0xF55F33FE,
- 0xF5701EFF,
- 0xF87C0D00,
- },
+ static const struct dispc_v_coef coef_vup_5tap[8] = {
+ { 0, 0, 128, 0, 0 },
+ { -1, 13, 124, -8, 0 },
+ { -2, 30, 112, -11, -1 },
+ { -5, 51, 95, -11, -2 },
+ { 0, -9, 73, 73, -9 },
+ { -2, -11, 95, 51, -5 },
+ { -1, -11, 112, 30, -2 },
+ { 0, -8, 124, 13, -1 },
};
- /* Coefficients for horizontal and vertical down-sampling */
- static const u32 coef_hvdown[2][8] = {
- {
- 0x24382400,
- 0x28391F04,
- 0x2D381B08,
- 0x3237170C,
- 0x123737F7,
- 0x173732F9,
- 0x1B382DFB,
- 0x1F3928FE,
- },
- {
- 0x24382400,
- 0x28371F04,
- 0x2C361B08,
- 0x3035160C,
- 0x113433F7,
- 0x163530F9,
- 0x1B362CFB,
- 0x1F3728FE,
- },
+ /* Coefficients for horizontal down-sampling */
+ static const struct dispc_h_coef coef_hdown[8] = {
+ { 0, 36, 56, 36, 0 },
+ { 4, 40, 55, 31, -2 },
+ { 8, 44, 54, 27, -5 },
+ { 12, 48, 53, 22, -7 },
+ { -9, 17, 52, 51, 17 },
+ { -7, 22, 53, 48, 12 },
+ { -5, 27, 54, 44, 8 },
+ { -2, 31, 55, 40, 4 },
};
- /* Coefficients for vertical up-sampling */
- static const u32 coef_vup[8] = {
- 0x00000000,
- 0x0000FF00,
- 0x0000FEFF,
- 0x0000FBFE,
- 0x000000F7,
- 0x0000FEFB,
- 0x0000FFFE,
- 0x000000FF,
+ /* Coefficients for vertical down-sampling */
+ static const struct dispc_v_coef coef_vdown_3tap[8] = {
+ { 0, 36, 56, 36, 0 },
+ { 0, 40, 57, 31, 0 },
+ { 0, 45, 56, 27, 0 },
+ { 0, 50, 55, 23, 0 },
+ { 0, 18, 55, 55, 0 },
+ { 0, 23, 55, 50, 0 },
+ { 0, 27, 56, 45, 0 },
+ { 0, 31, 57, 40, 0 },
};
-
- /* Coefficients for vertical down-sampling */
- static const u32 coef_vdown[8] = {
- 0x00000000,
- 0x000004FE,
- 0x000008FB,
- 0x00000CF9,
- 0x0000F711,
- 0x0000F90C,
- 0x0000FB08,
- 0x0000FE04,
+ static const struct dispc_v_coef coef_vdown_5tap[8] = {
+ { 0, 36, 56, 36, 0 },
+ { 4, 40, 55, 31, -2 },
+ { 8, 44, 54, 27, -5 },
+ { 12, 48, 53, 22, -7 },
+ { -9, 17, 52, 51, 17 },
+ { -7, 22, 53, 48, 12 },
+ { -5, 27, 54, 44, 8 },
+ { -2, 31, 55, 40, 4 },
};
- const u32 *h_coef;
- const u32 *hv_coef;
- const u32 *hv_coef_mod;
- const u32 *v_coef;
+ const struct dispc_h_coef *h_coef;
+ const struct dispc_v_coef *v_coef;
int i;
if (hscaleup)
@@ -671,47 +658,34 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
else
h_coef = coef_hdown;
- if (vscaleup) {
- hv_coef = coef_hvup[five_taps];
- v_coef = coef_vup;
-
- if (hscaleup)
- hv_coef_mod = NULL;
- else
- hv_coef_mod = coef_hvdown[five_taps];
- } else {
- hv_coef = coef_hvdown[five_taps];
- v_coef = coef_vdown;
-
- if (hscaleup)
- hv_coef_mod = coef_hvup[five_taps];
- else
- hv_coef_mod = NULL;
- }
+ if (vscaleup)
+ v_coef = five_taps ? coef_vup_5tap : coef_vup_3tap;
+ else
+ v_coef = five_taps ? coef_vdown_5tap : coef_vdown_3tap;
for (i = 0; i < 8; i++) {
u32 h, hv;
- h = h_coef[i];
-
- hv = hv_coef[i];
-
- if (hv_coef_mod) {
- hv &= 0xffffff00;
- hv |= (hv_coef_mod[i] & 0xff);
- }
+ h = FLD_VAL(h_coef[i].hc0, 7, 0)
+ | FLD_VAL(h_coef[i].hc1, 15, 8)
+ | FLD_VAL(h_coef[i].hc2, 23, 16)
+ | FLD_VAL(h_coef[i].hc3, 31, 24);
+ hv = FLD_VAL(h_coef[i].hc4, 7, 0)
+ | FLD_VAL(v_coef[i].vc0, 15, 8)
+ | FLD_VAL(v_coef[i].vc1, 23, 16)
+ | FLD_VAL(v_coef[i].vc2, 31, 24);
_dispc_write_firh_reg(plane, i, h);
_dispc_write_firhv_reg(plane, i, hv);
}
- if (!five_taps)
- return;
-
- for (i = 0; i < 8; i++) {
- u32 v;
- v = v_coef[i];
- _dispc_write_firv_reg(plane, i, v);
+ if (five_taps) {
+ for (i = 0; i < 8; i++) {
+ u32 v;
+ v = FLD_VAL(v_coef[i].vc00, 7, 0)
+ | FLD_VAL(v_coef[i].vc22, 15, 8);
+ _dispc_write_firv_reg(plane, i, v);
+ }
}
}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 04034d410d6d..bddfca6f7f70 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -714,10 +714,10 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
var->pixclock = timings.pixel_clock != 0 ?
KHZ2PICOS(timings.pixel_clock) :
0;
- var->left_margin = timings.hfp;
- var->right_margin = timings.hbp;
- var->upper_margin = timings.vfp;
- var->lower_margin = timings.vbp;
+ var->left_margin = timings.hbp;
+ var->right_margin = timings.hfp;
+ var->upper_margin = timings.vbp;
+ var->lower_margin = timings.vfp;
var->hsync_len = timings.hsw;
var->vsync_len = timings.vsw;
} else {
@@ -1436,7 +1436,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
}
if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
- vaddr = ioremap_wc(paddr, size);
+ vaddr = omap_vram_remap(size, paddr);
if (!vaddr) {
dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
@@ -2059,10 +2059,10 @@ static int omapfb_mode_to_timings(const char *mode_str,
if (r != 0) {
timings->pixel_clock = PICOS2KHZ(var.pixclock);
- timings->hfp = var.left_margin;
- timings->hbp = var.right_margin;
- timings->vfp = var.upper_margin;
- timings->vbp = var.lower_margin;
+ timings->hbp = var.left_margin;
+ timings->hfp = var.right_margin;
+ timings->vbp = var.upper_margin;
+ timings->vfp = var.lower_margin;
timings->hsw = var.hsync_len;
timings->vsw = var.vsync_len;
timings->x_res = var.xres;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index f6fdc2085f3e..37557b60c171 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -30,6 +30,7 @@
#include <linux/debugfs.h>
#include <linux/jiffies.h>
#include <linux/module.h>
+#include <linux/io.h>
#include <asm/setup.h>
@@ -425,6 +426,15 @@ void omap_vram_get_info(unsigned long *vram,
}
EXPORT_SYMBOL(omap_vram_get_info);
+void __iomem *omap_vram_remap(size_t size, unsigned long paddr)
+{
+ if (region_mem_type(paddr) == OMAP_VRAM_MEMTYPE_SDRAM)
+ return phys_to_virt(paddr);
+
+ return ioremap_wc(paddr, size);
+}
+EXPORT_SYMBOL(omap_vram_remap);
+
#if defined(CONFIG_DEBUG_FS)
static int vram_debug_show(struct seq_file *s, void *unused)
{
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c
index c91a7f70f7b0..5d786bd3e304 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/pxa168fb.c
@@ -559,7 +559,7 @@ static struct fb_ops pxa168fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int __init pxa168fb_init_mode(struct fb_info *info,
+static int __devinit pxa168fb_init_mode(struct fb_info *info,
struct pxa168fb_mach_info *mi)
{
struct pxa168fb_info *fbi = info->par;
@@ -599,7 +599,7 @@ static int __init pxa168fb_init_mode(struct fb_info *info,
return ret;
}
-static int __init pxa168fb_probe(struct platform_device *pdev)
+static int __devinit pxa168fb_probe(struct platform_device *pdev)
{
struct pxa168fb_mach_info *mi;
struct fb_info *info = 0;
@@ -792,7 +792,7 @@ static struct platform_driver pxa168fb_driver = {
.probe = pxa168fb_probe,
};
-static int __devinit pxa168fb_init(void)
+static int __init pxa168fb_init(void)
{
return platform_driver_register(&pxa168fb_driver);
}
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index fc32c323a381..f5a39f5aa900 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -28,7 +28,7 @@
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
-static struct fb_fix_screeninfo q40fb_fix __initdata = {
+static struct fb_fix_screeninfo q40fb_fix __devinitdata = {
.id = "Q40",
.smem_len = 1024*1024,
.type = FB_TYPE_PACKED_PIXELS,
@@ -37,7 +37,7 @@ static struct fb_fix_screeninfo q40fb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
-static struct fb_var_screeninfo q40fb_var __initdata = {
+static struct fb_var_screeninfo q40fb_var __devinitdata = {
.xres = 1024,
.yres = 512,
.xres_virtual = 1024,
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 5699ce0c1780..3f3d431033ca 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -123,83 +123,87 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
u32 linelength;
bool yuv;
- /* Select data format */
+ /*
+ * Select data format. MIPI DSI is not hot-pluggable, so, we just use
+ * the default videomode. If this ever becomes a problem, We'll have to
+ * move this to mipi_display_on() above and use info->var.xres
+ */
switch (pdata->data_format) {
case MIPI_RGB888:
pctype = 0;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_cfg.xres * 3;
+ linelength = ch->lcd_cfg[0].xres * 3;
yuv = false;
break;
case MIPI_RGB565:
pctype = 1;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_cfg.xres * 2;
+ linelength = ch->lcd_cfg[0].xres * 2;
yuv = false;
break;
case MIPI_RGB666_LP:
pctype = 2;
datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_cfg.xres * 3;
+ linelength = ch->lcd_cfg[0].xres * 3;
yuv = false;
break;
case MIPI_RGB666:
pctype = 3;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
- linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+ linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
yuv = false;
break;
case MIPI_BGR888:
pctype = 8;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_cfg.xres * 3;
+ linelength = ch->lcd_cfg[0].xres * 3;
yuv = false;
break;
case MIPI_BGR565:
pctype = 9;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_cfg.xres * 2;
+ linelength = ch->lcd_cfg[0].xres * 2;
yuv = false;
break;
case MIPI_BGR666_LP:
pctype = 0xa;
datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
- linelength = ch->lcd_cfg.xres * 3;
+ linelength = ch->lcd_cfg[0].xres * 3;
yuv = false;
break;
case MIPI_BGR666:
pctype = 0xb;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
- linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+ linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
yuv = false;
break;
case MIPI_YUYV:
pctype = 4;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_cfg.xres * 2;
+ linelength = ch->lcd_cfg[0].xres * 2;
yuv = true;
break;
case MIPI_UYVY:
pctype = 5;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
- linelength = ch->lcd_cfg.xres * 2;
+ linelength = ch->lcd_cfg[0].xres * 2;
yuv = true;
break;
case MIPI_YUV420_L:
pctype = 6;
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
- linelength = (ch->lcd_cfg.xres * 12 + 7) / 8;
+ linelength = (ch->lcd_cfg[0].xres * 12 + 7) / 8;
yuv = true;
break;
case MIPI_YUV420:
@@ -207,7 +211,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
/* Length of U/V line */
- linelength = (ch->lcd_cfg.xres + 1) / 2;
+ linelength = (ch->lcd_cfg[0].xres + 1) / 2;
yuv = true;
break;
default:
@@ -281,7 +285,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
/*
* 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
- * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
+ * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default
* (unused, since VMCTR2[HSABM] = 0)
*/
iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 2fde08cc66bf..e78298330ab3 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -22,10 +22,14 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
#include <video/sh_mobile_hdmi.h>
#include <video/sh_mobile_lcdc.h>
+#include "sh_mobile_lcdcfb.h"
+
#define HDMI_SYSTEM_CTRL 0x00 /* System control */
#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control,
bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
@@ -204,12 +208,15 @@ enum hotplug_state {
struct sh_hdmi {
void __iomem *base;
- enum hotplug_state hp_state;
+ enum hotplug_state hp_state; /* hot-plug status */
+ bool preprogrammed_mode; /* use a pre-programmed VIC or the external mode */
struct clk *hdmi_clk;
struct device *dev;
struct fb_info *info;
+ struct mutex mutex; /* Protect the info pointer */
struct delayed_work edid_work;
struct fb_var_screeninfo var;
+ struct fb_monspecs monspec;
};
static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -222,8 +229,60 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
return ioread8(hdmi->base + reg);
}
+/*
+ * HDMI sound
+ */
+static unsigned int sh_hdmi_snd_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
+
+ return hdmi_read(hdmi, reg);
+}
+
+static int sh_hdmi_snd_write(struct snd_soc_codec *codec,
+ unsigned int reg,
+ unsigned int value)
+{
+ struct sh_hdmi *hdmi = snd_soc_codec_get_drvdata(codec);
+
+ hdmi_write(hdmi, value, reg);
+ return 0;
+}
+
+static struct snd_soc_dai_driver sh_hdmi_dai = {
+ .name = "sh_mobile_hdmi-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
+ },
+};
+
+static int sh_hdmi_snd_probe(struct snd_soc_codec *codec)
+{
+ dev_info(codec->dev, "SH Mobile HDMI Audio Codec");
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
+ .probe = sh_hdmi_snd_probe,
+ .read = sh_hdmi_snd_read,
+ .write = sh_hdmi_snd_write,
+};
+
+/*
+ * HDMI video
+ */
+
/* External video parameter settings */
-static void hdmi_external_video_param(struct sh_hdmi *hdmi)
+static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi)
{
struct fb_var_screeninfo *var = &hdmi->var;
u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
@@ -255,9 +314,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
sync |= 8;
- pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
- htotal, hblank, hdelay, var->hsync_len,
- vtotal, vblank, vdelay, var->vsync_len, sync);
+ dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
+ htotal, hblank, hdelay, var->hsync_len,
+ vtotal, vblank, vdelay, var->vsync_len, sync);
hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
@@ -282,7 +341,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
- /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */
+ /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
+ if (!hdmi->preprogrammed_mode)
+ hdmi_write(hdmi, sync | 1 | (voffset << 4),
+ HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
}
/**
@@ -318,6 +380,9 @@ static void sh_hdmi_video_config(struct sh_hdmi *hdmi)
*/
static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
{
+ u8 data;
+ struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+
/*
* [7:4] L/R data swap control
* [3:0] appropriate N[19:16]
@@ -335,7 +400,23 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
* [6:5] set required down sampling rate if required
* [4:3] set required audio source
*/
- hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1);
+ switch (pdata->flags & HDMI_SND_SRC_MASK) {
+ default:
+ /* fall through */
+ case HDMI_SND_SRC_I2S:
+ data = 0x0 << 3;
+ break;
+ case HDMI_SND_SRC_SPDIF:
+ data = 0x1 << 3;
+ break;
+ case HDMI_SND_SRC_DSD:
+ data = 0x2 << 3;
+ break;
+ case HDMI_SND_SRC_HBR:
+ data = 0x3 << 3;
+ break;
+ }
+ hdmi_write(hdmi, data, HDMI_AUDIO_SETTING_1);
/* [3:0] set sending channel number for channel status */
hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2);
@@ -381,21 +462,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
}
/**
- * sh_hdmi_phy_config()
+ * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode
*/
static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
{
- /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
- hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
- hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
- hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
- /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
- hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
- hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
- hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
- hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
- hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
- hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+ if (hdmi->var.yres > 480) {
+ /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
+ /*
+ * [1:0] Speed_A
+ * [3:2] Speed_B
+ * [4] PLLA_Bypass
+ * [6] DRV_TEST_EN
+ * [7] DRV_TEST_IN
+ */
+ hdmi_write(hdmi, 0x0f, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
+ /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */
+ hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
+ /*
+ * [2:0] BGR_I_OFFSET
+ * [6:4] BGR_V_OFFSET
+ */
+ hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
+ /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
+ hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
+ /*
+ * PLLA_CONFIG[15:8]: regulator voltage[0], CP current,
+ * LPF capacitance, LPF resistance[1]
+ */
+ hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
+ /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */
+ hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
+ /*
+ * PLLB_CONFIG[15:8]: regulator voltage[0], CP current,
+ * LPF capacitance, LPF resistance[1]
+ */
+ hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
+ /* DRV_CONFIG, PE_CONFIG */
+ hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
+ /*
+ * [2:0] AMON_SEL (4 == LPF voltage)
+ * [4] PLLA_CONFIG[16]
+ * [5] PLLB_CONFIG[16]
+ */
+ hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+ } else {
+ /* for 480p8bit 27MHz */
+ hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
+ hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
+ hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
+ hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
+ hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
+ hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
+ hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
+ hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
+ hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+ }
}
/**
@@ -403,6 +524,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
*/
static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
{
+ u8 vic;
+
/* AVI InfoFrame */
hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX);
@@ -427,9 +550,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
/*
- * C = No Data
- * M = 16:9 Picture Aspect Ratio
- * R = Same as picture aspect ratio
+ * [7:6] C = Colorimetry: no data
+ * [5:4] M = 2: 16:9, 1: 4:3 Picture Aspect Ratio
+ * [3:0] R = 8: Active Frame Aspect Ratio: same as picture aspect ratio
*/
hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
@@ -443,9 +566,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
/*
* VIC = 1280 x 720p: ignored if external config is used
- * Send 2 for 720 x 480p, 16 for 1080p
+ * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode
*/
- hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
+ if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920)
+ vic = 16;
+ else if (hdmi->var.yres == 480 && hdmi->var.xres == 720)
+ vic = 2;
+ else
+ vic = 4;
+ hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
/* PR = No Repetition */
hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
@@ -519,100 +648,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
}
/**
- * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
- */
-static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi)
-{
- int i;
-
- /* Gamut Metadata Packet */
- hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX);
-
- /* Packet Type = 0x0A */
- hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
- /* Gamut Packet is not used, so default value */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
- /* Gamut Packet is not used, so default value */
- hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
- /* GBD bytes 0 through 27 */
- for (i = 0; i <= 27; i++)
- /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
- */
-static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi)
-{
- int i;
-
- /* Audio Content Protection Packet (ACP) */
- hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX);
-
- /* Packet Type = 0x04 */
- hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
- /* ACP_Type */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
- /* Reserved (0) */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
- /* GBD bytes 0 through 27 */
- for (i = 0; i <= 27; i++)
- /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_isrc1_setup() - ISRC1 Packet
- */
-static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi)
-{
- int i;
-
- /* ISRC1 Packet */
- hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX);
-
- /* Packet Type = 0x05 */
- hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
- /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
- /* Reserved (0) */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
- /* PB0 UPC_EAN_ISRC_0-15 */
- /* Bytes PB16-PB27 shall be set to a value of 0. */
- for (i = 0; i <= 27; i++)
- /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_isrc2_setup() - ISRC2 Packet
- */
-static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi)
-{
- int i;
-
- /* ISRC2 Packet */
- hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX);
-
- /* HB0 Packet Type = 0x06 */
- hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
- /* Reserved (0) */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
- /* Reserved (0) */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
- /* PB0 UPC_EAN_ISRC_16-31 */
- /* Bytes PB16-PB27 shall be set to a value of 0. */
- for (i = 0; i <= 27; i++)
- /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
- hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
* sh_hdmi_configure() - Initialise HDMI for output
*/
static void sh_hdmi_configure(struct sh_hdmi *hdmi)
@@ -632,18 +667,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
/* Audio InfoFrame */
sh_hdmi_audio_infoframe_setup(hdmi);
- /* Gamut Metadata packet */
- sh_hdmi_gamut_metadata_setup(hdmi);
-
- /* Audio Content Protection (ACP) Packet */
- sh_hdmi_acp_setup(hdmi);
-
- /* ISRC1 Packet */
- sh_hdmi_isrc1_setup(hdmi);
-
- /* ISRC2 Packet */
- sh_hdmi_isrc2_setup(hdmi);
-
/*
* Control packet auto send with VSYNC control: auto send
* General control, Gamut metadata, ISRC, and ACP packets
@@ -661,17 +684,17 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
}
-static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
+static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
{
- struct fb_var_screeninfo *var = &hdmi->var;
- struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
- struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg;
- unsigned long height = var->height, width = var->width;
+ struct fb_var_screeninfo tmpvar;
+ /* TODO: When we are ready to use EDID, use this to fill &hdmi->var */
+ struct fb_var_screeninfo *var = &tmpvar;
+ const struct fb_videomode *mode, *found = NULL;
int i;
u8 edid[128];
/* Read EDID */
- pr_debug("Read back EDID code:");
+ dev_dbg(hdmi->dev, "Read back EDID code:");
for (i = 0; i < 128; i++) {
edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
#ifdef DEBUG
@@ -686,29 +709,84 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
#ifdef DEBUG
printk(KERN_CONT "\n");
#endif
- fb_parse_edid(edid, var);
- pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n",
- var->left_margin, var->xres, var->right_margin, var->hsync_len,
- var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
- PICOS2KHZ(var->pixclock));
-
- /* FIXME: Use user-provided configuration instead of EDID */
- var->width = width;
- var->xres = lcd_cfg->xres;
- var->xres_virtual = lcd_cfg->xres;
- var->left_margin = lcd_cfg->left_margin;
- var->right_margin = lcd_cfg->right_margin;
- var->hsync_len = lcd_cfg->hsync_len;
- var->height = height;
- var->yres = lcd_cfg->yres;
- var->yres_virtual = lcd_cfg->yres * 2;
- var->upper_margin = lcd_cfg->upper_margin;
- var->lower_margin = lcd_cfg->lower_margin;
- var->vsync_len = lcd_cfg->vsync_len;
- var->sync = lcd_cfg->sync;
- var->pixclock = lcd_cfg->pixclock;
-
- hdmi_external_video_param(hdmi);
+
+ fb_edid_to_monspecs(edid, &hdmi->monspec);
+
+ /* First look for an exact match */
+ for (i = 0, mode = hdmi->monspec.modedb; i < hdmi->monspec.modedb_len;
+ i++, mode++) {
+ dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n",
+ mode->left_margin, mode->xres,
+ mode->right_margin, mode->hsync_len,
+ mode->upper_margin, mode->yres,
+ mode->lower_margin, mode->vsync_len,
+ PICOS2KHZ(mode->pixclock));
+ if (!found && hdmi->info) {
+ fb_videomode_to_var(var, mode);
+ found = fb_match_mode(var, &hdmi->info->modelist);
+ /*
+ * If an exact match found, we're good to bail out, but
+ * continue to print out all modes
+ */
+ }
+ }
+
+ /*
+ * The monitor might also work with a mode, that is smaller, than one of
+ * its modes, use the first (default) one for this
+ */
+ if (!found && hdmi->info && hdmi->monspec.modedb_len) {
+ struct fb_modelist *modelist;
+ unsigned int min_err = UINT_MAX, err;
+ const struct fb_videomode *mon_mode = hdmi->monspec.modedb;
+
+ list_for_each_entry(modelist, &hdmi->info->modelist, list) {
+ mode = &modelist->mode;
+ dev_dbg(hdmi->dev, "matching %ux%u to %ux%u\n", mode->xres, mode->yres,
+ mon_mode->xres, mon_mode->yres);
+ if (mode->xres <= mon_mode->xres && mode->yres <= mon_mode->yres) {
+ err = mon_mode->xres - mode->xres + mon_mode->yres - mode->yres;
+ if (!err) {
+ found = mode;
+ break;
+ }
+ if (err < min_err) {
+ found = mode;
+ min_err = err;
+ }
+ }
+ }
+ }
+
+ /* Nothing suitable specified by the platform: use monitor's first mode */
+ if (!found && hdmi->monspec.modedb_len)
+ found = hdmi->monspec.modedb;
+
+ /* No valid timing info in EDID - last resort: use platform default mode */
+ if (!found && hdmi->info) {
+ struct fb_modelist *modelist = list_entry(hdmi->info->modelist.next,
+ struct fb_modelist, list);
+ found = &modelist->mode;
+ }
+
+ /* No cookie today */
+ if (!found)
+ return -ENXIO;
+
+ dev_dbg(hdmi->dev, "best \"%s\" %ux%u@%ups\n", found->name,
+ found->xres, found->yres, found->pixclock);
+
+ if ((found->xres == 720 && found->yres == 480) ||
+ (found->xres == 1280 && found->yres == 720) ||
+ (found->xres == 1920 && found->yres == 1080))
+ hdmi->preprogrammed_mode = true;
+ else
+ hdmi->preprogrammed_mode = false;
+
+ fb_videomode_to_var(&hdmi->var, found);
+ sh_hdmi_external_video_param(hdmi);
+
+ return 0;
}
static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
@@ -736,8 +814,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);
if (printk_ratelimit())
- pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
- irq, status1, mask1, status2, mask2);
+ dev_dbg(hdmi->dev, "IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
+ irq, status1, mask1, status2, mask2);
if (!((status1 & mask1) | (status2 & mask2))) {
return IRQ_NONE;
@@ -748,7 +826,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
udelay(500);
msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
- pr_debug("MSENS 0x%x\n", msens);
+ dev_dbg(hdmi->dev, "MSENS 0x%x\n", msens);
/* Check, if hot plug & MSENS pin status are both high */
if ((msens & 0xC0) == 0xC0) {
/* Display plug in */
@@ -784,83 +862,176 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void hdmi_display_on(void *arg, struct fb_info *info)
+/* locking: called with info->lock held, or before register_framebuffer() */
+static void sh_hdmi_display_on(void *arg, struct fb_info *info)
{
+ /*
+ * info is guaranteed to be valid, when we are called, because our
+ * FB_EVENT_FB_UNBIND notify is also called with info->lock held
+ */
struct sh_hdmi *hdmi = arg;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+ struct sh_mobile_lcdc_chan *ch = info->par;
- if (info->var.xres != 1280 || info->var.yres != 720) {
- dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n",
- info->var.xres, info->var.yres);
- return;
- }
+ dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
+ pdata->lcd_dev, info->state);
+
+ /* No need to lock */
+ hdmi->info = info;
- pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
/*
- * FIXME: not a good place to store fb_info. And we cannot nullify it
- * even on monitor disconnect. What should the lifecycle be?
+ * hp_state can be set to
+ * HDMI_HOTPLUG_DISCONNECTED: on monitor unplug
+ * HDMI_HOTPLUG_CONNECTED: on monitor plug-in
+ * HDMI_HOTPLUG_EDID_DONE: on EDID read completion
*/
- hdmi->info = info;
switch (hdmi->hp_state) {
case HDMI_HOTPLUG_EDID_DONE:
/* PS mode d->e. All functions are active */
hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
- pr_debug("HDMI running\n");
+ dev_dbg(hdmi->dev, "HDMI running\n");
break;
case HDMI_HOTPLUG_DISCONNECTED:
info->state = FBINFO_STATE_SUSPENDED;
default:
- hdmi->var = info->var;
+ hdmi->var = ch->display_var;
}
}
-static void hdmi_display_off(void *arg)
+/* locking: called with info->lock held */
+static void sh_hdmi_display_off(void *arg)
{
struct sh_hdmi *hdmi = arg;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
- pr_debug("%s(%p)\n", __func__, pdata->lcd_dev);
+ dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
/* PS mode e->a */
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
+static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
+{
+ struct fb_info *info = hdmi->info;
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
+ struct fb_videomode mode1, mode2;
+
+ fb_var_to_videomode(&mode1, old_var);
+ fb_var_to_videomode(&mode2, new_var);
+
+ dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
+ mode1.xres, mode1.yres, mode2.xres, mode2.yres);
+
+ if (fb_mode_is_equal(&mode1, &mode2))
+ return false;
+
+ dev_dbg(info->dev, "Switching %u -> %u lines\n",
+ mode1.yres, mode2.yres);
+ *old_var = *new_var;
+
+ return true;
+}
+
+/**
+ * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
+ * @hdmi: driver context
+ * @pixclock: pixel clock period in picoseconds
+ * return: configured positive rate if successful
+ * 0 if couldn't set the rate, but managed to enable the clock
+ * negative error, if couldn't enable the clock
+ */
+static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock)
+{
+ long rate;
+ int ret;
+
+ rate = PICOS2KHZ(pixclock) * 1000;
+ rate = clk_round_rate(hdmi->hdmi_clk, rate);
+ if (rate > 0) {
+ ret = clk_set_rate(hdmi->hdmi_clk, rate);
+ if (ret < 0) {
+ dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret);
+ rate = 0;
+ } else {
+ dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate);
+ }
+ } else {
+ rate = 0;
+ dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate);
+ }
+
+ ret = clk_enable(hdmi->hdmi_clk);
+ if (ret < 0) {
+ dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
+ return ret;
+ }
+
+ return rate;
+}
+
/* Hotplug interrupt occurred, read EDID */
-static void edid_work_fn(struct work_struct *work)
+static void sh_hdmi_edid_work_fn(struct work_struct *work)
{
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+ struct sh_mobile_lcdc_chan *ch;
+ int ret;
- pr_debug("%s(%p): begin, hotplug status %d\n", __func__,
- pdata->lcd_dev, hdmi->hp_state);
+ dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
+ pdata->lcd_dev, hdmi->hp_state);
if (!pdata->lcd_dev)
return;
+ mutex_lock(&hdmi->mutex);
+
if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
- pm_runtime_get_sync(hdmi->dev);
/* A device has been plugged in */
- sh_hdmi_read_edid(hdmi);
+ pm_runtime_get_sync(hdmi->dev);
+
+ ret = sh_hdmi_read_edid(hdmi);
+ if (ret < 0)
+ goto out;
+
+ /* Reconfigure the clock */
+ clk_disable(hdmi->hdmi_clk);
+ ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock);
+ if (ret < 0)
+ goto out;
+
msleep(10);
sh_hdmi_configure(hdmi);
/* Switched to another (d) power-save mode */
msleep(10);
if (!hdmi->info)
- return;
+ goto out;
+
+ ch = hdmi->info->par;
acquire_console_sem();
/* HDMI plug in */
- hdmi->info->var = hdmi->var;
- if (hdmi->info->state != FBINFO_STATE_RUNNING)
+ if (!sh_hdmi_must_reconfigure(hdmi) &&
+ hdmi->info->state == FBINFO_STATE_RUNNING) {
+ /*
+ * First activation with the default monitor - just turn
+ * on, if we run a resume here, the logo disappears
+ */
+ if (lock_fb_info(hdmi->info)) {
+ sh_hdmi_display_on(hdmi, hdmi->info);
+ unlock_fb_info(hdmi->info);
+ }
+ } else {
+ /* New monitor or have to wake up */
fb_set_suspend(hdmi->info, 0);
- else
- hdmi_display_on(hdmi, hdmi->info);
+ }
release_console_sem();
} else {
+ ret = 0;
if (!hdmi->info)
- return;
+ goto out;
acquire_console_sem();
@@ -869,15 +1040,67 @@ static void edid_work_fn(struct work_struct *work)
release_console_sem();
pm_runtime_put(hdmi->dev);
+ fb_destroy_modedb(hdmi->monspec.modedb);
}
- pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev);
+out:
+ if (ret < 0)
+ hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
+ mutex_unlock(&hdmi->mutex);
+
+ dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
+}
+
+static int sh_hdmi_notify(struct notifier_block *nb,
+ unsigned long action, void *data);
+
+static struct notifier_block sh_hdmi_notifier = {
+ .notifier_call = sh_hdmi_notify,
+};
+
+static int sh_hdmi_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct fb_event *event = data;
+ struct fb_info *info = event->info;
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ struct sh_hdmi *hdmi = board_cfg->board_data;
+
+ if (nb != &sh_hdmi_notifier || !hdmi || hdmi->info != info)
+ return NOTIFY_DONE;
+
+ switch(action) {
+ case FB_EVENT_FB_REGISTERED:
+ /* Unneeded, activation taken care by sh_hdmi_display_on() */
+ break;
+ case FB_EVENT_FB_UNREGISTERED:
+ /*
+ * We are called from unregister_framebuffer() with the
+ * info->lock held. This is bad for us, because we can race with
+ * the scheduled work, which has to call fb_set_suspend(), which
+ * takes info->lock internally, so, sh_hdmi_edid_work_fn()
+ * cannot take and hold info->lock for the whole function
+ * duration. Using an additional lock creates a classical AB-BA
+ * lock up. Therefore, we have to release the info->lock
+ * temporarily, synchronise with the work queue and re-acquire
+ * the info->lock.
+ */
+ unlock_fb_info(hdmi->info);
+ mutex_lock(&hdmi->mutex);
+ hdmi->info = NULL;
+ mutex_unlock(&hdmi->mutex);
+ lock_fb_info(hdmi->info);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
}
static int __init sh_hdmi_probe(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct sh_mobile_lcdc_board_cfg *board_cfg;
int irq = platform_get_irq(pdev, 0), ret;
struct sh_hdmi *hdmi;
long rate;
@@ -891,6 +1114,12 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ ret = snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
+ if (ret < 0)
+ goto esndreg;
+
+ mutex_init(&hdmi->mutex);
hdmi->dev = &pdev->dev;
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
@@ -900,30 +1129,13 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto egetclk;
}
- rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000;
-
- rate = clk_round_rate(hdmi->hdmi_clk, rate);
+ rate = sh_hdmi_clk_configure(hdmi, pdata->lcd_chan->lcd_cfg[0].pixclock);
if (rate < 0) {
ret = rate;
- dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
- goto erate;
- }
-
- ret = clk_set_rate(hdmi->hdmi_clk, rate);
- if (ret < 0) {
- dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
goto erate;
}
- pr_debug("HDMI set frequency %lu\n", rate);
-
- ret = clk_enable(hdmi->hdmi_clk);
- if (ret < 0) {
- dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret);
- goto eclkenable;
- }
-
- dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
+ dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
dev_err(&pdev->dev, "HDMI register region already claimed\n");
@@ -940,18 +1152,18 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hdmi);
-#if 1
/* Product and revision IDs are 0 in sh-mobile version */
dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
-#endif
/* Set up LCDC callbacks */
- pdata->lcd_chan->board_cfg.board_data = hdmi;
- pdata->lcd_chan->board_cfg.display_on = hdmi_display_on;
- pdata->lcd_chan->board_cfg.display_off = hdmi_display_off;
+ board_cfg = &pdata->lcd_chan->board_cfg;
+ board_cfg->owner = THIS_MODULE;
+ board_cfg->board_data = hdmi;
+ board_cfg->display_on = sh_hdmi_display_on;
+ board_cfg->display_off = sh_hdmi_display_off;
- INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn);
+ INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
@@ -972,10 +1184,12 @@ emap:
release_mem_region(res->start, resource_size(res));
ereqreg:
clk_disable(hdmi->hdmi_clk);
-eclkenable:
erate:
clk_put(hdmi->hdmi_clk);
egetclk:
+ mutex_destroy(&hdmi->mutex);
+ snd_soc_unregister_codec(&pdev->dev);
+esndreg:
kfree(hdmi);
return ret;
@@ -986,19 +1200,26 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
int irq = platform_get_irq(pdev, 0);
- pdata->lcd_chan->board_cfg.display_on = NULL;
- pdata->lcd_chan->board_cfg.display_off = NULL;
- pdata->lcd_chan->board_cfg.board_data = NULL;
+ snd_soc_unregister_codec(&pdev->dev);
+
+ board_cfg->display_on = NULL;
+ board_cfg->display_off = NULL;
+ board_cfg->board_data = NULL;
+ board_cfg->owner = NULL;
+ /* No new work will be scheduled, wait for running ISR */
free_irq(irq, hdmi);
- pm_runtime_disable(&pdev->dev);
+ /* Wait for already scheduled work */
cancel_delayed_work_sync(&hdmi->edid_work);
+ pm_runtime_disable(&pdev->dev);
clk_disable(hdmi->hdmi_clk);
clk_put(hdmi->hdmi_clk);
iounmap(hdmi->base);
release_mem_region(res->start, resource_size(res));
+ mutex_destroy(&hdmi->mutex);
kfree(hdmi);
return 0;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index d72075a9f01c..b4a878624510 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/mm.h>
-#include <linux/fb.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
@@ -24,7 +23,8 @@
#include <video/sh_mobile_lcdc.h>
#include <asm/atomic.h>
-#define PALETTE_NR 16
+#include "sh_mobile_lcdcfb.h"
+
#define SIDE_B_OFFSET 0x1000
#define MIRROR_OFFSET 0x2000
@@ -53,12 +53,6 @@ static int lcdc_shared_regs[] = {
};
#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
-/* per-channel registers */
-enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
- LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
- LDHAJR,
- NR_CH_REGS };
-
static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
[LDDCKPAT1R] = 0x400,
[LDDCKPAT2R] = 0x404,
@@ -112,25 +106,6 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
#define LDRCNTR_MRC 0x00000001
#define LDSR_MRS 0x00000100
-struct sh_mobile_lcdc_priv;
-struct sh_mobile_lcdc_chan {
- struct sh_mobile_lcdc_priv *lcdc;
- unsigned long *reg_offs;
- unsigned long ldmt1r_value;
- unsigned long enabled; /* ME and SE in LDCNT2R */
- struct sh_mobile_lcdc_chan_cfg cfg;
- u32 pseudo_palette[PALETTE_NR];
- unsigned long saved_ch_regs[NR_CH_REGS];
- struct fb_info *info;
- dma_addr_t dma_handle;
- struct fb_deferred_io defio;
- struct scatterlist *sglist;
- unsigned long frame_end;
- unsigned long pan_offset;
- wait_queue_head_t frame_end_wait;
- struct completion vsync_completion;
-};
-
struct sh_mobile_lcdc_priv {
void __iomem *base;
int irq;
@@ -409,8 +384,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
{
- struct fb_var_screeninfo *var = &ch->info->var;
- unsigned long h_total, hsync_pos;
+ struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
+ unsigned long h_total, hsync_pos, display_h_total;
u32 tmp;
tmp = ch->ldmt1r_value;
@@ -428,31 +403,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
/* horizontal configuration */
- h_total = var->xres + var->hsync_len +
- var->left_margin + var->right_margin;
+ h_total = display_var->xres + display_var->hsync_len +
+ display_var->left_margin + display_var->right_margin;
tmp = h_total / 8; /* HTCN */
- tmp |= (var->xres / 8) << 16; /* HDCN */
+ tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
lcdc_write_chan(ch, LDHCNR, tmp);
- hsync_pos = var->xres + var->right_margin;
+ hsync_pos = display_var->xres + display_var->right_margin;
tmp = hsync_pos / 8; /* HSYNP */
- tmp |= (var->hsync_len / 8) << 16; /* HSYNW */
+ tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
lcdc_write_chan(ch, LDHSYNR, tmp);
/* vertical configuration */
- tmp = var->yres + var->vsync_len +
- var->upper_margin + var->lower_margin; /* VTLN */
- tmp |= var->yres << 16; /* VDLN */
+ tmp = display_var->yres + display_var->vsync_len +
+ display_var->upper_margin + display_var->lower_margin; /* VTLN */
+ tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
lcdc_write_chan(ch, LDVLNR, tmp);
- tmp = var->yres + var->lower_margin; /* VSYNP */
- tmp |= var->vsync_len << 16; /* VSYNW */
+ tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
+ tmp |= display_var->vsync_len << 16; /* VSYNW */
lcdc_write_chan(ch, LDVSYNR, tmp);
/* Adjust horizontal synchronisation for HDMI */
- tmp = ((var->xres & 7) << 24) |
- ((h_total & 7) << 16) |
- ((var->hsync_len & 7) << 8) |
+ display_h_total = display_var->xres + display_var->hsync_len +
+ display_var->left_margin + display_var->right_margin;
+ tmp = ((display_var->xres & 7) << 24) |
+ ((display_h_total & 7) << 16) |
+ ((display_var->hsync_len & 7) << 8) |
hsync_pos;
lcdc_write_chan(ch, LDHAJR, tmp);
}
@@ -460,7 +437,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
{
struct sh_mobile_lcdc_chan *ch;
- struct fb_videomode *lcd_cfg;
struct sh_mobile_lcdc_board_cfg *board_cfg;
unsigned long tmp;
int k, m;
@@ -503,7 +479,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
m = 1 << 6;
tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
- lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000);
+ lcdc_write_chan(ch, LDDCKPAT1R, 0);
lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
}
@@ -518,7 +494,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
ch = &priv->ch[k];
- lcd_cfg = &ch->cfg.lcd_cfg;
if (!ch->enabled)
continue;
@@ -547,7 +522,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* set bpp format in PKF[4:0] */
tmp = lcdc_read_chan(ch, LDDFR);
- tmp &= ~(0x0001001f);
+ tmp &= ~0x0001001f;
tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
lcdc_write_chan(ch, LDDFR, tmp);
@@ -591,8 +566,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
continue;
board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_on)
+ if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
board_cfg->display_on(board_cfg->board_data, ch->info);
+ module_put(board_cfg->owner);
+ }
}
return 0;
@@ -614,7 +591,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
* flush frame, and wait for frame end interrupt
* clean up deferred io and enable clock
*/
- if (ch->info->fbdefio) {
+ if (ch->info && ch->info->fbdefio) {
ch->frame_end = 0;
schedule_delayed_work(&ch->info->deferred_work, 0);
wait_event(ch->frame_end_wait, ch->frame_end);
@@ -624,8 +601,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
}
board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_off)
+ if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
board_cfg->display_off(board_cfg->board_data);
+ module_put(board_cfg->owner);
+ }
}
/* stop the lcdc */
@@ -704,7 +683,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
return PTR_ERR(priv->dot_clk);
}
}
- atomic_set(&priv->hw_usecnt, -1);
/* Runtime PM support involves two step for this driver:
* 1) Enable Runtime PM
@@ -837,7 +815,6 @@ static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
return retval;
}
-
static struct fb_ops sh_mobile_lcdc_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -958,6 +935,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
.runtime_resume = sh_mobile_lcdc_runtime_resume,
};
+/* locking: called with info->lock held */
static int sh_mobile_lcdc_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -966,52 +944,38 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
struct sh_mobile_lcdc_chan *ch = info->par;
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
struct fb_var_screeninfo *var;
+ int ret;
if (&ch->lcdc->notifier != nb)
- return 0;
+ return NOTIFY_DONE;
dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
__func__, action, event->data);
switch(action) {
case FB_EVENT_SUSPEND:
- if (board_cfg->display_off)
+ if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
board_cfg->display_off(board_cfg->board_data);
+ module_put(board_cfg->owner);
+ }
pm_runtime_put(info->device);
+ sh_mobile_lcdc_stop(ch->lcdc);
break;
case FB_EVENT_RESUME:
var = &info->var;
/* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on)
+ if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
board_cfg->display_on(board_cfg->board_data, ch->info);
-
- /* Check if the new display is not in our modelist */
- if (ch->info->modelist.next &&
- !fb_match_mode(var, &ch->info->modelist)) {
- struct fb_videomode mode;
- int ret;
-
- /* Can we handle this display? */
- if (var->xres > ch->cfg.lcd_cfg.xres ||
- var->yres > ch->cfg.lcd_cfg.yres)
- return -ENOMEM;
-
- /* Add to the modelist */
- fb_var_to_videomode(&mode, var);
- ret = fb_add_videomode(&mode, &ch->info->modelist);
- if (ret < 0)
- return ret;
+ module_put(board_cfg->owner);
}
- pm_runtime_get_sync(info->device);
-
- sh_mobile_lcdc_geometry(ch);
-
- break;
+ ret = sh_mobile_lcdc_start(ch->lcdc);
+ if (!ret)
+ pm_runtime_get_sync(info->device);
}
- return 0;
+ return NOTIFY_OK;
}
static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -1020,14 +984,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
{
struct fb_info *info;
struct sh_mobile_lcdc_priv *priv;
- struct sh_mobile_lcdc_info *pdata;
+ struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
struct sh_mobile_lcdc_chan_cfg *cfg;
struct resource *res;
int error;
void *buf;
int i, j;
- if (!pdev->dev.platform_data) {
+ if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
}
@@ -1055,31 +1019,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
priv->irq = i;
- pdata = pdev->dev.platform_data;
+ atomic_set(&priv->hw_usecnt, -1);
j = 0;
for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
- priv->ch[j].lcdc = priv;
- memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
+ struct sh_mobile_lcdc_chan *ch = priv->ch + j;
- error = sh_mobile_lcdc_check_interface(&priv->ch[j]);
+ ch->lcdc = priv;
+ memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
+
+ error = sh_mobile_lcdc_check_interface(ch);
if (error) {
dev_err(&pdev->dev, "unsupported interface type\n");
goto err1;
}
- init_waitqueue_head(&priv->ch[j].frame_end_wait);
- init_completion(&priv->ch[j].vsync_completion);
- priv->ch[j].pan_offset = 0;
+ init_waitqueue_head(&ch->frame_end_wait);
+ init_completion(&ch->vsync_completion);
+ ch->pan_offset = 0;
switch (pdata->ch[i].chan) {
case LCDC_CHAN_MAINLCD:
- priv->ch[j].enabled = 1 << 1;
- priv->ch[j].reg_offs = lcdc_offs_mainlcd;
+ ch->enabled = 1 << 1;
+ ch->reg_offs = lcdc_offs_mainlcd;
j++;
break;
case LCDC_CHAN_SUBLCD:
- priv->ch[j].enabled = 1 << 2;
- priv->ch[j].reg_offs = lcdc_offs_sublcd;
+ ch->enabled = 1 << 2;
+ ch->reg_offs = lcdc_offs_sublcd;
j++;
break;
}
@@ -1103,69 +1069,73 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
for (i = 0; i < j; i++) {
struct fb_var_screeninfo *var;
- struct fb_videomode *lcd_cfg;
- cfg = &priv->ch[i].cfg;
+ const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
+ struct sh_mobile_lcdc_chan *ch = priv->ch + i;
+ unsigned long max_size = 0;
+ int k;
+
+ cfg = &ch->cfg;
- priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
- if (!priv->ch[i].info) {
+ ch->info = framebuffer_alloc(0, &pdev->dev);
+ if (!ch->info) {
dev_err(&pdev->dev, "unable to allocate fb_info\n");
error = -ENOMEM;
break;
}
- info = priv->ch[i].info;
+ info = ch->info;
var = &info->var;
- lcd_cfg = &cfg->lcd_cfg;
info->fbops = &sh_mobile_lcdc_ops;
- var->xres = var->xres_virtual = lcd_cfg->xres;
- var->yres = lcd_cfg->yres;
+ fb_videomode_to_var(var, &cfg->lcd_cfg[0]);
/* Default Y virtual resolution is 2x panel size */
var->yres_virtual = var->yres * 2;
- var->width = cfg->lcd_size_cfg.width;
- var->height = cfg->lcd_size_cfg.height;
- var->activate = FB_ACTIVATE_NOW;
- var->left_margin = lcd_cfg->left_margin;
- var->right_margin = lcd_cfg->right_margin;
- var->upper_margin = lcd_cfg->upper_margin;
- var->lower_margin = lcd_cfg->lower_margin;
- var->hsync_len = lcd_cfg->hsync_len;
- var->vsync_len = lcd_cfg->vsync_len;
- var->sync = lcd_cfg->sync;
- var->pixclock = lcd_cfg->pixclock;
error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
if (error)
break;
+ for (k = 0, lcd_cfg = cfg->lcd_cfg;
+ k < cfg->num_cfg;
+ k++, lcd_cfg++) {
+ unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
+
+ if (size > max_size) {
+ max_cfg = lcd_cfg;
+ max_size = size;
+ }
+ }
+
+ dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
+ max_cfg->xres, max_cfg->yres);
+
info->fix = sh_mobile_lcdc_fix;
- info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8);
- info->fix.smem_len = info->fix.line_length *
- var->yres_virtual;
+ info->fix.line_length = cfg->lcd_cfg[0].xres * (cfg->bpp / 8);
+ info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
- &priv->ch[i].dma_handle, GFP_KERNEL);
+ &ch->dma_handle, GFP_KERNEL);
if (!buf) {
dev_err(&pdev->dev, "unable to allocate buffer\n");
error = -ENOMEM;
break;
}
- info->pseudo_palette = &priv->ch[i].pseudo_palette;
+ info->pseudo_palette = &ch->pseudo_palette;
info->flags = FBINFO_FLAG_DEFAULT;
error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
if (error < 0) {
dev_err(&pdev->dev, "unable to allocate cmap\n");
dma_free_coherent(&pdev->dev, info->fix.smem_len,
- buf, priv->ch[i].dma_handle);
+ buf, ch->dma_handle);
break;
}
- memset(buf, 0, info->fix.smem_len);
- info->fix.smem_start = priv->ch[i].dma_handle;
+ info->fix.smem_start = ch->dma_handle;
info->screen_base = buf;
info->device = &pdev->dev;
- info->par = &priv->ch[i];
+ info->par = ch;
+ ch->display_var = *var;
}
if (error)
@@ -1191,6 +1161,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
}
+ fb_videomode_to_modelist(ch->cfg.lcd_cfg, ch->cfg.num_cfg, &info->modelist);
error = register_framebuffer(info);
if (error < 0)
goto err1;
@@ -1200,8 +1171,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
pdev->name,
(ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
"mainlcd" : "sublcd",
- (int) ch->cfg.lcd_cfg.xres,
- (int) ch->cfg.lcd_cfg.yres,
+ (int) ch->cfg.lcd_cfg[0].xres,
+ (int) ch->cfg.lcd_cfg[0].yres,
ch->cfg.bpp);
/* deferred io mode: disable clock to save power */
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
new file mode 100644
index 000000000000..dfd3d766a556
--- /dev/null
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -0,0 +1,38 @@
+#ifndef SH_MOBILE_LCDCFB_H
+#define SH_MOBILE_LCDCFB_H
+
+#include <linux/completion.h>
+#include <linux/fb.h>
+#include <linux/wait.h>
+
+/* per-channel registers */
+enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
+ LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
+ LDHAJR,
+ NR_CH_REGS };
+
+#define PALETTE_NR 16
+
+struct sh_mobile_lcdc_priv;
+struct fb_info;
+
+struct sh_mobile_lcdc_chan {
+ struct sh_mobile_lcdc_priv *lcdc;
+ unsigned long *reg_offs;
+ unsigned long ldmt1r_value;
+ unsigned long enabled; /* ME and SE in LDCNT2R */
+ struct sh_mobile_lcdc_chan_cfg cfg;
+ u32 pseudo_palette[PALETTE_NR];
+ unsigned long saved_ch_regs[NR_CH_REGS];
+ struct fb_info *info;
+ dma_addr_t dma_handle;
+ struct fb_deferred_io defio;
+ struct scatterlist *sglist;
+ unsigned long frame_end;
+ unsigned long pan_offset;
+ wait_queue_head_t frame_end_wait;
+ struct completion vsync_completion;
+ struct fb_var_screeninfo display_var;
+};
+
+#endif
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 090aa1a9be6e..6a069d047914 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -253,7 +253,7 @@ static int __init vesafb_probe(struct platform_device *dev)
size_vmode = vesafb_defined.yres * vesafb_fix.line_length;
/* size_total -- all video memory we have. Used for mtrr
- * entries, ressource allocation and bounds
+ * entries, resource allocation and bounds
* checking. */
size_total = screen_info.lfb_size * 65536;
if (vram_total)
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 39b040bb3817..7c82f6fda918 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -25,10 +25,12 @@
static void tmds_register_write(int index, u8 data);
static int tmds_register_read(int index);
static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
-static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
- *tmds_chip, struct tmds_setting_information *tmds_setting);
-static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
- *tmds_chip, struct tmds_setting_information *tmds_setting);
+static void __devinit dvi_get_panel_size_from_DDCv1(
+ struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting);
+static void __devinit dvi_get_panel_size_from_DDCv2(
+ struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting);
static int viafb_dvi_query_EDID(void);
static int check_tmds_chip(int device_id_subaddr, int device_id)
@@ -39,7 +41,7 @@ static int check_tmds_chip(int device_id_subaddr, int device_id)
return FAIL;
}
-void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting)
{
DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
@@ -60,7 +62,7 @@ void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
return;
}
-int viafb_tmds_trasmitter_identify(void)
+int __devinit viafb_tmds_trasmitter_identify(void)
{
unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
@@ -208,8 +210,6 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
}
}
viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
- viafb_set_output_path(DEVICE_DVI, set_iga,
- viaparinfo->chip_info->tmds_chip_info.output_interface);
}
/* Sense DVI Connector */
@@ -313,8 +313,9 @@ static int viafb_dvi_query_EDID(void)
}
/* Get Panel Size Using EDID1 Table */
-static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
- *tmds_chip, struct tmds_setting_information *tmds_setting)
+static void __devinit dvi_get_panel_size_from_DDCv1(
+ struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting)
{
int i, max_h = 0, tmp, restore;
unsigned char rData;
@@ -418,8 +419,9 @@ static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information
}
/* Get Panel Size Using EDID2 Table */
-static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information
- *tmds_chip, struct tmds_setting_information *tmds_setting)
+static void __devinit dvi_get_panel_size_from_DDCv2(
+ struct tmds_chip_information *tmds_chip,
+ struct tmds_setting_information *tmds_setting)
{
int restore;
unsigned char R_Buffer[2];
@@ -494,38 +496,103 @@ void viafb_dvi_disable(void)
viafb_read_reg(VIACR, CRD2) | 0x08);
}
+static void dvi_patch_skew_dvp0(void)
+{
+ /* Reset data driving first: */
+ viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
+ viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_P4M890:
+ {
+ if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
+ (viaparinfo->tmds_setting_info->v_active ==
+ 1200))
+ viafb_write_reg_mask(CR96, VIACR, 0x03,
+ BIT0 + BIT1 + BIT2);
+ else
+ viafb_write_reg_mask(CR96, VIACR, 0x07,
+ BIT0 + BIT1 + BIT2);
+ break;
+ }
+
+ case UNICHROME_P4M900:
+ {
+ viafb_write_reg_mask(CR96, VIACR, 0x07,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
+ viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+static void dvi_patch_skew_dvp_low(void)
+{
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
+ break;
+ }
+
+ case UNICHROME_P4M900:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x08,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ break;
+ }
+
+ case UNICHROME_P4M890:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x0F,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
/* If Enable DVI, turn off pad */
void viafb_dvi_enable(void)
{
u8 data;
- if (viaparinfo->chip_info->
- tmds_chip_info.output_interface == INTERFACE_DVP0) {
- viafb_write_reg(SR1E, VIASR,
- viafb_read_reg(VIASR, SR1E) | 0xC0);
+ switch (viaparinfo->chip_info->tmds_chip_info.output_interface) {
+ case INTERFACE_DVP0:
+ viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
+ viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5);
+ viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
+ dvi_patch_skew_dvp0();
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
tmds_register_write(0x88, 0x3b);
else
/*clear CR91[5] to direct on display period
in the secondary diplay path */
- viafb_write_reg(CR91, VIACR,
- viafb_read_reg(VIACR, CR91) & 0xDF);
- }
+ via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
+ break;
- if (viaparinfo->chip_info->
- tmds_chip_info.output_interface == INTERFACE_DVP1) {
- viafb_write_reg(SR1E, VIASR,
- viafb_read_reg(VIASR, SR1E) | 0x30);
+ case INTERFACE_DVP1:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5);
+ viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
/*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
- if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
tmds_register_write(0x88, 0x3b);
- } else {
+ else
/*clear CR91[5] to direct on display period
in the secondary diplay path */
- viafb_write_reg(CR91, VIACR,
- viafb_read_reg(VIACR, CR91) & 0xDF);
- }
+ via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
/*fix DVI cannot enable on EPIA-M board */
if (viafb_platform_epia_dvi == 1) {
@@ -537,36 +604,41 @@ void viafb_dvi_enable(void)
else
data = 0x37;
viafb_i2c_writebyte(viaparinfo->chip_info->
- tmds_chip_info.i2c_port,
- viaparinfo->chip_info->
- tmds_chip_info.tmds_chip_slave_addr,
- 0x08, data);
+ tmds_chip_info.i2c_port,
+ viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_slave_addr,
+ 0x08, data);
}
}
- }
+ break;
- if (viaparinfo->chip_info->
- tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
- viafb_write_reg(SR2A, VIASR,
- viafb_read_reg(VIASR, SR2A) | 0x0C);
- viafb_write_reg(CR91, VIACR,
- viafb_read_reg(VIACR, CR91) & 0xDF);
- }
+ case INTERFACE_DFP_HIGH:
+ if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+ via_write_reg_mask(VIACR, CR97, 0x03, 0x03);
- if (viaparinfo->chip_info->
- tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
- viafb_write_reg(SR2A, VIASR,
- viafb_read_reg(VIASR, SR2A) | 0x03);
- viafb_write_reg(CR91, VIACR,
- viafb_read_reg(VIACR, CR91) & 0xDF);
- }
- if (viaparinfo->chip_info->
- tmds_chip_info.output_interface == INTERFACE_TMDS) {
+ viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
+ via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
+ break;
+
+ case INTERFACE_DFP_LOW:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ break;
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+ dvi_patch_skew_dvp_low();
+ via_write_reg_mask(VIACR, 0x91, 0x00, 0x20);
+ break;
+
+ case INTERFACE_TMDS:
/* Turn on Display period in the panel path. */
viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
/* Turn on TMDS power. */
viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
+ break;
}
-}
+ if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
+ /* Disable LCD Scaling */
+ viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
+ }
+}
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index 0dffcfd395f3..2c525c0c1adb 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -56,8 +56,8 @@
int viafb_dvi_sense(void);
void viafb_dvi_disable(void);
void viafb_dvi_enable(void);
-int viafb_tmds_trasmitter_identify(void);
-void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
+int __devinit viafb_tmds_trasmitter_identify(void);
+void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting);
void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp,
int set_iga);
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 7dcb4d5bb9c3..03303232e543 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -718,16 +718,10 @@ static struct rgbLUT palLUT_table[] = {
0x00}
};
-static void set_crt_output_path(int set_iga);
-static void dvi_patch_skew_dvp0(void);
-static void dvi_patch_skew_dvp1(void);
-static void dvi_patch_skew_dvp_low(void);
-static void set_dvi_output_path(int set_iga, int output_interface);
-static void set_lcd_output_path(int set_iga, int output_interface);
static void load_fix_bit_crtc_reg(void);
-static void init_gfx_chip_info(int chip_type);
-static void init_tmds_chip_info(void);
-static void init_lvds_chip_info(void);
+static void __devinit init_gfx_chip_info(int chip_type);
+static void __devinit init_tmds_chip_info(void);
+static void __devinit init_lvds_chip_info(void);
static void device_screen_off(void);
static void device_screen_on(void);
static void set_display_channel(void);
@@ -755,6 +749,66 @@ void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
outb(b, LUT_DATA);
}
+static u32 get_dvi_devices(int output_interface)
+{
+ switch (output_interface) {
+ case INTERFACE_DVP0:
+ return VIA_96 | VIA_6C;
+
+ case INTERFACE_DVP1:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ return VIA_93;
+ else
+ return VIA_DVP1;
+
+ case INTERFACE_DFP_HIGH:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ return 0;
+ else
+ return VIA_LVDS2 | VIA_96;
+
+ case INTERFACE_DFP_LOW:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ return 0;
+ else
+ return VIA_DVP1 | VIA_LVDS1;
+
+ case INTERFACE_TMDS:
+ return VIA_LVDS1;
+ }
+
+ return 0;
+}
+
+static u32 get_lcd_devices(int output_interface)
+{
+ switch (output_interface) {
+ case INTERFACE_DVP0:
+ return VIA_96;
+
+ case INTERFACE_DVP1:
+ return VIA_DVP1;
+
+ case INTERFACE_DFP_HIGH:
+ return VIA_LVDS2 | VIA_96;
+
+ case INTERFACE_DFP_LOW:
+ return VIA_LVDS1 | VIA_DVP1;
+
+ case INTERFACE_DFP:
+ return VIA_LVDS1 | VIA_LVDS2;
+
+ case INTERFACE_LVDS0:
+ case INTERFACE_LVDS0LVDS1:
+ return VIA_LVDS1;
+
+ case INTERFACE_LVDS1:
+ return VIA_LVDS2;
+ }
+
+ return 0;
+}
+
/*Set IGA path for each device*/
void viafb_set_iga_path(void)
{
@@ -821,6 +875,48 @@ void viafb_set_iga_path(void)
viaparinfo->tmds_setting_info->iga_path = IGA1;
}
}
+
+ viaparinfo->shared->iga1_devices = 0;
+ viaparinfo->shared->iga2_devices = 0;
+ if (viafb_CRT_ON) {
+ if (viaparinfo->crt_setting_info->iga_path == IGA1)
+ viaparinfo->shared->iga1_devices |= VIA_CRT;
+ else
+ viaparinfo->shared->iga2_devices |= VIA_CRT;
+ }
+
+ if (viafb_DVI_ON) {
+ if (viaparinfo->tmds_setting_info->iga_path == IGA1)
+ viaparinfo->shared->iga1_devices |= get_dvi_devices(
+ viaparinfo->chip_info->
+ tmds_chip_info.output_interface);
+ else
+ viaparinfo->shared->iga2_devices |= get_dvi_devices(
+ viaparinfo->chip_info->
+ tmds_chip_info.output_interface);
+ }
+
+ if (viafb_LCD_ON) {
+ if (viaparinfo->lvds_setting_info->iga_path == IGA1)
+ viaparinfo->shared->iga1_devices |= get_lcd_devices(
+ viaparinfo->chip_info->
+ lvds_chip_info.output_interface);
+ else
+ viaparinfo->shared->iga2_devices |= get_lcd_devices(
+ viaparinfo->chip_info->
+ lvds_chip_info.output_interface);
+ }
+
+ if (viafb_LCD2_ON) {
+ if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
+ viaparinfo->shared->iga1_devices |= get_lcd_devices(
+ viaparinfo->chip_info->
+ lvds_chip_info2.output_interface);
+ else
+ viaparinfo->shared->iga2_devices |= get_lcd_devices(
+ viaparinfo->chip_info->
+ lvds_chip_info2.output_interface);
+ }
}
static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
@@ -844,295 +940,90 @@ void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
set_color_register(index, red, green, blue);
}
-void viafb_set_output_path(int device, int set_iga, int output_interface)
+static void set_source_common(u8 index, u8 offset, u8 iga)
{
- switch (device) {
- case DEVICE_CRT:
- set_crt_output_path(set_iga);
- break;
- case DEVICE_DVI:
- set_dvi_output_path(set_iga, output_interface);
+ u8 value, mask = 1 << offset;
+
+ switch (iga) {
+ case IGA1:
+ value = 0x00;
break;
- case DEVICE_LCD:
- set_lcd_output_path(set_iga, output_interface);
+ case IGA2:
+ value = mask;
break;
+ default:
+ printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
+ return;
}
+
+ via_write_reg_mask(VIACR, index, value, mask);
}
-static void set_crt_output_path(int set_iga)
+static void set_crt_source(u8 iga)
{
- viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
+ u8 value;
- switch (set_iga) {
+ switch (iga) {
case IGA1:
- viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
+ value = 0x00;
break;
case IGA2:
- viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
- viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
+ value = 0x40;
break;
+ default:
+ printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
+ return;
}
+
+ via_write_reg_mask(VIASR, 0x16, value, 0x40);
}
-static void dvi_patch_skew_dvp0(void)
+static inline void set_6C_source(u8 iga)
{
- /* Reset data driving first: */
- viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
- viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
-
- switch (viaparinfo->chip_info->gfx_chip_name) {
- case UNICHROME_P4M890:
- {
- if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
- (viaparinfo->tmds_setting_info->v_active ==
- 1200))
- viafb_write_reg_mask(CR96, VIACR, 0x03,
- BIT0 + BIT1 + BIT2);
- else
- viafb_write_reg_mask(CR96, VIACR, 0x07,
- BIT0 + BIT1 + BIT2);
- break;
- }
-
- case UNICHROME_P4M900:
- {
- viafb_write_reg_mask(CR96, VIACR, 0x07,
- BIT0 + BIT1 + BIT2 + BIT3);
- viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
- viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
- break;
- }
-
- default:
- {
- break;
- }
- }
+ set_source_common(0x6C, 7, iga);
}
-static void dvi_patch_skew_dvp1(void)
+static inline void set_93_source(u8 iga)
{
- switch (viaparinfo->chip_info->gfx_chip_name) {
- case UNICHROME_CX700:
- {
- break;
- }
-
- default:
- {
- break;
- }
- }
+ set_source_common(0x93, 7, iga);
}
-static void dvi_patch_skew_dvp_low(void)
+static inline void set_96_source(u8 iga)
{
- switch (viaparinfo->chip_info->gfx_chip_name) {
- case UNICHROME_K8M890:
- {
- viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
- break;
- }
-
- case UNICHROME_P4M900:
- {
- viafb_write_reg_mask(CR99, VIACR, 0x08,
- BIT0 + BIT1 + BIT2 + BIT3);
- break;
- }
-
- case UNICHROME_P4M890:
- {
- viafb_write_reg_mask(CR99, VIACR, 0x0F,
- BIT0 + BIT1 + BIT2 + BIT3);
- break;
- }
-
- default:
- {
- break;
- }
- }
+ set_source_common(0x96, 4, iga);
}
-static void set_dvi_output_path(int set_iga, int output_interface)
+static inline void set_dvp1_source(u8 iga)
{
- switch (output_interface) {
- case INTERFACE_DVP0:
- viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
-
- if (set_iga == IGA1) {
- viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
- viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
- BIT5 + BIT7);
- } else {
- viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
- BIT5 + BIT7);
- }
-
- viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
-
- dvi_patch_skew_dvp0();
- break;
-
- case INTERFACE_DVP1:
- if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR93, VIACR, 0x21,
- BIT0 + BIT5 + BIT7);
- else
- viafb_write_reg_mask(CR93, VIACR, 0xA1,
- BIT0 + BIT5 + BIT7);
- } else {
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
- else
- viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
- }
-
- viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
- dvi_patch_skew_dvp1();
- break;
- case INTERFACE_DFP_HIGH:
- if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) {
- if (set_iga == IGA1) {
- viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
- viafb_write_reg_mask(CR97, VIACR, 0x03,
- BIT0 + BIT1 + BIT4);
- } else {
- viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR97, VIACR, 0x13,
- BIT0 + BIT1 + BIT4);
- }
- }
- viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
- break;
-
- case INTERFACE_DFP_LOW:
- if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
- break;
-
- if (set_iga == IGA1) {
- viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
- viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
- } else {
- viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
- }
-
- viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
- dvi_patch_skew_dvp_low();
- break;
-
- case INTERFACE_TMDS:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
- else
- viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
- break;
- }
-
- if (set_iga == IGA2) {
- enable_second_display_channel();
- /* Disable LCD Scaling */
- viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
- }
+ set_source_common(0x9B, 4, iga);
}
-static void set_lcd_output_path(int set_iga, int output_interface)
+static inline void set_lvds1_source(u8 iga)
{
- DEBUG_MSG(KERN_INFO
- "set_lcd_output_path, iga:%d,out_interface:%d\n",
- set_iga, output_interface);
- switch (set_iga) {
- case IGA1:
- viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
- viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
-
- disable_second_display_channel();
- break;
-
- case IGA2:
- viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
- viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
-
- enable_second_display_channel();
- break;
- }
-
- switch (output_interface) {
- case INTERFACE_DVP0:
- if (set_iga == IGA1) {
- viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
- } else {
- viafb_write_reg(CR91, VIACR, 0x00);
- viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
- }
- break;
-
- case INTERFACE_DVP1:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
- else {
- viafb_write_reg(CR91, VIACR, 0x00);
- viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
- }
- break;
-
- case INTERFACE_DFP_HIGH:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
- else {
- viafb_write_reg(CR91, VIACR, 0x00);
- viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
- }
- break;
-
- case INTERFACE_DFP_LOW:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
- else {
- viafb_write_reg(CR91, VIACR, 0x00);
- viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
- }
-
- break;
-
- case INTERFACE_DFP:
- if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
- || (UNICHROME_P4M890 ==
- viaparinfo->chip_info->gfx_chip_name))
- viafb_write_reg_mask(CR97, VIACR, 0x84,
- BIT7 + BIT2 + BIT1 + BIT0);
- if (set_iga == IGA1) {
- viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
- viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
- } else {
- viafb_write_reg(CR91, VIACR, 0x00);
- viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
- viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
- }
- break;
-
- case INTERFACE_LVDS0:
- case INTERFACE_LVDS0LVDS1:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
- else
- viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+ set_source_common(0x99, 4, iga);
+}
- break;
+static inline void set_lvds2_source(u8 iga)
+{
+ set_source_common(0x97, 4, iga);
+}
- case INTERFACE_LVDS1:
- if (set_iga == IGA1)
- viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
- else
- viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
- break;
- }
+void via_set_source(u32 devices, u8 iga)
+{
+ if (devices & VIA_6C)
+ set_6C_source(iga);
+ if (devices & VIA_93)
+ set_93_source(iga);
+ if (devices & VIA_96)
+ set_96_source(iga);
+ if (devices & VIA_CRT)
+ set_crt_source(iga);
+ if (devices & VIA_DVP1)
+ set_dvp1_source(iga);
+ if (devices & VIA_LVDS1)
+ set_lvds1_source(iga);
+ if (devices & VIA_LVDS2)
+ set_lvds2_source(iga);
}
static void load_fix_bit_crtc_reg(void)
@@ -1688,8 +1579,8 @@ void viafb_set_vclock(u32 clk, int set_iga)
}
if (set_iga == IGA2) {
- viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
- viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
+ viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
+ viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
}
/* Fire! */
@@ -2004,7 +1895,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
}
-void viafb_init_chip_info(int chip_type)
+void __devinit viafb_init_chip_info(int chip_type)
{
init_gfx_chip_info(chip_type);
init_tmds_chip_info();
@@ -2071,7 +1962,7 @@ void viafb_update_device_setting(int hres, int vres,
}
}
-static void init_gfx_chip_info(int chip_type)
+static void __devinit init_gfx_chip_info(int chip_type)
{
u8 tmp;
@@ -2123,7 +2014,7 @@ static void init_gfx_chip_info(int chip_type)
}
}
-static void init_tmds_chip_info(void)
+static void __devinit init_tmds_chip_info(void)
{
viafb_tmds_trasmitter_identify();
@@ -2168,7 +2059,7 @@ static void init_tmds_chip_info(void)
&viaparinfo->shared->tmds_setting_info);
}
-static void init_lvds_chip_info(void)
+static void __devinit init_lvds_chip_info(void)
{
viafb_lvds_trasmitter_identify();
viafb_init_lcd_size();
@@ -2202,7 +2093,7 @@ static void init_lvds_chip_info(void)
viaparinfo->chip_info->lvds_chip_info.output_interface);
}
-void viafb_init_dac(int set_iga)
+void __devinit viafb_init_dac(int set_iga)
{
int i;
u8 tmp;
@@ -2337,7 +2228,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
via_write_reg(VIASR, i, VPIT.SR[i - 1]);
viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
- viafb_set_iga_path();
/* Write CRTC */
viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
@@ -2377,6 +2267,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
via_set_primary_color_depth(viaparinfo->depth);
via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
: viaparinfo->depth);
+ via_set_source(viaparinfo->shared->iga1_devices, IGA1);
+ via_set_source(viaparinfo->shared->iga2_devices, IGA2);
+ if (viaparinfo->shared->iga2_devices)
+ enable_second_display_channel();
+ else
+ disable_second_display_channel();
+
/* Update Refresh Rate Setting */
/* Clear On Screen */
@@ -2394,8 +2291,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
viaparinfo->crt_setting_info->iga_path);
}
- set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
-
/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
to 8 alignment (1368),there is several pixels (2 pixels)
on right side of screen. */
@@ -2482,10 +2377,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
viafb_DeviceStatus = CRT_Device;
}
device_on();
-
- if (viafb_SAMM_ON == 1)
- viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
-
device_screen_on();
return 1;
}
@@ -2567,7 +2458,6 @@ static void disable_second_display_channel(void)
viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
}
-
void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
*p_gfx_dpa_setting)
{
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index c44399895294..45dee39a8b23 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -30,6 +30,15 @@
#define viafb_write_reg(i, p, d) via_write_reg(p, i, d)
#define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m)
+/* VIA output devices */
+#define VIA_6C 0x00000001
+#define VIA_93 0x00000002
+#define VIA_96 0x00000004
+#define VIA_CRT 0x00000010
+#define VIA_DVP1 0x00000020
+#define VIA_LVDS1 0x00000040
+#define VIA_LVDS2 0x00000080
+
/***************************************************
* Definition IGA1 Design Method of CRTC Registers *
****************************************************/
@@ -881,9 +890,6 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
-void viafb_set_output_path(int device, int set_iga,
- int output_interface);
-
void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
@@ -908,8 +914,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
struct VideoModeTable *vmode_tbl1, int video_bpp1);
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
struct VideoModeTable *vmode_tbl);
-void viafb_init_chip_info(int chip_type);
-void viafb_init_dac(int set_iga);
+void __devinit viafb_init_chip_info(int chip_type);
+void __devinit viafb_init_dac(int set_iga);
int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
int viafb_get_refresh(int hres, int vres, u32 float_refresh);
void viafb_update_device_setting(int hres, int vres, int bpp,
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c
index da03c074e32a..455b39f46e57 100644
--- a/drivers/video/via/ioctl.c
+++ b/drivers/video/via/ioctl.c
@@ -92,6 +92,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp)
viafb_CRT_ON = 0;
viafb_LCD_ON = 0;
viafb_DeviceStatus = DVI_Device;
+ viafb_set_iga_path();
return viafb_DeviceStatus;
}
status = 1;
@@ -105,6 +106,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp)
viafb_LCD_ON = 0;
viafb_DeviceStatus = CRT_Device;
+ viafb_set_iga_path();
return viafb_DeviceStatus;
}
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index fc25ae30c5f6..e99f933faf19 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -21,10 +21,16 @@
#include <linux/via-core.h>
#include <linux/via_i2c.h>
#include "global.h"
-#include "lcdtbl.h"
#define viafb_compact_res(x, y) (((x)<<16)|(y))
+/* CLE266 Software Power Sequence */
+/* {Mask}, {Data}, {Delay} */
+int PowerSequenceOn[3][3] = { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06},
+ {0x19, 0x1FE, 0x01} };
+int PowerSequenceOff[3][3] = { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00},
+ {0xD2, 0x19, 0x01} };
+
static struct _lcd_scaling_factor lcd_scaling_factor = {
/* LCD Horizontal Scaling Factor Register */
{LCD_HOR_SCALING_FACTOR_REG_NUM,
@@ -42,7 +48,7 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
static int check_lvds_chip(int device_id_subaddr, int device_id);
static bool lvds_identify_integratedlvds(void);
-static void fp_id_to_vindex(int panel_id);
+static void __devinit fp_id_to_vindex(int panel_id);
static int lvds_register_read(int index);
static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
int panel_vres);
@@ -84,7 +90,7 @@ static int check_lvds_chip(int device_id_subaddr, int device_id)
return FAIL;
}
-void viafb_init_lcd_size(void)
+void __devinit viafb_init_lcd_size(void)
{
DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
@@ -144,7 +150,7 @@ static bool lvds_identify_integratedlvds(void)
return true;
}
-int viafb_lvds_trasmitter_identify(void)
+int __devinit viafb_lvds_trasmitter_identify(void)
{
if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
@@ -185,7 +191,7 @@ int viafb_lvds_trasmitter_identify(void)
return FAIL;
}
-static void fp_id_to_vindex(int panel_id)
+static void __devinit fp_id_to_vindex(int panel_id)
{
DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
@@ -655,9 +661,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
viafb_set_vclock(pll_D_N, set_iga);
-
- viafb_set_output_path(DEVICE_LCD, set_iga,
- plvds_chip_info->output_interface);
lcd_patch_skew(plvds_setting_info, plvds_chip_info);
/* If K8M800, enable LCD Prefetch Mode. */
@@ -830,8 +833,36 @@ void viafb_lcd_disable(void)
}
+static void set_lcd_output_path(int set_iga, int output_interface)
+{
+ switch (output_interface) {
+ case INTERFACE_DFP:
+ if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
+ || (UNICHROME_P4M890 ==
+ viaparinfo->chip_info->gfx_chip_name))
+ viafb_write_reg_mask(CR97, VIACR, 0x84,
+ BIT7 + BIT2 + BIT1 + BIT0);
+ case INTERFACE_DVP0:
+ case INTERFACE_DVP1:
+ case INTERFACE_DFP_HIGH:
+ case INTERFACE_DFP_LOW:
+ if (set_iga == IGA2)
+ viafb_write_reg(CR91, VIACR, 0x00);
+ break;
+ }
+}
+
void viafb_lcd_enable(void)
{
+ viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+ set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path,
+ viaparinfo->chip_info->lvds_chip_info.output_interface);
+ if (viafb_LCD2_ON)
+ set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path,
+ viaparinfo->chip_info->
+ lvds_chip_info2.output_interface);
+
if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
/* DI1 pad on */
viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
@@ -993,7 +1024,7 @@ static void check_diport_of_integrated_lvds(
plvds_chip_info->output_interface);
}
-void viafb_init_lvds_output_interface(struct lvds_chip_information
+void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info)
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index b348efc360b8..c7909fe29550 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -71,15 +71,15 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information
struct lvds_chip_information *plvds_chip_info);
void viafb_lcd_disable(void);
void viafb_lcd_enable(void);
-void viafb_init_lcd_size(void);
-void viafb_init_lvds_output_interface(struct lvds_chip_information
+void __devinit viafb_init_lcd_size(void);
+void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info);
void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info);
-int viafb_lvds_trasmitter_identify(void);
+int __devinit viafb_lvds_trasmitter_identify(void);
void viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h
deleted file mode 100644
index 6f3dd800be59..000000000000
--- a/drivers/video/via/lcdtbl.h
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation;
- * either version 2, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 __LCDTBL_H__
-#define __LCDTBL_H__
-
-#include "share.h"
-
-/* CLE266 Software Power Sequence */
-/* {Mask}, {Data}, {Delay} */
-int PowerSequenceOn[3][3] =
- { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} };
-int PowerSequenceOff[3][3] =
- { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} };
-
-/* ++++++ P880 ++++++ */
-/* Panel 1600x1200 */
-struct io_reg P880_LCD_RES_6X4_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x5E},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C},
- {VIASR, SR46, 0xFF, 0x02}
-
-};
-
-#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12)
-
-struct io_reg P880_LCD_RES_7X4_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x78},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C},
- {VIASR, SR46, 0xFF, 0x01}
-
-};
-
-#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12)
-
-struct io_reg P880_LCD_RES_8X6_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88},
- {VIASR, SR46, 0xFF, 0x03}
-
-};
-
-#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12)
-
-struct io_reg P880_LCD_RES_10X7_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xAF},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88},
- {VIASR, SR46, 0xFF, 0x03}
-
-};
-
-#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12)
-
-struct io_reg P880_LCD_RES_12X10_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xD4},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88},
- {VIASR, SR46, 0xFF, 0x05}
-
-};
-
-#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12)
-
-/* Panel 1400x1050 */
-struct io_reg P880_LCD_RES_6X4_14X10[] = {
- /* 640x480 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x63},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C},
- {VIASR, SR46, 0xFF, 0x05}
-};
-
-#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10)
-
-struct io_reg P880_LCD_RES_8X6_14X10[] = {
- /* 800x600 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D},
- {VIASR, SR46, 0xFF, 0x05}
-};
-
-#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10)
-
-/* ++++++ K400 ++++++ */
-/* Panel 1600x1200 */
-struct io_reg K400_LCD_RES_6X4_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x5E},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12)
-
-struct io_reg K400_LCD_RES_7X4_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x78},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12)
-
-struct io_reg K400_LCD_RES_8X6_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12)
-
-struct io_reg K400_LCD_RES_10X7_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xAF},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12)
-
-struct io_reg K400_LCD_RES_12X10_16X12[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
- {VIACR, CR5D, 0x40, 0x40},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xD4},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12)
-
-/* Panel 1400x1050 */
-struct io_reg K400_LCD_RES_6X4_14X10[] = {
- /* 640x400 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x63},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10)
-
-struct io_reg K400_LCD_RES_8X6_14X10[] = {
- /* 800x600 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10)
-
-struct io_reg K400_LCD_RES_10X7_14X10[] = {
- /* 1024x768 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xA7},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10)
-
-struct io_reg K400_LCD_RES_12X10_14X10[] = {
- /* 1280x768, 1280x960, 1280x1024 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xD2},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10)
-
-/* ++++++ K400 ++++++ */
-/* Panel 1366x768 */
-struct io_reg K400_LCD_RES_6X4_1366X7[] = {
- /* 640x400 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x64},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7)
-
-struct io_reg K400_LCD_RES_7X4_1366X7[] = {
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x75},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7)
-
-struct io_reg K400_LCD_RES_8X6_1366X7[] = {
- /* 800x600 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x82},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7)
-
-struct io_reg K400_LCD_RES_10X7_1366X7[] = {
- /* 1024x768 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xA7},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7)
-
-struct io_reg K400_LCD_RES_12X10_1366X7[] = {
- /* 1280x768, 1280x960, 1280x1024 */
- /* IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
- /* IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
- {VIACR, CR5D, 0x40, 0x24},
- /* IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
- /* IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xD2},
- /* IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
- /* VCLK */
- {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\
- ARRAY_SIZE(K400_LCD_RES_12X10_1366X7)
-
-/* ++++++ K400 ++++++ */
-/* Panel 1280x1024 */
-struct io_reg K400_LCD_RES_6X4_12X10[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
- {VIACR, CR5D, 0x40, 0x1C},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x63},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10)
-
-struct io_reg K400_LCD_RES_7X4_12X10[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
- {VIACR, CR5D, 0x40, 0x1C},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x6C},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10)
-
-struct io_reg K400_LCD_RES_8X6_12X10[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
- {VIACR, CR5D, 0x40, 0x1C},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10)
-
-struct io_reg K400_LCD_RES_10X7_12X10[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
- {VIACR, CR5D, 0x40, 0x1C},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0xA7},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10)
-
-/* ++++++ K400 ++++++ */
-/* Panel 1024x768 */
-struct io_reg K400_LCD_RES_6X4_10X7[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x64},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7)
-
-struct io_reg K400_LCD_RES_7X4_10X7[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x75},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7)
-
-struct io_reg K400_LCD_RES_8X6_10X7[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
- {VIACR, CR5D, 0x40, 0x13},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x82},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7)
-
-/* ++++++ K400 ++++++ */
-/* Panel 800x600 */
-struct io_reg K400_LCD_RES_6X4_8X6[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3},
- {VIACR, CR5D, 0x40, 0x12},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x63},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6)
-
-struct io_reg K400_LCD_RES_7X4_8X6[] = {
- /*IGA2 Horizontal Total */
- {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34},
- /*IGA2 Horizontal Blank End */
- {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3},
- {VIACR, CR5D, 0x40, 0x12},
- /*IGA2 Horizontal Total Shadow */
- {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22},
- /*IGA2 Horizontal Blank End Shadow */
- {VIACR, CR6E, 0xFF, 0x83},
- /*IGA2 Offset */
- {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00},
- /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59}
-};
-
-#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6)
-
-#endif /* __LCDTBL_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index bdd0e4130f4e..5a947b096269 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -961,7 +961,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting
setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
}
-static int parse_active_dev(void)
+static int __init parse_active_dev(void)
{
viafb_CRT_ON = STATE_OFF;
viafb_DVI_ON = STATE_OFF;
@@ -1031,7 +1031,7 @@ static int parse_active_dev(void)
return 0;
}
-static int parse_port(char *opt_str, int *output_interface)
+static int __devinit parse_port(char *opt_str, int *output_interface)
{
if (!strncmp(opt_str, "DVP0", 4))
*output_interface = INTERFACE_DVP0;
@@ -1048,7 +1048,7 @@ static int parse_port(char *opt_str, int *output_interface)
return 0;
}
-static void parse_lcd_port(void)
+static void __devinit parse_lcd_port(void)
{
parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
output_interface);
@@ -1061,7 +1061,7 @@ static void parse_lcd_port(void)
output_interface);
}
-static void parse_dvi_port(void)
+static void __devinit parse_dvi_port(void)
{
parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
output_interface);
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 52a35fabba91..945a47a63c4d 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -40,6 +40,9 @@
#define VIAFB_NUM_I2C 5
struct viafb_shared {
+ u32 iga1_devices;
+ u32 iga2_devices;
+
struct proc_dir_entry *proc_entry; /*viafb proc entry */
struct viafb_dev *vdev; /* Global dev info */
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b036677df8c4..24efd8ea41bb 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -213,11 +213,11 @@ config OMAP_WATCHDOG
here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
config PNX4008_WATCHDOG
- tristate "PNX4008 Watchdog"
- depends on ARCH_PNX4008
+ tristate "PNX4008 and LPC32XX Watchdog"
+ depends on ARCH_PNX4008 || ARCH_LPC32XX
help
Say Y here if to include support for the watchdog timer
- in the PNX4008 processor.
+ in the PNX4008 or LPC32XX processor.
This driver can be built as a module by choosing M. The module
will be called pnx4008_wdt.
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index c764c52412e4..9d4d560d8b6e 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -267,6 +267,7 @@ static const struct file_operations ar7_wdt_fops = {
.unlocked_ioctl = ar7_wdt_ioctl,
.open = ar7_wdt_open,
.release = ar7_wdt_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice ar7_wdt_miscdev = {
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 566343b3c131..61b621126da0 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -25,7 +25,7 @@
#include <linux/ioport.h>
#include <linux/timer.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -89,6 +89,7 @@ struct cpwd {
} devs[WD_NUMDEVS];
};
+static DEFINE_MUTEX(cpwd_mutex);
static struct cpwd *cpwd_device;
/* Sun uses Altera PLD EPF8820ATC144-4
@@ -368,7 +369,7 @@ static int cpwd_open(struct inode *inode, struct file *f)
{
struct cpwd *p = cpwd_device;
- lock_kernel();
+ mutex_lock(&cpwd_mutex);
switch (iminor(inode)) {
case WD0_MINOR:
case WD1_MINOR:
@@ -376,7 +377,7 @@ static int cpwd_open(struct inode *inode, struct file *f)
break;
default:
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return -ENODEV;
}
@@ -386,13 +387,13 @@ static int cpwd_open(struct inode *inode, struct file *f)
IRQF_SHARED, DRIVER_NAME, p)) {
printk(KERN_ERR PFX "Cannot register IRQ %d\n",
p->irq);
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return -EBUSY;
}
p->initialized = true;
}
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return nonseekable_open(inode, f);
}
@@ -482,9 +483,9 @@ static long cpwd_compat_ioctl(struct file *file, unsigned int cmd,
case WIOCSTART:
case WIOCSTOP:
case WIOCGSTAT:
- lock_kernel();
+ mutex_lock(&cpwd_mutex);
rval = cpwd_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
break;
/* everything else is handled by the generic compat layer */
@@ -524,6 +525,7 @@ static const struct file_operations cpwd_fops = {
.write = cpwd_write,
.read = cpwd_read,
.release = cpwd_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int __devinit cpwd_probe(struct platform_device *op,
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 59359c9a5e01..6c9e0a73ed30 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -188,6 +188,7 @@ static const struct file_operations ep93xx_wdt_fops = {
.unlocked_ioctl = ep93xx_wdt_ioctl,
.open = ep93xx_wdt_open,
.release = ep93xx_wdt_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static struct miscdevice ep93xx_wdt_miscdev = {
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 76b58abf4451..f60f4e355937 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -258,6 +258,7 @@ static const struct file_operations omap_wdt_fops = {
.unlocked_ioctl = omap_wdt_ioctl,
.open = omap_wdt_open,
.release = omap_wdt_release,
+ .llseek = no_llseek,/* open uses nonseekable */
};
static int __devinit omap_wdt_probe(struct platform_device *pdev)
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index 88c83aa57303..f31493e65b38 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -305,7 +305,7 @@ static int __init sbwdog_init(void)
if (ret) {
printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
ident.identity, ret);
- return ret;
+ goto out;
}
ret = misc_register(&sbwdog_miscdev);
@@ -313,14 +313,20 @@ static int __init sbwdog_init(void)
printk(KERN_INFO "%s: timeout is %ld.%ld secs\n",
ident.identity,
timeout / 1000000, (timeout / 100000) % 10);
- } else
- free_irq(1, (void *)user_dog);
+ return 0;
+ }
+ free_irq(1, (void *)user_dog);
+out:
+ unregister_reboot_notifier(&sbwdog_notifier);
+
return ret;
}
static void __exit sbwdog_exit(void)
{
misc_deregister(&sbwdog_miscdev);
+ free_irq(1, (void *)user_dog);
+ unregister_reboot_notifier(&sbwdog_notifier);
}
module_init(sbwdog_init);
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
index 458c499c1223..18cdeb4c4258 100644
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -449,6 +449,9 @@ static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
wdt->pdev = pdev;
mutex_init(&wdt->lock);
+ /* make sure that the watchdog is disabled */
+ ts72xx_wdt_stop(wdt);
+
error = misc_register(&ts72xx_wdt_miscdev);
if (error) {
dev_err(&pdev->dev, "failed to register miscdev\n");
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index 66e185cfe92f..09149a818ac6 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -467,6 +467,7 @@ static const struct file_operations evtchn_fops = {
.fasync = evtchn_fasync,
.open = evtchn_open,
.release = evtchn_release,
+ .llseek = noop_llseek,/* read and write both use no f_pos */
};
static struct miscdevice evtchn_miscdev = {
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index 78bfab0700ba..85258ed89c1e 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -35,6 +35,7 @@ static ssize_t capabilities_read(struct file *file, char __user *buf,
static const struct file_operations capabilities_file_ops = {
.read = capabilities_read,
+ .llseek = default_llseek,/* read accesses f_pos */
};
static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index 3b39c3752e21..559240c6e2ec 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -594,4 +594,5 @@ const struct file_operations xenbus_file_ops = {
.open = xenbus_file_open,
.release = xenbus_file_release,
.poll = xenbus_file_poll,
+ .llseek = no_llseek,/* open uses nonseekable */
};